From a5d00e6498f9916cee31785e00a9aee7f3f63caf Mon Sep 17 00:00:00 2001 From: Amy Date: Thu, 6 Feb 2020 15:47:20 -0800 Subject: [PATCH 001/790] Refactoring Tuner VTS frontend test part Note that other interface tests are comment out in this CL and will be refactored and uncomment in the CL chains. Test: cuttlefish atest + vendor device test Bug: 135708935 Change-Id: If831219fc588827c9367a506ba7fe7c96bea0286 --- tv/tuner/1.0/default/Frontend.cpp | 4 + .../VtsHalTvTunerV1_0TargetTest.cpp | 353 +++++++++++------- .../VtsHalTvTunerV1_0TestConfigurations.h | 137 +++++++ 3 files changed, 359 insertions(+), 135 deletions(-) create mode 100644 tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h diff --git a/tv/tuner/1.0/default/Frontend.cpp b/tv/tuner/1.0/default/Frontend.cpp index dd2f8a68d5..7e206a76cb 100644 --- a/tv/tuner/1.0/default/Frontend.cpp +++ b/tv/tuner/1.0/default/Frontend.cpp @@ -81,6 +81,10 @@ Return Frontend::stopTune() { Return Frontend::scan(const FrontendSettings& /* settings */, FrontendScanType /* type */) { ALOGV("%s", __FUNCTION__); + FrontendScanMessage msg; + msg.isLocked(true); + mCallback->onScanMessage(FrontendScanMessageType::LOCKED, msg); + return Result::SUCCESS; } diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp index 820c58c4ce..1b4929b37e 100644 --- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp +++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * 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. @@ -44,6 +44,8 @@ #include #include +#include "VtsHalTvTunerV1_0TestConfigurations.h" + #define WAIT_TIMEOUT 3000000000 #define WAIT_TIMEOUT_data_ready 3000000000 * 4 @@ -84,9 +86,11 @@ using android::hardware::tv::tuner::V1_0::FrontendAtscSettings; using android::hardware::tv::tuner::V1_0::FrontendDvbtSettings; using android::hardware::tv::tuner::V1_0::FrontendEventType; using android::hardware::tv::tuner::V1_0::FrontendId; +using android::hardware::tv::tuner::V1_0::FrontendInfo; using android::hardware::tv::tuner::V1_0::FrontendInnerFec; using android::hardware::tv::tuner::V1_0::FrontendScanMessage; using android::hardware::tv::tuner::V1_0::FrontendScanMessageType; +using android::hardware::tv::tuner::V1_0::FrontendScanType; using android::hardware::tv::tuner::V1_0::FrontendSettings; using android::hardware::tv::tuner::V1_0::IDemux; using android::hardware::tv::tuner::V1_0::IDescrambler; @@ -103,6 +107,8 @@ using android::hardware::tv::tuner::V1_0::RecordSettings; using android::hardware::tv::tuner::V1_0::RecordStatus; using android::hardware::tv::tuner::V1_0::Result; +using ::testing::AssertionResult; + namespace { using FilterMQ = MessageQueue; @@ -148,8 +154,9 @@ const std::vector goldenDataOutputBuffer{ }; // const uint16_t FMQ_SIZE_4K = 0x1000; -const uint32_t FMQ_SIZE_1M = 0x100000; -const uint32_t FMQ_SIZE_16M = 0x1000000; +// const uint32_t FMQ_SIZE_1M = 0x100000; +// const uint32_t FMQ_SIZE_16M = 0x1000000; +const uint8_t FRONTEND_EVENT_CALLBACK_WAIT_COUNT = 4; struct FilterConf { DemuxFilterType type; @@ -172,6 +179,7 @@ struct PlaybackConf { PlaybackSettings setting; }; +/******************************** Start FrontendCallback **********************************/ class FrontendCallback : public IFrontendCallback { public: virtual Return onEvent(FrontendEventType frontendEventType) override { @@ -182,28 +190,38 @@ class FrontendCallback : public IFrontendCallback { return Void(); } - virtual Return onScanMessage(FrontendScanMessageType /* type */, - const FrontendScanMessage& /* message */) override { + virtual Return onScanMessage(FrontendScanMessageType type, + const FrontendScanMessage& message) override { android::Mutex::Autolock autoLock(mMsgLock); + ALOGD("[vts] scan message. Type: %d", mScanMessageType); mScanMessageReceived = true; + mScanMessageType = type; + mScanLockMessageReceived = + mScanLockMessageReceived | (type == FrontendScanMessageType::LOCKED); + mScanMessage = message; mMsgCondition.signal(); return Void(); }; - void testOnEvent(sp& frontend, FrontendSettings settings); - void testOnDiseqcMessage(sp& frontend, FrontendSettings settings); + void tuneTestOnEventReceive(sp& frontend, FrontendSettings settings); + void tuneTestOnLock(sp& frontend, FrontendSettings settings); + void scanTestOnMessageLock(sp& frontend, FrontendSettings settings, + FrontendScanType type); private: bool mEventReceived = false; - bool mDiseqcMessageReceived = false; bool mScanMessageReceived = false; + bool mScanLockMessageReceived = false; FrontendEventType mEventType; + FrontendScanMessageType mScanMessageType; + FrontendScanMessage mScanMessage; hidl_vec mEventMessage; android::Mutex mMsgLock; android::Condition mMsgCondition; + uint8_t mOnEvenRetry = 0; }; -void FrontendCallback::testOnEvent(sp& frontend, FrontendSettings settings) { +void FrontendCallback::tuneTestOnEventReceive(sp& frontend, FrontendSettings settings) { Result result = frontend->tune(settings); EXPECT_TRUE(result == Result::SUCCESS); @@ -215,22 +233,70 @@ void FrontendCallback::testOnEvent(sp& frontend, FrontendSettings set return; } } + mEventReceived = false; } -void FrontendCallback::testOnDiseqcMessage(sp& frontend, FrontendSettings settings) { +void FrontendCallback::tuneTestOnLock(sp& frontend, FrontendSettings settings) { Result result = frontend->tune(settings); EXPECT_TRUE(result == Result::SUCCESS); android::Mutex::Autolock autoLock(mMsgLock); - while (!mDiseqcMessageReceived) { +wait: + while (!mEventReceived) { if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) { - EXPECT_TRUE(false) << "diseqc message not received within timeout"; + EXPECT_TRUE(false) << "event not received within timeout"; return; } } + if (mEventType != FrontendEventType::LOCKED) { + ALOGD("[vts] frontend callback event received. Type: %d", mEventType); + mEventReceived = false; + if (mOnEvenRetry++ < FRONTEND_EVENT_CALLBACK_WAIT_COUNT) { + goto wait; + } + } + EXPECT_TRUE(mEventType == FrontendEventType::LOCKED) << "LOCK event not received"; + mEventReceived = false; + mOnEvenRetry = 0; } +void FrontendCallback::scanTestOnMessageLock(sp& frontend, FrontendSettings settings, + FrontendScanType type) { + Result result = frontend->scan(settings, type); + EXPECT_TRUE(result == Result::SUCCESS); + android::Mutex::Autolock autoLock(mMsgLock); + int messagesCount = 0; + +wait: + int count = 0; + while (!mScanMessageReceived) { + if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) { + ALOGD("[vts] waiting for scan message callback..."); + if (count++ > 10) { + EXPECT_TRUE(false) << "WAITING TOO LONG!!"; + return; + } + } + } + + if (mScanMessageType != FrontendScanMessageType::END) { + ALOGD("[vts] frontend scan message received. Type: %d", mScanMessageType); + mScanMessageReceived = false; + if (messagesCount++ > 3) { + EXPECT_TRUE(false) << "WAITING ON TOO MANY MSGS!!"; + return; + } + goto wait; + } + + EXPECT_TRUE(mScanLockMessageReceived) << "scan lock message not received before scan ended"; + mScanMessageReceived = false; + mScanLockMessageReceived = false; +} +/******************************** End FrontendCallback **********************************/ + +/******************************** Start FilterCallback **********************************/ class FilterCallback : public IFilterCallback { public: virtual Return onFilterEvent(const DemuxFilterEvent& filterEvent) override { @@ -381,7 +447,9 @@ bool FilterCallback::readFilterEventData() { mFilterIdToMQEventFlag->wake(static_cast(DemuxQueueNotifyBits::DATA_CONSUMED)); return result; } +/******************************** End FilterCallback **********************************/ +/******************************** Start DvrCallback **********************************/ class DvrCallback : public IDvrCallback { public: virtual Return onRecordStatus(DemuxFilterStatus status) override { @@ -635,22 +703,32 @@ void DvrCallback::stopRecordThread() { mRecordThreadRunning = false; android::Mutex::Autolock autoLock(mRecordThreadLock); } +/******************************** End DvrCallback **********************************/ +/******************************** Start Test Implementation**********************************/ class TunerHidlTest : public testing::TestWithParam { public: virtual void SetUp() override { mService = ITuner::getService(GetParam()); ASSERT_NE(mService, nullptr); + initFrontendConfig(); + initFrontendScanConfig(); + initFilterConfig(); } sp mService; protected: + static AssertionResult failure() { return ::testing::AssertionFailure(); } + + static AssertionResult success() { return ::testing::AssertionSuccess(); } + static void description(const std::string& description) { RecordProperty("description", description); } sp mFrontend; + FrontendInfo mFrontendInfo; sp mFrontendCallback; sp mDescrambler; sp mDemux; @@ -664,6 +742,7 @@ class TunerHidlTest : public testing::TestWithParam { MQDesc mPlaybackMQDescriptor; MQDesc mRecordMQDescriptor; vector mUsedFilterIds; + hidl_vec mFeIds; uint32_t mDemuxId; uint32_t mFilterId; @@ -671,10 +750,16 @@ class TunerHidlTest : public testing::TestWithParam { pthread_t mPlaybackshread; bool mPlaybackThreadRunning; - ::testing::AssertionResult createFrontend(int32_t frontendId); - ::testing::AssertionResult tuneFrontend(int32_t frontendId); - ::testing::AssertionResult stopTuneFrontend(int32_t frontendId); - ::testing::AssertionResult closeFrontend(int32_t frontendId); + AssertionResult getFrontendIds(); + AssertionResult getFrontendInfo(uint32_t frontendId); + AssertionResult openFrontend(uint32_t frontendId); + AssertionResult setFrontendCallback(); + AssertionResult scanFrontend(FrontendConfig config, FrontendScanType type); + AssertionResult stopScanFrontend(); + AssertionResult tuneFrontend(FrontendConfig config); + AssertionResult stopTuneFrontend(); + AssertionResult closeFrontend(); + ::testing::AssertionResult createDemux(); ::testing::AssertionResult createDemuxWithFrontend(int32_t frontendId, FrontendSettings settings); @@ -698,68 +783,88 @@ class TunerHidlTest : public testing::TestWithParam { vector goldenOutputFiles); }; -::testing::AssertionResult TunerHidlTest::createFrontend(int32_t frontendId) { +/*============================Start Frontend APIs Tests Implementation============================*/ +AssertionResult TunerHidlTest::getFrontendIds() { Result status; + mService->getFrontendIds([&](Result result, const hidl_vec& frontendIds) { + status = result; + mFeIds = frontendIds; + }); + return AssertionResult(status == Result::SUCCESS); +} + +AssertionResult TunerHidlTest::getFrontendInfo(uint32_t frontendId) { + Result status; + mService->getFrontendInfo(frontendId, [&](Result result, const FrontendInfo& frontendInfo) { + mFrontendInfo = frontendInfo; + status = result; + }); + return AssertionResult(status == Result::SUCCESS); +} +AssertionResult TunerHidlTest::openFrontend(uint32_t frontendId) { + Result status; mService->openFrontendById(frontendId, [&](Result result, const sp& frontend) { mFrontend = frontend; status = result; }); - if (status != Result::SUCCESS) { - return ::testing::AssertionFailure(); - } + return AssertionResult(status == Result::SUCCESS); +} +AssertionResult TunerHidlTest::setFrontendCallback() { + EXPECT_TRUE(mFrontend) << "Test with openFrontend first."; mFrontendCallback = new FrontendCallback(); auto callbackStatus = mFrontend->setCallback(mFrontendCallback); + return AssertionResult(callbackStatus.isOk()); +} + +AssertionResult TunerHidlTest::scanFrontend(FrontendConfig config, FrontendScanType type) { + EXPECT_TRUE(mFrontendCallback) + << "test with openFrontend/setFrontendCallback/getFrontendInfo first."; - return ::testing::AssertionResult(callbackStatus.isOk()); + EXPECT_TRUE(mFrontendInfo.type == config.type) + << "FrontendConfig does not match the frontend info of the given id."; + + mFrontendCallback->scanTestOnMessageLock(mFrontend, config.settings, type); + return AssertionResult(true); } -::testing::AssertionResult TunerHidlTest::tuneFrontend(int32_t frontendId) { - if (createFrontend(frontendId) == ::testing::AssertionFailure()) { - return ::testing::AssertionFailure(); - } +AssertionResult TunerHidlTest::stopScanFrontend() { + EXPECT_TRUE(mFrontend) << "Test with openFrontend first."; + Result status; + status = mFrontend->stopScan(); + return AssertionResult(status == Result::SUCCESS); +} - // Frontend Settings for testing - FrontendSettings frontendSettings; - FrontendAtscSettings frontendAtscSettings{ - .frequency = 0, - .modulation = FrontendAtscModulation::UNDEFINED, - }; - frontendSettings.atsc(frontendAtscSettings); - mFrontendCallback->testOnEvent(mFrontend, frontendSettings); +AssertionResult TunerHidlTest::tuneFrontend(FrontendConfig config) { + EXPECT_TRUE(mFrontendCallback) + << "test with openFrontend/setFrontendCallback/getFrontendInfo first."; - FrontendDvbtSettings frontendDvbtSettings{ - .frequency = 0, - }; - frontendSettings.dvbt(frontendDvbtSettings); - mFrontendCallback->testOnEvent(mFrontend, frontendSettings); + EXPECT_TRUE(mFrontendInfo.type == config.type) + << "FrontendConfig does not match the frontend info of the given id."; - return ::testing::AssertionResult(true); + mFrontendCallback->tuneTestOnLock(mFrontend, config.settings); + return AssertionResult(true); } -::testing::AssertionResult TunerHidlTest::stopTuneFrontend(int32_t frontendId) { +AssertionResult TunerHidlTest::stopTuneFrontend() { + EXPECT_TRUE(mFrontend) << "Test with openFrontend first."; Result status; - if (!mFrontend && createFrontend(frontendId) == ::testing::AssertionFailure()) { - return ::testing::AssertionFailure(); - } - status = mFrontend->stopTune(); - return ::testing::AssertionResult(status == Result::SUCCESS); + return AssertionResult(status == Result::SUCCESS); } -::testing::AssertionResult TunerHidlTest::closeFrontend(int32_t frontendId) { +AssertionResult TunerHidlTest::closeFrontend() { + EXPECT_TRUE(mFrontend) << "Test with openFrontend first."; Result status; - if (!mFrontend && createFrontend(frontendId) == ::testing::AssertionFailure()) { - return ::testing::AssertionFailure(); - } - status = mFrontend->close(); mFrontend = nullptr; - return ::testing::AssertionResult(status == Result::SUCCESS); + mFrontendCallback = nullptr; + return AssertionResult(status == Result::SUCCESS); } +/*============================End Frontend APIs Tests Implementation============================*/ -::testing::AssertionResult TunerHidlTest::createDemux() { +/*::testing::AssertionResult TunerHidlTest::createDemux() { Result status; mService->openDemux([&](Result result, uint32_t demuxId, const sp& demux) { @@ -984,16 +1089,16 @@ class TunerHidlTest : public testing::TestWithParam { } break; case DemuxFilterMainType::MMTP: - /*mmtpSettings*/ + \/\*mmtpSettings\*\/ break; case DemuxFilterMainType::IP: - /*ipSettings*/ + \/\*ipSettings\*\/ break; case DemuxFilterMainType::TLV: - /*tlvSettings*/ + \/\*tlvSettings\*\/ break; case DemuxFilterMainType::ALP: - /*alpSettings*/ + \/\*alpSettings\*\/ break; default: break; @@ -1023,7 +1128,7 @@ class TunerHidlTest : public testing::TestWithParam { ::testing::AssertionResult TunerHidlTest::playbackDataFlowTest( vector filterConf, PlaybackConf playbackConf, - vector /*goldenOutputFiles*/) { + vector \/\*goldenOutputFiles\*\/) { Result status; int filterIdsSize; // Filter Configuration Module @@ -1087,7 +1192,7 @@ class TunerHidlTest : public testing::TestWithParam { } ::testing::AssertionResult TunerHidlTest::broadcastDataFlowTest( - vector filterConf, vector /*goldenOutputFiles*/) { + vector filterConf, vector \/\*goldenOutputFiles\*\/) { Result status; hidl_vec feIds; @@ -1155,9 +1260,8 @@ class TunerHidlTest : public testing::TestWithParam { ::testing::AssertionResult TunerHidlTest::recordDataFlowTest(vector filterConf, RecordSettings recordSetting, - vector /*goldenOutputFiles*/) { - Result status; - hidl_vec feIds; + vector +\/\*goldenOutputFiles\*\/) { Result status; hidl_vec feIds; mService->getFrontendIds([&](Result result, const hidl_vec& frontendIds) { status = result; @@ -1227,92 +1331,71 @@ class TunerHidlTest : public testing::TestWithParam { mFilterCallbacks.clear(); mFilters.clear(); return closeDemux(); +}*/ +/******************************** End Test Implementation**********************************/ + +/******************************** Start Test Entry**********************************/ +/*============================Start Frontend Tests============================*/ +TEST_P(TunerHidlTest, getFrontendIds) { + description("Get Frontend ids and verify frontends exist"); + ASSERT_TRUE(getFrontendIds()); + ASSERT_TRUE(mFeIds.size() > 0); } -/* - * API STATUS TESTS - */ -TEST_P(TunerHidlTest, CreateFrontend) { - Result status; - hidl_vec feIds; - - description("Create Frontends"); - mService->getFrontendIds([&](Result result, const hidl_vec& frontendIds) { - status = result; - feIds = frontendIds; - }); - - if (feIds.size() == 0) { - ALOGW("[ WARN ] Frontend isn't available"); - return; - } +TEST_P(TunerHidlTest, openFrontend) { + description("Open all the existing Frontends and close them"); + ASSERT_TRUE(getFrontendIds()); + ASSERT_TRUE(mFeIds.size() > 0); - for (size_t i = 0; i < feIds.size(); i++) { - ASSERT_TRUE(createFrontend(feIds[i])); + for (size_t i = 0; i < mFeIds.size(); i++) { + ASSERT_TRUE(openFrontend(mFeIds[i])); + ASSERT_TRUE(closeFrontend()); } } TEST_P(TunerHidlTest, TuneFrontend) { - Result status; - hidl_vec feIds; - - description("Tune Frontends and check callback onEvent"); - mService->getFrontendIds([&](Result result, const hidl_vec& frontendIds) { - status = result; - feIds = frontendIds; - }); - - if (feIds.size() == 0) { - ALOGW("[ WARN ] Frontend isn't available"); - return; - } - - for (size_t i = 0; i < feIds.size(); i++) { - ASSERT_TRUE(tuneFrontend(feIds[i])); - } -} - -TEST_P(TunerHidlTest, StopTuneFrontend) { - Result status; - hidl_vec feIds; - - description("stopTune Frontends"); - mService->getFrontendIds([&](Result result, const hidl_vec& frontendIds) { - status = result; - feIds = frontendIds; - }); - - if (feIds.size() == 0) { - ALOGW("[ WARN ] Frontend isn't available"); - return; - } - - for (size_t i = 0; i < feIds.size(); i++) { - ASSERT_TRUE(stopTuneFrontend(feIds[i])); + description("Tune one Frontend with specific setting and check Lock event"); + ASSERT_TRUE(getFrontendIds()); + ASSERT_TRUE(mFeIds.size() > 0); + ALOGW("[vts] expected Frontend type is %d", frontendArray[0].type); + for (size_t i = 0; i < mFeIds.size(); i++) { + ASSERT_TRUE(getFrontendInfo(mFeIds[i])); + ALOGW("[vts] Frontend type is %d", mFrontendInfo.type); + if (mFrontendInfo.type != frontendArray[0].type) { + continue; + } + ASSERT_TRUE(openFrontend(mFeIds[i])); + ASSERT_TRUE(setFrontendCallback()); + ASSERT_TRUE(stopTuneFrontend()); + ASSERT_TRUE(tuneFrontend(frontendArray[0])); + ASSERT_TRUE(stopTuneFrontend()); + ASSERT_TRUE(closeFrontend()); + break; } } -TEST_P(TunerHidlTest, CloseFrontend) { - Result status; - hidl_vec feIds; - - description("Close Frontends"); - mService->getFrontendIds([&](Result result, const hidl_vec& frontendIds) { - status = result; - feIds = frontendIds; - }); +TEST_P(TunerHidlTest, AutoScanFrontend) { + description("Run an auto frontend scan with specific setting and check lock scanMessage"); + ASSERT_TRUE(getFrontendIds()); + ASSERT_TRUE(mFeIds.size() > 0); - if (feIds.size() == 0) { - ALOGW("[ WARN ] Frontend isn't available"); - return; - } - - for (size_t i = 0; i < feIds.size(); i++) { - ASSERT_TRUE(closeFrontend(feIds[i])); + for (size_t i = 0; i < mFeIds.size(); i++) { + ASSERT_TRUE(getFrontendInfo(mFeIds[i])); + if (mFrontendInfo.type != frontendArray[0].type) { + continue; + } + ASSERT_TRUE(openFrontend(mFeIds[i])); + ASSERT_TRUE(setFrontendCallback()); + ASSERT_TRUE(stopScanFrontend()); + ASSERT_TRUE(scanFrontend(frontendScanArray[0], FrontendScanType::SCAN_AUTO)); + ASSERT_TRUE(stopScanFrontend()); + ASSERT_TRUE(closeFrontend()); + break; } } +/*============================End Frontend Tests============================*/ -TEST_P(TunerHidlTest, CreateDemuxWithFrontend) { +/*TEST_P(TunerHidlTest, CreateDemuxWithFrontend) { Result status; hidl_vec feIds; @@ -1357,7 +1440,7 @@ TEST_P(TunerHidlTest, CreateDescrambler) { TEST_P(TunerHidlTest, CloseDescrambler) { description("Close Descrambler"); ASSERT_TRUE(closeDescrambler()); -} +}*/ /* * DATA FLOW TESTS @@ -1474,7 +1557,7 @@ TEST_P(TunerHidlTest, RecordDataFlowWithTsRecordFilterTest) { ASSERT_TRUE(recordDataFlowTest(filterConf, recordSetting, goldenOutputFiles)); }*/ - +/******************************** End Test Entry**********************************/ } // namespace INSTANTIATE_TEST_SUITE_P( diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h new file mode 100644 index 0000000000..55ca8579fb --- /dev/null +++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h @@ -0,0 +1,137 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using android::hardware::tv::tuner::V1_0::DemuxFilterEvent; +using android::hardware::tv::tuner::V1_0::DemuxFilterMainType; +using android::hardware::tv::tuner::V1_0::DemuxFilterPesDataSettings; +using android::hardware::tv::tuner::V1_0::DemuxFilterPesEvent; +using android::hardware::tv::tuner::V1_0::DemuxFilterRecordSettings; +using android::hardware::tv::tuner::V1_0::DemuxFilterSectionEvent; +using android::hardware::tv::tuner::V1_0::DemuxFilterSectionSettings; +using android::hardware::tv::tuner::V1_0::DemuxFilterSettings; +using android::hardware::tv::tuner::V1_0::DemuxFilterStatus; +using android::hardware::tv::tuner::V1_0::DemuxFilterType; +using android::hardware::tv::tuner::V1_0::DemuxQueueNotifyBits; +using android::hardware::tv::tuner::V1_0::DemuxTpid; +using android::hardware::tv::tuner::V1_0::DemuxTsFilterSettings; +using android::hardware::tv::tuner::V1_0::DemuxTsFilterType; +using android::hardware::tv::tuner::V1_0::FrontendDvbtBandwidth; +using android::hardware::tv::tuner::V1_0::FrontendDvbtCoderate; +using android::hardware::tv::tuner::V1_0::FrontendDvbtConstellation; +using android::hardware::tv::tuner::V1_0::FrontendDvbtGuardInterval; +using android::hardware::tv::tuner::V1_0::FrontendDvbtHierarchy; +using android::hardware::tv::tuner::V1_0::FrontendDvbtSettings; +using android::hardware::tv::tuner::V1_0::FrontendDvbtStandard; +using android::hardware::tv::tuner::V1_0::FrontendDvbtTransmissionMode; +using android::hardware::tv::tuner::V1_0::FrontendSettings; +using android::hardware::tv::tuner::V1_0::FrontendType; + +namespace { + +#define frontend_transponders_count 1 +#define channels_count 1 +#define frontend_scan_count 1 +#define filter_count 2 + +struct FilterConfig { + DemuxFilterType type; + DemuxFilterSettings setting; +}; + +struct FrontendConfig { + FrontendType type; + FrontendSettings settings; +}; + +struct ChannelConfig { + int32_t frontendId; + int32_t channelId; + std::string channelName; + DemuxTpid videoPid; + DemuxTpid audioPid; +}; + +static FrontendConfig frontendArray[frontend_transponders_count]; +static FrontendConfig frontendScanArray[channels_count]; +static ChannelConfig channelArray[frontend_scan_count]; +static FilterConfig filterArray[filter_count]; +static vector goldenOutputFiles; + +/** Configuration array for the frontend tune test */ +inline void initFrontendConfig() { + FrontendDvbtSettings dvbtSettings{ + .frequency = 578000, + .transmissionMode = FrontendDvbtTransmissionMode::AUTO, + .bandwidth = FrontendDvbtBandwidth::BANDWIDTH_8MHZ, + .constellation = FrontendDvbtConstellation::AUTO, + .hierarchy = FrontendDvbtHierarchy::AUTO, + .hpCoderate = FrontendDvbtCoderate::AUTO, + .lpCoderate = FrontendDvbtCoderate::AUTO, + .guardInterval = FrontendDvbtGuardInterval::AUTO, + .isHighPriority = true, + .standard = FrontendDvbtStandard::T, + }; + frontendArray[0].type = FrontendType::DVBT, frontendArray[0].settings.dvbt(dvbtSettings); +}; + +/** Configuration array for the frontend scan test */ +inline void initFrontendScanConfig() { + frontendScanArray[0].type = FrontendType::DVBT, frontendScanArray[0].settings.dvbt({ + .frequency = 577000, + }); +}; + +/** Configuration array for the filter test */ +inline void initFilterConfig() { + // TS Video filter setting + filterArray[0].type.mainType = DemuxFilterMainType::TS; + filterArray[0].type.subType.tsFilterType(DemuxTsFilterType::VIDEO); + filterArray[0].setting.ts().tpid = 49; + filterArray[0].setting.ts().filterSettings.av({.isPassthrough = false}); + // TS PES filter setting + filterArray[1].type.mainType = DemuxFilterMainType::TS; + filterArray[1].type.subType.tsFilterType(DemuxTsFilterType::PES); + filterArray[1].setting.ts().tpid = 256; + filterArray[1].setting.ts().filterSettings.pesData({ + .isRaw = true, + .streamId = 0xbd, + }); +}; + +} // namespace \ No newline at end of file -- GitLab From dd08190510627e08b745809d2efea72ed9a84c9e Mon Sep 17 00:00:00 2001 From: Amy Date: Thu, 6 Feb 2020 16:19:04 -0800 Subject: [PATCH 002/790] Refactor Tuner vts test Demux part Test: cuttlefish + vendor device test Bug: 135708935 Change-Id: I7e8e14809975854d6c88819a40819227a187a5a1 --- .../VtsHalTvTunerV1_0TargetTest.cpp | 104 +++++++----------- 1 file changed, 37 insertions(+), 67 deletions(-) diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp index 1b4929b37e..53ab2ce3d2 100644 --- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp +++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp @@ -760,16 +760,16 @@ class TunerHidlTest : public testing::TestWithParam { AssertionResult stopTuneFrontend(); AssertionResult closeFrontend(); - ::testing::AssertionResult createDemux(); - ::testing::AssertionResult createDemuxWithFrontend(int32_t frontendId, - FrontendSettings settings); + AssertionResult openDemux(); + AssertionResult setDemuxFrontendDataSource(uint32_t frontendId); + AssertionResult closeDemux(); + ::testing::AssertionResult getPlaybackMQDescriptor(); ::testing::AssertionResult addPlaybackToDemux(PlaybackSettings setting); ::testing::AssertionResult getRecordMQDescriptor(); ::testing::AssertionResult addRecordToDemux(RecordSettings setting); ::testing::AssertionResult addFilterToDemux(DemuxFilterType type, DemuxFilterSettings setting); ::testing::AssertionResult getFilterMQDescriptor(); - ::testing::AssertionResult closeDemux(); ::testing::AssertionResult createDescrambler(); ::testing::AssertionResult closeDescrambler(); @@ -864,48 +864,33 @@ AssertionResult TunerHidlTest::closeFrontend() { } /*============================End Frontend APIs Tests Implementation============================*/ -/*::testing::AssertionResult TunerHidlTest::createDemux() { +/*============================Start Demux APIs Tests Implementation============================*/ +AssertionResult TunerHidlTest::openDemux() { Result status; - mService->openDemux([&](Result result, uint32_t demuxId, const sp& demux) { mDemux = demux; mDemuxId = demuxId; status = result; }); - return ::testing::AssertionResult(status == Result::SUCCESS); + return AssertionResult(status == Result::SUCCESS); } -::testing::AssertionResult TunerHidlTest::createDemuxWithFrontend(int32_t frontendId, - FrontendSettings settings) { - Result status; - - if (!mDemux && createDemux() == ::testing::AssertionFailure()) { - return ::testing::AssertionFailure(); - } - - if (!mFrontend && createFrontend(frontendId) == ::testing::AssertionFailure()) { - return ::testing::AssertionFailure(); - } - - mFrontendCallback->testOnEvent(mFrontend, settings); - - status = mDemux->setFrontendDataSource(frontendId); - - return ::testing::AssertionResult(status == Result::SUCCESS); +AssertionResult TunerHidlTest::setDemuxFrontendDataSource(uint32_t frontendId) { + EXPECT_TRUE(mDemux) << "Test with openDemux first."; + EXPECT_TRUE(mFrontend) << "Test with openFrontend first."; + auto status = mDemux->setFrontendDataSource(frontendId); + return AssertionResult(status.isOk()); } -::testing::AssertionResult TunerHidlTest::closeDemux() { - Result status; - if (!mDemux && createDemux() == ::testing::AssertionFailure()) { - return ::testing::AssertionFailure(); - } - - status = mDemux->close(); +AssertionResult TunerHidlTest::closeDemux() { + EXPECT_TRUE(mDemux) << "Test with openDemux first."; + auto status = mDemux->close(); mDemux = nullptr; - return ::testing::AssertionResult(status == Result::SUCCESS); + return AssertionResult(status.isOk()); } +/*============================End Demux APIs Tests Implementation============================*/ -::testing::AssertionResult TunerHidlTest::createDescrambler() { +/*::testing::AssertionResult TunerHidlTest::createDescrambler() { Result status; mService->openDescrambler([&](Result result, const sp& descrambler) { @@ -1395,44 +1380,29 @@ TEST_P(TunerHidlTest, AutoScanFrontend) { } /*============================End Frontend Tests============================*/ -/*TEST_P(TunerHidlTest, CreateDemuxWithFrontend) { - Result status; - hidl_vec feIds; - - description("Create Demux with Frontend"); - mService->getFrontendIds([&](Result result, const hidl_vec& frontendIds) { - status = result; - feIds = frontendIds; - }); - - if (feIds.size() == 0) { - ALOGW("[ WARN ] Frontend isn't available"); - return; - } - - FrontendDvbtSettings dvbt{ - .frequency = 1000, - }; - FrontendSettings settings; - settings.dvbt(dvbt); +/*============================Start Demux Tests============================*/ +TEST_P(TunerHidlTest, OpenDemuxWithFrontendDataSource) { + description("Open Demux with a Frontend as its data source."); + ASSERT_TRUE(getFrontendIds()); + ASSERT_TRUE(mFeIds.size() > 0); - for (size_t i = 0; i < feIds.size(); i++) { - ASSERT_TRUE(createDemuxWithFrontend(feIds[i], settings)); - mFrontend->stopTune(); + for (size_t i = 0; i < mFeIds.size(); i++) { + ASSERT_TRUE(getFrontendInfo(mFeIds[i])); + if (mFrontendInfo.type != frontendArray[0].type) { + continue; + } + ASSERT_TRUE(openFrontend(mFeIds[i])); + ASSERT_TRUE(setFrontendCallback()); + ASSERT_TRUE(openDemux()); + ASSERT_TRUE(setDemuxFrontendDataSource(mFeIds[i])); + ASSERT_TRUE(closeDemux()); + ASSERT_TRUE(closeFrontend()); + break; } } +/*============================End Demux Tests============================*/ -TEST_P(TunerHidlTest, CreateDemux) { - description("Create Demux"); - ASSERT_TRUE(createDemux()); -} - -TEST_P(TunerHidlTest, CloseDemux) { - description("Close Demux"); - ASSERT_TRUE(closeDemux()); -} - -TEST_P(TunerHidlTest, CreateDescrambler) { +/*TEST_P(TunerHidlTest, CreateDescrambler) { description("Create Descrambler"); ASSERT_TRUE(createDescrambler()); } -- GitLab From 6fbe5d77d744e83b3abd5819a73bc6412efd0458 Mon Sep 17 00:00:00 2001 From: Amy Date: Thu, 6 Feb 2020 18:09:31 -0800 Subject: [PATCH 003/790] Refactor Tuner VTS filter part Test: cuttlefish + vendor device Bug: 135708935 Change-Id: I77b86da48720fa117d5afd273c3b157ddd650e10 --- .../VtsHalTvTunerV1_0TargetTest.cpp | 360 +++++++++++------- 1 file changed, 232 insertions(+), 128 deletions(-) diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp index 53ab2ce3d2..5fb817eecd 100644 --- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp +++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp @@ -155,14 +155,9 @@ const std::vector goldenDataOutputBuffer{ // const uint16_t FMQ_SIZE_4K = 0x1000; // const uint32_t FMQ_SIZE_1M = 0x100000; -// const uint32_t FMQ_SIZE_16M = 0x1000000; +const uint32_t FMQ_SIZE_16M = 0x1000000; const uint8_t FRONTEND_EVENT_CALLBACK_WAIT_COUNT = 4; -struct FilterConf { - DemuxFilterType type; - DemuxFilterSettings setting; -}; - enum FilterEventType : uint8_t { UNDEFINED, SECTION, @@ -303,7 +298,7 @@ class FilterCallback : public IFilterCallback { android::Mutex::Autolock autoLock(mMsgLock); // Temprarily we treat the first coming back filter data on the matching pid a success // once all of the MQ are cleared, means we got all the expected output - mFilterIdToEvent = filterEvent; + mFilterEvent = filterEvent; readFilterEventData(); mPidFilterOutputCount++; // mFilterIdToMQ.erase(filterEvent.filterId); @@ -342,9 +337,9 @@ class FilterCallback : public IFilterCallback { uint32_t mFilterId; FilterEventType mFilterEventType; - std::unique_ptr mFilterIdToMQ; - EventFlag* mFilterIdToMQEventFlag; - DemuxFilterEvent mFilterIdToEvent; + std::unique_ptr mFilterMQ; + EventFlag* mFilterMQEventFlag; + DemuxFilterEvent mFilterEvent; android::Mutex mMsgLock; android::Mutex mFilterOutputLock; @@ -379,10 +374,10 @@ void FilterCallback::testFilterDataOutput() { } void FilterCallback::updateFilterMQ(MQDesc& filterMQDescriptor) { - mFilterIdToMQ = std::make_unique(filterMQDescriptor, true /* resetPointers */); - EXPECT_TRUE(mFilterIdToMQ); - EXPECT_TRUE(EventFlag::createEventFlag(mFilterIdToMQ->getEventFlagWord(), - &mFilterIdToMQEventFlag) == android::OK); + mFilterMQ = std::make_unique(filterMQDescriptor, true /* resetPointers */); + EXPECT_TRUE(mFilterMQ); + EXPECT_TRUE(EventFlag::createEventFlag(mFilterMQ->getEventFlagWord(), &mFilterMQEventFlag) == + android::OK); } void FilterCallback::updateGoldenOutputMap(string goldenOutputFile) { @@ -398,7 +393,7 @@ void* FilterCallback::__threadLoopFilter(void* threadArgs) { void FilterCallback::filterThreadLoop(DemuxFilterEvent& /* event */) { android::Mutex::Autolock autoLock(mFilterOutputLock); - // Read from mFilterIdToMQ[event.filterId] per event and filter type + // Read from mFilterMQ[event.filterId] per event and filter type // Assemble to filterOutput[filterId] @@ -411,7 +406,7 @@ void FilterCallback::filterThreadLoop(DemuxFilterEvent& /* event */) { bool FilterCallback::readFilterEventData() { bool result = false; - DemuxFilterEvent filterEvent = mFilterIdToEvent; + DemuxFilterEvent filterEvent = mFilterEvent; ALOGW("[vts] reading from filter FMQ %d", mFilterId); // todo separate filter handlers for (int i = 0; i < filterEvent.events.size(); i++) { @@ -423,6 +418,7 @@ bool FilterCallback::readFilterEventData() { mDataLength = filterEvent.events[i].pes().dataLength; break; case FilterEventType::MEDIA: + mDataLength = filterEvent.events[i].media().dataLength; break; case FilterEventType::RECORD: break; @@ -437,14 +433,14 @@ bool FilterCallback::readFilterEventData() { // match"; mDataOutputBuffer.resize(mDataLength); - result = mFilterIdToMQ->read(mDataOutputBuffer.data(), mDataLength); + result = mFilterMQ->read(mDataOutputBuffer.data(), mDataLength); EXPECT_TRUE(result) << "can't read from Filter MQ"; /*for (int i = 0; i < mDataLength; i++) { EXPECT_TRUE(goldenDataOutputBuffer[i] == mDataOutputBuffer[i]) << "data does not match"; }*/ } - mFilterIdToMQEventFlag->wake(static_cast(DemuxQueueNotifyBits::DATA_CONSUMED)); + mFilterMQEventFlag->wake(static_cast(DemuxQueueNotifyBits::DATA_CONSUMED)); return result; } /******************************** End FilterCallback **********************************/ @@ -513,11 +509,10 @@ class DvrCallback : public IDvrCallback { uint16_t mDataLength = 0; std::vector mDataOutputBuffer; - std::map> mFilterIdToMQ; + std::map> mFilterMQ; std::unique_ptr mPlaybackMQ; std::unique_ptr mRecordMQ; - std::map mFilterIdToMQEventFlag; - std::map mFilterIdToEvent; + std::map mFilterMQEventFlag; android::Mutex mMsgLock; android::Mutex mPlaybackThreadLock; @@ -745,7 +740,7 @@ class TunerHidlTest : public testing::TestWithParam { hidl_vec mFeIds; uint32_t mDemuxId; - uint32_t mFilterId; + uint32_t mFilterId = -1; pthread_t mPlaybackshread; bool mPlaybackThreadRunning; @@ -764,23 +759,31 @@ class TunerHidlTest : public testing::TestWithParam { AssertionResult setDemuxFrontendDataSource(uint32_t frontendId); AssertionResult closeDemux(); + AssertionResult openFilterInDemux(DemuxFilterType type); + AssertionResult getNewlyOpenedFilterId(uint32_t& filterId); + AssertionResult configFilter(DemuxFilterSettings setting, uint32_t filterId); + AssertionResult getFilterMQDescriptor(uint32_t filterId); + AssertionResult startFilter(uint32_t filterId); + AssertionResult stopFilter(uint32_t filterId); + AssertionResult closeFilter(uint32_t filterId); + ::testing::AssertionResult getPlaybackMQDescriptor(); ::testing::AssertionResult addPlaybackToDemux(PlaybackSettings setting); ::testing::AssertionResult getRecordMQDescriptor(); ::testing::AssertionResult addRecordToDemux(RecordSettings setting); - ::testing::AssertionResult addFilterToDemux(DemuxFilterType type, DemuxFilterSettings setting); - ::testing::AssertionResult getFilterMQDescriptor(); ::testing::AssertionResult createDescrambler(); ::testing::AssertionResult closeDescrambler(); - ::testing::AssertionResult playbackDataFlowTest(vector filterConf, + ::testing::AssertionResult playbackDataFlowTest(vector filterConf, PlaybackConf playbackConf, vector goldenOutputFiles); - ::testing::AssertionResult recordDataFlowTest(vector filterConf, + ::testing::AssertionResult recordDataFlowTest(vector filterConf, RecordSettings recordSetting, vector goldenOutputFiles); - ::testing::AssertionResult broadcastDataFlowTest(vector filterConf, + ::testing::AssertionResult broadcastDataFlowTest(vector filterConf, vector goldenOutputFiles); + + FilterEventType getFilterEventType(DemuxFilterType type); }; /*============================Start Frontend APIs Tests Implementation============================*/ @@ -888,8 +891,106 @@ AssertionResult TunerHidlTest::closeDemux() { mDemux = nullptr; return AssertionResult(status.isOk()); } + +AssertionResult TunerHidlTest::openFilterInDemux(DemuxFilterType type) { + Result status; + EXPECT_TRUE(mDemux) << "Test with openDemux first."; + + // Create demux callback + mFilterCallback = new FilterCallback(); + + // Add filter to the local demux + mDemux->openFilter(type, FMQ_SIZE_16M, mFilterCallback, + [&](Result result, const sp& filter) { + mFilter = filter; + status = result; + }); + + if (status == Result::SUCCESS) { + mFilterCallback->setFilterEventType(getFilterEventType(type)); + } + + return AssertionResult(status == Result::SUCCESS); +} /*============================End Demux APIs Tests Implementation============================*/ +/*============================Start Filter APIs Tests Implementation============================*/ +AssertionResult TunerHidlTest::getNewlyOpenedFilterId(uint32_t& filterId) { + Result status; + EXPECT_TRUE(mDemux) << "Test with openDemux first."; + EXPECT_TRUE(mFilter) << "Test with openFilterInDemux first."; + EXPECT_TRUE(mFilterCallback) << "Test with openFilterInDemux first."; + + mFilter->getId([&](Result result, uint32_t filterId) { + mFilterId = filterId; + status = result; + }); + + if (status == Result::SUCCESS) { + mFilterCallback->setFilterId(mFilterId); + mUsedFilterIds.insert(mUsedFilterIds.end(), mFilterId); + mFilters[mFilterId] = mFilter; + mFilterCallbacks[mFilterId] = mFilterCallback; + filterId = mFilterId; + } + + return AssertionResult(status == Result::SUCCESS || status == Result::UNAVAILABLE); +} + +AssertionResult TunerHidlTest::configFilter(DemuxFilterSettings setting, uint32_t filterId) { + Result status; + EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first."; + status = mFilters[filterId]->configure(setting); + + return AssertionResult(status == Result::SUCCESS); +} + +AssertionResult TunerHidlTest::getFilterMQDescriptor(uint32_t filterId) { + Result status; + EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first."; + EXPECT_TRUE(mFilterCallbacks[filterId]) << "Test with getNewlyOpenedFilterId first."; + + mFilter->getQueueDesc([&](Result result, const MQDesc& filterMQDesc) { + mFilterMQDescriptor = filterMQDesc; + status = result; + }); + + if (status == Result::SUCCESS) { + mFilterCallbacks[filterId]->updateFilterMQ(mFilterMQDescriptor); + } + + return AssertionResult(status == Result::SUCCESS); +} + +AssertionResult TunerHidlTest::startFilter(uint32_t filterId) { + EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first."; + Result status = mFilters[filterId]->start(); + return AssertionResult(status == Result::SUCCESS); +} + +AssertionResult TunerHidlTest::stopFilter(uint32_t filterId) { + EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first."; + Result status = mFilters[filterId]->stop(); + return AssertionResult(status == Result::SUCCESS); +} + +AssertionResult TunerHidlTest::closeFilter(uint32_t filterId) { + EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first."; + Result status = mFilters[filterId]->close(); + if (status == Result::SUCCESS) { + for (int i = 0; i < mUsedFilterIds.size(); i++) { + if (mUsedFilterIds[i] == filterId) { + mUsedFilterIds.erase(mUsedFilterIds.begin() + i); + break; + } + } + mFilterCallbacks.erase(filterId); + mFilters.erase(filterId); + } + return AssertionResult(status == Result::SUCCESS); +} +/*============================End Filter APIs Tests Implementation============================*/ + /*::testing::AssertionResult TunerHidlTest::createDescrambler() { Result status; @@ -1012,105 +1113,6 @@ AssertionResult TunerHidlTest::closeDemux() { return ::testing::AssertionResult(status == Result::SUCCESS); } -::testing::AssertionResult TunerHidlTest::addFilterToDemux(DemuxFilterType type, - DemuxFilterSettings setting) { - Result status; - - if (!mDemux && createDemux() == ::testing::AssertionFailure()) { - return ::testing::AssertionFailure(); - } - - // Create demux callback - mFilterCallback = new FilterCallback(); - - // Add filter to the local demux - mDemux->openFilter(type, FMQ_SIZE_16M, mFilterCallback, - [&](Result result, const sp& filter) { - mFilter = filter; - status = result; - }); - - if (status != Result::SUCCESS) { - return ::testing::AssertionFailure(); - } - - mFilter->getId([&](Result result, uint32_t filterId) { - mFilterId = filterId; - status = result; - }); - - if (status != Result::SUCCESS) { - return ::testing::AssertionFailure(); - } - - mFilterCallback->setFilterId(mFilterId); - - FilterEventType eventType = FilterEventType::UNDEFINED; - switch (type.mainType) { - case DemuxFilterMainType::TS: - switch (type.subType.tsFilterType()) { - case DemuxTsFilterType::UNDEFINED: - break; - case DemuxTsFilterType::SECTION: - eventType = FilterEventType::SECTION; - break; - case DemuxTsFilterType::PES: - eventType = FilterEventType::PES; - break; - case DemuxTsFilterType::TS: - break; - case DemuxTsFilterType::AUDIO: - case DemuxTsFilterType::VIDEO: - eventType = FilterEventType::MEDIA; - break; - case DemuxTsFilterType::PCR: - break; - case DemuxTsFilterType::RECORD: - eventType = FilterEventType::RECORD; - break; - case DemuxTsFilterType::TEMI: - eventType = FilterEventType::TEMI; - break; - } - break; - case DemuxFilterMainType::MMTP: - \/\*mmtpSettings\*\/ - break; - case DemuxFilterMainType::IP: - \/\*ipSettings\*\/ - break; - case DemuxFilterMainType::TLV: - \/\*tlvSettings\*\/ - break; - case DemuxFilterMainType::ALP: - \/\*alpSettings\*\/ - break; - default: - break; - } - mFilterCallback->setFilterEventType(eventType); - - // Configure the filter - status = mFilter->configure(setting); - - return ::testing::AssertionResult(status == Result::SUCCESS); -} - -::testing::AssertionResult TunerHidlTest::getFilterMQDescriptor() { - Result status; - - if (!mDemux || !mFilter) { - return ::testing::AssertionFailure(); - } - - mFilter->getQueueDesc([&](Result result, const MQDesc& filterMQDesc) { - mFilterMQDescriptor = filterMQDesc; - status = result; - }); - - return ::testing::AssertionResult(status == Result::SUCCESS); -} - ::testing::AssertionResult TunerHidlTest::playbackDataFlowTest( vector filterConf, PlaybackConf playbackConf, vector \/\*goldenOutputFiles\*\/) { @@ -1317,6 +1319,56 @@ AssertionResult TunerHidlTest::closeDemux() { mFilters.clear(); return closeDemux(); }*/ +/*============================End Data Flow Tests Implementation============================*/ + +/*============================Start Helper Functions============================*/ +FilterEventType TunerHidlTest::getFilterEventType(DemuxFilterType type) { + FilterEventType eventType = FilterEventType::UNDEFINED; + switch (type.mainType) { + case DemuxFilterMainType::TS: + switch (type.subType.tsFilterType()) { + case DemuxTsFilterType::UNDEFINED: + break; + case DemuxTsFilterType::SECTION: + eventType = FilterEventType::SECTION; + break; + case DemuxTsFilterType::PES: + eventType = FilterEventType::PES; + break; + case DemuxTsFilterType::TS: + break; + case DemuxTsFilterType::AUDIO: + case DemuxTsFilterType::VIDEO: + eventType = FilterEventType::MEDIA; + break; + case DemuxTsFilterType::PCR: + break; + case DemuxTsFilterType::RECORD: + eventType = FilterEventType::RECORD; + break; + case DemuxTsFilterType::TEMI: + eventType = FilterEventType::TEMI; + break; + } + break; + case DemuxFilterMainType::MMTP: + /*mmtpSettings*/ + break; + case DemuxFilterMainType::IP: + /*ipSettings*/ + break; + case DemuxFilterMainType::TLV: + /*tlvSettings*/ + break; + case DemuxFilterMainType::ALP: + /*alpSettings*/ + break; + default: + break; + } + return eventType; +} +/*============================End Helper Functions============================*/ /******************************** End Test Implementation**********************************/ /******************************** Start Test Entry**********************************/ @@ -1380,7 +1432,7 @@ TEST_P(TunerHidlTest, AutoScanFrontend) { } /*============================End Frontend Tests============================*/ -/*============================Start Demux Tests============================*/ +/*============================Start Demux/Filter Tests============================*/ TEST_P(TunerHidlTest, OpenDemuxWithFrontendDataSource) { description("Open Demux with a Frontend as its data source."); ASSERT_TRUE(getFrontendIds()); @@ -1400,7 +1452,59 @@ TEST_P(TunerHidlTest, OpenDemuxWithFrontendDataSource) { break; } } -/*============================End Demux Tests============================*/ + +TEST_P(TunerHidlTest, OpenFilterInDemux) { + description("Open a filter in Demux."); + ASSERT_TRUE(getFrontendIds()); + ASSERT_TRUE(mFeIds.size() > 0); + + for (size_t i = 0; i < mFeIds.size(); i++) { + ASSERT_TRUE(getFrontendInfo(mFeIds[i])); + if (mFrontendInfo.type != frontendArray[0].type) { + continue; + } + ASSERT_TRUE(openFrontend(mFeIds[i])); + ASSERT_TRUE(setFrontendCallback()); + ASSERT_TRUE(openDemux()); + ASSERT_TRUE(setDemuxFrontendDataSource(mFeIds[i])); + ASSERT_TRUE(openFilterInDemux(filterArray[0].type)); + uint32_t filterId; + ASSERT_TRUE(getNewlyOpenedFilterId(filterId)); + ASSERT_TRUE(closeFilter(filterId)); + ASSERT_TRUE(closeDemux()); + ASSERT_TRUE(closeFrontend()); + break; + } +} + +TEST_P(TunerHidlTest, StartFilterInDemux) { + description("Open and start a filter in Demux."); + ASSERT_TRUE(getFrontendIds()); + ASSERT_TRUE(mFeIds.size() > 0); + + for (size_t i = 0; i < mFeIds.size(); i++) { + ASSERT_TRUE(getFrontendInfo(mFeIds[i])); + if (mFrontendInfo.type != frontendArray[0].type) { + continue; + } + ASSERT_TRUE(openFrontend(mFeIds[i])); + ASSERT_TRUE(setFrontendCallback()); + ASSERT_TRUE(openDemux()); + ASSERT_TRUE(setDemuxFrontendDataSource(mFeIds[i])); + ASSERT_TRUE(openFilterInDemux(filterArray[0].type)); + uint32_t filterId; + ASSERT_TRUE(getNewlyOpenedFilterId(filterId)); + ASSERT_TRUE(configFilter(filterArray[0].setting, filterId)); + ASSERT_TRUE(getFilterMQDescriptor(filterId)); + ASSERT_TRUE(startFilter(filterId)); + ASSERT_TRUE(stopFilter(filterId)); + ASSERT_TRUE(closeFilter(filterId)); + ASSERT_TRUE(closeDemux()); + ASSERT_TRUE(closeFrontend()); + break; + } +} +/*============================End Demux/Filter Tests============================*/ /*TEST_P(TunerHidlTest, CreateDescrambler) { description("Create Descrambler"); -- GitLab From 46f46cd931ac5270ebc5c12c526aa5c91202b337 Mon Sep 17 00:00:00 2001 From: Amy Date: Thu, 6 Feb 2020 19:00:29 -0800 Subject: [PATCH 004/790] Refactor Tuner VTS broadcast data flow test Test: cuttlefish + vendor device test Bug: 135708935 Change-Id: Ia7b6bf76c1f98202fb93ddf5d4f09c742e3f7c8b --- .../VtsHalTvTunerV1_0TargetTest.cpp | 156 ++++++------------ 1 file changed, 54 insertions(+), 102 deletions(-) diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp index 5fb817eecd..e8c80101ed 100644 --- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp +++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp @@ -767,6 +767,8 @@ class TunerHidlTest : public testing::TestWithParam { AssertionResult stopFilter(uint32_t filterId); AssertionResult closeFilter(uint32_t filterId); + AssertionResult broadcastDataFlowTest(vector goldenOutputFiles); + ::testing::AssertionResult getPlaybackMQDescriptor(); ::testing::AssertionResult addPlaybackToDemux(PlaybackSettings setting); ::testing::AssertionResult getRecordMQDescriptor(); @@ -780,8 +782,6 @@ class TunerHidlTest : public testing::TestWithParam { ::testing::AssertionResult recordDataFlowTest(vector filterConf, RecordSettings recordSetting, vector goldenOutputFiles); - ::testing::AssertionResult broadcastDataFlowTest(vector filterConf, - vector goldenOutputFiles); FilterEventType getFilterEventType(DemuxFilterType type); }; @@ -1111,9 +1111,26 @@ AssertionResult TunerHidlTest::closeFilter(uint32_t filterId) { }); return ::testing::AssertionResult(status == Result::SUCCESS); +}*/ + +/*============================Start Data Flow Tests Implementation============================*/ +AssertionResult TunerHidlTest::broadcastDataFlowTest(vector /*goldenOutputFiles*/) { + EXPECT_TRUE(mFrontend) << "Test with openFilterInDemux first."; + EXPECT_TRUE(mDemux) << "Test with openDemux first."; + EXPECT_TRUE(mFilterCallback) << "Test with getFilterMQDescriptor first."; + + // Data Verify Module + std::map>::iterator it; + for (it = mFilterCallbacks.begin(); it != mFilterCallbacks.end(); it++) { + it->second->testFilterDataOutput(); + } + return success(); } -::testing::AssertionResult TunerHidlTest::playbackDataFlowTest( +/* + * TODO: re-enable the tests after finalizing the test refactoring. + */ +/*::testing::AssertionResult TunerHidlTest::playbackDataFlowTest( vector filterConf, PlaybackConf playbackConf, vector \/\*goldenOutputFiles\*\/) { Result status; @@ -1178,73 +1195,6 @@ AssertionResult TunerHidlTest::closeFilter(uint32_t filterId) { return closeDemux(); } -::testing::AssertionResult TunerHidlTest::broadcastDataFlowTest( - vector filterConf, vector \/\*goldenOutputFiles\*\/) { - Result status; - hidl_vec feIds; - - mService->getFrontendIds([&](Result result, const hidl_vec& frontendIds) { - status = result; - feIds = frontendIds; - }); - - if (feIds.size() == 0) { - ALOGW("[ WARN ] Frontend isn't available"); - return ::testing::AssertionFailure(); - } - - FrontendDvbtSettings dvbt{ - .frequency = 1000, - }; - FrontendSettings settings; - settings.dvbt(dvbt); - - if (createDemuxWithFrontend(feIds[0], settings) != ::testing::AssertionSuccess()) { - return ::testing::AssertionFailure(); - } - - int filterIdsSize; - // Filter Configuration Module - for (int i = 0; i < filterConf.size(); i++) { - if (addFilterToDemux(filterConf[i].type, filterConf[i].setting) == - ::testing::AssertionFailure() || - // TODO use a map to save the FMQs/EvenFlags and pass to callback - getFilterMQDescriptor() == ::testing::AssertionFailure()) { - return ::testing::AssertionFailure(); - } - filterIdsSize = mUsedFilterIds.size(); - mUsedFilterIds.resize(filterIdsSize + 1); - mUsedFilterIds[filterIdsSize] = mFilterId; - mFilters[mFilterId] = mFilter; - mFilterCallbacks[mFilterId] = mFilterCallback; - mFilterCallback->updateFilterMQ(mFilterMQDescriptor); - status = mFilter->start(); - if (status != Result::SUCCESS) { - return ::testing::AssertionFailure(); - } - } - - // Data Verify Module - std::map>::iterator it; - for (it = mFilterCallbacks.begin(); it != mFilterCallbacks.end(); it++) { - it->second->testFilterDataOutput(); - } - - // Clean Up Module - for (int i = 0; i <= filterIdsSize; i++) { - if (mFilters[mUsedFilterIds[i]]->stop() != Result::SUCCESS) { - return ::testing::AssertionFailure(); - } - } - if (mFrontend->stopTune() != Result::SUCCESS) { - return ::testing::AssertionFailure(); - } - mUsedFilterIds.clear(); - mFilterCallbacks.clear(); - mFilters.clear(); - return closeDemux(); -} - ::testing::AssertionResult TunerHidlTest::recordDataFlowTest(vector filterConf, RecordSettings recordSetting, vector @@ -1516,9 +1466,41 @@ TEST_P(TunerHidlTest, CloseDescrambler) { ASSERT_TRUE(closeDescrambler()); }*/ +/*============================Start Data Flow Tests============================*/ +TEST_P(TunerHidlTest, BroadcastDataFlowWithAudioFilterTest) { + description("Open Demux with a Frontend as its data source."); + ASSERT_TRUE(getFrontendIds()); + ASSERT_TRUE(mFeIds.size() > 0); + + for (size_t i = 0; i < mFeIds.size(); i++) { + ASSERT_TRUE(getFrontendInfo(mFeIds[i])); + if (mFrontendInfo.type != frontendArray[0].type) { + continue; + } + ASSERT_TRUE(openFrontend(mFeIds[i])); + ASSERT_TRUE(setFrontendCallback()); + ASSERT_TRUE(openDemux()); + ASSERT_TRUE(setDemuxFrontendDataSource(mFeIds[i])); + ASSERT_TRUE(openFilterInDemux(filterArray[0].type)); + uint32_t filterId; + ASSERT_TRUE(getNewlyOpenedFilterId(filterId)); + ASSERT_TRUE(configFilter(filterArray[0].setting, filterId)); + ASSERT_TRUE(getFilterMQDescriptor(filterId)); + ASSERT_TRUE(startFilter(filterId)); + // tune test + ASSERT_TRUE(tuneFrontend(frontendArray[0])); + // broadcast data flow test + ASSERT_TRUE(broadcastDataFlowTest(goldenOutputFiles)); + ASSERT_TRUE(stopTuneFrontend()); + ASSERT_TRUE(stopFilter(filterId)); + ASSERT_TRUE(closeFilter(filterId)); + ASSERT_TRUE(closeDemux()); + ASSERT_TRUE(closeFrontend()); + break; + } +} + /* - * DATA FLOW TESTS - * * TODO: re-enable the tests after finalizing the testing stream. */ /*TEST_P(TunerHidlTest, PlaybackDataFlowWithSectionFilterTest) { @@ -1564,36 +1546,6 @@ TEST_P(TunerHidlTest, CloseDescrambler) { ASSERT_TRUE(playbackDataFlowTest(filterConf, playbackConf, goldenOutputFiles)); } -TEST_P(TunerHidlTest, BroadcastDataFlowWithPesFilterTest) { - description("Feed ts data from frontend and test with PES filter"); - - // todo modulize the filter conf parser - vector filterConf; - filterConf.resize(1); - - DemuxFilterSettings filterSetting; - DemuxTsFilterSettings tsFilterSetting{ - .tpid = 119, - }; - DemuxFilterPesDataSettings pesFilterSetting; - tsFilterSetting.filterSettings.pesData(pesFilterSetting); - filterSetting.ts(tsFilterSetting); - - DemuxFilterType type{ - .mainType = DemuxFilterMainType::TS, - }; - type.subType.tsFilterType(DemuxTsFilterType::PES); - FilterConf pesFilterConf{ - .type = type, - .setting = filterSetting, - }; - filterConf[0] = pesFilterConf; - - vector goldenOutputFiles; - - ASSERT_TRUE(broadcastDataFlowTest(filterConf, goldenOutputFiles)); -} - TEST_P(TunerHidlTest, RecordDataFlowWithTsRecordFilterTest) { description("Feed ts data from frontend to recording and test with ts record filter"); -- GitLab From fc7cc15ebb604022c935ccedde9613dcb1c7070a Mon Sep 17 00:00:00 2001 From: Amy Date: Thu, 6 Feb 2020 19:14:28 -0800 Subject: [PATCH 005/790] Refactor Tuner VTS dvr and descrambler test implementation Note that we are not testing them right now Test entry will be implemented or uncomment in next Tuner develop phase Test: cuttlefish + vendor device Bug: 135708935 Change-Id: Iea72bd54c85105f74133c67433bd51f8fd07f28d --- .../VtsHalTvTunerV1_0TargetTest.cpp | 241 +++++++----------- 1 file changed, 97 insertions(+), 144 deletions(-) diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp index e8c80101ed..f693e7cff9 100644 --- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp +++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp @@ -154,7 +154,7 @@ const std::vector goldenDataOutputBuffer{ }; // const uint16_t FMQ_SIZE_4K = 0x1000; -// const uint32_t FMQ_SIZE_1M = 0x100000; +const uint32_t FMQ_SIZE_1M = 0x100000; const uint32_t FMQ_SIZE_16M = 0x1000000; const uint8_t FRONTEND_EVENT_CALLBACK_WAIT_COUNT = 4; @@ -698,9 +698,9 @@ void DvrCallback::stopRecordThread() { mRecordThreadRunning = false; android::Mutex::Autolock autoLock(mRecordThreadLock); } -/******************************** End DvrCallback **********************************/ +/********************************** End DvrCallback ************************************/ -/******************************** Start Test Implementation**********************************/ +/***************************** Start Test Implementation ******************************/ class TunerHidlTest : public testing::TestWithParam { public: virtual void SetUp() override { @@ -734,7 +734,7 @@ class TunerHidlTest : public testing::TestWithParam { sp mFilterCallback; sp mDvrCallback; MQDesc mFilterMQDescriptor; - MQDesc mPlaybackMQDescriptor; + MQDesc mDvrMQDescriptor; MQDesc mRecordMQDescriptor; vector mUsedFilterIds; hidl_vec mFeIds; @@ -759,6 +759,10 @@ class TunerHidlTest : public testing::TestWithParam { AssertionResult setDemuxFrontendDataSource(uint32_t frontendId); AssertionResult closeDemux(); + AssertionResult openDvrInDemux(DvrType type); + AssertionResult configDvr(DvrSettings setting); + AssertionResult getDvrMQDescriptor(); + AssertionResult openFilterInDemux(DemuxFilterType type); AssertionResult getNewlyOpenedFilterId(uint32_t& filterId); AssertionResult configFilter(DemuxFilterSettings setting, uint32_t filterId); @@ -767,26 +771,20 @@ class TunerHidlTest : public testing::TestWithParam { AssertionResult stopFilter(uint32_t filterId); AssertionResult closeFilter(uint32_t filterId); - AssertionResult broadcastDataFlowTest(vector goldenOutputFiles); + AssertionResult createDescrambler(); + AssertionResult closeDescrambler(); - ::testing::AssertionResult getPlaybackMQDescriptor(); - ::testing::AssertionResult addPlaybackToDemux(PlaybackSettings setting); - ::testing::AssertionResult getRecordMQDescriptor(); - ::testing::AssertionResult addRecordToDemux(RecordSettings setting); - ::testing::AssertionResult createDescrambler(); - ::testing::AssertionResult closeDescrambler(); - - ::testing::AssertionResult playbackDataFlowTest(vector filterConf, - PlaybackConf playbackConf, - vector goldenOutputFiles); - ::testing::AssertionResult recordDataFlowTest(vector filterConf, - RecordSettings recordSetting, - vector goldenOutputFiles); + AssertionResult playbackDataFlowTest(vector filterConf, PlaybackConf playbackConf, + vector goldenOutputFiles); + AssertionResult recordDataFlowTest(vector filterConf, + RecordSettings recordSetting, + vector goldenOutputFiles); + AssertionResult broadcastDataFlowTest(vector goldenOutputFiles); FilterEventType getFilterEventType(DemuxFilterType type); }; -/*============================Start Frontend APIs Tests Implementation============================*/ +/*========================== Start Frontend APIs Tests Implementation ==========================*/ AssertionResult TunerHidlTest::getFrontendIds() { Result status; mService->getFrontendIds([&](Result result, const hidl_vec& frontendIds) { @@ -865,9 +863,9 @@ AssertionResult TunerHidlTest::closeFrontend() { mFrontendCallback = nullptr; return AssertionResult(status == Result::SUCCESS); } -/*============================End Frontend APIs Tests Implementation============================*/ +/*=========================== End Frontend APIs Tests Implementation ===========================*/ -/*============================Start Demux APIs Tests Implementation============================*/ +/*============================ Start Demux APIs Tests Implementation ============================*/ AssertionResult TunerHidlTest::openDemux() { Result status; mService->openDemux([&](Result result, uint32_t demuxId, const sp& demux) { @@ -912,9 +910,9 @@ AssertionResult TunerHidlTest::openFilterInDemux(DemuxFilterType type) { return AssertionResult(status == Result::SUCCESS); } -/*============================End Demux APIs Tests Implementation============================*/ +/*============================ End Demux APIs Tests Implementation ============================*/ -/*============================Start Filter APIs Tests Implementation============================*/ +/*=========================== Start Filter APIs Tests Implementation ===========================*/ AssertionResult TunerHidlTest::getNewlyOpenedFilterId(uint32_t& filterId) { Result status; EXPECT_TRUE(mDemux) << "Test with openDemux first."; @@ -989,131 +987,79 @@ AssertionResult TunerHidlTest::closeFilter(uint32_t filterId) { } return AssertionResult(status == Result::SUCCESS); } -/*============================End Filter APIs Tests Implementation============================*/ +/*=========================== End Filter APIs Tests Implementation ===========================*/ -/*::testing::AssertionResult TunerHidlTest::createDescrambler() { +/*======================== Start Descrambler APIs Tests Implementation ========================*/ +AssertionResult TunerHidlTest::createDescrambler() { Result status; - + EXPECT_TRUE(mDemux) << "Test with openDemux first."; mService->openDescrambler([&](Result result, const sp& descrambler) { mDescrambler = descrambler; status = result; }); if (status != Result::SUCCESS) { - return ::testing::AssertionFailure(); - } - - if (!mDemux && createDemux() == ::testing::AssertionFailure()) { - return ::testing::AssertionFailure(); + return failure(); } status = mDescrambler->setDemuxSource(mDemuxId); if (status != Result::SUCCESS) { - return ::testing::AssertionFailure(); + return failure(); } // Test if demux source can be set more than once. status = mDescrambler->setDemuxSource(mDemuxId); - return ::testing::AssertionResult(status == Result::INVALID_STATE); + return AssertionResult(status == Result::INVALID_STATE); } -::testing::AssertionResult TunerHidlTest::closeDescrambler() { +AssertionResult TunerHidlTest::closeDescrambler() { Result status; - if (!mDescrambler && createDescrambler() == ::testing::AssertionFailure()) { - return ::testing::AssertionFailure(); + if (!mDescrambler && createDescrambler() == failure()) { + return failure(); } status = mDescrambler->close(); mDescrambler = nullptr; - return ::testing::AssertionResult(status == Result::SUCCESS); + return AssertionResult(status == Result::SUCCESS); } +/*========================= End Descrambler APIs Tests Implementation =========================*/ -::testing::AssertionResult TunerHidlTest::addPlaybackToDemux(PlaybackSettings setting) { +/*============================ Start Dvr APIs Tests Implementation ============================*/ +AssertionResult TunerHidlTest::openDvrInDemux(DvrType type) { Result status; - - if (!mDemux && createDemux() == ::testing::AssertionFailure()) { - return ::testing::AssertionFailure(); - } + EXPECT_TRUE(mDemux) << "Test with openDemux first."; // Create dvr callback mDvrCallback = new DvrCallback(); - // Add playback input to the local demux - mDemux->openDvr(DvrType::PLAYBACK, FMQ_SIZE_1M, mDvrCallback, - [&](Result result, const sp& dvr) { - mDvr = dvr; - status = result; - }); - - if (status != Result::SUCCESS) { - return ::testing::AssertionFailure(); - } - - DvrSettings dvrSetting; - dvrSetting.playback(setting); - status = mDvr->configure(dvrSetting); - - return ::testing::AssertionResult(status == Result::SUCCESS); -} - -::testing::AssertionResult TunerHidlTest::getPlaybackMQDescriptor() { - Result status; - - if ((!mDemux && createDemux() == ::testing::AssertionFailure()) || !mDvr) { - return ::testing::AssertionFailure(); - } - - mDvr->getQueueDesc([&](Result result, const MQDesc& dvrMQDesc) { - mPlaybackMQDescriptor = dvrMQDesc; + mDemux->openDvr(type, FMQ_SIZE_1M, mDvrCallback, [&](Result result, const sp& dvr) { + mDvr = dvr; status = result; }); - return ::testing::AssertionResult(status == Result::SUCCESS); + return AssertionResult(status == Result::SUCCESS); } -::testing::AssertionResult TunerHidlTest::addRecordToDemux(RecordSettings setting) { - Result status; - - if (!mDemux && createDemux() == ::testing::AssertionFailure()) { - return ::testing::AssertionFailure(); - } - - // Create dvr callback - mDvrCallback = new DvrCallback(); - - // Add playback input to the local demux - mDemux->openDvr(DvrType::RECORD, FMQ_SIZE_1M, mDvrCallback, - [&](Result result, const sp& dvr) { - mDvr = dvr; - status = result; - }); - - if (status != Result::SUCCESS) { - return ::testing::AssertionFailure(); - } - - DvrSettings dvrSetting; - dvrSetting.record(setting); - status = mDvr->configure(dvrSetting); +AssertionResult TunerHidlTest::configDvr(DvrSettings setting) { + Result status = mDvr->configure(setting); - return ::testing::AssertionResult(status == Result::SUCCESS); + return AssertionResult(status == Result::SUCCESS); } -::testing::AssertionResult TunerHidlTest::getRecordMQDescriptor() { +AssertionResult TunerHidlTest::getDvrMQDescriptor() { Result status; - - if ((!mDemux && createDemux() == ::testing::AssertionFailure()) || !mDvr) { - return ::testing::AssertionFailure(); - } + EXPECT_TRUE(mDemux) << "Test with openDemux first."; + EXPECT_TRUE(mDvr) << "Test with openDvr first."; mDvr->getQueueDesc([&](Result result, const MQDesc& dvrMQDesc) { - mRecordMQDescriptor = dvrMQDesc; + mDvrMQDescriptor = dvrMQDesc; status = result; }); - return ::testing::AssertionResult(status == Result::SUCCESS); -}*/ + return AssertionResult(status == Result::SUCCESS); +} +/*============================ End Dvr APIs Tests Implementation ============================*/ -/*============================Start Data Flow Tests Implementation============================*/ +/*========================== Start Data Flow Tests Implementation ==========================*/ AssertionResult TunerHidlTest::broadcastDataFlowTest(vector /*goldenOutputFiles*/) { EXPECT_TRUE(mFrontend) << "Test with openFilterInDemux first."; EXPECT_TRUE(mDemux) << "Test with openDemux first."; @@ -1130,7 +1076,7 @@ AssertionResult TunerHidlTest::broadcastDataFlowTest(vector /*goldenOutp /* * TODO: re-enable the tests after finalizing the test refactoring. */ -/*::testing::AssertionResult TunerHidlTest::playbackDataFlowTest( +/*AssertionResult TunerHidlTest::playbackDataFlowTest( vector filterConf, PlaybackConf playbackConf, vector \/\*goldenOutputFiles\*\/) { Result status; @@ -1138,10 +1084,10 @@ AssertionResult TunerHidlTest::broadcastDataFlowTest(vector /*goldenOutp // Filter Configuration Module for (int i = 0; i < filterConf.size(); i++) { if (addFilterToDemux(filterConf[i].type, filterConf[i].setting) == - ::testing::AssertionFailure() || + failure() || // TODO use a map to save the FMQs/EvenFlags and pass to callback - getFilterMQDescriptor() == ::testing::AssertionFailure()) { - return ::testing::AssertionFailure(); + getFilterMQDescriptor() == failure()) { + return failure(); } filterIdsSize = mUsedFilterIds.size(); mUsedFilterIds.resize(filterIdsSize + 1); @@ -1152,25 +1098,25 @@ AssertionResult TunerHidlTest::broadcastDataFlowTest(vector /*goldenOutp // mDemuxCallback->updateGoldenOutputMap(goldenOutputFiles[i]); status = mFilter->start(); if (status != Result::SUCCESS) { - return ::testing::AssertionFailure(); + return failure(); } } // Playback Input Module PlaybackSettings playbackSetting = playbackConf.setting; - if (addPlaybackToDemux(playbackSetting) == ::testing::AssertionFailure() || - getPlaybackMQDescriptor() == ::testing::AssertionFailure()) { - return ::testing::AssertionFailure(); + if (addPlaybackToDemux(playbackSetting) == failure() || + getPlaybackMQDescriptor() == failure()) { + return failure(); } for (int i = 0; i <= filterIdsSize; i++) { if (mDvr->attachFilter(mFilters[mUsedFilterIds[i]]) != Result::SUCCESS) { - return ::testing::AssertionFailure(); + return failure(); } } mDvrCallback->startPlaybackInputThread(playbackConf, mPlaybackMQDescriptor); status = mDvr->start(); if (status != Result::SUCCESS) { - return ::testing::AssertionFailure(); + return failure(); } // Data Verify Module @@ -1183,11 +1129,11 @@ AssertionResult TunerHidlTest::broadcastDataFlowTest(vector /*goldenOutp // Clean Up Module for (int i = 0; i <= filterIdsSize; i++) { if (mFilters[mUsedFilterIds[i]]->stop() != Result::SUCCESS) { - return ::testing::AssertionFailure(); + return failure(); } } if (mDvr->stop() != Result::SUCCESS) { - return ::testing::AssertionFailure(); + return failure(); } mUsedFilterIds.clear(); mFilterCallbacks.clear(); @@ -1195,10 +1141,11 @@ AssertionResult TunerHidlTest::broadcastDataFlowTest(vector /*goldenOutp return closeDemux(); } -::testing::AssertionResult TunerHidlTest::recordDataFlowTest(vector filterConf, - RecordSettings recordSetting, - vector -\/\*goldenOutputFiles\*\/) { Result status; hidl_vec feIds; +AssertionResult TunerHidlTest::recordDataFlowTest(vector filterConf, + RecordSettings recordSetting, + vector goldenOutputFiles) { + Result status; + hidl_vec feIds; mService->getFrontendIds([&](Result result, const hidl_vec& frontendIds) { status = result; @@ -1207,7 +1154,7 @@ AssertionResult TunerHidlTest::broadcastDataFlowTest(vector /*goldenOutp if (feIds.size() == 0) { ALOGW("[ WARN ] Frontend isn't available"); - return ::testing::AssertionFailure(); + return failure(); } FrontendDvbtSettings dvbt{ @@ -1220,10 +1167,10 @@ AssertionResult TunerHidlTest::broadcastDataFlowTest(vector /*goldenOutp // Filter Configuration Module for (int i = 0; i < filterConf.size(); i++) { if (addFilterToDemux(filterConf[i].type, filterConf[i].setting) == - ::testing::AssertionFailure() || + failure() || // TODO use a map to save the FMQs/EvenFlags and pass to callback - getFilterMQDescriptor() == ::testing::AssertionFailure()) { - return ::testing::AssertionFailure(); + getFilterMQDescriptor() == failure()) { + return failure(); } filterIdsSize = mUsedFilterIds.size(); mUsedFilterIds.resize(filterIdsSize + 1); @@ -1232,24 +1179,24 @@ AssertionResult TunerHidlTest::broadcastDataFlowTest(vector /*goldenOutp } // Record Config Module - if (addRecordToDemux(recordSetting) == ::testing::AssertionFailure() || - getRecordMQDescriptor() == ::testing::AssertionFailure()) { - return ::testing::AssertionFailure(); + if (addRecordToDemux(recordSetting) == failure() || + getRecordMQDescriptor() == failure()) { + return failure(); } for (int i = 0; i <= filterIdsSize; i++) { if (mDvr->attachFilter(mFilters[mUsedFilterIds[i]]) != Result::SUCCESS) { - return ::testing::AssertionFailure(); + return failure(); } } mDvrCallback->startRecordOutputThread(recordSetting, mRecordMQDescriptor); status = mDvr->start(); if (status != Result::SUCCESS) { - return ::testing::AssertionFailure(); + return failure(); } - if (createDemuxWithFrontend(feIds[0], settings) != ::testing::AssertionSuccess()) { - return ::testing::AssertionFailure(); + if (setDemuxFrontendDataSource(feIds[0]) != success()) { + return failure(); } // Data Verify Module @@ -1258,20 +1205,20 @@ AssertionResult TunerHidlTest::broadcastDataFlowTest(vector /*goldenOutp // Clean Up Module for (int i = 0; i <= filterIdsSize; i++) { if (mFilters[mUsedFilterIds[i]]->stop() != Result::SUCCESS) { - return ::testing::AssertionFailure(); + return failure(); } } if (mFrontend->stopTune() != Result::SUCCESS) { - return ::testing::AssertionFailure(); + return failure(); } mUsedFilterIds.clear(); mFilterCallbacks.clear(); mFilters.clear(); return closeDemux(); }*/ -/*============================End Data Flow Tests Implementation============================*/ +/*========================= End Data Flow Tests Implementation =========================*/ -/*============================Start Helper Functions============================*/ +/*=============================== Start Helper Functions ===============================*/ FilterEventType TunerHidlTest::getFilterEventType(DemuxFilterType type) { FilterEventType eventType = FilterEventType::UNDEFINED; switch (type.mainType) { @@ -1318,11 +1265,11 @@ FilterEventType TunerHidlTest::getFilterEventType(DemuxFilterType type) { } return eventType; } -/*============================End Helper Functions============================*/ -/******************************** End Test Implementation**********************************/ +/*============================== End Helper Functions ==============================*/ +/***************************** End Test Implementation *****************************/ -/******************************** Start Test Entry**********************************/ -/*============================Start Frontend Tests============================*/ +/******************************** Start Test Entry **********************************/ +/*============================== Start Frontend Tests ==============================*/ TEST_P(TunerHidlTest, getFrontendIds) { description("Get Frontend ids and verify frontends exist"); ASSERT_TRUE(getFrontendIds()); @@ -1380,9 +1327,9 @@ TEST_P(TunerHidlTest, AutoScanFrontend) { break; } } -/*============================End Frontend Tests============================*/ +/*=============================== End Frontend Tests ===============================*/ -/*============================Start Demux/Filter Tests============================*/ +/*============================ Start Demux/Filter Tests ============================*/ TEST_P(TunerHidlTest, OpenDemuxWithFrontendDataSource) { description("Open Demux with a Frontend as its data source."); ASSERT_TRUE(getFrontendIds()); @@ -1454,8 +1401,12 @@ TEST_P(TunerHidlTest, StartFilterInDemux) { break; } } -/*============================End Demux/Filter Tests============================*/ +/*============================ End Demux/Filter Tests ============================*/ +/*============================ Start Descrambler Tests ============================*/ +/* + * TODO: re-enable the tests after finalizing the test refactoring. + */ /*TEST_P(TunerHidlTest, CreateDescrambler) { description("Create Descrambler"); ASSERT_TRUE(createDescrambler()); @@ -1465,8 +1416,9 @@ TEST_P(TunerHidlTest, CloseDescrambler) { description("Close Descrambler"); ASSERT_TRUE(closeDescrambler()); }*/ +/*============================== End Descrambler Tests ==============================*/ -/*============================Start Data Flow Tests============================*/ +/*============================== Start Data Flow Tests ==============================*/ TEST_P(TunerHidlTest, BroadcastDataFlowWithAudioFilterTest) { description("Open Demux with a Frontend as its data source."); ASSERT_TRUE(getFrontendIds()); @@ -1583,7 +1535,8 @@ TEST_P(TunerHidlTest, RecordDataFlowWithTsRecordFilterTest) { ASSERT_TRUE(recordDataFlowTest(filterConf, recordSetting, goldenOutputFiles)); }*/ -/******************************** End Test Entry**********************************/ +/*============================== End Data Flow Tests ==============================*/ +/******************************** End Test Entry **********************************/ } // namespace INSTANTIATE_TEST_SUITE_P( -- GitLab From c91b679ac1ae75ac60a277be7d4a6f573e4c22bf Mon Sep 17 00:00:00 2001 From: Andy Hung Date: Fri, 14 Feb 2020 15:39:55 -0800 Subject: [PATCH 006/790] audio hal: Update offload configuration Test: no regression with offloaded Play Music Bug: 133526565 Change-Id: Ie655a96503be5a4ad1660d4b2183b01e514452fd --- audio/common/6.0/types.hal | 22 +++++++++++ .../common/all-versions/default/HidlUtils.cpp | 37 +++++++++++++++++-- audio/common/all-versions/default/HidlUtils.h | 15 +++++--- audio/core/all-versions/default/Device.cpp | 6 ++- current.txt | 2 +- 5 files changed, 70 insertions(+), 12 deletions(-) diff --git a/audio/common/6.0/types.hal b/audio/common/6.0/types.hal index b2806c7eeb..67217ab503 100644 --- a/audio/common/6.0/types.hal +++ b/audio/common/6.0/types.hal @@ -903,6 +903,25 @@ enum AudioContentType : uint32_t { SONIFICATION = 4, }; +/** Encapsulation mode used for sending audio compressed data. */ +@export(name="audio_encapsulation_mode_t", value_prefix="AUDIO_ENCAPSULATION_MODE_") +enum AudioEncapsulationMode : int32_t { + // Do not change these values without updating their counterparts + // in frameworks/base/media/java/android/media/AudioTrack.java + /** + * No encapsulation mode for metadata. + */ + NONE = 0, + /** + * Elementary stream payload with metadata + */ + ELEMENTARY_STREAM = 1, + /** + * Handle-based payload with metadata + */ + HANDLE = 2, +}; + /** * Additional information about the stream passed to hardware decoders. */ @@ -918,6 +937,9 @@ struct AudioOffloadInfo { uint32_t bitWidth; uint32_t bufferSize; AudioUsage usage; + AudioEncapsulationMode encapsulationMode; + int32_t contentId; + int32_t syncId; }; /** diff --git a/audio/common/all-versions/default/HidlUtils.cpp b/audio/common/all-versions/default/HidlUtils.cpp index 08002c8788..a470c9cb78 100644 --- a/audio/common/all-versions/default/HidlUtils.cpp +++ b/audio/common/all-versions/default/HidlUtils.cpp @@ -28,12 +28,13 @@ namespace common { namespace CPP_VERSION { namespace implementation { -void HidlUtils::audioConfigFromHal(const audio_config_t& halConfig, AudioConfig* config) { +status_t HidlUtils::audioConfigFromHal(const audio_config_t& halConfig, AudioConfig* config) { config->sampleRateHz = halConfig.sample_rate; config->channelMask = EnumBitfield(halConfig.channel_mask); config->format = AudioFormat(halConfig.format); - audioOffloadInfoFromHal(halConfig.offload_info, &config->offloadInfo); + status_t status = audioOffloadInfoFromHal(halConfig.offload_info, &config->offloadInfo); config->frameCount = halConfig.frame_count; + return status; } void HidlUtils::audioConfigToHal(const AudioConfig& config, audio_config_t* halConfig) { @@ -106,8 +107,8 @@ audio_usage_t HidlUtils::audioUsageToHal(const AudioUsage usage) { return static_cast(usage); } -void HidlUtils::audioOffloadInfoFromHal(const audio_offload_info_t& halOffload, - AudioOffloadInfo* offload) { +status_t HidlUtils::audioOffloadInfoFromHal(const audio_offload_info_t& halOffload, + AudioOffloadInfo* offload) { offload->sampleRateHz = halOffload.sample_rate; offload->channelMask = EnumBitfield(halOffload.channel_mask); offload->format = AudioFormat(halOffload.format); @@ -119,6 +120,26 @@ void HidlUtils::audioOffloadInfoFromHal(const audio_offload_info_t& halOffload, offload->bitWidth = halOffload.bit_width; offload->bufferSize = halOffload.offload_buffer_size; offload->usage = audioUsageFromHal(halOffload.usage); +#if MAJOR_VERSION >= 6 + if (halOffload.version >= AUDIO_OFFLOAD_INFO_VERSION_0_2) { + offload->encapsulationMode = + static_cast(halOffload.encapsulation_mode); + offload->contentId = halOffload.content_id; + offload->syncId = halOffload.sync_id; + } else { + offload->encapsulationMode = AudioEncapsulationMode::NONE; + offload->contentId = 0; + offload->syncId = 0; + } +#else + // nonzero values here are not compatible with HAL versions below 6. + if (halOffload.version >= AUDIO_OFFLOAD_INFO_VERSION_0_2 && + (halOffload.encapsulation_mode != AUDIO_ENCAPSULATION_MODE_NONE || + halOffload.content_id != 0 || halOffload.sync_id != 0)) { + return BAD_VALUE; + } +#endif + return OK; } void HidlUtils::audioOffloadInfoToHal(const AudioOffloadInfo& offload, @@ -135,6 +156,14 @@ void HidlUtils::audioOffloadInfoToHal(const AudioOffloadInfo& offload, halOffload->bit_width = offload.bitWidth; halOffload->offload_buffer_size = offload.bufferSize; halOffload->usage = audioUsageToHal(offload.usage); +#if MAJOR_VERSION >= 6 + halOffload->encapsulation_mode = + static_cast(offload.encapsulationMode); + halOffload->content_id = offload.contentId; + halOffload->sync_id = offload.syncId; +#else + // offload doesn't contain encapsulationMode, contentId, syncId, so this is OK. +#endif } void HidlUtils::audioPortConfigFromHal(const struct audio_port_config& halConfig, diff --git a/audio/common/all-versions/default/HidlUtils.h b/audio/common/all-versions/default/HidlUtils.h index 758a7f43d1..ef6dee3706 100644 --- a/audio/common/all-versions/default/HidlUtils.h +++ b/audio/common/all-versions/default/HidlUtils.h @@ -35,8 +35,11 @@ namespace implementation { using namespace ::android::hardware::audio::common::CPP_VERSION; class HidlUtils { - public: - static void audioConfigFromHal(const audio_config_t& halConfig, AudioConfig* config); + public: + // A failure here indicates a platform config that is incompatible with + // the compiled HIDL interface version. + static status_t audioConfigFromHal(const audio_config_t& halConfig, AudioConfig* config); + static void audioConfigToHal(const AudioConfig& config, audio_config_t* halConfig); static void audioGainConfigFromHal(const struct audio_gain_config& halConfig, AudioGainConfig* config); @@ -46,8 +49,10 @@ class HidlUtils { static void audioGainToHal(const AudioGain& gain, struct audio_gain* halGain); static AudioUsage audioUsageFromHal(const audio_usage_t halUsage); static audio_usage_t audioUsageToHal(const AudioUsage usage); - static void audioOffloadInfoFromHal(const audio_offload_info_t& halOffload, - AudioOffloadInfo* offload); + // A failure here indicates a platform offload info that is incompatible with + // the compiled HIDL interface version. + static status_t audioOffloadInfoFromHal(const audio_offload_info_t& halOffload, + AudioOffloadInfo* offload); static void audioOffloadInfoToHal(const AudioOffloadInfo& offload, audio_offload_info_t* halOffload); static void audioPortConfigFromHal(const struct audio_port_config& halConfig, @@ -58,7 +63,7 @@ class HidlUtils { const struct audio_port_config* halConfigs, hidl_vec* configs); static std::unique_ptr audioPortConfigsToHal( - const hidl_vec& configs); + const hidl_vec& configs); static void audioPortFromHal(const struct audio_port& halPort, AudioPort* port); static void audioPortToHal(const AudioPort& port, struct audio_port* halPort); static void uuidFromHal(const audio_uuid_t& halUuid, Uuid* uuid); diff --git a/audio/core/all-versions/default/Device.cpp b/audio/core/all-versions/default/Device.cpp index 47e31c1801..6260ba1979 100644 --- a/audio/core/all-versions/default/Device.cpp +++ b/audio/core/all-versions/default/Device.cpp @@ -171,7 +171,8 @@ std::tuple> Device::openOutputStreamImpl(int32_t ioHandle streamOut = new StreamOut(this, halStream); ++mOpenedStreamsCount; } - HidlUtils::audioConfigFromHal(halConfig, suggestedConfig); + status_t convertStatus = HidlUtils::audioConfigFromHal(halConfig, suggestedConfig); + ALOGW_IF(convertStatus != OK, "%s: suggested config with incompatible fields", __func__); return {analyzeStatus("open_output_stream", status, {EINVAL} /*ignore*/), streamOut}; } @@ -198,7 +199,8 @@ std::tuple> Device::openInputStreamImpl( streamIn = new StreamIn(this, halStream); ++mOpenedStreamsCount; } - HidlUtils::audioConfigFromHal(halConfig, suggestedConfig); + status_t convertStatus = HidlUtils::audioConfigFromHal(halConfig, suggestedConfig); + ALOGW_IF(convertStatus != OK, "%s: suggested config with incompatible fields", __func__); return {analyzeStatus("open_input_stream", status, {EINVAL} /*ignore*/), streamIn}; } diff --git a/current.txt b/current.txt index 2ed3c47e2a..2346d214ca 100644 --- a/current.txt +++ b/current.txt @@ -613,7 +613,7 @@ fd1f1b29f26b42e886220f04a08086c00e5ade9d7b53f095438e578ab9d42a93 android.hardwar 2df5d5866b37776f25079c0e54b54350a2abe4e025a59c9e02a7d3abe8ca00e8 android.hardware.audio@6.0::IStreamIn 78e4138cc8307c11fc777c3bd376e581ba4ba48196b05ca1d7cdfa515c87b48a android.hardware.audio@6.0::IStreamOut 997fdaad7a9d17ee7e01feb7031a753e2365e72ad30b11d950e9183fabdf3844 android.hardware.audio@6.0::IStreamOutCallback -167ed5cfb7d91db2e2bf20f1320c1a9004eeb768e26f535e0f7db94a21867d21 android.hardware.audio.common@6.0::types +bee662c62d997d8065e2bcb5c1e7a9578931f22ce28fd02c219fdb4d0630abf7 android.hardware.audio.common@6.0::types 817930d58412d662cb45e641c50cb62c727e4a3e3ffe7029a53cad9677b97d58 android.hardware.audio.effect@6.0::types 525bec6b44f1103869c269a128d51b8dccd73af5340ba863c8886c68357c7faf android.hardware.audio.effect@6.0::IAcousticEchoCancelerEffect 8d76bbe3719d051a8e9a1dcf9244f37f5b0a491feb249fa48391edf7cb4f3131 android.hardware.audio.effect@6.0::IAutomaticGainControlEffect -- GitLab From 1ab35548682491d8f5ead7bb9b618c5c36a8fcf4 Mon Sep 17 00:00:00 2001 From: chrisweir Date: Fri, 21 Feb 2020 10:16:17 -0800 Subject: [PATCH 007/790] Clean up TODOs Squeegee supports Android now, so I'm cleaning up my TODOs. Test: Only changes to comments Change-Id: Ifd9907ba944759d4d5b36bce92f6bd11b5bb74e7 --- automotive/can/1.0/default/CanBus.cpp | 2 -- automotive/can/1.0/default/CanBusSlcan.cpp | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/automotive/can/1.0/default/CanBus.cpp b/automotive/can/1.0/default/CanBus.cpp index 9f704c1ebd..8b98e5ee2b 100644 --- a/automotive/can/1.0/default/CanBus.cpp +++ b/automotive/can/1.0/default/CanBus.cpp @@ -226,7 +226,6 @@ bool CanBus::down() { * \param flag bool object from CanMessage object */ static bool satisfiesFilterFlag(FilterFlag filterFlag, bool flag) { - // TODO(b/144458917) add testing for this to VTS tests if (filterFlag == FilterFlag::DONT_CARE) return true; if (filterFlag == FilterFlag::SET) return flag; if (filterFlag == FilterFlag::NOT_SET) return !flag; @@ -302,7 +301,6 @@ void CanBus::onRead(const struct canfd_frame& frame, std::chrono::nanoseconds ti if ((frame.can_id & CAN_ERR_FLAG) != 0) { // error bit is set LOG(WARNING) << "CAN Error frame received"; - // TODO(b/144458917) consider providing different values for isFatal, depending on error notifyErrorListeners(parseErrorFrame(frame), false); return; } diff --git a/automotive/can/1.0/default/CanBusSlcan.cpp b/automotive/can/1.0/default/CanBusSlcan.cpp index d15905da53..5005ecd642 100644 --- a/automotive/can/1.0/default/CanBusSlcan.cpp +++ b/automotive/can/1.0/default/CanBusSlcan.cpp @@ -133,7 +133,7 @@ ICanController::Result CanBusSlcan::preUp() { return ICanController::Result::UNKNOWN_ERROR; } - // set open flag TODO: also support listen only + // TODO(b/144775286): set open flag & support listen only if (write(mFd.get(), slcanprotocol::kOpenCommand.c_str(), slcanprotocol::kOpenCommand.length()) <= 0) { LOG(ERROR) << "Failed to set open flag: " << strerror(errno); -- GitLab From 33ce7505d150a39eb288f3062ee2090afc734199 Mon Sep 17 00:00:00 2001 From: chrisweir Date: Thu, 9 Jan 2020 15:55:44 -0800 Subject: [PATCH 008/790] CAN Configurator Service Configurator service for the CAN HAL and extracting some of the CAN HAL configuration logic into a library for the various tools to share. Bug: 142653776 Test: Manual Change-Id: Id33871da851bcb442a7f851919f713ec913830ff --- automotive/can/1.0/tools/Android.bp | 9 ++ automotive/can/1.0/tools/canhalctrl.cpp | 24 +-- .../can/1.0/tools/configurator/Android.bp | 34 ++++ .../tools/configurator/canhalconfigurator.cpp | 103 ++++++++++++ .../tools/configurator/canhalconfigurator.rc | 3 + .../1.0/tools/configurator/canprototools.cpp | 152 ++++++++++++++++++ .../1.0/tools/configurator/canprototools.h | 49 ++++++ .../1.0/tools/configurator/proto/Android.bp | 28 ++++ .../configurator/proto/canbus_config.proto | 52 ++++++ .../can/1.0/tools/libcanhaltools/Android.bp | 32 ++++ .../include/libcanhaltools/libcanhaltools.h | 48 ++++++ .../tools/libcanhaltools/libcanhaltools.cpp | 85 ++++++++++ 12 files changed, 599 insertions(+), 20 deletions(-) create mode 100644 automotive/can/1.0/tools/configurator/Android.bp create mode 100644 automotive/can/1.0/tools/configurator/canhalconfigurator.cpp create mode 100644 automotive/can/1.0/tools/configurator/canhalconfigurator.rc create mode 100644 automotive/can/1.0/tools/configurator/canprototools.cpp create mode 100644 automotive/can/1.0/tools/configurator/canprototools.h create mode 100644 automotive/can/1.0/tools/configurator/proto/Android.bp create mode 100644 automotive/can/1.0/tools/configurator/proto/canbus_config.proto create mode 100644 automotive/can/1.0/tools/libcanhaltools/Android.bp create mode 100644 automotive/can/1.0/tools/libcanhaltools/include/libcanhaltools/libcanhaltools.h create mode 100644 automotive/can/1.0/tools/libcanhaltools/libcanhaltools.cpp diff --git a/automotive/can/1.0/tools/Android.bp b/automotive/can/1.0/tools/Android.bp index 21f364b629..a6c40d933a 100644 --- a/automotive/can/1.0/tools/Android.bp +++ b/automotive/can/1.0/tools/Android.bp @@ -27,6 +27,9 @@ cc_binary { header_libs: [ "android.hardware.automotive.can@hidl-utils-lib", ], + static_libs: [ + "android.hardware.automotive.can@libcanhaltools", + ], } cc_binary { @@ -42,6 +45,9 @@ cc_binary { header_libs: [ "android.hardware.automotive.can@hidl-utils-lib", ], + static_libs: [ + "android.hardware.automotive.can@libcanhaltools", + ], } cc_binary { @@ -54,4 +60,7 @@ cc_binary { "android.hardware.automotive.can@1.0", "libhidlbase", ], + static_libs: [ + "android.hardware.automotive.can@libcanhaltools", + ], } diff --git a/automotive/can/1.0/tools/canhalctrl.cpp b/automotive/can/1.0/tools/canhalctrl.cpp index 33755bfffd..c186b74386 100644 --- a/automotive/can/1.0/tools/canhalctrl.cpp +++ b/automotive/can/1.0/tools/canhalctrl.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -41,34 +42,17 @@ static void usage() { std::cerr << " bus name - name under which ICanBus will be published" << std::endl; } -static hidl_vec getControlServices() { - auto manager = hidl::manager::V1_2::IServiceManager::getService(); - hidl_vec services; - manager->listManifestByInterface(ICanController::descriptor, hidl_utils::fill(&services)); - if (services.size() == 0) { - std::cerr << "No ICanController services registered (missing privileges?)" << std::endl; - exit(-1); - } - return services; -} - -static bool isSupported(sp ctrl, ICanController::InterfaceType iftype) { - hidl_vec supported; - if (!ctrl->getSupportedInterfaceTypes(hidl_utils::fill(&supported)).isOk()) return false; - return supported.contains(iftype); -} - static int up(const std::string& busName, ICanController::InterfaceType type, const std::string& interface, uint32_t bitrate) { bool anySupported = false; - for (auto&& service : getControlServices()) { + for (auto&& service : libcanhaltools::getControlServices()) { auto ctrl = ICanController::getService(service); if (ctrl == nullptr) { std::cerr << "Couldn't open ICanController/" << service; continue; } - if (!isSupported(ctrl, type)) continue; + if (!libcanhaltools::isSupported(ctrl, type)) continue; anySupported = true; ICanController::BusConfig config = {}; @@ -111,7 +95,7 @@ static int up(const std::string& busName, ICanController::InterfaceType type, } static int down(const std::string& busName) { - for (auto&& service : getControlServices()) { + for (auto&& service : libcanhaltools::getControlServices()) { auto ctrl = ICanController::getService(service); if (ctrl == nullptr) continue; diff --git a/automotive/can/1.0/tools/configurator/Android.bp b/automotive/can/1.0/tools/configurator/Android.bp new file mode 100644 index 0000000000..2c4bc1d6fc --- /dev/null +++ b/automotive/can/1.0/tools/configurator/Android.bp @@ -0,0 +1,34 @@ +// +// 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. +// + +cc_binary { + name: "canhalconfigurator", + init_rc: ["canhalconfigurator.rc"], + defaults: ["android.hardware.automotive.can@defaults"], + srcs: [ + "canhalconfigurator.cpp", + "canprototools.cpp", + ], + shared_libs: [ + "android.hardware.automotive.can@1.0", + "libhidlbase", + "libprotobuf-cpp-full", + ], + static_libs: [ + "android.hardware.automotive.can@1.x-config-format", + "android.hardware.automotive.can@libcanhaltools", + ], +} diff --git a/automotive/can/1.0/tools/configurator/canhalconfigurator.cpp b/automotive/can/1.0/tools/configurator/canhalconfigurator.cpp new file mode 100644 index 0000000000..a100f06f1b --- /dev/null +++ b/automotive/can/1.0/tools/configurator/canhalconfigurator.cpp @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "canbus_config.pb.h" +#include "canprototools.h" + +#include +#include +#include + +#include +#include + +namespace android::hardware::automotive::can { + +using ICanController = V1_0::ICanController; + +/** + * Takes output from parsed protobuf config and uses it to configure the CAN HAL. + * + * \param pb_cfg is an instance of the autogenerated protobuf object for our configuration. + * \return boolean status, true on success, false on failure. + */ +static bool processPbCfg(const config::CanBusConfig& pb_cfg) { + for (auto const& bus : pb_cfg.buses()) { + if (bus.name().empty()) { + LOG(ERROR) << "Invalid config: Bus config must have a valid name field"; + return false; + } + + LOG(INFO) << "Configure " << bus.name(); + auto bus_cfg = config::fromPbBus(bus); + if (!bus_cfg.has_value()) { + return false; + } + + // TODO(149405589): remove this sleep and associated includes. + std::this_thread::sleep_for(std::chrono::seconds(1)); + if (libcanhaltools::configureIface(*bus_cfg) != ICanController::Result::OK) { + LOG(ERROR) << "No controller supports " << bus.name() << std::endl; + // TODO(149405589): add retry logic in case a bus fails to come up. + continue; + } + LOG(INFO) << bus.name() << " has been successfully configured!"; + } + return true; +} + +/** + * This kicks off the CAN HAL configuration process. This starts the following: + * 1. Reading the config file + * 2. Setting up CAN buses + * 3. Handling services + * \param filepath is a string specifying the absolute path of the config file + * \return boolean status, true on success, false on failure + */ +static bool configuratorStart(const std::string& filepath) { + base::SetDefaultTag("CanConfigurator"); + + auto pb_cfg = config::parseConfigFile(filepath); + if (!pb_cfg.has_value()) { + return false; + } + + // process the rest of the config file data and configure the CAN buses. + if (!processPbCfg(*pb_cfg)) { + return false; + } + LOG(INFO) << "CAN HAL has been configured!"; + return true; +} + +} // namespace android::hardware::automotive::can + +int main(int argc, char* argv[]) { + std::string config_filepath = "/etc/canbus_config.pb"; + + // allow for CLI specification of a config file. + if (argc == 2) { + config_filepath = argv[1]; + } else if (argc > 2) { + std::cerr << "usage: " << argv[0] << " [optional config filepath]"; + return 1; + } + + if (!::android::hardware::automotive::can::configuratorStart(config_filepath)) { + return 1; + } + return 0; +} diff --git a/automotive/can/1.0/tools/configurator/canhalconfigurator.rc b/automotive/can/1.0/tools/configurator/canhalconfigurator.rc new file mode 100644 index 0000000000..12c24652dd --- /dev/null +++ b/automotive/can/1.0/tools/configurator/canhalconfigurator.rc @@ -0,0 +1,3 @@ +service canhalconfigurator /system/bin/canhalconfigurator + class core + oneshot diff --git a/automotive/can/1.0/tools/configurator/canprototools.cpp b/automotive/can/1.0/tools/configurator/canprototools.cpp new file mode 100644 index 0000000000..8e6b2b1d45 --- /dev/null +++ b/automotive/can/1.0/tools/configurator/canprototools.cpp @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "canprototools.h" + +#include +#include +#include +#include +#include + +#include + +namespace android::hardware::automotive::can::config { + +using ICanController = V1_0::ICanController; + +/** + * Helper function for parseConfigFile. readString is used to get the fist n characters (n) from an + * istream object (s) and return it as a string object. + * + * \param s istream of the file you intend to read. + * \param n streamsize object of the number of characters you'd like. + * \return optional string containing up to n characters from the stream(s) you provided. + */ +static std::optional readString(std::istream& s, std::streamsize n) { + char buff[n]; + auto got = s.read(buff, n).gcount(); + if (!s.good() && !s.eof()) return std::nullopt; + return std::string(buff, 0, std::min(n, got)); +} + +std::optional parseConfigFile(const std::string& filepath) { + std::ifstream cfg_stream(filepath); + + // text headers that would be present in a plaintext proto config file. + static const std::array text_headers = {"buses", "#", "controller"}; + auto cfg_file_snippet = readString(cfg_stream, 10); + + if (!cfg_file_snippet.has_value()) { + LOG(ERROR) << "Can't open " << filepath << " for reading"; + return std::nullopt; + } + cfg_stream.seekg(0); + + // check if any of the textHeaders are at the start of the config file. + bool text_format = false; + for (auto const& header : text_headers) { + if (cfg_file_snippet->compare(0, header.length(), header) == 0) { + text_format = true; + break; + } + } + + CanBusConfig config; + if (text_format) { + google::protobuf::io::IstreamInputStream pb_stream(&cfg_stream); + if (!google::protobuf::TextFormat::Parse(&pb_stream, &config)) { + LOG(ERROR) << "Failed to parse (text format) " << filepath; + return std::nullopt; + } + } else if (!config.ParseFromIstream(&cfg_stream)) { + LOG(ERROR) << "Failed to parse (binary format) " << filepath; + return std::nullopt; + } + return config; +} + +std::optional fromPbBus(const Bus& pb_bus) { + ICanController::BusConfig bus_cfg = {}; + bus_cfg.name = pb_bus.name(); + + switch (pb_bus.iface_type_case()) { + case Bus::kNative: { + const auto ifname = pb_bus.native().ifname(); + if (ifname.empty()) { + LOG(ERROR) << "Invalid config: native type bus must have an iface name"; + return std::nullopt; + } + bus_cfg.bitrate = pb_bus.bitrate(); + ICanController::BusConfig::InterfaceId::Socketcan socketcan = {}; + socketcan.ifname(ifname); + bus_cfg.interfaceId.socketcan(socketcan); + // TODO(b/142654031) - add support for serial number as an option instead of ifname. + break; + } + case Bus::kSlcan: { + const auto ttyname = pb_bus.slcan().ttyname(); + if (ttyname.empty()) { + LOG(ERROR) << "Invalid config: slcan type bus must have a tty name"; + return std::nullopt; + } + bus_cfg.bitrate = pb_bus.bitrate(); + ICanController::BusConfig::InterfaceId::Slcan slcan = {}; + slcan.ttyname(pb_bus.slcan().ttyname()); + bus_cfg.interfaceId.slcan(slcan); + break; + } + case Bus::kVirtual: { + // Theoretically, we could just create the next available vcan iface. + const auto ifname = pb_bus.virtual_().ifname(); + if (ifname.empty()) { + LOG(ERROR) << "Invalid config: native type bus must have an iface name"; + return std::nullopt; + } + bus_cfg.interfaceId.virtualif({ifname}); + break; + } + case Bus::kIndexed: { + const auto index = pb_bus.indexed().index(); + if (index > UINT8_MAX) { + LOG(ERROR) << "Interface index out of range: " << index; + return std::nullopt; + } + bus_cfg.interfaceId.indexed({uint8_t(index)}); + break; + } + default: + LOG(ERROR) << "Invalid config: bad interface type for " << bus_cfg.name; + return std::nullopt; + } + return bus_cfg; +} + +std::optional getHalIftype(const Bus& pb_bus) { + switch (pb_bus.iface_type_case()) { + case Bus::kNative: + return ICanController::InterfaceType::SOCKETCAN; + case Bus::kSlcan: + return ICanController::InterfaceType::SLCAN; + case Bus::kVirtual: + return ICanController::InterfaceType::VIRTUAL; + case Bus::kIndexed: + return ICanController::InterfaceType::INDEXED; + default: + return std::nullopt; + } +} + +} // namespace android::hardware::automotive::can::config diff --git a/automotive/can/1.0/tools/configurator/canprototools.h b/automotive/can/1.0/tools/configurator/canprototools.h new file mode 100644 index 0000000000..b7f2b6f0d2 --- /dev/null +++ b/automotive/can/1.0/tools/configurator/canprototools.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once + +#include "canbus_config.pb.h" + +#include + +namespace android::hardware::automotive::can::config { + +/** + * This reads the protobuf config file into a protobuf object. Both text based protobuf files as + * well as binary format protobuf files are supported. + * + * \param filepath string containing the name of the config file to read. + * \return a CanBusConfig protobuf object constructed from the config file. + */ +std::optional parseConfigFile(const std::string& filepath); + +/** + * Converts protobuf format single-bus config object to a HAL bus config object. + * + * \param pb_bus is the protobuf object representing a the configuration of one CAN bus. + * \return a converted HAL bus config object. + */ +std::optional fromPbBus(const Bus& pb_bus); + +/** + * Get the CAN HAL interface type specified by a given protobuf config object. + * + * \param pb_bus is the protobuf object representing a the configuration of one CAN bus. + * \return the CAN HAL interface type. + */ +std::optional getHalIftype(const Bus& pb_bus); + +} // namespace android::hardware::automotive::can::config diff --git a/automotive/can/1.0/tools/configurator/proto/Android.bp b/automotive/can/1.0/tools/configurator/proto/Android.bp new file mode 100644 index 0000000000..05e120524a --- /dev/null +++ b/automotive/can/1.0/tools/configurator/proto/Android.bp @@ -0,0 +1,28 @@ +// +// Copyright (C) 2020 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +cc_library_static { + name: "android.hardware.automotive.can@1.x-config-format", + defaults: ["android.hardware.automotive.can@defaults"], + proto: { + export_proto_headers: true, + type: "full", + }, + strip: { + keep_symbols: true, + }, + srcs: ["canbus_config.proto"], +} diff --git a/automotive/can/1.0/tools/configurator/proto/canbus_config.proto b/automotive/can/1.0/tools/configurator/proto/canbus_config.proto new file mode 100644 index 0000000000..9aa33aceb5 --- /dev/null +++ b/automotive/can/1.0/tools/configurator/proto/canbus_config.proto @@ -0,0 +1,52 @@ +/* + * 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. + */ + +syntax = "proto3"; + +package android.hardware.automotive.can.config; + +message IfaceNative { + string ifname = 1; + repeated string serialno = 2; +}; + +message IfaceSlcan { + string ttyname = 1; + repeated string serialno = 2; +}; + +message IfaceVirtual { + string ifname = 1; +}; + +message IfaceIndexed { + uint32 index = 1; +}; + +message Bus { + string name = 1; // this is the name presented in the HAL + oneof iface_type { + IfaceNative native = 2; + IfaceSlcan slcan = 3; + IfaceVirtual virtual = 4; + IfaceIndexed indexed = 5; + } + uint32 bitrate = 6; +}; + +message CanBusConfig { + repeated Bus buses = 1; +}; diff --git a/automotive/can/1.0/tools/libcanhaltools/Android.bp b/automotive/can/1.0/tools/libcanhaltools/Android.bp new file mode 100644 index 0000000000..cee9eef20d --- /dev/null +++ b/automotive/can/1.0/tools/libcanhaltools/Android.bp @@ -0,0 +1,32 @@ +// +// 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. +// + +cc_library_static { + name: "android.hardware.automotive.can@libcanhaltools", + defaults: ["android.hardware.automotive.can@defaults"], + vendor_available: true, + srcs: [ + "libcanhaltools.cpp", + ], + export_include_dirs: ["include"], + shared_libs: [ + "android.hardware.automotive.can@1.0", + "libhidlbase", + ], + header_libs: [ + "android.hardware.automotive.can@hidl-utils-lib", + ], +} diff --git a/automotive/can/1.0/tools/libcanhaltools/include/libcanhaltools/libcanhaltools.h b/automotive/can/1.0/tools/libcanhaltools/include/libcanhaltools/libcanhaltools.h new file mode 100644 index 0000000000..bbd1fe5873 --- /dev/null +++ b/automotive/can/1.0/tools/libcanhaltools/include/libcanhaltools/libcanhaltools.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include + +namespace android::hardware::automotive::can::libcanhaltools { + +/** + * Fetch the list of registered can controller services. + * + * \return list of service names identifying the registered can controllers. + */ +hidl_vec getControlServices(); + +/** + * Determine if an can controller supports a specific interface type. + * + * \param ctrl a pointer to a can controller instance to check for interface support. + * \param iftype the interface type we wish to check if ctrl supports. + * \return true if iftype is supported by ctrl, false if not supported. + */ +bool isSupported(sp ctrl, V1_0::ICanController::InterfaceType iftype); + +/** + * Configures a CAN interface through the CAN HAL and brings it up. + * + * \param can_config this holds the parameters for configuring a CAN bus. + * \return status passed back from the CAN HAL, should be OK on success. + */ +V1_0::ICanController::Result configureIface(V1_0::ICanController::BusConfig can_config); + +} // namespace android::hardware::automotive::can::libcanhaltools diff --git a/automotive/can/1.0/tools/libcanhaltools/libcanhaltools.cpp b/automotive/can/1.0/tools/libcanhaltools/libcanhaltools.cpp new file mode 100644 index 0000000000..9192e2f52d --- /dev/null +++ b/automotive/can/1.0/tools/libcanhaltools/libcanhaltools.cpp @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "libcanhaltools/libcanhaltools.h" + +#include +#include +#include +#include + +#include +#include + +namespace android::hardware::automotive::can::libcanhaltools { + +using ICanBus = V1_0::ICanBus; +using ICanController = V1_0::ICanController; +using IfIdDisc = ICanController::BusConfig::InterfaceId::hidl_discriminator; + +hidl_vec getControlServices() { + auto manager = hidl::manager::V1_2::IServiceManager::getService(); + hidl_vec services; + manager->listManifestByInterface(ICanController::descriptor, hidl_utils::fill(&services)); + CHECK(services.size() > 0) << "No ICanController services registered (missing privileges?)" + << std::endl; + return services; +} + +bool isSupported(sp ctrl, ICanController::InterfaceType iftype) { + hidl_vec supported; + if (!ctrl->getSupportedInterfaceTypes(hidl_utils::fill(&supported)).isOk()) return false; + return supported.contains(iftype); +} + +ICanController::InterfaceType getIftype(ICanController::BusConfig can_config) { + switch (can_config.interfaceId.getDiscriminator()) { + case IfIdDisc::socketcan: + return ICanController::InterfaceType::SOCKETCAN; + case IfIdDisc::slcan: + return ICanController::InterfaceType::SLCAN; + case IfIdDisc::virtualif: + return ICanController::InterfaceType::VIRTUAL; + case IfIdDisc::indexed: + return ICanController::InterfaceType::INDEXED; + default: + CHECK(false) << "HAL returned unexpected interface type!"; + } +} + +ICanController::Result configureIface(ICanController::BusConfig can_config) { + auto iftype = getIftype(can_config); + auto can_controller_list = getControlServices(); + for (auto const& service : can_controller_list) { + auto ctrl = ICanController::getService(service); + if (ctrl == nullptr) { + LOG(ERROR) << "Couldn't open ICanController/" << service; + continue; + } + + if (!libcanhaltools::isSupported(ctrl, iftype)) continue; + + const auto up_result = ctrl->upInterface(can_config); + if (up_result != ICanController::Result::OK) { + LOG(ERROR) << "Failed to bring " << can_config.name << " up: " << toString(up_result) + << std::endl; + } + return up_result; + } + return ICanController::Result::NOT_SUPPORTED; +} + +} // namespace android::hardware::automotive::can::libcanhaltools -- GitLab From 080963546aabc1ee9c06b5309f2d1dc1aec218f0 Mon Sep 17 00:00:00 2001 From: Hao Chen Date: Thu, 13 Feb 2020 16:37:33 -0800 Subject: [PATCH 009/790] Add headers and macros for building VHAL server for AGL It won't change the logic of Android codes. Bug: 148877226 Test: Android build won't break Change-Id: I07006a4a3e20900a2fa90b84167d114f9ac45cfe --- .../include/vhal_v2_0/VehicleObjectPool.h | 1 + .../common/include/vhal_v2_0/VehicleUtils.h | 6 ++++++ .../default/common/src/VehicleObjectPool.cpp | 2 +- .../2.0/default/common/src/VehicleUtils.cpp | 19 +++++++++++-------- .../default/impl/vhal_v2_0/DefaultConfig.h | 5 +++-- .../impl/vhal_v2_0/FakeValueGenerator.h | 2 ++ .../vhal_v2_0/LinearFakeValueGenerator.cpp | 3 ++- 7 files changed, 26 insertions(+), 12 deletions(-) diff --git a/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleObjectPool.h b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleObjectPool.h index 946e74ddda..e3cbf2e7cd 100644 --- a/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleObjectPool.h +++ b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleObjectPool.h @@ -21,6 +21,7 @@ #include #include #include +#include #include diff --git a/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleUtils.h b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleUtils.h index f97dfa1bba..955341504c 100644 --- a/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleUtils.h +++ b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleUtils.h @@ -19,7 +19,9 @@ #include +#ifdef __ANDROID__ #include +#endif #include @@ -69,6 +71,8 @@ size_t getVehicleRawValueVectorSize( void copyVehicleRawValue(VehiclePropValue::RawValue* dest, const VehiclePropValue::RawValue& src); +#ifdef __ANDROID__ + template void shallowCopyHidlVec(hidl_vec* dest, const hidl_vec& src); @@ -76,6 +80,8 @@ void shallowCopyHidlStr(hidl_string* dest, const hidl_string& src); void shallowCopy(VehiclePropValue* dest, const VehiclePropValue& src); +#endif // __ANDROID__ + } // namespace V2_0 } // namespace vehicle } // namespace automotive diff --git a/automotive/vehicle/2.0/default/common/src/VehicleObjectPool.cpp b/automotive/vehicle/2.0/default/common/src/VehicleObjectPool.cpp index 40dd56e73d..0947c9fe8c 100644 --- a/automotive/vehicle/2.0/default/common/src/VehicleObjectPool.cpp +++ b/automotive/vehicle/2.0/default/common/src/VehicleObjectPool.cpp @@ -131,7 +131,7 @@ void VehiclePropValuePool::InternalPool::recycle(VehiclePropValue* o) { ALOGE("Discarding value for prop 0x%x because it contains " "data that is not consistent with this pool. " "Expected type: %d, vector size: %zu", - o->prop, mPropType, mVectorSize); + o->prop, toInt(mPropType), mVectorSize); delete o; } else { ObjectPool::recycle(o); diff --git a/automotive/vehicle/2.0/default/common/src/VehicleUtils.cpp b/automotive/vehicle/2.0/default/common/src/VehicleUtils.cpp index 5b6816ee21..c16b29a2e7 100644 --- a/automotive/vehicle/2.0/default/common/src/VehicleUtils.cpp +++ b/automotive/vehicle/2.0/default/common/src/VehicleUtils.cpp @@ -52,7 +52,7 @@ std::unique_ptr createVehiclePropValue( case VehiclePropertyType::MIXED: break; // Valid, but nothing to do. default: - ALOGE("createVehiclePropValue: unknown type: %d", type); + ALOGE("createVehiclePropValue: unknown type: %d", toInt(type)); val.reset(nullptr); } return val; @@ -78,13 +78,6 @@ size_t getVehicleRawValueVectorSize( } } -template -inline void copyHidlVec(hidl_vec * dest, const hidl_vec & src) { - for (size_t i = 0; i < std::min(dest->size(), src.size()); i++) { - (*dest)[i] = src[i]; - } -} - void copyVehicleRawValue(VehiclePropValue::RawValue* dest, const VehiclePropValue::RawValue& src) { dest->int32Values = src.int32Values; @@ -94,6 +87,15 @@ void copyVehicleRawValue(VehiclePropValue::RawValue* dest, dest->stringValue = src.stringValue; } +#ifdef __ANDROID__ + +template +inline void copyHidlVec(hidl_vec * dest, const hidl_vec & src) { + for (size_t i = 0; i < std::min(dest->size(), src.size()); i++) { + (*dest)[i] = src[i]; + } +} + template void shallowCopyHidlVec(hidl_vec * dest, const hidl_vec & src) { if (src.size() > 0) { @@ -123,6 +125,7 @@ void shallowCopy(VehiclePropValue* dest, const VehiclePropValue& src) { shallowCopyHidlStr(&dest->value.stringValue, src.value.stringValue); } +#endif // __ANDROID__ //} // namespace utils diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h index 785f0e0724..24608b87eb 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h @@ -17,9 +17,11 @@ #ifndef android_hardware_automotive_vehicle_V2_0_impl_DefaultConfig_H_ #define android_hardware_automotive_vehicle_V2_0_impl_DefaultConfig_H_ -#include +#include #include +#include + namespace android { namespace hardware { namespace automotive { @@ -1000,7 +1002,6 @@ const ConfigDeclaration kVehicleProperties[]{ .changeMode = VehiclePropertyChangeMode::ON_CHANGE, }, }, - }; } // impl diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/FakeValueGenerator.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/FakeValueGenerator.h index d6ad77df73..2dc502b9e0 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/FakeValueGenerator.h +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/FakeValueGenerator.h @@ -19,6 +19,8 @@ #include +#include + namespace android { namespace hardware { namespace automotive { diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/LinearFakeValueGenerator.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/LinearFakeValueGenerator.cpp index 7bdc97cd2b..96aaafe0b0 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/LinearFakeValueGenerator.cpp +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/LinearFakeValueGenerator.cpp @@ -46,7 +46,8 @@ VehiclePropValue LinearFakeValueGenerator::nextEvent() { if (mGenCfg.currentValue > mGenCfg.initialValue + mGenCfg.dispersion) { mGenCfg.currentValue = mGenCfg.initialValue - mGenCfg.dispersion; } - VehiclePropValue event = {.prop = mGenCfg.propId}; + // TODO: (chenhaosjtuacm) remove "{}" if AGL compiler updated + VehiclePropValue event = {.timestamp = {}, .areaId = {}, .prop = mGenCfg.propId}; auto& value = event.value; switch (getPropType(event.prop)) { case VehiclePropertyType::INT32: -- GitLab From 0eac27ccf30b4d04be3796818b08b830dfab649f Mon Sep 17 00:00:00 2001 From: Brad Ebinger Date: Thu, 20 Feb 2020 13:57:31 -0800 Subject: [PATCH 010/790] Clarify new setRadioPower documentation There were some questions on how the new IRadio 1.5 setRadioPower command should be implemented based on vendor feedback. This CL clarifies this behavior. Test: manual Bug: 143683674 Change-Id: If08741f0ea156a5c2656a47e46f7e1f98bf54ec4 --- current.txt | 2 +- radio/1.5/IRadio.hal | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/current.txt b/current.txt index fde9d539f2..edf17fc457 100644 --- a/current.txt +++ b/current.txt @@ -688,7 +688,7 @@ a64467bae843569f0d465c5be7f0c7a5b987985b55a3ef4794dd5afc68538650 android.hardwar 77531c8d048f8f8ae532babd0ca86332a865ec9aace1b051226ef2b21123e645 android.hardware.wifi.supplicant@1.3::ISupplicantStaNetwork 98592d193a717066facf91428426e5abe211e3bd718bc372e29fb944ddbe6e7c android.hardware.wifi.supplicant@1.3::types 99f5c26b952271d1246c957e1d0271fa39445ee65cc93aa7c187834f98914a33 android.hardware.radio@1.5::types -7fefa2cc5b3b3be10b5cff5c5dc195385f491d4bf23ca65f9c6b3c30c8753a33 android.hardware.radio@1.5::IRadio +890ecacaaa6660802bac01bbbe5f16b1eb1d6a3a3f0e5b398be5cec76a5ab673 android.hardware.radio@1.5::IRadio e96ae1c3a9c0689002ec2318e9c587f4f607c16a75a3cd38788b77eb91072021 android.hardware.radio@1.5::IRadioIndication 829d3827eeb5a8f563e80fe627419b3231012fc02bc2e79782ec5e9ad9f799a4 android.hardware.radio@1.5::IRadioResponse 4c4ce691df02faa28c0729e2a033ec464e1d72699be8bcde4dfb141313dbeba8 android.hardware.radio.config@1.3::types diff --git a/radio/1.5/IRadio.hal b/radio/1.5/IRadio.hal index 0b50436ff9..87824e2ea8 100644 --- a/radio/1.5/IRadio.hal +++ b/radio/1.5/IRadio.hal @@ -238,7 +238,8 @@ interface IRadio extends @1.4::IRadio { * 1) Emergency call is completed; or * 2) Another setRadioPower_1_5 is issued with forEmergencyCall being false or * preferredForEmergencyCall being false; or - * 3) Timeout after a long period of time. + * 3) Timeout after 30 seconds if dial or emergencyDial is not called. + * Once one of these conditions is reached, the modem should move into normal operation. * * @param serial Serial number of request. * @param powerOn To turn on radio -> on = true, to turn off radio -> on = false. -- GitLab From 02ee09f588b7363a559a38ea4c6375c686e8b6c1 Mon Sep 17 00:00:00 2001 From: Ana Krulec Date: Sat, 22 Feb 2020 22:00:23 -0800 Subject: [PATCH 011/790] SF: RenderEngine->drawLayers takes Graphic Buffer instead of ANativeWindow see ag/10392154 for more information Test: RenderEngineVts Change-Id: I75198d2d9fa43013d6497c1c2a393fa3d62c7708 --- graphics/composer/2.2/utils/vts/RenderEngineVts.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp b/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp index c78c358857..3becacea91 100644 --- a/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp +++ b/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp @@ -69,9 +69,8 @@ void TestRenderEngine::drawLayers() { [](renderengine::LayerSettings& settings) -> renderengine::LayerSettings* { return &settings; }); - mRenderEngine->drawLayers(mDisplaySettings, compositionLayerPointers, - mGraphicBuffer->getNativeBuffer(), true, std::move(bufferFence), - &readyFence); + mRenderEngine->drawLayers(mDisplaySettings, compositionLayerPointers, mGraphicBuffer, true, + std::move(bufferFence), &readyFence); int fd = readyFence.release(); if (fd != -1) { ASSERT_EQ(0, sync_wait(fd, -1)); -- GitLab From 4f6022ae5de718c2892a9371c7a75fabacc9b837 Mon Sep 17 00:00:00 2001 From: "Anton D. Kachalov" Date: Mon, 10 Feb 2020 20:37:08 +0100 Subject: [PATCH 012/790] Camera: Advertise numbered string ID for external cameras With current implementation cameraId is part of something like: device@3.5/external//dev/video0 This doesn't work well with Camera2 API based apps. Adding CameraIdOffset tag to Provider as a base offset. Change-Id: I6309d16be565616f048fb24a70e9be5b2f5ed480 --- .../3.4/default/ExternalCameraDevice.cpp | 29 +++++++++----- .../3.4/default/ExternalCameraUtils.cpp | 7 ++++ .../ExternalCameraDevice_3_4.h | 1 + .../ExternalCameraUtils.h | 3 ++ .../ExternalCameraProviderImpl_2_4.cpp | 39 +++++++++++-------- 5 files changed, 54 insertions(+), 25 deletions(-) diff --git a/camera/device/3.4/default/ExternalCameraDevice.cpp b/camera/device/3.4/default/ExternalCameraDevice.cpp index f518a155a7..677b496324 100644 --- a/camera/device/3.4/default/ExternalCameraDevice.cpp +++ b/camera/device/3.4/default/ExternalCameraDevice.cpp @@ -20,6 +20,7 @@ #include #include +#include #include #include "android-base/macros.h" #include "CameraMetadata.h" @@ -46,10 +47,20 @@ constexpr int OPEN_RETRY_SLEEP_US = 100000; // 100ms * MAX_RETRY = 0.5 seconds } // anonymous namespace +const std::regex kDevicePathRE("/dev/video([0-9]+)"); + ExternalCameraDevice::ExternalCameraDevice( - const std::string& cameraId, const ExternalCameraConfig& cfg) : - mCameraId(cameraId), - mCfg(cfg) {} + const std::string& devicePath, const ExternalCameraConfig& cfg) : + mCameraId("-1"), + mDevicePath(devicePath), + mCfg(cfg) { + std::smatch sm; + if (std::regex_match(mDevicePath, sm, kDevicePathRE)) { + mCameraId = std::to_string(mCfg.cameraIdOffset + std::stoi(sm[1])); + } else { + ALOGE("%s: device path match failed for %s", __FUNCTION__, mDevicePath.c_str()); + } +} ExternalCameraDevice::~ExternalCameraDevice() {} @@ -129,20 +140,20 @@ Return ExternalCameraDevice::open( return Void(); } - unique_fd fd(::open(mCameraId.c_str(), O_RDWR)); + unique_fd fd(::open(mDevicePath.c_str(), O_RDWR)); if (fd.get() < 0) { int numAttempt = 0; do { ALOGW("%s: v4l2 device %s open failed, wait 33ms and try again", - __FUNCTION__, mCameraId.c_str()); + __FUNCTION__, mDevicePath.c_str()); usleep(OPEN_RETRY_SLEEP_US); // sleep and try again - fd.reset(::open(mCameraId.c_str(), O_RDWR)); + fd.reset(::open(mDevicePath.c_str(), O_RDWR)); numAttempt++; } while (fd.get() < 0 && numAttempt <= MAX_RETRY); if (fd.get() < 0) { ALOGE("%s: v4l2 device open %s failed: %s", - __FUNCTION__, mCameraId.c_str(), strerror(errno)); + __FUNCTION__, mDevicePath.c_str(), strerror(errno)); mLock.unlock(); _hidl_cb(Status::INTERNAL_ERROR, nullptr); return Void(); @@ -203,9 +214,9 @@ Return ExternalCameraDevice::dumpState(const ::android::hardware::hidl_han status_t ExternalCameraDevice::initCameraCharacteristics() { if (mCameraCharacteristics.isEmpty()) { // init camera characteristics - unique_fd fd(::open(mCameraId.c_str(), O_RDWR)); + unique_fd fd(::open(mDevicePath.c_str(), O_RDWR)); if (fd.get() < 0) { - ALOGE("%s: v4l2 device open %s failed", __FUNCTION__, mCameraId.c_str()); + ALOGE("%s: v4l2 device open %s failed", __FUNCTION__, mDevicePath.c_str()); return DEAD_OBJECT; } diff --git a/camera/device/3.4/default/ExternalCameraUtils.cpp b/camera/device/3.4/default/ExternalCameraUtils.cpp index 62a4c87af5..8f4626c56d 100644 --- a/camera/device/3.4/default/ExternalCameraUtils.cpp +++ b/camera/device/3.4/default/ExternalCameraUtils.cpp @@ -703,6 +703,7 @@ namespace external { namespace common { namespace { + const int kDefaultCameraIdOffset = 100; const int kDefaultJpegBufSize = 5 << 20; // 5MB const int kDefaultNumVideoBuffer = 4; const int kDefaultNumStillBuffer = 2; @@ -738,6 +739,11 @@ ExternalCameraConfig ExternalCameraConfig::loadFromCfg(const char* cfgPath) { return ret; } + XMLElement *cameraIdOffset = providerCfg->FirstChildElement("CameraIdOffset"); + if (cameraIdOffset != nullptr) { + ret.cameraIdOffset = std::atoi(cameraIdOffset->GetText()); + } + XMLElement *ignore = providerCfg->FirstChildElement("ignore"); if (ignore == nullptr) { ALOGI("%s: no internal ignored device specified", __FUNCTION__); @@ -874,6 +880,7 @@ bool ExternalCameraConfig::updateFpsList(tinyxml2::XMLElement* fpsList, } ExternalCameraConfig::ExternalCameraConfig() : + cameraIdOffset(kDefaultCameraIdOffset), maxJpegBufSize(kDefaultJpegBufSize), numVideoBuffers(kDefaultNumVideoBuffer), numStillBuffers(kDefaultNumStillBuffer), diff --git a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDevice_3_4.h b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDevice_3_4.h index 1958fcbab5..88726f4969 100644 --- a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDevice_3_4.h +++ b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDevice_3_4.h @@ -149,6 +149,7 @@ protected: bool mInitialized = false; bool mInitFailed = false; std::string mCameraId; + std::string mDevicePath; const ExternalCameraConfig& mCfg; std::vector mSupportedFormats; CroppingType mCroppingType; diff --git a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraUtils.h b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraUtils.h index 74f75eb246..b354406a5b 100644 --- a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraUtils.h +++ b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraUtils.h @@ -68,6 +68,9 @@ struct ExternalCameraConfig { static const char* kDefaultCfgPath; static ExternalCameraConfig loadFromCfg(const char* cfgPath = kDefaultCfgPath); + // CameraId base offset for numerical representation + uint32_t cameraIdOffset; + // List of internal V4L2 video nodes external camera HAL must ignore. std::unordered_set mInternalDevices; diff --git a/camera/provider/2.4/default/ExternalCameraProviderImpl_2_4.cpp b/camera/provider/2.4/default/ExternalCameraProviderImpl_2_4.cpp index 2bfced2c62..64a51f6141 100644 --- a/camera/provider/2.4/default/ExternalCameraProviderImpl_2_4.cpp +++ b/camera/provider/2.4/default/ExternalCameraProviderImpl_2_4.cpp @@ -44,17 +44,19 @@ const int kMaxDevicePathLen = 256; const char* kDevicePath = "/dev/"; constexpr char kPrefix[] = "video"; constexpr int kPrefixLen = sizeof(kPrefix) - 1; +constexpr int kDevicePrefixLen = sizeof(kDevicePath) + kPrefixLen + 1; -bool matchDeviceName(const hidl_string& deviceName, std::string* deviceVersion, - std::string* cameraId) { +bool matchDeviceName(int cameraIdOffset, + const hidl_string& deviceName, std::string* deviceVersion, + std::string* cameraDevicePath) { std::string deviceNameStd(deviceName.c_str()); std::smatch sm; if (std::regex_match(deviceNameStd, sm, kDeviceNameRE)) { if (deviceVersion != nullptr) { *deviceVersion = sm[1]; } - if (cameraId != nullptr) { - *cameraId = sm[2]; + if (cameraDevicePath != nullptr) { + *cameraDevicePath = "/dev/video" + std::to_string(std::stoi(sm[2]) - cameraIdOffset); } return true; } @@ -146,8 +148,9 @@ Return ExternalCameraProviderImpl_2_4::getCameraDeviceInterface_V3_x( const hidl_string& cameraDeviceName, ICameraProvider::getCameraDeviceInterface_V3_x_cb _hidl_cb) { - std::string cameraId, deviceVersion; - bool match = matchDeviceName(cameraDeviceName, &deviceVersion, &cameraId); + std::string cameraDevicePath, deviceVersion; + bool match = matchDeviceName(mCfg.cameraIdOffset, cameraDeviceName, + &deviceVersion, &cameraDevicePath); if (!match) { _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr); return Void(); @@ -164,19 +167,19 @@ Return ExternalCameraProviderImpl_2_4::getCameraDeviceInterface_V3_x( case 4: { ALOGV("Constructing v3.4 external camera device"); deviceImpl = new device::V3_4::implementation::ExternalCameraDevice( - cameraId, mCfg); + cameraDevicePath, mCfg); break; } case 5: { ALOGV("Constructing v3.5 external camera device"); deviceImpl = new device::V3_5::implementation::ExternalCameraDevice( - cameraId, mCfg); + cameraDevicePath, mCfg); break; } case 6: { ALOGV("Constructing v3.6 external camera device"); deviceImpl = new device::V3_6::implementation::ExternalCameraDevice( - cameraId, mCfg); + cameraDevicePath, mCfg); break; } default: @@ -186,7 +189,7 @@ Return ExternalCameraProviderImpl_2_4::getCameraDeviceInterface_V3_x( } if (deviceImpl == nullptr || deviceImpl->isInitFailed()) { - ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str()); + ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraDevicePath.c_str()); _hidl_cb(Status::INTERNAL_ERROR, nullptr); return Void(); } @@ -210,12 +213,14 @@ void ExternalCameraProviderImpl_2_4::addExternalCamera(const char* devName) { ALOGI("ExtCam: adding %s to External Camera HAL!", devName); Mutex::Autolock _l(mLock); std::string deviceName; + std::string cameraId = std::to_string(mCfg.cameraIdOffset + + std::atoi(devName + kDevicePrefixLen)); if (mPreferredHal3MinorVersion == 6) { - deviceName = std::string("device@3.6/external/") + devName; + deviceName = std::string("device@3.6/external/") + cameraId; } else if (mPreferredHal3MinorVersion == 5) { - deviceName = std::string("device@3.5/external/") + devName; + deviceName = std::string("device@3.5/external/") + cameraId; } else { - deviceName = std::string("device@3.4/external/") + devName; + deviceName = std::string("device@3.4/external/") + cameraId; } mCameraStatusMap[deviceName] = CameraDeviceStatus::PRESENT; if (mCallbacks != nullptr) { @@ -259,12 +264,14 @@ void ExternalCameraProviderImpl_2_4::deviceAdded(const char* devName) { void ExternalCameraProviderImpl_2_4::deviceRemoved(const char* devName) { Mutex::Autolock _l(mLock); std::string deviceName; + std::string cameraId = std::to_string(mCfg.cameraIdOffset + + std::atoi(devName + kDevicePrefixLen)); if (mPreferredHal3MinorVersion == 6) { - deviceName = std::string("device@3.6/external/") + devName; + deviceName = std::string("device@3.6/external/") + cameraId; } else if (mPreferredHal3MinorVersion == 5) { - deviceName = std::string("device@3.5/external/") + devName; + deviceName = std::string("device@3.5/external/") + cameraId; } else { - deviceName = std::string("device@3.4/external/") + devName; + deviceName = std::string("device@3.4/external/") + cameraId; } if (mCameraStatusMap.find(deviceName) != mCameraStatusMap.end()) { mCameraStatusMap.erase(deviceName); -- GitLab From 8dfac92fee6e1543f03687ff85cebb0247256766 Mon Sep 17 00:00:00 2001 From: Hao Chen Date: Fri, 14 Feb 2020 11:26:03 -0800 Subject: [PATCH 013/790] Split vehicle client and server interface header Since vehicle client may contains some Android-specific types/headers that may not exist on AGL, we split the header into "client" and "server". It won't change the logic of Android codes. Bug: 148877226 Test: build Change-Id: I550034b071ca6a7ca322fb26b61d76ed4a7307ee --- .../common/include/vhal_v2_0/VehicleClient.h | 73 +++++++++++++++++ .../include/vhal_v2_0/VehicleConnector.h | 82 +------------------ .../common/include/vhal_v2_0/VehicleServer.h | 76 +++++++++++++++++ 3 files changed, 152 insertions(+), 79 deletions(-) create mode 100644 automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleClient.h create mode 100644 automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleServer.h diff --git a/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleClient.h b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleClient.h new file mode 100644 index 0000000000..1e2f3add17 --- /dev/null +++ b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleClient.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +#include + +namespace android { +namespace hardware { +namespace automotive { +namespace vehicle { +namespace V2_0 { + +/** + * Vehicle HAL talks to the vehicle through a client, instead of accessing + * the car bus directly, to give us more flexibility on the implementation. + * Android OS do not need direct access to the vehicle, and the communication + * channel is also customizable. + * + * Client lives on the Android (HAL) side to talk to the vehicle + */ +class IVehicleClient { + public: + IVehicleClient() = default; + + IVehicleClient(const IVehicleClient&) = delete; + + IVehicleClient& operator=(const IVehicleClient&) = delete; + + IVehicleClient(IVehicleClient&&) = default; + + virtual ~IVehicleClient() = default; + + // Get configuration of all properties from server + virtual std::vector getAllPropertyConfig() const = 0; + + // Send the set property request to server + // updateStatus indicate if VHal should change the status of the value + // it should be false except injecting values for e2e tests + virtual StatusCode setProperty(const VehiclePropValue& value, bool updateStatus) = 0; + + // Receive a new property value from server + // updateStatus is true if and only if the value is + // generated by car (ECU/fake generator/injected) + virtual void onPropertyValue(const VehiclePropValue& value, bool updateStatus) = 0; + + // Dump method forwarded from HIDL's debug() + // If implemented, it must return whether the caller should dump its state. + virtual bool dump(const hidl_handle& /* handle */, const hidl_vec& /* options */) { + return true; + } +}; + +} // namespace V2_0 +} // namespace vehicle +} // namespace automotive +} // namespace hardware +} // namespace android diff --git a/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleConnector.h b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleConnector.h index 00b5afe217..2908a55c25 100644 --- a/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleConnector.h +++ b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleConnector.h @@ -21,6 +21,9 @@ #include +#include "VehicleClient.h" +#include "VehicleServer.h" + namespace android { namespace hardware { namespace automotive { @@ -33,85 +36,6 @@ namespace V2_0 { * regardless of the underlying communication channels. */ -/** - * Vehicle HAL talks to the vehicle through a client, instead of accessing - * the car bus directly, to give us more flexibility on the implementation. - * Android OS do not need direct access to the vehicle, and the communication - * channel is also customizable. - * - * Client lives on the Android (HAL) side to talk to the vehicle - */ -class IVehicleClient { - public: - IVehicleClient() = default; - - IVehicleClient(const IVehicleClient&) = delete; - - IVehicleClient& operator=(const IVehicleClient&) = delete; - - IVehicleClient(IVehicleClient&&) = default; - - virtual ~IVehicleClient() = default; - - // Get configuration of all properties from server - virtual std::vector getAllPropertyConfig() const = 0; - - // Send the set property request to server - // updateStatus indicate if VHal should change the status of the value - // it should be false except injecting values for e2e tests - virtual StatusCode setProperty(const VehiclePropValue& value, bool updateStatus) = 0; - - // Receive a new property value from server - // updateStatus is true if and only if the value is - // generated by car (ECU/fake generator/injected) - virtual void onPropertyValue(const VehiclePropValue& value, bool updateStatus) = 0; - - // Dump method forwarded from HIDL's debug() - // If implemented, it must return whether the caller should dump its state. - virtual bool dump(const hidl_handle& /* handle */, const hidl_vec& /* options */) { - return true; - } -}; - -/** - * Server lives on the vehicle side to talk to Android HAL - */ -class IVehicleServer { - public: - IVehicleServer() = default; - - IVehicleServer(const IVehicleServer&) = delete; - - IVehicleServer& operator=(const IVehicleServer&) = delete; - - IVehicleServer(IVehicleServer&&) = default; - - virtual ~IVehicleServer() = default; - - // Receive the get property configuration request from HAL. - // Return a list of all property config - virtual std::vector onGetAllPropertyConfig() const = 0; - - // Receive the set property request from HAL. - // Process the setting and return the status code - // updateStatus indicate if VHal should change the status of the value - // it should be false except injecting values for e2e tests - virtual StatusCode onSetProperty(const VehiclePropValue& value, bool updateStatus) = 0; - - // Receive a new property value from car (via direct connection to the car bus or the emulator) - // and forward the value to HAL - // updateStatus is true if and only if the value is - // generated by car (ECU/fake generator/injected) - virtual void onPropertyValueFromCar(const VehiclePropValue& value, bool updateStatus) = 0; - - // Dump method forwarded from HIDL's debug() - // If implemented, it must return whether the caller should dump its state. - virtual bool onDump(const hidl_handle& /* handle */, - const hidl_vec& /* options */) { - return true; - } -}; - /** * If Android has direct access to the vehicle, then the client and * the server may act in passthrough mode to avoid extra IPC diff --git a/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleServer.h b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleServer.h new file mode 100644 index 0000000000..27ebbeef55 --- /dev/null +++ b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleServer.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +#include + +namespace android { +namespace hardware { +namespace automotive { +namespace vehicle { +namespace V2_0 { + +/** + * Server lives on the vehicle side to talk to Android HAL. + * Note that the server may not be run on Android + */ +class IVehicleServer { + public: + IVehicleServer() = default; + + IVehicleServer(const IVehicleServer&) = delete; + + IVehicleServer& operator=(const IVehicleServer&) = delete; + + IVehicleServer(IVehicleServer&&) = default; + + virtual ~IVehicleServer() = default; + + // Receive the get property configuration request from HAL. + // Return a list of all property config + virtual std::vector onGetAllPropertyConfig() const = 0; + + // Receive the set property request from HAL. + // Process the setting and return the status code + // updateStatus indicate if VHal should change the status of the value + // it should be false except injecting values for e2e tests + virtual StatusCode onSetProperty(const VehiclePropValue& value, bool updateStatus) = 0; + + // Receive a new property value from car (via direct connection to the car bus or the emulator) + // and forward the value to HAL + // updateStatus is true if and only if the value is + // generated by car (ECU/fake generator/injected) + virtual void onPropertyValueFromCar(const VehiclePropValue& value, bool updateStatus) = 0; + + // TODO (chenhaosjtuacm): fix this since there are no HIDL in non-Android OS +#ifdef __ANDROID__ + // Dump method forwarded from HIDL's debug() + // If implemented, it must return whether the caller should dump its state. + virtual bool onDump(const hidl_handle& /* handle */, + const hidl_vec& /* options */) { + return true; + } +#endif // __ANDROID__ +}; + +} // namespace V2_0 +} // namespace vehicle +} // namespace automotive +} // namespace hardware +} // namespace android -- GitLab From 7e9e37fa0a6278f1af454229cafc0707c27cd4c3 Mon Sep 17 00:00:00 2001 From: Hao Chen Date: Fri, 14 Feb 2020 11:51:26 -0800 Subject: [PATCH 014/790] Split client and server impl Some of the code in VHAL client implementation contains Android-specific code, and some of the server operations only works in the native case. So we split them up so that the AGL VHAL server can selectivly pick the parts it needs. It won't change the logic of native VHAL. Bug: 148877226 Test: Build Change-Id: Ie142b19a5c435a0b4252ffd297504bde69eb44b0 --- automotive/vehicle/2.0/default/Android.bp | 2 + .../vhal_v2_0/EmulatedVehicleConnector.cpp | 350 +---------------- .../impl/vhal_v2_0/EmulatedVehicleConnector.h | 69 +--- .../impl/vhal_v2_0/EmulatedVehicleHal.cpp | 7 +- .../impl/vhal_v2_0/EmulatedVehicleHal.h | 4 +- .../impl/vhal_v2_0/VehicleHalClient.cpp | 39 ++ .../default/impl/vhal_v2_0/VehicleHalClient.h | 39 ++ .../impl/vhal_v2_0/VehicleHalServer.cpp | 353 ++++++++++++++++++ .../default/impl/vhal_v2_0/VehicleHalServer.h | 71 ++++ 9 files changed, 524 insertions(+), 410 deletions(-) create mode 100644 automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalClient.cpp create mode 100644 automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalClient.h create mode 100644 automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.cpp create mode 100644 automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.h diff --git a/automotive/vehicle/2.0/default/Android.bp b/automotive/vehicle/2.0/default/Android.bp index 8e579012cd..e529675203 100644 --- a/automotive/vehicle/2.0/default/Android.bp +++ b/automotive/vehicle/2.0/default/Android.bp @@ -63,6 +63,8 @@ cc_library_static { "impl/vhal_v2_0/CommConn.cpp", "impl/vhal_v2_0/EmulatedVehicleConnector.cpp", "impl/vhal_v2_0/EmulatedVehicleHal.cpp", + "impl/vhal_v2_0/VehicleHalClient.cpp", + "impl/vhal_v2_0/VehicleHalServer.cpp", "impl/vhal_v2_0/VehicleEmulator.cpp", "impl/vhal_v2_0/PipeComm.cpp", "impl/vhal_v2_0/ProtoMessageConverter.cpp", diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.cpp index 7f90914302..9c3c95facd 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.cpp +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.cpp @@ -35,346 +35,16 @@ namespace V2_0 { namespace impl { -void EmulatedVehicleClient::onPropertyValue(const VehiclePropValue& value, bool updateStatus) { - if (!mPropCallback) { - LOG(ERROR) << __func__ << ": PropertyCallBackType is not registered!"; - return; - } - return mPropCallback(value, updateStatus); -} - -void EmulatedVehicleClient::registerPropertyValueCallback(PropertyCallBackType&& callback) { - if (mPropCallback) { - LOG(ERROR) << __func__ << ": Cannot register multiple callbacks!"; - return; - } - mPropCallback = std::move(callback); -} - -GeneratorHub* EmulatedVehicleServer::getGenerator() { - return &mGeneratorHub; -} - -VehiclePropValuePool* EmulatedVehicleServer::getValuePool() const { - if (!mValuePool) { - LOG(WARNING) << __func__ << ": Value pool not set!"; - } - return mValuePool; -} - -void EmulatedVehicleServer::setValuePool(VehiclePropValuePool* valuePool) { - if (!valuePool) { - LOG(WARNING) << __func__ << ": Setting value pool to nullptr!"; - } - mValuePool = valuePool; -} - -void EmulatedVehicleServer::onFakeValueGenerated(const VehiclePropValue& value) { - constexpr bool updateStatus = true; - LOG(DEBUG) << __func__ << ": " << toString(value); - auto updatedPropValue = getValuePool()->obtain(value); - if (updatedPropValue) { - updatedPropValue->timestamp = value.timestamp; - updatedPropValue->status = VehiclePropertyStatus::AVAILABLE; - onPropertyValueFromCar(*updatedPropValue, updateStatus); - } -} - -std::vector EmulatedVehicleServer::onGetAllPropertyConfig() const { - std::vector vehiclePropConfigs; - constexpr size_t numOfVehiclePropConfigs = - sizeof(kVehicleProperties) / sizeof(kVehicleProperties[0]); - vehiclePropConfigs.reserve(numOfVehiclePropConfigs); - for (auto& it : kVehicleProperties) { - vehiclePropConfigs.emplace_back(it.config); - } - return vehiclePropConfigs; -} - -StatusCode EmulatedVehicleServer::handleGenerateFakeDataRequest(const VehiclePropValue& request) { - constexpr bool updateStatus = true; - - LOG(INFO) << __func__; - const auto& v = request.value; - if (!v.int32Values.size()) { - LOG(ERROR) << __func__ << ": expected at least \"command\" field in int32Values"; - return StatusCode::INVALID_ARG; - } - - FakeDataCommand command = static_cast(v.int32Values[0]); - - switch (command) { - case FakeDataCommand::StartLinear: { - LOG(INFO) << __func__ << ", FakeDataCommand::StartLinear"; - if (v.int32Values.size() < 2) { - LOG(ERROR) << __func__ << ": expected property ID in int32Values"; - return StatusCode::INVALID_ARG; - } - if (!v.int64Values.size()) { - LOG(ERROR) << __func__ << ": interval is not provided in int64Values"; - return StatusCode::INVALID_ARG; - } - if (v.floatValues.size() < 3) { - LOG(ERROR) << __func__ << ": expected at least 3 elements in floatValues, got: " - << v.floatValues.size(); - return StatusCode::INVALID_ARG; - } - int32_t cookie = v.int32Values[1]; - getGenerator()->registerGenerator(cookie, - std::make_unique(request)); - break; - } - case FakeDataCommand::StartJson: { - LOG(INFO) << __func__ << ", FakeDataCommand::StartJson"; - if (v.stringValue.empty()) { - LOG(ERROR) << __func__ << ": path to JSON file is missing"; - return StatusCode::INVALID_ARG; - } - int32_t cookie = std::hash()(v.stringValue); - getGenerator()->registerGenerator(cookie, - std::make_unique(request)); - break; - } - case FakeDataCommand::StopLinear: { - LOG(INFO) << __func__ << ", FakeDataCommand::StopLinear"; - if (v.int32Values.size() < 2) { - LOG(ERROR) << __func__ << ": expected property ID in int32Values"; - return StatusCode::INVALID_ARG; - } - int32_t cookie = v.int32Values[1]; - getGenerator()->unregisterGenerator(cookie); - break; - } - case FakeDataCommand::StopJson: { - LOG(INFO) << __func__ << ", FakeDataCommand::StopJson"; - if (v.stringValue.empty()) { - LOG(ERROR) << __func__ << ": path to JSON file is missing"; - return StatusCode::INVALID_ARG; - } - int32_t cookie = std::hash()(v.stringValue); - getGenerator()->unregisterGenerator(cookie); - break; - } - case FakeDataCommand::KeyPress: { - LOG(INFO) << __func__ << ", FakeDataCommand::KeyPress"; - int32_t keyCode = request.value.int32Values[2]; - int32_t display = request.value.int32Values[3]; - // Send back to HAL - onPropertyValueFromCar( - *createHwInputKeyProp(VehicleHwKeyInputAction::ACTION_DOWN, keyCode, display), - updateStatus); - onPropertyValueFromCar( - *createHwInputKeyProp(VehicleHwKeyInputAction::ACTION_UP, keyCode, display), - updateStatus); - break; - } - default: { - LOG(ERROR) << __func__ << ": unexpected command: " << toInt(command); - return StatusCode::INVALID_ARG; - } - } - return StatusCode::OK; -} - -VehicleHal::VehiclePropValuePtr EmulatedVehicleServer::createApPowerStateReq( - VehicleApPowerStateReq state, int32_t param) { - auto req = getValuePool()->obtain(VehiclePropertyType::INT32_VEC, 2); - req->prop = toInt(VehicleProperty::AP_POWER_STATE_REQ); - req->areaId = 0; - req->timestamp = elapsedRealtimeNano(); - req->status = VehiclePropertyStatus::AVAILABLE; - req->value.int32Values[0] = toInt(state); - req->value.int32Values[1] = param; - return req; -} - -VehicleHal::VehiclePropValuePtr EmulatedVehicleServer::createHwInputKeyProp( - VehicleHwKeyInputAction action, int32_t keyCode, int32_t targetDisplay) { - auto keyEvent = getValuePool()->obtain(VehiclePropertyType::INT32_VEC, 3); - keyEvent->prop = toInt(VehicleProperty::HW_KEY_INPUT); - keyEvent->areaId = 0; - keyEvent->timestamp = elapsedRealtimeNano(); - keyEvent->status = VehiclePropertyStatus::AVAILABLE; - keyEvent->value.int32Values[0] = toInt(action); - keyEvent->value.int32Values[1] = keyCode; - keyEvent->value.int32Values[2] = targetDisplay; - return keyEvent; -} +class EmulatedPassthroughConnector : public PassthroughConnector { + public: + bool onDump(const hidl_handle& fd, const hidl_vec& options) override; -StatusCode EmulatedVehicleServer::onSetProperty(const VehiclePropValue& value, bool updateStatus) { - // Some properties need to be treated non-trivially - switch (value.prop) { - case kGenerateFakeDataControllingProperty: - return handleGenerateFakeDataRequest(value); - - // set the value from vehicle side, used in end to end test. - case kSetIntPropertyFromVehicleForTest: { - auto updatedPropValue = createVehiclePropValue(VehiclePropertyType::INT32, 1); - updatedPropValue->prop = value.value.int32Values[0]; - updatedPropValue->value.int32Values[0] = value.value.int32Values[1]; - updatedPropValue->timestamp = value.value.int64Values[0]; - updatedPropValue->areaId = value.areaId; - onPropertyValueFromCar(*updatedPropValue, updateStatus); - return StatusCode::OK; - } - case kSetFloatPropertyFromVehicleForTest: { - auto updatedPropValue = createVehiclePropValue(VehiclePropertyType::FLOAT, 1); - updatedPropValue->prop = value.value.int32Values[0]; - updatedPropValue->value.floatValues[0] = value.value.floatValues[0]; - updatedPropValue->timestamp = value.value.int64Values[0]; - updatedPropValue->areaId = value.areaId; - onPropertyValueFromCar(*updatedPropValue, updateStatus); - return StatusCode::OK; - } - case kSetBooleanPropertyFromVehicleForTest: { - auto updatedPropValue = createVehiclePropValue(VehiclePropertyType::BOOLEAN, 1); - updatedPropValue->prop = value.value.int32Values[1]; - updatedPropValue->value.int32Values[0] = value.value.int32Values[0]; - updatedPropValue->timestamp = value.value.int64Values[0]; - updatedPropValue->areaId = value.areaId; - onPropertyValueFromCar(*updatedPropValue, updateStatus); - return StatusCode::OK; - } - - case AP_POWER_STATE_REPORT: - switch (value.value.int32Values[0]) { - case toInt(VehicleApPowerStateReport::DEEP_SLEEP_EXIT): - case toInt(VehicleApPowerStateReport::SHUTDOWN_CANCELLED): - case toInt(VehicleApPowerStateReport::WAIT_FOR_VHAL): - // CPMS is in WAIT_FOR_VHAL state, simply move to ON - // Send back to HAL - // ALWAYS update status for generated property value - onPropertyValueFromCar(*createApPowerStateReq(VehicleApPowerStateReq::ON, 0), - true /* updateStatus */); - break; - case toInt(VehicleApPowerStateReport::DEEP_SLEEP_ENTRY): - case toInt(VehicleApPowerStateReport::SHUTDOWN_START): - // CPMS is in WAIT_FOR_FINISH state, send the FINISHED command - // Send back to HAL - // ALWAYS update status for generated property value - onPropertyValueFromCar( - *createApPowerStateReq(VehicleApPowerStateReq::FINISHED, 0), - true /* updateStatus */); - break; - case toInt(VehicleApPowerStateReport::ON): - case toInt(VehicleApPowerStateReport::SHUTDOWN_POSTPONE): - case toInt(VehicleApPowerStateReport::SHUTDOWN_PREPARE): - // Do nothing - break; - default: - // Unknown state - break; - } - break; - case INITIAL_USER_INFO: - return onSetInitialUserInfo(value, updateStatus); - default: - break; - } - - // In the real vhal, the value will be sent to Car ECU. - // We just pretend it is done here and send back to HAL - auto updatedPropValue = getValuePool()->obtain(value); - updatedPropValue->timestamp = elapsedRealtimeNano(); - - onPropertyValueFromCar(*updatedPropValue, updateStatus); - return StatusCode::OK; -} - -/** - * INITIAL_USER_INFO is called by Android when it starts, and it's expecting a property change - * indicating what the initial user should be. - * - * During normal circumstances, the emulator will reply right away, passing a response if - * InitialUserInfoResponseAction::DEFAULT (so Android could use its own logic to decide which user - * to boot). - * - * But during development / testing, the behavior can be changed using lshal dump, which must use - * the areaId to indicate what should happen next. - * - * So, the behavior of set(INITIAL_USER_INFO) is: - * - * - if it has an areaId, store the property into mInitialUserResponseFromCmd (as it was called by - * lshal). - * - else if mInitialUserResponseFromCmd is not set, return a response with the same request id and - * InitialUserInfoResponseAction::DEFAULT - * - else the behavior is defined by the areaId on mInitialUserResponseFromCmd: - * - if it's 1, reply with mInitialUserResponseFromCmd and the right request id - * - if it's 2, reply with mInitialUserResponseFromCmd but a wrong request id (so Android can test - * this error scenario) - * - if it's 3, then don't send a property change (so Android can emulate a timeout) - * - */ -StatusCode EmulatedVehicleServer::onSetInitialUserInfo(const VehiclePropValue& value, - bool updateStatus) { - // TODO: LOG calls below might be more suited to be DEBUG, but those are not being logged - // (even when explicitly calling setprop log.tag. As this class should be using ALOG instead of - // LOG, it's not worth investigating why... - - if (value.value.int32Values.size() == 0) { - LOG(ERROR) << "set(INITIAL_USER_INFO): no int32values, ignoring it: " << toString(value); - return StatusCode::INVALID_ARG; - } - - if (value.areaId != 0) { - LOG(INFO) << "set(INITIAL_USER_INFO) called from lshal; storing it: " << toString(value); - mInitialUserResponseFromCmd.reset(new VehiclePropValue(value)); - return StatusCode::OK; - } - LOG(INFO) << "set(INITIAL_USER_INFO) called from Android: " << toString(value); - - int32_t requestId = value.value.int32Values[0]; - - // Create the update property and set common values - auto updatedValue = createVehiclePropValue(VehiclePropertyType::MIXED, 0); - updatedValue->prop = INITIAL_USER_INFO; - updatedValue->timestamp = elapsedRealtimeNano(); - - if (mInitialUserResponseFromCmd == nullptr) { - updatedValue->value.int32Values.resize(2); - updatedValue->value.int32Values[0] = requestId; - updatedValue->value.int32Values[1] = (int32_t)InitialUserInfoResponseAction::DEFAULT; - LOG(INFO) << "no lshal response; returning InitialUserInfoResponseAction::DEFAULT: " - << toString(*updatedValue); - onPropertyValueFromCar(*updatedValue, updateStatus); - return StatusCode::OK; - } - - // mInitialUserResponseFromCmd is used for just one request - std::unique_ptr response = std::move(mInitialUserResponseFromCmd); - - // TODO(b/138709788): rather than populate the raw values directly, it should use the - // libraries that convert a InitialUserInfoResponse into a VehiclePropValue) - - switch (response->areaId) { - case 1: - LOG(INFO) << "returning response with right request id"; - *updatedValue = *response; - updatedValue->areaId = 0; - updatedValue->value.int32Values[0] = requestId; - break; - case 2: - LOG(INFO) << "returning response with wrong request id"; - *updatedValue = *response; - updatedValue->areaId = 0; - updatedValue->value.int32Values[0] = -requestId; - break; - case 3: - LOG(INFO) << "not generating a property change event because of lshal prop: " - << toString(*response); - return StatusCode::OK; - default: - LOG(ERROR) << "invalid action on lshal response: " << toString(*response); - return StatusCode::INTERNAL_ERROR; - } - - LOG(INFO) << "updating property to: " << toString(*updatedValue); - onPropertyValueFromCar(*updatedValue, updateStatus); - return StatusCode::OK; -} + private: + void dumpUserHal(int fd, std::string indent); +}; -bool EmulatedVehicleServer::onDump(const hidl_handle& handle, - const hidl_vec& options) { +bool EmulatedPassthroughConnector::onDump(const hidl_handle& handle, + const hidl_vec& options) { int fd = handle->data[0]; if (options.size() > 0) { @@ -401,7 +71,7 @@ bool EmulatedVehicleServer::onDump(const hidl_handle& handle, return true; } -void EmulatedVehicleServer::dumpUserHal(int fd, std::string indent) { +void EmulatedPassthroughConnector::dumpUserHal(int fd, std::string indent) { if (mInitialUserResponseFromCmd != nullptr) { dprintf(fd, "%sInitial User Info: %s\n", indent.c_str(), toString(*mInitialUserResponseFromCmd).c_str()); @@ -410,7 +80,7 @@ void EmulatedVehicleServer::dumpUserHal(int fd, std::string indent) { } } -EmulatedPassthroughConnectorPtr makeEmulatedPassthroughConnector() { +PassthroughConnectorPtr makeEmulatedPassthroughConnector() { return std::make_unique(); } diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.h index 4850d32d94..57cbb8b893 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.h +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.h @@ -18,9 +18,9 @@ #define android_hardware_automotive_vehicle_V2_0_impl_EmulatedVehicleConnector_H_ #include -#include -#include "GeneratorHub.h" +#include "VehicleHalClient.h" +#include "VehicleHalServer.h" namespace android { namespace hardware { @@ -30,69 +30,10 @@ namespace V2_0 { namespace impl { -// Extension of the client/server interfaces for emulated vehicle +using PassthroughConnector = IPassThroughConnector; +using PassthroughConnectorPtr = std::unique_ptr; -class EmulatedVehicleClient : public IVehicleClient { - public: - // Type of callback function for handling the new property values - using PropertyCallBackType = std::function; - - // Method from IVehicleClient - void onPropertyValue(const VehiclePropValue& value, bool updateStatus) override; - - void registerPropertyValueCallback(PropertyCallBackType&& callback); - - private: - PropertyCallBackType mPropCallback; -}; - -class EmulatedVehicleServer : public IVehicleServer { - public: - // Methods from IVehicleServer - - std::vector onGetAllPropertyConfig() const override; - - StatusCode onSetProperty(const VehiclePropValue& value, bool updateStatus) override; - - bool onDump(const hidl_handle& fd, const hidl_vec& options) override; - - // Set the Property Value Pool used in this server - void setValuePool(VehiclePropValuePool* valuePool); - - private: - GeneratorHub* getGenerator(); - - VehiclePropValuePool* getValuePool() const; - - void onFakeValueGenerated(const VehiclePropValue& value); - - StatusCode handleGenerateFakeDataRequest(const VehiclePropValue& request); - - VehicleHal::VehiclePropValuePtr createApPowerStateReq(VehicleApPowerStateReq req, int32_t param); - - VehicleHal::VehiclePropValuePtr createHwInputKeyProp(VehicleHwKeyInputAction action, - int32_t keyCode, int32_t targetDisplay); - - // private data members - - GeneratorHub mGeneratorHub{ - std::bind(&EmulatedVehicleServer::onFakeValueGenerated, this, std::placeholders::_1)}; - - VehiclePropValuePool* mValuePool{nullptr}; - - // TODO(b/146207078): it might be clearer to move members below to an EmulatedUserHal class - std::unique_ptr mInitialUserResponseFromCmd; - StatusCode onSetInitialUserInfo(const VehiclePropValue& value, bool updateStatus); - void dumpUserHal(int fd, std::string indent); -}; - -// Helper functions - -using EmulatedPassthroughConnector = - IPassThroughConnector; -using EmulatedPassthroughConnectorPtr = std::unique_ptr; - -EmulatedPassthroughConnectorPtr makeEmulatedPassthroughConnector(); +PassthroughConnectorPtr makeEmulatedPassthroughConnector(); } // namespace impl diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp index 692c7f791f..6d5f23f7fc 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp @@ -87,12 +87,11 @@ static std::unique_ptr fillDefaultObd2Frame(size_t numVendorInt return sensorStore; } -EmulatedVehicleHal::EmulatedVehicleHal(VehiclePropertyStore* propStore, - EmulatedVehicleClient* client) +EmulatedVehicleHal::EmulatedVehicleHal(VehiclePropertyStore* propStore, VehicleHalClient* client) : mPropStore(propStore), mHvacPowerProps(std::begin(kHvacPowerProperties), std::end(kHvacPowerProperties)), - mRecurrentTimer( - std::bind(&EmulatedVehicleHal::onContinuousPropertyTimer, this, std::placeholders::_1)), + mRecurrentTimer(std::bind(&EmulatedVehicleHal::onContinuousPropertyTimer, this, + std::placeholders::_1)), mVehicleClient(client) { initStaticConfig(); for (size_t i = 0; i < arraysize(kVehicleProperties); i++) { diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h index ebc405e04a..ebf19951b3 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h @@ -46,7 +46,7 @@ namespace impl { class EmulatedVehicleHal : public EmulatedVehicleHalIface { public: EmulatedVehicleHal(VehiclePropertyStore* propStore, - EmulatedVehicleClient* client); + VehicleHalClient* client); ~EmulatedVehicleHal() = default; // Methods from VehicleHal @@ -85,7 +85,7 @@ private: VehiclePropertyStore* mPropStore; std::unordered_set mHvacPowerProps; RecurrentTimer mRecurrentTimer; - EmulatedVehicleClient* mVehicleClient; + VehicleHalClient* mVehicleClient; }; } // impl diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalClient.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalClient.cpp new file mode 100644 index 0000000000..25ffc6d70d --- /dev/null +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalClient.cpp @@ -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. + */ + +#include "VehicleHalClient.h" + +#include + +namespace android::hardware::automotive::vehicle::V2_0::impl { + +void VehicleHalClient::onPropertyValue(const VehiclePropValue& value, bool updateStatus) { + if (!mPropCallback) { + LOG(ERROR) << __func__ << ": PropertyCallBackType is not registered!"; + return; + } + return mPropCallback(value, updateStatus); +} + +void VehicleHalClient::registerPropertyValueCallback(PropertyCallBackType&& callback) { + if (mPropCallback) { + LOG(ERROR) << __func__ << ": Cannot register multiple callbacks!"; + return; + } + mPropCallback = std::move(callback); +} + +} // namespace android::hardware::automotive::vehicle::V2_0::impl diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalClient.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalClient.h new file mode 100644 index 0000000000..6559e2aa84 --- /dev/null +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalClient.h @@ -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. + */ + +#pragma once + +#include + +namespace android::hardware::automotive::vehicle::V2_0::impl { + +// The common client operations that may be used by both native and +// virtualized VHAL clients. +class VehicleHalClient : public IVehicleClient { + public: + // Type of callback function for handling the new property values + using PropertyCallBackType = std::function; + + // Method from IVehicleClient + void onPropertyValue(const VehiclePropValue& value, bool updateStatus) override; + + void registerPropertyValueCallback(PropertyCallBackType&& callback); + + private: + PropertyCallBackType mPropCallback; +}; + +} // namespace android::hardware::automotive::vehicle::V2_0::impl diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.cpp new file mode 100644 index 0000000000..a91ca8e770 --- /dev/null +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.cpp @@ -0,0 +1,353 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "VehicleHalServer.h" + +#include + +#include +#include + +#include "DefaultConfig.h" +#include "JsonFakeValueGenerator.h" +#include "LinearFakeValueGenerator.h" +#include "Obd2SensorStore.h" + +namespace android::hardware::automotive::vehicle::V2_0::impl { + +GeneratorHub* VehicleHalServer::getGenerator() { + return &mGeneratorHub; +} + +VehiclePropValuePool* VehicleHalServer::getValuePool() const { + if (!mValuePool) { + LOG(WARNING) << __func__ << ": Value pool not set!"; + } + return mValuePool; +} + +void VehicleHalServer::setValuePool(VehiclePropValuePool* valuePool) { + if (!valuePool) { + LOG(WARNING) << __func__ << ": Setting value pool to nullptr!"; + } + mValuePool = valuePool; +} + +void VehicleHalServer::onFakeValueGenerated(const VehiclePropValue& value) { + constexpr bool updateStatus = true; + LOG(DEBUG) << __func__ << ": " << toString(value); + auto updatedPropValue = getValuePool()->obtain(value); + if (updatedPropValue) { + updatedPropValue->timestamp = value.timestamp; + updatedPropValue->status = VehiclePropertyStatus::AVAILABLE; + onPropertyValueFromCar(*updatedPropValue, updateStatus); + } +} + +std::vector VehicleHalServer::onGetAllPropertyConfig() const { + std::vector vehiclePropConfigs; + constexpr size_t numOfVehiclePropConfigs = + sizeof(kVehicleProperties) / sizeof(kVehicleProperties[0]); + vehiclePropConfigs.reserve(numOfVehiclePropConfigs); + for (auto& it : kVehicleProperties) { + vehiclePropConfigs.emplace_back(it.config); + } + return vehiclePropConfigs; +} + +StatusCode VehicleHalServer::handleGenerateFakeDataRequest(const VehiclePropValue& request) { + constexpr bool updateStatus = true; + + LOG(INFO) << __func__; + const auto& v = request.value; + if (!v.int32Values.size()) { + LOG(ERROR) << __func__ << ": expected at least \"command\" field in int32Values"; + return StatusCode::INVALID_ARG; + } + + FakeDataCommand command = static_cast(v.int32Values[0]); + + switch (command) { + case FakeDataCommand::StartLinear: { + LOG(INFO) << __func__ << ", FakeDataCommand::StartLinear"; + if (v.int32Values.size() < 2) { + LOG(ERROR) << __func__ << ": expected property ID in int32Values"; + return StatusCode::INVALID_ARG; + } + if (!v.int64Values.size()) { + LOG(ERROR) << __func__ << ": interval is not provided in int64Values"; + return StatusCode::INVALID_ARG; + } + if (v.floatValues.size() < 3) { + LOG(ERROR) << __func__ << ": expected at least 3 elements in floatValues, got: " + << v.floatValues.size(); + return StatusCode::INVALID_ARG; + } + int32_t cookie = v.int32Values[1]; + getGenerator()->registerGenerator(cookie, + std::make_unique(request)); + break; + } + case FakeDataCommand::StartJson: { + LOG(INFO) << __func__ << ", FakeDataCommand::StartJson"; + if (v.stringValue.empty()) { + LOG(ERROR) << __func__ << ": path to JSON file is missing"; + return StatusCode::INVALID_ARG; + } + int32_t cookie = std::hash()(v.stringValue); + getGenerator()->registerGenerator(cookie, + std::make_unique(request)); + break; + } + case FakeDataCommand::StopLinear: { + LOG(INFO) << __func__ << ", FakeDataCommand::StopLinear"; + if (v.int32Values.size() < 2) { + LOG(ERROR) << __func__ << ": expected property ID in int32Values"; + return StatusCode::INVALID_ARG; + } + int32_t cookie = v.int32Values[1]; + getGenerator()->unregisterGenerator(cookie); + break; + } + case FakeDataCommand::StopJson: { + LOG(INFO) << __func__ << ", FakeDataCommand::StopJson"; + if (v.stringValue.empty()) { + LOG(ERROR) << __func__ << ": path to JSON file is missing"; + return StatusCode::INVALID_ARG; + } + int32_t cookie = std::hash()(v.stringValue); + getGenerator()->unregisterGenerator(cookie); + break; + } + case FakeDataCommand::KeyPress: { + LOG(INFO) << __func__ << ", FakeDataCommand::KeyPress"; + int32_t keyCode = request.value.int32Values[2]; + int32_t display = request.value.int32Values[3]; + // Send back to HAL + onPropertyValueFromCar( + *createHwInputKeyProp(VehicleHwKeyInputAction::ACTION_DOWN, keyCode, display), + updateStatus); + onPropertyValueFromCar( + *createHwInputKeyProp(VehicleHwKeyInputAction::ACTION_UP, keyCode, display), + updateStatus); + break; + } + default: { + LOG(ERROR) << __func__ << ": unexpected command: " << toInt(command); + return StatusCode::INVALID_ARG; + } + } + return StatusCode::OK; +} + +VehicleHalServer::VehiclePropValuePtr VehicleHalServer::createApPowerStateReq( + VehicleApPowerStateReq state, int32_t param) { + auto req = getValuePool()->obtain(VehiclePropertyType::INT32_VEC, 2); + req->prop = toInt(VehicleProperty::AP_POWER_STATE_REQ); + req->areaId = 0; + req->timestamp = elapsedRealtimeNano(); + req->status = VehiclePropertyStatus::AVAILABLE; + req->value.int32Values[0] = toInt(state); + req->value.int32Values[1] = param; + return req; +} + +VehicleHalServer::VehiclePropValuePtr VehicleHalServer::createHwInputKeyProp( + VehicleHwKeyInputAction action, int32_t keyCode, int32_t targetDisplay) { + auto keyEvent = getValuePool()->obtain(VehiclePropertyType::INT32_VEC, 3); + keyEvent->prop = toInt(VehicleProperty::HW_KEY_INPUT); + keyEvent->areaId = 0; + keyEvent->timestamp = elapsedRealtimeNano(); + keyEvent->status = VehiclePropertyStatus::AVAILABLE; + keyEvent->value.int32Values[0] = toInt(action); + keyEvent->value.int32Values[1] = keyCode; + keyEvent->value.int32Values[2] = targetDisplay; + return keyEvent; +} + +StatusCode VehicleHalServer::onSetProperty(const VehiclePropValue& value, bool updateStatus) { + // Some properties need to be treated non-trivially + switch (value.prop) { + case kGenerateFakeDataControllingProperty: + return handleGenerateFakeDataRequest(value); + + // set the value from vehicle side, used in end to end test. + case kSetIntPropertyFromVehicleForTest: { + auto updatedPropValue = createVehiclePropValue(VehiclePropertyType::INT32, 1); + updatedPropValue->prop = value.value.int32Values[0]; + updatedPropValue->value.int32Values[0] = value.value.int32Values[1]; + updatedPropValue->timestamp = value.value.int64Values[0]; + updatedPropValue->areaId = value.areaId; + onPropertyValueFromCar(*updatedPropValue, updateStatus); + return StatusCode::OK; + } + case kSetFloatPropertyFromVehicleForTest: { + auto updatedPropValue = createVehiclePropValue(VehiclePropertyType::FLOAT, 1); + updatedPropValue->prop = value.value.int32Values[0]; + updatedPropValue->value.floatValues[0] = value.value.floatValues[0]; + updatedPropValue->timestamp = value.value.int64Values[0]; + updatedPropValue->areaId = value.areaId; + onPropertyValueFromCar(*updatedPropValue, updateStatus); + return StatusCode::OK; + } + case kSetBooleanPropertyFromVehicleForTest: { + auto updatedPropValue = createVehiclePropValue(VehiclePropertyType::BOOLEAN, 1); + updatedPropValue->prop = value.value.int32Values[1]; + updatedPropValue->value.int32Values[0] = value.value.int32Values[0]; + updatedPropValue->timestamp = value.value.int64Values[0]; + updatedPropValue->areaId = value.areaId; + onPropertyValueFromCar(*updatedPropValue, updateStatus); + return StatusCode::OK; + } + + case AP_POWER_STATE_REPORT: + switch (value.value.int32Values[0]) { + case toInt(VehicleApPowerStateReport::DEEP_SLEEP_EXIT): + case toInt(VehicleApPowerStateReport::SHUTDOWN_CANCELLED): + case toInt(VehicleApPowerStateReport::WAIT_FOR_VHAL): + // CPMS is in WAIT_FOR_VHAL state, simply move to ON + // Send back to HAL + // ALWAYS update status for generated property value + onPropertyValueFromCar(*createApPowerStateReq(VehicleApPowerStateReq::ON, 0), + true /* updateStatus */); + break; + case toInt(VehicleApPowerStateReport::DEEP_SLEEP_ENTRY): + case toInt(VehicleApPowerStateReport::SHUTDOWN_START): + // CPMS is in WAIT_FOR_FINISH state, send the FINISHED command + // Send back to HAL + // ALWAYS update status for generated property value + onPropertyValueFromCar( + *createApPowerStateReq(VehicleApPowerStateReq::FINISHED, 0), + true /* updateStatus */); + break; + case toInt(VehicleApPowerStateReport::ON): + case toInt(VehicleApPowerStateReport::SHUTDOWN_POSTPONE): + case toInt(VehicleApPowerStateReport::SHUTDOWN_PREPARE): + // Do nothing + break; + default: + // Unknown state + break; + } + break; + case INITIAL_USER_INFO: + return onSetInitialUserInfo(value, updateStatus); + default: + break; + } + + // In the real vhal, the value will be sent to Car ECU. + // We just pretend it is done here and send back to HAL + auto updatedPropValue = getValuePool()->obtain(value); + updatedPropValue->timestamp = elapsedRealtimeNano(); + + onPropertyValueFromCar(*updatedPropValue, updateStatus); + return StatusCode::OK; +} + +/** + * INITIAL_USER_INFO is called by Android when it starts, and it's expecting a property change + * indicating what the initial user should be. + * + * During normal circumstances, the emulator will reply right away, passing a response if + * InitialUserInfoResponseAction::DEFAULT (so Android could use its own logic to decide which user + * to boot). + * + * But during development / testing, the behavior can be changed using lshal dump, which must use + * the areaId to indicate what should happen next. + * + * So, the behavior of set(INITIAL_USER_INFO) is: + * + * - if it has an areaId, store the property into mInitialUserResponseFromCmd (as it was called by + * lshal). + * - else if mInitialUserResponseFromCmd is not set, return a response with the same request id and + * InitialUserInfoResponseAction::DEFAULT + * - else the behavior is defined by the areaId on mInitialUserResponseFromCmd: + * - if it's 1, reply with mInitialUserResponseFromCmd and the right request id + * - if it's 2, reply with mInitialUserResponseFromCmd but a wrong request id (so Android can test + * this error scenario) + * - if it's 3, then don't send a property change (so Android can emulate a timeout) + * + */ +StatusCode VehicleHalServer::onSetInitialUserInfo(const VehiclePropValue& value, + bool updateStatus) { + // TODO: LOG calls below might be more suited to be DEBUG, but those are not being logged + // (even when explicitly calling setprop log.tag. As this class should be using ALOG instead of + // LOG, it's not worth investigating why... + + if (value.value.int32Values.size() == 0) { + LOG(ERROR) << "set(INITIAL_USER_INFO): no int32values, ignoring it: " << toString(value); + return StatusCode::INVALID_ARG; + } + + if (value.areaId != 0) { + LOG(INFO) << "set(INITIAL_USER_INFO) called from lshal; storing it: " << toString(value); + mInitialUserResponseFromCmd.reset(new VehiclePropValue(value)); + return StatusCode::OK; + } + LOG(INFO) << "set(INITIAL_USER_INFO) called from Android: " << toString(value); + + int32_t requestId = value.value.int32Values[0]; + + // Create the update property and set common values + auto updatedValue = createVehiclePropValue(VehiclePropertyType::MIXED, 0); + updatedValue->prop = INITIAL_USER_INFO; + updatedValue->timestamp = elapsedRealtimeNano(); + + if (mInitialUserResponseFromCmd == nullptr) { + updatedValue->value.int32Values.resize(2); + updatedValue->value.int32Values[0] = requestId; + updatedValue->value.int32Values[1] = (int32_t)InitialUserInfoResponseAction::DEFAULT; + LOG(INFO) << "no lshal response; returning InitialUserInfoResponseAction::DEFAULT: " + << toString(*updatedValue); + onPropertyValueFromCar(*updatedValue, updateStatus); + return StatusCode::OK; + } + + // mInitialUserResponseFromCmd is used for just one request + std::unique_ptr response = std::move(mInitialUserResponseFromCmd); + + // TODO(b/138709788): rather than populate the raw values directly, it should use the + // libraries that convert a InitialUserInfoResponse into a VehiclePropValue) + + switch (response->areaId) { + case 1: + LOG(INFO) << "returning response with right request id"; + *updatedValue = *response; + updatedValue->areaId = 0; + updatedValue->value.int32Values[0] = requestId; + break; + case 2: + LOG(INFO) << "returning response with wrong request id"; + *updatedValue = *response; + updatedValue->areaId = 0; + updatedValue->value.int32Values[0] = -requestId; + break; + case 3: + LOG(INFO) << "not generating a property change event because of lshal prop: " + << toString(*response); + return StatusCode::OK; + default: + LOG(ERROR) << "invalid action on lshal response: " << toString(*response); + return StatusCode::INTERNAL_ERROR; + } + + LOG(INFO) << "updating property to: " << toString(*updatedValue); + onPropertyValueFromCar(*updatedValue, updateStatus); + return StatusCode::OK; +} + +} // namespace android::hardware::automotive::vehicle::V2_0::impl diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.h new file mode 100644 index 0000000000..b1ae106331 --- /dev/null +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include + +#include "GeneratorHub.h" + +namespace android::hardware::automotive::vehicle::V2_0::impl { + +// This contains the common server operations that will be used by +// both native and virtualized VHAL server. Notice that in the virtualized +// scenario, the server may be run on a different OS than Android. +class VehicleHalServer : public IVehicleServer { + public: + // Methods from IVehicleServer + + std::vector onGetAllPropertyConfig() const override; + + StatusCode onSetProperty(const VehiclePropValue& value, bool updateStatus) override; + + // Set the Property Value Pool used in this server + void setValuePool(VehiclePropValuePool* valuePool); + + private: + using VehiclePropValuePtr = recyclable_ptr; + + GeneratorHub* getGenerator(); + + VehiclePropValuePool* getValuePool() const; + + void onFakeValueGenerated(const VehiclePropValue& value); + + StatusCode handleGenerateFakeDataRequest(const VehiclePropValue& request); + + VehiclePropValuePtr createApPowerStateReq(VehicleApPowerStateReq req, int32_t param); + + VehiclePropValuePtr createHwInputKeyProp(VehicleHwKeyInputAction action, int32_t keyCode, + int32_t targetDisplay); + + StatusCode onSetInitialUserInfo(const VehiclePropValue& value, bool updateStatus); + + // data members + + protected: + // TODO(b/146207078): it might be clearer to move members below to an EmulatedUserHal class + std::unique_ptr mInitialUserResponseFromCmd; + + private: + GeneratorHub mGeneratorHub{ + std::bind(&VehicleHalServer::onFakeValueGenerated, this, std::placeholders::_1)}; + + VehiclePropValuePool* mValuePool{nullptr}; +}; + +} // namespace android::hardware::automotive::vehicle::V2_0::impl -- GitLab From 5f7c1aae49825463572f4b4624bbaa3eb179b567 Mon Sep 17 00:00:00 2001 From: Hao Chen Date: Tue, 25 Feb 2020 13:20:41 -0800 Subject: [PATCH 015/790] Merge nested namesapces fix the nits in ag/10318156 Test: build Change-Id: I44609f8c7cbeffcb02cb9f2e2f56f3a829de17f6 --- .../default/common/include/vhal_v2_0/VehicleClient.h | 12 ++---------- .../default/common/include/vhal_v2_0/VehicleServer.h | 12 ++---------- 2 files changed, 4 insertions(+), 20 deletions(-) diff --git a/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleClient.h b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleClient.h index 1e2f3add17..5e4bf27d6b 100644 --- a/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleClient.h +++ b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleClient.h @@ -20,11 +20,7 @@ #include -namespace android { -namespace hardware { -namespace automotive { -namespace vehicle { -namespace V2_0 { +namespace android::hardware::automotive::vehicle::V2_0 { /** * Vehicle HAL talks to the vehicle through a client, instead of accessing @@ -66,8 +62,4 @@ class IVehicleClient { } }; -} // namespace V2_0 -} // namespace vehicle -} // namespace automotive -} // namespace hardware -} // namespace android +} // namespace android::hardware::automotive::vehicle::V2_0 diff --git a/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleServer.h b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleServer.h index 27ebbeef55..ba9799af1b 100644 --- a/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleServer.h +++ b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehicleServer.h @@ -20,11 +20,7 @@ #include -namespace android { -namespace hardware { -namespace automotive { -namespace vehicle { -namespace V2_0 { +namespace android::hardware::automotive::vehicle::V2_0 { /** * Server lives on the vehicle side to talk to Android HAL. @@ -69,8 +65,4 @@ class IVehicleServer { #endif // __ANDROID__ }; -} // namespace V2_0 -} // namespace vehicle -} // namespace automotive -} // namespace hardware -} // namespace android +} // namespace android::hardware::automotive::vehicle::V2_0 -- GitLab From 30bd3dce06e3f20f2bb20473099b8350f1d4cacc Mon Sep 17 00:00:00 2001 From: chrisweir Date: Tue, 25 Feb 2020 15:15:40 -0800 Subject: [PATCH 016/790] Add support for EFF/RTR to canhalsend Adding support for extended format frames and remote transmission request frames to canhalsend. Bug: 149404884 Test: Manual Change-Id: I330b9d24c34918b38612ddc1745f019e11bfd474 --- automotive/can/1.0/tools/canhalsend.cpp | 52 ++++++++++++++++++------- 1 file changed, 37 insertions(+), 15 deletions(-) diff --git a/automotive/can/1.0/tools/canhalsend.cpp b/automotive/can/1.0/tools/canhalsend.cpp index 7e6833a8a6..18e815dd6e 100644 --- a/automotive/can/1.0/tools/canhalsend.cpp +++ b/automotive/can/1.0/tools/canhalsend.cpp @@ -15,6 +15,8 @@ */ #include +#include +#include #include #include @@ -27,13 +29,13 @@ using ICanBus = V1_0::ICanBus; using Result = V1_0::Result; static void usage() { - std::cerr << "cansend - simple command line tool to send raw CAN frames" << std::endl; + std::cerr << "canhalsend - simple command line tool to send raw CAN frames" << std::endl; std::cerr << std::endl << "usage:" << std::endl << std::endl; std::cerr << "canhalsend #" << std::endl; std::cerr << "where:" << std::endl; - std::cerr << " bus name - name under which ICanBus is be published" << std::endl; - std::cerr << " can id - such as 1a5" << std::endl; - std::cerr << " data - such as deadbeef or 010203" << std::endl; + std::cerr << " bus name - name under which ICanBus is published" << std::endl; + std::cerr << " can id - such as 1a5 or 1fab5982" << std::endl; + std::cerr << " data - such as deadbeef, 010203, or R for a remote frame" << std::endl; } // TODO(b/135918744): extract to a new library @@ -53,18 +55,13 @@ static sp tryOpen(const std::string& busname) { return ICanBus::castFrom(ret); } -static int cansend(const std::string& busname, V1_0::CanMessageId msgid, - std::vector payload) { +static int cansend(const std::string& busname, const V1_0::CanMessage& msg) { auto bus = tryOpen(busname); if (bus == nullptr) { std::cerr << "Bus " << busname << " is not available" << std::endl; return -1; } - V1_0::CanMessage msg = {}; - msg.id = msgid; - msg.payload = payload; - const auto result = bus->send(msg); if (result != Result::OK) { std::cerr << "Send call failed: " << toString(result) << std::endl; @@ -73,8 +70,7 @@ static int cansend(const std::string& busname, V1_0::CanMessageId msgid, return 0; } -static std::optional>> parseCanMessage( - const std::string& msg) { +static std::optional parseCanMessage(const std::string& msg) { const auto hashpos = msg.find("#"); if (hashpos == std::string::npos) return std::nullopt; @@ -85,6 +81,32 @@ static std::optional>> parse V1_0::CanMessageId msgid = std::stoi(msgidStr, &idx, 16); if (msgidStr[idx] != '\0') return std::nullopt; + V1_0::CanMessage canmsg = {}; + canmsg.id = msgid; + if (msgid > 0x7FF) { + canmsg.isExtendedId = true; + } + + if (android::base::StartsWith(payloadStr, "R")) { + canmsg.remoteTransmissionRequest = true; + + /* The CAN bus HAL doesn't define a data length code (DLC) field, since it is inferrred + * from the payload size. RTR messages indicate to the receiver how many bytes they are + * expecting to receive back via the DLC sent with the RTR frame. */ + if (payloadStr.size() <= 1) return canmsg; + + unsigned int dlc = 0; + + /* The maximum DLC for CAN-FD is 64 bytes and CAN 2.0 is 8 bytes. Limit the size of the DLC + * to something memory safe and let the HAL determine if the DLC is valid. */ + if (!android::base::ParseUint(payloadStr.substr(1), &dlc, 10000u)) { + std::cerr << "Invalid DLC for RTR frame!" << std::endl; + return std::nullopt; + } + canmsg.payload.resize(dlc); + return canmsg; + } + std::vector payload; if (payloadStr.size() % 2 != 0) return std::nullopt; for (size_t i = 0; i < payloadStr.size(); i += 2) { @@ -92,8 +114,9 @@ static std::optional>> parse payload.emplace_back(std::stoi(byteStr, &idx, 16)); if (byteStr[idx] != '\0') return std::nullopt; } + canmsg.payload = payload; - return {{msgid, payload}}; + return canmsg; } static int main(int argc, char* argv[]) { @@ -117,9 +140,8 @@ static int main(int argc, char* argv[]) { std::cerr << "Failed to parse CAN message argument" << std::endl; return -1; } - const auto [msgid, payload] = *canmsg; - return cansend(busname, msgid, payload); + return cansend(busname, *canmsg); } } // namespace android::hardware::automotive::can -- GitLab From 8c2a986ee9ee1cab3ed5c8ba89615438aaf7b40e Mon Sep 17 00:00:00 2001 From: Jordan Liu Date: Fri, 21 Feb 2020 14:46:22 -0800 Subject: [PATCH 017/790] Add more info on control key param Bug: 149957303 Test: no change to behavior Change-Id: Id9d0e0e9cb2eb1eda83d7b5f1bd72be63216d976 --- current.txt | 2 +- radio/1.5/IRadio.hal | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/current.txt b/current.txt index 8e2016de2e..852a7bfea7 100644 --- a/current.txt +++ b/current.txt @@ -703,7 +703,7 @@ a64467bae843569f0d465c5be7f0c7a5b987985b55a3ef4794dd5afc68538650 android.hardwar 77531c8d048f8f8ae532babd0ca86332a865ec9aace1b051226ef2b21123e645 android.hardware.wifi.supplicant@1.3::ISupplicantStaNetwork 98592d193a717066facf91428426e5abe211e3bd718bc372e29fb944ddbe6e7c android.hardware.wifi.supplicant@1.3::types 99f5c26b952271d1246c957e1d0271fa39445ee65cc93aa7c187834f98914a33 android.hardware.radio@1.5::types -890ecacaaa6660802bac01bbbe5f16b1eb1d6a3a3f0e5b398be5cec76a5ab673 android.hardware.radio@1.5::IRadio +b454df853441c12f6e425e8a60dd29fda20f5e6e39b93d1103e4b37495db38aa android.hardware.radio@1.5::IRadio e96ae1c3a9c0689002ec2318e9c587f4f607c16a75a3cd38788b77eb91072021 android.hardware.radio@1.5::IRadioIndication 829d3827eeb5a8f563e80fe627419b3231012fc02bc2e79782ec5e9ad9f799a4 android.hardware.radio@1.5::IRadioResponse 3ca6616381080bdd6c08141ad12775a94ae868c58b02b1274ae3326f7de724ab android.hardware.sensors@2.1::ISensors diff --git a/radio/1.5/IRadio.hal b/radio/1.5/IRadio.hal index 87824e2ea8..956f9bd0a1 100644 --- a/radio/1.5/IRadio.hal +++ b/radio/1.5/IRadio.hal @@ -325,11 +325,15 @@ interface IRadio extends @1.4::IRadio { oneway sendCdmaSmsExpectMore(int32_t serial, CdmaSmsMessage sms); /** - * Requests that deactivates one category of the device personalization. + * Request that deactivates one category of device personalization. Device personalization + * generally binds the device so it can only be used on one carrier or even one carrier subnet + * (See TS 22.022). When the user has gained the rights to unbind the device (at the end of a + * contract period or other event), the controlKey will be delivered to either the user for + * manual entry or to a carrier app on the device for automatic entry. * * @param serial Serial number of request. * @param persoType SIM personalization type. - * @param controlKey depersonalization code corresponding to persoType + * @param controlKey the unlock code for removing persoType personalization from this device * * Response function is IRadioResponse.supplySimDepersonalizationResponse() */ -- GitLab From 1173a7253becba2b548057112372c8a94d9b6a41 Mon Sep 17 00:00:00 2001 From: chrisweir Date: Wed, 26 Feb 2020 14:39:56 -0800 Subject: [PATCH 018/790] Clean up errno logs and sto* conversions I learned that we should be using PLOG to log errno strings, and we should be avoiding stoi, stol, etc... conversions and instead use the built in Android ParseInt/ParseUint functions. Bug: 150250606 Bug: 150245058 Test: Manual for CLI tools, VTS for everything else Change-Id: Icdd8a6af8564d5de3bedd1bc934f7928eb5e66e9 --- automotive/can/1.0/default/CanBusSlcan.cpp | 20 +++++++++---------- automotive/can/1.0/default/CanSocket.cpp | 6 +++--- .../default/libnetdevice/NetlinkSocket.cpp | 8 ++++---- .../can/1.0/default/libnetdevice/can.cpp | 2 +- .../1.0/default/libnetdevice/libnetdevice.cpp | 2 +- automotive/can/1.0/tools/canhalctrl.cpp | 13 +++++++----- automotive/can/1.0/tools/canhalsend.cpp | 11 +++++----- 7 files changed, 32 insertions(+), 30 deletions(-) diff --git a/automotive/can/1.0/default/CanBusSlcan.cpp b/automotive/can/1.0/default/CanBusSlcan.cpp index 5005ecd642..f08566ca5f 100644 --- a/automotive/can/1.0/default/CanBusSlcan.cpp +++ b/automotive/can/1.0/default/CanBusSlcan.cpp @@ -56,7 +56,7 @@ ICanController::Result CanBusSlcan::updateIfaceName(base::unique_fd& uartFd) { * that has already been configured and brought up. */ if (ioctl(uartFd.get(), SIOCGIFNAME, ifrequest.ifr_name) < 0) { - LOG(ERROR) << "Failed to get the name of the created device: " << strerror(errno); + PLOG(ERROR) << "Failed to get the name of the created device"; return ICanController::Result::UNKNOWN_ERROR; } @@ -80,7 +80,7 @@ ICanController::Result CanBusSlcan::preUp() { * controlling terminal */ mFd = base::unique_fd(open(mUartName.c_str(), O_RDWR | O_NONBLOCK | O_NOCTTY)); if (!mFd.ok()) { - LOG(ERROR) << "SLCAN Failed to open " << mUartName << ": " << strerror(errno); + PLOG(ERROR) << "SLCAN Failed to open " << mUartName; return ICanController::Result::BAD_INTERFACE_ID; } @@ -92,7 +92,7 @@ ICanController::Result CanBusSlcan::preUp() { // blank terminal settings and pull them from the device struct termios terminalSettings = {}; if (tcgetattr(mFd.get(), &terminalSettings) < 0) { - LOG(ERROR) << "Failed to read attrs of" << mUartName << ": " << strerror(errno); + PLOG(ERROR) << "Failed to read attrs of" << mUartName; return ICanController::Result::UNKNOWN_ERROR; } @@ -107,42 +107,40 @@ ICanController::Result CanBusSlcan::preUp() { struct serial_struct serialSettings; // get serial settings if (ioctl(mFd.get(), TIOCGSERIAL, &serialSettings) < 0) { - LOG(ERROR) << "Failed to read serial settings from " << mUartName << ": " - << strerror(errno); + PLOG(ERROR) << "Failed to read serial settings from " << mUartName; return ICanController::Result::UNKNOWN_ERROR; } // set low latency mode serialSettings.flags |= ASYNC_LOW_LATENCY; // apply serial settings if (ioctl(mFd.get(), TIOCSSERIAL, &serialSettings) < 0) { - LOG(ERROR) << "Failed to set low latency mode on " << mUartName << ": " << strerror(errno); + PLOG(ERROR) << "Failed to set low latency mode on " << mUartName; return ICanController::Result::UNKNOWN_ERROR; } /* TCSADRAIN applies settings after we finish writing the rest of our * changes (as opposed to TCSANOW, which changes immediately) */ if (tcsetattr(mFd.get(), TCSADRAIN, &terminalSettings) < 0) { - LOG(ERROR) << "Failed to apply terminal settings to " << mUartName << ": " - << strerror(errno); + PLOG(ERROR) << "Failed to apply terminal settings to " << mUartName; return ICanController::Result::UNKNOWN_ERROR; } // apply speed setting for CAN if (write(mFd.get(), canBitrateCommand->c_str(), canBitrateCommand->length()) <= 0) { - LOG(ERROR) << "Failed to apply CAN bitrate: " << strerror(errno); + PLOG(ERROR) << "Failed to apply CAN bitrate"; return ICanController::Result::UNKNOWN_ERROR; } // TODO(b/144775286): set open flag & support listen only if (write(mFd.get(), slcanprotocol::kOpenCommand.c_str(), slcanprotocol::kOpenCommand.length()) <= 0) { - LOG(ERROR) << "Failed to set open flag: " << strerror(errno); + PLOG(ERROR) << "Failed to set open flag"; return ICanController::Result::UNKNOWN_ERROR; } // set line discipline to slcan if (ioctl(mFd.get(), TIOCSETD, &slcanprotocol::kSlcanDiscipline) < 0) { - LOG(ERROR) << "Failed to set line discipline to slcan: " << strerror(errno); + PLOG(ERROR) << "Failed to set line discipline to slcan"; return ICanController::Result::UNKNOWN_ERROR; } diff --git a/automotive/can/1.0/default/CanSocket.cpp b/automotive/can/1.0/default/CanSocket.cpp index 86ccc0e84e..f379d5a070 100644 --- a/automotive/can/1.0/default/CanSocket.cpp +++ b/automotive/can/1.0/default/CanSocket.cpp @@ -67,7 +67,7 @@ CanSocket::~CanSocket() { bool CanSocket::send(const struct canfd_frame& frame) { const auto res = write(mSocket.get(), &frame, CAN_MTU); if (res < 0) { - LOG(DEBUG) << "CanSocket send failed: " << errno; + PLOG(DEBUG) << "CanSocket send failed"; return false; } if (res != CAN_MTU) { @@ -102,7 +102,7 @@ void CanSocket::readerThread() { const auto sel = selectRead(mSocket, kReadPooling); if (sel == 0) continue; // timeout if (sel == -1) { - LOG(ERROR) << "Select failed: " << errno; + PLOG(ERROR) << "Select failed"; break; } @@ -130,7 +130,7 @@ void CanSocket::readerThread() { if (errno == EAGAIN) continue; errnoCopy = errno; - LOG(ERROR) << "Failed to read CAN packet: " << strerror(errno) << " (" << errno << ")"; + PLOG(ERROR) << "Failed to read CAN packet"; break; } diff --git a/automotive/can/1.0/default/libnetdevice/NetlinkSocket.cpp b/automotive/can/1.0/default/libnetdevice/NetlinkSocket.cpp index 6a7f50681d..7817169876 100644 --- a/automotive/can/1.0/default/libnetdevice/NetlinkSocket.cpp +++ b/automotive/can/1.0/default/libnetdevice/NetlinkSocket.cpp @@ -23,7 +23,7 @@ namespace android::netdevice { NetlinkSocket::NetlinkSocket(int protocol) { mFd.reset(socket(AF_NETLINK, SOCK_RAW, protocol)); if (!mFd.ok()) { - LOG(ERROR) << "Can't open Netlink socket: " << errno; + PLOG(ERROR) << "Can't open Netlink socket"; mFailed = true; return; } @@ -32,7 +32,7 @@ NetlinkSocket::NetlinkSocket(int protocol) { sa.nl_family = AF_NETLINK; if (bind(mFd.get(), reinterpret_cast(&sa), sizeof(sa)) < 0) { - LOG(ERROR) << "Can't bind Netlink socket: " << errno; + PLOG(ERROR) << "Can't bind Netlink socket"; mFd.reset(); mFailed = true; } @@ -57,7 +57,7 @@ bool NetlinkSocket::send(struct nlmsghdr* nlmsg) { msg.msg_iovlen = 1; if (sendmsg(mFd.get(), &msg, 0) < 0) { - LOG(ERROR) << "Can't send Netlink message: " << errno; + PLOG(ERROR) << "Can't send Netlink message"; return false; } return true; @@ -79,7 +79,7 @@ bool NetlinkSocket::receiveAck() { const ssize_t status = recvmsg(mFd.get(), &msg, 0); if (status < 0) { - LOG(ERROR) << "Failed to receive Netlink message: " << errno; + PLOG(ERROR) << "Failed to receive Netlink message"; return false; } size_t remainingLen = status; diff --git a/automotive/can/1.0/default/libnetdevice/can.cpp b/automotive/can/1.0/default/libnetdevice/can.cpp index 06d45d3b7d..a2a85dcae8 100644 --- a/automotive/can/1.0/default/libnetdevice/can.cpp +++ b/automotive/can/1.0/default/libnetdevice/can.cpp @@ -48,7 +48,7 @@ base::unique_fd socket(const std::string& ifname) { } if (setsockopt(sock.get(), SOL_CAN_RAW, CAN_RAW_ERR_FILTER, &kErrMask, sizeof(kErrMask)) < 0) { - LOG(ERROR) << "Can't receive error frames, CAN setsockpt failed: " << strerror(errno); + PLOG(ERROR) << "Can't receive error frames, CAN setsockpt failed"; return {}; } diff --git a/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp b/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp index aee820573f..b05144209e 100644 --- a/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp +++ b/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp @@ -41,7 +41,7 @@ static bool sendIfreq(unsigned long request, struct ifreq& ifr) { } if (ioctl(sock.get(), request, &ifr) < 0) { - LOG(ERROR) << "ioctl(" << std::hex << request << std::dec << ") failed: " << errno; + PLOG(ERROR) << "ioctl(" << std::hex << request << std::dec << ") failed"; return false; } diff --git a/automotive/can/1.0/tools/canhalctrl.cpp b/automotive/can/1.0/tools/canhalctrl.cpp index c186b74386..bf1c3b10a6 100644 --- a/automotive/can/1.0/tools/canhalctrl.cpp +++ b/automotive/can/1.0/tools/canhalctrl.cpp @@ -15,6 +15,7 @@ */ #include +#include #include #include #include @@ -72,8 +73,8 @@ static int up(const std::string& busName, ICanController::InterfaceType type, slcan.ttyname(interface); config.interfaceId.slcan(slcan); } else if (type == ICanController::InterfaceType::INDEXED) { - auto idx = std::stol(interface); - if (idx < 0 || idx > UINT8_MAX) { + unsigned idx; + if (!android::base::ParseUint(interface, &idx, unsigned(UINT8_MAX))) { std::cerr << "Interface index out of range: " << idx; return -1; } @@ -146,9 +147,11 @@ static int main(int argc, char* argv[]) { return -1; } - long long bitrate = 0; - if (argc == 4) { - bitrate = std::stoll(argv[3]); + uint32_t bitrate = 0; + if (argc == 4 && !android::base::ParseUint(argv[3], &bitrate)) { + std::cerr << "Invalid bitrate!" << std::endl; + usage(); + return -1; } return up(busName, *type, interface, bitrate); diff --git a/automotive/can/1.0/tools/canhalsend.cpp b/automotive/can/1.0/tools/canhalsend.cpp index 18e815dd6e..f0f9d10875 100644 --- a/automotive/can/1.0/tools/canhalsend.cpp +++ b/automotive/can/1.0/tools/canhalsend.cpp @@ -77,9 +77,9 @@ static std::optional parseCanMessage(const std::string& msg) { const std::string msgidStr = msg.substr(0, hashpos); const std::string payloadStr = msg.substr(hashpos + 1); - size_t idx = 0; - V1_0::CanMessageId msgid = std::stoi(msgidStr, &idx, 16); - if (msgidStr[idx] != '\0') return std::nullopt; + V1_0::CanMessageId msgid; + // "0x" must be prepended to msgidStr, since ParseUint doesn't accept a base argument. + if (!android::base::ParseUint("0x" + msgidStr, &msgid)) return std::nullopt; V1_0::CanMessage canmsg = {}; canmsg.id = msgid; @@ -111,8 +111,9 @@ static std::optional parseCanMessage(const std::string& msg) { if (payloadStr.size() % 2 != 0) return std::nullopt; for (size_t i = 0; i < payloadStr.size(); i += 2) { std::string byteStr(payloadStr, i, 2); - payload.emplace_back(std::stoi(byteStr, &idx, 16)); - if (byteStr[idx] != '\0') return std::nullopt; + uint8_t byteBuf; + if (!android::base::ParseUint("0x" + byteStr, &byteBuf)) return std::nullopt; + payload.emplace_back(byteBuf); } canmsg.payload = payload; -- GitLab From 9070318462e5e73acf1509cf7e75ac260e51e43a Mon Sep 17 00:00:00 2001 From: Jooyung Han Date: Fri, 21 Feb 2020 21:17:06 +0900 Subject: [PATCH 019/790] use vector for byte[] in AIDL In native world, byte stream is typically represented in uint8_t[] or vector. C++ backend already generates that way. This change involves NDK backend. Now NDK backend also uses vector just like C++ backend. Bug: 144957764 Test: atest CtsNdkBinderTestCases Change-Id: I8de348b57cf92dd99b3ee16252f56300ce5f4683 --- identity/aidl/default/IdentityCredential.cpp | 50 ++++++++----------- identity/aidl/default/IdentityCredential.h | 22 ++++---- .../aidl/default/IdentityCredentialStore.cpp | 6 +-- .../aidl/default/IdentityCredentialStore.h | 2 +- identity/aidl/default/Util.cpp | 13 +---- identity/aidl/default/Util.h | 4 -- .../default/WritableIdentityCredential.cpp | 26 +++++----- .../aidl/default/WritableIdentityCredential.h | 12 ++--- rebootescrow/aidl/default/RebootEscrow.cpp | 8 ++- .../include/rebootescrow-impl/RebootEscrow.h | 4 +- 10 files changed, 62 insertions(+), 85 deletions(-) diff --git a/identity/aidl/default/IdentityCredential.cpp b/identity/aidl/default/IdentityCredential.cpp index 341fae6e93..aaae1f6ae5 100644 --- a/identity/aidl/default/IdentityCredential.cpp +++ b/identity/aidl/default/IdentityCredential.cpp @@ -102,7 +102,7 @@ int IdentityCredential::initialize() { } ndk::ScopedAStatus IdentityCredential::deleteCredential( - vector* outProofOfDeletionSignature) { + vector* outProofOfDeletionSignature) { cppbor::Array array = {"ProofOfDeletion", docType_, testCredential_}; vector proofOfDeletion = array.encode(); @@ -115,11 +115,11 @@ ndk::ScopedAStatus IdentityCredential::deleteCredential( IIdentityCredentialStore::STATUS_FAILED, "Error signing data")); } - *outProofOfDeletionSignature = byteStringToSigned(signature.value()); + *outProofOfDeletionSignature = signature.value(); return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus IdentityCredential::createEphemeralKeyPair(vector* outKeyPair) { +ndk::ScopedAStatus IdentityCredential::createEphemeralKeyPair(vector* outKeyPair) { optional> kp = support::createEcKeyPair(); if (!kp) { return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( @@ -135,13 +135,13 @@ ndk::ScopedAStatus IdentityCredential::createEphemeralKeyPair(vector* ou } ephemeralPublicKey_ = publicKey.value(); - *outKeyPair = byteStringToSigned(kp.value()); + *outKeyPair = kp.value(); return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus IdentityCredential::setReaderEphemeralPublicKey( - const vector& publicKey) { - readerPublicKey_ = byteStringToUnsigned(publicKey); + const vector& publicKey) { + readerPublicKey_ = publicKey; return ndk::ScopedAStatus::ok(); } @@ -169,8 +169,8 @@ ndk::ScopedAStatus IdentityCredential::createAuthChallenge(int64_t* outChallenge // ahead of time. bool checkReaderAuthentication(const SecureAccessControlProfile& profile, const vector& readerCertificateChain) { - optional> acpPubKey = support::certificateChainGetTopMostKey( - byteStringToUnsigned(profile.readerCertificate.encodedCertificate)); + optional> acpPubKey = + support::certificateChainGetTopMostKey(profile.readerCertificate.encodedCertificate); if (!acpPubKey) { LOG(ERROR) << "Error extracting public key from readerCertificate in profile"; return false; @@ -255,13 +255,9 @@ bool checkUserAuthentication(const SecureAccessControlProfile& profile, ndk::ScopedAStatus IdentityCredential::startRetrieval( const vector& accessControlProfiles, - const HardwareAuthToken& authToken, const vector& itemsRequestS, - const vector& signingKeyBlobS, const vector& sessionTranscriptS, - const vector& readerSignatureS, const vector& requestCounts) { - auto sessionTranscript = byteStringToUnsigned(sessionTranscriptS); - auto itemsRequest = byteStringToUnsigned(itemsRequestS); - auto readerSignature = byteStringToUnsigned(readerSignatureS); - + const HardwareAuthToken& authToken, const vector& itemsRequest, + const vector& signingKeyBlob, const vector& sessionTranscript, + const vector& readerSignature, const vector& requestCounts) { if (sessionTranscript.size() > 0) { auto [item, _, message] = cppbor::parse(sessionTranscript); if (item == nullptr) { @@ -498,7 +494,7 @@ ndk::ScopedAStatus IdentityCredential::startRetrieval( currentNameSpace_ = ""; itemsRequest_ = itemsRequest; - signingKeyBlob_ = byteStringToUnsigned(signingKeyBlobS); + signingKeyBlob_ = signingKeyBlob; numStartRetrievalCalls_ += 1; return ndk::ScopedAStatus::ok(); @@ -605,10 +601,8 @@ ndk::ScopedAStatus IdentityCredential::startRetrieveEntryValue( return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus IdentityCredential::retrieveEntryValue(const vector& encryptedContentS, - vector* outContent) { - auto encryptedContent = byteStringToUnsigned(encryptedContentS); - +ndk::ScopedAStatus IdentityCredential::retrieveEntryValue(const vector& encryptedContent, + vector* outContent) { optional> content = support::decryptAes128Gcm(storageKey_, encryptedContent, entryAdditionalData_); if (!content) { @@ -647,12 +641,12 @@ ndk::ScopedAStatus IdentityCredential::retrieveEntryValue(const vector& currentNameSpaceDeviceNameSpacesMap_.add(currentName_, std::move(entryValueItem)); } - *outContent = byteStringToSigned(content.value()); + *outContent = content.value(); return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus IdentityCredential::finishRetrieval(vector* outMac, - vector* outDeviceNameSpaces) { +ndk::ScopedAStatus IdentityCredential::finishRetrieval(vector* outMac, + vector* outDeviceNameSpaces) { if (currentNameSpaceDeviceNameSpacesMap_.size() > 0) { deviceNameSpacesMap_.add(currentNameSpace_, std::move(currentNameSpaceDeviceNameSpacesMap_)); @@ -704,13 +698,13 @@ ndk::ScopedAStatus IdentityCredential::finishRetrieval(vector* outMac, } } - *outMac = byteStringToSigned(mac.value_or(vector({}))); - *outDeviceNameSpaces = byteStringToSigned(encodedDeviceNameSpaces); + *outMac = mac.value_or(vector({})); + *outDeviceNameSpaces = encodedDeviceNameSpaces; return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus IdentityCredential::generateSigningKeyPair( - vector* outSigningKeyBlob, Certificate* outSigningKeyCertificate) { + vector* outSigningKeyBlob, Certificate* outSigningKeyCertificate) { string serialDecimal = "0"; // TODO: set serial to something unique string issuer = "Android Open Source Project"; string subject = "Android IdentityCredential Reference Implementation"; @@ -758,9 +752,9 @@ ndk::ScopedAStatus IdentityCredential::generateSigningKeyPair( return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( IIdentityCredentialStore::STATUS_FAILED, "Error encrypting signingKey")); } - *outSigningKeyBlob = byteStringToSigned(encryptedSigningKey.value()); + *outSigningKeyBlob = encryptedSigningKey.value(); *outSigningKeyCertificate = Certificate(); - outSigningKeyCertificate->encodedCertificate = byteStringToSigned(certificate.value()); + outSigningKeyCertificate->encodedCertificate = certificate.value(); return ndk::ScopedAStatus::ok(); } diff --git a/identity/aidl/default/IdentityCredential.h b/identity/aidl/default/IdentityCredential.h index fc29254f4b..6072afe04f 100644 --- a/identity/aidl/default/IdentityCredential.h +++ b/identity/aidl/default/IdentityCredential.h @@ -47,23 +47,23 @@ class IdentityCredential : public BnIdentityCredential { int initialize(); // Methods from IIdentityCredential follow. - ndk::ScopedAStatus deleteCredential(vector* outProofOfDeletionSignature) override; - ndk::ScopedAStatus createEphemeralKeyPair(vector* outKeyPair) override; - ndk::ScopedAStatus setReaderEphemeralPublicKey(const vector& publicKey) override; + ndk::ScopedAStatus deleteCredential(vector* outProofOfDeletionSignature) override; + ndk::ScopedAStatus createEphemeralKeyPair(vector* outKeyPair) override; + ndk::ScopedAStatus setReaderEphemeralPublicKey(const vector& publicKey) override; ndk::ScopedAStatus createAuthChallenge(int64_t* outChallenge) override; ndk::ScopedAStatus startRetrieval( const vector& accessControlProfiles, - const HardwareAuthToken& authToken, const vector& itemsRequest, - const vector& signingKeyBlob, const vector& sessionTranscript, - const vector& readerSignature, const vector& requestCounts) override; + const HardwareAuthToken& authToken, const vector& itemsRequest, + const vector& signingKeyBlob, const vector& sessionTranscript, + const vector& readerSignature, const vector& requestCounts) override; ndk::ScopedAStatus startRetrieveEntryValue( const string& nameSpace, const string& name, int32_t entrySize, const vector& accessControlProfileIds) override; - ndk::ScopedAStatus retrieveEntryValue(const vector& encryptedContent, - vector* outContent) override; - ndk::ScopedAStatus finishRetrieval(vector* outMac, - vector* outDeviceNameSpaces) override; - ndk::ScopedAStatus generateSigningKeyPair(vector* outSigningKeyBlob, + ndk::ScopedAStatus retrieveEntryValue(const vector& encryptedContent, + vector* outContent) override; + ndk::ScopedAStatus finishRetrieval(vector* outMac, + vector* outDeviceNameSpaces) override; + ndk::ScopedAStatus generateSigningKeyPair(vector* outSigningKeyBlob, Certificate* outSigningKeyCertificate) override; private: diff --git a/identity/aidl/default/IdentityCredentialStore.cpp b/identity/aidl/default/IdentityCredentialStore.cpp index 1efb4b4937..30dc6f330b 100644 --- a/identity/aidl/default/IdentityCredentialStore.cpp +++ b/identity/aidl/default/IdentityCredentialStore.cpp @@ -51,7 +51,7 @@ ndk::ScopedAStatus IdentityCredentialStore::createCredential( } ndk::ScopedAStatus IdentityCredentialStore::getCredential( - CipherSuite cipherSuite, const vector& credentialData, + CipherSuite cipherSuite, const vector& credentialData, shared_ptr* outCredential) { // 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) { @@ -60,8 +60,8 @@ ndk::ScopedAStatus IdentityCredentialStore::getCredential( "Unsupported cipher suite")); } - vector data = vector(credentialData.begin(), credentialData.end()); - shared_ptr credential = ndk::SharedRefBase::make(data); + shared_ptr credential = + ndk::SharedRefBase::make(credentialData); auto ret = credential->initialize(); if (ret != IIdentityCredentialStore::STATUS_OK) { return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( diff --git a/identity/aidl/default/IdentityCredentialStore.h b/identity/aidl/default/IdentityCredentialStore.h index a2051130b0..4f3a42139f 100644 --- a/identity/aidl/default/IdentityCredentialStore.h +++ b/identity/aidl/default/IdentityCredentialStore.h @@ -39,7 +39,7 @@ class IdentityCredentialStore : public BnIdentityCredentialStore { const string& docType, bool testCredential, shared_ptr* outWritableCredential) override; - ndk::ScopedAStatus getCredential(CipherSuite cipherSuite, const vector& credentialData, + ndk::ScopedAStatus getCredential(CipherSuite cipherSuite, const vector& credentialData, shared_ptr* outCredential) override; }; diff --git a/identity/aidl/default/Util.cpp b/identity/aidl/default/Util.cpp index a0f86bedcd..66b9f13d89 100644 --- a/identity/aidl/default/Util.cpp +++ b/identity/aidl/default/Util.cpp @@ -39,21 +39,12 @@ const vector& getHardwareBoundKey() { return hardwareBoundKey; } -vector byteStringToUnsigned(const vector& value) { - return vector(value.begin(), value.end()); -} - -vector byteStringToSigned(const vector& value) { - return vector(value.begin(), value.end()); -} - vector secureAccessControlProfileEncodeCbor(const SecureAccessControlProfile& profile) { cppbor::Map map; map.add("id", profile.id); if (profile.readerCertificate.encodedCertificate.size() > 0) { - map.add("readerCertificate", - cppbor::Bstr(byteStringToUnsigned(profile.readerCertificate.encodedCertificate))); + map.add("readerCertificate", cppbor::Bstr(profile.readerCertificate.encodedCertificate)); } if (profile.userAuthenticationRequired) { @@ -94,7 +85,7 @@ bool secureAccessControlProfileCheckMac(const SecureAccessControlProfile& profil if (!mac) { return false; } - if (mac.value() != byteStringToUnsigned(profile.mac)) { + if (mac.value() != profile.mac) { return false; } return true; diff --git a/identity/aidl/default/Util.h b/identity/aidl/default/Util.h index ee41ad1aac..9fccba2c72 100644 --- a/identity/aidl/default/Util.h +++ b/identity/aidl/default/Util.h @@ -49,10 +49,6 @@ bool secureAccessControlProfileCheckMac(const SecureAccessControlProfile& profil vector entryCreateAdditionalData(const string& nameSpace, const string& name, const vector accessControlProfileIds); -vector byteStringToUnsigned(const vector& value); - -vector byteStringToSigned(const vector& value); - } // namespace aidl::android::hardware::identity #endif // ANDROID_HARDWARE_IDENTITY_UTIL_H diff --git a/identity/aidl/default/WritableIdentityCredential.cpp b/identity/aidl/default/WritableIdentityCredential.cpp index 89f7f35696..bce913aeec 100644 --- a/identity/aidl/default/WritableIdentityCredential.cpp +++ b/identity/aidl/default/WritableIdentityCredential.cpp @@ -53,8 +53,8 @@ bool WritableIdentityCredential::initialize() { // attestation certificate with current time and expires one year from now. The // certificate shall contain all values as specified in hal. ndk::ScopedAStatus WritableIdentityCredential::getAttestationCertificate( - const vector& attestationApplicationId, // - const vector& attestationChallenge, // + const vector& attestationApplicationId, // + const vector& attestationChallenge, // vector* outCertificateChain) { if (!credentialPrivKey_.empty() || !credentialPubKey_.empty() || !certificateChain_.empty()) { return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( @@ -97,7 +97,7 @@ ndk::ScopedAStatus WritableIdentityCredential::getAttestationCertificate( *outCertificateChain = vector(); for (const vector& cert : certificateChain_) { Certificate c = Certificate(); - c.encodedCertificate = byteStringToSigned(cert); + c.encodedCertificate = cert; outCertificateChain->push_back(std::move(c)); } return ndk::ScopedAStatus::ok(); @@ -146,14 +146,13 @@ ndk::ScopedAStatus WritableIdentityCredential::addAccessControlProfile( return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( IIdentityCredentialStore::STATUS_FAILED, "Error calculating MAC for profile")); } - profile.mac = byteStringToSigned(mac.value()); + profile.mac = mac.value(); cppbor::Map profileMap; profileMap.add("id", profile.id); if (profile.readerCertificate.encodedCertificate.size() > 0) { - profileMap.add( - "readerCertificate", - cppbor::Bstr(byteStringToUnsigned(profile.readerCertificate.encodedCertificate))); + profileMap.add("readerCertificate", + cppbor::Bstr(profile.readerCertificate.encodedCertificate)); } if (profile.userAuthenticationRequired) { profileMap.add("userAuthenticationRequired", profile.userAuthenticationRequired); @@ -223,9 +222,8 @@ ndk::ScopedAStatus WritableIdentityCredential::beginAddEntry( return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus WritableIdentityCredential::addEntryValue(const vector& contentS, - vector* outEncryptedContent) { - auto content = byteStringToUnsigned(contentS); +ndk::ScopedAStatus WritableIdentityCredential::addEntryValue(const vector& content, + vector* outEncryptedContent) { size_t contentSize = content.size(); if (contentSize > IdentityCredentialStore::kGcmChunkSize) { @@ -280,7 +278,7 @@ ndk::ScopedAStatus WritableIdentityCredential::addEntryValue(const vector& hardwareBoundKey, const strin } ndk::ScopedAStatus WritableIdentityCredential::finishAddingEntries( - vector* outCredentialData, vector* outProofOfProvisioningSignature) { + vector* outCredentialData, vector* outProofOfProvisioningSignature) { if (signedDataCurrentNamespace_.size() > 0) { signedDataNamespaces_.add(entryNameSpace_, std::move(signedDataCurrentNamespace_)); } @@ -364,8 +362,8 @@ ndk::ScopedAStatus WritableIdentityCredential::finishAddingEntries( IIdentityCredentialStore::STATUS_FAILED, "Error generating CredentialData")); } - *outCredentialData = byteStringToSigned(credentialData); - *outProofOfProvisioningSignature = byteStringToSigned(signature.value()); + *outCredentialData = credentialData; + *outProofOfProvisioningSignature = signature.value(); return ndk::ScopedAStatus::ok(); } diff --git a/identity/aidl/default/WritableIdentityCredential.h b/identity/aidl/default/WritableIdentityCredential.h index b182862862..4b6fca8d91 100644 --- a/identity/aidl/default/WritableIdentityCredential.h +++ b/identity/aidl/default/WritableIdentityCredential.h @@ -37,8 +37,8 @@ class WritableIdentityCredential : public BnWritableIdentityCredential { bool initialize(); // Methods from IWritableIdentityCredential follow. - ndk::ScopedAStatus getAttestationCertificate(const vector& attestationApplicationId, - const vector& attestationChallenge, + ndk::ScopedAStatus getAttestationCertificate(const vector& attestationApplicationId, + const vector& attestationChallenge, vector* outCertificateChain) override; ndk::ScopedAStatus startPersonalization(int32_t accessControlProfileCount, @@ -53,12 +53,12 @@ class WritableIdentityCredential : public BnWritableIdentityCredential { const string& nameSpace, const string& name, int32_t entrySize) override; - ndk::ScopedAStatus addEntryValue(const vector& content, - vector* outEncryptedContent) override; + ndk::ScopedAStatus addEntryValue(const vector& content, + vector* outEncryptedContent) override; ndk::ScopedAStatus finishAddingEntries( - vector* outCredentialData, - vector* outProofOfProvisioningSignature) override; + vector* outCredentialData, + vector* outProofOfProvisioningSignature) override; // private: string docType_; diff --git a/rebootescrow/aidl/default/RebootEscrow.cpp b/rebootescrow/aidl/default/RebootEscrow.cpp index dbc09215b3..8e5e97c80c 100644 --- a/rebootescrow/aidl/default/RebootEscrow.cpp +++ b/rebootescrow/aidl/default/RebootEscrow.cpp @@ -28,7 +28,7 @@ namespace rebootescrow { using ::android::base::unique_fd; -ndk::ScopedAStatus RebootEscrow::storeKey(const std::vector& kek) { +ndk::ScopedAStatus RebootEscrow::storeKey(const std::vector& ukek) { int rawFd = TEMP_FAILURE_RETRY(::open(devicePath_.c_str(), O_WRONLY | O_NOFOLLOW | O_CLOEXEC)); unique_fd fd(rawFd); if (fd.get() < 0) { @@ -36,7 +36,6 @@ ndk::ScopedAStatus RebootEscrow::storeKey(const std::vector& kek) { return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION)); } - std::vector ukek(kek.begin(), kek.end()); auto encoded = hadamard::EncodeKey(ukek); if (!::android::base::WriteFully(fd, encoded.data(), encoded.size())) { @@ -47,7 +46,7 @@ ndk::ScopedAStatus RebootEscrow::storeKey(const std::vector& kek) { return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus RebootEscrow::retrieveKey(std::vector* _aidl_return) { +ndk::ScopedAStatus RebootEscrow::retrieveKey(std::vector* _aidl_return) { int rawFd = TEMP_FAILURE_RETRY(::open(devicePath_.c_str(), O_RDONLY | O_NOFOLLOW | O_CLOEXEC)); unique_fd fd(rawFd); if (fd.get() < 0) { @@ -63,8 +62,7 @@ ndk::ScopedAStatus RebootEscrow::retrieveKey(std::vector* _aidl_return) auto keyBytes = hadamard::DecodeKey(encodedBytes); - std::vector signedKeyBytes(keyBytes.begin(), keyBytes.end()); - *_aidl_return = signedKeyBytes; + *_aidl_return = keyBytes; return ndk::ScopedAStatus::ok(); } diff --git a/rebootescrow/aidl/default/include/rebootescrow-impl/RebootEscrow.h b/rebootescrow/aidl/default/include/rebootescrow-impl/RebootEscrow.h index 00ff16b2ea..cdbeb67eba 100644 --- a/rebootescrow/aidl/default/include/rebootescrow-impl/RebootEscrow.h +++ b/rebootescrow/aidl/default/include/rebootescrow-impl/RebootEscrow.h @@ -26,8 +26,8 @@ namespace rebootescrow { class RebootEscrow : public BnRebootEscrow { public: explicit RebootEscrow(const std::string& devicePath) : devicePath_(devicePath) {} - ndk::ScopedAStatus storeKey(const std::vector& kek) override; - ndk::ScopedAStatus retrieveKey(std::vector* _aidl_return) override; + ndk::ScopedAStatus storeKey(const std::vector& kek) override; + ndk::ScopedAStatus retrieveKey(std::vector* _aidl_return) override; private: const std::string devicePath_; -- GitLab From 88417a586b889eec772e3acab5dffaba18a0e678 Mon Sep 17 00:00:00 2001 From: Marissa Wall Date: Fri, 28 Feb 2020 10:07:28 -0800 Subject: [PATCH 020/790] graphics: update OWNERS marissaw@ is leaving. jessehall@ is on a different team. Remove them and add new owners. Test: Compiles Bug: 150462113 Change-Id: I922710de701d3923268591bcb48db3e12acb0500 --- graphics/allocator/2.0/default/OWNERS | 4 ++-- graphics/allocator/2.0/utils/OWNERS | 4 ++-- graphics/mapper/2.0/default/OWNERS | 4 ++-- graphics/mapper/2.0/utils/OWNERS | 4 ++-- graphics/mapper/2.0/vts/OWNERS | 4 +++- graphics/mapper/2.1/default/OWNERS | 4 ++-- graphics/mapper/2.1/utils/OWNERS | 4 ++-- graphics/mapper/2.1/vts/OWNERS | 4 +++- graphics/mapper/3.0/utils/OWNERS | 3 ++- graphics/mapper/3.0/vts/OWNERS | 3 ++- graphics/mapper/4.0/utils/OWNERS | 3 ++- graphics/mapper/4.0/vts/OWNERS | 3 ++- 12 files changed, 26 insertions(+), 18 deletions(-) diff --git a/graphics/allocator/2.0/default/OWNERS b/graphics/allocator/2.0/default/OWNERS index 273cb4c4b9..2a56b381a4 100644 --- a/graphics/allocator/2.0/default/OWNERS +++ b/graphics/allocator/2.0/default/OWNERS @@ -1,4 +1,4 @@ # Graphics team -jessehall@google.com -marissaw@google.com +chrisforbes@google.com stoza@google.com +vhau@google.com diff --git a/graphics/allocator/2.0/utils/OWNERS b/graphics/allocator/2.0/utils/OWNERS index 273cb4c4b9..2a56b381a4 100644 --- a/graphics/allocator/2.0/utils/OWNERS +++ b/graphics/allocator/2.0/utils/OWNERS @@ -1,4 +1,4 @@ # Graphics team -jessehall@google.com -marissaw@google.com +chrisforbes@google.com stoza@google.com +vhau@google.com diff --git a/graphics/mapper/2.0/default/OWNERS b/graphics/mapper/2.0/default/OWNERS index 273cb4c4b9..2a56b381a4 100644 --- a/graphics/mapper/2.0/default/OWNERS +++ b/graphics/mapper/2.0/default/OWNERS @@ -1,4 +1,4 @@ # Graphics team -jessehall@google.com -marissaw@google.com +chrisforbes@google.com stoza@google.com +vhau@google.com diff --git a/graphics/mapper/2.0/utils/OWNERS b/graphics/mapper/2.0/utils/OWNERS index 273cb4c4b9..2a56b381a4 100644 --- a/graphics/mapper/2.0/utils/OWNERS +++ b/graphics/mapper/2.0/utils/OWNERS @@ -1,4 +1,4 @@ # Graphics team -jessehall@google.com -marissaw@google.com +chrisforbes@google.com stoza@google.com +vhau@google.com diff --git a/graphics/mapper/2.0/vts/OWNERS b/graphics/mapper/2.0/vts/OWNERS index 8e86f64c9d..11b7d216ce 100644 --- a/graphics/mapper/2.0/vts/OWNERS +++ b/graphics/mapper/2.0/vts/OWNERS @@ -1,5 +1,7 @@ # Graphics team -marissaw@google.com +chrisforbes@google.com +stoza@google.com +vhau@google.com # VTS team yim@google.com diff --git a/graphics/mapper/2.1/default/OWNERS b/graphics/mapper/2.1/default/OWNERS index 273cb4c4b9..2a56b381a4 100644 --- a/graphics/mapper/2.1/default/OWNERS +++ b/graphics/mapper/2.1/default/OWNERS @@ -1,4 +1,4 @@ # Graphics team -jessehall@google.com -marissaw@google.com +chrisforbes@google.com stoza@google.com +vhau@google.com diff --git a/graphics/mapper/2.1/utils/OWNERS b/graphics/mapper/2.1/utils/OWNERS index 273cb4c4b9..2a56b381a4 100644 --- a/graphics/mapper/2.1/utils/OWNERS +++ b/graphics/mapper/2.1/utils/OWNERS @@ -1,4 +1,4 @@ # Graphics team -jessehall@google.com -marissaw@google.com +chrisforbes@google.com stoza@google.com +vhau@google.com diff --git a/graphics/mapper/2.1/vts/OWNERS b/graphics/mapper/2.1/vts/OWNERS index 8e86f64c9d..11b7d216ce 100644 --- a/graphics/mapper/2.1/vts/OWNERS +++ b/graphics/mapper/2.1/vts/OWNERS @@ -1,5 +1,7 @@ # Graphics team -marissaw@google.com +chrisforbes@google.com +stoza@google.com +vhau@google.com # VTS team yim@google.com diff --git a/graphics/mapper/3.0/utils/OWNERS b/graphics/mapper/3.0/utils/OWNERS index 96f6d51573..2a56b381a4 100644 --- a/graphics/mapper/3.0/utils/OWNERS +++ b/graphics/mapper/3.0/utils/OWNERS @@ -1,3 +1,4 @@ # Graphics team -marissaw@google.com +chrisforbes@google.com stoza@google.com +vhau@google.com diff --git a/graphics/mapper/3.0/vts/OWNERS b/graphics/mapper/3.0/vts/OWNERS index 96f6d51573..2a56b381a4 100644 --- a/graphics/mapper/3.0/vts/OWNERS +++ b/graphics/mapper/3.0/vts/OWNERS @@ -1,3 +1,4 @@ # Graphics team -marissaw@google.com +chrisforbes@google.com stoza@google.com +vhau@google.com diff --git a/graphics/mapper/4.0/utils/OWNERS b/graphics/mapper/4.0/utils/OWNERS index 96f6d51573..2a56b381a4 100644 --- a/graphics/mapper/4.0/utils/OWNERS +++ b/graphics/mapper/4.0/utils/OWNERS @@ -1,3 +1,4 @@ # Graphics team -marissaw@google.com +chrisforbes@google.com stoza@google.com +vhau@google.com diff --git a/graphics/mapper/4.0/vts/OWNERS b/graphics/mapper/4.0/vts/OWNERS index 96f6d51573..2a56b381a4 100644 --- a/graphics/mapper/4.0/vts/OWNERS +++ b/graphics/mapper/4.0/vts/OWNERS @@ -1,3 +1,4 @@ # Graphics team -marissaw@google.com +chrisforbes@google.com stoza@google.com +vhau@google.com -- GitLab From d7c88e3e551f4fd434e0d055428e2f31df1502a3 Mon Sep 17 00:00:00 2001 From: Dan Shi Date: Mon, 2 Mar 2020 13:40:17 -0800 Subject: [PATCH 021/790] Push prebuilt libvtswidevine to device for drm HAL test Bug: 143220441 Test: atest VtsHalDrmV1_3TargetTest Change-Id: I08af2bf9524b0bbb362c28eceef5e6642545ecc7 --- drm/1.3/vts/functional/AndroidTest.xml | 33 ++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 drm/1.3/vts/functional/AndroidTest.xml diff --git a/drm/1.3/vts/functional/AndroidTest.xml b/drm/1.3/vts/functional/AndroidTest.xml new file mode 100644 index 0000000000..338430f010 --- /dev/null +++ b/drm/1.3/vts/functional/AndroidTest.xml @@ -0,0 +1,33 @@ + + + + -- GitLab From f58ff069ee8866fa7b3e931fcbd80cb1bb4f835c Mon Sep 17 00:00:00 2001 From: Daniel Norman Date: Fri, 28 Feb 2020 15:43:32 -0800 Subject: [PATCH 022/790] Adds IWifi 1.3 and 1.4 as interfaces provided by vendor.wifi_hal_legacy. Bug: 150474819 Test: vts_ibase_test Change-Id: Ie5462d41177ec6dd56e6de266157e7d4ac28b388 --- wifi/1.4/default/android.hardware.wifi@1.0-service.rc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/wifi/1.4/default/android.hardware.wifi@1.0-service.rc b/wifi/1.4/default/android.hardware.wifi@1.0-service.rc index 2317bac546..64a51b0ae8 100644 --- a/wifi/1.4/default/android.hardware.wifi@1.0-service.rc +++ b/wifi/1.4/default/android.hardware.wifi@1.0-service.rc @@ -2,6 +2,8 @@ service vendor.wifi_hal_legacy /vendor/bin/hw/android.hardware.wifi@1.0-service interface android.hardware.wifi@1.0::IWifi default interface android.hardware.wifi@1.1::IWifi default interface android.hardware.wifi@1.2::IWifi default + interface android.hardware.wifi@1.3::IWifi default + interface android.hardware.wifi@1.4::IWifi default class hal capabilities NET_ADMIN NET_RAW SYS_MODULE user wifi -- GitLab From 1507f74397f6b9d217423f5d50f8c892f3629950 Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Fri, 28 Feb 2020 12:22:46 -0800 Subject: [PATCH 023/790] Shuffled some TODOs around... Bug: 146207078 Bug: 150409377 Bug: 150413515 Test: not really Exempt-From-Owner-Approval: only changed bug numbers on TODO omments Change-Id: If71f62ed0ca5e2a088e4663cacdf8c9504c5df5d --- .../vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.cpp | 2 +- .../vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.cpp index a91ca8e770..3f6ea5e1f7 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.cpp +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.cpp @@ -320,7 +320,7 @@ StatusCode VehicleHalServer::onSetInitialUserInfo(const VehiclePropValue& value, // mInitialUserResponseFromCmd is used for just one request std::unique_ptr response = std::move(mInitialUserResponseFromCmd); - // TODO(b/138709788): rather than populate the raw values directly, it should use the + // TODO(b/150409377): rather than populate the raw values directly, it should use the // libraries that convert a InitialUserInfoResponse into a VehiclePropValue) switch (response->areaId) { diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.h index b1ae106331..4d7dbea493 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.h +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.h @@ -58,7 +58,7 @@ class VehicleHalServer : public IVehicleServer { // data members protected: - // TODO(b/146207078): it might be clearer to move members below to an EmulatedUserHal class + // TODO(b/150413515): it might be clearer to move members below to an EmulatedUserHal class std::unique_ptr mInitialUserResponseFromCmd; private: -- GitLab From 3d652709ed40f8070c990bb275d3709d603d318e Mon Sep 17 00:00:00 2001 From: Yu-Han Yang Date: Thu, 5 Mar 2020 22:41:23 -0800 Subject: [PATCH 024/790] Fix deadlock in cuttlefish/default implementation Bug: 150830099 Test: atest LocationManagerFineTest#testRegisterGnssMeasurementsCallback -c --iterations 100 Change-Id: I70aec19a481781d924ed3008765ca624a7eeb950 --- gnss/2.0/default/GnssMeasurement.cpp | 2 +- gnss/2.0/default/GnssMeasurement.h | 2 ++ gnss/2.1/default/GnssAntennaInfo.cpp | 2 +- gnss/2.1/default/GnssAntennaInfo.h | 2 ++ gnss/2.1/default/GnssMeasurement.cpp | 2 +- gnss/2.1/default/GnssMeasurement.h | 3 +++ 6 files changed, 10 insertions(+), 3 deletions(-) diff --git a/gnss/2.0/default/GnssMeasurement.cpp b/gnss/2.0/default/GnssMeasurement.cpp index d778d508cd..a3ea807729 100644 --- a/gnss/2.0/default/GnssMeasurement.cpp +++ b/gnss/2.0/default/GnssMeasurement.cpp @@ -49,8 +49,8 @@ Return GnssMeasurement::setCallba Return GnssMeasurement::close() { ALOGD("close"); - std::unique_lock lock(mMutex); stop(); + std::unique_lock lock(mMutex); sCallback = nullptr; return Void(); } diff --git a/gnss/2.0/default/GnssMeasurement.h b/gnss/2.0/default/GnssMeasurement.h index d8ffd59305..151456cdb1 100644 --- a/gnss/2.0/default/GnssMeasurement.h +++ b/gnss/2.0/default/GnssMeasurement.h @@ -61,10 +61,12 @@ struct GnssMeasurement : public IGnssMeasurement { void stop(); void reportMeasurement(const GnssData&); + // Guarded by mMutex static sp sCallback; std::atomic mMinIntervalMillis; std::atomic mIsActive; std::thread mThread; + // Synchronization lock for sCallback mutable std::mutex mMutex; }; diff --git a/gnss/2.1/default/GnssAntennaInfo.cpp b/gnss/2.1/default/GnssAntennaInfo.cpp index d32a0afc48..ed183a9383 100644 --- a/gnss/2.1/default/GnssAntennaInfo.cpp +++ b/gnss/2.1/default/GnssAntennaInfo.cpp @@ -55,8 +55,8 @@ Return GnssAntennaInfo::setCallback( Return GnssAntennaInfo::close() { ALOGD("close"); - std::unique_lock lock(mMutex); stop(); + std::unique_lock lock(mMutex); sCallback = nullptr; return Void(); } diff --git a/gnss/2.1/default/GnssAntennaInfo.h b/gnss/2.1/default/GnssAntennaInfo.h index f4bfd24367..c512e4e955 100644 --- a/gnss/2.1/default/GnssAntennaInfo.h +++ b/gnss/2.1/default/GnssAntennaInfo.h @@ -47,10 +47,12 @@ struct GnssAntennaInfo : public IGnssAntennaInfo { void reportAntennaInfo( const hidl_vec& antennaInfo) const; + // Guarded by mMutex static sp sCallback; std::atomic mMinIntervalMillis; std::atomic mIsActive; std::thread mThread; + // Synchronization lock for sCallback mutable std::mutex mMutex; }; diff --git a/gnss/2.1/default/GnssMeasurement.cpp b/gnss/2.1/default/GnssMeasurement.cpp index 34e20e5790..63bbc0a399 100644 --- a/gnss/2.1/default/GnssMeasurement.cpp +++ b/gnss/2.1/default/GnssMeasurement.cpp @@ -47,8 +47,8 @@ Return GnssMeasurement::setCallba Return GnssMeasurement::close() { ALOGD("close"); - std::unique_lock lock(mMutex); stop(); + std::unique_lock lock(mMutex); sCallback_2_1 = nullptr; sCallback_2_0 = nullptr; return Void(); diff --git a/gnss/2.1/default/GnssMeasurement.h b/gnss/2.1/default/GnssMeasurement.h index 3ed7bc597d..410876dd5a 100644 --- a/gnss/2.1/default/GnssMeasurement.h +++ b/gnss/2.1/default/GnssMeasurement.h @@ -66,11 +66,14 @@ struct GnssMeasurement : public IGnssMeasurement { void reportMeasurement(const GnssDataV2_0&); void reportMeasurement(const GnssDataV2_1&); + // Guarded by mMutex static sp sCallback_2_1; + // Guarded by mMutex static sp sCallback_2_0; std::atomic mMinIntervalMillis; std::atomic mIsActive; std::thread mThread; + // Synchronization lock for sCallback_2_1 and sCallback_2_0 mutable std::mutex mMutex; }; -- GitLab From 9cc3aae973e1fc29124465d77db8b189fa310a47 Mon Sep 17 00:00:00 2001 From: Yu-Han Yang Date: Fri, 6 Mar 2020 12:50:39 -0800 Subject: [PATCH 025/790] Add newlines to clarify the comments Bug: 150830099 Test: format only Change-Id: Icdcb5f8587e3d95c3d707f0f843824989fde064b --- gnss/2.0/default/GnssMeasurement.h | 2 ++ gnss/2.1/default/GnssAntennaInfo.h | 2 ++ gnss/2.1/default/GnssMeasurement.h | 3 +++ 3 files changed, 7 insertions(+) diff --git a/gnss/2.0/default/GnssMeasurement.h b/gnss/2.0/default/GnssMeasurement.h index 151456cdb1..73eaa1320a 100644 --- a/gnss/2.0/default/GnssMeasurement.h +++ b/gnss/2.0/default/GnssMeasurement.h @@ -63,9 +63,11 @@ struct GnssMeasurement : public IGnssMeasurement { // Guarded by mMutex static sp sCallback; + std::atomic mMinIntervalMillis; std::atomic mIsActive; std::thread mThread; + // Synchronization lock for sCallback mutable std::mutex mMutex; }; diff --git a/gnss/2.1/default/GnssAntennaInfo.h b/gnss/2.1/default/GnssAntennaInfo.h index c512e4e955..f2ce9a8955 100644 --- a/gnss/2.1/default/GnssAntennaInfo.h +++ b/gnss/2.1/default/GnssAntennaInfo.h @@ -49,9 +49,11 @@ struct GnssAntennaInfo : public IGnssAntennaInfo { // Guarded by mMutex static sp sCallback; + std::atomic mMinIntervalMillis; std::atomic mIsActive; std::thread mThread; + // Synchronization lock for sCallback mutable std::mutex mMutex; }; diff --git a/gnss/2.1/default/GnssMeasurement.h b/gnss/2.1/default/GnssMeasurement.h index 410876dd5a..d44641978f 100644 --- a/gnss/2.1/default/GnssMeasurement.h +++ b/gnss/2.1/default/GnssMeasurement.h @@ -68,11 +68,14 @@ struct GnssMeasurement : public IGnssMeasurement { // Guarded by mMutex static sp sCallback_2_1; + // Guarded by mMutex static sp sCallback_2_0; + std::atomic mMinIntervalMillis; std::atomic mIsActive; std::thread mThread; + // Synchronization lock for sCallback_2_1 and sCallback_2_0 mutable std::mutex mMutex; }; -- GitLab From 5d463fdaaa02189d500f189fe1e9401c07a42046 Mon Sep 17 00:00:00 2001 From: Huihong Luo Date: Thu, 6 Feb 2020 18:39:56 -0800 Subject: [PATCH 026/790] Don't send brightness to car service inside Emulator This fixes this cts test: android.cts.statsd.atom.UidAtomTests#testScreenBrightness Bug: 139959479 Test: atest android.cts.statsd.atom.UidAtomTests#testScreenBrightness Change-Id: I66f858ce7686a90cd395f4e646133e8ea4604be4 (cherry picked from commit 1322465c48d0c3dfa5953573b80a89460b8e7e95) --- .../impl/vhal_v2_0/EmulatedVehicleHal.cpp | 24 ++++++++++++++++++- .../impl/vhal_v2_0/EmulatedVehicleHal.h | 1 + 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp index 6d5f23f7fc..b76aff9421 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp @@ -15,8 +15,9 @@ */ #define LOG_TAG "DefaultVehicleHal_v2_0" -#include #include +#include +#include #include "EmulatedVehicleHal.h" #include "JsonFakeValueGenerator.h" @@ -186,6 +187,14 @@ StatusCode EmulatedVehicleHal::set(const VehiclePropValue& propValue) { return StatusCode::NOT_AVAILABLE; } + if (mInEmulator && propValue.prop == toInt(VehicleProperty::DISPLAY_BRIGHTNESS)) { + // Emulator does not support remote brightness control, b/139959479 + // do not send it down so that it does not bring unnecessary property change event + // return other error code, such NOT_AVAILABLE, causes Emulator to be freezing + // TODO: return StatusCode::NOT_AVAILABLE once the above issue is fixed + return StatusCode::OK; + } + /** * After checking all conditions, such as the property is available, a real vhal will * sent the events to Car ECU to take actions. @@ -211,6 +220,17 @@ static bool isDiagnosticProperty(VehiclePropConfig propConfig) { return false; } +// determine if it's running inside Android Emulator +static bool isInEmulator() { + char propValue[PROP_VALUE_MAX]; + bool isEmulator = (__system_property_get("ro.kernel.qemu", propValue) != 0); + if (!isEmulator) { + isEmulator = (__system_property_get("ro.hardware", propValue) != 0) && + (!strcmp(propValue, "ranchu") || !strcmp(propValue, "goldfish")); + } + return isEmulator; +} + // Parse supported properties list and generate vector of property values to hold current values. void EmulatedVehicleHal::onCreate() { static constexpr bool shouldUpdateStatus = true; @@ -261,6 +281,8 @@ void EmulatedVehicleHal::onCreate() { } initObd2LiveFrame(*mPropStore->getConfigOrDie(OBD2_LIVE_FRAME)); initObd2FreezeFrame(*mPropStore->getConfigOrDie(OBD2_FREEZE_FRAME)); + mInEmulator = isInEmulator(); + ALOGD("mInEmulator=%s", mInEmulator ? "true" : "false"); } std::vector EmulatedVehicleHal::listProperties() { diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h index ebf19951b3..dc05145cd7 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h @@ -86,6 +86,7 @@ private: std::unordered_set mHvacPowerProps; RecurrentTimer mRecurrentTimer; VehicleHalClient* mVehicleClient; + bool mInEmulator; }; } // impl -- GitLab From b0d2062abebee358ac9d4fa66b8124ec37a916c8 Mon Sep 17 00:00:00 2001 From: Paul Crowley Date: Wed, 11 Mar 2020 16:30:18 -0700 Subject: [PATCH 027/790] Use a constant-time MAX function Bug: 146520538 Test: atest HadamardTest Change-Id: Ife1012c14d697141e6ee0c583dc32eaacdb72b73 --- rebootescrow/aidl/default/HadamardUtils.cpp | 46 ++++++++++++++------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/rebootescrow/aidl/default/HadamardUtils.cpp b/rebootescrow/aidl/default/HadamardUtils.cpp index d2422b9cd5..adb2010ae6 100644 --- a/rebootescrow/aidl/default/HadamardUtils.cpp +++ b/rebootescrow/aidl/default/HadamardUtils.cpp @@ -16,8 +16,6 @@ #include -#include - #include namespace aidl { @@ -92,6 +90,31 @@ std::vector EncodeKey(const std::vector& input) { return result; } +// Constant-time conditional copy, to fix b/146520538 +// ctl must be 0 or 1; we do the copy if it's 1. +static void CondCopy(uint32_t ctl, void* dest, const void* src, size_t len) { + const auto cdest = reinterpret_cast(dest); + const auto csrc = reinterpret_cast(src); + for (size_t i = 0; i < len; i++) { + const uint32_t d = cdest[i]; + const uint32_t s = csrc[i]; + cdest[i] = d ^ (-ctl & (s ^ d)); + } +} + +struct CodewordWinner { + uint16_t codeword; + int32_t score; +}; + +// Replace dest with src if it has a higher score +static void CopyWinner(CodewordWinner* dest, const CodewordWinner& src) { + // Scores are between - 2^15 and 2^15, so taking the difference won't + // overflow; we use the sign bit of the difference here. + CondCopy(static_cast(dest->score - src.score) >> 31, dest, &src, + sizeof(CodewordWinner)); +} + // Decode a single codeword. Because of the way codewords are striped together // this takes the entire input, plus an offset telling it which word to decode. static uint16_t DecodeWord(size_t word, const std::vector& encoded) { @@ -118,20 +141,15 @@ static uint16_t DecodeWord(size_t word, const std::vector& encoded) { } } } - auto hiscore = std::numeric_limits::min(); - uint16_t winner; - // TODO(b/146520538): this needs to be constant time + // -ENCODE_LENGTH is least possible score, so start one less than that + auto best = CodewordWinner{0, -static_cast(ENCODE_LENGTH + 1)}; + // For every possible codeword value, look at its score, and replace best if it's higher, + // in constant time. for (size_t i = 0; i < ENCODE_LENGTH; i++) { - if (scores[i] > hiscore) { - winner = i; - hiscore = scores[i]; - - } else if (-scores[i] > hiscore) { - winner = i | (1 << CODE_K); - hiscore = -scores[i]; - } + CopyWinner(&best, CodewordWinner{static_cast(i), scores[i]}); + CopyWinner(&best, CodewordWinner{static_cast(i | (1 << CODE_K)), -scores[i]}); } - return winner; + return best.codeword; } std::vector DecodeKey(const std::vector& shuffled) { -- GitLab From 9fcccf8b85b3ecde96a1b0810a61b2156e083885 Mon Sep 17 00:00:00 2001 From: Xusong Wang Date: Fri, 13 Mar 2020 10:02:36 -0700 Subject: [PATCH 028/790] Fix VTS of fenced execution with zero-sized output. Fixes: 151441390 Test: 1.3 VTS Change-Id: I100329e18c34c377d217af155c2abc8e67078778 --- .../vts/functional/GeneratedTestHarness.cpp | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/neuralnetworks/1.3/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/1.3/vts/functional/GeneratedTestHarness.cpp index 83a8d94ba5..aae58bfb3e 100644 --- a/neuralnetworks/1.3/vts/functional/GeneratedTestHarness.cpp +++ b/neuralnetworks/1.3/vts/functional/GeneratedTestHarness.cpp @@ -493,6 +493,13 @@ static std::vector getOutputBuffers(const TestModel& testModel, cons return outputBuffers; } +static bool hasZeroSizedOutput(const TestModel& testModel) { + return std::any_of(testModel.main.outputIndexes.begin(), testModel.main.outputIndexes.end(), + [&testModel](uint32_t index) { + return testModel.main.operands[index].data.size() == 0; + }); +} + static Return ExecutePreparedModel(const sp& preparedModel, const Request& request, MeasureTiming measure, const OptionalTimeoutDuration& loopTimeoutDuration, @@ -689,6 +696,11 @@ void EvaluatePreparedModel(const sp& device, const sp& 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 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); @@ -936,13 +948,8 @@ INSTANTIATE_GENERATED_TEST(DynamicOutputShapeTest, [](const TestModel& testModel INSTANTIATE_GENERATED_TEST(MemoryDomainTest, [](const TestModel& testModel) { return !testModel.expectFailure; }); -INSTANTIATE_GENERATED_TEST(FencedComputeTest, [](const TestModel& testModel) { - return !testModel.expectFailure && - std::all_of(testModel.main.outputIndexes.begin(), testModel.main.outputIndexes.end(), - [&testModel](uint32_t index) { - return testModel.main.operands[index].data.size() > 0; - }); -}); +INSTANTIATE_GENERATED_TEST(FencedComputeTest, + [](const TestModel& testModel) { return !testModel.expectFailure; }); INSTANTIATE_GENERATED_TEST(QuantizationCouplingTest, [](const TestModel& testModel) { return testModel.hasQuant8CoupledOperands() && testModel.main.operations.size() == 1; -- GitLab From 2c9251becf7eeac4737779e06a038a7b5e330a66 Mon Sep 17 00:00:00 2001 From: chrisweir Date: Tue, 24 Mar 2020 11:01:57 -0700 Subject: [PATCH 029/790] Add libc++fs for auto Add a temporary version of libc++fs for a couple of auto features. This will need to be switched out when libc++fs merges, possibly in S. Bug: 152067309 Bug: 142654031 Test: Manual Change-Id: Ibb495af8140470b79e73fd104fd5061f7e3ad8a9 --- .../can/1.0/default/libc++fs/Android.bp | 83 +++++++++++++++++++ automotive/can/1.0/default/libc++fs/include | 1 + automotive/can/1.0/default/libc++fs/src | 1 + 3 files changed, 85 insertions(+) create mode 100644 automotive/can/1.0/default/libc++fs/Android.bp create mode 120000 automotive/can/1.0/default/libc++fs/include create mode 120000 automotive/can/1.0/default/libc++fs/src diff --git a/automotive/can/1.0/default/libc++fs/Android.bp b/automotive/can/1.0/default/libc++fs/Android.bp new file mode 100644 index 0000000000..1fe324ed0f --- /dev/null +++ b/automotive/can/1.0/default/libc++fs/Android.bp @@ -0,0 +1,83 @@ +// +// 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. +// + +// TODO(152067309): Stop building this yourself once it's ABI stable and has +// been made vendor available. Just use libc++fs instead of this. + +cc_defaults { + name: "android.hardware.automotive@libc++fsdefaults", + host_supported: true, + local_include_dirs: ["include"], + export_include_dirs: ["include"], + cflags: [ + "-Wall", + "-Werror", + "-Wno-unused-parameter", + ], + cppflags: [ + "-std=c++14", + "-fexceptions", + "-DLIBCXX_BUILDING_LIBCXXABI", + "-D_LIBCPP_BUILDING_LIBRARY", + ], + rtti: true, + stl: "none", + target: { + linux_bionic: { + enabled: true, + }, + windows: { + enabled: true, + cflags: [ + "-D_LIBCPP_HAS_THREAD_API_WIN32", + "-D_LIBCXXABI_BUILDING_LIBRARY", + "-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS", + "-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS", + "-UWIN32_LEAN_AND_MEAN", + ], + }, + windows_x86: { + cflags: [ + "-fsjlj-exceptions", + ], + }, + }, +} + +cc_library_static { + name: "android.hardware.automotive@libc++fs", + recovery_available: true, + vendor: true, + defaults: ["android.hardware.automotive@libc++fsdefaults"], + srcs: [ + "src/filesystem/directory_iterator.cpp", + "src/filesystem/operations.cpp", + ], + multilib: { + lib32: { + // off_t usage is constrained to within the libc++ source (not the + // headers), so we can build the filesystem library with a 64-bit + // off_t on LP32 to get large file support without needing all users + // of the library to match. + cflags: ["-D_FILE_OFFSET_BITS=64"], + }, + }, + target: { + windows: { + enabled: false, + }, + }, +} diff --git a/automotive/can/1.0/default/libc++fs/include b/automotive/can/1.0/default/libc++fs/include new file mode 120000 index 0000000000..346e65945a --- /dev/null +++ b/automotive/can/1.0/default/libc++fs/include @@ -0,0 +1 @@ +../../../../../../../external/libcxx/include/ \ No newline at end of file diff --git a/automotive/can/1.0/default/libc++fs/src b/automotive/can/1.0/default/libc++fs/src new file mode 120000 index 0000000000..7abb4ba5f9 --- /dev/null +++ b/automotive/can/1.0/default/libc++fs/src @@ -0,0 +1 @@ +../../../../../../../external/libcxx/src/ \ No newline at end of file -- GitLab From 442b3badc8e2458f249104df47cd58bb58c4c9e0 Mon Sep 17 00:00:00 2001 From: chrisweir Date: Thu, 27 Feb 2020 14:33:51 -0800 Subject: [PATCH 030/790] Add Support for Configuring CAN HAL by Serialno Configuration files may now specify a list of serial numbers, or serial number suffixes. These can be used to identify a USB peripheral, regardless of what order the interface names are configured by the OS. Bug: 142654031 Test: Manual Change-Id: Idcdad1159b216119eb063df8bb229172a383b9ed --- automotive/can/1.0/default/Android.bp | 1 + automotive/can/1.0/default/CanController.cpp | 213 +++++++++++++++++- .../1.0/tools/configurator/canprototools.cpp | 15 +- 3 files changed, 214 insertions(+), 15 deletions(-) diff --git a/automotive/can/1.0/default/Android.bp b/automotive/can/1.0/default/Android.bp index ee2e92bdb1..f5cf425887 100644 --- a/automotive/can/1.0/default/Android.bp +++ b/automotive/can/1.0/default/Android.bp @@ -51,5 +51,6 @@ cc_binary { ], static_libs: [ "android.hardware.automotive.can@libnetdevice", + "android.hardware.automotive@libc++fs", ], } diff --git a/automotive/can/1.0/default/CanController.cpp b/automotive/can/1.0/default/CanController.cpp index 0700c77513..a2643afccf 100644 --- a/automotive/can/1.0/default/CanController.cpp +++ b/automotive/can/1.0/default/CanController.cpp @@ -23,6 +23,8 @@ #include #include +#include +#include #include namespace android::hardware::automotive::can::V1_0::implementation { @@ -30,6 +32,29 @@ namespace android::hardware::automotive::can::V1_0::implementation { using IfId = ICanController::BusConfig::InterfaceId; using IfIdDisc = ICanController::BusConfig::InterfaceId::hidl_discriminator; +namespace fsErrors { +static const std::error_code ok; +static const std::error_code eperm(EPERM, std::generic_category()); +static const std::error_code enoent(ENOENT, std::generic_category()); +static const std::error_code eacces(EACCES, std::generic_category()); +} // namespace fsErrors + +/* In the /sys/devices tree, there are files called "serial", which contain the serial numbers + * for various devices. The exact location inside of this directory is dependent upon the + * hardware we are running on, so we have to start from /sys/devices and work our way down. */ +static const std::filesystem::path kDevPath("/sys/devices/"); +static const std::regex kTtyRe("^tty[A-Z]+[0-9]+$"); +static constexpr auto kOpts = ~(std::filesystem::directory_options::follow_directory_symlink | + std::filesystem::directory_options::skip_permission_denied); + +/** + * A helper object to associate the interface name and type of a USB to CAN adapter. + */ +struct UsbCanIface { + ICanController::InterfaceType iftype; + std::string ifaceName; +}; + Return CanController::getSupportedInterfaceTypes(getSupportedInterfaceTypes_cb _hidl_cb) { _hidl_cb({ICanController::InterfaceType::VIRTUAL, ICanController::InterfaceType::SOCKETCAN, ICanController::InterfaceType::SLCAN}); @@ -41,6 +66,152 @@ static bool isValidName(const std::string& name) { return std::regex_match(name, nameRE); } +/** + * Given a UsbCanIface object, get the ifaceName given the serialPath. + * + * \param serialPath - Absolute path to a "serial" file for a given device in /sys. + * \return A populated UsbCanIface. On failure, nullopt is returned. + */ +static std::optional getIfaceName(std::filesystem::path serialPath) { + std::error_code fsStatus; + // Since the path is to a file called "serial", we need to search its parent directory. + std::filesystem::recursive_directory_iterator fsItr(serialPath.parent_path(), kOpts, fsStatus); + if (fsStatus != fsErrors::ok) { + LOG(ERROR) << "Failed to open " << serialPath.parent_path(); + return std::nullopt; + } + + for (; fsStatus == fsErrors::ok && fsItr != std::filesystem::recursive_directory_iterator(); + fsItr.increment(fsStatus)) { + /* We want either a directory called "net" or a directory that looks like tty, so + * skip files. */ + bool isDir = fsItr->is_directory(fsStatus); + if (fsStatus != fsErrors::ok || !isDir) continue; + + /* path() returns an iterator that steps through directories from / to the leaf. + * end() returns one past the leaf of the path, but we want the leaf. Decrementing the + * path gives us a pointer to the leaf, which we then dereference.*/ + std::string currentDir = *(--(fsItr->path().end())); + if (currentDir == "net") { + /* This device is a SocketCAN device. The iface name is the only directory under + * net/. Multiple directories under net/ is an error.*/ + std::filesystem::directory_iterator netItr(fsItr->path(), kOpts, fsStatus); + if (fsStatus != fsErrors::ok) { + LOG(ERROR) << "Failed to open " << fsItr->path() << " to get net name!"; + return std::nullopt; + } + + // Get the leaf of the path. This is the interface name, assuming it's the only leaf. + std::string netName = *(--(netItr->path().end())); + + // Check if there is more than one item in net/ + netItr.increment(fsStatus); + if (fsStatus != fsErrors::ok) { + // It's possible we have a valid net name, but this is most likely an error. + LOG(ERROR) << "Failed to verify " << fsItr->path() << " has valid net name!"; + return std::nullopt; + } + if (netItr != std::filesystem::directory_iterator()) { + // There should never be more than one name under net/ + LOG(ERROR) << "Found more than one net name in " << fsItr->path() << "!"; + return std::nullopt; + } + return {{ICanController::InterfaceType::SOCKETCAN, netName}}; + } else if (std::regex_match(currentDir, kTtyRe)) { + // This device is a USB serial device, and currentDir is the tty name. + return {{ICanController::InterfaceType::SLCAN, "/dev/" + currentDir}}; + } + } + + // check if the loop above exited due to a c++fs error. + if (fsStatus != fsErrors::ok) { + LOG(ERROR) << "Failed search filesystem: " << fsStatus; + } + return std::nullopt; +} + +/** + * A helper function to read the serial number from a "serial" file in /sys/devices/ + * + * \param serialnoPath - path to the file to read. + * \return the serial number, or nullopt on failure. + */ +static std::optional readSerialNo(const std::string& serialnoPath) { + std::ifstream serialnoStream(serialnoPath); + std::string serialno; + if (!serialnoStream.good()) { + LOG(ERROR) << "Failed to read serial number from " << serialnoPath; + return std::nullopt; + } + std::getline(serialnoStream, serialno); + return serialno; +} + +/** + * Searches for USB devices found in /sys/devices/, and attempts to find a device matching the + * provided list of serial numbers. + * + * \param configSerialnos - a list of serial number (suffixes) from the HAL config. + * \param iftype - the type of the interface to be located. + * \return a matching USB device. On failure, std::nullopt is returned. + */ +static std::optional findUsbDevice(const hidl_vec& configSerialnos) { + std::error_code fsStatus; + std::filesystem::recursive_directory_iterator fsItr(kDevPath, kOpts, fsStatus); + if (fsStatus != fsErrors::ok) { + LOG(ERROR) << "Failed to open " << kDevPath; + return std::nullopt; + } + + for (; fsStatus == fsErrors::ok && fsItr != std::filesystem::recursive_directory_iterator(); + fsItr.increment(fsStatus)) { + // We want to find a file called "serial", which is in a directory somewhere. Skip files. + bool isDir = fsItr->is_directory(fsStatus); + if (fsStatus != fsErrors::ok) { + LOG(ERROR) << "Failed check if " << fsStatus; + return std::nullopt; + } + if (!isDir) continue; + + auto serialnoPath = fsItr->path() / "serial"; + bool isReg = std::filesystem::is_regular_file(serialnoPath, fsStatus); + + /* Make sure we have permissions to this directory, ignore enoent, since the file + * "serial" may not exist, which is ok. */ + if (fsStatus == fsErrors::eperm || fsStatus == fsErrors::eacces) { + /* This means we don't have access to this directory. If we recurse into it, this + * will cause the iterator to loose its state and we'll crash. */ + fsItr.disable_recursion_pending(); + continue; + } + if (fsStatus == fsErrors::enoent) continue; + if (fsStatus != fsErrors::ok) { + LOG(WARNING) << "An unexpected error occurred while checking for serialno: " + << fsStatus; + continue; + } + if (!isReg) continue; + + // we found a serial number + auto serialno = readSerialNo(serialnoPath); + if (!serialno.has_value()) continue; + + // see if the serial number exists in the config + for (auto&& cfgSn : configSerialnos) { + if (serialno->ends_with(std::string(cfgSn))) { + auto ifaceInfo = getIfaceName(serialnoPath); + if (!ifaceInfo.has_value()) break; + return ifaceInfo; + } + } + } + if (fsStatus != fsErrors::ok) { + LOG(ERROR) << "Error searching filesystem: " << fsStatus; + return std::nullopt; + } + return std::nullopt; +} + Return CanController::upInterface(const ICanController::BusConfig& config) { LOG(VERBOSE) << "Attempting to bring interface up: " << toString(config); @@ -58,24 +229,46 @@ Return CanController::upInterface(const ICanController:: sp busService; + // SocketCAN native type interface. if (config.interfaceId.getDiscriminator() == IfIdDisc::socketcan) { - // TODO(b/142654031): support serialno auto& socketcan = config.interfaceId.socketcan(); - if (socketcan.getDiscriminator() == IfId::Socketcan::hidl_discriminator::ifname) { - busService = new CanBusNative(socketcan.ifname(), config.bitrate); + std::string ifaceName; + if (socketcan.getDiscriminator() == IfId::Socketcan::hidl_discriminator::serialno) { + // Configure by serial number. + auto selectedDevice = findUsbDevice(socketcan.serialno()); + // verify the returned device is the correct one + if (!selectedDevice.has_value() || + selectedDevice->iftype != ICanController::InterfaceType::SOCKETCAN) { + return ICanController::Result::BAD_INTERFACE_ID; + } + ifaceName = selectedDevice->ifaceName; } else { - return ICanController::Result::BAD_INTERFACE_ID; + // configure by iface name. + ifaceName = socketcan.ifname(); } - } else if (config.interfaceId.getDiscriminator() == IfIdDisc::virtualif) { + busService = new CanBusNative(ifaceName, config.bitrate); + } + // Virtual interface. + else if (config.interfaceId.getDiscriminator() == IfIdDisc::virtualif) { busService = new CanBusVirtual(config.interfaceId.virtualif().ifname); - } else if (config.interfaceId.getDiscriminator() == IfIdDisc::slcan) { - // TODO(b/142654031): support serialno + } + // SLCAN interface. + else if (config.interfaceId.getDiscriminator() == IfIdDisc::slcan) { auto& slcan = config.interfaceId.slcan(); - if (slcan.getDiscriminator() == IfId::Slcan::hidl_discriminator::ttyname) { - busService = new CanBusSlcan(slcan.ttyname(), config.bitrate); + std::string ttyName; + if (slcan.getDiscriminator() == IfId::Slcan::hidl_discriminator::serialno) { + // Configure by serial number. + auto selectedDevice = findUsbDevice(slcan.serialno()); + if (!selectedDevice.has_value() || + selectedDevice->iftype != ICanController::InterfaceType::SLCAN) { + return ICanController::Result::BAD_INTERFACE_ID; + } + ttyName = selectedDevice->ifaceName; } else { - return ICanController::Result::BAD_INTERFACE_ID; + // Configure by tty name. + ttyName = slcan.ttyname(); } + busService = new CanBusSlcan(ttyName, config.bitrate); } else { return ICanController::Result::NOT_SUPPORTED; } diff --git a/automotive/can/1.0/tools/configurator/canprototools.cpp b/automotive/can/1.0/tools/configurator/canprototools.cpp index 8e6b2b1d45..e7e364222c 100644 --- a/automotive/can/1.0/tools/configurator/canprototools.cpp +++ b/automotive/can/1.0/tools/configurator/canprototools.cpp @@ -85,26 +85,31 @@ std::optional fromPbBus(const Bus& pb_bus) { switch (pb_bus.iface_type_case()) { case Bus::kNative: { const auto ifname = pb_bus.native().ifname(); - if (ifname.empty()) { - LOG(ERROR) << "Invalid config: native type bus must have an iface name"; + const auto serialno = pb_bus.native().serialno(); + if (ifname.empty() == serialno.empty()) { + LOG(ERROR) << "Invalid config: native type bus must have an iface name xor a " + << "serial number"; return std::nullopt; } bus_cfg.bitrate = pb_bus.bitrate(); ICanController::BusConfig::InterfaceId::Socketcan socketcan = {}; - socketcan.ifname(ifname); + if (!ifname.empty()) socketcan.ifname(ifname); + if (!serialno.empty()) socketcan.serialno({serialno.begin(), serialno.end()}); bus_cfg.interfaceId.socketcan(socketcan); // TODO(b/142654031) - add support for serial number as an option instead of ifname. break; } case Bus::kSlcan: { const auto ttyname = pb_bus.slcan().ttyname(); - if (ttyname.empty()) { + const auto serialno = pb_bus.slcan().serialno(); + if (ttyname.empty() == serialno.empty()) { LOG(ERROR) << "Invalid config: slcan type bus must have a tty name"; return std::nullopt; } bus_cfg.bitrate = pb_bus.bitrate(); ICanController::BusConfig::InterfaceId::Slcan slcan = {}; - slcan.ttyname(pb_bus.slcan().ttyname()); + if (!ttyname.empty()) slcan.ttyname(ttyname); + if (!serialno.empty()) slcan.serialno({serialno.begin(), serialno.end()}); bus_cfg.interfaceId.slcan(slcan); break; } -- GitLab From 48618f607cc71c11fc141f44e619d343f412f23b Mon Sep 17 00:00:00 2001 From: Yipeng Cao Date: Thu, 19 Mar 2020 18:11:16 -0700 Subject: [PATCH 031/790] Hal layer for gnss replay Test: Added following kernel cmdline and tested on local CF gnss_cmdline.serdev=serial8250/serial0/serial0-0 gnss_cmdline.type=0 serdev_ttyport.pdev_tty_port=ttyS1 Change-Id: I3766c31672aa91341403105759b2fd997e7f8879 --- gnss/2.1/default/Gnss.cpp | 77 ++++- gnss/2.1/default/Gnss.h | 10 + gnss/common/utils/default/Android.bp | 1 + gnss/common/utils/default/NmeaFixInfo.cpp | 266 ++++++++++++++++++ .../utils/default/include/NmeaFixInfo.h | 92 ++++++ 5 files changed, 435 insertions(+), 11 deletions(-) create mode 100644 gnss/common/utils/default/NmeaFixInfo.cpp create mode 100644 gnss/common/utils/default/include/NmeaFixInfo.h diff --git a/gnss/2.1/default/Gnss.cpp b/gnss/2.1/default/Gnss.cpp index 2b327a9916..16f2bf3cd0 100644 --- a/gnss/2.1/default/Gnss.cpp +++ b/gnss/2.1/default/Gnss.cpp @@ -17,14 +17,15 @@ #define LOG_TAG "Gnss" #include "Gnss.h" +#include +#include +#include #include "GnssAntennaInfo.h" #include "GnssDebug.h" #include "GnssMeasurement.h" #include "GnssMeasurementCorrections.h" #include "Utils.h" -#include - using ::android::hardware::gnss::common::Utils; using ::android::hardware::gnss::measurement_corrections::V1_1::implementation:: GnssMeasurementCorrections; @@ -40,14 +41,55 @@ sp Gnss::sGnssCallback_2_0 = nullptr; sp Gnss::sGnssCallback_1_1 = nullptr; sp Gnss::sGnssCallback_1_0 = nullptr; -Gnss::Gnss() : mMinIntervalMs(1000), mGnssConfiguration{new GnssConfiguration()} {} +Gnss::Gnss() + : mMinIntervalMs(1000), + mGnssConfiguration{new GnssConfiguration()}, + mHardwareModeOn(false), + mGnssFd(-1) {} Gnss::~Gnss() { stop(); } +std::unique_ptr Gnss::getLocationFromHW() { + char inputBuffer[INPUT_BUFFER_SIZE]; + mHardwareModeOn = false; + if (mGnssFd == -1) { + mGnssFd = open(GNSS_PATH, O_RDWR | O_NONBLOCK); + } + if (mGnssFd == -1) { + return nullptr; + } + // Send control message to device + int bytes_write = write(mGnssFd, CMD_GET_LOCATION, strlen(CMD_GET_LOCATION)); + if (bytes_write <= 0) { + return nullptr; + } + + struct epoll_event ev, events[1]; + ev.data.fd = mGnssFd; + ev.events = EPOLLIN; + int epoll_fd = epoll_create1(0); + epoll_ctl(epoll_fd, EPOLL_CTL_ADD, mGnssFd, &ev); + int bytes_read = -1; + std::string inputStr = ""; + int epoll_ret = epoll_wait(epoll_fd, events, 1, mMinIntervalMs); + // Indicates it is a hardwareMode, don't need to wait outside. + mHardwareModeOn = true; + if (epoll_ret == -1) { + return nullptr; + } + while (true) { + bytes_read = read(mGnssFd, &inputBuffer, INPUT_BUFFER_SIZE); + if (bytes_read <= 0) { + break; + } + inputStr += std::string(inputBuffer, bytes_read); + } + return NmeaFixInfo::getLocationFromInputStr(inputStr); +} + Return Gnss::start() { - ALOGD("start"); if (mIsActive) { ALOGW("Gnss has started. Restarting..."); stop(); @@ -59,15 +101,24 @@ Return Gnss::start() { auto svStatus = filterBlacklistedSatellitesV2_1(Utils::getMockSvInfoListV2_1()); this->reportSvStatus(svStatus); - if (sGnssCallback_2_1 != nullptr || sGnssCallback_2_0 != nullptr) { - const auto location = Utils::getMockLocationV2_0(); - this->reportLocation(location); + auto currentLocation = getLocationFromHW(); + if (currentLocation != nullptr) { + this->reportLocation(*currentLocation); } else { - const auto location = Utils::getMockLocationV1_0(); - this->reportLocation(location); + if (sGnssCallback_2_1 != nullptr || sGnssCallback_2_0 != nullptr) { + const auto location = Utils::getMockLocationV2_0(); + this->reportLocation(location); + } else { + const auto location = Utils::getMockLocationV1_0(); + this->reportLocation(location); + } + + // Only need do the sleep in the static location mode, which mocks the "wait + // for" hardware behavior. + if (!mHardwareModeOn) { + std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMs)); + } } - - std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMs)); } }); return true; @@ -89,6 +140,10 @@ Return Gnss::stop() { if (mThread.joinable()) { mThread.join(); } + if (mGnssFd != -1) { + close(mGnssFd); + mGnssFd = -1; + } return true; } diff --git a/gnss/2.1/default/Gnss.h b/gnss/2.1/default/Gnss.h index bd5e6e852c..9af0d46e39 100644 --- a/gnss/2.1/default/Gnss.h +++ b/gnss/2.1/default/Gnss.h @@ -24,6 +24,7 @@ #include #include "GnssAntennaInfo.h" #include "GnssConfiguration.h" +#include "NmeaFixInfo.h" namespace android { namespace hardware { @@ -31,9 +32,14 @@ namespace gnss { namespace V2_1 { using GnssSvInfo = IGnssCallback::GnssSvInfo; +using ::android::hardware::gnss::common::NmeaFixInfo; namespace implementation { +constexpr int INPUT_BUFFER_SIZE = 128; +constexpr char CMD_GET_LOCATION[] = "CMD_GET_LOCATION"; +constexpr char GNSS_PATH[] = "/dev/gnss0"; + struct Gnss : public IGnss { Gnss(); ~Gnss(); @@ -95,6 +101,7 @@ struct Gnss : public IGnss { Return> getExtensionGnssAntennaInfo() override; private: + std::unique_ptr getLocationFromHW(); void reportLocation(const V2_0::GnssLocation&) const; void reportLocation(const V1_0::GnssLocation&) const; void reportSvStatus(const hidl_vec&) const; @@ -106,7 +113,10 @@ struct Gnss : public IGnss { std::atomic mMinIntervalMs; sp mGnssConfiguration; std::atomic mIsActive; + std::atomic mHardwareModeOn; + std::atomic mGnssFd; std::thread mThread; + mutable std::mutex mMutex; hidl_vec filterBlacklistedSatellitesV2_1(hidl_vec gnssSvInfoList); }; diff --git a/gnss/common/utils/default/Android.bp b/gnss/common/utils/default/Android.bp index 577f6ae5e3..2712e7776c 100644 --- a/gnss/common/utils/default/Android.bp +++ b/gnss/common/utils/default/Android.bp @@ -25,6 +25,7 @@ cc_library_static { ], srcs: [ "Utils.cpp", + "NmeaFixInfo.cpp", ], export_include_dirs: ["include"], shared_libs: [ diff --git a/gnss/common/utils/default/NmeaFixInfo.cpp b/gnss/common/utils/default/NmeaFixInfo.cpp new file mode 100644 index 0000000000..43e008bb72 --- /dev/null +++ b/gnss/common/utils/default/NmeaFixInfo.cpp @@ -0,0 +1,266 @@ +/* + * 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 "NmeaFixInfo" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace android { +namespace hardware { +namespace gnss { +namespace common { + +NmeaFixInfo::NmeaFixInfo() : hasGMCRecord(false), hasGGARecord(false) {} + +float NmeaFixInfo::getAltitudeMeters() const { + return altitudeMeters; +} + +float NmeaFixInfo::checkAndConvertToFloat(const std::string& sentence) { + if (sentence.empty()) { + return std::numeric_limits::quiet_NaN(); + } + return std::stof(sentence); +} + +float NmeaFixInfo::getBearingAccuracyDegrees() const { + // Current NMEA doesn't contains beaing accuracy inforamtion + return kMockBearingAccuracyDegrees; +} +float NmeaFixInfo::getBearingDegrees() const { + return bearingDegrees; +} + +float NmeaFixInfo::getHorizontalAccuracyMeters() const { + // Current NMEA doesn't contains horizontal accuracy inforamtion + return kMockHorizontalAccuracyMeters; +} + +float NmeaFixInfo::getLatDeg() const { + return latDeg; +} + +float NmeaFixInfo::getLngDeg() const { + return lngDeg; +} + +float NmeaFixInfo::getSpeedAccuracyMetersPerSecond() const { + // Current NMEA doesn't contains speed accuracy inforamtion + return kMockSpeedAccuracyMetersPerSecond; +} + +float NmeaFixInfo::getSpeedMetersPerSec() const { + return speedMetersPerSec; +} + +int64_t NmeaFixInfo::getTimestamp() const { + return timestamp; +} + +float NmeaFixInfo::getVerticalAccuracyMeters() const { + // Current NMEA doesn't contains vertical accuracy inforamtion + return kMockVerticalAccuracyMeters; +} + +int64_t NmeaFixInfo::nmeaPartsToTimestamp(const std::string& timeStr, const std::string& dateStr) { + /** + * In NMEA format, the full time can only get from the $GPRMC record, see + * the following example: + * $GPRMC,213204.00,A,3725.371240,N,12205.589239,W,000.0,000.0,290819,,,A*49 + * the datetime is stored in two parts, 213204 and 290819, which means + * 2019/08/29 21:32:04, however for in unix the year starts from 1900, we + * need to add the offset. + */ + struct tm tm; + const int32_t unixYearOffset = 100; + tm.tm_mday = std::stoi(dateStr.substr(0, 2).c_str()); + tm.tm_mon = std::stoi(dateStr.substr(2, 2).c_str()) - 1; + tm.tm_year = std::stoi(dateStr.substr(4, 2).c_str()) + unixYearOffset; + tm.tm_hour = std::stoi(timeStr.substr(0, 2).c_str()); + tm.tm_min = std::stoi(timeStr.substr(2, 2).c_str()); + tm.tm_sec = std::stoi(timeStr.substr(4, 2).c_str()); + return static_cast(mktime(&tm) - timezone); +} + +bool NmeaFixInfo::isValidFix() const { + return hasGMCRecord && hasGGARecord; +} + +void NmeaFixInfo::parseGGALine(const std::vector& sentenceValues) { + if (sentenceValues.size() == 0 || sentenceValues[0].compare(GPGA_RECORD_TAG) != 0) { + return; + } + // LatDeg, need covert to degree, if it is 'N', should be negative value + this->latDeg = std::stof(sentenceValues[2].substr(0, 2)) + + (std::stof(sentenceValues[2].substr(2)) / 60.0); + if (sentenceValues[3].compare("N") != 0) { + this->latDeg *= -1; + } + + // LngDeg, need covert to degree, if it is 'E', should be negative value + this->lngDeg = std::stof(sentenceValues[4].substr(0, 3)) + + std::stof(sentenceValues[4].substr(3)) / 60.0; + if (sentenceValues[5].compare("E") != 0) { + this->lngDeg *= -1; + } + + this->altitudeMeters = std::stof(sentenceValues[9]); + + this->hDop = sentenceValues[8].empty() ? std::numeric_limits::quiet_NaN() + : std::stof(sentenceValues[8]); + this->hasGGARecord = true; +} + +void NmeaFixInfo::parseRMCLine(const std::vector& sentenceValues) { + if (sentenceValues.size() == 0 || sentenceValues[0].compare(GPRMC_RECORD_TAG) != 0) { + return; + } + this->speedMetersPerSec = checkAndConvertToFloat(sentenceValues[7]); + this->bearingDegrees = checkAndConvertToFloat(sentenceValues[8]); + this->timestamp = nmeaPartsToTimestamp(sentenceValues[1], sentenceValues[9]); + this->hasGMCRecord = true; +} + +/** invalid the current NmeaFixInfo */ +void NmeaFixInfo::reset() { + this->altitudeMeters = 0; + this->bearingDegrees = 0; + this->fixId = 0; + this->hasGMCRecord = false; + this->hasGGARecord = false; + this->latDeg = 0; + this->lngDeg = 0; + this->hDop = 0; + this->vDop = 0; + this->satelliteCount = 0; + this->speedMetersPerSec = 0; + this->timestamp = 0; +} + +void NmeaFixInfo::splitStr(const std::string& line, const char& delimiter, + std::vector& out) { + std::istringstream iss(line); + std::string item; + while (std::getline(iss, item, delimiter)) { + out.push_back(item); + } +} + +NmeaFixInfo& NmeaFixInfo::operator=(const NmeaFixInfo& rhs) { + if (this == &rhs) return *this; + this->altitudeMeters = rhs.altitudeMeters; + this->bearingDegrees = rhs.bearingDegrees; + this->fixId = rhs.fixId; + this->hasGMCRecord = rhs.hasGMCRecord; + this->hasGGARecord = rhs.hasGGARecord; + this->hDop = rhs.hDop; + this->vDop = rhs.vDop; + this->latDeg = rhs.latDeg; + this->lngDeg = rhs.lngDeg; + this->satelliteCount = rhs.satelliteCount; + this->speedMetersPerSec = rhs.speedMetersPerSec; + this->timestamp = rhs.timestamp; + + return *this; +} + +/** + * Parses the input string in NMEA format and convert to GnssLocation. + * Currently version only cares about $GPGGA and $GPRMC records. but we + * can easily extend to other types supported by NMEA if needed. + */ +std::unique_ptr NmeaFixInfo::getLocationFromInputStr( + const std::string& inputStr) { + std::vector nmeaRecords; + splitStr(inputStr, LINE_SEPARATOR, nmeaRecords); + NmeaFixInfo nmeaFixInfo; + NmeaFixInfo candidateFixInfo; + uint32_t fixId = 0; + double lastTimeStamp = 0; + for (const auto& line : nmeaRecords) { + std::vector sentenceValues; + splitStr(line, COMMA_SEPARATOR, sentenceValues); + double currentTimeStamp = std::stof(sentenceValues[1]); + // If see a new timestamp, report correct location. + if ((currentTimeStamp - lastTimeStamp) > TIMESTAMP_EPSILON && + candidateFixInfo.isValidFix()) { + nmeaFixInfo = candidateFixInfo; + candidateFixInfo.reset(); + fixId++; + } + if (line.compare(0, strlen(GPGA_RECORD_TAG), GPGA_RECORD_TAG) == 0) { + candidateFixInfo.fixId = fixId; + candidateFixInfo.parseGGALine(sentenceValues); + } else if (line.compare(0, strlen(GPRMC_RECORD_TAG), GPRMC_RECORD_TAG) == 0) { + candidateFixInfo.parseRMCLine(sentenceValues); + } + } + if (candidateFixInfo.isValidFix()) { + nmeaFixInfo = candidateFixInfo; + candidateFixInfo.reset(); + } + if (!nmeaFixInfo.isValidFix()) { + return nullptr; + } + return nmeaFixInfo.toGnssLocation(); +} + +/** + * Parses the input string in NMEA format and convert to GnssLocation. + */ +std::unique_ptr NmeaFixInfo::toGnssLocation() const { + const V2_0::ElapsedRealtime currentOsTimestamp = { + .flags = V2_0::ElapsedRealtimeFlags::HAS_TIMESTAMP_NS | + V2_0::ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS, + .timestampNs = static_cast(::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 = 1000000}; + + V1_0::GnssLocation locationV1 = { + .gnssLocationFlags = 0xFF, + .latitudeDegrees = this->getLatDeg(), + .longitudeDegrees = this->getLngDeg(), + .altitudeMeters = this->getAltitudeMeters(), + .speedMetersPerSec = this->getSpeedMetersPerSec(), + .bearingDegrees = this->getBearingDegrees(), + .horizontalAccuracyMeters = this->getHorizontalAccuracyMeters(), + .verticalAccuracyMeters = this->getVerticalAccuracyMeters(), + .speedAccuracyMetersPerSecond = this->getSpeedAccuracyMetersPerSecond(), + .bearingAccuracyDegrees = this->getBearingAccuracyDegrees(), + .timestamp = this->getTimestamp()}; + + V2_0::GnssLocation locationV2 = {.v1_0 = locationV1, .elapsedRealtime = currentOsTimestamp}; + + return std::make_unique(locationV2); +} + +} // namespace common +} // namespace gnss +} // namespace hardware +} // namespace android \ No newline at end of file diff --git a/gnss/common/utils/default/include/NmeaFixInfo.h b/gnss/common/utils/default/include/NmeaFixInfo.h new file mode 100644 index 0000000000..fb2c1a4491 --- /dev/null +++ b/gnss/common/utils/default/include/NmeaFixInfo.h @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +namespace android { +namespace hardware { +namespace gnss { +namespace common { +using ::android::sp; +using ::android::hardware::hidl_string; +using ::android::hardware::hidl_vec; +using ::android::hardware::Return; +using ::android::hardware::Void; + +constexpr char GPGA_RECORD_TAG[] = "$GPGGA"; +constexpr char GPRMC_RECORD_TAG[] = "$GPRMC"; +constexpr char LINE_SEPARATOR = '\n'; +constexpr char COMMA_SEPARATOR = ','; +constexpr double TIMESTAMP_EPSILON = 0.001; + +/** Helper class to parse and store the GNSS fix details information. */ +class NmeaFixInfo { + private: + float altitudeMeters; + float bearingDegrees; + uint32_t fixId; + bool hasGMCRecord; + bool hasGGARecord; + float hDop; + float vDop; + float latDeg; + float lngDeg; + uint32_t satelliteCount; + float speedMetersPerSec; + int64_t timestamp; + + public: + static std::unique_ptr getLocationFromInputStr(const std::string& inputStr); + + private: + static void splitStr(const std::string& line, const char& delimiter, + std::vector& out); + static float checkAndConvertToFloat(const std::string& sentence); + static int64_t nmeaPartsToTimestamp(const std::string& timeStr, const std::string& dateStr); + + NmeaFixInfo(); + void parseGGALine(const std::vector& sentenceValues); + void parseRMCLine(const std::vector& sentenceValues); + std::unique_ptr toGnssLocation() const; + + // Getters + float getAltitudeMeters() const; + float getBearingAccuracyDegrees() const; + float getBearingDegrees() const; + uint32_t getFixId() const; + float getHorizontalAccuracyMeters() const; + float getLatDeg() const; + float getLngDeg() const; + float getSpeedAccuracyMetersPerSecond() const; + float getSpeedMetersPerSec() const; + int64_t getTimestamp() const; + float getVerticalAccuracyMeters() const; + + bool isValidFix() const; + void reset(); + NmeaFixInfo& operator=(const NmeaFixInfo& rhs); +}; + +} // namespace common +} // namespace gnss +} // namespace hardware +} // namespace android \ No newline at end of file -- GitLab From 25a866eecc75058be54a837fe5c00df496e626ca Mon Sep 17 00:00:00 2001 From: Siarhei Vishniakou Date: Mon, 30 Mar 2020 17:17:21 -0700 Subject: [PATCH 032/790] Convert InputClassifierTest to parametrized test The test is currently based on old vts harness and not in vts suite. Bug: 150383004 Test: atest VtsHalInputClassifierV1_0TargetTest Change-Id: I5df4eff845fd49b8663d1589c5314d5acf4b5057 --- .../classifier/1.0/vts/functional/Android.bp | 6 ++- .../VtsHalInputClassifierV1_0TargetTest.cpp | 47 ++++++------------- 2 files changed, 18 insertions(+), 35 deletions(-) diff --git a/input/classifier/1.0/vts/functional/Android.bp b/input/classifier/1.0/vts/functional/Android.bp index ef49d70dfb..4db1398778 100644 --- a/input/classifier/1.0/vts/functional/Android.bp +++ b/input/classifier/1.0/vts/functional/Android.bp @@ -22,6 +22,8 @@ cc_test { "android.hardware.input.classifier@1.0", "android.hardware.input.common@1.0", ], - test_suites: ["general-tests"], + test_suites: [ + "general-tests", + "vts-core", + ], } - diff --git a/input/classifier/1.0/vts/functional/VtsHalInputClassifierV1_0TargetTest.cpp b/input/classifier/1.0/vts/functional/VtsHalInputClassifierV1_0TargetTest.cpp index f033c2a102..ee529c73b0 100644 --- a/input/classifier/1.0/vts/functional/VtsHalInputClassifierV1_0TargetTest.cpp +++ b/input/classifier/1.0/vts/functional/VtsHalInputClassifierV1_0TargetTest.cpp @@ -16,11 +16,12 @@ #define LOG_TAG "input_classifier_hal_test" -#include -#include #include #include #include +#include +#include +#include #include #include @@ -72,27 +73,11 @@ static MotionEvent getSimpleMotionEvent() { return event; } -// Test environment for Input Classifier HIDL HAL. -class InputClassifierHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase { - public: - // get the test environment singleton - static InputClassifierHidlEnvironment* Instance() { - static InputClassifierHidlEnvironment* instance = new InputClassifierHidlEnvironment; - return instance; - } - - virtual void registerTestServices() override { registerTestService(); } - - private: - InputClassifierHidlEnvironment() {} -}; - // The main test class for INPUT CLASSIFIER HIDL HAL 1.0. -class InputClassifierHidlTest_1_0 : public ::testing::VtsHalHidlTargetTestBase { +class InputClassifierHidlTest_1_0 : public ::testing::TestWithParam { public: virtual void SetUp() override { - classifier = ::testing::VtsHalHidlTargetTestBase::getService( - InputClassifierHidlEnvironment::Instance()->getServiceName()); + classifier = IInputClassifier::getService(GetParam()); ASSERT_NE(classifier, nullptr); } @@ -105,7 +90,7 @@ class InputClassifierHidlTest_1_0 : public ::testing::VtsHalHidlTargetTestBase { * Call resetDevice(..) for a few common device id values, and make sure that the HAL * can handle the resets gracefully. */ -TEST_F(InputClassifierHidlTest_1_0, ResetDevice) { +TEST_P(InputClassifierHidlTest_1_0, ResetDevice) { EXPECT_TRUE(classifier->resetDevice(ReservedInputDeviceId::VIRTUAL_KEYBOARD_ID).isOk()); EXPECT_TRUE(classifier->resetDevice(ReservedInputDeviceId::BUILT_IN_KEYBOARD_ID).isOk()); EXPECT_TRUE(classifier->resetDevice(1).isOk()); @@ -115,14 +100,14 @@ TEST_F(InputClassifierHidlTest_1_0, ResetDevice) { /** * Call reset() on the HAL to ensure no fatal failure there. */ -TEST_F(InputClassifierHidlTest_1_0, ResetHal) { +TEST_P(InputClassifierHidlTest_1_0, ResetHal) { EXPECT_TRUE(classifier->reset().isOk()); } /** * Classify an event without any video frames. */ -TEST_F(InputClassifierHidlTest_1_0, Classify_NoVideoFrame) { +TEST_P(InputClassifierHidlTest_1_0, Classify_NoVideoFrame) { // Create a MotionEvent that does not have any video data MotionEvent event = getSimpleMotionEvent(); @@ -137,7 +122,7 @@ TEST_F(InputClassifierHidlTest_1_0, Classify_NoVideoFrame) { /** * Classify an event with one video frame. Should be the most common scenario. */ -TEST_F(InputClassifierHidlTest_1_0, Classify_OneVideoFrame) { +TEST_P(InputClassifierHidlTest_1_0, Classify_OneVideoFrame) { MotionEvent event = getSimpleMotionEvent(); VideoFrame frame; frame.data = {1, 2, 3, 4}; @@ -163,7 +148,7 @@ TEST_F(InputClassifierHidlTest_1_0, Classify_OneVideoFrame) { * monotonically increasing timestamps. Still, we provide consistent timestamps here since that * is the most realistic mode of operation. */ -TEST_F(InputClassifierHidlTest_1_0, Classify_TwoVideoFrames) { +TEST_P(InputClassifierHidlTest_1_0, Classify_TwoVideoFrames) { MotionEvent event = getSimpleMotionEvent(); VideoFrame frame1; frame1.data = {1, 2, 3, 4}; @@ -183,11 +168,7 @@ TEST_F(InputClassifierHidlTest_1_0, Classify_TwoVideoFrames) { classifier->reset(); } -int main(int argc, char** argv) { - ::testing::AddGlobalTestEnvironment(InputClassifierHidlEnvironment::Instance()); - ::testing::InitGoogleTest(&argc, argv); - InputClassifierHidlEnvironment::Instance()->init(&argc, argv); - int status = RUN_ALL_TESTS(); - LOG(INFO) << "Test result = " << status; - return status; -} +INSTANTIATE_TEST_SUITE_P( + PerInstance, InputClassifierHidlTest_1_0, + testing::ValuesIn(android::hardware::getAllHalInstanceNames(IInputClassifier::descriptor)), + android::hardware::PrintInstanceNameToString); -- GitLab From 69d1d66bb477af9dacb7439165c618b883535c31 Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Wed, 25 Mar 2020 17:14:12 -0700 Subject: [PATCH 033/790] Revert "Revert "Define biometrics.face@1.1 with remote enrollment"" This reverts commit 9a471eb8be92b59ba2d97d9c7310476e38aa1d31. Change-Id: I6130e5c3d39d81a077641f6cc225da9f061de1c5 --- biometrics/face/1.1/Android.bp | 17 +++++ biometrics/face/1.1/IBiometricsFace.hal | 82 +++++++++++++++++++++++++ 2 files changed, 99 insertions(+) create mode 100644 biometrics/face/1.1/Android.bp create mode 100644 biometrics/face/1.1/IBiometricsFace.hal diff --git a/biometrics/face/1.1/Android.bp b/biometrics/face/1.1/Android.bp new file mode 100644 index 0000000000..2206597dec --- /dev/null +++ b/biometrics/face/1.1/Android.bp @@ -0,0 +1,17 @@ +// This file is autogenerated by hidl-gen -Landroidbp. + +hidl_interface { + name: "android.hardware.biometrics.face@1.1", + root: "android.hardware", + vndk: { + enabled: true, + }, + srcs: [ + "IBiometricsFace.hal", + ], + interfaces: [ + "android.hardware.biometrics.face@1.0", + "android.hidl.base@1.0", + ], + gen_java: true, +} diff --git a/biometrics/face/1.1/IBiometricsFace.hal b/biometrics/face/1.1/IBiometricsFace.hal new file mode 100644 index 0000000000..975001f30b --- /dev/null +++ b/biometrics/face/1.1/IBiometricsFace.hal @@ -0,0 +1,82 @@ +/* + * 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. + */ + +package android.hardware.biometrics.face@1.1; +import @1.0::IBiometricsFace; +import @1.0::Status; +import @1.0::Feature; + +/** + * The HAL interface for biometric face authentication. + */ +interface IBiometricsFace extends @1.0::IBiometricsFace { + /** + * Enrolls a user's face for a remote client, for example Android Auto. + * + * The HAL implementation is responsible for creating a secure communication + * channel and receiving the enrollment images from a mobile device with + * face authentication hardware. + * + * Note that the Hardware Authentication Token must be valid for the + * duration of enrollment and thus should be explicitly invalidated by a + * call to revokeChallenge() when enrollment is complete, to reduce the + * window of opportunity to re-use the challenge and HAT. For example, + * Settings calls generateChallenge() once to allow the user to enroll one + * or more faces or toggle secure settings without having to re-enter the + * PIN/pattern/password. Once the user completes the operation, Settings + * invokes revokeChallenge() to close the transaction. If the HAT is expired, + * the implementation must invoke onError with UNABLE_TO_PROCESS. + * + * Requirements for using this API: + * - Mobile devices MUST NOT delegate enrollment to another device by calling + * this API. This feature is intended only to allow enrollment on devices + * where it is impossible to enroll locally on the device. + * - The path MUST be protected by a secret key with rollback protection. + * - Synchronizing between devices MUST be accomplished by having both + * devices agree on a secret PIN entered by the user (similar to BT + * pairing procedure) and use a salted version of that PIN plus other secret + * to encrypt traffic. + * - All communication to/from the remote device MUST be encrypted and signed + * to prevent image injection and other man-in-the-middle type attacks. + * - generateChallenge() and revokeChallenge() MUST be implemented on both + * remote and local host (e.g. hash the result of the remote host with a + * local secret before responding to the API call) and any transmission of + * the challenge between hosts MUST be signed to prevent man-in-the-middle + * attacks. + * - In the event of a lost connection, the result of the last + * generateChallenge() MUST be invalidated and the process started over. + * - Both the remote and local host MUST honor the timeout and invalidate the + * challenge. + * + * This method triggers the IBiometricsFaceClientCallback#onEnrollResult() + * method. + * + * @param hat A valid Hardware Authentication Token, generated as a result + * of a generateChallenge() challenge being wrapped by the gatekeeper + * after a successful strong authentication request. + * @param timeoutSec A timeout in seconds, after which this enroll + * attempt is cancelled. Note that the framework can continue + * enrollment by calling this again with a valid HAT. This timeout is + * expected to be used to limit power usage if the device becomes idle + * during enrollment. The implementation is expected to send + * ERROR_TIMEOUT if this happens. + * @param disabledFeatures A list of features to be disabled during + * enrollment. Note that all features are enabled by default. + * @return status The status of this method call. + */ + enrollRemotely(vec hat, uint32_t timeoutSec, + vec disabledFeatures) generates (Status status); +}; -- GitLab From 605521ca5713d028f0746cb4e90127e744322115 Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Fri, 27 Mar 2020 17:27:00 -0700 Subject: [PATCH 034/790] Revert "Revert "Add VTS tests for biometrics.face@1.1"" This reverts commit 32142e7c419589f0fa3634425a61e122e0bc99f3. Change-Id: I017ff957e58f99b4a227cfbcc7b3a8ae881ad7e0 --- biometrics/face/1.1/vts/functional/Android.bp | 29 ++++ .../VtsHalBiometricsFaceV1_1TargetTest.cpp | 163 ++++++++++++++++++ 2 files changed, 192 insertions(+) create mode 100644 biometrics/face/1.1/vts/functional/Android.bp create mode 100644 biometrics/face/1.1/vts/functional/VtsHalBiometricsFaceV1_1TargetTest.cpp diff --git a/biometrics/face/1.1/vts/functional/Android.bp b/biometrics/face/1.1/vts/functional/Android.bp new file mode 100644 index 0000000000..ccbb3994e1 --- /dev/null +++ b/biometrics/face/1.1/vts/functional/Android.bp @@ -0,0 +1,29 @@ +/* + * 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. + */ + +cc_test { + name: "VtsHalBiometricsFaceV1_1TargetTest", + defaults: ["VtsHalTargetTestDefaults"], + srcs: ["VtsHalBiometricsFaceV1_1TargetTest.cpp"], + static_libs: [ + "android.hardware.biometrics.face@1.0", + "android.hardware.biometrics.face@1.1", + ], + test_suites: [ + "general-tests", + "vts-core", + ], +} diff --git a/biometrics/face/1.1/vts/functional/VtsHalBiometricsFaceV1_1TargetTest.cpp b/biometrics/face/1.1/vts/functional/VtsHalBiometricsFaceV1_1TargetTest.cpp new file mode 100644 index 0000000000..c2431c6727 --- /dev/null +++ b/biometrics/face/1.1/vts/functional/VtsHalBiometricsFaceV1_1TargetTest.cpp @@ -0,0 +1,163 @@ +/* + * 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. + */ + +#define LOG_TAG "biometrics_face_hidl_hal_test" + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +using android::sp; +using android::hardware::hidl_vec; +using android::hardware::Return; +using android::hardware::Void; +using android::hardware::biometrics::face::V1_0::FaceAcquiredInfo; +using android::hardware::biometrics::face::V1_0::FaceError; +using android::hardware::biometrics::face::V1_0::IBiometricsFaceClientCallback; +using android::hardware::biometrics::face::V1_0::OptionalUint64; +using android::hardware::biometrics::face::V1_0::Status; +using android::hardware::biometrics::face::V1_1::IBiometricsFace; + +namespace { + +// Arbitrary, nonexistent userId +constexpr uint32_t kUserId = 9; +constexpr uint32_t kTimeoutSec = 3; +constexpr auto kTimeout = std::chrono::seconds(kTimeoutSec); +constexpr char kFacedataDir[] = "/data/vendor_de/0/facedata"; +constexpr char kCallbackNameOnError[] = "onError"; + +// Callback arguments that need to be captured for the tests. +struct FaceCallbackArgs { + // The error passed to the last onError() callback. + FaceError error; + + // The userId passed to the last callback. + int32_t userId; +}; + +// Test callback class for the BiometricsFace HAL. +// The HAL will call these callback methods to notify about completed operations +// or encountered errors. +class FaceCallback : public ::testing::VtsHalHidlTargetCallbackBase, + public IBiometricsFaceClientCallback { + public: + Return onEnrollResult(uint64_t, uint32_t, int32_t, uint32_t) override { return Void(); } + + Return onAuthenticated(uint64_t, uint32_t, int32_t, const hidl_vec&) override { + return Void(); + } + + Return onAcquired(uint64_t, int32_t, FaceAcquiredInfo, int32_t) override { + return Void(); + } + + Return onError(uint64_t, int32_t userId, FaceError error, int32_t) override { + FaceCallbackArgs args = {}; + args.error = error; + args.userId = userId; + NotifyFromCallback(kCallbackNameOnError, args); + return Void(); + } + + Return onRemoved(uint64_t, const hidl_vec&, int32_t) override { return Void(); } + + Return onEnumerate(uint64_t, const hidl_vec&, int32_t) override { + return Void(); + } + + Return onLockoutChanged(uint64_t) override { return Void(); } +}; + +// Test class for the BiometricsFace HAL. +class FaceHidlTest : public ::testing::TestWithParam { + public: + void SetUp() override { + mService = IBiometricsFace::getService(GetParam()); + ASSERT_NE(mService, nullptr); + mCallback = new FaceCallback(); + mCallback->SetWaitTimeoutDefault(kTimeout); + Return ret1 = mService->setCallback(mCallback, [](const OptionalUint64& res) { + ASSERT_EQ(Status::OK, res.status); + // Makes sure the "deviceId" represented by "res.value" is not 0. + // 0 would mean the HIDL is not available. + ASSERT_NE(0UL, res.value); + }); + ASSERT_TRUE(ret1.isOk()); + Return ret2 = mService->setActiveUser(kUserId, kFacedataDir); + ASSERT_EQ(Status::OK, static_cast(ret2)); + } + + void TearDown() override {} + + sp mService; + sp mCallback; +}; + +// enroll with an invalid (all zeroes) HAT should fail. +TEST_P(FaceHidlTest, EnrollRemotelyZeroHatTest) { + // Filling HAT with zeros + hidl_vec token(69); + for (size_t i = 0; i < 69; i++) { + token[i] = 0; + } + + Return ret = mService->enrollRemotely(token, kTimeoutSec, {}); + ASSERT_EQ(Status::OK, static_cast(ret)); + + // onError should be called with a meaningful (nonzero) error. + auto res = mCallback->WaitForCallback(kCallbackNameOnError); + EXPECT_TRUE(res.no_timeout); + EXPECT_EQ(kUserId, res.args->userId); + EXPECT_EQ(FaceError::UNABLE_TO_PROCESS, res.args->error); +} + +// enroll with an invalid HAT should fail. +TEST_P(FaceHidlTest, EnrollRemotelyGarbageHatTest) { + // Filling HAT with pseudorandom invalid data. + // Using default seed to make the test reproducible. + std::mt19937 gen(std::mt19937::default_seed); + std::uniform_int_distribution dist; + hidl_vec token(69); + for (size_t i = 0; i < 69; ++i) { + token[i] = dist(gen); + } + + Return ret = mService->enrollRemotely(token, kTimeoutSec, {}); + ASSERT_EQ(Status::OK, static_cast(ret)); + + // onError should be called with a meaningful (nonzero) error. + auto res = mCallback->WaitForCallback(kCallbackNameOnError); + EXPECT_TRUE(res.no_timeout); + EXPECT_EQ(kUserId, res.args->userId); + EXPECT_EQ(FaceError::UNABLE_TO_PROCESS, res.args->error); +} + +} // anonymous namespace + +INSTANTIATE_TEST_SUITE_P( + PerInstance, FaceHidlTest, + testing::ValuesIn(android::hardware::getAllHalInstanceNames(IBiometricsFace::descriptor)), + android::hardware::PrintInstanceNameToString); -- GitLab From 94992158c9242a74dd8bdea17468db2d451711ca Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Fri, 27 Mar 2020 17:27:04 -0700 Subject: [PATCH 035/790] Revert "Move default implementation from 1.1 to 1.0" This reverts commit 1c0e3b7e57e2e5b1c3742a5144182ac6efc54b13. Change-Id: Ia11585a0206c3bdf99f32f2c0a3364011d05647a --- biometrics/face/{1.0 => 1.1}/default/Android.bp | 5 +++-- biometrics/face/{1.0 => 1.1}/default/BiometricsFace.cpp | 8 ++++++++ biometrics/face/{1.0 => 1.1}/default/BiometricsFace.h | 8 ++++++-- .../android.hardware.biometrics.face@1.1-service.rc} | 2 +- .../face/{1.0 => 1.1}/default/manifest_face_default.xml | 2 +- biometrics/face/{1.0 => 1.1}/default/service.cpp | 6 +++--- 6 files changed, 22 insertions(+), 9 deletions(-) rename biometrics/face/{1.0 => 1.1}/default/Android.bp (85%) rename biometrics/face/{1.0 => 1.1}/default/BiometricsFace.cpp (89%) rename biometrics/face/{1.0 => 1.1}/default/BiometricsFace.h (87%) rename biometrics/face/{1.0/default/android.hardware.biometrics.face@1.0-service.rc => 1.1/default/android.hardware.biometrics.face@1.1-service.rc} (75%) rename biometrics/face/{1.0 => 1.1}/default/manifest_face_default.xml (90%) rename biometrics/face/{1.0 => 1.1}/default/service.cpp (88%) diff --git a/biometrics/face/1.0/default/Android.bp b/biometrics/face/1.1/default/Android.bp similarity index 85% rename from biometrics/face/1.0/default/Android.bp rename to biometrics/face/1.1/default/Android.bp index d6ff087ee6..360071f3dd 100644 --- a/biometrics/face/1.0/default/Android.bp +++ b/biometrics/face/1.1/default/Android.bp @@ -15,10 +15,10 @@ */ cc_binary { - name: "android.hardware.biometrics.face@1.0-service.example", + name: "android.hardware.biometrics.face@1.1-service.example", defaults: ["hidl_defaults"], vendor: true, - init_rc: ["android.hardware.biometrics.face@1.0-service.rc"], + init_rc: ["android.hardware.biometrics.face@1.1-service.rc"], vintf_fragments: ["manifest_face_default.xml"], relative_install_path: "hw", proprietary: true, @@ -31,5 +31,6 @@ cc_binary { "libutils", "liblog", "android.hardware.biometrics.face@1.0", + "android.hardware.biometrics.face@1.1", ], } diff --git a/biometrics/face/1.0/default/BiometricsFace.cpp b/biometrics/face/1.1/default/BiometricsFace.cpp similarity index 89% rename from biometrics/face/1.0/default/BiometricsFace.cpp rename to biometrics/face/1.1/default/BiometricsFace.cpp index 2dd64764bb..7bda57fb7f 100644 --- a/biometrics/face/1.0/default/BiometricsFace.cpp +++ b/biometrics/face/1.1/default/BiometricsFace.cpp @@ -110,4 +110,12 @@ Return BiometricsFace::resetLockout(const hidl_vec& /* hat */) return Status::OK; } +// Methods from ::android::hardware::biometrics::face::V1_1::IBiometricsFace follow. +Return BiometricsFace::enrollRemotely(const hidl_vec& /* hat */, + uint32_t /* timeoutSec */, + const hidl_vec& /* disabledFeatures */) { + mClientCallback->onError(kDeviceId, mUserId, FaceError::UNABLE_TO_PROCESS, 0 /* vendorCode */); + return Status::OK; +} + } // namespace android::hardware::biometrics::face::implementation diff --git a/biometrics/face/1.0/default/BiometricsFace.h b/biometrics/face/1.1/default/BiometricsFace.h similarity index 87% rename from biometrics/face/1.0/default/BiometricsFace.h rename to biometrics/face/1.1/default/BiometricsFace.h index 1d99ed26bc..5620b45a43 100644 --- a/biometrics/face/1.0/default/BiometricsFace.h +++ b/biometrics/face/1.1/default/BiometricsFace.h @@ -16,7 +16,7 @@ #pragma once -#include +#include #include #include #include @@ -34,7 +34,7 @@ using ::android::hardware::biometrics::face::V1_0::Feature; using ::android::hardware::biometrics::face::V1_0::IBiometricsFaceClientCallback; using ::android::hardware::biometrics::face::V1_0::Status; -class BiometricsFace : public V1_0::IBiometricsFace { +class BiometricsFace : public V1_1::IBiometricsFace { public: BiometricsFace(); @@ -71,6 +71,10 @@ class BiometricsFace : public V1_0::IBiometricsFace { Return resetLockout(const hidl_vec& hat) override; + // Methods from ::android::hardware::biometrics::face::V1_1::IBiometricsFace follow. + Return enrollRemotely(const hidl_vec& hat, uint32_t timeoutSec, + const hidl_vec& disabledFeatures) override; + private: std::mt19937 mRandom; int32_t mUserId; diff --git a/biometrics/face/1.0/default/android.hardware.biometrics.face@1.0-service.rc b/biometrics/face/1.1/default/android.hardware.biometrics.face@1.1-service.rc similarity index 75% rename from biometrics/face/1.0/default/android.hardware.biometrics.face@1.0-service.rc rename to biometrics/face/1.1/default/android.hardware.biometrics.face@1.1-service.rc index 6c7362f2bb..687e2d8c86 100644 --- a/biometrics/face/1.0/default/android.hardware.biometrics.face@1.0-service.rc +++ b/biometrics/face/1.1/default/android.hardware.biometrics.face@1.1-service.rc @@ -1,4 +1,4 @@ -service vendor.face-hal-1-0-default /vendor/bin/hw/android.hardware.biometrics.face@1.0-service.example +service vendor.face-hal-1-1-default /vendor/bin/hw/android.hardware.biometrics.face@1.1-service.example # "class hal" causes a race condition on some devices due to files created # in /data. As a workaround, postpone startup until later in boot once # /data is mounted. diff --git a/biometrics/face/1.0/default/manifest_face_default.xml b/biometrics/face/1.1/default/manifest_face_default.xml similarity index 90% rename from biometrics/face/1.0/default/manifest_face_default.xml rename to biometrics/face/1.1/default/manifest_face_default.xml index 380ae49e93..ec71d9c92b 100644 --- a/biometrics/face/1.0/default/manifest_face_default.xml +++ b/biometrics/face/1.1/default/manifest_face_default.xml @@ -2,7 +2,7 @@ android.hardware.biometrics.face hwbinder - 1.0 + 1.1 IBiometricsFace default diff --git a/biometrics/face/1.0/default/service.cpp b/biometrics/face/1.1/default/service.cpp similarity index 88% rename from biometrics/face/1.0/default/service.cpp rename to biometrics/face/1.1/default/service.cpp index 9818c959d6..344bdb99b4 100644 --- a/biometrics/face/1.0/default/service.cpp +++ b/biometrics/face/1.1/default/service.cpp @@ -14,10 +14,10 @@ * limitations under the License. */ -#define LOG_TAG "android.hardware.biometrics.face@1.0-service" +#define LOG_TAG "android.hardware.biometrics.face@1.1-service" #include -#include +#include #include #include #include @@ -27,7 +27,7 @@ using android::sp; using android::hardware::configureRpcThreadpool; using android::hardware::joinRpcThreadpool; using android::hardware::biometrics::face::implementation::BiometricsFace; -using android::hardware::biometrics::face::V1_0::IBiometricsFace; +using android::hardware::biometrics::face::V1_1::IBiometricsFace; int main() { ALOGI("BiometricsFace HAL is being started."); -- GitLab From 35e8d370fe7b4ecde43bdc919aa6361e81be67f8 Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Wed, 25 Mar 2020 17:17:56 -0700 Subject: [PATCH 036/790] Revert "Revert "Add enroll_1_1 with preview window id"" This reverts commit 921df7abd29ad086a684b2820a0fa7c21bf19280. Change-Id: I13a54a8288e122f7c02f2b23d6aaf21dfd782282 --- biometrics/face/1.1/IBiometricsFace.hal | 39 ++++++++++++++++- .../face/1.1/default/BiometricsFace.cpp | 8 ++++ biometrics/face/1.1/default/BiometricsFace.h | 4 ++ .../VtsHalBiometricsFaceV1_1TargetTest.cpp | 42 +++++++++++++++++++ 4 files changed, 91 insertions(+), 2 deletions(-) diff --git a/biometrics/face/1.1/IBiometricsFace.hal b/biometrics/face/1.1/IBiometricsFace.hal index 975001f30b..84e7443c9c 100644 --- a/biometrics/face/1.1/IBiometricsFace.hal +++ b/biometrics/face/1.1/IBiometricsFace.hal @@ -15,6 +15,7 @@ */ package android.hardware.biometrics.face@1.1; + import @1.0::IBiometricsFace; import @1.0::Status; import @1.0::Feature; @@ -77,6 +78,40 @@ interface IBiometricsFace extends @1.0::IBiometricsFace { * enrollment. Note that all features are enabled by default. * @return status The status of this method call. */ - enrollRemotely(vec hat, uint32_t timeoutSec, - vec disabledFeatures) generates (Status status); + enrollRemotely(vec hat, uint32_t timeoutSec, vec disabledFeatures) + generates (Status status); + + /** + * Enrolls a user's face. + * + * Note that the Hardware Authentication Token must be valid for the + * duration of enrollment and thus should be explicitly invalidated by a + * call to revokeChallenge() when enrollment is complete, to reduce the + * window of opportunity to re-use the challenge and HAT. For example, + * Settings calls generateChallenge() once to allow the user to enroll one + * or more faces or toggle secure settings without having to re-enter the + * PIN/pattern/password. Once the user completes the operation, Settings + * invokes revokeChallenge() to close the transaction. If the HAT is expired, + * the implementation must invoke onError with UNABLE_TO_PROCESS. + * + * This method triggers the IBiometricsFaceClientCallback#onEnrollResult() + * method. + * + * @param hat A valid Hardware Authentication Token, generated as a result + * of a generateChallenge() challenge being wrapped by the gatekeeper + * after a successful strong authentication request. + * @param timeoutSec A timeout in seconds, after which this enroll + * attempt is cancelled. Note that the framework can continue + * enrollment by calling this again with a valid HAT. This timeout is + * expected to be used to limit power usage if the device becomes idle + * during enrollment. The implementation is expected to send + * ERROR_TIMEOUT if this happens. + * @param disabledFeatures A list of features to be disabled during + * enrollment. Note that all features are enabled by default. + * @param windowId optional ID of a camera preview window for a + * single-camera device. Must be null if not used. + * @return status The status of this method call. + */ + enroll_1_1(vec hat, uint32_t timeoutSec, vec disabledFeatures, + handle windowId) generates (Status status); }; diff --git a/biometrics/face/1.1/default/BiometricsFace.cpp b/biometrics/face/1.1/default/BiometricsFace.cpp index 7bda57fb7f..2143880514 100644 --- a/biometrics/face/1.1/default/BiometricsFace.cpp +++ b/biometrics/face/1.1/default/BiometricsFace.cpp @@ -111,6 +111,14 @@ Return BiometricsFace::resetLockout(const hidl_vec& /* hat */) } // Methods from ::android::hardware::biometrics::face::V1_1::IBiometricsFace follow. +Return BiometricsFace::enroll_1_1(const hidl_vec& /* hat */, + uint32_t /* timeoutSec */, + const hidl_vec& /* disabledFeatures */, + const hidl_handle& /* windowId */) { + mClientCallback->onError(kDeviceId, mUserId, FaceError::UNABLE_TO_PROCESS, 0 /* vendorCode */); + return Status::OK; +} + Return BiometricsFace::enrollRemotely(const hidl_vec& /* hat */, uint32_t /* timeoutSec */, const hidl_vec& /* disabledFeatures */) { diff --git a/biometrics/face/1.1/default/BiometricsFace.h b/biometrics/face/1.1/default/BiometricsFace.h index 5620b45a43..5ce5771eae 100644 --- a/biometrics/face/1.1/default/BiometricsFace.h +++ b/biometrics/face/1.1/default/BiometricsFace.h @@ -72,6 +72,10 @@ class BiometricsFace : public V1_1::IBiometricsFace { Return resetLockout(const hidl_vec& hat) override; // Methods from ::android::hardware::biometrics::face::V1_1::IBiometricsFace follow. + Return enroll_1_1(const hidl_vec& hat, uint32_t timeoutSec, + const hidl_vec& disabledFeatures, + const hidl_handle& windowId) override; + Return enrollRemotely(const hidl_vec& hat, uint32_t timeoutSec, const hidl_vec& disabledFeatures) override; diff --git a/biometrics/face/1.1/vts/functional/VtsHalBiometricsFaceV1_1TargetTest.cpp b/biometrics/face/1.1/vts/functional/VtsHalBiometricsFaceV1_1TargetTest.cpp index c2431c6727..a105d8f8fd 100644 --- a/biometrics/face/1.1/vts/functional/VtsHalBiometricsFaceV1_1TargetTest.cpp +++ b/biometrics/face/1.1/vts/functional/VtsHalBiometricsFaceV1_1TargetTest.cpp @@ -30,6 +30,7 @@ #include using android::sp; +using android::hardware::hidl_handle; using android::hardware::hidl_vec; using android::hardware::Return; using android::hardware::Void; @@ -116,6 +117,47 @@ class FaceHidlTest : public ::testing::TestWithParam { sp mCallback; }; +// enroll with an invalid (all zeroes) HAT should fail. +TEST_P(FaceHidlTest, Enroll1_1ZeroHatTest) { + // Filling HAT with zeros + hidl_vec token(69); + for (size_t i = 0; i < 69; i++) { + token[i] = 0; + } + + hidl_handle windowId = nullptr; + Return ret = mService->enroll_1_1(token, kTimeoutSec, {}, windowId); + ASSERT_EQ(Status::OK, static_cast(ret)); + + // onError should be called with a meaningful (nonzero) error. + auto res = mCallback->WaitForCallback(kCallbackNameOnError); + EXPECT_TRUE(res.no_timeout); + EXPECT_EQ(kUserId, res.args->userId); + EXPECT_EQ(FaceError::UNABLE_TO_PROCESS, res.args->error); +} + +// enroll with an invalid HAT should fail. +TEST_P(FaceHidlTest, Enroll1_1GarbageHatTest) { + // Filling HAT with pseudorandom invalid data. + // Using default seed to make the test reproducible. + std::mt19937 gen(std::mt19937::default_seed); + std::uniform_int_distribution dist; + hidl_vec token(69); + for (size_t i = 0; i < 69; ++i) { + token[i] = dist(gen); + } + + hidl_handle windowId = nullptr; + Return ret = mService->enroll_1_1(token, kTimeoutSec, {}, windowId); + ASSERT_EQ(Status::OK, static_cast(ret)); + + // onError should be called with a meaningful (nonzero) error. + auto res = mCallback->WaitForCallback(kCallbackNameOnError); + EXPECT_TRUE(res.no_timeout); + EXPECT_EQ(kUserId, res.args->userId); + EXPECT_EQ(FaceError::UNABLE_TO_PROCESS, res.args->error); +} + // enroll with an invalid (all zeroes) HAT should fail. TEST_P(FaceHidlTest, EnrollRemotelyZeroHatTest) { // Filling HAT with zeros -- GitLab From 25fbdab041059bce5403ca8329c49d4646057269 Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Tue, 31 Mar 2020 11:25:45 -0700 Subject: [PATCH 037/790] Add biometrics.face@1.1 to current.txt Bug: 150479890 Bug: 145027036 Test: atest vts_treble_vintf_vendor_test Change-Id: I0e8bcc4184307d815fa03e600ccdb62324a85def --- current.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/current.txt b/current.txt index e3b2f566a9..e789d2d4e4 100644 --- a/current.txt +++ b/current.txt @@ -764,4 +764,6 @@ a64467bae843569f0d465c5be7f0c7a5b987985b55a3ef4794dd5afc68538650 android.hardwar # ABI preserving changes to HALs during Android S # HALs released in Android S +7e8e1c3d0173c5d503dd01cecff8e3864478557ca6b9e8cc2291598b1a4aea62 android.hardware.biometrics.face@1.1::IBiometricsFace + # NOTE: new HALs are recommended to be in AIDL -- GitLab From 3a8a650c617fb8bae8e111a49e873af87e196938 Mon Sep 17 00:00:00 2001 From: Dan Shi Date: Thu, 26 Mar 2020 00:06:39 -0700 Subject: [PATCH 038/790] Rename vts-core to vts Bug: 151896491 Test: local build Exempt-From-Owner-Approval: This CL update suite name vts-core to vts as the suite name is updated. This CL won't change test logic or behavior. Change-Id: I562b4dc50765e953800a814a8fd84a01c1b9352b --- atrace/1.0/vts/functional/Android.bp | 2 +- audio/core/all-versions/vts/functional/Android.bp | 10 +++++----- audio/effect/all-versions/vts/functional/Android.bp | 10 +++++----- audio/policy/1.0/vts/functional/Android.bp | 4 ++-- authsecret/1.0/vts/functional/Android.bp | 2 +- automotive/audiocontrol/2.0/vts/functional/Android.bp | 2 +- automotive/evs/1.0/vts/functional/Android.bp | 2 +- automotive/evs/1.1/vts/functional/Android.bp | 2 +- .../occupant_awareness/aidl/vts/functional/Android.bp | 2 +- automotive/sv/1.0/vts/functional/Android.bp | 2 +- biometrics/face/1.0/vts/functional/Android.bp | 2 +- biometrics/face/1.1/vts/functional/Android.bp | 2 +- biometrics/fingerprint/2.1/vts/functional/Android.bp | 2 +- biometrics/fingerprint/2.2/vts/functional/Android.bp | 2 +- bluetooth/1.0/vts/functional/Android.bp | 2 +- bluetooth/1.1/vts/functional/Android.bp | 2 +- bluetooth/a2dp/1.0/vts/functional/Android.bp | 2 +- bluetooth/audio/2.0/vts/functional/Android.bp | 2 +- boot/1.0/vts/functional/Android.bp | 2 +- broadcastradio/2.0/vts/functional/Android.bp | 2 +- camera/provider/2.4/vts/functional/Android.bp | 2 +- cas/1.0/vts/functional/Android.bp | 2 +- cas/1.1/vts/functional/Android.bp | 2 +- cas/1.2/vts/functional/Android.bp | 2 +- configstore/1.0/vts/functional/Android.bp | 2 +- confirmationui/1.0/vts/functional/Android.bp | 2 +- contexthub/1.0/vts/functional/Android.bp | 2 +- contexthub/1.1/vts/functional/Android.bp | 2 +- drm/1.0/vts/functional/Android.bp | 2 +- drm/1.1/vts/functional/Android.bp | 2 +- drm/1.2/vts/functional/Android.bp | 2 +- drm/1.3/vts/functional/Android.bp | 2 +- dumpstate/1.0/vts/functional/Android.bp | 2 +- dumpstate/1.1/vts/functional/Android.bp | 2 +- gatekeeper/1.0/vts/functional/Android.bp | 2 +- gnss/1.0/vts/functional/Android.bp | 2 +- gnss/1.1/vts/functional/Android.bp | 2 +- gnss/2.0/vts/functional/Android.bp | 2 +- gnss/2.1/vts/functional/Android.bp | 2 +- graphics/composer/2.1/vts/functional/Android.bp | 2 +- graphics/composer/2.2/vts/functional/Android.bp | 2 +- graphics/composer/2.3/vts/functional/Android.bp | 2 +- graphics/composer/2.4/vts/functional/Android.bp | 2 +- graphics/mapper/2.0/vts/functional/Android.bp | 2 +- graphics/mapper/2.1/vts/functional/Android.bp | 2 +- graphics/mapper/3.0/vts/functional/Android.bp | 2 +- graphics/mapper/4.0/vts/functional/Android.bp | 2 +- health/1.0/vts/functional/Android.bp | 2 +- health/2.0/vts/functional/Android.bp | 2 +- health/2.1/vts/functional/Android.bp | 2 +- health/storage/1.0/vts/functional/Android.bp | 2 +- identity/aidl/vts/Android.bp | 2 +- input/classifier/1.0/vts/functional/Android.bp | 2 +- ir/1.0/vts/functional/Android.bp | 2 +- keymaster/3.0/vts/functional/Android.bp | 2 +- keymaster/4.0/vts/functional/Android.bp | 2 +- keymaster/4.1/vts/functional/Android.bp | 2 +- light/2.0/vts/functional/Android.bp | 2 +- light/aidl/vts/functional/Android.bp | 2 +- media/omx/1.0/vts/functional/audio/Android.bp | 4 ++-- media/omx/1.0/vts/functional/component/Android.bp | 2 +- media/omx/1.0/vts/functional/master/Android.bp | 2 +- media/omx/1.0/vts/functional/video/Android.bp | 4 ++-- memtrack/1.0/vts/functional/Android.bp | 2 +- neuralnetworks/1.0/vts/functional/Android.bp | 2 +- neuralnetworks/1.1/vts/functional/Android.bp | 2 +- neuralnetworks/1.2/vts/functional/Android.bp | 2 +- nfc/1.0/vts/functional/Android.bp | 2 +- nfc/1.1/vts/functional/Android.bp | 2 +- nfc/1.2/vts/functional/Android.bp | 2 +- oemlock/1.0/vts/functional/Android.bp | 2 +- power/1.0/vts/functional/Android.bp | 2 +- power/1.1/vts/functional/Android.bp | 2 +- power/1.2/vts/functional/Android.bp | 2 +- power/1.3/vts/functional/Android.bp | 2 +- power/aidl/vts/Android.bp | 2 +- power/stats/1.0/vts/functional/Android.bp | 2 +- radio/1.0/vts/functional/Android.bp | 4 ++-- radio/1.1/vts/functional/Android.bp | 2 +- radio/1.2/vts/functional/Android.bp | 2 +- radio/1.3/vts/functional/Android.bp | 2 +- radio/1.4/vts/functional/Android.bp | 2 +- radio/1.5/vts/functional/Android.bp | 2 +- radio/config/1.0/vts/functional/Android.bp | 2 +- radio/config/1.1/vts/functional/Android.bp | 2 +- radio/config/1.2/vts/functional/Android.bp | 2 +- rebootescrow/aidl/vts/functional/Android.bp | 2 +- renderscript/1.0/vts/functional/Android.bp | 2 +- secure_element/1.0/vts/functional/Android.bp | 2 +- secure_element/1.1/vts/functional/Android.bp | 2 +- secure_element/1.2/vts/functional/Android.bp | 2 +- sensors/1.0/vts/functional/Android.bp | 2 +- sensors/2.0/vts/functional/Android.bp | 2 +- sensors/2.1/vts/functional/Android.bp | 2 +- soundtrigger/2.0/vts/functional/Android.bp | 2 +- soundtrigger/2.1/vts/functional/Android.bp | 2 +- soundtrigger/2.2/vts/functional/Android.bp | 2 +- soundtrigger/2.3/vts/functional/Android.bp | 2 +- tetheroffload/config/1.0/vts/functional/Android.bp | 2 +- tetheroffload/control/1.0/vts/functional/Android.bp | 2 +- thermal/1.0/vts/functional/Android.bp | 2 +- thermal/1.1/vts/functional/Android.bp | 2 +- thermal/2.0/vts/functional/Android.bp | 2 +- tv/input/1.0/vts/functional/Android.bp | 2 +- tv/tuner/1.0/vts/functional/Android.bp | 2 +- usb/1.0/vts/functional/Android.bp | 2 +- usb/1.1/vts/functional/Android.bp | 2 +- vibrator/1.0/vts/functional/Android.bp | 2 +- vibrator/1.1/vts/functional/Android.bp | 2 +- vibrator/1.2/vts/functional/Android.bp | 2 +- vibrator/1.3/vts/functional/Android.bp | 2 +- vibrator/aidl/vts/Android.bp | 2 +- vr/1.0/vts/functional/Android.bp | 2 +- weaver/1.0/vts/functional/Android.bp | 2 +- wifi/1.0/vts/functional/Android.bp | 6 +++--- wifi/1.1/vts/functional/Android.bp | 2 +- wifi/1.2/vts/functional/Android.bp | 4 ++-- wifi/1.3/vts/functional/Android.bp | 2 +- wifi/1.4/vts/functional/Android.bp | 2 +- wifi/hostapd/1.0/vts/functional/Android.bp | 2 +- wifi/hostapd/1.1/vts/functional/Android.bp | 2 +- wifi/hostapd/1.2/vts/functional/Android.bp | 2 +- wifi/offload/1.0/vts/functional/Android.bp | 2 +- wifi/supplicant/1.0/vts/functional/Android.bp | 4 ++-- wifi/supplicant/1.1/vts/functional/Android.bp | 2 +- wifi/supplicant/1.2/vts/functional/Android.bp | 4 ++-- wifi/supplicant/1.3/vts/functional/Android.bp | 2 +- 127 files changed, 144 insertions(+), 144 deletions(-) diff --git a/atrace/1.0/vts/functional/Android.bp b/atrace/1.0/vts/functional/Android.bp index ae24968aba..07d3f7fedf 100644 --- a/atrace/1.0/vts/functional/Android.bp +++ b/atrace/1.0/vts/functional/Android.bp @@ -19,5 +19,5 @@ cc_test { defaults: ["VtsHalTargetTestDefaults"], srcs: ["VtsHalAtraceV1_0TargetTest.cpp"], static_libs: ["android.hardware.atrace@1.0"], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/audio/core/all-versions/vts/functional/Android.bp b/audio/core/all-versions/vts/functional/Android.bp index db52e6095f..2d5e8a5c92 100644 --- a/audio/core/all-versions/vts/functional/Android.bp +++ b/audio/core/all-versions/vts/functional/Android.bp @@ -33,7 +33,7 @@ cc_defaults { ], test_suites: [ "general-tests", - "vts-core", + "vts", ], } @@ -55,7 +55,7 @@ cc_test { data: [ ":audio_policy_configuration_V2_0", ], - // Use test_config for vts-core suite. + // Use test_config for vts suite. // TODO(b/146104851): Add auto-gen rules and remove it. test_config: "VtsHalAudioV2_0TargetTest.xml", } @@ -78,7 +78,7 @@ cc_test { data: [ ":audio_policy_configuration_V4_0", ], - // Use test_config for vts-core suite. + // Use test_config for vts suite. // TODO(b/146104851): Add auto-gen rules and remove it. test_config: "VtsHalAudioV4_0TargetTest.xml", } @@ -101,7 +101,7 @@ cc_test { data: [ ":audio_policy_configuration_V5_0", ], - // Use test_config for vts-core suite. + // Use test_config for vts suite. // TODO(b/146104851): Add auto-gen rules and remove it. test_config: "VtsHalAudioV5_0TargetTest.xml", } @@ -124,7 +124,7 @@ cc_test { data: [ ":audio_policy_configuration_V6_0", ], - // Use test_config for vts-core suite. + // Use test_config for vts suite. // TODO(b/146104851): Add auto-gen rules and remove it. test_config: "VtsHalAudioV6_0TargetTest.xml", } diff --git a/audio/effect/all-versions/vts/functional/Android.bp b/audio/effect/all-versions/vts/functional/Android.bp index 4ab572e6ed..309aa9d27f 100644 --- a/audio/effect/all-versions/vts/functional/Android.bp +++ b/audio/effect/all-versions/vts/functional/Android.bp @@ -31,13 +31,13 @@ cc_defaults { header_libs: [ "android.hardware.audio.common.util@all-versions", ], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } cc_test { name: "VtsHalAudioEffectV2_0TargetTest", defaults: ["VtsHalAudioEffectTargetTest_default"], - // Use test_config for vts-core suite. + // Use test_config for vts suite. // TODO(b/146104851): Add auto-gen rules and remove it. test_config: "VtsHalAudioEffectV2_0TargetTest.xml", static_libs: [ @@ -57,7 +57,7 @@ cc_test { cc_test { name: "VtsHalAudioEffectV4_0TargetTest", defaults: ["VtsHalAudioEffectTargetTest_default"], - // Use test_config for vts-core suite. + // Use test_config for vts suite. // TODO(b/146104851): Add auto-gen rules and remove it. test_config: "VtsHalAudioEffectV4_0TargetTest.xml", static_libs: [ @@ -77,7 +77,7 @@ cc_test { cc_test { name: "VtsHalAudioEffectV5_0TargetTest", defaults: ["VtsHalAudioEffectTargetTest_default"], - // Use test_config for vts-core suite. + // Use test_config for vts suite. // TODO(b/146104851): Add auto-gen rules and remove it. test_config: "VtsHalAudioEffectV5_0TargetTest.xml", static_libs: [ @@ -97,7 +97,7 @@ cc_test { cc_test { name: "VtsHalAudioEffectV6_0TargetTest", defaults: ["VtsHalAudioEffectTargetTest_default"], - // Use test_config for vts-core suite. + // Use test_config for vts suite. // TODO(b/146104851): Add auto-gen rules and remove it. test_config: "VtsHalAudioEffectV6_0TargetTest.xml", static_libs: [ diff --git a/audio/policy/1.0/vts/functional/Android.bp b/audio/policy/1.0/vts/functional/Android.bp index b50e501d15..a5ddee51ef 100644 --- a/audio/policy/1.0/vts/functional/Android.bp +++ b/audio/policy/1.0/vts/functional/Android.bp @@ -24,7 +24,7 @@ cc_test { shared_libs: [ "libaudiofoundation", ], - // Use test_config for vts-core suite. + // Use test_config for vts suite. // TODO(b/146104851): Add auto-gen rules and remove it. test_config: "VtsHalAudioPolicyV1_0TargetTest.xml", cflags: [ @@ -54,6 +54,6 @@ cc_test { gtest: true, test_suites: [ "general-tests", - "vts-core", + "vts", ], } diff --git a/authsecret/1.0/vts/functional/Android.bp b/authsecret/1.0/vts/functional/Android.bp index 9ce9cda2f9..c49d37492d 100644 --- a/authsecret/1.0/vts/functional/Android.bp +++ b/authsecret/1.0/vts/functional/Android.bp @@ -21,7 +21,7 @@ cc_test { static_libs: ["android.hardware.authsecret@1.0"], test_suites: [ "general-tests", - "vts-core", + "vts", ], require_root: true, } diff --git a/automotive/audiocontrol/2.0/vts/functional/Android.bp b/automotive/audiocontrol/2.0/vts/functional/Android.bp index 520b042e37..ac20509dd5 100644 --- a/automotive/audiocontrol/2.0/vts/functional/Android.bp +++ b/automotive/audiocontrol/2.0/vts/functional/Android.bp @@ -24,6 +24,6 @@ cc_test { ], test_suites: [ "general-tests", - "vts-core", + "vts", ], } diff --git a/automotive/evs/1.0/vts/functional/Android.bp b/automotive/evs/1.0/vts/functional/Android.bp index 9f7cd3f02a..74d512293b 100644 --- a/automotive/evs/1.0/vts/functional/Android.bp +++ b/automotive/evs/1.0/vts/functional/Android.bp @@ -28,7 +28,7 @@ cc_test { "android.hardware.automotive.evs@1.0", "android.hardware.automotive.evs@common-default-lib", ], - test_suites: ["vts-core"], + test_suites: ["vts"], cflags: [ "-O0", "-g", diff --git a/automotive/evs/1.1/vts/functional/Android.bp b/automotive/evs/1.1/vts/functional/Android.bp index 086a199ca5..d61f0a8f9c 100644 --- a/automotive/evs/1.1/vts/functional/Android.bp +++ b/automotive/evs/1.1/vts/functional/Android.bp @@ -38,7 +38,7 @@ cc_test { "android.hardware.graphics.common@1.2", "android.hardware.camera.device@3.2", ], - test_suites: ["vts-core"], + test_suites: ["vts"], cflags: [ "-O0", "-g", diff --git a/automotive/occupant_awareness/aidl/vts/functional/Android.bp b/automotive/occupant_awareness/aidl/vts/functional/Android.bp index 1256b69c67..514b0afc2b 100644 --- a/automotive/occupant_awareness/aidl/vts/functional/Android.bp +++ b/automotive/occupant_awareness/aidl/vts/functional/Android.bp @@ -12,6 +12,6 @@ cc_test { "android.hardware.automotive.occupant_awareness-cpp", ], test_suites: [ - "vts-core", + "vts", ], } diff --git a/automotive/sv/1.0/vts/functional/Android.bp b/automotive/sv/1.0/vts/functional/Android.bp index 0e5d3df9a7..d5d72a6c5b 100644 --- a/automotive/sv/1.0/vts/functional/Android.bp +++ b/automotive/sv/1.0/vts/functional/Android.bp @@ -33,7 +33,7 @@ cc_test { "android.hidl.memory@1.0", "libhidlmemory", ], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], cflags: [ "-O0", "-g", diff --git a/biometrics/face/1.0/vts/functional/Android.bp b/biometrics/face/1.0/vts/functional/Android.bp index f2598a7934..ff4a6de889 100644 --- a/biometrics/face/1.0/vts/functional/Android.bp +++ b/biometrics/face/1.0/vts/functional/Android.bp @@ -19,6 +19,6 @@ cc_test { defaults: ["VtsHalTargetTestDefaults"], srcs: ["VtsHalBiometricsFaceV1_0TargetTest.cpp"], static_libs: ["android.hardware.biometrics.face@1.0"], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/biometrics/face/1.1/vts/functional/Android.bp b/biometrics/face/1.1/vts/functional/Android.bp index ccbb3994e1..aa0b1fa082 100644 --- a/biometrics/face/1.1/vts/functional/Android.bp +++ b/biometrics/face/1.1/vts/functional/Android.bp @@ -24,6 +24,6 @@ cc_test { ], test_suites: [ "general-tests", - "vts-core", + "vts", ], } diff --git a/biometrics/fingerprint/2.1/vts/functional/Android.bp b/biometrics/fingerprint/2.1/vts/functional/Android.bp index c4180322b8..7e3f3406bb 100644 --- a/biometrics/fingerprint/2.1/vts/functional/Android.bp +++ b/biometrics/fingerprint/2.1/vts/functional/Android.bp @@ -19,6 +19,6 @@ cc_test { defaults: ["VtsHalTargetTestDefaults"], srcs: ["VtsHalBiometricsFingerprintV2_1TargetTest.cpp"], static_libs: ["android.hardware.biometrics.fingerprint@2.1"], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/biometrics/fingerprint/2.2/vts/functional/Android.bp b/biometrics/fingerprint/2.2/vts/functional/Android.bp index 496570c64c..5e8e7c80be 100644 --- a/biometrics/fingerprint/2.2/vts/functional/Android.bp +++ b/biometrics/fingerprint/2.2/vts/functional/Android.bp @@ -24,6 +24,6 @@ cc_test { ], test_suites: [ "general-tests", - "vts-core", + "vts", ], } diff --git a/bluetooth/1.0/vts/functional/Android.bp b/bluetooth/1.0/vts/functional/Android.bp index cf25cc8ff9..463ed849f6 100644 --- a/bluetooth/1.0/vts/functional/Android.bp +++ b/bluetooth/1.0/vts/functional/Android.bp @@ -24,6 +24,6 @@ cc_test { ], test_suites: [ "general-tests", - "vts-core", + "vts", ], } diff --git a/bluetooth/1.1/vts/functional/Android.bp b/bluetooth/1.1/vts/functional/Android.bp index 8d6d7490e3..eb4a720f95 100644 --- a/bluetooth/1.1/vts/functional/Android.bp +++ b/bluetooth/1.1/vts/functional/Android.bp @@ -23,5 +23,5 @@ cc_test { "android.hardware.bluetooth@1.0", "libbluetooth-types", ], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/bluetooth/a2dp/1.0/vts/functional/Android.bp b/bluetooth/a2dp/1.0/vts/functional/Android.bp index 5b8410adc5..df18fcc7c5 100644 --- a/bluetooth/a2dp/1.0/vts/functional/Android.bp +++ b/bluetooth/a2dp/1.0/vts/functional/Android.bp @@ -23,5 +23,5 @@ cc_test { "android.hardware.bluetooth.a2dp@1.0", "libbluetooth-types", ], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/bluetooth/audio/2.0/vts/functional/Android.bp b/bluetooth/audio/2.0/vts/functional/Android.bp index b778b97b09..0ed5da43f2 100644 --- a/bluetooth/audio/2.0/vts/functional/Android.bp +++ b/bluetooth/audio/2.0/vts/functional/Android.bp @@ -9,5 +9,5 @@ cc_test { shared_libs: [ "libfmq", ], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/boot/1.0/vts/functional/Android.bp b/boot/1.0/vts/functional/Android.bp index 5244b958ca..92c818c56c 100644 --- a/boot/1.0/vts/functional/Android.bp +++ b/boot/1.0/vts/functional/Android.bp @@ -19,5 +19,5 @@ cc_test { defaults: ["VtsHalTargetTestDefaults"], srcs: ["VtsHalBootV1_0TargetTest.cpp"], static_libs: ["android.hardware.boot@1.0"], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/broadcastradio/2.0/vts/functional/Android.bp b/broadcastradio/2.0/vts/functional/Android.bp index 49bb66554f..be17da32df 100644 --- a/broadcastradio/2.0/vts/functional/Android.bp +++ b/broadcastradio/2.0/vts/functional/Android.bp @@ -27,6 +27,6 @@ cc_test { ], test_suites: [ "general-tests", - "vts-core", + "vts", ], } diff --git a/camera/provider/2.4/vts/functional/Android.bp b/camera/provider/2.4/vts/functional/Android.bp index 4b9d6f125b..cd66f74571 100644 --- a/camera/provider/2.4/vts/functional/Android.bp +++ b/camera/provider/2.4/vts/functional/Android.bp @@ -49,5 +49,5 @@ cc_test { "libhidlmemory", "libgralloctypes", ], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/cas/1.0/vts/functional/Android.bp b/cas/1.0/vts/functional/Android.bp index ab39c0e93b..82dc568fa6 100644 --- a/cas/1.0/vts/functional/Android.bp +++ b/cas/1.0/vts/functional/Android.bp @@ -29,6 +29,6 @@ cc_test { shared_libs: [ "libbinder", ], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/cas/1.1/vts/functional/Android.bp b/cas/1.1/vts/functional/Android.bp index 9e8eb52efe..de223c8ce2 100644 --- a/cas/1.1/vts/functional/Android.bp +++ b/cas/1.1/vts/functional/Android.bp @@ -30,6 +30,6 @@ cc_test { shared_libs: [ "libbinder", ], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/cas/1.2/vts/functional/Android.bp b/cas/1.2/vts/functional/Android.bp index 2d6517f0b0..74ea85fbf2 100644 --- a/cas/1.2/vts/functional/Android.bp +++ b/cas/1.2/vts/functional/Android.bp @@ -33,6 +33,6 @@ cc_test { ], test_suites: [ "general-tests", - "vts-core", + "vts", ], } diff --git a/configstore/1.0/vts/functional/Android.bp b/configstore/1.0/vts/functional/Android.bp index 31d4b1c9d9..4e1e045dd1 100644 --- a/configstore/1.0/vts/functional/Android.bp +++ b/configstore/1.0/vts/functional/Android.bp @@ -19,6 +19,6 @@ cc_test { defaults: ["VtsHalTargetTestDefaults"], srcs: ["VtsHalConfigstoreV1_0TargetTest.cpp"], static_libs: ["android.hardware.configstore@1.0"], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/confirmationui/1.0/vts/functional/Android.bp b/confirmationui/1.0/vts/functional/Android.bp index c8b522c119..c73ee2826c 100644 --- a/confirmationui/1.0/vts/functional/Android.bp +++ b/confirmationui/1.0/vts/functional/Android.bp @@ -27,5 +27,5 @@ cc_test { "libcn-cbor", "android.hardware.confirmationui-support-lib", ], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/contexthub/1.0/vts/functional/Android.bp b/contexthub/1.0/vts/functional/Android.bp index d51c9669c8..091f2dc201 100644 --- a/contexthub/1.0/vts/functional/Android.bp +++ b/contexthub/1.0/vts/functional/Android.bp @@ -24,6 +24,6 @@ cc_test { ], test_suites: [ "general-tests", - "vts-core", + "vts", ], } diff --git a/contexthub/1.1/vts/functional/Android.bp b/contexthub/1.1/vts/functional/Android.bp index f1625a6b6b..034c11fb0c 100644 --- a/contexthub/1.1/vts/functional/Android.bp +++ b/contexthub/1.1/vts/functional/Android.bp @@ -25,6 +25,6 @@ cc_test { ], test_suites: [ "general-tests", - "vts-core", + "vts", ], } diff --git a/drm/1.0/vts/functional/Android.bp b/drm/1.0/vts/functional/Android.bp index e4d3393272..0545c70606 100644 --- a/drm/1.0/vts/functional/Android.bp +++ b/drm/1.0/vts/functional/Android.bp @@ -100,6 +100,6 @@ cc_test { }, test_suites: [ "general-tests", - "vts-core", + "vts", ], } diff --git a/drm/1.1/vts/functional/Android.bp b/drm/1.1/vts/functional/Android.bp index c31aee0827..053a564023 100644 --- a/drm/1.1/vts/functional/Android.bp +++ b/drm/1.1/vts/functional/Android.bp @@ -81,6 +81,6 @@ cc_test { }, test_suites: [ "general-tests", - "vts-core", + "vts", ], } diff --git a/drm/1.2/vts/functional/Android.bp b/drm/1.2/vts/functional/Android.bp index 793ef801d9..271cc043d0 100644 --- a/drm/1.2/vts/functional/Android.bp +++ b/drm/1.2/vts/functional/Android.bp @@ -86,6 +86,6 @@ cc_test { }, test_suites: [ "general-tests", - "vts-core", + "vts", ], } diff --git a/drm/1.3/vts/functional/Android.bp b/drm/1.3/vts/functional/Android.bp index ac1f912c08..4ef94ec332 100644 --- a/drm/1.3/vts/functional/Android.bp +++ b/drm/1.3/vts/functional/Android.bp @@ -73,6 +73,6 @@ cc_test { ], test_suites: [ "general-tests", - "vts-core", + "vts", ], } diff --git a/dumpstate/1.0/vts/functional/Android.bp b/dumpstate/1.0/vts/functional/Android.bp index 3bac281598..451b0536fd 100644 --- a/dumpstate/1.0/vts/functional/Android.bp +++ b/dumpstate/1.0/vts/functional/Android.bp @@ -18,5 +18,5 @@ cc_test { defaults: ["VtsHalTargetTestDefaults"], srcs: ["VtsHalDumpstateV1_0TargetTest.cpp"], static_libs: ["android.hardware.dumpstate@1.0"], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/dumpstate/1.1/vts/functional/Android.bp b/dumpstate/1.1/vts/functional/Android.bp index 5267706c0b..43a3c21b7c 100644 --- a/dumpstate/1.1/vts/functional/Android.bp +++ b/dumpstate/1.1/vts/functional/Android.bp @@ -24,6 +24,6 @@ cc_test { ], test_suites: [ "general-tests", - "vts-core", + "vts", ], } diff --git a/gatekeeper/1.0/vts/functional/Android.bp b/gatekeeper/1.0/vts/functional/Android.bp index a115285392..1ca966d20f 100644 --- a/gatekeeper/1.0/vts/functional/Android.bp +++ b/gatekeeper/1.0/vts/functional/Android.bp @@ -19,5 +19,5 @@ cc_test { defaults: ["VtsHalTargetTestDefaults"], srcs: ["VtsHalGatekeeperV1_0TargetTest.cpp"], static_libs: ["android.hardware.gatekeeper@1.0"], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/gnss/1.0/vts/functional/Android.bp b/gnss/1.0/vts/functional/Android.bp index d73b32ea8b..45755e6671 100644 --- a/gnss/1.0/vts/functional/Android.bp +++ b/gnss/1.0/vts/functional/Android.bp @@ -19,5 +19,5 @@ cc_test { defaults: ["VtsHalTargetTestDefaults"], srcs: ["VtsHalGnssV1_0TargetTest.cpp"], static_libs: ["android.hardware.gnss@1.0"], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/gnss/1.1/vts/functional/Android.bp b/gnss/1.1/vts/functional/Android.bp index 369a89da39..0d540b7250 100644 --- a/gnss/1.1/vts/functional/Android.bp +++ b/gnss/1.1/vts/functional/Android.bp @@ -33,6 +33,6 @@ cc_test { ], test_suites: [ "general-tests", - "vts-core", + "vts", ], } diff --git a/gnss/2.0/vts/functional/Android.bp b/gnss/2.0/vts/functional/Android.bp index da5289d006..d67677afe4 100644 --- a/gnss/2.0/vts/functional/Android.bp +++ b/gnss/2.0/vts/functional/Android.bp @@ -31,5 +31,5 @@ cc_test { "android.hardware.gnss@2.1", "android.hardware.gnss@common-vts-lib", ], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/gnss/2.1/vts/functional/Android.bp b/gnss/2.1/vts/functional/Android.bp index f008a26f1f..b3051d4b48 100644 --- a/gnss/2.1/vts/functional/Android.bp +++ b/gnss/2.1/vts/functional/Android.bp @@ -34,6 +34,6 @@ cc_test { ], test_suites: [ "general-tests", - "vts-core", + "vts", ], } diff --git a/graphics/composer/2.1/vts/functional/Android.bp b/graphics/composer/2.1/vts/functional/Android.bp index 5f1ed63936..dafbbf9c9e 100644 --- a/graphics/composer/2.1/vts/functional/Android.bp +++ b/graphics/composer/2.1/vts/functional/Android.bp @@ -43,5 +43,5 @@ cc_test { "android.hardware.graphics.composer@2.1-command-buffer", ], disable_framework: true, - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/graphics/composer/2.2/vts/functional/Android.bp b/graphics/composer/2.2/vts/functional/Android.bp index e38af00a38..e1a254dee4 100644 --- a/graphics/composer/2.2/vts/functional/Android.bp +++ b/graphics/composer/2.2/vts/functional/Android.bp @@ -61,6 +61,6 @@ cc_test { disable_framework: true, test_suites: [ "general-tests", - "vts-core", + "vts", ], } diff --git a/graphics/composer/2.3/vts/functional/Android.bp b/graphics/composer/2.3/vts/functional/Android.bp index fa4823efbd..18ea2aa96c 100644 --- a/graphics/composer/2.3/vts/functional/Android.bp +++ b/graphics/composer/2.3/vts/functional/Android.bp @@ -50,5 +50,5 @@ cc_test { "android.hardware.graphics.composer@2.3-command-buffer", ], disable_framework: true, - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/graphics/composer/2.4/vts/functional/Android.bp b/graphics/composer/2.4/vts/functional/Android.bp index 937af3d4d2..9e7cc46c56 100644 --- a/graphics/composer/2.4/vts/functional/Android.bp +++ b/graphics/composer/2.4/vts/functional/Android.bp @@ -52,5 +52,5 @@ cc_test { "android.hardware.graphics.composer@2.4-command-buffer", ], disable_framework: true, - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/graphics/mapper/2.0/vts/functional/Android.bp b/graphics/mapper/2.0/vts/functional/Android.bp index a055b61b60..1f7ae04c15 100644 --- a/graphics/mapper/2.0/vts/functional/Android.bp +++ b/graphics/mapper/2.0/vts/functional/Android.bp @@ -24,5 +24,5 @@ cc_test { "android.hardware.graphics.mapper@2.0", "android.hardware.graphics.mapper@2.0-vts", ], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/graphics/mapper/2.1/vts/functional/Android.bp b/graphics/mapper/2.1/vts/functional/Android.bp index bb76c7452a..ccbe40fd96 100644 --- a/graphics/mapper/2.1/vts/functional/Android.bp +++ b/graphics/mapper/2.1/vts/functional/Android.bp @@ -26,5 +26,5 @@ cc_test { "android.hardware.graphics.mapper@2.0-vts", "android.hardware.graphics.mapper@2.1-vts", ], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/graphics/mapper/3.0/vts/functional/Android.bp b/graphics/mapper/3.0/vts/functional/Android.bp index f01670e299..3f4abecdd4 100644 --- a/graphics/mapper/3.0/vts/functional/Android.bp +++ b/graphics/mapper/3.0/vts/functional/Android.bp @@ -26,5 +26,5 @@ cc_test { "android.hardware.graphics.mapper@3.0", "android.hardware.graphics.mapper@3.0-vts", ], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/graphics/mapper/4.0/vts/functional/Android.bp b/graphics/mapper/4.0/vts/functional/Android.bp index 3542a6ee89..03abc891c0 100644 --- a/graphics/mapper/4.0/vts/functional/Android.bp +++ b/graphics/mapper/4.0/vts/functional/Android.bp @@ -36,6 +36,6 @@ cc_test { ], test_suites: [ "general-tests", - "vts-core", + "vts", ], } diff --git a/health/1.0/vts/functional/Android.bp b/health/1.0/vts/functional/Android.bp index be2d20685a..f4a04a7308 100644 --- a/health/1.0/vts/functional/Android.bp +++ b/health/1.0/vts/functional/Android.bp @@ -19,5 +19,5 @@ cc_test { defaults: ["VtsHalTargetTestDefaults"], srcs: ["VtsHalHealthV1_0TargetTest.cpp"], static_libs: ["android.hardware.health@1.0"], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/health/2.0/vts/functional/Android.bp b/health/2.0/vts/functional/Android.bp index 43571efaef..ab14ca75c3 100644 --- a/health/2.0/vts/functional/Android.bp +++ b/health/2.0/vts/functional/Android.bp @@ -23,5 +23,5 @@ cc_test { "android.hardware.health@1.0", "android.hardware.health@2.0", ], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/health/2.1/vts/functional/Android.bp b/health/2.1/vts/functional/Android.bp index 17472fa2fa..7894ca24a8 100644 --- a/health/2.1/vts/functional/Android.bp +++ b/health/2.1/vts/functional/Android.bp @@ -27,6 +27,6 @@ cc_test { ], test_suites: [ "general-tests", - "vts-core", + "vts", ], } diff --git a/health/storage/1.0/vts/functional/Android.bp b/health/storage/1.0/vts/functional/Android.bp index 4c703c571f..22010319a2 100644 --- a/health/storage/1.0/vts/functional/Android.bp +++ b/health/storage/1.0/vts/functional/Android.bp @@ -24,7 +24,7 @@ cc_test { ], test_suites: [ "general-tests", - "vts-core", + "vts", ], test_config: "VtsHalHealthStorageV1_0TargetTest.config", } diff --git a/identity/aidl/vts/Android.bp b/identity/aidl/vts/Android.bp index cecc814fdc..ef8beb4cdf 100644 --- a/identity/aidl/vts/Android.bp +++ b/identity/aidl/vts/Android.bp @@ -17,6 +17,6 @@ cc_test { ], test_suites: [ "general-tests", - "vts-core", + "vts", ], } diff --git a/input/classifier/1.0/vts/functional/Android.bp b/input/classifier/1.0/vts/functional/Android.bp index 4db1398778..4d6c9c367e 100644 --- a/input/classifier/1.0/vts/functional/Android.bp +++ b/input/classifier/1.0/vts/functional/Android.bp @@ -24,6 +24,6 @@ cc_test { ], test_suites: [ "general-tests", - "vts-core", + "vts", ], } diff --git a/ir/1.0/vts/functional/Android.bp b/ir/1.0/vts/functional/Android.bp index f9edebdb96..160129f8c5 100644 --- a/ir/1.0/vts/functional/Android.bp +++ b/ir/1.0/vts/functional/Android.bp @@ -21,5 +21,5 @@ cc_test { static_libs: [ "android.hardware.ir@1.0", ], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/keymaster/3.0/vts/functional/Android.bp b/keymaster/3.0/vts/functional/Android.bp index 36a6861a7d..35b9387132 100644 --- a/keymaster/3.0/vts/functional/Android.bp +++ b/keymaster/3.0/vts/functional/Android.bp @@ -29,5 +29,5 @@ cc_test { "libcrypto_static", "libsoftkeymasterdevice", ], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/keymaster/4.0/vts/functional/Android.bp b/keymaster/4.0/vts/functional/Android.bp index db500805dc..e706c689e6 100644 --- a/keymaster/4.0/vts/functional/Android.bp +++ b/keymaster/4.0/vts/functional/Android.bp @@ -30,7 +30,7 @@ cc_test { ], test_suites: [ "general-tests", - "vts-core", + "vts", ], } diff --git a/keymaster/4.1/vts/functional/Android.bp b/keymaster/4.1/vts/functional/Android.bp index c2d7fa3547..5ba05ea4ef 100644 --- a/keymaster/4.1/vts/functional/Android.bp +++ b/keymaster/4.1/vts/functional/Android.bp @@ -37,6 +37,6 @@ cc_test { ], test_suites: [ "general-tests", - "vts-core", + "vts", ], } diff --git a/light/2.0/vts/functional/Android.bp b/light/2.0/vts/functional/Android.bp index 2c0a08fab4..06590c3a15 100644 --- a/light/2.0/vts/functional/Android.bp +++ b/light/2.0/vts/functional/Android.bp @@ -19,6 +19,6 @@ cc_test { defaults: ["VtsHalTargetTestDefaults"], srcs: ["VtsHalLightV2_0TargetTest.cpp"], static_libs: ["android.hardware.light@2.0"], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/light/aidl/vts/functional/Android.bp b/light/aidl/vts/functional/Android.bp index 3dd8cf64ce..aa4719b739 100644 --- a/light/aidl/vts/functional/Android.bp +++ b/light/aidl/vts/functional/Android.bp @@ -30,6 +30,6 @@ cc_test { "android.hardware.light-cpp", ], test_suites: [ - "vts-core", + "vts", ], } diff --git a/media/omx/1.0/vts/functional/audio/Android.bp b/media/omx/1.0/vts/functional/audio/Android.bp index 532521e0fe..ec7357cb3d 100644 --- a/media/omx/1.0/vts/functional/audio/Android.bp +++ b/media/omx/1.0/vts/functional/audio/Android.bp @@ -25,7 +25,7 @@ cc_test { data: [":media_omx_audio_res"], test_config: "VtsHalMediaOmxV1_0TargetAudioEncTest.xml", test_suites: [ - "vts-core", + "vts", ], } @@ -40,6 +40,6 @@ cc_test { data: [":media_omx_audio_res"], test_config: "VtsHalMediaOmxV1_0TargetAudioDecTest.xml", test_suites: [ - "vts-core", + "vts", ], } diff --git a/media/omx/1.0/vts/functional/component/Android.bp b/media/omx/1.0/vts/functional/component/Android.bp index c7be2cc8d9..8fb627ad42 100644 --- a/media/omx/1.0/vts/functional/component/Android.bp +++ b/media/omx/1.0/vts/functional/component/Android.bp @@ -19,6 +19,6 @@ cc_test { defaults: ["VtsHalMediaOmxV1_0Defaults"], srcs: ["VtsHalMediaOmxV1_0TargetComponentTest.cpp"], test_suites: [ - "vts-core", + "vts", ], } diff --git a/media/omx/1.0/vts/functional/master/Android.bp b/media/omx/1.0/vts/functional/master/Android.bp index 0eb2cc998d..8e58821e12 100644 --- a/media/omx/1.0/vts/functional/master/Android.bp +++ b/media/omx/1.0/vts/functional/master/Android.bp @@ -19,6 +19,6 @@ cc_test { defaults: ["VtsHalMediaOmxV1_0Defaults"], srcs: ["VtsHalMediaOmxV1_0TargetMasterTest.cpp"], test_suites: [ - "vts-core", + "vts", ], } diff --git a/media/omx/1.0/vts/functional/video/Android.bp b/media/omx/1.0/vts/functional/video/Android.bp index 7e93faa261..b35c26c0f3 100644 --- a/media/omx/1.0/vts/functional/video/Android.bp +++ b/media/omx/1.0/vts/functional/video/Android.bp @@ -25,7 +25,7 @@ cc_test { data: [":media_omx_video_res"], test_config: "VtsHalMediaOmxV1_0TargetVideoDecTest.xml", test_suites: [ - "vts-core", + "vts", ], } @@ -43,6 +43,6 @@ cc_test { data: [":media_omx_video_res"], test_config: "VtsHalMediaOmxV1_0TargetVideoEncTest.xml", test_suites: [ - "vts-core", + "vts", ], } diff --git a/memtrack/1.0/vts/functional/Android.bp b/memtrack/1.0/vts/functional/Android.bp index 9e5cf6dc37..445770ad9b 100644 --- a/memtrack/1.0/vts/functional/Android.bp +++ b/memtrack/1.0/vts/functional/Android.bp @@ -19,5 +19,5 @@ cc_test { defaults: ["VtsHalTargetTestDefaults"], srcs: ["VtsHalMemtrackV1_0TargetTest.cpp"], static_libs: ["android.hardware.memtrack@1.0"], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/neuralnetworks/1.0/vts/functional/Android.bp b/neuralnetworks/1.0/vts/functional/Android.bp index 03af671086..87e851930d 100644 --- a/neuralnetworks/1.0/vts/functional/Android.bp +++ b/neuralnetworks/1.0/vts/functional/Android.bp @@ -88,5 +88,5 @@ cc_test { header_libs: [ "libneuralnetworks_headers", ], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/neuralnetworks/1.1/vts/functional/Android.bp b/neuralnetworks/1.1/vts/functional/Android.bp index 9ba192518a..9afa0af35b 100644 --- a/neuralnetworks/1.1/vts/functional/Android.bp +++ b/neuralnetworks/1.1/vts/functional/Android.bp @@ -47,5 +47,5 @@ cc_test { header_libs: [ "libneuralnetworks_headers", ], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/neuralnetworks/1.2/vts/functional/Android.bp b/neuralnetworks/1.2/vts/functional/Android.bp index 7c1faeef68..481eb80258 100644 --- a/neuralnetworks/1.2/vts/functional/Android.bp +++ b/neuralnetworks/1.2/vts/functional/Android.bp @@ -72,6 +72,6 @@ cc_test { ], test_suites: [ "general-tests", - "vts-core", + "vts", ], } diff --git a/nfc/1.0/vts/functional/Android.bp b/nfc/1.0/vts/functional/Android.bp index 40b82bbf98..40ba22ee2f 100644 --- a/nfc/1.0/vts/functional/Android.bp +++ b/nfc/1.0/vts/functional/Android.bp @@ -21,5 +21,5 @@ cc_test { static_libs: [ "android.hardware.nfc@1.0", ], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/nfc/1.1/vts/functional/Android.bp b/nfc/1.1/vts/functional/Android.bp index 8da0ce3a78..1c18418514 100644 --- a/nfc/1.1/vts/functional/Android.bp +++ b/nfc/1.1/vts/functional/Android.bp @@ -22,5 +22,5 @@ cc_test { "android.hardware.nfc@1.0", "android.hardware.nfc@1.1", ], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/nfc/1.2/vts/functional/Android.bp b/nfc/1.2/vts/functional/Android.bp index 7b50a36d74..83e7a8e58e 100644 --- a/nfc/1.2/vts/functional/Android.bp +++ b/nfc/1.2/vts/functional/Android.bp @@ -23,5 +23,5 @@ cc_test { "android.hardware.nfc@1.1", "android.hardware.nfc@1.2", ], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/oemlock/1.0/vts/functional/Android.bp b/oemlock/1.0/vts/functional/Android.bp index 90de347562..4dd92b53d6 100644 --- a/oemlock/1.0/vts/functional/Android.bp +++ b/oemlock/1.0/vts/functional/Android.bp @@ -19,5 +19,5 @@ cc_test { defaults: ["VtsHalTargetTestDefaults"], srcs: ["VtsHalOemLockV1_0TargetTest.cpp"], static_libs: ["android.hardware.oemlock@1.0"], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/power/1.0/vts/functional/Android.bp b/power/1.0/vts/functional/Android.bp index 5d5676d36b..27b945651c 100644 --- a/power/1.0/vts/functional/Android.bp +++ b/power/1.0/vts/functional/Android.bp @@ -19,5 +19,5 @@ cc_test { defaults: ["VtsHalTargetTestDefaults"], srcs: ["VtsHalPowerV1_0TargetTest.cpp"], static_libs: ["android.hardware.power@1.0"], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/power/1.1/vts/functional/Android.bp b/power/1.1/vts/functional/Android.bp index d9a32df9ab..2860fdb10a 100644 --- a/power/1.1/vts/functional/Android.bp +++ b/power/1.1/vts/functional/Android.bp @@ -22,5 +22,5 @@ cc_test { "android.hardware.power@1.0", "android.hardware.power@1.1", ], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/power/1.2/vts/functional/Android.bp b/power/1.2/vts/functional/Android.bp index 5385faa8a8..5d1b2a4973 100644 --- a/power/1.2/vts/functional/Android.bp +++ b/power/1.2/vts/functional/Android.bp @@ -23,5 +23,5 @@ cc_test { "android.hardware.power@1.1", "android.hardware.power@1.2", ], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/power/1.3/vts/functional/Android.bp b/power/1.3/vts/functional/Android.bp index 77e86197a0..d8e1c050ad 100644 --- a/power/1.3/vts/functional/Android.bp +++ b/power/1.3/vts/functional/Android.bp @@ -24,5 +24,5 @@ cc_test { "android.hardware.power@1.2", "android.hardware.power@1.3", ], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/power/aidl/vts/Android.bp b/power/aidl/vts/Android.bp index 7726fd8a73..28b08c7c4e 100644 --- a/power/aidl/vts/Android.bp +++ b/power/aidl/vts/Android.bp @@ -26,6 +26,6 @@ cc_test { "android.hardware.power-cpp", ], test_suites: [ - "vts-core", + "vts", ], } diff --git a/power/stats/1.0/vts/functional/Android.bp b/power/stats/1.0/vts/functional/Android.bp index ab47061461..d5f1da2d9d 100644 --- a/power/stats/1.0/vts/functional/Android.bp +++ b/power/stats/1.0/vts/functional/Android.bp @@ -33,5 +33,5 @@ cc_test { "libfmq", "libutils", ], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/radio/1.0/vts/functional/Android.bp b/radio/1.0/vts/functional/Android.bp index 2351d903fa..13fc5425ac 100644 --- a/radio/1.0/vts/functional/Android.bp +++ b/radio/1.0/vts/functional/Android.bp @@ -34,7 +34,7 @@ cc_test { "android.hardware.radio@1.0", ], test_config: "vts_hal_radio_target_test.xml", - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } cc_test { @@ -49,7 +49,7 @@ cc_test { "android.hardware.radio@1.0", ], test_config: "vts_hal_sap_target_test.xml", - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } cc_library_static { diff --git a/radio/1.1/vts/functional/Android.bp b/radio/1.1/vts/functional/Android.bp index 58aa67e0f9..e1278b926a 100644 --- a/radio/1.1/vts/functional/Android.bp +++ b/radio/1.1/vts/functional/Android.bp @@ -30,5 +30,5 @@ cc_test { header_libs: [ "radio.util.header@1.0", ], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/radio/1.2/vts/functional/Android.bp b/radio/1.2/vts/functional/Android.bp index f7189a8cbd..56f2d5fb49 100644 --- a/radio/1.2/vts/functional/Android.bp +++ b/radio/1.2/vts/functional/Android.bp @@ -34,5 +34,5 @@ cc_test { "android.hardware.radio.config@1.1", ], header_libs: ["radio.util.header@1.0"], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/radio/1.3/vts/functional/Android.bp b/radio/1.3/vts/functional/Android.bp index 2301732331..e32258f5d3 100644 --- a/radio/1.3/vts/functional/Android.bp +++ b/radio/1.3/vts/functional/Android.bp @@ -32,5 +32,5 @@ cc_test { "android.hardware.radio@1.0", ], header_libs: ["radio.util.header@1.0"], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/radio/1.4/vts/functional/Android.bp b/radio/1.4/vts/functional/Android.bp index 82844048b6..369b55b7a2 100644 --- a/radio/1.4/vts/functional/Android.bp +++ b/radio/1.4/vts/functional/Android.bp @@ -35,5 +35,5 @@ cc_test { "android.hardware.radio.config@1.1", ], header_libs: ["radio.util.header@1.0"], - test_suites: ["general-tests", "vts-core"] + test_suites: ["general-tests", "vts"] } diff --git a/radio/1.5/vts/functional/Android.bp b/radio/1.5/vts/functional/Android.bp index cd30f7dd39..cd54d274fd 100644 --- a/radio/1.5/vts/functional/Android.bp +++ b/radio/1.5/vts/functional/Android.bp @@ -36,5 +36,5 @@ cc_test { "android.hardware.radio.config@1.1", ], header_libs: ["radio.util.header@1.0"], - test_suites: ["general-tests", "vts-core"] + test_suites: ["general-tests", "vts"] } diff --git a/radio/config/1.0/vts/functional/Android.bp b/radio/config/1.0/vts/functional/Android.bp index 859b24bde9..330209eed0 100644 --- a/radio/config/1.0/vts/functional/Android.bp +++ b/radio/config/1.0/vts/functional/Android.bp @@ -29,5 +29,5 @@ cc_test { "android.hardware.radio.config@1.0", ], header_libs: ["radio.util.header@1.0"], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/radio/config/1.1/vts/functional/Android.bp b/radio/config/1.1/vts/functional/Android.bp index 8cf7b629a5..f60331d1c3 100644 --- a/radio/config/1.1/vts/functional/Android.bp +++ b/radio/config/1.1/vts/functional/Android.bp @@ -29,5 +29,5 @@ cc_test { "android.hardware.radio.config@1.1", ], header_libs: ["radio.util.header@1.0"], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/radio/config/1.2/vts/functional/Android.bp b/radio/config/1.2/vts/functional/Android.bp index 2c2073a214..fdc83b73fc 100644 --- a/radio/config/1.2/vts/functional/Android.bp +++ b/radio/config/1.2/vts/functional/Android.bp @@ -31,5 +31,5 @@ cc_test { "android.hardware.radio.config@1.2", ], header_libs: ["radio.util.header@1.0"], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/rebootescrow/aidl/vts/functional/Android.bp b/rebootescrow/aidl/vts/functional/Android.bp index 5d51a53f06..2cc00685d6 100644 --- a/rebootescrow/aidl/vts/functional/Android.bp +++ b/rebootescrow/aidl/vts/functional/Android.bp @@ -28,7 +28,7 @@ cc_test { "android.hardware.rebootescrow-cpp", ], test_suites: [ - "vts-core", + "vts", ], require_root: true, } diff --git a/renderscript/1.0/vts/functional/Android.bp b/renderscript/1.0/vts/functional/Android.bp index e3716e01b1..327c09edb5 100644 --- a/renderscript/1.0/vts/functional/Android.bp +++ b/renderscript/1.0/vts/functional/Android.bp @@ -28,5 +28,5 @@ cc_test { "android.hardware.renderscript@1.0", "libnativewindow", ], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/secure_element/1.0/vts/functional/Android.bp b/secure_element/1.0/vts/functional/Android.bp index 6dbd027747..d428c6f771 100644 --- a/secure_element/1.0/vts/functional/Android.bp +++ b/secure_element/1.0/vts/functional/Android.bp @@ -21,5 +21,5 @@ cc_test { static_libs: [ "android.hardware.secure_element@1.0", ], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/secure_element/1.1/vts/functional/Android.bp b/secure_element/1.1/vts/functional/Android.bp index a2c39dc973..200aed829d 100644 --- a/secure_element/1.1/vts/functional/Android.bp +++ b/secure_element/1.1/vts/functional/Android.bp @@ -22,5 +22,5 @@ cc_test { "android.hardware.secure_element@1.0", "android.hardware.secure_element@1.1", ], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/secure_element/1.2/vts/functional/Android.bp b/secure_element/1.2/vts/functional/Android.bp index a1732108ab..9a7ca45b54 100644 --- a/secure_element/1.2/vts/functional/Android.bp +++ b/secure_element/1.2/vts/functional/Android.bp @@ -23,5 +23,5 @@ cc_test { "android.hardware.secure_element@1.1", "android.hardware.secure_element@1.2", ], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/sensors/1.0/vts/functional/Android.bp b/sensors/1.0/vts/functional/Android.bp index aaefccbe19..31424abb79 100644 --- a/sensors/1.0/vts/functional/Android.bp +++ b/sensors/1.0/vts/functional/Android.bp @@ -33,6 +33,6 @@ cc_test { ], test_suites: [ "general-tests", - "vts-core", + "vts", ], } diff --git a/sensors/2.0/vts/functional/Android.bp b/sensors/2.0/vts/functional/Android.bp index 08c59b6378..598ad15923 100644 --- a/sensors/2.0/vts/functional/Android.bp +++ b/sensors/2.0/vts/functional/Android.bp @@ -40,6 +40,6 @@ cc_test { ], test_suites: [ "general-tests", - "vts-core", + "vts", ], } diff --git a/sensors/2.1/vts/functional/Android.bp b/sensors/2.1/vts/functional/Android.bp index c4f5e9d2d7..3f01a3ec84 100644 --- a/sensors/2.1/vts/functional/Android.bp +++ b/sensors/2.1/vts/functional/Android.bp @@ -42,6 +42,6 @@ cc_test { ], test_suites: [ "general-tests", - "vts-core", + "vts", ], } diff --git a/soundtrigger/2.0/vts/functional/Android.bp b/soundtrigger/2.0/vts/functional/Android.bp index 13dcdec69e..86697bda3d 100644 --- a/soundtrigger/2.0/vts/functional/Android.bp +++ b/soundtrigger/2.0/vts/functional/Android.bp @@ -19,5 +19,5 @@ cc_test { defaults: ["VtsHalTargetTestDefaults"], srcs: ["VtsHalSoundtriggerV2_0TargetTest.cpp"], static_libs: ["android.hardware.soundtrigger@2.0"], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/soundtrigger/2.1/vts/functional/Android.bp b/soundtrigger/2.1/vts/functional/Android.bp index 7830fe2602..9de913b641 100644 --- a/soundtrigger/2.1/vts/functional/Android.bp +++ b/soundtrigger/2.1/vts/functional/Android.bp @@ -25,5 +25,5 @@ cc_test { "android.hardware.soundtrigger@2.1", "libhidlmemory" ], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/soundtrigger/2.2/vts/functional/Android.bp b/soundtrigger/2.2/vts/functional/Android.bp index b5d241d263..b7967d966f 100644 --- a/soundtrigger/2.2/vts/functional/Android.bp +++ b/soundtrigger/2.2/vts/functional/Android.bp @@ -23,5 +23,5 @@ cc_test { "android.hardware.soundtrigger@2.1", "android.hardware.soundtrigger@2.2", ], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/soundtrigger/2.3/vts/functional/Android.bp b/soundtrigger/2.3/vts/functional/Android.bp index e3855fc372..2c1b9e594e 100644 --- a/soundtrigger/2.3/vts/functional/Android.bp +++ b/soundtrigger/2.3/vts/functional/Android.bp @@ -26,6 +26,6 @@ cc_test { ], test_suites: [ "general-tests", - "vts-core", + "vts", ], } diff --git a/tetheroffload/config/1.0/vts/functional/Android.bp b/tetheroffload/config/1.0/vts/functional/Android.bp index 7b472e3e79..ad5a1b1af4 100644 --- a/tetheroffload/config/1.0/vts/functional/Android.bp +++ b/tetheroffload/config/1.0/vts/functional/Android.bp @@ -17,5 +17,5 @@ cc_test { defaults: ["VtsHalTargetTestDefaults"], srcs: ["VtsHalTetheroffloadConfigV1_0TargetTest.cpp"], static_libs: ["android.hardware.tetheroffload.config@1.0"], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/tetheroffload/control/1.0/vts/functional/Android.bp b/tetheroffload/control/1.0/vts/functional/Android.bp index 4af59b66ed..c51dd8b08d 100644 --- a/tetheroffload/control/1.0/vts/functional/Android.bp +++ b/tetheroffload/control/1.0/vts/functional/Android.bp @@ -20,5 +20,5 @@ cc_test { "android.hardware.tetheroffload.config@1.0", "android.hardware.tetheroffload.control@1.0", ], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/thermal/1.0/vts/functional/Android.bp b/thermal/1.0/vts/functional/Android.bp index d183bd8a0e..5ccf07af17 100644 --- a/thermal/1.0/vts/functional/Android.bp +++ b/thermal/1.0/vts/functional/Android.bp @@ -19,6 +19,6 @@ cc_test { defaults: ["VtsHalTargetTestDefaults"], srcs: ["VtsHalThermalV1_0TargetTest.cpp"], static_libs: ["android.hardware.thermal@1.0"], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/thermal/1.1/vts/functional/Android.bp b/thermal/1.1/vts/functional/Android.bp index 2c43d79766..b869ece290 100644 --- a/thermal/1.1/vts/functional/Android.bp +++ b/thermal/1.1/vts/functional/Android.bp @@ -22,5 +22,5 @@ cc_test { "android.hardware.thermal@1.0", "android.hardware.thermal@1.1", ], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/thermal/2.0/vts/functional/Android.bp b/thermal/2.0/vts/functional/Android.bp index 09405763a2..026cb62577 100644 --- a/thermal/2.0/vts/functional/Android.bp +++ b/thermal/2.0/vts/functional/Android.bp @@ -22,6 +22,6 @@ cc_test { "android.hardware.thermal@1.0", "android.hardware.thermal@2.0", ], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/tv/input/1.0/vts/functional/Android.bp b/tv/input/1.0/vts/functional/Android.bp index 5d20bceeed..29d4e21de2 100644 --- a/tv/input/1.0/vts/functional/Android.bp +++ b/tv/input/1.0/vts/functional/Android.bp @@ -21,7 +21,7 @@ cc_test { static_libs: ["android.hardware.tv.input@1.0"], test_suites: [ "general-tests", - "vts-core", + "vts", ], require_root: true, } diff --git a/tv/tuner/1.0/vts/functional/Android.bp b/tv/tuner/1.0/vts/functional/Android.bp index 3637708a6a..641e16a937 100644 --- a/tv/tuner/1.0/vts/functional/Android.bp +++ b/tv/tuner/1.0/vts/functional/Android.bp @@ -32,7 +32,7 @@ cc_test { ], test_suites: [ "general-tests", - "vts-core", + "vts", ], require_root: true, diff --git a/usb/1.0/vts/functional/Android.bp b/usb/1.0/vts/functional/Android.bp index 1a3b56b99c..ae31bd2d30 100644 --- a/usb/1.0/vts/functional/Android.bp +++ b/usb/1.0/vts/functional/Android.bp @@ -19,5 +19,5 @@ cc_test { defaults: ["VtsHalTargetTestDefaults"], srcs: ["VtsHalUsbV1_0TargetTest.cpp"], static_libs: ["android.hardware.usb@1.0"], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/usb/1.1/vts/functional/Android.bp b/usb/1.1/vts/functional/Android.bp index 32c470b096..5bec94af66 100644 --- a/usb/1.1/vts/functional/Android.bp +++ b/usb/1.1/vts/functional/Android.bp @@ -22,6 +22,6 @@ cc_test { "android.hardware.usb@1.0", "android.hardware.usb@1.1", ], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/vibrator/1.0/vts/functional/Android.bp b/vibrator/1.0/vts/functional/Android.bp index 10ec2cbab6..4ec1aa8064 100644 --- a/vibrator/1.0/vts/functional/Android.bp +++ b/vibrator/1.0/vts/functional/Android.bp @@ -19,6 +19,6 @@ cc_test { defaults: ["VtsHalTargetTestDefaults"], srcs: ["VtsHalVibratorV1_0TargetTest.cpp"], static_libs: ["android.hardware.vibrator@1.0"], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/vibrator/1.1/vts/functional/Android.bp b/vibrator/1.1/vts/functional/Android.bp index 4cde350e79..b291e7ce50 100644 --- a/vibrator/1.1/vts/functional/Android.bp +++ b/vibrator/1.1/vts/functional/Android.bp @@ -22,6 +22,6 @@ cc_test { "android.hardware.vibrator@1.0", "android.hardware.vibrator@1.1", ], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/vibrator/1.2/vts/functional/Android.bp b/vibrator/1.2/vts/functional/Android.bp index e7052f2b6d..7bf69d06d3 100644 --- a/vibrator/1.2/vts/functional/Android.bp +++ b/vibrator/1.2/vts/functional/Android.bp @@ -23,6 +23,6 @@ cc_test { "android.hardware.vibrator@1.1", "android.hardware.vibrator@1.2", ], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/vibrator/1.3/vts/functional/Android.bp b/vibrator/1.3/vts/functional/Android.bp index 038dc5ca59..5215ed04cf 100644 --- a/vibrator/1.3/vts/functional/Android.bp +++ b/vibrator/1.3/vts/functional/Android.bp @@ -24,6 +24,6 @@ cc_test { "android.hardware.vibrator@1.2", "android.hardware.vibrator@1.3", ], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/vibrator/aidl/vts/Android.bp b/vibrator/aidl/vts/Android.bp index d1e135e4a3..28cb4d9856 100644 --- a/vibrator/aidl/vts/Android.bp +++ b/vibrator/aidl/vts/Android.bp @@ -13,6 +13,6 @@ cc_test { ], test_suites: [ "general-tests", - "vts-core", + "vts", ], } diff --git a/vr/1.0/vts/functional/Android.bp b/vr/1.0/vts/functional/Android.bp index bd0336cc15..6bfa05cad7 100644 --- a/vr/1.0/vts/functional/Android.bp +++ b/vr/1.0/vts/functional/Android.bp @@ -19,5 +19,5 @@ cc_test { defaults: ["VtsHalTargetTestDefaults"], srcs: ["VtsHalVrV1_0TargetTest.cpp"], static_libs: ["android.hardware.vr@1.0"], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/weaver/1.0/vts/functional/Android.bp b/weaver/1.0/vts/functional/Android.bp index 3942deb166..b20f127647 100644 --- a/weaver/1.0/vts/functional/Android.bp +++ b/weaver/1.0/vts/functional/Android.bp @@ -19,5 +19,5 @@ cc_test { defaults: ["VtsHalTargetTestDefaults"], srcs: ["VtsHalWeaverV1_0TargetTest.cpp"], static_libs: ["android.hardware.weaver@1.0"], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/wifi/1.0/vts/functional/Android.bp b/wifi/1.0/vts/functional/Android.bp index 2242510933..793dd8cc7c 100644 --- a/wifi/1.0/vts/functional/Android.bp +++ b/wifi/1.0/vts/functional/Android.bp @@ -51,7 +51,7 @@ cc_test { "android.hardware.wifi@1.3", "libwifi-system-iface" ], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } // These tests are split out so that they can be conditioned on presence of the @@ -68,7 +68,7 @@ cc_test { "android.hardware.wifi@1.0", "libwifi-system-iface" ], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } // These tests are split out so that they can be conditioned on presence of @@ -85,5 +85,5 @@ cc_test { "android.hardware.wifi@1.0", "libwifi-system-iface" ], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/wifi/1.1/vts/functional/Android.bp b/wifi/1.1/vts/functional/Android.bp index d34ae222d9..eb68bc0ddc 100644 --- a/wifi/1.1/vts/functional/Android.bp +++ b/wifi/1.1/vts/functional/Android.bp @@ -27,5 +27,5 @@ cc_test { "android.hardware.wifi@1.3", "libwifi-system-iface" ], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/wifi/1.2/vts/functional/Android.bp b/wifi/1.2/vts/functional/Android.bp index d3de5cfc67..90bcac1d33 100644 --- a/wifi/1.2/vts/functional/Android.bp +++ b/wifi/1.2/vts/functional/Android.bp @@ -30,7 +30,7 @@ cc_test { "libwifi-system-iface" ], disable_framework: true, - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } cc_test { @@ -47,5 +47,5 @@ cc_test { "libwifi-system-iface" ], disable_framework: true, - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/wifi/1.3/vts/functional/Android.bp b/wifi/1.3/vts/functional/Android.bp index 457de2973a..3568330845 100644 --- a/wifi/1.3/vts/functional/Android.bp +++ b/wifi/1.3/vts/functional/Android.bp @@ -30,5 +30,5 @@ cc_test { "libwifi-system-iface" ], disable_framework: true, - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/wifi/1.4/vts/functional/Android.bp b/wifi/1.4/vts/functional/Android.bp index 7e74cbd5de..3824c3aecf 100644 --- a/wifi/1.4/vts/functional/Android.bp +++ b/wifi/1.4/vts/functional/Android.bp @@ -35,6 +35,6 @@ cc_test { ], test_suites: [ "general-tests", - "vts-core", + "vts", ], } diff --git a/wifi/hostapd/1.0/vts/functional/Android.bp b/wifi/hostapd/1.0/vts/functional/Android.bp index e966d7e817..2a35f15190 100644 --- a/wifi/hostapd/1.0/vts/functional/Android.bp +++ b/wifi/hostapd/1.0/vts/functional/Android.bp @@ -48,5 +48,5 @@ cc_test { "libwifi-system", "libwifi-system-iface", ], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/wifi/hostapd/1.1/vts/functional/Android.bp b/wifi/hostapd/1.1/vts/functional/Android.bp index 8670f2fe97..291eceb80c 100644 --- a/wifi/hostapd/1.1/vts/functional/Android.bp +++ b/wifi/hostapd/1.1/vts/functional/Android.bp @@ -30,6 +30,6 @@ cc_test { "libwifi-system", "libwifi-system-iface", ], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/wifi/hostapd/1.2/vts/functional/Android.bp b/wifi/hostapd/1.2/vts/functional/Android.bp index 4f4a741bf3..cec17823fd 100644 --- a/wifi/hostapd/1.2/vts/functional/Android.bp +++ b/wifi/hostapd/1.2/vts/functional/Android.bp @@ -31,6 +31,6 @@ cc_test { "libwifi-system", "libwifi-system-iface", ], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/wifi/offload/1.0/vts/functional/Android.bp b/wifi/offload/1.0/vts/functional/Android.bp index 965c946764..abfefa8214 100644 --- a/wifi/offload/1.0/vts/functional/Android.bp +++ b/wifi/offload/1.0/vts/functional/Android.bp @@ -19,5 +19,5 @@ cc_test { defaults: ["VtsHalTargetTestDefaults"], srcs: ["VtsHalWifiOffloadV1_0TargetTest.cpp"], static_libs: ["android.hardware.wifi.offload@1.0"], - test_suites: ["general-tests", "vts-core"], + test_suites: ["general-tests", "vts"], } diff --git a/wifi/supplicant/1.0/vts/functional/Android.bp b/wifi/supplicant/1.0/vts/functional/Android.bp index a05cc6bfa8..6f282bb9d7 100644 --- a/wifi/supplicant/1.0/vts/functional/Android.bp +++ b/wifi/supplicant/1.0/vts/functional/Android.bp @@ -54,7 +54,7 @@ cc_test { ], test_suites: [ "general-tests", - "vts-core", + "vts", ], } @@ -77,6 +77,6 @@ cc_test { ], test_suites: [ "general-tests", - "vts-core", + "vts", ], } diff --git a/wifi/supplicant/1.1/vts/functional/Android.bp b/wifi/supplicant/1.1/vts/functional/Android.bp index 90a3e872fb..44b020e021 100644 --- a/wifi/supplicant/1.1/vts/functional/Android.bp +++ b/wifi/supplicant/1.1/vts/functional/Android.bp @@ -55,6 +55,6 @@ cc_test { ], test_suites: [ "general-tests", - "vts-core", + "vts", ], } diff --git a/wifi/supplicant/1.2/vts/functional/Android.bp b/wifi/supplicant/1.2/vts/functional/Android.bp index 80f3658edd..c23585aaef 100644 --- a/wifi/supplicant/1.2/vts/functional/Android.bp +++ b/wifi/supplicant/1.2/vts/functional/Android.bp @@ -59,7 +59,7 @@ cc_test { ], test_suites: [ "general-tests", - "vts-core", + "vts", ], } @@ -85,6 +85,6 @@ cc_test { ], test_suites: [ "general-tests", - "vts-core", + "vts", ], } diff --git a/wifi/supplicant/1.3/vts/functional/Android.bp b/wifi/supplicant/1.3/vts/functional/Android.bp index 00a0bf7ee1..8eebed0586 100644 --- a/wifi/supplicant/1.3/vts/functional/Android.bp +++ b/wifi/supplicant/1.3/vts/functional/Android.bp @@ -62,6 +62,6 @@ cc_test { ], test_suites: [ "general-tests", - "vts-core", + "vts", ], } -- GitLab From 19a64c8f4a2f5691d9f3d5a1d7266597ba5e98a0 Mon Sep 17 00:00:00 2001 From: Steven Moreland Date: Wed, 15 Apr 2020 04:43:17 +0000 Subject: [PATCH 039/790] Revert "Add biometrics.face@1.1 to current.txt" This reverts commit 25fbdab041059bce5403ca8329c49d4646057269. Reason for revert: only requiring hashes in release branches Change-Id: Id542b54ba2da1fca03a9c44bf05d0f68793445cf --- current.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/current.txt b/current.txt index e789d2d4e4..e3b2f566a9 100644 --- a/current.txt +++ b/current.txt @@ -764,6 +764,4 @@ a64467bae843569f0d465c5be7f0c7a5b987985b55a3ef4794dd5afc68538650 android.hardwar # ABI preserving changes to HALs during Android S # HALs released in Android S -7e8e1c3d0173c5d503dd01cecff8e3864478557ca6b9e8cc2291598b1a4aea62 android.hardware.biometrics.face@1.1::IBiometricsFace - # NOTE: new HALs are recommended to be in AIDL -- GitLab From 43c1a6a41c82ec00683f13dc282072189d0c0594 Mon Sep 17 00:00:00 2001 From: Orion Hodson Date: Wed, 22 Apr 2020 11:26:59 +0100 Subject: [PATCH 040/790] Add dependency on jni_headers Preparation for removing implicit include paths for jni.h from soong. Bug: 152482542 Test: Apply future soong change && m checkbuild Change-Id: I880eb1f307d995cbd4f0f19e8f8d22c20fc36bef Exempt-From-Owner-Approval: build clean-up --- input/classifier/1.0/vts/functional/Android.bp | 1 + 1 file changed, 1 insertion(+) diff --git a/input/classifier/1.0/vts/functional/Android.bp b/input/classifier/1.0/vts/functional/Android.bp index 4d6c9c367e..99fdb8c445 100644 --- a/input/classifier/1.0/vts/functional/Android.bp +++ b/input/classifier/1.0/vts/functional/Android.bp @@ -18,6 +18,7 @@ cc_test { name: "VtsHalInputClassifierV1_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], srcs: ["VtsHalInputClassifierV1_0TargetTest.cpp"], + header_libs: ["jni_headers"], static_libs: [ "android.hardware.input.classifier@1.0", "android.hardware.input.common@1.0", -- GitLab From 836842221a5924744a4aaaee104fb17d0c305d2a Mon Sep 17 00:00:00 2001 From: felipeal Date: Fri, 17 Apr 2020 14:32:53 -0700 Subject: [PATCH 041/790] Moved emulated User HAL capabilities into a library. So it can be used by other Vehicle HAL implementations. Test: adb shell lshal debug android.hardware.automotive.vehicle@2.0::IVehicle/default --user-hal Test: adb shell lshal debug android.hardware.automotive.vehicle@2.0::IVehicle/default --help Test: m -j android.hardware.automotive.vehicle@2.0-emulated-user-hal-lib Bug: 150167241 Bug: 150409377 Exempt-From-Owner-Approval: already approved on rvc-dev, need to submit here due to merge conflict Change-Id: I2d0c5039c3b994dfe10d3b411f6d502bebe7cca0 (cherry picked from commit 1847a9b25e191c8258522f30b6d4223458feebd1) --- automotive/vehicle/2.0/default/Android.bp | 15 +- .../default/impl/vhal_v2_0/DefaultConfig.h | 2 - .../impl/vhal_v2_0/EmulatedUserHal.cpp | 186 ++++++++++++++++++ .../default/impl/vhal_v2_0/EmulatedUserHal.h | 115 +++++++++++ .../vhal_v2_0/EmulatedVehicleConnector.cpp | 26 +-- .../impl/vhal_v2_0/VehicleHalServer.cpp | 182 ++--------------- .../default/impl/vhal_v2_0/VehicleHalServer.h | 8 +- 7 files changed, 338 insertions(+), 196 deletions(-) create mode 100644 automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedUserHal.cpp create mode 100644 automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedUserHal.h diff --git a/automotive/vehicle/2.0/default/Android.bp b/automotive/vehicle/2.0/default/Android.bp index 21b410a080..872b35b4f0 100644 --- a/automotive/vehicle/2.0/default/Android.bp +++ b/automotive/vehicle/2.0/default/Android.bp @@ -75,7 +75,10 @@ cc_library_static { ], local_include_dirs: ["common/include/vhal_v2_0"], export_include_dirs: ["impl"], - whole_static_libs: ["android.hardware.automotive.vehicle@2.0-manager-lib"], + whole_static_libs: [ + "android.hardware.automotive.vehicle@2.0-emulated-user-hal-lib", + "android.hardware.automotive.vehicle@2.0-manager-lib", + ], shared_libs: [ "libbase", "libjsoncpp", @@ -87,6 +90,16 @@ cc_library_static { ], } +// Library used to emulate User HAL behavior through lshal debug requests. +cc_library_static { + name: "android.hardware.automotive.vehicle@2.0-emulated-user-hal-lib", + vendor: true, + defaults: ["vhal_v2_0_defaults"], + srcs: [ + "impl/vhal_v2_0/EmulatedUserHal.cpp", + ], +} + cc_test { name: "android.hardware.automotive.vehicle@2.0-manager-unit-tests", vendor: true, diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h index 83546e266a..b8a606adab 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h @@ -79,8 +79,6 @@ constexpr int WHEEL_FRONT_LEFT = (int)VehicleAreaWheel::LEFT_FRONT; constexpr int WHEEL_FRONT_RIGHT = (int)VehicleAreaWheel::RIGHT_FRONT; constexpr int WHEEL_REAR_LEFT = (int)VehicleAreaWheel::LEFT_REAR; constexpr int WHEEL_REAR_RIGHT = (int)VehicleAreaWheel::RIGHT_REAR; -constexpr int INITIAL_USER_INFO = (int)VehicleProperty::INITIAL_USER_INFO; -constexpr int SWITCH_USER = (int)VehicleProperty::SWITCH_USER; /** * This property is used for test purpose to generate fake events. Here is the test package that diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedUserHal.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedUserHal.cpp new file mode 100644 index 0000000000..7ffee1f71a --- /dev/null +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedUserHal.cpp @@ -0,0 +1,186 @@ +/* + * 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 "EmulatedUserHal" + +#include +#include + +#include "EmulatedUserHal.h" + +namespace android { +namespace hardware { +namespace automotive { +namespace vehicle { +namespace V2_0 { + +namespace impl { + +constexpr int INITIAL_USER_INFO = (int)VehicleProperty::INITIAL_USER_INFO; +constexpr int SWITCH_USER = (int)VehicleProperty::SWITCH_USER; + +bool EmulatedUserHal::isSupported(int32_t prop) { + switch (prop) { + case INITIAL_USER_INFO: + case SWITCH_USER: + return true; + default: + return false; + } +} + +android::base::Result> EmulatedUserHal::onSetProperty( + const VehiclePropValue& value) { + ALOGV("onSetProperty(): %s", toString(value).c_str()); + + switch (value.prop) { + case INITIAL_USER_INFO: + return onSetInitialUserInfoResponse(value); + case SWITCH_USER: + return onSetSwitchUserResponse(value); + default: + return android::base::Error((int)StatusCode::INVALID_ARG) + << "Unsupported property: " << toString(value); + } +} + +android::base::Result> +EmulatedUserHal::onSetInitialUserInfoResponse(const VehiclePropValue& value) { + if (value.value.int32Values.size() == 0) { + ALOGE("set(INITIAL_USER_INFO): no int32values, ignoring it: %s", toString(value).c_str()); + return android::base::Error((int)StatusCode::INVALID_ARG) + << "no int32values on " << toString(value); + } + + if (value.areaId != 0) { + ALOGD("set(INITIAL_USER_INFO) called from lshal; storing it: %s", toString(value).c_str()); + mInitialUserResponseFromCmd.reset(new VehiclePropValue(value)); + return {}; + } + + ALOGD("set(INITIAL_USER_INFO) called from Android: %s", toString(value).c_str()); + + int32_t requestId = value.value.int32Values[0]; + if (mInitialUserResponseFromCmd != nullptr) { + ALOGI("replying INITIAL_USER_INFO with lshal value: %s", + toString(*mInitialUserResponseFromCmd).c_str()); + return sendUserHalResponse(std::move(mInitialUserResponseFromCmd), requestId); + } + + // Returns default response + auto updatedValue = std::unique_ptr(new VehiclePropValue); + updatedValue->prop = INITIAL_USER_INFO; + updatedValue->timestamp = elapsedRealtimeNano(); + updatedValue->value.int32Values.resize(2); + updatedValue->value.int32Values[0] = requestId; + updatedValue->value.int32Values[1] = (int32_t)InitialUserInfoResponseAction::DEFAULT; + + ALOGI("no lshal response; replying with InitialUserInfoResponseAction::DEFAULT: %s", + toString(*updatedValue).c_str()); + + return updatedValue; +} + +android::base::Result> EmulatedUserHal::onSetSwitchUserResponse( + const VehiclePropValue& value) { + if (value.value.int32Values.size() == 0) { + ALOGE("set(SWITCH_USER): no int32values, ignoring it: %s", toString(value).c_str()); + return android::base::Error((int)StatusCode::INVALID_ARG) + << "no int32values on " << toString(value); + } + + if (value.areaId != 0) { + ALOGD("set(SWITCH_USER) called from lshal; storing it: %s", toString(value).c_str()); + mSwitchUserResponseFromCmd.reset(new VehiclePropValue(value)); + return {}; + } + ALOGD("set(SWITCH_USER) called from Android: %s", toString(value).c_str()); + + int32_t requestId = value.value.int32Values[0]; + if (mSwitchUserResponseFromCmd != nullptr) { + ALOGI("replying SWITCH_USER with lshal value: %s", + toString(*mSwitchUserResponseFromCmd).c_str()); + return sendUserHalResponse(std::move(mSwitchUserResponseFromCmd), requestId); + } + + // Returns default response + auto updatedValue = std::unique_ptr(new VehiclePropValue); + updatedValue->prop = SWITCH_USER; + updatedValue->timestamp = elapsedRealtimeNano(); + updatedValue->value.int32Values.resize(3); + updatedValue->value.int32Values[0] = requestId; + updatedValue->value.int32Values[1] = (int32_t)SwitchUserMessageType::VEHICLE_RESPONSE; + updatedValue->value.int32Values[2] = (int32_t)SwitchUserStatus::SUCCESS; + + ALOGI("no lshal response; replying with VEHICLE_RESPONSE / SUCCESS: %s", + toString(*updatedValue).c_str()); + + return updatedValue; +} + +android::base::Result> EmulatedUserHal::sendUserHalResponse( + std::unique_ptr response, int32_t requestId) { + switch (response->areaId) { + case 1: + ALOGD("returning response with right request id"); + response->value.int32Values[0] = requestId; + break; + case 2: + ALOGD("returning response with wrong request id"); + response->value.int32Values[0] = -requestId; + break; + case 3: + ALOGD("not generating a property change event because of lshal prop: %s", + toString(*response).c_str()); + return android::base::Error((int)StatusCode::NOT_AVAILABLE) + << "not generating a property change event because of lshal prop: " + << toString(*response); + default: + ALOGE("invalid action on lshal response: %s", toString(*response).c_str()); + return android::base::Error((int)StatusCode::INTERNAL_ERROR) + << "invalid action on lshal response: " << toString(*response); + } + + ALOGD("updating property to: %s", toString(*response).c_str()); + + return response; +} + +void EmulatedUserHal::showDumpHelp(int fd) { + dprintf(fd, "%s: dumps state used for user management\n", kUserHalDumpOption); +} + +void EmulatedUserHal::dump(int fd, std::string indent) { + if (mInitialUserResponseFromCmd != nullptr) { + dprintf(fd, "%sInitialUserInfo response: %s\n", indent.c_str(), + toString(*mInitialUserResponseFromCmd).c_str()); + } else { + dprintf(fd, "%sNo InitialUserInfo response\n", indent.c_str()); + } + if (mSwitchUserResponseFromCmd != nullptr) { + dprintf(fd, "%sSwitchUser response: %s\n", indent.c_str(), + toString(*mSwitchUserResponseFromCmd).c_str()); + } else { + dprintf(fd, "%sNo SwitchUser response\n", indent.c_str()); + } +} + +} // namespace impl + +} // namespace V2_0 +} // namespace vehicle +} // namespace automotive +} // namespace hardware +} // namespace android diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedUserHal.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedUserHal.h new file mode 100644 index 0000000000..b25efcb4d7 --- /dev/null +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedUserHal.h @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef android_hardware_automotive_vehicle_V2_0_impl_EmulatedUserHal_H_ +#define android_hardware_automotive_vehicle_V2_0_impl_EmulatedUserHal_H_ + +#include + +#include + +namespace android { +namespace hardware { +namespace automotive { +namespace vehicle { +namespace V2_0 { + +namespace impl { + +constexpr char kUserHalDumpOption[] = "--user-hal"; + +/** + * Class used to emulate User HAL behavior through lshal debug requests. + */ +class EmulatedUserHal { + public: + EmulatedUserHal() {} + + ~EmulatedUserHal() = default; + + /** + * Checks if the emulator can handle the property. + */ + bool isSupported(int32_t prop); + + /** + * Lets the emulator handle the property. + * + * @return updated property and StatusCode + */ + android::base::Result> onSetProperty( + const VehiclePropValue& value); + + /** + * Shows the User HAL emulation help. + */ + void showDumpHelp(int fd); + + /** + * Dump its contents. + */ + void dump(int fd, std::string indent); + + private: + /** + * INITIAL_USER_INFO is called by Android when it starts, and it's expecting a property change + * indicating what the initial user should be. + * + * During normal circumstances, the emulator will reply right away, passing a response if + * InitialUserInfoResponseAction::DEFAULT (so Android could use its own logic to decide which + * user to boot). + * + * But during development / testing, the behavior can be changed using lshal dump, which must + * use the areaId to indicate what should happen next. + * + * So, the behavior of set(INITIAL_USER_INFO) is: + * + * - if it has an areaId, store the property into mInitialUserResponseFromCmd (as it was called + * by lshal). + * - else if mInitialUserResponseFromCmd is not set, return a response with the same request id + * and InitialUserInfoResponseAction::DEFAULT + * - else the behavior is defined by the areaId on mInitialUserResponseFromCmd: + * - if it's 1, reply with mInitialUserResponseFromCmd and the right request id + * - if it's 2, reply with mInitialUserResponseFromCmd but a wrong request id (so Android can + * test this error scenario) + * - if it's 3, then don't send a property change (so Android can emulate a timeout) + * + */ + android::base::Result> onSetInitialUserInfoResponse( + const VehiclePropValue& value); + + /** + * Used to emulate SWITCH_USER - see onSetInitialUserInfoResponse() for usage. + */ + android::base::Result> onSetSwitchUserResponse( + const VehiclePropValue& value); + + android::base::Result> sendUserHalResponse( + std::unique_ptr response, int32_t requestId); + + std::unique_ptr mInitialUserResponseFromCmd; + std::unique_ptr mSwitchUserResponseFromCmd; +}; + +} // namespace impl + +} // namespace V2_0 +} // namespace vehicle +} // namespace automotive +} // namespace hardware +} // namespace android + +#endif // android_hardware_automotive_vehicle_V2_0_impl_EmulatedUserHal_H_ diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.cpp index ce7dc65127..7f9362fdf4 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.cpp +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.cpp @@ -38,9 +38,6 @@ namespace impl { class EmulatedPassthroughConnector : public PassthroughConnector { public: bool onDump(const hidl_handle& fd, const hidl_vec& options) override; - - private: - void dumpUserHal(int fd, std::string indent); }; bool EmulatedPassthroughConnector::onDump(const hidl_handle& handle, @@ -50,12 +47,12 @@ bool EmulatedPassthroughConnector::onDump(const hidl_handle& handle, if (options.size() > 0) { if (options[0] == "--help") { dprintf(fd, "Emulator-specific usage:\n"); - dprintf(fd, "--user-hal: dumps state used for user management \n"); + mEmulatedUserHal.showDumpHelp(fd); dprintf(fd, "\n"); // Include caller's help options return true; - } else if (options[0] == "--user-hal") { - dumpUserHal(fd, ""); + } else if (options[0] == kUserHalDumpOption) { + mEmulatedUserHal.dump(fd, ""); return false; } else { @@ -65,27 +62,12 @@ bool EmulatedPassthroughConnector::onDump(const hidl_handle& handle, } dprintf(fd, "Emulator-specific state:\n"); - dumpUserHal(fd, " "); + mEmulatedUserHal.dump(fd, " "); dprintf(fd, "\n"); return true; } -void EmulatedPassthroughConnector::dumpUserHal(int fd, std::string indent) { - if (mInitialUserResponseFromCmd != nullptr) { - dprintf(fd, "%sInitialUserInfo response: %s\n", indent.c_str(), - toString(*mInitialUserResponseFromCmd).c_str()); - } else { - dprintf(fd, "%sNo InitialUserInfo response\n", indent.c_str()); - } - if (mSwitchUserResponseFromCmd != nullptr) { - dprintf(fd, "%sSwitchUser response: %s\n", indent.c_str(), - toString(*mSwitchUserResponseFromCmd).c_str()); - } else { - dprintf(fd, "%sNo SwitchUser response\n", indent.c_str()); - } -} - PassthroughConnectorPtr makeEmulatedPassthroughConnector() { return std::make_unique(); } diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.cpp index 70e39ebdbf..ad5096e58f 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.cpp +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.cpp @@ -181,6 +181,23 @@ VehicleHalServer::VehiclePropValuePtr VehicleHalServer::createHwInputKeyProp( } StatusCode VehicleHalServer::onSetProperty(const VehiclePropValue& value, bool updateStatus) { + if (mEmulatedUserHal.isSupported(value.prop)) { + LOG(INFO) << "onSetProperty(): property " << value.prop << " will be handled by UserHal"; + + const auto& ret = mEmulatedUserHal.onSetProperty(value); + if (!ret.ok()) { + LOG(ERROR) << "onSetProperty(): HAL returned error: " << ret.error().message(); + return StatusCode(ret.error().code()); + } + auto updatedValue = ret.value().get(); + if (updatedValue != nullptr) { + LOG(INFO) << "onSetProperty(): updating property returned by HAL: " + << toString(*updatedValue); + onPropertyValueFromCar(*updatedValue, updateStatus); + } + return StatusCode::OK; + } + // Some properties need to be treated non-trivially switch (value.prop) { case kGenerateFakeDataControllingProperty: @@ -245,10 +262,6 @@ StatusCode VehicleHalServer::onSetProperty(const VehiclePropValue& value, bool u break; } break; - case INITIAL_USER_INFO: - return onSetInitialUserInfoResponse(value, updateStatus); - case SWITCH_USER: - return onSetSwitchUserResponse(value, updateStatus); default: break; } @@ -262,165 +275,4 @@ StatusCode VehicleHalServer::onSetProperty(const VehiclePropValue& value, bool u return StatusCode::OK; } -/** - * INITIAL_USER_INFO is called by Android when it starts, and it's expecting a property change - * indicating what the initial user should be. - * - * During normal circumstances, the emulator will reply right away, passing a response if - * InitialUserInfoResponseAction::DEFAULT (so Android could use its own logic to decide which user - * to boot). - * - * But during development / testing, the behavior can be changed using lshal dump, which must use - * the areaId to indicate what should happen next. - * - * So, the behavior of set(INITIAL_USER_INFO) is: - * - * - if it has an areaId, store the property into mInitialUserResponseFromCmd (as it was called by - * lshal). - * - else if mInitialUserResponseFromCmd is not set, return a response with the same request id and - * InitialUserInfoResponseAction::DEFAULT - * - else the behavior is defined by the areaId on mInitialUserResponseFromCmd: - * - if it's 1, reply with mInitialUserResponseFromCmd and the right request id - * - if it's 2, reply with mInitialUserResponseFromCmd but a wrong request id (so Android can test - * this error scenario) - * - if it's 3, then don't send a property change (so Android can emulate a timeout) - * - */ -StatusCode VehicleHalServer::onSetInitialUserInfoResponse(const VehiclePropValue& value, - bool updateStatus) { - // TODO: LOG calls below might be more suited to be DEBUG, but those are not being logged - // (even when explicitly calling setprop log.tag. As this class should be using ALOG instead of - // LOG, it's not worth investigating why... - - if (value.value.int32Values.size() == 0) { - LOG(ERROR) << "set(INITIAL_USER_INFO): no int32values, ignoring it: " << toString(value); - return StatusCode::INVALID_ARG; - } - - if (value.areaId != 0) { - LOG(INFO) << "set(INITIAL_USER_INFO) called from lshal; storing it: " << toString(value); - mInitialUserResponseFromCmd.reset(new VehiclePropValue(value)); - return StatusCode::OK; - } - LOG(INFO) << "set(INITIAL_USER_INFO) called from Android: " << toString(value); - - int32_t requestId = value.value.int32Values[0]; - - // Create the update property and set common values - auto updatedValue = createVehiclePropValue(VehiclePropertyType::MIXED, 0); - updatedValue->prop = INITIAL_USER_INFO; - updatedValue->timestamp = elapsedRealtimeNano(); - - if (mInitialUserResponseFromCmd == nullptr) { - updatedValue->value.int32Values.resize(2); - updatedValue->value.int32Values[0] = requestId; - updatedValue->value.int32Values[1] = (int32_t)InitialUserInfoResponseAction::DEFAULT; - LOG(INFO) << "no lshal response; returning InitialUserInfoResponseAction::DEFAULT: " - << toString(*updatedValue); - onPropertyValueFromCar(*updatedValue, updateStatus); - return StatusCode::OK; - } - - // mInitialUserResponseFromCmd is used for just one request - std::unique_ptr response = std::move(mInitialUserResponseFromCmd); - - // TODO(b/150409377): rather than populate the raw values directly, it should use the - // libraries that convert a InitialUserInfoResponse into a VehiclePropValue) - - switch (response->areaId) { - case 1: - LOG(INFO) << "returning response with right request id"; - *updatedValue = *response; - updatedValue->areaId = 0; - updatedValue->value.int32Values[0] = requestId; - break; - case 2: - LOG(INFO) << "returning response with wrong request id"; - *updatedValue = *response; - updatedValue->areaId = 0; - updatedValue->value.int32Values[0] = -requestId; - break; - case 3: - LOG(INFO) << "not generating a property change event because of lshal prop: " - << toString(*response); - return StatusCode::OK; - default: - LOG(ERROR) << "invalid action on lshal response: " << toString(*response); - return StatusCode::INTERNAL_ERROR; - } - - LOG(INFO) << "updating property to: " << toString(*updatedValue); - onPropertyValueFromCar(*updatedValue, updateStatus); - return StatusCode::OK; -} - -/** - * Used to emulate SWITCH_USER - see onSetInitialUserInfoResponse() for usage. - */ -StatusCode VehicleHalServer::onSetSwitchUserResponse(const VehiclePropValue& value, - bool updateStatus) { - if (value.value.int32Values.size() == 0) { - LOG(ERROR) << "set(SWITCH_USER): no int32values, ignoring it: " << toString(value); - return StatusCode::INVALID_ARG; - } - - if (value.areaId != 0) { - LOG(INFO) << "set(SWITCH_USER) called from lshal; storing it: " << toString(value); - mSwitchUserResponseFromCmd.reset(new VehiclePropValue(value)); - return StatusCode::OK; - } - LOG(INFO) << "set(SWITCH_USER) called from Android: " << toString(value); - - int32_t requestId = value.value.int32Values[0]; - - // Create the update property and set common values - auto updatedValue = createVehiclePropValue(VehiclePropertyType::MIXED, 0); - updatedValue->prop = SWITCH_USER; - updatedValue->timestamp = elapsedRealtimeNano(); - - if (mSwitchUserResponseFromCmd == nullptr) { - updatedValue->value.int32Values.resize(3); - updatedValue->value.int32Values[0] = requestId; - updatedValue->value.int32Values[1] = (int32_t)SwitchUserMessageType::VEHICLE_RESPONSE; - updatedValue->value.int32Values[2] = (int32_t)SwitchUserStatus::SUCCESS; - LOG(INFO) << "no lshal response; returning VEHICLE_RESPONSE / SUCCESS: " - << toString(*updatedValue); - onPropertyValueFromCar(*updatedValue, updateStatus); - return StatusCode::OK; - } - - // mSwitchUserResponseFromCmd is used for just one request - std::unique_ptr response = std::move(mSwitchUserResponseFromCmd); - - // TODO(b/150409377): move code below to a local function like sendUserHalResponse(), - // as it's the same for all (like onSetInitialUserInfoResponse) - - switch (response->areaId) { - case 1: - LOG(INFO) << "returning response with right request id"; - *updatedValue = *response; - updatedValue->areaId = 0; - updatedValue->value.int32Values[0] = requestId; - break; - case 2: - LOG(INFO) << "returning response with wrong request id"; - *updatedValue = *response; - updatedValue->areaId = 0; - updatedValue->value.int32Values[0] = -requestId; - break; - case 3: - LOG(INFO) << "not generating a property change event because of lshal prop: " - << toString(*response); - return StatusCode::OK; - default: - LOG(ERROR) << "invalid action on lshal response: " << toString(*response); - return StatusCode::INTERNAL_ERROR; - } - - LOG(INFO) << "updating property to: " << toString(*updatedValue); - onPropertyValueFromCar(*updatedValue, updateStatus); - - return StatusCode::OK; -} - } // namespace android::hardware::automotive::vehicle::V2_0::impl diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.h index 28e23d5c25..2841fbee3c 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.h +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.h @@ -19,6 +19,7 @@ #include #include +#include "EmulatedUserHal.h" #include "GeneratorHub.h" namespace android::hardware::automotive::vehicle::V2_0::impl { @@ -53,15 +54,10 @@ class VehicleHalServer : public IVehicleServer { VehiclePropValuePtr createHwInputKeyProp(VehicleHwKeyInputAction action, int32_t keyCode, int32_t targetDisplay); - StatusCode onSetInitialUserInfoResponse(const VehiclePropValue& value, bool updateStatus); - StatusCode onSetSwitchUserResponse(const VehiclePropValue& value, bool updateStatus); - // data members protected: - // TODO(b/150413515): it might be clearer to move members below to an EmulatedUserHal class - std::unique_ptr mInitialUserResponseFromCmd; - std::unique_ptr mSwitchUserResponseFromCmd; + EmulatedUserHal mEmulatedUserHal; private: GeneratorHub mGeneratorHub{ -- GitLab From af51663e9980265853750a51fa2f4bb1cd4e48c1 Mon Sep 17 00:00:00 2001 From: David Gross Date: Mon, 14 May 2018 12:23:04 -0700 Subject: [PATCH 042/790] More tests for graph validation. - detect cycle (CycleTest) - detect bad execution order (mutateExecutionOrderTest) - detect lifetime inconsistent with whether operand is written (mutateOperandLifeTimeTest) - detect lifetime inconsistent with Model inputIndexes/outputIndexes (mutateOperandInputOutputTest) - detect incorrect number of consumers (mutateOperandNumberOfConsumersTest) - detect operand written multiple times (mutateOperandAddWriterTest) - detect operand never written (mutateOperationRemoveWriteTest) Bug: 66478689 Test: VtsHalNeuralnetworksV1_*TargetTest Change-Id: Id4ba19660bbd31a16f8a675f7b6437f4d779e8da --- .../1.0/vts/functional/BasicTests.cpp | 136 +++++ neuralnetworks/1.0/vts/functional/Utils.cpp | 43 ++ .../1.0/vts/functional/ValidateModel.cpp | 489 +++++++++++++++- .../1.0/vts/functional/include/1.0/Utils.h | 22 + .../1.1/vts/functional/BasicTests.cpp | 139 +++++ .../1.1/vts/functional/ValidateModel.cpp | 482 +++++++++++++++- neuralnetworks/1.2/vts/functional/Android.bp | 5 +- .../1.2/vts/functional/BasicTests.cpp | 139 +++++ neuralnetworks/1.2/vts/functional/Utils.cpp | 85 +++ .../1.2/vts/functional/ValidateModel.cpp | 520 ++++++++++++++++- .../1.2/vts/functional/include/1.2/Utils.h | 42 ++ neuralnetworks/1.3/vts/functional/Android.bp | 2 +- .../1.3/vts/functional/BasicTests.cpp | 142 +++++ neuralnetworks/1.3/vts/functional/Utils.cpp | 71 ++- .../1.3/vts/functional/ValidateModel.cpp | 538 +++++++++++++++++- .../1.3/vts/functional/include/1.3/Utils.h | 12 + 16 files changed, 2838 insertions(+), 29 deletions(-) create mode 100644 neuralnetworks/1.2/vts/functional/Utils.cpp create mode 100644 neuralnetworks/1.2/vts/functional/include/1.2/Utils.h diff --git a/neuralnetworks/1.0/vts/functional/BasicTests.cpp b/neuralnetworks/1.0/vts/functional/BasicTests.cpp index cc44c9efe1..bda43b1986 100644 --- a/neuralnetworks/1.0/vts/functional/BasicTests.cpp +++ b/neuralnetworks/1.0/vts/functional/BasicTests.cpp @@ -18,8 +18,12 @@ #include "VtsHalNeuralnetworks.h" +#include "1.0/Callbacks.h" + namespace android::hardware::neuralnetworks::V1_0::vts::functional { +using implementation::PreparedModelCallback; + // create device test TEST_P(NeuralnetworksHidlTest, CreateDevice) {} @@ -43,4 +47,136 @@ TEST_P(NeuralnetworksHidlTest, GetCapabilitiesTest) { EXPECT_TRUE(ret.isOk()); } +// detect cycle +TEST_P(NeuralnetworksHidlTest, CycleTest) { + // opnd0 = TENSOR_FLOAT32 // model input + // opnd1 = TENSOR_FLOAT32 // model input + // opnd2 = INT32 // model input + // opnd3 = ADD(opnd0, opnd4, opnd2) + // opnd4 = ADD(opnd1, opnd3, opnd2) + // opnd5 = ADD(opnd4, opnd0, opnd2) // model output + // + // +-----+ + // | | + // v | + // 3 = ADD(0, 4, 2) | + // | | + // +----------+ | + // | | + // v | + // 4 = ADD(1, 3, 2) | + // | | + // +----------------+ + // | + // | + // +-------+ + // | + // v + // 5 = ADD(4, 0, 2) + + const std::vector operands = { + { + // operands[0] + .type = OperandType::TENSOR_FLOAT32, + .dimensions = {1}, + .numberOfConsumers = 2, + .scale = 0.0f, + .zeroPoint = 0, + .lifetime = OperandLifeTime::MODEL_INPUT, + .location = {.poolIndex = 0, .offset = 0, .length = 0}, + }, + { + // operands[1] + .type = OperandType::TENSOR_FLOAT32, + .dimensions = {1}, + .numberOfConsumers = 1, + .scale = 0.0f, + .zeroPoint = 0, + .lifetime = OperandLifeTime::MODEL_INPUT, + .location = {.poolIndex = 0, .offset = 0, .length = 0}, + }, + { + // operands[2] + .type = OperandType::INT32, + .dimensions = {}, + .numberOfConsumers = 3, + .scale = 0.0f, + .zeroPoint = 0, + .lifetime = OperandLifeTime::MODEL_INPUT, + .location = {.poolIndex = 0, .offset = 0, .length = 0}, + }, + { + // operands[3] + .type = OperandType::TENSOR_FLOAT32, + .dimensions = {1}, + .numberOfConsumers = 1, + .scale = 0.0f, + .zeroPoint = 0, + .lifetime = OperandLifeTime::TEMPORARY_VARIABLE, + .location = {.poolIndex = 0, .offset = 0, .length = 0}, + }, + { + // operands[4] + .type = OperandType::TENSOR_FLOAT32, + .dimensions = {1}, + .numberOfConsumers = 2, + .scale = 0.0f, + .zeroPoint = 0, + .lifetime = OperandLifeTime::TEMPORARY_VARIABLE, + .location = {.poolIndex = 0, .offset = 0, .length = 0}, + }, + { + // operands[5] + .type = OperandType::TENSOR_FLOAT32, + .dimensions = {1}, + .numberOfConsumers = 0, + .scale = 0.0f, + .zeroPoint = 0, + .lifetime = OperandLifeTime::MODEL_OUTPUT, + .location = {.poolIndex = 0, .offset = 0, .length = 0}, + }, + }; + + const std::vector operations = { + {.type = OperationType::ADD, .inputs = {0, 4, 2}, .outputs = {3}}, + {.type = OperationType::ADD, .inputs = {1, 3, 2}, .outputs = {4}}, + {.type = OperationType::ADD, .inputs = {4, 0, 2}, .outputs = {5}}, + }; + + const Model model = { + .operands = operands, + .operations = operations, + .inputIndexes = {0, 1, 2}, + .outputIndexes = {5}, + .operandValues = {}, + .pools = {}, + }; + + // ensure that getSupportedOperations() checks model validity + ErrorStatus supportedOpsErrorStatus = ErrorStatus::GENERAL_FAILURE; + Return supportedOpsReturn = kDevice->getSupportedOperations( + model, [&model, &supportedOpsErrorStatus](ErrorStatus status, + const hidl_vec& supported) { + supportedOpsErrorStatus = status; + if (status == ErrorStatus::NONE) { + ASSERT_EQ(supported.size(), model.operations.size()); + } + }); + ASSERT_TRUE(supportedOpsReturn.isOk()); + ASSERT_EQ(supportedOpsErrorStatus, ErrorStatus::INVALID_ARGUMENT); + + // ensure that prepareModel() checks model validity + sp preparedModelCallback = new PreparedModelCallback; + Return prepareLaunchReturn = kDevice->prepareModel(model, preparedModelCallback); + ASSERT_TRUE(prepareLaunchReturn.isOk()); + // Note that preparation can fail for reasons other than an + // invalid model (invalid model should result in + // INVALID_ARGUMENT) -- for example, perhaps not all + // operations are supported, or perhaps the device hit some + // kind of capacity limit. + EXPECT_NE(prepareLaunchReturn, ErrorStatus::NONE); + EXPECT_NE(preparedModelCallback->getStatus(), ErrorStatus::NONE); + EXPECT_EQ(preparedModelCallback->getPreparedModel(), nullptr); +} + } // namespace android::hardware::neuralnetworks::V1_0::vts::functional diff --git a/neuralnetworks/1.0/vts/functional/Utils.cpp b/neuralnetworks/1.0/vts/functional/Utils.cpp index 3613e69088..32850b060c 100644 --- a/neuralnetworks/1.0/vts/functional/Utils.cpp +++ b/neuralnetworks/1.0/vts/functional/Utils.cpp @@ -29,7 +29,11 @@ #include #include +#include +#include #include +#include +#include #include namespace android::hardware::neuralnetworks { @@ -172,6 +176,45 @@ std::vector ExecutionContext::getOutputBuffers(const Request& reques return outputBuffers; } +uint32_t sizeOfData(V1_0::OperandType type) { + switch (type) { + case V1_0::OperandType::FLOAT32: + case V1_0::OperandType::INT32: + case V1_0::OperandType::UINT32: + case V1_0::OperandType::TENSOR_FLOAT32: + case V1_0::OperandType::TENSOR_INT32: + return 4; + case V1_0::OperandType::TENSOR_QUANT8_ASYMM: + return 1; + default: + CHECK(false) << "Invalid OperandType " << static_cast(type); + return 0; + } +} + +static bool isTensor(V1_0::OperandType type) { + switch (type) { + case V1_0::OperandType::FLOAT32: + case V1_0::OperandType::INT32: + case V1_0::OperandType::UINT32: + return false; + case V1_0::OperandType::TENSOR_FLOAT32: + case V1_0::OperandType::TENSOR_INT32: + case V1_0::OperandType::TENSOR_QUANT8_ASYMM: + return true; + default: + CHECK(false) << "Invalid OperandType " << static_cast(type); + return false; + } +} + +uint32_t sizeOfData(const V1_0::Operand& operand) { + const uint32_t dataSize = sizeOfData(operand.type); + if (isTensor(operand.type) && operand.dimensions.size() == 0) return 0; + return std::accumulate(operand.dimensions.begin(), operand.dimensions.end(), dataSize, + std::multiplies<>{}); +} + std::string gtestCompliantName(std::string name) { // gtest test names must only contain alphanumeric characters std::replace_if( diff --git a/neuralnetworks/1.0/vts/functional/ValidateModel.cpp b/neuralnetworks/1.0/vts/functional/ValidateModel.cpp index 79d85943b1..5ffbd4328c 100644 --- a/neuralnetworks/1.0/vts/functional/ValidateModel.cpp +++ b/neuralnetworks/1.0/vts/functional/ValidateModel.cpp @@ -17,9 +17,14 @@ #define LOG_TAG "neuralnetworks_hidl_hal_test" #include "1.0/Callbacks.h" +#include "1.0/Utils.h" #include "GeneratedTestHarness.h" #include "VtsHalNeuralnetworks.h" +#include +#include +#include + namespace android::hardware::neuralnetworks::V1_0::vts::functional { using implementation::PreparedModelCallback; @@ -67,26 +72,6 @@ static void validate(const sp& device, const std::string& message, validatePrepareModel(device, message, model); } -// Delete element from hidl_vec. hidl_vec doesn't support a "remove" operation, -// so this is efficiently accomplished by moving the element to the end and -// resizing the hidl_vec to one less. -template -static void hidl_vec_removeAt(hidl_vec* vec, uint32_t index) { - if (vec) { - std::rotate(vec->begin() + index, vec->begin() + index + 1, vec->end()); - vec->resize(vec->size() - 1); - } -} - -template -static uint32_t hidl_vec_push_back(hidl_vec* vec, const Type& value) { - // assume vec is valid - const uint32_t index = vec->size(); - vec->resize(index + 1); - (*vec)[index] = value; - return index; -} - static uint32_t addOperand(Model* model) { return hidl_vec_push_back(&model->operands, { @@ -107,6 +92,211 @@ static uint32_t addOperand(Model* model, OperandLifeTime lifetime) { return index; } +// If we introduce a CONSTANT_COPY for an operand of size operandSize, +// how much will this increase the size of the model? This assumes +// that we can (re)use all of model.operandValues for the operand +// value. +static size_t constantCopyExtraSize(const Model& model, size_t operandSize) { + const size_t operandValuesSize = model.operandValues.size(); + return (operandValuesSize < operandSize) ? (operandSize - operandValuesSize) : 0; +} + +// Highly specialized utility routine for converting an operand to +// CONSTANT_COPY lifetime. +// +// Expects that: +// - operand has a known size +// - operand->lifetime has already been set to CONSTANT_COPY +// - operand->location has been zeroed out +// +// Does the following: +// - initializes operand->location to point to the beginning of model->operandValues +// - resizes model->operandValues (if necessary) to be large enough for the operand +// value, padding it with zeroes on the end +// +// Potential problem: +// By changing the operand to CONSTANT_COPY lifetime, this function is effectively initializing the +// operand with unspecified (but deterministic) data. This means that the model may be invalidated +// in two ways: not only is the lifetime of CONSTANT_COPY invalid, but the operand's value in the +// graph may also be invalid (e.g., if the operand is used as an activation code and has an invalid +// value). For now, this should be fine because it just means we're not testing what we think we're +// testing in certain cases; but we can handwave this and assume we're probabilistically likely to +// exercise the validation code over the span of the entire test set and operand space. +// +// Aborts if the specified operand type is an extension type or OEM type. +static void becomeConstantCopy(Model* model, Operand* operand) { + // sizeOfData will abort if the specified type is an extension type or OEM type. + const size_t sizeOfOperand = sizeOfData(*operand); + EXPECT_NE(sizeOfOperand, size_t(0)); + operand->location.poolIndex = 0; + operand->location.offset = 0; + operand->location.length = sizeOfOperand; + if (model->operandValues.size() < sizeOfOperand) { + model->operandValues.resize(sizeOfOperand); + } +} + +// The sizeForBinder() functions estimate the size of the +// representation of a value when sent to binder. It's probably a bit +// of an under-estimate, because we don't know the size of the +// metadata in the binder format (e.g., representation of the size of +// a vector); but at least it adds up "big" things like vector +// contents. However, it doesn't treat inter-field or end-of-struct +// padding in a methodical way -- there's no attempt to be consistent +// in whether or not padding in the native (C++) representation +// contributes to the estimated size for the binder representation; +// and there's no attempt to understand what padding (if any) is +// needed in the binder representation. +// +// This assumes that non-metadata uses a fixed length encoding (e.g., +// a uint32_t is always encoded in sizeof(uint32_t) bytes, rather than +// using an encoding whose length is related to the magnitude of the +// encoded value). + +template +static size_t sizeForBinder(const Type& val) { + static_assert(std::is_trivially_copyable_v>, + "expected a trivially copyable type"); + return sizeof(val); +} + +template +static size_t sizeForBinder(const hidl_vec& vec) { + return std::accumulate(vec.begin(), vec.end(), 0, + [](size_t acc, const Type& x) { return acc + sizeForBinder(x); }); +} + +template <> +size_t sizeForBinder(const Operand& operand) { + size_t size = 0; + + size += sizeForBinder(operand.type); + size += sizeForBinder(operand.dimensions); + size += sizeForBinder(operand.numberOfConsumers); + size += sizeForBinder(operand.scale); + size += sizeForBinder(operand.zeroPoint); + size += sizeForBinder(operand.lifetime); + size += sizeForBinder(operand.location); + + return size; +} + +template <> +size_t sizeForBinder(const Operation& operation) { + size_t size = 0; + + size += sizeForBinder(operation.type); + size += sizeForBinder(operation.inputs); + size += sizeForBinder(operation.outputs); + + return size; +} + +template <> +size_t sizeForBinder(const hidl_string& name) { + return name.size(); +} + +template <> +size_t sizeForBinder(const hidl_memory& memory) { + // This is just a guess. + + size_t size = 0; + + if (const native_handle_t* handle = memory.handle()) { + size += sizeof(*handle); + size += sizeof(handle->data[0] * (handle->numFds + handle->numInts)); + } + size += sizeForBinder(memory.name()); + + return size; +} + +template <> +size_t sizeForBinder(const Model& model) { + size_t size = 0; + + size += sizeForBinder(model.operands); + size += sizeForBinder(model.operations); + size += sizeForBinder(model.inputIndexes); + size += sizeForBinder(model.outputIndexes); + size += sizeForBinder(model.operandValues); + size += sizeForBinder(model.pools); + + return size; +} + +// https://developer.android.com/reference/android/os/TransactionTooLargeException.html +// +// "The Binder transaction buffer has a limited fixed size, +// currently 1Mb, which is shared by all transactions in progress +// for the process." +// +// Will our representation fit under this limit? There are two complications: +// - Our representation size is just approximate (see sizeForBinder()). +// - This object may not be the only occupant of the Binder transaction buffer. +// So we'll be very conservative: We want the representation size to be no +// larger than half the transaction buffer size. +// +// If our representation grows large enough that it still fits within +// the transaction buffer but combined with other transactions may +// exceed the buffer size, then we may see intermittent HAL transport +// errors. +static bool exceedsBinderSizeLimit(size_t representationSize) { + // Instead of using this fixed buffer size, we might instead be able to use + // ProcessState::self()->getMmapSize(). However, this has a potential + // problem: The binder/mmap size of the current process does not necessarily + // indicate the binder/mmap size of the service (i.e., the other process). + // The only way it would be a good indication is if both the current process + // and the service use the default size. + static const size_t kHalfBufferSize = 1024 * 1024 / 2; + + return representationSize > kHalfBufferSize; +} + +///////////////////////// VALIDATE EXECUTION ORDER //////////////////////////// + +static void mutateExecutionOrderTest(const sp& device, const V1_0::Model& model) { + for (size_t operation = 0; operation < model.operations.size(); ++operation) { + const Operation& operationObj = model.operations[operation]; + for (uint32_t input : operationObj.inputs) { + if (model.operands[input].lifetime == OperandLifeTime::TEMPORARY_VARIABLE || + model.operands[input].lifetime == OperandLifeTime::MODEL_OUTPUT) { + // This operation reads an operand written by some + // other operation. Move this operation to the + // beginning of the sequence, ensuring that it reads + // the operand before that operand is written, thereby + // violating execution order rules. + const std::string message = "mutateExecutionOrderTest: operation " + + std::to_string(operation) + " is a reader"; + validate(device, message, model, [operation](Model* model) { + auto& operations = model->operations; + std::rotate(operations.begin(), operations.begin() + operation, + operations.begin() + operation + 1); + }); + break; // only need to do this once per operation + } + } + for (uint32_t output : operationObj.outputs) { + if (model.operands[output].numberOfConsumers > 0) { + // This operation writes an operand read by some other + // operation. Move this operation to the end of the + // sequence, ensuring that it writes the operand after + // that operand is read, thereby violating execution + // order rules. + const std::string message = "mutateExecutionOrderTest: operation " + + std::to_string(operation) + " is a writer"; + validate(device, message, model, [operation](Model* model) { + auto& operations = model->operations; + std::rotate(operations.begin() + operation, operations.begin() + operation + 1, + operations.end()); + }); + break; // only need to do this once per operation + } + } + } +} + ///////////////////////// VALIDATE MODEL OPERAND TYPE ///////////////////////// static const int32_t invalidOperandTypes[] = { @@ -218,9 +408,233 @@ static void mutateOperandZeroPointTest(const sp& device, const Model& m } } +///////////////////////// VALIDATE OPERAND LIFETIME ///////////////////////////////////////////// + +static std::vector getInvalidLifeTimes(const Model& model, size_t modelSize, + const Operand& operand) { + // TODO: Support OperandLifeTime::CONSTANT_REFERENCE as an invalid lifetime + // TODO: Support OperandLifeTime::NO_VALUE as an invalid lifetime + + // Ways to get an invalid lifetime: + // - change whether a lifetime means an operand should have a writer + std::vector ret; + switch (operand.lifetime) { + case OperandLifeTime::MODEL_OUTPUT: + case OperandLifeTime::TEMPORARY_VARIABLE: + ret = { + OperandLifeTime::MODEL_INPUT, + OperandLifeTime::CONSTANT_COPY, + }; + break; + case OperandLifeTime::CONSTANT_COPY: + case OperandLifeTime::CONSTANT_REFERENCE: + case OperandLifeTime::MODEL_INPUT: + ret = { + OperandLifeTime::TEMPORARY_VARIABLE, + OperandLifeTime::MODEL_OUTPUT, + }; + break; + case OperandLifeTime::NO_VALUE: + // Not enough information to know whether + // TEMPORARY_VARIABLE or CONSTANT_COPY would be invalid -- + // is this operand written (then CONSTANT_COPY would be + // invalid) or not (then TEMPORARY_VARIABLE would be + // invalid)? + break; + default: + ADD_FAILURE(); + break; + } + + const size_t operandSize = sizeOfData(operand); // will be zero if shape is unknown + if (!operandSize || + exceedsBinderSizeLimit(modelSize + constantCopyExtraSize(model, operandSize))) { + // Unknown size or too-large size + ret.erase(std::remove(ret.begin(), ret.end(), OperandLifeTime::CONSTANT_COPY), ret.end()); + } + + return ret; +} + +static void mutateOperandLifeTimeTest(const sp& device, const V1_0::Model& model) { + const size_t modelSize = sizeForBinder(model); + for (size_t operand = 0; operand < model.operands.size(); ++operand) { + const std::vector invalidLifeTimes = + getInvalidLifeTimes(model, modelSize, model.operands[operand]); + for (OperandLifeTime invalidLifeTime : invalidLifeTimes) { + const std::string message = "mutateOperandLifetimeTest: operand " + + std::to_string(operand) + " has lifetime " + + toString(invalidLifeTime) + " instead of lifetime " + + toString(model.operands[operand].lifetime); + validate(device, message, model, [operand, invalidLifeTime](Model* model) { + static const DataLocation kZeroDataLocation = {}; + Operand& operandObj = model->operands[operand]; + switch (operandObj.lifetime) { + case OperandLifeTime::MODEL_INPUT: { + hidl_vec_remove(&model->inputIndexes, uint32_t(operand)); + break; + } + case OperandLifeTime::MODEL_OUTPUT: { + hidl_vec_remove(&model->outputIndexes, uint32_t(operand)); + break; + } + default: + break; + } + operandObj.lifetime = invalidLifeTime; + operandObj.location = kZeroDataLocation; + switch (invalidLifeTime) { + case OperandLifeTime::CONSTANT_COPY: { + becomeConstantCopy(model, &operandObj); + break; + } + case OperandLifeTime::MODEL_INPUT: + hidl_vec_push_back(&model->inputIndexes, uint32_t(operand)); + break; + case OperandLifeTime::MODEL_OUTPUT: + hidl_vec_push_back(&model->outputIndexes, uint32_t(operand)); + break; + default: + break; + } + }); + } + } +} + +///////////////////////// VALIDATE OPERAND INPUT-or-OUTPUT ////////////////////////////////////// + +static std::optional getInputOutputLifeTime(const Model& model, size_t modelSize, + const Operand& operand) { + // Ways to get an invalid lifetime (with respect to model inputIndexes and outputIndexes): + // - change whether a lifetime means an operand is a model input, a model output, or neither + // - preserve whether or not a lifetime means an operand should have a writer + switch (operand.lifetime) { + case OperandLifeTime::CONSTANT_COPY: + case OperandLifeTime::CONSTANT_REFERENCE: + return OperandLifeTime::MODEL_INPUT; + case OperandLifeTime::MODEL_INPUT: { + const size_t operandSize = sizeOfData(operand); // will be zero if shape is unknown + if (!operandSize || + exceedsBinderSizeLimit(modelSize + constantCopyExtraSize(model, operandSize))) { + // Unknown size or too-large size + break; + } + return OperandLifeTime::CONSTANT_COPY; + } + case OperandLifeTime::MODEL_OUTPUT: + return OperandLifeTime::TEMPORARY_VARIABLE; + case OperandLifeTime::TEMPORARY_VARIABLE: + return OperandLifeTime::MODEL_OUTPUT; + case OperandLifeTime::NO_VALUE: + // Not enough information to know whether + // TEMPORARY_VARIABLE or CONSTANT_COPY would be an + // appropriate choice -- is this operand written (then + // TEMPORARY_VARIABLE would be appropriate) or not (then + // CONSTANT_COPY would be appropriate)? + break; + default: + ADD_FAILURE(); + break; + } + + return std::nullopt; +} + +static void mutateOperandInputOutputTest(const sp& device, const V1_0::Model& model) { + const size_t modelSize = sizeForBinder(model); + for (size_t operand = 0; operand < model.operands.size(); ++operand) { + const std::optional changedLifeTime = + getInputOutputLifeTime(model, modelSize, model.operands[operand]); + if (changedLifeTime) { + const std::string message = "mutateOperandInputOutputTest: operand " + + std::to_string(operand) + " has lifetime " + + toString(*changedLifeTime) + " instead of lifetime " + + toString(model.operands[operand].lifetime); + validate(device, message, model, [operand, changedLifeTime](Model* model) { + static const DataLocation kZeroDataLocation = {}; + Operand& operandObj = model->operands[operand]; + operandObj.lifetime = *changedLifeTime; + operandObj.location = kZeroDataLocation; + if (*changedLifeTime == OperandLifeTime::CONSTANT_COPY) { + becomeConstantCopy(model, &operandObj); + } + }); + } + } +} + +///////////////////////// VALIDATE OPERAND NUMBER OF CONSUMERS ////////////////////////////////// + +static std::vector getInvalidNumberOfConsumers(uint32_t numberOfConsumers) { + if (numberOfConsumers == 0) { + return {1}; + } else { + return {numberOfConsumers - 1, numberOfConsumers + 1}; + } +} + +static void mutateOperandNumberOfConsumersTest(const sp& device, + const V1_0::Model& model) { + for (size_t operand = 0; operand < model.operands.size(); ++operand) { + const std::vector invalidNumberOfConsumersVec = + getInvalidNumberOfConsumers(model.operands[operand].numberOfConsumers); + for (uint32_t invalidNumberOfConsumers : invalidNumberOfConsumersVec) { + const std::string message = + "mutateOperandNumberOfConsumersTest: operand " + std::to_string(operand) + + " numberOfConsumers = " + std::to_string(invalidNumberOfConsumers); + validate(device, message, model, [operand, invalidNumberOfConsumers](Model* model) { + model->operands[operand].numberOfConsumers = invalidNumberOfConsumers; + }); + } + } +} + +///////////////////////// VALIDATE OPERAND NUMBER OF WRITERS //////////////////////////////////// + +static void mutateOperandAddWriterTest(const sp& device, const V1_0::Model& model) { + for (size_t operation = 0; operation < model.operations.size(); ++operation) { + for (size_t badOutputNum = 0; badOutputNum < model.operations[operation].outputs.size(); + ++badOutputNum) { + const uint32_t outputOperandIndex = model.operations[operation].outputs[badOutputNum]; + const std::string message = "mutateOperandAddWriterTest: operation " + + std::to_string(operation) + " writes to " + + std::to_string(outputOperandIndex); + // We'll insert a copy of the operation, all of whose + // OTHER output operands are newly-created -- i.e., + // there'll only be a duplicate write of ONE of that + // operation's output operands. + validate(device, message, model, [operation, badOutputNum](Model* model) { + Operation newOperation = model->operations[operation]; + for (uint32_t input : newOperation.inputs) { + ++model->operands[input].numberOfConsumers; + } + for (size_t outputNum = 0; outputNum < newOperation.outputs.size(); ++outputNum) { + if (outputNum == badOutputNum) continue; + + Operand operandValue = model->operands[newOperation.outputs[outputNum]]; + operandValue.numberOfConsumers = 0; + if (operandValue.lifetime == OperandLifeTime::MODEL_OUTPUT) { + operandValue.lifetime = OperandLifeTime::TEMPORARY_VARIABLE; + } else { + ASSERT_EQ(operandValue.lifetime, OperandLifeTime::TEMPORARY_VARIABLE); + } + newOperation.outputs[outputNum] = + hidl_vec_push_back(&model->operands, operandValue); + } + // Where do we insert the extra writer (a new + // operation)? It has to be later than all the + // writers of its inputs. The easiest thing to do + // is to insert it at the end of the operation + // sequence. + hidl_vec_push_back(&model->operations, newOperation); + }); + } + } +} + ///////////////////////// VALIDATE EXTRA ??? ///////////////////////// -// TODO: Operand::lifetime // TODO: Operand::location ///////////////////////// VALIDATE OPERATION OPERAND TYPE ///////////////////////// @@ -351,6 +765,33 @@ static void mutateOperationOutputOperandIndexTest(const sp& device, con } } +///////////////////////// VALIDATE MODEL OPERANDS WRITTEN /////////////////////////////////////// + +static void mutateOperationRemoveWriteTest(const sp& device, const V1_0::Model& model) { + for (size_t operation = 0; operation < model.operations.size(); ++operation) { + for (size_t outputNum = 0; outputNum < model.operations[operation].outputs.size(); + ++outputNum) { + const uint32_t outputOperandIndex = model.operations[operation].outputs[outputNum]; + if (model.operands[outputOperandIndex].numberOfConsumers > 0) { + const std::string message = "mutateOperationRemoveWriteTest: operation " + + std::to_string(operation) + " writes to " + + std::to_string(outputOperandIndex); + validate(device, message, model, [operation, outputNum](Model* model) { + uint32_t& outputOperandIndex = model->operations[operation].outputs[outputNum]; + Operand operandValue = model->operands[outputOperandIndex]; + operandValue.numberOfConsumers = 0; + if (operandValue.lifetime == OperandLifeTime::MODEL_OUTPUT) { + operandValue.lifetime = OperandLifeTime::TEMPORARY_VARIABLE; + } else { + ASSERT_EQ(operandValue.lifetime, OperandLifeTime::TEMPORARY_VARIABLE); + } + outputOperandIndex = hidl_vec_push_back(&model->operands, operandValue); + }); + } + } + } +} + ///////////////////////// REMOVE OPERAND FROM EVERYTHING ///////////////////////// static void removeValueAndDecrementGreaterValues(hidl_vec* vec, uint32_t value) { @@ -476,14 +917,20 @@ static void addOperationOutputTest(const sp& device, const Model& model ////////////////////////// ENTRY POINT ////////////////////////////// void validateModel(const sp& device, const Model& model) { + mutateExecutionOrderTest(device, model); mutateOperandTypeTest(device, model); mutateOperandRankTest(device, model); mutateOperandScaleTest(device, model); mutateOperandZeroPointTest(device, model); + mutateOperandLifeTimeTest(device, model); + mutateOperandInputOutputTest(device, model); + mutateOperandNumberOfConsumersTest(device, model); + mutateOperandAddWriterTest(device, model); mutateOperationOperandTypeTest(device, model); mutateOperationTypeTest(device, model); mutateOperationInputOperandIndexTest(device, model); mutateOperationOutputOperandIndexTest(device, model); + mutateOperationRemoveWriteTest(device, model); removeOperandTest(device, model); removeOperationTest(device, model); removeOperationInputTest(device, model); diff --git a/neuralnetworks/1.0/vts/functional/include/1.0/Utils.h b/neuralnetworks/1.0/vts/functional/include/1.0/Utils.h index 3292f79b1a..7bd0460b82 100644 --- a/neuralnetworks/1.0/vts/functional/include/1.0/Utils.h +++ b/neuralnetworks/1.0/vts/functional/include/1.0/Utils.h @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -108,6 +109,15 @@ inline void hidl_vec_removeAt(hidl_vec* vec, uint32_t index) { vec->resize(vec->size() - 1); } +// Assumes there is exactly one instance of the value in the vector. +template +inline void hidl_vec_remove(hidl_vec* vec, const Type& val) { + CHECK(vec != nullptr); + auto where = std::find(vec->begin(), vec->end(), val); + ASSERT_NE(where, vec->end()); + hidl_vec_removeAt(vec, where - vec->begin()); +} + template inline uint32_t hidl_vec_push_back(hidl_vec* vec, const Type& value) { CHECK(vec != nullptr); @@ -117,6 +127,18 @@ inline uint32_t hidl_vec_push_back(hidl_vec* vec, const Type& value) { return index; } +// Returns the amount of space needed to store a value of the specified type. +// +// Aborts if the specified type is an extension type or OEM type. +uint32_t sizeOfData(V1_0::OperandType type); + +// Returns the amount of space needed to store a value of the dimensions and +// type of this operand. For a non-extension, non-OEM tensor with unspecified +// rank or at least one unspecified dimension, returns zero. +// +// Aborts if the specified type is an extension type or OEM type. +uint32_t sizeOfData(const V1_0::Operand& operand); + template using Named = std::pair; diff --git a/neuralnetworks/1.1/vts/functional/BasicTests.cpp b/neuralnetworks/1.1/vts/functional/BasicTests.cpp index 44836f0c95..baadd1b23b 100644 --- a/neuralnetworks/1.1/vts/functional/BasicTests.cpp +++ b/neuralnetworks/1.1/vts/functional/BasicTests.cpp @@ -18,10 +18,16 @@ #include "VtsHalNeuralnetworks.h" +#include "1.0/Callbacks.h" + namespace android::hardware::neuralnetworks::V1_1::vts::functional { using V1_0::DeviceStatus; using V1_0::ErrorStatus; +using V1_0::Operand; +using V1_0::OperandLifeTime; +using V1_0::OperandType; +using V1_0::implementation::PreparedModelCallback; // create device test TEST_P(NeuralnetworksHidlTest, CreateDevice) {} @@ -48,4 +54,137 @@ TEST_P(NeuralnetworksHidlTest, GetCapabilitiesTest) { EXPECT_TRUE(ret.isOk()); } +// detect cycle +TEST_P(NeuralnetworksHidlTest, CycleTest) { + // opnd0 = TENSOR_FLOAT32 // model input + // opnd1 = TENSOR_FLOAT32 // model input + // opnd2 = INT32 // model input + // opnd3 = ADD(opnd0, opnd4, opnd2) + // opnd4 = ADD(opnd1, opnd3, opnd2) + // opnd5 = ADD(opnd4, opnd0, opnd2) // model output + // + // +-----+ + // | | + // v | + // 3 = ADD(0, 4, 2) | + // | | + // +----------+ | + // | | + // v | + // 4 = ADD(1, 3, 2) | + // | | + // +----------------+ + // | + // | + // +-------+ + // | + // v + // 5 = ADD(4, 0, 2) + + const std::vector operands = { + { + // operands[0] + .type = OperandType::TENSOR_FLOAT32, + .dimensions = {1}, + .numberOfConsumers = 2, + .scale = 0.0f, + .zeroPoint = 0, + .lifetime = OperandLifeTime::MODEL_INPUT, + .location = {.poolIndex = 0, .offset = 0, .length = 0}, + }, + { + // operands[1] + .type = OperandType::TENSOR_FLOAT32, + .dimensions = {1}, + .numberOfConsumers = 1, + .scale = 0.0f, + .zeroPoint = 0, + .lifetime = OperandLifeTime::MODEL_INPUT, + .location = {.poolIndex = 0, .offset = 0, .length = 0}, + }, + { + // operands[2] + .type = OperandType::INT32, + .dimensions = {}, + .numberOfConsumers = 3, + .scale = 0.0f, + .zeroPoint = 0, + .lifetime = OperandLifeTime::MODEL_INPUT, + .location = {.poolIndex = 0, .offset = 0, .length = 0}, + }, + { + // operands[3] + .type = OperandType::TENSOR_FLOAT32, + .dimensions = {1}, + .numberOfConsumers = 1, + .scale = 0.0f, + .zeroPoint = 0, + .lifetime = OperandLifeTime::TEMPORARY_VARIABLE, + .location = {.poolIndex = 0, .offset = 0, .length = 0}, + }, + { + // operands[4] + .type = OperandType::TENSOR_FLOAT32, + .dimensions = {1}, + .numberOfConsumers = 2, + .scale = 0.0f, + .zeroPoint = 0, + .lifetime = OperandLifeTime::TEMPORARY_VARIABLE, + .location = {.poolIndex = 0, .offset = 0, .length = 0}, + }, + { + // operands[5] + .type = OperandType::TENSOR_FLOAT32, + .dimensions = {1}, + .numberOfConsumers = 0, + .scale = 0.0f, + .zeroPoint = 0, + .lifetime = OperandLifeTime::MODEL_OUTPUT, + .location = {.poolIndex = 0, .offset = 0, .length = 0}, + }, + }; + + const std::vector operations = { + {.type = OperationType::ADD, .inputs = {0, 4, 2}, .outputs = {3}}, + {.type = OperationType::ADD, .inputs = {1, 3, 2}, .outputs = {4}}, + {.type = OperationType::ADD, .inputs = {4, 0, 2}, .outputs = {5}}, + }; + + const Model model = { + .operands = operands, + .operations = operations, + .inputIndexes = {0, 1, 2}, + .outputIndexes = {5}, + .operandValues = {}, + .pools = {}, + }; + + // ensure that getSupportedOperations_1_1() checks model validity + ErrorStatus supportedOpsErrorStatus = ErrorStatus::GENERAL_FAILURE; + Return supportedOpsReturn = kDevice->getSupportedOperations_1_1( + model, [&model, &supportedOpsErrorStatus](ErrorStatus status, + const hidl_vec& supported) { + supportedOpsErrorStatus = status; + if (status == ErrorStatus::NONE) { + ASSERT_EQ(supported.size(), model.operations.size()); + } + }); + ASSERT_TRUE(supportedOpsReturn.isOk()); + ASSERT_EQ(supportedOpsErrorStatus, ErrorStatus::INVALID_ARGUMENT); + + // ensure that prepareModel_1_1() checks model validity + sp preparedModelCallback = new PreparedModelCallback; + Return prepareLaunchReturn = kDevice->prepareModel_1_1( + model, ExecutionPreference::FAST_SINGLE_ANSWER, preparedModelCallback); + ASSERT_TRUE(prepareLaunchReturn.isOk()); + // Note that preparation can fail for reasons other than an + // invalid model (invalid model should result in + // INVALID_ARGUMENT) -- for example, perhaps not all + // operations are supported, or perhaps the device hit some + // kind of capacity limit. + EXPECT_NE(prepareLaunchReturn, ErrorStatus::NONE); + EXPECT_NE(preparedModelCallback->getStatus(), ErrorStatus::NONE); + EXPECT_EQ(preparedModelCallback->getPreparedModel(), nullptr); +} + } // namespace android::hardware::neuralnetworks::V1_1::vts::functional diff --git a/neuralnetworks/1.1/vts/functional/ValidateModel.cpp b/neuralnetworks/1.1/vts/functional/ValidateModel.cpp index 3b6f0f8300..1f4e4eda49 100644 --- a/neuralnetworks/1.1/vts/functional/ValidateModel.cpp +++ b/neuralnetworks/1.1/vts/functional/ValidateModel.cpp @@ -16,13 +16,19 @@ #define LOG_TAG "neuralnetworks_hidl_hal_test" +#include #include "1.0/Callbacks.h" #include "1.0/Utils.h" #include "GeneratedTestHarness.h" #include "VtsHalNeuralnetworks.h" +#include +#include +#include + namespace android::hardware::neuralnetworks::V1_1::vts::functional { +using V1_0::DataLocation; using V1_0::ErrorStatus; using V1_0::IPreparedModel; using V1_0::Operand; @@ -105,6 +111,212 @@ static uint32_t addOperand(Model* model, OperandLifeTime lifetime) { return index; } +// If we introduce a CONSTANT_COPY for an operand of size operandSize, +// how much will this increase the size of the model? This assumes +// that we can (re)use all of model.operandValues for the operand +// value. +static size_t constantCopyExtraSize(const Model& model, size_t operandSize) { + const size_t operandValuesSize = model.operandValues.size(); + return (operandValuesSize < operandSize) ? (operandSize - operandValuesSize) : 0; +} + +// Highly specialized utility routine for converting an operand to +// CONSTANT_COPY lifetime. +// +// Expects that: +// - operand has a known size +// - operand->lifetime has already been set to CONSTANT_COPY +// - operand->location has been zeroed out +// +// Does the following: +// - initializes operand->location to point to the beginning of model->operandValues +// - resizes model->operandValues (if necessary) to be large enough for the operand +// value, padding it with zeroes on the end +// +// Potential problem: +// By changing the operand to CONSTANT_COPY lifetime, this function is effectively initializing the +// operand with unspecified (but deterministic) data. This means that the model may be invalidated +// in two ways: not only is the lifetime of CONSTANT_COPY invalid, but the operand's value in the +// graph may also be invalid (e.g., if the operand is used as an activation code and has an invalid +// value). For now, this should be fine because it just means we're not testing what we think we're +// testing in certain cases; but we can handwave this and assume we're probabilistically likely to +// exercise the validation code over the span of the entire test set and operand space. +// +// Aborts if the specified operand type is an extension type or OEM type. +static void becomeConstantCopy(Model* model, Operand* operand) { + // sizeOfData will abort if the specified type is an extension type or OEM type. + const size_t sizeOfOperand = sizeOfData(*operand); + EXPECT_NE(sizeOfOperand, size_t(0)); + operand->location.poolIndex = 0; + operand->location.offset = 0; + operand->location.length = sizeOfOperand; + if (model->operandValues.size() < sizeOfOperand) { + model->operandValues.resize(sizeOfOperand); + } +} + +// The sizeForBinder() functions estimate the size of the +// representation of a value when sent to binder. It's probably a bit +// of an under-estimate, because we don't know the size of the +// metadata in the binder format (e.g., representation of the size of +// a vector); but at least it adds up "big" things like vector +// contents. However, it doesn't treat inter-field or end-of-struct +// padding in a methodical way -- there's no attempt to be consistent +// in whether or not padding in the native (C++) representation +// contributes to the estimated size for the binder representation; +// and there's no attempt to understand what padding (if any) is +// needed in the binder representation. +// +// This assumes that non-metadata uses a fixed length encoding (e.g., +// a uint32_t is always encoded in sizeof(uint32_t) bytes, rather than +// using an encoding whose length is related to the magnitude of the +// encoded value). + +template +static size_t sizeForBinder(const Type& val) { + static_assert(std::is_trivially_copyable_v>, + "expected a trivially copyable type"); + return sizeof(val); +} + +template +static size_t sizeForBinder(const hidl_vec& vec) { + return std::accumulate(vec.begin(), vec.end(), 0, + [](size_t acc, const Type& x) { return acc + sizeForBinder(x); }); +} + +template <> +size_t sizeForBinder(const Operand& operand) { + size_t size = 0; + + size += sizeForBinder(operand.type); + size += sizeForBinder(operand.dimensions); + size += sizeForBinder(operand.numberOfConsumers); + size += sizeForBinder(operand.scale); + size += sizeForBinder(operand.zeroPoint); + size += sizeForBinder(operand.lifetime); + size += sizeForBinder(operand.location); + + return size; +} + +template <> +size_t sizeForBinder(const Operation& operation) { + size_t size = 0; + + size += sizeForBinder(operation.type); + size += sizeForBinder(operation.inputs); + size += sizeForBinder(operation.outputs); + + return size; +} + +template <> +size_t sizeForBinder(const hidl_string& name) { + return name.size(); +} + +template <> +size_t sizeForBinder(const hidl_memory& memory) { + // This is just a guess. + + size_t size = 0; + + if (const native_handle_t* handle = memory.handle()) { + size += sizeof(*handle); + size += sizeof(handle->data[0] * (handle->numFds + handle->numInts)); + } + size += sizeForBinder(memory.name()); + + return size; +} + +template <> +size_t sizeForBinder(const Model& model) { + size_t size = 0; + + size += sizeForBinder(model.operands); + size += sizeForBinder(model.operations); + size += sizeForBinder(model.inputIndexes); + size += sizeForBinder(model.outputIndexes); + size += sizeForBinder(model.operandValues); + size += sizeForBinder(model.pools); + size += sizeForBinder(model.relaxComputationFloat32toFloat16); + + return size; +} + +// https://developer.android.com/reference/android/os/TransactionTooLargeException.html +// +// "The Binder transaction buffer has a limited fixed size, +// currently 1Mb, which is shared by all transactions in progress +// for the process." +// +// Will our representation fit under this limit? There are two complications: +// - Our representation size is just approximate (see sizeForBinder()). +// - This object may not be the only occupant of the Binder transaction buffer. +// So we'll be very conservative: We want the representation size to be no +// larger than half the transaction buffer size. +// +// If our representation grows large enough that it still fits within +// the transaction buffer but combined with other transactions may +// exceed the buffer size, then we may see intermittent HAL transport +// errors. +static bool exceedsBinderSizeLimit(size_t representationSize) { + // Instead of using this fixed buffer size, we might instead be able to use + // ProcessState::self()->getMmapSize(). However, this has a potential + // problem: The binder/mmap size of the current process does not necessarily + // indicate the binder/mmap size of the service (i.e., the other process). + // The only way it would be a good indication is if both the current process + // and the service use the default size. + static const size_t kHalfBufferSize = 1024 * 1024 / 2; + + return representationSize > kHalfBufferSize; +} + +///////////////////////// VALIDATE EXECUTION ORDER //////////////////////////// + +static void mutateExecutionOrderTest(const sp& device, const V1_1::Model& model) { + for (size_t operation = 0; operation < model.operations.size(); ++operation) { + const Operation& operationObj = model.operations[operation]; + for (uint32_t input : operationObj.inputs) { + if (model.operands[input].lifetime == OperandLifeTime::TEMPORARY_VARIABLE || + model.operands[input].lifetime == OperandLifeTime::MODEL_OUTPUT) { + // This operation reads an operand written by some + // other operation. Move this operation to the + // beginning of the sequence, ensuring that it reads + // the operand before that operand is written, thereby + // violating execution order rules. + const std::string message = "mutateExecutionOrderTest: operation " + + std::to_string(operation) + " is a reader"; + validate(device, message, model, [operation](Model* model, ExecutionPreference*) { + auto& operations = model->operations; + std::rotate(operations.begin(), operations.begin() + operation, + operations.begin() + operation + 1); + }); + break; // only need to do this once per operation + } + } + for (uint32_t output : operationObj.outputs) { + if (model.operands[output].numberOfConsumers > 0) { + // This operation writes an operand read by some other + // operation. Move this operation to the end of the + // sequence, ensuring that it writes the operand after + // that operand is read, thereby violating execution + // order rules. + const std::string message = "mutateExecutionOrderTest: operation " + + std::to_string(operation) + " is a writer"; + validate(device, message, model, [operation](Model* model, ExecutionPreference*) { + auto& operations = model->operations; + std::rotate(operations.begin() + operation, operations.begin() + operation + 1, + operations.end()); + }); + break; // only need to do this once per operation + } + } + } +} + ///////////////////////// VALIDATE MODEL OPERAND TYPE ///////////////////////// static const int32_t invalidOperandTypes[] = { @@ -221,9 +433,240 @@ static void mutateOperandZeroPointTest(const sp& device, const Model& m } } +///////////////////////// VALIDATE OPERAND LIFETIME ///////////////////////////////////////////// + +static std::vector getInvalidLifeTimes(const Model& model, size_t modelSize, + const Operand& operand) { + // TODO: Support OperandLifeTime::CONSTANT_REFERENCE as an invalid lifetime + // TODO: Support OperandLifeTime::NO_VALUE as an invalid lifetime + + // Ways to get an invalid lifetime: + // - change whether a lifetime means an operand should have a writer + std::vector ret; + switch (operand.lifetime) { + case OperandLifeTime::MODEL_OUTPUT: + case OperandLifeTime::TEMPORARY_VARIABLE: + ret = { + OperandLifeTime::MODEL_INPUT, + OperandLifeTime::CONSTANT_COPY, + }; + break; + case OperandLifeTime::CONSTANT_COPY: + case OperandLifeTime::CONSTANT_REFERENCE: + case OperandLifeTime::MODEL_INPUT: + ret = { + OperandLifeTime::TEMPORARY_VARIABLE, + OperandLifeTime::MODEL_OUTPUT, + }; + break; + case OperandLifeTime::NO_VALUE: + // Not enough information to know whether + // TEMPORARY_VARIABLE or CONSTANT_COPY would be invalid -- + // is this operand written (then CONSTANT_COPY would be + // invalid) or not (then TEMPORARY_VARIABLE would be + // invalid)? + break; + default: + ADD_FAILURE(); + break; + } + + const size_t operandSize = sizeOfData(operand); // will be zero if shape is unknown + if (!operandSize || + exceedsBinderSizeLimit(modelSize + constantCopyExtraSize(model, operandSize))) { + // Unknown size or too-large size + ret.erase(std::remove(ret.begin(), ret.end(), OperandLifeTime::CONSTANT_COPY), ret.end()); + } + + return ret; +} + +static void mutateOperandLifeTimeTest(const sp& device, const V1_1::Model& model) { + const size_t modelSize = sizeForBinder(model); + for (size_t operand = 0; operand < model.operands.size(); ++operand) { + const std::vector invalidLifeTimes = + getInvalidLifeTimes(model, modelSize, model.operands[operand]); + for (OperandLifeTime invalidLifeTime : invalidLifeTimes) { + const std::string message = "mutateOperandLifetimeTest: operand " + + std::to_string(operand) + " has lifetime " + + toString(invalidLifeTime) + " instead of lifetime " + + toString(model.operands[operand].lifetime); + validate(device, message, model, + [operand, invalidLifeTime](Model* model, ExecutionPreference*) { + static const DataLocation kZeroDataLocation = {}; + Operand& operandObj = model->operands[operand]; + switch (operandObj.lifetime) { + case OperandLifeTime::MODEL_INPUT: { + hidl_vec_remove(&model->inputIndexes, uint32_t(operand)); + break; + } + case OperandLifeTime::MODEL_OUTPUT: { + hidl_vec_remove(&model->outputIndexes, uint32_t(operand)); + break; + } + default: + break; + } + operandObj.lifetime = invalidLifeTime; + operandObj.location = kZeroDataLocation; + switch (invalidLifeTime) { + case OperandLifeTime::CONSTANT_COPY: { + becomeConstantCopy(model, &operandObj); + break; + } + case OperandLifeTime::MODEL_INPUT: + hidl_vec_push_back(&model->inputIndexes, uint32_t(operand)); + break; + case OperandLifeTime::MODEL_OUTPUT: + hidl_vec_push_back(&model->outputIndexes, uint32_t(operand)); + break; + default: + break; + } + }); + } + } +} + +///////////////////////// VALIDATE OPERAND INPUT-or-OUTPUT ////////////////////////////////////// + +static std::optional getInputOutputLifeTime(const Model& model, size_t modelSize, + const Operand& operand) { + // Ways to get an invalid lifetime (with respect to model inputIndexes and outputIndexes): + // - change whether a lifetime means an operand is a model input, a model output, or neither + // - preserve whether or not a lifetime means an operand should have a writer + switch (operand.lifetime) { + case OperandLifeTime::CONSTANT_COPY: + case OperandLifeTime::CONSTANT_REFERENCE: + return OperandLifeTime::MODEL_INPUT; + case OperandLifeTime::MODEL_INPUT: { + const size_t operandSize = sizeOfData(operand); // will be zero if shape is unknown + if (!operandSize || + exceedsBinderSizeLimit(modelSize + constantCopyExtraSize(model, operandSize))) { + // Unknown size or too-large size + break; + } + return OperandLifeTime::CONSTANT_COPY; + } + case OperandLifeTime::MODEL_OUTPUT: + return OperandLifeTime::TEMPORARY_VARIABLE; + case OperandLifeTime::TEMPORARY_VARIABLE: + return OperandLifeTime::MODEL_OUTPUT; + case OperandLifeTime::NO_VALUE: + // Not enough information to know whether + // TEMPORARY_VARIABLE or CONSTANT_COPY would be an + // appropriate choice -- is this operand written (then + // TEMPORARY_VARIABLE would be appropriate) or not (then + // CONSTANT_COPY would be appropriate)? + break; + default: + ADD_FAILURE(); + break; + } + + return std::nullopt; +} + +static void mutateOperandInputOutputTest(const sp& device, const V1_1::Model& model) { + const size_t modelSize = sizeForBinder(model); + for (size_t operand = 0; operand < model.operands.size(); ++operand) { + const std::optional changedLifeTime = + getInputOutputLifeTime(model, modelSize, model.operands[operand]); + if (changedLifeTime) { + const std::string message = "mutateOperandInputOutputTest: operand " + + std::to_string(operand) + " has lifetime " + + toString(*changedLifeTime) + " instead of lifetime " + + toString(model.operands[operand].lifetime); + validate(device, message, model, + [operand, changedLifeTime](Model* model, ExecutionPreference*) { + static const DataLocation kZeroDataLocation = {}; + Operand& operandObj = model->operands[operand]; + operandObj.lifetime = *changedLifeTime; + operandObj.location = kZeroDataLocation; + if (*changedLifeTime == OperandLifeTime::CONSTANT_COPY) { + becomeConstantCopy(model, &operandObj); + } + }); + } + } +} + +///////////////////////// VALIDATE OPERAND NUMBER OF CONSUMERS ////////////////////////////////// + +static std::vector getInvalidNumberOfConsumers(uint32_t numberOfConsumers) { + if (numberOfConsumers == 0) { + return {1}; + } else { + return {numberOfConsumers - 1, numberOfConsumers + 1}; + } +} + +static void mutateOperandNumberOfConsumersTest(const sp& device, + const V1_1::Model& model) { + for (size_t operand = 0; operand < model.operands.size(); ++operand) { + const std::vector invalidNumberOfConsumersVec = + getInvalidNumberOfConsumers(model.operands[operand].numberOfConsumers); + for (uint32_t invalidNumberOfConsumers : invalidNumberOfConsumersVec) { + const std::string message = + "mutateOperandNumberOfConsumersTest: operand " + std::to_string(operand) + + " numberOfConsumers = " + std::to_string(invalidNumberOfConsumers); + validate(device, message, model, + [operand, invalidNumberOfConsumers](Model* model, ExecutionPreference*) { + model->operands[operand].numberOfConsumers = invalidNumberOfConsumers; + }); + } + } +} + +///////////////////////// VALIDATE OPERAND NUMBER OF WRITERS //////////////////////////////////// + +static void mutateOperandAddWriterTest(const sp& device, const V1_1::Model& model) { + for (size_t operation = 0; operation < model.operations.size(); ++operation) { + for (size_t badOutputNum = 0; badOutputNum < model.operations[operation].outputs.size(); + ++badOutputNum) { + const uint32_t outputOperandIndex = model.operations[operation].outputs[badOutputNum]; + const std::string message = "mutateOperandAddWriterTest: operation " + + std::to_string(operation) + " writes to " + + std::to_string(outputOperandIndex); + // We'll insert a copy of the operation, all of whose + // OTHER output operands are newly-created -- i.e., + // there'll only be a duplicate write of ONE of that + // operation's output operands. + validate(device, message, model, + [operation, badOutputNum](Model* model, ExecutionPreference*) { + Operation newOperation = model->operations[operation]; + for (uint32_t input : newOperation.inputs) { + ++model->operands[input].numberOfConsumers; + } + for (size_t outputNum = 0; outputNum < newOperation.outputs.size(); + ++outputNum) { + if (outputNum == badOutputNum) continue; + + Operand operandValue = + model->operands[newOperation.outputs[outputNum]]; + operandValue.numberOfConsumers = 0; + if (operandValue.lifetime == OperandLifeTime::MODEL_OUTPUT) { + operandValue.lifetime = OperandLifeTime::TEMPORARY_VARIABLE; + } else { + ASSERT_EQ(operandValue.lifetime, + OperandLifeTime::TEMPORARY_VARIABLE); + } + newOperation.outputs[outputNum] = + hidl_vec_push_back(&model->operands, operandValue); + } + // Where do we insert the extra writer (a new + // operation)? It has to be later than all the + // writers of its inputs. The easiest thing to do + // is to insert it at the end of the operation + // sequence. + hidl_vec_push_back(&model->operations, newOperation); + }); + } + } +} + ///////////////////////// VALIDATE EXTRA ??? ///////////////////////// -// TODO: Operand::lifetime // TODO: Operand::location ///////////////////////// VALIDATE OPERATION OPERAND TYPE ///////////////////////// @@ -358,6 +801,37 @@ static void mutateOperationOutputOperandIndexTest(const sp& device, con } } +///////////////////////// VALIDATE MODEL OPERANDS WRITTEN /////////////////////////////////////// + +static void mutateOperationRemoveWriteTest(const sp& device, const V1_1::Model& model) { + for (size_t operation = 0; operation < model.operations.size(); ++operation) { + for (size_t outputNum = 0; outputNum < model.operations[operation].outputs.size(); + ++outputNum) { + const uint32_t outputOperandIndex = model.operations[operation].outputs[outputNum]; + if (model.operands[outputOperandIndex].numberOfConsumers > 0) { + const std::string message = "mutateOperationRemoveWriteTest: operation " + + std::to_string(operation) + " writes to " + + std::to_string(outputOperandIndex); + validate(device, message, model, + [operation, outputNum](Model* model, ExecutionPreference*) { + uint32_t& outputOperandIndex = + model->operations[operation].outputs[outputNum]; + Operand operandValue = model->operands[outputOperandIndex]; + operandValue.numberOfConsumers = 0; + if (operandValue.lifetime == OperandLifeTime::MODEL_OUTPUT) { + operandValue.lifetime = OperandLifeTime::TEMPORARY_VARIABLE; + } else { + ASSERT_EQ(operandValue.lifetime, + OperandLifeTime::TEMPORARY_VARIABLE); + } + outputOperandIndex = + hidl_vec_push_back(&model->operands, operandValue); + }); + } + } + } +} + ///////////////////////// REMOVE OPERAND FROM EVERYTHING ///////////////////////// static void removeValueAndDecrementGreaterValues(hidl_vec* vec, uint32_t value) { @@ -504,14 +978,20 @@ static void mutateExecutionPreferenceTest(const sp& device, const Model ////////////////////////// ENTRY POINT ////////////////////////////// void validateModel(const sp& device, const Model& model) { + mutateExecutionOrderTest(device, model); mutateOperandTypeTest(device, model); mutateOperandRankTest(device, model); mutateOperandScaleTest(device, model); mutateOperandZeroPointTest(device, model); + mutateOperandLifeTimeTest(device, model); + mutateOperandInputOutputTest(device, model); + mutateOperandNumberOfConsumersTest(device, model); + mutateOperandAddWriterTest(device, model); mutateOperationOperandTypeTest(device, model); mutateOperationTypeTest(device, model); mutateOperationInputOperandIndexTest(device, model); mutateOperationOutputOperandIndexTest(device, model); + mutateOperationRemoveWriteTest(device, model); removeOperandTest(device, model); removeOperationTest(device, model); removeOperationInputTest(device, model); diff --git a/neuralnetworks/1.2/vts/functional/Android.bp b/neuralnetworks/1.2/vts/functional/Android.bp index 481eb80258..182f716115 100644 --- a/neuralnetworks/1.2/vts/functional/Android.bp +++ b/neuralnetworks/1.2/vts/functional/Android.bp @@ -15,11 +15,12 @@ // cc_library_static { - name: "VtsHalNeuralNetworksV1_2Callbacks", + name: "VtsHalNeuralNetworksV1_2_utils", defaults: ["neuralnetworks_vts_functional_defaults"], export_include_dirs: ["include"], srcs: [ "Callbacks.cpp", + "Utils.cpp", ], static_libs: [ "android.hardware.neuralnetworks@1.0", @@ -51,7 +52,7 @@ cc_test { ], static_libs: [ "VtsHalNeuralNetworksV1_0_utils", - "VtsHalNeuralNetworksV1_2Callbacks", + "VtsHalNeuralNetworksV1_2_utils", "android.hardware.neuralnetworks@1.0", "android.hardware.neuralnetworks@1.1", "android.hardware.neuralnetworks@1.2", diff --git a/neuralnetworks/1.2/vts/functional/BasicTests.cpp b/neuralnetworks/1.2/vts/functional/BasicTests.cpp index 58d3c4a403..77340e7434 100644 --- a/neuralnetworks/1.2/vts/functional/BasicTests.cpp +++ b/neuralnetworks/1.2/vts/functional/BasicTests.cpp @@ -20,9 +20,13 @@ namespace android::hardware::neuralnetworks::V1_2::vts::functional { +using implementation::PreparedModelCallback; using V1_0::DeviceStatus; using V1_0::ErrorStatus; +using V1_0::OperandLifeTime; using V1_0::PerformanceInfo; +using V1_1::ExecutionPreference; +using HidlToken = hidl_array(Constant::BYTE_SIZE_OF_CACHE_TOKEN)>; // create device test TEST_P(NeuralnetworksHidlTest, CreateDevice) {} @@ -123,4 +127,139 @@ TEST_P(NeuralnetworksHidlTest, getNumberOfCacheFilesNeeded) { }); EXPECT_TRUE(ret.isOk()); } + +// detect cycle +TEST_P(NeuralnetworksHidlTest, CycleTest) { + // opnd0 = TENSOR_FLOAT32 // model input + // opnd1 = TENSOR_FLOAT32 // model input + // opnd2 = INT32 // model input + // opnd3 = ADD(opnd0, opnd4, opnd2) + // opnd4 = ADD(opnd1, opnd3, opnd2) + // opnd5 = ADD(opnd4, opnd0, opnd2) // model output + // + // +-----+ + // | | + // v | + // 3 = ADD(0, 4, 2) | + // | | + // +----------+ | + // | | + // v | + // 4 = ADD(1, 3, 2) | + // | | + // +----------------+ + // | + // | + // +-------+ + // | + // v + // 5 = ADD(4, 0, 2) + + const std::vector operands = { + { + // operands[0] + .type = OperandType::TENSOR_FLOAT32, + .dimensions = {1}, + .numberOfConsumers = 2, + .scale = 0.0f, + .zeroPoint = 0, + .lifetime = OperandLifeTime::MODEL_INPUT, + .location = {.poolIndex = 0, .offset = 0, .length = 0}, + }, + { + // operands[1] + .type = OperandType::TENSOR_FLOAT32, + .dimensions = {1}, + .numberOfConsumers = 1, + .scale = 0.0f, + .zeroPoint = 0, + .lifetime = OperandLifeTime::MODEL_INPUT, + .location = {.poolIndex = 0, .offset = 0, .length = 0}, + }, + { + // operands[2] + .type = OperandType::INT32, + .dimensions = {}, + .numberOfConsumers = 3, + .scale = 0.0f, + .zeroPoint = 0, + .lifetime = OperandLifeTime::MODEL_INPUT, + .location = {.poolIndex = 0, .offset = 0, .length = 0}, + }, + { + // operands[3] + .type = OperandType::TENSOR_FLOAT32, + .dimensions = {1}, + .numberOfConsumers = 1, + .scale = 0.0f, + .zeroPoint = 0, + .lifetime = OperandLifeTime::TEMPORARY_VARIABLE, + .location = {.poolIndex = 0, .offset = 0, .length = 0}, + }, + { + // operands[4] + .type = OperandType::TENSOR_FLOAT32, + .dimensions = {1}, + .numberOfConsumers = 2, + .scale = 0.0f, + .zeroPoint = 0, + .lifetime = OperandLifeTime::TEMPORARY_VARIABLE, + .location = {.poolIndex = 0, .offset = 0, .length = 0}, + }, + { + // operands[5] + .type = OperandType::TENSOR_FLOAT32, + .dimensions = {1}, + .numberOfConsumers = 0, + .scale = 0.0f, + .zeroPoint = 0, + .lifetime = OperandLifeTime::MODEL_OUTPUT, + .location = {.poolIndex = 0, .offset = 0, .length = 0}, + }, + }; + + const std::vector operations = { + {.type = OperationType::ADD, .inputs = {0, 4, 2}, .outputs = {3}}, + {.type = OperationType::ADD, .inputs = {1, 3, 2}, .outputs = {4}}, + {.type = OperationType::ADD, .inputs = {4, 0, 2}, .outputs = {5}}, + }; + + const Model model = { + .operands = operands, + .operations = operations, + .inputIndexes = {0, 1, 2}, + .outputIndexes = {5}, + .operandValues = {}, + .pools = {}, + }; + + // ensure that getSupportedOperations_1_2() checks model validity + ErrorStatus supportedOpsErrorStatus = ErrorStatus::GENERAL_FAILURE; + Return supportedOpsReturn = kDevice->getSupportedOperations_1_2( + model, [&model, &supportedOpsErrorStatus](ErrorStatus status, + const hidl_vec& supported) { + supportedOpsErrorStatus = status; + if (status == ErrorStatus::NONE) { + ASSERT_EQ(supported.size(), model.operations.size()); + } + }); + ASSERT_TRUE(supportedOpsReturn.isOk()); + ASSERT_EQ(supportedOpsErrorStatus, ErrorStatus::INVALID_ARGUMENT); + + // ensure that prepareModel_1_2() checks model validity + sp preparedModelCallback = new PreparedModelCallback; + Return prepareLaunchReturn = kDevice->prepareModel_1_2( + model, ExecutionPreference::FAST_SINGLE_ANSWER, hidl_vec(), + hidl_vec(), HidlToken(), preparedModelCallback); + ASSERT_TRUE(prepareLaunchReturn.isOk()); + // Note that preparation can fail for reasons other than an + // invalid model (invalid model should result in + // INVALID_ARGUMENT) -- for example, perhaps not all + // operations are supported, or perhaps the device hit some + // kind of capacity limit. + EXPECT_NE(prepareLaunchReturn, ErrorStatus::NONE); + EXPECT_NE(preparedModelCallback->getStatus(), ErrorStatus::NONE); + EXPECT_EQ(preparedModelCallback->getPreparedModel(), nullptr); +} + } // namespace android::hardware::neuralnetworks::V1_2::vts::functional diff --git a/neuralnetworks/1.2/vts/functional/Utils.cpp b/neuralnetworks/1.2/vts/functional/Utils.cpp new file mode 100644 index 0000000000..cc654f2c57 --- /dev/null +++ b/neuralnetworks/1.2/vts/functional/Utils.cpp @@ -0,0 +1,85 @@ +/* + * 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 +#include + +#include +#include + +namespace android { +namespace hardware { +namespace neuralnetworks { + +uint32_t sizeOfData(V1_2::OperandType type) { + switch (type) { + case V1_2::OperandType::FLOAT32: + case V1_2::OperandType::INT32: + case V1_2::OperandType::UINT32: + case V1_2::OperandType::TENSOR_FLOAT32: + case V1_2::OperandType::TENSOR_INT32: + return 4; + case V1_2::OperandType::TENSOR_QUANT16_SYMM: + case V1_2::OperandType::TENSOR_FLOAT16: + case V1_2::OperandType::FLOAT16: + case V1_2::OperandType::TENSOR_QUANT16_ASYMM: + return 2; + case V1_2::OperandType::TENSOR_QUANT8_ASYMM: + case V1_2::OperandType::BOOL: + case V1_2::OperandType::TENSOR_BOOL8: + case V1_2::OperandType::TENSOR_QUANT8_SYMM_PER_CHANNEL: + case V1_2::OperandType::TENSOR_QUANT8_SYMM: + return 1; + default: + CHECK(false) << "Invalid OperandType " << static_cast(type); + return 0; + } +} + +static bool isTensor(V1_2::OperandType type) { + switch (type) { + case V1_2::OperandType::FLOAT32: + case V1_2::OperandType::INT32: + case V1_2::OperandType::UINT32: + case V1_2::OperandType::FLOAT16: + case V1_2::OperandType::BOOL: + return false; + case V1_2::OperandType::TENSOR_FLOAT32: + case V1_2::OperandType::TENSOR_INT32: + case V1_2::OperandType::TENSOR_QUANT16_SYMM: + case V1_2::OperandType::TENSOR_FLOAT16: + case V1_2::OperandType::TENSOR_QUANT16_ASYMM: + case V1_2::OperandType::TENSOR_QUANT8_ASYMM: + case V1_2::OperandType::TENSOR_BOOL8: + case V1_2::OperandType::TENSOR_QUANT8_SYMM_PER_CHANNEL: + case V1_2::OperandType::TENSOR_QUANT8_SYMM: + return true; + default: + CHECK(false) << "Invalid OperandType " << static_cast(type); + return false; + } +} + +uint32_t sizeOfData(const V1_2::Operand& operand) { + const uint32_t dataSize = sizeOfData(operand.type); + if (isTensor(operand.type) && operand.dimensions.size() == 0) return 0; + return std::accumulate(operand.dimensions.begin(), operand.dimensions.end(), dataSize, + std::multiplies<>{}); +} + +} // namespace neuralnetworks +} // namespace hardware +} // namespace android diff --git a/neuralnetworks/1.2/vts/functional/ValidateModel.cpp b/neuralnetworks/1.2/vts/functional/ValidateModel.cpp index 7451f095bf..3375602d27 100644 --- a/neuralnetworks/1.2/vts/functional/ValidateModel.cpp +++ b/neuralnetworks/1.2/vts/functional/ValidateModel.cpp @@ -16,14 +16,21 @@ #define LOG_TAG "neuralnetworks_hidl_hal_test" +#include #include "1.0/Utils.h" #include "1.2/Callbacks.h" +#include "1.2/Utils.h" #include "GeneratedTestHarness.h" #include "VtsHalNeuralnetworks.h" +#include +#include +#include + namespace android::hardware::neuralnetworks::V1_2::vts::functional { using implementation::PreparedModelCallback; +using V1_0::DataLocation; using V1_0::ErrorStatus; using V1_0::OperandLifeTime; using V1_1::ExecutionPreference; @@ -105,6 +112,250 @@ static uint32_t addOperand(Model* model, OperandLifeTime lifetime) { return index; } +// If we introduce a CONSTANT_COPY for an operand of size operandSize, +// how much will this increase the size of the model? This assumes +// that we can (re)use all of model.operandValues for the operand +// value. +static size_t constantCopyExtraSize(const Model& model, size_t operandSize) { + const size_t operandValuesSize = model.operandValues.size(); + return (operandValuesSize < operandSize) ? (operandSize - operandValuesSize) : 0; +} + +// Highly specialized utility routine for converting an operand to +// CONSTANT_COPY lifetime. +// +// Expects that: +// - operand has a known size +// - operand->lifetime has already been set to CONSTANT_COPY +// - operand->location has been zeroed out +// +// Does the following: +// - initializes operand->location to point to the beginning of model->operandValues +// - resizes model->operandValues (if necessary) to be large enough for the operand +// value, padding it with zeroes on the end +// +// Potential problem: +// By changing the operand to CONSTANT_COPY lifetime, this function is effectively initializing the +// operand with unspecified (but deterministic) data. This means that the model may be invalidated +// in two ways: not only is the lifetime of CONSTANT_COPY invalid, but the operand's value in the +// graph may also be invalid (e.g., if the operand is used as an activation code and has an invalid +// value). For now, this should be fine because it just means we're not testing what we think we're +// testing in certain cases; but we can handwave this and assume we're probabilistically likely to +// exercise the validation code over the span of the entire test set and operand space. +// +// Aborts if the specified operand type is an extension type or OEM type. +static void becomeConstantCopy(Model* model, Operand* operand) { + // sizeOfData will abort if the specified type is an extension type or OEM type. + const size_t sizeOfOperand = sizeOfData(*operand); + EXPECT_NE(sizeOfOperand, size_t(0)); + operand->location.poolIndex = 0; + operand->location.offset = 0; + operand->location.length = sizeOfOperand; + if (model->operandValues.size() < sizeOfOperand) { + model->operandValues.resize(sizeOfOperand); + } +} + +// The sizeForBinder() functions estimate the size of the +// representation of a value when sent to binder. It's probably a bit +// of an under-estimate, because we don't know the size of the +// metadata in the binder format (e.g., representation of the size of +// a vector); but at least it adds up "big" things like vector +// contents. However, it doesn't treat inter-field or end-of-struct +// padding in a methodical way -- there's no attempt to be consistent +// in whether or not padding in the native (C++) representation +// contributes to the estimated size for the binder representation; +// and there's no attempt to understand what padding (if any) is +// needed in the binder representation. +// +// This assumes that non-metadata uses a fixed length encoding (e.g., +// a uint32_t is always encoded in sizeof(uint32_t) bytes, rather than +// using an encoding whose length is related to the magnitude of the +// encoded value). + +template +static size_t sizeForBinder(const Type& val) { + static_assert(std::is_trivially_copyable_v>, + "expected a trivially copyable type"); + return sizeof(val); +} + +template +static size_t sizeForBinder(const hidl_vec& vec) { + return std::accumulate(vec.begin(), vec.end(), 0, + [](size_t acc, const Type& x) { return acc + sizeForBinder(x); }); +} + +template <> +size_t sizeForBinder(const SymmPerChannelQuantParams& symmPerChannelQuantParams) { + size_t size = 0; + + size += sizeForBinder(symmPerChannelQuantParams.scales); + size += sizeForBinder(symmPerChannelQuantParams.channelDim); + + return size; +} + +template <> +size_t sizeForBinder(const Operand::ExtraParams& extraParams) { + using Discriminator = Operand::ExtraParams::hidl_discriminator; + switch (extraParams.getDiscriminator()) { + case Discriminator::none: + return 0; + case Discriminator::channelQuant: + return sizeForBinder(extraParams.channelQuant()); + case Discriminator::extension: + return sizeForBinder(extraParams.extension()); + } + LOG(FATAL) << "Unrecognized extraParams enum: " + << static_cast(extraParams.getDiscriminator()); + return 0; +} + +template <> +size_t sizeForBinder(const Operand& operand) { + size_t size = 0; + + size += sizeForBinder(operand.type); + size += sizeForBinder(operand.dimensions); + size += sizeForBinder(operand.numberOfConsumers); + size += sizeForBinder(operand.scale); + size += sizeForBinder(operand.zeroPoint); + size += sizeForBinder(operand.lifetime); + size += sizeForBinder(operand.location); + size += sizeForBinder(operand.extraParams); + + return size; +} + +template <> +size_t sizeForBinder(const Operation& operation) { + size_t size = 0; + + size += sizeForBinder(operation.type); + size += sizeForBinder(operation.inputs); + size += sizeForBinder(operation.outputs); + + return size; +} + +template <> +size_t sizeForBinder(const hidl_string& name) { + return name.size(); +} + +template <> +size_t sizeForBinder(const hidl_memory& memory) { + // This is just a guess. + + size_t size = 0; + + if (const native_handle_t* handle = memory.handle()) { + size += sizeof(*handle); + size += sizeof(handle->data[0] * (handle->numFds + handle->numInts)); + } + size += sizeForBinder(memory.name()); + + return size; +} + +template <> +size_t sizeForBinder(const Model::ExtensionNameAndPrefix& extensionNameToPrefix) { + size_t size = 0; + + size += sizeForBinder(extensionNameToPrefix.name); + size += sizeForBinder(extensionNameToPrefix.prefix); + + return size; +} + +template <> +size_t sizeForBinder(const Model& model) { + size_t size = 0; + + size += sizeForBinder(model.operands); + size += sizeForBinder(model.operations); + size += sizeForBinder(model.inputIndexes); + size += sizeForBinder(model.outputIndexes); + size += sizeForBinder(model.operandValues); + size += sizeForBinder(model.pools); + size += sizeForBinder(model.relaxComputationFloat32toFloat16); + size += sizeForBinder(model.extensionNameToPrefix); + + return size; +} + +// https://developer.android.com/reference/android/os/TransactionTooLargeException.html +// +// "The Binder transaction buffer has a limited fixed size, +// currently 1Mb, which is shared by all transactions in progress +// for the process." +// +// Will our representation fit under this limit? There are two complications: +// - Our representation size is just approximate (see sizeForBinder()). +// - This object may not be the only occupant of the Binder transaction buffer. +// So we'll be very conservative: We want the representation size to be no +// larger than half the transaction buffer size. +// +// If our representation grows large enough that it still fits within +// the transaction buffer but combined with other transactions may +// exceed the buffer size, then we may see intermittent HAL transport +// errors. +static bool exceedsBinderSizeLimit(size_t representationSize) { + // Instead of using this fixed buffer size, we might instead be able to use + // ProcessState::self()->getMmapSize(). However, this has a potential + // problem: The binder/mmap size of the current process does not necessarily + // indicate the binder/mmap size of the service (i.e., the other process). + // The only way it would be a good indication is if both the current process + // and the service use the default size. + static const size_t kHalfBufferSize = 1024 * 1024 / 2; + + return representationSize > kHalfBufferSize; +} + +///////////////////////// VALIDATE EXECUTION ORDER //////////////////////////// + +static void mutateExecutionOrderTest(const sp& device, const Model& model) { + for (size_t operation = 0; operation < model.operations.size(); ++operation) { + const Operation& operationObj = model.operations[operation]; + for (uint32_t input : operationObj.inputs) { + if (model.operands[input].lifetime == OperandLifeTime::TEMPORARY_VARIABLE || + model.operands[input].lifetime == OperandLifeTime::MODEL_OUTPUT) { + // This operation reads an operand written by some + // other operation. Move this operation to the + // beginning of the sequence, ensuring that it reads + // the operand before that operand is written, thereby + // violating execution order rules. + const std::string message = "mutateExecutionOrderTest: operation " + + std::to_string(operation) + " is a reader"; + validate(device, message, model, [operation](Model* model, ExecutionPreference*) { + auto& operations = model->operations; + std::rotate(operations.begin(), operations.begin() + operation, + operations.begin() + operation + 1); + }); + break; // only need to do this once per operation + } + } + for (uint32_t output : operationObj.outputs) { + if (model.operands[output].numberOfConsumers > 0) { + // This operation writes an operand read by some other + // operation. Move this operation to the end of the + // sequence, ensuring that it writes the operand after + // that operand is read, thereby violating execution + // order rules. + const std::string message = "mutateExecutionOrderTest: operation " + + std::to_string(operation) + " is a writer"; + validate(device, message, model, [operation](Model* model, ExecutionPreference*) { + auto& operations = model->operations; + std::rotate(operations.begin() + operation, operations.begin() + operation + 1, + operations.end()); + }); + break; // only need to do this once per operation + } + } + } +} + ///////////////////////// VALIDATE MODEL OPERAND TYPE ///////////////////////// static const uint32_t invalidOperandTypes[] = { @@ -251,9 +502,239 @@ static void mutateOperandZeroPointTest(const sp& device, const Model& m } } +///////////////////////// VALIDATE OPERAND LIFETIME ///////////////////////////////////////////// + +static std::vector getInvalidLifeTimes(const Model& model, size_t modelSize, + const Operand& operand) { + // TODO: Support OperandLifeTime::CONSTANT_REFERENCE as an invalid lifetime + // TODO: Support OperandLifeTime::NO_VALUE as an invalid lifetime + + // Ways to get an invalid lifetime: + // - change whether a lifetime means an operand should have a writer + std::vector ret; + switch (operand.lifetime) { + case OperandLifeTime::MODEL_OUTPUT: + case OperandLifeTime::TEMPORARY_VARIABLE: + ret = { + OperandLifeTime::MODEL_INPUT, + OperandLifeTime::CONSTANT_COPY, + }; + break; + case OperandLifeTime::CONSTANT_COPY: + case OperandLifeTime::CONSTANT_REFERENCE: + case OperandLifeTime::MODEL_INPUT: + ret = { + OperandLifeTime::TEMPORARY_VARIABLE, + OperandLifeTime::MODEL_OUTPUT, + }; + break; + case OperandLifeTime::NO_VALUE: + // Not enough information to know whether + // TEMPORARY_VARIABLE or CONSTANT_COPY would be invalid -- + // is this operand written (then CONSTANT_COPY would be + // invalid) or not (then TEMPORARY_VARIABLE would be + // invalid)? + break; + default: + ADD_FAILURE(); + break; + } + + const size_t operandSize = sizeOfData(operand); // will be zero if shape is unknown + if (!operandSize || + exceedsBinderSizeLimit(modelSize + constantCopyExtraSize(model, operandSize))) { + // Unknown size or too-large size + ret.erase(std::remove(ret.begin(), ret.end(), OperandLifeTime::CONSTANT_COPY), ret.end()); + } + + return ret; +} + +static void mutateOperandLifeTimeTest(const sp& device, const Model& model) { + const size_t modelSize = sizeForBinder(model); + for (size_t operand = 0; operand < model.operands.size(); ++operand) { + const std::vector invalidLifeTimes = + getInvalidLifeTimes(model, modelSize, model.operands[operand]); + for (OperandLifeTime invalidLifeTime : invalidLifeTimes) { + const std::string message = "mutateOperandLifetimeTest: operand " + + std::to_string(operand) + " has lifetime " + + toString(invalidLifeTime) + " instead of lifetime " + + toString(model.operands[operand].lifetime); + validate(device, message, model, + [operand, invalidLifeTime](Model* model, ExecutionPreference*) { + static const DataLocation kZeroDataLocation = {}; + Operand& operandObj = model->operands[operand]; + switch (operandObj.lifetime) { + case OperandLifeTime::MODEL_INPUT: { + hidl_vec_remove(&model->inputIndexes, uint32_t(operand)); + break; + } + case OperandLifeTime::MODEL_OUTPUT: { + hidl_vec_remove(&model->outputIndexes, uint32_t(operand)); + break; + } + default: + break; + } + operandObj.lifetime = invalidLifeTime; + operandObj.location = kZeroDataLocation; + switch (invalidLifeTime) { + case OperandLifeTime::CONSTANT_COPY: { + becomeConstantCopy(model, &operandObj); + break; + } + case OperandLifeTime::MODEL_INPUT: + hidl_vec_push_back(&model->inputIndexes, uint32_t(operand)); + break; + case OperandLifeTime::MODEL_OUTPUT: + hidl_vec_push_back(&model->outputIndexes, uint32_t(operand)); + break; + default: + break; + } + }); + } + } +} + +///////////////////////// VALIDATE OPERAND INPUT-or-OUTPUT ////////////////////////////////////// + +static std::optional getInputOutputLifeTime(const Model& model, size_t modelSize, + const Operand& operand) { + // Ways to get an invalid lifetime (with respect to model inputIndexes and outputIndexes): + // - change whether a lifetime means an operand is a model input, a model output, or neither + // - preserve whether or not a lifetime means an operand should have a writer + switch (operand.lifetime) { + case OperandLifeTime::CONSTANT_COPY: + case OperandLifeTime::CONSTANT_REFERENCE: + return OperandLifeTime::MODEL_INPUT; + case OperandLifeTime::MODEL_INPUT: { + const size_t operandSize = sizeOfData(operand); // will be zero if shape is unknown + if (!operandSize || + exceedsBinderSizeLimit(modelSize + constantCopyExtraSize(model, operandSize))) { + // Unknown size or too-large size + break; + } + return OperandLifeTime::CONSTANT_COPY; + } + case OperandLifeTime::MODEL_OUTPUT: + return OperandLifeTime::TEMPORARY_VARIABLE; + case OperandLifeTime::TEMPORARY_VARIABLE: + return OperandLifeTime::MODEL_OUTPUT; + case OperandLifeTime::NO_VALUE: + // Not enough information to know whether + // TEMPORARY_VARIABLE or CONSTANT_COPY would be an + // appropriate choice -- is this operand written (then + // TEMPORARY_VARIABLE would be appropriate) or not (then + // CONSTANT_COPY would be appropriate)? + break; + default: + ADD_FAILURE(); + break; + } + + return std::nullopt; +} + +static void mutateOperandInputOutputTest(const sp& device, const Model& model) { + const size_t modelSize = sizeForBinder(model); + for (size_t operand = 0; operand < model.operands.size(); ++operand) { + const std::optional changedLifeTime = + getInputOutputLifeTime(model, modelSize, model.operands[operand]); + if (changedLifeTime) { + const std::string message = "mutateOperandInputOutputTest: operand " + + std::to_string(operand) + " has lifetime " + + toString(*changedLifeTime) + " instead of lifetime " + + toString(model.operands[operand].lifetime); + validate(device, message, model, + [operand, changedLifeTime](Model* model, ExecutionPreference*) { + static const DataLocation kZeroDataLocation = {}; + Operand& operandObj = model->operands[operand]; + operandObj.lifetime = *changedLifeTime; + operandObj.location = kZeroDataLocation; + if (*changedLifeTime == OperandLifeTime::CONSTANT_COPY) { + becomeConstantCopy(model, &operandObj); + } + }); + } + } +} + +///////////////////////// VALIDATE OPERAND NUMBER OF CONSUMERS ////////////////////////////////// + +static std::vector getInvalidNumberOfConsumers(uint32_t numberOfConsumers) { + if (numberOfConsumers == 0) { + return {1}; + } else { + return {numberOfConsumers - 1, numberOfConsumers + 1}; + } +} + +static void mutateOperandNumberOfConsumersTest(const sp& device, const Model& model) { + for (size_t operand = 0; operand < model.operands.size(); ++operand) { + const std::vector invalidNumberOfConsumersVec = + getInvalidNumberOfConsumers(model.operands[operand].numberOfConsumers); + for (uint32_t invalidNumberOfConsumers : invalidNumberOfConsumersVec) { + const std::string message = + "mutateOperandNumberOfConsumersTest: operand " + std::to_string(operand) + + " numberOfConsumers = " + std::to_string(invalidNumberOfConsumers); + validate(device, message, model, + [operand, invalidNumberOfConsumers](Model* model, ExecutionPreference*) { + model->operands[operand].numberOfConsumers = invalidNumberOfConsumers; + }); + } + } +} + +///////////////////////// VALIDATE OPERAND NUMBER OF WRITERS //////////////////////////////////// + +static void mutateOperandAddWriterTest(const sp& device, const Model& model) { + for (size_t operation = 0; operation < model.operations.size(); ++operation) { + for (size_t badOutputNum = 0; badOutputNum < model.operations[operation].outputs.size(); + ++badOutputNum) { + const uint32_t outputOperandIndex = model.operations[operation].outputs[badOutputNum]; + const std::string message = "mutateOperandAddWriterTest: operation " + + std::to_string(operation) + " writes to " + + std::to_string(outputOperandIndex); + // We'll insert a copy of the operation, all of whose + // OTHER output operands are newly-created -- i.e., + // there'll only be a duplicate write of ONE of that + // operation's output operands. + validate(device, message, model, + [operation, badOutputNum](Model* model, ExecutionPreference*) { + Operation newOperation = model->operations[operation]; + for (uint32_t input : newOperation.inputs) { + ++model->operands[input].numberOfConsumers; + } + for (size_t outputNum = 0; outputNum < newOperation.outputs.size(); + ++outputNum) { + if (outputNum == badOutputNum) continue; + + Operand operandValue = + model->operands[newOperation.outputs[outputNum]]; + operandValue.numberOfConsumers = 0; + if (operandValue.lifetime == OperandLifeTime::MODEL_OUTPUT) { + operandValue.lifetime = OperandLifeTime::TEMPORARY_VARIABLE; + } else { + ASSERT_EQ(operandValue.lifetime, + OperandLifeTime::TEMPORARY_VARIABLE); + } + newOperation.outputs[outputNum] = + hidl_vec_push_back(&model->operands, operandValue); + } + // Where do we insert the extra writer (a new + // operation)? It has to be later than all the + // writers of its inputs. The easiest thing to do + // is to insert it at the end of the operation + // sequence. + hidl_vec_push_back(&model->operations, newOperation); + }); + } + } +} + ///////////////////////// VALIDATE EXTRA ??? ///////////////////////// -// TODO: Operand::lifetime // TODO: Operand::location ///////////////////////// VALIDATE OPERATION OPERAND TYPE ///////////////////////// @@ -461,6 +942,37 @@ static void mutateOperationOutputOperandIndexTest(const sp& device, con } } +///////////////////////// VALIDATE MODEL OPERANDS WRITTEN /////////////////////////////////////// + +static void mutateOperationRemoveWriteTest(const sp& device, const Model& model) { + for (size_t operation = 0; operation < model.operations.size(); ++operation) { + for (size_t outputNum = 0; outputNum < model.operations[operation].outputs.size(); + ++outputNum) { + const uint32_t outputOperandIndex = model.operations[operation].outputs[outputNum]; + if (model.operands[outputOperandIndex].numberOfConsumers > 0) { + const std::string message = "mutateOperationRemoveWriteTest: operation " + + std::to_string(operation) + " writes to " + + std::to_string(outputOperandIndex); + validate(device, message, model, + [operation, outputNum](Model* model, ExecutionPreference*) { + uint32_t& outputOperandIndex = + model->operations[operation].outputs[outputNum]; + Operand operandValue = model->operands[outputOperandIndex]; + operandValue.numberOfConsumers = 0; + if (operandValue.lifetime == OperandLifeTime::MODEL_OUTPUT) { + operandValue.lifetime = OperandLifeTime::TEMPORARY_VARIABLE; + } else { + ASSERT_EQ(operandValue.lifetime, + OperandLifeTime::TEMPORARY_VARIABLE); + } + outputOperandIndex = + hidl_vec_push_back(&model->operands, operandValue); + }); + } + } + } +} + ///////////////////////// REMOVE OPERAND FROM EVERYTHING ///////////////////////// static void removeValueAndDecrementGreaterValues(hidl_vec* vec, uint32_t value) { @@ -711,14 +1223,20 @@ static void mutateExecutionPreferenceTest(const sp& device, const Model ////////////////////////// ENTRY POINT ////////////////////////////// void validateModel(const sp& device, const Model& model) { + mutateExecutionOrderTest(device, model); mutateOperandTypeTest(device, model); mutateOperandRankTest(device, model); mutateOperandScaleTest(device, model); mutateOperandZeroPointTest(device, model); + mutateOperandLifeTimeTest(device, model); + mutateOperandInputOutputTest(device, model); + mutateOperandNumberOfConsumersTest(device, model); + mutateOperandAddWriterTest(device, model); mutateOperationOperandTypeTest(device, model); mutateOperationTypeTest(device, model); mutateOperationInputOperandIndexTest(device, model); mutateOperationOutputOperandIndexTest(device, model); + mutateOperationRemoveWriteTest(device, model); removeOperandTest(device, model); removeOperationTest(device, model); removeOperationInputTest(device, model); diff --git a/neuralnetworks/1.2/vts/functional/include/1.2/Utils.h b/neuralnetworks/1.2/vts/functional/include/1.2/Utils.h new file mode 100644 index 0000000000..61a8d7485a --- /dev/null +++ b/neuralnetworks/1.2/vts/functional/include/1.2/Utils.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_NEURALNETWORKS_V1_2_UTILS_H +#define ANDROID_HARDWARE_NEURALNETWORKS_V1_2_UTILS_H + +#include + +namespace android { +namespace hardware { +namespace neuralnetworks { + +// Returns the amount of space needed to store a value of the specified type. +// +// Aborts if the specified type is an extension type or OEM type. +uint32_t sizeOfData(V1_2::OperandType type); + +// Returns the amount of space needed to store a value of the dimensions and +// type of this operand. For a non-extension, non-OEM tensor with unspecified +// rank or at least one unspecified dimension, returns zero. +// +// Aborts if the specified type is an extension type or OEM type. +uint32_t sizeOfData(const V1_2::Operand& operand); + +} // namespace neuralnetworks +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_NEURALNETWORKS_V1_2_UTILS_H diff --git a/neuralnetworks/1.3/vts/functional/Android.bp b/neuralnetworks/1.3/vts/functional/Android.bp index 2c1be0b008..771fc54e0d 100644 --- a/neuralnetworks/1.3/vts/functional/Android.bp +++ b/neuralnetworks/1.3/vts/functional/Android.bp @@ -54,7 +54,7 @@ cc_test { ], static_libs: [ "VtsHalNeuralNetworksV1_0_utils", - "VtsHalNeuralNetworksV1_2Callbacks", + "VtsHalNeuralNetworksV1_2_utils", "VtsHalNeuralNetworksV1_3_utils", "android.hardware.neuralnetworks@1.0", "android.hardware.neuralnetworks@1.1", diff --git a/neuralnetworks/1.3/vts/functional/BasicTests.cpp b/neuralnetworks/1.3/vts/functional/BasicTests.cpp index 1c2536983e..6fcfc3482d 100644 --- a/neuralnetworks/1.3/vts/functional/BasicTests.cpp +++ b/neuralnetworks/1.3/vts/functional/BasicTests.cpp @@ -20,11 +20,14 @@ namespace android::hardware::neuralnetworks::V1_3::vts::functional { +using implementation::PreparedModelCallback; using V1_0::DeviceStatus; using V1_0::PerformanceInfo; +using V1_1::ExecutionPreference; using V1_2::Constant; using V1_2::DeviceType; using V1_2::Extension; +using HidlToken = hidl_array(Constant::BYTE_SIZE_OF_CACHE_TOKEN)>; // create device test TEST_P(NeuralnetworksHidlTest, CreateDevice) {} @@ -65,4 +68,143 @@ TEST_P(NeuralnetworksHidlTest, GetCapabilitiesTest) { }); EXPECT_TRUE(ret.isOk()); } + +// detect cycle +TEST_P(NeuralnetworksHidlTest, CycleTest) { + // opnd0 = TENSOR_FLOAT32 // model input + // opnd1 = TENSOR_FLOAT32 // model input + // opnd2 = INT32 // model input + // opnd3 = ADD(opnd0, opnd4, opnd2) + // opnd4 = ADD(opnd1, opnd3, opnd2) + // opnd5 = ADD(opnd4, opnd0, opnd2) // model output + // + // +-----+ + // | | + // v | + // 3 = ADD(0, 4, 2) | + // | | + // +----------+ | + // | | + // v | + // 4 = ADD(1, 3, 2) | + // | | + // +----------------+ + // | + // | + // +-------+ + // | + // v + // 5 = ADD(4, 0, 2) + + const std::vector operands = { + { + // operands[0] + .type = OperandType::TENSOR_FLOAT32, + .dimensions = {1}, + .numberOfConsumers = 2, + .scale = 0.0f, + .zeroPoint = 0, + .lifetime = OperandLifeTime::SUBGRAPH_INPUT, + .location = {.poolIndex = 0, .offset = 0, .length = 0}, + }, + { + // operands[1] + .type = OperandType::TENSOR_FLOAT32, + .dimensions = {1}, + .numberOfConsumers = 1, + .scale = 0.0f, + .zeroPoint = 0, + .lifetime = OperandLifeTime::SUBGRAPH_INPUT, + .location = {.poolIndex = 0, .offset = 0, .length = 0}, + }, + { + // operands[2] + .type = OperandType::INT32, + .dimensions = {}, + .numberOfConsumers = 3, + .scale = 0.0f, + .zeroPoint = 0, + .lifetime = OperandLifeTime::SUBGRAPH_INPUT, + .location = {.poolIndex = 0, .offset = 0, .length = 0}, + }, + { + // operands[3] + .type = OperandType::TENSOR_FLOAT32, + .dimensions = {1}, + .numberOfConsumers = 1, + .scale = 0.0f, + .zeroPoint = 0, + .lifetime = OperandLifeTime::TEMPORARY_VARIABLE, + .location = {.poolIndex = 0, .offset = 0, .length = 0}, + }, + { + // operands[4] + .type = OperandType::TENSOR_FLOAT32, + .dimensions = {1}, + .numberOfConsumers = 2, + .scale = 0.0f, + .zeroPoint = 0, + .lifetime = OperandLifeTime::TEMPORARY_VARIABLE, + .location = {.poolIndex = 0, .offset = 0, .length = 0}, + }, + { + // operands[5] + .type = OperandType::TENSOR_FLOAT32, + .dimensions = {1}, + .numberOfConsumers = 0, + .scale = 0.0f, + .zeroPoint = 0, + .lifetime = OperandLifeTime::SUBGRAPH_OUTPUT, + .location = {.poolIndex = 0, .offset = 0, .length = 0}, + }, + }; + + const std::vector operations = { + {.type = OperationType::ADD, .inputs = {0, 4, 2}, .outputs = {3}}, + {.type = OperationType::ADD, .inputs = {1, 3, 2}, .outputs = {4}}, + {.type = OperationType::ADD, .inputs = {4, 0, 2}, .outputs = {5}}, + }; + + Subgraph subgraph = { + .operands = operands, + .operations = operations, + .inputIndexes = {0, 1, 2}, + .outputIndexes = {5}, + }; + const Model model = { + .main = std::move(subgraph), + .referenced = {}, + .operandValues = {}, + .pools = {}, + }; + + // ensure that getSupportedOperations_1_2() checks model validity + ErrorStatus supportedOpsErrorStatus = ErrorStatus::GENERAL_FAILURE; + Return supportedOpsReturn = kDevice->getSupportedOperations_1_3( + model, [&model, &supportedOpsErrorStatus](ErrorStatus status, + const hidl_vec& supported) { + supportedOpsErrorStatus = status; + if (status == ErrorStatus::NONE) { + ASSERT_EQ(supported.size(), model.main.operations.size()); + } + }); + ASSERT_TRUE(supportedOpsReturn.isOk()); + ASSERT_EQ(supportedOpsErrorStatus, ErrorStatus::INVALID_ARGUMENT); + + // ensure that prepareModel_1_3() checks model validity + sp preparedModelCallback = new PreparedModelCallback; + Return prepareLaunchReturn = kDevice->prepareModel_1_3( + model, ExecutionPreference::FAST_SINGLE_ANSWER, Priority::MEDIUM, {}, + hidl_vec(), hidl_vec(), HidlToken(), preparedModelCallback); + ASSERT_TRUE(prepareLaunchReturn.isOk()); + // Note that preparation can fail for reasons other than an + // invalid model (invalid model should result in + // INVALID_ARGUMENT) -- for example, perhaps not all + // operations are supported, or perhaps the device hit some + // kind of capacity limit. + EXPECT_NE(prepareLaunchReturn, ErrorStatus::NONE); + EXPECT_NE(preparedModelCallback->getStatus(), ErrorStatus::NONE); + EXPECT_EQ(preparedModelCallback->getPreparedModel(), nullptr); +} + } // namespace android::hardware::neuralnetworks::V1_3::vts::functional diff --git a/neuralnetworks/1.3/vts/functional/Utils.cpp b/neuralnetworks/1.3/vts/functional/Utils.cpp index 23e2af823e..c460e1127b 100644 --- a/neuralnetworks/1.3/vts/functional/Utils.cpp +++ b/neuralnetworks/1.3/vts/functional/Utils.cpp @@ -17,11 +17,78 @@ #include "1.3/Utils.h" #include +#include +#include "android-base/logging.h" +#include "android/hardware/neuralnetworks/1.3/types.h" -namespace android::hardware::neuralnetworks::V1_3 { +namespace android::hardware::neuralnetworks { + +uint32_t sizeOfData(V1_3::OperandType type) { + switch (type) { + case V1_3::OperandType::FLOAT32: + case V1_3::OperandType::INT32: + case V1_3::OperandType::UINT32: + case V1_3::OperandType::TENSOR_FLOAT32: + case V1_3::OperandType::TENSOR_INT32: + return 4; + case V1_3::OperandType::TENSOR_QUANT16_SYMM: + case V1_3::OperandType::TENSOR_FLOAT16: + case V1_3::OperandType::FLOAT16: + case V1_3::OperandType::TENSOR_QUANT16_ASYMM: + return 2; + case V1_3::OperandType::TENSOR_QUANT8_ASYMM: + case V1_3::OperandType::BOOL: + case V1_3::OperandType::TENSOR_BOOL8: + case V1_3::OperandType::TENSOR_QUANT8_SYMM_PER_CHANNEL: + case V1_3::OperandType::TENSOR_QUANT8_SYMM: + case V1_3::OperandType::TENSOR_QUANT8_ASYMM_SIGNED: + return 1; + case V1_3::OperandType::SUBGRAPH: + return 0; + default: + CHECK(false) << "Invalid OperandType " << static_cast(type); + return 0; + } +} + +static bool isTensor(V1_3::OperandType type) { + switch (type) { + case V1_3::OperandType::FLOAT32: + case V1_3::OperandType::INT32: + case V1_3::OperandType::UINT32: + case V1_3::OperandType::FLOAT16: + case V1_3::OperandType::BOOL: + case V1_3::OperandType::SUBGRAPH: + return false; + case V1_3::OperandType::TENSOR_FLOAT32: + case V1_3::OperandType::TENSOR_INT32: + case V1_3::OperandType::TENSOR_QUANT16_SYMM: + case V1_3::OperandType::TENSOR_FLOAT16: + case V1_3::OperandType::TENSOR_QUANT16_ASYMM: + case V1_3::OperandType::TENSOR_QUANT8_ASYMM: + case V1_3::OperandType::TENSOR_BOOL8: + case V1_3::OperandType::TENSOR_QUANT8_SYMM_PER_CHANNEL: + case V1_3::OperandType::TENSOR_QUANT8_SYMM: + case V1_3::OperandType::TENSOR_QUANT8_ASYMM_SIGNED: + return true; + default: + CHECK(false) << "Invalid OperandType " << static_cast(type); + return false; + } +} + +uint32_t sizeOfData(const V1_3::Operand& operand) { + const uint32_t dataSize = sizeOfData(operand.type); + if (isTensor(operand.type) && operand.dimensions.size() == 0) return 0; + return std::accumulate(operand.dimensions.begin(), operand.dimensions.end(), dataSize, + std::multiplies<>{}); +} + +namespace V1_3 { ::std::ostream& operator<<(::std::ostream& os, ErrorStatus errorStatus) { return os << toString(errorStatus); } -} // namespace android::hardware::neuralnetworks::V1_3 +} // namespace V1_3 +} // namespace android::hardware::neuralnetworks diff --git a/neuralnetworks/1.3/vts/functional/ValidateModel.cpp b/neuralnetworks/1.3/vts/functional/ValidateModel.cpp index e590fdad2d..849ef7bf50 100644 --- a/neuralnetworks/1.3/vts/functional/ValidateModel.cpp +++ b/neuralnetworks/1.3/vts/functional/ValidateModel.cpp @@ -16,15 +16,22 @@ #define LOG_TAG "neuralnetworks_hidl_hal_test" +#include +#include #include "1.0/Utils.h" #include "1.3/Callbacks.h" #include "1.3/Utils.h" #include "GeneratedTestHarness.h" #include "VtsHalNeuralnetworks.h" +#include +#include +#include + namespace android::hardware::neuralnetworks::V1_3::vts::functional { using implementation::PreparedModelCallback; +using V1_0::DataLocation; using V1_1::ExecutionPreference; using V1_2::SymmPerChannelQuantParams; using HidlToken = @@ -112,6 +119,262 @@ static uint32_t addOperand(Model* model, OperandLifeTime lifetime) { return index; } +// If we introduce a CONSTANT_COPY for an operand of size operandSize, +// how much will this increase the size of the model? This assumes +// that we can (re)use all of model.operandValues for the operand +// value. +static size_t constantCopyExtraSize(const Model& model, size_t operandSize) { + const size_t operandValuesSize = model.operandValues.size(); + return (operandValuesSize < operandSize) ? (operandSize - operandValuesSize) : 0; +} + +// Highly specialized utility routine for converting an operand to +// CONSTANT_COPY lifetime. +// +// Expects that: +// - operand has a known size +// - operand->lifetime has already been set to CONSTANT_COPY +// - operand->location has been zeroed out +// +// Does the following: +// - initializes operand->location to point to the beginning of model->operandValues +// - resizes model->operandValues (if necessary) to be large enough for the operand +// value, padding it with zeroes on the end +// +// Potential problem: +// By changing the operand to CONSTANT_COPY lifetime, this function is effectively initializing the +// operand with unspecified (but deterministic) data. This means that the model may be invalidated +// in two ways: not only is the lifetime of CONSTANT_COPY invalid, but the operand's value in the +// graph may also be invalid (e.g., if the operand is used as an activation code and has an invalid +// value). For now, this should be fine because it just means we're not testing what we think we're +// testing in certain cases; but we can handwave this and assume we're probabilistically likely to +// exercise the validation code over the span of the entire test set and operand space. +// +// Aborts if the specified operand type is an extension type or OEM type. +static void becomeConstantCopy(Model* model, Operand* operand) { + // sizeOfData will abort if the specified type is an extension type or OEM type. + const size_t sizeOfOperand = sizeOfData(*operand); + EXPECT_NE(sizeOfOperand, size_t(0)); + operand->location.poolIndex = 0; + operand->location.offset = 0; + operand->location.length = sizeOfOperand; + if (model->operandValues.size() < sizeOfOperand) { + model->operandValues.resize(sizeOfOperand); + } +} + +// The sizeForBinder() functions estimate the size of the +// representation of a value when sent to binder. It's probably a bit +// of an under-estimate, because we don't know the size of the +// metadata in the binder format (e.g., representation of the size of +// a vector); but at least it adds up "big" things like vector +// contents. However, it doesn't treat inter-field or end-of-struct +// padding in a methodical way -- there's no attempt to be consistent +// in whether or not padding in the native (C++) representation +// contributes to the estimated size for the binder representation; +// and there's no attempt to understand what padding (if any) is +// needed in the binder representation. +// +// This assumes that non-metadata uses a fixed length encoding (e.g., +// a uint32_t is always encoded in sizeof(uint32_t) bytes, rather than +// using an encoding whose length is related to the magnitude of the +// encoded value). + +template +static size_t sizeForBinder(const Type& val) { + static_assert(std::is_trivially_copyable_v>, + "expected a trivially copyable type"); + return sizeof(val); +} + +template +static size_t sizeForBinder(const hidl_vec& vec) { + return std::accumulate(vec.begin(), vec.end(), 0, + [](size_t acc, const Type& x) { return acc + sizeForBinder(x); }); +} + +template <> +size_t sizeForBinder(const SymmPerChannelQuantParams& symmPerChannelQuantParams) { + size_t size = 0; + + size += sizeForBinder(symmPerChannelQuantParams.scales); + size += sizeForBinder(symmPerChannelQuantParams.channelDim); + + return size; +} + +template <> +size_t sizeForBinder(const V1_2::Operand::ExtraParams& extraParams) { + using Discriminator = V1_2::Operand::ExtraParams::hidl_discriminator; + switch (extraParams.getDiscriminator()) { + case Discriminator::none: + return 0; + case Discriminator::channelQuant: + return sizeForBinder(extraParams.channelQuant()); + case Discriminator::extension: + return sizeForBinder(extraParams.extension()); + } + LOG(FATAL) << "Unrecognized extraParams enum: " + << static_cast(extraParams.getDiscriminator()); + return 0; +} + +template <> +size_t sizeForBinder(const Operand& operand) { + size_t size = 0; + + size += sizeForBinder(operand.type); + size += sizeForBinder(operand.dimensions); + size += sizeForBinder(operand.numberOfConsumers); + size += sizeForBinder(operand.scale); + size += sizeForBinder(operand.zeroPoint); + size += sizeForBinder(operand.lifetime); + size += sizeForBinder(operand.location); + size += sizeForBinder(operand.extraParams); + + return size; +} + +template <> +size_t sizeForBinder(const Operation& operation) { + size_t size = 0; + + size += sizeForBinder(operation.type); + size += sizeForBinder(operation.inputs); + size += sizeForBinder(operation.outputs); + + return size; +} + +template <> +size_t sizeForBinder(const hidl_string& name) { + return name.size(); +} + +template <> +size_t sizeForBinder(const hidl_memory& memory) { + // This is just a guess. + + size_t size = 0; + + if (const native_handle_t* handle = memory.handle()) { + size += sizeof(*handle); + size += sizeof(handle->data[0] * (handle->numFds + handle->numInts)); + } + size += sizeForBinder(memory.name()); + + return size; +} + +template <> +size_t sizeForBinder(const Subgraph& subgraph) { + size_t size = 0; + + size += sizeForBinder(subgraph.operands); + size += sizeForBinder(subgraph.operations); + size += sizeForBinder(subgraph.inputIndexes); + size += sizeForBinder(subgraph.outputIndexes); + + return size; +} + +template <> +size_t sizeForBinder(const V1_2::Model::ExtensionNameAndPrefix& extensionNameToPrefix) { + size_t size = 0; + + size += sizeForBinder(extensionNameToPrefix.name); + size += sizeForBinder(extensionNameToPrefix.prefix); + + return size; +} + +template <> +size_t sizeForBinder(const Model& model) { + size_t size = 0; + + size += sizeForBinder(model.main); + size += sizeForBinder(model.referenced); + size += sizeForBinder(model.operandValues); + size += sizeForBinder(model.pools); + size += sizeForBinder(model.relaxComputationFloat32toFloat16); + size += sizeForBinder(model.extensionNameToPrefix); + + return size; +} + +// https://developer.android.com/reference/android/os/TransactionTooLargeException.html +// +// "The Binder transaction buffer has a limited fixed size, +// currently 1Mb, which is shared by all transactions in progress +// for the process." +// +// Will our representation fit under this limit? There are two complications: +// - Our representation size is just approximate (see sizeForBinder()). +// - This object may not be the only occupant of the Binder transaction buffer. +// So we'll be very conservative: We want the representation size to be no +// larger than half the transaction buffer size. +// +// If our representation grows large enough that it still fits within +// the transaction buffer but combined with other transactions may +// exceed the buffer size, then we may see intermittent HAL transport +// errors. +static bool exceedsBinderSizeLimit(size_t representationSize) { + // Instead of using this fixed buffer size, we might instead be able to use + // ProcessState::self()->getMmapSize(). However, this has a potential + // problem: The binder/mmap size of the current process does not necessarily + // indicate the binder/mmap size of the service (i.e., the other process). + // The only way it would be a good indication is if both the current process + // and the service use the default size. + static const size_t kHalfBufferSize = 1024 * 1024 / 2; + + return representationSize > kHalfBufferSize; +} + +///////////////////////// VALIDATE EXECUTION ORDER //////////////////////////// + +static void mutateExecutionOrderTest(const sp& device, const Model& model) { + for (size_t operation = 0; operation < model.main.operations.size(); ++operation) { + const Operation& operationObj = model.main.operations[operation]; + for (uint32_t input : operationObj.inputs) { + if (model.main.operands[input].lifetime == OperandLifeTime::TEMPORARY_VARIABLE || + model.main.operands[input].lifetime == OperandLifeTime::SUBGRAPH_OUTPUT) { + // This operation reads an operand written by some + // other operation. Move this operation to the + // beginning of the sequence, ensuring that it reads + // the operand before that operand is written, thereby + // violating execution order rules. + const std::string message = "mutateExecutionOrderTest: operation " + + std::to_string(operation) + " is a reader"; + validate(device, message, model, + [operation](Model* model, ExecutionPreference*, Priority*) { + auto& operations = model->main.operations; + std::rotate(operations.begin(), operations.begin() + operation, + operations.begin() + operation + 1); + }); + break; // only need to do this once per operation + } + } + for (uint32_t output : operationObj.outputs) { + if (model.main.operands[output].numberOfConsumers > 0) { + // This operation writes an operand read by some other + // operation. Move this operation to the end of the + // sequence, ensuring that it writes the operand after + // that operand is read, thereby violating execution + // order rules. + const std::string message = "mutateExecutionOrderTest: operation " + + std::to_string(operation) + " is a writer"; + validate(device, message, model, + [operation](Model* model, ExecutionPreference*, Priority*) { + auto& operations = model->main.operations; + std::rotate(operations.begin() + operation, + operations.begin() + operation + 1, operations.end()); + }); + break; // only need to do this once per operation + } + } + } +} + ///////////////////////// VALIDATE MODEL OPERAND TYPE ///////////////////////// static const uint32_t invalidOperandTypes[] = { @@ -261,9 +524,245 @@ static void mutateOperandZeroPointTest(const sp& device, const Model& m } } +///////////////////////// VALIDATE OPERAND LIFETIME ///////////////////////////////////////////// + +static std::vector getInvalidLifeTimes(const Model& model, size_t modelSize, + const Operand& operand) { + // TODO: Support OperandLifeTime::CONSTANT_REFERENCE as an invalid lifetime + // TODO: Support OperandLifeTime::NO_VALUE as an invalid lifetime + + // Ways to get an invalid lifetime: + // - change whether a lifetime means an operand should have a writer + std::vector ret; + switch (operand.lifetime) { + case OperandLifeTime::SUBGRAPH_OUTPUT: + case OperandLifeTime::TEMPORARY_VARIABLE: + ret = { + OperandLifeTime::SUBGRAPH_INPUT, + OperandLifeTime::CONSTANT_COPY, + }; + break; + case OperandLifeTime::CONSTANT_COPY: + case OperandLifeTime::CONSTANT_REFERENCE: + case OperandLifeTime::SUBGRAPH_INPUT: + ret = { + OperandLifeTime::TEMPORARY_VARIABLE, + OperandLifeTime::SUBGRAPH_OUTPUT, + }; + break; + case OperandLifeTime::NO_VALUE: + // Not enough information to know whether + // TEMPORARY_VARIABLE or CONSTANT_COPY would be invalid -- + // is this operand written (then CONSTANT_COPY would be + // invalid) or not (then TEMPORARY_VARIABLE would be + // invalid)? + break; + case OperandLifeTime::SUBGRAPH: + break; + default: + ADD_FAILURE(); + break; + } + + const size_t operandSize = sizeOfData(operand); // will be zero if shape is unknown + if (!operandSize || + exceedsBinderSizeLimit(modelSize + constantCopyExtraSize(model, operandSize))) { + // Unknown size or too-large size + ret.erase(std::remove(ret.begin(), ret.end(), OperandLifeTime::CONSTANT_COPY), ret.end()); + } + + return ret; +} + +static void mutateOperandLifeTimeTest(const sp& device, const Model& model) { + const size_t modelSize = sizeForBinder(model); + for (size_t operand = 0; operand < model.main.operands.size(); ++operand) { + const std::vector invalidLifeTimes = + getInvalidLifeTimes(model, modelSize, model.main.operands[operand]); + for (OperandLifeTime invalidLifeTime : invalidLifeTimes) { + const std::string message = "mutateOperandLifetimeTest: operand " + + std::to_string(operand) + " has lifetime " + + toString(invalidLifeTime) + " instead of lifetime " + + toString(model.main.operands[operand].lifetime); + validate(device, message, model, + [operand, invalidLifeTime](Model* model, ExecutionPreference*, Priority*) { + static const DataLocation kZeroDataLocation = {}; + Operand& operandObj = model->main.operands[operand]; + switch (operandObj.lifetime) { + case OperandLifeTime::SUBGRAPH_INPUT: { + hidl_vec_remove(&model->main.inputIndexes, uint32_t(operand)); + break; + } + case OperandLifeTime::SUBGRAPH_OUTPUT: { + hidl_vec_remove(&model->main.outputIndexes, uint32_t(operand)); + break; + } + default: + break; + } + operandObj.lifetime = invalidLifeTime; + operandObj.location = kZeroDataLocation; + switch (invalidLifeTime) { + case OperandLifeTime::CONSTANT_COPY: { + becomeConstantCopy(model, &operandObj); + break; + } + case OperandLifeTime::SUBGRAPH_INPUT: + hidl_vec_push_back(&model->main.inputIndexes, uint32_t(operand)); + break; + case OperandLifeTime::SUBGRAPH_OUTPUT: + hidl_vec_push_back(&model->main.outputIndexes, uint32_t(operand)); + break; + default: + break; + } + }); + } + } +} + +///////////////////////// VALIDATE OPERAND INPUT-or-OUTPUT ////////////////////////////////////// + +static std::optional getInputOutputLifeTime(const Model& model, size_t modelSize, + const Operand& operand) { + // Ways to get an invalid lifetime (with respect to model inputIndexes and outputIndexes): + // - change whether a lifetime means an operand is a model input, a model output, or neither + // - preserve whether or not a lifetime means an operand should have a writer + switch (operand.lifetime) { + case OperandLifeTime::CONSTANT_COPY: + case OperandLifeTime::CONSTANT_REFERENCE: + return OperandLifeTime::SUBGRAPH_INPUT; + case OperandLifeTime::SUBGRAPH_INPUT: { + const size_t operandSize = sizeOfData(operand); // will be zero if shape is unknown + if (!operandSize || + exceedsBinderSizeLimit(modelSize + constantCopyExtraSize(model, operandSize))) { + // Unknown size or too-large size + break; + } + return OperandLifeTime::CONSTANT_COPY; + } + case OperandLifeTime::SUBGRAPH_OUTPUT: + return OperandLifeTime::TEMPORARY_VARIABLE; + case OperandLifeTime::TEMPORARY_VARIABLE: + return OperandLifeTime::SUBGRAPH_OUTPUT; + case OperandLifeTime::NO_VALUE: + // Not enough information to know whether + // TEMPORARY_VARIABLE or CONSTANT_COPY would be an + // appropriate choice -- is this operand written (then + // TEMPORARY_VARIABLE would be appropriate) or not (then + // CONSTANT_COPY would be appropriate)? + break; + case OperandLifeTime::SUBGRAPH: + break; + default: + ADD_FAILURE(); + break; + } + + return std::nullopt; +} + +static void mutateOperandInputOutputTest(const sp& device, const Model& model) { + const size_t modelSize = sizeForBinder(model); + for (size_t operand = 0; operand < model.main.operands.size(); ++operand) { + const std::optional changedLifeTime = + getInputOutputLifeTime(model, modelSize, model.main.operands[operand]); + if (changedLifeTime) { + const std::string message = "mutateOperandInputOutputTest: operand " + + std::to_string(operand) + " has lifetime " + + toString(*changedLifeTime) + " instead of lifetime " + + toString(model.main.operands[operand].lifetime); + validate(device, message, model, + [operand, changedLifeTime](Model* model, ExecutionPreference*, Priority*) { + static const DataLocation kZeroDataLocation = {}; + Operand& operandObj = model->main.operands[operand]; + operandObj.lifetime = *changedLifeTime; + operandObj.location = kZeroDataLocation; + if (*changedLifeTime == OperandLifeTime::CONSTANT_COPY) { + becomeConstantCopy(model, &operandObj); + } + }); + } + } +} + +///////////////////////// VALIDATE OPERAND NUMBER OF CONSUMERS ////////////////////////////////// + +static std::vector getInvalidNumberOfConsumers(uint32_t numberOfConsumers) { + if (numberOfConsumers == 0) { + return {1}; + } else { + return {numberOfConsumers - 1, numberOfConsumers + 1}; + } +} + +static void mutateOperandNumberOfConsumersTest(const sp& device, const Model& model) { + for (size_t operand = 0; operand < model.main.operands.size(); ++operand) { + const std::vector invalidNumberOfConsumersVec = + getInvalidNumberOfConsumers(model.main.operands[operand].numberOfConsumers); + for (uint32_t invalidNumberOfConsumers : invalidNumberOfConsumersVec) { + const std::string message = + "mutateOperandNumberOfConsumersTest: operand " + std::to_string(operand) + + " numberOfConsumers = " + std::to_string(invalidNumberOfConsumers); + validate(device, message, model, + [operand, invalidNumberOfConsumers](Model* model, ExecutionPreference*, + Priority*) { + model->main.operands[operand].numberOfConsumers = invalidNumberOfConsumers; + }); + } + } +} + +///////////////////////// VALIDATE OPERAND NUMBER OF WRITERS //////////////////////////////////// + +static void mutateOperandAddWriterTest(const sp& device, const Model& model) { + for (size_t operation = 0; operation < model.main.operations.size(); ++operation) { + for (size_t badOutputNum = 0; + badOutputNum < model.main.operations[operation].outputs.size(); ++badOutputNum) { + const uint32_t outputOperandIndex = + model.main.operations[operation].outputs[badOutputNum]; + const std::string message = "mutateOperandAddWriterTest: operation " + + std::to_string(operation) + " writes to " + + std::to_string(outputOperandIndex); + // We'll insert a copy of the operation, all of whose + // OTHER output operands are newly-created -- i.e., + // there'll only be a duplicate write of ONE of that + // operation's output operands. + validate(device, message, model, + [operation, badOutputNum](Model* model, ExecutionPreference*, Priority*) { + Operation newOperation = model->main.operations[operation]; + for (uint32_t input : newOperation.inputs) { + ++model->main.operands[input].numberOfConsumers; + } + for (size_t outputNum = 0; outputNum < newOperation.outputs.size(); + ++outputNum) { + if (outputNum == badOutputNum) continue; + + Operand operandValue = + model->main.operands[newOperation.outputs[outputNum]]; + operandValue.numberOfConsumers = 0; + if (operandValue.lifetime == OperandLifeTime::SUBGRAPH_OUTPUT) { + operandValue.lifetime = OperandLifeTime::TEMPORARY_VARIABLE; + } else { + ASSERT_EQ(operandValue.lifetime, + OperandLifeTime::TEMPORARY_VARIABLE); + } + newOperation.outputs[outputNum] = + hidl_vec_push_back(&model->main.operands, operandValue); + } + // Where do we insert the extra writer (a new + // operation)? It has to be later than all the + // writers of its inputs. The easiest thing to do + // is to insert it at the end of the operation + // sequence. + hidl_vec_push_back(&model->main.operations, newOperation); + }); + } + } +} + ///////////////////////// VALIDATE EXTRA ??? ///////////////////////// -// TODO: Operand::lifetime // TODO: Operand::location ///////////////////////// VALIDATE OPERATION OPERAND TYPE ///////////////////////// @@ -511,6 +1010,37 @@ static void mutateOperationOutputOperandIndexTest(const sp& device, con } } +///////////////////////// VALIDATE MODEL OPERANDS WRITTEN /////////////////////////////////////// + +static void mutateOperationRemoveWriteTest(const sp& device, const Model& model) { + for (size_t operation = 0; operation < model.main.operations.size(); ++operation) { + for (size_t outputNum = 0; outputNum < model.main.operations[operation].outputs.size(); + ++outputNum) { + const uint32_t outputOperandIndex = model.main.operations[operation].outputs[outputNum]; + if (model.main.operands[outputOperandIndex].numberOfConsumers > 0) { + const std::string message = "mutateOperationRemoveWriteTest: operation " + + std::to_string(operation) + " writes to " + + std::to_string(outputOperandIndex); + validate(device, message, model, + [operation, outputNum](Model* model, ExecutionPreference*, Priority*) { + uint32_t& outputOperandIndex = + model->main.operations[operation].outputs[outputNum]; + Operand operandValue = model->main.operands[outputOperandIndex]; + operandValue.numberOfConsumers = 0; + if (operandValue.lifetime == OperandLifeTime::SUBGRAPH_OUTPUT) { + operandValue.lifetime = OperandLifeTime::TEMPORARY_VARIABLE; + } else { + ASSERT_EQ(operandValue.lifetime, + OperandLifeTime::TEMPORARY_VARIABLE); + } + outputOperandIndex = + hidl_vec_push_back(&model->main.operands, operandValue); + }); + } + } + } +} + ///////////////////////// REMOVE OPERAND FROM EVERYTHING ///////////////////////// static void removeValueAndDecrementGreaterValues(hidl_vec* vec, uint32_t value) { @@ -804,14 +1334,20 @@ static void mutateExecutionPriorityTest(const sp& device, const Model& ////////////////////////// ENTRY POINT ////////////////////////////// void validateModel(const sp& device, const Model& model) { + mutateExecutionOrderTest(device, model); mutateOperandTypeTest(device, model); mutateOperandRankTest(device, model); mutateOperandScaleTest(device, model); mutateOperandZeroPointTest(device, model); + mutateOperandLifeTimeTest(device, model); + mutateOperandInputOutputTest(device, model); + mutateOperandNumberOfConsumersTest(device, model); + mutateOperandAddWriterTest(device, model); mutateOperationOperandTypeTest(device, model); mutateOperationTypeTest(device, model); mutateOperationInputOperandIndexTest(device, model); mutateOperationOutputOperandIndexTest(device, model); + mutateOperationRemoveWriteTest(device, model); removeOperandTest(device, model); removeOperationTest(device, model); removeOperationInputTest(device, model); diff --git a/neuralnetworks/1.3/vts/functional/include/1.3/Utils.h b/neuralnetworks/1.3/vts/functional/include/1.3/Utils.h index 3661b66445..e07e73bde8 100644 --- a/neuralnetworks/1.3/vts/functional/include/1.3/Utils.h +++ b/neuralnetworks/1.3/vts/functional/include/1.3/Utils.h @@ -24,6 +24,18 @@ namespace android::hardware::neuralnetworks { inline constexpr V1_3::Priority kDefaultPriority = V1_3::Priority::MEDIUM; +// Returns the amount of space needed to store a value of the specified type. +// +// Aborts if the specified type is an extension type or OEM type. +uint32_t sizeOfData(V1_3::OperandType type); + +// Returns the amount of space needed to store a value of the dimensions and +// type of this operand. For a non-extension, non-OEM tensor with unspecified +// rank or at least one unspecified dimension, returns zero. +// +// Aborts if the specified type is an extension type or OEM type. +uint32_t sizeOfData(const V1_3::Operand& operand); + } // namespace android::hardware::neuralnetworks namespace android::hardware::neuralnetworks::V1_3 { -- GitLab From cec924166a3a6c3cf3bbdb1be1071793cd8864bc Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Wed, 6 May 2020 21:31:17 -0700 Subject: [PATCH 043/790] Fixed cast. Test: echo 'in TH we trust' Bug: 150409351 Change-Id: Id7392551bcb08f3679c58fb4accc15088de0f05a --- .../vehicle/2.0/default/impl/vhal_v2_0/EmulatedUserHal.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedUserHal.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedUserHal.cpp index 7ffee1f71a..63ddc010b8 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedUserHal.cpp +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedUserHal.cpp @@ -28,8 +28,8 @@ namespace V2_0 { namespace impl { -constexpr int INITIAL_USER_INFO = (int)VehicleProperty::INITIAL_USER_INFO; -constexpr int SWITCH_USER = (int)VehicleProperty::SWITCH_USER; +constexpr int INITIAL_USER_INFO = static_cast(VehicleProperty::INITIAL_USER_INFO); +constexpr int SWITCH_USER = static_cast(VehicleProperty::SWITCH_USER); bool EmulatedUserHal::isSupported(int32_t prop) { switch (prop) { -- GitLab From ac6d14d4d0147bac45883d6195604bd092f423fb Mon Sep 17 00:00:00 2001 From: Nate Jiang Date: Thu, 14 May 2020 18:06:26 -0700 Subject: [PATCH 044/790] Skip test when NAN or RTT feature not supported Bug: 155372761 Test: atest VtsHalWifiApV1_4TargetTest, VtsHalWifiNanV1_4TargetTest, VtsHalWifiRttV1_4TargetTest Change-Id: I04bfffe9dc587e3f7209601c3712422b6e2d165c --- wifi/1.0/vts/functional/Android.bp | 25 +++++++++++++------ .../wifi_rtt_controller_hidl_test.cpp | 3 +++ wifi/1.1/vts/functional/Android.bp | 10 +++++--- wifi/1.2/vts/functional/Android.bp | 15 +++++++---- .../functional/wifi_nan_iface_hidl_test.cpp | 3 +++ .../functional/wifi_nan_iface_hidl_test.cpp | 3 +++ .../wifi_rtt_controller_hidl_test.cpp | 3 +++ 7 files changed, 46 insertions(+), 16 deletions(-) diff --git a/wifi/1.0/vts/functional/Android.bp b/wifi/1.0/vts/functional/Android.bp index 793dd8cc7c..14a8509718 100644 --- a/wifi/1.0/vts/functional/Android.bp +++ b/wifi/1.0/vts/functional/Android.bp @@ -23,14 +23,14 @@ cc_library_static { "wifi_hidl_test_utils.cpp", ], export_include_dirs: [ - "." + ".", ], shared_libs: [ "libnativehelper", ], static_libs: [ "android.hardware.wifi@1.0", - "libwifi-system-iface" + "libwifi-system-iface", ], } @@ -49,9 +49,12 @@ cc_test { "android.hardware.wifi@1.1", "android.hardware.wifi@1.2", "android.hardware.wifi@1.3", - "libwifi-system-iface" + "libwifi-system-iface", + ], + test_suites: [ + "general-tests", + "vts", ], - test_suites: ["general-tests", "vts"], } // These tests are split out so that they can be conditioned on presence of the @@ -66,9 +69,12 @@ cc_test { static_libs: [ "VtsHalWifiV1_0TargetTestUtil", "android.hardware.wifi@1.0", - "libwifi-system-iface" + "libwifi-system-iface", + ], + test_suites: [ + "general-tests", + "vts", ], - test_suites: ["general-tests", "vts"], } // These tests are split out so that they can be conditioned on presence of @@ -83,7 +89,10 @@ cc_test { static_libs: [ "VtsHalWifiV1_0TargetTestUtil", "android.hardware.wifi@1.0", - "libwifi-system-iface" + "libwifi-system-iface", + ], + test_suites: [ + "general-tests", + "vts", ], - test_suites: ["general-tests", "vts"], } diff --git a/wifi/1.0/vts/functional/wifi_rtt_controller_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_rtt_controller_hidl_test.cpp index 1014c1dc68..3c9ed9ee23 100644 --- a/wifi/1.0/vts/functional/wifi_rtt_controller_hidl_test.cpp +++ b/wifi/1.0/vts/functional/wifi_rtt_controller_hidl_test.cpp @@ -16,6 +16,7 @@ #include +#include #include #include #include @@ -38,6 +39,8 @@ using ::android::hardware::wifi::V1_0::WifiStatusCode; class WifiRttControllerHidlTest : public ::testing::TestWithParam { public: virtual void SetUp() override { + if (!::testing::deviceSupportsFeature("android.hardware.wifi.rtt")) + GTEST_SKIP() << "Skipping this test since RTT is not supported."; // Make sure test starts with a clean state stopWifi(GetInstanceName()); } diff --git a/wifi/1.1/vts/functional/Android.bp b/wifi/1.1/vts/functional/Android.bp index eb68bc0ddc..7dc78e4519 100644 --- a/wifi/1.1/vts/functional/Android.bp +++ b/wifi/1.1/vts/functional/Android.bp @@ -18,14 +18,18 @@ cc_test { name: "VtsHalWifiV1_1TargetTest", defaults: ["VtsHalTargetTestDefaults"], srcs: [ - "wifi_chip_hidl_test.cpp"], + "wifi_chip_hidl_test.cpp", + ], static_libs: [ "VtsHalWifiV1_0TargetTestUtil", "android.hardware.wifi@1.0", "android.hardware.wifi@1.1", "android.hardware.wifi@1.2", "android.hardware.wifi@1.3", - "libwifi-system-iface" + "libwifi-system-iface", + ], + test_suites: [ + "general-tests", + "vts", ], - test_suites: ["general-tests", "vts"], } diff --git a/wifi/1.2/vts/functional/Android.bp b/wifi/1.2/vts/functional/Android.bp index 90bcac1d33..159ba94340 100644 --- a/wifi/1.2/vts/functional/Android.bp +++ b/wifi/1.2/vts/functional/Android.bp @@ -27,10 +27,13 @@ cc_test { "android.hardware.wifi@1.1", "android.hardware.wifi@1.2", "android.hardware.wifi@1.3", - "libwifi-system-iface" + "libwifi-system-iface", ], disable_framework: true, - test_suites: ["general-tests", "vts"], + test_suites: [ + "general-tests", + "vts", + ], } cc_test { @@ -44,8 +47,10 @@ cc_test { "android.hardware.wifi@1.0", "android.hardware.wifi@1.1", "android.hardware.wifi@1.2", - "libwifi-system-iface" + "libwifi-system-iface", + ], + test_suites: [ + "general-tests", + "vts", ], - disable_framework: true, - test_suites: ["general-tests", "vts"], } diff --git a/wifi/1.2/vts/functional/wifi_nan_iface_hidl_test.cpp b/wifi/1.2/vts/functional/wifi_nan_iface_hidl_test.cpp index 96656f3c73..bc392a91ec 100644 --- a/wifi/1.2/vts/functional/wifi_nan_iface_hidl_test.cpp +++ b/wifi/1.2/vts/functional/wifi_nan_iface_hidl_test.cpp @@ -16,6 +16,7 @@ #include +#include #include #include #include @@ -50,6 +51,8 @@ android::sp getWifiNanIface_1_2( class WifiNanIfaceHidlTest : public ::testing::TestWithParam { public: virtual void SetUp() override { + if (!::testing::deviceSupportsFeature("android.hardware.wifi.aware")) + GTEST_SKIP() << "Skipping this test since NAN is not supported."; // Make sure to start with a clean state stopWifi(GetInstanceName()); diff --git a/wifi/1.4/vts/functional/wifi_nan_iface_hidl_test.cpp b/wifi/1.4/vts/functional/wifi_nan_iface_hidl_test.cpp index 24daee69f3..f6a1147e0d 100644 --- a/wifi/1.4/vts/functional/wifi_nan_iface_hidl_test.cpp +++ b/wifi/1.4/vts/functional/wifi_nan_iface_hidl_test.cpp @@ -16,6 +16,7 @@ #include +#include #include #include #include @@ -51,6 +52,8 @@ android::sp getWifiNanIface_1_4( class WifiNanIfaceHidlTest : public ::testing::TestWithParam { public: virtual void SetUp() override { + if (!::testing::deviceSupportsFeature("android.hardware.wifi.aware")) + GTEST_SKIP() << "Skipping this test since NAN is not supported."; // Make sure to start with a clean state stopWifi(GetInstanceName()); diff --git a/wifi/1.4/vts/functional/wifi_rtt_controller_hidl_test.cpp b/wifi/1.4/vts/functional/wifi_rtt_controller_hidl_test.cpp index 4035fb8f71..9d842234b7 100644 --- a/wifi/1.4/vts/functional/wifi_rtt_controller_hidl_test.cpp +++ b/wifi/1.4/vts/functional/wifi_rtt_controller_hidl_test.cpp @@ -19,6 +19,7 @@ #undef NAN // NAN is defined in bionic/libc/include/math.h:38 +#include #include #include #include @@ -59,6 +60,8 @@ using ::android::hardware::wifi::V1_4::RttResult; class WifiRttControllerHidlTest : public ::testing::TestWithParam { public: virtual void SetUp() override { + if (!::testing::deviceSupportsFeature("android.hardware.wifi.rtt")) + GTEST_SKIP() << "Skipping this test since RTT is not supported."; // Make sure to start with a clean state stopWifi(GetInstanceName()); -- GitLab From 504d3da1d8c3f9260ad7a9a963c69e2c3f4d0afd Mon Sep 17 00:00:00 2001 From: Pierre Couillaud Date: Wed, 3 Jun 2020 04:56:00 -0700 Subject: [PATCH 045/790] vts: wifi: softap and p2p are optional feature per CDD backport to P changes to ensure optional features are only exercised if advertised as supported. Bug: 73543546 Bug: 73306751 Signed-off-by: Pierre Couillaud Change-Id: I809a3eb90dfcc8ab37fdd3e2c60e432c7a686a49 --- .../functional/wifi_ap_iface_hidl_test.cpp | 11 ++++- .../vts/functional/wifi_chip_hidl_test.cpp | 5 +++ .../1.0/vts/functional/wifi_hidl_test_utils.h | 11 ++++- wifi/supplicant/1.0/vts/functional/Android.bp | 21 +++++++++- .../VtsHalWifiSupplicantV1_0TargetTest.cpp | 9 +++- .../vts/functional/supplicant_hidl_test.cpp | 24 +++++++---- .../functional/supplicant_hidl_test_utils.cpp | 5 ++- .../functional/supplicant_hidl_test_utils.h | 42 ++++++++++++++++++- .../VtsHalWifiSupplicantV1_1TargetTest.cpp | 12 +++++- .../vts/functional/supplicant_hidl_test.cpp | 4 ++ 10 files changed, 125 insertions(+), 19 deletions(-) diff --git a/wifi/1.0/vts/functional/wifi_ap_iface_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_ap_iface_hidl_test.cpp index c0af30bf5a..811677f35a 100644 --- a/wifi/1.0/vts/functional/wifi_ap_iface_hidl_test.cpp +++ b/wifi/1.0/vts/functional/wifi_ap_iface_hidl_test.cpp @@ -29,17 +29,22 @@ using ::android::hardware::wifi::V1_0::WifiBand; using ::android::hardware::wifi::V1_0::WifiStatusCode; using ::android::sp; +extern WifiHidlEnvironment* gEnv; /** * Fixture to use for all AP Iface HIDL interface tests. */ class WifiApIfaceHidlTest : public ::testing::VtsHalHidlTargetTestBase { public: virtual void SetUp() override { + if (!gEnv->isSoftApOn) return; wifi_ap_iface_ = getWifiApIface(); ASSERT_NE(nullptr, wifi_ap_iface_.get()); } - virtual void TearDown() override { stopWifi(); } + virtual void TearDown() override { + if (!gEnv->isSoftApOn) return; + stopWifi(); + } protected: sp wifi_ap_iface_; @@ -51,6 +56,7 @@ class WifiApIfaceHidlTest : public ::testing::VtsHalHidlTargetTestBase { * successfully created. */ TEST(WifiApIfaceHidlTestNoFixture, Create) { + if (!gEnv->isSoftApOn) return; EXPECT_NE(nullptr, getWifiApIface().get()); stopWifi(); } @@ -60,6 +66,7 @@ TEST(WifiApIfaceHidlTestNoFixture, Create) { * Ensures that the correct interface type is returned for AP interface. */ TEST_F(WifiApIfaceHidlTest, GetType) { + if (!gEnv->isSoftApOn) return; const auto& status_and_type = HIDL_INVOKE(wifi_ap_iface_, getType); EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_type.first.code); EXPECT_EQ(IfaceType::AP, status_and_type.second); @@ -71,6 +78,7 @@ TEST_F(WifiApIfaceHidlTest, GetType) { * status code. */ TEST_F(WifiApIfaceHidlTest, SetCountryCode) { + if (!gEnv->isSoftApOn) return; const android::hardware::hidl_array kCountryCode{ std::array{{0x55, 0x53}}}; EXPECT_EQ(WifiStatusCode::SUCCESS, @@ -82,6 +90,7 @@ TEST_F(WifiApIfaceHidlTest, SetCountryCode) { * Ensures that we can retrieve valid frequencies for 2.4 GHz band. */ TEST_F(WifiApIfaceHidlTest, GetValidFrequenciesForBand) { + if (!gEnv->isSoftApOn) return; const auto& status_and_freqs = HIDL_INVOKE( wifi_ap_iface_, getValidFrequenciesForBand, WifiBand::BAND_24GHZ); EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_freqs.first.code); diff --git a/wifi/1.0/vts/functional/wifi_chip_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_chip_hidl_test.cpp index 14d592707f..1386ff3c48 100644 --- a/wifi/1.0/vts/functional/wifi_chip_hidl_test.cpp +++ b/wifi/1.0/vts/functional/wifi_chip_hidl_test.cpp @@ -352,6 +352,7 @@ TEST_F(WifiChipHidlTest, GetDebugHostWakeReasonStats) { * succeeds. */ TEST_F(WifiChipHidlTest, CreateApIface) { + if (!gEnv->isSoftApOn) return; configureChipForIfaceType(IfaceType::AP, true); sp iface; @@ -366,6 +367,7 @@ TEST_F(WifiChipHidlTest, CreateApIface) { * iface name is returned via the list. */ TEST_F(WifiChipHidlTest, GetApIfaceNames) { + if (!gEnv->isSoftApOn) return; configureChipForIfaceType(IfaceType::AP, true); const auto& status_and_iface_names1 = @@ -398,6 +400,7 @@ TEST_F(WifiChipHidlTest, GetApIfaceNames) { * doesn't retrieve an iface object. */ TEST_F(WifiChipHidlTest, GetApIface) { + if (!gEnv->isSoftApOn) return; configureChipForIfaceType(IfaceType::AP, true); sp ap_iface; @@ -424,6 +427,7 @@ TEST_F(WifiChipHidlTest, GetApIface) { * doesn't remove the iface. */ TEST_F(WifiChipHidlTest, RemoveApIface) { + if (!gEnv->isSoftApOn) return; configureChipForIfaceType(IfaceType::AP, true); sp ap_iface; @@ -727,6 +731,7 @@ TEST_F(WifiChipHidlTest, RemoveStaIface) { * CreateRttController */ TEST_F(WifiChipHidlTest, CreateRttController) { + if (!gEnv->isSoftApOn) return; configureChipForIfaceType(IfaceType::AP, true); sp iface; diff --git a/wifi/1.0/vts/functional/wifi_hidl_test_utils.h b/wifi/1.0/vts/functional/wifi_hidl_test_utils.h index 2b1c8ec82e..d430ce0bea 100644 --- a/wifi/1.0/vts/functional/wifi_hidl_test_utils.h +++ b/wifi/1.0/vts/functional/wifi_hidl_test_utils.h @@ -58,26 +58,33 @@ class WifiHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase { public: // Whether NaN feature is supported on the device. bool isNanOn = false; + // Whether SoftAp feature is supported on the device. + bool isSoftApOn = false; void usage(char* me, char* arg) { fprintf(stderr, "unrecognized option: %s\n\n" "usage: %s \n\n" "test options are:\n\n" - "-N, --nan_on: Whether NAN feature is supported\n", + "-N, --nan_on: Whether NAN feature is supported\n" + "-S, --softap_on: Whether SOFTAP feature is supported\n", arg, me); } int initFromOptions(int argc, char** argv) { static struct option options[] = {{"nan_on", no_argument, 0, 'N'}, + {"softap_on", no_argument, 0, 'S'}, {0, 0, 0, 0}}; int c; - while ((c = getopt_long(argc, argv, "N", options, NULL)) >= 0) { + while ((c = getopt_long(argc, argv, "NS", options, NULL)) >= 0) { switch (c) { case 'N': isNanOn = true; break; + case 'S': + isSoftApOn = true; + break; default: usage(argv[0], argv[optind]); return 2; diff --git a/wifi/supplicant/1.0/vts/functional/Android.bp b/wifi/supplicant/1.0/vts/functional/Android.bp index ee6a68e048..1ed745515d 100644 --- a/wifi/supplicant/1.0/vts/functional/Android.bp +++ b/wifi/supplicant/1.0/vts/functional/Android.bp @@ -39,7 +39,6 @@ cc_test { srcs: [ "VtsHalWifiSupplicantV1_0TargetTest.cpp", "supplicant_hidl_test.cpp", - "supplicant_p2p_iface_hidl_test.cpp", "supplicant_sta_iface_hidl_test.cpp", "supplicant_sta_network_hidl_test.cpp", ], @@ -55,3 +54,23 @@ cc_test { "libwifi-system-iface", ], } + +cc_test { + name: "VtsHalWifiSupplicantP2pV1_0TargetTest", + defaults: ["VtsHalTargetTestDefaults"], + srcs: [ + "VtsHalWifiSupplicantV1_0TargetTest.cpp", + "supplicant_p2p_iface_hidl_test.cpp", + ], + static_libs: [ + "VtsHalWifiV1_0TargetTestUtil", + "VtsHalWifiSupplicantV1_0TargetTestUtil", + "android.hardware.wifi.supplicant@1.0", + "android.hardware.wifi.supplicant@1.1", + "android.hardware.wifi@1.0", + "libcrypto", + "libgmock", + "libwifi-system", + "libwifi-system-iface", + ], +} \ No newline at end of file diff --git a/wifi/supplicant/1.0/vts/functional/VtsHalWifiSupplicantV1_0TargetTest.cpp b/wifi/supplicant/1.0/vts/functional/VtsHalWifiSupplicantV1_0TargetTest.cpp index adf2a85ab5..9f166ef8d8 100644 --- a/wifi/supplicant/1.0/vts/functional/VtsHalWifiSupplicantV1_0TargetTest.cpp +++ b/wifi/supplicant/1.0/vts/functional/VtsHalWifiSupplicantV1_0TargetTest.cpp @@ -44,7 +44,12 @@ int main(int argc, char** argv) { ::testing::AddGlobalTestEnvironment(gEnv); ::testing::InitGoogleTest(&argc, argv); gEnv->init(&argc, argv); - int status = RUN_ALL_TESTS(); - LOG(INFO) << "Test result = " << status; + + int status = gEnv->initFromOptions(argc, argv); + if (status == 0) { + int status = RUN_ALL_TESTS(); + LOG(INFO) << "Test result = " << status; + } + return status; } diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test.cpp b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test.cpp index c6ac03ce64..e6c27119c8 100644 --- a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test.cpp +++ b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test.cpp @@ -30,6 +30,7 @@ using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatus; using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatusCode; using ::android::hardware::wifi::supplicant::V1_0::IfaceType; +extern WifiSupplicantHidlEnvironment* gEnv; class SupplicantHidlTest : public ::testing::VtsHalHidlTargetTestBase { public: virtual void SetUp() override { @@ -72,10 +73,14 @@ TEST_F(SupplicantHidlTest, ListInterfaces) { std::find_if(ifaces.begin(), ifaces.end(), [](const auto& iface) { return iface.type == IfaceType::STA; })); - EXPECT_NE(ifaces.end(), - std::find_if(ifaces.begin(), ifaces.end(), [](const auto& iface) { - return iface.type == IfaceType::P2P; - })); + + if (gEnv->isP2pOn) { + EXPECT_NE( + ifaces.end(), + std::find_if(ifaces.begin(), ifaces.end(), [](const auto& iface) { + return iface.type == IfaceType::P2P; + })); + } } /* @@ -178,8 +183,11 @@ TEST_F(SupplicantHidlTest, SetConcurrencyPriority) { IfaceType::STA, [](const SupplicantStatus& status) { EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); }); - supplicant_->setConcurrencyPriority( - IfaceType::P2P, [](const SupplicantStatus& status) { - EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); - }); + + if (gEnv->isP2pOn) { + supplicant_->setConcurrencyPriority( + IfaceType::P2P, [](const SupplicantStatus& status) { + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + }); + } } diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp index bdedfba258..da5f933ae7 100644 --- a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp +++ b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp @@ -225,7 +225,10 @@ sp getSupplicant() { // For 1.1 supplicant, we need to add interfaces at initialization. if (is_1_1(supplicant)) { addSupplicantStaIface_1_1(supplicant); - addSupplicantP2pIface_1_1(supplicant); + + if (gEnv->isP2pOn) { + addSupplicantP2pIface_1_1(supplicant); + } } return supplicant; } diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.h b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.h index d4a768fb5b..e91daf87c8 100644 --- a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.h +++ b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.h @@ -23,8 +23,9 @@ #include #include -#include +#include +#include // Used to stop the android wifi framework before every test. void stopWifiFramework(); void startWifiFramework(); @@ -50,11 +51,48 @@ bool turnOnExcessiveLogging(); class WifiSupplicantHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase { - public: + protected: virtual void HidlSetUp() override { stopSupplicant(); } virtual void HidlTearDown() override { startSupplicantAndWaitForHidlService(); } + + public: + // Whether P2P feature is supported on the device. + bool isP2pOn = true; + + void usage(char* me, char* arg) { + fprintf(stderr, + "unrecognized option: %s\n\n" + "usage: %s \n\n" + "test options are:\n\n" + "-P, --p2p_on: Whether P2P feature is supported\n", + arg, me); + } + + int initFromOptions(int argc, char** argv) { + static struct option options[] = {{"p2p_off", no_argument, 0, 'P'}, + {0, 0, 0, 0}}; + + int c; + while ((c = getopt_long(argc, argv, "P", options, NULL)) >= 0) { + switch (c) { + case 'P': + isP2pOn = false; + break; + default: + usage(argv[0], argv[optind]); + return 2; + } + } + + if (optind < argc) { + usage(argv[0], argv[optind]); + return 2; + } + + return 0; + } }; #endif /* SUPPLICANT_HIDL_TEST_UTILS_H */ diff --git a/wifi/supplicant/1.1/vts/functional/VtsHalWifiSupplicantV1_1TargetTest.cpp b/wifi/supplicant/1.1/vts/functional/VtsHalWifiSupplicantV1_1TargetTest.cpp index 3d24fc3eee..c6cc37a423 100644 --- a/wifi/supplicant/1.1/vts/functional/VtsHalWifiSupplicantV1_1TargetTest.cpp +++ b/wifi/supplicant/1.1/vts/functional/VtsHalWifiSupplicantV1_1TargetTest.cpp @@ -30,7 +30,10 @@ class WifiSupplicantHidlEnvironment_1_1 : public WifiSupplicantHidlEnvironment { return instance; } virtual void registerTestServices() override { + registerTestService<::android::hardware::wifi::V1_0::IWifi>(); registerTestService<::android::hardware::wifi::V1_1::IWifi>(); + registerTestService< + ::android::hardware::wifi::supplicant::V1_0::ISupplicant>(); registerTestService< ::android::hardware::wifi::supplicant::V1_1::ISupplicant>(); } @@ -46,7 +49,12 @@ int main(int argc, char** argv) { ::testing::AddGlobalTestEnvironment(gEnv); ::testing::InitGoogleTest(&argc, argv); gEnv->init(&argc, argv); - int status = RUN_ALL_TESTS(); - LOG(INFO) << "Test result = " << status; + + int status = gEnv->initFromOptions(argc, argv); + if (status == 0) { + int status = RUN_ALL_TESTS(); + LOG(INFO) << "Test result = " << status; + } + return status; } diff --git a/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test.cpp b/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test.cpp index 7e773d611e..28f980cf85 100644 --- a/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test.cpp +++ b/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test.cpp @@ -33,6 +33,8 @@ using ::android::hardware::wifi::supplicant::V1_0::IfaceType; using ::android::hardware::wifi::supplicant::V1_1::ISupplicant; using ::android::sp; +extern WifiSupplicantHidlEnvironment* gEnv; + class SupplicantHidlTest : public ::testing::VtsHalHidlTargetTestBase { public: virtual void SetUp() override { @@ -81,6 +83,7 @@ TEST_F(SupplicantHidlTest, AddStaInterface) { * AddP2pInterface */ TEST_F(SupplicantHidlTest, AddP2pInterface) { + if (!gEnv->isP2pOn) return; ISupplicant::IfaceInfo iface_info; iface_info.name = getP2pIfaceName(); iface_info.type = IfaceType::P2P; @@ -120,6 +123,7 @@ TEST_F(SupplicantHidlTest, RemoveStaInterface) { * RemoveP2pInterface */ TEST_F(SupplicantHidlTest, RemoveP2pInterface) { + if (!gEnv->isP2pOn) return; ISupplicant::IfaceInfo iface_info; iface_info.name = getP2pIfaceName(); iface_info.type = IfaceType::P2P; -- GitLab From ad10741a3ad0ec1029a3ee6a4959f198be29befb Mon Sep 17 00:00:00 2001 From: Tomasz Wasilczyk Date: Fri, 29 May 2020 16:32:43 -0700 Subject: [PATCH 046/790] Implement creating VLAN interfaces Also, minor improvements for TCU: - added existsAndIsUp convenience function - added useCanSockets configuration flag Bug: 156783614 Test: manual Change-Id: Ia3d48655067792b712519e25ed48ae0cb657347b --- .../can/1.0/default/libnetdevice/Android.bp | 1 + .../can/1.0/default/libnetdevice/can.cpp | 2 +- .../include/libnetdevice/libnetdevice.h | 21 ++++++++ .../libnetdevice/include/libnetdevice/vlan.h | 25 +++++++++ .../1.0/default/libnetdevice/libnetdevice.cpp | 28 ++++++++-- .../can/1.0/default/libnetdevice/vlan.cpp | 52 +++++++++++++++++++ automotive/can/1.0/default/service.cpp | 3 ++ 7 files changed, 128 insertions(+), 4 deletions(-) create mode 100644 automotive/can/1.0/default/libnetdevice/include/libnetdevice/vlan.h create mode 100644 automotive/can/1.0/default/libnetdevice/vlan.cpp diff --git a/automotive/can/1.0/default/libnetdevice/Android.bp b/automotive/can/1.0/default/libnetdevice/Android.bp index 31e5ad0376..6e2c7828fa 100644 --- a/automotive/can/1.0/default/libnetdevice/Android.bp +++ b/automotive/can/1.0/default/libnetdevice/Android.bp @@ -25,6 +25,7 @@ cc_library_static { "can.cpp", "common.cpp", "libnetdevice.cpp", + "vlan.cpp", ], export_include_dirs: ["include"], } diff --git a/automotive/can/1.0/default/libnetdevice/can.cpp b/automotive/can/1.0/default/libnetdevice/can.cpp index a2a85dcae8..06fa8aadd2 100644 --- a/automotive/can/1.0/default/libnetdevice/can.cpp +++ b/automotive/can/1.0/default/libnetdevice/can.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include +#include #include "NetlinkRequest.h" #include "NetlinkSocket.h" diff --git a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/libnetdevice.h b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/libnetdevice.h index 3818a31c4c..54cbafcc0d 100644 --- a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/libnetdevice.h +++ b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/libnetdevice.h @@ -21,6 +21,17 @@ namespace android::netdevice { +/** + * Configures libnetdevice to use PF_CAN sockets instead of AF_INET, + * what requires less permissive SEPolicy rules for a given process. + * + * In such case, the process would only be able to control CAN interfaces. + * + * TODO(b/158011272): consider less hacky solution + * \param yes true to use CAN sockets, false for general sockets + */ +void useCanSockets(bool yes); + /** * Checks, if the network interface exists. * @@ -37,6 +48,16 @@ bool exists(std::string ifname); */ std::optional isUp(std::string ifname); +/** + * Checks, if the network interface exists and is up. + * + * This is a convenience function to call both exists() and isUp(). + * + * \param ifname Interface to check + * \return true if the interface is up, false otherwise + */ +bool existsAndIsUp(const std::string& ifname); + /** * Brings network interface up. * diff --git a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/vlan.h b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/vlan.h new file mode 100644 index 0000000000..3e1b736ebd --- /dev/null +++ b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/vlan.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +namespace android::netdevice::vlan { + +bool add(const std::string& eth, const std::string& vlan, uint16_t id); + +} // namespace android::netdevice::vlan diff --git a/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp b/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp index b05144209e..827f8f3905 100644 --- a/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp +++ b/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp @@ -27,14 +27,32 @@ namespace android::netdevice { +namespace socketparams { + +struct Params { + int domain; + int type; + int protocol; +}; + +static constexpr Params general = {AF_INET, SOCK_DGRAM, 0}; +static constexpr Params can = {PF_CAN, SOCK_RAW, CAN_RAW}; + +static Params current = general; + +} // namespace socketparams + +void useCanSockets(bool yes) { + socketparams::current = yes ? socketparams::can : socketparams::general; +} + bool exists(std::string ifname) { return nametoindex(ifname) != 0; } static bool sendIfreq(unsigned long request, struct ifreq& ifr) { - /* For general interfaces it would be socket(AF_INET, SOCK_DGRAM, 0), - * but SEPolicy forces us to limit our flexibility here. */ - base::unique_fd sock(socket(PF_CAN, SOCK_RAW, CAN_RAW)); + base::unique_fd sock(socket(socketparams::current.domain, socketparams::current.type, + socketparams::current.protocol)); if (!sock.ok()) { LOG(ERROR) << "Can't create socket"; return false; @@ -60,6 +78,10 @@ std::optional isUp(std::string ifname) { return ifr.ifr_flags & IFF_UP; } +bool existsAndIsUp(const std::string& ifname) { + return exists(ifname) && isUp(ifname).value_or(false); +} + bool up(std::string ifname) { struct ifreq ifr = ifreqFromName(ifname); if (!sendIfreq(SIOCGIFFLAGS, ifr)) return false; diff --git a/automotive/can/1.0/default/libnetdevice/vlan.cpp b/automotive/can/1.0/default/libnetdevice/vlan.cpp new file mode 100644 index 0000000000..82ef0d9239 --- /dev/null +++ b/automotive/can/1.0/default/libnetdevice/vlan.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "NetlinkRequest.h" +#include "NetlinkSocket.h" +#include "common.h" + +#include + +namespace android::netdevice::vlan { + +bool add(const std::string& eth, const std::string& vlan, uint16_t id) { + const auto ethidx = nametoindex(eth); + if (ethidx == 0) { + LOG(ERROR) << "Ethernet interface " << eth << " doesn't exist"; + return false; + } + + NetlinkRequest req(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL); + req.addattr(IFLA_IFNAME, vlan); + req.addattr(IFLA_LINK, ethidx); + + { + auto linkinfo = req.nest(IFLA_LINKINFO); + req.addattr(IFLA_INFO_KIND, "vlan"); + + { + auto linkinfo = req.nest(IFLA_INFO_DATA); + req.addattr(IFLA_VLAN_ID, id); + } + } + + NetlinkSocket sock(NETLINK_ROUTE); + return sock.send(req) && sock.receiveAck(); +} + +} // namespace android::netdevice::vlan diff --git a/automotive/can/1.0/default/service.cpp b/automotive/can/1.0/default/service.cpp index b52a54a5b7..b5801c0880 100644 --- a/automotive/can/1.0/default/service.cpp +++ b/automotive/can/1.0/default/service.cpp @@ -18,6 +18,7 @@ #include #include +#include namespace android::hardware::automotive::can::V1_0::implementation { @@ -27,6 +28,8 @@ static void canControllerService() { configureRpcThreadpool(16, true); LOG(DEBUG) << "CAN controller service starting..."; + netdevice::useCanSockets(true); + sp canController(new CanController); if (canController->registerAsService("socketcan") != OK) { LOG(FATAL) << "Failed to register CAN controller"; -- GitLab From 8a8bfd188d3d3cdb989aea33d583c2236ae610ef Mon Sep 17 00:00:00 2001 From: Henry Fang Date: Mon, 8 Jun 2020 14:54:41 -0700 Subject: [PATCH 047/790] Remove the enforce to build 32 binary bug: 157096583 Test: Manual Change-Id: Ice58cac7adf46f17606be8c4b2c3fe2e4bf1a472 --- cas/1.0/default/Android.bp | 2 -- cas/1.0/default/DescramblerImpl.cpp | 15 ++++++++------- cas/1.1/default/Android.bp | 2 -- cas/1.1/default/DescramblerImpl.cpp | 15 ++++++++------- cas/1.2/default/Android.bp | 2 -- cas/1.2/default/DescramblerImpl.cpp | 15 ++++++++------- 6 files changed, 24 insertions(+), 27 deletions(-) diff --git a/cas/1.0/default/Android.bp b/cas/1.0/default/Android.bp index f9977ff7be..802dce125f 100644 --- a/cas/1.0/default/Android.bp +++ b/cas/1.0/default/Android.bp @@ -12,8 +12,6 @@ cc_defaults { "TypeConvert.cpp", ], - compile_multilib: "32", - shared_libs: [ "android.hardware.cas@1.0", "android.hardware.cas.native@1.0", diff --git a/cas/1.0/default/DescramblerImpl.cpp b/cas/1.0/default/DescramblerImpl.cpp index 9b09751d72..f79b32db44 100644 --- a/cas/1.0/default/DescramblerImpl.cpp +++ b/cas/1.0/default/DescramblerImpl.cpp @@ -18,6 +18,7 @@ #define LOG_TAG "android.hardware.cas@1.0-DescramblerImpl" #include +#include #include #include #include @@ -101,7 +102,7 @@ Return DescramblerImpl::descramble( // size in size_t. If size is over SIZE_MAX, mapMemory mapMemory could succeed // but the mapped memory's actual size will be smaller than the reported size. if (srcBuffer.heapBase.size() > SIZE_MAX) { - ALOGE("Invalid hidl_memory size: %llu", srcBuffer.heapBase.size()); + ALOGE("Invalid hidl_memory size: %" PRIu64 "", srcBuffer.heapBase.size()); android_errorWriteLog(0x534e4554, "79376389"); _hidl_cb(toStatus(BAD_VALUE), 0, NULL); return Void(); @@ -118,8 +119,8 @@ Return DescramblerImpl::descramble( } if (!validateRangeForSize( srcBuffer.offset, srcBuffer.size, (uint64_t)srcMem->getSize())) { - ALOGE("Invalid src buffer range: offset %llu, size %llu, srcMem size %llu", - srcBuffer.offset, srcBuffer.size, (uint64_t)srcMem->getSize()); + ALOGE("Invalid src buffer range: offset %" PRIu64 ", size %" PRIu64 ", srcMem" + "size %" PRIu64 "", srcBuffer.offset, srcBuffer.size, (uint64_t)srcMem->getSize()); android_errorWriteLog(0x534e4554, "67962232"); _hidl_cb(toStatus(BAD_VALUE), 0, NULL); return Void(); @@ -135,8 +136,8 @@ Return DescramblerImpl::descramble( // is consistent with the source shared buffer size. if (!validateRangeForSize(srcOffset, totalBytesInSubSamples, srcBuffer.size)) { ALOGE("Invalid srcOffset and subsample size: " - "srcOffset %llu, totalBytesInSubSamples %llu, srcBuffer size %llu", - srcOffset, totalBytesInSubSamples, srcBuffer.size); + "srcOffset %" PRIu64 ", totalBytesInSubSamples %" PRIu64 ", srcBuffer" + "size %" PRIu64 "", srcOffset, totalBytesInSubSamples, srcBuffer.size); android_errorWriteLog(0x534e4554, "67962232"); _hidl_cb(toStatus(BAD_VALUE), 0, NULL); return Void(); @@ -153,8 +154,8 @@ Return DescramblerImpl::descramble( // dstOffset against the buffer size too. if (!validateRangeForSize(dstOffset, totalBytesInSubSamples, srcBuffer.size)) { ALOGE("Invalid dstOffset and subsample size: " - "dstOffset %llu, totalBytesInSubSamples %llu, srcBuffer size %llu", - dstOffset, totalBytesInSubSamples, srcBuffer.size); + "dstOffset %" PRIu64 ", totalBytesInSubSamples %" PRIu64 ", srcBuffer" + "size %" PRIu64 "", dstOffset, totalBytesInSubSamples, srcBuffer.size); android_errorWriteLog(0x534e4554, "67962232"); _hidl_cb(toStatus(BAD_VALUE), 0, NULL); return Void(); diff --git a/cas/1.1/default/Android.bp b/cas/1.1/default/Android.bp index 66a1eb8804..dc42a42473 100644 --- a/cas/1.1/default/Android.bp +++ b/cas/1.1/default/Android.bp @@ -12,8 +12,6 @@ cc_defaults { "TypeConvert.cpp", ], - compile_multilib: "32", - shared_libs: [ "android.hardware.cas@1.0", "android.hardware.cas@1.1", diff --git a/cas/1.1/default/DescramblerImpl.cpp b/cas/1.1/default/DescramblerImpl.cpp index 36dc1a51d0..309cd3c007 100644 --- a/cas/1.1/default/DescramblerImpl.cpp +++ b/cas/1.1/default/DescramblerImpl.cpp @@ -18,6 +18,7 @@ #define LOG_TAG "android.hardware.cas@1.1-DescramblerImpl" #include +#include #include #include #include @@ -92,7 +93,7 @@ Return DescramblerImpl::descramble(ScramblingControl scramblingControl, // size in size_t. If size is over SIZE_MAX, mapMemory mapMemory could succeed // but the mapped memory's actual size will be smaller than the reported size. if (srcBuffer.heapBase.size() > SIZE_MAX) { - ALOGE("Invalid hidl_memory size: %llu", srcBuffer.heapBase.size()); + ALOGE("Invalid hidl_memory size: %" PRIu64 "", srcBuffer.heapBase.size()); android_errorWriteLog(0x534e4554, "79376389"); _hidl_cb(toStatus(BAD_VALUE), 0, NULL); return Void(); @@ -108,8 +109,8 @@ Return DescramblerImpl::descramble(ScramblingControl scramblingControl, return Void(); } if (!validateRangeForSize(srcBuffer.offset, srcBuffer.size, (uint64_t)srcMem->getSize())) { - ALOGE("Invalid src buffer range: offset %llu, size %llu, srcMem size %llu", - srcBuffer.offset, srcBuffer.size, (uint64_t)srcMem->getSize()); + ALOGE("Invalid src buffer range: offset %" PRIu64 ", size %" PRIu64 ", srcMem" + "size %" PRIu64 "", srcBuffer.offset, srcBuffer.size, (uint64_t)srcMem->getSize()); android_errorWriteLog(0x534e4554, "67962232"); _hidl_cb(toStatus(BAD_VALUE), 0, NULL); return Void(); @@ -125,8 +126,8 @@ Return DescramblerImpl::descramble(ScramblingControl scramblingControl, // is consistent with the source shared buffer size. if (!validateRangeForSize(srcOffset, totalBytesInSubSamples, srcBuffer.size)) { ALOGE("Invalid srcOffset and subsample size: " - "srcOffset %llu, totalBytesInSubSamples %llu, srcBuffer size %llu", - srcOffset, totalBytesInSubSamples, srcBuffer.size); + "srcOffset %" PRIu64 ", totalBytesInSubSamples %" PRIu64 ", srcBuffer" + "size %" PRIu64 "", srcOffset, totalBytesInSubSamples, srcBuffer.size); android_errorWriteLog(0x534e4554, "67962232"); _hidl_cb(toStatus(BAD_VALUE), 0, NULL); return Void(); @@ -143,8 +144,8 @@ Return DescramblerImpl::descramble(ScramblingControl scramblingControl, // dstOffset against the buffer size too. if (!validateRangeForSize(dstOffset, totalBytesInSubSamples, srcBuffer.size)) { ALOGE("Invalid dstOffset and subsample size: " - "dstOffset %llu, totalBytesInSubSamples %llu, srcBuffer size %llu", - dstOffset, totalBytesInSubSamples, srcBuffer.size); + "dstOffset %" PRIu64 ", totalBytesInSubSamples %" PRIu64 ", srcBuffer" + "size %" PRIu64 "", dstOffset, totalBytesInSubSamples, srcBuffer.size); android_errorWriteLog(0x534e4554, "67962232"); _hidl_cb(toStatus(BAD_VALUE), 0, NULL); return Void(); diff --git a/cas/1.2/default/Android.bp b/cas/1.2/default/Android.bp index 9e5314874f..94d5b3d8c6 100644 --- a/cas/1.2/default/Android.bp +++ b/cas/1.2/default/Android.bp @@ -12,8 +12,6 @@ cc_defaults { "TypeConvert.cpp", ], - compile_multilib: "32", - shared_libs: [ "android.hardware.cas@1.0", "android.hardware.cas@1.1", diff --git a/cas/1.2/default/DescramblerImpl.cpp b/cas/1.2/default/DescramblerImpl.cpp index 36dc1a51d0..309cd3c007 100644 --- a/cas/1.2/default/DescramblerImpl.cpp +++ b/cas/1.2/default/DescramblerImpl.cpp @@ -18,6 +18,7 @@ #define LOG_TAG "android.hardware.cas@1.1-DescramblerImpl" #include +#include #include #include #include @@ -92,7 +93,7 @@ Return DescramblerImpl::descramble(ScramblingControl scramblingControl, // size in size_t. If size is over SIZE_MAX, mapMemory mapMemory could succeed // but the mapped memory's actual size will be smaller than the reported size. if (srcBuffer.heapBase.size() > SIZE_MAX) { - ALOGE("Invalid hidl_memory size: %llu", srcBuffer.heapBase.size()); + ALOGE("Invalid hidl_memory size: %" PRIu64 "", srcBuffer.heapBase.size()); android_errorWriteLog(0x534e4554, "79376389"); _hidl_cb(toStatus(BAD_VALUE), 0, NULL); return Void(); @@ -108,8 +109,8 @@ Return DescramblerImpl::descramble(ScramblingControl scramblingControl, return Void(); } if (!validateRangeForSize(srcBuffer.offset, srcBuffer.size, (uint64_t)srcMem->getSize())) { - ALOGE("Invalid src buffer range: offset %llu, size %llu, srcMem size %llu", - srcBuffer.offset, srcBuffer.size, (uint64_t)srcMem->getSize()); + ALOGE("Invalid src buffer range: offset %" PRIu64 ", size %" PRIu64 ", srcMem" + "size %" PRIu64 "", srcBuffer.offset, srcBuffer.size, (uint64_t)srcMem->getSize()); android_errorWriteLog(0x534e4554, "67962232"); _hidl_cb(toStatus(BAD_VALUE), 0, NULL); return Void(); @@ -125,8 +126,8 @@ Return DescramblerImpl::descramble(ScramblingControl scramblingControl, // is consistent with the source shared buffer size. if (!validateRangeForSize(srcOffset, totalBytesInSubSamples, srcBuffer.size)) { ALOGE("Invalid srcOffset and subsample size: " - "srcOffset %llu, totalBytesInSubSamples %llu, srcBuffer size %llu", - srcOffset, totalBytesInSubSamples, srcBuffer.size); + "srcOffset %" PRIu64 ", totalBytesInSubSamples %" PRIu64 ", srcBuffer" + "size %" PRIu64 "", srcOffset, totalBytesInSubSamples, srcBuffer.size); android_errorWriteLog(0x534e4554, "67962232"); _hidl_cb(toStatus(BAD_VALUE), 0, NULL); return Void(); @@ -143,8 +144,8 @@ Return DescramblerImpl::descramble(ScramblingControl scramblingControl, // dstOffset against the buffer size too. if (!validateRangeForSize(dstOffset, totalBytesInSubSamples, srcBuffer.size)) { ALOGE("Invalid dstOffset and subsample size: " - "dstOffset %llu, totalBytesInSubSamples %llu, srcBuffer size %llu", - dstOffset, totalBytesInSubSamples, srcBuffer.size); + "dstOffset %" PRIu64 ", totalBytesInSubSamples %" PRIu64 ", srcBuffer" + "size %" PRIu64 "", dstOffset, totalBytesInSubSamples, srcBuffer.size); android_errorWriteLog(0x534e4554, "67962232"); _hidl_cb(toStatus(BAD_VALUE), 0, NULL); return Void(); -- GitLab From 376454d935aed40ac412aba7cd4f25d6c9dcd87c Mon Sep 17 00:00:00 2001 From: Henry Fang Date: Mon, 15 Jun 2020 10:47:33 -0700 Subject: [PATCH 048/790] add 32 bit requirement back because of regression from CTS bug: 158703549 bug: 158888458 test: Manual Change-Id: I6248858bac1a59f2f7e7213f4096192925419e3f --- cas/1.0/default/Android.bp | 2 ++ cas/1.1/default/Android.bp | 2 ++ cas/1.2/default/Android.bp | 2 ++ 3 files changed, 6 insertions(+) diff --git a/cas/1.0/default/Android.bp b/cas/1.0/default/Android.bp index 802dce125f..f9977ff7be 100644 --- a/cas/1.0/default/Android.bp +++ b/cas/1.0/default/Android.bp @@ -12,6 +12,8 @@ cc_defaults { "TypeConvert.cpp", ], + compile_multilib: "32", + shared_libs: [ "android.hardware.cas@1.0", "android.hardware.cas.native@1.0", diff --git a/cas/1.1/default/Android.bp b/cas/1.1/default/Android.bp index dc42a42473..66a1eb8804 100644 --- a/cas/1.1/default/Android.bp +++ b/cas/1.1/default/Android.bp @@ -12,6 +12,8 @@ cc_defaults { "TypeConvert.cpp", ], + compile_multilib: "32", + shared_libs: [ "android.hardware.cas@1.0", "android.hardware.cas@1.1", diff --git a/cas/1.2/default/Android.bp b/cas/1.2/default/Android.bp index 94d5b3d8c6..9e5314874f 100644 --- a/cas/1.2/default/Android.bp +++ b/cas/1.2/default/Android.bp @@ -12,6 +12,8 @@ cc_defaults { "TypeConvert.cpp", ], + compile_multilib: "32", + shared_libs: [ "android.hardware.cas@1.0", "android.hardware.cas@1.1", -- GitLab From 1bdd58dcf665fe337a8f79adb664e33efe898bd7 Mon Sep 17 00:00:00 2001 From: Matej Pfajfar Date: Tue, 16 Jun 2020 20:22:12 +0100 Subject: [PATCH 049/790] Change 'blacklist' to 'disallow' Bug: None Test: mma Test: atest Change-Id: I6d1bc4f1cd95a56287127918f4c8111cafd6e833 --- current.txt | 1 + neuralnetworks/1.2/IDevice.hal | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/current.txt b/current.txt index ad7879e484..eb3594bc46 100644 --- a/current.txt +++ b/current.txt @@ -766,6 +766,7 @@ a64467bae843569f0d465c5be7f0c7a5b987985b55a3ef4794dd5afc68538650 android.hardwar 98592d193a717066facf91428426e5abe211e3bd718bc372e29fb944ddbe6e7c android.hardware.wifi.supplicant@1.3::types # ABI preserving changes to HALs during Android S +cd84ab19c590e0e73dd2307b591a3093ee18147ef95e6d5418644463a6620076 android.hardware.neuralnetworks@1.2::IDevice # HALs released in Android S # NOTE: waiting to freeze HALs until later in the release diff --git a/neuralnetworks/1.2/IDevice.hal b/neuralnetworks/1.2/IDevice.hal index ff20c12867..5fb339f1d9 100644 --- a/neuralnetworks/1.2/IDevice.hal +++ b/neuralnetworks/1.2/IDevice.hal @@ -40,7 +40,7 @@ interface IDevice extends @1.1::IDevice { * NNAPI applications filter devices based on their needs: * - An application demands a certain level of performance, but a specific version of * the driver cannot meet that requirement because of a performance regression. - * The application can blacklist the driver based on the version provided. + * The application can disallow the driver based on the version provided. * - An application has a minimum precision requirement, but certain versions of * the driver cannot meet that requirement because of bugs or certain optimizations. * The application can filter out versions of these drivers. -- GitLab From a987273530efe853291d74a7d5fc9e203584d4d7 Mon Sep 17 00:00:00 2001 From: Tomasz Wasilczyk Date: Tue, 2 Jun 2020 18:03:27 -0700 Subject: [PATCH 050/790] Implement Netlink message printer Bug: 158756457 Test: manual Change-Id: I93e40bbf1eff1c4c0e502ca38e07865909ba04f3 --- .../can/1.0/default/libnetdevice/Android.bp | 12 ++ .../1.0/default/libnetdevice/NetlinkRequest.h | 22 +- .../default/libnetdevice/NetlinkSocket.cpp | 22 +- .../1.0/default/libnetdevice/NetlinkSocket.h | 6 +- .../can/1.0/default/libnetdevice/common.cpp | 23 +++ .../can/1.0/default/libnetdevice/common.h | 22 ++ .../include/libnetdevice/printer.h | 27 +++ .../can/1.0/default/libnetdevice/nlbuf.h | 189 ++++++++++++++++++ .../can/1.0/default/libnetdevice/printer.cpp | 168 ++++++++++++++++ .../protocols/MessageDefinition.cpp | 62 ++++++ .../protocols/MessageDefinition.h | 123 ++++++++++++ .../protocols/NetlinkProtocol.cpp | 64 ++++++ .../libnetdevice/protocols/NetlinkProtocol.h | 61 ++++++ .../1.0/default/libnetdevice/protocols/README | 8 + .../default/libnetdevice/protocols/all.cpp | 46 +++++ .../1.0/default/libnetdevice/protocols/all.h | 31 +++ .../libnetdevice/protocols/common/Empty.cpp | 31 +++ .../libnetdevice/protocols/common/Empty.h | 32 +++ .../libnetdevice/protocols/common/Error.cpp | 36 ++++ .../libnetdevice/protocols/common/Error.h | 32 +++ .../libnetdevice/protocols/generic/Ctrl.cpp | 55 +++++ .../libnetdevice/protocols/generic/Ctrl.h | 28 +++ .../protocols/generic/Generic.cpp | 36 ++++ .../libnetdevice/protocols/generic/Generic.h | 37 ++++ .../protocols/generic/GenericMessageBase.cpp | 40 ++++ .../protocols/generic/GenericMessageBase.h | 40 ++++ .../protocols/generic/Unknown.cpp | 24 +++ .../libnetdevice/protocols/generic/Unknown.h | 28 +++ .../libnetdevice/protocols/route/Link.cpp | 99 +++++++++ .../libnetdevice/protocols/route/Link.h | 31 +++ .../libnetdevice/protocols/route/Route.cpp | 25 +++ .../libnetdevice/protocols/route/Route.h | 31 +++ .../can/1.0/default/libnetdevice/types.h | 27 +++ 33 files changed, 1505 insertions(+), 13 deletions(-) create mode 100644 automotive/can/1.0/default/libnetdevice/include/libnetdevice/printer.h create mode 100644 automotive/can/1.0/default/libnetdevice/nlbuf.h create mode 100644 automotive/can/1.0/default/libnetdevice/printer.cpp create mode 100644 automotive/can/1.0/default/libnetdevice/protocols/MessageDefinition.cpp create mode 100644 automotive/can/1.0/default/libnetdevice/protocols/MessageDefinition.h create mode 100644 automotive/can/1.0/default/libnetdevice/protocols/NetlinkProtocol.cpp create mode 100644 automotive/can/1.0/default/libnetdevice/protocols/NetlinkProtocol.h create mode 100644 automotive/can/1.0/default/libnetdevice/protocols/README create mode 100644 automotive/can/1.0/default/libnetdevice/protocols/all.cpp create mode 100644 automotive/can/1.0/default/libnetdevice/protocols/all.h create mode 100644 automotive/can/1.0/default/libnetdevice/protocols/common/Empty.cpp create mode 100644 automotive/can/1.0/default/libnetdevice/protocols/common/Empty.h create mode 100644 automotive/can/1.0/default/libnetdevice/protocols/common/Error.cpp create mode 100644 automotive/can/1.0/default/libnetdevice/protocols/common/Error.h create mode 100644 automotive/can/1.0/default/libnetdevice/protocols/generic/Ctrl.cpp create mode 100644 automotive/can/1.0/default/libnetdevice/protocols/generic/Ctrl.h create mode 100644 automotive/can/1.0/default/libnetdevice/protocols/generic/Generic.cpp create mode 100644 automotive/can/1.0/default/libnetdevice/protocols/generic/Generic.h create mode 100644 automotive/can/1.0/default/libnetdevice/protocols/generic/GenericMessageBase.cpp create mode 100644 automotive/can/1.0/default/libnetdevice/protocols/generic/GenericMessageBase.h create mode 100644 automotive/can/1.0/default/libnetdevice/protocols/generic/Unknown.cpp create mode 100644 automotive/can/1.0/default/libnetdevice/protocols/generic/Unknown.h create mode 100644 automotive/can/1.0/default/libnetdevice/protocols/route/Link.cpp create mode 100644 automotive/can/1.0/default/libnetdevice/protocols/route/Link.h create mode 100644 automotive/can/1.0/default/libnetdevice/protocols/route/Route.cpp create mode 100644 automotive/can/1.0/default/libnetdevice/protocols/route/Route.h create mode 100644 automotive/can/1.0/default/libnetdevice/types.h diff --git a/automotive/can/1.0/default/libnetdevice/Android.bp b/automotive/can/1.0/default/libnetdevice/Android.bp index 6e2c7828fa..c5fd3111fc 100644 --- a/automotive/can/1.0/default/libnetdevice/Android.bp +++ b/automotive/can/1.0/default/libnetdevice/Android.bp @@ -20,11 +20,23 @@ cc_library_static { vendor_available: true, relative_install_path: "hw", srcs: [ + "protocols/common/Empty.cpp", + "protocols/common/Error.cpp", + "protocols/generic/Ctrl.cpp", + "protocols/generic/Generic.cpp", + "protocols/generic/GenericMessageBase.cpp", + "protocols/generic/Unknown.cpp", + "protocols/route/Link.cpp", + "protocols/route/Route.cpp", + "protocols/MessageDefinition.cpp", + "protocols/NetlinkProtocol.cpp", + "protocols/all.cpp", "NetlinkRequest.cpp", "NetlinkSocket.cpp", "can.cpp", "common.cpp", "libnetdevice.cpp", + "printer.cpp", "vlan.cpp", ], export_include_dirs: ["include"], diff --git a/automotive/can/1.0/default/libnetdevice/NetlinkRequest.h b/automotive/can/1.0/default/libnetdevice/NetlinkRequest.h index 3e28d78485..5bea3335f1 100644 --- a/automotive/can/1.0/default/libnetdevice/NetlinkRequest.h +++ b/automotive/can/1.0/default/libnetdevice/NetlinkRequest.h @@ -16,6 +16,8 @@ #pragma once +#include "types.h" + #include #include @@ -23,12 +25,10 @@ namespace android::netdevice { -typedef unsigned short rtattrtype_t; // as in rtnetlink.h -typedef __u16 nlmsgtype_t; // as in netlink.h - /** Implementation details, do not use outside NetlinkRequest template. */ namespace impl { +// TODO(twasilczyk): use nlattr instead of rtattr struct rtattr* addattr_l(struct nlmsghdr* n, size_t maxLen, rtattrtype_t type, const void* data, size_t dataLen); struct rtattr* addattr_nest(struct nlmsghdr* n, size_t maxLen, rtattrtype_t type); @@ -36,6 +36,7 @@ void addattr_nest_end(struct nlmsghdr* n, struct rtattr* nest); } // namespace impl +// TODO(twasilczyk): rename to NetlinkMessage /** * Wrapper around NETLINK_ROUTE messages, to build them in C++ style. * @@ -44,6 +45,14 @@ void addattr_nest_end(struct nlmsghdr* n, struct rtattr* nest); */ template struct NetlinkRequest { + struct RequestData { + struct nlmsghdr nlmsg; + T data; + char buf[BUFSIZE]; + }; + + static constexpr size_t totalLength = sizeof(RequestData); + /** * Create empty message. * @@ -131,12 +140,7 @@ struct NetlinkRequest { private: bool mIsGood = true; - - struct { - struct nlmsghdr nlmsg; - T data; - char buf[BUFSIZE]; - } mRequest = {}; + RequestData mRequest = {}; struct rtattr* nestStart(rtattrtype_t type) { if (!mIsGood) return nullptr; diff --git a/automotive/can/1.0/default/libnetdevice/NetlinkSocket.cpp b/automotive/can/1.0/default/libnetdevice/NetlinkSocket.cpp index 7817169876..15c0f9b6dd 100644 --- a/automotive/can/1.0/default/libnetdevice/NetlinkSocket.cpp +++ b/automotive/can/1.0/default/libnetdevice/NetlinkSocket.cpp @@ -16,11 +16,18 @@ #include "NetlinkSocket.h" +#include + #include namespace android::netdevice { -NetlinkSocket::NetlinkSocket(int protocol) { +/** + * Print all outbound/inbound Netlink messages. + */ +static constexpr bool kSuperVerbose = false; + +NetlinkSocket::NetlinkSocket(int protocol) : mProtocol(protocol) { mFd.reset(socket(AF_NETLINK, SOCK_RAW, protocol)); if (!mFd.ok()) { PLOG(ERROR) << "Can't open Netlink socket"; @@ -38,7 +45,13 @@ NetlinkSocket::NetlinkSocket(int protocol) { } } -bool NetlinkSocket::send(struct nlmsghdr* nlmsg) { +bool NetlinkSocket::send(struct nlmsghdr* nlmsg, size_t totalLen) { + if constexpr (kSuperVerbose) { + nlmsg->nlmsg_seq = mSeq; + LOG(VERBOSE) << (mFailed ? "(not)" : "") + << "sending Netlink message: " << toString(nlmsg, totalLen, mProtocol); + } + if (mFailed) return false; nlmsg->nlmsg_pid = 0; // kernel @@ -91,6 +104,11 @@ bool NetlinkSocket::receiveAck() { for (auto nlmsg = reinterpret_cast(buf); NLMSG_OK(nlmsg, remainingLen); nlmsg = NLMSG_NEXT(nlmsg, remainingLen)) { + if constexpr (kSuperVerbose) { + LOG(VERBOSE) << "received Netlink response: " + << toString(nlmsg, sizeof(buf), mProtocol); + } + // We're looking for error/ack message only, ignoring others. if (nlmsg->nlmsg_type != NLMSG_ERROR) { LOG(WARNING) << "Received unexpected Netlink message (ignored): " << nlmsg->nlmsg_type; diff --git a/automotive/can/1.0/default/libnetdevice/NetlinkSocket.h b/automotive/can/1.0/default/libnetdevice/NetlinkSocket.h index 2b40ea20c0..595c31acf6 100644 --- a/automotive/can/1.0/default/libnetdevice/NetlinkSocket.h +++ b/automotive/can/1.0/default/libnetdevice/NetlinkSocket.h @@ -43,7 +43,7 @@ struct NetlinkSocket { template bool send(NetlinkRequest& req) { if (!req.isGood()) return false; - return send(req.header()); + return send(req.header(), req.totalLength); } /** @@ -54,11 +54,13 @@ struct NetlinkSocket { bool receiveAck(); private: + const int mProtocol; + uint32_t mSeq = 0; base::unique_fd mFd; bool mFailed = false; - bool send(struct nlmsghdr* msg); + bool send(struct nlmsghdr* msg, size_t totalLen); DISALLOW_COPY_AND_ASSIGN(NetlinkSocket); }; diff --git a/automotive/can/1.0/default/libnetdevice/common.cpp b/automotive/can/1.0/default/libnetdevice/common.cpp index 5c624439cd..f64d7d3e5c 100644 --- a/automotive/can/1.0/default/libnetdevice/common.cpp +++ b/automotive/can/1.0/default/libnetdevice/common.cpp @@ -33,4 +33,27 @@ unsigned int nametoindex(const std::string& ifname) { return 0; } +std::string sanitize(std::string str) { + str.erase(std::find(str.begin(), str.end(), '\0'), str.end()); + + const auto isInvalid = [](char c) { return !isprint(c); }; + std::replace_if(str.begin(), str.end(), isInvalid, '?'); + + return str; +} + +uint16_t crc16(const nlbuf data, uint16_t crc) { + for (const auto byte : data.getRaw()) { + crc ^= byte; + for (unsigned i = 0; i < 8; i++) { + if (crc & 1) { + crc = (crc >> 1) ^ 0xA001; + } else { + crc >>= 1; + } + } + } + return crc; +} + } // namespace android::netdevice diff --git a/automotive/can/1.0/default/libnetdevice/common.h b/automotive/can/1.0/default/libnetdevice/common.h index 8097f374ad..c52183588b 100644 --- a/automotive/can/1.0/default/libnetdevice/common.h +++ b/automotive/can/1.0/default/libnetdevice/common.h @@ -16,6 +16,8 @@ #pragma once +#include "nlbuf.h" + #include namespace android::netdevice { @@ -31,4 +33,24 @@ namespace android::netdevice { */ unsigned int nametoindex(const std::string& ifname); +/** + * Sanitize a string of unknown contents. + * + * Trims the string to the first '\0' character and replaces all non-printable characters with '?'. + */ +std::string sanitize(std::string str); + +/** + * Calculates a (optionally running) CRC16 checksum. + * + * CRC16 isn't a strong checksum, but is good for quick comparison purposes. + * One benefit (and also a drawback too) is that all-zero payloads with any length will + * always have a checksum of 0x0000. + * + * \param data Buffer to calculate checksum for + * \param crc Previous CRC16 value to continue calculating running checksum + * \return CRC16 checksum + */ +uint16_t crc16(const nlbuf data, uint16_t crc = 0); + } // namespace android::netdevice diff --git a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/printer.h b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/printer.h new file mode 100644 index 0000000000..efeb6b16b9 --- /dev/null +++ b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/printer.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +#include + +namespace android::netdevice { + +std::string toString(const nlmsghdr* hdr, size_t bufLen, int protocol); + +} // namespace android::netdevice diff --git a/automotive/can/1.0/default/libnetdevice/nlbuf.h b/automotive/can/1.0/default/libnetdevice/nlbuf.h new file mode 100644 index 0000000000..f7e53be48e --- /dev/null +++ b/automotive/can/1.0/default/libnetdevice/nlbuf.h @@ -0,0 +1,189 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +#include + +#include + +namespace android::netdevice { + +/** + * Buffer containing netlink structure (e.g. struct nlmsghdr, struct nlattr). + * + * This is a C++-style, memory safe(r) and generic implementation of linux/netlink.h macros. + * + * While netlink structures contain information about their total length (with payload), they can + * not be trusted - the value may either be larger than the buffer message is allocated in or + * smaller than the header itself (so it couldn't even fit itself). + * + * As a solution, nlbuf<> keeps track of two lengths (both attribute for header with payload): + * - buffer length - how much memory was allocated to a given structure + * - declared length - what nlmsg_len or nla_len says how long the structure is + * + * In most cases buffer length would be larger than declared length (or equal - modulo alignment - + * for continuous data). If that's not the case, there is a potential of ouf-of-bounds read which + * this template attempts to protect against. + */ +template +class nlbuf { + // The following definitions are C++ equivalents of NLMSG_* macros from linux/netlink.h + + static constexpr size_t alignto = NLMSG_ALIGNTO; + static_assert(NLMSG_ALIGNTO == NLA_ALIGNTO); + + static constexpr size_t align(size_t ptr) { return (ptr + alignto - 1) & ~(alignto - 1); } + + static constexpr size_t hdrlen = align(sizeof(T)); + + public: + nlbuf(const T* data, size_t bufferLen) : mData(data), mBufferEnd(pointerAdd(data, bufferLen)) {} + + const T* operator->() const { + CHECK(firstOk()) << "buffer can't fit the first element's header"; + return mData; + } + + std::optional> getFirst() const { + if (!ok()) return std::nullopt; + return *mData; + } + + /** + * Copy the first element of the buffer. + * + * This is a memory-safe cast operation, useful for reading e.g. uint32_t values + * from 1-byte buffer. + */ + T copyFirst() const { + T val = {}; + memcpy(&val, mData, std::min(sizeof(val), remainingLength())); + return val; + } + + bool firstOk() const { return sizeof(T) <= remainingLength(); } + + template + const nlbuf data(size_t offset = 0) const { + // Equivalent to NLMSG_DATA(hdr) + NLMSG_ALIGN(offset) + const D* dptr = reinterpret_cast(uintptr_t(mData) + hdrlen + align(offset)); + return {dptr, dataEnd()}; + } + + class iterator { + public: + iterator() : mCurrent(nullptr, size_t(0)) { + CHECK(!mCurrent.ok()) << "end() iterator should indicate it's beyond end"; + } + iterator(const nlbuf& buf) : mCurrent(buf) {} + + iterator operator++() { + // mBufferEnd stays the same + mCurrent.mData = reinterpret_cast( // + uintptr_t(mCurrent.mData) + align(mCurrent.declaredLength())); + + return *this; + } + + bool operator==(const iterator& other) const { + // all iterators beyond end are the same + if (!mCurrent.ok() && !other.mCurrent.ok()) return true; + + return uintptr_t(other.mCurrent.mData) == uintptr_t(mCurrent.mData); + } + + const nlbuf& operator*() const { return mCurrent; } + + protected: + nlbuf mCurrent; + }; + iterator begin() const { return {*this}; } + iterator end() const { return {}; } + + class raw_iterator : public iterator { + public: + iterator operator++() { + this->mCurrent.mData++; // ignore alignment + return *this; + } + const T& operator*() const { return *this->mCurrent.mData; } + }; + + class raw_view { + public: + raw_view(const nlbuf& buffer) : mBuffer(buffer) {} + raw_iterator begin() const { return {mBuffer}; } + raw_iterator end() const { return {}; } + + const T* ptr() const { return mBuffer.mData; } + size_t len() const { return mBuffer.remainingLength(); } + + private: + const nlbuf& mBuffer; + }; + + raw_view getRaw() const { return {*this}; } + + private: + const T* mData; + const void* mBufferEnd; + + nlbuf(const T* data, const void* bufferEnd) : mData(data), mBufferEnd(bufferEnd) {} + + bool ok() const { return declaredLength() <= remainingLength(); } + + // to be specialized individually for each T with payload after a header + inline size_t declaredLengthImpl() const { return sizeof(T); } + + size_t declaredLength() const { + // We can't even fit a header, so let's return some absurd high value to trip off + // buffer overflow checks. + if (sizeof(T) > remainingLength()) return std::numeric_limits::max() / 2; + return declaredLengthImpl(); + } + + size_t remainingLength() const { + auto len = intptr_t(mBufferEnd) - intptr_t(mData); + return (len >= 0) ? len : 0; + } + + const void* dataEnd() const { + auto declaredEnd = pointerAdd(mData, declaredLength()); + return std::min(declaredEnd, mBufferEnd); + } + + static const void* pointerAdd(const void* ptr, size_t len) { + return reinterpret_cast(uintptr_t(ptr) + len); + } + + template + friend class nlbuf; // calling private constructor of data buffers +}; + +template <> +inline size_t nlbuf::declaredLengthImpl() const { + return mData->nlmsg_len; +} + +template <> +inline size_t nlbuf::declaredLengthImpl() const { + return mData->nla_len; +} + +} // namespace android::netdevice diff --git a/automotive/can/1.0/default/libnetdevice/printer.cpp b/automotive/can/1.0/default/libnetdevice/printer.cpp new file mode 100644 index 0000000000..8e17e7f6ad --- /dev/null +++ b/automotive/can/1.0/default/libnetdevice/printer.cpp @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "common.h" +#include "nlbuf.h" +#include "protocols/all.h" + +#include + +#include +#include +#include + +namespace android::netdevice { + +static void flagsToStream(std::stringstream& ss, __u16 nlmsg_flags) { + bool first = true; + auto printFlag = [&ss, &first, &nlmsg_flags](__u16 flag, const std::string& name) { + if (!(nlmsg_flags & flag)) return; + nlmsg_flags &= ~flag; + + if (first) { + first = false; + } else { + ss << '|'; + } + + ss << name; + }; + printFlag(NLM_F_REQUEST, "REQUEST"); + printFlag(NLM_F_MULTI, "MULTI"); + printFlag(NLM_F_ACK, "ACK"); + printFlag(NLM_F_ECHO, "ECHO"); + printFlag(NLM_F_DUMP_INTR, "DUMP_INTR"); + printFlag(NLM_F_DUMP_FILTERED, "DUMP_FILTERED"); + + // TODO(twasilczyk): print flags depending on request type + printFlag(NLM_F_ROOT, "ROOT-REPLACE"); + printFlag(NLM_F_MATCH, "MATCH-EXCL"); + printFlag(NLM_F_ATOMIC, "ATOMIC-CREATE"); + printFlag(NLM_F_APPEND, "APPEND"); + + if (nlmsg_flags != 0) { + if (!first) ss << '|'; + ss << std::hex << nlmsg_flags << std::dec; + } +} + +static void toStream(std::stringstream& ss, const nlbuf data) { + ss << std::hex; + int i = 0; + for (const auto byte : data.getRaw()) { + if (i++ > 0) ss << ' '; + ss << std::setw(2) << unsigned(byte); + } + ss << std::dec; +} + +static void toStream(std::stringstream& ss, const nlbuf attr, + const protocols::AttributeMap& attrMap) { + using DataType = protocols::AttributeDefinition::DataType; + const auto attrtype = attrMap[attr->nla_type]; + + ss << attrtype.name << ": "; + switch (attrtype.dataType) { + case DataType::Raw: { + toStream(ss, attr.data()); + break; + } + case DataType::Nested: { + ss << '{'; + bool first = true; + for (auto childattr : attr.data()) { + if (!first) ss << ", "; + first = false; + toStream(ss, childattr, attrtype.subTypes); + } + ss << '}'; + break; + } + case DataType::String: { + const auto str = attr.data().getRaw(); + ss << '"' << sanitize({str.ptr(), str.len()}) << '"'; + break; + } + case DataType::Uint: { + ss << attr.data().copyFirst(); + break; + } + } +} + +static std::string toString(const nlbuf hdr, int protocol) { + if (!hdr.firstOk()) return "nlmsg{buffer overflow}"; + + std::stringstream ss; + ss << std::setfill('0'); + + auto protocolMaybe = protocols::get(protocol); + if (!protocolMaybe.has_value()) { + ss << "nlmsg{protocol=" << protocol << "}"; + return ss.str(); + } + protocols::NetlinkProtocol& protocolDescr = *protocolMaybe; + + auto msgDescMaybe = protocolDescr.getMessageDescriptor(hdr->nlmsg_type); + const auto msgTypeName = msgDescMaybe.has_value() + ? msgDescMaybe->get().getMessageName(hdr->nlmsg_type) + : std::to_string(hdr->nlmsg_type); + + ss << "nlmsg{" << protocolDescr.getName() << " "; + + ss << "hdr={"; + ss << "type=" << msgTypeName; + if (hdr->nlmsg_flags != 0) { + ss << ", flags="; + flagsToStream(ss, hdr->nlmsg_flags); + } + if (hdr->nlmsg_seq != 0) ss << ", seq=" << hdr->nlmsg_seq; + if (hdr->nlmsg_pid != 0) ss << ", pid=" << hdr->nlmsg_pid; + + ss << ", crc=" << std::hex << std::setw(4) << crc16(hdr.data()) << std::dec; + ss << "} "; + + if (!msgDescMaybe.has_value()) { + toStream(ss, hdr.data()); + } else { + const protocols::MessageDescriptor& msgDesc = *msgDescMaybe; + msgDesc.dataToStream(ss, hdr); + + bool first = true; + for (auto attr : hdr.data(msgDesc.getContentsSize())) { + if (first) { + ss << " attributes: {"; + first = false; + } else { + ss << ", "; + } + toStream(ss, attr, msgDesc.getAttributeMap()); + } + if (!first) ss << '}'; + } + + ss << "}"; + + return ss.str(); +} + +std::string toString(const nlmsghdr* hdr, size_t bufLen, int protocol) { + return toString({hdr, bufLen}, protocol); +} + +} // namespace android::netdevice diff --git a/automotive/can/1.0/default/libnetdevice/protocols/MessageDefinition.cpp b/automotive/can/1.0/default/libnetdevice/protocols/MessageDefinition.cpp new file mode 100644 index 0000000000..cb42896c67 --- /dev/null +++ b/automotive/can/1.0/default/libnetdevice/protocols/MessageDefinition.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "MessageDefinition.h" + +namespace android::netdevice::protocols { + +AttributeMap::AttributeMap(const std::initializer_list attrTypes) + : std::map, AttributeDefinition>(attrTypes) {} + +const AttributeDefinition AttributeMap::operator[](nlattrtype_t nla_type) const { + if (count(nla_type) == 0) { + if (count(std::nullopt) == 0) return {std::to_string(nla_type)}; + + auto definition = find(std::nullopt)->second; + definition.name += std::to_string(nla_type); + return definition; + } + return find(nla_type)->second; +} + +MessageDescriptor::MessageDescriptor(const std::string& name, const MessageTypeMap&& messageTypes, + const AttributeMap&& attrTypes, size_t contentsSize) + : mName(name), + mContentsSize(contentsSize), + mMessageTypes(messageTypes), + mAttributeMap(attrTypes) {} + +MessageDescriptor::~MessageDescriptor() {} + +size_t MessageDescriptor::getContentsSize() const { + return mContentsSize; +} + +const MessageDescriptor::MessageTypeMap& MessageDescriptor::getMessageTypeMap() const { + return mMessageTypes; +} + +const AttributeMap& MessageDescriptor::getAttributeMap() const { + return mAttributeMap; +} + +const std::string MessageDescriptor::getMessageName(nlmsgtype_t msgtype) const { + const auto it = mMessageTypes.find(msgtype); + if (it == mMessageTypes.end()) return "?"; + return it->second; +} + +} // namespace android::netdevice::protocols diff --git a/automotive/can/1.0/default/libnetdevice/protocols/MessageDefinition.h b/automotive/can/1.0/default/libnetdevice/protocols/MessageDefinition.h new file mode 100644 index 0000000000..9764f8d17e --- /dev/null +++ b/automotive/can/1.0/default/libnetdevice/protocols/MessageDefinition.h @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "nlbuf.h" +#include "types.h" + +#include +#include + +namespace android::netdevice::protocols { + +struct AttributeDefinition; + +/** + * Mapping between nlattrtype_t identifier and attribute definition. + * + * The map contains values for all nlattrtype_t identifiers - if some is missing, a generic + * definition with a identifier as its name will be generated. + * + * It's possible to define a default attribute to return instead of to_string of its identifier + * (useful for nested attribute lists). In such case, an entry with id=std::nullopt needs to be + * present in the map. + */ +class AttributeMap : private std::map, AttributeDefinition> { + public: + using std::map, AttributeDefinition>::value_type; + + AttributeMap(const std::initializer_list attrTypes); + + const AttributeDefinition operator[](nlattrtype_t nla_type) const; +}; + +/** + * Attribute definition. + * + * Describes the name and type (optionally sub types, in case of Nested attribute) + * for a given message attribute. + */ +struct AttributeDefinition { + enum class DataType : uint8_t { + Raw, + Nested, + String, + Uint, + }; + + std::string name; + DataType dataType = DataType::Raw; + AttributeMap subTypes = {}; +}; + +/** + * Message family descriptor. + * + * Describes the structure of all message types with the same header and attributes. + */ +class MessageDescriptor { + protected: + typedef std::map MessageTypeMap; + + MessageDescriptor(const std::string& name, const MessageTypeMap&& messageTypes, + const AttributeMap&& attrTypes, size_t contentsSize); + + public: + virtual ~MessageDescriptor(); + + size_t getContentsSize() const; + const MessageTypeMap& getMessageTypeMap() const; + const AttributeMap& getAttributeMap() const; + const std::string getMessageName(nlmsgtype_t msgtype) const; + virtual void dataToStream(std::stringstream& ss, const nlbuf hdr) const = 0; + + private: + const std::string mName; + const size_t mContentsSize; + const MessageTypeMap mMessageTypes; + const AttributeMap mAttributeMap; +}; + +/** + * Message definition template. + * + * A convenience initialization helper of a message descriptor. + */ +template +class MessageDefinition : public MessageDescriptor { + public: + MessageDefinition( + const std::string& name, + const std::initializer_list messageTypes, + const std::initializer_list attrTypes = {}) + : MessageDescriptor(name, messageTypes, attrTypes, sizeof(T)) {} + + void dataToStream(std::stringstream& ss, const nlbuf hdr) const override { + const auto msg = hdr.data().getFirst(); + if (!msg.has_value()) { + ss << "{incomplete payload}"; + return; + } + + toStream(ss, *msg); + } + + protected: + virtual void toStream(std::stringstream& ss, const T& data) const = 0; +}; + +} // namespace android::netdevice::protocols diff --git a/automotive/can/1.0/default/libnetdevice/protocols/NetlinkProtocol.cpp b/automotive/can/1.0/default/libnetdevice/protocols/NetlinkProtocol.cpp new file mode 100644 index 0000000000..4b6cefb8be --- /dev/null +++ b/automotive/can/1.0/default/libnetdevice/protocols/NetlinkProtocol.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "NetlinkProtocol.h" + +namespace android::netdevice::protocols { + +NetlinkProtocol::NetlinkProtocol(int protocol, const std::string name, + const MessageDescriptorList&& messageDescrs) + : mProtocol(protocol), mName(name), mMessageDescrs(toMap(messageDescrs, protocol)) {} + +NetlinkProtocol::~NetlinkProtocol() {} + +int NetlinkProtocol::getProtocol() const { + return mProtocol; +} + +const std::string& NetlinkProtocol::getName() const { + return mName; +} + +const std::optional> +NetlinkProtocol::getMessageDescriptor(nlmsgtype_t nlmsg_type) { + if (mMessageDescrs.count(nlmsg_type) == 0) return std::nullopt; + return *mMessageDescrs.find(nlmsg_type)->second; +} + +NetlinkProtocol::MessageDescriptorMap NetlinkProtocol::toMap( + const NetlinkProtocol::MessageDescriptorList& descrs, int protocol) { + MessageDescriptorMap map; + for (const auto& descr : descrs) { + for (const auto& [mtype, mname] : descr->getMessageTypeMap()) { + map.emplace(mtype, descr); + } + } + + const MessageDescriptorList baseDescriptors = { + std::make_shared(), + std::make_shared(protocol), + }; + + for (const auto& descr : baseDescriptors) { + for (const auto& [mtype, mname] : descr->getMessageTypeMap()) { + map.emplace(mtype, descr); + } + } + + return map; +} + +} // namespace android::netdevice::protocols diff --git a/automotive/can/1.0/default/libnetdevice/protocols/NetlinkProtocol.h b/automotive/can/1.0/default/libnetdevice/protocols/NetlinkProtocol.h new file mode 100644 index 0000000000..0e1878d74d --- /dev/null +++ b/automotive/can/1.0/default/libnetdevice/protocols/NetlinkProtocol.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "MessageDefinition.h" +#include "common/Empty.h" +#include "common/Error.h" +#include "types.h" + +#include +#include + +namespace android::netdevice::protocols { + +/** + * Netlink-based protocol definition. + * + * Usually it's just an id/name and a list of supported messages. + */ +class NetlinkProtocol { + public: + virtual ~NetlinkProtocol(); + + int getProtocol() const; + + const std::string& getName() const; + + virtual const std::optional> + getMessageDescriptor(nlmsgtype_t nlmsg_type); + + protected: + typedef std::vector> MessageDescriptorList; + + NetlinkProtocol(int protocol, const std::string name, + const MessageDescriptorList&& messageDescrs); + + private: + typedef std::map> MessageDescriptorMap; + + const int mProtocol; + const std::string mName; + const MessageDescriptorMap mMessageDescrs; + + static MessageDescriptorMap toMap(const MessageDescriptorList& descrs, int protocol); +}; + +} // namespace android::netdevice::protocols diff --git a/automotive/can/1.0/default/libnetdevice/protocols/README b/automotive/can/1.0/default/libnetdevice/protocols/README new file mode 100644 index 0000000000..45c95c40ea --- /dev/null +++ b/automotive/can/1.0/default/libnetdevice/protocols/README @@ -0,0 +1,8 @@ +This folder contains message definitions for various protocols based on Netlink. + +The structure is as follows: +protocols/*.(cpp|h) - base definition classes and protocol definition lookup +protocols/common/ - common message types that apply to all protocols +protocols//.(cpp|h) - protocol definition (usually just a list of message types) +protocols//*.(cpp|h) - message definition that covers all message types with the same + header (T type in MessageDefinition template) and attributes diff --git a/automotive/can/1.0/default/libnetdevice/protocols/all.cpp b/automotive/can/1.0/default/libnetdevice/protocols/all.cpp new file mode 100644 index 0000000000..980e3d0f16 --- /dev/null +++ b/automotive/can/1.0/default/libnetdevice/protocols/all.cpp @@ -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. + */ + +#include "all.h" + +#include "generic/Generic.h" +#include "route/Route.h" + +#include + +namespace android::netdevice::protocols { + +// This should be a map of unique_ptr, but it's not trivial to uniformly initialize such a map +static std::map> toMap( + std::initializer_list> l) { + std::map> map; + for (auto p : l) { + map[p->getProtocol()] = p; + } + return map; +} + +static auto all = toMap({ + std::make_unique(), + std::make_unique(), +}); + +std::optional> get(int protocol) { + if (all.count(protocol) == 0) return std::nullopt; + return *all.find(protocol)->second.get(); +} + +} // namespace android::netdevice::protocols diff --git a/automotive/can/1.0/default/libnetdevice/protocols/all.h b/automotive/can/1.0/default/libnetdevice/protocols/all.h new file mode 100644 index 0000000000..2180ebb017 --- /dev/null +++ b/automotive/can/1.0/default/libnetdevice/protocols/all.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "NetlinkProtocol.h" + +namespace android::netdevice::protocols { + +/** + * Protocol definition lookup. + * + * \param protocol Protocol identifier from linux/netlink.h + * \return Protocol definition or nullopt if it's not implemented + */ +std::optional> get(int protocol); + +} // namespace android::netdevice::protocols diff --git a/automotive/can/1.0/default/libnetdevice/protocols/common/Empty.cpp b/automotive/can/1.0/default/libnetdevice/protocols/common/Empty.cpp new file mode 100644 index 0000000000..9f252039da --- /dev/null +++ b/automotive/can/1.0/default/libnetdevice/protocols/common/Empty.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Empty.h" + +namespace android::netdevice::protocols::base { + +// clang-format off +Empty::Empty() : MessageDefinition("nlmsg", { + {NLMSG_NOOP, "NOOP"}, + {NLMSG_DONE, "DONE"}, + {NLMSG_OVERRUN, "OVERRUN"}, +}) {} +// clang-format on + +void Empty::toStream(std::stringstream&, const char&) const {} + +} // namespace android::netdevice::protocols::base diff --git a/automotive/can/1.0/default/libnetdevice/protocols/common/Empty.h b/automotive/can/1.0/default/libnetdevice/protocols/common/Empty.h new file mode 100644 index 0000000000..b5b317f436 --- /dev/null +++ b/automotive/can/1.0/default/libnetdevice/protocols/common/Empty.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "../MessageDefinition.h" + +#include + +namespace android::netdevice::protocols::base { + +// no-payload (like NLMSG_NOOP) messages can't be defined with T=void, so let's use char +class Empty : public MessageDefinition { + public: + Empty(); + void toStream(std::stringstream&, const char&) const override; +}; + +} // namespace android::netdevice::protocols::base diff --git a/automotive/can/1.0/default/libnetdevice/protocols/common/Error.cpp b/automotive/can/1.0/default/libnetdevice/protocols/common/Error.cpp new file mode 100644 index 0000000000..d42a50ac57 --- /dev/null +++ b/automotive/can/1.0/default/libnetdevice/protocols/common/Error.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Error.h" + +#include "../MessageDefinition.h" + +#include + +namespace android::netdevice::protocols::base { + +// clang-format off +Error::Error(int protocol) : MessageDefinition("nlmsg", { + {NLMSG_ERROR, "ERROR"}, +}), mProtocol(protocol) {} +// clang-format on + +void Error::toStream(std::stringstream& ss, const nlmsgerr& data) const { + ss << "nlmsgerr{error=" << data.error + << ", msg=" << toString(&data.msg, sizeof(data.msg), mProtocol) << "}"; +} + +} // namespace android::netdevice::protocols::base diff --git a/automotive/can/1.0/default/libnetdevice/protocols/common/Error.h b/automotive/can/1.0/default/libnetdevice/protocols/common/Error.h new file mode 100644 index 0000000000..1f3c1dd694 --- /dev/null +++ b/automotive/can/1.0/default/libnetdevice/protocols/common/Error.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "../MessageDefinition.h" + +namespace android::netdevice::protocols::base { + +class Error : public MessageDefinition { + public: + Error(int protocol); + void toStream(std::stringstream& ss, const nlmsgerr& data) const override; + + private: + const int mProtocol; +}; + +} // namespace android::netdevice::protocols::base diff --git a/automotive/can/1.0/default/libnetdevice/protocols/generic/Ctrl.cpp b/automotive/can/1.0/default/libnetdevice/protocols/generic/Ctrl.cpp new file mode 100644 index 0000000000..08b2be7e65 --- /dev/null +++ b/automotive/can/1.0/default/libnetdevice/protocols/generic/Ctrl.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Ctrl.h" + +namespace android::netdevice::protocols::generic { + +using DataType = AttributeDefinition::DataType; + +// clang-format off +Ctrl::Ctrl() : GenericMessageBase(GENL_ID_CTRL, "ID_CTRL", { + {CTRL_CMD_NEWFAMILY, "NEWFAMILY"}, + {CTRL_CMD_DELFAMILY, "DELFAMILY"}, + {CTRL_CMD_GETFAMILY, "GETFAMILY"}, + {CTRL_CMD_NEWOPS, "NEWOPS"}, + {CTRL_CMD_DELOPS, "DELOPS"}, + {CTRL_CMD_GETOPS, "GETOPS"}, + {CTRL_CMD_NEWMCAST_GRP, "NEWMCAST_GRP"}, + {CTRL_CMD_DELMCAST_GRP, "DELMCAST_GRP"}, + {CTRL_CMD_GETMCAST_GRP, "GETMCAST_GRP"}, +}, { + {CTRL_ATTR_FAMILY_ID, {"FAMILY_ID", DataType::Uint}}, + {CTRL_ATTR_FAMILY_NAME, {"FAMILY_NAME", DataType::String}}, + {CTRL_ATTR_VERSION, {"VERSION", DataType::Uint}}, + {CTRL_ATTR_HDRSIZE, {"HDRSIZE", DataType::Uint}}, + {CTRL_ATTR_MAXATTR, {"MAXATTR", DataType::Uint}}, + {CTRL_ATTR_OPS, {"OPS", DataType::Nested, { + {std::nullopt, {"OP", DataType::Nested, { + {CTRL_ATTR_OP_ID, {"ID", DataType::Uint}}, + {CTRL_ATTR_OP_FLAGS, {"FLAGS", DataType::Uint}}, + }}}, + }}}, + {CTRL_ATTR_MCAST_GROUPS, {"MCAST_GROUPS", DataType::Nested, { + {std::nullopt, {"GRP", DataType::Nested, { + {CTRL_ATTR_MCAST_GRP_NAME, {"NAME", DataType::String}}, + {CTRL_ATTR_MCAST_GRP_ID, {"ID", DataType::Uint}}, + }}}, + }}}, +}) {} +// clang-format on + +} // namespace android::netdevice::protocols::generic diff --git a/automotive/can/1.0/default/libnetdevice/protocols/generic/Ctrl.h b/automotive/can/1.0/default/libnetdevice/protocols/generic/Ctrl.h new file mode 100644 index 0000000000..804ed2cf9a --- /dev/null +++ b/automotive/can/1.0/default/libnetdevice/protocols/generic/Ctrl.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "GenericMessageBase.h" + +namespace android::netdevice::protocols::generic { + +class Ctrl : public GenericMessageBase { + public: + Ctrl(); +}; + +} // namespace android::netdevice::protocols::generic diff --git a/automotive/can/1.0/default/libnetdevice/protocols/generic/Generic.cpp b/automotive/can/1.0/default/libnetdevice/protocols/generic/Generic.cpp new file mode 100644 index 0000000000..633ef3cbbe --- /dev/null +++ b/automotive/can/1.0/default/libnetdevice/protocols/generic/Generic.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Generic.h" + +#include "Ctrl.h" +#include "Unknown.h" + +namespace android::netdevice::protocols::generic { + +Generic::Generic() : NetlinkProtocol(NETLINK_GENERIC, "GENERIC", {std::make_shared()}) {} + +const std::optional> Generic::getMessageDescriptor( + nlmsgtype_t nlmsg_type) { + const auto desc = NetlinkProtocol::getMessageDescriptor(nlmsg_type); + if (desc.has_value()) return desc; + + auto it = mFamilyRegister.find(nlmsg_type); + if (it != mFamilyRegister.end()) return *it->second; + return *(mFamilyRegister[nlmsg_type] = std::make_shared(nlmsg_type)); +} + +} // namespace android::netdevice::protocols::generic diff --git a/automotive/can/1.0/default/libnetdevice/protocols/generic/Generic.h b/automotive/can/1.0/default/libnetdevice/protocols/generic/Generic.h new file mode 100644 index 0000000000..b4352f6193 --- /dev/null +++ b/automotive/can/1.0/default/libnetdevice/protocols/generic/Generic.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "../NetlinkProtocol.h" + +namespace android::netdevice::protocols::generic { + +/** + * Definition of NETLINK_GENERIC protocol. + */ +class Generic : public NetlinkProtocol { + public: + Generic(); + + const std::optional> getMessageDescriptor( + nlmsgtype_t nlmsg_type); + + private: + std::map> mFamilyRegister; +}; + +} // namespace android::netdevice::protocols::generic diff --git a/automotive/can/1.0/default/libnetdevice/protocols/generic/GenericMessageBase.cpp b/automotive/can/1.0/default/libnetdevice/protocols/generic/GenericMessageBase.cpp new file mode 100644 index 0000000000..c9f08131fc --- /dev/null +++ b/automotive/can/1.0/default/libnetdevice/protocols/generic/GenericMessageBase.cpp @@ -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. + */ + +#include "GenericMessageBase.h" + +namespace android::netdevice::protocols::generic { + +GenericMessageBase::GenericMessageBase( + nlmsgtype_t msgtype, std::string msgname, + const std::initializer_list commandNames, + const std::initializer_list attrTypes) + : MessageDefinition(msgname, {{msgtype, msgname}}, attrTypes), + mCommandNames(commandNames) {} + +void GenericMessageBase::toStream(std::stringstream& ss, const struct genlmsghdr& data) const { + ss << "genlmsghdr{"; + if (mCommandNames.count(data.cmd) == 0) { + ss << "cmd=" << unsigned(data.cmd); + } else { + ss << "cmd=" << mCommandNames.find(data.cmd)->second; + } + ss << ", version=" << unsigned(data.version); + if (data.reserved != 0) ss << ", reserved=" << data.reserved; + ss << "}"; +} + +} // namespace android::netdevice::protocols::generic diff --git a/automotive/can/1.0/default/libnetdevice/protocols/generic/GenericMessageBase.h b/automotive/can/1.0/default/libnetdevice/protocols/generic/GenericMessageBase.h new file mode 100644 index 0000000000..2a19034dda --- /dev/null +++ b/automotive/can/1.0/default/libnetdevice/protocols/generic/GenericMessageBase.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "../MessageDefinition.h" + +#include + +namespace android::netdevice::protocols::generic { + +class GenericMessageBase : public MessageDefinition { + public: + typedef std::map GenericCommandNameMap; + + GenericMessageBase( + nlmsgtype_t msgtype, std::string msgname, + const std::initializer_list commandNames = {}, + const std::initializer_list attrTypes = {}); + + void toStream(std::stringstream& ss, const struct genlmsghdr& data) const override; + + private: + const GenericCommandNameMap mCommandNames; +}; + +} // namespace android::netdevice::protocols::generic diff --git a/automotive/can/1.0/default/libnetdevice/protocols/generic/Unknown.cpp b/automotive/can/1.0/default/libnetdevice/protocols/generic/Unknown.cpp new file mode 100644 index 0000000000..9a71d897c3 --- /dev/null +++ b/automotive/can/1.0/default/libnetdevice/protocols/generic/Unknown.cpp @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Unknown.h" + +namespace android::netdevice::protocols::generic { + +Unknown::Unknown(nlmsgtype_t msgtype) + : GenericMessageBase(msgtype, "Unknown(" + std::to_string(msgtype) + ")") {} + +} // namespace android::netdevice::protocols::generic diff --git a/automotive/can/1.0/default/libnetdevice/protocols/generic/Unknown.h b/automotive/can/1.0/default/libnetdevice/protocols/generic/Unknown.h new file mode 100644 index 0000000000..82a5501830 --- /dev/null +++ b/automotive/can/1.0/default/libnetdevice/protocols/generic/Unknown.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "GenericMessageBase.h" + +namespace android::netdevice::protocols::generic { + +class Unknown : public GenericMessageBase { + public: + Unknown(nlmsgtype_t msgtype); +}; + +} // namespace android::netdevice::protocols::generic diff --git a/automotive/can/1.0/default/libnetdevice/protocols/route/Link.cpp b/automotive/can/1.0/default/libnetdevice/protocols/route/Link.cpp new file mode 100644 index 0000000000..4617d92e09 --- /dev/null +++ b/automotive/can/1.0/default/libnetdevice/protocols/route/Link.cpp @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Link.h" + +namespace android::netdevice::protocols::route { + +using DataType = AttributeDefinition::DataType; + +// clang-format off +Link::Link() : MessageDefinition("link", { + {RTM_NEWLINK, "NEWLINK"}, + {RTM_DELLINK, "DELLINK"}, + {RTM_GETLINK, "GETLINK"}, +}, { + {IFLA_ADDRESS, {"ADDRESS"}}, + {IFLA_BROADCAST, {"BROADCAST"}}, + {IFLA_IFNAME, {"IFNAME", DataType::String}}, + {IFLA_MTU, {"MTU"}}, + {IFLA_LINK, {"LINK", DataType::Uint}}, + {IFLA_QDISC, {"QDISC"}}, + {IFLA_STATS, {"STATS"}}, + {IFLA_COST, {"COST"}}, + {IFLA_PRIORITY, {"PRIORITY"}}, + {IFLA_MASTER, {"MASTER"}}, + {IFLA_WIRELESS, {"WIRELESS"}}, + {IFLA_PROTINFO, {"PROTINFO"}}, + {IFLA_TXQLEN, {"TXQLEN"}}, + {IFLA_MAP, {"MAP"}}, + {IFLA_WEIGHT, {"WEIGHT"}}, + {IFLA_OPERSTATE, {"OPERSTATE"}}, + {IFLA_LINKMODE, {"LINKMODE"}}, + {IFLA_LINKINFO, {"LINKINFO", DataType::Nested, { + {IFLA_INFO_KIND, {"INFO_KIND", DataType::String}}, + {IFLA_INFO_DATA, {"INFO_DATA", DataType::Nested}}, + {IFLA_INFO_XSTATS, {"INFO_XSTATS"}}, + {IFLA_INFO_SLAVE_KIND, {"INFO_SLAVE_KIND"}}, + {IFLA_INFO_SLAVE_DATA, {"INFO_SLAVE_DATA"}}, + }}}, + {IFLA_NET_NS_PID, {"NET_NS_PID"}}, + {IFLA_IFALIAS, {"IFALIAS"}}, + {IFLA_NUM_VF, {"NUM_VF"}}, + {IFLA_VFINFO_LIST, {"VFINFO_LIST"}}, + {IFLA_STATS64, {"STATS64"}}, + {IFLA_VF_PORTS, {"VF_PORTS"}}, + {IFLA_PORT_SELF, {"PORT_SELF"}}, + {IFLA_AF_SPEC, {"AF_SPEC"}}, + {IFLA_GROUP, {"GROUP"}}, + {IFLA_NET_NS_FD, {"NET_NS_FD"}}, + {IFLA_EXT_MASK, {"EXT_MASK"}}, + {IFLA_PROMISCUITY, {"PROMISCUITY"}}, + {IFLA_NUM_TX_QUEUES, {"NUM_TX_QUEUES"}}, + {IFLA_NUM_RX_QUEUES, {"NUM_RX_QUEUES"}}, + {IFLA_CARRIER, {"CARRIER"}}, + {IFLA_PHYS_PORT_ID, {"PHYS_PORT_ID"}}, + {IFLA_CARRIER_CHANGES, {"CARRIER_CHANGES"}}, + {IFLA_PHYS_SWITCH_ID, {"PHYS_SWITCH_ID"}}, + {IFLA_LINK_NETNSID, {"LINK_NETNSID"}}, + {IFLA_PHYS_PORT_NAME, {"PHYS_PORT_NAME"}}, + {IFLA_PROTO_DOWN, {"PROTO_DOWN"}}, + {IFLA_GSO_MAX_SEGS, {"GSO_MAX_SEGS"}}, + {IFLA_GSO_MAX_SIZE, {"GSO_MAX_SIZE"}}, + {IFLA_PAD, {"PAD"}}, + {IFLA_XDP, {"XDP"}}, + {IFLA_EVENT, {"EVENT"}}, + {IFLA_NEW_NETNSID, {"NEW_NETNSID"}}, + {IFLA_TARGET_NETNSID, {"TARGET_NETNSID"}}, + {IFLA_CARRIER_UP_COUNT, {"CARRIER_UP_COUNT"}}, + {IFLA_CARRIER_DOWN_COUNT, {"CARRIER_DOWN_COUNT"}}, + {IFLA_NEW_IFINDEX, {"NEW_IFINDEX"}}, + {IFLA_MIN_MTU, {"MIN_MTU"}}, + {IFLA_MAX_MTU, {"MAX_MTU"}}, + {IFLA_PROP_LIST, {"PROP_LIST"}}, + {IFLA_ALT_IFNAME, {"ALT_IFNAME"}}, + {IFLA_PERM_ADDRESS, {"PERM_ADDRESS"}}, +}) {} +// clang-format off + +void Link::toStream(std::stringstream& ss, const struct ifinfomsg& data) const { + ss << "ifinfomsg{" + << "family=" << unsigned(data.ifi_family) << ", type=" << data.ifi_type + << ", index=" << data.ifi_index << ", flags=" << data.ifi_flags + << ", change=" << data.ifi_change << "}"; +} + +} // namespace android::netdevice::protocols::route diff --git a/automotive/can/1.0/default/libnetdevice/protocols/route/Link.h b/automotive/can/1.0/default/libnetdevice/protocols/route/Link.h new file mode 100644 index 0000000000..bcfce19795 --- /dev/null +++ b/automotive/can/1.0/default/libnetdevice/protocols/route/Link.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "../MessageDefinition.h" + +#include + +namespace android::netdevice::protocols::route { + +class Link : public MessageDefinition { + public: + Link(); + void toStream(std::stringstream& ss, const struct ifinfomsg& data) const override; +}; + +} // namespace android::netdevice::protocols::route diff --git a/automotive/can/1.0/default/libnetdevice/protocols/route/Route.cpp b/automotive/can/1.0/default/libnetdevice/protocols/route/Route.cpp new file mode 100644 index 0000000000..456072b84a --- /dev/null +++ b/automotive/can/1.0/default/libnetdevice/protocols/route/Route.cpp @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Route.h" + +#include "Link.h" + +namespace android::netdevice::protocols::route { + +Route::Route() : NetlinkProtocol(NETLINK_ROUTE, "ROUTE", {std::make_shared()}) {} + +} // namespace android::netdevice::protocols::route diff --git a/automotive/can/1.0/default/libnetdevice/protocols/route/Route.h b/automotive/can/1.0/default/libnetdevice/protocols/route/Route.h new file mode 100644 index 0000000000..3051cf93b4 --- /dev/null +++ b/automotive/can/1.0/default/libnetdevice/protocols/route/Route.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "../NetlinkProtocol.h" + +namespace android::netdevice::protocols::route { + +/** + * Definition of NETLINK_ROUTE protocol. + */ +class Route : public NetlinkProtocol { + public: + Route(); +}; + +} // namespace android::netdevice::protocols::route diff --git a/automotive/can/1.0/default/libnetdevice/types.h b/automotive/can/1.0/default/libnetdevice/types.h new file mode 100644 index 0000000000..9d90c8a7ac --- /dev/null +++ b/automotive/can/1.0/default/libnetdevice/types.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +namespace android::netdevice { + +typedef __u16 nlmsgtype_t; // nlmsghdr::nlmsg_type +typedef __u16 nlattrtype_t; // nlattr::nla_type +typedef unsigned short rtattrtype_t; // rtattr::rta_type + +} // namespace android::netdevice -- GitLab From a5c83a56233acad147efb9cf5292f2f0ce6ccccc Mon Sep 17 00:00:00 2001 From: Tomasz Wasilczyk Date: Tue, 16 Jun 2020 15:58:19 -0700 Subject: [PATCH 051/790] Implement ethtool get/set value operations Bug: 156784343 Test: manual Change-Id: I33b23bf9c6639cab6006c756d4ddbe561b9441ba --- .../can/1.0/default/libnetdevice/Android.bp | 2 + .../can/1.0/default/libnetdevice/common.cpp | 2 + .../can/1.0/default/libnetdevice/common.h | 18 +++++++ .../can/1.0/default/libnetdevice/ethtool.cpp | 47 ++++++++++++++++ .../can/1.0/default/libnetdevice/ifreqs.cpp | 48 +++++++++++++++++ .../can/1.0/default/libnetdevice/ifreqs.h | 42 +++++++++++++++ .../include/libnetdevice/ethtool.h | 45 ++++++++++++++++ .../1.0/default/libnetdevice/libnetdevice.cpp | 54 ++++--------------- 8 files changed, 213 insertions(+), 45 deletions(-) create mode 100644 automotive/can/1.0/default/libnetdevice/ethtool.cpp create mode 100644 automotive/can/1.0/default/libnetdevice/ifreqs.cpp create mode 100644 automotive/can/1.0/default/libnetdevice/ifreqs.h create mode 100644 automotive/can/1.0/default/libnetdevice/include/libnetdevice/ethtool.h diff --git a/automotive/can/1.0/default/libnetdevice/Android.bp b/automotive/can/1.0/default/libnetdevice/Android.bp index c5fd3111fc..928ad1339a 100644 --- a/automotive/can/1.0/default/libnetdevice/Android.bp +++ b/automotive/can/1.0/default/libnetdevice/Android.bp @@ -35,6 +35,8 @@ cc_library_static { "NetlinkSocket.cpp", "can.cpp", "common.cpp", + "ethtool.cpp", + "ifreqs.cpp", "libnetdevice.cpp", "printer.cpp", "vlan.cpp", diff --git a/automotive/can/1.0/default/libnetdevice/common.cpp b/automotive/can/1.0/default/libnetdevice/common.cpp index f64d7d3e5c..103cf5378c 100644 --- a/automotive/can/1.0/default/libnetdevice/common.cpp +++ b/automotive/can/1.0/default/libnetdevice/common.cpp @@ -22,6 +22,8 @@ namespace android::netdevice { +socketparams::Params socketparams::current = general; + unsigned int nametoindex(const std::string& ifname) { const auto ifidx = if_nametoindex(ifname.c_str()); if (ifidx != 0) return ifidx; diff --git a/automotive/can/1.0/default/libnetdevice/common.h b/automotive/can/1.0/default/libnetdevice/common.h index c52183588b..1e04d4147f 100644 --- a/automotive/can/1.0/default/libnetdevice/common.h +++ b/automotive/can/1.0/default/libnetdevice/common.h @@ -18,10 +18,28 @@ #include "nlbuf.h" +#include +#include + #include namespace android::netdevice { +namespace socketparams { + +struct Params { + int domain; + int type; + int protocol; +}; + +constexpr Params general = {AF_INET, SOCK_DGRAM, 0}; +constexpr Params can = {PF_CAN, SOCK_RAW, CAN_RAW}; + +extern Params current; + +} // namespace socketparams + /** * Returns the index of a given network interface. * diff --git a/automotive/can/1.0/default/libnetdevice/ethtool.cpp b/automotive/can/1.0/default/libnetdevice/ethtool.cpp new file mode 100644 index 0000000000..762ef5cc88 --- /dev/null +++ b/automotive/can/1.0/default/libnetdevice/ethtool.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "ifreqs.h" + +#include + +namespace android::netdevice::ethtool { + +std::optional getValue(const std::string& ifname, uint32_t command) { + struct ethtool_value valueop = {}; + valueop.cmd = command; + + auto ifr = ifreqs::fromName(ifname); + ifr.ifr_data = &valueop; + + if (!ifreqs::send(SIOCETHTOOL, ifr)) return std::nullopt; + return valueop.data; +} + +bool setValue(const std::string& ifname, uint32_t command, uint32_t value) { + struct ethtool_value valueop = {}; + valueop.cmd = command; + valueop.data = value; + + auto ifr = ifreqs::fromName(ifname); + ifr.ifr_data = &valueop; + + return ifreqs::send(SIOCETHTOOL, ifr); +} + +} // namespace android::netdevice::ethtool diff --git a/automotive/can/1.0/default/libnetdevice/ifreqs.cpp b/automotive/can/1.0/default/libnetdevice/ifreqs.cpp new file mode 100644 index 0000000000..9335021714 --- /dev/null +++ b/automotive/can/1.0/default/libnetdevice/ifreqs.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ifreqs.h" + +#include "common.h" + +#include +#include + +namespace android::netdevice::ifreqs { + +bool send(unsigned long request, struct ifreq& ifr) { + base::unique_fd sock(socket(socketparams::current.domain, socketparams::current.type, + socketparams::current.protocol)); + if (!sock.ok()) { + LOG(ERROR) << "Can't create socket"; + return false; + } + + if (ioctl(sock.get(), request, &ifr) < 0) { + PLOG(ERROR) << "ioctl(" << std::hex << request << std::dec << ") failed"; + return false; + } + + return true; +} + +struct ifreq fromName(const std::string& ifname) { + struct ifreq ifr = {}; + strlcpy(ifr.ifr_name, ifname.c_str(), IF_NAMESIZE); + return ifr; +} + +} // namespace android::netdevice::ifreqs diff --git a/automotive/can/1.0/default/libnetdevice/ifreqs.h b/automotive/can/1.0/default/libnetdevice/ifreqs.h new file mode 100644 index 0000000000..25a40a69a9 --- /dev/null +++ b/automotive/can/1.0/default/libnetdevice/ifreqs.h @@ -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. + */ + +#pragma once + +#include + +#include + +namespace android::netdevice::ifreqs { + +/** + * Sends ioctl interface request. + * + * \param request Request type (such as SIOCGIFFLAGS) + * \param ifr Request data (both input and output) + * \return true if the call succeeded, false otherwise + */ +bool send(unsigned long request, struct ifreq& ifr); + +/** + * Initializes interface request with interface name. + * + * \param ifname Interface to initialize request with + * \return Interface request with ifr_name field set to ifname + */ +struct ifreq fromName(const std::string& ifname); + +} // namespace android::netdevice::ifreqs diff --git a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/ethtool.h b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/ethtool.h new file mode 100644 index 0000000000..26bfdce00c --- /dev/null +++ b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/ethtool.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include + +namespace android::netdevice::ethtool { + +/** + * Fetch a single value with ethtool_value. + * + * \see linux/ethtool.h + * \param ifname Interface to fetch data for + * \param command Fetch command (ETHTOOL_G*) + * \return value, or nullopt if fetch failed + */ +std::optional getValue(const std::string& ifname, uint32_t command); + +/** + * Set a single value with ethtool_value. + * + * \see linux/ethtool.h + * \param ifname Interface to set data for + * \param command Set command (ETHTOOL_S*) + * \param value New value + * \return true if succeeded, false otherwise + */ +bool setValue(const std::string& ifname, uint32_t command, uint32_t value); + +} // namespace android::netdevice::ethtool diff --git a/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp b/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp index 827f8f3905..73b91d0ee6 100644 --- a/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp +++ b/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp @@ -19,6 +19,7 @@ #include "NetlinkRequest.h" #include "NetlinkSocket.h" #include "common.h" +#include "ifreqs.h" #include @@ -27,21 +28,6 @@ namespace android::netdevice { -namespace socketparams { - -struct Params { - int domain; - int type; - int protocol; -}; - -static constexpr Params general = {AF_INET, SOCK_DGRAM, 0}; -static constexpr Params can = {PF_CAN, SOCK_RAW, CAN_RAW}; - -static Params current = general; - -} // namespace socketparams - void useCanSockets(bool yes) { socketparams::current = yes ? socketparams::can : socketparams::general; } @@ -50,31 +36,9 @@ bool exists(std::string ifname) { return nametoindex(ifname) != 0; } -static bool sendIfreq(unsigned long request, struct ifreq& ifr) { - base::unique_fd sock(socket(socketparams::current.domain, socketparams::current.type, - socketparams::current.protocol)); - if (!sock.ok()) { - LOG(ERROR) << "Can't create socket"; - return false; - } - - if (ioctl(sock.get(), request, &ifr) < 0) { - PLOG(ERROR) << "ioctl(" << std::hex << request << std::dec << ") failed"; - return false; - } - - return true; -} - -static struct ifreq ifreqFromName(const std::string& ifname) { - struct ifreq ifr = {}; - strlcpy(ifr.ifr_name, ifname.c_str(), IF_NAMESIZE); - return ifr; -} - std::optional isUp(std::string ifname) { - struct ifreq ifr = ifreqFromName(ifname); - if (!sendIfreq(SIOCGIFFLAGS, ifr)) return std::nullopt; + auto ifr = ifreqs::fromName(ifname); + if (!ifreqs::send(SIOCGIFFLAGS, ifr)) return std::nullopt; return ifr.ifr_flags & IFF_UP; } @@ -83,17 +47,17 @@ bool existsAndIsUp(const std::string& ifname) { } bool up(std::string ifname) { - struct ifreq ifr = ifreqFromName(ifname); - if (!sendIfreq(SIOCGIFFLAGS, ifr)) return false; + auto ifr = ifreqs::fromName(ifname); + if (!ifreqs::send(SIOCGIFFLAGS, ifr)) return false; ifr.ifr_flags |= IFF_UP; - return sendIfreq(SIOCSIFFLAGS, ifr); + return ifreqs::send(SIOCSIFFLAGS, ifr); } bool down(std::string ifname) { - struct ifreq ifr = ifreqFromName(ifname); - if (!sendIfreq(SIOCGIFFLAGS, ifr)) return false; + auto ifr = ifreqs::fromName(ifname); + if (!ifreqs::send(SIOCGIFFLAGS, ifr)) return false; ifr.ifr_flags &= ~IFF_UP; - return sendIfreq(SIOCSIFFLAGS, ifr); + return ifreqs::send(SIOCSIFFLAGS, ifr); } bool add(std::string dev, std::string type) { -- GitLab From 3fcb7bf3fe8af8ac40b0685e16a5b8c1f5dd4ccc Mon Sep 17 00:00:00 2001 From: Yu-Han Yang Date: Wed, 10 Jun 2020 14:59:50 -0700 Subject: [PATCH 052/790] Add GNSS HAL v3.0 (hardware/interfaces) Bug: 158518085 Test: atest VtsHalGnssV3_0TargetTest atest VtsHalGnssV2_1TargetTest atest VtsHalGnssV2_0TargetTest atest VtsHalGnssV1_1TargetTest atest VtsHalGnssV1_0TargetTest Change-Id: Id4ac1e31207da7cfff3f1885c84748785bec19ba --- .../compatibility_matrix.current.xml | 1 + gnss/2.1/Android.bp | 5 +- gnss/2.1/default/Android.bp | 6 - gnss/2.1/default/Gnss.h | 128 ------ gnss/2.1/default/service.cpp | 6 +- gnss/2.1/vts/functional/Android.bp | 1 - gnss/2.1/vts/functional/gnss_hal_test.cpp | 278 ------------- gnss/2.1/vts/functional/gnss_hal_test.h | 217 +--------- gnss/3.0/Android.bp | 25 ++ gnss/3.0/IGnss.hal | 32 ++ gnss/3.0/IGnssPsds.hal | 48 +++ gnss/3.0/IGnssPsdsCallback.hal | 41 ++ gnss/3.0/default/Android.bp | 43 ++ gnss/3.0/default/Gnss.cpp | 32 ++ gnss/3.0/default/Gnss.h | 42 ++ gnss/3.0/default/GnssPsds.cpp | 50 +++ gnss/3.0/default/GnssPsds.h | 50 +++ gnss/3.0/default/OWNERS | 4 + .../android.hardware.gnss@3.0-service.rc | 4 + .../android.hardware.gnss@3.0-service.xml | 13 + gnss/3.0/default/service.cpp | 41 ++ gnss/3.0/vts/OWNERS | 4 + gnss/3.0/vts/functional/Android.bp | 39 ++ .../functional/VtsHalGnssV3_0TargetTest.cpp | 29 ++ gnss/3.0/vts/functional/gnss_hal_test.h | 25 ++ .../vts/functional/gnss_hal_test_cases.cpp | 49 +++ gnss/common/utils/default/Android.bp | 7 + .../default/include/v2_1}/GnssAntennaInfo.h | 19 +- .../default/include/v2_1}/GnssConfiguration.h | 17 +- .../utils/default/include/v2_1}/GnssDebug.h | 17 +- .../default/include/v2_1}/GnssMeasurement.h | 12 +- .../v2_1}/GnssMeasurementCorrections.h | 22 +- .../default/include/v2_1/GnssTemplate.h} | 293 ++++++++++---- .../utils/default/v2_1}/GnssAntennaInfo.cpp | 14 +- .../utils/default/v2_1}/GnssConfiguration.cpp | 14 +- .../utils/default/v2_1}/GnssDebug.cpp | 14 +- .../utils/default/v2_1}/GnssMeasurement.cpp | 15 +- .../v2_1}/GnssMeasurementCorrections.cpp | 20 +- gnss/common/utils/vts/Android.bp | 3 + .../utils/vts/include/v2_1/GnssCallback.h | 107 +++++ .../vts/include/v2_1/gnss_hal_test_template.h | 381 ++++++++++++++++++ gnss/common/utils/vts/v2_1/GnssCallback.cpp | 95 +++++ gnss/measurement_corrections/1.1/Android.bp | 2 +- 43 files changed, 1433 insertions(+), 832 deletions(-) delete mode 100644 gnss/2.1/default/Gnss.h delete mode 100644 gnss/2.1/vts/functional/gnss_hal_test.cpp create mode 100644 gnss/3.0/Android.bp create mode 100644 gnss/3.0/IGnss.hal create mode 100644 gnss/3.0/IGnssPsds.hal create mode 100644 gnss/3.0/IGnssPsdsCallback.hal create mode 100644 gnss/3.0/default/Android.bp create mode 100644 gnss/3.0/default/Gnss.cpp create mode 100644 gnss/3.0/default/Gnss.h create mode 100644 gnss/3.0/default/GnssPsds.cpp create mode 100644 gnss/3.0/default/GnssPsds.h create mode 100644 gnss/3.0/default/OWNERS create mode 100644 gnss/3.0/default/android.hardware.gnss@3.0-service.rc create mode 100644 gnss/3.0/default/android.hardware.gnss@3.0-service.xml create mode 100644 gnss/3.0/default/service.cpp create mode 100644 gnss/3.0/vts/OWNERS create mode 100644 gnss/3.0/vts/functional/Android.bp create mode 100644 gnss/3.0/vts/functional/VtsHalGnssV3_0TargetTest.cpp create mode 100644 gnss/3.0/vts/functional/gnss_hal_test.h create mode 100644 gnss/3.0/vts/functional/gnss_hal_test_cases.cpp rename gnss/{2.1/default => common/utils/default/include/v2_1}/GnssAntennaInfo.h (80%) rename gnss/{2.1/default => common/utils/default/include/v2_1}/GnssConfiguration.h (89%) rename gnss/{2.1/default => common/utils/default/include/v2_1}/GnssDebug.h (76%) rename gnss/{2.1/default => common/utils/default/include/v2_1}/GnssMeasurement.h (92%) rename gnss/{2.1/default => common/utils/default/include/v2_1}/GnssMeasurementCorrections.h (72%) rename gnss/{2.1/default/Gnss.cpp => common/utils/default/include/v2_1/GnssTemplate.h} (50%) rename gnss/{2.1/default => common/utils/default/v2_1}/GnssAntennaInfo.cpp (91%) rename gnss/{2.1/default => common/utils/default/v2_1}/GnssConfiguration.cpp (93%) rename gnss/{2.1/default => common/utils/default/v2_1}/GnssDebug.cpp (88%) rename gnss/{2.1/default => common/utils/default/v2_1}/GnssMeasurement.cpp (94%) rename gnss/{2.1/default => common/utils/default/v2_1}/GnssMeasurementCorrections.cpp (93%) create mode 100644 gnss/common/utils/vts/include/v2_1/GnssCallback.h create mode 100644 gnss/common/utils/vts/include/v2_1/gnss_hal_test_template.h create mode 100644 gnss/common/utils/vts/v2_1/GnssCallback.cpp diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index 41a7d0bb76..cfee298c6d 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -203,6 +203,7 @@ android.hardware.gnss 2.0-1 + 3.0 IGnss default diff --git a/gnss/2.1/Android.bp b/gnss/2.1/Android.bp index 21223997b3..1a6b4140c1 100644 --- a/gnss/2.1/Android.bp +++ b/gnss/2.1/Android.bp @@ -12,13 +12,13 @@ hidl_interface { "IGnssAntennaInfo.hal", "IGnssAntennaInfoCallback.hal", "IGnssCallback.hal", + "IGnssConfiguration.hal", "IGnssMeasurement.hal", "IGnssMeasurementCallback.hal", - "IGnssConfiguration.hal", ], interfaces: [ - "android.hardware.gnss.measurement_corrections@1.1", "android.hardware.gnss.measurement_corrections@1.0", + "android.hardware.gnss.measurement_corrections@1.1", "android.hardware.gnss.visibility_control@1.0", "android.hardware.gnss@1.0", "android.hardware.gnss@1.1", @@ -26,4 +26,5 @@ hidl_interface { "android.hidl.base@1.0", ], gen_java: true, + gen_java_constants: true, } diff --git a/gnss/2.1/default/Android.bp b/gnss/2.1/default/Android.bp index c4dc8fd55d..7739f908a7 100644 --- a/gnss/2.1/default/Android.bp +++ b/gnss/2.1/default/Android.bp @@ -21,12 +21,6 @@ cc_binary { vendor: true, vintf_fragments: ["android.hardware.gnss@2.1-service.xml"], srcs: [ - "Gnss.cpp", - "GnssAntennaInfo.cpp", - "GnssDebug.cpp", - "GnssMeasurement.cpp", - "GnssMeasurementCorrections.cpp", - "GnssConfiguration.cpp", "service.cpp", ], shared_libs: [ diff --git a/gnss/2.1/default/Gnss.h b/gnss/2.1/default/Gnss.h deleted file mode 100644 index 9af0d46e39..0000000000 --- a/gnss/2.1/default/Gnss.h +++ /dev/null @@ -1,128 +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. - */ - -#pragma once - -#include -#include -#include -#include -#include -#include -#include "GnssAntennaInfo.h" -#include "GnssConfiguration.h" -#include "NmeaFixInfo.h" - -namespace android { -namespace hardware { -namespace gnss { -namespace V2_1 { - -using GnssSvInfo = IGnssCallback::GnssSvInfo; -using ::android::hardware::gnss::common::NmeaFixInfo; - -namespace implementation { - -constexpr int INPUT_BUFFER_SIZE = 128; -constexpr char CMD_GET_LOCATION[] = "CMD_GET_LOCATION"; -constexpr char GNSS_PATH[] = "/dev/gnss0"; - -struct Gnss : public IGnss { - Gnss(); - ~Gnss(); - // Methods from V1_0::IGnss follow. - Return setCallback(const sp& callback) override; - Return start() override; - Return stop() override; - Return cleanup() override; - Return injectTime(int64_t timeMs, int64_t timeReferenceMs, - int32_t uncertaintyMs) override; - Return injectLocation(double latitudeDegrees, double longitudeDegrees, - float accuracyMeters) override; - Return deleteAidingData(V1_0::IGnss::GnssAidingData aidingDataFlags) override; - Return setPositionMode(V1_0::IGnss::GnssPositionMode mode, - V1_0::IGnss::GnssPositionRecurrence recurrence, - uint32_t minIntervalMs, uint32_t preferredAccuracyMeters, - uint32_t preferredTimeMs) override; - Return> getExtensionAGnssRil() override; - Return> getExtensionGnssGeofencing() override; - Return> getExtensionAGnss() override; - Return> getExtensionGnssNi() override; - Return> getExtensionGnssMeasurement() override; - Return> getExtensionGnssNavigationMessage() override; - Return> getExtensionXtra() override; - Return> getExtensionGnssConfiguration() override; - Return> getExtensionGnssDebug() override; - Return> getExtensionGnssBatching() override; - - // Methods from V1_1::IGnss follow. - Return setCallback_1_1(const sp& callback) override; - Return setPositionMode_1_1(V1_0::IGnss::GnssPositionMode mode, - V1_0::IGnss::GnssPositionRecurrence recurrence, - uint32_t minIntervalMs, uint32_t preferredAccuracyMeters, - uint32_t preferredTimeMs, bool lowPowerMode) override; - Return> getExtensionGnssConfiguration_1_1() override; - Return> getExtensionGnssMeasurement_1_1() override; - Return injectBestLocation(const V1_0::GnssLocation& location) override; - - // Methods from V2_0::IGnss follow. - Return setCallback_2_0(const sp& callback) override; - Return> getExtensionGnssConfiguration_2_0() override; - Return> getExtensionGnssDebug_2_0() override; - Return> getExtensionAGnss_2_0() override; - Return> getExtensionAGnssRil_2_0() override; - Return> getExtensionGnssMeasurement_2_0() override; - Return> - getExtensionMeasurementCorrections() override; - Return> getExtensionVisibilityControl() - override; - Return> getExtensionGnssBatching_2_0() override; - Return injectBestLocation_2_0(const V2_0::GnssLocation& location) override; - - // Methods from V2_1::IGnss follow. - Return setCallback_2_1(const sp& callback) override; - Return> getExtensionGnssMeasurement_2_1() override; - Return> getExtensionGnssConfiguration_2_1() override; - Return> - getExtensionMeasurementCorrections_1_1() override; - Return> getExtensionGnssAntennaInfo() override; - - private: - std::unique_ptr getLocationFromHW(); - void reportLocation(const V2_0::GnssLocation&) const; - void reportLocation(const V1_0::GnssLocation&) const; - void reportSvStatus(const hidl_vec&) const; - - static sp sGnssCallback_2_1; - static sp sGnssCallback_2_0; - static sp sGnssCallback_1_1; - static sp sGnssCallback_1_0; - std::atomic mMinIntervalMs; - sp mGnssConfiguration; - std::atomic mIsActive; - std::atomic mHardwareModeOn; - std::atomic mGnssFd; - std::thread mThread; - - mutable std::mutex mMutex; - hidl_vec filterBlacklistedSatellitesV2_1(hidl_vec gnssSvInfoList); -}; - -} // namespace implementation -} // namespace V2_1 -} // namespace gnss -} // namespace hardware -} // namespace android diff --git a/gnss/2.1/default/service.cpp b/gnss/2.1/default/service.cpp index 5e004d5697..4f282cfdaf 100644 --- a/gnss/2.1/default/service.cpp +++ b/gnss/2.1/default/service.cpp @@ -18,17 +18,17 @@ #include #include -#include "Gnss.h" +#include "v2_1/GnssTemplate.h" using ::android::OK; using ::android::sp; using ::android::hardware::configureRpcThreadpool; using ::android::hardware::joinRpcThreadpool; +using ::android::hardware::gnss::common::implementation::GnssTemplate; using ::android::hardware::gnss::V2_1::IGnss; -using ::android::hardware::gnss::V2_1::implementation::Gnss; int main(int /* argc */, char* /* argv */[]) { - sp gnss = new Gnss(); + sp gnss = new GnssTemplate(); configureRpcThreadpool(1, true /* will join */); if (gnss->registerAsService() != OK) { ALOGE("Could not register gnss 2.1 service."); diff --git a/gnss/2.1/vts/functional/Android.bp b/gnss/2.1/vts/functional/Android.bp index b3051d4b48..175bc75481 100644 --- a/gnss/2.1/vts/functional/Android.bp +++ b/gnss/2.1/vts/functional/Android.bp @@ -18,7 +18,6 @@ cc_test { name: "VtsHalGnssV2_1TargetTest", defaults: ["VtsHalTargetTestDefaults"], srcs: [ - "gnss_hal_test.cpp", "gnss_hal_test_cases.cpp", "VtsHalGnssV2_1TargetTest.cpp", ], diff --git a/gnss/2.1/vts/functional/gnss_hal_test.cpp b/gnss/2.1/vts/functional/gnss_hal_test.cpp deleted file mode 100644 index da7a62b4bd..0000000000 --- a/gnss/2.1/vts/functional/gnss_hal_test.cpp +++ /dev/null @@ -1,278 +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. - */ - -#define LOG_TAG "GnssHalTest" - -#include -#include -#include "Utils.h" - -#include - -using ::android::hardware::gnss::common::Utils; - -// Implementations for the main test class for GNSS HAL -void GnssHalTest::SetUp() { - gnss_hal_ = IGnss::getService(GetParam()); - ASSERT_NE(gnss_hal_, nullptr); - - SetUpGnssCallback(); -} - -void GnssHalTest::TearDown() { - if (gnss_hal_ != nullptr) { - gnss_hal_->cleanup(); - gnss_hal_ = nullptr; - } - - // Set to nullptr to destruct the callback event queues and warn of any unprocessed events. - gnss_cb_ = nullptr; -} - -void GnssHalTest::SetUpGnssCallback() { - gnss_cb_ = new GnssCallback(); - ASSERT_NE(gnss_cb_, nullptr); - - auto result = gnss_hal_->setCallback_2_1(gnss_cb_); - if (!result.isOk()) { - ALOGE("result of failed setCallback %s", result.description().c_str()); - } - - ASSERT_TRUE(result.isOk()); - ASSERT_TRUE(result); - - /* - * All capabilities, name and systemInfo callbacks should trigger - */ - EXPECT_TRUE(gnss_cb_->capabilities_cbq_.retrieve(gnss_cb_->last_capabilities_, TIMEOUT_SEC)); - EXPECT_TRUE(gnss_cb_->info_cbq_.retrieve(gnss_cb_->last_info_, TIMEOUT_SEC)); - EXPECT_TRUE(gnss_cb_->name_cbq_.retrieve(gnss_cb_->last_name_, TIMEOUT_SEC)); - - EXPECT_EQ(gnss_cb_->capabilities_cbq_.calledCount(), 1); - EXPECT_EQ(gnss_cb_->info_cbq_.calledCount(), 1); - EXPECT_EQ(gnss_cb_->name_cbq_.calledCount(), 1); -} - -void GnssHalTest::StopAndClearLocations() { - const auto result = gnss_hal_->stop(); - - EXPECT_TRUE(result.isOk()); - EXPECT_TRUE(result); - - /* - * Clear notify/waiting counter, allowing up till the timeout after - * the last reply for final startup messages to arrive (esp. system - * info.) - */ - while (gnss_cb_->location_cbq_.retrieve(gnss_cb_->last_location_, TIMEOUT_SEC)) { - } - gnss_cb_->location_cbq_.reset(); -} - -void GnssHalTest::SetPositionMode(const int min_interval_msec, const bool low_power_mode) { - const int kPreferredAccuracy = 0; // Ideally perfect (matches GnssLocationProvider) - const int kPreferredTimeMsec = 0; // Ideally immediate - - const auto result = gnss_hal_->setPositionMode_1_1( - IGnss::GnssPositionMode::MS_BASED, IGnss::GnssPositionRecurrence::RECURRENCE_PERIODIC, - min_interval_msec, kPreferredAccuracy, kPreferredTimeMsec, low_power_mode); - - ASSERT_TRUE(result.isOk()); - EXPECT_TRUE(result); -} - -bool GnssHalTest::StartAndCheckFirstLocation() { - const auto result = gnss_hal_->start(); - - EXPECT_TRUE(result.isOk()); - EXPECT_TRUE(result); - - /* - * GnssLocationProvider support of AGPS SUPL & XtraDownloader is not available in VTS, - * so allow time to demodulate ephemeris over the air. - */ - const int kFirstGnssLocationTimeoutSeconds = 75; - - EXPECT_TRUE(gnss_cb_->location_cbq_.retrieve(gnss_cb_->last_location_, - kFirstGnssLocationTimeoutSeconds)); - int locationCalledCount = gnss_cb_->location_cbq_.calledCount(); - EXPECT_EQ(locationCalledCount, 1); - - if (locationCalledCount > 0) { - // don't require speed on first fix - CheckLocation(gnss_cb_->last_location_, false); - return true; - } - return false; -} - -void GnssHalTest::CheckLocation(const GnssLocation_2_0& location, bool check_speed) { - const bool check_more_accuracies = - (gnss_cb_->info_cbq_.calledCount() > 0 && gnss_cb_->last_info_.yearOfHw >= 2017); - - Utils::checkLocation(location.v1_0, check_speed, check_more_accuracies); -} - -void GnssHalTest::StartAndCheckLocations(int count) { - const int kMinIntervalMsec = 500; - const int kLocationTimeoutSubsequentSec = 2; - const bool kLowPowerMode = false; - - SetPositionMode(kMinIntervalMsec, kLowPowerMode); - - EXPECT_TRUE(StartAndCheckFirstLocation()); - - for (int i = 1; i < count; i++) { - EXPECT_TRUE(gnss_cb_->location_cbq_.retrieve(gnss_cb_->last_location_, - kLocationTimeoutSubsequentSec)); - int locationCalledCount = gnss_cb_->location_cbq_.calledCount(); - EXPECT_EQ(locationCalledCount, i + 1); - // Don't cause confusion by checking details if no location yet - if (locationCalledCount > 0) { - // Should be more than 1 location by now, but if not, still don't check first fix speed - CheckLocation(gnss_cb_->last_location_, locationCalledCount > 1); - } - } -} - -GnssConstellationType GnssHalTest::startLocationAndGetNonGpsConstellation( - const int locations_to_await, const int gnss_sv_info_list_timeout) { - gnss_cb_->location_cbq_.reset(); - StartAndCheckLocations(locations_to_await); - const int location_called_count = gnss_cb_->location_cbq_.calledCount(); - - // Tolerate 1 less sv status to handle edge cases in reporting. - int sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size(); - EXPECT_GE(sv_info_list_cbq_size + 1, locations_to_await); - ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations (%d received)", - sv_info_list_cbq_size, locations_to_await, location_called_count); - - // Find first non-GPS constellation to blacklist - GnssConstellationType constellation_to_blacklist = GnssConstellationType::UNKNOWN; - for (int i = 0; i < sv_info_list_cbq_size; ++i) { - hidl_vec sv_info_vec; - gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, gnss_sv_info_list_timeout); - for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) { - const auto& gnss_sv = sv_info_vec[iSv]; - if ((gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX) && - (gnss_sv.v2_0.constellation != GnssConstellationType::UNKNOWN) && - (gnss_sv.v2_0.constellation != GnssConstellationType::GPS)) { - // found a non-GPS constellation - constellation_to_blacklist = gnss_sv.v2_0.constellation; - break; - } - } - if (constellation_to_blacklist != GnssConstellationType::UNKNOWN) { - break; - } - } - - if (constellation_to_blacklist == GnssConstellationType::UNKNOWN) { - ALOGI("No non-GPS constellations found, constellation blacklist test less effective."); - // Proceed functionally to blacklist something. - constellation_to_blacklist = GnssConstellationType::GLONASS; - } - - return constellation_to_blacklist; -} - -GnssHalTest::GnssCallback::GnssCallback() - : info_cbq_("system_info"), - name_cbq_("name"), - capabilities_cbq_("capabilities"), - location_cbq_("location"), - sv_info_list_cbq_("sv_info") {} - -Return GnssHalTest::GnssCallback::gnssSetSystemInfoCb( - const IGnssCallback_1_0::GnssSystemInfo& info) { - ALOGI("Info received, year %d", info.yearOfHw); - info_cbq_.store(info); - return Void(); -} - -Return GnssHalTest::GnssCallback::gnssSetCapabilitesCb(uint32_t capabilities) { - ALOGI("Capabilities received %d", capabilities); - capabilities_cbq_.store(capabilities); - return Void(); -} - -Return GnssHalTest::GnssCallback::gnssSetCapabilitiesCb_2_0(uint32_t capabilities) { - ALOGI("Capabilities (v2.0) received %d", capabilities); - capabilities_cbq_.store(capabilities); - return Void(); -} - -Return GnssHalTest::GnssCallback::gnssSetCapabilitiesCb_2_1(uint32_t capabilities) { - ALOGI("Capabilities (v2.1) received %d", capabilities); - capabilities_cbq_.store(capabilities); - return Void(); -} - -Return GnssHalTest::GnssCallback::gnssNameCb(const android::hardware::hidl_string& name) { - ALOGI("Name received: %s", name.c_str()); - name_cbq_.store(name); - return Void(); -} - -Return GnssHalTest::GnssCallback::gnssLocationCb(const GnssLocation_1_0& location) { - ALOGI("Location received"); - GnssLocation_2_0 location_v2_0; - location_v2_0.v1_0 = location; - return gnssLocationCbImpl(location_v2_0); -} - -Return GnssHalTest::GnssCallback::gnssLocationCb_2_0(const GnssLocation_2_0& location) { - ALOGI("Location (v2.0) received"); - return gnssLocationCbImpl(location); -} - -Return GnssHalTest::GnssCallback::gnssLocationCbImpl(const GnssLocation_2_0& location) { - location_cbq_.store(location); - return Void(); -} - -Return GnssHalTest::GnssCallback::gnssSvStatusCb(const IGnssCallback_1_0::GnssSvStatus&) { - ALOGI("gnssSvStatusCb"); - return Void(); -} - -Return GnssHalTest::GnssCallback::gnssSvStatusCb_2_1( - const hidl_vec& svInfoList) { - ALOGI("gnssSvStatusCb_2_1. Size = %d", (int)svInfoList.size()); - sv_info_list_cbq_.store(svInfoList); - return Void(); -} - -Return GnssHalTest::GnssMeasurementCallback::gnssMeasurementCb_2_1( - const IGnssMeasurementCallback_2_1::GnssData& data) { - ALOGD("GnssMeasurement v2.1 received. Size = %d", (int)data.measurements.size()); - measurement_cbq_.store(data); - return Void(); -} - -Return GnssHalTest::GnssMeasurementCorrectionsCallback::setCapabilitiesCb( - uint32_t capabilities) { - ALOGI("GnssMeasurementCorrectionsCallback capabilities received %d", capabilities); - capabilities_cbq_.store(capabilities); - return Void(); -} - -Return GnssHalTest::GnssAntennaInfoCallback::gnssAntennaInfoCb( - const hidl_vec& gnssAntennaInfos) { - ALOGD("GnssAntennaInfo v2.1 received. Size = %d", (int)gnssAntennaInfos.size()); - antenna_info_cbq_.store(gnssAntennaInfos); - return Void(); -} \ No newline at end of file diff --git a/gnss/2.1/vts/functional/gnss_hal_test.h b/gnss/2.1/vts/functional/gnss_hal_test.h index 9e6e162a13..c28e2480f7 100644 --- a/gnss/2.1/vts/functional/gnss_hal_test.h +++ b/gnss/2.1/vts/functional/gnss_hal_test.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * 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. @@ -14,221 +14,12 @@ * limitations under the License. */ -#ifndef GNSS_HAL_TEST_H_ -#define GNSS_HAL_TEST_H_ +#pragma once #include -#include "GnssCallbackEventQueue.h" +#include "v2_1/gnss_hal_test_template.h" -#include - -using android::hardware::hidl_vec; -using android::hardware::Return; -using android::hardware::Void; - -using android::hardware::gnss::common::GnssCallbackEventQueue; -using android::hardware::gnss::measurement_corrections::V1_0::IMeasurementCorrectionsCallback; -using android::hardware::gnss::V1_0::GnssLocationFlags; -using android::hardware::gnss::V2_0::GnssConstellationType; using android::hardware::gnss::V2_1::IGnss; -using android::hardware::gnss::V2_1::IGnssAntennaInfo; -using android::hardware::gnss::V2_1::IGnssAntennaInfoCallback; - -using GnssLocation_1_0 = android::hardware::gnss::V1_0::GnssLocation; -using GnssLocation_2_0 = android::hardware::gnss::V2_0::GnssLocation; - -using IGnssCallback_1_0 = android::hardware::gnss::V1_0::IGnssCallback; -using IGnssCallback_2_0 = android::hardware::gnss::V2_0::IGnssCallback; -using IGnssCallback_2_1 = android::hardware::gnss::V2_1::IGnssCallback; - -using IGnssMeasurementCallback_1_0 = android::hardware::gnss::V1_0::IGnssMeasurementCallback; -using IGnssMeasurementCallback_1_1 = android::hardware::gnss::V1_1::IGnssMeasurementCallback; -using IGnssMeasurementCallback_2_0 = android::hardware::gnss::V2_0::IGnssMeasurementCallback; -using IGnssMeasurementCallback_2_1 = android::hardware::gnss::V2_1::IGnssMeasurementCallback; - -using android::sp; - -#define TIMEOUT_SEC 2 // for basic commands/responses // The main test class for GNSS HAL. -class GnssHalTest : public testing::TestWithParam { - public: - virtual void SetUp() override; - - virtual void TearDown() override; - - /* Callback class for data & Event. */ - class GnssCallback : public IGnssCallback_2_1 { - public: - IGnssCallback_1_0::GnssSystemInfo last_info_; - android::hardware::hidl_string last_name_; - uint32_t last_capabilities_; - GnssLocation_2_0 last_location_; - - GnssCallbackEventQueue info_cbq_; - GnssCallbackEventQueue name_cbq_; - GnssCallbackEventQueue capabilities_cbq_; - GnssCallbackEventQueue location_cbq_; - GnssCallbackEventQueue> sv_info_list_cbq_; - - GnssCallback(); - virtual ~GnssCallback() = default; - - // Dummy callback handlers - Return gnssStatusCb(const IGnssCallback_1_0::GnssStatusValue /* status */) override { - return Void(); - } - Return gnssNmeaCb(int64_t /* timestamp */, - const android::hardware::hidl_string& /* nmea */) override { - return Void(); - } - Return gnssAcquireWakelockCb() override { return Void(); } - Return gnssReleaseWakelockCb() override { return Void(); } - Return gnssRequestLocationCb(bool /* independentFromGnss */) override { - return Void(); - } - Return gnssRequestTimeCb() override { return Void(); } - // Actual (test) callback handlers - Return gnssNameCb(const android::hardware::hidl_string& name) override; - Return gnssLocationCb(const GnssLocation_1_0& location) override; - Return gnssSetCapabilitesCb(uint32_t capabilities) override; - Return gnssSetSystemInfoCb(const IGnssCallback_1_0::GnssSystemInfo& info) override; - Return gnssSvStatusCb(const IGnssCallback_1_0::GnssSvStatus& svStatus) override; - - // New in v2.0 - Return gnssLocationCb_2_0(const GnssLocation_2_0& location) override; - Return gnssRequestLocationCb_2_0(bool /* independentFromGnss */, - bool /* isUserEmergency */) override { - return Void(); - } - Return gnssSetCapabilitiesCb_2_0(uint32_t capabilities) override; - Return gnssSvStatusCb_2_0(const hidl_vec&) override { - return Void(); - } - - // New in v2.1 - Return gnssSvStatusCb_2_1( - const hidl_vec& svInfoList) override; - Return gnssSetCapabilitiesCb_2_1(uint32_t capabilities) override; - - private: - Return gnssLocationCbImpl(const GnssLocation_2_0& location); - }; - - /* Callback class for GnssMeasurement. */ - class GnssMeasurementCallback : public IGnssMeasurementCallback_2_1 { - public: - GnssCallbackEventQueue measurement_cbq_; - - GnssMeasurementCallback() : measurement_cbq_("measurement"){}; - virtual ~GnssMeasurementCallback() = default; - - // Methods from V1_0::IGnssMeasurementCallback follow. - Return GnssMeasurementCb(const IGnssMeasurementCallback_1_0::GnssData&) override { - return Void(); - } - - // Methods from V1_1::IGnssMeasurementCallback follow. - Return gnssMeasurementCb(const IGnssMeasurementCallback_1_1::GnssData&) override { - return Void(); - } - - // Methods from V2_0::IGnssMeasurementCallback follow. - Return gnssMeasurementCb_2_0(const IGnssMeasurementCallback_2_0::GnssData&) override { - return Void(); - } - - // Methods from V2_1::IGnssMeasurementCallback follow. - Return gnssMeasurementCb_2_1(const IGnssMeasurementCallback_2_1::GnssData&) override; - }; - - /* Callback class for GnssMeasurementCorrections. */ - class GnssMeasurementCorrectionsCallback : public IMeasurementCorrectionsCallback { - public: - uint32_t last_capabilities_; - GnssCallbackEventQueue capabilities_cbq_; - - GnssMeasurementCorrectionsCallback() : capabilities_cbq_("capabilities"){}; - virtual ~GnssMeasurementCorrectionsCallback() = default; - - // Methods from V1_0::IMeasurementCorrectionsCallback follow. - Return setCapabilitiesCb(uint32_t capabilities) override; - }; - - /* Callback class for GnssAntennaInfo. */ - class GnssAntennaInfoCallback : public IGnssAntennaInfoCallback { - public: - GnssCallbackEventQueue> - antenna_info_cbq_; - - GnssAntennaInfoCallback() : antenna_info_cbq_("info"){}; - virtual ~GnssAntennaInfoCallback() = default; - - // Methods from V2_1::GnssAntennaInfoCallback follow. - Return gnssAntennaInfoCb( - const hidl_vec& gnssAntennaInfos); - }; - - /* - * SetUpGnssCallback: - * Set GnssCallback and verify the result. - */ - void SetUpGnssCallback(); - - /* - * StartAndCheckFirstLocation: - * Helper function to start location, and check the first one. - * - *

Note this leaves the Location request active, to enable Stop call vs. other call - * reordering tests. - * - * returns true if a location was successfully generated - */ - bool StartAndCheckFirstLocation(); - - /* - * CheckLocation: - * Helper function to vet Location fields - * - * check_speed: true if speed related fields are also verified. - */ - void CheckLocation(const GnssLocation_2_0& location, const bool check_speed); - - /* - * StartAndCheckLocations: - * Helper function to collect, and check a number of - * normal ~1Hz locations. - * - * Note this leaves the Location request active, to enable Stop call vs. other call - * reordering tests. - */ - void StartAndCheckLocations(int count); - - /* - * StopAndClearLocations: - * Helper function to stop locations, and clear any remaining notifications - */ - void StopAndClearLocations(); - - /* - * SetPositionMode: - * Helper function to set positioning mode and verify output - */ - void SetPositionMode(const int min_interval_msec, const bool low_power_mode); - - /* - * startLocationAndGetNonGpsConstellation: - * 1. Start location - * 2. Find and return first non-GPS constellation - * - * Note that location is not stopped in this method. The client should call - * StopAndClearLocations() after the call. - */ - GnssConstellationType startLocationAndGetNonGpsConstellation( - const int locations_to_await, const int gnss_sv_info_list_timeout); - - sp gnss_hal_; // GNSS HAL to call into - sp gnss_cb_; // Primary callback interface -}; - -#endif // GNSS_HAL_TEST_H_ +class GnssHalTest : public GnssHalTestTemplate {}; diff --git a/gnss/3.0/Android.bp b/gnss/3.0/Android.bp new file mode 100644 index 0000000000..603c0db589 --- /dev/null +++ b/gnss/3.0/Android.bp @@ -0,0 +1,25 @@ +// This file is autogenerated by hidl-gen -Landroidbp. + +hidl_interface { + name: "android.hardware.gnss@3.0", + root: "android.hardware", + vndk: { + enabled: true, + }, + srcs: [ + "IGnss.hal", + "IGnssPsds.hal", + "IGnssPsdsCallback.hal", + ], + interfaces: [ + "android.hardware.gnss.measurement_corrections@1.0", + "android.hardware.gnss.measurement_corrections@1.1", + "android.hardware.gnss.visibility_control@1.0", + "android.hardware.gnss@1.0", + "android.hardware.gnss@1.1", + "android.hardware.gnss@2.0", + "android.hardware.gnss@2.1", + "android.hidl.base@1.0", + ], + gen_java: true, +} diff --git a/gnss/3.0/IGnss.hal b/gnss/3.0/IGnss.hal new file mode 100644 index 0000000000..18e5a9dee3 --- /dev/null +++ b/gnss/3.0/IGnss.hal @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.gnss@3.0; + +import @2.1::IGnss; +import IGnssPsds; + +/** + * Represents the standard GNSS (Global Navigation Satellite System) interface. + */ +interface IGnss extends @2.1::IGnss { + /** + * This method returns the IGnssPsds interface. + * + * @return psdsIface Handle to the IGnssPsds interface. + */ + getExtensionPsds() generates (IGnssPsds psdsIface); +}; diff --git a/gnss/3.0/IGnssPsds.hal b/gnss/3.0/IGnssPsds.hal new file mode 100644 index 0000000000..5004570574 --- /dev/null +++ b/gnss/3.0/IGnssPsds.hal @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.gnss@3.0; + +import @1.0::IGnssXtra; +import IGnssPsdsCallback; + +/** + * This interface is used by the GNSS HAL to request the framework to download Predicted Satellite + * Data Service data. + */ +interface IGnssPsds extends @1.0::IGnssXtra { + /** + * Opens the PSDS interface and provides the callback routines to the implementation of this + * interface. + * + * @param callback Handle to the IGnssPsdsCallback interface. + * + * @return success True if the operation is successful. + */ + setCallback_3_0(IGnssPsdsCallback callback) generates (bool success); + + /** + * Inject the downloaded PSDS data into the GNSS receiver. + * + * @param psdsType Type of PSDS as defined in IGnssPsdsCallback.hal + * @param psdsData GNSS PSDS data. Framework must not parse the data since the data format is + * opaque to framework. + * + * @return success True if the operation is successful. + */ + injectPsdsData_3_0(int32_t psdsType, string psdsData) generates (bool success); +}; + diff --git a/gnss/3.0/IGnssPsdsCallback.hal b/gnss/3.0/IGnssPsdsCallback.hal new file mode 100644 index 0000000000..d91385f814 --- /dev/null +++ b/gnss/3.0/IGnssPsdsCallback.hal @@ -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. + */ + +package android.hardware.gnss@3.0; + +import @1.0::IGnssXtraCallback; + +/** + * This interface is used by the GNSS HAL to request download data from Predicted Satellite Data + * Service (PSDS). + */ +interface IGnssPsdsCallback extends @1.0::IGnssXtraCallback { + /** + * Callback to request the client to download PSDS data. The client should + * download PSDS data and inject it by calling injectPsdsData(). + * + * psdsType represents the type of PSDS data requested. + * - Value 1 represents the Long-Term type PSDS data, which lasts for many hours to several days + * and often provides satellite orbit and clock accuracy of 2 - 20 meters. + * - Value 2 represents the Normal type PSDS data, which is similar to broadcast ephemeris in + * longevity - lasting for hours and providings satellite orbit and clock accuracy of 1 - 2 + * meters. + * - Value 3 represents the Real-Time type PSDS data, which lasts for minutes and provides brief + * satellite status information such as temporary malfunction, but does not include satellite + * orbit or clock information. + */ + downloadRequestCb_3_0(int32_t psdsType); +}; diff --git a/gnss/3.0/default/Android.bp b/gnss/3.0/default/Android.bp new file mode 100644 index 0000000000..2b33b32058 --- /dev/null +++ b/gnss/3.0/default/Android.bp @@ -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. + */ + +cc_binary { + name: "android.hardware.gnss@3.0-service", + init_rc: ["android.hardware.gnss@3.0-service.rc"], + relative_install_path: "hw", + vendor: true, + vintf_fragments: ["android.hardware.gnss@3.0-service.xml"], + srcs: [ + "Gnss.cpp", + "GnssPsds.cpp", + "service.cpp", + ], + shared_libs: [ + "libhidlbase", + "libutils", + "liblog", + "android.hardware.gnss@1.0", + "android.hardware.gnss@1.1", + "android.hardware.gnss@2.0", + "android.hardware.gnss@2.1", + "android.hardware.gnss@3.0", + "android.hardware.gnss.measurement_corrections@1.1", + "android.hardware.gnss.measurement_corrections@1.0", + ], + static_libs: [ + "android.hardware.gnss@common-default-lib", + ], +} diff --git a/gnss/3.0/default/Gnss.cpp b/gnss/3.0/default/Gnss.cpp new file mode 100644 index 0000000000..5f2ca4f522 --- /dev/null +++ b/gnss/3.0/default/Gnss.cpp @@ -0,0 +1,32 @@ +/* + * 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 "Gnss" + +#include "Gnss.h" +#include +#include "GnssPsds.h" +#include "Utils.h" + +namespace android::hardware::gnss::V3_0::implementation { + +// Methods from V3_0::IGnss follow. +Return> Gnss::getExtensionPsds() { + ALOGD("Gnss::getExtensionPsds"); + return new GnssPsds(); +} + +} // namespace android::hardware::gnss::V3_0::implementation diff --git a/gnss/3.0/default/Gnss.h b/gnss/3.0/default/Gnss.h new file mode 100644 index 0000000000..7ae562ade3 --- /dev/null +++ b/gnss/3.0/default/Gnss.h @@ -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. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include "v2_1/GnssTemplate.h" + +namespace android::hardware::gnss::V3_0::implementation { + +using ::android::sp; +using ::android::hardware::Return; +using ::android::hardware::Void; +using ::android::hardware::gnss::common::implementation::GnssTemplate; + +struct Gnss : public GnssTemplate { + Gnss(){}; + ~Gnss(){}; + + // Methods from V3_0::IGnss follow. + Return> getExtensionPsds() override; +}; + +} // namespace android::hardware::gnss::V3_0::implementation diff --git a/gnss/3.0/default/GnssPsds.cpp b/gnss/3.0/default/GnssPsds.cpp new file mode 100644 index 0000000000..44e096ebd3 --- /dev/null +++ b/gnss/3.0/default/GnssPsds.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "GnssPsds" + +#include "GnssPsds.h" + +#include + +namespace android::hardware::gnss::V3_0::implementation { + +sp GnssPsds::sCallback_3_0 = nullptr; + +// Methods from V1_0::IGnssXtra follow. +Return GnssPsds::setCallback(const sp&) { + // TODO implement + return bool{}; +} + +Return GnssPsds::injectXtraData(const hidl_string&) { + // TODO implement + return bool{}; +} + +// Methods from V3_0::IGnssPsds follow. +Return GnssPsds::setCallback_3_0(const sp& callback) { + ALOGD("setCallback_3_0"); + std::unique_lock lock(mMutex); + sCallback_3_0 = callback; + return true; +} + +Return GnssPsds::injectPsdsData_3_0(int32_t psdsType, const hidl_string& psdsData) { + ALOGD("injectPsdsData_3_0. psdsType: %d, psdsData: %s", psdsType, psdsData.c_str()); + return true; +} +} // namespace android::hardware::gnss::V3_0::implementation diff --git a/gnss/3.0/default/GnssPsds.h b/gnss/3.0/default/GnssPsds.h new file mode 100644 index 0000000000..4053bf17c8 --- /dev/null +++ b/gnss/3.0/default/GnssPsds.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include + +namespace android::hardware::gnss::V3_0::implementation { + +using ::android::sp; +using ::android::hardware::hidl_array; +using ::android::hardware::hidl_memory; +using ::android::hardware::hidl_string; +using ::android::hardware::hidl_vec; +using ::android::hardware::Return; +using ::android::hardware::Void; + +struct GnssPsds : public V3_0::IGnssPsds { + // Methods from V1_0::IGnssXtra follow. + Return setCallback(const sp& callback) override; + Return injectXtraData(const hidl_string& xtraData) override; + + // Methods from V3_0::IGnssPsds follow. + Return setCallback_3_0(const sp& callback) override; + Return injectPsdsData_3_0(int32_t psdsType, const hidl_string& psdsData) override; + + private: + // Guarded by mMutex + static sp sCallback_3_0; + + // Synchronization lock for sCallback_3_0 + mutable std::mutex mMutex; +}; + +} // namespace android::hardware::gnss::V3_0::implementation diff --git a/gnss/3.0/default/OWNERS b/gnss/3.0/default/OWNERS new file mode 100644 index 0000000000..b7b4a2e902 --- /dev/null +++ b/gnss/3.0/default/OWNERS @@ -0,0 +1,4 @@ +gomo@google.com +smalkos@google.com +wyattriley@google.com +yuhany@google.com diff --git a/gnss/3.0/default/android.hardware.gnss@3.0-service.rc b/gnss/3.0/default/android.hardware.gnss@3.0-service.rc new file mode 100644 index 0000000000..c2bfb91e22 --- /dev/null +++ b/gnss/3.0/default/android.hardware.gnss@3.0-service.rc @@ -0,0 +1,4 @@ +service vendor.gnss-3-0 /vendor/bin/hw/android.hardware.gnss@3.0-service + class hal + user system + group system diff --git a/gnss/3.0/default/android.hardware.gnss@3.0-service.xml b/gnss/3.0/default/android.hardware.gnss@3.0-service.xml new file mode 100644 index 0000000000..6709e0c3b5 --- /dev/null +++ b/gnss/3.0/default/android.hardware.gnss@3.0-service.xml @@ -0,0 +1,13 @@ + + + android.hardware.gnss + hwbinder + 3.0 + 2.1 + 1.1 + + IGnss + default + + + diff --git a/gnss/3.0/default/service.cpp b/gnss/3.0/default/service.cpp new file mode 100644 index 0000000000..87b458070b --- /dev/null +++ b/gnss/3.0/default/service.cpp @@ -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. + */ + +#define LOG_TAG "android.hardware.gnss@3.0-service" + +#include +#include +#include "Gnss.h" + +using ::android::OK; +using ::android::sp; +using ::android::hardware::configureRpcThreadpool; +using ::android::hardware::joinRpcThreadpool; +using ::android::hardware::gnss::V3_0::IGnss; +using ::android::hardware::gnss::V3_0::implementation::Gnss; + +int main(int /* argc */, char* /* argv */[]) { + sp gnss = new Gnss(); + configureRpcThreadpool(1, true /* will join */); + if (gnss->registerAsService() != OK) { + ALOGE("Could not register gnss 3.0 service."); + return 1; + } + joinRpcThreadpool(); + + ALOGE("Service exited!"); + return 1; +} \ No newline at end of file diff --git a/gnss/3.0/vts/OWNERS b/gnss/3.0/vts/OWNERS new file mode 100644 index 0000000000..b7b4a2e902 --- /dev/null +++ b/gnss/3.0/vts/OWNERS @@ -0,0 +1,4 @@ +gomo@google.com +smalkos@google.com +wyattriley@google.com +yuhany@google.com diff --git a/gnss/3.0/vts/functional/Android.bp b/gnss/3.0/vts/functional/Android.bp new file mode 100644 index 0000000000..584424ccc4 --- /dev/null +++ b/gnss/3.0/vts/functional/Android.bp @@ -0,0 +1,39 @@ +// +// Copyright (C) 2020 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +cc_test { + name: "VtsHalGnssV3_0TargetTest", + defaults: ["VtsHalTargetTestDefaults"], + srcs: [ + "gnss_hal_test_cases.cpp", + "VtsHalGnssV3_0TargetTest.cpp", + ], + static_libs: [ + "android.hardware.gnss.measurement_corrections@1.0", + "android.hardware.gnss.measurement_corrections@1.1", + "android.hardware.gnss.visibility_control@1.0", + "android.hardware.gnss@1.0", + "android.hardware.gnss@1.1", + "android.hardware.gnss@2.0", + "android.hardware.gnss@2.1", + "android.hardware.gnss@3.0", + "android.hardware.gnss@common-vts-lib", + ], + test_suites: [ + "general-tests", + "vts", + ], +} diff --git a/gnss/3.0/vts/functional/VtsHalGnssV3_0TargetTest.cpp b/gnss/3.0/vts/functional/VtsHalGnssV3_0TargetTest.cpp new file mode 100644 index 0000000000..9eca7b0620 --- /dev/null +++ b/gnss/3.0/vts/functional/VtsHalGnssV3_0TargetTest.cpp @@ -0,0 +1,29 @@ +/* + * 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 "VtsHalGnssV3_0TargetTest" + +#include +#include +#include + +#include "gnss_hal_test.h" + +using android::hardware::gnss::V3_0::IGnss; + +INSTANTIATE_TEST_SUITE_P( + PerInstance, GnssHalTest, + testing::ValuesIn(android::hardware::getAllHalInstanceNames(IGnss::descriptor)), + android::hardware::PrintInstanceNameToString); \ No newline at end of file diff --git a/gnss/3.0/vts/functional/gnss_hal_test.h b/gnss/3.0/vts/functional/gnss_hal_test.h new file mode 100644 index 0000000000..387214eba2 --- /dev/null +++ b/gnss/3.0/vts/functional/gnss_hal_test.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include "v2_1/gnss_hal_test_template.h" + +using android::hardware::gnss::V3_0::IGnss; + +// The main test class for GNSS HAL. +class GnssHalTest : public GnssHalTestTemplate {}; \ No newline at end of file diff --git a/gnss/3.0/vts/functional/gnss_hal_test_cases.cpp b/gnss/3.0/vts/functional/gnss_hal_test_cases.cpp new file mode 100644 index 0000000000..cc5341c181 --- /dev/null +++ b/gnss/3.0/vts/functional/gnss_hal_test_cases.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "GnssHalTestCases" + +#include +#include +#include "Utils.h" + +#include + +using android::hardware::hidl_string; +using android::hardware::hidl_vec; + +using android::hardware::gnss::common::Utils; + +using android::hardware::gnss::V3_0::IGnssPsds; + +/* + * SetupTeardownCreateCleanup: + * Requests the gnss HAL then calls cleanup + * + * Empty test fixture to verify basic Setup & Teardown + */ +TEST_P(GnssHalTest, SetupTeardownCreateCleanup) {} + +/* + * TestPsdsExtension: + * Gets the PsdsExtension and verifies that it returns a non-null extension. + */ +TEST_P(GnssHalTest, TestPsdsExtension) { + auto psds = gnss_hal_->getExtensionPsds(); + ASSERT_TRUE(psds.isOk()); + sp iPsds = psds; + ASSERT_TRUE(iPsds != nullptr); +} diff --git a/gnss/common/utils/default/Android.bp b/gnss/common/utils/default/Android.bp index 2712e7776c..8d9d4d46aa 100644 --- a/gnss/common/utils/default/Android.bp +++ b/gnss/common/utils/default/Android.bp @@ -24,6 +24,11 @@ cc_library_static { "-Werror", ], srcs: [ + "v2_1/GnssAntennaInfo.cpp", + "v2_1/GnssConfiguration.cpp", + "v2_1/GnssDebug.cpp", + "v2_1/GnssMeasurement.cpp", + "v2_1/GnssMeasurementCorrections.cpp", "Utils.cpp", "NmeaFixInfo.cpp", ], @@ -34,5 +39,7 @@ cc_library_static { "android.hardware.gnss@1.0", "android.hardware.gnss@2.0", "android.hardware.gnss@2.1", + "android.hardware.gnss.measurement_corrections@1.1", + "android.hardware.gnss.measurement_corrections@1.0", ], } diff --git a/gnss/2.1/default/GnssAntennaInfo.h b/gnss/common/utils/default/include/v2_1/GnssAntennaInfo.h similarity index 80% rename from gnss/2.1/default/GnssAntennaInfo.h rename to gnss/common/utils/default/include/v2_1/GnssAntennaInfo.h index f2ce9a8955..e74ff54839 100644 --- a/gnss/2.1/default/GnssAntennaInfo.h +++ b/gnss/common/utils/default/include/v2_1/GnssAntennaInfo.h @@ -14,23 +14,20 @@ * limitations under the License. */ -#ifndef ANDROID_HARDWARE_GNSS_V2_1_GNSSANTENNAINFO_H -#define ANDROID_HARDWARE_GNSS_V2_1_GNSSANTENNAINFO_H +#pragma once #include #include #include -namespace android { -namespace hardware { -namespace gnss { -namespace V2_1 { -namespace implementation { +namespace android::hardware::gnss::V2_1::implementation { using ::android::sp; using ::android::hardware::Return; using ::android::hardware::Void; +using IGnssAntennaInfo = ::android::hardware::gnss::V2_1::IGnssAntennaInfo; +using IGnssAntennaInfoCallback = ::android::hardware::gnss::V2_1::IGnssAntennaInfoCallback; struct GnssAntennaInfo : public IGnssAntennaInfo { GnssAntennaInfo(); @@ -58,10 +55,4 @@ struct GnssAntennaInfo : public IGnssAntennaInfo { mutable std::mutex mMutex; }; -} // namespace implementation -} // namespace V2_1 -} // namespace gnss -} // namespace hardware -} // namespace android - -#endif // ANDROID_HARDWARE_GNSS_V2_1_GNSSCONFIGURATION_H \ No newline at end of file +} // namespace android::hardware::gnss::V2_1::implementation diff --git a/gnss/2.1/default/GnssConfiguration.h b/gnss/common/utils/default/include/v2_1/GnssConfiguration.h similarity index 89% rename from gnss/2.1/default/GnssConfiguration.h rename to gnss/common/utils/default/include/v2_1/GnssConfiguration.h index 662d61d038..8463a5caa2 100644 --- a/gnss/2.1/default/GnssConfiguration.h +++ b/gnss/common/utils/default/include/v2_1/GnssConfiguration.h @@ -14,8 +14,7 @@ * limitations under the License. */ -#ifndef ANDROID_HARDWARE_GNSS_V2_1_GNSSCONFIGURATION_H -#define ANDROID_HARDWARE_GNSS_V2_1_GNSSCONFIGURATION_H +#pragma once #include #include @@ -24,11 +23,7 @@ #include #include -namespace android { -namespace hardware { -namespace gnss { -namespace V2_1 { -namespace implementation { +namespace android::hardware::gnss::V2_1::implementation { using ::android::sp; using ::android::hardware::hidl_array; @@ -92,10 +87,4 @@ struct GnssConfiguration : public IGnssConfiguration { BlacklistedConstellationSetV2_1 mBlacklistedConstellationSet; }; -} // namespace implementation -} // namespace V2_1 -} // namespace gnss -} // namespace hardware -} // namespace android - -#endif // ANDROID_HARDWARE_GNSS_V2_1_GNSSCONFIGURATION_H \ No newline at end of file +} // namespace android::hardware::gnss::V2_1::implementation diff --git a/gnss/2.1/default/GnssDebug.h b/gnss/common/utils/default/include/v2_1/GnssDebug.h similarity index 76% rename from gnss/2.1/default/GnssDebug.h rename to gnss/common/utils/default/include/v2_1/GnssDebug.h index 969d337524..8580989c6a 100644 --- a/gnss/2.1/default/GnssDebug.h +++ b/gnss/common/utils/default/include/v2_1/GnssDebug.h @@ -14,17 +14,12 @@ * limitations under the License. */ -#ifndef android_hardware_gnss_V1_1_GnssDebug_H_ -#define android_hardware_gnss_V1_1_GnssDebug_H_ +#pragma once #include #include -namespace android { -namespace hardware { -namespace gnss { -namespace V1_1 { -namespace implementation { +namespace android::hardware::gnss::V1_1::implementation { using ::android::sp; using ::android::hardware::hidl_string; @@ -42,10 +37,4 @@ struct GnssDebug : public IGnssDebug { Return getDebugData(V1_0::IGnssDebug::getDebugData_cb _hidl_cb) override; }; -} // namespace implementation -} // namespace V1_1 -} // namespace gnss -} // namespace hardware -} // namespace android - -#endif // android_hardware_gnss_V1_1_GnssDebug_H_ +} // namespace android::hardware::gnss::V1_1::implementation diff --git a/gnss/2.1/default/GnssMeasurement.h b/gnss/common/utils/default/include/v2_1/GnssMeasurement.h similarity index 92% rename from gnss/2.1/default/GnssMeasurement.h rename to gnss/common/utils/default/include/v2_1/GnssMeasurement.h index d44641978f..1d1fc9d712 100644 --- a/gnss/2.1/default/GnssMeasurement.h +++ b/gnss/common/utils/default/include/v2_1/GnssMeasurement.h @@ -23,11 +23,7 @@ #include #include -namespace android { -namespace hardware { -namespace gnss { -namespace V2_1 { -namespace implementation { +namespace android::hardware::gnss::V2_1::implementation { using GnssDataV2_1 = V2_1::IGnssMeasurementCallback::GnssData; using GnssDataV2_0 = V2_0::IGnssMeasurementCallback::GnssData; @@ -80,8 +76,4 @@ struct GnssMeasurement : public IGnssMeasurement { mutable std::mutex mMutex; }; -} // namespace implementation -} // namespace V2_1 -} // namespace gnss -} // namespace hardware -} // namespace android +} // namespace android::hardware::gnss::V2_1::implementation diff --git a/gnss/2.1/default/GnssMeasurementCorrections.h b/gnss/common/utils/default/include/v2_1/GnssMeasurementCorrections.h similarity index 72% rename from gnss/2.1/default/GnssMeasurementCorrections.h rename to gnss/common/utils/default/include/v2_1/GnssMeasurementCorrections.h index 036e855586..eaa7659c6b 100644 --- a/gnss/2.1/default/GnssMeasurementCorrections.h +++ b/gnss/common/utils/default/include/v2_1/GnssMeasurementCorrections.h @@ -20,22 +20,15 @@ #include #include -namespace android { -namespace hardware { -namespace gnss { -namespace measurement_corrections { -namespace V1_1 { -namespace implementation { +namespace android::hardware::gnss::measurement_corrections::V1_1::implementation { using ::android::sp; -using ::android::hardware::hidl_array; -using ::android::hardware::hidl_memory; -using ::android::hardware::hidl_string; -using ::android::hardware::hidl_vec; using ::android::hardware::Return; -using ::android::hardware::Void; struct GnssMeasurementCorrections : public IMeasurementCorrections { + GnssMeasurementCorrections(); + ~GnssMeasurementCorrections(); + // Methods from V1_0::IMeasurementCorrections follow. Return setCorrections(const V1_0::MeasurementCorrections& corrections) override; Return setCallback(const sp& callback) override; @@ -44,9 +37,4 @@ struct GnssMeasurementCorrections : public IMeasurementCorrections { Return setCorrections_1_1(const V1_1::MeasurementCorrections& corrections) override; }; -} // namespace implementation -} // namespace V1_1 -} // namespace measurement_corrections -} // namespace gnss -} // namespace hardware -} // namespace android +} // namespace android::hardware::gnss::measurement_corrections::V1_1::implementation diff --git a/gnss/2.1/default/Gnss.cpp b/gnss/common/utils/default/include/v2_1/GnssTemplate.h similarity index 50% rename from gnss/2.1/default/Gnss.cpp rename to gnss/common/utils/default/include/v2_1/GnssTemplate.h index 16f2bf3cd0..d16a67bffe 100644 --- a/gnss/2.1/default/Gnss.cpp +++ b/gnss/common/utils/default/include/v2_1/GnssTemplate.h @@ -14,44 +14,149 @@ * limitations under the License. */ -#define LOG_TAG "Gnss" +#pragma once -#include "Gnss.h" +#include +#include +#include +#include #include #include +#include +#include #include +#include + #include "GnssAntennaInfo.h" +#include "GnssConfiguration.h" #include "GnssDebug.h" #include "GnssMeasurement.h" #include "GnssMeasurementCorrections.h" +#include "NmeaFixInfo.h" #include "Utils.h" -using ::android::hardware::gnss::common::Utils; -using ::android::hardware::gnss::measurement_corrections::V1_1::implementation:: - GnssMeasurementCorrections; - -namespace android { -namespace hardware { -namespace gnss { -namespace V2_1 { -namespace implementation { - -sp Gnss::sGnssCallback_2_1 = nullptr; -sp Gnss::sGnssCallback_2_0 = nullptr; -sp Gnss::sGnssCallback_1_1 = nullptr; -sp Gnss::sGnssCallback_1_0 = nullptr; - -Gnss::Gnss() +namespace android::hardware::gnss::common::implementation { + +using GnssSvInfo = V2_1::IGnssCallback::GnssSvInfo; + +using common::NmeaFixInfo; +using common::Utils; +using measurement_corrections::V1_1::implementation::GnssMeasurementCorrections; + +using V2_1::implementation::GnssAntennaInfo; +using V2_1::implementation::GnssConfiguration; +using V2_1::implementation::GnssMeasurement; + +constexpr int INPUT_BUFFER_SIZE = 128; +constexpr char CMD_GET_LOCATION[] = "CMD_GET_LOCATION"; +constexpr char GNSS_PATH[] = "/dev/gnss0"; + +template +struct GnssTemplate : public T_IGnss { + GnssTemplate(); + ~GnssTemplate(); + // Methods from V1_0::IGnss follow. + Return setCallback(const sp& callback) override; + Return start() override; + Return stop() override; + Return cleanup() override; + Return injectTime(int64_t timeMs, int64_t timeReferenceMs, + int32_t uncertaintyMs) override; + Return injectLocation(double latitudeDegrees, double longitudeDegrees, + float accuracyMeters) override; + Return deleteAidingData(V1_0::IGnss::GnssAidingData aidingDataFlags) override; + Return setPositionMode(V1_0::IGnss::GnssPositionMode mode, + V1_0::IGnss::GnssPositionRecurrence recurrence, + uint32_t minIntervalMs, uint32_t preferredAccuracyMeters, + uint32_t preferredTimeMs) override; + Return> getExtensionAGnssRil() override; + Return> getExtensionGnssGeofencing() override; + Return> getExtensionAGnss() override; + Return> getExtensionGnssNi() override; + Return> getExtensionGnssMeasurement() override; + Return> getExtensionGnssNavigationMessage() override; + Return> getExtensionXtra() override; + Return> getExtensionGnssConfiguration() override; + Return> getExtensionGnssDebug() override; + Return> getExtensionGnssBatching() override; + + // Methods from V1_1::IGnss follow. + Return setCallback_1_1(const sp& callback) override; + Return setPositionMode_1_1(V1_0::IGnss::GnssPositionMode mode, + V1_0::IGnss::GnssPositionRecurrence recurrence, + uint32_t minIntervalMs, uint32_t preferredAccuracyMeters, + uint32_t preferredTimeMs, bool lowPowerMode) override; + Return> getExtensionGnssConfiguration_1_1() override; + Return> getExtensionGnssMeasurement_1_1() override; + Return injectBestLocation(const V1_0::GnssLocation& location) override; + + // Methods from V2_0::IGnss follow. + Return setCallback_2_0(const sp& callback) override; + Return> getExtensionGnssConfiguration_2_0() override; + Return> getExtensionGnssDebug_2_0() override; + Return> getExtensionAGnss_2_0() override; + Return> getExtensionAGnssRil_2_0() override; + Return> getExtensionGnssMeasurement_2_0() override; + Return> + getExtensionMeasurementCorrections() override; + Return> getExtensionVisibilityControl() + override; + Return> getExtensionGnssBatching_2_0() override; + Return injectBestLocation_2_0(const V2_0::GnssLocation& location) override; + + // Methods from V2_1::IGnss follow. + Return setCallback_2_1(const sp& callback) override; + Return> getExtensionGnssMeasurement_2_1() override; + Return> getExtensionGnssConfiguration_2_1() override; + Return> + getExtensionMeasurementCorrections_1_1() override; + Return> getExtensionGnssAntennaInfo() override; + + private: + std::unique_ptr getLocationFromHW(); + void reportLocation(const V2_0::GnssLocation&) const; + void reportLocation(const V1_0::GnssLocation&) const; + void reportSvStatus(const hidl_vec&) const; + + static sp sGnssCallback_2_1; + static sp sGnssCallback_2_0; + static sp sGnssCallback_1_1; + static sp sGnssCallback_1_0; + + std::atomic mMinIntervalMs; + sp mGnssConfiguration; + std::atomic mIsActive; + std::atomic mHardwareModeOn; + std::atomic mGnssFd; + std::thread mThread; + + mutable std::mutex mMutex; + hidl_vec filterBlacklistedSatellitesV2_1(hidl_vec gnssSvInfoList); +}; + +template +sp GnssTemplate::sGnssCallback_2_1 = nullptr; +template +sp GnssTemplate::sGnssCallback_2_0 = nullptr; +template +sp GnssTemplate::sGnssCallback_1_1 = nullptr; +template +sp GnssTemplate::sGnssCallback_1_0 = nullptr; + +template +GnssTemplate::GnssTemplate() : mMinIntervalMs(1000), mGnssConfiguration{new GnssConfiguration()}, mHardwareModeOn(false), mGnssFd(-1) {} -Gnss::~Gnss() { +template +GnssTemplate::~GnssTemplate() { stop(); } -std::unique_ptr Gnss::getLocationFromHW() { +template +std::unique_ptr GnssTemplate::getLocationFromHW() { char inputBuffer[INPUT_BUFFER_SIZE]; mHardwareModeOn = false; if (mGnssFd == -1) { @@ -89,7 +194,8 @@ std::unique_ptr Gnss::getLocationFromHW() { return NmeaFixInfo::getLocationFromInputStr(inputStr); } -Return Gnss::start() { +template +Return GnssTemplate::start() { if (mIsActive) { ALOGW("Gnss has started. Restarting..."); stop(); @@ -124,7 +230,9 @@ Return Gnss::start() { return true; } -hidl_vec Gnss::filterBlacklistedSatellitesV2_1(hidl_vec gnssSvInfoList) { +template +hidl_vec GnssTemplate::filterBlacklistedSatellitesV2_1( + hidl_vec gnssSvInfoList) { for (uint32_t i = 0; i < gnssSvInfoList.size(); i++) { if (mGnssConfiguration->isBlacklistedV2_1(gnssSvInfoList[i])) { gnssSvInfoList[i].v2_0.v1_0.svFlag &= @@ -134,7 +242,8 @@ hidl_vec Gnss::filterBlacklistedSatellitesV2_1(hidl_vec return gnssSvInfoList; } -Return Gnss::stop() { +template +Return GnssTemplate::stop() { ALOGD("stop"); mIsActive = false; if (mThread.joinable()) { @@ -148,7 +257,8 @@ Return Gnss::stop() { } // Methods from V1_0::IGnss follow. -Return Gnss::setCallback(const sp& callback) { +template +Return GnssTemplate::setCallback(const sp& callback) { if (callback == nullptr) { ALOGE("%s: Null callback ignored", __func__); return false; @@ -163,7 +273,7 @@ Return Gnss::setCallback(const sp& callback) { ALOGE("%s: Unable to invoke callback", __func__); } - IGnssCallback::GnssSystemInfo gnssInfo = {.yearOfHw = 2018}; + V2_1::IGnssCallback::GnssSystemInfo gnssInfo = {.yearOfHw = 2018}; ret = sGnssCallback_1_0->gnssSetSystemInfoCb(gnssInfo); if (!ret.isOk()) { @@ -173,83 +283,100 @@ Return Gnss::setCallback(const sp& callback) { return true; } -Return Gnss::cleanup() { +template +Return GnssTemplate::cleanup() { sGnssCallback_2_1 = nullptr; sGnssCallback_2_0 = nullptr; return Void(); } -Return Gnss::injectTime(int64_t, int64_t, int32_t) { +template +Return GnssTemplate::injectTime(int64_t, int64_t, int32_t) { return true; } -Return Gnss::injectLocation(double, double, float) { +template +Return GnssTemplate::injectLocation(double, double, float) { return true; } -Return Gnss::deleteAidingData(V1_0::IGnss::GnssAidingData) { +template +Return GnssTemplate::deleteAidingData(V1_0::IGnss::GnssAidingData) { // TODO implement return Void(); } -Return Gnss::setPositionMode(V1_0::IGnss::GnssPositionMode, - V1_0::IGnss::GnssPositionRecurrence, uint32_t minIntervalMs, - uint32_t, uint32_t) { +template +Return GnssTemplate::setPositionMode(V1_0::IGnss::GnssPositionMode, + V1_0::IGnss::GnssPositionRecurrence, + uint32_t minIntervalMs, uint32_t, uint32_t) { mMinIntervalMs = minIntervalMs; return true; } -Return> Gnss::getExtensionAGnssRil() { +template +Return> GnssTemplate::getExtensionAGnssRil() { // TODO implement return ::android::sp{}; } -Return> Gnss::getExtensionGnssGeofencing() { +template +Return> GnssTemplate::getExtensionGnssGeofencing() { // TODO implement return ::android::sp{}; } -Return> Gnss::getExtensionAGnss() { +template +Return> GnssTemplate::getExtensionAGnss() { // TODO implement return ::android::sp{}; } -Return> Gnss::getExtensionGnssNi() { +template +Return> GnssTemplate::getExtensionGnssNi() { // TODO implement return ::android::sp{}; } -Return> Gnss::getExtensionGnssMeasurement() { +template +Return> GnssTemplate::getExtensionGnssMeasurement() { ALOGD("Gnss::getExtensionGnssMeasurement"); return new GnssMeasurement(); } -Return> Gnss::getExtensionGnssNavigationMessage() { +template +Return> +GnssTemplate::getExtensionGnssNavigationMessage() { // TODO implement return ::android::sp{}; } -Return> Gnss::getExtensionXtra() { +template +Return> GnssTemplate::getExtensionXtra() { // TODO implement return ::android::sp{}; } -Return> Gnss::getExtensionGnssConfiguration() { +template +Return> GnssTemplate::getExtensionGnssConfiguration() { // TODO implement return ::android::sp{}; } -Return> Gnss::getExtensionGnssDebug() { +template +Return> GnssTemplate::getExtensionGnssDebug() { return new V1_1::implementation::GnssDebug(); } -Return> Gnss::getExtensionGnssBatching() { +template +Return> GnssTemplate::getExtensionGnssBatching() { // TODO implement return ::android::sp{}; } // Methods from V1_1::IGnss follow. -Return Gnss::setCallback_1_1(const sp& callback) { +template +Return GnssTemplate::setCallback_1_1(const sp& callback) { if (callback == nullptr) { ALOGE("%s: Null callback ignored", __func__); return false; @@ -263,7 +390,7 @@ Return Gnss::setCallback_1_1(const sp& callback) { ALOGE("%s: Unable to invoke callback", __func__); } - IGnssCallback::GnssSystemInfo gnssInfo = {.yearOfHw = 2018}; + V2_1::IGnssCallback::GnssSystemInfo gnssInfo = {.yearOfHw = 2018}; ret = sGnssCallback_1_1->gnssSetSystemInfoCb(gnssInfo); if (!ret.isOk()) { @@ -279,29 +406,35 @@ Return Gnss::setCallback_1_1(const sp& callback) { return true; } -Return Gnss::setPositionMode_1_1(V1_0::IGnss::GnssPositionMode, - V1_0::IGnss::GnssPositionRecurrence, uint32_t minIntervalMs, - uint32_t, uint32_t, bool) { +template +Return GnssTemplate::setPositionMode_1_1(V1_0::IGnss::GnssPositionMode, + V1_0::IGnss::GnssPositionRecurrence, + uint32_t minIntervalMs, uint32_t, uint32_t, + bool) { mMinIntervalMs = minIntervalMs; return true; } -Return> Gnss::getExtensionGnssConfiguration_1_1() { +template +Return> GnssTemplate::getExtensionGnssConfiguration_1_1() { // TODO implement return ::android::sp{}; } -Return> Gnss::getExtensionGnssMeasurement_1_1() { +template +Return> GnssTemplate::getExtensionGnssMeasurement_1_1() { // TODO implement return ::android::sp{}; } -Return Gnss::injectBestLocation(const V1_0::GnssLocation&) { +template +Return GnssTemplate::injectBestLocation(const V1_0::GnssLocation&) { return true; } // Methods from V2_0::IGnss follow. -Return Gnss::setCallback_2_0(const sp& callback) { +template +Return GnssTemplate::setCallback_2_0(const sp& callback) { ALOGD("Gnss::setCallback_2_0"); if (callback == nullptr) { ALOGE("%s: Null callback ignored", __func__); @@ -334,54 +467,65 @@ Return Gnss::setCallback_2_0(const sp& callback) { return true; } -Return> Gnss::getExtensionGnssConfiguration_2_0() { +template +Return> GnssTemplate::getExtensionGnssConfiguration_2_0() { ALOGD("Gnss::getExtensionGnssConfiguration_2_0"); return mGnssConfiguration; } -Return> Gnss::getExtensionGnssDebug_2_0() { +template +Return> GnssTemplate::getExtensionGnssDebug_2_0() { // TODO implement return ::android::sp{}; } -Return> Gnss::getExtensionAGnss_2_0() { +template +Return> GnssTemplate::getExtensionAGnss_2_0() { // TODO implement return ::android::sp{}; } -Return> Gnss::getExtensionAGnssRil_2_0() { +template +Return> GnssTemplate::getExtensionAGnssRil_2_0() { // TODO implement return ::android::sp{}; } -Return> Gnss::getExtensionGnssMeasurement_2_0() { +template +Return> GnssTemplate::getExtensionGnssMeasurement_2_0() { ALOGD("Gnss::getExtensionGnssMeasurement_2_0"); return new GnssMeasurement(); } +template Return> -Gnss::getExtensionMeasurementCorrections() { +GnssTemplate::getExtensionMeasurementCorrections() { ALOGD("Gnss::getExtensionMeasurementCorrections()"); return new GnssMeasurementCorrections(); } -Return> Gnss::getExtensionVisibilityControl() { +template +Return> +GnssTemplate::getExtensionVisibilityControl() { // TODO implement return ::android::sp{}; } -Return> Gnss::getExtensionGnssBatching_2_0() { +template +Return> GnssTemplate::getExtensionGnssBatching_2_0() { // TODO implement return ::android::sp{}; } -Return Gnss::injectBestLocation_2_0(const V2_0::GnssLocation&) { +template +Return GnssTemplate::injectBestLocation_2_0(const V2_0::GnssLocation&) { // TODO(b/124012850): Implement function. return bool{}; } // Methods from V2_1::IGnss follow. -Return Gnss::setCallback_2_1(const sp& callback) { +template +Return GnssTemplate::setCallback_2_1(const sp& callback) { ALOGD("Gnss::setCallback_2_1"); if (callback == nullptr) { ALOGE("%s: Null callback ignored", __func__); @@ -415,28 +559,33 @@ Return Gnss::setCallback_2_1(const sp& callback) { return true; } -Return> Gnss::getExtensionGnssMeasurement_2_1() { +template +Return> GnssTemplate::getExtensionGnssMeasurement_2_1() { ALOGD("Gnss::getExtensionGnssMeasurement_2_1"); return new GnssMeasurement(); } -Return> Gnss::getExtensionGnssConfiguration_2_1() { +template +Return> GnssTemplate::getExtensionGnssConfiguration_2_1() { ALOGD("Gnss::getExtensionGnssConfiguration_2_1"); return mGnssConfiguration; } +template Return> -Gnss::getExtensionMeasurementCorrections_1_1() { +GnssTemplate::getExtensionMeasurementCorrections_1_1() { ALOGD("Gnss::getExtensionMeasurementCorrections_1_1()"); return new GnssMeasurementCorrections(); } -Return> Gnss::getExtensionGnssAntennaInfo() { +template +Return> GnssTemplate::getExtensionGnssAntennaInfo() { ALOGD("Gnss::getExtensionGnssAntennaInfo"); return new GnssAntennaInfo(); } -void Gnss::reportSvStatus(const hidl_vec& svInfoList) const { +template +void GnssTemplate::reportSvStatus(const hidl_vec& svInfoList) const { std::unique_lock lock(mMutex); // TODO(skz): update this to call 2_0 callback if non-null if (sGnssCallback_2_1 == nullptr) { @@ -449,7 +598,8 @@ void Gnss::reportSvStatus(const hidl_vec& svInfoList) const { } } -void Gnss::reportLocation(const V1_0::GnssLocation& location) const { +template +void GnssTemplate::reportLocation(const V1_0::GnssLocation& location) const { std::unique_lock lock(mMutex); if (sGnssCallback_1_1 != nullptr) { auto ret = sGnssCallback_1_1->gnssLocationCb(location); @@ -468,7 +618,8 @@ void Gnss::reportLocation(const V1_0::GnssLocation& location) const { } } -void Gnss::reportLocation(const V2_0::GnssLocation& location) const { +template +void GnssTemplate::reportLocation(const V2_0::GnssLocation& location) const { std::unique_lock lock(mMutex); if (sGnssCallback_2_1 != nullptr) { auto ret = sGnssCallback_2_1->gnssLocationCb_2_0(location); @@ -487,8 +638,4 @@ void Gnss::reportLocation(const V2_0::GnssLocation& location) const { } } -} // namespace implementation -} // namespace V2_1 -} // namespace gnss -} // namespace hardware -} // namespace android +} // namespace android::hardware::gnss::common::implementation diff --git a/gnss/2.1/default/GnssAntennaInfo.cpp b/gnss/common/utils/default/v2_1/GnssAntennaInfo.cpp similarity index 91% rename from gnss/2.1/default/GnssAntennaInfo.cpp rename to gnss/common/utils/default/v2_1/GnssAntennaInfo.cpp index ed183a9383..962451c0dd 100644 --- a/gnss/2.1/default/GnssAntennaInfo.cpp +++ b/gnss/common/utils/default/v2_1/GnssAntennaInfo.cpp @@ -16,18 +16,14 @@ #define LOG_TAG "GnssAntennaInfo" -#include "GnssAntennaInfo.h" +#include "v2_1/GnssAntennaInfo.h" #include "Utils.h" #include using ::android::hardware::gnss::common::Utils; -namespace android { -namespace hardware { -namespace gnss { -namespace V2_1 { -namespace implementation { +namespace android::hardware::gnss::V2_1::implementation { sp GnssAntennaInfo::sCallback = nullptr; @@ -102,8 +98,4 @@ void GnssAntennaInfo::reportAntennaInfo( } } -} // namespace implementation -} // namespace V2_1 -} // namespace gnss -} // namespace hardware -} // namespace android \ No newline at end of file +} // namespace android::hardware::gnss::V2_1::implementation diff --git a/gnss/2.1/default/GnssConfiguration.cpp b/gnss/common/utils/default/v2_1/GnssConfiguration.cpp similarity index 93% rename from gnss/2.1/default/GnssConfiguration.cpp rename to gnss/common/utils/default/v2_1/GnssConfiguration.cpp index cd8f07fcc4..8b30701ea1 100644 --- a/gnss/2.1/default/GnssConfiguration.cpp +++ b/gnss/common/utils/default/v2_1/GnssConfiguration.cpp @@ -16,14 +16,10 @@ #define LOG_TAG "GnssConfiguration" -#include "GnssConfiguration.h" +#include "v2_1/GnssConfiguration.h" #include -namespace android { -namespace hardware { -namespace gnss { -namespace V2_1 { -namespace implementation { +namespace android::hardware::gnss::V2_1::implementation { // Methods from ::android::hardware::gnss::V1_0::IGnssConfiguration follow. Return GnssConfiguration::setSuplEs(bool enable) { @@ -99,8 +95,4 @@ Return GnssConfiguration::isBlacklistedV2_1(const GnssSvInfoV2_1& gnssSvIn return (mBlacklistedSourceSet.find(source) != mBlacklistedSourceSet.end()); } -} // namespace implementation -} // namespace V2_1 -} // namespace gnss -} // namespace hardware -} // namespace android \ No newline at end of file +} // namespace android::hardware::gnss::V2_1::implementation diff --git a/gnss/2.1/default/GnssDebug.cpp b/gnss/common/utils/default/v2_1/GnssDebug.cpp similarity index 88% rename from gnss/2.1/default/GnssDebug.cpp rename to gnss/common/utils/default/v2_1/GnssDebug.cpp index a9f7ded2a7..492b970b59 100644 --- a/gnss/2.1/default/GnssDebug.cpp +++ b/gnss/common/utils/default/v2_1/GnssDebug.cpp @@ -19,15 +19,11 @@ #include #include "Constants.h" -#include "GnssDebug.h" +#include "v2_1/GnssDebug.h" using namespace ::android::hardware::gnss::common; -namespace android { -namespace hardware { -namespace gnss { -namespace V1_1 { -namespace implementation { +namespace android::hardware::gnss::V1_1::implementation { // Methods from ::android::hardware::gnss::V1_0::IGnssDebug follow. Return GnssDebug::getDebugData(V1_0::IGnssDebug::getDebugData_cb _hidl_cb) { @@ -55,8 +51,4 @@ Return GnssDebug::getDebugData(V1_0::IGnssDebug::getDebugData_cb _hidl_cb) return Void(); } -} // namespace implementation -} // namespace V1_1 -} // namespace gnss -} // namespace hardware -} // namespace android +} // namespace android::hardware::gnss::V1_1::implementation diff --git a/gnss/2.1/default/GnssMeasurement.cpp b/gnss/common/utils/default/v2_1/GnssMeasurement.cpp similarity index 94% rename from gnss/2.1/default/GnssMeasurement.cpp rename to gnss/common/utils/default/v2_1/GnssMeasurement.cpp index 63bbc0a399..7d3a002ea7 100644 --- a/gnss/2.1/default/GnssMeasurement.cpp +++ b/gnss/common/utils/default/v2_1/GnssMeasurement.cpp @@ -16,19 +16,14 @@ #define LOG_TAG "GnssMeasurement" -#include "GnssMeasurement.h" +#include "v2_1/GnssMeasurement.h" #include #include "Utils.h" -namespace android { -namespace hardware { -namespace gnss { +namespace android::hardware::gnss::V2_1::implementation { using common::Utils; -namespace V2_1 { -namespace implementation { - sp GnssMeasurement::sCallback_2_1 = nullptr; sp GnssMeasurement::sCallback_2_0 = nullptr; @@ -145,8 +140,4 @@ void GnssMeasurement::reportMeasurement(const GnssDataV2_1& data) { } } -} // namespace implementation -} // namespace V2_1 -} // namespace gnss -} // namespace hardware -} // namespace android +} // namespace android::hardware::gnss::V2_1::implementation diff --git a/gnss/2.1/default/GnssMeasurementCorrections.cpp b/gnss/common/utils/default/v2_1/GnssMeasurementCorrections.cpp similarity index 93% rename from gnss/2.1/default/GnssMeasurementCorrections.cpp rename to gnss/common/utils/default/v2_1/GnssMeasurementCorrections.cpp index accf62b733..9be7e2350f 100644 --- a/gnss/2.1/default/GnssMeasurementCorrections.cpp +++ b/gnss/common/utils/default/v2_1/GnssMeasurementCorrections.cpp @@ -16,15 +16,14 @@ #define LOG_TAG "GnssMeasurementCorrections" -#include "GnssMeasurementCorrections.h" +#include "v2_1/GnssMeasurementCorrections.h" #include -namespace android { -namespace hardware { -namespace gnss { -namespace measurement_corrections { -namespace V1_1 { -namespace implementation { +namespace android::hardware::gnss::measurement_corrections::V1_1::implementation { + +GnssMeasurementCorrections::GnssMeasurementCorrections() {} + +GnssMeasurementCorrections::~GnssMeasurementCorrections() {} // Methods from V1_0::IMeasurementCorrections follow. Return GnssMeasurementCorrections::setCorrections( @@ -101,9 +100,4 @@ Return GnssMeasurementCorrections::setCorrections_1_1( return true; } -} // namespace implementation -} // namespace V1_1 -} // namespace measurement_corrections -} // namespace gnss -} // namespace hardware -} // namespace android +} // namespace android::hardware::gnss::measurement_corrections::V1_1::implementation diff --git a/gnss/common/utils/vts/Android.bp b/gnss/common/utils/vts/Android.bp index 4c6d4439bc..e36b656171 100644 --- a/gnss/common/utils/vts/Android.bp +++ b/gnss/common/utils/vts/Android.bp @@ -25,11 +25,14 @@ cc_library_static { ], srcs: [ "Utils.cpp", + "v2_1/GnssCallback.cpp", ], export_include_dirs: ["include"], shared_libs: [ "android.hardware.gnss@1.0", + "android.hardware.gnss@1.1", "android.hardware.gnss@2.0", + "android.hardware.gnss@2.1", "android.hardware.gnss.measurement_corrections@1.0", "android.hardware.gnss.measurement_corrections@1.1", ], diff --git a/gnss/common/utils/vts/include/v2_1/GnssCallback.h b/gnss/common/utils/vts/include/v2_1/GnssCallback.h new file mode 100644 index 0000000000..ab1375d3a5 --- /dev/null +++ b/gnss/common/utils/vts/include/v2_1/GnssCallback.h @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include "GnssCallbackEventQueue.h" + +#include + +using android::hardware::hidl_vec; +using android::hardware::Return; +using android::hardware::Void; + +using android::hardware::gnss::common::GnssCallbackEventQueue; +using android::hardware::gnss::measurement_corrections::V1_0::IMeasurementCorrectionsCallback; +using android::hardware::gnss::V1_0::GnssLocationFlags; +using android::hardware::gnss::V2_0::GnssConstellationType; + +using GnssLocation_1_0 = android::hardware::gnss::V1_0::GnssLocation; +using GnssLocation_2_0 = android::hardware::gnss::V2_0::GnssLocation; + +using IGnssCallback_1_0 = android::hardware::gnss::V1_0::IGnssCallback; +using IGnssCallback_2_0 = android::hardware::gnss::V2_0::IGnssCallback; +using IGnssCallback_2_1 = android::hardware::gnss::V2_1::IGnssCallback; + +using IGnssMeasurementCallback_1_0 = android::hardware::gnss::V1_0::IGnssMeasurementCallback; +using IGnssMeasurementCallback_1_1 = android::hardware::gnss::V1_1::IGnssMeasurementCallback; +using IGnssMeasurementCallback_2_0 = android::hardware::gnss::V2_0::IGnssMeasurementCallback; +using IGnssMeasurementCallback_2_1 = android::hardware::gnss::V2_1::IGnssMeasurementCallback; + +using android::sp; + +#define TIMEOUT_SEC 2 // for basic commands/responses + +namespace android::hardware::gnss::common { + +/* Callback class for data & Event. */ +class GnssCallback : public IGnssCallback_2_1 { + public: + IGnssCallback_1_0::GnssSystemInfo last_info_; + android::hardware::hidl_string last_name_; + uint32_t last_capabilities_; + GnssLocation_2_0 last_location_; + + GnssCallbackEventQueue info_cbq_; + GnssCallbackEventQueue name_cbq_; + GnssCallbackEventQueue capabilities_cbq_; + GnssCallbackEventQueue location_cbq_; + GnssCallbackEventQueue> sv_info_list_cbq_; + + GnssCallback(); + virtual ~GnssCallback() = default; + + // Dummy callback handlers + Return gnssStatusCb(const IGnssCallback_1_0::GnssStatusValue /* status */) override { + return Void(); + } + Return gnssNmeaCb(int64_t /* timestamp */, + const android::hardware::hidl_string& /* nmea */) override { + return Void(); + } + Return gnssAcquireWakelockCb() override { return Void(); } + Return gnssReleaseWakelockCb() override { return Void(); } + Return gnssRequestLocationCb(bool /* independentFromGnss */) override { return Void(); } + Return gnssRequestTimeCb() override { return Void(); } + // Actual (test) callback handlers + Return gnssNameCb(const android::hardware::hidl_string& name) override; + Return gnssLocationCb(const GnssLocation_1_0& location) override; + Return gnssSetCapabilitesCb(uint32_t capabilities) override; + Return gnssSetSystemInfoCb(const IGnssCallback_1_0::GnssSystemInfo& info) override; + Return gnssSvStatusCb(const IGnssCallback_1_0::GnssSvStatus& svStatus) override; + + // New in v2.0 + Return gnssLocationCb_2_0(const GnssLocation_2_0& location) override; + Return gnssRequestLocationCb_2_0(bool /* independentFromGnss */, + bool /* isUserEmergency */) override { + return Void(); + } + Return gnssSetCapabilitiesCb_2_0(uint32_t capabilities) override; + Return gnssSvStatusCb_2_0(const hidl_vec&) override { + return Void(); + } + + // New in v2.1 + Return gnssSvStatusCb_2_1( + const hidl_vec& svInfoList) override; + Return gnssSetCapabilitiesCb_2_1(uint32_t capabilities) override; + + private: + Return gnssLocationCbImpl(const GnssLocation_2_0& location); +}; + +} // namespace android::hardware::gnss::common diff --git a/gnss/common/utils/vts/include/v2_1/gnss_hal_test_template.h b/gnss/common/utils/vts/include/v2_1/gnss_hal_test_template.h new file mode 100644 index 0000000000..d057c617be --- /dev/null +++ b/gnss/common/utils/vts/include/v2_1/gnss_hal_test_template.h @@ -0,0 +1,381 @@ +/* + * 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. + */ + +#pragma once + +#include "GnssCallbackEventQueue.h" +#include "Utils.h" +#include "v2_1/GnssCallback.h" + +#include +#include + +using ::android::hardware::gnss::common::Utils; + +using android::hardware::hidl_vec; +using android::hardware::Return; +using android::hardware::Void; + +using android::hardware::gnss::common::GnssCallback; +using android::hardware::gnss::common::GnssCallbackEventQueue; +using android::hardware::gnss::measurement_corrections::V1_0::IMeasurementCorrectionsCallback; +using android::hardware::gnss::V1_0::GnssLocationFlags; +using android::hardware::gnss::V2_0::GnssConstellationType; +using android::hardware::gnss::V2_1::IGnssAntennaInfo; +using android::hardware::gnss::V2_1::IGnssAntennaInfoCallback; + +using GnssLocation_1_0 = android::hardware::gnss::V1_0::GnssLocation; +using GnssLocation_2_0 = android::hardware::gnss::V2_0::GnssLocation; + +using IGnssCallback_1_0 = android::hardware::gnss::V1_0::IGnssCallback; +using IGnssCallback_2_0 = android::hardware::gnss::V2_0::IGnssCallback; +using IGnssCallback_2_1 = android::hardware::gnss::V2_1::IGnssCallback; + +using IGnssMeasurementCallback_1_0 = android::hardware::gnss::V1_0::IGnssMeasurementCallback; +using IGnssMeasurementCallback_1_1 = android::hardware::gnss::V1_1::IGnssMeasurementCallback; +using IGnssMeasurementCallback_2_0 = android::hardware::gnss::V2_0::IGnssMeasurementCallback; +using IGnssMeasurementCallback_2_1 = android::hardware::gnss::V2_1::IGnssMeasurementCallback; + +using android::sp; + +#define TIMEOUT_SEC 2 // for basic commands/responses + +// The main test class for GNSS HAL. +template +class GnssHalTestTemplate : public testing::TestWithParam { + public: + virtual void SetUp() override; + + virtual void TearDown() override; + + /* Callback class for GnssMeasurement. */ + class GnssMeasurementCallback : public IGnssMeasurementCallback_2_1 { + public: + GnssCallbackEventQueue measurement_cbq_; + + GnssMeasurementCallback() : measurement_cbq_("measurement"){}; + virtual ~GnssMeasurementCallback() = default; + + // Methods from V1_0::IGnssMeasurementCallback follow. + Return GnssMeasurementCb(const IGnssMeasurementCallback_1_0::GnssData&) override { + return Void(); + } + + // Methods from V1_1::IGnssMeasurementCallback follow. + Return gnssMeasurementCb(const IGnssMeasurementCallback_1_1::GnssData&) override { + return Void(); + } + + // Methods from V2_0::IGnssMeasurementCallback follow. + Return gnssMeasurementCb_2_0(const IGnssMeasurementCallback_2_0::GnssData&) override { + return Void(); + } + + // Methods from V2_1::IGnssMeasurementCallback follow. + Return gnssMeasurementCb_2_1(const IGnssMeasurementCallback_2_1::GnssData&) override; + }; + + /* Callback class for GnssMeasurementCorrections. */ + class GnssMeasurementCorrectionsCallback : public IMeasurementCorrectionsCallback { + public: + uint32_t last_capabilities_; + GnssCallbackEventQueue capabilities_cbq_; + + GnssMeasurementCorrectionsCallback() : capabilities_cbq_("capabilities"){}; + virtual ~GnssMeasurementCorrectionsCallback() = default; + + // Methods from V1_0::IMeasurementCorrectionsCallback follow. + Return setCapabilitiesCb(uint32_t capabilities) override; + }; + + /* Callback class for GnssAntennaInfo. */ + class GnssAntennaInfoCallback : public IGnssAntennaInfoCallback { + public: + GnssCallbackEventQueue> + antenna_info_cbq_; + + GnssAntennaInfoCallback() : antenna_info_cbq_("info"){}; + virtual ~GnssAntennaInfoCallback() = default; + + // Methods from V2_1::GnssAntennaInfoCallback follow. + Return gnssAntennaInfoCb( + const hidl_vec& gnssAntennaInfos); + }; + + /* + * SetUpGnssCallback: + * Set GnssCallback and verify the result. + */ + void SetUpGnssCallback(); + + /* + * StartAndCheckFirstLocation: + * Helper function to start location, and check the first one. + * + *

Note this leaves the Location request active, to enable Stop call vs. other call + * reordering tests. + * + * returns true if a location was successfully generated + */ + bool StartAndCheckFirstLocation(); + + /* + * CheckLocation: + * Helper function to vet Location fields + * + * check_speed: true if speed related fields are also verified. + */ + void CheckLocation(const GnssLocation_2_0& location, const bool check_speed); + + /* + * StartAndCheckLocations: + * Helper function to collect, and check a number of + * normal ~1Hz locations. + * + * Note this leaves the Location request active, to enable Stop call vs. other call + * reordering tests. + */ + void StartAndCheckLocations(int count); + + /* + * StopAndClearLocations: + * Helper function to stop locations, and clear any remaining notifications + */ + void StopAndClearLocations(); + + /* + * SetPositionMode: + * Helper function to set positioning mode and verify output + */ + void SetPositionMode(const int min_interval_msec, const bool low_power_mode); + + /* + * startLocationAndGetNonGpsConstellation: + * 1. Start location + * 2. Find and return first non-GPS constellation + * + * Note that location is not stopped in this method. The client should call + * StopAndClearLocations() after the call. + */ + GnssConstellationType startLocationAndGetNonGpsConstellation( + const int locations_to_await, const int gnss_sv_info_list_timeout); + + sp gnss_hal_; // GNSS HAL to call into + sp gnss_cb_; // Primary callback interface +}; + +using ::android::hardware::gnss::common::Utils; + +// Implementations for the main test class for GNSS HAL +template +void GnssHalTestTemplate::SetUp() { + gnss_hal_ = T_IGnss::getService(GetParam()); + ASSERT_NE(gnss_hal_, nullptr); + + SetUpGnssCallback(); +} + +template +void GnssHalTestTemplate::TearDown() { + if (gnss_hal_ != nullptr) { + gnss_hal_->cleanup(); + gnss_hal_ = nullptr; + } + + // Set to nullptr to destruct the callback event queues and warn of any unprocessed events. + gnss_cb_ = nullptr; +} + +template +void GnssHalTestTemplate::SetUpGnssCallback() { + gnss_cb_ = new GnssCallback(); + ASSERT_NE(gnss_cb_, nullptr); + + auto result = gnss_hal_->setCallback_2_1(gnss_cb_); + if (!result.isOk()) { + ALOGE("result of failed setCallback %s", result.description().c_str()); + } + + ASSERT_TRUE(result.isOk()); + ASSERT_TRUE(result); + + /* + * All capabilities, name and systemInfo callbacks should trigger + */ + EXPECT_TRUE(gnss_cb_->capabilities_cbq_.retrieve(gnss_cb_->last_capabilities_, TIMEOUT_SEC)); + EXPECT_TRUE(gnss_cb_->info_cbq_.retrieve(gnss_cb_->last_info_, TIMEOUT_SEC)); + EXPECT_TRUE(gnss_cb_->name_cbq_.retrieve(gnss_cb_->last_name_, TIMEOUT_SEC)); + + EXPECT_EQ(gnss_cb_->capabilities_cbq_.calledCount(), 1); + EXPECT_EQ(gnss_cb_->info_cbq_.calledCount(), 1); + EXPECT_EQ(gnss_cb_->name_cbq_.calledCount(), 1); +} + +template +void GnssHalTestTemplate::StopAndClearLocations() { + const auto result = gnss_hal_->stop(); + + EXPECT_TRUE(result.isOk()); + EXPECT_TRUE(result); + + /* + * Clear notify/waiting counter, allowing up till the timeout after + * the last reply for final startup messages to arrive (esp. system + * info.) + */ + while (gnss_cb_->location_cbq_.retrieve(gnss_cb_->last_location_, TIMEOUT_SEC)) { + } + gnss_cb_->location_cbq_.reset(); +} + +template +void GnssHalTestTemplate::SetPositionMode(const int min_interval_msec, + const bool low_power_mode) { + const int kPreferredAccuracy = 0; // Ideally perfect (matches GnssLocationProvider) + const int kPreferredTimeMsec = 0; // Ideally immediate + + const auto result = gnss_hal_->setPositionMode_1_1( + T_IGnss::GnssPositionMode::MS_BASED, + T_IGnss::GnssPositionRecurrence::RECURRENCE_PERIODIC, min_interval_msec, + kPreferredAccuracy, kPreferredTimeMsec, low_power_mode); + + ASSERT_TRUE(result.isOk()); + EXPECT_TRUE(result); +} + +template +bool GnssHalTestTemplate::StartAndCheckFirstLocation() { + const auto result = gnss_hal_->start(); + + EXPECT_TRUE(result.isOk()); + EXPECT_TRUE(result); + + /* + * GnssLocationProvider support of AGPS SUPL & XtraDownloader is not available in VTS, + * so allow time to demodulate ephemeris over the air. + */ + const int kFirstGnssLocationTimeoutSeconds = 75; + + EXPECT_TRUE(gnss_cb_->location_cbq_.retrieve(gnss_cb_->last_location_, + kFirstGnssLocationTimeoutSeconds)); + int locationCalledCount = gnss_cb_->location_cbq_.calledCount(); + EXPECT_EQ(locationCalledCount, 1); + + if (locationCalledCount > 0) { + // don't require speed on first fix + CheckLocation(gnss_cb_->last_location_, false); + return true; + } + return false; +} + +template +void GnssHalTestTemplate::CheckLocation(const GnssLocation_2_0& location, + bool check_speed) { + const bool check_more_accuracies = + (gnss_cb_->info_cbq_.calledCount() > 0 && gnss_cb_->last_info_.yearOfHw >= 2017); + + Utils::checkLocation(location.v1_0, check_speed, check_more_accuracies); +} + +template +void GnssHalTestTemplate::StartAndCheckLocations(int count) { + const int kMinIntervalMsec = 500; + const int kLocationTimeoutSubsequentSec = 2; + const bool kLowPowerMode = false; + + SetPositionMode(kMinIntervalMsec, kLowPowerMode); + + EXPECT_TRUE(StartAndCheckFirstLocation()); + + for (int i = 1; i < count; i++) { + EXPECT_TRUE(gnss_cb_->location_cbq_.retrieve(gnss_cb_->last_location_, + kLocationTimeoutSubsequentSec)); + int locationCalledCount = gnss_cb_->location_cbq_.calledCount(); + EXPECT_EQ(locationCalledCount, i + 1); + // Don't cause confusion by checking details if no location yet + if (locationCalledCount > 0) { + // Should be more than 1 location by now, but if not, still don't check first fix speed + CheckLocation(gnss_cb_->last_location_, locationCalledCount > 1); + } + } +} + +template +GnssConstellationType GnssHalTestTemplate::startLocationAndGetNonGpsConstellation( + const int locations_to_await, const int gnss_sv_info_list_timeout) { + gnss_cb_->location_cbq_.reset(); + StartAndCheckLocations(locations_to_await); + const int location_called_count = gnss_cb_->location_cbq_.calledCount(); + + // Tolerate 1 less sv status to handle edge cases in reporting. + int sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size(); + EXPECT_GE(sv_info_list_cbq_size + 1, locations_to_await); + ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations (%d received)", + sv_info_list_cbq_size, locations_to_await, location_called_count); + + // Find first non-GPS constellation to blacklist + GnssConstellationType constellation_to_blacklist = GnssConstellationType::UNKNOWN; + for (int i = 0; i < sv_info_list_cbq_size; ++i) { + hidl_vec sv_info_vec; + gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, gnss_sv_info_list_timeout); + for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) { + const auto& gnss_sv = sv_info_vec[iSv]; + if ((gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX) && + (gnss_sv.v2_0.constellation != GnssConstellationType::UNKNOWN) && + (gnss_sv.v2_0.constellation != GnssConstellationType::GPS)) { + // found a non-GPS constellation + constellation_to_blacklist = gnss_sv.v2_0.constellation; + break; + } + } + if (constellation_to_blacklist != GnssConstellationType::UNKNOWN) { + break; + } + } + + if (constellation_to_blacklist == GnssConstellationType::UNKNOWN) { + ALOGI("No non-GPS constellations found, constellation blacklist test less effective."); + // Proceed functionally to blacklist something. + constellation_to_blacklist = GnssConstellationType::GLONASS; + } + + return constellation_to_blacklist; +} + +template +Return GnssHalTestTemplate::GnssMeasurementCallback::gnssMeasurementCb_2_1( + const IGnssMeasurementCallback_2_1::GnssData& data) { + ALOGD("GnssMeasurement v2.1 received. Size = %d", (int)data.measurements.size()); + measurement_cbq_.store(data); + return Void(); +} + +template +Return GnssHalTestTemplate::GnssMeasurementCorrectionsCallback::setCapabilitiesCb( + uint32_t capabilities) { + ALOGI("GnssMeasurementCorrectionsCallback capabilities received %d", capabilities); + capabilities_cbq_.store(capabilities); + return Void(); +} + +template +Return GnssHalTestTemplate::GnssAntennaInfoCallback::gnssAntennaInfoCb( + const hidl_vec& gnssAntennaInfos) { + ALOGD("GnssAntennaInfo v2.1 received. Size = %d", (int)gnssAntennaInfos.size()); + antenna_info_cbq_.store(gnssAntennaInfos); + return Void(); +} diff --git a/gnss/common/utils/vts/v2_1/GnssCallback.cpp b/gnss/common/utils/vts/v2_1/GnssCallback.cpp new file mode 100644 index 0000000000..3b96fb834b --- /dev/null +++ b/gnss/common/utils/vts/v2_1/GnssCallback.cpp @@ -0,0 +1,95 @@ +/* + * 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 "GnssCallback" + +#include "v2_1/GnssCallback.h" +#include +#include "Utils.h" + +#include + +using ::android::hardware::gnss::common::Utils; + +namespace android::hardware::gnss::common { + +GnssCallback::GnssCallback() + : info_cbq_("system_info"), + name_cbq_("name"), + capabilities_cbq_("capabilities"), + location_cbq_("location"), + sv_info_list_cbq_("sv_info") {} + +Return GnssCallback::gnssSetSystemInfoCb(const IGnssCallback_1_0::GnssSystemInfo& info) { + ALOGI("Info received, year %d", info.yearOfHw); + info_cbq_.store(info); + return Void(); +} + +Return GnssCallback::gnssSetCapabilitesCb(uint32_t capabilities) { + ALOGI("Capabilities received %d", capabilities); + capabilities_cbq_.store(capabilities); + return Void(); +} + +Return GnssCallback::gnssSetCapabilitiesCb_2_0(uint32_t capabilities) { + ALOGI("Capabilities (v2.0) received %d", capabilities); + capabilities_cbq_.store(capabilities); + return Void(); +} + +Return GnssCallback::gnssSetCapabilitiesCb_2_1(uint32_t capabilities) { + ALOGI("Capabilities (v2.1) received %d", capabilities); + capabilities_cbq_.store(capabilities); + return Void(); +} + +Return GnssCallback::gnssNameCb(const android::hardware::hidl_string& name) { + ALOGI("Name received: %s", name.c_str()); + name_cbq_.store(name); + return Void(); +} + +Return GnssCallback::gnssLocationCb(const GnssLocation_1_0& location) { + ALOGI("Location received"); + GnssLocation_2_0 location_v2_0; + location_v2_0.v1_0 = location; + return gnssLocationCbImpl(location_v2_0); +} + +Return GnssCallback::gnssLocationCb_2_0(const GnssLocation_2_0& location) { + ALOGI("Location (v2.0) received"); + return gnssLocationCbImpl(location); +} + +Return GnssCallback::gnssLocationCbImpl(const GnssLocation_2_0& location) { + location_cbq_.store(location); + return Void(); +} + +Return GnssCallback::gnssSvStatusCb(const IGnssCallback_1_0::GnssSvStatus&) { + ALOGI("gnssSvStatusCb"); + return Void(); +} + +Return GnssCallback::gnssSvStatusCb_2_1( + const hidl_vec& svInfoList) { + ALOGI("gnssSvStatusCb_2_1. Size = %d", (int)svInfoList.size()); + sv_info_list_cbq_.store(svInfoList); + return Void(); +} + +} // namespace android::hardware::gnss::common diff --git a/gnss/measurement_corrections/1.1/Android.bp b/gnss/measurement_corrections/1.1/Android.bp index d279af6cd2..f7ac8b88fd 100644 --- a/gnss/measurement_corrections/1.1/Android.bp +++ b/gnss/measurement_corrections/1.1/Android.bp @@ -12,8 +12,8 @@ hidl_interface { ], interfaces: [ "android.hardware.gnss.measurement_corrections@1.0", - "android.hardware.gnss@2.0", "android.hardware.gnss@1.0", + "android.hardware.gnss@2.0", "android.hidl.base@1.0", ], gen_java: true, -- GitLab From 85a9ab32d7243a4cf027267e439c7e025b463570 Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Fri, 19 Jun 2020 16:44:52 -0700 Subject: [PATCH 053/790] Implement ES data process in Tuner default impl to support Sample TIS This CL also provides a new VTS case to test ES input stream. Please see the test.es https://drive.google.com/file/d/13ZDT9uhEO1LXDT2GcOhB91iIK6m_KEER/view?usp=sharing ES Format(all the numbers are in decimal): 1. First line is a general meta data to describe the whole file m:meta data size in bytes, l:ES frame line count X, V:video raw data size int bytes, A:audio raw data size in bytes, pv:video pid, pa:audio pid 2. The following X lines(equals to the ES frame line count) are the size/pts information of the video or audio ES frames. Starting with v means video, a means audio. They are printed in the same order as how they presented in the original ts. v, Len:current ES frame size in bytes, PTS: current ES frame PTS 3. After the X lines of ES frame descriptions, there are the video ES raw data connected with the audio ES raw data. Test: atest VtsHalTvTunerV1_0TargetTest Bug: 159027928 Change-Id: I56bd799fd6eda867df54d593235510a5e4758257 --- tv/tuner/1.0/default/Demux.cpp | 11 ++ tv/tuner/1.0/default/Demux.h | 1 + tv/tuner/1.0/default/Dvr.cpp | 149 ++++++++++++++++-- tv/tuner/1.0/default/Dvr.h | 10 ++ tv/tuner/1.0/default/Filter.cpp | 99 +++++++----- tv/tuner/1.0/default/Filter.h | 3 + tv/tuner/1.0/vts/functional/FrontendTests.cpp | 10 +- tv/tuner/1.0/vts/functional/FrontendTests.h | 5 +- .../VtsHalTvTunerV1_0TargetTest.cpp | 56 +++++++ .../VtsHalTvTunerV1_0TestConfigurations.h | 18 +-- 10 files changed, 292 insertions(+), 70 deletions(-) diff --git a/tv/tuner/1.0/default/Demux.cpp b/tv/tuner/1.0/default/Demux.cpp index 67eff1bd63..b122a05017 100644 --- a/tv/tuner/1.0/default/Demux.cpp +++ b/tv/tuner/1.0/default/Demux.cpp @@ -294,6 +294,11 @@ void Demux::updateFilterOutput(uint16_t filterId, vector data) { mFilters[filterId]->updateFilterOutput(data); } +void Demux::updateMediaFilterOutput(uint16_t filterId, vector data, uint64_t pts) { + updateFilterOutput(filterId, data); + mFilters[filterId]->updatePts(pts); +} + uint16_t Demux::getFilterTpid(uint32_t filterId) { return mFilters[filterId]->getTpid(); } @@ -322,6 +327,12 @@ void Demux::frontendInputThreadLoop() { ALOGD("[Demux] wait for data ready on the playback FMQ"); continue; } + if (mDvrPlayback->getSettings().playback().dataFormat == DataFormat::ES) { + if (!mDvrPlayback->processEsDataOnPlayback(true /*isVirtualFrontend*/, mIsRecording)) { + ALOGE("[Demux] playback es data failed to be filtered. Ending thread"); + break; + } + } // Our current implementation filter the data and write it into the filter FMQ immediately // after the DATA_READY from the VTS/framework if (!mDvrPlayback->readPlaybackFMQ(true /*isVirtualFrontend*/, mIsRecording) || diff --git a/tv/tuner/1.0/default/Demux.h b/tv/tuner/1.0/default/Demux.h index 7f282b250f..6e93ea32f8 100644 --- a/tv/tuner/1.0/default/Demux.h +++ b/tv/tuner/1.0/default/Demux.h @@ -87,6 +87,7 @@ class Demux : public IDemux { bool detachRecordFilter(int filterId); Result startFilterHandler(uint32_t filterId); void updateFilterOutput(uint16_t filterId, vector data); + void updateMediaFilterOutput(uint16_t filterId, vector data, uint64_t pts); uint16_t getFilterTpid(uint32_t filterId); void setIsRecording(bool isRecording); void startFrontendInputLoop(); diff --git a/tv/tuner/1.0/default/Dvr.cpp b/tv/tuner/1.0/default/Dvr.cpp index 68e175c17d..bb3b087ceb 100644 --- a/tv/tuner/1.0/default/Dvr.cpp +++ b/tv/tuner/1.0/default/Dvr.cpp @@ -129,7 +129,7 @@ Return Dvr::stop() { mDvrThreadRunning = false; - std::lock_guard lock(mDvrThreadLock); + lock_guard lock(mDvrThreadLock); mIsRecordStarted = false; mDemux->setIsRecording(false); @@ -155,14 +155,13 @@ bool Dvr::createDvrMQ() { ALOGV("%s", __FUNCTION__); // Create a synchronized FMQ that supports blocking read/write - std::unique_ptr tmpDvrMQ = - std::unique_ptr(new (std::nothrow) DvrMQ(mBufferSize, true)); + unique_ptr tmpDvrMQ = unique_ptr(new (nothrow) DvrMQ(mBufferSize, true)); if (!tmpDvrMQ->isValid()) { ALOGW("[Dvr] Failed to create FMQ of DVR"); return false; } - mDvrMQ = std::move(tmpDvrMQ); + mDvrMQ = move(tmpDvrMQ); if (EventFlag::createEventFlag(mDvrMQ->getEventFlagWord(), &mDvrEventFlag) != OK) { return false; @@ -183,7 +182,7 @@ void* Dvr::__threadLoopPlayback(void* user) { void Dvr::playbackThreadLoop() { ALOGD("[Dvr] playback threadLoop start."); - std::lock_guard lock(mDvrThreadLock); + lock_guard lock(mDvrThreadLock); mDvrThreadRunning = true; while (mDvrThreadRunning) { @@ -195,6 +194,14 @@ void Dvr::playbackThreadLoop() { ALOGD("[Dvr] wait for data ready on the playback FMQ"); continue; } + + if (mDvrSettings.playback().dataFormat == DataFormat::ES) { + if (!processEsDataOnPlayback(false /*isVirtualFrontend*/, false /*isRecording*/)) { + ALOGE("[Dvr] playback es data failed to be filtered. Ending thread"); + break; + } + maySendPlaybackStatusCallback(); + } // Our current implementation filter the data and write it into the filter FMQ immediately // after the DATA_READY from the VTS/framework if (!readPlaybackFMQ(false /*isVirtualFrontend*/, false /*isRecording*/) || @@ -211,7 +218,7 @@ void Dvr::playbackThreadLoop() { } void Dvr::maySendPlaybackStatusCallback() { - std::lock_guard lock(mPlaybackStatusLock); + lock_guard lock(mPlaybackStatusLock); int availableToRead = mDvrMQ->availableToRead(); int availableToWrite = mDvrMQ->availableToWrite(); @@ -263,8 +270,128 @@ bool Dvr::readPlaybackFMQ(bool isVirtualFrontend, bool isRecording) { return true; } +bool Dvr::processEsDataOnPlayback(bool isVirtualFrontend, bool isRecording) { + // Read ES from the DVR FMQ + // Note that currently we only provides ES with metaData in a specific format to be parsed. + // The ES size should be smaller than the Playback FMQ size to avoid reading truncated data. + int size = mDvrMQ->availableToRead(); + vector dataOutputBuffer; + dataOutputBuffer.resize(size); + if (!mDvrMQ->read(dataOutputBuffer.data(), size)) { + return false; + } + + int metaDataSize = size; + int totalFrames = 0; + int videoEsDataSize = 0; + int audioEsDataSize = 0; + int audioPid = 0; + int videoPid = 0; + + vector esMeta; + int videoReadPointer = 0; + int audioReadPointer = 0; + int frameCount = 0; + // Get meta data from the es + for (int i = 0; i < metaDataSize; i++) { + switch (dataOutputBuffer[i]) { + case 'm': + metaDataSize = 0; + getMetaDataValue(i, dataOutputBuffer.data(), metaDataSize); + videoReadPointer = metaDataSize; + continue; + case 'l': + getMetaDataValue(i, dataOutputBuffer.data(), totalFrames); + esMeta.resize(totalFrames); + continue; + case 'V': + getMetaDataValue(i, dataOutputBuffer.data(), videoEsDataSize); + audioReadPointer = metaDataSize + videoEsDataSize; + continue; + case 'A': + getMetaDataValue(i, dataOutputBuffer.data(), audioEsDataSize); + continue; + case 'p': + if (dataOutputBuffer[++i] == 'a') { + getMetaDataValue(i, dataOutputBuffer.data(), audioPid); + } else if (dataOutputBuffer[i] == 'v') { + getMetaDataValue(i, dataOutputBuffer.data(), videoPid); + } + continue; + case 'v': + case 'a': + if (dataOutputBuffer[i + 1] != ',') { + ALOGE("[Dvr] Invalid format meta data."); + return false; + } + esMeta[frameCount] = { + .isAudio = dataOutputBuffer[i] == 'a' ? true : false, + }; + i += 5; // Move to Len + getMetaDataValue(i, dataOutputBuffer.data(), esMeta[frameCount].len); + if (esMeta[frameCount].isAudio) { + esMeta[frameCount].startIndex = audioReadPointer; + audioReadPointer += esMeta[frameCount].len; + } else { + esMeta[frameCount].startIndex = videoReadPointer; + videoReadPointer += esMeta[frameCount].len; + } + i += 4; // move to PTS + getMetaDataValue(i, dataOutputBuffer.data(), esMeta[frameCount].pts); + frameCount++; + continue; + default: + continue; + } + } + + if (frameCount != totalFrames) { + ALOGE("[Dvr] Invalid meta data, frameCount=%d, totalFrames reported=%d", frameCount, + totalFrames); + return false; + } + + if (metaDataSize + audioEsDataSize + videoEsDataSize != size) { + ALOGE("[Dvr] Invalid meta data, metaSize=%d, videoSize=%d, audioSize=%d, totolSize=%d", + metaDataSize, videoEsDataSize, audioEsDataSize, size); + return false; + } + + // Read es raw data from the FMQ per meta data built previously + vector frameData; + map>::iterator it; + int pid = 0; + for (int i = 0; i < totalFrames; i++) { + frameData.resize(esMeta[i].len); + pid = esMeta[i].isAudio ? audioPid : videoPid; + memcpy(dataOutputBuffer.data() + esMeta[i].startIndex, frameData.data(), esMeta[i].len); + // Send to the media filter + if (isVirtualFrontend && isRecording) { + // TODO validate record + mDemux->sendFrontendInputToRecord(frameData); + } else { + for (it = mFilters.begin(); it != mFilters.end(); it++) { + if (pid == mDemux->getFilterTpid(it->first)) { + mDemux->updateMediaFilterOutput(it->first, frameData, + static_cast(esMeta[i].pts)); + startFilterDispatcher(isVirtualFrontend, isRecording); + } + } + } + } + + return true; +} + +void Dvr::getMetaDataValue(int& index, uint8_t* dataOutputBuffer, int& value) { + index += 2; // Move the pointer across the ":" to the value + while (dataOutputBuffer[index] != ',' && dataOutputBuffer[index] != '\n') { + value = ((dataOutputBuffer[index++] - 48) + value * 10); + } +} + void Dvr::startTpidFilter(vector data) { - std::map>::iterator it; + map>::iterator it; for (it = mFilters.begin(); it != mFilters.end(); it++) { uint16_t pid = ((data[1] & 0x1f) << 8) | ((data[2] & 0xff)); if (DEBUG_DVR) { @@ -285,7 +412,7 @@ bool Dvr::startFilterDispatcher(bool isVirtualFrontend, bool isRecording) { } } - std::map>::iterator it; + map>::iterator it; // Handle the output data per filter type for (it = mFilters.begin(); it != mFilters.end(); it++) { if (mDemux->startFilterHandler(it->first) != Result::SUCCESS) { @@ -296,8 +423,8 @@ bool Dvr::startFilterDispatcher(bool isVirtualFrontend, bool isRecording) { return true; } -bool Dvr::writeRecordFMQ(const std::vector& data) { - std::lock_guard lock(mWriteLock); +bool Dvr::writeRecordFMQ(const vector& data) { + lock_guard lock(mWriteLock); if (mRecordStatus == RecordStatus::OVERFLOW) { ALOGW("[Dvr] stops writing and wait for the client side flushing."); return true; @@ -313,7 +440,7 @@ bool Dvr::writeRecordFMQ(const std::vector& data) { } void Dvr::maySendRecordStatusCallback() { - std::lock_guard lock(mRecordStatusLock); + lock_guard lock(mRecordStatusLock); int availableToRead = mDvrMQ->availableToRead(); int availableToWrite = mDvrMQ->availableToWrite(); diff --git a/tv/tuner/1.0/default/Dvr.h b/tv/tuner/1.0/default/Dvr.h index a63a25670c..30695866ca 100644 --- a/tv/tuner/1.0/default/Dvr.h +++ b/tv/tuner/1.0/default/Dvr.h @@ -44,6 +44,13 @@ using ::android::hardware::tv::tuner::V1_0::Result; using DvrMQ = MessageQueue; +struct MediaEsMetaData { + bool isAudio; + int startIndex; + int len; + int pts; +}; + class Demux; class Filter; class Frontend; @@ -84,8 +91,10 @@ class Dvr : public IDvr { bool addPlaybackFilter(uint32_t filterId, sp filter); bool removePlaybackFilter(uint32_t filterId); bool readPlaybackFMQ(bool isVirtualFrontend, bool isRecording); + bool processEsDataOnPlayback(bool isVirtualFrontend, bool isRecording); bool startFilterDispatcher(bool isVirtualFrontend, bool isRecording); EventFlag* getDvrEventFlag(); + DvrSettings getSettings() { return mDvrSettings; } private: // Demux service @@ -98,6 +107,7 @@ class Dvr : public IDvr { void deleteEventFlag(); bool readDataFromMQ(); + void getMetaDataValue(int& index, uint8_t* dataOutputBuffer, int& value); void maySendPlaybackStatusCallback(); void maySendRecordStatusCallback(); PlaybackStatus checkPlaybackStatusChange(uint32_t availableToWrite, uint32_t availableToRead, diff --git a/tv/tuner/1.0/default/Filter.cpp b/tv/tuner/1.0/default/Filter.cpp index 30b19c0b07..ce748e5098 100644 --- a/tv/tuner/1.0/default/Filter.cpp +++ b/tv/tuner/1.0/default/Filter.cpp @@ -317,6 +317,11 @@ void Filter::updateFilterOutput(vector data) { mFilterOutput.insert(mFilterOutput.end(), data.begin(), data.end()); } +void Filter::updatePts(uint64_t pts) { + std::lock_guard lock(mFilterOutputLock); + mPts = pts; +} + void Filter::updateRecordOutput(vector data) { std::lock_guard lock(mRecordFilterOutputLock); mRecordFilterOutput.insert(mRecordFilterOutput.end(), data.begin(), data.end()); @@ -460,6 +465,11 @@ Result Filter::startMediaFilterHandler() { if (mFilterOutput.empty()) { return Result::SUCCESS; } + + if (mPts) { + return createMediaFilterEventWithIon(mFilterOutput); + } + for (int i = 0; i < mFilterOutput.size(); i += 188) { if (mPesSizeLeft == 0) { uint32_t prefix = (mFilterOutput[i + 4] << 16) | (mFilterOutput[i + 5] << 8) | @@ -493,46 +503,7 @@ Result Filter::startMediaFilterHandler() { continue; } - int av_fd = createAvIonFd(mPesOutput.size()); - if (av_fd == -1) { - return Result::UNKNOWN_ERROR; - } - // copy the filtered data to the buffer - uint8_t* avBuffer = getIonBuffer(av_fd, mPesOutput.size()); - if (avBuffer == NULL) { - return Result::UNKNOWN_ERROR; - } - memcpy(avBuffer, mPesOutput.data(), mPesOutput.size() * sizeof(uint8_t)); - - native_handle_t* nativeHandle = createNativeHandle(av_fd); - if (nativeHandle == NULL) { - return Result::UNKNOWN_ERROR; - } - hidl_handle handle; - handle.setTo(nativeHandle, /*shouldOwn=*/true); - - // Create a dataId and add a pair into the dataId2Avfd map - uint64_t dataId = mLastUsedDataId++ /*createdUID*/; - mDataId2Avfd[dataId] = dup(av_fd); - - // Create mediaEvent and send callback - DemuxFilterMediaEvent mediaEvent; - mediaEvent = { - .avMemory = std::move(handle), - .dataLength = static_cast(mPesOutput.size()), - .avDataId = dataId, - }; - int size = mFilterEvent.events.size(); - mFilterEvent.events.resize(size + 1); - mFilterEvent.events[size].media(mediaEvent); - - // Clear and log - mPesOutput.clear(); - mAvBufferCopyCount = 0; - ::close(av_fd); - if (DEBUG_FILTER) { - ALOGD("[Filter] assembled av data length %d", mediaEvent.dataLength); - } + createMediaFilterEventWithIon(mPesOutput); } mFilterOutput.clear(); @@ -540,6 +511,54 @@ Result Filter::startMediaFilterHandler() { return Result::SUCCESS; } +Result Filter::createMediaFilterEventWithIon(vector output) { + int av_fd = createAvIonFd(output.size()); + if (av_fd == -1) { + return Result::UNKNOWN_ERROR; + } + // copy the filtered data to the buffer + uint8_t* avBuffer = getIonBuffer(av_fd, output.size()); + if (avBuffer == NULL) { + return Result::UNKNOWN_ERROR; + } + memcpy(avBuffer, output.data(), output.size() * sizeof(uint8_t)); + + native_handle_t* nativeHandle = createNativeHandle(av_fd); + if (nativeHandle == NULL) { + return Result::UNKNOWN_ERROR; + } + hidl_handle handle; + handle.setTo(nativeHandle, /*shouldOwn=*/true); + + // Create a dataId and add a pair into the dataId2Avfd map + uint64_t dataId = mLastUsedDataId++ /*createdUID*/; + mDataId2Avfd[dataId] = dup(av_fd); + + // Create mediaEvent and send callback + DemuxFilterMediaEvent mediaEvent; + mediaEvent = { + .avMemory = std::move(handle), + .dataLength = static_cast(output.size()), + .avDataId = dataId, + }; + if (mPts) { + mediaEvent.pts = mPts; + mPts = 0; + } + int size = mFilterEvent.events.size(); + mFilterEvent.events.resize(size + 1); + mFilterEvent.events[size].media(mediaEvent); + + // Clear and log + output.clear(); + mAvBufferCopyCount = 0; + ::close(av_fd); + if (DEBUG_FILTER) { + ALOGD("[Filter] av data length %d", mediaEvent.dataLength); + } + return Result::SUCCESS; +} + Result Filter::startRecordFilterHandler() { std::lock_guard lock(mRecordFilterOutputLock); if (mRecordFilterOutput.empty()) { diff --git a/tv/tuner/1.0/default/Filter.h b/tv/tuner/1.0/default/Filter.h index 9386dca1a2..9b18a66c07 100644 --- a/tv/tuner/1.0/default/Filter.h +++ b/tv/tuner/1.0/default/Filter.h @@ -84,6 +84,7 @@ class Filter : public IFilter { uint16_t getTpid(); void updateFilterOutput(vector data); void updateRecordOutput(vector data); + void updatePts(uint64_t pts); Result startFilterHandler(); Result startRecordFilterHandler(); void attachFilterToRecord(const sp dvr); @@ -116,6 +117,7 @@ class Filter : public IFilter { bool mIsDataSourceDemux = true; vector mFilterOutput; vector mRecordFilterOutput; + uint64_t mPts = 0; unique_ptr mFilterMQ; bool mIsUsingFMQ = false; EventFlag* mFilterEventFlag; @@ -172,6 +174,7 @@ class Filter : public IFilter { int createAvIonFd(int size); uint8_t* getIonBuffer(int fd, int size); native_handle_t* createNativeHandle(int fd); + Result createMediaFilterEventWithIon(vector output); /** * Lock to protect writes to the FMQs diff --git a/tv/tuner/1.0/vts/functional/FrontendTests.cpp b/tv/tuner/1.0/vts/functional/FrontendTests.cpp index 45951d2b20..b35d11220d 100644 --- a/tv/tuner/1.0/vts/functional/FrontendTests.cpp +++ b/tv/tuner/1.0/vts/functional/FrontendTests.cpp @@ -370,13 +370,11 @@ AssertionResult FrontendTests::tuneFrontend(FrontendConfig config, bool testWith mIsSoftwareFe = config.isSoftwareFe; bool result = true; if (mIsSoftwareFe && testWithDemux) { - DvrConfig dvrConfig; - getSoftwareFrontendPlaybackConfig(dvrConfig); - result &= mDvrTests.openDvrInDemux(dvrConfig.type, dvrConfig.bufferSize) == success(); - result &= mDvrTests.configDvrPlayback(dvrConfig.settings) == success(); + result &= mDvrTests.openDvrInDemux(mDvrConfig.type, mDvrConfig.bufferSize) == success(); + result &= mDvrTests.configDvrPlayback(mDvrConfig.settings) == success(); result &= mDvrTests.getDvrPlaybackMQDescriptor() == success(); - mDvrTests.startPlaybackInputThread(dvrConfig.playbackInputFile, - dvrConfig.settings.playback()); + mDvrTests.startPlaybackInputThread(mDvrConfig.playbackInputFile, + mDvrConfig.settings.playback()); if (!result) { ALOGW("[vts] Software frontend dvr configure failed."); return failure(); diff --git a/tv/tuner/1.0/vts/functional/FrontendTests.h b/tv/tuner/1.0/vts/functional/FrontendTests.h index c536325126..4974ff351e 100644 --- a/tv/tuner/1.0/vts/functional/FrontendTests.h +++ b/tv/tuner/1.0/vts/functional/FrontendTests.h @@ -104,6 +104,7 @@ class FrontendTests { void setService(sp tuner) { mService = tuner; mDvrTests.setService(tuner); + getDefaultSoftwareFrontendPlaybackConfig(mDvrConfig); } AssertionResult getFrontendIds(); @@ -125,12 +126,13 @@ class FrontendTests { void setDvrTests(DvrTests dvrTests) { mDvrTests = dvrTests; } void setDemux(sp demux) { mDvrTests.setDemux(demux); } + void setSoftwareFrontendDvrConfig(DvrConfig conf) { mDvrConfig = conf; } protected: static AssertionResult failure() { return ::testing::AssertionFailure(); } static AssertionResult success() { return ::testing::AssertionSuccess(); } - void getSoftwareFrontendPlaybackConfig(DvrConfig& dvrConfig) { + void getDefaultSoftwareFrontendPlaybackConfig(DvrConfig& dvrConfig) { PlaybackSettings playbackSettings{ .statusMask = 0xf, .lowThreshold = 0x1000, @@ -151,4 +153,5 @@ class FrontendTests { DvrTests mDvrTests; bool mIsSoftwareFe = false; + DvrConfig mDvrConfig; }; diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp index 6819659915..9318bc4d70 100644 --- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp +++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp @@ -486,6 +486,62 @@ TEST_P(TunerBroadcastHidlTest, LnbBroadcastDataFlowVideoFilterTest) { broadcastSingleFilterTest(filterArray[TS_VIDEO0], frontendArray[DVBS]); } +TEST_P(TunerBroadcastHidlTest, BroadcastEsDataFlowMediaFiltersTest) { + description("Test Meida Filters functionality in Broadcast use case with ES input."); + uint32_t feId; + uint32_t demuxId; + sp demux; + uint32_t filterId; + + mFrontendTests.getFrontendIdByType(frontendArray[DVBT].type, feId); + if (feId == INVALID_ID) { + // TODO broadcast test on Cuttlefish needs licensed ts input, + // these tests are runnable on vendor device with real frontend module + // or with manual ts installing and use DVBT frontend. + return; + } + ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); + ASSERT_TRUE(mFrontendTests.setFrontendCallback()); + ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); + ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); + mFrontendTests.setDemux(demux); + mFilterTests.setDemux(demux); + ASSERT_TRUE(mFilterTests.openFilterInDemux(filterArray[TS_AUDIO1].type, + filterArray[TS_AUDIO1].bufferSize)); + ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId)); + ASSERT_TRUE(mFilterTests.configFilter(filterArray[TS_AUDIO1].settings, filterId)); + ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId)); + ASSERT_TRUE(mFilterTests.startFilter(filterId)); + ASSERT_TRUE(mFilterTests.openFilterInDemux(filterArray[TS_VIDEO1].type, + filterArray[TS_VIDEO1].bufferSize)); + ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId)); + ASSERT_TRUE(mFilterTests.configFilter(filterArray[TS_VIDEO1].settings, filterId)); + ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId)); + ASSERT_TRUE(mFilterTests.startFilter(filterId)); + // tune test + PlaybackSettings playbackSettings{ + .statusMask = 0xf, + .lowThreshold = 0x1000, + .highThreshold = 0x07fff, + .dataFormat = DataFormat::ES, + .packetSize = 188, + }; + DvrConfig dvrConfig{ + .type = DvrType::PLAYBACK, + .playbackInputFile = "/data/local/tmp/test.es", + .bufferSize = FMQ_SIZE_4M, + }; + dvrConfig.settings.playback(playbackSettings); + mFrontendTests.setSoftwareFrontendDvrConfig(dvrConfig); + ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendArray[DVBT], true /*testWithDemux*/)); + ASSERT_TRUE(filterDataOutputTest(goldenOutputFiles)); + ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/)); + ASSERT_TRUE(mFilterTests.stopFilter(filterId)); + ASSERT_TRUE(mFilterTests.closeFilter(filterId)); + ASSERT_TRUE(mDemuxTests.closeDemux()); + ASSERT_TRUE(mFrontendTests.closeFrontend()); +} + TEST_P(TunerPlaybackHidlTest, PlaybackDataFlowWithTsSectionFilterTest) { description("Feed ts data from playback and configure Ts section filter to get output"); playbackSingleFilterTest(filterArray[TS_SECTION0], dvrArray[DVR_PLAYBACK0]); diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h index 6c68e3588e..27c65931b8 100644 --- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h +++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h @@ -77,6 +77,7 @@ typedef enum { TS_VIDEO0, TS_VIDEO1, TS_AUDIO0, + TS_AUDIO1, TS_PES0, TS_PCR0, TS_SECTION0, @@ -121,7 +122,6 @@ typedef enum { typedef enum { DVR_RECORD0, DVR_PLAYBACK0, - DVR_SOFTWARE_FE, DVR_MAX, } Dvr; @@ -274,6 +274,11 @@ inline void initFilterConfig() { filterArray[TS_AUDIO0].bufferSize = FMQ_SIZE_16M; filterArray[TS_AUDIO0].settings.ts().tpid = 256; filterArray[TS_AUDIO0].settings.ts().filterSettings.av({.isPassthrough = false}); + filterArray[TS_AUDIO1].type.mainType = DemuxFilterMainType::TS; + filterArray[TS_AUDIO1].type.subType.tsFilterType(DemuxTsFilterType::AUDIO); + filterArray[TS_AUDIO1].bufferSize = FMQ_SIZE_16M; + filterArray[TS_AUDIO1].settings.ts().tpid = 257; + filterArray[TS_AUDIO1].settings.ts().filterSettings.av({.isPassthrough = false}); // TS PES filter setting filterArray[TS_PES0].type.mainType = DemuxFilterMainType::TS; filterArray[TS_PES0].type.subType.tsFilterType(DemuxTsFilterType::PES); @@ -362,17 +367,6 @@ inline void initDvrConfig() { dvrArray[DVR_PLAYBACK0].playbackInputFile = "/data/local/tmp/segment000000.ts"; dvrArray[DVR_PLAYBACK0].bufferSize = FMQ_SIZE_4M; dvrArray[DVR_PLAYBACK0].settings.playback(playbackSettings); - PlaybackSettings softwareFePlaybackSettings{ - .statusMask = 0xf, - .lowThreshold = 0x1000, - .highThreshold = 0x07fff, - .dataFormat = DataFormat::TS, - .packetSize = 188, - }; - dvrArray[DVR_SOFTWARE_FE].type = DvrType::PLAYBACK; - dvrArray[DVR_SOFTWARE_FE].playbackInputFile = "/data/local/tmp/segment000000.ts"; - dvrArray[DVR_SOFTWARE_FE].bufferSize = FMQ_SIZE_4M; - dvrArray[DVR_SOFTWARE_FE].settings.playback(softwareFePlaybackSettings); }; /** Configuration array for the descrambler test */ -- GitLab From 4585601fb36b6ea5e1342bc9a68d229e97d8e0a3 Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Tue, 23 Jun 2020 01:20:24 -0700 Subject: [PATCH 054/790] Define biometrics.fingerprint@2.3 This HIDL introduces onFingerDown and onFingerUp methods. Bug: 158135499 Test: build Change-Id: If2bfd70ee518b3f980ed2dc36a2df2a1ccf3afce --- biometrics/fingerprint/2.3/Android.bp | 18 ++++++ .../2.3/IBiometricsFingerprint.hal | 43 ++++++++++++++ .../fingerprint/2.3/vts/functional/Android.bp | 30 ++++++++++ ...HalBiometricsFingerprintV2_3TargetTest.cpp | 59 +++++++++++++++++++ 4 files changed, 150 insertions(+) create mode 100644 biometrics/fingerprint/2.3/Android.bp create mode 100644 biometrics/fingerprint/2.3/IBiometricsFingerprint.hal create mode 100644 biometrics/fingerprint/2.3/vts/functional/Android.bp create mode 100644 biometrics/fingerprint/2.3/vts/functional/VtsHalBiometricsFingerprintV2_3TargetTest.cpp diff --git a/biometrics/fingerprint/2.3/Android.bp b/biometrics/fingerprint/2.3/Android.bp new file mode 100644 index 0000000000..57ab83230d --- /dev/null +++ b/biometrics/fingerprint/2.3/Android.bp @@ -0,0 +1,18 @@ +// This file is autogenerated by hidl-gen -Landroidbp. + +hidl_interface { + name: "android.hardware.biometrics.fingerprint@2.3", + root: "android.hardware", + vndk: { + enabled: true, + }, + srcs: [ + "IBiometricsFingerprint.hal", + ], + interfaces: [ + "android.hardware.biometrics.fingerprint@2.1", + "android.hardware.biometrics.fingerprint@2.2", + "android.hidl.base@1.0", + ], + gen_java: true, +} diff --git a/biometrics/fingerprint/2.3/IBiometricsFingerprint.hal b/biometrics/fingerprint/2.3/IBiometricsFingerprint.hal new file mode 100644 index 0000000000..8777c28e3a --- /dev/null +++ b/biometrics/fingerprint/2.3/IBiometricsFingerprint.hal @@ -0,0 +1,43 @@ +/* + * 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. + */ + +package android.hardware.biometrics.fingerprint@2.3; + +import @2.2::IBiometricsFingerprint; + +/** + * The interface for biometric fingerprint authentication. + */ +interface IBiometricsFingerprint extends @2.2::IBiometricsFingerprint { + /** + * Notifies about a finger touching the sensor area. + * + * @param x The screen x-coordinate of the center of the touch contact area, in + * display pixels. + * @param y The screen y-coordinate of the center of the touch contact area, in + * display pixels. + * @param minor The length of the minor axis of an ellipse that describes the + * touch area, in display pixels. + * @param major The length of the major axis of an ellipse that describes the + * touch area, in display pixels. + */ + oneway onFingerDown(uint32_t x, uint32_t y, float minor, float major); + + /** + * Notifies about a finger leaving the sensor area. + */ + oneway onFingerUp(); +}; diff --git a/biometrics/fingerprint/2.3/vts/functional/Android.bp b/biometrics/fingerprint/2.3/vts/functional/Android.bp new file mode 100644 index 0000000000..521c0f41fd --- /dev/null +++ b/biometrics/fingerprint/2.3/vts/functional/Android.bp @@ -0,0 +1,30 @@ +/* + * 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. + */ + +cc_test { + name: "VtsHalBiometricsFingerprintV2_3TargetTest", + defaults: ["VtsHalTargetTestDefaults"], + srcs: ["VtsHalBiometricsFingerprintV2_3TargetTest.cpp"], + static_libs: [ + "android.hardware.biometrics.fingerprint@2.1", + "android.hardware.biometrics.fingerprint@2.2", + "android.hardware.biometrics.fingerprint@2.3", + ], + test_suites: [ + "general-tests", + "vts", + ], +} diff --git a/biometrics/fingerprint/2.3/vts/functional/VtsHalBiometricsFingerprintV2_3TargetTest.cpp b/biometrics/fingerprint/2.3/vts/functional/VtsHalBiometricsFingerprintV2_3TargetTest.cpp new file mode 100644 index 0000000000..722621379d --- /dev/null +++ b/biometrics/fingerprint/2.3/vts/functional/VtsHalBiometricsFingerprintV2_3TargetTest.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +namespace { + +namespace hidl_interface_2_3 = android::hardware::biometrics::fingerprint::V2_3; + +using hidl_interface_2_3::IBiometricsFingerprint; + +using android::sp; + +// Callback arguments that need to be captured for the tests. +struct FingerprintCallbackArgs {}; + +class FingerprintHidlTest : public ::testing::TestWithParam { + public: + void SetUp() override { + mService = IBiometricsFingerprint::getService(GetParam()); + ASSERT_NE(mService, nullptr); + } + + sp mService; +}; + +// This is a one-way method that doesn't return anything. +TEST_P(FingerprintHidlTest, onFingerDownTest) { + mService->onFingerDown(1, 2, 3.0f, 4.0f); +} + +// This is a one-way method that doesn't return anything. +TEST_P(FingerprintHidlTest, onFingerUp) { + mService->onFingerUp(); +} + +} // anonymous namespace + +INSTANTIATE_TEST_SUITE_P(PerInstance, FingerprintHidlTest, + testing::ValuesIn(android::hardware::getAllHalInstanceNames( + IBiometricsFingerprint::descriptor)), + android::hardware::PrintInstanceNameToString); -- GitLab From 91c3a0479299896a7ac0905e6d680b7aaa1d10b7 Mon Sep 17 00:00:00 2001 From: Tomasz Wasilczyk Date: Wed, 24 Jun 2020 15:30:10 -0700 Subject: [PATCH 055/790] Implement fetching hardware address Bug: 159327274 Test: manual Change-Id: Ic3c7d757141da498f7d86ffabadac21a2372f443 --- .../include/libnetdevice/libnetdevice.h | 15 +++++++++++++++ .../can/1.0/default/libnetdevice/libnetdevice.cpp | 14 ++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/libnetdevice.h b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/libnetdevice.h index 54cbafcc0d..c8e6f75426 100644 --- a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/libnetdevice.h +++ b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/libnetdevice.h @@ -16,11 +16,16 @@ #pragma once +#include + +#include #include #include namespace android::netdevice { +typedef std::array hwaddr_t; + /** * Configures libnetdevice to use PF_CAN sockets instead of AF_INET, * what requires less permissive SEPolicy rules for a given process. @@ -91,4 +96,14 @@ bool add(std::string dev, std::string type); */ bool del(std::string dev); +/** + * Fetches interface's hardware address. + * + * \param ifname Interface name + * \return Hardware address (MAC address) or nullopt if the lookup failed + */ +std::optional getHwAddr(const std::string& ifname); + } // namespace android::netdevice + +bool operator==(const android::netdevice::hwaddr_t lhs, const unsigned char rhs[ETH_ALEN]); diff --git a/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp b/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp index 73b91d0ee6..a16dd3436d 100644 --- a/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp +++ b/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp @@ -81,4 +81,18 @@ bool del(std::string dev) { return sock.send(req) && sock.receiveAck(); } +std::optional getHwAddr(const std::string& ifname) { + auto ifr = ifreqs::fromName(ifname); + if (!ifreqs::send(SIOCGIFHWADDR, ifr)) return std::nullopt; + + hwaddr_t hwaddr; + memcpy(hwaddr.data(), ifr.ifr_hwaddr.sa_data, hwaddr.size()); + return hwaddr; +} + } // namespace android::netdevice + +bool operator==(const android::netdevice::hwaddr_t lhs, const unsigned char rhs[ETH_ALEN]) { + static_assert(lhs.size() == ETH_ALEN); + return 0 == memcmp(lhs.data(), rhs, lhs.size()); +} -- GitLab From caeae195a705c9a62d49b7b8eada214af19c7781 Mon Sep 17 00:00:00 2001 From: Tomasz Wasilczyk Date: Thu, 25 Jun 2020 13:36:48 -0700 Subject: [PATCH 056/790] Implement setting hardware address Bug: 156784343 Test: manual Change-Id: I6a533ab15bb93db26261f826bb8e7d8f12824d62 --- .../libnetdevice/include/libnetdevice/libnetdevice.h | 8 ++++++++ .../can/1.0/default/libnetdevice/libnetdevice.cpp | 10 ++++++++++ 2 files changed, 18 insertions(+) diff --git a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/libnetdevice.h b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/libnetdevice.h index c8e6f75426..037618a2e6 100644 --- a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/libnetdevice.h +++ b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/libnetdevice.h @@ -104,6 +104,14 @@ bool del(std::string dev); */ std::optional getHwAddr(const std::string& ifname); +/** + * Changes interface's hardware address. + * + * \param ifname Interface name + * \param hwaddr New hardware address to set + */ +bool setHwAddr(const std::string& ifname, hwaddr_t hwaddr); + } // namespace android::netdevice bool operator==(const android::netdevice::hwaddr_t lhs, const unsigned char rhs[ETH_ALEN]); diff --git a/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp b/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp index a16dd3436d..efbd0bbd78 100644 --- a/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp +++ b/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp @@ -90,6 +90,16 @@ std::optional getHwAddr(const std::string& ifname) { return hwaddr; } +bool setHwAddr(const std::string& ifname, hwaddr_t hwaddr) { + auto ifr = ifreqs::fromName(ifname); + + // fetch sa_family + if (!ifreqs::send(SIOCGIFHWADDR, ifr)) return false; + + memcpy(ifr.ifr_hwaddr.sa_data, hwaddr.data(), hwaddr.size()); + return ifreqs::send(SIOCSIFHWADDR, ifr); +} + } // namespace android::netdevice bool operator==(const android::netdevice::hwaddr_t lhs, const unsigned char rhs[ETH_ALEN]) { -- GitLab From 3fb244a56ff72fbd3fb11e4d4202dffd0b466321 Mon Sep 17 00:00:00 2001 From: chrisweir Date: Mon, 29 Jun 2020 13:05:17 -0700 Subject: [PATCH 057/790] Make NetlinkSocket and nlbuf exported Move NetlinkSocket.h and nlbuf.h to include/libnetdevice as to make them available for include. Bug: 160171644 Test: Manual Change-Id: If54852398cfbcc53eb830a66685c6b44e36ced87 --- automotive/can/1.0/default/libnetdevice/NetlinkRequest.cpp | 2 +- automotive/can/1.0/default/libnetdevice/NetlinkSocket.cpp | 2 +- automotive/can/1.0/default/libnetdevice/can.cpp | 4 ++-- automotive/can/1.0/default/libnetdevice/common.h | 2 +- .../libnetdevice/{ => include/libnetdevice}/NetlinkRequest.h | 0 .../libnetdevice/{ => include/libnetdevice}/NetlinkSocket.h | 3 +-- .../default/libnetdevice/{ => include/libnetdevice}/nlbuf.h | 0 automotive/can/1.0/default/libnetdevice/libnetdevice.cpp | 4 ++-- automotive/can/1.0/default/libnetdevice/printer.cpp | 2 +- .../1.0/default/libnetdevice/protocols/MessageDefinition.h | 3 ++- automotive/can/1.0/default/libnetdevice/vlan.cpp | 4 ++-- 11 files changed, 13 insertions(+), 13 deletions(-) rename automotive/can/1.0/default/libnetdevice/{ => include/libnetdevice}/NetlinkRequest.h (100%) rename automotive/can/1.0/default/libnetdevice/{ => include/libnetdevice}/NetlinkSocket.h (97%) rename automotive/can/1.0/default/libnetdevice/{ => include/libnetdevice}/nlbuf.h (100%) diff --git a/automotive/can/1.0/default/libnetdevice/NetlinkRequest.cpp b/automotive/can/1.0/default/libnetdevice/NetlinkRequest.cpp index 556debfc09..4c06f7cdb4 100644 --- a/automotive/can/1.0/default/libnetdevice/NetlinkRequest.cpp +++ b/automotive/can/1.0/default/libnetdevice/NetlinkRequest.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "NetlinkRequest.h" +#include #include diff --git a/automotive/can/1.0/default/libnetdevice/NetlinkSocket.cpp b/automotive/can/1.0/default/libnetdevice/NetlinkSocket.cpp index 15c0f9b6dd..6146d5e4a4 100644 --- a/automotive/can/1.0/default/libnetdevice/NetlinkSocket.cpp +++ b/automotive/can/1.0/default/libnetdevice/NetlinkSocket.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "NetlinkSocket.h" +#include #include diff --git a/automotive/can/1.0/default/libnetdevice/can.cpp b/automotive/can/1.0/default/libnetdevice/can.cpp index 06fa8aadd2..b0a243244d 100644 --- a/automotive/can/1.0/default/libnetdevice/can.cpp +++ b/automotive/can/1.0/default/libnetdevice/can.cpp @@ -16,12 +16,12 @@ #include -#include "NetlinkRequest.h" -#include "NetlinkSocket.h" #include "common.h" #include #include +#include +#include #include #include diff --git a/automotive/can/1.0/default/libnetdevice/common.h b/automotive/can/1.0/default/libnetdevice/common.h index 1e04d4147f..b4f91bd1bb 100644 --- a/automotive/can/1.0/default/libnetdevice/common.h +++ b/automotive/can/1.0/default/libnetdevice/common.h @@ -16,7 +16,7 @@ #pragma once -#include "nlbuf.h" +#include #include #include diff --git a/automotive/can/1.0/default/libnetdevice/NetlinkRequest.h b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/NetlinkRequest.h similarity index 100% rename from automotive/can/1.0/default/libnetdevice/NetlinkRequest.h rename to automotive/can/1.0/default/libnetdevice/include/libnetdevice/NetlinkRequest.h diff --git a/automotive/can/1.0/default/libnetdevice/NetlinkSocket.h b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/NetlinkSocket.h similarity index 97% rename from automotive/can/1.0/default/libnetdevice/NetlinkSocket.h rename to automotive/can/1.0/default/libnetdevice/include/libnetdevice/NetlinkSocket.h index 595c31acf6..8900ff776f 100644 --- a/automotive/can/1.0/default/libnetdevice/NetlinkSocket.h +++ b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/NetlinkSocket.h @@ -16,10 +16,9 @@ #pragma once -#include "NetlinkRequest.h" - #include #include +#include #include diff --git a/automotive/can/1.0/default/libnetdevice/nlbuf.h b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/nlbuf.h similarity index 100% rename from automotive/can/1.0/default/libnetdevice/nlbuf.h rename to automotive/can/1.0/default/libnetdevice/include/libnetdevice/nlbuf.h diff --git a/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp b/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp index 73b91d0ee6..0545ebfa98 100644 --- a/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp +++ b/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp @@ -16,12 +16,12 @@ #include -#include "NetlinkRequest.h" -#include "NetlinkSocket.h" #include "common.h" #include "ifreqs.h" #include +#include +#include #include #include diff --git a/automotive/can/1.0/default/libnetdevice/printer.cpp b/automotive/can/1.0/default/libnetdevice/printer.cpp index 8e17e7f6ad..a8715da188 100644 --- a/automotive/can/1.0/default/libnetdevice/printer.cpp +++ b/automotive/can/1.0/default/libnetdevice/printer.cpp @@ -17,10 +17,10 @@ #include #include "common.h" -#include "nlbuf.h" #include "protocols/all.h" #include +#include #include #include diff --git a/automotive/can/1.0/default/libnetdevice/protocols/MessageDefinition.h b/automotive/can/1.0/default/libnetdevice/protocols/MessageDefinition.h index 9764f8d17e..00fce8c0a4 100644 --- a/automotive/can/1.0/default/libnetdevice/protocols/MessageDefinition.h +++ b/automotive/can/1.0/default/libnetdevice/protocols/MessageDefinition.h @@ -16,9 +16,10 @@ #pragma once -#include "nlbuf.h" #include "types.h" +#include + #include #include diff --git a/automotive/can/1.0/default/libnetdevice/vlan.cpp b/automotive/can/1.0/default/libnetdevice/vlan.cpp index 82ef0d9239..f0caacdb75 100644 --- a/automotive/can/1.0/default/libnetdevice/vlan.cpp +++ b/automotive/can/1.0/default/libnetdevice/vlan.cpp @@ -16,11 +16,11 @@ #include -#include "NetlinkRequest.h" -#include "NetlinkSocket.h" #include "common.h" #include +#include +#include namespace android::netdevice::vlan { -- GitLab From 134ace098a52d93c62a1651b4f2918816f611bc2 Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Fri, 26 Jun 2020 10:47:46 -0700 Subject: [PATCH 058/790] Add isUdfps method to biometrics.fingerprint@2.3 Bug: 158135499 Test: atest VtsHalBiometricsFingerprintV2_3TargetTest Change-Id: I10a75f8362f2596709399a45555bf9f09451f962 --- .../2.3/IBiometricsFingerprint.hal | 57 +++++++++++++------ ...HalBiometricsFingerprintV2_3TargetTest.cpp | 17 ++++-- 2 files changed, 53 insertions(+), 21 deletions(-) diff --git a/biometrics/fingerprint/2.3/IBiometricsFingerprint.hal b/biometrics/fingerprint/2.3/IBiometricsFingerprint.hal index 8777c28e3a..13f03c5eea 100644 --- a/biometrics/fingerprint/2.3/IBiometricsFingerprint.hal +++ b/biometrics/fingerprint/2.3/IBiometricsFingerprint.hal @@ -22,22 +22,45 @@ import @2.2::IBiometricsFingerprint; * The interface for biometric fingerprint authentication. */ interface IBiometricsFingerprint extends @2.2::IBiometricsFingerprint { - /** - * Notifies about a finger touching the sensor area. - * - * @param x The screen x-coordinate of the center of the touch contact area, in - * display pixels. - * @param y The screen y-coordinate of the center of the touch contact area, in - * display pixels. - * @param minor The length of the minor axis of an ellipse that describes the - * touch area, in display pixels. - * @param major The length of the major axis of an ellipse that describes the - * touch area, in display pixels. - */ - oneway onFingerDown(uint32_t x, uint32_t y, float minor, float major); + /** + * Returns whether the fingerprint sensor is an under-display fingerprint + * sensor. + * @param sensorId the unique sensor ID for which the operation should be + * performed. + * @return isUdfps indicating whether the specified sensor is an + * under-display fingerprint sensor. + */ + isUdfps(uint32_t sensorId) generates (bool isUdfps); - /** - * Notifies about a finger leaving the sensor area. - */ - oneway onFingerUp(); + /** + * Notifies about a touch occurring within the under-display fingerprint + * sensor area. + * + * It it assumed that the device can only have one active under-display + * fingerprint sensor at a time. + * + * If multiple fingers are detected within the sensor area, only the + * chronologically first event will be reported. + * + * @param x The screen x-coordinate of the center of the touch contact area, in + * display pixels. + * @param y The screen y-coordinate of the center of the touch contact area, in + * display pixels. + * @param minor The length of the minor axis of an ellipse that describes the + * touch area, in display pixels. + * @param major The length of the major axis of an ellipse that describes the + * touch area, in display pixels. + */ + onFingerDown(uint32_t x, uint32_t y, float minor, float major); + + /** + * Notifies about a finger leaving the under-display fingerprint sensor area. + * + * It it assumed that the device can only have one active under-display + * fingerprint sensor at a time. + * + * If multiple fingers have left the sensor area, only the finger which + * previously caused a "finger down" event will be reported. + */ + onFingerUp(); }; diff --git a/biometrics/fingerprint/2.3/vts/functional/VtsHalBiometricsFingerprintV2_3TargetTest.cpp b/biometrics/fingerprint/2.3/vts/functional/VtsHalBiometricsFingerprintV2_3TargetTest.cpp index 722621379d..72420162f0 100644 --- a/biometrics/fingerprint/2.3/vts/functional/VtsHalBiometricsFingerprintV2_3TargetTest.cpp +++ b/biometrics/fingerprint/2.3/vts/functional/VtsHalBiometricsFingerprintV2_3TargetTest.cpp @@ -14,6 +14,8 @@ * limitations under the License. */ +#define ASSERT_OK(v) ASSERT_TRUE(v.isOk()) + #include #include #include @@ -41,14 +43,21 @@ class FingerprintHidlTest : public ::testing::TestWithParam { sp mService; }; -// This is a one-way method that doesn't return anything. +// This method returns true or false depending on the implementation. +TEST_P(FingerprintHidlTest, isUdfpsTest) { + // Arbitrary ID + uint32_t sensorId = 1234; + ASSERT_OK(mService->isUdfps(sensorId)); +} + +// This method that doesn't return anything. TEST_P(FingerprintHidlTest, onFingerDownTest) { - mService->onFingerDown(1, 2, 3.0f, 4.0f); + ASSERT_OK(mService->onFingerDown(1, 2, 3.0f, 4.0f)); } -// This is a one-way method that doesn't return anything. +// This method that doesn't return anything. TEST_P(FingerprintHidlTest, onFingerUp) { - mService->onFingerUp(); + ASSERT_OK(mService->onFingerUp()); } } // anonymous namespace -- GitLab From e56f9e18a6b4da753060c6c5d4d61b6cb1ef8d0b Mon Sep 17 00:00:00 2001 From: chrisweir Date: Tue, 30 Jun 2020 16:20:30 -0700 Subject: [PATCH 059/790] Export libnetdevice headers The previous change to do this missed a couple includes. Simply compiling doesn't catch header problems unless the headers are actually used. Bug: 160171644 Test: Manual Change-Id: I9edc76b47e934b60a143ebfacdeaeeddc0768fc5 --- .../libnetdevice/include/libnetdevice/NetlinkRequest.h | 4 ++-- .../default/libnetdevice/{ => include/libnetdevice}/types.h | 0 .../1.0/default/libnetdevice/protocols/MessageDefinition.h | 3 +-- .../can/1.0/default/libnetdevice/protocols/NetlinkProtocol.h | 3 ++- 4 files changed, 5 insertions(+), 5 deletions(-) rename automotive/can/1.0/default/libnetdevice/{ => include/libnetdevice}/types.h (100%) diff --git a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/NetlinkRequest.h b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/NetlinkRequest.h index 5bea3335f1..c19d04d874 100644 --- a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/NetlinkRequest.h +++ b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/NetlinkRequest.h @@ -16,9 +16,9 @@ #pragma once -#include "types.h" - #include +#include + #include #include diff --git a/automotive/can/1.0/default/libnetdevice/types.h b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/types.h similarity index 100% rename from automotive/can/1.0/default/libnetdevice/types.h rename to automotive/can/1.0/default/libnetdevice/include/libnetdevice/types.h diff --git a/automotive/can/1.0/default/libnetdevice/protocols/MessageDefinition.h b/automotive/can/1.0/default/libnetdevice/protocols/MessageDefinition.h index 00fce8c0a4..a25e885660 100644 --- a/automotive/can/1.0/default/libnetdevice/protocols/MessageDefinition.h +++ b/automotive/can/1.0/default/libnetdevice/protocols/MessageDefinition.h @@ -16,9 +16,8 @@ #pragma once -#include "types.h" - #include +#include #include #include diff --git a/automotive/can/1.0/default/libnetdevice/protocols/NetlinkProtocol.h b/automotive/can/1.0/default/libnetdevice/protocols/NetlinkProtocol.h index 0e1878d74d..7b12efaa2c 100644 --- a/automotive/can/1.0/default/libnetdevice/protocols/NetlinkProtocol.h +++ b/automotive/can/1.0/default/libnetdevice/protocols/NetlinkProtocol.h @@ -19,7 +19,8 @@ #include "MessageDefinition.h" #include "common/Empty.h" #include "common/Error.h" -#include "types.h" + +#include #include #include -- GitLab From 1accab968152999f0bdcb00c3edbc3bf4a712adf Mon Sep 17 00:00:00 2001 From: Tomasz Wasilczyk Date: Wed, 1 Jul 2020 08:08:43 -0700 Subject: [PATCH 060/790] Use PLOG instead of printing errno Also, print error message where the error code is available through other means than errno. Test: it builds Change-Id: I0276c4bcd50debc0003aab4e3229ea33ac79f3ac --- automotive/can/1.0/default/libnetdevice/NetlinkSocket.cpp | 2 +- automotive/can/1.0/default/libnetdevice/common.cpp | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/automotive/can/1.0/default/libnetdevice/NetlinkSocket.cpp b/automotive/can/1.0/default/libnetdevice/NetlinkSocket.cpp index 15c0f9b6dd..86442f2eec 100644 --- a/automotive/can/1.0/default/libnetdevice/NetlinkSocket.cpp +++ b/automotive/can/1.0/default/libnetdevice/NetlinkSocket.cpp @@ -118,7 +118,7 @@ bool NetlinkSocket::receiveAck() { // Found error/ack message, return status. auto nlerr = reinterpret_cast(NLMSG_DATA(nlmsg)); if (nlerr->error != 0) { - LOG(ERROR) << "Received Netlink error message: " << nlerr->error; + LOG(ERROR) << "Received Netlink error message: " << strerror(-nlerr->error); return false; } return true; diff --git a/automotive/can/1.0/default/libnetdevice/common.cpp b/automotive/can/1.0/default/libnetdevice/common.cpp index 103cf5378c..387c91f81a 100644 --- a/automotive/can/1.0/default/libnetdevice/common.cpp +++ b/automotive/can/1.0/default/libnetdevice/common.cpp @@ -28,9 +28,8 @@ unsigned int nametoindex(const std::string& ifname) { const auto ifidx = if_nametoindex(ifname.c_str()); if (ifidx != 0) return ifidx; - const auto err = errno; - if (err != ENODEV) { - LOG(ERROR) << "if_nametoindex(" << ifname << ") failed: " << err; + if (errno != ENODEV) { + PLOG(ERROR) << "if_nametoindex(" << ifname << ") failed"; } return 0; } -- GitLab From b0907a6bb86e6ab67e181ac2477da8d827233d1f Mon Sep 17 00:00:00 2001 From: Jooyung Han Date: Wed, 1 Jul 2020 12:16:13 +0900 Subject: [PATCH 061/790] update hidl .bp HIDL libs are not necessarily part of VNDK now. Because some are used by VNDK libs, they are still VNDK. But rest are now just vendor-available. .hidl_for_test files are also removed because they are used to exclude test-purpose hidl libs from VNDK libs. Instead, .hidl_for_system_ext files are added to tests/lazy to distinguish them from others which are installed /system. Bug: 143933769 Test: update-makefiles.sh && m com.android.vndk.current Change-Id: Ia81312dda340b6b5cbdd7a3c21e1d323bda39a4a --- atrace/1.0/Android.bp | 3 --- audio/2.0/Android.bp | 3 --- audio/4.0/Android.bp | 3 --- audio/5.0/Android.bp | 3 --- audio/6.0/Android.bp | 3 --- audio/common/4.0/Android.bp | 3 --- audio/common/5.0/Android.bp | 3 --- audio/common/6.0/Android.bp | 3 --- audio/effect/2.0/Android.bp | 3 --- audio/effect/4.0/Android.bp | 3 --- audio/effect/5.0/Android.bp | 3 --- audio/effect/6.0/Android.bp | 3 --- authsecret/1.0/Android.bp | 3 --- automotive/audiocontrol/1.0/Android.bp | 3 --- automotive/audiocontrol/2.0/Android.bp | 6 ++---- automotive/can/1.0/Android.bp | 3 --- automotive/evs/1.0/Android.bp | 3 --- automotive/evs/1.1/Android.bp | 3 --- automotive/sv/1.0/Android.bp | 9 +++------ automotive/vehicle/2.0/Android.bp | 3 --- biometrics/face/1.0/Android.bp | 3 --- biometrics/face/1.1/Android.bp | 3 --- biometrics/fingerprint/2.1/Android.bp | 3 --- biometrics/fingerprint/2.2/Android.bp | 3 --- biometrics/fingerprint/2.3/Android.bp | 3 --- bluetooth/1.0/Android.bp | 3 --- bluetooth/1.1/Android.bp | 3 --- bluetooth/a2dp/1.0/Android.bp | 3 --- bluetooth/audio/2.0/Android.bp | 3 --- boot/1.0/Android.bp | 3 --- boot/1.1/Android.bp | 3 --- broadcastradio/1.0/Android.bp | 3 --- broadcastradio/1.1/Android.bp | 3 --- broadcastradio/2.0/Android.bp | 3 --- camera/common/1.0/Android.bp | 3 --- camera/device/1.0/Android.bp | 3 --- camera/device/3.2/Android.bp | 3 --- camera/device/3.3/Android.bp | 3 --- camera/device/3.4/Android.bp | 3 --- camera/device/3.5/Android.bp | 3 --- camera/device/3.6/Android.bp | 3 --- camera/metadata/3.2/Android.bp | 3 --- camera/metadata/3.3/Android.bp | 3 --- camera/metadata/3.4/Android.bp | 3 --- camera/metadata/3.5/Android.bp | 3 --- camera/provider/2.4/Android.bp | 3 --- camera/provider/2.5/Android.bp | 3 --- camera/provider/2.6/Android.bp | 3 --- cas/1.0/Android.bp | 3 --- cas/1.1/Android.bp | 3 --- cas/1.2/Android.bp | 3 --- cas/native/1.0/Android.bp | 3 --- confirmationui/1.0/Android.bp | 3 --- contexthub/1.0/Android.bp | 3 --- contexthub/1.1/Android.bp | 3 --- drm/1.0/Android.bp | 3 --- drm/1.1/Android.bp | 3 --- drm/1.2/Android.bp | 3 --- drm/1.3/Android.bp | 5 +---- dumpstate/1.0/Android.bp | 3 --- dumpstate/1.1/Android.bp | 3 --- fastboot/1.0/Android.bp | 3 --- gatekeeper/1.0/Android.bp | 3 --- gnss/1.0/Android.bp | 3 --- gnss/1.1/Android.bp | 3 --- gnss/2.0/Android.bp | 3 --- gnss/2.1/Android.bp | 3 --- gnss/3.0/Android.bp | 3 --- gnss/measurement_corrections/1.0/Android.bp | 3 --- gnss/measurement_corrections/1.1/Android.bp | 3 --- gnss/visibility_control/1.0/Android.bp | 3 --- graphics/composer/2.1/Android.bp | 3 --- graphics/composer/2.2/Android.bp | 3 --- graphics/composer/2.3/Android.bp | 3 --- graphics/composer/2.4/Android.bp | 3 --- health/1.0/Android.bp | 3 --- health/2.0/Android.bp | 3 --- health/2.1/Android.bp | 3 --- health/storage/1.0/Android.bp | 3 --- input/classifier/1.0/Android.bp | 3 --- input/common/1.0/Android.bp | 3 --- ir/1.0/Android.bp | 3 --- keymaster/3.0/Android.bp | 3 --- keymaster/4.0/Android.bp | 3 --- keymaster/4.1/Android.bp | 3 --- light/2.0/Android.bp | 3 --- media/bufferpool/1.0/Android.bp | 3 --- media/c2/1.0/Android.bp | 3 --- media/c2/1.1/Android.bp | 3 --- neuralnetworks/1.0/Android.bp | 3 --- neuralnetworks/1.1/Android.bp | 3 --- neuralnetworks/1.2/Android.bp | 3 --- neuralnetworks/1.3/Android.bp | 3 --- nfc/1.0/Android.bp | 3 --- nfc/1.1/Android.bp | 3 --- nfc/1.2/Android.bp | 3 --- oemlock/1.0/Android.bp | 3 --- power/1.0/Android.bp | 3 --- power/1.1/Android.bp | 3 --- power/1.2/Android.bp | 3 --- power/1.3/Android.bp | 3 --- power/stats/1.0/Android.bp | 3 --- radio/1.0/Android.bp | 3 --- radio/1.1/Android.bp | 3 --- radio/1.2/Android.bp | 3 --- radio/1.3/Android.bp | 3 --- radio/1.4/Android.bp | 3 --- radio/1.5/Android.bp | 3 --- radio/config/1.0/Android.bp | 3 --- radio/config/1.1/Android.bp | 3 --- radio/config/1.2/Android.bp | 3 --- radio/deprecated/1.0/Android.bp | 3 --- secure_element/1.0/Android.bp | 3 --- secure_element/1.1/Android.bp | 3 --- secure_element/1.2/Android.bp | 3 --- sensors/1.0/Android.bp | 3 --- sensors/2.0/Android.bp | 3 --- sensors/2.1/Android.bp | 3 --- soundtrigger/2.1/Android.bp | 3 --- soundtrigger/2.2/Android.bp | 3 --- soundtrigger/2.3/Android.bp | 3 --- tests/expression/1.0/.hidl_for_test | 0 tests/extension/light/2.0/.hidl_for_test | 0 tests/foo/1.0/.hidl_for_test | 0 tests/hash/1.0/.hidl_for_test | 0 tests/inheritance/1.0/.hidl_for_test | 0 .../1.0/.hidl_for_test => lazy/1.0/.hidl_for_system_ext} | 0 tests/lazy/1.0/.hidl_for_test | 0 .../1.0/.hidl_for_test => lazy/1.1/.hidl_for_system_ext} | 0 tests/lazy/1.1/.hidl_for_test | 0 tests/libhwbinder/1.0/.hidl_for_test | 0 tests/libhwbinder/aidl/.hidl_for_test | 0 tests/memory/1.0/.hidl_for_test | 0 tests/memory/2.0/.hidl_for_test | 0 tests/msgq/1.0/.hidl_for_test | 0 tests/multithread/1.0/.hidl_for_test | 0 tests/safeunion/1.0/.hidl_for_test | 0 tests/safeunion/cpp/1.0/.hidl_for_test | 0 tests/trie/1.0/.hidl_for_test | 0 tetheroffload/config/1.0/Android.bp | 3 --- tetheroffload/control/1.0/Android.bp | 3 --- thermal/1.0/Android.bp | 3 --- thermal/1.1/Android.bp | 3 --- thermal/2.0/Android.bp | 3 --- tv/cec/1.0/Android.bp | 3 --- tv/cec/2.0/Android.bp | 3 --- tv/input/1.0/Android.bp | 3 --- tv/tuner/1.0/Android.bp | 3 --- usb/1.0/Android.bp | 3 --- usb/1.1/Android.bp | 3 --- usb/1.2/Android.bp | 3 --- usb/gadget/1.0/Android.bp | 3 --- usb/gadget/1.1/Android.bp | 3 --- vibrator/1.0/Android.bp | 3 --- vibrator/1.1/Android.bp | 3 --- vibrator/1.2/Android.bp | 3 --- vibrator/1.3/Android.bp | 3 --- vr/1.0/Android.bp | 3 --- weaver/1.0/Android.bp | 3 --- wifi/1.0/Android.bp | 3 --- wifi/1.1/Android.bp | 3 --- wifi/1.2/Android.bp | 3 --- wifi/1.3/Android.bp | 3 --- wifi/1.4/Android.bp | 3 --- wifi/hostapd/1.0/Android.bp | 3 --- wifi/hostapd/1.1/Android.bp | 3 --- wifi/hostapd/1.2/Android.bp | 3 --- wifi/offload/1.0/Android.bp | 3 --- wifi/supplicant/1.0/Android.bp | 3 --- wifi/supplicant/1.1/Android.bp | 3 --- wifi/supplicant/1.2/Android.bp | 3 --- wifi/supplicant/1.3/Android.bp | 3 --- 172 files changed, 6 insertions(+), 467 deletions(-) delete mode 100644 tests/expression/1.0/.hidl_for_test delete mode 100644 tests/extension/light/2.0/.hidl_for_test delete mode 100644 tests/foo/1.0/.hidl_for_test delete mode 100644 tests/hash/1.0/.hidl_for_test delete mode 100644 tests/inheritance/1.0/.hidl_for_test rename tests/{bar/1.0/.hidl_for_test => lazy/1.0/.hidl_for_system_ext} (100%) delete mode 100644 tests/lazy/1.0/.hidl_for_test rename tests/{baz/1.0/.hidl_for_test => lazy/1.1/.hidl_for_system_ext} (100%) delete mode 100644 tests/lazy/1.1/.hidl_for_test delete mode 100644 tests/libhwbinder/1.0/.hidl_for_test delete mode 100644 tests/libhwbinder/aidl/.hidl_for_test delete mode 100644 tests/memory/1.0/.hidl_for_test delete mode 100644 tests/memory/2.0/.hidl_for_test delete mode 100644 tests/msgq/1.0/.hidl_for_test delete mode 100644 tests/multithread/1.0/.hidl_for_test delete mode 100644 tests/safeunion/1.0/.hidl_for_test delete mode 100644 tests/safeunion/cpp/1.0/.hidl_for_test delete mode 100644 tests/trie/1.0/.hidl_for_test diff --git a/atrace/1.0/Android.bp b/atrace/1.0/Android.bp index c7e8d04eeb..5290a9a486 100644 --- a/atrace/1.0/Android.bp +++ b/atrace/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.atrace@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IAtraceDevice.hal", diff --git a/audio/2.0/Android.bp b/audio/2.0/Android.bp index 02f8b4087c..35f6803e30 100644 --- a/audio/2.0/Android.bp +++ b/audio/2.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.audio@2.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IDevice.hal", diff --git a/audio/4.0/Android.bp b/audio/4.0/Android.bp index 862c71117c..dfc304760e 100644 --- a/audio/4.0/Android.bp +++ b/audio/4.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.audio@4.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IDevice.hal", diff --git a/audio/5.0/Android.bp b/audio/5.0/Android.bp index 9b28497472..365a654610 100644 --- a/audio/5.0/Android.bp +++ b/audio/5.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.audio@5.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IDevice.hal", diff --git a/audio/6.0/Android.bp b/audio/6.0/Android.bp index 16abc521e2..d7880b631d 100644 --- a/audio/6.0/Android.bp +++ b/audio/6.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.audio@6.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IDevice.hal", diff --git a/audio/common/4.0/Android.bp b/audio/common/4.0/Android.bp index c01c486829..1b0a624fb0 100644 --- a/audio/common/4.0/Android.bp +++ b/audio/common/4.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.audio.common@4.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", ], diff --git a/audio/common/5.0/Android.bp b/audio/common/5.0/Android.bp index 761c171c96..bf265a5511 100644 --- a/audio/common/5.0/Android.bp +++ b/audio/common/5.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.audio.common@5.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", ], diff --git a/audio/common/6.0/Android.bp b/audio/common/6.0/Android.bp index 94f1cf8926..caeee6f75b 100644 --- a/audio/common/6.0/Android.bp +++ b/audio/common/6.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.audio.common@6.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", ], diff --git a/audio/effect/2.0/Android.bp b/audio/effect/2.0/Android.bp index d4482c2082..6b5d8aa99f 100644 --- a/audio/effect/2.0/Android.bp +++ b/audio/effect/2.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.audio.effect@2.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IAcousticEchoCancelerEffect.hal", diff --git a/audio/effect/4.0/Android.bp b/audio/effect/4.0/Android.bp index 8c1900f1fe..f396dcdb1b 100644 --- a/audio/effect/4.0/Android.bp +++ b/audio/effect/4.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.audio.effect@4.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IAcousticEchoCancelerEffect.hal", diff --git a/audio/effect/5.0/Android.bp b/audio/effect/5.0/Android.bp index b7dad8d9ca..a3081c688c 100644 --- a/audio/effect/5.0/Android.bp +++ b/audio/effect/5.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.audio.effect@5.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IAcousticEchoCancelerEffect.hal", diff --git a/audio/effect/6.0/Android.bp b/audio/effect/6.0/Android.bp index b6184f3a58..de4bde74b1 100644 --- a/audio/effect/6.0/Android.bp +++ b/audio/effect/6.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.audio.effect@6.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IAcousticEchoCancelerEffect.hal", diff --git a/authsecret/1.0/Android.bp b/authsecret/1.0/Android.bp index 3b84c3b518..5c556d2926 100644 --- a/authsecret/1.0/Android.bp +++ b/authsecret/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.authsecret@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "IAuthSecret.hal", ], diff --git a/automotive/audiocontrol/1.0/Android.bp b/automotive/audiocontrol/1.0/Android.bp index 7ef7909802..8835f51a29 100644 --- a/automotive/audiocontrol/1.0/Android.bp +++ b/automotive/audiocontrol/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.automotive.audiocontrol@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IAudioControl.hal", diff --git a/automotive/audiocontrol/2.0/Android.bp b/automotive/audiocontrol/2.0/Android.bp index 2a9f8499e3..e9ce638bae 100644 --- a/automotive/audiocontrol/2.0/Android.bp +++ b/automotive/audiocontrol/2.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.automotive.audiocontrol@2.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IAudioControl.hal", @@ -13,8 +10,9 @@ hidl_interface { "IFocusListener.hal", ], interfaces: [ - "android.hidl.base@1.0", "android.hardware.audio.common@6.0", + "android.hidl.base@1.0", + "android.hidl.safe_union@1.0", ], gen_java: true, } diff --git a/automotive/can/1.0/Android.bp b/automotive/can/1.0/Android.bp index 2221e6623e..2ddfaf93b8 100644 --- a/automotive/can/1.0/Android.bp +++ b/automotive/can/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.automotive.can@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "ICanBus.hal", diff --git a/automotive/evs/1.0/Android.bp b/automotive/evs/1.0/Android.bp index 51f8e208b1..279c09aca0 100644 --- a/automotive/evs/1.0/Android.bp +++ b/automotive/evs/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.automotive.evs@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IEvsCamera.hal", diff --git a/automotive/evs/1.1/Android.bp b/automotive/evs/1.1/Android.bp index f9bccef5fe..443422e5aa 100644 --- a/automotive/evs/1.1/Android.bp +++ b/automotive/evs/1.1/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.automotive.evs@1.1", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IEvsCamera.hal", diff --git a/automotive/sv/1.0/Android.bp b/automotive/sv/1.0/Android.bp index 769bdc62d8..3a39148aa0 100644 --- a/automotive/sv/1.0/Android.bp +++ b/automotive/sv/1.0/Android.bp @@ -3,22 +3,19 @@ hidl_interface { name: "android.hardware.automotive.sv@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", - "ISurroundViewStream.hal", - "ISurroundViewSession.hal", "ISurroundView2dSession.hal", "ISurroundView3dSession.hal", "ISurroundViewService.hal", + "ISurroundViewSession.hal", + "ISurroundViewStream.hal", ], interfaces: [ - "android.hidl.base@1.0", "android.hardware.graphics.common@1.0", "android.hardware.graphics.common@1.1", "android.hardware.graphics.common@1.2", + "android.hidl.base@1.0", ], gen_java: true, } diff --git a/automotive/vehicle/2.0/Android.bp b/automotive/vehicle/2.0/Android.bp index 0e73d856d9..4fa8773270 100644 --- a/automotive/vehicle/2.0/Android.bp +++ b/automotive/vehicle/2.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.automotive.vehicle@2.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IVehicle.hal", diff --git a/biometrics/face/1.0/Android.bp b/biometrics/face/1.0/Android.bp index ebb8668938..dd406f99c3 100644 --- a/biometrics/face/1.0/Android.bp +++ b/biometrics/face/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.biometrics.face@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IBiometricsFace.hal", diff --git a/biometrics/face/1.1/Android.bp b/biometrics/face/1.1/Android.bp index 2206597dec..14a86f14b8 100644 --- a/biometrics/face/1.1/Android.bp +++ b/biometrics/face/1.1/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.biometrics.face@1.1", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "IBiometricsFace.hal", ], diff --git a/biometrics/fingerprint/2.1/Android.bp b/biometrics/fingerprint/2.1/Android.bp index c8cc0f17bb..25bd48db70 100644 --- a/biometrics/fingerprint/2.1/Android.bp +++ b/biometrics/fingerprint/2.1/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.biometrics.fingerprint@2.1", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IBiometricsFingerprint.hal", diff --git a/biometrics/fingerprint/2.2/Android.bp b/biometrics/fingerprint/2.2/Android.bp index 6c769ac22e..a8f202c2c0 100644 --- a/biometrics/fingerprint/2.2/Android.bp +++ b/biometrics/fingerprint/2.2/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.biometrics.fingerprint@2.2", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IBiometricsFingerprint.hal", diff --git a/biometrics/fingerprint/2.3/Android.bp b/biometrics/fingerprint/2.3/Android.bp index 57ab83230d..cf635029f1 100644 --- a/biometrics/fingerprint/2.3/Android.bp +++ b/biometrics/fingerprint/2.3/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.biometrics.fingerprint@2.3", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "IBiometricsFingerprint.hal", ], diff --git a/bluetooth/1.0/Android.bp b/bluetooth/1.0/Android.bp index 7036d6e78a..1cac820427 100644 --- a/bluetooth/1.0/Android.bp +++ b/bluetooth/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.bluetooth@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IBluetoothHci.hal", diff --git a/bluetooth/1.1/Android.bp b/bluetooth/1.1/Android.bp index 4204aed7dc..c3967f028f 100644 --- a/bluetooth/1.1/Android.bp +++ b/bluetooth/1.1/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.bluetooth@1.1", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "IBluetoothHci.hal", "IBluetoothHciCallbacks.hal", diff --git a/bluetooth/a2dp/1.0/Android.bp b/bluetooth/a2dp/1.0/Android.bp index 02f224acff..d9ec982da8 100644 --- a/bluetooth/a2dp/1.0/Android.bp +++ b/bluetooth/a2dp/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.bluetooth.a2dp@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IBluetoothAudioHost.hal", diff --git a/bluetooth/audio/2.0/Android.bp b/bluetooth/audio/2.0/Android.bp index 6bf0070851..3fbd51f631 100644 --- a/bluetooth/audio/2.0/Android.bp +++ b/bluetooth/audio/2.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.bluetooth.audio@2.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IBluetoothAudioPort.hal", diff --git a/boot/1.0/Android.bp b/boot/1.0/Android.bp index 55684360bf..844cf9b26b 100644 --- a/boot/1.0/Android.bp +++ b/boot/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.boot@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IBootControl.hal", diff --git a/boot/1.1/Android.bp b/boot/1.1/Android.bp index 6a8d57aa8c..3f505e659e 100644 --- a/boot/1.1/Android.bp +++ b/boot/1.1/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.boot@1.1", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IBootControl.hal", diff --git a/broadcastradio/1.0/Android.bp b/broadcastradio/1.0/Android.bp index 8239d748fb..5fc120d3b9 100644 --- a/broadcastradio/1.0/Android.bp +++ b/broadcastradio/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.broadcastradio@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IBroadcastRadio.hal", diff --git a/broadcastradio/1.1/Android.bp b/broadcastradio/1.1/Android.bp index 1cc9b62ee6..5efa3d4599 100644 --- a/broadcastradio/1.1/Android.bp +++ b/broadcastradio/1.1/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.broadcastradio@1.1", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IBroadcastRadio.hal", diff --git a/broadcastradio/2.0/Android.bp b/broadcastradio/2.0/Android.bp index 1040ba1968..0ef635eb5e 100644 --- a/broadcastradio/2.0/Android.bp +++ b/broadcastradio/2.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.broadcastradio@2.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IAnnouncementListener.hal", diff --git a/camera/common/1.0/Android.bp b/camera/common/1.0/Android.bp index ed64060067..bd00dbbd37 100644 --- a/camera/common/1.0/Android.bp +++ b/camera/common/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.camera.common@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", ], diff --git a/camera/device/1.0/Android.bp b/camera/device/1.0/Android.bp index 668884d8c8..f2125af005 100644 --- a/camera/device/1.0/Android.bp +++ b/camera/device/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.camera.device@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "ICameraDevice.hal", diff --git a/camera/device/3.2/Android.bp b/camera/device/3.2/Android.bp index 2e5349f054..93d1e75a36 100644 --- a/camera/device/3.2/Android.bp +++ b/camera/device/3.2/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.camera.device@3.2", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "ICameraDevice.hal", diff --git a/camera/device/3.3/Android.bp b/camera/device/3.3/Android.bp index 679fad698e..0f8502b80c 100644 --- a/camera/device/3.3/Android.bp +++ b/camera/device/3.3/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.camera.device@3.3", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "ICameraDeviceSession.hal", diff --git a/camera/device/3.4/Android.bp b/camera/device/3.4/Android.bp index e6f42d6e1a..5575366155 100644 --- a/camera/device/3.4/Android.bp +++ b/camera/device/3.4/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.camera.device@3.4", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "ICameraDeviceCallback.hal", diff --git a/camera/device/3.5/Android.bp b/camera/device/3.5/Android.bp index 362a5e6894..94962169d9 100644 --- a/camera/device/3.5/Android.bp +++ b/camera/device/3.5/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.camera.device@3.5", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "ICameraDevice.hal", diff --git a/camera/device/3.6/Android.bp b/camera/device/3.6/Android.bp index 19adb3472d..e6f458ca5f 100644 --- a/camera/device/3.6/Android.bp +++ b/camera/device/3.6/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.camera.device@3.6", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "ICameraDevice.hal", diff --git a/camera/metadata/3.2/Android.bp b/camera/metadata/3.2/Android.bp index f58fb289e6..6e55139241 100644 --- a/camera/metadata/3.2/Android.bp +++ b/camera/metadata/3.2/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.camera.metadata@3.2", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", ], diff --git a/camera/metadata/3.3/Android.bp b/camera/metadata/3.3/Android.bp index 885f4f9b16..f11fe2bd2f 100644 --- a/camera/metadata/3.3/Android.bp +++ b/camera/metadata/3.3/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.camera.metadata@3.3", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", ], diff --git a/camera/metadata/3.4/Android.bp b/camera/metadata/3.4/Android.bp index 6a924580fd..31218be61e 100644 --- a/camera/metadata/3.4/Android.bp +++ b/camera/metadata/3.4/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.camera.metadata@3.4", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", ], diff --git a/camera/metadata/3.5/Android.bp b/camera/metadata/3.5/Android.bp index 224c36976a..a28ba430a5 100644 --- a/camera/metadata/3.5/Android.bp +++ b/camera/metadata/3.5/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.camera.metadata@3.5", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", ], diff --git a/camera/provider/2.4/Android.bp b/camera/provider/2.4/Android.bp index 876814d8f7..8b67f3fc13 100644 --- a/camera/provider/2.4/Android.bp +++ b/camera/provider/2.4/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.camera.provider@2.4", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "ICameraProvider.hal", "ICameraProviderCallback.hal", diff --git a/camera/provider/2.5/Android.bp b/camera/provider/2.5/Android.bp index 4ca1efbfc3..be71806206 100644 --- a/camera/provider/2.5/Android.bp +++ b/camera/provider/2.5/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.camera.provider@2.5", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "ICameraProvider.hal", diff --git a/camera/provider/2.6/Android.bp b/camera/provider/2.6/Android.bp index e69819c863..6934c175e0 100644 --- a/camera/provider/2.6/Android.bp +++ b/camera/provider/2.6/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.camera.provider@2.6", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "ICameraProvider.hal", diff --git a/cas/1.0/Android.bp b/cas/1.0/Android.bp index 4982e20b35..9f289a1dcc 100644 --- a/cas/1.0/Android.bp +++ b/cas/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.cas@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "ICas.hal", diff --git a/cas/1.1/Android.bp b/cas/1.1/Android.bp index 13217b6439..e20298b374 100644 --- a/cas/1.1/Android.bp +++ b/cas/1.1/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.cas@1.1", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "ICas.hal", "ICasListener.hal", diff --git a/cas/1.2/Android.bp b/cas/1.2/Android.bp index fbb38b0bb8..f03b6b7db1 100644 --- a/cas/1.2/Android.bp +++ b/cas/1.2/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.cas@1.2", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "ICas.hal", diff --git a/cas/native/1.0/Android.bp b/cas/native/1.0/Android.bp index 633ceb9306..6aa420414b 100644 --- a/cas/native/1.0/Android.bp +++ b/cas/native/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.cas.native@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IDescrambler.hal", diff --git a/confirmationui/1.0/Android.bp b/confirmationui/1.0/Android.bp index a22067a167..15c4f18c99 100644 --- a/confirmationui/1.0/Android.bp +++ b/confirmationui/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.confirmationui@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IConfirmationResultCallback.hal", diff --git a/contexthub/1.0/Android.bp b/contexthub/1.0/Android.bp index 71dd9787a3..be30d61a11 100644 --- a/contexthub/1.0/Android.bp +++ b/contexthub/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.contexthub@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IContexthub.hal", diff --git a/contexthub/1.1/Android.bp b/contexthub/1.1/Android.bp index 649f1db4c7..9ee8e765e5 100644 --- a/contexthub/1.1/Android.bp +++ b/contexthub/1.1/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.contexthub@1.1", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IContexthub.hal", diff --git a/drm/1.0/Android.bp b/drm/1.0/Android.bp index 9049af2882..44fb83777f 100644 --- a/drm/1.0/Android.bp +++ b/drm/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.drm@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "ICryptoFactory.hal", diff --git a/drm/1.1/Android.bp b/drm/1.1/Android.bp index 16010a656d..0af4cf4cdf 100644 --- a/drm/1.1/Android.bp +++ b/drm/1.1/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.drm@1.1", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "ICryptoFactory.hal", diff --git a/drm/1.2/Android.bp b/drm/1.2/Android.bp index 9104aa9ce8..f1c60de482 100644 --- a/drm/1.2/Android.bp +++ b/drm/1.2/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.drm@1.2", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "ICryptoFactory.hal", diff --git a/drm/1.3/Android.bp b/drm/1.3/Android.bp index b0ffcb92a5..9a2b9e12aa 100644 --- a/drm/1.3/Android.bp +++ b/drm/1.3/Android.bp @@ -3,12 +3,9 @@ hidl_interface { name: "android.hardware.drm@1.3", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ - "IDrmFactory.hal", "ICryptoFactory.hal", + "IDrmFactory.hal", ], interfaces: [ "android.hardware.drm@1.0", diff --git a/dumpstate/1.0/Android.bp b/dumpstate/1.0/Android.bp index 3d47550607..5d9eefcdf3 100644 --- a/dumpstate/1.0/Android.bp +++ b/dumpstate/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.dumpstate@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "IDumpstateDevice.hal", ], diff --git a/dumpstate/1.1/Android.bp b/dumpstate/1.1/Android.bp index 2aa8c82dc7..75805dfb51 100644 --- a/dumpstate/1.1/Android.bp +++ b/dumpstate/1.1/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.dumpstate@1.1", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IDumpstateDevice.hal", diff --git a/fastboot/1.0/Android.bp b/fastboot/1.0/Android.bp index ec447b80fc..60dfb2d9f5 100644 --- a/fastboot/1.0/Android.bp +++ b/fastboot/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.fastboot@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IFastboot.hal", diff --git a/gatekeeper/1.0/Android.bp b/gatekeeper/1.0/Android.bp index 5d63eaf0e9..28fd5b689a 100644 --- a/gatekeeper/1.0/Android.bp +++ b/gatekeeper/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.gatekeeper@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IGatekeeper.hal", diff --git a/gnss/1.0/Android.bp b/gnss/1.0/Android.bp index d97588c195..22f47e8aba 100644 --- a/gnss/1.0/Android.bp +++ b/gnss/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.gnss@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IAGnss.hal", diff --git a/gnss/1.1/Android.bp b/gnss/1.1/Android.bp index 5294a6b107..1c38e97c44 100644 --- a/gnss/1.1/Android.bp +++ b/gnss/1.1/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.gnss@1.1", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "IGnss.hal", "IGnssCallback.hal", diff --git a/gnss/2.0/Android.bp b/gnss/2.0/Android.bp index db5075f862..b7a98b7af2 100644 --- a/gnss/2.0/Android.bp +++ b/gnss/2.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.gnss@2.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IAGnss.hal", diff --git a/gnss/2.1/Android.bp b/gnss/2.1/Android.bp index 1a6b4140c1..affbeae66d 100644 --- a/gnss/2.1/Android.bp +++ b/gnss/2.1/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.gnss@2.1", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IGnss.hal", diff --git a/gnss/3.0/Android.bp b/gnss/3.0/Android.bp index 603c0db589..dada17ced7 100644 --- a/gnss/3.0/Android.bp +++ b/gnss/3.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.gnss@3.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "IGnss.hal", "IGnssPsds.hal", diff --git a/gnss/measurement_corrections/1.0/Android.bp b/gnss/measurement_corrections/1.0/Android.bp index 837cc7abca..a140674338 100644 --- a/gnss/measurement_corrections/1.0/Android.bp +++ b/gnss/measurement_corrections/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.gnss.measurement_corrections@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IMeasurementCorrections.hal", diff --git a/gnss/measurement_corrections/1.1/Android.bp b/gnss/measurement_corrections/1.1/Android.bp index f7ac8b88fd..93638489b0 100644 --- a/gnss/measurement_corrections/1.1/Android.bp +++ b/gnss/measurement_corrections/1.1/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.gnss.measurement_corrections@1.1", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IMeasurementCorrections.hal", diff --git a/gnss/visibility_control/1.0/Android.bp b/gnss/visibility_control/1.0/Android.bp index e58e9327cb..975da785e9 100644 --- a/gnss/visibility_control/1.0/Android.bp +++ b/gnss/visibility_control/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.gnss.visibility_control@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "IGnssVisibilityControl.hal", "IGnssVisibilityControlCallback.hal", diff --git a/graphics/composer/2.1/Android.bp b/graphics/composer/2.1/Android.bp index 4e4b81ce97..2358a8fbf3 100644 --- a/graphics/composer/2.1/Android.bp +++ b/graphics/composer/2.1/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.graphics.composer@2.1", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IComposer.hal", diff --git a/graphics/composer/2.2/Android.bp b/graphics/composer/2.2/Android.bp index 930cadc01d..234b9ac6bf 100644 --- a/graphics/composer/2.2/Android.bp +++ b/graphics/composer/2.2/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.graphics.composer@2.2", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "IComposer.hal", "IComposerClient.hal", diff --git a/graphics/composer/2.3/Android.bp b/graphics/composer/2.3/Android.bp index a777556aee..96f301c807 100644 --- a/graphics/composer/2.3/Android.bp +++ b/graphics/composer/2.3/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.graphics.composer@2.3", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "IComposer.hal", "IComposerClient.hal", diff --git a/graphics/composer/2.4/Android.bp b/graphics/composer/2.4/Android.bp index 5f700bed9b..2bbe751402 100644 --- a/graphics/composer/2.4/Android.bp +++ b/graphics/composer/2.4/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.graphics.composer@2.4", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IComposer.hal", diff --git a/health/1.0/Android.bp b/health/1.0/Android.bp index ea6b0c8161..7845871d6d 100644 --- a/health/1.0/Android.bp +++ b/health/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.health@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IHealth.hal", diff --git a/health/2.0/Android.bp b/health/2.0/Android.bp index b8323b62fe..420586e2e2 100644 --- a/health/2.0/Android.bp +++ b/health/2.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.health@2.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IHealth.hal", diff --git a/health/2.1/Android.bp b/health/2.1/Android.bp index 254bfc0d30..80a6501664 100644 --- a/health/2.1/Android.bp +++ b/health/2.1/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.health@2.1", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IHealth.hal", diff --git a/health/storage/1.0/Android.bp b/health/storage/1.0/Android.bp index e4620f8ee7..b9d892db43 100644 --- a/health/storage/1.0/Android.bp +++ b/health/storage/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.health.storage@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IGarbageCollectCallback.hal", diff --git a/input/classifier/1.0/Android.bp b/input/classifier/1.0/Android.bp index 11e0f52dd0..b6e54ca56a 100644 --- a/input/classifier/1.0/Android.bp +++ b/input/classifier/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.input.classifier@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "IInputClassifier.hal", ], diff --git a/input/common/1.0/Android.bp b/input/common/1.0/Android.bp index 2c7c517cce..07ced7ab05 100644 --- a/input/common/1.0/Android.bp +++ b/input/common/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.input.common@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", ], diff --git a/ir/1.0/Android.bp b/ir/1.0/Android.bp index 5fca96dca5..6a521f7d51 100644 --- a/ir/1.0/Android.bp +++ b/ir/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.ir@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IConsumerIr.hal", diff --git a/keymaster/3.0/Android.bp b/keymaster/3.0/Android.bp index 0fdc32c810..d0c7a7cd3e 100644 --- a/keymaster/3.0/Android.bp +++ b/keymaster/3.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.keymaster@3.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IKeymasterDevice.hal", diff --git a/keymaster/4.0/Android.bp b/keymaster/4.0/Android.bp index ea328f4c15..5774718601 100644 --- a/keymaster/4.0/Android.bp +++ b/keymaster/4.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.keymaster@4.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IKeymasterDevice.hal", diff --git a/keymaster/4.1/Android.bp b/keymaster/4.1/Android.bp index f6ac6f8426..4e7e944564 100644 --- a/keymaster/4.1/Android.bp +++ b/keymaster/4.1/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.keymaster@4.1", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IKeymasterDevice.hal", diff --git a/light/2.0/Android.bp b/light/2.0/Android.bp index d51f10dfb8..ae6d37c387 100644 --- a/light/2.0/Android.bp +++ b/light/2.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.light@2.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "ILight.hal", diff --git a/media/bufferpool/1.0/Android.bp b/media/bufferpool/1.0/Android.bp index 079e47fceb..5dbbadd436 100644 --- a/media/bufferpool/1.0/Android.bp +++ b/media/bufferpool/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.media.bufferpool@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IAccessor.hal", diff --git a/media/c2/1.0/Android.bp b/media/c2/1.0/Android.bp index 391e6c4a1f..089ce981eb 100644 --- a/media/c2/1.0/Android.bp +++ b/media/c2/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.media.c2@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IComponent.hal", diff --git a/media/c2/1.1/Android.bp b/media/c2/1.1/Android.bp index c3e30b215f..a3d31dfaff 100644 --- a/media/c2/1.1/Android.bp +++ b/media/c2/1.1/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.media.c2@1.1", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "IComponent.hal", "IComponentStore.hal", diff --git a/neuralnetworks/1.0/Android.bp b/neuralnetworks/1.0/Android.bp index 3e740c435d..20de9d56ec 100644 --- a/neuralnetworks/1.0/Android.bp +++ b/neuralnetworks/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.neuralnetworks@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IDevice.hal", diff --git a/neuralnetworks/1.1/Android.bp b/neuralnetworks/1.1/Android.bp index bef21c037c..52d866f853 100644 --- a/neuralnetworks/1.1/Android.bp +++ b/neuralnetworks/1.1/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.neuralnetworks@1.1", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IDevice.hal", diff --git a/neuralnetworks/1.2/Android.bp b/neuralnetworks/1.2/Android.bp index 4aa90aa54c..9e1db1e8f8 100644 --- a/neuralnetworks/1.2/Android.bp +++ b/neuralnetworks/1.2/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.neuralnetworks@1.2", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IBurstCallback.hal", diff --git a/neuralnetworks/1.3/Android.bp b/neuralnetworks/1.3/Android.bp index 7b02cc510f..3e02c909c7 100644 --- a/neuralnetworks/1.3/Android.bp +++ b/neuralnetworks/1.3/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.neuralnetworks@1.3", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IBuffer.hal", diff --git a/nfc/1.0/Android.bp b/nfc/1.0/Android.bp index bd64907364..667922a4ac 100644 --- a/nfc/1.0/Android.bp +++ b/nfc/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.nfc@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "INfc.hal", diff --git a/nfc/1.1/Android.bp b/nfc/1.1/Android.bp index 1f8789fc35..a8976b06c4 100644 --- a/nfc/1.1/Android.bp +++ b/nfc/1.1/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.nfc@1.1", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "INfc.hal", diff --git a/nfc/1.2/Android.bp b/nfc/1.2/Android.bp index aa68d2fde1..514d5313aa 100644 --- a/nfc/1.2/Android.bp +++ b/nfc/1.2/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.nfc@1.2", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "INfc.hal", diff --git a/oemlock/1.0/Android.bp b/oemlock/1.0/Android.bp index e784be098b..8ab2911b8e 100644 --- a/oemlock/1.0/Android.bp +++ b/oemlock/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.oemlock@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IOemLock.hal", diff --git a/power/1.0/Android.bp b/power/1.0/Android.bp index 6ba1d78e33..7381c709c9 100644 --- a/power/1.0/Android.bp +++ b/power/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.power@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IPower.hal", diff --git a/power/1.1/Android.bp b/power/1.1/Android.bp index 6b133cce00..e026e7021f 100644 --- a/power/1.1/Android.bp +++ b/power/1.1/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.power@1.1", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IPower.hal", diff --git a/power/1.2/Android.bp b/power/1.2/Android.bp index 296965b5c2..ccf66dc1a6 100644 --- a/power/1.2/Android.bp +++ b/power/1.2/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.power@1.2", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IPower.hal", diff --git a/power/1.3/Android.bp b/power/1.3/Android.bp index 00ca750212..15955e5db5 100644 --- a/power/1.3/Android.bp +++ b/power/1.3/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.power@1.3", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IPower.hal", diff --git a/power/stats/1.0/Android.bp b/power/stats/1.0/Android.bp index c592006089..2a71490522 100644 --- a/power/stats/1.0/Android.bp +++ b/power/stats/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.power.stats@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IPowerStats.hal", diff --git a/radio/1.0/Android.bp b/radio/1.0/Android.bp index 6765b4da7d..f3cc2e0ad4 100644 --- a/radio/1.0/Android.bp +++ b/radio/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.radio@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IRadio.hal", diff --git a/radio/1.1/Android.bp b/radio/1.1/Android.bp index 28388b0ebe..b325015824 100644 --- a/radio/1.1/Android.bp +++ b/radio/1.1/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.radio@1.1", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IRadio.hal", diff --git a/radio/1.2/Android.bp b/radio/1.2/Android.bp index 28e6b266cc..0a4caf11f5 100644 --- a/radio/1.2/Android.bp +++ b/radio/1.2/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.radio@1.2", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IRadio.hal", diff --git a/radio/1.3/Android.bp b/radio/1.3/Android.bp index b6af874956..1c8e6c2242 100644 --- a/radio/1.3/Android.bp +++ b/radio/1.3/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.radio@1.3", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IRadio.hal", diff --git a/radio/1.4/Android.bp b/radio/1.4/Android.bp index ff2e0d60d6..6c3a7d2563 100644 --- a/radio/1.4/Android.bp +++ b/radio/1.4/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.radio@1.4", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IRadio.hal", diff --git a/radio/1.5/Android.bp b/radio/1.5/Android.bp index 06a2a6ecf3..0542924e2d 100644 --- a/radio/1.5/Android.bp +++ b/radio/1.5/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.radio@1.5", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IRadio.hal", diff --git a/radio/config/1.0/Android.bp b/radio/config/1.0/Android.bp index 387f953edb..eea4c34b90 100644 --- a/radio/config/1.0/Android.bp +++ b/radio/config/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.radio.config@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IRadioConfig.hal", diff --git a/radio/config/1.1/Android.bp b/radio/config/1.1/Android.bp index 1e9071ab9a..a5c3114728 100644 --- a/radio/config/1.1/Android.bp +++ b/radio/config/1.1/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.radio.config@1.1", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IRadioConfig.hal", diff --git a/radio/config/1.2/Android.bp b/radio/config/1.2/Android.bp index 812f16643e..39d55ffa7a 100644 --- a/radio/config/1.2/Android.bp +++ b/radio/config/1.2/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.radio.config@1.2", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IRadioConfigIndication.hal", diff --git a/radio/deprecated/1.0/Android.bp b/radio/deprecated/1.0/Android.bp index cb13b86ca9..1a7cb940ae 100644 --- a/radio/deprecated/1.0/Android.bp +++ b/radio/deprecated/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.radio.deprecated@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "IOemHook.hal", "IOemHookIndication.hal", diff --git a/secure_element/1.0/Android.bp b/secure_element/1.0/Android.bp index 32b752ba3c..a32b9d1401 100644 --- a/secure_element/1.0/Android.bp +++ b/secure_element/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.secure_element@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "ISecureElement.hal", diff --git a/secure_element/1.1/Android.bp b/secure_element/1.1/Android.bp index 3ea2de94d1..08e6c8855e 100644 --- a/secure_element/1.1/Android.bp +++ b/secure_element/1.1/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.secure_element@1.1", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "ISecureElement.hal", "ISecureElementHalCallback.hal", diff --git a/secure_element/1.2/Android.bp b/secure_element/1.2/Android.bp index e134771880..03df5f9d68 100644 --- a/secure_element/1.2/Android.bp +++ b/secure_element/1.2/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.secure_element@1.2", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "ISecureElement.hal", ], diff --git a/sensors/1.0/Android.bp b/sensors/1.0/Android.bp index 509f72fc4a..109367106a 100644 --- a/sensors/1.0/Android.bp +++ b/sensors/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.sensors@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "ISensors.hal", diff --git a/sensors/2.0/Android.bp b/sensors/2.0/Android.bp index c8517c8dcb..d71f07b355 100644 --- a/sensors/2.0/Android.bp +++ b/sensors/2.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.sensors@2.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "ISensors.hal", diff --git a/sensors/2.1/Android.bp b/sensors/2.1/Android.bp index 8e80e1fb5d..9ba3248085 100644 --- a/sensors/2.1/Android.bp +++ b/sensors/2.1/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.sensors@2.1", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "ISensors.hal", diff --git a/soundtrigger/2.1/Android.bp b/soundtrigger/2.1/Android.bp index 30173cbcd8..024e0f6b5a 100644 --- a/soundtrigger/2.1/Android.bp +++ b/soundtrigger/2.1/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.soundtrigger@2.1", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "ISoundTriggerHw.hal", "ISoundTriggerHwCallback.hal", diff --git a/soundtrigger/2.2/Android.bp b/soundtrigger/2.2/Android.bp index 7556aa4fb5..dbf4f8bacd 100644 --- a/soundtrigger/2.2/Android.bp +++ b/soundtrigger/2.2/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.soundtrigger@2.2", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "ISoundTriggerHw.hal", ], diff --git a/soundtrigger/2.3/Android.bp b/soundtrigger/2.3/Android.bp index 3253a86695..480df4daa4 100644 --- a/soundtrigger/2.3/Android.bp +++ b/soundtrigger/2.3/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.soundtrigger@2.3", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "ISoundTriggerHw.hal", diff --git a/tests/expression/1.0/.hidl_for_test b/tests/expression/1.0/.hidl_for_test deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/extension/light/2.0/.hidl_for_test b/tests/extension/light/2.0/.hidl_for_test deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/foo/1.0/.hidl_for_test b/tests/foo/1.0/.hidl_for_test deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/hash/1.0/.hidl_for_test b/tests/hash/1.0/.hidl_for_test deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/inheritance/1.0/.hidl_for_test b/tests/inheritance/1.0/.hidl_for_test deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/bar/1.0/.hidl_for_test b/tests/lazy/1.0/.hidl_for_system_ext similarity index 100% rename from tests/bar/1.0/.hidl_for_test rename to tests/lazy/1.0/.hidl_for_system_ext diff --git a/tests/lazy/1.0/.hidl_for_test b/tests/lazy/1.0/.hidl_for_test deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/baz/1.0/.hidl_for_test b/tests/lazy/1.1/.hidl_for_system_ext similarity index 100% rename from tests/baz/1.0/.hidl_for_test rename to tests/lazy/1.1/.hidl_for_system_ext diff --git a/tests/lazy/1.1/.hidl_for_test b/tests/lazy/1.1/.hidl_for_test deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/libhwbinder/1.0/.hidl_for_test b/tests/libhwbinder/1.0/.hidl_for_test deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/libhwbinder/aidl/.hidl_for_test b/tests/libhwbinder/aidl/.hidl_for_test deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/memory/1.0/.hidl_for_test b/tests/memory/1.0/.hidl_for_test deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/memory/2.0/.hidl_for_test b/tests/memory/2.0/.hidl_for_test deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/msgq/1.0/.hidl_for_test b/tests/msgq/1.0/.hidl_for_test deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/multithread/1.0/.hidl_for_test b/tests/multithread/1.0/.hidl_for_test deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/safeunion/1.0/.hidl_for_test b/tests/safeunion/1.0/.hidl_for_test deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/safeunion/cpp/1.0/.hidl_for_test b/tests/safeunion/cpp/1.0/.hidl_for_test deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/trie/1.0/.hidl_for_test b/tests/trie/1.0/.hidl_for_test deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tetheroffload/config/1.0/Android.bp b/tetheroffload/config/1.0/Android.bp index 321224ad86..e774048751 100644 --- a/tetheroffload/config/1.0/Android.bp +++ b/tetheroffload/config/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.tetheroffload.config@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "IOffloadConfig.hal", ], diff --git a/tetheroffload/control/1.0/Android.bp b/tetheroffload/control/1.0/Android.bp index f894448ea4..4bcaed2dbf 100644 --- a/tetheroffload/control/1.0/Android.bp +++ b/tetheroffload/control/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.tetheroffload.control@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IOffloadControl.hal", diff --git a/thermal/1.0/Android.bp b/thermal/1.0/Android.bp index de168d877d..10eeddc07d 100644 --- a/thermal/1.0/Android.bp +++ b/thermal/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.thermal@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IThermal.hal", diff --git a/thermal/1.1/Android.bp b/thermal/1.1/Android.bp index f38ed3b107..7dc30a324d 100644 --- a/thermal/1.1/Android.bp +++ b/thermal/1.1/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.thermal@1.1", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "IThermal.hal", "IThermalCallback.hal", diff --git a/thermal/2.0/Android.bp b/thermal/2.0/Android.bp index 1b76f37f27..3d9cea1230 100644 --- a/thermal/2.0/Android.bp +++ b/thermal/2.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.thermal@2.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IThermal.hal", diff --git a/tv/cec/1.0/Android.bp b/tv/cec/1.0/Android.bp index d41a7e73eb..0e0f284d51 100644 --- a/tv/cec/1.0/Android.bp +++ b/tv/cec/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.tv.cec@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IHdmiCec.hal", diff --git a/tv/cec/2.0/Android.bp b/tv/cec/2.0/Android.bp index 61450ac4fb..5463b6da61 100644 --- a/tv/cec/2.0/Android.bp +++ b/tv/cec/2.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.tv.cec@2.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IHdmiCec.hal", diff --git a/tv/input/1.0/Android.bp b/tv/input/1.0/Android.bp index 1164430e93..1121f4ed46 100644 --- a/tv/input/1.0/Android.bp +++ b/tv/input/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.tv.input@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "ITvInput.hal", diff --git a/tv/tuner/1.0/Android.bp b/tv/tuner/1.0/Android.bp index d78f3f2f5c..e5786418f5 100644 --- a/tv/tuner/1.0/Android.bp +++ b/tv/tuner/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.tv.tuner@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IDemux.hal", diff --git a/usb/1.0/Android.bp b/usb/1.0/Android.bp index c0e883fd19..607d1aca79 100644 --- a/usb/1.0/Android.bp +++ b/usb/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.usb@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IUsb.hal", diff --git a/usb/1.1/Android.bp b/usb/1.1/Android.bp index 6f2abae27c..8742e77c57 100644 --- a/usb/1.1/Android.bp +++ b/usb/1.1/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.usb@1.1", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IUsb.hal", diff --git a/usb/1.2/Android.bp b/usb/1.2/Android.bp index b3ba81f1cf..8b9f0fb609 100644 --- a/usb/1.2/Android.bp +++ b/usb/1.2/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.usb@1.2", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IUsb.hal", diff --git a/usb/gadget/1.0/Android.bp b/usb/gadget/1.0/Android.bp index 4921abff76..21f152c36c 100644 --- a/usb/gadget/1.0/Android.bp +++ b/usb/gadget/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.usb.gadget@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IUsbGadget.hal", diff --git a/usb/gadget/1.1/Android.bp b/usb/gadget/1.1/Android.bp index b41eb9cbc5..e5100697cc 100644 --- a/usb/gadget/1.1/Android.bp +++ b/usb/gadget/1.1/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.usb.gadget@1.1", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "IUsbGadget.hal", ], diff --git a/vibrator/1.0/Android.bp b/vibrator/1.0/Android.bp index 792e130ee0..d6321fb163 100644 --- a/vibrator/1.0/Android.bp +++ b/vibrator/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.vibrator@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IVibrator.hal", diff --git a/vibrator/1.1/Android.bp b/vibrator/1.1/Android.bp index 0d04a870d8..0302220b56 100644 --- a/vibrator/1.1/Android.bp +++ b/vibrator/1.1/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.vibrator@1.1", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IVibrator.hal", diff --git a/vibrator/1.2/Android.bp b/vibrator/1.2/Android.bp index 290a0cfa43..1fa01144fa 100644 --- a/vibrator/1.2/Android.bp +++ b/vibrator/1.2/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.vibrator@1.2", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IVibrator.hal", diff --git a/vibrator/1.3/Android.bp b/vibrator/1.3/Android.bp index 357ea9a3e1..d742388879 100644 --- a/vibrator/1.3/Android.bp +++ b/vibrator/1.3/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.vibrator@1.3", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IVibrator.hal", diff --git a/vr/1.0/Android.bp b/vr/1.0/Android.bp index f91f874f14..769ee3b4a3 100644 --- a/vr/1.0/Android.bp +++ b/vr/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.vr@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "IVr.hal", ], diff --git a/weaver/1.0/Android.bp b/weaver/1.0/Android.bp index 7d5b8fe883..11fc68560a 100644 --- a/weaver/1.0/Android.bp +++ b/weaver/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.weaver@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IWeaver.hal", diff --git a/wifi/1.0/Android.bp b/wifi/1.0/Android.bp index 958ff3f2bf..c41864f853 100644 --- a/wifi/1.0/Android.bp +++ b/wifi/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.wifi@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IWifi.hal", diff --git a/wifi/1.1/Android.bp b/wifi/1.1/Android.bp index a34ac44218..4068b31fbb 100644 --- a/wifi/1.1/Android.bp +++ b/wifi/1.1/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.wifi@1.1", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "IWifi.hal", "IWifiChip.hal", diff --git a/wifi/1.2/Android.bp b/wifi/1.2/Android.bp index c28d09bd77..5812b8268a 100644 --- a/wifi/1.2/Android.bp +++ b/wifi/1.2/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.wifi@1.2", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IWifi.hal", diff --git a/wifi/1.3/Android.bp b/wifi/1.3/Android.bp index 3719c2b76b..f4e130a7a8 100644 --- a/wifi/1.3/Android.bp +++ b/wifi/1.3/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.wifi@1.3", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IWifi.hal", diff --git a/wifi/1.4/Android.bp b/wifi/1.4/Android.bp index 3b94619b3d..5620d03553 100644 --- a/wifi/1.4/Android.bp +++ b/wifi/1.4/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.wifi@1.4", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IWifi.hal", diff --git a/wifi/hostapd/1.0/Android.bp b/wifi/hostapd/1.0/Android.bp index cce1182af3..b736167f24 100644 --- a/wifi/hostapd/1.0/Android.bp +++ b/wifi/hostapd/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.wifi.hostapd@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IHostapd.hal", diff --git a/wifi/hostapd/1.1/Android.bp b/wifi/hostapd/1.1/Android.bp index 64fbc93791..bba065df08 100644 --- a/wifi/hostapd/1.1/Android.bp +++ b/wifi/hostapd/1.1/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.wifi.hostapd@1.1", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "IHostapd.hal", "IHostapdCallback.hal", diff --git a/wifi/hostapd/1.2/Android.bp b/wifi/hostapd/1.2/Android.bp index 3dcad71881..9b26ece6b2 100644 --- a/wifi/hostapd/1.2/Android.bp +++ b/wifi/hostapd/1.2/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.wifi.hostapd@1.2", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IHostapd.hal", diff --git a/wifi/offload/1.0/Android.bp b/wifi/offload/1.0/Android.bp index 110bb702d2..91ed476c62 100644 --- a/wifi/offload/1.0/Android.bp +++ b/wifi/offload/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.wifi.offload@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "IOffload.hal", diff --git a/wifi/supplicant/1.0/Android.bp b/wifi/supplicant/1.0/Android.bp index d91512f7bd..d46e463ac9 100644 --- a/wifi/supplicant/1.0/Android.bp +++ b/wifi/supplicant/1.0/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.wifi.supplicant@1.0", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "ISupplicant.hal", diff --git a/wifi/supplicant/1.1/Android.bp b/wifi/supplicant/1.1/Android.bp index 6d940d17ed..bc20dca6db 100644 --- a/wifi/supplicant/1.1/Android.bp +++ b/wifi/supplicant/1.1/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.wifi.supplicant@1.1", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "ISupplicant.hal", "ISupplicantStaIface.hal", diff --git a/wifi/supplicant/1.2/Android.bp b/wifi/supplicant/1.2/Android.bp index 185d2b8df2..aa2fa7be60 100644 --- a/wifi/supplicant/1.2/Android.bp +++ b/wifi/supplicant/1.2/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.wifi.supplicant@1.2", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "ISupplicant.hal", diff --git a/wifi/supplicant/1.3/Android.bp b/wifi/supplicant/1.3/Android.bp index 15c72fed59..4268490f6a 100644 --- a/wifi/supplicant/1.3/Android.bp +++ b/wifi/supplicant/1.3/Android.bp @@ -3,9 +3,6 @@ hidl_interface { name: "android.hardware.wifi.supplicant@1.3", root: "android.hardware", - vndk: { - enabled: true, - }, srcs: [ "types.hal", "ISupplicant.hal", -- GitLab From 2134bf71f827ae793031b0ce967d6f7676e0c4ab Mon Sep 17 00:00:00 2001 From: Ahmed ElArabawy Date: Thu, 18 Jun 2020 15:07:12 -0700 Subject: [PATCH 062/790] Wifi: Handle subsystem restart notification This commit adds the logic to handle a notification of a wifi subsystem restart to trigger the callback to the framework for self recovery. Bug: 159367026 Test: force a firmware restart and make sure Wifi is recovered. Change-Id: If6b5863d1d7473917088ec5be1910fa0db5dd6ae --- .../default/tests/wifi_chip_unit_tests.cpp | 7 +++-- wifi/1.4/default/wifi.cpp | 18 +++++++++++-- wifi/1.4/default/wifi_chip.cpp | 10 +++++-- wifi/1.4/default/wifi_chip.h | 17 +++++++----- wifi/1.4/default/wifi_legacy_hal.cpp | 27 +++++++++++++++++++ wifi/1.4/default/wifi_legacy_hal.h | 5 ++++ wifi/1.4/default/wifi_legacy_hal_stubs.cpp | 1 + 7 files changed, 72 insertions(+), 13 deletions(-) diff --git a/wifi/1.4/default/tests/wifi_chip_unit_tests.cpp b/wifi/1.4/default/tests/wifi_chip_unit_tests.cpp index 323d2ffa81..3f1af2eafd 100644 --- a/wifi/1.4/default/tests/wifi_chip_unit_tests.cpp +++ b/wifi/1.4/default/tests/wifi_chip_unit_tests.cpp @@ -263,6 +263,8 @@ class WifiChipTest : public Test { return success; } + static void subsystemRestartHandler(const std::string& /*error*/) {} + sp chip_; ChipId chip_id_ = kFakeChipId; std::shared_ptr> iface_tool_{ @@ -278,8 +280,9 @@ class WifiChipTest : public Test { public: void SetUp() override { - chip_ = new WifiChip(chip_id_, legacy_hal_, mode_controller_, - iface_util_, feature_flags_); + chip_ = + new WifiChip(chip_id_, legacy_hal_, mode_controller_, iface_util_, + feature_flags_, subsystemRestartHandler); EXPECT_CALL(*mode_controller_, changeFirmwareMode(testing::_)) .WillRepeatedly(testing::Return(true)); diff --git a/wifi/1.4/default/wifi.cpp b/wifi/1.4/default/wifi.cpp index 9c6b0f0f16..cfebfe03c7 100644 --- a/wifi/1.4/default/wifi.cpp +++ b/wifi/1.4/default/wifi.cpp @@ -107,9 +107,23 @@ WifiStatus Wifi::startInternal() { } 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()) { + if (!callback->onFailure(wifi_status).isOk()) { + LOG(ERROR) << "Failed to invoke onFailure callback"; + } + } + }; + // Create the chip instance once the HAL is started. - chip_ = new WifiChip(kChipId, legacy_hal_, mode_controller_, - iface_util_, feature_flags_); + // Need to consider the case of multiple chips TODO(156998862) + chip_ = + new WifiChip(kChipId, legacy_hal_, mode_controller_, iface_util_, + feature_flags_, on_subsystem_restart_callback); run_state_ = RunState::STARTED; for (const auto& callback : event_cb_handler_.getCallbacks()) { if (!callback->onStart().isOk()) { diff --git a/wifi/1.4/default/wifi_chip.cpp b/wifi/1.4/default/wifi_chip.cpp index 8747e61992..96b83ac286 100644 --- a/wifi/1.4/default/wifi_chip.cpp +++ b/wifi/1.4/default/wifi_chip.cpp @@ -335,7 +335,8 @@ WifiChip::WifiChip( ChipId chip_id, const std::weak_ptr legacy_hal, const std::weak_ptr mode_controller, const std::weak_ptr iface_util, - const std::weak_ptr feature_flags) + const std::weak_ptr feature_flags, + const std::function& handler) : chip_id_(chip_id), legacy_hal_(legacy_hal), mode_controller_(mode_controller), @@ -343,7 +344,8 @@ WifiChip::WifiChip( is_valid_(true), current_mode_id_(feature_flags::chip_mode_ids::kInvalid), modes_(feature_flags.lock()->getChipModes()), - debug_ring_buffer_cb_registered_(false) { + debug_ring_buffer_cb_registered_(false), + subsystemCallbackHandler_(handler) { setActiveWlanIfaceNameProperty(kNoActiveWlanIfaceNamePropertyValue); } @@ -737,6 +739,10 @@ WifiStatus WifiChip::configureChipInternal( current_mode_id_ = mode_id; LOG(INFO) << "Configured chip in mode " << mode_id; setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName()); + + legacy_hal_.lock()->registerSubsystemRestartCallbackHandler( + subsystemCallbackHandler_); + return status; } diff --git a/wifi/1.4/default/wifi_chip.h b/wifi/1.4/default/wifi_chip.h index 98e18bba07..e7650bdc1d 100644 --- a/wifi/1.4/default/wifi_chip.h +++ b/wifi/1.4/default/wifi_chip.h @@ -50,13 +50,14 @@ using namespace android::hardware::wifi::V1_0; */ class WifiChip : public V1_4::IWifiChip { public: - WifiChip( - ChipId chip_id, - const std::weak_ptr legacy_hal, - const std::weak_ptr - mode_controller, - const std::weak_ptr iface_util, - const std::weak_ptr feature_flags); + WifiChip(ChipId chip_id, + const std::weak_ptr legacy_hal, + const std::weak_ptr + mode_controller, + const std::weak_ptr iface_util, + const std::weak_ptr feature_flags, + const std::function& + 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 @@ -282,6 +283,8 @@ class WifiChip : public V1_4::IWifiChip { hidl_callback_util::HidlCallbackHandler event_cb_handler_; + const std::function subsystemCallbackHandler_; + DISALLOW_COPY_AND_ASSIGN(WifiChip); }; diff --git a/wifi/1.4/default/wifi_legacy_hal.cpp b/wifi/1.4/default/wifi_legacy_hal.cpp index 29123bfe47..e9c3a0e3fd 100644 --- a/wifi/1.4/default/wifi_legacy_hal.cpp +++ b/wifi/1.4/default/wifi_legacy_hal.cpp @@ -162,6 +162,15 @@ void onAsyncRadioModeChange(wifi_request_id id, uint32_t num_macs, } } +// Callback to be invoked to report subsystem restart +std::function on_subsystem_restart_internal_callback; +void onAsyncSubsystemRestart(const char* error) { + const auto lock = hidl_sync_util::acquireGlobalLock(); + if (on_subsystem_restart_internal_callback) { + on_subsystem_restart_internal_callback(error); + } +} + // Callback to be invoked for rtt results results. std::function @@ -1049,6 +1058,23 @@ wifi_error WifiLegacyHal::registerRadioModeChangeCallbackHandler( return status; } +wifi_error WifiLegacyHal::registerSubsystemRestartCallbackHandler( + 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); + }; + wifi_error status = global_func_table_.wifi_set_subsystem_restart_handler( + global_handle_, {onAsyncSubsystemRestart}); + if (status != WIFI_SUCCESS) { + on_subsystem_restart_internal_callback = nullptr; + } + return status; +} + wifi_error WifiLegacyHal::startRttRangeRequest( const std::string& iface_name, wifi_request_id id, const std::vector& rtt_configs, @@ -1471,6 +1497,7 @@ void WifiLegacyHal::invalidate() { on_ring_buffer_data_internal_callback = nullptr; on_error_alert_internal_callback = nullptr; on_radio_mode_change_internal_callback = nullptr; + on_subsystem_restart_internal_callback = nullptr; on_rtt_results_internal_callback = nullptr; on_nan_notify_response_user_callback = nullptr; on_nan_event_publish_terminated_user_callback = nullptr; diff --git a/wifi/1.4/default/wifi_legacy_hal.h b/wifi/1.4/default/wifi_legacy_hal.h index 99644604cc..2d4c59478a 100644 --- a/wifi/1.4/default/wifi_legacy_hal.h +++ b/wifi/1.4/default/wifi_legacy_hal.h @@ -142,6 +142,9 @@ using on_ring_buffer_data_callback = using on_error_alert_callback = std::function&)>; +// Callback for subsystem restart +using on_subsystem_restart_callback = std::function; + // Struct for the mac info from the legacy HAL. This is a cleaner version // of the |wifi_mac_info| & |wifi_iface_info|. typedef struct { @@ -277,6 +280,8 @@ class WifiLegacyHal { 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> getRingBuffersStatus(const std::string& iface_name); wifi_error startRingBufferLogging(const std::string& iface_name, diff --git a/wifi/1.4/default/wifi_legacy_hal_stubs.cpp b/wifi/1.4/default/wifi_legacy_hal_stubs.cpp index 153a68520f..64b058e692 100644 --- a/wifi/1.4/default/wifi_legacy_hal_stubs.cpp +++ b/wifi/1.4/default/wifi_legacy_hal_stubs.cpp @@ -143,6 +143,7 @@ bool initHalFuncTableWithStubs(wifi_hal_fn* hal_fn) { populateStubFor(&hal_fn->wifi_virtual_interface_delete); populateStubFor(&hal_fn->wifi_map_dscp_access_category); populateStubFor(&hal_fn->wifi_reset_dscp_mapping); + populateStubFor(&hal_fn->wifi_set_subsystem_restart_handler); return true; } } // namespace legacy_hal -- GitLab From 0d6cefe90b949c9e2e90471f7aa959a0714eeb45 Mon Sep 17 00:00:00 2001 From: Slava Shklyaev Date: Thu, 9 Jul 2020 15:28:18 +0100 Subject: [PATCH 063/790] Fix stale NNAPI documentation The scale and zeroPoint fields are applicable to other types since 1.2. Also makes some whitespaces changes due to the generated documentation getting out of sync with the template in frameworks/ml/nn. Fix: 160406237 Test: generate_api.sh Test: m Change-Id: Icf594d40c73ff8c05044c320ac9eb6a9c5a89754 --- current.txt | 2 ++ neuralnetworks/1.2/types.hal | 9 ++++++--- neuralnetworks/1.2/types.t | 9 ++++++--- neuralnetworks/1.3/types.hal | 23 +++++++++++++---------- neuralnetworks/1.3/types.t | 9 ++++++--- 5 files changed, 33 insertions(+), 19 deletions(-) diff --git a/current.txt b/current.txt index fc8c025c04..2756c5f4d4 100644 --- a/current.txt +++ b/current.txt @@ -768,6 +768,8 @@ a64467bae843569f0d465c5be7f0c7a5b987985b55a3ef4794dd5afc68538650 android.hardwar # ABI preserving changes to HALs during Android S cd84ab19c590e0e73dd2307b591a3093ee18147ef95e6d5418644463a6620076 android.hardware.neuralnetworks@1.2::IDevice +9625e85f56515ad2cf87b6a1847906db669f746ea4ab02cd3d4ca25abc9b0109 android.hardware.neuralnetworks@1.2::types +745295adfd826de650eedaf8cc6979f52a1cf30b04ea7a089a132d0089475e95 android.hardware.neuralnetworks@1.3::types # HALs released in Android S # NOTE: waiting to freeze HALs until later in the release diff --git a/neuralnetworks/1.2/types.hal b/neuralnetworks/1.2/types.hal index 92cf2aa5e4..7441a54dba 100644 --- a/neuralnetworks/1.2/types.hal +++ b/neuralnetworks/1.2/types.hal @@ -4853,15 +4853,18 @@ struct Operand { /** * Quantized scale of the operand. * - * Only applicable if the operand is of type TENSOR_QUANT8_ASYMM or - * TENSOR_INT32. + * Must be 0 when not applicable to an operand type. + * + * See {@link OperandType}. */ float scale; /** * Quantized zero-point offset of the operand. * - * Only applicable if the operand is of type TENSOR_QUANT8_ASYMM. + * Must be 0 when not applicable to an operand type. + * + * See {@link OperandType}. */ int32_t zeroPoint; diff --git a/neuralnetworks/1.2/types.t b/neuralnetworks/1.2/types.t index d197f6b541..21d88acf8f 100644 --- a/neuralnetworks/1.2/types.t +++ b/neuralnetworks/1.2/types.t @@ -251,15 +251,18 @@ struct Operand { /** * Quantized scale of the operand. * - * Only applicable if the operand is of type TENSOR_QUANT8_ASYMM or - * TENSOR_INT32. + * Must be 0 when not applicable to an operand type. + * + * See {@link OperandType}. */ float scale; /** * Quantized zero-point offset of the operand. * - * Only applicable if the operand is of type TENSOR_QUANT8_ASYMM. + * Must be 0 when not applicable to an operand type. + * + * See {@link OperandType}. */ int32_t zeroPoint; diff --git a/neuralnetworks/1.3/types.hal b/neuralnetworks/1.3/types.hal index 3b2b14c98c..7ec60648c5 100644 --- a/neuralnetworks/1.3/types.hal +++ b/neuralnetworks/1.3/types.hal @@ -5103,8 +5103,8 @@ enum OperationType : int32_t { * signature of this operation. That is, if the operation has (3 + n) inputs * and m outputs, both subgraphs must have n inputs and m outputs with the same * types, ranks, dimensions, scales, - * zeroPoints, and extraParams as the corresponding operation inputs and - * outputs. + * zeroPoints, and extraParams as the corresponding operation + * inputs and outputs. * All of the operands mentioned must have fully specified dimensions. * * Inputs: @@ -5170,15 +5170,15 @@ enum OperationType : int32_t { * * 0: A {@link OperandType::SUBGRAPH} reference to the condition * subgraph. The subgraph must have (m + k + n) inputs with * the same types, ranks, dimensions, - * scales, zeroPoints, and extraParams as the corresponding inputs of - * the WHILE operation and exactly one output of - * {@link OperandType::TENSOR_BOOL8} and shape [1]. + * scales, zeroPoints, and extraParams as the + * corresponding inputs of the WHILE operation and exactly one output + * of {@link OperandType::TENSOR_BOOL8} and shape [1]. * All of the operands mentioned must have fully specified dimensions. * * 1: A {@link OperandType::SUBGRAPH} reference to the body subgraph. * The subgraph must have (m + k + n) inputs and (m + k) outputs with * the same types, ranks, dimensions, - * scales, zeroPoints, and extraParams as the corresponding inputs and - * outputs of the WHILE operation. + * scales, zeroPoints, and extraParams as the + * corresponding inputs and outputs of the WHILE operation. * All of the operands mentioned must have fully specified dimensions. * * (m inputs): Initial values for input-output operands. * * (k inputs): Initial values for state-only operands. @@ -5538,15 +5538,18 @@ struct Operand { /** * Quantized scale of the operand. * - * Only applicable if the operand is of type TENSOR_QUANT8_ASYMM or - * TENSOR_INT32. + * Must be 0 when not applicable to an operand type. + * + * See {@link OperandType}. */ float scale; /** * Quantized zero-point offset of the operand. * - * Only applicable if the operand is of type TENSOR_QUANT8_ASYMM. + * Must be 0 when not applicable to an operand type. + * + * See {@link OperandType}. */ int32_t zeroPoint; diff --git a/neuralnetworks/1.3/types.t b/neuralnetworks/1.3/types.t index 7220e372a7..9cffc7a32c 100644 --- a/neuralnetworks/1.3/types.t +++ b/neuralnetworks/1.3/types.t @@ -303,15 +303,18 @@ struct Operand { /** * Quantized scale of the operand. * - * Only applicable if the operand is of type TENSOR_QUANT8_ASYMM or - * TENSOR_INT32. + * Must be 0 when not applicable to an operand type. + * + * See {@link OperandType}. */ float scale; /** * Quantized zero-point offset of the operand. * - * Only applicable if the operand is of type TENSOR_QUANT8_ASYMM. + * Must be 0 when not applicable to an operand type. + * + * See {@link OperandType}. */ int32_t zeroPoint; -- GitLab From 3bbc2aedd0c02afe9eeb3c4460ee1b6d8ddc1796 Mon Sep 17 00:00:00 2001 From: Slava Shklyaev Date: Mon, 13 Jul 2020 14:18:27 +0100 Subject: [PATCH 064/790] Fix typo in NNAPI documentation Fix: 160960007 Test: m Change-Id: I6c1af92f640fde833d2d93f7db4576c92a6f9719 --- current.txt | 2 +- neuralnetworks/1.3/types.hal | 8 ++++---- neuralnetworks/1.3/types.t | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/current.txt b/current.txt index 2756c5f4d4..6f0debd047 100644 --- a/current.txt +++ b/current.txt @@ -769,7 +769,7 @@ a64467bae843569f0d465c5be7f0c7a5b987985b55a3ef4794dd5afc68538650 android.hardwar # ABI preserving changes to HALs during Android S cd84ab19c590e0e73dd2307b591a3093ee18147ef95e6d5418644463a6620076 android.hardware.neuralnetworks@1.2::IDevice 9625e85f56515ad2cf87b6a1847906db669f746ea4ab02cd3d4ca25abc9b0109 android.hardware.neuralnetworks@1.2::types -745295adfd826de650eedaf8cc6979f52a1cf30b04ea7a089a132d0089475e95 android.hardware.neuralnetworks@1.3::types +9e758e208d14f7256e0885d6d8ad0b61121b21d8c313864f981727ae55bffd16 android.hardware.neuralnetworks@1.3::types # HALs released in Android S # NOTE: waiting to freeze HALs until later in the release diff --git a/neuralnetworks/1.3/types.hal b/neuralnetworks/1.3/types.hal index 7ec60648c5..5f5ee0360c 100644 --- a/neuralnetworks/1.3/types.hal +++ b/neuralnetworks/1.3/types.hal @@ -5743,8 +5743,8 @@ struct Request { * Input data and information to be used in the execution of a prepared * model. * - * The index of the input corresponds to the index in Model.inputIndexes. - * E.g., input[i] corresponds to Model.inputIndexes[i]. + * The index of the input corresponds to the index in Model.main.inputIndexes. + * E.g., input[i] corresponds to Model.main.inputIndexes[i]. */ vec inputs; @@ -5752,8 +5752,8 @@ struct Request { * Output data and information to be used in the execution of a prepared * model. * - * The index of the output corresponds to the index in Model.outputIndexes. - * E.g., output[i] corresponds to Model.outputIndexes[i]. + * The index of the output corresponds to the index in Model.main.outputIndexes. + * E.g., output[i] corresponds to Model.main.outputIndexes[i]. */ vec outputs; diff --git a/neuralnetworks/1.3/types.t b/neuralnetworks/1.3/types.t index 9cffc7a32c..2901d18525 100644 --- a/neuralnetworks/1.3/types.t +++ b/neuralnetworks/1.3/types.t @@ -508,8 +508,8 @@ struct Request { * Input data and information to be used in the execution of a prepared * model. * - * The index of the input corresponds to the index in Model.inputIndexes. - * E.g., input[i] corresponds to Model.inputIndexes[i]. + * The index of the input corresponds to the index in Model.main.inputIndexes. + * E.g., input[i] corresponds to Model.main.inputIndexes[i]. */ vec inputs; @@ -517,8 +517,8 @@ struct Request { * Output data and information to be used in the execution of a prepared * model. * - * The index of the output corresponds to the index in Model.outputIndexes. - * E.g., output[i] corresponds to Model.outputIndexes[i]. + * The index of the output corresponds to the index in Model.main.outputIndexes. + * E.g., output[i] corresponds to Model.main.outputIndexes[i]. */ vec outputs; -- GitLab From 01c595f4dfd58f2801399492bf96499b0a1b1e60 Mon Sep 17 00:00:00 2001 From: chaviw Date: Mon, 13 Jul 2020 12:53:44 -0700 Subject: [PATCH 065/790] Added libui-types dependency Test: m VtsHalInputClassifierV1_0TargetTest Bug: 158476194 Change-Id: I53dbb41575d9e9b5919cb887130da27bee69d792 --- input/classifier/1.0/vts/functional/Android.bp | 1 + 1 file changed, 1 insertion(+) diff --git a/input/classifier/1.0/vts/functional/Android.bp b/input/classifier/1.0/vts/functional/Android.bp index 99fdb8c445..fc1f5857b2 100644 --- a/input/classifier/1.0/vts/functional/Android.bp +++ b/input/classifier/1.0/vts/functional/Android.bp @@ -22,6 +22,7 @@ cc_test { static_libs: [ "android.hardware.input.classifier@1.0", "android.hardware.input.common@1.0", + "libui-types", ], test_suites: [ "general-tests", -- GitLab From cd3fd87d475a94b67d3544001cbfa0e2712fc7b6 Mon Sep 17 00:00:00 2001 From: Shuo Qian Date: Mon, 13 Jul 2020 13:52:22 -0700 Subject: [PATCH 066/790] Change range of SS-RSRQ per 3gpp Bug: 159761054 Test: VTS Change-Id: I377ef00015876b706ffeb20d9255c1b1ebf66c15 --- current.txt | 2 ++ radio/1.4/types.hal | 4 ++-- radio/1.5/types.hal | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/current.txt b/current.txt index 6f0debd047..6f5e55916c 100644 --- a/current.txt +++ b/current.txt @@ -770,6 +770,8 @@ a64467bae843569f0d465c5be7f0c7a5b987985b55a3ef4794dd5afc68538650 android.hardwar cd84ab19c590e0e73dd2307b591a3093ee18147ef95e6d5418644463a6620076 android.hardware.neuralnetworks@1.2::IDevice 9625e85f56515ad2cf87b6a1847906db669f746ea4ab02cd3d4ca25abc9b0109 android.hardware.neuralnetworks@1.2::types 9e758e208d14f7256e0885d6d8ad0b61121b21d8c313864f981727ae55bffd16 android.hardware.neuralnetworks@1.3::types +38d65fb20c60a5b823298560fc0825457ecdc49603a4b4e94bf81511790737da android.hardware.radio@1.4::types +954c334efd80e8869b66d1ce5fe2755712d96ba4b3c38d415739c330af5fb4cb android.hardware.radio@1.5::types # HALs released in Android S # NOTE: waiting to freeze HALs until later in the release diff --git a/radio/1.4/types.hal b/radio/1.4/types.hal index 393716b7ce..a830816822 100644 --- a/radio/1.4/types.hal +++ b/radio/1.4/types.hal @@ -1847,9 +1847,9 @@ struct NrSignalStrength { /** * SS reference signal received quality, multipled by -1. * - * Reference: 3GPP TS 38.215. + * Reference: 3GPP TS 38.215, 3GPP TS 38.133 section 10. * - * Range [3, 20], INT_MAX means invalid/unreported. + * Range [-20 dB, 43 dB], INT_MAX means invalid/unreported. */ int32_t ssRsrq; diff --git a/radio/1.5/types.hal b/radio/1.5/types.hal index b061bd51c8..c1f3f0358e 100644 --- a/radio/1.5/types.hal +++ b/radio/1.5/types.hal @@ -107,9 +107,9 @@ enum SignalMeasurementType : int32_t { SSRSRP = 6, /** * 5G SS reference signal received quality. - * Range: -20 dB to -3 dB. + * Range: -43 dB to 20 dB. * Used RAN: NGRAN - * Reference: 3GPP TS 38.215. + * Reference: 3GPP TS 38.215, 3GPP TS 38.133 section 10 */ SSRSRQ = 7, /** -- GitLab From 3f0c09583c489f35795b19bd2588ddd9a39b4afb Mon Sep 17 00:00:00 2001 From: TF Huang Date: Wed, 1 Jul 2020 10:43:31 +0800 Subject: [PATCH 067/790] wlan: add supported interfaces in rc file Service vendor.wifi_hal_legacy should add all supported interface into relevant .rc files. Bug: 160377428 Test: Wifi presubmit tests Change-Id: I68e8d3e7ddb1470a92c5ccd30f6d4d5f90ad9e37 --- wifi/1.4/default/android.hardware.wifi@1.0-service-lazy.rc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/wifi/1.4/default/android.hardware.wifi@1.0-service-lazy.rc b/wifi/1.4/default/android.hardware.wifi@1.0-service-lazy.rc index cf917b5458..061689dbe5 100644 --- a/wifi/1.4/default/android.hardware.wifi@1.0-service-lazy.rc +++ b/wifi/1.4/default/android.hardware.wifi@1.0-service-lazy.rc @@ -1,5 +1,9 @@ service vendor.wifi_hal_legacy /vendor/bin/hw/android.hardware.wifi@1.0-service-lazy interface android.hardware.wifi@1.0::IWifi default + interface android.hardware.wifi@1.1::IWifi default + interface android.hardware.wifi@1.2::IWifi default + interface android.hardware.wifi@1.3::IWifi default + interface android.hardware.wifi@1.4::IWifi default oneshot disabled class hal -- GitLab From 6d774c89a1112c36ad14c9c0b95ee8816cb176f2 Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Wed, 15 Jul 2020 14:27:32 -0700 Subject: [PATCH 068/790] Fix bugs in the Tuner HAL 1.0 VTS The previous implementation did not check some of the Descrambler API test results to stop the test. And the test itself was also implemented in a wrong way. Test: atest VtsHalTvTunerV1_0TargetTest Bug: 150987138 Change-Id: Ie26db0ec1b231062d0314631eebec319382da1bc --- .../1.0/vts/functional/DescramblerTests.cpp | 16 ++++++++-------- .../functional/VtsHalTvTunerV1_0TargetTest.cpp | 18 +++++++++--------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/tv/tuner/1.0/vts/functional/DescramblerTests.cpp b/tv/tuner/1.0/vts/functional/DescramblerTests.cpp index d7440bc135..2e27475e71 100644 --- a/tv/tuner/1.0/vts/functional/DescramblerTests.cpp +++ b/tv/tuner/1.0/vts/functional/DescramblerTests.cpp @@ -102,13 +102,13 @@ AssertionResult DescramblerTests::openDescrambler(uint32_t demuxId) { AssertionResult DescramblerTests::setKeyToken(TunerKeyToken token) { Result status; - if (mDescrambler) { + if (!mDescrambler) { ALOGW("[vts] Descrambler is not opened yet."); return failure(); } status = mDescrambler->setKeyToken(token); - if (status == Result::SUCCESS) { + if (status != Result::SUCCESS) { ALOGW("[vts] setKeyToken failed."); return failure(); } @@ -118,13 +118,13 @@ AssertionResult DescramblerTests::setKeyToken(TunerKeyToken token) { AssertionResult DescramblerTests::addPid(DemuxPid pid, sp optionalSourceFilter) { Result status; - if (mDescrambler) { + if (!mDescrambler) { ALOGW("[vts] Descrambler is not opened yet."); return failure(); } status = mDescrambler->addPid(pid, optionalSourceFilter); - if (status == Result::SUCCESS) { + if (status != Result::SUCCESS) { ALOGW("[vts] addPid failed."); return failure(); } @@ -134,13 +134,13 @@ AssertionResult DescramblerTests::addPid(DemuxPid pid, sp optionalSourc AssertionResult DescramblerTests::removePid(DemuxPid pid, sp optionalSourceFilter) { Result status; - if (mDescrambler) { + if (!mDescrambler) { ALOGW("[vts] Descrambler is not opened yet."); return failure(); } status = mDescrambler->removePid(pid, optionalSourceFilter); - if (status == Result::SUCCESS) { + if (status != Result::SUCCESS) { ALOGW("[vts] removePid failed."); return failure(); } @@ -150,14 +150,14 @@ AssertionResult DescramblerTests::removePid(DemuxPid pid, sp optionalSo AssertionResult DescramblerTests::closeDescrambler() { Result status; - if (mDescrambler) { + if (!mDescrambler) { ALOGW("[vts] Descrambler is not opened yet."); return failure(); } status = mDescrambler->close(); mDescrambler = nullptr; - if (status == Result::SUCCESS) { + if (status != Result::SUCCESS) { ALOGW("[vts] close Descrambler failed."); return failure(); } diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp index 9318bc4d70..078f5df391 100644 --- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp +++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp @@ -292,18 +292,18 @@ void TunerDescramblerHidlTest::scrambledBroadcastTest(set m ASSERT_TRUE(mFilterTests.configFilter((*config).settings, filterId)); filterIds.insert(filterId); } - mDescramblerTests.openDescrambler(demuxId); + ASSERT_TRUE(mDescramblerTests.openDescrambler(demuxId)); TunerKeyToken token; ASSERT_TRUE(mDescramblerTests.getKeyToken(descConfig.casSystemId, descConfig.provisionStr, descConfig.hidlPvtData, token)); - mDescramblerTests.setKeyToken(token); + ASSERT_TRUE(mDescramblerTests.setKeyToken(token)); vector pids; DemuxPid pid; for (config = mediaFilterConfs.begin(); config != mediaFilterConfs.end(); config++) { ASSERT_TRUE(mDescramblerTests.getDemuxPidFromFilterSettings((*config).type, (*config).settings, pid)); pids.push_back(pid); - mDescramblerTests.addPid(pid, nullptr); + ASSERT_TRUE(mDescramblerTests.addPid(pid, nullptr)); } for (id = filterIds.begin(); id != filterIds.end(); id++) { ASSERT_TRUE(mFilterTests.startFilter(*id)); @@ -316,9 +316,9 @@ void TunerDescramblerHidlTest::scrambledBroadcastTest(set m ASSERT_TRUE(mFilterTests.stopFilter(*id)); } for (auto pid : pids) { - mDescramblerTests.removePid(pid, nullptr); + ASSERT_TRUE(mDescramblerTests.removePid(pid, nullptr)); } - mDescramblerTests.closeDescrambler(); + ASSERT_TRUE(mDescramblerTests.closeDescrambler()); for (id = filterIds.begin(); id != filterIds.end(); id++) { ASSERT_TRUE(mFilterTests.closeFilter(*id)); } @@ -410,9 +410,9 @@ TEST_P(TunerDemuxHidlTest, getAvSyncTime) { filterArray[TS_PCR0].bufferSize)); ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(pcrFilterId)); ASSERT_TRUE(mFilterTests.configFilter(filterArray[TS_PCR0].settings, pcrFilterId)); - mDemuxTests.getAvSyncId(mediaFilter, avSyncHwId); + ASSERT_TRUE(mDemuxTests.getAvSyncId(mediaFilter, avSyncHwId)); ASSERT_TRUE(pcrFilterId == avSyncHwId); - mDemuxTests.getAvSyncTime(pcrFilterId); + ASSERT_TRUE(mDemuxTests.getAvSyncTime(pcrFilterId)); ASSERT_TRUE(mFilterTests.closeFilter(pcrFilterId)); ASSERT_TRUE(mFilterTests.closeFilter(mediaFilterId)); ASSERT_TRUE(mDemuxTests.closeDemux()); @@ -575,8 +575,8 @@ TEST_P(TunerDescramblerHidlTest, CreateDescrambler) { ASSERT_TRUE(mFrontendTests.setFrontendCallback()); ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); - mDescramblerTests.openDescrambler(demuxId); - mDescramblerTests.closeDescrambler(); + ASSERT_TRUE(mDescramblerTests.openDescrambler(demuxId)); + ASSERT_TRUE(mDescramblerTests.closeDescrambler()); ASSERT_TRUE(mDemuxTests.closeDemux()); ASSERT_TRUE(mFrontendTests.closeFrontend()); } -- GitLab From 06c2c0dea112bfa676569f927d2de21e55fdddfc Mon Sep 17 00:00:00 2001 From: chrisweir Date: Thu, 18 Jun 2020 16:06:40 -0700 Subject: [PATCH 069/790] Extend libnetdevice for Netlink Proxy Add some additional generic send/receive functionality for NetlinkSocket. Bug: 155190864 Test: Manual Change-Id: I7a882fa642553c61e0b2b3a32638a309089c6d22 --- .../default/libnetdevice/NetlinkSocket.cpp | 93 ++++++++++++++++--- .../include/libnetdevice/NetlinkSocket.h | 57 +++++++++++- .../libnetdevice/include/libnetdevice/nlbuf.h | 6 ++ .../include/libnetdevice/printer.h | 12 ++- .../can/1.0/default/libnetdevice/printer.cpp | 18 ++-- .../libnetdevice/protocols/common/Error.cpp | 2 +- 6 files changed, 161 insertions(+), 27 deletions(-) diff --git a/automotive/can/1.0/default/libnetdevice/NetlinkSocket.cpp b/automotive/can/1.0/default/libnetdevice/NetlinkSocket.cpp index 6146d5e4a4..633ed82976 100644 --- a/automotive/can/1.0/default/libnetdevice/NetlinkSocket.cpp +++ b/automotive/can/1.0/default/libnetdevice/NetlinkSocket.cpp @@ -27,7 +27,8 @@ namespace android::netdevice { */ static constexpr bool kSuperVerbose = false; -NetlinkSocket::NetlinkSocket(int protocol) : mProtocol(protocol) { +NetlinkSocket::NetlinkSocket(int protocol, unsigned int pid, uint32_t groups) + : mProtocol(protocol) { mFd.reset(socket(AF_NETLINK, SOCK_RAW, protocol)); if (!mFd.ok()) { PLOG(ERROR) << "Can't open Netlink socket"; @@ -35,21 +36,23 @@ NetlinkSocket::NetlinkSocket(int protocol) : mProtocol(protocol) { return; } - struct sockaddr_nl sa = {}; + sockaddr_nl sa = {}; sa.nl_family = AF_NETLINK; + sa.nl_pid = pid; + sa.nl_groups = groups; - if (bind(mFd.get(), reinterpret_cast(&sa), sizeof(sa)) < 0) { + if (bind(mFd.get(), reinterpret_cast(&sa), sizeof(sa)) < 0) { PLOG(ERROR) << "Can't bind Netlink socket"; mFd.reset(); mFailed = true; } } -bool NetlinkSocket::send(struct nlmsghdr* nlmsg, size_t totalLen) { +bool NetlinkSocket::send(nlmsghdr* nlmsg, size_t totalLen) { if constexpr (kSuperVerbose) { nlmsg->nlmsg_seq = mSeq; - LOG(VERBOSE) << (mFailed ? "(not)" : "") - << "sending Netlink message: " << toString(nlmsg, totalLen, mProtocol); + LOG(VERBOSE) << (mFailed ? "(not) " : "") + << "sending Netlink message: " << toString({nlmsg, totalLen}, mProtocol); } if (mFailed) return false; @@ -58,12 +61,12 @@ bool NetlinkSocket::send(struct nlmsghdr* nlmsg, size_t totalLen) { nlmsg->nlmsg_seq = mSeq++; nlmsg->nlmsg_flags |= NLM_F_ACK; - struct iovec iov = {nlmsg, nlmsg->nlmsg_len}; + iovec iov = {nlmsg, nlmsg->nlmsg_len}; - struct sockaddr_nl sa = {}; + sockaddr_nl sa = {}; sa.nl_family = AF_NETLINK; - struct msghdr msg = {}; + msghdr msg = {}; msg.msg_name = &sa; msg.msg_namelen = sizeof(sa); msg.msg_iov = &iov; @@ -76,15 +79,65 @@ bool NetlinkSocket::send(struct nlmsghdr* nlmsg, size_t totalLen) { return true; } +bool NetlinkSocket::send(const nlbuf& msg, const sockaddr_nl& sa) { + if constexpr (kSuperVerbose) { + LOG(VERBOSE) << (mFailed ? "(not) " : "") + << "sending Netlink message: " << toString(msg, mProtocol); + } + + if (mFailed) return false; + const auto rawMsg = msg.getRaw(); + const auto bytesSent = sendto(mFd.get(), rawMsg.ptr(), rawMsg.len(), 0, + reinterpret_cast(&sa), sizeof(sa)); + if (bytesSent < 0) { + PLOG(ERROR) << "Can't send Netlink message"; + return false; + } + return true; +} + +std::optional> NetlinkSocket::receive(void* buf, size_t bufLen) { + sockaddr_nl sa = {}; + return receive(buf, bufLen, sa); +} + +std::optional> NetlinkSocket::receive(void* buf, size_t bufLen, sockaddr_nl& sa) { + if (mFailed) return std::nullopt; + + socklen_t saLen = sizeof(sa); + if (bufLen == 0) { + LOG(ERROR) << "Receive buffer has zero size!"; + return std::nullopt; + } + const auto bytesReceived = + recvfrom(mFd.get(), buf, bufLen, MSG_TRUNC, reinterpret_cast(&sa), &saLen); + if (bytesReceived <= 0) { + PLOG(ERROR) << "Failed to receive Netlink message"; + return std::nullopt; + } else if (unsigned(bytesReceived) > bufLen) { + PLOG(ERROR) << "Received data larger than the receive buffer! " << bytesReceived << " > " + << bufLen; + return std::nullopt; + } + + nlbuf msg(reinterpret_cast(buf), bytesReceived); + if constexpr (kSuperVerbose) { + LOG(VERBOSE) << "received " << toString(msg, mProtocol); + } + return msg; +} + +/* TODO(161389935): Migrate receiveAck to use nlmsg<> internally. Possibly reuse + * NetlinkSocket::receive(). */ bool NetlinkSocket::receiveAck() { if (mFailed) return false; char buf[8192]; - struct sockaddr_nl sa; - struct iovec iov = {buf, sizeof(buf)}; + sockaddr_nl sa; + iovec iov = {buf, sizeof(buf)}; - struct msghdr msg = {}; + msghdr msg = {}; msg.msg_name = &sa; msg.msg_namelen = sizeof(sa); msg.msg_iov = &iov; @@ -102,11 +155,11 @@ bool NetlinkSocket::receiveAck() { return false; } - for (auto nlmsg = reinterpret_cast(buf); NLMSG_OK(nlmsg, remainingLen); + for (auto nlmsg = reinterpret_cast(buf); NLMSG_OK(nlmsg, remainingLen); nlmsg = NLMSG_NEXT(nlmsg, remainingLen)) { if constexpr (kSuperVerbose) { LOG(VERBOSE) << "received Netlink response: " - << toString(nlmsg, sizeof(buf), mProtocol); + << toString({nlmsg, nlmsg->nlmsg_len}, mProtocol); } // We're looking for error/ack message only, ignoring others. @@ -116,7 +169,7 @@ bool NetlinkSocket::receiveAck() { } // Found error/ack message, return status. - auto nlerr = reinterpret_cast(NLMSG_DATA(nlmsg)); + const auto nlerr = reinterpret_cast(NLMSG_DATA(nlmsg)); if (nlerr->error != 0) { LOG(ERROR) << "Received Netlink error message: " << nlerr->error; return false; @@ -127,4 +180,14 @@ bool NetlinkSocket::receiveAck() { return false; } +std::optional NetlinkSocket::getSocketPid() { + sockaddr_nl sa = {}; + socklen_t sasize = sizeof(sa); + if (getsockname(mFd.get(), reinterpret_cast(&sa), &sasize) < 0) { + PLOG(ERROR) << "Failed to getsockname() for netlink_fd!"; + return std::nullopt; + } + return sa.nl_pid; +} + } // namespace android::netdevice diff --git a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/NetlinkSocket.h b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/NetlinkSocket.h index 8900ff776f..826b6b88de 100644 --- a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/NetlinkSocket.h +++ b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/NetlinkSocket.h @@ -19,9 +19,12 @@ #include #include #include +#include #include +#include + namespace android::netdevice { /** @@ -31,12 +34,23 @@ namespace android::netdevice { * use multiple instances over multiple threads. */ struct NetlinkSocket { - NetlinkSocket(int protocol); + /** + * NetlinkSocket constructor. + * + * \param protocol the Netlink protocol to use. + * \param pid port id. Default value of 0 allows the kernel to assign us a unique pid. (NOTE: + * this is NOT the same as process id!) + * \param groups Netlink multicast groups to listen to. This is a 32-bit bitfield, where each + * bit is a different group. Default value of 0 means no groups are selected. See man netlink.7 + * for more details. + */ + NetlinkSocket(int protocol, unsigned int pid = 0, uint32_t groups = 0); /** - * Send Netlink message to Kernel. + * Send Netlink message to Kernel. The sequence number will be automatically incremented, and + * the NLM_F_ACK (request ACK) flag will be set. * - * \param msg Message to send, nlmsg_seq will be set to next sequence number + * \param msg Message to send. * \return true, if succeeded */ template @@ -45,6 +59,34 @@ struct NetlinkSocket { return send(req.header(), req.totalLength); } + /** + * Send Netlink message. The message will be sent as is, without any modification. + * + * \param msg Message to send. + * \param sa Destination address. + * \return true, if succeeded + */ + bool send(const nlbuf& msg, const sockaddr_nl& sa); + + /** + * Receive Netlink data. + * + * \param buf buffer to hold message data. + * \param bufLen length of buf. + * \return nlbuf with message data, std::nullopt on error. + */ + std::optional> receive(void* buf, size_t bufLen); + + /** + * Receive Netlink data with address info. + * + * \param buf buffer to hold message data. + * \param bufLen length of buf. + * \param sa Blank struct that recvfrom will populate with address info. + * \return nlbuf with message data, std::nullopt on error. + */ + std::optional> receive(void* buf, size_t bufLen, sockaddr_nl& sa); + /** * Receive Netlink ACK message from Kernel. * @@ -52,6 +94,13 @@ struct NetlinkSocket { */ bool receiveAck(); + /** + * Gets the PID assigned to mFd. + * + * \return pid that mSocket is bound to. + */ + std::optional getSocketPid(); + private: const int mProtocol; @@ -59,7 +108,7 @@ struct NetlinkSocket { base::unique_fd mFd; bool mFailed = false; - bool send(struct nlmsghdr* msg, size_t totalLen); + bool send(nlmsghdr* msg, size_t totalLen); DISALLOW_COPY_AND_ASSIGN(NetlinkSocket); }; diff --git a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/nlbuf.h b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/nlbuf.h index f7e53be48e..17815f9b7b 100644 --- a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/nlbuf.h +++ b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/nlbuf.h @@ -53,6 +53,12 @@ class nlbuf { static constexpr size_t hdrlen = align(sizeof(T)); public: + /** + * Constructor for nlbuf. + * + * \param data A pointer to the data the nlbuf wraps. + * \param bufferLen Length of buffer. + */ nlbuf(const T* data, size_t bufferLen) : mData(data), mBufferEnd(pointerAdd(data, bufferLen)) {} const T* operator->() const { diff --git a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/printer.h b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/printer.h index efeb6b16b9..071fa63612 100644 --- a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/printer.h +++ b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/printer.h @@ -16,12 +16,22 @@ #pragma once +#include + #include #include namespace android::netdevice { -std::string toString(const nlmsghdr* hdr, size_t bufLen, int protocol); +/** + * Stringify a Netlink message. + * + * \param hdr Pointer to the message(s) to print. + * \param protocol Which Netlink protocol hdr uses. + * \param printPayload True will stringify message data, false will only stringify the header(s). + * \return Stringified message. + */ +std::string toString(const nlbuf hdr, int protocol, bool printPayload = false); } // namespace android::netdevice diff --git a/automotive/can/1.0/default/libnetdevice/printer.cpp b/automotive/can/1.0/default/libnetdevice/printer.cpp index a8715da188..0076dd68cf 100644 --- a/automotive/can/1.0/default/libnetdevice/printer.cpp +++ b/automotive/can/1.0/default/libnetdevice/printer.cpp @@ -62,13 +62,20 @@ static void flagsToStream(std::stringstream& ss, __u16 nlmsg_flags) { } static void toStream(std::stringstream& ss, const nlbuf data) { + const auto rawData = data.getRaw(); + const auto dataLen = rawData.len(); ss << std::hex; + if (dataLen > 16) ss << std::endl << " 0000 "; int i = 0; - for (const auto byte : data.getRaw()) { + for (const auto byte : rawData) { if (i++ > 0) ss << ' '; ss << std::setw(2) << unsigned(byte); + if (i % 16 == 0) { + ss << std::endl << ' ' << std::dec << std::setw(4) << i << std::hex; + } } ss << std::dec; + if (dataLen > 16) ss << std::endl; } static void toStream(std::stringstream& ss, const nlbuf attr, @@ -105,7 +112,7 @@ static void toStream(std::stringstream& ss, const nlbuf attr, } } -static std::string toString(const nlbuf hdr, int protocol) { +std::string toString(const nlbuf hdr, int protocol, bool printPayload) { if (!hdr.firstOk()) return "nlmsg{buffer overflow}"; std::stringstream ss; @@ -133,10 +140,13 @@ static std::string toString(const nlbuf hdr, int protocol) { } if (hdr->nlmsg_seq != 0) ss << ", seq=" << hdr->nlmsg_seq; if (hdr->nlmsg_pid != 0) ss << ", pid=" << hdr->nlmsg_pid; + ss << ", len=" << hdr->nlmsg_len; ss << ", crc=" << std::hex << std::setw(4) << crc16(hdr.data()) << std::dec; ss << "} "; + if (!printPayload) return ss.str(); + if (!msgDescMaybe.has_value()) { toStream(ss, hdr.data()); } else { @@ -161,8 +171,4 @@ static std::string toString(const nlbuf hdr, int protocol) { return ss.str(); } -std::string toString(const nlmsghdr* hdr, size_t bufLen, int protocol) { - return toString({hdr, bufLen}, protocol); -} - } // namespace android::netdevice diff --git a/automotive/can/1.0/default/libnetdevice/protocols/common/Error.cpp b/automotive/can/1.0/default/libnetdevice/protocols/common/Error.cpp index d42a50ac57..25ae680227 100644 --- a/automotive/can/1.0/default/libnetdevice/protocols/common/Error.cpp +++ b/automotive/can/1.0/default/libnetdevice/protocols/common/Error.cpp @@ -30,7 +30,7 @@ Error::Error(int protocol) : MessageDefinition("nlmsg", { void Error::toStream(std::stringstream& ss, const nlmsgerr& data) const { ss << "nlmsgerr{error=" << data.error - << ", msg=" << toString(&data.msg, sizeof(data.msg), mProtocol) << "}"; + << ", msg=" << toString({&data.msg, sizeof(data.msg)}, mProtocol) << "}"; } } // namespace android::netdevice::protocols::base -- GitLab From 2aa1a124fc62bd4375fe3771e6ac5d370e446df3 Mon Sep 17 00:00:00 2001 From: Tomasz Wasilczyk Date: Mon, 20 Jul 2020 14:03:05 -0700 Subject: [PATCH 070/790] Replace useCanSockets hack with flexible per-process domain selection Bug: 158011272 Test: manual Change-Id: I29d88a42e2309483a740cde9f9a463d83c7a560c --- .../can/1.0/default/libnetdevice/common.cpp | 2 -- .../can/1.0/default/libnetdevice/common.h | 15 ---------- .../can/1.0/default/libnetdevice/ifreqs.cpp | 28 +++++++++++++++++-- .../can/1.0/default/libnetdevice/ifreqs.h | 5 ++++ .../include/libnetdevice/libnetdevice.h | 11 ++++---- .../1.0/default/libnetdevice/libnetdevice.cpp | 4 +-- automotive/can/1.0/default/service.cpp | 2 +- 7 files changed, 39 insertions(+), 28 deletions(-) diff --git a/automotive/can/1.0/default/libnetdevice/common.cpp b/automotive/can/1.0/default/libnetdevice/common.cpp index 387c91f81a..f2968fc6ec 100644 --- a/automotive/can/1.0/default/libnetdevice/common.cpp +++ b/automotive/can/1.0/default/libnetdevice/common.cpp @@ -22,8 +22,6 @@ namespace android::netdevice { -socketparams::Params socketparams::current = general; - unsigned int nametoindex(const std::string& ifname) { const auto ifidx = if_nametoindex(ifname.c_str()); if (ifidx != 0) return ifidx; diff --git a/automotive/can/1.0/default/libnetdevice/common.h b/automotive/can/1.0/default/libnetdevice/common.h index b4f91bd1bb..1e0d5b7eed 100644 --- a/automotive/can/1.0/default/libnetdevice/common.h +++ b/automotive/can/1.0/default/libnetdevice/common.h @@ -25,21 +25,6 @@ namespace android::netdevice { -namespace socketparams { - -struct Params { - int domain; - int type; - int protocol; -}; - -constexpr Params general = {AF_INET, SOCK_DGRAM, 0}; -constexpr Params can = {PF_CAN, SOCK_RAW, CAN_RAW}; - -extern Params current; - -} // namespace socketparams - /** * Returns the index of a given network interface. * diff --git a/automotive/can/1.0/default/libnetdevice/ifreqs.cpp b/automotive/can/1.0/default/libnetdevice/ifreqs.cpp index 9335021714..8df6434796 100644 --- a/automotive/can/1.0/default/libnetdevice/ifreqs.cpp +++ b/automotive/can/1.0/default/libnetdevice/ifreqs.cpp @@ -21,11 +21,35 @@ #include #include +#include + namespace android::netdevice::ifreqs { +static constexpr int defaultSocketDomain = AF_INET; +std::atomic_int socketDomain = defaultSocketDomain; + +struct SocketParams { + int domain; + int type; + int protocol; +}; + +static const std::map socketParams = { + {AF_INET, {AF_INET, SOCK_DGRAM, 0}}, + {AF_CAN, {AF_CAN, SOCK_RAW, CAN_RAW}}, +}; + +static SocketParams getSocketParams(int domain) { + if (socketParams.count(domain)) return socketParams.find(domain)->second; + + auto params = socketParams.find(defaultSocketDomain)->second; + params.domain = domain; + return params; +} + bool send(unsigned long request, struct ifreq& ifr) { - base::unique_fd sock(socket(socketparams::current.domain, socketparams::current.type, - socketparams::current.protocol)); + const auto sp = getSocketParams(socketDomain); + base::unique_fd sock(socket(sp.domain, sp.type, sp.protocol)); if (!sock.ok()) { LOG(ERROR) << "Can't create socket"; return false; diff --git a/automotive/can/1.0/default/libnetdevice/ifreqs.h b/automotive/can/1.0/default/libnetdevice/ifreqs.h index 25a40a69a9..74e58775b6 100644 --- a/automotive/can/1.0/default/libnetdevice/ifreqs.h +++ b/automotive/can/1.0/default/libnetdevice/ifreqs.h @@ -22,6 +22,11 @@ namespace android::netdevice::ifreqs { +/** + * \see useSocketDomain() + */ +extern std::atomic_int socketDomain; + /** * Sends ioctl interface request. * diff --git a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/libnetdevice.h b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/libnetdevice.h index 037618a2e6..9a26ff17be 100644 --- a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/libnetdevice.h +++ b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/libnetdevice.h @@ -27,15 +27,14 @@ namespace android::netdevice { typedef std::array hwaddr_t; /** - * Configures libnetdevice to use PF_CAN sockets instead of AF_INET, + * Configures libnetdevice to use other socket domain than AF_INET, * what requires less permissive SEPolicy rules for a given process. * - * In such case, the process would only be able to control CAN interfaces. - * - * TODO(b/158011272): consider less hacky solution - * \param yes true to use CAN sockets, false for general sockets + * In such case, the process would only be able to control interfaces of a given kind. + + * \param domain Socket domain to use (e.g. AF_CAN), see socket(2) for details */ -void useCanSockets(bool yes); +void useSocketDomain(int domain); /** * Checks, if the network interface exists. diff --git a/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp b/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp index 4bba5f635e..4293cad0db 100644 --- a/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp +++ b/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp @@ -28,8 +28,8 @@ namespace android::netdevice { -void useCanSockets(bool yes) { - socketparams::current = yes ? socketparams::can : socketparams::general; +void useSocketDomain(int domain) { + ifreqs::socketDomain = domain; } bool exists(std::string ifname) { diff --git a/automotive/can/1.0/default/service.cpp b/automotive/can/1.0/default/service.cpp index b5801c0880..9a9d3226f0 100644 --- a/automotive/can/1.0/default/service.cpp +++ b/automotive/can/1.0/default/service.cpp @@ -28,7 +28,7 @@ static void canControllerService() { configureRpcThreadpool(16, true); LOG(DEBUG) << "CAN controller service starting..."; - netdevice::useCanSockets(true); + netdevice::useSocketDomain(AF_CAN); sp canController(new CanController); if (canController->registerAsService("socketcan") != OK) { -- GitLab From 3e2de6cc22adb374d2d13b38e2d6f73e7a5000a9 Mon Sep 17 00:00:00 2001 From: shubang Date: Mon, 20 Jul 2020 19:26:36 -0700 Subject: [PATCH 071/790] Tuner HAL: fix a memcpy issue Bug: 161481210 Test: cuttlefisih + TIS Change-Id: I79274970ddd8ed8b7b97f56ca4200499fdee1b38 --- tv/tuner/1.0/default/Dvr.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tv/tuner/1.0/default/Dvr.cpp b/tv/tuner/1.0/default/Dvr.cpp index bb3b087ceb..c3edac973e 100644 --- a/tv/tuner/1.0/default/Dvr.cpp +++ b/tv/tuner/1.0/default/Dvr.cpp @@ -364,7 +364,7 @@ bool Dvr::processEsDataOnPlayback(bool isVirtualFrontend, bool isRecording) { for (int i = 0; i < totalFrames; i++) { frameData.resize(esMeta[i].len); pid = esMeta[i].isAudio ? audioPid : videoPid; - memcpy(dataOutputBuffer.data() + esMeta[i].startIndex, frameData.data(), esMeta[i].len); + memcpy(frameData.data(), dataOutputBuffer.data() + esMeta[i].startIndex, esMeta[i].len); // Send to the media filter if (isVirtualFrontend && isRecording) { // TODO validate record @@ -479,4 +479,4 @@ bool Dvr::removePlaybackFilter(uint32_t filterId) { } // namespace tuner } // namespace tv } // namespace hardware -} // namespace android \ No newline at end of file +} // namespace android -- GitLab From d460df3f3b8ee46bc712dc99e3fe46d9b4f1e2a3 Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Fri, 29 Nov 2019 17:31:22 +0200 Subject: [PATCH 072/790] wifi: upgrade wifi interface to 1.5 Only a root interface is added and update relevant code. Bug: 160834354 Test: atest VtsHalWifiV1_0TargetTest VtsHalWifiNanV1_0TargetTest VtsHalWifiApV1_0TargetTest \ VtsHalWifiV1_1TargetTest \ VtsHalWifiV1_2TargetTest VtsHalWifiNanV1_2TargetTest \ VtsHalWifiV1_3TargetTest \ VtsHalWifiApV1_4TargetTest VtsHalWifiNanV1_4TargetTest VtsHalWifiRttV1_4TargetTest Change-Id: Ifdffa3a6996eca1d3c4b499258896cdfe5eb9c87 --- .../compatibility_matrix.current.xml | 2 +- wifi/1.5/Android.bp | 21 +++++ wifi/1.5/IWifi.hal | 27 ++++++ wifi/{1.4 => 1.5}/default/Android.mk | 10 ++- wifi/{1.4 => 1.5}/default/OWNERS | 0 wifi/{1.4 => 1.5}/default/THREADING.README | 0 .../android.hardware.wifi@1.0-service-lazy.rc | 0 .../android.hardware.wifi@1.0-service.rc | 1 + .../android.hardware.wifi@1.0-service.xml | 2 +- .../{1.4 => 1.5}/default/hidl_callback_util.h | 4 +- wifi/{1.4 => 1.5}/default/hidl_return_util.h | 4 +- .../{1.4 => 1.5}/default/hidl_struct_util.cpp | 90 ++++++++++--------- wifi/{1.4 => 1.5}/default/hidl_struct_util.h | 25 +++--- wifi/{1.4 => 1.5}/default/hidl_sync_util.cpp | 4 +- wifi/{1.4 => 1.5}/default/hidl_sync_util.h | 4 +- wifi/{1.4 => 1.5}/default/ringbuffer.cpp | 4 +- wifi/{1.4 => 1.5}/default/ringbuffer.h | 4 +- wifi/{1.4 => 1.5}/default/service.cpp | 12 +-- .../tests/hidl_struct_util_unit_tests.cpp | 38 ++++---- wifi/{1.4 => 1.5}/default/tests/main.cpp | 0 .../default/tests/mock_interface_tool.cpp | 0 .../default/tests/mock_interface_tool.h | 0 .../default/tests/mock_wifi_feature_flags.cpp | 4 +- .../default/tests/mock_wifi_feature_flags.h | 4 +- .../default/tests/mock_wifi_iface_util.cpp | 4 +- .../default/tests/mock_wifi_iface_util.h | 4 +- .../default/tests/mock_wifi_legacy_hal.cpp | 4 +- .../default/tests/mock_wifi_legacy_hal.h | 4 +- .../tests/mock_wifi_mode_controller.cpp | 4 +- .../default/tests/mock_wifi_mode_controller.h | 4 +- .../default/tests/ringbuffer_unit_tests.cpp | 4 +- wifi/{1.4 => 1.5}/default/tests/runtests.sh | 0 .../default/tests/wifi_chip_unit_tests.cpp | 28 +++--- .../tests/wifi_iface_util_unit_tests.cpp | 4 +- .../tests/wifi_nan_iface_unit_tests.cpp | 4 +- wifi/{1.4 => 1.5}/default/wifi.cpp | 7 +- wifi/{1.4 => 1.5}/default/wifi.h | 10 +-- wifi/{1.4 => 1.5}/default/wifi_ap_iface.cpp | 4 +- wifi/{1.4 => 1.5}/default/wifi_ap_iface.h | 4 +- wifi/{1.4 => 1.5}/default/wifi_chip.cpp | 31 +++---- wifi/{1.4 => 1.5}/default/wifi_chip.h | 24 ++--- .../default/wifi_feature_flags.cpp | 4 +- .../{1.4 => 1.5}/default/wifi_feature_flags.h | 4 +- wifi/{1.4 => 1.5}/default/wifi_iface_util.cpp | 4 +- wifi/{1.4 => 1.5}/default/wifi_iface_util.h | 4 +- wifi/{1.4 => 1.5}/default/wifi_legacy_hal.cpp | 4 +- wifi/{1.4 => 1.5}/default/wifi_legacy_hal.h | 4 +- .../default/wifi_legacy_hal_stubs.cpp | 4 +- .../default/wifi_legacy_hal_stubs.h | 4 +- .../default/wifi_mode_controller.cpp | 4 +- .../default/wifi_mode_controller.h | 4 +- wifi/{1.4 => 1.5}/default/wifi_nan_iface.cpp | 12 +-- wifi/{1.4 => 1.5}/default/wifi_nan_iface.h | 16 ++-- wifi/{1.4 => 1.5}/default/wifi_p2p_iface.cpp | 4 +- wifi/{1.4 => 1.5}/default/wifi_p2p_iface.h | 4 +- .../default/wifi_rtt_controller.cpp | 28 +++--- .../default/wifi_rtt_controller.h | 24 ++--- wifi/{1.4 => 1.5}/default/wifi_sta_iface.cpp | 4 +- wifi/{1.4 => 1.5}/default/wifi_sta_iface.h | 4 +- .../{1.4 => 1.5}/default/wifi_status_util.cpp | 4 +- wifi/{1.4 => 1.5}/default/wifi_status_util.h | 4 +- 61 files changed, 306 insertions(+), 242 deletions(-) create mode 100644 wifi/1.5/Android.bp create mode 100644 wifi/1.5/IWifi.hal rename wifi/{1.4 => 1.5}/default/Android.mk (95%) rename wifi/{1.4 => 1.5}/default/OWNERS (100%) rename wifi/{1.4 => 1.5}/default/THREADING.README (100%) rename wifi/{1.4 => 1.5}/default/android.hardware.wifi@1.0-service-lazy.rc (100%) rename wifi/{1.4 => 1.5}/default/android.hardware.wifi@1.0-service.rc (89%) rename wifi/{1.4 => 1.5}/default/android.hardware.wifi@1.0-service.xml (90%) rename wifi/{1.4 => 1.5}/default/hidl_callback_util.h (99%) rename wifi/{1.4 => 1.5}/default/hidl_return_util.h (99%) rename wifi/{1.4 => 1.5}/default/hidl_struct_util.cpp (97%) rename wifi/{1.4 => 1.5}/default/hidl_struct_util.h (93%) rename wifi/{1.4 => 1.5}/default/hidl_sync_util.cpp (96%) rename wifi/{1.4 => 1.5}/default/hidl_sync_util.h (96%) rename wifi/{1.4 => 1.5}/default/ringbuffer.cpp (97%) rename wifi/{1.4 => 1.5}/default/ringbuffer.h (97%) rename wifi/{1.4 => 1.5}/default/service.cpp (85%) rename wifi/{1.4 => 1.5}/default/tests/hidl_struct_util_unit_tests.cpp (92%) rename wifi/{1.4 => 1.5}/default/tests/main.cpp (100%) rename wifi/{1.4 => 1.5}/default/tests/mock_interface_tool.cpp (100%) rename wifi/{1.4 => 1.5}/default/tests/mock_interface_tool.h (100%) rename wifi/{1.4 => 1.5}/default/tests/mock_wifi_feature_flags.cpp (96%) rename wifi/{1.4 => 1.5}/default/tests/mock_wifi_feature_flags.h (97%) rename wifi/{1.4 => 1.5}/default/tests/mock_wifi_iface_util.cpp (96%) rename wifi/{1.4 => 1.5}/default/tests/mock_wifi_iface_util.h (97%) rename wifi/{1.4 => 1.5}/default/tests/mock_wifi_legacy_hal.cpp (96%) rename wifi/{1.4 => 1.5}/default/tests/mock_wifi_legacy_hal.h (98%) rename wifi/{1.4 => 1.5}/default/tests/mock_wifi_mode_controller.cpp (96%) rename wifi/{1.4 => 1.5}/default/tests/mock_wifi_mode_controller.h (97%) rename wifi/{1.4 => 1.5}/default/tests/ringbuffer_unit_tests.cpp (98%) rename wifi/{1.4 => 1.5}/default/tests/runtests.sh (100%) rename wifi/{1.4 => 1.5}/default/tests/wifi_chip_unit_tests.cpp (98%) rename wifi/{1.4 => 1.5}/default/tests/wifi_iface_util_unit_tests.cpp (98%) rename wifi/{1.4 => 1.5}/default/tests/wifi_nan_iface_unit_tests.cpp (99%) rename wifi/{1.4 => 1.5}/default/wifi.cpp (98%) rename wifi/{1.4 => 1.5}/default/wifi.h (94%) rename wifi/{1.4 => 1.5}/default/wifi_ap_iface.cpp (99%) rename wifi/{1.4 => 1.5}/default/wifi_ap_iface.h (98%) rename wifi/{1.4 => 1.5}/default/wifi_chip.cpp (98%) rename wifi/{1.4 => 1.5}/default/wifi_chip.h (95%) rename wifi/{1.4 => 1.5}/default/wifi_feature_flags.cpp (99%) rename wifi/{1.4 => 1.5}/default/wifi_feature_flags.h (97%) rename wifi/{1.4 => 1.5}/default/wifi_iface_util.cpp (99%) rename wifi/{1.4 => 1.5}/default/wifi_iface_util.h (98%) rename wifi/{1.4 => 1.5}/default/wifi_legacy_hal.cpp (99%) rename wifi/{1.4 => 1.5}/default/wifi_legacy_hal.h (99%) rename wifi/{1.4 => 1.5}/default/wifi_legacy_hal_stubs.cpp (99%) rename wifi/{1.4 => 1.5}/default/wifi_legacy_hal_stubs.h (96%) rename wifi/{1.4 => 1.5}/default/wifi_mode_controller.cpp (98%) rename wifi/{1.4 => 1.5}/default/wifi_mode_controller.h (98%) rename wifi/{1.4 => 1.5}/default/wifi_nan_iface.cpp (99%) rename wifi/{1.4 => 1.5}/default/wifi_nan_iface.h (95%) rename wifi/{1.4 => 1.5}/default/wifi_p2p_iface.cpp (98%) rename wifi/{1.4 => 1.5}/default/wifi_p2p_iface.h (98%) rename wifi/{1.4 => 1.5}/default/wifi_rtt_controller.cpp (95%) rename wifi/{1.4 => 1.5}/default/wifi_rtt_controller.h (87%) rename wifi/{1.4 => 1.5}/default/wifi_sta_iface.cpp (99%) rename wifi/{1.4 => 1.5}/default/wifi_sta_iface.h (99%) rename wifi/{1.4 => 1.5}/default/wifi_status_util.cpp (99%) rename wifi/{1.4 => 1.5}/default/wifi_status_util.h (97%) diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index cfee298c6d..382b282dd3 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -529,7 +529,7 @@ android.hardware.wifi - 1.0-4 + 1.0-5 IWifi default diff --git a/wifi/1.5/Android.bp b/wifi/1.5/Android.bp new file mode 100644 index 0000000000..37a1cf31a4 --- /dev/null +++ b/wifi/1.5/Android.bp @@ -0,0 +1,21 @@ +// This file is autogenerated by hidl-gen -Landroidbp. + +hidl_interface { + name: "android.hardware.wifi@1.5", + 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.hidl.base@1.0", + ], + gen_java: true, + apex_available: [ + "com.android.wifi", + ], +} diff --git a/wifi/1.5/IWifi.hal b/wifi/1.5/IWifi.hal new file mode 100644 index 0000000000..66d0a9c2f9 --- /dev/null +++ b/wifi/1.5/IWifi.hal @@ -0,0 +1,27 @@ +/* + * 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. + */ + +package android.hardware.wifi@1.5; + +import @1.4::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.4::IWifi {}; diff --git a/wifi/1.4/default/Android.mk b/wifi/1.5/default/Android.mk similarity index 95% rename from wifi/1.4/default/Android.mk rename to wifi/1.5/default/Android.mk index 6be7dad59e..236dae23e0 100644 --- a/wifi/1.4/default/Android.mk +++ b/wifi/1.5/default/Android.mk @@ -71,7 +71,8 @@ LOCAL_SHARED_LIBRARIES := \ android.hardware.wifi@1.1 \ android.hardware.wifi@1.2 \ android.hardware.wifi@1.3 \ - android.hardware.wifi@1.4 + android.hardware.wifi@1.4 \ + android.hardware.wifi@1.5 LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH) include $(BUILD_STATIC_LIBRARY) @@ -99,7 +100,8 @@ LOCAL_SHARED_LIBRARIES := \ android.hardware.wifi@1.1 \ android.hardware.wifi@1.2 \ android.hardware.wifi@1.3 \ - android.hardware.wifi@1.4 + android.hardware.wifi@1.4 \ + android.hardware.wifi@1.5 LOCAL_STATIC_LIBRARIES := \ android.hardware.wifi@1.0-service-lib LOCAL_INIT_RC := android.hardware.wifi@1.0-service.rc @@ -131,7 +133,8 @@ LOCAL_SHARED_LIBRARIES := \ android.hardware.wifi@1.1 \ android.hardware.wifi@1.2 \ android.hardware.wifi@1.3 \ - android.hardware.wifi@1.4 + android.hardware.wifi@1.4 \ + android.hardware.wifi@1.5 LOCAL_STATIC_LIBRARIES := \ android.hardware.wifi@1.0-service-lib LOCAL_INIT_RC := android.hardware.wifi@1.0-service-lazy.rc @@ -164,6 +167,7 @@ LOCAL_STATIC_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.0-service-lib LOCAL_SHARED_LIBRARIES := \ libbase \ diff --git a/wifi/1.4/default/OWNERS b/wifi/1.5/default/OWNERS similarity index 100% rename from wifi/1.4/default/OWNERS rename to wifi/1.5/default/OWNERS diff --git a/wifi/1.4/default/THREADING.README b/wifi/1.5/default/THREADING.README similarity index 100% rename from wifi/1.4/default/THREADING.README rename to wifi/1.5/default/THREADING.README diff --git a/wifi/1.4/default/android.hardware.wifi@1.0-service-lazy.rc b/wifi/1.5/default/android.hardware.wifi@1.0-service-lazy.rc similarity index 100% rename from wifi/1.4/default/android.hardware.wifi@1.0-service-lazy.rc rename to wifi/1.5/default/android.hardware.wifi@1.0-service-lazy.rc diff --git a/wifi/1.4/default/android.hardware.wifi@1.0-service.rc b/wifi/1.5/default/android.hardware.wifi@1.0-service.rc similarity index 89% rename from wifi/1.4/default/android.hardware.wifi@1.0-service.rc rename to wifi/1.5/default/android.hardware.wifi@1.0-service.rc index 64a51b0ae8..05706ef4f4 100644 --- a/wifi/1.4/default/android.hardware.wifi@1.0-service.rc +++ b/wifi/1.5/default/android.hardware.wifi@1.0-service.rc @@ -4,6 +4,7 @@ service vendor.wifi_hal_legacy /vendor/bin/hw/android.hardware.wifi@1.0-service interface android.hardware.wifi@1.2::IWifi default interface android.hardware.wifi@1.3::IWifi default interface android.hardware.wifi@1.4::IWifi default + interface android.hardware.wifi@1.5::IWifi default class hal capabilities NET_ADMIN NET_RAW SYS_MODULE user wifi diff --git a/wifi/1.4/default/android.hardware.wifi@1.0-service.xml b/wifi/1.5/default/android.hardware.wifi@1.0-service.xml similarity index 90% rename from wifi/1.4/default/android.hardware.wifi@1.0-service.xml rename to wifi/1.5/default/android.hardware.wifi@1.0-service.xml index b5d25cd140..88dd1e3285 100644 --- a/wifi/1.4/default/android.hardware.wifi@1.0-service.xml +++ b/wifi/1.5/default/android.hardware.wifi@1.0-service.xml @@ -2,7 +2,7 @@ android.hardware.wifi hwbinder - 1.4 + 1.5 IWifi default diff --git a/wifi/1.4/default/hidl_callback_util.h b/wifi/1.5/default/hidl_callback_util.h similarity index 99% rename from wifi/1.4/default/hidl_callback_util.h rename to wifi/1.5/default/hidl_callback_util.h index fc601b804a..d144658750 100644 --- a/wifi/1.4/default/hidl_callback_util.h +++ b/wifi/1.5/default/hidl_callback_util.h @@ -52,7 +52,7 @@ class HidlDeathHandler : public android::hardware::hidl_death_recipient { namespace android { namespace hardware { namespace wifi { -namespace V1_4 { +namespace V1_5 { namespace implementation { namespace hidl_callback_util { template @@ -117,7 +117,7 @@ class HidlCallbackHandler { } // namespace hidl_callback_util } // namespace implementation -} // namespace V1_4 +} // namespace V1_5 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.4/default/hidl_return_util.h b/wifi/1.5/default/hidl_return_util.h similarity index 99% rename from wifi/1.4/default/hidl_return_util.h rename to wifi/1.5/default/hidl_return_util.h index 99c70928b7..4455185283 100644 --- a/wifi/1.4/default/hidl_return_util.h +++ b/wifi/1.5/default/hidl_return_util.h @@ -23,7 +23,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_4 { +namespace V1_5 { namespace implementation { namespace hidl_return_util { using namespace android::hardware::wifi::V1_0; @@ -113,7 +113,7 @@ Return validateAndCall( } // namespace hidl_return_util } // namespace implementation -} // namespace V1_4 +} // namespace V1_5 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.4/default/hidl_struct_util.cpp b/wifi/1.5/default/hidl_struct_util.cpp similarity index 97% rename from wifi/1.4/default/hidl_struct_util.cpp rename to wifi/1.5/default/hidl_struct_util.cpp index fd1d5b1121..a155ff877a 100644 --- a/wifi/1.4/default/hidl_struct_util.cpp +++ b/wifi/1.5/default/hidl_struct_util.cpp @@ -22,7 +22,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_4 { +namespace V1_5 { namespace implementation { namespace hidl_struct_util { @@ -314,7 +314,7 @@ legacy_hal::wifi_latency_mode convertHidlLatencyModeToLegacy( bool convertLegacyWifiMacInfoToHidl( const legacy_hal::WifiMacInfo& legacy_mac_info, - IWifiChipEventCallback::RadioModeInfo* hidl_radio_mode_info) { + V1_4::IWifiChipEventCallback::RadioModeInfo* hidl_radio_mode_info) { if (!hidl_radio_mode_info) { return false; } @@ -326,21 +326,21 @@ bool convertLegacyWifiMacInfoToHidl( if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_6_0_BAND && legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_5_0_BAND && legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_2_4_BAND) { - hidl_radio_mode_info->bandInfo = WifiBand::BAND_24GHZ_5GHZ_6GHZ; + hidl_radio_mode_info->bandInfo = V1_4::WifiBand::BAND_24GHZ_5GHZ_6GHZ; } else if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_6_0_BAND && legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_5_0_BAND) { - hidl_radio_mode_info->bandInfo = WifiBand::BAND_5GHZ_6GHZ; + hidl_radio_mode_info->bandInfo = V1_4::WifiBand::BAND_5GHZ_6GHZ; } else if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_6_0_BAND) { - hidl_radio_mode_info->bandInfo = WifiBand::BAND_6GHZ; + hidl_radio_mode_info->bandInfo = V1_4::WifiBand::BAND_6GHZ; } else if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_2_4_BAND && legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_5_0_BAND) { - hidl_radio_mode_info->bandInfo = WifiBand::BAND_24GHZ_5GHZ; + hidl_radio_mode_info->bandInfo = V1_4::WifiBand::BAND_24GHZ_5GHZ; } else if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_2_4_BAND) { - hidl_radio_mode_info->bandInfo = WifiBand::BAND_24GHZ; + hidl_radio_mode_info->bandInfo = V1_4::WifiBand::BAND_24GHZ; } else if (legacy_mac_info.mac_band & legacy_hal::WLAN_MAC_5_0_BAND) { - hidl_radio_mode_info->bandInfo = WifiBand::BAND_5GHZ; + hidl_radio_mode_info->bandInfo = V1_4::WifiBand::BAND_5GHZ; } else { - hidl_radio_mode_info->bandInfo = WifiBand::BAND_UNSPECIFIED; + hidl_radio_mode_info->bandInfo = V1_4::WifiBand::BAND_UNSPECIFIED; } std::vector iface_info_vec; for (const auto& legacy_iface_info : legacy_mac_info.iface_infos) { @@ -355,14 +355,15 @@ bool convertLegacyWifiMacInfoToHidl( bool convertLegacyWifiMacInfosToHidl( const std::vector& legacy_mac_infos, - std::vector* hidl_radio_mode_infos) { + std::vector* + hidl_radio_mode_infos) { if (!hidl_radio_mode_infos) { return false; } *hidl_radio_mode_infos = {}; for (const auto& legacy_mac_info : legacy_mac_infos) { - IWifiChipEventCallback::RadioModeInfo hidl_radio_mode_info; + V1_4::IWifiChipEventCallback::RadioModeInfo hidl_radio_mode_info; if (!convertLegacyWifiMacInfoToHidl(legacy_mac_info, &hidl_radio_mode_info)) { return false; @@ -1079,7 +1080,7 @@ void convertToWifiNanStatus(legacy_hal::NanStatusType type, const char* str, } bool convertHidlNanEnableRequestToLegacy( - const NanEnableRequest& hidl_request, + const V1_4::NanEnableRequest& hidl_request, legacy_hal::NanEnableRequest* legacy_request) { if (!legacy_request) { LOG(ERROR) @@ -1275,7 +1276,7 @@ bool convertHidlNanEnableRequestToLegacy( } bool convertHidlNanEnableRequest_1_4ToLegacy( - const NanEnableRequest& hidl_request1, + const V1_4::NanEnableRequest& hidl_request1, const V1_2::NanConfigRequestSupplemental& hidl_request2, legacy_hal::NanEnableRequest* legacy_request) { if (!legacy_request) { @@ -1674,7 +1675,7 @@ bool convertHidlNanTransmitFollowupRequestToLegacy( } bool convertHidlNanConfigRequestToLegacy( - const NanConfigRequest& hidl_request, + const V1_4::NanConfigRequest& hidl_request, legacy_hal::NanConfigRequest* legacy_request) { if (!legacy_request) { LOG(ERROR) @@ -1789,7 +1790,7 @@ bool convertHidlNanConfigRequestToLegacy( } bool convertHidlNanConfigRequest_1_4ToLegacy( - const NanConfigRequest& hidl_request1, + const V1_4::NanConfigRequest& hidl_request1, const V1_2::NanConfigRequestSupplemental& hidl_request2, legacy_hal::NanConfigRequest* legacy_request) { if (!legacy_request) { @@ -2298,30 +2299,32 @@ WifiChannelWidthInMhz convertLegacyWifiChannelWidthToHidl( CHECK(false) << "Unknown legacy type: " << type; } -legacy_hal::wifi_rtt_preamble convertHidlRttPreambleToLegacy(RttPreamble type) { +legacy_hal::wifi_rtt_preamble convertHidlRttPreambleToLegacy( + V1_4::RttPreamble type) { switch (type) { - case RttPreamble::LEGACY: + case V1_4::RttPreamble::LEGACY: return legacy_hal::WIFI_RTT_PREAMBLE_LEGACY; - case RttPreamble::HT: + case V1_4::RttPreamble::HT: return legacy_hal::WIFI_RTT_PREAMBLE_HT; - case RttPreamble::VHT: + case V1_4::RttPreamble::VHT: return legacy_hal::WIFI_RTT_PREAMBLE_VHT; - case RttPreamble::HE: + case V1_4::RttPreamble::HE: return legacy_hal::WIFI_RTT_PREAMBLE_HE; }; CHECK(false); } -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 RttPreamble::LEGACY; + return V1_4::RttPreamble::LEGACY; case legacy_hal::WIFI_RTT_PREAMBLE_HT: - return RttPreamble::HT; + return V1_4::RttPreamble::HT; case legacy_hal::WIFI_RTT_PREAMBLE_VHT: - return RttPreamble::VHT; + return V1_4::RttPreamble::VHT; case legacy_hal::WIFI_RTT_PREAMBLE_HE: - return RttPreamble::HE; + return V1_4::RttPreamble::HE; }; CHECK(false) << "Unknown legacy type: " << type; } @@ -2375,20 +2378,20 @@ legacy_hal::wifi_motion_pattern convertHidlRttMotionPatternToLegacy( CHECK(false); } -WifiRatePreamble convertLegacyWifiRatePreambleToHidl(uint8_t preamble) { +V1_4::WifiRatePreamble convertLegacyWifiRatePreambleToHidl(uint8_t preamble) { switch (preamble) { case 0: - return WifiRatePreamble::OFDM; + return V1_4::WifiRatePreamble::OFDM; case 1: - return WifiRatePreamble::CCK; + return V1_4::WifiRatePreamble::CCK; case 2: - return WifiRatePreamble::HT; + return V1_4::WifiRatePreamble::HT; case 3: - return WifiRatePreamble::VHT; + return V1_4::WifiRatePreamble::VHT; case 4: - return WifiRatePreamble::HE; + return V1_4::WifiRatePreamble::HE; default: - return WifiRatePreamble::RESERVED; + return V1_4::WifiRatePreamble::RESERVED; }; CHECK(false) << "Unknown legacy preamble: " << preamble; } @@ -2478,7 +2481,7 @@ bool convertLegacyWifiChannelInfoToHidl( return true; } -bool convertHidlRttConfigToLegacy(const RttConfig& hidl_config, +bool convertHidlRttConfigToLegacy(const V1_4::RttConfig& hidl_config, legacy_hal::wifi_rtt_config* legacy_config) { if (!legacy_config) { return false; @@ -2509,7 +2512,7 @@ bool convertHidlRttConfigToLegacy(const RttConfig& hidl_config, } bool convertHidlVectorOfRttConfigToLegacy( - const std::vector& hidl_configs, + const std::vector& hidl_configs, std::vector* legacy_configs) { if (!legacy_configs) { return false; @@ -2566,7 +2569,7 @@ bool convertHidlRttLcrInformationToLegacy( } bool convertHidlRttResponderToLegacy( - const RttResponder& hidl_responder, + const V1_4::RttResponder& hidl_responder, legacy_hal::wifi_rtt_responder* legacy_responder) { if (!legacy_responder) { return false; @@ -2583,7 +2586,7 @@ bool convertHidlRttResponderToLegacy( bool convertLegacyRttResponderToHidl( const legacy_hal::wifi_rtt_responder& legacy_responder, - RttResponder* hidl_responder) { + V1_4::RttResponder* hidl_responder) { if (!hidl_responder) { return false; } @@ -2599,7 +2602,7 @@ bool convertLegacyRttResponderToHidl( bool convertLegacyRttCapabilitiesToHidl( const legacy_hal::wifi_rtt_capabilities& legacy_capabilities, - RttCapabilities* hidl_capabilities) { + V1_4::RttCapabilities* hidl_capabilities) { if (!hidl_capabilities) { return false; } @@ -2618,7 +2621,7 @@ bool convertLegacyRttCapabilitiesToHidl( legacy_hal::WIFI_RTT_PREAMBLE_HE}) { if (legacy_capabilities.preamble_support & flag) { hidl_capabilities->preambleSupport |= - static_cast::type>( + static_cast::type>( convertLegacyRttPreambleToHidl(flag)); } } @@ -2638,7 +2641,7 @@ bool convertLegacyRttCapabilitiesToHidl( } bool convertLegacyWifiRateInfoToHidl(const legacy_hal::wifi_rate& legacy_rate, - WifiRateInfo* hidl_rate) { + V1_4::WifiRateInfo* hidl_rate) { if (!hidl_rate) { return false; } @@ -2654,7 +2657,8 @@ bool convertLegacyWifiRateInfoToHidl(const legacy_hal::wifi_rate& legacy_rate, } bool convertLegacyRttResultToHidl( - const legacy_hal::wifi_rtt_result& legacy_result, RttResult* hidl_result) { + const legacy_hal::wifi_rtt_result& legacy_result, + V1_4::RttResult* hidl_result) { if (!hidl_result) { return false; } @@ -2701,13 +2705,13 @@ bool convertLegacyRttResultToHidl( bool convertLegacyVectorOfRttResultToHidl( const std::vector& legacy_results, - std::vector* hidl_results) { + std::vector* hidl_results) { if (!hidl_results) { return false; } *hidl_results = {}; for (const auto legacy_result : legacy_results) { - RttResult hidl_result; + V1_4::RttResult hidl_result; if (!convertLegacyRttResultToHidl(*legacy_result, &hidl_result)) { return false; } @@ -2732,7 +2736,7 @@ legacy_hal::wifi_interface_type convertHidlIfaceTypeToLegacy( } } // namespace hidl_struct_util } // namespace implementation -} // namespace V1_4 +} // namespace V1_5 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.4/default/hidl_struct_util.h b/wifi/1.5/default/hidl_struct_util.h similarity index 93% rename from wifi/1.4/default/hidl_struct_util.h rename to wifi/1.5/default/hidl_struct_util.h index 929f877d96..b6567ff809 100644 --- a/wifi/1.4/default/hidl_struct_util.h +++ b/wifi/1.5/default/hidl_struct_util.h @@ -38,7 +38,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_4 { +namespace V1_5 { namespace implementation { namespace hidl_struct_util { using namespace android::hardware::wifi::V1_0; @@ -64,7 +64,8 @@ legacy_hal::wifi_power_scenario convertHidlTxPowerScenarioToLegacy_1_2( V1_2::IWifiChip::TxPowerScenario hidl_scenario); bool convertLegacyWifiMacInfosToHidl( const std::vector& legacy_mac_infos, - std::vector* hidl_radio_mode_infos); + std::vector* + hidl_radio_mode_infos); legacy_hal::wifi_interface_type convertHidlIfaceTypeToLegacy( IfaceType hidl_interface_type); @@ -114,17 +115,17 @@ bool convertLegacyVectorOfDebugRxPacketFateToHidl( void convertToWifiNanStatus(legacy_hal::NanStatusType type, const char* str, size_t max_len, WifiNanStatus* wifiNanStatus); bool convertHidlNanEnableRequestToLegacy( - const NanEnableRequest& hidl_request, + const V1_4::NanEnableRequest& hidl_request, legacy_hal::NanEnableRequest* legacy_request); bool convertHidlNanConfigRequestToLegacy( - const NanConfigRequest& hidl_request, + const V1_4::NanConfigRequest& hidl_request, legacy_hal::NanConfigRequest* legacy_request); bool convertHidlNanEnableRequest_1_4ToLegacy( - const NanEnableRequest& hidl_request1, + const V1_4::NanEnableRequest& hidl_request1, const V1_2::NanConfigRequestSupplemental& hidl_request2, legacy_hal::NanEnableRequest* legacy_request); bool convertHidlNanConfigRequest_1_4ToLegacy( - const NanConfigRequest& hidl_request1, + const V1_4::NanConfigRequest& hidl_request1, const V1_2::NanConfigRequestSupplemental& hidl_request2, legacy_hal::NanConfigRequest* legacy_request); bool convertHidlNanPublishRequestToLegacy( @@ -165,7 +166,7 @@ bool convertLegacyNanDataPathScheduleUpdateIndToHidl( // RTT controller conversion methods. bool convertHidlVectorOfRttConfigToLegacy( - const std::vector& hidl_configs, + const std::vector& hidl_configs, std::vector* legacy_configs); bool convertHidlRttLciInformationToLegacy( const RttLciInformation& hidl_info, @@ -174,23 +175,23 @@ bool convertHidlRttLcrInformationToLegacy( const RttLcrInformation& hidl_info, legacy_hal::wifi_lcr_information* legacy_info); bool convertHidlRttResponderToLegacy( - const RttResponder& hidl_responder, + 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, - RttResponder* hidl_responder); + V1_4::RttResponder* hidl_responder); bool convertLegacyRttCapabilitiesToHidl( const legacy_hal::wifi_rtt_capabilities& legacy_capabilities, - RttCapabilities* hidl_capabilities); + V1_4::RttCapabilities* hidl_capabilities); bool convertLegacyVectorOfRttResultToHidl( const std::vector& legacy_results, - std::vector* hidl_results); + std::vector* hidl_results); } // namespace hidl_struct_util } // namespace implementation -} // namespace V1_4 +} // namespace V1_5 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.4/default/hidl_sync_util.cpp b/wifi/1.5/default/hidl_sync_util.cpp similarity index 96% rename from wifi/1.4/default/hidl_sync_util.cpp rename to wifi/1.5/default/hidl_sync_util.cpp index 593a3bc5be..93eefe9560 100644 --- a/wifi/1.4/default/hidl_sync_util.cpp +++ b/wifi/1.5/default/hidl_sync_util.cpp @@ -23,7 +23,7 @@ std::recursive_mutex g_mutex; namespace android { namespace hardware { namespace wifi { -namespace V1_4 { +namespace V1_5 { namespace implementation { namespace hidl_sync_util { @@ -33,7 +33,7 @@ std::unique_lock acquireGlobalLock() { } // namespace hidl_sync_util } // namespace implementation -} // namespace V1_4 +} // namespace V1_5 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.4/default/hidl_sync_util.h b/wifi/1.5/default/hidl_sync_util.h similarity index 96% rename from wifi/1.4/default/hidl_sync_util.h rename to wifi/1.5/default/hidl_sync_util.h index 02444219e9..e706f4cd87 100644 --- a/wifi/1.4/default/hidl_sync_util.h +++ b/wifi/1.5/default/hidl_sync_util.h @@ -24,13 +24,13 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_4 { +namespace V1_5 { namespace implementation { namespace hidl_sync_util { std::unique_lock acquireGlobalLock(); } // namespace hidl_sync_util } // namespace implementation -} // namespace V1_4 +} // namespace V1_5 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.4/default/ringbuffer.cpp b/wifi/1.5/default/ringbuffer.cpp similarity index 97% rename from wifi/1.4/default/ringbuffer.cpp rename to wifi/1.5/default/ringbuffer.cpp index 0fe8ef45aa..26971ff25b 100644 --- a/wifi/1.4/default/ringbuffer.cpp +++ b/wifi/1.5/default/ringbuffer.cpp @@ -21,7 +21,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_4 { +namespace V1_5 { namespace implementation { Ringbuffer::Ringbuffer(size_t maxSize) : size_(0), maxSize_(maxSize) {} @@ -48,7 +48,7 @@ const std::list>& Ringbuffer::getData() const { } } // namespace implementation -} // namespace V1_4 +} // namespace V1_5 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.4/default/ringbuffer.h b/wifi/1.5/default/ringbuffer.h similarity index 97% rename from wifi/1.4/default/ringbuffer.h rename to wifi/1.5/default/ringbuffer.h index ddce648949..d8b87f2171 100644 --- a/wifi/1.4/default/ringbuffer.h +++ b/wifi/1.5/default/ringbuffer.h @@ -23,7 +23,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_4 { +namespace V1_5 { namespace implementation { /** @@ -45,7 +45,7 @@ class Ringbuffer { }; } // namespace implementation -} // namespace V1_4 +} // namespace V1_5 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.4/default/service.cpp b/wifi/1.5/default/service.cpp similarity index 85% rename from wifi/1.4/default/service.cpp rename to wifi/1.5/default/service.cpp index 3f7f6094fd..f53d528136 100644 --- a/wifi/1.4/default/service.cpp +++ b/wifi/1.5/default/service.cpp @@ -28,11 +28,11 @@ using android::hardware::configureRpcThreadpool; using android::hardware::joinRpcThreadpool; using android::hardware::LazyServiceRegistrar; -using android::hardware::wifi::V1_4::implementation::feature_flags:: +using android::hardware::wifi::V1_5::implementation::feature_flags:: WifiFeatureFlags; -using android::hardware::wifi::V1_4::implementation::iface_util::WifiIfaceUtil; -using android::hardware::wifi::V1_4::implementation::legacy_hal::WifiLegacyHal; -using android::hardware::wifi::V1_4::implementation::mode_controller:: +using android::hardware::wifi::V1_5::implementation::iface_util::WifiIfaceUtil; +using android::hardware::wifi::V1_5::implementation::legacy_hal::WifiLegacyHal; +using android::hardware::wifi::V1_5::implementation::mode_controller:: WifiModeController; #ifdef LAZY_SERVICE @@ -51,8 +51,8 @@ int main(int /*argc*/, char** argv) { const auto iface_tool = std::make_shared(); // Setup hwbinder service - android::sp service = - new android::hardware::wifi::V1_4::implementation::Wifi( + android::sp service = + new android::hardware::wifi::V1_5::implementation::Wifi( iface_tool, std::make_shared(iface_tool), std::make_shared(), std::make_shared(iface_tool), diff --git a/wifi/1.4/default/tests/hidl_struct_util_unit_tests.cpp b/wifi/1.5/default/tests/hidl_struct_util_unit_tests.cpp similarity index 92% rename from wifi/1.4/default/tests/hidl_struct_util_unit_tests.cpp rename to wifi/1.5/default/tests/hidl_struct_util_unit_tests.cpp index b71d549d9c..81eb14e8e0 100644 --- a/wifi/1.4/default/tests/hidl_struct_util_unit_tests.cpp +++ b/wifi/1.5/default/tests/hidl_struct_util_unit_tests.cpp @@ -34,7 +34,7 @@ constexpr char kIfaceName2[] = "wlan1"; namespace android { namespace hardware { namespace wifi { -namespace V1_4 { +namespace V1_5 { namespace implementation { using namespace android::hardware::wifi::V1_0; using ::android::hardware::wifi::V1_0::WifiChannelWidthInMhz; @@ -55,14 +55,15 @@ TEST_F(HidlStructUtilTest, CanConvertLegacyWifiMacInfosToHidlWithOneMac) { legacy_mac_info1.iface_infos.push_back(legacy_iface_info2); legacy_mac_infos.push_back(legacy_mac_info1); - std::vector hidl_radio_mode_infos; + std::vector + 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]; EXPECT_EQ(legacy_mac_info1.wlan_mac_id, hidl_radio_mode_info1.radioId); - EXPECT_EQ(WifiBand::BAND_24GHZ_5GHZ, hidl_radio_mode_info1.bandInfo); + EXPECT_EQ(V1_4::WifiBand::BAND_24GHZ_5GHZ, hidl_radio_mode_info1.bandInfo); 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); @@ -89,20 +90,22 @@ TEST_F(HidlStructUtilTest, CanConvertLegacyWifiMacInfosToHidlWithTwoMac) { legacy_mac_info2.iface_infos.push_back(legacy_iface_info2); legacy_mac_infos.push_back(legacy_mac_info2); - std::vector hidl_radio_mode_infos; + std::vector + 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 IWifiChipEventCallback::RadioModeInfo& x) { - return x.radioId == legacy_mac_info1.wlan_mac_id; - }); + 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; + }); ASSERT_NE(hidl_radio_mode_infos.end(), hidl_radio_mode_info1); - EXPECT_EQ(WifiBand::BAND_5GHZ, hidl_radio_mode_info1->bandInfo); + 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); @@ -110,13 +113,14 @@ TEST_F(HidlStructUtilTest, CanConvertLegacyWifiMacInfosToHidlWithTwoMac) { 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 IWifiChipEventCallback::RadioModeInfo& x) { - return x.radioId == legacy_mac_info2.wlan_mac_id; - }); + 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; + }); ASSERT_NE(hidl_radio_mode_infos.end(), hidl_radio_mode_info2); - EXPECT_EQ(WifiBand::BAND_24GHZ, hidl_radio_mode_info2->bandInfo); + 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); @@ -288,7 +292,7 @@ TEST_F(HidlStructUtilTest, CanConvertLegacyFeaturesToHidl) { hidle_caps); } } // namespace implementation -} // namespace V1_4 +} // namespace V1_5 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.4/default/tests/main.cpp b/wifi/1.5/default/tests/main.cpp similarity index 100% rename from wifi/1.4/default/tests/main.cpp rename to wifi/1.5/default/tests/main.cpp diff --git a/wifi/1.4/default/tests/mock_interface_tool.cpp b/wifi/1.5/default/tests/mock_interface_tool.cpp similarity index 100% rename from wifi/1.4/default/tests/mock_interface_tool.cpp rename to wifi/1.5/default/tests/mock_interface_tool.cpp diff --git a/wifi/1.4/default/tests/mock_interface_tool.h b/wifi/1.5/default/tests/mock_interface_tool.h similarity index 100% rename from wifi/1.4/default/tests/mock_interface_tool.h rename to wifi/1.5/default/tests/mock_interface_tool.h diff --git a/wifi/1.4/default/tests/mock_wifi_feature_flags.cpp b/wifi/1.5/default/tests/mock_wifi_feature_flags.cpp similarity index 96% rename from wifi/1.4/default/tests/mock_wifi_feature_flags.cpp rename to wifi/1.5/default/tests/mock_wifi_feature_flags.cpp index b1fa432ca3..2f66ba121b 100644 --- a/wifi/1.4/default/tests/mock_wifi_feature_flags.cpp +++ b/wifi/1.5/default/tests/mock_wifi_feature_flags.cpp @@ -21,7 +21,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_4 { +namespace V1_5 { namespace implementation { namespace feature_flags { @@ -29,7 +29,7 @@ MockWifiFeatureFlags::MockWifiFeatureFlags() {} } // namespace feature_flags } // namespace implementation -} // namespace V1_4 +} // namespace V1_5 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.4/default/tests/mock_wifi_feature_flags.h b/wifi/1.5/default/tests/mock_wifi_feature_flags.h similarity index 97% rename from wifi/1.4/default/tests/mock_wifi_feature_flags.h rename to wifi/1.5/default/tests/mock_wifi_feature_flags.h index 72d23045b0..92fbb055d6 100644 --- a/wifi/1.4/default/tests/mock_wifi_feature_flags.h +++ b/wifi/1.5/default/tests/mock_wifi_feature_flags.h @@ -25,7 +25,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_4 { +namespace V1_5 { namespace implementation { namespace feature_flags { @@ -39,7 +39,7 @@ class MockWifiFeatureFlags : public WifiFeatureFlags { } // namespace feature_flags } // namespace implementation -} // namespace V1_4 +} // namespace V1_5 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.4/default/tests/mock_wifi_iface_util.cpp b/wifi/1.5/default/tests/mock_wifi_iface_util.cpp similarity index 96% rename from wifi/1.4/default/tests/mock_wifi_iface_util.cpp rename to wifi/1.5/default/tests/mock_wifi_iface_util.cpp index 0968569c56..fe6e9e2e57 100644 --- a/wifi/1.4/default/tests/mock_wifi_iface_util.cpp +++ b/wifi/1.5/default/tests/mock_wifi_iface_util.cpp @@ -24,7 +24,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_4 { +namespace V1_5 { namespace implementation { namespace iface_util { @@ -33,7 +33,7 @@ MockWifiIfaceUtil::MockWifiIfaceUtil( : WifiIfaceUtil(iface_tool) {} } // namespace iface_util } // namespace implementation -} // namespace V1_4 +} // namespace V1_5 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.4/default/tests/mock_wifi_iface_util.h b/wifi/1.5/default/tests/mock_wifi_iface_util.h similarity index 97% rename from wifi/1.4/default/tests/mock_wifi_iface_util.h rename to wifi/1.5/default/tests/mock_wifi_iface_util.h index 8d77a7d9d0..a719fec878 100644 --- a/wifi/1.4/default/tests/mock_wifi_iface_util.h +++ b/wifi/1.5/default/tests/mock_wifi_iface_util.h @@ -24,7 +24,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_4 { +namespace V1_5 { namespace implementation { namespace iface_util { @@ -45,7 +45,7 @@ class MockWifiIfaceUtil : public WifiIfaceUtil { }; } // namespace iface_util } // namespace implementation -} // namespace V1_4 +} // namespace V1_5 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.4/default/tests/mock_wifi_legacy_hal.cpp b/wifi/1.5/default/tests/mock_wifi_legacy_hal.cpp similarity index 96% rename from wifi/1.4/default/tests/mock_wifi_legacy_hal.cpp rename to wifi/1.5/default/tests/mock_wifi_legacy_hal.cpp index 8d65c59e25..501bd7f4cf 100644 --- a/wifi/1.4/default/tests/mock_wifi_legacy_hal.cpp +++ b/wifi/1.5/default/tests/mock_wifi_legacy_hal.cpp @@ -24,7 +24,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_4 { +namespace V1_5 { namespace implementation { namespace legacy_hal { @@ -33,7 +33,7 @@ MockWifiLegacyHal::MockWifiLegacyHal( : WifiLegacyHal(iface_tool) {} } // namespace legacy_hal } // namespace implementation -} // namespace V1_4 +} // namespace V1_5 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.4/default/tests/mock_wifi_legacy_hal.h b/wifi/1.5/default/tests/mock_wifi_legacy_hal.h similarity index 98% rename from wifi/1.4/default/tests/mock_wifi_legacy_hal.h rename to wifi/1.5/default/tests/mock_wifi_legacy_hal.h index 3bb7b54760..f93834775c 100644 --- a/wifi/1.4/default/tests/mock_wifi_legacy_hal.h +++ b/wifi/1.5/default/tests/mock_wifi_legacy_hal.h @@ -24,7 +24,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_4 { +namespace V1_5 { namespace implementation { namespace legacy_hal { @@ -64,7 +64,7 @@ class MockWifiLegacyHal : public WifiLegacyHal { }; } // namespace legacy_hal } // namespace implementation -} // namespace V1_4 +} // namespace V1_5 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.4/default/tests/mock_wifi_mode_controller.cpp b/wifi/1.5/default/tests/mock_wifi_mode_controller.cpp similarity index 96% rename from wifi/1.4/default/tests/mock_wifi_mode_controller.cpp rename to wifi/1.5/default/tests/mock_wifi_mode_controller.cpp index ee09029820..e7ab22a01b 100644 --- a/wifi/1.4/default/tests/mock_wifi_mode_controller.cpp +++ b/wifi/1.5/default/tests/mock_wifi_mode_controller.cpp @@ -24,14 +24,14 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_4 { +namespace V1_5 { namespace implementation { namespace mode_controller { MockWifiModeController::MockWifiModeController() : WifiModeController() {} } // namespace mode_controller } // namespace implementation -} // namespace V1_4 +} // namespace V1_5 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.4/default/tests/mock_wifi_mode_controller.h b/wifi/1.5/default/tests/mock_wifi_mode_controller.h similarity index 97% rename from wifi/1.4/default/tests/mock_wifi_mode_controller.h rename to wifi/1.5/default/tests/mock_wifi_mode_controller.h index 1e1ce696f0..b9151f18b4 100644 --- a/wifi/1.4/default/tests/mock_wifi_mode_controller.h +++ b/wifi/1.5/default/tests/mock_wifi_mode_controller.h @@ -24,7 +24,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_4 { +namespace V1_5 { namespace implementation { namespace mode_controller { @@ -38,7 +38,7 @@ class MockWifiModeController : public WifiModeController { }; } // namespace mode_controller } // namespace implementation -} // namespace V1_4 +} // namespace V1_5 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.4/default/tests/ringbuffer_unit_tests.cpp b/wifi/1.5/default/tests/ringbuffer_unit_tests.cpp similarity index 98% rename from wifi/1.4/default/tests/ringbuffer_unit_tests.cpp rename to wifi/1.5/default/tests/ringbuffer_unit_tests.cpp index a65347f7ac..6fd34ee29c 100644 --- a/wifi/1.4/default/tests/ringbuffer_unit_tests.cpp +++ b/wifi/1.5/default/tests/ringbuffer_unit_tests.cpp @@ -24,7 +24,7 @@ using testing::Test; namespace android { namespace hardware { namespace wifi { -namespace V1_4 { +namespace V1_5 { namespace implementation { class RingbufferTest : public Test { @@ -91,7 +91,7 @@ TEST_F(RingbufferTest, OversizedAppendDoesNotDropExistingData) { EXPECT_EQ(input, buffer_.getData().front()); } } // namespace implementation -} // namespace V1_4 +} // namespace V1_5 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.4/default/tests/runtests.sh b/wifi/1.5/default/tests/runtests.sh similarity index 100% rename from wifi/1.4/default/tests/runtests.sh rename to wifi/1.5/default/tests/runtests.sh diff --git a/wifi/1.4/default/tests/wifi_chip_unit_tests.cpp b/wifi/1.5/default/tests/wifi_chip_unit_tests.cpp similarity index 98% rename from wifi/1.4/default/tests/wifi_chip_unit_tests.cpp rename to wifi/1.5/default/tests/wifi_chip_unit_tests.cpp index 3f1af2eafd..1d55e164d4 100644 --- a/wifi/1.4/default/tests/wifi_chip_unit_tests.cpp +++ b/wifi/1.5/default/tests/wifi_chip_unit_tests.cpp @@ -41,7 +41,7 @@ constexpr ChipId kFakeChipId = 5; namespace android { namespace hardware { namespace wifi { -namespace V1_4 { +namespace V1_5 { namespace implementation { class WifiChipTest : public Test { @@ -173,18 +173,18 @@ class WifiChipTest : public Test { std::string createIface(const IfaceType& type) { std::string iface_name; if (type == IfaceType::AP) { - chip_->createApIface([&iface_name]( - const WifiStatus& status, - const sp& 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(); - }); - } - }); + chip_->createApIface( + [&iface_name](const WifiStatus& status, + const sp& 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]( @@ -897,7 +897,7 @@ TEST_F(WifiChip_MultiIfaceTest, CreateApStartsWithIdx1) { ASSERT_EQ(createIface(IfaceType::STA), "wlan3"); } } // namespace implementation -} // namespace V1_4 +} // namespace V1_5 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.4/default/tests/wifi_iface_util_unit_tests.cpp b/wifi/1.5/default/tests/wifi_iface_util_unit_tests.cpp similarity index 98% rename from wifi/1.4/default/tests/wifi_iface_util_unit_tests.cpp rename to wifi/1.5/default/tests/wifi_iface_util_unit_tests.cpp index 03394bc209..d70e42f80e 100644 --- a/wifi/1.4/default/tests/wifi_iface_util_unit_tests.cpp +++ b/wifi/1.5/default/tests/wifi_iface_util_unit_tests.cpp @@ -41,7 +41,7 @@ bool isValidUnicastLocallyAssignedMacAddress( namespace android { namespace hardware { namespace wifi { -namespace V1_4 { +namespace V1_5 { namespace implementation { namespace iface_util { class WifiIfaceUtilTest : public Test { @@ -90,7 +90,7 @@ TEST_F(WifiIfaceUtilTest, IfaceEventHandlers_SetMacAddress) { } } // namespace iface_util } // namespace implementation -} // namespace V1_4 +} // namespace V1_5 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.4/default/tests/wifi_nan_iface_unit_tests.cpp b/wifi/1.5/default/tests/wifi_nan_iface_unit_tests.cpp similarity index 99% rename from wifi/1.4/default/tests/wifi_nan_iface_unit_tests.cpp rename to wifi/1.5/default/tests/wifi_nan_iface_unit_tests.cpp index 70424db815..3e7026f1f8 100644 --- a/wifi/1.4/default/tests/wifi_nan_iface_unit_tests.cpp +++ b/wifi/1.5/default/tests/wifi_nan_iface_unit_tests.cpp @@ -38,7 +38,7 @@ constexpr char kIfaceName[] = "mockWlan0"; namespace android { namespace hardware { namespace wifi { -namespace V1_4 { +namespace V1_5 { namespace implementation { using android::hardware::wifi::V1_2::IWifiNanIfaceEventCallback; @@ -151,7 +151,7 @@ TEST_F(WifiNanIfaceTest, IfacEventHandlers_OnStateToggleOffOn) { captured_iface_event_handlers.on_state_toggle_off_on(kIfaceName); } } // namespace implementation -} // namespace V1_4 +} // namespace V1_5 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.4/default/wifi.cpp b/wifi/1.5/default/wifi.cpp similarity index 98% rename from wifi/1.4/default/wifi.cpp rename to wifi/1.5/default/wifi.cpp index cfebfe03c7..c4e23337c8 100644 --- a/wifi/1.4/default/wifi.cpp +++ b/wifi/1.5/default/wifi.cpp @@ -28,7 +28,7 @@ static constexpr android::hardware::wifi::V1_0::ChipId kChipId = 0; namespace android { namespace hardware { namespace wifi { -namespace V1_4 { +namespace V1_5 { namespace implementation { using hidl_return_util::validateAndCall; using hidl_return_util::validateAndCallWithLock; @@ -187,7 +187,8 @@ std::pair> Wifi::getChipIdsInternal() { return {createWifiStatus(WifiStatusCode::SUCCESS), std::move(chip_ids)}; } -std::pair> Wifi::getChipInternal(ChipId chip_id) { +std::pair> Wifi::getChipInternal( + ChipId chip_id) { if (!chip_.get()) { return {createWifiStatus(WifiStatusCode::ERROR_NOT_STARTED), nullptr}; } @@ -228,7 +229,7 @@ WifiStatus Wifi::stopLegacyHalAndDeinitializeModeController( return createWifiStatus(WifiStatusCode::SUCCESS); } } // namespace implementation -} // namespace V1_4 +} // namespace V1_5 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.4/default/wifi.h b/wifi/1.5/default/wifi.h similarity index 94% rename from wifi/1.4/default/wifi.h rename to wifi/1.5/default/wifi.h index 087d6f71e8..8de0ef4c28 100644 --- a/wifi/1.4/default/wifi.h +++ b/wifi/1.5/default/wifi.h @@ -20,7 +20,7 @@ #include #include -#include +#include #include #include "hidl_callback_util.h" @@ -32,13 +32,13 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_4 { +namespace V1_5 { namespace implementation { /** * Root HIDL interface object used to control the Wifi HAL. */ -class Wifi : public V1_4::IWifi { +class Wifi : public V1_5::IWifi { public: Wifi(const std::shared_ptr iface_tool, const std::shared_ptr legacy_hal, @@ -70,7 +70,7 @@ class Wifi : public V1_4::IWifi { WifiStatus startInternal(); WifiStatus stopInternal(std::unique_lock* lock); std::pair> getChipIdsInternal(); - std::pair> getChipInternal(ChipId chip_id); + std::pair> getChipInternal(ChipId chip_id); WifiStatus initializeModeControllerAndLegacyHal(); WifiStatus stopLegacyHalAndDeinitializeModeController( @@ -92,7 +92,7 @@ class Wifi : public V1_4::IWifi { }; } // namespace implementation -} // namespace V1_4 +} // namespace V1_5 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.4/default/wifi_ap_iface.cpp b/wifi/1.5/default/wifi_ap_iface.cpp similarity index 99% rename from wifi/1.4/default/wifi_ap_iface.cpp rename to wifi/1.5/default/wifi_ap_iface.cpp index 8777a4cb9c..04e382a659 100644 --- a/wifi/1.4/default/wifi_ap_iface.cpp +++ b/wifi/1.5/default/wifi_ap_iface.cpp @@ -24,7 +24,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_4 { +namespace V1_5 { namespace implementation { using hidl_return_util::validateAndCall; @@ -131,7 +131,7 @@ WifiApIface::getFactoryMacAddressInternal() { return {createWifiStatus(WifiStatusCode::SUCCESS), mac}; } } // namespace implementation -} // namespace V1_4 +} // namespace V1_5 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.4/default/wifi_ap_iface.h b/wifi/1.5/default/wifi_ap_iface.h similarity index 98% rename from wifi/1.4/default/wifi_ap_iface.h rename to wifi/1.5/default/wifi_ap_iface.h index bf16d5eb85..48b444a66c 100644 --- a/wifi/1.4/default/wifi_ap_iface.h +++ b/wifi/1.5/default/wifi_ap_iface.h @@ -26,7 +26,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_4 { +namespace V1_5 { namespace implementation { using namespace android::hardware::wifi::V1_0; @@ -76,7 +76,7 @@ class WifiApIface : public V1_4::IWifiApIface { }; } // namespace implementation -} // namespace V1_4 +} // namespace V1_5 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.4/default/wifi_chip.cpp b/wifi/1.5/default/wifi_chip.cpp similarity index 98% rename from wifi/1.4/default/wifi_chip.cpp rename to wifi/1.5/default/wifi_chip.cpp index 96b83ac286..9883fc2277 100644 --- a/wifi/1.4/default/wifi_chip.cpp +++ b/wifi/1.5/default/wifi_chip.cpp @@ -326,7 +326,7 @@ std::vector makeCharVec(const std::string& str) { namespace android { namespace hardware { namespace wifi { -namespace V1_4 { +namespace V1_5 { namespace implementation { using hidl_return_util::validateAndCall; using hidl_return_util::validateAndCallWithLock; @@ -362,7 +362,7 @@ void WifiChip::invalidate() { bool WifiChip::isValid() { return is_valid_; } -std::set> WifiChip::getEventCallbacks() { +std::set> WifiChip::getEventCallbacks() { return event_cb_handler_.getCallbacks(); } @@ -650,7 +650,7 @@ Return WifiChip::createRttController_1_4( } Return WifiChip::registerEventCallback_1_4( - const sp& event_callback, + const sp& event_callback, registerEventCallback_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, &WifiChip::registerEventCallbackInternal_1_4, @@ -706,7 +706,7 @@ std::pair WifiChip::getCapabilitiesInternal() { return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), 0}; } -std::pair> +std::pair> WifiChip::getAvailableModesInternal() { return {createWifiStatus(WifiStatusCode::SUCCESS), modes_}; } @@ -754,9 +754,9 @@ std::pair WifiChip::getModeInternal() { return {createWifiStatus(WifiStatusCode::SUCCESS), current_mode_id_}; } -std::pair +std::pair WifiChip::requestChipDebugInfoInternal() { - IWifiChip::ChipDebugInfo result; + V1_4::IWifiChip::ChipDebugInfo result; legacy_hal::wifi_error legacy_status; std::string driver_desc; const auto ifname = getFirstActiveWlanIfaceName(); @@ -885,7 +885,8 @@ WifiStatus WifiChip::removeApIfaceInternal(const std::string& ifname) { return createWifiStatus(WifiStatusCode::SUCCESS); } -std::pair> WifiChip::createNanIfaceInternal() { +std::pair> +WifiChip::createNanIfaceInternal() { if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::NAN)) { return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; } @@ -916,7 +917,7 @@ WifiChip::getNanIfaceNamesInternal() { return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(nan_ifaces_)}; } -std::pair> WifiChip::getNanIfaceInternal( +std::pair> WifiChip::getNanIfaceInternal( const std::string& ifname) { const auto iface = findUsingName(nan_ifaces_, ifname); if (!iface.get()) { @@ -1233,7 +1234,7 @@ std::pair WifiChip::getCapabilitiesInternal_1_3() { return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps}; } -std::pair> +std::pair> WifiChip::createRttControllerInternal_1_4(const sp& bound_iface) { if (sta_ifaces_.size() == 0 && !canCurrentModeSupportIfaceOfType(IfaceType::STA)) { @@ -1249,7 +1250,7 @@ WifiChip::createRttControllerInternal_1_4(const sp& bound_iface) { } WifiStatus WifiChip::registerEventCallbackInternal_1_4( - const sp& event_callback) { + const sp& event_callback) { if (!event_cb_handler_.addCallback(event_callback)) { return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); } @@ -1297,7 +1298,7 @@ WifiStatus WifiChip::handleChipConfiguration( LOG(ERROR) << "Failed to register radio mode change callback"; } // Extract and save the version information into property. - std::pair version_info; + std::pair version_info; version_info = WifiChip::requestChipDebugInfoInternal(); if (WifiStatusCode::SUCCESS == version_info.first.code) { property_set("vendor.wlan.firmware.version", @@ -1363,7 +1364,7 @@ WifiStatus WifiChip::registerRadioModeChangeCallback() { LOG(ERROR) << "Callback invoked on an invalid object"; return; } - std::vector + std::vector hidl_radio_mode_infos; if (!hidl_struct_util::convertLegacyWifiMacInfosToHidl( mac_infos, &hidl_radio_mode_infos)) { @@ -1384,7 +1385,7 @@ WifiStatus WifiChip::registerRadioModeChangeCallback() { return createWifiStatusFromLegacyError(legacy_status); } -std::vector +std::vector WifiChip::getCurrentModeIfaceCombinations() { if (!isValidModeId(current_mode_id_)) { LOG(ERROR) << "Chip not configured in a mode yet"; @@ -1415,7 +1416,7 @@ std::map WifiChip::getCurrentIfaceCombination() { // of ifaces of each type in the combination. // This method is a port of HalDeviceManager.expandIfaceCombos() from framework. std::vector> WifiChip::expandIfaceCombinations( - const 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++) { @@ -1649,7 +1650,7 @@ bool WifiChip::writeRingbufferFilesInternal() { } } // namespace implementation -} // namespace V1_4 +} // namespace V1_5 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.4/default/wifi_chip.h b/wifi/1.5/default/wifi_chip.h similarity index 95% rename from wifi/1.4/default/wifi_chip.h rename to wifi/1.5/default/wifi_chip.h index e7650bdc1d..36c191cbcd 100644 --- a/wifi/1.4/default/wifi_chip.h +++ b/wifi/1.5/default/wifi_chip.h @@ -39,7 +39,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_4 { +namespace V1_5 { namespace implementation { using namespace android::hardware::wifi::V1_0; @@ -73,7 +73,7 @@ class WifiChip : public V1_4::IWifiChip { // marked valid before processing them. void invalidate(); bool isValid(); - std::set> getEventCallbacks(); + std::set> getEventCallbacks(); // HIDL methods exposed. Return getId(getId_cb hidl_status_cb) override; @@ -159,7 +159,7 @@ class WifiChip : public V1_4::IWifiChip { const sp& bound_iface, createRttController_1_4_cb hidl_status_cb) override; Return registerEventCallback_1_4( - const sp& event_callback, + const sp& event_callback, registerEventCallback_1_4_cb hidl_status_cb) override; private: @@ -189,9 +189,9 @@ class WifiChip : public V1_4::IWifiChip { std::pair> getApIfaceInternal( const std::string& ifname); WifiStatus removeApIfaceInternal(const std::string& ifname); - std::pair> createNanIfaceInternal(); + std::pair> createNanIfaceInternal(); std::pair> getNanIfaceNamesInternal(); - std::pair> getNanIfaceInternal( + std::pair> getNanIfaceInternal( const std::string& ifname); WifiStatus removeNanIfaceInternal(const std::string& ifname); std::pair> createP2pIfaceInternal(); @@ -226,21 +226,21 @@ class WifiChip : public V1_4::IWifiChip { const sp& event_callback); WifiStatus selectTxPowerScenarioInternal_1_2(TxPowerScenario scenario); std::pair getCapabilitiesInternal_1_3(); - std::pair> + std::pair> createRttControllerInternal_1_4(const sp& bound_iface); WifiStatus registerEventCallbackInternal_1_4( - const sp& event_callback); + const sp& event_callback); WifiStatus handleChipConfiguration( std::unique_lock* lock, ChipModeId mode_id); WifiStatus registerDebugRingBufferCallback(); WifiStatus registerRadioModeChangeCallback(); - std::vector + std::vector getCurrentModeIfaceCombinations(); std::map getCurrentIfaceCombination(); std::vector> expandIfaceCombinations( - const IWifiChip::ChipIfaceCombination& combination); + const V1_4::IWifiChip::ChipIfaceCombination& combination); bool canExpandedIfaceComboSupportIfaceOfTypeWithCurrentIfaces( const std::map& expanded_combo, IfaceType requested_type); @@ -275,12 +275,12 @@ class WifiChip : public V1_4::IWifiChip { // Members pertaining to chip configuration. uint32_t current_mode_id_; std::mutex lock_t; - std::vector modes_; + std::vector modes_; // The legacy ring buffer callback API has only a global callback // registration mechanism. Use this to check if we have already // registered a callback. bool debug_ring_buffer_cb_registered_; - hidl_callback_util::HidlCallbackHandler + hidl_callback_util::HidlCallbackHandler event_cb_handler_; const std::function subsystemCallbackHandler_; @@ -289,7 +289,7 @@ class WifiChip : public V1_4::IWifiChip { }; } // namespace implementation -} // namespace V1_4 +} // namespace V1_5 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.4/default/wifi_feature_flags.cpp b/wifi/1.5/default/wifi_feature_flags.cpp similarity index 99% rename from wifi/1.4/default/wifi_feature_flags.cpp rename to wifi/1.5/default/wifi_feature_flags.cpp index 195b460dfe..151d473e46 100644 --- a/wifi/1.4/default/wifi_feature_flags.cpp +++ b/wifi/1.5/default/wifi_feature_flags.cpp @@ -19,7 +19,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_4 { +namespace V1_5 { namespace implementation { namespace feature_flags { @@ -160,7 +160,7 @@ std::vector WifiFeatureFlags::getChipModes() { } // namespace feature_flags } // namespace implementation -} // namespace V1_4 +} // namespace V1_5 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.4/default/wifi_feature_flags.h b/wifi/1.5/default/wifi_feature_flags.h similarity index 97% rename from wifi/1.4/default/wifi_feature_flags.h rename to wifi/1.5/default/wifi_feature_flags.h index 292dedfe19..73d18eca35 100644 --- a/wifi/1.4/default/wifi_feature_flags.h +++ b/wifi/1.5/default/wifi_feature_flags.h @@ -22,7 +22,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_4 { +namespace V1_5 { namespace implementation { namespace feature_flags { @@ -47,7 +47,7 @@ class WifiFeatureFlags { } // namespace feature_flags } // namespace implementation -} // namespace V1_4 +} // namespace V1_5 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.4/default/wifi_iface_util.cpp b/wifi/1.5/default/wifi_iface_util.cpp similarity index 99% rename from wifi/1.4/default/wifi_iface_util.cpp rename to wifi/1.5/default/wifi_iface_util.cpp index 49b76747d6..07175e489f 100644 --- a/wifi/1.4/default/wifi_iface_util.cpp +++ b/wifi/1.5/default/wifi_iface_util.cpp @@ -36,7 +36,7 @@ constexpr uint8_t kMacAddressLocallyAssignedMask = 0x02; namespace android { namespace hardware { namespace wifi { -namespace V1_4 { +namespace V1_5 { namespace implementation { namespace iface_util { @@ -129,7 +129,7 @@ unsigned WifiIfaceUtil::ifNameToIndex(const std::string& iface_name) { } } // namespace iface_util } // namespace implementation -} // namespace V1_4 +} // namespace V1_5 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.4/default/wifi_iface_util.h b/wifi/1.5/default/wifi_iface_util.h similarity index 98% rename from wifi/1.4/default/wifi_iface_util.h rename to wifi/1.5/default/wifi_iface_util.h index 126b6ca599..7b812fa7d6 100644 --- a/wifi/1.4/default/wifi_iface_util.h +++ b/wifi/1.5/default/wifi_iface_util.h @@ -24,7 +24,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_4 { +namespace V1_5 { namespace implementation { namespace iface_util { @@ -69,7 +69,7 @@ class WifiIfaceUtil { } // namespace iface_util } // namespace implementation -} // namespace V1_4 +} // namespace V1_5 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.4/default/wifi_legacy_hal.cpp b/wifi/1.5/default/wifi_legacy_hal.cpp similarity index 99% rename from wifi/1.4/default/wifi_legacy_hal.cpp rename to wifi/1.5/default/wifi_legacy_hal.cpp index e9c3a0e3fd..40705689ce 100644 --- a/wifi/1.4/default/wifi_legacy_hal.cpp +++ b/wifi/1.5/default/wifi_legacy_hal.cpp @@ -51,7 +51,7 @@ std::vector makeCharVec(const std::string& str) { namespace android { namespace hardware { namespace wifi { -namespace V1_4 { +namespace V1_5 { namespace implementation { namespace legacy_hal { // Legacy HAL functions accept "C" style function pointers, so use global @@ -1520,7 +1520,7 @@ void WifiLegacyHal::invalidate() { } // namespace legacy_hal } // namespace implementation -} // namespace V1_4 +} // namespace V1_5 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.4/default/wifi_legacy_hal.h b/wifi/1.5/default/wifi_legacy_hal.h similarity index 99% rename from wifi/1.4/default/wifi_legacy_hal.h rename to wifi/1.5/default/wifi_legacy_hal.h index 2d4c59478a..ae520a85bc 100644 --- a/wifi/1.4/default/wifi_legacy_hal.h +++ b/wifi/1.5/default/wifi_legacy_hal.h @@ -35,7 +35,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_4 { +namespace V1_5 { namespace implementation { // This is in a separate namespace to prevent typename conflicts between // the legacy HAL types and the HIDL interface types. @@ -412,7 +412,7 @@ class WifiLegacyHal { } // namespace legacy_hal } // namespace implementation -} // namespace V1_4 +} // namespace V1_5 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.4/default/wifi_legacy_hal_stubs.cpp b/wifi/1.5/default/wifi_legacy_hal_stubs.cpp similarity index 99% rename from wifi/1.4/default/wifi_legacy_hal_stubs.cpp rename to wifi/1.5/default/wifi_legacy_hal_stubs.cpp index 64b058e692..73b58564f1 100644 --- a/wifi/1.4/default/wifi_legacy_hal_stubs.cpp +++ b/wifi/1.5/default/wifi_legacy_hal_stubs.cpp @@ -20,7 +20,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_4 { +namespace V1_5 { namespace implementation { namespace legacy_hal { template @@ -148,7 +148,7 @@ bool initHalFuncTableWithStubs(wifi_hal_fn* hal_fn) { } } // namespace legacy_hal } // namespace implementation -} // namespace V1_4 +} // namespace V1_5 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.4/default/wifi_legacy_hal_stubs.h b/wifi/1.5/default/wifi_legacy_hal_stubs.h similarity index 96% rename from wifi/1.4/default/wifi_legacy_hal_stubs.h rename to wifi/1.5/default/wifi_legacy_hal_stubs.h index 577a545b1d..7e4eb0a0fd 100644 --- a/wifi/1.4/default/wifi_legacy_hal_stubs.h +++ b/wifi/1.5/default/wifi_legacy_hal_stubs.h @@ -20,7 +20,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_4 { +namespace V1_5 { namespace implementation { namespace legacy_hal { #include @@ -28,7 +28,7 @@ namespace legacy_hal { bool initHalFuncTableWithStubs(wifi_hal_fn* hal_fn); } // namespace legacy_hal } // namespace implementation -} // namespace V1_4 +} // namespace V1_5 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.4/default/wifi_mode_controller.cpp b/wifi/1.5/default/wifi_mode_controller.cpp similarity index 98% rename from wifi/1.4/default/wifi_mode_controller.cpp rename to wifi/1.5/default/wifi_mode_controller.cpp index 252121a5b4..b1db8b3725 100644 --- a/wifi/1.4/default/wifi_mode_controller.cpp +++ b/wifi/1.5/default/wifi_mode_controller.cpp @@ -48,7 +48,7 @@ int convertIfaceTypeToFirmwareMode(IfaceType type) { namespace android { namespace hardware { namespace wifi { -namespace V1_4 { +namespace V1_5 { namespace implementation { namespace mode_controller { @@ -85,7 +85,7 @@ bool WifiModeController::deinitialize() { } } // namespace mode_controller } // namespace implementation -} // namespace V1_4 +} // namespace V1_5 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.4/default/wifi_mode_controller.h b/wifi/1.5/default/wifi_mode_controller.h similarity index 98% rename from wifi/1.4/default/wifi_mode_controller.h rename to wifi/1.5/default/wifi_mode_controller.h index 45fa999b2a..2eeca78c8b 100644 --- a/wifi/1.4/default/wifi_mode_controller.h +++ b/wifi/1.5/default/wifi_mode_controller.h @@ -24,7 +24,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_4 { +namespace V1_5 { namespace implementation { namespace mode_controller { using namespace android::hardware::wifi::V1_0; @@ -55,7 +55,7 @@ class WifiModeController { } // namespace mode_controller } // namespace implementation -} // namespace V1_4 +} // namespace V1_5 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.4/default/wifi_nan_iface.cpp b/wifi/1.5/default/wifi_nan_iface.cpp similarity index 99% rename from wifi/1.4/default/wifi_nan_iface.cpp rename to wifi/1.5/default/wifi_nan_iface.cpp index 5764d35ec4..84fb558db9 100644 --- a/wifi/1.4/default/wifi_nan_iface.cpp +++ b/wifi/1.5/default/wifi_nan_iface.cpp @@ -24,7 +24,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_4 { +namespace V1_5 { namespace implementation { using hidl_return_util::validateAndCall; @@ -718,7 +718,7 @@ Return WifiNanIface::configRequest_1_2( } Return WifiNanIface::enableRequest_1_4( - uint16_t cmd_id, const NanEnableRequest& msg1, + 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, @@ -727,7 +727,7 @@ Return WifiNanIface::enableRequest_1_4( } Return WifiNanIface::configRequest_1_4( - uint16_t cmd_id, const NanConfigRequest& msg1, + 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, @@ -898,7 +898,7 @@ WifiStatus WifiNanIface::configRequest_1_2Internal( } WifiStatus WifiNanIface::enableRequest_1_4Internal( - uint16_t cmd_id, const NanEnableRequest& msg1, + uint16_t cmd_id, const V1_4::NanEnableRequest& msg1, const V1_2::NanConfigRequestSupplemental& msg2) { legacy_hal::NanEnableRequest legacy_msg; if (!hidl_struct_util::convertHidlNanEnableRequest_1_4ToLegacy( @@ -911,7 +911,7 @@ WifiStatus WifiNanIface::enableRequest_1_4Internal( } WifiStatus WifiNanIface::configRequest_1_4Internal( - uint16_t cmd_id, const NanConfigRequest& msg1, + uint16_t cmd_id, const V1_4::NanConfigRequest& msg1, const V1_2::NanConfigRequestSupplemental& msg2) { legacy_hal::NanConfigRequest legacy_msg; if (!hidl_struct_util::convertHidlNanConfigRequest_1_4ToLegacy( @@ -924,7 +924,7 @@ WifiStatus WifiNanIface::configRequest_1_4Internal( } } // namespace implementation -} // namespace V1_4 +} // namespace V1_5 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.4/default/wifi_nan_iface.h b/wifi/1.5/default/wifi_nan_iface.h similarity index 95% rename from wifi/1.4/default/wifi_nan_iface.h rename to wifi/1.5/default/wifi_nan_iface.h index 06edbf2609..efdb2da65e 100644 --- a/wifi/1.4/default/wifi_nan_iface.h +++ b/wifi/1.5/default/wifi_nan_iface.h @@ -28,7 +28,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_4 { +namespace V1_5 { namespace implementation { using namespace android::hardware::wifi::V1_0; using namespace android::hardware::wifi::V1_2; @@ -105,13 +105,13 @@ class WifiNanIface : public V1_4::IWifiNanIface { const V1_2::NanConfigRequestSupplemental& msg2, configRequest_1_2_cb hidl_status_cb) override; Return enableRequest_1_4( - uint16_t cmd_id, const NanEnableRequest& msg1, + uint16_t cmd_id, const V1_4::NanEnableRequest& msg1, const V1_2::NanConfigRequestSupplemental& msg2, - enableRequest_1_2_cb hidl_status_cb) override; + enableRequest_1_4_cb hidl_status_cb) override; Return configRequest_1_4( - uint16_t cmd_id, const NanConfigRequest& msg1, + uint16_t cmd_id, const V1_4::NanConfigRequest& msg1, const V1_2::NanConfigRequestSupplemental& msg2, - configRequest_1_2_cb hidl_status_cb) override; + configRequest_1_4_cb hidl_status_cb) override; private: // Corresponding worker functions for the HIDL methods. @@ -153,10 +153,10 @@ class WifiNanIface : public V1_4::IWifiNanIface { uint16_t cmd_id, const V1_0::NanConfigRequest& msg, const V1_2::NanConfigRequestSupplemental& msg2); WifiStatus enableRequest_1_4Internal( - uint16_t cmd_id, const NanEnableRequest& msg1, + uint16_t cmd_id, const V1_4::NanEnableRequest& msg1, const V1_2::NanConfigRequestSupplemental& msg2); WifiStatus configRequest_1_4Internal( - uint16_t cmd_id, const NanConfigRequest& msg, + uint16_t cmd_id, const V1_4::NanConfigRequest& msg, const V1_2::NanConfigRequestSupplemental& msg2); // all 1_0 and descendant callbacks @@ -178,7 +178,7 @@ class WifiNanIface : public V1_4::IWifiNanIface { }; } // namespace implementation -} // namespace V1_4 +} // namespace V1_5 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.4/default/wifi_p2p_iface.cpp b/wifi/1.5/default/wifi_p2p_iface.cpp similarity index 98% rename from wifi/1.4/default/wifi_p2p_iface.cpp rename to wifi/1.5/default/wifi_p2p_iface.cpp index 9e7341f248..b8893da153 100644 --- a/wifi/1.4/default/wifi_p2p_iface.cpp +++ b/wifi/1.5/default/wifi_p2p_iface.cpp @@ -23,7 +23,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_4 { +namespace V1_5 { namespace implementation { using hidl_return_util::validateAndCall; @@ -60,7 +60,7 @@ std::pair WifiP2pIface::getTypeInternal() { } } // namespace implementation -} // namespace V1_4 +} // namespace V1_5 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.4/default/wifi_p2p_iface.h b/wifi/1.5/default/wifi_p2p_iface.h similarity index 98% rename from wifi/1.4/default/wifi_p2p_iface.h rename to wifi/1.5/default/wifi_p2p_iface.h index a6fc59d04b..c1adc50278 100644 --- a/wifi/1.4/default/wifi_p2p_iface.h +++ b/wifi/1.5/default/wifi_p2p_iface.h @@ -25,7 +25,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_4 { +namespace V1_5 { namespace implementation { using namespace android::hardware::wifi::V1_0; @@ -58,7 +58,7 @@ class WifiP2pIface : public V1_0::IWifiP2pIface { }; } // namespace implementation -} // namespace V1_4 +} // namespace V1_5 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.4/default/wifi_rtt_controller.cpp b/wifi/1.5/default/wifi_rtt_controller.cpp similarity index 95% rename from wifi/1.4/default/wifi_rtt_controller.cpp rename to wifi/1.5/default/wifi_rtt_controller.cpp index 594a11660f..a0f9969033 100644 --- a/wifi/1.4/default/wifi_rtt_controller.cpp +++ b/wifi/1.5/default/wifi_rtt_controller.cpp @@ -24,7 +24,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_4 { +namespace V1_5 { namespace implementation { using hidl_return_util::validateAndCall; @@ -44,7 +44,7 @@ void WifiRttController::invalidate() { bool WifiRttController::isValid() { return is_valid_; } -std::vector> +std::vector> WifiRttController::getEventCallbacks() { return event_callbacks_; } @@ -131,7 +131,7 @@ Return WifiRttController::disableResponder( } Return WifiRttController::registerEventCallback_1_4( - const sp& callback, + const sp& callback, registerEventCallback_1_4_cb hidl_status_cb) { return validateAndCall( this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, @@ -140,7 +140,7 @@ Return WifiRttController::registerEventCallback_1_4( } Return WifiRttController::rangeRequest_1_4( - uint32_t cmd_id, const hidl_vec& rtt_configs, + uint32_t cmd_id, const hidl_vec& rtt_configs, rangeRequest_1_4_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID, @@ -164,7 +164,7 @@ Return WifiRttController::getResponderInfo_1_4( Return WifiRttController::enableResponder_1_4( uint32_t cmd_id, const WifiChannelInfo& channel_hint, - uint32_t max_duration_seconds, const RttResponder& info, + 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, @@ -252,14 +252,14 @@ WifiStatus WifiRttController::disableResponderInternal(uint32_t cmd_id) { } WifiStatus WifiRttController::registerEventCallbackInternal_1_4( - const sp& callback) { + const sp& 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& rtt_configs) { + uint32_t cmd_id, const std::vector& rtt_configs) { std::vector legacy_configs; if (!hidl_struct_util::convertHidlVectorOfRttConfigToLegacy( rtt_configs, &legacy_configs)) { @@ -275,7 +275,7 @@ WifiStatus WifiRttController::rangeRequestInternal_1_4( LOG(ERROR) << "Callback invoked on an invalid object"; return; } - std::vector hidl_results; + std::vector hidl_results; if (!hidl_struct_util::convertLegacyVectorOfRttResultToHidl( results, &hidl_results)) { LOG(ERROR) << "Failed to convert rtt results to HIDL structs"; @@ -291,7 +291,7 @@ WifiStatus WifiRttController::rangeRequestInternal_1_4( return createWifiStatusFromLegacyError(legacy_status); } -std::pair +std::pair WifiRttController::getCapabilitiesInternal_1_4() { legacy_hal::wifi_error legacy_status; legacy_hal::wifi_rtt_capabilities legacy_caps; @@ -300,7 +300,7 @@ WifiRttController::getCapabilitiesInternal_1_4() { if (legacy_status != legacy_hal::WIFI_SUCCESS) { return {createWifiStatusFromLegacyError(legacy_status), {}}; } - RttCapabilities hidl_caps; + V1_4::RttCapabilities hidl_caps; if (!hidl_struct_util::convertLegacyRttCapabilitiesToHidl(legacy_caps, &hidl_caps)) { return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}}; @@ -308,7 +308,7 @@ WifiRttController::getCapabilitiesInternal_1_4() { return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps}; } -std::pair +std::pair WifiRttController::getResponderInfoInternal_1_4() { legacy_hal::wifi_error legacy_status; legacy_hal::wifi_rtt_responder legacy_responder; @@ -317,7 +317,7 @@ WifiRttController::getResponderInfoInternal_1_4() { if (legacy_status != legacy_hal::WIFI_SUCCESS) { return {createWifiStatusFromLegacyError(legacy_status), {}}; } - RttResponder hidl_responder; + V1_4::RttResponder hidl_responder; if (!hidl_struct_util::convertLegacyRttResponderToHidl(legacy_responder, &hidl_responder)) { return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}}; @@ -327,7 +327,7 @@ WifiRttController::getResponderInfoInternal_1_4() { WifiStatus WifiRttController::enableResponderInternal_1_4( uint32_t cmd_id, const WifiChannelInfo& channel_hint, - uint32_t max_duration_seconds, const RttResponder& info) { + 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)) { @@ -345,7 +345,7 @@ WifiStatus WifiRttController::enableResponderInternal_1_4( return createWifiStatusFromLegacyError(legacy_status); } } // namespace implementation -} // namespace V1_4 +} // namespace V1_5 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.4/default/wifi_rtt_controller.h b/wifi/1.5/default/wifi_rtt_controller.h similarity index 87% rename from wifi/1.4/default/wifi_rtt_controller.h rename to wifi/1.5/default/wifi_rtt_controller.h index 1f125555d0..9ac3e06fcc 100644 --- a/wifi/1.4/default/wifi_rtt_controller.h +++ b/wifi/1.5/default/wifi_rtt_controller.h @@ -27,7 +27,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_4 { +namespace V1_5 { namespace implementation { /** @@ -41,7 +41,7 @@ class WifiRttController : public V1_4::IWifiRttController { // Refer to |WifiChip::invalidate()|. void invalidate(); bool isValid(); - std::vector> getEventCallbacks(); + std::vector> getEventCallbacks(); std::string getIfaceName(); // HIDL methods exposed. @@ -69,10 +69,10 @@ class WifiRttController : public V1_4::IWifiRttController { Return disableResponder(uint32_t cmd_id, disableResponder_cb hidl_status_cb) override; Return registerEventCallback_1_4( - const sp& callback, + const sp& callback, registerEventCallback_1_4_cb hidl_status_cb) override; Return rangeRequest_1_4(uint32_t cmd_id, - const hidl_vec& rtt_configs, + const hidl_vec& rtt_configs, rangeRequest_1_4_cb hidl_status_cb) override; Return getCapabilities_1_4( getCapabilities_1_4_cb hidl_status_cb) override; @@ -80,7 +80,7 @@ class WifiRttController : public V1_4::IWifiRttController { getResponderInfo_1_4_cb hidl_status_cb) override; Return enableResponder_1_4( uint32_t cmd_id, const WifiChannelInfo& channel_hint, - uint32_t max_duration_seconds, const RttResponder& info, + uint32_t max_duration_seconds, const V1_4::RttResponder& info, enableResponder_1_4_cb hidl_status_cb) override; private: @@ -102,27 +102,27 @@ class WifiRttController : public V1_4::IWifiRttController { const V1_0::RttResponder& info); WifiStatus disableResponderInternal(uint32_t cmd_id); WifiStatus registerEventCallbackInternal_1_4( - const sp& callback); + const sp& callback); WifiStatus rangeRequestInternal_1_4( - uint32_t cmd_id, const std::vector& rtt_configs); - std::pair getCapabilitiesInternal_1_4(); - std::pair getResponderInfoInternal_1_4(); + uint32_t cmd_id, const std::vector& rtt_configs); + std::pair getCapabilitiesInternal_1_4(); + std::pair getResponderInfoInternal_1_4(); WifiStatus enableResponderInternal_1_4(uint32_t cmd_id, const WifiChannelInfo& channel_hint, uint32_t max_duration_seconds, - const RttResponder& info); + const V1_4::RttResponder& info); std::string ifname_; sp bound_iface_; std::weak_ptr legacy_hal_; - std::vector> event_callbacks_; + std::vector> event_callbacks_; bool is_valid_; DISALLOW_COPY_AND_ASSIGN(WifiRttController); }; } // namespace implementation -} // namespace V1_4 +} // namespace V1_5 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.4/default/wifi_sta_iface.cpp b/wifi/1.5/default/wifi_sta_iface.cpp similarity index 99% rename from wifi/1.4/default/wifi_sta_iface.cpp rename to wifi/1.5/default/wifi_sta_iface.cpp index 49f383ae2f..04087fda7a 100644 --- a/wifi/1.4/default/wifi_sta_iface.cpp +++ b/wifi/1.5/default/wifi_sta_iface.cpp @@ -24,7 +24,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_4 { +namespace V1_5 { namespace implementation { using hidl_return_util::validateAndCall; @@ -640,7 +640,7 @@ WifiStaIface::getFactoryMacAddressInternal() { } } // namespace implementation -} // namespace V1_4 +} // namespace V1_5 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.4/default/wifi_sta_iface.h b/wifi/1.5/default/wifi_sta_iface.h similarity index 99% rename from wifi/1.4/default/wifi_sta_iface.h rename to wifi/1.5/default/wifi_sta_iface.h index dee04f2a69..7695f3c9f1 100644 --- a/wifi/1.4/default/wifi_sta_iface.h +++ b/wifi/1.5/default/wifi_sta_iface.h @@ -28,7 +28,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_4 { +namespace V1_5 { namespace implementation { using namespace android::hardware::wifi::V1_0; @@ -172,7 +172,7 @@ class WifiStaIface : public V1_3::IWifiStaIface { }; } // namespace implementation -} // namespace V1_4 +} // namespace V1_5 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.4/default/wifi_status_util.cpp b/wifi/1.5/default/wifi_status_util.cpp similarity index 99% rename from wifi/1.4/default/wifi_status_util.cpp rename to wifi/1.5/default/wifi_status_util.cpp index 8ceb9265f1..eb8c8694db 100644 --- a/wifi/1.4/default/wifi_status_util.cpp +++ b/wifi/1.5/default/wifi_status_util.cpp @@ -19,7 +19,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_4 { +namespace V1_5 { namespace implementation { std::string legacyErrorToString(legacy_hal::wifi_error error) { @@ -106,7 +106,7 @@ WifiStatus createWifiStatusFromLegacyError(legacy_hal::wifi_error error) { } } // namespace implementation -} // namespace V1_4 +} // namespace V1_5 } // namespace wifi } // namespace hardware } // namespace android diff --git a/wifi/1.4/default/wifi_status_util.h b/wifi/1.5/default/wifi_status_util.h similarity index 97% rename from wifi/1.4/default/wifi_status_util.h rename to wifi/1.5/default/wifi_status_util.h index 3ff58f0c0a..68f21689c5 100644 --- a/wifi/1.4/default/wifi_status_util.h +++ b/wifi/1.5/default/wifi_status_util.h @@ -24,7 +24,7 @@ namespace android { namespace hardware { namespace wifi { -namespace V1_4 { +namespace V1_5 { namespace implementation { using namespace android::hardware::wifi::V1_0; @@ -37,7 +37,7 @@ WifiStatus createWifiStatusFromLegacyError(legacy_hal::wifi_error error, WifiStatus createWifiStatusFromLegacyError(legacy_hal::wifi_error error); } // namespace implementation -} // namespace V1_4 +} // namespace V1_5 } // namespace wifi } // namespace hardware } // namespace android -- GitLab From 3ab6e1fbbfba51384577c0e60d77742e7f29c9d2 Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Thu, 9 Jul 2020 22:42:15 -0700 Subject: [PATCH 073/790] Enable Tuner HAL 1.1 interface The first feature to support in this new Tuner HAL is the 64-bit id. In the current CL, we support Demux and Filter ids in 64-bit format. More component ids will be suppored in 64-bit in the following CLs. Test: atest VtsHalTvTunerV1_1TargetTest Bug: b/159058358 Change-Id: If05eb9f0cd76935064b2e51ff3ff1a3a477e3bd1 --- .../compatibility_matrix.current.xml | 2 +- tv/tuner/1.1/Android.bp | 16 +++++++ tv/tuner/1.1/IFilter.hal | 43 +++++++++++++++++++ tv/tuner/1.1/ITuner.hal | 26 +++++++++++ 4 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 tv/tuner/1.1/Android.bp create mode 100644 tv/tuner/1.1/IFilter.hal create mode 100644 tv/tuner/1.1/ITuner.hal diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index cfee298c6d..90ec76e1cc 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -482,7 +482,7 @@ android.hardware.tv.tuner - 1.0 + 1.0-1 ITuner default diff --git a/tv/tuner/1.1/Android.bp b/tv/tuner/1.1/Android.bp new file mode 100644 index 0000000000..c051ab0902 --- /dev/null +++ b/tv/tuner/1.1/Android.bp @@ -0,0 +1,16 @@ +// This file is autogenerated by hidl-gen -Landroidbp. + +hidl_interface { + name: "android.hardware.tv.tuner@1.1", + root: "android.hardware", + srcs: [ + "IFilter.hal", + "ITuner.hal", + ], + interfaces: [ + "android.hidl.base@1.0", + "android.hidl.safe_union@1.0", + "android.hardware.tv.tuner@1.0", + ], + gen_java: false, +} diff --git a/tv/tuner/1.1/IFilter.hal b/tv/tuner/1.1/IFilter.hal new file mode 100644 index 0000000000..6c4d8a5a03 --- /dev/null +++ b/tv/tuner/1.1/IFilter.hal @@ -0,0 +1,43 @@ +/* + * 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. + */ + +package android.hardware.tv.tuner@1.1; + +import @1.0::IFilter; +import @1.0::Result; + +/** + * The Filter is used to filter wanted data according to the filter's + * configuration. + * + * To access the v1.1 IFilter APIs, the implementation can cast the IFilter + * interface returned from the @1.0::IDemux openFilter into a v1.1 IFiler + * using V1_1::IFilter::castFrom(V1_0::IFilter). + */ +interface IFilter extends @1.0::IFilter { + /** + * Get the 64-bit filter Id. This id is 32-bit in Tuner HAL 1.0. + * + * It is used by the client to ask the hardware resource id for the filter. + * + * @return result Result status of the operation. + * SUCCESS if successful, + * INVALID_STATE if failed for wrong state. + * UNKNOWN_ERROR if failed for other reasons. + * @return filterId the hardware resource Id for the filter. + */ + getId64Bit() generates (Result result, uint64_t filterId); +}; diff --git a/tv/tuner/1.1/ITuner.hal b/tv/tuner/1.1/ITuner.hal new file mode 100644 index 0000000000..915fb85806 --- /dev/null +++ b/tv/tuner/1.1/ITuner.hal @@ -0,0 +1,26 @@ +/* + * 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. + */ + +package android.hardware.tv.tuner@1.1; + +import @1.0::ITuner; +import @1.0::Result; + +/** + * Top level interface to manage Frontend, Demux and Decrambler hardware + * resources which are needed for Android TV. + */ +interface ITuner extends @1.0::ITuner {}; -- GitLab From bb94eeb456c28e05fc54c6b23a34ab386766b2c0 Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Thu, 9 Jul 2020 22:48:04 -0700 Subject: [PATCH 074/790] Add default implementation of Tuner HAL 1.1 This CL enables the android.hardware.tv.tuner@1.1-service with the default implementation of Tuner HAL 1.1 The 1.0 Tuner HAL interface implementation are identical to the 1.0 default implementation. The 1.1 new API implementation are added with *_1_1 suffix. Note that we cast all the uint32_t id in the 1.0 Hal implementation into uint64_t even calling the old 1.0 APIs. This makes sure the 1.1 default implementation internally only record 64-bit ids. Test: atest VtsHalTvTunerV1_1TargetTest Bug: b/159058358 Change-Id: Ic506376e520f03235010bc503e337c02d5735ec3 --- tv/tuner/1.1/default/Android.bp | 52 ++ tv/tuner/1.1/default/Demux.cpp | 395 ++++++++++ tv/tuner/1.1/default/Demux.h | 197 +++++ tv/tuner/1.1/default/Descrambler.cpp | 80 +++ tv/tuner/1.1/default/Descrambler.h | 62 ++ tv/tuner/1.1/default/Dvr.cpp | 498 +++++++++++++ tv/tuner/1.1/default/Dvr.h | 167 +++++ tv/tuner/1.1/default/Filter.cpp | 672 ++++++++++++++++++ tv/tuner/1.1/default/Filter.h | 214 ++++++ tv/tuner/1.1/default/Frontend.cpp | 284 ++++++++ tv/tuner/1.1/default/Frontend.h | 85 +++ tv/tuner/1.1/default/Lnb.cpp | 81 +++ tv/tuner/1.1/default/Lnb.h | 63 ++ tv/tuner/1.1/default/OWNERS | 4 + tv/tuner/1.1/default/TimeFilter.cpp | 87 +++ tv/tuner/1.1/default/TimeFilter.h | 70 ++ tv/tuner/1.1/default/Tuner.cpp | 259 +++++++ tv/tuner/1.1/default/Tuner.h | 94 +++ ...roid.hardware.tv.tuner@1.1-service-lazy.rc | 9 + ...oid.hardware.tv.tuner@1.1-service-lazy.xml | 11 + .../android.hardware.tv.tuner@1.1-service.rc | 6 + .../android.hardware.tv.tuner@1.1-service.xml | 11 + tv/tuner/1.1/default/service.cpp | 57 ++ 23 files changed, 3458 insertions(+) create mode 100644 tv/tuner/1.1/default/Android.bp create mode 100644 tv/tuner/1.1/default/Demux.cpp create mode 100644 tv/tuner/1.1/default/Demux.h create mode 100644 tv/tuner/1.1/default/Descrambler.cpp create mode 100644 tv/tuner/1.1/default/Descrambler.h create mode 100644 tv/tuner/1.1/default/Dvr.cpp create mode 100644 tv/tuner/1.1/default/Dvr.h create mode 100644 tv/tuner/1.1/default/Filter.cpp create mode 100644 tv/tuner/1.1/default/Filter.h create mode 100644 tv/tuner/1.1/default/Frontend.cpp create mode 100644 tv/tuner/1.1/default/Frontend.h create mode 100644 tv/tuner/1.1/default/Lnb.cpp create mode 100644 tv/tuner/1.1/default/Lnb.h create mode 100644 tv/tuner/1.1/default/OWNERS create mode 100644 tv/tuner/1.1/default/TimeFilter.cpp create mode 100644 tv/tuner/1.1/default/TimeFilter.h create mode 100644 tv/tuner/1.1/default/Tuner.cpp create mode 100644 tv/tuner/1.1/default/Tuner.h create mode 100644 tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service-lazy.rc create mode 100644 tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service-lazy.xml create mode 100644 tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service.rc create mode 100644 tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service.xml create mode 100644 tv/tuner/1.1/default/service.cpp diff --git a/tv/tuner/1.1/default/Android.bp b/tv/tuner/1.1/default/Android.bp new file mode 100644 index 0000000000..7e45864791 --- /dev/null +++ b/tv/tuner/1.1/default/Android.bp @@ -0,0 +1,52 @@ +cc_defaults { + name: "tuner_service_defaults@1.1", + defaults: ["hidl_defaults"], + vendor: true, + relative_install_path: "hw", + srcs: [ + "Filter.cpp", + "Frontend.cpp", + "Descrambler.cpp", + "Demux.cpp", + "Dvr.cpp", + "TimeFilter.cpp", + "Tuner.cpp", + "Lnb.cpp", + "service.cpp", + ], + + compile_multilib: "first", + + shared_libs: [ + "android.hardware.tv.tuner@1.0", + "android.hardware.tv.tuner@1.1", + "android.hidl.memory@1.0", + "libcutils", + "libfmq", + "libhidlbase", + "libhidlmemory", + "libion", + "liblog", + "libstagefright_foundation", + "libutils", + ], + header_libs: [ + "media_plugin_headers", + ], +} + +cc_binary { + name: "android.hardware.tv.tuner@1.1-service", + vintf_fragments: ["android.hardware.tv.tuner@1.1-service.xml"], + defaults: ["tuner_service_defaults@1.1"], + init_rc: ["android.hardware.tv.tuner@1.1-service.rc"], +} + +cc_binary { + name: "android.hardware.tv.tuner@1.1-service-lazy", + vintf_fragments: ["android.hardware.tv.tuner@1.1-service-lazy.xml"], + overrides: ["android.hardware.tv.tuner@1.1-service"], + defaults: ["tuner_service_defaults@1.1"], + init_rc: ["android.hardware.tv.tuner@1.1-service-lazy.rc"], + cflags: ["-DLAZY_SERVICE"], +} diff --git a/tv/tuner/1.1/default/Demux.cpp b/tv/tuner/1.1/default/Demux.cpp new file mode 100644 index 0000000000..b6b029fdb4 --- /dev/null +++ b/tv/tuner/1.1/default/Demux.cpp @@ -0,0 +1,395 @@ +/* + * 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. + */ + +#define LOG_TAG "android.hardware.tv.tuner@1.1-Demux" + +#include "Demux.h" +#include + +namespace android { +namespace hardware { +namespace tv { +namespace tuner { +namespace V1_0 { +namespace implementation { + +#define WAIT_TIMEOUT 3000000000 +Demux::Demux(uint32_t demuxId, sp tuner) { + mDemuxId = demuxId; + mTunerService = tuner; +} + +Demux::~Demux() {} + +Return Demux::setFrontendDataSource(uint32_t frontendId) { + ALOGV("%s", __FUNCTION__); + + if (mTunerService == nullptr) { + return Result::NOT_INITIALIZED; + } + + mFrontend = mTunerService->getFrontendById(frontendId); + + if (mFrontend == nullptr) { + return Result::INVALID_STATE; + } + + mTunerService->setFrontendAsDemuxSource(frontendId, mDemuxId); + + return Result::SUCCESS; +} + +Return Demux::openFilter(const DemuxFilterType& type, uint32_t bufferSize, + const sp& cb, openFilter_cb _hidl_cb) { + ALOGV("%s", __FUNCTION__); + + uint64_t filterId; + filterId = ++mLastUsedFilterId; + + if (cb == nullptr) { + ALOGW("[Demux] callback can't be null"); + _hidl_cb(Result::INVALID_ARGUMENT, new Filter()); + return Void(); + } + + sp filter = new Filter(type, filterId, bufferSize, cb, this); + + if (!filter->createFilterMQ()) { + _hidl_cb(Result::UNKNOWN_ERROR, filter); + return Void(); + } + + mFilters[filterId] = filter; + if (filter->isPcrFilter()) { + mPcrFilterIds.insert(filterId); + } + bool result = true; + if (!filter->isRecordFilter()) { + // Only save non-record filters for now. Record filters are saved when the + // IDvr.attacheFilter is called. + mPlaybackFilterIds.insert(filterId); + if (mDvrPlayback != nullptr) { + result = mDvrPlayback->addPlaybackFilter(filterId, filter); + } + } + + _hidl_cb(result ? Result::SUCCESS : Result::INVALID_ARGUMENT, filter); + return Void(); +} + +Return Demux::openTimeFilter(openTimeFilter_cb _hidl_cb) { + ALOGV("%s", __FUNCTION__); + + mTimeFilter = new TimeFilter(this); + + _hidl_cb(Result::SUCCESS, mTimeFilter); + return Void(); +} + +Return Demux::getAvSyncHwId(const sp& filter, getAvSyncHwId_cb _hidl_cb) { + ALOGV("%s", __FUNCTION__); + + uint32_t avSyncHwId = -1; + uint64_t id; + Result status; + + sp filter_v1_1 = V1_1::IFilter::castFrom(filter); + if (filter_v1_1 != NULL) { + filter_v1_1->getId64Bit([&](Result result, uint64_t filterId) { + id = filterId; + status = result; + }); + } else { + filter->getId([&](Result result, uint32_t filterId) { + id = filterId; + status = result; + }); + } + + if (status != Result::SUCCESS) { + ALOGE("[Demux] Can't get filter Id."); + _hidl_cb(Result::INVALID_STATE, avSyncHwId); + return Void(); + } + + if (!mFilters[id]->isMediaFilter()) { + ALOGE("[Demux] Given filter is not a media filter."); + _hidl_cb(Result::INVALID_ARGUMENT, avSyncHwId); + return Void(); + } + + if (!mPcrFilterIds.empty()) { + // Return the lowest pcr filter id in the default implementation as the av sync id + _hidl_cb(Result::SUCCESS, *mPcrFilterIds.begin()); + return Void(); + } + + ALOGE("[Demux] No PCR filter opened."); + _hidl_cb(Result::INVALID_STATE, avSyncHwId); + return Void(); +} + +Return Demux::getAvSyncTime(AvSyncHwId avSyncHwId, getAvSyncTime_cb _hidl_cb) { + ALOGV("%s", __FUNCTION__); + + uint64_t avSyncTime = -1; + if (mPcrFilterIds.empty()) { + _hidl_cb(Result::INVALID_STATE, avSyncTime); + return Void(); + } + if (avSyncHwId != *mPcrFilterIds.begin()) { + _hidl_cb(Result::INVALID_ARGUMENT, avSyncTime); + return Void(); + } + + _hidl_cb(Result::SUCCESS, avSyncTime); + return Void(); +} + +Return Demux::close() { + ALOGV("%s", __FUNCTION__); + + set::iterator it; + for (it = mPlaybackFilterIds.begin(); it != mPlaybackFilterIds.end(); it++) { + mDvrPlayback->removePlaybackFilter(*it); + } + mPlaybackFilterIds.clear(); + mRecordFilterIds.clear(); + mFilters.clear(); + mLastUsedFilterId = -1; + + return Result::SUCCESS; +} + +Return Demux::openDvr(DvrType type, uint32_t bufferSize, const sp& cb, + openDvr_cb _hidl_cb) { + ALOGV("%s", __FUNCTION__); + + if (cb == nullptr) { + ALOGW("[Demux] DVR callback can't be null"); + _hidl_cb(Result::INVALID_ARGUMENT, new Dvr()); + return Void(); + } + + set::iterator it; + switch (type) { + case DvrType::PLAYBACK: + mDvrPlayback = new Dvr(type, bufferSize, cb, this); + if (!mDvrPlayback->createDvrMQ()) { + _hidl_cb(Result::UNKNOWN_ERROR, mDvrPlayback); + return Void(); + } + + for (it = mPlaybackFilterIds.begin(); it != mPlaybackFilterIds.end(); it++) { + if (!mDvrPlayback->addPlaybackFilter(*it, mFilters[*it])) { + ALOGE("[Demux] Can't get filter info for DVR playback"); + _hidl_cb(Result::UNKNOWN_ERROR, mDvrPlayback); + return Void(); + } + } + + _hidl_cb(Result::SUCCESS, mDvrPlayback); + return Void(); + case DvrType::RECORD: + mDvrRecord = new Dvr(type, bufferSize, cb, this); + if (!mDvrRecord->createDvrMQ()) { + _hidl_cb(Result::UNKNOWN_ERROR, mDvrRecord); + return Void(); + } + + _hidl_cb(Result::SUCCESS, mDvrRecord); + return Void(); + default: + _hidl_cb(Result::INVALID_ARGUMENT, nullptr); + return Void(); + } +} + +Return Demux::connectCiCam(uint32_t ciCamId) { + ALOGV("%s", __FUNCTION__); + + mCiCamId = ciCamId; + + return Result::SUCCESS; +} + +Return Demux::disconnectCiCam() { + ALOGV("%s", __FUNCTION__); + + return Result::SUCCESS; +} + +Result Demux::removeFilter(uint64_t filterId) { + ALOGV("%s", __FUNCTION__); + + if (mDvrPlayback != nullptr) { + mDvrPlayback->removePlaybackFilter(filterId); + } + mPlaybackFilterIds.erase(filterId); + mRecordFilterIds.erase(filterId); + mFilters.erase(filterId); + + return Result::SUCCESS; +} + +void Demux::startBroadcastTsFilter(vector data) { + set::iterator it; + uint16_t pid = ((data[1] & 0x1f) << 8) | ((data[2] & 0xff)); + if (DEBUG_DEMUX) { + ALOGW("[Demux] start ts filter pid: %d", pid); + } + for (it = mPlaybackFilterIds.begin(); it != mPlaybackFilterIds.end(); it++) { + if (pid == mFilters[*it]->getTpid()) { + mFilters[*it]->updateFilterOutput(data); + } + } +} + +void Demux::sendFrontendInputToRecord(vector data) { + set::iterator it; + if (DEBUG_DEMUX) { + ALOGW("[Demux] update record filter output"); + } + for (it = mRecordFilterIds.begin(); it != mRecordFilterIds.end(); it++) { + mFilters[*it]->updateRecordOutput(data); + } +} + +bool Demux::startBroadcastFilterDispatcher() { + set::iterator it; + + // Handle the output data per filter type + for (it = mPlaybackFilterIds.begin(); it != mPlaybackFilterIds.end(); it++) { + if (mFilters[*it]->startFilterHandler() != Result::SUCCESS) { + return false; + } + } + + return true; +} + +bool Demux::startRecordFilterDispatcher() { + set::iterator it; + + for (it = mRecordFilterIds.begin(); it != mRecordFilterIds.end(); it++) { + if (mFilters[*it]->startRecordFilterHandler() != Result::SUCCESS) { + return false; + } + } + + return true; +} + +Result Demux::startFilterHandler(uint64_t filterId) { + return mFilters[filterId]->startFilterHandler(); +} + +void Demux::updateFilterOutput(uint64_t filterId, vector data) { + mFilters[filterId]->updateFilterOutput(data); +} + +void Demux::updateMediaFilterOutput(uint64_t filterId, vector data, uint64_t pts) { + updateFilterOutput(filterId, data); + mFilters[filterId]->updatePts(pts); +} + +uint16_t Demux::getFilterTpid(uint64_t filterId) { + return mFilters[filterId]->getTpid(); +} + +void Demux::startFrontendInputLoop() { + pthread_create(&mFrontendInputThread, NULL, __threadLoopFrontend, this); + pthread_setname_np(mFrontendInputThread, "frontend_input_thread"); +} + +void* Demux::__threadLoopFrontend(void* user) { + Demux* const self = static_cast(user); + self->frontendInputThreadLoop(); + return 0; +} + +void Demux::frontendInputThreadLoop() { + std::lock_guard lock(mFrontendInputThreadLock); + mFrontendInputThreadRunning = true; + + while (mFrontendInputThreadRunning) { + uint32_t efState = 0; + status_t status = mDvrPlayback->getDvrEventFlag()->wait( + static_cast(DemuxQueueNotifyBits::DATA_READY), &efState, WAIT_TIMEOUT, + true /* retry on spurious wake */); + if (status != OK) { + ALOGD("[Demux] wait for data ready on the playback FMQ"); + continue; + } + if (mDvrPlayback->getSettings().playback().dataFormat == DataFormat::ES) { + if (!mDvrPlayback->processEsDataOnPlayback(true /*isVirtualFrontend*/, mIsRecording)) { + ALOGE("[Demux] playback es data failed to be filtered. Ending thread"); + break; + } + } + // Our current implementation filter the data and write it into the filter FMQ immediately + // after the DATA_READY from the VTS/framework + if (!mDvrPlayback->readPlaybackFMQ(true /*isVirtualFrontend*/, mIsRecording) || + !mDvrPlayback->startFilterDispatcher(true /*isVirtualFrontend*/, mIsRecording)) { + ALOGE("[Demux] playback data failed to be filtered. Ending thread"); + break; + } + } + + mFrontendInputThreadRunning = false; + ALOGW("[Demux] Frontend Input thread end."); +} + +void Demux::stopFrontendInput() { + ALOGD("[Demux] stop frontend on demux"); + mKeepFetchingDataFromFrontend = false; + mFrontendInputThreadRunning = false; + std::lock_guard lock(mFrontendInputThreadLock); +} + +void Demux::setIsRecording(bool isRecording) { + mIsRecording = isRecording; +} + +bool Demux::attachRecordFilter(uint64_t filterId) { + if (mFilters[filterId] == nullptr || mDvrRecord == nullptr || + !mFilters[filterId]->isRecordFilter()) { + return false; + } + + mRecordFilterIds.insert(filterId); + mFilters[filterId]->attachFilterToRecord(mDvrRecord); + + return true; +} + +bool Demux::detachRecordFilter(uint64_t filterId) { + if (mFilters[filterId] == nullptr || mDvrRecord == nullptr) { + return false; + } + + mRecordFilterIds.erase(filterId); + mFilters[filterId]->detachFilterFromRecord(); + + return true; +} + +} // namespace implementation +} // namespace V1_0 +} // namespace tuner +} // namespace tv +} // namespace hardware +} // namespace android diff --git a/tv/tuner/1.1/default/Demux.h b/tv/tuner/1.1/default/Demux.h new file mode 100644 index 0000000000..62f916267f --- /dev/null +++ b/tv/tuner/1.1/default/Demux.h @@ -0,0 +1,197 @@ +/* + * 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. + */ + +#ifndef ANDROID_HARDWARE_TV_TUNER_V1_1_DEMUX_H_ +#define ANDROID_HARDWARE_TV_TUNER_V1_1_DEMUX_H_ + +#include +#include +#include +#include "Dvr.h" +#include "Filter.h" +#include "Frontend.h" +#include "TimeFilter.h" +#include "Tuner.h" + +using namespace std; + +namespace android { +namespace hardware { +namespace tv { +namespace tuner { +namespace V1_0 { +namespace implementation { + +using ::android::hardware::EventFlag; +using ::android::hardware::kSynchronizedReadWrite; +using ::android::hardware::MessageQueue; +using ::android::hardware::MQDescriptorSync; + +using FilterMQ = MessageQueue; + +class Dvr; +class Filter; +class Frontend; +class TimeFilter; +class Tuner; + +class Demux : public IDemux { + public: + Demux(uint32_t demuxId, sp tuner); + + ~Demux(); + + virtual Return setFrontendDataSource(uint32_t frontendId) override; + + virtual Return openFilter(const DemuxFilterType& type, uint32_t bufferSize, + const sp& cb, openFilter_cb _hidl_cb) override; + + virtual Return openTimeFilter(openTimeFilter_cb _hidl_cb) override; + + virtual Return getAvSyncHwId(const sp& filter, + getAvSyncHwId_cb _hidl_cb) override; + + virtual Return getAvSyncTime(AvSyncHwId avSyncHwId, getAvSyncTime_cb _hidl_cb) override; + + virtual Return close() override; + + virtual Return openDvr(DvrType type, uint32_t bufferSize, const sp& cb, + openDvr_cb _hidl_cb) override; + + virtual Return connectCiCam(uint32_t ciCamId) override; + + virtual Return disconnectCiCam() override; + + // Functions interacts with Tuner Service + void stopFrontendInput(); + Result removeFilter(uint64_t filterId); + bool attachRecordFilter(uint64_t filterId); + bool detachRecordFilter(uint64_t filterId); + Result startFilterHandler(uint64_t filterId); + void updateFilterOutput(uint64_t filterId, vector data); + void updateMediaFilterOutput(uint64_t filterId, vector data, uint64_t pts); + uint16_t getFilterTpid(uint64_t filterId); + void setIsRecording(bool isRecording); + void startFrontendInputLoop(); + + /** + * A dispatcher to read and dispatch input data to all the started filters. + * Each filter handler handles the data filtering/output writing/filterEvent updating. + * Note that recording filters are not included. + */ + bool startBroadcastFilterDispatcher(); + void startBroadcastTsFilter(vector data); + + void sendFrontendInputToRecord(vector data); + bool startRecordFilterDispatcher(); + + private: + // Tuner service + sp mTunerService; + + // Frontend source + sp mFrontend; + + // A struct that passes the arguments to a newly created filter thread + struct ThreadArgs { + Demux* user; + uint64_t filterId; + }; + + static void* __threadLoopFrontend(void* user); + void frontendInputThreadLoop(); + + /** + * To create a FilterMQ with the next available Filter ID. + * Creating Event Flag at the same time. + * Add the successfully created/saved FilterMQ into the local list. + * + * Return false is any of the above processes fails. + */ + void deleteEventFlag(); + bool readDataFromMQ(); + + uint32_t mDemuxId = -1; + uint32_t mCiCamId; + set mPcrFilterIds; + /** + * Record the last used filter id. Initial value is -1. + * Filter Id starts with 0. + */ + uint64_t mLastUsedFilterId = -1; + /** + * Record all the used playback filter Ids. + * Any removed filter id should be removed from this set. + */ + set mPlaybackFilterIds; + /** + * Record all the attached record filter Ids. + * Any removed filter id should be removed from this set. + */ + set mRecordFilterIds; + /** + * A list of created Filter sp. + * The array number is the filter ID. + */ + std::map> mFilters; + + /** + * Local reference to the opened Timer Filter instance. + */ + sp mTimeFilter; + + /** + * Local reference to the opened DVR object. + */ + sp mDvrPlayback; + sp mDvrRecord; + + // Thread handlers + pthread_t mFrontendInputThread; + /** + * If a specific filter's writing loop is still running + */ + bool mFrontendInputThreadRunning; + bool mKeepFetchingDataFromFrontend; + /** + * If the dvr recording is running. + */ + bool mIsRecording = false; + /** + * Lock to protect writes to the FMQs + */ + std::mutex mWriteLock; + /** + * Lock to protect writes to the input status + */ + std::mutex mFrontendInputThreadLock; + + // temp handle single PES filter + // TODO handle mulptiple Pes filters + int mPesSizeLeft = 0; + vector mPesOutput; + + const bool DEBUG_DEMUX = false; +}; + +} // namespace implementation +} // namespace V1_0 +} // namespace tuner +} // namespace tv +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_TV_TUNER_V1_1_DEMUX_H_ diff --git a/tv/tuner/1.1/default/Descrambler.cpp b/tv/tuner/1.1/default/Descrambler.cpp new file mode 100644 index 0000000000..1fbc780c34 --- /dev/null +++ b/tv/tuner/1.1/default/Descrambler.cpp @@ -0,0 +1,80 @@ +/* + * 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. + */ + +#define LOG_TAG "android.hardware.tv.tuner@1.1-Descrambler" + +#include +#include + +#include "Descrambler.h" + +namespace android { +namespace hardware { +namespace tv { +namespace tuner { +namespace V1_0 { +namespace implementation { + +Descrambler::Descrambler() {} + +Descrambler::~Descrambler() {} + +Return Descrambler::setDemuxSource(uint32_t demuxId) { + ALOGV("%s", __FUNCTION__); + if (mDemuxSet) { + ALOGW("[ WARN ] Descrambler has already been set with a demux id %" PRIu32, + mSourceDemuxId); + return Result::INVALID_STATE; + } + mDemuxSet = true; + mSourceDemuxId = static_cast(demuxId); + + return Result::SUCCESS; +} + +Return Descrambler::setKeyToken(const hidl_vec& /* keyToken */) { + ALOGV("%s", __FUNCTION__); + + return Result::SUCCESS; +} + +Return Descrambler::addPid(const DemuxPid& /* pid */, + const sp& /* optionalSourceFilter */) { + ALOGV("%s", __FUNCTION__); + + return Result::SUCCESS; +} + +Return Descrambler::removePid(const DemuxPid& /* pid */, + const sp& /* optionalSourceFilter */) { + ALOGV("%s", __FUNCTION__); + + return Result::SUCCESS; +} + +Return Descrambler::close() { + ALOGV("%s", __FUNCTION__); + mDemuxSet = false; + + return Result::SUCCESS; +} + +} // namespace implementation +} // namespace V1_0 +} // namespace tuner +} // namespace tv +} // namespace hardware +} // namespace android diff --git a/tv/tuner/1.1/default/Descrambler.h b/tv/tuner/1.1/default/Descrambler.h new file mode 100644 index 0000000000..ffc284ddde --- /dev/null +++ b/tv/tuner/1.1/default/Descrambler.h @@ -0,0 +1,62 @@ +/* + * 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. + */ + +#ifndef ANDROID_HARDWARE_TV_TUNER_V1_1_DESCRAMBLER_H_ +#define ANDROID_HARDWARE_TV_TUNER_V1_1_DESCRAMBLER_H_ + +#include +#include +#include + +using namespace std; + +namespace android { +namespace hardware { +namespace tv { +namespace tuner { +namespace V1_0 { +namespace implementation { + +class Descrambler : public IDescrambler { + public: + Descrambler(); + + virtual Return setDemuxSource(uint32_t demuxId) override; + + virtual Return setKeyToken(const hidl_vec& keyToken) override; + + virtual Return addPid(const DemuxPid& pid, + const sp& optionalSourceFilter) override; + + virtual Return removePid(const DemuxPid& pid, + const sp& optionalSourceFilter) override; + + virtual Return close() override; + + private: + virtual ~Descrambler(); + uint32_t mSourceDemuxId; + bool mDemuxSet = false; +}; + +} // namespace implementation +} // namespace V1_0 +} // namespace tuner +} // namespace tv +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_TV_TUNER_V1_DESCRAMBLER_H_ diff --git a/tv/tuner/1.1/default/Dvr.cpp b/tv/tuner/1.1/default/Dvr.cpp new file mode 100644 index 0000000000..02d6a42e58 --- /dev/null +++ b/tv/tuner/1.1/default/Dvr.cpp @@ -0,0 +1,498 @@ +/* + * 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. + */ + +#define LOG_TAG "android.hardware.tv.tuner@1.1-Dvr" + +#include "Dvr.h" +#include + +namespace android { +namespace hardware { +namespace tv { +namespace tuner { +namespace V1_0 { +namespace implementation { + +#define WAIT_TIMEOUT 3000000000 + +Dvr::Dvr() {} + +Dvr::Dvr(DvrType type, uint32_t bufferSize, const sp& cb, sp demux) { + mType = type; + mBufferSize = bufferSize; + mCallback = cb; + mDemux = demux; +} + +Dvr::~Dvr() {} + +Return Dvr::getQueueDesc(getQueueDesc_cb _hidl_cb) { + ALOGV("%s", __FUNCTION__); + + _hidl_cb(Result::SUCCESS, *mDvrMQ->getDesc()); + return Void(); +} + +Return Dvr::configure(const DvrSettings& settings) { + ALOGV("%s", __FUNCTION__); + + mDvrSettings = settings; + mDvrConfigured = true; + + return Result::SUCCESS; +} + +Return Dvr::attachFilter(const sp& filter) { + ALOGV("%s", __FUNCTION__); + + uint64_t filterId; + Result status; + + sp filter_v1_1 = V1_1::IFilter::castFrom(filter); + if (filter_v1_1 != NULL) { + filter_v1_1->getId64Bit([&](Result result, uint64_t id) { + filterId = id; + status = result; + }); + } else { + filter->getId([&](Result result, uint32_t id) { + filterId = id; + status = result; + }); + } + + if (status != Result::SUCCESS) { + return status; + } + + // TODO check if the attached filter is a record filter + if (!mDemux->attachRecordFilter(filterId)) { + return Result::INVALID_ARGUMENT; + } + + return Result::SUCCESS; +} + +Return Dvr::detachFilter(const sp& filter) { + ALOGV("%s", __FUNCTION__); + + uint64_t filterId; + Result status; + + sp filter_v1_1 = V1_1::IFilter::castFrom(filter); + if (filter_v1_1 != NULL) { + filter_v1_1->getId64Bit([&](Result result, uint64_t id) { + filterId = id; + status = result; + }); + } else { + filter->getId([&](Result result, uint32_t id) { + filterId = id; + status = result; + }); + } + + if (status != Result::SUCCESS) { + return status; + } + + if (!mDemux->detachRecordFilter(filterId)) { + return Result::INVALID_ARGUMENT; + } + + return Result::SUCCESS; +} + +Return Dvr::start() { + ALOGV("%s", __FUNCTION__); + + if (!mCallback) { + return Result::NOT_INITIALIZED; + } + + if (!mDvrConfigured) { + return Result::INVALID_STATE; + } + + if (mType == DvrType::PLAYBACK) { + pthread_create(&mDvrThread, NULL, __threadLoopPlayback, this); + pthread_setname_np(mDvrThread, "playback_waiting_loop"); + } else if (mType == DvrType::RECORD) { + mRecordStatus = RecordStatus::DATA_READY; + mDemux->setIsRecording(mType == DvrType::RECORD); + } + + // TODO start another thread to send filter status callback to the framework + + return Result::SUCCESS; +} + +Return Dvr::stop() { + ALOGV("%s", __FUNCTION__); + + mDvrThreadRunning = false; + + lock_guard lock(mDvrThreadLock); + + mIsRecordStarted = false; + mDemux->setIsRecording(false); + + return Result::SUCCESS; +} + +Return Dvr::flush() { + ALOGV("%s", __FUNCTION__); + + mRecordStatus = RecordStatus::DATA_READY; + + return Result::SUCCESS; +} + +Return Dvr::close() { + ALOGV("%s", __FUNCTION__); + + return Result::SUCCESS; +} + +bool Dvr::createDvrMQ() { + ALOGV("%s", __FUNCTION__); + + // Create a synchronized FMQ that supports blocking read/write + unique_ptr tmpDvrMQ = unique_ptr(new (nothrow) DvrMQ(mBufferSize, true)); + if (!tmpDvrMQ->isValid()) { + ALOGW("[Dvr] Failed to create FMQ of DVR"); + return false; + } + + mDvrMQ = move(tmpDvrMQ); + + if (EventFlag::createEventFlag(mDvrMQ->getEventFlagWord(), &mDvrEventFlag) != OK) { + return false; + } + + return true; +} + +EventFlag* Dvr::getDvrEventFlag() { + return mDvrEventFlag; +} + +void* Dvr::__threadLoopPlayback(void* user) { + Dvr* const self = static_cast(user); + self->playbackThreadLoop(); + return 0; +} + +void Dvr::playbackThreadLoop() { + ALOGD("[Dvr] playback threadLoop start."); + lock_guard lock(mDvrThreadLock); + mDvrThreadRunning = true; + + while (mDvrThreadRunning) { + uint32_t efState = 0; + status_t status = + mDvrEventFlag->wait(static_cast(DemuxQueueNotifyBits::DATA_READY), + &efState, WAIT_TIMEOUT, true /* retry on spurious wake */); + if (status != OK) { + ALOGD("[Dvr] wait for data ready on the playback FMQ"); + continue; + } + + if (mDvrSettings.playback().dataFormat == DataFormat::ES) { + if (!processEsDataOnPlayback(false /*isVirtualFrontend*/, false /*isRecording*/)) { + ALOGE("[Dvr] playback es data failed to be filtered. Ending thread"); + break; + } + maySendPlaybackStatusCallback(); + } + // Our current implementation filter the data and write it into the filter FMQ immediately + // after the DATA_READY from the VTS/framework + if (!readPlaybackFMQ(false /*isVirtualFrontend*/, false /*isRecording*/) || + !startFilterDispatcher(false /*isVirtualFrontend*/, false /*isRecording*/)) { + ALOGE("[Dvr] playback data failed to be filtered. Ending thread"); + break; + } + + maySendPlaybackStatusCallback(); + } + + mDvrThreadRunning = false; + ALOGD("[Dvr] playback thread ended."); +} + +void Dvr::maySendPlaybackStatusCallback() { + lock_guard lock(mPlaybackStatusLock); + int availableToRead = mDvrMQ->availableToRead(); + int availableToWrite = mDvrMQ->availableToWrite(); + + PlaybackStatus newStatus = checkPlaybackStatusChange(availableToWrite, availableToRead, + mDvrSettings.playback().highThreshold, + mDvrSettings.playback().lowThreshold); + if (mPlaybackStatus != newStatus) { + mCallback->onPlaybackStatus(newStatus); + mPlaybackStatus = newStatus; + } +} + +PlaybackStatus Dvr::checkPlaybackStatusChange(uint32_t availableToWrite, uint32_t availableToRead, + uint32_t highThreshold, uint32_t lowThreshold) { + if (availableToWrite == 0) { + return PlaybackStatus::SPACE_FULL; + } else if (availableToRead > highThreshold) { + return PlaybackStatus::SPACE_ALMOST_FULL; + } else if (availableToRead < lowThreshold) { + return PlaybackStatus::SPACE_ALMOST_EMPTY; + } else if (availableToRead == 0) { + return PlaybackStatus::SPACE_EMPTY; + } + return mPlaybackStatus; +} + +bool Dvr::readPlaybackFMQ(bool isVirtualFrontend, bool isRecording) { + // Read playback data from the input FMQ + int size = mDvrMQ->availableToRead(); + int playbackPacketSize = mDvrSettings.playback().packetSize; + vector dataOutputBuffer; + dataOutputBuffer.resize(playbackPacketSize); + // Dispatch the packet to the PID matching filter output buffer + for (int i = 0; i < size / playbackPacketSize; i++) { + if (!mDvrMQ->read(dataOutputBuffer.data(), playbackPacketSize)) { + return false; + } + if (isVirtualFrontend) { + if (isRecording) { + mDemux->sendFrontendInputToRecord(dataOutputBuffer); + } else { + mDemux->startBroadcastTsFilter(dataOutputBuffer); + } + } else { + startTpidFilter(dataOutputBuffer); + } + } + + return true; +} + +bool Dvr::processEsDataOnPlayback(bool isVirtualFrontend, bool isRecording) { + // Read ES from the DVR FMQ + // Note that currently we only provides ES with metaData in a specific format to be parsed. + // The ES size should be smaller than the Playback FMQ size to avoid reading truncated data. + int size = mDvrMQ->availableToRead(); + vector dataOutputBuffer; + dataOutputBuffer.resize(size); + if (!mDvrMQ->read(dataOutputBuffer.data(), size)) { + return false; + } + + int metaDataSize = size; + int totalFrames = 0; + int videoEsDataSize = 0; + int audioEsDataSize = 0; + int audioPid = 0; + int videoPid = 0; + + vector esMeta; + int videoReadPointer = 0; + int audioReadPointer = 0; + int frameCount = 0; + // Get meta data from the es + for (int i = 0; i < metaDataSize; i++) { + switch (dataOutputBuffer[i]) { + case 'm': + metaDataSize = 0; + getMetaDataValue(i, dataOutputBuffer.data(), metaDataSize); + videoReadPointer = metaDataSize; + continue; + case 'l': + getMetaDataValue(i, dataOutputBuffer.data(), totalFrames); + esMeta.resize(totalFrames); + continue; + case 'V': + getMetaDataValue(i, dataOutputBuffer.data(), videoEsDataSize); + audioReadPointer = metaDataSize + videoEsDataSize; + continue; + case 'A': + getMetaDataValue(i, dataOutputBuffer.data(), audioEsDataSize); + continue; + case 'p': + if (dataOutputBuffer[++i] == 'a') { + getMetaDataValue(i, dataOutputBuffer.data(), audioPid); + } else if (dataOutputBuffer[i] == 'v') { + getMetaDataValue(i, dataOutputBuffer.data(), videoPid); + } + continue; + case 'v': + case 'a': + if (dataOutputBuffer[i + 1] != ',') { + ALOGE("[Dvr] Invalid format meta data."); + return false; + } + esMeta[frameCount] = { + .isAudio = dataOutputBuffer[i] == 'a' ? true : false, + }; + i += 5; // Move to Len + getMetaDataValue(i, dataOutputBuffer.data(), esMeta[frameCount].len); + if (esMeta[frameCount].isAudio) { + esMeta[frameCount].startIndex = audioReadPointer; + audioReadPointer += esMeta[frameCount].len; + } else { + esMeta[frameCount].startIndex = videoReadPointer; + videoReadPointer += esMeta[frameCount].len; + } + i += 4; // move to PTS + getMetaDataValue(i, dataOutputBuffer.data(), esMeta[frameCount].pts); + frameCount++; + continue; + default: + continue; + } + } + + if (frameCount != totalFrames) { + ALOGE("[Dvr] Invalid meta data, frameCount=%d, totalFrames reported=%d", frameCount, + totalFrames); + return false; + } + + if (metaDataSize + audioEsDataSize + videoEsDataSize != size) { + ALOGE("[Dvr] Invalid meta data, metaSize=%d, videoSize=%d, audioSize=%d, totolSize=%d", + metaDataSize, videoEsDataSize, audioEsDataSize, size); + return false; + } + + // Read es raw data from the FMQ per meta data built previously + vector frameData; + map>::iterator it; + int pid = 0; + for (int i = 0; i < totalFrames; i++) { + frameData.resize(esMeta[i].len); + pid = esMeta[i].isAudio ? audioPid : videoPid; + memcpy(dataOutputBuffer.data() + esMeta[i].startIndex, frameData.data(), esMeta[i].len); + // Send to the media filter + if (isVirtualFrontend && isRecording) { + // TODO validate record + mDemux->sendFrontendInputToRecord(frameData); + } else { + for (it = mFilters.begin(); it != mFilters.end(); it++) { + if (pid == mDemux->getFilterTpid(it->first)) { + mDemux->updateMediaFilterOutput(it->first, frameData, + static_cast(esMeta[i].pts)); + startFilterDispatcher(isVirtualFrontend, isRecording); + } + } + } + } + + return true; +} + +void Dvr::getMetaDataValue(int& index, uint8_t* dataOutputBuffer, int& value) { + index += 2; // Move the pointer across the ":" to the value + while (dataOutputBuffer[index] != ',' && dataOutputBuffer[index] != '\n') { + value = ((dataOutputBuffer[index++] - 48) + value * 10); + } +} + +void Dvr::startTpidFilter(vector data) { + map>::iterator it; + for (it = mFilters.begin(); it != mFilters.end(); it++) { + uint16_t pid = ((data[1] & 0x1f) << 8) | ((data[2] & 0xff)); + if (DEBUG_DVR) { + ALOGW("[Dvr] start ts filter pid: %d", pid); + } + if (pid == mDemux->getFilterTpid(it->first)) { + mDemux->updateFilterOutput(it->first, data); + } + } +} + +bool Dvr::startFilterDispatcher(bool isVirtualFrontend, bool isRecording) { + if (isVirtualFrontend) { + if (isRecording) { + return mDemux->startRecordFilterDispatcher(); + } else { + return mDemux->startBroadcastFilterDispatcher(); + } + } + + map>::iterator it; + // Handle the output data per filter type + for (it = mFilters.begin(); it != mFilters.end(); it++) { + if (mDemux->startFilterHandler(it->first) != Result::SUCCESS) { + return false; + } + } + + return true; +} + +bool Dvr::writeRecordFMQ(const vector& data) { + lock_guard lock(mWriteLock); + if (mRecordStatus == RecordStatus::OVERFLOW) { + ALOGW("[Dvr] stops writing and wait for the client side flushing."); + return true; + } + if (mDvrMQ->write(data.data(), data.size())) { + mDvrEventFlag->wake(static_cast(DemuxQueueNotifyBits::DATA_READY)); + maySendRecordStatusCallback(); + return true; + } + + maySendRecordStatusCallback(); + return false; +} + +void Dvr::maySendRecordStatusCallback() { + lock_guard lock(mRecordStatusLock); + int availableToRead = mDvrMQ->availableToRead(); + int availableToWrite = mDvrMQ->availableToWrite(); + + RecordStatus newStatus = checkRecordStatusChange(availableToWrite, availableToRead, + mDvrSettings.record().highThreshold, + mDvrSettings.record().lowThreshold); + if (mRecordStatus != newStatus) { + mCallback->onRecordStatus(newStatus); + mRecordStatus = newStatus; + } +} + +RecordStatus Dvr::checkRecordStatusChange(uint32_t availableToWrite, uint32_t availableToRead, + uint32_t highThreshold, uint32_t lowThreshold) { + if (availableToWrite == 0) { + return DemuxFilterStatus::OVERFLOW; + } else if (availableToRead > highThreshold) { + return DemuxFilterStatus::HIGH_WATER; + } else if (availableToRead < lowThreshold) { + return DemuxFilterStatus::LOW_WATER; + } + return mRecordStatus; +} + +bool Dvr::addPlaybackFilter(uint64_t filterId, sp filter) { + mFilters[filterId] = filter; + return true; +} + +bool Dvr::removePlaybackFilter(uint64_t filterId) { + mFilters.erase(filterId); + return true; +} +} // namespace implementation +} // namespace V1_0 +} // namespace tuner +} // namespace tv +} // namespace hardware +} // namespace android diff --git a/tv/tuner/1.1/default/Dvr.h b/tv/tuner/1.1/default/Dvr.h new file mode 100644 index 0000000000..7b7efefada --- /dev/null +++ b/tv/tuner/1.1/default/Dvr.h @@ -0,0 +1,167 @@ +/* + * 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. + */ + +#ifndef ANDROID_HARDWARE_TV_TUNER_V1_1_DVR_H_ +#define ANDROID_HARDWARE_TV_TUNER_V1_1_DVR_H_ + +#include +#include +#include +#include "Demux.h" +#include "Frontend.h" +#include "Tuner.h" + +using namespace std; + +namespace android { +namespace hardware { +namespace tv { +namespace tuner { +namespace V1_0 { +namespace implementation { + +using ::android::hardware::EventFlag; +using ::android::hardware::kSynchronizedReadWrite; +using ::android::hardware::MessageQueue; +using ::android::hardware::MQDescriptorSync; + +using DvrMQ = MessageQueue; + +struct MediaEsMetaData { + bool isAudio; + int startIndex; + int len; + int pts; +}; + +class Demux; +class Filter; +class Frontend; +class Tuner; + +class Dvr : public IDvr { + public: + Dvr(); + + Dvr(DvrType type, uint32_t bufferSize, const sp& cb, sp demux); + + ~Dvr(); + + virtual Return getQueueDesc(getQueueDesc_cb _hidl_cb) override; + + virtual Return configure(const DvrSettings& settings) override; + + virtual Return attachFilter(const sp& filter) override; + + virtual Return detachFilter(const sp& filter) override; + + virtual Return start() override; + + virtual Return stop() override; + + virtual Return flush() override; + + virtual Return close() override; + + /** + * To create a DvrMQ and its Event Flag. + * + * Return false is any of the above processes fails. + */ + bool createDvrMQ(); + void sendBroadcastInputToDvrRecord(vector byteBuffer); + bool writeRecordFMQ(const std::vector& data); + bool addPlaybackFilter(uint64_t filterId, sp filter); + bool removePlaybackFilter(uint64_t filterId); + bool readPlaybackFMQ(bool isVirtualFrontend, bool isRecording); + bool processEsDataOnPlayback(bool isVirtualFrontend, bool isRecording); + bool startFilterDispatcher(bool isVirtualFrontend, bool isRecording); + EventFlag* getDvrEventFlag(); + DvrSettings getSettings() { return mDvrSettings; } + + private: + // Demux service + sp mDemux; + + DvrType mType; + uint32_t mBufferSize; + sp mCallback; + std::map> mFilters; + + void deleteEventFlag(); + bool readDataFromMQ(); + void getMetaDataValue(int& index, uint8_t* dataOutputBuffer, int& value); + void maySendPlaybackStatusCallback(); + void maySendRecordStatusCallback(); + PlaybackStatus checkPlaybackStatusChange(uint32_t availableToWrite, uint32_t availableToRead, + uint32_t highThreshold, uint32_t lowThreshold); + RecordStatus checkRecordStatusChange(uint32_t availableToWrite, uint32_t availableToRead, + uint32_t highThreshold, uint32_t lowThreshold); + /** + * A dispatcher to read and dispatch input data to all the started filters. + * Each filter handler handles the data filtering/output writing/filterEvent updating. + */ + void startTpidFilter(vector data); + static void* __threadLoopPlayback(void* user); + static void* __threadLoopRecord(void* user); + void playbackThreadLoop(); + void recordThreadLoop(); + + unique_ptr mDvrMQ; + EventFlag* mDvrEventFlag; + /** + * Demux callbacks used on filter events or IO buffer status + */ + bool mDvrConfigured = false; + DvrSettings mDvrSettings; + + // Thread handlers + pthread_t mDvrThread; + + // FMQ status local records + PlaybackStatus mPlaybackStatus; + RecordStatus mRecordStatus; + /** + * If a specific filter's writing loop is still running + */ + bool mDvrThreadRunning; + bool mKeepFetchingDataFromFrontend; + /** + * Lock to protect writes to the FMQs + */ + std::mutex mWriteLock; + /** + * Lock to protect writes to the input status + */ + std::mutex mPlaybackStatusLock; + std::mutex mRecordStatusLock; + std::mutex mDvrThreadLock; + + const bool DEBUG_DVR = false; + + // Booleans to check if recording is running. + // Recording is ready when both of the following are set to true. + bool mIsRecordStarted = false; +}; + +} // namespace implementation +} // namespace V1_0 +} // namespace tuner +} // namespace tv +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_TV_TUNER_V1_1_DVR_H_ \ No newline at end of file diff --git a/tv/tuner/1.1/default/Filter.cpp b/tv/tuner/1.1/default/Filter.cpp new file mode 100644 index 0000000000..108baf74f3 --- /dev/null +++ b/tv/tuner/1.1/default/Filter.cpp @@ -0,0 +1,672 @@ +/* + * 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. + */ + +#define LOG_TAG "android.hardware.tv.tuner@1.1-Filter" + +#include "Filter.h" +#include + +namespace android { +namespace hardware { +namespace tv { +namespace tuner { +namespace V1_0 { +namespace implementation { + +#define WAIT_TIMEOUT 3000000000 + +Filter::Filter() {} + +Filter::Filter(DemuxFilterType type, uint64_t filterId, uint32_t bufferSize, + const sp& cb, sp demux) { + mType = type; + mFilterId = filterId; + mBufferSize = bufferSize; + mCallback = cb; + mDemux = demux; + + switch (mType.mainType) { + case DemuxFilterMainType::TS: + if (mType.subType.tsFilterType() == DemuxTsFilterType::AUDIO || + mType.subType.tsFilterType() == DemuxTsFilterType::VIDEO) { + mIsMediaFilter = true; + } + if (mType.subType.tsFilterType() == DemuxTsFilterType::PCR) { + mIsPcrFilter = true; + } + if (mType.subType.tsFilterType() == DemuxTsFilterType::RECORD) { + mIsRecordFilter = true; + } + break; + case DemuxFilterMainType::MMTP: + if (mType.subType.mmtpFilterType() == DemuxMmtpFilterType::AUDIO || + mType.subType.mmtpFilterType() == DemuxMmtpFilterType::VIDEO) { + mIsMediaFilter = true; + } + if (mType.subType.mmtpFilterType() == DemuxMmtpFilterType::RECORD) { + mIsRecordFilter = true; + } + break; + case DemuxFilterMainType::IP: + break; + case DemuxFilterMainType::TLV: + break; + case DemuxFilterMainType::ALP: + break; + default: + break; + } +} + +Filter::~Filter() {} + +Return Filter::getId64Bit(getId64Bit_cb _hidl_cb) { + ALOGV("%s", __FUNCTION__); + + _hidl_cb(Result::SUCCESS, mFilterId); + return Void(); +} + +Return Filter::getId(getId_cb _hidl_cb) { + ALOGV("%s", __FUNCTION__); + + _hidl_cb(Result::SUCCESS, static_cast(mFilterId)); + return Void(); +} + +Return Filter::setDataSource(const sp& filter) { + ALOGV("%s", __FUNCTION__); + + mDataSource = filter; + mIsDataSourceDemux = false; + + return Result::SUCCESS; +} + +Return Filter::getQueueDesc(getQueueDesc_cb _hidl_cb) { + ALOGV("%s", __FUNCTION__); + + mIsUsingFMQ = true; + + _hidl_cb(Result::SUCCESS, *mFilterMQ->getDesc()); + return Void(); +} + +Return Filter::configure(const DemuxFilterSettings& settings) { + ALOGV("%s", __FUNCTION__); + + mFilterSettings = settings; + switch (mType.mainType) { + case DemuxFilterMainType::TS: + mTpid = settings.ts().tpid; + break; + case DemuxFilterMainType::MMTP: + break; + case DemuxFilterMainType::IP: + break; + case DemuxFilterMainType::TLV: + break; + case DemuxFilterMainType::ALP: + break; + default: + break; + } + + return Result::SUCCESS; +} + +Return Filter::start() { + ALOGV("%s", __FUNCTION__); + + return startFilterLoop(); +} + +Return Filter::stop() { + ALOGV("%s", __FUNCTION__); + + mFilterThreadRunning = false; + + std::lock_guard lock(mFilterThreadLock); + + return Result::SUCCESS; +} + +Return Filter::flush() { + ALOGV("%s", __FUNCTION__); + + // temp implementation to flush the FMQ + int size = mFilterMQ->availableToRead(); + char* buffer = new char[size]; + mFilterMQ->read((unsigned char*)&buffer[0], size); + delete[] buffer; + mFilterStatus = DemuxFilterStatus::DATA_READY; + + return Result::SUCCESS; +} + +Return Filter::releaseAvHandle(const hidl_handle& /*avMemory*/, uint64_t avDataId) { + ALOGV("%s", __FUNCTION__); + if (mDataId2Avfd.find(avDataId) == mDataId2Avfd.end()) { + return Result::INVALID_ARGUMENT; + } + + ::close(mDataId2Avfd[avDataId]); + return Result::SUCCESS; +} + +Return Filter::close() { + ALOGV("%s", __FUNCTION__); + + return mDemux->removeFilter(mFilterId); +} + +bool Filter::createFilterMQ() { + ALOGV("%s", __FUNCTION__); + + // Create a synchronized FMQ that supports blocking read/write + std::unique_ptr tmpFilterMQ = + std::unique_ptr(new (std::nothrow) FilterMQ(mBufferSize, true)); + if (!tmpFilterMQ->isValid()) { + ALOGW("[Filter] Failed to create FMQ of filter with id: %" PRIu64, mFilterId); + return false; + } + + mFilterMQ = std::move(tmpFilterMQ); + + if (EventFlag::createEventFlag(mFilterMQ->getEventFlagWord(), &mFilterEventFlag) != OK) { + return false; + } + + return true; +} + +Result Filter::startFilterLoop() { + pthread_create(&mFilterThread, NULL, __threadLoopFilter, this); + pthread_setname_np(mFilterThread, "filter_waiting_loop"); + + return Result::SUCCESS; +} + +void* Filter::__threadLoopFilter(void* user) { + Filter* const self = static_cast(user); + self->filterThreadLoop(); + return 0; +} + +void Filter::filterThreadLoop() { + ALOGD("[Filter] filter %" PRIu64 " threadLoop start.", mFilterId); + std::lock_guard lock(mFilterThreadLock); + mFilterThreadRunning = true; + + // For the first time of filter output, implementation needs to send the filter + // Event Callback without waiting for the DATA_CONSUMED to init the process. + while (mFilterThreadRunning) { + if (mFilterEvent.events.size() == 0) { + if (DEBUG_FILTER) { + ALOGD("[Filter] wait for filter data output."); + } + usleep(1000 * 1000); + continue; + } + // After successfully write, send a callback and wait for the read to be done + mCallback->onFilterEvent(mFilterEvent); + freeAvHandle(); + mFilterEvent.events.resize(0); + mFilterStatus = DemuxFilterStatus::DATA_READY; + if (mCallback == nullptr) { + ALOGD("[Filter] filter %" PRIu64 " does not hava callback. Ending thread", mFilterId); + break; + } + mCallback->onFilterStatus(mFilterStatus); + break; + } + + while (mFilterThreadRunning) { + uint32_t efState = 0; + // We do not wait for the last round of written data to be read to finish the thread + // because the VTS can verify the reading itself. + for (int i = 0; i < SECTION_WRITE_COUNT; i++) { + while (mFilterThreadRunning && mIsUsingFMQ) { + status_t status = mFilterEventFlag->wait( + static_cast(DemuxQueueNotifyBits::DATA_CONSUMED), &efState, + WAIT_TIMEOUT, true /* retry on spurious wake */); + if (status != OK) { + ALOGD("[Filter] wait for data consumed"); + continue; + } + break; + } + + maySendFilterStatusCallback(); + + while (mFilterThreadRunning) { + std::lock_guard lock(mFilterEventLock); + if (mFilterEvent.events.size() == 0) { + continue; + } + // After successfully write, send a callback and wait for the read to be done + mCallback->onFilterEvent(mFilterEvent); + mFilterEvent.events.resize(0); + break; + } + // We do not wait for the last read to be done + // VTS can verify the read result itself. + if (i == SECTION_WRITE_COUNT - 1) { + ALOGD("[Filter] filter %" PRIu64 " writing done. Ending thread", mFilterId); + break; + } + } + mFilterThreadRunning = false; + } + + ALOGD("[Filter] filter thread ended."); +} + +void Filter::freeAvHandle() { + if (!mIsMediaFilter) { + return; + } + for (int i = 0; i < mFilterEvent.events.size(); i++) { + ::close(mFilterEvent.events[i].media().avMemory.getNativeHandle()->data[0]); + native_handle_close(mFilterEvent.events[i].media().avMemory.getNativeHandle()); + } +} + +void Filter::maySendFilterStatusCallback() { + if (!mIsUsingFMQ) { + return; + } + std::lock_guard lock(mFilterStatusLock); + int availableToRead = mFilterMQ->availableToRead(); + int availableToWrite = mFilterMQ->availableToWrite(); + int fmqSize = mFilterMQ->getQuantumCount(); + + DemuxFilterStatus newStatus = checkFilterStatusChange( + availableToWrite, availableToRead, ceil(fmqSize * 0.75), ceil(fmqSize * 0.25)); + if (mFilterStatus != newStatus) { + mCallback->onFilterStatus(newStatus); + mFilterStatus = newStatus; + } +} + +DemuxFilterStatus Filter::checkFilterStatusChange(uint32_t availableToWrite, + uint32_t availableToRead, uint32_t highThreshold, + uint32_t lowThreshold) { + if (availableToWrite == 0) { + return DemuxFilterStatus::OVERFLOW; + } else if (availableToRead > highThreshold) { + return DemuxFilterStatus::HIGH_WATER; + } else if (availableToRead < lowThreshold) { + return DemuxFilterStatus::LOW_WATER; + } + return mFilterStatus; +} + +uint16_t Filter::getTpid() { + return mTpid; +} + +void Filter::updateFilterOutput(vector data) { + std::lock_guard lock(mFilterOutputLock); + mFilterOutput.insert(mFilterOutput.end(), data.begin(), data.end()); +} + +void Filter::updatePts(uint64_t pts) { + std::lock_guard lock(mFilterOutputLock); + mPts = pts; +} + +void Filter::updateRecordOutput(vector data) { + std::lock_guard lock(mRecordFilterOutputLock); + mRecordFilterOutput.insert(mRecordFilterOutput.end(), data.begin(), data.end()); +} + +Result Filter::startFilterHandler() { + std::lock_guard lock(mFilterOutputLock); + switch (mType.mainType) { + case DemuxFilterMainType::TS: + switch (mType.subType.tsFilterType()) { + case DemuxTsFilterType::UNDEFINED: + break; + case DemuxTsFilterType::SECTION: + startSectionFilterHandler(); + break; + case DemuxTsFilterType::PES: + startPesFilterHandler(); + break; + case DemuxTsFilterType::TS: + startTsFilterHandler(); + break; + case DemuxTsFilterType::AUDIO: + case DemuxTsFilterType::VIDEO: + startMediaFilterHandler(); + break; + case DemuxTsFilterType::PCR: + startPcrFilterHandler(); + break; + case DemuxTsFilterType::TEMI: + startTemiFilterHandler(); + break; + default: + break; + } + break; + case DemuxFilterMainType::MMTP: + /*mmtpSettings*/ + break; + case DemuxFilterMainType::IP: + /*ipSettings*/ + break; + case DemuxFilterMainType::TLV: + /*tlvSettings*/ + break; + case DemuxFilterMainType::ALP: + /*alpSettings*/ + break; + default: + break; + } + return Result::SUCCESS; +} + +Result Filter::startSectionFilterHandler() { + if (mFilterOutput.empty()) { + return Result::SUCCESS; + } + if (!writeSectionsAndCreateEvent(mFilterOutput)) { + ALOGD("[Filter] filter %" PRIu64 " fails to write into FMQ. Ending thread", mFilterId); + return Result::UNKNOWN_ERROR; + } + + mFilterOutput.clear(); + + return Result::SUCCESS; +} + +Result Filter::startPesFilterHandler() { + std::lock_guard lock(mFilterEventLock); + if (mFilterOutput.empty()) { + return Result::SUCCESS; + } + + for (int i = 0; i < mFilterOutput.size(); i += 188) { + if (mPesSizeLeft == 0) { + uint32_t prefix = (mFilterOutput[i + 4] << 16) | (mFilterOutput[i + 5] << 8) | + mFilterOutput[i + 6]; + if (DEBUG_FILTER) { + ALOGD("[Filter] prefix %d", prefix); + } + if (prefix == 0x000001) { + // TODO handle mulptiple Pes filters + mPesSizeLeft = (mFilterOutput[i + 8] << 8) | mFilterOutput[i + 9]; + mPesSizeLeft += 6; + if (DEBUG_FILTER) { + ALOGD("[Filter] pes data length %d", mPesSizeLeft); + } + } else { + continue; + } + } + + int endPoint = min(184, mPesSizeLeft); + // append data and check size + vector::const_iterator first = mFilterOutput.begin() + i + 4; + vector::const_iterator last = mFilterOutput.begin() + i + 4 + endPoint; + mPesOutput.insert(mPesOutput.end(), first, last); + // size does not match then continue + mPesSizeLeft -= endPoint; + if (DEBUG_FILTER) { + ALOGD("[Filter] pes data left %d", mPesSizeLeft); + } + if (mPesSizeLeft > 0) { + continue; + } + // size match then create event + if (!writeDataToFilterMQ(mPesOutput)) { + ALOGD("[Filter] pes data write failed"); + mFilterOutput.clear(); + return Result::INVALID_STATE; + } + maySendFilterStatusCallback(); + DemuxFilterPesEvent pesEvent; + pesEvent = { + // temp dump meta data + .streamId = mPesOutput[3], + .dataLength = static_cast(mPesOutput.size()), + }; + if (DEBUG_FILTER) { + ALOGD("[Filter] assembled pes data length %d", pesEvent.dataLength); + } + + int size = mFilterEvent.events.size(); + mFilterEvent.events.resize(size + 1); + mFilterEvent.events[size].pes(pesEvent); + mPesOutput.clear(); + } + + mFilterOutput.clear(); + + return Result::SUCCESS; +} + +Result Filter::startTsFilterHandler() { + // TODO handle starting TS filter + return Result::SUCCESS; +} + +Result Filter::startMediaFilterHandler() { + std::lock_guard lock(mFilterEventLock); + if (mFilterOutput.empty()) { + return Result::SUCCESS; + } + + if (mPts) { + return createMediaFilterEventWithIon(mFilterOutput); + } + + for (int i = 0; i < mFilterOutput.size(); i += 188) { + if (mPesSizeLeft == 0) { + uint32_t prefix = (mFilterOutput[i + 4] << 16) | (mFilterOutput[i + 5] << 8) | + mFilterOutput[i + 6]; + if (DEBUG_FILTER) { + ALOGD("[Filter] prefix %d", prefix); + } + if (prefix == 0x000001) { + // TODO handle mulptiple Pes filters + mPesSizeLeft = (mFilterOutput[i + 8] << 8) | mFilterOutput[i + 9]; + mPesSizeLeft += 6; + if (DEBUG_FILTER) { + ALOGD("[Filter] pes data length %d", mPesSizeLeft); + } + } else { + continue; + } + } + + int endPoint = min(184, mPesSizeLeft); + // append data and check size + vector::const_iterator first = mFilterOutput.begin() + i + 4; + vector::const_iterator last = mFilterOutput.begin() + i + 4 + endPoint; + mPesOutput.insert(mPesOutput.end(), first, last); + // size does not match then continue + mPesSizeLeft -= endPoint; + if (DEBUG_FILTER) { + ALOGD("[Filter] pes data left %d", mPesSizeLeft); + } + if (mPesSizeLeft > 0 || mAvBufferCopyCount++ < 10) { + continue; + } + + createMediaFilterEventWithIon(mPesOutput); + } + + mFilterOutput.clear(); + + return Result::SUCCESS; +} + +Result Filter::createMediaFilterEventWithIon(vector output) { + int av_fd = createAvIonFd(output.size()); + if (av_fd == -1) { + return Result::UNKNOWN_ERROR; + } + // copy the filtered data to the buffer + uint8_t* avBuffer = getIonBuffer(av_fd, output.size()); + if (avBuffer == NULL) { + return Result::UNKNOWN_ERROR; + } + memcpy(avBuffer, output.data(), output.size() * sizeof(uint8_t)); + + native_handle_t* nativeHandle = createNativeHandle(av_fd); + if (nativeHandle == NULL) { + return Result::UNKNOWN_ERROR; + } + hidl_handle handle; + handle.setTo(nativeHandle, /*shouldOwn=*/true); + + // Create a dataId and add a pair into the dataId2Avfd map + uint64_t dataId = mLastUsedDataId++ /*createdUID*/; + mDataId2Avfd[dataId] = dup(av_fd); + + // Create mediaEvent and send callback + DemuxFilterMediaEvent mediaEvent; + mediaEvent = { + .avMemory = std::move(handle), + .dataLength = static_cast(output.size()), + .avDataId = dataId, + }; + if (mPts) { + mediaEvent.pts = mPts; + mPts = 0; + } + int size = mFilterEvent.events.size(); + mFilterEvent.events.resize(size + 1); + mFilterEvent.events[size].media(mediaEvent); + + // Clear and log + output.clear(); + mAvBufferCopyCount = 0; + ::close(av_fd); + if (DEBUG_FILTER) { + ALOGD("[Filter] av data length %d", mediaEvent.dataLength); + } + return Result::SUCCESS; +} + +Result Filter::startRecordFilterHandler() { + std::lock_guard lock(mRecordFilterOutputLock); + if (mRecordFilterOutput.empty()) { + return Result::SUCCESS; + } + + if (mDvr == nullptr || !mDvr->writeRecordFMQ(mRecordFilterOutput)) { + ALOGD("[Filter] dvr fails to write into record FMQ."); + return Result::UNKNOWN_ERROR; + } + + mRecordFilterOutput.clear(); + return Result::SUCCESS; +} + +Result Filter::startPcrFilterHandler() { + // TODO handle starting PCR filter + return Result::SUCCESS; +} + +Result Filter::startTemiFilterHandler() { + // TODO handle starting TEMI filter + return Result::SUCCESS; +} + +bool Filter::writeSectionsAndCreateEvent(vector data) { + // TODO check how many sections has been read + ALOGD("[Filter] section handler"); + std::lock_guard lock(mFilterEventLock); + if (!writeDataToFilterMQ(data)) { + return false; + } + int size = mFilterEvent.events.size(); + mFilterEvent.events.resize(size + 1); + DemuxFilterSectionEvent secEvent; + secEvent = { + // temp dump meta data + .tableId = 0, + .version = 1, + .sectionNum = 1, + .dataLength = static_cast(data.size()), + }; + mFilterEvent.events[size].section(secEvent); + return true; +} + +bool Filter::writeDataToFilterMQ(const std::vector& data) { + std::lock_guard lock(mWriteLock); + if (mFilterMQ->write(data.data(), data.size())) { + return true; + } + return false; +} + +void Filter::attachFilterToRecord(const sp dvr) { + mDvr = dvr; +} + +void Filter::detachFilterFromRecord() { + mDvr = nullptr; +} + +int Filter::createAvIonFd(int size) { + // Create an ion fd and allocate an av fd mapped to a buffer to it. + int ion_fd = ion_open(); + if (ion_fd == -1) { + ALOGE("[Filter] Failed to open ion fd %d", errno); + return -1; + } + int av_fd = -1; + ion_alloc_fd(dup(ion_fd), size, 0 /*align*/, ION_HEAP_SYSTEM_MASK, 0 /*flags*/, &av_fd); + if (av_fd == -1) { + ALOGE("[Filter] Failed to create av fd %d", errno); + return -1; + } + return av_fd; +} + +uint8_t* Filter::getIonBuffer(int fd, int size) { + uint8_t* avBuf = static_cast( + mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 /*offset*/)); + if (avBuf == MAP_FAILED) { + ALOGE("[Filter] fail to allocate buffer %d", errno); + return NULL; + } + return avBuf; +} + +native_handle_t* Filter::createNativeHandle(int fd) { + // Create a native handle to pass the av fd via the callback event. + native_handle_t* nativeHandle = native_handle_create(/*numFd*/ 1, 0); + if (nativeHandle == NULL) { + ALOGE("[Filter] Failed to create native_handle %d", errno); + return NULL; + } + nativeHandle->data[0] = dup(fd); + return nativeHandle; +} +} // namespace implementation +} // namespace V1_0 +} // namespace tuner +} // namespace tv +} // namespace hardware +} // namespace android diff --git a/tv/tuner/1.1/default/Filter.h b/tv/tuner/1.1/default/Filter.h new file mode 100644 index 0000000000..d5801d4f74 --- /dev/null +++ b/tv/tuner/1.1/default/Filter.h @@ -0,0 +1,214 @@ +/* + * 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. + */ + +#ifndef ANDROID_HARDWARE_TV_TUNER_V1_1_FILTER_H_ +#define ANDROID_HARDWARE_TV_TUNER_V1_1_FILTER_H_ + +#include +#include +#include +#include +#include +#include +#include "Demux.h" +#include "Dvr.h" +#include "Frontend.h" + +using namespace std; + +namespace android { +namespace hardware { +namespace tv { +namespace tuner { +namespace V1_0 { +namespace implementation { + +using ::android::hardware::EventFlag; +using ::android::hardware::kSynchronizedReadWrite; +using ::android::hardware::MessageQueue; +using ::android::hardware::MQDescriptorSync; + +using FilterMQ = MessageQueue; + +class Demux; +class Dvr; + +class Filter : public V1_1::IFilter { + public: + Filter(); + + Filter(DemuxFilterType type, uint64_t filterId, uint32_t bufferSize, + const sp& cb, sp demux); + + ~Filter(); + + virtual Return getId64Bit(getId64Bit_cb _hidl_cb) override; + + virtual Return getId(getId_cb _hidl_cb) override; + + virtual Return setDataSource(const sp& filter) override; + + virtual Return getQueueDesc(getQueueDesc_cb _hidl_cb) override; + + virtual Return configure(const DemuxFilterSettings& settings) override; + + virtual Return start() override; + + virtual Return stop() override; + + virtual Return flush() override; + + virtual Return releaseAvHandle(const hidl_handle& avMemory, uint64_t avDataId) override; + + virtual Return close() override; + + /** + * To create a FilterMQ and its Event Flag. + * + * Return false is any of the above processes fails. + */ + bool createFilterMQ(); + uint16_t getTpid(); + void updateFilterOutput(vector data); + void updateRecordOutput(vector data); + void updatePts(uint64_t pts); + Result startFilterHandler(); + Result startRecordFilterHandler(); + void attachFilterToRecord(const sp dvr); + void detachFilterFromRecord(); + void freeAvHandle(); + bool isMediaFilter() { return mIsMediaFilter; }; + bool isPcrFilter() { return mIsPcrFilter; }; + bool isRecordFilter() { return mIsRecordFilter; }; + + private: + // Tuner service + sp mDemux; + // Dvr reference once the filter is attached to any + sp mDvr = nullptr; + /** + * Filter callbacks used on filter events or FMQ status + */ + sp mCallback; + + uint64_t mFilterId; + uint32_t mBufferSize; + DemuxFilterType mType; + bool mIsMediaFilter = false; + bool mIsPcrFilter = false; + bool mIsRecordFilter = false; + DemuxFilterSettings mFilterSettings; + + uint16_t mTpid; + sp mDataSource; + bool mIsDataSourceDemux = true; + vector mFilterOutput; + vector mRecordFilterOutput; + uint64_t mPts = 0; + unique_ptr mFilterMQ; + bool mIsUsingFMQ = false; + EventFlag* mFilterEventFlag; + DemuxFilterEvent mFilterEvent; + + // Thread handlers + pthread_t mFilterThread; + + // FMQ status local records + DemuxFilterStatus mFilterStatus; + /** + * If a specific filter's writing loop is still running + */ + bool mFilterThreadRunning; + bool mKeepFetchingDataFromFrontend; + + /** + * How many times a filter should write + * TODO make this dynamic/random/can take as a parameter + */ + const uint16_t SECTION_WRITE_COUNT = 10; + + bool DEBUG_FILTER = false; + + /** + * Filter handlers to handle the data filtering. + * They are also responsible to write the filtered output into the filter FMQ + * and update the filterEvent bound with the same filterId. + */ + Result startSectionFilterHandler(); + Result startPesFilterHandler(); + Result startTsFilterHandler(); + Result startMediaFilterHandler(); + Result startPcrFilterHandler(); + Result startTemiFilterHandler(); + Result startFilterLoop(); + + void deleteEventFlag(); + bool writeDataToFilterMQ(const std::vector& data); + bool readDataFromMQ(); + bool writeSectionsAndCreateEvent(vector data); + void maySendFilterStatusCallback(); + DemuxFilterStatus checkFilterStatusChange(uint32_t availableToWrite, uint32_t availableToRead, + uint32_t highThreshold, uint32_t lowThreshold); + /** + * A dispatcher to read and dispatch input data to all the started filters. + * Each filter handler handles the data filtering/output writing/filterEvent updating. + */ + void startTsFilter(vector data); + bool startFilterDispatcher(); + static void* __threadLoopFilter(void* user); + void filterThreadLoop(); + + int createAvIonFd(int size); + uint8_t* getIonBuffer(int fd, int size); + native_handle_t* createNativeHandle(int fd); + Result createMediaFilterEventWithIon(vector output); + + /** + * Lock to protect writes to the FMQs + */ + std::mutex mWriteLock; + /** + * Lock to protect writes to the filter event + */ + // TODO make each filter separate event lock + std::mutex mFilterEventLock; + /** + * Lock to protect writes to the input status + */ + std::mutex mFilterStatusLock; + std::mutex mFilterThreadLock; + std::mutex mFilterOutputLock; + std::mutex mRecordFilterOutputLock; + + // temp handle single PES filter + // TODO handle mulptiple Pes filters + int mPesSizeLeft = 0; + vector mPesOutput; + + // A map from data id to ion handle + std::map mDataId2Avfd; + uint64_t mLastUsedDataId = 1; + int mAvBufferCopyCount = 0; +}; + +} // namespace implementation +} // namespace V1_0 +} // namespace tuner +} // namespace tv +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_TV_TUNER_V1_1_FILTER_H_ diff --git a/tv/tuner/1.1/default/Frontend.cpp b/tv/tuner/1.1/default/Frontend.cpp new file mode 100644 index 0000000000..3475c3686b --- /dev/null +++ b/tv/tuner/1.1/default/Frontend.cpp @@ -0,0 +1,284 @@ +/* + * 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. + */ + +#define LOG_TAG "android.hardware.tv.tuner@1.1-Frontend" + +#include "Frontend.h" +#include +#include + +namespace android { +namespace hardware { +namespace tv { +namespace tuner { +namespace V1_0 { +namespace implementation { + +Frontend::Frontend(FrontendType type, FrontendId id, sp tuner) { + mType = type; + mId = id; + mTunerService = tuner; + // Init callback to nullptr + mCallback = nullptr; +} + +Frontend::~Frontend() {} + +Return Frontend::close() { + ALOGV("%s", __FUNCTION__); + // Reset callback + mCallback = nullptr; + mIsLocked = false; + + return Result::SUCCESS; +} + +Return Frontend::setCallback(const sp& callback) { + ALOGV("%s", __FUNCTION__); + if (callback == nullptr) { + ALOGW("[ WARN ] Set Frontend callback with nullptr"); + return Result::INVALID_ARGUMENT; + } + + mCallback = callback; + return Result::SUCCESS; +} + +Return Frontend::tune(const FrontendSettings& /* settings */) { + ALOGV("%s", __FUNCTION__); + if (mCallback == nullptr) { + ALOGW("[ WARN ] Frontend callback is not set when tune"); + return Result::INVALID_STATE; + } + + mTunerService->frontendStartTune(mId); + mCallback->onEvent(FrontendEventType::LOCKED); + mIsLocked = true; + return Result::SUCCESS; +} + +Return Frontend::stopTune() { + ALOGV("%s", __FUNCTION__); + + mTunerService->frontendStopTune(mId); + mIsLocked = false; + + return Result::SUCCESS; +} + +Return Frontend::scan(const FrontendSettings& settings, FrontendScanType type) { + ALOGV("%s", __FUNCTION__); + + if (mType == FrontendType::ATSC) { + FrontendScanMessage msg; + msg.isLocked(true); + mCallback->onScanMessage(FrontendScanMessageType::LOCKED, msg); + mIsLocked = true; + return Result::SUCCESS; + } + if (mType != FrontendType::DVBT) { + return Result::UNAVAILABLE; + } + + FrontendScanMessage msg; + + if (mIsLocked) { + msg.isEnd(true); + mCallback->onScanMessage(FrontendScanMessageType::END, msg); + return Result::SUCCESS; + } + + uint32_t frequency = settings.dvbt().frequency; + if (type == FrontendScanType::SCAN_BLIND) { + frequency += 100; + } + msg.frequencies({frequency}); + mCallback->onScanMessage(FrontendScanMessageType::FREQUENCY, msg); + msg.isLocked(true); + mCallback->onScanMessage(FrontendScanMessageType::LOCKED, msg); + mIsLocked = true; + + return Result::SUCCESS; +} + +Return Frontend::stopScan() { + ALOGV("%s", __FUNCTION__); + + mIsLocked = false; + return Result::SUCCESS; +} + +Return Frontend::getStatus(const hidl_vec& statusTypes, + getStatus_cb _hidl_cb) { + ALOGV("%s", __FUNCTION__); + + vector statuses; + for (int i = 0; i < statusTypes.size(); i++) { + FrontendStatusType type = statusTypes[i]; + FrontendStatus status; + // assign randomly selected values for testing. + switch (type) { + case FrontendStatusType::DEMOD_LOCK: { + status.isDemodLocked(true); + break; + } + case FrontendStatusType::SNR: { + status.snr(221); + break; + } + case FrontendStatusType::BER: { + status.ber(1); + break; + } + case FrontendStatusType::PER: { + status.per(2); + break; + } + case FrontendStatusType::PRE_BER: { + status.preBer(3); + break; + } + case FrontendStatusType::SIGNAL_QUALITY: { + status.signalQuality(4); + break; + } + case FrontendStatusType::SIGNAL_STRENGTH: { + status.signalStrength(5); + break; + } + case FrontendStatusType::SYMBOL_RATE: { + status.symbolRate(6); + break; + } + case FrontendStatusType::FEC: { + status.innerFec(FrontendInnerFec::FEC_2_9); // value = 1 << 7 + break; + } + case FrontendStatusType::MODULATION: { + FrontendModulationStatus modulationStatus; + modulationStatus.isdbt(FrontendIsdbtModulation::MOD_16QAM); // value = 1 << 3 + status.modulation(modulationStatus); + break; + } + case FrontendStatusType::SPECTRAL: { + status.inversion(FrontendDvbcSpectralInversion::NORMAL); + break; + } + case FrontendStatusType::LNB_VOLTAGE: { + status.lnbVoltage(LnbVoltage::VOLTAGE_5V); + break; + } + case FrontendStatusType::PLP_ID: { + status.plpId(101); // type uint8_t + break; + } + case FrontendStatusType::EWBS: { + status.isEWBS(false); + break; + } + case FrontendStatusType::AGC: { + status.agc(7); + break; + } + case FrontendStatusType::LNA: { + status.isLnaOn(false); + break; + } + case FrontendStatusType::LAYER_ERROR: { + vector v = {false, true, true}; + status.isLayerError(v); + break; + } + case FrontendStatusType::MER: { + status.mer(8); + break; + } + case FrontendStatusType::FREQ_OFFSET: { + status.freqOffset(9); + break; + } + case FrontendStatusType::HIERARCHY: { + status.hierarchy(FrontendDvbtHierarchy::HIERARCHY_1_NATIVE); + break; + } + case FrontendStatusType::RF_LOCK: { + status.isRfLocked(false); + break; + } + case FrontendStatusType::ATSC3_PLP_INFO: { + vector v; + FrontendStatusAtsc3PlpInfo info1{ + .plpId = 3, + .isLocked = false, + .uec = 313, + }; + FrontendStatusAtsc3PlpInfo info2{ + .plpId = 5, + .isLocked = true, + .uec = 515, + }; + v.push_back(info1); + v.push_back(info2); + status.plpInfo(v); + break; + } + default: { + continue; + } + } + statuses.push_back(status); + } + _hidl_cb(Result::SUCCESS, statuses); + + return Void(); +} + +Return Frontend::setLna(bool /* bEnable */) { + ALOGV("%s", __FUNCTION__); + + return Result::SUCCESS; +} + +Return Frontend::setLnb(uint32_t /* lnb */) { + ALOGV("%s", __FUNCTION__); + if (!supportsSatellite()) { + return Result::INVALID_STATE; + } + return Result::SUCCESS; +} + +FrontendType Frontend::getFrontendType() { + return mType; +} + +FrontendId Frontend::getFrontendId() { + return mId; +} + +bool Frontend::supportsSatellite() { + return mType == FrontendType::DVBS || mType == FrontendType::ISDBS || + mType == FrontendType::ISDBS3; +} + +bool Frontend::isLocked() { + return mIsLocked; +} +} // namespace implementation +} // namespace V1_0 +} // namespace tuner +} // namespace tv +} // namespace hardware +} // namespace android diff --git a/tv/tuner/1.1/default/Frontend.h b/tv/tuner/1.1/default/Frontend.h new file mode 100644 index 0000000000..89b4a6b5f3 --- /dev/null +++ b/tv/tuner/1.1/default/Frontend.h @@ -0,0 +1,85 @@ +/* + * 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. + */ + +#ifndef ANDROID_HARDWARE_TV_TUNER_V1_1_FRONTEND_H_ +#define ANDROID_HARDWARE_TV_TUNER_V1_1_FRONTEND_H_ + +#include +#include +#include "Tuner.h" + +using namespace std; + +namespace android { +namespace hardware { +namespace tv { +namespace tuner { +namespace V1_0 { +namespace implementation { + +class Tuner; + +class Frontend : public IFrontend { + public: + Frontend(FrontendType type, FrontendId id, sp tuner); + + virtual Return close() override; + + virtual Return setCallback(const sp& callback) override; + + virtual Return tune(const FrontendSettings& settings) override; + + virtual Return stopTune() override; + + virtual Return scan(const FrontendSettings& settings, FrontendScanType type) override; + + virtual Return stopScan() override; + + virtual Return getStatus(const hidl_vec& statusTypes, + getStatus_cb _hidl_cb) override; + + virtual Return setLna(bool bEnable) override; + + virtual Return setLnb(uint32_t lnb) override; + + FrontendType getFrontendType(); + + FrontendId getFrontendId(); + + string getSourceFile(); + + bool isLocked(); + + private: + virtual ~Frontend(); + bool supportsSatellite(); + sp mCallback; + sp mTunerService; + FrontendType mType = FrontendType::UNDEFINED; + FrontendId mId = 0; + bool mIsLocked = false; + + std::ifstream mFrontendData; +}; + +} // namespace implementation +} // namespace V1_0 +} // namespace tuner +} // namespace tv +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_TV_TUNER_V1_1_FRONTEND_H_ diff --git a/tv/tuner/1.1/default/Lnb.cpp b/tv/tuner/1.1/default/Lnb.cpp new file mode 100644 index 0000000000..044727ff54 --- /dev/null +++ b/tv/tuner/1.1/default/Lnb.cpp @@ -0,0 +1,81 @@ +/* + * 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. + */ + +#define LOG_TAG "android.hardware.tv.tuner@1.1-Lnb" + +#include "Lnb.h" +#include + +namespace android { +namespace hardware { +namespace tv { +namespace tuner { +namespace V1_0 { +namespace implementation { + +Lnb::Lnb() {} +Lnb::Lnb(int id) { + mId = id; +} + +Lnb::~Lnb() {} + +Return Lnb::setCallback(const sp& /* callback */) { + ALOGV("%s", __FUNCTION__); + + return Result::SUCCESS; +} + +Return Lnb::setVoltage(LnbVoltage /* voltage */) { + ALOGV("%s", __FUNCTION__); + + return Result::SUCCESS; +} + +Return Lnb::setTone(LnbTone /* tone */) { + ALOGV("%s", __FUNCTION__); + + return Result::SUCCESS; +} + +Return Lnb::setSatellitePosition(LnbPosition /* position */) { + ALOGV("%s", __FUNCTION__); + + return Result::SUCCESS; +} + +Return Lnb::sendDiseqcMessage(const hidl_vec& /* diseqcMessage */) { + ALOGV("%s", __FUNCTION__); + + return Result::SUCCESS; +} + +Return Lnb::close() { + ALOGV("%s", __FUNCTION__); + + return Result::SUCCESS; +} + +int Lnb::getId() { + return mId; +} + +} // namespace implementation +} // namespace V1_0 +} // namespace tuner +} // namespace tv +} // namespace hardware +} // namespace android diff --git a/tv/tuner/1.1/default/Lnb.h b/tv/tuner/1.1/default/Lnb.h new file mode 100644 index 0000000000..70a8e41b8b --- /dev/null +++ b/tv/tuner/1.1/default/Lnb.h @@ -0,0 +1,63 @@ +/* + * 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. + */ + +#ifndef ANDROID_HARDWARE_TV_TUNER_V1_1_LNB_H_ +#define ANDROID_HARDWARE_TV_TUNER_V1_1_LNB_H_ + +#include +#include + +using namespace std; + +namespace android { +namespace hardware { +namespace tv { +namespace tuner { +namespace V1_0 { +namespace implementation { + +class Lnb : public ILnb { + public: + Lnb(); + Lnb(int id); + + virtual Return setCallback(const sp& callback) override; + + virtual Return setVoltage(LnbVoltage voltage) override; + + virtual Return setTone(LnbTone tone) override; + + virtual Return setSatellitePosition(LnbPosition position) override; + + virtual Return sendDiseqcMessage(const hidl_vec& diseqcMessage) override; + + virtual Return close() override; + + int getId(); + + private: + int mId; + virtual ~Lnb(); +}; + +} // namespace implementation +} // namespace V1_0 +} // namespace tuner +} // namespace tv +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_TV_TUNER_V1_1_LNB_H_ diff --git a/tv/tuner/1.1/default/OWNERS b/tv/tuner/1.1/default/OWNERS new file mode 100644 index 0000000000..1b3d095f9c --- /dev/null +++ b/tv/tuner/1.1/default/OWNERS @@ -0,0 +1,4 @@ +nchalko@google.com +amyjojo@google.com +shubang@google.com +quxiangfang@google.com diff --git a/tv/tuner/1.1/default/TimeFilter.cpp b/tv/tuner/1.1/default/TimeFilter.cpp new file mode 100644 index 0000000000..bb243a66bc --- /dev/null +++ b/tv/tuner/1.1/default/TimeFilter.cpp @@ -0,0 +1,87 @@ +/* + * 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. + */ + +#define LOG_TAG "android.hardware.tv.tuner@1.1-TimeFilter" + +#include "TimeFilter.h" +#include + +namespace android { +namespace hardware { +namespace tv { +namespace tuner { +namespace V1_0 { +namespace implementation { + +TimeFilter::TimeFilter() {} + +TimeFilter::TimeFilter(sp demux) { + mDemux = demux; +} + +TimeFilter::~TimeFilter() {} + +Return TimeFilter::setTimeStamp(uint64_t timeStamp) { + ALOGV("%s", __FUNCTION__); + if (timeStamp == INVALID_TIME_STAMP) { + return Result::INVALID_ARGUMENT; + } + mTimeStamp = timeStamp; + mBeginTime = time(NULL); + + return Result::SUCCESS; +} + +Return TimeFilter::clearTimeStamp() { + ALOGV("%s", __FUNCTION__); + mTimeStamp = INVALID_TIME_STAMP; + + return Result::SUCCESS; +} + +Return TimeFilter::getTimeStamp(getTimeStamp_cb _hidl_cb) { + ALOGV("%s", __FUNCTION__); + if (mTimeStamp == INVALID_TIME_STAMP) { + _hidl_cb(Result::INVALID_STATE, mTimeStamp); + } + + uint64_t currentTimeStamp = mTimeStamp + difftime(time(NULL), mBeginTime) * 900000; + _hidl_cb(Result::SUCCESS, currentTimeStamp); + return Void(); +} + +Return TimeFilter::getSourceTime(getSourceTime_cb _hidl_cb) { + ALOGV("%s", __FUNCTION__); + + uint64_t time = 0; + + _hidl_cb(Result::SUCCESS, time); + return Void(); +} + +Return TimeFilter::close() { + ALOGV("%s", __FUNCTION__); + mTimeStamp = INVALID_TIME_STAMP; + + return Result::SUCCESS; +} + +} // namespace implementation +} // namespace V1_0 +} // namespace tuner +} // namespace tv +} // namespace hardware +} // namespace android \ No newline at end of file diff --git a/tv/tuner/1.1/default/TimeFilter.h b/tv/tuner/1.1/default/TimeFilter.h new file mode 100644 index 0000000000..d53ad2c900 --- /dev/null +++ b/tv/tuner/1.1/default/TimeFilter.h @@ -0,0 +1,70 @@ +/* + * 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. + */ + +#ifndef ANDROID_HARDWARE_TV_TUNER_V1_1_TIMEFILTER_H_ +#define ANDROID_HARDWARE_TV_TUNER_V1_1_TIMEFILTER_H_ + +#include +#include "Demux.h" +#include "time.h" + +using namespace std; + +namespace android { +namespace hardware { +namespace tv { +namespace tuner { +namespace V1_0 { +namespace implementation { + +using FilterMQ = MessageQueue; + +#define INVALID_TIME_STAMP -1 + +class Demux; + +class TimeFilter : public ITimeFilter { + public: + TimeFilter(); + + TimeFilter(sp demux); + + ~TimeFilter(); + + virtual Return setTimeStamp(uint64_t timeStamp) override; + + virtual Return clearTimeStamp() override; + + virtual Return getTimeStamp(getTimeStamp_cb _hidl_cb) override; + + virtual Return getSourceTime(getSourceTime_cb _hidl_cb) override; + + virtual Return close() override; + + private: + sp mDemux; + uint64_t mTimeStamp = INVALID_TIME_STAMP; + time_t mBeginTime; +}; + +} // namespace implementation +} // namespace V1_0 +} // namespace tuner +} // namespace tv +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_TV_TUNER_V1_1_TIMEFILTER_H_ \ No newline at end of file diff --git a/tv/tuner/1.1/default/Tuner.cpp b/tv/tuner/1.1/default/Tuner.cpp new file mode 100644 index 0000000000..c220ea2682 --- /dev/null +++ b/tv/tuner/1.1/default/Tuner.cpp @@ -0,0 +1,259 @@ +/* + * 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. + */ + +#define LOG_TAG "android.hardware.tv.tuner@1.1-Tuner" + +#include "Tuner.h" +#include +#include "Demux.h" +#include "Descrambler.h" +#include "Frontend.h" +#include "Lnb.h" + +namespace android { +namespace hardware { +namespace tv { +namespace tuner { +namespace V1_0 { +namespace implementation { + +Tuner::Tuner() { + // Static Frontends array to maintain local frontends information + // Array index matches their FrontendId in the default impl + mFrontendSize = 8; + mFrontends.resize(mFrontendSize); + mFrontends[0] = new Frontend(FrontendType::DVBT, 0, this); + mFrontends[1] = new Frontend(FrontendType::ATSC, 1, this); + mFrontends[2] = new Frontend(FrontendType::DVBC, 2, this); + mFrontends[3] = new Frontend(FrontendType::DVBS, 3, this); + mFrontends[4] = new Frontend(FrontendType::DVBT, 4, this); + mFrontends[5] = new Frontend(FrontendType::ISDBT, 5, this); + mFrontends[6] = new Frontend(FrontendType::ANALOG, 6, this); + mFrontends[7] = new Frontend(FrontendType::ATSC, 7, this); + + FrontendInfo::FrontendCapabilities caps; + mFrontendCaps.resize(mFrontendSize); + caps = FrontendInfo::FrontendCapabilities(); + caps.dvbtCaps(FrontendDvbtCapabilities()); + mFrontendCaps[0] = caps; + + caps = FrontendInfo::FrontendCapabilities(); + caps.atscCaps(FrontendAtscCapabilities()); + mFrontendCaps[1] = caps; + + caps = FrontendInfo::FrontendCapabilities(); + caps.dvbcCaps(FrontendDvbcCapabilities()); + mFrontendCaps[2] = caps; + + caps = FrontendInfo::FrontendCapabilities(); + caps.dvbsCaps(FrontendDvbsCapabilities()); + mFrontendCaps[3] = caps; + + caps = FrontendInfo::FrontendCapabilities(); + caps.dvbtCaps(FrontendDvbtCapabilities()); + mFrontendCaps[4] = caps; + + caps = FrontendInfo::FrontendCapabilities(); + FrontendIsdbtCapabilities isdbtCaps{ + .modeCap = FrontendIsdbtMode::MODE_1 | FrontendIsdbtMode::MODE_2, + .bandwidthCap = (unsigned int)FrontendIsdbtBandwidth::BANDWIDTH_6MHZ, + .modulationCap = (unsigned int)FrontendIsdbtModulation::MOD_16QAM, + // ISDBT shares coderate and guard interval with DVBT + .coderateCap = FrontendDvbtCoderate::CODERATE_4_5 | FrontendDvbtCoderate::CODERATE_6_7, + .guardIntervalCap = (unsigned int)FrontendDvbtGuardInterval::INTERVAL_1_128, + }; + caps.isdbtCaps(isdbtCaps); + mFrontendCaps[5] = caps; + + caps = FrontendInfo::FrontendCapabilities(); + caps.analogCaps(FrontendAnalogCapabilities()); + mFrontendCaps[6] = caps; + + caps = FrontendInfo::FrontendCapabilities(); + caps.atscCaps(FrontendAtscCapabilities()); + mFrontendCaps[7] = caps; + + mLnbs.resize(2); + mLnbs[0] = new Lnb(0); + mLnbs[1] = new Lnb(1); +} + +Tuner::~Tuner() {} + +Return Tuner::getFrontendIds(getFrontendIds_cb _hidl_cb) { + ALOGV("%s", __FUNCTION__); + + vector frontendIds; + frontendIds.resize(mFrontendSize); + for (int i = 0; i < mFrontendSize; i++) { + frontendIds[i] = mFrontends[i]->getFrontendId(); + } + + _hidl_cb(Result::SUCCESS, frontendIds); + return Void(); +} + +Return Tuner::openFrontendById(uint32_t frontendId, openFrontendById_cb _hidl_cb) { + ALOGV("%s", __FUNCTION__); + + if (frontendId >= mFrontendSize || frontendId < 0) { + ALOGW("[ WARN ] Frontend with id %d isn't available", frontendId); + _hidl_cb(Result::UNAVAILABLE, nullptr); + return Void(); + } + + _hidl_cb(Result::SUCCESS, mFrontends[frontendId]); + return Void(); +} + +Return Tuner::openDemux(openDemux_cb _hidl_cb) { + ALOGV("%s", __FUNCTION__); + + uint32_t demuxId = mLastUsedId + 1; + mLastUsedId += 1; + sp demux = new Demux(demuxId, this); + mDemuxes[demuxId] = demux; + + _hidl_cb(Result::SUCCESS, demuxId, demux); + return Void(); +} + +Return Tuner::getDemuxCaps(getDemuxCaps_cb _hidl_cb) { + ALOGV("%s", __FUNCTION__); + + DemuxCapabilities caps; + + // IP filter can be an MMTP filter's data source. + caps.linkCaps = {0x00, 0x00, 0x02, 0x00, 0x00}; + _hidl_cb(Result::SUCCESS, caps); + return Void(); +} + +Return Tuner::openDescrambler(openDescrambler_cb _hidl_cb) { + ALOGV("%s", __FUNCTION__); + + sp descrambler = new Descrambler(); + + _hidl_cb(Result::SUCCESS, descrambler); + return Void(); +} + +Return Tuner::getFrontendInfo(FrontendId frontendId, getFrontendInfo_cb _hidl_cb) { + ALOGV("%s", __FUNCTION__); + + FrontendInfo info; + if (frontendId >= mFrontendSize) { + _hidl_cb(Result::INVALID_ARGUMENT, info); + return Void(); + } + + vector statusCaps = { + FrontendStatusType::DEMOD_LOCK, + FrontendStatusType::SNR, + FrontendStatusType::FEC, + FrontendStatusType::MODULATION, + FrontendStatusType::PLP_ID, + FrontendStatusType::LAYER_ERROR, + FrontendStatusType::ATSC3_PLP_INFO, + }; + // assign randomly selected values for testing. + info = { + .type = mFrontends[frontendId]->getFrontendType(), + .minFrequency = 139, + .maxFrequency = 1139, + .minSymbolRate = 45, + .maxSymbolRate = 1145, + .acquireRange = 30, + .exclusiveGroupId = 57, + .statusCaps = statusCaps, + .frontendCaps = mFrontendCaps[frontendId], + }; + + _hidl_cb(Result::SUCCESS, info); + return Void(); +} + +Return Tuner::getLnbIds(getLnbIds_cb _hidl_cb) { + ALOGV("%s", __FUNCTION__); + + vector lnbIds; + lnbIds.resize(mLnbs.size()); + for (int i = 0; i < lnbIds.size(); i++) { + lnbIds[i] = mLnbs[i]->getId(); + } + + _hidl_cb(Result::SUCCESS, lnbIds); + return Void(); +} + +Return Tuner::openLnbById(V1_0::LnbId lnbId, openLnbById_cb _hidl_cb) { + ALOGV("%s", __FUNCTION__); + + if (lnbId >= mLnbs.size()) { + _hidl_cb(Result::INVALID_ARGUMENT, nullptr); + return Void(); + } + + _hidl_cb(Result::SUCCESS, mLnbs[lnbId]); + return Void(); +} + +sp Tuner::getFrontendById(uint32_t frontendId) { + ALOGV("%s", __FUNCTION__); + + return mFrontends[frontendId]; +} + +Return Tuner::openLnbByName(const hidl_string& /*lnbName*/, openLnbByName_cb _hidl_cb) { + ALOGV("%s", __FUNCTION__); + + sp lnb = new Lnb(); + + _hidl_cb(Result::SUCCESS, 1234, lnb); + return Void(); +} + +void Tuner::setFrontendAsDemuxSource(uint32_t frontendId, uint32_t demuxId) { + mFrontendToDemux[frontendId] = demuxId; + if (mFrontends[frontendId] != nullptr && mFrontends[frontendId]->isLocked()) { + mDemuxes[demuxId]->startFrontendInputLoop(); + } +} + +void Tuner::frontendStopTune(uint32_t frontendId) { + map::iterator it = mFrontendToDemux.find(frontendId); + uint32_t demuxId; + if (it != mFrontendToDemux.end()) { + demuxId = it->second; + mDemuxes[demuxId]->stopFrontendInput(); + } +} + +void Tuner::frontendStartTune(uint32_t frontendId) { + map::iterator it = mFrontendToDemux.find(frontendId); + uint32_t demuxId; + if (it != mFrontendToDemux.end()) { + demuxId = it->second; + mDemuxes[demuxId]->startFrontendInputLoop(); + } +} + +} // namespace implementation +} // namespace V1_0 +} // namespace tuner +} // namespace tv +} // namespace hardware +} // namespace android diff --git a/tv/tuner/1.1/default/Tuner.h b/tv/tuner/1.1/default/Tuner.h new file mode 100644 index 0000000000..9463278a1e --- /dev/null +++ b/tv/tuner/1.1/default/Tuner.h @@ -0,0 +1,94 @@ +/* + * 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. + */ + +#ifndef ANDROID_HARDWARE_TV_TUNER_V1_1_TUNER_H_ +#define ANDROID_HARDWARE_TV_TUNER_V1_1_TUNER_H_ + +#include +#include +#include "Demux.h" +#include "Frontend.h" +#include "Lnb.h" + +using namespace std; + +namespace android { +namespace hardware { +namespace tv { +namespace tuner { +namespace V1_0 { +namespace implementation { + +using ::android::hardware::tv::tuner::V1_1::ITuner; + +class Frontend; +class Demux; +class Lnb; + +class Tuner : public ITuner { + public: + Tuner(); + + virtual Return getFrontendIds(getFrontendIds_cb _hidl_cb) override; + + virtual Return openFrontendById(uint32_t frontendId, + openFrontendById_cb _hidl_cb) override; + + virtual Return openDemux(openDemux_cb _hidl_cb) override; + + virtual Return getDemuxCaps(getDemuxCaps_cb _hidl_cb) override; + + virtual Return openDescrambler(openDescrambler_cb _hidl_cb) override; + + virtual Return getFrontendInfo(uint32_t frontendId, getFrontendInfo_cb _hidl_cb) override; + + virtual Return getLnbIds(getLnbIds_cb _hidl_cb) override; + + virtual Return openLnbById(uint32_t lnbId, openLnbById_cb _hidl_cb) override; + + virtual Return openLnbByName(const hidl_string& lnbName, + openLnbByName_cb _hidl_cb) override; + + sp getFrontendById(uint32_t frontendId); + + void setFrontendAsDemuxSource(uint32_t frontendId, uint32_t demuxId); + + void frontendStartTune(uint32_t frontendId); + void frontendStopTune(uint32_t frontendId); + + private: + virtual ~Tuner(); + // Static mFrontends array to maintain local frontends information + vector> mFrontends; + vector mFrontendCaps; + std::map mFrontendToDemux; + std::map> mDemuxes; + // To maintain how many Frontends we have + int mFrontendSize; + // The last used demux id. Initial value is -1. + // First used id will be 0. + uint32_t mLastUsedId = -1; + vector> mLnbs; +}; + +} // namespace implementation +} // namespace V1_0 +} // namespace tuner +} // namespace tv +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_TV_TUNER_V1_1_TUNER_H_ diff --git a/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service-lazy.rc b/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service-lazy.rc new file mode 100644 index 0000000000..9e228f7d58 --- /dev/null +++ b/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service-lazy.rc @@ -0,0 +1,9 @@ +service vendor.tuner-hal-1-1 /vendor/bin/hw/android.hardware.tv.tuner@1.1-service-lazy + interface android.hardware.tv.tuner@1.1::ITuner default + oneshot + disabled + class hal + user media + group mediadrm drmrpc + ioprio rt 4 + writepid /dev/cpuset/foreground/tasks \ No newline at end of file diff --git a/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service-lazy.xml b/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service-lazy.xml new file mode 100644 index 0000000000..86b044525f --- /dev/null +++ b/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service-lazy.xml @@ -0,0 +1,11 @@ + + + android.hardware.tv.tuner + hwbinder + 1.1 + + ITuner + default + + + \ No newline at end of file diff --git a/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service.rc b/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service.rc new file mode 100644 index 0000000000..3718a9388f --- /dev/null +++ b/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service.rc @@ -0,0 +1,6 @@ +service vendor.tuner-hal-1-1 /vendor/bin/hw/android.hardware.tv.tuner@1.1-service + class hal + user media + group mediadrm drmrpc + ioprio rt 4 + writepid /dev/cpuset/foreground/tasks \ No newline at end of file diff --git a/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service.xml b/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service.xml new file mode 100644 index 0000000000..86b044525f --- /dev/null +++ b/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service.xml @@ -0,0 +1,11 @@ + + + android.hardware.tv.tuner + hwbinder + 1.1 + + ITuner + default + + + \ No newline at end of file diff --git a/tv/tuner/1.1/default/service.cpp b/tv/tuner/1.1/default/service.cpp new file mode 100644 index 0000000000..232030850d --- /dev/null +++ b/tv/tuner/1.1/default/service.cpp @@ -0,0 +1,57 @@ +/* + * 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. + */ + +//#define LOG_NDEBUG 0 +#ifdef LAZY_SERVICE +#define LOG_TAG "android.hardware.tv.tuner@1.1-service-lazy" +#else +#define LOG_TAG "android.hardware.tv.tuner@1.1-service" +#endif + +#include +#include + +#include "Tuner.h" + +using android::hardware::configureRpcThreadpool; +using android::hardware::joinRpcThreadpool; +using android::hardware::LazyServiceRegistrar; +using android::hardware::tv::tuner::V1_0::implementation::Tuner; +using android::hardware::tv::tuner::V1_1::ITuner; + +#ifdef LAZY_SERVICE +const bool kLazyService = true; +#else +const bool kLazyService = false; +#endif + +int main() { + configureRpcThreadpool(8, true /* callerWillJoin */); + + // Setup hwbinder service + android::sp service = new Tuner(); + android::status_t status; + if (kLazyService) { + auto serviceRegistrar = LazyServiceRegistrar::getInstance(); + status = serviceRegistrar.registerService(service); + } else { + status = service->registerAsService(); + } + LOG_ALWAYS_FATAL_IF(status != android::OK, "Error while registering tuner service: %d", status); + + joinRpcThreadpool(); + return 0; +} -- GitLab From 45cc57ac67adc06d86ac6ae1b2c56a6ff27de007 Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Thu, 9 Jul 2020 22:56:25 -0700 Subject: [PATCH 075/790] Add VTS of Tuner HAL 1.1 For the APIs that have both 1.0 and 1.1 versions, the VTS 1.1 only tests the 1.1 version of them. For example for getId in IFilter 1.0 and getId_64bit in IFilter 1.1, the 1.1 VTS only tests the getId_64bit. Test: atest VtsHalTvTunerV1_1TargetTest Bug: b/159058358 Change-Id: Ibef0ef40c3d1fbb9ff034bfcabeb44663a444d23 --- tv/tuner/1.1/TEST_MAPPING | 7 + tv/tuner/1.1/vts/OWNERS | 4 + tv/tuner/1.1/vts/functional/Android.bp | 48 +++++ tv/tuner/1.1/vts/functional/DemuxTests.cpp | 41 ++++ tv/tuner/1.1/vts/functional/DemuxTests.h | 56 ++++++ tv/tuner/1.1/vts/functional/FilterTests.cpp | 111 +++++++++++ tv/tuner/1.1/vts/functional/FilterTests.h | 168 +++++++++++++++++ tv/tuner/1.1/vts/functional/FrontendTests.cpp | 83 ++++++++ tv/tuner/1.1/vts/functional/FrontendTests.h | 96 ++++++++++ .../VtsHalTvTunerV1_1TargetTest.cpp | 58 ++++++ .../functional/VtsHalTvTunerV1_1TargetTest.h | 52 +++++ .../VtsHalTvTunerV1_1TestConfigurations.h | 178 ++++++++++++++++++ 12 files changed, 902 insertions(+) create mode 100644 tv/tuner/1.1/TEST_MAPPING create mode 100644 tv/tuner/1.1/vts/OWNERS create mode 100644 tv/tuner/1.1/vts/functional/Android.bp create mode 100644 tv/tuner/1.1/vts/functional/DemuxTests.cpp create mode 100644 tv/tuner/1.1/vts/functional/DemuxTests.h create mode 100644 tv/tuner/1.1/vts/functional/FilterTests.cpp create mode 100644 tv/tuner/1.1/vts/functional/FilterTests.h create mode 100644 tv/tuner/1.1/vts/functional/FrontendTests.cpp create mode 100644 tv/tuner/1.1/vts/functional/FrontendTests.h create mode 100644 tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp create mode 100644 tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h create mode 100644 tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h diff --git a/tv/tuner/1.1/TEST_MAPPING b/tv/tuner/1.1/TEST_MAPPING new file mode 100644 index 0000000000..7c91b8fe6c --- /dev/null +++ b/tv/tuner/1.1/TEST_MAPPING @@ -0,0 +1,7 @@ +{ + "presubmit": [ + { + "name": "VtsHalTvTunerV1_1TargetTest" + } + ] +} \ No newline at end of file diff --git a/tv/tuner/1.1/vts/OWNERS b/tv/tuner/1.1/vts/OWNERS new file mode 100644 index 0000000000..1b3d095f9c --- /dev/null +++ b/tv/tuner/1.1/vts/OWNERS @@ -0,0 +1,4 @@ +nchalko@google.com +amyjojo@google.com +shubang@google.com +quxiangfang@google.com diff --git a/tv/tuner/1.1/vts/functional/Android.bp b/tv/tuner/1.1/vts/functional/Android.bp new file mode 100644 index 0000000000..7ab0f87119 --- /dev/null +++ b/tv/tuner/1.1/vts/functional/Android.bp @@ -0,0 +1,48 @@ +// +// 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. +// + +cc_test { + name: "VtsHalTvTunerV1_1TargetTest", + defaults: ["VtsHalTargetTestDefaults"], + srcs: [ + "VtsHalTvTunerV1_1TargetTest.cpp", + "FrontendTests.cpp", + "DemuxTests.cpp", + "FilterTests.cpp", + ], + static_libs: [ + "android.hardware.cas@1.0", + "android.hardware.cas@1.1", + "android.hardware.cas@1.2", + "android.hardware.tv.tuner@1.0", + "android.hardware.tv.tuner@1.1", + "android.hidl.allocator@1.0", + "android.hidl.memory@1.0", + "libhidlallocatorutils", + "libhidlmemory", + "libcutils", + "libfmq", + ], + shared_libs: [ + "libbinder", + ], + test_suites: [ + "general-tests", + "vts", + ], + + require_root: true, +} diff --git a/tv/tuner/1.1/vts/functional/DemuxTests.cpp b/tv/tuner/1.1/vts/functional/DemuxTests.cpp new file mode 100644 index 0000000000..b1d8a0a0b2 --- /dev/null +++ b/tv/tuner/1.1/vts/functional/DemuxTests.cpp @@ -0,0 +1,41 @@ +/* + * 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 "DemuxTests.h" + +AssertionResult DemuxTests::openDemux(sp& demux, uint32_t& demuxId) { + Result status; + mService->openDemux([&](Result result, uint32_t id, const sp& demuxSp) { + mDemux = demuxSp; + demux = demuxSp; + demuxId = id; + status = result; + }); + return AssertionResult(status == Result::SUCCESS); +} + +AssertionResult DemuxTests::setDemuxFrontendDataSource(uint32_t frontendId) { + EXPECT_TRUE(mDemux) << "Test with openDemux first."; + auto status = mDemux->setFrontendDataSource(frontendId); + return AssertionResult(status.isOk()); +} + +AssertionResult DemuxTests::closeDemux() { + EXPECT_TRUE(mDemux) << "Test with openDemux first."; + auto status = mDemux->close(); + mDemux = nullptr; + return AssertionResult(status.isOk()); +} \ No newline at end of file diff --git a/tv/tuner/1.1/vts/functional/DemuxTests.h b/tv/tuner/1.1/vts/functional/DemuxTests.h new file mode 100644 index 0000000000..c28d6ca524 --- /dev/null +++ b/tv/tuner/1.1/vts/functional/DemuxTests.h @@ -0,0 +1,56 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using android::sp; +using android::hardware::Return; +using android::hardware::Void; +using android::hardware::tv::tuner::V1_0::IDemux; +using android::hardware::tv::tuner::V1_0::IFilter; +using android::hardware::tv::tuner::V1_0::Result; +using android::hardware::tv::tuner::V1_1::ITuner; + +using ::testing::AssertionResult; + +class DemuxTests { + public: + void setService(sp tuner) { mService = tuner; } + + AssertionResult openDemux(sp& demux, uint32_t& demuxId); + AssertionResult setDemuxFrontendDataSource(uint32_t frontendId); + AssertionResult closeDemux(); + + protected: + static AssertionResult failure() { return ::testing::AssertionFailure(); } + + static AssertionResult success() { return ::testing::AssertionSuccess(); } + + sp mService; + sp mDemux; +}; diff --git a/tv/tuner/1.1/vts/functional/FilterTests.cpp b/tv/tuner/1.1/vts/functional/FilterTests.cpp new file mode 100644 index 0000000000..fb0c1a5cc8 --- /dev/null +++ b/tv/tuner/1.1/vts/functional/FilterTests.cpp @@ -0,0 +1,111 @@ +/* + * 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 "FilterTests.h" + +AssertionResult FilterTests::openFilterInDemux(DemuxFilterType type, uint32_t bufferSize) { + Result status; + EXPECT_TRUE(mDemux) << "Test with openDemux first."; + + // Create demux callback + mFilterCallback = new FilterCallback(); + + // Add filter to the local demux + mDemux->openFilter(type, bufferSize, mFilterCallback, + [&](Result result, const sp& filter) { + mFilter = filter; + status = result; + }); + + return AssertionResult(status == Result::SUCCESS); +} + +AssertionResult FilterTests::getNewlyOpenedFilterId_64bit(uint64_t& filterId) { + Result status; + EXPECT_TRUE(mDemux) << "Test with openDemux first."; + EXPECT_TRUE(mFilter) << "Test with openFilterInDemux first."; + EXPECT_TRUE(mFilterCallback) << "Test with openFilterInDemux first."; + + sp filter_v1_1 = + android::hardware::tv::tuner::V1_1::IFilter::castFrom(mFilter); + if (filter_v1_1 != NULL) { + filter_v1_1->getId64Bit([&](Result result, uint64_t filterId) { + mFilterId = filterId; + status = result; + }); + } else { + ALOGW("[vts] Can't cast IFilter into v1_1."); + return failure(); + } + + if (status == Result::SUCCESS) { + mUsedFilterIds.insert(mUsedFilterIds.end(), mFilterId); + mFilters[mFilterId] = mFilter; + mFilterCallbacks[mFilterId] = mFilterCallback; + filterId = mFilterId; + } + + return AssertionResult(status == Result::SUCCESS); +} + +AssertionResult FilterTests::configFilter(DemuxFilterSettings setting, uint64_t filterId) { + Result status; + EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first."; + status = mFilters[filterId]->configure(setting); + + return AssertionResult(status == Result::SUCCESS); +} + +AssertionResult FilterTests::getFilterMQDescriptor(uint64_t filterId) { + Result status; + EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first."; + EXPECT_TRUE(mFilterCallbacks[filterId]) << "Test with getNewlyOpenedFilterId first."; + + mFilter->getQueueDesc([&](Result result, const MQDesc& filterMQDesc) { + mFilterMQDescriptor = filterMQDesc; + status = result; + }); + + return AssertionResult(status == Result::SUCCESS); +} + +AssertionResult FilterTests::startFilter(uint64_t filterId) { + EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first."; + Result status = mFilters[filterId]->start(); + return AssertionResult(status == Result::SUCCESS); +} + +AssertionResult FilterTests::stopFilter(uint64_t filterId) { + EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first."; + Result status = mFilters[filterId]->stop(); + return AssertionResult(status == Result::SUCCESS); +} + +AssertionResult FilterTests::closeFilter(uint64_t filterId) { + EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first."; + Result status = mFilters[filterId]->close(); + if (status == Result::SUCCESS) { + for (int i = 0; i < mUsedFilterIds.size(); i++) { + if (mUsedFilterIds[i] == filterId) { + mUsedFilterIds.erase(mUsedFilterIds.begin() + i); + break; + } + } + mFilterCallbacks.erase(filterId); + mFilters.erase(filterId); + } + return AssertionResult(status == Result::SUCCESS); +} diff --git a/tv/tuner/1.1/vts/functional/FilterTests.h b/tv/tuner/1.1/vts/functional/FilterTests.h new file mode 100644 index 0000000000..b1b6e13759 --- /dev/null +++ b/tv/tuner/1.1/vts/functional/FilterTests.h @@ -0,0 +1,168 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using android::Condition; +using android::Mutex; +using android::sp; +using android::hardware::EventFlag; +using android::hardware::hidl_handle; +using android::hardware::hidl_string; +using android::hardware::hidl_vec; +using android::hardware::kSynchronizedReadWrite; +using android::hardware::MessageQueue; +using android::hardware::MQDescriptorSync; +using android::hardware::Return; +using android::hardware::Void; +using android::hardware::tv::tuner::V1_0::DemuxFilterEvent; +using android::hardware::tv::tuner::V1_0::DemuxFilterMainType; +using android::hardware::tv::tuner::V1_0::DemuxFilterSettings; +using android::hardware::tv::tuner::V1_0::DemuxFilterStatus; +using android::hardware::tv::tuner::V1_0::DemuxFilterType; +using android::hardware::tv::tuner::V1_0::DemuxTsFilterType; +using android::hardware::tv::tuner::V1_0::IDemux; +using android::hardware::tv::tuner::V1_0::IFilter; +using android::hardware::tv::tuner::V1_0::IFilterCallback; +using android::hardware::tv::tuner::V1_0::Result; +using android::hardware::tv::tuner::V1_1::ITuner; + +using ::testing::AssertionResult; + +using namespace std; + +enum FilterEventType : uint8_t { + UNDEFINED, + SECTION, + MEDIA, + PES, + RECORD, + MMTPRECORD, + DOWNLOAD, + TEMI, +}; + +using FilterMQ = MessageQueue; +using MQDesc = MQDescriptorSync; + +#define WAIT_TIMEOUT 3000000000 + +class FilterCallback : public IFilterCallback { + public: + virtual Return onFilterEvent(const DemuxFilterEvent& /*filterEvent*/) override { + return Void(); + } + + virtual Return onFilterStatus(const DemuxFilterStatus /*status*/) override { + return Void(); + } +}; + +class FilterTests { + public: + void setService(sp tuner) { mService = tuner; } + void setDemux(sp demux) { mDemux = demux; } + sp getFilterById(uint64_t filterId) { return mFilters[filterId]; } + + std::map> getFilterCallbacks() { return mFilterCallbacks; } + + AssertionResult openFilterInDemux(DemuxFilterType type, uint32_t bufferSize); + AssertionResult getNewlyOpenedFilterId_64bit(uint64_t& filterId); + AssertionResult configFilter(DemuxFilterSettings setting, uint64_t filterId); + AssertionResult getFilterMQDescriptor(uint64_t filterId); + AssertionResult startFilter(uint64_t filterId); + AssertionResult stopFilter(uint64_t filterId); + AssertionResult closeFilter(uint64_t filterId); + + FilterEventType getFilterEventType(DemuxFilterType type) { + FilterEventType eventType = FilterEventType::UNDEFINED; + switch (type.mainType) { + case DemuxFilterMainType::TS: + switch (type.subType.tsFilterType()) { + case DemuxTsFilterType::UNDEFINED: + break; + case DemuxTsFilterType::SECTION: + eventType = FilterEventType::SECTION; + break; + case DemuxTsFilterType::PES: + eventType = FilterEventType::PES; + break; + case DemuxTsFilterType::TS: + break; + case DemuxTsFilterType::AUDIO: + case DemuxTsFilterType::VIDEO: + eventType = FilterEventType::MEDIA; + break; + case DemuxTsFilterType::PCR: + break; + case DemuxTsFilterType::RECORD: + eventType = FilterEventType::RECORD; + break; + case DemuxTsFilterType::TEMI: + eventType = FilterEventType::TEMI; + break; + } + break; + case DemuxFilterMainType::MMTP: + /*mmtpSettings*/ + break; + case DemuxFilterMainType::IP: + /*ipSettings*/ + break; + case DemuxFilterMainType::TLV: + /*tlvSettings*/ + break; + case DemuxFilterMainType::ALP: + /*alpSettings*/ + break; + default: + break; + } + return eventType; + } + + protected: + static AssertionResult failure() { return ::testing::AssertionFailure(); } + + static AssertionResult success() { return ::testing::AssertionSuccess(); } + + sp mService; + sp mFilter; + sp mDemux; + std::map> mFilters; + std::map> mFilterCallbacks; + + sp mFilterCallback; + MQDesc mFilterMQDescriptor; + vector mUsedFilterIds; + + uint64_t mFilterId = -1; +}; diff --git a/tv/tuner/1.1/vts/functional/FrontendTests.cpp b/tv/tuner/1.1/vts/functional/FrontendTests.cpp new file mode 100644 index 0000000000..8c359c51a6 --- /dev/null +++ b/tv/tuner/1.1/vts/functional/FrontendTests.cpp @@ -0,0 +1,83 @@ +/* + * 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 "FrontendTests.h" + +Return FrontendCallback::onEvent(FrontendEventType /*frontendEventType*/) { + return Void(); +} + +Return FrontendCallback::onScanMessage(FrontendScanMessageType /*type*/, + const FrontendScanMessage& /*message*/) { + return Void(); +} + +AssertionResult FrontendTests::getFrontendIds() { + Result status; + mService->getFrontendIds([&](Result result, const hidl_vec& frontendIds) { + status = result; + mFeIds = frontendIds; + }); + return AssertionResult(status == Result::SUCCESS); +} + +AssertionResult FrontendTests::getFrontendInfo(uint32_t frontendId) { + Result status; + mService->getFrontendInfo(frontendId, [&](Result result, const FrontendInfo& frontendInfo) { + mFrontendInfo = frontendInfo; + status = result; + }); + return AssertionResult(status == Result::SUCCESS); +} + +AssertionResult FrontendTests::openFrontendById(uint32_t frontendId) { + Result status; + mService->openFrontendById(frontendId, [&](Result result, const sp& frontend) { + mFrontend = frontend; + status = result; + }); + return AssertionResult(status == Result::SUCCESS); +} + +AssertionResult FrontendTests::setFrontendCallback() { + EXPECT_TRUE(mFrontend) << "Test with openFrontendById first."; + mFrontendCallback = new FrontendCallback(); + auto callbackStatus = mFrontend->setCallback(mFrontendCallback); + return AssertionResult(callbackStatus.isOk()); +} + +AssertionResult FrontendTests::closeFrontend() { + EXPECT_TRUE(mFrontend) << "Test with openFrontendById first."; + Result status; + status = mFrontend->close(); + mFrontend = nullptr; + mFrontendCallback = nullptr; + return AssertionResult(status == Result::SUCCESS); +} + +void FrontendTests::getFrontendIdByType(FrontendType feType, uint32_t& feId) { + ASSERT_TRUE(getFrontendIds()); + ASSERT_TRUE(mFeIds.size() > 0); + for (size_t i = 0; i < mFeIds.size(); i++) { + ASSERT_TRUE(getFrontendInfo(mFeIds[i])); + if (mFrontendInfo.type != feType) { + continue; + } + feId = mFeIds[i]; + return; + } + feId = INVALID_ID; +} \ No newline at end of file diff --git a/tv/tuner/1.1/vts/functional/FrontendTests.h b/tv/tuner/1.1/vts/functional/FrontendTests.h new file mode 100644 index 0000000000..e68758919d --- /dev/null +++ b/tv/tuner/1.1/vts/functional/FrontendTests.h @@ -0,0 +1,96 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "VtsHalTvTunerV1_1TestConfigurations.h" + +#define WAIT_TIMEOUT 3000000000 +#define INVALID_ID -1 + +using android::Condition; +using android::IMemory; +using android::IMemoryHeap; +using android::MemoryDealer; +using android::Mutex; +using android::sp; +using android::hardware::fromHeap; +using android::hardware::hidl_vec; +using android::hardware::Return; +using android::hardware::Void; +using android::hardware::tv::tuner::V1_0::FrontendEventType; +using android::hardware::tv::tuner::V1_0::FrontendId; +using android::hardware::tv::tuner::V1_0::FrontendInfo; +using android::hardware::tv::tuner::V1_0::FrontendScanMessage; +using android::hardware::tv::tuner::V1_0::FrontendScanMessageType; +using android::hardware::tv::tuner::V1_0::IFrontend; +using android::hardware::tv::tuner::V1_0::IFrontendCallback; +using android::hardware::tv::tuner::V1_0::Result; +using android::hardware::tv::tuner::V1_1::ITuner; + +using ::testing::AssertionResult; + +using namespace std; + +#define INVALID_ID -1 + +class FrontendCallback : public IFrontendCallback { + public: + virtual Return onEvent(FrontendEventType frontendEventType) override; + virtual Return onScanMessage(FrontendScanMessageType type, + const FrontendScanMessage& message) override; +}; + +class FrontendTests { + public: + sp mService; + + void setService(sp tuner) { mService = tuner; } + + AssertionResult getFrontendIds(); + AssertionResult getFrontendInfo(uint32_t frontendId); + AssertionResult openFrontendById(uint32_t frontendId); + AssertionResult setFrontendCallback(); + AssertionResult closeFrontend(); + + void getFrontendIdByType(FrontendType feType, uint32_t& feId); + + protected: + static AssertionResult failure() { return ::testing::AssertionFailure(); } + static AssertionResult success() { return ::testing::AssertionSuccess(); } + + sp mFrontend; + FrontendInfo mFrontendInfo; + sp mFrontendCallback; + hidl_vec mFeIds; + + bool mIsSoftwareFe = false; +}; \ No newline at end of file diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp new file mode 100644 index 0000000000..7c113d4421 --- /dev/null +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp @@ -0,0 +1,58 @@ +/* + * 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 "VtsHalTvTunerV1_1TargetTest.h" + +namespace { + +void TunerFilterHidlTest::configSingleFilterInDemuxTest(FilterConfig filterConf, + FrontendConfig frontendConf) { + uint32_t feId; + uint32_t demuxId; + sp demux; + uint64_t filterId; + + mFrontendTests.getFrontendIdByType(frontendConf.type, feId); + ASSERT_TRUE(feId != INVALID_ID); + ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); + ASSERT_TRUE(mFrontendTests.setFrontendCallback()); + ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); + ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); + mFilterTests.setDemux(demux); + ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize)); + ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(filterId)); + ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId)); + ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId)); + ASSERT_TRUE(mFilterTests.startFilter(filterId)); + ASSERT_TRUE(mFilterTests.stopFilter(filterId)); + ASSERT_TRUE(mFilterTests.closeFilter(filterId)); + ASSERT_TRUE(mDemuxTests.closeDemux()); + ASSERT_TRUE(mFrontendTests.closeFrontend()); +} + +TEST_P(TunerFilterHidlTest, StartFilterInDemux) { + description("Open and start a filter in Demux."); + // TODO use parameterized tests + configSingleFilterInDemuxTest(filterArray[TS_VIDEO0], frontendArray[DVBT]); +} + +INSTANTIATE_TEST_SUITE_P( + PerInstance, TunerFilterHidlTest, + testing::ValuesIn(android::hardware::getAllHalInstanceNames(ITuner::descriptor)), + android::hardware::PrintInstanceNameToString); + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerFilterHidlTest); +} // namespace diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h new file mode 100644 index 0000000000..04536343fa --- /dev/null +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h @@ -0,0 +1,52 @@ +/* + * 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 "DemuxTests.h" +#include "FilterTests.h" +#include "FrontendTests.h" + +namespace { + +void initConfiguration() { + initFrontendConfig(); + initFilterConfig(); +} + +class TunerFilterHidlTest : public testing::TestWithParam { + public: + virtual void SetUp() override { + mService = ITuner::getService(GetParam()); + ASSERT_NE(mService, nullptr); + initConfiguration(); + + mFrontendTests.setService(mService); + mDemuxTests.setService(mService); + mFilterTests.setService(mService); + } + + protected: + static void description(const std::string& description) { + RecordProperty("description", description); + } + + void configSingleFilterInDemuxTest(FilterConfig filterConf, FrontendConfig frontendConf); + + sp mService; + FrontendTests mFrontendTests; + DemuxTests mDemuxTests; + FilterTests mFilterTests; +}; +} // namespace \ No newline at end of file diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h new file mode 100644 index 0000000000..23c9353d03 --- /dev/null +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h @@ -0,0 +1,178 @@ +/* + * 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 +#include +#include +#include +#include +#include + +using android::hardware::tv::tuner::V1_0::DemuxAlpFilterType; +using android::hardware::tv::tuner::V1_0::DemuxFilterEvent; +using android::hardware::tv::tuner::V1_0::DemuxFilterMainType; +using android::hardware::tv::tuner::V1_0::DemuxFilterSettings; +using android::hardware::tv::tuner::V1_0::DemuxFilterType; +using android::hardware::tv::tuner::V1_0::DemuxIpFilterType; +using android::hardware::tv::tuner::V1_0::DemuxMmtpFilterType; +using android::hardware::tv::tuner::V1_0::DemuxRecordScIndexType; +using android::hardware::tv::tuner::V1_0::DemuxTsFilterType; +using android::hardware::tv::tuner::V1_0::FrontendDvbtBandwidth; +using android::hardware::tv::tuner::V1_0::FrontendDvbtCoderate; +using android::hardware::tv::tuner::V1_0::FrontendDvbtConstellation; +using android::hardware::tv::tuner::V1_0::FrontendDvbtGuardInterval; +using android::hardware::tv::tuner::V1_0::FrontendDvbtHierarchy; +using android::hardware::tv::tuner::V1_0::FrontendDvbtSettings; +using android::hardware::tv::tuner::V1_0::FrontendDvbtStandard; +using android::hardware::tv::tuner::V1_0::FrontendDvbtTransmissionMode; +using android::hardware::tv::tuner::V1_0::FrontendSettings; +using android::hardware::tv::tuner::V1_0::FrontendStatus; +using android::hardware::tv::tuner::V1_0::FrontendStatusType; +using android::hardware::tv::tuner::V1_0::FrontendType; + +using namespace std; + +const uint32_t FMQ_SIZE_1M = 0x100000; +const uint32_t FMQ_SIZE_4M = 0x400000; +const uint32_t FMQ_SIZE_16M = 0x1000000; + +typedef enum { + TS_VIDEO0, + TS_VIDEO1, + TS_AUDIO0, + TS_AUDIO1, + TS_PES0, + TS_PCR0, + TS_SECTION0, + TS_TS0, + TS_RECORD0, + FILTER_MAX, +} Filter; + +typedef enum { + DVBT, + DVBS, + FRONTEND_MAX, +} Frontend; + +struct FilterConfig { + uint32_t bufferSize; + DemuxFilterType type; + DemuxFilterSettings settings; + + bool operator<(const FilterConfig& /*c*/) const { return false; } +}; + +struct FrontendConfig { + bool isSoftwareFe; + FrontendType type; + FrontendSettings settings; + vector tuneStatusTypes; + vector expectTuneStatuses; +}; + +static FrontendConfig frontendArray[FILTER_MAX]; +static FilterConfig filterArray[FILTER_MAX]; + +/** Configuration array for the frontend tune test */ +inline void initFrontendConfig() { + FrontendDvbtSettings dvbtSettings{ + .frequency = 578000, + .transmissionMode = FrontendDvbtTransmissionMode::AUTO, + .bandwidth = FrontendDvbtBandwidth::BANDWIDTH_8MHZ, + .constellation = FrontendDvbtConstellation::AUTO, + .hierarchy = FrontendDvbtHierarchy::AUTO, + .hpCoderate = FrontendDvbtCoderate::AUTO, + .lpCoderate = FrontendDvbtCoderate::AUTO, + .guardInterval = FrontendDvbtGuardInterval::AUTO, + .isHighPriority = true, + .standard = FrontendDvbtStandard::T, + }; + frontendArray[DVBT].type = FrontendType::DVBT, frontendArray[DVBT].settings.dvbt(dvbtSettings); + vector types; + types.push_back(FrontendStatusType::DEMOD_LOCK); + FrontendStatus status; + status.isDemodLocked(true); + vector statuses; + statuses.push_back(status); + frontendArray[DVBT].tuneStatusTypes = types; + frontendArray[DVBT].expectTuneStatuses = statuses; + frontendArray[DVBT].isSoftwareFe = true; + frontendArray[DVBS].type = FrontendType::DVBS; + frontendArray[DVBS].isSoftwareFe = true; +}; + +/** Configuration array for the filter test */ +inline void initFilterConfig() { + // TS VIDEO filter setting for default implementation testing + filterArray[TS_VIDEO0].type.mainType = DemuxFilterMainType::TS; + filterArray[TS_VIDEO0].type.subType.tsFilterType(DemuxTsFilterType::VIDEO); + filterArray[TS_VIDEO0].bufferSize = FMQ_SIZE_16M; + filterArray[TS_VIDEO0].settings.ts().tpid = 256; + filterArray[TS_VIDEO0].settings.ts().filterSettings.av({.isPassthrough = false}); + filterArray[TS_VIDEO1].type.mainType = DemuxFilterMainType::TS; + filterArray[TS_VIDEO1].type.subType.tsFilterType(DemuxTsFilterType::VIDEO); + filterArray[TS_VIDEO1].bufferSize = FMQ_SIZE_16M; + filterArray[TS_VIDEO1].settings.ts().tpid = 256; + filterArray[TS_VIDEO1].settings.ts().filterSettings.av({.isPassthrough = false}); + // TS AUDIO filter setting + filterArray[TS_AUDIO0].type.mainType = DemuxFilterMainType::TS; + filterArray[TS_AUDIO0].type.subType.tsFilterType(DemuxTsFilterType::AUDIO); + filterArray[TS_AUDIO0].bufferSize = FMQ_SIZE_16M; + filterArray[TS_AUDIO0].settings.ts().tpid = 256; + filterArray[TS_AUDIO0].settings.ts().filterSettings.av({.isPassthrough = false}); + filterArray[TS_AUDIO1].type.mainType = DemuxFilterMainType::TS; + filterArray[TS_AUDIO1].type.subType.tsFilterType(DemuxTsFilterType::AUDIO); + filterArray[TS_AUDIO1].bufferSize = FMQ_SIZE_16M; + filterArray[TS_AUDIO1].settings.ts().tpid = 257; + filterArray[TS_AUDIO1].settings.ts().filterSettings.av({.isPassthrough = false}); + // TS PES filter setting + filterArray[TS_PES0].type.mainType = DemuxFilterMainType::TS; + filterArray[TS_PES0].type.subType.tsFilterType(DemuxTsFilterType::PES); + filterArray[TS_PES0].bufferSize = FMQ_SIZE_16M; + filterArray[TS_PES0].settings.ts().tpid = 256; + filterArray[TS_PES0].settings.ts().filterSettings.pesData({ + .isRaw = false, + .streamId = 0xbd, + }); + // TS PCR filter setting + filterArray[TS_PCR0].type.mainType = DemuxFilterMainType::TS; + filterArray[TS_PCR0].type.subType.tsFilterType(DemuxTsFilterType::PCR); + filterArray[TS_PCR0].bufferSize = FMQ_SIZE_16M; + filterArray[TS_PCR0].settings.ts().tpid = 256; + filterArray[TS_PCR0].settings.ts().filterSettings.noinit(); + // TS filter setting + filterArray[TS_TS0].type.mainType = DemuxFilterMainType::TS; + filterArray[TS_TS0].type.subType.tsFilterType(DemuxTsFilterType::TS); + filterArray[TS_TS0].bufferSize = FMQ_SIZE_16M; + filterArray[TS_TS0].settings.ts().tpid = 256; + filterArray[TS_TS0].settings.ts().filterSettings.noinit(); + // TS SECTION filter setting + filterArray[TS_SECTION0].type.mainType = DemuxFilterMainType::TS; + filterArray[TS_SECTION0].type.subType.tsFilterType(DemuxTsFilterType::SECTION); + filterArray[TS_SECTION0].bufferSize = FMQ_SIZE_16M; + filterArray[TS_SECTION0].settings.ts().tpid = 256; + filterArray[TS_SECTION0].settings.ts().filterSettings.section({ + .isRaw = false, + }); + // TS RECORD filter setting + filterArray[TS_RECORD0].type.mainType = DemuxFilterMainType::TS; + filterArray[TS_RECORD0].type.subType.tsFilterType(DemuxTsFilterType::RECORD); + filterArray[TS_RECORD0].settings.ts().tpid = 81; + filterArray[TS_RECORD0].settings.ts().filterSettings.record({ + .scIndexType = DemuxRecordScIndexType::NONE, + }); +}; -- GitLab From 80cb96048b6c07666e508137201b4f2a03a6da34 Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Wed, 15 Jul 2020 13:06:39 -0700 Subject: [PATCH 076/790] Add a getAvSyncHwId_64bit in Tuner HAL 1.1 to support 64 bit hw sync id Test: atest VtsHalTvTunerV1_1TargetTest Bug: b/159058358 Change-Id: I3e58beaf4f61b27acce71a530e42293c4a87b181 --- tv/tuner/1.1/Android.bp | 1 + tv/tuner/1.1/IDemux.hal | 41 +++++++++++++++ tv/tuner/1.1/default/Demux.cpp | 50 +++++++++++++++++++ tv/tuner/1.1/default/Demux.h | 6 ++- tv/tuner/1.1/default/Frontend.cpp | 1 + tv/tuner/1.1/default/Tuner.cpp | 18 ++++++- tv/tuner/1.1/default/Tuner.h | 10 ++-- tv/tuner/1.1/vts/functional/DemuxTests.cpp | 30 +++++++++++ tv/tuner/1.1/vts/functional/DemuxTests.h | 3 ++ .../VtsHalTvTunerV1_1TargetTest.cpp | 41 +++++++++++++++ .../functional/VtsHalTvTunerV1_1TargetTest.h | 23 +++++++++ 11 files changed, 217 insertions(+), 7 deletions(-) create mode 100644 tv/tuner/1.1/IDemux.hal diff --git a/tv/tuner/1.1/Android.bp b/tv/tuner/1.1/Android.bp index c051ab0902..476915e9b0 100644 --- a/tv/tuner/1.1/Android.bp +++ b/tv/tuner/1.1/Android.bp @@ -6,6 +6,7 @@ hidl_interface { srcs: [ "IFilter.hal", "ITuner.hal", + "IDemux.hal", ], interfaces: [ "android.hidl.base@1.0", diff --git a/tv/tuner/1.1/IDemux.hal b/tv/tuner/1.1/IDemux.hal new file mode 100644 index 0000000000..81cd001313 --- /dev/null +++ b/tv/tuner/1.1/IDemux.hal @@ -0,0 +1,41 @@ +/* + * 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. + */ + +package android.hardware.tv.tuner@1.1; + +import @1.0::IDemux; +import @1.0::Result; +import @1.0::IFilter; + +/** + * Demultiplexer(Demux) takes a single multiplexed input and splits it into + * one or more output. + */ +interface IDemux extends @1.0::IDemux { + /** + * Get a 64-bit hardware sync ID for audio and video. + * + * It is used by the client to get the hardware sync ID for audio and video. + * + * @param filter the filter instance. + * @return result Result status of the operation. + * SUCCESS if successful, + * INVALID_ARGUMENT if failed for a wrong filter ID. + * UNKNOWN_ERROR if failed for other reasons. + * @return avSyncHwId the id of hardware A/V sync. + */ + getAvSyncHwId64Bit(IFilter filter) generates (Result result, uint64_t avSyncHwId); +}; \ No newline at end of file diff --git a/tv/tuner/1.1/default/Demux.cpp b/tv/tuner/1.1/default/Demux.cpp index b6b029fdb4..f501d74e67 100644 --- a/tv/tuner/1.1/default/Demux.cpp +++ b/tv/tuner/1.1/default/Demux.cpp @@ -34,6 +34,49 @@ Demux::Demux(uint32_t demuxId, sp tuner) { Demux::~Demux() {} +Return Demux::getAvSyncHwId64Bit(const sp& filter, getAvSyncHwId64Bit_cb _hidl_cb) { + ALOGV("%s", __FUNCTION__); + + uint64_t avSyncHwId = -1; + uint64_t id; + Result status; + + sp filter_v1_1 = V1_1::IFilter::castFrom(filter); + if (filter_v1_1 != NULL) { + filter_v1_1->getId64Bit([&](Result result, uint64_t filterId) { + id = filterId; + status = result; + }); + } else { + filter->getId([&](Result result, uint32_t filterId) { + id = filterId; + status = result; + }); + } + + if (status != Result::SUCCESS) { + ALOGE("[Demux] Can't get 64-bit filter Id."); + _hidl_cb(Result::INVALID_STATE, avSyncHwId); + return Void(); + } + + if (!mFilters[id]->isMediaFilter()) { + ALOGE("[Demux] Given filter is not a media filter."); + _hidl_cb(Result::INVALID_ARGUMENT, avSyncHwId); + return Void(); + } + + if (!mPcrFilterIds.empty()) { + // Return the lowest pcr filter id in the default implementation as the av sync id + _hidl_cb(Result::SUCCESS, *mPcrFilterIds.begin()); + return Void(); + } + + ALOGE("[Demux] No PCR filter opened."); + _hidl_cb(Result::INVALID_STATE, avSyncHwId); + return Void(); +} + Return Demux::setFrontendDataSource(uint32_t frontendId) { ALOGV("%s", __FUNCTION__); @@ -170,6 +213,7 @@ Return Demux::close() { mRecordFilterIds.clear(); mFilters.clear(); mLastUsedFilterId = -1; + mTunerService->removeDemux(mDemuxId); return Result::SUCCESS; } @@ -325,6 +369,12 @@ void Demux::frontendInputThreadLoop() { std::lock_guard lock(mFrontendInputThreadLock); mFrontendInputThreadRunning = true; + if (!mDvrPlayback) { + ALOGW("[Demux] No software Frontend input configured. Ending Frontend thread loop."); + mFrontendInputThreadRunning = false; + return; + } + while (mFrontendInputThreadRunning) { uint32_t efState = 0; status_t status = mDvrPlayback->getDvrEventFlag()->wait( diff --git a/tv/tuner/1.1/default/Demux.h b/tv/tuner/1.1/default/Demux.h index 62f916267f..f38f006aae 100644 --- a/tv/tuner/1.1/default/Demux.h +++ b/tv/tuner/1.1/default/Demux.h @@ -17,6 +17,7 @@ #ifndef ANDROID_HARDWARE_TV_TUNER_V1_1_DEMUX_H_ #define ANDROID_HARDWARE_TV_TUNER_V1_1_DEMUX_H_ +#include #include #include #include @@ -48,12 +49,15 @@ class Frontend; class TimeFilter; class Tuner; -class Demux : public IDemux { +class Demux : public V1_1::IDemux { public: Demux(uint32_t demuxId, sp tuner); ~Demux(); + virtual Return getAvSyncHwId64Bit(const sp& filter, + getAvSyncHwId64Bit_cb _hidl_cb) override; + virtual Return setFrontendDataSource(uint32_t frontendId) override; virtual Return openFilter(const DemuxFilterType& type, uint32_t bufferSize, diff --git a/tv/tuner/1.1/default/Frontend.cpp b/tv/tuner/1.1/default/Frontend.cpp index 3475c3686b..6f5885fad7 100644 --- a/tv/tuner/1.1/default/Frontend.cpp +++ b/tv/tuner/1.1/default/Frontend.cpp @@ -42,6 +42,7 @@ Return Frontend::close() { // Reset callback mCallback = nullptr; mIsLocked = false; + mTunerService->removeFrontend(mId); return Result::SUCCESS; } diff --git a/tv/tuner/1.1/default/Tuner.cpp b/tv/tuner/1.1/default/Tuner.cpp index c220ea2682..0a0667e87d 100644 --- a/tv/tuner/1.1/default/Tuner.cpp +++ b/tv/tuner/1.1/default/Tuner.cpp @@ -34,7 +34,6 @@ Tuner::Tuner() { // Static Frontends array to maintain local frontends information // Array index matches their FrontendId in the default impl mFrontendSize = 8; - mFrontends.resize(mFrontendSize); mFrontends[0] = new Frontend(FrontendType::DVBT, 0, this); mFrontends[1] = new Frontend(FrontendType::ATSC, 1, this); mFrontends[2] = new Frontend(FrontendType::DVBC, 2, this); @@ -45,7 +44,6 @@ Tuner::Tuner() { mFrontends[7] = new Frontend(FrontendType::ATSC, 7, this); FrontendInfo::FrontendCapabilities caps; - mFrontendCaps.resize(mFrontendSize); caps = FrontendInfo::FrontendCapabilities(); caps.dvbtCaps(FrontendDvbtCapabilities()); mFrontendCaps[0] = caps; @@ -233,6 +231,22 @@ void Tuner::setFrontendAsDemuxSource(uint32_t frontendId, uint32_t demuxId) { } } +void Tuner::removeDemux(uint32_t demuxId) { + map::iterator it; + for (it = mFrontendToDemux.begin(); it != mFrontendToDemux.end();) { + if (it->second == demuxId) { + it = mFrontendToDemux.erase(it); + } else { + it++; + } + } + mDemuxes.erase(demuxId); +} + +void Tuner::removeFrontend(uint32_t frontendId) { + mFrontendToDemux.erase(frontendId); +} + void Tuner::frontendStopTune(uint32_t frontendId) { map::iterator it = mFrontendToDemux.find(frontendId); uint32_t demuxId; diff --git a/tv/tuner/1.1/default/Tuner.h b/tv/tuner/1.1/default/Tuner.h index 9463278a1e..3b1574b8aa 100644 --- a/tv/tuner/1.1/default/Tuner.h +++ b/tv/tuner/1.1/default/Tuner.h @@ -68,14 +68,16 @@ class Tuner : public ITuner { void frontendStartTune(uint32_t frontendId); void frontendStopTune(uint32_t frontendId); + void removeDemux(uint32_t demuxId); + void removeFrontend(uint32_t frontendId); private: virtual ~Tuner(); // Static mFrontends array to maintain local frontends information - vector> mFrontends; - vector mFrontendCaps; - std::map mFrontendToDemux; - std::map> mDemuxes; + map> mFrontends; + map mFrontendCaps; + map mFrontendToDemux; + map> mDemuxes; // To maintain how many Frontends we have int mFrontendSize; // The last used demux id. Initial value is -1. diff --git a/tv/tuner/1.1/vts/functional/DemuxTests.cpp b/tv/tuner/1.1/vts/functional/DemuxTests.cpp index b1d8a0a0b2..e0600b62a1 100644 --- a/tv/tuner/1.1/vts/functional/DemuxTests.cpp +++ b/tv/tuner/1.1/vts/functional/DemuxTests.cpp @@ -38,4 +38,34 @@ AssertionResult DemuxTests::closeDemux() { auto status = mDemux->close(); mDemux = nullptr; return AssertionResult(status.isOk()); +} + +AssertionResult DemuxTests::getAvSyncId_64bit(sp filter, uint64_t& avSyncHwId) { + EXPECT_TRUE(mDemux) << "Demux is not opened yet."; + Result status; + + sp demux_v1_1 = + android::hardware::tv::tuner::V1_1::IDemux::castFrom(mDemux); + if (demux_v1_1 != NULL) { + demux_v1_1->getAvSyncHwId64Bit(filter, [&](Result result, uint64_t id) { + status = result; + avSyncHwId = id; + }); + } else { + ALOGW("[vts] Can't cast IDemux into v1_1."); + return failure(); + } + + return AssertionResult(status == Result::SUCCESS); +} + +AssertionResult DemuxTests::getAvSyncTime(uint32_t avSyncId) { + EXPECT_TRUE(mDemux) << "Demux is not opened yet."; + Result status; + uint64_t syncTime; + mDemux->getAvSyncTime(avSyncId, [&](Result result, uint64_t time) { + status = result; + syncTime = time; + }); + return AssertionResult(status == Result::SUCCESS); } \ No newline at end of file diff --git a/tv/tuner/1.1/vts/functional/DemuxTests.h b/tv/tuner/1.1/vts/functional/DemuxTests.h index c28d6ca524..393757c3b6 100644 --- a/tv/tuner/1.1/vts/functional/DemuxTests.h +++ b/tv/tuner/1.1/vts/functional/DemuxTests.h @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -44,6 +45,8 @@ class DemuxTests { AssertionResult openDemux(sp& demux, uint32_t& demuxId); AssertionResult setDemuxFrontendDataSource(uint32_t frontendId); + AssertionResult getAvSyncId_64bit(sp filter, uint64_t& avSyncHwId); + AssertionResult getAvSyncTime(uint32_t avSyncId); AssertionResult closeDemux(); protected: diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp index 7c113d4421..c74e29c002 100644 --- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp @@ -43,6 +43,41 @@ void TunerFilterHidlTest::configSingleFilterInDemuxTest(FilterConfig filterConf, ASSERT_TRUE(mFrontendTests.closeFrontend()); } +TEST_P(TunerDemuxHidlTest, getAvSyncTime) { + description("Get the A/V sync time from a PCR filter."); + uint32_t feId; + uint32_t demuxId; + sp demux; + uint64_t mediaFilterId; + uint64_t pcrFilterId; + uint64_t avSyncHwId; + sp mediaFilter; + + mFrontendTests.getFrontendIdByType(frontendArray[DVBT].type, feId); + ASSERT_TRUE(feId != INVALID_ID); + ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); + ASSERT_TRUE(mFrontendTests.setFrontendCallback()); + ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); + ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); + mFilterTests.setDemux(demux); + ASSERT_TRUE(mFilterTests.openFilterInDemux(filterArray[TS_VIDEO1].type, + filterArray[TS_VIDEO1].bufferSize)); + ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(mediaFilterId)); + ASSERT_TRUE(mFilterTests.configFilter(filterArray[TS_VIDEO1].settings, mediaFilterId)); + mediaFilter = mFilterTests.getFilterById(mediaFilterId); + ASSERT_TRUE(mFilterTests.openFilterInDemux(filterArray[TS_PCR0].type, + filterArray[TS_PCR0].bufferSize)); + ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(pcrFilterId)); + ASSERT_TRUE(mFilterTests.configFilter(filterArray[TS_PCR0].settings, pcrFilterId)); + ASSERT_TRUE(mDemuxTests.getAvSyncId_64bit(mediaFilter, avSyncHwId)); + ASSERT_TRUE(pcrFilterId == avSyncHwId); + ASSERT_TRUE(mDemuxTests.getAvSyncTime(pcrFilterId)); + ASSERT_TRUE(mFilterTests.closeFilter(pcrFilterId)); + ASSERT_TRUE(mFilterTests.closeFilter(mediaFilterId)); + ASSERT_TRUE(mDemuxTests.closeDemux()); + ASSERT_TRUE(mFrontendTests.closeFrontend()); +} + TEST_P(TunerFilterHidlTest, StartFilterInDemux) { description("Open and start a filter in Demux."); // TODO use parameterized tests @@ -54,5 +89,11 @@ INSTANTIATE_TEST_SUITE_P( testing::ValuesIn(android::hardware::getAllHalInstanceNames(ITuner::descriptor)), android::hardware::PrintInstanceNameToString); +INSTANTIATE_TEST_SUITE_P( + PerInstance, TunerDemuxHidlTest, + testing::ValuesIn(android::hardware::getAllHalInstanceNames(ITuner::descriptor)), + android::hardware::PrintInstanceNameToString); + GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerFilterHidlTest); +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerDemuxHidlTest); } // namespace diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h index 04536343fa..30533b1310 100644 --- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h @@ -49,4 +49,27 @@ class TunerFilterHidlTest : public testing::TestWithParam { DemuxTests mDemuxTests; FilterTests mFilterTests; }; + +class TunerDemuxHidlTest : public testing::TestWithParam { + public: + virtual void SetUp() override { + mService = ITuner::getService(GetParam()); + ASSERT_NE(mService, nullptr); + initConfiguration(); + + mFrontendTests.setService(mService); + mDemuxTests.setService(mService); + mFilterTests.setService(mService); + } + + protected: + static void description(const std::string& description) { + RecordProperty("description", description); + } + + sp mService; + FrontendTests mFrontendTests; + DemuxTests mDemuxTests; + FilterTests mFilterTests; +}; } // namespace \ No newline at end of file -- GitLab From 849540300007aa35222f0171c3f25e7f58b091a4 Mon Sep 17 00:00:00 2001 From: Tomasz Wasilczyk Date: Wed, 22 Jul 2020 14:19:21 -0700 Subject: [PATCH 077/790] Implement struct printing Also: - fix potential use-after-free in nlbuf iterator - simplify getFirst usage by migrating from std::optional to std::pair Bug: 161898189 Test: print all messages from RTMGRP_LINK group Change-Id: I4aa785ccef60e397ba87088f37e35d9873fc3c82 --- .../can/1.0/default/libnetdevice/Android.bp | 1 + .../libnetdevice/include/libnetdevice/nlbuf.h | 19 ++-- .../can/1.0/default/libnetdevice/printer.cpp | 14 ++- .../protocols/MessageDefinition.h | 11 ++- .../libnetdevice/protocols/generic/Ctrl.cpp | 8 +- .../libnetdevice/protocols/route/Link.cpp | 94 +++++++++++-------- .../libnetdevice/protocols/route/structs.cpp | 49 ++++++++++ .../libnetdevice/protocols/route/structs.h | 78 +++++++++++++++ 8 files changed, 217 insertions(+), 57 deletions(-) create mode 100644 automotive/can/1.0/default/libnetdevice/protocols/route/structs.cpp create mode 100644 automotive/can/1.0/default/libnetdevice/protocols/route/structs.h diff --git a/automotive/can/1.0/default/libnetdevice/Android.bp b/automotive/can/1.0/default/libnetdevice/Android.bp index 928ad1339a..d49b9abb17 100644 --- a/automotive/can/1.0/default/libnetdevice/Android.bp +++ b/automotive/can/1.0/default/libnetdevice/Android.bp @@ -28,6 +28,7 @@ cc_library_static { "protocols/generic/Unknown.cpp", "protocols/route/Link.cpp", "protocols/route/Route.cpp", + "protocols/route/structs.cpp", "protocols/MessageDefinition.cpp", "protocols/NetlinkProtocol.cpp", "protocols/all.cpp", diff --git a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/nlbuf.h b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/nlbuf.h index 17815f9b7b..601ab942af 100644 --- a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/nlbuf.h +++ b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/nlbuf.h @@ -66,9 +66,12 @@ class nlbuf { return mData; } - std::optional> getFirst() const { - if (!ok()) return std::nullopt; - return *mData; + std::pair getFirst() const { + if (!ok()) { + static const T dummy = {}; + return {false, dummy}; + } + return {true, *mData}; } /** @@ -141,7 +144,7 @@ class nlbuf { size_t len() const { return mBuffer.remainingLength(); } private: - const nlbuf& mBuffer; + const nlbuf mBuffer; }; raw_view getRaw() const { return {*this}; } @@ -160,8 +163,12 @@ class nlbuf { size_t declaredLength() const { // We can't even fit a header, so let's return some absurd high value to trip off // buffer overflow checks. - if (sizeof(T) > remainingLength()) return std::numeric_limits::max() / 2; - return declaredLengthImpl(); + static constexpr size_t badHeaderLength = std::numeric_limits::max() / 2; + + if (sizeof(T) > remainingLength()) return badHeaderLength; + const auto len = declaredLengthImpl(); + if (sizeof(T) > len) return badHeaderLength; + return len; } size_t remainingLength() const { diff --git a/automotive/can/1.0/default/libnetdevice/printer.cpp b/automotive/can/1.0/default/libnetdevice/printer.cpp index 0076dd68cf..f6c9c6072b 100644 --- a/automotive/can/1.0/default/libnetdevice/printer.cpp +++ b/automotive/can/1.0/default/libnetdevice/printer.cpp @@ -85,17 +85,16 @@ static void toStream(std::stringstream& ss, const nlbuf attr, ss << attrtype.name << ": "; switch (attrtype.dataType) { - case DataType::Raw: { + case DataType::Raw: toStream(ss, attr.data()); break; - } case DataType::Nested: { ss << '{'; bool first = true; - for (auto childattr : attr.data()) { + for (const auto childattr : attr.data()) { if (!first) ss << ", "; first = false; - toStream(ss, childattr, attrtype.subTypes); + toStream(ss, childattr, std::get(attrtype.ops)); } ss << '}'; break; @@ -105,9 +104,14 @@ static void toStream(std::stringstream& ss, const nlbuf attr, ss << '"' << sanitize({str.ptr(), str.len()}) << '"'; break; } - case DataType::Uint: { + case DataType::Uint: ss << attr.data().copyFirst(); break; + case DataType::Struct: { + const auto structToStream = + std::get(attrtype.ops); + structToStream(ss, attr); + break; } } } diff --git a/automotive/can/1.0/default/libnetdevice/protocols/MessageDefinition.h b/automotive/can/1.0/default/libnetdevice/protocols/MessageDefinition.h index a25e885660..3a8b2b55d0 100644 --- a/automotive/can/1.0/default/libnetdevice/protocols/MessageDefinition.h +++ b/automotive/can/1.0/default/libnetdevice/protocols/MessageDefinition.h @@ -21,6 +21,7 @@ #include #include +#include namespace android::netdevice::protocols { @@ -57,11 +58,13 @@ struct AttributeDefinition { Nested, String, Uint, + Struct, }; + using ToStream = std::function attr)>; std::string name; DataType dataType = DataType::Raw; - AttributeMap subTypes = {}; + std::variant ops = AttributeMap{}; }; /** @@ -107,13 +110,13 @@ class MessageDefinition : public MessageDescriptor { : MessageDescriptor(name, messageTypes, attrTypes, sizeof(T)) {} void dataToStream(std::stringstream& ss, const nlbuf hdr) const override { - const auto msg = hdr.data().getFirst(); - if (!msg.has_value()) { + const auto& [ok, msg] = hdr.data().getFirst(); + if (!ok) { ss << "{incomplete payload}"; return; } - toStream(ss, *msg); + toStream(ss, msg); } protected: diff --git a/automotive/can/1.0/default/libnetdevice/protocols/generic/Ctrl.cpp b/automotive/can/1.0/default/libnetdevice/protocols/generic/Ctrl.cpp index 08b2be7e65..4120008519 100644 --- a/automotive/can/1.0/default/libnetdevice/protocols/generic/Ctrl.cpp +++ b/automotive/can/1.0/default/libnetdevice/protocols/generic/Ctrl.cpp @@ -37,14 +37,14 @@ Ctrl::Ctrl() : GenericMessageBase(GENL_ID_CTRL, "ID_CTRL", { {CTRL_ATTR_VERSION, {"VERSION", DataType::Uint}}, {CTRL_ATTR_HDRSIZE, {"HDRSIZE", DataType::Uint}}, {CTRL_ATTR_MAXATTR, {"MAXATTR", DataType::Uint}}, - {CTRL_ATTR_OPS, {"OPS", DataType::Nested, { - {std::nullopt, {"OP", DataType::Nested, { + {CTRL_ATTR_OPS, {"OPS", DataType::Nested, AttributeMap{ + {std::nullopt, {"OP", DataType::Nested, AttributeMap{ {CTRL_ATTR_OP_ID, {"ID", DataType::Uint}}, {CTRL_ATTR_OP_FLAGS, {"FLAGS", DataType::Uint}}, }}}, }}}, - {CTRL_ATTR_MCAST_GROUPS, {"MCAST_GROUPS", DataType::Nested, { - {std::nullopt, {"GRP", DataType::Nested, { + {CTRL_ATTR_MCAST_GROUPS, {"MCAST_GROUPS", DataType::Nested, AttributeMap{ + {std::nullopt, {"GRP", DataType::Nested, AttributeMap{ {CTRL_ATTR_MCAST_GRP_NAME, {"NAME", DataType::String}}, {CTRL_ATTR_MCAST_GRP_ID, {"ID", DataType::Uint}}, }}}, diff --git a/automotive/can/1.0/default/libnetdevice/protocols/route/Link.cpp b/automotive/can/1.0/default/libnetdevice/protocols/route/Link.cpp index 4617d92e09..53e1700219 100644 --- a/automotive/can/1.0/default/libnetdevice/protocols/route/Link.cpp +++ b/automotive/can/1.0/default/libnetdevice/protocols/route/Link.cpp @@ -16,6 +16,10 @@ #include "Link.h" +#include "structs.h" + +#include + namespace android::netdevice::protocols::route { using DataType = AttributeDefinition::DataType; @@ -29,62 +33,76 @@ Link::Link() : MessageDefinition("link", { {IFLA_ADDRESS, {"ADDRESS"}}, {IFLA_BROADCAST, {"BROADCAST"}}, {IFLA_IFNAME, {"IFNAME", DataType::String}}, - {IFLA_MTU, {"MTU"}}, + {IFLA_MTU, {"MTU", DataType::Uint}}, {IFLA_LINK, {"LINK", DataType::Uint}}, - {IFLA_QDISC, {"QDISC"}}, - {IFLA_STATS, {"STATS"}}, + {IFLA_QDISC, {"QDISC", DataType::String}}, + {IFLA_STATS, {"STATS", DataType::Struct, statsToStream}}, {IFLA_COST, {"COST"}}, {IFLA_PRIORITY, {"PRIORITY"}}, - {IFLA_MASTER, {"MASTER"}}, + {IFLA_MASTER, {"MASTER", DataType::Uint}}, {IFLA_WIRELESS, {"WIRELESS"}}, {IFLA_PROTINFO, {"PROTINFO"}}, - {IFLA_TXQLEN, {"TXQLEN"}}, - {IFLA_MAP, {"MAP"}}, - {IFLA_WEIGHT, {"WEIGHT"}}, - {IFLA_OPERSTATE, {"OPERSTATE"}}, - {IFLA_LINKMODE, {"LINKMODE"}}, - {IFLA_LINKINFO, {"LINKINFO", DataType::Nested, { + {IFLA_TXQLEN, {"TXQLEN", DataType::Uint}}, + {IFLA_MAP, {"MAP", DataType::Struct, mapToStream}}, + {IFLA_WEIGHT, {"WEIGHT", DataType::Uint}}, + {IFLA_OPERSTATE, {"OPERSTATE", DataType::Uint}}, + {IFLA_LINKMODE, {"LINKMODE", DataType::Uint}}, + {IFLA_LINKINFO, {"LINKINFO", DataType::Nested, AttributeMap{ {IFLA_INFO_KIND, {"INFO_KIND", DataType::String}}, {IFLA_INFO_DATA, {"INFO_DATA", DataType::Nested}}, {IFLA_INFO_XSTATS, {"INFO_XSTATS"}}, - {IFLA_INFO_SLAVE_KIND, {"INFO_SLAVE_KIND"}}, + {IFLA_INFO_SLAVE_KIND, {"INFO_SLAVE_KIND", DataType::String}}, {IFLA_INFO_SLAVE_DATA, {"INFO_SLAVE_DATA"}}, }}}, - {IFLA_NET_NS_PID, {"NET_NS_PID"}}, - {IFLA_IFALIAS, {"IFALIAS"}}, - {IFLA_NUM_VF, {"NUM_VF"}}, + {IFLA_NET_NS_PID, {"NET_NS_PID", DataType::Uint}}, + {IFLA_IFALIAS, {"IFALIAS", DataType::String}}, + {IFLA_NUM_VF, {"NUM_VF", DataType::Uint}}, {IFLA_VFINFO_LIST, {"VFINFO_LIST"}}, - {IFLA_STATS64, {"STATS64"}}, + {IFLA_STATS64, {"STATS64", DataType::Struct, statsToStream}}, {IFLA_VF_PORTS, {"VF_PORTS"}}, {IFLA_PORT_SELF, {"PORT_SELF"}}, - {IFLA_AF_SPEC, {"AF_SPEC"}}, - {IFLA_GROUP, {"GROUP"}}, - {IFLA_NET_NS_FD, {"NET_NS_FD"}}, - {IFLA_EXT_MASK, {"EXT_MASK"}}, - {IFLA_PROMISCUITY, {"PROMISCUITY"}}, - {IFLA_NUM_TX_QUEUES, {"NUM_TX_QUEUES"}}, - {IFLA_NUM_RX_QUEUES, {"NUM_RX_QUEUES"}}, - {IFLA_CARRIER, {"CARRIER"}}, + {IFLA_AF_SPEC, {"AF_SPEC", DataType::Nested, AttributeMap{ + {AF_INET, {"AF_INET", DataType::Nested, AttributeMap{ + {IFLA_INET_CONF, {"INET_CONF", DataType::Struct, arrayToStream}}, + }}}, + {AF_INET6, {"AF_INET6", DataType::Nested, AttributeMap{ + {IFLA_INET6_FLAGS, {"INET6_FLAGS", DataType::Uint}}, + {IFLA_INET6_CONF, {"INET6_CONF", DataType::Struct, arrayToStream}}, + {IFLA_INET6_STATS, {"INET6_STATS", DataType::Struct, arrayToStream}}, + {IFLA_INET6_MCAST, {"INET6_MCAST"}}, + {IFLA_INET6_CACHEINFO, {"INET6_CACHEINFO", DataType::Struct, ifla_cacheinfoToStream}}, + {IFLA_INET6_ICMP6STATS, {"INET6_ICMP6STATS", DataType::Struct, arrayToStream}}, + {IFLA_INET6_TOKEN, {"INET6_TOKEN"}}, + {IFLA_INET6_ADDR_GEN_MODE, {"INET6_ADDR_GEN_MODE", DataType::Uint}}, + }}}, + }}}, + {IFLA_GROUP, {"GROUP", DataType::Uint}}, + {IFLA_NET_NS_FD, {"NET_NS_FD", DataType::Uint}}, + {IFLA_EXT_MASK, {"EXT_MASK", DataType::Uint}}, + {IFLA_PROMISCUITY, {"PROMISCUITY", DataType::Uint}}, + {IFLA_NUM_TX_QUEUES, {"NUM_TX_QUEUES", DataType::Uint}}, + {IFLA_NUM_RX_QUEUES, {"NUM_RX_QUEUES", DataType::Uint}}, + {IFLA_CARRIER, {"CARRIER", DataType::Uint}}, {IFLA_PHYS_PORT_ID, {"PHYS_PORT_ID"}}, - {IFLA_CARRIER_CHANGES, {"CARRIER_CHANGES"}}, + {IFLA_CARRIER_CHANGES, {"CARRIER_CHANGES", DataType::Uint}}, {IFLA_PHYS_SWITCH_ID, {"PHYS_SWITCH_ID"}}, - {IFLA_LINK_NETNSID, {"LINK_NETNSID"}}, - {IFLA_PHYS_PORT_NAME, {"PHYS_PORT_NAME"}}, - {IFLA_PROTO_DOWN, {"PROTO_DOWN"}}, - {IFLA_GSO_MAX_SEGS, {"GSO_MAX_SEGS"}}, - {IFLA_GSO_MAX_SIZE, {"GSO_MAX_SIZE"}}, + {IFLA_LINK_NETNSID, {"LINK_NETNSID"}}, // NLA_S32 + {IFLA_PHYS_PORT_NAME, {"PHYS_PORT_NAME", DataType::String}}, + {IFLA_PROTO_DOWN, {"PROTO_DOWN", DataType::Uint}}, + {IFLA_GSO_MAX_SEGS, {"GSO_MAX_SEGS", DataType::Uint}}, + {IFLA_GSO_MAX_SIZE, {"GSO_MAX_SIZE", DataType::Uint}}, {IFLA_PAD, {"PAD"}}, {IFLA_XDP, {"XDP"}}, - {IFLA_EVENT, {"EVENT"}}, - {IFLA_NEW_NETNSID, {"NEW_NETNSID"}}, - {IFLA_TARGET_NETNSID, {"TARGET_NETNSID"}}, - {IFLA_CARRIER_UP_COUNT, {"CARRIER_UP_COUNT"}}, - {IFLA_CARRIER_DOWN_COUNT, {"CARRIER_DOWN_COUNT"}}, - {IFLA_NEW_IFINDEX, {"NEW_IFINDEX"}}, - {IFLA_MIN_MTU, {"MIN_MTU"}}, - {IFLA_MAX_MTU, {"MAX_MTU"}}, + {IFLA_EVENT, {"EVENT", DataType::Uint}}, + {IFLA_NEW_NETNSID, {"NEW_NETNSID"}}, // NLA_S32 + {IFLA_TARGET_NETNSID, {"TARGET_NETNSID"}}, // NLA_S32 + {IFLA_CARRIER_UP_COUNT, {"CARRIER_UP_COUNT", DataType::Uint}}, + {IFLA_CARRIER_DOWN_COUNT, {"CARRIER_DOWN_COUNT", DataType::Uint}}, + {IFLA_NEW_IFINDEX, {"NEW_IFINDEX"}}, // NLA_S32 + {IFLA_MIN_MTU, {"MIN_MTU", DataType::Uint}}, + {IFLA_MAX_MTU, {"MAX_MTU", DataType::Uint}}, {IFLA_PROP_LIST, {"PROP_LIST"}}, - {IFLA_ALT_IFNAME, {"ALT_IFNAME"}}, + {IFLA_ALT_IFNAME, {"ALT_IFNAME", DataType::String}}, {IFLA_PERM_ADDRESS, {"PERM_ADDRESS"}}, }) {} // clang-format off diff --git a/automotive/can/1.0/default/libnetdevice/protocols/route/structs.cpp b/automotive/can/1.0/default/libnetdevice/protocols/route/structs.cpp new file mode 100644 index 0000000000..48d64f0a4a --- /dev/null +++ b/automotive/can/1.0/default/libnetdevice/protocols/route/structs.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "structs.h" + +namespace android::netdevice::protocols::route { + +void mapToStream(std::stringstream& ss, const nlbuf attr) { + const auto& [ok, data] = attr.data().getFirst(); + if (!ok) { + ss << "invalid structure"; + return; + } + ss << '{' // + << data.mem_start << ',' // + << data.mem_end << ',' // + << data.base_addr << ',' // + << data.irq << ',' // + << unsigned(data.dma) << ',' // + << unsigned(data.port) << '}'; +} + +void ifla_cacheinfoToStream(std::stringstream& ss, const nlbuf attr) { + const auto& [ok, data] = attr.data().getFirst(); + if (!ok) { + ss << "invalid structure"; + return; + } + ss << '{' // + << data.max_reasm_len << ',' // + << data.tstamp << ',' // + << data.reachable_time << ',' // + << data.retrans_time << '}'; +} + +} // namespace android::netdevice::protocols::route diff --git a/automotive/can/1.0/default/libnetdevice/protocols/route/structs.h b/automotive/can/1.0/default/libnetdevice/protocols/route/structs.h new file mode 100644 index 0000000000..e53270439c --- /dev/null +++ b/automotive/can/1.0/default/libnetdevice/protocols/route/structs.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +#include + +#include + +namespace android::netdevice::protocols::route { + +// rtnl_link_ifmap +void mapToStream(std::stringstream& ss, const nlbuf attr); + +// ifla_cacheinfo +void ifla_cacheinfoToStream(std::stringstream& ss, const nlbuf attr); + +template +void arrayToStream(std::stringstream& ss, const nlbuf attr) { + ss << '{'; + for (const auto it : attr.data().getRaw()) { + ss << it << ','; + } + ss.seekp(-1, std::ios_base::cur); + ss << '}'; +} + +// rtnl_link_stats or rtnl_link_stats64 +template +void statsToStream(std::stringstream& ss, const nlbuf attr) { + const auto& [ok, data] = attr.data().getFirst(); + if (!ok) { + ss << "invalid structure"; + return; + } + ss << '{' // + << data.rx_packets << ',' // + << data.tx_packets << ',' // + << data.rx_bytes << ',' // + << data.tx_bytes << ',' // + << data.rx_errors << ',' // + << data.tx_errors << ',' // + << data.rx_dropped << ',' // + << data.tx_dropped << ',' // + << data.multicast << ',' // + << data.collisions << ',' // + << data.rx_length_errors << ',' // + << data.rx_over_errors << ',' // + << data.rx_crc_errors << ',' // + << data.rx_frame_errors << ',' // + << data.rx_fifo_errors << ',' // + << data.rx_missed_errors << ',' // + << data.tx_aborted_errors << ',' // + << data.tx_carrier_errors << ',' // + << data.tx_fifo_errors << ',' // + << data.tx_heartbeat_errors << ',' // + << data.tx_window_errors << ',' // + << data.rx_compressed << ',' // + << data.tx_compressed << ',' // + << data.rx_nohandler << '}'; +} + +} // namespace android::netdevice::protocols::route -- GitLab From 45c1263a661868c26e8dec74d4ee871e34ec27ac Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Thu, 16 Jul 2020 14:06:25 -0700 Subject: [PATCH 078/790] Fix Tuner 1.0 default implementation Demux and Frontend mapping The previous impl keeps the demux and frontend mapping in the Tuner implementation even the instance has been closed. Clean up the mapping and the local vectors in the Tuner impl when Demux or Frontend is closed. Test: atest VtsHalTvTunerV1_0TargetTest Bug: 150952766 Change-Id: I2038e902ba7ab323c6dacc886ac6984ee7c475aa --- tv/tuner/1.0/default/Demux.cpp | 7 +++++++ tv/tuner/1.0/default/Frontend.cpp | 1 + tv/tuner/1.0/default/Tuner.cpp | 17 +++++++++++++++-- tv/tuner/1.0/default/Tuner.h | 10 ++++++---- 4 files changed, 29 insertions(+), 6 deletions(-) diff --git a/tv/tuner/1.0/default/Demux.cpp b/tv/tuner/1.0/default/Demux.cpp index b122a05017..9055a43bd8 100644 --- a/tv/tuner/1.0/default/Demux.cpp +++ b/tv/tuner/1.0/default/Demux.cpp @@ -163,6 +163,7 @@ Return Demux::close() { mRecordFilterIds.clear(); mFilters.clear(); mLastUsedFilterId = -1; + mTunerService->removeDemux(mDemuxId); return Result::SUCCESS; } @@ -318,6 +319,12 @@ void Demux::frontendInputThreadLoop() { std::lock_guard lock(mFrontendInputThreadLock); mFrontendInputThreadRunning = true; + if (!mDvrPlayback) { + ALOGW("[Demux] No software Frontend input configured. Ending Frontend thread loop."); + mFrontendInputThreadRunning = false; + return; + } + while (mFrontendInputThreadRunning) { uint32_t efState = 0; status_t status = mDvrPlayback->getDvrEventFlag()->wait( diff --git a/tv/tuner/1.0/default/Frontend.cpp b/tv/tuner/1.0/default/Frontend.cpp index 8bf0ec5353..6561c92caf 100644 --- a/tv/tuner/1.0/default/Frontend.cpp +++ b/tv/tuner/1.0/default/Frontend.cpp @@ -42,6 +42,7 @@ Return Frontend::close() { // Reset callback mCallback = nullptr; mIsLocked = false; + mTunerService->removeFrontend(mId); return Result::SUCCESS; } diff --git a/tv/tuner/1.0/default/Tuner.cpp b/tv/tuner/1.0/default/Tuner.cpp index 48ce384e7b..9a6ecf704f 100644 --- a/tv/tuner/1.0/default/Tuner.cpp +++ b/tv/tuner/1.0/default/Tuner.cpp @@ -37,7 +37,6 @@ Tuner::Tuner() { // Static Frontends array to maintain local frontends information // Array index matches their FrontendId in the default impl mFrontendSize = 8; - mFrontends.resize(mFrontendSize); mFrontends[0] = new Frontend(FrontendType::DVBT, 0, this); mFrontends[1] = new Frontend(FrontendType::ATSC, 1, this); mFrontends[2] = new Frontend(FrontendType::DVBC, 2, this); @@ -48,7 +47,6 @@ Tuner::Tuner() { mFrontends[7] = new Frontend(FrontendType::ATSC, 7, this); FrontendInfo::FrontendCapabilities caps; - mFrontendCaps.resize(mFrontendSize); caps = FrontendInfo::FrontendCapabilities(); caps.dvbtCaps(FrontendDvbtCapabilities()); mFrontendCaps[0] = caps; @@ -236,6 +234,21 @@ void Tuner::setFrontendAsDemuxSource(uint32_t frontendId, uint32_t demuxId) { } } +void Tuner::removeDemux(uint32_t demuxId) { + map::iterator it; + for (it = mFrontendToDemux.begin(); it != mFrontendToDemux.end(); it++) { + if (it->second == demuxId) { + it = mFrontendToDemux.erase(it); + break; + } + } + mDemuxes.erase(demuxId); +} + +void Tuner::removeFrontend(uint32_t frontendId) { + mFrontendToDemux.erase(frontendId); +} + void Tuner::frontendStopTune(uint32_t frontendId) { map::iterator it = mFrontendToDemux.find(frontendId); uint32_t demuxId; diff --git a/tv/tuner/1.0/default/Tuner.h b/tv/tuner/1.0/default/Tuner.h index 5de568f072..1c09d6c684 100644 --- a/tv/tuner/1.0/default/Tuner.h +++ b/tv/tuner/1.0/default/Tuner.h @@ -65,14 +65,16 @@ class Tuner : public ITuner { void frontendStartTune(uint32_t frontendId); void frontendStopTune(uint32_t frontendId); + void removeDemux(uint32_t demuxId); + void removeFrontend(uint32_t frontendId); private: virtual ~Tuner(); // Static mFrontends array to maintain local frontends information - vector> mFrontends; - vector mFrontendCaps; - std::map mFrontendToDemux; - std::map> mDemuxes; + map> mFrontends; + map mFrontendCaps; + map mFrontendToDemux; + map> mDemuxes; // To maintain how many Frontends we have int mFrontendSize; // The last used demux id. Initial value is -1. -- GitLab From afdd8d4a834571298f2e9f511d4c61c5da326ffa Mon Sep 17 00:00:00 2001 From: chrisweir Date: Wed, 22 Jul 2020 16:47:18 -0700 Subject: [PATCH 079/790] Fix netlink message printer byte counts Don't print extra byte numbering for arrays with a size that is a multiple of 16. Bug: 161938586 Test: Manual inspection of printer output Change-Id: I4a7948439dd18b440a6abfae388306167433ebd6 --- automotive/can/1.0/default/libnetdevice/printer.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/automotive/can/1.0/default/libnetdevice/printer.cpp b/automotive/can/1.0/default/libnetdevice/printer.cpp index 0076dd68cf..00dc992245 100644 --- a/automotive/can/1.0/default/libnetdevice/printer.cpp +++ b/automotive/can/1.0/default/libnetdevice/printer.cpp @@ -65,14 +65,13 @@ static void toStream(std::stringstream& ss, const nlbuf data) { const auto rawData = data.getRaw(); const auto dataLen = rawData.len(); ss << std::hex; - if (dataLen > 16) ss << std::endl << " 0000 "; int i = 0; for (const auto byte : rawData) { - if (i++ > 0) ss << ' '; - ss << std::setw(2) << unsigned(byte); - if (i % 16 == 0) { + if (i % 16 == 0 && dataLen > 16) { ss << std::endl << ' ' << std::dec << std::setw(4) << i << std::hex; } + if (i++ > 0 || dataLen > 16) ss << ' '; + ss << std::setw(2) << unsigned(byte); } ss << std::dec; if (dataLen > 16) ss << std::endl; -- GitLab From 0a0fe51a6aa50a4ade84ad26207fef45ed2c9c3e Mon Sep 17 00:00:00 2001 From: xshu Date: Wed, 22 Jul 2020 17:53:37 -0700 Subject: [PATCH 080/790] Ringbuffer stops logging after wifi toggle Forces ringbuffer updates before writing zipped files to bugreport. Also properly resets the ringbuffer callback when it's deregistered. Bug: 161307741 Test: make vts -j64 && vts-tradefed run commandAndExit vts --module VtsHalWifiV1_0Target Test: manual verification with triggering a bugreport Test: manual verification with wifi toggles Change-Id: I74deffda917054e20cfcf4f0dd90d778626c89d3 --- wifi/1.5/default/wifi_chip.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/wifi/1.5/default/wifi_chip.cpp b/wifi/1.5/default/wifi_chip.cpp index 9883fc2277..069fd65054 100644 --- a/wifi/1.5/default/wifi_chip.cpp +++ b/wifi/1.5/default/wifi_chip.cpp @@ -626,6 +626,15 @@ Return WifiChip::getCapabilities_1_3(getCapabilities_cb hidl_status_cb) { Return WifiChip::debug(const hidl_handle& handle, const hidl_vec&) { if (handle != nullptr && handle->numFds >= 1) { + { + std::unique_lock lk(lock_t); + for (const auto& item : ringbuffer_map_) { + forceDumpToDebugRingBufferInternal(item.first); + } + // unique_lock unlocked here + } + usleep(100 * 1000); // sleep for 100 milliseconds to wait for + // ringbuffer updates. int fd = handle->data[0]; if (!writeRingbufferFilesInternal()) { LOG(ERROR) << "Error writing files to flash"; @@ -1127,6 +1136,9 @@ WifiStatus WifiChip::stopLoggingToDebugRingBufferInternal() { legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->deregisterRingBufferCallbackHandler( getFirstActiveWlanIfaceName()); + if (legacy_status == legacy_hal::WIFI_SUCCESS) { + debug_ring_buffer_cb_registered_ = false; + } return createWifiStatusFromLegacyError(legacy_status); } @@ -1342,7 +1354,7 @@ WifiStatus WifiChip::registerDebugRingBufferCallback() { LOG(ERROR) << "Ringname " << name << " not found"; return; } - // unlock + // unique_lock unlocked here } }; legacy_hal::wifi_error legacy_status = @@ -1644,7 +1656,7 @@ bool WifiChip::writeRingbufferFilesInternal() { } } } - // unlock + // unique_lock unlocked here } return true; } -- GitLab From 68afca6d7caea032486d55b9feb58a811742a4c7 Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Mon, 20 Jul 2020 18:28:58 -0700 Subject: [PATCH 081/790] Add the PTS field for recording-time indexing in the DemuxFilterEvent Test: atest VtsHalTvTunerV1_1TargetTest Bug: 158816517 Change-Id: Ib29fd0f55aaae2fb44b77f754cceb5152fc7158d --- tv/tuner/1.0/vts/functional/FilterTests.cpp | 7 +- tv/tuner/1.0/vts/functional/FilterTests.h | 2 + tv/tuner/1.1/Android.bp | 4 +- tv/tuner/1.1/IDemux.hal | 4 +- tv/tuner/1.1/IFilterCallback.hal | 29 ++ tv/tuner/1.1/default/Android.bp | 8 +- tv/tuner/1.1/default/Demux.cpp | 12 + tv/tuner/1.1/default/Demux.h | 1 + tv/tuner/1.1/default/Dvr.cpp | 15 +- tv/tuner/1.1/default/Filter.cpp | 71 +++- tv/tuner/1.1/default/Filter.h | 9 +- tv/tuner/1.1/default/Tuner.cpp | 5 +- ...roid.hardware.tv.tuner@1.1-service-lazy.rc | 1 + tv/tuner/1.1/types.hal | 87 +++++ tv/tuner/1.1/vts/functional/Android.bp | 5 +- tv/tuner/1.1/vts/functional/DvrTests.cpp | 348 ++++++++++++++++++ tv/tuner/1.1/vts/functional/DvrTests.h | 195 ++++++++++ tv/tuner/1.1/vts/functional/FilterTests.cpp | 19 + tv/tuner/1.1/vts/functional/FilterTests.h | 39 +- tv/tuner/1.1/vts/functional/FrontendTests.cpp | 68 +++- tv/tuner/1.1/vts/functional/FrontendTests.h | 42 ++- .../VtsHalTvTunerV1_1TargetTest.cpp | 54 +++ .../functional/VtsHalTvTunerV1_1TargetTest.h | 30 +- .../VtsHalTvTunerV1_1TestConfigurations.h | 47 ++- 24 files changed, 1057 insertions(+), 45 deletions(-) create mode 100644 tv/tuner/1.1/IFilterCallback.hal create mode 100644 tv/tuner/1.1/types.hal create mode 100644 tv/tuner/1.1/vts/functional/DvrTests.cpp create mode 100644 tv/tuner/1.1/vts/functional/DvrTests.h diff --git a/tv/tuner/1.0/vts/functional/FilterTests.cpp b/tv/tuner/1.0/vts/functional/FilterTests.cpp index 0ecdf73130..5f5d108fd3 100644 --- a/tv/tuner/1.0/vts/functional/FilterTests.cpp +++ b/tv/tuner/1.0/vts/functional/FilterTests.cpp @@ -85,7 +85,7 @@ bool FilterCallback::readFilterEventData() { case FilterEventType::MEDIA: return dumpAvData(filterEvent.events[i].media()); case FilterEventType::RECORD: - break; + return readRecordData(filterEvent.events[i].tsRecord()); case FilterEventType::MMTPRECORD: break; case FilterEventType::DOWNLOAD: @@ -128,6 +128,11 @@ bool FilterCallback::dumpAvData(DemuxFilterMediaEvent event) { return true; } +bool FilterCallback::readRecordData(DemuxFilterTsRecordEvent event) { + ALOGD("[vts] got DemuxFilterTsRecordEvent with pid=%d.", event.pid.tPid()); + return true; +} + AssertionResult FilterTests::openFilterInDemux(DemuxFilterType type, uint32_t bufferSize) { Result status; EXPECT_TRUE(mDemux) << "Test with openDemux first."; diff --git a/tv/tuner/1.0/vts/functional/FilterTests.h b/tv/tuner/1.0/vts/functional/FilterTests.h index a76a6b9e2a..8ac9c555c1 100644 --- a/tv/tuner/1.0/vts/functional/FilterTests.h +++ b/tv/tuner/1.0/vts/functional/FilterTests.h @@ -50,6 +50,7 @@ using android::hardware::tv::tuner::V1_0::DemuxFilterSectionEvent; using android::hardware::tv::tuner::V1_0::DemuxFilterSectionSettings; using android::hardware::tv::tuner::V1_0::DemuxFilterSettings; using android::hardware::tv::tuner::V1_0::DemuxFilterStatus; +using android::hardware::tv::tuner::V1_0::DemuxFilterTsRecordEvent; using android::hardware::tv::tuner::V1_0::DemuxFilterType; using android::hardware::tv::tuner::V1_0::DemuxQueueNotifyBits; using android::hardware::tv::tuner::V1_0::DemuxTsFilterSettings; @@ -115,6 +116,7 @@ class FilterCallback : public IFilterCallback { void updateGoldenOutputMap(string goldenOutputFile); bool readFilterEventData(); bool dumpAvData(DemuxFilterMediaEvent event); + bool readRecordData(DemuxFilterTsRecordEvent event); private: struct FilterThreadArgs { diff --git a/tv/tuner/1.1/Android.bp b/tv/tuner/1.1/Android.bp index 476915e9b0..2019050df2 100644 --- a/tv/tuner/1.1/Android.bp +++ b/tv/tuner/1.1/Android.bp @@ -4,9 +4,11 @@ hidl_interface { name: "android.hardware.tv.tuner@1.1", root: "android.hardware", srcs: [ + "IDemux.hal", "IFilter.hal", + "IFilterCallback.hal", "ITuner.hal", - "IDemux.hal", + "types.hal", ], interfaces: [ "android.hidl.base@1.0", diff --git a/tv/tuner/1.1/IDemux.hal b/tv/tuner/1.1/IDemux.hal index 81cd001313..434ecbd461 100644 --- a/tv/tuner/1.1/IDemux.hal +++ b/tv/tuner/1.1/IDemux.hal @@ -17,8 +17,8 @@ package android.hardware.tv.tuner@1.1; import @1.0::IDemux; -import @1.0::Result; import @1.0::IFilter; +import @1.0::Result; /** * Demultiplexer(Demux) takes a single multiplexed input and splits it into @@ -30,7 +30,7 @@ interface IDemux extends @1.0::IDemux { * * It is used by the client to get the hardware sync ID for audio and video. * - * @param filter the filter instance. + * @param filter the v1_1 filter instance. * @return result Result status of the operation. * SUCCESS if successful, * INVALID_ARGUMENT if failed for a wrong filter ID. diff --git a/tv/tuner/1.1/IFilterCallback.hal b/tv/tuner/1.1/IFilterCallback.hal new file mode 100644 index 0000000000..a80273b462 --- /dev/null +++ b/tv/tuner/1.1/IFilterCallback.hal @@ -0,0 +1,29 @@ +/* + * 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. + */ + +package android.hardware.tv.tuner@1.1; + +import @1.0::IFilterCallback; +import @1.1::DemuxFilterEvent; + +interface IFilterCallback extends @1.0::IFilterCallback { + /** + * Notify the client that a new filter event happened. + * + * @param filterEvent a v1_1 filter event. + */ + oneway onFilterEvent_1_1(DemuxFilterEvent filterEvent); +}; diff --git a/tv/tuner/1.1/default/Android.bp b/tv/tuner/1.1/default/Android.bp index 7e45864791..4401f7cd2c 100644 --- a/tv/tuner/1.1/default/Android.bp +++ b/tv/tuner/1.1/default/Android.bp @@ -4,14 +4,14 @@ cc_defaults { vendor: true, relative_install_path: "hw", srcs: [ - "Filter.cpp", - "Frontend.cpp", - "Descrambler.cpp", "Demux.cpp", + "Descrambler.cpp", "Dvr.cpp", + "Filter.cpp", + "Frontend.cpp", + "Lnb.cpp", "TimeFilter.cpp", "Tuner.cpp", - "Lnb.cpp", "service.cpp", ], diff --git a/tv/tuner/1.1/default/Demux.cpp b/tv/tuner/1.1/default/Demux.cpp index f501d74e67..007d5eb623 100644 --- a/tv/tuner/1.1/default/Demux.cpp +++ b/tv/tuner/1.1/default/Demux.cpp @@ -312,6 +312,16 @@ void Demux::sendFrontendInputToRecord(vector data) { } } +void Demux::sendFrontendInputToRecord(vector data, uint16_t pid, uint64_t pts) { + sendFrontendInputToRecord(data); + set::iterator it; + for (it = mRecordFilterIds.begin(); it != mRecordFilterIds.end(); it++) { + if (pid == mFilters[*it]->getTpid()) { + mFilters[*it]->updatePts(pts); + } + } +} + bool Demux::startBroadcastFilterDispatcher() { set::iterator it; @@ -389,9 +399,11 @@ void Demux::frontendInputThreadLoop() { ALOGE("[Demux] playback es data failed to be filtered. Ending thread"); break; } + continue; } // Our current implementation filter the data and write it into the filter FMQ immediately // after the DATA_READY from the VTS/framework + // This is for the non-ES data source, real playback use case handling. if (!mDvrPlayback->readPlaybackFMQ(true /*isVirtualFrontend*/, mIsRecording) || !mDvrPlayback->startFilterDispatcher(true /*isVirtualFrontend*/, mIsRecording)) { ALOGE("[Demux] playback data failed to be filtered. Ending thread"); diff --git a/tv/tuner/1.1/default/Demux.h b/tv/tuner/1.1/default/Demux.h index f38f006aae..3623d0fe10 100644 --- a/tv/tuner/1.1/default/Demux.h +++ b/tv/tuner/1.1/default/Demux.h @@ -100,6 +100,7 @@ class Demux : public V1_1::IDemux { void startBroadcastTsFilter(vector data); void sendFrontendInputToRecord(vector data); + void sendFrontendInputToRecord(vector data, uint16_t pid, uint64_t pts); bool startRecordFilterDispatcher(); private: diff --git a/tv/tuner/1.1/default/Dvr.cpp b/tv/tuner/1.1/default/Dvr.cpp index 02d6a42e58..bf4c77e785 100644 --- a/tv/tuner/1.1/default/Dvr.cpp +++ b/tv/tuner/1.1/default/Dvr.cpp @@ -217,9 +217,11 @@ void Dvr::playbackThreadLoop() { break; } maySendPlaybackStatusCallback(); + continue; } // Our current implementation filter the data and write it into the filter FMQ immediately // after the DATA_READY from the VTS/framework + // This is for the non-ES data source, real playback use case handling. if (!readPlaybackFMQ(false /*isVirtualFrontend*/, false /*isRecording*/) || !startFilterDispatcher(false /*isVirtualFrontend*/, false /*isRecording*/)) { ALOGE("[Dvr] playback data failed to be filtered. Ending thread"); @@ -380,20 +382,19 @@ bool Dvr::processEsDataOnPlayback(bool isVirtualFrontend, bool isRecording) { for (int i = 0; i < totalFrames; i++) { frameData.resize(esMeta[i].len); pid = esMeta[i].isAudio ? audioPid : videoPid; - memcpy(dataOutputBuffer.data() + esMeta[i].startIndex, frameData.data(), esMeta[i].len); - // Send to the media filter - if (isVirtualFrontend && isRecording) { - // TODO validate record - mDemux->sendFrontendInputToRecord(frameData); - } else { + memcpy(frameData.data(), dataOutputBuffer.data() + esMeta[i].startIndex, esMeta[i].len); + // Send to the media filters or record filters + if (!isRecording) { for (it = mFilters.begin(); it != mFilters.end(); it++) { if (pid == mDemux->getFilterTpid(it->first)) { mDemux->updateMediaFilterOutput(it->first, frameData, static_cast(esMeta[i].pts)); - startFilterDispatcher(isVirtualFrontend, isRecording); } } + } else { + mDemux->sendFrontendInputToRecord(frameData, pid, static_cast(esMeta[i].pts)); } + startFilterDispatcher(isVirtualFrontend, isRecording); } return true; diff --git a/tv/tuner/1.1/default/Filter.cpp b/tv/tuner/1.1/default/Filter.cpp index 108baf74f3..2d6214d52c 100644 --- a/tv/tuner/1.1/default/Filter.cpp +++ b/tv/tuner/1.1/default/Filter.cpp @@ -35,7 +35,6 @@ Filter::Filter(DemuxFilterType type, uint64_t filterId, uint32_t bufferSize, mType = type; mFilterId = filterId; mBufferSize = bufferSize; - mCallback = cb; mDemux = demux; switch (mType.mainType) { @@ -69,6 +68,13 @@ Filter::Filter(DemuxFilterType type, uint64_t filterId, uint32_t bufferSize, default: break; } + + sp filterCallback_v1_1 = V1_1::IFilterCallback::castFrom(cb); + if (filterCallback_v1_1 != NULL) { + mCallback_1_1 = filterCallback_v1_1; + } else { + mCallback = cb; + } } Filter::~Filter() {} @@ -99,7 +105,7 @@ Return Filter::setDataSource(const sp& filter) { Return Filter::getQueueDesc(getQueueDesc_cb _hidl_cb) { ALOGV("%s", __FUNCTION__); - mIsUsingFMQ = true; + mIsUsingFMQ = mIsRecordFilter ? false : true; _hidl_cb(Result::SUCCESS, *mFilterMQ->getDesc()); return Void(); @@ -214,7 +220,7 @@ void Filter::filterThreadLoop() { // For the first time of filter output, implementation needs to send the filter // Event Callback without waiting for the DATA_CONSUMED to init the process. while (mFilterThreadRunning) { - if (mFilterEvent.events.size() == 0) { + if (mFilterEvent.events.size() == 0 && mFilterEvent_1_1.events.size() == 0) { if (DEBUG_FILTER) { ALOGD("[Filter] wait for filter data output."); } @@ -222,15 +228,26 @@ void Filter::filterThreadLoop() { continue; } // After successfully write, send a callback and wait for the read to be done - mCallback->onFilterEvent(mFilterEvent); + if (mFilterEvent_1_1.events.size() > 0) { + if (mCallback_1_1 == nullptr) { + ALOGE("[Filter] IFilterCallback_1_1 has not been configured yet. Can't send event"); + mFilterThreadRunning = false; + break; + } + mCallback_1_1->onFilterEvent_1_1(mFilterEvent_1_1); + mFilterEvent_1_1.events.resize(0); + } else { + mCallback->onFilterEvent(mFilterEvent); + mFilterEvent.events.resize(0); + } + freeAvHandle(); - mFilterEvent.events.resize(0); mFilterStatus = DemuxFilterStatus::DATA_READY; - if (mCallback == nullptr) { - ALOGD("[Filter] filter %" PRIu64 " does not hava callback. Ending thread", mFilterId); - break; + if (mCallback != nullptr) { + mCallback->onFilterStatus(mFilterStatus); + } else if (mCallback_1_1 != nullptr) { + mCallback_1_1->onFilterStatus(mFilterStatus); } - mCallback->onFilterStatus(mFilterStatus); break; } @@ -258,8 +275,13 @@ void Filter::filterThreadLoop() { continue; } // After successfully write, send a callback and wait for the read to be done - mCallback->onFilterEvent(mFilterEvent); - mFilterEvent.events.resize(0); + if (mCallback != nullptr) { + mCallback->onFilterEvent(mFilterEvent); + mFilterEvent.events.resize(0); + } else if (mCallback_1_1 != nullptr) { + mCallback_1_1->onFilterEvent_1_1(mFilterEvent_1_1); + mFilterEvent_1_1.events.resize(0); + } break; } // We do not wait for the last read to be done @@ -297,7 +319,11 @@ void Filter::maySendFilterStatusCallback() { DemuxFilterStatus newStatus = checkFilterStatusChange( availableToWrite, availableToRead, ceil(fmqSize * 0.75), ceil(fmqSize * 0.25)); if (mFilterStatus != newStatus) { - mCallback->onFilterStatus(newStatus); + if (mCallback != nullptr) { + mCallback->onFilterStatus(newStatus); + } else if (mCallback_1_1 != nullptr) { + mCallback_1_1->onFilterStatus(newStatus); + } mFilterStatus = newStatus; } } @@ -577,6 +603,27 @@ Result Filter::startRecordFilterHandler() { return Result::UNKNOWN_ERROR; } + V1_0::DemuxFilterTsRecordEvent recordEvent; + recordEvent = { + .byteNumber = mRecordFilterOutput.size(), + }; + V1_1::DemuxFilterTsRecordEvent recordEvent_1_1; + recordEvent_1_1 = { + .tsRecordEvent_1_0 = recordEvent, + .pts = (mPts == 0) ? time(NULL) * 900000 : mPts, + }; + + int size; + if (mCallback_1_1 != nullptr) { + size = mFilterEvent_1_1.events.size(); + mFilterEvent_1_1.events.resize(size + 1); + mFilterEvent_1_1.events[size].tsRecord(recordEvent_1_1); + } else if (mCallback != nullptr) { + size = mFilterEvent.events.size(); + mFilterEvent.events.resize(size + 1); + mFilterEvent.events[size].tsRecord(recordEvent); + } + mRecordFilterOutput.clear(); return Result::SUCCESS; } diff --git a/tv/tuner/1.1/default/Filter.h b/tv/tuner/1.1/default/Filter.h index d5801d4f74..8e6fe388cc 100644 --- a/tv/tuner/1.1/default/Filter.h +++ b/tv/tuner/1.1/default/Filter.h @@ -18,6 +18,7 @@ #define ANDROID_HARDWARE_TV_TUNER_V1_1_FILTER_H_ #include +#include #include #include #include @@ -102,7 +103,12 @@ class Filter : public V1_1::IFilter { /** * Filter callbacks used on filter events or FMQ status */ - sp mCallback; + sp mCallback = nullptr; + + /** + * V1_1 Filter callbacks used on filter events or FMQ status + */ + sp mCallback_1_1 = nullptr; uint64_t mFilterId; uint32_t mBufferSize; @@ -122,6 +128,7 @@ class Filter : public V1_1::IFilter { bool mIsUsingFMQ = false; EventFlag* mFilterEventFlag; DemuxFilterEvent mFilterEvent; + V1_1::DemuxFilterEvent mFilterEvent_1_1; // Thread handlers pthread_t mFilterThread; diff --git a/tv/tuner/1.1/default/Tuner.cpp b/tv/tuner/1.1/default/Tuner.cpp index 0a0667e87d..87a4d36735 100644 --- a/tv/tuner/1.1/default/Tuner.cpp +++ b/tv/tuner/1.1/default/Tuner.cpp @@ -233,11 +233,10 @@ void Tuner::setFrontendAsDemuxSource(uint32_t frontendId, uint32_t demuxId) { void Tuner::removeDemux(uint32_t demuxId) { map::iterator it; - for (it = mFrontendToDemux.begin(); it != mFrontendToDemux.end();) { + for (it = mFrontendToDemux.begin(); it != mFrontendToDemux.end(); it++) { if (it->second == demuxId) { it = mFrontendToDemux.erase(it); - } else { - it++; + break; } } mDemuxes.erase(demuxId); diff --git a/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service-lazy.rc b/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service-lazy.rc index 9e228f7d58..abff430d3c 100644 --- a/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service-lazy.rc +++ b/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service-lazy.rc @@ -1,4 +1,5 @@ service vendor.tuner-hal-1-1 /vendor/bin/hw/android.hardware.tv.tuner@1.1-service-lazy + interface android.hardware.tv.tuner@1.0::ITuner default interface android.hardware.tv.tuner@1.1::ITuner default oneshot disabled diff --git a/tv/tuner/1.1/types.hal b/tv/tuner/1.1/types.hal new file mode 100644 index 0000000000..21c7021461 --- /dev/null +++ b/tv/tuner/1.1/types.hal @@ -0,0 +1,87 @@ +/* + * 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. + */ + +package android.hardware.tv.tuner@1.1; + +import @1.0::DemuxFilterDownloadEvent; +import @1.0::DemuxFilterIpPayloadEvent; +import @1.0::DemuxFilterMediaEvent; +import @1.0::DemuxFilterMmtpRecordEvent; +import @1.0::DemuxFilterPesEvent; +import @1.0::DemuxFilterSectionEvent; +import @1.0::DemuxFilterTemiEvent; +import @1.0::DemuxFilterTsRecordEvent; +import android.hidl.safe_union@1.0; + +/** + * Filter Event for TS Record data. + */ +struct DemuxFilterTsRecordEvent { + /** + * V1_0 Filter Event for TS Record data. + */ + @1.0::DemuxFilterTsRecordEvent tsRecordEvent_1_0; + + /** + * The Presentation Time Stamp(PTS) for the audio or video frame. It is based on 90KHz + * and has the same format as the PTS in ISO/IEC 13818-1. It is used only for the SC and + * the SC_HEVC. + */ + uint64_t pts; +}; + +/** + * Filter Event for MMTP Record data. + */ +struct DemuxFilterMmtpRecordEvent { + /** + * V1_0 Filter Event for MMTP Record data. + */ + @1.0::DemuxFilterMmtpRecordEvent mmtpRecordEvent_1_0; + + /** + * MPU sequence number of the filtered data. This is only used for MMTP. + */ + uint32_t mpuSequenceNumber; +}; + +/** + * Filter Event. + */ +struct DemuxFilterEvent { + safe_union Event { + DemuxFilterSectionEvent section; + + DemuxFilterMediaEvent media; + + DemuxFilterPesEvent pes; + + @1.1::DemuxFilterTsRecordEvent tsRecord; + + @1.1::DemuxFilterMmtpRecordEvent mmtpRecord; + + DemuxFilterDownloadEvent download; + + DemuxFilterIpPayloadEvent ipPayload; + + DemuxFilterTemiEvent temi; + }; + + /** + * An array of events + */ + vec events; +}; diff --git a/tv/tuner/1.1/vts/functional/Android.bp b/tv/tuner/1.1/vts/functional/Android.bp index 7ab0f87119..1fc36f10e5 100644 --- a/tv/tuner/1.1/vts/functional/Android.bp +++ b/tv/tuner/1.1/vts/functional/Android.bp @@ -18,10 +18,11 @@ cc_test { name: "VtsHalTvTunerV1_1TargetTest", defaults: ["VtsHalTargetTestDefaults"], srcs: [ - "VtsHalTvTunerV1_1TargetTest.cpp", - "FrontendTests.cpp", "DemuxTests.cpp", + "DvrTests.cpp", "FilterTests.cpp", + "FrontendTests.cpp", + "VtsHalTvTunerV1_1TargetTest.cpp", ], static_libs: [ "android.hardware.cas@1.0", diff --git a/tv/tuner/1.1/vts/functional/DvrTests.cpp b/tv/tuner/1.1/vts/functional/DvrTests.cpp new file mode 100644 index 0000000000..0dfc032d19 --- /dev/null +++ b/tv/tuner/1.1/vts/functional/DvrTests.cpp @@ -0,0 +1,348 @@ +/* + * 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 "DvrTests.h" + +void DvrCallback::startPlaybackInputThread(string& dataInputFile, PlaybackSettings& settings, + MQDesc& playbackMQDescriptor) { + mInputDataFile = dataInputFile; + mPlaybackSettings = settings; + mPlaybackMQ = std::make_unique(playbackMQDescriptor, true /* resetPointers */); + EXPECT_TRUE(mPlaybackMQ); + pthread_create(&mPlaybackThread, NULL, __threadLoopPlayback, this); + pthread_setname_np(mPlaybackThread, "test_playback_input_loop"); +} + +void DvrCallback::stopPlaybackThread() { + mPlaybackThreadRunning = false; + mKeepWritingPlaybackFMQ = false; + + android::Mutex::Autolock autoLock(mPlaybackThreadLock); +} + +void* DvrCallback::__threadLoopPlayback(void* user) { + DvrCallback* const self = static_cast(user); + self->playbackThreadLoop(); + return 0; +} + +void DvrCallback::playbackThreadLoop() { + android::Mutex::Autolock autoLock(mPlaybackThreadLock); + mPlaybackThreadRunning = true; + + // Create the EventFlag that is used to signal the HAL impl that data have been + // written into the Playback FMQ + EventFlag* playbackMQEventFlag; + EXPECT_TRUE(EventFlag::createEventFlag(mPlaybackMQ->getEventFlagWord(), &playbackMQEventFlag) == + android::OK); + + int fd = open(mInputDataFile.c_str(), O_RDONLY | O_LARGEFILE); + int readBytes; + uint32_t regionSize = 0; + uint8_t* buffer; + ALOGW("[vts] playback thread loop start %s", mInputDataFile.c_str()); + if (fd < 0) { + mPlaybackThreadRunning = false; + ALOGW("[vts] Error %s", strerror(errno)); + } + + while (mPlaybackThreadRunning) { + while (mKeepWritingPlaybackFMQ) { + int totalWrite = mPlaybackMQ->availableToWrite(); + if (totalWrite * 4 < mPlaybackMQ->getQuantumCount()) { + // Wait for the HAL implementation to read more data then write. + continue; + } + MessageQueue::MemTransaction memTx; + if (!mPlaybackMQ->beginWrite(totalWrite, &memTx)) { + ALOGW("[vts] Fail to write into Playback fmq."); + mPlaybackThreadRunning = false; + break; + } + auto first = memTx.getFirstRegion(); + buffer = first.getAddress(); + regionSize = first.getLength(); + + if (regionSize > 0) { + readBytes = read(fd, buffer, regionSize); + if (readBytes <= 0) { + if (readBytes < 0) { + ALOGW("[vts] Read from %s failed.", mInputDataFile.c_str()); + } else { + ALOGW("[vts] playback input EOF."); + } + mPlaybackThreadRunning = false; + break; + } + } + if (regionSize == 0 || (readBytes == regionSize && regionSize < totalWrite)) { + auto second = memTx.getSecondRegion(); + buffer = second.getAddress(); + regionSize = second.getLength(); + int ret = read(fd, buffer, regionSize); + if (ret <= 0) { + if (ret < 0) { + ALOGW("[vts] Read from %s failed.", mInputDataFile.c_str()); + } else { + ALOGW("[vts] playback input EOF."); + } + mPlaybackThreadRunning = false; + break; + } + readBytes += ret; + } + if (!mPlaybackMQ->commitWrite(readBytes)) { + ALOGW("[vts] Failed to commit write playback fmq."); + mPlaybackThreadRunning = false; + break; + } + playbackMQEventFlag->wake(static_cast(DemuxQueueNotifyBits::DATA_READY)); + } + } + + mPlaybackThreadRunning = false; + ALOGW("[vts] Playback thread end."); + close(fd); +} + +void DvrCallback::testRecordOutput() { + android::Mutex::Autolock autoLock(mMsgLock); + while (mDataOutputBuffer.empty()) { + if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) { + EXPECT_TRUE(false) << "record output matching pid does not output within timeout"; + stopRecordThread(); + return; + } + } + stopRecordThread(); + ALOGW("[vts] record pass and stop"); +} + +void DvrCallback::startRecordOutputThread(RecordSettings recordSettings, + MQDesc& recordMQDescriptor) { + mRecordMQ = std::make_unique(recordMQDescriptor, true /* resetPointers */); + EXPECT_TRUE(mRecordMQ); + struct RecordThreadArgs* threadArgs = + (struct RecordThreadArgs*)malloc(sizeof(struct RecordThreadArgs)); + threadArgs->user = this; + threadArgs->recordSettings = &recordSettings; + threadArgs->keepReadingRecordFMQ = &mKeepReadingRecordFMQ; + + pthread_create(&mRecordThread, NULL, __threadLoopRecord, (void*)threadArgs); + pthread_setname_np(mRecordThread, "test_record_input_loop"); +} + +void* DvrCallback::__threadLoopRecord(void* threadArgs) { + DvrCallback* const self = + static_cast(((struct RecordThreadArgs*)threadArgs)->user); + self->recordThreadLoop(((struct RecordThreadArgs*)threadArgs)->recordSettings, + ((struct RecordThreadArgs*)threadArgs)->keepReadingRecordFMQ); + return 0; +} + +void DvrCallback::recordThreadLoop(RecordSettings* /*recordSettings*/, bool* keepReadingRecordFMQ) { + ALOGD("[vts] DvrCallback record threadLoop start."); + android::Mutex::Autolock autoLock(mRecordThreadLock); + mRecordThreadRunning = true; + mKeepReadingRecordFMQ = true; + + // Create the EventFlag that is used to signal the HAL impl that data have been + // read from the Record FMQ + EventFlag* recordMQEventFlag; + EXPECT_TRUE(EventFlag::createEventFlag(mRecordMQ->getEventFlagWord(), &recordMQEventFlag) == + android::OK); + + while (mRecordThreadRunning) { + while (*keepReadingRecordFMQ) { + uint32_t efState = 0; + android::status_t status = recordMQEventFlag->wait( + static_cast(DemuxQueueNotifyBits::DATA_READY), &efState, WAIT_TIMEOUT, + true /* retry on spurious wake */); + if (status != android::OK) { + ALOGD("[vts] wait for data ready on the record FMQ"); + continue; + } + // Our current implementation filter the data and write it into the filter FMQ + // immediately after the DATA_READY from the VTS/framework + if (!readRecordFMQ()) { + ALOGD("[vts] record data failed to be filtered. Ending thread"); + mRecordThreadRunning = false; + break; + } + } + } + + mRecordThreadRunning = false; + ALOGD("[vts] record thread ended."); +} + +bool DvrCallback::readRecordFMQ() { + android::Mutex::Autolock autoLock(mMsgLock); + bool result = false; + mDataOutputBuffer.clear(); + mDataOutputBuffer.resize(mRecordMQ->availableToRead()); + result = mRecordMQ->read(mDataOutputBuffer.data(), mRecordMQ->availableToRead()); + EXPECT_TRUE(result) << "can't read from Record MQ"; + mMsgCondition.signal(); + return result; +} + +void DvrCallback::stopRecordThread() { + mKeepReadingRecordFMQ = false; + mRecordThreadRunning = false; +} + +AssertionResult DvrTests::openDvrInDemux(DvrType type, uint32_t bufferSize) { + Result status; + EXPECT_TRUE(mDemux) << "Test with openDemux first."; + + // Create dvr callback + if (type == DvrType::PLAYBACK) { + mDvrPlaybackCallback = new DvrCallback(); + mDemux->openDvr(type, bufferSize, mDvrPlaybackCallback, + [&](Result result, const sp& dvr) { + mDvrPlayback = dvr; + status = result; + }); + if (status == Result::SUCCESS) { + mDvrPlaybackCallback->setDvr(mDvrPlayback); + } + } + + if (type == DvrType::RECORD) { + mDvrRecordCallback = new DvrCallback(); + mDemux->openDvr(type, bufferSize, mDvrRecordCallback, + [&](Result result, const sp& dvr) { + mDvrRecord = dvr; + status = result; + }); + if (status == Result::SUCCESS) { + mDvrRecordCallback->setDvr(mDvrRecord); + } + } + + return AssertionResult(status == Result::SUCCESS); +} + +AssertionResult DvrTests::configDvrPlayback(DvrSettings setting) { + Result status = mDvrPlayback->configure(setting); + + return AssertionResult(status == Result::SUCCESS); +} + +AssertionResult DvrTests::configDvrRecord(DvrSettings setting) { + Result status = mDvrRecord->configure(setting); + + return AssertionResult(status == Result::SUCCESS); +} + +AssertionResult DvrTests::getDvrPlaybackMQDescriptor() { + Result status; + EXPECT_TRUE(mDemux) << "Test with openDemux first."; + EXPECT_TRUE(mDvrPlayback) << "Test with openDvr first."; + + mDvrPlayback->getQueueDesc([&](Result result, const MQDesc& dvrMQDesc) { + mDvrPlaybackMQDescriptor = dvrMQDesc; + status = result; + }); + + return AssertionResult(status == Result::SUCCESS); +} + +AssertionResult DvrTests::getDvrRecordMQDescriptor() { + Result status; + EXPECT_TRUE(mDemux) << "Test with openDemux first."; + EXPECT_TRUE(mDvrRecord) << "Test with openDvr first."; + + mDvrRecord->getQueueDesc([&](Result result, const MQDesc& dvrMQDesc) { + mDvrRecordMQDescriptor = dvrMQDesc; + status = result; + }); + + return AssertionResult(status == Result::SUCCESS); +} + +AssertionResult DvrTests::attachFilterToDvr(sp filter) { + Result status; + EXPECT_TRUE(mDemux) << "Test with openDemux first."; + EXPECT_TRUE(mDvrRecord) << "Test with openDvr first."; + + status = mDvrRecord->attachFilter(filter); + + return AssertionResult(status == Result::SUCCESS); +} + +AssertionResult DvrTests::detachFilterToDvr(sp filter) { + Result status; + EXPECT_TRUE(mDemux) << "Test with openDemux first."; + EXPECT_TRUE(mDvrRecord) << "Test with openDvr first."; + + status = mDvrRecord->detachFilter(filter); + + return AssertionResult(status == Result::SUCCESS); +} + +AssertionResult DvrTests::startDvrPlayback() { + Result status; + EXPECT_TRUE(mDemux) << "Test with openDemux first."; + EXPECT_TRUE(mDvrPlayback) << "Test with openDvr first."; + + status = mDvrPlayback->start(); + + return AssertionResult(status == Result::SUCCESS); +} + +AssertionResult DvrTests::stopDvrPlayback() { + Result status; + EXPECT_TRUE(mDemux) << "Test with openDemux first."; + EXPECT_TRUE(mDvrPlayback) << "Test with openDvr first."; + + status = mDvrPlayback->stop(); + + return AssertionResult(status == Result::SUCCESS); +} + +void DvrTests::closeDvrPlayback() { + ASSERT_TRUE(mDemux); + ASSERT_TRUE(mDvrPlayback); + ASSERT_TRUE(mDvrPlayback->close() == Result::SUCCESS); +} + +AssertionResult DvrTests::startDvrRecord() { + Result status; + EXPECT_TRUE(mDemux) << "Test with openDemux first."; + EXPECT_TRUE(mDvrRecord) << "Test with openDvr first."; + + status = mDvrRecord->start(); + + return AssertionResult(status == Result::SUCCESS); +} + +AssertionResult DvrTests::stopDvrRecord() { + Result status; + EXPECT_TRUE(mDemux) << "Test with openDemux first."; + EXPECT_TRUE(mDvrRecord) << "Test with openDvr first."; + + status = mDvrRecord->stop(); + + return AssertionResult(status == Result::SUCCESS); +} + +void DvrTests::closeDvrRecord() { + ASSERT_TRUE(mDemux); + ASSERT_TRUE(mDvrRecord); + ASSERT_TRUE(mDvrRecord->close() == Result::SUCCESS); +} diff --git a/tv/tuner/1.1/vts/functional/DvrTests.h b/tv/tuner/1.1/vts/functional/DvrTests.h new file mode 100644 index 0000000000..289ddf6d7d --- /dev/null +++ b/tv/tuner/1.1/vts/functional/DvrTests.h @@ -0,0 +1,195 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "FilterTests.h" + +using android::Condition; +using android::Mutex; +using android::sp; +using android::hardware::EventFlag; +using android::hardware::kSynchronizedReadWrite; +using android::hardware::MessageQueue; +using android::hardware::MQDescriptorSync; +using android::hardware::Return; +using android::hardware::Void; +using android::hardware::tv::tuner::V1_0::DemuxFilterStatus; +using android::hardware::tv::tuner::V1_0::DemuxQueueNotifyBits; +using android::hardware::tv::tuner::V1_0::DvrSettings; +using android::hardware::tv::tuner::V1_0::DvrType; +using android::hardware::tv::tuner::V1_0::IDvr; +using android::hardware::tv::tuner::V1_0::IDvrCallback; +using android::hardware::tv::tuner::V1_0::PlaybackSettings; +using android::hardware::tv::tuner::V1_0::PlaybackStatus; +using android::hardware::tv::tuner::V1_0::RecordSettings; +using android::hardware::tv::tuner::V1_0::RecordStatus; +using android::hardware::tv::tuner::V1_0::Result; +using android::hardware::tv::tuner::V1_1::ITuner; + +using namespace std; + +#define WAIT_TIMEOUT 3000000000 + +class DvrCallback : public IDvrCallback { + public: + virtual Return onRecordStatus(DemuxFilterStatus status) override { + ALOGD("[vts] record status %hhu", status); + switch (status) { + case DemuxFilterStatus::DATA_READY: + break; + case DemuxFilterStatus::LOW_WATER: + break; + case DemuxFilterStatus::HIGH_WATER: + case DemuxFilterStatus::OVERFLOW: + ALOGD("[vts] record overflow. Flushing."); + EXPECT_TRUE(mDvr) << "Dvr callback is not set with an IDvr"; + if (mDvr) { + Result result = mDvr->flush(); + ALOGD("[vts] Flushing result %d.", result); + } + break; + } + return Void(); + } + + virtual Return onPlaybackStatus(PlaybackStatus status) override { + // android::Mutex::Autolock autoLock(mMsgLock); + ALOGD("[vts] playback status %d", status); + switch (status) { + case PlaybackStatus::SPACE_EMPTY: + case PlaybackStatus::SPACE_ALMOST_EMPTY: + ALOGD("[vts] keep playback inputing %d", status); + mKeepWritingPlaybackFMQ = true; + break; + case PlaybackStatus::SPACE_ALMOST_FULL: + case PlaybackStatus::SPACE_FULL: + ALOGD("[vts] stop playback inputing %d", status); + mKeepWritingPlaybackFMQ = false; + break; + } + return Void(); + } + + void stopPlaybackThread(); + void testRecordOutput(); + void stopRecordThread(); + + void startPlaybackInputThread(string& dataInputFile, PlaybackSettings& settings, + MQDesc& playbackMQDescriptor); + void startRecordOutputThread(RecordSettings recordSettings, MQDesc& recordMQDescriptor); + static void* __threadLoopPlayback(void* user); + static void* __threadLoopRecord(void* threadArgs); + void playbackThreadLoop(); + void recordThreadLoop(RecordSettings* recordSetting, bool* keepWritingPlaybackFMQ); + + bool readRecordFMQ(); + + void setDvr(sp dvr) { mDvr = dvr; } + + private: + struct RecordThreadArgs { + DvrCallback* user; + RecordSettings* recordSettings; + bool* keepReadingRecordFMQ; + }; + // uint16_t mDataLength = 0; + std::vector mDataOutputBuffer; + + std::map> mFilterMQ; + std::unique_ptr mPlaybackMQ; + std::unique_ptr mRecordMQ; + std::map mFilterMQEventFlag; + + android::Mutex mMsgLock; + android::Mutex mPlaybackThreadLock; + android::Mutex mRecordThreadLock; + android::Condition mMsgCondition; + + bool mKeepWritingPlaybackFMQ = true; + bool mKeepReadingRecordFMQ = true; + bool mPlaybackThreadRunning; + bool mRecordThreadRunning; + pthread_t mPlaybackThread; + pthread_t mRecordThread; + string mInputDataFile; + PlaybackSettings mPlaybackSettings; + + sp mDvr = nullptr; + + // int mPidFilterOutputCount = 0; +}; + +class DvrTests { + public: + void setService(sp tuner) { mService = tuner; } + void setDemux(sp demux) { mDemux = demux; } + + void startPlaybackInputThread(string& dataInputFile, PlaybackSettings& settings) { + mDvrPlaybackCallback->startPlaybackInputThread(dataInputFile, settings, + mDvrPlaybackMQDescriptor); + }; + + void startRecordOutputThread(RecordSettings settings) { + mDvrRecordCallback->startRecordOutputThread(settings, mDvrRecordMQDescriptor); + }; + + void stopPlaybackThread() { mDvrPlaybackCallback->stopPlaybackThread(); } + void testRecordOutput() { mDvrRecordCallback->testRecordOutput(); } + void stopRecordThread() { mDvrRecordCallback->stopRecordThread(); } + + AssertionResult openDvrInDemux(DvrType type, uint32_t bufferSize); + AssertionResult configDvrPlayback(DvrSettings setting); + AssertionResult configDvrRecord(DvrSettings setting); + AssertionResult getDvrPlaybackMQDescriptor(); + AssertionResult getDvrRecordMQDescriptor(); + AssertionResult attachFilterToDvr(sp filter); + AssertionResult detachFilterToDvr(sp filter); + AssertionResult stopDvrPlayback(); + AssertionResult startDvrPlayback(); + AssertionResult stopDvrRecord(); + AssertionResult startDvrRecord(); + void closeDvrPlayback(); + void closeDvrRecord(); + + protected: + static AssertionResult failure() { return ::testing::AssertionFailure(); } + + static AssertionResult success() { return ::testing::AssertionSuccess(); } + + sp mService; + sp mDvrPlayback; + sp mDvrRecord; + sp mDemux; + sp mDvrPlaybackCallback; + sp mDvrRecordCallback; + MQDesc mDvrPlaybackMQDescriptor; + MQDesc mDvrRecordMQDescriptor; +}; diff --git a/tv/tuner/1.1/vts/functional/FilterTests.cpp b/tv/tuner/1.1/vts/functional/FilterTests.cpp index fb0c1a5cc8..9cbec869c4 100644 --- a/tv/tuner/1.1/vts/functional/FilterTests.cpp +++ b/tv/tuner/1.1/vts/functional/FilterTests.cpp @@ -16,6 +16,23 @@ #include "FilterTests.h" +bool FilterCallback::readFilterEventData() { + bool result = false; + ALOGW("[vts] reading from filter FMQ or buffer %d", mFilterId); + // todo separate filter handlers + for (int i = 0; i < mFilterEvent.events.size(); i++) { + switch (mFilterEventType) { + case FilterEventType::RECORD: + ALOGW("[vts] Record filter event, pts=%" PRIu64 ".", + mFilterEvent.events[0].tsRecord().pts); + break; + default: + break; + } + } + return result; +} + AssertionResult FilterTests::openFilterInDemux(DemuxFilterType type, uint32_t bufferSize) { Result status; EXPECT_TRUE(mDemux) << "Test with openDemux first."; @@ -52,6 +69,8 @@ AssertionResult FilterTests::getNewlyOpenedFilterId_64bit(uint64_t& filterId) { } if (status == Result::SUCCESS) { + mFilterCallback->setFilterId(mFilterId); + mFilterCallback->setFilterInterface(mFilter); mUsedFilterIds.insert(mUsedFilterIds.end(), mFilterId); mFilters[mFilterId] = mFilter; mFilterCallbacks[mFilterId] = mFilterCallback; diff --git a/tv/tuner/1.1/vts/functional/FilterTests.h b/tv/tuner/1.1/vts/functional/FilterTests.h index b1b6e13759..8156f140cf 100644 --- a/tv/tuner/1.1/vts/functional/FilterTests.h +++ b/tv/tuner/1.1/vts/functional/FilterTests.h @@ -17,10 +17,11 @@ #include #include #include -#include #include #include +#include #include +#include #include #include #include @@ -43,7 +44,6 @@ using android::hardware::MessageQueue; using android::hardware::MQDescriptorSync; using android::hardware::Return; using android::hardware::Void; -using android::hardware::tv::tuner::V1_0::DemuxFilterEvent; using android::hardware::tv::tuner::V1_0::DemuxFilterMainType; using android::hardware::tv::tuner::V1_0::DemuxFilterSettings; using android::hardware::tv::tuner::V1_0::DemuxFilterStatus; @@ -51,8 +51,9 @@ using android::hardware::tv::tuner::V1_0::DemuxFilterType; using android::hardware::tv::tuner::V1_0::DemuxTsFilterType; using android::hardware::tv::tuner::V1_0::IDemux; using android::hardware::tv::tuner::V1_0::IFilter; -using android::hardware::tv::tuner::V1_0::IFilterCallback; using android::hardware::tv::tuner::V1_0::Result; +using android::hardware::tv::tuner::V1_1::DemuxFilterEvent; +using android::hardware::tv::tuner::V1_1::IFilterCallback; using android::hardware::tv::tuner::V1_1::ITuner; using ::testing::AssertionResult; @@ -77,13 +78,43 @@ using MQDesc = MQDescriptorSync; class FilterCallback : public IFilterCallback { public: - virtual Return onFilterEvent(const DemuxFilterEvent& /*filterEvent*/) override { + virtual Return onFilterEvent_1_1(const DemuxFilterEvent& filterEvent) override { + android::Mutex::Autolock autoLock(mMsgLock); + // Temprarily we treat the first coming back filter data on the matching pid a success + // once all of the MQ are cleared, means we got all the expected output + mFilterEvent = filterEvent; + readFilterEventData(); + mPidFilterOutputCount++; + mMsgCondition.signal(); + return Void(); + } + + virtual Return onFilterEvent( + const android::hardware::tv::tuner::V1_0::DemuxFilterEvent& /*filterEvent*/) override { return Void(); } virtual Return onFilterStatus(const DemuxFilterStatus /*status*/) override { return Void(); } + + void setFilterId(uint32_t filterId) { mFilterId = filterId; } + void setFilterInterface(sp filter) { mFilter = filter; } + void setFilterEventType(FilterEventType type) { mFilterEventType = type; } + + bool readFilterEventData(); + + private: + uint32_t mFilterId; + sp mFilter; + FilterEventType mFilterEventType; + DemuxFilterEvent mFilterEvent; + + android::Mutex mMsgLock; + android::Mutex mFilterOutputLock; + android::Condition mMsgCondition; + + int mPidFilterOutputCount = 0; }; class FilterTests { diff --git a/tv/tuner/1.1/vts/functional/FrontendTests.cpp b/tv/tuner/1.1/vts/functional/FrontendTests.cpp index 8c359c51a6..da46adbee7 100644 --- a/tv/tuner/1.1/vts/functional/FrontendTests.cpp +++ b/tv/tuner/1.1/vts/functional/FrontendTests.cpp @@ -16,8 +16,20 @@ #include "FrontendTests.h" -Return FrontendCallback::onEvent(FrontendEventType /*frontendEventType*/) { - return Void(); +Return FrontendCallback::onEvent(FrontendEventType frontendEventType) { + android::Mutex::Autolock autoLock(mMsgLock); + ALOGD("[vts] frontend event received. Type: %d", frontendEventType); + mEventReceived = true; + mMsgCondition.signal(); + switch (frontendEventType) { + case FrontendEventType::LOCKED: + mLockMsgReceived = true; + mLockMsgCondition.signal(); + return Void(); + default: + // do nothing + return Void(); + } } Return FrontendCallback::onScanMessage(FrontendScanMessageType /*type*/, @@ -25,6 +37,21 @@ Return FrontendCallback::onScanMessage(FrontendScanMessageType /*type*/, return Void(); } +void FrontendCallback::tuneTestOnLock(sp& frontend, FrontendSettings settings) { + Result result = frontend->tune(settings); + EXPECT_TRUE(result == Result::SUCCESS); + + android::Mutex::Autolock autoLock(mMsgLock); + while (!mLockMsgReceived) { + if (-ETIMEDOUT == mLockMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) { + EXPECT_TRUE(false) << "Event LOCKED not received within timeout"; + mLockMsgReceived = false; + return; + } + } + mLockMsgReceived = false; +} + AssertionResult FrontendTests::getFrontendIds() { Result status; mService->getFrontendIds([&](Result result, const hidl_vec& frontendIds) { @@ -59,6 +86,41 @@ AssertionResult FrontendTests::setFrontendCallback() { return AssertionResult(callbackStatus.isOk()); } +AssertionResult FrontendTests::tuneFrontend(FrontendConfig config, bool testWithDemux) { + EXPECT_TRUE(mFrontendCallback) + << "test with openFrontendById/setFrontendCallback/getFrontendInfo first."; + + EXPECT_TRUE(mFrontendInfo.type == config.type) + << "FrontendConfig does not match the frontend info of the given id."; + + mIsSoftwareFe = config.isSoftwareFe; + bool result = true; + if (mIsSoftwareFe && testWithDemux) { + result &= mDvrTests.openDvrInDemux(mDvrConfig.type, mDvrConfig.bufferSize) == success(); + result &= mDvrTests.configDvrPlayback(mDvrConfig.settings) == success(); + result &= mDvrTests.getDvrPlaybackMQDescriptor() == success(); + mDvrTests.startPlaybackInputThread(mDvrConfig.playbackInputFile, + mDvrConfig.settings.playback()); + if (!result) { + ALOGW("[vts] Software frontend dvr configure failed."); + return failure(); + } + } + mFrontendCallback->tuneTestOnLock(mFrontend, config.settings); + return AssertionResult(true); +} + +AssertionResult FrontendTests::stopTuneFrontend(bool testWithDemux) { + EXPECT_TRUE(mFrontend) << "Test with openFrontendById first."; + Result status; + status = mFrontend->stopTune(); + if (mIsSoftwareFe && testWithDemux) { + mDvrTests.stopPlaybackThread(); + mDvrTests.closeDvrPlayback(); + } + return AssertionResult(status == Result::SUCCESS); +} + AssertionResult FrontendTests::closeFrontend() { EXPECT_TRUE(mFrontend) << "Test with openFrontendById first."; Result status; @@ -80,4 +142,4 @@ void FrontendTests::getFrontendIdByType(FrontendType feType, uint32_t& feId) { return; } feId = INVALID_ID; -} \ No newline at end of file +} diff --git a/tv/tuner/1.1/vts/functional/FrontendTests.h b/tv/tuner/1.1/vts/functional/FrontendTests.h index e68758919d..492f2f00c5 100644 --- a/tv/tuner/1.1/vts/functional/FrontendTests.h +++ b/tv/tuner/1.1/vts/functional/FrontendTests.h @@ -31,6 +31,7 @@ #include #include +#include "DvrTests.h" #include "VtsHalTvTunerV1_1TestConfigurations.h" #define WAIT_TIMEOUT 3000000000 @@ -61,36 +62,73 @@ using ::testing::AssertionResult; using namespace std; #define INVALID_ID -1 +#define WAIT_TIMEOUT 3000000000 class FrontendCallback : public IFrontendCallback { public: virtual Return onEvent(FrontendEventType frontendEventType) override; virtual Return onScanMessage(FrontendScanMessageType type, const FrontendScanMessage& message) override; + + void tuneTestOnLock(sp& frontend, FrontendSettings settings); + + private: + bool mEventReceived = false; + bool mLockMsgReceived = false; + hidl_vec mEventMessage; + android::Mutex mMsgLock; + android::Condition mMsgCondition; + android::Condition mLockMsgCondition; }; class FrontendTests { public: sp mService; - void setService(sp tuner) { mService = tuner; } + void setService(sp tuner) { + mService = tuner; + mDvrTests.setService(tuner); + getDefaultSoftwareFrontendPlaybackConfig(mDvrConfig); + } AssertionResult getFrontendIds(); AssertionResult getFrontendInfo(uint32_t frontendId); AssertionResult openFrontendById(uint32_t frontendId); AssertionResult setFrontendCallback(); + AssertionResult tuneFrontend(FrontendConfig config, bool testWithDemux); + AssertionResult stopTuneFrontend(bool testWithDemux); AssertionResult closeFrontend(); void getFrontendIdByType(FrontendType feType, uint32_t& feId); + void setDvrTests(DvrTests dvrTests) { mDvrTests = dvrTests; } + void setDemux(sp demux) { mDvrTests.setDemux(demux); } + void setSoftwareFrontendDvrConfig(DvrConfig conf) { mDvrConfig = conf; } + protected: static AssertionResult failure() { return ::testing::AssertionFailure(); } static AssertionResult success() { return ::testing::AssertionSuccess(); } + void getDefaultSoftwareFrontendPlaybackConfig(DvrConfig& dvrConfig) { + PlaybackSettings playbackSettings{ + .statusMask = 0xf, + .lowThreshold = 0x1000, + .highThreshold = 0x07fff, + .dataFormat = DataFormat::ES, + .packetSize = 188, + }; + dvrConfig.type = DvrType::PLAYBACK; + dvrConfig.playbackInputFile = "/data/local/tmp/test.es"; + dvrConfig.bufferSize = FMQ_SIZE_4M; + dvrConfig.settings.playback(playbackSettings); + } + sp mFrontend; FrontendInfo mFrontendInfo; sp mFrontendCallback; hidl_vec mFeIds; + DvrTests mDvrTests; bool mIsSoftwareFe = false; -}; \ No newline at end of file + DvrConfig mDvrConfig; +}; diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp index c74e29c002..c9873b2c90 100644 --- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp @@ -43,6 +43,49 @@ void TunerFilterHidlTest::configSingleFilterInDemuxTest(FilterConfig filterConf, ASSERT_TRUE(mFrontendTests.closeFrontend()); } +void TunerRecordHidlTest::recordSingleFilterTest(FilterConfig filterConf, + FrontendConfig frontendConf, DvrConfig dvrConf) { + uint32_t feId; + uint32_t demuxId; + sp demux; + uint64_t filterId; + sp filter; + + mFrontendTests.getFrontendIdByType(frontendConf.type, feId); + ASSERT_TRUE(feId != INVALID_ID); + ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); + ASSERT_TRUE(mFrontendTests.setFrontendCallback()); + ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); + ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); + mFilterTests.setDemux(demux); + mDvrTests.setDemux(demux); + mFrontendTests.setDvrTests(mDvrTests); + ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrConf.type, dvrConf.bufferSize)); + ASSERT_TRUE(mDvrTests.configDvrRecord(dvrConf.settings)); + ASSERT_TRUE(mDvrTests.getDvrRecordMQDescriptor()); + ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize)); + ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(filterId)); + ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId)); + ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId)); + filter = mFilterTests.getFilterById(filterId); + ASSERT_TRUE(filter != nullptr); + mDvrTests.startRecordOutputThread(dvrConf.settings.record()); + ASSERT_TRUE(mDvrTests.attachFilterToDvr(filter)); + ASSERT_TRUE(mDvrTests.startDvrRecord()); + ASSERT_TRUE(mFilterTests.startFilter(filterId)); + ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/)); + mDvrTests.testRecordOutput(); + mDvrTests.stopRecordThread(); + ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/)); + ASSERT_TRUE(mFilterTests.stopFilter(filterId)); + ASSERT_TRUE(mDvrTests.stopDvrRecord()); + ASSERT_TRUE(mDvrTests.detachFilterToDvr(filter)); + ASSERT_TRUE(mFilterTests.closeFilter(filterId)); + mDvrTests.closeDvrRecord(); + ASSERT_TRUE(mDemuxTests.closeDemux()); + ASSERT_TRUE(mFrontendTests.closeFrontend()); +} + TEST_P(TunerDemuxHidlTest, getAvSyncTime) { description("Get the A/V sync time from a PCR filter."); uint32_t feId; @@ -84,6 +127,11 @@ TEST_P(TunerFilterHidlTest, StartFilterInDemux) { configSingleFilterInDemuxTest(filterArray[TS_VIDEO0], frontendArray[DVBT]); } +TEST_P(TunerRecordHidlTest, RecordDataFlowWithTsRecordFilterTest) { + description("Feed ts data from frontend to recording and test with ts record filter"); + recordSingleFilterTest(filterArray[TS_RECORD0], frontendArray[DVBT], dvrArray[DVR_RECORD0]); +} + INSTANTIATE_TEST_SUITE_P( PerInstance, TunerFilterHidlTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames(ITuner::descriptor)), @@ -94,6 +142,12 @@ INSTANTIATE_TEST_SUITE_P( testing::ValuesIn(android::hardware::getAllHalInstanceNames(ITuner::descriptor)), android::hardware::PrintInstanceNameToString); +INSTANTIATE_TEST_SUITE_P( + PerInstance, TunerRecordHidlTest, + testing::ValuesIn(android::hardware::getAllHalInstanceNames(ITuner::descriptor)), + android::hardware::PrintInstanceNameToString); + GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerFilterHidlTest); GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerDemuxHidlTest); +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerRecordHidlTest); } // namespace diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h index 30533b1310..1b28853a4b 100644 --- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h @@ -15,7 +15,6 @@ */ #include "DemuxTests.h" -#include "FilterTests.h" #include "FrontendTests.h" namespace { @@ -23,6 +22,7 @@ namespace { void initConfiguration() { initFrontendConfig(); initFilterConfig(); + initDvrConfig(); } class TunerFilterHidlTest : public testing::TestWithParam { @@ -72,4 +72,32 @@ class TunerDemuxHidlTest : public testing::TestWithParam { DemuxTests mDemuxTests; FilterTests mFilterTests; }; + +class TunerRecordHidlTest : public testing::TestWithParam { + public: + virtual void SetUp() override { + mService = ITuner::getService(GetParam()); + ASSERT_NE(mService, nullptr); + initConfiguration(); + + mFrontendTests.setService(mService); + mDemuxTests.setService(mService); + mFilterTests.setService(mService); + mDvrTests.setService(mService); + } + + protected: + static void description(const std::string& description) { + RecordProperty("description", description); + } + + void recordSingleFilterTest(FilterConfig filterConf, FrontendConfig frontendConf, + DvrConfig dvrConf); + + sp mService; + FrontendTests mFrontendTests; + DemuxTests mDemuxTests; + FilterTests mFilterTests; + DvrTests mDvrTests; +}; } // namespace \ No newline at end of file diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h index 23c9353d03..39872d2524 100644 --- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h @@ -21,8 +21,8 @@ #include #include +using android::hardware::tv::tuner::V1_0::DataFormat; using android::hardware::tv::tuner::V1_0::DemuxAlpFilterType; -using android::hardware::tv::tuner::V1_0::DemuxFilterEvent; using android::hardware::tv::tuner::V1_0::DemuxFilterMainType; using android::hardware::tv::tuner::V1_0::DemuxFilterSettings; using android::hardware::tv::tuner::V1_0::DemuxFilterType; @@ -30,6 +30,8 @@ using android::hardware::tv::tuner::V1_0::DemuxIpFilterType; using android::hardware::tv::tuner::V1_0::DemuxMmtpFilterType; using android::hardware::tv::tuner::V1_0::DemuxRecordScIndexType; using android::hardware::tv::tuner::V1_0::DemuxTsFilterType; +using android::hardware::tv::tuner::V1_0::DvrSettings; +using android::hardware::tv::tuner::V1_0::DvrType; using android::hardware::tv::tuner::V1_0::FrontendDvbtBandwidth; using android::hardware::tv::tuner::V1_0::FrontendDvbtCoderate; using android::hardware::tv::tuner::V1_0::FrontendDvbtConstellation; @@ -42,6 +44,8 @@ using android::hardware::tv::tuner::V1_0::FrontendSettings; using android::hardware::tv::tuner::V1_0::FrontendStatus; using android::hardware::tv::tuner::V1_0::FrontendStatusType; using android::hardware::tv::tuner::V1_0::FrontendType; +using android::hardware::tv::tuner::V1_0::PlaybackSettings; +using android::hardware::tv::tuner::V1_0::RecordSettings; using namespace std; @@ -68,6 +72,12 @@ typedef enum { FRONTEND_MAX, } Frontend; +typedef enum { + DVR_RECORD0, + DVR_PLAYBACK0, + DVR_MAX, +} Dvr; + struct FilterConfig { uint32_t bufferSize; DemuxFilterType type; @@ -84,8 +94,16 @@ struct FrontendConfig { vector expectTuneStatuses; }; +struct DvrConfig { + DvrType type; + uint32_t bufferSize; + DvrSettings settings; + string playbackInputFile; +}; + static FrontendConfig frontendArray[FILTER_MAX]; static FilterConfig filterArray[FILTER_MAX]; +static DvrConfig dvrArray[DVR_MAX]; /** Configuration array for the frontend tune test */ inline void initFrontendConfig() { @@ -171,8 +189,33 @@ inline void initFilterConfig() { // TS RECORD filter setting filterArray[TS_RECORD0].type.mainType = DemuxFilterMainType::TS; filterArray[TS_RECORD0].type.subType.tsFilterType(DemuxTsFilterType::RECORD); - filterArray[TS_RECORD0].settings.ts().tpid = 81; + filterArray[TS_RECORD0].settings.ts().tpid = 256; filterArray[TS_RECORD0].settings.ts().filterSettings.record({ .scIndexType = DemuxRecordScIndexType::NONE, }); }; + +/** Configuration array for the dvr test */ +inline void initDvrConfig() { + RecordSettings recordSettings{ + .statusMask = 0xf, + .lowThreshold = 0x1000, + .highThreshold = 0x07fff, + .dataFormat = DataFormat::TS, + .packetSize = 188, + }; + dvrArray[DVR_RECORD0].type = DvrType::RECORD; + dvrArray[DVR_RECORD0].bufferSize = FMQ_SIZE_4M; + dvrArray[DVR_RECORD0].settings.record(recordSettings); + PlaybackSettings playbackSettings{ + .statusMask = 0xf, + .lowThreshold = 0x1000, + .highThreshold = 0x07fff, + .dataFormat = DataFormat::TS, + .packetSize = 188, + }; + dvrArray[DVR_PLAYBACK0].type = DvrType::PLAYBACK; + dvrArray[DVR_PLAYBACK0].playbackInputFile = "/data/local/tmp/segment000000.ts"; + dvrArray[DVR_PLAYBACK0].bufferSize = FMQ_SIZE_4M; + dvrArray[DVR_PLAYBACK0].settings.playback(playbackSettings); +}; -- GitLab From cf79f5eb2e44a7ba11f3cce2d94bfc716a493ea5 Mon Sep 17 00:00:00 2001 From: Manisha Jajoo Date: Wed, 15 Jul 2020 19:11:26 +0530 Subject: [PATCH 082/790] OMX VTS: Use GraphicBuffer utils from libui Use GraphicBufferMapper and GraphicBufferAllocator for gralloc buffers. This makes the tests independent of gralloc version Bug: 160355727 Test: atest VtsHalMediaOmxV1_0TargetMasterTest \ VtsHalMediaOmxV1_0TargetComponentTest \ VtsHalMediaOmxV1_0TargetAudioEncTest \ VtsHalMediaOmxV1_0TargetAudioDecTest \ VtsHalMediaOmxV1_0TargetVideoDecTest \ VtsHalMediaOmxV1_0TargetVideoEncTest Change-Id: If407ac3d8c0fadc55a8e57627121244a8d5155f8 Merged-In: If407ac3d8c0fadc55a8e57627121244a8d5155f8 --- .../omx/1.0/vts/functional/common/Android.bp | 18 +- .../common/media_hidl_test_common.cpp | 112 ++----- .../common/media_hidl_test_common.h | 42 +-- .../VtsHalMediaOmxV1_0TargetVideoEncTest.cpp | 300 ++++++------------ 4 files changed, 122 insertions(+), 350 deletions(-) diff --git a/media/omx/1.0/vts/functional/common/Android.bp b/media/omx/1.0/vts/functional/common/Android.bp index 3845b9f36f..89df4ff3fb 100644 --- a/media/omx/1.0/vts/functional/common/Android.bp +++ b/media/omx/1.0/vts/functional/common/Android.bp @@ -22,28 +22,24 @@ cc_library_static { export_header_lib_headers: ["media_plugin_headers"], export_include_dirs: ["."], + shared_libs: [ + "libui", + ], + static_libs: [ "libgtest", "libhidlmemory", "android.hidl.allocator@1.0", "android.hidl.memory@1.0", "android.hardware.media.omx@1.0", - "android.hardware.graphics.allocator@2.0", - "android.hardware.graphics.allocator@3.0", "android.hardware.graphics.common@1.0", "android.hardware.graphics.common@1.1", "android.hardware.graphics.common@1.2", - "android.hardware.graphics.mapper@2.0", - "android.hardware.graphics.mapper@3.0", ], export_static_lib_headers: [ - "android.hardware.graphics.allocator@2.0", - "android.hardware.graphics.allocator@3.0", "android.hardware.graphics.common@1.0", "android.hardware.graphics.common@1.1", "android.hardware.graphics.common@1.2", - "android.hardware.graphics.mapper@2.0", - "android.hardware.graphics.mapper@3.0", ], } @@ -54,15 +50,10 @@ cc_defaults { // Link to these statically as they are not guaranteed to be on the device. static_libs: [ "VtsHalMediaOmxV1_0CommonUtil", - "android.hardware.graphics.allocator@2.0", - "android.hardware.graphics.allocator@3.0", "android.hardware.graphics.common@1.0", "android.hardware.graphics.common@1.1", "android.hardware.graphics.common@1.2", - "android.hardware.graphics.mapper@2.0", - "android.hardware.graphics.mapper@3.0", "android.hardware.graphics.bufferqueue@1.0", - "android.hardware.graphics.common@1.0", "android.hardware.media.omx@1.0", "android.hardware.media@1.0", "android.hidl.allocator@1.0", @@ -73,6 +64,7 @@ cc_defaults { // TODO(b/64437680): Assume these libs are always available on the device. shared_libs: [ "libnativehelper", + "libui", "libstagefright_foundation", "libstagefright_omx_utils", ], diff --git a/media/omx/1.0/vts/functional/common/media_hidl_test_common.cpp b/media/omx/1.0/vts/functional/common/media_hidl_test_common.cpp index d9d11571c4..64f27e8ad8 100644 --- a/media/omx/1.0/vts/functional/common/media_hidl_test_common.cpp +++ b/media/omx/1.0/vts/functional/common/media_hidl_test_common.cpp @@ -21,12 +21,6 @@ #include -#include -#include -#include -#include -#include -#include #include #include #include @@ -199,42 +193,6 @@ void allocateGraphicBuffers(sp omxNode, OMX_U32 portIndex, BufferInfo* buffer, uint32_t nFrameWidth, uint32_t nFrameHeight, int32_t* nStride, int format) { - struct AllocatorV2 : public GrallocV2 { - sp mAllocator; - sp mMapper; - AllocatorV2(sp&& allocator, sp&& mapper) - : mAllocator{std::move(allocator)}, mMapper{std::move(mapper)} {} - AllocatorV2() = default; - }; - struct AllocatorV3 : public GrallocV3 { - sp mAllocator; - sp mMapper; - AllocatorV3(sp&& allocator, sp&& mapper) - : mAllocator{std::move(allocator)}, mMapper{std::move(mapper)} {} - AllocatorV3() = default; - }; - std::variant grallocVar; - - sp mapper2{}; - sp mapper3{}; - sp allocator2{}; - sp allocator3 = - android::hardware::graphics::allocator::V3_0::IAllocator::getService(); - if (allocator3) { - mapper3 = - android::hardware::graphics::mapper::V3_0::IMapper::getService(); - ASSERT_NE(nullptr, mapper3.get()); - grallocVar.emplace(std::move(allocator3), std::move(mapper3)); - } else { - allocator2 = - android::hardware::graphics::allocator::V2_0::IAllocator::getService(); - ASSERT_NE(nullptr, allocator2.get()); - mapper2 = - android::hardware::graphics::mapper::V2_0::IMapper::getService(); - ASSERT_NE(nullptr, allocator2.get()); - grallocVar.emplace(std::move(allocator2), std::move(mapper2)); - } - android::hardware::media::omx::V1_0::Status status{}; uint64_t usage{}; ASSERT_TRUE(omxNode->getGraphicBufferUsage( @@ -246,57 +204,27 @@ void allocateGraphicBuffers(sp omxNode, OMX_U32 portIndex, }).isOk()); ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK); + uint32_t stride; + buffer_handle_t handle = nullptr; + android::GraphicBufferAllocator& allocator = android::GraphicBufferAllocator::get(); + android::status_t error = allocator.allocate( + nFrameWidth, nFrameHeight, static_cast(format), 1, + usage | BufferUsage::CPU_READ_OFTEN, &handle, &stride, "omx_vts_common"); + + ASSERT_EQ(error, android::NO_ERROR); + ASSERT_NE(handle, nullptr); + + *nStride = static_cast(stride); + buffer->omxBuffer.nativeHandle = handle; + buffer->omxBuffer.attr.anwBuffer.width = nFrameWidth; + buffer->omxBuffer.attr.anwBuffer.height = nFrameHeight; + buffer->omxBuffer.attr.anwBuffer.stride = stride; + buffer->omxBuffer.attr.anwBuffer.format = static_cast(format); + buffer->omxBuffer.attr.anwBuffer.usage = usage | BufferUsage::CPU_READ_OFTEN; + buffer->omxBuffer.attr.anwBuffer.layerCount = 1; static std::atomic_int32_t bufferIdCounter{0}; - - std::visit([buffer, nFrameWidth, nFrameHeight, format, usage, nStride](auto&& gralloc) { - using Gralloc = std::remove_reference_t; - using Descriptor = typename Gralloc::Descriptor; - using DescriptorInfo = typename Gralloc::DescriptorInfo; - using Error = typename Gralloc::Error; - using Format = typename Gralloc::Format; - using Usage = typename Gralloc::Usage; - - Error error{}; - Descriptor descriptor{}; - - DescriptorInfo descriptorInfo{}; - descriptorInfo.width = nFrameWidth; - descriptorInfo.height = nFrameHeight; - descriptorInfo.layerCount = 1; - descriptorInfo.format = static_cast(format); - descriptorInfo.usage = usage | Usage(BufferUsage::CPU_READ_OFTEN); - - gralloc.mMapper->createDescriptor(descriptorInfo, - [&error, &descriptor]( - Error _s, - const Descriptor& _n1) { - error = _s; - descriptor = _n1; - }); - ASSERT_EQ(error, Error::NONE); - - gralloc.mAllocator->allocate( - descriptor, 1, - [&](Error _s, uint32_t _n1, - const ::android::hardware::hidl_vec< - ::android::hardware::hidl_handle>& _n2) { - ASSERT_EQ(Error::NONE, _s); - *nStride = _n1; - buffer->omxBuffer.nativeHandle = _n2[0]; - buffer->omxBuffer.attr.anwBuffer.width = nFrameWidth; - buffer->omxBuffer.attr.anwBuffer.height = nFrameHeight; - buffer->omxBuffer.attr.anwBuffer.stride = _n1; - buffer->omxBuffer.attr.anwBuffer.format = - static_cast(descriptorInfo.format); - buffer->omxBuffer.attr.anwBuffer.usage = - static_cast(descriptorInfo.usage); - buffer->omxBuffer.attr.anwBuffer.layerCount = - descriptorInfo.layerCount; - buffer->omxBuffer.attr.anwBuffer.id = - (static_cast(getpid()) << 32) | - bufferIdCounter.fetch_add(1, std::memory_order_relaxed); - }); - }, grallocVar); + buffer->omxBuffer.attr.anwBuffer.id = (static_cast(getpid()) << 32) | + bufferIdCounter.fetch_add(1, std::memory_order_relaxed); } // allocate buffers needed on a component port diff --git a/media/omx/1.0/vts/functional/common/media_hidl_test_common.h b/media/omx/1.0/vts/functional/common/media_hidl_test_common.h index bb03dd0341..044408d58d 100644 --- a/media/omx/1.0/vts/functional/common/media_hidl_test_common.h +++ b/media/omx/1.0/vts/functional/common/media_hidl_test_common.h @@ -22,16 +22,6 @@ #endif #include - -#include -#include -#include -#include -#include -#include -#include -#include -#include #include #include #include @@ -46,6 +36,9 @@ #include #include +#include +#include + /* TIME OUTS (Wait time in dequeueMessage()) */ /* As component is switching states (loaded<->idle<->execute), dequeueMessage() @@ -312,35 +305,6 @@ Return setPortConfig( /* * common functions declarations */ -struct GrallocV2 { - using Format = android::hardware::graphics::common::V1_0::PixelFormat; - using Usage = android::hardware::hidl_bitfield< - android::hardware::graphics::common::V1_0::BufferUsage>; - - using IAllocator = android::hardware::graphics::allocator::V2_0::IAllocator; - - using IMapper = android::hardware::graphics::mapper::V2_0::IMapper; - using Error = android::hardware::graphics::mapper::V2_0::Error; - using Descriptor = android::hardware::graphics::mapper::V2_0::BufferDescriptor; - using YCbCrLayout = android::hardware::graphics::mapper::V2_0::YCbCrLayout; - using DescriptorInfo = IMapper::BufferDescriptorInfo; - using Rect = IMapper::Rect; -}; - -struct GrallocV3 { - using Format = android::hardware::graphics::common::V1_2::PixelFormat; - using Usage = android::hardware::hidl_bitfield< - android::hardware::graphics::common::V1_2::BufferUsage>; - - using IAllocator = android::hardware::graphics::allocator::V3_0::IAllocator; - - using IMapper = android::hardware::graphics::mapper::V3_0::IMapper; - using Error = android::hardware::graphics::mapper::V3_0::Error; - using Descriptor = android::hardware::graphics::mapper::V3_0::BufferDescriptor; - using YCbCrLayout = android::hardware::graphics::mapper::V3_0::YCbCrLayout; - using DescriptorInfo = IMapper::BufferDescriptorInfo; - using Rect = IMapper::Rect; -}; Return setRole(sp omxNode, const std::string& role); diff --git a/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoEncTest.cpp b/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoEncTest.cpp index 4b469e6bb1..7519f2f13a 100644 --- a/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoEncTest.cpp +++ b/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoEncTest.cpp @@ -23,8 +23,6 @@ #include #include -#include -#include #include #include #include @@ -364,61 +362,6 @@ Return DummyBufferSource::onInputBufferEmptied( return Void(); }; -// Variant of mappers -struct MapperV2 : public GrallocV2 { - sp mMapper; - MapperV2(sp&& mapper): mMapper{std::move(mapper)} {} - MapperV2() = default; - android::hardware::Return lock( - void* buffer, - Usage usage, - const Rect& rect, - const android::hardware::hidl_handle& handle, - Error* error, - void** data) { - return mMapper->lock(buffer, usage, rect, handle, - [error, data](Error e, void* d) { - *error = e; - *data = d; - }); - } -}; -struct MapperV3 : public GrallocV3 { - sp mMapper; - MapperV3(sp&& mapper): mMapper{std::move(mapper)} {} - MapperV3() = default; - android::hardware::Return lock( - void* buffer, - Usage usage, - const Rect& rect, - const android::hardware::hidl_handle& handle, - Error* error, - void** data) { - return mMapper->lock(buffer, usage, rect, handle, - [error, data](Error e, void* d, int32_t, int32_t) { - *error = e; - *data = d; - }); - } -}; -using MapperVar = std::variant; -// Initializes the MapperVar by trying services of different versions. -bool initialize(MapperVar& mapperVar) { - sp mapper3 = - android::hardware::graphics::mapper::V3_0::IMapper::getService(); - if (mapper3) { - mapperVar.emplace(std::move(mapper3)); - return true; - } - sp mapper2 = - android::hardware::graphics::mapper::V2_0::IMapper::getService(); - if (mapper2) { - mapperVar.emplace(std::move(mapper2)); - return true; - } - return false; -} - // request VOP refresh void requestIDR(sp omxNode, OMX_U32 portIndex) { android::hardware::media::omx::V1_0::Status status; @@ -627,168 +570,113 @@ void waitOnInputConsumption(sp omxNode, sp observer, } } -int colorFormatConversion(BufferInfo* buffer, void* buff, PixelFormat format, +int colorFormatConversion(BufferInfo* buffer, buffer_handle_t buff, PixelFormat format, std::ifstream& eleStream) { - MapperVar mapperVar; - if (!initialize(mapperVar)) { - EXPECT_TRUE(false) << "failed to obtain mapper service"; - return 1; - } - - return std::visit([buffer, buff, format, &eleStream](auto&& mapper) -> int { - using Gralloc = std::remove_reference_t; - using Error = typename Gralloc::Error; - using Rect = typename Gralloc::Rect; - using Usage = typename Gralloc::Usage; - using YCbCrLayout = typename Gralloc::YCbCrLayout; - - android::hardware::hidl_handle fence; - Rect rect; - YCbCrLayout ycbcrLayout; - Error error; - rect.left = 0; - rect.top = 0; - rect.width = buffer->omxBuffer.attr.anwBuffer.width; - rect.height = buffer->omxBuffer.attr.anwBuffer.height; - - if (format == PixelFormat::YV12 || format == PixelFormat::YCRCB_420_SP || - format == PixelFormat::YCBCR_420_888) { - mapper.mMapper->lockYCbCr( - buff, - static_cast( - buffer->omxBuffer.attr.anwBuffer.usage), - rect, - fence, - [&](Error _e, - const YCbCrLayout& _n1) { - error = _e; - ycbcrLayout = _n1; - }); - EXPECT_EQ(error, Error::NONE); - if (error != Error::NONE) - return 1; - - int size = ((rect.width * rect.height * 3) >> 1); - char* img = new char[size]; - if (img == nullptr) return 1; - eleStream.read(img, size); - if (eleStream.gcount() != size) { - delete[] img; - return 1; - } + android::GraphicBufferMapper& gbmapper = android::GraphicBufferMapper::get(); + + android::Rect rect(0, 0, buffer->omxBuffer.attr.anwBuffer.width, + buffer->omxBuffer.attr.anwBuffer.height); + android_ycbcr ycbcrLayout; + android::status_t error = android::NO_ERROR; + + if (format == PixelFormat::YV12 || format == PixelFormat::YCRCB_420_SP || + format == PixelFormat::YCBCR_420_888) { + error = gbmapper.lockYCbCr(buff, buffer->omxBuffer.attr.anwBuffer.usage, rect, + &ycbcrLayout); + EXPECT_EQ(error, android::NO_ERROR); + if (error != android::NO_ERROR) return 1; + + int size = ((rect.getWidth() * rect.getHeight() * 3) >> 1); + char* img = new char[size]; + if (img == nullptr) return 1; + eleStream.read(img, size); + if (eleStream.gcount() != size) { + delete[] img; + return 1; + } - char* imgTmp = img; - char* ipBuffer = static_cast(ycbcrLayout.y); - for (size_t y = rect.height; y > 0; --y) { - memcpy(ipBuffer, imgTmp, rect.width); - ipBuffer += ycbcrLayout.yStride; - imgTmp += rect.width; - } + char* imgTmp = img; + char* ipBuffer = static_cast(ycbcrLayout.y); + for (size_t y = rect.getHeight(); y > 0; --y) { + memcpy(ipBuffer, imgTmp, rect.getWidth()); + ipBuffer += ycbcrLayout.ystride; + imgTmp += rect.getWidth(); + } - if (format == PixelFormat::YV12) - EXPECT_EQ(ycbcrLayout.chromaStep, 1U); - else if (format == PixelFormat::YCRCB_420_SP) - EXPECT_EQ(ycbcrLayout.chromaStep, 2U); + if (format == PixelFormat::YV12) + EXPECT_EQ(ycbcrLayout.chroma_step, 1U); + else if (format == PixelFormat::YCRCB_420_SP) + EXPECT_EQ(ycbcrLayout.chroma_step, 2U); - ipBuffer = static_cast(ycbcrLayout.cb); - for (size_t y = rect.height >> 1; y > 0; --y) { - for (int32_t x = 0; x < (rect.width >> 1); ++x) { - ipBuffer[ycbcrLayout.chromaStep * x] = *imgTmp++; - } - ipBuffer += ycbcrLayout.cStride; - } - ipBuffer = static_cast(ycbcrLayout.cr); - for (size_t y = rect.height >> 1; y > 0; --y) { - for (int32_t x = 0; x < (rect.width >> 1); ++x) { - ipBuffer[ycbcrLayout.chromaStep * x] = *imgTmp++; - } - ipBuffer += ycbcrLayout.cStride; - } + ipBuffer = static_cast(ycbcrLayout.cb); + for (size_t y = rect.getHeight() >> 1; y > 0; --y) { + for (int32_t x = 0; x < (rect.getWidth() >> 1); ++x) { + ipBuffer[ycbcrLayout.chroma_step * x] = *imgTmp++; + } + ipBuffer += ycbcrLayout.cstride; + } + ipBuffer = static_cast(ycbcrLayout.cr); + for (size_t y = rect.getHeight() >> 1; y > 0; --y) { + for (int32_t x = 0; x < (rect.getWidth() >> 1); ++x) { + ipBuffer[ycbcrLayout.chroma_step * x] = *imgTmp++; + } + ipBuffer += ycbcrLayout.cstride; + } - delete[] img; - - mapper.mMapper->unlock(buff, - [&](Error _e, - const android::hardware::hidl_handle& _n1) { - error = _e; - fence = _n1; - }); - EXPECT_EQ(error, Error::NONE); - if (error != Error::NONE) - return 1; - } else { - void* data; - mapper.lock( - buff, - buffer->omxBuffer.attr.anwBuffer.usage, - rect, - fence, - &error, - &data); - EXPECT_EQ(error, Error::NONE); - if (error != Error::NONE) - return 1; - - if (format == PixelFormat::BGRA_8888) { - char* ipBuffer = static_cast(data); - for (size_t y = rect.height; y > 0; --y) { - eleStream.read(ipBuffer, rect.width * 4); - if (eleStream.gcount() != rect.width * 4) return 1; - ipBuffer += buffer->omxBuffer.attr.anwBuffer.stride * 4; - } - } else { - EXPECT_TRUE(false) << "un expected pixel format"; - return 1; - } + delete[] img; - mapper.mMapper->unlock( - buff, - [&](Error _e, const android::hardware::hidl_handle& _n1) { - error = _e; - fence = _n1; - }); - EXPECT_EQ(error, Error::NONE); - if (error != Error::NONE) - return 1; + error = gbmapper.unlock(buff); + EXPECT_EQ(error, android::NO_ERROR); + if (error != android::NO_ERROR) return 1; + } else { + void* data; + int32_t outBytesPerPixel; + int32_t outBytesPerStride; + error = gbmapper.lock(buff, buffer->omxBuffer.attr.anwBuffer.usage, rect, &data, + &outBytesPerPixel, &outBytesPerStride); + EXPECT_EQ(error, android::NO_ERROR); + if (error != android::NO_ERROR) return 1; + + if (format == PixelFormat::BGRA_8888) { + char* ipBuffer = static_cast(data); + for (size_t y = rect.getHeight(); y > 0; --y) { + eleStream.read(ipBuffer, rect.getWidth() * 4); + if (eleStream.gcount() != rect.getWidth() * 4) return 1; + ipBuffer += buffer->omxBuffer.attr.anwBuffer.stride * 4; } + } else { + EXPECT_TRUE(false) << "un expected pixel format"; + return 1; + } + + error = gbmapper.unlock(buff); + EXPECT_EQ(error, android::NO_ERROR); + if (error != android::NO_ERROR) return 1; + } - return 0; - }, mapperVar); + return 0; } int fillGraphicBuffer(BufferInfo* buffer, PixelFormat format, std::ifstream& eleStream) { - MapperVar mapperVar; - if (!initialize(mapperVar)) { - EXPECT_TRUE(false) << "failed to obtain mapper service"; - return 1; - } + android::GraphicBufferMapper& gbmapper = android::GraphicBufferMapper::get(); + buffer_handle_t buff; + android::status_t error = android::NO_ERROR; + gbmapper.importBuffer( + buffer->omxBuffer.nativeHandle, buffer->omxBuffer.attr.anwBuffer.width, + buffer->omxBuffer.attr.anwBuffer.height, buffer->omxBuffer.attr.anwBuffer.layerCount, + static_cast(format), buffer->omxBuffer.attr.anwBuffer.usage, + buffer->omxBuffer.attr.anwBuffer.stride, &buff); + EXPECT_EQ(error, android::NO_ERROR); + if (error != android::NO_ERROR) return 1; + + if (colorFormatConversion(buffer, buff, format, eleStream)) return 1; + + error = gbmapper.freeBuffer(buff); + EXPECT_EQ(error, android::NO_ERROR); + if (error != android::NO_ERROR) return 1; - return std::visit([buffer, format, &eleStream](auto&& mapper) -> int { - using Gralloc = std::remove_reference_t; - using Error = typename Gralloc::Error; - - void* buff = nullptr; - Error error; - mapper.mMapper->importBuffer( - buffer->omxBuffer.nativeHandle, - [&](Error _e, void* _n1) { - error = _e; - buff = _n1; - }); - EXPECT_EQ(error, Error::NONE); - if (error != Error::NONE) - return 1; - - if (colorFormatConversion(buffer, buff, format, eleStream)) return 1; - - error = mapper.mMapper->freeBuffer(buff); - EXPECT_EQ(error, Error::NONE); - if (error != Error::NONE) - return 1; - - return 0; - }, mapperVar); + return 0; } int dispatchGraphicBuffer(sp omxNode, -- GitLab From 1695459e63cdf1fabb4b9247f1e9e145083ea25d Mon Sep 17 00:00:00 2001 From: Tomasz Wasilczyk Date: Tue, 28 Jul 2020 09:42:55 -0700 Subject: [PATCH 083/790] Split out libnl++ from libnetdevice Bug: 162032964 Test: it builds Change-Id: I86b574de458d9ee8204e6a356a80e70c101b443a --- automotive/can/1.0/default/Android.bp | 1 + .../can/1.0/default/libnetdevice/Android.bp | 19 +----- .../can/1.0/default/libnetdevice/can.cpp | 4 +- .../can/1.0/default/libnetdevice/common.cpp | 23 -------- .../can/1.0/default/libnetdevice/common.h | 22 +------ .../1.0/default/libnetdevice/libnetdevice.cpp | 4 +- .../can/1.0/default/libnetdevice/vlan.cpp | 4 +- automotive/can/1.0/default/libnl++/Android.bp | 40 +++++++++++++ .../NetlinkRequest.cpp | 2 +- .../NetlinkSocket.cpp | 4 +- automotive/can/1.0/default/libnl++/common.cpp | 58 ++++++++++++++++++ automotive/can/1.0/default/libnl++/common.h | 59 +++++++++++++++++++ .../include/libnl++}/NetlinkRequest.h | 2 +- .../include/libnl++}/NetlinkSocket.h | 4 +- .../include/libnl++}/nlbuf.h | 0 .../include/libnl++}/printer.h | 2 +- .../include/libnl++}/types.h | 0 .../{libnetdevice => libnl++}/printer.cpp | 4 +- .../protocols/MessageDefinition.cpp | 0 .../protocols/MessageDefinition.h | 4 +- .../protocols/NetlinkProtocol.cpp | 0 .../protocols/NetlinkProtocol.h | 2 +- .../protocols/README | 0 .../protocols/all.cpp | 0 .../{libnetdevice => libnl++}/protocols/all.h | 0 .../protocols/common/Empty.cpp | 0 .../protocols/common/Empty.h | 2 +- .../protocols/common/Error.cpp | 2 +- .../protocols/common/Error.h | 0 .../protocols/generic/Ctrl.cpp | 0 .../protocols/generic/Ctrl.h | 0 .../protocols/generic/Generic.cpp | 0 .../protocols/generic/Generic.h | 0 .../protocols/generic/GenericMessageBase.cpp | 0 .../protocols/generic/GenericMessageBase.h | 0 .../protocols/generic/Unknown.cpp | 0 .../protocols/generic/Unknown.h | 0 .../protocols/route/Link.cpp | 0 .../protocols/route/Link.h | 0 .../protocols/route/Route.cpp | 0 .../protocols/route/Route.h | 0 .../protocols/route/structs.cpp | 0 .../protocols/route/structs.h | 2 +- 43 files changed, 183 insertions(+), 81 deletions(-) create mode 100644 automotive/can/1.0/default/libnl++/Android.bp rename automotive/can/1.0/default/{libnetdevice => libnl++}/NetlinkRequest.cpp (97%) rename automotive/can/1.0/default/{libnetdevice => libnl++}/NetlinkSocket.cpp (98%) create mode 100644 automotive/can/1.0/default/libnl++/common.cpp create mode 100644 automotive/can/1.0/default/libnl++/common.h rename automotive/can/1.0/default/{libnetdevice/include/libnetdevice => libnl++/include/libnl++}/NetlinkRequest.h (99%) rename automotive/can/1.0/default/{libnetdevice/include/libnetdevice => libnl++/include/libnl++}/NetlinkSocket.h (97%) rename automotive/can/1.0/default/{libnetdevice/include/libnetdevice => libnl++/include/libnl++}/nlbuf.h (100%) rename automotive/can/1.0/default/{libnetdevice/include/libnetdevice => libnl++/include/libnl++}/printer.h (97%) rename automotive/can/1.0/default/{libnetdevice/include/libnetdevice => libnl++/include/libnl++}/types.h (100%) rename automotive/can/1.0/default/{libnetdevice => libnl++}/printer.cpp (98%) rename automotive/can/1.0/default/{libnetdevice => libnl++}/protocols/MessageDefinition.cpp (100%) rename automotive/can/1.0/default/{libnetdevice => libnl++}/protocols/MessageDefinition.h (98%) rename automotive/can/1.0/default/{libnetdevice => libnl++}/protocols/NetlinkProtocol.cpp (100%) rename automotive/can/1.0/default/{libnetdevice => libnl++}/protocols/NetlinkProtocol.h (98%) rename automotive/can/1.0/default/{libnetdevice => libnl++}/protocols/README (100%) rename automotive/can/1.0/default/{libnetdevice => libnl++}/protocols/all.cpp (100%) rename automotive/can/1.0/default/{libnetdevice => libnl++}/protocols/all.h (100%) rename automotive/can/1.0/default/{libnetdevice => libnl++}/protocols/common/Empty.cpp (100%) rename automotive/can/1.0/default/{libnetdevice => libnl++}/protocols/common/Empty.h (96%) rename automotive/can/1.0/default/{libnetdevice => libnl++}/protocols/common/Error.cpp (97%) rename automotive/can/1.0/default/{libnetdevice => libnl++}/protocols/common/Error.h (100%) rename automotive/can/1.0/default/{libnetdevice => libnl++}/protocols/generic/Ctrl.cpp (100%) rename automotive/can/1.0/default/{libnetdevice => libnl++}/protocols/generic/Ctrl.h (100%) rename automotive/can/1.0/default/{libnetdevice => libnl++}/protocols/generic/Generic.cpp (100%) rename automotive/can/1.0/default/{libnetdevice => libnl++}/protocols/generic/Generic.h (100%) rename automotive/can/1.0/default/{libnetdevice => libnl++}/protocols/generic/GenericMessageBase.cpp (100%) rename automotive/can/1.0/default/{libnetdevice => libnl++}/protocols/generic/GenericMessageBase.h (100%) rename automotive/can/1.0/default/{libnetdevice => libnl++}/protocols/generic/Unknown.cpp (100%) rename automotive/can/1.0/default/{libnetdevice => libnl++}/protocols/generic/Unknown.h (100%) rename automotive/can/1.0/default/{libnetdevice => libnl++}/protocols/route/Link.cpp (100%) rename automotive/can/1.0/default/{libnetdevice => libnl++}/protocols/route/Link.h (100%) rename automotive/can/1.0/default/{libnetdevice => libnl++}/protocols/route/Route.cpp (100%) rename automotive/can/1.0/default/{libnetdevice => libnl++}/protocols/route/Route.h (100%) rename automotive/can/1.0/default/{libnetdevice => libnl++}/protocols/route/structs.cpp (100%) rename automotive/can/1.0/default/{libnetdevice => libnl++}/protocols/route/structs.h (98%) diff --git a/automotive/can/1.0/default/Android.bp b/automotive/can/1.0/default/Android.bp index f5cf425887..0ba066e35a 100644 --- a/automotive/can/1.0/default/Android.bp +++ b/automotive/can/1.0/default/Android.bp @@ -52,5 +52,6 @@ cc_binary { static_libs: [ "android.hardware.automotive.can@libnetdevice", "android.hardware.automotive@libc++fs", + "libnl++", ], } diff --git a/automotive/can/1.0/default/libnetdevice/Android.bp b/automotive/can/1.0/default/libnetdevice/Android.bp index d49b9abb17..2605f88104 100644 --- a/automotive/can/1.0/default/libnetdevice/Android.bp +++ b/automotive/can/1.0/default/libnetdevice/Android.bp @@ -18,29 +18,16 @@ cc_library_static { name: "android.hardware.automotive.can@libnetdevice", defaults: ["android.hardware.automotive.can@defaults"], vendor_available: true, - relative_install_path: "hw", srcs: [ - "protocols/common/Empty.cpp", - "protocols/common/Error.cpp", - "protocols/generic/Ctrl.cpp", - "protocols/generic/Generic.cpp", - "protocols/generic/GenericMessageBase.cpp", - "protocols/generic/Unknown.cpp", - "protocols/route/Link.cpp", - "protocols/route/Route.cpp", - "protocols/route/structs.cpp", - "protocols/MessageDefinition.cpp", - "protocols/NetlinkProtocol.cpp", - "protocols/all.cpp", - "NetlinkRequest.cpp", - "NetlinkSocket.cpp", "can.cpp", "common.cpp", "ethtool.cpp", "ifreqs.cpp", "libnetdevice.cpp", - "printer.cpp", "vlan.cpp", ], export_include_dirs: ["include"], + static_libs: [ + "libnl++", + ], } diff --git a/automotive/can/1.0/default/libnetdevice/can.cpp b/automotive/can/1.0/default/libnetdevice/can.cpp index b0a243244d..fef9e00685 100644 --- a/automotive/can/1.0/default/libnetdevice/can.cpp +++ b/automotive/can/1.0/default/libnetdevice/can.cpp @@ -20,8 +20,8 @@ #include #include -#include -#include +#include +#include #include #include diff --git a/automotive/can/1.0/default/libnetdevice/common.cpp b/automotive/can/1.0/default/libnetdevice/common.cpp index f2968fc6ec..28e50af60a 100644 --- a/automotive/can/1.0/default/libnetdevice/common.cpp +++ b/automotive/can/1.0/default/libnetdevice/common.cpp @@ -32,27 +32,4 @@ unsigned int nametoindex(const std::string& ifname) { return 0; } -std::string sanitize(std::string str) { - str.erase(std::find(str.begin(), str.end(), '\0'), str.end()); - - const auto isInvalid = [](char c) { return !isprint(c); }; - std::replace_if(str.begin(), str.end(), isInvalid, '?'); - - return str; -} - -uint16_t crc16(const nlbuf data, uint16_t crc) { - for (const auto byte : data.getRaw()) { - crc ^= byte; - for (unsigned i = 0; i < 8; i++) { - if (crc & 1) { - crc = (crc >> 1) ^ 0xA001; - } else { - crc >>= 1; - } - } - } - return crc; -} - } // namespace android::netdevice diff --git a/automotive/can/1.0/default/libnetdevice/common.h b/automotive/can/1.0/default/libnetdevice/common.h index 1e0d5b7eed..201909f4c7 100644 --- a/automotive/can/1.0/default/libnetdevice/common.h +++ b/automotive/can/1.0/default/libnetdevice/common.h @@ -16,7 +16,7 @@ #pragma once -#include +#include #include #include @@ -36,24 +36,4 @@ namespace android::netdevice { */ unsigned int nametoindex(const std::string& ifname); -/** - * Sanitize a string of unknown contents. - * - * Trims the string to the first '\0' character and replaces all non-printable characters with '?'. - */ -std::string sanitize(std::string str); - -/** - * Calculates a (optionally running) CRC16 checksum. - * - * CRC16 isn't a strong checksum, but is good for quick comparison purposes. - * One benefit (and also a drawback too) is that all-zero payloads with any length will - * always have a checksum of 0x0000. - * - * \param data Buffer to calculate checksum for - * \param crc Previous CRC16 value to continue calculating running checksum - * \return CRC16 checksum - */ -uint16_t crc16(const nlbuf data, uint16_t crc = 0); - } // namespace android::netdevice diff --git a/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp b/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp index 4293cad0db..05d1e768ec 100644 --- a/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp +++ b/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp @@ -20,8 +20,8 @@ #include "ifreqs.h" #include -#include -#include +#include +#include #include #include diff --git a/automotive/can/1.0/default/libnetdevice/vlan.cpp b/automotive/can/1.0/default/libnetdevice/vlan.cpp index f0caacdb75..3c70247eab 100644 --- a/automotive/can/1.0/default/libnetdevice/vlan.cpp +++ b/automotive/can/1.0/default/libnetdevice/vlan.cpp @@ -19,8 +19,8 @@ #include "common.h" #include -#include -#include +#include +#include namespace android::netdevice::vlan { diff --git a/automotive/can/1.0/default/libnl++/Android.bp b/automotive/can/1.0/default/libnl++/Android.bp new file mode 100644 index 0000000000..cffefe7faa --- /dev/null +++ b/automotive/can/1.0/default/libnl++/Android.bp @@ -0,0 +1,40 @@ +// +// 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. +// + +cc_library_static { + name: "libnl++", + defaults: ["android.hardware.automotive.can@defaults"], + vendor_available: true, + srcs: [ + "protocols/common/Empty.cpp", + "protocols/common/Error.cpp", + "protocols/generic/Ctrl.cpp", + "protocols/generic/Generic.cpp", + "protocols/generic/GenericMessageBase.cpp", + "protocols/generic/Unknown.cpp", + "protocols/route/Link.cpp", + "protocols/route/Route.cpp", + "protocols/route/structs.cpp", + "protocols/MessageDefinition.cpp", + "protocols/NetlinkProtocol.cpp", + "protocols/all.cpp", + "NetlinkRequest.cpp", + "NetlinkSocket.cpp", + "common.cpp", + "printer.cpp", + ], + export_include_dirs: ["include"], +} diff --git a/automotive/can/1.0/default/libnetdevice/NetlinkRequest.cpp b/automotive/can/1.0/default/libnl++/NetlinkRequest.cpp similarity index 97% rename from automotive/can/1.0/default/libnetdevice/NetlinkRequest.cpp rename to automotive/can/1.0/default/libnl++/NetlinkRequest.cpp index 4c06f7cdb4..ff771dc6e1 100644 --- a/automotive/can/1.0/default/libnetdevice/NetlinkRequest.cpp +++ b/automotive/can/1.0/default/libnl++/NetlinkRequest.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include +#include #include diff --git a/automotive/can/1.0/default/libnetdevice/NetlinkSocket.cpp b/automotive/can/1.0/default/libnl++/NetlinkSocket.cpp similarity index 98% rename from automotive/can/1.0/default/libnetdevice/NetlinkSocket.cpp rename to automotive/can/1.0/default/libnl++/NetlinkSocket.cpp index 91149c0160..4db20e1a00 100644 --- a/automotive/can/1.0/default/libnetdevice/NetlinkSocket.cpp +++ b/automotive/can/1.0/default/libnl++/NetlinkSocket.cpp @@ -14,9 +14,9 @@ * limitations under the License. */ -#include +#include -#include +#include #include diff --git a/automotive/can/1.0/default/libnl++/common.cpp b/automotive/can/1.0/default/libnl++/common.cpp new file mode 100644 index 0000000000..f2968fc6ec --- /dev/null +++ b/automotive/can/1.0/default/libnl++/common.cpp @@ -0,0 +1,58 @@ +/* + * 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 "common.h" + +#include + +#include + +namespace android::netdevice { + +unsigned int nametoindex(const std::string& ifname) { + const auto ifidx = if_nametoindex(ifname.c_str()); + if (ifidx != 0) return ifidx; + + if (errno != ENODEV) { + PLOG(ERROR) << "if_nametoindex(" << ifname << ") failed"; + } + return 0; +} + +std::string sanitize(std::string str) { + str.erase(std::find(str.begin(), str.end(), '\0'), str.end()); + + const auto isInvalid = [](char c) { return !isprint(c); }; + std::replace_if(str.begin(), str.end(), isInvalid, '?'); + + return str; +} + +uint16_t crc16(const nlbuf data, uint16_t crc) { + for (const auto byte : data.getRaw()) { + crc ^= byte; + for (unsigned i = 0; i < 8; i++) { + if (crc & 1) { + crc = (crc >> 1) ^ 0xA001; + } else { + crc >>= 1; + } + } + } + return crc; +} + +} // namespace android::netdevice diff --git a/automotive/can/1.0/default/libnl++/common.h b/automotive/can/1.0/default/libnl++/common.h new file mode 100644 index 0000000000..83f5f1e7b4 --- /dev/null +++ b/automotive/can/1.0/default/libnl++/common.h @@ -0,0 +1,59 @@ +/* + * 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. + */ + +#pragma once + +#include + +#include +#include + +#include + +namespace android::netdevice { + +/** + * Returns the index of a given network interface. + * + * If the syscall to check the index fails with other error than ENODEV, it gets logged and the + * return value indicates the interface doesn't exists. + * + * \param ifname Interface to check + * \return Interface index, or 0 if the interface doesn't exist + */ +unsigned int nametoindex(const std::string& ifname); + +/** + * Sanitize a string of unknown contents. + * + * Trims the string to the first '\0' character and replaces all non-printable characters with '?'. + */ +std::string sanitize(std::string str); + +/** + * Calculates a (optionally running) CRC16 checksum. + * + * CRC16 isn't a strong checksum, but is good for quick comparison purposes. + * One benefit (and also a drawback too) is that all-zero payloads with any length will + * always have a checksum of 0x0000. + * + * \param data Buffer to calculate checksum for + * \param crc Previous CRC16 value to continue calculating running checksum + * \return CRC16 checksum + */ +uint16_t crc16(const nlbuf data, uint16_t crc = 0); + +} // namespace android::netdevice diff --git a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/NetlinkRequest.h b/automotive/can/1.0/default/libnl++/include/libnl++/NetlinkRequest.h similarity index 99% rename from automotive/can/1.0/default/libnetdevice/include/libnetdevice/NetlinkRequest.h rename to automotive/can/1.0/default/libnl++/include/libnl++/NetlinkRequest.h index c19d04d874..b0cb8ce6f2 100644 --- a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/NetlinkRequest.h +++ b/automotive/can/1.0/default/libnl++/include/libnl++/NetlinkRequest.h @@ -17,7 +17,7 @@ #pragma once #include -#include +#include #include diff --git a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/NetlinkSocket.h b/automotive/can/1.0/default/libnl++/include/libnl++/NetlinkSocket.h similarity index 97% rename from automotive/can/1.0/default/libnetdevice/include/libnetdevice/NetlinkSocket.h rename to automotive/can/1.0/default/libnl++/include/libnl++/NetlinkSocket.h index 826b6b88de..0e73550acf 100644 --- a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/NetlinkSocket.h +++ b/automotive/can/1.0/default/libnl++/include/libnl++/NetlinkSocket.h @@ -18,8 +18,8 @@ #include #include -#include -#include +#include +#include #include diff --git a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/nlbuf.h b/automotive/can/1.0/default/libnl++/include/libnl++/nlbuf.h similarity index 100% rename from automotive/can/1.0/default/libnetdevice/include/libnetdevice/nlbuf.h rename to automotive/can/1.0/default/libnl++/include/libnl++/nlbuf.h diff --git a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/printer.h b/automotive/can/1.0/default/libnl++/include/libnl++/printer.h similarity index 97% rename from automotive/can/1.0/default/libnetdevice/include/libnetdevice/printer.h rename to automotive/can/1.0/default/libnl++/include/libnl++/printer.h index 071fa63612..486f422493 100644 --- a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/printer.h +++ b/automotive/can/1.0/default/libnl++/include/libnl++/printer.h @@ -16,7 +16,7 @@ #pragma once -#include +#include #include diff --git a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/types.h b/automotive/can/1.0/default/libnl++/include/libnl++/types.h similarity index 100% rename from automotive/can/1.0/default/libnetdevice/include/libnetdevice/types.h rename to automotive/can/1.0/default/libnl++/include/libnl++/types.h diff --git a/automotive/can/1.0/default/libnetdevice/printer.cpp b/automotive/can/1.0/default/libnl++/printer.cpp similarity index 98% rename from automotive/can/1.0/default/libnetdevice/printer.cpp rename to automotive/can/1.0/default/libnl++/printer.cpp index 179d501264..bd84309396 100644 --- a/automotive/can/1.0/default/libnetdevice/printer.cpp +++ b/automotive/can/1.0/default/libnl++/printer.cpp @@ -14,13 +14,13 @@ * limitations under the License. */ -#include +#include #include "common.h" #include "protocols/all.h" #include -#include +#include #include #include diff --git a/automotive/can/1.0/default/libnetdevice/protocols/MessageDefinition.cpp b/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.cpp similarity index 100% rename from automotive/can/1.0/default/libnetdevice/protocols/MessageDefinition.cpp rename to automotive/can/1.0/default/libnl++/protocols/MessageDefinition.cpp diff --git a/automotive/can/1.0/default/libnetdevice/protocols/MessageDefinition.h b/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.h similarity index 98% rename from automotive/can/1.0/default/libnetdevice/protocols/MessageDefinition.h rename to automotive/can/1.0/default/libnl++/protocols/MessageDefinition.h index 3a8b2b55d0..27459e199b 100644 --- a/automotive/can/1.0/default/libnetdevice/protocols/MessageDefinition.h +++ b/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.h @@ -16,8 +16,8 @@ #pragma once -#include -#include +#include +#include #include #include diff --git a/automotive/can/1.0/default/libnetdevice/protocols/NetlinkProtocol.cpp b/automotive/can/1.0/default/libnl++/protocols/NetlinkProtocol.cpp similarity index 100% rename from automotive/can/1.0/default/libnetdevice/protocols/NetlinkProtocol.cpp rename to automotive/can/1.0/default/libnl++/protocols/NetlinkProtocol.cpp diff --git a/automotive/can/1.0/default/libnetdevice/protocols/NetlinkProtocol.h b/automotive/can/1.0/default/libnl++/protocols/NetlinkProtocol.h similarity index 98% rename from automotive/can/1.0/default/libnetdevice/protocols/NetlinkProtocol.h rename to automotive/can/1.0/default/libnl++/protocols/NetlinkProtocol.h index 7b12efaa2c..5516452bf0 100644 --- a/automotive/can/1.0/default/libnetdevice/protocols/NetlinkProtocol.h +++ b/automotive/can/1.0/default/libnl++/protocols/NetlinkProtocol.h @@ -20,7 +20,7 @@ #include "common/Empty.h" #include "common/Error.h" -#include +#include #include #include diff --git a/automotive/can/1.0/default/libnetdevice/protocols/README b/automotive/can/1.0/default/libnl++/protocols/README similarity index 100% rename from automotive/can/1.0/default/libnetdevice/protocols/README rename to automotive/can/1.0/default/libnl++/protocols/README diff --git a/automotive/can/1.0/default/libnetdevice/protocols/all.cpp b/automotive/can/1.0/default/libnl++/protocols/all.cpp similarity index 100% rename from automotive/can/1.0/default/libnetdevice/protocols/all.cpp rename to automotive/can/1.0/default/libnl++/protocols/all.cpp diff --git a/automotive/can/1.0/default/libnetdevice/protocols/all.h b/automotive/can/1.0/default/libnl++/protocols/all.h similarity index 100% rename from automotive/can/1.0/default/libnetdevice/protocols/all.h rename to automotive/can/1.0/default/libnl++/protocols/all.h diff --git a/automotive/can/1.0/default/libnetdevice/protocols/common/Empty.cpp b/automotive/can/1.0/default/libnl++/protocols/common/Empty.cpp similarity index 100% rename from automotive/can/1.0/default/libnetdevice/protocols/common/Empty.cpp rename to automotive/can/1.0/default/libnl++/protocols/common/Empty.cpp diff --git a/automotive/can/1.0/default/libnetdevice/protocols/common/Empty.h b/automotive/can/1.0/default/libnl++/protocols/common/Empty.h similarity index 96% rename from automotive/can/1.0/default/libnetdevice/protocols/common/Empty.h rename to automotive/can/1.0/default/libnl++/protocols/common/Empty.h index b5b317f436..701a17c2b8 100644 --- a/automotive/can/1.0/default/libnetdevice/protocols/common/Empty.h +++ b/automotive/can/1.0/default/libnl++/protocols/common/Empty.h @@ -18,7 +18,7 @@ #include "../MessageDefinition.h" -#include +#include namespace android::netdevice::protocols::base { diff --git a/automotive/can/1.0/default/libnetdevice/protocols/common/Error.cpp b/automotive/can/1.0/default/libnl++/protocols/common/Error.cpp similarity index 97% rename from automotive/can/1.0/default/libnetdevice/protocols/common/Error.cpp rename to automotive/can/1.0/default/libnl++/protocols/common/Error.cpp index 25ae680227..313cbfb2a0 100644 --- a/automotive/can/1.0/default/libnetdevice/protocols/common/Error.cpp +++ b/automotive/can/1.0/default/libnl++/protocols/common/Error.cpp @@ -18,7 +18,7 @@ #include "../MessageDefinition.h" -#include +#include namespace android::netdevice::protocols::base { diff --git a/automotive/can/1.0/default/libnetdevice/protocols/common/Error.h b/automotive/can/1.0/default/libnl++/protocols/common/Error.h similarity index 100% rename from automotive/can/1.0/default/libnetdevice/protocols/common/Error.h rename to automotive/can/1.0/default/libnl++/protocols/common/Error.h diff --git a/automotive/can/1.0/default/libnetdevice/protocols/generic/Ctrl.cpp b/automotive/can/1.0/default/libnl++/protocols/generic/Ctrl.cpp similarity index 100% rename from automotive/can/1.0/default/libnetdevice/protocols/generic/Ctrl.cpp rename to automotive/can/1.0/default/libnl++/protocols/generic/Ctrl.cpp diff --git a/automotive/can/1.0/default/libnetdevice/protocols/generic/Ctrl.h b/automotive/can/1.0/default/libnl++/protocols/generic/Ctrl.h similarity index 100% rename from automotive/can/1.0/default/libnetdevice/protocols/generic/Ctrl.h rename to automotive/can/1.0/default/libnl++/protocols/generic/Ctrl.h diff --git a/automotive/can/1.0/default/libnetdevice/protocols/generic/Generic.cpp b/automotive/can/1.0/default/libnl++/protocols/generic/Generic.cpp similarity index 100% rename from automotive/can/1.0/default/libnetdevice/protocols/generic/Generic.cpp rename to automotive/can/1.0/default/libnl++/protocols/generic/Generic.cpp diff --git a/automotive/can/1.0/default/libnetdevice/protocols/generic/Generic.h b/automotive/can/1.0/default/libnl++/protocols/generic/Generic.h similarity index 100% rename from automotive/can/1.0/default/libnetdevice/protocols/generic/Generic.h rename to automotive/can/1.0/default/libnl++/protocols/generic/Generic.h diff --git a/automotive/can/1.0/default/libnetdevice/protocols/generic/GenericMessageBase.cpp b/automotive/can/1.0/default/libnl++/protocols/generic/GenericMessageBase.cpp similarity index 100% rename from automotive/can/1.0/default/libnetdevice/protocols/generic/GenericMessageBase.cpp rename to automotive/can/1.0/default/libnl++/protocols/generic/GenericMessageBase.cpp diff --git a/automotive/can/1.0/default/libnetdevice/protocols/generic/GenericMessageBase.h b/automotive/can/1.0/default/libnl++/protocols/generic/GenericMessageBase.h similarity index 100% rename from automotive/can/1.0/default/libnetdevice/protocols/generic/GenericMessageBase.h rename to automotive/can/1.0/default/libnl++/protocols/generic/GenericMessageBase.h diff --git a/automotive/can/1.0/default/libnetdevice/protocols/generic/Unknown.cpp b/automotive/can/1.0/default/libnl++/protocols/generic/Unknown.cpp similarity index 100% rename from automotive/can/1.0/default/libnetdevice/protocols/generic/Unknown.cpp rename to automotive/can/1.0/default/libnl++/protocols/generic/Unknown.cpp diff --git a/automotive/can/1.0/default/libnetdevice/protocols/generic/Unknown.h b/automotive/can/1.0/default/libnl++/protocols/generic/Unknown.h similarity index 100% rename from automotive/can/1.0/default/libnetdevice/protocols/generic/Unknown.h rename to automotive/can/1.0/default/libnl++/protocols/generic/Unknown.h diff --git a/automotive/can/1.0/default/libnetdevice/protocols/route/Link.cpp b/automotive/can/1.0/default/libnl++/protocols/route/Link.cpp similarity index 100% rename from automotive/can/1.0/default/libnetdevice/protocols/route/Link.cpp rename to automotive/can/1.0/default/libnl++/protocols/route/Link.cpp diff --git a/automotive/can/1.0/default/libnetdevice/protocols/route/Link.h b/automotive/can/1.0/default/libnl++/protocols/route/Link.h similarity index 100% rename from automotive/can/1.0/default/libnetdevice/protocols/route/Link.h rename to automotive/can/1.0/default/libnl++/protocols/route/Link.h diff --git a/automotive/can/1.0/default/libnetdevice/protocols/route/Route.cpp b/automotive/can/1.0/default/libnl++/protocols/route/Route.cpp similarity index 100% rename from automotive/can/1.0/default/libnetdevice/protocols/route/Route.cpp rename to automotive/can/1.0/default/libnl++/protocols/route/Route.cpp diff --git a/automotive/can/1.0/default/libnetdevice/protocols/route/Route.h b/automotive/can/1.0/default/libnl++/protocols/route/Route.h similarity index 100% rename from automotive/can/1.0/default/libnetdevice/protocols/route/Route.h rename to automotive/can/1.0/default/libnl++/protocols/route/Route.h diff --git a/automotive/can/1.0/default/libnetdevice/protocols/route/structs.cpp b/automotive/can/1.0/default/libnl++/protocols/route/structs.cpp similarity index 100% rename from automotive/can/1.0/default/libnetdevice/protocols/route/structs.cpp rename to automotive/can/1.0/default/libnl++/protocols/route/structs.cpp diff --git a/automotive/can/1.0/default/libnetdevice/protocols/route/structs.h b/automotive/can/1.0/default/libnl++/protocols/route/structs.h similarity index 98% rename from automotive/can/1.0/default/libnetdevice/protocols/route/structs.h rename to automotive/can/1.0/default/libnl++/protocols/route/structs.h index e53270439c..2c1771b9e0 100644 --- a/automotive/can/1.0/default/libnetdevice/protocols/route/structs.h +++ b/automotive/can/1.0/default/libnl++/protocols/route/structs.h @@ -16,7 +16,7 @@ #pragma once -#include +#include #include -- GitLab From 1d5beb85a3f899cd75b009fae7934deb96badd6a Mon Sep 17 00:00:00 2001 From: Tomasz Wasilczyk Date: Wed, 29 Jul 2020 09:37:44 -0700 Subject: [PATCH 084/790] Change libnl++ namespace to android::nl Bug: 162032964 Test: it builds Change-Id: I3790f49c41319794e61ed422705c5e18e55e8bfc --- automotive/can/1.0/default/libnetdevice/can.cpp | 4 ++-- automotive/can/1.0/default/libnetdevice/libnetdevice.cpp | 9 +++++---- automotive/can/1.0/default/libnetdevice/vlan.cpp | 5 +++-- automotive/can/1.0/default/libnl++/NetlinkRequest.cpp | 4 ++-- automotive/can/1.0/default/libnl++/NetlinkSocket.cpp | 4 ++-- automotive/can/1.0/default/libnl++/common.cpp | 4 ++-- automotive/can/1.0/default/libnl++/common.h | 4 ++-- .../1.0/default/libnl++/include/libnl++/NetlinkRequest.h | 4 ++-- .../1.0/default/libnl++/include/libnl++/NetlinkSocket.h | 4 ++-- .../can/1.0/default/libnl++/include/libnl++/nlbuf.h | 4 ++-- .../can/1.0/default/libnl++/include/libnl++/printer.h | 4 ++-- .../can/1.0/default/libnl++/include/libnl++/types.h | 4 ++-- automotive/can/1.0/default/libnl++/printer.cpp | 4 ++-- .../1.0/default/libnl++/protocols/MessageDefinition.cpp | 4 ++-- .../1.0/default/libnl++/protocols/MessageDefinition.h | 4 ++-- .../1.0/default/libnl++/protocols/NetlinkProtocol.cpp | 4 ++-- .../can/1.0/default/libnl++/protocols/NetlinkProtocol.h | 4 ++-- automotive/can/1.0/default/libnl++/protocols/all.cpp | 4 ++-- automotive/can/1.0/default/libnl++/protocols/all.h | 4 ++-- .../can/1.0/default/libnl++/protocols/common/Empty.cpp | 4 ++-- .../can/1.0/default/libnl++/protocols/common/Empty.h | 4 ++-- .../can/1.0/default/libnl++/protocols/common/Error.cpp | 4 ++-- .../can/1.0/default/libnl++/protocols/common/Error.h | 4 ++-- .../can/1.0/default/libnl++/protocols/generic/Ctrl.cpp | 4 ++-- .../can/1.0/default/libnl++/protocols/generic/Ctrl.h | 4 ++-- .../1.0/default/libnl++/protocols/generic/Generic.cpp | 4 ++-- .../can/1.0/default/libnl++/protocols/generic/Generic.h | 4 ++-- .../libnl++/protocols/generic/GenericMessageBase.cpp | 4 ++-- .../libnl++/protocols/generic/GenericMessageBase.h | 4 ++-- .../1.0/default/libnl++/protocols/generic/Unknown.cpp | 4 ++-- .../can/1.0/default/libnl++/protocols/generic/Unknown.h | 4 ++-- .../can/1.0/default/libnl++/protocols/route/Link.cpp | 4 ++-- .../can/1.0/default/libnl++/protocols/route/Link.h | 4 ++-- .../can/1.0/default/libnl++/protocols/route/Route.cpp | 4 ++-- .../can/1.0/default/libnl++/protocols/route/Route.h | 4 ++-- .../can/1.0/default/libnl++/protocols/route/structs.cpp | 4 ++-- .../can/1.0/default/libnl++/protocols/route/structs.h | 4 ++-- 37 files changed, 78 insertions(+), 76 deletions(-) diff --git a/automotive/can/1.0/default/libnetdevice/can.cpp b/automotive/can/1.0/default/libnetdevice/can.cpp index fef9e00685..0aa5afefde 100644 --- a/automotive/can/1.0/default/libnetdevice/can.cpp +++ b/automotive/can/1.0/default/libnetdevice/can.cpp @@ -69,7 +69,7 @@ bool setBitrate(std::string ifname, uint32_t bitrate) { struct can_bittiming bt = {}; bt.bitrate = bitrate; - NetlinkRequest req(RTM_NEWLINK, NLM_F_REQUEST); + nl::NetlinkRequest req(RTM_NEWLINK, NLM_F_REQUEST); const auto ifidx = nametoindex(ifname); if (ifidx == 0) { @@ -89,7 +89,7 @@ bool setBitrate(std::string ifname, uint32_t bitrate) { } } - NetlinkSocket sock(NETLINK_ROUTE); + nl::NetlinkSocket sock(NETLINK_ROUTE); return sock.send(req) && sock.receiveAck(); } diff --git a/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp b/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp index 05d1e768ec..04381f2d32 100644 --- a/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp +++ b/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp @@ -61,7 +61,8 @@ bool down(std::string ifname) { } bool add(std::string dev, std::string type) { - NetlinkRequest req(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL); + nl::NetlinkRequest req(RTM_NEWLINK, + NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL); req.addattr(IFLA_IFNAME, dev); { @@ -69,15 +70,15 @@ bool add(std::string dev, std::string type) { req.addattr(IFLA_INFO_KIND, type); } - NetlinkSocket sock(NETLINK_ROUTE); + nl::NetlinkSocket sock(NETLINK_ROUTE); return sock.send(req) && sock.receiveAck(); } bool del(std::string dev) { - NetlinkRequest req(RTM_DELLINK, NLM_F_REQUEST); + nl::NetlinkRequest req(RTM_DELLINK, NLM_F_REQUEST); req.addattr(IFLA_IFNAME, dev); - NetlinkSocket sock(NETLINK_ROUTE); + nl::NetlinkSocket sock(NETLINK_ROUTE); return sock.send(req) && sock.receiveAck(); } diff --git a/automotive/can/1.0/default/libnetdevice/vlan.cpp b/automotive/can/1.0/default/libnetdevice/vlan.cpp index 3c70247eab..bcc9345e69 100644 --- a/automotive/can/1.0/default/libnetdevice/vlan.cpp +++ b/automotive/can/1.0/default/libnetdevice/vlan.cpp @@ -31,7 +31,8 @@ bool add(const std::string& eth, const std::string& vlan, uint16_t id) { return false; } - NetlinkRequest req(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL); + nl::NetlinkRequest req(RTM_NEWLINK, + NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL); req.addattr(IFLA_IFNAME, vlan); req.addattr(IFLA_LINK, ethidx); @@ -45,7 +46,7 @@ bool add(const std::string& eth, const std::string& vlan, uint16_t id) { } } - NetlinkSocket sock(NETLINK_ROUTE); + nl::NetlinkSocket sock(NETLINK_ROUTE); return sock.send(req) && sock.receiveAck(); } diff --git a/automotive/can/1.0/default/libnl++/NetlinkRequest.cpp b/automotive/can/1.0/default/libnl++/NetlinkRequest.cpp index ff771dc6e1..e9463d1106 100644 --- a/automotive/can/1.0/default/libnl++/NetlinkRequest.cpp +++ b/automotive/can/1.0/default/libnl++/NetlinkRequest.cpp @@ -18,7 +18,7 @@ #include -namespace android::netdevice::impl { +namespace android::nl::impl { static struct rtattr* nlmsg_tail(struct nlmsghdr* n) { return reinterpret_cast( // @@ -51,4 +51,4 @@ void addattr_nest_end(struct nlmsghdr* n, struct rtattr* nest) { nest->rta_len = nestLen; } -} // namespace android::netdevice::impl +} // namespace android::nl::impl diff --git a/automotive/can/1.0/default/libnl++/NetlinkSocket.cpp b/automotive/can/1.0/default/libnl++/NetlinkSocket.cpp index 4db20e1a00..6f0f0c2017 100644 --- a/automotive/can/1.0/default/libnl++/NetlinkSocket.cpp +++ b/automotive/can/1.0/default/libnl++/NetlinkSocket.cpp @@ -20,7 +20,7 @@ #include -namespace android::netdevice { +namespace android::nl { /** * Print all outbound/inbound Netlink messages. @@ -190,4 +190,4 @@ std::optional NetlinkSocket::getSocketPid() { return sa.nl_pid; } -} // namespace android::netdevice +} // namespace android::nl diff --git a/automotive/can/1.0/default/libnl++/common.cpp b/automotive/can/1.0/default/libnl++/common.cpp index f2968fc6ec..7848646508 100644 --- a/automotive/can/1.0/default/libnl++/common.cpp +++ b/automotive/can/1.0/default/libnl++/common.cpp @@ -20,7 +20,7 @@ #include -namespace android::netdevice { +namespace android::nl { unsigned int nametoindex(const std::string& ifname) { const auto ifidx = if_nametoindex(ifname.c_str()); @@ -55,4 +55,4 @@ uint16_t crc16(const nlbuf data, uint16_t crc) { return crc; } -} // namespace android::netdevice +} // namespace android::nl diff --git a/automotive/can/1.0/default/libnl++/common.h b/automotive/can/1.0/default/libnl++/common.h index 83f5f1e7b4..dc5777c160 100644 --- a/automotive/can/1.0/default/libnl++/common.h +++ b/automotive/can/1.0/default/libnl++/common.h @@ -23,7 +23,7 @@ #include -namespace android::netdevice { +namespace android::nl { /** * Returns the index of a given network interface. @@ -56,4 +56,4 @@ std::string sanitize(std::string str); */ uint16_t crc16(const nlbuf data, uint16_t crc = 0); -} // namespace android::netdevice +} // namespace android::nl diff --git a/automotive/can/1.0/default/libnl++/include/libnl++/NetlinkRequest.h b/automotive/can/1.0/default/libnl++/include/libnl++/NetlinkRequest.h index b0cb8ce6f2..3b30a2acdf 100644 --- a/automotive/can/1.0/default/libnl++/include/libnl++/NetlinkRequest.h +++ b/automotive/can/1.0/default/libnl++/include/libnl++/NetlinkRequest.h @@ -23,7 +23,7 @@ #include -namespace android::netdevice { +namespace android::nl { /** Implementation details, do not use outside NetlinkRequest template. */ namespace impl { @@ -154,4 +154,4 @@ struct NetlinkRequest { } }; -} // namespace android::netdevice +} // namespace android::nl diff --git a/automotive/can/1.0/default/libnl++/include/libnl++/NetlinkSocket.h b/automotive/can/1.0/default/libnl++/include/libnl++/NetlinkSocket.h index 0e73550acf..f2a38fbe04 100644 --- a/automotive/can/1.0/default/libnl++/include/libnl++/NetlinkSocket.h +++ b/automotive/can/1.0/default/libnl++/include/libnl++/NetlinkSocket.h @@ -25,7 +25,7 @@ #include -namespace android::netdevice { +namespace android::nl { /** * A wrapper around AF_NETLINK sockets. @@ -113,4 +113,4 @@ struct NetlinkSocket { DISALLOW_COPY_AND_ASSIGN(NetlinkSocket); }; -} // namespace android::netdevice +} // namespace android::nl diff --git a/automotive/can/1.0/default/libnl++/include/libnl++/nlbuf.h b/automotive/can/1.0/default/libnl++/include/libnl++/nlbuf.h index 601ab942af..4c0e581a71 100644 --- a/automotive/can/1.0/default/libnl++/include/libnl++/nlbuf.h +++ b/automotive/can/1.0/default/libnl++/include/libnl++/nlbuf.h @@ -22,7 +22,7 @@ #include -namespace android::netdevice { +namespace android::nl { /** * Buffer containing netlink structure (e.g. struct nlmsghdr, struct nlattr). @@ -199,4 +199,4 @@ inline size_t nlbuf::declaredLengthImpl() const { return mData->nla_len; } -} // namespace android::netdevice +} // namespace android::nl diff --git a/automotive/can/1.0/default/libnl++/include/libnl++/printer.h b/automotive/can/1.0/default/libnl++/include/libnl++/printer.h index 486f422493..7167965cfe 100644 --- a/automotive/can/1.0/default/libnl++/include/libnl++/printer.h +++ b/automotive/can/1.0/default/libnl++/include/libnl++/printer.h @@ -22,7 +22,7 @@ #include -namespace android::netdevice { +namespace android::nl { /** * Stringify a Netlink message. @@ -34,4 +34,4 @@ namespace android::netdevice { */ std::string toString(const nlbuf hdr, int protocol, bool printPayload = false); -} // namespace android::netdevice +} // namespace android::nl diff --git a/automotive/can/1.0/default/libnl++/include/libnl++/types.h b/automotive/can/1.0/default/libnl++/include/libnl++/types.h index 9d90c8a7ac..d2f10ff925 100644 --- a/automotive/can/1.0/default/libnl++/include/libnl++/types.h +++ b/automotive/can/1.0/default/libnl++/include/libnl++/types.h @@ -18,10 +18,10 @@ #include -namespace android::netdevice { +namespace android::nl { typedef __u16 nlmsgtype_t; // nlmsghdr::nlmsg_type typedef __u16 nlattrtype_t; // nlattr::nla_type typedef unsigned short rtattrtype_t; // rtattr::rta_type -} // namespace android::netdevice +} // namespace android::nl diff --git a/automotive/can/1.0/default/libnl++/printer.cpp b/automotive/can/1.0/default/libnl++/printer.cpp index bd84309396..c32afb3453 100644 --- a/automotive/can/1.0/default/libnl++/printer.cpp +++ b/automotive/can/1.0/default/libnl++/printer.cpp @@ -26,7 +26,7 @@ #include #include -namespace android::netdevice { +namespace android::nl { static void flagsToStream(std::stringstream& ss, __u16 nlmsg_flags) { bool first = true; @@ -174,4 +174,4 @@ std::string toString(const nlbuf hdr, int protocol, bool printPayload) return ss.str(); } -} // namespace android::netdevice +} // namespace android::nl diff --git a/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.cpp b/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.cpp index cb42896c67..dc5664376c 100644 --- a/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.cpp +++ b/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.cpp @@ -16,7 +16,7 @@ #include "MessageDefinition.h" -namespace android::netdevice::protocols { +namespace android::nl::protocols { AttributeMap::AttributeMap(const std::initializer_list attrTypes) : std::map, AttributeDefinition>(attrTypes) {} @@ -59,4 +59,4 @@ const std::string MessageDescriptor::getMessageName(nlmsgtype_t msgtype) const { return it->second; } -} // namespace android::netdevice::protocols +} // namespace android::nl::protocols diff --git a/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.h b/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.h index 27459e199b..046ef478c5 100644 --- a/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.h +++ b/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.h @@ -23,7 +23,7 @@ #include #include -namespace android::netdevice::protocols { +namespace android::nl::protocols { struct AttributeDefinition; @@ -123,4 +123,4 @@ class MessageDefinition : public MessageDescriptor { virtual void toStream(std::stringstream& ss, const T& data) const = 0; }; -} // namespace android::netdevice::protocols +} // namespace android::nl::protocols diff --git a/automotive/can/1.0/default/libnl++/protocols/NetlinkProtocol.cpp b/automotive/can/1.0/default/libnl++/protocols/NetlinkProtocol.cpp index 4b6cefb8be..4b795d97c4 100644 --- a/automotive/can/1.0/default/libnl++/protocols/NetlinkProtocol.cpp +++ b/automotive/can/1.0/default/libnl++/protocols/NetlinkProtocol.cpp @@ -16,7 +16,7 @@ #include "NetlinkProtocol.h" -namespace android::netdevice::protocols { +namespace android::nl::protocols { NetlinkProtocol::NetlinkProtocol(int protocol, const std::string name, const MessageDescriptorList&& messageDescrs) @@ -61,4 +61,4 @@ NetlinkProtocol::MessageDescriptorMap NetlinkProtocol::toMap( return map; } -} // namespace android::netdevice::protocols +} // namespace android::nl::protocols diff --git a/automotive/can/1.0/default/libnl++/protocols/NetlinkProtocol.h b/automotive/can/1.0/default/libnl++/protocols/NetlinkProtocol.h index 5516452bf0..81a0a6589f 100644 --- a/automotive/can/1.0/default/libnl++/protocols/NetlinkProtocol.h +++ b/automotive/can/1.0/default/libnl++/protocols/NetlinkProtocol.h @@ -25,7 +25,7 @@ #include #include -namespace android::netdevice::protocols { +namespace android::nl::protocols { /** * Netlink-based protocol definition. @@ -59,4 +59,4 @@ class NetlinkProtocol { static MessageDescriptorMap toMap(const MessageDescriptorList& descrs, int protocol); }; -} // namespace android::netdevice::protocols +} // namespace android::nl::protocols diff --git a/automotive/can/1.0/default/libnl++/protocols/all.cpp b/automotive/can/1.0/default/libnl++/protocols/all.cpp index 980e3d0f16..a398dc8f1f 100644 --- a/automotive/can/1.0/default/libnl++/protocols/all.cpp +++ b/automotive/can/1.0/default/libnl++/protocols/all.cpp @@ -21,7 +21,7 @@ #include -namespace android::netdevice::protocols { +namespace android::nl::protocols { // This should be a map of unique_ptr, but it's not trivial to uniformly initialize such a map static std::map> toMap( @@ -43,4 +43,4 @@ std::optional> get(int protocol) { return *all.find(protocol)->second.get(); } -} // namespace android::netdevice::protocols +} // namespace android::nl::protocols diff --git a/automotive/can/1.0/default/libnl++/protocols/all.h b/automotive/can/1.0/default/libnl++/protocols/all.h index 2180ebb017..6d6ec1e76d 100644 --- a/automotive/can/1.0/default/libnl++/protocols/all.h +++ b/automotive/can/1.0/default/libnl++/protocols/all.h @@ -18,7 +18,7 @@ #include "NetlinkProtocol.h" -namespace android::netdevice::protocols { +namespace android::nl::protocols { /** * Protocol definition lookup. @@ -28,4 +28,4 @@ namespace android::netdevice::protocols { */ std::optional> get(int protocol); -} // namespace android::netdevice::protocols +} // namespace android::nl::protocols diff --git a/automotive/can/1.0/default/libnl++/protocols/common/Empty.cpp b/automotive/can/1.0/default/libnl++/protocols/common/Empty.cpp index 9f252039da..dbf10d4273 100644 --- a/automotive/can/1.0/default/libnl++/protocols/common/Empty.cpp +++ b/automotive/can/1.0/default/libnl++/protocols/common/Empty.cpp @@ -16,7 +16,7 @@ #include "Empty.h" -namespace android::netdevice::protocols::base { +namespace android::nl::protocols::base { // clang-format off Empty::Empty() : MessageDefinition("nlmsg", { @@ -28,4 +28,4 @@ Empty::Empty() : MessageDefinition("nlmsg", { void Empty::toStream(std::stringstream&, const char&) const {} -} // namespace android::netdevice::protocols::base +} // namespace android::nl::protocols::base diff --git a/automotive/can/1.0/default/libnl++/protocols/common/Empty.h b/automotive/can/1.0/default/libnl++/protocols/common/Empty.h index 701a17c2b8..79a0f46aa2 100644 --- a/automotive/can/1.0/default/libnl++/protocols/common/Empty.h +++ b/automotive/can/1.0/default/libnl++/protocols/common/Empty.h @@ -20,7 +20,7 @@ #include -namespace android::netdevice::protocols::base { +namespace android::nl::protocols::base { // no-payload (like NLMSG_NOOP) messages can't be defined with T=void, so let's use char class Empty : public MessageDefinition { @@ -29,4 +29,4 @@ class Empty : public MessageDefinition { void toStream(std::stringstream&, const char&) const override; }; -} // namespace android::netdevice::protocols::base +} // namespace android::nl::protocols::base diff --git a/automotive/can/1.0/default/libnl++/protocols/common/Error.cpp b/automotive/can/1.0/default/libnl++/protocols/common/Error.cpp index 313cbfb2a0..1d6bd1c6ba 100644 --- a/automotive/can/1.0/default/libnl++/protocols/common/Error.cpp +++ b/automotive/can/1.0/default/libnl++/protocols/common/Error.cpp @@ -20,7 +20,7 @@ #include -namespace android::netdevice::protocols::base { +namespace android::nl::protocols::base { // clang-format off Error::Error(int protocol) : MessageDefinition("nlmsg", { @@ -33,4 +33,4 @@ void Error::toStream(std::stringstream& ss, const nlmsgerr& data) const { << ", msg=" << toString({&data.msg, sizeof(data.msg)}, mProtocol) << "}"; } -} // namespace android::netdevice::protocols::base +} // namespace android::nl::protocols::base diff --git a/automotive/can/1.0/default/libnl++/protocols/common/Error.h b/automotive/can/1.0/default/libnl++/protocols/common/Error.h index 1f3c1dd694..782986b7a3 100644 --- a/automotive/can/1.0/default/libnl++/protocols/common/Error.h +++ b/automotive/can/1.0/default/libnl++/protocols/common/Error.h @@ -18,7 +18,7 @@ #include "../MessageDefinition.h" -namespace android::netdevice::protocols::base { +namespace android::nl::protocols::base { class Error : public MessageDefinition { public: @@ -29,4 +29,4 @@ class Error : public MessageDefinition { const int mProtocol; }; -} // namespace android::netdevice::protocols::base +} // namespace android::nl::protocols::base diff --git a/automotive/can/1.0/default/libnl++/protocols/generic/Ctrl.cpp b/automotive/can/1.0/default/libnl++/protocols/generic/Ctrl.cpp index 4120008519..a3c6736cef 100644 --- a/automotive/can/1.0/default/libnl++/protocols/generic/Ctrl.cpp +++ b/automotive/can/1.0/default/libnl++/protocols/generic/Ctrl.cpp @@ -16,7 +16,7 @@ #include "Ctrl.h" -namespace android::netdevice::protocols::generic { +namespace android::nl::protocols::generic { using DataType = AttributeDefinition::DataType; @@ -52,4 +52,4 @@ Ctrl::Ctrl() : GenericMessageBase(GENL_ID_CTRL, "ID_CTRL", { }) {} // clang-format on -} // namespace android::netdevice::protocols::generic +} // namespace android::nl::protocols::generic diff --git a/automotive/can/1.0/default/libnl++/protocols/generic/Ctrl.h b/automotive/can/1.0/default/libnl++/protocols/generic/Ctrl.h index 804ed2cf9a..6af87a8bb8 100644 --- a/automotive/can/1.0/default/libnl++/protocols/generic/Ctrl.h +++ b/automotive/can/1.0/default/libnl++/protocols/generic/Ctrl.h @@ -18,11 +18,11 @@ #include "GenericMessageBase.h" -namespace android::netdevice::protocols::generic { +namespace android::nl::protocols::generic { class Ctrl : public GenericMessageBase { public: Ctrl(); }; -} // namespace android::netdevice::protocols::generic +} // namespace android::nl::protocols::generic diff --git a/automotive/can/1.0/default/libnl++/protocols/generic/Generic.cpp b/automotive/can/1.0/default/libnl++/protocols/generic/Generic.cpp index 633ef3cbbe..1a24914ab7 100644 --- a/automotive/can/1.0/default/libnl++/protocols/generic/Generic.cpp +++ b/automotive/can/1.0/default/libnl++/protocols/generic/Generic.cpp @@ -19,7 +19,7 @@ #include "Ctrl.h" #include "Unknown.h" -namespace android::netdevice::protocols::generic { +namespace android::nl::protocols::generic { Generic::Generic() : NetlinkProtocol(NETLINK_GENERIC, "GENERIC", {std::make_shared()}) {} @@ -33,4 +33,4 @@ const std::optional> Generic::ge return *(mFamilyRegister[nlmsg_type] = std::make_shared(nlmsg_type)); } -} // namespace android::netdevice::protocols::generic +} // namespace android::nl::protocols::generic diff --git a/automotive/can/1.0/default/libnl++/protocols/generic/Generic.h b/automotive/can/1.0/default/libnl++/protocols/generic/Generic.h index b4352f6193..593c92d3e8 100644 --- a/automotive/can/1.0/default/libnl++/protocols/generic/Generic.h +++ b/automotive/can/1.0/default/libnl++/protocols/generic/Generic.h @@ -18,7 +18,7 @@ #include "../NetlinkProtocol.h" -namespace android::netdevice::protocols::generic { +namespace android::nl::protocols::generic { /** * Definition of NETLINK_GENERIC protocol. @@ -34,4 +34,4 @@ class Generic : public NetlinkProtocol { std::map> mFamilyRegister; }; -} // namespace android::netdevice::protocols::generic +} // namespace android::nl::protocols::generic diff --git a/automotive/can/1.0/default/libnl++/protocols/generic/GenericMessageBase.cpp b/automotive/can/1.0/default/libnl++/protocols/generic/GenericMessageBase.cpp index c9f08131fc..520336855e 100644 --- a/automotive/can/1.0/default/libnl++/protocols/generic/GenericMessageBase.cpp +++ b/automotive/can/1.0/default/libnl++/protocols/generic/GenericMessageBase.cpp @@ -16,7 +16,7 @@ #include "GenericMessageBase.h" -namespace android::netdevice::protocols::generic { +namespace android::nl::protocols::generic { GenericMessageBase::GenericMessageBase( nlmsgtype_t msgtype, std::string msgname, @@ -37,4 +37,4 @@ void GenericMessageBase::toStream(std::stringstream& ss, const struct genlmsghdr ss << "}"; } -} // namespace android::netdevice::protocols::generic +} // namespace android::nl::protocols::generic diff --git a/automotive/can/1.0/default/libnl++/protocols/generic/GenericMessageBase.h b/automotive/can/1.0/default/libnl++/protocols/generic/GenericMessageBase.h index 2a19034dda..f3b0b31add 100644 --- a/automotive/can/1.0/default/libnl++/protocols/generic/GenericMessageBase.h +++ b/automotive/can/1.0/default/libnl++/protocols/generic/GenericMessageBase.h @@ -20,7 +20,7 @@ #include -namespace android::netdevice::protocols::generic { +namespace android::nl::protocols::generic { class GenericMessageBase : public MessageDefinition { public: @@ -37,4 +37,4 @@ class GenericMessageBase : public MessageDefinition { const GenericCommandNameMap mCommandNames; }; -} // namespace android::netdevice::protocols::generic +} // namespace android::nl::protocols::generic diff --git a/automotive/can/1.0/default/libnl++/protocols/generic/Unknown.cpp b/automotive/can/1.0/default/libnl++/protocols/generic/Unknown.cpp index 9a71d897c3..17367f0029 100644 --- a/automotive/can/1.0/default/libnl++/protocols/generic/Unknown.cpp +++ b/automotive/can/1.0/default/libnl++/protocols/generic/Unknown.cpp @@ -16,9 +16,9 @@ #include "Unknown.h" -namespace android::netdevice::protocols::generic { +namespace android::nl::protocols::generic { Unknown::Unknown(nlmsgtype_t msgtype) : GenericMessageBase(msgtype, "Unknown(" + std::to_string(msgtype) + ")") {} -} // namespace android::netdevice::protocols::generic +} // namespace android::nl::protocols::generic diff --git a/automotive/can/1.0/default/libnl++/protocols/generic/Unknown.h b/automotive/can/1.0/default/libnl++/protocols/generic/Unknown.h index 82a5501830..62ae19d758 100644 --- a/automotive/can/1.0/default/libnl++/protocols/generic/Unknown.h +++ b/automotive/can/1.0/default/libnl++/protocols/generic/Unknown.h @@ -18,11 +18,11 @@ #include "GenericMessageBase.h" -namespace android::netdevice::protocols::generic { +namespace android::nl::protocols::generic { class Unknown : public GenericMessageBase { public: Unknown(nlmsgtype_t msgtype); }; -} // namespace android::netdevice::protocols::generic +} // namespace android::nl::protocols::generic diff --git a/automotive/can/1.0/default/libnl++/protocols/route/Link.cpp b/automotive/can/1.0/default/libnl++/protocols/route/Link.cpp index 53e1700219..26d3e3e8f5 100644 --- a/automotive/can/1.0/default/libnl++/protocols/route/Link.cpp +++ b/automotive/can/1.0/default/libnl++/protocols/route/Link.cpp @@ -20,7 +20,7 @@ #include -namespace android::netdevice::protocols::route { +namespace android::nl::protocols::route { using DataType = AttributeDefinition::DataType; @@ -114,4 +114,4 @@ void Link::toStream(std::stringstream& ss, const struct ifinfomsg& data) const { << ", change=" << data.ifi_change << "}"; } -} // namespace android::netdevice::protocols::route +} // namespace android::nl::protocols::route diff --git a/automotive/can/1.0/default/libnl++/protocols/route/Link.h b/automotive/can/1.0/default/libnl++/protocols/route/Link.h index bcfce19795..4ea3ebaf72 100644 --- a/automotive/can/1.0/default/libnl++/protocols/route/Link.h +++ b/automotive/can/1.0/default/libnl++/protocols/route/Link.h @@ -20,7 +20,7 @@ #include -namespace android::netdevice::protocols::route { +namespace android::nl::protocols::route { class Link : public MessageDefinition { public: @@ -28,4 +28,4 @@ class Link : public MessageDefinition { void toStream(std::stringstream& ss, const struct ifinfomsg& data) const override; }; -} // namespace android::netdevice::protocols::route +} // namespace android::nl::protocols::route diff --git a/automotive/can/1.0/default/libnl++/protocols/route/Route.cpp b/automotive/can/1.0/default/libnl++/protocols/route/Route.cpp index 456072b84a..c134911525 100644 --- a/automotive/can/1.0/default/libnl++/protocols/route/Route.cpp +++ b/automotive/can/1.0/default/libnl++/protocols/route/Route.cpp @@ -18,8 +18,8 @@ #include "Link.h" -namespace android::netdevice::protocols::route { +namespace android::nl::protocols::route { Route::Route() : NetlinkProtocol(NETLINK_ROUTE, "ROUTE", {std::make_shared()}) {} -} // namespace android::netdevice::protocols::route +} // namespace android::nl::protocols::route diff --git a/automotive/can/1.0/default/libnl++/protocols/route/Route.h b/automotive/can/1.0/default/libnl++/protocols/route/Route.h index 3051cf93b4..433e610101 100644 --- a/automotive/can/1.0/default/libnl++/protocols/route/Route.h +++ b/automotive/can/1.0/default/libnl++/protocols/route/Route.h @@ -18,7 +18,7 @@ #include "../NetlinkProtocol.h" -namespace android::netdevice::protocols::route { +namespace android::nl::protocols::route { /** * Definition of NETLINK_ROUTE protocol. @@ -28,4 +28,4 @@ class Route : public NetlinkProtocol { Route(); }; -} // namespace android::netdevice::protocols::route +} // namespace android::nl::protocols::route diff --git a/automotive/can/1.0/default/libnl++/protocols/route/structs.cpp b/automotive/can/1.0/default/libnl++/protocols/route/structs.cpp index 48d64f0a4a..ea923bbd8c 100644 --- a/automotive/can/1.0/default/libnl++/protocols/route/structs.cpp +++ b/automotive/can/1.0/default/libnl++/protocols/route/structs.cpp @@ -16,7 +16,7 @@ #include "structs.h" -namespace android::netdevice::protocols::route { +namespace android::nl::protocols::route { void mapToStream(std::stringstream& ss, const nlbuf attr) { const auto& [ok, data] = attr.data().getFirst(); @@ -46,4 +46,4 @@ void ifla_cacheinfoToStream(std::stringstream& ss, const nlbuf attr) { << data.retrans_time << '}'; } -} // namespace android::netdevice::protocols::route +} // namespace android::nl::protocols::route diff --git a/automotive/can/1.0/default/libnl++/protocols/route/structs.h b/automotive/can/1.0/default/libnl++/protocols/route/structs.h index 2c1771b9e0..38776fad8b 100644 --- a/automotive/can/1.0/default/libnl++/protocols/route/structs.h +++ b/automotive/can/1.0/default/libnl++/protocols/route/structs.h @@ -22,7 +22,7 @@ #include -namespace android::netdevice::protocols::route { +namespace android::nl::protocols::route { // rtnl_link_ifmap void mapToStream(std::stringstream& ss, const nlbuf attr); @@ -75,4 +75,4 @@ void statsToStream(std::stringstream& ss, const nlbuf attr) { << data.rx_nohandler << '}'; } -} // namespace android::netdevice::protocols::route +} // namespace android::nl::protocols::route -- GitLab From ff985a85a8a66fcea861917929e5f103e0d16243 Mon Sep 17 00:00:00 2001 From: Dan Shi Date: Wed, 29 Jul 2020 09:45:03 -0700 Subject: [PATCH 085/790] Suppress gtest error for tests without any instance Bug: 162052785 Test: m -j vts Change-Id: I58bc808a82b2128bb8774f762f9b9fcecd2614fb --- .../vts/functional/VtsHalAudioControlV1_0TargetTest.cpp | 1 + .../vts/functional/VtsHalAudioControlV2_0TargetTest.cpp | 1 + .../can/1.0/vts/functional/VtsHalCanBusV1_0TargetTest.cpp | 7 ++++--- .../vts/functional/VtsHalCanBusVirtualV1_0TargetTest.cpp | 8 ++++---- .../vts/functional/VtsHalCanControllerV1_0TargetTest.cpp | 8 ++++---- .../evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp | 2 +- .../functional/VtsHalOccupantAwarenessV1_0TargetTest.cpp | 1 + .../vts/functional/VtsHalSurroundViewV1_0TargetTest.cpp | 1 + .../vts/functional/VtsHalBiometricsFaceV1_1TargetTest.cpp | 1 + .../VtsHalBiometricsFingerprintV2_2TargetTest.cpp | 1 + .../VtsHalBiometricsFingerprintV2_3TargetTest.cpp | 1 + .../vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp | 1 + cas/1.0/vts/functional/VtsHalCasV1_0TargetTest.cpp | 1 + cas/1.1/vts/functional/VtsHalCasV1_1TargetTest.cpp | 1 + cas/1.2/vts/functional/VtsHalCasV1_2TargetTest.cpp | 1 + .../1.0/vts/functional/VtsHalContexthubV1_0TargetTest.cpp | 2 ++ .../1.1/vts/functional/VtsHalContexthubV1_1TargetTest.cpp | 1 + drm/1.3/vts/functional/drm_hal_test_main.cpp | 7 +++++++ .../1.1/vts/functional/VtsHalDumpstateV1_1TargetTest.cpp | 2 ++ gnss/1.1/vts/functional/VtsHalGnssV1_1TargetTest.cpp | 1 + gnss/2.0/vts/functional/VtsHalGnssV2_0TargetTest.cpp | 1 + gnss/2.1/vts/functional/VtsHalGnssV2_1TargetTest.cpp | 1 + gnss/3.0/vts/functional/VtsHalGnssV3_0TargetTest.cpp | 1 + .../functional/VtsHalGraphicsComposerV2_1TargetTest.cpp | 2 ++ .../functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp | 2 ++ .../functional/VtsHalGraphicsComposerV2_2TargetTest.cpp | 2 ++ .../functional/VtsHalGraphicsComposerV2_3TargetTest.cpp | 2 ++ .../functional/VtsHalGraphicsComposerV2_4TargetTest.cpp | 2 ++ .../functional/VtsHalInputClassifierV1_0TargetTest.cpp | 1 + .../aidl/vts/functional/VtsHalRebootEscrowTargetTest.cpp | 1 + .../2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp | 1 + .../2.1/vts/functional/VtsHalSensorsV2_1TargetTest.cpp | 1 + .../vts/functional/VtsHalSoundtriggerV2_0TargetTest.cpp | 1 + .../vts/functional/VtsHalSoundtriggerV2_1TargetTest.cpp | 1 + .../vts/functional/VtsHalSoundtriggerV2_3TargetTest.cpp | 1 + usb/1.2/vts/functional/VtsHalUsbV1_2TargetTest.cpp | 1 + wifi/1.0/vts/functional/wifi_ap_iface_hidl_test.cpp | 1 + wifi/1.0/vts/functional/wifi_chip_hidl_ap_test.cpp | 1 + wifi/1.0/vts/functional/wifi_chip_hidl_nan_test.cpp | 1 + wifi/1.0/vts/functional/wifi_chip_hidl_test.cpp | 1 + wifi/1.0/vts/functional/wifi_hidl_test.cpp | 1 + wifi/1.0/vts/functional/wifi_nan_iface_hidl_test.cpp | 1 + wifi/1.0/vts/functional/wifi_p2p_iface_hidl_test.cpp | 1 + wifi/1.0/vts/functional/wifi_rtt_controller_hidl_test.cpp | 1 + wifi/1.0/vts/functional/wifi_sta_iface_hidl_test.cpp | 1 + wifi/1.1/vts/functional/wifi_chip_hidl_test.cpp | 1 + wifi/1.2/vts/functional/wifi_chip_hidl_test.cpp | 1 + wifi/1.2/vts/functional/wifi_nan_iface_hidl_test.cpp | 1 + wifi/1.2/vts/functional/wifi_sta_iface_hidl_test.cpp | 1 + wifi/1.3/vts/functional/wifi_chip_hidl_test.cpp | 1 + wifi/1.3/vts/functional/wifi_sta_iface_hidl_test.cpp | 1 + wifi/1.4/vts/functional/wifi_ap_iface_hidl_test.cpp | 1 + wifi/1.4/vts/functional/wifi_chip_hidl_test.cpp | 1 + wifi/1.4/vts/functional/wifi_nan_iface_hidl_test.cpp | 1 + wifi/1.4/vts/functional/wifi_rtt_controller_hidl_test.cpp | 1 + 55 files changed, 77 insertions(+), 12 deletions(-) diff --git a/automotive/audiocontrol/1.0/vts/functional/VtsHalAudioControlV1_0TargetTest.cpp b/automotive/audiocontrol/1.0/vts/functional/VtsHalAudioControlV1_0TargetTest.cpp index de1ec02072..982cf2c358 100644 --- a/automotive/audiocontrol/1.0/vts/functional/VtsHalAudioControlV1_0TargetTest.cpp +++ b/automotive/audiocontrol/1.0/vts/functional/VtsHalAudioControlV1_0TargetTest.cpp @@ -140,6 +140,7 @@ TEST_P(CarAudioControlHidlTest, ContextMapping) { EXPECT_EQ(bus, -1); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(CarAudioControlHidlTest); INSTANTIATE_TEST_SUITE_P( PerInstance, CarAudioControlHidlTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames(IAudioControl::descriptor)), diff --git a/automotive/audiocontrol/2.0/vts/functional/VtsHalAudioControlV2_0TargetTest.cpp b/automotive/audiocontrol/2.0/vts/functional/VtsHalAudioControlV2_0TargetTest.cpp index 0c106647c5..fa351430e3 100644 --- a/automotive/audiocontrol/2.0/vts/functional/VtsHalAudioControlV2_0TargetTest.cpp +++ b/automotive/audiocontrol/2.0/vts/functional/VtsHalAudioControlV2_0TargetTest.cpp @@ -149,6 +149,7 @@ TEST_P(CarAudioControlHidlTest, FocusChangeExercise) { AudioFocusChange::GAIN_TRANSIENT | 0); }; +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(CarAudioControlHidlTest); INSTANTIATE_TEST_SUITE_P( PerInstance, CarAudioControlHidlTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames(IAudioControl::descriptor)), diff --git a/automotive/can/1.0/vts/functional/VtsHalCanBusV1_0TargetTest.cpp b/automotive/can/1.0/vts/functional/VtsHalCanBusV1_0TargetTest.cpp index a8e7c0b633..d91d9f5035 100644 --- a/automotive/can/1.0/vts/functional/VtsHalCanBusV1_0TargetTest.cpp +++ b/automotive/can/1.0/vts/functional/VtsHalCanBusV1_0TargetTest.cpp @@ -176,8 +176,9 @@ TEST_P(CanBusHalTest, DontCloseErrorListener) { * adb shell /data/nativetest64/VtsHalCanBusV1_0TargetTest/VtsHalCanBusV1_0TargetTest\ * --gtest_filter=*_ */ -INSTANTIATE_TEST_SUITE_P( // - PerInstance, CanBusHalTest, testing::ValuesIn(getAllHalInstanceNames(ICanBus::descriptor)), - PrintInstanceNameToString); +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(CanBusHalTest); +INSTANTIATE_TEST_SUITE_P(PerInstance, CanBusHalTest, + testing::ValuesIn(getAllHalInstanceNames(ICanBus::descriptor)), + PrintInstanceNameToString); } // namespace android::hardware::automotive::can::V1_0::vts diff --git a/automotive/can/1.0/vts/functional/VtsHalCanBusVirtualV1_0TargetTest.cpp b/automotive/can/1.0/vts/functional/VtsHalCanBusVirtualV1_0TargetTest.cpp index 9039435458..8dfd7d6c4d 100644 --- a/automotive/can/1.0/vts/functional/VtsHalCanBusVirtualV1_0TargetTest.cpp +++ b/automotive/can/1.0/vts/functional/VtsHalCanBusVirtualV1_0TargetTest.cpp @@ -868,9 +868,9 @@ TEST_P(CanBusVirtualHalTest, FilterMixed) { * Example manual invocation: * adb shell /data/nativetest64/VtsHalCanBusVirtualV1_0TargetTest/VtsHalCanBusVirtualV1_0TargetTest */ -INSTANTIATE_TEST_SUITE_P( // - PerInstance, CanBusVirtualHalTest, - testing::ValuesIn(getAllHalInstanceNames(ICanController::descriptor)), - PrintInstanceNameToString); +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(CanBusVirtualHalTest); +INSTANTIATE_TEST_SUITE_P(PerInstance, CanBusVirtualHalTest, + testing::ValuesIn(getAllHalInstanceNames(ICanController::descriptor)), + PrintInstanceNameToString); } // namespace android::hardware::automotive::can::V1_0::vts diff --git a/automotive/can/1.0/vts/functional/VtsHalCanControllerV1_0TargetTest.cpp b/automotive/can/1.0/vts/functional/VtsHalCanControllerV1_0TargetTest.cpp index 8ef57589cd..b945978b0b 100644 --- a/automotive/can/1.0/vts/functional/VtsHalCanControllerV1_0TargetTest.cpp +++ b/automotive/can/1.0/vts/functional/VtsHalCanControllerV1_0TargetTest.cpp @@ -293,9 +293,9 @@ TEST_P(CanControllerHalTest, FailBadSlcanAddress) { * Example manual invocation: * adb shell /data/nativetest64/VtsHalCanControllerV1_0TargetTest/VtsHalCanControllerV1_0TargetTest */ -INSTANTIATE_TEST_SUITE_P( // - PerInstance, CanControllerHalTest, - testing::ValuesIn(getAllHalInstanceNames(ICanController::descriptor)), - PrintInstanceNameToString); +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(CanControllerHalTest); +INSTANTIATE_TEST_SUITE_P(PerInstance, CanControllerHalTest, + testing::ValuesIn(getAllHalInstanceNames(ICanController::descriptor)), + PrintInstanceNameToString); } // namespace android::hardware::automotive::can::V1_0::vts diff --git a/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp b/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp index 8b68fd6f0a..4398fb13e3 100644 --- a/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp +++ b/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp @@ -2471,7 +2471,7 @@ TEST_P(EvsHidlTest, UltrasonicsSetFramesInFlight) { } } - +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EvsHidlTest); INSTANTIATE_TEST_SUITE_P( PerInstance, EvsHidlTest, diff --git a/automotive/occupant_awareness/aidl/vts/functional/VtsHalOccupantAwarenessV1_0TargetTest.cpp b/automotive/occupant_awareness/aidl/vts/functional/VtsHalOccupantAwarenessV1_0TargetTest.cpp index c431f9d3b8..a1fd05aa17 100644 --- a/automotive/occupant_awareness/aidl/vts/functional/VtsHalOccupantAwarenessV1_0TargetTest.cpp +++ b/automotive/occupant_awareness/aidl/vts/functional/VtsHalOccupantAwarenessV1_0TargetTest.cpp @@ -190,6 +190,7 @@ TEST_P(OccupantAwarenessAidl, GetLatestDetectionTest) { ASSERT_LE(elapsed, kTimeout); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(OccupantAwarenessAidl); INSTANTIATE_TEST_SUITE_P( InstantiationName, OccupantAwarenessAidl, testing::ValuesIn(android::getAidlHalInstanceNames(IOccupantAwareness::descriptor)), diff --git a/automotive/sv/1.0/vts/functional/VtsHalSurroundViewV1_0TargetTest.cpp b/automotive/sv/1.0/vts/functional/VtsHalSurroundViewV1_0TargetTest.cpp index b1b9d16bc2..059d152bcf 100644 --- a/automotive/sv/1.0/vts/functional/VtsHalSurroundViewV1_0TargetTest.cpp +++ b/automotive/sv/1.0/vts/functional/VtsHalSurroundViewV1_0TargetTest.cpp @@ -1127,6 +1127,7 @@ TEST_P(SurroundViewHidlTest, projectPointsInvalidPointsFail) { mSurroundViewService->stop3dSession(surroundView3dSession); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SurroundViewHidlTest); INSTANTIATE_TEST_SUITE_P( PerInstance, SurroundViewHidlTest, diff --git a/biometrics/face/1.1/vts/functional/VtsHalBiometricsFaceV1_1TargetTest.cpp b/biometrics/face/1.1/vts/functional/VtsHalBiometricsFaceV1_1TargetTest.cpp index a105d8f8fd..0077c8c728 100644 --- a/biometrics/face/1.1/vts/functional/VtsHalBiometricsFaceV1_1TargetTest.cpp +++ b/biometrics/face/1.1/vts/functional/VtsHalBiometricsFaceV1_1TargetTest.cpp @@ -199,6 +199,7 @@ TEST_P(FaceHidlTest, EnrollRemotelyGarbageHatTest) { } // anonymous namespace +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(FaceHidlTest); INSTANTIATE_TEST_SUITE_P( PerInstance, FaceHidlTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames(IBiometricsFace::descriptor)), diff --git a/biometrics/fingerprint/2.2/vts/functional/VtsHalBiometricsFingerprintV2_2TargetTest.cpp b/biometrics/fingerprint/2.2/vts/functional/VtsHalBiometricsFingerprintV2_2TargetTest.cpp index df29fd4179..e0789ce11b 100644 --- a/biometrics/fingerprint/2.2/vts/functional/VtsHalBiometricsFingerprintV2_2TargetTest.cpp +++ b/biometrics/fingerprint/2.2/vts/functional/VtsHalBiometricsFingerprintV2_2TargetTest.cpp @@ -136,6 +136,7 @@ TEST_P(FingerprintHidlTest, acquiredInfoStartTest) { } // anonymous namespace +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(FingerprintHidlTest); INSTANTIATE_TEST_SUITE_P(PerInstance, FingerprintHidlTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames( IBiometricsFingerprint::descriptor)), diff --git a/biometrics/fingerprint/2.3/vts/functional/VtsHalBiometricsFingerprintV2_3TargetTest.cpp b/biometrics/fingerprint/2.3/vts/functional/VtsHalBiometricsFingerprintV2_3TargetTest.cpp index 72420162f0..d2a08a0360 100644 --- a/biometrics/fingerprint/2.3/vts/functional/VtsHalBiometricsFingerprintV2_3TargetTest.cpp +++ b/biometrics/fingerprint/2.3/vts/functional/VtsHalBiometricsFingerprintV2_3TargetTest.cpp @@ -62,6 +62,7 @@ TEST_P(FingerprintHidlTest, onFingerUp) { } // anonymous namespace +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(FingerprintHidlTest); INSTANTIATE_TEST_SUITE_P(PerInstance, FingerprintHidlTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames( IBiometricsFingerprint::descriptor)), diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp index f235235ab7..384edf3d05 100644 --- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp +++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp @@ -7584,6 +7584,7 @@ void CameraHidlTest::verifyRequestTemplate(const camera_metadata_t* metadata, } } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(CameraHidlTest); INSTANTIATE_TEST_SUITE_P( PerInstance, CameraHidlTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames(ICameraProvider::descriptor)), diff --git a/cas/1.0/vts/functional/VtsHalCasV1_0TargetTest.cpp b/cas/1.0/vts/functional/VtsHalCasV1_0TargetTest.cpp index 0f16de5e90..7f5d98888a 100644 --- a/cas/1.0/vts/functional/VtsHalCasV1_0TargetTest.cpp +++ b/cas/1.0/vts/functional/VtsHalCasV1_0TargetTest.cpp @@ -837,6 +837,7 @@ TEST_P(MediaCasHidlTest, TestClearKeyOobFails) { } // anonymous namespace +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MediaCasHidlTest); INSTANTIATE_TEST_SUITE_P( PerInstance, MediaCasHidlTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames(IMediaCasService::descriptor)), diff --git a/cas/1.1/vts/functional/VtsHalCasV1_1TargetTest.cpp b/cas/1.1/vts/functional/VtsHalCasV1_1TargetTest.cpp index 1b5797b845..b657f07c1a 100644 --- a/cas/1.1/vts/functional/VtsHalCasV1_1TargetTest.cpp +++ b/cas/1.1/vts/functional/VtsHalCasV1_1TargetTest.cpp @@ -549,6 +549,7 @@ TEST_P(MediaCasHidlTest, TestClearKeyApisWithSession) { } // anonymous namespace +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MediaCasHidlTest); INSTANTIATE_TEST_SUITE_P( PerInstance, MediaCasHidlTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames(IMediaCasService::descriptor)), diff --git a/cas/1.2/vts/functional/VtsHalCasV1_2TargetTest.cpp b/cas/1.2/vts/functional/VtsHalCasV1_2TargetTest.cpp index 58e0f2e0a8..f436b8b5ee 100644 --- a/cas/1.2/vts/functional/VtsHalCasV1_2TargetTest.cpp +++ b/cas/1.2/vts/functional/VtsHalCasV1_2TargetTest.cpp @@ -597,6 +597,7 @@ TEST_P(MediaCasHidlTest, TestClearKeyApisWithSession) { } // anonymous namespace +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MediaCasHidlTest); INSTANTIATE_TEST_SUITE_P( PerInstance, MediaCasHidlTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames(IMediaCasService::descriptor)), diff --git a/contexthub/1.0/vts/functional/VtsHalContexthubV1_0TargetTest.cpp b/contexthub/1.0/vts/functional/VtsHalContexthubV1_0TargetTest.cpp index ada232b9fc..8a90173bf1 100644 --- a/contexthub/1.0/vts/functional/VtsHalContexthubV1_0TargetTest.cpp +++ b/contexthub/1.0/vts/functional/VtsHalContexthubV1_0TargetTest.cpp @@ -261,9 +261,11 @@ TEST_P(ContexthubTxnTest, TestDisableNonexistentNanoApp) { EXPECT_TRUE(checkFailureSyncOrAsync(result, Result::BAD_PARAMS, cb->promise.get_future())); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ContexthubHidlTest); INSTANTIATE_TEST_SUITE_P(HubIdSpecificTests, ContexthubHidlTest, testing::ValuesIn(kTestParameters), android::hardware::PrintInstanceTupleNameToString<>); +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ContexthubTxnTest); INSTANTIATE_TEST_SUITE_P(HubIdSpecificTests, ContexthubTxnTest, testing::ValuesIn(kTestParameters), android::hardware::PrintInstanceTupleNameToString<>); diff --git a/contexthub/1.1/vts/functional/VtsHalContexthubV1_1TargetTest.cpp b/contexthub/1.1/vts/functional/VtsHalContexthubV1_1TargetTest.cpp index f2fcdfca48..5f1dad97cb 100644 --- a/contexthub/1.1/vts/functional/VtsHalContexthubV1_1TargetTest.cpp +++ b/contexthub/1.1/vts/functional/VtsHalContexthubV1_1TargetTest.cpp @@ -54,6 +54,7 @@ TEST_P(ContexthubHidlTest, TestOnSettingChanged) { ASSERT_OK(registerCallback(nullptr)); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ContexthubHidlTest); INSTANTIATE_TEST_SUITE_P(HubIdSpecificTests, ContexthubHidlTest, testing::ValuesIn(kTestParameters), android::hardware::PrintInstanceTupleNameToString<>); diff --git a/drm/1.3/vts/functional/drm_hal_test_main.cpp b/drm/1.3/vts/functional/drm_hal_test_main.cpp index 02b45ea6b9..746f09ee0b 100644 --- a/drm/1.3/vts/functional/drm_hal_test_main.cpp +++ b/drm/1.3/vts/functional/drm_hal_test_main.cpp @@ -91,27 +91,34 @@ INSTANTIATE_TEST_CASE_P(PerInstanceUuidV1_0, DrmHalVendorDecryptTest, testing::ValuesIn(kAllInstances), drm_vts::PrintParamInstanceToString); +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DrmHalClearkeyFactoryTest); INSTANTIATE_TEST_SUITE_P(PerInstanceUuidV1_0, DrmHalClearkeyFactoryTest, testing::ValuesIn(kAllInstances), drm_vts::PrintParamInstanceToString); +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DrmHalClearkeyPluginTest); INSTANTIATE_TEST_SUITE_P(PerInstanceUuidV1_0, DrmHalClearkeyPluginTest, testing::ValuesIn(kAllInstances), drm_vts::PrintParamInstanceToString); +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DrmHalClearkeyDecryptTest); INSTANTIATE_TEST_SUITE_P(PerInstanceUuidV1_0, DrmHalClearkeyDecryptTest, testing::ValuesIn(kAllInstances), drm_vts::PrintParamInstanceToString); +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DrmHalClearkeyTest); INSTANTIATE_TEST_SUITE_P(PerInstanceUuidV1_1, DrmHalClearkeyTest, testing::ValuesIn(kAllInstances), PrintParamInstanceToString); +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DrmHalTest); INSTANTIATE_TEST_SUITE_P(PerInstanceUuidV1_2, DrmHalTest, testing::ValuesIn(kAllInstances), PrintParamInstanceToString); +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DrmHalClearkeyTestV1_2); INSTANTIATE_TEST_SUITE_P(PerInstanceUuidV1_2, DrmHalClearkeyTestV1_2, testing::ValuesIn(kAllInstances), PrintParamInstanceToString); +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DrmHalTestV1_3); INSTANTIATE_TEST_SUITE_P(PerInstanceUuidV1_3, DrmHalTestV1_3, testing::ValuesIn(kAllInstances), PrintParamInstanceToString); diff --git a/dumpstate/1.1/vts/functional/VtsHalDumpstateV1_1TargetTest.cpp b/dumpstate/1.1/vts/functional/VtsHalDumpstateV1_1TargetTest.cpp index 1bef66358a..dac43e35b6 100644 --- a/dumpstate/1.1/vts/functional/VtsHalDumpstateV1_1TargetTest.cpp +++ b/dumpstate/1.1/vts/functional/VtsHalDumpstateV1_1TargetTest.cpp @@ -321,6 +321,7 @@ TEST_P(DumpstateHidl1_1GeneralTest, TestRepeatedToggle) { DisableVerboseLogging(); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DumpstateHidl1_1GeneralTest); INSTANTIATE_TEST_SUITE_P( PerInstance, DumpstateHidl1_1GeneralTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames(IDumpstateDevice::descriptor)), @@ -334,6 +335,7 @@ static inline std::string PrintInstanceNameToStringWithMode( "_" + toString(std::get<1>(info.param)); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DumpstateHidl1_1PerModeTest); INSTANTIATE_TEST_SUITE_P( PerInstanceAndMode, DumpstateHidl1_1PerModeTest, testing::Combine(testing::ValuesIn(android::hardware::getAllHalInstanceNames( diff --git a/gnss/1.1/vts/functional/VtsHalGnssV1_1TargetTest.cpp b/gnss/1.1/vts/functional/VtsHalGnssV1_1TargetTest.cpp index 4a0a7f9ffa..e33ff58dd1 100644 --- a/gnss/1.1/vts/functional/VtsHalGnssV1_1TargetTest.cpp +++ b/gnss/1.1/vts/functional/VtsHalGnssV1_1TargetTest.cpp @@ -23,6 +23,7 @@ using android::hardware::gnss::V1_1::IGnss; +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GnssHalTest); INSTANTIATE_TEST_SUITE_P( PerInstance, GnssHalTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames(IGnss::descriptor)), diff --git a/gnss/2.0/vts/functional/VtsHalGnssV2_0TargetTest.cpp b/gnss/2.0/vts/functional/VtsHalGnssV2_0TargetTest.cpp index 2c74fa37be..54f5652084 100644 --- a/gnss/2.0/vts/functional/VtsHalGnssV2_0TargetTest.cpp +++ b/gnss/2.0/vts/functional/VtsHalGnssV2_0TargetTest.cpp @@ -23,6 +23,7 @@ using android::hardware::gnss::V2_0::IGnss; +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GnssHalTest); INSTANTIATE_TEST_SUITE_P( PerInstance, GnssHalTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames(IGnss::descriptor)), diff --git a/gnss/2.1/vts/functional/VtsHalGnssV2_1TargetTest.cpp b/gnss/2.1/vts/functional/VtsHalGnssV2_1TargetTest.cpp index e61d885654..89a9781125 100644 --- a/gnss/2.1/vts/functional/VtsHalGnssV2_1TargetTest.cpp +++ b/gnss/2.1/vts/functional/VtsHalGnssV2_1TargetTest.cpp @@ -23,6 +23,7 @@ using android::hardware::gnss::V2_1::IGnss; +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GnssHalTest); INSTANTIATE_TEST_SUITE_P( PerInstance, GnssHalTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames(IGnss::descriptor)), diff --git a/gnss/3.0/vts/functional/VtsHalGnssV3_0TargetTest.cpp b/gnss/3.0/vts/functional/VtsHalGnssV3_0TargetTest.cpp index 9eca7b0620..31e6164f9e 100644 --- a/gnss/3.0/vts/functional/VtsHalGnssV3_0TargetTest.cpp +++ b/gnss/3.0/vts/functional/VtsHalGnssV3_0TargetTest.cpp @@ -23,6 +23,7 @@ using android::hardware::gnss::V3_0::IGnss; +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GnssHalTest); INSTANTIATE_TEST_SUITE_P( PerInstance, GnssHalTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames(IGnss::descriptor)), diff --git a/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp b/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp index b92279d45f..4fee560def 100644 --- a/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp +++ b/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp @@ -1083,11 +1083,13 @@ TEST_P(GraphicsComposerHidlCommandTest, SET_LAYER_Z_ORDER) { execute(); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerHidlCommandTest); INSTANTIATE_TEST_SUITE_P( PerInstance, GraphicsComposerHidlCommandTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames(IComposer::descriptor)), android::hardware::PrintInstanceNameToString); +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerHidlTest); INSTANTIATE_TEST_SUITE_P( PerInstance, GraphicsComposerHidlTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames(IComposer::descriptor)), diff --git a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp index cb43e64c81..26163fd1a4 100644 --- a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp +++ b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp @@ -1381,6 +1381,7 @@ TEST_P(GraphicsTransformCompositionTest, ROT_180) { } } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsCompositionTest); INSTANTIATE_TEST_SUITE_P( PerInstance, GraphicsCompositionTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames(IComposer::descriptor)), @@ -1393,6 +1394,7 @@ INSTANTIATE_TEST_CASE_P( testing::Values("0.2", "1.0")), android::hardware::PrintInstanceTupleNameToString<>); +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsTransformCompositionTest); INSTANTIATE_TEST_SUITE_P( PerInstance, GraphicsTransformCompositionTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames(IComposer::descriptor)), diff --git a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp index 95a0f69c32..4d7df1c0e0 100644 --- a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp +++ b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp @@ -681,11 +681,13 @@ TEST_P(GraphicsComposerHidlTest, SetColorMode_2_2BadParameter) { EXPECT_EQ(Error::BAD_PARAMETER, renderIntentError); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerHidlTest); INSTANTIATE_TEST_SUITE_P( PerInstance, GraphicsComposerHidlTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames(IComposer::descriptor)), android::hardware::PrintInstanceNameToString); +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerHidlCommandTest); INSTANTIATE_TEST_SUITE_P( PerInstance, GraphicsComposerHidlCommandTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames(IComposer::descriptor)), diff --git a/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp b/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp index 94766af480..a4c1b63f3c 100644 --- a/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp +++ b/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp @@ -611,11 +611,13 @@ TEST_P(GraphicsComposerHidlTest, setDisplayBrightness) { EXPECT_EQ(mComposerClient->setDisplayBrightness(mPrimaryDisplay, -2.0f), Error::BAD_PARAMETER); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerHidlTest); INSTANTIATE_TEST_SUITE_P( PerInstance, GraphicsComposerHidlTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames(IComposer::descriptor)), android::hardware::PrintInstanceNameToString); +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerHidlCommandTest); INSTANTIATE_TEST_SUITE_P( PerInstance, GraphicsComposerHidlCommandTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames(IComposer::descriptor)), diff --git a/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp b/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp index f0de4f7932..e6ecf933b3 100644 --- a/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp +++ b/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp @@ -644,11 +644,13 @@ TEST_P(GraphicsComposerHidlTest, setGameContentType) { Test_setContentType(ContentType::GAME, "GAME"); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerHidlTest); INSTANTIATE_TEST_SUITE_P( PerInstance, GraphicsComposerHidlTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames(IComposer::descriptor)), android::hardware::PrintInstanceNameToString); +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerHidlCommandTest); INSTANTIATE_TEST_SUITE_P( PerInstance, GraphicsComposerHidlCommandTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames(IComposer::descriptor)), diff --git a/input/classifier/1.0/vts/functional/VtsHalInputClassifierV1_0TargetTest.cpp b/input/classifier/1.0/vts/functional/VtsHalInputClassifierV1_0TargetTest.cpp index ee529c73b0..186e406aca 100644 --- a/input/classifier/1.0/vts/functional/VtsHalInputClassifierV1_0TargetTest.cpp +++ b/input/classifier/1.0/vts/functional/VtsHalInputClassifierV1_0TargetTest.cpp @@ -168,6 +168,7 @@ TEST_P(InputClassifierHidlTest_1_0, Classify_TwoVideoFrames) { classifier->reset(); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(InputClassifierHidlTest_1_0); INSTANTIATE_TEST_SUITE_P( PerInstance, InputClassifierHidlTest_1_0, testing::ValuesIn(android::hardware::getAllHalInstanceNames(IInputClassifier::descriptor)), diff --git a/rebootescrow/aidl/vts/functional/VtsHalRebootEscrowTargetTest.cpp b/rebootescrow/aidl/vts/functional/VtsHalRebootEscrowTargetTest.cpp index 809a3b502a..28357a1a1e 100644 --- a/rebootescrow/aidl/vts/functional/VtsHalRebootEscrowTargetTest.cpp +++ b/rebootescrow/aidl/vts/functional/VtsHalRebootEscrowTargetTest.cpp @@ -123,6 +123,7 @@ TEST_P(RebootEscrowAidlTest, Store_Success) { rebootescrow->storeKey(KEY_1); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(RebootEscrowAidlTest); INSTANTIATE_TEST_SUITE_P( RebootEscrow, RebootEscrowAidlTest, testing::ValuesIn(android::getAidlHalInstanceNames(IRebootEscrow::descriptor)), diff --git a/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp b/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp index a0d436f3f9..e212423fa7 100644 --- a/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp +++ b/sensors/2.0/vts/functional/VtsHalSensorsV2_0TargetTest.cpp @@ -296,6 +296,7 @@ TEST_P(SensorsHidlTest, FlushNonexistentSensor) { 0 /* expectedFlushCount */, Result::BAD_VALUE); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SensorsHidlTest); INSTANTIATE_TEST_SUITE_P(PerInstance, SensorsHidlTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames( android::hardware::sensors::V2_0::ISensors::descriptor)), diff --git a/sensors/2.1/vts/functional/VtsHalSensorsV2_1TargetTest.cpp b/sensors/2.1/vts/functional/VtsHalSensorsV2_1TargetTest.cpp index 230bb6c2f1..3a866b1603 100644 --- a/sensors/2.1/vts/functional/VtsHalSensorsV2_1TargetTest.cpp +++ b/sensors/2.1/vts/functional/VtsHalSensorsV2_1TargetTest.cpp @@ -16,6 +16,7 @@ #include "VtsHalSensorsV2_XTargetTest.h" +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SensorsHidlTest); INSTANTIATE_TEST_SUITE_P(PerInstance, SensorsHidlTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames( android::hardware::sensors::V2_1::ISensors::descriptor)), diff --git a/soundtrigger/2.0/vts/functional/VtsHalSoundtriggerV2_0TargetTest.cpp b/soundtrigger/2.0/vts/functional/VtsHalSoundtriggerV2_0TargetTest.cpp index 63edec570a..0065dbc236 100644 --- a/soundtrigger/2.0/vts/functional/VtsHalSoundtriggerV2_0TargetTest.cpp +++ b/soundtrigger/2.0/vts/functional/VtsHalSoundtriggerV2_0TargetTest.cpp @@ -293,6 +293,7 @@ TEST_P(SoundTriggerHidlTest, StopRecognitionNoAStartFail) { EXPECT_NE(0, hidlReturn); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SoundTriggerHidlTest); INSTANTIATE_TEST_SUITE_P( PerInstance, SoundTriggerHidlTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames(ISoundTriggerHw::descriptor)), diff --git a/soundtrigger/2.1/vts/functional/VtsHalSoundtriggerV2_1TargetTest.cpp b/soundtrigger/2.1/vts/functional/VtsHalSoundtriggerV2_1TargetTest.cpp index 392679d0cb..91b8da861d 100644 --- a/soundtrigger/2.1/vts/functional/VtsHalSoundtriggerV2_1TargetTest.cpp +++ b/soundtrigger/2.1/vts/functional/VtsHalSoundtriggerV2_1TargetTest.cpp @@ -317,6 +317,7 @@ TEST_P(SoundTriggerHidlTest, StartRecognitionNoModelFail_2_1) { EXPECT_NE(0, hidlReturn); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SoundTriggerHidlTest); INSTANTIATE_TEST_SUITE_P( PerInstance, SoundTriggerHidlTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames(ISoundTriggerHw::descriptor)), diff --git a/soundtrigger/2.3/vts/functional/VtsHalSoundtriggerV2_3TargetTest.cpp b/soundtrigger/2.3/vts/functional/VtsHalSoundtriggerV2_3TargetTest.cpp index 2d147e4606..50646d47c8 100644 --- a/soundtrigger/2.3/vts/functional/VtsHalSoundtriggerV2_3TargetTest.cpp +++ b/soundtrigger/2.3/vts/functional/VtsHalSoundtriggerV2_3TargetTest.cpp @@ -84,6 +84,7 @@ TEST_P(SoundTriggerHidlTest, GetProperties_2_3) { (AudioCapabilities::ECHO_CANCELLATION | AudioCapabilities::NOISE_SUPPRESSION)); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SoundTriggerHidlTest); INSTANTIATE_TEST_SUITE_P( PerInstance, SoundTriggerHidlTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames(ISoundTriggerHw::descriptor)), diff --git a/usb/1.2/vts/functional/VtsHalUsbV1_2TargetTest.cpp b/usb/1.2/vts/functional/VtsHalUsbV1_2TargetTest.cpp index 5f901cd4f6..0123d58d84 100644 --- a/usb/1.2/vts/functional/VtsHalUsbV1_2TargetTest.cpp +++ b/usb/1.2/vts/functional/VtsHalUsbV1_2TargetTest.cpp @@ -360,6 +360,7 @@ TEST_P(UsbHidlTest, contaminantPresenceProtectionStability) { if (!supported) EXPECT_GE(successCount, 9); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(UsbHidlTest); INSTANTIATE_TEST_SUITE_P( PerInstance, UsbHidlTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames(IUsb::descriptor)), diff --git a/wifi/1.0/vts/functional/wifi_ap_iface_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_ap_iface_hidl_test.cpp index 3599b94075..96b4501360 100644 --- a/wifi/1.0/vts/functional/wifi_ap_iface_hidl_test.cpp +++ b/wifi/1.0/vts/functional/wifi_ap_iface_hidl_test.cpp @@ -94,6 +94,7 @@ TEST_P(WifiApIfaceHidlTest, GetValidFrequenciesForBand) { EXPECT_GT(status_and_freqs.second.size(), 0u); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiApIfaceHidlTest); INSTANTIATE_TEST_SUITE_P( PerInstance, WifiApIfaceHidlTest, testing::ValuesIn( diff --git a/wifi/1.0/vts/functional/wifi_chip_hidl_ap_test.cpp b/wifi/1.0/vts/functional/wifi_chip_hidl_ap_test.cpp index 5a2c6a740e..2e6ad32d64 100644 --- a/wifi/1.0/vts/functional/wifi_chip_hidl_ap_test.cpp +++ b/wifi/1.0/vts/functional/wifi_chip_hidl_ap_test.cpp @@ -176,6 +176,7 @@ TEST_P(WifiChipHidlApTest, RemoveApIface) { EXPECT_EQ(WifiStatusCode::ERROR_INVALID_ARGS, removeApIface(iface_name)); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiChipHidlApTest); INSTANTIATE_TEST_SUITE_P( PerInstance, WifiChipHidlApTest, testing::ValuesIn( diff --git a/wifi/1.0/vts/functional/wifi_chip_hidl_nan_test.cpp b/wifi/1.0/vts/functional/wifi_chip_hidl_nan_test.cpp index bb7a3a6797..49a25e5cfa 100644 --- a/wifi/1.0/vts/functional/wifi_chip_hidl_nan_test.cpp +++ b/wifi/1.0/vts/functional/wifi_chip_hidl_nan_test.cpp @@ -181,6 +181,7 @@ TEST_P(WifiChipHidlNanTest, RemoveNanIface) { EXPECT_EQ(WifiStatusCode::ERROR_INVALID_ARGS, removeNanIface(iface_name)); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiChipHidlNanTest); INSTANTIATE_TEST_SUITE_P( PerInstance, WifiChipHidlNanTest, testing::ValuesIn( diff --git a/wifi/1.0/vts/functional/wifi_chip_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_chip_hidl_test.cpp index 53131cee78..b17d2ad1be 100644 --- a/wifi/1.0/vts/functional/wifi_chip_hidl_test.cpp +++ b/wifi/1.0/vts/functional/wifi_chip_hidl_test.cpp @@ -552,6 +552,7 @@ TEST_P(WifiChipHidlTest, CreateRttController) { } } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiChipHidlTest); INSTANTIATE_TEST_SUITE_P( PerInstance, WifiChipHidlTest, testing::ValuesIn( diff --git a/wifi/1.0/vts/functional/wifi_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_hidl_test.cpp index f3c82da3e9..109d116011 100644 --- a/wifi/1.0/vts/functional/wifi_hidl_test.cpp +++ b/wifi/1.0/vts/functional/wifi_hidl_test.cpp @@ -52,6 +52,7 @@ TEST_P(WifiHidlTest, Create) { // The creation of a proxy object is tested as part of SetUp method. } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiHidlTest); INSTANTIATE_TEST_SUITE_P( PerInstance, WifiHidlTest, testing::ValuesIn( diff --git a/wifi/1.0/vts/functional/wifi_nan_iface_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_nan_iface_hidl_test.cpp index 2b63ddc4cf..17abbd7096 100644 --- a/wifi/1.0/vts/functional/wifi_nan_iface_hidl_test.cpp +++ b/wifi/1.0/vts/functional/wifi_nan_iface_hidl_test.cpp @@ -509,6 +509,7 @@ TEST_P(WifiNanIfaceHidlTest, getCapabilitiesRequest) { EXPECT_NE(capabilities.supportedCipherSuites, (unsigned int)0); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiNanIfaceHidlTest); INSTANTIATE_TEST_SUITE_P( PerInstance, WifiNanIfaceHidlTest, testing::ValuesIn( diff --git a/wifi/1.0/vts/functional/wifi_p2p_iface_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_p2p_iface_hidl_test.cpp index fd175f5218..ce525f00e9 100644 --- a/wifi/1.0/vts/functional/wifi_p2p_iface_hidl_test.cpp +++ b/wifi/1.0/vts/functional/wifi_p2p_iface_hidl_test.cpp @@ -54,6 +54,7 @@ TEST_P(WifiP2pIfaceHidlTest, Create) { EXPECT_NE(nullptr, getWifiP2pIface(GetInstanceName()).get()); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiP2pIfaceHidlTest); INSTANTIATE_TEST_SUITE_P( PerInstance, WifiP2pIfaceHidlTest, testing::ValuesIn( diff --git a/wifi/1.0/vts/functional/wifi_rtt_controller_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_rtt_controller_hidl_test.cpp index 3c9ed9ee23..b1a918d545 100644 --- a/wifi/1.0/vts/functional/wifi_rtt_controller_hidl_test.cpp +++ b/wifi/1.0/vts/functional/wifi_rtt_controller_hidl_test.cpp @@ -76,6 +76,7 @@ TEST_P(WifiRttControllerHidlTest, Create) { } } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiRttControllerHidlTest); INSTANTIATE_TEST_SUITE_P( PerInstance, WifiRttControllerHidlTest, testing::ValuesIn( diff --git a/wifi/1.0/vts/functional/wifi_sta_iface_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_sta_iface_hidl_test.cpp index e311c846e8..08d81ff3d8 100644 --- a/wifi/1.0/vts/functional/wifi_sta_iface_hidl_test.cpp +++ b/wifi/1.0/vts/functional/wifi_sta_iface_hidl_test.cpp @@ -298,6 +298,7 @@ TEST_P(WifiStaIfaceHidlTest, PacketFateMonitoring) { HIDL_INVOKE(wifi_sta_iface_, getDebugRxPacketFates).first.code); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiStaIfaceHidlTest); INSTANTIATE_TEST_SUITE_P( PerInstance, WifiStaIfaceHidlTest, testing::ValuesIn( diff --git a/wifi/1.1/vts/functional/wifi_chip_hidl_test.cpp b/wifi/1.1/vts/functional/wifi_chip_hidl_test.cpp index 4b94acb258..68c29659b5 100644 --- a/wifi/1.1/vts/functional/wifi_chip_hidl_test.cpp +++ b/wifi/1.1/vts/functional/wifi_chip_hidl_test.cpp @@ -114,6 +114,7 @@ TEST_P(WifiChipHidlTest, ResetTxPowerScenario) { } } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiChipHidlTest); INSTANTIATE_TEST_SUITE_P( PerInstance, WifiChipHidlTest, testing::ValuesIn( diff --git a/wifi/1.2/vts/functional/wifi_chip_hidl_test.cpp b/wifi/1.2/vts/functional/wifi_chip_hidl_test.cpp index b04acadef9..8d91a23bfb 100644 --- a/wifi/1.2/vts/functional/wifi_chip_hidl_test.cpp +++ b/wifi/1.2/vts/functional/wifi_chip_hidl_test.cpp @@ -186,6 +186,7 @@ TEST_P(WifiChipHidlTest, registerEventCallback_1_2) { } } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiChipHidlTest); INSTANTIATE_TEST_SUITE_P( PerInstance, WifiChipHidlTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames( diff --git a/wifi/1.2/vts/functional/wifi_nan_iface_hidl_test.cpp b/wifi/1.2/vts/functional/wifi_nan_iface_hidl_test.cpp index bc392a91ec..f1c751eea1 100644 --- a/wifi/1.2/vts/functional/wifi_nan_iface_hidl_test.cpp +++ b/wifi/1.2/vts/functional/wifi_nan_iface_hidl_test.cpp @@ -559,6 +559,7 @@ TEST_P(WifiNanIfaceHidlTest, configRequest_1_2ShimInvalidArgs) { } } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiNanIfaceHidlTest); INSTANTIATE_TEST_SUITE_P( PerInstance, WifiNanIfaceHidlTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames( diff --git a/wifi/1.2/vts/functional/wifi_sta_iface_hidl_test.cpp b/wifi/1.2/vts/functional/wifi_sta_iface_hidl_test.cpp index 066dcaae87..cfa67d43bb 100644 --- a/wifi/1.2/vts/functional/wifi_sta_iface_hidl_test.cpp +++ b/wifi/1.2/vts/functional/wifi_sta_iface_hidl_test.cpp @@ -117,6 +117,7 @@ TEST_P(WifiStaIfaceHidlTest, DISABLED_ReadApfPacketFilterData) { EXPECT_EQ(status_and_data.second, data); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiStaIfaceHidlTest); INSTANTIATE_TEST_SUITE_P( PerInstance, WifiStaIfaceHidlTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames( diff --git a/wifi/1.3/vts/functional/wifi_chip_hidl_test.cpp b/wifi/1.3/vts/functional/wifi_chip_hidl_test.cpp index e99b34a7f8..361a87079f 100644 --- a/wifi/1.3/vts/functional/wifi_chip_hidl_test.cpp +++ b/wifi/1.3/vts/functional/wifi_chip_hidl_test.cpp @@ -125,6 +125,7 @@ TEST_P(WifiChipHidlTest, GetCapabilities_1_3) { EXPECT_NE(0u, status_and_caps.second); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiChipHidlTest); INSTANTIATE_TEST_SUITE_P( PerInstance, WifiChipHidlTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames( diff --git a/wifi/1.3/vts/functional/wifi_sta_iface_hidl_test.cpp b/wifi/1.3/vts/functional/wifi_sta_iface_hidl_test.cpp index 41d4ebbcb1..22efe0875a 100644 --- a/wifi/1.3/vts/functional/wifi_sta_iface_hidl_test.cpp +++ b/wifi/1.3/vts/functional/wifi_sta_iface_hidl_test.cpp @@ -104,6 +104,7 @@ TEST_P(WifiStaIfaceHidlTest, GetLinkLayerStats_1_3) { HIDL_INVOKE(wifi_sta_iface_, disableLinkLayerStatsCollection).code); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiStaIfaceHidlTest); INSTANTIATE_TEST_SUITE_P( PerInstance, WifiStaIfaceHidlTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames( diff --git a/wifi/1.4/vts/functional/wifi_ap_iface_hidl_test.cpp b/wifi/1.4/vts/functional/wifi_ap_iface_hidl_test.cpp index aff0ef741f..fc7dcd641c 100644 --- a/wifi/1.4/vts/functional/wifi_ap_iface_hidl_test.cpp +++ b/wifi/1.4/vts/functional/wifi_ap_iface_hidl_test.cpp @@ -77,6 +77,7 @@ TEST_P(WifiApIfaceHidlTest, GetFactoryMacAddress) { EXPECT_NE(all_zero, status_and_mac.second); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiApIfaceHidlTest); INSTANTIATE_TEST_SUITE_P( PerInstance, WifiApIfaceHidlTest, testing::ValuesIn( diff --git a/wifi/1.4/vts/functional/wifi_chip_hidl_test.cpp b/wifi/1.4/vts/functional/wifi_chip_hidl_test.cpp index be5c3bde9e..e8a2d0a4d6 100644 --- a/wifi/1.4/vts/functional/wifi_chip_hidl_test.cpp +++ b/wifi/1.4/vts/functional/wifi_chip_hidl_test.cpp @@ -150,6 +150,7 @@ TEST_P(WifiChipHidlTest, registerEventCallback_1_4) { } } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiChipHidlTest); INSTANTIATE_TEST_SUITE_P( PerInstance, WifiChipHidlTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames( diff --git a/wifi/1.4/vts/functional/wifi_nan_iface_hidl_test.cpp b/wifi/1.4/vts/functional/wifi_nan_iface_hidl_test.cpp index f6a1147e0d..9b69f57233 100644 --- a/wifi/1.4/vts/functional/wifi_nan_iface_hidl_test.cpp +++ b/wifi/1.4/vts/functional/wifi_nan_iface_hidl_test.cpp @@ -549,6 +549,7 @@ TEST_P(WifiNanIfaceHidlTest, configRequest_1_4ShimInvalidArgs) { .code); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiNanIfaceHidlTest); INSTANTIATE_TEST_SUITE_P( PerInstance, WifiNanIfaceHidlTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames( diff --git a/wifi/1.4/vts/functional/wifi_rtt_controller_hidl_test.cpp b/wifi/1.4/vts/functional/wifi_rtt_controller_hidl_test.cpp index a099c8afd5..902b2f01f5 100644 --- a/wifi/1.4/vts/functional/wifi_rtt_controller_hidl_test.cpp +++ b/wifi/1.4/vts/functional/wifi_rtt_controller_hidl_test.cpp @@ -240,6 +240,7 @@ TEST_P(WifiRttControllerHidlTest, EnableResponder_1_4) { EXPECT_EQ(WifiStatusCode::SUCCESS, status.code); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiRttControllerHidlTest); INSTANTIATE_TEST_SUITE_P( PerInstance, WifiRttControllerHidlTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames( -- GitLab From 410732f04f7b8effe28b4b1442a2165a34f9a5b9 Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Mon, 27 Jul 2020 14:33:39 -0700 Subject: [PATCH 086/790] Add PTS field in the DemuxFilterMmtpRecordEvent Add a 64-bit Constant enum for INVALID 64-bit filter id and hw av sync id Test: make -j44 dist Bug: 158816517 Change-Id: I27911841a719c69e668c89a4bca3ac0ce8eb701f --- tv/tuner/1.1/Android.bp | 1 + tv/tuner/1.1/types.hal | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/tv/tuner/1.1/Android.bp b/tv/tuner/1.1/Android.bp index 2019050df2..032232da51 100644 --- a/tv/tuner/1.1/Android.bp +++ b/tv/tuner/1.1/Android.bp @@ -16,4 +16,5 @@ hidl_interface { "android.hardware.tv.tuner@1.0", ], gen_java: false, + gen_java_constants: true, } diff --git a/tv/tuner/1.1/types.hal b/tv/tuner/1.1/types.hal index 21c7021461..5c02b85b3f 100644 --- a/tv/tuner/1.1/types.hal +++ b/tv/tuner/1.1/types.hal @@ -16,6 +16,7 @@ package android.hardware.tv.tuner@1.1; +import @1.0::Constant; import @1.0::DemuxFilterDownloadEvent; import @1.0::DemuxFilterIpPayloadEvent; import @1.0::DemuxFilterMediaEvent; @@ -26,6 +27,30 @@ import @1.0::DemuxFilterTemiEvent; import @1.0::DemuxFilterTsRecordEvent; import android.hidl.safe_union@1.0; +@export +enum Constant : @1.0::Constant { + /** + * An invalid mpuSequenceNumber in DemuxFilterMmtpRecordEvent. + */ + INVALID_MMTP_RECORD_EVENT_MPT_SEQUENCE_NUM = 0xFFFFFFFF, +}; + +@export +enum Constant64Bit : uint64_t { + /** + * An invalid 64-bit Filter ID. + */ + INVALID_FILTER_ID_64BIT = 0xFFFFFFFFFFFFFFFF, + /** + * An invalid 64-bit AV sync hardware ID. + */ + INVALID_AV_SYNC_ID_64BIT = 0xFFFFFFFFFFFFFFFF, + /** + * An invalid pts in the DemuxFilterTsRecordEvent or DemuxFilterMmtpRecordEvent. + */ + INVALID_PRESENTATION_TIME_STAMP = 0xFFFFFFFFFFFFFFFF, +}; + /** * Filter Event for TS Record data. */ @@ -56,6 +81,13 @@ struct DemuxFilterMmtpRecordEvent { * MPU sequence number of the filtered data. This is only used for MMTP. */ uint32_t mpuSequenceNumber; + + /** + * The Presentation Time Stamp(PTS) for the audio or video frame. It is based on 90KHz + * and has the same format as the PTS in ISO/IEC 13818-1. It is used only for the SC and + * the SC_HEVC. + */ + uint64_t pts; }; /** -- GitLab From 535292625147a95927068b4c613caffb31ad6fb5 Mon Sep 17 00:00:00 2001 From: Sarah Chin Date: Wed, 29 Jul 2020 14:14:07 -0700 Subject: [PATCH 087/790] Update language to comply with Android's inclusive language guidance See https://source.android.com/setup/contribute/respectful-code for reference Test: build Bug: 161896447 Change-Id: I3c0d02e1ee94c575c3a18291d438b464d7396463 --- current.txt | 1 + radio/1.0/types.hal | 4 ++-- radio/1.2/default/Radio.cpp | 12 ++++++------ radio/1.5/vts/functional/radio_hidl_hal_api.cpp | 4 ++-- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/current.txt b/current.txt index 6f5e55916c..594ceb632c 100644 --- a/current.txt +++ b/current.txt @@ -770,6 +770,7 @@ a64467bae843569f0d465c5be7f0c7a5b987985b55a3ef4794dd5afc68538650 android.hardwar cd84ab19c590e0e73dd2307b591a3093ee18147ef95e6d5418644463a6620076 android.hardware.neuralnetworks@1.2::IDevice 9625e85f56515ad2cf87b6a1847906db669f746ea4ab02cd3d4ca25abc9b0109 android.hardware.neuralnetworks@1.2::types 9e758e208d14f7256e0885d6d8ad0b61121b21d8c313864f981727ae55bffd16 android.hardware.neuralnetworks@1.3::types +7da2707d4cf93818eaf8038eb65e2180116a399c310e594a00935c5c981aa340 android.hardware.radio@1.0::types 38d65fb20c60a5b823298560fc0825457ecdc49603a4b4e94bf81511790737da android.hardware.radio@1.4::types 954c334efd80e8869b66d1ce5fe2755712d96ba4b3c38d415739c330af5fb4cb android.hardware.radio@1.5::types diff --git a/radio/1.0/types.hal b/radio/1.0/types.hal index 8393cf5e14..025aa7ccca 100644 --- a/radio/1.0/types.hal +++ b/radio/1.0/types.hal @@ -1890,8 +1890,8 @@ struct Carrier { }; struct CarrierRestrictions { - vec allowedCarriers; // whitelist for allowed carriers - vec excludedCarriers; // blacklist for explicitly excluded carriers + vec allowedCarriers; // Allowed carriers + vec excludedCarriers; // Explicitly excluded carriers // which match allowed_carriers. Eg. allowedCarriers // match mcc/mnc, excludedCarriers has same mcc/mnc and // gid1 is ABCD. It means except the carrier whose gid1 diff --git a/radio/1.2/default/Radio.cpp b/radio/1.2/default/Radio.cpp index 73512e4c23..28a815f60c 100644 --- a/radio/1.2/default/Radio.cpp +++ b/radio/1.2/default/Radio.cpp @@ -52,16 +52,16 @@ Return Radio::getIccCardStatus(int32_t serial) { /** * IRadio-defined request is called from the client and talk to the radio to get * IRadioResponse-defined response or/and IRadioIndication-defined indication back to the - * client. This dummy implementation omits and replaces the design and implementation of vendor + * client. This implementation omits and replaces the design and implementation of vendor * codes that needs to handle the receipt of the request and the return of the response from the - * radio; this just directly returns a dummy response back to the client. + * radio; this just directly returns a fake response back to the client. */ ALOGD("Radio Request: getIccCardStatus is entering"); if (mRadioResponse != nullptr || mRadioResponseV1_1 != nullptr || mRadioResponseV1_2 != nullptr) { - // Dummy RadioResponseInfo as part of response to return in 1.0, 1.1 and 1.2 + // Fake RadioResponseInfo as part of response to return in 1.0, 1.1 and 1.2 ::android::hardware::radio::V1_0::RadioResponseInfo info; info.serial = serial; info.type = ::android::hardware::radio::V1_0::RadioResponseType::SOLICITED; @@ -72,7 +72,7 @@ Return Radio::getIccCardStatus(int32_t serial) { * return getIccCardStatusResponse. */ if (mRadioResponseV1_2 != nullptr) { - // Dummy CardStatus as part of getIccCardStatusResponse_1_2 response to return + // Fake CardStatus as part of getIccCardStatusResponse_1_2 response to return ::android::hardware::radio::V1_2::CardStatus card_status; card_status.base.cardState = ::android::hardware::radio::V1_0::CardState::ABSENT; card_status.base.gsmUmtsSubscriptionAppIndex = 0; @@ -80,7 +80,7 @@ Return Radio::getIccCardStatus(int32_t serial) { mRadioResponseV1_2->getIccCardStatusResponse_1_2(info, card_status); ALOGD("Radio Response: getIccCardStatusResponse_1_2 is sent"); } else if (mRadioResponseV1_1 != nullptr) { - // Dummy CardStatus as part of getIccCardStatusResponse response to return + // Fake CardStatus as part of getIccCardStatusResponse response to return ::android::hardware::radio::V1_0::CardStatus card_status_V1_0; card_status_V1_0.cardState = ::android::hardware::radio::V1_0::CardState::ABSENT; card_status_V1_0.gsmUmtsSubscriptionAppIndex = 0; @@ -88,7 +88,7 @@ Return Radio::getIccCardStatus(int32_t serial) { mRadioResponseV1_1->getIccCardStatusResponse(info, card_status_V1_0); ALOGD("Radio Response: getIccCardStatusResponse is sent"); } else { - // Dummy CardStatus as part of getIccCardStatusResponse response to return + // Fake CardStatus as part of getIccCardStatusResponse response to return ::android::hardware::radio::V1_0::CardStatus card_status_V1_0; card_status_V1_0.cardState = ::android::hardware::radio::V1_0::CardState::ABSENT; card_status_V1_0.gsmUmtsSubscriptionAppIndex = 0; 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 24b7fd5df3..ca1593f031 100644 --- a/radio/1.5/vts/functional/radio_hidl_hal_api.cpp +++ b/radio/1.5/vts/functional/radio_hidl_hal_api.cpp @@ -1265,7 +1265,7 @@ TEST_P(RadioHidlTest_v1_5, getBarringInfo) { info.serviceType <= BarringInfo::ServiceType::OPERATOR_32)); reportedServices.insert(info.serviceType); - // Any type that is "conditional" must have sane values for conditional barring + // Any type that is "conditional" must have valid values for conditional barring // factor and time. switch (info.barringType) { case BarringInfo::BarringType::NONE: // fall through @@ -1284,7 +1284,7 @@ TEST_P(RadioHidlTest_v1_5, getBarringInfo) { // Certain types of barring are relevant for certain RANs. Ensure that only the right // types are reported. Note that no types are required, simply that for a given technology - // only certain types are valid. This is one way to sanity check that implementations are + // only certain types are valid. This is one way to check that implementations are // not providing information that they don't have. static const std::set UTRA_SERVICES{ BarringInfo::ServiceType::CS_SERVICE, BarringInfo::ServiceType::PS_SERVICE, -- GitLab From 390c711087930da32de9ebda676c3c7da64d6688 Mon Sep 17 00:00:00 2001 From: Tomasz Wasilczyk Date: Thu, 30 Jul 2020 11:08:29 -0700 Subject: [PATCH 088/790] Remove libnl++ dependency on NETLINK_ROUTE. One exception is for RTA_* definitions at NetlinkRequest. This class is going to be refactored anyway, so let's focus on this later. While we're here, also replace type assumptions with an actual decltype lookup. Bug: 162032964 Test: canhalctrl up test virtual vcan123 Change-Id: I3b509fa7b1870d4de7302fb5221a06613dfbb817 --- .../can/1.0/default/libnetdevice/can.cpp | 1 + .../1.0/default/libnetdevice/libnetdevice.cpp | 1 + .../can/1.0/default/libnetdevice/vlan.cpp | 2 ++ .../1.0/default/libnl++/NetlinkRequest.cpp | 19 ++++++++++------- .../libnl++/include/libnl++/NetlinkRequest.h | 21 +++++++++---------- .../default/libnl++/include/libnl++/types.h | 7 +++---- 6 files changed, 28 insertions(+), 23 deletions(-) diff --git a/automotive/can/1.0/default/libnetdevice/can.cpp b/automotive/can/1.0/default/libnetdevice/can.cpp index 0aa5afefde..c6f1b0413a 100644 --- a/automotive/can/1.0/default/libnetdevice/can.cpp +++ b/automotive/can/1.0/default/libnetdevice/can.cpp @@ -27,6 +27,7 @@ #include #include #include +#include namespace android::netdevice::can { diff --git a/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp b/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp index 04381f2d32..aeb5005344 100644 --- a/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp +++ b/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp @@ -24,6 +24,7 @@ #include #include +#include #include namespace android::netdevice { diff --git a/automotive/can/1.0/default/libnetdevice/vlan.cpp b/automotive/can/1.0/default/libnetdevice/vlan.cpp index bcc9345e69..e4191545e5 100644 --- a/automotive/can/1.0/default/libnetdevice/vlan.cpp +++ b/automotive/can/1.0/default/libnetdevice/vlan.cpp @@ -22,6 +22,8 @@ #include #include +#include + namespace android::netdevice::vlan { bool add(const std::string& eth, const std::string& vlan, uint16_t id) { diff --git a/automotive/can/1.0/default/libnl++/NetlinkRequest.cpp b/automotive/can/1.0/default/libnl++/NetlinkRequest.cpp index e9463d1106..b12489c00b 100644 --- a/automotive/can/1.0/default/libnl++/NetlinkRequest.cpp +++ b/automotive/can/1.0/default/libnl++/NetlinkRequest.cpp @@ -18,14 +18,17 @@ #include +// for RTA_ macros missing from NLA_ definitions +#include + namespace android::nl::impl { -static struct rtattr* nlmsg_tail(struct nlmsghdr* n) { - return reinterpret_cast( // +static struct nlattr* nlmsg_tail(struct nlmsghdr* n) { + return reinterpret_cast( // reinterpret_cast(n) + NLMSG_ALIGN(n->nlmsg_len)); } -struct rtattr* addattr_l(struct nlmsghdr* n, size_t maxLen, rtattrtype_t type, const void* data, +struct nlattr* addattr_l(struct nlmsghdr* n, size_t maxLen, nlattrtype_t type, const void* data, size_t dataLen) { size_t newLen = NLMSG_ALIGN(n->nlmsg_len) + RTA_SPACE(dataLen); if (newLen > maxLen) { @@ -34,21 +37,21 @@ struct rtattr* addattr_l(struct nlmsghdr* n, size_t maxLen, rtattrtype_t type, c } auto attr = nlmsg_tail(n); - attr->rta_len = RTA_SPACE(dataLen); - attr->rta_type = type; + attr->nla_len = RTA_SPACE(dataLen); + attr->nla_type = type; if (dataLen > 0) memcpy(RTA_DATA(attr), data, dataLen); n->nlmsg_len = newLen; return attr; } -struct rtattr* addattr_nest(struct nlmsghdr* n, size_t maxLen, rtattrtype_t type) { +struct nlattr* addattr_nest(struct nlmsghdr* n, size_t maxLen, nlattrtype_t type) { return addattr_l(n, maxLen, type, nullptr, 0); } -void addattr_nest_end(struct nlmsghdr* n, struct rtattr* nest) { +void addattr_nest_end(struct nlmsghdr* n, struct nlattr* nest) { size_t nestLen = reinterpret_cast(nlmsg_tail(n)) - reinterpret_cast(nest); - nest->rta_len = nestLen; + nest->nla_len = nestLen; } } // namespace android::nl::impl diff --git a/automotive/can/1.0/default/libnl++/include/libnl++/NetlinkRequest.h b/automotive/can/1.0/default/libnl++/include/libnl++/NetlinkRequest.h index 3b30a2acdf..29c36012bf 100644 --- a/automotive/can/1.0/default/libnl++/include/libnl++/NetlinkRequest.h +++ b/automotive/can/1.0/default/libnl++/include/libnl++/NetlinkRequest.h @@ -19,7 +19,7 @@ #include #include -#include +#include #include @@ -28,11 +28,10 @@ namespace android::nl { /** Implementation details, do not use outside NetlinkRequest template. */ namespace impl { -// TODO(twasilczyk): use nlattr instead of rtattr -struct rtattr* addattr_l(struct nlmsghdr* n, size_t maxLen, rtattrtype_t type, const void* data, +struct nlattr* addattr_l(struct nlmsghdr* n, size_t maxLen, nlattrtype_t type, const void* data, size_t dataLen); -struct rtattr* addattr_nest(struct nlmsghdr* n, size_t maxLen, rtattrtype_t type); -void addattr_nest_end(struct nlmsghdr* n, struct rtattr* nest); +struct nlattr* addattr_nest(struct nlmsghdr* n, size_t maxLen, nlattrtype_t type); +void addattr_nest_end(struct nlmsghdr* n, struct nlattr* nest); } // namespace impl @@ -82,14 +81,14 @@ struct NetlinkRequest { * \param attr attribute data */ template - void addattr(rtattrtype_t type, const A& attr) { + void addattr(nlattrtype_t type, const A& attr) { if (!mIsGood) return; auto ap = impl::addattr_l(&mRequest.nlmsg, sizeof(mRequest), type, &attr, sizeof(attr)); if (ap == nullptr) mIsGood = false; } template <> - void addattr(rtattrtype_t type, const std::string& s) { + void addattr(nlattrtype_t type, const std::string& s) { if (!mIsGood) return; auto ap = impl::addattr_l(&mRequest.nlmsg, sizeof(mRequest), type, s.c_str(), s.size() + 1); if (ap == nullptr) mIsGood = false; @@ -97,12 +96,12 @@ struct NetlinkRequest { /** Guard class to frame nested attributes. See nest(int). */ struct Nest { - Nest(NetlinkRequest& req, rtattrtype_t type) : mReq(req), mAttr(req.nestStart(type)) {} + Nest(NetlinkRequest& req, nlattrtype_t type) : mReq(req), mAttr(req.nestStart(type)) {} ~Nest() { mReq.nestEnd(mAttr); } private: NetlinkRequest& mReq; - struct rtattr* mAttr; + struct nlattr* mAttr; DISALLOW_COPY_AND_ASSIGN(Nest); }; @@ -142,14 +141,14 @@ struct NetlinkRequest { bool mIsGood = true; RequestData mRequest = {}; - struct rtattr* nestStart(rtattrtype_t type) { + struct nlattr* nestStart(nlattrtype_t type) { if (!mIsGood) return nullptr; auto attr = impl::addattr_nest(&mRequest.nlmsg, sizeof(mRequest), type); if (attr == nullptr) mIsGood = false; return attr; } - void nestEnd(struct rtattr* nest) { + void nestEnd(struct nlattr* nest) { if (mIsGood && nest != nullptr) impl::addattr_nest_end(&mRequest.nlmsg, nest); } }; diff --git a/automotive/can/1.0/default/libnl++/include/libnl++/types.h b/automotive/can/1.0/default/libnl++/include/libnl++/types.h index d2f10ff925..567590b456 100644 --- a/automotive/can/1.0/default/libnl++/include/libnl++/types.h +++ b/automotive/can/1.0/default/libnl++/include/libnl++/types.h @@ -16,12 +16,11 @@ #pragma once -#include +#include namespace android::nl { -typedef __u16 nlmsgtype_t; // nlmsghdr::nlmsg_type -typedef __u16 nlattrtype_t; // nlattr::nla_type -typedef unsigned short rtattrtype_t; // rtattr::rta_type +typedef decltype(nlmsghdr::nlmsg_type) nlmsgtype_t; +typedef decltype(nlattr::nla_type) nlattrtype_t; } // namespace android::nl -- GitLab From 6b47b98c405cf0fbbb1e91185c96d6164b6ac963 Mon Sep 17 00:00:00 2001 From: Tomasz Wasilczyk Date: Thu, 30 Jul 2020 14:09:10 -0700 Subject: [PATCH 089/790] Implement nlmsg Bug: 162032964 Test: custom code to parse RTM_NEWLINK messages Change-Id: I1ee4fb65d5b555c7665b7c42e6810efce7c726b6 --- .../default/libnl++/include/libnl++/nlmsg.h | 94 +++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 automotive/can/1.0/default/libnl++/include/libnl++/nlmsg.h diff --git a/automotive/can/1.0/default/libnl++/include/libnl++/nlmsg.h b/automotive/can/1.0/default/libnl++/include/libnl++/nlmsg.h new file mode 100644 index 0000000000..d6a797bc1e --- /dev/null +++ b/automotive/can/1.0/default/libnl++/include/libnl++/nlmsg.h @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +namespace android::nl { + +/** + * In-place Netlink message parser. + * + * This is a C++-style, memory safe(r) implementation of linux/netlink.h macros accessing Netlink + * message contents. The class doesn't own the underlying data, so the instance is valid as long as + * the source buffer is allocated and unmodified. + */ +template +class nlmsg { + public: + /** + * Validate buffer contents as a message carrying T data and create instance of nlmsg. + * + * \param buf Buffer containing the message. + * \return Parsed message or nullopt, if the buffer data is invalid. + */ + static std::optional> parse(nlbuf buf) { + const auto& [nlOk, nlHeader] = buf.getFirst(); + if (!nlOk) return std::nullopt; + + const auto& [dataOk, dataHeader] = buf.data().getFirst(); + if (!dataOk) return std::nullopt; + + const auto attributes = buf.data(sizeof(T)); + + return nlmsg(nlHeader, dataHeader, attributes); + } + + /** + * Validate buffer contents as a message of a given type and create instance of nlmsg. + * + * \param buf Buffer containing the message. + * \param msgtypes Acceptable message types (within a specific Netlink protocol) + * \return Parsed message or nullopt, if the buffer data is invalid or message type + * doesn't match. + */ + static std::optional> parse(nlbuf buf, std::set msgtypes) { + const auto& [nlOk, nlHeader] = buf.getFirst(); // we're doing it twice, but it's fine + if (!nlOk) return std::nullopt; + + if (msgtypes.count(nlHeader.nlmsg_type) == 0) return std::nullopt; + + return parse(buf); + } + + /** + * Netlink message header. + * + * This is a generic Netlink header containing information such as message flags. + */ + const nlmsghdr& header; + + /** + * Netlink message data. + * + * This is a payload specific to a given message type. + */ + const T& data; + + /** + * Netlink message attributes. + */ + const nlbuf attributes; + + const T* operator->() const { return &data; } + + private: + nlmsg(const nlmsghdr& nlHeader, const T& dataHeader, nlbuf attributes) + : header(nlHeader), data(dataHeader), attributes(attributes) {} +}; + +} // namespace android::nl -- GitLab From 990ee76d7731121663c6d395ec1b174c41b84c59 Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Thu, 30 Jul 2020 17:24:37 -0700 Subject: [PATCH 090/790] Fix the media filter buffer issue in the Tuner default implementation The current implementation does not clear the previous memcopy before copying the next round of data into the buffer. This CL fixes the issue. Test: atest VtsHalTvTunerV1_0TargetTest Bug: 159027928 Change-Id: I3399c69ead046630d9c22e8fbe1e816f6ea529f9 --- tv/tuner/1.1/default/Dvr.cpp | 1 + tv/tuner/1.1/default/Filter.cpp | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/tv/tuner/1.1/default/Dvr.cpp b/tv/tuner/1.1/default/Dvr.cpp index bf4c77e785..3a4ef1bee7 100644 --- a/tv/tuner/1.1/default/Dvr.cpp +++ b/tv/tuner/1.1/default/Dvr.cpp @@ -395,6 +395,7 @@ bool Dvr::processEsDataOnPlayback(bool isVirtualFrontend, bool isRecording) { mDemux->sendFrontendInputToRecord(frameData, pid, static_cast(esMeta[i].pts)); } startFilterDispatcher(isVirtualFrontend, isRecording); + frameData.clear(); } return true; diff --git a/tv/tuner/1.1/default/Filter.cpp b/tv/tuner/1.1/default/Filter.cpp index 2d6214d52c..4d08afe6f5 100644 --- a/tv/tuner/1.1/default/Filter.cpp +++ b/tv/tuner/1.1/default/Filter.cpp @@ -500,7 +500,12 @@ Result Filter::startMediaFilterHandler() { } if (mPts) { - return createMediaFilterEventWithIon(mFilterOutput); + Result result; + result = createMediaFilterEventWithIon(mFilterOutput); + if (result == Result::SUCCESS) { + mFilterOutput.clear(); + } + return result; } for (int i = 0; i < mFilterOutput.size(); i += 188) { -- GitLab From 29f0a4ff380a49977e412e4f4446ba95e7f1a547 Mon Sep 17 00:00:00 2001 From: Yipeng Cao Date: Fri, 31 Jul 2020 18:13:59 -0700 Subject: [PATCH 091/790] Fix for Gnss Hal for replay In the old logic, if /dev/gnss0 doesn't report location, it will fail back to the default mock location. Now we change to only report default location if /dev/gnss0 is not present. Test: launch_cvd --start_gnss_proxy Change-Id: Ie1026d5b4dd3e3c2ed1e2107232bcb94c3ba5079 Change-Id: I787b71d80be7875fc594d17b4296e7d28d9c2f5a --- .../utils/default/include/v2_1/GnssTemplate.h | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/gnss/common/utils/default/include/v2_1/GnssTemplate.h b/gnss/common/utils/default/include/v2_1/GnssTemplate.h index d16a67bffe..1fe6c3eb87 100644 --- a/gnss/common/utils/default/include/v2_1/GnssTemplate.h +++ b/gnss/common/utils/default/include/v2_1/GnssTemplate.h @@ -17,6 +17,7 @@ #pragma once #include +#include #include #include #include @@ -158,14 +159,16 @@ GnssTemplate::~GnssTemplate() { template std::unique_ptr GnssTemplate::getLocationFromHW() { char inputBuffer[INPUT_BUFFER_SIZE]; - mHardwareModeOn = false; if (mGnssFd == -1) { mGnssFd = open(GNSS_PATH, O_RDWR | O_NONBLOCK); } + if (mGnssFd == -1) { + ALOGW("Failed to open /dev/gnss0 errno: %d", errno); return nullptr; } - // Send control message to device + // Indicates it is a hardwareMode, don't report the default location. + mHardwareModeOn = true; int bytes_write = write(mGnssFd, CMD_GET_LOCATION, strlen(CMD_GET_LOCATION)); if (bytes_write <= 0) { return nullptr; @@ -179,8 +182,7 @@ std::unique_ptr GnssTemplate::getLocationFromHW() { int bytes_read = -1; std::string inputStr = ""; int epoll_ret = epoll_wait(epoll_fd, events, 1, mMinIntervalMs); - // Indicates it is a hardwareMode, don't need to wait outside. - mHardwareModeOn = true; + if (epoll_ret == -1) { return nullptr; } @@ -206,10 +208,12 @@ Return GnssTemplate::start() { while (mIsActive == true) { auto svStatus = filterBlacklistedSatellitesV2_1(Utils::getMockSvInfoListV2_1()); this->reportSvStatus(svStatus); - auto currentLocation = getLocationFromHW(); - if (currentLocation != nullptr) { - this->reportLocation(*currentLocation); + if (mHardwareModeOn) { + if (currentLocation != nullptr) { + // Only report location if the return from hardware is valid + this->reportLocation(*currentLocation); + } } else { if (sGnssCallback_2_1 != nullptr || sGnssCallback_2_0 != nullptr) { const auto location = Utils::getMockLocationV2_0(); @@ -218,13 +222,8 @@ Return GnssTemplate::start() { const auto location = Utils::getMockLocationV1_0(); this->reportLocation(location); } - - // Only need do the sleep in the static location mode, which mocks the "wait - // for" hardware behavior. - if (!mHardwareModeOn) { - std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMs)); - } } + std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMs)); } }); return true; -- GitLab From 34eb83aef276a00296dfab6d35f508bc3f0436fc Mon Sep 17 00:00:00 2001 From: Tomasz Wasilczyk Date: Fri, 31 Jul 2020 12:22:39 -0700 Subject: [PATCH 092/790] Implement attribute map. Bug: 162032964 Test: custom code to parse RTM_NEWLINK messages Change-Id: Ib07b0a4e553307e2ddaf7359e25f332660a29aec --- automotive/can/1.0/default/libnl++/Android.bp | 1 + .../can/1.0/default/libnl++/Attributes.cpp | 80 +++++++++ .../libnl++/include/libnl++/Attributes.h | 170 ++++++++++++++++++ .../default/libnl++/include/libnl++/nlbuf.h | 12 +- .../default/libnl++/include/libnl++/nlmsg.h | 8 +- 5 files changed, 266 insertions(+), 5 deletions(-) create mode 100644 automotive/can/1.0/default/libnl++/Attributes.cpp create mode 100644 automotive/can/1.0/default/libnl++/include/libnl++/Attributes.h diff --git a/automotive/can/1.0/default/libnl++/Android.bp b/automotive/can/1.0/default/libnl++/Android.bp index cffefe7faa..c4eb805aeb 100644 --- a/automotive/can/1.0/default/libnl++/Android.bp +++ b/automotive/can/1.0/default/libnl++/Android.bp @@ -31,6 +31,7 @@ cc_library_static { "protocols/MessageDefinition.cpp", "protocols/NetlinkProtocol.cpp", "protocols/all.cpp", + "Attributes.cpp", "NetlinkRequest.cpp", "NetlinkSocket.cpp", "common.cpp", diff --git a/automotive/can/1.0/default/libnl++/Attributes.cpp b/automotive/can/1.0/default/libnl++/Attributes.cpp new file mode 100644 index 0000000000..0f3c7f8d2a --- /dev/null +++ b/automotive/can/1.0/default/libnl++/Attributes.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +namespace android::nl { + +Attributes::Attributes() {} + +Attributes::Attributes(nlbuf buffer) : nlbuf(buffer) {} + +const Attributes::Index& Attributes::index() const { + if (mIndex.has_value()) return *mIndex; + + mIndex = Index(); + auto& index = *mIndex; + + for (auto attr : static_cast>(*this)) { + index.emplace(attr->nla_type, attr); + } + + return index; +} + +bool Attributes::contains(nlattrtype_t attrtype) const { + return index().count(attrtype) > 0; +} + +/* Parser specializations for selected types (more to come if necessary). */ + +template <> +Attributes Attributes::parse(nlbuf buf) { + return buf.data(); +} + +template <> +std::string Attributes::parse(nlbuf buf) { + const auto rawString = buf.data().getRaw(); + return std::string(rawString.ptr(), rawString.len()); +} + +template +static T parseUnsigned(nlbuf buf) { + return buf.data().copyFirst(); +} + +template <> +uint8_t Attributes::parse(nlbuf buf) { + return parseUnsigned(buf); +} + +template <> +uint16_t Attributes::parse(nlbuf buf) { + return parseUnsigned(buf); +} + +template <> +uint32_t Attributes::parse(nlbuf buf) { + return parseUnsigned(buf); +} + +template <> +uint64_t Attributes::parse(nlbuf buf) { + return parseUnsigned(buf); +} + +} // namespace android::nl diff --git a/automotive/can/1.0/default/libnl++/include/libnl++/Attributes.h b/automotive/can/1.0/default/libnl++/include/libnl++/Attributes.h new file mode 100644 index 0000000000..082b97a587 --- /dev/null +++ b/automotive/can/1.0/default/libnl++/include/libnl++/Attributes.h @@ -0,0 +1,170 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include +#include + +#include + +namespace android::nl { + +/** + * Netlink attribute map. + * + * This is a C++-style, memory safe(r) implementation of linux/netlink.h macros accessing Netlink + * message attributes. The class doesn't own the underlying data, so the instance is valid as long + * as the source buffer is allocated and unmodified. + * + * WARNING: this class is NOT thread-safe (it's safe to be used in multithreaded application, but + * a single instance can only be used by a single thread - the one owning the underlying buffer). + */ +class Attributes : private nlbuf { + public: + /** + * Constructs empty attribute map. + */ + Attributes(); + + /** + * Construct attribute map from underlying buffer. + * + * \param buffer Source buffer pointing at the first attribute. + */ + Attributes(nlbuf buffer); + + /** + * Checks, if the map contains given attribute type (key). + * + * \param attrtype Attribute type (such as IFLA_IFNAME). + * \return true if attribute is in the map, false otherwise. + */ + bool contains(nlattrtype_t attrtype) const; + + /** + * Fetches attribute of a given type by copying it. + * + * While this is quite efficient for simple types, fetching nested attribute creates a new copy + * of child attribute map. This may be costly if you calculate the index for child maps multiple + * times. Examples below. + * + * BAD: + * ``` + * const auto flags = msg->attributes. + * get(IFLA_AF_SPEC). + * get(AF_INET6). // IFLA_AF_SPEC index lazy-calculated + * get(IFLA_INET6_FLAGS); // AF_INET6 index lazy-calculated + * const auto& cacheinfo = msg->attributes. + * get(IFLA_AF_SPEC). // new instance of IFLA_AF_SPEC index + * get(AF_INET6). // IFLA_AF_SPEC index calculated again + * getStruct(IFLA_INET6_CACHEINFO); // AF_INET6 calculated again + * ``` + * + * GOOD: + * ``` + * const auto inet6 = msg->attributes. + * get(IFLA_AF_SPEC). + * get(AF_INET6); + * const auto flags = inet6.get(IFLA_INET6_FLAGS); // AF_INET6 index lazy-calculated + * const auto& cache = inet6.getStruct(IFLA_INET6_CACHEINFO); // index reused + * ``` + * + * If the attribute doesn't exists, default value of a given type is returned and warning + * spawned into the log. To check for attribute existence, \see contains(nlattrtype_t). + * + * \param attrtype Attribute to fetch. + * \return Attribute value. + */ + template + T get(nlattrtype_t attrtype) const { + const auto& ind = index(); + const auto it = ind.find(attrtype); + if (it == ind.end()) { + LOG(WARNING) << "Netlink attribute is missing: " << attrtype; + return T{}; + } + + return parse(it->second); + } + + /** + * Fetches a reference to a given attribute's data. + * + * This method is intended for arbitrary structures not specialized with get(nlattrtype_t) + * template and slightly more efficient for larger payloads due to not copying its data. + * + * If the attribute doesn't exists, a reference to empty value of a given type is returned and + * warning spawned into the log. To check for attribute existence, \see contains(nlattrtype_t). + * + * \param attrtype Attribute to fetch. + * \return Reference to the attribute's data. + */ + template + const T& getStruct(nlattrtype_t attrtype) const { + const auto& ind = index(); + const auto it = ind.find(attrtype); + if (it == ind.end()) { + LOG(WARNING) << "Netlink attribute is missing: " << attrtype; + static const T empty = {}; + return empty; + } + + const auto& [ok, val] = it->second.data().getFirst(); + if (!ok) LOG(WARNING) << "Can't fetch structure of size " << sizeof(T); + return val; + } + + private: + using Index = std::map>; + + /** + * Attribute index. + * + * Since this field is not protected by mutex, the use of \see index() dependent methods + * (such as \see get(nlattrtype_t)) is not thread-safe. This is a compromise made based on the + * following assumptions: + * + * 1. Most (or even all) use-cases involve attribute parsing in the same thread as where the + * buffer was allocated. This is partly forced by a dependence of nlmsg lifecycle on the + * underlying data buffer. + * + * 2. Index calculation and access would come with performance penalty never justified in most + * or all use cases (see the previous point). Since Index is not a trivially assignable data + * structure, it's not possible to use it with atomic types only and avoid mutexes. + */ + mutable std::optional mIndex; + + /** + * Lazy-calculate and cache index. + * + * \return Attribute index. + */ + const Index& index() const; + + /** + * Parse attribute data into a specific type. + * + * \param buf Raw attribute data. + * \return Parsed data. + */ + template + static T parse(nlbuf buf); +}; + +} // namespace android::nl diff --git a/automotive/can/1.0/default/libnl++/include/libnl++/nlbuf.h b/automotive/can/1.0/default/libnl++/include/libnl++/nlbuf.h index 4c0e581a71..7625020cf1 100644 --- a/automotive/can/1.0/default/libnl++/include/libnl++/nlbuf.h +++ b/automotive/can/1.0/default/libnl++/include/libnl++/nlbuf.h @@ -53,6 +53,11 @@ class nlbuf { static constexpr size_t hdrlen = align(sizeof(T)); public: + /** + * Constructs empty buffer of size 0. + */ + nlbuf() : mData(nullptr), mBufferEnd(nullptr) {} + /** * Constructor for nlbuf. * @@ -68,8 +73,8 @@ class nlbuf { std::pair getFirst() const { if (!ok()) { - static const T dummy = {}; - return {false, dummy}; + static const T empty = {}; + return {false, empty}; } return {true, *mData}; } @@ -78,7 +83,8 @@ class nlbuf { * Copy the first element of the buffer. * * This is a memory-safe cast operation, useful for reading e.g. uint32_t values - * from 1-byte buffer. + * from 1-byte buffer. If the buffer is smaller than the copied type, the rest is + * padded with default constructor output (usually zeros). */ T copyFirst() const { T val = {}; diff --git a/automotive/can/1.0/default/libnl++/include/libnl++/nlmsg.h b/automotive/can/1.0/default/libnl++/include/libnl++/nlmsg.h index d6a797bc1e..e9c92382a7 100644 --- a/automotive/can/1.0/default/libnl++/include/libnl++/nlmsg.h +++ b/automotive/can/1.0/default/libnl++/include/libnl++/nlmsg.h @@ -16,6 +16,7 @@ #pragma once +#include #include namespace android::nl { @@ -26,6 +27,9 @@ namespace android::nl { * This is a C++-style, memory safe(r) implementation of linux/netlink.h macros accessing Netlink * message contents. The class doesn't own the underlying data, so the instance is valid as long as * the source buffer is allocated and unmodified. + * + * WARNING: this class is NOT thread-safe (it's safe to be used in multithreaded application, but + * a single instance can only be used by a single thread - the one owning the underlying buffer). */ template class nlmsg { @@ -82,12 +86,12 @@ class nlmsg { /** * Netlink message attributes. */ - const nlbuf attributes; + const Attributes attributes; const T* operator->() const { return &data; } private: - nlmsg(const nlmsghdr& nlHeader, const T& dataHeader, nlbuf attributes) + nlmsg(const nlmsghdr& nlHeader, const T& dataHeader, Attributes attributes) : header(nlHeader), data(dataHeader), attributes(attributes) {} }; -- GitLab From 66fc939023cbf763a77ef8e25559e0ce0f81918a Mon Sep 17 00:00:00 2001 From: Tomasz Wasilczyk Date: Mon, 3 Aug 2020 10:22:52 -0700 Subject: [PATCH 093/790] Update libnl++ class naming to match Android code style nl::nlbuf -> nl::Buffer nl::nlmsg -> nl::Message nl::NetlinkRequest -> nl::MessageFactory nl::NetlinkSocket -> nl::Socket Bug: 162032964 Test: it builds Change-Id: Id9858805ff3fce3e48f9a82b7dbaea09269bcb3c --- .../can/1.0/default/libnetdevice/can.cpp | 8 ++--- .../can/1.0/default/libnetdevice/common.h | 2 -- .../1.0/default/libnetdevice/libnetdevice.cpp | 12 +++---- .../can/1.0/default/libnetdevice/vlan.cpp | 8 ++--- automotive/can/1.0/default/libnl++/Android.bp | 4 +-- .../can/1.0/default/libnl++/Attributes.cpp | 18 +++++----- ...{NetlinkRequest.cpp => MessageFactory.cpp} | 2 +- .../libnl++/{NetlinkSocket.cpp => Socket.cpp} | 21 ++++++----- automotive/can/1.0/default/libnl++/common.cpp | 2 +- automotive/can/1.0/default/libnl++/common.h | 4 +-- .../libnl++/include/libnl++/Attributes.h | 10 +++--- .../include/libnl++/{nlbuf.h => Buffer.h} | 36 +++++++++---------- .../include/libnl++/{nlmsg.h => Message.h} | 16 ++++----- .../{NetlinkRequest.h => MessageFactory.h} | 12 +++---- .../libnl++/{NetlinkSocket.h => Socket.h} | 24 ++++++------- .../default/libnl++/include/libnl++/printer.h | 4 +-- .../can/1.0/default/libnl++/printer.cpp | 8 ++--- .../libnl++/protocols/MessageDefinition.h | 8 ++--- .../libnl++/protocols/route/structs.cpp | 4 +-- .../default/libnl++/protocols/route/structs.h | 10 +++--- 20 files changed, 105 insertions(+), 108 deletions(-) rename automotive/can/1.0/default/libnl++/{NetlinkRequest.cpp => MessageFactory.cpp} (98%) rename automotive/can/1.0/default/libnl++/{NetlinkSocket.cpp => Socket.cpp} (88%) rename automotive/can/1.0/default/libnl++/include/libnl++/{nlbuf.h => Buffer.h} (84%) rename automotive/can/1.0/default/libnl++/include/libnl++/{nlmsg.h => Message.h} (86%) rename automotive/can/1.0/default/libnl++/include/libnl++/{NetlinkRequest.h => MessageFactory.h} (94%) rename automotive/can/1.0/default/libnl++/include/libnl++/{NetlinkSocket.h => Socket.h} (81%) diff --git a/automotive/can/1.0/default/libnetdevice/can.cpp b/automotive/can/1.0/default/libnetdevice/can.cpp index c6f1b0413a..b047bc920b 100644 --- a/automotive/can/1.0/default/libnetdevice/can.cpp +++ b/automotive/can/1.0/default/libnetdevice/can.cpp @@ -20,8 +20,8 @@ #include #include -#include -#include +#include +#include #include #include @@ -70,7 +70,7 @@ bool setBitrate(std::string ifname, uint32_t bitrate) { struct can_bittiming bt = {}; bt.bitrate = bitrate; - nl::NetlinkRequest req(RTM_NEWLINK, NLM_F_REQUEST); + nl::MessageFactory req(RTM_NEWLINK, NLM_F_REQUEST); const auto ifidx = nametoindex(ifname); if (ifidx == 0) { @@ -90,7 +90,7 @@ bool setBitrate(std::string ifname, uint32_t bitrate) { } } - nl::NetlinkSocket sock(NETLINK_ROUTE); + nl::Socket sock(NETLINK_ROUTE); return sock.send(req) && sock.receiveAck(); } diff --git a/automotive/can/1.0/default/libnetdevice/common.h b/automotive/can/1.0/default/libnetdevice/common.h index 201909f4c7..661e3f80f2 100644 --- a/automotive/can/1.0/default/libnetdevice/common.h +++ b/automotive/can/1.0/default/libnetdevice/common.h @@ -16,8 +16,6 @@ #pragma once -#include - #include #include diff --git a/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp b/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp index aeb5005344..f7f5f4dd43 100644 --- a/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp +++ b/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp @@ -20,8 +20,8 @@ #include "ifreqs.h" #include -#include -#include +#include +#include #include #include @@ -62,7 +62,7 @@ bool down(std::string ifname) { } bool add(std::string dev, std::string type) { - nl::NetlinkRequest req(RTM_NEWLINK, + nl::MessageFactory req(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL); req.addattr(IFLA_IFNAME, dev); @@ -71,15 +71,15 @@ bool add(std::string dev, std::string type) { req.addattr(IFLA_INFO_KIND, type); } - nl::NetlinkSocket sock(NETLINK_ROUTE); + nl::Socket sock(NETLINK_ROUTE); return sock.send(req) && sock.receiveAck(); } bool del(std::string dev) { - nl::NetlinkRequest req(RTM_DELLINK, NLM_F_REQUEST); + nl::MessageFactory req(RTM_DELLINK, NLM_F_REQUEST); req.addattr(IFLA_IFNAME, dev); - nl::NetlinkSocket sock(NETLINK_ROUTE); + nl::Socket sock(NETLINK_ROUTE); return sock.send(req) && sock.receiveAck(); } diff --git a/automotive/can/1.0/default/libnetdevice/vlan.cpp b/automotive/can/1.0/default/libnetdevice/vlan.cpp index e4191545e5..3e07f670df 100644 --- a/automotive/can/1.0/default/libnetdevice/vlan.cpp +++ b/automotive/can/1.0/default/libnetdevice/vlan.cpp @@ -19,8 +19,8 @@ #include "common.h" #include -#include -#include +#include +#include #include @@ -33,7 +33,7 @@ bool add(const std::string& eth, const std::string& vlan, uint16_t id) { return false; } - nl::NetlinkRequest req(RTM_NEWLINK, + nl::MessageFactory req(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL); req.addattr(IFLA_IFNAME, vlan); req.addattr(IFLA_LINK, ethidx); @@ -48,7 +48,7 @@ bool add(const std::string& eth, const std::string& vlan, uint16_t id) { } } - nl::NetlinkSocket sock(NETLINK_ROUTE); + nl::Socket sock(NETLINK_ROUTE); return sock.send(req) && sock.receiveAck(); } diff --git a/automotive/can/1.0/default/libnl++/Android.bp b/automotive/can/1.0/default/libnl++/Android.bp index c4eb805aeb..4042b169d6 100644 --- a/automotive/can/1.0/default/libnl++/Android.bp +++ b/automotive/can/1.0/default/libnl++/Android.bp @@ -32,8 +32,8 @@ cc_library_static { "protocols/NetlinkProtocol.cpp", "protocols/all.cpp", "Attributes.cpp", - "NetlinkRequest.cpp", - "NetlinkSocket.cpp", + "MessageFactory.cpp", + "Socket.cpp", "common.cpp", "printer.cpp", ], diff --git a/automotive/can/1.0/default/libnl++/Attributes.cpp b/automotive/can/1.0/default/libnl++/Attributes.cpp index 0f3c7f8d2a..c10164731a 100644 --- a/automotive/can/1.0/default/libnl++/Attributes.cpp +++ b/automotive/can/1.0/default/libnl++/Attributes.cpp @@ -20,7 +20,7 @@ namespace android::nl { Attributes::Attributes() {} -Attributes::Attributes(nlbuf buffer) : nlbuf(buffer) {} +Attributes::Attributes(Buffer buffer) : Buffer(buffer) {} const Attributes::Index& Attributes::index() const { if (mIndex.has_value()) return *mIndex; @@ -28,7 +28,7 @@ const Attributes::Index& Attributes::index() const { mIndex = Index(); auto& index = *mIndex; - for (auto attr : static_cast>(*this)) { + for (auto attr : static_cast>(*this)) { index.emplace(attr->nla_type, attr); } @@ -42,38 +42,38 @@ bool Attributes::contains(nlattrtype_t attrtype) const { /* Parser specializations for selected types (more to come if necessary). */ template <> -Attributes Attributes::parse(nlbuf buf) { +Attributes Attributes::parse(Buffer buf) { return buf.data(); } template <> -std::string Attributes::parse(nlbuf buf) { +std::string Attributes::parse(Buffer buf) { const auto rawString = buf.data().getRaw(); return std::string(rawString.ptr(), rawString.len()); } template -static T parseUnsigned(nlbuf buf) { +static T parseUnsigned(Buffer buf) { return buf.data().copyFirst(); } template <> -uint8_t Attributes::parse(nlbuf buf) { +uint8_t Attributes::parse(Buffer buf) { return parseUnsigned(buf); } template <> -uint16_t Attributes::parse(nlbuf buf) { +uint16_t Attributes::parse(Buffer buf) { return parseUnsigned(buf); } template <> -uint32_t Attributes::parse(nlbuf buf) { +uint32_t Attributes::parse(Buffer buf) { return parseUnsigned(buf); } template <> -uint64_t Attributes::parse(nlbuf buf) { +uint64_t Attributes::parse(Buffer buf) { return parseUnsigned(buf); } diff --git a/automotive/can/1.0/default/libnl++/NetlinkRequest.cpp b/automotive/can/1.0/default/libnl++/MessageFactory.cpp similarity index 98% rename from automotive/can/1.0/default/libnl++/NetlinkRequest.cpp rename to automotive/can/1.0/default/libnl++/MessageFactory.cpp index b12489c00b..0c6a3315da 100644 --- a/automotive/can/1.0/default/libnl++/NetlinkRequest.cpp +++ b/automotive/can/1.0/default/libnl++/MessageFactory.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include +#include #include diff --git a/automotive/can/1.0/default/libnl++/NetlinkSocket.cpp b/automotive/can/1.0/default/libnl++/Socket.cpp similarity index 88% rename from automotive/can/1.0/default/libnl++/NetlinkSocket.cpp rename to automotive/can/1.0/default/libnl++/Socket.cpp index 6f0f0c2017..aac6416f47 100644 --- a/automotive/can/1.0/default/libnl++/NetlinkSocket.cpp +++ b/automotive/can/1.0/default/libnl++/Socket.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include +#include #include @@ -27,8 +27,7 @@ namespace android::nl { */ static constexpr bool kSuperVerbose = false; -NetlinkSocket::NetlinkSocket(int protocol, unsigned int pid, uint32_t groups) - : mProtocol(protocol) { +Socket::Socket(int protocol, unsigned int pid, uint32_t groups) : mProtocol(protocol) { mFd.reset(socket(AF_NETLINK, SOCK_RAW, protocol)); if (!mFd.ok()) { PLOG(ERROR) << "Can't open Netlink socket"; @@ -48,7 +47,7 @@ NetlinkSocket::NetlinkSocket(int protocol, unsigned int pid, uint32_t groups) } } -bool NetlinkSocket::send(nlmsghdr* nlmsg, size_t totalLen) { +bool Socket::send(nlmsghdr* nlmsg, size_t totalLen) { if constexpr (kSuperVerbose) { nlmsg->nlmsg_seq = mSeq; LOG(VERBOSE) << (mFailed ? "(not) " : "") @@ -79,7 +78,7 @@ bool NetlinkSocket::send(nlmsghdr* nlmsg, size_t totalLen) { return true; } -bool NetlinkSocket::send(const nlbuf& msg, const sockaddr_nl& sa) { +bool Socket::send(const Buffer& msg, const sockaddr_nl& sa) { if constexpr (kSuperVerbose) { LOG(VERBOSE) << (mFailed ? "(not) " : "") << "sending Netlink message: " << toString(msg, mProtocol); @@ -96,12 +95,12 @@ bool NetlinkSocket::send(const nlbuf& msg, const sockaddr_nl& sa) { return true; } -std::optional> NetlinkSocket::receive(void* buf, size_t bufLen) { +std::optional> Socket::receive(void* buf, size_t bufLen) { sockaddr_nl sa = {}; return receive(buf, bufLen, sa); } -std::optional> NetlinkSocket::receive(void* buf, size_t bufLen, sockaddr_nl& sa) { +std::optional> Socket::receive(void* buf, size_t bufLen, sockaddr_nl& sa) { if (mFailed) return std::nullopt; socklen_t saLen = sizeof(sa); @@ -120,7 +119,7 @@ std::optional> NetlinkSocket::receive(void* buf, size_t bufLen, return std::nullopt; } - nlbuf msg(reinterpret_cast(buf), bytesReceived); + Buffer msg(reinterpret_cast(buf), bytesReceived); if constexpr (kSuperVerbose) { LOG(VERBOSE) << "received " << toString(msg, mProtocol); } @@ -128,8 +127,8 @@ std::optional> NetlinkSocket::receive(void* buf, size_t bufLen, } /* TODO(161389935): Migrate receiveAck to use nlmsg<> internally. Possibly reuse - * NetlinkSocket::receive(). */ -bool NetlinkSocket::receiveAck() { + * Socket::receive(). */ +bool Socket::receiveAck() { if (mFailed) return false; char buf[8192]; @@ -180,7 +179,7 @@ bool NetlinkSocket::receiveAck() { return false; } -std::optional NetlinkSocket::getSocketPid() { +std::optional Socket::getSocketPid() { sockaddr_nl sa = {}; socklen_t sasize = sizeof(sa); if (getsockname(mFd.get(), reinterpret_cast(&sa), &sasize) < 0) { diff --git a/automotive/can/1.0/default/libnl++/common.cpp b/automotive/can/1.0/default/libnl++/common.cpp index 7848646508..74eee247b9 100644 --- a/automotive/can/1.0/default/libnl++/common.cpp +++ b/automotive/can/1.0/default/libnl++/common.cpp @@ -41,7 +41,7 @@ std::string sanitize(std::string str) { return str; } -uint16_t crc16(const nlbuf data, uint16_t crc) { +uint16_t crc16(const Buffer data, uint16_t crc) { for (const auto byte : data.getRaw()) { crc ^= byte; for (unsigned i = 0; i < 8; i++) { diff --git a/automotive/can/1.0/default/libnl++/common.h b/automotive/can/1.0/default/libnl++/common.h index dc5777c160..1d9dbab28e 100644 --- a/automotive/can/1.0/default/libnl++/common.h +++ b/automotive/can/1.0/default/libnl++/common.h @@ -16,7 +16,7 @@ #pragma once -#include +#include #include #include @@ -54,6 +54,6 @@ std::string sanitize(std::string str); * \param crc Previous CRC16 value to continue calculating running checksum * \return CRC16 checksum */ -uint16_t crc16(const nlbuf data, uint16_t crc = 0); +uint16_t crc16(const Buffer data, uint16_t crc = 0); } // namespace android::nl diff --git a/automotive/can/1.0/default/libnl++/include/libnl++/Attributes.h b/automotive/can/1.0/default/libnl++/include/libnl++/Attributes.h index 082b97a587..f16d997899 100644 --- a/automotive/can/1.0/default/libnl++/include/libnl++/Attributes.h +++ b/automotive/can/1.0/default/libnl++/include/libnl++/Attributes.h @@ -17,7 +17,7 @@ #pragma once #include -#include +#include #include #include @@ -35,7 +35,7 @@ namespace android::nl { * WARNING: this class is NOT thread-safe (it's safe to be used in multithreaded application, but * a single instance can only be used by a single thread - the one owning the underlying buffer). */ -class Attributes : private nlbuf { +class Attributes : private Buffer { public: /** * Constructs empty attribute map. @@ -47,7 +47,7 @@ class Attributes : private nlbuf { * * \param buffer Source buffer pointing at the first attribute. */ - Attributes(nlbuf buffer); + Attributes(Buffer buffer); /** * Checks, if the map contains given attribute type (key). @@ -131,7 +131,7 @@ class Attributes : private nlbuf { } private: - using Index = std::map>; + using Index = std::map>; /** * Attribute index. @@ -164,7 +164,7 @@ class Attributes : private nlbuf { * \return Parsed data. */ template - static T parse(nlbuf buf); + static T parse(Buffer buf); }; } // namespace android::nl diff --git a/automotive/can/1.0/default/libnl++/include/libnl++/nlbuf.h b/automotive/can/1.0/default/libnl++/include/libnl++/Buffer.h similarity index 84% rename from automotive/can/1.0/default/libnl++/include/libnl++/nlbuf.h rename to automotive/can/1.0/default/libnl++/include/libnl++/Buffer.h index 7625020cf1..a6f8f7a8f1 100644 --- a/automotive/can/1.0/default/libnl++/include/libnl++/nlbuf.h +++ b/automotive/can/1.0/default/libnl++/include/libnl++/Buffer.h @@ -25,7 +25,7 @@ namespace android::nl { /** - * Buffer containing netlink structure (e.g. struct nlmsghdr, struct nlattr). + * Buffer wrapper containing netlink structure (e.g. struct nlmsghdr, struct nlattr). * * This is a C++-style, memory safe(r) and generic implementation of linux/netlink.h macros. * @@ -33,7 +33,7 @@ namespace android::nl { * not be trusted - the value may either be larger than the buffer message is allocated in or * smaller than the header itself (so it couldn't even fit itself). * - * As a solution, nlbuf<> keeps track of two lengths (both attribute for header with payload): + * As a solution, Buffer<> keeps track of two lengths (both attribute for header with payload): * - buffer length - how much memory was allocated to a given structure * - declared length - what nlmsg_len or nla_len says how long the structure is * @@ -42,7 +42,7 @@ namespace android::nl { * this template attempts to protect against. */ template -class nlbuf { +class Buffer { // The following definitions are C++ equivalents of NLMSG_* macros from linux/netlink.h static constexpr size_t alignto = NLMSG_ALIGNTO; @@ -56,15 +56,15 @@ class nlbuf { /** * Constructs empty buffer of size 0. */ - nlbuf() : mData(nullptr), mBufferEnd(nullptr) {} + Buffer() : mData(nullptr), mBufferEnd(nullptr) {} /** - * Constructor for nlbuf. + * Buffer constructor. * - * \param data A pointer to the data the nlbuf wraps. - * \param bufferLen Length of buffer. + * \param data A pointer to the data the Buffer wraps. + * \param bufLen Length of the buffer. */ - nlbuf(const T* data, size_t bufferLen) : mData(data), mBufferEnd(pointerAdd(data, bufferLen)) {} + Buffer(const T* data, size_t bufLen) : mData(data), mBufferEnd(pointerAdd(data, bufLen)) {} const T* operator->() const { CHECK(firstOk()) << "buffer can't fit the first element's header"; @@ -95,7 +95,7 @@ class nlbuf { bool firstOk() const { return sizeof(T) <= remainingLength(); } template - const nlbuf data(size_t offset = 0) const { + const Buffer data(size_t offset = 0) const { // Equivalent to NLMSG_DATA(hdr) + NLMSG_ALIGN(offset) const D* dptr = reinterpret_cast(uintptr_t(mData) + hdrlen + align(offset)); return {dptr, dataEnd()}; @@ -106,7 +106,7 @@ class nlbuf { iterator() : mCurrent(nullptr, size_t(0)) { CHECK(!mCurrent.ok()) << "end() iterator should indicate it's beyond end"; } - iterator(const nlbuf& buf) : mCurrent(buf) {} + iterator(const Buffer& buf) : mCurrent(buf) {} iterator operator++() { // mBufferEnd stays the same @@ -123,10 +123,10 @@ class nlbuf { return uintptr_t(other.mCurrent.mData) == uintptr_t(mCurrent.mData); } - const nlbuf& operator*() const { return mCurrent; } + const Buffer& operator*() const { return mCurrent; } protected: - nlbuf mCurrent; + Buffer mCurrent; }; iterator begin() const { return {*this}; } iterator end() const { return {}; } @@ -142,7 +142,7 @@ class nlbuf { class raw_view { public: - raw_view(const nlbuf& buffer) : mBuffer(buffer) {} + raw_view(const Buffer& buffer) : mBuffer(buffer) {} raw_iterator begin() const { return {mBuffer}; } raw_iterator end() const { return {}; } @@ -150,7 +150,7 @@ class nlbuf { size_t len() const { return mBuffer.remainingLength(); } private: - const nlbuf mBuffer; + const Buffer mBuffer; }; raw_view getRaw() const { return {*this}; } @@ -159,7 +159,7 @@ class nlbuf { const T* mData; const void* mBufferEnd; - nlbuf(const T* data, const void* bufferEnd) : mData(data), mBufferEnd(bufferEnd) {} + Buffer(const T* data, const void* bufferEnd) : mData(data), mBufferEnd(bufferEnd) {} bool ok() const { return declaredLength() <= remainingLength(); } @@ -192,16 +192,16 @@ class nlbuf { } template - friend class nlbuf; // calling private constructor of data buffers + friend class Buffer; // calling private constructor of data buffers }; template <> -inline size_t nlbuf::declaredLengthImpl() const { +inline size_t Buffer::declaredLengthImpl() const { return mData->nlmsg_len; } template <> -inline size_t nlbuf::declaredLengthImpl() const { +inline size_t Buffer::declaredLengthImpl() const { return mData->nla_len; } diff --git a/automotive/can/1.0/default/libnl++/include/libnl++/nlmsg.h b/automotive/can/1.0/default/libnl++/include/libnl++/Message.h similarity index 86% rename from automotive/can/1.0/default/libnl++/include/libnl++/nlmsg.h rename to automotive/can/1.0/default/libnl++/include/libnl++/Message.h index e9c92382a7..2b84a869e2 100644 --- a/automotive/can/1.0/default/libnl++/include/libnl++/nlmsg.h +++ b/automotive/can/1.0/default/libnl++/include/libnl++/Message.h @@ -17,7 +17,7 @@ #pragma once #include -#include +#include namespace android::nl { @@ -32,15 +32,15 @@ namespace android::nl { * a single instance can only be used by a single thread - the one owning the underlying buffer). */ template -class nlmsg { +class Message { public: /** - * Validate buffer contents as a message carrying T data and create instance of nlmsg. + * Validate buffer contents as a message carrying T data and create instance of parsed message. * * \param buf Buffer containing the message. * \return Parsed message or nullopt, if the buffer data is invalid. */ - static std::optional> parse(nlbuf buf) { + static std::optional> parse(Buffer buf) { const auto& [nlOk, nlHeader] = buf.getFirst(); if (!nlOk) return std::nullopt; @@ -49,18 +49,18 @@ class nlmsg { const auto attributes = buf.data(sizeof(T)); - return nlmsg(nlHeader, dataHeader, attributes); + return Message(nlHeader, dataHeader, attributes); } /** - * Validate buffer contents as a message of a given type and create instance of nlmsg. + * Validate buffer contents as a message of a given type and create instance of parsed message. * * \param buf Buffer containing the message. * \param msgtypes Acceptable message types (within a specific Netlink protocol) * \return Parsed message or nullopt, if the buffer data is invalid or message type * doesn't match. */ - static std::optional> parse(nlbuf buf, std::set msgtypes) { + static std::optional> parse(Buffer buf, std::set msgtypes) { const auto& [nlOk, nlHeader] = buf.getFirst(); // we're doing it twice, but it's fine if (!nlOk) return std::nullopt; @@ -91,7 +91,7 @@ class nlmsg { const T* operator->() const { return &data; } private: - nlmsg(const nlmsghdr& nlHeader, const T& dataHeader, Attributes attributes) + Message(const nlmsghdr& nlHeader, const T& dataHeader, Attributes attributes) : header(nlHeader), data(dataHeader), attributes(attributes) {} }; diff --git a/automotive/can/1.0/default/libnl++/include/libnl++/NetlinkRequest.h b/automotive/can/1.0/default/libnl++/include/libnl++/MessageFactory.h similarity index 94% rename from automotive/can/1.0/default/libnl++/include/libnl++/NetlinkRequest.h rename to automotive/can/1.0/default/libnl++/include/libnl++/MessageFactory.h index 29c36012bf..e00ca20fcd 100644 --- a/automotive/can/1.0/default/libnl++/include/libnl++/NetlinkRequest.h +++ b/automotive/can/1.0/default/libnl++/include/libnl++/MessageFactory.h @@ -25,7 +25,7 @@ namespace android::nl { -/** Implementation details, do not use outside NetlinkRequest template. */ +/** Implementation details, do not use outside MessageFactory template. */ namespace impl { struct nlattr* addattr_l(struct nlmsghdr* n, size_t maxLen, nlattrtype_t type, const void* data, @@ -43,7 +43,7 @@ void addattr_nest_end(struct nlmsghdr* n, struct nlattr* nest); * \param BUFSIZE how much space to reserve for payload (not counting the header size) */ template -struct NetlinkRequest { +struct MessageFactory { struct RequestData { struct nlmsghdr nlmsg; T data; @@ -58,7 +58,7 @@ struct NetlinkRequest { * \param type Message type (such as RTM_NEWLINK) * \param flags Message flags (such as NLM_F_REQUEST) */ - NetlinkRequest(nlmsgtype_t type, uint16_t flags) { + MessageFactory(nlmsgtype_t type, uint16_t flags) { mRequest.nlmsg.nlmsg_len = NLMSG_LENGTH(sizeof(mRequest.data)); mRequest.nlmsg.nlmsg_type = type; mRequest.nlmsg.nlmsg_flags = flags; @@ -96,11 +96,11 @@ struct NetlinkRequest { /** Guard class to frame nested attributes. See nest(int). */ struct Nest { - Nest(NetlinkRequest& req, nlattrtype_t type) : mReq(req), mAttr(req.nestStart(type)) {} + Nest(MessageFactory& req, nlattrtype_t type) : mReq(req), mAttr(req.nestStart(type)) {} ~Nest() { mReq.nestEnd(mAttr); } private: - NetlinkRequest& mReq; + MessageFactory& mReq; struct nlattr* mAttr; DISALLOW_COPY_AND_ASSIGN(Nest); @@ -114,7 +114,7 @@ struct NetlinkRequest { * * Example usage nesting IFLA_CAN_BITTIMING inside IFLA_INFO_DATA, which is nested * inside IFLA_LINKINFO: - * NetlinkRequest req(RTM_NEWLINK, NLM_F_REQUEST); + * MessageFactory req(RTM_NEWLINK, NLM_F_REQUEST); * { * auto linkinfo = req.nest(IFLA_LINKINFO); * req.addattr(IFLA_INFO_KIND, "can"); diff --git a/automotive/can/1.0/default/libnl++/include/libnl++/NetlinkSocket.h b/automotive/can/1.0/default/libnl++/include/libnl++/Socket.h similarity index 81% rename from automotive/can/1.0/default/libnl++/include/libnl++/NetlinkSocket.h rename to automotive/can/1.0/default/libnl++/include/libnl++/Socket.h index f2a38fbe04..7685733ce5 100644 --- a/automotive/can/1.0/default/libnl++/include/libnl++/NetlinkSocket.h +++ b/automotive/can/1.0/default/libnl++/include/libnl++/Socket.h @@ -18,8 +18,8 @@ #include #include -#include -#include +#include +#include #include @@ -33,9 +33,9 @@ namespace android::nl { * This class is not thread safe to use a single instance between multiple threads, but it's fine to * use multiple instances over multiple threads. */ -struct NetlinkSocket { +struct Socket { /** - * NetlinkSocket constructor. + * Socket constructor. * * \param protocol the Netlink protocol to use. * \param pid port id. Default value of 0 allows the kernel to assign us a unique pid. (NOTE: @@ -44,7 +44,7 @@ struct NetlinkSocket { * bit is a different group. Default value of 0 means no groups are selected. See man netlink.7 * for more details. */ - NetlinkSocket(int protocol, unsigned int pid = 0, uint32_t groups = 0); + Socket(int protocol, unsigned int pid = 0, uint32_t groups = 0); /** * Send Netlink message to Kernel. The sequence number will be automatically incremented, and @@ -54,7 +54,7 @@ struct NetlinkSocket { * \return true, if succeeded */ template - bool send(NetlinkRequest& req) { + bool send(MessageFactory& req) { if (!req.isGood()) return false; return send(req.header(), req.totalLength); } @@ -66,16 +66,16 @@ struct NetlinkSocket { * \param sa Destination address. * \return true, if succeeded */ - bool send(const nlbuf& msg, const sockaddr_nl& sa); + bool send(const Buffer& msg, const sockaddr_nl& sa); /** * Receive Netlink data. * * \param buf buffer to hold message data. * \param bufLen length of buf. - * \return nlbuf with message data, std::nullopt on error. + * \return Buffer with message data, std::nullopt on error. */ - std::optional> receive(void* buf, size_t bufLen); + std::optional> receive(void* buf, size_t bufLen); /** * Receive Netlink data with address info. @@ -83,9 +83,9 @@ struct NetlinkSocket { * \param buf buffer to hold message data. * \param bufLen length of buf. * \param sa Blank struct that recvfrom will populate with address info. - * \return nlbuf with message data, std::nullopt on error. + * \return Buffer with message data, std::nullopt on error. */ - std::optional> receive(void* buf, size_t bufLen, sockaddr_nl& sa); + std::optional> receive(void* buf, size_t bufLen, sockaddr_nl& sa); /** * Receive Netlink ACK message from Kernel. @@ -110,7 +110,7 @@ struct NetlinkSocket { bool send(nlmsghdr* msg, size_t totalLen); - DISALLOW_COPY_AND_ASSIGN(NetlinkSocket); + DISALLOW_COPY_AND_ASSIGN(Socket); }; } // namespace android::nl diff --git a/automotive/can/1.0/default/libnl++/include/libnl++/printer.h b/automotive/can/1.0/default/libnl++/include/libnl++/printer.h index 7167965cfe..53a06d805b 100644 --- a/automotive/can/1.0/default/libnl++/include/libnl++/printer.h +++ b/automotive/can/1.0/default/libnl++/include/libnl++/printer.h @@ -16,7 +16,7 @@ #pragma once -#include +#include #include @@ -32,6 +32,6 @@ namespace android::nl { * \param printPayload True will stringify message data, false will only stringify the header(s). * \return Stringified message. */ -std::string toString(const nlbuf hdr, int protocol, bool printPayload = false); +std::string toString(const Buffer hdr, int protocol, bool printPayload = false); } // namespace android::nl diff --git a/automotive/can/1.0/default/libnl++/printer.cpp b/automotive/can/1.0/default/libnl++/printer.cpp index c32afb3453..9735db1faf 100644 --- a/automotive/can/1.0/default/libnl++/printer.cpp +++ b/automotive/can/1.0/default/libnl++/printer.cpp @@ -20,7 +20,7 @@ #include "protocols/all.h" #include -#include +#include #include #include @@ -61,7 +61,7 @@ static void flagsToStream(std::stringstream& ss, __u16 nlmsg_flags) { } } -static void toStream(std::stringstream& ss, const nlbuf data) { +static void toStream(std::stringstream& ss, const Buffer data) { const auto rawData = data.getRaw(); const auto dataLen = rawData.len(); ss << std::hex; @@ -77,7 +77,7 @@ static void toStream(std::stringstream& ss, const nlbuf data) { if (dataLen > 16) ss << std::endl; } -static void toStream(std::stringstream& ss, const nlbuf attr, +static void toStream(std::stringstream& ss, const Buffer attr, const protocols::AttributeMap& attrMap) { using DataType = protocols::AttributeDefinition::DataType; const auto attrtype = attrMap[attr->nla_type]; @@ -115,7 +115,7 @@ static void toStream(std::stringstream& ss, const nlbuf attr, } } -std::string toString(const nlbuf hdr, int protocol, bool printPayload) { +std::string toString(const Buffer hdr, int protocol, bool printPayload) { if (!hdr.firstOk()) return "nlmsg{buffer overflow}"; std::stringstream ss; diff --git a/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.h b/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.h index 046ef478c5..ef73d09236 100644 --- a/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.h +++ b/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.h @@ -16,7 +16,7 @@ #pragma once -#include +#include #include #include @@ -60,7 +60,7 @@ struct AttributeDefinition { Uint, Struct, }; - using ToStream = std::function attr)>; + using ToStream = std::function attr)>; std::string name; DataType dataType = DataType::Raw; @@ -86,7 +86,7 @@ class MessageDescriptor { const MessageTypeMap& getMessageTypeMap() const; const AttributeMap& getAttributeMap() const; const std::string getMessageName(nlmsgtype_t msgtype) const; - virtual void dataToStream(std::stringstream& ss, const nlbuf hdr) const = 0; + virtual void dataToStream(std::stringstream& ss, const Buffer hdr) const = 0; private: const std::string mName; @@ -109,7 +109,7 @@ class MessageDefinition : public MessageDescriptor { const std::initializer_list attrTypes = {}) : MessageDescriptor(name, messageTypes, attrTypes, sizeof(T)) {} - void dataToStream(std::stringstream& ss, const nlbuf hdr) const override { + void dataToStream(std::stringstream& ss, const Buffer hdr) const override { const auto& [ok, msg] = hdr.data().getFirst(); if (!ok) { ss << "{incomplete payload}"; diff --git a/automotive/can/1.0/default/libnl++/protocols/route/structs.cpp b/automotive/can/1.0/default/libnl++/protocols/route/structs.cpp index ea923bbd8c..b62cec3c7e 100644 --- a/automotive/can/1.0/default/libnl++/protocols/route/structs.cpp +++ b/automotive/can/1.0/default/libnl++/protocols/route/structs.cpp @@ -18,7 +18,7 @@ namespace android::nl::protocols::route { -void mapToStream(std::stringstream& ss, const nlbuf attr) { +void mapToStream(std::stringstream& ss, const Buffer attr) { const auto& [ok, data] = attr.data().getFirst(); if (!ok) { ss << "invalid structure"; @@ -33,7 +33,7 @@ void mapToStream(std::stringstream& ss, const nlbuf attr) { << unsigned(data.port) << '}'; } -void ifla_cacheinfoToStream(std::stringstream& ss, const nlbuf attr) { +void ifla_cacheinfoToStream(std::stringstream& ss, const Buffer attr) { const auto& [ok, data] = attr.data().getFirst(); if (!ok) { ss << "invalid structure"; diff --git a/automotive/can/1.0/default/libnl++/protocols/route/structs.h b/automotive/can/1.0/default/libnl++/protocols/route/structs.h index 38776fad8b..b9d622a739 100644 --- a/automotive/can/1.0/default/libnl++/protocols/route/structs.h +++ b/automotive/can/1.0/default/libnl++/protocols/route/structs.h @@ -16,7 +16,7 @@ #pragma once -#include +#include #include @@ -25,13 +25,13 @@ namespace android::nl::protocols::route { // rtnl_link_ifmap -void mapToStream(std::stringstream& ss, const nlbuf attr); +void mapToStream(std::stringstream& ss, const Buffer attr); // ifla_cacheinfo -void ifla_cacheinfoToStream(std::stringstream& ss, const nlbuf attr); +void ifla_cacheinfoToStream(std::stringstream& ss, const Buffer attr); template -void arrayToStream(std::stringstream& ss, const nlbuf attr) { +void arrayToStream(std::stringstream& ss, const Buffer attr) { ss << '{'; for (const auto it : attr.data().getRaw()) { ss << it << ','; @@ -42,7 +42,7 @@ void arrayToStream(std::stringstream& ss, const nlbuf attr) { // rtnl_link_stats or rtnl_link_stats64 template -void statsToStream(std::stringstream& ss, const nlbuf attr) { +void statsToStream(std::stringstream& ss, const Buffer attr) { const auto& [ok, data] = attr.data().getFirst(); if (!ok) { ss << "invalid structure"; -- GitLab From b428f77f6cbb1576a38e79795adc7ff5795c5d05 Mon Sep 17 00:00:00 2001 From: Tomasz Wasilczyk Date: Mon, 3 Aug 2020 15:06:23 -0700 Subject: [PATCH 094/790] Netlink socket refactoring - merge two send() methods into one - use internal receive buffer instead of asking user to supply one - move setting sequence number to MessageFactory sending code - don't limit send function to Kernel as a recipient - move adding NLM_F_ACK to the caller side - getSocketPid -> getPid - unsigned int -> unsigned One part missing is refactoring receiveAck (b/161389935). Bug: 162032964 Test: canhalctrl up test virtual vcan3 Change-Id: Ie3d460dbc2ea1251469bf08504cfe2c6e80bbe75 --- .../can/1.0/default/libnetdevice/can.cpp | 2 +- .../1.0/default/libnetdevice/libnetdevice.cpp | 4 +- .../can/1.0/default/libnetdevice/vlan.cpp | 2 +- automotive/can/1.0/default/libnl++/Socket.cpp | 89 +++++++------------ .../libnl++/include/libnl++/MessageFactory.h | 1 - .../default/libnl++/include/libnl++/Socket.h | 87 ++++++++++++------ 6 files changed, 95 insertions(+), 90 deletions(-) diff --git a/automotive/can/1.0/default/libnetdevice/can.cpp b/automotive/can/1.0/default/libnetdevice/can.cpp index b047bc920b..ab107fdbaa 100644 --- a/automotive/can/1.0/default/libnetdevice/can.cpp +++ b/automotive/can/1.0/default/libnetdevice/can.cpp @@ -70,7 +70,7 @@ bool setBitrate(std::string ifname, uint32_t bitrate) { struct can_bittiming bt = {}; bt.bitrate = bitrate; - nl::MessageFactory req(RTM_NEWLINK, NLM_F_REQUEST); + nl::MessageFactory req(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_ACK); const auto ifidx = nametoindex(ifname); if (ifidx == 0) { diff --git a/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp b/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp index f7f5f4dd43..ed2a51e864 100644 --- a/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp +++ b/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp @@ -63,7 +63,7 @@ bool down(std::string ifname) { bool add(std::string dev, std::string type) { nl::MessageFactory req(RTM_NEWLINK, - NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL); + NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL | NLM_F_ACK); req.addattr(IFLA_IFNAME, dev); { @@ -76,7 +76,7 @@ bool add(std::string dev, std::string type) { } bool del(std::string dev) { - nl::MessageFactory req(RTM_DELLINK, NLM_F_REQUEST); + nl::MessageFactory req(RTM_DELLINK, NLM_F_REQUEST | NLM_F_ACK); req.addattr(IFLA_IFNAME, dev); nl::Socket sock(NETLINK_ROUTE); diff --git a/automotive/can/1.0/default/libnetdevice/vlan.cpp b/automotive/can/1.0/default/libnetdevice/vlan.cpp index 3e07f670df..3f904f0b02 100644 --- a/automotive/can/1.0/default/libnetdevice/vlan.cpp +++ b/automotive/can/1.0/default/libnetdevice/vlan.cpp @@ -34,7 +34,7 @@ bool add(const std::string& eth, const std::string& vlan, uint16_t id) { } nl::MessageFactory req(RTM_NEWLINK, - NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL); + NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL | NLM_F_ACK); req.addattr(IFLA_IFNAME, vlan); req.addattr(IFLA_LINK, ethidx); diff --git a/automotive/can/1.0/default/libnl++/Socket.cpp b/automotive/can/1.0/default/libnl++/Socket.cpp index aac6416f47..56e990c23f 100644 --- a/automotive/can/1.0/default/libnl++/Socket.cpp +++ b/automotive/can/1.0/default/libnl++/Socket.cpp @@ -27,7 +27,7 @@ namespace android::nl { */ static constexpr bool kSuperVerbose = false; -Socket::Socket(int protocol, unsigned int pid, uint32_t groups) : mProtocol(protocol) { +Socket::Socket(int protocol, unsigned pid, uint32_t groups) : mProtocol(protocol) { mFd.reset(socket(AF_NETLINK, SOCK_RAW, protocol)); if (!mFd.ok()) { PLOG(ERROR) << "Can't open Netlink socket"; @@ -47,83 +47,60 @@ Socket::Socket(int protocol, unsigned int pid, uint32_t groups) : mProtocol(prot } } -bool Socket::send(nlmsghdr* nlmsg, size_t totalLen) { - if constexpr (kSuperVerbose) { - nlmsg->nlmsg_seq = mSeq; - LOG(VERBOSE) << (mFailed ? "(not) " : "") - << "sending Netlink message: " << toString({nlmsg, totalLen}, mProtocol); - } - - if (mFailed) return false; - - nlmsg->nlmsg_pid = 0; // kernel - nlmsg->nlmsg_seq = mSeq++; - nlmsg->nlmsg_flags |= NLM_F_ACK; - - iovec iov = {nlmsg, nlmsg->nlmsg_len}; - - sockaddr_nl sa = {}; - sa.nl_family = AF_NETLINK; - - msghdr msg = {}; - msg.msg_name = &sa; - msg.msg_namelen = sizeof(sa); - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - - if (sendmsg(mFd.get(), &msg, 0) < 0) { - PLOG(ERROR) << "Can't send Netlink message"; - return false; - } - return true; -} - bool Socket::send(const Buffer& msg, const sockaddr_nl& sa) { if constexpr (kSuperVerbose) { - LOG(VERBOSE) << (mFailed ? "(not) " : "") - << "sending Netlink message: " << toString(msg, mProtocol); + LOG(VERBOSE) << (mFailed ? "(not) " : "") << "sending Netlink message (" // + << msg->nlmsg_pid << " -> " << sa.nl_pid << "): " << toString(msg, mProtocol); } - if (mFailed) return false; + + mSeq = msg->nlmsg_seq; const auto rawMsg = msg.getRaw(); const auto bytesSent = sendto(mFd.get(), rawMsg.ptr(), rawMsg.len(), 0, reinterpret_cast(&sa), sizeof(sa)); if (bytesSent < 0) { PLOG(ERROR) << "Can't send Netlink message"; return false; + } else if (size_t(bytesSent) != rawMsg.len()) { + LOG(ERROR) << "Can't send Netlink message: truncated message"; + return false; } return true; } -std::optional> Socket::receive(void* buf, size_t bufLen) { - sockaddr_nl sa = {}; - return receive(buf, bufLen, sa); +std::optional> Socket::receive(size_t maxSize) { + return receiveFrom(maxSize).first; } -std::optional> Socket::receive(void* buf, size_t bufLen, sockaddr_nl& sa) { - if (mFailed) return std::nullopt; +std::pair>, sockaddr_nl> Socket::receiveFrom(size_t maxSize) { + if (mFailed) return {std::nullopt, {}}; - socklen_t saLen = sizeof(sa); - if (bufLen == 0) { - LOG(ERROR) << "Receive buffer has zero size!"; - return std::nullopt; + if (maxSize == 0) { + LOG(ERROR) << "Maximum receive size should not be zero"; + return {std::nullopt, {}}; } - const auto bytesReceived = - recvfrom(mFd.get(), buf, bufLen, MSG_TRUNC, reinterpret_cast(&sa), &saLen); + if (mReceiveBuffer.size() < maxSize) mReceiveBuffer.resize(maxSize); + + sockaddr_nl sa = {}; + socklen_t saLen = sizeof(sa); + const auto bytesReceived = recvfrom(mFd.get(), mReceiveBuffer.data(), maxSize, MSG_TRUNC, + reinterpret_cast(&sa), &saLen); + if (bytesReceived <= 0) { PLOG(ERROR) << "Failed to receive Netlink message"; - return std::nullopt; - } else if (unsigned(bytesReceived) > bufLen) { - PLOG(ERROR) << "Received data larger than the receive buffer! " << bytesReceived << " > " - << bufLen; - return std::nullopt; + return {std::nullopt, {}}; + } else if (size_t(bytesReceived) > maxSize) { + PLOG(ERROR) << "Received data larger than maximum receive size: " // + << bytesReceived << " > " << maxSize; + return {std::nullopt, {}}; } - Buffer msg(reinterpret_cast(buf), bytesReceived); + Buffer msg(reinterpret_cast(mReceiveBuffer.data()), bytesReceived); if constexpr (kSuperVerbose) { - LOG(VERBOSE) << "received " << toString(msg, mProtocol); + LOG(VERBOSE) << "received (" << sa.nl_pid << " -> " << msg->nlmsg_pid << "):" // + << toString(msg, mProtocol); } - return msg; + return {msg, sa}; } /* TODO(161389935): Migrate receiveAck to use nlmsg<> internally. Possibly reuse @@ -179,11 +156,11 @@ bool Socket::receiveAck() { return false; } -std::optional Socket::getSocketPid() { +std::optional Socket::getPid() { sockaddr_nl sa = {}; socklen_t sasize = sizeof(sa); if (getsockname(mFd.get(), reinterpret_cast(&sa), &sasize) < 0) { - PLOG(ERROR) << "Failed to getsockname() for netlink_fd!"; + PLOG(ERROR) << "Failed to get PID of Netlink socket"; return std::nullopt; } return sa.nl_pid; diff --git a/automotive/can/1.0/default/libnl++/include/libnl++/MessageFactory.h b/automotive/can/1.0/default/libnl++/include/libnl++/MessageFactory.h index e00ca20fcd..5272577b53 100644 --- a/automotive/can/1.0/default/libnl++/include/libnl++/MessageFactory.h +++ b/automotive/can/1.0/default/libnl++/include/libnl++/MessageFactory.h @@ -35,7 +35,6 @@ void addattr_nest_end(struct nlmsghdr* n, struct nlattr* nest); } // namespace impl -// TODO(twasilczyk): rename to NetlinkMessage /** * Wrapper around NETLINK_ROUTE messages, to build them in C++ style. * diff --git a/automotive/can/1.0/default/libnl++/include/libnl++/Socket.h b/automotive/can/1.0/default/libnl++/include/libnl++/Socket.h index 7685733ce5..bc6ad9df54 100644 --- a/automotive/can/1.0/default/libnl++/include/libnl++/Socket.h +++ b/automotive/can/1.0/default/libnl++/include/libnl++/Socket.h @@ -24,6 +24,7 @@ #include #include +#include namespace android::nl { @@ -33,59 +34,88 @@ namespace android::nl { * This class is not thread safe to use a single instance between multiple threads, but it's fine to * use multiple instances over multiple threads. */ -struct Socket { +class Socket { + public: + static constexpr size_t defaultReceiveSize = 8192; + /** * Socket constructor. * * \param protocol the Netlink protocol to use. - * \param pid port id. Default value of 0 allows the kernel to assign us a unique pid. (NOTE: - * this is NOT the same as process id!) + * \param pid port id. Default value of 0 allows the kernel to assign us a unique pid. + * (NOTE: this is NOT the same as process id). * \param groups Netlink multicast groups to listen to. This is a 32-bit bitfield, where each - * bit is a different group. Default value of 0 means no groups are selected. See man netlink.7 + * bit is a different group. Default value of 0 means no groups are selected. + * See man netlink.7. * for more details. */ - Socket(int protocol, unsigned int pid = 0, uint32_t groups = 0); + Socket(int protocol, unsigned pid = 0, uint32_t groups = 0); /** - * Send Netlink message to Kernel. The sequence number will be automatically incremented, and - * the NLM_F_ACK (request ACK) flag will be set. + * Send Netlink message with incremented sequence number to the Kernel. * - * \param msg Message to send. - * \return true, if succeeded + * \param msg Message to send. Its sequence number will be updated. + * \return true, if succeeded. */ - template + template bool send(MessageFactory& req) { + sockaddr_nl sa = {}; + sa.nl_family = AF_NETLINK; + sa.nl_pid = 0; // Kernel + return send(req, sa); + } + + /** + * Send Netlink message with incremented sequence number. + * + * \param msg Message to send. Its sequence number will be updated. + * \param sa Destination address. + * \return true, if succeeded. + */ + template + bool send(MessageFactory& req, const sockaddr_nl& sa) { if (!req.isGood()) return false; - return send(req.header(), req.totalLength); + + const auto nlmsg = req.header(); + nlmsg->nlmsg_seq = mSeq + 1; + + // With MessageFactory<>, we trust nlmsg_len to be correct. + return send({nlmsg, nlmsg->nlmsg_len}, sa); } /** - * Send Netlink message. The message will be sent as is, without any modification. + * Send Netlink message. * * \param msg Message to send. * \param sa Destination address. - * \return true, if succeeded + * \return true, if succeeded. */ bool send(const Buffer& msg, const sockaddr_nl& sa); /** - * Receive Netlink data. + * Receive one or multiple Netlink messages. * - * \param buf buffer to hold message data. - * \param bufLen length of buf. - * \return Buffer with message data, std::nullopt on error. + * WARNING: the underlying buffer is owned by Socket class and the data is valid until the next + * call to the read function or until deallocation of Socket instance. + * + * \param maxSize Maximum total size of received messages + * \return Buffer view with message data, std::nullopt on error. */ - std::optional> receive(void* buf, size_t bufLen); + std::optional> receive(size_t maxSize = defaultReceiveSize); /** - * Receive Netlink data with address info. + * Receive one or multiple Netlink messages and the sender process address. + * + * WARNING: the underlying buffer is owned by Socket class and the data is valid until the next + * call to the read function or until deallocation of Socket instance. * - * \param buf buffer to hold message data. - * \param bufLen length of buf. - * \param sa Blank struct that recvfrom will populate with address info. - * \return Buffer with message data, std::nullopt on error. + * \param maxSize Maximum total size of received messages + * \return A pair (for use with structured binding) containing: + * - buffer view with message data, std::nullopt on error; + * - sender process address. */ - std::optional> receive(void* buf, size_t bufLen, sockaddr_nl& sa); + std::pair>, sockaddr_nl> receiveFrom( + size_t maxSize = defaultReceiveSize); /** * Receive Netlink ACK message from Kernel. @@ -95,11 +125,11 @@ struct Socket { bool receiveAck(); /** - * Gets the PID assigned to mFd. + * Fetches the socket PID. * - * \return pid that mSocket is bound to. + * \return PID that socket is bound to. */ - std::optional getSocketPid(); + std::optional getPid(); private: const int mProtocol; @@ -107,8 +137,7 @@ struct Socket { uint32_t mSeq = 0; base::unique_fd mFd; bool mFailed = false; - - bool send(nlmsghdr* msg, size_t totalLen); + std::vector mReceiveBuffer; DISALLOW_COPY_AND_ASSIGN(Socket); }; -- GitLab From 09dc1b3f752da7b8e6a56dc5b6674b62f9411e43 Mon Sep 17 00:00:00 2001 From: Tomasz Wasilczyk Date: Tue, 4 Aug 2020 12:12:06 -0700 Subject: [PATCH 095/790] Inclusive language for CAN bus HAL Bug: 162745675 Test: it builds Change-Id: I0f9461cd866ccb51743549d978c9f7367499399e --- automotive/can/1.0/default/CanBus.cpp | 2 +- .../1.0/vts/functional/VtsHalCanBusVirtualV1_0TargetTest.cpp | 2 +- .../1.0/vts/functional/VtsHalCanControllerV1_0TargetTest.cpp | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/automotive/can/1.0/default/CanBus.cpp b/automotive/can/1.0/default/CanBus.cpp index 8b98e5ee2b..2efe0547ea 100644 --- a/automotive/can/1.0/default/CanBus.cpp +++ b/automotive/can/1.0/default/CanBus.cpp @@ -254,7 +254,7 @@ static bool match(const hidl_vec& filter, CanMessageId id, boo satisfiesFilterFlag(rule.extendedFormat, isExtendedId); if (rule.exclude) { - // Any excluded (blacklist) rule not being satisfied invalidates the whole filter set. + // Any exclude rule being satisfied invalidates the whole filter set. if (satisfied) return false; } else { anyNonExcludeRulePresent = true; diff --git a/automotive/can/1.0/vts/functional/VtsHalCanBusVirtualV1_0TargetTest.cpp b/automotive/can/1.0/vts/functional/VtsHalCanBusVirtualV1_0TargetTest.cpp index 8dfd7d6c4d..fc77579058 100644 --- a/automotive/can/1.0/vts/functional/VtsHalCanBusVirtualV1_0TargetTest.cpp +++ b/automotive/can/1.0/vts/functional/VtsHalCanBusVirtualV1_0TargetTest.cpp @@ -86,7 +86,7 @@ struct Bus { EXPECT_EQ(ICanController::Result::OK, result); /* Not using ICanBus::getService here, since it ignores interfaces not in the manifest - * file -- this is a test, so we don't want to add dummy services to a device manifest. */ + * file -- this is a test, so we don't want to add fake services to a device manifest. */ auto manager = hidl::manager::V1_2::IServiceManager::getService(); auto service = manager->get(ICanBus::descriptor, config.name); mBus = ICanBus::castFrom(service); diff --git a/automotive/can/1.0/vts/functional/VtsHalCanControllerV1_0TargetTest.cpp b/automotive/can/1.0/vts/functional/VtsHalCanControllerV1_0TargetTest.cpp index b945978b0b..294cd17758 100644 --- a/automotive/can/1.0/vts/functional/VtsHalCanControllerV1_0TargetTest.cpp +++ b/automotive/can/1.0/vts/functional/VtsHalCanControllerV1_0TargetTest.cpp @@ -119,7 +119,7 @@ bool CanControllerHalTest::up(InterfaceType iftype, std::string srvname, std::st void CanControllerHalTest::assertRegistered(std::string srvname, bool expectRegistered) { /* Not using ICanBus::tryGetService here, since it ignores interfaces not in the manifest - * file -- this is a test, so we don't want to add dummy services to a device manifest. */ + * file -- this is a test, so we don't want to add fake services to a device manifest. */ auto manager = hidl::manager::V1_2::IServiceManager::getService(); auto busService = manager->get(ICanBus::descriptor, srvname); ASSERT_EQ(expectRegistered, busService.withDefault(nullptr) != nullptr) @@ -145,7 +145,7 @@ TEST_P(CanControllerHalTest, BringUpDown) { assertRegistered(name, false); } -TEST_P(CanControllerHalTest, DownDummy) { +TEST_P(CanControllerHalTest, DownFake) { const auto result = mCanController->downInterface("imnotup"); ASSERT_FALSE(result); } -- GitLab From df75bc1dfbc336837b7171c77e8811dfe214fb55 Mon Sep 17 00:00:00 2001 From: lesl Date: Tue, 4 Aug 2020 17:04:57 +0800 Subject: [PATCH 096/790] wifi: Upgrade hostapd HIDL to 1.3 1. Upgrade hostapd HIDL to 1.3 2. Add new callback register in 1.3 3. Update 1.1 vts to ignore register callback test 4. Add Wifi generation define. sinca 1.3 support the new callback Test: Manuel Test. Hotspot works normally. Test: atest VtsHalWifiHostapdV1_0TargetTest Test: atest VtsHalWifiHostapdV1_1TargetTest Test: atest VtsHalWifiHostapdV1_2TargetTest Bug: 151189102 Change-Id: I21b81ce21b8bd22b4ffe70c9b69d36810b1f925f --- .../compatibility_matrix.current.xml | 2 +- wifi/hostapd/1.1/vts/functional/Android.bp | 8 +++- .../1.1/vts/functional/hostapd_hidl_test.cpp | 9 ++++ wifi/hostapd/1.3/Android.bp | 22 ++++++++++ wifi/hostapd/1.3/IHostapd.hal | 44 +++++++++++++++++++ wifi/hostapd/1.3/IHostapdCallback.hal | 27 ++++++++++++ wifi/hostapd/1.3/types.hal | 37 ++++++++++++++++ 7 files changed, 146 insertions(+), 3 deletions(-) create mode 100644 wifi/hostapd/1.3/Android.bp create mode 100644 wifi/hostapd/1.3/IHostapd.hal create mode 100644 wifi/hostapd/1.3/IHostapdCallback.hal create mode 100644 wifi/hostapd/1.3/types.hal diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index 946392458e..d0b08a99bb 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -537,7 +537,7 @@ android.hardware.wifi.hostapd - 1.0-2 + 1.0-3 IHostapd default diff --git a/wifi/hostapd/1.1/vts/functional/Android.bp b/wifi/hostapd/1.1/vts/functional/Android.bp index 291eceb80c..61a8dfd813 100644 --- a/wifi/hostapd/1.1/vts/functional/Android.bp +++ b/wifi/hostapd/1.1/vts/functional/Android.bp @@ -25,11 +25,15 @@ cc_test { "VtsHalWifiHostapdV1_0TargetTestUtil", "android.hardware.wifi.hostapd@1.0", "android.hardware.wifi.hostapd@1.1", + "android.hardware.wifi.hostapd@1.2", + "android.hardware.wifi.hostapd@1.3", "android.hardware.wifi@1.0", "libgmock", "libwifi-system", "libwifi-system-iface", ], - test_suites: ["general-tests", "vts"], + test_suites: [ + "general-tests", + "vts", + ], } - diff --git a/wifi/hostapd/1.1/vts/functional/hostapd_hidl_test.cpp b/wifi/hostapd/1.1/vts/functional/hostapd_hidl_test.cpp index 345cf312d4..0162a9918e 100644 --- a/wifi/hostapd/1.1/vts/functional/hostapd_hidl_test.cpp +++ b/wifi/hostapd/1.1/vts/functional/hostapd_hidl_test.cpp @@ -23,6 +23,7 @@ #include #include +#include #include "hostapd_hidl_call_util.h" #include "hostapd_hidl_test_utils.h" @@ -43,6 +44,7 @@ constexpr unsigned char kNwSsid[] = {'t', 'e', 's', 't', '1', constexpr char kNwPassphrase[] = "test12345"; constexpr int kIfaceChannel = 6; constexpr int kIfaceInvalidChannel = 567; + } // namespace class HostapdHidlTest @@ -170,10 +172,17 @@ class IfaceCallback : public IHostapdCallback { } }; +bool is_1_3(const sp& hostapd) { + sp<::android::hardware::wifi::hostapd::V1_3::IHostapd> hostapd_1_3 = + ::android::hardware::wifi::hostapd::V1_3::IHostapd::castFrom(hostapd); + return hostapd_1_3.get() != nullptr; +} + /* * RegisterCallback */ TEST_P(HostapdHidlTest, registerCallback) { + if (is_1_3(hostapd_)) GTEST_SKIP() << "Ignore since current HIDL over 1.3"; hostapd_->registerCallback( new IfaceCallback(), [](const HostapdStatus& status) { EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); diff --git a/wifi/hostapd/1.3/Android.bp b/wifi/hostapd/1.3/Android.bp new file mode 100644 index 0000000000..aef3267d14 --- /dev/null +++ b/wifi/hostapd/1.3/Android.bp @@ -0,0 +1,22 @@ +// This file is autogenerated by hidl-gen -Landroidbp. + +hidl_interface { + name: "android.hardware.wifi.hostapd@1.3", + root: "android.hardware", + srcs: [ + "types.hal", + "IHostapd.hal", + "IHostapdCallback.hal", + ], + interfaces: [ + "android.hardware.wifi.hostapd@1.0", + "android.hardware.wifi.hostapd@1.1", + "android.hardware.wifi.hostapd@1.2", + "android.hardware.wifi.supplicant@1.0", + "android.hidl.base@1.0", + ], + gen_java: true, + apex_available: [ + "com.android.wifi", + ], +} diff --git a/wifi/hostapd/1.3/IHostapd.hal b/wifi/hostapd/1.3/IHostapd.hal new file mode 100644 index 0000000000..7ac20e43e5 --- /dev/null +++ b/wifi/hostapd/1.3/IHostapd.hal @@ -0,0 +1,44 @@ +/* + * 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. + */ + +package android.hardware.wifi.hostapd@1.3; + +import @1.2::IHostapd; +import @1.2::HostapdStatus; + +import IHostapdCallback; +/** + * Top-level object for managing SoftAPs. + */ +interface IHostapd extends @1.2::IHostapd { + /** + * Register for callbacks from the hostapd service. + * + * These callbacks are invoked for global events that are not specific + * to any interface or network. Registration of multiple callback + * objects is supported. These objects must be deleted when the corresponding + * client process is dead. + * + * @param callback An instance of the |IHostapdCallback| HIDL interface + * object. + * @return status Status of the operation. + * Possible status codes: + * |HostapdStatusCode.SUCCESS|, + * |HostapdStatusCode.FAILURE_UNKNOWN| + */ + registerCallback_1_3(IHostapdCallback callback) + generates (HostapdStatus status); +}; diff --git a/wifi/hostapd/1.3/IHostapdCallback.hal b/wifi/hostapd/1.3/IHostapdCallback.hal new file mode 100644 index 0000000000..5202178935 --- /dev/null +++ b/wifi/hostapd/1.3/IHostapdCallback.hal @@ -0,0 +1,27 @@ +/* + * 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. + */ + +package android.hardware.wifi.hostapd@1.3; + +import @1.1::IHostapdCallback; +import Generation; + +/** + * Top-level callback object for managing SoftAPs. + */ +interface IHostapdCallback extends @1.1::IHostapdCallback { + oneway onInterfaceInfoChanged(string ifaceName, Generation generation); +}; diff --git a/wifi/hostapd/1.3/types.hal b/wifi/hostapd/1.3/types.hal new file mode 100644 index 0000000000..ce092c07a9 --- /dev/null +++ b/wifi/hostapd/1.3/types.hal @@ -0,0 +1,37 @@ +/* + * 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. + */ + +package android.hardware.wifi.hostapd@1.3; + +/** + * The wifi generation which AP reside on. + * It depends on hw mode and HT/VHT capabilities in hostapd. + * + * WIFI_STANDARD_LEGACY = (hw_mode is HOSTAPD_MODE_IEEE80211B) or + * (hw_mode is HOSTAPD_MODE_IEEE80211G and HT is 0). + * WIFI_STANDARD_11N = [hw_mode is HOSTAPD_MODE_IEEE80211G and (HT is 1 or HT40 is 1)] or + * [hw_mode is HOSTAPD_MODE_IEEE80211A and VHT is 0]. + * WIFI_STANDARD_11AC = hw_mode is HOSTAPD_MODE_IEEE80211A and VHT is 1. + * WIFI_STANDARD_11AX = hw_mode is HOSTAPD_MODE_IEEE80211AX. + */ +enum Generation : uint32_t { + WIFI_STANDARD_UNKNOWN = -1, + WIFI_STANDARD_LEGACY = 0, + WIFI_STANDARD_11N = 1, + WIFI_STANDARD_11AC = 2, + WIFI_STANDARD_11AX = 3, +}; + -- GitLab From 713960523dcc4bcf704e51c6a8f1a0e89f150e40 Mon Sep 17 00:00:00 2001 From: Tomasz Wasilczyk Date: Tue, 4 Aug 2020 16:21:39 -0700 Subject: [PATCH 097/790] Implement Socket::receive and refactor Socket::receiveAck Bug: 162032964 Bug: 161389935 Test: canhalctrl up test virtual vcan3 Change-Id: I8bd351cec0d484ee4be8a40908476194958afcb1 --- .../can/1.0/default/libnetdevice/can.cpp | 2 +- .../1.0/default/libnetdevice/libnetdevice.cpp | 4 +- .../can/1.0/default/libnetdevice/vlan.cpp | 2 +- automotive/can/1.0/default/libnl++/Socket.cpp | 69 ++++++++----------- .../default/libnl++/include/libnl++/Message.h | 5 +- .../default/libnl++/include/libnl++/Socket.h | 65 ++++++++++++++--- 6 files changed, 90 insertions(+), 57 deletions(-) diff --git a/automotive/can/1.0/default/libnetdevice/can.cpp b/automotive/can/1.0/default/libnetdevice/can.cpp index ab107fdbaa..5a1105c420 100644 --- a/automotive/can/1.0/default/libnetdevice/can.cpp +++ b/automotive/can/1.0/default/libnetdevice/can.cpp @@ -91,7 +91,7 @@ bool setBitrate(std::string ifname, uint32_t bitrate) { } nl::Socket sock(NETLINK_ROUTE); - return sock.send(req) && sock.receiveAck(); + return sock.send(req) && sock.receiveAck(req); } } // namespace android::netdevice::can diff --git a/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp b/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp index ed2a51e864..e2ba2cb311 100644 --- a/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp +++ b/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp @@ -72,7 +72,7 @@ bool add(std::string dev, std::string type) { } nl::Socket sock(NETLINK_ROUTE); - return sock.send(req) && sock.receiveAck(); + return sock.send(req) && sock.receiveAck(req); } bool del(std::string dev) { @@ -80,7 +80,7 @@ bool del(std::string dev) { req.addattr(IFLA_IFNAME, dev); nl::Socket sock(NETLINK_ROUTE); - return sock.send(req) && sock.receiveAck(); + return sock.send(req) && sock.receiveAck(req); } std::optional getHwAddr(const std::string& ifname) { diff --git a/automotive/can/1.0/default/libnetdevice/vlan.cpp b/automotive/can/1.0/default/libnetdevice/vlan.cpp index 3f904f0b02..33dc029833 100644 --- a/automotive/can/1.0/default/libnetdevice/vlan.cpp +++ b/automotive/can/1.0/default/libnetdevice/vlan.cpp @@ -49,7 +49,7 @@ bool add(const std::string& eth, const std::string& vlan, uint16_t id) { } nl::Socket sock(NETLINK_ROUTE); - return sock.send(req) && sock.receiveAck(); + return sock.send(req) && sock.receiveAck(req); } } // namespace android::netdevice::vlan diff --git a/automotive/can/1.0/default/libnl++/Socket.cpp b/automotive/can/1.0/default/libnl++/Socket.cpp index 56e990c23f..1a34df8d85 100644 --- a/automotive/can/1.0/default/libnl++/Socket.cpp +++ b/automotive/can/1.0/default/libnl++/Socket.cpp @@ -103,60 +103,45 @@ std::pair>, sockaddr_nl> Socket::receiveFrom(size return {msg, sa}; } -/* TODO(161389935): Migrate receiveAck to use nlmsg<> internally. Possibly reuse - * Socket::receive(). */ -bool Socket::receiveAck() { - if (mFailed) return false; - - char buf[8192]; - - sockaddr_nl sa; - iovec iov = {buf, sizeof(buf)}; - - msghdr msg = {}; - msg.msg_name = &sa; - msg.msg_namelen = sizeof(sa); - msg.msg_iov = &iov; - msg.msg_iovlen = 1; +bool Socket::receiveAck(uint32_t seq) { + const auto nlerr = receive({NLMSG_ERROR}); + if (!nlerr.has_value()) return false; - const ssize_t status = recvmsg(mFd.get(), &msg, 0); - if (status < 0) { - PLOG(ERROR) << "Failed to receive Netlink message"; + if (nlerr->data.msg.nlmsg_seq != seq) { + LOG(ERROR) << "Received ACK for a different message (" << nlerr->data.msg.nlmsg_seq + << ", expected " << seq << "). Multi-message tracking is not implemented."; return false; } - size_t remainingLen = status; - if (msg.msg_flags & MSG_TRUNC) { - LOG(ERROR) << "Failed to receive Netlink message: truncated"; - return false; - } + if (nlerr->data.error == 0) return true; - for (auto nlmsg = reinterpret_cast(buf); NLMSG_OK(nlmsg, remainingLen); - nlmsg = NLMSG_NEXT(nlmsg, remainingLen)) { - if constexpr (kSuperVerbose) { - LOG(VERBOSE) << "received Netlink response: " - << toString({nlmsg, nlmsg->nlmsg_len}, mProtocol); - } + LOG(WARNING) << "Received Netlink error message: " << strerror(-nlerr->data.error); + return false; +} - // We're looking for error/ack message only, ignoring others. - if (nlmsg->nlmsg_type != NLMSG_ERROR) { - LOG(WARNING) << "Received unexpected Netlink message (ignored): " << nlmsg->nlmsg_type; - continue; - } +std::optional> Socket::receive(const std::set& msgtypes, + size_t maxSize) { + while (!mFailed) { + const auto msgBuf = receive(maxSize); + if (!msgBuf.has_value()) return std::nullopt; + + for (const auto rawMsg : *msgBuf) { + if (msgtypes.count(rawMsg->nlmsg_type) == 0) { + LOG(WARNING) << "Received (and ignored) unexpected Netlink message of type " + << rawMsg->nlmsg_type; + continue; + } - // Found error/ack message, return status. - const auto nlerr = reinterpret_cast(NLMSG_DATA(nlmsg)); - if (nlerr->error != 0) { - LOG(ERROR) << "Received Netlink error message: " << strerror(-nlerr->error); - return false; + return rawMsg; } - return true; } - // Couldn't find any error/ack messages. - return false; + + return std::nullopt; } std::optional Socket::getPid() { + if (mFailed) return std::nullopt; + sockaddr_nl sa = {}; socklen_t sasize = sizeof(sa); if (getsockname(mFd.get(), reinterpret_cast(&sa), &sasize) < 0) { diff --git a/automotive/can/1.0/default/libnl++/include/libnl++/Message.h b/automotive/can/1.0/default/libnl++/include/libnl++/Message.h index 2b84a869e2..50b3c4b05d 100644 --- a/automotive/can/1.0/default/libnl++/include/libnl++/Message.h +++ b/automotive/can/1.0/default/libnl++/include/libnl++/Message.h @@ -19,6 +19,8 @@ #include #include +#include + namespace android::nl { /** @@ -60,7 +62,8 @@ class Message { * \return Parsed message or nullopt, if the buffer data is invalid or message type * doesn't match. */ - static std::optional> parse(Buffer buf, std::set msgtypes) { + static std::optional> parse(Buffer buf, + const std::set& msgtypes) { const auto& [nlOk, nlHeader] = buf.getFirst(); // we're doing it twice, but it's fine if (!nlOk) return std::nullopt; diff --git a/automotive/can/1.0/default/libnl++/include/libnl++/Socket.h b/automotive/can/1.0/default/libnl++/include/libnl++/Socket.h index bc6ad9df54..16b63f57da 100644 --- a/automotive/can/1.0/default/libnl++/include/libnl++/Socket.h +++ b/automotive/can/1.0/default/libnl++/include/libnl++/Socket.h @@ -19,11 +19,13 @@ #include #include #include +#include #include #include #include +#include #include namespace android::nl { @@ -57,7 +59,7 @@ class Socket { * \param msg Message to send. Its sequence number will be updated. * \return true, if succeeded. */ - template + template bool send(MessageFactory& req) { sockaddr_nl sa = {}; sa.nl_family = AF_NETLINK; @@ -72,7 +74,7 @@ class Socket { * \param sa Destination address. * \return true, if succeeded. */ - template + template bool send(MessageFactory& req, const sockaddr_nl& sa) { if (!req.isGood()) return false; @@ -109,7 +111,7 @@ class Socket { * WARNING: the underlying buffer is owned by Socket class and the data is valid until the next * call to the read function or until deallocation of Socket instance. * - * \param maxSize Maximum total size of received messages + * \param maxSize Maximum total size of received messages. * \return A pair (for use with structured binding) containing: * - buffer view with message data, std::nullopt on error; * - sender process address. @@ -118,27 +120,70 @@ class Socket { size_t maxSize = defaultReceiveSize); /** - * Receive Netlink ACK message from Kernel. + * Receive matching Netlink message of a given payload type. + * + * This method should be used if the caller expects exactly one incoming message of exactly + * given type (such as ACK). If there is a use case to handle multiple types of messages, + * please use receive(size_t) directly and iterate through potential multipart messages. + * + * If this method is used in such an environment, it will only return the first matching message + * from multipart packet and will issue warnings on messages that do not match. + * + * \param msgtypes Expected message types (such as NLMSG_ERROR). + * \param maxSize Maximum total size of received messages. + * \return Parsed message or std::nullopt in case of error. + */ + template + std::optional> receive(const std::set& msgtypes, + size_t maxSize = defaultReceiveSize) { + const auto msg = receive(msgtypes, maxSize); + if (!msg.has_value()) return std::nullopt; + + const auto parsed = Message::parse(*msg); + if (!parsed.has_value()) { + LOG(WARNING) << "Received matching Netlink message, but couldn't parse it"; + return std::nullopt; + } + + return parsed; + } + + /** + * Receive Netlink ACK message. + * + * \param req Message to match sequence number against. + * \return true if received ACK message, false in case of error. + */ + template + bool receiveAck(MessageFactory& req) { + return receiveAck(req.header()->nlmsg_seq); + } + + /** + * Receive Netlink ACK message. * - * \return true if received ACK message, false in case of error + * \param seq Sequence number of message to ACK. + * \return true if received ACK message, false in case of error. */ - bool receiveAck(); + bool receiveAck(uint32_t seq); /** * Fetches the socket PID. * - * \return PID that socket is bound to. + * \return PID that socket is bound to or std::nullopt. */ std::optional getPid(); private: const int mProtocol; - - uint32_t mSeq = 0; base::unique_fd mFd; - bool mFailed = false; std::vector mReceiveBuffer; + bool mFailed = false; + uint32_t mSeq = 0; + + std::optional> receive(const std::set& msgtypes, size_t maxSize); + DISALLOW_COPY_AND_ASSIGN(Socket); }; -- GitLab From 3ab105b13dcb95c295242adf4b40cbb1b6ad4056 Mon Sep 17 00:00:00 2001 From: Tomasz Wasilczyk Date: Wed, 5 Aug 2020 14:07:40 -0700 Subject: [PATCH 098/790] Refactor MessageFactory While we're here, also drop struct keywords where we use Linux structures. Bug: 162032964 Test: canhalctrl up test virtual vcan3 Change-Id: Ib629cad3d2203b998668f45534699292863cadd9 --- .../can/1.0/default/libnetdevice/can.cpp | 21 ++- .../1.0/default/libnetdevice/libnetdevice.cpp | 14 +- .../can/1.0/default/libnetdevice/vlan.cpp | 16 +- .../1.0/default/libnl++/MessageFactory.cpp | 41 +++-- .../default/libnl++/include/libnl++/Buffer.h | 18 +-- .../libnl++/include/libnl++/MessageFactory.h | 144 ++++++++++-------- .../default/libnl++/include/libnl++/Socket.h | 11 +- .../default/libnl++/include/libnl++/bits.h | 54 +++++++ .../protocols/generic/GenericMessageBase.cpp | 4 +- .../protocols/generic/GenericMessageBase.h | 4 +- .../default/libnl++/protocols/route/Link.cpp | 4 +- .../default/libnl++/protocols/route/Link.h | 4 +- 12 files changed, 191 insertions(+), 144 deletions(-) create mode 100644 automotive/can/1.0/default/libnl++/include/libnl++/bits.h diff --git a/automotive/can/1.0/default/libnetdevice/can.cpp b/automotive/can/1.0/default/libnetdevice/can.cpp index 5a1105c420..083f4f0028 100644 --- a/automotive/can/1.0/default/libnetdevice/can.cpp +++ b/automotive/can/1.0/default/libnetdevice/can.cpp @@ -34,7 +34,7 @@ namespace android::netdevice::can { static constexpr can_err_mask_t kErrMask = CAN_ERR_MASK; base::unique_fd socket(const std::string& ifname) { - struct sockaddr_can addr = {}; + sockaddr_can addr = {}; addr.can_family = AF_CAN; addr.can_ifindex = nametoindex(ifname); if (addr.can_ifindex == 0) { @@ -58,7 +58,7 @@ base::unique_fd socket(const std::string& ifname) { return {}; } - if (0 != bind(sock.get(), reinterpret_cast(&addr), sizeof(addr))) { + if (0 != bind(sock.get(), reinterpret_cast(&addr), sizeof(addr))) { LOG(ERROR) << "Can't bind to CAN interface " << ifname; return {}; } @@ -67,26 +67,25 @@ base::unique_fd socket(const std::string& ifname) { } bool setBitrate(std::string ifname, uint32_t bitrate) { - struct can_bittiming bt = {}; + can_bittiming bt = {}; bt.bitrate = bitrate; - nl::MessageFactory req(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_ACK); + nl::MessageFactory req(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_ACK); - const auto ifidx = nametoindex(ifname); - if (ifidx == 0) { + req->ifi_index = nametoindex(ifname); + if (req->ifi_index == 0) { LOG(ERROR) << "Can't find interface " << ifname; return false; } - req.data().ifi_index = ifidx; { - auto linkinfo = req.nest(IFLA_LINKINFO); - req.addattr(IFLA_INFO_KIND, "can"); + auto linkinfo = req.addNested(IFLA_LINKINFO); + req.add(IFLA_INFO_KIND, "can"); { - auto infodata = req.nest(IFLA_INFO_DATA); + auto infodata = req.addNested(IFLA_INFO_DATA); /* For CAN FD, it would require to add IFLA_CAN_DATA_BITTIMING * and IFLA_CAN_CTRLMODE as well. */ - req.addattr(IFLA_CAN_BITTIMING, bt); + req.add(IFLA_CAN_BITTIMING, bt); } } diff --git a/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp b/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp index e2ba2cb311..9447c0c31f 100644 --- a/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp +++ b/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp @@ -62,13 +62,13 @@ bool down(std::string ifname) { } bool add(std::string dev, std::string type) { - nl::MessageFactory req(RTM_NEWLINK, - NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL | NLM_F_ACK); - req.addattr(IFLA_IFNAME, dev); + nl::MessageFactory req(RTM_NEWLINK, + NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL | NLM_F_ACK); + req.add(IFLA_IFNAME, dev); { - auto linkinfo = req.nest(IFLA_LINKINFO); - req.addattr(IFLA_INFO_KIND, type); + auto linkinfo = req.addNested(IFLA_LINKINFO); + req.add(IFLA_INFO_KIND, type); } nl::Socket sock(NETLINK_ROUTE); @@ -76,8 +76,8 @@ bool add(std::string dev, std::string type) { } bool del(std::string dev) { - nl::MessageFactory req(RTM_DELLINK, NLM_F_REQUEST | NLM_F_ACK); - req.addattr(IFLA_IFNAME, dev); + nl::MessageFactory req(RTM_DELLINK, NLM_F_REQUEST | NLM_F_ACK); + req.add(IFLA_IFNAME, dev); nl::Socket sock(NETLINK_ROUTE); return sock.send(req) && sock.receiveAck(req); diff --git a/automotive/can/1.0/default/libnetdevice/vlan.cpp b/automotive/can/1.0/default/libnetdevice/vlan.cpp index 33dc029833..ee02f7b58a 100644 --- a/automotive/can/1.0/default/libnetdevice/vlan.cpp +++ b/automotive/can/1.0/default/libnetdevice/vlan.cpp @@ -33,18 +33,18 @@ bool add(const std::string& eth, const std::string& vlan, uint16_t id) { return false; } - nl::MessageFactory req(RTM_NEWLINK, - NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL | NLM_F_ACK); - req.addattr(IFLA_IFNAME, vlan); - req.addattr(IFLA_LINK, ethidx); + nl::MessageFactory req(RTM_NEWLINK, + NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL | NLM_F_ACK); + req.add(IFLA_IFNAME, vlan); + req.add(IFLA_LINK, ethidx); { - auto linkinfo = req.nest(IFLA_LINKINFO); - req.addattr(IFLA_INFO_KIND, "vlan"); + auto linkinfo = req.addNested(IFLA_LINKINFO); + req.add(IFLA_INFO_KIND, "vlan"); { - auto linkinfo = req.nest(IFLA_INFO_DATA); - req.addattr(IFLA_VLAN_ID, id); + auto linkinfo = req.addNested(IFLA_INFO_DATA); + req.add(IFLA_VLAN_ID, id); } } diff --git a/automotive/can/1.0/default/libnl++/MessageFactory.cpp b/automotive/can/1.0/default/libnl++/MessageFactory.cpp index 0c6a3315da..6f35897e32 100644 --- a/automotive/can/1.0/default/libnl++/MessageFactory.cpp +++ b/automotive/can/1.0/default/libnl++/MessageFactory.cpp @@ -17,41 +17,36 @@ #include #include +#include -// for RTA_ macros missing from NLA_ definitions -#include +namespace android::nl { -namespace android::nl::impl { - -static struct nlattr* nlmsg_tail(struct nlmsghdr* n) { - return reinterpret_cast( // - reinterpret_cast(n) + NLMSG_ALIGN(n->nlmsg_len)); +static nlattr* tail(nlmsghdr* msg) { + return reinterpret_cast(uintptr_t(msg) + impl::align(msg->nlmsg_len)); } -struct nlattr* addattr_l(struct nlmsghdr* n, size_t maxLen, nlattrtype_t type, const void* data, - size_t dataLen) { - size_t newLen = NLMSG_ALIGN(n->nlmsg_len) + RTA_SPACE(dataLen); +nlattr* MessageFactoryBase::add(nlmsghdr* msg, size_t maxLen, nlattrtype_t type, const void* data, + size_t dataLen) { + const auto totalAttrLen = impl::space(dataLen); + const auto newLen = impl::align(msg->nlmsg_len) + totalAttrLen; if (newLen > maxLen) { - LOG(ERROR) << "addattr_l failed - exceeded maxLen: " << newLen << " > " << maxLen; + LOG(ERROR) << "Can't add attribute of size " << dataLen // + << " - exceeded maxLen: " << newLen << " > " << maxLen; return nullptr; } - auto attr = nlmsg_tail(n); - attr->nla_len = RTA_SPACE(dataLen); + auto attr = tail(msg); + attr->nla_len = totalAttrLen; attr->nla_type = type; - if (dataLen > 0) memcpy(RTA_DATA(attr), data, dataLen); + if (dataLen > 0) memcpy(impl::data(attr), data, dataLen); - n->nlmsg_len = newLen; + msg->nlmsg_len = newLen; return attr; } -struct nlattr* addattr_nest(struct nlmsghdr* n, size_t maxLen, nlattrtype_t type) { - return addattr_l(n, maxLen, type, nullptr, 0); -} - -void addattr_nest_end(struct nlmsghdr* n, struct nlattr* nest) { - size_t nestLen = reinterpret_cast(nlmsg_tail(n)) - reinterpret_cast(nest); - nest->nla_len = nestLen; +void MessageFactoryBase::closeNested(nlmsghdr* msg, nlattr* nested) { + if (nested == nullptr) return; + nested->nla_len = uintptr_t(tail(msg)) - uintptr_t(nested); } -} // namespace android::nl::impl +} // namespace android::nl diff --git a/automotive/can/1.0/default/libnl++/include/libnl++/Buffer.h b/automotive/can/1.0/default/libnl++/include/libnl++/Buffer.h index a6f8f7a8f1..c3137c8994 100644 --- a/automotive/can/1.0/default/libnl++/include/libnl++/Buffer.h +++ b/automotive/can/1.0/default/libnl++/include/libnl++/Buffer.h @@ -17,6 +17,7 @@ #pragma once #include +#include #include @@ -25,7 +26,7 @@ namespace android::nl { /** - * Buffer wrapper containing netlink structure (e.g. struct nlmsghdr, struct nlattr). + * Buffer wrapper containing netlink structure (e.g. nlmsghdr, nlattr). * * This is a C++-style, memory safe(r) and generic implementation of linux/netlink.h macros. * @@ -43,15 +44,6 @@ namespace android::nl { */ template class Buffer { - // The following definitions are C++ equivalents of NLMSG_* macros from linux/netlink.h - - static constexpr size_t alignto = NLMSG_ALIGNTO; - static_assert(NLMSG_ALIGNTO == NLA_ALIGNTO); - - static constexpr size_t align(size_t ptr) { return (ptr + alignto - 1) & ~(alignto - 1); } - - static constexpr size_t hdrlen = align(sizeof(T)); - public: /** * Constructs empty buffer of size 0. @@ -96,9 +88,7 @@ class Buffer { template const Buffer data(size_t offset = 0) const { - // Equivalent to NLMSG_DATA(hdr) + NLMSG_ALIGN(offset) - const D* dptr = reinterpret_cast(uintptr_t(mData) + hdrlen + align(offset)); - return {dptr, dataEnd()}; + return {impl::data(mData, offset), dataEnd()}; } class iterator { @@ -111,7 +101,7 @@ class Buffer { iterator operator++() { // mBufferEnd stays the same mCurrent.mData = reinterpret_cast( // - uintptr_t(mCurrent.mData) + align(mCurrent.declaredLength())); + uintptr_t(mCurrent.mData) + impl::align(mCurrent.declaredLength())); return *this; } diff --git a/automotive/can/1.0/default/libnl++/include/libnl++/MessageFactory.h b/automotive/can/1.0/default/libnl++/include/libnl++/MessageFactory.h index 5272577b53..c3d72c54e2 100644 --- a/automotive/can/1.0/default/libnl++/include/libnl++/MessageFactory.h +++ b/automotive/can/1.0/default/libnl++/include/libnl++/MessageFactory.h @@ -17,6 +17,7 @@ #pragma once #include +#include #include #include @@ -25,131 +26,140 @@ namespace android::nl { -/** Implementation details, do not use outside MessageFactory template. */ -namespace impl { - -struct nlattr* addattr_l(struct nlmsghdr* n, size_t maxLen, nlattrtype_t type, const void* data, - size_t dataLen); -struct nlattr* addattr_nest(struct nlmsghdr* n, size_t maxLen, nlattrtype_t type); -void addattr_nest_end(struct nlmsghdr* n, struct nlattr* nest); - -} // namespace impl +class MessageFactoryBase { + protected: + static nlattr* add(nlmsghdr* msg, size_t maxLen, nlattrtype_t type, const void* data, + size_t dataLen); + static void closeNested(nlmsghdr* msg, nlattr* nested); +}; /** * Wrapper around NETLINK_ROUTE messages, to build them in C++ style. * - * \param T specific message header (such as struct ifinfomsg) - * \param BUFSIZE how much space to reserve for payload (not counting the header size) + * \param T Message payload type (such as ifinfomsg). + * \param BUFSIZE how much space to reserve for attributes. */ template -struct MessageFactory { - struct RequestData { - struct nlmsghdr nlmsg; +class MessageFactory : private MessageFactoryBase { + struct alignas(NLMSG_ALIGNTO) Message { + nlmsghdr header; T data; - char buf[BUFSIZE]; + uint8_t attributesBuffer[BUFSIZE]; }; - static constexpr size_t totalLength = sizeof(RequestData); - + public: /** * Create empty message. * - * \param type Message type (such as RTM_NEWLINK) - * \param flags Message flags (such as NLM_F_REQUEST) + * \param type Message type (such as RTM_NEWLINK). + * \param flags Message flags (such as NLM_F_REQUEST). */ - MessageFactory(nlmsgtype_t type, uint16_t flags) { - mRequest.nlmsg.nlmsg_len = NLMSG_LENGTH(sizeof(mRequest.data)); - mRequest.nlmsg.nlmsg_type = type; - mRequest.nlmsg.nlmsg_flags = flags; + MessageFactory(nlmsgtype_t type, uint16_t flags) + : header(mMessage.header), data(mMessage.data) { + mMessage.header.nlmsg_len = offsetof(Message, attributesBuffer); + mMessage.header.nlmsg_type = type; + mMessage.header.nlmsg_flags = flags; } - /** \return pointer to raw netlink message header. */ - struct nlmsghdr* header() { - return &mRequest.nlmsg; + /** + * Netlink message header. + * + * This is a generic Netlink header containing information such as message flags. + */ + nlmsghdr& header; + + /** + * Netlink message data. + * + * This is a payload specific to a given message type. + */ + T& data; + + T* operator->() { return &mMessage.data; } + + /** + * Build netlink message. + * + * In fact, this operation is almost a no-op, since the factory builds the message in a single + * buffer, using native data structures. + * + * A likely failure case is when the BUFSIZE template parameter is too small to acommodate + * added attributes. In such a case, please increase this parameter. + * + * \return Netlink message or std::nullopt in case of failure. + */ + std::optional> build() const { + if (!mIsGood) return std::nullopt; + return {{&mMessage.header, mMessage.header.nlmsg_len}}; } - /** Reference to message-specific header. */ - T& data() { return mRequest.data; } /** - * Adds an attribute of a simple type. + * Adds an attribute of a trivially copyable type. + * + * Template specializations may extend this function for other types, such as std::string. * - * If this method fails (i.e. due to insufficient space), the message will be marked - * as bad (\see isGood). + * If this method fails (i.e. due to insufficient space), a warning will be printed to the log + * and the message will be marked as bad, causing later \see build call to fail. * * \param type attribute type (such as IFLA_IFNAME) * \param attr attribute data */ template - void addattr(nlattrtype_t type, const A& attr) { - if (!mIsGood) return; - auto ap = impl::addattr_l(&mRequest.nlmsg, sizeof(mRequest), type, &attr, sizeof(attr)); - if (ap == nullptr) mIsGood = false; + void add(nlattrtype_t type, const A& attr) { + add(type, &attr, sizeof(attr)); } template <> - void addattr(nlattrtype_t type, const std::string& s) { - if (!mIsGood) return; - auto ap = impl::addattr_l(&mRequest.nlmsg, sizeof(mRequest), type, s.c_str(), s.size() + 1); - if (ap == nullptr) mIsGood = false; + void add(nlattrtype_t type, const std::string& s) { + add(type, s.c_str(), s.size() + 1); } - /** Guard class to frame nested attributes. See nest(int). */ - struct Nest { - Nest(MessageFactory& req, nlattrtype_t type) : mReq(req), mAttr(req.nestStart(type)) {} - ~Nest() { mReq.nestEnd(mAttr); } + /** Guard class to frame nested attributes. \see addNested(nlattrtype_t). */ + class [[nodiscard]] NestedGuard { + public: + NestedGuard(MessageFactory & req, nlattrtype_t type) : mReq(req), mAttr(req.add(type)) {} + ~NestedGuard() { closeNested(&mReq.mMessage.header, mAttr); } private: MessageFactory& mReq; - struct nlattr* mAttr; + nlattr* mAttr; - DISALLOW_COPY_AND_ASSIGN(Nest); + DISALLOW_COPY_AND_ASSIGN(NestedGuard); }; /** * Add nested attribute. * * The returned object is a guard for auto-nesting children inside the argument attribute. - * When the Nest object goes out of scope, the nesting attribute is closed. + * When the guard object goes out of scope, the nesting attribute is closed. * * Example usage nesting IFLA_CAN_BITTIMING inside IFLA_INFO_DATA, which is nested * inside IFLA_LINKINFO: - * MessageFactory req(RTM_NEWLINK, NLM_F_REQUEST); + * MessageFactory req(RTM_NEWLINK, NLM_F_REQUEST); * { - * auto linkinfo = req.nest(IFLA_LINKINFO); - * req.addattr(IFLA_INFO_KIND, "can"); + * auto linkinfo = req.addNested(IFLA_LINKINFO); + * req.add(IFLA_INFO_KIND, "can"); * { - * auto infodata = req.nest(IFLA_INFO_DATA); - * req.addattr(IFLA_CAN_BITTIMING, bitTimingStruct); + * auto infodata = req.addNested(IFLA_INFO_DATA); + * req.add(IFLA_CAN_BITTIMING, bitTimingStruct); * } * } * // use req * * \param type attribute type (such as IFLA_LINKINFO) */ - Nest nest(int type) { return Nest(*this, type); } - - /** - * Indicates, whether the message is in a good state. - * - * The bad state is usually a result of payload buffer being too small. - * You can modify BUFSIZE template parameter to fix this. - */ - bool isGood() const { return mIsGood; } + NestedGuard addNested(nlattrtype_t type) { return {*this, type}; } private: + Message mMessage = {}; bool mIsGood = true; - RequestData mRequest = {}; - struct nlattr* nestStart(nlattrtype_t type) { + nlattr* add(nlattrtype_t type, const void* data = nullptr, size_t len = 0) { if (!mIsGood) return nullptr; - auto attr = impl::addattr_nest(&mRequest.nlmsg, sizeof(mRequest), type); + auto attr = MessageFactoryBase::add(&mMessage.header, sizeof(mMessage), type, data, len); if (attr == nullptr) mIsGood = false; return attr; } - - void nestEnd(struct nlattr* nest) { - if (mIsGood && nest != nullptr) impl::addattr_nest_end(&mRequest.nlmsg, nest); - } }; } // namespace android::nl diff --git a/automotive/can/1.0/default/libnl++/include/libnl++/Socket.h b/automotive/can/1.0/default/libnl++/include/libnl++/Socket.h index 16b63f57da..6a4e82e25b 100644 --- a/automotive/can/1.0/default/libnl++/include/libnl++/Socket.h +++ b/automotive/can/1.0/default/libnl++/include/libnl++/Socket.h @@ -76,13 +76,12 @@ class Socket { */ template bool send(MessageFactory& req, const sockaddr_nl& sa) { - if (!req.isGood()) return false; + req.header.nlmsg_seq = mSeq + 1; - const auto nlmsg = req.header(); - nlmsg->nlmsg_seq = mSeq + 1; + const auto msg = req.build(); + if (!msg.has_value()) return false; - // With MessageFactory<>, we trust nlmsg_len to be correct. - return send({nlmsg, nlmsg->nlmsg_len}, sa); + return send(*msg, sa); } /** @@ -156,7 +155,7 @@ class Socket { */ template bool receiveAck(MessageFactory& req) { - return receiveAck(req.header()->nlmsg_seq); + return receiveAck(req.header.nlmsg_seq); } /** diff --git a/automotive/can/1.0/default/libnl++/include/libnl++/bits.h b/automotive/can/1.0/default/libnl++/include/libnl++/bits.h new file mode 100644 index 0000000000..4c8f1aa9a1 --- /dev/null +++ b/automotive/can/1.0/default/libnl++/include/libnl++/bits.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +namespace android::nl::impl { + +// The following definitions are C++ equivalents of NLMSG_* macros from linux/netlink.h. + +/** + * Equivalent to NLMSG_ALIGNTO. + */ +constexpr size_t alignto = NLMSG_ALIGNTO; +static_assert(NLMSG_ALIGNTO == NLA_ALIGNTO); + +/** + * Equivalent to NLMSG_ALIGN(len). + */ +constexpr size_t align(size_t len) { + return (len + alignto - 1) & ~(alignto - 1); +} + +/** + * Equivalent to NLMSG_SPACE(len). + */ +template +constexpr size_t space(size_t len) { + return align(align(sizeof(H)) + len); +} + +/** + * Equivalent to NLMSG_DATA(hdr) + NLMSG_ALIGN(offset). + */ +template +constexpr D* data(H* header, size_t offset = 0) { + return reinterpret_cast(uintptr_t(header) + space(offset)); +} + +} // namespace android::nl::impl diff --git a/automotive/can/1.0/default/libnl++/protocols/generic/GenericMessageBase.cpp b/automotive/can/1.0/default/libnl++/protocols/generic/GenericMessageBase.cpp index 520336855e..877bb2158a 100644 --- a/automotive/can/1.0/default/libnl++/protocols/generic/GenericMessageBase.cpp +++ b/automotive/can/1.0/default/libnl++/protocols/generic/GenericMessageBase.cpp @@ -22,10 +22,10 @@ GenericMessageBase::GenericMessageBase( nlmsgtype_t msgtype, std::string msgname, const std::initializer_list commandNames, const std::initializer_list attrTypes) - : MessageDefinition(msgname, {{msgtype, msgname}}, attrTypes), + : MessageDefinition(msgname, {{msgtype, msgname}}, attrTypes), mCommandNames(commandNames) {} -void GenericMessageBase::toStream(std::stringstream& ss, const struct genlmsghdr& data) const { +void GenericMessageBase::toStream(std::stringstream& ss, const genlmsghdr& data) const { ss << "genlmsghdr{"; if (mCommandNames.count(data.cmd) == 0) { ss << "cmd=" << unsigned(data.cmd); diff --git a/automotive/can/1.0/default/libnl++/protocols/generic/GenericMessageBase.h b/automotive/can/1.0/default/libnl++/protocols/generic/GenericMessageBase.h index f3b0b31add..f0ee5b0978 100644 --- a/automotive/can/1.0/default/libnl++/protocols/generic/GenericMessageBase.h +++ b/automotive/can/1.0/default/libnl++/protocols/generic/GenericMessageBase.h @@ -22,7 +22,7 @@ namespace android::nl::protocols::generic { -class GenericMessageBase : public MessageDefinition { +class GenericMessageBase : public MessageDefinition { public: typedef std::map GenericCommandNameMap; @@ -31,7 +31,7 @@ class GenericMessageBase : public MessageDefinition { const std::initializer_list commandNames = {}, const std::initializer_list attrTypes = {}); - void toStream(std::stringstream& ss, const struct genlmsghdr& data) const override; + void toStream(std::stringstream& ss, const genlmsghdr& data) const override; private: const GenericCommandNameMap mCommandNames; diff --git a/automotive/can/1.0/default/libnl++/protocols/route/Link.cpp b/automotive/can/1.0/default/libnl++/protocols/route/Link.cpp index 26d3e3e8f5..bc44d8eda3 100644 --- a/automotive/can/1.0/default/libnl++/protocols/route/Link.cpp +++ b/automotive/can/1.0/default/libnl++/protocols/route/Link.cpp @@ -25,7 +25,7 @@ namespace android::nl::protocols::route { using DataType = AttributeDefinition::DataType; // clang-format off -Link::Link() : MessageDefinition("link", { +Link::Link() : MessageDefinition("link", { {RTM_NEWLINK, "NEWLINK"}, {RTM_DELLINK, "DELLINK"}, {RTM_GETLINK, "GETLINK"}, @@ -107,7 +107,7 @@ Link::Link() : MessageDefinition("link", { }) {} // clang-format off -void Link::toStream(std::stringstream& ss, const struct ifinfomsg& data) const { +void Link::toStream(std::stringstream& ss, const ifinfomsg& data) const { ss << "ifinfomsg{" << "family=" << unsigned(data.ifi_family) << ", type=" << data.ifi_type << ", index=" << data.ifi_index << ", flags=" << data.ifi_flags diff --git a/automotive/can/1.0/default/libnl++/protocols/route/Link.h b/automotive/can/1.0/default/libnl++/protocols/route/Link.h index 4ea3ebaf72..ecfefc928b 100644 --- a/automotive/can/1.0/default/libnl++/protocols/route/Link.h +++ b/automotive/can/1.0/default/libnl++/protocols/route/Link.h @@ -22,10 +22,10 @@ namespace android::nl::protocols::route { -class Link : public MessageDefinition { +class Link : public MessageDefinition { public: Link(); - void toStream(std::stringstream& ss, const struct ifinfomsg& data) const override; + void toStream(std::stringstream& ss, const ifinfomsg& data) const override; }; } // namespace android::nl::protocols::route -- GitLab From cc9207ccc0a29c3b4891c9b1b2e8b831f1409126 Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Tue, 4 Aug 2020 15:49:51 -0700 Subject: [PATCH 099/790] Move Tuner 1.1 new RecordFilterEvent fields into a separate struct Previously we added the PTS and the mpuSequenceNumber separately into the tsRecord and the mmtpRecord filter event data structure. Now there is a better way that we merge all the new fields into one new struct to pass as a callback parameter. With this approach, we can minimize the change in both Tuner JNI and Tuner HAL implementation side to reuse the 1.0 structure and implementation. Test: atest VtsHalTvTunerV1_1TargetTest Bug: 158816517 Change-Id: Ic4f1dc78f76fb52ee0bc6b90d2d297026a788711 --- tv/tuner/1.1/IFilterCallback.hal | 8 +-- tv/tuner/1.1/default/Filter.cpp | 45 ++++++++-------- tv/tuner/1.1/default/Filter.h | 2 +- tv/tuner/1.1/types.hal | 57 +++++---------------- tv/tuner/1.1/vts/functional/FilterTests.cpp | 11 ++-- tv/tuner/1.1/vts/functional/FilterTests.h | 8 ++- 6 files changed, 50 insertions(+), 81 deletions(-) diff --git a/tv/tuner/1.1/IFilterCallback.hal b/tv/tuner/1.1/IFilterCallback.hal index a80273b462..3e5f047f22 100644 --- a/tv/tuner/1.1/IFilterCallback.hal +++ b/tv/tuner/1.1/IFilterCallback.hal @@ -17,13 +17,15 @@ package android.hardware.tv.tuner@1.1; import @1.0::IFilterCallback; -import @1.1::DemuxFilterEvent; +import @1.0::DemuxFilterEvent; +import @1.1::DemuxFilterEventExt; interface IFilterCallback extends @1.0::IFilterCallback { /** * Notify the client that a new filter event happened. * - * @param filterEvent a v1_1 filter event. + * @param filterEvent a v1_0 filter event. + * @param filterEventExt a v1_1 extended filter event. */ - oneway onFilterEvent_1_1(DemuxFilterEvent filterEvent); + oneway onFilterEvent_1_1(DemuxFilterEvent filterEvent, DemuxFilterEventExt filterEventExt); }; diff --git a/tv/tuner/1.1/default/Filter.cpp b/tv/tuner/1.1/default/Filter.cpp index 4d08afe6f5..fae83a2fb2 100644 --- a/tv/tuner/1.1/default/Filter.cpp +++ b/tv/tuner/1.1/default/Filter.cpp @@ -220,7 +220,7 @@ void Filter::filterThreadLoop() { // For the first time of filter output, implementation needs to send the filter // Event Callback without waiting for the DATA_CONSUMED to init the process. while (mFilterThreadRunning) { - if (mFilterEvent.events.size() == 0 && mFilterEvent_1_1.events.size() == 0) { + if (mFilterEvent.events.size() == 0 && mFilterEventExt.events.size() == 0) { if (DEBUG_FILTER) { ALOGD("[Filter] wait for filter data output."); } @@ -228,18 +228,17 @@ void Filter::filterThreadLoop() { continue; } // After successfully write, send a callback and wait for the read to be done - if (mFilterEvent_1_1.events.size() > 0) { - if (mCallback_1_1 == nullptr) { - ALOGE("[Filter] IFilterCallback_1_1 has not been configured yet. Can't send event"); - mFilterThreadRunning = false; - break; - } - mCallback_1_1->onFilterEvent_1_1(mFilterEvent_1_1); - mFilterEvent_1_1.events.resize(0); - } else { + if (mCallback_1_1 != nullptr) { + mCallback_1_1->onFilterEvent_1_1(mFilterEvent, mFilterEventExt); + mFilterEventExt.events.resize(0); + } else if (mCallback != nullptr) { mCallback->onFilterEvent(mFilterEvent); - mFilterEvent.events.resize(0); + } else { + ALOGD("[Filter] filter callback is not configured yet."); + mFilterThreadRunning = false; + return; } + mFilterEvent.events.resize(0); freeAvHandle(); mFilterStatus = DemuxFilterStatus::DATA_READY; @@ -279,8 +278,8 @@ void Filter::filterThreadLoop() { mCallback->onFilterEvent(mFilterEvent); mFilterEvent.events.resize(0); } else if (mCallback_1_1 != nullptr) { - mCallback_1_1->onFilterEvent_1_1(mFilterEvent_1_1); - mFilterEvent_1_1.events.resize(0); + mCallback_1_1->onFilterEvent_1_1(mFilterEvent, mFilterEventExt); + mFilterEventExt.events.resize(0); } break; } @@ -612,22 +611,18 @@ Result Filter::startRecordFilterHandler() { recordEvent = { .byteNumber = mRecordFilterOutput.size(), }; - V1_1::DemuxFilterTsRecordEvent recordEvent_1_1; - recordEvent_1_1 = { - .tsRecordEvent_1_0 = recordEvent, + V1_1::DemuxFilterRecordEventExt recordEventExt; + recordEventExt = { .pts = (mPts == 0) ? time(NULL) * 900000 : mPts, }; int size; - if (mCallback_1_1 != nullptr) { - size = mFilterEvent_1_1.events.size(); - mFilterEvent_1_1.events.resize(size + 1); - mFilterEvent_1_1.events[size].tsRecord(recordEvent_1_1); - } else if (mCallback != nullptr) { - size = mFilterEvent.events.size(); - mFilterEvent.events.resize(size + 1); - mFilterEvent.events[size].tsRecord(recordEvent); - } + size = mFilterEventExt.events.size(); + mFilterEventExt.events.resize(size + 1); + mFilterEventExt.events[size].tsRecord(recordEventExt); + size = mFilterEvent.events.size(); + mFilterEvent.events.resize(size + 1); + mFilterEvent.events[size].tsRecord(recordEvent); mRecordFilterOutput.clear(); return Result::SUCCESS; diff --git a/tv/tuner/1.1/default/Filter.h b/tv/tuner/1.1/default/Filter.h index 8e6fe388cc..fa52f9635a 100644 --- a/tv/tuner/1.1/default/Filter.h +++ b/tv/tuner/1.1/default/Filter.h @@ -128,7 +128,7 @@ class Filter : public V1_1::IFilter { bool mIsUsingFMQ = false; EventFlag* mFilterEventFlag; DemuxFilterEvent mFilterEvent; - V1_1::DemuxFilterEvent mFilterEvent_1_1; + V1_1::DemuxFilterEventExt mFilterEventExt; // Thread handlers pthread_t mFilterThread; diff --git a/tv/tuner/1.1/types.hal b/tv/tuner/1.1/types.hal index 5c02b85b3f..bbfc39a010 100644 --- a/tv/tuner/1.1/types.hal +++ b/tv/tuner/1.1/types.hal @@ -17,15 +17,10 @@ package android.hardware.tv.tuner@1.1; import @1.0::Constant; -import @1.0::DemuxFilterDownloadEvent; -import @1.0::DemuxFilterIpPayloadEvent; -import @1.0::DemuxFilterMediaEvent; import @1.0::DemuxFilterMmtpRecordEvent; -import @1.0::DemuxFilterPesEvent; -import @1.0::DemuxFilterSectionEvent; -import @1.0::DemuxFilterTemiEvent; import @1.0::DemuxFilterTsRecordEvent; import android.hidl.safe_union@1.0; +import android.hidl.safe_union@1.0::Monostate; @export enum Constant : @1.0::Constant { @@ -52,64 +47,36 @@ enum Constant64Bit : uint64_t { }; /** - * Filter Event for TS Record data. + * Extended Demux Filter Record Event. */ -struct DemuxFilterTsRecordEvent { - /** - * V1_0 Filter Event for TS Record data. - */ - @1.0::DemuxFilterTsRecordEvent tsRecordEvent_1_0; - +struct DemuxFilterRecordEventExt { /** * The Presentation Time Stamp(PTS) for the audio or video frame. It is based on 90KHz * and has the same format as the PTS in ISO/IEC 13818-1. It is used only for the SC and * the SC_HEVC. */ uint64_t pts; -}; - -/** - * Filter Event for MMTP Record data. - */ -struct DemuxFilterMmtpRecordEvent { - /** - * V1_0 Filter Event for MMTP Record data. - */ - @1.0::DemuxFilterMmtpRecordEvent mmtpRecordEvent_1_0; /** * MPU sequence number of the filtered data. This is only used for MMTP. */ uint32_t mpuSequenceNumber; - - /** - * The Presentation Time Stamp(PTS) for the audio or video frame. It is based on 90KHz - * and has the same format as the PTS in ISO/IEC 13818-1. It is used only for the SC and - * the SC_HEVC. - */ - uint64_t pts; }; /** - * Filter Event. + * Extended Demux Filter Event. */ -struct DemuxFilterEvent { +struct DemuxFilterEventExt { safe_union Event { - DemuxFilterSectionEvent section; - - DemuxFilterMediaEvent media; - - DemuxFilterPesEvent pes; - - @1.1::DemuxFilterTsRecordEvent tsRecord; - - @1.1::DemuxFilterMmtpRecordEvent mmtpRecord; - - DemuxFilterDownloadEvent download; + /** + * No extended record filter Event. This is used by the tsRecord or mmtpRecord filter event + * that does not contain the DemuxFilterRecordEventExt information. + */ + Monostate noinit; - DemuxFilterIpPayloadEvent ipPayload; + DemuxFilterRecordEventExt tsRecord; - DemuxFilterTemiEvent temi; + DemuxFilterRecordEventExt mmtpRecord; }; /** diff --git a/tv/tuner/1.1/vts/functional/FilterTests.cpp b/tv/tuner/1.1/vts/functional/FilterTests.cpp index 9cbec869c4..24e1fa0957 100644 --- a/tv/tuner/1.1/vts/functional/FilterTests.cpp +++ b/tv/tuner/1.1/vts/functional/FilterTests.cpp @@ -20,11 +20,12 @@ bool FilterCallback::readFilterEventData() { bool result = false; ALOGW("[vts] reading from filter FMQ or buffer %d", mFilterId); // todo separate filter handlers - for (int i = 0; i < mFilterEvent.events.size(); i++) { - switch (mFilterEventType) { - case FilterEventType::RECORD: - ALOGW("[vts] Record filter event, pts=%" PRIu64 ".", - mFilterEvent.events[0].tsRecord().pts); + for (int i = 0; i < mFilterEventExt.events.size(); i++) { + auto eventExt = mFilterEventExt.events[i]; + switch (eventExt.getDiscriminator()) { + case DemuxFilterEventExt::Event::hidl_discriminator::tsRecord: + ALOGW("[vts] Extended TS record filter event, pts=%" PRIu64 ".", + eventExt.tsRecord().pts); break; default: break; diff --git a/tv/tuner/1.1/vts/functional/FilterTests.h b/tv/tuner/1.1/vts/functional/FilterTests.h index 8156f140cf..721e4190c4 100644 --- a/tv/tuner/1.1/vts/functional/FilterTests.h +++ b/tv/tuner/1.1/vts/functional/FilterTests.h @@ -44,6 +44,7 @@ using android::hardware::MessageQueue; using android::hardware::MQDescriptorSync; using android::hardware::Return; using android::hardware::Void; +using android::hardware::tv::tuner::V1_0::DemuxFilterEvent; using android::hardware::tv::tuner::V1_0::DemuxFilterMainType; using android::hardware::tv::tuner::V1_0::DemuxFilterSettings; using android::hardware::tv::tuner::V1_0::DemuxFilterStatus; @@ -52,7 +53,7 @@ using android::hardware::tv::tuner::V1_0::DemuxTsFilterType; using android::hardware::tv::tuner::V1_0::IDemux; using android::hardware::tv::tuner::V1_0::IFilter; using android::hardware::tv::tuner::V1_0::Result; -using android::hardware::tv::tuner::V1_1::DemuxFilterEvent; +using android::hardware::tv::tuner::V1_1::DemuxFilterEventExt; using android::hardware::tv::tuner::V1_1::IFilterCallback; using android::hardware::tv::tuner::V1_1::ITuner; @@ -78,11 +79,13 @@ using MQDesc = MQDescriptorSync; class FilterCallback : public IFilterCallback { public: - virtual Return onFilterEvent_1_1(const DemuxFilterEvent& filterEvent) override { + virtual Return onFilterEvent_1_1(const DemuxFilterEvent& filterEvent, + const DemuxFilterEventExt& filterEventExt) override { android::Mutex::Autolock autoLock(mMsgLock); // Temprarily we treat the first coming back filter data on the matching pid a success // once all of the MQ are cleared, means we got all the expected output mFilterEvent = filterEvent; + mFilterEventExt = filterEventExt; readFilterEventData(); mPidFilterOutputCount++; mMsgCondition.signal(); @@ -109,6 +112,7 @@ class FilterCallback : public IFilterCallback { sp mFilter; FilterEventType mFilterEventType; DemuxFilterEvent mFilterEvent; + DemuxFilterEventExt mFilterEventExt; android::Mutex mMsgLock; android::Mutex mFilterOutputLock; -- GitLab From 4b8f50c17a6761787ba8f1e53a708adfa64a4ad3 Mon Sep 17 00:00:00 2001 From: Tomasz Wasilczyk Date: Thu, 6 Aug 2020 10:50:35 -0700 Subject: [PATCH 100/790] Implement message kinds for flag printing Bug: 162032964 Test: adb shell canhalctrl up test virtual vcan1 Change-Id: Ib71c928862b0d098cc698c09f2efdd72bf03d8b0 --- automotive/can/1.0/default/libnl++/Socket.cpp | 7 ++- .../default/libnl++/include/libnl++/printer.h | 2 +- .../can/1.0/default/libnl++/printer.cpp | 48 +++++++++++++------ .../libnl++/protocols/MessageDefinition.cpp | 22 ++++++--- .../libnl++/protocols/MessageDefinition.h | 45 ++++++++++++----- .../libnl++/protocols/NetlinkProtocol.cpp | 4 +- .../libnl++/protocols/common/Empty.cpp | 6 +-- .../libnl++/protocols/common/Error.cpp | 10 +++- .../protocols/generic/GenericMessageBase.cpp | 3 +- .../default/libnl++/protocols/route/Link.cpp | 6 +-- 10 files changed, 104 insertions(+), 49 deletions(-) diff --git a/automotive/can/1.0/default/libnl++/Socket.cpp b/automotive/can/1.0/default/libnl++/Socket.cpp index 1a34df8d85..9e96ea9739 100644 --- a/automotive/can/1.0/default/libnl++/Socket.cpp +++ b/automotive/can/1.0/default/libnl++/Socket.cpp @@ -49,8 +49,8 @@ Socket::Socket(int protocol, unsigned pid, uint32_t groups) : mProtocol(protocol bool Socket::send(const Buffer& msg, const sockaddr_nl& sa) { if constexpr (kSuperVerbose) { - LOG(VERBOSE) << (mFailed ? "(not) " : "") << "sending Netlink message (" // - << msg->nlmsg_pid << " -> " << sa.nl_pid << "): " << toString(msg, mProtocol); + LOG(VERBOSE) << (mFailed ? "(not) " : "") << "sending to " << sa.nl_pid << ": " + << toString(msg, mProtocol); } if (mFailed) return false; @@ -97,8 +97,7 @@ std::pair>, sockaddr_nl> Socket::receiveFrom(size Buffer msg(reinterpret_cast(mReceiveBuffer.data()), bytesReceived); if constexpr (kSuperVerbose) { - LOG(VERBOSE) << "received (" << sa.nl_pid << " -> " << msg->nlmsg_pid << "):" // - << toString(msg, mProtocol); + LOG(VERBOSE) << "received from " << sa.nl_pid << ": " << toString(msg, mProtocol); } return {msg, sa}; } diff --git a/automotive/can/1.0/default/libnl++/include/libnl++/printer.h b/automotive/can/1.0/default/libnl++/include/libnl++/printer.h index 53a06d805b..3570918e2d 100644 --- a/automotive/can/1.0/default/libnl++/include/libnl++/printer.h +++ b/automotive/can/1.0/default/libnl++/include/libnl++/printer.h @@ -32,6 +32,6 @@ namespace android::nl { * \param printPayload True will stringify message data, false will only stringify the header(s). * \return Stringified message. */ -std::string toString(const Buffer hdr, int protocol, bool printPayload = false); +std::string toString(const Buffer hdr, int protocol, bool printPayload = true); } // namespace android::nl diff --git a/automotive/can/1.0/default/libnl++/printer.cpp b/automotive/can/1.0/default/libnl++/printer.cpp index 9735db1faf..320641c842 100644 --- a/automotive/can/1.0/default/libnl++/printer.cpp +++ b/automotive/can/1.0/default/libnl++/printer.cpp @@ -28,10 +28,10 @@ namespace android::nl { -static void flagsToStream(std::stringstream& ss, __u16 nlmsg_flags) { +static void flagsToStream(std::stringstream& ss, __u16 nlmsg_flags, protocols::MessageGenre genre) { bool first = true; auto printFlag = [&ss, &first, &nlmsg_flags](__u16 flag, const std::string& name) { - if (!(nlmsg_flags & flag)) return; + if ((nlmsg_flags & flag) != flag) return; nlmsg_flags &= ~flag; if (first) { @@ -42,6 +42,7 @@ static void flagsToStream(std::stringstream& ss, __u16 nlmsg_flags) { ss << name; }; + printFlag(NLM_F_REQUEST, "REQUEST"); printFlag(NLM_F_MULTI, "MULTI"); printFlag(NLM_F_ACK, "ACK"); @@ -49,11 +50,29 @@ static void flagsToStream(std::stringstream& ss, __u16 nlmsg_flags) { printFlag(NLM_F_DUMP_INTR, "DUMP_INTR"); printFlag(NLM_F_DUMP_FILTERED, "DUMP_FILTERED"); - // TODO(twasilczyk): print flags depending on request type - printFlag(NLM_F_ROOT, "ROOT-REPLACE"); - printFlag(NLM_F_MATCH, "MATCH-EXCL"); - printFlag(NLM_F_ATOMIC, "ATOMIC-CREATE"); - printFlag(NLM_F_APPEND, "APPEND"); + switch (genre) { + case protocols::MessageGenre::UNKNOWN: + break; + case protocols::MessageGenre::GET: + printFlag(NLM_F_DUMP, "DUMP"); // ROOT | MATCH + printFlag(NLM_F_ROOT, "ROOT"); + printFlag(NLM_F_MATCH, "MATCH"); + printFlag(NLM_F_ATOMIC, "ATOMIC"); + break; + case protocols::MessageGenre::NEW: + printFlag(NLM_F_REPLACE, "REPLACE"); + printFlag(NLM_F_EXCL, "EXCL"); + printFlag(NLM_F_CREATE, "CREATE"); + printFlag(NLM_F_APPEND, "APPEND"); + break; + case protocols::MessageGenre::DELETE: + printFlag(NLM_F_NONREC, "NONREC"); + break; + case protocols::MessageGenre::ACK: + printFlag(NLM_F_CAPPED, "CAPPED"); + printFlag(NLM_F_ACK_TLVS, "ACK_TLVS"); + break; + } if (nlmsg_flags != 0) { if (!first) ss << '|'; @@ -128,27 +147,26 @@ std::string toString(const Buffer hdr, int protocol, bool printPayload } protocols::NetlinkProtocol& protocolDescr = *protocolMaybe; - auto msgDescMaybe = protocolDescr.getMessageDescriptor(hdr->nlmsg_type); - const auto msgTypeName = msgDescMaybe.has_value() - ? msgDescMaybe->get().getMessageName(hdr->nlmsg_type) - : std::to_string(hdr->nlmsg_type); + const auto msgDescMaybe = protocolDescr.getMessageDescriptor(hdr->nlmsg_type); + const auto msgDetails = + protocols::MessageDescriptor::getMessageDetails(msgDescMaybe, hdr->nlmsg_type); ss << "nlmsg{" << protocolDescr.getName() << " "; ss << "hdr={"; - ss << "type=" << msgTypeName; + ss << "type=" << msgDetails.name; if (hdr->nlmsg_flags != 0) { ss << ", flags="; - flagsToStream(ss, hdr->nlmsg_flags); + flagsToStream(ss, hdr->nlmsg_flags, msgDetails.genre); } if (hdr->nlmsg_seq != 0) ss << ", seq=" << hdr->nlmsg_seq; if (hdr->nlmsg_pid != 0) ss << ", pid=" << hdr->nlmsg_pid; ss << ", len=" << hdr->nlmsg_len; - ss << ", crc=" << std::hex << std::setw(4) << crc16(hdr.data()) << std::dec; - ss << "} "; + ss << '}'; if (!printPayload) return ss.str(); + ss << ' '; if (!msgDescMaybe.has_value()) { toStream(ss, hdr.data()); diff --git a/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.cpp b/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.cpp index dc5664376c..c93d86561e 100644 --- a/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.cpp +++ b/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.cpp @@ -32,11 +32,12 @@ const AttributeDefinition AttributeMap::operator[](nlattrtype_t nla_type) const return find(nla_type)->second; } -MessageDescriptor::MessageDescriptor(const std::string& name, const MessageTypeMap&& messageTypes, +MessageDescriptor::MessageDescriptor(const std::string& name, + const MessageDetailsMap&& messageDetails, const AttributeMap&& attrTypes, size_t contentsSize) : mName(name), mContentsSize(contentsSize), - mMessageTypes(messageTypes), + mMessageDetails(messageDetails), mAttributeMap(attrTypes) {} MessageDescriptor::~MessageDescriptor() {} @@ -45,18 +46,25 @@ size_t MessageDescriptor::getContentsSize() const { return mContentsSize; } -const MessageDescriptor::MessageTypeMap& MessageDescriptor::getMessageTypeMap() const { - return mMessageTypes; +const MessageDescriptor::MessageDetailsMap& MessageDescriptor::getMessageDetailsMap() const { + return mMessageDetails; } const AttributeMap& MessageDescriptor::getAttributeMap() const { return mAttributeMap; } -const std::string MessageDescriptor::getMessageName(nlmsgtype_t msgtype) const { - const auto it = mMessageTypes.find(msgtype); - if (it == mMessageTypes.end()) return "?"; +MessageDescriptor::MessageDetails MessageDescriptor::getMessageDetails(nlmsgtype_t msgtype) const { + const auto it = mMessageDetails.find(msgtype); + if (it == mMessageDetails.end()) return {std::to_string(msgtype), MessageGenre::UNKNOWN}; return it->second; } +MessageDescriptor::MessageDetails MessageDescriptor::getMessageDetails( + const std::optional>& msgDescMaybe, + nlmsgtype_t msgtype) { + if (msgDescMaybe.has_value()) return msgDescMaybe->get().getMessageDetails(msgtype); + return {std::to_string(msgtype), protocols::MessageGenre::UNKNOWN}; +} + } // namespace android::nl::protocols diff --git a/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.h b/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.h index ef73d09236..bd0e60f9cf 100644 --- a/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.h +++ b/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.h @@ -67,31 +67,54 @@ struct AttributeDefinition { std::variant ops = AttributeMap{}; }; +/** + * General message type's kind. + * + * For example, RTM_NEWLINK is a NEW kind. For details, please see "Flags values" + * section in linux/netlink.h. + */ +enum class MessageGenre { + UNKNOWN, + GET, + NEW, + DELETE, + ACK, +}; + /** * Message family descriptor. * * Describes the structure of all message types with the same header and attributes. */ class MessageDescriptor { - protected: - typedef std::map MessageTypeMap; - - MessageDescriptor(const std::string& name, const MessageTypeMap&& messageTypes, - const AttributeMap&& attrTypes, size_t contentsSize); + public: + struct MessageDetails { + std::string name; + MessageGenre genre; + }; + typedef std::map MessageDetailsMap; public: virtual ~MessageDescriptor(); size_t getContentsSize() const; - const MessageTypeMap& getMessageTypeMap() const; + const MessageDetailsMap& getMessageDetailsMap() const; const AttributeMap& getAttributeMap() const; - const std::string getMessageName(nlmsgtype_t msgtype) const; + MessageDetails getMessageDetails(nlmsgtype_t msgtype) const; virtual void dataToStream(std::stringstream& ss, const Buffer hdr) const = 0; + static MessageDetails getMessageDetails( + const std::optional>& msgDescMaybe, + nlmsgtype_t msgtype); + + protected: + MessageDescriptor(const std::string& name, const MessageDetailsMap&& messageDetails, + const AttributeMap&& attrTypes, size_t contentsSize); + private: const std::string mName; const size_t mContentsSize; - const MessageTypeMap mMessageTypes; + const MessageDetailsMap mMessageDetails; const AttributeMap mAttributeMap; }; @@ -103,11 +126,11 @@ class MessageDescriptor { template class MessageDefinition : public MessageDescriptor { public: - MessageDefinition( + MessageDefinition( // const std::string& name, - const std::initializer_list messageTypes, + const std::initializer_list msgDet, const std::initializer_list attrTypes = {}) - : MessageDescriptor(name, messageTypes, attrTypes, sizeof(T)) {} + : MessageDescriptor(name, msgDet, attrTypes, sizeof(T)) {} void dataToStream(std::stringstream& ss, const Buffer hdr) const override { const auto& [ok, msg] = hdr.data().getFirst(); diff --git a/automotive/can/1.0/default/libnl++/protocols/NetlinkProtocol.cpp b/automotive/can/1.0/default/libnl++/protocols/NetlinkProtocol.cpp index 4b795d97c4..159b6d643d 100644 --- a/automotive/can/1.0/default/libnl++/protocols/NetlinkProtocol.cpp +++ b/automotive/can/1.0/default/libnl++/protocols/NetlinkProtocol.cpp @@ -42,7 +42,7 @@ NetlinkProtocol::MessageDescriptorMap NetlinkProtocol::toMap( const NetlinkProtocol::MessageDescriptorList& descrs, int protocol) { MessageDescriptorMap map; for (const auto& descr : descrs) { - for (const auto& [mtype, mname] : descr->getMessageTypeMap()) { + for (const auto& [mtype, mdet] : descr->getMessageDetailsMap()) { map.emplace(mtype, descr); } } @@ -53,7 +53,7 @@ NetlinkProtocol::MessageDescriptorMap NetlinkProtocol::toMap( }; for (const auto& descr : baseDescriptors) { - for (const auto& [mtype, mname] : descr->getMessageTypeMap()) { + for (const auto& [mtype, mdet] : descr->getMessageDetailsMap()) { map.emplace(mtype, descr); } } diff --git a/automotive/can/1.0/default/libnl++/protocols/common/Empty.cpp b/automotive/can/1.0/default/libnl++/protocols/common/Empty.cpp index dbf10d4273..8a672d3864 100644 --- a/automotive/can/1.0/default/libnl++/protocols/common/Empty.cpp +++ b/automotive/can/1.0/default/libnl++/protocols/common/Empty.cpp @@ -20,9 +20,9 @@ namespace android::nl::protocols::base { // clang-format off Empty::Empty() : MessageDefinition("nlmsg", { - {NLMSG_NOOP, "NOOP"}, - {NLMSG_DONE, "DONE"}, - {NLMSG_OVERRUN, "OVERRUN"}, + {NLMSG_NOOP, {"NOOP", MessageGenre::UNKNOWN}}, + {NLMSG_DONE, {"DONE", MessageGenre::UNKNOWN}}, + {NLMSG_OVERRUN, {"OVERRUN", MessageGenre::UNKNOWN}}, }) {} // clang-format on diff --git a/automotive/can/1.0/default/libnl++/protocols/common/Error.cpp b/automotive/can/1.0/default/libnl++/protocols/common/Error.cpp index 1d6bd1c6ba..44708a3a9c 100644 --- a/automotive/can/1.0/default/libnl++/protocols/common/Error.cpp +++ b/automotive/can/1.0/default/libnl++/protocols/common/Error.cpp @@ -22,15 +22,21 @@ namespace android::nl::protocols::base { +using DataType = AttributeDefinition::DataType; + // clang-format off Error::Error(int protocol) : MessageDefinition("nlmsg", { - {NLMSG_ERROR, "ERROR"}, + {NLMSG_ERROR, {"ERROR", MessageGenre::ACK}}, +}, { + {NLMSGERR_ATTR_MSG, {"MSG", DataType::String}}, + {NLMSGERR_ATTR_OFFS, {"OFFS", DataType::Uint}}, + {NLMSGERR_ATTR_COOKIE, {"COOKIE", DataType::Raw}}, }), mProtocol(protocol) {} // clang-format on void Error::toStream(std::stringstream& ss, const nlmsgerr& data) const { ss << "nlmsgerr{error=" << data.error - << ", msg=" << toString({&data.msg, sizeof(data.msg)}, mProtocol) << "}"; + << ", msg=" << toString({&data.msg, sizeof(data.msg)}, mProtocol, false) << "}"; } } // namespace android::nl::protocols::base diff --git a/automotive/can/1.0/default/libnl++/protocols/generic/GenericMessageBase.cpp b/automotive/can/1.0/default/libnl++/protocols/generic/GenericMessageBase.cpp index 877bb2158a..5b6bd97789 100644 --- a/automotive/can/1.0/default/libnl++/protocols/generic/GenericMessageBase.cpp +++ b/automotive/can/1.0/default/libnl++/protocols/generic/GenericMessageBase.cpp @@ -22,7 +22,8 @@ GenericMessageBase::GenericMessageBase( nlmsgtype_t msgtype, std::string msgname, const std::initializer_list commandNames, const std::initializer_list attrTypes) - : MessageDefinition(msgname, {{msgtype, msgname}}, attrTypes), + : MessageDefinition(msgname, {{msgtype, {msgname, MessageGenre::UNKNOWN}}}, + attrTypes), mCommandNames(commandNames) {} void GenericMessageBase::toStream(std::stringstream& ss, const genlmsghdr& data) const { diff --git a/automotive/can/1.0/default/libnl++/protocols/route/Link.cpp b/automotive/can/1.0/default/libnl++/protocols/route/Link.cpp index bc44d8eda3..7db487ae39 100644 --- a/automotive/can/1.0/default/libnl++/protocols/route/Link.cpp +++ b/automotive/can/1.0/default/libnl++/protocols/route/Link.cpp @@ -26,9 +26,9 @@ using DataType = AttributeDefinition::DataType; // clang-format off Link::Link() : MessageDefinition("link", { - {RTM_NEWLINK, "NEWLINK"}, - {RTM_DELLINK, "DELLINK"}, - {RTM_GETLINK, "GETLINK"}, + {RTM_NEWLINK, {"NEWLINK", MessageGenre::NEW}}, + {RTM_DELLINK, {"DELLINK", MessageGenre::DELETE}}, + {RTM_GETLINK, {"GETLINK", MessageGenre::GET}}, }, { {IFLA_ADDRESS, {"ADDRESS"}}, {IFLA_BROADCAST, {"BROADCAST"}}, -- GitLab From cf03efbb84d3b00d58d21f1f770c6798dd8b674f Mon Sep 17 00:00:00 2001 From: Tomasz Wasilczyk Date: Thu, 6 Aug 2020 12:33:54 -0700 Subject: [PATCH 101/790] Trim trailing NIL character when fetching string attribute Also, fix one instance of non-inclusive language that slipped through. Bug: 162032964 Bug: 162745675 Test: custom implementation to watch for NEWLINK/DELLINK messages Change-Id: I8fe05731fd9d598ec3aec1452aa04ac764e9c7e7 --- automotive/can/1.0/default/libnl++/Attributes.cpp | 6 +++++- automotive/can/1.0/default/libnl++/common.cpp | 4 +--- automotive/can/1.0/default/libnl++/common.h | 9 ++++++--- automotive/can/1.0/default/libnl++/printer.cpp | 2 +- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/automotive/can/1.0/default/libnl++/Attributes.cpp b/automotive/can/1.0/default/libnl++/Attributes.cpp index c10164731a..620f57b2f6 100644 --- a/automotive/can/1.0/default/libnl++/Attributes.cpp +++ b/automotive/can/1.0/default/libnl++/Attributes.cpp @@ -49,7 +49,11 @@ Attributes Attributes::parse(Buffer buf) { template <> std::string Attributes::parse(Buffer buf) { const auto rawString = buf.data().getRaw(); - return std::string(rawString.ptr(), rawString.len()); + std::string str(rawString.ptr(), rawString.len()); + + str.erase(std::find(str.begin(), str.end(), '\0'), str.end()); + + return str; } template diff --git a/automotive/can/1.0/default/libnl++/common.cpp b/automotive/can/1.0/default/libnl++/common.cpp index 74eee247b9..23c2d94a6d 100644 --- a/automotive/can/1.0/default/libnl++/common.cpp +++ b/automotive/can/1.0/default/libnl++/common.cpp @@ -32,9 +32,7 @@ unsigned int nametoindex(const std::string& ifname) { return 0; } -std::string sanitize(std::string str) { - str.erase(std::find(str.begin(), str.end(), '\0'), str.end()); - +std::string printableOnly(std::string str) { const auto isInvalid = [](char c) { return !isprint(c); }; std::replace_if(str.begin(), str.end(), isInvalid, '?'); diff --git a/automotive/can/1.0/default/libnl++/common.h b/automotive/can/1.0/default/libnl++/common.h index 1d9dbab28e..38263c5173 100644 --- a/automotive/can/1.0/default/libnl++/common.h +++ b/automotive/can/1.0/default/libnl++/common.h @@ -37,11 +37,14 @@ namespace android::nl { unsigned int nametoindex(const std::string& ifname); /** - * Sanitize a string of unknown contents. + * Filter a string against non-printable characters. * - * Trims the string to the first '\0' character and replaces all non-printable characters with '?'. + * Replaces all non-printable characters with '?'. + * + * \param str String to filter. + * \return Filtered string. */ -std::string sanitize(std::string str); +std::string printableOnly(std::string str); /** * Calculates a (optionally running) CRC16 checksum. diff --git a/automotive/can/1.0/default/libnl++/printer.cpp b/automotive/can/1.0/default/libnl++/printer.cpp index 320641c842..e6cada2801 100644 --- a/automotive/can/1.0/default/libnl++/printer.cpp +++ b/automotive/can/1.0/default/libnl++/printer.cpp @@ -119,7 +119,7 @@ static void toStream(std::stringstream& ss, const Buffer attr, } case DataType::String: { const auto str = attr.data().getRaw(); - ss << '"' << sanitize({str.ptr(), str.len()}) << '"'; + ss << '"' << printableOnly({str.ptr(), str.len()}) << '"'; break; } case DataType::Uint: -- GitLab From cb877f950bc0e18929e5cc52b5da7a1d72316e13 Mon Sep 17 00:00:00 2001 From: Changyeon Jo Date: Thu, 6 Aug 2020 13:14:43 -0700 Subject: [PATCH 102/790] Use more inclusive terms Updating language to comply with the inclusive language guidance Bug: 162326641 Test: m -j Change-Id: I627c22c3a0f89879255f1c65cfa314aebc70417e --- automotive/evs/1.0/default/EvsCamera.cpp | 2 +- .../functional/VtsHalEvsV1_0TargetTest.cpp | 4 +- automotive/evs/1.1/default/ConfigManager.h | 2 +- automotive/evs/1.1/default/EvsEnumerator.cpp | 2 +- .../evs/1.1/default/EvsUltrasonicsArray.cpp | 28 +-- .../evs/1.1/default/EvsUltrasonicsArray.h | 2 +- .../functional/VtsHalEvsV1_1TargetTest.cpp | 234 +++++++++--------- 7 files changed, 137 insertions(+), 137 deletions(-) diff --git a/automotive/evs/1.0/default/EvsCamera.cpp b/automotive/evs/1.0/default/EvsCamera.cpp index e0782ec779..0daea5a295 100644 --- a/automotive/evs/1.0/default/EvsCamera.cpp +++ b/automotive/evs/1.0/default/EvsCamera.cpp @@ -49,7 +49,7 @@ EvsCamera::EvsCamera(const char *id) : mDescription.cameraId = id; - // Set up dummy data for testing + // Set up mock data for testing if (mDescription.cameraId == kCameraName_Backup) { mWidth = 640; // full NTSC/VGA mHeight = 480; // full NTSC/VGA diff --git a/automotive/evs/1.0/vts/functional/VtsHalEvsV1_0TargetTest.cpp b/automotive/evs/1.0/vts/functional/VtsHalEvsV1_0TargetTest.cpp index 7fe7a3399b..ad607d8087 100644 --- a/automotive/evs/1.0/vts/functional/VtsHalEvsV1_0TargetTest.cpp +++ b/automotive/evs/1.0/vts/functional/VtsHalEvsV1_0TargetTest.cpp @@ -369,7 +369,7 @@ TEST_P(EvsHidlTest, CameraStreamPerformance) { TEST_P(EvsHidlTest, CameraStreamBuffering) { ALOGI("Starting CameraStreamBuffering test"); - // Arbitrary constant (should be > 1 and less than crazy) + // Arbitrary constant (should be > 1 and not too big) static const unsigned int kBuffersToHold = 6; // Get the camera list @@ -381,7 +381,7 @@ TEST_P(EvsHidlTest, CameraStreamBuffering) { sp pCam = pEnumerator->openCamera(cam.cameraId); ASSERT_NE(pCam, nullptr); - // Ask for a crazy number of buffers in flight to ensure it errors correctly + // Ask for a very large number of buffers in flight to ensure it errors correctly Return badResult = pCam->setMaxFramesInFlight(0xFFFFFFFF); EXPECT_EQ(EvsResult::BUFFER_NOT_AVAILABLE, badResult); diff --git a/automotive/evs/1.1/default/ConfigManager.h b/automotive/evs/1.1/default/ConfigManager.h index 870af1caa9..b0b2670fb6 100644 --- a/automotive/evs/1.1/default/ConfigManager.h +++ b/automotive/evs/1.1/default/ConfigManager.h @@ -76,7 +76,7 @@ public: } /* - * List of supported controls that the master client can program. + * List of supported controls that the primary client can program. * Paraemters are stored with its valid range */ unordered_map windowService) { // Add ultrasonics array desc. sUltrasonicsArrayRecordList.emplace_back( - EvsUltrasonicsArray::GetDummyArrayDesc("front_array")); + EvsUltrasonicsArray::GetMockArrayDesc("front_array")); } diff --git a/automotive/evs/1.1/default/EvsUltrasonicsArray.cpp b/automotive/evs/1.1/default/EvsUltrasonicsArray.cpp index bc69aa4156..ebd47c618b 100644 --- a/automotive/evs/1.1/default/EvsUltrasonicsArray.cpp +++ b/automotive/evs/1.1/default/EvsUltrasonicsArray.cpp @@ -45,7 +45,7 @@ const int kTargetFrameRate = 10; namespace { -void fillDummyArrayDesc(UltrasonicsArrayDesc& arrayDesc) { +void fillMockArrayDesc(UltrasonicsArrayDesc& arrayDesc) { arrayDesc.maxReadingsPerSensorCount = kMaxReadingsPerSensor; arrayDesc.maxReceiversCount = kMaxReceiversCount; @@ -99,8 +99,8 @@ void SerializeWaveformData(const std::vector& waveformDataList, ui } } -// Fills dataFrameDesc with dummy data. -bool fillDummyDataFrame(UltrasonicsDataFrameDesc& dataFrameDesc, sp pIMemory) { +// Fills dataFrameDesc with mock data. +bool fillMockDataFrame(UltrasonicsDataFrameDesc& dataFrameDesc, sp pIMemory) { dataFrameDesc.timestampNs = elapsedRealtimeNano(); const std::vector transmittersIdList = {0}; @@ -137,9 +137,9 @@ EvsUltrasonicsArray::EvsUltrasonicsArray(const char* deviceName) : mFramesAllowed(0), mFramesInUse(0), mStreamState(STOPPED) { LOG(DEBUG) << "EvsUltrasonicsArray instantiated"; - // Set up dummy data for description. + // Set up mock data for description. mArrayDesc.ultrasonicsArrayId = deviceName; - fillDummyArrayDesc(mArrayDesc); + fillMockArrayDesc(mArrayDesc); // Assign allocator. mShmemAllocator = IAllocator::getService("ashmem"); @@ -182,10 +182,10 @@ void EvsUltrasonicsArray::forceShutdown() { mStreamState = DEAD; } -UltrasonicsArrayDesc EvsUltrasonicsArray::GetDummyArrayDesc(const char* deviceName) { +UltrasonicsArrayDesc EvsUltrasonicsArray::GetMockArrayDesc(const char* deviceName) { UltrasonicsArrayDesc ultrasonicsArrayDesc; ultrasonicsArrayDesc.ultrasonicsArrayId = deviceName; - fillDummyArrayDesc(ultrasonicsArrayDesc); + fillMockArrayDesc(ultrasonicsArrayDesc); return ultrasonicsArrayDesc; } @@ -497,17 +497,17 @@ void EvsUltrasonicsArray::generateDataFrames() { if (timeForFrame) { // Assemble the buffer description we'll transmit below - UltrasonicsDataFrameDesc dummyDataFrameDesc; - dummyDataFrameDesc.dataFrameId = idx; - dummyDataFrameDesc.waveformsData = mDataFrames[idx].sharedMemory.hidlMemory; + UltrasonicsDataFrameDesc mockDataFrameDesc; + mockDataFrameDesc.dataFrameId = idx; + mockDataFrameDesc.waveformsData = mDataFrames[idx].sharedMemory.hidlMemory; - // Fill dummy waveform data. - fillDummyDataFrame(dummyDataFrameDesc, mDataFrames[idx].sharedMemory.pIMemory); + // Fill mock waveform data. + fillMockDataFrame(mockDataFrameDesc, mDataFrames[idx].sharedMemory.pIMemory); // Issue the (asynchronous) callback to the client -- can't be holding the lock - auto result = mStream->deliverDataFrame(dummyDataFrameDesc); + auto result = mStream->deliverDataFrame(mockDataFrameDesc); if (result.isOk()) { - LOG(DEBUG) << "Delivered data frame id: " << dummyDataFrameDesc.dataFrameId; + LOG(DEBUG) << "Delivered data frame id: " << mockDataFrameDesc.dataFrameId; } else { // This can happen if the client dies and is likely unrecoverable. // To avoid consuming resources generating failing calls, we stop sending diff --git a/automotive/evs/1.1/default/EvsUltrasonicsArray.h b/automotive/evs/1.1/default/EvsUltrasonicsArray.h index 7a4101290e..88aa6003f6 100644 --- a/automotive/evs/1.1/default/EvsUltrasonicsArray.h +++ b/automotive/evs/1.1/default/EvsUltrasonicsArray.h @@ -58,7 +58,7 @@ class EvsUltrasonicsArray : public IEvsUltrasonicsArray { static sp Create(const char* deviceName); // Returns a ultrasonics array descriptor filled with sample data. - static UltrasonicsArrayDesc GetDummyArrayDesc(const char* id); + static UltrasonicsArrayDesc GetMockArrayDesc(const char* id); DISALLOW_COPY_AND_ASSIGN(EvsUltrasonicsArray); virtual ~EvsUltrasonicsArray() override; diff --git a/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp b/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp index 4398fb13e3..638ecd5446 100644 --- a/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp +++ b/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp @@ -500,7 +500,7 @@ TEST_P(EvsHidlTest, CameraStreamPerformance) { TEST_P(EvsHidlTest, CameraStreamBuffering) { LOG(INFO) << "Starting CameraStreamBuffering test"; - // Arbitrary constant (should be > 1 and less than crazy) + // Arbitrary constant (should be > 1 and not too big) static const unsigned int kBuffersToHold = 6; // Get the camera list @@ -527,7 +527,7 @@ TEST_P(EvsHidlTest, CameraStreamBuffering) { // Store a camera handle for a clean-up activeCameras.push_back(pCam); - // Ask for a crazy number of buffers in flight to ensure it errors correctly + // Ask for a very large number of buffers in flight to ensure it errors correctly Return badResult = pCam->setMaxFramesInFlight(0xFFFFFFFF); EXPECT_EQ(EvsResult::BUFFER_NOT_AVAILABLE, badResult); @@ -930,12 +930,12 @@ TEST_P(EvsHidlTest, CameraParameter) { /* - * CameraMasterRelease - * Verify that non-master client gets notified when the master client either + * CameraPrimaryClientRelease + * Verify that non-primary client gets notified when the primary client either * terminates or releases a role. */ -TEST_P(EvsHidlTest, CameraMasterRelease) { - LOG(INFO) << "Starting CameraMasterRelease test"; +TEST_P(EvsHidlTest, CameraPrimaryClientRelease) { + LOG(INFO) << "Starting CameraPrimaryClientRelease test"; if (mIsHwModule) { // This test is not for HW module implementation. @@ -961,57 +961,57 @@ TEST_P(EvsHidlTest, CameraMasterRelease) { } // Create two camera clients. - sp pCamMaster = + sp pCamPrimary = IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg)) .withDefault(nullptr); - ASSERT_NE(pCamMaster, nullptr); + ASSERT_NE(pCamPrimary, nullptr); // Store a camera handle for a clean-up - activeCameras.push_back(pCamMaster); + activeCameras.push_back(pCamPrimary); - sp pCamNonMaster = + sp pCamSecondary = IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg)) .withDefault(nullptr); - ASSERT_NE(pCamNonMaster, nullptr); + ASSERT_NE(pCamSecondary, nullptr); // Store a camera handle for a clean-up - activeCameras.push_back(pCamNonMaster); + activeCameras.push_back(pCamSecondary); // Set up per-client frame receiver objects which will fire up its own thread - sp frameHandlerMaster = - new FrameHandler(pCamMaster, cam, + sp frameHandlerPrimary = + new FrameHandler(pCamPrimary, cam, nullptr, FrameHandler::eAutoReturn); - ASSERT_NE(frameHandlerMaster, nullptr); - sp frameHandlerNonMaster = - new FrameHandler(pCamNonMaster, cam, + ASSERT_NE(frameHandlerPrimary, nullptr); + sp frameHandlerSecondary = + new FrameHandler(pCamSecondary, cam, nullptr, FrameHandler::eAutoReturn); - ASSERT_NE(frameHandlerNonMaster, nullptr); + ASSERT_NE(frameHandlerSecondary, nullptr); - // Set one client as the master - EvsResult result = pCamMaster->setMaster(); + // Set one client as the primary client + EvsResult result = pCamPrimary->setMaster(); ASSERT_TRUE(result == EvsResult::OK); - // Try to set another client as the master. - result = pCamNonMaster->setMaster(); + // Try to set another client as the primary client. + result = pCamSecondary->setMaster(); ASSERT_TRUE(result == EvsResult::OWNERSHIP_LOST); - // Start the camera's video stream via a master client. - bool startResult = frameHandlerMaster->startStream(); + // Start the camera's video stream via a primary client client. + bool startResult = frameHandlerPrimary->startStream(); ASSERT_TRUE(startResult); // Ensure the stream starts - frameHandlerMaster->waitForFrameCount(1); + frameHandlerPrimary->waitForFrameCount(1); // Start the camera's video stream via another client - startResult = frameHandlerNonMaster->startStream(); + startResult = frameHandlerSecondary->startStream(); ASSERT_TRUE(startResult); // Ensure the stream starts - frameHandlerNonMaster->waitForFrameCount(1); + frameHandlerSecondary->waitForFrameCount(1); - // Non-master client expects to receive a master role relesed + // Non-primary client expects to receive a primary client role relesed // notification. EvsEventDesc aTargetEvent = {}; EvsEventDesc aNotification = {}; @@ -1020,14 +1020,14 @@ TEST_P(EvsHidlTest, CameraMasterRelease) { std::mutex eventLock; std::condition_variable eventCond; std::thread listener = std::thread( - [&aNotification, &frameHandlerNonMaster, &listening, &eventCond]() { + [&aNotification, &frameHandlerSecondary, &listening, &eventCond]() { // Notify that a listening thread is running. listening = true; eventCond.notify_all(); EvsEventDesc aTargetEvent; aTargetEvent.aType = EvsEventType::MASTER_RELEASED; - if (!frameHandlerNonMaster->waitForEvent(aTargetEvent, aNotification, true)) { + if (!frameHandlerSecondary->waitForEvent(aTargetEvent, aNotification, true)) { LOG(WARNING) << "A timer is expired before a target event is fired."; } @@ -1043,8 +1043,8 @@ TEST_P(EvsHidlTest, CameraMasterRelease) { } lock.unlock(); - // Release a master role. - pCamMaster->unsetMaster(); + // Release a primary client role. + pCamPrimary->unsetMaster(); // Join a listening thread. if (listener.joinable()) { @@ -1055,24 +1055,24 @@ TEST_P(EvsHidlTest, CameraMasterRelease) { ASSERT_EQ(EvsEventType::MASTER_RELEASED, static_cast(aNotification.aType)); - // Non-master becomes a master. - result = pCamNonMaster->setMaster(); + // Non-primary becomes a primary client. + result = pCamSecondary->setMaster(); ASSERT_TRUE(result == EvsResult::OK); - // Previous master client fails to become a master. - result = pCamMaster->setMaster(); + // Previous primary client fails to become a primary client. + result = pCamPrimary->setMaster(); ASSERT_TRUE(result == EvsResult::OWNERSHIP_LOST); listening = false; listener = std::thread( - [&aNotification, &frameHandlerMaster, &listening, &eventCond]() { + [&aNotification, &frameHandlerPrimary, &listening, &eventCond]() { // Notify that a listening thread is running. listening = true; eventCond.notify_all(); EvsEventDesc aTargetEvent; aTargetEvent.aType = EvsEventType::MASTER_RELEASED; - if (!frameHandlerMaster->waitForEvent(aTargetEvent, aNotification, true)) { + if (!frameHandlerPrimary->waitForEvent(aTargetEvent, aNotification, true)) { LOG(WARNING) << "A timer is expired before a target event is fired."; } @@ -1087,8 +1087,8 @@ TEST_P(EvsHidlTest, CameraMasterRelease) { } lock.unlock(); - // Closing current master client. - frameHandlerNonMaster->shutdown(); + // Closing current primary client. + frameHandlerSecondary->shutdown(); // Join a listening thread. if (listener.joinable()) { @@ -1100,11 +1100,11 @@ TEST_P(EvsHidlTest, CameraMasterRelease) { static_cast(aNotification.aType)); // Closing streams. - frameHandlerMaster->shutdown(); + frameHandlerPrimary->shutdown(); // Explicitly release the camera - pEnumerator->closeCamera(pCamMaster); - pEnumerator->closeCamera(pCamNonMaster); + pEnumerator->closeCamera(pCamPrimary); + pEnumerator->closeCamera(pCamSecondary); activeCameras.clear(); } } @@ -1112,7 +1112,7 @@ TEST_P(EvsHidlTest, CameraMasterRelease) { /* * MultiCameraParameter: - * Verify that master and non-master clients behave as expected when they try to adjust + * Verify that primary and non-primary clients behave as expected when they try to adjust * camera parameters. */ TEST_P(EvsHidlTest, MultiCameraParameter) { @@ -1142,88 +1142,88 @@ TEST_P(EvsHidlTest, MultiCameraParameter) { } // Create two camera clients. - sp pCamMaster = + sp pCamPrimary = IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg)) .withDefault(nullptr); - ASSERT_NE(pCamMaster, nullptr); + ASSERT_NE(pCamPrimary, nullptr); // Store a camera handle for a clean-up - activeCameras.push_back(pCamMaster); + activeCameras.push_back(pCamPrimary); - sp pCamNonMaster = + sp pCamSecondary = IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg)) .withDefault(nullptr); - ASSERT_NE(pCamNonMaster, nullptr); + ASSERT_NE(pCamSecondary, nullptr); // Store a camera handle for a clean-up - activeCameras.push_back(pCamNonMaster); + activeCameras.push_back(pCamSecondary); // Get the parameter list - std::vector camMasterCmds, camNonMasterCmds; - pCamMaster->getParameterList([&camMasterCmds](hidl_vec cmdList) { - camMasterCmds.reserve(cmdList.size()); + std::vector camPrimaryCmds, camSecondaryCmds; + pCamPrimary->getParameterList([&camPrimaryCmds](hidl_vec cmdList) { + camPrimaryCmds.reserve(cmdList.size()); for (auto &&cmd : cmdList) { - camMasterCmds.push_back(cmd); + camPrimaryCmds.push_back(cmd); } } ); - pCamNonMaster->getParameterList([&camNonMasterCmds](hidl_vec cmdList) { - camNonMasterCmds.reserve(cmdList.size()); + pCamSecondary->getParameterList([&camSecondaryCmds](hidl_vec cmdList) { + camSecondaryCmds.reserve(cmdList.size()); for (auto &&cmd : cmdList) { - camNonMasterCmds.push_back(cmd); + camSecondaryCmds.push_back(cmd); } } ); - if (camMasterCmds.size() < 1 || - camNonMasterCmds.size() < 1) { + if (camPrimaryCmds.size() < 1 || + camSecondaryCmds.size() < 1) { // Skip a camera device if it does not support any parameter. continue; } // Set up per-client frame receiver objects which will fire up its own thread - sp frameHandlerMaster = - new FrameHandler(pCamMaster, cam, + sp frameHandlerPrimary = + new FrameHandler(pCamPrimary, cam, nullptr, FrameHandler::eAutoReturn); - ASSERT_NE(frameHandlerMaster, nullptr); - sp frameHandlerNonMaster = - new FrameHandler(pCamNonMaster, cam, + ASSERT_NE(frameHandlerPrimary, nullptr); + sp frameHandlerSecondary = + new FrameHandler(pCamSecondary, cam, nullptr, FrameHandler::eAutoReturn); - ASSERT_NE(frameHandlerNonMaster, nullptr); + ASSERT_NE(frameHandlerSecondary, nullptr); - // Set one client as the master - EvsResult result = pCamMaster->setMaster(); + // Set one client as the primary client. + EvsResult result = pCamPrimary->setMaster(); ASSERT_EQ(EvsResult::OK, result); - // Try to set another client as the master. - result = pCamNonMaster->setMaster(); + // Try to set another client as the primary client. + result = pCamSecondary->setMaster(); ASSERT_EQ(EvsResult::OWNERSHIP_LOST, result); - // Start the camera's video stream via a master client. - bool startResult = frameHandlerMaster->startStream(); + // Start the camera's video stream via a primary client client. + bool startResult = frameHandlerPrimary->startStream(); ASSERT_TRUE(startResult); // Ensure the stream starts - frameHandlerMaster->waitForFrameCount(1); + frameHandlerPrimary->waitForFrameCount(1); // Start the camera's video stream via another client - startResult = frameHandlerNonMaster->startStream(); + startResult = frameHandlerSecondary->startStream(); ASSERT_TRUE(startResult); // Ensure the stream starts - frameHandlerNonMaster->waitForFrameCount(1); + frameHandlerSecondary->waitForFrameCount(1); int32_t val0 = 0; std::vector values; EvsEventDesc aNotification0 = {}; EvsEventDesc aNotification1 = {}; - for (auto &cmd : camMasterCmds) { + for (auto &cmd : camPrimaryCmds) { // Get a valid parameter value range int32_t minVal, maxVal, step; - pCamMaster->getIntParameterRange( + pCamPrimary->getIntParameterRange( cmd, [&minVal, &maxVal, &step](int32_t val0, int32_t val1, int32_t val2) { minVal = val0; @@ -1236,7 +1236,7 @@ TEST_P(EvsHidlTest, MultiCameraParameter) { if (cmd == CameraParam::ABSOLUTE_FOCUS) { // Try to turn off auto-focus values.clear(); - pCamMaster->setIntParameter(CameraParam::AUTO_FOCUS, 0, + pCamPrimary->setIntParameter(CameraParam::AUTO_FOCUS, 0, [&result, &values](auto status, auto effectiveValues) { result = status; if (status == EvsResult::OK) { @@ -1261,7 +1261,7 @@ TEST_P(EvsHidlTest, MultiCameraParameter) { std::condition_variable eventCond; std::thread listener0 = std::thread( [cmd, val0, - &aNotification0, &frameHandlerMaster, &listening0, &listening1, &eventCond]() { + &aNotification0, &frameHandlerPrimary, &listening0, &listening1, &eventCond]() { listening0 = true; if (listening1) { eventCond.notify_all(); @@ -1271,14 +1271,14 @@ TEST_P(EvsHidlTest, MultiCameraParameter) { aTargetEvent.aType = EvsEventType::PARAMETER_CHANGED; aTargetEvent.payload[0] = static_cast(cmd); aTargetEvent.payload[1] = val0; - if (!frameHandlerMaster->waitForEvent(aTargetEvent, aNotification0)) { + if (!frameHandlerPrimary->waitForEvent(aTargetEvent, aNotification0)) { LOG(WARNING) << "A timer is expired before a target event is fired."; } } ); std::thread listener1 = std::thread( [cmd, val0, - &aNotification1, &frameHandlerNonMaster, &listening0, &listening1, &eventCond]() { + &aNotification1, &frameHandlerSecondary, &listening0, &listening1, &eventCond]() { listening1 = true; if (listening0) { eventCond.notify_all(); @@ -1288,7 +1288,7 @@ TEST_P(EvsHidlTest, MultiCameraParameter) { aTargetEvent.aType = EvsEventType::PARAMETER_CHANGED; aTargetEvent.payload[0] = static_cast(cmd); aTargetEvent.payload[1] = val0; - if (!frameHandlerNonMaster->waitForEvent(aTargetEvent, aNotification1)) { + if (!frameHandlerSecondary->waitForEvent(aTargetEvent, aNotification1)) { LOG(WARNING) << "A timer is expired before a target event is fired."; } } @@ -1305,7 +1305,7 @@ TEST_P(EvsHidlTest, MultiCameraParameter) { // Try to program a parameter values.clear(); - pCamMaster->setIntParameter(cmd, val0, + pCamPrimary->setIntParameter(cmd, val0, [&result, &values](auto status, auto effectiveValues) { result = status; if (status == EvsResult::OK) { @@ -1345,9 +1345,9 @@ TEST_P(EvsHidlTest, MultiCameraParameter) { } // Clients expects to receive a parameter change notification - // whenever a master client adjusts it. + // whenever a primary client client adjusts it. values.clear(); - pCamMaster->getIntParameter(cmd, + pCamPrimary->getIntParameter(cmd, [&result, &values](auto status, auto readValues) { result = status; if (status == EvsResult::OK) { @@ -1362,9 +1362,9 @@ TEST_P(EvsHidlTest, MultiCameraParameter) { } } - // Try to adjust a parameter via non-master client + // Try to adjust a parameter via non-primary client values.clear(); - pCamNonMaster->setIntParameter(camNonMasterCmds[0], val0, + pCamSecondary->setIntParameter(camSecondaryCmds[0], val0, [&result, &values](auto status, auto effectiveValues) { result = status; if (status == EvsResult::OK) { @@ -1375,21 +1375,21 @@ TEST_P(EvsHidlTest, MultiCameraParameter) { }); ASSERT_EQ(EvsResult::INVALID_ARG, result); - // Non-master client attemps to be a master - result = pCamNonMaster->setMaster(); + // Non-primary client attempts to be a primary client + result = pCamSecondary->setMaster(); ASSERT_EQ(EvsResult::OWNERSHIP_LOST, result); - // Master client retires from a master role + // Primary client retires from a primary client role bool listening = false; std::condition_variable eventCond; std::thread listener = std::thread( - [&aNotification0, &frameHandlerNonMaster, &listening, &eventCond]() { + [&aNotification0, &frameHandlerSecondary, &listening, &eventCond]() { listening = true; eventCond.notify_all(); EvsEventDesc aTargetEvent; aTargetEvent.aType = EvsEventType::MASTER_RELEASED; - if (!frameHandlerNonMaster->waitForEvent(aTargetEvent, aNotification0, true)) { + if (!frameHandlerSecondary->waitForEvent(aTargetEvent, aNotification0, true)) { LOG(WARNING) << "A timer is expired before a target event is fired."; } } @@ -1403,7 +1403,7 @@ TEST_P(EvsHidlTest, MultiCameraParameter) { } lock.unlock(); - result = pCamMaster->unsetMaster(); + result = pCamPrimary->unsetMaster(); ASSERT_EQ(EvsResult::OK, result); if (listener.joinable()) { @@ -1414,7 +1414,7 @@ TEST_P(EvsHidlTest, MultiCameraParameter) { // Try to adjust a parameter after being retired values.clear(); - pCamMaster->setIntParameter(camMasterCmds[0], val0, + pCamPrimary->setIntParameter(camPrimaryCmds[0], val0, [&result, &values](auto status, auto effectiveValues) { result = status; if (status == EvsResult::OK) { @@ -1425,15 +1425,15 @@ TEST_P(EvsHidlTest, MultiCameraParameter) { }); ASSERT_EQ(EvsResult::INVALID_ARG, result); - // Non-master client becomes a master - result = pCamNonMaster->setMaster(); + // Non-primary client becomes a primary client + result = pCamSecondary->setMaster(); ASSERT_EQ(EvsResult::OK, result); - // Try to adjust a parameter via new master client - for (auto &cmd : camNonMasterCmds) { + // Try to adjust a parameter via new primary client + for (auto &cmd : camSecondaryCmds) { // Get a valid parameter value range int32_t minVal, maxVal, step; - pCamNonMaster->getIntParameterRange( + pCamSecondary->getIntParameterRange( cmd, [&minVal, &maxVal, &step](int32_t val0, int32_t val1, int32_t val2) { minVal = val0; @@ -1447,7 +1447,7 @@ TEST_P(EvsHidlTest, MultiCameraParameter) { if (cmd == CameraParam::ABSOLUTE_FOCUS) { // Try to turn off auto-focus values.clear(); - pCamNonMaster->setIntParameter(CameraParam::AUTO_FOCUS, 0, + pCamSecondary->setIntParameter(CameraParam::AUTO_FOCUS, 0, [&result, &values](auto status, auto effectiveValues) { result = status; if (status == EvsResult::OK) { @@ -1471,7 +1471,7 @@ TEST_P(EvsHidlTest, MultiCameraParameter) { bool listening1 = false; std::condition_variable eventCond; std::thread listener0 = std::thread( - [&cmd, &val0, &aNotification0, &frameHandlerMaster, &listening0, &listening1, &eventCond]() { + [&]() { listening0 = true; if (listening1) { eventCond.notify_all(); @@ -1481,13 +1481,13 @@ TEST_P(EvsHidlTest, MultiCameraParameter) { aTargetEvent.aType = EvsEventType::PARAMETER_CHANGED; aTargetEvent.payload[0] = static_cast(cmd); aTargetEvent.payload[1] = val0; - if (!frameHandlerMaster->waitForEvent(aTargetEvent, aNotification0)) { + if (!frameHandlerPrimary->waitForEvent(aTargetEvent, aNotification0)) { LOG(WARNING) << "A timer is expired before a target event is fired."; } } ); std::thread listener1 = std::thread( - [&cmd, &val0, &aNotification1, &frameHandlerNonMaster, &listening0, &listening1, &eventCond]() { + [&]() { listening1 = true; if (listening0) { eventCond.notify_all(); @@ -1497,7 +1497,7 @@ TEST_P(EvsHidlTest, MultiCameraParameter) { aTargetEvent.aType = EvsEventType::PARAMETER_CHANGED; aTargetEvent.payload[0] = static_cast(cmd); aTargetEvent.payload[1] = val0; - if (!frameHandlerNonMaster->waitForEvent(aTargetEvent, aNotification1)) { + if (!frameHandlerSecondary->waitForEvent(aTargetEvent, aNotification1)) { LOG(WARNING) << "A timer is expired before a target event is fired."; } } @@ -1514,7 +1514,7 @@ TEST_P(EvsHidlTest, MultiCameraParameter) { // Try to program a parameter values.clear(); - pCamNonMaster->setIntParameter(cmd, val0, + pCamSecondary->setIntParameter(cmd, val0, [&result, &values](auto status, auto effectiveValues) { result = status; if (status == EvsResult::OK) { @@ -1526,9 +1526,9 @@ TEST_P(EvsHidlTest, MultiCameraParameter) { ASSERT_EQ(EvsResult::OK, result); // Clients expects to receive a parameter change notification - // whenever a master client adjusts it. + // whenever a primary client client adjusts it. values.clear(); - pCamNonMaster->getIntParameter(cmd, + pCamSecondary->getIntParameter(cmd, [&result, &values](auto status, auto readValues) { result = status; if (status == EvsResult::OK) { @@ -1567,17 +1567,17 @@ TEST_P(EvsHidlTest, MultiCameraParameter) { } } - // New master retires from a master role - result = pCamNonMaster->unsetMaster(); + // New primary client retires from the role + result = pCamSecondary->unsetMaster(); ASSERT_EQ(EvsResult::OK, result); // Shutdown - frameHandlerMaster->shutdown(); - frameHandlerNonMaster->shutdown(); + frameHandlerPrimary->shutdown(); + frameHandlerSecondary->shutdown(); // Explicitly release the camera - pEnumerator->closeCamera(pCamMaster); - pEnumerator->closeCamera(pCamNonMaster); + pEnumerator->closeCamera(pCamPrimary); + pEnumerator->closeCamera(pCamSecondary); activeCameras.clear(); } } @@ -1586,7 +1586,7 @@ TEST_P(EvsHidlTest, MultiCameraParameter) { /* * HighPriorityCameraClient: * EVS client, which owns the display, is priortized and therefore can take over - * a master role from other EVS clients without the display. + * a primary client role from other EVS clients without the display. */ TEST_P(EvsHidlTest, HighPriorityCameraClient) { LOG(INFO) << "Starting HighPriorityCameraClient test"; @@ -1668,7 +1668,7 @@ TEST_P(EvsHidlTest, HighPriorityCameraClient) { frameHandler0->waitForFrameCount(1); frameHandler1->waitForFrameCount(1); - // Client 1 becomes a master and programs a parameter. + // Client 1 becomes a primary client and programs a parameter. EvsResult result = EvsResult::OK; // Get a valid parameter value range int32_t minVal, maxVal, step; @@ -1681,7 +1681,7 @@ TEST_P(EvsHidlTest, HighPriorityCameraClient) { } ); - // Client1 becomes a master + // Client1 becomes a primary client result = pCam1->setMaster(); ASSERT_EQ(EvsResult::OK, result); @@ -1820,7 +1820,7 @@ TEST_P(EvsHidlTest, HighPriorityCameraClient) { } lock.unlock(); - // Client 0 steals a master role + // Client 0 steals a primary client role ASSERT_EQ(EvsResult::OK, pCam0->forceMaster(pDisplay)); // Join a listener @@ -2241,7 +2241,7 @@ TEST_P(EvsHidlTest, LogicalCameraMetadata) { TEST_P(EvsHidlTest, CameraStreamExternalBuffering) { LOG(INFO) << "Starting CameraStreamExternalBuffering test"; - // Arbitrary constant (should be > 1 and less than crazy) + // Arbitrary constant (should be > 1 and not too big) static const unsigned int kBuffersToHold = 6; // Get the camera list -- GitLab From 1913fdbf3eb694d99e7a0dcfef69a904613d6439 Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Wed, 5 Aug 2020 10:17:48 +0800 Subject: [PATCH 103/790] wifi: uprev supplicant interface to 1.4 Bug: 162901316 Test: atest VtsHalWifiSupplicantV1_0TargetTest \ VtsHalWifiSupplicantP2pV1_0TargetTest \ VtsHalWifiSupplicantV1_1TargetTest \ VtsHalWifiSupplicantV1_2TargetTest \ VtsHalWifiSupplicantP2pV1_2TargetTest \ VtsHalWifiSupplicantV1_3TargetTest Change-Id: Ic6292bb27e234f76013a341e62652dedf55f8490 --- .../compatibility_matrix.current.xml | 2 +- wifi/supplicant/1.4/Android.bp | 21 ++++++++++++++ wifi/supplicant/1.4/ISupplicant.hal | 29 +++++++++++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 wifi/supplicant/1.4/Android.bp create mode 100644 wifi/supplicant/1.4/ISupplicant.hal diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index 946392458e..31dd6c4b66 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -545,7 +545,7 @@ android.hardware.wifi.supplicant - 1.0-3 + 1.0-4 ISupplicant default diff --git a/wifi/supplicant/1.4/Android.bp b/wifi/supplicant/1.4/Android.bp new file mode 100644 index 0000000000..ff2a8bc665 --- /dev/null +++ b/wifi/supplicant/1.4/Android.bp @@ -0,0 +1,21 @@ +// This file is autogenerated by hidl-gen -Landroidbp. + +hidl_interface { + name: "android.hardware.wifi.supplicant@1.4", + root: "android.hardware", + srcs: [ + "ISupplicant.hal", + ], + interfaces: [ + "android.hardware.wifi.supplicant@1.0", + "android.hardware.wifi.supplicant@1.1", + "android.hardware.wifi.supplicant@1.2", + "android.hardware.wifi.supplicant@1.3", + "android.hardware.wifi@1.0", + "android.hidl.base@1.0", + ], + gen_java: true, + apex_available: [ + "com.android.wifi", + ], +} diff --git a/wifi/supplicant/1.4/ISupplicant.hal b/wifi/supplicant/1.4/ISupplicant.hal new file mode 100644 index 0000000000..9cb88ba43b --- /dev/null +++ b/wifi/supplicant/1.4/ISupplicant.hal @@ -0,0 +1,29 @@ +/* + * 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. + */ + +package android.hardware.wifi.supplicant@1.4; + +import @1.3::ISupplicant; + +/** + * Interface exposed by the supplicant HIDL service registered + * with the hardware service manager. + * This is the root level object for any the supplicant interactions. + * To use 1.4 features you must cast specific interfaces returned from the + * 1.1 HAL. For example V1_1::ISupplicant::addIface() adds V1_0::ISupplicantIface, + * which can be cast to V1_4::ISupplicantStaIface. + */ +interface ISupplicant extends @1.3::ISupplicant {}; -- GitLab From e29acd8194c6df2fc81613cebdb2dc4507ec4c1b Mon Sep 17 00:00:00 2001 From: Lais Andrade Date: Fri, 7 Aug 2020 13:21:17 +0000 Subject: [PATCH 104/790] Move vibrator HAL benchmarks to interfaces/vibrator The benchmarks are relying only with the HAL interfaces, so they can be moved outside the pixel folder and integrated with continuous native metric tests. Bug: b/159981541 Test: N/A, just moving tests Change-Id: I54e7155d12eb844df7f77e8c5d232949426546d2 --- vibrator/bench/Android.bp | 34 +++ vibrator/bench/benchmark.cpp | 577 +++++++++++++++++++++++++++++++++++ 2 files changed, 611 insertions(+) create mode 100644 vibrator/bench/Android.bp create mode 100644 vibrator/bench/benchmark.cpp diff --git a/vibrator/bench/Android.bp b/vibrator/bench/Android.bp new file mode 100644 index 0000000000..c7f824d75f --- /dev/null +++ b/vibrator/bench/Android.bp @@ -0,0 +1,34 @@ +// +// 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. + +cc_benchmark { + name: "VibratorHalIntegrationBenchmark", + defaults: ["hidl_defaults"], + srcs: [ + "benchmark.cpp", + ], + shared_libs: [ + "android.hardware.vibrator-cpp", + "android.hardware.vibrator@1.0", + "android.hardware.vibrator@1.1", + "android.hardware.vibrator@1.2", + "android.hardware.vibrator@1.3", + "libbinder", + "libhardware", + "libhidlbase", + "libutils", + ], + test_suites: ["device-tests"], +} diff --git a/vibrator/bench/benchmark.cpp b/vibrator/bench/benchmark.cpp new file mode 100644 index 0000000000..e19dc6f215 --- /dev/null +++ b/vibrator/bench/benchmark.cpp @@ -0,0 +1,577 @@ +/* + * 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 "benchmark/benchmark.h" + +#include +#include +#include +#include + +using ::android::enum_range; +using ::android::sp; +using ::android::hardware::hidl_enum_range; +using ::android::hardware::Return; +using ::android::hardware::details::hidl_enum_values; +using ::benchmark::Counter; +using ::benchmark::Fixture; +using ::benchmark::kMicrosecond; +using ::benchmark::State; +using ::benchmark::internal::Benchmark; +using ::std::chrono::duration; +using ::std::chrono::duration_cast; +using ::std::chrono::high_resolution_clock; + +namespace Aidl = ::android::hardware::vibrator; +namespace V1_0 = ::android::hardware::vibrator::V1_0; +namespace V1_1 = ::android::hardware::vibrator::V1_1; +namespace V1_2 = ::android::hardware::vibrator::V1_2; +namespace V1_3 = ::android::hardware::vibrator::V1_3; + +template +class BaseBench : public Fixture { + public: + void TearDown(State& /*state*/) override { + if (!mVibrator) { + return; + } + mVibrator->off(); + } + + static void DefaultConfig(Benchmark* b) { b->Unit(kMicrosecond); } + + static void DefaultArgs(Benchmark* /*b*/) { /* none */ + } + + protected: + auto getOtherArg(const State& state, std::size_t index) const { return state.range(index + 0); } + + protected: + sp mVibrator; +}; + +template +class VibratorBench : public BaseBench { + public: + void SetUp(State& /*state*/) override { this->mVibrator = I::getService(); } +}; + +enum class EmptyEnum : uint32_t; +template <> +inline constexpr std::array hidl_enum_values = {}; + +template +std::set difference(const hidl_enum_range& t, const hidl_enum_range& u) { + class Compare { + public: + bool operator()(const T& a, const U& b) { return a < static_cast(b); } + bool operator()(const U& a, const T& b) { return static_cast(a) < b; } + }; + std::set ret; + + std::set_difference(t.begin(), t.end(), u.begin(), u.end(), + std::insert_iterator(ret, ret.begin()), Compare()); + + return ret; +} + +template +class VibratorEffectsBench : public VibratorBench { + public: + using Effect = E1; + using EffectStrength = V1_0::EffectStrength; + using Status = V1_0::Status; + + public: + static void DefaultArgs(Benchmark* b) { + b->ArgNames({"Effect", "Strength"}); + for (const auto& effect : difference(hidl_enum_range(), hidl_enum_range())) { + for (const auto& strength : hidl_enum_range()) { + b->Args({static_cast(effect), static_cast(strength)}); + } + } + } + + void performBench(State* state, Return (I::*performApi)(Effect, EffectStrength, + typename I::perform_cb)) { + auto effect = getEffect(*state); + auto strength = getStrength(*state); + bool supported = true; + + (*this->mVibrator.*performApi)(effect, strength, [&](Status status, uint32_t /*lengthMs*/) { + if (status == Status::UNSUPPORTED_OPERATION) { + supported = false; + } + }); + + if (!supported) { + return; + } + + for (auto _ : *state) { + state->ResumeTiming(); + (*this->mVibrator.*performApi)(effect, strength, + [](Status /*status*/, uint32_t /*lengthMs*/) {}); + state->PauseTiming(); + this->mVibrator->off(); + } + } + + protected: + auto getEffect(const State& state) const { + return static_cast(this->getOtherArg(state, 0)); + } + + auto getStrength(const State& state) const { + return static_cast(this->getOtherArg(state, 1)); + } +}; + +#define BENCHMARK_WRAPPER(fixt, test, code) \ + BENCHMARK_DEFINE_F(fixt, test) \ + /* NOLINTNEXTLINE */ \ + (State & state) { \ + if (!mVibrator) { \ + return; \ + } \ + \ + code \ + } \ + BENCHMARK_REGISTER_F(fixt, test)->Apply(fixt::DefaultConfig)->Apply(fixt::DefaultArgs) + +using VibratorBench_V1_0 = VibratorBench; + +BENCHMARK_WRAPPER(VibratorBench_V1_0, on, { + uint32_t ms = UINT32_MAX; + + for (auto _ : state) { + state.ResumeTiming(); + mVibrator->on(ms); + state.PauseTiming(); + mVibrator->off(); + } +}); + +BENCHMARK_WRAPPER(VibratorBench_V1_0, off, { + uint32_t ms = UINT32_MAX; + + for (auto _ : state) { + state.PauseTiming(); + mVibrator->on(ms); + state.ResumeTiming(); + mVibrator->off(); + } +}); + +BENCHMARK_WRAPPER(VibratorBench_V1_0, supportsAmplitudeControl, { + for (auto _ : state) { + mVibrator->supportsAmplitudeControl(); + } +}); + +BENCHMARK_WRAPPER(VibratorBench_V1_0, setAmplitude, { + uint8_t amplitude = UINT8_MAX; + + if (!mVibrator->supportsAmplitudeControl()) { + return; + } + + mVibrator->on(UINT32_MAX); + + for (auto _ : state) { + mVibrator->setAmplitude(amplitude); + } + + mVibrator->off(); +}); + +using VibratorEffectsBench_V1_0 = VibratorEffectsBench; + +BENCHMARK_WRAPPER(VibratorEffectsBench_V1_0, perform, + { performBench(&state, &V1_0::IVibrator::perform); }); + +using VibratorEffectsBench_V1_1 = + VibratorEffectsBench; + +BENCHMARK_WRAPPER(VibratorEffectsBench_V1_1, perform_1_1, + { performBench(&state, &V1_1::IVibrator::perform_1_1); }); + +using VibratorEffectsBench_V1_2 = + VibratorEffectsBench; + +BENCHMARK_WRAPPER(VibratorEffectsBench_V1_2, perform_1_2, + { performBench(&state, &V1_2::IVibrator::perform_1_2); }); + +using VibratorBench_V1_3 = VibratorBench; + +BENCHMARK_WRAPPER(VibratorBench_V1_3, supportsExternalControl, { + for (auto _ : state) { + mVibrator->supportsExternalControl(); + } +}); + +BENCHMARK_WRAPPER(VibratorBench_V1_3, setExternalControl, { + bool enable = true; + + if (!mVibrator->supportsExternalControl()) { + return; + } + + for (auto _ : state) { + state.ResumeTiming(); + mVibrator->setExternalControl(enable); + state.PauseTiming(); + mVibrator->setExternalControl(false); + } +}); + +BENCHMARK_WRAPPER(VibratorBench_V1_3, supportsExternalAmplitudeControl, { + if (!mVibrator->supportsExternalControl()) { + return; + } + + mVibrator->setExternalControl(true); + + for (auto _ : state) { + mVibrator->supportsAmplitudeControl(); + } + + mVibrator->setExternalControl(false); +}); + +BENCHMARK_WRAPPER(VibratorBench_V1_3, setExternalAmplitude, { + uint8_t amplitude = UINT8_MAX; + + if (!mVibrator->supportsExternalControl()) { + return; + } + + mVibrator->setExternalControl(true); + + if (!mVibrator->supportsAmplitudeControl()) { + return; + } + + for (auto _ : state) { + mVibrator->setAmplitude(amplitude); + } + + mVibrator->setExternalControl(false); +}); + +using VibratorEffectsBench_V1_3 = VibratorEffectsBench; + +BENCHMARK_WRAPPER(VibratorEffectsBench_V1_3, perform_1_3, + { performBench(&state, &V1_3::IVibrator::perform_1_3); }); + +class VibratorBench_Aidl : public BaseBench { + public: + void SetUp(State& /*state*/) override { + this->mVibrator = android::waitForVintfService(); + } +}; + +class HalCallback : public Aidl::BnVibratorCallback { + public: + HalCallback() = default; + ~HalCallback() = default; + + android::binder::Status onComplete() override { return android::binder::Status::ok(); } +}; + +BENCHMARK_WRAPPER(VibratorBench_Aidl, on, { + int32_t capabilities = 0; + mVibrator->getCapabilities(&capabilities); + + int32_t ms = INT32_MAX; + auto cb = (capabilities & Aidl::IVibrator::CAP_ON_CALLBACK) ? new HalCallback() : nullptr; + + for (auto _ : state) { + state.ResumeTiming(); + mVibrator->on(ms, cb); + state.PauseTiming(); + mVibrator->off(); + } +}); + +BENCHMARK_WRAPPER(VibratorBench_Aidl, off, { + for (auto _ : state) { + state.PauseTiming(); + mVibrator->on(INT32_MAX, nullptr); + state.ResumeTiming(); + mVibrator->off(); + } +}); + +BENCHMARK_WRAPPER(VibratorBench_Aidl, getCapabilities, { + int32_t capabilities = 0; + + for (auto _ : state) { + mVibrator->getCapabilities(&capabilities); + } +}); + +BENCHMARK_WRAPPER(VibratorBench_Aidl, setAmplitude, { + int32_t capabilities = 0; + mVibrator->getCapabilities(&capabilities); + if ((capabilities & Aidl::IVibrator::CAP_AMPLITUDE_CONTROL) == 0) { + return; + } + + float amplitude = 1.0f; + mVibrator->on(INT32_MAX, nullptr); + + for (auto _ : state) { + mVibrator->setAmplitude(amplitude); + } + + mVibrator->off(); +}); + +BENCHMARK_WRAPPER(VibratorBench_Aidl, setExternalControl, { + int32_t capabilities = 0; + mVibrator->getCapabilities(&capabilities); + if ((capabilities & Aidl::IVibrator::CAP_EXTERNAL_CONTROL) == 0) { + return; + } + + for (auto _ : state) { + state.ResumeTiming(); + mVibrator->setExternalControl(true); + state.PauseTiming(); + mVibrator->setExternalControl(false); + } +}); + +BENCHMARK_WRAPPER(VibratorBench_Aidl, setExternalAmplitude, { + int32_t capabilities = 0; + mVibrator->getCapabilities(&capabilities); + if ((capabilities & Aidl::IVibrator::CAP_EXTERNAL_CONTROL) == 0 || + (capabilities & Aidl::IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL) == 0) { + return; + } + + float amplitude = 1.0f; + mVibrator->setExternalControl(true); + + for (auto _ : state) { + mVibrator->setAmplitude(amplitude); + } + + mVibrator->setExternalControl(false); +}); + +BENCHMARK_WRAPPER(VibratorBench_Aidl, getSupportedEffects, { + std::vector supportedEffects; + + for (auto _ : state) { + mVibrator->getSupportedEffects(&supportedEffects); + } +}); + +BENCHMARK_WRAPPER(VibratorBench_Aidl, getSupportedAlwaysOnEffects, { + std::vector supportedEffects; + + for (auto _ : state) { + mVibrator->getSupportedAlwaysOnEffects(&supportedEffects); + } +}); + +BENCHMARK_WRAPPER(VibratorBench_Aidl, getSupportedPrimitives, { + std::vector supportedPrimitives; + + for (auto _ : state) { + mVibrator->getSupportedPrimitives(&supportedPrimitives); + } +}); + +class VibratorEffectsBench_Aidl : public VibratorBench_Aidl { + public: + static void DefaultArgs(Benchmark* b) { + b->ArgNames({"Effect", "Strength"}); + for (const auto& effect : enum_range()) { + for (const auto& strength : enum_range()) { + b->Args({static_cast(effect), static_cast(strength)}); + } + } + } + + protected: + auto getEffect(const State& state) const { + return static_cast(this->getOtherArg(state, 0)); + } + + auto getStrength(const State& state) const { + return static_cast(this->getOtherArg(state, 1)); + } +}; + +BENCHMARK_WRAPPER(VibratorEffectsBench_Aidl, alwaysOnEnable, { + int32_t capabilities = 0; + mVibrator->getCapabilities(&capabilities); + if ((capabilities & Aidl::IVibrator::CAP_ALWAYS_ON_CONTROL) == 0) { + return; + } + + int32_t id = 1; + auto effect = getEffect(state); + auto strength = getStrength(state); + + std::vector supported; + mVibrator->getSupportedAlwaysOnEffects(&supported); + if (std::find(supported.begin(), supported.end(), effect) == supported.end()) { + return; + } + + for (auto _ : state) { + state.ResumeTiming(); + mVibrator->alwaysOnEnable(id, effect, strength); + state.PauseTiming(); + mVibrator->alwaysOnDisable(id); + } +}); + +BENCHMARK_WRAPPER(VibratorEffectsBench_Aidl, alwaysOnDisable, { + int32_t capabilities = 0; + mVibrator->getCapabilities(&capabilities); + if ((capabilities & Aidl::IVibrator::CAP_ALWAYS_ON_CONTROL) == 0) { + return; + } + + int32_t id = 1; + auto effect = getEffect(state); + auto strength = getStrength(state); + + std::vector supported; + mVibrator->getSupportedAlwaysOnEffects(&supported); + if (std::find(supported.begin(), supported.end(), effect) == supported.end()) { + return; + } + + for (auto _ : state) { + state.PauseTiming(); + mVibrator->alwaysOnEnable(id, effect, strength); + state.ResumeTiming(); + mVibrator->alwaysOnDisable(id); + } +}); + +BENCHMARK_WRAPPER(VibratorEffectsBench_Aidl, perform, { + int32_t capabilities = 0; + mVibrator->getCapabilities(&capabilities); + + auto effect = getEffect(state); + auto strength = getStrength(state); + auto cb = (capabilities & Aidl::IVibrator::CAP_PERFORM_CALLBACK) ? new HalCallback() : nullptr; + int32_t lengthMs = 0; + + std::vector supported; + mVibrator->getSupportedEffects(&supported); + if (std::find(supported.begin(), supported.end(), effect) == supported.end()) { + return; + } + + for (auto _ : state) { + state.ResumeTiming(); + mVibrator->perform(effect, strength, cb, &lengthMs); + state.PauseTiming(); + mVibrator->off(); + } +}); + +class VibratorPrimitivesBench_Aidl : public VibratorBench_Aidl { + public: + static void DefaultArgs(Benchmark* b) { + b->ArgNames({"Primitive"}); + for (const auto& primitive : enum_range()) { + b->Args({static_cast(primitive)}); + } + } + + protected: + auto getPrimitive(const State& state) const { + return static_cast(this->getOtherArg(state, 0)); + } +}; + +BENCHMARK_WRAPPER(VibratorBench_Aidl, getCompositionDelayMax, { + int32_t ms = 0; + + for (auto _ : state) { + mVibrator->getCompositionDelayMax(&ms); + } +}); + +BENCHMARK_WRAPPER(VibratorBench_Aidl, getCompositionSizeMax, { + int32_t size = 0; + + for (auto _ : state) { + mVibrator->getCompositionSizeMax(&size); + } +}); + +BENCHMARK_WRAPPER(VibratorPrimitivesBench_Aidl, getPrimitiveDuration, { + int32_t capabilities = 0; + mVibrator->getCapabilities(&capabilities); + if ((capabilities & Aidl::IVibrator::CAP_COMPOSE_EFFECTS) == 0) { + return; + } + + auto primitive = getPrimitive(state); + int32_t ms = 0; + + std::vector supported; + mVibrator->getSupportedPrimitives(&supported); + if (std::find(supported.begin(), supported.end(), primitive) == supported.end()) { + return; + } + + for (auto _ : state) { + mVibrator->getPrimitiveDuration(primitive, &ms); + } +}); + +BENCHMARK_WRAPPER(VibratorPrimitivesBench_Aidl, compose, { + int32_t capabilities = 0; + mVibrator->getCapabilities(&capabilities); + if ((capabilities & Aidl::IVibrator::CAP_COMPOSE_EFFECTS) == 0) { + return; + } + + Aidl::CompositeEffect effect; + effect.primitive = getPrimitive(state); + effect.scale = 1.0f; + effect.delayMs = 0; + + std::vector supported; + mVibrator->getSupportedPrimitives(&supported); + if (std::find(supported.begin(), supported.end(), effect.primitive) == supported.end()) { + return; + } + + auto cb = new HalCallback(); + std::vector effects; + effects.push_back(effect); + + for (auto _ : state) { + state.ResumeTiming(); + mVibrator->compose(effects, cb); + state.PauseTiming(); + mVibrator->off(); + } +}); + +BENCHMARK_MAIN(); -- GitLab From b759eca4356319b5040b9384a70d39cc7bf4d6ed Mon Sep 17 00:00:00 2001 From: Tomasz Wasilczyk Date: Thu, 6 Aug 2020 16:12:40 -0700 Subject: [PATCH 105/790] Implement waitFor (interface) to avoid polling interface state Bug: 159239960 Test: grep TCU for ifauto and l2rep Change-Id: Ia3831f7c1796cfdfeb20af4481b61736d828d69b --- .../include/libnetdevice/libnetdevice.h | 33 +++++- .../1.0/default/libnetdevice/libnetdevice.cpp | 107 ++++++++++++++++-- 2 files changed, 124 insertions(+), 16 deletions(-) diff --git a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/libnetdevice.h b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/libnetdevice.h index 9a26ff17be..70cb688933 100644 --- a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/libnetdevice.h +++ b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/libnetdevice.h @@ -20,6 +20,7 @@ #include #include +#include #include namespace android::netdevice { @@ -53,14 +54,34 @@ bool exists(std::string ifname); std::optional isUp(std::string ifname); /** - * Checks, if the network interface exists and is up. - * - * This is a convenience function to call both exists() and isUp(). + * Interface condition to wait for. + */ +enum class WaitCondition { + /** + * Interface is present (but not necessarily up). + */ + PRESENT, + + /** + * Interface is up. + */ + PRESENT_AND_UP, + + /** + * Interface is down or not present (disconnected) at all. + */ + DOWN_OR_GONE, +}; + +/** + * Listens for interface changes until anticipated condition takes place. * - * \param ifname Interface to check - * \return true if the interface is up, false otherwise + * \param ifnames List of interfaces to watch for. + * \param cnd Awaited condition. + * \param allOf true if all interfaces need to satisfy the condition, false if only one satistying + * interface should stop the wait. */ -bool existsAndIsUp(const std::string& ifname); +void waitFor(std::set ifnames, WaitCondition cnd, bool allOf = true); /** * Brings network interface up. diff --git a/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp b/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp index 9447c0c31f..b3cfbe2c58 100644 --- a/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp +++ b/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp @@ -27,6 +27,8 @@ #include #include +#include + namespace android::netdevice { void useSocketDomain(int domain) { @@ -37,16 +39,6 @@ bool exists(std::string ifname) { return nametoindex(ifname) != 0; } -std::optional isUp(std::string ifname) { - auto ifr = ifreqs::fromName(ifname); - if (!ifreqs::send(SIOCGIFFLAGS, ifr)) return std::nullopt; - return ifr.ifr_flags & IFF_UP; -} - -bool existsAndIsUp(const std::string& ifname) { - return exists(ifname) && isUp(ifname).value_or(false); -} - bool up(std::string ifname) { auto ifr = ifreqs::fromName(ifname); if (!ifreqs::send(SIOCGIFFLAGS, ifr)) return false; @@ -102,6 +94,101 @@ bool setHwAddr(const std::string& ifname, hwaddr_t hwaddr) { return ifreqs::send(SIOCSIFHWADDR, ifr); } +std::optional isUp(std::string ifname) { + auto ifr = ifreqs::fromName(ifname); + if (!ifreqs::send(SIOCGIFFLAGS, ifr)) return std::nullopt; + return ifr.ifr_flags & IFF_UP; +} + +struct WaitState { + bool present; + bool up; + + bool satisfied(WaitCondition cnd) const { + switch (cnd) { + case WaitCondition::PRESENT: + if (present) return true; + break; + case WaitCondition::PRESENT_AND_UP: + if (present && up) return true; + break; + case WaitCondition::DOWN_OR_GONE: + if (!present || !up) return true; + break; + } + return false; + } +}; + +static std::string toString(WaitCondition cnd) { + switch (cnd) { + case WaitCondition::PRESENT: + return "become present"; + case WaitCondition::PRESENT_AND_UP: + return "come up"; + case WaitCondition::DOWN_OR_GONE: + return "go down"; + } +} + +static std::string toString(const std::set& ifnames) { + std::stringstream ss; + std::copy(ifnames.begin(), ifnames.end(), std::ostream_iterator(ss, ",")); + auto str = ss.str(); + str.pop_back(); + return str; +} + +void waitFor(std::set ifnames, WaitCondition cnd, bool allOf) { + nl::Socket sock(NETLINK_ROUTE, 0, RTMGRP_LINK); + + using StatesMap = std::map; + StatesMap states = {}; + for (const auto ifname : ifnames) { + const auto present = exists(ifname); + const auto up = present && isUp(ifname).value_or(false); + states[ifname] = {present, up}; + } + + const auto mapConditionChecker = [cnd](const StatesMap::iterator::value_type& it) { + return it.second.satisfied(cnd); + }; + const auto isFullySatisfied = [&states, allOf, mapConditionChecker]() { + if (allOf) { + return std::all_of(states.begin(), states.end(), mapConditionChecker); + } else { + return std::any_of(states.begin(), states.end(), mapConditionChecker); + } + }; + + if (isFullySatisfied()) return; + + LOG(DEBUG) << "Waiting for " << (allOf ? "" : "any of ") << toString(ifnames) << " to " + << toString(cnd); + while (true) { + const auto msgBuf = sock.receive(); + CHECK(msgBuf.has_value()) << "Can't read Netlink socket"; + + for (const auto rawMsg : *msgBuf) { + const auto msg = nl::Message::parse(rawMsg, {RTM_NEWLINK, RTM_DELLINK}); + if (!msg.has_value()) continue; + + const auto ifname = msg->attributes.get(IFLA_IFNAME); + if (ifnames.count(ifname) == 0) continue; + + const bool present = (msg->header.nlmsg_type != RTM_DELLINK); + const bool up = present && (msg->data.ifi_flags & IFF_UP) != 0; + states[ifname] = {present, up}; + + if (isFullySatisfied()) { + LOG(DEBUG) << "Finished waiting for " << (allOf ? "" : "some of ") + << toString(ifnames) << " to " << toString(cnd); + return; + } + } + } +} + } // namespace android::netdevice bool operator==(const android::netdevice::hwaddr_t lhs, const unsigned char rhs[ETH_ALEN]) { -- GitLab From 2424b716b3462719627c80330891823a66cac334 Mon Sep 17 00:00:00 2001 From: Tomasz Wasilczyk Date: Fri, 7 Aug 2020 11:04:26 -0700 Subject: [PATCH 106/790] Implement socket receive iterator Bug: 162032964 Test: watch logcat for ifautocf and l2repeater Test: adb shell canhalctrl up test virtual vcan2 Change-Id: Icbae3951113391846cfcf9a6747ed565bdaa7dd7 --- .../1.0/default/libnetdevice/libnetdevice.cpp | 36 ++++----- automotive/can/1.0/default/libnl++/Socket.cpp | 80 +++++++++++++++---- .../default/libnl++/include/libnl++/Buffer.h | 6 +- .../default/libnl++/include/libnl++/Socket.h | 37 +++++++++ .../libnl++/protocols/NetlinkProtocol.cpp | 2 +- .../libnl++/protocols/NetlinkProtocol.h | 2 +- .../protocols/generic/GenericMessageBase.cpp | 2 +- .../protocols/generic/GenericMessageBase.h | 2 +- 8 files changed, 124 insertions(+), 43 deletions(-) diff --git a/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp b/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp index b3cfbe2c58..4c5b30928f 100644 --- a/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp +++ b/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp @@ -165,28 +165,24 @@ void waitFor(std::set ifnames, WaitCondition cnd, bool allOf) { LOG(DEBUG) << "Waiting for " << (allOf ? "" : "any of ") << toString(ifnames) << " to " << toString(cnd); - while (true) { - const auto msgBuf = sock.receive(); - CHECK(msgBuf.has_value()) << "Can't read Netlink socket"; - - for (const auto rawMsg : *msgBuf) { - const auto msg = nl::Message::parse(rawMsg, {RTM_NEWLINK, RTM_DELLINK}); - if (!msg.has_value()) continue; - - const auto ifname = msg->attributes.get(IFLA_IFNAME); - if (ifnames.count(ifname) == 0) continue; - - const bool present = (msg->header.nlmsg_type != RTM_DELLINK); - const bool up = present && (msg->data.ifi_flags & IFF_UP) != 0; - states[ifname] = {present, up}; - - if (isFullySatisfied()) { - LOG(DEBUG) << "Finished waiting for " << (allOf ? "" : "some of ") - << toString(ifnames) << " to " << toString(cnd); - return; - } + for (const auto rawMsg : sock) { + const auto msg = nl::Message::parse(rawMsg, {RTM_NEWLINK, RTM_DELLINK}); + if (!msg.has_value()) continue; + + const auto ifname = msg->attributes.get(IFLA_IFNAME); + if (ifnames.count(ifname) == 0) continue; + + const bool present = (msg->header.nlmsg_type != RTM_DELLINK); + const bool up = present && (msg->data.ifi_flags & IFF_UP) != 0; + states[ifname] = {present, up}; + + if (isFullySatisfied()) { + LOG(DEBUG) << "Finished waiting for " << (allOf ? "" : "some of ") << toString(ifnames) + << " to " << toString(cnd); + return; } } + LOG(FATAL) << "Can't read Netlink socket"; } } // namespace android::netdevice diff --git a/automotive/can/1.0/default/libnl++/Socket.cpp b/automotive/can/1.0/default/libnl++/Socket.cpp index 9e96ea9739..08683ca7bc 100644 --- a/automotive/can/1.0/default/libnl++/Socket.cpp +++ b/automotive/can/1.0/default/libnl++/Socket.cpp @@ -68,6 +68,16 @@ bool Socket::send(const Buffer& msg, const sockaddr_nl& sa) { return true; } +bool Socket::increaseReceiveBuffer(size_t maxSize) { + if (maxSize == 0) { + LOG(ERROR) << "Maximum receive size should not be zero"; + return false; + } + + if (mReceiveBuffer.size() < maxSize) mReceiveBuffer.resize(maxSize); + return true; +} + std::optional> Socket::receive(size_t maxSize) { return receiveFrom(maxSize).first; } @@ -75,11 +85,7 @@ std::optional> Socket::receive(size_t maxSize) { std::pair>, sockaddr_nl> Socket::receiveFrom(size_t maxSize) { if (mFailed) return {std::nullopt, {}}; - if (maxSize == 0) { - LOG(ERROR) << "Maximum receive size should not be zero"; - return {std::nullopt, {}}; - } - if (mReceiveBuffer.size() < maxSize) mReceiveBuffer.resize(maxSize); + if (!increaseReceiveBuffer(maxSize)) return {std::nullopt, {}}; sockaddr_nl sa = {}; socklen_t saLen = sizeof(sa); @@ -120,19 +126,16 @@ bool Socket::receiveAck(uint32_t seq) { std::optional> Socket::receive(const std::set& msgtypes, size_t maxSize) { - while (!mFailed) { - const auto msgBuf = receive(maxSize); - if (!msgBuf.has_value()) return std::nullopt; - - for (const auto rawMsg : *msgBuf) { - if (msgtypes.count(rawMsg->nlmsg_type) == 0) { - LOG(WARNING) << "Received (and ignored) unexpected Netlink message of type " - << rawMsg->nlmsg_type; - continue; - } - - return rawMsg; + if (mFailed || !increaseReceiveBuffer(maxSize)) return std::nullopt; + + for (const auto rawMsg : *this) { + if (msgtypes.count(rawMsg->nlmsg_type) == 0) { + LOG(WARNING) << "Received (and ignored) unexpected Netlink message of type " + << rawMsg->nlmsg_type; + continue; } + + return rawMsg; } return std::nullopt; @@ -150,4 +153,47 @@ std::optional Socket::getPid() { return sa.nl_pid; } +Socket::receive_iterator::receive_iterator(Socket& socket, bool end) + : mSocket(socket), mIsEnd(end) { + if (!end) receive(); +} + +Socket::receive_iterator Socket::receive_iterator::operator++() { + CHECK(!mIsEnd) << "Trying to increment end iterator"; + ++mCurrent; + if (mCurrent.isEnd()) receive(); + return *this; +} + +bool Socket::receive_iterator::operator==(const receive_iterator& other) const { + if (mIsEnd != other.mIsEnd) return false; + if (mIsEnd && other.mIsEnd) return true; + return mCurrent == other.mCurrent; +} + +const Buffer& Socket::receive_iterator::operator*() const { + CHECK(!mIsEnd) << "Trying to dereference end iterator"; + return *mCurrent; +} + +void Socket::receive_iterator::receive() { + CHECK(!mIsEnd) << "Trying to receive on end iterator"; + CHECK(mCurrent.isEnd()) << "Trying to receive without draining previous read"; + + const auto buf = mSocket.receive(); + if (buf.has_value()) { + mCurrent = buf->begin(); + } else { + mIsEnd = true; + } +} + +Socket::receive_iterator Socket::begin() { + return {*this, false}; +} + +Socket::receive_iterator Socket::end() { + return {*this, true}; +} + } // namespace android::nl diff --git a/automotive/can/1.0/default/libnl++/include/libnl++/Buffer.h b/automotive/can/1.0/default/libnl++/include/libnl++/Buffer.h index c3137c8994..bf83fbcc20 100644 --- a/automotive/can/1.0/default/libnl++/include/libnl++/Buffer.h +++ b/automotive/can/1.0/default/libnl++/include/libnl++/Buffer.h @@ -94,7 +94,7 @@ class Buffer { class iterator { public: iterator() : mCurrent(nullptr, size_t(0)) { - CHECK(!mCurrent.ok()) << "end() iterator should indicate it's beyond end"; + CHECK(isEnd()) << "end() iterator should indicate it's beyond end"; } iterator(const Buffer& buf) : mCurrent(buf) {} @@ -108,13 +108,15 @@ class Buffer { bool operator==(const iterator& other) const { // all iterators beyond end are the same - if (!mCurrent.ok() && !other.mCurrent.ok()) return true; + if (isEnd() && other.isEnd()) return true; return uintptr_t(other.mCurrent.mData) == uintptr_t(mCurrent.mData); } const Buffer& operator*() const { return mCurrent; } + bool isEnd() const { return !mCurrent.ok(); } + protected: Buffer mCurrent; }; diff --git a/automotive/can/1.0/default/libnl++/include/libnl++/Socket.h b/automotive/can/1.0/default/libnl++/include/libnl++/Socket.h index 6a4e82e25b..c69523da3d 100644 --- a/automotive/can/1.0/default/libnl++/include/libnl++/Socket.h +++ b/automotive/can/1.0/default/libnl++/include/libnl++/Socket.h @@ -173,6 +173,42 @@ class Socket { */ std::optional getPid(); + /** + * Live iterator continuously receiving messages from Netlink socket. + * + * Iteration ends when socket fails to receive a buffer. + * + * Example: + * ``` + * nl::Socket sock(NETLINK_ROUTE, 0, RTMGRP_LINK); + * for (const auto rawMsg : sock) { + * const auto msg = nl::Message::parse(rawMsg, {RTM_NEWLINK, RTM_DELLINK}); + * if (!msg.has_value()) continue; + * + * LOG(INFO) << msg->attributes.get(IFLA_IFNAME) + * << " is " << ((msg->data.ifi_flags & IFF_UP) ? "up" : "down"); + * } + * LOG(FATAL) << "Failed to read from Netlink socket"; + * ``` + */ + class receive_iterator { + public: + receive_iterator(Socket& socket, bool end); + + receive_iterator operator++(); + bool operator==(const receive_iterator& other) const; + const Buffer& operator*() const; + + private: + Socket& mSocket; + bool mIsEnd; + Buffer::iterator mCurrent; + + void receive(); + }; + receive_iterator begin(); + receive_iterator end(); + private: const int mProtocol; base::unique_fd mFd; @@ -181,6 +217,7 @@ class Socket { bool mFailed = false; uint32_t mSeq = 0; + bool increaseReceiveBuffer(size_t maxSize); std::optional> receive(const std::set& msgtypes, size_t maxSize); DISALLOW_COPY_AND_ASSIGN(Socket); diff --git a/automotive/can/1.0/default/libnl++/protocols/NetlinkProtocol.cpp b/automotive/can/1.0/default/libnl++/protocols/NetlinkProtocol.cpp index 159b6d643d..cd2e8c6860 100644 --- a/automotive/can/1.0/default/libnl++/protocols/NetlinkProtocol.cpp +++ b/automotive/can/1.0/default/libnl++/protocols/NetlinkProtocol.cpp @@ -18,7 +18,7 @@ namespace android::nl::protocols { -NetlinkProtocol::NetlinkProtocol(int protocol, const std::string name, +NetlinkProtocol::NetlinkProtocol(int protocol, const std::string& name, const MessageDescriptorList&& messageDescrs) : mProtocol(protocol), mName(name), mMessageDescrs(toMap(messageDescrs, protocol)) {} diff --git a/automotive/can/1.0/default/libnl++/protocols/NetlinkProtocol.h b/automotive/can/1.0/default/libnl++/protocols/NetlinkProtocol.h index 81a0a6589f..c969547393 100644 --- a/automotive/can/1.0/default/libnl++/protocols/NetlinkProtocol.h +++ b/automotive/can/1.0/default/libnl++/protocols/NetlinkProtocol.h @@ -46,7 +46,7 @@ class NetlinkProtocol { protected: typedef std::vector> MessageDescriptorList; - NetlinkProtocol(int protocol, const std::string name, + NetlinkProtocol(int protocol, const std::string& name, const MessageDescriptorList&& messageDescrs); private: diff --git a/automotive/can/1.0/default/libnl++/protocols/generic/GenericMessageBase.cpp b/automotive/can/1.0/default/libnl++/protocols/generic/GenericMessageBase.cpp index 5b6bd97789..134638e45b 100644 --- a/automotive/can/1.0/default/libnl++/protocols/generic/GenericMessageBase.cpp +++ b/automotive/can/1.0/default/libnl++/protocols/generic/GenericMessageBase.cpp @@ -19,7 +19,7 @@ namespace android::nl::protocols::generic { GenericMessageBase::GenericMessageBase( - nlmsgtype_t msgtype, std::string msgname, + nlmsgtype_t msgtype, const std::string&& msgname, const std::initializer_list commandNames, const std::initializer_list attrTypes) : MessageDefinition(msgname, {{msgtype, {msgname, MessageGenre::UNKNOWN}}}, diff --git a/automotive/can/1.0/default/libnl++/protocols/generic/GenericMessageBase.h b/automotive/can/1.0/default/libnl++/protocols/generic/GenericMessageBase.h index f0ee5b0978..443f10c60a 100644 --- a/automotive/can/1.0/default/libnl++/protocols/generic/GenericMessageBase.h +++ b/automotive/can/1.0/default/libnl++/protocols/generic/GenericMessageBase.h @@ -27,7 +27,7 @@ class GenericMessageBase : public MessageDefinition { typedef std::map GenericCommandNameMap; GenericMessageBase( - nlmsgtype_t msgtype, std::string msgname, + nlmsgtype_t msgtype, const std::string&& msgname, const std::initializer_list commandNames = {}, const std::initializer_list attrTypes = {}); -- GitLab From 3ea25a6445e34a2ab8510550a6e39c15e2f17be2 Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Tue, 4 Aug 2020 10:23:52 -0700 Subject: [PATCH 107/790] Add FrontendSettingsExt struct in Tuner 1.1 The new FrontendSettingsExt includes more options to configure the tune and scan action on the IFrontend interface. This new struct will be used as a parameter in the tune_1_1 and scan_1_1 APIs of the 1.1 IFrontend. Test: atest VtsHalTvTunerV1_1TargetTest Bug: 158818695 Change-Id: Ibe38a0be76969d23255574357d7494188182f467 --- tv/tuner/1.1/Android.bp | 1 + tv/tuner/1.1/IFrontend.hal | 70 ++++ tv/tuner/1.1/default/Frontend.cpp | 12 + tv/tuner/1.1/default/Frontend.h | 9 +- tv/tuner/1.1/types.hal | 94 ++++++ tv/tuner/1.1/vts/functional/FrontendTests.cpp | 307 +++++++++++++++++- tv/tuner/1.1/vts/functional/FrontendTests.h | 21 +- .../VtsHalTvTunerV1_1TargetTest.cpp | 19 +- .../functional/VtsHalTvTunerV1_1TargetTest.h | 28 ++ .../VtsHalTvTunerV1_1TestConfigurations.h | 34 ++ 10 files changed, 583 insertions(+), 12 deletions(-) create mode 100644 tv/tuner/1.1/IFrontend.hal diff --git a/tv/tuner/1.1/Android.bp b/tv/tuner/1.1/Android.bp index 032232da51..92769f04ff 100644 --- a/tv/tuner/1.1/Android.bp +++ b/tv/tuner/1.1/Android.bp @@ -6,6 +6,7 @@ hidl_interface { srcs: [ "IDemux.hal", "IFilter.hal", + "IFrontend.hal", "IFilterCallback.hal", "ITuner.hal", "types.hal", diff --git a/tv/tuner/1.1/IFrontend.hal b/tv/tuner/1.1/IFrontend.hal new file mode 100644 index 0000000000..b570549d86 --- /dev/null +++ b/tv/tuner/1.1/IFrontend.hal @@ -0,0 +1,70 @@ +/* + * 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. + */ + +package android.hardware.tv.tuner@1.1; + +import @1.0::FrontendScanType; +import @1.0::FrontendSettings; +import @1.0::IFrontend; +import @1.0::Result; + +/** + * A Tuner Frontend is used to tune to a frequency and lock signal. + * + * IFrontend provides a bit stream to the Tuner Demux interface. + */ +interface IFrontend extends @1.0::IFrontend { + /** + * Tunes the frontend to using the settings given. + * + * This locks the frontend to a frequency by providing signal + * delivery information. If previous tuning isn't completed, this call MUST + * stop previous tuning, and start a new tuning. + * Tune is an async call, with LOCKED or NO_SIGNAL events sent via callback. + * + * @param settings Signal delivery information the frontend uses to + * search and lock the signal. + * @param settingsExt Extended information that would be used in the 1.1 Frontend to + * search and lock the signal in a better way. + * + * @return result Result status of the operation. + * SUCCESS if successful, + * INVALID_STATE if tuning can't be applied at current stage, + * UNKNOWN_ERROR if tuning failed for other reasons. + */ + tune_1_1(FrontendSettings settings, FrontendSettingsExt settingsExt) generates (Result result); + + /** + * Scan the frontend to use the settings given. + * + * This uses the frontend to start a scan from signal delivery information. + * If previous scan isn't completed, this call MUST stop previous scan, + * and start a new scan. + * Scan is an async call, with FrontendScanMessage sent via callback. + * + * @param settings Signal delivery information which the frontend uses to + * scan the signal. + * @param type the type which the frontend uses to scan the signal. + * @param settingsExt Extended information that would be used in the 1.1 Frontend to + * search and lock the signal in a better way. + * @return result Result status of the operation. + * SUCCESS if successful, + * INVALID_STATE if tuning can't be applied at current stage, + * UNKNOWN_ERROR if tuning failed for other reasons. + */ + scan_1_1(FrontendSettings settings, FrontendScanType type, FrontendSettingsExt settingsExt) + generates (Result result); +}; diff --git a/tv/tuner/1.1/default/Frontend.cpp b/tv/tuner/1.1/default/Frontend.cpp index 6f5885fad7..fde26c16ad 100644 --- a/tv/tuner/1.1/default/Frontend.cpp +++ b/tv/tuner/1.1/default/Frontend.cpp @@ -71,6 +71,12 @@ Return Frontend::tune(const FrontendSettings& /* settings */) { return Result::SUCCESS; } +Return Frontend::tune_1_1(const FrontendSettings& settings, + const V1_1::FrontendSettingsExt& settingsExt) { + ALOGV("%s", __FUNCTION__); + return tune(settings); +} + Return Frontend::stopTune() { ALOGV("%s", __FUNCTION__); @@ -115,6 +121,12 @@ Return Frontend::scan(const FrontendSettings& settings, FrontendScanType return Result::SUCCESS; } +Return Frontend::scan_1_1(const FrontendSettings& settings, FrontendScanType type, + const V1_1::FrontendSettingsExt& /*settingsExt*/) { + ALOGV("%s", __FUNCTION__); + return scan(settings, type); +} + Return Frontend::stopScan() { ALOGV("%s", __FUNCTION__); diff --git a/tv/tuner/1.1/default/Frontend.h b/tv/tuner/1.1/default/Frontend.h index 89b4a6b5f3..d44f4aea7d 100644 --- a/tv/tuner/1.1/default/Frontend.h +++ b/tv/tuner/1.1/default/Frontend.h @@ -17,6 +17,7 @@ #ifndef ANDROID_HARDWARE_TV_TUNER_V1_1_FRONTEND_H_ #define ANDROID_HARDWARE_TV_TUNER_V1_1_FRONTEND_H_ +#include #include #include #include "Tuner.h" @@ -32,7 +33,7 @@ namespace implementation { class Tuner; -class Frontend : public IFrontend { +class Frontend : public V1_1::IFrontend { public: Frontend(FrontendType type, FrontendId id, sp tuner); @@ -42,10 +43,16 @@ class Frontend : public IFrontend { virtual Return tune(const FrontendSettings& settings) override; + virtual Return tune_1_1(const FrontendSettings& settings, + const V1_1::FrontendSettingsExt& settingsExt) override; + virtual Return stopTune() override; virtual Return scan(const FrontendSettings& settings, FrontendScanType type) override; + virtual Return scan_1_1(const FrontendSettings& settings, FrontendScanType type, + const V1_1::FrontendSettingsExt& settingsExt) override; + virtual Return stopScan() override; virtual Return getStatus(const hidl_vec& statusTypes, diff --git a/tv/tuner/1.1/types.hal b/tv/tuner/1.1/types.hal index bbfc39a010..9e2f453b70 100644 --- a/tv/tuner/1.1/types.hal +++ b/tv/tuner/1.1/types.hal @@ -19,6 +19,8 @@ package android.hardware.tv.tuner@1.1; import @1.0::Constant; import @1.0::DemuxFilterMmtpRecordEvent; import @1.0::DemuxFilterTsRecordEvent; +import @1.0::FrontendDvbcSpectralInversion; +import @1.0::FrontendDvbtTransmissionMode; import android.hidl.safe_union@1.0; import android.hidl.safe_union@1.0::Monostate; @@ -28,6 +30,10 @@ enum Constant : @1.0::Constant { * An invalid mpuSequenceNumber in DemuxFilterMmtpRecordEvent. */ INVALID_MMTP_RECORD_EVENT_MPT_SEQUENCE_NUM = 0xFFFFFFFF, + /** + * An invalid frenquency that can be used as the default value of the frontend setting. + */ + INVALID_FRONTEND_SETTING_FREQUENCY = 0xFFFFFFFF, }; @export @@ -84,3 +90,91 @@ struct DemuxFilterEventExt { */ vec events; }; + +typedef FrontendDvbcSpectralInversion FrontendSpectralInversion; + +/** + * Scan type for a DVBS Frontend. + */ +@export +enum FrontendDvbsScanType : uint32_t { + UNDEFINED = 0, + DIRECT, + DISEQC, + UNICABLE, + JESS, +}; + +/** + * Rotation status for a DVBT Frontend. + */ +@export +enum FrontendDvbtRotation : uint32_t { + UNDEFINED, + NOT_ROTATED, + ROTATED, +}; + +/** + * AFT flag for an Analog Frontend. + */ +@export +enum FrontendAnalogAftFlag : uint32_t { + UNDEFINED, + AFT_TRUE, + AFT_FALSE, +}; + +/** + * Extended Transmission Mode for DVBT. + */ +@export +enum FrontendDvbtTransmissionMode : @1.0::FrontendDvbtTransmissionMode { + MODE_8K_E = 1 << 7, + + MODE_16K_E = 1 << 8, + + MODE_32K_E = 1 << 9, +}; + +/** + * Extended Signal Settings for a DVBS Frontend. + */ +struct FrontendDvbsSettingsExt { + FrontendDvbsScanType scanType; +}; + +/** + * Extended Signal Settings for a DVBT Frontend. + */ +struct FrontendDvbtSettingsExt { + FrontendDvbtRotation rotation; + + FrontendDvbtTransmissionMode transmissionMode; +}; + +/** + * Extended Signal Settings for an Analog Frontend. + */ +struct FrontendAnalogSettingsExt { + FrontendAnalogAftFlag aftFlag; +}; + +/** + * Extended Signal Settings for Frontend. + */ +struct FrontendSettingsExt { + uint32_t endFrequency; + + FrontendSpectralInversion inversion; + + safe_union SettingsExt { + Monostate noinit; + + FrontendAnalogSettingsExt analog; + + FrontendDvbsSettingsExt dvbs; + + FrontendDvbtSettingsExt dvbt; + } settingExt; +}; diff --git a/tv/tuner/1.1/vts/functional/FrontendTests.cpp b/tv/tuner/1.1/vts/functional/FrontendTests.cpp index da46adbee7..5e2b2886ce 100644 --- a/tv/tuner/1.1/vts/functional/FrontendTests.cpp +++ b/tv/tuner/1.1/vts/functional/FrontendTests.cpp @@ -32,13 +32,31 @@ Return FrontendCallback::onEvent(FrontendEventType frontendEventType) { } } -Return FrontendCallback::onScanMessage(FrontendScanMessageType /*type*/, - const FrontendScanMessage& /*message*/) { +Return FrontendCallback::onScanMessage(FrontendScanMessageType type, + const FrontendScanMessage& message) { + android::Mutex::Autolock autoLock(mMsgLock); + while (!mScanMsgProcessed) { + mMsgCondition.wait(mMsgLock); + } + ALOGD("[vts] frontend scan message. Type: %d", type); + mScanMessageReceived = true; + mScanMsgProcessed = false; + mScanMessageType = type; + mScanMessage = message; + mMsgCondition.signal(); return Void(); } -void FrontendCallback::tuneTestOnLock(sp& frontend, FrontendSettings settings) { - Result result = frontend->tune(settings); +void FrontendCallback::tuneTestOnLock(sp& frontend, FrontendSettings settings, + FrontendSettingsExt settingsExt) { + sp frontend_1_1; + frontend_1_1 = android::hardware::tv::tuner::V1_1::IFrontend::castFrom(frontend); + if (frontend_1_1 == nullptr) { + EXPECT_TRUE(false) << "Couldn't get 1.1 IFrontend from the Hal implementation."; + return; + } + + Result result = frontend_1_1->tune_1_1(settings, settingsExt); EXPECT_TRUE(result == Result::SUCCESS); android::Mutex::Autolock autoLock(mMsgLock); @@ -52,6 +70,130 @@ void FrontendCallback::tuneTestOnLock(sp& frontend, FrontendSettings mLockMsgReceived = false; } +void FrontendCallback::scanTest(sp& frontend, FrontendConfig config, + FrontendScanType type) { + sp frontend_1_1; + frontend_1_1 = android::hardware::tv::tuner::V1_1::IFrontend::castFrom(frontend); + if (frontend_1_1 == nullptr) { + EXPECT_TRUE(false) << "Couldn't get 1.1 IFrontend from the Hal implementation."; + return; + } + + uint32_t targetFrequency = getTargetFrequency(config.settings, config.type); + if (type == FrontendScanType::SCAN_BLIND) { + // reset the frequency in the scan configuration to test blind scan. The settings param of + // passed in means the real input config on the transponder connected to the DUT. + // We want the blind the test to start from lower frequency than this to check the blind + // scan implementation. + resetBlindScanStartingFrequency(config, targetFrequency - 100); + } + + Result result = frontend_1_1->scan_1_1(config.settings, type, config.settingsExt); + EXPECT_TRUE(result == Result::SUCCESS); + + bool scanMsgLockedReceived = false; + bool targetFrequencyReceived = false; + + android::Mutex::Autolock autoLock(mMsgLock); +wait: + while (!mScanMessageReceived) { + if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) { + EXPECT_TRUE(false) << "Scan message not received within timeout"; + mScanMessageReceived = false; + mScanMsgProcessed = true; + return; + } + } + + if (mScanMessageType != FrontendScanMessageType::END) { + if (mScanMessageType == FrontendScanMessageType::LOCKED) { + scanMsgLockedReceived = true; + Result result = frontend_1_1->scan_1_1(config.settings, type, config.settingsExt); + EXPECT_TRUE(result == Result::SUCCESS); + } + + if (mScanMessageType == FrontendScanMessageType::FREQUENCY) { + targetFrequencyReceived = mScanMessage.frequencies().size() > 0 && + mScanMessage.frequencies()[0] == targetFrequency; + } + + if (mScanMessageType == FrontendScanMessageType::PROGRESS_PERCENT) { + ALOGD("[vts] Scan in progress...[%d%%]", mScanMessage.progressPercent()); + } + + mScanMessageReceived = false; + mScanMsgProcessed = true; + mMsgCondition.signal(); + goto wait; + } + + EXPECT_TRUE(scanMsgLockedReceived) << "Scan message LOCKED not received before END"; + EXPECT_TRUE(targetFrequencyReceived) << "frequency not received before LOCKED on blindScan"; + mScanMessageReceived = false; + mScanMsgProcessed = true; +} + +uint32_t FrontendCallback::getTargetFrequency(FrontendSettings settings, FrontendType type) { + switch (type) { + case FrontendType::ANALOG: + return settings.analog().frequency; + case FrontendType::ATSC: + return settings.atsc().frequency; + case FrontendType::ATSC3: + return settings.atsc3().frequency; + case FrontendType::DVBC: + return settings.dvbc().frequency; + case FrontendType::DVBS: + return settings.dvbs().frequency; + case FrontendType::DVBT: + return settings.dvbt().frequency; + case FrontendType::ISDBS: + return settings.isdbs().frequency; + case FrontendType::ISDBS3: + return settings.isdbs3().frequency; + case FrontendType::ISDBT: + return settings.isdbt().frequency; + default: + return 0; + } +} + +void FrontendCallback::resetBlindScanStartingFrequency(FrontendConfig& config, + uint32_t resetingFreq) { + switch (config.type) { + case FrontendType::ANALOG: + config.settings.analog().frequency = resetingFreq; + break; + case FrontendType::ATSC: + config.settings.atsc().frequency = resetingFreq; + break; + case FrontendType::ATSC3: + config.settings.atsc3().frequency = resetingFreq; + break; + case FrontendType::DVBC: + config.settings.dvbc().frequency = resetingFreq; + break; + case FrontendType::DVBS: + config.settings.dvbs().frequency = resetingFreq; + break; + case FrontendType::DVBT: + config.settings.dvbt().frequency = resetingFreq; + break; + case FrontendType::ISDBS: + config.settings.isdbs().frequency = resetingFreq; + break; + case FrontendType::ISDBS3: + config.settings.isdbs3().frequency = resetingFreq; + break; + case FrontendType::ISDBT: + config.settings.isdbt().frequency = resetingFreq; + break; + default: + // do nothing + return; + } +} + AssertionResult FrontendTests::getFrontendIds() { Result status; mService->getFrontendIds([&](Result result, const hidl_vec& frontendIds) { @@ -86,6 +228,138 @@ AssertionResult FrontendTests::setFrontendCallback() { return AssertionResult(callbackStatus.isOk()); } +AssertionResult FrontendTests::scanFrontend(FrontendConfig config, FrontendScanType type) { + EXPECT_TRUE(mFrontendCallback) + << "test with openFrontendById/setFrontendCallback/getFrontendInfo first."; + + EXPECT_TRUE(mFrontendInfo.type == config.type) + << "FrontendConfig does not match the frontend info of the given id."; + + mFrontendCallback->scanTest(mFrontend, config, type); + return AssertionResult(true); +} + +AssertionResult FrontendTests::stopScanFrontend() { + EXPECT_TRUE(mFrontend) << "Test with openFrontendById first."; + Result status; + status = mFrontend->stopScan(); + return AssertionResult(status == Result::SUCCESS); +} + +void FrontendTests::verifyFrontendStatus(vector statusTypes, + vector expectStatuses) { + ASSERT_TRUE(mFrontend) << "Frontend is not opened yet."; + Result status; + vector realStatuses; + + mFrontend->getStatus(statusTypes, [&](Result result, const hidl_vec& statuses) { + status = result; + realStatuses = statuses; + }); + + ASSERT_TRUE(realStatuses.size() == statusTypes.size()); + for (int i = 0; i < statusTypes.size(); i++) { + FrontendStatusType type = statusTypes[i]; + switch (type) { + case FrontendStatusType::DEMOD_LOCK: { + ASSERT_TRUE(realStatuses[i].isDemodLocked() == expectStatuses[i].isDemodLocked()); + break; + } + case FrontendStatusType::SNR: { + ASSERT_TRUE(realStatuses[i].snr() == expectStatuses[i].snr()); + break; + } + case FrontendStatusType::BER: { + ASSERT_TRUE(realStatuses[i].ber() == expectStatuses[i].ber()); + break; + } + case FrontendStatusType::PER: { + ASSERT_TRUE(realStatuses[i].per() == expectStatuses[i].per()); + break; + } + case FrontendStatusType::PRE_BER: { + ASSERT_TRUE(realStatuses[i].preBer() == expectStatuses[i].preBer()); + break; + } + case FrontendStatusType::SIGNAL_QUALITY: { + ASSERT_TRUE(realStatuses[i].signalQuality() == expectStatuses[i].signalQuality()); + break; + } + case FrontendStatusType::SIGNAL_STRENGTH: { + ASSERT_TRUE(realStatuses[i].signalStrength() == expectStatuses[i].signalStrength()); + break; + } + case FrontendStatusType::SYMBOL_RATE: { + ASSERT_TRUE(realStatuses[i].symbolRate() == expectStatuses[i].symbolRate()); + break; + } + case FrontendStatusType::FEC: { + ASSERT_TRUE(realStatuses[i].innerFec() == expectStatuses[i].innerFec()); + break; + } + case FrontendStatusType::MODULATION: { + // TODO: check modulation status + break; + } + case FrontendStatusType::SPECTRAL: { + ASSERT_TRUE(realStatuses[i].inversion() == expectStatuses[i].inversion()); + break; + } + case FrontendStatusType::LNB_VOLTAGE: { + ASSERT_TRUE(realStatuses[i].lnbVoltage() == expectStatuses[i].lnbVoltage()); + break; + } + case FrontendStatusType::PLP_ID: { + ASSERT_TRUE(realStatuses[i].plpId() == expectStatuses[i].plpId()); + break; + } + case FrontendStatusType::EWBS: { + ASSERT_TRUE(realStatuses[i].isEWBS() == expectStatuses[i].isEWBS()); + break; + } + case FrontendStatusType::AGC: { + ASSERT_TRUE(realStatuses[i].agc() == expectStatuses[i].agc()); + break; + } + case FrontendStatusType::LNA: { + ASSERT_TRUE(realStatuses[i].isLnaOn() == expectStatuses[i].isLnaOn()); + break; + } + case FrontendStatusType::LAYER_ERROR: { + vector realLayberError = realStatuses[i].isLayerError(); + vector expectLayerError = expectStatuses[i].isLayerError(); + ASSERT_TRUE(realLayberError.size() == expectLayerError.size()); + for (int i = 0; i < realLayberError.size(); i++) { + ASSERT_TRUE(realLayberError[i] == expectLayerError[i]); + } + break; + } + case FrontendStatusType::MER: { + ASSERT_TRUE(realStatuses[i].mer() == expectStatuses[i].mer()); + break; + } + case FrontendStatusType::FREQ_OFFSET: { + ASSERT_TRUE(realStatuses[i].freqOffset() == expectStatuses[i].freqOffset()); + break; + } + case FrontendStatusType::HIERARCHY: { + ASSERT_TRUE(realStatuses[i].hierarchy() == expectStatuses[i].hierarchy()); + break; + } + case FrontendStatusType::RF_LOCK: { + ASSERT_TRUE(realStatuses[i].isRfLocked() == expectStatuses[i].isRfLocked()); + break; + } + case FrontendStatusType::ATSC3_PLP_INFO: + // TODO: verify plpinfo + break; + default: + continue; + } + } + ASSERT_TRUE(status == Result::SUCCESS); +} + AssertionResult FrontendTests::tuneFrontend(FrontendConfig config, bool testWithDemux) { EXPECT_TRUE(mFrontendCallback) << "test with openFrontendById/setFrontendCallback/getFrontendInfo first."; @@ -106,7 +380,7 @@ AssertionResult FrontendTests::tuneFrontend(FrontendConfig config, bool testWith return failure(); } } - mFrontendCallback->tuneTestOnLock(mFrontend, config.settings); + mFrontendCallback->tuneTestOnLock(mFrontend, config.settings, config.settingsExt); return AssertionResult(true); } @@ -143,3 +417,26 @@ void FrontendTests::getFrontendIdByType(FrontendType feType, uint32_t& feId) { } feId = INVALID_ID; } + +void FrontendTests::tuneTest(FrontendConfig frontendConf) { + uint32_t feId; + getFrontendIdByType(frontendConf.type, feId); + ASSERT_TRUE(feId != INVALID_ID); + ASSERT_TRUE(openFrontendById(feId)); + ASSERT_TRUE(setFrontendCallback()); + ASSERT_TRUE(tuneFrontend(frontendConf, false /*testWithDemux*/)); + verifyFrontendStatus(frontendConf.tuneStatusTypes, frontendConf.expectTuneStatuses); + ASSERT_TRUE(stopTuneFrontend(false /*testWithDemux*/)); + ASSERT_TRUE(closeFrontend()); +} + +void FrontendTests::scanTest(FrontendConfig frontendConf, FrontendScanType scanType) { + uint32_t feId; + getFrontendIdByType(frontendConf.type, feId); + ASSERT_TRUE(feId != INVALID_ID); + ASSERT_TRUE(openFrontendById(feId)); + ASSERT_TRUE(setFrontendCallback()); + ASSERT_TRUE(scanFrontend(frontendConf, scanType)); + ASSERT_TRUE(stopScanFrontend()); + ASSERT_TRUE(closeFrontend()); +} diff --git a/tv/tuner/1.1/vts/functional/FrontendTests.h b/tv/tuner/1.1/vts/functional/FrontendTests.h index 492f2f00c5..8986d8177a 100644 --- a/tv/tuner/1.1/vts/functional/FrontendTests.h +++ b/tv/tuner/1.1/vts/functional/FrontendTests.h @@ -15,9 +15,9 @@ */ #include -#include #include #include +#include #include #include #include @@ -52,6 +52,7 @@ using android::hardware::tv::tuner::V1_0::FrontendId; using android::hardware::tv::tuner::V1_0::FrontendInfo; using android::hardware::tv::tuner::V1_0::FrontendScanMessage; using android::hardware::tv::tuner::V1_0::FrontendScanMessageType; +using android::hardware::tv::tuner::V1_0::FrontendScanType; using android::hardware::tv::tuner::V1_0::IFrontend; using android::hardware::tv::tuner::V1_0::IFrontendCallback; using android::hardware::tv::tuner::V1_0::Result; @@ -70,11 +71,21 @@ class FrontendCallback : public IFrontendCallback { virtual Return onScanMessage(FrontendScanMessageType type, const FrontendScanMessage& message) override; - void tuneTestOnLock(sp& frontend, FrontendSettings settings); + void tuneTestOnLock(sp& frontend, FrontendSettings settings, + FrontendSettingsExt settingsExt); + void scanTest(sp& frontend, FrontendConfig config, FrontendScanType type); + + // Helper methods + uint32_t getTargetFrequency(FrontendSettings settings, FrontendType type); + void resetBlindScanStartingFrequency(FrontendConfig& config, uint32_t resetingFreq); private: bool mEventReceived = false; + bool mScanMessageReceived = false; bool mLockMsgReceived = false; + bool mScanMsgProcessed = true; + FrontendScanMessageType mScanMessageType; + FrontendScanMessage mScanMessage; hidl_vec mEventMessage; android::Mutex mMsgLock; android::Condition mMsgCondition; @@ -95,11 +106,17 @@ class FrontendTests { AssertionResult getFrontendInfo(uint32_t frontendId); AssertionResult openFrontendById(uint32_t frontendId); AssertionResult setFrontendCallback(); + AssertionResult scanFrontend(FrontendConfig config, FrontendScanType type); + AssertionResult stopScanFrontend(); AssertionResult tuneFrontend(FrontendConfig config, bool testWithDemux); + void verifyFrontendStatus(vector statusTypes, + vector expectStatuses); AssertionResult stopTuneFrontend(bool testWithDemux); AssertionResult closeFrontend(); void getFrontendIdByType(FrontendType feType, uint32_t& feId); + void tuneTest(FrontendConfig frontendConf); + void scanTest(FrontendConfig frontend, FrontendScanType type); void setDvrTests(DvrTests dvrTests) { mDvrTests = dvrTests; } void setDemux(sp demux) { mDvrTests.setDemux(demux); } diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp index c9873b2c90..c3df078c1c 100644 --- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp @@ -132,6 +132,21 @@ TEST_P(TunerRecordHidlTest, RecordDataFlowWithTsRecordFilterTest) { recordSingleFilterTest(filterArray[TS_RECORD0], frontendArray[DVBT], dvrArray[DVR_RECORD0]); } +TEST_P(TunerFrontendHidlTest, TuneFrontendWithFrontendSettingsExt) { + description("Tune one Frontend with specific setting and check Lock event"); + mFrontendTests.tuneTest(frontendArray[DVBT]); +} + +TEST_P(TunerFrontendHidlTest, BlindScanFrontendWithEndFrequency) { + description("Run an blind frontend scan with specific setting and check lock scanMessage"); + mFrontendTests.scanTest(frontendScanArray[SCAN_DVBT], FrontendScanType::SCAN_BLIND); +} + +INSTANTIATE_TEST_SUITE_P( + PerInstance, TunerFrontendHidlTest, + testing::ValuesIn(android::hardware::getAllHalInstanceNames(ITuner::descriptor)), + android::hardware::PrintInstanceNameToString); + INSTANTIATE_TEST_SUITE_P( PerInstance, TunerFilterHidlTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames(ITuner::descriptor)), @@ -146,8 +161,4 @@ INSTANTIATE_TEST_SUITE_P( PerInstance, TunerRecordHidlTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames(ITuner::descriptor)), android::hardware::PrintInstanceNameToString); - -GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerFilterHidlTest); -GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerDemuxHidlTest); -GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerRecordHidlTest); } // namespace diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h index 1b28853a4b..505e35a536 100644 --- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h @@ -21,6 +21,7 @@ namespace { void initConfiguration() { initFrontendConfig(); + initFrontendScanConfig(); initFilterConfig(); initDvrConfig(); } @@ -50,6 +51,8 @@ class TunerFilterHidlTest : public testing::TestWithParam { FilterTests mFilterTests; }; +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerFilterHidlTest); + class TunerDemuxHidlTest : public testing::TestWithParam { public: virtual void SetUp() override { @@ -73,6 +76,8 @@ class TunerDemuxHidlTest : public testing::TestWithParam { FilterTests mFilterTests; }; +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerDemuxHidlTest); + class TunerRecordHidlTest : public testing::TestWithParam { public: virtual void SetUp() override { @@ -100,4 +105,27 @@ class TunerRecordHidlTest : public testing::TestWithParam { FilterTests mFilterTests; DvrTests mDvrTests; }; + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerRecordHidlTest); + +class TunerFrontendHidlTest : public testing::TestWithParam { + public: + virtual void SetUp() override { + mService = ITuner::getService(GetParam()); + ASSERT_NE(mService, nullptr); + initConfiguration(); + + mFrontendTests.setService(mService); + } + + protected: + static void description(const std::string& description) { + RecordProperty("description", description); + } + + sp mService; + FrontendTests mFrontendTests; +}; + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerFrontendHidlTest); } // namespace \ No newline at end of file diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h index 39872d2524..34418d146b 100644 --- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h @@ -46,6 +46,7 @@ using android::hardware::tv::tuner::V1_0::FrontendStatusType; using android::hardware::tv::tuner::V1_0::FrontendType; using android::hardware::tv::tuner::V1_0::PlaybackSettings; using android::hardware::tv::tuner::V1_0::RecordSettings; +using android::hardware::tv::tuner::V1_1::FrontendSettingsExt; using namespace std; @@ -72,6 +73,11 @@ typedef enum { FRONTEND_MAX, } Frontend; +typedef enum { + SCAN_DVBT, + SCAN_MAX, +} FrontendScan; + typedef enum { DVR_RECORD0, DVR_PLAYBACK0, @@ -90,6 +96,7 @@ struct FrontendConfig { bool isSoftwareFe; FrontendType type; FrontendSettings settings; + FrontendSettingsExt settingsExt; vector tuneStatusTypes; vector expectTuneStatuses; }; @@ -102,6 +109,7 @@ struct DvrConfig { }; static FrontendConfig frontendArray[FILTER_MAX]; +static FrontendConfig frontendScanArray[SCAN_MAX]; static FilterConfig filterArray[FILTER_MAX]; static DvrConfig dvrArray[DVR_MAX]; @@ -129,10 +137,36 @@ inline void initFrontendConfig() { frontendArray[DVBT].tuneStatusTypes = types; frontendArray[DVBT].expectTuneStatuses = statuses; frontendArray[DVBT].isSoftwareFe = true; + frontendArray[DVBT].settingsExt.settingExt.dvbt({ + .transmissionMode = + android::hardware::tv::tuner::V1_1::FrontendDvbtTransmissionMode::MODE_8K_E, + }); frontendArray[DVBS].type = FrontendType::DVBS; frontendArray[DVBS].isSoftwareFe = true; }; +/** Configuration array for the frontend scan test */ +inline void initFrontendScanConfig() { + frontendScanArray[SCAN_DVBT].type = FrontendType::DVBT; + frontendScanArray[SCAN_DVBT].settings.dvbt({ + .frequency = 578000, + .transmissionMode = FrontendDvbtTransmissionMode::MODE_8K, + .bandwidth = FrontendDvbtBandwidth::BANDWIDTH_8MHZ, + .constellation = FrontendDvbtConstellation::AUTO, + .hierarchy = FrontendDvbtHierarchy::AUTO, + .hpCoderate = FrontendDvbtCoderate::AUTO, + .lpCoderate = FrontendDvbtCoderate::AUTO, + .guardInterval = FrontendDvbtGuardInterval::AUTO, + .isHighPriority = true, + .standard = FrontendDvbtStandard::T, + }); + frontendScanArray[SCAN_DVBT].settingsExt.endFrequency = 800000; + frontendScanArray[SCAN_DVBT].settingsExt.settingExt.dvbt({ + .transmissionMode = + android::hardware::tv::tuner::V1_1::FrontendDvbtTransmissionMode::MODE_8K_E, + }); +}; + /** Configuration array for the filter test */ inline void initFilterConfig() { // TS VIDEO filter setting for default implementation testing -- GitLab From 7a82ad8c6acffb91750bea53c46a41f82c740950 Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Fri, 29 Nov 2019 17:31:22 +0200 Subject: [PATCH 108/790] Wifi: fix bug during WIFI HAL stop In WifiChip::invalidateAndRemoveDependencies, the iterator was not implemented correctly as it was deleting objects while iterating. This could cause the entire WIFI HAL to be restarted when disabling WIFI. Bug: 146922967 Test: atest VtsHalWifiV1_0TargetTest VtsHalWifiNanV1_0TargetTest VtsHalWifiApV1_0TargetTest \ VtsHalWifiV1_1TargetTest \ VtsHalWifiV1_2TargetTest VtsHalWifiNanV1_2TargetTest \ VtsHalWifiV1_3TargetTest \ VtsHalWifiApV1_4TargetTest VtsHalWifiNanV1_4TargetTest VtsHalWifiRttV1_4TargetTest Change-Id: Id86f1a662684467d3b86a79b271144ac3055d0a0 --- wifi/1.5/default/wifi_chip.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/wifi/1.5/default/wifi_chip.cpp b/wifi/1.5/default/wifi_chip.cpp index 069fd65054..b898f686eb 100644 --- a/wifi/1.5/default/wifi_chip.cpp +++ b/wifi/1.5/default/wifi_chip.cpp @@ -681,9 +681,10 @@ void WifiChip::invalidateAndRemoveAllIfaces() { void WifiChip::invalidateAndRemoveDependencies( const std::string& removed_iface_name) { - for (const auto& nan_iface : nan_ifaces_) { + for (auto it = nan_ifaces_.begin(); it != nan_ifaces_.end();) { + auto nan_iface = *it; if (nan_iface->getName() == removed_iface_name) { - invalidateAndClear(nan_ifaces_, nan_iface); + nan_iface->invalidate(); for (const auto& callback : event_cb_handler_.getCallbacks()) { if (!callback ->onIfaceRemoved(IfaceType::NAN, removed_iface_name) @@ -691,11 +692,19 @@ void WifiChip::invalidateAndRemoveDependencies( LOG(ERROR) << "Failed to invoke onIfaceRemoved callback"; } } + it = nan_ifaces_.erase(it); + } else { + ++it; } } - for (const auto& rtt : rtt_controllers_) { + + for (auto it = rtt_controllers_.begin(); it != rtt_controllers_.end();) { + auto rtt = *it; if (rtt->getIfaceName() == removed_iface_name) { - invalidateAndClear(rtt_controllers_, rtt); + rtt->invalidate(); + it = rtt_controllers_.erase(it); + } else { + ++it; } } } -- GitLab From 2dddd79e1645ea7d2ec41991bd00d6bfe4170ec7 Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Mon, 23 Dec 2019 17:50:39 +0200 Subject: [PATCH 109/790] Wifi: support multiple WIFI chips The WIFI HAL API has support for multiple WIFI chips (IWifiChip instances) however the implementation is hard-coded to support only a single WIFI chip. This change reworks the implementation so multiple WIFI chips will be supported. Support for multiple chips is based on the concept that each chip is represented by its own vendor HAL library. The implementation will look for descriptor files for vendor HAL libraries under /vendor/etc/wifi/vendor_hals. It will parse descriptors, dynamically load vendor HAL libraries and create WifiLegacyHal and WifiChip objects for each loaded vendor HAL library. One of the descriptors should be marked with "primary" flag. The implementation will create the first WifiChip object for this library. Typically it is the one providing the best WIFI functionality, which was previously used as the only WIFI chip. Additional support is added inside WifiChip and WifiLegacyHal for getting available chip modes and concurrency combinations from the vendor HAL if available, and allowing the chip to override network interface name when creating interfaces. The mechanism for getting chip capabilities is improved to allow getting chip-global capabilities, which are independent of any created interfaces. For example, if the framework needs to start a SoftAP on the 60GHz band, it needs to find a chip which supports this band, but before creating any interface on the chip. The new mechanism allows this. Bug: 146922967 Test: atest VtsHalWifiV1_0TargetTest VtsHalWifiNanV1_0TargetTest VtsHalWifiApV1_0TargetTest \ VtsHalWifiV1_1TargetTest \ VtsHalWifiV1_2TargetTest VtsHalWifiNanV1_2TargetTest \ VtsHalWifiV1_3TargetTest \ VtsHalWifiApV1_4TargetTest VtsHalWifiNanV1_4TargetTest VtsHalWifiRttV1_4TargetTest Change-Id: Ibdff93ea56aff186d4b5361ac77f6f448a0dfd45 --- .../vts/functional/wifi_hidl_test_utils.cpp | 2 +- wifi/1.5/default/Android.mk | 5 + wifi/1.5/default/service.cpp | 8 +- .../default/tests/mock_wifi_feature_flags.h | 3 +- .../default/tests/mock_wifi_legacy_hal.cpp | 5 +- wifi/1.5/default/tests/mock_wifi_legacy_hal.h | 3 +- .../default/tests/wifi_chip_unit_tests.cpp | 20 +- .../tests/wifi_nan_iface_unit_tests.cpp | 4 +- wifi/1.5/default/wifi.cpp | 110 ++++++-- wifi/1.5/default/wifi.h | 10 +- wifi/1.5/default/wifi_chip.cpp | 28 +- wifi/1.5/default/wifi_chip.h | 5 +- wifi/1.5/default/wifi_feature_flags.cpp | 12 +- wifi/1.5/default/wifi_feature_flags.h | 3 +- wifi/1.5/default/wifi_legacy_hal.cpp | 85 ++++-- wifi/1.5/default/wifi_legacy_hal.h | 9 +- wifi/1.5/default/wifi_legacy_hal_factory.cpp | 263 ++++++++++++++++++ wifi/1.5/default/wifi_legacy_hal_factory.h | 67 +++++ wifi/1.5/default/wifi_legacy_hal_stubs.cpp | 4 + 19 files changed, 554 insertions(+), 92 deletions(-) create mode 100644 wifi/1.5/default/wifi_legacy_hal_factory.cpp create mode 100644 wifi/1.5/default/wifi_legacy_hal_factory.h diff --git a/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp b/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp index 5b11dd3fc4..092822f932 100644 --- a/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp +++ b/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp @@ -112,7 +112,7 @@ sp getWifiChip(const std::string& instance_name) { const auto& status_and_chip_ids = HIDL_INVOKE(wifi, getChipIds); const auto& chip_ids = status_and_chip_ids.second; if (status_and_chip_ids.first.code != WifiStatusCode::SUCCESS || - chip_ids.size() != 1) { + chip_ids.size() < 1) { return nullptr; } const auto& status_and_chip = HIDL_INVOKE(wifi, getChip, chip_ids[0]); diff --git a/wifi/1.5/default/Android.mk b/wifi/1.5/default/Android.mk index 236dae23e0..dc9e89b2b6 100644 --- a/wifi/1.5/default/Android.mk +++ b/wifi/1.5/default/Android.mk @@ -51,6 +51,7 @@ LOCAL_SRC_FILES := \ 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 \ @@ -67,12 +68,14 @@ LOCAL_SHARED_LIBRARIES := \ libutils \ libwifi-hal \ libwifi-system-iface \ + libxml2 \ 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 +LOCAL_C_INCLUDES += $(TOP)/external/libxml2/include LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH) include $(BUILD_STATIC_LIBRARY) @@ -96,6 +99,7 @@ LOCAL_SHARED_LIBRARIES := \ libutils \ libwifi-hal \ libwifi-system-iface \ + libxml2 \ android.hardware.wifi@1.0 \ android.hardware.wifi@1.1 \ android.hardware.wifi@1.2 \ @@ -129,6 +133,7 @@ LOCAL_SHARED_LIBRARIES := \ libutils \ libwifi-hal \ libwifi-system-iface \ + libxml2 \ android.hardware.wifi@1.0 \ android.hardware.wifi@1.1 \ android.hardware.wifi@1.2 \ diff --git a/wifi/1.5/default/service.cpp b/wifi/1.5/default/service.cpp index f53d528136..8539a37647 100644 --- a/wifi/1.5/default/service.cpp +++ b/wifi/1.5/default/service.cpp @@ -23,6 +23,7 @@ #include "wifi.h" #include "wifi_feature_flags.h" #include "wifi_legacy_hal.h" +#include "wifi_legacy_hal_factory.h" #include "wifi_mode_controller.h" using android::hardware::configureRpcThreadpool; @@ -32,6 +33,8 @@ using android::hardware::wifi::V1_5::implementation::feature_flags:: WifiFeatureFlags; using android::hardware::wifi::V1_5::implementation::iface_util::WifiIfaceUtil; 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; @@ -50,10 +53,13 @@ int main(int /*argc*/, char** argv) { const auto iface_tool = std::make_shared(); + const auto legacy_hal_factory = + std::make_shared(iface_tool); + // Setup hwbinder service android::sp service = new android::hardware::wifi::V1_5::implementation::Wifi( - iface_tool, std::make_shared(iface_tool), + iface_tool, legacy_hal_factory, std::make_shared(), std::make_shared(iface_tool), std::make_shared()); diff --git a/wifi/1.5/default/tests/mock_wifi_feature_flags.h b/wifi/1.5/default/tests/mock_wifi_feature_flags.h index 92fbb055d6..c3877edd60 100644 --- a/wifi/1.5/default/tests/mock_wifi_feature_flags.h +++ b/wifi/1.5/default/tests/mock_wifi_feature_flags.h @@ -33,7 +33,8 @@ class MockWifiFeatureFlags : public WifiFeatureFlags { public: MockWifiFeatureFlags(); - MOCK_METHOD0(getChipModes, std::vector()); + MOCK_METHOD1(getChipModes, + std::vector(bool is_primary)); MOCK_METHOD0(isApMacRandomizationDisabled, bool()); }; diff --git a/wifi/1.5/default/tests/mock_wifi_legacy_hal.cpp b/wifi/1.5/default/tests/mock_wifi_legacy_hal.cpp index 501bd7f4cf..d13c5568b3 100644 --- a/wifi/1.5/default/tests/mock_wifi_legacy_hal.cpp +++ b/wifi/1.5/default/tests/mock_wifi_legacy_hal.cpp @@ -29,8 +29,9 @@ namespace implementation { namespace legacy_hal { MockWifiLegacyHal::MockWifiLegacyHal( - const std::weak_ptr iface_tool) - : WifiLegacyHal(iface_tool) {} + const std::weak_ptr iface_tool, + const wifi_hal_fn& fn, bool is_primary) + : WifiLegacyHal(iface_tool, fn, is_primary) {} } // namespace legacy_hal } // namespace implementation } // namespace V1_5 diff --git a/wifi/1.5/default/tests/mock_wifi_legacy_hal.h b/wifi/1.5/default/tests/mock_wifi_legacy_hal.h index f93834775c..9ab2fd5421 100644 --- a/wifi/1.5/default/tests/mock_wifi_legacy_hal.h +++ b/wifi/1.5/default/tests/mock_wifi_legacy_hal.h @@ -31,7 +31,8 @@ namespace legacy_hal { class MockWifiLegacyHal : public WifiLegacyHal { public: MockWifiLegacyHal( - const std::weak_ptr iface_tool); + const std::weak_ptr 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*, diff --git a/wifi/1.5/default/tests/wifi_chip_unit_tests.cpp b/wifi/1.5/default/tests/wifi_chip_unit_tests.cpp index 1d55e164d4..d99bfbd0d5 100644 --- a/wifi/1.5/default/tests/wifi_chip_unit_tests.cpp +++ b/wifi/1.5/default/tests/wifi_chip_unit_tests.cpp @@ -59,7 +59,7 @@ class WifiChipTest : public Test { {feature_flags::chip_mode_ids::kV1Ap, combinationsAp} }; // clang-format on - EXPECT_CALL(*feature_flags_, getChipModes()) + EXPECT_CALL(*feature_flags_, getChipModes(true)) .WillRepeatedly(testing::Return(modes)); } @@ -76,7 +76,7 @@ class WifiChipTest : public Test { {feature_flags::chip_mode_ids::kV1Ap, combinationsAp} }; // clang-format on - EXPECT_CALL(*feature_flags_, getChipModes()) + EXPECT_CALL(*feature_flags_, getChipModes(true)) .WillRepeatedly(testing::Return(modes)); } @@ -89,7 +89,7 @@ class WifiChipTest : public Test { {feature_flags::chip_mode_ids::kV1Sta, combinationsSta} }; // clang-format on - EXPECT_CALL(*feature_flags_, getChipModes()) + EXPECT_CALL(*feature_flags_, getChipModes(true)) .WillRepeatedly(testing::Return(modes)); } @@ -103,7 +103,7 @@ class WifiChipTest : public Test { {feature_flags::chip_mode_ids::kV3, combinations} }; // clang-format on - EXPECT_CALL(*feature_flags_, getChipModes()) + EXPECT_CALL(*feature_flags_, getChipModes(true)) .WillRepeatedly(testing::Return(modes)); } @@ -116,7 +116,7 @@ class WifiChipTest : public Test { {feature_flags::chip_mode_ids::kV3, combinations} }; // clang-format on - EXPECT_CALL(*feature_flags_, getChipModes()) + EXPECT_CALL(*feature_flags_, getChipModes(true)) .WillRepeatedly(testing::Return(modes)); } @@ -129,7 +129,7 @@ class WifiChipTest : public Test { {feature_flags::chip_mode_ids::kV3, combinations} }; // clang-format on - EXPECT_CALL(*feature_flags_, getChipModes()) + EXPECT_CALL(*feature_flags_, getChipModes(true)) .WillRepeatedly(testing::Return(modes)); } @@ -267,10 +267,12 @@ class WifiChipTest : public Test { sp chip_; ChipId chip_id_ = kFakeChipId; + legacy_hal::wifi_hal_fn fake_func_table_; std::shared_ptr> iface_tool_{ new NiceMock}; std::shared_ptr> legacy_hal_{ - new NiceMock(iface_tool_)}; + new NiceMock(iface_tool_, + fake_func_table_, true)}; std::shared_ptr> mode_controller_{new NiceMock}; std::shared_ptr> iface_util_{ @@ -281,8 +283,8 @@ class WifiChipTest : public Test { public: void SetUp() override { chip_ = - new WifiChip(chip_id_, legacy_hal_, mode_controller_, iface_util_, - feature_flags_, subsystemRestartHandler); + new WifiChip(chip_id_, true, legacy_hal_, mode_controller_, + iface_util_, feature_flags_, subsystemRestartHandler); EXPECT_CALL(*mode_controller_, changeFirmwareMode(testing::_)) .WillRepeatedly(testing::Return(true)); 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 index 3e7026f1f8..411190b01a 100644 --- a/wifi/1.5/default/tests/wifi_nan_iface_unit_tests.cpp +++ b/wifi/1.5/default/tests/wifi_nan_iface_unit_tests.cpp @@ -112,10 +112,12 @@ class MockNanIfaceEventCallback : public IWifiNanIfaceEventCallback { class WifiNanIfaceTest : public Test { protected: + legacy_hal::wifi_hal_fn fake_func_table_; std::shared_ptr> iface_tool_{ new NiceMock}; std::shared_ptr> legacy_hal_{ - new NiceMock(iface_tool_)}; + new NiceMock(iface_tool_, + fake_func_table_, true)}; std::shared_ptr> iface_util_{ new NiceMock(iface_tool_)}; }; diff --git a/wifi/1.5/default/wifi.cpp b/wifi/1.5/default/wifi.cpp index c4e23337c8..17db51d35b 100644 --- a/wifi/1.5/default/wifi.cpp +++ b/wifi/1.5/default/wifi.cpp @@ -21,8 +21,8 @@ #include "wifi_status_util.h" namespace { -// Chip ID to use for the only supported chip. -static constexpr android::hardware::wifi::V1_0::ChipId kChipId = 0; +// Starting Chip ID, will be assigned to primary chip +static constexpr android::hardware::wifi::V1_0::ChipId kPrimaryChipId = 0; } // namespace namespace android { @@ -35,12 +35,12 @@ using hidl_return_util::validateAndCallWithLock; Wifi::Wifi( const std::shared_ptr iface_tool, - const std::shared_ptr legacy_hal, + const std::shared_ptr legacy_hal_factory, const std::shared_ptr mode_controller, const std::shared_ptr iface_util, const std::shared_ptr feature_flags) : iface_tool_(iface_tool), - legacy_hal_(legacy_hal), + legacy_hal_factory_(legacy_hal_factory), mode_controller_(mode_controller), iface_util_(iface_util), feature_flags_(feature_flags), @@ -84,10 +84,16 @@ Return Wifi::getChip(ChipId chip_id, getChip_cb hidl_status_cb) { Return Wifi::debug(const hidl_handle& handle, const hidl_vec&) { LOG(INFO) << "-----------Debug is called----------------"; - if (!chip_.get()) { + if (chips_.size() == 0) { return Void(); } - return chip_->debug(handle, {}); + + for (sp chip : chips_) { + if (!chip.get()) continue; + + chip->debug(handle, {}); + } + return Void(); } WifiStatus Wifi::registerEventCallbackInternal( @@ -120,10 +126,13 @@ WifiStatus Wifi::startInternal() { }; // Create the chip instance once the HAL is started. - // Need to consider the case of multiple chips TODO(156998862) - chip_ = - new WifiChip(kChipId, legacy_hal_, mode_controller_, iface_util_, - feature_flags_, on_subsystem_restart_callback); + android::hardware::wifi::V1_0::ChipId chipId = kPrimaryChipId; + for (auto& hal : legacy_hals_) { + chips_.push_back(new WifiChip( + chipId, chipId == kPrimaryChipId, hal, mode_controller_, + iface_util_, feature_flags_, on_subsystem_restart_callback)); + chipId++; + } run_state_ = RunState::STARTED; for (const auto& callback : event_cb_handler_.getCallbacks()) { if (!callback->onStart().isOk()) { @@ -154,10 +163,13 @@ WifiStatus Wifi::stopInternal( } // Clear the chip object and its child objects since the HAL is now // stopped. - if (chip_.get()) { - chip_->invalidate(); - chip_.clear(); + for (auto& chip : chips_) { + if (chip.get()) { + chip->invalidate(); + chip.clear(); + } } + chips_.clear(); WifiStatus wifi_status = stopLegacyHalAndDeinitializeModeController(lock); if (wifi_status.code == WifiStatusCode::SUCCESS) { for (const auto& callback : event_cb_handler_.getCallbacks()) { @@ -181,21 +193,23 @@ WifiStatus Wifi::stopInternal( std::pair> Wifi::getChipIdsInternal() { std::vector chip_ids; - if (chip_.get()) { - chip_ids.emplace_back(kChipId); + + for (auto& chip : chips_) { + ChipId chip_id = getChipIdFromWifiChip(chip); + if (chip_id != UINT32_MAX) chip_ids.emplace_back(chip_id); } return {createWifiStatus(WifiStatusCode::SUCCESS), std::move(chip_ids)}; } std::pair> Wifi::getChipInternal( ChipId chip_id) { - if (!chip_.get()) { - return {createWifiStatus(WifiStatusCode::ERROR_NOT_STARTED), nullptr}; + for (auto& chip : chips_) { + ChipId cand_id = getChipIdFromWifiChip(chip); + if ((cand_id != UINT32_MAX) && (cand_id == chip_id)) + return {createWifiStatus(WifiStatusCode::SUCCESS), chip}; } - if (chip_id != kChipId) { - return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr}; - } - return {createWifiStatus(WifiStatusCode::SUCCESS), chip_}; + + return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr}; } WifiStatus Wifi::initializeModeControllerAndLegacyHal() { @@ -203,23 +217,46 @@ WifiStatus Wifi::initializeModeControllerAndLegacyHal() { LOG(ERROR) << "Failed to initialize firmware mode controller"; return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); } - legacy_hal::wifi_error legacy_status = legacy_hal_->initialize(); - if (legacy_status != legacy_hal::WIFI_SUCCESS) { - LOG(ERROR) << "Failed to initialize legacy HAL: " - << legacyErrorToString(legacy_status); - return createWifiStatusFromLegacyError(legacy_status); + + legacy_hals_ = legacy_hal_factory_->getHals(); + 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(); + if (legacy_status != legacy_hal::WIFI_SUCCESS) { + // Currently WifiLegacyHal::initialize does not allocate extra mem, + // only initializes the function table. If this changes, need to + // implement WifiLegacyHal::deinitialize and deinitalize the + // HALs already initialized + LOG(ERROR) << "Failed to initialize legacy HAL index: " << index + << " error: " << legacyErrorToString(legacy_status); + return createWifiStatusFromLegacyError(legacy_status); + } + index++; } return createWifiStatus(WifiStatusCode::SUCCESS); } WifiStatus Wifi::stopLegacyHalAndDeinitializeModeController( /* NONNULL */ std::unique_lock* lock) { + legacy_hal::wifi_error legacy_status = legacy_hal::WIFI_SUCCESS; + int index = 0; + run_state_ = RunState::STOPPING; - legacy_hal::wifi_error legacy_status = - legacy_hal_->stop(lock, [&]() { run_state_ = RunState::STOPPED; }); + for (auto& hal : legacy_hals_) { + legacy_hal::wifi_error tmp = hal->stop(lock, [&]() {}); + if (tmp != legacy_hal::WIFI_SUCCESS) { + LOG(ERROR) << "Failed to stop legacy HAL index: " << index + << " error: " << legacyErrorToString(legacy_status); + legacy_status = tmp; + } + index++; + } + run_state_ = RunState::STOPPED; + if (legacy_status != legacy_hal::WIFI_SUCCESS) { - LOG(ERROR) << "Failed to stop legacy HAL: " - << legacyErrorToString(legacy_status); + LOG(ERROR) << "One or more legacy HALs failed to stop"; return createWifiStatusFromLegacyError(legacy_status); } if (!mode_controller_->deinitialize()) { @@ -228,6 +265,19 @@ WifiStatus Wifi::stopLegacyHalAndDeinitializeModeController( } return createWifiStatus(WifiStatusCode::SUCCESS); } + +ChipId Wifi::getChipIdFromWifiChip(sp& chip) { + ChipId chip_id = UINT32_MAX; + if (chip.get()) { + chip->getId([&](WifiStatus status, uint32_t id) { + if (status.code == WifiStatusCode::SUCCESS) { + chip_id = id; + } + }); + } + + return chip_id; +} } // namespace implementation } // namespace V1_5 } // namespace wifi diff --git a/wifi/1.5/default/wifi.h b/wifi/1.5/default/wifi.h index 8de0ef4c28..9f5a1b0a3c 100644 --- a/wifi/1.5/default/wifi.h +++ b/wifi/1.5/default/wifi.h @@ -27,6 +27,7 @@ #include "wifi_chip.h" #include "wifi_feature_flags.h" #include "wifi_legacy_hal.h" +#include "wifi_legacy_hal_factory.h" #include "wifi_mode_controller.h" namespace android { @@ -41,7 +42,8 @@ namespace implementation { class Wifi : public V1_5::IWifi { public: Wifi(const std::shared_ptr iface_tool, - const std::shared_ptr legacy_hal, + const std::shared_ptr + legacy_hal_factory, const std::shared_ptr mode_controller, const std::shared_ptr iface_util, @@ -75,16 +77,18 @@ class Wifi : public V1_5::IWifi { WifiStatus initializeModeControllerAndLegacyHal(); WifiStatus stopLegacyHalAndDeinitializeModeController( std::unique_lock* lock); + ChipId getChipIdFromWifiChip(sp& chip); // Instance is created in this root level |IWifi| HIDL interface object // and shared with all the child HIDL interface objects. std::shared_ptr iface_tool_; - std::shared_ptr legacy_hal_; + std::shared_ptr legacy_hal_factory_; std::shared_ptr mode_controller_; + std::vector> legacy_hals_; std::shared_ptr iface_util_; std::shared_ptr feature_flags_; RunState run_state_; - sp chip_; + std::vector> chips_; hidl_callback_util::HidlCallbackHandler event_cb_handler_; diff --git a/wifi/1.5/default/wifi_chip.cpp b/wifi/1.5/default/wifi_chip.cpp index b898f686eb..9c352bc563 100644 --- a/wifi/1.5/default/wifi_chip.cpp +++ b/wifi/1.5/default/wifi_chip.cpp @@ -332,7 +332,8 @@ using hidl_return_util::validateAndCall; using hidl_return_util::validateAndCallWithLock; WifiChip::WifiChip( - ChipId chip_id, const std::weak_ptr legacy_hal, + ChipId chip_id, bool is_primary, + const std::weak_ptr legacy_hal, const std::weak_ptr mode_controller, const std::weak_ptr iface_util, const std::weak_ptr feature_flags, @@ -343,7 +344,7 @@ WifiChip::WifiChip( iface_util_(iface_util), is_valid_(true), current_mode_id_(feature_flags::chip_mode_ids::kInvalid), - modes_(feature_flags.lock()->getChipModes()), + modes_(feature_flags.lock()->getChipModes(is_primary)), debug_ring_buffer_cb_registered_(false), subsystemCallbackHandler_(handler) { setActiveWlanIfaceNameProperty(kNoActiveWlanIfaceNamePropertyValue); @@ -1599,15 +1600,16 @@ std::string WifiChip::getFirstActiveWlanIfaceName() { // This could happen if the chip call is made before any STA/AP // iface is created. Default to wlan0 for such cases. LOG(WARNING) << "No active wlan interfaces in use! Using default"; - return getWlanIfaceName(0); + return getWlanIfaceNameWithType(IfaceType::STA, 0); } // 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(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 = getWlanIfaceName(idx); + const auto ifname = getWlanIfaceNameWithType(type, idx); if (findUsingName(ap_ifaces_, ifname)) continue; if (findUsingName(sta_ifaces_, ifname)) continue; return ifname; @@ -1625,7 +1627,8 @@ std::string WifiChip::allocateApIfaceName() { if (!ifname.empty()) { return ifname; } - return allocateApOrStaIfaceName((isStaApConcurrencyAllowedInCurrentMode() && + return allocateApOrStaIfaceName(IfaceType::AP, + (isStaApConcurrencyAllowedInCurrentMode() && !isDualApAllowedInCurrentMode()) ? 1 : 0); @@ -1634,7 +1637,7 @@ std::string WifiChip::allocateApIfaceName() { // STA iface names start with idx 0. // Primary STA iface will always be 0. std::string WifiChip::allocateStaIfaceName() { - return allocateApOrStaIfaceName(0); + return allocateApOrStaIfaceName(IfaceType::STA, 0); } bool WifiChip::writeRingbufferFilesInternal() { @@ -1670,6 +1673,17 @@ bool WifiChip::writeRingbufferFilesInternal() { return true; } +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); + if (err == legacy_hal::WIFI_SUCCESS) return ifname; + + return getWlanIfaceName(idx); +} + } // namespace implementation } // namespace V1_5 } // namespace wifi diff --git a/wifi/1.5/default/wifi_chip.h b/wifi/1.5/default/wifi_chip.h index 36c191cbcd..5f1d9e8eda 100644 --- a/wifi/1.5/default/wifi_chip.h +++ b/wifi/1.5/default/wifi_chip.h @@ -50,7 +50,7 @@ using namespace android::hardware::wifi::V1_0; */ class WifiChip : public V1_4::IWifiChip { public: - WifiChip(ChipId chip_id, + WifiChip(ChipId chip_id, bool is_primary, const std::weak_ptr legacy_hal, const std::weak_ptr mode_controller, @@ -256,10 +256,11 @@ class WifiChip : public V1_4::IWifiChip { bool isStaApConcurrencyAllowedInCurrentMode(); bool isDualApAllowedInCurrentMode(); std::string getFirstActiveWlanIfaceName(); - std::string allocateApOrStaIfaceName(uint32_t start_idx); + std::string allocateApOrStaIfaceName(IfaceType type, uint32_t start_idx); std::string allocateApIfaceName(); std::string allocateStaIfaceName(); bool writeRingbufferFilesInternal(); + std::string getWlanIfaceNameWithType(IfaceType type, unsigned idx); ChipId chip_id_; std::weak_ptr legacy_hal_; diff --git a/wifi/1.5/default/wifi_feature_flags.cpp b/wifi/1.5/default/wifi_feature_flags.cpp index 151d473e46..9f91bd7dc4 100644 --- a/wifi/1.5/default/wifi_feature_flags.cpp +++ b/wifi/1.5/default/wifi_feature_flags.cpp @@ -139,6 +139,13 @@ static const std::vector kChipModes{ ChipIfaceCombination::make_vec({WIFI_HAL_INTERFACE_COMBINATIONS_AP})}, #endif }; + +static const std::vector kChipModesSecondary{ +#ifdef WIFI_HAL_INTERFACE_COMBINATIONS_SECONDARY_CHIP + {chip_mode_ids::kV3, ChipIfaceCombination::make_vec( + {WIFI_HAL_INTERFACE_COMBINATIONS_SECONDARY_CHIP})}, +#endif +}; #undef STA #undef AP #undef P2P @@ -154,8 +161,9 @@ static const std::vector kChipModes{ WifiFeatureFlags::WifiFeatureFlags() {} -std::vector WifiFeatureFlags::getChipModes() { - return kChipModes; +std::vector WifiFeatureFlags::getChipModes( + bool is_primary) { + return (is_primary) ? kChipModes : kChipModesSecondary; } } // namespace feature_flags diff --git a/wifi/1.5/default/wifi_feature_flags.h b/wifi/1.5/default/wifi_feature_flags.h index 73d18eca35..cb68b8c0c1 100644 --- a/wifi/1.5/default/wifi_feature_flags.h +++ b/wifi/1.5/default/wifi_feature_flags.h @@ -42,7 +42,8 @@ class WifiFeatureFlags { WifiFeatureFlags(); virtual ~WifiFeatureFlags() = default; - virtual std::vector getChipModes(); + virtual std::vector getChipModes( + bool is_primary); }; } // namespace feature_flags diff --git a/wifi/1.5/default/wifi_legacy_hal.cpp b/wifi/1.5/default/wifi_legacy_hal.cpp index 40705689ce..6ee8937d5f 100644 --- a/wifi/1.5/default/wifi_legacy_hal.cpp +++ b/wifi/1.5/default/wifi_legacy_hal.cpp @@ -36,7 +36,8 @@ static constexpr uint32_t kMaxGscanFrequenciesForBand = 64; static constexpr uint32_t kLinkLayerStatsDataMpduSizeThreshold = 128; static constexpr uint32_t kMaxWakeReasonStatsArraySize = 32; static constexpr uint32_t kMaxRingBuffers = 10; -static constexpr uint32_t kMaxStopCompleteWaitMs = 100; +// need a long timeout (1000ms) for chips that unload their driver. +static constexpr uint32_t kMaxStopCompleteWaitMs = 1000; static constexpr char kDriverPropName[] = "wlan.driver.status"; // Helper function to create a non-const char* for legacy Hal API's. @@ -54,6 +55,7 @@ namespace wifi { namespace V1_5 { namespace implementation { namespace legacy_hal { + // Legacy HAL functions accept "C" style function pointers, so use global // functions to pass to the legacy HAL function and store the corresponding // std::function methods to be invoked. @@ -344,26 +346,20 @@ void onAsyncNanEventScheduleUpdate(NanDataPathScheduleUpdateInd* event) { // End of the free-standing "C" style callbacks. WifiLegacyHal::WifiLegacyHal( - const std::weak_ptr iface_tool) - : global_handle_(nullptr), + const std::weak_ptr iface_tool, + const wifi_hal_fn& fn, bool is_primary) + : global_func_table_(fn), + global_handle_(nullptr), awaiting_event_loop_termination_(false), is_started_(false), - iface_tool_(iface_tool) {} + iface_tool_(iface_tool), + is_primary_(is_primary) {} wifi_error WifiLegacyHal::initialize() { LOG(DEBUG) << "Initialize legacy HAL"; - // TODO: Add back the HAL Tool if we need to. All we need from the HAL tool - // for now is this function call which we can directly call. - if (!initHalFuncTableWithStubs(&global_func_table_)) { - LOG(ERROR) - << "Failed to initialize legacy hal function table with stubs"; - return WIFI_ERROR_UNKNOWN; - } - wifi_error status = init_wifi_vendor_hal_func_table(&global_func_table_); - if (status != WIFI_SUCCESS) { - LOG(ERROR) << "Failed to initialize legacy hal function table"; - } - return status; + // this now does nothing, since HAL function table is provided + // to the constructor + return WIFI_SUCCESS; } wifi_error WifiLegacyHal::start() { @@ -380,13 +376,17 @@ wifi_error WifiLegacyHal::start() { LOG(ERROR) << "Timed out awaiting driver ready"; return status; } - property_set(kDriverPropName, "ok"); - LOG(DEBUG) << "Starting legacy HAL"; - if (!iface_tool_.lock()->SetWifiUpState(true)) { - LOG(ERROR) << "Failed to set WiFi interface up"; - return WIFI_ERROR_UNKNOWN; + if (is_primary_) { + property_set(kDriverPropName, "ok"); + + if (!iface_tool_.lock()->SetWifiUpState(true)) { + LOG(ERROR) << "Failed to set WiFi interface up"; + return WIFI_ERROR_UNKNOWN; + } } + + LOG(DEBUG) << "Starting legacy HAL"; status = global_func_table_.wifi_initialize(&global_handle_); if (status != WIFI_SUCCESS || !global_handle_) { LOG(ERROR) << "Failed to retrieve global handle"; @@ -419,7 +419,7 @@ wifi_error WifiLegacyHal::stop( // Invalidate all the internal pointers now that the HAL is // stopped. invalidate(); - iface_tool_.lock()->SetWifiUpState(false); + if (is_primary_) iface_tool_.lock()->SetWifiUpState(false); on_stop_complete_user_callback(); is_started_ = false; }; @@ -488,12 +488,21 @@ WifiLegacyHal::requestFirmwareMemoryDump(const std::string& iface_name) { std::pair WifiLegacyHal::getSupportedFeatureSet( const std::string& iface_name) { - feature_set set; + feature_set set = 0, chip_set = 0; + wifi_error status = WIFI_SUCCESS; + static_assert(sizeof(set) == sizeof(uint64_t), "Some feature_flags can not be represented in output"); - wifi_error status = global_func_table_.wifi_get_supported_feature_set( - getIfaceHandle(iface_name), &set); - return {status, static_cast(set)}; + 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 */ + + if (iface_handle) { + status = global_func_table_.wifi_get_supported_feature_set(iface_handle, + &set); + } + return {status, static_cast(set | chip_set)}; } std::pair @@ -845,10 +854,15 @@ wifi_error WifiLegacyHal::resetDscpToAccessCategoryMapping() { std::pair WifiLegacyHal::getLoggerSupportedFeatureSet( const std::string& iface_name) { - uint32_t supported_feature_flags; - wifi_error status = - global_func_table_.wifi_get_logger_supported_feature_set( - getIfaceHandle(iface_name), &supported_feature_flags); + 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); + } return {status, supported_feature_flags}; } @@ -1485,6 +1499,17 @@ wifi_error WifiLegacyHal::handleVirtualInterfaceCreateOrDeleteStatus( return status; } +wifi_error WifiLegacyHal::getSupportedIfaceName(uint32_t iface_type, + std::string& ifname) { + std::array buffer; + + wifi_error res = global_func_table_.wifi_get_supported_iface_name( + global_handle_, (uint32_t)iface_type, buffer.data(), buffer.size()); + if (res == WIFI_SUCCESS) ifname = buffer.data(); + + return res; +} + void WifiLegacyHal::invalidate() { global_handle_ = nullptr; iface_name_to_handle_.clear(); diff --git a/wifi/1.5/default/wifi_legacy_hal.h b/wifi/1.5/default/wifi_legacy_hal.h index ae520a85bc..2984a00c9b 100644 --- a/wifi/1.5/default/wifi_legacy_hal.h +++ b/wifi/1.5/default/wifi_legacy_hal.h @@ -173,7 +173,8 @@ using on_radio_mode_change_callback = */ class WifiLegacyHal { public: - WifiLegacyHal(const std::weak_ptr iface_tool); + WifiLegacyHal(const std::weak_ptr iface_tool, + const wifi_hal_fn& fn, bool is_primary); virtual ~WifiLegacyHal() = default; // Initialize the legacy HAL function table. @@ -379,6 +380,7 @@ class WifiLegacyHal { virtual wifi_error createVirtualInterface(const std::string& ifname, wifi_interface_type iftype); virtual wifi_error deleteVirtualInterface(const std::string& ifname); + wifi_error getSupportedIfaceName(uint32_t iface_type, std::string& ifname); private: // Retrieve interface handles for all the available interfaces. @@ -408,6 +410,11 @@ class WifiLegacyHal { // Flag to indicate if the legacy HAL has been started. bool is_started_; std::weak_ptr iface_tool_; + // flag to indicate if this HAL is for the primary chip. This is used + // in order to avoid some hard-coded behavior used with older HALs, + // such as bring wlan0 interface up/down on start/stop HAL. + // it may be removed once vendor HALs are updated. + bool is_primary_; }; } // namespace legacy_hal diff --git a/wifi/1.5/default/wifi_legacy_hal_factory.cpp b/wifi/1.5/default/wifi_legacy_hal_factory.cpp new file mode 100644 index 0000000000..fbaa284f56 --- /dev/null +++ b/wifi/1.5/default/wifi_legacy_hal_factory.cpp @@ -0,0 +1,263 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "wifi_legacy_hal_factory.h" +#include "wifi_legacy_hal_stubs.h" + +namespace { +static constexpr char kVendorHalsDescPath[] = "/vendor/etc/wifi/vendor_hals"; +static constexpr char kVendorHalsDescExt[] = ".xml"; +static constexpr uint32_t kVendorHalsDescVersion = 1; + +bool isDirectory(struct dirent* entryPtr) { + bool isDir = false; + if (entryPtr->d_type != DT_UNKNOWN && entryPtr->d_type != DT_LNK) { + isDir = (entryPtr->d_type == DT_DIR); + } else { + struct stat entryStat; + stat(entryPtr->d_name, &entryStat); + isDir = S_ISDIR(entryStat.st_mode); + } + return isDir; +} + +bool isFileExtension(const char* name, const char* ext) { + if (name == NULL) return false; + if (ext == NULL) return false; + + size_t extLen = strlen(ext); + size_t nameLen = strlen(name); + + if (extLen > nameLen) return false; + + if (strncmp(name + nameLen - extLen, ext, extLen) != 0) return false; + + return true; +} +}; // namespace + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_5 { +namespace implementation { +namespace legacy_hal { + +WifiLegacyHalFactory::WifiLegacyHalFactory( + const std::weak_ptr iface_tool) + : iface_tool_(iface_tool) {} + +std::vector> WifiLegacyHalFactory::getHals() { + if (legacy_hals_.empty()) { + if (!initVendorHalDescriptorFromLinked()) + initVendorHalsDescriptorList(); + for (auto& desc : descs_) { + std::shared_ptr hal = + std::make_shared(iface_tool_, desc.fn, + desc.primary); + legacy_hals_.push_back(hal); + } + } + + return legacy_hals_; +} + +bool WifiLegacyHalFactory::initVendorHalDescriptorFromLinked() { + wifi_hal_lib_desc desc; + + if (!initLinkedHalFunctionTable(&desc.fn)) return false; + + desc.primary = true; + desc.handle = NULL; + descs_.push_back(desc); + return true; +} + +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"); + if (!initfn) { + LOG(INFO) << "no vendor HAL library linked, will try dynamic load"; + return false; + } + + if (!initHalFuncTableWithStubs(hal_fn)) { + LOG(ERROR) << "Can not initialize the basic function pointer table"; + return false; + } + + if (initfn(hal_fn) != WIFI_SUCCESS) { + LOG(ERROR) << "Can not initialize the vendor function pointer table"; + return false; + } + + return true; +} + +/* + * Overall structure of the HAL descriptor XML schema + * + * + * + * /vendor/lib64/libwifi-hal-qcom.so + * 1 + * + */ +void WifiLegacyHalFactory::initVendorHalsDescriptorList() { + xmlDocPtr xml; + xmlNodePtr node, cnode; + char* version; + std::string path; + xmlChar* value; + wifi_hal_lib_desc desc; + + LOG(INFO) << "processing vendor HALs descriptions in " + << kVendorHalsDescPath; + DIR* dirPtr = ::opendir(kVendorHalsDescPath); + if (dirPtr == NULL) { + LOG(ERROR) << "failed to open " << kVendorHalsDescPath; + return; + } + for (struct dirent* entryPtr = ::readdir(dirPtr); entryPtr != NULL; + entryPtr = ::readdir(dirPtr)) { + if (isDirectory(entryPtr)) continue; + + if (!isFileExtension(entryPtr->d_name, kVendorHalsDescExt)) + continue; // only process .xml files + + LOG(INFO) << "processing config file: " << entryPtr->d_name; + + std::string fullPath(kVendorHalsDescPath); + fullPath.append("/"); + 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..."; + continue; + } + node = xmlDocGetRootElement(xml); + if (!node) { + 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..."; + 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..."; + goto skip; + } + cnode = node->children; + path.clear(); + desc.primary = false; + while (cnode) { + if (!xmlStrcmp(cnode->name, BAD_CAST "path")) { + value = xmlNodeListGetString(xml, cnode->children, 1); + if (value) path = (char*)value; + xmlFree(value); + } else if (!xmlStrcmp(cnode->name, BAD_CAST "primary")) { + value = xmlNodeListGetString(xml, cnode->children, 1); + desc.primary = !xmlStrcmp(value, BAD_CAST "1"); + xmlFree(value); + } + cnode = cnode->next; + } + if (path.empty()) { + LOG(ERROR) << "hal library path not provided in: " + << entryPtr->d_name << ", skipping..."; + goto skip; + } + if (loadVendorHalLib(path, desc)) { + if (desc.primary) + descs_.insert(descs_.begin(), desc); + else + descs_.push_back(desc); + } + skip: + xmlFreeDoc(xml); + } + ::closedir(dirPtr); +} + +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; + + if (!h) { + 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"); + if (!initfn) { + LOG(ERROR) << "init_wifi_vendor_hal_func_table not found in: " << path; + goto out_err; + } + + if (!initHalFuncTableWithStubs(&desc.fn)) { + LOG(ERROR) << "Can not initialize the basic function pointer table"; + goto out_err; + } + res = initfn(&desc.fn); + if (res != WIFI_SUCCESS) { + LOG(ERROR) << "failed to initialize the vendor func table in: " << path + << " error: " << res; + goto out_err; + } + + res = desc.fn.wifi_early_initialize(); + // 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; + goto out_err; + } + + desc.handle = h; + return true; +out_err: + dlclose(h); + return false; +} + +} // namespace legacy_hal +} // namespace implementation +} // namespace V1_5 +} // namespace wifi +} // namespace hardware +} // namespace android diff --git a/wifi/1.5/default/wifi_legacy_hal_factory.h b/wifi/1.5/default/wifi_legacy_hal_factory.h new file mode 100644 index 0000000000..e3440faff2 --- /dev/null +++ b/wifi/1.5/default/wifi_legacy_hal_factory.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WIFI_LEGACY_HAL_FACTORY_H_ +#define WIFI_LEGACY_HAL_FACTORY_H_ + +#include + +#include "wifi_legacy_hal.h" + +namespace android { +namespace hardware { +namespace wifi { +namespace V1_5 { +namespace implementation { +// This is in a separate namespace to prevent typename conflicts between +// the legacy HAL types and the HIDL interface types. +namespace legacy_hal { +/** + * Class that creates WifiLegacyHal objects for vendor HALs in the system. + */ +class WifiLegacyHalFactory { + public: + WifiLegacyHalFactory( + const std::weak_ptr iface_tool); + virtual ~WifiLegacyHalFactory() = default; + + std::vector> getHals(); + + private: + typedef struct { + wifi_hal_fn fn; + bool primary; + void* handle; + } wifi_hal_lib_desc; + + bool initVendorHalDescriptorFromLinked(); + void initVendorHalsDescriptorList(); + bool initLinkedHalFunctionTable(wifi_hal_fn* hal_fn); + bool loadVendorHalLib(const std::string& path, wifi_hal_lib_desc& desc); + + std::weak_ptr iface_tool_; + std::vector descs_; + std::vector> legacy_hals_; +}; + +} // namespace legacy_hal +} // namespace implementation +} // namespace V1_5 +} // namespace wifi +} // namespace hardware +} // namespace android + +#endif // WIFI_LEGACY_HAL_FACTORY_H_ diff --git a/wifi/1.5/default/wifi_legacy_hal_stubs.cpp b/wifi/1.5/default/wifi_legacy_hal_stubs.cpp index 73b58564f1..a1122e97f2 100644 --- a/wifi/1.5/default/wifi_legacy_hal_stubs.cpp +++ b/wifi/1.5/default/wifi_legacy_hal_stubs.cpp @@ -144,6 +144,10 @@ bool initHalFuncTableWithStubs(wifi_hal_fn* hal_fn) { populateStubFor(&hal_fn->wifi_map_dscp_access_category); populateStubFor(&hal_fn->wifi_reset_dscp_mapping); populateStubFor(&hal_fn->wifi_set_subsystem_restart_handler); + populateStubFor(&hal_fn->wifi_get_supported_iface_name); + populateStubFor(&hal_fn->wifi_early_initialize); + populateStubFor(&hal_fn->wifi_get_chip_feature_set); + return true; } } // namespace legacy_hal -- GitLab From 5aa08b7d592cfc83c446c8bb6e67ac79cf67aa02 Mon Sep 17 00:00:00 2001 From: Jordan Jozwiak Date: Tue, 11 Aug 2020 14:40:44 -0700 Subject: [PATCH 110/790] Add INFO_MODEL and INFO_MODEL_YEAR default values Bug: 162611157 Test: adb shell cmd car_service get-carpropertyconfig | grep MODEL Change-Id: Iff9f763aa624a2002b0dd326316410a93a47d5c0 --- .../2.0/default/impl/vhal_v2_0/DefaultConfig.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h index 16c33b9d19..16e1bf7291 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h @@ -264,6 +264,20 @@ const ConfigDeclaration kVehicleProperties[]{ .changeMode = VehiclePropertyChangeMode::STATIC, }, .initialValue = {.stringValue = "Toy Vehicle"}}, + {.config = + { + .prop = toInt(VehicleProperty::INFO_MODEL), + .access = VehiclePropertyAccess::READ, + .changeMode = VehiclePropertyChangeMode::STATIC, + }, + .initialValue = {.stringValue = "Speedy Model"}}, + {.config = + { + .prop = toInt(VehicleProperty::INFO_MODEL_YEAR), + .access = VehiclePropertyAccess::READ, + .changeMode = VehiclePropertyChangeMode::STATIC, + }, + .initialValue = {.int32Values = {2020}}}, {.config = { .prop = toInt(VehicleProperty::INFO_EXTERIOR_DIMENSIONS), -- GitLab From 2fb0424c089c2afedf15c9d934a9dc0c838f5cbb Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Wed, 12 Aug 2020 15:40:01 -0700 Subject: [PATCH 111/790] Comment out unused parameter in Tuner Frontend implementation Test: make Bug: 163870103 Change-Id: Ie02454fca63558d519c34c2566a20d2c1a6958d1 --- tv/tuner/1.1/default/Frontend.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tv/tuner/1.1/default/Frontend.cpp b/tv/tuner/1.1/default/Frontend.cpp index fde26c16ad..1e9435ba7e 100644 --- a/tv/tuner/1.1/default/Frontend.cpp +++ b/tv/tuner/1.1/default/Frontend.cpp @@ -72,7 +72,7 @@ Return Frontend::tune(const FrontendSettings& /* settings */) { } Return Frontend::tune_1_1(const FrontendSettings& settings, - const V1_1::FrontendSettingsExt& settingsExt) { + const V1_1::FrontendSettingsExt& /*settingsExt*/) { ALOGV("%s", __FUNCTION__); return tune(settings); } -- GitLab From f392fb46889f6db2cdd9b480824ba956af05ad51 Mon Sep 17 00:00:00 2001 From: xshu Date: Thu, 13 Aug 2020 16:57:00 -0700 Subject: [PATCH 112/790] Attach timestamp to ringbuffer generated files The file last modified time expressed in seconds from epoch is attached to only the archived version of the file that is passed to dumpstate. Files stored on the device will still have no timestamp in their name. Bug: 159808285 Test: manual verification adb root adb shell lshal debug android.hardware.wifi@1.5::IWifi >> archive.cpio cpio -iv < archive.cpio Verify that a timestamp is attached to the filename at the end: connectivity_events_rbhOVjYpDdNY-1597364258 Change-Id: Iee0c2b37fc1d27cb979ec9125461416cd2d02549 --- wifi/1.5/default/wifi_chip.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/wifi/1.5/default/wifi_chip.cpp b/wifi/1.5/default/wifi_chip.cpp index 069fd65054..8f0e0005c3 100644 --- a/wifi/1.5/default/wifi_chip.cpp +++ b/wifi/1.5/default/wifi_chip.cpp @@ -281,9 +281,6 @@ size_t cpioArchiveFilesInDir(int out_fd, const char* input_dir) { continue; } std::string cur_file_name(dp->d_name); - // 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 = cur_file_name.size() + 1; struct stat st; const std::string cur_file_path = kTombstoneFolderPath + cur_file_name; if (stat(cur_file_path.c_str(), &st) == -1) { @@ -297,8 +294,15 @@ size_t cpioArchiveFilesInDir(int out_fd, const char* input_dir) { n_error++; continue; } + std::string file_name_with_last_modified_time = + 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; unique_fd file_auto_closer(fd_read); - if (!cpioWriteHeader(out_fd, st, cur_file_name.c_str(), + if (!cpioWriteHeader(out_fd, st, + file_name_with_last_modified_time.c_str(), file_name_len)) { return ++n_error; } -- GitLab From 5ebbfe417c8269328848a42d8b845fdaaff744a5 Mon Sep 17 00:00:00 2001 From: Mikhail Naganov Date: Wed, 22 Jul 2020 22:58:25 +0000 Subject: [PATCH 113/790] Audio: Update and fix copyHAL script Make necessary updates and fixes to produce HAL V7 and VTS. Bug: 142480271 Test: audio/common/all-versions/copyHAL.sh 6.0 7.0 && atest --rebuild-module-info -b VtsHalAudioV7_0TargetTest && m Change-Id: I5bc2344dae611fbf7e3e0fef185deee999c4aefa --- audio/common/all-versions/copyHAL.sh | 31 ++++++++++++++++++---------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/audio/common/all-versions/copyHAL.sh b/audio/common/all-versions/copyHAL.sh index 0a32a51275..23e057a6f7 100755 --- a/audio/common/all-versions/copyHAL.sh +++ b/audio/common/all-versions/copyHAL.sh @@ -16,6 +16,7 @@ fi readonly HAL_DIRECTORY=hardware/interfaces/audio readonly HAL_VTS_DIRECTORY=core/all-versions/vts/functional readonly HAL_VTS_FILE=AudioPrimaryHidlHalTest.cpp +readonly HAL_EFFECT_VTS_DIRECTORY=effect/all-versions/vts/functional readonly HAL_SERVICE_DIRECTORY=common/all-versions/default/service/ readonly HAL_SERVICE_CPP=service.cpp @@ -25,7 +26,7 @@ readonly IMPL_FACTORYHAL=FactoryHalHidl.cpp readonly VTS_DIRECTORY=test/vts-testcase/hal/audio readonly VTS_LIST=test/vts/tools/build/tasks/list/vts_test_lib_hidl_package_list.mk -readonly WATCHDOG=frameworks/base/services/core/java/com/android/server/Watchdog.cpp +readonly WATCHDOG=frameworks/base/services/core/java/com/android/server/Watchdog.java readonly DUMP_UTILS=frameworks/native/libs/dumputils/dump_utils.cpp readonly GSI_CURRENT=build/make/target/product/gsi/current.txt @@ -45,6 +46,9 @@ readonly NEW_VERSION_REGEX="${NEW_MAJOR_VERSION}[._]${NEW_MINOR_VERSION}" readonly BASE_VERSION_ESCAPE="${BASE_MAJOR_VERSION}\.${BASE_MINOR_VERSION}" readonly BASE_VERSION_UNDERSCORE="${BASE_MAJOR_VERSION}_${BASE_MINOR_VERSION}" readonly NEW_VERSION_UNDERSCORE="${NEW_MAJOR_VERSION}_${NEW_MINOR_VERSION}" + +readonly HAL_VTS_CONFIG_FILE_GLOB="*Audio*V${BASE_VERSION_UNDERSCORE}*Test.xml" + updateVersion() { if [ $1 == "-e" ]; then local -r REGEX="$2"; shift 2 @@ -71,6 +75,10 @@ updateAudioVersion() { updateVersion -e "audio.*$BASE_VERSION_REGEX" "$@" } +updateAudioVtsTargetVersion() { + updateVersion -e "Audio.*V$BASE_VERSION_REGEX" "$@" +} + updateLicenceDates() { # Update date on the 2 first lines sed -i "1,2 s/20[0-9][0-9]/$(date +"%Y")/g" "$@" @@ -101,9 +109,16 @@ createHALVersion() { cp -Tar $DIR/$BASE_VERSION $DIR/$NEW_VERSION COPY+=" $DIR/$NEW_VERSION" done + local COPY_FILES_TO= + for FILE_FROM in $(find . -type f -name "$HAL_VTS_CONFIG_FILE_GLOB"); do + local FILE_TO=${FILE_FROM/$BASE_VERSION_UNDERSCORE/$NEW_VERSION_UNDERSCORE} + cp "$FILE_FROM" "$FILE_TO" + COPY_FILES_TO+=" $FILE_TO" + done echo "Replacing $BASE_VERSION by $NEW_VERSION in the copied files" updateVersion $(find $COPY -type f) + updateVersion $COPY_FILES_TO updateLicenceDates $(find $COPY -type f) echo "Update implementation and VTS generic code" @@ -156,18 +171,12 @@ createFrameworkAdapter() { echo "Now creating the framework adapter version" runIfNeeded $FWK_DIRECTORY createFrameworkAdapter -createVTSXML() { - cp -Tar V$BASE_VERSION_UNDERSCORE V$NEW_VERSION_UNDERSCORE - cp -Tar effect/{V$BASE_VERSION_UNDERSCORE,V$NEW_VERSION_UNDERSCORE} - local -r FILES=$(find {.,effect}/V$NEW_VERSION_UNDERSCORE -type f) - updateVersion $FILES - updateLicenceDates $FILES -} -echo "Now update VTS XML" -runIfNeeded $VTS_DIRECTORY createVTSXML - echo "Now register new VTS" +PREV_MODIFIED="$MODIFIED" runIfNeeded $(dirname $VTS_LIST) updateAudioVersion -v original_before=1 $(basename $VTS_LIST) +if [[ "$PREV_MODIFIED" != "$MODIFIED" ]]; then + updateAudioVtsTargetVersion -v original_after=1 $(basename $VTS_LIST) +fi echo "Now update watchdog" runIfNeeded $(dirname $WATCHDOG) updateAudioVersion -v original_before=1 $(basename $WATCHDOG) -- GitLab From 159260c58602c552b95715b3db9a47e5c8f670b0 Mon Sep 17 00:00:00 2001 From: Mikhail Naganov Date: Thu, 23 Jul 2020 18:08:26 +0000 Subject: [PATCH 114/790] Audio: Copy HAL V6 into V7 This is an automated copy performed using copyHAL.sh script. Bug: 142480271 Test: m Change-Id: Ifd91cc0bb59608cd92d1d8e4e76c3abea0a8da5e --- audio/7.0/Android.bp | 25 + audio/7.0/IDevice.hal | 346 +++++ audio/7.0/IDevicesFactory.hal | 70 + audio/7.0/IPrimaryDevice.hal | 195 +++ audio/7.0/IStream.hal | 317 +++++ audio/7.0/IStreamIn.hal | 199 +++ audio/7.0/IStreamOut.hal | 378 ++++++ audio/7.0/IStreamOutCallback.hal | 37 + audio/7.0/IStreamOutEventCallback.hal | 140 ++ audio/7.0/config/Android.bp | 5 + audio/7.0/config/api/current.txt | 435 ++++++ audio/7.0/config/api/last_current.txt | 0 audio/7.0/config/api/last_removed.txt | 0 audio/7.0/config/api/removed.txt | 1 + .../7.0/config/audio_policy_configuration.xsd | 634 +++++++++ audio/7.0/types.hal | 357 +++++ audio/common/7.0/Android.bp | 14 + audio/common/7.0/types.hal | 1191 +++++++++++++++++ audio/common/all-versions/default/Android.bp | 13 + audio/core/all-versions/default/Android.bp | 15 + .../7.0/AudioPrimaryHidlHalTest.cpp | 18 + .../all-versions/vts/functional/Android.bp | 23 + .../functional/VtsHalAudioV7_0TargetTest.xml | 38 + audio/effect/7.0/Android.bp | 30 + .../7.0/IAcousticEchoCancelerEffect.hal | 32 + .../7.0/IAutomaticGainControlEffect.hal | 68 + audio/effect/7.0/IBassBoostEffect.hal | 48 + audio/effect/7.0/IDownmixEffect.hal | 37 + audio/effect/7.0/IEffect.hal | 421 ++++++ .../7.0/IEffectBufferProviderCallback.hal | 38 + audio/effect/7.0/IEffectsFactory.hal | 62 + .../effect/7.0/IEnvironmentalReverbEffect.hal | 178 +++ audio/effect/7.0/IEqualizerEffect.hal | 93 ++ audio/effect/7.0/ILoudnessEnhancerEffect.hal | 32 + audio/effect/7.0/INoiseSuppressionEffect.hal | 68 + audio/effect/7.0/IPresetReverbEffect.hal | 43 + audio/effect/7.0/IVirtualizerEffect.hal | 77 ++ audio/effect/7.0/IVisualizerEffect.hal | 110 ++ audio/effect/7.0/types.hal | 301 +++++ audio/effect/7.0/xml/Android.bp | 5 + audio/effect/7.0/xml/api/current.txt | 208 +++ audio/effect/7.0/xml/api/last_current.txt | 0 audio/effect/7.0/xml/api/last_removed.txt | 0 audio/effect/7.0/xml/api/removed.txt | 1 + audio/effect/7.0/xml/audio_effects_conf.xsd | 323 +++++ audio/effect/all-versions/default/Android.bp | 15 + .../all-versions/vts/functional/Android.bp | 20 + .../VtsHalAudioEffectV7_0TargetTest.xml | 38 + 48 files changed, 6699 insertions(+) create mode 100644 audio/7.0/Android.bp create mode 100644 audio/7.0/IDevice.hal create mode 100644 audio/7.0/IDevicesFactory.hal create mode 100644 audio/7.0/IPrimaryDevice.hal create mode 100644 audio/7.0/IStream.hal create mode 100644 audio/7.0/IStreamIn.hal create mode 100644 audio/7.0/IStreamOut.hal create mode 100644 audio/7.0/IStreamOutCallback.hal create mode 100644 audio/7.0/IStreamOutEventCallback.hal create mode 100644 audio/7.0/config/Android.bp create mode 100644 audio/7.0/config/api/current.txt create mode 100644 audio/7.0/config/api/last_current.txt create mode 100644 audio/7.0/config/api/last_removed.txt create mode 100644 audio/7.0/config/api/removed.txt create mode 100644 audio/7.0/config/audio_policy_configuration.xsd create mode 100644 audio/7.0/types.hal create mode 100644 audio/common/7.0/Android.bp create mode 100644 audio/common/7.0/types.hal create mode 100644 audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp create mode 100644 audio/core/all-versions/vts/functional/VtsHalAudioV7_0TargetTest.xml create mode 100644 audio/effect/7.0/Android.bp create mode 100644 audio/effect/7.0/IAcousticEchoCancelerEffect.hal create mode 100644 audio/effect/7.0/IAutomaticGainControlEffect.hal create mode 100644 audio/effect/7.0/IBassBoostEffect.hal create mode 100644 audio/effect/7.0/IDownmixEffect.hal create mode 100644 audio/effect/7.0/IEffect.hal create mode 100644 audio/effect/7.0/IEffectBufferProviderCallback.hal create mode 100644 audio/effect/7.0/IEffectsFactory.hal create mode 100644 audio/effect/7.0/IEnvironmentalReverbEffect.hal create mode 100644 audio/effect/7.0/IEqualizerEffect.hal create mode 100644 audio/effect/7.0/ILoudnessEnhancerEffect.hal create mode 100644 audio/effect/7.0/INoiseSuppressionEffect.hal create mode 100644 audio/effect/7.0/IPresetReverbEffect.hal create mode 100644 audio/effect/7.0/IVirtualizerEffect.hal create mode 100644 audio/effect/7.0/IVisualizerEffect.hal create mode 100644 audio/effect/7.0/types.hal create mode 100644 audio/effect/7.0/xml/Android.bp create mode 100644 audio/effect/7.0/xml/api/current.txt create mode 100644 audio/effect/7.0/xml/api/last_current.txt create mode 100644 audio/effect/7.0/xml/api/last_removed.txt create mode 100644 audio/effect/7.0/xml/api/removed.txt create mode 100644 audio/effect/7.0/xml/audio_effects_conf.xsd create mode 100644 audio/effect/all-versions/vts/functional/VtsHalAudioEffectV7_0TargetTest.xml diff --git a/audio/7.0/Android.bp b/audio/7.0/Android.bp new file mode 100644 index 0000000000..d07ce1284a --- /dev/null +++ b/audio/7.0/Android.bp @@ -0,0 +1,25 @@ +// This file is autogenerated by hidl-gen -Landroidbp. + +hidl_interface { + name: "android.hardware.audio@7.0", + root: "android.hardware", + srcs: [ + "types.hal", + "IDevice.hal", + "IDevicesFactory.hal", + "IPrimaryDevice.hal", + "IStream.hal", + "IStreamIn.hal", + "IStreamOut.hal", + "IStreamOutCallback.hal", + "IStreamOutEventCallback.hal", + ], + interfaces: [ + "android.hardware.audio.common@7.0", + "android.hardware.audio.effect@7.0", + "android.hidl.base@1.0", + "android.hidl.safe_union@1.0", + ], + gen_java: false, + gen_java_constants: true, +} diff --git a/audio/7.0/IDevice.hal b/audio/7.0/IDevice.hal new file mode 100644 index 0000000000..7082d6b7ab --- /dev/null +++ b/audio/7.0/IDevice.hal @@ -0,0 +1,346 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.audio@7.0; + +import android.hardware.audio.common@7.0; +import IStreamIn; +import IStreamOut; + +interface IDevice { + /** + * Returns whether the audio hardware interface has been initialized. + * + * @return retval OK on success, NOT_INITIALIZED on failure. + */ + initCheck() generates (Result retval); + + /** + * Sets the audio volume for all audio activities other than voice call. If + * NOT_SUPPORTED is returned, the software mixer will emulate this + * capability. + * + * @param volume 1.0f means unity, 0.0f is zero. + * @return retval operation completion status. + */ + setMasterVolume(float volume) generates (Result retval); + + /** + * Get the current master volume value for the HAL, if the HAL supports + * master volume control. For example, AudioFlinger will query this value + * from the primary audio HAL when the service starts and use the value for + * setting the initial master volume across all HALs. HALs which do not + * support this method must return NOT_SUPPORTED in 'retval'. + * + * @return retval operation completion status. + * @return volume 1.0f means unity, 0.0f is zero. + */ + getMasterVolume() generates (Result retval, float volume); + + /** + * Sets microphone muting state. + * + * @param mute whether microphone is muted. + * @return retval operation completion status. + */ + setMicMute(bool mute) generates (Result retval); + + /** + * Gets whether microphone is muted. + * + * @return retval operation completion status. + * @return mute whether microphone is muted. + */ + getMicMute() generates (Result retval, bool mute); + + /** + * Set the audio mute status for all audio activities. If the return value + * is NOT_SUPPORTED, the software mixer will emulate this capability. + * + * @param mute whether audio is muted. + * @return retval operation completion status. + */ + setMasterMute(bool mute) generates (Result retval); + + /** + * Get the current master mute status for the HAL, if the HAL supports + * master mute control. AudioFlinger will query this value from the primary + * audio HAL when the service starts and use the value for setting the + * initial master mute across all HALs. HAL must indicate that the feature + * is not supported by returning NOT_SUPPORTED status. + * + * @return retval operation completion status. + * @return mute whether audio is muted. + */ + getMasterMute() generates (Result retval, bool mute); + + /** + * Returns audio input buffer size according to parameters passed or + * INVALID_ARGUMENTS if one of the parameters is not supported. + * + * @param config audio configuration. + * @return retval operation completion status. + * @return bufferSize input buffer size in bytes. + */ + getInputBufferSize(AudioConfig config) + generates (Result retval, uint64_t bufferSize); + + /** + * This method creates and opens the audio hardware output stream. + * If the stream can not be opened with the proposed audio config, + * HAL must provide suggested values for the audio config. + * + * @param ioHandle handle assigned by AudioFlinger. + * @param device device type and (if needed) address. + * @param config stream configuration. + * @param flags additional flags. + * @param sourceMetadata Description of the audio that will be played. + May be used by implementations to configure hardware effects. + * @return retval operation completion status. + * @return outStream created output stream. + * @return suggestedConfig in case of invalid parameters, suggested config. + */ + openOutputStream( + AudioIoHandle ioHandle, + DeviceAddress device, + AudioConfig config, + bitfield flags, + SourceMetadata sourceMetadata) generates ( + Result retval, + IStreamOut outStream, + AudioConfig suggestedConfig); + + /** + * This method creates and opens the audio hardware input stream. + * If the stream can not be opened with the proposed audio config, + * HAL must provide suggested values for the audio config. + * + * @param ioHandle handle assigned by AudioFlinger. + * @param device device type and (if needed) address. + * @param config stream configuration. + * @param flags additional flags. + * @param sinkMetadata Description of the audio that is suggested by the client. + * May be used by implementations to configure processing effects. + * @return retval operation completion status. + * @return inStream in case of success, created input stream. + * @return suggestedConfig in case of invalid parameters, suggested config. + */ + openInputStream( + AudioIoHandle ioHandle, + DeviceAddress device, + AudioConfig config, + bitfield flags, + SinkMetadata sinkMetadata) generates ( + Result retval, + IStreamIn inStream, + AudioConfig suggestedConfig); + + /** + * Returns whether HAL supports audio patches. Patch represents a connection + * between signal source(s) and signal sink(s). If HAL doesn't support + * patches natively (in hardware) then audio system will need to establish + * them in software. + * + * @return supports true if audio patches are supported. + */ + supportsAudioPatches() generates (bool supports); + + /** + * Creates an audio patch between several source and sink ports. The handle + * is allocated by the HAL and must be unique for this audio HAL module. + * + * @param sources patch sources. + * @param sinks patch sinks. + * @return retval operation completion status. + * @return patch created patch handle. + */ + createAudioPatch(vec sources, vec sinks) + generates (Result retval, AudioPatchHandle patch); + + /** + * Updates an audio patch. + * + * Use of this function is preferred to releasing and re-creating a patch + * as the HAL module can figure out a way of switching the route without + * causing audio disruption. + * + * @param previousPatch handle of the previous patch to update. + * @param sources new patch sources. + * @param sinks new patch sinks. + * @return retval operation completion status. + * @return patch updated patch handle. + */ + updateAudioPatch( + AudioPatchHandle previousPatch, + vec sources, + vec sinks) generates ( + Result retval, AudioPatchHandle patch); + + /** + * Release an audio patch. + * + * @param patch patch handle. + * @return retval operation completion status. + */ + releaseAudioPatch(AudioPatchHandle patch) generates (Result retval); + + /** + * Returns the list of supported attributes for a given audio port. + * + * As input, 'port' contains the information (type, role, address etc...) + * needed by the HAL to identify the port. + * + * As output, 'resultPort' contains possible attributes (sampling rates, + * formats, channel masks, gain controllers...) for this port. + * + * @param port port identifier. + * @return retval operation completion status. + * @return resultPort port descriptor with all parameters filled up. + */ + getAudioPort(AudioPort port) + generates (Result retval, AudioPort resultPort); + + /** + * Set audio port configuration. + * + * @param config audio port configuration. + * @return retval operation completion status. + */ + setAudioPortConfig(AudioPortConfig config) generates (Result retval); + + /** + * Gets the HW synchronization source of the device. Calling this method is + * equivalent to getting AUDIO_PARAMETER_HW_AV_SYNC on the legacy HAL. + * Optional method + * + * @return retval operation completion status: OK or NOT_SUPPORTED. + * @return hwAvSync HW synchronization source + */ + getHwAvSync() generates (Result retval, AudioHwSync hwAvSync); + + /** + * Sets whether the screen is on. Calling this method is equivalent to + * setting AUDIO_PARAMETER_KEY_SCREEN_STATE on the legacy HAL. + * Optional method + * + * @param turnedOn whether the screen is turned on. + * @return retval operation completion status. + */ + setScreenState(bool turnedOn) generates (Result retval); + + /** + * Generic method for retrieving vendor-specific parameter values. + * The framework does not interpret the parameters, they are passed + * in an opaque manner between a vendor application and HAL. + * + * Multiple parameters can be retrieved at the same time. + * The implementation should return as many requested parameters + * as possible, even if one or more is not supported + * + * @param context provides more information about the request + * @param keys keys of the requested parameters + * @return retval operation completion status. + * OK must be returned if keys is empty. + * NOT_SUPPORTED must be returned if at least one key is unknown. + * @return parameters parameter key value pairs. + * Must contain the value of all requested keys if retval == OK + */ + getParameters(vec context, vec keys) + generates (Result retval, vec parameters); + + /** + * Generic method for setting vendor-specific parameter values. + * The framework does not interpret the parameters, they are passed + * in an opaque manner between a vendor application and HAL. + * + * Multiple parameters can be set at the same time though this is + * discouraged as it make failure analysis harder. + * + * If possible, a failed setParameters should not impact the platform state. + * + * @param context provides more information about the request + * @param parameters parameter key value pairs. + * @return retval operation completion status. + * All parameters must be successfully set for OK to be returned + */ + setParameters(vec context, vec parameters) + generates (Result retval); + + /** + * Returns an array with available microphones in device. + * + * @return retval NOT_SUPPORTED if there are no microphones on this device + * INVALID_STATE if the call is not successful, + * OK otherwise. + * + * @return microphones array with microphones info + */ + getMicrophones() + generates(Result retval, vec microphones); + + /** + * Notifies the device module about the connection state of an input/output + * device attached to it. Calling this method is equivalent to setting + * AUDIO_PARAMETER_DEVICE_[DIS]CONNECT on the legacy HAL. + * + * @param address audio device specification. + * @param connected whether the device is connected. + * @return retval operation completion status. + */ + setConnectedState(DeviceAddress address, bool connected) + generates (Result retval); + + /** + * Called by the framework to deinitialize the device and free up + * all currently allocated resources. It is recommended to close + * the device on the client side as soon as it is becomes unused. + * + * Note that all streams must be closed by the client before + * attempting to close the device they belong to. + * + * @return retval OK in case the success. + * INVALID_STATE if the device was already closed + * or there are streams currently opened. + */ + @exit + close() generates (Result retval); + + /** + * Applies an audio effect to an audio device. The effect is inserted + * according to its insertion preference specified by INSERT_... EffectFlags + * in the EffectDescriptor. + * + * @param device identifies the sink or source device this effect must be applied to. + * "device" is the AudioPortHandle indicated for the device when the audio + * patch connecting that device was created. + * @param effectId effect ID (obtained from IEffectsFactory.createEffect) of + * the effect to add. + * @return retval operation completion status. + */ + addDeviceEffect(AudioPortHandle device, uint64_t effectId) generates (Result retval); + + /** + * Stops applying an audio effect to an audio device. + * + * @param device identifies the sink or source device this effect was applied to. + * "device" is the AudioPortHandle indicated for the device when the audio + * patch is created at the audio HAL. + * @param effectId effect ID (obtained from IEffectsFactory.createEffect) of + * the effect. + * @return retval operation completion status. + */ + removeDeviceEffect(AudioPortHandle device, uint64_t effectId) generates (Result retval); +}; diff --git a/audio/7.0/IDevicesFactory.hal b/audio/7.0/IDevicesFactory.hal new file mode 100644 index 0000000000..03549b4267 --- /dev/null +++ b/audio/7.0/IDevicesFactory.hal @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.audio@7.0; + +import android.hardware.audio.common@7.0; +import IDevice; +import IPrimaryDevice; + +/** This factory allows a HAL implementation to be split in multiple independent + * devices (called module in the pre-treble API). + * Note that this division is arbitrary and implementation are free + * to only have a Primary. + * The framework will query the devices according to audio_policy_configuration.xml + * + * Each device name is arbitrary, provided by the vendor's audio_policy_configuration.xml + * and only used to identify a device in this factory. + * The framework must not interpret the name, treating it as a vendor opaque data + * with the following exception: + * - the "r_submix" device that must be present to support policyMixes (Eg: Android projected). + * Note that this Device is included by default in a build derived from AOSP. + * + * Note that on AOSP Oreo (including MR1) the "a2dp" module is not using this API + * but is loaded directly from the system partition using the legacy API + * due to limitations with the Bluetooth framework. + */ +interface IDevicesFactory { + + /** + * Opens an audio device. To close the device, it is necessary to release + * references to the returned device object. + * + * @param device device name. + * @return retval operation completion status. Returns INVALID_ARGUMENTS + * if there is no corresponding hardware module found, + * NOT_INITIALIZED if an error occurred while opening the hardware + * module. + * @return result the interface for the created device. + */ + openDevice(string device) generates (Result retval, IDevice result); + + /** + * Opens the Primary audio device that must be present. + * This function is not optional and must return successfully the primary device. + * + * This device must have the name "primary". + * + * The telephony stack uses this device to control the audio during a voice call. + * + * @return retval operation completion status. Must be SUCCESS. + * For debugging, return INVALID_ARGUMENTS if there is no corresponding + * hardware module found, NOT_INITIALIZED if an error occurred + * while opening the hardware module. + * @return result the interface for the created device. + */ + openPrimaryDevice() generates (Result retval, IPrimaryDevice result); +}; diff --git a/audio/7.0/IPrimaryDevice.hal b/audio/7.0/IPrimaryDevice.hal new file mode 100644 index 0000000000..1427ae8191 --- /dev/null +++ b/audio/7.0/IPrimaryDevice.hal @@ -0,0 +1,195 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.audio@7.0; + +import android.hardware.audio.common@7.0; +import IDevice; + +interface IPrimaryDevice extends IDevice { + /** + * Sets the audio volume of a voice call. + * + * @param volume 1.0f means unity, 0.0f is zero. + * @return retval operation completion status. + */ + setVoiceVolume(float volume) generates (Result retval); + + /** + * This method is used to notify the HAL about audio mode changes. + * + * @param mode new mode. + * @return retval operation completion status. + */ + setMode(AudioMode mode) generates (Result retval); + + /** + * Sets the name of the current BT SCO headset. Calling this method + * is equivalent to setting legacy "bt_headset_name" parameter. + * The BT SCO headset name must only be used for debugging purposes. + * Optional method + * + * @param name the name of the current BT SCO headset (can be empty). + * @return retval operation completion status. + */ + setBtScoHeadsetDebugName(string name) generates (Result retval); + + /** + * Gets whether BT SCO Noise Reduction and Echo Cancellation are enabled. + * Calling this method is equivalent to getting AUDIO_PARAMETER_KEY_BT_NREC + * on the legacy HAL. + * + * @return retval operation completion status. + * @return enabled whether BT SCO NR + EC are enabled. + */ + getBtScoNrecEnabled() generates (Result retval, bool enabled); + + /** + * Sets whether BT SCO Noise Reduction and Echo Cancellation are enabled. + * Calling this method is equivalent to setting AUDIO_PARAMETER_KEY_BT_NREC + * on the legacy HAL. + * Optional method + * + * @param enabled whether BT SCO NR + EC are enabled. + * @return retval operation completion status. + */ + setBtScoNrecEnabled(bool enabled) generates (Result retval); + + /** + * Gets whether BT SCO Wideband mode is enabled. Calling this method is + * equivalent to getting AUDIO_PARAMETER_KEY_BT_SCO_WB on the legacy HAL. + * + * @return retval operation completion status. + * @return enabled whether BT Wideband is enabled. + */ + getBtScoWidebandEnabled() generates (Result retval, bool enabled); + + /** + * Sets whether BT SCO Wideband mode is enabled. Calling this method is + * equivalent to setting AUDIO_PARAMETER_KEY_BT_SCO_WB on the legacy HAL. + * Optional method + * + * @param enabled whether BT Wideband is enabled. + * @return retval operation completion status. + */ + setBtScoWidebandEnabled(bool enabled) generates (Result retval); + + /** + * Gets whether BT HFP (Hands-Free Profile) is enabled. Calling this method + * is equivalent to getting "hfp_enable" parameter value on the legacy HAL. + * + * @return retval operation completion status. + * @return enabled whether BT HFP is enabled. + */ + getBtHfpEnabled() generates (Result retval, bool enabled); + + /** + * Sets whether BT HFP (Hands-Free Profile) is enabled. Calling this method + * is equivalent to setting "hfp_enable" parameter on the legacy HAL. + * Optional method + * + * @param enabled whether BT HFP is enabled. + * @return retval operation completion status. + */ + setBtHfpEnabled(bool enabled) generates (Result retval); + + /** + * Sets the sampling rate of BT HFP (Hands-Free Profile). Calling this + * method is equivalent to setting "hfp_set_sampling_rate" parameter + * on the legacy HAL. + * Optional method + * + * @param sampleRateHz sample rate in Hz. + * @return retval operation completion status. + */ + setBtHfpSampleRate(uint32_t sampleRateHz) generates (Result retval); + + /** + * Sets the current output volume Hz for BT HFP (Hands-Free Profile). + * Calling this method is equivalent to setting "hfp_volume" parameter value + * on the legacy HAL (except that legacy HAL implementations expect + * an integer value in the range from 0 to 15.) + * Optional method + * + * @param volume 1.0f means unity, 0.0f is zero. + * @return retval operation completion status. + */ + setBtHfpVolume(float volume) generates (Result retval); + + enum TtyMode : int32_t { + OFF, + VCO, + HCO, + FULL + }; + + /** + * Gets current TTY mode selection. Calling this method is equivalent to + * getting AUDIO_PARAMETER_KEY_TTY_MODE on the legacy HAL. + * + * @return retval operation completion status. + * @return mode TTY mode. + */ + getTtyMode() generates (Result retval, TtyMode mode); + + /** + * Sets current TTY mode. Calling this method is equivalent to setting + * AUDIO_PARAMETER_KEY_TTY_MODE on the legacy HAL. + * + * @param mode TTY mode. + * @return retval operation completion status. + */ + setTtyMode(TtyMode mode) generates (Result retval); + + /** + * Gets whether Hearing Aid Compatibility - Telecoil (HAC-T) mode is + * enabled. Calling this method is equivalent to getting + * AUDIO_PARAMETER_KEY_HAC on the legacy HAL. + * + * @return retval operation completion status. + * @return enabled whether HAC mode is enabled. + */ + getHacEnabled() generates (Result retval, bool enabled); + + /** + * Sets whether Hearing Aid Compatibility - Telecoil (HAC-T) mode is + * enabled. Calling this method is equivalent to setting + * AUDIO_PARAMETER_KEY_HAC on the legacy HAL. + * Optional method + * + * @param enabled whether HAC mode is enabled. + * @return retval operation completion status. + */ + setHacEnabled(bool enabled) generates (Result retval); + + enum Rotation : int32_t { + DEG_0, + DEG_90, + DEG_180, + DEG_270 + }; + + /** + * Updates HAL on the current rotation of the device relative to natural + * orientation. Calling this method is equivalent to setting legacy + * parameter "rotation". + * + * @param rotation rotation in degrees relative to natural device + * orientation. + * @return retval operation completion status. + */ + updateRotation(Rotation rotation) generates (Result retval); +}; diff --git a/audio/7.0/IStream.hal b/audio/7.0/IStream.hal new file mode 100644 index 0000000000..dacd3fd342 --- /dev/null +++ b/audio/7.0/IStream.hal @@ -0,0 +1,317 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.audio@7.0; + +import android.hardware.audio.common@7.0; +import android.hardware.audio.effect@7.0::IEffect; + +interface IStream { + /** + * Return the frame size (number of bytes per sample). + * + * @return frameSize frame size in bytes. + */ + getFrameSize() generates (uint64_t frameSize); + + /** + * Return the frame count of the buffer. Calling this method is equivalent + * to getting AUDIO_PARAMETER_STREAM_FRAME_COUNT on the legacy HAL. + * + * @return count frame count. + */ + getFrameCount() generates (uint64_t count); + + /** + * Return the size of input/output buffer in bytes for this stream. + * It must be a multiple of the frame size. + * + * @return buffer buffer size in bytes. + */ + getBufferSize() generates (uint64_t bufferSize); + + /** + * Return the sampling rate in Hz. + * + * @return sampleRateHz sample rate in Hz. + */ + getSampleRate() generates (uint32_t sampleRateHz); + + /** + * Return supported native sampling rates of the stream for a given format. + * A supported native sample rate is a sample rate that can be efficiently + * played by the hardware (typically without sample-rate conversions). + * + * This function is only called for dynamic profile. If called for + * non-dynamic profile is should return NOT_SUPPORTED or the same list + * as in audio_policy_configuration.xml. + * + * Calling this method is equivalent to getting + * AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES on the legacy HAL. + * + * + * @param format audio format for which the sample rates are supported. + * @return retval operation completion status. + * Must be OK if the format is supported. + * @return sampleRateHz supported sample rates. + */ + getSupportedSampleRates(AudioFormat format) + generates (Result retval, vec sampleRates); + + /** + * Sets the sampling rate of the stream. Calling this method is equivalent + * to setting AUDIO_PARAMETER_STREAM_SAMPLING_RATE on the legacy HAL. + * Optional method. If implemented, only called on a stopped stream. + * + * @param sampleRateHz sample rate in Hz. + * @return retval operation completion status. + */ + setSampleRate(uint32_t sampleRateHz) generates (Result retval); + + /** + * Return the channel mask of the stream. + * + * @return mask channel mask. + */ + getChannelMask() generates (bitfield mask); + + /** + * Return supported channel masks of the stream. Calling this method is + * equivalent to getting AUDIO_PARAMETER_STREAM_SUP_CHANNELS on the legacy + * HAL. + * + * @param format audio format for which the channel masks are supported. + * @return retval operation completion status. + * Must be OK if the format is supported. + * @return masks supported audio masks. + */ + getSupportedChannelMasks(AudioFormat format) + generates (Result retval, vec> masks); + + /** + * Sets the channel mask of the stream. Calling this method is equivalent to + * setting AUDIO_PARAMETER_STREAM_CHANNELS on the legacy HAL. + * Optional method + * + * @param format audio format. + * @return retval operation completion status. + */ + setChannelMask(bitfield mask) generates (Result retval); + + /** + * Return the audio format of the stream. + * + * @return format audio format. + */ + getFormat() generates (AudioFormat format); + + /** + * Return supported audio formats of the stream. Calling this method is + * equivalent to getting AUDIO_PARAMETER_STREAM_SUP_FORMATS on the legacy + * HAL. + * + * @return retval operation completion status. + * @return formats supported audio formats. + * Must be non empty if retval is OK. + */ + getSupportedFormats() generates (Result retval, vec formats); + + /** + * Sets the audio format of the stream. Calling this method is equivalent to + * setting AUDIO_PARAMETER_STREAM_FORMAT on the legacy HAL. + * Optional method + * + * @param format audio format. + * @return retval operation completion status. + */ + setFormat(AudioFormat format) generates (Result retval); + + /** + * Convenience method for retrieving several stream parameters in + * one transaction. + * + * @return sampleRateHz sample rate in Hz. + * @return mask channel mask. + * @return format audio format. + */ + getAudioProperties() generates ( + uint32_t sampleRateHz, bitfield mask, AudioFormat format); + + /** + * Applies audio effect to the stream. + * + * @param effectId effect ID (obtained from IEffectsFactory.createEffect) of + * the effect to apply. + * @return retval operation completion status. + */ + addEffect(uint64_t effectId) generates (Result retval); + + /** + * Stops application of the effect to the stream. + * + * @param effectId effect ID (obtained from IEffectsFactory.createEffect) of + * the effect to remove. + * @return retval operation completion status. + */ + removeEffect(uint64_t effectId) generates (Result retval); + + /** + * Put the audio hardware input/output into standby mode. + * Driver must exit from standby mode at the next I/O operation. + * + * @return retval operation completion status. + */ + standby() generates (Result retval); + + /** + * Return the set of devices which this stream is connected to. + * Optional method + * + * @return retval operation completion status: OK or NOT_SUPPORTED. + * @return device set of devices which this stream is connected to. + */ + getDevices() generates (Result retval, vec devices); + + /** + * Connects the stream to one or multiple devices. + * + * This method must only be used for HALs that do not support + * 'IDevice.createAudioPatch' method. Calling this method is + * equivalent to setting AUDIO_PARAMETER_STREAM_ROUTING preceded + * with a device address in the legacy HAL interface. + * + * @param address device to connect the stream to. + * @return retval operation completion status. + */ + setDevices(vec devices) generates (Result retval); + + /** + * Sets the HW synchronization source. Calling this method is equivalent to + * setting AUDIO_PARAMETER_STREAM_HW_AV_SYNC on the legacy HAL. + * Optional method + * + * @param hwAvSync HW synchronization source + * @return retval operation completion status. + */ + setHwAvSync(AudioHwSync hwAvSync) generates (Result retval); + + /** + * Generic method for retrieving vendor-specific parameter values. + * The framework does not interpret the parameters, they are passed + * in an opaque manner between a vendor application and HAL. + * + * Multiple parameters can be retrieved at the same time. + * The implementation should return as many requested parameters + * as possible, even if one or more is not supported + * + * @param context provides more information about the request + * @param keys keys of the requested parameters + * @return retval operation completion status. + * OK must be returned if keys is empty. + * NOT_SUPPORTED must be returned if at least one key is unknown. + * @return parameters parameter key value pairs. + * Must contain the value of all requested keys if retval == OK + */ + getParameters(vec context, vec keys) + generates (Result retval, vec parameters); + + /** + * Generic method for setting vendor-specific parameter values. + * The framework does not interpret the parameters, they are passed + * in an opaque manner between a vendor application and HAL. + * + * Multiple parameters can be set at the same time though this is + * discouraged as it make failure analysis harder. + * + * If possible, a failed setParameters should not impact the platform state. + * + * @param context provides more information about the request + * @param parameters parameter key value pairs. + * @return retval operation completion status. + * All parameters must be successfully set for OK to be returned + */ + setParameters(vec context, vec parameters) + generates (Result retval); + + /** + * Called by the framework to start a stream operating in mmap mode. + * createMmapBuffer() must be called before calling start(). + * Function only implemented by streams operating in mmap mode. + * + * @return retval OK in case the success. + * NOT_SUPPORTED on non mmap mode streams + * INVALID_STATE if called out of sequence + */ + start() generates (Result retval); + + /** + * Called by the framework to stop a stream operating in mmap mode. + * Function only implemented by streams operating in mmap mode. + * + * @return retval OK in case the success. + * NOT_SUPPORTED on non mmap mode streams + * INVALID_STATE if called out of sequence + */ + stop() generates (Result retval) ; + + /** + * Called by the framework to retrieve information on the mmap buffer used for audio + * samples transfer. + * Function only implemented by streams operating in mmap mode. + * + * @param minSizeFrames minimum buffer size requested. The actual buffer + * size returned in struct MmapBufferInfo can be larger. + * The size must be a positive value. + * @return retval OK in case the success. + * NOT_SUPPORTED on non mmap mode streams + * NOT_INITIALIZED in case of memory allocation error + * INVALID_ARGUMENTS if the requested buffer size is invalid + * INVALID_STATE if called out of sequence + * @return info a MmapBufferInfo struct containing information on the MMMAP buffer created. + */ + createMmapBuffer(int32_t minSizeFrames) + generates (Result retval, MmapBufferInfo info); + + /** + * Called by the framework to read current read/write position in the mmap buffer + * with associated time stamp. + * Function only implemented by streams operating in mmap mode. + * + * @return retval OK in case the success. + * NOT_SUPPORTED on non mmap mode streams + * INVALID_STATE if called out of sequence + * @return position a MmapPosition struct containing current HW read/write position in frames + * with associated time stamp. + */ + getMmapPosition() + generates (Result retval, MmapPosition position); + + /** + * Called by the framework to deinitialize the stream and free up + * all currently allocated resources. It is recommended to close + * the stream on the client side as soon as it is becomes unused. + * + * The client must ensure that this function is not called while + * audio data is being transferred through the stream's message queues. + * + * @return retval OK in case the success. + * NOT_SUPPORTED if called on IStream instead of input or + * output stream interface. + * INVALID_STATE if the stream was already closed. + */ + @exit + close() generates (Result retval); +}; diff --git a/audio/7.0/IStreamIn.hal b/audio/7.0/IStreamIn.hal new file mode 100644 index 0000000000..15e436359e --- /dev/null +++ b/audio/7.0/IStreamIn.hal @@ -0,0 +1,199 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.audio@7.0; + +import android.hardware.audio.common@7.0; +import IStream; + +interface IStreamIn extends IStream { + /** + * Returns the source descriptor of the input stream. Calling this method is + * equivalent to getting AUDIO_PARAMETER_STREAM_INPUT_SOURCE on the legacy + * HAL. + * Optional method + * + * @return retval operation completion status. + * @return source audio source. + */ + getAudioSource() generates (Result retval, AudioSource source); + + /** + * Set the input gain for the audio driver. + * Optional method + * + * @param gain 1.0f is unity, 0.0f is zero. + * @result retval operation completion status. + */ + setGain(float gain) generates (Result retval); + + /** + * Commands that can be executed on the driver reader thread. + */ + enum ReadCommand : int32_t { + READ, + GET_CAPTURE_POSITION + }; + + /** + * Data structure passed to the driver for executing commands + * on the driver reader thread. + */ + struct ReadParameters { + ReadCommand command; // discriminator + union Params { + uint64_t read; // READ command, amount of bytes to read, >= 0. + // No parameters for GET_CAPTURE_POSITION. + } params; + }; + + /** + * Data structure passed back to the client via status message queue + * of 'read' operation. + * + * Possible values of 'retval' field: + * - OK, read operation was successful; + * - INVALID_ARGUMENTS, stream was not configured properly; + * - INVALID_STATE, stream is in a state that doesn't allow reads. + */ + struct ReadStatus { + Result retval; + ReadCommand replyTo; // discriminator + union Reply { + uint64_t read; // READ command, amount of bytes read, >= 0. + struct CapturePosition { // same as generated by getCapturePosition. + uint64_t frames; + uint64_t time; + } capturePosition; + } reply; + }; + + /** + * Called when the metadata of the stream's sink has been changed. + * @param sinkMetadata Description of the audio that is suggested by the clients. + */ + updateSinkMetadata(SinkMetadata sinkMetadata); + + /** + * Set up required transports for receiving audio buffers from the driver. + * + * The transport consists of three message queues: + * -- command queue is used to instruct the reader thread what operation + * to perform; + * -- data queue is used for passing audio data from the driver + * to the client; + * -- status queue is used for reporting operation status + * (e.g. amount of bytes actually read or error code). + * + * The driver operates on a dedicated thread. The client must ensure that + * the thread is given an appropriate priority and assigned to correct + * scheduler and cgroup. For this purpose, the method returns identifiers + * of the driver thread. + * + * @param frameSize the size of a single frame, in bytes. + * @param framesCount the number of frames in a buffer. + * @param threadPriority priority of the driver thread. + * @return retval OK if both message queues were created successfully. + * INVALID_STATE if the method was already called. + * INVALID_ARGUMENTS if there was a problem setting up + * the queues. + * @return commandMQ a message queue used for passing commands. + * @return dataMQ a message queue used for passing audio data in the format + * specified at the stream opening. + * @return statusMQ a message queue used for passing status from the driver + * using ReadStatus structures. + * @return threadInfo identifiers of the driver's dedicated thread. + */ + prepareForReading(uint32_t frameSize, uint32_t framesCount) + generates ( + Result retval, + fmq_sync commandMQ, + fmq_sync dataMQ, + fmq_sync statusMQ, + ThreadInfo threadInfo); + + /** + * Return the amount of input frames lost in the audio driver since the last + * call of this function. + * + * Audio driver is expected to reset the value to 0 and restart counting + * upon returning the current value by this function call. Such loss + * typically occurs when the user space process is blocked longer than the + * capacity of audio driver buffers. + * + * @return framesLost the number of input audio frames lost. + */ + getInputFramesLost() generates (uint32_t framesLost); + + /** + * Return a recent count of the number of audio frames received and the + * clock time associated with that frame count. + * + * @return retval INVALID_STATE if the device is not ready/available, + * NOT_SUPPORTED if the command is not supported, + * OK otherwise. + * @return frames the total frame count received. This must be as early in + * the capture pipeline as possible. In general, frames + * must be non-negative and must not go "backwards". + * @return time is the clock monotonic time when frames was measured. In + * general, time must be a positive quantity and must not + * go "backwards". + */ + getCapturePosition() + generates (Result retval, uint64_t frames, uint64_t time); + + /** + * Returns an array with active microphones in the stream. + * + * @return retval INVALID_STATE if the call is not successful, + * OK otherwise. + * + * @return microphones array with microphones info + */ + getActiveMicrophones() + generates(Result retval, vec microphones); + + /** + * Specifies the logical microphone (for processing). + * + * If the feature is not supported an error should be returned + * If multiple microphones are present, this should be treated as a preference + * for their combined direction. + * + * Optional method + * + * @param Direction constant + * @return retval OK if the call is successful, an error code otherwise. + */ + setMicrophoneDirection(MicrophoneDirection direction) + generates(Result retval); + + /** + * Specifies the zoom factor for the selected microphone (for processing). + * + * If the feature is not supported an error should be returned + * If multiple microphones are present, this should be treated as a preference + * for their combined field dimension. + * + * Optional method + * + * @param the desired field dimension of microphone capture. Range is from -1 (wide angle), + * though 0 (no zoom) to 1 (maximum zoom). + * + * @return retval OK if the call is not successful, an error code otherwise. + */ + setMicrophoneFieldDimension(float zoom) generates(Result retval); +}; diff --git a/audio/7.0/IStreamOut.hal b/audio/7.0/IStreamOut.hal new file mode 100644 index 0000000000..208beb6363 --- /dev/null +++ b/audio/7.0/IStreamOut.hal @@ -0,0 +1,378 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.audio@7.0; + +import android.hardware.audio.common@7.0; +import IStream; +import IStreamOutCallback; +import IStreamOutEventCallback; + +interface IStreamOut extends IStream { + /** + * Return the audio hardware driver estimated latency in milliseconds. + * + * @return latencyMs latency in milliseconds. + */ + getLatency() generates (uint32_t latencyMs); + + /** + * This method is used in situations where audio mixing is done in the + * hardware. This method serves as a direct interface with hardware, + * allowing to directly set the volume as apposed to via the framework. + * This method might produce multiple PCM outputs or hardware accelerated + * codecs, such as MP3 or AAC. + * Optional method + * + * @param left left channel attenuation, 1.0f is unity, 0.0f is zero. + * @param right right channel attenuation, 1.0f is unity, 0.0f is zero. + * @return retval operation completion status. + * If a volume is outside [0,1], return INVALID_ARGUMENTS + */ + setVolume(float left, float right) generates (Result retval); + + /** + * Commands that can be executed on the driver writer thread. + */ + enum WriteCommand : int32_t { + WRITE, + GET_PRESENTATION_POSITION, + GET_LATENCY + }; + + /** + * Data structure passed back to the client via status message queue + * of 'write' operation. + * + * Possible values of 'retval' field: + * - OK, write operation was successful; + * - INVALID_ARGUMENTS, stream was not configured properly; + * - INVALID_STATE, stream is in a state that doesn't allow writes; + * - INVALID_OPERATION, retrieving presentation position isn't supported. + */ + struct WriteStatus { + Result retval; + WriteCommand replyTo; // discriminator + union Reply { + uint64_t written; // WRITE command, amount of bytes written, >= 0. + struct PresentationPosition { // same as generated by + uint64_t frames; // getPresentationPosition. + TimeSpec timeStamp; + } presentationPosition; + uint32_t latencyMs; // Same as generated by getLatency. + } reply; + }; + + /** + * Called when the metadata of the stream's source has been changed. + * @param sourceMetadata Description of the audio that is played by the clients. + */ + updateSourceMetadata(SourceMetadata sourceMetadata); + + /** + * Set up required transports for passing audio buffers to the driver. + * + * The transport consists of three message queues: + * -- command queue is used to instruct the writer thread what operation + * to perform; + * -- data queue is used for passing audio data from the client + * to the driver; + * -- status queue is used for reporting operation status + * (e.g. amount of bytes actually written or error code). + * + * The driver operates on a dedicated thread. The client must ensure that + * the thread is given an appropriate priority and assigned to correct + * scheduler and cgroup. For this purpose, the method returns identifiers + * of the driver thread. + * + * @param frameSize the size of a single frame, in bytes. + * @param framesCount the number of frames in a buffer. + * @return retval OK if both message queues were created successfully. + * INVALID_STATE if the method was already called. + * INVALID_ARGUMENTS if there was a problem setting up + * the queues. + * @return commandMQ a message queue used for passing commands. + * @return dataMQ a message queue used for passing audio data in the format + * specified at the stream opening. + * @return statusMQ a message queue used for passing status from the driver + * using WriteStatus structures. + * @return threadInfo identifiers of the driver's dedicated thread. + */ + prepareForWriting(uint32_t frameSize, uint32_t framesCount) + generates ( + Result retval, + fmq_sync commandMQ, + fmq_sync dataMQ, + fmq_sync statusMQ, + ThreadInfo threadInfo); + + /** + * Return the number of audio frames written by the audio DSP to DAC since + * the output has exited standby. + * Optional method + * + * @return retval operation completion status. + * @return dspFrames number of audio frames written. + */ + getRenderPosition() generates (Result retval, uint32_t dspFrames); + + /** + * Get the local time at which the next write to the audio driver will be + * presented. The units are microseconds, where the epoch is decided by the + * local audio HAL. + * Optional method + * + * @return retval operation completion status. + * @return timestampUs time of the next write. + */ + getNextWriteTimestamp() generates (Result retval, int64_t timestampUs); + + /** + * Set the callback interface for notifying completion of non-blocking + * write and drain. + * + * Calling this function implies that all future 'write' and 'drain' + * must be non-blocking and use the callback to signal completion. + * + * 'clearCallback' method needs to be called in order to release the local + * callback proxy on the server side and thus dereference the callback + * implementation on the client side. + * + * @return retval operation completion status. + */ + setCallback(IStreamOutCallback callback) generates (Result retval); + + /** + * Clears the callback previously set via 'setCallback' method. + * + * Warning: failure to call this method results in callback implementation + * on the client side being held until the HAL server termination. + * + * If no callback was previously set, the method should be a no-op + * and return OK. + * + * @return retval operation completion status: OK or NOT_SUPPORTED. + */ + clearCallback() generates (Result retval); + + /** + * Set the callback interface for notifying about an output stream event. + * + * Calling this method with a null pointer will result in releasing + * the local callback proxy on the server side and thus dereference + * the callback implementation on the client side. + * + * @return retval operation completion status. + */ + setEventCallback(IStreamOutEventCallback callback) + generates (Result retval); + + /** + * Returns whether HAL supports pausing and resuming of streams. + * + * @return supportsPause true if pausing is supported. + * @return supportsResume true if resume is supported. + */ + supportsPauseAndResume() + generates (bool supportsPause, bool supportsResume); + + /** + * Notifies to the audio driver to stop playback however the queued buffers + * are retained by the hardware. Useful for implementing pause/resume. Empty + * implementation if not supported however must be implemented for hardware + * with non-trivial latency. In the pause state, some audio hardware may + * still be using power. Client code may consider calling 'suspend' after a + * timeout to prevent that excess power usage. + * + * Implementation of this function is mandatory for offloaded playback. + * + * @return retval operation completion status. + */ + pause() generates (Result retval); + + /** + * Notifies to the audio driver to resume playback following a pause. + * Returns error INVALID_STATE if called without matching pause. + * + * Implementation of this function is mandatory for offloaded playback. + * + * @return retval operation completion status. + */ + resume() generates (Result retval); + + /** + * Returns whether HAL supports draining of streams. + * + * @return supports true if draining is supported. + */ + supportsDrain() generates (bool supports); + + /** + * Requests notification when data buffered by the driver/hardware has been + * played. If 'setCallback' has previously been called to enable + * non-blocking mode, then 'drain' must not block, instead it must return + * quickly and completion of the drain is notified through the callback. If + * 'setCallback' has not been called, then 'drain' must block until + * completion. + * + * If 'type' is 'ALL', the drain completes when all previously written data + * has been played. + * + * If 'type' is 'EARLY_NOTIFY', the drain completes shortly before all data + * for the current track has played to allow time for the framework to + * perform a gapless track switch. + * + * Drain must return immediately on 'stop' and 'flush' calls. + * + * Implementation of this function is mandatory for offloaded playback. + * + * @param type type of drain. + * @return retval operation completion status. + */ + drain(AudioDrain type) generates (Result retval); + + /** + * Notifies to the audio driver to flush the queued data. Stream must + * already be paused before calling 'flush'. + * Optional method + * + * Implementation of this function is mandatory for offloaded playback. + * + * @return retval operation completion status. + */ + flush() generates (Result retval); + + /** + * Return a recent count of the number of audio frames presented to an + * external observer. This excludes frames which have been written but are + * still in the pipeline. The count is not reset to zero when output enters + * standby. Also returns the value of CLOCK_MONOTONIC as of this + * presentation count. The returned count is expected to be 'recent', but + * does not need to be the most recent possible value. However, the + * associated time must correspond to whatever count is returned. + * + * Example: assume that N+M frames have been presented, where M is a 'small' + * number. Then it is permissible to return N instead of N+M, and the + * timestamp must correspond to N rather than N+M. The terms 'recent' and + * 'small' are not defined. They reflect the quality of the implementation. + * + * Optional method + * + * @return retval operation completion status. + * @return frames count of presented audio frames. + * @return timeStamp associated clock time. + */ + getPresentationPosition() + generates (Result retval, uint64_t frames, TimeSpec timeStamp); + + /** + * Selects a presentation for decoding from a next generation media stream + * (as defined per ETSI TS 103 190-2) and a program within the presentation. + * Optional method + * + * @param presentationId selected audio presentation. + * @param programId refinement for the presentation. + * @return retval operation completion status. + */ + selectPresentation(int32_t presentationId, int32_t programId) + generates (Result retval); + + /** + * Returns the Dual Mono mode presentation setting. + * + * Optional method + * + * @return retval operation completion status. + * @return mode current setting of Dual Mono mode. + */ + getDualMonoMode() generates (Result retval, DualMonoMode mode); + + /** + * Sets the Dual Mono mode presentation on the output device. + * + * The Dual Mono mode is generally applied to stereo audio streams + * where the left and right channels come from separate sources. + * + * Optional method + * + * @param mode selected Dual Mono mode. + * @return retval operation completion status. + */ + setDualMonoMode(DualMonoMode mode) generates (Result retval); + + /** + * Returns the Audio Description Mix level in dB. + * + * The level is applied to streams incorporating a secondary Audio + * Description stream. It specifies the relative level of mixing for + * the Audio Description with a reference to the Main Audio. + * + * Optional method + * + * The value of the relative level is in the range from negative infinity + * to +48. + * + * @return retval operation completion status. + * @return leveldB the current Audio Description Mix Level in dB. + */ + getAudioDescriptionMixLevel() generates (Result retval, float leveldB); + + /** + * Sets the Audio Description Mix level in dB. + * + * For streams incorporating a secondary Audio Description stream + * the relative level of mixing of the Audio Description to the Main Audio + * is controlled by this method. + * + * Optional method + * + * The value of the relative level must be in the range from negative + * infinity to +48. + * + * @param leveldB Audio Description Mix Level in dB + * @return retval operation completion status. + */ + setAudioDescriptionMixLevel(float leveldB) generates (Result retval); + + /** + * Retrieves current playback rate parameters. + * + * Optional method + * + * @return retval operation completion status. + * @return playbackRate current playback parameters + */ + getPlaybackRateParameters() + generates (Result retval, PlaybackRate playbackRate); + + /** + * Sets the playback rate parameters that control playback behavior. + * This is normally used when playing encoded content and decoding + * is performed in hardware. Otherwise, the framework can apply + * necessary transformations. + * + * Optional method + * + * If the HAL supports setting the playback rate, it is recommended + * to support speed and pitch values at least in the range + * from 0.5f to 2.0f, inclusive (see the definition of PlaybackRate struct). + * + * @param playbackRate playback parameters + * @return retval operation completion status. + */ + setPlaybackRateParameters(PlaybackRate playbackRate) + generates (Result retval); +}; diff --git a/audio/7.0/IStreamOutCallback.hal b/audio/7.0/IStreamOutCallback.hal new file mode 100644 index 0000000000..7b9d47fa8b --- /dev/null +++ b/audio/7.0/IStreamOutCallback.hal @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.audio@7.0; + +/** + * Asynchronous write callback interface. + */ +interface IStreamOutCallback { + /** + * Non blocking write completed. + */ + oneway onWriteReady(); + + /** + * Drain completed. + */ + oneway onDrainReady(); + + /** + * Stream hit an error. + */ + oneway onError(); +}; diff --git a/audio/7.0/IStreamOutEventCallback.hal b/audio/7.0/IStreamOutEventCallback.hal new file mode 100644 index 0000000000..52e65d3df9 --- /dev/null +++ b/audio/7.0/IStreamOutEventCallback.hal @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.audio@7.0; + +/** + * Asynchronous stream out event callback interface. The interface provides + * a way for the HAL to notify platform when there are changes, e.g. codec + * format change, from the lower layer. + */ +interface IStreamOutEventCallback { + /** + * Codec format changed. + * + * onCodecFormatChanged returns an AudioMetadata object in read-only ByteString format. + * It represents the most recent codec format decoded by a HW audio decoder. + * + * Codec format is an optional message from HW audio decoders. It serves to + * notify the application about the codec format and audio objects contained + * within the compressed audio stream for control, informational, + * and display purposes. + * + * audioMetadata ByteString is convertible to an AudioMetadata object through + * both a C++ and a C API present in Metadata.h [1], or through a Java API present + * in AudioMetadata.java [2]. + * + * The ByteString format is a stable format used for parcelling (marshalling) across + * JNI, AIDL, and HIDL interfaces. The test for R compatibility for native marshalling + * is TEST(metadata_tests, compatibility_R) [3]. The test for R compatibility for JNI + * marshalling is android.media.cts.AudioMetadataTest#testCompatibilityR [4]. + * + * R (audio HAL 7.0) defined keys are as follows [2]: + * "bitrate", int32 + * "channel-mask", int32 + * "mime", string + * "sample-rate", int32 + * "bit-width", int32 + * "has-atmos", int32 + * "audio-encoding", int32 + * + * Parceling Format: + * All values are native endian order. [1] + * + * using type_size_t = uint32_t; + * using index_size_t = uint32_t; + * using datum_size_t = uint32_t; + * + * Permitted type indexes are + * TYPE_NONE = 0, // Reserved + * TYPE_INT32 = 1, + * TYPE_INT64 = 2, + * TYPE_FLOAT = 3, + * TYPE_DOUBLE = 4, + * TYPE_STRING = 5, + * TYPE_DATA = 6, // A data table of + * + * Datum = { + * (type_size_t) Type (the type index from type_as_value.) + * (datum_size_t) Size (size of the Payload) + * (byte string) Payload + * } + * + * The data is specified in native endian order. + * Since the size of the Payload is always present, unknown types may be skipped. + * + * Payload + * [ sizeof(Primitive_Value) in raw bytes ] + * + * Example of Payload of 123: + * Payload + * [ value of 123 ] = 0x7b 0x00 0x00 0x00 123 + * + * Payload + * [ (index_size_t) length, not including zero terminator.] + * [ (length) raw bytes ] + * + * Example of Payload of std::string("hi"): + * [ (index_size_t) length ] = 0x02 0x00 0x00 0x00 2 strlen("hi") + * [ raw bytes "hi" ] = 0x68 0x69 "hi" + * + * Payload + * [ (index_size_t) entries ] + * [ raw bytes (entry 1) Key (Payload) + * Value (Datum) + * ... (until #entries) ] + * + * Example of Payload of {{"hello", "world"}, + * {"value", (int32_t)1000}}; + * [ (index_size_t) #entries ] = 0x02 0x00 0x00 0x00 2 entries + * Key (Payload) + * [ index_size_t length ] = 0x05 0x00 0x00 0x00 5 strlen("hello") + * [ raw bytes "hello" ] = 0x68 0x65 0x6c 0x6c 0x6f "hello" + * Value (Datum) + * [ (type_size_t) type ] = 0x05 0x00 0x00 0x00 5 (TYPE_STRING) + * [ (datum_size_t) size ] = 0x09 0x00 0x00 0x00 sizeof(index_size_t) + + * strlen("world") + * Payload + * [ (index_size_t) length ] = 0x05 0x00 0x00 0x00 5 strlen("world") + * [ raw bytes "world" ] = 0x77 0x6f 0x72 0x6c 0x64 "world" + * Key (Payload) + * [ index_size_t length ] = 0x05 0x00 0x00 0x00 5 strlen("value") + * [ raw bytes "value" ] = 0x76 0x61 0x6c 0x75 0x65 "value" + * Value (Datum) + * [ (type_size_t) type ] = 0x01 0x00 0x00 0x00 1 (TYPE_INT32) + * [ (datum_size_t) size ] = 0x04 0x00 0x00 0x00 4 sizeof(int32_t) + * Payload + * [ raw bytes 1000 ] = 0xe8 0x03 0x00 0x00 1000 + * + * The contents of audioMetadata is a Payload. + * An implementation dependent detail is that the Keys are always + * stored sorted, so the byte string representation generated is unique. + * + * Vendor keys are allowed for informational and debugging purposes. + * Vendor keys should consist of the vendor company name followed + * by a dot; for example, "vendorCompany.someVolume" [2]. + * + * [1] system/media/audio_utils/include/audio_utils/Metadata.h + * [2] frameworks/base/media/java/android/media/AudioMetadata.java + * [3] system/media/audio_utils/tests/metadata_tests.cpp + * [4] cts/tests/tests/media/src/android/media/cts/AudioMetadataTest.java + * + * @param audioMetadata is a buffer containing decoded format changes + * reported by codec. The buffer contains data that can be transformed + * to audio metadata, which is a C++ object based map. + */ + oneway onCodecFormatChanged(vec audioMetadata); +}; diff --git a/audio/7.0/config/Android.bp b/audio/7.0/config/Android.bp new file mode 100644 index 0000000000..015c4244e8 --- /dev/null +++ b/audio/7.0/config/Android.bp @@ -0,0 +1,5 @@ +xsd_config { + name: "audio_policy_configuration_V7_0", + srcs: ["audio_policy_configuration.xsd"], + package_name: "audio.policy.configuration.V7_0", +} diff --git a/audio/7.0/config/api/current.txt b/audio/7.0/config/api/current.txt new file mode 100644 index 0000000000..98c5eac982 --- /dev/null +++ b/audio/7.0/config/api/current.txt @@ -0,0 +1,435 @@ +// Signature format: 2.0 +package audio.policy.configuration.V7_0 { + + public class AttachedDevices { + ctor public AttachedDevices(); + method public java.util.List getItem(); + } + + public enum AudioDevice { + method public String getRawName(); + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_AMBIENT; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_AUX_DIGITAL; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_BACK_MIC; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_BLUETOOTH_A2DP; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_BLUETOOTH_BLE; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_BUILTIN_MIC; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_BUS; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_COMMUNICATION; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_DEFAULT; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_ECHO_REFERENCE; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_FM_TUNER; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_HDMI; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_HDMI_ARC; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_IP; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_LINE; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_LOOPBACK; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_PROXY; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_REMOTE_SUBMIX; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_SPDIF; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_STUB; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_TELEPHONY_RX; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_TV_TUNER; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_USB_ACCESSORY; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_USB_DEVICE; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_USB_HEADSET; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_VOICE_CALL; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_WIRED_HEADSET; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_NONE; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_AUX_DIGITAL; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_AUX_LINE; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_A2DP; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_SCO; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_BUS; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_DEFAULT; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_EARPIECE; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_ECHO_CANCELLER; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_FM; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_HDMI; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_HDMI_ARC; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_HEARING_AID; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_IP; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_LINE; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_PROXY; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_REMOTE_SUBMIX; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_SPDIF; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_SPEAKER; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_SPEAKER_SAFE; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_STUB; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_TELEPHONY_TX; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_USB_ACCESSORY; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_USB_DEVICE; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_USB_HEADSET; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_WIRED_HEADPHONE; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_WIRED_HEADSET; + } + + public enum AudioFormat { + method public String getRawName(); + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_ADIF; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_ADTS; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_ADTS_ELD; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_ADTS_ERLC; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_ADTS_HE_V1; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_ADTS_HE_V2; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_ADTS_LC; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_ADTS_LD; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_ADTS_LTP; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_ADTS_MAIN; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_ADTS_SCALABLE; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_ADTS_SSR; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_ADTS_XHE; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_ELD; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_ERLC; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_HE_V1; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_HE_V2; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_LATM; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_LATM_HE_V1; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_LATM_HE_V2; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_LATM_LC; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_LC; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_LD; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_LTP; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_MAIN; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_SCALABLE; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_SSR; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_XHE; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AC3; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AC4; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_ALAC; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AMR_NB; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AMR_WB; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AMR_WB_PLUS; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_APE; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_APTX; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_APTX_ADAPTIVE; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_APTX_HD; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_APTX_TWSP; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_CELT; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DOLBY_TRUEHD; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DSD; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DTS; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DTS_HD; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_EVRC; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_EVRCB; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_EVRCNW; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_EVRCWB; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_E_AC3; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_E_AC3_JOC; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_FLAC; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_HE_AAC_V1; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_HE_AAC_V2; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_IEC61937; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_LDAC; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_LHDC; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_LHDC_LL; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_MAT_1_0; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_MAT_2_0; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_MAT_2_1; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_MP2; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_MP3; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_OPUS; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_PCM_16_BIT; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_PCM_24_BIT_PACKED; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_PCM_32_BIT; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_PCM_8_24_BIT; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_PCM_8_BIT; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_PCM_FLOAT; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_QCELP; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_SBC; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_VORBIS; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_WMA; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_WMA_PRO; + } + + public class AudioPolicyConfiguration { + ctor public AudioPolicyConfiguration(); + method public audio.policy.configuration.V7_0.GlobalConfiguration getGlobalConfiguration(); + method public java.util.List getModules(); + method public audio.policy.configuration.V7_0.SurroundSound getSurroundSound(); + method public audio.policy.configuration.V7_0.Version getVersion(); + method public java.util.List getVolumes(); + method public void setGlobalConfiguration(audio.policy.configuration.V7_0.GlobalConfiguration); + method public void setSurroundSound(audio.policy.configuration.V7_0.SurroundSound); + method public void setVersion(audio.policy.configuration.V7_0.Version); + } + + public enum AudioUsage { + method public String getRawName(); + enum_constant public static final audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_ALARM; + enum_constant public static final audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY; + enum_constant public static final audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE; + enum_constant public static final audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_ASSISTANCE_SONIFICATION; + enum_constant public static final audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_ASSISTANT; + enum_constant public static final audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_GAME; + enum_constant public static final audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_MEDIA; + enum_constant public static final audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_NOTIFICATION; + enum_constant public static final audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE; + enum_constant public static final audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_UNKNOWN; + enum_constant public static final audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_VIRTUAL_SOURCE; + enum_constant public static final audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_VOICE_COMMUNICATION; + enum_constant public static final audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING; + } + + public enum DeviceCategory { + method public String getRawName(); + enum_constant public static final audio.policy.configuration.V7_0.DeviceCategory DEVICE_CATEGORY_EARPIECE; + enum_constant public static final audio.policy.configuration.V7_0.DeviceCategory DEVICE_CATEGORY_EXT_MEDIA; + enum_constant public static final audio.policy.configuration.V7_0.DeviceCategory DEVICE_CATEGORY_HEADSET; + enum_constant public static final audio.policy.configuration.V7_0.DeviceCategory DEVICE_CATEGORY_HEARING_AID; + enum_constant public static final audio.policy.configuration.V7_0.DeviceCategory DEVICE_CATEGORY_SPEAKER; + } + + public class DevicePorts { + ctor public DevicePorts(); + method public java.util.List getDevicePort(); + } + + public static class DevicePorts.DevicePort { + ctor public DevicePorts.DevicePort(); + method public String getAddress(); + method public java.util.List getEncodedFormats(); + method public audio.policy.configuration.V7_0.Gains getGains(); + method public java.util.List getProfile(); + method public audio.policy.configuration.V7_0.Role getRole(); + method public String getTagName(); + method public String getType(); + method public boolean get_default(); + method public void setAddress(String); + method public void setEncodedFormats(java.util.List); + method public void setGains(audio.policy.configuration.V7_0.Gains); + method public void setRole(audio.policy.configuration.V7_0.Role); + method public void setTagName(String); + method public void setType(String); + method public void set_default(boolean); + } + + public enum EngineSuffix { + method public String getRawName(); + enum_constant public static final audio.policy.configuration.V7_0.EngineSuffix _default; + enum_constant public static final audio.policy.configuration.V7_0.EngineSuffix configurable; + } + + public enum GainMode { + method public String getRawName(); + enum_constant public static final audio.policy.configuration.V7_0.GainMode AUDIO_GAIN_MODE_CHANNELS; + enum_constant public static final audio.policy.configuration.V7_0.GainMode AUDIO_GAIN_MODE_JOINT; + enum_constant public static final audio.policy.configuration.V7_0.GainMode AUDIO_GAIN_MODE_RAMP; + } + + public class Gains { + ctor public Gains(); + method public java.util.List getGain(); + } + + public static class Gains.Gain { + ctor public Gains.Gain(); + method public String getChannel_mask(); + method public int getDefaultValueMB(); + method public int getMaxRampMs(); + method public int getMaxValueMB(); + method public int getMinRampMs(); + method public int getMinValueMB(); + method public audio.policy.configuration.V7_0.GainMode getMode(); + method public String getName(); + method public int getStepValueMB(); + method public boolean getUseForVolume(); + method public void setChannel_mask(String); + method public void setDefaultValueMB(int); + method public void setMaxRampMs(int); + method public void setMaxValueMB(int); + method public void setMinRampMs(int); + method public void setMinValueMB(int); + method public void setMode(audio.policy.configuration.V7_0.GainMode); + method public void setName(String); + method public void setStepValueMB(int); + method public void setUseForVolume(boolean); + } + + public class GlobalConfiguration { + ctor public GlobalConfiguration(); + method public boolean getCall_screen_mode_supported(); + method public audio.policy.configuration.V7_0.EngineSuffix getEngine_library(); + method public boolean getSpeaker_drc_enabled(); + method public void setCall_screen_mode_supported(boolean); + method public void setEngine_library(audio.policy.configuration.V7_0.EngineSuffix); + method public void setSpeaker_drc_enabled(boolean); + } + + public enum HalVersion { + method public String getRawName(); + enum_constant public static final audio.policy.configuration.V7_0.HalVersion _2_0; + enum_constant public static final audio.policy.configuration.V7_0.HalVersion _3_0; + } + + public class MixPorts { + ctor public MixPorts(); + method public java.util.List getMixPort(); + } + + public static class MixPorts.MixPort { + ctor public MixPorts.MixPort(); + method public String getFlags(); + method public audio.policy.configuration.V7_0.Gains getGains(); + method public long getMaxActiveCount(); + method public long getMaxOpenCount(); + method public String getName(); + method public java.util.List getPreferredUsage(); + method public java.util.List getProfile(); + method public audio.policy.configuration.V7_0.Role getRole(); + method public void setFlags(String); + method public void setGains(audio.policy.configuration.V7_0.Gains); + method public void setMaxActiveCount(long); + method public void setMaxOpenCount(long); + method public void setName(String); + method public void setPreferredUsage(java.util.List); + method public void setRole(audio.policy.configuration.V7_0.Role); + } + + public enum MixType { + method public String getRawName(); + enum_constant public static final audio.policy.configuration.V7_0.MixType mix; + enum_constant public static final audio.policy.configuration.V7_0.MixType mux; + } + + public class Modules { + ctor public Modules(); + method public java.util.List getModule(); + } + + public static class Modules.Module { + ctor public Modules.Module(); + method public audio.policy.configuration.V7_0.AttachedDevices getAttachedDevices(); + method public String getDefaultOutputDevice(); + method public audio.policy.configuration.V7_0.DevicePorts getDevicePorts(); + method public audio.policy.configuration.V7_0.HalVersion getHalVersion(); + method public audio.policy.configuration.V7_0.MixPorts getMixPorts(); + method public String getName(); + method public audio.policy.configuration.V7_0.Routes getRoutes(); + method public void setAttachedDevices(audio.policy.configuration.V7_0.AttachedDevices); + method public void setDefaultOutputDevice(String); + method public void setDevicePorts(audio.policy.configuration.V7_0.DevicePorts); + method public void setHalVersion(audio.policy.configuration.V7_0.HalVersion); + method public void setMixPorts(audio.policy.configuration.V7_0.MixPorts); + method public void setName(String); + method public void setRoutes(audio.policy.configuration.V7_0.Routes); + } + + public class Profile { + ctor public Profile(); + method public String getChannelMasks(); + method public String getFormat(); + method public String getName(); + method public String getSamplingRates(); + method public void setChannelMasks(String); + method public void setFormat(String); + method public void setName(String); + method public void setSamplingRates(String); + } + + public class Reference { + ctor public Reference(); + method public String getName(); + method public java.util.List getPoint(); + method public void setName(String); + } + + public enum Role { + method public String getRawName(); + enum_constant public static final audio.policy.configuration.V7_0.Role sink; + enum_constant public static final audio.policy.configuration.V7_0.Role source; + } + + public class Routes { + ctor public Routes(); + method public java.util.List getRoute(); + } + + public static class Routes.Route { + ctor public Routes.Route(); + method public String getSink(); + method public String getSources(); + method public audio.policy.configuration.V7_0.MixType getType(); + method public void setSink(String); + method public void setSources(String); + method public void setType(audio.policy.configuration.V7_0.MixType); + } + + public enum Stream { + method public String getRawName(); + enum_constant public static final audio.policy.configuration.V7_0.Stream AUDIO_STREAM_ACCESSIBILITY; + enum_constant public static final audio.policy.configuration.V7_0.Stream AUDIO_STREAM_ALARM; + enum_constant public static final audio.policy.configuration.V7_0.Stream AUDIO_STREAM_ASSISTANT; + enum_constant public static final audio.policy.configuration.V7_0.Stream AUDIO_STREAM_BLUETOOTH_SCO; + enum_constant public static final audio.policy.configuration.V7_0.Stream AUDIO_STREAM_DTMF; + enum_constant public static final audio.policy.configuration.V7_0.Stream AUDIO_STREAM_ENFORCED_AUDIBLE; + enum_constant public static final audio.policy.configuration.V7_0.Stream AUDIO_STREAM_MUSIC; + enum_constant public static final audio.policy.configuration.V7_0.Stream AUDIO_STREAM_NOTIFICATION; + enum_constant public static final audio.policy.configuration.V7_0.Stream AUDIO_STREAM_PATCH; + enum_constant public static final audio.policy.configuration.V7_0.Stream AUDIO_STREAM_REROUTING; + enum_constant public static final audio.policy.configuration.V7_0.Stream AUDIO_STREAM_RING; + enum_constant public static final audio.policy.configuration.V7_0.Stream AUDIO_STREAM_SYSTEM; + enum_constant public static final audio.policy.configuration.V7_0.Stream AUDIO_STREAM_TTS; + enum_constant public static final audio.policy.configuration.V7_0.Stream AUDIO_STREAM_VOICE_CALL; + } + + public class SurroundFormats { + ctor public SurroundFormats(); + method public java.util.List getFormat(); + } + + public static class SurroundFormats.Format { + ctor public SurroundFormats.Format(); + method public audio.policy.configuration.V7_0.AudioFormat getName(); + method public java.util.List getSubformats(); + method public void setName(audio.policy.configuration.V7_0.AudioFormat); + method public void setSubformats(java.util.List); + } + + public class SurroundSound { + ctor public SurroundSound(); + method public audio.policy.configuration.V7_0.SurroundFormats getFormats(); + method public void setFormats(audio.policy.configuration.V7_0.SurroundFormats); + } + + public enum Version { + method public String getRawName(); + enum_constant public static final audio.policy.configuration.V7_0.Version _1_0; + } + + public class Volume { + ctor public Volume(); + method public audio.policy.configuration.V7_0.DeviceCategory getDeviceCategory(); + method public java.util.List getPoint(); + method public String getRef(); + method public audio.policy.configuration.V7_0.Stream getStream(); + method public void setDeviceCategory(audio.policy.configuration.V7_0.DeviceCategory); + method public void setRef(String); + method public void setStream(audio.policy.configuration.V7_0.Stream); + } + + public class Volumes { + ctor public Volumes(); + method public java.util.List getReference(); + method public java.util.List getVolume(); + } + + public class XmlParser { + ctor public XmlParser(); + method public static audio.policy.configuration.V7_0.AudioPolicyConfiguration read(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException; + method public static String readText(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; + method public static void skip(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; + } + +} + diff --git a/audio/7.0/config/api/last_current.txt b/audio/7.0/config/api/last_current.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/audio/7.0/config/api/last_removed.txt b/audio/7.0/config/api/last_removed.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/audio/7.0/config/api/removed.txt b/audio/7.0/config/api/removed.txt new file mode 100644 index 0000000000..d802177e24 --- /dev/null +++ b/audio/7.0/config/api/removed.txt @@ -0,0 +1 @@ +// Signature format: 2.0 diff --git a/audio/7.0/config/audio_policy_configuration.xsd b/audio/7.0/config/audio_policy_configuration.xsd new file mode 100644 index 0000000000..19c6f70536 --- /dev/null +++ b/audio/7.0/config/audio_policy_configuration.xsd @@ -0,0 +1,634 @@ + + + + + + + + + + + + + + Version of the interface the hal implements. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + There should be one section per audio HW module present on the platform. + Each contains two mandatory tags: “halVersion” and “name”. + The module "name" is the same as in previous .conf file. + Each module must contain the following sections: + - : a list of device descriptors for all + input and output devices accessible via this module. + This contains both permanently attached devices and removable devices. + - : listing all output and input streams exposed by the audio HAL + - : list of possible connections between input + and output devices or between stream and devices. + A is defined by a set of 3 attributes: + -"type": mux|mix means all sources are mutual exclusive (mux) or can be mixed (mix) + -"sink": the sink involved in this route + -"sources": all the sources than can be connected to the sink via this route + - : permanently attached devices. + The attachedDevices section is a list of devices names. + Their names correspond to device names defined in "devicePorts" section. + - is the device to be used when no policy rule applies + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + "|" separated list of audio_output_flags_t or audio_input_flags_t. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + When choosing the mixPort of an audio track, the audioPolicy + first considers the mixPorts with a preferredUsage including + the track AudioUsage preferred . + If non support the track format, the other mixPorts are considered. + Eg: a will receive + the audio of all apps playing with a MEDIA usage. + It may receive audio from ALARM if there are no audio compatible + . + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Comma (",") separated list of channel flags + from audio_channel_mask_t. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The default device will be used if multiple have the same type + and no explicit route request exists for a specific device of + that type. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + List all available sources for a given sink. + + + + + + + + + + + + + + + + + + + + + + Comma separated pair of number. + The fist one is the framework level (between 0 and 100). + The second one is the volume to send to the HAL. + The framework will interpolate volumes not specified. + Their MUST be at least 2 points specified. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Volume section defines a volume curve for a given use case and device category. + It contains a list of points of this curve expressing the attenuation in Millibels + for a given volume index from 0 to 100. + + 0,-9600 + 100,0 + + + It may also reference a reference/@name to avoid duplicating curves. + + + 0,-9600 + 100,0 + + + + + + + + + + + + + + + + + + + + Surround Sound section provides configuration related to handling of + multi-channel formats. + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/audio/7.0/types.hal b/audio/7.0/types.hal new file mode 100644 index 0000000000..b0b08430fa --- /dev/null +++ b/audio/7.0/types.hal @@ -0,0 +1,357 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.audio@7.0; + +import android.hardware.audio.common@7.0; + +enum Result : int32_t { + OK, + NOT_INITIALIZED, + INVALID_ARGUMENTS, + INVALID_STATE, + /** + * Methods marked as "Optional method" must return this result value + * if the operation is not supported by HAL. + */ + NOT_SUPPORTED +}; + +@export(name="audio_drain_type_t", value_prefix="AUDIO_DRAIN_") +enum AudioDrain : int32_t { + /** drain() returns when all data has been played. */ + ALL, + /** + * drain() returns a short time before all data from the current track has + * been played to give time for gapless track switch. + */ + EARLY_NOTIFY +}; + +/** + * A substitute for POSIX timespec. + */ +struct TimeSpec { + uint64_t tvSec; // seconds + uint64_t tvNSec; // nanoseconds +}; + +struct ParameterValue { + string key; + string value; +}; + +enum MmapBufferFlag : uint32_t { + NONE = 0x0, + /** + * If the buffer can be securely shared to untrusted applications + * through the AAudio exclusive mode. + * Only set this flag if applications are restricted from accessing the + * memory surrounding the audio data buffer by a kernel mechanism. + * See Linux kernel's dma_buf. + */ + APPLICATION_SHAREABLE = 0x1, +}; + +/** + * Mmap buffer descriptor returned by IStream.createMmapBuffer(). + * Used by streams opened in mmap mode. + */ +struct MmapBufferInfo { + /** Mmap memory buffer */ + memory sharedMemory; + /** Total buffer size in frames */ + uint32_t bufferSizeFrames; + /** Transfer size granularity in frames */ + uint32_t burstSizeFrames; + /** Attributes describing the buffer. */ + bitfield flags; +}; + +/** + * Mmap buffer read/write position returned by IStream.getMmapPosition(). + * Used by streams opened in mmap mode. + */ +struct MmapPosition { + int64_t timeNanoseconds; // time stamp in ns, CLOCK_MONOTONIC + int32_t positionFrames; // increasing 32 bit frame count reset when IStream.stop() is called +}; + +/** + * The message queue flags used to synchronize reads and writes from + * message queues used by StreamIn and StreamOut. + */ +enum MessageQueueFlagBits : uint32_t { + NOT_EMPTY = 1 << 0, + NOT_FULL = 1 << 1 +}; + +/* + * Microphone information + * + */ + +/** + * A 3D point used to represent position or orientation of a microphone. + * + * Position: Coordinates of the microphone's capsule, in meters, from the + * bottom-left-back corner of the bounding box of android device in natural + * orientation (PORTRAIT for phones, LANDSCAPE for tablets, tvs, etc). + * The orientation musth match the reported by the api Display.getRotation(). + * + * Orientation: Normalized vector to signal the main orientation of the + * microphone's capsule. Magnitude = sqrt(x^2 + y^2 + z^2) = 1 + */ +struct AudioMicrophoneCoordinate { + float x; + float y; + float z; +}; + +/** + * Enum to identify the type of channel mapping for active microphones. + * Used channels further identify if the microphone has any significative + * process (e.g. High Pass Filtering, dynamic compression) + * Simple processing as constant gain adjustment must be DIRECT. + */ +enum AudioMicrophoneChannelMapping : uint32_t { + UNUSED = 0, /* Channel not used */ + DIRECT = 1, /* Channel used and signal not processed */ + PROCESSED = 2, /* Channel used and signal has some process */ +}; + +/** + * Enum to identify locations of microphones in regards to the body of the + * android device. + */ +enum AudioMicrophoneLocation : uint32_t { + UNKNOWN = 0, + MAINBODY = 1, + MAINBODY_MOVABLE = 2, + PERIPHERAL = 3, +}; + +/** + * Identifier to help group related microphones together + * e.g. microphone arrays should belong to the same group + */ +typedef int32_t AudioMicrophoneGroup; + +/** + * Enum with standard polar patterns of microphones + */ +enum AudioMicrophoneDirectionality : uint32_t { + UNKNOWN = 0, + OMNI = 1, + BI_DIRECTIONAL = 2, + CARDIOID = 3, + HYPER_CARDIOID = 4, + SUPER_CARDIOID = 5, +}; + +/** + * A (frequency, level) pair. Used to represent frequency response. + */ +struct AudioFrequencyResponsePoint { + /** In Hz */ + float frequency; + /** In dB */ + float level; +}; + +/** + * Structure used by the HAL to describe microphone's characteristics + * Used by StreamIn and Device + */ +struct MicrophoneInfo { + /** Unique alphanumeric id for microphone. Guaranteed to be the same + * even after rebooting. + */ + string deviceId; + /** + * Device specific information + */ + DeviceAddress deviceAddress; + /** Each element of the vector must describe the channel with the same + * index. + */ + vec channelMapping; + /** Location of the microphone in regard to the body of the device */ + AudioMicrophoneLocation location; + /** Identifier to help group related microphones together + * e.g. microphone arrays should belong to the same group + */ + AudioMicrophoneGroup group; + /** Index of this microphone within the group. + * (group, index) must be unique within the same device. + */ + uint32_t indexInTheGroup; + /** Level in dBFS produced by a 1000 Hz tone at 94 dB SPL */ + float sensitivity; + /** Level in dB of the max SPL supported at 1000 Hz */ + float maxSpl; + /** Level in dB of the min SPL supported at 1000 Hz */ + float minSpl; + /** Standard polar pattern of the microphone */ + AudioMicrophoneDirectionality directionality; + /** Vector with ordered frequency responses (from low to high frequencies) + * with the frequency response of the microphone. + * Levels are in dB, relative to level at 1000 Hz + */ + vec frequencyResponse; + /** Position of the microphone's capsule in meters, from the + * bottom-left-back corner of the bounding box of device. + */ + AudioMicrophoneCoordinate position; + /** Normalized point to signal the main orientation of the microphone's + * capsule. sqrt(x^2 + y^2 + z^2) = 1 + */ + AudioMicrophoneCoordinate orientation; +}; + +/** + * Constants used by the HAL to determine how to select microphones and process those inputs in + * order to optimize for capture in the specified direction. + * + * MicrophoneDirection Constants are defined in MicrophoneDirection.java. + */ +@export(name="audio_microphone_direction_t", value_prefix="MIC_DIRECTION_") +enum MicrophoneDirection : int32_t { + /** + * Don't do any directionality processing of the activated microphone(s). + */ + UNSPECIFIED = 0, + /** + * Optimize capture for audio coming from the screen-side of the device. + */ + FRONT = 1, + /** + * Optimize capture for audio coming from the side of the device opposite the screen. + */ + BACK = 2, + /** + * Optimize capture for audio coming from an off-device microphone. + */ + EXTERNAL = 3, +}; + + +/* Dual Mono handling is used when a stereo audio stream + * contains separate audio content on the left and right channels. + * Such information about the content of the stream may be found, for example, + * in ITU T-REC-J.94-201610 A.6.2.3 Component descriptor. + */ +@export(name="audio_dual_mono_mode_t", value_prefix="AUDIO_DUAL_MONO_MODE_") +enum DualMonoMode : int32_t { + // Need to be in sync with DUAL_MONO_MODE* constants in + // frameworks/base/media/java/android/media/AudioTrack.java + /** + * Disable any Dual Mono presentation effect. + * + */ + OFF = 0, + /** + * This mode indicates that a stereo stream should be presented + * with the left and right audio channels blended together + * and delivered to both channels. + * + * Behavior for non-stereo streams is implementation defined. + * A suggested guideline is that the left-right stereo symmetric + * channels are pairwise blended, the other channels such as center + * are left alone. + */ + LR = 1, + /** + * This mode indicates that a stereo stream should be presented + * with the left audio channel replicated into the right audio channel. + * + * Behavior for non-stereo streams is implementation defined. + * A suggested guideline is that all channels with left-right + * stereo symmetry will have the left channel position replicated + * into the right channel position. The center channels (with no + * left/right symmetry) or unbalanced channels are left alone. + */ + LL = 2, + /** + * This mode indicates that a stereo stream should be presented + * with the right audio channel replicated into the left audio channel. + * + * Behavior for non-stereo streams is implementation defined. + * A suggested guideline is that all channels with left-right + * stereo symmetry will have the right channel position replicated + * into the left channel position. The center channels (with no + * left/right symmetry) or unbalanced channels are left alone. + */ + RR = 3, +}; + +/** + * Algorithms used for timestretching (preserving pitch while playing audio + * content at different speed). + */ +@export(name="audio_timestretch_stretch_mode_t", value_prefix="AUDIO_TIMESTRETCH_STRETCH_") +enum TimestretchMode : int32_t { + // Need to be in sync with AUDIO_STRETCH_MODE_* constants in + // frameworks/base/media/java/android/media/PlaybackParams.java + DEFAULT = 0, + /** Selects timestretch algorithm best suitable for voice (speech) content. */ + VOICE = 1, +}; + +/** + * Behavior when the values for speed and / or pitch are out + * of applicable range. + */ +@export(name="audio_timestretch_fallback_mode_t", value_prefix="AUDIO_TIMESTRETCH_FALLBACK_") +enum TimestretchFallbackMode : int32_t { + // Need to be in sync with AUDIO_FALLBACK_MODE_* constants in + // frameworks/base/media/java/android/media/PlaybackParams.java + /** Play silence for parameter values that are out of range. */ + MUTE = 1, + /** Return an error while trying to set the parameters. */ + FAIL = 2, +}; + +/** + * Parameters determining playback behavior. They are used to speed up or + * slow down playback and / or change the tonal frequency of the audio content + * (pitch). + */ +struct PlaybackRate { + /** + * Speed factor (multiplier). Normal speed has the value of 1.0f. + * Values less than 1.0f slow down playback, value greater than 1.0f + * speed it up. + */ + float speed; + /** + * Pitch factor (multiplier). Setting pitch value to 1.0f together + * with changing playback speed preserves the pitch, this is often + * called "timestretching." Setting the pitch value equal to speed produces + * the same effect as playing audio content at different sampling rate. + */ + float pitch; + /** + * Selects the algorithm used for timestretching (preserving pitch while + * playing audio at different speed). + */ + TimestretchMode timestretchMode; + /** + * Selects the behavior when the specified values for speed and / or pitch + * are out of applicable range. + */ + TimestretchFallbackMode fallbackMode; +}; diff --git a/audio/common/7.0/Android.bp b/audio/common/7.0/Android.bp new file mode 100644 index 0000000000..eef563fecd --- /dev/null +++ b/audio/common/7.0/Android.bp @@ -0,0 +1,14 @@ +// This file is autogenerated by hidl-gen -Landroidbp. + +hidl_interface { + name: "android.hardware.audio.common@7.0", + root: "android.hardware", + srcs: [ + "types.hal", + ], + interfaces: [ + "android.hidl.safe_union@1.0", + ], + gen_java: true, + gen_java_constants: true, +} diff --git a/audio/common/7.0/types.hal b/audio/common/7.0/types.hal new file mode 100644 index 0000000000..2288eb1d47 --- /dev/null +++ b/audio/common/7.0/types.hal @@ -0,0 +1,1191 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.audio.common@7.0; + +import android.hidl.safe_union@1.0; + +/* + * + * IDs and Handles + * + */ + +/** + * Handle type for identifying audio sources and sinks. + */ +typedef int32_t AudioIoHandle; + +/** + * Audio hw module handle functions or structures referencing a module. + */ +typedef int32_t AudioModuleHandle; + +/** + * Each port has a unique ID or handle allocated by policy manager. + */ +typedef int32_t AudioPortHandle; + +/** + * Each patch is identified by a handle at the interface used to create that + * patch. For instance, when a patch is created by the audio HAL, the HAL + * allocates and returns a handle. This handle is unique to a given audio HAL + * hardware module. But the same patch receives another system wide unique + * handle allocated by the framework. This unique handle is used for all + * transactions inside the framework. + */ +typedef int32_t AudioPatchHandle; + +/** + * A HW synchronization source returned by the audio HAL. + */ +typedef uint32_t AudioHwSync; + +/** + * Each port has a unique ID or handle allocated by policy manager. + */ +@export(name="") +enum AudioHandleConsts : int32_t { + AUDIO_IO_HANDLE_NONE = 0, + AUDIO_MODULE_HANDLE_NONE = 0, + AUDIO_PORT_HANDLE_NONE = 0, + AUDIO_PATCH_HANDLE_NONE = 0, +}; + +/** + * Commonly used structure for passing unique identifieds (UUID). + * For the definition of UUID, refer to ITU-T X.667 spec. + */ +struct Uuid { + uint32_t timeLow; + uint16_t timeMid; + uint16_t versionAndTimeHigh; + uint16_t variantAndClockSeqHigh; + uint8_t[6] node; +}; + + +/* + * + * Audio streams + * + */ + +/** + * Audio stream type describing the intended use case of a stream. + */ +@export(name="audio_stream_type_t", value_prefix="AUDIO_STREAM_") +enum AudioStreamType : int32_t { + // These values must kept in sync with + // frameworks/base/media/java/android/media/AudioSystem.java + /** Used to identify the default audio stream volume. */ + DEFAULT = -1, + /** Specifies the minimum value for use in checks and loops. */ + MIN = 0, + /** Used to identify the volume of audio streams for phone calls. */ + VOICE_CALL = 0, + /** Used to identify the volume of audio streams for system sounds. */ + SYSTEM = 1, + /** + * Used to identify the volume of audio streams for the phone ring + * and message alerts. + */ + RING = 2, + /** Used to identify the volume of audio streams for music playback. */ + MUSIC = 3, + /** Used to identify the volume of audio streams for alarms. */ + ALARM = 4, + /** Used to identify the volume of audio streams for notifications. */ + NOTIFICATION = 5, + /** + * Used to identify the volume of audio streams for phone calls + * when connected on bluetooth. + */ + BLUETOOTH_SCO = 6, + /** + * Used to identify the volume of audio streams for enforced system + * sounds in certain countries (e.g camera in Japan). */ + ENFORCED_AUDIBLE = 7, + /** Used to identify the volume of audio streams for DTMF tones. */ + DTMF = 8, + /** + * Used to identify the volume of audio streams exclusively transmitted + * through the speaker (TTS) of the device. + */ + TTS = 9, + /** + * Used to identify the volume of audio streams for accessibility prompts. + */ + ACCESSIBILITY = 10, + /** Used to identify the volume of audio streams for virtual assistant. */ + ASSISTANT = 11, +}; + +@export(name="audio_source_t", value_prefix="AUDIO_SOURCE_") +enum AudioSource : int32_t { + // These values must kept in sync with + // frameworks/base/media/java/android/media/MediaRecorder.java, + // system/media/audio_effects/include/audio_effects/audio_effects_conf.h + /** Default audio source. */ + DEFAULT = 0, + /** Microphone audio source. */ + MIC = 1, + /** Voice call uplink (Tx) audio source. */ + VOICE_UPLINK = 2, + /** Voice call downlink (Rx) audio source. */ + VOICE_DOWNLINK = 3, + /** Voice call uplink + downlink audio source. */ + VOICE_CALL = 4, + /** + * Microphone audio source tuned for video recording, with the same + * orientation as the camera if available. + */ + CAMCORDER = 5, + /** Microphone audio source tuned for voice recognition. */ + VOICE_RECOGNITION = 6, + /** + * Microphone audio source tuned for voice communications such as VoIP. It + * will for instance take advantage of echo cancellation or automatic gain + * control if available. + */ + VOICE_COMMUNICATION = 7, + /** + * Source for the mix to be presented remotely. An example of remote + * presentation is Wifi Display where a dongle attached to a TV can be used + * to play the mix captured by this audio source. + */ + REMOTE_SUBMIX = 8, + /** + * Source for unprocessed sound. Usage examples include level measurement + * and raw signal analysis. + */ + UNPROCESSED = 9, + /** + * Source for capturing audio meant to be processed in real time and played back for live + * performance (e.g karaoke). The capture path will minimize latency and coupling with + * playback path. + */ + VOICE_PERFORMANCE = 10, + /** + * Source for an echo canceller to capture the reference signal to be cancelled. + * The echo reference signal will be captured as close as possible to the DAC in order + * to include all post processing applied to the playback path. + */ + ECHO_REFERENCE = 1997, + /** Virtual source for the built-in FM tuner. */ + FM_TUNER = 1998, + /** Virtual source for the last captured hotword. */ + HOTWORD = 1999, +}; + +typedef int32_t AudioSession; +/** + * Special audio session values. + */ +@export(name="audio_session_t", value_prefix="AUDIO_SESSION_") +enum AudioSessionConsts : int32_t { + /** + * Session for effects attached to a particular sink or source audio device + * (e.g an effect only applied to a speaker) + */ + DEVICE = -2, + /** + * Session for effects attached to a particular output stream + * (value must be less than 0) + */ + OUTPUT_STAGE = -1, + /** + * Session for effects applied to output mix. These effects can + * be moved by audio policy manager to another output stream + * (value must be 0) + */ + OUTPUT_MIX = 0, + /** + * Application does not specify an explicit session ID to be used, and + * requests a new session ID to be allocated. Corresponds to + * AudioManager.AUDIO_SESSION_ID_GENERATE and + * AudioSystem.AUDIO_SESSION_ALLOCATE. + */ + ALLOCATE = 0, + /** + * For use with AudioRecord::start(), this indicates no trigger session. + * It is also used with output tracks and patch tracks, which never have a + * session. + */ + NONE = 0 +}; + +/** + * Audio format is a 32-bit word that consists of: + * main format field (upper 8 bits) + * sub format field (lower 24 bits). + * + * The main format indicates the main codec type. The sub format field indicates + * options and parameters for each format. The sub format is mainly used for + * record to indicate for instance the requested bitrate or profile. It can + * also be used for certain formats to give informations not present in the + * encoded audio stream (e.g. octet alignement for AMR). + */ +@export(name="audio_format_t", value_prefix="AUDIO_FORMAT_") +enum AudioFormat : uint32_t { + INVALID = 0xFFFFFFFFUL, + DEFAULT = 0, + PCM = 0x00000000UL, + MP3 = 0x01000000UL, + AMR_NB = 0x02000000UL, + AMR_WB = 0x03000000UL, + AAC = 0x04000000UL, + /** Deprecated, Use AAC_HE_V1 */ + HE_AAC_V1 = 0x05000000UL, + /** Deprecated, Use AAC_HE_V2 */ + HE_AAC_V2 = 0x06000000UL, + VORBIS = 0x07000000UL, + OPUS = 0x08000000UL, + AC3 = 0x09000000UL, + E_AC3 = 0x0A000000UL, + DTS = 0x0B000000UL, + DTS_HD = 0x0C000000UL, + /** IEC61937 is encoded audio wrapped in 16-bit PCM. */ + IEC61937 = 0x0D000000UL, + DOLBY_TRUEHD = 0x0E000000UL, + EVRC = 0x10000000UL, + EVRCB = 0x11000000UL, + EVRCWB = 0x12000000UL, + EVRCNW = 0x13000000UL, + AAC_ADIF = 0x14000000UL, + WMA = 0x15000000UL, + WMA_PRO = 0x16000000UL, + AMR_WB_PLUS = 0x17000000UL, + MP2 = 0x18000000UL, + QCELP = 0x19000000UL, + DSD = 0x1A000000UL, + FLAC = 0x1B000000UL, + ALAC = 0x1C000000UL, + APE = 0x1D000000UL, + AAC_ADTS = 0x1E000000UL, + SBC = 0x1F000000UL, + APTX = 0x20000000UL, + APTX_HD = 0x21000000UL, + AC4 = 0x22000000UL, + LDAC = 0x23000000UL, + /** Dolby Metadata-enhanced Audio Transmission */ + MAT = 0x24000000UL, + AAC_LATM = 0x25000000UL, + CELT = 0x26000000UL, + APTX_ADAPTIVE = 0x27000000UL, + LHDC = 0x28000000UL, + LHDC_LL = 0x29000000UL, + APTX_TWSP = 0x2A000000UL, + + /** Deprecated */ + MAIN_MASK = 0xFF000000UL, + SUB_MASK = 0x00FFFFFFUL, + + /* Subformats */ + PCM_SUB_16_BIT = 0x1, // PCM signed 16 bits + PCM_SUB_8_BIT = 0x2, // PCM unsigned 8 bits + PCM_SUB_32_BIT = 0x3, // PCM signed .31 fixed point + PCM_SUB_8_24_BIT = 0x4, // PCM signed 8.23 fixed point + PCM_SUB_FLOAT = 0x5, // PCM single-precision float pt + PCM_SUB_24_BIT_PACKED = 0x6, // PCM signed .23 fix pt (3 bytes) + + MP3_SUB_NONE = 0x0, + + AMR_SUB_NONE = 0x0, + + AAC_SUB_MAIN = 0x1, + AAC_SUB_LC = 0x2, + AAC_SUB_SSR = 0x4, + AAC_SUB_LTP = 0x8, + AAC_SUB_HE_V1 = 0x10, + AAC_SUB_SCALABLE = 0x20, + AAC_SUB_ERLC = 0x40, + AAC_SUB_LD = 0x80, + AAC_SUB_HE_V2 = 0x100, + AAC_SUB_ELD = 0x200, + AAC_SUB_XHE = 0x300, + + VORBIS_SUB_NONE = 0x0, + + E_AC3_SUB_JOC = 0x1, + + MAT_SUB_1_0 = 0x1, + MAT_SUB_2_0 = 0x2, + MAT_SUB_2_1 = 0x3, + + /* Aliases */ + /** note != AudioFormat.ENCODING_PCM_16BIT */ + PCM_16_BIT = (PCM | PCM_SUB_16_BIT), + /** note != AudioFormat.ENCODING_PCM_8BIT */ + PCM_8_BIT = (PCM | PCM_SUB_8_BIT), + PCM_32_BIT = (PCM | PCM_SUB_32_BIT), + PCM_8_24_BIT = (PCM | PCM_SUB_8_24_BIT), + PCM_FLOAT = (PCM | PCM_SUB_FLOAT), + PCM_24_BIT_PACKED = (PCM | PCM_SUB_24_BIT_PACKED), + AAC_MAIN = (AAC | AAC_SUB_MAIN), + AAC_LC = (AAC | AAC_SUB_LC), + AAC_SSR = (AAC | AAC_SUB_SSR), + AAC_LTP = (AAC | AAC_SUB_LTP), + AAC_HE_V1 = (AAC | AAC_SUB_HE_V1), + AAC_SCALABLE = (AAC | AAC_SUB_SCALABLE), + AAC_ERLC = (AAC | AAC_SUB_ERLC), + AAC_LD = (AAC | AAC_SUB_LD), + AAC_HE_V2 = (AAC | AAC_SUB_HE_V2), + AAC_ELD = (AAC | AAC_SUB_ELD), + AAC_XHE = (AAC | AAC_SUB_XHE), + AAC_ADTS_MAIN = (AAC_ADTS | AAC_SUB_MAIN), + AAC_ADTS_LC = (AAC_ADTS | AAC_SUB_LC), + AAC_ADTS_SSR = (AAC_ADTS | AAC_SUB_SSR), + AAC_ADTS_LTP = (AAC_ADTS | AAC_SUB_LTP), + AAC_ADTS_HE_V1 = (AAC_ADTS | AAC_SUB_HE_V1), + AAC_ADTS_SCALABLE = (AAC_ADTS | AAC_SUB_SCALABLE), + AAC_ADTS_ERLC = (AAC_ADTS | AAC_SUB_ERLC), + AAC_ADTS_LD = (AAC_ADTS | AAC_SUB_LD), + AAC_ADTS_HE_V2 = (AAC_ADTS | AAC_SUB_HE_V2), + AAC_ADTS_ELD = (AAC_ADTS | AAC_SUB_ELD), + AAC_ADTS_XHE = (AAC_ADTS | AAC_SUB_XHE), + E_AC3_JOC = (E_AC3 | E_AC3_SUB_JOC), + MAT_1_0 = (MAT | MAT_SUB_1_0), + MAT_2_0 = (MAT | MAT_SUB_2_0), + MAT_2_1 = (MAT | MAT_SUB_2_1), + AAC_LATM_LC = (AAC_LATM | AAC_SUB_LC), + AAC_LATM_HE_V1 = (AAC_LATM | AAC_SUB_HE_V1), + AAC_LATM_HE_V2 = (AAC_LATM | AAC_SUB_HE_V2), +}; + +/** + * Usage of these values highlights places in the code that use 2- or 8- channel + * assumptions. + */ +@export(name="") +enum FixedChannelCount : int32_t { + FCC_2 = 2, // This is typically due to legacy implementation of stereo I/O + FCC_8 = 8 // This is typically due to audio mixer and resampler limitations +}; + +/** + * A channel mask per se only defines the presence or absence of a channel, not + * the order. + * + * The channel order convention is that channels are interleaved in order from + * least significant channel mask bit to most significant channel mask bit, + * with unused bits skipped. For example for stereo, LEFT would be first, + * followed by RIGHT. + * Any exceptions to this convention are noted at the appropriate API. + * + * AudioChannelMask is an opaque type and its internal layout should not be + * assumed as it may change in the future. Instead, always use functions + * to examine it. + * + * These are the current representations: + * + * REPRESENTATION_POSITION + * is a channel mask representation for position assignment. Each low-order + * bit corresponds to the spatial position of a transducer (output), or + * interpretation of channel (input). The user of a channel mask needs to + * know the context of whether it is for output or input. The constants + * OUT_* or IN_* apply to the bits portion. It is not permitted for no bits + * to be set. + * + * REPRESENTATION_INDEX + * is a channel mask representation for index assignment. Each low-order + * bit corresponds to a selected channel. There is no platform + * interpretation of the various bits. There is no concept of output or + * input. It is not permitted for no bits to be set. + * + * All other representations are reserved for future use. + * + * Warning: current representation distinguishes between input and output, but + * this will not the be case in future revisions of the platform. Wherever there + * is an ambiguity between input and output that is currently resolved by + * checking the channel mask, the implementer should look for ways to fix it + * with additional information outside of the mask. + */ +@export(name="", value_prefix="AUDIO_CHANNEL_") +enum AudioChannelMask : uint32_t { + /** must be 0 for compatibility */ + REPRESENTATION_POSITION = 0, + /** 1 is reserved for future use */ + REPRESENTATION_INDEX = 2, + /* 3 is reserved for future use */ + + /** These can be a complete value of AudioChannelMask */ + NONE = 0x0, + INVALID = 0xC0000000, + + /* + * These can be the bits portion of an AudioChannelMask + * with representation REPRESENTATION_POSITION. + */ + + /** output channels */ + OUT_FRONT_LEFT = 0x1, + OUT_FRONT_RIGHT = 0x2, + OUT_FRONT_CENTER = 0x4, + OUT_LOW_FREQUENCY = 0x8, + OUT_BACK_LEFT = 0x10, + OUT_BACK_RIGHT = 0x20, + OUT_FRONT_LEFT_OF_CENTER = 0x40, + OUT_FRONT_RIGHT_OF_CENTER = 0x80, + OUT_BACK_CENTER = 0x100, + OUT_SIDE_LEFT = 0x200, + OUT_SIDE_RIGHT = 0x400, + OUT_TOP_CENTER = 0x800, + OUT_TOP_FRONT_LEFT = 0x1000, + OUT_TOP_FRONT_CENTER = 0x2000, + OUT_TOP_FRONT_RIGHT = 0x4000, + OUT_TOP_BACK_LEFT = 0x8000, + OUT_TOP_BACK_CENTER = 0x10000, + OUT_TOP_BACK_RIGHT = 0x20000, + OUT_TOP_SIDE_LEFT = 0x40000, + OUT_TOP_SIDE_RIGHT = 0x80000, + + /** + * Haptic channel characteristics are specific to a device and + * only used to play device specific resources (eg: ringtones). + * The HAL can freely map A and B to haptic controllers, the + * framework shall not interpret those values and forward them + * from the device audio assets. + */ + OUT_HAPTIC_A = 0x20000000, + OUT_HAPTIC_B = 0x10000000, + + OUT_MONO = OUT_FRONT_LEFT, + OUT_STEREO = (OUT_FRONT_LEFT | OUT_FRONT_RIGHT), + OUT_2POINT1 = (OUT_FRONT_LEFT | OUT_FRONT_RIGHT | OUT_LOW_FREQUENCY), + OUT_2POINT0POINT2 = (OUT_FRONT_LEFT | OUT_FRONT_RIGHT | + OUT_TOP_SIDE_LEFT | OUT_TOP_SIDE_RIGHT), + OUT_2POINT1POINT2 = (OUT_FRONT_LEFT | OUT_FRONT_RIGHT | + OUT_TOP_SIDE_LEFT | OUT_TOP_SIDE_RIGHT | + OUT_LOW_FREQUENCY), + OUT_3POINT0POINT2 = (OUT_FRONT_LEFT | OUT_FRONT_RIGHT | OUT_FRONT_CENTER | + OUT_TOP_SIDE_LEFT | OUT_TOP_SIDE_RIGHT), + OUT_3POINT1POINT2 = (OUT_FRONT_LEFT | OUT_FRONT_RIGHT | OUT_FRONT_CENTER | + OUT_TOP_SIDE_LEFT | OUT_TOP_SIDE_RIGHT | + OUT_LOW_FREQUENCY), + OUT_QUAD = (OUT_FRONT_LEFT | OUT_FRONT_RIGHT | + OUT_BACK_LEFT | OUT_BACK_RIGHT), + OUT_QUAD_BACK = OUT_QUAD, + /** like OUT_QUAD_BACK with *_SIDE_* instead of *_BACK_* */ + OUT_QUAD_SIDE = (OUT_FRONT_LEFT | OUT_FRONT_RIGHT | + OUT_SIDE_LEFT | OUT_SIDE_RIGHT), + OUT_SURROUND = (OUT_FRONT_LEFT | OUT_FRONT_RIGHT | + OUT_FRONT_CENTER | OUT_BACK_CENTER), + OUT_PENTA = (OUT_QUAD | OUT_FRONT_CENTER), + OUT_5POINT1 = (OUT_FRONT_LEFT | OUT_FRONT_RIGHT | + OUT_FRONT_CENTER | OUT_LOW_FREQUENCY | + OUT_BACK_LEFT | OUT_BACK_RIGHT), + OUT_5POINT1_BACK = OUT_5POINT1, + /** like OUT_5POINT1_BACK with *_SIDE_* instead of *_BACK_* */ + OUT_5POINT1_SIDE = (OUT_FRONT_LEFT | OUT_FRONT_RIGHT | + OUT_FRONT_CENTER | OUT_LOW_FREQUENCY | + OUT_SIDE_LEFT | OUT_SIDE_RIGHT), + OUT_5POINT1POINT2 = (OUT_5POINT1 | OUT_TOP_SIDE_LEFT | OUT_TOP_SIDE_RIGHT), + OUT_5POINT1POINT4 = (OUT_5POINT1 | + OUT_TOP_FRONT_LEFT | OUT_TOP_FRONT_RIGHT | + OUT_TOP_BACK_LEFT | OUT_TOP_BACK_RIGHT), + OUT_6POINT1 = (OUT_FRONT_LEFT | OUT_FRONT_RIGHT | + OUT_FRONT_CENTER | OUT_LOW_FREQUENCY | + OUT_BACK_LEFT | OUT_BACK_RIGHT | + OUT_BACK_CENTER), + /** matches the correct AudioFormat.CHANNEL_OUT_7POINT1_SURROUND */ + OUT_7POINT1 = (OUT_FRONT_LEFT | OUT_FRONT_RIGHT | + OUT_FRONT_CENTER | OUT_LOW_FREQUENCY | + OUT_BACK_LEFT | OUT_BACK_RIGHT | + OUT_SIDE_LEFT | OUT_SIDE_RIGHT), + OUT_7POINT1POINT2 = (OUT_7POINT1 | OUT_TOP_SIDE_LEFT | OUT_TOP_SIDE_RIGHT), + OUT_7POINT1POINT4 = (OUT_7POINT1 | + OUT_TOP_FRONT_LEFT | OUT_TOP_FRONT_RIGHT | + OUT_TOP_BACK_LEFT | OUT_TOP_BACK_RIGHT), + OUT_MONO_HAPTIC_A = (OUT_FRONT_LEFT | OUT_HAPTIC_A), + OUT_STEREO_HAPTIC_A = (OUT_FRONT_LEFT | OUT_FRONT_RIGHT | OUT_HAPTIC_A), + OUT_HAPTIC_AB = (OUT_HAPTIC_A | OUT_HAPTIC_B), + OUT_MONO_HAPTIC_AB = (OUT_FRONT_LEFT | OUT_HAPTIC_A | OUT_HAPTIC_B), + OUT_STEREO_HAPTIC_AB = (OUT_FRONT_LEFT | OUT_FRONT_RIGHT | + OUT_HAPTIC_A | OUT_HAPTIC_B), + // Note that the 2.0 OUT_ALL* have been moved to helper functions + + /* These are bits only, not complete values */ + + /** input channels */ + IN_LEFT = 0x4, + IN_RIGHT = 0x8, + IN_FRONT = 0x10, + IN_BACK = 0x20, + IN_LEFT_PROCESSED = 0x40, + IN_RIGHT_PROCESSED = 0x80, + IN_FRONT_PROCESSED = 0x100, + IN_BACK_PROCESSED = 0x200, + IN_PRESSURE = 0x400, + IN_X_AXIS = 0x800, + IN_Y_AXIS = 0x1000, + IN_Z_AXIS = 0x2000, + IN_BACK_LEFT = 0x10000, + IN_BACK_RIGHT = 0x20000, + IN_CENTER = 0x40000, + IN_LOW_FREQUENCY = 0x100000, + IN_TOP_LEFT = 0x200000, + IN_TOP_RIGHT = 0x400000, + + IN_VOICE_UPLINK = 0x4000, + IN_VOICE_DNLINK = 0x8000, + + IN_MONO = IN_FRONT, + IN_STEREO = (IN_LEFT | IN_RIGHT), + IN_FRONT_BACK = (IN_FRONT | IN_BACK), + IN_6 = (IN_LEFT | IN_RIGHT | + IN_FRONT | IN_BACK | + IN_LEFT_PROCESSED | IN_RIGHT_PROCESSED), + IN_2POINT0POINT2 = (IN_LEFT | IN_RIGHT | IN_TOP_LEFT | IN_TOP_RIGHT), + IN_2POINT1POINT2 = (IN_LEFT | IN_RIGHT | IN_TOP_LEFT | IN_TOP_RIGHT | + IN_LOW_FREQUENCY), + IN_3POINT0POINT2 = (IN_LEFT | IN_CENTER | IN_RIGHT | IN_TOP_LEFT | IN_TOP_RIGHT), + IN_3POINT1POINT2 = (IN_LEFT | IN_CENTER | IN_RIGHT | + IN_TOP_LEFT | IN_TOP_RIGHT | IN_LOW_FREQUENCY), + IN_5POINT1 = (IN_LEFT | IN_CENTER | IN_RIGHT | + IN_BACK_LEFT | IN_BACK_RIGHT | IN_LOW_FREQUENCY), + IN_VOICE_UPLINK_MONO = (IN_VOICE_UPLINK | IN_MONO), + IN_VOICE_DNLINK_MONO = (IN_VOICE_DNLINK | IN_MONO), + IN_VOICE_CALL_MONO = (IN_VOICE_UPLINK_MONO | + IN_VOICE_DNLINK_MONO), + // Note that the 2.0 IN_ALL* have been moved to helper functions + + COUNT_MAX = 30, + INDEX_HDR = REPRESENTATION_INDEX << COUNT_MAX, + INDEX_MASK_1 = INDEX_HDR | ((1 << 1) - 1), + INDEX_MASK_2 = INDEX_HDR | ((1 << 2) - 1), + INDEX_MASK_3 = INDEX_HDR | ((1 << 3) - 1), + INDEX_MASK_4 = INDEX_HDR | ((1 << 4) - 1), + INDEX_MASK_5 = INDEX_HDR | ((1 << 5) - 1), + INDEX_MASK_6 = INDEX_HDR | ((1 << 6) - 1), + INDEX_MASK_7 = INDEX_HDR | ((1 << 7) - 1), + INDEX_MASK_8 = INDEX_HDR | ((1 << 8) - 1), + INDEX_MASK_9 = INDEX_HDR | ((1 << 9) - 1), + INDEX_MASK_10 = INDEX_HDR | ((1 << 10) - 1), + INDEX_MASK_11 = INDEX_HDR | ((1 << 11) - 1), + INDEX_MASK_12 = INDEX_HDR | ((1 << 12) - 1), + INDEX_MASK_13 = INDEX_HDR | ((1 << 13) - 1), + INDEX_MASK_14 = INDEX_HDR | ((1 << 14) - 1), + INDEX_MASK_15 = INDEX_HDR | ((1 << 15) - 1), + INDEX_MASK_16 = INDEX_HDR | ((1 << 16) - 1), + INDEX_MASK_17 = INDEX_HDR | ((1 << 17) - 1), + INDEX_MASK_18 = INDEX_HDR | ((1 << 18) - 1), + INDEX_MASK_19 = INDEX_HDR | ((1 << 19) - 1), + INDEX_MASK_20 = INDEX_HDR | ((1 << 20) - 1), + INDEX_MASK_21 = INDEX_HDR | ((1 << 21) - 1), + INDEX_MASK_22 = INDEX_HDR | ((1 << 22) - 1), + INDEX_MASK_23 = INDEX_HDR | ((1 << 23) - 1), + INDEX_MASK_24 = INDEX_HDR | ((1 << 24) - 1), +}; + +/** + * Major modes for a mobile device. The current mode setting affects audio + * routing. + */ +@export(name="audio_mode_t", value_prefix="AUDIO_MODE_") +enum AudioMode : int32_t { + NORMAL = 0, + RINGTONE = 1, + /** Calls handled by the telephony stack (Eg: PSTN). */ + IN_CALL = 2, + /** Calls handled by apps (Eg: Hangout). */ + IN_COMMUNICATION = 3, + /** Call screening in progress. */ + CALL_SCREEN = 4, +}; + +@export(name="", value_prefix="AUDIO_DEVICE_") +enum AudioDevice : uint32_t { + NONE = 0x0, + /** reserved bits */ + BIT_IN = 0x80000000, + BIT_DEFAULT = 0x40000000, + /** output devices */ + OUT_EARPIECE = 0x1, + OUT_SPEAKER = 0x2, + OUT_WIRED_HEADSET = 0x4, + OUT_WIRED_HEADPHONE = 0x8, + OUT_BLUETOOTH_SCO = 0x10, + OUT_BLUETOOTH_SCO_HEADSET = 0x20, + OUT_BLUETOOTH_SCO_CARKIT = 0x40, + OUT_BLUETOOTH_A2DP = 0x80, + OUT_BLUETOOTH_A2DP_HEADPHONES = 0x100, + OUT_BLUETOOTH_A2DP_SPEAKER = 0x200, + OUT_AUX_DIGITAL = 0x400, + OUT_HDMI = OUT_AUX_DIGITAL, + /** uses an analog connection (multiplexed over the USB pins for instance) */ + OUT_ANLG_DOCK_HEADSET = 0x800, + OUT_DGTL_DOCK_HEADSET = 0x1000, + /** USB accessory mode: Android device is USB device and dock is USB host */ + OUT_USB_ACCESSORY = 0x2000, + /** USB host mode: Android device is USB host and dock is USB device */ + OUT_USB_DEVICE = 0x4000, + OUT_REMOTE_SUBMIX = 0x8000, + /** Telephony voice TX path */ + OUT_TELEPHONY_TX = 0x10000, + /** Analog jack with line impedance detected */ + OUT_LINE = 0x20000, + /** HDMI Audio Return Channel */ + OUT_HDMI_ARC = 0x40000, + /** S/PDIF out */ + OUT_SPDIF = 0x80000, + /** FM transmitter out */ + OUT_FM = 0x100000, + /** Line out for av devices */ + OUT_AUX_LINE = 0x200000, + /** limited-output speaker device for acoustic safety */ + OUT_SPEAKER_SAFE = 0x400000, + OUT_IP = 0x800000, + /** audio bus implemented by the audio system (e.g an MOST stereo channel) */ + OUT_BUS = 0x1000000, + OUT_PROXY = 0x2000000, + OUT_USB_HEADSET = 0x4000000, + OUT_HEARING_AID = 0x8000000, + OUT_ECHO_CANCELLER = 0x10000000, + OUT_DEFAULT = BIT_DEFAULT, + // Note that the 2.0 OUT_ALL* have been moved to helper functions + + /** input devices */ + IN_COMMUNICATION = BIT_IN | 0x1, + IN_AMBIENT = BIT_IN | 0x2, + IN_BUILTIN_MIC = BIT_IN | 0x4, + IN_BLUETOOTH_SCO_HEADSET = BIT_IN | 0x8, + IN_WIRED_HEADSET = BIT_IN | 0x10, + IN_AUX_DIGITAL = BIT_IN | 0x20, + IN_HDMI = IN_AUX_DIGITAL, + /** Telephony voice RX path */ + IN_VOICE_CALL = BIT_IN | 0x40, + IN_TELEPHONY_RX = IN_VOICE_CALL, + IN_BACK_MIC = BIT_IN | 0x80, + IN_REMOTE_SUBMIX = BIT_IN | 0x100, + IN_ANLG_DOCK_HEADSET = BIT_IN | 0x200, + IN_DGTL_DOCK_HEADSET = BIT_IN | 0x400, + IN_USB_ACCESSORY = BIT_IN | 0x800, + IN_USB_DEVICE = BIT_IN | 0x1000, + /** FM tuner input */ + IN_FM_TUNER = BIT_IN | 0x2000, + /** TV tuner input */ + IN_TV_TUNER = BIT_IN | 0x4000, + /** Analog jack with line impedance detected */ + IN_LINE = BIT_IN | 0x8000, + /** S/PDIF in */ + IN_SPDIF = BIT_IN | 0x10000, + IN_BLUETOOTH_A2DP = BIT_IN | 0x20000, + IN_LOOPBACK = BIT_IN | 0x40000, + IN_IP = BIT_IN | 0x80000, + /** audio bus implemented by the audio system (e.g an MOST stereo channel) */ + IN_BUS = BIT_IN | 0x100000, + IN_PROXY = BIT_IN | 0x1000000, + IN_USB_HEADSET = BIT_IN | 0x2000000, + IN_BLUETOOTH_BLE = BIT_IN | 0x4000000, + IN_ECHO_REFERENCE = BIT_IN | 0x10000000, + IN_DEFAULT = BIT_IN | BIT_DEFAULT, + + // Note that the 2.0 IN_ALL* have been moved to helper functions +}; + +/** + * IEEE 802 MAC address. + */ +typedef uint8_t[6] MacAddress; + +/** + * Specifies a device address in case when several devices of the same type + * can be connected (e.g. BT A2DP, USB). + */ +struct DeviceAddress { + AudioDevice device; // discriminator + union Address { + MacAddress mac; // used for BLUETOOTH_A2DP_* + uint8_t[4] ipv4; // used for IP + struct Alsa { + int32_t card; + int32_t device; + } alsa; // used for USB_* + } address; + /** Arbitrary BUS device unique address. Should not be interpreted by the framework. */ + string busAddress; + /** Arbitrary REMOTE_SUBMIX device unique address. Should not be interpreted by the HAL. */ + string rSubmixAddress; +}; + +/** + * The audio output flags serve two purposes: + * + * - when an AudioTrack is created they indicate a "wish" to be connected to an + * output stream with attributes corresponding to the specified flags; + * + * - when present in an output profile descriptor listed for a particular audio + * hardware module, they indicate that an output stream can be opened that + * supports the attributes indicated by the flags. + * + * The audio policy manager will try to match the flags in the request + * (when getOuput() is called) to an available output stream. + */ +@export(name="audio_output_flags_t", value_prefix="AUDIO_OUTPUT_FLAG_") +enum AudioOutputFlag : int32_t { + NONE = 0x0, // no attributes + DIRECT = 0x1, // this output directly connects a track + // to one output stream: no software mixer + PRIMARY = 0x2, // this output is the primary output of the device. It is + // unique and must be present. It is opened by default and + // receives routing, audio mode and volume controls related + // to voice calls. + FAST = 0x4, // output supports "fast tracks", defined elsewhere + DEEP_BUFFER = 0x8, // use deep audio buffers + COMPRESS_OFFLOAD = 0x10, // offload playback of compressed streams to + // hardware codec + NON_BLOCKING = 0x20, // use non-blocking write + HW_AV_SYNC = 0x40, // output uses a hardware A/V sync + TTS = 0x80, // output for streams transmitted through speaker at a + // sample rate high enough to accommodate lower-range + // ultrasonic p/b + RAW = 0x100, // minimize signal processing + SYNC = 0x200, // synchronize I/O streams + IEC958_NONAUDIO = 0x400, // Audio stream contains compressed audio in SPDIF + // data bursts, not PCM. + DIRECT_PCM = 0x2000, // Audio stream containing PCM data that needs + // to pass through compress path for DSP post proc. + MMAP_NOIRQ = 0x4000, // output operates in MMAP no IRQ mode. + VOIP_RX = 0x8000, // preferred output for VoIP calls. + /** preferred output for call music */ + INCALL_MUSIC = 0x10000, +}; + +/** + * The audio input flags are analogous to audio output flags. + * Currently they are used only when an AudioRecord is created, + * to indicate a preference to be connected to an input stream with + * attributes corresponding to the specified flags. + */ +@export(name="audio_input_flags_t", value_prefix="AUDIO_INPUT_FLAG_") +enum AudioInputFlag : int32_t { + NONE = 0x0, // no attributes + FAST = 0x1, // prefer an input that supports "fast tracks" + HW_HOTWORD = 0x2, // prefer an input that captures from hw hotword source + RAW = 0x4, // minimize signal processing + SYNC = 0x8, // synchronize I/O streams + MMAP_NOIRQ = 0x10, // input operates in MMAP no IRQ mode. + VOIP_TX = 0x20, // preferred input for VoIP calls. + HW_AV_SYNC = 0x40, // input connected to an output that uses a hardware A/V sync + DIRECT = 0x80, // for acquiring encoded streams +}; + +@export(name="audio_usage_t", value_prefix="AUDIO_USAGE_") +enum AudioUsage : int32_t { + // These values must kept in sync with + // frameworks/base/media/java/android/media/AudioAttributes.java + // Note that not all framework values are exposed + /** + * Usage value to use when the usage is unknown. + */ + UNKNOWN = 0, + /** + * Usage value to use when the usage is media, such as music, or movie + * soundtracks. + */ + MEDIA = 1, + /** + * Usage value to use when the usage is voice communications, such as + * telephony or VoIP. + */ + VOICE_COMMUNICATION = 2, + /** + * Usage value to use when the usage is in-call signalling, such as with + * a "busy" beep, or DTMF tones. + */ + VOICE_COMMUNICATION_SIGNALLING = 3, + /** + * Usage value to use when the usage is an alarm (e.g. wake-up alarm). + */ + ALARM = 4, + /** + * Usage value to use when the usage is a generic notification. + */ + NOTIFICATION = 5, + /** + * Usage value to use when the usage is telephony ringtone. + */ + NOTIFICATION_TELEPHONY_RINGTONE = 6, + /** + * Usage value to use when the usage is for accessibility, such as with + * a screen reader. + */ + ASSISTANCE_ACCESSIBILITY = 11, + /** + * Usage value to use when the usage is driving or navigation directions. + */ + ASSISTANCE_NAVIGATION_GUIDANCE = 12, + /** + * Usage value to use when the usage is sonification, such as with user + * interface sounds. + */ + ASSISTANCE_SONIFICATION = 13, + /** + * Usage value to use when the usage is for game audio. + */ + GAME = 14, + /** + * Usage value to use when feeding audio to the platform and replacing + * "traditional" audio source, such as audio capture devices. + */ + VIRTUAL_SOURCE = 15, + /** + * Usage value to use for audio responses to user queries, audio + * instructions or help utterances. + */ + ASSISTANT = 16, + /** + * Usage value to use for assistant voice interaction with remote caller + * on Cell and VoIP calls. + */ + CALL_ASSISTANT = 17, + /** + * Usage value to use when the usage is an emergency. + */ + EMERGENCY = 1000, + /** + * Usage value to use when the usage is a safety sound. + */ + SAFETY = 1001, + /** + * Usage value to use when the usage is a vehicle status. + */ + VEHICLE_STATUS = 1002, + /** + * Usage value to use when the usage is an announcement. + */ + ANNOUNCEMENT = 1003, +}; + +/** Type of audio generated by an application. */ +@export(name="audio_content_type_t", value_prefix="AUDIO_CONTENT_TYPE_") +enum AudioContentType : uint32_t { + // Do not change these values without updating their counterparts + // in frameworks/base/media/java/android/media/AudioAttributes.java + /** + * Content type value to use when the content type is unknown, or other than + * the ones defined. + */ + UNKNOWN = 0, + /** + * Content type value to use when the content type is speech. + */ + SPEECH = 1, + /** + * Content type value to use when the content type is music. + */ + MUSIC = 2, + /** + * Content type value to use when the content type is a soundtrack, + * typically accompanying a movie or TV program. + */ + MOVIE = 3, + /** + * Content type value to use when the content type is a sound used to + * accompany a user action, such as a beep or sound effect expressing a key + * click, or event, such as the type of a sound for a bonus being received + * in a game. These sounds are mostly synthesized or short Foley sounds. + */ + SONIFICATION = 4, +}; + +/** Encapsulation mode used for sending audio compressed data. */ +@export(name="audio_encapsulation_mode_t", value_prefix="AUDIO_ENCAPSULATION_MODE_") +enum AudioEncapsulationMode : int32_t { + // Do not change these values without updating their counterparts + // in frameworks/base/media/java/android/media/AudioTrack.java + /** + * No encapsulation mode for metadata. + */ + NONE = 0, + /** + * Elementary stream payload with metadata + */ + ELEMENTARY_STREAM = 1, + /** + * Handle-based payload with metadata + */ + HANDLE = 2, +}; + +/** + * Additional information about the stream passed to hardware decoders. + */ +struct AudioOffloadInfo { + uint32_t sampleRateHz; + bitfield channelMask; + AudioFormat format; + AudioStreamType streamType; + uint32_t bitRatePerSecond; + int64_t durationMicroseconds; // -1 if unknown + bool hasVideo; + bool isStreaming; + uint32_t bitWidth; + uint32_t bufferSize; + AudioUsage usage; + AudioEncapsulationMode encapsulationMode; + int32_t contentId; + int32_t syncId; +}; + +/** + * Commonly used audio stream configuration parameters. + */ +struct AudioConfig { + uint32_t sampleRateHz; + bitfield channelMask; + AudioFormat format; + AudioOffloadInfo offloadInfo; + uint64_t frameCount; +}; + +/** Metadata of a playback track for a StreamOut. */ +struct PlaybackTrackMetadata { + AudioUsage usage; + AudioContentType contentType; + /** + * Positive linear gain applied to the track samples. 0 being muted and 1 is no attenuation, + * 2 means double amplification... + * Must not be negative. + */ + float gain; +}; + +/** Metadatas of the source of a StreamOut. */ +struct SourceMetadata { + vec tracks; +}; + +/** Metadata of a record track for a StreamIn. */ +struct RecordTrackMetadata { + AudioSource source; + /** + * Positive linear gain applied to the track samples. 0 being muted and 1 is no attenuation, + * 2 means double amplification... + * Must not be negative. + */ + float gain; + /** + * Indicates the destination of an input stream, can be left unspecified. + */ + safe_union Destination { + Monostate unspecified; + DeviceAddress device; + }; + Destination destination; +}; + +/** Metadatas of the sink of a StreamIn. */ +struct SinkMetadata { + vec tracks; +}; + + +/* + * + * Volume control + * + */ + +/** + * Type of gain control exposed by an audio port. + */ +@export(name="", value_prefix="AUDIO_GAIN_MODE_") +enum AudioGainMode : uint32_t { + JOINT = 0x1, // supports joint channel gain control + CHANNELS = 0x2, // supports separate channel gain control + RAMP = 0x4 // supports gain ramps +}; + +/** + * An audio_gain struct is a representation of a gain stage. + * A gain stage is always attached to an audio port. + */ +struct AudioGain { + bitfield mode; + bitfield channelMask; // channels which gain an be controlled + int32_t minValue; // minimum gain value in millibels + int32_t maxValue; // maximum gain value in millibels + int32_t defaultValue; // default gain value in millibels + uint32_t stepValue; // gain step in millibels + uint32_t minRampMs; // minimum ramp duration in ms + uint32_t maxRampMs; // maximum ramp duration in ms +}; + +/** + * The gain configuration structure is used to get or set the gain values of a + * given port. + */ +struct AudioGainConfig { + int32_t index; // index of the corresponding AudioGain in AudioPort.gains + AudioGainMode mode; + AudioChannelMask channelMask; // channels which gain value follows + /** + * 4 = sizeof(AudioChannelMask), + * 8 is not "FCC_8", so it won't need to be changed for > 8 channels. + * Gain values in millibels for each channel ordered from LSb to MSb in + * channel mask. The number of values is 1 in joint mode or + * popcount(channel_mask). + */ + int32_t[4 * 8] values; + uint32_t rampDurationMs; // ramp duration in ms +}; + + +/* + * + * Routing control + * + */ + +/* + * Types defined here are used to describe an audio source or sink at internal + * framework interfaces (audio policy, patch panel) or at the audio HAL. + * Sink and sources are grouped in a concept of “audio port” representing an + * audio end point at the edge of the system managed by the module exposing + * the interface. + */ + +/** Audio port role: either source or sink */ +@export(name="audio_port_role_t", value_prefix="AUDIO_PORT_ROLE_") +enum AudioPortRole : int32_t { + NONE, + SOURCE, + SINK, +}; + +/** + * Audio port type indicates if it is a session (e.g AudioTrack), a mix (e.g + * PlaybackThread output) or a physical device (e.g OUT_SPEAKER) + */ +@export(name="audio_port_type_t", value_prefix="AUDIO_PORT_TYPE_") +enum AudioPortType : int32_t { + NONE, + DEVICE, + MIX, + SESSION, +}; + +/** + * Extension for audio port configuration structure when the audio port is a + * hardware device. + */ +struct AudioPortConfigDeviceExt { + AudioModuleHandle hwModule; // module the device is attached to + AudioDevice type; // device type (e.g OUT_SPEAKER) + uint8_t[32] address; // device address. "" if N/A +}; + +/** + * Extension for audio port configuration structure when the audio port is an + * audio session. + */ +struct AudioPortConfigSessionExt { + AudioSession session; +}; + +/** + * Flags indicating which fields are to be considered in AudioPortConfig. + */ +@export(name="", value_prefix="AUDIO_PORT_CONFIG_") +enum AudioPortConfigMask : uint32_t { + SAMPLE_RATE = 0x1, + CHANNEL_MASK = 0x2, + FORMAT = 0x4, + GAIN = 0x8, +}; + +/** + * Audio port configuration structure used to specify a particular configuration + * of an audio port. + */ +struct AudioPortConfig { + AudioPortHandle id; + bitfield configMask; + uint32_t sampleRateHz; + bitfield channelMask; + AudioFormat format; + AudioGainConfig gain; + AudioPortType type; // type is used as a discriminator for Ext union + AudioPortRole role; // role is used as a discriminator for UseCase union + union Ext { + AudioPortConfigDeviceExt device; + struct AudioPortConfigMixExt { + AudioModuleHandle hwModule; // module the stream is attached to + AudioIoHandle ioHandle; // I/O handle of the input/output stream + union UseCase { + AudioStreamType stream; + AudioSource source; + } useCase; + } mix; + AudioPortConfigSessionExt session; + } ext; +}; + +/** + * Extension for audio port structure when the audio port is a hardware device. + */ +struct AudioPortDeviceExt { + AudioModuleHandle hwModule; // module the device is attached to + AudioDevice type; + /** 32 byte string identifying the port. */ + uint8_t[32] address; +}; + +/** + * Latency class of the audio mix. + */ +@export(name="audio_mix_latency_class_t", value_prefix="AUDIO_LATENCY_") +enum AudioMixLatencyClass : int32_t { + LOW, + NORMAL +}; + +struct AudioPortMixExt { + AudioModuleHandle hwModule; // module the stream is attached to + AudioIoHandle ioHandle; // I/O handle of the stream + AudioMixLatencyClass latencyClass; +}; + +/** + * Extension for audio port structure when the audio port is an audio session. + */ +struct AudioPortSessionExt { + AudioSession session; +}; + +struct AudioPort { + AudioPortHandle id; + AudioPortRole role; + string name; + vec sampleRates; + vec> channelMasks; + vec formats; + vec gains; + AudioPortConfig activeConfig; // current audio port configuration + AudioPortType type; // type is used as a discriminator + union Ext { + AudioPortDeviceExt device; + AudioPortMixExt mix; + AudioPortSessionExt session; + } ext; +}; + +struct ThreadInfo { + int64_t pid; + int64_t tid; +}; diff --git a/audio/common/all-versions/default/Android.bp b/audio/common/all-versions/default/Android.bp index 0eb4a71348..5caddcf3fa 100644 --- a/audio/common/all-versions/default/Android.bp +++ b/audio/common/all-versions/default/Android.bp @@ -117,3 +117,16 @@ cc_library_shared { "-include common/all-versions/VersionMacro.h", ] } + +cc_library_shared { + name: "android.hardware.audio.common@7.0-util", + defaults: ["android.hardware.audio.common-util_default"], + shared_libs: [ + "android.hardware.audio.common@7.0", + ], + cflags: [ + "-DMAJOR_VERSION=7", + "-DMINOR_VERSION=0", + "-include common/all-versions/VersionMacro.h", + ] +} diff --git a/audio/core/all-versions/default/Android.bp b/audio/core/all-versions/default/Android.bp index 8fdb70d1a2..46f64b70f3 100644 --- a/audio/core/all-versions/default/Android.bp +++ b/audio/core/all-versions/default/Android.bp @@ -123,3 +123,18 @@ cc_library_shared { name: "android.hardware.audio@6.0-impl", defaults: ["android.hardware.audio@6.0-impl_default"], } + +cc_library_shared { + name: "android.hardware.audio@7.0-impl", + defaults: ["android.hardware.audio-impl_default"], + shared_libs: [ + "android.hardware.audio@7.0", + "android.hardware.audio.common@7.0", + "android.hardware.audio.common@7.0-util", + ], + cflags: [ + "-DMAJOR_VERSION=7", + "-DMINOR_VERSION=0", + "-include common/all-versions/VersionMacro.h", + ], +} diff --git a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp new file mode 100644 index 0000000000..33efa6f4d6 --- /dev/null +++ b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp @@ -0,0 +1,18 @@ +/* + * 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. + */ + +// pull in all the <= 6.0 tests +#include "6.0/AudioPrimaryHidlHalTest.cpp" diff --git a/audio/core/all-versions/vts/functional/Android.bp b/audio/core/all-versions/vts/functional/Android.bp index 2d5e8a5c92..598944a80f 100644 --- a/audio/core/all-versions/vts/functional/Android.bp +++ b/audio/core/all-versions/vts/functional/Android.bp @@ -128,3 +128,26 @@ cc_test { // TODO(b/146104851): Add auto-gen rules and remove it. test_config: "VtsHalAudioV6_0TargetTest.xml", } + +cc_test { + name: "VtsHalAudioV7_0TargetTest", + defaults: ["VtsHalAudioTargetTest_defaults"], + srcs: [ + "7.0/AudioPrimaryHidlHalTest.cpp", + ], + static_libs: [ + "android.hardware.audio@7.0", + "android.hardware.audio.common@7.0", + ], + cflags: [ + "-DMAJOR_VERSION=7", + "-DMINOR_VERSION=0", + "-include common/all-versions/VersionMacro.h", + ], + data: [ + ":audio_policy_configuration_V7_0", + ], + // Use test_config for vts suite. + // TODO(b/146104851): Add auto-gen rules and remove it. + test_config: "VtsHalAudioV7_0TargetTest.xml", +} diff --git a/audio/core/all-versions/vts/functional/VtsHalAudioV7_0TargetTest.xml b/audio/core/all-versions/vts/functional/VtsHalAudioV7_0TargetTest.xml new file mode 100644 index 0000000000..6635f3194a --- /dev/null +++ b/audio/core/all-versions/vts/functional/VtsHalAudioV7_0TargetTest.xml @@ -0,0 +1,38 @@ + + + + diff --git a/audio/effect/7.0/Android.bp b/audio/effect/7.0/Android.bp new file mode 100644 index 0000000000..c1137827cf --- /dev/null +++ b/audio/effect/7.0/Android.bp @@ -0,0 +1,30 @@ +// This file is autogenerated by hidl-gen -Landroidbp. + +hidl_interface { + name: "android.hardware.audio.effect@7.0", + root: "android.hardware", + srcs: [ + "types.hal", + "IAcousticEchoCancelerEffect.hal", + "IAutomaticGainControlEffect.hal", + "IBassBoostEffect.hal", + "IDownmixEffect.hal", + "IEffect.hal", + "IEffectBufferProviderCallback.hal", + "IEffectsFactory.hal", + "IEnvironmentalReverbEffect.hal", + "IEqualizerEffect.hal", + "ILoudnessEnhancerEffect.hal", + "INoiseSuppressionEffect.hal", + "IPresetReverbEffect.hal", + "IVirtualizerEffect.hal", + "IVisualizerEffect.hal", + ], + interfaces: [ + "android.hardware.audio.common@7.0", + "android.hidl.base@1.0", + "android.hidl.safe_union@1.0", + ], + gen_java: false, + gen_java_constants: true, +} diff --git a/audio/effect/7.0/IAcousticEchoCancelerEffect.hal b/audio/effect/7.0/IAcousticEchoCancelerEffect.hal new file mode 100644 index 0000000000..2bc2a7fdbf --- /dev/null +++ b/audio/effect/7.0/IAcousticEchoCancelerEffect.hal @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.audio.effect@7.0; + +import android.hardware.audio.common@7.0; +import IEffect; + +interface IAcousticEchoCancelerEffect extends IEffect { + /** + * Sets echo delay value in milliseconds. + */ + setEchoDelay(uint32_t echoDelayMs) generates (Result retval); + + /** + * Gets echo delay value in milliseconds. + */ + getEchoDelay() generates (Result retval, uint32_t echoDelayMs); +}; diff --git a/audio/effect/7.0/IAutomaticGainControlEffect.hal b/audio/effect/7.0/IAutomaticGainControlEffect.hal new file mode 100644 index 0000000000..8ffa659db9 --- /dev/null +++ b/audio/effect/7.0/IAutomaticGainControlEffect.hal @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.audio.effect@7.0; + +import android.hardware.audio.common@7.0; +import IEffect; + +interface IAutomaticGainControlEffect extends IEffect { + /** + * Sets target level in millibels. + */ + setTargetLevel(int16_t targetLevelMb) generates (Result retval); + + /** + * Gets target level. + */ + getTargetLevel() generates (Result retval, int16_t targetLevelMb); + + /** + * Sets gain in the compression range in millibels. + */ + setCompGain(int16_t compGainMb) generates (Result retval); + + /** + * Gets gain in the compression range. + */ + getCompGain() generates (Result retval, int16_t compGainMb); + + /** + * Enables or disables limiter. + */ + setLimiterEnabled(bool enabled) generates (Result retval); + + /** + * Returns whether limiter is enabled. + */ + isLimiterEnabled() generates (Result retval, bool enabled); + + struct AllProperties { + int16_t targetLevelMb; + int16_t compGainMb; + bool limiterEnabled; + }; + + /** + * Sets all properties at once. + */ + setAllProperties(AllProperties properties) generates (Result retval); + + /** + * Gets all properties at once. + */ + getAllProperties() generates (Result retval, AllProperties properties); +}; diff --git a/audio/effect/7.0/IBassBoostEffect.hal b/audio/effect/7.0/IBassBoostEffect.hal new file mode 100644 index 0000000000..d8d049ed10 --- /dev/null +++ b/audio/effect/7.0/IBassBoostEffect.hal @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.audio.effect@7.0; + +import android.hardware.audio.common@7.0; +import IEffect; + +interface IBassBoostEffect extends IEffect { + /** + * Returns whether setting bass boost strength is supported. + */ + isStrengthSupported() generates (Result retval, bool strengthSupported); + + enum StrengthRange : uint16_t { + MIN = 0, + MAX = 1000 + }; + + /** + * Sets bass boost strength. + * + * @param strength strength of the effect. The valid range for strength + * strength is [0, 1000], where 0 per mille designates the + * mildest effect and 1000 per mille designates the + * strongest. + * @return retval operation completion status. + */ + setStrength(uint16_t strength) generates (Result retval); + + /** + * Gets virtualization strength. + */ + getStrength() generates (Result retval, uint16_t strength); +}; diff --git a/audio/effect/7.0/IDownmixEffect.hal b/audio/effect/7.0/IDownmixEffect.hal new file mode 100644 index 0000000000..2035430ee6 --- /dev/null +++ b/audio/effect/7.0/IDownmixEffect.hal @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.audio.effect@7.0; + +import android.hardware.audio.common@7.0; +import IEffect; + +interface IDownmixEffect extends IEffect { + enum Type : int32_t { + STRIP, // throw away the extra channels + FOLD // mix the extra channels with FL/FR + }; + + /** + * Sets the current downmix preset. + */ + setType(Type preset) generates (Result retval); + + /** + * Gets the current downmix preset. + */ + getType() generates (Result retval, Type preset); +}; diff --git a/audio/effect/7.0/IEffect.hal b/audio/effect/7.0/IEffect.hal new file mode 100644 index 0000000000..5b176dc2f3 --- /dev/null +++ b/audio/effect/7.0/IEffect.hal @@ -0,0 +1,421 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.audio.effect@7.0; + +import android.hardware.audio.common@7.0; +import IEffectBufferProviderCallback; + +interface IEffect { + /** + * Initialize effect engine--all configurations return to default. + * + * @return retval operation completion status. + */ + @entry + init() generates (Result retval); + + /** + * Apply new audio parameters configurations for input and output buffers. + * The provider callbacks may be empty, but in this case the buffer + * must be provided in the EffectConfig structure. + * + * @param config configuration descriptor. + * @param inputBufferProvider optional buffer provider reference. + * @param outputBufferProvider optional buffer provider reference. + * @return retval operation completion status. + */ + setConfig(EffectConfig config, + IEffectBufferProviderCallback inputBufferProvider, + IEffectBufferProviderCallback outputBufferProvider) + generates (Result retval); + + /** + * Reset the effect engine. Keep configuration but resets state and buffer + * content. + * + * @return retval operation completion status. + */ + reset() generates (Result retval); + + /** + * Enable processing. + * + * @return retval operation completion status. + */ + @callflow(next={"prepareForProcessing"}) + enable() generates (Result retval); + + /** + * Disable processing. + * + * @return retval operation completion status. + */ + @callflow(next={"close"}) + disable() generates (Result retval); + + /** + * Set the rendering device the audio output path is connected to. The + * effect implementation must set EFFECT_FLAG_DEVICE_IND flag in its + * descriptor to receive this command when the device changes. + * + * Note: this method is only supported for effects inserted into + * the output chain. + * + * @param device output device specification. + * @return retval operation completion status. + */ + setDevice(bitfield device) generates (Result retval); + + /** + * Set and get volume. Used by audio framework to delegate volume control to + * effect engine. The effect implementation must set EFFECT_FLAG_VOLUME_CTRL + * flag in its descriptor to receive this command. The effect engine must + * return the volume that should be applied before the effect is + * processed. The overall volume (the volume actually applied by the effect + * engine multiplied by the returned value) should match the value indicated + * in the command. + * + * @param volumes vector containing volume for each channel defined in + * EffectConfig for output buffer expressed in 8.24 fixed + * point format. + * @return result updated volume values. + * @return retval operation completion status. + */ + setAndGetVolume(vec volumes) + generates (Result retval, vec result); + + /** + * Notify the effect of the volume change. The effect implementation must + * set EFFECT_FLAG_VOLUME_IND flag in its descriptor to receive this + * command. + * + * @param volumes vector containing volume for each channel defined in + * EffectConfig for output buffer expressed in 8.24 fixed + * point format. + * @return retval operation completion status. + */ + volumeChangeNotification(vec volumes) + generates (Result retval); + + /** + * Set the audio mode. The effect implementation must set + * EFFECT_FLAG_AUDIO_MODE_IND flag in its descriptor to receive this command + * when the audio mode changes. + * + * @param mode desired audio mode. + * @return retval operation completion status. + */ + setAudioMode(AudioMode mode) generates (Result retval); + + /** + * Apply new audio parameters configurations for input and output buffers of + * reverse stream. An example of reverse stream is the echo reference + * supplied to an Acoustic Echo Canceler. + * + * @param config configuration descriptor. + * @param inputBufferProvider optional buffer provider reference. + * @param outputBufferProvider optional buffer provider reference. + * @return retval operation completion status. + */ + setConfigReverse(EffectConfig config, + IEffectBufferProviderCallback inputBufferProvider, + IEffectBufferProviderCallback outputBufferProvider) + generates (Result retval); + + /** + * Set the capture device the audio input path is connected to. The effect + * implementation must set EFFECT_FLAG_DEVICE_IND flag in its descriptor to + * receive this command when the device changes. + * + * Note: this method is only supported for effects inserted into + * the input chain. + * + * @param device input device specification. + * @return retval operation completion status. + */ + setInputDevice(bitfield device) generates (Result retval); + + /** + * Read audio parameters configurations for input and output buffers. + * + * @return retval operation completion status. + * @return config configuration descriptor. + */ + getConfig() generates (Result retval, EffectConfig config); + + /** + * Read audio parameters configurations for input and output buffers of + * reverse stream. + * + * @return retval operation completion status. + * @return config configuration descriptor. + */ + getConfigReverse() generates (Result retval, EffectConfig config); + + /** + * Queries for supported combinations of main and auxiliary channels + * (e.g. for a multi-microphone noise suppressor). + * + * @param maxConfigs maximum number of the combinations to return. + * @return retval absence of the feature support is indicated using + * NOT_SUPPORTED code. RESULT_TOO_BIG is returned if + * the number of supported combinations exceeds 'maxConfigs'. + * @return result list of configuration descriptors. + */ + getSupportedAuxChannelsConfigs(uint32_t maxConfigs) + generates (Result retval, vec result); + + /** + * Retrieves the current configuration of main and auxiliary channels. + * + * @return retval absence of the feature support is indicated using + * NOT_SUPPORTED code. + * @return result configuration descriptor. + */ + getAuxChannelsConfig() + generates (Result retval, EffectAuxChannelsConfig result); + + /** + * Sets the current configuration of main and auxiliary channels. + * + * @return retval operation completion status; absence of the feature + * support is indicated using NOT_SUPPORTED code. + */ + setAuxChannelsConfig(EffectAuxChannelsConfig config) + generates (Result retval); + + /** + * Set the audio source the capture path is configured for (Camcorder, voice + * recognition...). + * + * Note: this method is only supported for effects inserted into + * the input chain. + * + * @param source source descriptor. + * @return retval operation completion status. + */ + setAudioSource(AudioSource source) generates (Result retval); + + /** + * This command indicates if the playback thread the effect is attached to + * is offloaded or not, and updates the I/O handle of the playback thread + * the effect is attached to. + * + * @param param effect offload descriptor. + * @return retval operation completion status. + */ + offload(EffectOffloadParameter param) generates (Result retval); + + /** + * Returns the effect descriptor. + * + * @return retval operation completion status. + * @return descriptor effect descriptor. + */ + getDescriptor() generates (Result retval, EffectDescriptor descriptor); + + /** + * Set up required transports for passing audio buffers to the effect. + * + * The transport consists of shared memory and a message queue for reporting + * effect processing operation status. The shared memory is set up + * separately using 'setProcessBuffers' method. + * + * Processing is requested by setting 'REQUEST_PROCESS' or + * 'REQUEST_PROCESS_REVERSE' EventFlags associated with the status message + * queue. The result of processing may be one of the following: + * OK if there were no errors during processing; + * INVALID_ARGUMENTS if audio buffers are invalid; + * INVALID_STATE if the engine has finished the disable phase; + * NOT_INITIALIZED if the audio buffers were not set; + * NOT_SUPPORTED if the requested processing type is not supported by + * the effect. + * + * @return retval OK if both message queues were created successfully. + * INVALID_STATE if the method was already called. + * INVALID_ARGUMENTS if there was a problem setting up + * the queue. + * @return statusMQ a message queue used for passing status from the effect. + */ + @callflow(next={"setProcessBuffers"}) + prepareForProcessing() generates (Result retval, fmq_sync statusMQ); + + /** + * Set up input and output buffers for processing audio data. The effect + * may modify both the input and the output buffer during the operation. + * Buffers may be set multiple times during effect lifetime. + * + * The input and the output buffer may be reused between different effects, + * and the input buffer may be used as an output buffer. Buffers are + * distinguished using 'AudioBuffer.id' field. + * + * @param inBuffer input audio buffer. + * @param outBuffer output audio buffer. + * @return retval OK if both buffers were mapped successfully. + * INVALID_ARGUMENTS if there was a problem with mapping + * any of the buffers. + */ + setProcessBuffers(AudioBuffer inBuffer, AudioBuffer outBuffer) + generates (Result retval); + + /** + * Execute a vendor specific command on the effect. The command code + * and data, as well as result data are not interpreted by Android + * Framework and are passed as-is between the application and the effect. + * + * The effect must use standard POSIX.1-2001 error codes for the operation + * completion status. + * + * Use this method only if the effect is provided by a third party, and + * there is no interface defined for it. This method only works for effects + * implemented in software. + * + * @param commandId the ID of the command. + * @param data command data. + * @param resultMaxSize maximum size in bytes of the result; can be 0. + * @return status command completion status. + * @return result result data. + */ + command(uint32_t commandId, vec data, uint32_t resultMaxSize) + generates (int32_t status, vec result); + + /** + * Set a vendor-specific parameter and apply it immediately. The parameter + * code and data are not interpreted by Android Framework and are passed + * as-is between the application and the effect. + * + * The effect must use INVALID_ARGUMENTS return code if the parameter ID is + * unknown or if provided parameter data is invalid. If the effect does not + * support setting vendor-specific parameters, it must return NOT_SUPPORTED. + * + * Use this method only if the effect is provided by a third party, and + * there is no interface defined for it. This method only works for effects + * implemented in software. + * + * @param parameter identifying data of the parameter. + * @param value the value of the parameter. + * @return retval operation completion status. + */ + setParameter(vec parameter, vec value) + generates (Result retval); + + /** + * Get a vendor-specific parameter value. The parameter code and returned + * data are not interpreted by Android Framework and are passed as-is + * between the application and the effect. + * + * The effect must use INVALID_ARGUMENTS return code if the parameter ID is + * unknown. If the effect does not support setting vendor-specific + * parameters, it must return NOT_SUPPORTED. + * + * Use this method only if the effect is provided by a third party, and + * there is no interface defined for it. This method only works for effects + * implemented in software. + * + * @param parameter identifying data of the parameter. + * @param valueMaxSize maximum size in bytes of the value. + * @return retval operation completion status. + * @return result the value of the parameter. + */ + getParameter(vec parameter, uint32_t valueMaxSize) + generates (Result retval, vec value); + + /** + * Get supported configs for a vendor-specific feature. The configs returned + * are not interpreted by Android Framework and are passed as-is between the + * application and the effect. + * + * The effect must use INVALID_ARGUMENTS return code if the feature ID is + * unknown. If the effect does not support getting vendor-specific feature + * configs, it must return NOT_SUPPORTED. If the feature is supported but + * the total number of supported configurations exceeds the maximum number + * indicated by the caller, the method must return RESULT_TOO_BIG. + * + * Use this method only if the effect is provided by a third party, and + * there is no interface defined for it. This method only works for effects + * implemented in software. + * + * @param featureId feature identifier. + * @param maxConfigs maximum number of configs to return. + * @param configSize size of each config in bytes. + * @return retval operation completion status. + * @return configsCount number of configs returned. + * @return configsData data for all the configs returned. + */ + getSupportedConfigsForFeature( + uint32_t featureId, + uint32_t maxConfigs, + uint32_t configSize) generates ( + Result retval, + uint32_t configsCount, + vec configsData); + + /** + * Get the current config for a vendor-specific feature. The config returned + * is not interpreted by Android Framework and is passed as-is between the + * application and the effect. + * + * The effect must use INVALID_ARGUMENTS return code if the feature ID is + * unknown. If the effect does not support getting vendor-specific + * feature configs, it must return NOT_SUPPORTED. + * + * Use this method only if the effect is provided by a third party, and + * there is no interface defined for it. This method only works for effects + * implemented in software. + * + * @param featureId feature identifier. + * @param configSize size of the config in bytes. + * @return retval operation completion status. + * @return configData config data. + */ + getCurrentConfigForFeature(uint32_t featureId, uint32_t configSize) + generates (Result retval, vec configData); + + /** + * Set the current config for a vendor-specific feature. The config data + * is not interpreted by Android Framework and is passed as-is between the + * application and the effect. + * + * The effect must use INVALID_ARGUMENTS return code if the feature ID is + * unknown. If the effect does not support getting vendor-specific + * feature configs, it must return NOT_SUPPORTED. + * + * Use this method only if the effect is provided by a third party, and + * there is no interface defined for it. This method only works for effects + * implemented in software. + * + * @param featureId feature identifier. + * @param configData config data. + * @return retval operation completion status. + */ + setCurrentConfigForFeature(uint32_t featureId, vec configData) + generates (Result retval); + + /** + * Called by the framework to deinitialize the effect and free up + * all currently allocated resources. It is recommended to close + * the effect on the client side as soon as it is becomes unused. + * + * The client must ensure that this function is not called while + * audio data is being transferred through the effect's message queues. + * + * @return retval OK in case the success. + * INVALID_STATE if the effect was already closed. + */ + @exit + close() generates (Result retval); +}; diff --git a/audio/effect/7.0/IEffectBufferProviderCallback.hal b/audio/effect/7.0/IEffectBufferProviderCallback.hal new file mode 100644 index 0000000000..d18f7dfa36 --- /dev/null +++ b/audio/effect/7.0/IEffectBufferProviderCallback.hal @@ -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. + */ + +package android.hardware.audio.effect@7.0; + +/** + * This callback interface contains functions that can be used by the effect + * engine 'process' function to exchange input and output audio buffers. + */ +interface IEffectBufferProviderCallback { + /** + * Called to retrieve a buffer where data should read from by 'process' + * function. + * + * @return buffer audio buffer for processing + */ + getBuffer() generates (AudioBuffer buffer); + + /** + * Called to provide a buffer with the data written by 'process' function. + * + * @param buffer audio buffer for processing + */ + putBuffer(AudioBuffer buffer); +}; diff --git a/audio/effect/7.0/IEffectsFactory.hal b/audio/effect/7.0/IEffectsFactory.hal new file mode 100644 index 0000000000..337251cfde --- /dev/null +++ b/audio/effect/7.0/IEffectsFactory.hal @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.audio.effect@7.0; + +import android.hardware.audio.common@7.0; +import IEffect; + +interface IEffectsFactory { + /** + * Returns descriptors of different effects in all loaded libraries. + * + * @return retval operation completion status. + * @return result list of effect descriptors. + */ + getAllDescriptors() generates(Result retval, vec result); + + /** + * Returns a descriptor of a particular effect. + * + * @return retval operation completion status. + * @return result effect descriptor. + */ + getDescriptor(Uuid uid) generates(Result retval, EffectDescriptor result); + + /** + * Creates an effect engine of the specified type. To release the effect + * engine, it is necessary to release references to the returned effect + * object. + * + * @param uid effect uuid. + * @param session audio session to which this effect instance will be + * attached. All effects created with the same session ID + * are connected in series and process the same signal + * stream. + * @param ioHandle identifies the output or input stream this effect is + * directed to in audio HAL. + * @param device identifies the sink or source device this effect is directed to in the + * audio HAL. Must be specified if session is AudioSessionConsts.DEVICE. + * "device" is the AudioPortHandle used for the device when the audio + * patch is created at the audio HAL. + * @return retval operation completion status. + * @return result the interface for the created effect. + * @return effectId the unique ID of the effect to be used with + * IStream::addEffect and IStream::removeEffect methods. + */ + createEffect(Uuid uid, AudioSession session, AudioIoHandle ioHandle, AudioPortHandle device) + generates (Result retval, IEffect result, uint64_t effectId); +}; diff --git a/audio/effect/7.0/IEnvironmentalReverbEffect.hal b/audio/effect/7.0/IEnvironmentalReverbEffect.hal new file mode 100644 index 0000000000..e02cfbceb3 --- /dev/null +++ b/audio/effect/7.0/IEnvironmentalReverbEffect.hal @@ -0,0 +1,178 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.audio.effect@7.0; + +import android.hardware.audio.common@7.0; +import IEffect; + +interface IEnvironmentalReverbEffect extends IEffect { + /** + * Sets whether the effect should be bypassed. + */ + setBypass(bool bypass) generates (Result retval); + + /** + * Gets whether the effect should be bypassed. + */ + getBypass() generates (Result retval, bool bypass); + + enum ParamRange : int16_t { + ROOM_LEVEL_MIN = -6000, + ROOM_LEVEL_MAX = 0, + ROOM_HF_LEVEL_MIN = -4000, + ROOM_HF_LEVEL_MAX = 0, + DECAY_TIME_MIN = 100, + DECAY_TIME_MAX = 20000, + DECAY_HF_RATIO_MIN = 100, + DECAY_HF_RATIO_MAX = 1000, + REFLECTIONS_LEVEL_MIN = -6000, + REFLECTIONS_LEVEL_MAX = 0, + REFLECTIONS_DELAY_MIN = 0, + REFLECTIONS_DELAY_MAX = 65, + REVERB_LEVEL_MIN = -6000, + REVERB_LEVEL_MAX = 0, + REVERB_DELAY_MIN = 0, + REVERB_DELAY_MAX = 65, + DIFFUSION_MIN = 0, + DIFFUSION_MAX = 1000, + DENSITY_MIN = 0, + DENSITY_MAX = 1000 + }; + + /** + * Sets the room level. + */ + setRoomLevel(int16_t roomLevel) generates (Result retval); + + /** + * Gets the room level. + */ + getRoomLevel() generates (Result retval, int16_t roomLevel); + + /** + * Sets the room high frequencies level. + */ + setRoomHfLevel(int16_t roomHfLevel) generates (Result retval); + + /** + * Gets the room high frequencies level. + */ + getRoomHfLevel() generates (Result retval, int16_t roomHfLevel); + + /** + * Sets the room decay time. + */ + setDecayTime(uint32_t decayTime) generates (Result retval); + + /** + * Gets the room decay time. + */ + getDecayTime() generates (Result retval, uint32_t decayTime); + + /** + * Sets the ratio of high frequencies decay. + */ + setDecayHfRatio(int16_t decayHfRatio) generates (Result retval); + + /** + * Gets the ratio of high frequencies decay. + */ + getDecayHfRatio() generates (Result retval, int16_t decayHfRatio); + + /** + * Sets the level of reflections in the room. + */ + setReflectionsLevel(int16_t reflectionsLevel) generates (Result retval); + + /** + * Gets the level of reflections in the room. + */ + getReflectionsLevel() generates (Result retval, int16_t reflectionsLevel); + + /** + * Sets the reflections delay in the room. + */ + setReflectionsDelay(uint32_t reflectionsDelay) generates (Result retval); + + /** + * Gets the reflections delay in the room. + */ + getReflectionsDelay() generates (Result retval, uint32_t reflectionsDelay); + + /** + * Sets the reverb level of the room. + */ + setReverbLevel(int16_t reverbLevel) generates (Result retval); + + /** + * Gets the reverb level of the room. + */ + getReverbLevel() generates (Result retval, int16_t reverbLevel); + + /** + * Sets the reverb delay of the room. + */ + setReverbDelay(uint32_t reverDelay) generates (Result retval); + + /** + * Gets the reverb delay of the room. + */ + getReverbDelay() generates (Result retval, uint32_t reverbDelay); + + /** + * Sets room diffusion. + */ + setDiffusion(int16_t diffusion) generates (Result retval); + + /** + * Gets room diffusion. + */ + getDiffusion() generates (Result retval, int16_t diffusion); + + /** + * Sets room wall density. + */ + setDensity(int16_t density) generates (Result retval); + + /** + * Gets room wall density. + */ + getDensity() generates (Result retval, int16_t density); + + struct AllProperties { + int16_t roomLevel; // in millibels, range -6000 to 0 + int16_t roomHfLevel; // in millibels, range -4000 to 0 + uint32_t decayTime; // in milliseconds, range 100 to 20000 + int16_t decayHfRatio; // in permilles, range 100 to 1000 + int16_t reflectionsLevel; // in millibels, range -6000 to 0 + uint32_t reflectionsDelay; // in milliseconds, range 0 to 65 + int16_t reverbLevel; // in millibels, range -6000 to 0 + uint32_t reverbDelay; // in milliseconds, range 0 to 65 + int16_t diffusion; // in permilles, range 0 to 1000 + int16_t density; // in permilles, range 0 to 1000 + }; + + /** + * Sets all properties at once. + */ + setAllProperties(AllProperties properties) generates (Result retval); + + /** + * Gets all properties at once. + */ + getAllProperties() generates (Result retval, AllProperties properties); +}; diff --git a/audio/effect/7.0/IEqualizerEffect.hal b/audio/effect/7.0/IEqualizerEffect.hal new file mode 100644 index 0000000000..e7d7ae197b --- /dev/null +++ b/audio/effect/7.0/IEqualizerEffect.hal @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.audio.effect@7.0; + +import android.hardware.audio.common@7.0; +import IEffect; + +interface IEqualizerEffect extends IEffect { + /** + * Gets the number of frequency bands that the equalizer supports. + */ + getNumBands() generates (Result retval, uint16_t numBands); + + /** + * Returns the minimum and maximum band levels supported. + */ + getLevelRange() + generates (Result retval, int16_t minLevel, int16_t maxLevel); + + /** + * Sets the gain for the given equalizer band. + */ + setBandLevel(uint16_t band, int16_t level) generates (Result retval); + + /** + * Gets the gain for the given equalizer band. + */ + getBandLevel(uint16_t band) generates (Result retval, int16_t level); + + /** + * Gets the center frequency of the given band, in milliHertz. + */ + getBandCenterFrequency(uint16_t band) + generates (Result retval, uint32_t centerFreqmHz); + + /** + * Gets the frequency range of the given frequency band, in milliHertz. + */ + getBandFrequencyRange(uint16_t band) + generates (Result retval, uint32_t minFreqmHz, uint32_t maxFreqmHz); + + /** + * Gets the band that has the most effect on the given frequency + * in milliHertz. + */ + getBandForFrequency(uint32_t freqmHz) + generates (Result retval, uint16_t band); + + /** + * Gets the names of all presets the equalizer supports. + */ + getPresetNames() generates (Result retval, vec names); + + /** + * Sets the current preset using the index of the preset in the names + * vector returned via 'getPresetNames'. + */ + setCurrentPreset(uint16_t preset) generates (Result retval); + + /** + * Gets the current preset. + */ + getCurrentPreset() generates (Result retval, uint16_t preset); + + struct AllProperties { + uint16_t curPreset; + vec bandLevels; + }; + + /** + * Sets all properties at once. + */ + setAllProperties(AllProperties properties) generates (Result retval); + + /** + * Gets all properties at once. + */ + getAllProperties() generates (Result retval, AllProperties properties); +}; diff --git a/audio/effect/7.0/ILoudnessEnhancerEffect.hal b/audio/effect/7.0/ILoudnessEnhancerEffect.hal new file mode 100644 index 0000000000..0304f208a4 --- /dev/null +++ b/audio/effect/7.0/ILoudnessEnhancerEffect.hal @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.audio.effect@7.0; + +import android.hardware.audio.common@7.0; +import IEffect; + +interface ILoudnessEnhancerEffect extends IEffect { + /** + * Sets target gain expressed in millibels. + */ + setTargetGain(int32_t targetGainMb) generates (Result retval); + + /** + * Gets target gain expressed in millibels. + */ + getTargetGain() generates (Result retval, int32_t targetGainMb); +}; diff --git a/audio/effect/7.0/INoiseSuppressionEffect.hal b/audio/effect/7.0/INoiseSuppressionEffect.hal new file mode 100644 index 0000000000..2c6210c5df --- /dev/null +++ b/audio/effect/7.0/INoiseSuppressionEffect.hal @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.audio.effect@7.0; + +import android.hardware.audio.common@7.0; +import IEffect; + +interface INoiseSuppressionEffect extends IEffect { + enum Level : int32_t { + LOW, + MEDIUM, + HIGH + }; + + /** + * Sets suppression level. + */ + setSuppressionLevel(Level level) generates (Result retval); + + /** + * Gets suppression level. + */ + getSuppressionLevel() generates (Result retval, Level level); + + enum Type : int32_t { + SINGLE_CHANNEL, + MULTI_CHANNEL + }; + + /** + * Set suppression type. + */ + setSuppressionType(Type type) generates (Result retval); + + /** + * Get suppression type. + */ + getSuppressionType() generates (Result retval, Type type); + + struct AllProperties { + Level level; + Type type; + }; + + /** + * Sets all properties at once. + */ + setAllProperties(AllProperties properties) generates (Result retval); + + /** + * Gets all properties at once. + */ + getAllProperties() generates (Result retval, AllProperties properties); +}; diff --git a/audio/effect/7.0/IPresetReverbEffect.hal b/audio/effect/7.0/IPresetReverbEffect.hal new file mode 100644 index 0000000000..da61d24c7a --- /dev/null +++ b/audio/effect/7.0/IPresetReverbEffect.hal @@ -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. + */ + +package android.hardware.audio.effect@7.0; + +import android.hardware.audio.common@7.0; +import IEffect; + +interface IPresetReverbEffect extends IEffect { + enum Preset : int32_t { + NONE, // no reverb or reflections + SMALLROOM, // a small room less than five meters in length + MEDIUMROOM, // a medium room with a length of ten meters or less + LARGEROOM, // a large-sized room suitable for live performances + MEDIUMHALL, // a medium-sized hall + LARGEHALL, // a large-sized hall suitable for a full orchestra + PLATE, // synthesis of the traditional plate reverb + LAST = PLATE + }; + + /** + * Sets the current preset. + */ + setPreset(Preset preset) generates (Result retval); + + /** + * Gets the current preset. + */ + getPreset() generates (Result retval, Preset preset); +}; diff --git a/audio/effect/7.0/IVirtualizerEffect.hal b/audio/effect/7.0/IVirtualizerEffect.hal new file mode 100644 index 0000000000..0e6ff54403 --- /dev/null +++ b/audio/effect/7.0/IVirtualizerEffect.hal @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.audio.effect@7.0; + +import android.hardware.audio.common@7.0; +import IEffect; + +interface IVirtualizerEffect extends IEffect { + /** + * Returns whether setting virtualization strength is supported. + */ + isStrengthSupported() generates (bool strengthSupported); + + enum StrengthRange : uint16_t { + MIN = 0, + MAX = 1000 + }; + + /** + * Sets virtualization strength. + * + * @param strength strength of the effect. The valid range for strength + * strength is [0, 1000], where 0 per mille designates the + * mildest effect and 1000 per mille designates the + * strongest. + * @return retval operation completion status. + */ + setStrength(uint16_t strength) generates (Result retval); + + /** + * Gets virtualization strength. + */ + getStrength() generates (Result retval, uint16_t strength); + + struct SpeakerAngle { + /** Speaker channel mask */ + bitfield mask; + // all angles are expressed in degrees and + // are relative to the listener. + int16_t azimuth; // 0 is the direction the listener faces + // 180 is behind the listener + // -90 is to their left + int16_t elevation; // 0 is the horizontal plane + // +90 is above the listener, -90 is below + }; + /** + * Retrieves virtual speaker angles for the given channel mask on the + * specified device. + */ + getVirtualSpeakerAngles(bitfield mask, AudioDevice device) + generates (Result retval, vec speakerAngles); + + /** + * Forces the virtualizer effect for the given output device. + */ + forceVirtualizationMode(AudioDevice device) generates (Result retval); + + /** + * Returns audio device reflecting the current virtualization mode, + * AUDIO_DEVICE_NONE when not virtualizing. + */ + getVirtualizationMode() generates (Result retval, AudioDevice device); +}; diff --git a/audio/effect/7.0/IVisualizerEffect.hal b/audio/effect/7.0/IVisualizerEffect.hal new file mode 100644 index 0000000000..b4e86594d8 --- /dev/null +++ b/audio/effect/7.0/IVisualizerEffect.hal @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.audio.effect@7.0; + +import android.hardware.audio.common@7.0; +import IEffect; + +interface IVisualizerEffect extends IEffect { + enum CaptureSizeRange : int32_t { + MAX = 1024, // maximum capture size in samples + MIN = 128 // minimum capture size in samples + }; + + /** + * Sets the number PCM samples in the capture. + */ + setCaptureSize(uint16_t captureSize) generates (Result retval); + + /** + * Gets the number PCM samples in the capture. + */ + getCaptureSize() generates (Result retval, uint16_t captureSize); + + enum ScalingMode : int32_t { + // Keep in sync with SCALING_MODE_... in + // frameworks/base/media/java/android/media/audiofx/Visualizer.java + NORMALIZED = 0, + AS_PLAYED = 1 + }; + + /** + * Specifies the way the captured data is scaled. + */ + setScalingMode(ScalingMode scalingMode) generates (Result retval); + + /** + * Retrieves the way the captured data is scaled. + */ + getScalingMode() generates (Result retval, ScalingMode scalingMode); + + /** + * Informs the visualizer about the downstream latency. + */ + setLatency(uint32_t latencyMs) generates (Result retval); + + /** + * Gets the downstream latency. + */ + getLatency() generates (Result retval, uint32_t latencyMs); + + enum MeasurementMode : int32_t { + // Keep in sync with MEASUREMENT_MODE_... in + // frameworks/base/media/java/android/media/audiofx/Visualizer.java + NONE = 0x0, + PEAK_RMS = 0x1 + }; + + /** + * Specifies which measurements are to be made. + */ + setMeasurementMode(MeasurementMode measurementMode) + generates (Result retval); + + /** + * Retrieves which measurements are to be made. + */ + getMeasurementMode() generates ( + Result retval, MeasurementMode measurementMode); + + /** + * Retrieves the latest PCM snapshot captured by the visualizer engine. The + * number of samples to capture is specified by 'setCaptureSize' parameter. + * + * @return retval operation completion status. + * @return samples samples in 8 bit unsigned format (0 = 0x80) + */ + capture() generates (Result retval, vec samples); + + struct Measurement { + MeasurementMode mode; // discriminator + union Values { + struct PeakAndRms { + int32_t peakMb; // millibels + int32_t rmsMb; // millibels + } peakAndRms; + } value; + }; + /** + * Retrieves the latest measurements. The measurements to be made + * are specified by 'setMeasurementMode' parameter. + * + * @return retval operation completion status. + * @return result measurement. + */ + measure() generates (Result retval, Measurement result); +}; diff --git a/audio/effect/7.0/types.hal b/audio/effect/7.0/types.hal new file mode 100644 index 0000000000..7f5a38238f --- /dev/null +++ b/audio/effect/7.0/types.hal @@ -0,0 +1,301 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.audio.effect@7.0; + +import android.hardware.audio.common@7.0; + +enum Result : int32_t { + OK, + NOT_INITIALIZED, + INVALID_ARGUMENTS, + INVALID_STATE, + NOT_SUPPORTED, + RESULT_TOO_BIG +}; + +/** + * Effect engine capabilities/requirements flags. + * + * Definitions for flags field of effect descriptor. + * + * +----------------+--------+-------------------------------------------------- + * | description | bits | values + * +----------------+--------+-------------------------------------------------- + * | connection | 0..2 | 0 insert: after track process + * | mode | | 1 auxiliary: connect to track auxiliary + * | | | output and use send level + * | | | 2 replace: replaces track process function; + * | | | must implement SRC, volume and mono to stereo. + * | | | 3 pre processing: applied below audio HAL on in + * | | | 4 post processing: applied below audio HAL on out + * | | | 5 - 7 reserved + * +----------------+--------+-------------------------------------------------- + * | insertion | 3..5 | 0 none + * | preference | | 1 first of the chain + * | | | 2 last of the chain + * | | | 3 exclusive (only effect in the insert chain) + * | | | 4..7 reserved + * +----------------+--------+-------------------------------------------------- + * | Volume | 6..8 | 0 none + * | management | | 1 implements volume control + * | | | 2 requires volume indication + * | | | 3 monitors requested volume + * | | | 4 reserved + * +----------------+--------+-------------------------------------------------- + * | Device | 9..11 | 0 none + * | indication | | 1 requires device updates + * | | | 2, 4 reserved + * +----------------+--------+-------------------------------------------------- + * | Sample input | 12..13 | 1 direct: process() function or + * | mode | | EFFECT_CMD_SET_CONFIG command must specify + * | | | a buffer descriptor + * | | | 2 provider: process() function uses the + * | | | bufferProvider indicated by the + * | | | EFFECT_CMD_SET_CONFIG command to request input. + * | | | buffers. + * | | | 3 both: both input modes are supported + * +----------------+--------+-------------------------------------------------- + * | Sample output | 14..15 | 1 direct: process() function or + * | mode | | EFFECT_CMD_SET_CONFIG command must specify + * | | | a buffer descriptor + * | | | 2 provider: process() function uses the + * | | | bufferProvider indicated by the + * | | | EFFECT_CMD_SET_CONFIG command to request output + * | | | buffers. + * | | | 3 both: both output modes are supported + * +----------------+--------+-------------------------------------------------- + * | Hardware | 16..17 | 0 No hardware acceleration + * | acceleration | | 1 non tunneled hw acceleration: the process() + * | | | function reads the samples, send them to HW + * | | | accelerated effect processor, reads back + * | | | the processed samples and returns them + * | | | to the output buffer. + * | | | 2 tunneled hw acceleration: the process() + * | | | function is transparent. The effect interface + * | | | is only used to control the effect engine. + * | | | This mode is relevant for global effects + * | | | actually applied by the audio hardware on + * | | | the output stream. + * +----------------+--------+-------------------------------------------------- + * | Audio Mode | 18..19 | 0 none + * | indication | | 1 requires audio mode updates + * | | | 2..3 reserved + * +----------------+--------+-------------------------------------------------- + * | Audio source | 20..21 | 0 none + * | indication | | 1 requires audio source updates + * | | | 2..3 reserved + * +----------------+--------+-------------------------------------------------- + * | Effect offload | 22 | 0 The effect cannot be offloaded to an audio DSP + * | supported | | 1 The effect can be offloaded to an audio DSP + * +----------------+--------+-------------------------------------------------- + * | Process | 23 | 0 The effect implements a process function. + * | function | | 1 The effect does not implement a process + * | not | | function: enabling the effect has no impact + * | implemented | | on latency or CPU load. + * | | | Effect implementations setting this flag do not + * | | | have to implement a process function. + * +----------------+--------+-------------------------------------------------- + */ +@export(name="", value_prefix="EFFECT_FLAG_") +enum EffectFlags : int32_t { + // Insert mode + TYPE_SHIFT = 0, + TYPE_SIZE = 3, + TYPE_MASK = ((1 << TYPE_SIZE) -1) << TYPE_SHIFT, + TYPE_INSERT = 0 << TYPE_SHIFT, + TYPE_AUXILIARY = 1 << TYPE_SHIFT, + TYPE_REPLACE = 2 << TYPE_SHIFT, + TYPE_PRE_PROC = 3 << TYPE_SHIFT, + TYPE_POST_PROC = 4 << TYPE_SHIFT, + + // Insert preference + INSERT_SHIFT = TYPE_SHIFT + TYPE_SIZE, + INSERT_SIZE = 3, + INSERT_MASK = ((1 << INSERT_SIZE) -1) << INSERT_SHIFT, + INSERT_ANY = 0 << INSERT_SHIFT, + INSERT_FIRST = 1 << INSERT_SHIFT, + INSERT_LAST = 2 << INSERT_SHIFT, + INSERT_EXCLUSIVE = 3 << INSERT_SHIFT, + + // Volume control + VOLUME_SHIFT = INSERT_SHIFT + INSERT_SIZE, + VOLUME_SIZE = 3, + VOLUME_MASK = ((1 << VOLUME_SIZE) -1) << VOLUME_SHIFT, + VOLUME_CTRL = 1 << VOLUME_SHIFT, + VOLUME_IND = 2 << VOLUME_SHIFT, + VOLUME_MONITOR = 3 << VOLUME_SHIFT, + VOLUME_NONE = 0 << VOLUME_SHIFT, + + // Device indication + DEVICE_SHIFT = VOLUME_SHIFT + VOLUME_SIZE, + DEVICE_SIZE = 3, + DEVICE_MASK = ((1 << DEVICE_SIZE) -1) << DEVICE_SHIFT, + DEVICE_IND = 1 << DEVICE_SHIFT, + DEVICE_NONE = 0 << DEVICE_SHIFT, + + // Sample input modes + INPUT_SHIFT = DEVICE_SHIFT + DEVICE_SIZE, + INPUT_SIZE = 2, + INPUT_MASK = ((1 << INPUT_SIZE) -1) << INPUT_SHIFT, + INPUT_DIRECT = 1 << INPUT_SHIFT, + INPUT_PROVIDER = 2 << INPUT_SHIFT, + INPUT_BOTH = 3 << INPUT_SHIFT, + + // Sample output modes + OUTPUT_SHIFT = INPUT_SHIFT + INPUT_SIZE, + OUTPUT_SIZE = 2, + OUTPUT_MASK = ((1 << OUTPUT_SIZE) -1) << OUTPUT_SHIFT, + OUTPUT_DIRECT = 1 << OUTPUT_SHIFT, + OUTPUT_PROVIDER = 2 << OUTPUT_SHIFT, + OUTPUT_BOTH = 3 << OUTPUT_SHIFT, + + // Hardware acceleration mode + HW_ACC_SHIFT = OUTPUT_SHIFT + OUTPUT_SIZE, + HW_ACC_SIZE = 2, + HW_ACC_MASK = ((1 << HW_ACC_SIZE) -1) << HW_ACC_SHIFT, + HW_ACC_SIMPLE = 1 << HW_ACC_SHIFT, + HW_ACC_TUNNEL = 2 << HW_ACC_SHIFT, + + // Audio mode indication + AUDIO_MODE_SHIFT = HW_ACC_SHIFT + HW_ACC_SIZE, + AUDIO_MODE_SIZE = 2, + AUDIO_MODE_MASK = ((1 << AUDIO_MODE_SIZE) -1) << AUDIO_MODE_SHIFT, + AUDIO_MODE_IND = 1 << AUDIO_MODE_SHIFT, + AUDIO_MODE_NONE = 0 << AUDIO_MODE_SHIFT, + + // Audio source indication + AUDIO_SOURCE_SHIFT = AUDIO_MODE_SHIFT + AUDIO_MODE_SIZE, + AUDIO_SOURCE_SIZE = 2, + AUDIO_SOURCE_MASK = ((1 << AUDIO_SOURCE_SIZE) -1) << AUDIO_SOURCE_SHIFT, + AUDIO_SOURCE_IND = 1 << AUDIO_SOURCE_SHIFT, + AUDIO_SOURCE_NONE = 0 << AUDIO_SOURCE_SHIFT, + + // Effect offload indication + OFFLOAD_SHIFT = AUDIO_SOURCE_SHIFT + AUDIO_SOURCE_SIZE, + OFFLOAD_SIZE = 1, + OFFLOAD_MASK = ((1 << OFFLOAD_SIZE) -1) << OFFLOAD_SHIFT, + OFFLOAD_SUPPORTED = 1 << OFFLOAD_SHIFT, + + // Effect has no process indication + NO_PROCESS_SHIFT = OFFLOAD_SHIFT + OFFLOAD_SIZE, + NO_PROCESS_SIZE = 1, + NO_PROCESS_MASK = ((1 << NO_PROCESS_SIZE) -1) << NO_PROCESS_SHIFT, + NO_PROCESS = 1 << NO_PROCESS_SHIFT +}; + +/** + * The effect descriptor contains necessary information to facilitate the + * enumeration of the effect engines present in a library. + */ +struct EffectDescriptor { + Uuid type; // UUID of to the OpenSL ES interface implemented + // by this effect + Uuid uuid; // UUID for this particular implementation + bitfield flags; // effect engine capabilities/requirements flags + uint16_t cpuLoad; // CPU load indication expressed in 0.1 MIPS units + // as estimated on an ARM9E core (ARMv5TE) with 0 WS + uint16_t memoryUsage; // data memory usage expressed in KB and includes + // only dynamically allocated memory + uint8_t[64] name; // human readable effect name + uint8_t[64] implementor; // human readable effect implementor name +}; + +/** + * A buffer is a chunk of audio data for processing. Multi-channel audio is + * always interleaved. The channel order is from LSB to MSB with regard to the + * channel mask definition in audio.h, audio_channel_mask_t, e.g.: + * Stereo: L, R; 5.1: FL, FR, FC, LFE, BL, BR. + * + * The buffer size is expressed in frame count, a frame being composed of + * samples for all channels at a given time. Frame size for unspecified format + * (AUDIO_FORMAT_OTHER) is 8 bit by definition. + */ +struct AudioBuffer { + uint64_t id; + uint32_t frameCount; + memory data; +}; + +@export(name="effect_buffer_access_e", value_prefix="EFFECT_BUFFER_") +enum EffectBufferAccess : int32_t { + ACCESS_WRITE, + ACCESS_READ, + ACCESS_ACCUMULATE +}; + +/** + * Determines what fields of EffectBufferConfig need to be considered. + */ +@export(name="", value_prefix="EFFECT_CONFIG_") +enum EffectConfigParameters : int32_t { + BUFFER = 0x0001, // buffer field + SMP_RATE = 0x0002, // samplingRate + CHANNELS = 0x0004, // channels + FORMAT = 0x0008, // format + ACC_MODE = 0x0010, // accessMode + // Note that the 2.0 ALL have been moved to an helper function +}; + +/** + * The buffer config structure specifies the input or output audio format + * to be used by the effect engine. + */ +struct EffectBufferConfig { + AudioBuffer buffer; + uint32_t samplingRateHz; + bitfield channels; + AudioFormat format; + EffectBufferAccess accessMode; + bitfield mask; +}; + +struct EffectConfig { + EffectBufferConfig inputCfg; + EffectBufferConfig outputCfg; +}; + +@export(name="effect_feature_e", value_prefix="EFFECT_FEATURE_") +enum EffectFeature : int32_t { + AUX_CHANNELS, // supports auxiliary channels + // (e.g. dual mic noise suppressor) + CNT +}; + +struct EffectAuxChannelsConfig { + bitfield mainChannels; // channel mask for main channels + bitfield auxChannels; // channel mask for auxiliary channels +}; + +struct EffectOffloadParameter { + bool isOffload; // true if the playback thread the effect + // is attached to is offloaded + AudioIoHandle ioHandle; // io handle of the playback thread + // the effect is attached to +}; + +/** + * The message queue flags used to synchronize reads and writes from + * the status message queue used by effects. + */ +enum MessageQueueFlagBits : uint32_t { + DONE_PROCESSING = 1 << 0, + REQUEST_PROCESS = 1 << 1, + REQUEST_PROCESS_REVERSE = 1 << 2, + REQUEST_QUIT = 1 << 3, + REQUEST_PROCESS_ALL = + REQUEST_PROCESS | REQUEST_PROCESS_REVERSE | REQUEST_QUIT +}; diff --git a/audio/effect/7.0/xml/Android.bp b/audio/effect/7.0/xml/Android.bp new file mode 100644 index 0000000000..dc12e6368d --- /dev/null +++ b/audio/effect/7.0/xml/Android.bp @@ -0,0 +1,5 @@ +xsd_config { + name: "audio_effects_conf_V7_0", + srcs: ["audio_effects_conf.xsd"], + package_name: "audio.effects.V7_0", +} diff --git a/audio/effect/7.0/xml/api/current.txt b/audio/effect/7.0/xml/api/current.txt new file mode 100644 index 0000000000..34cb541ff8 --- /dev/null +++ b/audio/effect/7.0/xml/api/current.txt @@ -0,0 +1,208 @@ +// Signature format: 2.0 +package audio.effects.V7_0 { + + public class AudioEffectsConf { + ctor public AudioEffectsConf(); + method public audio.effects.V7_0.AudioEffectsConf.DeviceEffects getDeviceEffects(); + method public audio.effects.V7_0.EffectsType getEffects(); + method public audio.effects.V7_0.LibrariesType getLibraries(); + method public audio.effects.V7_0.AudioEffectsConf.Postprocess getPostprocess(); + method public audio.effects.V7_0.AudioEffectsConf.Preprocess getPreprocess(); + method public audio.effects.V7_0.VersionType getVersion(); + method public void setDeviceEffects(audio.effects.V7_0.AudioEffectsConf.DeviceEffects); + method public void setEffects(audio.effects.V7_0.EffectsType); + method public void setLibraries(audio.effects.V7_0.LibrariesType); + method public void setPostprocess(audio.effects.V7_0.AudioEffectsConf.Postprocess); + method public void setPreprocess(audio.effects.V7_0.AudioEffectsConf.Preprocess); + method public void setVersion(audio.effects.V7_0.VersionType); + } + + public static class AudioEffectsConf.DeviceEffects { + ctor public AudioEffectsConf.DeviceEffects(); + method public java.util.List getDevicePort(); + } + + public static class AudioEffectsConf.Postprocess { + ctor public AudioEffectsConf.Postprocess(); + method public java.util.List getStream(); + } + + public static class AudioEffectsConf.Preprocess { + ctor public AudioEffectsConf.Preprocess(); + method public java.util.List getStream(); + } + + public class DeviceProcessType extends audio.effects.V7_0.StreamProcessingType { + ctor public DeviceProcessType(); + method public String getAddress(); + method public audio.effects.V7_0.DeviceType getType(); + method public void setAddress(String); + method public void setType(audio.effects.V7_0.DeviceType); + } + + public enum DeviceType { + method public String getRawName(); + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_IN_AUX_DIGITAL; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_IN_BACK_MIC; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_IN_BLUETOOTH_A2DP; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_IN_BLUETOOTH_BLE; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_IN_BUILTIN_MIC; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_IN_BUS; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_IN_COMMUNICATION; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_IN_ECHO_REFERENCE; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_IN_FM_TUNER; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_IN_HDMI; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_IN_HDMI_ARC; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_IN_IP; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_IN_LINE; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_IN_LOOPBACK; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_IN_PROXY; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_IN_REMOTE_SUBMIX; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_IN_SPDIF; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_IN_TELEPHONY_RX; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_IN_TV_TUNER; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_IN_USB_ACCESSORY; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_IN_USB_DEVICE; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_IN_USB_HEADSET; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_IN_VOICE_CALL; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_IN_WIRED_HEADSET; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_OUT_AUX_DIGITAL; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_OUT_AUX_LINE; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_OUT_BLUETOOTH_A2DP; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_OUT_BLUETOOTH_SCO; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_OUT_BUS; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_OUT_EARPIECE; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_OUT_ECHO_CANCELLER; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_OUT_FM; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_OUT_HDMI; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_OUT_HDMI_ARC; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_OUT_HEARING_AID; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_OUT_IP; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_OUT_LINE; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_OUT_PROXY; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_OUT_REMOTE_SUBMIX; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_OUT_SPDIF; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_OUT_SPEAKER; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_OUT_SPEAKER_SAFE; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_OUT_TELEPHONY_TX; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_OUT_USB_ACCESSORY; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_OUT_USB_DEVICE; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_OUT_USB_HEADSET; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_OUT_WIRED_HEADPHONE; + enum_constant public static final audio.effects.V7_0.DeviceType AUDIO_DEVICE_OUT_WIRED_HEADSET; + } + + public class EffectImplType { + ctor public EffectImplType(); + method public String getLibrary(); + method public String getUuid(); + method public void setLibrary(String); + method public void setUuid(String); + } + + public class EffectProxyType extends audio.effects.V7_0.EffectType { + ctor public EffectProxyType(); + method public audio.effects.V7_0.EffectImplType getLibhw(); + method public audio.effects.V7_0.EffectImplType getLibsw(); + method public void setLibhw(audio.effects.V7_0.EffectImplType); + method public void setLibsw(audio.effects.V7_0.EffectImplType); + } + + public class EffectType extends audio.effects.V7_0.EffectImplType { + ctor public EffectType(); + method public String getName(); + method public void setName(String); + } + + public class EffectsType { + ctor public EffectsType(); + method public java.util.List getEffectProxy_optional(); + method public java.util.List getEffect_optional(); + } + + public class LibrariesType { + ctor public LibrariesType(); + method public java.util.List getLibrary(); + } + + public static class LibrariesType.Library { + ctor public LibrariesType.Library(); + method public String getName(); + method public String getPath(); + method public void setName(String); + method public void setPath(String); + } + + public enum StreamInputType { + method public String getRawName(); + enum_constant public static final audio.effects.V7_0.StreamInputType camcorder; + enum_constant public static final audio.effects.V7_0.StreamInputType echo_reference; + enum_constant public static final audio.effects.V7_0.StreamInputType fm_tuner; + enum_constant public static final audio.effects.V7_0.StreamInputType mic; + enum_constant public static final audio.effects.V7_0.StreamInputType unprocessed; + enum_constant public static final audio.effects.V7_0.StreamInputType voice_call; + enum_constant public static final audio.effects.V7_0.StreamInputType voice_communication; + enum_constant public static final audio.effects.V7_0.StreamInputType voice_downlink; + enum_constant public static final audio.effects.V7_0.StreamInputType voice_performance; + enum_constant public static final audio.effects.V7_0.StreamInputType voice_recognition; + enum_constant public static final audio.effects.V7_0.StreamInputType voice_uplink; + } + + public enum StreamOutputType { + method public String getRawName(); + enum_constant public static final audio.effects.V7_0.StreamOutputType alarm; + enum_constant public static final audio.effects.V7_0.StreamOutputType assistant; + enum_constant public static final audio.effects.V7_0.StreamOutputType bluetooth_sco; + enum_constant public static final audio.effects.V7_0.StreamOutputType dtmf; + enum_constant public static final audio.effects.V7_0.StreamOutputType enforced_audible; + enum_constant public static final audio.effects.V7_0.StreamOutputType music; + enum_constant public static final audio.effects.V7_0.StreamOutputType notification; + enum_constant public static final audio.effects.V7_0.StreamOutputType ring; + enum_constant public static final audio.effects.V7_0.StreamOutputType system; + enum_constant public static final audio.effects.V7_0.StreamOutputType tts; + enum_constant public static final audio.effects.V7_0.StreamOutputType voice_call; + } + + public class StreamPostprocessType extends audio.effects.V7_0.StreamProcessingType { + ctor public StreamPostprocessType(); + method public audio.effects.V7_0.StreamOutputType getType(); + method public void setType(audio.effects.V7_0.StreamOutputType); + } + + public class StreamPreprocessType extends audio.effects.V7_0.StreamProcessingType { + ctor public StreamPreprocessType(); + method public audio.effects.V7_0.StreamInputType getType(); + method public void setType(audio.effects.V7_0.StreamInputType); + } + + public class StreamProcessingType { + ctor public StreamProcessingType(); + method public java.util.List getApply(); + } + + public static class StreamProcessingType.Apply { + ctor public StreamProcessingType.Apply(); + method public String getEffect(); + method public void setEffect(String); + } + + public enum VersionType { + method public String getRawName(); + enum_constant public static final audio.effects.V7_0.VersionType _2_0; + } + + public class XmlParser { + ctor public XmlParser(); + method public static audio.effects.V7_0.AudioEffectsConf read(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException; + method public static String readText(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; + method public static void skip(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; + } + +} + diff --git a/audio/effect/7.0/xml/api/last_current.txt b/audio/effect/7.0/xml/api/last_current.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/audio/effect/7.0/xml/api/last_removed.txt b/audio/effect/7.0/xml/api/last_removed.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/audio/effect/7.0/xml/api/removed.txt b/audio/effect/7.0/xml/api/removed.txt new file mode 100644 index 0000000000..d802177e24 --- /dev/null +++ b/audio/effect/7.0/xml/api/removed.txt @@ -0,0 +1 @@ +// Signature format: 2.0 diff --git a/audio/effect/7.0/xml/audio_effects_conf.xsd b/audio/effect/7.0/xml/audio_effects_conf.xsd new file mode 100644 index 0000000000..94f9f764a6 --- /dev/null +++ b/audio/effect/7.0/xml/audio_effects_conf.xsd @@ -0,0 +1,323 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + List of effect libraries to load. Each library element must have "name" and + "path" attributes. The latter is giving the path of the library .so file + relative to the standard effect folders: /(vendor|odm|system)/lib(64)?/soundfx/ + Example for a library in "/vendor/lib/soundfx/lib.so": + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + List of effects to load. Each effect element must contain "name", + "library", and "uuid" attrs. The value of the "library" attr must + correspond to the name of a "library" element. The name of the effect + element is indicative, only the value of the "uuid" element designates + the effect for the audio framework. The uuid is the implementation + specific UUID as specified by the effect vendor. This is not the generic + effect type UUID. + For effect proxy implementations, SW and HW implementations of the effect + can be specified. + Example: + + + + + + + + + + + + + + + + + + + + + + + + + Audio preprocessing configuration. The processing configuration consists + of a list of elements each describing processing settings for a given + input stream. Valid input stream types are listed in "streamInputType". + Each stream element contains a list of "apply" elements. The value of the + "effect" attr must correspond to the name of an "effect" element. + Example: + + + + + + + + + + + + + + + + Audio postprocessing configuration. The processing configuration consists + of a list of elements each describing processing settings for a given + output stream. Valid output stream types are listed in "streamOutputType". + Each stream element contains a list of "apply" elements. The value of the + "effect" attr must correspond to the name of an "effect" element. + Example: + + + + + + + + + + + + + + + Audio Device Effects configuration. The processing configuration consists + of a list of effects to be automatically added on a device Port when involved in an audio + patch. + Valid device type are listed in "deviceType" and shall be aligned. + Each stream element contains a list of "apply" elements. The value of the + "effect" attr must correspond to the name of an "effect" element. + Note that if the device is involved in a hardware patch, the effect must be hardware + accelerated. + Example: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/audio/effect/all-versions/default/Android.bp b/audio/effect/all-versions/default/Android.bp index d9bb78b700..01392bd13a 100644 --- a/audio/effect/all-versions/default/Android.bp +++ b/audio/effect/all-versions/default/Android.bp @@ -103,3 +103,18 @@ cc_library_shared { "-include common/all-versions/VersionMacro.h", ] } + +cc_library_shared { + name: "android.hardware.audio.effect@7.0-impl", + defaults: ["android.hardware.audio.effect-impl_default"], + shared_libs: [ + "android.hardware.audio.common@7.0", + "android.hardware.audio.common@7.0-util", + "android.hardware.audio.effect@7.0", + ], + cflags: [ + "-DMAJOR_VERSION=7", + "-DMINOR_VERSION=0", + "-include common/all-versions/VersionMacro.h", + ] +} diff --git a/audio/effect/all-versions/vts/functional/Android.bp b/audio/effect/all-versions/vts/functional/Android.bp index 309aa9d27f..6a1d6a3f04 100644 --- a/audio/effect/all-versions/vts/functional/Android.bp +++ b/audio/effect/all-versions/vts/functional/Android.bp @@ -113,3 +113,23 @@ cc_test { "-include common/all-versions/VersionMacro.h", ] } + +cc_test { + name: "VtsHalAudioEffectV7_0TargetTest", + defaults: ["VtsHalAudioEffectTargetTest_default"], + // Use test_config for vts suite. + // TODO(b/146104851): Add auto-gen rules and remove it. + test_config: "VtsHalAudioEffectV7_0TargetTest.xml", + static_libs: [ + "android.hardware.audio.common@7.0", + "android.hardware.audio.effect@7.0", + ], + data: [ + ":audio_effects_conf_V7_0", + ], + cflags: [ + "-DMAJOR_VERSION=7", + "-DMINOR_VERSION=0", + "-include common/all-versions/VersionMacro.h", + ] +} diff --git a/audio/effect/all-versions/vts/functional/VtsHalAudioEffectV7_0TargetTest.xml b/audio/effect/all-versions/vts/functional/VtsHalAudioEffectV7_0TargetTest.xml new file mode 100644 index 0000000000..e6097563cb --- /dev/null +++ b/audio/effect/all-versions/vts/functional/VtsHalAudioEffectV7_0TargetTest.xml @@ -0,0 +1,38 @@ + + + + -- GitLab From 6cd03bfdb9179f259f3c94b3079d37bc4bf34c8c Mon Sep 17 00:00:00 2001 From: Mikhail Naganov Date: Thu, 6 Aug 2020 23:34:26 +0000 Subject: [PATCH 115/790] Audio: Build file updates Add target for the library with code generated by xsdc. Temporarily disable default implementation and VTS targets. Bug: 142480271 Test: m Change-Id: I6c891893398617a36f4748f185e189064ba4d4ee --- audio/common/7.0/Android.bp | 13 +++++++++++++ audio/common/all-versions/default/Android.bp | 15 ++++++++------- audio/core/all-versions/default/Android.bp | 1 + .../all-versions/vts/functional/Android.bp | 1 + audio/effect/all-versions/default/Android.bp | 11 ++++++----- .../all-versions/vts/functional/Android.bp | 18 +++++++++++------- 6 files changed, 40 insertions(+), 19 deletions(-) diff --git a/audio/common/7.0/Android.bp b/audio/common/7.0/Android.bp index eef563fecd..e24871c8b5 100644 --- a/audio/common/7.0/Android.bp +++ b/audio/common/7.0/Android.bp @@ -12,3 +12,16 @@ hidl_interface { gen_java: true, gen_java_constants: true, } + +cc_library { + name: "android.hardware.audio.common@7.0-enums", + vendor_available: true, + generated_sources: ["audio_policy_configuration_V7_0"], + generated_headers: ["audio_policy_configuration_V7_0"], + header_libs: ["libxsdc-utils"], + shared_libs: [ + "libbase", + "liblog", + "libxml2", + ], +} diff --git a/audio/common/all-versions/default/Android.bp b/audio/common/all-versions/default/Android.bp index 5caddcf3fa..a72c8dc989 100644 --- a/audio/common/all-versions/default/Android.bp +++ b/audio/common/all-versions/default/Android.bp @@ -36,7 +36,7 @@ cc_library_shared { ], export_header_lib_headers: [ "android.hardware.audio.common.util@all-versions", - ] + ], } cc_defaults { @@ -57,7 +57,7 @@ cc_defaults { "android.hardware.audio.common-util", ], export_shared_lib_headers: [ - "android.hardware.audio.common-util" + "android.hardware.audio.common-util", ], header_libs: [ @@ -76,7 +76,7 @@ cc_library_shared { "-DMAJOR_VERSION=2", "-DMINOR_VERSION=0", "-include common/all-versions/VersionMacro.h", - ] + ], } cc_library_shared { @@ -89,7 +89,7 @@ cc_library_shared { "-DMAJOR_VERSION=4", "-DMINOR_VERSION=0", "-include common/all-versions/VersionMacro.h", - ] + ], } cc_library_shared { @@ -102,7 +102,7 @@ cc_library_shared { "-DMAJOR_VERSION=5", "-DMINOR_VERSION=0", "-include common/all-versions/VersionMacro.h", - ] + ], } cc_library_shared { @@ -115,10 +115,11 @@ cc_library_shared { "-DMAJOR_VERSION=6", "-DMINOR_VERSION=0", "-include common/all-versions/VersionMacro.h", - ] + ], } cc_library_shared { + enabled: false, name: "android.hardware.audio.common@7.0-util", defaults: ["android.hardware.audio.common-util_default"], shared_libs: [ @@ -128,5 +129,5 @@ cc_library_shared { "-DMAJOR_VERSION=7", "-DMINOR_VERSION=0", "-include common/all-versions/VersionMacro.h", - ] + ], } diff --git a/audio/core/all-versions/default/Android.bp b/audio/core/all-versions/default/Android.bp index 46f64b70f3..6be0628b35 100644 --- a/audio/core/all-versions/default/Android.bp +++ b/audio/core/all-versions/default/Android.bp @@ -125,6 +125,7 @@ cc_library_shared { } cc_library_shared { + enabled: false, name: "android.hardware.audio@7.0-impl", defaults: ["android.hardware.audio-impl_default"], shared_libs: [ diff --git a/audio/core/all-versions/vts/functional/Android.bp b/audio/core/all-versions/vts/functional/Android.bp index 598944a80f..6ac9b20f95 100644 --- a/audio/core/all-versions/vts/functional/Android.bp +++ b/audio/core/all-versions/vts/functional/Android.bp @@ -130,6 +130,7 @@ cc_test { } cc_test { + enabled: false, name: "VtsHalAudioV7_0TargetTest", defaults: ["VtsHalAudioTargetTest_defaults"], srcs: [ diff --git a/audio/effect/all-versions/default/Android.bp b/audio/effect/all-versions/default/Android.bp index 01392bd13a..1c3dc74f17 100644 --- a/audio/effect/all-versions/default/Android.bp +++ b/audio/effect/all-versions/default/Android.bp @@ -56,7 +56,7 @@ cc_library_shared { "-DMAJOR_VERSION=2", "-DMINOR_VERSION=0", "-include common/all-versions/VersionMacro.h", - ] + ], } cc_library_shared { @@ -71,7 +71,7 @@ cc_library_shared { "-DMAJOR_VERSION=4", "-DMINOR_VERSION=0", "-include common/all-versions/VersionMacro.h", - ] + ], } cc_library_shared { @@ -86,7 +86,7 @@ cc_library_shared { "-DMAJOR_VERSION=5", "-DMINOR_VERSION=0", "-include common/all-versions/VersionMacro.h", - ] + ], } cc_library_shared { @@ -101,10 +101,11 @@ cc_library_shared { "-DMAJOR_VERSION=6", "-DMINOR_VERSION=0", "-include common/all-versions/VersionMacro.h", - ] + ], } cc_library_shared { + enabled: false, name: "android.hardware.audio.effect@7.0-impl", defaults: ["android.hardware.audio.effect-impl_default"], shared_libs: [ @@ -116,5 +117,5 @@ cc_library_shared { "-DMAJOR_VERSION=7", "-DMINOR_VERSION=0", "-include common/all-versions/VersionMacro.h", - ] + ], } diff --git a/audio/effect/all-versions/vts/functional/Android.bp b/audio/effect/all-versions/vts/functional/Android.bp index 6a1d6a3f04..7cdb18f95f 100644 --- a/audio/effect/all-versions/vts/functional/Android.bp +++ b/audio/effect/all-versions/vts/functional/Android.bp @@ -19,7 +19,7 @@ cc_defaults { defaults: ["VtsHalTargetTestDefaults"], srcs: [ "VtsHalAudioEffectTargetTest.cpp", - "ValidateAudioEffectsConfiguration.cpp" + "ValidateAudioEffectsConfiguration.cpp", ], static_libs: [ "android.hardware.audio.common.test.utility", @@ -31,7 +31,10 @@ cc_defaults { header_libs: [ "android.hardware.audio.common.util@all-versions", ], - test_suites: ["general-tests", "vts"], + test_suites: [ + "general-tests", + "vts", + ], } cc_test { @@ -51,7 +54,7 @@ cc_test { "-DMAJOR_VERSION=2", "-DMINOR_VERSION=0", "-include common/all-versions/VersionMacro.h", - ] + ], } cc_test { @@ -71,7 +74,7 @@ cc_test { "-DMAJOR_VERSION=4", "-DMINOR_VERSION=0", "-include common/all-versions/VersionMacro.h", - ] + ], } cc_test { @@ -91,7 +94,7 @@ cc_test { "-DMAJOR_VERSION=5", "-DMINOR_VERSION=0", "-include common/all-versions/VersionMacro.h", - ] + ], } cc_test { @@ -111,10 +114,11 @@ cc_test { "-DMAJOR_VERSION=6", "-DMINOR_VERSION=0", "-include common/all-versions/VersionMacro.h", - ] + ], } cc_test { + enabled: false, name: "VtsHalAudioEffectV7_0TargetTest", defaults: ["VtsHalAudioEffectTargetTest_default"], // Use test_config for vts suite. @@ -131,5 +135,5 @@ cc_test { "-DMAJOR_VERSION=7", "-DMINOR_VERSION=0", "-include common/all-versions/VersionMacro.h", - ] + ], } -- GitLab From 7dd87f42f1f7c684c773c1c615926f2e77e2595f Mon Sep 17 00:00:00 2001 From: Mikhail Naganov Date: Tue, 4 Aug 2020 23:37:05 +0000 Subject: [PATCH 116/790] Audio: Rearrange types in V7 Update channel mask and SR lists to conform to XSD. Added a script for converting existing APM XML files. Bug: 142480271 Test: m Change-Id: I986b9bccdade5fa850b06b033143388715a656af --- audio/7.0/IDevice.hal | 1 - audio/7.0/IStream.hal | 68 +- audio/7.0/IStreamIn.hal | 8 +- audio/7.0/IStreamOut.hal | 8 +- audio/7.0/config/api/current.txt | 151 ++- .../7.0/config/audio_policy_configuration.xsd | 168 ++- .../7.0/config/update_audio_policy_config.sh | 159 +++ audio/7.0/types.hal | 55 + audio/common/7.0/types.hal | 1032 +++-------------- audio/effect/7.0/IEffect.hal | 8 +- audio/effect/7.0/IVirtualizerEffect.hal | 10 +- audio/effect/7.0/types.hal | 6 +- 12 files changed, 642 insertions(+), 1032 deletions(-) create mode 100755 audio/7.0/config/update_audio_policy_config.sh diff --git a/audio/7.0/IDevice.hal b/audio/7.0/IDevice.hal index 7082d6b7ab..eecd92ed7c 100644 --- a/audio/7.0/IDevice.hal +++ b/audio/7.0/IDevice.hal @@ -315,7 +315,6 @@ interface IDevice { * INVALID_STATE if the device was already closed * or there are streams currently opened. */ - @exit close() generates (Result retval); /** diff --git a/audio/7.0/IStream.hal b/audio/7.0/IStream.hal index dacd3fd342..789cb1dfd1 100644 --- a/audio/7.0/IStream.hal +++ b/audio/7.0/IStream.hal @@ -43,13 +43,6 @@ interface IStream { */ getBufferSize() generates (uint64_t bufferSize); - /** - * Return the sampling rate in Hz. - * - * @return sampleRateHz sample rate in Hz. - */ - getSampleRate() generates (uint32_t sampleRateHz); - /** * Return supported native sampling rates of the stream for a given format. * A supported native sample rate is a sample rate that can be efficiently @@ -71,23 +64,6 @@ interface IStream { getSupportedSampleRates(AudioFormat format) generates (Result retval, vec sampleRates); - /** - * Sets the sampling rate of the stream. Calling this method is equivalent - * to setting AUDIO_PARAMETER_STREAM_SAMPLING_RATE on the legacy HAL. - * Optional method. If implemented, only called on a stopped stream. - * - * @param sampleRateHz sample rate in Hz. - * @return retval operation completion status. - */ - setSampleRate(uint32_t sampleRateHz) generates (Result retval); - - /** - * Return the channel mask of the stream. - * - * @return mask channel mask. - */ - getChannelMask() generates (bitfield mask); - /** * Return supported channel masks of the stream. Calling this method is * equivalent to getting AUDIO_PARAMETER_STREAM_SUP_CHANNELS on the legacy @@ -99,24 +75,7 @@ interface IStream { * @return masks supported audio masks. */ getSupportedChannelMasks(AudioFormat format) - generates (Result retval, vec> masks); - - /** - * Sets the channel mask of the stream. Calling this method is equivalent to - * setting AUDIO_PARAMETER_STREAM_CHANNELS on the legacy HAL. - * Optional method - * - * @param format audio format. - * @return retval operation completion status. - */ - setChannelMask(bitfield mask) generates (Result retval); - - /** - * Return the audio format of the stream. - * - * @return format audio format. - */ - getFormat() generates (AudioFormat format); + generates (Result retval, vec> masks); /** * Return supported audio formats of the stream. Calling this method is @@ -130,25 +89,23 @@ interface IStream { getSupportedFormats() generates (Result retval, vec formats); /** - * Sets the audio format of the stream. Calling this method is equivalent to - * setting AUDIO_PARAMETER_STREAM_FORMAT on the legacy HAL. - * Optional method + * Retrieves basic stream configuration: sample rate, audio format, + * channel mask. * - * @param format audio format. - * @return retval operation completion status. + * @return config basic stream configuration. */ - setFormat(AudioFormat format) generates (Result retval); + getAudioProperties() generates (AudioBasicConfig config); /** - * Convenience method for retrieving several stream parameters in - * one transaction. + * Sets stream parameters. Only sets parameters that are specified. + * See the description of AudioBasicConfig for the details. * - * @return sampleRateHz sample rate in Hz. - * @return mask channel mask. - * @return format audio format. + * Optional method. If implemented, only called on a stopped stream. + * + * @param config basic stream configuration. + * @return retval operation completion status. */ - getAudioProperties() generates ( - uint32_t sampleRateHz, bitfield mask, AudioFormat format); + setAudioProperties(AudioBasicConfig config) generates (Result retval); /** * Applies audio effect to the stream. @@ -312,6 +269,5 @@ interface IStream { * output stream interface. * INVALID_STATE if the stream was already closed. */ - @exit close() generates (Result retval); }; diff --git a/audio/7.0/IStreamIn.hal b/audio/7.0/IStreamIn.hal index 15e436359e..0a3f24b840 100644 --- a/audio/7.0/IStreamIn.hal +++ b/audio/7.0/IStreamIn.hal @@ -100,7 +100,7 @@ interface IStreamIn extends IStream { * * The driver operates on a dedicated thread. The client must ensure that * the thread is given an appropriate priority and assigned to correct - * scheduler and cgroup. For this purpose, the method returns identifiers + * scheduler and cgroup. For this purpose, the method returns the identifier * of the driver thread. * * @param frameSize the size of a single frame, in bytes. @@ -115,7 +115,9 @@ interface IStreamIn extends IStream { * specified at the stream opening. * @return statusMQ a message queue used for passing status from the driver * using ReadStatus structures. - * @return threadInfo identifiers of the driver's dedicated thread. + * @return threadId identifier of the driver's dedicated thread; the caller + * may adjust the thread priority to match the priority + * of the thread that provides audio data. */ prepareForReading(uint32_t frameSize, uint32_t framesCount) generates ( @@ -123,7 +125,7 @@ interface IStreamIn extends IStream { fmq_sync commandMQ, fmq_sync dataMQ, fmq_sync statusMQ, - ThreadInfo threadInfo); + int32_t threadId); /** * Return the amount of input frames lost in the audio driver since the last diff --git a/audio/7.0/IStreamOut.hal b/audio/7.0/IStreamOut.hal index 208beb6363..38d750f76b 100644 --- a/audio/7.0/IStreamOut.hal +++ b/audio/7.0/IStreamOut.hal @@ -95,7 +95,7 @@ interface IStreamOut extends IStream { * * The driver operates on a dedicated thread. The client must ensure that * the thread is given an appropriate priority and assigned to correct - * scheduler and cgroup. For this purpose, the method returns identifiers + * scheduler and cgroup. For this purpose, the method returns the identifier * of the driver thread. * * @param frameSize the size of a single frame, in bytes. @@ -109,7 +109,9 @@ interface IStreamOut extends IStream { * specified at the stream opening. * @return statusMQ a message queue used for passing status from the driver * using WriteStatus structures. - * @return threadInfo identifiers of the driver's dedicated thread. + * @return threadId identifier of the driver's dedicated thread; the caller + * may adjust the thread priority to match the priority + * of the thread that provides audio data. */ prepareForWriting(uint32_t frameSize, uint32_t framesCount) generates ( @@ -117,7 +119,7 @@ interface IStreamOut extends IStream { fmq_sync commandMQ, fmq_sync dataMQ, fmq_sync statusMQ, - ThreadInfo threadInfo); + int32_t threadId); /** * Return the number of audio frames written by the audio DSP to DAC since diff --git a/audio/7.0/config/api/current.txt b/audio/7.0/config/api/current.txt index 98c5eac982..fd9a8ef200 100644 --- a/audio/7.0/config/api/current.txt +++ b/audio/7.0/config/api/current.txt @@ -6,6 +6,81 @@ package audio.policy.configuration.V7_0 { method public java.util.List getItem(); } + public enum AudioChannelMask { + method public String getRawName(); + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_1; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_10; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_11; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_12; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_13; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_14; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_15; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_16; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_17; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_18; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_19; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_2; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_20; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_21; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_22; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_23; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_24; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_3; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_4; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_5; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_6; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_7; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_8; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_9; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_IN_2POINT0POINT2; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_IN_2POINT1POINT2; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_IN_3POINT0POINT2; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_IN_3POINT1POINT2; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_IN_5POINT1; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_IN_6; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_IN_FRONT_BACK; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_IN_MONO; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_IN_STEREO; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_IN_VOICE_CALL_MONO; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_IN_VOICE_DNLINK_MONO; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_IN_VOICE_UPLINK_MONO; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_2POINT0POINT2; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_2POINT1; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_2POINT1POINT2; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_3POINT0POINT2; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_3POINT1POINT2; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_5POINT1; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_5POINT1POINT2; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_5POINT1POINT4; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_5POINT1_BACK; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_5POINT1_SIDE; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_6POINT1; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_7POINT1; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_7POINT1POINT2; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_7POINT1POINT4; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_HAPTIC_AB; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_MONO; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_MONO_HAPTIC_A; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_MONO_HAPTIC_AB; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_PENTA; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_QUAD; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_QUAD_BACK; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_QUAD_SIDE; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_STEREO; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_STEREO_HAPTIC_A; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_STEREO_HAPTIC_AB; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_SURROUND; + } + + public enum AudioContentType { + method public String getRawName(); + enum_constant public static final audio.policy.configuration.V7_0.AudioContentType AUDIO_CONTENT_TYPE_MOVIE; + enum_constant public static final audio.policy.configuration.V7_0.AudioContentType AUDIO_CONTENT_TYPE_MUSIC; + enum_constant public static final audio.policy.configuration.V7_0.AudioContentType AUDIO_CONTENT_TYPE_SONIFICATION; + enum_constant public static final audio.policy.configuration.V7_0.AudioContentType AUDIO_CONTENT_TYPE_SPEECH; + enum_constant public static final audio.policy.configuration.V7_0.AudioContentType AUDIO_CONTENT_TYPE_UNKNOWN; + } + public enum AudioDevice { method public String getRawName(); enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_AMBIENT; @@ -116,6 +191,7 @@ package audio.policy.configuration.V7_0 { enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_APTX_HD; enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_APTX_TWSP; enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_CELT; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DEFAULT; enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DOLBY_TRUEHD; enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DSD; enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DTS; @@ -164,18 +240,59 @@ package audio.policy.configuration.V7_0 { method public void setVersion(audio.policy.configuration.V7_0.Version); } + public enum AudioSource { + method public String getRawName(); + enum_constant public static final audio.policy.configuration.V7_0.AudioSource AUDIO_SOURCE_CAMCORDER; + enum_constant public static final audio.policy.configuration.V7_0.AudioSource AUDIO_SOURCE_DEFAULT; + enum_constant public static final audio.policy.configuration.V7_0.AudioSource AUDIO_SOURCE_ECHO_REFERENCE; + enum_constant public static final audio.policy.configuration.V7_0.AudioSource AUDIO_SOURCE_FM_TUNER; + enum_constant public static final audio.policy.configuration.V7_0.AudioSource AUDIO_SOURCE_HOTWORD; + enum_constant public static final audio.policy.configuration.V7_0.AudioSource AUDIO_SOURCE_MIC; + enum_constant public static final audio.policy.configuration.V7_0.AudioSource AUDIO_SOURCE_REMOTE_SUBMIX; + enum_constant public static final audio.policy.configuration.V7_0.AudioSource AUDIO_SOURCE_UNPROCESSED; + enum_constant public static final audio.policy.configuration.V7_0.AudioSource AUDIO_SOURCE_VOICE_CALL; + enum_constant public static final audio.policy.configuration.V7_0.AudioSource AUDIO_SOURCE_VOICE_COMMUNICATION; + enum_constant public static final audio.policy.configuration.V7_0.AudioSource AUDIO_SOURCE_VOICE_DOWNLINK; + enum_constant public static final audio.policy.configuration.V7_0.AudioSource AUDIO_SOURCE_VOICE_PERFORMANCE; + enum_constant public static final audio.policy.configuration.V7_0.AudioSource AUDIO_SOURCE_VOICE_RECOGNITION; + enum_constant public static final audio.policy.configuration.V7_0.AudioSource AUDIO_SOURCE_VOICE_UPLINK; + } + + public enum AudioStreamType { + method public String getRawName(); + enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_ACCESSIBILITY; + enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_ALARM; + enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_ASSISTANT; + enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_BLUETOOTH_SCO; + enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_DTMF; + enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_ENFORCED_AUDIBLE; + enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_MUSIC; + enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_NOTIFICATION; + enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_PATCH; + enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_REROUTING; + enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_RING; + enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_SYSTEM; + enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_TTS; + enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_VOICE_CALL; + } + public enum AudioUsage { method public String getRawName(); enum_constant public static final audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_ALARM; + enum_constant public static final audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_ANNOUNCEMENT; enum_constant public static final audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY; enum_constant public static final audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE; enum_constant public static final audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_ASSISTANCE_SONIFICATION; enum_constant public static final audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_ASSISTANT; + enum_constant public static final audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_CALL_ASSISTANT; + enum_constant public static final audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_EMERGENCY; enum_constant public static final audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_GAME; enum_constant public static final audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_MEDIA; enum_constant public static final audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_NOTIFICATION; enum_constant public static final audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE; + enum_constant public static final audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_SAFETY; enum_constant public static final audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_UNKNOWN; + enum_constant public static final audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_VEHICLE_STATUS; enum_constant public static final audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_VIRTUAL_SOURCE; enum_constant public static final audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_VOICE_COMMUNICATION; enum_constant public static final audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING; @@ -234,7 +351,7 @@ package audio.policy.configuration.V7_0 { public static class Gains.Gain { ctor public Gains.Gain(); - method public String getChannel_mask(); + method public audio.policy.configuration.V7_0.AudioChannelMask getChannel_mask(); method public int getDefaultValueMB(); method public int getMaxRampMs(); method public int getMaxValueMB(); @@ -244,7 +361,7 @@ package audio.policy.configuration.V7_0 { method public String getName(); method public int getStepValueMB(); method public boolean getUseForVolume(); - method public void setChannel_mask(String); + method public void setChannel_mask(audio.policy.configuration.V7_0.AudioChannelMask); method public void setDefaultValueMB(int); method public void setMaxRampMs(int); method public void setMaxValueMB(int); @@ -327,14 +444,14 @@ package audio.policy.configuration.V7_0 { public class Profile { ctor public Profile(); - method public String getChannelMasks(); + method public java.util.List getChannelMasks(); method public String getFormat(); method public String getName(); - method public String getSamplingRates(); - method public void setChannelMasks(String); + method public java.util.List getSamplingRates(); + method public void setChannelMasks(java.util.List); method public void setFormat(String); method public void setName(String); - method public void setSamplingRates(String); + method public void setSamplingRates(java.util.List); } public class Reference { @@ -365,24 +482,6 @@ package audio.policy.configuration.V7_0 { method public void setType(audio.policy.configuration.V7_0.MixType); } - public enum Stream { - method public String getRawName(); - enum_constant public static final audio.policy.configuration.V7_0.Stream AUDIO_STREAM_ACCESSIBILITY; - enum_constant public static final audio.policy.configuration.V7_0.Stream AUDIO_STREAM_ALARM; - enum_constant public static final audio.policy.configuration.V7_0.Stream AUDIO_STREAM_ASSISTANT; - enum_constant public static final audio.policy.configuration.V7_0.Stream AUDIO_STREAM_BLUETOOTH_SCO; - enum_constant public static final audio.policy.configuration.V7_0.Stream AUDIO_STREAM_DTMF; - enum_constant public static final audio.policy.configuration.V7_0.Stream AUDIO_STREAM_ENFORCED_AUDIBLE; - enum_constant public static final audio.policy.configuration.V7_0.Stream AUDIO_STREAM_MUSIC; - enum_constant public static final audio.policy.configuration.V7_0.Stream AUDIO_STREAM_NOTIFICATION; - enum_constant public static final audio.policy.configuration.V7_0.Stream AUDIO_STREAM_PATCH; - enum_constant public static final audio.policy.configuration.V7_0.Stream AUDIO_STREAM_REROUTING; - enum_constant public static final audio.policy.configuration.V7_0.Stream AUDIO_STREAM_RING; - enum_constant public static final audio.policy.configuration.V7_0.Stream AUDIO_STREAM_SYSTEM; - enum_constant public static final audio.policy.configuration.V7_0.Stream AUDIO_STREAM_TTS; - enum_constant public static final audio.policy.configuration.V7_0.Stream AUDIO_STREAM_VOICE_CALL; - } - public class SurroundFormats { ctor public SurroundFormats(); method public java.util.List getFormat(); @@ -412,10 +511,10 @@ package audio.policy.configuration.V7_0 { method public audio.policy.configuration.V7_0.DeviceCategory getDeviceCategory(); method public java.util.List getPoint(); method public String getRef(); - method public audio.policy.configuration.V7_0.Stream getStream(); + method public audio.policy.configuration.V7_0.AudioStreamType getStream(); method public void setDeviceCategory(audio.policy.configuration.V7_0.DeviceCategory); method public void setRef(String); - method public void setStream(audio.policy.configuration.V7_0.Stream); + method public void setStream(audio.policy.configuration.V7_0.AudioStreamType); } public class Volumes { diff --git a/audio/7.0/config/audio_policy_configuration.xsd b/audio/7.0/config/audio_policy_configuration.xsd index 19c6f70536..4555a88034 100644 --- a/audio/7.0/config/audio_policy_configuration.xsd +++ b/audio/7.0/config/audio_policy_configuration.xsd @@ -13,7 +13,6 @@ See the License for the specific language governing permissions and limitations under the License. --> - - Version of the interface the hal implements. + Version of the interface the hal implements. Note that this + relates to legacy HAL API versions since HIDL APIs are versioned + using other mechanisms. @@ -154,7 +155,6 @@ - @@ -212,9 +212,6 @@ - @@ -252,7 +249,6 @@ - @@ -298,10 +294,9 @@ - + @@ -382,9 +377,14 @@ - + + + Audio usage specifies the intended use case for the sound being played. + Please consult frameworks/base/media/java/android/media/AudioAttributes.java + for the description of each value. + + @@ -399,34 +399,119 @@ + + + + + - - + + + + Audio content type expresses the general category of the content. + Please consult frameworks/base/media/java/android/media/AudioAttributes.java + for the description of each value. + + - + + + + + - - + + + + - Comma (",") separated list of channel flags - from audio_channel_mask_t. + Audio channel mask specifies presence of particular channels. + There are two representations: + - representation position (traditional discrete channel specification, + e.g. "left", "right"); + - indexed (this is similar to "tracks" in audio mixing, channels + are represented using numbers). - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + @@ -441,7 +526,7 @@ - + @@ -537,9 +622,14 @@ - - + + + + Audio stream type describing the intended use case of a stream. + Please consult frameworks/base/media/java/android/media/AudioSystem.java + for the description of each value. + + @@ -557,8 +647,32 @@ - + + + + An audio source defines the intended use case for the sound being recorded. + Please consult frameworks/base/media/java/android/media/MediaRecorder.java + for the description of each value. + + + + + + + + + + + + + + + + + + + + @@ -591,7 +705,7 @@ - + diff --git a/audio/7.0/config/update_audio_policy_config.sh b/audio/7.0/config/update_audio_policy_config.sh new file mode 100755 index 0000000000..8714b5f2d3 --- /dev/null +++ b/audio/7.0/config/update_audio_policy_config.sh @@ -0,0 +1,159 @@ +#!/bin/bash + +# 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 script is used to update audio policy configuration files +# to comply with the updated audio_policy_configuration.xsd from V7.0. +# +# The main difference is the separator used in lists for attributes. +# Since the XML Schema Definition standard only allows space to be +# used as a separator (see https://www.w3.org/TR/xmlschema11-2/#list-datatypes) +# the previous versions used a regular expression to validate lists +# in attribute values. E.g. the channel masks were validated using +# the following regexp: [_A-Z][_A-Z0-9]*(,[_A-Z][_A-Z0-9]*)* +# This has an obvious drawback of missing typos in the config file. +# +# The V7.0 has shifted to defining most of the frequently changed +# types in the XSD schema only. This allows for verifying all the values +# in lists, but in order to comply with XML Schema requirements +# list elements must be separated by space. +# +# Since the APM config files typically use include directives, +# the script must be pointed to the main APM config file and will +# take care all the included files automatically. +# If the included file is a shared version from 'frameworks/av', +# instead of updating it the script checks if there is a newer +# version with the corresponding name suffix (e.g. +# 'a2dp_audio_policy_configuration_7_0.xml') and updates the include +# path instead. + +set -euo pipefail + +if (echo "$@" | grep -qe -h); then + echo "This script will update Audio Policy Manager config file" + echo "to the format required by V7.0 XSD schema from a previous" + echo "version." + echo + echo "USAGE: $0 [APM_XML_FILE] [OLD_VERSION]" + echo " APM_XML_FILE specifies the path to audio_policy_configuration.xml" + echo " relative to Android repository root" + echo " OLD_VERSION specifies the version of schema currently used" + echo + echo "Example: $0 device/generic/goldfish/audio/policy/audio_policy_configuration.xml 6.0" + exit +fi +readonly HAL_DIRECTORY=hardware/interfaces/audio +readonly SHARED_CONFIGS_DIRECTORY=frameworks/av/services/audiopolicy/config +readonly OLD_VERSION=${2:-$(ls ${ANDROID_BUILD_TOP}/${HAL_DIRECTORY} | grep -E '[0-9]+\.[0-9]+' | + sort -n | tail -n1)} +readonly NEW_VERSION=7.0 +readonly NEW_VERSION_UNDERSCORE=7_0 + +readonly SOURCE_CONFIG=${ANDROID_BUILD_TOP}/$1 + +# First, validate the input using the schema of the current version + +echo Validating the source against the $OLD_VERSION schema +xmllint --noout --xinclude \ + --nofixup-base-uris --path "$ANDROID_BUILD_TOP/$SHARED_CONFIGS_DIRECTORY" \ + --schema ${ANDROID_BUILD_TOP}/${HAL_DIRECTORY}/${OLD_VERSION}/config/audio_policy_configuration.xsd \ + ${SOURCE_CONFIG} +if [ $? -ne 0 ]; then + echo + echo "Config file fails validation for the specified version $OLD_VERSION--unsafe to update" + exit 1 +fi + +# Find all the source files recursively + +SOURCE_FILES=${SOURCE_CONFIG} +SHARED_FILES= +findIncludes() { + local FILES_TO_CHECK= + for F in $1; do + local FOUND_INCLUDES=$(grep -Po ' channelMask; // empty means 'unspecified' + AudioFormat format; // 'DEFAULT' means 'unspecified' }; /** @@ -607,301 +136,55 @@ enum AudioMode : int32_t { CALL_SCREEN = 4, }; -@export(name="", value_prefix="AUDIO_DEVICE_") -enum AudioDevice : uint32_t { - NONE = 0x0, - /** reserved bits */ - BIT_IN = 0x80000000, - BIT_DEFAULT = 0x40000000, - /** output devices */ - OUT_EARPIECE = 0x1, - OUT_SPEAKER = 0x2, - OUT_WIRED_HEADSET = 0x4, - OUT_WIRED_HEADPHONE = 0x8, - OUT_BLUETOOTH_SCO = 0x10, - OUT_BLUETOOTH_SCO_HEADSET = 0x20, - OUT_BLUETOOTH_SCO_CARKIT = 0x40, - OUT_BLUETOOTH_A2DP = 0x80, - OUT_BLUETOOTH_A2DP_HEADPHONES = 0x100, - OUT_BLUETOOTH_A2DP_SPEAKER = 0x200, - OUT_AUX_DIGITAL = 0x400, - OUT_HDMI = OUT_AUX_DIGITAL, - /** uses an analog connection (multiplexed over the USB pins for instance) */ - OUT_ANLG_DOCK_HEADSET = 0x800, - OUT_DGTL_DOCK_HEADSET = 0x1000, - /** USB accessory mode: Android device is USB device and dock is USB host */ - OUT_USB_ACCESSORY = 0x2000, - /** USB host mode: Android device is USB host and dock is USB device */ - OUT_USB_DEVICE = 0x4000, - OUT_REMOTE_SUBMIX = 0x8000, - /** Telephony voice TX path */ - OUT_TELEPHONY_TX = 0x10000, - /** Analog jack with line impedance detected */ - OUT_LINE = 0x20000, - /** HDMI Audio Return Channel */ - OUT_HDMI_ARC = 0x40000, - /** S/PDIF out */ - OUT_SPDIF = 0x80000, - /** FM transmitter out */ - OUT_FM = 0x100000, - /** Line out for av devices */ - OUT_AUX_LINE = 0x200000, - /** limited-output speaker device for acoustic safety */ - OUT_SPEAKER_SAFE = 0x400000, - OUT_IP = 0x800000, - /** audio bus implemented by the audio system (e.g an MOST stereo channel) */ - OUT_BUS = 0x1000000, - OUT_PROXY = 0x2000000, - OUT_USB_HEADSET = 0x4000000, - OUT_HEARING_AID = 0x8000000, - OUT_ECHO_CANCELLER = 0x10000000, - OUT_DEFAULT = BIT_DEFAULT, - // Note that the 2.0 OUT_ALL* have been moved to helper functions - - /** input devices */ - IN_COMMUNICATION = BIT_IN | 0x1, - IN_AMBIENT = BIT_IN | 0x2, - IN_BUILTIN_MIC = BIT_IN | 0x4, - IN_BLUETOOTH_SCO_HEADSET = BIT_IN | 0x8, - IN_WIRED_HEADSET = BIT_IN | 0x10, - IN_AUX_DIGITAL = BIT_IN | 0x20, - IN_HDMI = IN_AUX_DIGITAL, - /** Telephony voice RX path */ - IN_VOICE_CALL = BIT_IN | 0x40, - IN_TELEPHONY_RX = IN_VOICE_CALL, - IN_BACK_MIC = BIT_IN | 0x80, - IN_REMOTE_SUBMIX = BIT_IN | 0x100, - IN_ANLG_DOCK_HEADSET = BIT_IN | 0x200, - IN_DGTL_DOCK_HEADSET = BIT_IN | 0x400, - IN_USB_ACCESSORY = BIT_IN | 0x800, - IN_USB_DEVICE = BIT_IN | 0x1000, - /** FM tuner input */ - IN_FM_TUNER = BIT_IN | 0x2000, - /** TV tuner input */ - IN_TV_TUNER = BIT_IN | 0x4000, - /** Analog jack with line impedance detected */ - IN_LINE = BIT_IN | 0x8000, - /** S/PDIF in */ - IN_SPDIF = BIT_IN | 0x10000, - IN_BLUETOOTH_A2DP = BIT_IN | 0x20000, - IN_LOOPBACK = BIT_IN | 0x40000, - IN_IP = BIT_IN | 0x80000, - /** audio bus implemented by the audio system (e.g an MOST stereo channel) */ - IN_BUS = BIT_IN | 0x100000, - IN_PROXY = BIT_IN | 0x1000000, - IN_USB_HEADSET = BIT_IN | 0x2000000, - IN_BLUETOOTH_BLE = BIT_IN | 0x4000000, - IN_ECHO_REFERENCE = BIT_IN | 0x10000000, - IN_DEFAULT = BIT_IN | BIT_DEFAULT, - - // Note that the 2.0 IN_ALL* have been moved to helper functions -}; - -/** - * IEEE 802 MAC address. - */ -typedef uint8_t[6] MacAddress; - /** * Specifies a device address in case when several devices of the same type * can be connected (e.g. BT A2DP, USB). */ struct DeviceAddress { - AudioDevice device; // discriminator - union Address { - MacAddress mac; // used for BLUETOOTH_A2DP_* - uint8_t[4] ipv4; // used for IP + /** + * Audio device specifies type (or category) of audio I/O device + * (e.g. speaker or headphones). + * See 'audioDevice' in audio_policy_configuration.xsd for the + * list of allowed values. + */ + string deviceType; + safe_union Address { + /** + * The address may be left unspecified if 'device' specifies + * a physical device unambiguously. + */ + Monostate unspecified; + /** IEEE 802 MAC address. Set for Bluetooth devices. */ + uint8_t[6] mac; + /** IPv4 Address. Set for IPv4 devices. */ + uint8_t[4] ipv4; + /** IPv6 Address. Set for IPv6 devices. */ + uint16_t[8] ipv6; + /** PCI bus Address. Set for USB devices. */ struct Alsa { int32_t card; int32_t device; - } alsa; // used for USB_* + } alsa; + /** Arbitrary BUS device unique address. Not interpreted by the framework. */ + string bus; + /** Arbitrary REMOTE_SUBMIX device unique address. Not interpreted by the HAL. */ + string rSubmix; } address; - /** Arbitrary BUS device unique address. Should not be interpreted by the framework. */ - string busAddress; - /** Arbitrary REMOTE_SUBMIX device unique address. Should not be interpreted by the HAL. */ - string rSubmixAddress; }; /** - * The audio output flags serve two purposes: - * - * - when an AudioTrack is created they indicate a "wish" to be connected to an - * output stream with attributes corresponding to the specified flags; - * - * - when present in an output profile descriptor listed for a particular audio - * hardware module, they indicate that an output stream can be opened that - * supports the attributes indicated by the flags. - * - * The audio policy manager will try to match the flags in the request - * (when getOuput() is called) to an available output stream. + * Audio usage specifies the intended use case for the sound being played. + * See 'audioUsage' in audio_policy_configuration.xsd for the + * list of allowed values. */ -@export(name="audio_output_flags_t", value_prefix="AUDIO_OUTPUT_FLAG_") -enum AudioOutputFlag : int32_t { - NONE = 0x0, // no attributes - DIRECT = 0x1, // this output directly connects a track - // to one output stream: no software mixer - PRIMARY = 0x2, // this output is the primary output of the device. It is - // unique and must be present. It is opened by default and - // receives routing, audio mode and volume controls related - // to voice calls. - FAST = 0x4, // output supports "fast tracks", defined elsewhere - DEEP_BUFFER = 0x8, // use deep audio buffers - COMPRESS_OFFLOAD = 0x10, // offload playback of compressed streams to - // hardware codec - NON_BLOCKING = 0x20, // use non-blocking write - HW_AV_SYNC = 0x40, // output uses a hardware A/V sync - TTS = 0x80, // output for streams transmitted through speaker at a - // sample rate high enough to accommodate lower-range - // ultrasonic p/b - RAW = 0x100, // minimize signal processing - SYNC = 0x200, // synchronize I/O streams - IEC958_NONAUDIO = 0x400, // Audio stream contains compressed audio in SPDIF - // data bursts, not PCM. - DIRECT_PCM = 0x2000, // Audio stream containing PCM data that needs - // to pass through compress path for DSP post proc. - MMAP_NOIRQ = 0x4000, // output operates in MMAP no IRQ mode. - VOIP_RX = 0x8000, // preferred output for VoIP calls. - /** preferred output for call music */ - INCALL_MUSIC = 0x10000, -}; +typedef string AudioUsage; /** - * The audio input flags are analogous to audio output flags. - * Currently they are used only when an AudioRecord is created, - * to indicate a preference to be connected to an input stream with - * attributes corresponding to the specified flags. + * Audio content type expresses the general category of the content. + * See 'audioContentType' in audio_policy_configuration.xsd for the + * list of allowed values. */ -@export(name="audio_input_flags_t", value_prefix="AUDIO_INPUT_FLAG_") -enum AudioInputFlag : int32_t { - NONE = 0x0, // no attributes - FAST = 0x1, // prefer an input that supports "fast tracks" - HW_HOTWORD = 0x2, // prefer an input that captures from hw hotword source - RAW = 0x4, // minimize signal processing - SYNC = 0x8, // synchronize I/O streams - MMAP_NOIRQ = 0x10, // input operates in MMAP no IRQ mode. - VOIP_TX = 0x20, // preferred input for VoIP calls. - HW_AV_SYNC = 0x40, // input connected to an output that uses a hardware A/V sync - DIRECT = 0x80, // for acquiring encoded streams -}; - -@export(name="audio_usage_t", value_prefix="AUDIO_USAGE_") -enum AudioUsage : int32_t { - // These values must kept in sync with - // frameworks/base/media/java/android/media/AudioAttributes.java - // Note that not all framework values are exposed - /** - * Usage value to use when the usage is unknown. - */ - UNKNOWN = 0, - /** - * Usage value to use when the usage is media, such as music, or movie - * soundtracks. - */ - MEDIA = 1, - /** - * Usage value to use when the usage is voice communications, such as - * telephony or VoIP. - */ - VOICE_COMMUNICATION = 2, - /** - * Usage value to use when the usage is in-call signalling, such as with - * a "busy" beep, or DTMF tones. - */ - VOICE_COMMUNICATION_SIGNALLING = 3, - /** - * Usage value to use when the usage is an alarm (e.g. wake-up alarm). - */ - ALARM = 4, - /** - * Usage value to use when the usage is a generic notification. - */ - NOTIFICATION = 5, - /** - * Usage value to use when the usage is telephony ringtone. - */ - NOTIFICATION_TELEPHONY_RINGTONE = 6, - /** - * Usage value to use when the usage is for accessibility, such as with - * a screen reader. - */ - ASSISTANCE_ACCESSIBILITY = 11, - /** - * Usage value to use when the usage is driving or navigation directions. - */ - ASSISTANCE_NAVIGATION_GUIDANCE = 12, - /** - * Usage value to use when the usage is sonification, such as with user - * interface sounds. - */ - ASSISTANCE_SONIFICATION = 13, - /** - * Usage value to use when the usage is for game audio. - */ - GAME = 14, - /** - * Usage value to use when feeding audio to the platform and replacing - * "traditional" audio source, such as audio capture devices. - */ - VIRTUAL_SOURCE = 15, - /** - * Usage value to use for audio responses to user queries, audio - * instructions or help utterances. - */ - ASSISTANT = 16, - /** - * Usage value to use for assistant voice interaction with remote caller - * on Cell and VoIP calls. - */ - CALL_ASSISTANT = 17, - /** - * Usage value to use when the usage is an emergency. - */ - EMERGENCY = 1000, - /** - * Usage value to use when the usage is a safety sound. - */ - SAFETY = 1001, - /** - * Usage value to use when the usage is a vehicle status. - */ - VEHICLE_STATUS = 1002, - /** - * Usage value to use when the usage is an announcement. - */ - ANNOUNCEMENT = 1003, -}; - -/** Type of audio generated by an application. */ -@export(name="audio_content_type_t", value_prefix="AUDIO_CONTENT_TYPE_") -enum AudioContentType : uint32_t { - // Do not change these values without updating their counterparts - // in frameworks/base/media/java/android/media/AudioAttributes.java - /** - * Content type value to use when the content type is unknown, or other than - * the ones defined. - */ - UNKNOWN = 0, - /** - * Content type value to use when the content type is speech. - */ - SPEECH = 1, - /** - * Content type value to use when the content type is music. - */ - MUSIC = 2, - /** - * Content type value to use when the content type is a soundtrack, - * typically accompanying a movie or TV program. - */ - MOVIE = 3, - /** - * Content type value to use when the content type is a sound used to - * accompany a user action, such as a beep or sound effect expressing a key - * click, or event, such as the type of a sound for a bonus being received - * in a game. These sounds are mostly synthesized or short Foley sounds. - */ - SONIFICATION = 4, -}; +typedef string AudioContentType; /** Encapsulation mode used for sending audio compressed data. */ @export(name="audio_encapsulation_mode_t", value_prefix="AUDIO_ENCAPSULATION_MODE_") @@ -926,9 +209,7 @@ enum AudioEncapsulationMode : int32_t { * Additional information about the stream passed to hardware decoders. */ struct AudioOffloadInfo { - uint32_t sampleRateHz; - bitfield channelMask; - AudioFormat format; + AudioBasicConfig base; AudioStreamType streamType; uint32_t bitRatePerSecond; int64_t durationMicroseconds; // -1 if unknown @@ -946,9 +227,7 @@ struct AudioOffloadInfo { * Commonly used audio stream configuration parameters. */ struct AudioConfig { - uint32_t sampleRateHz; - bitfield channelMask; - AudioFormat format; + AudioBasicConfig base; AudioOffloadInfo offloadInfo; uint64_t frameCount; }; @@ -985,8 +264,7 @@ struct RecordTrackMetadata { safe_union Destination { Monostate unspecified; DeviceAddress device; - }; - Destination destination; + } destination; }; /** Metadatas of the sink of a StreamIn. */ @@ -994,7 +272,6 @@ struct SinkMetadata { vec tracks; }; - /* * * Volume control @@ -1017,7 +294,7 @@ enum AudioGainMode : uint32_t { */ struct AudioGain { bitfield mode; - bitfield channelMask; // channels which gain an be controlled + vec channelMask; // channels which gain an be controlled int32_t minValue; // minimum gain value in millibels int32_t maxValue; // maximum gain value in millibels int32_t defaultValue; // default gain value in millibels @@ -1033,10 +310,8 @@ struct AudioGain { struct AudioGainConfig { int32_t index; // index of the corresponding AudioGain in AudioPort.gains AudioGainMode mode; - AudioChannelMask channelMask; // channels which gain value follows + vec channelMask; // channels which gain value follows /** - * 4 = sizeof(AudioChannelMask), - * 8 is not "FCC_8", so it won't need to be changed for > 8 channels. * Gain values in millibels for each channel ordered from LSb to MSb in * channel mask. The number of values is 1 in joint mode or * popcount(channel_mask). @@ -1060,132 +335,85 @@ struct AudioGainConfig { * the interface. */ -/** Audio port role: either source or sink */ -@export(name="audio_port_role_t", value_prefix="AUDIO_PORT_ROLE_") -enum AudioPortRole : int32_t { - NONE, - SOURCE, - SINK, -}; - -/** - * Audio port type indicates if it is a session (e.g AudioTrack), a mix (e.g - * PlaybackThread output) or a physical device (e.g OUT_SPEAKER) - */ -@export(name="audio_port_type_t", value_prefix="AUDIO_PORT_TYPE_") -enum AudioPortType : int32_t { - NONE, - DEVICE, - MIX, - SESSION, -}; - /** - * Extension for audio port configuration structure when the audio port is a - * hardware device. - */ -struct AudioPortConfigDeviceExt { - AudioModuleHandle hwModule; // module the device is attached to - AudioDevice type; // device type (e.g OUT_SPEAKER) - uint8_t[32] address; // device address. "" if N/A -}; - -/** - * Extension for audio port configuration structure when the audio port is an - * audio session. - */ -struct AudioPortConfigSessionExt { + * A helper aggregate structure providing parameters that depend on the + * port role. + */ +safe_union AudioPortExtendedInfo { + /** Set when no information is provided. */ + Monostate unspecified; + /** Set when the audio port is an audio device. */ + DeviceAddress device; + /** Set when the audio port is a mix. The handle is of a stream. */ + struct AudioPortMixExt { + /** I/O handle of the input/output stream. */ + AudioIoHandle ioHandle; + safe_union UseCase { + /** Specified when the port is in the SOURCE role. */ + AudioStreamType stream; + /** Specified when the port is in the SINK role. */ + AudioSource source; + } useCase; + } mix; + /** Set when the audio port is an audio session. */ AudioSession session; }; -/** - * Flags indicating which fields are to be considered in AudioPortConfig. - */ -@export(name="", value_prefix="AUDIO_PORT_CONFIG_") -enum AudioPortConfigMask : uint32_t { - SAMPLE_RATE = 0x1, - CHANNEL_MASK = 0x2, - FORMAT = 0x4, - GAIN = 0x8, -}; - /** * Audio port configuration structure used to specify a particular configuration * of an audio port. */ struct AudioPortConfig { + /** + * The 'id' field is set when it is needed to select the port and + * apply new configuration for it. + */ AudioPortHandle id; - bitfield configMask; - uint32_t sampleRateHz; - bitfield channelMask; - AudioFormat format; - AudioGainConfig gain; - AudioPortType type; // type is used as a discriminator for Ext union - AudioPortRole role; // role is used as a discriminator for UseCase union - union Ext { - AudioPortConfigDeviceExt device; - struct AudioPortConfigMixExt { - AudioModuleHandle hwModule; // module the stream is attached to - AudioIoHandle ioHandle; // I/O handle of the input/output stream - union UseCase { - AudioStreamType stream; - AudioSource source; - } useCase; - } mix; - AudioPortConfigSessionExt session; - } ext; -}; - -/** - * Extension for audio port structure when the audio port is a hardware device. - */ -struct AudioPortDeviceExt { - AudioModuleHandle hwModule; // module the device is attached to - AudioDevice type; - /** 32 byte string identifying the port. */ - uint8_t[32] address; -}; - -/** - * Latency class of the audio mix. - */ -@export(name="audio_mix_latency_class_t", value_prefix="AUDIO_LATENCY_") -enum AudioMixLatencyClass : int32_t { - LOW, - NORMAL -}; - -struct AudioPortMixExt { - AudioModuleHandle hwModule; // module the stream is attached to - AudioIoHandle ioHandle; // I/O handle of the stream - AudioMixLatencyClass latencyClass; + /** + * Basic parameters: sampling rate, format, channel mask. Only some of the + * parameters (or none) may be set. See the documentation of the + * AudioBasicConfig struct. + */ + AudioBasicConfig config; + /** Associated gain control. */ + safe_union OptionalGain { + Monostate unspecified; + AudioGainConfig config; + } gain; + /** Parameters that depend on the actual port role. */ + AudioPortExtendedInfo ext; }; /** - * Extension for audio port structure when the audio port is an audio session. + * Audio port structure describes the capabilities of an audio port + * as well as its current configuration. */ -struct AudioPortSessionExt { - AudioSession session; -}; - struct AudioPort { + /** + * Unique identifier of the port within this HAL service. When calling + * from the client side functions like IDevice.getAudioPort is it allowed + * to only specify the 'id' and leave the other fields unspecified. + */ AudioPortHandle id; - AudioPortRole role; + /** + * Human-readable name describing the function of the port. + * E.g. "telephony_tx" or "fm_tuner". + */ string name; - vec sampleRates; - vec> channelMasks; - vec formats; + /** List of audio profiles supported by the port. */ + struct AudioProfile { + AudioFormat format; + /** List of the sample rates supported by the profile. */ + vec sampleRates; + /** List of channel masks supported by the profile. */ + vec channelMasks; + }; + vec profiles; + /** List of gain controls attached to the port. */ vec gains; - AudioPortConfig activeConfig; // current audio port configuration - AudioPortType type; // type is used as a discriminator - union Ext { - AudioPortDeviceExt device; - AudioPortMixExt mix; - AudioPortSessionExt session; - } ext; -}; - -struct ThreadInfo { - int64_t pid; - int64_t tid; + /** + * Current configuration of the audio port, may have all the fields left + * unspecified. + */ + AudioPortConfig activeConfig; }; diff --git a/audio/effect/7.0/IEffect.hal b/audio/effect/7.0/IEffect.hal index 5b176dc2f3..aa94f6ddcd 100644 --- a/audio/effect/7.0/IEffect.hal +++ b/audio/effect/7.0/IEffect.hal @@ -56,7 +56,6 @@ interface IEffect { * * @return retval operation completion status. */ - @callflow(next={"prepareForProcessing"}) enable() generates (Result retval); /** @@ -64,7 +63,6 @@ interface IEffect { * * @return retval operation completion status. */ - @callflow(next={"close"}) disable() generates (Result retval); /** @@ -78,7 +76,7 @@ interface IEffect { * @param device output device specification. * @return retval operation completion status. */ - setDevice(bitfield device) generates (Result retval); + setDevice(DeviceAddress device) generates (Result retval); /** * Set and get volume. Used by audio framework to delegate volume control to @@ -147,7 +145,7 @@ interface IEffect { * @param device input device specification. * @return retval operation completion status. */ - setInputDevice(bitfield device) generates (Result retval); + setInputDevice(DeviceAddress device) generates (Result retval); /** * Read audio parameters configurations for input and output buffers. @@ -251,7 +249,6 @@ interface IEffect { * the queue. * @return statusMQ a message queue used for passing status from the effect. */ - @callflow(next={"setProcessBuffers"}) prepareForProcessing() generates (Result retval, fmq_sync statusMQ); /** @@ -416,6 +413,5 @@ interface IEffect { * @return retval OK in case the success. * INVALID_STATE if the effect was already closed. */ - @exit close() generates (Result retval); }; diff --git a/audio/effect/7.0/IVirtualizerEffect.hal b/audio/effect/7.0/IVirtualizerEffect.hal index 0e6ff54403..141b4e6797 100644 --- a/audio/effect/7.0/IVirtualizerEffect.hal +++ b/audio/effect/7.0/IVirtualizerEffect.hal @@ -48,7 +48,7 @@ interface IVirtualizerEffect extends IEffect { struct SpeakerAngle { /** Speaker channel mask */ - bitfield mask; + vec mask; // all angles are expressed in degrees and // are relative to the listener. int16_t azimuth; // 0 is the direction the listener faces @@ -61,17 +61,17 @@ interface IVirtualizerEffect extends IEffect { * Retrieves virtual speaker angles for the given channel mask on the * specified device. */ - getVirtualSpeakerAngles(bitfield mask, AudioDevice device) + getVirtualSpeakerAngles(vec mask, DeviceAddress device) generates (Result retval, vec speakerAngles); /** * Forces the virtualizer effect for the given output device. */ - forceVirtualizationMode(AudioDevice device) generates (Result retval); + forceVirtualizationMode(DeviceAddress device) generates (Result retval); /** * Returns audio device reflecting the current virtualization mode, - * AUDIO_DEVICE_NONE when not virtualizing. + * Device type can be empty when not virtualizing. */ - getVirtualizationMode() generates (Result retval, AudioDevice device); + getVirtualizationMode() generates (Result retval, DeviceAddress device); }; diff --git a/audio/effect/7.0/types.hal b/audio/effect/7.0/types.hal index 7f5a38238f..fe4ee51584 100644 --- a/audio/effect/7.0/types.hal +++ b/audio/effect/7.0/types.hal @@ -257,7 +257,7 @@ enum EffectConfigParameters : int32_t { struct EffectBufferConfig { AudioBuffer buffer; uint32_t samplingRateHz; - bitfield channels; + AudioChannelMask channels; AudioFormat format; EffectBufferAccess accessMode; bitfield mask; @@ -276,8 +276,8 @@ enum EffectFeature : int32_t { }; struct EffectAuxChannelsConfig { - bitfield mainChannels; // channel mask for main channels - bitfield auxChannels; // channel mask for auxiliary channels + vec mainChannels; // channel mask for main channels + vec auxChannels; // channel mask for auxiliary channels }; struct EffectOffloadParameter { -- GitLab From d85edb7f66f542558583cd4893ee96a9d13ee913 Mon Sep 17 00:00:00 2001 From: Sunil Ravi Date: Sun, 16 Aug 2020 11:56:42 -0700 Subject: [PATCH 117/790] wifi: Added capability check in RTT tests Added test for 2 sided RTT. Added RTT measurement type capability check in range request tests. Bug: 163327074 Test: vts test - VtsHalWifiRttV1_4TargetTest Change-Id: I546806605b6b3ecd124068fc81b9fb275b745f45 --- .../wifi_rtt_controller_hidl_test.cpp | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/wifi/1.4/vts/functional/wifi_rtt_controller_hidl_test.cpp b/wifi/1.4/vts/functional/wifi_rtt_controller_hidl_test.cpp index 902b2f01f5..3977cdd857 100644 --- a/wifi/1.4/vts/functional/wifi_rtt_controller_hidl_test.cpp +++ b/wifi/1.4/vts/functional/wifi_rtt_controller_hidl_test.cpp @@ -147,6 +147,51 @@ TEST_P(WifiRttControllerHidlTest, RegisterEventCallback_1_4) { EXPECT_EQ(WifiStatusCode::SUCCESS, status.code); } +/* + * Request2SidedRangeMeasurement + * This test case tests the two sided ranging - 802.11mc FTM protocol. + */ +TEST_P(WifiRttControllerHidlTest, Request2SidedRangeMeasurement) { + std::pair status_and_caps; + + // Get the Capabilities + status_and_caps = HIDL_INVOKE(wifi_rtt_controller_, getCapabilities_1_4); + EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_caps.first.code); + if (!status_and_caps.second.rttFtmSupported) { + GTEST_SKIP() + << "Skipping two sided RTT since driver/fw doesn't support"; + } + std::vector configs; + RttConfig config; + int cmdId = 55; + // Set the config with test data + for (int i = 0; i < 6; i++) { + config.addr[i] = i; + } + config.type = RttType::TWO_SIDED; + config.peer = RttPeerType::AP; + config.channel.width = WifiChannelWidthInMhz::WIDTH_80; + config.channel.centerFreq = 5180; + config.channel.centerFreq0 = 5210; + config.channel.centerFreq1 = 0; + config.bw = RttBw::BW_20MHZ; + config.preamble = RttPreamble::HT; + config.mustRequestLci = false; + config.mustRequestLcr = false; + config.burstPeriod = 0; + config.numBurst = 0; + config.numFramesPerBurst = 8; + config.numRetriesPerRttFrame = 0; + config.numRetriesPerFtmr = 0; + config.burstDuration = 9; + // Insert config in the vector + configs.push_back(config); + + // Invoke the call + const auto& status = + HIDL_INVOKE(wifi_rtt_controller_, rangeRequest_1_4, cmdId, configs); + EXPECT_EQ(WifiStatusCode::SUCCESS, status.code); +} /* * rangeRequest_1_4 */ @@ -156,6 +201,10 @@ TEST_P(WifiRttControllerHidlTest, RangeRequest_1_4) { // Get the Capabilities status_and_caps = HIDL_INVOKE(wifi_rtt_controller_, getCapabilities_1_4); EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_caps.first.code); + if (!status_and_caps.second.rttOneSidedSupported) { + GTEST_SKIP() + << "Skipping one sided RTT since driver/fw doesn't support"; + } // Get the highest support preamble int preamble = 1; status_and_caps.second.preambleSupport >>= 1; -- GitLab From bfdb1ac6073448c7ea3998a837db3ce6f80777b4 Mon Sep 17 00:00:00 2001 From: Lakshman Annadorai Date: Thu, 6 Aug 2020 14:25:03 -0700 Subject: [PATCH 118/790] Update EmulatedUserHal to use UserHalHelper native library. Bug: 150409377 Test: Tested using lshal commands in go/user-hal-emulation. cherry pick from commit I79486a715c92111d3d6f5c011b7e1cd8c5501c25 Change-Id: I4ba2202e28ef9260b38ebbf21083d55d7aa07fc9 --- automotive/vehicle/2.0/default/Android.bp | 4 + .../impl/vhal_v2_0/EmulatedUserHal.cpp | 222 +++++++++--------- .../vehicle/2.0/utils/UserHalHelper.cpp | 35 +-- automotive/vehicle/2.0/utils/UserHalHelper.h | 5 + 4 files changed, 140 insertions(+), 126 deletions(-) diff --git a/automotive/vehicle/2.0/default/Android.bp b/automotive/vehicle/2.0/default/Android.bp index d9ac239f62..9a0d89d209 100644 --- a/automotive/vehicle/2.0/default/Android.bp +++ b/automotive/vehicle/2.0/default/Android.bp @@ -108,6 +108,9 @@ cc_library_static { srcs: [ "impl/vhal_v2_0/EmulatedUserHal.cpp", ], + whole_static_libs: [ + "android.hardware.automotive.vehicle@2.0-user-hal-helper-lib", + ], } // Vehicle HAL Server reference impl lib @@ -143,6 +146,7 @@ cc_library_static { ], whole_static_libs: [ "android.hardware.automotive.vehicle@2.0-server-common-lib", + "android.hardware.automotive.vehicle@2.0-user-hal-helper-lib", ], static_libs: [ "android.hardware.automotive.vehicle@2.0-libproto-native", diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedUserHal.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedUserHal.cpp index a5c2930a96..3bdf5a84a0 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedUserHal.cpp +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedUserHal.cpp @@ -15,10 +15,12 @@ */ #define LOG_TAG "EmulatedUserHal" +#include "EmulatedUserHal.h" + #include #include -#include "EmulatedUserHal.h" +#include "UserHalHelper.h" namespace android { namespace hardware { @@ -28,12 +30,35 @@ namespace V2_0 { namespace impl { -constexpr int INITIAL_USER_INFO = static_cast(VehicleProperty::INITIAL_USER_INFO); -constexpr int SWITCH_USER = static_cast(VehicleProperty::SWITCH_USER); -constexpr int CREATE_USER = static_cast(VehicleProperty::CREATE_USER); -constexpr int REMOVE_USER = static_cast(VehicleProperty::REMOVE_USER); -constexpr int USER_IDENTIFICATION_ASSOCIATION = - static_cast(VehicleProperty::USER_IDENTIFICATION_ASSOCIATION); +namespace { + +using android::base::Error; +using android::base::Result; + +constexpr int32_t INITIAL_USER_INFO = static_cast(VehicleProperty::INITIAL_USER_INFO); +constexpr int32_t SWITCH_USER = static_cast(VehicleProperty::SWITCH_USER); +constexpr int32_t CREATE_USER = static_cast(VehicleProperty::CREATE_USER); +constexpr int32_t REMOVE_USER = static_cast(VehicleProperty::REMOVE_USER); +constexpr int32_t USER_IDENTIFICATION_ASSOCIATION = + static_cast(VehicleProperty::USER_IDENTIFICATION_ASSOCIATION); + +Result getRequestId(const VehiclePropValue& value) { + if (value.value.int32Values.size() < 1) { + return Error(static_cast(StatusCode::INVALID_ARG)) + << "no int32values on " << toString(value); + } + return value.value.int32Values[0]; +} + +Result getSwitchUserMessageType(const VehiclePropValue& value) { + if (value.value.int32Values.size() < 2) { + return Error(static_cast(StatusCode::INVALID_ARG)) + << "missing switch user message type " << toString(value); + } + return user_hal_helper::verifyAndCast(value.value.int32Values[1]); +} + +} // namespace bool EmulatedUserHal::isSupported(int32_t prop) { switch (prop) { @@ -48,7 +73,7 @@ bool EmulatedUserHal::isSupported(int32_t prop) { } } -android::base::Result> EmulatedUserHal::onSetProperty( +Result> EmulatedUserHal::onSetProperty( const VehiclePropValue& value) { ALOGV("onSetProperty(): %s", toString(value).c_str()); @@ -65,12 +90,12 @@ android::base::Result> EmulatedUserHal::onSetP case USER_IDENTIFICATION_ASSOCIATION: return onSetUserIdentificationAssociation(value); default: - return android::base::Error((int)StatusCode::INVALID_ARG) + return Error(static_cast(StatusCode::INVALID_ARG)) << "Unsupported property: " << toString(value); } } -android::base::Result> EmulatedUserHal::onGetProperty( +Result> EmulatedUserHal::onGetProperty( const VehiclePropValue& value) { ALOGV("onGetProperty(%s)", toString(value).c_str()); switch (value.prop) { @@ -79,42 +104,41 @@ android::base::Result> EmulatedUserHal::onGetP case CREATE_USER: case REMOVE_USER: ALOGE("onGetProperty(): %d is only supported on SET", value.prop); - return android::base::Error(static_cast(StatusCode::INVALID_ARG)) - << "only supported on SET"; + return Error(static_cast(StatusCode::INVALID_ARG)) << "only supported on SET"; case USER_IDENTIFICATION_ASSOCIATION: return onGetUserIdentificationAssociation(value); default: ALOGE("onGetProperty(): %d is not supported", value.prop); - return android::base::Error(static_cast(StatusCode::INVALID_ARG)) - << "not supported by User HAL"; + return Error(static_cast(StatusCode::INVALID_ARG)) << "not supported by User HAL"; } } -android::base::Result> -EmulatedUserHal::onGetUserIdentificationAssociation(const VehiclePropValue& value) { - if (mSetUserIdentificationAssociationResponseFromCmd != nullptr) { - ALOGI("get(USER_IDENTIFICATION_ASSOCIATION): returning %s", - toString(*mSetUserIdentificationAssociationResponseFromCmd).c_str()); - auto newValue = std::unique_ptr( - new VehiclePropValue(*mSetUserIdentificationAssociationResponseFromCmd)); +Result> EmulatedUserHal::onGetUserIdentificationAssociation( + const VehiclePropValue& value) { + if (mSetUserIdentificationAssociationResponseFromCmd == nullptr) { + return defaultUserIdentificationAssociation(value); + } + ALOGI("get(USER_IDENTIFICATION_ASSOCIATION): returning %s", + toString(*mSetUserIdentificationAssociationResponseFromCmd).c_str()); + auto newValue = std::unique_ptr( + new VehiclePropValue(*mSetUserIdentificationAssociationResponseFromCmd)); + auto requestId = getRequestId(value); + if (requestId.ok()) { // Must use the same requestId - if (value.value.int32Values.size() > 0) { - newValue->value.int32Values[0] = value.value.int32Values[0]; - } else { - ALOGE("get(USER_IDENTIFICATION_ASSOCIATION): no requestId on %s", - toString(value).c_str()); - } - return newValue; + newValue->value.int32Values[0] = *requestId; + } else { + ALOGE("get(USER_IDENTIFICATION_ASSOCIATION): no requestId on %s", toString(value).c_str()); } - return defaultUserIdentificationAssociation(value); + return newValue; } -android::base::Result> -EmulatedUserHal::onSetInitialUserInfoResponse(const VehiclePropValue& value) { - if (value.value.int32Values.size() == 0) { - ALOGE("set(INITIAL_USER_INFO): no int32values, ignoring it: %s", toString(value).c_str()); - return android::base::Error((int)StatusCode::INVALID_ARG) - << "no int32values on " << toString(value); +Result> EmulatedUserHal::onSetInitialUserInfoResponse( + const VehiclePropValue& value) { + auto requestId = getRequestId(value); + if (!requestId.ok()) { + ALOGE("Failed to get requestId on set(INITIAL_USER_INFO): %s", + requestId.error().message().c_str()); + return requestId.error(); } if (value.areaId != 0) { @@ -124,40 +148,40 @@ EmulatedUserHal::onSetInitialUserInfoResponse(const VehiclePropValue& value) { } ALOGD("set(INITIAL_USER_INFO) called from Android: %s", toString(value).c_str()); - - int32_t requestId = value.value.int32Values[0]; if (mInitialUserResponseFromCmd != nullptr) { ALOGI("replying INITIAL_USER_INFO with lshal value: %s", toString(*mInitialUserResponseFromCmd).c_str()); - return sendUserHalResponse(std::move(mInitialUserResponseFromCmd), requestId); + return sendUserHalResponse(std::move(mInitialUserResponseFromCmd), *requestId); } // Returns default response - auto updatedValue = std::unique_ptr(new VehiclePropValue); - updatedValue->prop = INITIAL_USER_INFO; - updatedValue->timestamp = elapsedRealtimeNano(); - updatedValue->value.int32Values.resize(2); - updatedValue->value.int32Values[0] = requestId; - updatedValue->value.int32Values[1] = (int32_t)InitialUserInfoResponseAction::DEFAULT; - + auto updatedValue = user_hal_helper::toVehiclePropValue(InitialUserInfoResponse{ + .requestId = *requestId, + .action = InitialUserInfoResponseAction::DEFAULT, + }); ALOGI("no lshal response; replying with InitialUserInfoResponseAction::DEFAULT: %s", toString(*updatedValue).c_str()); - return updatedValue; } -android::base::Result> EmulatedUserHal::onSetSwitchUserResponse( +Result> EmulatedUserHal::onSetSwitchUserResponse( const VehiclePropValue& value) { - if (value.value.int32Values.size() == 0) { - ALOGE("set(SWITCH_USER): no int32values, ignoring it: %s", toString(value).c_str()); - return android::base::Error((int)StatusCode::INVALID_ARG) - << "no int32values on " << toString(value); + auto requestId = getRequestId(value); + if (!requestId.ok()) { + ALOGE("Failed to get requestId on set(SWITCH_USER): %s", + requestId.error().message().c_str()); + return requestId.error(); + } + + auto messageType = getSwitchUserMessageType(value); + if (!messageType.ok()) { + ALOGE("Failed to get messageType on set(SWITCH_USER): %s", + messageType.error().message().c_str()); + return messageType.error(); } if (value.areaId != 0) { - if (value.value.int32Values.size() >= 2 && - static_cast(value.value.int32Values[1]) == - SwitchUserMessageType::VEHICLE_REQUEST) { + if (*messageType == SwitchUserMessageType::VEHICLE_REQUEST) { // User HAL can also request a user switch, so we need to check it first ALOGD("set(SWITCH_USER) called from lshal to emulate a vehicle request: %s", toString(value).c_str()); @@ -170,48 +194,36 @@ android::base::Result> EmulatedUserHal::onSetS } ALOGD("set(SWITCH_USER) called from Android: %s", toString(value).c_str()); - int32_t requestId = value.value.int32Values[0]; if (mSwitchUserResponseFromCmd != nullptr) { ALOGI("replying SWITCH_USER with lshal value: %s", toString(*mSwitchUserResponseFromCmd).c_str()); - return sendUserHalResponse(std::move(mSwitchUserResponseFromCmd), requestId); + return sendUserHalResponse(std::move(mSwitchUserResponseFromCmd), *requestId); } - if (value.value.int32Values.size() > 1) { - auto messageType = static_cast(value.value.int32Values[1]); - switch (messageType) { - case SwitchUserMessageType::LEGACY_ANDROID_SWITCH: - ALOGI("request is LEGACY_ANDROID_SWITCH; ignoring it"); - return {}; - case SwitchUserMessageType::ANDROID_POST_SWITCH: - ALOGI("request is ANDROID_POST_SWITCH; ignoring it"); - return {}; - default: - break; - } + if (*messageType == SwitchUserMessageType::LEGACY_ANDROID_SWITCH || + *messageType == SwitchUserMessageType::ANDROID_POST_SWITCH) { + ALOGI("request is %s; ignoring it", toString(*messageType).c_str()); + return {}; } // Returns default response - auto updatedValue = std::unique_ptr(new VehiclePropValue); - updatedValue->prop = SWITCH_USER; - updatedValue->timestamp = elapsedRealtimeNano(); - updatedValue->value.int32Values.resize(3); - updatedValue->value.int32Values[0] = requestId; - updatedValue->value.int32Values[1] = (int32_t)SwitchUserMessageType::VEHICLE_RESPONSE; - updatedValue->value.int32Values[2] = (int32_t)SwitchUserStatus::SUCCESS; - + auto updatedValue = user_hal_helper::toVehiclePropValue(SwitchUserResponse{ + .requestId = *requestId, + .messageType = SwitchUserMessageType::VEHICLE_RESPONSE, + .status = SwitchUserStatus::SUCCESS, + }); ALOGI("no lshal response; replying with VEHICLE_RESPONSE / SUCCESS: %s", toString(*updatedValue).c_str()); - return updatedValue; } -android::base::Result> EmulatedUserHal::onSetCreateUserResponse( +Result> EmulatedUserHal::onSetCreateUserResponse( const VehiclePropValue& value) { - if (value.value.int32Values.size() == 0) { - ALOGE("set(CREATE_USER): no int32values, ignoring it: %s", toString(value).c_str()); - return android::base::Error(static_cast(StatusCode::INVALID_ARG)) - << "no int32values on " << toString(value); + auto requestId = getRequestId(value); + if (!requestId.ok()) { + ALOGE("Failed to get requestId on set(CREATE_USER): %s", + requestId.error().message().c_str()); + return requestId.error(); } if (value.areaId != 0) { @@ -221,33 +233,28 @@ android::base::Result> EmulatedUserHal::onSetC } ALOGD("set(CREATE_USER) called from Android: %s", toString(value).c_str()); - int32_t requestId = value.value.int32Values[0]; if (mCreateUserResponseFromCmd != nullptr) { ALOGI("replying CREATE_USER with lshal value: %s", toString(*mCreateUserResponseFromCmd).c_str()); - return sendUserHalResponse(std::move(mCreateUserResponseFromCmd), requestId); + return sendUserHalResponse(std::move(mCreateUserResponseFromCmd), *requestId); } // Returns default response - auto updatedValue = std::unique_ptr(new VehiclePropValue); - updatedValue->prop = CREATE_USER; - updatedValue->timestamp = elapsedRealtimeNano(); - updatedValue->value.int32Values.resize(2); - updatedValue->value.int32Values[0] = requestId; - updatedValue->value.int32Values[1] = (int32_t)CreateUserStatus::SUCCESS; - + auto updatedValue = user_hal_helper::toVehiclePropValue(CreateUserResponse{ + .requestId = *requestId, + .status = CreateUserStatus::SUCCESS, + }); ALOGI("no lshal response; replying with SUCCESS: %s", toString(*updatedValue).c_str()); - return updatedValue; } -android::base::Result> -EmulatedUserHal::onSetUserIdentificationAssociation(const VehiclePropValue& value) { - if (value.value.int32Values.size() == 0) { - ALOGE("set(USER_IDENTIFICATION_ASSOCIATION): no int32values, ignoring it: %s", - toString(value).c_str()); - return android::base::Error(static_cast(StatusCode::INVALID_ARG)) - << "no int32values on " << toString(value); +Result> EmulatedUserHal::onSetUserIdentificationAssociation( + const VehiclePropValue& value) { + auto requestId = getRequestId(value); + if (!requestId.ok()) { + ALOGE("Failed to get requestId on set(USER_IDENTIFICATION_ASSOCIATION): %s", + requestId.error().message().c_str()); + return requestId.error(); } if (value.areaId != 0) { @@ -258,28 +265,26 @@ EmulatedUserHal::onSetUserIdentificationAssociation(const VehiclePropValue& valu } ALOGD("set(USER_IDENTIFICATION_ASSOCIATION) called from Android: %s", toString(value).c_str()); - int32_t requestId = value.value.int32Values[0]; if (mSetUserIdentificationAssociationResponseFromCmd != nullptr) { ALOGI("replying USER_IDENTIFICATION_ASSOCIATION with lshal value: %s", toString(*mSetUserIdentificationAssociationResponseFromCmd).c_str()); // Not moving response so it can be used on GET requests auto copy = std::unique_ptr( new VehiclePropValue(*mSetUserIdentificationAssociationResponseFromCmd)); - return sendUserHalResponse(std::move(copy), requestId); + return sendUserHalResponse(std::move(copy), *requestId); } - // Returns default response return defaultUserIdentificationAssociation(value); } -android::base::Result> -EmulatedUserHal::defaultUserIdentificationAssociation(const VehiclePropValue& request) { +Result> EmulatedUserHal::defaultUserIdentificationAssociation( + const VehiclePropValue& request) { // TODO(b/159498909): return a response with NOT_ASSOCIATED_ANY_USER for all requested types ALOGE("no lshal response for %s; replying with NOT_AVAILABLE", toString(request).c_str()); - return android::base::Error(static_cast(StatusCode::NOT_AVAILABLE)) << "not set by lshal"; + return Error(static_cast(StatusCode::NOT_AVAILABLE)) << "not set by lshal"; } -android::base::Result> EmulatedUserHal::sendUserHalResponse( +Result> EmulatedUserHal::sendUserHalResponse( std::unique_ptr response, int32_t requestId) { switch (response->areaId) { case 1: @@ -293,17 +298,16 @@ android::base::Result> EmulatedUserHal::sendUs case 3: ALOGD("not generating a property change event because of lshal prop: %s", toString(*response).c_str()); - return android::base::Error((int)StatusCode::NOT_AVAILABLE) + return Error(static_cast(StatusCode::NOT_AVAILABLE)) << "not generating a property change event because of lshal prop: " << toString(*response); default: ALOGE("invalid action on lshal response: %s", toString(*response).c_str()); - return android::base::Error((int)StatusCode::INTERNAL_ERROR) + return Error(static_cast(StatusCode::INTERNAL_ERROR)) << "invalid action on lshal response: " << toString(*response); } ALOGD("updating property to: %s", toString(*response).c_str()); - return response; } diff --git a/automotive/vehicle/2.0/utils/UserHalHelper.cpp b/automotive/vehicle/2.0/utils/UserHalHelper.cpp index 33b39482da..fcfe4bf17f 100644 --- a/automotive/vehicle/2.0/utils/UserHalHelper.cpp +++ b/automotive/vehicle/2.0/utils/UserHalHelper.cpp @@ -36,22 +36,6 @@ static constexpr const char* kSeparator = "||"; static const size_t kNumFieldsPerUserInfo = 2; static const size_t kNumFieldsPerSetAssociation = 2; -template -Result verifyAndCast(int32_t value) { - T castValue = static_cast(value); - const auto iter = hidl_enum_range(); - if (castValue < *iter.begin() || castValue > *std::prev(iter.end())) { - return Error() << "Value " << value << " not in range [" << toString(*iter.begin()) << ", " - << toString(*std::prev(iter.end())) << "]"; - } - for (const auto& v : hidl_enum_range()) { - if (castValue == v) { - return castValue; - } - } - return Error() << "Value " << value << " not in enum values"; -} - Result verifyPropValue(const VehiclePropValue& propValue, VehicleProperty vehicleProperty, size_t minInt32Values) { auto prop = verifyAndCast(propValue.prop); @@ -154,6 +138,22 @@ Result parseUserAssociations(const hidl_vec& int32Values, size_t } // namespace +template +Result verifyAndCast(int32_t value) { + T castValue = static_cast(value); + const auto iter = hidl_enum_range(); + if (castValue < *iter.begin() || castValue > *std::prev(iter.end())) { + return Error() << "Value " << value << " not in range [" << toString(*iter.begin()) << ", " + << toString(*std::prev(iter.end())) << "]"; + } + for (const auto& v : hidl_enum_range()) { + if (castValue == v) { + return castValue; + } + } + return Error() << "Value " << value << " not in enum values"; +} + Result toInitialUserInfoRequest(const VehiclePropValue& propValue) { auto ret = verifyPropValue(propValue, VehicleProperty::INITIAL_USER_INFO, 2); if (!ret.ok()) { @@ -186,7 +186,8 @@ Result toSwitchUserRequest(const VehiclePropValue& propValue) if (*messageType != SwitchUserMessageType::LEGACY_ANDROID_SWITCH && *messageType != SwitchUserMessageType::ANDROID_SWITCH && *messageType != SwitchUserMessageType::ANDROID_POST_SWITCH) { - return Error() << "Invalid " << toString(*messageType) << " from Android System"; + return Error() << "Invalid " << toString(*messageType) + << " message type from Android System"; } request.requestId = propValue.value.int32Values[0]; request.messageType = *messageType; diff --git a/automotive/vehicle/2.0/utils/UserHalHelper.h b/automotive/vehicle/2.0/utils/UserHalHelper.h index bee34cf0f6..fad71451aa 100644 --- a/automotive/vehicle/2.0/utils/UserHalHelper.h +++ b/automotive/vehicle/2.0/utils/UserHalHelper.h @@ -31,6 +31,11 @@ namespace V2_0 { namespace user_hal_helper { +// Verify whether the |value| can be casted to the type |T| and return the casted value on success. +// Otherwise, return the error. +template +android::base::Result verifyAndCast(int32_t value); + // Below functions parse VehiclePropValues to the respective User HAL request structs. On success, // these functions return the User HAL struct. Otherwise, they return the error. android::base::Result toInitialUserInfoRequest( -- GitLab From 4ee510ca5b8ed9d53b4db5ca66ab93b7d9597919 Mon Sep 17 00:00:00 2001 From: Ankit Goyal Date: Wed, 19 Aug 2020 15:59:09 +0800 Subject: [PATCH 119/790] Allow gtest to instantiate no tests without failures Fix: 162211705 Test: atest VtsHalGraphicsMapperV4_0TargetTest (before and after change) Change-Id: I8cf7f6bf82f939040f59043b00515e66a4b8ce68 --- .../2.1/vts/functional/VtsHalGraphicsMapperV2_1TargetTest.cpp | 3 ++- .../3.0/vts/functional/VtsHalGraphicsMapperV3_0TargetTest.cpp | 1 + .../4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/graphics/mapper/2.1/vts/functional/VtsHalGraphicsMapperV2_1TargetTest.cpp b/graphics/mapper/2.1/vts/functional/VtsHalGraphicsMapperV2_1TargetTest.cpp index 3d792f9f8e..9f927e59f6 100644 --- a/graphics/mapper/2.1/vts/functional/VtsHalGraphicsMapperV2_1TargetTest.cpp +++ b/graphics/mapper/2.1/vts/functional/VtsHalGraphicsMapperV2_1TargetTest.cpp @@ -204,6 +204,7 @@ TEST_P(GraphicsMapperHidlTest, CreateDescriptor_2_1Negative) { }); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsMapperHidlTest); INSTANTIATE_TEST_CASE_P( PerInstance, GraphicsMapperHidlTest, testing::Combine( @@ -218,4 +219,4 @@ INSTANTIATE_TEST_CASE_P( } // namespace mapper } // namespace graphics } // namespace hardware -} // namespace android \ No newline at end of file +} // namespace android diff --git a/graphics/mapper/3.0/vts/functional/VtsHalGraphicsMapperV3_0TargetTest.cpp b/graphics/mapper/3.0/vts/functional/VtsHalGraphicsMapperV3_0TargetTest.cpp index 92b5994eed..4187dd1354 100644 --- a/graphics/mapper/3.0/vts/functional/VtsHalGraphicsMapperV3_0TargetTest.cpp +++ b/graphics/mapper/3.0/vts/functional/VtsHalGraphicsMapperV3_0TargetTest.cpp @@ -458,6 +458,7 @@ TEST_P(GraphicsMapperHidlTest, IsSupportedY16) { ASSERT_NO_FATAL_FAILURE(supported = mGralloc->isSupported(info)); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsMapperHidlTest); INSTANTIATE_TEST_CASE_P( PerInstance, GraphicsMapperHidlTest, testing::Combine( diff --git a/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp b/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp index bb775dc689..f55a6b77ed 100644 --- a/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp +++ b/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp @@ -2592,6 +2592,7 @@ TEST_P(GraphicsMapperHidlTest, GetReservedRegionBadBuffer) { ASSERT_EQ(0, reservedSize); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsMapperHidlTest); INSTANTIATE_TEST_CASE_P( PerInstance, GraphicsMapperHidlTest, testing::Combine( -- GitLab From ea68502f12bd2350698e1b0554de4258aea3e52e Mon Sep 17 00:00:00 2001 From: Benjamin Schwartz Date: Thu, 30 Jul 2020 16:20:55 -0700 Subject: [PATCH 120/790] Create Power Stats AIDL interface Bug: 162472196 Test: m Change-Id: I225135c24cc713da085ff7238c1b0695e8ab93ed --- .../compatibility_matrix.current.xml | 5 +- powerstats/aidl/Android.bp | 35 +++++++ .../hardware/powerstats/EnergyData.aidl | 24 +++++ .../hardware/powerstats/IPowerStats.aidl | 31 ++++++ .../hardware/powerstats/PowerEntityInfo.aidl | 24 +++++ .../powerstats/PowerEntityStateInfo.aidl | 23 +++++ .../PowerEntityStateResidencyData.aidl | 25 +++++ .../PowerEntityStateResidencyResult.aidl | 23 +++++ .../powerstats/PowerEntityStateSpace.aidl | 23 +++++ .../hardware/powerstats/PowerEntityType.aidl | 24 +++++ .../android/hardware/powerstats/RailInfo.aidl | 25 +++++ .../hardware/powerstats/EnergyData.aidl | 35 +++++++ .../hardware/powerstats/IPowerStats.aidl | 96 +++++++++++++++++++ .../hardware/powerstats/PowerEntityInfo.aidl | 39 ++++++++ .../powerstats/PowerEntityStateInfo.aidl | 30 ++++++ .../PowerEntityStateResidencyData.aidl | 44 +++++++++ .../PowerEntityStateResidencyResult.aidl | 32 +++++++ .../powerstats/PowerEntityStateSpace.aidl | 37 +++++++ .../hardware/powerstats/PowerEntityType.aidl | 37 +++++++ .../android/hardware/powerstats/RailInfo.aidl | 38 ++++++++ powerstats/aidl/default/Android.bp | 30 ++++++ powerstats/aidl/default/PowerStats.cpp | 59 ++++++++++++ powerstats/aidl/default/PowerStats.h | 44 +++++++++ powerstats/aidl/default/main.cpp | 35 +++++++ powerstats/aidl/default/powerstats-default.rc | 4 + .../aidl/default/powerstats-default.xml | 6 ++ 26 files changed, 825 insertions(+), 3 deletions(-) create mode 100644 powerstats/aidl/Android.bp create mode 100644 powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/EnergyData.aidl create mode 100644 powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/IPowerStats.aidl create mode 100644 powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityInfo.aidl create mode 100644 powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityStateInfo.aidl create mode 100644 powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityStateResidencyData.aidl create mode 100644 powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityStateResidencyResult.aidl create mode 100644 powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityStateSpace.aidl create mode 100644 powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityType.aidl create mode 100644 powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/RailInfo.aidl create mode 100644 powerstats/aidl/android/hardware/powerstats/EnergyData.aidl create mode 100644 powerstats/aidl/android/hardware/powerstats/IPowerStats.aidl create mode 100644 powerstats/aidl/android/hardware/powerstats/PowerEntityInfo.aidl create mode 100644 powerstats/aidl/android/hardware/powerstats/PowerEntityStateInfo.aidl create mode 100644 powerstats/aidl/android/hardware/powerstats/PowerEntityStateResidencyData.aidl create mode 100644 powerstats/aidl/android/hardware/powerstats/PowerEntityStateResidencyResult.aidl create mode 100644 powerstats/aidl/android/hardware/powerstats/PowerEntityStateSpace.aidl create mode 100644 powerstats/aidl/android/hardware/powerstats/PowerEntityType.aidl create mode 100644 powerstats/aidl/android/hardware/powerstats/RailInfo.aidl create mode 100644 powerstats/aidl/default/Android.bp create mode 100644 powerstats/aidl/default/PowerStats.cpp create mode 100644 powerstats/aidl/default/PowerStats.h create mode 100644 powerstats/aidl/default/main.cpp create mode 100644 powerstats/aidl/default/powerstats-default.rc create mode 100644 powerstats/aidl/default/powerstats-default.xml diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index 44fbc645ae..089c89aa97 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -362,9 +362,8 @@ default - - android.hardware.power.stats - 1.0 + + android.hardware.powerstats IPowerStats default diff --git a/powerstats/aidl/Android.bp b/powerstats/aidl/Android.bp new file mode 100644 index 0000000000..1aa58cb063 --- /dev/null +++ b/powerstats/aidl/Android.bp @@ -0,0 +1,35 @@ +// 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. + +aidl_interface { + name: "android.hardware.powerstats", + vendor_available: true, + srcs: [ + "android/hardware/powerstats/*.aidl", + ], + stability: "vintf", + backend: { + java: { + platform_apis: true, + }, + ndk: { + vndk: { + enabled: true, + }, + }, + cpp: { + enabled: false, + }, + }, +} diff --git a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/EnergyData.aidl b/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/EnergyData.aidl new file mode 100644 index 0000000000..2e384da5ca --- /dev/null +++ b/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/EnergyData.aidl @@ -0,0 +1,24 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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.powerstats; +@VintfStability +parcelable EnergyData { + int railIndex; + long timestampMs; + long energyUWs; +} diff --git a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/IPowerStats.aidl b/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/IPowerStats.aidl new file mode 100644 index 0000000000..b13f0c7c97 --- /dev/null +++ b/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/IPowerStats.aidl @@ -0,0 +1,31 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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.powerstats; +@VintfStability +interface IPowerStats { + android.hardware.powerstats.EnergyData[] getEnergyData(in int[] railIndices); + android.hardware.powerstats.PowerEntityInfo[] getPowerEntityInfo(); + android.hardware.powerstats.PowerEntityStateSpace[] getPowerEntityStateInfo(in int[] powerEntityIds); + android.hardware.powerstats.PowerEntityStateResidencyResult[] getPowerEntityStateResidencyData(in int[] powerEntityIds); + android.hardware.powerstats.RailInfo[] getRailInfo(); + const int SUCCESS = 0; + const int NOT_SUPPORTED = 1; + const int INVALID_INPUT = 2; + const int FILESYSTEM_ERROR = 3; + const int INSUFFICIENT_RESOURCES = 4; +} diff --git a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityInfo.aidl b/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityInfo.aidl new file mode 100644 index 0000000000..8cacd55b0a --- /dev/null +++ b/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityInfo.aidl @@ -0,0 +1,24 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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.powerstats; +@VintfStability +parcelable PowerEntityInfo { + int powerEntityId; + String powerEntityName; + android.hardware.powerstats.PowerEntityType type; +} diff --git a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityStateInfo.aidl b/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityStateInfo.aidl new file mode 100644 index 0000000000..9de66ba8bc --- /dev/null +++ b/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityStateInfo.aidl @@ -0,0 +1,23 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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.powerstats; +@VintfStability +parcelable PowerEntityStateInfo { + int powerEntityStateId; + String powerEntityStateName; +} diff --git a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityStateResidencyData.aidl b/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityStateResidencyData.aidl new file mode 100644 index 0000000000..8a3b227ed6 --- /dev/null +++ b/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityStateResidencyData.aidl @@ -0,0 +1,25 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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.powerstats; +@VintfStability +parcelable PowerEntityStateResidencyData { + int powerEntityStateId; + long totalTimeInStateMs; + long totalStateEntryCount; + long lastEntryTimestampMs; +} diff --git a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityStateResidencyResult.aidl b/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityStateResidencyResult.aidl new file mode 100644 index 0000000000..fbe567ea83 --- /dev/null +++ b/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityStateResidencyResult.aidl @@ -0,0 +1,23 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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.powerstats; +@VintfStability +parcelable PowerEntityStateResidencyResult { + int powerEntityId; + android.hardware.powerstats.PowerEntityStateResidencyData[] stateResidencyData; +} diff --git a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityStateSpace.aidl b/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityStateSpace.aidl new file mode 100644 index 0000000000..0508fea7e0 --- /dev/null +++ b/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityStateSpace.aidl @@ -0,0 +1,23 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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.powerstats; +@VintfStability +parcelable PowerEntityStateSpace { + int powerEntityId; + android.hardware.powerstats.PowerEntityStateInfo[] states; +} diff --git a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityType.aidl b/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityType.aidl new file mode 100644 index 0000000000..5deefa9dd8 --- /dev/null +++ b/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityType.aidl @@ -0,0 +1,24 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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.powerstats; +@Backing(type="int") @VintfStability +enum PowerEntityType { + SUBSYSTEM = 0, + PERIPHERAL = 1, + POWER_DOMAIN = 2, +} diff --git a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/RailInfo.aidl b/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/RailInfo.aidl new file mode 100644 index 0000000000..413ea0dd80 --- /dev/null +++ b/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/RailInfo.aidl @@ -0,0 +1,25 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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.powerstats; +@VintfStability +parcelable RailInfo { + int railIndex; + String railName; + String subsysName; + int samplingRateHz; +} diff --git a/powerstats/aidl/android/hardware/powerstats/EnergyData.aidl b/powerstats/aidl/android/hardware/powerstats/EnergyData.aidl new file mode 100644 index 0000000000..ec12c5e0b2 --- /dev/null +++ b/powerstats/aidl/android/hardware/powerstats/EnergyData.aidl @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.powerstats; + +@VintfStability +parcelable EnergyData { + /** + * Index corresponding to the rail. This index matches + * the index returned in RailInfo + */ + int railIndex; + /** + * Time since device boot(CLOCK_BOOTTIME) in milli-seconds + */ + long timestampMs; + /** + * Accumulated energy since device boot in microwatt-seconds (uWs) + */ + long energyUWs; +} + diff --git a/powerstats/aidl/android/hardware/powerstats/IPowerStats.aidl b/powerstats/aidl/android/hardware/powerstats/IPowerStats.aidl new file mode 100644 index 0000000000..f8f69e0b5f --- /dev/null +++ b/powerstats/aidl/android/hardware/powerstats/IPowerStats.aidl @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.powerstats; + +import android.hardware.powerstats.EnergyData; +import android.hardware.powerstats.PowerEntityInfo; +import android.hardware.powerstats.PowerEntityStateResidencyResult; +import android.hardware.powerstats.PowerEntityStateSpace; +import android.hardware.powerstats.RailInfo; + +@VintfStability +interface IPowerStats { + const int SUCCESS = 0; + const int NOT_SUPPORTED = 1; + const int INVALID_INPUT = 2; + const int FILESYSTEM_ERROR = 3; + const int INSUFFICIENT_RESOURCES = 4; + + /** + * Rail level energy measurements for low frequency clients: + * Reports accumulated energy since boot on each rail. + * + * @param railIndices Indices of rails for which data is required. + * To get data for all rails pass an empty vector. Rail name to + * index mapping can be queried from getRailInfo() API. + * @return Energy values since boot for all requested rails. + */ + EnergyData[] getEnergyData(in int[] railIndices); + + /** + * PowerEntity information: + * Reports information related to all supported PowerEntity(s) for which + * data is available. A PowerEntity is defined as a platform subsystem, + * peripheral, or power domain that impacts the total device power + * consumption. + * + * @return List of information on each PowerEntity + */ + PowerEntityInfo[] getPowerEntityInfo(); + + /** + * PowerEntity state information: + * Reports the set of power states for which the specified + * PowerEntity(s) provide residency data. + * + * @param powerEntityIds collection of IDs of PowerEntity(s) for which + * state information is requested. PowerEntity name to ID mapping may + * be queried from getPowerEntityInfo(). To get state space + * information for all PowerEntity(s) pass an empty vector. + * + * @return PowerEntity state space information for + * each specified PowerEntity that provides state space information. + */ + PowerEntityStateSpace[] getPowerEntityStateInfo(in int[] powerEntityIds); + + /** + * PowerEntity residencies for low frequency clients: + * Reports accumulated residency data for each specified PowerEntity. + * Each PowerEntity may reside in one of multiple states. It may also + * transition to another state. Residency data is an accumulation of time + * that a specified PowerEntity resided in each of its possible states, + * the number of times that each state was entered, and a timestamp + * corresponding to the last time that state was entered. Data is + * accumulated starting from the last time the PowerEntity was reset. + * + * @param powerEntityId collection of IDs of PowerEntity(s) for which + * residency data is requested. PowerEntity name to ID mapping may + * be queried from getPowerEntityInfo(). To get state residency + * data for all PowerEntity(s) pass an empty vector. + * @return state residency data for each specified + * PowerEntity that provides state residency data. + */ + PowerEntityStateResidencyResult[] getPowerEntityStateResidencyData(in int[] powerEntityIds); + + /** + * Rail information: + * Reports information related to the rails being monitored. + * + * @return Information about monitored rails. + */ + RailInfo[] getRailInfo(); +} \ No newline at end of file diff --git a/powerstats/aidl/android/hardware/powerstats/PowerEntityInfo.aidl b/powerstats/aidl/android/hardware/powerstats/PowerEntityInfo.aidl new file mode 100644 index 0000000000..2b5b352673 --- /dev/null +++ b/powerstats/aidl/android/hardware/powerstats/PowerEntityInfo.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.powerstats; + +import android.hardware.powerstats.PowerEntityType; + +/** + * PowerEntityInfo contains information, such as the ID, name, and type of a + * given PowerEntity. + */ +@VintfStability +parcelable PowerEntityInfo { + /** + * Unique ID corresponding to the PowerEntity + */ + int powerEntityId; + /** + * Name of the PowerEntity (opaque to the framework) + */ + String powerEntityName; + /** + * Type of the PowerEntity + */ + PowerEntityType type; +} \ No newline at end of file diff --git a/powerstats/aidl/android/hardware/powerstats/PowerEntityStateInfo.aidl b/powerstats/aidl/android/hardware/powerstats/PowerEntityStateInfo.aidl new file mode 100644 index 0000000000..69fc79828d --- /dev/null +++ b/powerstats/aidl/android/hardware/powerstats/PowerEntityStateInfo.aidl @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.powerstats; + +@VintfStability +parcelable PowerEntityStateInfo { + /** + * ID corresponding to the state. Unique for a given PowerEntityStateSpace + */ + int powerEntityStateId; + /** + * Name of the state (opaque to the framework) + */ + String powerEntityStateName; +} + diff --git a/powerstats/aidl/android/hardware/powerstats/PowerEntityStateResidencyData.aidl b/powerstats/aidl/android/hardware/powerstats/PowerEntityStateResidencyData.aidl new file mode 100644 index 0000000000..a738457fe9 --- /dev/null +++ b/powerstats/aidl/android/hardware/powerstats/PowerEntityStateResidencyData.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. + */ + +package android.hardware.powerstats; + +/** + * Contains residency data for a single state + */ +@VintfStability +parcelable PowerEntityStateResidencyData { + /** + * Unique ID of the corresponding PowerEntityStateInfo + */ + int powerEntityStateId; + /** + * Total time in milliseconds that the corresponding PowerEntity resided + * in this state since the PowerEntity was reset + */ + long totalTimeInStateMs; + /** + * Total number of times that the state was entered since the corresponding + * PowerEntity was reset + */ + long totalStateEntryCount; + /** + * Last time this state was entered. Time in milliseconds since the + * corresponding PowerEntity was reset + */ + long lastEntryTimestampMs; +} + diff --git a/powerstats/aidl/android/hardware/powerstats/PowerEntityStateResidencyResult.aidl b/powerstats/aidl/android/hardware/powerstats/PowerEntityStateResidencyResult.aidl new file mode 100644 index 0000000000..555ae4c78e --- /dev/null +++ b/powerstats/aidl/android/hardware/powerstats/PowerEntityStateResidencyResult.aidl @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.powerstats; + +import android.hardware.powerstats.PowerEntityStateResidencyData; + +@VintfStability +parcelable PowerEntityStateResidencyResult { + /** + * Unique ID of the corresponding PowerEntity + */ + int powerEntityId; + /** + * Residency data for each state the PowerEntity's state space + */ + PowerEntityStateResidencyData[] stateResidencyData; +} + diff --git a/powerstats/aidl/android/hardware/powerstats/PowerEntityStateSpace.aidl b/powerstats/aidl/android/hardware/powerstats/PowerEntityStateSpace.aidl new file mode 100644 index 0000000000..8e3066515f --- /dev/null +++ b/powerstats/aidl/android/hardware/powerstats/PowerEntityStateSpace.aidl @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.powerstats; + +import android.hardware.powerstats.PowerEntityStateInfo; + +/** + * PowerEntityStateSpace contains the state space information of a given + * PowerEntity. The state space, is the set of possible states that a given + * PowerEntity provides residency data for. + */ +@VintfStability +parcelable PowerEntityStateSpace { + /** + * Unique ID of the corresponding PowerEntity + */ + int powerEntityId; + /** + * List of states that the PowerEntity may reside in + */ + PowerEntityStateInfo[] states; +} + diff --git a/powerstats/aidl/android/hardware/powerstats/PowerEntityType.aidl b/powerstats/aidl/android/hardware/powerstats/PowerEntityType.aidl new file mode 100644 index 0000000000..a8cd0b71c1 --- /dev/null +++ b/powerstats/aidl/android/hardware/powerstats/PowerEntityType.aidl @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.powerstats; + +@VintfStability +@Backing(type="int") +enum PowerEntityType { + /** + * A subsystem is a self-contained compute unit. Some examples include + * application processor, DSP, GPU. + */ + SUBSYSTEM = 0, + /** + * A peripheral is an auxiliary device that connects to and works with a + * compute unit. Some examples include simple sensors, camera, display. + */ + PERIPHERAL = 1, + /** + * A power domain is a single subsystem or a collection of subsystems + * that is controlled by a single voltage rail. + */ + POWER_DOMAIN = 2, +} \ No newline at end of file diff --git a/powerstats/aidl/android/hardware/powerstats/RailInfo.aidl b/powerstats/aidl/android/hardware/powerstats/RailInfo.aidl new file mode 100644 index 0000000000..4c05bfec87 --- /dev/null +++ b/powerstats/aidl/android/hardware/powerstats/RailInfo.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. + */ + +package android.hardware.powerstats; + +@VintfStability +parcelable RailInfo { + /** + * Index corresponding to the rail + */ + int railIndex; + /** + * Name of the rail (opaque to the framework) + */ + String railName; + /** + * Name of the subsystem to which this rail belongs (opaque to the framework) + */ + String subsysName; + /** + * Hardware sampling rate in Hz + */ + int samplingRateHz; +} + diff --git a/powerstats/aidl/default/Android.bp b/powerstats/aidl/default/Android.bp new file mode 100644 index 0000000000..caecd88ce9 --- /dev/null +++ b/powerstats/aidl/default/Android.bp @@ -0,0 +1,30 @@ +// 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. + +cc_binary { + name: "android.hardware.powerstats-service.example", + relative_install_path: "hw", + init_rc: ["powerstats-default.rc"], + vintf_fragments: ["powerstats-default.xml"], + vendor: true, + shared_libs: [ + "libbase", + "libbinder_ndk", + "android.hardware.powerstats-ndk_platform", + ], + srcs: [ + "main.cpp", + "PowerStats.cpp", + ], +} diff --git a/powerstats/aidl/default/PowerStats.cpp b/powerstats/aidl/default/PowerStats.cpp new file mode 100644 index 0000000000..50a829e133 --- /dev/null +++ b/powerstats/aidl/default/PowerStats.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "PowerStats.h" + +#include + +namespace aidl { +namespace android { +namespace hardware { +namespace powerstats { + +ndk::ScopedAStatus PowerStats::getEnergyData(const std::vector& in_railIndices, + std::vector* _aidl_return) { + (void)in_railIndices; + (void)_aidl_return; + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus PowerStats::getPowerEntityInfo(std::vector* _aidl_return) { + (void)_aidl_return; + return ndk::ScopedAStatus::ok(); +} +ndk::ScopedAStatus PowerStats::getPowerEntityStateInfo( + const std::vector& in_powerEntityIds, + std::vector* _aidl_return) { + (void)in_powerEntityIds; + (void)_aidl_return; + return ndk::ScopedAStatus::ok(); +} +ndk::ScopedAStatus PowerStats::getPowerEntityStateResidencyData( + const std::vector& in_powerEntityIds, + std::vector* _aidl_return) { + (void)in_powerEntityIds; + (void)_aidl_return; + return ndk::ScopedAStatus::ok(); +} +ndk::ScopedAStatus PowerStats::getRailInfo(std::vector* _aidl_return) { + (void)_aidl_return; + return ndk::ScopedAStatus::ok(); +} + +} // namespace powerstats +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/powerstats/aidl/default/PowerStats.h b/powerstats/aidl/default/PowerStats.h new file mode 100644 index 0000000000..392d1e6042 --- /dev/null +++ b/powerstats/aidl/default/PowerStats.h @@ -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. + */ + +#pragma once + +#include + +namespace aidl { +namespace android { +namespace hardware { +namespace powerstats { + +class PowerStats : public BnPowerStats { + public: + PowerStats() = default; + ndk::ScopedAStatus getEnergyData(const std::vector& in_railIndices, + std::vector* _aidl_return) override; + ndk::ScopedAStatus getPowerEntityInfo(std::vector* _aidl_return) override; + ndk::ScopedAStatus getPowerEntityStateInfo( + const std::vector& in_powerEntityIds, + std::vector* _aidl_return) override; + ndk::ScopedAStatus getPowerEntityStateResidencyData( + const std::vector& in_powerEntityIds, + std::vector* _aidl_return) override; + ndk::ScopedAStatus getRailInfo(std::vector* _aidl_return) override; +}; + +} // namespace powerstats +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/powerstats/aidl/default/main.cpp b/powerstats/aidl/default/main.cpp new file mode 100644 index 0000000000..1496805528 --- /dev/null +++ b/powerstats/aidl/default/main.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "PowerStats.h" + +#include +#include +#include + +using aidl::android::hardware::powerstats::PowerStats; + +int main() { + ABinderProcess_setThreadPoolMaxThreadCount(0); + std::shared_ptr p = ndk::SharedRefBase::make(); + + const std::string instance = std::string() + PowerStats::descriptor + "/default"; + binder_status_t status = AServiceManager_addService(p->asBinder().get(), instance.c_str()); + CHECK(status == STATUS_OK); + + ABinderProcess_joinThreadPool(); + return EXIT_FAILURE; // should not reach +} diff --git a/powerstats/aidl/default/powerstats-default.rc b/powerstats/aidl/default/powerstats-default.rc new file mode 100644 index 0000000000..9b04be374d --- /dev/null +++ b/powerstats/aidl/default/powerstats-default.rc @@ -0,0 +1,4 @@ +service vendor.powerstats-default /vendor/bin/hw/android.hardware.powerstats-service.example + class hal + user system + group system diff --git a/powerstats/aidl/default/powerstats-default.xml b/powerstats/aidl/default/powerstats-default.xml new file mode 100644 index 0000000000..e07513d8fa --- /dev/null +++ b/powerstats/aidl/default/powerstats-default.xml @@ -0,0 +1,6 @@ + + + android.hardware.powerstats + IPowerStats/default + + -- GitLab From d91c540c170ce76d0448bdc1d3cea4b8bcd81278 Mon Sep 17 00:00:00 2001 From: lesl Date: Mon, 10 Aug 2020 13:23:29 +0800 Subject: [PATCH 121/790] wifi: Add client connected callback Add client connected callback support on hostapd HIDL interface Bug: 163288112 Test: Manuel Test. Hotspot works normally. Test: atest VtsHalWifiHostapdV1_0TargetTest Test: atest VtsHalWifiHostapdV1_1TargetTest Test: atest VtsHalWifiHostapdV1_2TargetTest Change-Id: Ib0a41b3ef4a46c7c4bf1ed6e01b31ce3a334a213 --- wifi/hostapd/1.3/IHostapd.hal | 5 ++--- wifi/hostapd/1.3/IHostapdCallback.hal | 17 +++++++++++++++++ wifi/hostapd/1.3/types.hal | 1 - 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/wifi/hostapd/1.3/IHostapd.hal b/wifi/hostapd/1.3/IHostapd.hal index 7ac20e43e5..d16448d074 100644 --- a/wifi/hostapd/1.3/IHostapd.hal +++ b/wifi/hostapd/1.3/IHostapd.hal @@ -18,8 +18,8 @@ package android.hardware.wifi.hostapd@1.3; import @1.2::IHostapd; import @1.2::HostapdStatus; - import IHostapdCallback; + /** * Top-level object for managing SoftAPs. */ @@ -39,6 +39,5 @@ interface IHostapd extends @1.2::IHostapd { * |HostapdStatusCode.SUCCESS|, * |HostapdStatusCode.FAILURE_UNKNOWN| */ - registerCallback_1_3(IHostapdCallback callback) - generates (HostapdStatus status); + registerCallback_1_3(IHostapdCallback callback) generates (HostapdStatus status); }; diff --git a/wifi/hostapd/1.3/IHostapdCallback.hal b/wifi/hostapd/1.3/IHostapdCallback.hal index 5202178935..4db470de43 100644 --- a/wifi/hostapd/1.3/IHostapdCallback.hal +++ b/wifi/hostapd/1.3/IHostapdCallback.hal @@ -17,6 +17,7 @@ package android.hardware.wifi.hostapd@1.3; import @1.1::IHostapdCallback; +import @1.2::MacAddress; import Generation; /** @@ -24,4 +25,20 @@ import Generation; */ interface IHostapdCallback extends @1.1::IHostapdCallback { oneway onInterfaceInfoChanged(string ifaceName, Generation generation); + + /** + * Invoked when a client connects/disconnects from the hotspot. + * + * @param ifaceName Name of the interface which is added via + * |IHostapd.addAccessPoint|. + * @param apIfaceInstance The identity of the AP instance. The interface + * will have two instances in dual AP mode. The apIfaceInstance can be used + * to identify which instance the callback is from. + * Note: The apIfaceInstance must be same as ifaceName in single AP mode. + * @param clientAddress Mac Address of hotspot client. + * @param isConnected true when client connected, false when client + * disconnected. + */ + oneway onConnectedClientsChanged(string ifaceName, string apIfaceInstance, + MacAddress clientAddress, bool isConnected); }; diff --git a/wifi/hostapd/1.3/types.hal b/wifi/hostapd/1.3/types.hal index ce092c07a9..887ea0fc25 100644 --- a/wifi/hostapd/1.3/types.hal +++ b/wifi/hostapd/1.3/types.hal @@ -34,4 +34,3 @@ enum Generation : uint32_t { WIFI_STANDARD_11AC = 2, WIFI_STANDARD_11AX = 3, }; - -- GitLab From 5118e4f043a68e46f2478d15f05b5067cd452a75 Mon Sep 17 00:00:00 2001 From: Kai Shi Date: Wed, 12 Aug 2020 18:56:43 -0700 Subject: [PATCH 122/790] wifi: Support 11b only mode upgrade @1.4::ConnectionCapabilities to include legacyMode, update corresponding 1.3 VTS test and add new 1.4 VTS test files Bug: 163912712 Test: atest VtsHalWifiSupplicantV1_0TargetTest \ VtsHalWifiSupplicantV1_1TargetTest \ VtsHalWifiSupplicantV1_2TargetTest \ VtsHalWifiSupplicantV1_3TargetTest \ VtsHalWifiSupplicantV1_4TargetTest Test: manual test with 11b only AP to confirm 11b mode is detected and passed to throughput predictor correctly. Change-Id: Id4fd567401289091a5d74a770e759eee326c3873 --- current.txt | 3 + .../supplicant_sta_iface_hidl_test.cpp | 6 +- wifi/supplicant/1.4/Android.bp | 2 + wifi/supplicant/1.4/ISupplicantStaIface.hal | 39 ++++++++ wifi/supplicant/1.4/types.hal | 52 ++++++++++ wifi/supplicant/1.4/vts/OWNERS | 2 + wifi/supplicant/1.4/vts/functional/Android.bp | 71 ++++++++++++++ .../supplicant_hidl_test_utils_1_4.cpp | 36 +++++++ .../supplicant_hidl_test_utils_1_4.h | 30 ++++++ .../supplicant_sta_iface_hidl_test.cpp | 94 +++++++++++++++++++ 10 files changed, 334 insertions(+), 1 deletion(-) create mode 100644 wifi/supplicant/1.4/ISupplicantStaIface.hal create mode 100644 wifi/supplicant/1.4/types.hal create mode 100644 wifi/supplicant/1.4/vts/OWNERS create mode 100644 wifi/supplicant/1.4/vts/functional/Android.bp create mode 100644 wifi/supplicant/1.4/vts/functional/supplicant_hidl_test_utils_1_4.cpp create mode 100644 wifi/supplicant/1.4/vts/functional/supplicant_hidl_test_utils_1_4.h create mode 100644 wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp diff --git a/current.txt b/current.txt index 594ceb632c..b929f7ddd3 100644 --- a/current.txt +++ b/current.txt @@ -777,3 +777,6 @@ cd84ab19c590e0e73dd2307b591a3093ee18147ef95e6d5418644463a6620076 android.hardwar # HALs released in Android S # NOTE: waiting to freeze HALs until later in the release # NOTE: new HALs are recommended to be in AIDL +57d183b10b13ec0a8e542c0b3d61991ae541c60e85dbbc5499bb21dfd068cbb8 android.hardware.wifi.supplicant@1.4::types +17818b6b1952a75e4364ae82c534b9d2f5c0a9765a56256b16faa5a5cf45d3a8 android.hardware.wifi.supplicant@1.4::ISupplicant +8342b5f6ec8f48ad2b741128aede010995d0b5709257b7ec09bb469b4f61ef1a android.hardware.wifi.supplicant@1.4::ISupplicantStaIface diff --git a/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp index 12bd122b14..fba986ea67 100644 --- a/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp +++ b/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp @@ -349,7 +349,11 @@ TEST_P(SupplicantStaIfaceHidlTest, GetConnectionCapabilities) { sta_iface_->getConnectionCapabilities( [&](const SupplicantStatus& status, ConnectionCapabilities /* capabilities */) { - EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + // Since getConnectionCapabilities() is overridden by an + // upgraded API in newer HAL versions, allow for FAILURE_UNKNOWN + if (status.code != SupplicantStatusCode::FAILURE_UNKNOWN) { + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + } }); } diff --git a/wifi/supplicant/1.4/Android.bp b/wifi/supplicant/1.4/Android.bp index ff2a8bc665..81e17387f1 100644 --- a/wifi/supplicant/1.4/Android.bp +++ b/wifi/supplicant/1.4/Android.bp @@ -4,7 +4,9 @@ hidl_interface { name: "android.hardware.wifi.supplicant@1.4", root: "android.hardware", srcs: [ + "types.hal", "ISupplicant.hal", + "ISupplicantStaIface.hal", ], interfaces: [ "android.hardware.wifi.supplicant@1.0", diff --git a/wifi/supplicant/1.4/ISupplicantStaIface.hal b/wifi/supplicant/1.4/ISupplicantStaIface.hal new file mode 100644 index 0000000000..28ef912eae --- /dev/null +++ b/wifi/supplicant/1.4/ISupplicantStaIface.hal @@ -0,0 +1,39 @@ +/* + * 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. + */ + +package android.hardware.wifi.supplicant@1.4; + +import @1.0::SupplicantStatus; +import @1.3::ISupplicantStaIface; + +/** + * Interface exposed by the supplicant for each station mode network + * interface (e.g wlan0) it controls. + */ +interface ISupplicantStaIface extends @1.3::ISupplicantStaIface { + + /** + * Get Connection capabilities + * + * @return status Status of the operation, and connection capabilities. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_UNKNOWN|, + */ + getConnectionCapabilities_1_4() + generates (SupplicantStatus status, ConnectionCapabilities capabilities); + +}; diff --git a/wifi/supplicant/1.4/types.hal b/wifi/supplicant/1.4/types.hal new file mode 100644 index 0000000000..79e367aa91 --- /dev/null +++ b/wifi/supplicant/1.4/types.hal @@ -0,0 +1,52 @@ +/* + * 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. + */ + +package android.hardware.wifi.supplicant@1.4; + +import @1.3::ConnectionCapabilities; + +/** + * Detailed network mode for legacy network + */ +enum LegacyMode : uint32_t { + UNKNOWN = 0, + /** + * For 802.11a + */ + A_MODE = 1, + /** + * For 802.11b + */ + B_MODE = 2, + /** + * For 802.11g + */ + G_MODE = 3, +}; + +/** + * Connection Capabilities supported by current network and device + */ +struct ConnectionCapabilities { + /** + * Baseline information as defined in HAL 1.3. + */ + @1.3::ConnectionCapabilities V1_3; + /** + * detailed network mode for legacy network + */ + LegacyMode legacyMode; +}; diff --git a/wifi/supplicant/1.4/vts/OWNERS b/wifi/supplicant/1.4/vts/OWNERS new file mode 100644 index 0000000000..8bfb14882c --- /dev/null +++ b/wifi/supplicant/1.4/vts/OWNERS @@ -0,0 +1,2 @@ +rpius@google.com +etancohen@google.com diff --git a/wifi/supplicant/1.4/vts/functional/Android.bp b/wifi/supplicant/1.4/vts/functional/Android.bp new file mode 100644 index 0000000000..7f2ba70125 --- /dev/null +++ b/wifi/supplicant/1.4/vts/functional/Android.bp @@ -0,0 +1,71 @@ +// +// 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. +// + +cc_library_static { + name: "VtsHalWifiSupplicantV1_4TargetTestUtil", + defaults: ["VtsHalTargetTestDefaults"], + srcs: ["supplicant_hidl_test_utils_1_4.cpp"], + export_include_dirs: [ + ".", + ], + static_libs: [ + "VtsHalWifiV1_0TargetTestUtil", + "VtsHalWifiSupplicantV1_0TargetTestUtil", + "VtsHalWifiSupplicantV1_1TargetTestUtil", + "VtsHalWifiSupplicantV1_2TargetTestUtil", + "VtsHalWifiSupplicantV1_3TargetTestUtil", + "android.hardware.wifi.supplicant@1.0", + "android.hardware.wifi.supplicant@1.1", + "android.hardware.wifi.supplicant@1.2", + "android.hardware.wifi.supplicant@1.3", + "android.hardware.wifi.supplicant@1.4", + "android.hardware.wifi@1.0", + "libgmock", + "libwifi-system", + "libwifi-system-iface", + ], +} + +cc_test { + name: "VtsHalWifiSupplicantV1_4TargetTest", + defaults: ["VtsHalTargetTestDefaults"], + srcs: [ + "supplicant_sta_iface_hidl_test.cpp", + ], + static_libs: [ + "VtsHalWifiV1_0TargetTestUtil", + "VtsHalWifiSupplicantV1_0TargetTestUtil", + "VtsHalWifiSupplicantV1_1TargetTestUtil", + "VtsHalWifiSupplicantV1_2TargetTestUtil", + "VtsHalWifiSupplicantV1_3TargetTestUtil", + "VtsHalWifiSupplicantV1_4TargetTestUtil", + "android.hardware.wifi.supplicant@1.0", + "android.hardware.wifi.supplicant@1.1", + "android.hardware.wifi.supplicant@1.2", + "android.hardware.wifi.supplicant@1.3", + "android.hardware.wifi.supplicant@1.4", + "android.hardware.wifi@1.0", + "android.hardware.wifi@1.1", + "libgmock", + "libwifi-system", + "libwifi-system-iface", + ], + test_suites: [ + "general-tests", + "vts", + ], + disable_framework: true, +} diff --git a/wifi/supplicant/1.4/vts/functional/supplicant_hidl_test_utils_1_4.cpp b/wifi/supplicant/1.4/vts/functional/supplicant_hidl_test_utils_1_4.cpp new file mode 100644 index 0000000000..3a59bd6297 --- /dev/null +++ b/wifi/supplicant/1.4/vts/functional/supplicant_hidl_test_utils_1_4.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "supplicant_hidl_test_utils.h" +#include "supplicant_hidl_test_utils_1_4.h" + +using ::android::sp; +using ::android::hardware::wifi::supplicant::V1_4::ISupplicant; +using ::android::hardware::wifi::supplicant::V1_4::ISupplicantStaIface; + +sp getSupplicantStaIface_1_4( + const android::sp& + supplicant) { + return ISupplicantStaIface::castFrom(getSupplicantStaIface(supplicant)); +} + +sp getSupplicant_1_4(const std::string& supplicant_instance_name, + bool isP2pOn) { + return ISupplicant::castFrom( + getSupplicant(supplicant_instance_name, isP2pOn)); +} diff --git a/wifi/supplicant/1.4/vts/functional/supplicant_hidl_test_utils_1_4.h b/wifi/supplicant/1.4/vts/functional/supplicant_hidl_test_utils_1_4.h new file mode 100644 index 0000000000..bea4dc102a --- /dev/null +++ b/wifi/supplicant/1.4/vts/functional/supplicant_hidl_test_utils_1_4.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SUPPLICANT_HIDL_TEST_UTILS_1_4_H +#define SUPPLICANT_HIDL_TEST_UTILS_1_4_H + +#include +#include + +android::sp +getSupplicantStaIface_1_4( + const android::sp& + supplicant); +android::sp +getSupplicant_1_4(const std::string& supplicant_instance_name, bool isP2pOn); + +#endif /* SUPPLICANT_HIDL_TEST_UTILS_1_4_H */ diff --git a/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp new file mode 100644 index 0000000000..2a4f5348b4 --- /dev/null +++ b/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "supplicant_hidl_test_utils.h" +#include "supplicant_hidl_test_utils_1_4.h" + +using ::android::sp; +using ::android::hardware::Void; +using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatus; +using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatusCode; + +using ::android::hardware::wifi::supplicant::V1_4::ConnectionCapabilities; +using ::android::hardware::wifi::supplicant::V1_4::ISupplicant; +using ::android::hardware::wifi::supplicant::V1_4::ISupplicantStaIface; + +class SupplicantStaIfaceHidlTest + : public ::testing::TestWithParam> { + public: + virtual void SetUp() override { + wifi_v1_0_instance_name_ = std::get<0>(GetParam()); + supplicant_v1_4_instance_name_ = std::get<1>(GetParam()); + isP2pOn_ = + testing::deviceSupportsFeature("android.hardware.wifi.direct"); + + stopSupplicant(wifi_v1_0_instance_name_); + startSupplicantAndWaitForHidlService(wifi_v1_0_instance_name_, + supplicant_v1_4_instance_name_); + supplicant_ = + getSupplicant_1_4(supplicant_v1_4_instance_name_, isP2pOn_); + EXPECT_TRUE(turnOnExcessiveLogging(supplicant_)); + sta_iface_ = getSupplicantStaIface_1_4(supplicant_); + ASSERT_NE(sta_iface_.get(), nullptr); + } + + virtual void TearDown() override { + stopSupplicant(wifi_v1_0_instance_name_); + } + + protected: + // ISupplicantStaIface object used for all tests in this fixture. + sp sta_iface_; + sp supplicant_; + bool isP2pOn_ = false; + std::string wifi_v1_0_instance_name_; + std::string supplicant_v1_4_instance_name_; +}; + +/* + * getConnectionCapabilities_1_4 + */ +TEST_P(SupplicantStaIfaceHidlTest, GetConnectionCapabilities) { + sta_iface_->getConnectionCapabilities_1_4( + [&](const SupplicantStatus& status, + ConnectionCapabilities /* capabilities */) { + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + }); +} + +INSTANTIATE_TEST_CASE_P( + PerInstance, SupplicantStaIfaceHidlTest, + testing::Combine( + testing::ValuesIn(android::hardware::getAllHalInstanceNames( + android::hardware::wifi::V1_0::IWifi::descriptor)), + testing::ValuesIn(android::hardware::getAllHalInstanceNames( + android::hardware::wifi::supplicant::V1_4::ISupplicant:: + descriptor))), + android::hardware::PrintInstanceTupleNameToString<>); -- GitLab From 81dec9cfc46c844ba929bee7cf0333a63bc9e9e9 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Fri, 28 Aug 2020 15:05:59 -0700 Subject: [PATCH 123/790] Make wifi hidl interfaces available to the platform The wifi hidl interfaces need apex_available: ["com.android.wifi"] because the generated java interfaces are needed by the com.android.wifi apex, but that causes the C interfaces to not be available to the platform. The unavailability was hidden by b/154888298. Explicitly mark them with "//apex_available:platform". Bug: 154888298 Test: m checkbuild Change-Id: I8959ec1454cce6817802bcc1785a34ba56adc99c --- wifi/1.5/Android.bp | 1 + wifi/hostapd/1.3/Android.bp | 1 + wifi/supplicant/1.4/Android.bp | 1 + 3 files changed, 3 insertions(+) diff --git a/wifi/1.5/Android.bp b/wifi/1.5/Android.bp index 37a1cf31a4..1714ef8e73 100644 --- a/wifi/1.5/Android.bp +++ b/wifi/1.5/Android.bp @@ -16,6 +16,7 @@ hidl_interface { ], gen_java: true, apex_available: [ + "//apex_available:platform", "com.android.wifi", ], } diff --git a/wifi/hostapd/1.3/Android.bp b/wifi/hostapd/1.3/Android.bp index aef3267d14..31faa6a9a6 100644 --- a/wifi/hostapd/1.3/Android.bp +++ b/wifi/hostapd/1.3/Android.bp @@ -17,6 +17,7 @@ hidl_interface { ], gen_java: true, apex_available: [ + "//apex_available:platform", "com.android.wifi", ], } diff --git a/wifi/supplicant/1.4/Android.bp b/wifi/supplicant/1.4/Android.bp index 81e17387f1..f3a7cf8104 100644 --- a/wifi/supplicant/1.4/Android.bp +++ b/wifi/supplicant/1.4/Android.bp @@ -18,6 +18,7 @@ hidl_interface { ], gen_java: true, apex_available: [ + "//apex_available:platform", "com.android.wifi", ], } -- GitLab From 40492c22e170bb5fbc6988a557c5c94f947cce95 Mon Sep 17 00:00:00 2001 From: Benjamin Schwartz Date: Mon, 31 Aug 2020 11:55:55 -0700 Subject: [PATCH 124/790] Add VTS tests for PowerStats HAL 2.0 Right now these VTS tests only check for successful return status since this HAL only contains a stub implementation at the moment. These tests will be updated as this HAL implementation is completed. Bug: 165345767 Test: atest VtsHalPowerStatsTargetTest Change-Id: I3a6a4a333ee743fac4eba8ae225d5d1c9ffff32e --- powerstats/aidl/vts/Android.bp | 32 ++++++++ .../aidl/vts/VtsHalPowerStatsTargetTest.cpp | 79 +++++++++++++++++++ 2 files changed, 111 insertions(+) create mode 100644 powerstats/aidl/vts/Android.bp create mode 100644 powerstats/aidl/vts/VtsHalPowerStatsTargetTest.cpp diff --git a/powerstats/aidl/vts/Android.bp b/powerstats/aidl/vts/Android.bp new file mode 100644 index 0000000000..c61022ec0a --- /dev/null +++ b/powerstats/aidl/vts/Android.bp @@ -0,0 +1,32 @@ +// 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. + +cc_test { + name: "VtsHalPowerStatsTargetTest", + defaults: [ + "VtsHalTargetTestDefaults", + "use_libaidlvintf_gtest_helper_static", + ], + srcs: ["VtsHalPowerStatsTargetTest.cpp"], + shared_libs: [ + "libbinder_ndk", + ], + static_libs: [ + "android.hardware.powerstats-ndk_platform", + ], + test_suites: [ + "general-tests", + "vts", + ], +} diff --git a/powerstats/aidl/vts/VtsHalPowerStatsTargetTest.cpp b/powerstats/aidl/vts/VtsHalPowerStatsTargetTest.cpp new file mode 100644 index 0000000000..fc0e659ec7 --- /dev/null +++ b/powerstats/aidl/vts/VtsHalPowerStatsTargetTest.cpp @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include + +#include +#include +#include +#include + +using aidl::android::hardware::powerstats::EnergyData; +using aidl::android::hardware::powerstats::IPowerStats; +using aidl::android::hardware::powerstats::PowerEntityInfo; +using aidl::android::hardware::powerstats::PowerEntityStateResidencyResult; +using aidl::android::hardware::powerstats::PowerEntityStateSpace; +using aidl::android::hardware::powerstats::RailInfo; +using ndk::SpAIBinder; + +class PowerStatsAidl : public testing::TestWithParam { + public: + virtual void SetUp() override { + powerstats = IPowerStats::fromBinder( + SpAIBinder(AServiceManager_waitForService(GetParam().c_str()))); + ASSERT_NE(nullptr, powerstats.get()); + } + + std::shared_ptr powerstats; +}; + +TEST_P(PowerStatsAidl, TestGetEnergyData) { + std::vector data; + ASSERT_TRUE(powerstats->getEnergyData({}, &data).isOk()); +} + +TEST_P(PowerStatsAidl, TestGetPowerEntityInfo) { + std::vector info; + ASSERT_TRUE(powerstats->getPowerEntityInfo(&info).isOk()); +} + +TEST_P(PowerStatsAidl, TestGetPowerEntityStateInfo) { + std::vector info; + ASSERT_TRUE(powerstats->getPowerEntityStateInfo({}, &info).isOk()); +} + +TEST_P(PowerStatsAidl, TestGetPowerEntityStateResidencyData) { + std::vector data; + ASSERT_TRUE(powerstats->getPowerEntityStateResidencyData({}, &data).isOk()); +} + +TEST_P(PowerStatsAidl, TestGetRailInfo) { + std::vector info; + ASSERT_TRUE(powerstats->getRailInfo(&info).isOk()); +} + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(PowerStatsAidl); +INSTANTIATE_TEST_SUITE_P( + PowerStats, PowerStatsAidl, + testing::ValuesIn(android::getAidlHalInstanceNames(IPowerStats::descriptor)), + android::PrintInstanceNameToString); + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + ABinderProcess_setThreadPoolMaxThreadCount(1); + ABinderProcess_startThreadPool(); + return RUN_ALL_TESTS(); +} -- GitLab From 48d97f3921320c78e055e104cb38b6be75722837 Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Mon, 31 Aug 2020 17:14:39 -0700 Subject: [PATCH 125/790] Mark GraphicsMapperHidlTest as allowing not being instantiated Only the variant(s) actually implemented by the device will be instantiated. This is consistent with tests for other versioned or optional HALs. Bug: b/167222309 Test: atest VtsHalGraphicsMapperV2_0TargetTest:GoogleTestVerification#UninstantiatedParameterizedTestSuite -- --abi arm64-v8a Change-Id: I4f1bfbad47bdbf75578ec48a3a56fb5351e7729a --- .../2.0/vts/functional/VtsHalGraphicsMapperV2_0TargetTest.cpp | 1 + .../2.1/vts/functional/VtsHalGraphicsMapperV2_1TargetTest.cpp | 3 ++- .../3.0/vts/functional/VtsHalGraphicsMapperV3_0TargetTest.cpp | 1 + .../4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp | 1 + 4 files changed, 5 insertions(+), 1 deletion(-) diff --git a/graphics/mapper/2.0/vts/functional/VtsHalGraphicsMapperV2_0TargetTest.cpp b/graphics/mapper/2.0/vts/functional/VtsHalGraphicsMapperV2_0TargetTest.cpp index b079a4b689..7d733ff68e 100644 --- a/graphics/mapper/2.0/vts/functional/VtsHalGraphicsMapperV2_0TargetTest.cpp +++ b/graphics/mapper/2.0/vts/functional/VtsHalGraphicsMapperV2_0TargetTest.cpp @@ -410,6 +410,7 @@ TEST_P(GraphicsMapperHidlTest, UnlockNegative) { #endif } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsMapperHidlTest); INSTANTIATE_TEST_CASE_P( PerInstance, GraphicsMapperHidlTest, testing::Combine( diff --git a/graphics/mapper/2.1/vts/functional/VtsHalGraphicsMapperV2_1TargetTest.cpp b/graphics/mapper/2.1/vts/functional/VtsHalGraphicsMapperV2_1TargetTest.cpp index 3d792f9f8e..9f927e59f6 100644 --- a/graphics/mapper/2.1/vts/functional/VtsHalGraphicsMapperV2_1TargetTest.cpp +++ b/graphics/mapper/2.1/vts/functional/VtsHalGraphicsMapperV2_1TargetTest.cpp @@ -204,6 +204,7 @@ TEST_P(GraphicsMapperHidlTest, CreateDescriptor_2_1Negative) { }); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsMapperHidlTest); INSTANTIATE_TEST_CASE_P( PerInstance, GraphicsMapperHidlTest, testing::Combine( @@ -218,4 +219,4 @@ INSTANTIATE_TEST_CASE_P( } // namespace mapper } // namespace graphics } // namespace hardware -} // namespace android \ No newline at end of file +} // namespace android diff --git a/graphics/mapper/3.0/vts/functional/VtsHalGraphicsMapperV3_0TargetTest.cpp b/graphics/mapper/3.0/vts/functional/VtsHalGraphicsMapperV3_0TargetTest.cpp index 92b5994eed..4187dd1354 100644 --- a/graphics/mapper/3.0/vts/functional/VtsHalGraphicsMapperV3_0TargetTest.cpp +++ b/graphics/mapper/3.0/vts/functional/VtsHalGraphicsMapperV3_0TargetTest.cpp @@ -458,6 +458,7 @@ TEST_P(GraphicsMapperHidlTest, IsSupportedY16) { ASSERT_NO_FATAL_FAILURE(supported = mGralloc->isSupported(info)); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsMapperHidlTest); INSTANTIATE_TEST_CASE_P( PerInstance, GraphicsMapperHidlTest, testing::Combine( diff --git a/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp b/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp index bb775dc689..f55a6b77ed 100644 --- a/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp +++ b/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp @@ -2592,6 +2592,7 @@ TEST_P(GraphicsMapperHidlTest, GetReservedRegionBadBuffer) { ASSERT_EQ(0, reservedSize); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsMapperHidlTest); INSTANTIATE_TEST_CASE_P( PerInstance, GraphicsMapperHidlTest, testing::Combine( -- GitLab From 1bdf1a79f4715ff52fd8c670d31d704df09f40d2 Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Mon, 23 Dec 2019 17:53:40 +0200 Subject: [PATCH 126/790] Wifi: add new chip capability WIGIG Add a new chip capability WIGIG, for chips that can operate on the 60GHz band. This capability is mapped to the vendor HAL feature WIFI_FEATURE_INFRA_60G. Bug: 147522435 Test: atest VtsHalWifiV1_0TargetTest VtsHalWifiNanV1_0TargetTest VtsHalWifiApV1_0TargetTest \ VtsHalWifiV1_1TargetTest \ VtsHalWifiV1_2TargetTest VtsHalWifiNanV1_2TargetTest \ VtsHalWifiV1_3TargetTest \ VtsHalWifiApV1_4TargetTest VtsHalWifiNanV1_4TargetTest VtsHalWifiRttV1_4TargetTest Change-Id: I37b1121c62acadb621dca5e38671c78817f592e1 --- wifi/1.0/vts/functional/Android.bp | 4 ++ .../vts/functional/wifi_chip_hidl_test.cpp | 19 +------ .../vts/functional/wifi_hidl_test_utils.cpp | 23 +++++++++ .../1.0/vts/functional/wifi_hidl_test_utils.h | 2 + wifi/1.1/vts/functional/Android.bp | 2 + .../vts/functional/wifi_chip_hidl_test.cpp | 16 +----- wifi/1.2/vts/functional/Android.bp | 5 ++ .../vts/functional/wifi_chip_hidl_test.cpp | 15 +----- wifi/1.3/vts/functional/Android.bp | 9 +++- .../vts/functional/wifi_chip_hidl_test.cpp | 5 +- wifi/1.5/Android.bp | 1 + wifi/1.5/IWifiChip.hal | 51 +++++++++++++++++++ wifi/1.5/default/hidl_struct_util.cpp | 13 +++-- wifi/1.5/default/hidl_struct_util.h | 4 +- wifi/1.5/default/wifi_chip.cpp | 14 ++++- wifi/1.5/default/wifi_chip.h | 7 ++- wifi/1.5/default/wifi_legacy_hal.cpp | 4 +- wifi/1.5/default/wifi_legacy_hal.h | 2 +- 18 files changed, 130 insertions(+), 66 deletions(-) create mode 100644 wifi/1.5/IWifiChip.hal diff --git a/wifi/1.0/vts/functional/Android.bp b/wifi/1.0/vts/functional/Android.bp index 14a8509718..cad54feb5c 100644 --- a/wifi/1.0/vts/functional/Android.bp +++ b/wifi/1.0/vts/functional/Android.bp @@ -30,6 +30,8 @@ cc_library_static { ], static_libs: [ "android.hardware.wifi@1.0", + "android.hardware.wifi@1.3", + "android.hardware.wifi@1.5", "libwifi-system-iface", ], } @@ -49,6 +51,8 @@ cc_test { "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", "libwifi-system-iface", ], test_suites: [ diff --git a/wifi/1.0/vts/functional/wifi_chip_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_chip_hidl_test.cpp index b17d2ad1be..6c8f560769 100644 --- a/wifi/1.0/vts/functional/wifi_chip_hidl_test.cpp +++ b/wifi/1.0/vts/functional/wifi_chip_hidl_test.cpp @@ -18,7 +18,6 @@ #include #include -#include #include #include #include @@ -94,23 +93,7 @@ class WifiChipHidlTest : public ::testing::TestWithParam { uint32_t configureChipForStaIfaceAndGetCapabilities() { configureChipForIfaceType(IfaceType::STA, true); - sp<::android::hardware::wifi::V1_3::IWifiChip> chip_converted = - ::android::hardware::wifi::V1_3::IWifiChip::castFrom(wifi_chip_); - - std::pair status_and_caps; - - if (chip_converted != nullptr) { - // Call the newer HAL version - status_and_caps = HIDL_INVOKE(chip_converted, getCapabilities_1_3); - } else { - status_and_caps = HIDL_INVOKE(wifi_chip_, getCapabilities); - } - - if (status_and_caps.first.code != WifiStatusCode::SUCCESS) { - EXPECT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED, status_and_caps.first.code); - return 0; - } - return status_and_caps.second; + return getChipCapabilitiesLatest(wifi_chip_); } std::string getIfaceName(const sp& iface) { diff --git a/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp b/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp index 092822f932..e6e61cf8b7 100644 --- a/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp +++ b/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp @@ -16,6 +16,8 @@ #include +#include +#include #include #include "wifi_hidl_call_util.h" @@ -208,3 +210,24 @@ void stopWifi(const std::string& instance_name) { ASSERT_NE(wifi, nullptr); HIDL_INVOKE(wifi, stop); } + +uint32_t getChipCapabilitiesLatest(const sp& wifi_chip) { + sp<::android::hardware::wifi::V1_5::IWifiChip> chip_converted15 = + ::android::hardware::wifi::V1_5::IWifiChip::castFrom(wifi_chip); + sp<::android::hardware::wifi::V1_3::IWifiChip> chip_converted13 = + ::android::hardware::wifi::V1_3::IWifiChip::castFrom(wifi_chip); + std::pair status_and_caps; + + if (chip_converted15 != nullptr) { + // Call the newer HAL 1.5 version + status_and_caps = HIDL_INVOKE(chip_converted15, getCapabilities_1_5); + } else if (chip_converted13 != nullptr) { + // Call the newer HAL 1.3 version + status_and_caps = HIDL_INVOKE(chip_converted13, getCapabilities_1_3); + } else { + status_and_caps = HIDL_INVOKE(wifi_chip, getCapabilities); + } + + EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_caps.first.code); + return status_and_caps.second; +} diff --git a/wifi/1.0/vts/functional/wifi_hidl_test_utils.h b/wifi/1.0/vts/functional/wifi_hidl_test_utils.h index 5c7863740d..62c015cb39 100644 --- a/wifi/1.0/vts/functional/wifi_hidl_test_utils.h +++ b/wifi/1.0/vts/functional/wifi_hidl_test_utils.h @@ -51,3 +51,5 @@ bool configureChipToSupportIfaceType( android::hardware::wifi::V1_0::ChipModeId* configured_mode_id); // Used to trigger IWifi.stop() at the end of every test. void stopWifi(const std::string& instance_name); +uint32_t getChipCapabilitiesLatest( + const android::sp& wifi_chip); diff --git a/wifi/1.1/vts/functional/Android.bp b/wifi/1.1/vts/functional/Android.bp index 7dc78e4519..98931372e2 100644 --- a/wifi/1.1/vts/functional/Android.bp +++ b/wifi/1.1/vts/functional/Android.bp @@ -26,6 +26,8 @@ cc_test { "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", "libwifi-system-iface", ], test_suites: [ diff --git a/wifi/1.1/vts/functional/wifi_chip_hidl_test.cpp b/wifi/1.1/vts/functional/wifi_chip_hidl_test.cpp index 68c29659b5..874aa83584 100644 --- a/wifi/1.1/vts/functional/wifi_chip_hidl_test.cpp +++ b/wifi/1.1/vts/functional/wifi_chip_hidl_test.cpp @@ -18,7 +18,6 @@ #include #include -#include #include #include #include @@ -64,20 +63,7 @@ class WifiChipHidlTest : public ::testing::TestWithParam { EXPECT_TRUE(configureChipToSupportIfaceType( wifi_chip_, IfaceType::STA, &mode_id)); - sp<::android::hardware::wifi::V1_3::IWifiChip> chip_converted = - ::android::hardware::wifi::V1_3::IWifiChip::castFrom(wifi_chip_); - - std::pair status_and_caps; - - if (chip_converted != nullptr) { - // Call the newer HAL version - status_and_caps = HIDL_INVOKE(chip_converted, getCapabilities_1_3); - } else { - status_and_caps = HIDL_INVOKE(wifi_chip_, getCapabilities); - } - - EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_caps.first.code); - return status_and_caps.second; + return getChipCapabilitiesLatest(wifi_chip_); } sp wifi_chip_; diff --git a/wifi/1.2/vts/functional/Android.bp b/wifi/1.2/vts/functional/Android.bp index 159ba94340..21d8388369 100644 --- a/wifi/1.2/vts/functional/Android.bp +++ b/wifi/1.2/vts/functional/Android.bp @@ -27,6 +27,8 @@ cc_test { "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", "libwifi-system-iface", ], disable_framework: true, @@ -47,6 +49,9 @@ cc_test { "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", "libwifi-system-iface", ], test_suites: [ diff --git a/wifi/1.2/vts/functional/wifi_chip_hidl_test.cpp b/wifi/1.2/vts/functional/wifi_chip_hidl_test.cpp index 8d91a23bfb..6113fbf1f9 100644 --- a/wifi/1.2/vts/functional/wifi_chip_hidl_test.cpp +++ b/wifi/1.2/vts/functional/wifi_chip_hidl_test.cpp @@ -111,20 +111,7 @@ class WifiChipHidlTest : public ::testing::TestWithParam { EXPECT_TRUE( configureChipToSupportIfaceType(wifi_chip_, IfaceType::STA, &mode_id)); - sp<::android::hardware::wifi::V1_3::IWifiChip> chip_converted = - ::android::hardware::wifi::V1_3::IWifiChip::castFrom(wifi_chip_); - - std::pair status_and_caps; - - if (chip_converted != nullptr) { - // Call the newer HAL version - status_and_caps = HIDL_INVOKE(chip_converted, getCapabilities_1_3); - } else { - status_and_caps = HIDL_INVOKE(wifi_chip_, getCapabilities); - } - - EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_caps.first.code); - return status_and_caps.second; + return getChipCapabilitiesLatest(wifi_chip_); } sp wifi_chip_; diff --git a/wifi/1.3/vts/functional/Android.bp b/wifi/1.3/vts/functional/Android.bp index 3568330845..7ee69c9964 100644 --- a/wifi/1.3/vts/functional/Android.bp +++ b/wifi/1.3/vts/functional/Android.bp @@ -27,8 +27,13 @@ cc_test { "android.hardware.wifi@1.1", "android.hardware.wifi@1.2", "android.hardware.wifi@1.3", - "libwifi-system-iface" + "android.hardware.wifi@1.4", + "android.hardware.wifi@1.5", + "libwifi-system-iface", ], disable_framework: true, - test_suites: ["general-tests", "vts"], + test_suites: [ + "general-tests", + "vts", + ], } diff --git a/wifi/1.3/vts/functional/wifi_chip_hidl_test.cpp b/wifi/1.3/vts/functional/wifi_chip_hidl_test.cpp index 361a87079f..f2c2beac50 100644 --- a/wifi/1.3/vts/functional/wifi_chip_hidl_test.cpp +++ b/wifi/1.3/vts/functional/wifi_chip_hidl_test.cpp @@ -68,10 +68,7 @@ class WifiChipHidlTest : public ::testing::TestWithParam { ChipModeId mode_id; EXPECT_TRUE(configureChipToSupportIfaceType(wifi_chip_, IfaceType::STA, &mode_id)); - const auto& status_and_caps = - HIDL_INVOKE(wifi_chip_, getCapabilities_1_3); - EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_caps.first.code); - return status_and_caps.second; + return getChipCapabilitiesLatest(wifi_chip_); } sp wifi_chip_; diff --git a/wifi/1.5/Android.bp b/wifi/1.5/Android.bp index 1714ef8e73..4492521109 100644 --- a/wifi/1.5/Android.bp +++ b/wifi/1.5/Android.bp @@ -5,6 +5,7 @@ hidl_interface { root: "android.hardware", srcs: [ "IWifi.hal", + "IWifiChip.hal", ], interfaces: [ "android.hardware.wifi@1.0", diff --git a/wifi/1.5/IWifiChip.hal b/wifi/1.5/IWifiChip.hal new file mode 100644 index 0000000000..5243baf7f3 --- /dev/null +++ b/wifi/1.5/IWifiChip.hal @@ -0,0 +1,51 @@ +/* + * 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. + */ + +package android.hardware.wifi@1.5; + +import @1.0::WifiStatus; +import @1.0::IWifiIface; +import @1.3::IWifiChip; +import @1.4::IWifiChip; + +/** + * Interface that represents a chip that must be configured as a single unit. + */ +interface IWifiChip extends @1.4::IWifiChip { + /** + * Capabilities exposed by this chip. + */ + enum ChipCapabilityMask : @1.3::IWifiChip.ChipCapabilityMask { + /** + * chip can operate in the 60GHz band(WiGig chip) + */ + WIGIG = 1 << 14, + }; + + /** + * Get the capabilities supported by this chip. + * + * @return status WifiStatus of the operation. + * Possible status codes: + * |WifiStatusCode.SUCCESS|, + * |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|, + * |WifiStatusCode.ERROR_NOT_AVAILABLE|, + * |WifiStatusCode.ERROR_UNKNOWN| + * @return capabilities Bitset of |ChipCapabilityMask| values. + */ + getCapabilities_1_5() + generates (WifiStatus status, bitfield capabilities); +}; diff --git a/wifi/1.5/default/hidl_struct_util.cpp b/wifi/1.5/default/hidl_struct_util.cpp index a155ff877a..91a82a7661 100644 --- a/wifi/1.5/default/hidl_struct_util.cpp +++ b/wifi/1.5/default/hidl_struct_util.cpp @@ -69,9 +69,9 @@ convertLegacyLoggerFeatureToHidlStaIfaceCapability(uint32_t feature) { return {}; } -V1_3::IWifiChip::ChipCapabilityMask convertLegacyFeatureToHidlChipCapability( - uint32_t feature) { - using HidlChipCaps = V1_3::IWifiChip::ChipCapabilityMask; +V1_5::IWifiChip::ChipCapabilityMask convertLegacyFeatureToHidlChipCapability( + uint64_t feature) { + using HidlChipCaps = V1_5::IWifiChip::ChipCapabilityMask; switch (feature) { case WIFI_FEATURE_SET_TX_POWER_LIMIT: return HidlChipCaps::SET_TX_POWER_LIMIT; @@ -81,6 +81,8 @@ V1_3::IWifiChip::ChipCapabilityMask convertLegacyFeatureToHidlChipCapability( return HidlChipCaps::D2D_RTT; case WIFI_FEATURE_D2AP_RTT: return HidlChipCaps::D2AP_RTT; + case WIFI_FEATURE_INFRA_60G: + return HidlChipCaps::WIGIG; case WIFI_FEATURE_SET_LATENCY_MODE: return HidlChipCaps::SET_LATENCY_MODE; case WIFI_FEATURE_P2P_RAND_MAC: @@ -126,7 +128,7 @@ convertLegacyFeatureToHidlStaIfaceCapability(uint64_t feature) { } bool convertLegacyFeaturesToHidlChipCapabilities( - uint32_t legacy_feature_set, uint32_t legacy_logger_feature_set, + uint64_t legacy_feature_set, uint32_t legacy_logger_feature_set, uint32_t* hidl_caps) { if (!hidl_caps) { return false; @@ -143,10 +145,11 @@ bool convertLegacyFeaturesToHidlChipCapabilities( convertLegacyLoggerFeatureToHidlChipCapability(feature); } } - std::vector features = {WIFI_FEATURE_SET_TX_POWER_LIMIT, + std::vector features = {WIFI_FEATURE_SET_TX_POWER_LIMIT, WIFI_FEATURE_USE_BODY_HEAD_SAR, WIFI_FEATURE_D2D_RTT, WIFI_FEATURE_D2AP_RTT, + WIFI_FEATURE_INFRA_60G, WIFI_FEATURE_SET_LATENCY_MODE, WIFI_FEATURE_P2P_RAND_MAC}; for (const auto feature : features) { diff --git a/wifi/1.5/default/hidl_struct_util.h b/wifi/1.5/default/hidl_struct_util.h index b6567ff809..c6dc692367 100644 --- a/wifi/1.5/default/hidl_struct_util.h +++ b/wifi/1.5/default/hidl_struct_util.h @@ -22,10 +22,10 @@ #include #include #include -#include #include #include #include +#include #include "wifi_legacy_hal.h" @@ -45,7 +45,7 @@ using namespace android::hardware::wifi::V1_0; // Chip conversion methods. bool convertLegacyFeaturesToHidlChipCapabilities( - uint32_t legacy_feature_set, uint32_t legacy_logger_feature_set, + 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, diff --git a/wifi/1.5/default/wifi_chip.cpp b/wifi/1.5/default/wifi_chip.cpp index ecf170abc2..ebff722859 100644 --- a/wifi/1.5/default/wifi_chip.cpp +++ b/wifi/1.5/default/wifi_chip.cpp @@ -628,6 +628,13 @@ Return WifiChip::getCapabilities_1_3(getCapabilities_cb hidl_status_cb) { hidl_status_cb); } +Return 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); +} + Return WifiChip::debug(const hidl_handle& handle, const hidl_vec&) { if (handle != nullptr && handle->numFds >= 1) { @@ -1237,8 +1244,13 @@ WifiStatus WifiChip::selectTxPowerScenarioInternal_1_2( } std::pair WifiChip::getCapabilitiesInternal_1_3() { + // Deprecated support for this callback. + return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), 0}; +} + +std::pair WifiChip::getCapabilitiesInternal_1_5() { legacy_hal::wifi_error legacy_status; - uint32_t legacy_feature_set; + uint64_t legacy_feature_set; uint32_t legacy_logger_feature_set; const auto ifname = getFirstActiveWlanIfaceName(); std::tie(legacy_status, legacy_feature_set) = diff --git a/wifi/1.5/default/wifi_chip.h b/wifi/1.5/default/wifi_chip.h index 5f1d9e8eda..8cc0452df9 100644 --- a/wifi/1.5/default/wifi_chip.h +++ b/wifi/1.5/default/wifi_chip.h @@ -22,8 +22,8 @@ #include #include -#include #include +#include #include "hidl_callback_util.h" #include "ringbuffer.h" @@ -48,7 +48,7 @@ using namespace android::hardware::wifi::V1_0; * Since there is only a single chip instance used today, there is no * identifying handle information stored here. */ -class WifiChip : public V1_4::IWifiChip { +class WifiChip : public V1_5::IWifiChip { public: WifiChip(ChipId chip_id, bool is_primary, const std::weak_ptr legacy_hal, @@ -153,6 +153,8 @@ class WifiChip : public V1_4::IWifiChip { selectTxPowerScenario_cb hidl_status_cb) override; Return getCapabilities_1_3( getCapabilities_cb hidl_status_cb) override; + Return getCapabilities_1_5( + getCapabilities_1_5_cb hidl_status_cb) override; Return debug(const hidl_handle& handle, const hidl_vec& options) override; Return createRttController_1_4( @@ -226,6 +228,7 @@ class WifiChip : public V1_4::IWifiChip { const sp& event_callback); WifiStatus selectTxPowerScenarioInternal_1_2(TxPowerScenario scenario); std::pair getCapabilitiesInternal_1_3(); + std::pair getCapabilitiesInternal_1_5(); std::pair> createRttControllerInternal_1_4(const sp& bound_iface); WifiStatus registerEventCallbackInternal_1_4( diff --git a/wifi/1.5/default/wifi_legacy_hal.cpp b/wifi/1.5/default/wifi_legacy_hal.cpp index 7d14e9d231..398bfac3f6 100644 --- a/wifi/1.5/default/wifi_legacy_hal.cpp +++ b/wifi/1.5/default/wifi_legacy_hal.cpp @@ -486,7 +486,7 @@ WifiLegacyHal::requestFirmwareMemoryDump(const std::string& iface_name) { return {status, std::move(firmware_dump)}; } -std::pair WifiLegacyHal::getSupportedFeatureSet( +std::pair WifiLegacyHal::getSupportedFeatureSet( const std::string& iface_name) { feature_set set = 0, chip_set = 0; wifi_error status = WIFI_SUCCESS; @@ -502,7 +502,7 @@ std::pair WifiLegacyHal::getSupportedFeatureSet( status = global_func_table_.wifi_get_supported_feature_set(iface_handle, &set); } - return {status, static_cast(set | chip_set)}; + return {status, static_cast(set | chip_set)}; } std::pair diff --git a/wifi/1.5/default/wifi_legacy_hal.h b/wifi/1.5/default/wifi_legacy_hal.h index 2984a00c9b..9a06efd342 100644 --- a/wifi/1.5/default/wifi_legacy_hal.h +++ b/wifi/1.5/default/wifi_legacy_hal.h @@ -196,7 +196,7 @@ class WifiLegacyHal { const std::string& iface_name); std::pair> requestFirmwareMemoryDump( const std::string& iface_name); - std::pair getSupportedFeatureSet( + std::pair getSupportedFeatureSet( const std::string& iface_name); // APF functions. std::pair getPacketFilterCapabilities( -- GitLab From 5cbf6276f5ccd0c8a7d3b6f979a3b2f557c5c229 Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Sun, 29 Dec 2019 21:31:56 +0200 Subject: [PATCH 127/790] Wifi: support 60GHz (Wigig) band Update WifiBand enum with new bands to support 60GHz band: BAND_60GHZ - 60GHz band BAND_24GHZ_5GHZ_6GHZ_60GHZ - 2.4 GHz + 5 GHz (no DFS) + 6GHz + 60GHz BAND_24GHZ_5GHZ_WITH_DFS_6GHZ_60GHZ - 2.4 GHz + 5 GHz with DFS + 6GHz + 60GHz Bug: 147495506 Test: atest VtsHalWifiV1_0TargetTest VtsHalWifiNanV1_0TargetTest VtsHalWifiApV1_0TargetTest \ VtsHalWifiV1_1TargetTest \ VtsHalWifiV1_2TargetTest VtsHalWifiNanV1_2TargetTest \ VtsHalWifiV1_3TargetTest \ VtsHalWifiApV1_4TargetTest VtsHalWifiNanV1_4TargetTest VtsHalWifiRttV1_4TargetTest Change-Id: I7c7cc514b88b999cc33e9573ac65910c0c53417a --- wifi/1.5/Android.bp | 1 + wifi/1.5/types.hal | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 wifi/1.5/types.hal diff --git a/wifi/1.5/Android.bp b/wifi/1.5/Android.bp index 4492521109..53047603b9 100644 --- a/wifi/1.5/Android.bp +++ b/wifi/1.5/Android.bp @@ -4,6 +4,7 @@ hidl_interface { name: "android.hardware.wifi@1.5", root: "android.hardware", srcs: [ + "types.hal", "IWifi.hal", "IWifiChip.hal", ], diff --git a/wifi/1.5/types.hal b/wifi/1.5/types.hal new file mode 100644 index 0000000000..71f0679ed9 --- /dev/null +++ b/wifi/1.5/types.hal @@ -0,0 +1,37 @@ +/* + * 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. + */ + +package android.hardware.wifi@1.5; + +import @1.0::WifiBand; + +/** + * Wifi bands defined in 80211 spec. + */ +enum WifiBand : @1.0::WifiBand { + /** + * 60 GHz. + */ + BAND_60GHZ = 16, + /** + * 2.4 GHz + 5 GHz no DFS + 6 GHz + 60 GHz. + */ + BAND_24GHZ_5GHZ_6GHZ_60GHZ = 27, + /** + * 2.4 GHz + 5 GHz with DFS + 6 GHz + 60 GHz. + */ + BAND_24GHZ_5GHZ_WITH_DFS_6GHZ_60GHZ = 31, +}; -- GitLab From a3b16c2d8e3354d848dfb18826ce89d2bdb6460e Mon Sep 17 00:00:00 2001 From: Kai Date: Tue, 1 Sep 2020 21:40:22 -0700 Subject: [PATCH 128/790] Add configArray for Gear_Selection in google VHAL ConfigArray in Gear_Selection indicates the supported Gear Bug: 165942804 Test: build and check value in emulator Change-Id: I4567031a072edda550b671bc190934d24d5b5eba --- .../vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h index 16c33b9d19..5446d4c7fa 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h @@ -674,6 +674,12 @@ const ConfigDeclaration kVehicleProperties[]{ .prop = toInt(VehicleProperty::GEAR_SELECTION), .access = VehiclePropertyAccess::READ, .changeMode = VehiclePropertyChangeMode::ON_CHANGE, + .configArray = {(int)VehicleGear::GEAR_PARK, + (int)VehicleGear::GEAR_NEUTRAL, + (int)VehicleGear::GEAR_REVERSE, + (int)VehicleGear::GEAR_DRIVE, (int)VehicleGear::GEAR_1, + (int)VehicleGear::GEAR_2, (int)VehicleGear::GEAR_3, + (int)VehicleGear::GEAR_4, (int)VehicleGear::GEAR_5}, }, .initialValue = {.int32Values = {toInt(VehicleGear::GEAR_PARK)}}}, -- GitLab From 4aee25fa696fcd2ffabfb8d2bab5c14e8272e61c Mon Sep 17 00:00:00 2001 From: lesl Date: Mon, 17 Aug 2020 17:55:59 +0800 Subject: [PATCH 129/790] wifi: Add Mobile Hotspot(MHS) info callback The info includes AP's frequency, bandwidth and generation(operational mode). Bug: 163288112 Test: Manuel Test. Hotspot works normally. Test: atest VtsHalWifiHostapdV1_0TargetTest Test: atest VtsHalWifiHostapdV1_1TargetTest Test: atest VtsHalWifiHostapdV1_2TargetTest Change-Id: I5ff640169f10178fac196d17cadbfeedd2787fc0 --- wifi/hostapd/1.3/IHostapdCallback.hal | 20 ++++++++++++++++++-- wifi/hostapd/1.3/types.hal | 15 ++++++++++++++- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/wifi/hostapd/1.3/IHostapdCallback.hal b/wifi/hostapd/1.3/IHostapdCallback.hal index 4db470de43..98cde67f71 100644 --- a/wifi/hostapd/1.3/IHostapdCallback.hal +++ b/wifi/hostapd/1.3/IHostapdCallback.hal @@ -18,18 +18,34 @@ package android.hardware.wifi.hostapd@1.3; import @1.1::IHostapdCallback; import @1.2::MacAddress; +import Bandwidth; import Generation; /** * Top-level callback object for managing SoftAPs. */ interface IHostapdCallback extends @1.1::IHostapdCallback { - oneway onInterfaceInfoChanged(string ifaceName, Generation generation); + /** + * Invoked when information changes for one of the AP instances. + * + * @param ifaceName Name of the interface which was added via + * |IHostapd.addAccessPoint|. + * @param apIfaceInstance The identity of the AP instance. The interface + * will have two instances (e.q. 2.4 Ghz AP and 5 GHz AP) in dual AP mode. + * The apIfaceInstance can be used to identify which instance the callback + * is from. + * Note: The apIfaceInstance must be same as ifaceName in single AP mode. + * @param freq The operational frequency of the AP. + * @param bandwidth The operational bandwidth of the AP. + * @param generation The operational mode of the AP (e.g. 11ac, 11ax). + */ + oneway onApInstanceInfoChanged(string ifaceName, string apIfaceInstance, uint32_t freq, + Bandwidth bandwidth, Generation generation); /** * Invoked when a client connects/disconnects from the hotspot. * - * @param ifaceName Name of the interface which is added via + * @param ifaceName Name of the interface which was added via * |IHostapd.addAccessPoint|. * @param apIfaceInstance The identity of the AP instance. The interface * will have two instances in dual AP mode. The apIfaceInstance can be used diff --git a/wifi/hostapd/1.3/types.hal b/wifi/hostapd/1.3/types.hal index 887ea0fc25..de85043e84 100644 --- a/wifi/hostapd/1.3/types.hal +++ b/wifi/hostapd/1.3/types.hal @@ -17,7 +17,7 @@ package android.hardware.wifi.hostapd@1.3; /** - * The wifi generation which AP reside on. + * The wifi operational mode of the AP. * It depends on hw mode and HT/VHT capabilities in hostapd. * * WIFI_STANDARD_LEGACY = (hw_mode is HOSTAPD_MODE_IEEE80211B) or @@ -34,3 +34,16 @@ enum Generation : uint32_t { WIFI_STANDARD_11AC = 2, WIFI_STANDARD_11AX = 3, }; + +/** + * The channel bandwidth of the AP. + */ +enum Bandwidth : uint32_t { + WIFI_BANDWIDTH_INVALID = 0, + WIFI_BANDWIDTH_20_NOHT = 1, + WIFI_BANDWIDTH_20 = 2, + WIFI_BANDWIDTH_40 = 3, + WIFI_BANDWIDTH_80 = 4, + WIFI_BANDWIDTH_80P80 = 5, + WIFI_BANDWIDTH_160 = 6, +}; -- GitLab From 17f8eac2a42ea935ff30583c865a8c6bd1de9b38 Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Mon, 17 Aug 2020 16:52:13 -0700 Subject: [PATCH 130/790] Add linkCicam API in Frontend 1.1 This API is mostly for restoring the by-pass mode Frontend and Cicam connection Test: make Bug: 158818696 Change-Id: I62ba19a1c6c531769db6286d3bcd41ab1529bb99 --- tv/tuner/1.1/IFrontend.hal | 14 ++++++++++++++ tv/tuner/1.1/default/Frontend.cpp | 8 ++++++++ tv/tuner/1.1/default/Frontend.h | 3 +++ 3 files changed, 25 insertions(+) diff --git a/tv/tuner/1.1/IFrontend.hal b/tv/tuner/1.1/IFrontend.hal index b570549d86..0b0ce39525 100644 --- a/tv/tuner/1.1/IFrontend.hal +++ b/tv/tuner/1.1/IFrontend.hal @@ -67,4 +67,18 @@ interface IFrontend extends @1.0::IFrontend { */ scan_1_1(FrontendSettings settings, FrontendScanType type, FrontendSettingsExt settingsExt) generates (Result result); + + /** + * Link Conditional Access Modules (CAM) to Frontend support Common Interface (CI) bypass mode. + * + * The client may use this to link CI-CAM to a frontend. CI bypass mode requires that the + * CICAM also receives the TS concurrently from the frontend when the Demux is receiving the TS + * directly from the frontend. + * + * @param ciCamId specify CI-CAM Id to link. + * @return result Result status of the operation. + * SUCCESS if successful, + * UNKNOWN_ERROR if failed for other reasons. + */ + linkCiCam(uint32_t ciCamId) generates (Result result); }; diff --git a/tv/tuner/1.1/default/Frontend.cpp b/tv/tuner/1.1/default/Frontend.cpp index 1e9435ba7e..467d54776b 100644 --- a/tv/tuner/1.1/default/Frontend.cpp +++ b/tv/tuner/1.1/default/Frontend.cpp @@ -273,6 +273,14 @@ Return Frontend::setLnb(uint32_t /* lnb */) { return Result::SUCCESS; } +Return Frontend::linkCiCam(uint32_t ciCamId) { + ALOGV("%s", __FUNCTION__); + + mCiCamId = ciCamId; + + return Result::SUCCESS; +} + FrontendType Frontend::getFrontendType() { return mType; } diff --git a/tv/tuner/1.1/default/Frontend.h b/tv/tuner/1.1/default/Frontend.h index d44f4aea7d..6a80232b21 100644 --- a/tv/tuner/1.1/default/Frontend.h +++ b/tv/tuner/1.1/default/Frontend.h @@ -62,6 +62,8 @@ class Frontend : public V1_1::IFrontend { virtual Return setLnb(uint32_t lnb) override; + virtual Return linkCiCam(uint32_t ciCamId) override; + FrontendType getFrontendType(); FrontendId getFrontendId(); @@ -78,6 +80,7 @@ class Frontend : public V1_1::IFrontend { FrontendType mType = FrontendType::UNDEFINED; FrontendId mId = 0; bool mIsLocked = false; + uint32_t mCiCamId; std::ifstream mFrontendData; }; -- GitLab From bd5244642004d868028d674248d58e9e1bde878d Mon Sep 17 00:00:00 2001 From: Benjamin Schwartz Date: Mon, 31 Aug 2020 14:25:06 -0700 Subject: [PATCH 131/790] powerstats: Simplify Power Stats HAL API Removing unused types, and statuses. Removing getPowerEntityStateSpace and moving that functionality into getPowerEntityInfo. Bug: 167218032 Test: m Change-Id: I6dabd18a41338e715713f43c2e009003dcc003b6 --- .../hardware/powerstats/IPowerStats.aidl | 6 --- .../hardware/powerstats/PowerEntityInfo.aidl | 2 +- .../powerstats/PowerEntityStateSpace.aidl | 23 ------------ .../hardware/powerstats/PowerEntityType.aidl | 24 ------------ .../hardware/powerstats/IPowerStats.aidl | 22 ----------- .../hardware/powerstats/PowerEntityInfo.aidl | 6 +-- .../powerstats/PowerEntityStateSpace.aidl | 37 ------------------- .../hardware/powerstats/PowerEntityType.aidl | 37 ------------------- powerstats/aidl/default/PowerStats.cpp | 9 +---- powerstats/aidl/default/PowerStats.h | 3 -- 10 files changed, 6 insertions(+), 163 deletions(-) delete mode 100644 powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityStateSpace.aidl delete mode 100644 powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityType.aidl delete mode 100644 powerstats/aidl/android/hardware/powerstats/PowerEntityStateSpace.aidl delete mode 100644 powerstats/aidl/android/hardware/powerstats/PowerEntityType.aidl diff --git a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/IPowerStats.aidl b/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/IPowerStats.aidl index b13f0c7c97..6772f6f3c4 100644 --- a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/IPowerStats.aidl +++ b/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/IPowerStats.aidl @@ -20,12 +20,6 @@ package android.hardware.powerstats; interface IPowerStats { android.hardware.powerstats.EnergyData[] getEnergyData(in int[] railIndices); android.hardware.powerstats.PowerEntityInfo[] getPowerEntityInfo(); - android.hardware.powerstats.PowerEntityStateSpace[] getPowerEntityStateInfo(in int[] powerEntityIds); android.hardware.powerstats.PowerEntityStateResidencyResult[] getPowerEntityStateResidencyData(in int[] powerEntityIds); android.hardware.powerstats.RailInfo[] getRailInfo(); - const int SUCCESS = 0; - const int NOT_SUPPORTED = 1; - const int INVALID_INPUT = 2; - const int FILESYSTEM_ERROR = 3; - const int INSUFFICIENT_RESOURCES = 4; } diff --git a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityInfo.aidl b/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityInfo.aidl index 8cacd55b0a..016af91839 100644 --- a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityInfo.aidl +++ b/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityInfo.aidl @@ -20,5 +20,5 @@ package android.hardware.powerstats; parcelable PowerEntityInfo { int powerEntityId; String powerEntityName; - android.hardware.powerstats.PowerEntityType type; + android.hardware.powerstats.PowerEntityStateInfo[] states; } diff --git a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityStateSpace.aidl b/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityStateSpace.aidl deleted file mode 100644 index 0508fea7e0..0000000000 --- a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityStateSpace.aidl +++ /dev/null @@ -1,23 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // -/////////////////////////////////////////////////////////////////////////////// - -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. -// -// You must not make a backward incompatible changes to the AIDL files 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.powerstats; -@VintfStability -parcelable PowerEntityStateSpace { - int powerEntityId; - android.hardware.powerstats.PowerEntityStateInfo[] states; -} diff --git a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityType.aidl b/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityType.aidl deleted file mode 100644 index 5deefa9dd8..0000000000 --- a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityType.aidl +++ /dev/null @@ -1,24 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // -/////////////////////////////////////////////////////////////////////////////// - -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. -// -// You must not make a backward incompatible changes to the AIDL files 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.powerstats; -@Backing(type="int") @VintfStability -enum PowerEntityType { - SUBSYSTEM = 0, - PERIPHERAL = 1, - POWER_DOMAIN = 2, -} diff --git a/powerstats/aidl/android/hardware/powerstats/IPowerStats.aidl b/powerstats/aidl/android/hardware/powerstats/IPowerStats.aidl index f8f69e0b5f..93d1448376 100644 --- a/powerstats/aidl/android/hardware/powerstats/IPowerStats.aidl +++ b/powerstats/aidl/android/hardware/powerstats/IPowerStats.aidl @@ -19,17 +19,10 @@ package android.hardware.powerstats; import android.hardware.powerstats.EnergyData; import android.hardware.powerstats.PowerEntityInfo; import android.hardware.powerstats.PowerEntityStateResidencyResult; -import android.hardware.powerstats.PowerEntityStateSpace; import android.hardware.powerstats.RailInfo; @VintfStability interface IPowerStats { - const int SUCCESS = 0; - const int NOT_SUPPORTED = 1; - const int INVALID_INPUT = 2; - const int FILESYSTEM_ERROR = 3; - const int INSUFFICIENT_RESOURCES = 4; - /** * Rail level energy measurements for low frequency clients: * Reports accumulated energy since boot on each rail. @@ -52,21 +45,6 @@ interface IPowerStats { */ PowerEntityInfo[] getPowerEntityInfo(); - /** - * PowerEntity state information: - * Reports the set of power states for which the specified - * PowerEntity(s) provide residency data. - * - * @param powerEntityIds collection of IDs of PowerEntity(s) for which - * state information is requested. PowerEntity name to ID mapping may - * be queried from getPowerEntityInfo(). To get state space - * information for all PowerEntity(s) pass an empty vector. - * - * @return PowerEntity state space information for - * each specified PowerEntity that provides state space information. - */ - PowerEntityStateSpace[] getPowerEntityStateInfo(in int[] powerEntityIds); - /** * PowerEntity residencies for low frequency clients: * Reports accumulated residency data for each specified PowerEntity. diff --git a/powerstats/aidl/android/hardware/powerstats/PowerEntityInfo.aidl b/powerstats/aidl/android/hardware/powerstats/PowerEntityInfo.aidl index 2b5b352673..72222a627e 100644 --- a/powerstats/aidl/android/hardware/powerstats/PowerEntityInfo.aidl +++ b/powerstats/aidl/android/hardware/powerstats/PowerEntityInfo.aidl @@ -16,7 +16,7 @@ package android.hardware.powerstats; -import android.hardware.powerstats.PowerEntityType; +import android.hardware.powerstats.PowerEntityStateInfo; /** * PowerEntityInfo contains information, such as the ID, name, and type of a @@ -33,7 +33,7 @@ parcelable PowerEntityInfo { */ String powerEntityName; /** - * Type of the PowerEntity + * List of states that the PowerEntity may reside in */ - PowerEntityType type; + PowerEntityStateInfo[] states; } \ No newline at end of file diff --git a/powerstats/aidl/android/hardware/powerstats/PowerEntityStateSpace.aidl b/powerstats/aidl/android/hardware/powerstats/PowerEntityStateSpace.aidl deleted file mode 100644 index 8e3066515f..0000000000 --- a/powerstats/aidl/android/hardware/powerstats/PowerEntityStateSpace.aidl +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.hardware.powerstats; - -import android.hardware.powerstats.PowerEntityStateInfo; - -/** - * PowerEntityStateSpace contains the state space information of a given - * PowerEntity. The state space, is the set of possible states that a given - * PowerEntity provides residency data for. - */ -@VintfStability -parcelable PowerEntityStateSpace { - /** - * Unique ID of the corresponding PowerEntity - */ - int powerEntityId; - /** - * List of states that the PowerEntity may reside in - */ - PowerEntityStateInfo[] states; -} - diff --git a/powerstats/aidl/android/hardware/powerstats/PowerEntityType.aidl b/powerstats/aidl/android/hardware/powerstats/PowerEntityType.aidl deleted file mode 100644 index a8cd0b71c1..0000000000 --- a/powerstats/aidl/android/hardware/powerstats/PowerEntityType.aidl +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.hardware.powerstats; - -@VintfStability -@Backing(type="int") -enum PowerEntityType { - /** - * A subsystem is a self-contained compute unit. Some examples include - * application processor, DSP, GPU. - */ - SUBSYSTEM = 0, - /** - * A peripheral is an auxiliary device that connects to and works with a - * compute unit. Some examples include simple sensors, camera, display. - */ - PERIPHERAL = 1, - /** - * A power domain is a single subsystem or a collection of subsystems - * that is controlled by a single voltage rail. - */ - POWER_DOMAIN = 2, -} \ No newline at end of file diff --git a/powerstats/aidl/default/PowerStats.cpp b/powerstats/aidl/default/PowerStats.cpp index 50a829e133..8d6a0ee4aa 100644 --- a/powerstats/aidl/default/PowerStats.cpp +++ b/powerstats/aidl/default/PowerStats.cpp @@ -34,13 +34,7 @@ ndk::ScopedAStatus PowerStats::getPowerEntityInfo(std::vector* (void)_aidl_return; return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus PowerStats::getPowerEntityStateInfo( - const std::vector& in_powerEntityIds, - std::vector* _aidl_return) { - (void)in_powerEntityIds; - (void)_aidl_return; - return ndk::ScopedAStatus::ok(); -} + ndk::ScopedAStatus PowerStats::getPowerEntityStateResidencyData( const std::vector& in_powerEntityIds, std::vector* _aidl_return) { @@ -48,6 +42,7 @@ ndk::ScopedAStatus PowerStats::getPowerEntityStateResidencyData( (void)_aidl_return; return ndk::ScopedAStatus::ok(); } + ndk::ScopedAStatus PowerStats::getRailInfo(std::vector* _aidl_return) { (void)_aidl_return; return ndk::ScopedAStatus::ok(); diff --git a/powerstats/aidl/default/PowerStats.h b/powerstats/aidl/default/PowerStats.h index 392d1e6042..49240cb718 100644 --- a/powerstats/aidl/default/PowerStats.h +++ b/powerstats/aidl/default/PowerStats.h @@ -29,9 +29,6 @@ class PowerStats : public BnPowerStats { ndk::ScopedAStatus getEnergyData(const std::vector& in_railIndices, std::vector* _aidl_return) override; ndk::ScopedAStatus getPowerEntityInfo(std::vector* _aidl_return) override; - ndk::ScopedAStatus getPowerEntityStateInfo( - const std::vector& in_powerEntityIds, - std::vector* _aidl_return) override; ndk::ScopedAStatus getPowerEntityStateResidencyData( const std::vector& in_powerEntityIds, std::vector* _aidl_return) override; -- GitLab From c4529fb13a6517bd3b55ac50ba8870fe263929aa Mon Sep 17 00:00:00 2001 From: Benjamin Schwartz Date: Tue, 1 Sep 2020 11:57:53 -0700 Subject: [PATCH 132/790] powerstats: Add VTS tests for PowerStats HAL 2.0 Adding tests to validate getPowerEntityInfo Bug: 165345767 Test: atest VtsHalPowerStatsTargetTest Change-Id: I4e63cb0cd94b37be25b9f20fe308c9d38a452146 --- .../aidl/vts/VtsHalPowerStatsTargetTest.cpp | 73 +++++++++++++++++-- 1 file changed, 66 insertions(+), 7 deletions(-) diff --git a/powerstats/aidl/vts/VtsHalPowerStatsTargetTest.cpp b/powerstats/aidl/vts/VtsHalPowerStatsTargetTest.cpp index fc0e659ec7..b3cd233945 100644 --- a/powerstats/aidl/vts/VtsHalPowerStatsTargetTest.cpp +++ b/powerstats/aidl/vts/VtsHalPowerStatsTargetTest.cpp @@ -25,7 +25,6 @@ using aidl::android::hardware::powerstats::EnergyData; using aidl::android::hardware::powerstats::IPowerStats; using aidl::android::hardware::powerstats::PowerEntityInfo; using aidl::android::hardware::powerstats::PowerEntityStateResidencyResult; -using aidl::android::hardware::powerstats::PowerEntityStateSpace; using aidl::android::hardware::powerstats::RailInfo; using ndk::SpAIBinder; @@ -45,14 +44,74 @@ TEST_P(PowerStatsAidl, TestGetEnergyData) { ASSERT_TRUE(powerstats->getEnergyData({}, &data).isOk()); } -TEST_P(PowerStatsAidl, TestGetPowerEntityInfo) { - std::vector info; - ASSERT_TRUE(powerstats->getPowerEntityInfo(&info).isOk()); +// Each PowerEntity must have a valid name +TEST_P(PowerStatsAidl, ValidatePowerEntityNames) { + std::vector infos; + ASSERT_TRUE(powerstats->getPowerEntityInfo(&infos).isOk()); + + for (auto info : infos) { + EXPECT_NE(info.powerEntityName, ""); + } +} + +// Each power entity must have a unique name +TEST_P(PowerStatsAidl, ValidatePowerEntityUniqueNames) { + std::vector infos; + ASSERT_TRUE(powerstats->getPowerEntityInfo(&infos).isOk()); + + std::set names; + for (auto info : infos) { + EXPECT_TRUE(names.insert(info.powerEntityName).second); + } +} + +// Each PowerEntity must have a unique ID +TEST_P(PowerStatsAidl, ValidatePowerEntityIds) { + std::vector infos; + ASSERT_TRUE(powerstats->getPowerEntityInfo(&infos).isOk()); + + std::set ids; + for (auto info : infos) { + EXPECT_TRUE(ids.insert(info.powerEntityId).second); + } } -TEST_P(PowerStatsAidl, TestGetPowerEntityStateInfo) { - std::vector info; - ASSERT_TRUE(powerstats->getPowerEntityStateInfo({}, &info).isOk()); +// Each state must have a valid name +TEST_P(PowerStatsAidl, ValidateStateNames) { + std::vector infos; + ASSERT_TRUE(powerstats->getPowerEntityInfo(&infos).isOk()); + + for (auto info : infos) { + for (auto state : info.states) { + EXPECT_NE(state.powerEntityStateName, ""); + } + } +} + +// Each state must have a name that is unique to the given PowerEntity +TEST_P(PowerStatsAidl, ValidateStateUniqueNames) { + std::vector infos; + ASSERT_TRUE(powerstats->getPowerEntityInfo(&infos).isOk()); + + for (auto info : infos) { + std::set stateNames; + for (auto state : info.states) { + EXPECT_TRUE(stateNames.insert(state.powerEntityStateName).second); + } + } +} + +// Each state must have an ID that is unique to the given PowerEntity +TEST_P(PowerStatsAidl, ValidateStateUniqueIds) { + std::vector infos; + ASSERT_TRUE(powerstats->getPowerEntityInfo(&infos).isOk()); + + for (auto info : infos) { + std::set stateIds; + for (auto state : info.states) { + EXPECT_TRUE(stateIds.insert(state.powerEntityStateId).second); + } + } } TEST_P(PowerStatsAidl, TestGetPowerEntityStateResidencyData) { -- GitLab From 6b0fd062bb35954705fad8d90e64a06e743ff9f1 Mon Sep 17 00:00:00 2001 From: Dan Shi Date: Tue, 8 Sep 2020 10:42:38 -0700 Subject: [PATCH 133/790] Suppress gtest error for tests without any instance Bug: 162052785 Test: m -j vts Change-Id: I627d6790aa08aa9c6e3c5b8bdc533213ee08de21 --- .../vts/functional/6.0/AudioPrimaryHidlHalTest.cpp | 3 +++ .../1.0/vts/functional/VtsHalBroadcastradioV1_0TargetTest.cpp | 1 + .../1.1/vts/functional/VtsHalBroadcastradioV1_1TargetTest.cpp | 1 + drm/1.0/vts/functional/drm_hal_test_main.cpp | 3 +++ drm/1.3/vts/functional/drm_hal_test_main.cpp | 3 +++ .../vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp | 1 + .../vts/functional/store/VtsHalMediaOmxV1_0TargetStoreTest.cpp | 1 + .../functional/VtsHalTetheroffloadControlV1_0TargetTest.cpp | 2 ++ wifi/hostapd/1.1/vts/functional/hostapd_hidl_test.cpp | 1 + wifi/hostapd/1.2/vts/functional/hostapd_hidl_test.cpp | 1 + wifi/supplicant/1.0/vts/functional/supplicant_hidl_test.cpp | 1 + .../1.0/vts/functional/supplicant_p2p_iface_hidl_test.cpp | 1 + .../1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp | 1 + .../1.0/vts/functional/supplicant_sta_network_hidl_test.cpp | 1 + wifi/supplicant/1.1/vts/functional/supplicant_hidl_test.cpp | 1 + .../1.1/vts/functional/supplicant_sta_iface_hidl_test.cpp | 1 + .../1.1/vts/functional/supplicant_sta_network_hidl_test.cpp | 1 + .../1.2/vts/functional/supplicant_p2p_iface_hidl_test.cpp | 1 + .../1.2/vts/functional/supplicant_sta_iface_hidl_test.cpp | 1 + .../1.2/vts/functional/supplicant_sta_network_hidl_test.cpp | 1 + .../1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp | 1 + .../1.3/vts/functional/supplicant_sta_network_hidl_test.cpp | 1 + .../1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp | 1 + 23 files changed, 30 insertions(+) diff --git a/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp index e09eeab4eb..54d4bbd2cc 100644 --- a/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp +++ b/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp @@ -152,6 +152,7 @@ TEST_P(DualMonoModeAccessorHidlTest, DualMonoModeTest) { &IStreamOut::setDualMonoMode, &IStreamOut::getDualMonoMode); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DualMonoModeAccessorHidlTest); INSTANTIATE_TEST_CASE_P(DualMonoModeHidl, DualMonoModeAccessorHidlTest, ::testing::ValuesIn(getOutputDeviceConfigParameters()), &DeviceConfigParameterToString); @@ -166,6 +167,7 @@ TEST_P(AudioDescriptionMixLevelHidlTest, AudioDescriptionMixLevelTest) { {48.5f, 1000.0f, std::numeric_limits::infinity()}); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioDescriptionMixLevelHidlTest); INSTANTIATE_TEST_CASE_P(AudioDescriptionMixLevelHidl, AudioDescriptionMixLevelHidlTest, ::testing::ValuesIn(getOutputDeviceConfigParameters()), &DeviceConfigParameterToString); @@ -200,6 +202,7 @@ TEST_P(PlaybackRateParametersHidlTest, PlaybackRateParametersTest) { TimestretchFallbackMode::FAIL}}); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(PlaybackRateParametersHidlTest); INSTANTIATE_TEST_CASE_P(PlaybackRateParametersHidl, PlaybackRateParametersHidlTest, ::testing::ValuesIn(getOutputDeviceConfigParameters()), &DeviceConfigParameterToString); diff --git a/broadcastradio/1.0/vts/functional/VtsHalBroadcastradioV1_0TargetTest.cpp b/broadcastradio/1.0/vts/functional/VtsHalBroadcastradioV1_0TargetTest.cpp index 9897ab7af5..cac3dd0eae 100644 --- a/broadcastradio/1.0/vts/functional/VtsHalBroadcastradioV1_0TargetTest.cpp +++ b/broadcastradio/1.0/vts/functional/VtsHalBroadcastradioV1_0TargetTest.cpp @@ -728,6 +728,7 @@ TEST_P(BroadcastRadioHidlTest, IbImagesOnly) { } } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BroadcastRadioHidlTest); INSTANTIATE_TEST_CASE_P( PerInstance, BroadcastRadioHidlTest, testing::Combine(testing::ValuesIn(android::hardware::getAllHalInstanceNames( diff --git a/broadcastradio/1.1/vts/functional/VtsHalBroadcastradioV1_1TargetTest.cpp b/broadcastradio/1.1/vts/functional/VtsHalBroadcastradioV1_1TargetTest.cpp index 4833beb5bb..caf6cbd982 100644 --- a/broadcastradio/1.1/vts/functional/VtsHalBroadcastradioV1_1TargetTest.cpp +++ b/broadcastradio/1.1/vts/functional/VtsHalBroadcastradioV1_1TargetTest.cpp @@ -600,6 +600,7 @@ TEST_P(BroadcastRadioHalTest, VerifyIdentifiersFormat) { } while (nextBand()); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BroadcastRadioHalTest); INSTANTIATE_TEST_CASE_P( PerInstance, BroadcastRadioHalTest, testing::Combine(testing::ValuesIn(android::hardware::getAllHalInstanceNames( diff --git a/drm/1.0/vts/functional/drm_hal_test_main.cpp b/drm/1.0/vts/functional/drm_hal_test_main.cpp index 25571368f4..ccbf51e7c1 100644 --- a/drm/1.0/vts/functional/drm_hal_test_main.cpp +++ b/drm/1.0/vts/functional/drm_hal_test_main.cpp @@ -51,14 +51,17 @@ static const std::vector kAllInstances = [] { return allInstanceUuidCombos; }(); +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DrmHalVendorFactoryTest); INSTANTIATE_TEST_CASE_P(DrmHalVendorFactoryTestCases, DrmHalVendorFactoryTest, testing::ValuesIn(kAllInstances), drm_vts::PrintParamInstanceToString); +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DrmHalVendorPluginTest); INSTANTIATE_TEST_CASE_P(DrmHalVendorPluginTestCases, DrmHalVendorPluginTest, testing::ValuesIn(kAllInstances), drm_vts::PrintParamInstanceToString); +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DrmHalVendorDecryptTest); INSTANTIATE_TEST_CASE_P(DrmHalVendorDecryptTestCases, DrmHalVendorDecryptTest, testing::ValuesIn(kAllInstances), drm_vts::PrintParamInstanceToString); diff --git a/drm/1.3/vts/functional/drm_hal_test_main.cpp b/drm/1.3/vts/functional/drm_hal_test_main.cpp index 746f09ee0b..8abba694d7 100644 --- a/drm/1.3/vts/functional/drm_hal_test_main.cpp +++ b/drm/1.3/vts/functional/drm_hal_test_main.cpp @@ -81,12 +81,15 @@ static const std::vector kAllInstances = [] { return allInstanceUuidCombos; }(); +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DrmHalVendorFactoryTest); INSTANTIATE_TEST_CASE_P(PerInstanceUuidV1_0, DrmHalVendorFactoryTest, testing::ValuesIn(kAllInstances), drm_vts::PrintParamInstanceToString); +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DrmHalVendorPluginTest); INSTANTIATE_TEST_CASE_P(PerInstanceUuidV1_0, DrmHalVendorPluginTest, testing::ValuesIn(kAllInstances), drm_vts::PrintParamInstanceToString); +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DrmHalVendorDecryptTest); INSTANTIATE_TEST_CASE_P(PerInstanceUuidV1_0, DrmHalVendorDecryptTest, testing::ValuesIn(kAllInstances), drm_vts::PrintParamInstanceToString); diff --git a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp index 26163fd1a4..f522731ec9 100644 --- a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp +++ b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp @@ -1387,6 +1387,7 @@ INSTANTIATE_TEST_SUITE_P( testing::ValuesIn(android::hardware::getAllHalInstanceNames(IComposer::descriptor)), android::hardware::PrintInstanceNameToString); +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsBlendModeCompositionTest); INSTANTIATE_TEST_CASE_P( BlendModeTest, GraphicsBlendModeCompositionTest, testing::Combine( diff --git a/media/omx/1.0/vts/functional/store/VtsHalMediaOmxV1_0TargetStoreTest.cpp b/media/omx/1.0/vts/functional/store/VtsHalMediaOmxV1_0TargetStoreTest.cpp index 8c36347dda..e73196cfb2 100644 --- a/media/omx/1.0/vts/functional/store/VtsHalMediaOmxV1_0TargetStoreTest.cpp +++ b/media/omx/1.0/vts/functional/store/VtsHalMediaOmxV1_0TargetStoreTest.cpp @@ -418,6 +418,7 @@ TEST_P(StoreHidlTest, ListNodes) { EXPECT_TRUE(isPass); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(StoreHidlTest); INSTANTIATE_TEST_CASE_P( PerInstance, StoreHidlTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames(IOmxStore::descriptor)), diff --git a/tetheroffload/control/1.0/vts/functional/VtsHalTetheroffloadControlV1_0TargetTest.cpp b/tetheroffload/control/1.0/vts/functional/VtsHalTetheroffloadControlV1_0TargetTest.cpp index b422b2f543..d3a70202e2 100644 --- a/tetheroffload/control/1.0/vts/functional/VtsHalTetheroffloadControlV1_0TargetTest.cpp +++ b/tetheroffload/control/1.0/vts/functional/VtsHalTetheroffloadControlV1_0TargetTest.cpp @@ -675,6 +675,7 @@ TEST_P(OffloadControlHidlTest, RemoveDownstreamBogusPrefixFails) { } } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(OffloadControlHidlTestBase); INSTANTIATE_TEST_CASE_P( PerInstance, OffloadControlHidlTestBase, testing::Combine( @@ -684,6 +685,7 @@ INSTANTIATE_TEST_CASE_P( android::hardware::getAllHalInstanceNames(IOffloadControl::descriptor))), android::hardware::PrintInstanceTupleNameToString<>); +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(OffloadControlHidlTest); INSTANTIATE_TEST_CASE_P( PerInstance, OffloadControlHidlTest, testing::Combine( diff --git a/wifi/hostapd/1.1/vts/functional/hostapd_hidl_test.cpp b/wifi/hostapd/1.1/vts/functional/hostapd_hidl_test.cpp index 0162a9918e..3944a3a9cd 100644 --- a/wifi/hostapd/1.1/vts/functional/hostapd_hidl_test.cpp +++ b/wifi/hostapd/1.1/vts/functional/hostapd_hidl_test.cpp @@ -318,6 +318,7 @@ TEST_P(HostapdHidlTest, AddInvalidPskAccessPointWithoutAcs) { EXPECT_NE(HostapdStatusCode::SUCCESS, status.code); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(HostapdHidlTest); INSTANTIATE_TEST_CASE_P( PerInstance, HostapdHidlTest, testing::Combine( diff --git a/wifi/hostapd/1.2/vts/functional/hostapd_hidl_test.cpp b/wifi/hostapd/1.2/vts/functional/hostapd_hidl_test.cpp index a39f064aab..62e3c16072 100644 --- a/wifi/hostapd/1.2/vts/functional/hostapd_hidl_test.cpp +++ b/wifi/hostapd/1.2/vts/functional/hostapd_hidl_test.cpp @@ -414,6 +414,7 @@ TEST_P(HostapdHidlTest, SetDebugParams) { EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(HostapdHidlTest); INSTANTIATE_TEST_CASE_P( PerInstance, HostapdHidlTest, testing::Combine( diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test.cpp b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test.cpp index 47f0394db1..ac39a24fa4 100644 --- a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test.cpp +++ b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test.cpp @@ -212,6 +212,7 @@ TEST_P(SupplicantHidlTest, SetConcurrencyPriority) { } } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantHidlTest); INSTANTIATE_TEST_CASE_P( PerInstance, SupplicantHidlTest, testing::Combine( diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_p2p_iface_hidl_test.cpp b/wifi/supplicant/1.0/vts/functional/supplicant_p2p_iface_hidl_test.cpp index c333c4f859..616869b26b 100644 --- a/wifi/supplicant/1.0/vts/functional/supplicant_p2p_iface_hidl_test.cpp +++ b/wifi/supplicant/1.0/vts/functional/supplicant_p2p_iface_hidl_test.cpp @@ -647,6 +647,7 @@ TEST_P(SupplicantP2pIfaceHidlTest, SetWfdDeviceInfo) { HIDL_INVOKE(p2p_iface_, setWfdDeviceInfo, kTestWfdDeviceInfo).code); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantP2pIfaceHidlTest); INSTANTIATE_TEST_CASE_P( PerInstance, SupplicantP2pIfaceHidlTest, testing::Combine( diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp index ff287541f8..e4fe52ca7e 100644 --- a/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp +++ b/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp @@ -558,6 +558,7 @@ TEST_P(SupplicantStaIfaceHidlTest, RemoveExtRadioWork) { HIDL_INVOKE(sta_iface_, removeExtRadioWork, kTestRadioWorkId).code); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantStaIfaceHidlTest); INSTANTIATE_TEST_CASE_P( PerInstance, SupplicantStaIfaceHidlTest, testing::Combine( diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_sta_network_hidl_test.cpp b/wifi/supplicant/1.0/vts/functional/supplicant_sta_network_hidl_test.cpp index 295ebfb808..7e93c5f4e9 100644 --- a/wifi/supplicant/1.0/vts/functional/supplicant_sta_network_hidl_test.cpp +++ b/wifi/supplicant/1.0/vts/functional/supplicant_sta_network_hidl_test.cpp @@ -839,6 +839,7 @@ TEST_P(SupplicantStaNetworkHidlTest, GetWpsNfcConfigurationToken) { EXPECT_FALSE(0 == status_and_token.second.size()); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantStaNetworkHidlTest); INSTANTIATE_TEST_CASE_P( PerInstance, SupplicantStaNetworkHidlTest, testing::Combine( diff --git a/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test.cpp b/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test.cpp index 24a7ec31aa..0e404e7f96 100644 --- a/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test.cpp +++ b/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test.cpp @@ -149,6 +149,7 @@ static std::vector get_wifi_instances() { return instances; } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantHidlTest); INSTANTIATE_TEST_CASE_P( PerInstance, SupplicantHidlTest, testing::Combine( diff --git a/wifi/supplicant/1.1/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.1/vts/functional/supplicant_sta_iface_hidl_test.cpp index 8a1aeccf7d..2fade4493d 100644 --- a/wifi/supplicant/1.1/vts/functional/supplicant_sta_iface_hidl_test.cpp +++ b/wifi/supplicant/1.1/vts/functional/supplicant_sta_iface_hidl_test.cpp @@ -140,6 +140,7 @@ TEST_P(SupplicantStaIfaceHidlTest, RegisterCallback_1_1) { }); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantStaIfaceHidlTest); INSTANTIATE_TEST_CASE_P( PerInstance, SupplicantStaIfaceHidlTest, testing::Combine( diff --git a/wifi/supplicant/1.1/vts/functional/supplicant_sta_network_hidl_test.cpp b/wifi/supplicant/1.1/vts/functional/supplicant_sta_network_hidl_test.cpp index a4b7d40b53..bd8a2ab2f7 100644 --- a/wifi/supplicant/1.1/vts/functional/supplicant_sta_network_hidl_test.cpp +++ b/wifi/supplicant/1.1/vts/functional/supplicant_sta_network_hidl_test.cpp @@ -93,6 +93,7 @@ TEST_P(SupplicantStaNetworkHidlTest, SendNetworkEapIdentityResponse_1_1) { }); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantStaNetworkHidlTest); INSTANTIATE_TEST_CASE_P( PerInstance, SupplicantStaNetworkHidlTest, testing::Combine( diff --git a/wifi/supplicant/1.2/vts/functional/supplicant_p2p_iface_hidl_test.cpp b/wifi/supplicant/1.2/vts/functional/supplicant_p2p_iface_hidl_test.cpp index cab160bc1f..75512d7035 100644 --- a/wifi/supplicant/1.2/vts/functional/supplicant_p2p_iface_hidl_test.cpp +++ b/wifi/supplicant/1.2/vts/functional/supplicant_p2p_iface_hidl_test.cpp @@ -162,6 +162,7 @@ TEST_P(SupplicantP2pIfaceHidlTest, EnableMacRandomization) { }); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantP2pIfaceHidlTest); INSTANTIATE_TEST_CASE_P( PerInstance, SupplicantP2pIfaceHidlTest, testing::Combine( diff --git a/wifi/supplicant/1.2/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.2/vts/functional/supplicant_sta_iface_hidl_test.cpp index 7377f780f2..184543b58d 100644 --- a/wifi/supplicant/1.2/vts/functional/supplicant_sta_iface_hidl_test.cpp +++ b/wifi/supplicant/1.2/vts/functional/supplicant_sta_iface_hidl_test.cpp @@ -460,6 +460,7 @@ TEST_P(SupplicantStaIfaceHidlTest, StartDppConfiguratorInitiator) { }); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantStaIfaceHidlTest); INSTANTIATE_TEST_CASE_P( PerInstance, SupplicantStaIfaceHidlTest, testing::Combine( diff --git a/wifi/supplicant/1.2/vts/functional/supplicant_sta_network_hidl_test.cpp b/wifi/supplicant/1.2/vts/functional/supplicant_sta_network_hidl_test.cpp index 54ceb20211..5a2f808949 100644 --- a/wifi/supplicant/1.2/vts/functional/supplicant_sta_network_hidl_test.cpp +++ b/wifi/supplicant/1.2/vts/functional/supplicant_sta_network_hidl_test.cpp @@ -222,6 +222,7 @@ TEST_P(SupplicantStaNetworkHidlTest, EnableTlsSuiteBEapPhase1Param) { }); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantStaNetworkHidlTest); INSTANTIATE_TEST_CASE_P( PerInstance, SupplicantStaNetworkHidlTest, testing::Combine( diff --git a/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp index 9b7b45db8c..221c393801 100644 --- a/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp +++ b/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp @@ -581,6 +581,7 @@ TEST_P(SupplicantStaIfaceHidlTest, FilsHlpFlushRequest) { EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); }); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantStaIfaceHidlTest); INSTANTIATE_TEST_CASE_P( PerInstance, SupplicantStaIfaceHidlTest, testing::Combine( diff --git a/wifi/supplicant/1.3/vts/functional/supplicant_sta_network_hidl_test.cpp b/wifi/supplicant/1.3/vts/functional/supplicant_sta_network_hidl_test.cpp index 5f60746845..11c55a6a20 100644 --- a/wifi/supplicant/1.3/vts/functional/supplicant_sta_network_hidl_test.cpp +++ b/wifi/supplicant/1.3/vts/functional/supplicant_sta_network_hidl_test.cpp @@ -348,6 +348,7 @@ TEST_P(SupplicantStaNetworkHidlTest, SetEapErp) { EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); }); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantStaNetworkHidlTest); INSTANTIATE_TEST_CASE_P( PerInstance, SupplicantStaNetworkHidlTest, testing::Combine( diff --git a/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp index 2a4f5348b4..0a20455dd5 100644 --- a/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp +++ b/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp @@ -83,6 +83,7 @@ TEST_P(SupplicantStaIfaceHidlTest, GetConnectionCapabilities) { }); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantStaIfaceHidlTest); INSTANTIATE_TEST_CASE_P( PerInstance, SupplicantStaIfaceHidlTest, testing::Combine( -- GitLab From 50c25280c1cfe14486097313c76834dd07fd30b8 Mon Sep 17 00:00:00 2001 From: chrisweir Date: Wed, 26 Aug 2020 13:32:46 -0700 Subject: [PATCH 134/790] Add support for poll()-ing nlsockets Adding support for polling netlink sockets. Bug: 168050726 Test: Verify that Netlink Proxy works Change-Id: I1e363a9c5cb77b10f247d27cc4e6a2428aa92211 --- automotive/can/1.0/default/libnl++/Socket.cpp | 4 ++++ .../can/1.0/default/libnl++/include/libnl++/Socket.h | 9 +++++++++ 2 files changed, 13 insertions(+) diff --git a/automotive/can/1.0/default/libnl++/Socket.cpp b/automotive/can/1.0/default/libnl++/Socket.cpp index 08683ca7bc..514d9bb1b9 100644 --- a/automotive/can/1.0/default/libnl++/Socket.cpp +++ b/automotive/can/1.0/default/libnl++/Socket.cpp @@ -153,6 +153,10 @@ std::optional Socket::getPid() { return sa.nl_pid; } +pollfd Socket::preparePoll(short events) { + return {mFd.get(), events, 0}; +} + Socket::receive_iterator::receive_iterator(Socket& socket, bool end) : mSocket(socket), mIsEnd(end) { if (!end) receive(); diff --git a/automotive/can/1.0/default/libnl++/include/libnl++/Socket.h b/automotive/can/1.0/default/libnl++/include/libnl++/Socket.h index c69523da3d..8ea3575720 100644 --- a/automotive/can/1.0/default/libnl++/include/libnl++/Socket.h +++ b/automotive/can/1.0/default/libnl++/include/libnl++/Socket.h @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -173,6 +174,14 @@ class Socket { */ std::optional getPid(); + /** + * Creates a pollfd object for the socket. + * + * \param events Value for pollfd.events. + * \return A populated pollfd object. + */ + pollfd preparePoll(short events = 0); + /** * Live iterator continuously receiving messages from Netlink socket. * -- GitLab From c5cd6b7c6dc862475641d851f98a3f7070b4131b Mon Sep 17 00:00:00 2001 From: Eric Jeong Date: Mon, 17 Aug 2020 17:13:48 -0700 Subject: [PATCH 135/790] Add vehicle properties to integrate car watchdog - WATCHDOG_ALIVE to tell car watchdog is alive - WATCHDOG_TERMINATED_PROCESS to pass a process information terminated - VHAL_HEARTBEAT to signal that VHAL is alive by car watchdog Bug: 159912961 Test: build okay Change-Id: I0498d525aa6465199f0b0011600234feaf7c4aa4 --- .../default/impl/vhal_v2_0/DefaultConfig.h | 24 +++++++ automotive/vehicle/2.0/types.hal | 66 +++++++++++++++++++ 2 files changed, 90 insertions(+) diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h index 16e1bf7291..fc83078314 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h @@ -1074,6 +1074,30 @@ const ConfigDeclaration kVehicleProperties[]{ .changeMode = VehiclePropertyChangeMode::ON_CHANGE, }, }, + { + .config = + { + .prop = toInt(VehicleProperty::WATCHDOG_ALIVE), + .access = VehiclePropertyAccess::WRITE, + .changeMode = VehiclePropertyChangeMode::ON_CHANGE, + }, + }, + { + .config = + { + .prop = toInt(VehicleProperty::WATCHDOG_TERMINATED_PROCESS), + .access = VehiclePropertyAccess::WRITE, + .changeMode = VehiclePropertyChangeMode::ON_CHANGE, + }, + }, + { + .config = + { + .prop = toInt(VehicleProperty::VHAL_HEARTBEAT), + .access = VehiclePropertyAccess::READ, + .changeMode = VehiclePropertyChangeMode::ON_CHANGE, + }, + }, }; } // impl diff --git a/automotive/vehicle/2.0/types.hal b/automotive/vehicle/2.0/types.hal index f7a42e959b..b7c72e4f44 100644 --- a/automotive/vehicle/2.0/types.hal +++ b/automotive/vehicle/2.0/types.hal @@ -2892,6 +2892,52 @@ enum VehicleProperty : int32_t { | VehiclePropertyGroup:SYSTEM | VehiclePropertyType:MIXED | VehicleArea:GLOBAL), + + /** + * Defines an event that car watchdog updates to tell it's alive. + * + * Car watchdog sets this property to system uptime in milliseconds at every 3 second. + * During the boot, the update may take longer time. + * + * @change_mode VehiclePropertyChangeMode:ON_CHANGE + * @access VehiclePropertyAccess:WRITE + */ + WATCHDOG_ALIVE = ( + 0xF31 + | VehiclePropertyGroup:SYSTEM + | VehiclePropertyType:INT64 + | VehicleArea:GLOBAL), + + /** + * Defines a process terminated by car watchdog and the reason of termination. + * + * int32Values[0]: 1 // ProcessTerminationReason showing why a process is terminated. + * string: "/system/bin/log" // Process execution command. + * + * @change_mode VehiclePropertyChangeMode:ON_CHANGE + * @access VehiclePropertyAccess:WRITE + */ + WATCHDOG_TERMINATED_PROCESS = ( + 0x0F32 + | VehiclePropertyGroup:SYSTEM + | VehiclePropertyType:MIXED + | VehicleArea:GLOBAL), + + /** + * Defines an event that VHAL signals to the car watchdog as a heartbeat. + * + * VHAL is supposed to write system uptime to this property at every 3 second. + * Car watchdog subscribes to this property and checks if the property is updated at every 3 + * second. If it isn’t, car watchdog considers VHAL unhealthy and terminates it. + * + * @change_mode VehiclePropertyChangeMode:ON_CHANGE + * @access VehiclePropertyAccess:READ + */ + VHAL_HEARTBEAT = ( + 0x0F33 + | VehiclePropertyGroup:SYSTEM + | VehiclePropertyType:INT64 + | VehicleArea:GLOBAL), }; /** @@ -4790,3 +4836,23 @@ enum RotaryInputType : int32_t { ROTARY_INPUT_TYPE_AUDIO_VOLUME = 1, }; +/** + * The reason why a process is terminated by car watchdog. + * This is used with WATCHDOG_TERMINATED_PROCESS property. + */ +enum ProcessTerminationReason : int32_t { + /** + * A process doesn't respond to car watchdog within the timeout. + */ + NOT_RESPONDING = 1, + + /** + * A process uses more IO operations than what is allowed. + */ + IO_OVERUSE = 2, + + /** + * A process uses more memory space than what is allowed. + */ + MEMORY_OVERUSE = 3, +}; -- GitLab From 81108e249c50b545ac7508699aca14523b577aa9 Mon Sep 17 00:00:00 2001 From: Eric Jeong Date: Tue, 1 Sep 2020 09:24:30 -0700 Subject: [PATCH 136/790] New health check in VHAL - VHAL will not be a client to car watchdog. - Instead, VHAL updates VHAL_HEARTBEAT periodically and car watchdog determines VHAL's health based on it. Bug: 165861394 Test: manual test Change-Id: If84979ad4ed4dd60c18810b8ae17d6ed8e9bb132 --- .../vehicle/2.0/default/VehicleService.cpp | 21 ++--------- .../impl/vhal_v2_0/EmulatedVehicleHal.cpp | 35 +++++++++++++++++++ .../impl/vhal_v2_0/EmulatedVehicleHal.h | 2 ++ 3 files changed, 39 insertions(+), 19 deletions(-) diff --git a/automotive/vehicle/2.0/default/VehicleService.cpp b/automotive/vehicle/2.0/default/VehicleService.cpp index 47133fd162..62a4f204bc 100644 --- a/automotive/vehicle/2.0/default/VehicleService.cpp +++ b/automotive/vehicle/2.0/default/VehicleService.cpp @@ -20,13 +20,10 @@ #include -#include -#include #include #include #include #include -#include using namespace android; using namespace android::hardware; @@ -41,7 +38,7 @@ int main(int /* argc */, char* /* argv */ []) { auto service = std::make_unique(hal.get()); connector->setValuePool(hal->getValuePool()); - configureRpcThreadpool(4, false /* callerWillJoin */); + configureRpcThreadpool(4, true /* callerWillJoin */); ALOGI("Registering as service..."); status_t status = service->registerAsService(); @@ -51,22 +48,8 @@ int main(int /* argc */, char* /* argv */ []) { return 1; } - // Setup a binder thread pool to be a car watchdog client. - ABinderProcess_setThreadPoolMaxThreadCount(1); - ABinderProcess_startThreadPool(); - sp looper(Looper::prepare(0 /* opts */)); - std::shared_ptr watchdogClient = - ndk::SharedRefBase::make(looper, service.get()); - // The current health check is done in the main thread, so it falls short of capturing the real - // situation. Checking through HAL binder thread should be considered. - if (!watchdogClient->initialize()) { - ALOGE("Failed to initialize car watchdog client"); - return 1; - } ALOGI("Ready"); - while (true) { - looper->pollAll(-1 /* timeoutMillis */); - } + joinRpcThreadpool(); return 1; } diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp index a0b566d1ee..c83e2deb69 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp @@ -15,11 +15,13 @@ */ #define LOG_TAG "DefaultVehicleHal_v2_0" +#include #include #include #include #include #include +#include #include #include @@ -36,6 +38,8 @@ namespace V2_0 { namespace impl { +static constexpr std::chrono::nanoseconds kHeartBeatIntervalNs = 3s; + static std::unique_ptr fillDefaultObd2Frame(size_t numVendorIntegerSensors, size_t numVendorFloatSensors) { std::unique_ptr sensorStore( @@ -342,6 +346,8 @@ void EmulatedVehicleHal::onCreate() { initObd2FreezeFrame(*mPropStore->getConfigOrDie(OBD2_FREEZE_FRAME)); mInEmulator = isInEmulator(); ALOGD("mInEmulator=%s", mInEmulator ? "true" : "false"); + mRecurrentTimer.registerRecurrentEvent(kHeartBeatIntervalNs, + static_cast(VehicleProperty::VHAL_HEARTBEAT)); } std::vector EmulatedVehicleHal::listProperties() { @@ -359,6 +365,10 @@ void EmulatedVehicleHal::onContinuousPropertyTimer(const std::vector& p if (internalPropValue != nullptr) { v = pool.obtain(*internalPropValue); } + } else if (property == static_cast(VehicleProperty::VHAL_HEARTBEAT)) { + // VHAL_HEARTBEAT is not a continuous value, but it needs to be updated periodically. + // So, the update is done through onContinuousPropertyTimer. + v = doInternalHealthCheck(); } else { ALOGE("Unexpected onContinuousPropertyTimer for property: 0x%x", property); } @@ -512,6 +522,31 @@ StatusCode EmulatedVehicleHal::fillObd2DtcInfo(VehiclePropValue* outValue) { return StatusCode::OK; } +VehicleHal::VehiclePropValuePtr EmulatedVehicleHal::doInternalHealthCheck() { + VehicleHal::VehiclePropValuePtr v = nullptr; + + // This is an example of very simpe health checking. VHAL is considered healthy if we can read + // PERF_VEHICLE_SPEED. The more comprehensive health checking is required. + VehiclePropValue propValue = { + .prop = static_cast(VehicleProperty::PERF_VEHICLE_SPEED), + }; + auto internalPropValue = mPropStore->readValueOrNull(propValue); + if (internalPropValue != nullptr) { + v = createVhalHeartBeatProp(); + } else { + ALOGW("VHAL health check failed"); + } + return v; +} + +VehicleHal::VehiclePropValuePtr EmulatedVehicleHal::createVhalHeartBeatProp() { + VehicleHal::VehiclePropValuePtr v = getValuePool()->obtainInt64(uptimeMillis()); + v->prop = static_cast(VehicleProperty::VHAL_HEARTBEAT); + v->areaId = 0; + v->status = VehiclePropertyStatus::AVAILABLE; + return v; +} + } // impl } // namespace V2_0 diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h index eb38d7de89..5c676416d7 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h @@ -82,6 +82,8 @@ private: VehiclePropValue* outValue); StatusCode fillObd2DtcInfo(VehiclePropValue* outValue); StatusCode clearObd2FreezeFrames(const VehiclePropValue& propValue); + VehicleHal::VehiclePropValuePtr doInternalHealthCheck(); + VehicleHal::VehiclePropValuePtr createVhalHeartBeatProp(); /* Private members */ VehiclePropertyStore* mPropStore; -- GitLab From 1da23f2c85bb08c9638836d8f523606813d2c44a Mon Sep 17 00:00:00 2001 From: Yifan Hong Date: Thu, 10 Sep 2020 17:55:30 -0700 Subject: [PATCH 137/790] Add fingerprint 2.3 to compatibility matrix. Test: builds Bug: 110261831 Change-Id: Ia732a450685ddca53a087e443e121ae47e9e1bf0 --- compatibility_matrices/compatibility_matrix.current.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index 089c89aa97..772c9cdc84 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -94,7 +94,7 @@ android.hardware.biometrics.fingerprint - 2.1-2 + 2.1-3 IBiometricsFingerprint default -- GitLab From ed361970c6b63f3baf61095c0f1b33fb8429f8b6 Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Wed, 24 Jun 2020 10:59:56 -0700 Subject: [PATCH 138/790] Define IFingerprint Bug: 152416783 Test: m android.hardware.biometrics.fingerprint-update-api Change-Id: Iba1fae1739366955b6aaed55b59eed0a3fed5a57 --- biometrics/fingerprint/aidl/Android.bp | 19 +++++++ .../biometrics/fingerprint/AcquiredInfo.aidl | 29 ++++++++++ .../biometrics/fingerprint/Error.aidl | 30 +++++++++++ .../fingerprint/ICancellationSignal.aidl | 22 ++++++++ .../biometrics/fingerprint/IFingerprint.aidl | 26 +++++++++ .../IGenerateChallengeCallback.aidl | 22 ++++++++ .../fingerprint/IResetLockoutCallback.aidl | 22 ++++++++ .../fingerprint/IRevokeChallengeCallback.aidl | 22 ++++++++ .../biometrics/fingerprint/ISession.aidl | 31 +++++++++++ .../fingerprint/ISessionCallback.aidl | 29 ++++++++++ .../biometrics/fingerprint/SensorProps.aidl | 24 +++++++++ .../biometrics/fingerprint/SensorType.aidl | 27 ++++++++++ .../biometrics/fingerprint/SessionState.aidl | 29 ++++++++++ .../biometrics/fingerprint/AcquiredInfo.aidl | 31 +++++++++++ .../biometrics/fingerprint/Error.aidl | 32 +++++++++++ .../fingerprint/ICancellationSignal.aidl | 23 ++++++++ .../biometrics/fingerprint/IFingerprint.aidl | 37 +++++++++++++ .../IGenerateChallengeCallback.aidl | 23 ++++++++ .../fingerprint/IResetLockoutCallback.aidl | 23 ++++++++ .../fingerprint/IRevokeChallengeCallback.aidl | 23 ++++++++ .../biometrics/fingerprint/ISession.aidl | 53 +++++++++++++++++++ .../fingerprint/ISessionCallback.aidl | 41 ++++++++++++++ .../biometrics/fingerprint/SensorProps.aidl | 29 ++++++++++ .../biometrics/fingerprint/SensorType.aidl | 29 ++++++++++ .../biometrics/fingerprint/SessionState.aidl | 31 +++++++++++ .../compatibility_matrix.current.xml | 7 +++ 26 files changed, 714 insertions(+) create mode 100644 biometrics/fingerprint/aidl/Android.bp create mode 100644 biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl create mode 100644 biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl create mode 100644 biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ICancellationSignal.aidl create mode 100644 biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl create mode 100644 biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IGenerateChallengeCallback.aidl create mode 100644 biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IResetLockoutCallback.aidl create mode 100644 biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IRevokeChallengeCallback.aidl create mode 100644 biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISession.aidl create mode 100644 biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl create mode 100644 biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl create mode 100644 biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorType.aidl create mode 100644 biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.aidl create mode 100644 biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl create mode 100644 biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/Error.aidl create mode 100644 biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ICancellationSignal.aidl create mode 100644 biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl create mode 100644 biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IGenerateChallengeCallback.aidl create mode 100644 biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IResetLockoutCallback.aidl create mode 100644 biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IRevokeChallengeCallback.aidl create mode 100644 biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl create mode 100644 biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl create mode 100644 biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl create mode 100644 biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorType.aidl create mode 100644 biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SessionState.aidl diff --git a/biometrics/fingerprint/aidl/Android.bp b/biometrics/fingerprint/aidl/Android.bp new file mode 100644 index 0000000000..e6baa8a8b9 --- /dev/null +++ b/biometrics/fingerprint/aidl/Android.bp @@ -0,0 +1,19 @@ +aidl_interface { + name: "android.hardware.biometrics.fingerprint", + vendor_available: true, + srcs: [ + "android/hardware/biometrics/fingerprint/**/*.aidl", + ], + imports: [ + "android.hardware.keymaster", + ], + stability: "vintf", + backend: { + java: { + platform_apis: true, + }, + cpp: { + enabled: false, + }, + }, +} diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl new file mode 100644 index 0000000000..329a35dc49 --- /dev/null +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl @@ -0,0 +1,29 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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.fingerprint; +@Backing(type="byte") @VintfStability +enum AcquiredInfo { + GOOD = 0, + PARTIAL = 1, + INSUFFICIENT = 2, + SENSOR_DIRTY = 3, + TOO_SLOW = 4, + TOO_FAST = 5, + START = 6, + VENDOR = 7, +} diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl new file mode 100644 index 0000000000..0298c126c4 --- /dev/null +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl @@ -0,0 +1,30 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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.fingerprint; +@Backing(type="byte") @VintfStability +enum Error { + HW_UNAVAILABLE = 0, + UNABLE_TO_PROCESS = 1, + TIMEOUT = 2, + NO_SPACE = 3, + CANCELED = 4, + UNABLE_TO_REMOVE = 5, + LOCKOUT = 6, + LOCKOUT_PERMANENT = 7, + VENDOR = 8, +} diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ICancellationSignal.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ICancellationSignal.aidl new file mode 100644 index 0000000000..6f3d2dbb3a --- /dev/null +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ICancellationSignal.aidl @@ -0,0 +1,22 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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.fingerprint; +@VintfStability +interface ICancellationSignal { + oneway void cancel(); +} diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl new file mode 100644 index 0000000000..a376acfbe9 --- /dev/null +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl @@ -0,0 +1,26 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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.fingerprint; +@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); + void setResetLockoutCallback(in android.hardware.biometrics.fingerprint.IResetLockoutCallback cb); + void generateChallenge(in int sensorId, in int userId, in long keystoreOperationId, in int timeoutSec, in android.hardware.biometrics.fingerprint.IGenerateChallengeCallback cb); + void revokeChallenge(in int sensorId, in int userId, in android.hardware.biometrics.fingerprint.IRevokeChallengeCallback cb); +} diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IGenerateChallengeCallback.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IGenerateChallengeCallback.aidl new file mode 100644 index 0000000000..eaf27d2235 --- /dev/null +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IGenerateChallengeCallback.aidl @@ -0,0 +1,22 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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.fingerprint; +@VintfStability +interface IGenerateChallengeCallback { + oneway void onChallengeGenerated(in int sensorId, in int userId, in long keystoreOperationId, in long challenge); +} diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IResetLockoutCallback.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IResetLockoutCallback.aidl new file mode 100644 index 0000000000..ac0decda6b --- /dev/null +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IResetLockoutCallback.aidl @@ -0,0 +1,22 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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.fingerprint; +@VintfStability +interface IResetLockoutCallback { + oneway void onLockoutReset(in int sensorId, in int userId, in long durationMilli); +} diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IRevokeChallengeCallback.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IRevokeChallengeCallback.aidl new file mode 100644 index 0000000000..23fc10f9ae --- /dev/null +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IRevokeChallengeCallback.aidl @@ -0,0 +1,22 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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.fingerprint; +@VintfStability +interface IRevokeChallengeCallback { + oneway void onChallengeRevoked(in int sensorId, in int userId, in long challenge); +} 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 new file mode 100644 index 0000000000..4b71527f71 --- /dev/null +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISession.aidl @@ -0,0 +1,31 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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.fingerprint; +@VintfStability +interface ISession { + android.hardware.biometrics.fingerprint.ICancellationSignal enroll(in int cookie, in android.hardware.keymaster.HardwareAuthToken hat); + android.hardware.biometrics.fingerprint.ICancellationSignal authenticate(in int cookie, in long keystoreOperationId); + android.hardware.biometrics.fingerprint.ICancellationSignal detectInteraction(in int cookie); + void enumerateEnrollments(in int cookie); + void removeEnrollments(in int cookie, in int[] enrollmentIds); + void getAuthenticatorId(in int cookie); + void resetLockout(in int cookie, in android.hardware.keymaster.HardwareAuthToken hat); + void onPointerDown(in int pointerId, in int x, in int y, in float minor, in float major); + void onPointerUp(in int pointerId); + void onUiReady(); +} diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl new file mode 100644 index 0000000000..f50554b458 --- /dev/null +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl @@ -0,0 +1,29 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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.fingerprint; +@VintfStability +interface ISessionCallback { + void onStateChanged(in int cookie, in android.hardware.biometrics.fingerprint.SessionState state); + 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, int vendorCode); + void onAuthenticated(in int enrollmentId, in android.hardware.keymaster.HardwareAuthToken hat); + void onInteractionDetected(); + void onEnrollmentsEnumerated(in int[] enrollmentIds); + void onEnrollmentsRemoved(in int[] enrollmentIds); +} diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl new file mode 100644 index 0000000000..c30e35d96b --- /dev/null +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl @@ -0,0 +1,24 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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.fingerprint; +@VintfStability +parcelable SensorProps { + int sensorId; + android.hardware.biometrics.fingerprint.SensorType sensorType; + boolean resetLockoutRequiresHardwareAuthToken; +} diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorType.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorType.aidl new file mode 100644 index 0000000000..2aaf94fc01 --- /dev/null +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorType.aidl @@ -0,0 +1,27 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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.fingerprint; +@Backing(type="byte") @VintfStability +enum SensorType { + UNKNOWN = 0, + REAR = 1, + UNDER_DISPLAY_ULTRASONIC = 2, + UNDER_DISPLAY_OPTICAL = 3, + POWER_BUTTON = 4, + HOME_BUTTON = 5, +} diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.aidl new file mode 100644 index 0000000000..38ca1e052b --- /dev/null +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.aidl @@ -0,0 +1,29 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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.fingerprint; +@Backing(type="byte") @VintfStability +enum SessionState { + IDLING = 0, + ENROLLING = 1, + AUTHENTICATING = 2, + DETECTING_INTERACTION = 3, + ENUMERATING_ENROLLMENTS = 4, + REMOVING_ENROLLMENTS = 5, + GETTING_AUTHENTICATOR_ID = 6, + RESETTING_LOCKOUT = 7, +} diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl new file mode 100644 index 0000000000..8cb78339c4 --- /dev/null +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.biometrics.fingerprint; + +@VintfStability +@Backing(type="byte") +enum AcquiredInfo { + GOOD, + PARTIAL, + INSUFFICIENT, + SENSOR_DIRTY, + TOO_SLOW, + TOO_FAST, + START, + VENDOR +} + diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/Error.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/Error.aidl new file mode 100644 index 0000000000..cc79de7b05 --- /dev/null +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/Error.aidl @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.biometrics.fingerprint; + +@VintfStability +@Backing(type="byte") +enum Error { + HW_UNAVAILABLE, + UNABLE_TO_PROCESS, + TIMEOUT, + NO_SPACE, + CANCELED, + UNABLE_TO_REMOVE, + LOCKOUT, + LOCKOUT_PERMANENT, + VENDOR +} + diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ICancellationSignal.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ICancellationSignal.aidl new file mode 100644 index 0000000000..abfbb2ab89 --- /dev/null +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ICancellationSignal.aidl @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.biometrics.fingerprint; + +@VintfStability +oneway interface ICancellationSignal { + void cancel(); +} + diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl new file mode 100644 index 0000000000..9aafeab17d --- /dev/null +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.biometrics.fingerprint; + +import android.hardware.biometrics.fingerprint.IGenerateChallengeCallback; +import android.hardware.biometrics.fingerprint.IResetLockoutCallback; +import android.hardware.biometrics.fingerprint.IRevokeChallengeCallback; +import android.hardware.biometrics.fingerprint.ISession; +import android.hardware.biometrics.fingerprint.ISessionCallback; +import android.hardware.biometrics.fingerprint.SensorProps; + +@VintfStability +interface IFingerprint { + SensorProps[] getSensorProps(); + + ISession createSession(in int sensorId, in int userId, in ISessionCallback cb); + + void setResetLockoutCallback(in IResetLockoutCallback cb); + + void generateChallenge(in int sensorId, in int userId, in long keystoreOperationId, in int timeoutSec, in IGenerateChallengeCallback cb); + + void revokeChallenge(in int sensorId, in int userId, in IRevokeChallengeCallback cb); +} diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IGenerateChallengeCallback.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IGenerateChallengeCallback.aidl new file mode 100644 index 0000000000..93a2d7bdc4 --- /dev/null +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IGenerateChallengeCallback.aidl @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.biometrics.fingerprint; + +@VintfStability +oneway interface IGenerateChallengeCallback { + void onChallengeGenerated(in int sensorId, in int userId, in long keystoreOperationId, in long challenge); +} + diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IResetLockoutCallback.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IResetLockoutCallback.aidl new file mode 100644 index 0000000000..d97a701c73 --- /dev/null +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IResetLockoutCallback.aidl @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.biometrics.fingerprint; + +@VintfStability +oneway interface IResetLockoutCallback { + void onLockoutReset(in int sensorId, in int userId, in long durationMilli); +} + diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IRevokeChallengeCallback.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IRevokeChallengeCallback.aidl new file mode 100644 index 0000000000..cca3453e39 --- /dev/null +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IRevokeChallengeCallback.aidl @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.biometrics.fingerprint; + +@VintfStability +oneway interface IRevokeChallengeCallback { + void onChallengeRevoked(in int sensorId, in int userId, in long challenge); +} + diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl new file mode 100644 index 0000000000..78da7ae845 --- /dev/null +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.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. + */ + +package android.hardware.biometrics.fingerprint; + +import android.hardware.biometrics.fingerprint.ICancellationSignal; +import android.hardware.keymaster.HardwareAuthToken; + +@VintfStability +interface ISession { + /** + * Methods applicable to any fingerprint type. + */ + + ICancellationSignal enroll(in int cookie, in HardwareAuthToken hat); + + ICancellationSignal authenticate(in int cookie, in long keystoreOperationId); + + ICancellationSignal detectInteraction(in int cookie); + + void enumerateEnrollments(in int cookie); + + void removeEnrollments(in int cookie, in int[] enrollmentIds); + + void getAuthenticatorId(in int cookie); + + void resetLockout(in int cookie, in HardwareAuthToken hat); + + + /** + * Methods for notifying the under-display fingerprint sensor about external events. + */ + + void onPointerDown(in int pointerId, in int x, in int y, in float minor, in float major); + + void onPointerUp(in int pointerId); + + void onUiReady(); +} + diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl new file mode 100644 index 0000000000..655f030d54 --- /dev/null +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.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. + */ + +package android.hardware.biometrics.fingerprint; + +import android.hardware.biometrics.fingerprint.AcquiredInfo; +import android.hardware.biometrics.fingerprint.Error; +import android.hardware.biometrics.fingerprint.SessionState; +import android.hardware.keymaster.HardwareAuthToken; + +@VintfStability +interface ISessionCallback { + void onStateChanged(in int cookie, in SessionState state); + + void onAcquired(in AcquiredInfo info, in int vendorCode); + + void onError(in Error error, in int vendorCode); + + void onEnrollmentProgress(in int enrollmentId, int remaining, int vendorCode); + + void onAuthenticated(in int enrollmentId, in HardwareAuthToken hat); + + void onInteractionDetected(); + + void onEnrollmentsEnumerated(in int[] enrollmentIds); + + void onEnrollmentsRemoved(in int[] enrollmentIds); +} diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl new file mode 100644 index 0000000000..bbb1ecb622 --- /dev/null +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.biometrics.fingerprint; + +import android.hardware.biometrics.fingerprint.SensorType; + +@VintfStability +parcelable SensorProps { + int sensorId; + + SensorType sensorType; + + boolean resetLockoutRequiresHardwareAuthToken; +} + diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorType.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorType.aidl new file mode 100644 index 0000000000..589e737f93 --- /dev/null +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorType.aidl @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.biometrics.fingerprint; + +@VintfStability +@Backing(type="byte") +enum SensorType { + UNKNOWN, + REAR, + UNDER_DISPLAY_ULTRASONIC, + UNDER_DISPLAY_OPTICAL, + POWER_BUTTON, + HOME_BUTTON +} + diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SessionState.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SessionState.aidl new file mode 100644 index 0000000000..3b4ba184e6 --- /dev/null +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SessionState.aidl @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.biometrics.fingerprint; + +@VintfStability +@Backing(type="byte") +enum SessionState { + IDLING, + ENROLLING, + AUTHENTICATING, + DETECTING_INTERACTION, + ENUMERATING_ENROLLMENTS, + REMOVING_ENROLLMENTS, + GETTING_AUTHENTICATOR_ID, + RESETTING_LOCKOUT +} + diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index 772c9cdc84..cfd6d1c70e 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -100,6 +100,13 @@ default + + android.hardware.biometrics.fingerprint + + IFingerprint + default + + android.hardware.bluetooth 1.0-1 -- GitLab From 14412df89f523b3cd4b3a7a04dec2d4b5f67db2e Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Thu, 27 Aug 2020 14:26:06 -0700 Subject: [PATCH 139/790] Add VTS tests for IFingerprint Bug: 152416783 Test: atest VtsHalBiometricsFingerprintTargetTest Change-Id: I6aec70e8f9f4342cab2f7ce367698841e22f57f1 --- biometrics/fingerprint/aidl/vts/Android.bp | 16 +++ .../VtsHalBiometricsFingerprintTargetTest.cpp | 133 ++++++++++++++++++ 2 files changed, 149 insertions(+) create mode 100644 biometrics/fingerprint/aidl/vts/Android.bp create mode 100644 biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp diff --git a/biometrics/fingerprint/aidl/vts/Android.bp b/biometrics/fingerprint/aidl/vts/Android.bp new file mode 100644 index 0000000000..b441eb3bcb --- /dev/null +++ b/biometrics/fingerprint/aidl/vts/Android.bp @@ -0,0 +1,16 @@ +cc_test { + name: "VtsHalBiometricsFingerprintTargetTest", + defaults: [ + "VtsHalTargetTestDefaults", + "use_libaidlvintf_gtest_helper_static", + ], + srcs: ["VtsHalBiometricsFingerprintTargetTest.cpp"], + shared_libs: [ + "libbinder_ndk", + "android.hardware.biometrics.fingerprint-ndk_platform", + ], + test_suites: [ + "general-tests", + "vts", + ], +} diff --git a/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp b/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp new file mode 100644 index 0000000000..88980bf8c9 --- /dev/null +++ b/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include +#include + +#include +#include + +#include + +namespace aidl::android::hardware::biometrics::fingerprint { +namespace { + +constexpr int kSensorId = 0; +constexpr int kUserId = 0; +constexpr auto kCallbackTimeout = std::chrono::seconds(1); + +enum class SessionCallbackMethodName { + kOnStateChanged, +}; + +struct SessionCallbackInvocation { + SessionCallbackMethodName method_name; + SessionState state; +}; + +class SessionCallback : public BnSessionCallback { + public: + explicit SessionCallback(std::promise invocation_promise) + : invocation_promise_(std::move(invocation_promise)) {} + + ndk::ScopedAStatus onStateChanged(int32_t /*cookie*/, SessionState state) override { + SessionCallbackInvocation invocation = {}; + invocation.method_name = SessionCallbackMethodName::kOnStateChanged; + invocation.state = state; + invocation_promise_.set_value(invocation); + return ndk::ScopedAStatus::ok(); + } + + ndk::ScopedAStatus onAcquired(AcquiredInfo /*info*/, int32_t /*vendorCode*/) override { + return ndk::ScopedAStatus::ok(); + } + + ndk::ScopedAStatus onError(Error /*error*/, int32_t /*vendorCode*/) override { + return ndk::ScopedAStatus::ok(); + } + + ndk::ScopedAStatus onEnrollmentProgress(int32_t /*enrollmentId*/, int32_t /*remaining*/, + int32_t /*vendorCode*/) override { + return ndk::ScopedAStatus::ok(); + } + + ndk::ScopedAStatus onAuthenticated(int32_t /*enrollmentId*/, + const keymaster::HardwareAuthToken& /*hat*/) override { + return ndk::ScopedAStatus::ok(); + } + + ndk::ScopedAStatus onInteractionDetected() override { return ndk::ScopedAStatus::ok(); } + + ndk::ScopedAStatus onEnrollmentsEnumerated( + const std::vector& /*enrollmentIds*/) override { + return ndk::ScopedAStatus::ok(); + } + + ndk::ScopedAStatus onEnrollmentsRemoved( + const std::vector& /*enrollmentIds*/) override { + return ndk::ScopedAStatus::ok(); + } + + private: + std::promise invocation_promise_; +}; + +class Fingerprint : public testing::TestWithParam { + protected: + void SetUp() override { + AIBinder* binder = AServiceManager_waitForService(GetParam().c_str()); + ASSERT_NE(binder, nullptr); + hal_ = IFingerprint::fromBinder(ndk::SpAIBinder(binder)); + } + + std::shared_ptr hal_; +}; + +TEST_P(Fingerprint, AuthenticateTest) { + std::promise invocation_promise; + std::future invocation_future = invocation_promise.get_future(); + std::shared_ptr session_cb = + ndk::SharedRefBase::make(std::move(invocation_promise)); + + std::shared_ptr session; + ASSERT_TRUE(hal_->createSession(kSensorId, kUserId, session_cb, &session).isOk()); + + std::shared_ptr cancel_cb; + ASSERT_TRUE(session->authenticate(0, 0, &cancel_cb).isOk()); + ASSERT_EQ(invocation_future.wait_for(kCallbackTimeout), std::future_status::ready); + + SessionCallbackInvocation invocation = invocation_future.get(); + EXPECT_EQ(invocation.method_name, SessionCallbackMethodName::kOnStateChanged); + EXPECT_EQ(invocation.state, SessionState::AUTHENTICATING); +} + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Fingerprint); +INSTANTIATE_TEST_SUITE_P( + IFingerprint, Fingerprint, + testing::ValuesIn(::android::getAidlHalInstanceNames(IFingerprint::descriptor)), + ::android::PrintInstanceNameToString); + +} // namespace + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + ABinderProcess_setThreadPoolMaxThreadCount(1); + ABinderProcess_startThreadPool(); + return RUN_ALL_TESTS(); +} + +} // namespace aidl::android::hardware::biometrics::fingerprint -- GitLab From a9a3c850bc7d683974182a590a7cf621cbcc3ae1 Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Tue, 18 Aug 2020 03:09:41 -0700 Subject: [PATCH 140/790] Default implementation for IFingerprint Bug: 152416783 Test: atest VtsHalBiometricsFingerprintTargetTest Test: atest vts_treble_vintf_vendor_test Test: atest hal_implementation_test Change-Id: I67efda2d5418147a7cac9cc54920005a199fcbe3 --- .../fingerprint/aidl/default/Android.bp | 17 ++++ .../fingerprint/aidl/default/Fingerprint.cpp | 50 ++++++++++++ .../fingerprint/aidl/default/Fingerprint.h | 43 ++++++++++ .../fingerprint/aidl/default/Session.cpp | 80 +++++++++++++++++++ biometrics/fingerprint/aidl/default/Session.h | 60 ++++++++++++++ .../aidl/default/fingerprint-default.rc | 5 ++ .../aidl/default/fingerprint-default.xml | 6 ++ biometrics/fingerprint/aidl/default/main.cpp | 35 ++++++++ 8 files changed, 296 insertions(+) create mode 100644 biometrics/fingerprint/aidl/default/Android.bp create mode 100644 biometrics/fingerprint/aidl/default/Fingerprint.cpp create mode 100644 biometrics/fingerprint/aidl/default/Fingerprint.h create mode 100644 biometrics/fingerprint/aidl/default/Session.cpp create mode 100644 biometrics/fingerprint/aidl/default/Session.h create mode 100644 biometrics/fingerprint/aidl/default/fingerprint-default.rc create mode 100644 biometrics/fingerprint/aidl/default/fingerprint-default.xml create mode 100644 biometrics/fingerprint/aidl/default/main.cpp diff --git a/biometrics/fingerprint/aidl/default/Android.bp b/biometrics/fingerprint/aidl/default/Android.bp new file mode 100644 index 0000000000..f2536d4ba8 --- /dev/null +++ b/biometrics/fingerprint/aidl/default/Android.bp @@ -0,0 +1,17 @@ +cc_binary { + name: "android.hardware.biometrics.fingerprint-service.example", + relative_install_path: "hw", + init_rc: ["fingerprint-default.rc"], + vintf_fragments: ["fingerprint-default.xml"], + vendor: true, + shared_libs: [ + "libbase", + "libbinder_ndk", + "android.hardware.biometrics.fingerprint-ndk_platform", + ], + srcs: [ + "main.cpp", + "Fingerprint.cpp", + "Session.cpp", + ], +} diff --git a/biometrics/fingerprint/aidl/default/Fingerprint.cpp b/biometrics/fingerprint/aidl/default/Fingerprint.cpp new file mode 100644 index 0000000000..6f9e3a0628 --- /dev/null +++ b/biometrics/fingerprint/aidl/default/Fingerprint.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Fingerprint.h" +#include "Session.h" + +namespace aidl::android::hardware::biometrics::fingerprint { + +ndk::ScopedAStatus Fingerprint::getSensorProps(std::vector* /*return_val*/) { + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Fingerprint::createSession(int32_t /*sensorId*/, int32_t /*userId*/, + const std::shared_ptr& cb, + std::shared_ptr* return_val) { + *return_val = SharedRefBase::make(cb); + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Fingerprint::setResetLockoutCallback( + const std::shared_ptr& /*cb*/) { + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Fingerprint::generateChallenge( + int32_t /*sensorId*/, int32_t /*userId*/, int64_t /*keystoreOperationId*/, + int32_t /*timeoutSec*/, const std::shared_ptr& /*cb*/) { + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Fingerprint::revokeChallenge( + int32_t /*sensorId*/, int32_t /*userId*/, + const std::shared_ptr& /*cb*/) { + return ndk::ScopedAStatus::ok(); +} + +} // namespace aidl::android::hardware::biometrics::fingerprint diff --git a/biometrics/fingerprint/aidl/default/Fingerprint.h b/biometrics/fingerprint/aidl/default/Fingerprint.h new file mode 100644 index 0000000000..9f04893592 --- /dev/null +++ b/biometrics/fingerprint/aidl/default/Fingerprint.h @@ -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. + */ + +#pragma once + +#include + +namespace aidl::android::hardware::biometrics::fingerprint { + +class Fingerprint : public BnFingerprint { + public: + ndk::ScopedAStatus getSensorProps(std::vector* _aidl_return) override; + + ndk::ScopedAStatus createSession(int32_t sensorId, int32_t userId, + const std::shared_ptr& cb, + std::shared_ptr* _aidl_return) override; + + ndk::ScopedAStatus setResetLockoutCallback( + const std::shared_ptr& cb) override; + + ndk::ScopedAStatus generateChallenge( + int32_t sensorId, int32_t userId, int64_t keystoreOperationId, int32_t timeoutSec, + const std::shared_ptr& cb) override; + + ndk::ScopedAStatus revokeChallenge( + int32_t sensorId, int32_t userId, + const std::shared_ptr& cb) override; +}; + +} // namespace aidl::android::hardware::biometrics::fingerprint diff --git a/biometrics/fingerprint/aidl/default/Session.cpp b/biometrics/fingerprint/aidl/default/Session.cpp new file mode 100644 index 0000000000..5eb3134ec1 --- /dev/null +++ b/biometrics/fingerprint/aidl/default/Session.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "Session.h" + +namespace aidl::android::hardware::biometrics::fingerprint { + +class CancellationSignal : public BnCancellationSignal { + public: + ndk::ScopedAStatus cancel() override { return ndk::ScopedAStatus::ok(); } +}; + +Session::Session(std::shared_ptr cb) : cb_(std::move(cb)) {} + +ndk::ScopedAStatus Session::enroll(int32_t /*cookie*/, const keymaster::HardwareAuthToken& /*hat*/, + std::shared_ptr* /*return_val*/) { + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Session::authenticate(int32_t /*cookie*/, int64_t /*keystoreOperationId*/, + std::shared_ptr* return_val) { + if (cb_) { + cb_->onStateChanged(0, SessionState::AUTHENTICATING); + } + *return_val = SharedRefBase::make(); + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Session::detectInteraction( + int32_t /*cookie*/, std::shared_ptr* /*return_val*/) { + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Session::enumerateEnrollments(int32_t /*cookie*/) { + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Session::removeEnrollments(int32_t /*cookie*/, + const std::vector& /*enrollmentIds*/) { + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Session::getAuthenticatorId(int32_t /*cookie*/) { + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Session::resetLockout(int32_t /*cookie*/, + const keymaster::HardwareAuthToken& /*hat*/) { + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Session::onPointerDown(int32_t /*pointerId*/, int32_t /*x*/, int32_t /*y*/, + float /*minor*/, float /*major*/) { + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Session::onPointerUp(int32_t /*pointerId*/) { + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Session::onUiReady() { + return ndk::ScopedAStatus::ok(); +} + +} // namespace aidl::android::hardware::biometrics::fingerprint diff --git a/biometrics/fingerprint/aidl/default/Session.h b/biometrics/fingerprint/aidl/default/Session.h new file mode 100644 index 0000000000..69950fb8d3 --- /dev/null +++ b/biometrics/fingerprint/aidl/default/Session.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include + +namespace aidl::android::hardware::biometrics::fingerprint { + +namespace aidl::android::hardware::keymaster = keymaster; + +class Session : public BnSession { + public: + explicit Session(std::shared_ptr cb); + + ndk::ScopedAStatus enroll(int32_t cookie, const keymaster::HardwareAuthToken& hat, + std::shared_ptr* return_val) override; + + ndk::ScopedAStatus authenticate(int32_t cookie, int64_t keystoreOperationId, + std::shared_ptr* return_val) override; + + ndk::ScopedAStatus detectInteraction(int32_t cookie, + std::shared_ptr* return_val) override; + + ndk::ScopedAStatus enumerateEnrollments(int32_t cookie) override; + + ndk::ScopedAStatus removeEnrollments(int32_t cookie, + const std::vector& enrollmentIds) override; + + ndk::ScopedAStatus getAuthenticatorId(int32_t cookie) override; + + ndk::ScopedAStatus resetLockout(int32_t cookie, + const keymaster::HardwareAuthToken& hat) override; + + ndk::ScopedAStatus onPointerDown(int32_t pointerId, int32_t x, int32_t y, float minor, + float major) override; + + ndk::ScopedAStatus onPointerUp(int32_t pointerId) override; + + ndk::ScopedAStatus onUiReady() override; + + private: + std::shared_ptr cb_; +}; + +} // namespace aidl::android::hardware::biometrics::fingerprint diff --git a/biometrics/fingerprint/aidl/default/fingerprint-default.rc b/biometrics/fingerprint/aidl/default/fingerprint-default.rc new file mode 100644 index 0000000000..eb62c567fd --- /dev/null +++ b/biometrics/fingerprint/aidl/default/fingerprint-default.rc @@ -0,0 +1,5 @@ +service vendor.fingerprint-default /vendor/bin/hw/android.hardware.biometrics.fingerprint-service.example + class hal + user nobody + group nobody + diff --git a/biometrics/fingerprint/aidl/default/fingerprint-default.xml b/biometrics/fingerprint/aidl/default/fingerprint-default.xml new file mode 100644 index 0000000000..89da765616 --- /dev/null +++ b/biometrics/fingerprint/aidl/default/fingerprint-default.xml @@ -0,0 +1,6 @@ + + + android.hardware.biometrics.fingerprint + IFingerprint/default + + diff --git a/biometrics/fingerprint/aidl/default/main.cpp b/biometrics/fingerprint/aidl/default/main.cpp new file mode 100644 index 0000000000..058a008370 --- /dev/null +++ b/biometrics/fingerprint/aidl/default/main.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Fingerprint.h" + +#include +#include +#include + +using aidl::android::hardware::biometrics::fingerprint::Fingerprint; + +int main() { + ABinderProcess_setThreadPoolMaxThreadCount(0); + std::shared_ptr hal = ndk::SharedRefBase::make(); + + const std::string instance = std::string(Fingerprint::descriptor) + "/default"; + binder_status_t status = AServiceManager_addService(hal->asBinder().get(), instance.c_str()); + CHECK(status == STATUS_OK); + + ABinderProcess_joinThreadPool(); + return EXIT_FAILURE; // should not reach +} -- GitLab From 0d23292225b9c320b3790a90b43ecc35bea0fd4f Mon Sep 17 00:00:00 2001 From: lesl Date: Thu, 10 Sep 2020 22:29:44 +0800 Subject: [PATCH 141/790] wifi: Report mac address of apIfaceInstance in callback Test: Manuel Test. Hotspot works normally & mac address is correct to show in framework. Test: atest VtsHalWifiHostapdV1_0TargetTest Test: atest VtsHalWifiHostapdV1_1TargetTest Test: atest VtsHalWifiHostapdV1_2TargetTest Change-Id: I33f4548257d51fc06fa85af00a92637345364820 --- wifi/hostapd/1.3/IHostapdCallback.hal | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/wifi/hostapd/1.3/IHostapdCallback.hal b/wifi/hostapd/1.3/IHostapdCallback.hal index 98cde67f71..a098d87093 100644 --- a/wifi/hostapd/1.3/IHostapdCallback.hal +++ b/wifi/hostapd/1.3/IHostapdCallback.hal @@ -38,9 +38,10 @@ interface IHostapdCallback extends @1.1::IHostapdCallback { * @param freq The operational frequency of the AP. * @param bandwidth The operational bandwidth of the AP. * @param generation The operational mode of the AP (e.g. 11ac, 11ax). + * @param apIfaceInstanceMacAddress MAC Address of the apIfaceInstance. */ oneway onApInstanceInfoChanged(string ifaceName, string apIfaceInstance, uint32_t freq, - Bandwidth bandwidth, Generation generation); + Bandwidth bandwidth, Generation generation, MacAddress apIfaceInstanceMacAddress); /** * Invoked when a client connects/disconnects from the hotspot. @@ -51,7 +52,7 @@ interface IHostapdCallback extends @1.1::IHostapdCallback { * will have two instances in dual AP mode. The apIfaceInstance can be used * to identify which instance the callback is from. * Note: The apIfaceInstance must be same as ifaceName in single AP mode. - * @param clientAddress Mac Address of hotspot client. + * @param clientAddress MAC Address of hotspot client. * @param isConnected true when client connected, false when client * disconnected. */ -- GitLab From af9ac3b8a0b462f2c97a769d02e7ca4b048d6c16 Mon Sep 17 00:00:00 2001 From: Xusong Wang Date: Fri, 11 Sep 2020 10:47:03 -0700 Subject: [PATCH 142/790] Suppress gtest error for tests without any instance NNAPI VTS is parameterized by discovered devices. When there is no device available, the compilation caching and memory domain tests will not be instantiated, and will cause a gtest error. This patch suppresses the error by GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST macro. Bug: 168152007 Test: 1.2/1.3 VTS without NNAPI driver Change-Id: I715ae6f45df66e4a03c12b5d3f38bcc028a9ed7c --- neuralnetworks/1.2/vts/functional/CompilationCachingTests.cpp | 2 ++ neuralnetworks/1.3/vts/functional/CompilationCachingTests.cpp | 2 ++ neuralnetworks/1.3/vts/functional/MemoryDomainTests.cpp | 3 +++ 3 files changed, 7 insertions(+) diff --git a/neuralnetworks/1.2/vts/functional/CompilationCachingTests.cpp b/neuralnetworks/1.2/vts/functional/CompilationCachingTests.cpp index 70bee35cf1..ede1600090 100644 --- a/neuralnetworks/1.2/vts/functional/CompilationCachingTests.cpp +++ b/neuralnetworks/1.2/vts/functional/CompilationCachingTests.cpp @@ -1209,6 +1209,7 @@ std::string printCompilationCachingTest( return gtestCompliantName(getName(namedDevice) + "_" + type); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(CompilationCachingTest); INSTANTIATE_TEST_SUITE_P(TestCompilationCaching, CompilationCachingTest, testing::Combine(kNamedDeviceChoices, kOperandTypeChoices), printCompilationCachingTest); @@ -1365,6 +1366,7 @@ std::string printCompilationCachingSecurityTest( return gtestCompliantName(getName(namedDevice) + "_" + type + "_" + std::to_string(seed)); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(CompilationCachingSecurityTest); INSTANTIATE_TEST_SUITE_P(TestCompilationCaching, CompilationCachingSecurityTest, testing::Combine(kNamedDeviceChoices, kOperandTypeChoices, testing::Range(0U, 10U)), diff --git a/neuralnetworks/1.3/vts/functional/CompilationCachingTests.cpp b/neuralnetworks/1.3/vts/functional/CompilationCachingTests.cpp index 400349220e..edffa22cca 100644 --- a/neuralnetworks/1.3/vts/functional/CompilationCachingTests.cpp +++ b/neuralnetworks/1.3/vts/functional/CompilationCachingTests.cpp @@ -1200,6 +1200,7 @@ std::string printCompilationCachingTest( return gtestCompliantName(getName(namedDevice) + "_" + type); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(CompilationCachingTest); INSTANTIATE_TEST_SUITE_P(TestCompilationCaching, CompilationCachingTest, testing::Combine(kNamedDeviceChoices, kOperandTypeChoices), printCompilationCachingTest); @@ -1356,6 +1357,7 @@ std::string printCompilationCachingSecurityTest( return gtestCompliantName(getName(namedDevice) + "_" + type + "_" + std::to_string(seed)); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(CompilationCachingSecurityTest); INSTANTIATE_TEST_SUITE_P(TestCompilationCaching, CompilationCachingSecurityTest, testing::Combine(kNamedDeviceChoices, kOperandTypeChoices, testing::Range(0U, 10U)), diff --git a/neuralnetworks/1.3/vts/functional/MemoryDomainTests.cpp b/neuralnetworks/1.3/vts/functional/MemoryDomainTests.cpp index 0c657e06c9..5facc5ee96 100644 --- a/neuralnetworks/1.3/vts/functional/MemoryDomainTests.cpp +++ b/neuralnetworks/1.3/vts/functional/MemoryDomainTests.cpp @@ -605,6 +605,7 @@ std::string printMemoryDomainAllocateTest( return gtestCompliantName(getName(namedDevice) + "_" + type); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MemoryDomainAllocateTest); INSTANTIATE_TEST_SUITE_P(TestMemoryDomain, MemoryDomainAllocateTest, testing::Combine(kNamedDeviceChoices, kTestOperandTypeChoices), printMemoryDomainAllocateTest); @@ -829,6 +830,7 @@ std::string printMemoryDomainCopyTest( return gtestCompliantName(getName(namedDevice) + "_" + type); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MemoryDomainCopyTest); INSTANTIATE_TEST_SUITE_P(TestMemoryDomain, MemoryDomainCopyTest, testing::Combine(kNamedDeviceChoices, kTestOperandTypeChoices), printMemoryDomainCopyTest); @@ -1195,6 +1197,7 @@ std::string printMemoryDomainExecutionTest( return gtestCompliantName(getName(namedDevice) + "_" + type + "_" + executorStr); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MemoryDomainExecutionTest); INSTANTIATE_TEST_SUITE_P(TestMemoryDomain, MemoryDomainExecutionTest, testing::Combine(kNamedDeviceChoices, kTestOperandTypeChoices, kExecutorChoices), -- GitLab From c3b3f8127255aa5bfde19652aea8323a36c22476 Mon Sep 17 00:00:00 2001 From: jiabin Date: Fri, 11 Sep 2020 11:10:57 -0700 Subject: [PATCH 143/790] Make getPresentationPosition mandatory. GetPresentationPosition is marked as optional method at audio HAL v4.0. This method return a recent count of number of audio frames presented to an external observer. Making it mandatory can help improve the timestamp reporting. Test: make Bug: 158609200 Change-Id: Ic164c10e4c406e7382cdc676f13c64de49e48734 --- audio/7.0/IStreamOut.hal | 2 -- 1 file changed, 2 deletions(-) diff --git a/audio/7.0/IStreamOut.hal b/audio/7.0/IStreamOut.hal index 38d750f76b..0951a9e42a 100644 --- a/audio/7.0/IStreamOut.hal +++ b/audio/7.0/IStreamOut.hal @@ -271,8 +271,6 @@ interface IStreamOut extends IStream { * timestamp must correspond to N rather than N+M. The terms 'recent' and * 'small' are not defined. They reflect the quality of the implementation. * - * Optional method - * * @return retval operation completion status. * @return frames count of presented audio frames. * @return timeStamp associated clock time. -- GitLab From 5e4daa8d9a8daf19fb45ec7af4746907ad8fd72a Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Mon, 14 Sep 2020 15:07:47 +0800 Subject: [PATCH 144/790] wifi: wait for the framework to be ready before checking features supplicant vts will stop and then start the framework, it is too slow to allow next test checking necessary features. This change also create a base class, SupplicantHidlTestBase, to do the common initialization for all vts tests. Bug: 167230822 Test: atest VtsHalWifiSupplicantV1_0TargetTest \ VtsHalWifiSupplicantP2pV1_0TargetTest \ VtsHalWifiSupplicantV1_1TargetTest \ VtsHalWifiSupplicantV1_2TargetTest \ VtsHalWifiSupplicantP2pV1_2TargetTest \ VtsHalWifiSupplicantV1_3TargetTest \ VtsHalWifiSupplicantV1_4TargetTest Change-Id: Ice25c6d2198f719fc964a17515e66146a0a8ace2 --- .../functional/supplicant_hidl_test_utils.cpp | 14 ++++++ .../functional/supplicant_hidl_test_utils.h | 49 +++++++++++++++++++ .../supplicant_p2p_iface_hidl_test.cpp | 45 +++++------------ .../supplicant_sta_iface_hidl_test.cpp | 30 ++---------- .../supplicant_sta_network_hidl_test.cpp | 29 ++--------- .../vts/functional/supplicant_hidl_test.cpp | 4 +- .../supplicant_hidl_test_utils_1_1.h | 25 ++-------- .../supplicant_sta_iface_hidl_test.cpp | 7 ++- .../supplicant_sta_network_hidl_test.cpp | 11 ++--- .../supplicant_hidl_test_utils_1_2.h | 25 ++-------- .../supplicant_p2p_iface_hidl_test.cpp | 5 +- .../supplicant_sta_iface_hidl_test.cpp | 5 +- .../supplicant_sta_network_hidl_test.cpp | 4 +- .../supplicant_hidl_test_utils_1_3.h | 13 +++++ .../supplicant_sta_iface_hidl_test.cpp | 27 +--------- .../supplicant_sta_network_hidl_test.cpp | 27 +--------- .../supplicant_hidl_test_utils_1_4.h | 13 +++++ .../supplicant_sta_iface_hidl_test.cpp | 23 +-------- 18 files changed, 139 insertions(+), 217 deletions(-) diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp index 5e7a371d67..be6aad9583 100644 --- a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp +++ b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp @@ -283,3 +283,17 @@ bool turnOnExcessiveLogging(const sp& supplicant) { }); return !operation_failed; } + +bool waitForFrameworkReady() { + int waitCount = 10; + do { + // Check whether package service is ready or not. + if (!testing::checkSubstringInCommandOutput( + "/system/bin/service check package", ": not found")) { + return true; + } + LOG(INFO) << "Framework is not ready"; + sleep(1); + } while (waitCount-- > 0); + return false; +} diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.h b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.h index 1ccf0919aa..33945ccb19 100644 --- a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.h +++ b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.h @@ -17,6 +17,8 @@ #ifndef SUPPLICANT_HIDL_TEST_UTILS_H #define SUPPLICANT_HIDL_TEST_UTILS_H +#include +#include #include #include #include @@ -62,4 +64,51 @@ bool turnOnExcessiveLogging( bool turnOnExcessiveLogging(); +bool waitForFrameworkReady(); + +class SupplicantHidlTestBase + : public ::testing::TestWithParam> { + public: + virtual void SetUp() override { + // should always be v1.0 wifi + wifi_v1_0_instance_name_ = std::get<0>(GetParam()); + supplicant_instance_name_ = std::get<1>(GetParam()); + std::system("/system/bin/start"); + ASSERT_TRUE(waitForFrameworkReady()); + + isP2pOn_ = + testing::deviceSupportsFeature("android.hardware.wifi.direct"); + // Stop Framework + std::system("/system/bin/stop"); + stopSupplicant(wifi_v1_0_instance_name_); + startSupplicantAndWaitForHidlService(wifi_v1_0_instance_name_, + supplicant_instance_name_); + LOG(INFO) << "SupplicantHidlTestBase isP2pOn_: " << isP2pOn_; + } + + virtual void TearDown() override { + stopSupplicant(wifi_v1_0_instance_name_); + // Start Framework + std::system("/system/bin/start"); + } + + protected: + bool isP2pOn_ = false; + std::string wifi_v1_0_instance_name_; + std::string supplicant_instance_name_; +}; + +class SupplicantHidlTestBaseV1_0 : public SupplicantHidlTestBase { + public: + virtual void SetUp() override { + SupplicantHidlTestBase::SetUp(); + supplicant_ = getSupplicant(supplicant_instance_name_, isP2pOn_); + ASSERT_NE(supplicant_.get(), nullptr); + EXPECT_TRUE(turnOnExcessiveLogging(supplicant_)); + } + + protected: + android::sp + supplicant_; +}; #endif /* SUPPLICANT_HIDL_TEST_UTILS_H */ diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_p2p_iface_hidl_test.cpp b/wifi/supplicant/1.0/vts/functional/supplicant_p2p_iface_hidl_test.cpp index 616869b26b..e74fd590ab 100644 --- a/wifi/supplicant/1.0/vts/functional/supplicant_p2p_iface_hidl_test.cpp +++ b/wifi/supplicant/1.0/vts/functional/supplicant_p2p_iface_hidl_test.cpp @@ -71,21 +71,13 @@ constexpr uint32_t kTestExtListenInterval = 400; constexpr SupplicantNetworkId kTestNetworkId = 5; } // namespace -class SupplicantP2pIfaceHidlTest - : public ::testing::TestWithParam> { +class SupplicantP2pIfaceHidlTest : public SupplicantHidlTestBaseV1_0 { public: virtual void SetUp() override { - wifi_instance_name_ = std::get<0>(GetParam()); - supplicant_instance_name_ = std::get<1>(GetParam()); - isP2pOn_ = - testing::deviceSupportsFeature("android.hardware.wifi.direct"); - // Stop Framework - std::system("/system/bin/stop"); - stopSupplicant(wifi_instance_name_); - startSupplicantAndWaitForHidlService(wifi_instance_name_, - supplicant_instance_name_); - supplicant_ = getSupplicant(supplicant_instance_name_, isP2pOn_); - EXPECT_TRUE(turnOnExcessiveLogging(supplicant_)); + SupplicantHidlTestBaseV1_0::SetUp(); + if (!isP2pOn_) { + GTEST_SKIP() << "Wi-Fi Direct is not supported, skip this test."; + } p2p_iface_ = getSupplicantP2pIface(supplicant_); ASSERT_NE(p2p_iface_.get(), nullptr); @@ -93,22 +85,11 @@ class SupplicantP2pIfaceHidlTest memcpy(peer_mac_addr_.data(), kTestPeerMacAddr, peer_mac_addr_.size()); } - virtual void TearDown() override { - stopSupplicant(wifi_instance_name_); - // Start Framework - std::system("/system/bin/start"); - } - protected: - bool isP2pOn_ = false; - sp supplicant_; - // ISupplicantP2pIface object used for all tests in this fixture. sp p2p_iface_; // MAC address to use for various tests. std::array mac_addr_; std::array peer_mac_addr_; - std::string wifi_instance_name_; - std::string supplicant_instance_name_; }; class IfaceCallback : public ISupplicantP2pIfaceCallback { @@ -201,8 +182,8 @@ class IfaceCallback : public ISupplicantP2pIfaceCallback { * successfully created. */ TEST_P(SupplicantP2pIfaceHidlTest, Create) { - stopSupplicant(wifi_instance_name_); - startSupplicantAndWaitForHidlService(wifi_instance_name_, + stopSupplicant(wifi_v1_0_instance_name_); + startSupplicantAndWaitForHidlService(wifi_v1_0_instance_name_, supplicant_instance_name_); sp p2p_iface = getSupplicantP2pIface( getSupplicant(supplicant_instance_name_, isP2pOn_)); @@ -301,8 +282,8 @@ TEST_P(SupplicantP2pIfaceHidlTest, Connect) { mac_addr_, ISupplicantP2pIface::WpsProvisionMethod::PBC, kTestConnectPin, false, false, kTestConnectGoIntent, [](const SupplicantStatus& status, const hidl_string& /* pin */) { - // This is not going to work with fake values. - EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code); + // After enabling auto-join, it will succeed always. + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); }); } @@ -314,12 +295,12 @@ TEST_P(SupplicantP2pIfaceHidlTest, CancelConnect) { mac_addr_, ISupplicantP2pIface::WpsProvisionMethod::PBC, kTestConnectPin, false, false, kTestConnectGoIntent, [](const SupplicantStatus& status, const hidl_string& /* pin */) { - // This is not going to work with fake values. - EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code); + // After enabling auto-join, it will succeed always. + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); }); p2p_iface_->cancelConnect([](const SupplicantStatus& status) { - EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code); + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); }); } @@ -655,4 +636,4 @@ INSTANTIATE_TEST_CASE_P( android::hardware::getAllHalInstanceNames(IWifi::descriptor)), testing::ValuesIn(android::hardware::getAllHalInstanceNames( ISupplicant::descriptor))), - android::hardware::PrintInstanceTupleNameToString<>); \ No newline at end of file + android::hardware::PrintInstanceTupleNameToString<>); diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp index e4fe52ca7e..6b85e001dd 100644 --- a/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp +++ b/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp @@ -66,42 +66,22 @@ constexpr uint8_t kTestWpsDeviceType[] = {[0 ... 7] = 0x01}; constexpr uint16_t kTestWpsConfigMethods = 0xffff; } // namespace -class SupplicantStaIfaceHidlTest - : public ::testing::TestWithParam> { +class SupplicantStaIfaceHidlTest : public SupplicantHidlTestBaseV1_0 { public: virtual void SetUp() override { - wifi_instance_name_ = std::get<0>(GetParam()); - supplicant_instance_name_ = std::get<1>(GetParam()); - isP2pOn_ = - testing::deviceSupportsFeature("android.hardware.wifi.direct"); - // Stop Framework - std::system("/system/bin/stop"); - stopSupplicant(wifi_instance_name_); - startSupplicantAndWaitForHidlService(wifi_instance_name_, - supplicant_instance_name_); - supplicant_ = getSupplicant(supplicant_instance_name_, isP2pOn_); - EXPECT_TRUE(turnOnExcessiveLogging(supplicant_)); + SupplicantHidlTestBaseV1_0::SetUp(); sta_iface_ = getSupplicantStaIface(supplicant_); ASSERT_NE(sta_iface_.get(), nullptr); memcpy(mac_addr_.data(), kTestMacAddr, mac_addr_.size()); } - virtual void TearDown() override { - stopSupplicant(wifi_instance_name_); - // Start Framework - std::system("/system/bin/start"); - } - protected: bool isP2pOn_ = false; - sp supplicant_; // ISupplicantStaIface object used for all tests in this fixture. sp sta_iface_; // MAC address to use for various tests. std::array mac_addr_; - std::string wifi_instance_name_; - std::string supplicant_instance_name_; }; class IfaceCallback : public ISupplicantStaIfaceCallback { @@ -183,8 +163,8 @@ class IfaceCallback : public ISupplicantStaIfaceCallback { * successfully created. */ TEST_P(SupplicantStaIfaceHidlTest, Create) { - stopSupplicant(wifi_instance_name_); - startSupplicantAndWaitForHidlService(wifi_instance_name_, + stopSupplicant(wifi_v1_0_instance_name_); + startSupplicantAndWaitForHidlService(wifi_v1_0_instance_name_, supplicant_instance_name_); EXPECT_NE(nullptr, getSupplicantStaIface( getSupplicant(supplicant_instance_name_, isP2pOn_)) @@ -566,4 +546,4 @@ INSTANTIATE_TEST_CASE_P( android::hardware::getAllHalInstanceNames(IWifi::descriptor)), testing::ValuesIn(android::hardware::getAllHalInstanceNames( ISupplicant::descriptor))), - android::hardware::PrintInstanceTupleNameToString<>); \ No newline at end of file + android::hardware::PrintInstanceTupleNameToString<>); diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_sta_network_hidl_test.cpp b/wifi/supplicant/1.0/vts/functional/supplicant_sta_network_hidl_test.cpp index 7e93c5f4e9..2b4d681017 100644 --- a/wifi/supplicant/1.0/vts/functional/supplicant_sta_network_hidl_test.cpp +++ b/wifi/supplicant/1.0/vts/functional/supplicant_sta_network_hidl_test.cpp @@ -79,21 +79,10 @@ constexpr uint32_t kTestPairwiseCipher = ISupplicantStaNetwork::PairwiseCipherMask::TKIP); } // namespace -class SupplicantStaNetworkHidlTest - : public ::testing::TestWithParam> { +class SupplicantStaNetworkHidlTest : public SupplicantHidlTestBaseV1_0 { public: virtual void SetUp() override { - wifi_instance_name_ = std::get<0>(GetParam()); - supplicant_instance_name_ = std::get<1>(GetParam()); - isP2pOn_ = - testing::deviceSupportsFeature("android.hardware.wifi.direct"); - // Stop Framework - std::system("/system/bin/stop"); - stopSupplicant(wifi_instance_name_); - startSupplicantAndWaitForHidlService(wifi_instance_name_, - supplicant_instance_name_); - supplicant_ = getSupplicant(supplicant_instance_name_, isP2pOn_); - EXPECT_TRUE(turnOnExcessiveLogging(supplicant_)); + SupplicantHidlTestBaseV1_0::SetUp(); sta_network_ = createSupplicantStaNetwork(supplicant_); ASSERT_NE(sta_network_.get(), nullptr); /* variable used to check if the underlying HAL version is 1.3 or @@ -105,12 +94,6 @@ class SupplicantStaNetworkHidlTest ssid_.assign(kTestSsidStr, kTestSsidStr + strlen(kTestSsidStr)); } - virtual void TearDown() override { - stopSupplicant(wifi_instance_name_); - // Start Framework - std::system("/system/bin/start"); - } - protected: void removeNetwork() { sp sta_iface = getSupplicantStaIface(supplicant_); @@ -128,14 +111,10 @@ class SupplicantStaNetworkHidlTest sp<::android::hardware::wifi::supplicant::V1_3::ISupplicantStaNetwork> v1_3 = nullptr; - bool isP2pOn_ = false; - sp supplicant_; // ISupplicantStaNetwork object used for all tests in this fixture. sp sta_network_; // SSID to use for various tests. std::vector ssid_; - std::string wifi_instance_name_; - std::string supplicant_instance_name_; }; class NetworkCallback : public ISupplicantStaNetworkCallback { @@ -158,8 +137,8 @@ class NetworkCallback : public ISupplicantStaNetworkCallback { * successfully created. */ TEST_P(SupplicantStaNetworkHidlTest, Create) { - stopSupplicant(wifi_instance_name_); - startSupplicantAndWaitForHidlService(wifi_instance_name_, + stopSupplicant(wifi_v1_0_instance_name_); + startSupplicantAndWaitForHidlService(wifi_v1_0_instance_name_, supplicant_instance_name_); sp supplicant = getSupplicant(supplicant_instance_name_, isP2pOn_); diff --git a/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test.cpp b/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test.cpp index 0e404e7f96..3c4d06b107 100644 --- a/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test.cpp +++ b/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test.cpp @@ -35,9 +35,9 @@ using ::android::hardware::wifi::supplicant::V1_0::IfaceType; using ::android::hardware::wifi::supplicant::V1_1::ISupplicant; using ::android::sp; -class SupplicantHidlTest : public SupplicantHidlTestBase { +class SupplicantHidlTest : public SupplicantHidlTestBaseV1_1 { public: - virtual void SetUp() override { SupplicantHidlTestBase::SetUp(); } + virtual void SetUp() override { SupplicantHidlTestBaseV1_1::SetUp(); } protected: std::string getWlan0IfaceName() { diff --git a/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test_utils_1_1.h b/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test_utils_1_1.h index 2104794770..b6feb41abe 100644 --- a/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test_utils_1_1.h +++ b/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test_utils_1_1.h @@ -36,34 +36,15 @@ createSupplicantStaNetwork_1_1( const android::sp& supplicant); -class SupplicantHidlTestBase - : public ::testing::TestWithParam> { +class SupplicantHidlTestBaseV1_1 : public SupplicantHidlTestBase { public: virtual void SetUp() override { - wifi_v1_0_instance_name_ = std::get<0>(GetParam()); - supplicant_v1_1_instance_name_ = std::get<1>(GetParam()); - isP2pOn_ = - testing::deviceSupportsFeature("android.hardware.wifi.direct"); - // Stop Framework - std::system("/system/bin/stop"); - stopSupplicant(wifi_v1_0_instance_name_); - startSupplicantAndWaitForHidlService(wifi_v1_0_instance_name_, - supplicant_v1_1_instance_name_); - supplicant_ = - getSupplicant_1_1(supplicant_v1_1_instance_name_, isP2pOn_); + SupplicantHidlTestBase::SetUp(); + supplicant_ = getSupplicant_1_1(supplicant_instance_name_, isP2pOn_); ASSERT_NE(supplicant_.get(), nullptr); } - virtual void TearDown() override { - stopSupplicant(wifi_v1_0_instance_name_); - // Start Framework - std::system("/system/bin/start"); - } - protected: android::sp supplicant_; - bool isP2pOn_ = false; - std::string wifi_v1_0_instance_name_; - std::string supplicant_v1_1_instance_name_; }; diff --git a/wifi/supplicant/1.1/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.1/vts/functional/supplicant_sta_iface_hidl_test.cpp index 2fade4493d..db6323c191 100644 --- a/wifi/supplicant/1.1/vts/functional/supplicant_sta_iface_hidl_test.cpp +++ b/wifi/supplicant/1.1/vts/functional/supplicant_sta_iface_hidl_test.cpp @@ -39,11 +39,10 @@ using ::android::hardware::wifi::supplicant::V1_1::ISupplicant; using ::android::hardware::wifi::supplicant::V1_1::ISupplicantStaIface; using ::android::hardware::wifi::supplicant::V1_1::ISupplicantStaIfaceCallback; -class SupplicantStaIfaceHidlTest : public SupplicantHidlTestBase { +class SupplicantStaIfaceHidlTest : public SupplicantHidlTestBaseV1_1 { public: virtual void SetUp() override { - SupplicantHidlTestBase::SetUp(); - EXPECT_TRUE(turnOnExcessiveLogging(supplicant_)); + SupplicantHidlTestBaseV1_1::SetUp(); sta_iface_ = getSupplicantStaIface_1_1(supplicant_); ASSERT_NE(sta_iface_.get(), nullptr); } @@ -149,4 +148,4 @@ INSTANTIATE_TEST_CASE_P( testing::ValuesIn(android::hardware::getAllHalInstanceNames( android::hardware::wifi::supplicant::V1_1::ISupplicant:: descriptor))), - android::hardware::PrintInstanceTupleNameToString<>); \ No newline at end of file + android::hardware::PrintInstanceTupleNameToString<>); diff --git a/wifi/supplicant/1.1/vts/functional/supplicant_sta_network_hidl_test.cpp b/wifi/supplicant/1.1/vts/functional/supplicant_sta_network_hidl_test.cpp index bd8a2ab2f7..37641a4a04 100644 --- a/wifi/supplicant/1.1/vts/functional/supplicant_sta_network_hidl_test.cpp +++ b/wifi/supplicant/1.1/vts/functional/supplicant_sta_network_hidl_test.cpp @@ -37,11 +37,10 @@ constexpr uint8_t kTestIdentity[] = {0x45, 0x67, 0x98, 0x67, 0x56}; constexpr uint8_t kTestEncryptedIdentity[] = {0x35, 0x37, 0x58, 0x57, 0x26}; } // namespace -class SupplicantStaNetworkHidlTest : public SupplicantHidlTestBase { +class SupplicantStaNetworkHidlTest : public SupplicantHidlTestBaseV1_1 { public: virtual void SetUp() override { - SupplicantHidlTestBase::SetUp(); - EXPECT_TRUE(turnOnExcessiveLogging(supplicant_)); + SupplicantHidlTestBaseV1_1::SetUp(); sta_network_ = createSupplicantStaNetwork_1_1(supplicant_); ASSERT_NE(sta_network_.get(), nullptr); } @@ -59,9 +58,9 @@ class SupplicantStaNetworkHidlTest : public SupplicantHidlTestBase { TEST_P(SupplicantStaNetworkHidlTest, Create) { stopSupplicant(wifi_v1_0_instance_name_); startSupplicantAndWaitForHidlService(wifi_v1_0_instance_name_, - supplicant_v1_1_instance_name_); + supplicant_instance_name_); sp supplicant = - getSupplicant_1_1(supplicant_v1_1_instance_name_, isP2pOn_); + getSupplicant_1_1(supplicant_instance_name_, isP2pOn_); EXPECT_NE(nullptr, createSupplicantStaNetwork_1_1(supplicant).get()); } @@ -102,4 +101,4 @@ INSTANTIATE_TEST_CASE_P( testing::ValuesIn(android::hardware::getAllHalInstanceNames( android::hardware::wifi::supplicant::V1_1::ISupplicant:: descriptor))), - android::hardware::PrintInstanceTupleNameToString<>); \ No newline at end of file + android::hardware::PrintInstanceTupleNameToString<>); diff --git a/wifi/supplicant/1.2/vts/functional/supplicant_hidl_test_utils_1_2.h b/wifi/supplicant/1.2/vts/functional/supplicant_hidl_test_utils_1_2.h index 2a432d075c..b9c5adef74 100644 --- a/wifi/supplicant/1.2/vts/functional/supplicant_hidl_test_utils_1_2.h +++ b/wifi/supplicant/1.2/vts/functional/supplicant_hidl_test_utils_1_2.h @@ -42,35 +42,16 @@ getSupplicantP2pIface_1_2( const android::sp& supplicant); -class SupplicantHidlTestBase - : public ::testing::TestWithParam> { +class SupplicantHidlTestBaseV1_2 : public SupplicantHidlTestBase { public: virtual void SetUp() override { - wifi_v1_0_instance_name_ = std::get<0>(GetParam()); - supplicant_v1_2_instance_name_ = std::get<1>(GetParam()); - isP2pOn_ = - testing::deviceSupportsFeature("android.hardware.wifi.direct"); - // Stop Framework - std::system("/system/bin/stop"); - stopSupplicant(wifi_v1_0_instance_name_); - startSupplicantAndWaitForHidlService(wifi_v1_0_instance_name_, - supplicant_v1_2_instance_name_); - supplicant_ = - getSupplicant_1_2(supplicant_v1_2_instance_name_, isP2pOn_); + SupplicantHidlTestBase::SetUp(); + supplicant_ = getSupplicant_1_2(supplicant_instance_name_, isP2pOn_); ASSERT_NE(supplicant_.get(), nullptr); EXPECT_TRUE(turnOnExcessiveLogging(supplicant_)); } - virtual void TearDown() override { - stopSupplicant(wifi_v1_0_instance_name_); - // Start Framework - std::system("/system/bin/start"); - } - protected: android::sp supplicant_; - bool isP2pOn_ = false; - std::string wifi_v1_0_instance_name_; - std::string supplicant_v1_2_instance_name_; }; diff --git a/wifi/supplicant/1.2/vts/functional/supplicant_p2p_iface_hidl_test.cpp b/wifi/supplicant/1.2/vts/functional/supplicant_p2p_iface_hidl_test.cpp index 75512d7035..7884cc6a25 100644 --- a/wifi/supplicant/1.2/vts/functional/supplicant_p2p_iface_hidl_test.cpp +++ b/wifi/supplicant/1.2/vts/functional/supplicant_p2p_iface_hidl_test.cpp @@ -38,11 +38,10 @@ constexpr char kTestPassphrase[] = "P2pWorld1234"; constexpr uint8_t kTestZeroMacAddr[] = {[0 ... 5] = 0x0}; } // namespace -class SupplicantP2pIfaceHidlTest : public SupplicantHidlTestBase { +class SupplicantP2pIfaceHidlTest : public SupplicantHidlTestBaseV1_2 { public: virtual void SetUp() override { - SupplicantHidlTestBase::SetUp(); - EXPECT_TRUE(turnOnExcessiveLogging(supplicant_)); + SupplicantHidlTestBaseV1_2::SetUp(); if (!isP2pOn_) { GTEST_SKIP() << "Wi-Fi Direct is not supported, skip this test."; } diff --git a/wifi/supplicant/1.2/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.2/vts/functional/supplicant_sta_iface_hidl_test.cpp index 184543b58d..cd08468938 100644 --- a/wifi/supplicant/1.2/vts/functional/supplicant_sta_iface_hidl_test.cpp +++ b/wifi/supplicant/1.2/vts/functional/supplicant_sta_iface_hidl_test.cpp @@ -53,11 +53,10 @@ using ::android::hardware::wifi::supplicant::V1_2::ISupplicantStaNetwork; #define TIMEOUT_PERIOD 60 class IfaceDppCallback; -class SupplicantStaIfaceHidlTest : public SupplicantHidlTestBase { +class SupplicantStaIfaceHidlTest : public SupplicantHidlTestBaseV1_2 { public: virtual void SetUp() override { - SupplicantHidlTestBase::SetUp(); - EXPECT_TRUE(turnOnExcessiveLogging(supplicant_)); + SupplicantHidlTestBaseV1_2::SetUp(); sta_iface_ = getSupplicantStaIface_1_2(supplicant_); ASSERT_NE(sta_iface_.get(), nullptr); count_ = 0; diff --git a/wifi/supplicant/1.2/vts/functional/supplicant_sta_network_hidl_test.cpp b/wifi/supplicant/1.2/vts/functional/supplicant_sta_network_hidl_test.cpp index 5a2f808949..ee5de69a78 100644 --- a/wifi/supplicant/1.2/vts/functional/supplicant_sta_network_hidl_test.cpp +++ b/wifi/supplicant/1.2/vts/functional/supplicant_sta_network_hidl_test.cpp @@ -37,10 +37,10 @@ using ::android::hardware::wifi::supplicant::V1_2::ISupplicantStaNetwork; // constexpr uint8_t kTestEncryptedIdentity[] = {0x35, 0x37, 0x58, 0x57, 0x26}; //} // namespace -class SupplicantStaNetworkHidlTest : public SupplicantHidlTestBase { +class SupplicantStaNetworkHidlTest : public SupplicantHidlTestBaseV1_2 { public: virtual void SetUp() override { - SupplicantHidlTestBase::SetUp(); + SupplicantHidlTestBaseV1_2::SetUp(); sta_network_ = createSupplicantStaNetwork_1_2(supplicant_); ASSERT_NE(sta_network_.get(), nullptr); } diff --git a/wifi/supplicant/1.3/vts/functional/supplicant_hidl_test_utils_1_3.h b/wifi/supplicant/1.3/vts/functional/supplicant_hidl_test_utils_1_3.h index 69fc598593..b28c5a486d 100644 --- a/wifi/supplicant/1.3/vts/functional/supplicant_hidl_test_utils_1_3.h +++ b/wifi/supplicant/1.3/vts/functional/supplicant_hidl_test_utils_1_3.h @@ -34,4 +34,17 @@ getSupplicant_1_3(const std::string& supplicant_instance_name, bool isP2pOn); bool isFilsSupported( android::sp sta_iface); + +class SupplicantHidlTestBaseV1_3 : public SupplicantHidlTestBase { + public: + virtual void SetUp() override { + SupplicantHidlTestBase::SetUp(); + supplicant_ = getSupplicant_1_3(supplicant_instance_name_, isP2pOn_); + ASSERT_NE(supplicant_.get(), nullptr); + } + + protected: + android::sp + supplicant_; +}; #endif /* SUPPLICANT_HIDL_TEST_UTILS_1_3_H */ diff --git a/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp index 221c393801..6dc267c1c6 100644 --- a/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp +++ b/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp @@ -55,33 +55,14 @@ using ::android::hardware::wifi::supplicant::V1_3::WpaDriverCapabilitiesMask; #define TIMEOUT_PERIOD 60 class IfaceDppCallback; -class SupplicantStaIfaceHidlTest - : public ::testing::TestWithParam> { +class SupplicantStaIfaceHidlTest : public SupplicantHidlTestBaseV1_3 { public: virtual void SetUp() override { - wifi_v1_0_instance_name_ = std::get<0>(GetParam()); - supplicant_v1_3_instance_name_ = std::get<1>(GetParam()); - isP2pOn_ = - testing::deviceSupportsFeature("android.hardware.wifi.direct"); - // Stop Framework - std::system("/system/bin/stop"); - - stopSupplicant(wifi_v1_0_instance_name_); - startSupplicantAndWaitForHidlService(wifi_v1_0_instance_name_, - supplicant_v1_3_instance_name_); - supplicant_ = - getSupplicant_1_3(supplicant_v1_3_instance_name_, isP2pOn_); - EXPECT_TRUE(turnOnExcessiveLogging(supplicant_)); + SupplicantHidlTestBaseV1_3::SetUp(); sta_iface_ = getSupplicantStaIface_1_3(supplicant_); ASSERT_NE(sta_iface_.get(), nullptr); } - virtual void TearDown() override { - stopSupplicant(wifi_v1_0_instance_name_); - // Start Framework - std::system("/system/bin/start"); - } - int64_t pmkCacheExpirationTimeInSec; std::vector serializedPmkCacheEntry; @@ -127,10 +108,6 @@ class SupplicantStaIfaceHidlTest protected: // ISupplicantStaIface object used for all tests in this fixture. sp sta_iface_; - sp supplicant_; - bool isP2pOn_ = false; - std::string wifi_v1_0_instance_name_; - std::string supplicant_v1_3_instance_name_; bool isDppSupported() { uint32_t keyMgmtMask = 0; diff --git a/wifi/supplicant/1.3/vts/functional/supplicant_sta_network_hidl_test.cpp b/wifi/supplicant/1.3/vts/functional/supplicant_sta_network_hidl_test.cpp index 11c55a6a20..12d8d0db0a 100644 --- a/wifi/supplicant/1.3/vts/functional/supplicant_sta_network_hidl_test.cpp +++ b/wifi/supplicant/1.3/vts/functional/supplicant_sta_network_hidl_test.cpp @@ -43,43 +43,20 @@ constexpr OcspType kTestOcspType = OcspType::REQUEST_CERT_STATUS; constexpr OcspType kTestInvalidOcspType = (OcspType)-1; } // namespace -class SupplicantStaNetworkHidlTest - : public ::testing::TestWithParam> { +class SupplicantStaNetworkHidlTest : public SupplicantHidlTestBaseV1_3 { public: virtual void SetUp() override { - wifi_v1_0_instance_name_ = std::get<0>(GetParam()); - supplicant_v1_3_instance_name_ = std::get<1>(GetParam()); - isP2pOn_ = - testing::deviceSupportsFeature("android.hardware.wifi.direct"); - // Stop Framework - std::system("/system/bin/stop"); - - stopSupplicant(wifi_v1_0_instance_name_); - startSupplicantAndWaitForHidlService(wifi_v1_0_instance_name_, - supplicant_v1_3_instance_name_); - supplicant_ = - getSupplicant_1_3(supplicant_v1_3_instance_name_, isP2pOn_); - EXPECT_TRUE(turnOnExcessiveLogging(supplicant_)); + SupplicantHidlTestBaseV1_3::SetUp(); sta_iface_ = getSupplicantStaIface_1_3(supplicant_); ASSERT_NE(nullptr, sta_iface_.get()); sta_network_ = createSupplicantStaNetwork_1_3(supplicant_); ASSERT_NE(sta_network_.get(), nullptr); } - virtual void TearDown() override { - stopSupplicant(wifi_v1_0_instance_name_); - // Start Framework - std::system("/system/bin/start"); - } - protected: sp sta_iface_; // ISupplicantStaNetwork object used for all tests in this fixture. sp sta_network_; - sp supplicant_; - bool isP2pOn_ = false; - std::string wifi_v1_0_instance_name_; - std::string supplicant_v1_3_instance_name_; bool isWapiSupported() { uint32_t keyMgmtMask = 0; diff --git a/wifi/supplicant/1.4/vts/functional/supplicant_hidl_test_utils_1_4.h b/wifi/supplicant/1.4/vts/functional/supplicant_hidl_test_utils_1_4.h index bea4dc102a..60fe1dca65 100644 --- a/wifi/supplicant/1.4/vts/functional/supplicant_hidl_test_utils_1_4.h +++ b/wifi/supplicant/1.4/vts/functional/supplicant_hidl_test_utils_1_4.h @@ -27,4 +27,17 @@ getSupplicantStaIface_1_4( android::sp getSupplicant_1_4(const std::string& supplicant_instance_name, bool isP2pOn); +class SupplicantHidlTestBaseV1_4 : public SupplicantHidlTestBase { + public: + virtual void SetUp() override { + SupplicantHidlTestBase::SetUp(); + supplicant_ = getSupplicant_1_4(supplicant_instance_name_, isP2pOn_); + ASSERT_NE(supplicant_.get(), nullptr); + EXPECT_TRUE(turnOnExcessiveLogging(supplicant_)); + } + + protected: + android::sp + supplicant_; +}; #endif /* SUPPLICANT_HIDL_TEST_UTILS_1_4_H */ diff --git a/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp index 0a20455dd5..5b9c750c4e 100644 --- a/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp +++ b/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp @@ -40,36 +40,17 @@ using ::android::hardware::wifi::supplicant::V1_4::ConnectionCapabilities; using ::android::hardware::wifi::supplicant::V1_4::ISupplicant; using ::android::hardware::wifi::supplicant::V1_4::ISupplicantStaIface; -class SupplicantStaIfaceHidlTest - : public ::testing::TestWithParam> { +class SupplicantStaIfaceHidlTest : public SupplicantHidlTestBaseV1_4 { public: virtual void SetUp() override { - wifi_v1_0_instance_name_ = std::get<0>(GetParam()); - supplicant_v1_4_instance_name_ = std::get<1>(GetParam()); - isP2pOn_ = - testing::deviceSupportsFeature("android.hardware.wifi.direct"); - - stopSupplicant(wifi_v1_0_instance_name_); - startSupplicantAndWaitForHidlService(wifi_v1_0_instance_name_, - supplicant_v1_4_instance_name_); - supplicant_ = - getSupplicant_1_4(supplicant_v1_4_instance_name_, isP2pOn_); - EXPECT_TRUE(turnOnExcessiveLogging(supplicant_)); + SupplicantHidlTestBaseV1_4::SetUp(); sta_iface_ = getSupplicantStaIface_1_4(supplicant_); ASSERT_NE(sta_iface_.get(), nullptr); } - virtual void TearDown() override { - stopSupplicant(wifi_v1_0_instance_name_); - } - protected: // ISupplicantStaIface object used for all tests in this fixture. sp sta_iface_; - sp supplicant_; - bool isP2pOn_ = false; - std::string wifi_v1_0_instance_name_; - std::string supplicant_v1_4_instance_name_; }; /* -- GitLab From 066a7d944cc47098d26c9a6d37b3d6d18820a89f Mon Sep 17 00:00:00 2001 From: John Reck Date: Mon, 14 Sep 2020 13:26:30 -0700 Subject: [PATCH 145/790] Add missing skia_deps Test: make Change-Id: I51e664120fd9fb6f574b5676eedca63df2c13951 --- graphics/composer/2.2/vts/functional/Android.bp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/graphics/composer/2.2/vts/functional/Android.bp b/graphics/composer/2.2/vts/functional/Android.bp index d80845f9dd..16e9138fb5 100644 --- a/graphics/composer/2.2/vts/functional/Android.bp +++ b/graphics/composer/2.2/vts/functional/Android.bp @@ -16,7 +16,11 @@ cc_test { name: "VtsHalGraphicsComposerV2_2TargetTest", - defaults: ["VtsHalTargetTestDefaults"], + defaults: [ + "VtsHalTargetTestDefaults", + // Needed for librenderengine + "skia_deps", + ], srcs: [ "VtsHalGraphicsComposerV2_2ReadbackTest.cpp", "VtsHalGraphicsComposerV2_2TargetTest.cpp", -- GitLab From e29dd0090bf428858bf996257a4d6f9dda582b43 Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Tue, 15 Sep 2020 17:50:48 +0800 Subject: [PATCH 146/790] wifi: remove wifi instance name string check When wifi instance name is empty, HAL should still be started normally. Bug: 161951052 Test: atest VtsHalWifiV1_0TargetTest VtsHalWifiNanV1_0TargetTest VtsHalWifiApV1_0TargetTest \ VtsHalWifiV1_1TargetTest \ VtsHalWifiV1_2TargetTest VtsHalWifiNanV1_2TargetTest \ VtsHalWifiV1_3TargetTest \ VtsHalWifiApV1_4TargetTest VtsHalWifiNanV1_4TargetTest VtsHalWifiRttV1_4TargetTest Change-Id: I2d848501ba3e7d4128b07d8ac858e5ebd31c6452 --- .../1.0/vts/functional/supplicant_hidl_test_utils.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp index 5e7a371d67..a44298a882 100644 --- a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp +++ b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp @@ -52,10 +52,6 @@ namespace { // Helper function to initialize the driver and firmware to STA mode // using the vendor HAL HIDL interface. void initilializeDriverAndFirmware(const std::string& wifi_instance_name) { - // Skip if wifi instance is not set. - if (wifi_instance_name == "") { - return; - } if (getWifi(wifi_instance_name) != nullptr) { sp wifi_chip = getWifiChip(wifi_instance_name); ChipModeId mode_id; @@ -69,10 +65,6 @@ void initilializeDriverAndFirmware(const std::string& wifi_instance_name) { // Helper function to deinitialize the driver and firmware // using the vendor HAL HIDL interface. void deInitilializeDriverAndFirmware(const std::string& wifi_instance_name) { - // Skip if wifi instance is not set. - if (wifi_instance_name == "") { - return; - } if (getWifi(wifi_instance_name) != nullptr) { stopWifi(wifi_instance_name); } else { -- GitLab From 6446c735a6bbafcd627c41171c8ae6abbc274acc Mon Sep 17 00:00:00 2001 From: Yifan Hong Date: Thu, 10 Sep 2020 17:50:44 -0700 Subject: [PATCH 147/790] Add audio V7 to compatility matrix. All HIDL HALs defined in the source tree must be specified in some framework compatibility matrix. Bug: 110261831 Test: builds Change-Id: I98a0798cc08761e8aa6a9ca920c67aa6f8155de4 --- compatibility_matrices/compatibility_matrix.current.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index cfd6d1c70e..f4f846b239 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -9,7 +9,9 @@ android.hardware.audio + 6.0 + 7.0 IDevicesFactory default @@ -17,7 +19,9 @@ android.hardware.audio.effect + 6.0 + 7.0 IEffectsFactory default -- GitLab From 585bb5e581c97e1f19af834f429901118125ca8c Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Tue, 15 Sep 2020 22:52:38 +0000 Subject: [PATCH 148/790] Revert "Add a getAvSyncHwId_64bit in Tuner HAL 1.1 to support 64 bit hw sync id" This reverts commit 80cb96048b6c07666e508137201b4f2a03a6da34. Reason for revert: This change is not specifically requested by vendors Might be unnecessary Test: make -j44, atest VtsHalTvTunerV1_1TargetTest Bug: 159058358 Change-Id: I305c17b4778608a59d04d93030f4ec19fa1b7137 --- tv/tuner/1.1/Android.bp | 1 - tv/tuner/1.1/IDemux.hal | 41 ------------------ tv/tuner/1.1/default/Demux.cpp | 43 ------------------- tv/tuner/1.1/default/Demux.h | 6 +-- tv/tuner/1.1/vts/functional/DemuxTests.cpp | 30 ------------- tv/tuner/1.1/vts/functional/DemuxTests.h | 3 -- .../VtsHalTvTunerV1_1TargetTest.cpp | 40 ----------------- .../functional/VtsHalTvTunerV1_1TargetTest.h | 25 ----------- 8 files changed, 1 insertion(+), 188 deletions(-) delete mode 100644 tv/tuner/1.1/IDemux.hal diff --git a/tv/tuner/1.1/Android.bp b/tv/tuner/1.1/Android.bp index 92769f04ff..6cf47f57b6 100644 --- a/tv/tuner/1.1/Android.bp +++ b/tv/tuner/1.1/Android.bp @@ -4,7 +4,6 @@ hidl_interface { name: "android.hardware.tv.tuner@1.1", root: "android.hardware", srcs: [ - "IDemux.hal", "IFilter.hal", "IFrontend.hal", "IFilterCallback.hal", diff --git a/tv/tuner/1.1/IDemux.hal b/tv/tuner/1.1/IDemux.hal deleted file mode 100644 index 434ecbd461..0000000000 --- a/tv/tuner/1.1/IDemux.hal +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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. - */ - -package android.hardware.tv.tuner@1.1; - -import @1.0::IDemux; -import @1.0::IFilter; -import @1.0::Result; - -/** - * Demultiplexer(Demux) takes a single multiplexed input and splits it into - * one or more output. - */ -interface IDemux extends @1.0::IDemux { - /** - * Get a 64-bit hardware sync ID for audio and video. - * - * It is used by the client to get the hardware sync ID for audio and video. - * - * @param filter the v1_1 filter instance. - * @return result Result status of the operation. - * SUCCESS if successful, - * INVALID_ARGUMENT if failed for a wrong filter ID. - * UNKNOWN_ERROR if failed for other reasons. - * @return avSyncHwId the id of hardware A/V sync. - */ - getAvSyncHwId64Bit(IFilter filter) generates (Result result, uint64_t avSyncHwId); -}; \ No newline at end of file diff --git a/tv/tuner/1.1/default/Demux.cpp b/tv/tuner/1.1/default/Demux.cpp index 007d5eb623..66c95dc3c2 100644 --- a/tv/tuner/1.1/default/Demux.cpp +++ b/tv/tuner/1.1/default/Demux.cpp @@ -34,49 +34,6 @@ Demux::Demux(uint32_t demuxId, sp tuner) { Demux::~Demux() {} -Return Demux::getAvSyncHwId64Bit(const sp& filter, getAvSyncHwId64Bit_cb _hidl_cb) { - ALOGV("%s", __FUNCTION__); - - uint64_t avSyncHwId = -1; - uint64_t id; - Result status; - - sp filter_v1_1 = V1_1::IFilter::castFrom(filter); - if (filter_v1_1 != NULL) { - filter_v1_1->getId64Bit([&](Result result, uint64_t filterId) { - id = filterId; - status = result; - }); - } else { - filter->getId([&](Result result, uint32_t filterId) { - id = filterId; - status = result; - }); - } - - if (status != Result::SUCCESS) { - ALOGE("[Demux] Can't get 64-bit filter Id."); - _hidl_cb(Result::INVALID_STATE, avSyncHwId); - return Void(); - } - - if (!mFilters[id]->isMediaFilter()) { - ALOGE("[Demux] Given filter is not a media filter."); - _hidl_cb(Result::INVALID_ARGUMENT, avSyncHwId); - return Void(); - } - - if (!mPcrFilterIds.empty()) { - // Return the lowest pcr filter id in the default implementation as the av sync id - _hidl_cb(Result::SUCCESS, *mPcrFilterIds.begin()); - return Void(); - } - - ALOGE("[Demux] No PCR filter opened."); - _hidl_cb(Result::INVALID_STATE, avSyncHwId); - return Void(); -} - Return Demux::setFrontendDataSource(uint32_t frontendId) { ALOGV("%s", __FUNCTION__); diff --git a/tv/tuner/1.1/default/Demux.h b/tv/tuner/1.1/default/Demux.h index 3623d0fe10..5212eae02d 100644 --- a/tv/tuner/1.1/default/Demux.h +++ b/tv/tuner/1.1/default/Demux.h @@ -17,7 +17,6 @@ #ifndef ANDROID_HARDWARE_TV_TUNER_V1_1_DEMUX_H_ #define ANDROID_HARDWARE_TV_TUNER_V1_1_DEMUX_H_ -#include #include #include #include @@ -49,15 +48,12 @@ class Frontend; class TimeFilter; class Tuner; -class Demux : public V1_1::IDemux { +class Demux : public IDemux { public: Demux(uint32_t demuxId, sp tuner); ~Demux(); - virtual Return getAvSyncHwId64Bit(const sp& filter, - getAvSyncHwId64Bit_cb _hidl_cb) override; - virtual Return setFrontendDataSource(uint32_t frontendId) override; virtual Return openFilter(const DemuxFilterType& type, uint32_t bufferSize, diff --git a/tv/tuner/1.1/vts/functional/DemuxTests.cpp b/tv/tuner/1.1/vts/functional/DemuxTests.cpp index e0600b62a1..b1d8a0a0b2 100644 --- a/tv/tuner/1.1/vts/functional/DemuxTests.cpp +++ b/tv/tuner/1.1/vts/functional/DemuxTests.cpp @@ -38,34 +38,4 @@ AssertionResult DemuxTests::closeDemux() { auto status = mDemux->close(); mDemux = nullptr; return AssertionResult(status.isOk()); -} - -AssertionResult DemuxTests::getAvSyncId_64bit(sp filter, uint64_t& avSyncHwId) { - EXPECT_TRUE(mDemux) << "Demux is not opened yet."; - Result status; - - sp demux_v1_1 = - android::hardware::tv::tuner::V1_1::IDemux::castFrom(mDemux); - if (demux_v1_1 != NULL) { - demux_v1_1->getAvSyncHwId64Bit(filter, [&](Result result, uint64_t id) { - status = result; - avSyncHwId = id; - }); - } else { - ALOGW("[vts] Can't cast IDemux into v1_1."); - return failure(); - } - - return AssertionResult(status == Result::SUCCESS); -} - -AssertionResult DemuxTests::getAvSyncTime(uint32_t avSyncId) { - EXPECT_TRUE(mDemux) << "Demux is not opened yet."; - Result status; - uint64_t syncTime; - mDemux->getAvSyncTime(avSyncId, [&](Result result, uint64_t time) { - status = result; - syncTime = time; - }); - return AssertionResult(status == Result::SUCCESS); } \ No newline at end of file diff --git a/tv/tuner/1.1/vts/functional/DemuxTests.h b/tv/tuner/1.1/vts/functional/DemuxTests.h index 393757c3b6..c28d6ca524 100644 --- a/tv/tuner/1.1/vts/functional/DemuxTests.h +++ b/tv/tuner/1.1/vts/functional/DemuxTests.h @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -45,8 +44,6 @@ class DemuxTests { AssertionResult openDemux(sp& demux, uint32_t& demuxId); AssertionResult setDemuxFrontendDataSource(uint32_t frontendId); - AssertionResult getAvSyncId_64bit(sp filter, uint64_t& avSyncHwId); - AssertionResult getAvSyncTime(uint32_t avSyncId); AssertionResult closeDemux(); protected: diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp index c3df078c1c..a5aab96638 100644 --- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp @@ -86,41 +86,6 @@ void TunerRecordHidlTest::recordSingleFilterTest(FilterConfig filterConf, ASSERT_TRUE(mFrontendTests.closeFrontend()); } -TEST_P(TunerDemuxHidlTest, getAvSyncTime) { - description("Get the A/V sync time from a PCR filter."); - uint32_t feId; - uint32_t demuxId; - sp demux; - uint64_t mediaFilterId; - uint64_t pcrFilterId; - uint64_t avSyncHwId; - sp mediaFilter; - - mFrontendTests.getFrontendIdByType(frontendArray[DVBT].type, feId); - ASSERT_TRUE(feId != INVALID_ID); - ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); - ASSERT_TRUE(mFrontendTests.setFrontendCallback()); - ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); - ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); - mFilterTests.setDemux(demux); - ASSERT_TRUE(mFilterTests.openFilterInDemux(filterArray[TS_VIDEO1].type, - filterArray[TS_VIDEO1].bufferSize)); - ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(mediaFilterId)); - ASSERT_TRUE(mFilterTests.configFilter(filterArray[TS_VIDEO1].settings, mediaFilterId)); - mediaFilter = mFilterTests.getFilterById(mediaFilterId); - ASSERT_TRUE(mFilterTests.openFilterInDemux(filterArray[TS_PCR0].type, - filterArray[TS_PCR0].bufferSize)); - ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(pcrFilterId)); - ASSERT_TRUE(mFilterTests.configFilter(filterArray[TS_PCR0].settings, pcrFilterId)); - ASSERT_TRUE(mDemuxTests.getAvSyncId_64bit(mediaFilter, avSyncHwId)); - ASSERT_TRUE(pcrFilterId == avSyncHwId); - ASSERT_TRUE(mDemuxTests.getAvSyncTime(pcrFilterId)); - ASSERT_TRUE(mFilterTests.closeFilter(pcrFilterId)); - ASSERT_TRUE(mFilterTests.closeFilter(mediaFilterId)); - ASSERT_TRUE(mDemuxTests.closeDemux()); - ASSERT_TRUE(mFrontendTests.closeFrontend()); -} - TEST_P(TunerFilterHidlTest, StartFilterInDemux) { description("Open and start a filter in Demux."); // TODO use parameterized tests @@ -152,11 +117,6 @@ INSTANTIATE_TEST_SUITE_P( testing::ValuesIn(android::hardware::getAllHalInstanceNames(ITuner::descriptor)), android::hardware::PrintInstanceNameToString); -INSTANTIATE_TEST_SUITE_P( - PerInstance, TunerDemuxHidlTest, - testing::ValuesIn(android::hardware::getAllHalInstanceNames(ITuner::descriptor)), - android::hardware::PrintInstanceNameToString); - INSTANTIATE_TEST_SUITE_P( PerInstance, TunerRecordHidlTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames(ITuner::descriptor)), diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h index 505e35a536..47004f62f0 100644 --- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h @@ -53,31 +53,6 @@ class TunerFilterHidlTest : public testing::TestWithParam { GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerFilterHidlTest); -class TunerDemuxHidlTest : public testing::TestWithParam { - public: - virtual void SetUp() override { - mService = ITuner::getService(GetParam()); - ASSERT_NE(mService, nullptr); - initConfiguration(); - - mFrontendTests.setService(mService); - mDemuxTests.setService(mService); - mFilterTests.setService(mService); - } - - protected: - static void description(const std::string& description) { - RecordProperty("description", description); - } - - sp mService; - FrontendTests mFrontendTests; - DemuxTests mDemuxTests; - FilterTests mFilterTests; -}; - -GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerDemuxHidlTest); - class TunerRecordHidlTest : public testing::TestWithParam { public: virtual void SetUp() override { -- GitLab From a8ae5ac2fa48d6b656f27c9e7b0e9386a39bdbda Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Wed, 25 Dec 2019 20:43:40 +0200 Subject: [PATCH 149/790] wifi: add 60GHz STA support Extend the PairwiseCipherMask and GroupCipherMask enums with GCMP_128 as WiGig doesn't support GCMP_256. Add a flag for enabling EDMG (802.11ay, 60GHz channel bonding) for STA. Bug: 147495507 Test: atest VtsHalWifiV1_0TargetTest VtsHalWifiNanV1_0TargetTest VtsHalWifiApV1_0TargetTest \ VtsHalWifiV1_1TargetTest \ VtsHalWifiV1_2TargetTest VtsHalWifiNanV1_2TargetTest \ VtsHalWifiV1_3TargetTest \ VtsHalWifiApV1_4TargetTest VtsHalWifiNanV1_4TargetTest VtsHalWifiRttV1_4TargetTest Change-Id: I008955c3f6960b888271a679a5ba10ae2f9a9ad1 --- current.txt | 1 + wifi/supplicant/1.4/Android.bp | 1 + wifi/supplicant/1.4/ISupplicantStaNetwork.hal | 126 ++++++++++++++++++ 3 files changed, 128 insertions(+) create mode 100644 wifi/supplicant/1.4/ISupplicantStaNetwork.hal diff --git a/current.txt b/current.txt index b929f7ddd3..9c5091b972 100644 --- a/current.txt +++ b/current.txt @@ -780,3 +780,4 @@ cd84ab19c590e0e73dd2307b591a3093ee18147ef95e6d5418644463a6620076 android.hardwar 57d183b10b13ec0a8e542c0b3d61991ae541c60e85dbbc5499bb21dfd068cbb8 android.hardware.wifi.supplicant@1.4::types 17818b6b1952a75e4364ae82c534b9d2f5c0a9765a56256b16faa5a5cf45d3a8 android.hardware.wifi.supplicant@1.4::ISupplicant 8342b5f6ec8f48ad2b741128aede010995d0b5709257b7ec09bb469b4f61ef1a android.hardware.wifi.supplicant@1.4::ISupplicantStaIface +6f969b191f0b699ceab0573548f1ac505853e56e704711edc51b51976d4f87ad android.hardware.wifi.supplicant@1.4::ISupplicantStaNetwork diff --git a/wifi/supplicant/1.4/Android.bp b/wifi/supplicant/1.4/Android.bp index f3a7cf8104..df0b23a8a6 100644 --- a/wifi/supplicant/1.4/Android.bp +++ b/wifi/supplicant/1.4/Android.bp @@ -7,6 +7,7 @@ hidl_interface { "types.hal", "ISupplicant.hal", "ISupplicantStaIface.hal", + "ISupplicantStaNetwork.hal", ], interfaces: [ "android.hardware.wifi.supplicant@1.0", diff --git a/wifi/supplicant/1.4/ISupplicantStaNetwork.hal b/wifi/supplicant/1.4/ISupplicantStaNetwork.hal new file mode 100644 index 0000000000..7b043d063e --- /dev/null +++ b/wifi/supplicant/1.4/ISupplicantStaNetwork.hal @@ -0,0 +1,126 @@ +/* + * 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. + */ + +package android.hardware.wifi.supplicant@1.4; + +import @1.3::ISupplicantStaNetwork; +import @1.0::SupplicantStatus; + +/** + * Interface exposed by the supplicant for each station mode network + * configuration it controls. + */ +interface ISupplicantStaNetwork extends @1.3::ISupplicantStaNetwork { + /** + * Possible mask of values for PairwiseCipher param. + */ + enum PairwiseCipherMask : @1.3::ISupplicantStaNetwork.PairwiseCipherMask { + /** + * GCMP-128 Pairwise Cipher + */ + GCMP_128 = 1 << 9, + }; + + /** + * Possible mask of values for GroupCipher param. + */ + enum GroupCipherMask : @1.3::ISupplicantStaNetwork.GroupCipherMask { + /** + * GCMP-128 Group Cipher + */ + GCMP_128 = 1 << 9, + }; + + /** + * Set group cipher mask for the network. + * + * @param groupCipherMask value to set. + * Combination of |ProtoMask| values. + * @return status Status of the operation. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_ARGS_INVALID|, + * |SupplicantStatusCode.FAILURE_NETWORK_INVALID|, + * |SupplicantStatusCode.FAILURE_UNKNOWN| + */ + setGroupCipher_1_4(bitfield groupCipherMask) + generates (SupplicantStatus status); + + /** + * Get the group cipher mask set for the network. + * + * @return status Status of the operation. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_NETWORK_INVALID|, + * |SupplicantStatusCode.FAILURE_UNKNOWN| + * @return groupCipherMask Combination of |GroupCipherMask| values. + */ + getGroupCipher_1_4() + generates (SupplicantStatus status, bitfield groupCipherMask); + + /** + * Set pairwise cipher mask for the network. + * + * @param pairwiseCipherMask value to set. + * Combination of |ProtoMask| values. + * @return status Status of the operation. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_ARGS_INVALID|, + * |SupplicantStatusCode.FAILURE_NETWORK_INVALID|, + * |SupplicantStatusCode.FAILURE_UNKNOWN| + */ + setPairwiseCipher_1_4(bitfield pairwiseCipherMask) + generates (SupplicantStatus status); + + /** + * Get the pairwise cipher mask set for the network. + * + * @return status Status of the operation. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_NETWORK_INVALID|, + * |SupplicantStatusCode.FAILURE_UNKNOWN| + * @return pairwiseCipherMask Combination of |PairwiseCipherMask| values. + */ + getPairwiseCipher_1_4() + generates (SupplicantStatus status, bitfield pairwiseCipherMask); + + /** + * Set whether to enable enhanced directional multi-gigabit (802.11ay EDMG). + * Only allowed if hw mode is |HOSTAPD_MODE_IEEE80211AD| + * + * @param enable true to set, false otherwise. + * @return status Status of the operation. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_UNKNOWN|, + * |SupplicantStatusCode.FAILURE_NETWORK_INVALID| + */ + setEdmg(bool enable) generates (SupplicantStatus status); + + /** + * Get whether enhanced directional multi-gigabit (802.11ay EDMG) is enabled for this network. + * + * @return status Status of the operation. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_NETWORK_INVALID| + * @return enabled true if set, false otherwise. + */ + getEdmg() generates (SupplicantStatus status, bool enabled); +}; -- GitLab From b7d50b91eb08c0d321718e3d74e740f3b04b3eac Mon Sep 17 00:00:00 2001 From: Lakshman Annadorai Date: Fri, 11 Sep 2020 11:25:43 -0700 Subject: [PATCH 150/790] Remove MIN and MAX checking for hidl_enum in UserHalHelper native library. VehiclePropValue enums is not sorted by their values. Thus obtaining MIN and MAX values for this enum is O(N), which is the same as looping through all the values and checking whether a given int32_t is in the enum. Test: Tested with `atest -c android.hardware.automotive.vehicle@2.0-utils-unit-tests`. Bug: 168249409 Change-Id: I296a56e31caa7a5ee69eac49806810f83e46571e --- automotive/vehicle/2.0/utils/UserHalHelper.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/automotive/vehicle/2.0/utils/UserHalHelper.cpp b/automotive/vehicle/2.0/utils/UserHalHelper.cpp index fcfe4bf17f..abf59b74e3 100644 --- a/automotive/vehicle/2.0/utils/UserHalHelper.cpp +++ b/automotive/vehicle/2.0/utils/UserHalHelper.cpp @@ -141,11 +141,6 @@ Result parseUserAssociations(const hidl_vec& int32Values, size_t template Result verifyAndCast(int32_t value) { T castValue = static_cast(value); - const auto iter = hidl_enum_range(); - if (castValue < *iter.begin() || castValue > *std::prev(iter.end())) { - return Error() << "Value " << value << " not in range [" << toString(*iter.begin()) << ", " - << toString(*std::prev(iter.end())) << "]"; - } for (const auto& v : hidl_enum_range()) { if (castValue == v) { return castValue; -- GitLab From 7d3fdf5ef6a46da024173ae341679bc850bdc30e Mon Sep 17 00:00:00 2001 From: Kevin Chyn Date: Tue, 15 Sep 2020 13:01:40 -0700 Subject: [PATCH 151/790] Add android.hardware.biometrics.common Bug: 168541000 Test: make -j56 android.hardware.biometrics.common-update-api Test: make -j56 android.hardware.biometrics.fingerprint-update-api Test: make -j56 android.hardware.biometrics.fingerprint-service.example Change-Id: Icaa1c2a0363a7fa446747ef89b5e50ca44dcd42e --- biometrics/common/aidl/Android.bp | 16 +++++++ .../biometrics/common/CommonProps.aidl | 24 ++++++++++ .../biometrics/common/SensorStrength.aidl | 24 ++++++++++ .../biometrics/common/CommonProps.aidl | 43 ++++++++++++++++++ .../biometrics/common/SensorStrength.aidl | 44 +++++++++++++++++++ biometrics/fingerprint/aidl/Android.bp | 1 + ...orType.aidl => FingerprintSensorType.aidl} | 2 +- .../biometrics/fingerprint/SensorProps.aidl | 5 +-- ...orType.aidl => FingerprintSensorType.aidl} | 2 +- .../biometrics/fingerprint/SensorProps.aidl | 16 ++++--- .../fingerprint/aidl/default/Fingerprint.cpp | 14 +++++- biometrics/fingerprint/aidl/default/main.cpp | 1 + .../exclude/fcm_exclude.cpp | 1 + 13 files changed, 182 insertions(+), 11 deletions(-) create mode 100644 biometrics/common/aidl/Android.bp create mode 100644 biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/CommonProps.aidl create mode 100644 biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/SensorStrength.aidl create mode 100644 biometrics/common/aidl/android/hardware/biometrics/common/CommonProps.aidl create mode 100644 biometrics/common/aidl/android/hardware/biometrics/common/SensorStrength.aidl rename biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/{SensorType.aidl => FingerprintSensorType.aidl} (97%) rename biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/{SensorType.aidl => FingerprintSensorType.aidl} (96%) diff --git a/biometrics/common/aidl/Android.bp b/biometrics/common/aidl/Android.bp new file mode 100644 index 0000000000..f7462e6f51 --- /dev/null +++ b/biometrics/common/aidl/Android.bp @@ -0,0 +1,16 @@ +aidl_interface { + name: "android.hardware.biometrics.common", + vendor_available: true, + srcs: [ + "android/hardware/biometrics/common/*.aidl", + ], + stability: "vintf", + backend: { + java: { + platform_apis: true, + }, + cpp: { + enabled: false, + }, + } +} \ No newline at end of file diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/CommonProps.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/CommonProps.aidl new file mode 100644 index 0000000000..57574b5385 --- /dev/null +++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/CommonProps.aidl @@ -0,0 +1,24 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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 CommonProps { + int sensorId; + android.hardware.biometrics.common.SensorStrength sensorStrength; + int maxEnrollmentsPerUser; +} diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/SensorStrength.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/SensorStrength.aidl new file mode 100644 index 0000000000..eaff85d2f9 --- /dev/null +++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/SensorStrength.aidl @@ -0,0 +1,24 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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 SensorStrength { + CONVENIENCE = 0, + WEAK = 1, + STRONG = 2, +} diff --git a/biometrics/common/aidl/android/hardware/biometrics/common/CommonProps.aidl b/biometrics/common/aidl/android/hardware/biometrics/common/CommonProps.aidl new file mode 100644 index 0000000000..5982397fbf --- /dev/null +++ b/biometrics/common/aidl/android/hardware/biometrics/common/CommonProps.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. + */ + +package android.hardware.biometrics.common; + +import android.hardware.biometrics.common.SensorStrength; + +@VintfStability +parcelable CommonProps { + /** + * A statically configured unique ID that identifies a single biometric + * sensor. IDs must start at zero and increment by one for each unique + * sensor. Note that ID allocations are shared between all biometric + * modalities (e.g. fingerprint, face, iris), and a single ID must never + * be claimed by more than a single sensor. + */ + int sensorId; + + /** + * A statically configured strength for this sensor. See the SensorStrength + * interface for more information. + */ + SensorStrength sensorStrength; + + /** + * The maximum number of enrollments that a single user can have. + * Statically configured. + */ + int maxEnrollmentsPerUser; +} \ No newline at end of file diff --git a/biometrics/common/aidl/android/hardware/biometrics/common/SensorStrength.aidl b/biometrics/common/aidl/android/hardware/biometrics/common/SensorStrength.aidl new file mode 100644 index 0000000000..7460279728 --- /dev/null +++ b/biometrics/common/aidl/android/hardware/biometrics/common/SensorStrength.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. + */ + +package android.hardware.biometrics.common; + +@VintfStability +@Backing(type="byte") +enum SensorStrength { + /** + * A sensor that meets the requirements for Class 1 biometrics as defined + * in the CDD. This does not correspond to a public BiometricManager.Authenticators + * constant. Sensors of this strength are not available to applications ia the + * public API surface. + */ + CONVENIENCE, + + /** + * A sensor that meets the requirements for Class 2 biometrics as defined + * in the CDD. Corresponds to BiometricManager.Authenticators.BIOMETRIC_WEAK. + */ + WEAK, + + /** + * A sensor that meets the requirements for Class 3 biometrics as defined + * in the CDD. Corresponds to BiometricManager.Authenticators.BIOMETRIC_STRONG. + * + * Notably, this is the only strength that allows generation/verification of + * HardwareAuthToken(s). + */ + STRONG, +} \ No newline at end of file diff --git a/biometrics/fingerprint/aidl/Android.bp b/biometrics/fingerprint/aidl/Android.bp index e6baa8a8b9..6bf20386e1 100644 --- a/biometrics/fingerprint/aidl/Android.bp +++ b/biometrics/fingerprint/aidl/Android.bp @@ -5,6 +5,7 @@ aidl_interface { "android/hardware/biometrics/fingerprint/**/*.aidl", ], imports: [ + "android.hardware.biometrics.common", "android.hardware.keymaster", ], stability: "vintf", diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorType.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl similarity index 97% rename from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorType.aidl rename to biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl index 2aaf94fc01..14bfece745 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorType.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl @@ -17,7 +17,7 @@ package android.hardware.biometrics.fingerprint; @Backing(type="byte") @VintfStability -enum SensorType { +enum FingerprintSensorType { UNKNOWN = 0, REAR = 1, UNDER_DISPLAY_ULTRASONIC = 2, diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl index c30e35d96b..04a8f8671f 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl @@ -18,7 +18,6 @@ package android.hardware.biometrics.fingerprint; @VintfStability parcelable SensorProps { - int sensorId; - android.hardware.biometrics.fingerprint.SensorType sensorType; - boolean resetLockoutRequiresHardwareAuthToken; + android.hardware.biometrics.common.CommonProps commonProps; + android.hardware.biometrics.fingerprint.FingerprintSensorType sensorType; } diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorType.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl similarity index 96% rename from biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorType.aidl rename to biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl index 589e737f93..765a2ed664 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorType.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl @@ -18,7 +18,7 @@ package android.hardware.biometrics.fingerprint; @VintfStability @Backing(type="byte") -enum SensorType { +enum FingerprintSensorType { UNKNOWN, REAR, UNDER_DISPLAY_ULTRASONIC, diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl index bbb1ecb622..5355c5eea9 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl @@ -16,14 +16,20 @@ package android.hardware.biometrics.fingerprint; -import android.hardware.biometrics.fingerprint.SensorType; +import android.hardware.biometrics.common.CommonProps; +import android.hardware.biometrics.fingerprint.FingerprintSensorType; @VintfStability parcelable SensorProps { - int sensorId; + /** + * Statically configured properties that apply to this fingerprint sensor. + */ + CommonProps commonProps; - SensorType sensorType; - - boolean resetLockoutRequiresHardwareAuthToken; + /** + * A statically configured sensor type representing this fingerprint + * sensor. + */ + FingerprintSensorType sensorType; } diff --git a/biometrics/fingerprint/aidl/default/Fingerprint.cpp b/biometrics/fingerprint/aidl/default/Fingerprint.cpp index 6f9e3a0628..6eb62377b0 100644 --- a/biometrics/fingerprint/aidl/default/Fingerprint.cpp +++ b/biometrics/fingerprint/aidl/default/Fingerprint.cpp @@ -19,7 +19,19 @@ namespace aidl::android::hardware::biometrics::fingerprint { -ndk::ScopedAStatus Fingerprint::getSensorProps(std::vector* /*return_val*/) { +const int kSensorId = 0; +const common::SensorStrength kSensorStrength = common::SensorStrength::STRONG; +const int kMaxEnrollmentsPerUser = 5; +const FingerprintSensorType kSensorType = FingerprintSensorType::REAR; + +ndk::ScopedAStatus Fingerprint::getSensorProps(std::vector* return_val) { + *return_val = std::vector(); + common::CommonProps commonProps = {kSensorId, + kSensorStrength, + kMaxEnrollmentsPerUser}; + SensorProps props = {commonProps, + kSensorType}; + return_val->push_back(props); return ndk::ScopedAStatus::ok(); } diff --git a/biometrics/fingerprint/aidl/default/main.cpp b/biometrics/fingerprint/aidl/default/main.cpp index 058a008370..4690d73d80 100644 --- a/biometrics/fingerprint/aidl/default/main.cpp +++ b/biometrics/fingerprint/aidl/default/main.cpp @@ -23,6 +23,7 @@ using aidl::android::hardware::biometrics::fingerprint::Fingerprint; int main() { + LOG(INFO) << "Fingerprint HAL started"; ABinderProcess_setThreadPoolMaxThreadCount(0); std::shared_ptr hal = ndk::SharedRefBase::make(); diff --git a/compatibility_matrices/exclude/fcm_exclude.cpp b/compatibility_matrices/exclude/fcm_exclude.cpp index 50653a15a2..ce25a1936d 100644 --- a/compatibility_matrices/exclude/fcm_exclude.cpp +++ b/compatibility_matrices/exclude/fcm_exclude.cpp @@ -58,6 +58,7 @@ bool ShouldCheckMissingHalsInFcm(const std::string& package) { "android.hardware.gnss.visibility_control@1.0", "android.hardware.radio.config@1.2", // AIDL + "android.hardware.biometrics.common", "android.hardware.common", "android.hardware.graphics.common", "android.hardware.keymaster", -- GitLab From 4699ec631e4996a95ca0afb5e5a0aa94c24e0abd Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Thu, 10 Sep 2020 15:51:19 -0700 Subject: [PATCH 152/790] Extend DVBT Constellation to report the rotation status Test: make Bug: Change-Id: I24356125ec889c313459beba5e3caef2d3413fa7 --- tv/tuner/1.1/IFilterCallback.hal | 2 +- tv/tuner/1.1/IFrontend.hal | 5 +++-- tv/tuner/1.1/types.hal | 26 +++++++++++++------------- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/tv/tuner/1.1/IFilterCallback.hal b/tv/tuner/1.1/IFilterCallback.hal index 3e5f047f22..9960a23775 100644 --- a/tv/tuner/1.1/IFilterCallback.hal +++ b/tv/tuner/1.1/IFilterCallback.hal @@ -18,7 +18,7 @@ package android.hardware.tv.tuner@1.1; import @1.0::IFilterCallback; import @1.0::DemuxFilterEvent; -import @1.1::DemuxFilterEventExt; +import DemuxFilterEventExt; interface IFilterCallback extends @1.0::IFilterCallback { /** diff --git a/tv/tuner/1.1/IFrontend.hal b/tv/tuner/1.1/IFrontend.hal index 0b0ce39525..9858d4b061 100644 --- a/tv/tuner/1.1/IFrontend.hal +++ b/tv/tuner/1.1/IFrontend.hal @@ -45,7 +45,8 @@ interface IFrontend extends @1.0::IFrontend { * INVALID_STATE if tuning can't be applied at current stage, * UNKNOWN_ERROR if tuning failed for other reasons. */ - tune_1_1(FrontendSettings settings, FrontendSettingsExt settingsExt) generates (Result result); + tune_1_1(FrontendSettings settings, FrontendSettingsExt settingsExt) + generates (Result result); /** * Scan the frontend to use the settings given. @@ -66,7 +67,7 @@ interface IFrontend extends @1.0::IFrontend { * UNKNOWN_ERROR if tuning failed for other reasons. */ scan_1_1(FrontendSettings settings, FrontendScanType type, FrontendSettingsExt settingsExt) - generates (Result result); + generates (Result result); /** * Link Conditional Access Modules (CAM) to Frontend support Common Interface (CI) bypass mode. diff --git a/tv/tuner/1.1/types.hal b/tv/tuner/1.1/types.hal index 9e2f453b70..fe3581101b 100644 --- a/tv/tuner/1.1/types.hal +++ b/tv/tuner/1.1/types.hal @@ -20,6 +20,7 @@ import @1.0::Constant; import @1.0::DemuxFilterMmtpRecordEvent; import @1.0::DemuxFilterTsRecordEvent; import @1.0::FrontendDvbcSpectralInversion; +import @1.0::FrontendDvbtConstellation; import @1.0::FrontendDvbtTransmissionMode; import android.hidl.safe_union@1.0; import android.hidl.safe_union@1.0::Monostate; @@ -105,16 +106,6 @@ enum FrontendDvbsScanType : uint32_t { JESS, }; -/** - * Rotation status for a DVBT Frontend. - */ -@export -enum FrontendDvbtRotation : uint32_t { - UNDEFINED, - NOT_ROTATED, - ROTATED, -}; - /** * AFT flag for an Analog Frontend. */ @@ -131,12 +122,21 @@ enum FrontendAnalogAftFlag : uint32_t { @export enum FrontendDvbtTransmissionMode : @1.0::FrontendDvbtTransmissionMode { MODE_8K_E = 1 << 7, - MODE_16K_E = 1 << 8, - MODE_32K_E = 1 << 9, }; +/** + * Extended Constellation for DVBT. + */ +@export +enum FrontendDvbtConstellation : @1.0::FrontendDvbtConstellation { + CONSTELLATION_QPSK_R = 1 << 5, + CONSTELLATION_16QAM_R = 1 << 6, + CONSTELLATION_64QAM_R = 1 << 7, + CONSTELLATION_256QAM_R = 1 << 8, +}; + /** * Extended Signal Settings for a DVBS Frontend. */ @@ -148,7 +148,7 @@ struct FrontendDvbsSettingsExt { * Extended Signal Settings for a DVBT Frontend. */ struct FrontendDvbtSettingsExt { - FrontendDvbtRotation rotation; + FrontendDvbtConstellation constellation; FrontendDvbtTransmissionMode transmissionMode; }; -- GitLab From 6e862c31a1ebbca8c4596de46c2bdca61098c031 Mon Sep 17 00:00:00 2001 From: Kevin Chyn Date: Wed, 16 Sep 2020 18:27:37 -0700 Subject: [PATCH 153/790] Add authenticatorId changes to Fingerprint aidl Also adds a top-level README for the biometric package Bug: 159667191 Bug: 168541000 Test: make -j56 android.hardware.biometrics.fingerprint-update-api Test: make -j56 VtsHalBiometricsFingerprintTargetTest Change-Id: I3dba8e7ee16700865662c1a00b75576d2513f930 --- biometrics/README.md | 12 ++++ .../biometrics/fingerprint/IFingerprint.aidl | 2 +- .../biometrics/fingerprint/ISession.aidl | 1 + .../fingerprint/ISessionCallback.aidl | 2 + .../biometrics/fingerprint/IFingerprint.aidl | 2 +- .../biometrics/fingerprint/ISession.aidl | 68 +++++++++++++++++++ .../fingerprint/ISessionCallback.aidl | 10 +++ .../fingerprint/aidl/default/Fingerprint.cpp | 4 +- .../fingerprint/aidl/default/Fingerprint.h | 2 +- .../fingerprint/aidl/default/Session.cpp | 5 ++ biometrics/fingerprint/aidl/default/Session.h | 3 + .../VtsHalBiometricsFingerprintTargetTest.cpp | 8 +++ 12 files changed, 114 insertions(+), 5 deletions(-) create mode 100644 biometrics/README.md diff --git a/biometrics/README.md b/biometrics/README.md new file mode 100644 index 0000000000..8ae1ad6460 --- /dev/null +++ b/biometrics/README.md @@ -0,0 +1,12 @@ +## Biometric HALs ## +--- + +## Overview: ## + +The interfaces within the biometrics.* HAL tree are used by the Android Biometric Services +(e.g. FingerprintService, FaceService) to discover and operate biometric sensors on the device. + +More details and versioning information can be found within each particular HAL. + +More complete information about the Android Biometric HALs and subsystem can be found at +[source.android.com](https://source.android.com/security/biometric). \ No newline at end of file diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl index a376acfbe9..85d1f57e05 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl @@ -21,6 +21,6 @@ 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); void setResetLockoutCallback(in android.hardware.biometrics.fingerprint.IResetLockoutCallback cb); - void generateChallenge(in int sensorId, in int userId, in long keystoreOperationId, in int timeoutSec, in android.hardware.biometrics.fingerprint.IGenerateChallengeCallback cb); + void generateChallenge(in int sensorId, in int userId, in int timeoutSec, in android.hardware.biometrics.fingerprint.IGenerateChallengeCallback cb); void revokeChallenge(in int sensorId, in int userId, in android.hardware.biometrics.fingerprint.IRevokeChallengeCallback cb); } 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 4b71527f71..d92ca4f943 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 @@ -24,6 +24,7 @@ interface ISession { void enumerateEnrollments(in int cookie); void removeEnrollments(in int cookie, in int[] enrollmentIds); void getAuthenticatorId(in int cookie); + void invalidateAuthenticatorId(in int cookie, in android.hardware.keymaster.HardwareAuthToken hat); void resetLockout(in int cookie, in android.hardware.keymaster.HardwareAuthToken hat); void onPointerDown(in int pointerId, in int x, in int y, in float minor, in float major); void onPointerUp(in int pointerId); diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl index f50554b458..614044790a 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl @@ -26,4 +26,6 @@ interface ISessionCallback { void onInteractionDetected(); void onEnrollmentsEnumerated(in int[] enrollmentIds); void onEnrollmentsRemoved(in int[] enrollmentIds); + void onAuthenticatorIdRetrieved(in long authenticatorId); + void onAuthenticatorIdInvalidated(); } diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl index 9aafeab17d..47097785b5 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl @@ -31,7 +31,7 @@ interface IFingerprint { void setResetLockoutCallback(in IResetLockoutCallback cb); - void generateChallenge(in int sensorId, in int userId, in long keystoreOperationId, in int timeoutSec, in IGenerateChallengeCallback cb); + void generateChallenge(in int sensorId, in int userId, in int timeoutSec, in IGenerateChallengeCallback cb); void revokeChallenge(in int sensorId, in int userId, in IRevokeChallengeCallback cb); } diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl index 78da7ae845..55ea385adb 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl @@ -35,8 +35,76 @@ interface ISession { void removeEnrollments(in int cookie, in int[] enrollmentIds); + /** + * getAuthenticatorId: + * + * MUST return 0 via ISessionCallback#onAuthenticatorIdRetrieved for + * sensors that are configured as SensorStrength::WEAK or + * SensorStrength::CONVENIENCE. + * + * The following only applies to sensors that are configured as + * SensorStrength::STRONG. + * + * The authenticatorId is used during key generation and key import to to + * associate a key (in KeyStore / KeyMaster) with the current set of + * enrolled fingerprints. For example, the following public Android APIs + * allow for keys to be invalidated when the user adds a new enrollment + * after the key was created: + * KeyGenParameterSpec.Builder.setInvalidatedByBiometricEnrollment and + * KeyProtection.Builder.setInvalidatedByBiometricEnrollment. + * + * In addition, upon successful fingerprint authentication, the signed HAT + * that is returned to the framework via ISessionCallback#onAuthenticated + * must contain this identifier in the authenticatorId field. + * + * Returns an entropy-encoded random identifier associated with the current + * set of enrollments via ISessionCallback#onAuthenticatorIdRetrieved. The + * authenticatorId + * 1) MUST change whenever a new fingerprint is enrolled + * 2) MUST return 0 if no fingerprints are enrolled + * 3) MUST not change if a fingerprint is deleted. + * 4) MUST be an entropy-encoded random number + * + * @param cookie An identifier used to track subsystem operations related + * to this call path. The framework will guarantee that it is + * unique per ISession. + */ void getAuthenticatorId(in int cookie); + /** + * invalidateAuthenticatorId: + * + * This method only applies to sensors that are configured as + * SensorStrength::STRONG. If invoked erroneously by the framework for + * sensor of other strengths, the HAL should immediately invoke + * ISessionCallback#onAuthenticatorIdInvalidated. + * + * The following only applies to sensors that are configured as + * SensorStrength::STRONG. + * + * When invoked by the framework, the HAL implementation must perform the + * following sequence of events: + * 1) Verify the authenticity and integrity of the provided HAT + * 2) Update the authenticatorId with a new entropy-encoded random number + * 3) Persist the new authenticatorId to non-ephemeral storage + * 4) Notify the framework that the above is completed, via + * ISessionCallback#onAuthenticatorInvalidated + * + * A practical use case of invalidation would be when the user adds a new + * enrollment to a sensor managed by a different HAL instance. The + * public android.security.keystore APIs bind keys to "all biometrics" + * rather than "fingerprint-only" or "face-only" (see #getAuthenticatorId + * for more details). As such, the framework would coordinate invalidation + * across multiple biometric HALs as necessary. + * + * @param cookie An identifier used to track subsystem operations related + * to this call path. The framework will guarantee that it is + * unique per ISession. + * @param hat HardwareAuthToken that must be validated before proceeding + * with this operation. + */ + void invalidateAuthenticatorId(in int cookie, in HardwareAuthToken hat); + void resetLockout(in int cookie, in HardwareAuthToken hat); diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl index 655f030d54..c608d65569 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl @@ -38,4 +38,14 @@ interface ISessionCallback { void onEnrollmentsEnumerated(in int[] enrollmentIds); void onEnrollmentsRemoved(in int[] enrollmentIds); + + /** + * A callback invoked when ISession#getAuthenticatorId is invoked. + */ + void onAuthenticatorIdRetrieved(in long authenticatorId); + + /** + * A callback invoked when ISession#invalidateAuthenticatorId has completed. + */ + void onAuthenticatorIdInvalidated(); } diff --git a/biometrics/fingerprint/aidl/default/Fingerprint.cpp b/biometrics/fingerprint/aidl/default/Fingerprint.cpp index 6eb62377b0..b5d3949da4 100644 --- a/biometrics/fingerprint/aidl/default/Fingerprint.cpp +++ b/biometrics/fingerprint/aidl/default/Fingerprint.cpp @@ -48,8 +48,8 @@ ndk::ScopedAStatus Fingerprint::setResetLockoutCallback( } ndk::ScopedAStatus Fingerprint::generateChallenge( - int32_t /*sensorId*/, int32_t /*userId*/, int64_t /*keystoreOperationId*/, - int32_t /*timeoutSec*/, const std::shared_ptr& /*cb*/) { + int32_t /*sensorId*/, int32_t /*userId*/, int32_t /*timeoutSec*/, + const std::shared_ptr& /*cb*/) { return ndk::ScopedAStatus::ok(); } diff --git a/biometrics/fingerprint/aidl/default/Fingerprint.h b/biometrics/fingerprint/aidl/default/Fingerprint.h index 9f04893592..b5b09c0b74 100644 --- a/biometrics/fingerprint/aidl/default/Fingerprint.h +++ b/biometrics/fingerprint/aidl/default/Fingerprint.h @@ -32,7 +32,7 @@ class Fingerprint : public BnFingerprint { const std::shared_ptr& cb) override; ndk::ScopedAStatus generateChallenge( - int32_t sensorId, int32_t userId, int64_t keystoreOperationId, int32_t timeoutSec, + int32_t sensorId, int32_t userId, int32_t timeoutSec, const std::shared_ptr& cb) override; ndk::ScopedAStatus revokeChallenge( diff --git a/biometrics/fingerprint/aidl/default/Session.cpp b/biometrics/fingerprint/aidl/default/Session.cpp index 5eb3134ec1..a3dd75e62d 100644 --- a/biometrics/fingerprint/aidl/default/Session.cpp +++ b/biometrics/fingerprint/aidl/default/Session.cpp @@ -59,6 +59,11 @@ ndk::ScopedAStatus Session::getAuthenticatorId(int32_t /*cookie*/) { return ndk::ScopedAStatus::ok(); } +ndk::ScopedAStatus Session::invalidateAuthenticatorId(int32_t /*cookie*/, + const keymaster::HardwareAuthToken& /*hat*/) { + return ndk::ScopedAStatus::ok(); +} + ndk::ScopedAStatus Session::resetLockout(int32_t /*cookie*/, const keymaster::HardwareAuthToken& /*hat*/) { return ndk::ScopedAStatus::ok(); diff --git a/biometrics/fingerprint/aidl/default/Session.h b/biometrics/fingerprint/aidl/default/Session.h index 69950fb8d3..781e95a222 100644 --- a/biometrics/fingerprint/aidl/default/Session.h +++ b/biometrics/fingerprint/aidl/default/Session.h @@ -43,6 +43,9 @@ class Session : public BnSession { ndk::ScopedAStatus getAuthenticatorId(int32_t cookie) override; + ndk::ScopedAStatus invalidateAuthenticatorId(int32_t cookie, + const keymaster::HardwareAuthToken& hat) override; + ndk::ScopedAStatus resetLockout(int32_t cookie, const keymaster::HardwareAuthToken& hat) override; diff --git a/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp b/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp index 88980bf8c9..1a39ad4c12 100644 --- a/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp +++ b/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp @@ -82,6 +82,14 @@ class SessionCallback : public BnSessionCallback { return ndk::ScopedAStatus::ok(); } + ndk::ScopedAStatus onAuthenticatorIdRetrieved(int64_t /*authenticatorId*/) override { + return ndk::ScopedAStatus::ok(); + } + + ndk::ScopedAStatus onAuthenticatorIdInvalidated() override { + return ndk::ScopedAStatus::ok(); + } + private: std::promise invocation_promise_; }; -- GitLab From 94a82210c99caa062e620e0443f6252589dccd1c Mon Sep 17 00:00:00 2001 From: Kevin Chyn Date: Wed, 16 Sep 2020 18:55:39 -0700 Subject: [PATCH 154/790] Add sensorLocation, sensorRadius, displayId to SensorProps Bug: 168541000 Test: make -j56 android.hardware.biometrics.fingerprint-update-api Change-Id: Ia8323a114c74ec9c6680333c868881ac51e6363f --- .../biometrics/fingerprint/SensorProps.aidl | 4 +++ .../biometrics/fingerprint/SensorProps.aidl | 30 +++++++++++++++++++ .../fingerprint/aidl/default/Fingerprint.cpp | 6 +++- 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl index 04a8f8671f..9d946a9247 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl @@ -20,4 +20,8 @@ package android.hardware.biometrics.fingerprint; parcelable SensorProps { android.hardware.biometrics.common.CommonProps commonProps; android.hardware.biometrics.fingerprint.FingerprintSensorType sensorType; + int sensorLocationX; + int sensorLocationY; + int sensorRadius; + int displayId; } diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl index 5355c5eea9..7c1e1760af 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl @@ -31,5 +31,35 @@ parcelable SensorProps { * sensor. */ FingerprintSensorType sensorType; + + /** + * The location of the center of the sensor if applicable. For example, + * sensors of FingerprintSensorType::UNDER_DISPLAY_* would report this + * value as the distance in pixels, measured from the left edge of the + * screen. + */ + int sensorLocationX; + + /** + * The location of the center of the sensor if applicable. For example, + * sensors of FingerprintSensorType::UNDER_DISPLAY_* would report this + * value as the distance in pixels, measured from the top edge of the + * screen. + */ + int sensorLocationY; + + /** + * The radius of the sensor if applicable. For example, sensors of + * FingerprintSensorType::UNDER_DISPLAY_* would report this value as + * the radius of the sensor, in pixels. + */ + int sensorRadius; + + /** + * For sensors of FingerprintSensorType::UNDER_DISPLAY_*, this must + * correspond to the android.hardware.DisplayManager#getDisplay Android + * API. + */ + int displayId; } diff --git a/biometrics/fingerprint/aidl/default/Fingerprint.cpp b/biometrics/fingerprint/aidl/default/Fingerprint.cpp index b5d3949da4..80266d2e86 100644 --- a/biometrics/fingerprint/aidl/default/Fingerprint.cpp +++ b/biometrics/fingerprint/aidl/default/Fingerprint.cpp @@ -30,7 +30,11 @@ ndk::ScopedAStatus Fingerprint::getSensorProps(std::vector* return_ kSensorStrength, kMaxEnrollmentsPerUser}; SensorProps props = {commonProps, - kSensorType}; + kSensorType, + 0 /* sensorLocationX */, + 0 /* sensorLocationY */, + 0 /* sensorRadius */, + 0 /* displayId */}; return_val->push_back(props); return ndk::ScopedAStatus::ok(); } -- GitLab From c306b76f7fea5ff690a5c4336352d2be0df82b7e Mon Sep 17 00:00:00 2001 From: Kevin Chyn Date: Thu, 17 Sep 2020 12:40:09 -0700 Subject: [PATCH 155/790] Add HardwareInfo to CommonProps Bug: 168541000 Test: make -j android.hardware.biometrics.common-update-api Test: make -j Change-Id: I2a96a46dc768b4cdb500ca8ea6bfd23c9f724866 --- .../biometrics/common/CommonProps.aidl | 1 + .../biometrics/common/HardwareInfo.aidl | 25 ++++++++++++ .../biometrics/common/CommonProps.aidl | 7 ++++ .../biometrics/common/HardwareInfo.aidl | 40 +++++++++++++++++++ .../fingerprint/aidl/default/Fingerprint.cpp | 15 ++++++- 5 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/HardwareInfo.aidl create mode 100644 biometrics/common/aidl/android/hardware/biometrics/common/HardwareInfo.aidl diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/CommonProps.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/CommonProps.aidl index 57574b5385..8dbc149fa8 100644 --- a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/CommonProps.aidl +++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/CommonProps.aidl @@ -21,4 +21,5 @@ parcelable CommonProps { int sensorId; android.hardware.biometrics.common.SensorStrength sensorStrength; int maxEnrollmentsPerUser; + android.hardware.biometrics.common.HardwareInfo[] hardwareInfo; } diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/HardwareInfo.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/HardwareInfo.aidl new file mode 100644 index 0000000000..b94b6b0174 --- /dev/null +++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/HardwareInfo.aidl @@ -0,0 +1,25 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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 HardwareInfo { + String deviceName; + String hardwareVersion; + String firmwareVersion; + String serialNumber; +} diff --git a/biometrics/common/aidl/android/hardware/biometrics/common/CommonProps.aidl b/biometrics/common/aidl/android/hardware/biometrics/common/CommonProps.aidl index 5982397fbf..8304c953cc 100644 --- a/biometrics/common/aidl/android/hardware/biometrics/common/CommonProps.aidl +++ b/biometrics/common/aidl/android/hardware/biometrics/common/CommonProps.aidl @@ -16,6 +16,7 @@ package android.hardware.biometrics.common; +import android.hardware.biometrics.common.HardwareInfo; import android.hardware.biometrics.common.SensorStrength; @VintfStability @@ -40,4 +41,10 @@ parcelable CommonProps { * Statically configured. */ int maxEnrollmentsPerUser; + + /** + * A list of hardware information for subsystems that pertain to this + * biometric sensor. + */ + HardwareInfo[] hardwareInfo; } \ No newline at end of file diff --git a/biometrics/common/aidl/android/hardware/biometrics/common/HardwareInfo.aidl b/biometrics/common/aidl/android/hardware/biometrics/common/HardwareInfo.aidl new file mode 100644 index 0000000000..23f0202542 --- /dev/null +++ b/biometrics/common/aidl/android/hardware/biometrics/common/HardwareInfo.aidl @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.biometrics.common; + +@VintfStability +parcelable HardwareInfo { + /** + * An identifier uniquely identifying a subsystem. + */ + String deviceName; + + /** + * The hardware version. For example, //. + */ + String hardwareVersion; + + /** + * The firmware version. + */ + String firmwareVersion; + + /** + * The sensor's serial number. + */ + String serialNumber; +} \ No newline at end of file diff --git a/biometrics/fingerprint/aidl/default/Fingerprint.cpp b/biometrics/fingerprint/aidl/default/Fingerprint.cpp index 80266d2e86..0ca45f85f0 100644 --- a/biometrics/fingerprint/aidl/default/Fingerprint.cpp +++ b/biometrics/fingerprint/aidl/default/Fingerprint.cpp @@ -23,12 +23,25 @@ const int kSensorId = 0; const common::SensorStrength kSensorStrength = common::SensorStrength::STRONG; const int kMaxEnrollmentsPerUser = 5; const FingerprintSensorType kSensorType = FingerprintSensorType::REAR; +const std::string kHwDeviceName = "fingerprintSensor"; +const std::string kHardwareVersion = "vendor/model/revision"; +const std::string kFirmwareVersion = "1.01"; +const std::string kSerialNumber = "00000001"; ndk::ScopedAStatus Fingerprint::getSensorProps(std::vector* return_val) { *return_val = std::vector(); + + std::vector hardwareInfos = std::vector(); + common::HardwareInfo sensorInfo = {kHwDeviceName, + kHardwareVersion, + kFirmwareVersion, + kSerialNumber + }; + hardwareInfos.push_back(sensorInfo); common::CommonProps commonProps = {kSensorId, kSensorStrength, - kMaxEnrollmentsPerUser}; + kMaxEnrollmentsPerUser, + hardwareInfos}; SensorProps props = {commonProps, kSensorType, 0 /* sensorLocationX */, -- GitLab From cbd93156bd02a619d6194cfaa735592132a6a4dd Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Wed, 2 Sep 2020 17:49:00 -0700 Subject: [PATCH 156/790] IP and CID filtering configuration of IP filter Add the cid configuration API in IFilter and some related enums Test: atest VtsHalTvTunerV1_1TargetTest Bug: 153595125 Change-Id: I6e43c0f71466192f9fa69c76f9c635ecefe99d5e --- tv/tuner/1.1/IFilter.hal | 11 +++++++++++ tv/tuner/1.1/default/Filter.cpp | 11 +++++++++++ tv/tuner/1.1/default/Filter.h | 3 +++ tv/tuner/1.1/types.hal | 5 +++++ tv/tuner/1.1/vts/functional/FilterTests.cpp | 16 ++++++++++++++++ tv/tuner/1.1/vts/functional/FilterTests.h | 1 + .../functional/VtsHalTvTunerV1_1TargetTest.cpp | 9 +++++++++ .../VtsHalTvTunerV1_1TestConfigurations.h | 17 +++++++++++++++++ 8 files changed, 73 insertions(+) diff --git a/tv/tuner/1.1/IFilter.hal b/tv/tuner/1.1/IFilter.hal index 6c4d8a5a03..b362e32c22 100644 --- a/tv/tuner/1.1/IFilter.hal +++ b/tv/tuner/1.1/IFilter.hal @@ -40,4 +40,15 @@ interface IFilter extends @1.0::IFilter { * @return filterId the hardware resource Id for the filter. */ getId64Bit() generates (Result result, uint64_t filterId); + + /** + * Configure additional Context ID on the IP filter. + * + * @param ipCid Context Id of the IP filter. + * @return result Result status of the operation. + * SUCCESS if successful, + * INVALID_STATE if failed for wrong state. + * UNKNOWN_ERROR if failed for other reasons. + */ + configureIpCid(uint32_t ipCid) generates (Result result); }; diff --git a/tv/tuner/1.1/default/Filter.cpp b/tv/tuner/1.1/default/Filter.cpp index fae83a2fb2..3db8b9e70d 100644 --- a/tv/tuner/1.1/default/Filter.cpp +++ b/tv/tuner/1.1/default/Filter.cpp @@ -179,6 +179,17 @@ Return Filter::close() { return mDemux->removeFilter(mFilterId); } +Return Filter::configureIpCid(uint32_t ipCid) { + ALOGV("%s", __FUNCTION__); + + if (mType.mainType != DemuxFilterMainType::IP) { + return Result::INVALID_STATE; + } + + mCid = ipCid; + return Result::SUCCESS; +} + bool Filter::createFilterMQ() { ALOGV("%s", __FUNCTION__); diff --git a/tv/tuner/1.1/default/Filter.h b/tv/tuner/1.1/default/Filter.h index fa52f9635a..23bc25c0d3 100644 --- a/tv/tuner/1.1/default/Filter.h +++ b/tv/tuner/1.1/default/Filter.h @@ -76,6 +76,8 @@ class Filter : public V1_1::IFilter { virtual Return close() override; + virtual Return configureIpCid(uint32_t ipCid) override; + /** * To create a FilterMQ and its Event Flag. * @@ -111,6 +113,7 @@ class Filter : public V1_1::IFilter { sp mCallback_1_1 = nullptr; uint64_t mFilterId; + uint32_t mCid = static_cast(V1_1::Constant::INVALID_IP_FILTER_CONTEXT_ID); uint32_t mBufferSize; DemuxFilterType mType; bool mIsMediaFilter = false; diff --git a/tv/tuner/1.1/types.hal b/tv/tuner/1.1/types.hal index 9e2f453b70..b008dbc40f 100644 --- a/tv/tuner/1.1/types.hal +++ b/tv/tuner/1.1/types.hal @@ -34,6 +34,11 @@ enum Constant : @1.0::Constant { * An invalid frenquency that can be used as the default value of the frontend setting. */ INVALID_FRONTEND_SETTING_FREQUENCY = 0xFFFFFFFF, + /** + * An invalid context id that can be used as the default value of the unconfigured id. It can + * be used to reset the configured ip context id. + */ + INVALID_IP_FILTER_CONTEXT_ID = 0xFFFFFFFF, }; @export diff --git a/tv/tuner/1.1/vts/functional/FilterTests.cpp b/tv/tuner/1.1/vts/functional/FilterTests.cpp index 24e1fa0957..7e5b5498e0 100644 --- a/tv/tuner/1.1/vts/functional/FilterTests.cpp +++ b/tv/tuner/1.1/vts/functional/FilterTests.cpp @@ -89,6 +89,22 @@ AssertionResult FilterTests::configFilter(DemuxFilterSettings setting, uint64_t return AssertionResult(status == Result::SUCCESS); } +AssertionResult FilterTests::configIpFilterCid(uint32_t ipCid, uint64_t filterId) { + Result status; + EXPECT_TRUE(mFilters[filterId]) << "Open Ip filter first."; + + sp filter_v1_1 = + android::hardware::tv::tuner::V1_1::IFilter::castFrom(mFilters[filterId]); + if (filter_v1_1 != NULL) { + status = filter_v1_1->configureIpCid(ipCid); + } else { + ALOGW("[vts] Can't cast IFilter into v1_1."); + return failure(); + } + + return AssertionResult(status == Result::SUCCESS); +} + AssertionResult FilterTests::getFilterMQDescriptor(uint64_t filterId) { Result status; EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first."; diff --git a/tv/tuner/1.1/vts/functional/FilterTests.h b/tv/tuner/1.1/vts/functional/FilterTests.h index 721e4190c4..a47f631868 100644 --- a/tv/tuner/1.1/vts/functional/FilterTests.h +++ b/tv/tuner/1.1/vts/functional/FilterTests.h @@ -132,6 +132,7 @@ class FilterTests { AssertionResult openFilterInDemux(DemuxFilterType type, uint32_t bufferSize); AssertionResult getNewlyOpenedFilterId_64bit(uint64_t& filterId); AssertionResult configFilter(DemuxFilterSettings setting, uint64_t filterId); + AssertionResult configIpFilterCid(uint32_t ipCid, uint64_t filterId); AssertionResult getFilterMQDescriptor(uint64_t filterId); AssertionResult startFilter(uint64_t filterId); AssertionResult stopFilter(uint64_t filterId); diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp index a5aab96638..e06de5394c 100644 --- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp @@ -35,6 +35,9 @@ void TunerFilterHidlTest::configSingleFilterInDemuxTest(FilterConfig filterConf, ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize)); ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(filterId)); ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId)); + if (filterConf.type.mainType == DemuxFilterMainType::IP) { + ASSERT_TRUE(mFilterTests.configIpFilterCid(filterConf.ipCid, filterId)); + } ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId)); ASSERT_TRUE(mFilterTests.startFilter(filterId)); ASSERT_TRUE(mFilterTests.stopFilter(filterId)); @@ -92,6 +95,12 @@ TEST_P(TunerFilterHidlTest, StartFilterInDemux) { configSingleFilterInDemuxTest(filterArray[TS_VIDEO0], frontendArray[DVBT]); } +TEST_P(TunerFilterHidlTest, ConfigIpFilterInDemuxWithCid) { + description("Open and configure an ip filter in Demux."); + // TODO use parameterized tests + configSingleFilterInDemuxTest(filterArray[IP_IP0], frontendArray[DVBT]); +} + TEST_P(TunerRecordHidlTest, RecordDataFlowWithTsRecordFilterTest) { description("Feed ts data from frontend to recording and test with ts record filter"); recordSingleFilterTest(filterArray[TS_RECORD0], frontendArray[DVBT], dvrArray[DVR_RECORD0]); diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h index 34418d146b..36b4bd2cb0 100644 --- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h @@ -26,6 +26,8 @@ using android::hardware::tv::tuner::V1_0::DemuxAlpFilterType; using android::hardware::tv::tuner::V1_0::DemuxFilterMainType; using android::hardware::tv::tuner::V1_0::DemuxFilterSettings; using android::hardware::tv::tuner::V1_0::DemuxFilterType; +using android::hardware::tv::tuner::V1_0::DemuxIpAddress; +using android::hardware::tv::tuner::V1_0::DemuxIpFilterSettings; using android::hardware::tv::tuner::V1_0::DemuxIpFilterType; using android::hardware::tv::tuner::V1_0::DemuxMmtpFilterType; using android::hardware::tv::tuner::V1_0::DemuxRecordScIndexType; @@ -64,6 +66,7 @@ typedef enum { TS_SECTION0, TS_TS0, TS_RECORD0, + IP_IP0, FILTER_MAX, } Filter; @@ -88,6 +91,7 @@ struct FilterConfig { uint32_t bufferSize; DemuxFilterType type; DemuxFilterSettings settings; + uint32_t ipCid; bool operator<(const FilterConfig& /*c*/) const { return false; } }; @@ -227,6 +231,19 @@ inline void initFilterConfig() { filterArray[TS_RECORD0].settings.ts().filterSettings.record({ .scIndexType = DemuxRecordScIndexType::NONE, }); + // IP filter setting + filterArray[IP_IP0].type.mainType = DemuxFilterMainType::IP; + filterArray[IP_IP0].type.subType.ipFilterType(DemuxIpFilterType::IP); + uint8_t src[4] = {192, 168, 1, 1}; + uint8_t dest[4] = {192, 168, 1, 2}; + DemuxIpAddress ipAddress; + ipAddress.srcIpAddress.v4(src); + ipAddress.dstIpAddress.v4(dest); + DemuxIpFilterSettings ipSettings{ + .ipAddr = ipAddress, + }; + filterArray[IP_IP0].settings.ip(ipSettings); + filterArray[IP_IP0].ipCid = 1; }; /** Configuration array for the dvr test */ -- GitLab From e33abd645659910c27c53bf26e65ac200cb50aff Mon Sep 17 00:00:00 2001 From: Kevin Chyn Date: Fri, 18 Sep 2020 10:31:50 -0700 Subject: [PATCH 157/790] Move ICancellationSignal to common, add supportsNavigationGestures Bug: 168842956 Test: Builds Test: make -j56 android.hardware.biometrics.common-update-api Test: make -j56 android.hardware.biometrics.fingerprint-update-api Test: make -j56 VtsHalBiometricsFingerprintTargetTest Change-Id: Ie35ccc2ea8b7ef710914e9a18fc28f49c2d6f0be --- .../biometrics/common}/ICancellationSignal.aidl | 2 +- .../biometrics/common}/ICancellationSignal.aidl | 2 +- .../hardware/biometrics/fingerprint/ISession.aidl | 6 +++--- .../hardware/biometrics/fingerprint/SensorProps.aidl | 1 + .../hardware/biometrics/fingerprint/ISession.aidl | 2 +- .../hardware/biometrics/fingerprint/SensorProps.aidl | 6 ++++++ biometrics/fingerprint/aidl/default/Android.bp | 1 + biometrics/fingerprint/aidl/default/Fingerprint.cpp | 2 ++ biometrics/fingerprint/aidl/default/Session.cpp | 10 +++++----- biometrics/fingerprint/aidl/default/Session.h | 9 +++++---- .../aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp | 2 +- 11 files changed, 27 insertions(+), 16 deletions(-) rename biometrics/{fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint => common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common}/ICancellationSignal.aidl (95%) rename biometrics/{fingerprint/aidl/android/hardware/biometrics/fingerprint => common/aidl/android/hardware/biometrics/common}/ICancellationSignal.aidl (93%) diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ICancellationSignal.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/ICancellationSignal.aidl similarity index 95% rename from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ICancellationSignal.aidl rename to biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/ICancellationSignal.aidl index 6f3d2dbb3a..1a875bfbd8 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ICancellationSignal.aidl +++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/ICancellationSignal.aidl @@ -15,7 +15,7 @@ // 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.biometrics.common; @VintfStability interface ICancellationSignal { oneway void cancel(); diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ICancellationSignal.aidl b/biometrics/common/aidl/android/hardware/biometrics/common/ICancellationSignal.aidl similarity index 93% rename from biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ICancellationSignal.aidl rename to biometrics/common/aidl/android/hardware/biometrics/common/ICancellationSignal.aidl index abfbb2ab89..10102561b5 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ICancellationSignal.aidl +++ b/biometrics/common/aidl/android/hardware/biometrics/common/ICancellationSignal.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.biometrics.fingerprint; +package android.hardware.biometrics.common; @VintfStability oneway interface ICancellationSignal { 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 d92ca4f943..06c8623bf5 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 @@ -18,9 +18,9 @@ package android.hardware.biometrics.fingerprint; @VintfStability interface ISession { - android.hardware.biometrics.fingerprint.ICancellationSignal enroll(in int cookie, in android.hardware.keymaster.HardwareAuthToken hat); - android.hardware.biometrics.fingerprint.ICancellationSignal authenticate(in int cookie, in long keystoreOperationId); - android.hardware.biometrics.fingerprint.ICancellationSignal detectInteraction(in int cookie); + android.hardware.biometrics.common.ICancellationSignal enroll(in int cookie, in android.hardware.keymaster.HardwareAuthToken hat); + android.hardware.biometrics.common.ICancellationSignal authenticate(in int cookie, in long keystoreOperationId); + android.hardware.biometrics.common.ICancellationSignal detectInteraction(in int cookie); void enumerateEnrollments(in int cookie); void removeEnrollments(in int cookie, in int[] enrollmentIds); void getAuthenticatorId(in int cookie); diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl index 9d946a9247..8c779abc09 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl @@ -20,6 +20,7 @@ package android.hardware.biometrics.fingerprint; parcelable SensorProps { android.hardware.biometrics.common.CommonProps commonProps; android.hardware.biometrics.fingerprint.FingerprintSensorType sensorType; + boolean supportsNavigationGestures; int sensorLocationX; int sensorLocationY; int sensorRadius; diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl index 55ea385adb..dd340e8e8c 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl @@ -16,7 +16,7 @@ package android.hardware.biometrics.fingerprint; -import android.hardware.biometrics.fingerprint.ICancellationSignal; +import android.hardware.biometrics.common.ICancellationSignal; import android.hardware.keymaster.HardwareAuthToken; @VintfStability diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl index 7c1e1760af..fc3b44d608 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl @@ -32,6 +32,12 @@ parcelable SensorProps { */ FingerprintSensorType sensorType; + /** + * Must be set to true for sensors that support "swipe" gestures via + * android.view.KeyEvent#KEYCODE_SYSTEM_NAVIGATION_*. + */ + boolean supportsNavigationGestures; + /** * The location of the center of the sensor if applicable. For example, * sensors of FingerprintSensorType::UNDER_DISPLAY_* would report this diff --git a/biometrics/fingerprint/aidl/default/Android.bp b/biometrics/fingerprint/aidl/default/Android.bp index f2536d4ba8..ce1ff5964b 100644 --- a/biometrics/fingerprint/aidl/default/Android.bp +++ b/biometrics/fingerprint/aidl/default/Android.bp @@ -8,6 +8,7 @@ cc_binary { "libbase", "libbinder_ndk", "android.hardware.biometrics.fingerprint-ndk_platform", + "android.hardware.biometrics.common-unstable-ndk_platform", ], srcs: [ "main.cpp", diff --git a/biometrics/fingerprint/aidl/default/Fingerprint.cpp b/biometrics/fingerprint/aidl/default/Fingerprint.cpp index 0ca45f85f0..a1d9d0a006 100644 --- a/biometrics/fingerprint/aidl/default/Fingerprint.cpp +++ b/biometrics/fingerprint/aidl/default/Fingerprint.cpp @@ -23,6 +23,7 @@ const int kSensorId = 0; const common::SensorStrength kSensorStrength = common::SensorStrength::STRONG; const int kMaxEnrollmentsPerUser = 5; const FingerprintSensorType kSensorType = FingerprintSensorType::REAR; +const bool kSupportsNavigationGestures = true; const std::string kHwDeviceName = "fingerprintSensor"; const std::string kHardwareVersion = "vendor/model/revision"; const std::string kFirmwareVersion = "1.01"; @@ -44,6 +45,7 @@ ndk::ScopedAStatus Fingerprint::getSensorProps(std::vector* return_ hardwareInfos}; SensorProps props = {commonProps, kSensorType, + kSupportsNavigationGestures, 0 /* sensorLocationX */, 0 /* sensorLocationY */, 0 /* sensorRadius */, diff --git a/biometrics/fingerprint/aidl/default/Session.cpp b/biometrics/fingerprint/aidl/default/Session.cpp index a3dd75e62d..c2934a8bd7 100644 --- a/biometrics/fingerprint/aidl/default/Session.cpp +++ b/biometrics/fingerprint/aidl/default/Session.cpp @@ -14,13 +14,13 @@ * limitations under the License. */ -#include +#include #include "Session.h" namespace aidl::android::hardware::biometrics::fingerprint { -class CancellationSignal : public BnCancellationSignal { +class CancellationSignal : public common::BnCancellationSignal { public: ndk::ScopedAStatus cancel() override { return ndk::ScopedAStatus::ok(); } }; @@ -28,12 +28,12 @@ class CancellationSignal : public BnCancellationSignal { Session::Session(std::shared_ptr cb) : cb_(std::move(cb)) {} ndk::ScopedAStatus Session::enroll(int32_t /*cookie*/, const keymaster::HardwareAuthToken& /*hat*/, - std::shared_ptr* /*return_val*/) { + std::shared_ptr* /*return_val*/) { return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus Session::authenticate(int32_t /*cookie*/, int64_t /*keystoreOperationId*/, - std::shared_ptr* return_val) { + std::shared_ptr* return_val) { if (cb_) { cb_->onStateChanged(0, SessionState::AUTHENTICATING); } @@ -42,7 +42,7 @@ ndk::ScopedAStatus Session::authenticate(int32_t /*cookie*/, int64_t /*keystoreO } ndk::ScopedAStatus Session::detectInteraction( - int32_t /*cookie*/, std::shared_ptr* /*return_val*/) { + int32_t /*cookie*/, std::shared_ptr* /*return_val*/) { return ndk::ScopedAStatus::ok(); } diff --git a/biometrics/fingerprint/aidl/default/Session.h b/biometrics/fingerprint/aidl/default/Session.h index 781e95a222..f7cba1b801 100644 --- a/biometrics/fingerprint/aidl/default/Session.h +++ b/biometrics/fingerprint/aidl/default/Session.h @@ -21,20 +21,21 @@ namespace aidl::android::hardware::biometrics::fingerprint { -namespace aidl::android::hardware::keymaster = keymaster; +namespace common = aidl::android::hardware::biometrics::common; +namespace keymaster = aidl::android::hardware::keymaster; class Session : public BnSession { public: explicit Session(std::shared_ptr cb); ndk::ScopedAStatus enroll(int32_t cookie, const keymaster::HardwareAuthToken& hat, - std::shared_ptr* return_val) override; + std::shared_ptr* return_val) override; ndk::ScopedAStatus authenticate(int32_t cookie, int64_t keystoreOperationId, - std::shared_ptr* return_val) override; + std::shared_ptr* return_val) override; ndk::ScopedAStatus detectInteraction(int32_t cookie, - std::shared_ptr* return_val) override; + std::shared_ptr* return_val) override; ndk::ScopedAStatus enumerateEnrollments(int32_t cookie) override; diff --git a/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp b/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp index 1a39ad4c12..9590d68000 100644 --- a/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp +++ b/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp @@ -114,7 +114,7 @@ TEST_P(Fingerprint, AuthenticateTest) { std::shared_ptr session; ASSERT_TRUE(hal_->createSession(kSensorId, kUserId, session_cb, &session).isOk()); - std::shared_ptr cancel_cb; + std::shared_ptr cancel_cb; ASSERT_TRUE(session->authenticate(0, 0, &cancel_cb).isOk()); ASSERT_EQ(invocation_future.wait_for(kCallbackTimeout), std::future_status::ready); -- GitLab From 26abceefbe8f2d8bb11b684e9c3bdc5dc68ab581 Mon Sep 17 00:00:00 2001 From: Eric Jeong Date: Fri, 18 Sep 2020 12:14:54 -0700 Subject: [PATCH 158/790] Return immediately when prop is not found - when VHAL prop is not supported, getPropConfigs calls hidl callback with INVALID_ARG and has to return. - otherwise, there will be two callbacks invoked from VHAL. Bug: 168834308 Test: seahawk should boot up Change-Id: I41f5ddf26b9ba70221d59bae10d7ca9a2133a9eb --- automotive/vehicle/2.0/default/common/src/VehicleHalManager.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/automotive/vehicle/2.0/default/common/src/VehicleHalManager.cpp b/automotive/vehicle/2.0/default/common/src/VehicleHalManager.cpp index b09e9bfba0..dc5d3d300e 100644 --- a/automotive/vehicle/2.0/default/common/src/VehicleHalManager.cpp +++ b/automotive/vehicle/2.0/default/common/src/VehicleHalManager.cpp @@ -78,6 +78,7 @@ Return VehicleHalManager::getPropConfigs(const hidl_vec &properti } else { ALOGW("Requested config for undefined property: 0x%x", prop); _hidl_cb(StatusCode::INVALID_ARG, hidl_vec()); + return Void(); } } -- GitLab From a4573de71e9dfccfd702e1718f29ddb3bc6618d1 Mon Sep 17 00:00:00 2001 From: kanant Date: Thu, 23 Jul 2020 15:54:39 -0700 Subject: [PATCH 159/790] Introducing OEM partner custom input type (HW_CUSTOM_INPUT) HW_CUSTOM_INPUT is an input event to be defined by OEM partners. Bug: 159623196 Test: atest CarServiceUnitTest Change-Id: I6df5b292730079260af7c48c0d6e5748c5b3470a --- .../default/impl/vhal_v2_0/DefaultConfig.h | 12 +++++ automotive/vehicle/2.0/types.hal | 50 +++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h index 72df25629f..e3b559ec8d 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h @@ -499,6 +499,18 @@ const ConfigDeclaration kVehicleProperties[]{ }, .initialValue = {.int32Values = {0, 0, 0}}}, + {.config = + { + .prop = toInt(VehicleProperty::HW_CUSTOM_INPUT), + .access = VehiclePropertyAccess::READ, + .changeMode = VehiclePropertyChangeMode::ON_CHANGE, + .configArray = {0, 0, 0, 3, 0, 0, 0, 0, 0}, + }, + .initialValue = + { + .int32Values = {0, 0, 0}, + }}, + {.config = {.prop = toInt(VehicleProperty::HVAC_POWER_ON), .access = VehiclePropertyAccess::READ_WRITE, .changeMode = VehiclePropertyChangeMode::ON_CHANGE, diff --git a/automotive/vehicle/2.0/types.hal b/automotive/vehicle/2.0/types.hal index b7c72e4f44..40f1b3e004 100644 --- a/automotive/vehicle/2.0/types.hal +++ b/automotive/vehicle/2.0/types.hal @@ -1480,6 +1480,33 @@ enum VehicleProperty : int32_t { | VehiclePropertyType:INT32_VEC | VehicleArea:GLOBAL), + /** + * Defines a custom OEM partner input event. + * + * This input event must be used by OEM partners who wish to propagate events not supported + * by Android. It is composed by an array of int32 values only. + * + * The Android properties are: + * + * int32Values[0] : Input code identifying the function representing this event. Valid event + * types are defined by CustomInputType.CUSTOM_EVENT_F1 up to + * CustomInputType.CUSTOM_EVENT_F10. They represent the custom event to be + * defined by OEM partners. + * int32Values[1] : target display type defined in VehicleDisplay. Events not tied to specific + * display must be sent to VehicleDisplay#MAIN. + * int32Values[2] : repeat counter, if 0 then event is not repeated. Values 1 or above means + * how many times this event repeated. + * + * @change_mode VehiclePropertyChangeMode:ON_CHANGE + * @data_enum CustomInputType + * @access VehiclePropertyAccess:READ + */ + HW_CUSTOM_INPUT = ( + 0X0A30 + | VehiclePropertyGroup:SYSTEM + | VehiclePropertyType:INT32_VEC + | VehicleArea:GLOBAL), + /*************************************************************************** * Most Car Cabin properties have both a POSition and MOVE parameter. These * are used to control the various movements for seats, doors, and windows @@ -4856,3 +4883,26 @@ enum ProcessTerminationReason : int32_t { */ MEMORY_OVERUSE = 3, }; + +/** + * Input code values for HW_CUSTOM_INPUT. + */ +enum CustomInputType : int32_t { + /** + * Ten functions representing the custom input code to be defined and implemented by OEM + * partners. + * + * OEMs need to formally contact Android team if more than 10 functions are required. + */ + CUSTOM_EVENT_F1 = 1001, + CUSTOM_EVENT_F2 = 1002, + CUSTOM_EVENT_F3 = 1003, + CUSTOM_EVENT_F4 = 1004, + CUSTOM_EVENT_F5 = 1005, + CUSTOM_EVENT_F6 = 1006, + CUSTOM_EVENT_F7 = 1007, + CUSTOM_EVENT_F8 = 1008, + CUSTOM_EVENT_F9 = 1009, + CUSTOM_EVENT_F10 = 1010, +}; + -- GitLab From 571caa6a45fe43c384a7ba424ba182ff3db4fe06 Mon Sep 17 00:00:00 2001 From: Kevin Chyn Date: Thu, 17 Sep 2020 13:08:03 -0700 Subject: [PATCH 160/790] Start adding documentation for IFingerprint Minor changes to interface: 1) IResetLockoutCallback renamed to ILockoutCallback 2) Removes unnecessary parameter from onChallengeGenerated 3) Adds "challenge" param to revokeChallenge to support multiple in-flight challenges Bug: 168842956 Bug: 168843220 Test: make -j56 android.hardware.biometrics.fingerprint-update-api Test: make -j Test: make -j56 VtsHalBiometricsFingerprintTargetTest Change-Id: If1f63a6d0c135d7b59690a31728b4d3fc8c2d2c4 --- .../biometrics/fingerprint/IFingerprint.aidl | 4 +- .../IGenerateChallengeCallback.aidl | 2 +- ...outCallback.aidl => ILockoutCallback.aidl} | 6 +- .../biometrics/fingerprint/IFingerprint.aidl | 137 +++++++++++++++++- .../IGenerateChallengeCallback.aidl | 5 +- .../fingerprint/ILockoutCallback.aidl | 60 ++++++++ .../fingerprint/IResetLockoutCallback.aidl | 23 --- .../fingerprint/IRevokeChallengeCallback.aidl | 3 + .../biometrics/fingerprint/ISession.aidl | 30 +++- .../fingerprint/aidl/default/Fingerprint.cpp | 6 +- .../fingerprint/aidl/default/Fingerprint.h | 6 +- 11 files changed, 240 insertions(+), 42 deletions(-) rename biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/{IResetLockoutCallback.aidl => ILockoutCallback.aidl} (81%) create mode 100644 biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ILockoutCallback.aidl delete mode 100644 biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IResetLockoutCallback.aidl diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl index 85d1f57e05..9cbf343181 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl @@ -20,7 +20,7 @@ package android.hardware.biometrics.fingerprint; 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); - void setResetLockoutCallback(in android.hardware.biometrics.fingerprint.IResetLockoutCallback cb); + void setLockoutCallback(in android.hardware.biometrics.fingerprint.ILockoutCallback cb); void generateChallenge(in int sensorId, in int userId, in int timeoutSec, in android.hardware.biometrics.fingerprint.IGenerateChallengeCallback cb); - void revokeChallenge(in int sensorId, in int userId, in android.hardware.biometrics.fingerprint.IRevokeChallengeCallback cb); + void revokeChallenge(in int sensorId, in int userId, in long challenge, in android.hardware.biometrics.fingerprint.IRevokeChallengeCallback cb); } diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IGenerateChallengeCallback.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IGenerateChallengeCallback.aidl index eaf27d2235..063be60a0f 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IGenerateChallengeCallback.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IGenerateChallengeCallback.aidl @@ -18,5 +18,5 @@ package android.hardware.biometrics.fingerprint; @VintfStability interface IGenerateChallengeCallback { - oneway void onChallengeGenerated(in int sensorId, in int userId, in long keystoreOperationId, in long challenge); + oneway void onChallengeGenerated(in int sensorId, in int userId, in long challenge); } diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IResetLockoutCallback.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ILockoutCallback.aidl similarity index 81% rename from biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IResetLockoutCallback.aidl rename to biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ILockoutCallback.aidl index ac0decda6b..88aabbf487 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IResetLockoutCallback.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ILockoutCallback.aidl @@ -17,6 +17,8 @@ package android.hardware.biometrics.fingerprint; @VintfStability -interface IResetLockoutCallback { - oneway void onLockoutReset(in int sensorId, in int userId, in long durationMilli); +interface ILockoutCallback { + oneway void onLockoutTimed(in int sensorId, in int userId, in long durationMillis); + oneway void onLockoutPermanent(in int sensorId, in int userId); + oneway void onLockoutCleared(in int sensorId, in int userId); } diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl index 47097785b5..57319b2906 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl @@ -17,7 +17,7 @@ package android.hardware.biometrics.fingerprint; import android.hardware.biometrics.fingerprint.IGenerateChallengeCallback; -import android.hardware.biometrics.fingerprint.IResetLockoutCallback; +import android.hardware.biometrics.fingerprint.ILockoutCallback; import android.hardware.biometrics.fingerprint.IRevokeChallengeCallback; import android.hardware.biometrics.fingerprint.ISession; import android.hardware.biometrics.fingerprint.ISessionCallback; @@ -25,13 +25,144 @@ import android.hardware.biometrics.fingerprint.SensorProps; @VintfStability interface IFingerprint { + /** + * getSensorProps: + * + * @return A list of properties for all sensors that an instance of the + * HAL supports. + */ SensorProps[] getSensorProps(); + /** + * createSession: + * + * Creates a session which can then be used by the framework to perform + * operations such as enroll, authenticate, etc for the given sensorId + * and userId. + * + * A physical sensor identified by sensorId typically supports only a + * single in-flight session at a time. As such, if a session is currently + * in a state other than SessionState::IDLING, the HAL MUST finish or + * cancel the current operation and return to SessionState::IDLING before + * the new session is created. For example: + * 1) If a session for sensorId=0, userId=0 + * is currently in a cancellable state (see ICancellationSignal) such + * as SessionState::AUTHENTICATING and the framework requests a new + * session for sensorId=0, userId=10, the HAL must end the current + * session with Error::CANCELED, invoke + * ISessionCallback#onStateChanged with SessionState::IDLING, and + * then return a new session for sensorId=0, userId=10. + * 2) If a session for sensorId=0, userId=0 is currently in a + * non-cancellable state such as SessionState::REMOVING_ENROLLMENTS, + * and the framework requests a new session for sensorId=0, userId=10, + * the HAL must finish the current operation before invoking + * ISessionCallback#onStateChanged with SessionState::IDLING, and + * return a new session for sensorId=0, userId=10. + * + * Implementations must store user-specific state or metadata in + * /data/vendor_de//fpdata as specified by the SeLinux policy. This + * directory is created/removed by vold (see vold_prepare_subdirs.cpp). + * Implementations may store additional user-specific data, such as + * embeddings or templates in StrongBox. + * + * @param sensorId The sensor with which this session is being created. + * @param userId The userId with which this session is being created. + * @param cb Used to notify the framework. + * @return A new session + */ ISession createSession(in int sensorId, in int userId, in ISessionCallback cb); - void setResetLockoutCallback(in IResetLockoutCallback cb); + /** + * setLockoutCallback: + * + * Sets a callback to notify the framework lockout changes. Note + * that lockout is user AND sensor specific. In other words, there is a + * separate lockout state for each (user, sensor) pair. For example, the + * following is a valid state on a multi-sensor device: + * ------------------------------------------------------------------ + * | SensorId | UserId | FailedAttempts | LockedOut | LockedUntil | + * |----------|--------|----------------|-----------|---------------| + * | 0 | 0 | 1 | false | x | + * | 1 | 0 | 5 | true | | + * | 0 | 10 | 0 | false | x | + * | 1 | 10 | 0 | false | x | + * ------------------------------------------------------------------ + * + * Lockout may be cleared in the following ways: + * 1) ISession#resetLockout + * 2) After a period of time, according to a rate-limiter. + * + * In addition, lockout states MUST persist after device reboots, HAL + * crashes, etc. + * + * See the Android CDD section 7.3.10 for the full set of lockout and + * rate-limiting requirements. + * + * @param cb Used to notify the framework of lockout changes. + */ + void setLockoutCallback(in ILockoutCallback cb); + /** + * generateChallenge: + * + * Begins a secure transaction request. Note that the challenge by itself + * is not useful. It only becomes useful when wrapped in a verifiable + * message such as a HardwareAuthToken. + * + * Canonical example: + * 1) User requests an operation, such as fingerprint enrollment. + * 2) Fingerprint enrollment cannot happen until the user confirms + * their lockscreen credential (PIN/Pattern/Password). + * 3) However, the biometric subsystem does not want just "any" + * proof of credential confirmation. It needs proof that the + * user explicitly authenticated credential in order to allow + * addition of biometric enrollments. + * To secure this path, the following path is taken: + * 1) Upon user requesting fingerprint enroll, the framework requests + * IFingerprint#generateChallenge + * 2) Framework sends the challenge to the credential subsystem, and upon + * credential confirmation, a HAT is created, containing the challenge + * in the "challenge" field. + * 3) Framework sends the HAT to the HAL, e.g. ISession#enroll. + * 4) Implementation verifies the authenticity and integrity of the HAT. + * 5) Implementation now has confidence that the user entered their + * credential to allow biometric enrollment. + * + * Note that the interface allows multiple in-flight challenges. For + * example, invoking generateChallenge(0, 0, timeoutSec, cb) twice + * does not invalidate the first challenge. The challenge is invalidated + * only when: + * 1) The provided timeout expires, or + * 2) IFingerprint#revokeChallenge is invoked + * + * For example, the following is a possible table of valid challenges: + * ---------------------------------------------- + * | SensorId | UserId | ValidUntil | Challenge | + * |----------|--------|------------|-----------| + * | 0 | 0 | | | + * | 0 | 0 | | | + * | 1 | 0 | | | + * | 0 | 10 | | | + * ---------------------------------------------- + * + * @param sensorId Sensor to associate the challenge with + * @param userId User to associate the challenge with + * @param timeoutSec Duration for which the challenge is valid for + * @param cb Callback to notify the framework + */ void generateChallenge(in int sensorId, in int userId, in int timeoutSec, in IGenerateChallengeCallback cb); - void revokeChallenge(in int sensorId, in int userId, in IRevokeChallengeCallback cb); + /** + * revokeChallenge: + * + * Revokes a challenge that was previously generated. Note that if an + * invalid combination of parameters is requested, the implementation + * must still notify the framework using the provided callback. + * + * @param sensorId Sensor that the revocation should apply to. + * @param userId User that the revocation should apply to. + * @param challenge Challenge that should be revoked. + * @param cb Used to notify the framework. + */ + void revokeChallenge(in int sensorId, in int userId, in long challenge, in IRevokeChallengeCallback cb); } diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IGenerateChallengeCallback.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IGenerateChallengeCallback.aidl index 93a2d7bdc4..a51b188fcf 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IGenerateChallengeCallback.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IGenerateChallengeCallback.aidl @@ -18,6 +18,9 @@ package android.hardware.biometrics.fingerprint; @VintfStability oneway interface IGenerateChallengeCallback { - void onChallengeGenerated(in int sensorId, in int userId, in long keystoreOperationId, in long challenge); + /** + * Notifies the framework when a challenge is successfully generated. + */ + void onChallengeGenerated(in int sensorId, in int userId, in long challenge); } diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ILockoutCallback.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ILockoutCallback.aidl new file mode 100644 index 0000000000..4b31a38e52 --- /dev/null +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ILockoutCallback.aidl @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.biometrics.fingerprint; + +@VintfStability +oneway interface ILockoutCallback { + /** + * Notifies the framework that the user has just entered the Error::LOCKOUT state. This must be + * sent in the following scenarios: + * 1) The user just attempted authentication and was rejected, resulting in a timed lockout. + * 2) The framework just created a session for a sensorId/userId pair that has not been + * created since the HAL started (e.g. there is no active or idle session for this + * sensorId/userId pair. + * + * @param sensorId Sensor for which the user is locked out. + * @param userId User for which the sensor is locked out. + * @param durationMillis Remaining duration of the lockout. + */ + void onLockoutTimed(in int sensorId, in int userId, in long durationMillis); + + /** + * Notifies the framework that the user has just entered the Error::LOCKOUT_PERMANENT state. + * This must be sent in the following scenarios: + * 1) The user just attempted authentication and was rejected, resulting in a permanent lockout. + * 2) The framework just created a session for a sensorId/userId pair that has not been + * created since the HAL started (e.g. there is no active or idle session for this + * sensorId/userId pair. + * + * @param sensorId Sensor for which the user is locked out. + * @param userId User for which the sensor is locked out. + */ + void onLockoutPermanent(in int sensorId, in int userId); + + /** + * Notifies the framework that lockout has been cleared for this sensorId/userId pair. This + * can happen in the following scenarios: + * 1) A timed lockout has ended (e.g. original durationMillis specified in #onLockoutTimed + * has expired. + * 2) See ISession#resetLockout. + * + * @param sensorId Sensor for which the user's lockout is cleared. + * @param userId User for the sensor's lockout is cleared. + */ + void onLockoutCleared(in int sensorId, in int userId); +} + diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IResetLockoutCallback.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IResetLockoutCallback.aidl deleted file mode 100644 index d97a701c73..0000000000 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IResetLockoutCallback.aidl +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.hardware.biometrics.fingerprint; - -@VintfStability -oneway interface IResetLockoutCallback { - void onLockoutReset(in int sensorId, in int userId, in long durationMilli); -} - diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IRevokeChallengeCallback.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IRevokeChallengeCallback.aidl index cca3453e39..eadba526b3 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IRevokeChallengeCallback.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IRevokeChallengeCallback.aidl @@ -18,6 +18,9 @@ package android.hardware.biometrics.fingerprint; @VintfStability oneway interface IRevokeChallengeCallback { + /** + * Notifies the framework when a challenge has been revoked. + */ void onChallengeRevoked(in int sensorId, in int userId, in long challenge); } diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl index dd340e8e8c..e2d23a6160 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl @@ -82,12 +82,14 @@ interface ISession { * The following only applies to sensors that are configured as * SensorStrength::STRONG. * - * When invoked by the framework, the HAL implementation must perform the + * When invoked by the framework, the implementation must perform the * following sequence of events: * 1) Verify the authenticity and integrity of the provided HAT - * 2) Update the authenticatorId with a new entropy-encoded random number - * 3) Persist the new authenticatorId to non-ephemeral storage - * 4) Notify the framework that the above is completed, via + * 2) Verify that the timestamp provided within the HAT is relatively + * recent (e.g. on the order of minutes, not hours). + * 3) Update the authenticatorId with a new entropy-encoded random number + * 4) Persist the new authenticatorId to non-ephemeral storage + * 5) Notify the framework that the above is completed, via * ISessionCallback#onAuthenticatorInvalidated * * A practical use case of invalidation would be when the user adds a new @@ -105,6 +107,26 @@ interface ISession { */ void invalidateAuthenticatorId(in int cookie, in HardwareAuthToken hat); + /** + * resetLockout: + * + * Requests the implementation to clear the lockout counter. Upon receiving + * this request, the implementation must perform the following: + * 1) Verify the authenticity and integrity of the provided HAT + * 2) Verify that the timestamp provided within the HAT is relatively + * recent (e.g. on the order of minutes, not hours). + * + * Upon successful verification, the HAL must notify the framework via + * ILockoutCallback#onLockoutChanged(sensorId, userId, 0). + * + * If verification was uncessful, the HAL must notify the framework via + * ILockoutCallback#onLockoutChanged(sensorId, userId, remaining_time). + * + * @param cookie An identifier used to track subsystem operations related + * to this call path. The framework will guarantee that it is + * unique per ISession. + * @param hat HardwareAuthToken See above documentation. + */ void resetLockout(in int cookie, in HardwareAuthToken hat); diff --git a/biometrics/fingerprint/aidl/default/Fingerprint.cpp b/biometrics/fingerprint/aidl/default/Fingerprint.cpp index a1d9d0a006..b3bd4e7a29 100644 --- a/biometrics/fingerprint/aidl/default/Fingerprint.cpp +++ b/biometrics/fingerprint/aidl/default/Fingerprint.cpp @@ -61,8 +61,8 @@ ndk::ScopedAStatus Fingerprint::createSession(int32_t /*sensorId*/, int32_t /*us return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Fingerprint::setResetLockoutCallback( - const std::shared_ptr& /*cb*/) { +ndk::ScopedAStatus Fingerprint::setLockoutCallback( + const std::shared_ptr& /*cb*/) { return ndk::ScopedAStatus::ok(); } @@ -73,7 +73,7 @@ ndk::ScopedAStatus Fingerprint::generateChallenge( } ndk::ScopedAStatus Fingerprint::revokeChallenge( - int32_t /*sensorId*/, int32_t /*userId*/, + int32_t /*sensorId*/, int32_t /*userId*/, int64_t /*challenge*/, const std::shared_ptr& /*cb*/) { return ndk::ScopedAStatus::ok(); } diff --git a/biometrics/fingerprint/aidl/default/Fingerprint.h b/biometrics/fingerprint/aidl/default/Fingerprint.h index b5b09c0b74..463d07db13 100644 --- a/biometrics/fingerprint/aidl/default/Fingerprint.h +++ b/biometrics/fingerprint/aidl/default/Fingerprint.h @@ -28,15 +28,15 @@ class Fingerprint : public BnFingerprint { const std::shared_ptr& cb, std::shared_ptr* _aidl_return) override; - ndk::ScopedAStatus setResetLockoutCallback( - const std::shared_ptr& cb) override; + ndk::ScopedAStatus setLockoutCallback( + const std::shared_ptr& cb) override; ndk::ScopedAStatus generateChallenge( int32_t sensorId, int32_t userId, int32_t timeoutSec, const std::shared_ptr& cb) override; ndk::ScopedAStatus revokeChallenge( - int32_t sensorId, int32_t userId, + int32_t sensorId, int32_t userId, int64_t challenge, const std::shared_ptr& cb) override; }; -- GitLab From 976c640464b1d6ed82f68522ab4f7b692ca69dbb Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Tue, 8 Sep 2020 17:08:29 -0700 Subject: [PATCH 161/790] Add API to get the shared memory Audio/Video handle In the MediaEvent of AV filters, the AV memory handle is mapped/unmapped on each event. If the vendor allocates a persistent memory block, and use MediaEvent.offset to access the data, the mapping change is unnecessary. To improve this, a new API to get shared AV Memory is introduced. To pass additional information to Codec2 for AV memory, the index for Codec2 to setup additional information can be carried in the handle. Test: atest VtsHalTvTunerV1_1TargetTest Bug: 162013047 Bug: 157143515 Bug: 156664393 Change-Id: Ibd4471ff8e19b0a99b8bcbc982dc08dbcc92efcf --- tv/tuner/1.1/IFilter.hal | 19 ++ tv/tuner/1.1/default/Filter.cpp | 217 ++++++++++++++---- tv/tuner/1.1/default/Filter.h | 13 ++ tv/tuner/1.1/vts/functional/FilterTests.cpp | 85 ++++++- tv/tuner/1.1/vts/functional/FilterTests.h | 30 ++- .../VtsHalTvTunerV1_1TargetTest.cpp | 46 ++++ .../functional/VtsHalTvTunerV1_1TargetTest.h | 44 ++++ 7 files changed, 394 insertions(+), 60 deletions(-) diff --git a/tv/tuner/1.1/IFilter.hal b/tv/tuner/1.1/IFilter.hal index b362e32c22..2ba9bb761d 100644 --- a/tv/tuner/1.1/IFilter.hal +++ b/tv/tuner/1.1/IFilter.hal @@ -51,4 +51,23 @@ interface IFilter extends @1.0::IFilter { * UNKNOWN_ERROR if failed for other reasons. */ configureIpCid(uint32_t ipCid) generates (Result result); + + /** + * Get the shared AV memory handle. Use IFilter.releaseAvHandle to release the handle. + * + * When media filters are opened, call this API to initialize the share memory handle if it's + * needed. + * + * If DemuxFilterMediaEvent.avMemory contains file descriptor, share memory should be ignored. + * + * @return avMemory A handle associated to the shared memory for audio or video. + * avMemory.data[0] is normally an fd for ION memory. When the avMemory->numFd is 0, the + * share memory is not initialized and does not contain valid fd. + * avMemory.data[avMemory.numFds] is an index used as a parameter of + * C2DataIdInfo to build C2 buffer in Codec. No C2 buffer would be created if the index + * does not exist. + * @return avMemSize the size of the shared av memory. It should be ignored when the share + * memory is not initialized. + */ + getAvSharedHandle() generates (Result result, handle avMemory, uint64_t avMemSize); }; diff --git a/tv/tuner/1.1/default/Filter.cpp b/tv/tuner/1.1/default/Filter.cpp index 3db8b9e70d..c69beca12b 100644 --- a/tv/tuner/1.1/default/Filter.cpp +++ b/tv/tuner/1.1/default/Filter.cpp @@ -163,8 +163,17 @@ Return Filter::flush() { return Result::SUCCESS; } -Return Filter::releaseAvHandle(const hidl_handle& /*avMemory*/, uint64_t avDataId) { +Return Filter::releaseAvHandle(const hidl_handle& avMemory, uint64_t avDataId) { ALOGV("%s", __FUNCTION__); + + if ((avMemory.getNativeHandle()->numFds > 0) && + (mSharedAvMemHandle.getNativeHandle()->numFds > 0) && + (sameFile(avMemory.getNativeHandle()->data[0], + mSharedAvMemHandle.getNativeHandle()->data[0]))) { + freeSharedAvHandle(); + return Result::SUCCESS; + } + if (mDataId2Avfd.find(avDataId) == mDataId2Avfd.end()) { return Result::INVALID_ARGUMENT; } @@ -190,6 +199,35 @@ Return Filter::configureIpCid(uint32_t ipCid) { return Result::SUCCESS; } +Return Filter::getAvSharedHandle(getAvSharedHandle_cb _hidl_cb) { + ALOGV("%s", __FUNCTION__); + + if (!mIsMediaFilter) { + _hidl_cb(Result::INVALID_STATE, NULL, BUFFER_SIZE_16M); + return Void(); + } + + if (mSharedAvMemHandle.getNativeHandle() != nullptr) { + _hidl_cb(Result::SUCCESS, mSharedAvMemHandle, BUFFER_SIZE_16M); + return Void(); + } + + int av_fd = createAvIonFd(BUFFER_SIZE_16M); + if (av_fd == -1) { + _hidl_cb(Result::UNKNOWN_ERROR, NULL, 0); + } + + native_handle_t* nativeHandle = createNativeHandle(av_fd); + if (nativeHandle == NULL) { + _hidl_cb(Result::UNKNOWN_ERROR, NULL, 0); + } + mSharedAvMemHandle.setTo(nativeHandle, /*shouldOwn=*/true); + ::close(av_fd); + + _hidl_cb(Result::SUCCESS, mSharedAvMemHandle, BUFFER_SIZE_16M); + return Void(); +} + bool Filter::createFilterMQ() { ALOGV("%s", __FUNCTION__); @@ -313,8 +351,17 @@ void Filter::freeAvHandle() { } for (int i = 0; i < mFilterEvent.events.size(); i++) { ::close(mFilterEvent.events[i].media().avMemory.getNativeHandle()->data[0]); - native_handle_close(mFilterEvent.events[i].media().avMemory.getNativeHandle()); + native_handle_delete(const_cast( + mFilterEvent.events[i].media().avMemory.getNativeHandle())); + } +} + +void Filter::freeSharedAvHandle() { + if (!mIsMediaFilter) { + return; } + ::close(mSharedAvMemHandle.getNativeHandle()->data[0]); + native_handle_delete(const_cast(mSharedAvMemHandle.getNativeHandle())); } void Filter::maySendFilterStatusCallback() { @@ -509,8 +556,8 @@ Result Filter::startMediaFilterHandler() { return Result::SUCCESS; } + Result result; if (mPts) { - Result result; result = createMediaFilterEventWithIon(mFilterOutput); if (result == Result::SUCCESS) { mFilterOutput.clear(); @@ -551,7 +598,10 @@ Result Filter::startMediaFilterHandler() { continue; } - createMediaFilterEventWithIon(mPesOutput); + result = createMediaFilterEventWithIon(mPesOutput); + if (result != Result::SUCCESS) { + return result; + } } mFilterOutput.clear(); @@ -560,51 +610,14 @@ Result Filter::startMediaFilterHandler() { } Result Filter::createMediaFilterEventWithIon(vector output) { - int av_fd = createAvIonFd(output.size()); - if (av_fd == -1) { - return Result::UNKNOWN_ERROR; - } - // copy the filtered data to the buffer - uint8_t* avBuffer = getIonBuffer(av_fd, output.size()); - if (avBuffer == NULL) { - return Result::UNKNOWN_ERROR; - } - memcpy(avBuffer, output.data(), output.size() * sizeof(uint8_t)); - - native_handle_t* nativeHandle = createNativeHandle(av_fd); - if (nativeHandle == NULL) { - return Result::UNKNOWN_ERROR; - } - hidl_handle handle; - handle.setTo(nativeHandle, /*shouldOwn=*/true); - - // Create a dataId and add a pair into the dataId2Avfd map - uint64_t dataId = mLastUsedDataId++ /*createdUID*/; - mDataId2Avfd[dataId] = dup(av_fd); - - // Create mediaEvent and send callback - DemuxFilterMediaEvent mediaEvent; - mediaEvent = { - .avMemory = std::move(handle), - .dataLength = static_cast(output.size()), - .avDataId = dataId, - }; - if (mPts) { - mediaEvent.pts = mPts; - mPts = 0; + if (mUsingSharedAvMem) { + if (mSharedAvMemHandle.getNativeHandle() == nullptr) { + return Result::UNKNOWN_ERROR; + } + return createShareMemMediaEvents(output); } - int size = mFilterEvent.events.size(); - mFilterEvent.events.resize(size + 1); - mFilterEvent.events[size].media(mediaEvent); - // Clear and log - output.clear(); - mAvBufferCopyCount = 0; - ::close(av_fd); - if (DEBUG_FILTER) { - ALOGD("[Filter] av data length %d", mediaEvent.dataLength); - } - return Result::SUCCESS; + return createIndependentMediaEvents(output); } Result Filter::startRecordFilterHandler() { @@ -713,15 +726,119 @@ uint8_t* Filter::getIonBuffer(int fd, int size) { } native_handle_t* Filter::createNativeHandle(int fd) { - // Create a native handle to pass the av fd via the callback event. - native_handle_t* nativeHandle = native_handle_create(/*numFd*/ 1, 0); + native_handle_t* nativeHandle; + if (fd < 0) { + nativeHandle = native_handle_create(/*numFd*/ 0, 0); + } else { + // Create a native handle to pass the av fd via the callback event. + nativeHandle = native_handle_create(/*numFd*/ 1, 0); + } if (nativeHandle == NULL) { ALOGE("[Filter] Failed to create native_handle %d", errno); return NULL; } - nativeHandle->data[0] = dup(fd); + if (nativeHandle->numFds > 0) { + nativeHandle->data[0] = dup(fd); + } return nativeHandle; } + +Result Filter::createIndependentMediaEvents(vector output) { + int av_fd = createAvIonFd(output.size()); + if (av_fd == -1) { + return Result::UNKNOWN_ERROR; + } + // copy the filtered data to the buffer + uint8_t* avBuffer = getIonBuffer(av_fd, output.size()); + if (avBuffer == NULL) { + return Result::UNKNOWN_ERROR; + } + memcpy(avBuffer, output.data(), output.size() * sizeof(uint8_t)); + + native_handle_t* nativeHandle = createNativeHandle(av_fd); + if (nativeHandle == NULL) { + return Result::UNKNOWN_ERROR; + } + hidl_handle handle; + handle.setTo(nativeHandle, /*shouldOwn=*/true); + + // Create a dataId and add a pair into the dataId2Avfd map + uint64_t dataId = mLastUsedDataId++ /*createdUID*/; + mDataId2Avfd[dataId] = dup(av_fd); + + // Create mediaEvent and send callback + DemuxFilterMediaEvent mediaEvent; + mediaEvent = { + .avMemory = std::move(handle), + .dataLength = static_cast(output.size()), + .avDataId = dataId, + }; + if (mPts) { + mediaEvent.pts = mPts; + mPts = 0; + } + int size = mFilterEvent.events.size(); + mFilterEvent.events.resize(size + 1); + mFilterEvent.events[size].media(mediaEvent); + + // Clear and log + output.clear(); + mAvBufferCopyCount = 0; + ::close(av_fd); + if (DEBUG_FILTER) { + ALOGD("[Filter] av data length %d", mediaEvent.dataLength); + } + return Result::SUCCESS; +} + +Result Filter::createShareMemMediaEvents(vector output) { + // copy the filtered data to the shared buffer + uint8_t* sharedAvBuffer = getIonBuffer(mSharedAvMemHandle.getNativeHandle()->data[0], + output.size() + mSharedAvMemOffset); + if (sharedAvBuffer == NULL) { + return Result::UNKNOWN_ERROR; + } + memcpy(sharedAvBuffer + mSharedAvMemOffset, output.data(), output.size() * sizeof(uint8_t)); + + // Create a memory handle with numFds == 0 + native_handle_t* nativeHandle = createNativeHandle(-1); + if (nativeHandle == NULL) { + return Result::UNKNOWN_ERROR; + } + hidl_handle handle; + handle.setTo(nativeHandle, /*shouldOwn=*/true); + + // Create mediaEvent and send callback + DemuxFilterMediaEvent mediaEvent; + mediaEvent = { + .offset = static_cast(mSharedAvMemOffset), + .dataLength = static_cast(output.size()), + .avMemory = handle, + }; + mSharedAvMemOffset += output.size(); + if (mPts) { + mediaEvent.pts = mPts; + mPts = 0; + } + int size = mFilterEvent.events.size(); + mFilterEvent.events.resize(size + 1); + mFilterEvent.events[size].media(mediaEvent); + + // Clear and log + output.clear(); + if (DEBUG_FILTER) { + ALOGD("[Filter] shared av data length %d", mediaEvent.dataLength); + } + return Result::SUCCESS; +} + +bool Filter::sameFile(int fd1, int fd2) { + struct stat stat1, stat2; + if (fstat(fd1, &stat1) < 0 || fstat(fd2, &stat2) < 0) { + return false; + } + return (stat1.st_dev == stat2.st_dev) && (stat1.st_ino == stat2.st_ino); +} } // namespace implementation } // namespace V1_0 } // namespace tuner diff --git a/tv/tuner/1.1/default/Filter.h b/tv/tuner/1.1/default/Filter.h index 23bc25c0d3..f6776661d3 100644 --- a/tv/tuner/1.1/default/Filter.h +++ b/tv/tuner/1.1/default/Filter.h @@ -23,6 +23,7 @@ #include #include #include +#include #include #include "Demux.h" #include "Dvr.h" @@ -43,6 +44,7 @@ using ::android::hardware::MessageQueue; using ::android::hardware::MQDescriptorSync; using FilterMQ = MessageQueue; +const uint32_t BUFFER_SIZE_16M = 0x1000000; class Demux; class Dvr; @@ -78,6 +80,8 @@ class Filter : public V1_1::IFilter { virtual Return configureIpCid(uint32_t ipCid) override; + virtual Return getAvSharedHandle(getAvSharedHandle_cb _hidl_cb) override; + /** * To create a FilterMQ and its Event Flag. * @@ -93,6 +97,7 @@ class Filter : public V1_1::IFilter { void attachFilterToRecord(const sp dvr); void detachFilterFromRecord(); void freeAvHandle(); + void freeSharedAvHandle(); bool isMediaFilter() { return mIsMediaFilter; }; bool isPcrFilter() { return mIsPcrFilter; }; bool isRecordFilter() { return mIsRecordFilter; }; @@ -185,6 +190,9 @@ class Filter : public V1_1::IFilter { uint8_t* getIonBuffer(int fd, int size); native_handle_t* createNativeHandle(int fd); Result createMediaFilterEventWithIon(vector output); + Result createIndependentMediaEvents(vector output); + Result createShareMemMediaEvents(vector output); + bool sameFile(int fd1, int fd2); /** * Lock to protect writes to the FMQs @@ -212,6 +220,11 @@ class Filter : public V1_1::IFilter { std::map mDataId2Avfd; uint64_t mLastUsedDataId = 1; int mAvBufferCopyCount = 0; + + // Shared A/V memory handle + hidl_handle mSharedAvMemHandle; + bool mUsingSharedAvMem = true; + uint32_t mSharedAvMemOffset = 0; }; } // namespace implementation diff --git a/tv/tuner/1.1/vts/functional/FilterTests.cpp b/tv/tuner/1.1/vts/functional/FilterTests.cpp index 7e5b5498e0..5a8985dc2a 100644 --- a/tv/tuner/1.1/vts/functional/FilterTests.cpp +++ b/tv/tuner/1.1/vts/functional/FilterTests.cpp @@ -16,22 +16,70 @@ #include "FilterTests.h" -bool FilterCallback::readFilterEventData() { - bool result = false; - ALOGW("[vts] reading from filter FMQ or buffer %d", mFilterId); +void FilterCallback::testFilterDataOutput() { + android::Mutex::Autolock autoLock(mMsgLock); + while (mPidFilterOutputCount < 1) { + if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) { + EXPECT_TRUE(false) << "filter output matching pid does not output within timeout"; + return; + } + } + mPidFilterOutputCount = 0; + ALOGW("[vts] pass and stop"); +} + +void FilterCallback::readFilterEventData() { + ALOGW("[vts] reading filter event"); // todo separate filter handlers + for (int i = 0; i < mFilterEvent.events.size(); i++) { + auto event = mFilterEvent.events[i]; + switch (event.getDiscriminator()) { + case DemuxFilterEvent::Event::hidl_discriminator::media: + ALOGD("[vts] Media filter event, avMemHandle numFds=%d.", + event.media().avMemory.getNativeHandle()->numFds); + dumpAvData(event.media()); + break; + default: + break; + } + } for (int i = 0; i < mFilterEventExt.events.size(); i++) { auto eventExt = mFilterEventExt.events[i]; switch (eventExt.getDiscriminator()) { case DemuxFilterEventExt::Event::hidl_discriminator::tsRecord: - ALOGW("[vts] Extended TS record filter event, pts=%" PRIu64 ".", + ALOGD("[vts] Extended TS record filter event, pts=%" PRIu64 ".", eventExt.tsRecord().pts); break; default: break; } } - return result; +} + +bool FilterCallback::dumpAvData(DemuxFilterMediaEvent event) { + uint32_t length = event.dataLength; + uint32_t offset = event.offset; + // read data from buffer pointed by a handle + hidl_handle handle = event.avMemory; + if (handle.getNativeHandle()->numFds == 0) { + if (mAvSharedHandle == NULL) { + return false; + } + handle = mAvSharedHandle; + } + + int av_fd = handle.getNativeHandle()->data[0]; + uint8_t* buffer = + static_cast(mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, av_fd, 0)); + if (buffer == MAP_FAILED) { + ALOGE("[vts] fail to allocate av buffer, errno=%d", errno); + return false; + } + uint8_t output[length + 1]; + memcpy(output, buffer + offset, length); + // print buffer and check with golden output. + ::close(av_fd); + return true; } AssertionResult FilterTests::openFilterInDemux(DemuxFilterType type, uint32_t bufferSize) { @@ -81,6 +129,33 @@ AssertionResult FilterTests::getNewlyOpenedFilterId_64bit(uint64_t& filterId) { return AssertionResult(status == Result::SUCCESS); } +AssertionResult FilterTests::getSharedAvMemoryHandle(uint64_t filterId) { + EXPECT_TRUE(mFilters[filterId]) << "Open media filter first."; + Result status = Result::UNKNOWN_ERROR; + sp filter_v1_1 = + android::hardware::tv::tuner::V1_1::IFilter::castFrom(mFilters[filterId]); + if (filter_v1_1 != NULL) { + filter_v1_1->getAvSharedHandle([&](Result r, hidl_handle avMemory, uint64_t avMemSize) { + status = r; + if (status == Result::SUCCESS) { + mFilterCallbacks[mFilterId]->setSharedHandle(avMemory); + mFilterCallbacks[mFilterId]->setMemSize(avMemSize); + mAvSharedHandle = avMemory; + } + }); + } + return AssertionResult(status == Result::SUCCESS); +} + +AssertionResult FilterTests::releaseShareAvHandle(uint64_t filterId) { + Result status; + EXPECT_TRUE(mFilters[filterId]) << "Open media filter first."; + EXPECT_TRUE(mAvSharedHandle) << "No shared av handle to release."; + status = mFilters[filterId]->releaseAvHandle(mAvSharedHandle, 0 /*dataId*/); + + return AssertionResult(status == Result::SUCCESS); +} + AssertionResult FilterTests::configFilter(DemuxFilterSettings setting, uint64_t filterId) { Result status; EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first."; diff --git a/tv/tuner/1.1/vts/functional/FilterTests.h b/tv/tuner/1.1/vts/functional/FilterTests.h index a47f631868..bc6db86f9c 100644 --- a/tv/tuner/1.1/vts/functional/FilterTests.h +++ b/tv/tuner/1.1/vts/functional/FilterTests.h @@ -46,6 +46,7 @@ using android::hardware::Return; using android::hardware::Void; using android::hardware::tv::tuner::V1_0::DemuxFilterEvent; using android::hardware::tv::tuner::V1_0::DemuxFilterMainType; +using android::hardware::tv::tuner::V1_0::DemuxFilterMediaEvent; using android::hardware::tv::tuner::V1_0::DemuxFilterSettings; using android::hardware::tv::tuner::V1_0::DemuxFilterStatus; using android::hardware::tv::tuner::V1_0::DemuxFilterType; @@ -93,7 +94,14 @@ class FilterCallback : public IFilterCallback { } virtual Return onFilterEvent( - const android::hardware::tv::tuner::V1_0::DemuxFilterEvent& /*filterEvent*/) override { + const android::hardware::tv::tuner::V1_0::DemuxFilterEvent& filterEvent) override { + android::Mutex::Autolock autoLock(mMsgLock); + // Temprarily we treat the first coming back filter data on the matching pid a success + // once all of the MQ are cleared, means we got all the expected output + mFilterEvent = filterEvent; + readFilterEventData(); + mPidFilterOutputCount++; + mMsgCondition.signal(); return Void(); } @@ -104,8 +112,13 @@ class FilterCallback : public IFilterCallback { void setFilterId(uint32_t filterId) { mFilterId = filterId; } void setFilterInterface(sp filter) { mFilter = filter; } void setFilterEventType(FilterEventType type) { mFilterEventType = type; } + void setSharedHandle(hidl_handle sharedHandle) { mAvSharedHandle = sharedHandle; } + void setMemSize(uint64_t size) { mAvSharedMemSize = size; } + + void testFilterDataOutput(); - bool readFilterEventData(); + void readFilterEventData(); + bool dumpAvData(DemuxFilterMediaEvent event); private: uint32_t mFilterId; @@ -114,6 +127,9 @@ class FilterCallback : public IFilterCallback { DemuxFilterEvent mFilterEvent; DemuxFilterEventExt mFilterEventExt; + hidl_handle mAvSharedHandle = NULL; + uint64_t mAvSharedMemSize = -1; + android::Mutex mMsgLock; android::Mutex mFilterOutputLock; android::Condition mMsgCondition; @@ -127,10 +143,12 @@ class FilterTests { void setDemux(sp demux) { mDemux = demux; } sp getFilterById(uint64_t filterId) { return mFilters[filterId]; } - std::map> getFilterCallbacks() { return mFilterCallbacks; } + map> getFilterCallbacks() { return mFilterCallbacks; } AssertionResult openFilterInDemux(DemuxFilterType type, uint32_t bufferSize); AssertionResult getNewlyOpenedFilterId_64bit(uint64_t& filterId); + AssertionResult getSharedAvMemoryHandle(uint64_t filterId); + AssertionResult releaseShareAvHandle(uint64_t filterId); AssertionResult configFilter(DemuxFilterSettings setting, uint64_t filterId); AssertionResult configIpFilterCid(uint32_t ipCid, uint64_t filterId); AssertionResult getFilterMQDescriptor(uint64_t filterId); @@ -193,12 +211,14 @@ class FilterTests { sp mService; sp mFilter; sp mDemux; - std::map> mFilters; - std::map> mFilterCallbacks; + map> mFilters; + map> mFilterCallbacks; sp mFilterCallback; MQDesc mFilterMQDescriptor; vector mUsedFilterIds; + hidl_handle mAvSharedHandle = NULL; + uint64_t mFilterId = -1; }; diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp index e06de5394c..f87fa3c0d6 100644 --- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp @@ -18,6 +18,10 @@ namespace { +AssertionResult TunerBroadcastHidlTest::filterDataOutputTest() { + return filterDataOutputTestBase(mFilterTests); +} + void TunerFilterHidlTest::configSingleFilterInDemuxTest(FilterConfig filterConf, FrontendConfig frontendConf) { uint32_t feId; @@ -46,6 +50,38 @@ void TunerFilterHidlTest::configSingleFilterInDemuxTest(FilterConfig filterConf, ASSERT_TRUE(mFrontendTests.closeFrontend()); } +void TunerBroadcastHidlTest::mediaFilterUsingSharedMemoryTest(FilterConfig filterConf, + FrontendConfig frontendConf) { + uint32_t feId; + uint32_t demuxId; + sp demux; + uint64_t filterId; + + mFrontendTests.getFrontendIdByType(frontendConf.type, feId); + ASSERT_TRUE(feId != INVALID_ID); + ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); + ASSERT_TRUE(mFrontendTests.setFrontendCallback()); + ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); + ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); + mFrontendTests.setDemux(demux); + mFilterTests.setDemux(demux); + ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize)); + ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(filterId)); + ASSERT_TRUE(mFilterTests.getSharedAvMemoryHandle(filterId)); + ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId)); + ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId)); + ASSERT_TRUE(mFilterTests.startFilter(filterId)); + // tune test + ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/)); + ASSERT_TRUE(filterDataOutputTest()); + ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/)); + ASSERT_TRUE(mFilterTests.stopFilter(filterId)); + ASSERT_TRUE(mFilterTests.releaseShareAvHandle(filterId)); + ASSERT_TRUE(mFilterTests.closeFilter(filterId)); + ASSERT_TRUE(mDemuxTests.closeDemux()); + ASSERT_TRUE(mFrontendTests.closeFrontend()); +} + void TunerRecordHidlTest::recordSingleFilterTest(FilterConfig filterConf, FrontendConfig frontendConf, DvrConfig dvrConf) { uint32_t feId; @@ -116,6 +152,16 @@ TEST_P(TunerFrontendHidlTest, BlindScanFrontendWithEndFrequency) { mFrontendTests.scanTest(frontendScanArray[SCAN_DVBT], FrontendScanType::SCAN_BLIND); } +TEST_P(TunerBroadcastHidlTest, MediaFilterWithSharedMemoryHandle) { + description("Test the Media Filter with shared memory handle"); + mediaFilterUsingSharedMemoryTest(filterArray[TS_VIDEO0], frontendArray[DVBT]); +} + +INSTANTIATE_TEST_SUITE_P( + PerInstance, TunerBroadcastHidlTest, + testing::ValuesIn(android::hardware::getAllHalInstanceNames(ITuner::descriptor)), + android::hardware::PrintInstanceNameToString); + INSTANTIATE_TEST_SUITE_P( PerInstance, TunerFrontendHidlTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames(ITuner::descriptor)), diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h index 47004f62f0..f77a740136 100644 --- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h @@ -26,6 +26,20 @@ void initConfiguration() { initDvrConfig(); } +static AssertionResult success() { + return ::testing::AssertionSuccess(); +} + +AssertionResult filterDataOutputTestBase(FilterTests tests) { + // Data Verify Module + std::map>::iterator it; + std::map> filterCallbacks = tests.getFilterCallbacks(); + for (it = filterCallbacks.begin(); it != filterCallbacks.end(); it++) { + it->second->testFilterDataOutput(); + } + return success(); +} + class TunerFilterHidlTest : public testing::TestWithParam { public: virtual void SetUp() override { @@ -103,4 +117,34 @@ class TunerFrontendHidlTest : public testing::TestWithParam { }; GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerFrontendHidlTest); + +class TunerBroadcastHidlTest : public testing::TestWithParam { + public: + virtual void SetUp() override { + mService = ITuner::getService(GetParam()); + ASSERT_NE(mService, nullptr); + initConfiguration(); + + mFrontendTests.setService(mService); + mDemuxTests.setService(mService); + mFilterTests.setService(mService); + } + + protected: + static void description(const std::string& description) { + RecordProperty("description", description); + } + + sp mService; + FrontendTests mFrontendTests; + DemuxTests mDemuxTests; + FilterTests mFilterTests; + + AssertionResult filterDataOutputTest(); + + void mediaFilterUsingSharedMemoryTest(FilterConfig filterConf, FrontendConfig frontendConf); +}; + +// TODO remove from the allow list once the cf tv target is enabled for testing +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerBroadcastHidlTest); } // namespace \ No newline at end of file -- GitLab From c9d109fe0619e27d6034eb09bb97b86277c43da5 Mon Sep 17 00:00:00 2001 From: lesl Date: Wed, 16 Sep 2020 22:45:00 +0800 Subject: [PATCH 162/790] wifi: Add access network type support The access network type can be used to indicate network metered state. Add access network type support when create access point. Test: Manual Test, check client scan IE to show correct interworking value. see: b/137879206#comment14 Test: atest VtsHalWifiHostapdV1_0TargetTest Test: atest VtsHalWifiHostapdV1_1TargetTest Test: atest VtsHalWifiHostapdV1_2TargetTest Bug: 137879206 Change-Id: I74213bd763f865f26781313b00e1b1cfeee93086 --- wifi/hostapd/1.3/IHostapd.hal | 38 ++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/wifi/hostapd/1.3/IHostapd.hal b/wifi/hostapd/1.3/IHostapd.hal index d16448d074..0309f3b63f 100644 --- a/wifi/hostapd/1.3/IHostapd.hal +++ b/wifi/hostapd/1.3/IHostapd.hal @@ -16,14 +16,50 @@ package android.hardware.wifi.hostapd@1.3; -import @1.2::IHostapd; import @1.2::HostapdStatus; +import @1.2::IHostapd.IfaceParams; +import @1.2::IHostapd.NetworkParams; +import @1.2::IHostapd; import IHostapdCallback; /** * Top-level object for managing SoftAPs. */ interface IHostapd extends @1.2::IHostapd { + /** + * Parameters to use for setting up the access point network. + */ + struct NetworkParams { + /** + * Baseline information as defined in HAL 1.2. + */ + @1.2::IHostapd.NetworkParams V1_2; + + /** + * Enable the interworking service and set access network type to + * CHARGEABLE_PUBLIC_NETWORK when set to true. + */ + bool isMetered; + }; + + /** + * Adds a new access point for hostapd to control. + * + * This should trigger the setup of an access point with the specified + * interface and network params. + * + * @param ifaceParams AccessPoint Params for the access point. + * @param nwParams Network Params for the access point. + * @return status Status of the operation. + * Possible status codes: + * |HostapdStatusCode.SUCCESS|, + * |HostapdStatusCode.FAILURE_ARGS_INVALID|, + * |HostapdStatusCode.FAILURE_UNKNOWN|, + * |HostapdStatusCode.FAILURE_IFACE_EXISTS| + */ + addAccessPoint_1_3(@1.2::IHostapd.IfaceParams ifaceParams, NetworkParams nwParams) + generates (HostapdStatus status); + /** * Register for callbacks from the hostapd service. * -- GitLab From 64c13a083a2dd5226990d805105cbc9df15f02da Mon Sep 17 00:00:00 2001 From: Kevin Chyn Date: Mon, 21 Sep 2020 12:37:56 -0700 Subject: [PATCH 163/790] Update fingerprint #authenticate interfaces & documentation 1) Split into onAuthenticationSucceeded and onAuthenticaitonFailed. No longer need to use "weird behavior" below: A) authenticated(id=0) == reject B) onEnrolled(id=0) --> previously forbidden C) remove(id=0) --> previously magic number to remove all enrollments. The new interface has remove(int[] ids). 2) Renames keystoreOperationId to operationId, since keystore is only one example of a valid use case. operationId and HATs can be used as attestation for any opaque operation. Bug: 168842956 Bug: 168843220 Test: make -j56 android.hardware.biometrics.fingerprint-update-api Test: make -j56 VtsHalBiometricsFingerprintTargetTest Change-Id: I7ca0365be9cf82539d6cabc6d9fcec916badc323 --- .../biometrics/fingerprint/ISession.aidl | 2 +- .../fingerprint/ISessionCallback.aidl | 3 +- .../biometrics/fingerprint/ISession.aidl | 56 ++++++++++++++++++- .../fingerprint/ISessionCallback.aidl | 22 +++++++- .../VtsHalBiometricsFingerprintTargetTest.cpp | 6 +- 5 files changed, 84 insertions(+), 5 deletions(-) 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 06c8623bf5..c1f66e3b1f 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 @@ -19,7 +19,7 @@ package android.hardware.biometrics.fingerprint; @VintfStability interface ISession { android.hardware.biometrics.common.ICancellationSignal enroll(in int cookie, in android.hardware.keymaster.HardwareAuthToken hat); - android.hardware.biometrics.common.ICancellationSignal authenticate(in int cookie, in long keystoreOperationId); + android.hardware.biometrics.common.ICancellationSignal authenticate(in int cookie, in long operationId); android.hardware.biometrics.common.ICancellationSignal detectInteraction(in int cookie); void enumerateEnrollments(in int cookie); void removeEnrollments(in int cookie, in int[] enrollmentIds); diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl index 614044790a..114a2d10b1 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl @@ -22,7 +22,8 @@ interface ISessionCallback { 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, int vendorCode); - void onAuthenticated(in int enrollmentId, in android.hardware.keymaster.HardwareAuthToken hat); + void onAuthenticationSucceeded(in int enrollmentId, in android.hardware.keymaster.HardwareAuthToken hat); + void onAuthenticationFailed(); void onInteractionDetected(); void onEnrollmentsEnumerated(in int[] enrollmentIds); void onEnrollmentsRemoved(in int[] enrollmentIds); diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl index e2d23a6160..2d2dcafae9 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl @@ -27,7 +27,61 @@ interface ISession { ICancellationSignal enroll(in int cookie, in HardwareAuthToken hat); - ICancellationSignal authenticate(in int cookie, in long keystoreOperationId); + /** + * authenticate: + * + * A request to start looking for fingerprints to authenticate. + * + * Once the HAL is able to start processing the authentication request, it must + * notify framework via ISessionCallback#onStateChanged with + * SessionState::AUTHENTICATING. + * + * At any point during authentication, if a non-recoverable error occurs, + * the HAL must notify the framework via ISessionCallback#onError with + * the applicable authentication-specific error, and then send + * ISessionCallback#onStateChanged(cookie, SessionState::IDLING). + * + * During authentication, the implementation may notify the framework + * via ISessionCallback#onAcquired with messages that may be used to guide + * the user. This callback can be invoked multiple times if necessary. + * + * The HAL must notify the framework of accepts/rejects via + * ISessionCallback#onAuthentication*. + * + * The authentication lifecycle ends when either + * 1) A fingerprint is accepted, and ISessionCallback#onAuthenticationSucceeded + * is invoked, or + * 2) Any non-recoverable error occurs (such as lockout). See the full + * list of authentication-specific errors in the Error enum. + * + * Note that it is now the HAL's responsibility to keep track of lockout + * states. See IFingerprint#setLockoutCallback and ISession#resetLockout. + * + * Note that upon successful authentication, ONLY sensors configured as + * SensorStrength::STRONG are allowed to create and send a + * HardwareAuthToken to the framework. See the Android CDD for more + * details. For SensorStrength::STRONG sensors, the HardwareAuthToken's + * "challenge" field must be set with the operationId passed in during + * #authenticate. If the sensor is NOT SensorStrength::STRONG, the + * HardwareAuthToken MUST be null. + * + * @param cookie An identifier used to track subsystem operations related + * to this call path. The framework will guarantee that it is + * unique per ISession. + * @param operationId For sensors configured as SensorStrength::STRONG, + * this must be used ONLY upon successful authentication + * and wrapped in the HardwareAuthToken's "challenge" + * field and sent to the framework via + * ISessionCallback#onAuthenticated. The operationId is + * an opaque identifier created from a separate secure + * subsystem such as, but not limited to KeyStore/KeyMaster. + * The HardwareAuthToken can then be used as an attestation + * for the provided operation. For example, this is used + * to unlock biometric-bound auth-per-use keys (see + * setUserAuthenticationParameters in + * KeyGenParameterSpec.Builder and KeyProtection.Builder. + */ + ICancellationSignal authenticate(in int cookie, in long operationId); ICancellationSignal detectInteraction(in int cookie); diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl index c608d65569..d494965f42 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl @@ -31,7 +31,27 @@ interface ISessionCallback { void onEnrollmentProgress(in int enrollmentId, int remaining, int vendorCode); - void onAuthenticated(in int enrollmentId, in HardwareAuthToken hat); + /** + * Used to notify the framework upon successful authentication. Note that the authentication + * lifecycle ends when either 1) a fingerprint is accepted, or 2) an error such as + * Error::LOCKOUT occurred. The authentication lifecycle does NOT end when a fingerprint is + * rejected. + * + * @param enrollmentId Fingerprint that was accepted. + * @param hat If the sensor is configured as SensorStrength::STRONG, a non-null attestation that + * a fingerprint was accepted. The HardwareAuthToken's "challenge" field must be set + * with the operationId passed in during ISession#authenticate. If the sensor is NOT + * SensorStrength::STRONG, the HardwareAuthToken MUST be null. + */ + void onAuthenticationSucceeded(in int enrollmentId, in HardwareAuthToken hat); + + /** + * Used to notify the framework upon rejected attempts. Note that the authentication + * lifecycle ends when either 1) a fingerprint is accepted, or 2) an error such as + * Error::LOCKOUT occurred. The authentication lifecycle does NOT end when a fingerprint is + * rejected. + */ + void onAuthenticationFailed(); void onInteractionDetected(); diff --git a/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp b/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp index 9590d68000..4651f25879 100644 --- a/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp +++ b/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp @@ -65,11 +65,15 @@ class SessionCallback : public BnSessionCallback { return ndk::ScopedAStatus::ok(); } - ndk::ScopedAStatus onAuthenticated(int32_t /*enrollmentId*/, + ndk::ScopedAStatus onAuthenticationSucceeded(int32_t /*enrollmentId*/, const keymaster::HardwareAuthToken& /*hat*/) override { return ndk::ScopedAStatus::ok(); } + ndk::ScopedAStatus onAuthenticationFailed() override { + return ndk::ScopedAStatus::ok(); + } + ndk::ScopedAStatus onInteractionDetected() override { return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus onEnrollmentsEnumerated( -- GitLab From 90a29284e2e965a58d001b81c259b892de07b85e Mon Sep 17 00:00:00 2001 From: Eric Jeong Date: Wed, 9 Sep 2020 14:51:03 -0700 Subject: [PATCH 164/790] Add explanation to VHAL_HEARTBEAT property Bug: 168132371 Test: build okay Change-Id: I0755779b09ba830fae9f4017306740ec05b2f949 --- automotive/vehicle/2.0/types.hal | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/automotive/vehicle/2.0/types.hal b/automotive/vehicle/2.0/types.hal index b7c72e4f44..d8a6838bfa 100644 --- a/automotive/vehicle/2.0/types.hal +++ b/automotive/vehicle/2.0/types.hal @@ -2924,11 +2924,14 @@ enum VehicleProperty : int32_t { | VehicleArea:GLOBAL), /** - * Defines an event that VHAL signals to the car watchdog as a heartbeat. - * - * VHAL is supposed to write system uptime to this property at every 3 second. - * Car watchdog subscribes to this property and checks if the property is updated at every 3 - * second. If it isn’t, car watchdog considers VHAL unhealthy and terminates it. + * Defines an event that VHAL signals to car watchdog as a heartbeat. + * + * If VHAL supports this property, VHAL should write system uptime to this property at every 3 + * second. Car watchdog subscribes to this property and checks if the property is updated at + * every 3 second. With the buffer time of 3 second, car watchdog waits for a heart beat to be + * signaled up to 6 seconds from the last heart beat. If it isn’t, car watchdog considers + * VHAL unhealthy and terminates it. + * If this property is not supported by VHAL, car watchdog doesn't check VHAL health status. * * @change_mode VehiclePropertyChangeMode:ON_CHANGE * @access VehiclePropertyAccess:READ -- GitLab From 1288c105a7d074963cd0154abb01e65397dae3ab Mon Sep 17 00:00:00 2001 From: Kevin Chyn Date: Fri, 18 Sep 2020 16:42:44 -0700 Subject: [PATCH 165/790] Minor API changes and additional documentation for IFingerprint 1) Removes vendorCode from onEnrollmentProgress. This is already being sent in ISessionCallback#onAcquired 2) Adds missing SessionState::INVALIDATING_AUTHENTICATOR_ID state Test: make -j56 android.hardware.biometrics.fingerprint-update-api Test: make -j56 VtsHalBiometricsFingerprintTargetTest Test: make -j56 Change-Id: I246153339b336c029c9f156868127456aecf1a04 --- .../fingerprint/ISessionCallback.aidl | 2 +- .../biometrics/fingerprint/SessionState.aidl | 3 +- .../biometrics/fingerprint/Error.aidl | 43 +++++++- .../biometrics/fingerprint/ISession.aidl | 101 +++++++++++++++--- .../fingerprint/ISessionCallback.aidl | 9 +- .../biometrics/fingerprint/SessionState.aidl | 36 +++++++ .../VtsHalBiometricsFingerprintTargetTest.cpp | 4 +- 7 files changed, 177 insertions(+), 21 deletions(-) diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl index 114a2d10b1..cbac890442 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl @@ -21,7 +21,7 @@ interface ISessionCallback { void onStateChanged(in int cookie, in android.hardware.biometrics.fingerprint.SessionState state); 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, int vendorCode); + void onEnrollmentProgress(in int enrollmentId, int remaining); void onAuthenticationSucceeded(in int enrollmentId, in android.hardware.keymaster.HardwareAuthToken hat); void onAuthenticationFailed(); void onInteractionDetected(); diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.aidl index 38ca1e052b..97f1a1e987 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.aidl @@ -25,5 +25,6 @@ enum SessionState { ENUMERATING_ENROLLMENTS = 4, REMOVING_ENROLLMENTS = 5, GETTING_AUTHENTICATOR_ID = 6, - RESETTING_LOCKOUT = 7, + INVALIDATING_AUTHENTICATOR_ID = 7, + RESETTING_LOCKOUT = 8, } diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/Error.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/Error.aidl index cc79de7b05..da5ee18686 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/Error.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/Error.aidl @@ -19,14 +19,55 @@ package android.hardware.biometrics.fingerprint; @VintfStability @Backing(type="byte") enum Error { + /** + * A hardware error has occurred that cannot be resolved. For example, I2C failure or a broken + * sensor. + */ HW_UNAVAILABLE, + + /** + * The implementation is unable to process the request. For example, invalid arguments were + * supplied. + */ UNABLE_TO_PROCESS, + + /** + * The current operation took too long to complete. + */ TIMEOUT, + + /** + * No space available to store additional enrollments. + */ NO_SPACE, + + /** + * The operation was canceled. See common::ICancellationSignal. + */ CANCELED, + + /** + * The implementation was unable to remove an enrollment. + * See ISession#removeEnrollments. + */ UNABLE_TO_REMOVE, + + /** + * Authentication is locked out due to too many unsuccessful attempts. This is a rate-limiting + * lockout, and authentication can be restarted after a period of time. See the Android CDD for + * the full set of lockout and rate-limiting requirements. + */ LOCKOUT, + + /** + * Authenticatio nis disabled until the user unlocks with their device credential + * (PIN/Pattern/Password). See ISession#resetLockout. + */ LOCKOUT_PERMANENT, - VENDOR + + /** + * Used to enable vendor-specific error messages. + */ + VENDOR, } diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl index 2d2dcafae9..5fa56e012c 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl @@ -19,12 +19,75 @@ package android.hardware.biometrics.fingerprint; import android.hardware.biometrics.common.ICancellationSignal; import android.hardware.keymaster.HardwareAuthToken; +/** + * Operations that can be performed for unique sessions retrieved via IFingerprint#createSession. + * Methods defined within this interface can be split into the following categories: + * 1) Methods associated with a state (see the SessionState enum). State-based operations are + * handled by the HAL in FIFO order. + * 1a) Cancellable state-based operations. If a cancellable operation is in-progress and the + * framework requests a subsequent state-based operation, the implementation should finish + * the operation via ISessionCallback#onError with Error::CANCELED. + * 1b) Non-cancellable state-based operations. These operations should fully complete before the + * next state-based operation can be started. + * 2) Methods without a state. These methods may be invoked by the framework depending on its + * use case. For example on devices with sensors of FingerprintSensorType::UNDER_DISPLAY_*, + * ISession#onFingerDown may be invoked while the HAL is in SessionState::ENROLLING, + * SessionState::AUTHENTICATING, or SessionState::DETECTING_INTERACTION. + * + * If the HAL has multiple operations in its queue, it is not required to notify the framework + * of SessionState::IDLING between each operation. However, it must notify the framework when all + * work is completed. See ISessionCallback#onStateChanged. For example, the following is a valid + * sequence of ISessionCallback#onStateChanged invocations: SessionState::IDLING --> + * SessionState::ENROLLING --> SessionState::ENUMERATING_ENROLLMENTS --> SessionState::IDLING. + */ @VintfStability interface ISession { /** * Methods applicable to any fingerprint type. */ + /** + * enroll: + * + * A request to add a fingerprint enrollment. + * + * Once the HAL is able to start processing the enrollment request, it must + * notify the framework via ISessionCallback#onStateChanged with + * SessionState::ENROLLING. + * + * At any point during enrollment, if a non-recoverable error occurs, + * the HAL must notify the framework via ISessionCallback#onError with + * the applicable enrollment-specific error, and then send + * ISessionCallback#onStateChanged(cookie, SessionState::IDLING) if no + * subsequent operation is in the queue. + * + * Before capturing fingerprint data, the implementation must first + * verify the authenticity and integrity of the provided HardwareAuthToken. + * In addition, it must check that the challenge within the provided + * HardwareAuthToken is valid. See IFingerprint#generateChallenge. + * If any of the above checks fail, the framework must be notified + * via ISessionCallback#onError and the HAL must notify the framework when + * it returns to the idle state. See Error::UNABLE_TO_PROCESS. + * + * During enrollment, the implementation may notify the framework + * via ISessionCallback#onAcquired with messages that may be used to guide + * the user. This callback can be invoked multiple times if necessary. + * Similarly, the framework may be notified of enrollment progress changes + * via ISessionCallback#onEnrollmentProgress. Once the framework is notified + * that there are 0 "remaining" steps, the framework may cache the + * "enrollmentId". See ISessionCallback#onEnrollmentProgress for more info. + * The HAL must notify the framework once it returns to the idle state. + * + * When a finger is successfully added and before the framework is notified + * of remaining=0, the implementation MUST update and associate this + * (sensorId, user) pair with a new new entropy-encoded random identifier. + * See ISession#getAuthenticatorId for more information. + * + * @param cookie An identifier used to track subsystem operations related + * to this call path. The client must guarantee that it is + * unique per ISession. + * @param hat See above documentation. + */ ICancellationSignal enroll(in int cookie, in HardwareAuthToken hat); /** @@ -39,7 +102,8 @@ interface ISession { * At any point during authentication, if a non-recoverable error occurs, * the HAL must notify the framework via ISessionCallback#onError with * the applicable authentication-specific error, and then send - * ISessionCallback#onStateChanged(cookie, SessionState::IDLING). + * ISessionCallback#onStateChanged(cookie, SessionState::IDLING) if no + * subsequent operation is in the queue. * * During authentication, the implementation may notify the framework * via ISessionCallback#onAcquired with messages that may be used to guide @@ -66,7 +130,7 @@ interface ISession { * HardwareAuthToken MUST be null. * * @param cookie An identifier used to track subsystem operations related - * to this call path. The framework will guarantee that it is + * to this call path. The client must guarantee that it is * unique per ISession. * @param operationId For sensors configured as SensorStrength::STRONG, * this must be used ONLY upon successful authentication @@ -99,9 +163,10 @@ interface ISession { * The following only applies to sensors that are configured as * SensorStrength::STRONG. * - * The authenticatorId is used during key generation and key import to to - * associate a key (in KeyStore / KeyMaster) with the current set of - * enrolled fingerprints. For example, the following public Android APIs + * The authenticatorId is a (sensorId, user)-specific identifier which + * can be used during key generation and key import to to associate a + * key (in KeyStore / KeyMaster) with the current set of enrolled + * fingerprints. For example, the following public Android APIs * allow for keys to be invalidated when the user adds a new enrollment * after the key was created: * KeyGenParameterSpec.Builder.setInvalidatedByBiometricEnrollment and @@ -120,7 +185,7 @@ interface ISession { * 4) MUST be an entropy-encoded random number * * @param cookie An identifier used to track subsystem operations related - * to this call path. The framework will guarantee that it is + * to this call path. The client must guarantee that it is * unique per ISession. */ void getAuthenticatorId(in int cookie); @@ -138,9 +203,15 @@ interface ISession { * * When invoked by the framework, the implementation must perform the * following sequence of events: - * 1) Verify the authenticity and integrity of the provided HAT + * 1) Verify the authenticity and integrity of the provided HAT. If this + * check fails, the HAL must invoke ISessionCallback#onError with + * Error::UNABLE_TO_PROCESS and return to + * SessionState::IDLING if no subsequent work is in the queue. * 2) Verify that the timestamp provided within the HAT is relatively - * recent (e.g. on the order of minutes, not hours). + * recent (e.g. on the order of minutes, not hours). If this check fails, + * the HAL must invoke ISessionCallback#onError with + * Error::UNABLE_TO_PROCESS and return to SessionState::IDLING + * if no subsequent work is in the queue. * 3) Update the authenticatorId with a new entropy-encoded random number * 4) Persist the new authenticatorId to non-ephemeral storage * 5) Notify the framework that the above is completed, via @@ -154,7 +225,7 @@ interface ISession { * across multiple biometric HALs as necessary. * * @param cookie An identifier used to track subsystem operations related - * to this call path. The framework will guarantee that it is + * to this call path. The client must guarantee that it is * unique per ISession. * @param hat HardwareAuthToken that must be validated before proceeding * with this operation. @@ -169,15 +240,15 @@ interface ISession { * 1) Verify the authenticity and integrity of the provided HAT * 2) Verify that the timestamp provided within the HAT is relatively * recent (e.g. on the order of minutes, not hours). + * If either of the checks fail, the HAL must invoke ISessionCallback#onError + * with Error::UNABLE_TO_PROCESS and return to SessionState::IDLING + * if no subsequent work is in the queue. * - * Upon successful verification, the HAL must notify the framework via - * ILockoutCallback#onLockoutChanged(sensorId, userId, 0). - * - * If verification was uncessful, the HAL must notify the framework via - * ILockoutCallback#onLockoutChanged(sensorId, userId, remaining_time). + * Upon successful verification, the HAL must clear the lockout counter + * and notify the framework via ILockoutCallback#onLockoutChanged(sensorId, userId, 0). * * @param cookie An identifier used to track subsystem operations related - * to this call path. The framework will guarantee that it is + * to this call path. The client must guarantee that it is * unique per ISession. * @param hat HardwareAuthToken See above documentation. */ diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl index d494965f42..7130520ca6 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl @@ -29,7 +29,14 @@ interface ISessionCallback { void onError(in Error error, in int vendorCode); - void onEnrollmentProgress(in int enrollmentId, int remaining, int vendorCode); + /** + * Used to notify the framework of enrollment progress. Enrollment completes when remaining==0, + * + * @param enrollmentId Unique stable identifier for the enrollment that's being added by this + * ISession#enroll invocation. + * @param remaining Remaining number of steps before enrollment is complete. + */ + void onEnrollmentProgress(in int enrollmentId, int remaining); /** * Used to notify the framework upon successful authentication. Note that the authentication diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SessionState.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SessionState.aidl index 3b4ba184e6..405b011b31 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SessionState.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SessionState.aidl @@ -19,13 +19,49 @@ package android.hardware.biometrics.fingerprint; @VintfStability @Backing(type="byte") enum SessionState { + /** + * The HAL is not processing any session requests. + */ IDLING, + + /** + * The HAL is processing the ISession#enroll request. + */ ENROLLING, + + /** + * The HAL is processing the ISession#authenticate request. + */ AUTHENTICATING, + + /** + * The HAL is processing the ISession#detectInteraction request. + */ DETECTING_INTERACTION, + + /** + * The HAL is processing the ISession#enumerateEnrollments request. + */ ENUMERATING_ENROLLMENTS, + + /** + * The HAL is processing the ISession#removeEnrollments request. + */ REMOVING_ENROLLMENTS, + + /** + * The HAL is processing the ISession#getAuthenticatorId request. + */ GETTING_AUTHENTICATOR_ID, + + /** + * The HAL is processing the ISession#invalidateAuthenticatorId request. + */ + INVALIDATING_AUTHENTICATOR_ID, + + /** + * The HAL is processing the ISession#resetLockout request. + */ RESETTING_LOCKOUT } diff --git a/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp b/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp index 4651f25879..30117862ee 100644 --- a/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp +++ b/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp @@ -60,8 +60,8 @@ class SessionCallback : public BnSessionCallback { return ndk::ScopedAStatus::ok(); } - ndk::ScopedAStatus onEnrollmentProgress(int32_t /*enrollmentId*/, int32_t /*remaining*/, - int32_t /*vendorCode*/) override { + ndk::ScopedAStatus onEnrollmentProgress(int32_t /*enrollmentId*/, + int32_t /*remaining*/) override { return ndk::ScopedAStatus::ok(); } -- GitLab From 8b3cd5db216becb73b63834bc369a28bd39830d2 Mon Sep 17 00:00:00 2001 From: Kevin Chyn Date: Mon, 21 Sep 2020 17:03:18 -0700 Subject: [PATCH 166/790] Finish remainder of documentation. Note that this doesn't mean documentation is done, it just means that previously undocumented areas now at least have some documentation. Bug: 168843220 Test: Builds Change-Id: I92db9b228d46b3925d3f7ae56698f7c52a0ae1bf --- .../biometrics/fingerprint/AcquiredInfo.aidl | 36 ++++++ .../fingerprint/ILockoutCallback.aidl | 12 +- .../biometrics/fingerprint/ISession.aidl | 111 +++++++++++++++++- .../fingerprint/ISessionCallback.aidl | 75 +++++++++++- 4 files changed, 225 insertions(+), 9 deletions(-) diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl index 8cb78339c4..a3259f6916 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl @@ -19,13 +19,49 @@ package android.hardware.biometrics.fingerprint; @VintfStability @Backing(type="byte") enum AcquiredInfo { + /** + * A high quality fingerprint image was detected, no further user interaction is necessary. + */ GOOD, + + /** + * Not enough of a fingerprint was detected. Reposition the finger, or a longer swipe needed. + */ PARTIAL, + + /** + * Image doesn't contain enough detail for recognition. + */ INSUFFICIENT, + + /** + * The sensor needs to be cleaned. + */ SENSOR_DIRTY, + + /** + * For swipe-type sensors, the swipe was too slow and not enough data was collected. + */ TOO_SLOW, + + /** + * For swipe-type sensors, the swipe was too fast and not enough data was collected. + */ TOO_FAST, + + /** + * This message represents the earliest message sent at the beginning of the authentication + * pipeline. It is expected to be used to measure latency. For example, in a camera-based + * authentication system it's expected to be sent prior to camera initialization. Note this + * should be sent whenever authentication is started or restarted. The framework may measure + * latency based on the time between the last START message and the onAuthenticated callback. + */ START, + + /** + * Vendor-specific acquisition message. See ISessionCallback#onAcquired vendorCode + * documentation. + */ VENDOR } diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ILockoutCallback.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ILockoutCallback.aidl index 4b31a38e52..43cb20ffce 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ILockoutCallback.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ILockoutCallback.aidl @@ -22,9 +22,9 @@ oneway interface ILockoutCallback { * Notifies the framework that the user has just entered the Error::LOCKOUT state. This must be * sent in the following scenarios: * 1) The user just attempted authentication and was rejected, resulting in a timed lockout. - * 2) The framework just created a session for a sensorId/userId pair that has not been + * 2) The framework just created a session for a (sensorId, userId) pair that has not been * created since the HAL started (e.g. there is no active or idle session for this - * sensorId/userId pair. + * (sensorId, userId) pair. * * @param sensorId Sensor for which the user is locked out. * @param userId User for which the sensor is locked out. @@ -36,9 +36,9 @@ oneway interface ILockoutCallback { * Notifies the framework that the user has just entered the Error::LOCKOUT_PERMANENT state. * This must be sent in the following scenarios: * 1) The user just attempted authentication and was rejected, resulting in a permanent lockout. - * 2) The framework just created a session for a sensorId/userId pair that has not been + * 2) The framework just created a session for a (sensorId, userId) pair that has not been * created since the HAL started (e.g. there is no active or idle session for this - * sensorId/userId pair. + * (sensorId, userId) pair. * * @param sensorId Sensor for which the user is locked out. * @param userId User for which the sensor is locked out. @@ -46,11 +46,13 @@ oneway interface ILockoutCallback { void onLockoutPermanent(in int sensorId, in int userId); /** - * Notifies the framework that lockout has been cleared for this sensorId/userId pair. This + * Notifies the framework that lockout has been cleared for this (sensorId, userId) pair. This * can happen in the following scenarios: * 1) A timed lockout has ended (e.g. original durationMillis specified in #onLockoutTimed * has expired. * 2) See ISession#resetLockout. + * 3) The (sensorId, userId) pair is not in any lockout state, and the user successfully + * authenticated with a fingerprint. * * @param sensorId Sensor for which the user's lockout is cleared. * @param userId User for the sensor's lockout is cleared. diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl index 5fa56e012c..946027b5f1 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl @@ -80,7 +80,7 @@ interface ISession { * * When a finger is successfully added and before the framework is notified * of remaining=0, the implementation MUST update and associate this - * (sensorId, user) pair with a new new entropy-encoded random identifier. + * (sensorId, userId) pair with a new new entropy-encoded random identifier. * See ISession#getAuthenticatorId for more information. * * @param cookie An identifier used to track subsystem operations related @@ -147,10 +147,75 @@ interface ISession { */ ICancellationSignal authenticate(in int cookie, in long operationId); + /** + * detectInteraction: + * + * A request to start looking for fingerprints without performing matching. + * + * Once the HAL is able to start processing this request, it must notify the framework via + * ISessionCallback#onStateChanged with SessionState::DETECTING_INTERACTION. + * + * The framework will use this method in cases where determing user presence is required, but + * identifying/authentication is not. For example, when the device is encrypted (first boot) or + * in lockdown mode. + * + * At any point during detectInteraction, if a non-recoverable error occurs, the HAL must notify + * the framework via ISessionCallback#onError with the applicable error, and then send + * ISessionCallback#onStateChanged(cookie, SessionState::IDLING) if no subsequent operation is + * in the queue. + * + * The implementation must only check for a fingerprint-like image was detected (e.g. to + * minimize interactions due to non-fingerprint objects), and the lockout counter must not + * be modified. + * + * Upon detecting any fingerprint, the implementation must invoke + * ISessionCallback#onInteractionDetected. + * + * The lifecycle of this operation ends when either + * 1) Any fingerprint is detected and the framework is notified via + * ISessionCallback#onInteractiondetected + * 2) The operation was cancelled by the framework (see ICancellationSignal) + * 3) The HAL ends the operation, for example when a subsequent operation pre-empts this one. + * + * Note that if the operation is canceled, the implementation must notify the framework via + * ISessionCallback#onError with Error::CANCELED. + * + * @param cookie An identifier used to track subsystem operations related to this call path. + * The framework will guarantee that it is unique per ISession. + */ ICancellationSignal detectInteraction(in int cookie); + /* + * enumerateEnrollments: + * + * A request to enumerate (list) the enrollments for this (sensorId, userId) pair. The + * framework typically uses this to ensure that its cache is in sync with the HAL. + * + * Once the HAL is able to start processing this request, it must notify the framework via + * ISessionCallback#onStateChanged with SessionState::ENUMERATING_ENROLLMENTS. + * + * The implementation must then notify the framework with a list of enrollments applicable + * for the current session via ISessionCallback#onEnrollmentsEnumerated. + * + * @param cookie An identifier used to track subsystem operations related to this call path. + * The framework will guarantee that it is unique per ISession. + */ void enumerateEnrollments(in int cookie); + /** + * removeEnrollments: + * + * A request to remove the enrollments for this (sensorId, userId) pair. + * + * Once the HAL is able to start processing this request, it must notify the framework via + * ISessionCallback#onStateChanged with SessionState::REMOVING_ENROLLMENTS. + * + * After removing the enrollmentIds from everywhere necessary (filesystem, secure subsystems, + * etc), the implementation must notify the framework via ISessionCallback#onEnrollmentsRemoved. + * + * @param cookie An identifier used to track subsystem operations related to this call path. + * The framework will guarantee that it is unique per ISession. + */ void removeEnrollments(in int cookie, in int[] enrollmentIds); /** @@ -259,10 +324,54 @@ interface ISession { * Methods for notifying the under-display fingerprint sensor about external events. */ + /** + * onPointerDown: + * + * This method only applies to sensors that are configured as + * FingerprintSensorType::UNDER_DISPLAY_*. If invoked erroneously by the framework for sensors + * of other types, the HAL must treat this as a no-op and return immediately. + * + * For sensors of type FingerprintSensorType::UNDER_DISPLAY_*, this method is used to notify the + * HAL of display touches. This method can be invoked when the session is in one of the + * following states: SessionState::ENROLLING, SessionState::AUTHENTICATING, or + * SessionState::DETECTING_INTERACTION. + * + * Note that the framework will only invoke this method if the event occurred on the display + * on which this sensor is located. + * + * Note that for sensors which require illumination such as + * FingerprintSensorType::UNDER_DISPLAY_OPTICAL, and where illumination is handled below + * the framework, this is a good time to start illuminating. + * + * @param pointerId See android.view.MotionEvent#getPointerId + * @param x The distance in pixels from the left edge of the display. + * @param y The distance in pixels from the top edge of the display. + * @param minor See android.view.MotionEvent#getTouchMinor + * @param major See android.view.MotionEvent#getTouchMajor + */ void onPointerDown(in int pointerId, in int x, in int y, in float minor, in float major); + /** + * onPointerUp: + * + * This method only applies to sensors that are configured as + * FingerprintSensorType::UNDER_DISPLAY_*. If invoked for sensors of other types, the HAL must + * treat this as a no-op and return immediately. + * + * @param pointerId See android.view.MotionEvent#getPointerId + */ void onPointerUp(in int pointerId); + /* + * onUiReady: + * + * This method only applies to sensors that are configured as + * FingerprintSensorType::UNDER_DISPLAY_OPTICAL. If invoked for sensors of other types, the HAL + * must treat this as a no-op and return immediately. + * + * For FingerprintSensorType::UNDER_DISPLAY_OPTICAL where illumination is handled above the + * HAL, the framework will invoke this method to notify that the illumination has started. + */ void onUiReady(); } diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl index 7130520ca6..81a87a8290 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl @@ -23,14 +23,48 @@ import android.hardware.keymaster.HardwareAuthToken; @VintfStability interface ISessionCallback { + /** + * Used to notify the framework of session state changes. See ISession for more information. + */ void onStateChanged(in int cookie, in SessionState state); + /** + * This method must only be used to notify the framework during the following states: + * 1) SessionState::ENROLLING + * 2) SessionState::AUTHENTICATING + * 3) SessionState::DETECTING_INTERACTION + * + * These messages may be used to provide user guidance multiple times if necessary per + * operation. + * + * @param info See the AcquiredInfo enum. + * @param vendorCode Only valid if info == AcquiredInfo::VENDOR. + */ void onAcquired(in AcquiredInfo info, in int vendorCode); + /** + * This method must only be used to notify the framework during the following states: + * 1) SessionState::ENROLLING + * 2) SessionState::AUTHENTICATING + * 3) SessionState::DETECTING_INTERACTION + * 4) SessionState::INVALIDATING_AUTHENTICATOR_ID + * 5) SessionState::RESETTING_LOCKOUT + * + * These messages may be used to notify the framework or user that a non-recoverable error + * has occurred. The operation is finished, and the HAL must proceed with the next operation + * or return to SessionState::IDLING if the queue is empty. + * + * Note that cancellation (see common::ICancellationSignal) and preemption most be followed with + * an Error::CANCELED message. + * + * @param error See the Error enum. + * @param vendorCode Only valid if error == Error::VENDOR. + */ void onError(in Error error, in int vendorCode); /** - * Used to notify the framework of enrollment progress. Enrollment completes when remaining==0, + * This method must only be used to notify the framework during the following state: + * 1) SessionState::ENROLLING * * @param enrollmentId Unique stable identifier for the enrollment that's being added by this * ISession#enroll invocation. @@ -39,6 +73,8 @@ interface ISessionCallback { void onEnrollmentProgress(in int enrollmentId, int remaining); /** + * This method must only be used to notify the framework during SessionState::AUTHENTICATING. + * * Used to notify the framework upon successful authentication. Note that the authentication * lifecycle ends when either 1) a fingerprint is accepted, or 2) an error such as * Error::LOCKOUT occurred. The authentication lifecycle does NOT end when a fingerprint is @@ -53,6 +89,8 @@ interface ISessionCallback { void onAuthenticationSucceeded(in int enrollmentId, in HardwareAuthToken hat); /** + * This method must only be used to notify the framework during SessionState::AUTHENTICATING. + * * Used to notify the framework upon rejected attempts. Note that the authentication * lifecycle ends when either 1) a fingerprint is accepted, or 2) an error such as * Error::LOCKOUT occurred. The authentication lifecycle does NOT end when a fingerprint is @@ -60,19 +98,50 @@ interface ISessionCallback { */ void onAuthenticationFailed(); + /** + * This method must only be used to notify the framework during + * SessionState::DETECTING_INTERACTION + * + * Notifies the framework that user interaction occurred. See ISession#detectInteraction. + */ void onInteractionDetected(); + /** + * This method must only be used to notify the framework during + * SessionState::ENUMERATING_ENROLLMENTS. + * + * Notifies the framework of the current enrollments. See ISession#enumerateEnrollments. + * + * @param enrollmentIds A list of enrollments for the session's (userId, sensorId) pair. + */ void onEnrollmentsEnumerated(in int[] enrollmentIds); + /** + * This method must only be used to notify the framework during + * SessionState::REMOVING_ENROLLMENTS. + * + * Notifies the framework that the specified enrollments are removed. + * + * @param enrollmentIds The enrollments that were removed. + */ void onEnrollmentsRemoved(in int[] enrollmentIds); /** - * A callback invoked when ISession#getAuthenticatorId is invoked. + * This method must only be used to notify the framework during + * SessionState::GETTING_AUTHENTICATOR_ID. + * + * Notifies the framework with the authenticatorId corresponding to this session's + * (userId, sensorId) pair. + * + * @param authenticatorId See the above documentation. */ void onAuthenticatorIdRetrieved(in long authenticatorId); /** - * A callback invoked when ISession#invalidateAuthenticatorId has completed. + * This method must only be used to notify the framework during + * SessionState::INVALIDATING_AUTHENTICATOR_ID. + * + * See ISession#invalidateAuthenticatorId for more information. */ void onAuthenticatorIdInvalidated(); } -- GitLab From ef79d661ba73f7472557b9d48f3cd5b0f84cec69 Mon Sep 17 00:00:00 2001 From: Kevin Chyn Date: Tue, 22 Sep 2020 12:14:44 -0700 Subject: [PATCH 167/790] Move lockout callbacks to ISessionCallback Also fixes backward compatibility for AcquiredInfo and Error constants. For lockout-related changes: 1) If a session doesn't exist, it means the framework (or higher) doesn't care about its lockout state. 2) This allows the ISession#authenticate lifecycle to be clearer, e.g. no need for ILockoutCallback#onLockoutTimed followed by ISessionCallback#onError(LOCKOUT) Bug: 168842956 Bug: 168843220 Test: make -j android.hardware.biometrics.fingerprint-update-api Test: make -j Test: make -j VtsHalBiometricsFingerprintTargetTest Change-Id: I0b7e7ab3b89d0d1d7647535af07766c493a2067b --- .../biometrics/fingerprint/AcquiredInfo.aidl | 4 +- .../biometrics/fingerprint/Error.aidl | 14 +- .../biometrics/fingerprint/IFingerprint.aidl | 1 - .../fingerprint/ILockoutCallback.aidl | 24 ---- .../fingerprint/ISessionCallback.aidl | 3 + .../biometrics/fingerprint/AcquiredInfo.aidl | 12 +- .../biometrics/fingerprint/Error.aidl | 23 ++-- .../biometrics/fingerprint/IFingerprint.aidl | 31 ----- .../fingerprint/ILockoutCallback.aidl | 62 --------- .../biometrics/fingerprint/ISession.aidl | 122 ++++++++++-------- .../fingerprint/ISessionCallback.aidl | 49 ++++++- .../fingerprint/aidl/default/Fingerprint.cpp | 5 - .../fingerprint/aidl/default/Fingerprint.h | 3 - .../VtsHalBiometricsFingerprintTargetTest.cpp | 12 ++ 14 files changed, 154 insertions(+), 211 deletions(-) delete mode 100644 biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ILockoutCallback.aidl delete mode 100644 biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ILockoutCallback.aidl diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl index 329a35dc49..df30dcae47 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl @@ -24,6 +24,6 @@ enum AcquiredInfo { SENSOR_DIRTY = 3, TOO_SLOW = 4, TOO_FAST = 5, - START = 6, - VENDOR = 7, + VENDOR = 6, + START = 7, } diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl index 0298c126c4..6bd71b2d34 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl @@ -18,13 +18,11 @@ package android.hardware.biometrics.fingerprint; @Backing(type="byte") @VintfStability enum Error { - HW_UNAVAILABLE = 0, - UNABLE_TO_PROCESS = 1, - TIMEOUT = 2, - NO_SPACE = 3, - CANCELED = 4, - UNABLE_TO_REMOVE = 5, - LOCKOUT = 6, - LOCKOUT_PERMANENT = 7, + HW_UNAVAILABLE = 1, + UNABLE_TO_PROCESS = 2, + TIMEOUT = 3, + NO_SPACE = 4, + CANCELED = 5, + UNABLE_TO_REMOVE = 6, VENDOR = 8, } diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl index 9cbf343181..6ca6d16eb3 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl @@ -20,7 +20,6 @@ package android.hardware.biometrics.fingerprint; 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); - void setLockoutCallback(in android.hardware.biometrics.fingerprint.ILockoutCallback cb); void generateChallenge(in int sensorId, in int userId, in int timeoutSec, in android.hardware.biometrics.fingerprint.IGenerateChallengeCallback cb); void revokeChallenge(in int sensorId, in int userId, in long challenge, in android.hardware.biometrics.fingerprint.IRevokeChallengeCallback cb); } diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ILockoutCallback.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ILockoutCallback.aidl deleted file mode 100644 index 88aabbf487..0000000000 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ILockoutCallback.aidl +++ /dev/null @@ -1,24 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // -/////////////////////////////////////////////////////////////////////////////// - -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. -// -// You must not make a backward incompatible changes to the AIDL files 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.fingerprint; -@VintfStability -interface ILockoutCallback { - oneway void onLockoutTimed(in int sensorId, in int userId, in long durationMillis); - oneway void onLockoutPermanent(in int sensorId, in int userId); - oneway void onLockoutCleared(in int sensorId, in int userId); -} diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl index cbac890442..74ec07774c 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl @@ -24,6 +24,9 @@ interface ISessionCallback { 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); diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl index a3259f6916..adb1c78cb2 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl @@ -49,6 +49,12 @@ enum AcquiredInfo { */ TOO_FAST, + /** + * Vendor-specific acquisition message. See ISessionCallback#onAcquired vendorCode + * documentation. + */ + VENDOR, + /** * This message represents the earliest message sent at the beginning of the authentication * pipeline. It is expected to be used to measure latency. For example, in a camera-based @@ -57,11 +63,5 @@ enum AcquiredInfo { * latency based on the time between the last START message and the onAuthenticated callback. */ START, - - /** - * Vendor-specific acquisition message. See ISessionCallback#onAcquired vendorCode - * documentation. - */ - VENDOR } diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/Error.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/Error.aidl index da5ee18686..014a4c032a 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/Error.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/Error.aidl @@ -19,11 +19,16 @@ package android.hardware.biometrics.fingerprint; @VintfStability @Backing(type="byte") enum Error { + /** + * Used for testing, and to keep subsequent numbering consistent with older HIDLs. + */ + // NO_ERROR = 0, + /** * A hardware error has occurred that cannot be resolved. For example, I2C failure or a broken * sensor. */ - HW_UNAVAILABLE, + HW_UNAVAILABLE = 1, /** * The implementation is unable to process the request. For example, invalid arguments were @@ -53,21 +58,19 @@ enum Error { UNABLE_TO_REMOVE, /** - * Authentication is locked out due to too many unsuccessful attempts. This is a rate-limiting - * lockout, and authentication can be restarted after a period of time. See the Android CDD for - * the full set of lockout and rate-limiting requirements. + * Reserved to maintain backwards compatibility. See ISessionCallback#onLockoutTimed instead. */ - LOCKOUT, + // LOCKOUT = 7, /** - * Authenticatio nis disabled until the user unlocks with their device credential - * (PIN/Pattern/Password). See ISession#resetLockout. + * Used to enable vendor-specific error messages. */ - LOCKOUT_PERMANENT, + VENDOR = 8, /** - * Used to enable vendor-specific error messages. + * Reserved to maintain backwards compatibility. See ISessionCallback#onLockoutPermanent + * instead. */ - VENDOR, + // LOCKOUT_PERMANENT = 9, } diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl index 57319b2906..0c8ebc534b 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl @@ -17,7 +17,6 @@ package android.hardware.biometrics.fingerprint; import android.hardware.biometrics.fingerprint.IGenerateChallengeCallback; -import android.hardware.biometrics.fingerprint.ILockoutCallback; import android.hardware.biometrics.fingerprint.IRevokeChallengeCallback; import android.hardware.biometrics.fingerprint.ISession; import android.hardware.biometrics.fingerprint.ISessionCallback; @@ -72,36 +71,6 @@ interface IFingerprint { */ ISession createSession(in int sensorId, in int userId, in ISessionCallback cb); - /** - * setLockoutCallback: - * - * Sets a callback to notify the framework lockout changes. Note - * that lockout is user AND sensor specific. In other words, there is a - * separate lockout state for each (user, sensor) pair. For example, the - * following is a valid state on a multi-sensor device: - * ------------------------------------------------------------------ - * | SensorId | UserId | FailedAttempts | LockedOut | LockedUntil | - * |----------|--------|----------------|-----------|---------------| - * | 0 | 0 | 1 | false | x | - * | 1 | 0 | 5 | true | | - * | 0 | 10 | 0 | false | x | - * | 1 | 10 | 0 | false | x | - * ------------------------------------------------------------------ - * - * Lockout may be cleared in the following ways: - * 1) ISession#resetLockout - * 2) After a period of time, according to a rate-limiter. - * - * In addition, lockout states MUST persist after device reboots, HAL - * crashes, etc. - * - * See the Android CDD section 7.3.10 for the full set of lockout and - * rate-limiting requirements. - * - * @param cb Used to notify the framework of lockout changes. - */ - void setLockoutCallback(in ILockoutCallback cb); - /** * generateChallenge: * diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ILockoutCallback.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ILockoutCallback.aidl deleted file mode 100644 index 43cb20ffce..0000000000 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ILockoutCallback.aidl +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.hardware.biometrics.fingerprint; - -@VintfStability -oneway interface ILockoutCallback { - /** - * Notifies the framework that the user has just entered the Error::LOCKOUT state. This must be - * sent in the following scenarios: - * 1) The user just attempted authentication and was rejected, resulting in a timed lockout. - * 2) The framework just created a session for a (sensorId, userId) pair that has not been - * created since the HAL started (e.g. there is no active or idle session for this - * (sensorId, userId) pair. - * - * @param sensorId Sensor for which the user is locked out. - * @param userId User for which the sensor is locked out. - * @param durationMillis Remaining duration of the lockout. - */ - void onLockoutTimed(in int sensorId, in int userId, in long durationMillis); - - /** - * Notifies the framework that the user has just entered the Error::LOCKOUT_PERMANENT state. - * This must be sent in the following scenarios: - * 1) The user just attempted authentication and was rejected, resulting in a permanent lockout. - * 2) The framework just created a session for a (sensorId, userId) pair that has not been - * created since the HAL started (e.g. there is no active or idle session for this - * (sensorId, userId) pair. - * - * @param sensorId Sensor for which the user is locked out. - * @param userId User for which the sensor is locked out. - */ - void onLockoutPermanent(in int sensorId, in int userId); - - /** - * Notifies the framework that lockout has been cleared for this (sensorId, userId) pair. This - * can happen in the following scenarios: - * 1) A timed lockout has ended (e.g. original durationMillis specified in #onLockoutTimed - * has expired. - * 2) See ISession#resetLockout. - * 3) The (sensorId, userId) pair is not in any lockout state, and the user successfully - * authenticated with a fingerprint. - * - * @param sensorId Sensor for which the user's lockout is cleared. - * @param userId User for the sensor's lockout is cleared. - */ - void onLockoutCleared(in int sensorId, in int userId); -} - diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl index 946027b5f1..d0f546a41f 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl @@ -95,55 +95,46 @@ interface ISession { * * A request to start looking for fingerprints to authenticate. * - * Once the HAL is able to start processing the authentication request, it must - * notify framework via ISessionCallback#onStateChanged with - * SessionState::AUTHENTICATING. + * Once the HAL is able to start processing the authentication request, it must notify framework + * via ISessionCallback#onStateChanged with SessionState::AUTHENTICATING. * - * At any point during authentication, if a non-recoverable error occurs, - * the HAL must notify the framework via ISessionCallback#onError with - * the applicable authentication-specific error, and then send - * ISessionCallback#onStateChanged(cookie, SessionState::IDLING) if no + * At any point during authentication, if a non-recoverable error occurs, the HAL must notify + * the framework via ISessionCallback#onError with the applicable authentication-specific error, + * and then send ISessionCallback#onStateChanged(cookie, SessionState::IDLING) if no * subsequent operation is in the queue. * - * During authentication, the implementation may notify the framework - * via ISessionCallback#onAcquired with messages that may be used to guide - * the user. This callback can be invoked multiple times if necessary. + * During authentication, the implementation may notify the framework via + * ISessionCallback#onAcquired with messages that may be used to guide the user. This callback + * can be invoked multiple times if necessary. * - * The HAL must notify the framework of accepts/rejects via - * ISessionCallback#onAuthentication*. + * The HAL must notify the framework of accepts/rejects via ISessionCallback#onAuthentication*. * * The authentication lifecycle ends when either - * 1) A fingerprint is accepted, and ISessionCallback#onAuthenticationSucceeded - * is invoked, or - * 2) Any non-recoverable error occurs (such as lockout). See the full - * list of authentication-specific errors in the Error enum. - * - * Note that it is now the HAL's responsibility to keep track of lockout - * states. See IFingerprint#setLockoutCallback and ISession#resetLockout. - * - * Note that upon successful authentication, ONLY sensors configured as - * SensorStrength::STRONG are allowed to create and send a - * HardwareAuthToken to the framework. See the Android CDD for more - * details. For SensorStrength::STRONG sensors, the HardwareAuthToken's - * "challenge" field must be set with the operationId passed in during - * #authenticate. If the sensor is NOT SensorStrength::STRONG, the - * HardwareAuthToken MUST be null. - * - * @param cookie An identifier used to track subsystem operations related - * to this call path. The client must guarantee that it is - * unique per ISession. - * @param operationId For sensors configured as SensorStrength::STRONG, - * this must be used ONLY upon successful authentication - * and wrapped in the HardwareAuthToken's "challenge" - * field and sent to the framework via - * ISessionCallback#onAuthenticated. The operationId is - * an opaque identifier created from a separate secure - * subsystem such as, but not limited to KeyStore/KeyMaster. - * The HardwareAuthToken can then be used as an attestation - * for the provided operation. For example, this is used + * 1) A fingerprint is accepted, and ISessionCallback#onAuthenticationSucceeded is invoked, or + * 2) Any non-recoverable error occurs (such as lockout). See the full list of + * authentication-specific errors in the Error enum. + * + * Note that upon successful authentication, the lockout counter for this (sensorId, userId) + * pair must be cleared. + * + * Note that upon successful authentication, ONLY sensors configured as SensorStrength::STRONG + * are allowed to create and send a HardwareAuthToken to the framework. See the Android CDD for + * more details. For SensorStrength::STRONG sensors, the HardwareAuthToken's "challenge" field + * must be set with the operationId passed in during #authenticate. If the sensor is NOT + * SensorStrength::STRONG, the HardwareAuthToken MUST be null. + * + * @param cookie An identifier used to track subsystem operations related to this call path. The + * client must guarantee that it is unique per ISession. + * @param operationId For sensors configured as SensorStrength::STRONG, this must be used ONLY + * upon successful authentication and wrapped in the HardwareAuthToken's + * "challenge" field and sent to the framework via + * ISessionCallback#onAuthenticated. The operationId is an opaque identifier + * created from a separate secure subsystem such as, but not limited to + * KeyStore/KeyMaster. The HardwareAuthToken can then be used as an + * attestation for the provided operation. For example, this is used * to unlock biometric-bound auth-per-use keys (see - * setUserAuthenticationParameters in - * KeyGenParameterSpec.Builder and KeyProtection.Builder. + * setUserAuthenticationParameters in KeyGenParameterSpec.Builder and + * KeyProtection.Builder. */ ICancellationSignal authenticate(in int cookie, in long operationId); @@ -300,17 +291,43 @@ interface ISession { /** * resetLockout: * - * Requests the implementation to clear the lockout counter. Upon receiving - * this request, the implementation must perform the following: + * Requests the implementation to clear the lockout counter. Upon receiving this request, the + * implementation must perform the following: * 1) Verify the authenticity and integrity of the provided HAT - * 2) Verify that the timestamp provided within the HAT is relatively - * recent (e.g. on the order of minutes, not hours). - * If either of the checks fail, the HAL must invoke ISessionCallback#onError - * with Error::UNABLE_TO_PROCESS and return to SessionState::IDLING - * if no subsequent work is in the queue. - * - * Upon successful verification, the HAL must clear the lockout counter - * and notify the framework via ILockoutCallback#onLockoutChanged(sensorId, userId, 0). + * 2) Verify that the timestamp provided within the HAT is relatively recent (e.g. on the + * order of minutes, not hours). + * If either of the checks fail, the HAL must invoke ISessionCallback#onError with + * Error::UNABLE_TO_PROCESS and return to SessionState::IDLING if no subsequent work is in the + * queue. + * + * Upon successful verification, the HAL must clear the lockout counter and notify the framework + * via ISessionCallback#onLockoutCleared. + * + * Note that lockout is user AND sensor specific. In other words, there is a separate lockout + * state for each (user, sensor) pair. For example, the following is a valid state on a + * multi-sensor device: + * ------------------------------------------------------------------ + * | SensorId | UserId | FailedAttempts | LockedOut | LockedUntil | + * |----------|--------|----------------|-----------|---------------| + * | 0 | 0 | 1 | false | x | + * | 1 | 0 | 5 | true | | + * | 0 | 10 | 0 | false | x | + * | 1 | 10 | 0 | false | x | + * ------------------------------------------------------------------ + * + * Lockout may be cleared in the following ways: + * 1) ISession#resetLockout + * 2) After a period of time, according to a rate-limiter. + * + * Note that the "FailedAttempts" counter must be cleared upon successful fingerprint + * authentication. For example, if SensorId=0 UserId=0 FailedAttempts=1, and a successful + * fingerprint authentication occurs, the counter for that (SensorId, UserId) pair must be reset + * to 0. + * + * In addition, lockout states MUST persist after device reboots, HAL crashes, etc. + * + * See the Android CDD section 7.3.10 for the full set of lockout and rate-limiting + * requirements. * * @param cookie An identifier used to track subsystem operations related * to this call path. The client must guarantee that it is @@ -319,7 +336,6 @@ interface ISession { */ void resetLockout(in int cookie, in HardwareAuthToken hat); - /** * Methods for notifying the under-display fingerprint sensor about external events. */ diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl index 81a87a8290..33a93e59b4 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl @@ -76,9 +76,8 @@ interface ISessionCallback { * This method must only be used to notify the framework during SessionState::AUTHENTICATING. * * Used to notify the framework upon successful authentication. Note that the authentication - * lifecycle ends when either 1) a fingerprint is accepted, or 2) an error such as - * Error::LOCKOUT occurred. The authentication lifecycle does NOT end when a fingerprint is - * rejected. + * lifecycle ends when either 1) a fingerprint is accepted, or 2) an error occurred. The + * authentication lifecycle does NOT end when a fingerprint is rejected. * * @param enrollmentId Fingerprint that was accepted. * @param hat If the sensor is configured as SensorStrength::STRONG, a non-null attestation that @@ -92,12 +91,50 @@ interface ISessionCallback { * This method must only be used to notify the framework during SessionState::AUTHENTICATING. * * Used to notify the framework upon rejected attempts. Note that the authentication - * lifecycle ends when either 1) a fingerprint is accepted, or 2) an error such as - * Error::LOCKOUT occurred. The authentication lifecycle does NOT end when a fingerprint is - * rejected. + * lifecycle ends when either 1) a fingerprint is accepted, or 2) an occurred. The + * authentication lifecycle does NOT end when a fingerprint is rejected. */ void onAuthenticationFailed(); + /** + * This method must only be used to notify the framework during SessionState::AUTHENTICATING. + * + * Authentication is locked out due to too many unsuccessful attempts. This is a rate-limiting + * lockout, and authentication can be restarted after a period of time. See + * ISession#resetLockout. + * + * @param sensorId Sensor for which the user is locked out. + * @param userId User for which the sensor is locked out. + * @param durationMillis Remaining duration of the lockout. + */ + void onLockoutTimed(in long durationMillis); + + /** + * This method must only be used to notify the framework during SessionState::AUTHENTICATING. + * + * Authentication is disabled until the user unlocks with their device credential + * (PIN/Pattern/Password). See ISession#resetLockout. + * + * @param sensorId Sensor for which the user is locked out. + * @param userId User for which the sensor is locked out. + */ + void onLockoutPermanent(); + + /** + * Notifies the framework that lockout has been cleared for this (sensorId, userId) pair. + * + * Note that this method can be used to notify the framework during any state. + * + * Lockout can be cleared in the following scenarios: + * 1) A timed lockout has ended (e.g. durationMillis specified in previous #onLockoutTimed + * has expired. + * 2) See ISession#resetLockout. + * + * @param sensorId Sensor for which the user's lockout is cleared. + * @param userId User for the sensor's lockout is cleared. + */ + void onLockoutCleared(); + /** * This method must only be used to notify the framework during * SessionState::DETECTING_INTERACTION diff --git a/biometrics/fingerprint/aidl/default/Fingerprint.cpp b/biometrics/fingerprint/aidl/default/Fingerprint.cpp index b3bd4e7a29..b907bf1d31 100644 --- a/biometrics/fingerprint/aidl/default/Fingerprint.cpp +++ b/biometrics/fingerprint/aidl/default/Fingerprint.cpp @@ -61,11 +61,6 @@ ndk::ScopedAStatus Fingerprint::createSession(int32_t /*sensorId*/, int32_t /*us return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Fingerprint::setLockoutCallback( - const std::shared_ptr& /*cb*/) { - return ndk::ScopedAStatus::ok(); -} - ndk::ScopedAStatus Fingerprint::generateChallenge( int32_t /*sensorId*/, int32_t /*userId*/, int32_t /*timeoutSec*/, const std::shared_ptr& /*cb*/) { diff --git a/biometrics/fingerprint/aidl/default/Fingerprint.h b/biometrics/fingerprint/aidl/default/Fingerprint.h index 463d07db13..59cdd441fc 100644 --- a/biometrics/fingerprint/aidl/default/Fingerprint.h +++ b/biometrics/fingerprint/aidl/default/Fingerprint.h @@ -28,9 +28,6 @@ class Fingerprint : public BnFingerprint { const std::shared_ptr& cb, std::shared_ptr* _aidl_return) override; - ndk::ScopedAStatus setLockoutCallback( - const std::shared_ptr& cb) override; - ndk::ScopedAStatus generateChallenge( int32_t sensorId, int32_t userId, int32_t timeoutSec, const std::shared_ptr& cb) override; diff --git a/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp b/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp index 30117862ee..496badc741 100644 --- a/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp +++ b/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp @@ -74,6 +74,18 @@ class SessionCallback : public BnSessionCallback { return ndk::ScopedAStatus::ok(); } + ndk::ScopedAStatus onLockoutTimed(int64_t /*durationMillis*/) override { + return ndk::ScopedAStatus::ok(); + } + + ndk::ScopedAStatus onLockoutPermanent() override { + return ndk::ScopedAStatus::ok(); + } + + ndk::ScopedAStatus onLockoutCleared() override { + return ndk::ScopedAStatus::ok(); + } + ndk::ScopedAStatus onInteractionDetected() override { return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus onEnrollmentsEnumerated( -- GitLab From ea8d801f54a37a94dce4280bdba14def140f6b36 Mon Sep 17 00:00:00 2001 From: Daniel Bright Date: Wed, 2 Sep 2020 17:07:20 -0700 Subject: [PATCH 168/790] Add Handover Failure Mode to Radio Hal On a handover request failure, the modem can now determine whether or not to fallback. There is also the option to revert to the legacy logic. Following the legacy logic is the default behavior. Test: FrameworkTelephonyTests Bug: 161572465 Change-Id: Iad778e83ffc264ee25f57f54ff58532d6a8c5cbf --- radio/1.6/types.hal | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/radio/1.6/types.hal b/radio/1.6/types.hal index fbcbe976e9..4bd3cd6f35 100644 --- a/radio/1.6/types.hal +++ b/radio/1.6/types.hal @@ -157,7 +157,7 @@ struct QosFilter { QosFilterDirection direction; /** - * Specified the order in which the filter needs to be matched. + * Specifies the order in which the filter needs to be matched. * A lower numerical(positive) value has a higher precedence. * Set -1 when unspecified. */ @@ -176,6 +176,30 @@ struct QosSession { vec qosFilters; }; +/** The allowed failure modes on an IWLAN handover failure. */ +enum HandoverFailureMode : int32_t { + /** + * On data handover failure, fallback to the source data transport when the + * fail cause is due to a hand off preference change. + */ + LEGACY = 0, + + /** On data handover failure, fallback to the source data transport. */ + DO_FALLBACK = 1, + + /** + * On data handover failure, retry the handover instead of falling back to + * the source data transport. + */ + NO_FALLBACK_RETRY_HANDOVER = 2, + + /** + * On data handover failure, setup a new data connection by sending a normal + * request to the underlying data service. + */ + NO_FALLBACK_RETRY_SETUP_NORMAL = 3 +}; + struct SetupDataCallResult { @1.5::SetupDataCallResult base; @@ -187,4 +211,7 @@ struct SetupDataCallResult { * PDNs that support dedicated bearers. */ vec qosSessions; + + /** Specifies the fallback mode on an IWLAN handover failure. */ + HandoverFailureMode handoverFailureMode; }; -- GitLab From 3388eebde55ae611dcd009db81b9ef462a3b77bc Mon Sep 17 00:00:00 2001 From: Kevin Chyn Date: Wed, 23 Sep 2020 14:29:26 -0700 Subject: [PATCH 169/790] Reformat biometric interface documentation to 100 cols Bug: 168843220 Test: Builds Change-Id: Ibf2baa14f8c8bd47250dd964eab68307e3885b4c --- .../biometrics/common/CommonProps.aidl | 17 +- .../biometrics/common/SensorStrength.aidl | 15 +- .../biometrics/fingerprint/IFingerprint.aidl | 83 ++++------ .../biometrics/fingerprint/ISession.aidl | 156 ++++++++---------- .../biometrics/fingerprint/SensorProps.aidl | 26 ++- 5 files changed, 129 insertions(+), 168 deletions(-) diff --git a/biometrics/common/aidl/android/hardware/biometrics/common/CommonProps.aidl b/biometrics/common/aidl/android/hardware/biometrics/common/CommonProps.aidl index 8304c953cc..9c3fd58090 100644 --- a/biometrics/common/aidl/android/hardware/biometrics/common/CommonProps.aidl +++ b/biometrics/common/aidl/android/hardware/biometrics/common/CommonProps.aidl @@ -22,29 +22,26 @@ import android.hardware.biometrics.common.SensorStrength; @VintfStability parcelable CommonProps { /** - * A statically configured unique ID that identifies a single biometric - * sensor. IDs must start at zero and increment by one for each unique - * sensor. Note that ID allocations are shared between all biometric - * modalities (e.g. fingerprint, face, iris), and a single ID must never + * A statically configured unique ID that identifies a single biometric sensor. IDs must start + * at zero and increment by one for each unique sensor. Note that ID allocations are shared + * between all biometric modalities (e.g. fingerprint, face, iris), and a single ID must never * be claimed by more than a single sensor. */ int sensorId; /** - * A statically configured strength for this sensor. See the SensorStrength - * interface for more information. + * A statically configured strength for this sensor. See the SensorStrength interface for more + * information. */ SensorStrength sensorStrength; /** - * The maximum number of enrollments that a single user can have. - * Statically configured. + * The maximum number of enrollments that a single user can have. Statically configured. */ int maxEnrollmentsPerUser; /** - * A list of hardware information for subsystems that pertain to this - * biometric sensor. + * A list of hardware information for subsystems that pertain to this biometric sensor. */ HardwareInfo[] hardwareInfo; } \ No newline at end of file diff --git a/biometrics/common/aidl/android/hardware/biometrics/common/SensorStrength.aidl b/biometrics/common/aidl/android/hardware/biometrics/common/SensorStrength.aidl index 7460279728..790691cbfc 100644 --- a/biometrics/common/aidl/android/hardware/biometrics/common/SensorStrength.aidl +++ b/biometrics/common/aidl/android/hardware/biometrics/common/SensorStrength.aidl @@ -20,22 +20,21 @@ package android.hardware.biometrics.common; @Backing(type="byte") enum SensorStrength { /** - * A sensor that meets the requirements for Class 1 biometrics as defined - * in the CDD. This does not correspond to a public BiometricManager.Authenticators - * constant. Sensors of this strength are not available to applications ia the - * public API surface. + * A sensor that meets the requirements for Class 1 biometrics as defined in the CDD. This does + * not correspond to a public BiometricManager.Authenticators constant. Sensors of this strength + * are not available to applications via the public API surface. */ CONVENIENCE, /** - * A sensor that meets the requirements for Class 2 biometrics as defined - * in the CDD. Corresponds to BiometricManager.Authenticators.BIOMETRIC_WEAK. + * A sensor that meets the requirements for Class 2 biometrics as defined in the CDD. + * Corresponds to BiometricManager.Authenticators.BIOMETRIC_WEAK. */ WEAK, /** - * A sensor that meets the requirements for Class 3 biometrics as defined - * in the CDD. Corresponds to BiometricManager.Authenticators.BIOMETRIC_STRONG. + * A sensor that meets the requirements for Class 3 biometrics as defined in the CDD. + * Corresponds to BiometricManager.Authenticators.BIOMETRIC_STRONG. * * Notably, this is the only strength that allows generation/verification of * HardwareAuthToken(s). diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl index 0c8ebc534b..4b907b46b5 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl @@ -27,41 +27,34 @@ interface IFingerprint { /** * getSensorProps: * - * @return A list of properties for all sensors that an instance of the - * HAL supports. + * @return A list of properties for all sensors that an instance of the HAL supports. */ SensorProps[] getSensorProps(); /** * createSession: * - * Creates a session which can then be used by the framework to perform - * operations such as enroll, authenticate, etc for the given sensorId - * and userId. + * Creates a session which can then be used by the framework to perform operations such as + * enroll, authenticate, etc for the given sensorId and userId. * - * A physical sensor identified by sensorId typically supports only a - * single in-flight session at a time. As such, if a session is currently - * in a state other than SessionState::IDLING, the HAL MUST finish or - * cancel the current operation and return to SessionState::IDLING before - * the new session is created. For example: - * 1) If a session for sensorId=0, userId=0 - * is currently in a cancellable state (see ICancellationSignal) such - * as SessionState::AUTHENTICATING and the framework requests a new - * session for sensorId=0, userId=10, the HAL must end the current - * session with Error::CANCELED, invoke - * ISessionCallback#onStateChanged with SessionState::IDLING, and + * A physical sensor identified by sensorId typically supports only a single in-flight session + * at a time. As such, if a session is currently in a state other than SessionState::IDLING, the + * HAL MUST finish or cancel the current operation and return to SessionState::IDLING before the + * new session is created. For example: + * 1) If a session for sensorId=0, userId=0 is currently in a cancellable state (see + * ICancellationSignal) such as SessionState::AUTHENTICATING and the framework requests a + * new session for sensorId=0, userId=10, the HAL must end the current session with + * Error::CANCELED, invoke ISessionCallback#onStateChanged with SessionState::IDLING, and * then return a new session for sensorId=0, userId=10. - * 2) If a session for sensorId=0, userId=0 is currently in a - * non-cancellable state such as SessionState::REMOVING_ENROLLMENTS, - * and the framework requests a new session for sensorId=0, userId=10, - * the HAL must finish the current operation before invoking - * ISessionCallback#onStateChanged with SessionState::IDLING, and - * return a new session for sensorId=0, userId=10. + * 2) If a session for sensorId=0, userId=0 is currently in a non-cancellable state such as + * SessionState::REMOVING_ENROLLMENTS, and the framework requests a new session for + * sensorId=0, userId=10, the HAL must finish the current operation before invoking + * ISessionCallback#onStateChanged with SessionState::IDLING, and return a new session for + * sensorId=0, userId=10. * - * Implementations must store user-specific state or metadata in - * /data/vendor_de//fpdata as specified by the SeLinux policy. This - * directory is created/removed by vold (see vold_prepare_subdirs.cpp). - * Implementations may store additional user-specific data, such as + * Implementations must store user-specific state or metadata in /data/vendor_de//fpdata + * as specified by the SeLinux policy. This directory is created/removed by vold (see + * vold_prepare_subdirs.cpp). Implementations may store additional user-specific data, such as * embeddings or templates in StrongBox. * * @param sensorId The sensor with which this session is being created. @@ -74,33 +67,29 @@ interface IFingerprint { /** * generateChallenge: * - * Begins a secure transaction request. Note that the challenge by itself - * is not useful. It only becomes useful when wrapped in a verifiable - * message such as a HardwareAuthToken. + * Begins a secure transaction request. Note that the challenge by itself is not useful. It only + * becomes useful when wrapped in a verifiable message such as a HardwareAuthToken. * * Canonical example: * 1) User requests an operation, such as fingerprint enrollment. - * 2) Fingerprint enrollment cannot happen until the user confirms - * their lockscreen credential (PIN/Pattern/Password). - * 3) However, the biometric subsystem does not want just "any" - * proof of credential confirmation. It needs proof that the - * user explicitly authenticated credential in order to allow - * addition of biometric enrollments. + * 2) Fingerprint enrollment cannot happen until the user confirms their lockscreen credential + * (PIN/Pattern/Password). + * 3) However, the biometric subsystem does not want just "any" proof of credential + * confirmation. It needs proof that the user explicitly authenticated credential in order + * to allow addition of biometric enrollments. * To secure this path, the following path is taken: * 1) Upon user requesting fingerprint enroll, the framework requests * IFingerprint#generateChallenge - * 2) Framework sends the challenge to the credential subsystem, and upon - * credential confirmation, a HAT is created, containing the challenge - * in the "challenge" field. + * 2) Framework sends the challenge to the credential subsystem, and upon credential + * confirmation, a HAT is created, containing the challenge in the "challenge" field. * 3) Framework sends the HAT to the HAL, e.g. ISession#enroll. * 4) Implementation verifies the authenticity and integrity of the HAT. - * 5) Implementation now has confidence that the user entered their - * credential to allow biometric enrollment. + * 5) Implementation now has confidence that the user entered their credential to allow + * biometric enrollment. * - * Note that the interface allows multiple in-flight challenges. For - * example, invoking generateChallenge(0, 0, timeoutSec, cb) twice - * does not invalidate the first challenge. The challenge is invalidated - * only when: + * Note that the interface allows multiple in-flight challenges. For example, invoking + * generateChallenge(0, 0, timeoutSec, cb) twice does not invalidate the first challenge. The + * challenge is invalidated only when: * 1) The provided timeout expires, or * 2) IFingerprint#revokeChallenge is invoked * @@ -124,9 +113,9 @@ interface IFingerprint { /** * revokeChallenge: * - * Revokes a challenge that was previously generated. Note that if an - * invalid combination of parameters is requested, the implementation - * must still notify the framework using the provided callback. + * Revokes a challenge that was previously generated. Note that if an invalid combination of + * parameters is requested, the implementation must still notify the framework using the + * provided callback. * * @param sensorId Sensor that the revocation should apply to. * @param userId User that the revocation should apply to. diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl index d0f546a41f..644e214c42 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl @@ -51,41 +51,35 @@ interface ISession { * * A request to add a fingerprint enrollment. * - * Once the HAL is able to start processing the enrollment request, it must - * notify the framework via ISessionCallback#onStateChanged with - * SessionState::ENROLLING. - * - * At any point during enrollment, if a non-recoverable error occurs, - * the HAL must notify the framework via ISessionCallback#onError with - * the applicable enrollment-specific error, and then send - * ISessionCallback#onStateChanged(cookie, SessionState::IDLING) if no - * subsequent operation is in the queue. + * Once the HAL is able to start processing the enrollment request, it must notify the framework + * via ISessionCallback#onStateChanged with SessionState::ENROLLING. + * + * At any point during enrollment, if a non-recoverable error occurs, the HAL must notify the + * framework via ISessionCallback#onError with the applicable enrollment-specific error, and + * then send ISessionCallback#onStateChanged(cookie, SessionState::IDLING) if no subsequent + * operation is in the queue. + * + * Before capturing fingerprint data, the implementation must first verify the authenticity and + * integrity of the provided HardwareAuthToken. In addition, it must check that the challenge + * within the provided HardwareAuthToken is valid. See IFingerprint#generateChallenge. If any of + * the above checks fail, the framework must be notified via ISessionCallback#onError and the + * HAL must notify the framework when it returns to the idle state. See + * Error::UNABLE_TO_PROCESS. + * + * During enrollment, the implementation may notify the framework via + * ISessionCallback#onAcquired with messages that may be used to guide the user. This callback + * can be invoked multiple times if necessary. Similarly, the framework may be notified of + * enrollment progress changes via ISessionCallback#onEnrollmentProgress. Once the framework is + * notified that there are 0 "remaining" steps, the framework may cache the "enrollmentId". See + * ISessionCallback#onEnrollmentProgress for more info. The HAL must notify the framework once + * it returns to the idle state. * - * Before capturing fingerprint data, the implementation must first - * verify the authenticity and integrity of the provided HardwareAuthToken. - * In addition, it must check that the challenge within the provided - * HardwareAuthToken is valid. See IFingerprint#generateChallenge. - * If any of the above checks fail, the framework must be notified - * via ISessionCallback#onError and the HAL must notify the framework when - * it returns to the idle state. See Error::UNABLE_TO_PROCESS. - * - * During enrollment, the implementation may notify the framework - * via ISessionCallback#onAcquired with messages that may be used to guide - * the user. This callback can be invoked multiple times if necessary. - * Similarly, the framework may be notified of enrollment progress changes - * via ISessionCallback#onEnrollmentProgress. Once the framework is notified - * that there are 0 "remaining" steps, the framework may cache the - * "enrollmentId". See ISessionCallback#onEnrollmentProgress for more info. - * The HAL must notify the framework once it returns to the idle state. - * - * When a finger is successfully added and before the framework is notified - * of remaining=0, the implementation MUST update and associate this - * (sensorId, userId) pair with a new new entropy-encoded random identifier. - * See ISession#getAuthenticatorId for more information. - * - * @param cookie An identifier used to track subsystem operations related - * to this call path. The client must guarantee that it is - * unique per ISession. + * When a finger is successfully added and before the framework is notified of remaining=0, the + * implementation MUST update and associate this (sensorId, userId) pair with a new new + * entropy-encoded random identifier. See ISession#getAuthenticatorId for more information. + * + * @param cookie An identifier used to track subsystem operations related to this call path. The + * client must guarantee that it is unique per ISession. * @param hat See above documentation. */ ICancellationSignal enroll(in int cookie, in HardwareAuthToken hat); @@ -212,79 +206,66 @@ interface ISession { /** * getAuthenticatorId: * - * MUST return 0 via ISessionCallback#onAuthenticatorIdRetrieved for - * sensors that are configured as SensorStrength::WEAK or - * SensorStrength::CONVENIENCE. + * MUST return 0 via ISessionCallback#onAuthenticatorIdRetrieved for sensors that are configured + * as SensorStrength::WEAK or SensorStrength::CONVENIENCE. * - * The following only applies to sensors that are configured as - * SensorStrength::STRONG. + * The following only applies to sensors that are configured as SensorStrength::STRONG. * - * The authenticatorId is a (sensorId, user)-specific identifier which - * can be used during key generation and key import to to associate a - * key (in KeyStore / KeyMaster) with the current set of enrolled - * fingerprints. For example, the following public Android APIs - * allow for keys to be invalidated when the user adds a new enrollment - * after the key was created: + * The authenticatorId is a (sensorId, user)-specific identifier which can be used during key + * generation and key import to to associate a key (in KeyStore / KeyMaster) with the current + * set of enrolled fingerprints. For example, the following public Android APIs allow for keys + * to be invalidated when the user adds a new enrollment after the key was created: * KeyGenParameterSpec.Builder.setInvalidatedByBiometricEnrollment and * KeyProtection.Builder.setInvalidatedByBiometricEnrollment. * - * In addition, upon successful fingerprint authentication, the signed HAT - * that is returned to the framework via ISessionCallback#onAuthenticated - * must contain this identifier in the authenticatorId field. + * In addition, upon successful fingerprint authentication, the signed HAT that is returned to + * the framework via ISessionCallback#onAuthenticated must contain this identifier in the + * authenticatorId field. * - * Returns an entropy-encoded random identifier associated with the current - * set of enrollments via ISessionCallback#onAuthenticatorIdRetrieved. The - * authenticatorId + * Returns an entropy-encoded random identifier associated with the current set of enrollments + * via ISessionCallback#onAuthenticatorIdRetrieved. The authenticatorId * 1) MUST change whenever a new fingerprint is enrolled * 2) MUST return 0 if no fingerprints are enrolled * 3) MUST not change if a fingerprint is deleted. * 4) MUST be an entropy-encoded random number * - * @param cookie An identifier used to track subsystem operations related - * to this call path. The client must guarantee that it is - * unique per ISession. + * @param cookie An identifier used to track subsystem operations related to this call path. The + * client must guarantee that it is unique per ISession. */ void getAuthenticatorId(in int cookie); /** * invalidateAuthenticatorId: * - * This method only applies to sensors that are configured as - * SensorStrength::STRONG. If invoked erroneously by the framework for - * sensor of other strengths, the HAL should immediately invoke + * This method only applies to sensors that are configured as SensorStrength::STRONG. If invoked + * by the framework for sensor of other strengths, the HAL should immediately invoke * ISessionCallback#onAuthenticatorIdInvalidated. * - * The following only applies to sensors that are configured as - * SensorStrength::STRONG. + * The following only applies to sensors that are configured as SensorStrength::STRONG. * - * When invoked by the framework, the implementation must perform the - * following sequence of events: - * 1) Verify the authenticity and integrity of the provided HAT. If this - * check fails, the HAL must invoke ISessionCallback#onError with - * Error::UNABLE_TO_PROCESS and return to + * When invoked by the framework, the implementation must perform the following sequence of + * events: + * 1) Verify the authenticity and integrity of the provided HAT. If this check fails, the HAL + * must invoke ISessionCallback#onError with Error::UNABLE_TO_PROCESS and return to + * SessionState::IDLING if no subsequent work is in the queue. + * 2) Verify that the timestamp provided within the HAT is relatively recent (e.g. on the + * order of minutes, not hours). If this check fails, the HAL must invoke + * ISessionCallback#onError with Error::UNABLE_TO_PROCESS and return to * SessionState::IDLING if no subsequent work is in the queue. - * 2) Verify that the timestamp provided within the HAT is relatively - * recent (e.g. on the order of minutes, not hours). If this check fails, - * the HAL must invoke ISessionCallback#onError with - * Error::UNABLE_TO_PROCESS and return to SessionState::IDLING - * if no subsequent work is in the queue. * 3) Update the authenticatorId with a new entropy-encoded random number * 4) Persist the new authenticatorId to non-ephemeral storage * 5) Notify the framework that the above is completed, via * ISessionCallback#onAuthenticatorInvalidated * - * A practical use case of invalidation would be when the user adds a new - * enrollment to a sensor managed by a different HAL instance. The - * public android.security.keystore APIs bind keys to "all biometrics" - * rather than "fingerprint-only" or "face-only" (see #getAuthenticatorId - * for more details). As such, the framework would coordinate invalidation - * across multiple biometric HALs as necessary. - * - * @param cookie An identifier used to track subsystem operations related - * to this call path. The client must guarantee that it is - * unique per ISession. - * @param hat HardwareAuthToken that must be validated before proceeding - * with this operation. + * A practical use case of invalidation would be when the user adds a new enrollment to a sensor + * managed by a different HAL instance. The public android.security.keystore APIs bind keys to + * "all biometrics" rather than "fingerprint-only" or "face-only" (see #getAuthenticatorId + * for more details). As such, the framework would coordinate invalidation across multiple + * biometric HALs as necessary. + * + * @param cookie An identifier used to track subsystem operations related to this call path. The + * client must guarantee that it is unique per ISession. + * @param hat HardwareAuthToken that must be validated before proceeding with this operation. */ void invalidateAuthenticatorId(in int cookie, in HardwareAuthToken hat); @@ -329,9 +310,8 @@ interface ISession { * See the Android CDD section 7.3.10 for the full set of lockout and rate-limiting * requirements. * - * @param cookie An identifier used to track subsystem operations related - * to this call path. The client must guarantee that it is - * unique per ISession. + * @param cookie An identifier used to track subsystem operations related to this call path. The + * client must guarantee that it is unique per ISession. * @param hat HardwareAuthToken See above documentation. */ void resetLockout(in int cookie, in HardwareAuthToken hat); @@ -352,12 +332,12 @@ interface ISession { * following states: SessionState::ENROLLING, SessionState::AUTHENTICATING, or * SessionState::DETECTING_INTERACTION. * - * Note that the framework will only invoke this method if the event occurred on the display - * on which this sensor is located. + * Note that the framework will only invoke this method if the event occurred on the display on + * which this sensor is located. * * Note that for sensors which require illumination such as - * FingerprintSensorType::UNDER_DISPLAY_OPTICAL, and where illumination is handled below - * the framework, this is a good time to start illuminating. + * FingerprintSensorType::UNDER_DISPLAY_OPTICAL, and where illumination is handled below the + * framework, this is a good time to start illuminating. * * @param pointerId See android.view.MotionEvent#getPointerId * @param x The distance in pixels from the left edge of the display. diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl index fc3b44d608..ab70a5801c 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl @@ -27,8 +27,7 @@ parcelable SensorProps { CommonProps commonProps; /** - * A statically configured sensor type representing this fingerprint - * sensor. + * A statically configured sensor type representing this fingerprint sensor. */ FingerprintSensorType sensorType; @@ -39,32 +38,29 @@ parcelable SensorProps { boolean supportsNavigationGestures; /** - * The location of the center of the sensor if applicable. For example, - * sensors of FingerprintSensorType::UNDER_DISPLAY_* would report this - * value as the distance in pixels, measured from the left edge of the - * screen. + * The location of the center of the sensor if applicable. For example, sensors of + * FingerprintSensorType::UNDER_DISPLAY_* would report this value as the distance in pixels, + * measured from the left edge of the screen. */ int sensorLocationX; /** - * The location of the center of the sensor if applicable. For example, - * sensors of FingerprintSensorType::UNDER_DISPLAY_* would report this - * value as the distance in pixels, measured from the top edge of the - * screen. + * The location of the center of the sensor if applicable. For example, sensors of + * FingerprintSensorType::UNDER_DISPLAY_* would report this value as the distance in pixels, + * measured from the top edge of the screen. */ int sensorLocationY; /** * The radius of the sensor if applicable. For example, sensors of - * FingerprintSensorType::UNDER_DISPLAY_* would report this value as - * the radius of the sensor, in pixels. + * FingerprintSensorType::UNDER_DISPLAY_* would report this value as the radius of the sensor, + * in pixels. */ int sensorRadius; /** - * For sensors of FingerprintSensorType::UNDER_DISPLAY_*, this must - * correspond to the android.hardware.DisplayManager#getDisplay Android - * API. + * For sensors of FingerprintSensorType::UNDER_DISPLAY_*, this must correspond to the + * android.hardware.DisplayManager#getDisplay Android API. */ int displayId; } -- GitLab From 749799387e64b44cfa7e5930a8e6cf5e8c99c079 Mon Sep 17 00:00:00 2001 From: Kevin Chyn Date: Wed, 23 Sep 2020 14:11:39 -0700 Subject: [PATCH 170/790] Tweaks to fingerprint AIDL 1) Explicit numbering for Error enum, which contains intentionally skipped entries for backwards compatibility 2) Documentation for vendorCode. The vendorCodes must have a well defined behavior with the array API for things like GSI to work, e.g. generic system image with non-generic HAL implementation - with this explicit requirement, both components, as long as the contract is followed, would allow proper string feedback to be loaded/shown. Bug: 168843220 Test: Builds Change-Id: Ie78e42b926351a03162a4a6e40f3325641c34609 --- .../android/hardware/biometrics/fingerprint/Error.aidl | 10 +++++----- .../biometrics/fingerprint/ISessionCallback.aidl | 10 ++++++++-- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/Error.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/Error.aidl index 014a4c032a..4fe7f5f573 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/Error.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/Error.aidl @@ -34,28 +34,28 @@ enum Error { * The implementation is unable to process the request. For example, invalid arguments were * supplied. */ - UNABLE_TO_PROCESS, + UNABLE_TO_PROCESS = 2, /** * The current operation took too long to complete. */ - TIMEOUT, + TIMEOUT = 3, /** * No space available to store additional enrollments. */ - NO_SPACE, + NO_SPACE = 4, /** * The operation was canceled. See common::ICancellationSignal. */ - CANCELED, + CANCELED = 5, /** * The implementation was unable to remove an enrollment. * See ISession#removeEnrollments. */ - UNABLE_TO_REMOVE, + UNABLE_TO_REMOVE = 6, /** * Reserved to maintain backwards compatibility. See ISessionCallback#onLockoutTimed instead. diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl index 33a93e59b4..74792d8d4e 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl @@ -38,7 +38,10 @@ interface ISessionCallback { * operation. * * @param info See the AcquiredInfo enum. - * @param vendorCode Only valid if info == AcquiredInfo::VENDOR. + * @param vendorCode Only valid if info == AcquiredInfo::VENDOR. The vendorCode must be used to + * index into the configuration + * com.android.internal.R.array.fingerprint_acquired_vendor that's installed + * on the vendor partition. */ void onAcquired(in AcquiredInfo info, in int vendorCode); @@ -58,7 +61,10 @@ interface ISessionCallback { * an Error::CANCELED message. * * @param error See the Error enum. - * @param vendorCode Only valid if error == Error::VENDOR. + * @param vendorCode Only valid if error == Error::VENDOR. The vendorCode must be used to index + * into the configuration + * com.android.internal.R.fingerprint_error_vendor that's installed on the + * vendor partition. */ void onError(in Error error, in int vendorCode); -- GitLab From f00ab8b77b77fece0a9ff51def742728f5c95f1d Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Wed, 23 Sep 2020 22:04:28 +0000 Subject: [PATCH 171/790] Revert "wifi: remove wifi instance name string check" This reverts commit 1c50a59eae395bdd4c08b72a0edefbb83dbb194b. Reason for revert: This was not needed. Does not fix the issue at hand. Bug: 161951052 Merged-In: I872a1b3e87f17a43eb3c22c930e916c7e5e2d2a6 Change-Id: I872a1b3e87f17a43eb3c22c930e916c7e5e2d2a6 --- .../1.0/vts/functional/supplicant_hidl_test_utils.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp index da3996b80e..be6aad9583 100644 --- a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp +++ b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp @@ -52,6 +52,10 @@ namespace { // Helper function to initialize the driver and firmware to STA mode // using the vendor HAL HIDL interface. void initilializeDriverAndFirmware(const std::string& wifi_instance_name) { + // Skip if wifi instance is not set. + if (wifi_instance_name == "") { + return; + } if (getWifi(wifi_instance_name) != nullptr) { sp wifi_chip = getWifiChip(wifi_instance_name); ChipModeId mode_id; @@ -65,6 +69,10 @@ void initilializeDriverAndFirmware(const std::string& wifi_instance_name) { // Helper function to deinitialize the driver and firmware // using the vendor HAL HIDL interface. void deInitilializeDriverAndFirmware(const std::string& wifi_instance_name) { + // Skip if wifi instance is not set. + if (wifi_instance_name == "") { + return; + } if (getWifi(wifi_instance_name) != nullptr) { stopWifi(wifi_instance_name); } else { -- GitLab From 133389711dc9649d3e8390021f09802e5831a9c4 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Wed, 23 Sep 2020 15:18:52 -0700 Subject: [PATCH 172/790] supplicant(vts): Stop adding empty instance for vendor HAL We don't need to test supplicant in the presence of vendor HAL & without it. For a given device, this behavior is fixed. Bug: 161951052 Test: atest VtsHalWifiSupplicantV1_1TargetTest Merged-In: I71097c3afef1765ca514abf2c350c423e3999020 Change-Id: I71097c3afef1765ca514abf2c350c423e3999020 --- .../1.1/vts/functional/supplicant_hidl_test.cpp | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test.cpp b/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test.cpp index 3c4d06b107..8d7ea54b3c 100644 --- a/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test.cpp +++ b/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test.cpp @@ -33,6 +33,7 @@ using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatus; using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatusCode; using ::android::hardware::wifi::supplicant::V1_0::IfaceType; using ::android::hardware::wifi::supplicant::V1_1::ISupplicant; +using ::android::hardware::wifi::V1_0::IWifi; using ::android::sp; class SupplicantHidlTest : public SupplicantHidlTestBaseV1_1 { @@ -139,21 +140,12 @@ TEST_P(SupplicantHidlTest, RemoveP2pInterface) { */ TEST_P(SupplicantHidlTest, Terminate) { supplicant_->terminate(); } -static std::vector get_wifi_instances() { - std::vector instances = - android::hardware::getAllHalInstanceNames( - android::hardware::wifi::V1_0::IWifi::descriptor); - // Also test when wifi instance is not set. - instances.push_back(""); - - return instances; -} - GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantHidlTest); INSTANTIATE_TEST_CASE_P( PerInstance, SupplicantHidlTest, testing::Combine( - testing::ValuesIn(get_wifi_instances()), + testing::ValuesIn( + android::hardware::getAllHalInstanceNames(IWifi::descriptor)), testing::ValuesIn(android::hardware::getAllHalInstanceNames( android::hardware::wifi::supplicant::V1_1::ISupplicant:: descriptor))), -- GitLab From 274ea0a7c46101e716fadcc2c7579b98538ce247 Mon Sep 17 00:00:00 2001 From: Yu-Han Yang Date: Wed, 9 Sep 2020 17:25:02 -0700 Subject: [PATCH 173/790] Add GNSS AIDL interfaces (hardware/interfaces) Bug: 159467682 Test: atest VtsHalGnssTargetTest Change-Id: I75c5599f2e0698f833e2d36ac53d460f4f0c3bb4 --- .../compatibility_matrix.current.xml | 7 ++ gnss/aidl/Android.bp | 32 ++++++++ gnss/aidl/OWNERS | 4 + .../current/android/hardware/gnss/IGnss.aidl | 22 ++++++ .../android/hardware/gnss/IGnssPsds.aidl | 23 ++++++ .../hardware/gnss/IGnssPsdsCallback.aidl | 22 ++++++ .../android/hardware/gnss/PsdsType.aidl | 24 ++++++ gnss/aidl/android/hardware/gnss/IGnss.aidl | 33 ++++++++ .../aidl/android/hardware/gnss/IGnssPsds.aidl | 49 ++++++++++++ .../hardware/gnss/IGnssPsdsCallback.aidl | 37 +++++++++ gnss/aidl/android/hardware/gnss/PsdsType.aidl | 42 ++++++++++ gnss/aidl/default/Android.bp | 38 +++++++++ gnss/aidl/default/Gnss.cpp | 31 ++++++++ gnss/aidl/default/Gnss.h | 28 +++++++ gnss/aidl/default/GnssPsds.cpp | 43 +++++++++++ gnss/aidl/default/GnssPsds.h | 38 +++++++++ gnss/aidl/default/gnss-default.rc | 4 + gnss/aidl/default/gnss-default.xml | 9 +++ gnss/aidl/default/service.cpp | 35 +++++++++ gnss/aidl/vts/Android.bp | 31 ++++++++ gnss/aidl/vts/VtsHalGnssTargetTest.cpp | 77 +++++++++++++++++++ 21 files changed, 629 insertions(+) create mode 100644 gnss/aidl/Android.bp create mode 100644 gnss/aidl/OWNERS create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsds.aidl create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsdsCallback.aidl create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/PsdsType.aidl create mode 100644 gnss/aidl/android/hardware/gnss/IGnss.aidl create mode 100644 gnss/aidl/android/hardware/gnss/IGnssPsds.aidl create mode 100644 gnss/aidl/android/hardware/gnss/IGnssPsdsCallback.aidl create mode 100644 gnss/aidl/android/hardware/gnss/PsdsType.aidl create mode 100644 gnss/aidl/default/Android.bp create mode 100644 gnss/aidl/default/Gnss.cpp create mode 100644 gnss/aidl/default/Gnss.h create mode 100644 gnss/aidl/default/GnssPsds.cpp create mode 100644 gnss/aidl/default/GnssPsds.h create mode 100644 gnss/aidl/default/gnss-default.rc create mode 100644 gnss/aidl/default/gnss-default.xml create mode 100644 gnss/aidl/default/service.cpp create mode 100644 gnss/aidl/vts/Android.bp create mode 100644 gnss/aidl/vts/VtsHalGnssTargetTest.cpp diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index bb26bd3543..9400543e7f 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -220,6 +220,13 @@ default + + android.hardware.gnss + + IGnss + default + + android.hardware.graphics.allocator diff --git a/gnss/aidl/Android.bp b/gnss/aidl/Android.bp new file mode 100644 index 0000000000..c503190802 --- /dev/null +++ b/gnss/aidl/Android.bp @@ -0,0 +1,32 @@ +/* + * 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. + */ + +aidl_interface { + name: "android.hardware.gnss", + vendor_available: true, + srcs: ["android/hardware/gnss/*.aidl"], + stability: "vintf", + backend: { + java: { + platform_apis: true, + }, + ndk: { + vndk: { + enabled: true, + }, + }, + }, +} diff --git a/gnss/aidl/OWNERS b/gnss/aidl/OWNERS new file mode 100644 index 0000000000..b7b4a2e902 --- /dev/null +++ b/gnss/aidl/OWNERS @@ -0,0 +1,4 @@ +gomo@google.com +smalkos@google.com +wyattriley@google.com +yuhany@google.com 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 new file mode 100644 index 0000000000..33377ca906 --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl @@ -0,0 +1,22 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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 IGnss { + android.hardware.gnss.IGnssPsds getExtensionPsds(); +} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsds.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsds.aidl new file mode 100644 index 0000000000..352a694f0b --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsds.aidl @@ -0,0 +1,23 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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 IGnssPsds { + boolean injectPsdsData(in android.hardware.gnss.PsdsType psdsType, in byte[] psdsData); + boolean setCallback(in android.hardware.gnss.IGnssPsdsCallback callback); +} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsdsCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsdsCallback.aidl new file mode 100644 index 0000000000..8413d2cc77 --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsdsCallback.aidl @@ -0,0 +1,22 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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 IGnssPsdsCallback { + void downloadRequestCb(in android.hardware.gnss.PsdsType psdsType); +} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/PsdsType.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/PsdsType.aidl new file mode 100644 index 0000000000..9d1984e292 --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/PsdsType.aidl @@ -0,0 +1,24 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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; +@Backing(type="int") @VintfStability +enum PsdsType { + LONG_TERM = 1, + NORMAL = 2, + REALTIME = 3, +} diff --git a/gnss/aidl/android/hardware/gnss/IGnss.aidl b/gnss/aidl/android/hardware/gnss/IGnss.aidl new file mode 100644 index 0000000000..1da254c7ef --- /dev/null +++ b/gnss/aidl/android/hardware/gnss/IGnss.aidl @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.gnss; + +import android.hardware.gnss.IGnssPsds; + +/** + * Represents the standard GNSS (Global Navigation Satellite System) interface. + */ +@VintfStability +interface IGnss { + + /** + * This method returns the IGnssPsds interface. + * + * @return Handle to the IGnssPsds interface. + */ + IGnssPsds getExtensionPsds(); +} \ No newline at end of file diff --git a/gnss/aidl/android/hardware/gnss/IGnssPsds.aidl b/gnss/aidl/android/hardware/gnss/IGnssPsds.aidl new file mode 100644 index 0000000000..6f53d6faac --- /dev/null +++ b/gnss/aidl/android/hardware/gnss/IGnssPsds.aidl @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.gnss; + +import android.hardware.gnss.IGnssPsdsCallback; +import android.hardware.gnss.PsdsType; + +/** + * This interface is used by the GNSS HAL to request the framework to download Predicted Satellite + * Data Service data. + */ +@VintfStability +interface IGnssPsds { + + /** + * Inject the downloaded PSDS data into the GNSS receiver. + * + * @param psdsType Type of PSDS data. + * @param psdsData GNSS PSDS data. Framework must not parse the data since the data format is + * opaque to framework. + * + * @return True if the operation is successful. + */ + boolean injectPsdsData(in PsdsType psdsType, in byte[] psdsData); + + /** + * Opens the PSDS interface and provides the callback routines to the implementation of this + * interface. + * + * @param callback Handle to the IGnssPsdsCallback interface. + * + * @return True if the operation is successful. + */ + boolean setCallback(in IGnssPsdsCallback callback); +} \ No newline at end of file diff --git a/gnss/aidl/android/hardware/gnss/IGnssPsdsCallback.aidl b/gnss/aidl/android/hardware/gnss/IGnssPsdsCallback.aidl new file mode 100644 index 0000000000..72b693b4a3 --- /dev/null +++ b/gnss/aidl/android/hardware/gnss/IGnssPsdsCallback.aidl @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.gnss; + +import android.hardware.gnss.PsdsType; + +/** + * This interface is used by the GNSS HAL to request download data from Predicted Satellite Data + * Service (PSDS). + */ +@VintfStability +interface IGnssPsdsCallback { + + /** + * Callback to request the client to download PSDS data from one of the URLs defined in the + * framework specified by psdsType. The URLs must be specified via properties on the vendor + * partitions. E.g., LONGTERM_PSDS_SERVER_1, NORMAL_PSDS_SERVER, or REALTIME_PSDS_SERVER. The + * client must download PSDS data and inject it by calling injectPsdsData(). + * + * @param psdsType Type of PSDS data. + */ + void downloadRequestCb(in PsdsType psdsType); +} \ No newline at end of file diff --git a/gnss/aidl/android/hardware/gnss/PsdsType.aidl b/gnss/aidl/android/hardware/gnss/PsdsType.aidl new file mode 100644 index 0000000000..d4fec77ade --- /dev/null +++ b/gnss/aidl/android/hardware/gnss/PsdsType.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. + */ + +package android.hardware.gnss; + +/** The type of PSDS data. */ +@VintfStability +@Backing(type="int") +enum PsdsType { + + /** + * Long-Term type PSDS data, which lasts for many hours to several days and often provides + * satellite orbit and clock accuracy of 2 - 20 meters. + */ + LONG_TERM = 1, + + /** + * Normal type PSDS data, which is similar to broadcast ephemeris in longevity - lasting for + * hours and providings satellite orbit and clock accuracy of 1 - 2 meters. + */ + NORMAL = 2, + + /** + * Real-Time type PSDS data, which lasts for minutes and provides brief satellite status + * information such as temporary malfunction, but does not include satellite orbit or clock + * information. + */ + REALTIME = 3, +} diff --git a/gnss/aidl/default/Android.bp b/gnss/aidl/default/Android.bp new file mode 100644 index 0000000000..8c4ee405aa --- /dev/null +++ b/gnss/aidl/default/Android.bp @@ -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. + */ + +cc_binary { + name: "android.hardware.gnss-service.example", + relative_install_path: "hw", + init_rc: ["gnss-default.rc"], + vintf_fragments: ["gnss-default.xml"], + vendor: true, + cflags: [ + "-Wall", + "-Wextra", + ], + shared_libs: [ + "libbase", + "libbinder_ndk", + "liblog", + "android.hardware.gnss-ndk_platform", + ], + srcs: [ + "Gnss.cpp", + "GnssPsds.cpp", + "service.cpp", + ], +} diff --git a/gnss/aidl/default/Gnss.cpp b/gnss/aidl/default/Gnss.cpp new file mode 100644 index 0000000000..2a359244ef --- /dev/null +++ b/gnss/aidl/default/Gnss.cpp @@ -0,0 +1,31 @@ +/* + * 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 "GnssAidl" + +#include "Gnss.h" +#include +#include "GnssPsds.h" + +namespace aidl::android::hardware::gnss { + +ndk::ScopedAStatus Gnss::getExtensionPsds(std::shared_ptr* iGnssPsds) { + ALOGD("Gnss::getExtensionPsds"); + *iGnssPsds = SharedRefBase::make(); + return ndk::ScopedAStatus::ok(); +} + +} // namespace aidl::android::hardware::gnss diff --git a/gnss/aidl/default/Gnss.h b/gnss/aidl/default/Gnss.h new file mode 100644 index 0000000000..9864e9d98c --- /dev/null +++ b/gnss/aidl/default/Gnss.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include + +namespace aidl::android::hardware::gnss { + +class Gnss : public BnGnss { + ndk::ScopedAStatus getExtensionPsds(std::shared_ptr* iGnssPsds) override; +}; + +} // namespace aidl::android::hardware::gnss diff --git a/gnss/aidl/default/GnssPsds.cpp b/gnss/aidl/default/GnssPsds.cpp new file mode 100644 index 0000000000..c354217ebe --- /dev/null +++ b/gnss/aidl/default/GnssPsds.cpp @@ -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. + */ + +#define LOG_TAG "GnssPsdsAidl" + +#include "GnssPsds.h" + +#include + +namespace aidl::android::hardware::gnss { + +std::shared_ptr GnssPsds::sCallback = nullptr; + +ndk::ScopedAStatus GnssPsds::setCallback(const std::shared_ptr& callback, + bool* success) { + ALOGD("setCallback"); + std::unique_lock lock(mMutex); + sCallback = callback; + *success = true; + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus GnssPsds::injectPsdsData(PsdsType psdsType, const std::vector& psdsData, + bool* success) { + ALOGD("injectPsdsData. psdsType: %d, psdsData: %d bytes", static_cast(psdsType), + static_cast(psdsData.size())); + *success = (psdsData.size() > 0); + return ndk::ScopedAStatus::ok(); +} +} // namespace aidl::android::hardware::gnss diff --git a/gnss/aidl/default/GnssPsds.h b/gnss/aidl/default/GnssPsds.h new file mode 100644 index 0000000000..fc65bc15db --- /dev/null +++ b/gnss/aidl/default/GnssPsds.h @@ -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. + */ + +#pragma once + +#include + +namespace aidl::android::hardware::gnss { + +struct GnssPsds : public BnGnssPsds { + public: + ndk::ScopedAStatus setCallback(const std::shared_ptr& callback, + bool* success) override; + ndk::ScopedAStatus injectPsdsData(PsdsType psdsType, const std::vector& psdsData, + bool* success) override; + + private: + // Guarded by mMutex + static std::shared_ptr sCallback; + + // Synchronization lock for sCallback + mutable std::mutex mMutex; +}; + +} // namespace aidl::android::hardware::gnss diff --git a/gnss/aidl/default/gnss-default.rc b/gnss/aidl/default/gnss-default.rc new file mode 100644 index 0000000000..fe179c34f0 --- /dev/null +++ b/gnss/aidl/default/gnss-default.rc @@ -0,0 +1,4 @@ +service vendor.gnss-default /vendor/bin/hw/android.hardware.gnss-service.example + class hal + user nobody + group nobody diff --git a/gnss/aidl/default/gnss-default.xml b/gnss/aidl/default/gnss-default.xml new file mode 100644 index 0000000000..2b06cd28de --- /dev/null +++ b/gnss/aidl/default/gnss-default.xml @@ -0,0 +1,9 @@ + + + android.hardware.gnss + + IGnss + default + + + diff --git a/gnss/aidl/default/service.cpp b/gnss/aidl/default/service.cpp new file mode 100644 index 0000000000..c79a2718c5 --- /dev/null +++ b/gnss/aidl/default/service.cpp @@ -0,0 +1,35 @@ +/* + * 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 "Gnss.h" + +#include +#include +#include + +using aidl::android::hardware::gnss::Gnss; + +int main() { + ABinderProcess_setThreadPoolMaxThreadCount(0); + std::shared_ptr vib = ndk::SharedRefBase::make(); + + const std::string instance = std::string() + Gnss::descriptor + "/default"; + binder_status_t status = AServiceManager_addService(vib->asBinder().get(), instance.c_str()); + CHECK(status == STATUS_OK); + + ABinderProcess_joinThreadPool(); + return EXIT_FAILURE; // should not reach +} diff --git a/gnss/aidl/vts/Android.bp b/gnss/aidl/vts/Android.bp new file mode 100644 index 0000000000..e57b421768 --- /dev/null +++ b/gnss/aidl/vts/Android.bp @@ -0,0 +1,31 @@ +// 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. + +cc_test { + name: "VtsHalGnssTargetTest", + defaults: [ + "VtsHalTargetTestDefaults", + "use_libaidlvintf_gtest_helper_static", + ], + srcs: ["VtsHalGnssTargetTest.cpp"], + shared_libs: [ + "libbinder", + ], + static_libs: [ + "android.hardware.gnss-cpp", + ], + test_suites: [ + "vts", + ], +} diff --git a/gnss/aidl/vts/VtsHalGnssTargetTest.cpp b/gnss/aidl/vts/VtsHalGnssTargetTest.cpp new file mode 100644 index 0000000000..e7ffc05156 --- /dev/null +++ b/gnss/aidl/vts/VtsHalGnssTargetTest.cpp @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include + +#include +#include +#include +#include + +using android::ProcessState; +using android::sp; +using android::String16; +using android::binder::Status; +using android::hardware::gnss::IGnss; +using android::hardware::gnss::IGnssPsds; +using android::hardware::gnss::PsdsType; + +class GnssAidlHalTest : public testing::TestWithParam { + public: + virtual void SetUp() override { + gnss_hal_ = android::waitForDeclaredService(String16(GetParam().c_str())); + ASSERT_NE(gnss_hal_, nullptr); + } + + sp gnss_hal_; +}; + +/* + * SetupTeardownCreateCleanup: + * Requests the gnss HAL then calls cleanup + * + * Empty test fixture to verify basic Setup & Teardown + */ +TEST_P(GnssAidlHalTest, SetupTeardownCreateCleanup) {} + +/* + * TestPsdsExtension: + * 1. Gets the PsdsExtension and verifies that it returns a non-null extension. + * 2. Injects empty PSDS data and verifies that it returns false. + */ +TEST_P(GnssAidlHalTest, TestPsdsExtension) { + sp iGnssPsds; + auto status = gnss_hal_->getExtensionPsds(&iGnssPsds); + ASSERT_TRUE(status.isOk()); + ASSERT_TRUE(iGnssPsds != nullptr); + + bool success; + status = iGnssPsds->injectPsdsData(PsdsType::LONG_TERM, std::vector(), &success); + ASSERT_TRUE(status.isOk()); + ASSERT_FALSE(success); +} + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GnssAidlHalTest); +INSTANTIATE_TEST_SUITE_P(, GnssAidlHalTest, + testing::ValuesIn(android::getAidlHalInstanceNames(IGnss::descriptor)), + android::PrintInstanceNameToString); + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + ProcessState::self()->setThreadPoolMaxThreadCount(1); + ProcessState::self()->startThreadPool(); + return RUN_ALL_TESTS(); +} \ No newline at end of file -- GitLab From f910d10d23a3704a7073211ad29c0085951e15d7 Mon Sep 17 00:00:00 2001 From: lesl Date: Mon, 28 Sep 2020 11:17:56 +0800 Subject: [PATCH 174/790] wifi: ignore addAccessPoint_1_2 test if current hidl is 1_3 Bug: 169385303 Test: atest -c VtsHalWifiHostapdV1_2TargetTest Test: atest -c VtsHalWifiHostapdV1_1TargetTest Test: atest -c VtsHalWifiHostapdV1_0TargetTest Change-Id: I4be366be0e733b2ad00c64036a0f8be4e391228c --- wifi/hostapd/1.2/vts/functional/Android.bp | 9 +++-- .../1.2/vts/functional/hostapd_hidl_test.cpp | 37 +++++++++++++++++++ 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/wifi/hostapd/1.2/vts/functional/Android.bp b/wifi/hostapd/1.2/vts/functional/Android.bp index cec17823fd..577174b018 100644 --- a/wifi/hostapd/1.2/vts/functional/Android.bp +++ b/wifi/hostapd/1.2/vts/functional/Android.bp @@ -25,12 +25,15 @@ cc_test { "VtsHalWifiHostapdV1_0TargetTestUtil", "android.hardware.wifi.hostapd@1.0", "android.hardware.wifi.hostapd@1.1", - "android.hardware.wifi.hostapd@1.2", + "android.hardware.wifi.hostapd@1.2", + "android.hardware.wifi.hostapd@1.3", "android.hardware.wifi@1.0", "libgmock", "libwifi-system", "libwifi-system-iface", ], - test_suites: ["general-tests", "vts"], + test_suites: [ + "general-tests", + "vts", + ], } - diff --git a/wifi/hostapd/1.2/vts/functional/hostapd_hidl_test.cpp b/wifi/hostapd/1.2/vts/functional/hostapd_hidl_test.cpp index 99784a469e..c40c582406 100644 --- a/wifi/hostapd/1.2/vts/functional/hostapd_hidl_test.cpp +++ b/wifi/hostapd/1.2/vts/functional/hostapd_hidl_test.cpp @@ -25,6 +25,7 @@ #include #include +#include #include "hostapd_hidl_call_util.h" #include "hostapd_hidl_test_utils.h" @@ -216,12 +217,20 @@ class HostapdHidlTest std::string hostapd_instance_name_; }; +bool is_1_3(const sp& hostapd) { + sp<::android::hardware::wifi::hostapd::V1_3::IHostapd> hostapd_1_3 = + ::android::hardware::wifi::hostapd::V1_3::IHostapd::castFrom(hostapd); + return hostapd_1_3.get() != nullptr; +} + /** * Adds an access point with PSK network config & ACS enabled. * Access point creation should pass. */ TEST_P(HostapdHidlTest, AddPskAccessPointWithAcs) { if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support"; + if (is_1_3(hostapd_)) + GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3"; auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2, getIfaceParamsWithAcs(), getPskNwParams()); EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); @@ -233,6 +242,8 @@ TEST_P(HostapdHidlTest, AddPskAccessPointWithAcs) { */ TEST_P(HostapdHidlTest, AddPskAccessPointWithAcsAndFreqRange) { if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support"; + if (is_1_3(hostapd_)) + GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3"; auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2, getIfaceParamsWithAcsAndFreqRange(), getPskNwParams()); @@ -245,6 +256,8 @@ TEST_P(HostapdHidlTest, AddPskAccessPointWithAcsAndFreqRange) { */ TEST_P(HostapdHidlTest, AddPskAccessPointWithAcsAndInvalidFreqRange) { if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support"; + if (is_1_3(hostapd_)) + GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3"; auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2, getIfaceParamsWithAcsAndInvalidFreqRange(), getPskNwParams()); @@ -257,6 +270,8 @@ TEST_P(HostapdHidlTest, AddPskAccessPointWithAcsAndInvalidFreqRange) { */ TEST_P(HostapdHidlTest, AddOpenAccessPointWithAcs) { if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support"; + if (is_1_3(hostapd_)) + GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3"; auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2, getIfaceParamsWithAcs(), getOpenNwParams()); EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); @@ -267,6 +282,8 @@ TEST_P(HostapdHidlTest, AddOpenAccessPointWithAcs) { * Access point creation should pass. */ TEST_P(HostapdHidlTest, AddPskAccessPointWithoutAcs) { + if (is_1_3(hostapd_)) + GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3"; auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2, getIfaceParamsWithoutAcs(), getPskNwParams()); EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); @@ -277,6 +294,8 @@ TEST_P(HostapdHidlTest, AddPskAccessPointWithoutAcs) { * Access point creation should pass. */ TEST_P(HostapdHidlTest, AddOpenAccessPointWithoutAcs) { + if (is_1_3(hostapd_)) + GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3"; auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2, getIfaceParamsWithoutAcs(), getOpenNwParams()); EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); @@ -288,6 +307,8 @@ TEST_P(HostapdHidlTest, AddOpenAccessPointWithoutAcs) { */ TEST_P(HostapdHidlTest, AddSaeTransitionAccessPointWithoutAcs) { if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support"; + if (is_1_3(hostapd_)) + GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3"; auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2, getIfaceParamsWithoutAcs(), getSaeTransitionNwParams()); @@ -300,6 +321,8 @@ TEST_P(HostapdHidlTest, AddSaeTransitionAccessPointWithoutAcs) { */ TEST_P(HostapdHidlTest, AddSAEAccessPointWithoutAcs) { if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support"; + if (is_1_3(hostapd_)) + GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3"; auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2, getIfaceParamsWithoutAcs(), getSaeNwParams()); EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); @@ -311,6 +334,8 @@ TEST_P(HostapdHidlTest, AddSAEAccessPointWithoutAcs) { */ TEST_P(HostapdHidlTest, RemoveAccessPointWithAcs) { if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support"; + if (is_1_3(hostapd_)) + GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3"; auto status_1_2 = HIDL_INVOKE(hostapd_, addAccessPoint_1_2, getIfaceParamsWithAcs(), getPskNwParams()); EXPECT_EQ(HostapdStatusCode::SUCCESS, status_1_2.code); @@ -326,6 +351,8 @@ TEST_P(HostapdHidlTest, RemoveAccessPointWithAcs) { * Access point creation & removal should pass. */ TEST_P(HostapdHidlTest, RemoveAccessPointWithoutAcs) { + if (is_1_3(hostapd_)) + GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3"; auto status_1_2 = HIDL_INVOKE(hostapd_, addAccessPoint_1_2, getIfaceParamsWithoutAcs(), getPskNwParams()); EXPECT_EQ(HostapdStatusCode::SUCCESS, status_1_2.code); @@ -341,6 +368,8 @@ TEST_P(HostapdHidlTest, RemoveAccessPointWithoutAcs) { * Access point creation should fail. */ TEST_P(HostapdHidlTest, AddPskAccessPointWithInvalidChannel) { + if (is_1_3(hostapd_)) + GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3"; auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2, getIfaceParamsWithInvalidChannel(), getPskNwParams()); @@ -352,6 +381,8 @@ TEST_P(HostapdHidlTest, AddPskAccessPointWithInvalidChannel) { * Access point creation should fail. */ TEST_P(HostapdHidlTest, AddInvalidPskAccessPointWithoutAcs) { + if (is_1_3(hostapd_)) + GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3"; auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2, getIfaceParamsWithoutAcs(), getInvalidPskNwParams()); @@ -364,6 +395,8 @@ TEST_P(HostapdHidlTest, AddInvalidPskAccessPointWithoutAcs) { */ TEST_P(HostapdHidlTest, AddInvalidSaeTransitionAccessPointWithoutAcs) { if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support"; + if (is_1_3(hostapd_)) + GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3"; auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2, getIfaceParamsWithoutAcs(), getInvalidSaeTransitionNwParams()); @@ -376,6 +409,8 @@ TEST_P(HostapdHidlTest, AddInvalidSaeTransitionAccessPointWithoutAcs) { */ TEST_P(HostapdHidlTest, AddInvalidSaeAccessPointWithoutAcs) { if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support"; + if (is_1_3(hostapd_)) + GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3"; auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2, getIfaceParamsWithoutAcs(), getInvalidSaeNwParams()); @@ -398,6 +433,8 @@ TEST_P(HostapdHidlTest, DisconnectClientWhenIfaceNotAvailable) { * when hotspot interface available. */ TEST_P(HostapdHidlTest, DisconnectClientWhenIfacAvailable) { + if (is_1_3(hostapd_)) + GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3"; auto status_1_2 = HIDL_INVOKE(hostapd_, addAccessPoint_1_2, getIfaceParamsWithoutAcs(), getOpenNwParams()); -- GitLab From 9b85a78e714e5a8ec12ea3d6eba7e0a853b8279d Mon Sep 17 00:00:00 2001 From: lesl Date: Mon, 28 Sep 2020 11:31:21 +0800 Subject: [PATCH 175/790] wifi: Add vts 1.3 for hostapd hidl 1.3 Duplicate from 1.2 and add 1. Call setDebugParams for debugging 2. Add metered indication in NetworkParams (default is true) 3. Add non metered test case Bug: 151189102 Test: atest -c VtsHalWifiHostapdV1_3TargetTest --rebuild-module-info Test: atest -c VtsHalWifiHostapdV1_2TargetTest Test: atest -c VtsHalWifiHostapdV1_1TargetTest Test: atest -c VtsHalWifiHostapdV1_0TargetTest Change-Id: Ie425e14a08a71cfe4eb8a6b67cd837afd6da4dbe --- wifi/hostapd/1.3/vts/OWNERS | 2 + wifi/hostapd/1.3/vts/functional/Android.bp | 39 ++ .../1.3/vts/functional/hostapd_hidl_test.cpp | 433 ++++++++++++++++++ 3 files changed, 474 insertions(+) create mode 100644 wifi/hostapd/1.3/vts/OWNERS create mode 100644 wifi/hostapd/1.3/vts/functional/Android.bp create mode 100644 wifi/hostapd/1.3/vts/functional/hostapd_hidl_test.cpp diff --git a/wifi/hostapd/1.3/vts/OWNERS b/wifi/hostapd/1.3/vts/OWNERS new file mode 100644 index 0000000000..8bfb14882c --- /dev/null +++ b/wifi/hostapd/1.3/vts/OWNERS @@ -0,0 +1,2 @@ +rpius@google.com +etancohen@google.com diff --git a/wifi/hostapd/1.3/vts/functional/Android.bp b/wifi/hostapd/1.3/vts/functional/Android.bp new file mode 100644 index 0000000000..07cebb018a --- /dev/null +++ b/wifi/hostapd/1.3/vts/functional/Android.bp @@ -0,0 +1,39 @@ +// +// Copyright (C) 2020 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +cc_test { + name: "VtsHalWifiHostapdV1_3TargetTest", + defaults: ["VtsHalTargetTestDefaults"], + srcs: [ + "hostapd_hidl_test.cpp", + ], + static_libs: [ + "VtsHalWifiV1_0TargetTestUtil", + "VtsHalWifiHostapdV1_0TargetTestUtil", + "android.hardware.wifi.hostapd@1.0", + "android.hardware.wifi.hostapd@1.1", + "android.hardware.wifi.hostapd@1.2", + "android.hardware.wifi.hostapd@1.3", + "android.hardware.wifi@1.0", + "libgmock", + "libwifi-system", + "libwifi-system-iface", + ], + test_suites: [ + "general-tests", + "vts", + ], +} diff --git a/wifi/hostapd/1.3/vts/functional/hostapd_hidl_test.cpp b/wifi/hostapd/1.3/vts/functional/hostapd_hidl_test.cpp new file mode 100644 index 0000000000..d6c750f6c7 --- /dev/null +++ b/wifi/hostapd/1.3/vts/functional/hostapd_hidl_test.cpp @@ -0,0 +1,433 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include +#include + +#include +#include +#include + +#include +#include + +#include "hostapd_hidl_call_util.h" +#include "hostapd_hidl_test_utils.h" + +using ::android::sp; +using ::android::hardware::hidl_string; +using ::android::hardware::Return; +using ::android::hardware::Void; +using ::android::hardware::wifi::hostapd::V1_2::DebugLevel; +using ::android::hardware::wifi::hostapd::V1_2::HostapdStatusCode; +using ::android::hardware::wifi::hostapd::V1_2::Ieee80211ReasonCode; +using ::android::hardware::wifi::hostapd::V1_3::IHostapd; +using ::android::hardware::wifi::V1_0::IWifi; + +namespace { +constexpr unsigned char kNwSsid[] = {'t', 'e', 's', 't', '1', + '2', '3', '4', '5'}; +constexpr char kNwPassphrase[] = "test12345"; +constexpr char kInvalidMaxPskNwPassphrase[] = + "0123456789012345678901234567890123456789012345678901234567890123456789"; +constexpr char kInvalidMinPskNwPassphrase[] = "test"; +constexpr int kIfaceChannel = 6; +constexpr int kIfaceInvalidChannel = 567; +constexpr uint8_t kTestZeroMacAddr[] = {[0 ... 5] = 0x0}; +constexpr Ieee80211ReasonCode kTestDisconnectReasonCode = + Ieee80211ReasonCode::WLAN_REASON_UNSPECIFIED; +} // namespace + +class HostapdHidlTest + : public ::testing::TestWithParam> { + public: + virtual void SetUp() override { + wifi_instance_name_ = std::get<0>(GetParam()); + hostapd_instance_name_ = std::get<1>(GetParam()); + stopSupplicantIfNeeded(wifi_instance_name_); + startHostapdAndWaitForHidlService(wifi_instance_name_, + hostapd_instance_name_); + hostapd_ = IHostapd::getService(hostapd_instance_name_); + ASSERT_NE(hostapd_.get(), nullptr); + HIDL_INVOKE(hostapd_, setDebugParams, DebugLevel::EXCESSIVE); + isAcsSupport_ = testing::checkSubstringInCommandOutput( + "/system/bin/cmd wifi get-softap-supported-features", + "wifi_softap_acs_supported"); + isWpa3SaeSupport_ = testing::checkSubstringInCommandOutput( + "/system/bin/cmd wifi get-softap-supported-features", + "wifi_softap_wpa3_sae_supported"); + } + + virtual void TearDown() override { + HIDL_INVOKE_VOID_WITHOUT_ARGUMENTS(hostapd_, terminate); + stopHostapd(wifi_instance_name_); + } + + protected: + bool isWpa3SaeSupport_ = false; + bool isAcsSupport_ = false; + std::string getPrimaryWlanIfaceName() { + std::array buffer; + auto res = property_get("ro.vendor.wifi.sap.interface", buffer.data(), + nullptr); + if (res > 0) return buffer.data(); + property_get("wifi.interface", buffer.data(), "wlan0"); + return buffer.data(); + } + + IHostapd::IfaceParams getIfaceParamsWithoutAcs() { + ::android::hardware::wifi::hostapd::V1_0::IHostapd::IfaceParams + iface_params; + ::android::hardware::wifi::hostapd::V1_1::IHostapd::IfaceParams + iface_params_1_1; + IHostapd::IfaceParams iface_params_1_2; + + iface_params.ifaceName = getPrimaryWlanIfaceName(); + iface_params.hwModeParams.enable80211N = true; + iface_params.hwModeParams.enable80211AC = false; + iface_params.channelParams.enableAcs = false; + iface_params.channelParams.acsShouldExcludeDfs = false; + iface_params.channelParams.channel = kIfaceChannel; + iface_params_1_1.V1_0 = iface_params; + iface_params_1_2.V1_1 = iface_params_1_1; + // Newly added attributes in V1_2 + iface_params_1_2.hwModeParams.enable80211AX = false; + iface_params_1_2.hwModeParams.enable6GhzBand = false; + iface_params_1_2.channelParams.bandMask = 0; + iface_params_1_2.channelParams.bandMask |= + IHostapd::BandMask::BAND_2_GHZ; + return iface_params_1_2; + } + + IHostapd::IfaceParams getIfaceParamsWithAcs() { + // First get the settings for WithoutAcs and then make changes + IHostapd::IfaceParams iface_params_1_2 = getIfaceParamsWithoutAcs(); + iface_params_1_2.V1_1.V1_0.channelParams.enableAcs = true; + iface_params_1_2.V1_1.V1_0.channelParams.acsShouldExcludeDfs = true; + iface_params_1_2.V1_1.V1_0.channelParams.channel = 0; + iface_params_1_2.channelParams.bandMask |= + IHostapd::BandMask::BAND_5_GHZ; + + return iface_params_1_2; + } + + IHostapd::IfaceParams getIfaceParamsWithAcsAndFreqRange() { + IHostapd::IfaceParams iface_params_1_2 = getIfaceParamsWithAcs(); + ::android::hardware::wifi::hostapd::V1_2::IHostapd::AcsFrequencyRange + acsFrequencyRange; + acsFrequencyRange.start = 2412; + acsFrequencyRange.end = 2462; + std::vector<::android::hardware::wifi::hostapd::V1_2::IHostapd:: + AcsFrequencyRange> + vec_acsFrequencyRange; + vec_acsFrequencyRange.push_back(acsFrequencyRange); + iface_params_1_2.channelParams.acsChannelFreqRangesMhz = + vec_acsFrequencyRange; + return iface_params_1_2; + } + + IHostapd::IfaceParams getIfaceParamsWithAcsAndInvalidFreqRange() { + IHostapd::IfaceParams iface_params_1_2 = + getIfaceParamsWithAcsAndFreqRange(); + iface_params_1_2.channelParams.acsChannelFreqRangesMhz[0].start = 222; + iface_params_1_2.channelParams.acsChannelFreqRangesMhz[0].end = 999; + return iface_params_1_2; + } + + IHostapd::NetworkParams getOpenNwParams() { + IHostapd::NetworkParams nw_params_1_3; + ::android::hardware::wifi::hostapd::V1_2::IHostapd::NetworkParams + nw_params_1_2; + ::android::hardware::wifi::hostapd::V1_0::IHostapd::NetworkParams + nw_params_1_0; + nw_params_1_0.ssid = + std::vector(kNwSsid, kNwSsid + sizeof(kNwSsid)); + nw_params_1_0.isHidden = false; + nw_params_1_2.V1_0 = nw_params_1_0; + nw_params_1_2.encryptionType = IHostapd::EncryptionType::NONE; + nw_params_1_3.V1_2 = nw_params_1_2; + nw_params_1_3.isMetered = true; + return nw_params_1_3; + } + + IHostapd::NetworkParams getPskNwParamsWithNonMetered() { + IHostapd::NetworkParams nw_params_1_3 = getOpenNwParams(); + nw_params_1_3.V1_2.encryptionType = IHostapd::EncryptionType::WPA2; + nw_params_1_3.V1_2.passphrase = kNwPassphrase; + nw_params_1_3.isMetered = false; + return nw_params_1_3; + } + + IHostapd::NetworkParams getPskNwParams() { + IHostapd::NetworkParams nw_params_1_3 = getOpenNwParams(); + nw_params_1_3.V1_2.encryptionType = IHostapd::EncryptionType::WPA2; + nw_params_1_3.V1_2.passphrase = kNwPassphrase; + return nw_params_1_3; + } + + IHostapd::NetworkParams getInvalidPskNwParams() { + IHostapd::NetworkParams nw_params_1_3 = getOpenNwParams(); + nw_params_1_3.V1_2.encryptionType = IHostapd::EncryptionType::WPA2; + nw_params_1_3.V1_2.passphrase = kInvalidMaxPskNwPassphrase; + + return nw_params_1_3; + } + + IHostapd::NetworkParams getSaeTransitionNwParams() { + IHostapd::NetworkParams nw_params_1_3 = getOpenNwParams(); + nw_params_1_3.V1_2.encryptionType = + IHostapd::EncryptionType::WPA3_SAE_TRANSITION; + nw_params_1_3.V1_2.passphrase = kNwPassphrase; + return nw_params_1_3; + } + + IHostapd::NetworkParams getInvalidSaeTransitionNwParams() { + IHostapd::NetworkParams nw_params_1_3 = getOpenNwParams(); + nw_params_1_3.V1_2.encryptionType = IHostapd::EncryptionType::WPA2; + nw_params_1_3.V1_2.passphrase = kInvalidMinPskNwPassphrase; + return nw_params_1_3; + } + + IHostapd::NetworkParams getSaeNwParams() { + IHostapd::NetworkParams nw_params_1_3 = getOpenNwParams(); + nw_params_1_3.V1_2.encryptionType = IHostapd::EncryptionType::WPA3_SAE; + nw_params_1_3.V1_2.passphrase = kNwPassphrase; + return nw_params_1_3; + } + + IHostapd::NetworkParams getInvalidSaeNwParams() { + IHostapd::NetworkParams nw_params_1_3 = getOpenNwParams(); + nw_params_1_3.V1_2.encryptionType = IHostapd::EncryptionType::WPA3_SAE; + nw_params_1_3.V1_2.passphrase = ""; + return nw_params_1_3; + } + + IHostapd::IfaceParams getIfaceParamsWithInvalidChannel() { + IHostapd::IfaceParams iface_params_1_2 = getIfaceParamsWithoutAcs(); + iface_params_1_2.V1_1.V1_0.channelParams.channel = kIfaceInvalidChannel; + return iface_params_1_2; + } + + // IHostapd object used for all tests in this fixture. + sp hostapd_; + std::string wifi_instance_name_; + std::string hostapd_instance_name_; +}; + +/** + * Adds an access point with PSK network config & ACS enabled. + * Access point creation should pass. + */ +TEST_P(HostapdHidlTest, AddPskAccessPointWithAcs) { + if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support"; + auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, + getIfaceParamsWithAcs(), getPskNwParams()); + EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); +} + +/** + * Adds an access point with PSK network config, ACS enabled & frequency Range. + * Access point creation should pass. + */ +TEST_P(HostapdHidlTest, AddPskAccessPointWithAcsAndFreqRange) { + if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support"; + auto status = + HIDL_INVOKE(hostapd_, addAccessPoint_1_3, + getIfaceParamsWithAcsAndFreqRange(), getPskNwParams()); + EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); +} + +/** + * Adds an access point with invalid channel range. + * Access point creation should fail. + */ +TEST_P(HostapdHidlTest, AddPskAccessPointWithAcsAndInvalidFreqRange) { + if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support"; + auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, + getIfaceParamsWithAcsAndInvalidFreqRange(), + getPskNwParams()); + EXPECT_NE(HostapdStatusCode::SUCCESS, status.code); +} + +/** + * Adds an access point with Open network config & ACS enabled. + * Access point creation should pass. + */ +TEST_P(HostapdHidlTest, AddOpenAccessPointWithAcs) { + if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support"; + auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, + getIfaceParamsWithAcs(), getOpenNwParams()); + EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); +} + +/** + * Adds an access point with PSK network config & ACS disabled. + * Access point creation should pass. + */ +TEST_P(HostapdHidlTest, AddPskAccessPointWithoutAcs) { + auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, + getIfaceParamsWithoutAcs(), getPskNwParams()); + EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); +} + +/** + * Adds an access point with PSK network config, ACS disabled & Non metered. + * Access point creation should pass. + */ +TEST_P(HostapdHidlTest, AddPskAccessPointWithoutAcsAndNonMetered) { + auto status = + HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithoutAcs(), + getPskNwParamsWithNonMetered()); + EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); +} + +/** + * Adds an access point with Open network config & ACS disabled. + * Access point creation should pass. + */ +TEST_P(HostapdHidlTest, AddOpenAccessPointWithoutAcs) { + auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, + getIfaceParamsWithoutAcs(), getOpenNwParams()); + EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); +} + +/** + * Adds an access point with SAE Transition network config & ACS disabled. + * Access point creation should pass. + */ +TEST_P(HostapdHidlTest, AddSaeTransitionAccessPointWithoutAcs) { + if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support"; + auto status = + HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithoutAcs(), + getSaeTransitionNwParams()); + EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); +} + +/** + * Adds an access point with SAE network config & ACS disabled. + * Access point creation should pass. + */ +TEST_P(HostapdHidlTest, AddSAEAccessPointWithoutAcs) { + if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support"; + auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, + getIfaceParamsWithoutAcs(), getSaeNwParams()); + EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); +} + +/** + * Adds & then removes an access point with PSK network config & ACS enabled. + * Access point creation & removal should pass. + */ +TEST_P(HostapdHidlTest, RemoveAccessPointWithAcs) { + if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support"; + auto status_1_2 = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, + getIfaceParamsWithAcs(), getPskNwParams()); + EXPECT_EQ(HostapdStatusCode::SUCCESS, status_1_2.code); + auto status = + HIDL_INVOKE(hostapd_, removeAccessPoint, getPrimaryWlanIfaceName()); + EXPECT_EQ( + android::hardware::wifi::hostapd::V1_0::HostapdStatusCode::SUCCESS, + status.code); +} + +/** + * Adds & then removes an access point with PSK network config & ACS disabled. + * Access point creation & removal should pass. + */ +TEST_P(HostapdHidlTest, RemoveAccessPointWithoutAcs) { + auto status_1_2 = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, + getIfaceParamsWithoutAcs(), getPskNwParams()); + EXPECT_EQ(HostapdStatusCode::SUCCESS, status_1_2.code); + auto status = + HIDL_INVOKE(hostapd_, removeAccessPoint, getPrimaryWlanIfaceName()); + EXPECT_EQ( + android::hardware::wifi::hostapd::V1_0::HostapdStatusCode::SUCCESS, + status.code); +} + +/** + * Adds an access point with invalid channel. + * Access point creation should fail. + */ +TEST_P(HostapdHidlTest, AddPskAccessPointWithInvalidChannel) { + auto status = + HIDL_INVOKE(hostapd_, addAccessPoint_1_3, + getIfaceParamsWithInvalidChannel(), getPskNwParams()); + EXPECT_NE(HostapdStatusCode::SUCCESS, status.code); +} + +/** + * Adds an access point with invalid PSK network config. + * Access point creation should fail. + */ +TEST_P(HostapdHidlTest, AddInvalidPskAccessPointWithoutAcs) { + auto status = + HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithoutAcs(), + getInvalidPskNwParams()); + EXPECT_NE(HostapdStatusCode::SUCCESS, status.code); +} + +/** + * Adds an access point with invalid SAE transition network config. + * Access point creation should fail. + */ +TEST_P(HostapdHidlTest, AddInvalidSaeTransitionAccessPointWithoutAcs) { + if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support"; + auto status = + HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithoutAcs(), + getInvalidSaeTransitionNwParams()); + EXPECT_NE(HostapdStatusCode::SUCCESS, status.code); +} + +/** + * Adds an access point with invalid SAE network config. + * Access point creation should fail. + */ +TEST_P(HostapdHidlTest, AddInvalidSaeAccessPointWithoutAcs) { + if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support"; + auto status = + HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithoutAcs(), + getInvalidSaeNwParams()); + EXPECT_NE(HostapdStatusCode::SUCCESS, status.code); +} + +/** + * forceClientDisconnect should return FAILURE_CLIENT_UNKNOWN + * when hotspot interface available. + */ +TEST_P(HostapdHidlTest, DisconnectClientWhenIfacAvailable) { + auto status_1_2 = + HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithoutAcs(), + getOpenNwParams()); + EXPECT_EQ(HostapdStatusCode::SUCCESS, status_1_2.code); + + status_1_2 = + HIDL_INVOKE(hostapd_, forceClientDisconnect, getPrimaryWlanIfaceName(), + kTestZeroMacAddr, kTestDisconnectReasonCode); + EXPECT_EQ(HostapdStatusCode::FAILURE_CLIENT_UNKNOWN, status_1_2.code); +} + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(HostapdHidlTest); +INSTANTIATE_TEST_CASE_P( + PerInstance, HostapdHidlTest, + testing::Combine( + testing::ValuesIn( + android::hardware::getAllHalInstanceNames(IWifi::descriptor)), + testing::ValuesIn(android::hardware::getAllHalInstanceNames( + android::hardware::wifi::hostapd::V1_2::IHostapd::descriptor))), + android::hardware::PrintInstanceTupleNameToString<>); -- GitLab From 648ec5b750eb18fa5ffeedd06b00aa8aa4a771e1 Mon Sep 17 00:00:00 2001 From: Mikhail Naganov Date: Thu, 24 Sep 2020 18:00:44 +0000 Subject: [PATCH 176/790] audio: HAL V7 tweaks - rename AudioBasicConfig -> AudioConfigBase to better match a similar structure in audio.h; - define AudioProfile structure for defining an I/O profile; - use AudioProfile to replace IStream.getSupported* methods with a single IStream.getSupportedProfiles method; - define AudioDevice type for convenience and clarity; - move enums definition for AudioInputFlags and AudioOutputFlags into XSD. This allows parsing APM config w/o depending on the framework code. Bug: 142480271 Test: m Change-Id: I1951b2de383751fe53b96954dfd02cdd1ab6cc8f --- audio/7.0/IDevice.hal | 4 +- audio/7.0/IStream.hal | 56 +++++------------- audio/7.0/config/api/current.txt | 31 +++++++++- .../7.0/config/audio_policy_configuration.xsd | 31 +++++++++- .../7.0/config/update_audio_policy_config.sh | 1 + audio/7.0/types.hal | 57 +++---------------- audio/common/7.0/types.hal | 54 +++++++++++------- .../all-versions/default/VersionUtils.h | 2 +- .../default/include/core/default/Device.h | 2 + 9 files changed, 119 insertions(+), 119 deletions(-) diff --git a/audio/7.0/IDevice.hal b/audio/7.0/IDevice.hal index eecd92ed7c..e30e5456bc 100644 --- a/audio/7.0/IDevice.hal +++ b/audio/7.0/IDevice.hal @@ -117,7 +117,7 @@ interface IDevice { AudioIoHandle ioHandle, DeviceAddress device, AudioConfig config, - bitfield flags, + vec flags, SourceMetadata sourceMetadata) generates ( Result retval, IStreamOut outStream, @@ -142,7 +142,7 @@ interface IDevice { AudioIoHandle ioHandle, DeviceAddress device, AudioConfig config, - bitfield flags, + vec flags, SinkMetadata sinkMetadata) generates ( Result retval, IStreamIn inStream, diff --git a/audio/7.0/IStream.hal b/audio/7.0/IStream.hal index 789cb1dfd1..4fe8218b28 100644 --- a/audio/7.0/IStream.hal +++ b/audio/7.0/IStream.hal @@ -44,49 +44,23 @@ interface IStream { getBufferSize() generates (uint64_t bufferSize); /** - * Return supported native sampling rates of the stream for a given format. - * A supported native sample rate is a sample rate that can be efficiently - * played by the hardware (typically without sample-rate conversions). + * Return supported audio profiles for this particular stream. This method + * is normally called for streams opened on devices that use dynamic + * profiles, e.g. HDMI and USB interfaces. Please note that supported + * profiles of the stream may differ from the capabilities of the connected + * physical device. * - * This function is only called for dynamic profile. If called for - * non-dynamic profile is should return NOT_SUPPORTED or the same list - * as in audio_policy_configuration.xml. - * - * Calling this method is equivalent to getting - * AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES on the legacy HAL. - * - * - * @param format audio format for which the sample rates are supported. - * @return retval operation completion status. - * Must be OK if the format is supported. - * @return sampleRateHz supported sample rates. - */ - getSupportedSampleRates(AudioFormat format) - generates (Result retval, vec sampleRates); - - /** - * Return supported channel masks of the stream. Calling this method is - * equivalent to getting AUDIO_PARAMETER_STREAM_SUP_CHANNELS on the legacy - * HAL. - * - * @param format audio format for which the channel masks are supported. - * @return retval operation completion status. - * Must be OK if the format is supported. - * @return masks supported audio masks. - */ - getSupportedChannelMasks(AudioFormat format) - generates (Result retval, vec> masks); - - /** - * Return supported audio formats of the stream. Calling this method is - * equivalent to getting AUDIO_PARAMETER_STREAM_SUP_FORMATS on the legacy - * HAL. + * For devices with fixed configurations, e.g. built-in audio devices, all + * the profiles are specified in the audio_policy_configuration.xml + * file. For such devices, this method must return the configuration from + * the config file, or NOT_SUPPORTED retval. * * @return retval operation completion status. - * @return formats supported audio formats. + * @return formats supported audio profiles. * Must be non empty if retval is OK. */ - getSupportedFormats() generates (Result retval, vec formats); + getSupportedProfiles() + generates (Result retval, vec profiles); /** * Retrieves basic stream configuration: sample rate, audio format, @@ -94,18 +68,18 @@ interface IStream { * * @return config basic stream configuration. */ - getAudioProperties() generates (AudioBasicConfig config); + getAudioProperties() generates (AudioConfigBase config); /** * Sets stream parameters. Only sets parameters that are specified. - * See the description of AudioBasicConfig for the details. + * See the description of AudioConfigBase for the details. * * Optional method. If implemented, only called on a stopped stream. * * @param config basic stream configuration. * @return retval operation completion status. */ - setAudioProperties(AudioBasicConfig config) generates (Result retval); + setAudioProperties(AudioConfigBase config) generates (Result retval); /** * Applies audio effect to the stream. diff --git a/audio/7.0/config/api/current.txt b/audio/7.0/config/api/current.txt index fd9a8ef200..ac8dc8ae0c 100644 --- a/audio/7.0/config/api/current.txt +++ b/audio/7.0/config/api/current.txt @@ -228,6 +228,33 @@ package audio.policy.configuration.V7_0 { enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_WMA_PRO; } + public enum AudioInOutFlag { + method public String getRawName(); + enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_DIRECT; + enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_FAST; + enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_HW_AV_SYNC; + enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_HW_HOTWORD; + enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_MMAP_NOIRQ; + enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_RAW; + enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_SYNC; + enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_VOIP_TX; + enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD; + enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_DEEP_BUFFER; + enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_DIRECT; + enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_DIRECT_PCM; + enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_FAST; + enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_HW_AV_SYNC; + enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO; + enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_INCALL_MUSIC; + enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_MMAP_NOIRQ; + enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_NON_BLOCKING; + enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_PRIMARY; + enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_RAW; + enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_SYNC; + enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_TTS; + enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_VOIP_RX; + } + public class AudioPolicyConfiguration { ctor public AudioPolicyConfiguration(); method public audio.policy.configuration.V7_0.GlobalConfiguration getGlobalConfiguration(); @@ -396,7 +423,7 @@ package audio.policy.configuration.V7_0 { public static class MixPorts.MixPort { ctor public MixPorts.MixPort(); - method public String getFlags(); + method public java.util.List getFlags(); method public audio.policy.configuration.V7_0.Gains getGains(); method public long getMaxActiveCount(); method public long getMaxOpenCount(); @@ -404,7 +431,7 @@ package audio.policy.configuration.V7_0 { method public java.util.List getPreferredUsage(); method public java.util.List getProfile(); method public audio.policy.configuration.V7_0.Role getRole(); - method public void setFlags(String); + method public void setFlags(java.util.List); method public void setGains(audio.policy.configuration.V7_0.Gains); method public void setMaxActiveCount(long); method public void setMaxOpenCount(long); diff --git a/audio/7.0/config/audio_policy_configuration.xsd b/audio/7.0/config/audio_policy_configuration.xsd index 4555a88034..20fe02002e 100644 --- a/audio/7.0/config/audio_policy_configuration.xsd +++ b/audio/7.0/config/audio_policy_configuration.xsd @@ -155,16 +155,41 @@ - + - "|" separated list of audio_output_flags_t or audio_input_flags_t. + The flags indicate suggested stream attributes supported by the profile. - + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/audio/7.0/config/update_audio_policy_config.sh b/audio/7.0/config/update_audio_policy_config.sh index 8714b5f2d3..051a0df916 100755 --- a/audio/7.0/config/update_audio_policy_config.sh +++ b/audio/7.0/config/update_audio_policy_config.sh @@ -128,6 +128,7 @@ updateFile() { for F in $SOURCE_FILES; do updateFile ${F} "channelMasks" "," updateFile ${F} "samplingRates" "," + updateFile ${F} "flags" "|" done; updateIncludes() { diff --git a/audio/7.0/types.hal b/audio/7.0/types.hal index 15ca4921b0..4a9e28915a 100644 --- a/audio/7.0/types.hal +++ b/audio/7.0/types.hal @@ -357,56 +357,15 @@ struct PlaybackRate { }; /** - * The audio output flags serve two purposes: + * The audio flags serve two purposes: * - * - when an output stream is created they indicate its attributes; + * - when a stream is created they indicate its attributes; * - * - when present in an output profile descriptor listed for a particular audio - * hardware module, they indicate that an output stream can be opened that + * - when present in a profile descriptor listed for a particular audio + * hardware module, they indicate that a stream can be opened that * supports the attributes indicated by the flags. + * + * See 'audioIoFlag' in audio_policy_configuration.xsd for the + * list of allowed values. */ -@export(name="audio_output_flags_t", value_prefix="AUDIO_OUTPUT_FLAG_") -enum AudioOutputFlag : int32_t { - NONE = 0x0, // no attributes - DIRECT = 0x1, // this output directly connects a track - // to one output stream: no software mixer - PRIMARY = 0x2, // this output is the primary output of the device. It is - // unique and must be present. It is opened by default and - // receives routing, audio mode and volume controls related - // to voice calls. - FAST = 0x4, // output supports "fast tracks", defined elsewhere - DEEP_BUFFER = 0x8, // use deep audio buffers - COMPRESS_OFFLOAD = 0x10, // offload playback of compressed streams to - // hardware codec - NON_BLOCKING = 0x20, // use non-blocking write - HW_AV_SYNC = 0x40, // output uses a hardware A/V sync - TTS = 0x80, // output for streams transmitted through speaker at a - // sample rate high enough to accommodate lower-range - // ultrasonic p/b - RAW = 0x100, // minimize signal processing - SYNC = 0x200, // synchronize I/O streams - IEC958_NONAUDIO = 0x400, // Audio stream contains compressed audio in SPDIF - // data bursts, not PCM. - DIRECT_PCM = 0x2000, // Audio stream containing PCM data that needs - // to pass through compress path for DSP post proc. - MMAP_NOIRQ = 0x4000, // output operates in MMAP no IRQ mode. - VOIP_RX = 0x8000, // preferred output for VoIP calls. - /** preferred output for call music */ - INCALL_MUSIC = 0x10000, -}; - -/** - * The audio input flags are analogous to audio output flags. - */ -@export(name="audio_input_flags_t", value_prefix="AUDIO_INPUT_FLAG_") -enum AudioInputFlag : int32_t { - NONE = 0x0, // no attributes - FAST = 0x1, // prefer an input that supports "fast tracks" - HW_HOTWORD = 0x2, // prefer an input that captures from hw hotword source - RAW = 0x4, // minimize signal processing - SYNC = 0x8, // synchronize I/O streams - MMAP_NOIRQ = 0x10, // input operates in MMAP no IRQ mode. - VOIP_TX = 0x20, // preferred input for VoIP calls. - HW_AV_SYNC = 0x40, // input connected to an output that uses a hardware A/V sync - DIRECT = 0x80, // for acquiring encoded streams -}; +typedef string AudioInOutFlag; diff --git a/audio/common/7.0/types.hal b/audio/common/7.0/types.hal index 94d0af7673..31c7388329 100644 --- a/audio/common/7.0/types.hal +++ b/audio/common/7.0/types.hal @@ -112,12 +112,28 @@ typedef string AudioFormat; typedef string AudioChannelMask; /** - * Basic configuration applicable to any stream of audio. + * Base configuration attributes applicable to any stream of audio. */ -struct AudioBasicConfig { +struct AudioConfigBase { + AudioFormat format; // 'DEFAULT' means 'unspecified' uint32_t sampleRateHz; // 0 means 'unspecified' vec channelMask; // empty means 'unspecified' - AudioFormat format; // 'DEFAULT' means 'unspecified' +}; + +/** + * Configurations supported for a certain audio format. + */ +struct AudioProfile { + AudioFormat format; + /** List of the sample rates (in Hz) supported by the profile. */ + vec sampleRates; + /** + * List of channel masks supported by the profile. Every subvector might be + * comprised of several individual channel mask entries for non-traditional + * channel masks, e.g. a combination "OUT_FRONT_LEFT,OUT_FRONT_CENTER" which + * doesn't have a corresponding predefined channel mask. + */ + vec> channelMasks; }; /** @@ -136,18 +152,21 @@ enum AudioMode : int32_t { CALL_SCREEN = 4, }; +/** + * Audio device specifies type (or category) of audio I/O device + * (e.g. speaker or headphones). + * See 'audioDevice' in audio_policy_configuration.xsd for the + * list of allowed values. + */ +typedef string AudioDevice; + /** * Specifies a device address in case when several devices of the same type * can be connected (e.g. BT A2DP, USB). */ struct DeviceAddress { - /** - * Audio device specifies type (or category) of audio I/O device - * (e.g. speaker or headphones). - * See 'audioDevice' in audio_policy_configuration.xsd for the - * list of allowed values. - */ - string deviceType; + /** The type of the device. */ + AudioDevice deviceType; safe_union Address { /** * The address may be left unspecified if 'device' specifies @@ -209,7 +228,7 @@ enum AudioEncapsulationMode : int32_t { * Additional information about the stream passed to hardware decoders. */ struct AudioOffloadInfo { - AudioBasicConfig base; + AudioConfigBase base; AudioStreamType streamType; uint32_t bitRatePerSecond; int64_t durationMicroseconds; // -1 if unknown @@ -227,7 +246,7 @@ struct AudioOffloadInfo { * Commonly used audio stream configuration parameters. */ struct AudioConfig { - AudioBasicConfig base; + AudioConfigBase base; AudioOffloadInfo offloadInfo; uint64_t frameCount; }; @@ -372,9 +391,9 @@ struct AudioPortConfig { /** * Basic parameters: sampling rate, format, channel mask. Only some of the * parameters (or none) may be set. See the documentation of the - * AudioBasicConfig struct. + * AudioConfigBase struct. */ - AudioBasicConfig config; + AudioConfigBase config; /** Associated gain control. */ safe_union OptionalGain { Monostate unspecified; @@ -401,13 +420,6 @@ struct AudioPort { */ string name; /** List of audio profiles supported by the port. */ - struct AudioProfile { - AudioFormat format; - /** List of the sample rates supported by the profile. */ - vec sampleRates; - /** List of channel masks supported by the profile. */ - vec channelMasks; - }; vec profiles; /** List of gain controls attached to the port. */ vec gains; diff --git a/audio/common/all-versions/default/VersionUtils.h b/audio/common/all-versions/default/VersionUtils.h index e7755b1a7a..9bfca0cdcc 100644 --- a/audio/common/all-versions/default/VersionUtils.h +++ b/audio/common/all-versions/default/VersionUtils.h @@ -31,7 +31,7 @@ typedef common::CPP_VERSION::AudioDevice AudioDeviceBitfield; typedef common::CPP_VERSION::AudioChannelMask AudioChannelBitfield; typedef common::CPP_VERSION::AudioOutputFlag AudioOutputFlagBitfield; typedef common::CPP_VERSION::AudioInputFlag AudioInputFlagBitfield; -#elif MAJOR_VERSION >= 4 +#elif MAJOR_VERSION >= 4 && MAJOR_VERSION <= 6 typedef hidl_bitfield AudioDeviceBitfield; typedef hidl_bitfield AudioChannelBitfield; typedef hidl_bitfield AudioOutputFlagBitfield; diff --git a/audio/core/all-versions/default/include/core/default/Device.h b/audio/core/all-versions/default/include/core/default/Device.h index b0e72d9600..907acd7d7d 100644 --- a/audio/core/all-versions/default/include/core/default/Device.h +++ b/audio/core/all-versions/default/include/core/default/Device.h @@ -43,8 +43,10 @@ using ::android::hardware::hidl_string; using ::android::hardware::hidl_vec; using ::android::hardware::Return; using ::android::hardware::Void; +#if MAJOR_VERSION <= 6 using ::android::hardware::audio::common::CPP_VERSION::implementation::AudioInputFlagBitfield; using ::android::hardware::audio::common::CPP_VERSION::implementation::AudioOutputFlagBitfield; +#endif using namespace ::android::hardware::audio::common::CPP_VERSION; using namespace ::android::hardware::audio::CPP_VERSION; -- GitLab From 108e702dc736e40a371619af91c47a059daf095c Mon Sep 17 00:00:00 2001 From: Mikhail Naganov Date: Tue, 11 Aug 2020 22:21:40 +0000 Subject: [PATCH 177/790] audio: Reformat README as Markdown Rename README -> README.md, reformat it as Markdown. Provide missing descriptions for some directories. Bug: 142480271 Test: N/A Change-Id: Ic6f60a21def4bf210a7e1446454d709f68a13422 --- audio/README | 36 ------------------------------------ audio/README.md | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 36 deletions(-) delete mode 100644 audio/README create mode 100644 audio/README.md diff --git a/audio/README b/audio/README deleted file mode 100644 index afafbe32d2..0000000000 --- a/audio/README +++ /dev/null @@ -1,36 +0,0 @@ -Directory structure of the audio HIDL related code. - -Run `common/all-versions/copyHAL.sh` to create a new version of the audio HAL -based on an existing one. - -audio -|-- 2.0 <== core 2.0 HIDL API. .hal can not be moved into the core directory -| because that would change its namespace and include path -|-- 4.0 <== Version 4.0 of the core API -| -|-- ... -| -|-- common <== code common to audio core and effect API -| |-- 2.0 <== HIDL API of V2 -| |-- 4.0 -| |-- ... -| `-- all-versions <== code common to all version of both core and effect API -| |-- default <== implementation shared code between core and effect impl -| |-- test <== utilities used by tests -| `-- util <== utilities used by both implementation and tests -| -|-- core <== VTS and default implementation of the core API (not HIDL, see /audio/2.0)) -| `-- all-versions <== Code is version independent through #if and separate files -| |-- default <== code that wraps the legacy API -| `-- vts <== vts of core API -| |-- 2.0 <== 2.0 specific tests and helpers -| |-- 4.0 -| |-- ... -| -`-- effect <== idem for the effect API - |-- 2.0 - |-- 4.0 - |-- ... - `-- all-versions - |-- default - `-- vts diff --git a/audio/README.md b/audio/README.md new file mode 100644 index 0000000000..83ae6b26e8 --- /dev/null +++ b/audio/README.md @@ -0,0 +1,49 @@ +# Audio HAL + +Directory structure of the audio HAL related code. + +Run `common/all-versions/copyHAL.sh` to create a new version of the audio HAL +based on an existing one. + +## Directory Structure + +* `2.0` -- version 2.0 of the core HIDL API. Note that `.hal` files + can not be moved into the `core` directory because that would change + its namespace and include path. + - `config` -- the XSD schema for the Audio Policy Manager + configuration file. +* `4.0` -- version 4.0 of the core HIDL API. +* ... +* `common` -- common types for audio core and effect HIDL API. + - `2.0` -- version 2.0 of the common types HIDL API. + - `4.0` -- version 4.0. + - ... + - `all-versions` -- code common to all version of both core and effect API. + - `default` -- shared code of the default implementation. + - `service` -- vendor HAL service for hosting the default + implementation. + - `test` -- utilities used by tests. + - `util` -- utilities used by both implementation and tests. +* `core` -- VTS tests and the default implementation of the core API + (not HIDL API, it's in `audio/N.M`). + - `7.0` -- code specific to version V7.0 of the core HIDL API + - `all-versions` -- the code is common between all versions, + version-specific parts are enclosed into conditional directives + of preprocessor or reside in dedicated files. + - `default` -- code that wraps the legacy API (from + `hardware/libhardware`). + - `vts` VTS tests for the core HIDL API. +* `effect` -- same for the effect HIDL API. + - `2.0` + - `config` -- the XSD schema for the Audio Effects configuration + file. + - `4.0` + - ... + - `all-versions` + - `default` + - `vts` +* `policy` -- Configurable Audio Policy schemes. + - `1.0` -- note that versions of CAP are not linked to the versions + of audio HAL. + - `vts` -- VTS tests for validating actual configuration files. + - `xml` -- XSD schemas for CAP configuration files. -- GitLab From c9e1607de4c5f4854bc58ee9fdf45d16010cc476 Mon Sep 17 00:00:00 2001 From: Mikhail Naganov Date: Tue, 11 Aug 2020 23:23:16 +0000 Subject: [PATCH 178/790] audio: Add example HAL implementation This is partial implementation of the example V7.0 audio HAL which passes VTS tests. Note that the 'core' part of the HAL (IDevice/IStream) isn't implemented yet. It passes VTS because it doesn't provide any devices (modules) and the audio HAL isn't the 'default' instance. Bug: 142480271 Test: atest VtsHalAudioV7_0TargetTest atest VtsHalAudioEffectV7_0TargetTest Change-Id: Ie3dd62c5db1cdb5534df4dd7f326c4c8776bf3c4 --- audio/README.md | 4 + audio/common/7.0/example/Android.bp | 45 ++++ audio/common/7.0/example/DevicesFactory.cpp | 39 +++ audio/common/7.0/example/DevicesFactory.h | 33 +++ audio/common/7.0/example/Effect.cpp | 224 ++++++++++++++++++ audio/common/7.0/example/Effect.h | 90 +++++++ audio/common/7.0/example/EffectsFactory.cpp | 75 ++++++ audio/common/7.0/example/EffectsFactory.h | 39 +++ audio/common/7.0/example/EqualizerEffect.cpp | 130 ++++++++++ audio/common/7.0/example/EqualizerEffect.h | 163 +++++++++++++ .../7.0/example/LoudnessEnhancerEffect.cpp | 55 +++++ .../7.0/example/LoudnessEnhancerEffect.h | 146 ++++++++++++ audio/common/7.0/example/PREUPLOAD.cfg | 2 + ...roid.hardware.audio@7.0-service.example.rc | 7 + ...oid.hardware.audio@7.0-service.example.xml | 20 ++ audio/common/7.0/example/service.cpp | 57 +++++ 16 files changed, 1129 insertions(+) create mode 100644 audio/common/7.0/example/Android.bp create mode 100644 audio/common/7.0/example/DevicesFactory.cpp create mode 100644 audio/common/7.0/example/DevicesFactory.h create mode 100644 audio/common/7.0/example/Effect.cpp create mode 100644 audio/common/7.0/example/Effect.h create mode 100644 audio/common/7.0/example/EffectsFactory.cpp create mode 100644 audio/common/7.0/example/EffectsFactory.h create mode 100644 audio/common/7.0/example/EqualizerEffect.cpp create mode 100644 audio/common/7.0/example/EqualizerEffect.h create mode 100644 audio/common/7.0/example/LoudnessEnhancerEffect.cpp create mode 100644 audio/common/7.0/example/LoudnessEnhancerEffect.h create mode 100644 audio/common/7.0/example/PREUPLOAD.cfg create mode 100644 audio/common/7.0/example/android.hardware.audio@7.0-service.example.rc create mode 100644 audio/common/7.0/example/android.hardware.audio@7.0-service.example.xml create mode 100644 audio/common/7.0/example/service.cpp diff --git a/audio/README.md b/audio/README.md index 83ae6b26e8..b77b9ba42d 100644 --- a/audio/README.md +++ b/audio/README.md @@ -18,6 +18,10 @@ based on an existing one. - `2.0` -- version 2.0 of the common types HIDL API. - `4.0` -- version 4.0. - ... + - `7.0` -- version 7.0. + - `example` -- example implementation of the core and effect + V7.0 API. It represents a "fake" audio HAL that doesn't + actually communicate with hardware. - `all-versions` -- code common to all version of both core and effect API. - `default` -- shared code of the default implementation. - `service` -- vendor HAL service for hosting the default diff --git a/audio/common/7.0/example/Android.bp b/audio/common/7.0/example/Android.bp new file mode 100644 index 0000000000..03c1cd89cd --- /dev/null +++ b/audio/common/7.0/example/Android.bp @@ -0,0 +1,45 @@ +// +// 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. + +cc_binary { + name: "android.hardware.audio@7.0-service.example", + vendor: true, + relative_install_path: "hw", + init_rc: ["android.hardware.audio@7.0-service.example.rc"], + vintf_fragments: ["android.hardware.audio@7.0-service.example.xml"], + srcs: [ + "DevicesFactory.cpp", + "Effect.cpp", + "EffectsFactory.cpp", + "EqualizerEffect.cpp", + "LoudnessEnhancerEffect.cpp", + "service.cpp", + ], + cflags: [ + "-Wall", + "-Werror", + ], + shared_libs: [ + "libcutils", + "libhidlbase", + "liblog", + "libxml2", + "libutils", + "android.hardware.audio@7.0", + "android.hardware.audio.common@7.0", + "android.hardware.audio.common@7.0-enums", + "android.hardware.audio.effect@7.0", + ], +} diff --git a/audio/common/7.0/example/DevicesFactory.cpp b/audio/common/7.0/example/DevicesFactory.cpp new file mode 100644 index 0000000000..ddd5fef8f7 --- /dev/null +++ b/audio/common/7.0/example/DevicesFactory.cpp @@ -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. + */ + +#define LOG_TAG "DevicesFactory7.0" +#include + +#include "DevicesFactory.h" + +using ::android::hardware::hidl_string; +using ::android::hardware::Return; +using ::android::hardware::Void; + +namespace android::hardware::audio::V7_0::implementation { + +Return DevicesFactory::openDevice(const hidl_string& device, openDevice_cb _hidl_cb) { + (void)device; + _hidl_cb(Result::INVALID_ARGUMENTS, nullptr); + return Void(); +} + +Return DevicesFactory::openPrimaryDevice(openPrimaryDevice_cb _hidl_cb) { + _hidl_cb(Result::INVALID_ARGUMENTS, nullptr); + return Void(); +} + +} // namespace android::hardware::audio::V7_0::implementation diff --git a/audio/common/7.0/example/DevicesFactory.h b/audio/common/7.0/example/DevicesFactory.h new file mode 100644 index 0000000000..00f665c17e --- /dev/null +++ b/audio/common/7.0/example/DevicesFactory.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +namespace android::hardware::audio::V7_0::implementation { + +class DevicesFactory : public IDevicesFactory { + public: + DevicesFactory() = default; + + ::android::hardware::Return openDevice(const ::android::hardware::hidl_string& device, + openDevice_cb _hidl_cb) override; + + ::android::hardware::Return openPrimaryDevice(openPrimaryDevice_cb _hidl_cb) override; +}; + +} // namespace android::hardware::audio::V7_0::implementation diff --git a/audio/common/7.0/example/Effect.cpp b/audio/common/7.0/example/Effect.cpp new file mode 100644 index 0000000000..423754d593 --- /dev/null +++ b/audio/common/7.0/example/Effect.cpp @@ -0,0 +1,224 @@ +/* + * 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 "EffectsFactory7.0" +#include + +#include + +#include "Effect.h" + +using ::android::hardware::hidl_string; +using ::android::hardware::hidl_vec; +using ::android::hardware::Return; +using ::android::hardware::Void; +using namespace ::android::hardware::audio::common::V7_0; +// Make an alias for enumerations generated from the APM config XSD. +namespace xsd { +using namespace ::audio::policy::configuration::V7_0; +} + +namespace android::hardware::audio::effect::V7_0::implementation { + +Return Effect::init() { + return Result::OK; +} + +Return Effect::setConfig( + const EffectConfig& config, + const ::android::sp& inputBufferProvider, + const ::android::sp& outputBufferProvider) { + (void)config; + (void)inputBufferProvider; + (void)outputBufferProvider; + return Result::OK; +} + +Return Effect::reset() { + return Result::OK; +} + +Return Effect::enable() { + if (!mEnabled) { + mEnabled = true; + return Result::OK; + } else { + return Result::NOT_SUPPORTED; + } +} + +Return Effect::disable() { + if (mEnabled) { + mEnabled = false; + return Result::OK; + } else { + return Result::NOT_SUPPORTED; + } +} + +Return Effect::setDevice(const DeviceAddress& device) { + (void)device; + return Result::OK; +} + +Return Effect::setAndGetVolume(const hidl_vec& volumes, + setAndGetVolume_cb _hidl_cb) { + (void)volumes; + _hidl_cb(Result::OK, hidl_vec{}); + return Void(); +} + +Return Effect::volumeChangeNotification(const hidl_vec& volumes) { + (void)volumes; + return Result::OK; +} + +Return Effect::setAudioMode(AudioMode mode) { + (void)mode; + return Result::OK; +} + +Return Effect::setConfigReverse( + const EffectConfig& config, + const ::android::sp& inputBufferProvider, + const ::android::sp& outputBufferProvider) { + (void)config; + (void)inputBufferProvider; + (void)outputBufferProvider; + return Result::OK; +} + +Return Effect::setInputDevice(const DeviceAddress& device) { + (void)device; + return Result::OK; +} + +Return Effect::getConfig(getConfig_cb _hidl_cb) { + const EffectConfig config = {{} /* inputCfg */, + // outputCfg + {{} /* buffer */, + 48000 /* samplingRateHz */, + toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO), + toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT), + EffectBufferAccess::ACCESS_ACCUMULATE, + 0 /* mask */}}; + _hidl_cb(Result::OK, config); + return Void(); +} + +Return Effect::getConfigReverse(getConfigReverse_cb _hidl_cb) { + _hidl_cb(Result::OK, EffectConfig{}); + return Void(); +} + +Return Effect::getSupportedAuxChannelsConfigs(uint32_t maxConfigs, + getSupportedAuxChannelsConfigs_cb _hidl_cb) { + (void)maxConfigs; + _hidl_cb(Result::OK, hidl_vec{}); + return Void(); +} + +Return Effect::getAuxChannelsConfig(getAuxChannelsConfig_cb _hidl_cb) { + _hidl_cb(Result::OK, EffectAuxChannelsConfig{}); + return Void(); +} + +Return Effect::setAuxChannelsConfig(const EffectAuxChannelsConfig& config) { + (void)config; + return Result::OK; +} + +Return Effect::setAudioSource(const hidl_string& source) { + (void)source; + return Result::OK; +} + +Return Effect::offload(const EffectOffloadParameter& param) { + (void)param; + return Result::OK; +} + +Return Effect::getDescriptor(getDescriptor_cb _hidl_cb) { + _hidl_cb(Result::OK, mDescriptor); + return Void(); +} + +Return Effect::prepareForProcessing(prepareForProcessing_cb _hidl_cb) { + _hidl_cb(Result::OK, MQDescriptor{}); + return Void(); +} + +Return Effect::setProcessBuffers(const AudioBuffer& inBuffer, + const AudioBuffer& outBuffer) { + (void)inBuffer; + (void)outBuffer; + return Result::OK; +} + +Return Effect::command(uint32_t commandId, const hidl_vec& data, + uint32_t resultMaxSize, command_cb _hidl_cb) { + (void)commandId; + (void)data; + (void)resultMaxSize; + _hidl_cb(-EINVAL, hidl_vec{}); + return Void(); +} + +Return Effect::setParameter(const hidl_vec& parameter, + const hidl_vec& value) { + (void)parameter; + (void)value; + return Result::OK; +} + +Return Effect::getParameter(const hidl_vec& parameter, uint32_t valueMaxSize, + getParameter_cb _hidl_cb) { + (void)parameter; + (void)valueMaxSize; + _hidl_cb(Result::OK, hidl_vec{}); + return Void(); +} + +Return Effect::getSupportedConfigsForFeature(uint32_t featureId, uint32_t maxConfigs, + uint32_t configSize, + getSupportedConfigsForFeature_cb _hidl_cb) { + (void)featureId; + (void)maxConfigs; + (void)configSize; + _hidl_cb(Result::OK, 0, hidl_vec{}); + return Void(); +} + +Return Effect::getCurrentConfigForFeature(uint32_t featureId, uint32_t configSize, + getCurrentConfigForFeature_cb _hidl_cb) { + (void)featureId; + (void)configSize; + _hidl_cb(Result::OK, hidl_vec{}); + return Void(); +} + +Return Effect::setCurrentConfigForFeature(uint32_t featureId, + const hidl_vec& configData) { + (void)featureId; + (void)configData; + return Result::OK; +} + +Return Effect::close() { + return Result::OK; +} + +} // namespace android::hardware::audio::effect::V7_0::implementation diff --git a/audio/common/7.0/example/Effect.h b/audio/common/7.0/example/Effect.h new file mode 100644 index 0000000000..fa7f41bda6 --- /dev/null +++ b/audio/common/7.0/example/Effect.h @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +namespace android::hardware::audio::effect::V7_0::implementation { + +class Effect : public IEffect { + public: + explicit Effect(const EffectDescriptor& descriptor) : mDescriptor(descriptor) {} + + ::android::hardware::Return init() override; + ::android::hardware::Return setConfig( + const EffectConfig& config, + const ::android::sp& inputBufferProvider, + const ::android::sp& outputBufferProvider) override; + ::android::hardware::Return reset() override; + ::android::hardware::Return enable() override; + ::android::hardware::Return disable() override; + ::android::hardware::Return setDevice( + const ::android::hardware::audio::common::V7_0::DeviceAddress& device) override; + ::android::hardware::Return setAndGetVolume( + const ::android::hardware::hidl_vec& volumes, + setAndGetVolume_cb _hidl_cb) override; + ::android::hardware::Return volumeChangeNotification( + const ::android::hardware::hidl_vec& volumes) override; + ::android::hardware::Return setAudioMode( + ::android::hardware::audio::common::V7_0::AudioMode mode) override; + ::android::hardware::Return setConfigReverse( + const EffectConfig& config, + const ::android::sp& inputBufferProvider, + const ::android::sp& outputBufferProvider) override; + ::android::hardware::Return setInputDevice( + const ::android::hardware::audio::common::V7_0::DeviceAddress& device) override; + ::android::hardware::Return getConfig(getConfig_cb _hidl_cb) override; + ::android::hardware::Return getConfigReverse(getConfigReverse_cb _hidl_cb) override; + ::android::hardware::Return getSupportedAuxChannelsConfigs( + uint32_t maxConfigs, getSupportedAuxChannelsConfigs_cb _hidl_cb) override; + ::android::hardware::Return getAuxChannelsConfig( + getAuxChannelsConfig_cb _hidl_cb) override; + ::android::hardware::Return setAuxChannelsConfig( + const EffectAuxChannelsConfig& config) override; + ::android::hardware::Return setAudioSource( + const ::android::hardware::hidl_string& source) override; + ::android::hardware::Return offload(const EffectOffloadParameter& param) override; + ::android::hardware::Return getDescriptor(getDescriptor_cb _hidl_cb) override; + ::android::hardware::Return prepareForProcessing( + prepareForProcessing_cb _hidl_cb) override; + ::android::hardware::Return setProcessBuffers(const AudioBuffer& inBuffer, + const AudioBuffer& outBuffer) override; + ::android::hardware::Return command(uint32_t commandId, + const ::android::hardware::hidl_vec& data, + uint32_t resultMaxSize, command_cb _hidl_cb) override; + ::android::hardware::Return setParameter( + const ::android::hardware::hidl_vec& parameter, + const ::android::hardware::hidl_vec& value) override; + ::android::hardware::Return getParameter( + const ::android::hardware::hidl_vec& parameter, uint32_t valueMaxSize, + getParameter_cb _hidl_cb) override; + ::android::hardware::Return getSupportedConfigsForFeature( + uint32_t featureId, uint32_t maxConfigs, uint32_t configSize, + getSupportedConfigsForFeature_cb _hidl_cb) override; + ::android::hardware::Return getCurrentConfigForFeature( + uint32_t featureId, uint32_t configSize, + getCurrentConfigForFeature_cb _hidl_cb) override; + ::android::hardware::Return setCurrentConfigForFeature( + uint32_t featureId, const ::android::hardware::hidl_vec& configData) override; + ::android::hardware::Return close() override; + + private: + const EffectDescriptor mDescriptor; + bool mEnabled = false; +}; + +} // namespace android::hardware::audio::effect::V7_0::implementation diff --git a/audio/common/7.0/example/EffectsFactory.cpp b/audio/common/7.0/example/EffectsFactory.cpp new file mode 100644 index 0000000000..7d333ae040 --- /dev/null +++ b/audio/common/7.0/example/EffectsFactory.cpp @@ -0,0 +1,75 @@ +/* + * 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 "EffectsFactory7.0" +#include + +#include "EffectsFactory.h" +#include "EqualizerEffect.h" +#include "LoudnessEnhancerEffect.h" + +using ::android::hardware::hidl_string; +using ::android::hardware::hidl_vec; +using ::android::hardware::Return; +using ::android::hardware::Void; +using namespace ::android::hardware::audio::common::V7_0; + +namespace android::hardware::audio::effect::V7_0::implementation { + +Return EffectsFactory::getAllDescriptors(getAllDescriptors_cb _hidl_cb) { + hidl_vec descriptors; + descriptors.resize(2); + descriptors[0] = EqualizerEffect::getDescriptor(); + descriptors[1] = LoudnessEnhancerEffect::getDescriptor(); + _hidl_cb(Result::OK, descriptors); + return Void(); +} + +Return EffectsFactory::getDescriptor(const Uuid& uuid, getDescriptor_cb _hidl_cb) { + if (auto desc = EqualizerEffect::getDescriptor(); uuid == desc.type || uuid == desc.uuid) { + _hidl_cb(Result::OK, desc); + } else if (auto desc = LoudnessEnhancerEffect::getDescriptor(); + uuid == desc.type || uuid == desc.uuid) { + _hidl_cb(Result::OK, desc); + } else { + _hidl_cb(Result::INVALID_ARGUMENTS, EffectDescriptor{}); + } + return Void(); +} + +Return EffectsFactory::createEffect(const Uuid& uuid, int32_t session, int32_t ioHandle, + int32_t device, createEffect_cb _hidl_cb) { + (void)session; + (void)ioHandle; + (void)device; + if (auto desc = EqualizerEffect::getDescriptor(); uuid == desc.type || uuid == desc.uuid) { + _hidl_cb(Result::OK, new EqualizerEffect(), 0); + } else if (auto desc = LoudnessEnhancerEffect::getDescriptor(); + uuid == desc.type || uuid == desc.uuid) { + _hidl_cb(Result::OK, new LoudnessEnhancerEffect(), 0); + } else { + _hidl_cb(Result::INVALID_ARGUMENTS, nullptr, 0); + } + return Void(); +} + +Return EffectsFactory::debug(const hidl_handle& fd, const hidl_vec& options) { + (void)fd; + (void)options; + return Void(); +} + +} // namespace android::hardware::audio::effect::V7_0::implementation diff --git a/audio/common/7.0/example/EffectsFactory.h b/audio/common/7.0/example/EffectsFactory.h new file mode 100644 index 0000000000..8fec70cb35 --- /dev/null +++ b/audio/common/7.0/example/EffectsFactory.h @@ -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. + */ + +#pragma once + +#include + +namespace android::hardware::audio::effect::V7_0::implementation { + +class EffectsFactory : public IEffectsFactory { + public: + EffectsFactory() = default; + + ::android::hardware::Return getAllDescriptors(getAllDescriptors_cb _hidl_cb) override; + ::android::hardware::Return getDescriptor( + const ::android::hardware::audio::common::V7_0::Uuid& uuid, + getDescriptor_cb _hidl_cb) override; + ::android::hardware::Return createEffect( + const ::android::hardware::audio::common::V7_0::Uuid& uuid, int32_t session, + int32_t ioHandle, int32_t device, createEffect_cb _hidl_cb) override; + ::android::hardware::Return + debug(const ::android::hardware::hidl_handle& fd, + const ::android::hardware::hidl_vec<::android::hardware::hidl_string>& options) override; +}; + +} // namespace android::hardware::audio::effect::V7_0::implementation diff --git a/audio/common/7.0/example/EqualizerEffect.cpp b/audio/common/7.0/example/EqualizerEffect.cpp new file mode 100644 index 0000000000..c93c5a90fb --- /dev/null +++ b/audio/common/7.0/example/EqualizerEffect.cpp @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#define LOG_TAG "EffectsFactory7.0" +#include + +#include "EqualizerEffect.h" + +using ::android::hardware::hidl_string; +using ::android::hardware::hidl_vec; +using ::android::hardware::Return; +using ::android::hardware::Void; +using namespace ::android::hardware::audio::common::V7_0; + +namespace android::hardware::audio::effect::V7_0::implementation { + +const EffectDescriptor& EqualizerEffect::getDescriptor() { + // Note: for VTS tests only 'type' and 'uuid' fields are required. + // The actual implementation must provide meaningful values + // for all fields of the descriptor. + static const EffectDescriptor descriptor = { + .type = + {// Same UUID as AudioEffect.EFFECT_TYPE_EQUALIZER in Java. + 0x0bed4300, 0xddd6, 0x11db, 0x8f34, + std::array{{0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}}, + .uuid = {0, 0, 0, 1, std::array{{0, 0, 0, 0, 0, 0}}}}; + return descriptor; +} + +EqualizerEffect::EqualizerEffect() : mEffect(new Effect(getDescriptor())) { + mProperties.bandLevels.resize(kNumBands); +} + +Return EqualizerEffect::getNumBands(getNumBands_cb _hidl_cb) { + _hidl_cb(Result::OK, kNumBands); + return Void(); +} + +Return EqualizerEffect::getLevelRange(getLevelRange_cb _hidl_cb) { + _hidl_cb(Result::OK, std::numeric_limits::min(), std::numeric_limits::max()); + return Void(); +} + +Return EqualizerEffect::setBandLevel(uint16_t band, int16_t level) { + if (band < kNumBands) { + mProperties.bandLevels[band] = level; + return Result::OK; + } else { + return Result::INVALID_ARGUMENTS; + } +} + +Return EqualizerEffect::getBandLevel(uint16_t band, getBandLevel_cb _hidl_cb) { + if (band < kNumBands) { + _hidl_cb(Result::OK, mProperties.bandLevels[band]); + } else { + _hidl_cb(Result::INVALID_ARGUMENTS, 0); + } + return Void(); +} + +Return EqualizerEffect::getBandCenterFrequency(uint16_t band, + getBandCenterFrequency_cb _hidl_cb) { + (void)band; + _hidl_cb(Result::OK, 0); + return Void(); +} + +Return EqualizerEffect::getBandFrequencyRange(uint16_t band, + getBandFrequencyRange_cb _hidl_cb) { + (void)band; + _hidl_cb(Result::OK, 0, 1); + return Void(); +} + +Return EqualizerEffect::getBandForFrequency(uint32_t freq, getBandForFrequency_cb _hidl_cb) { + (void)freq; + _hidl_cb(Result::OK, 0); + return Void(); +} + +Return EqualizerEffect::getPresetNames(getPresetNames_cb _hidl_cb) { + hidl_vec presetNames; + presetNames.resize(kNumPresets); + presetNames[0] = "default"; + _hidl_cb(Result::OK, presetNames); + return Void(); +} + +Return EqualizerEffect::setCurrentPreset(uint16_t preset) { + if (preset < kNumPresets) { + mProperties.curPreset = preset; + return Result::OK; + } else { + return Result::INVALID_ARGUMENTS; + } +} + +Return EqualizerEffect::getCurrentPreset(getCurrentPreset_cb _hidl_cb) { + _hidl_cb(Result::OK, mProperties.curPreset); + return Void(); +} + +Return EqualizerEffect::setAllProperties( + const IEqualizerEffect::AllProperties& properties) { + mProperties = properties; + return Result::OK; +} + +Return EqualizerEffect::getAllProperties(getAllProperties_cb _hidl_cb) { + _hidl_cb(Result::OK, mProperties); + return Void(); +} + +} // namespace android::hardware::audio::effect::V7_0::implementation diff --git a/audio/common/7.0/example/EqualizerEffect.h b/audio/common/7.0/example/EqualizerEffect.h new file mode 100644 index 0000000000..11853c3392 --- /dev/null +++ b/audio/common/7.0/example/EqualizerEffect.h @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +#include "Effect.h" + +namespace android::hardware::audio::effect::V7_0::implementation { + +class EqualizerEffect : public IEqualizerEffect { + public: + static const EffectDescriptor& getDescriptor(); + + EqualizerEffect(); + + // Methods from IEffect interface. + ::android::hardware::Return init() override { return mEffect->init(); } + ::android::hardware::Return setConfig( + const EffectConfig& config, + const ::android::sp& inputBufferProvider, + const ::android::sp& outputBufferProvider) override { + return mEffect->setConfig(config, inputBufferProvider, outputBufferProvider); + } + ::android::hardware::Return reset() override { return mEffect->reset(); } + ::android::hardware::Return enable() override { return mEffect->enable(); } + ::android::hardware::Return disable() override { return mEffect->disable(); } + ::android::hardware::Return setDevice( + const ::android::hardware::audio::common::V7_0::DeviceAddress& device) override { + return mEffect->setDevice(device); + } + ::android::hardware::Return setAndGetVolume( + const ::android::hardware::hidl_vec& volumes, + setAndGetVolume_cb _hidl_cb) override { + return mEffect->setAndGetVolume(volumes, _hidl_cb); + } + ::android::hardware::Return volumeChangeNotification( + const ::android::hardware::hidl_vec& volumes) override { + return mEffect->volumeChangeNotification(volumes); + } + ::android::hardware::Return setAudioMode( + ::android::hardware::audio::common::V7_0::AudioMode mode) override { + return mEffect->setAudioMode(mode); + } + ::android::hardware::Return setConfigReverse( + const EffectConfig& config, + const ::android::sp& inputBufferProvider, + const ::android::sp& outputBufferProvider) override { + return mEffect->setConfigReverse(config, inputBufferProvider, outputBufferProvider); + } + ::android::hardware::Return setInputDevice( + const ::android::hardware::audio::common::V7_0::DeviceAddress& device) override { + return mEffect->setInputDevice(device); + } + ::android::hardware::Return getConfig(getConfig_cb _hidl_cb) override { + return mEffect->getConfig(_hidl_cb); + } + ::android::hardware::Return getConfigReverse(getConfigReverse_cb _hidl_cb) override { + return mEffect->getConfigReverse(_hidl_cb); + } + ::android::hardware::Return getSupportedAuxChannelsConfigs( + uint32_t maxConfigs, getSupportedAuxChannelsConfigs_cb _hidl_cb) override { + return mEffect->getSupportedAuxChannelsConfigs(maxConfigs, _hidl_cb); + } + ::android::hardware::Return getAuxChannelsConfig( + getAuxChannelsConfig_cb _hidl_cb) override { + return mEffect->getAuxChannelsConfig(_hidl_cb); + } + ::android::hardware::Return setAuxChannelsConfig( + const EffectAuxChannelsConfig& config) override { + return mEffect->setAuxChannelsConfig(config); + } + ::android::hardware::Return setAudioSource( + const ::android::hardware::hidl_string& source) override { + return mEffect->setAudioSource(source); + } + ::android::hardware::Return offload(const EffectOffloadParameter& param) override { + return mEffect->offload(param); + } + ::android::hardware::Return getDescriptor(getDescriptor_cb _hidl_cb) override { + return mEffect->getDescriptor(_hidl_cb); + } + ::android::hardware::Return prepareForProcessing( + prepareForProcessing_cb _hidl_cb) override { + return mEffect->prepareForProcessing(_hidl_cb); + } + ::android::hardware::Return setProcessBuffers(const AudioBuffer& inBuffer, + const AudioBuffer& outBuffer) override { + return mEffect->setProcessBuffers(inBuffer, outBuffer); + } + ::android::hardware::Return command(uint32_t commandId, + const ::android::hardware::hidl_vec& data, + uint32_t resultMaxSize, + command_cb _hidl_cb) override { + return mEffect->command(commandId, data, resultMaxSize, _hidl_cb); + } + ::android::hardware::Return setParameter( + const ::android::hardware::hidl_vec& parameter, + const ::android::hardware::hidl_vec& value) override { + return mEffect->setParameter(parameter, value); + } + ::android::hardware::Return getParameter( + const ::android::hardware::hidl_vec& parameter, uint32_t valueMaxSize, + getParameter_cb _hidl_cb) override { + return mEffect->getParameter(parameter, valueMaxSize, _hidl_cb); + } + ::android::hardware::Return getSupportedConfigsForFeature( + uint32_t featureId, uint32_t maxConfigs, uint32_t configSize, + getSupportedConfigsForFeature_cb _hidl_cb) override { + return mEffect->getSupportedConfigsForFeature(featureId, maxConfigs, configSize, _hidl_cb); + } + ::android::hardware::Return getCurrentConfigForFeature( + uint32_t featureId, uint32_t configSize, + getCurrentConfigForFeature_cb _hidl_cb) override { + return mEffect->getCurrentConfigForFeature(featureId, configSize, _hidl_cb); + } + ::android::hardware::Return setCurrentConfigForFeature( + uint32_t featureId, const ::android::hardware::hidl_vec& configData) override { + return mEffect->setCurrentConfigForFeature(featureId, configData); + } + ::android::hardware::Return close() override { return mEffect->close(); } + + // Methods from IEqualizerEffect interface. + ::android::hardware::Return getNumBands(getNumBands_cb _hidl_cb) override; + ::android::hardware::Return getLevelRange(getLevelRange_cb _hidl_cb) override; + ::android::hardware::Return setBandLevel(uint16_t band, int16_t level) override; + ::android::hardware::Return getBandLevel(uint16_t band, + getBandLevel_cb _hidl_cb) override; + ::android::hardware::Return getBandCenterFrequency( + uint16_t band, getBandCenterFrequency_cb _hidl_cb) override; + ::android::hardware::Return getBandFrequencyRange( + uint16_t band, getBandFrequencyRange_cb _hidl_cb) override; + ::android::hardware::Return getBandForFrequency(uint32_t freq, + getBandForFrequency_cb _hidl_cb) override; + ::android::hardware::Return getPresetNames(getPresetNames_cb _hidl_cb) override; + ::android::hardware::Return setCurrentPreset(uint16_t preset) override; + ::android::hardware::Return getCurrentPreset(getCurrentPreset_cb _hidl_cb) override; + ::android::hardware::Return setAllProperties( + const IEqualizerEffect::AllProperties& properties) override; + ::android::hardware::Return getAllProperties(getAllProperties_cb _hidl_cb) override; + + private: + static constexpr size_t kNumBands = 1; + static constexpr size_t kNumPresets = 1; + sp mEffect; + IEqualizerEffect::AllProperties mProperties{}; +}; + +} // namespace android::hardware::audio::effect::V7_0::implementation diff --git a/audio/common/7.0/example/LoudnessEnhancerEffect.cpp b/audio/common/7.0/example/LoudnessEnhancerEffect.cpp new file mode 100644 index 0000000000..38269b3308 --- /dev/null +++ b/audio/common/7.0/example/LoudnessEnhancerEffect.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "EffectsFactory7.0" +#include + +#include "LoudnessEnhancerEffect.h" + +using ::android::hardware::hidl_string; +using ::android::hardware::hidl_vec; +using ::android::hardware::Return; +using ::android::hardware::Void; +using namespace ::android::hardware::audio::common::V7_0; + +namespace android::hardware::audio::effect::V7_0::implementation { + +const EffectDescriptor& LoudnessEnhancerEffect::getDescriptor() { + // Note: for VTS tests only 'type' and 'uuid' fields are required. + // The actual implementation must provide meaningful values + // for all fields of the descriptor. + static const EffectDescriptor descriptor = { + .type = + {// Same UUID as AudioEffect.EFFECT_TYPE_LOUDNESS_ENHANCER in Java. + 0xfe3199be, 0xaed0, 0x413f, 0x87bb, + std::array{{0x11, 0x26, 0x0e, 0xb6, 0x3c, 0xf1}}}, + .uuid = {0, 0, 0, 2, std::array{{0, 0, 0, 0, 0, 0}}}}; + return descriptor; +} // namespace android::hardware::audio::effect::V7_0::implementation + +LoudnessEnhancerEffect::LoudnessEnhancerEffect() : mEffect(new Effect(getDescriptor())) {} + +Return LoudnessEnhancerEffect::setTargetGain(int32_t targetGainMb) { + mTargetGainMb = targetGainMb; + return Result::OK; +} + +Return LoudnessEnhancerEffect::getTargetGain(getTargetGain_cb _hidl_cb) { + _hidl_cb(Result::OK, mTargetGainMb); + return Void(); +} + +} // namespace android::hardware::audio::effect::V7_0::implementation diff --git a/audio/common/7.0/example/LoudnessEnhancerEffect.h b/audio/common/7.0/example/LoudnessEnhancerEffect.h new file mode 100644 index 0000000000..1af0d9f852 --- /dev/null +++ b/audio/common/7.0/example/LoudnessEnhancerEffect.h @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +#include "Effect.h" + +namespace android::hardware::audio::effect::V7_0::implementation { + +class LoudnessEnhancerEffect : public ILoudnessEnhancerEffect { + public: + static const EffectDescriptor& getDescriptor(); + + LoudnessEnhancerEffect(); + + // Methods from IEffect interface. + ::android::hardware::Return init() override { return mEffect->init(); } + ::android::hardware::Return setConfig( + const EffectConfig& config, + const ::android::sp& inputBufferProvider, + const ::android::sp& outputBufferProvider) override { + return mEffect->setConfig(config, inputBufferProvider, outputBufferProvider); + } + ::android::hardware::Return reset() override { return mEffect->reset(); } + ::android::hardware::Return enable() override { return mEffect->enable(); } + ::android::hardware::Return disable() override { return mEffect->disable(); } + ::android::hardware::Return setDevice( + const ::android::hardware::audio::common::V7_0::DeviceAddress& device) override { + return mEffect->setDevice(device); + } + ::android::hardware::Return setAndGetVolume( + const ::android::hardware::hidl_vec& volumes, + setAndGetVolume_cb _hidl_cb) override { + return mEffect->setAndGetVolume(volumes, _hidl_cb); + } + ::android::hardware::Return volumeChangeNotification( + const ::android::hardware::hidl_vec& volumes) override { + return mEffect->volumeChangeNotification(volumes); + } + ::android::hardware::Return setAudioMode( + ::android::hardware::audio::common::V7_0::AudioMode mode) override { + return mEffect->setAudioMode(mode); + } + ::android::hardware::Return setConfigReverse( + const EffectConfig& config, + const ::android::sp& inputBufferProvider, + const ::android::sp& outputBufferProvider) override { + return mEffect->setConfigReverse(config, inputBufferProvider, outputBufferProvider); + } + ::android::hardware::Return setInputDevice( + const ::android::hardware::audio::common::V7_0::DeviceAddress& device) override { + return mEffect->setInputDevice(device); + } + ::android::hardware::Return getConfig(getConfig_cb _hidl_cb) override { + return mEffect->getConfig(_hidl_cb); + } + ::android::hardware::Return getConfigReverse(getConfigReverse_cb _hidl_cb) override { + return mEffect->getConfigReverse(_hidl_cb); + } + ::android::hardware::Return getSupportedAuxChannelsConfigs( + uint32_t maxConfigs, getSupportedAuxChannelsConfigs_cb _hidl_cb) override { + return mEffect->getSupportedAuxChannelsConfigs(maxConfigs, _hidl_cb); + } + ::android::hardware::Return getAuxChannelsConfig( + getAuxChannelsConfig_cb _hidl_cb) override { + return mEffect->getAuxChannelsConfig(_hidl_cb); + } + ::android::hardware::Return setAuxChannelsConfig( + const EffectAuxChannelsConfig& config) override { + return mEffect->setAuxChannelsConfig(config); + } + ::android::hardware::Return setAudioSource( + const ::android::hardware::hidl_string& source) override { + return mEffect->setAudioSource(source); + } + ::android::hardware::Return offload(const EffectOffloadParameter& param) override { + return mEffect->offload(param); + } + ::android::hardware::Return getDescriptor(getDescriptor_cb _hidl_cb) override { + return mEffect->getDescriptor(_hidl_cb); + } + ::android::hardware::Return prepareForProcessing( + prepareForProcessing_cb _hidl_cb) override { + return mEffect->prepareForProcessing(_hidl_cb); + } + ::android::hardware::Return setProcessBuffers(const AudioBuffer& inBuffer, + const AudioBuffer& outBuffer) override { + return mEffect->setProcessBuffers(inBuffer, outBuffer); + } + ::android::hardware::Return command(uint32_t commandId, + const ::android::hardware::hidl_vec& data, + uint32_t resultMaxSize, + command_cb _hidl_cb) override { + return mEffect->command(commandId, data, resultMaxSize, _hidl_cb); + } + ::android::hardware::Return setParameter( + const ::android::hardware::hidl_vec& parameter, + const ::android::hardware::hidl_vec& value) override { + return mEffect->setParameter(parameter, value); + } + ::android::hardware::Return getParameter( + const ::android::hardware::hidl_vec& parameter, uint32_t valueMaxSize, + getParameter_cb _hidl_cb) override { + return mEffect->getParameter(parameter, valueMaxSize, _hidl_cb); + } + ::android::hardware::Return getSupportedConfigsForFeature( + uint32_t featureId, uint32_t maxConfigs, uint32_t configSize, + getSupportedConfigsForFeature_cb _hidl_cb) override { + return mEffect->getSupportedConfigsForFeature(featureId, maxConfigs, configSize, _hidl_cb); + } + ::android::hardware::Return getCurrentConfigForFeature( + uint32_t featureId, uint32_t configSize, + getCurrentConfigForFeature_cb _hidl_cb) override { + return mEffect->getCurrentConfigForFeature(featureId, configSize, _hidl_cb); + } + ::android::hardware::Return setCurrentConfigForFeature( + uint32_t featureId, const ::android::hardware::hidl_vec& configData) override { + return mEffect->setCurrentConfigForFeature(featureId, configData); + } + ::android::hardware::Return close() override { return mEffect->close(); } + + // Methods from ILoudnessEnhancerEffect interface. + ::android::hardware::Return setTargetGain(int32_t targetGainMb) override; + ::android::hardware::Return getTargetGain(getTargetGain_cb _hidl_cb) override; + + private: + sp mEffect; + int32_t mTargetGainMb = 0; +}; + +} // namespace android::hardware::audio::effect::V7_0::implementation diff --git a/audio/common/7.0/example/PREUPLOAD.cfg b/audio/common/7.0/example/PREUPLOAD.cfg new file mode 100644 index 0000000000..6b7fd7137c --- /dev/null +++ b/audio/common/7.0/example/PREUPLOAD.cfg @@ -0,0 +1,2 @@ +[Builtin Hooks] +clang_format = true diff --git a/audio/common/7.0/example/android.hardware.audio@7.0-service.example.rc b/audio/common/7.0/example/android.hardware.audio@7.0-service.example.rc new file mode 100644 index 0000000000..cf8b51f07b --- /dev/null +++ b/audio/common/7.0/example/android.hardware.audio@7.0-service.example.rc @@ -0,0 +1,7 @@ +service vendor.audio-hal-7-0 /vendor/bin/hw/android.hardware.audio@7.0-service.example + class hal + user audioserver + group audio + capabilities BLOCK_SUSPEND + ioprio rt 4 + task_profiles ProcessCapacityHigh HighPerformance diff --git a/audio/common/7.0/example/android.hardware.audio@7.0-service.example.xml b/audio/common/7.0/example/android.hardware.audio@7.0-service.example.xml new file mode 100644 index 0000000000..b91b0612ce --- /dev/null +++ b/audio/common/7.0/example/android.hardware.audio@7.0-service.example.xml @@ -0,0 +1,20 @@ + + + android.hardware.audio + hwbinder + 7.0 + + IDevicesFactory + example + + + + android.hardware.audio.effect + hwbinder + 7.0 + + IEffectsFactory + example + + + diff --git a/audio/common/7.0/example/service.cpp b/audio/common/7.0/example/service.cpp new file mode 100644 index 0000000000..641e2c90ae --- /dev/null +++ b/audio/common/7.0/example/service.cpp @@ -0,0 +1,57 @@ +/* + * 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 "android.hardware.audio@7.0-service.example" +#include +#include + +#include "DevicesFactory.h" +#include "EffectsFactory.h" + +using android::hardware::configureRpcThreadpool; +using android::hardware::joinRpcThreadpool; +using namespace android; + +status_t registerDevicesFactoryService() { + sp<::android::hardware::audio::V7_0::IDevicesFactory> devicesFactory = + new ::android::hardware::audio::V7_0::implementation::DevicesFactory(); + status_t status = devicesFactory->registerAsService("example"); + ALOGE_IF(status != OK, "Error registering devices factory as service: %d", status); + return status; +} + +status_t registerEffectsFactoryService() { + sp<::android::hardware::audio::effect::V7_0::IEffectsFactory> devicesFactory = + new ::android::hardware::audio::effect::V7_0::implementation::EffectsFactory(); + status_t status = devicesFactory->registerAsService("example"); + ALOGE_IF(status != OK, "Error registering effects factory as service: %d", status); + return status; +} + +int main() { + configureRpcThreadpool(1, true); + status_t status = registerDevicesFactoryService(); + if (status != OK) { + return status; + } + status = registerEffectsFactoryService(); + if (status != OK) { + return status; + } + joinRpcThreadpool(); + + return 1; +} -- GitLab From 5127a97bd8df18f6b2c40ca2540be58377362bcb Mon Sep 17 00:00:00 2001 From: Marin Shalamanov Date: Tue, 29 Sep 2020 16:03:55 +0200 Subject: [PATCH 179/790] Update the comment for ReplacedHandle Test: n/a Bug: n/a Change-Id: I388af766fb1b5e78aabfc72c70883e71d05ce18c --- .../include/composer-resources/2.1/ComposerResources.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/graphics/composer/2.1/utils/resources/include/composer-resources/2.1/ComposerResources.h b/graphics/composer/2.1/utils/resources/include/composer-resources/2.1/ComposerResources.h index 3738278559..df5513ea0a 100644 --- a/graphics/composer/2.1/utils/resources/include/composer-resources/2.1/ComposerResources.h +++ b/graphics/composer/2.1/utils/resources/include/composer-resources/2.1/ComposerResources.h @@ -177,7 +177,8 @@ class ComposerResources { bool mustValidateDisplay(Display display); // When a buffer in the cache is replaced by a new one, we must keep it - // alive until it has been replaced in ComposerHal. + // alive until it has been replaced in ComposerHal because it is still using + // the old buffer. class ReplacedHandle { public: explicit ReplacedHandle(bool isBuffer) : mIsBuffer(isBuffer) {} -- GitLab From bc15b5964ed681d9f7dc6c801d41f6f00a3850a2 Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Fri, 25 Sep 2020 15:35:55 -0700 Subject: [PATCH 180/790] Rename Tuner HAL 1.1 frontendSettingsExt into frontendSettingsExt1_1 Test: make Bug: 158818695 Change-Id: I1d9e89556fc7de0962dcfbf379c115ea4a0e8d32 --- tv/tuner/1.1/IFrontend.hal | 10 +++++----- tv/tuner/1.1/default/Frontend.cpp | 4 ++-- tv/tuner/1.1/default/Frontend.h | 4 ++-- tv/tuner/1.1/types.hal | 14 +++++++------- tv/tuner/1.1/vts/functional/FrontendTests.cpp | 10 +++++----- tv/tuner/1.1/vts/functional/FrontendTests.h | 2 +- .../vts/functional/VtsHalTvTunerV1_1TargetTest.cpp | 6 +++--- .../VtsHalTvTunerV1_1TestConfigurations.h | 10 +++++----- 8 files changed, 30 insertions(+), 30 deletions(-) diff --git a/tv/tuner/1.1/IFrontend.hal b/tv/tuner/1.1/IFrontend.hal index 9858d4b061..f39eb5de48 100644 --- a/tv/tuner/1.1/IFrontend.hal +++ b/tv/tuner/1.1/IFrontend.hal @@ -37,7 +37,7 @@ interface IFrontend extends @1.0::IFrontend { * * @param settings Signal delivery information the frontend uses to * search and lock the signal. - * @param settingsExt Extended information that would be used in the 1.1 Frontend to + * @param settingsExt1_1 v1_1 Extended information that would be used in the 1.1 Frontend to * search and lock the signal in a better way. * * @return result Result status of the operation. @@ -45,7 +45,7 @@ interface IFrontend extends @1.0::IFrontend { * INVALID_STATE if tuning can't be applied at current stage, * UNKNOWN_ERROR if tuning failed for other reasons. */ - tune_1_1(FrontendSettings settings, FrontendSettingsExt settingsExt) + tune_1_1(FrontendSettings settings, FrontendSettingsExt1_1 settingsExt1_1) generates (Result result); /** @@ -59,15 +59,15 @@ interface IFrontend extends @1.0::IFrontend { * @param settings Signal delivery information which the frontend uses to * scan the signal. * @param type the type which the frontend uses to scan the signal. - * @param settingsExt Extended information that would be used in the 1.1 Frontend to + * @param settingsExt1_1 v1_1 Extended information that would be used in the 1.1 Frontend to * search and lock the signal in a better way. * @return result Result status of the operation. * SUCCESS if successful, * INVALID_STATE if tuning can't be applied at current stage, * UNKNOWN_ERROR if tuning failed for other reasons. */ - scan_1_1(FrontendSettings settings, FrontendScanType type, FrontendSettingsExt settingsExt) - generates (Result result); + scan_1_1(FrontendSettings settings, FrontendScanType type, + FrontendSettingsExt1_1 settingsExt1_1) generates (Result result); /** * Link Conditional Access Modules (CAM) to Frontend support Common Interface (CI) bypass mode. diff --git a/tv/tuner/1.1/default/Frontend.cpp b/tv/tuner/1.1/default/Frontend.cpp index 467d54776b..0b8311ff69 100644 --- a/tv/tuner/1.1/default/Frontend.cpp +++ b/tv/tuner/1.1/default/Frontend.cpp @@ -72,7 +72,7 @@ Return Frontend::tune(const FrontendSettings& /* settings */) { } Return Frontend::tune_1_1(const FrontendSettings& settings, - const V1_1::FrontendSettingsExt& /*settingsExt*/) { + const V1_1::FrontendSettingsExt1_1& /*settingsExt1_1*/) { ALOGV("%s", __FUNCTION__); return tune(settings); } @@ -122,7 +122,7 @@ Return Frontend::scan(const FrontendSettings& settings, FrontendScanType } Return Frontend::scan_1_1(const FrontendSettings& settings, FrontendScanType type, - const V1_1::FrontendSettingsExt& /*settingsExt*/) { + const V1_1::FrontendSettingsExt1_1& /*settingsExt1_1*/) { ALOGV("%s", __FUNCTION__); return scan(settings, type); } diff --git a/tv/tuner/1.1/default/Frontend.h b/tv/tuner/1.1/default/Frontend.h index 6a80232b21..a843f6587c 100644 --- a/tv/tuner/1.1/default/Frontend.h +++ b/tv/tuner/1.1/default/Frontend.h @@ -44,14 +44,14 @@ class Frontend : public V1_1::IFrontend { virtual Return tune(const FrontendSettings& settings) override; virtual Return tune_1_1(const FrontendSettings& settings, - const V1_1::FrontendSettingsExt& settingsExt) override; + const V1_1::FrontendSettingsExt1_1& settingsExt1_1) override; virtual Return stopTune() override; virtual Return scan(const FrontendSettings& settings, FrontendScanType type) override; virtual Return scan_1_1(const FrontendSettings& settings, FrontendScanType type, - const V1_1::FrontendSettingsExt& settingsExt) override; + const V1_1::FrontendSettingsExt1_1& settingsExt1_1) override; virtual Return stopScan() override; diff --git a/tv/tuner/1.1/types.hal b/tv/tuner/1.1/types.hal index af8d628d90..214e3a12a4 100644 --- a/tv/tuner/1.1/types.hal +++ b/tv/tuner/1.1/types.hal @@ -145,14 +145,14 @@ enum FrontendDvbtConstellation : @1.0::FrontendDvbtConstellation { /** * Extended Signal Settings for a DVBS Frontend. */ -struct FrontendDvbsSettingsExt { +struct FrontendDvbsSettingsExt1_1 { FrontendDvbsScanType scanType; }; /** * Extended Signal Settings for a DVBT Frontend. */ -struct FrontendDvbtSettingsExt { +struct FrontendDvbtSettingsExt1_1 { FrontendDvbtConstellation constellation; FrontendDvbtTransmissionMode transmissionMode; @@ -161,14 +161,14 @@ struct FrontendDvbtSettingsExt { /** * Extended Signal Settings for an Analog Frontend. */ -struct FrontendAnalogSettingsExt { +struct FrontendAnalogSettingsExt1_1 { FrontendAnalogAftFlag aftFlag; }; /** * Extended Signal Settings for Frontend. */ -struct FrontendSettingsExt { +struct FrontendSettingsExt1_1 { uint32_t endFrequency; FrontendSpectralInversion inversion; @@ -176,10 +176,10 @@ struct FrontendSettingsExt { safe_union SettingsExt { Monostate noinit; - FrontendAnalogSettingsExt analog; + FrontendAnalogSettingsExt1_1 analog; - FrontendDvbsSettingsExt dvbs; + FrontendDvbsSettingsExt1_1 dvbs; - FrontendDvbtSettingsExt dvbt; + FrontendDvbtSettingsExt1_1 dvbt; } settingExt; }; diff --git a/tv/tuner/1.1/vts/functional/FrontendTests.cpp b/tv/tuner/1.1/vts/functional/FrontendTests.cpp index 5e2b2886ce..897cbaf998 100644 --- a/tv/tuner/1.1/vts/functional/FrontendTests.cpp +++ b/tv/tuner/1.1/vts/functional/FrontendTests.cpp @@ -48,7 +48,7 @@ Return FrontendCallback::onScanMessage(FrontendScanMessageType type, } void FrontendCallback::tuneTestOnLock(sp& frontend, FrontendSettings settings, - FrontendSettingsExt settingsExt) { + FrontendSettingsExt1_1 settingsExt1_1) { sp frontend_1_1; frontend_1_1 = android::hardware::tv::tuner::V1_1::IFrontend::castFrom(frontend); if (frontend_1_1 == nullptr) { @@ -56,7 +56,7 @@ void FrontendCallback::tuneTestOnLock(sp& frontend, FrontendSettings return; } - Result result = frontend_1_1->tune_1_1(settings, settingsExt); + Result result = frontend_1_1->tune_1_1(settings, settingsExt1_1); EXPECT_TRUE(result == Result::SUCCESS); android::Mutex::Autolock autoLock(mMsgLock); @@ -88,7 +88,7 @@ void FrontendCallback::scanTest(sp& frontend, FrontendConfig config, resetBlindScanStartingFrequency(config, targetFrequency - 100); } - Result result = frontend_1_1->scan_1_1(config.settings, type, config.settingsExt); + Result result = frontend_1_1->scan_1_1(config.settings, type, config.settingsExt1_1); EXPECT_TRUE(result == Result::SUCCESS); bool scanMsgLockedReceived = false; @@ -108,7 +108,7 @@ wait: if (mScanMessageType != FrontendScanMessageType::END) { if (mScanMessageType == FrontendScanMessageType::LOCKED) { scanMsgLockedReceived = true; - Result result = frontend_1_1->scan_1_1(config.settings, type, config.settingsExt); + Result result = frontend_1_1->scan_1_1(config.settings, type, config.settingsExt1_1); EXPECT_TRUE(result == Result::SUCCESS); } @@ -380,7 +380,7 @@ AssertionResult FrontendTests::tuneFrontend(FrontendConfig config, bool testWith return failure(); } } - mFrontendCallback->tuneTestOnLock(mFrontend, config.settings, config.settingsExt); + mFrontendCallback->tuneTestOnLock(mFrontend, config.settings, config.settingsExt1_1); return AssertionResult(true); } diff --git a/tv/tuner/1.1/vts/functional/FrontendTests.h b/tv/tuner/1.1/vts/functional/FrontendTests.h index 8986d8177a..4eec7a666c 100644 --- a/tv/tuner/1.1/vts/functional/FrontendTests.h +++ b/tv/tuner/1.1/vts/functional/FrontendTests.h @@ -72,7 +72,7 @@ class FrontendCallback : public IFrontendCallback { const FrontendScanMessage& message) override; void tuneTestOnLock(sp& frontend, FrontendSettings settings, - FrontendSettingsExt settingsExt); + FrontendSettingsExt1_1 settingsExt1_1); void scanTest(sp& frontend, FrontendConfig config, FrontendScanType type); // Helper methods diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp index f87fa3c0d6..5041741044 100644 --- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp @@ -142,13 +142,13 @@ TEST_P(TunerRecordHidlTest, RecordDataFlowWithTsRecordFilterTest) { recordSingleFilterTest(filterArray[TS_RECORD0], frontendArray[DVBT], dvrArray[DVR_RECORD0]); } -TEST_P(TunerFrontendHidlTest, TuneFrontendWithFrontendSettingsExt) { - description("Tune one Frontend with specific setting and check Lock event"); +TEST_P(TunerFrontendHidlTest, TuneFrontendWithFrontendSettingsExt1_1) { + description("Tune one Frontend with v1_1 extended setting and check Lock event"); mFrontendTests.tuneTest(frontendArray[DVBT]); } TEST_P(TunerFrontendHidlTest, BlindScanFrontendWithEndFrequency) { - description("Run an blind frontend scan with specific setting and check lock scanMessage"); + description("Run an blind frontend scan with v1_1 extended setting and check lock scanMessage"); mFrontendTests.scanTest(frontendScanArray[SCAN_DVBT], FrontendScanType::SCAN_BLIND); } diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h index 36b4bd2cb0..c6ebecb189 100644 --- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h @@ -48,7 +48,7 @@ using android::hardware::tv::tuner::V1_0::FrontendStatusType; using android::hardware::tv::tuner::V1_0::FrontendType; using android::hardware::tv::tuner::V1_0::PlaybackSettings; using android::hardware::tv::tuner::V1_0::RecordSettings; -using android::hardware::tv::tuner::V1_1::FrontendSettingsExt; +using android::hardware::tv::tuner::V1_1::FrontendSettingsExt1_1; using namespace std; @@ -100,7 +100,7 @@ struct FrontendConfig { bool isSoftwareFe; FrontendType type; FrontendSettings settings; - FrontendSettingsExt settingsExt; + FrontendSettingsExt1_1 settingsExt1_1; vector tuneStatusTypes; vector expectTuneStatuses; }; @@ -141,7 +141,7 @@ inline void initFrontendConfig() { frontendArray[DVBT].tuneStatusTypes = types; frontendArray[DVBT].expectTuneStatuses = statuses; frontendArray[DVBT].isSoftwareFe = true; - frontendArray[DVBT].settingsExt.settingExt.dvbt({ + frontendArray[DVBT].settingsExt1_1.settingExt.dvbt({ .transmissionMode = android::hardware::tv::tuner::V1_1::FrontendDvbtTransmissionMode::MODE_8K_E, }); @@ -164,8 +164,8 @@ inline void initFrontendScanConfig() { .isHighPriority = true, .standard = FrontendDvbtStandard::T, }); - frontendScanArray[SCAN_DVBT].settingsExt.endFrequency = 800000; - frontendScanArray[SCAN_DVBT].settingsExt.settingExt.dvbt({ + frontendScanArray[SCAN_DVBT].settingsExt1_1.endFrequency = 800000; + frontendScanArray[SCAN_DVBT].settingsExt1_1.settingExt.dvbt({ .transmissionMode = android::hardware::tv::tuner::V1_1::FrontendDvbtTransmissionMode::MODE_8K_E, }); -- GitLab From 343450a07409f015b041bbf8e9f6c095071ed5d3 Mon Sep 17 00:00:00 2001 From: Mikhail Naganov Date: Fri, 14 Aug 2020 00:16:09 +0000 Subject: [PATCH 181/790] audio: Implement VTS tests for V7.0 The major change in V7.0 is use of enum values defined in the Audio Policy Configuration XSD schema. This allows decoupling types used at the HIDL layer from system/audio.h. Added a header audio_policy_configuration_V7_0-enums.h with utility functions analogous to ones from system/audio.h but defined for the types generated from XSD schema. Since the code of VTS tests is shared between versions, ensured that the VTS tests for the previous HAL versions didn't regress. Bug: 142480271 Test: atest VtsHalAudioV6_0TargetTest atest VtsHalAudioEffectV6_0TargetTest atest VtsHalAudioV7_0TargetTest atest VtsHalAudioEffectV7_0TargetTest Change-Id: Ia7c2d49a02783725080c8fed6a25853e91bba487 --- audio/common/7.0/Android.bp | 5 +- .../audio_policy_configuration_V7_0-enums.h | 207 ++++++++++++ .../4.0/AudioPrimaryHidlHalTest.cpp | 100 +++++- .../functional/4.0/AudioPrimaryHidlHalUtils.h | 4 +- .../6.0/AudioPrimaryHidlHalTest.cpp | 45 ++- .../7.0/AudioPrimaryHidlHalTest.cpp | 98 ++++++ .../vts/functional/7.0/PolicyConfig.h | 91 ++++++ .../all-versions/vts/functional/Android.bp | 17 +- .../vts/functional/AudioPrimaryHidlHalTest.h | 300 ++++++++++-------- .../vts/functional/ConfigHelper.h | 26 +- .../vts/functional/DeviceManager.h | 9 +- .../vts/functional/PolicyConfig.h | 96 ++++++ .../all-versions/vts/functional/Android.bp | 2 +- .../VtsHalAudioEffectTargetTest.cpp | 41 ++- 14 files changed, 856 insertions(+), 185 deletions(-) create mode 100644 audio/common/7.0/enums/include/audio_policy_configuration_V7_0-enums.h create mode 100644 audio/core/all-versions/vts/functional/7.0/PolicyConfig.h create mode 100644 audio/core/all-versions/vts/functional/PolicyConfig.h diff --git a/audio/common/7.0/Android.bp b/audio/common/7.0/Android.bp index e24871c8b5..1c016b401b 100644 --- a/audio/common/7.0/Android.bp +++ b/audio/common/7.0/Android.bp @@ -16,9 +16,12 @@ hidl_interface { cc_library { name: "android.hardware.audio.common@7.0-enums", vendor_available: true, - generated_sources: ["audio_policy_configuration_V7_0"], generated_headers: ["audio_policy_configuration_V7_0"], + generated_sources: ["audio_policy_configuration_V7_0"], header_libs: ["libxsdc-utils"], + export_generated_headers: ["audio_policy_configuration_V7_0"], + export_header_lib_headers: ["libxsdc-utils"], + export_include_dirs: ["enums/include"], shared_libs: [ "libbase", "liblog", diff --git a/audio/common/7.0/enums/include/audio_policy_configuration_V7_0-enums.h b/audio/common/7.0/enums/include/audio_policy_configuration_V7_0-enums.h new file mode 100644 index 0000000000..d5fedce100 --- /dev/null +++ b/audio/common/7.0/enums/include/audio_policy_configuration_V7_0-enums.h @@ -0,0 +1,207 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AUDIO_POLICY_CONFIGURATION_V7_0_ENUMS_H +#define AUDIO_POLICY_CONFIGURATION_V7_0_ENUMS_H + +#include + +#include + +namespace audio::policy::configuration::V7_0 { + +static inline size_t getChannelCount(AudioChannelMask mask) { + switch (mask) { + case AudioChannelMask::AUDIO_CHANNEL_OUT_MONO: + case AudioChannelMask::AUDIO_CHANNEL_IN_MONO: + case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_1: + return 1; + case AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO: + case AudioChannelMask::AUDIO_CHANNEL_OUT_MONO_HAPTIC_A: + case AudioChannelMask::AUDIO_CHANNEL_OUT_HAPTIC_AB: + case AudioChannelMask::AUDIO_CHANNEL_IN_STEREO: + case AudioChannelMask::AUDIO_CHANNEL_IN_FRONT_BACK: + case AudioChannelMask::AUDIO_CHANNEL_IN_VOICE_UPLINK_MONO: + case AudioChannelMask::AUDIO_CHANNEL_IN_VOICE_DNLINK_MONO: + case AudioChannelMask::AUDIO_CHANNEL_IN_VOICE_CALL_MONO: + case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_2: + return 2; + case AudioChannelMask::AUDIO_CHANNEL_OUT_2POINT1: + case AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO_HAPTIC_A: + case AudioChannelMask::AUDIO_CHANNEL_OUT_MONO_HAPTIC_AB: + case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_3: + return 3; + case AudioChannelMask::AUDIO_CHANNEL_OUT_2POINT0POINT2: + case AudioChannelMask::AUDIO_CHANNEL_OUT_QUAD: + case AudioChannelMask::AUDIO_CHANNEL_OUT_QUAD_BACK: + case AudioChannelMask::AUDIO_CHANNEL_OUT_QUAD_SIDE: + case AudioChannelMask::AUDIO_CHANNEL_OUT_SURROUND: + case AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO_HAPTIC_AB: + case AudioChannelMask::AUDIO_CHANNEL_IN_2POINT0POINT2: + case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_4: + return 4; + case AudioChannelMask::AUDIO_CHANNEL_OUT_2POINT1POINT2: + case AudioChannelMask::AUDIO_CHANNEL_OUT_3POINT0POINT2: + case AudioChannelMask::AUDIO_CHANNEL_OUT_PENTA: + case AudioChannelMask::AUDIO_CHANNEL_IN_2POINT1POINT2: + case AudioChannelMask::AUDIO_CHANNEL_IN_3POINT0POINT2: + case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_5: + return 5; + case AudioChannelMask::AUDIO_CHANNEL_OUT_3POINT1POINT2: + case AudioChannelMask::AUDIO_CHANNEL_OUT_5POINT1: + case AudioChannelMask::AUDIO_CHANNEL_OUT_5POINT1_BACK: + case AudioChannelMask::AUDIO_CHANNEL_OUT_5POINT1_SIDE: + case AudioChannelMask::AUDIO_CHANNEL_IN_6: + case AudioChannelMask::AUDIO_CHANNEL_IN_3POINT1POINT2: + case AudioChannelMask::AUDIO_CHANNEL_IN_5POINT1: + case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_6: + return 6; + case AudioChannelMask::AUDIO_CHANNEL_OUT_6POINT1: + case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_7: + return 7; + case AudioChannelMask::AUDIO_CHANNEL_OUT_5POINT1POINT2: + case AudioChannelMask::AUDIO_CHANNEL_OUT_7POINT1: + case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_8: + return 8; + case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_9: + return 9; + case AudioChannelMask::AUDIO_CHANNEL_OUT_5POINT1POINT4: + case AudioChannelMask::AUDIO_CHANNEL_OUT_7POINT1POINT2: + case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_10: + return 10; + case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_11: + return 11; + case AudioChannelMask::AUDIO_CHANNEL_OUT_7POINT1POINT4: + case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_12: + return 12; + case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_13: + return 13; + case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_14: + return 14; + case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_15: + return 15; + case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_16: + return 16; + case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_17: + return 17; + case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_18: + return 18; + case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_19: + return 19; + case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_20: + return 20; + case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_21: + return 21; + case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_22: + return 22; + case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_23: + return 23; + case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_24: + return 24; + case AudioChannelMask::UNKNOWN: + return 0; + // No default to make sure all cases are covered. + } + // This is to avoid undefined behavior if 'mask' isn't a valid enum value. + return 0; +} + +static inline ssize_t getChannelCount(const std::string& mask) { + return getChannelCount(stringToAudioChannelMask(mask)); +} + +static inline bool isOutputDevice(AudioDevice device) { + switch (device) { + case AudioDevice::UNKNOWN: + case AudioDevice::AUDIO_DEVICE_NONE: + return false; + case AudioDevice::AUDIO_DEVICE_OUT_EARPIECE: + case AudioDevice::AUDIO_DEVICE_OUT_SPEAKER: + case AudioDevice::AUDIO_DEVICE_OUT_WIRED_HEADSET: + case AudioDevice::AUDIO_DEVICE_OUT_WIRED_HEADPHONE: + case AudioDevice::AUDIO_DEVICE_OUT_BLUETOOTH_SCO: + case AudioDevice::AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET: + case AudioDevice::AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT: + case AudioDevice::AUDIO_DEVICE_OUT_BLUETOOTH_A2DP: + case AudioDevice::AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES: + case AudioDevice::AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER: + case AudioDevice::AUDIO_DEVICE_OUT_AUX_DIGITAL: + case AudioDevice::AUDIO_DEVICE_OUT_HDMI: + case AudioDevice::AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET: + case AudioDevice::AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET: + case AudioDevice::AUDIO_DEVICE_OUT_USB_ACCESSORY: + case AudioDevice::AUDIO_DEVICE_OUT_USB_DEVICE: + case AudioDevice::AUDIO_DEVICE_OUT_REMOTE_SUBMIX: + case AudioDevice::AUDIO_DEVICE_OUT_TELEPHONY_TX: + case AudioDevice::AUDIO_DEVICE_OUT_LINE: + case AudioDevice::AUDIO_DEVICE_OUT_HDMI_ARC: + case AudioDevice::AUDIO_DEVICE_OUT_SPDIF: + case AudioDevice::AUDIO_DEVICE_OUT_FM: + case AudioDevice::AUDIO_DEVICE_OUT_AUX_LINE: + case AudioDevice::AUDIO_DEVICE_OUT_SPEAKER_SAFE: + case AudioDevice::AUDIO_DEVICE_OUT_IP: + case AudioDevice::AUDIO_DEVICE_OUT_BUS: + case AudioDevice::AUDIO_DEVICE_OUT_PROXY: + case AudioDevice::AUDIO_DEVICE_OUT_USB_HEADSET: + case AudioDevice::AUDIO_DEVICE_OUT_HEARING_AID: + case AudioDevice::AUDIO_DEVICE_OUT_ECHO_CANCELLER: + case AudioDevice::AUDIO_DEVICE_OUT_DEFAULT: + case AudioDevice::AUDIO_DEVICE_OUT_STUB: + return true; + case AudioDevice::AUDIO_DEVICE_IN_COMMUNICATION: + case AudioDevice::AUDIO_DEVICE_IN_AMBIENT: + case AudioDevice::AUDIO_DEVICE_IN_BUILTIN_MIC: + case AudioDevice::AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET: + case AudioDevice::AUDIO_DEVICE_IN_WIRED_HEADSET: + case AudioDevice::AUDIO_DEVICE_IN_AUX_DIGITAL: + case AudioDevice::AUDIO_DEVICE_IN_HDMI: + case AudioDevice::AUDIO_DEVICE_IN_VOICE_CALL: + case AudioDevice::AUDIO_DEVICE_IN_TELEPHONY_RX: + case AudioDevice::AUDIO_DEVICE_IN_BACK_MIC: + case AudioDevice::AUDIO_DEVICE_IN_REMOTE_SUBMIX: + case AudioDevice::AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET: + case AudioDevice::AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET: + case AudioDevice::AUDIO_DEVICE_IN_USB_ACCESSORY: + case AudioDevice::AUDIO_DEVICE_IN_USB_DEVICE: + case AudioDevice::AUDIO_DEVICE_IN_FM_TUNER: + case AudioDevice::AUDIO_DEVICE_IN_TV_TUNER: + case AudioDevice::AUDIO_DEVICE_IN_LINE: + case AudioDevice::AUDIO_DEVICE_IN_SPDIF: + case AudioDevice::AUDIO_DEVICE_IN_BLUETOOTH_A2DP: + case AudioDevice::AUDIO_DEVICE_IN_LOOPBACK: + case AudioDevice::AUDIO_DEVICE_IN_IP: + case AudioDevice::AUDIO_DEVICE_IN_BUS: + case AudioDevice::AUDIO_DEVICE_IN_PROXY: + case AudioDevice::AUDIO_DEVICE_IN_USB_HEADSET: + case AudioDevice::AUDIO_DEVICE_IN_BLUETOOTH_BLE: + case AudioDevice::AUDIO_DEVICE_IN_HDMI_ARC: + case AudioDevice::AUDIO_DEVICE_IN_ECHO_REFERENCE: + case AudioDevice::AUDIO_DEVICE_IN_DEFAULT: + case AudioDevice::AUDIO_DEVICE_IN_STUB: + return false; + // No default to make sure all cases are covered. + } + // This is to avoid undefined behavior if 'device' isn't a valid enum value. + return false; +} + +static inline bool isOutputDevice(const std::string& device) { + return isOutputDevice(stringToAudioDevice(device)); +} + +} // namespace audio::policy::configuration::V7_0 + +#endif // AUDIO_POLICY_CONFIGURATION_V7_0_ENUMS_H diff --git a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp index b0eb2e0cfb..2466fd120a 100644 --- a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp +++ b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp @@ -16,6 +16,13 @@ #include "AudioPrimaryHidlHalTest.h" +#if MAJOR_VERSION >= 7 +#include +#include + +using android::xsdc_enum_range; +#endif + TEST_P(AudioHidlTest, OpenPrimaryDeviceUsingGetDevice) { doc::test("Calling openDevice(\"primary\") should return the primary device."); if (getDeviceName() != DeviceManager::kPrimaryDevice) { @@ -53,14 +60,29 @@ TEST_P(AudioHidlDeviceTest, GetMicrophonesTest) { "Make sure getMicrophones always succeeds" "and getActiveMicrophones always succeeds when recording from these microphones."); AudioConfig config{}; +#if MAJOR_VERSION <= 6 config.channelMask = mkEnumBitfield(AudioChannelMask::IN_MONO); config.sampleRateHz = 8000; config.format = AudioFormat::PCM_16_BIT; auto flags = hidl_bitfield(AudioInputFlag::NONE); const SinkMetadata initMetadata = {{{.source = AudioSource::MIC, .gain = 1}}}; +#elif MAJOR_VERSION >= 7 + config.base.channelMask.resize(1); + config.base.channelMask[0] = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_IN_MONO); + config.base.sampleRateHz = 8000; + config.base.format = toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT); + hidl_vec flags; + const SinkMetadata initMetadata = { + {{.source = toString(xsd::AudioSource::AUDIO_SOURCE_MIC), .gain = 1}}}; +#endif EventFlag* efGroup; for (auto microphone : microphones) { +#if MAJOR_VERSION <= 6 if (microphone.deviceAddress.device != AudioDevice::IN_BUILTIN_MIC) { +#elif MAJOR_VERSION >= 7 + if (xsd::stringToAudioDevice(microphone.deviceAddress.deviceType) != + xsd::AudioDevice::AUDIO_DEVICE_IN_BUILTIN_MIC) { +#endif continue; } sp stream; @@ -81,16 +103,16 @@ TEST_P(AudioHidlDeviceTest, GetMicrophonesTest) { size_t frameSize = stream->getFrameSize(); size_t frameCount = stream->getBufferSize() / frameSize; ASSERT_OK(stream->prepareForReading( - frameSize, frameCount, [&](auto r, auto& c, auto& d, auto&, auto&) { - readRes = r; - if (readRes == Result::OK) { - commandMQ.reset(new CommandMQ(c)); - dataMQ.reset(new DataMQ(d)); - if (dataMQ->isValid() && dataMQ->getEventFlagWord()) { - EventFlag::createEventFlag(dataMQ->getEventFlagWord(), &efGroup); + frameSize, frameCount, [&](auto r, auto& c, auto& d, auto&, auto) { + readRes = r; + if (readRes == Result::OK) { + commandMQ.reset(new CommandMQ(c)); + dataMQ.reset(new DataMQ(d)); + if (dataMQ->isValid() && dataMQ->getEventFlagWord()) { + EventFlag::createEventFlag(dataMQ->getEventFlagWord(), &efGroup); + } } - } - })); + })); ASSERT_OK(readRes); IStreamIn::ReadParameters params; params.command = IStreamIn::ReadCommand::READ; @@ -116,13 +138,24 @@ TEST_P(AudioHidlDeviceTest, GetMicrophonesTest) { TEST_P(AudioHidlDeviceTest, SetConnectedState) { doc::test("Check that the HAL can be notified of device connection and deconnection"); +#if MAJOR_VERSION <= 6 using AD = AudioDevice; for (auto deviceType : {AD::OUT_HDMI, AD::OUT_WIRED_HEADPHONE, AD::IN_USB_HEADSET}) { +#elif MAJOR_VERSION >= 7 + using AD = xsd::AudioDevice; + for (auto deviceType : + {toString(AD::AUDIO_DEVICE_OUT_HDMI), toString(AD::AUDIO_DEVICE_OUT_WIRED_HEADPHONE), + toString(AD::AUDIO_DEVICE_IN_USB_HEADSET)}) { +#endif SCOPED_TRACE("device=" + ::testing::PrintToString(deviceType)); for (bool state : {true, false}) { SCOPED_TRACE("state=" + ::testing::PrintToString(state)); DeviceAddress address = {}; +#if MAJOR_VERSION <= 6 address.device = deviceType; +#elif MAJOR_VERSION >= 7 + address.deviceType = deviceType; +#endif auto ret = getDevice()->setConnectedState(address, state); ASSERT_TRUE(ret.isOk()); if (ret == Result::NOT_SUPPORTED) { @@ -148,7 +181,11 @@ static void testGetDevices(IStream* stream, AudioDevice expectedDevice) { } // The stream was constructed with one device, thus getDevices must only return one ASSERT_EQ(1U, devices.size()); +#if MAJOR_VERSION <= 6 AudioDevice device = devices[0].device; +#elif MAJOR_VERSION >= 7 + auto device = devices[0].deviceType; +#endif ASSERT_TRUE(device == expectedDevice) << "Expected: " << ::testing::PrintToString(expectedDevice) << "\n Actual: " << ::testing::PrintToString(device); @@ -156,12 +193,22 @@ static void testGetDevices(IStream* stream, AudioDevice expectedDevice) { TEST_IO_STREAM(GetDevices, "Check that the stream device == the one it was opened with", areAudioPatchesSupported() ? doc::partialTest("Audio patches are supported") +#if MAJOR_VERSION <= 6 : testGetDevices(stream.get(), address.device)) +#elif MAJOR_VERSION >= 7 + : testGetDevices(stream.get(), address.deviceType)) +#endif static void testSetDevices(IStream* stream, const DeviceAddress& address) { DeviceAddress otherAddress = address; +#if MAJOR_VERSION <= 6 otherAddress.device = (address.device & AudioDevice::BIT_IN) == 0 ? AudioDevice::OUT_SPEAKER : AudioDevice::IN_BUILTIN_MIC; +#elif MAJOR_VERSION >= 7 + otherAddress.deviceType = xsd::isOutputDevice(address.deviceType) + ? toString(xsd::AudioDevice::AUDIO_DEVICE_OUT_SPEAKER) + : toString(xsd::AudioDevice::AUDIO_DEVICE_IN_BUILTIN_MIC); +#endif EXPECT_RESULT(okOrNotSupported, stream->setDevices({otherAddress})); ASSERT_RESULT(okOrNotSupported, @@ -186,11 +233,19 @@ TEST_IO_STREAM(GetHwAvSync, "Get hardware sync can not fail", checkGetHwAVSync(g TEST_P(InputStreamTest, updateSinkMetadata) { doc::test("The HAL should not crash on metadata change"); +#if MAJOR_VERSION <= 6 hidl_enum_range range; +#elif MAJOR_VERSION >= 7 + xsdc_enum_range range; +#endif // Test all possible track configuration - for (AudioSource source : range) { + for (auto source : range) { for (float volume : {0.0, 0.5, 1.0}) { +#if MAJOR_VERSION <= 6 const SinkMetadata metadata = {{{.source = source, .gain = volume}}}; +#elif MAJOR_VERSION >= 7 + const SinkMetadata metadata = {{{.source = toString(source), .gain = volume}}}; +#endif ASSERT_OK(stream->updateSinkMetadata(metadata)) << "source=" << toString(source) << ", volume=" << volume; } @@ -213,13 +268,22 @@ TEST_P(OutputStreamTest, SelectPresentation) { TEST_P(OutputStreamTest, updateSourceMetadata) { doc::test("The HAL should not crash on metadata change"); +#if MAJOR_VERSION <= 6 hidl_enum_range usageRange; hidl_enum_range contentRange; +#elif MAJOR_VERSION >= 7 + xsdc_enum_range usageRange; + xsdc_enum_range contentRange; +#endif // Test all possible track configuration for (auto usage : usageRange) { for (auto content : contentRange) { for (float volume : {0.0, 0.5, 1.0}) { +#if MAJOR_VERSION <= 6 const SourceMetadata metadata = {{{usage, content, volume}}}; +#elif MAJOR_VERSION >= 7 + const SourceMetadata metadata = {{{toString(usage), toString(content), volume}}}; +#endif ASSERT_OK(stream->updateSourceMetadata(metadata)) << "usage=" << toString(usage) << ", content=" << toString(content) << ", volume=" << volume; @@ -227,12 +291,26 @@ TEST_P(OutputStreamTest, updateSourceMetadata) { } } + // clang-format off // Set many track of different configuration ASSERT_OK(stream->updateSourceMetadata( +#if MAJOR_VERSION <= 6 {{{AudioUsage::MEDIA, AudioContentType::MUSIC, 0.1}, {AudioUsage::VOICE_COMMUNICATION, AudioContentType::SPEECH, 1.0}, {AudioUsage::ALARM, AudioContentType::SONIFICATION, 0.0}, - {AudioUsage::ASSISTANT, AudioContentType::UNKNOWN, 0.3}}})); + {AudioUsage::ASSISTANT, AudioContentType::UNKNOWN, 0.3}}} +#elif MAJOR_VERSION >= 7 + {{{toString(xsd::AudioUsage::AUDIO_USAGE_MEDIA), + toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_MUSIC), 0.1}, + {toString(xsd::AudioUsage::AUDIO_USAGE_VOICE_COMMUNICATION), + toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_SPEECH), 1.0}, + {toString(xsd::AudioUsage::AUDIO_USAGE_ALARM), + toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_SONIFICATION), 0.0}, + {toString(xsd::AudioUsage::AUDIO_USAGE_ASSISTANT), + toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_UNKNOWN), 0.3}}} +#endif + )); + // clang-format on // Set no metadata as if all stream track had stopped ASSERT_OK(stream->updateSourceMetadata({})); diff --git a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalUtils.h b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalUtils.h index 7a52d0e364..81a1f7b4b7 100644 --- a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalUtils.h +++ b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalUtils.h @@ -56,6 +56,7 @@ struct Parameters { } }; +#if MAJOR_VERSION <= 6 struct GetSupported { static auto getFormat(IStream* stream) { auto ret = stream->getFormat(); @@ -80,7 +81,7 @@ struct GetSupported { EXPECT_OK(stream->getSupportedFormats(returnIn(capabilities))); return Result::OK; } -#elif MAJOR_VERSION >= 6 +#else // MAJOR_VERSION == 6 static Result formats(IStream* stream, hidl_vec& capabilities) { Result res; EXPECT_OK(stream->getSupportedFormats(returnIn(res, capabilities))); @@ -88,6 +89,7 @@ struct GetSupported { } #endif }; +#endif // MAJOR_VERSION <= 6 template auto dump(T t, hidl_handle handle) { diff --git a/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp index 54d4bbd2cc..bd8de2d0e6 100644 --- a/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp +++ b/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp @@ -17,6 +17,7 @@ // pull in all the <= 5.0 tests #include "5.0/AudioPrimaryHidlHalTest.cpp" +#if MAJOR_VERSION <= 6 const std::vector& getOutputDeviceConfigParameters() { static std::vector parameters = [] { std::vector result; @@ -28,8 +29,8 @@ const std::vector& getOutputDeviceConfigParameters() { const auto& channels = profile->getChannels(); const auto& sampleRates = profile->getSampleRates(); auto configs = ConfigHelper::combineAudioConfig( - vector(channels.begin(), channels.end()), - vector(sampleRates.begin(), sampleRates.end()), + std::vector(channels.begin(), channels.end()), + std::vector(sampleRates.begin(), sampleRates.end()), profile->getFormat()); auto flags = ioProfile->getFlags(); for (auto& config : configs) { @@ -46,8 +47,8 @@ const std::vector& getOutputDeviceConfigParameters() { config.offloadInfo.bufferSize = 256; // arbitrary value config.offloadInfo.usage = AudioUsage::MEDIA; result.emplace_back(device, config, - AudioOutputFlag(AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD | - AUDIO_OUTPUT_FLAG_DIRECT)); + AudioOutputFlag(AudioOutputFlag::COMPRESS_OFFLOAD | + AudioOutputFlag::DIRECT)); } else { if (flags & AUDIO_OUTPUT_FLAG_PRIMARY) { // ignore the flag flags &= ~AUDIO_OUTPUT_FLAG_PRIMARY; @@ -74,8 +75,8 @@ const std::vector& getInputDeviceConfigParameters() { const auto& channels = profile->getChannels(); const auto& sampleRates = profile->getSampleRates(); auto configs = ConfigHelper::combineAudioConfig( - vector(channels.begin(), channels.end()), - vector(sampleRates.begin(), sampleRates.end()), + std::vector(channels.begin(), channels.end()), + std::vector(sampleRates.begin(), sampleRates.end()), profile->getFormat()); for (const auto& config : configs) { result.emplace_back(device, config, AudioInputFlag(ioProfile->getFlags())); @@ -87,13 +88,22 @@ const std::vector& getInputDeviceConfigParameters() { }(); return parameters; } +#endif // MAJOR_VERSION <= 6 TEST_P(AudioHidlDeviceTest, CloseDeviceWithOpenedOutputStreams) { doc::test("Verify that a device can't be closed if there are streams opened"); +#if MAJOR_VERSION <= 6 DeviceAddress address{.device = AudioDevice::OUT_DEFAULT}; - AudioConfig config{}; - auto flags = hidl_bitfield(AudioOutputFlag::NONE); SourceMetadata initMetadata = {{{AudioUsage::MEDIA, AudioContentType::MUSIC, 1 /* gain */}}}; + auto flags = hidl_bitfield(AudioOutputFlag::NONE); +#elif MAJOR_VERSION >= 7 + DeviceAddress address{.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_OUT_DEFAULT)}; + SourceMetadata initMetadata = { + {{toString(xsd::AudioUsage::AUDIO_USAGE_MEDIA), + toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_MUSIC), 1 /* gain */}}}; + hidl_vec flags; +#endif + AudioConfig config{}; sp stream; StreamHelper helper(stream); AudioConfig suggestedConfig{}; @@ -111,14 +121,20 @@ TEST_P(AudioHidlDeviceTest, CloseDeviceWithOpenedOutputStreams) { TEST_P(AudioHidlDeviceTest, CloseDeviceWithOpenedInputStreams) { doc::test("Verify that a device can't be closed if there are streams opened"); - auto module = getCachedPolicyConfig().getModuleFromName(getDeviceName()); - if (module->getInputProfiles().empty()) { + if (!getCachedPolicyConfig().haveInputProfilesInModule(getDeviceName())) { GTEST_SKIP() << "Device doesn't have input profiles"; } +#if MAJOR_VERSION <= 6 DeviceAddress address{.device = AudioDevice::IN_DEFAULT}; - AudioConfig config{}; - auto flags = hidl_bitfield(AudioInputFlag::NONE); SinkMetadata initMetadata = {{{.source = AudioSource::MIC, .gain = 1}}}; + auto flags = hidl_bitfield(AudioInputFlag::NONE); +#elif MAJOR_VERSION >= 7 + DeviceAddress address{.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_IN_DEFAULT)}; + SinkMetadata initMetadata = { + {{.source = toString(xsd::AudioSource::AUDIO_SOURCE_MIC), .gain = 1}}}; + hidl_vec flags; +#endif + AudioConfig config{}; sp stream; StreamHelper helper(stream); AudioConfig suggestedConfig{}; @@ -137,9 +153,8 @@ TEST_P(AudioHidlDeviceTest, CloseDeviceWithOpenedInputStreams) { TEST_P(AudioPatchHidlTest, UpdatePatchInvalidHandle) { doc::test("Verify that passing an invalid handle to updateAudioPatch is checked"); AudioPatchHandle ignored; - ASSERT_OK(getDevice()->updateAudioPatch( - static_cast(AudioHandleConsts::AUDIO_PATCH_HANDLE_NONE), - hidl_vec(), hidl_vec(), returnIn(res, ignored))); + ASSERT_OK(getDevice()->updateAudioPatch(AudioPatchHandle{}, hidl_vec(), + hidl_vec(), returnIn(res, ignored))); ASSERT_RESULT(Result::INVALID_ARGUMENTS, res); } diff --git a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp index 33efa6f4d6..63eaea8acc 100644 --- a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp +++ b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp @@ -16,3 +16,101 @@ // pull in all the <= 6.0 tests #include "6.0/AudioPrimaryHidlHalTest.cpp" + +static std::vector combineAudioConfig(std::vector channelMasks, + std::vector sampleRates, + const std::string& format) { + std::vector configs; + configs.reserve(channelMasks.size() * sampleRates.size()); + for (auto channelMask : channelMasks) { + for (auto sampleRate : sampleRates) { + AudioConfig config{}; + // leave offloadInfo to 0 + config.base.channelMask.resize(1); + config.base.channelMask[0] = toString(channelMask); + config.base.sampleRateHz = sampleRate; + config.base.format = format; + configs.push_back(config); + } + } + return configs; +} + +const std::vector& getOutputDeviceConfigParameters() { + static std::vector parameters = [] { + std::vector result; + const std::vector offloadFlags = { + toString(xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD), + toString(xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_DIRECT)}; + for (const auto& device : getDeviceParameters()) { + auto module = + getCachedPolicyConfig().getModuleFromName(std::get(device)); + for (const auto& mixPort : module->getFirstMixPorts()->getMixPort()) { + if (mixPort.getRole() != xsd::Role::source) continue; // not an output profile + auto xsdFlags = mixPort.getFlags(); + const bool isOffload = + std::find(xsdFlags.begin(), xsdFlags.end(), + xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != + xsdFlags.end(); + std::vector flags; + if (!isOffload) { + for (auto flag : xsdFlags) { + if (flag != xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_PRIMARY) { + flags.push_back(toString(flag)); + } + } + } else { + flags = offloadFlags; + } + for (const auto& profile : mixPort.getProfile()) { + auto configs = + combineAudioConfig(profile.getChannelMasks(), + profile.getSamplingRates(), profile.getFormat()); + for (auto& config : configs) { + // Some combinations of flags declared in the config file require special + // treatment. + if (isOffload) { + config.offloadInfo.base = config.base; + config.offloadInfo.streamType = + toString(xsd::AudioStreamType::AUDIO_STREAM_MUSIC); + config.offloadInfo.usage = toString(xsd::AudioUsage::AUDIO_USAGE_MEDIA); + config.offloadInfo.bitRatePerSecond = 320; + config.offloadInfo.durationMicroseconds = -1; + config.offloadInfo.bitWidth = 16; + config.offloadInfo.bufferSize = 256; // arbitrary value + } + result.emplace_back(device, config, flags); + } + } + } + } + return result; + }(); + return parameters; +} + +const std::vector& getInputDeviceConfigParameters() { + static std::vector parameters = [] { + std::vector result; + for (const auto& device : getDeviceParameters()) { + auto module = + getCachedPolicyConfig().getModuleFromName(std::get(device)); + for (const auto& mixPort : module->getFirstMixPorts()->getMixPort()) { + if (mixPort.getRole() != xsd::Role::sink) continue; // not an input profile + std::vector flags; + std::transform(mixPort.getFlags().begin(), mixPort.getFlags().end(), flags.begin(), + [](auto flag) { return toString(flag); }); + for (const auto& profile : mixPort.getProfile()) { + auto configs = + combineAudioConfig(profile.getChannelMasks(), + profile.getSamplingRates(), profile.getFormat()); + for (const auto& config : configs) { + result.emplace_back(device, config, flags); + } + } + } + } + return result; + }(); + return parameters; +} diff --git a/audio/core/all-versions/vts/functional/7.0/PolicyConfig.h b/audio/core/all-versions/vts/functional/7.0/PolicyConfig.h new file mode 100644 index 0000000000..d790b34c46 --- /dev/null +++ b/audio/core/all-versions/vts/functional/7.0/PolicyConfig.h @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +// Note: it is assumed that this file is included from AudioPrimaryHidlTest.h +// and thus it doesn't have all '#include' and 'using' directives required +// for a standalone compilation. + +namespace xsd { +using Module = Modules::Module; +} + +class PolicyConfig { + public: + explicit PolicyConfig(const std::string& configFileName) + : mConfigFileName{configFileName}, + mFilePath{findExistingConfigurationFile(mConfigFileName)}, + mConfig{xsd::read(mFilePath.c_str())} { + if (mConfig) { + mStatus = OK; + mPrimaryModule = getModuleFromName(DeviceManager::kPrimaryDevice); + for (const auto& module : mConfig->getFirstModules()->get_module()) { + auto attachedDevices = module.getFirstAttachedDevices()->getItem(); + if (!attachedDevices.empty()) { + mModulesWithDevicesNames.insert(module.getName()); + } + } + } + } + status_t getStatus() const { return mStatus; } + std::string getError() const { + if (mFilePath.empty()) { + return std::string{"Could not find "} + mConfigFileName + + " file in: " + testing::PrintToString(android::audio_get_configuration_paths()); + } else { + return "Invalid config file: " + mFilePath; + } + } + const std::string& getFilePath() const { return mFilePath; } + const xsd::Module* getModuleFromName(const std::string& name) const { + if (mConfig) { + for (const auto& module : mConfig->getFirstModules()->get_module()) { + if (module.getName() == name) return &module; + } + } + return nullptr; + } + const xsd::Module* getPrimaryModule() const { return mPrimaryModule; } + const std::set& getModulesWithDevicesNames() const { + return mModulesWithDevicesNames; + } + bool haveInputProfilesInModule(const std::string& name) const { + auto module = getModuleFromName(name); + for (const auto& mixPort : module->getFirstMixPorts()->getMixPort()) { + if (mixPort.getRole() == xsd::Role::sink) return true; + } + return false; + } + + private: + static std::string findExistingConfigurationFile(const std::string& fileName) { + for (const auto& location : android::audio_get_configuration_paths()) { + std::string path = location + '/' + fileName; + if (access(path.c_str(), F_OK) == 0) { + return path; + } + } + return std::string{}; + } + + const std::string mConfigFileName; + const std::string mFilePath; + std::optional mConfig; + status_t mStatus = NO_INIT; + const xsd::Module* mPrimaryModule; + std::set mModulesWithDevicesNames; +}; diff --git a/audio/core/all-versions/vts/functional/Android.bp b/audio/core/all-versions/vts/functional/Android.bp index 6ac9b20f95..c7bfe08889 100644 --- a/audio/core/all-versions/vts/functional/Android.bp +++ b/audio/core/all-versions/vts/functional/Android.bp @@ -19,9 +19,6 @@ cc_defaults { defaults: ["VtsHalTargetTestDefaults"], static_libs: [ "android.hardware.audio.common.test.utility", - "libaudiofoundation", - "libaudiopolicycomponents", - "libmedia_helper", "libxml2", ], shared_libs: [ @@ -44,6 +41,9 @@ cc_test { "2.0/AudioPrimaryHidlHalTest.cpp", ], static_libs: [ + "libaudiofoundation", + "libaudiopolicycomponents", + "libmedia_helper", "android.hardware.audio@2.0", "android.hardware.audio.common@2.0", ], @@ -67,6 +67,9 @@ cc_test { "4.0/AudioPrimaryHidlHalTest.cpp", ], static_libs: [ + "libaudiofoundation", + "libaudiopolicycomponents", + "libmedia_helper", "android.hardware.audio@4.0", "android.hardware.audio.common@4.0", ], @@ -90,6 +93,9 @@ cc_test { "5.0/AudioPrimaryHidlHalTest.cpp", ], static_libs: [ + "libaudiofoundation", + "libaudiopolicycomponents", + "libmedia_helper", "android.hardware.audio@5.0", "android.hardware.audio.common@5.0", ], @@ -113,6 +119,9 @@ cc_test { "6.0/AudioPrimaryHidlHalTest.cpp", ], static_libs: [ + "libaudiofoundation", + "libaudiopolicycomponents", + "libmedia_helper", "android.hardware.audio@6.0", "android.hardware.audio.common@6.0", ], @@ -130,7 +139,6 @@ cc_test { } cc_test { - enabled: false, name: "VtsHalAudioV7_0TargetTest", defaults: ["VtsHalAudioTargetTest_defaults"], srcs: [ @@ -139,6 +147,7 @@ cc_test { static_libs: [ "android.hardware.audio@7.0", "android.hardware.audio.common@7.0", + "android.hardware.audio.common@7.0-enums", ], cflags: [ "-DMAJOR_VERSION=7", diff --git a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h index 01bdd69408..5e4b414d29 100644 --- a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h +++ b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h @@ -42,8 +42,11 @@ #include PATH(android/hardware/audio/FILE_VERSION/IPrimaryDevice.h) #include PATH(android/hardware/audio/FILE_VERSION/types.h) #include PATH(android/hardware/audio/common/FILE_VERSION/types.h) +#if MAJOR_VERSION >= 7 +#include +#include +#endif -#include #include #include #include @@ -63,14 +66,6 @@ #include "4.0/AudioPrimaryHidlHalUtils.h" #endif -using std::initializer_list; -using std::list; -using std::string; -using std::to_string; -using std::vector; - -using ::android::AudioPolicyConfig; -using ::android::HwModule; using ::android::NO_INIT; using ::android::OK; using ::android::sp; @@ -93,6 +88,12 @@ using ::android::hardware::details::toHexString; using namespace ::android::hardware::audio::common::CPP_VERSION; using namespace ::android::hardware::audio::common::test::utility; using namespace ::android::hardware::audio::CPP_VERSION; +#if MAJOR_VERSION >= 7 +// Make an alias for enumerations generated from the APM config XSD. +namespace xsd { +using namespace ::audio::policy::configuration::CPP_VERSION; +} +#endif // Typical accepted results from interface methods static auto okOrNotSupported = {Result::OK, Result::NOT_SUPPORTED}; @@ -103,8 +104,12 @@ static auto okOrInvalidStateOrNotSupported = {Result::OK, Result::INVALID_STATE, static auto invalidArgsOrNotSupported = {Result::INVALID_ARGUMENTS, Result::NOT_SUPPORTED}; static auto invalidStateOrNotSupported = {Result::INVALID_STATE, Result::NOT_SUPPORTED}; -#define AUDIO_PRIMARY_HIDL_HAL_TEST #include "DeviceManager.h" +#if MAJOR_VERSION <= 6 +#include "PolicyConfig.h" +#elif MAJOR_VERSION >= 7 +#include "7.0/PolicyConfig.h" +#endif class HidlTest : public ::testing::Test { public: @@ -136,83 +141,16 @@ class HidlTest : public ::testing::Test { ////////////////////////// Audio policy configuration //////////////////////// ////////////////////////////////////////////////////////////////////////////// -static constexpr char kConfigFileName[] = "audio_policy_configuration.xml"; - // Stringify the argument. #define QUOTE(x) #x #define STRINGIFY(x) QUOTE(x) -struct PolicyConfigData { - android::HwModuleCollection hwModules; - android::DeviceVector availableOutputDevices; - android::DeviceVector availableInputDevices; - sp defaultOutputDevice; -}; - -class PolicyConfig : private PolicyConfigData, public AudioPolicyConfig { - public: - PolicyConfig() - : AudioPolicyConfig(hwModules, availableOutputDevices, availableInputDevices, - defaultOutputDevice) { - for (const auto& location : android::audio_get_configuration_paths()) { - std::string path = location + '/' + kConfigFileName; - if (access(path.c_str(), F_OK) == 0) { - mFilePath = path; - break; - } - } - mStatus = android::deserializeAudioPolicyFile(mFilePath.c_str(), this); - if (mStatus == OK) { - mPrimaryModule = getHwModules().getModuleFromName(DeviceManager::kPrimaryDevice); - // Available devices are not 'attached' to modules at this moment. - // Need to go over available devices and find their module. - for (const auto& device : availableOutputDevices) { - for (const auto& module : hwModules) { - if (module->getDeclaredDevices().indexOf(device) >= 0) { - mModulesWithDevicesNames.insert(module->getName()); - break; - } - } - } - for (const auto& device : availableInputDevices) { - for (const auto& module : hwModules) { - if (module->getDeclaredDevices().indexOf(device) >= 0) { - mModulesWithDevicesNames.insert(module->getName()); - break; - } - } - } - } - } - status_t getStatus() const { return mStatus; } - std::string getError() const { - if (mFilePath.empty()) { - return std::string{"Could not find "} + kConfigFileName + - " file in: " + testing::PrintToString(android::audio_get_configuration_paths()); - } else { - return "Invalid config file: " + mFilePath; - } - } - const std::string& getFilePath() const { return mFilePath; } - sp getModuleFromName(const std::string& name) const { - return getHwModules().getModuleFromName(name.c_str()); - } - sp getPrimaryModule() const { return mPrimaryModule; } - const std::set& getModulesWithDevicesNames() const { - return mModulesWithDevicesNames; - } - - private: - status_t mStatus = NO_INIT; - std::string mFilePath; - sp mPrimaryModule = nullptr; - std::set mModulesWithDevicesNames; -}; +static constexpr char kConfigFileName[] = "audio_policy_configuration.xml"; // Cached policy config after parsing for faster test startup const PolicyConfig& getCachedPolicyConfig() { static std::unique_ptr policyConfig = [] { - auto config = std::make_unique(); + auto config = std::make_unique(kConfigFileName); return config; }(); return *policyConfig; @@ -449,9 +387,10 @@ class AccessorHidlTest : public BaseTestClass { * The getter and/or the setter may return NOT_SUPPORTED if optionality == OPTIONAL. */ template - void testAccessors(IUTGetter iutGetter, const string& propertyName, - const Initial expectedInitial, list valuesToTest, Setter setter, - Getter getter, const vector& invalidValues = {}) { + void testAccessors(IUTGetter iutGetter, const std::string& propertyName, + const Initial expectedInitial, std::list valuesToTest, + Setter setter, Getter getter, + const std::vector& invalidValues = {}) { const auto expectedResults = {Result::OK, optionality == OPTIONAL ? Result::NOT_SUPPORTED : Result::OK}; @@ -495,9 +434,9 @@ class AccessorHidlTest : public BaseTestClass { EXPECT_RESULT(expectedResults, ((this->*iutGetter)().get()->*setter)(initialValue)); } template - void testAccessors(const string& propertyName, const Initial expectedInitial, - list valuesToTest, Setter setter, Getter getter, - const vector& invalidValues = {}) { + void testAccessors(const std::string& propertyName, const Initial expectedInitial, + std::list valuesToTest, Setter setter, Getter getter, + const std::vector& invalidValues = {}) { testAccessors(&BaseTestClass::getDevice, propertyName, expectedInitial, valuesToTest, setter, getter, invalidValues); } @@ -573,9 +512,13 @@ GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioPatchHidlTest); // Nesting a tuple in another tuple allows to use GTest Combine function to generate // all combinations of devices and configs. enum { PARAM_DEVICE, PARAM_CONFIG, PARAM_FLAGS }; +#if MAJOR_VERSION <= 6 enum { INDEX_INPUT, INDEX_OUTPUT }; using DeviceConfigParameter = std::tuple>; +#elif MAJOR_VERSION >= 7 +using DeviceConfigParameter = std::tuple>; +#endif #if MAJOR_VERSION >= 6 const std::vector& getInputDeviceConfigParameters(); @@ -583,8 +526,8 @@ const std::vector& getOutputDeviceConfigParameters(); #endif #if MAJOR_VERSION >= 4 -static string SanitizeStringForGTestName(const string& s) { - string result = s; +static std::string SanitizeStringForGTestName(const std::string& s) { + std::string result = s; for (size_t i = 0; i < result.size(); i++) { // gtest test names must only contain alphanumeric characters if (!std::isalnum(result[i])) result[i] = '_'; @@ -598,43 +541,57 @@ static string SanitizeStringForGTestName(const string& s) { * As the only parameter changing are channel mask and sample rate, * only print those ones in the test name. */ -static string DeviceConfigParameterToString( +static std::string DeviceConfigParameterToString( const testing::TestParamInfo& info) { const AudioConfig& config = std::get(info.param); const auto deviceName = DeviceParameterToString(::testing::TestParamInfo{ std::get(info.param), info.index}); - return (deviceName.empty() ? "" : deviceName + "_") + to_string(info.index) + "__" + - to_string(config.sampleRateHz) + "_" + - // "MONO" is more clear than "FRONT_LEFT" - ((config.channelMask == mkEnumBitfield(AudioChannelMask::OUT_MONO) || - config.channelMask == mkEnumBitfield(AudioChannelMask::IN_MONO)) - ? "MONO" -#if MAJOR_VERSION == 2 - : ::testing::PrintToString(config.channelMask) -#elif MAJOR_VERSION >= 4 - // In V4 and above the channel mask is a bitfield. - // Printing its value using HIDL's toString for a bitfield emits a lot of extra - // text due to overlapping constant values. Instead, we print the bitfield value - // as if it was a single value + its hex representation - : SanitizeStringForGTestName( - ::testing::PrintToString(AudioChannelMask(config.channelMask)) + "_" + - toHexString(config.channelMask)) -#endif - ) + - "_" + + const auto devicePart = + (deviceName.empty() ? "" : deviceName + "_") + std::to_string(info.index); + // The types had changed a lot between versions 2, 4..6 and 7. Use separate + // code sections for easier understanding. #if MAJOR_VERSION == 2 - std::visit([](auto&& arg) -> std::string { return ::testing::PrintToString(arg); }, - std::get(info.param)); -#elif MAJOR_VERSION >= 4 - SanitizeStringForGTestName(std::visit( - [](auto&& arg) -> std::string { - using T = std::decay_t; - // Need to use FQN of toString to avoid confusing the compiler - return ::android::hardware::audio::common::CPP_VERSION::toString( - hidl_bitfield(arg)); - }, - std::get(info.param))); + const auto configPart = + std::to_string(config.sampleRateHz) + "_" + + // "MONO" is more clear than "FRONT_LEFT" + (config.channelMask == AudioChannelMask::OUT_MONO || + config.channelMask == AudioChannelMask::IN_MONO + ? "MONO" + : ::testing::PrintToString(config.channelMask)) + + "_" + + std::visit([](auto&& arg) -> std::string { return ::testing::PrintToString(arg); }, + std::get(info.param)); +#elif MAJOR_VERSION >= 4 && MAJOR_VERSION <= 6 + const auto configPart = + std::to_string(config.sampleRateHz) + "_" + + // "MONO" is more clear than "FRONT_LEFT" + (config.channelMask == mkEnumBitfield(AudioChannelMask::OUT_MONO) || + config.channelMask == mkEnumBitfield(AudioChannelMask::IN_MONO) + ? "MONO" + // In V4 and above the channel mask is a bitfield. + // Printing its value using HIDL's toString for a bitfield emits a lot of extra + // text due to overlapping constant values. Instead, we print the bitfield + // value as if it was a single value + its hex representation + : SanitizeStringForGTestName( + ::testing::PrintToString(AudioChannelMask(config.channelMask)) + + "_" + toHexString(config.channelMask))) + + "_" + + SanitizeStringForGTestName(std::visit( + [](auto&& arg) -> std::string { + using T = std::decay_t; + // Need to use FQN of toString to avoid confusing the compiler + return ::android::hardware::audio::common::CPP_VERSION::toString( + hidl_bitfield(arg)); + }, + std::get(info.param))); +#elif MAJOR_VERSION >= 7 + const auto configPart = + std::to_string(config.base.sampleRateHz) + "_" + + // The channel masks and flags are vectors of strings, just need to sanitize them. + SanitizeStringForGTestName(::testing::PrintToString(config.base.channelMask)) + "_" + + SanitizeStringForGTestName(::testing::PrintToString(std::get(info.param))); #endif + return devicePart + "__" + configPart; } class AudioHidlTestWithDeviceConfigParameter @@ -660,7 +617,7 @@ class AudioHidlTestWithDeviceConfigParameter AudioOutputFlag getOutputFlags() const { return std::get(std::get(GetParam())); } -#elif MAJOR_VERSION >= 4 +#elif MAJOR_VERSION >= 4 && MAJOR_VERSION <= 6 hidl_bitfield getInputFlags() const { return hidl_bitfield( std::get(std::get(GetParam()))); @@ -669,10 +626,17 @@ class AudioHidlTestWithDeviceConfigParameter return hidl_bitfield( std::get(std::get(GetParam()))); } +#elif MAJOR_VERSION >= 7 + hidl_vec getInputFlags() const { return std::get(GetParam()); } + hidl_vec getOutputFlags() const { return std::get(GetParam()); } #endif }; +#if MAJOR_VERSION <= 6 +#define AUDIO_PRIMARY_HIDL_HAL_TEST #include "ConfigHelper.h" +#undef AUDIO_PRIMARY_HIDL_HAL_TEST +#endif ////////////////////////////////////////////////////////////////////////////// ///////////////////////////// getInputBufferSize ///////////////////////////// @@ -839,7 +803,7 @@ class StreamHelper { AudioConfig* suggestedConfigPtr) { // FIXME: Open a stream without an IOHandle // This is not required to be accepted by hal implementations - AudioIoHandle ioHandle = (AudioIoHandle)AudioHandleConsts::AUDIO_IO_HANDLE_NONE; + AudioIoHandle ioHandle{}; AudioConfig suggestedConfig{}; bool retryWithSuggestedConfig = true; if (suggestedConfigPtr == nullptr) { @@ -932,7 +896,11 @@ class OpenStreamTest : public AudioHidlTestWithDeviceConfigParameter { class OutputStreamTest : public OpenStreamTest { void SetUp() override { ASSERT_NO_FATAL_FAILURE(OpenStreamTest::SetUp()); // setup base +#if MAJOR_VERSION <= 6 address.device = AudioDevice::OUT_DEFAULT; +#elif MAJOR_VERSION >= 7 + address.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_OUT_DEFAULT); +#endif const AudioConfig& config = getConfig(); auto flags = getOutputFlags(); testOpen( @@ -946,13 +914,19 @@ class OutputStreamTest : public OpenStreamTest { }, config); } -#if MAJOR_VERSION >= 4 +#if MAJOR_VERSION >= 4 && MAJOR_VERSION <= 6 - protected: + protected: const SourceMetadata initMetadata = { { { AudioUsage::MEDIA, AudioContentType::MUSIC, 1 /* gain */ } }}; +#elif MAJOR_VERSION >= 7 + protected: + const SourceMetadata initMetadata = { + { { toString(xsd::AudioUsage::AUDIO_USAGE_MEDIA), + toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_MUSIC), + 1 /* gain */ } }}; #endif }; TEST_P(OutputStreamTest, OpenOutputStreamTest) { @@ -995,7 +969,11 @@ GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(OutputStreamTest); class InputStreamTest : public OpenStreamTest { void SetUp() override { ASSERT_NO_FATAL_FAILURE(OpenStreamTest::SetUp()); // setup base +#if MAJOR_VERSION <= 6 address.device = AudioDevice::IN_DEFAULT; +#elif MAJOR_VERSION <= 7 + address.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_IN_DEFAULT); +#endif const AudioConfig& config = getConfig(); auto flags = getInputFlags(); testOpen( @@ -1009,8 +987,11 @@ class InputStreamTest : public OpenStreamTest { protected: #if MAJOR_VERSION == 2 const AudioSource initMetadata = AudioSource::DEFAULT; -#elif MAJOR_VERSION >= 4 - const SinkMetadata initMetadata = {{{.source = AudioSource::DEFAULT, .gain = 1}}}; +#elif MAJOR_VERSION >= 4 && MAJOR_VERSION <= 6 + const SinkMetadata initMetadata = {{ {.source = AudioSource::DEFAULT, .gain = 1 } }}; +#elif MAJOR_VERSION >= 7 + const SinkMetadata initMetadata = { + {{.source = toString(xsd::AudioSource::AUDIO_SOURCE_DEFAULT), .gain = 1}}}; #endif }; @@ -1067,6 +1048,7 @@ GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(InputStreamTest); TEST_IO_STREAM(GetFrameCount, "Check that getting stream frame count does not crash the HAL.", ASSERT_TRUE(stream->getFrameCount().isOk())) +#if MAJOR_VERSION <= 6 TEST_IO_STREAM(GetSampleRate, "Check that the stream sample rate == the one it was opened with", ASSERT_EQ(audioConfig.sampleRateHz, extract(stream->getSampleRate()))) @@ -1075,6 +1057,7 @@ TEST_IO_STREAM(GetChannelMask, "Check that the stream channel mask == the one it TEST_IO_STREAM(GetFormat, "Check that the stream format == the one it was opened with", ASSERT_EQ(audioConfig.format, extract(stream->getFormat()))) +#endif // TODO: for now only check that the framesize is not incoherent TEST_IO_STREAM(GetFrameSize, "Check that the stream frame size == the one it was opened with", @@ -1084,7 +1067,7 @@ TEST_IO_STREAM(GetBufferSize, "Check that the stream buffer size== the one it wa ASSERT_GE(extract(stream->getBufferSize()), extract(stream->getFrameSize()))); template -static void testCapabilityGetter(const string& name, IStream* stream, +static void testCapabilityGetter(const std::string& name, IStream* stream, CapabilityGetter capabilityGetter, Return (IStream::*getter)(), Return (IStream::*setter)(Property), @@ -1120,6 +1103,7 @@ static void testCapabilityGetter(const string& name, IStream* stream, } } +#if MAJOR_VERSION <= 6 TEST_IO_STREAM(SupportedSampleRate, "Check that the stream sample rate is declared as supported", testCapabilityGetter("getSupportedSampleRate", stream.get(), &GetSupported::sampleRates, &IStream::getSampleRate, @@ -1137,19 +1121,71 @@ TEST_IO_STREAM(SupportedChannelMask, "Check that the stream channel mask is decl TEST_IO_STREAM(SupportedFormat, "Check that the stream format is declared as supported", testCapabilityGetter("getSupportedFormat", stream.get(), &GetSupported::formats, &IStream::getFormat, &IStream::setFormat)) +#else +static void testGetSupportedProfiles(IStream* stream) { + Result res; + hidl_vec profiles; + auto ret = stream->getSupportedProfiles(returnIn(res, profiles)); + EXPECT_TRUE(ret.isOk()); + if (res == Result::OK) { + EXPECT_GT(profiles.size(), 0); + } else { + EXPECT_EQ(Result::NOT_SUPPORTED, res); + } +} + +TEST_IO_STREAM(GetSupportedProfiles, "Try to call optional method GetSupportedProfiles", + testGetSupportedProfiles(stream.get())) + +static void testSetAudioProperties(IStream* stream) { + Result res; + hidl_vec profiles; + auto ret = stream->getSupportedProfiles(returnIn(res, profiles)); + EXPECT_TRUE(ret.isOk()); + if (res == Result::NOT_SUPPORTED) { + GTEST_SKIP() << "Retrieving supported profiles is not implemented"; + } + for (const auto& profile : profiles) { + for (const auto& sampleRate : profile.sampleRates) { + for (const auto& channelMask : profile.channelMasks) { + AudioConfigBase config{.format = profile.format, + .sampleRateHz = sampleRate, + .channelMask = channelMask}; + auto ret = stream->setAudioProperties(config); + EXPECT_TRUE(ret.isOk()); + EXPECT_EQ(Result::OK, ret) << config.format << "; " << config.sampleRateHz << "; " + << toString(config.channelMask); + } + } + } +} + +TEST_IO_STREAM(SetAudioProperties, "Call setAudioProperties for all supported profiles", + testSetAudioProperties(stream.get())) +#endif static void testGetAudioProperties(IStream* stream, AudioConfig expectedConfig) { +#if MAJOR_VERSION <= 6 uint32_t sampleRateHz; auto mask = mkEnumBitfield({}); AudioFormat format; - stream->getAudioProperties(returnIn(sampleRateHz, mask, format)); + auto ret = stream->getAudioProperties(returnIn(sampleRateHz, mask, format)); + EXPECT_TRUE(ret.isOk()); // FIXME: the qcom hal it does not currently negotiate the sampleRate & // channel mask EXPECT_EQ(expectedConfig.sampleRateHz, sampleRateHz); EXPECT_EQ(expectedConfig.channelMask, mask); EXPECT_EQ(expectedConfig.format, format); +#elif MAJOR_VERSION >= 7 + AudioConfigBase actualConfig{}; + auto ret = stream->getAudioProperties(returnIn(actualConfig)); + EXPECT_TRUE(ret.isOk()); + EXPECT_EQ(expectedConfig.base.sampleRateHz, actualConfig.sampleRateHz); + EXPECT_EQ(expectedConfig.base.channelMask, actualConfig.channelMask); + EXPECT_EQ(expectedConfig.base.format, actualConfig.format); +#endif } TEST_IO_STREAM(GetAudioProperties, @@ -1160,7 +1196,7 @@ TEST_IO_STREAM(SetHwAvSync, "Try to set hardware sync to an invalid value", ASSERT_RESULT(okOrNotSupportedOrInvalidArgs, stream->setHwAvSync(666))) static void checkGetNoParameter(IStream* stream, hidl_vec keys, - initializer_list expectedResults) { + std::initializer_list expectedResults) { hidl_vec parameters; Result res; ASSERT_OK(Parameters::get(stream, keys, returnIn(res, parameters))); @@ -1271,7 +1307,11 @@ TEST_P(InputStreamTest, GetAudioSource) { return; } ASSERT_OK(res); +#if MAJOR_VERSION <= 6 ASSERT_EQ(AudioSource::DEFAULT, source); +#elif MAJOR_VERSION >= 7 + ASSERT_EQ(xsd::AudioSource::AUDIO_SOURCE_DEFAULT, xsd::stringToAudioSource(source)); +#endif } static void testUnitaryGain(std::function(float)> setGain) { @@ -1286,7 +1326,7 @@ static void testUnitaryGain(std::function(float)> setGain) { } static void testOptionalUnitaryGain(std::function(float)> setGain, - string debugName) { + std::string debugName) { auto result = setGain(1); ASSERT_IS_OK(result); if (result == Result::NOT_SUPPORTED) { @@ -1306,7 +1346,7 @@ static void testPrepareForReading(IStreamIn* stream, uint32_t frameSize, uint32_ Result res; // Ignore output parameters as the call should fail ASSERT_OK(stream->prepareForReading(frameSize, framesCount, - [&res](auto r, auto&, auto&, auto&, auto&) { res = r; })); + [&res](auto r, auto&, auto&, auto&, auto) { res = r; })); EXPECT_RESULT(Result::INVALID_ARGUMENTS, res); } @@ -1371,7 +1411,7 @@ static void testPrepareForWriting(IStreamOut* stream, uint32_t frameSize, uint32 Result res; // Ignore output parameters as the call should fail ASSERT_OK(stream->prepareForWriting(frameSize, framesCount, - [&res](auto r, auto&, auto&, auto&, auto&) { res = r; })); + [&res](auto r, auto&, auto&, auto&, auto) { res = r; })); EXPECT_RESULT(Result::INVALID_ARGUMENTS, res); } diff --git a/audio/core/all-versions/vts/functional/ConfigHelper.h b/audio/core/all-versions/vts/functional/ConfigHelper.h index 8ef2b436bb..1a1dbea939 100644 --- a/audio/core/all-versions/vts/functional/ConfigHelper.h +++ b/audio/core/all-versions/vts/functional/ConfigHelper.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#pragma once + // Code in this file uses 'getCachedPolicyConfig' #ifndef AUDIO_PRIMARY_HIDL_HAL_TEST #error Must be included from AudioPrimaryHidlTest.h @@ -46,32 +48,32 @@ struct ConfigHelper { } // Cache result ? - static const vector getRequiredSupportPlaybackAudioConfig() { + static const std::vector getRequiredSupportPlaybackAudioConfig() { return combineAudioConfig({AudioChannelMask::OUT_STEREO, AudioChannelMask::OUT_MONO}, {8000, 11025, 16000, 22050, 32000, 44100}, {AudioFormat::PCM_16_BIT}); } - static const vector getRecommendedSupportPlaybackAudioConfig() { + static const std::vector getRecommendedSupportPlaybackAudioConfig() { return combineAudioConfig({AudioChannelMask::OUT_STEREO, AudioChannelMask::OUT_MONO}, {24000, 48000}, {AudioFormat::PCM_16_BIT}); } - static const vector getRequiredSupportCaptureAudioConfig() { + static const std::vector getRequiredSupportCaptureAudioConfig() { if (!primaryHasMic()) return {}; return combineAudioConfig({AudioChannelMask::IN_MONO}, {8000, 11025, 16000, 44100}, {AudioFormat::PCM_16_BIT}); } - static const vector getRecommendedSupportCaptureAudioConfig() { + static const std::vector getRecommendedSupportCaptureAudioConfig() { if (!primaryHasMic()) return {}; return combineAudioConfig({AudioChannelMask::IN_STEREO}, {22050, 48000}, {AudioFormat::PCM_16_BIT}); } - static vector combineAudioConfig(vector channelMasks, - vector sampleRates, - audio_format_t format) { - vector configs; + static std::vector combineAudioConfig( + std::vector channelMasks, std::vector sampleRates, + audio_format_t format) { + std::vector configs; configs.reserve(channelMasks.size() * sampleRates.size()); for (auto channelMask : channelMasks) { for (auto sampleRate : sampleRates) { @@ -86,10 +88,10 @@ struct ConfigHelper { return configs; } - static vector combineAudioConfig(vector channelMasks, - vector sampleRates, - vector formats) { - vector configs; + static std::vector combineAudioConfig(std::vector channelMasks, + std::vector sampleRates, + std::vector formats) { + std::vector configs; configs.reserve(channelMasks.size() * sampleRates.size() * formats.size()); for (auto channelMask : channelMasks) { for (auto sampleRate : sampleRates) { diff --git a/audio/core/all-versions/vts/functional/DeviceManager.h b/audio/core/all-versions/vts/functional/DeviceManager.h index 0c0727f283..6efed7991e 100644 --- a/audio/core/all-versions/vts/functional/DeviceManager.h +++ b/audio/core/all-versions/vts/functional/DeviceManager.h @@ -14,10 +14,11 @@ * limitations under the License. */ -// Code in this file uses 'environment' -#ifndef AUDIO_PRIMARY_HIDL_HAL_TEST -#error Must be included from AudioPrimaryHidlTest.h -#endif +#pragma once + +// Note: it is assumed that this file is included from AudioPrimaryHidlTest.h +// and thus it doesn't have all '#include' and 'using' directives required +// for a standalone compilation. template class InterfaceManager { diff --git a/audio/core/all-versions/vts/functional/PolicyConfig.h b/audio/core/all-versions/vts/functional/PolicyConfig.h new file mode 100644 index 0000000000..c9e0c0dd5a --- /dev/null +++ b/audio/core/all-versions/vts/functional/PolicyConfig.h @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +// Note: it is assumed that this file is included from AudioPrimaryHidlTest.h +// and thus it doesn't have all '#include' and 'using' directives required +// for a standalone compilation. + +#include + +struct PolicyConfigData { + android::HwModuleCollection hwModules; + android::DeviceVector availableOutputDevices; + android::DeviceVector availableInputDevices; + sp defaultOutputDevice; +}; + +class PolicyConfig : private PolicyConfigData, public android::AudioPolicyConfig { + public: + explicit PolicyConfig(const std::string& configFileName) + : android::AudioPolicyConfig(hwModules, availableOutputDevices, availableInputDevices, + defaultOutputDevice), + mConfigFileName{configFileName} { + for (const auto& location : android::audio_get_configuration_paths()) { + std::string path = location + '/' + mConfigFileName; + if (access(path.c_str(), F_OK) == 0) { + mFilePath = path; + break; + } + } + mStatus = android::deserializeAudioPolicyFile(mFilePath.c_str(), this); + if (mStatus == OK) { + mPrimaryModule = getModuleFromName(DeviceManager::kPrimaryDevice); + // Available devices are not 'attached' to modules at this moment. + // Need to go over available devices and find their module. + for (const auto& device : availableOutputDevices) { + for (const auto& module : hwModules) { + if (module->getDeclaredDevices().indexOf(device) >= 0) { + mModulesWithDevicesNames.insert(module->getName()); + break; + } + } + } + for (const auto& device : availableInputDevices) { + for (const auto& module : hwModules) { + if (module->getDeclaredDevices().indexOf(device) >= 0) { + mModulesWithDevicesNames.insert(module->getName()); + break; + } + } + } + } + } + status_t getStatus() const { return mStatus; } + std::string getError() const { + if (mFilePath.empty()) { + return std::string{"Could not find "} + mConfigFileName + + " file in: " + testing::PrintToString(android::audio_get_configuration_paths()); + } else { + return "Invalid config file: " + mFilePath; + } + } + const std::string& getFilePath() const { return mFilePath; } + sp getModuleFromName(const std::string& name) const { + return getHwModules().getModuleFromName(name.c_str()); + } + sp getPrimaryModule() const { return mPrimaryModule; } + const std::set& getModulesWithDevicesNames() const { + return mModulesWithDevicesNames; + } + bool haveInputProfilesInModule(const std::string& name) const { + auto module = getModuleFromName(name); + return module && !module->getInputProfiles().empty(); + } + + private: + const std::string mConfigFileName; + status_t mStatus = NO_INIT; + std::string mFilePath; + sp mPrimaryModule = nullptr; + std::set mModulesWithDevicesNames; +}; diff --git a/audio/effect/all-versions/vts/functional/Android.bp b/audio/effect/all-versions/vts/functional/Android.bp index 7cdb18f95f..f4a72834d5 100644 --- a/audio/effect/all-versions/vts/functional/Android.bp +++ b/audio/effect/all-versions/vts/functional/Android.bp @@ -118,7 +118,6 @@ cc_test { } cc_test { - enabled: false, name: "VtsHalAudioEffectV7_0TargetTest", defaults: ["VtsHalAudioEffectTargetTest_default"], // Use test_config for vts suite. @@ -126,6 +125,7 @@ cc_test { test_config: "VtsHalAudioEffectV7_0TargetTest.xml", static_libs: [ "android.hardware.audio.common@7.0", + "android.hardware.audio.common@7.0-enums", "android.hardware.audio.effect@7.0", ], data: [ diff --git a/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp b/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp index 4787c091b2..b64f105eb4 100644 --- a/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp +++ b/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp @@ -16,7 +16,9 @@ #define LOG_TAG "AudioEffectHidlHalTest" #include +#if MAJOR_VERSION <= 6 #include +#endif #include PATH(android/hardware/audio/effect/FILE_VERSION/IEffect.h) #include PATH(android/hardware/audio/effect/FILE_VERSION/IEffectsFactory.h) @@ -25,6 +27,10 @@ #include PATH(android/hardware/audio/effect/FILE_VERSION/types.h) #include #include +#if MAJOR_VERSION >= 7 +#include +#include +#endif #include @@ -45,6 +51,12 @@ using ::android::hidl::allocator::V1_0::IAllocator; using ::android::hidl::memory::V1_0::IMemory; using namespace ::android::hardware::audio::common::CPP_VERSION; using namespace ::android::hardware::audio::effect::CPP_VERSION; +#if MAJOR_VERSION >= 7 +// Make an alias for enumerations generated from the APM config XSD. +namespace xsd { +using namespace ::audio::policy::configuration::CPP_VERSION; +} +#endif #ifndef ARRAY_SIZE #define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a))) @@ -171,7 +183,7 @@ class AudioEffectHidlTest : public ::testing::TestWithParam { effectsFactory = IEffectsFactory::getService(std::get(GetParam())); ASSERT_NE(nullptr, effectsFactory.get()); - findAndCreateEffect(getEffectType()); + ASSERT_NO_FATAL_FAILURE(findAndCreateEffect(getEffectType())); ASSERT_NE(nullptr, effect.get()); Return ret = effect->init(); @@ -201,7 +213,7 @@ class AudioEffectHidlTest : public ::testing::TestWithParam { void AudioEffectHidlTest::findAndCreateEffect(const Uuid& type) { Uuid effectUuid; - findEffectInstance(type, &effectUuid); + ASSERT_NO_FATAL_FAILURE(findEffectInstance(type, &effectUuid)); Return ret = effectsFactory->createEffect( effectUuid, 1 /*session*/, 1 /*ioHandle*/, #if MAJOR_VERSION >= 6 @@ -244,10 +256,16 @@ void AudioEffectHidlTest::getChannelCount(uint32_t* channelCount) { }); ASSERT_TRUE(ret.isOk()); ASSERT_EQ(Result::OK, retval); +#if MAJOR_VERSION <= 6 ASSERT_TRUE(audio_channel_mask_is_valid( static_cast(currentConfig.outputCfg.channels))); *channelCount = audio_channel_count_from_out_mask( static_cast(currentConfig.outputCfg.channels)); +#else + *channelCount = + audio::policy::configuration::V7_0::getChannelCount(currentConfig.outputCfg.channels); + ASSERT_NE(*channelCount, 0); +#endif } TEST_P(AudioEffectHidlTest, Close) { @@ -391,7 +409,12 @@ TEST_P(AudioEffectHidlTest, DisableEnableDisable) { TEST_P(AudioEffectHidlTest, SetDevice) { description("Verify that SetDevice works for an output chain effect"); +#if MAJOR_VERSION <= 6 Return ret = effect->setDevice(mkEnumBitfield(AudioDevice::OUT_SPEAKER)); +#else + DeviceAddress device{.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_OUT_SPEAKER)}; + Return ret = effect->setDevice(device); +#endif EXPECT_TRUE(ret.isOk()); EXPECT_EQ(Result::OK, ret); } @@ -441,22 +464,28 @@ TEST_P(AudioEffectHidlTest, SetConfigReverse) { TEST_P(AudioEffectHidlTest, SetInputDevice) { description("Verify that SetInputDevice does not crash"); +#if MAJOR_VERSION <= 6 Return ret = effect->setInputDevice(mkEnumBitfield(AudioDevice::IN_BUILTIN_MIC)); +#else + DeviceAddress device{.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_IN_BUILTIN_MIC)}; + Return ret = effect->setInputDevice(device); +#endif EXPECT_TRUE(ret.isOk()); } TEST_P(AudioEffectHidlTest, SetAudioSource) { description("Verify that SetAudioSource does not crash"); +#if MAJOR_VERSION <= 6 Return ret = effect->setAudioSource(AudioSource::MIC); +#else + Return ret = effect->setAudioSource(toString(xsd::AudioSource::AUDIO_SOURCE_MIC)); +#endif EXPECT_TRUE(ret.isOk()); } TEST_P(AudioEffectHidlTest, Offload) { description("Verify that calling Offload method does not crash"); - EffectOffloadParameter offloadParam; - offloadParam.isOffload = false; - offloadParam.ioHandle = static_cast(AudioHandleConsts::AUDIO_IO_HANDLE_NONE); - Return ret = effect->offload(offloadParam); + Return ret = effect->offload(EffectOffloadParameter{}); EXPECT_TRUE(ret.isOk()); } -- GitLab From 4c49c15e55153f7360bce0763d2bfef7fa410c4a Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Tue, 25 Aug 2020 21:08:19 -0700 Subject: [PATCH 182/790] Add DTMB Frontend Type and Related Capabilities enums Test: atest VtsHalTvTunerV1_1TargetTest Bug: 159064654 Change-Id: I4ed8ec1f47d74ba3d585725cb64ba925d7ddf910 --- tv/tuner/1.1/ITuner.hal | 9 +- tv/tuner/1.1/default/Tuner.cpp | 18 ++- tv/tuner/1.1/default/Tuner.h | 4 + tv/tuner/1.1/types.hal | 142 ++++++++++++++++++ tv/tuner/1.1/vts/functional/FrontendTests.cpp | 19 +++ tv/tuner/1.1/vts/functional/FrontendTests.h | 3 + .../VtsHalTvTunerV1_1TargetTest.cpp | 5 + 7 files changed, 198 insertions(+), 2 deletions(-) diff --git a/tv/tuner/1.1/ITuner.hal b/tv/tuner/1.1/ITuner.hal index 915fb85806..d59c425257 100644 --- a/tv/tuner/1.1/ITuner.hal +++ b/tv/tuner/1.1/ITuner.hal @@ -16,6 +16,7 @@ package android.hardware.tv.tuner@1.1; +import @1.0::FrontendId; import @1.0::ITuner; import @1.0::Result; @@ -23,4 +24,10 @@ import @1.0::Result; * Top level interface to manage Frontend, Demux and Decrambler hardware * resources which are needed for Android TV. */ -interface ITuner extends @1.0::ITuner {}; +interface ITuner extends @1.0::ITuner { + /** + * Get Dtmb Frontend Capabilities. If no dtmb exists, Result::UNAVAILABLE would be returned. + */ + getFrontendDtmbCapabilities(FrontendId frontendId) + generates (Result result, FrontendDtmbCapabilities caps); +}; diff --git a/tv/tuner/1.1/default/Tuner.cpp b/tv/tuner/1.1/default/Tuner.cpp index 87a4d36735..c3dcd1d8e4 100644 --- a/tv/tuner/1.1/default/Tuner.cpp +++ b/tv/tuner/1.1/default/Tuner.cpp @@ -33,7 +33,7 @@ namespace implementation { Tuner::Tuner() { // Static Frontends array to maintain local frontends information // Array index matches their FrontendId in the default impl - mFrontendSize = 8; + mFrontendSize = 9; mFrontends[0] = new Frontend(FrontendType::DVBT, 0, this); mFrontends[1] = new Frontend(FrontendType::ATSC, 1, this); mFrontends[2] = new Frontend(FrontendType::DVBC, 2, this); @@ -42,6 +42,8 @@ Tuner::Tuner() { mFrontends[5] = new Frontend(FrontendType::ISDBT, 5, this); mFrontends[6] = new Frontend(FrontendType::ANALOG, 6, this); mFrontends[7] = new Frontend(FrontendType::ATSC, 7, this); + mFrontends[8] = + new Frontend(static_cast(V1_1::FrontendType::DTMB), 8, this); FrontendInfo::FrontendCapabilities caps; caps = FrontendInfo::FrontendCapabilities(); @@ -224,6 +226,20 @@ Return Tuner::openLnbByName(const hidl_string& /*lnbName*/, openLnbByName_ return Void(); } +Return Tuner::getFrontendDtmbCapabilities(uint32_t frontendId, + getFrontendDtmbCapabilities_cb _hidl_cb) { + ALOGV("%s", __FUNCTION__); + + if (mFrontends[frontendId] != nullptr && + (mFrontends[frontendId]->getFrontendType() == + static_cast(V1_1::FrontendType::DTMB))) { + _hidl_cb(Result::SUCCESS, mDtmbCaps); + } else { + _hidl_cb(Result::UNAVAILABLE, mDtmbCaps); + } + return Void(); +} + void Tuner::setFrontendAsDemuxSource(uint32_t frontendId, uint32_t demuxId) { mFrontendToDemux[frontendId] = demuxId; if (mFrontends[frontendId] != nullptr && mFrontends[frontendId]->isLocked()) { diff --git a/tv/tuner/1.1/default/Tuner.h b/tv/tuner/1.1/default/Tuner.h index 3b1574b8aa..fda3636939 100644 --- a/tv/tuner/1.1/default/Tuner.h +++ b/tv/tuner/1.1/default/Tuner.h @@ -62,6 +62,9 @@ class Tuner : public ITuner { virtual Return openLnbByName(const hidl_string& lnbName, openLnbByName_cb _hidl_cb) override; + virtual Return getFrontendDtmbCapabilities( + uint32_t frontendId, getFrontendDtmbCapabilities_cb _hidl_cb) override; + sp getFrontendById(uint32_t frontendId); void setFrontendAsDemuxSource(uint32_t frontendId, uint32_t demuxId); @@ -76,6 +79,7 @@ class Tuner : public ITuner { // Static mFrontends array to maintain local frontends information map> mFrontends; map mFrontendCaps; + V1_1::FrontendDtmbCapabilities mDtmbCaps; map mFrontendToDemux; map> mDemuxes; // To maintain how many Frontends we have diff --git a/tv/tuner/1.1/types.hal b/tv/tuner/1.1/types.hal index 214e3a12a4..d9c22f8eb9 100644 --- a/tv/tuner/1.1/types.hal +++ b/tv/tuner/1.1/types.hal @@ -22,6 +22,7 @@ import @1.0::DemuxFilterTsRecordEvent; import @1.0::FrontendDvbcSpectralInversion; import @1.0::FrontendDvbtConstellation; import @1.0::FrontendDvbtTransmissionMode; +import @1.0::FrontendType; import android.hidl.safe_union@1.0; import android.hidl.safe_union@1.0::Monostate; @@ -181,5 +182,146 @@ struct FrontendSettingsExt1_1 { FrontendDvbsSettingsExt1_1 dvbs; FrontendDvbtSettingsExt1_1 dvbt; + + FrontendDtmbSettings dtmb; } settingExt; }; + +/** + * Extended Frontend Type. + */ +@export +enum FrontendType : @1.0::FrontendType { + /** + * DTMB (Digital Terrestrial Multimedia Broadcast) standard. + */ + DTMB, +}; + +/** + * Bandwidth Type for DTMB. + */ +@export +enum FrontendDtmbBandwidth : uint32_t { + UNDEFINED = 0, + /** + * hardware is able to detect and set Bandwidth automatically + */ + AUTO = 1 << 0, + BANDWIDTH_8MHZ = 1 << 1, + BANDWIDTH_6MHZ = 1 << 2, +}; + +/** + * TimeInterleaveMode Type for DTMB. + */ +@export +enum FrontendDtmbTimeInterleaveMode : uint32_t { + UNDEFINED = 0, + /** + * hardware is able to detect and set time interleave mode automatically + */ + AUTO = 1 << 0, + TIMER_INT_240 = 1 << 1, + TIMER_INT_720 = 1 << 2, +}; + +/** + * FrontendDtmbModulation Type for DTMB. + */ +@export +enum FrontendDtmbModulation : uint32_t { + UNDEFINED = 0, + /** + * hardware is able to detect and set Constellation automatically + */ + AUTO = 1 << 0, + CONSTELLATION_4QAM = 1 << 1, + CONSTELLATION_4QAM_NR = 1 << 2, + CONSTELLATION_16QAM = 1 << 3, + CONSTELLATION_32QAM = 1 << 4, + CONSTELLATION_64QAM = 1 << 5, +}; + +/** + * CODERATE Type for DTMB. + */ +@export +enum FrontendDtmbCodeRate : uint32_t { + UNDEFINED = 0, + /** + * hardware is able to detect and set code rate automatically + */ + AUTO = 1 << 0, + CODERATE_2_5 = 1 << 1, + CODERATE_3_5 = 1 << 2, + CODERATE_4_5 = 1 << 3, +}; + +/** + * Guard Interval Type for DTMB. + */ +@export +enum FrontendDtmbGuardInterval : uint32_t { + UNDEFINED = 0, + /** + * hardware is able to detect and set Guard Interval automatically + */ + AUTO = 1 << 0, + PN_420_VARIOUS = 1 << 1, + PN_595_CONST = 1 << 2, + PN_945_VARIOUS = 1 << 3, + PN_420_CONST = 1 << 4, + PN_945_CONST = 1 << 5, + PN_RESERVED = 1 << 6, +}; + +/** + * Transmission Mode for DTMB. + */ +@export +enum FrontendDtmbTransmissionMode : uint32_t { + UNDEFINED = 0, + /** + * hardware is able to detect and set Transmission Mode automatically + */ + AUTO = 1 << 0, + C1 = 1 << 1, + C3780 = 1 << 2, +}; + +/** + * Signal Setting for DTMB Frontend. + */ +struct FrontendDtmbSettings { + uint32_t frequency; + + FrontendDtmbTransmissionMode transmissionMode; + + FrontendDtmbBandwidth bandwidth; + + FrontendDtmbModulation modulation; + + FrontendDtmbCodeRate codeRate; + + FrontendDtmbGuardInterval guardInterval; + + FrontendDtmbTimeInterleaveMode interleaveMode; +}; + +/** + * Capabilities for DTMB Frontend. + */ +struct FrontendDtmbCapabilities { + bitfield transmissionModeCap; + + bitfield bandwidthCap; + + bitfield modulationCap; + + bitfield codeRateCap; + + bitfield guardIntervalCap; + + bitfield interleaveModeCap; +}; diff --git a/tv/tuner/1.1/vts/functional/FrontendTests.cpp b/tv/tuner/1.1/vts/functional/FrontendTests.cpp index 897cbaf998..bb91e4a771 100644 --- a/tv/tuner/1.1/vts/functional/FrontendTests.cpp +++ b/tv/tuner/1.1/vts/functional/FrontendTests.cpp @@ -243,6 +243,14 @@ AssertionResult FrontendTests::stopScanFrontend() { EXPECT_TRUE(mFrontend) << "Test with openFrontendById first."; Result status; status = mFrontend->stopScan(); + + return AssertionResult(status == Result::SUCCESS); +} + +AssertionResult FrontendTests::getFrontendDtmbCaps(uint32_t id) { + Result status; + mService->getFrontendDtmbCapabilities( + id, [&](Result result, const FrontendDtmbCapabilities& /*caps*/) { status = result; }); return AssertionResult(status == Result::SUCCESS); } @@ -440,3 +448,14 @@ void FrontendTests::scanTest(FrontendConfig frontendConf, FrontendScanType scanT ASSERT_TRUE(stopScanFrontend()); ASSERT_TRUE(closeFrontend()); } + +void FrontendTests::getFrontendDtmbCapsTest() { + uint32_t feId; + getFrontendIdByType( + static_cast(android::hardware::tv::tuner::V1_1::FrontendType::DTMB), + feId); + if (feId != INVALID_ID) { + ALOGD("[vts] Found DTMB Frontend"); + ASSERT_TRUE(getFrontendDtmbCaps(feId)); + } +} diff --git a/tv/tuner/1.1/vts/functional/FrontendTests.h b/tv/tuner/1.1/vts/functional/FrontendTests.h index 4eec7a666c..cb238e8d00 100644 --- a/tv/tuner/1.1/vts/functional/FrontendTests.h +++ b/tv/tuner/1.1/vts/functional/FrontendTests.h @@ -56,6 +56,7 @@ using android::hardware::tv::tuner::V1_0::FrontendScanType; using android::hardware::tv::tuner::V1_0::IFrontend; using android::hardware::tv::tuner::V1_0::IFrontendCallback; using android::hardware::tv::tuner::V1_0::Result; +using android::hardware::tv::tuner::V1_1::FrontendDtmbCapabilities; using android::hardware::tv::tuner::V1_1::ITuner; using ::testing::AssertionResult; @@ -113,10 +114,12 @@ class FrontendTests { vector expectStatuses); AssertionResult stopTuneFrontend(bool testWithDemux); AssertionResult closeFrontend(); + AssertionResult getFrontendDtmbCaps(uint32_t); void getFrontendIdByType(FrontendType feType, uint32_t& feId); void tuneTest(FrontendConfig frontendConf); void scanTest(FrontendConfig frontend, FrontendScanType type); + void getFrontendDtmbCapsTest(); void setDvrTests(DvrTests dvrTests) { mDvrTests = dvrTests; } void setDemux(sp demux) { mDvrTests.setDemux(demux); } diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp index 5041741044..263b0e9a8c 100644 --- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp @@ -157,6 +157,11 @@ TEST_P(TunerBroadcastHidlTest, MediaFilterWithSharedMemoryHandle) { mediaFilterUsingSharedMemoryTest(filterArray[TS_VIDEO0], frontendArray[DVBT]); } +TEST_P(TunerFrontendHidlTest, GetFrontendDtmbCaps) { + description("Test to query Dtmb frontend caps if exists"); + mFrontendTests.getFrontendDtmbCapsTest(); +} + INSTANTIATE_TEST_SUITE_P( PerInstance, TunerBroadcastHidlTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames(ITuner::descriptor)), -- GitLab From 58d9942ade982160f797b598d5f7534803f96edf Mon Sep 17 00:00:00 2001 From: Mikhail Naganov Date: Wed, 30 Sep 2020 00:09:16 +0000 Subject: [PATCH 183/790] Remove PREUPLOAD.cfg from audio HAL example As suggested by the comment on ag/12691153 Bug: 142480271 Test: N/A Change-Id: Ic9e2b986d3f9734dd884a2c88ca86d251147126b --- audio/common/7.0/example/PREUPLOAD.cfg | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 audio/common/7.0/example/PREUPLOAD.cfg diff --git a/audio/common/7.0/example/PREUPLOAD.cfg b/audio/common/7.0/example/PREUPLOAD.cfg deleted file mode 100644 index 6b7fd7137c..0000000000 --- a/audio/common/7.0/example/PREUPLOAD.cfg +++ /dev/null @@ -1,2 +0,0 @@ -[Builtin Hooks] -clang_format = true -- GitLab From 422bb11cca7aac9b05cbcc5fb8fd87daa3fa1c73 Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Wed, 12 Aug 2020 15:21:44 -0700 Subject: [PATCH 184/790] Add FrontendStatusExt1_1 and getStatusExt1_1 to get 1.1 Extended Frontend Status Test: atest VtsHalTvTunerV1_1TargetTest Bug: 158818695 Change-Id: I8cbbf1e3bca7f2ddda90ad6dd4a2ae0368561bfd --- tv/tuner/1.1/IFrontend.hal | 16 ++ tv/tuner/1.1/default/Frontend.cpp | 77 +++++++ tv/tuner/1.1/default/Frontend.h | 4 + tv/tuner/1.1/types.hal | 201 +++++++++++++++++- tv/tuner/1.1/vts/functional/FrontendTests.cpp | 130 +++++------ tv/tuner/1.1/vts/functional/FrontendTests.h | 4 +- .../VtsHalTvTunerV1_1TestConfigurations.h | 18 +- 7 files changed, 355 insertions(+), 95 deletions(-) diff --git a/tv/tuner/1.1/IFrontend.hal b/tv/tuner/1.1/IFrontend.hal index f39eb5de48..e9c5e190f5 100644 --- a/tv/tuner/1.1/IFrontend.hal +++ b/tv/tuner/1.1/IFrontend.hal @@ -82,4 +82,20 @@ interface IFrontend extends @1.0::IFrontend { * UNKNOWN_ERROR if failed for other reasons. */ linkCiCam(uint32_t ciCamId) generates (Result result); + + /** + * Get the v1_1 extended statuses of the frontend. + * + * This retrieve the extended statuses of the frontend for given extended status types. + * + * @param statusTypes an array of the extended status types which the caller request. + * + * @return result Result status of the operation. + * SUCCESS if successful, + * INVALID_STATE if tuning can't be applied at current stage, + * UNKNOWN_ERROR if tuning failed for other reasons. + * @return statuses an array of extended statuses the caller requests for. + */ + getStatusExt1_1(vec statusTypes) + generates (Result result, vec statuses); }; diff --git a/tv/tuner/1.1/default/Frontend.cpp b/tv/tuner/1.1/default/Frontend.cpp index 0b8311ff69..c5aeace1b5 100644 --- a/tv/tuner/1.1/default/Frontend.cpp +++ b/tv/tuner/1.1/default/Frontend.cpp @@ -259,6 +259,83 @@ Return Frontend::getStatus(const hidl_vec& statusTypes return Void(); } +Return Frontend::getStatusExt1_1(const hidl_vec& statusTypes, + V1_1::IFrontend::getStatusExt1_1_cb _hidl_cb) { + ALOGV("%s", __FUNCTION__); + + vector statuses; + for (int i = 0; i < statusTypes.size(); i++) { + V1_1::FrontendStatusTypeExt1_1 type = statusTypes[i]; + V1_1::FrontendStatusExt1_1 status; + // assign randomly selected values for testing. + switch (type) { + case V1_1::FrontendStatusTypeExt1_1::MODULATIONS: { + vector modulations; + V1_1::FrontendModulation modulation; + modulation.isdbt(FrontendIsdbtModulation::MOD_16QAM); // value = 1 << 3 + modulations.push_back(modulation); + status.modulations(modulations); + break; + } + case V1_1::FrontendStatusTypeExt1_1::BERS: { + vector bers = {1}; + status.bers(bers); + break; + } + case V1_1::FrontendStatusTypeExt1_1::CODERATES: { + // value = 1 << 39 + vector codeRates = {V1_1::FrontendInnerFec::FEC_6_15}; + status.codeRates(codeRates); + break; + } + case V1_1::FrontendStatusTypeExt1_1::GUARD_INTERVAL: { + V1_1::FrontendGuardInterval interval; + interval.dvbt(FrontendDvbtGuardInterval::INTERVAL_1_32); // value = 1 << 1 + status.interval(interval); + break; + } + case V1_1::FrontendStatusTypeExt1_1::TRANSMISSION_MODE: { + V1_1::FrontendTransmissionMode transMode; + transMode.dvbt(V1_1::FrontendDvbtTransmissionMode::AUTO); // value = 1 << 0 + status.transmissionMode(transMode); + break; + } + case V1_1::FrontendStatusTypeExt1_1::UEC: { + status.uec(4); + break; + } + case V1_1::FrontendStatusTypeExt1_1::T2_SYSTEM_ID: { + status.systemId(5); + break; + } + case V1_1::FrontendStatusTypeExt1_1::INTERLEAVINGS: { + V1_1::FrontendInterleaveMode interleave; + interleave.atsc3(FrontendAtsc3TimeInterleaveMode::AUTO); + vector interleaving = {interleave}; + status.interleaving(interleaving); + break; + } + case V1_1::FrontendStatusTypeExt1_1::ISDBT_SEGMENTS: { + vector segments = {2, 3}; + status.isdbtSegment(segments); + break; + } + case V1_1::FrontendStatusTypeExt1_1::TS_DATA_RATES: { + vector dataRates = {4, 5}; + status.tsDataRate(dataRates); + break; + } + default: { + continue; + } + } + statuses.push_back(status); + } + _hidl_cb(Result::SUCCESS, statuses); + + return Void(); +} + Return Frontend::setLna(bool /* bEnable */) { ALOGV("%s", __FUNCTION__); diff --git a/tv/tuner/1.1/default/Frontend.h b/tv/tuner/1.1/default/Frontend.h index a843f6587c..4c357189e4 100644 --- a/tv/tuner/1.1/default/Frontend.h +++ b/tv/tuner/1.1/default/Frontend.h @@ -58,6 +58,10 @@ class Frontend : public V1_1::IFrontend { virtual Return getStatus(const hidl_vec& statusTypes, getStatus_cb _hidl_cb) override; + virtual Return getStatusExt1_1( + const hidl_vec& statusTypes, + V1_1::IFrontend::getStatusExt1_1_cb _hidl_cb) override; + virtual Return setLna(bool bEnable) override; virtual Return setLnb(uint32_t lnb) override; diff --git a/tv/tuner/1.1/types.hal b/tv/tuner/1.1/types.hal index d9c22f8eb9..938751351a 100644 --- a/tv/tuner/1.1/types.hal +++ b/tv/tuner/1.1/types.hal @@ -19,9 +19,25 @@ package android.hardware.tv.tuner@1.1; import @1.0::Constant; import @1.0::DemuxFilterMmtpRecordEvent; import @1.0::DemuxFilterTsRecordEvent; +import @1.0::FrontendAtsc3Bandwidth; +import @1.0::FrontendAtsc3Modulation; +import @1.0::FrontendAtsc3TimeInterleaveMode; +import @1.0::FrontendAtscModulation; +import @1.0::FrontendDvbcModulation; +import @1.0::FrontendDvbtBandwidth; import @1.0::FrontendDvbcSpectralInversion; +import @1.0::FrontendDvbsModulation; import @1.0::FrontendDvbtConstellation; import @1.0::FrontendDvbtTransmissionMode; +import @1.0::FrontendDvbtGuardInterval; +import @1.0::FrontendInnerFec; +import @1.0::FrontendIsdbs3Modulation; +import @1.0::FrontendIsdbsModulation; +import @1.0::FrontendIsdbtBandwidth; +import @1.0::FrontendIsdbtGuardInterval; +import @1.0::FrontendIsdbtMode; +import @1.0::FrontendIsdbtModulation; +import @1.0::FrontendStatusType; import @1.0::FrontendType; import android.hidl.safe_union@1.0; import android.hidl.safe_union@1.0::Monostate; @@ -65,8 +81,7 @@ enum Constant64Bit : uint64_t { struct DemuxFilterRecordEventExt { /** * The Presentation Time Stamp(PTS) for the audio or video frame. It is based on 90KHz - * and has the same format as the PTS in ISO/IEC 13818-1. It is used only for the SC and - * the SC_HEVC. + * and has the same format as the PTS in ISO/IEC 13818-1. */ uint64_t pts; @@ -148,6 +163,8 @@ enum FrontendDvbtConstellation : @1.0::FrontendDvbtConstellation { */ struct FrontendDvbsSettingsExt1_1 { FrontendDvbsScanType scanType; + + bool isDiseqcRxMessage; }; /** @@ -325,3 +342,183 @@ struct FrontendDtmbCapabilities { bitfield interleaveModeCap; }; + +safe_union FrontendModulation { + @1.0::FrontendDvbcModulation dvbc; + + @1.0::FrontendDvbsModulation dvbs; + + FrontendDvbtConstellation dvbt; + + @1.0::FrontendIsdbsModulation isdbs; + + @1.0::FrontendIsdbs3Modulation isdbs3; + + @1.0::FrontendIsdbtModulation isdbt; + + @1.0::FrontendAtscModulation atsc; + + @1.0::FrontendAtsc3Modulation atsc3; + + FrontendDtmbModulation dtmb; +}; + +safe_union FrontendInterleaveMode { + @1.0::FrontendAtsc3TimeInterleaveMode atsc3; + + FrontendDtmbTimeInterleaveMode dtmb; +}; + +@export +enum FrontendInnerFec : @1.0::FrontendInnerFec { + FEC_2_15 = 1 << 36, + FEC_3_15 = 1 << 37, + FEC_5_15 = 1 << 38, + FEC_6_15 = 1 << 39, + FEC_9_15 = 1 << 40, + FEC_10_15 = 1 << 41, + FEC_12_15 = 1 << 42, + FEC_13_15 = 1 << 43, + FEC_18_30 = 1 << 44, + FEC_20_30 = 1 << 45, + FEC_90_180 = 1 << 46, + FEC_96_180 = 1 << 47, + FEC_104_180 = 1 << 48, + FEC_128_180 = 1 << 49, + FEC_132_180 = 1 << 50, + FEC_135_180 = 1 << 51, + FEC_140_180 = 1 << 52, +}; + +safe_union FrontendBandwidth { + @1.0::FrontendAtsc3Bandwidth atsc3; + + @1.0::FrontendDvbtBandwidth dvbt; + + @1.0::FrontendIsdbtBandwidth isdbt; + + FrontendDtmbBandwidth dtmb; +}; + +safe_union FrontendGuardInterval { + @1.0::FrontendDvbtGuardInterval dvbt; + + @1.0::FrontendIsdbtGuardInterval isdbt; + + FrontendDtmbGuardInterval dtmb; +}; + +safe_union FrontendTransmissionMode { + FrontendDvbtTransmissionMode dvbt; + + @1.0::FrontendIsdbtMode isdbt; + + FrontendDtmbTransmissionMode dtmb; +}; + +@export +enum FrontendStatusTypeExt1_1 : uint32_t { + /** + * Modulation Types. + */ + MODULATIONS = @1.0::FrontendStatusType:ATSC3_PLP_INFO + 1, + /** + * Bit Error Ratios. + */ + BERS, + /** + * Code Rates. + */ + CODERATES, + /** + * Extended Bandwidth. + */ + BANDWIDTH, + /** + * Extended Guard Intervals. + */ + GUARD_INTERVAL, + /** + * Extended Transmission Mode. + */ + TRANSMISSION_MODE, + /** + * Uncorrectable Error Counts of the frontend's Physical Layer Pipe (PLP) + * since the last tune operation. + */ + UEC, + /** + * DVB-T2 System Id. + */ + T2_SYSTEM_ID, + /** + * Frontend Interleaving Modes. + */ + INTERLEAVINGS, + /** + * Segments in ISDB-T Specification of all the channels. + */ + ISDBT_SEGMENTS, + /** + * Transport Stream Data Rate in BPS of the current channel. + */ + TS_DATA_RATES, +}; + +safe_union FrontendStatusExt1_1 { + /** + * Extended modulation status. + */ + vec modulations; + + /** + * Extended bit error ratio status. + */ + vec bers; + + /** + * Extended code rate status. + */ + vec codeRates; + + /** + * Extended bandwidth status. + */ + FrontendBandwidth bandwidth; + + /** + * Extended guard interval status. + */ + FrontendGuardInterval interval; + + /** + * Extended transmission mode status. + */ + FrontendTransmissionMode transmissionMode; + + /** + * Uncorrectable Error Counts of the frontend's Physical Layer Pipe (PLP) + * since the last tune operation. + */ + uint32_t uec; + + /** + * The current DVB-T2 system id status. + */ + uint16_t systemId; + + /** + * Frontend Interleaving Modes. + */ + vec interleaving; + + /** + * Segments in ISDB-T Specification of all the channels. + */ + vec isdbtSegment; + + /** + * Transport Stream Data Rate in BPS of the current channel. + */ + vec tsDataRate; +}; diff --git a/tv/tuner/1.1/vts/functional/FrontendTests.cpp b/tv/tuner/1.1/vts/functional/FrontendTests.cpp index bb91e4a771..1700e43553 100644 --- a/tv/tuner/1.1/vts/functional/FrontendTests.cpp +++ b/tv/tuner/1.1/vts/functional/FrontendTests.cpp @@ -254,115 +254,81 @@ AssertionResult FrontendTests::getFrontendDtmbCaps(uint32_t id) { return AssertionResult(status == Result::SUCCESS); } -void FrontendTests::verifyFrontendStatus(vector statusTypes, - vector expectStatuses) { +void FrontendTests::verifyFrontendStatusExt1_1(vector statusTypes, + vector expectStatuses) { ASSERT_TRUE(mFrontend) << "Frontend is not opened yet."; Result status; - vector realStatuses; + vector realStatuses; - mFrontend->getStatus(statusTypes, [&](Result result, const hidl_vec& statuses) { - status = result; - realStatuses = statuses; - }); + sp frontend_1_1; + frontend_1_1 = android::hardware::tv::tuner::V1_1::IFrontend::castFrom(mFrontend); + if (frontend_1_1 == nullptr) { + EXPECT_TRUE(false) << "Couldn't get 1.1 IFrontend from the Hal implementation."; + return; + } + + frontend_1_1->getStatusExt1_1( + statusTypes, [&](Result result, const hidl_vec& statuses) { + status = result; + realStatuses = statuses; + }); ASSERT_TRUE(realStatuses.size() == statusTypes.size()); for (int i = 0; i < statusTypes.size(); i++) { - FrontendStatusType type = statusTypes[i]; + FrontendStatusTypeExt1_1 type = statusTypes[i]; switch (type) { - case FrontendStatusType::DEMOD_LOCK: { - ASSERT_TRUE(realStatuses[i].isDemodLocked() == expectStatuses[i].isDemodLocked()); - break; - } - case FrontendStatusType::SNR: { - ASSERT_TRUE(realStatuses[i].snr() == expectStatuses[i].snr()); - break; - } - case FrontendStatusType::BER: { - ASSERT_TRUE(realStatuses[i].ber() == expectStatuses[i].ber()); - break; - } - case FrontendStatusType::PER: { - ASSERT_TRUE(realStatuses[i].per() == expectStatuses[i].per()); - break; - } - case FrontendStatusType::PRE_BER: { - ASSERT_TRUE(realStatuses[i].preBer() == expectStatuses[i].preBer()); + case FrontendStatusTypeExt1_1::MODULATIONS: { + // TODO: verify modulations break; } - case FrontendStatusType::SIGNAL_QUALITY: { - ASSERT_TRUE(realStatuses[i].signalQuality() == expectStatuses[i].signalQuality()); + case FrontendStatusTypeExt1_1::BERS: { + ASSERT_TRUE(std::equal(realStatuses[i].bers().begin(), realStatuses[i].bers().end(), + expectStatuses[i].bers().begin())); break; } - case FrontendStatusType::SIGNAL_STRENGTH: { - ASSERT_TRUE(realStatuses[i].signalStrength() == expectStatuses[i].signalStrength()); + case FrontendStatusTypeExt1_1::CODERATES: { + ASSERT_TRUE(std::equal(realStatuses[i].codeRates().begin(), + realStatuses[i].codeRates().end(), + expectStatuses[i].codeRates().begin())); break; } - case FrontendStatusType::SYMBOL_RATE: { - ASSERT_TRUE(realStatuses[i].symbolRate() == expectStatuses[i].symbolRate()); + case FrontendStatusTypeExt1_1::GUARD_INTERVAL: { + // TODO: verify interval break; } - case FrontendStatusType::FEC: { - ASSERT_TRUE(realStatuses[i].innerFec() == expectStatuses[i].innerFec()); + case FrontendStatusTypeExt1_1::TRANSMISSION_MODE: { + // TODO: verify tranmission mode break; } - case FrontendStatusType::MODULATION: { - // TODO: check modulation status + case FrontendStatusTypeExt1_1::UEC: { + ASSERT_TRUE(realStatuses[i].uec() == expectStatuses[i].uec()); break; } - case FrontendStatusType::SPECTRAL: { - ASSERT_TRUE(realStatuses[i].inversion() == expectStatuses[i].inversion()); + case FrontendStatusTypeExt1_1::T2_SYSTEM_ID: { + ASSERT_TRUE(realStatuses[i].systemId() == expectStatuses[i].systemId()); break; } - case FrontendStatusType::LNB_VOLTAGE: { - ASSERT_TRUE(realStatuses[i].lnbVoltage() == expectStatuses[i].lnbVoltage()); + case FrontendStatusTypeExt1_1::INTERLEAVINGS: { + ASSERT_TRUE(std::equal(realStatuses[i].interleaving().begin(), + realStatuses[i].interleaving().end(), + expectStatuses[i].interleaving().begin())); break; } - case FrontendStatusType::PLP_ID: { - ASSERT_TRUE(realStatuses[i].plpId() == expectStatuses[i].plpId()); + case FrontendStatusTypeExt1_1::ISDBT_SEGMENTS: { + ASSERT_TRUE(std::equal(realStatuses[i].isdbtSegment().begin(), + realStatuses[i].isdbtSegment().end(), + expectStatuses[i].isdbtSegment().begin())); break; } - case FrontendStatusType::EWBS: { - ASSERT_TRUE(realStatuses[i].isEWBS() == expectStatuses[i].isEWBS()); + case FrontendStatusTypeExt1_1::TS_DATA_RATES: { + ASSERT_TRUE(std::equal(realStatuses[i].tsDataRate().begin(), + realStatuses[i].tsDataRate().end(), + expectStatuses[i].tsDataRate().begin())); break; } - case FrontendStatusType::AGC: { - ASSERT_TRUE(realStatuses[i].agc() == expectStatuses[i].agc()); - break; - } - case FrontendStatusType::LNA: { - ASSERT_TRUE(realStatuses[i].isLnaOn() == expectStatuses[i].isLnaOn()); - break; - } - case FrontendStatusType::LAYER_ERROR: { - vector realLayberError = realStatuses[i].isLayerError(); - vector expectLayerError = expectStatuses[i].isLayerError(); - ASSERT_TRUE(realLayberError.size() == expectLayerError.size()); - for (int i = 0; i < realLayberError.size(); i++) { - ASSERT_TRUE(realLayberError[i] == expectLayerError[i]); - } - break; - } - case FrontendStatusType::MER: { - ASSERT_TRUE(realStatuses[i].mer() == expectStatuses[i].mer()); - break; - } - case FrontendStatusType::FREQ_OFFSET: { - ASSERT_TRUE(realStatuses[i].freqOffset() == expectStatuses[i].freqOffset()); - break; - } - case FrontendStatusType::HIERARCHY: { - ASSERT_TRUE(realStatuses[i].hierarchy() == expectStatuses[i].hierarchy()); - break; - } - case FrontendStatusType::RF_LOCK: { - ASSERT_TRUE(realStatuses[i].isRfLocked() == expectStatuses[i].isRfLocked()); - break; - } - case FrontendStatusType::ATSC3_PLP_INFO: - // TODO: verify plpinfo - break; - default: + default: { continue; + } } } ASSERT_TRUE(status == Result::SUCCESS); @@ -433,7 +399,7 @@ void FrontendTests::tuneTest(FrontendConfig frontendConf) { ASSERT_TRUE(openFrontendById(feId)); ASSERT_TRUE(setFrontendCallback()); ASSERT_TRUE(tuneFrontend(frontendConf, false /*testWithDemux*/)); - verifyFrontendStatus(frontendConf.tuneStatusTypes, frontendConf.expectTuneStatuses); + verifyFrontendStatusExt1_1(frontendConf.tuneStatusTypes, frontendConf.expectTuneStatuses); ASSERT_TRUE(stopTuneFrontend(false /*testWithDemux*/)); ASSERT_TRUE(closeFrontend()); } diff --git a/tv/tuner/1.1/vts/functional/FrontendTests.h b/tv/tuner/1.1/vts/functional/FrontendTests.h index cb238e8d00..106f653303 100644 --- a/tv/tuner/1.1/vts/functional/FrontendTests.h +++ b/tv/tuner/1.1/vts/functional/FrontendTests.h @@ -110,8 +110,8 @@ class FrontendTests { AssertionResult scanFrontend(FrontendConfig config, FrontendScanType type); AssertionResult stopScanFrontend(); AssertionResult tuneFrontend(FrontendConfig config, bool testWithDemux); - void verifyFrontendStatus(vector statusTypes, - vector expectStatuses); + void verifyFrontendStatusExt1_1(vector statusTypes, + vector expectStatuses); AssertionResult stopTuneFrontend(bool testWithDemux); AssertionResult closeFrontend(); AssertionResult getFrontendDtmbCaps(uint32_t); diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h index c6ebecb189..a3bfa1f87a 100644 --- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h @@ -43,12 +43,12 @@ using android::hardware::tv::tuner::V1_0::FrontendDvbtSettings; using android::hardware::tv::tuner::V1_0::FrontendDvbtStandard; using android::hardware::tv::tuner::V1_0::FrontendDvbtTransmissionMode; using android::hardware::tv::tuner::V1_0::FrontendSettings; -using android::hardware::tv::tuner::V1_0::FrontendStatus; -using android::hardware::tv::tuner::V1_0::FrontendStatusType; using android::hardware::tv::tuner::V1_0::FrontendType; using android::hardware::tv::tuner::V1_0::PlaybackSettings; using android::hardware::tv::tuner::V1_0::RecordSettings; using android::hardware::tv::tuner::V1_1::FrontendSettingsExt1_1; +using android::hardware::tv::tuner::V1_1::FrontendStatusExt1_1; +using android::hardware::tv::tuner::V1_1::FrontendStatusTypeExt1_1; using namespace std; @@ -101,8 +101,8 @@ struct FrontendConfig { FrontendType type; FrontendSettings settings; FrontendSettingsExt1_1 settingsExt1_1; - vector tuneStatusTypes; - vector expectTuneStatuses; + vector tuneStatusTypes; + vector expectTuneStatuses; }; struct DvrConfig { @@ -132,11 +132,11 @@ inline void initFrontendConfig() { .standard = FrontendDvbtStandard::T, }; frontendArray[DVBT].type = FrontendType::DVBT, frontendArray[DVBT].settings.dvbt(dvbtSettings); - vector types; - types.push_back(FrontendStatusType::DEMOD_LOCK); - FrontendStatus status; - status.isDemodLocked(true); - vector statuses; + vector types; + types.push_back(FrontendStatusTypeExt1_1::UEC); + FrontendStatusExt1_1 status; + status.uec(4); + vector statuses; statuses.push_back(status); frontendArray[DVBT].tuneStatusTypes = types; frontendArray[DVBT].expectTuneStatuses = statuses; -- GitLab From 19ed17bf1d6f75a1627a8cac2b90f6bbd5b37a58 Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Tue, 4 Aug 2020 10:23:52 -0700 Subject: [PATCH 185/790] Extend Scan Message and Message Type in Tuner HAL 1.1 A new API would be added in IFrontendCallback 1.1: onScanMessageExt to receive the extended scan message Test: atest VtsHalTvTunerV1_1TargetTest Bug: 158818695 Change-Id: If12535dada78ee2d2c7282ff17f9ab5f4983c750 --- tv/tuner/1.1/Android.bp | 1 + tv/tuner/1.1/IFrontendCallback.hal | 32 +++++++++++++ tv/tuner/1.1/default/Frontend.cpp | 13 +++++- tv/tuner/1.1/types.hal | 7 +++ tv/tuner/1.1/vts/functional/FrontendTests.cpp | 45 +++++++++++++++++++ tv/tuner/1.1/vts/functional/FrontendTests.h | 11 ++++- 6 files changed, 106 insertions(+), 3 deletions(-) create mode 100644 tv/tuner/1.1/IFrontendCallback.hal diff --git a/tv/tuner/1.1/Android.bp b/tv/tuner/1.1/Android.bp index 6cf47f57b6..daa3683fd7 100644 --- a/tv/tuner/1.1/Android.bp +++ b/tv/tuner/1.1/Android.bp @@ -7,6 +7,7 @@ hidl_interface { "IFilter.hal", "IFrontend.hal", "IFilterCallback.hal", + "IFrontendCallback.hal", "ITuner.hal", "types.hal", ], diff --git a/tv/tuner/1.1/IFrontendCallback.hal b/tv/tuner/1.1/IFrontendCallback.hal new file mode 100644 index 0000000000..e148b1ef48 --- /dev/null +++ b/tv/tuner/1.1/IFrontendCallback.hal @@ -0,0 +1,32 @@ +/* + * 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. + */ + +package android.hardware.tv.tuner@1.1; + +import @1.0::IFrontendCallback; +import FrontendScanMessageExt1_1; +import FrontendScanMessageTypeExt1_1; + +interface IFrontendCallback extends @1.0::IFrontendCallback { + /** + * The callback function that must be called by HAL implementation to notify + * the client of the v1_1 extended scan messages. + * + * @param type the type of v1_1 extended scan message. + * @param message the v1_1 extended scan message sent by HAL to the client. + */ + onScanMessageExt1_1(FrontendScanMessageTypeExt1_1 type, FrontendScanMessageExt1_1 messageExt); +}; diff --git a/tv/tuner/1.1/default/Frontend.cpp b/tv/tuner/1.1/default/Frontend.cpp index c5aeace1b5..971e335700 100644 --- a/tv/tuner/1.1/default/Frontend.cpp +++ b/tv/tuner/1.1/default/Frontend.cpp @@ -17,7 +17,7 @@ #define LOG_TAG "android.hardware.tv.tuner@1.1-Frontend" #include "Frontend.h" -#include +#include #include namespace android { @@ -118,6 +118,17 @@ Return Frontend::scan(const FrontendSettings& settings, FrontendScanType mCallback->onScanMessage(FrontendScanMessageType::LOCKED, msg); mIsLocked = true; + sp frontendCallback_v1_1 = + V1_1::IFrontendCallback::castFrom(mCallback); + if (frontendCallback_v1_1 != NULL) { + V1_1::FrontendScanMessageExt1_1 msg; + msg.dvbc(FrontendDvbcModulation::MOD_16QAM); + frontendCallback_v1_1->onScanMessageExt1_1(V1_1::FrontendScanMessageTypeExt1_1::MODULATION, + msg); + } else { + ALOGD("[Filter] Couldn't cast to V1_1 IFrontendCallback"); + } + return Result::SUCCESS; } diff --git a/tv/tuner/1.1/types.hal b/tv/tuner/1.1/types.hal index 938751351a..29b999f4d5 100644 --- a/tv/tuner/1.1/types.hal +++ b/tv/tuner/1.1/types.hal @@ -37,6 +37,7 @@ import @1.0::FrontendIsdbtBandwidth; import @1.0::FrontendIsdbtGuardInterval; import @1.0::FrontendIsdbtMode; import @1.0::FrontendIsdbtModulation; +import @1.0::FrontendScanMessageType; import @1.0::FrontendStatusType; import @1.0::FrontendType; import android.hidl.safe_union@1.0; @@ -522,3 +523,9 @@ safe_union FrontendStatusExt1_1 { */ vec tsDataRate; }; + +enum FrontendScanMessageTypeExt1_1 : uint32_t { + MODULATION = @1.0::FrontendScanMessageType:ATSC3_PLP_INFO + 1, +}; + +typedef FrontendModulation FrontendScanMessageExt1_1; diff --git a/tv/tuner/1.1/vts/functional/FrontendTests.cpp b/tv/tuner/1.1/vts/functional/FrontendTests.cpp index 1700e43553..3bc7114b17 100644 --- a/tv/tuner/1.1/vts/functional/FrontendTests.cpp +++ b/tv/tuner/1.1/vts/functional/FrontendTests.cpp @@ -47,6 +47,51 @@ Return FrontendCallback::onScanMessage(FrontendScanMessageType type, return Void(); } +Return FrontendCallback::onScanMessageExt1_1(FrontendScanMessageTypeExt1_1 type, + const FrontendScanMessageExt1_1& message) { + android::Mutex::Autolock autoLock(mMsgLock); + ALOGD("[vts] frontend ext1_1 scan message. Type: %d", type); + switch (type) { + case FrontendScanMessageTypeExt1_1::MODULATION: + readFrontendScanMessageExt1_1Modulation(message); + break; + default: + break; + } + return Void(); +} + +void FrontendCallback::readFrontendScanMessageExt1_1Modulation(FrontendModulation modulation) { + switch (modulation.getDiscriminator()) { + case FrontendModulation::hidl_discriminator::dvbc: + ALOGD("[vts] frontend ext1_1 scan message modulation dvbc: %d", modulation.dvbc()); + break; + case FrontendModulation::hidl_discriminator::dvbs: + ALOGD("[vts] frontend ext1_1 scan message modulation dvbs: %d", modulation.dvbs()); + break; + case FrontendModulation::hidl_discriminator::isdbs: + ALOGD("[vts] frontend ext1_1 scan message modulation isdbs: %d", modulation.isdbs()); + break; + case FrontendModulation::hidl_discriminator::isdbs3: + ALOGD("[vts] frontend ext1_1 scan message modulation isdbs3: %d", modulation.isdbs3()); + break; + case FrontendModulation::hidl_discriminator::isdbt: + ALOGD("[vts] frontend ext1_1 scan message modulation isdbt: %d", modulation.isdbt()); + break; + case FrontendModulation::hidl_discriminator::atsc: + ALOGD("[vts] frontend ext1_1 scan message modulation atsc: %d", modulation.atsc()); + break; + case FrontendModulation::hidl_discriminator::atsc3: + ALOGD("[vts] frontend ext1_1 scan message modulation atsc3: %d", modulation.atsc3()); + break; + case FrontendModulation::hidl_discriminator::dvbt: + ALOGD("[vts] frontend ext1_1 scan message modulation dvbt: %d", modulation.dvbt()); + break; + default: + break; + } +} + void FrontendCallback::tuneTestOnLock(sp& frontend, FrontendSettings settings, FrontendSettingsExt1_1 settingsExt1_1) { sp frontend_1_1; diff --git a/tv/tuner/1.1/vts/functional/FrontendTests.h b/tv/tuner/1.1/vts/functional/FrontendTests.h index 106f653303..243d9decd7 100644 --- a/tv/tuner/1.1/vts/functional/FrontendTests.h +++ b/tv/tuner/1.1/vts/functional/FrontendTests.h @@ -15,9 +15,9 @@ */ #include -#include #include #include +#include #include #include #include @@ -54,9 +54,12 @@ using android::hardware::tv::tuner::V1_0::FrontendScanMessage; using android::hardware::tv::tuner::V1_0::FrontendScanMessageType; using android::hardware::tv::tuner::V1_0::FrontendScanType; using android::hardware::tv::tuner::V1_0::IFrontend; -using android::hardware::tv::tuner::V1_0::IFrontendCallback; using android::hardware::tv::tuner::V1_0::Result; using android::hardware::tv::tuner::V1_1::FrontendDtmbCapabilities; +using android::hardware::tv::tuner::V1_1::FrontendModulation; +using android::hardware::tv::tuner::V1_1::FrontendScanMessageExt1_1; +using android::hardware::tv::tuner::V1_1::FrontendScanMessageTypeExt1_1; +using android::hardware::tv::tuner::V1_1::IFrontendCallback; using android::hardware::tv::tuner::V1_1::ITuner; using ::testing::AssertionResult; @@ -71,6 +74,8 @@ class FrontendCallback : public IFrontendCallback { virtual Return onEvent(FrontendEventType frontendEventType) override; virtual Return onScanMessage(FrontendScanMessageType type, const FrontendScanMessage& message) override; + virtual Return onScanMessageExt1_1(FrontendScanMessageTypeExt1_1 type, + const FrontendScanMessageExt1_1& message) override; void tuneTestOnLock(sp& frontend, FrontendSettings settings, FrontendSettingsExt1_1 settingsExt1_1); @@ -81,6 +86,8 @@ class FrontendCallback : public IFrontendCallback { void resetBlindScanStartingFrequency(FrontendConfig& config, uint32_t resetingFreq); private: + void readFrontendScanMessageExt1_1Modulation(FrontendModulation modulation); + bool mEventReceived = false; bool mScanMessageReceived = false; bool mLockMsgReceived = false; -- GitLab From 621887a91a18eb66997212ab3acb03384538620a Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Wed, 30 Sep 2020 11:33:34 -0700 Subject: [PATCH 186/790] Add DVBC Time Interleave Mode enum in Tuner HAL 1.1 Test: make android.hardware.tv.tuner@1.1 Bug: 158818695 Change-Id: I11ea762a789aaab1cf3a17b3c0515c6a37942098 --- tv/tuner/1.1/types.hal | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/tv/tuner/1.1/types.hal b/tv/tuner/1.1/types.hal index 938751351a..efde55d431 100644 --- a/tv/tuner/1.1/types.hal +++ b/tv/tuner/1.1/types.hal @@ -137,6 +137,24 @@ enum FrontendAnalogAftFlag : uint32_t { AFT_FALSE, }; +/** + * Time Interleave Mode for DVBC Frontend. + */ +@export +enum FrontendCableTimeInterleaveMode : uint32_t { + UNDEFINED = 0, + AUTO = 1 << 0, + INTERLEAVING_128_1_0 = 1 << 1, + INTERLEAVING_128_1_1 = 1 << 2, + INTERLEAVING_64_2 = 1 << 3, + INTERLEAVING_32_4 = 1 << 4, + INTERLEAVING_16_8 = 1 << 5, + INTERLEAVING_8_16 = 1 << 6, + INTERLEAVING_128_2 = 1 << 7, + INTERLEAVING_128_3 = 1 << 8, + INTERLEAVING_128_4 = 1 << 9, +}; + /** * Extended Transmission Mode for DVBT. */ @@ -183,6 +201,13 @@ struct FrontendAnalogSettingsExt1_1 { FrontendAnalogAftFlag aftFlag; }; +/** + * Extended Signal Settings for DVBC Frontend. + */ +struct FrontendDvbcSettingsExt1_1 { + FrontendCableTimeInterleaveMode interleaveMode; +}; + /** * Extended Signal Settings for Frontend. */ @@ -196,6 +221,8 @@ struct FrontendSettingsExt1_1 { FrontendAnalogSettingsExt1_1 analog; + FrontendDvbcSettingsExt1_1 dvbc; + FrontendDvbsSettingsExt1_1 dvbs; FrontendDvbtSettingsExt1_1 dvbt; @@ -366,6 +393,8 @@ safe_union FrontendModulation { safe_union FrontendInterleaveMode { @1.0::FrontendAtsc3TimeInterleaveMode atsc3; + FrontendCableTimeInterleaveMode dvbc; + FrontendDtmbTimeInterleaveMode dtmb; }; -- GitLab From a685c3dbf4afb35d0a80488155ce2bde30c9d6e9 Mon Sep 17 00:00:00 2001 From: Michael Butler Date: Sat, 22 Feb 2020 22:37:59 -0800 Subject: [PATCH 187/790] Create conversions to/from NNAPI canonical types This CL creates the following primary sets of functions: * V1_X::utils::convert() -- Converts a canonical type to the corresponding HAL version type. * nn::convert() -- Converts a HAL version type to the corresponding canonical type. * neuralnetworks::utils::hasNoPointerData -- Indicates if the object contains no pointer-based data that could be relocated to shared memory. * neuralnetworks::utils::flushDataFromPointerToShared -- Relocate pointer-based data to shared memory. * neuralnetworks::utils::unflushDataFromSharedToPointer -- Undoes `flushDataFromPointerToShared` on a Request object. More specifically, `unflushDataFromSharedToPointer` copies the output shared memory data from the transformed Request object back to the output pointer-based memory in the original Request object. It also introduces some other minor utility code, including makeQuantized8PerformanceConsistentWithP, countNumberOfConsumers, validate, valid, and validatedConvertToCanonical. Bug: 160667419 Test: mma Change-Id: I0732e658c1f4ed40cd122f1ca8581fb40b056757 --- neuralnetworks/1.0/utils/Android.bp | 33 ++ neuralnetworks/1.0/utils/OWNERS | 11 + .../utils/include/nnapi/hal/1.0/Conversions.h | 66 +++ .../1.0/utils/include/nnapi/hal/1.0/Utils.h | 63 ++ neuralnetworks/1.0/utils/src/Assertions.cpp | 122 ++++ neuralnetworks/1.0/utils/src/Conversions.cpp | 361 ++++++++++++ neuralnetworks/1.1/utils/Android.bp | 35 ++ neuralnetworks/1.1/utils/OWNERS | 11 + .../utils/include/nnapi/hal/1.1/Conversions.h | 45 ++ .../1.1/utils/include/nnapi/hal/1.1/Utils.h | 65 +++ neuralnetworks/1.1/utils/src/Assertions.cpp | 100 ++++ neuralnetworks/1.1/utils/src/Conversions.cpp | 209 +++++++ neuralnetworks/1.2/utils/Android.bp | 37 ++ neuralnetworks/1.2/utils/OWNERS | 11 + .../utils/include/nnapi/hal/1.2/Conversions.h | 86 +++ .../1.2/utils/include/nnapi/hal/1.2/Utils.h | 70 +++ neuralnetworks/1.2/utils/src/Assertions.cpp | 188 ++++++ neuralnetworks/1.2/utils/src/Conversions.cpp | 502 ++++++++++++++++ neuralnetworks/1.3/utils/Android.bp | 39 ++ neuralnetworks/1.3/utils/OWNERS | 11 + .../utils/include/nnapi/hal/1.3/Conversions.h | 79 +++ .../1.3/utils/include/nnapi/hal/1.3/Utils.h | 67 +++ neuralnetworks/1.3/utils/src/Assertions.cpp | 218 +++++++ neuralnetworks/1.3/utils/src/Conversions.cpp | 552 ++++++++++++++++++ neuralnetworks/utils/OWNERS | 11 + neuralnetworks/utils/common/Android.bp | 29 + .../common/include/nnapi/hal/CommonUtils.h | 59 ++ .../utils/common/src/CommonUtils.cpp | 224 +++++++ 28 files changed, 3304 insertions(+) create mode 100644 neuralnetworks/1.0/utils/Android.bp create mode 100644 neuralnetworks/1.0/utils/OWNERS create mode 100644 neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Conversions.h create mode 100644 neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Utils.h create mode 100644 neuralnetworks/1.0/utils/src/Assertions.cpp create mode 100644 neuralnetworks/1.0/utils/src/Conversions.cpp create mode 100644 neuralnetworks/1.1/utils/Android.bp create mode 100644 neuralnetworks/1.1/utils/OWNERS create mode 100644 neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Conversions.h create mode 100644 neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Utils.h create mode 100644 neuralnetworks/1.1/utils/src/Assertions.cpp create mode 100644 neuralnetworks/1.1/utils/src/Conversions.cpp create mode 100644 neuralnetworks/1.2/utils/Android.bp create mode 100644 neuralnetworks/1.2/utils/OWNERS create mode 100644 neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Conversions.h create mode 100644 neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Utils.h create mode 100644 neuralnetworks/1.2/utils/src/Assertions.cpp create mode 100644 neuralnetworks/1.2/utils/src/Conversions.cpp create mode 100644 neuralnetworks/1.3/utils/Android.bp create mode 100644 neuralnetworks/1.3/utils/OWNERS create mode 100644 neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Conversions.h create mode 100644 neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Utils.h create mode 100644 neuralnetworks/1.3/utils/src/Assertions.cpp create mode 100644 neuralnetworks/1.3/utils/src/Conversions.cpp create mode 100644 neuralnetworks/utils/OWNERS create mode 100644 neuralnetworks/utils/common/Android.bp create mode 100644 neuralnetworks/utils/common/include/nnapi/hal/CommonUtils.h create mode 100644 neuralnetworks/utils/common/src/CommonUtils.cpp diff --git a/neuralnetworks/1.0/utils/Android.bp b/neuralnetworks/1.0/utils/Android.bp new file mode 100644 index 0000000000..57a052f1f5 --- /dev/null +++ b/neuralnetworks/1.0/utils/Android.bp @@ -0,0 +1,33 @@ +// +// 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. +// + +cc_library_static { + name: "neuralnetworks_utils_hal_1_0", + defaults: ["neuralnetworks_utils_defaults"], + srcs: ["src/*"], + local_include_dirs: ["include/nnapi/hal/1.0/"], + export_include_dirs: ["include"], + static_libs: [ + "neuralnetworks_types", + "neuralnetworks_utils_hal_common", + ], + shared_libs: [ + "android.hardware.neuralnetworks@1.0", + ], + export_static_lib_headers: [ + "neuralnetworks_utils_hal_common", + ], +} diff --git a/neuralnetworks/1.0/utils/OWNERS b/neuralnetworks/1.0/utils/OWNERS new file mode 100644 index 0000000000..e4feee3496 --- /dev/null +++ b/neuralnetworks/1.0/utils/OWNERS @@ -0,0 +1,11 @@ +# Neuralnetworks team +butlermichael@google.com +dgross@google.com +galarragas@google.com +jeanluc@google.com +levp@google.com +miaowang@google.com +pszczepaniak@google.com +slavash@google.com +vddang@google.com +xusongw@google.com diff --git a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Conversions.h b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Conversions.h new file mode 100644 index 0000000000..8ad98cbafc --- /dev/null +++ b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Conversions.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_0_CONVERSIONS_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_0_CONVERSIONS_H + +#include +#include +#include +#include + +namespace android::nn { + +Result convert(const hal::V1_0::OperandType& operandType); +Result convert(const hal::V1_0::OperationType& operationType); +Result convert(const hal::V1_0::OperandLifeTime& lifetime); +Result convert(const hal::V1_0::DeviceStatus& deviceStatus); +Result convert(const hal::V1_0::PerformanceInfo& performanceInfo); +Result convert(const hal::V1_0::Capabilities& capabilities); +Result convert(const hal::V1_0::DataLocation& location); +Result convert(const hal::V1_0::Operand& operand); +Result convert(const hal::V1_0::Operation& operation); +Result convert(const hardware::hidl_vec& operandValues); +Result convert(const hardware::hidl_memory& memory); +Result convert(const hal::V1_0::Model& model); +Result convert(const hal::V1_0::RequestArgument& requestArgument); +Result convert(const hal::V1_0::Request& request); +Result convert(const hal::V1_0::ErrorStatus& status); + +} // namespace android::nn + +namespace android::hardware::neuralnetworks::V1_0::utils { + +nn::Result convert(const nn::OperandType& operandType); +nn::Result convert(const nn::OperationType& operationType); +nn::Result convert(const nn::Operand::LifeTime& lifetime); +nn::Result convert(const nn::DeviceStatus& deviceStatus); +nn::Result convert(const nn::Capabilities::PerformanceInfo& performanceInfo); +nn::Result convert(const nn::Capabilities& capabilities); +nn::Result convert(const nn::DataLocation& location); +nn::Result convert(const nn::Operand& operand); +nn::Result convert(const nn::Operation& operation); +nn::Result> convert(const nn::Model::OperandValues& operandValues); +nn::Result convert(const nn::Memory& memory); +nn::Result convert(const nn::Model& model); +nn::Result convert(const nn::Request::Argument& requestArgument); +nn::Result convert(const nn::Request::MemoryPool& memoryPool); +nn::Result convert(const nn::Request& request); +nn::Result convert(const nn::ErrorStatus& status); + +} // namespace android::hardware::neuralnetworks::V1_0::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_0_CONVERSIONS_H diff --git a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Utils.h b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Utils.h new file mode 100644 index 0000000000..ec8da06ca6 --- /dev/null +++ b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Utils.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_0_UTILS_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_0_UTILS_H + +#include "nnapi/hal/1.0/Conversions.h" + +#include +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::V1_0::utils { + +constexpr auto kVersion = nn::Version::ANDROID_OC_MR1; + +template +nn::Result validate(const Type& halObject) { + const auto canonical = NN_TRY(nn::convert(halObject)); + const auto version = NN_TRY(nn::validate(canonical)); + if (version > utils::kVersion) { + return NN_ERROR() << ""; + } + return {}; +} + +template +bool valid(const Type& halObject) { + const auto result = utils::validate(halObject); + if (!result.has_value()) { + LOG(ERROR) << result.error(); + } + return result.has_value(); +} + +template +decltype(nn::convert(std::declval())) validatedConvertToCanonical(const Type& halObject) { + auto canonical = NN_TRY(nn::convert(halObject)); + const auto version = NN_TRY(nn::validate(canonical)); + if (version > utils::kVersion) { + return NN_ERROR() << ""; + } + return canonical; +} + +} // namespace android::hardware::neuralnetworks::V1_0::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_0_UTILS_H diff --git a/neuralnetworks/1.0/utils/src/Assertions.cpp b/neuralnetworks/1.0/utils/src/Assertions.cpp new file mode 100644 index 0000000000..0f0095196d --- /dev/null +++ b/neuralnetworks/1.0/utils/src/Assertions.cpp @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +namespace { + +#define COMPARE_ENUMS_TYPES(lhsType, rhsType) \ + static_assert( \ + std::is_same_v< \ + std::underlying_type_t<::android::hardware::neuralnetworks::V1_0::lhsType>, \ + std::underlying_type_t<::android::nn::rhsType>>, \ + "::android::hardware::neuralnetworks::V1_0::" #lhsType \ + " does not have the same underlying type as ::android::nn::" #rhsType) + +COMPARE_ENUMS_TYPES(OperandType, OperandType); +COMPARE_ENUMS_TYPES(OperationType, OperationType); +COMPARE_ENUMS_TYPES(ErrorStatus, ErrorStatus); +COMPARE_ENUMS_TYPES(OperandLifeTime, Operand::LifeTime); + +#undef COMPARE_ENUMS_TYPES + +#define COMPARE_ENUMS_FULL(lhsSymbol, rhsSymbol, lhsType, rhsType) \ + static_assert( \ + static_cast< \ + std::underlying_type_t<::android::hardware::neuralnetworks::V1_0::lhsType>>( \ + ::android::hardware::neuralnetworks::V1_0::lhsType::lhsSymbol) == \ + static_cast>( \ + ::android::nn::rhsType::rhsSymbol), \ + "::android::hardware::neuralnetworks::V1_0::" #lhsType "::" #lhsSymbol \ + " does not match ::android::nn::" #rhsType "::" #rhsSymbol) + +#define COMPARE_ENUMS(symbol) COMPARE_ENUMS_FULL(symbol, symbol, OperandType, OperandType) + +COMPARE_ENUMS(FLOAT32); +COMPARE_ENUMS(INT32); +COMPARE_ENUMS(UINT32); +COMPARE_ENUMS(TENSOR_FLOAT32); +COMPARE_ENUMS(TENSOR_INT32); +COMPARE_ENUMS(TENSOR_QUANT8_ASYMM); +COMPARE_ENUMS(OEM); +COMPARE_ENUMS(TENSOR_OEM_BYTE); + +#undef COMPARE_ENUMS + +#define COMPARE_ENUMS(symbol) COMPARE_ENUMS_FULL(symbol, symbol, OperationType, OperationType) + +COMPARE_ENUMS(ADD); +COMPARE_ENUMS(AVERAGE_POOL_2D); +COMPARE_ENUMS(CONCATENATION); +COMPARE_ENUMS(CONV_2D); +COMPARE_ENUMS(DEPTHWISE_CONV_2D); +COMPARE_ENUMS(DEPTH_TO_SPACE); +COMPARE_ENUMS(DEQUANTIZE); +COMPARE_ENUMS(EMBEDDING_LOOKUP); +COMPARE_ENUMS(FLOOR); +COMPARE_ENUMS(FULLY_CONNECTED); +COMPARE_ENUMS(HASHTABLE_LOOKUP); +COMPARE_ENUMS(L2_NORMALIZATION); +COMPARE_ENUMS(L2_POOL_2D); +COMPARE_ENUMS(LOCAL_RESPONSE_NORMALIZATION); +COMPARE_ENUMS(LOGISTIC); +COMPARE_ENUMS(LSH_PROJECTION); +COMPARE_ENUMS(LSTM); +COMPARE_ENUMS(MAX_POOL_2D); +COMPARE_ENUMS(MUL); +COMPARE_ENUMS(RELU); +COMPARE_ENUMS(RELU1); +COMPARE_ENUMS(RELU6); +COMPARE_ENUMS(RESHAPE); +COMPARE_ENUMS(RESIZE_BILINEAR); +COMPARE_ENUMS(RNN); +COMPARE_ENUMS(SOFTMAX); +COMPARE_ENUMS(SPACE_TO_DEPTH); +COMPARE_ENUMS(SVDF); +COMPARE_ENUMS(TANH); +COMPARE_ENUMS(OEM_OPERATION); + +#undef COMPARE_ENUMS + +#define COMPARE_ENUMS(symbol) COMPARE_ENUMS_FULL(symbol, symbol, ErrorStatus, ErrorStatus) + +COMPARE_ENUMS(NONE); +COMPARE_ENUMS(DEVICE_UNAVAILABLE); +COMPARE_ENUMS(GENERAL_FAILURE); +COMPARE_ENUMS(OUTPUT_INSUFFICIENT_SIZE); +COMPARE_ENUMS(INVALID_ARGUMENT); + +#undef COMPARE_ENUMS + +#define COMPARE_ENUMS(lhsSymbol, rhsSymbol) \ + COMPARE_ENUMS_FULL(lhsSymbol, rhsSymbol, OperandLifeTime, Operand::LifeTime) + +COMPARE_ENUMS(TEMPORARY_VARIABLE, TEMPORARY_VARIABLE); +COMPARE_ENUMS(MODEL_INPUT, SUBGRAPH_INPUT); +COMPARE_ENUMS(MODEL_OUTPUT, SUBGRAPH_OUTPUT); +COMPARE_ENUMS(CONSTANT_COPY, CONSTANT_COPY); +COMPARE_ENUMS(CONSTANT_REFERENCE, CONSTANT_REFERENCE); +COMPARE_ENUMS(NO_VALUE, NO_VALUE); + +#undef COMPARE_ENUMS + +#undef COMPARE_ENUMS_FULL + +} // anonymous namespace diff --git a/neuralnetworks/1.0/utils/src/Conversions.cpp b/neuralnetworks/1.0/utils/src/Conversions.cpp new file mode 100644 index 0000000000..4a58f3b93c --- /dev/null +++ b/neuralnetworks/1.0/utils/src/Conversions.cpp @@ -0,0 +1,361 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Conversions.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace { + +template +constexpr std::underlying_type_t underlyingType(Type value) { + return static_cast>(value); +} + +} // namespace + +namespace android::nn { +namespace { + +using hardware::hidl_memory; +using hardware::hidl_vec; + +template +using ConvertOutput = std::decay_t()).value())>; + +template +Result>> convert(const hidl_vec& arguments) { + std::vector> canonical; + canonical.reserve(arguments.size()); + for (const auto& argument : arguments) { + canonical.push_back(NN_TRY(nn::convert(argument))); + } + return canonical; +} + +} // anonymous namespace + +Result convert(const hal::V1_0::OperandType& operandType) { + return static_cast(operandType); +} + +Result convert(const hal::V1_0::OperationType& operationType) { + return static_cast(operationType); +} + +Result convert(const hal::V1_0::OperandLifeTime& lifetime) { + return static_cast(lifetime); +} + +Result convert(const hal::V1_0::DeviceStatus& deviceStatus) { + return static_cast(deviceStatus); +} + +Result convert(const hal::V1_0::PerformanceInfo& performanceInfo) { + return Capabilities::PerformanceInfo{ + .execTime = performanceInfo.execTime, + .powerUsage = performanceInfo.powerUsage, + }; +} + +Result convert(const hal::V1_0::Capabilities& capabilities) { + const auto quantized8Performance = NN_TRY(convert(capabilities.quantized8Performance)); + const auto float32Performance = NN_TRY(convert(capabilities.float32Performance)); + + auto table = hal::utils::makeQuantized8PerformanceConsistentWithP(float32Performance, + quantized8Performance); + + return Capabilities{ + .relaxedFloat32toFloat16PerformanceScalar = float32Performance, + .relaxedFloat32toFloat16PerformanceTensor = float32Performance, + .operandPerformance = std::move(table), + }; +} + +Result convert(const hal::V1_0::DataLocation& location) { + return DataLocation{ + .poolIndex = location.poolIndex, + .offset = location.offset, + .length = location.length, + }; +} + +Result convert(const hal::V1_0::Operand& operand) { + return Operand{ + .type = NN_TRY(convert(operand.type)), + .dimensions = operand.dimensions, + .scale = operand.scale, + .zeroPoint = operand.zeroPoint, + .lifetime = NN_TRY(convert(operand.lifetime)), + .location = NN_TRY(convert(operand.location)), + }; +} + +Result convert(const hal::V1_0::Operation& operation) { + return Operation{ + .type = NN_TRY(convert(operation.type)), + .inputs = operation.inputs, + .outputs = operation.outputs, + }; +} + +Result convert(const hidl_vec& operandValues) { + return Model::OperandValues(operandValues.data(), operandValues.size()); +} + +Result convert(const hidl_memory& memory) { + return createSharedMemoryFromHidlMemory(memory); +} + +Result convert(const hal::V1_0::Model& model) { + auto operations = NN_TRY(convert(model.operations)); + + // Verify number of consumers. + const auto numberOfConsumers = + hal::utils::countNumberOfConsumers(model.operands.size(), operations); + CHECK(model.operands.size() == numberOfConsumers.size()); + for (size_t i = 0; i < model.operands.size(); ++i) { + if (model.operands[i].numberOfConsumers != numberOfConsumers[i]) { + return NN_ERROR() << "Invalid numberOfConsumers for operand " << i << ", expected " + << numberOfConsumers[i] << " but found " + << model.operands[i].numberOfConsumers; + } + } + + auto main = Model::Subgraph{ + .operands = NN_TRY(convert(model.operands)), + .operations = std::move(operations), + .inputIndexes = model.inputIndexes, + .outputIndexes = model.outputIndexes, + }; + + return Model{ + .main = std::move(main), + .operandValues = NN_TRY(convert(model.operandValues)), + .pools = NN_TRY(convert(model.pools)), + }; +} + +Result convert(const hal::V1_0::RequestArgument& argument) { + const auto lifetime = argument.hasNoValue ? Request::Argument::LifeTime::NO_VALUE + : Request::Argument::LifeTime::POOL; + return Request::Argument{ + .lifetime = lifetime, + .location = NN_TRY(convert(argument.location)), + .dimensions = argument.dimensions, + }; +} + +Result convert(const hal::V1_0::Request& request) { + auto memories = NN_TRY(convert(request.pools)); + std::vector pools; + pools.reserve(memories.size()); + std::move(memories.begin(), memories.end(), std::back_inserter(pools)); + + return Request{ + .inputs = NN_TRY(convert(request.inputs)), + .outputs = NN_TRY(convert(request.outputs)), + .pools = std::move(pools), + }; +} + +Result convert(const hal::V1_0::ErrorStatus& status) { + switch (status) { + case hal::V1_0::ErrorStatus::NONE: + case hal::V1_0::ErrorStatus::DEVICE_UNAVAILABLE: + case hal::V1_0::ErrorStatus::GENERAL_FAILURE: + case hal::V1_0::ErrorStatus::OUTPUT_INSUFFICIENT_SIZE: + case hal::V1_0::ErrorStatus::INVALID_ARGUMENT: + return static_cast(status); + } + return NN_ERROR() << "Invalid ErrorStatus " << underlyingType(status); +} + +} // namespace android::nn + +namespace android::hardware::neuralnetworks::V1_0::utils { +namespace { + +template +using ConvertOutput = std::decay_t()).value())>; + +template +nn::Result>> convert(const std::vector& arguments) { + hidl_vec> halObject(arguments.size()); + for (size_t i = 0; i < arguments.size(); ++i) { + halObject[i] = NN_TRY(utils::convert(arguments[i])); + } + return halObject; +} + +} // anonymous namespace + +nn::Result convert(const nn::OperandType& operandType) { + return static_cast(operandType); +} + +nn::Result convert(const nn::OperationType& operationType) { + return static_cast(operationType); +} + +nn::Result convert(const nn::Operand::LifeTime& lifetime) { + if (lifetime == nn::Operand::LifeTime::POINTER) { + return NN_ERROR() << "Model cannot be converted because it contains pointer-based memory"; + } + return static_cast(lifetime); +} + +nn::Result convert(const nn::DeviceStatus& deviceStatus) { + return static_cast(deviceStatus); +} + +nn::Result convert(const nn::Capabilities::PerformanceInfo& performanceInfo) { + return PerformanceInfo{ + .execTime = performanceInfo.execTime, + .powerUsage = performanceInfo.powerUsage, + }; +} + +nn::Result convert(const nn::Capabilities& capabilities) { + return Capabilities{ + .float32Performance = NN_TRY(convert( + capabilities.operandPerformance.lookup(nn::OperandType::TENSOR_FLOAT32))), + .quantized8Performance = NN_TRY(convert( + capabilities.operandPerformance.lookup(nn::OperandType::TENSOR_QUANT8_ASYMM))), + }; +} + +nn::Result convert(const nn::DataLocation& location) { + return DataLocation{ + .poolIndex = location.poolIndex, + .offset = location.offset, + .length = location.length, + }; +} + +nn::Result convert(const nn::Operand& operand) { + return Operand{ + .type = NN_TRY(convert(operand.type)), + .dimensions = operand.dimensions, + .numberOfConsumers = 0, + .scale = operand.scale, + .zeroPoint = operand.zeroPoint, + .lifetime = NN_TRY(convert(operand.lifetime)), + .location = NN_TRY(convert(operand.location)), + }; +} + +nn::Result convert(const nn::Operation& operation) { + return Operation{ + .type = NN_TRY(convert(operation.type)), + .inputs = operation.inputs, + .outputs = operation.outputs, + }; +} + +nn::Result> convert(const nn::Model::OperandValues& operandValues) { + return hidl_vec(operandValues.data(), operandValues.data() + operandValues.size()); +} + +nn::Result convert(const nn::Memory& memory) { + const auto hidlMemory = hidl_memory(memory.name, memory.handle->handle(), memory.size); + // Copy memory to force the native_handle_t to be copied. + auto copiedMemory = hidlMemory; + return copiedMemory; +} + +nn::Result convert(const nn::Model& model) { + if (!hal::utils::hasNoPointerData(model)) { + return NN_ERROR() << "Mdoel cannot be converted because it contains pointer-based memory"; + } + + auto operands = NN_TRY(convert(model.main.operands)); + + // Update number of consumers. + const auto numberOfConsumers = + hal::utils::countNumberOfConsumers(operands.size(), model.main.operations); + CHECK(operands.size() == numberOfConsumers.size()); + for (size_t i = 0; i < operands.size(); ++i) { + operands[i].numberOfConsumers = numberOfConsumers[i]; + } + + return Model{ + .operands = std::move(operands), + .operations = NN_TRY(convert(model.main.operations)), + .inputIndexes = model.main.inputIndexes, + .outputIndexes = model.main.outputIndexes, + .operandValues = NN_TRY(convert(model.operandValues)), + .pools = NN_TRY(convert(model.pools)), + }; +} + +nn::Result convert(const nn::Request::Argument& requestArgument) { + if (requestArgument.lifetime == nn::Request::Argument::LifeTime::POINTER) { + return NN_ERROR() << "Request cannot be converted because it contains pointer-based memory"; + } + const bool hasNoValue = requestArgument.lifetime == nn::Request::Argument::LifeTime::NO_VALUE; + return RequestArgument{ + .hasNoValue = hasNoValue, + .location = NN_TRY(convert(requestArgument.location)), + .dimensions = requestArgument.dimensions, + }; +} + +nn::Result convert(const nn::Request::MemoryPool& memoryPool) { + return convert(std::get(memoryPool)); +} + +nn::Result convert(const nn::Request& request) { + if (!hal::utils::hasNoPointerData(request)) { + return NN_ERROR() << "Request cannot be converted because it contains pointer-based memory"; + } + + return Request{ + .inputs = NN_TRY(convert(request.inputs)), + .outputs = NN_TRY(convert(request.outputs)), + .pools = NN_TRY(convert(request.pools)), + }; +} + +nn::Result convert(const nn::ErrorStatus& status) { + switch (status) { + case nn::ErrorStatus::NONE: + case nn::ErrorStatus::DEVICE_UNAVAILABLE: + case nn::ErrorStatus::GENERAL_FAILURE: + case nn::ErrorStatus::OUTPUT_INSUFFICIENT_SIZE: + case nn::ErrorStatus::INVALID_ARGUMENT: + return static_cast(status); + default: + return ErrorStatus::GENERAL_FAILURE; + } +} + +} // namespace android::hardware::neuralnetworks::V1_0::utils diff --git a/neuralnetworks/1.1/utils/Android.bp b/neuralnetworks/1.1/utils/Android.bp new file mode 100644 index 0000000000..85a32c5834 --- /dev/null +++ b/neuralnetworks/1.1/utils/Android.bp @@ -0,0 +1,35 @@ +// +// 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. +// + +cc_library_static { + name: "neuralnetworks_utils_hal_1_1", + defaults: ["neuralnetworks_utils_defaults"], + srcs: ["src/*"], + local_include_dirs: ["include/nnapi/hal/1.1/"], + export_include_dirs: ["include"], + static_libs: [ + "neuralnetworks_types", + "neuralnetworks_utils_hal_common", + "neuralnetworks_utils_hal_1_0", + ], + shared_libs: [ + "android.hardware.neuralnetworks@1.0", + "android.hardware.neuralnetworks@1.1", + ], + export_static_lib_headers: [ + "neuralnetworks_utils_hal_common", + ], +} diff --git a/neuralnetworks/1.1/utils/OWNERS b/neuralnetworks/1.1/utils/OWNERS new file mode 100644 index 0000000000..e4feee3496 --- /dev/null +++ b/neuralnetworks/1.1/utils/OWNERS @@ -0,0 +1,11 @@ +# Neuralnetworks team +butlermichael@google.com +dgross@google.com +galarragas@google.com +jeanluc@google.com +levp@google.com +miaowang@google.com +pszczepaniak@google.com +slavash@google.com +vddang@google.com +xusongw@google.com diff --git a/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Conversions.h b/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Conversions.h new file mode 100644 index 0000000000..d0c5397faf --- /dev/null +++ b/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Conversions.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_1_CONVERSIONS_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_1_CONVERSIONS_H + +#include +#include +#include +#include + +namespace android::nn { + +Result convert(const hal::V1_1::OperationType& operationType); +Result convert(const hal::V1_1::Capabilities& capabilities); +Result convert(const hal::V1_1::Operation& operation); +Result convert(const hal::V1_1::Model& model); +Result convert(const hal::V1_1::ExecutionPreference& executionPreference); + +} // namespace android::nn + +namespace android::hardware::neuralnetworks::V1_1::utils { + +nn::Result convert(const nn::OperationType& operationType); +nn::Result convert(const nn::Capabilities& capabilities); +nn::Result convert(const nn::Operation& operation); +nn::Result convert(const nn::Model& model); +nn::Result convert(const nn::ExecutionPreference& executionPreference); + +} // namespace android::hardware::neuralnetworks::V1_1::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_1_CONVERSIONS_H diff --git a/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Utils.h b/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Utils.h new file mode 100644 index 0000000000..6f9aa602d8 --- /dev/null +++ b/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Utils.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_1_UTILS_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_1_UTILS_H + +#include "nnapi/hal/1.1/Conversions.h" + +#include +#include +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::V1_1::utils { + +constexpr auto kDefaultExecutionPreference = ExecutionPreference::FAST_SINGLE_ANSWER; +constexpr auto kVersion = nn::Version::ANDROID_P; + +template +nn::Result validate(const Type& halObject) { + const auto canonical = NN_TRY(nn::convert(halObject)); + const auto version = NN_TRY(nn::validate(canonical)); + if (version > utils::kVersion) { + return NN_ERROR() << ""; + } + return {}; +} + +template +bool valid(const Type& halObject) { + const auto result = utils::validate(halObject); + if (!result.has_value()) { + LOG(ERROR) << result.error(); + } + return result.has_value(); +} + +template +decltype(nn::convert(std::declval())) validatedConvertToCanonical(const Type& halObject) { + auto canonical = NN_TRY(nn::convert(halObject)); + const auto version = NN_TRY(nn::validate(canonical)); + if (version > utils::kVersion) { + return NN_ERROR() << ""; + } + return canonical; +} + +} // namespace android::hardware::neuralnetworks::V1_1::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_1_UTILS_H diff --git a/neuralnetworks/1.1/utils/src/Assertions.cpp b/neuralnetworks/1.1/utils/src/Assertions.cpp new file mode 100644 index 0000000000..ba4a388e1c --- /dev/null +++ b/neuralnetworks/1.1/utils/src/Assertions.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +namespace { + +#define COMPARE_ENUMS_TYPES(type) \ + static_assert(std::is_same_v< \ + std::underlying_type_t<::android::hardware::neuralnetworks::V1_1::type>, \ + std::underlying_type_t<::android::nn::type>>, \ + "::android::hardware::neuralnetworks::V1_1::" #type \ + " does not have the same underlying type as ::android::nn::" #type) + +COMPARE_ENUMS_TYPES(OperationType); +COMPARE_ENUMS_TYPES(ExecutionPreference); + +#undef COMPARE_ENUMS_TYPES + +#define COMPARE_ENUMS_FULL(symbol, type) \ + static_assert( \ + static_cast>( \ + ::android::hardware::neuralnetworks::V1_1::type::symbol) == \ + static_cast>( \ + ::android::nn::type::symbol), \ + "::android::hardware::neuralnetworks::V1_1::" #type "::" #symbol \ + " does not match ::android::nn::" #type "::" #symbol) + +#define COMPARE_ENUMS(symbol) COMPARE_ENUMS_FULL(symbol, OperationType) + +COMPARE_ENUMS(ADD); +COMPARE_ENUMS(AVERAGE_POOL_2D); +COMPARE_ENUMS(CONCATENATION); +COMPARE_ENUMS(CONV_2D); +COMPARE_ENUMS(DEPTHWISE_CONV_2D); +COMPARE_ENUMS(DEPTH_TO_SPACE); +COMPARE_ENUMS(DEQUANTIZE); +COMPARE_ENUMS(EMBEDDING_LOOKUP); +COMPARE_ENUMS(FLOOR); +COMPARE_ENUMS(FULLY_CONNECTED); +COMPARE_ENUMS(HASHTABLE_LOOKUP); +COMPARE_ENUMS(L2_NORMALIZATION); +COMPARE_ENUMS(L2_POOL_2D); +COMPARE_ENUMS(LOCAL_RESPONSE_NORMALIZATION); +COMPARE_ENUMS(LOGISTIC); +COMPARE_ENUMS(LSH_PROJECTION); +COMPARE_ENUMS(LSTM); +COMPARE_ENUMS(MAX_POOL_2D); +COMPARE_ENUMS(MUL); +COMPARE_ENUMS(RELU); +COMPARE_ENUMS(RELU1); +COMPARE_ENUMS(RELU6); +COMPARE_ENUMS(RESHAPE); +COMPARE_ENUMS(RESIZE_BILINEAR); +COMPARE_ENUMS(RNN); +COMPARE_ENUMS(SOFTMAX); +COMPARE_ENUMS(SPACE_TO_DEPTH); +COMPARE_ENUMS(SVDF); +COMPARE_ENUMS(TANH); +COMPARE_ENUMS(BATCH_TO_SPACE_ND); +COMPARE_ENUMS(DIV); +COMPARE_ENUMS(MEAN); +COMPARE_ENUMS(PAD); +COMPARE_ENUMS(SPACE_TO_BATCH_ND); +COMPARE_ENUMS(SQUEEZE); +COMPARE_ENUMS(STRIDED_SLICE); +COMPARE_ENUMS(SUB); +COMPARE_ENUMS(TRANSPOSE); +COMPARE_ENUMS(OEM_OPERATION); + +#undef COMPARE_ENUMS + +#define COMPARE_ENUMS(symbol) COMPARE_ENUMS_FULL(symbol, ExecutionPreference) + +COMPARE_ENUMS(LOW_POWER); +COMPARE_ENUMS(FAST_SINGLE_ANSWER); +COMPARE_ENUMS(SUSTAINED_SPEED); + +#undef COMPARE_ENUMS + +#undef COMPARE_ENUMS_FULL + +} // anonymous namespace diff --git a/neuralnetworks/1.1/utils/src/Conversions.cpp b/neuralnetworks/1.1/utils/src/Conversions.cpp new file mode 100644 index 0000000000..7fee16b5f2 --- /dev/null +++ b/neuralnetworks/1.1/utils/src/Conversions.cpp @@ -0,0 +1,209 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Conversions.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace android::nn { +namespace { + +using hardware::hidl_vec; + +template +using convertOutput = std::decay_t()).value())>; + +template +Result>> convert(const hidl_vec& arguments) { + std::vector> canonical; + canonical.reserve(arguments.size()); + for (const auto& argument : arguments) { + canonical.push_back(NN_TRY(nn::convert(argument))); + } + return canonical; +} + +} // anonymous namespace + +Result convert(const hal::V1_1::OperationType& operationType) { + return static_cast(operationType); +} + +Result convert(const hal::V1_1::Capabilities& capabilities) { + const auto quantized8Performance = NN_TRY(convert(capabilities.quantized8Performance)); + const auto float32Performance = NN_TRY(convert(capabilities.float32Performance)); + const auto relaxedFloat32toFloat16Performance = + NN_TRY(convert(capabilities.relaxedFloat32toFloat16Performance)); + + auto table = hal::utils::makeQuantized8PerformanceConsistentWithP(float32Performance, + quantized8Performance); + + return Capabilities{ + .relaxedFloat32toFloat16PerformanceScalar = relaxedFloat32toFloat16Performance, + .relaxedFloat32toFloat16PerformanceTensor = relaxedFloat32toFloat16Performance, + .operandPerformance = std::move(table), + }; +} + +Result convert(const hal::V1_1::Operation& operation) { + return Operation{ + .type = NN_TRY(convert(operation.type)), + .inputs = operation.inputs, + .outputs = operation.outputs, + }; +} + +Result convert(const hal::V1_1::Model& model) { + auto operations = NN_TRY(convert(model.operations)); + + // Verify number of consumers. + const auto numberOfConsumers = + hal::utils::countNumberOfConsumers(model.operands.size(), operations); + CHECK(model.operands.size() == numberOfConsumers.size()); + for (size_t i = 0; i < model.operands.size(); ++i) { + if (model.operands[i].numberOfConsumers != numberOfConsumers[i]) { + return NN_ERROR() << "Invalid numberOfConsumers for operand " << i << ", expected " + << numberOfConsumers[i] << " but found " + << model.operands[i].numberOfConsumers; + } + } + + auto main = Model::Subgraph{ + .operands = NN_TRY(convert(model.operands)), + .operations = std::move(operations), + .inputIndexes = model.inputIndexes, + .outputIndexes = model.outputIndexes, + }; + + return Model{ + .main = std::move(main), + .operandValues = NN_TRY(convert(model.operandValues)), + .pools = NN_TRY(convert(model.pools)), + .relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16, + }; +} + +Result convert(const hal::V1_1::ExecutionPreference& executionPreference) { + return static_cast(executionPreference); +} + +} // namespace android::nn + +namespace android::hardware::neuralnetworks::V1_1::utils { +namespace { + +using utils::convert; + +nn::Result convert( + const nn::Capabilities::PerformanceInfo& performanceInfo) { + return V1_0::utils::convert(performanceInfo); +} + +nn::Result convert(const nn::Operand& operand) { + return V1_0::utils::convert(operand); +} + +nn::Result> convert(const nn::Model::OperandValues& operandValues) { + return V1_0::utils::convert(operandValues); +} + +nn::Result convert(const nn::Memory& memory) { + return V1_0::utils::convert(memory); +} + +template +using convertOutput = std::decay_t()).value())>; + +template +nn::Result>> convert(const std::vector& arguments) { + hidl_vec> halObject(arguments.size()); + for (size_t i = 0; i < arguments.size(); ++i) { + halObject[i] = NN_TRY(convert(arguments[i])); + } + return halObject; +} + +} // anonymous namespace + +nn::Result convert(const nn::OperationType& operationType) { + return static_cast(operationType); +} + +nn::Result convert(const nn::Capabilities& capabilities) { + return Capabilities{ + .float32Performance = NN_TRY(convert( + capabilities.operandPerformance.lookup(nn::OperandType::TENSOR_FLOAT32))), + .quantized8Performance = NN_TRY(convert( + capabilities.operandPerformance.lookup(nn::OperandType::TENSOR_QUANT8_ASYMM))), + .relaxedFloat32toFloat16Performance = + NN_TRY(convert(capabilities.relaxedFloat32toFloat16PerformanceTensor)), + }; +} + +nn::Result convert(const nn::Operation& operation) { + return Operation{ + .type = NN_TRY(convert(operation.type)), + .inputs = operation.inputs, + .outputs = operation.outputs, + }; +} + +nn::Result convert(const nn::Model& model) { + if (!hal::utils::hasNoPointerData(model)) { + return NN_ERROR() << "Mdoel cannot be converted because it contains pointer-based memory"; + } + + auto operands = NN_TRY(convert(model.main.operands)); + + // Update number of consumers. + const auto numberOfConsumers = + hal::utils::countNumberOfConsumers(operands.size(), model.main.operations); + CHECK(operands.size() == numberOfConsumers.size()); + for (size_t i = 0; i < operands.size(); ++i) { + operands[i].numberOfConsumers = numberOfConsumers[i]; + } + + return Model{ + .operands = std::move(operands), + .operations = NN_TRY(convert(model.main.operations)), + .inputIndexes = model.main.inputIndexes, + .outputIndexes = model.main.outputIndexes, + .operandValues = NN_TRY(convert(model.operandValues)), + .pools = NN_TRY(convert(model.pools)), + .relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16, + }; +} + +nn::Result convert(const nn::ExecutionPreference& executionPreference) { + return static_cast(executionPreference); +} + +} // namespace android::hardware::neuralnetworks::V1_1::utils diff --git a/neuralnetworks/1.2/utils/Android.bp b/neuralnetworks/1.2/utils/Android.bp new file mode 100644 index 0000000000..a1dd3d0b0d --- /dev/null +++ b/neuralnetworks/1.2/utils/Android.bp @@ -0,0 +1,37 @@ +// +// Copyright (C) 2020 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +cc_library_static { + name: "neuralnetworks_utils_hal_1_2", + defaults: ["neuralnetworks_utils_defaults"], + srcs: ["src/*"], + local_include_dirs: ["include/nnapi/hal/1.2/"], + export_include_dirs: ["include"], + static_libs: [ + "neuralnetworks_types", + "neuralnetworks_utils_hal_common", + "neuralnetworks_utils_hal_1_0", + "neuralnetworks_utils_hal_1_1", + ], + shared_libs: [ + "android.hardware.neuralnetworks@1.0", + "android.hardware.neuralnetworks@1.1", + "android.hardware.neuralnetworks@1.2", + ], + export_static_lib_headers: [ + "neuralnetworks_utils_hal_common", + ], +} diff --git a/neuralnetworks/1.2/utils/OWNERS b/neuralnetworks/1.2/utils/OWNERS new file mode 100644 index 0000000000..e4feee3496 --- /dev/null +++ b/neuralnetworks/1.2/utils/OWNERS @@ -0,0 +1,11 @@ +# Neuralnetworks team +butlermichael@google.com +dgross@google.com +galarragas@google.com +jeanluc@google.com +levp@google.com +miaowang@google.com +pszczepaniak@google.com +slavash@google.com +vddang@google.com +xusongw@google.com diff --git a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Conversions.h b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Conversions.h new file mode 100644 index 0000000000..81bf7928f6 --- /dev/null +++ b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Conversions.h @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_2_CONVERSIONS_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_2_CONVERSIONS_H + +#include +#include +#include +#include + +namespace android::nn { + +Result convert(const hal::V1_2::OperandType& operandType); +Result convert(const hal::V1_2::OperationType& operationType); +Result convert(const hal::V1_2::DeviceType& deviceType); +Result convert(const hal::V1_2::Capabilities& capabilities); +Result convert( + const hal::V1_2::Capabilities::OperandPerformance& operandPerformance); +Result convert(const hal::V1_2::Operation& operation); +Result convert( + const hal::V1_2::SymmPerChannelQuantParams& symmPerChannelQuantParams); +Result convert(const hal::V1_2::Operand& operand); +Result convert(const hal::V1_2::Operand::ExtraParams& extraParams); +Result convert(const hal::V1_2::Model& model); +Result convert( + const hal::V1_2::Model::ExtensionNameAndPrefix& extensionNameAndPrefix); +Result convert(const hal::V1_2::OutputShape& outputShape); +Result convert(const hal::V1_2::MeasureTiming& measureTiming); +Result convert(const hal::V1_2::Timing& timing); +Result convert(const hal::V1_2::Extension& extension); +Result convert( + const hal::V1_2::Extension::OperandTypeInformation& operandTypeInformation); +Result convert(const hardware::hidl_handle& handle); + +Result> convert(const hardware::hidl_vec& extensions); +Result> convert(const hardware::hidl_vec& handles); +Result> convert( + const hardware::hidl_vec& outputShapes); + +} // namespace android::nn + +namespace android::hardware::neuralnetworks::V1_2::utils { + +nn::Result convert(const nn::OperandType& operandType); +nn::Result convert(const nn::OperationType& operationType); +nn::Result convert(const nn::DeviceType& deviceType); +nn::Result convert(const nn::Capabilities& capabilities); +nn::Result convert( + const nn::Capabilities::OperandPerformance& operandPerformance); +nn::Result convert(const nn::Operation& operation); +nn::Result convert( + const nn::Operand::SymmPerChannelQuantParams& symmPerChannelQuantParams); +nn::Result convert(const nn::Operand& operand); +nn::Result convert(const nn::Operand::ExtraParams& extraParams); +nn::Result convert(const nn::Model& model); +nn::Result convert( + const nn::Model::ExtensionNameAndPrefix& extensionNameAndPrefix); +nn::Result convert(const nn::OutputShape& outputShape); +nn::Result convert(const nn::MeasureTiming& measureTiming); +nn::Result convert(const nn::Timing& timing); +nn::Result convert(const nn::Extension& extension); +nn::Result convert( + const nn::Extension::OperandTypeInformation& operandTypeInformation); +nn::Result convert(const nn::NativeHandle& handle); + +nn::Result> convert(const std::vector& extensions); +nn::Result> convert(const std::vector& handles); +nn::Result> convert(const std::vector& outputShapes); + +} // namespace android::hardware::neuralnetworks::V1_2::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_2_CONVERSIONS_H diff --git a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Utils.h b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Utils.h new file mode 100644 index 0000000000..b1c2f1a81a --- /dev/null +++ b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Utils.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_2_UTILS_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_2_UTILS_H + +#include "nnapi/hal/1.2/Conversions.h" + +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace android::hardware::neuralnetworks::V1_2::utils { + +constexpr auto kDefaultMesaureTiming = MeasureTiming::NO; +constexpr auto kNoTiming = Timing{.timeOnDevice = std::numeric_limits::max(), + .timeInDriver = std::numeric_limits::max()}; +constexpr auto kVersion = nn::Version::ANDROID_Q; + +template +nn::Result validate(const Type& halObject) { + const auto canonical = NN_TRY(nn::convert(halObject)); + const auto version = NN_TRY(nn::validate(canonical)); + if (version > utils::kVersion) { + return NN_ERROR() << ""; + } + return {}; +} + +template +bool valid(const Type& halObject) { + const auto result = utils::validate(halObject); + if (!result.has_value()) { + LOG(ERROR) << result.error(); + } + return result.has_value(); +} + +template +decltype(nn::convert(std::declval())) validatedConvertToCanonical(const Type& halObject) { + auto canonical = NN_TRY(nn::convert(halObject)); + const auto version = NN_TRY(nn::validate(canonical)); + if (version > utils::kVersion) { + return NN_ERROR() << ""; + } + return canonical; +} + +} // namespace android::hardware::neuralnetworks::V1_2::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_2_UTILS_H diff --git a/neuralnetworks/1.2/utils/src/Assertions.cpp b/neuralnetworks/1.2/utils/src/Assertions.cpp new file mode 100644 index 0000000000..9d9716acdf --- /dev/null +++ b/neuralnetworks/1.2/utils/src/Assertions.cpp @@ -0,0 +1,188 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +namespace { + +#define COMPARE_ENUMS_TYPES(type) \ + static_assert(std::is_same_v< \ + std::underlying_type_t<::android::hardware::neuralnetworks::V1_2::type>, \ + std::underlying_type_t<::android::nn::type>>, \ + "::android::hardware::neuralnetworks::V1_2::" #type \ + " does not have the same underlying type as ::android::nn::" #type) + +COMPARE_ENUMS_TYPES(OperandType); +COMPARE_ENUMS_TYPES(OperationType); +COMPARE_ENUMS_TYPES(DeviceType); +COMPARE_ENUMS_TYPES(MeasureTiming); + +#undef COMPARE_ENUMS_TYPES + +#define COMPARE_ENUMS_FULL(symbol, type) \ + static_assert( \ + static_cast>( \ + ::android::hardware::neuralnetworks::V1_2::type::symbol) == \ + static_cast>( \ + ::android::nn::type::symbol), \ + "::android::hardware::neuralnetworks::V1_2::" #type "::" #symbol \ + " does not match ::android::nn::" #type "::" #symbol) + +#define COMPARE_ENUMS(symbol) COMPARE_ENUMS_FULL(symbol, OperandType) + +COMPARE_ENUMS(FLOAT32); +COMPARE_ENUMS(INT32); +COMPARE_ENUMS(UINT32); +COMPARE_ENUMS(TENSOR_FLOAT32); +COMPARE_ENUMS(TENSOR_INT32); +COMPARE_ENUMS(TENSOR_QUANT8_ASYMM); +COMPARE_ENUMS(BOOL); +COMPARE_ENUMS(TENSOR_QUANT16_SYMM); +COMPARE_ENUMS(TENSOR_FLOAT16); +COMPARE_ENUMS(TENSOR_BOOL8); +COMPARE_ENUMS(FLOAT16); +COMPARE_ENUMS(TENSOR_QUANT8_SYMM_PER_CHANNEL); +COMPARE_ENUMS(TENSOR_QUANT16_ASYMM); +COMPARE_ENUMS(TENSOR_QUANT8_SYMM); +COMPARE_ENUMS(OEM); +COMPARE_ENUMS(TENSOR_OEM_BYTE); + +#undef COMPARE_ENUMS + +#define COMPARE_ENUMS(symbol) COMPARE_ENUMS_FULL(symbol, OperationType) + +COMPARE_ENUMS(ADD); +COMPARE_ENUMS(AVERAGE_POOL_2D); +COMPARE_ENUMS(CONCATENATION); +COMPARE_ENUMS(CONV_2D); +COMPARE_ENUMS(DEPTHWISE_CONV_2D); +COMPARE_ENUMS(DEPTH_TO_SPACE); +COMPARE_ENUMS(DEQUANTIZE); +COMPARE_ENUMS(EMBEDDING_LOOKUP); +COMPARE_ENUMS(FLOOR); +COMPARE_ENUMS(FULLY_CONNECTED); +COMPARE_ENUMS(HASHTABLE_LOOKUP); +COMPARE_ENUMS(L2_NORMALIZATION); +COMPARE_ENUMS(L2_POOL_2D); +COMPARE_ENUMS(LOCAL_RESPONSE_NORMALIZATION); +COMPARE_ENUMS(LOGISTIC); +COMPARE_ENUMS(LSH_PROJECTION); +COMPARE_ENUMS(LSTM); +COMPARE_ENUMS(MAX_POOL_2D); +COMPARE_ENUMS(MUL); +COMPARE_ENUMS(RELU); +COMPARE_ENUMS(RELU1); +COMPARE_ENUMS(RELU6); +COMPARE_ENUMS(RESHAPE); +COMPARE_ENUMS(RESIZE_BILINEAR); +COMPARE_ENUMS(RNN); +COMPARE_ENUMS(SOFTMAX); +COMPARE_ENUMS(SPACE_TO_DEPTH); +COMPARE_ENUMS(SVDF); +COMPARE_ENUMS(TANH); +COMPARE_ENUMS(BATCH_TO_SPACE_ND); +COMPARE_ENUMS(DIV); +COMPARE_ENUMS(MEAN); +COMPARE_ENUMS(PAD); +COMPARE_ENUMS(SPACE_TO_BATCH_ND); +COMPARE_ENUMS(SQUEEZE); +COMPARE_ENUMS(STRIDED_SLICE); +COMPARE_ENUMS(SUB); +COMPARE_ENUMS(TRANSPOSE); +COMPARE_ENUMS(ABS); +COMPARE_ENUMS(ARGMAX); +COMPARE_ENUMS(ARGMIN); +COMPARE_ENUMS(AXIS_ALIGNED_BBOX_TRANSFORM); +COMPARE_ENUMS(BIDIRECTIONAL_SEQUENCE_LSTM); +COMPARE_ENUMS(BIDIRECTIONAL_SEQUENCE_RNN); +COMPARE_ENUMS(BOX_WITH_NMS_LIMIT); +COMPARE_ENUMS(CAST); +COMPARE_ENUMS(CHANNEL_SHUFFLE); +COMPARE_ENUMS(DETECTION_POSTPROCESSING); +COMPARE_ENUMS(EQUAL); +COMPARE_ENUMS(EXP); +COMPARE_ENUMS(EXPAND_DIMS); +COMPARE_ENUMS(GATHER); +COMPARE_ENUMS(GENERATE_PROPOSALS); +COMPARE_ENUMS(GREATER); +COMPARE_ENUMS(GREATER_EQUAL); +COMPARE_ENUMS(GROUPED_CONV_2D); +COMPARE_ENUMS(HEATMAP_MAX_KEYPOINT); +COMPARE_ENUMS(INSTANCE_NORMALIZATION); +COMPARE_ENUMS(LESS); +COMPARE_ENUMS(LESS_EQUAL); +COMPARE_ENUMS(LOG); +COMPARE_ENUMS(LOGICAL_AND); +COMPARE_ENUMS(LOGICAL_NOT); +COMPARE_ENUMS(LOGICAL_OR); +COMPARE_ENUMS(LOG_SOFTMAX); +COMPARE_ENUMS(MAXIMUM); +COMPARE_ENUMS(MINIMUM); +COMPARE_ENUMS(NEG); +COMPARE_ENUMS(NOT_EQUAL); +COMPARE_ENUMS(PAD_V2); +COMPARE_ENUMS(POW); +COMPARE_ENUMS(PRELU); +COMPARE_ENUMS(QUANTIZE); +COMPARE_ENUMS(QUANTIZED_16BIT_LSTM); +COMPARE_ENUMS(RANDOM_MULTINOMIAL); +COMPARE_ENUMS(REDUCE_ALL); +COMPARE_ENUMS(REDUCE_ANY); +COMPARE_ENUMS(REDUCE_MAX); +COMPARE_ENUMS(REDUCE_MIN); +COMPARE_ENUMS(REDUCE_PROD); +COMPARE_ENUMS(REDUCE_SUM); +COMPARE_ENUMS(ROI_ALIGN); +COMPARE_ENUMS(ROI_POOLING); +COMPARE_ENUMS(RSQRT); +COMPARE_ENUMS(SELECT); +COMPARE_ENUMS(SIN); +COMPARE_ENUMS(SLICE); +COMPARE_ENUMS(SPLIT); +COMPARE_ENUMS(SQRT); +COMPARE_ENUMS(TILE); +COMPARE_ENUMS(TOPK_V2); +COMPARE_ENUMS(TRANSPOSE_CONV_2D); +COMPARE_ENUMS(UNIDIRECTIONAL_SEQUENCE_LSTM); +COMPARE_ENUMS(UNIDIRECTIONAL_SEQUENCE_RNN); +COMPARE_ENUMS(RESIZE_NEAREST_NEIGHBOR); +COMPARE_ENUMS(OEM_OPERATION); + +#undef COMPARE_ENUMS + +#define COMPARE_ENUMS(symbol) COMPARE_ENUMS_FULL(symbol, DeviceType) + +COMPARE_ENUMS(OTHER); +COMPARE_ENUMS(CPU); +COMPARE_ENUMS(GPU); +COMPARE_ENUMS(ACCELERATOR); + +#undef COMPARE_ENUMS + +#define COMPARE_ENUMS(symbol) COMPARE_ENUMS_FULL(symbol, MeasureTiming) + +COMPARE_ENUMS(NO); +COMPARE_ENUMS(YES); + +#undef COMPARE_ENUMS + +#undef COMPARE_ENUMS_FULL + +} // anonymous namespace diff --git a/neuralnetworks/1.2/utils/src/Conversions.cpp b/neuralnetworks/1.2/utils/src/Conversions.cpp new file mode 100644 index 0000000000..fed314b7c1 --- /dev/null +++ b/neuralnetworks/1.2/utils/src/Conversions.cpp @@ -0,0 +1,502 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Conversions.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace { + +template +constexpr std::underlying_type_t underlyingType(Type value) { + return static_cast>(value); +} + +} // namespace + +namespace android::nn { +namespace { + +constexpr bool validOperandType(OperandType operandType) { + switch (operandType) { + case OperandType::FLOAT32: + case OperandType::INT32: + case OperandType::UINT32: + case OperandType::TENSOR_FLOAT32: + case OperandType::TENSOR_INT32: + case OperandType::TENSOR_QUANT8_ASYMM: + case OperandType::BOOL: + case OperandType::TENSOR_QUANT16_SYMM: + case OperandType::TENSOR_FLOAT16: + case OperandType::TENSOR_BOOL8: + case OperandType::FLOAT16: + case OperandType::TENSOR_QUANT8_SYMM_PER_CHANNEL: + case OperandType::TENSOR_QUANT16_ASYMM: + case OperandType::TENSOR_QUANT8_SYMM: + case OperandType::OEM: + case OperandType::TENSOR_OEM_BYTE: + return true; + default: + break; + } + return isExtension(operandType); +} + +using hardware::hidl_handle; +using hardware::hidl_vec; + +template +using ConvertOutput = std::decay_t()).value())>; + +template +Result>> convertVec(const hidl_vec& arguments) { + std::vector> canonical; + canonical.reserve(arguments.size()); + for (const auto& argument : arguments) { + canonical.push_back(NN_TRY(nn::convert(argument))); + } + return canonical; +} + +template +Result>> convert(const hidl_vec& arguments) { + return convertVec(arguments); +} + +} // anonymous namespace + +Result convert(const hal::V1_2::OperandType& operandType) { + return static_cast(operandType); +} + +Result convert(const hal::V1_2::OperationType& operationType) { + return static_cast(operationType); +} + +Result convert(const hal::V1_2::DeviceType& deviceType) { + return static_cast(deviceType); +} + +Result convert(const hal::V1_2::Capabilities& capabilities) { + const bool validOperandTypes = std::all_of( + capabilities.operandPerformance.begin(), capabilities.operandPerformance.end(), + [](const hal::V1_2::Capabilities::OperandPerformance& operandPerformance) { + const auto maybeType = convert(operandPerformance.type); + return !maybeType.has_value() ? false : validOperandType(maybeType.value()); + }); + if (!validOperandTypes) { + return NN_ERROR() + << "Invalid OperandType when converting OperandPerformance in Capabilities"; + } + + const auto relaxedFloat32toFloat16PerformanceScalar = + NN_TRY(convert(capabilities.relaxedFloat32toFloat16PerformanceScalar)); + const auto relaxedFloat32toFloat16PerformanceTensor = + NN_TRY(convert(capabilities.relaxedFloat32toFloat16PerformanceTensor)); + auto operandPerformance = NN_TRY(convert(capabilities.operandPerformance)); + + auto table = + NN_TRY(Capabilities::OperandPerformanceTable::create(std::move(operandPerformance))); + + return Capabilities{ + .relaxedFloat32toFloat16PerformanceScalar = relaxedFloat32toFloat16PerformanceScalar, + .relaxedFloat32toFloat16PerformanceTensor = relaxedFloat32toFloat16PerformanceTensor, + .operandPerformance = std::move(table), + }; +} + +Result convert( + const hal::V1_2::Capabilities::OperandPerformance& operandPerformance) { + return Capabilities::OperandPerformance{ + .type = NN_TRY(convert(operandPerformance.type)), + .info = NN_TRY(convert(operandPerformance.info)), + }; +} + +Result convert(const hal::V1_2::Operation& operation) { + return Operation{ + .type = NN_TRY(convert(operation.type)), + .inputs = operation.inputs, + .outputs = operation.outputs, + }; +} + +Result convert( + const hal::V1_2::SymmPerChannelQuantParams& symmPerChannelQuantParams) { + return Operand::SymmPerChannelQuantParams{ + .scales = symmPerChannelQuantParams.scales, + .channelDim = symmPerChannelQuantParams.channelDim, + }; +} + +Result convert(const hal::V1_2::Operand& operand) { + return Operand{ + .type = NN_TRY(convert(operand.type)), + .dimensions = operand.dimensions, + .scale = operand.scale, + .zeroPoint = operand.zeroPoint, + .lifetime = NN_TRY(convert(operand.lifetime)), + .location = NN_TRY(convert(operand.location)), + .extraParams = NN_TRY(convert(operand.extraParams)), + }; +} + +Result convert(const hal::V1_2::Operand::ExtraParams& extraParams) { + using Discriminator = hal::V1_2::Operand::ExtraParams::hidl_discriminator; + switch (extraParams.getDiscriminator()) { + case Discriminator::none: + return Operand::NoParams{}; + case Discriminator::channelQuant: + return convert(extraParams.channelQuant()); + case Discriminator::extension: + return extraParams.extension(); + } + return NN_ERROR() << "Unrecognized Operand::ExtraParams discriminator: " + << underlyingType(extraParams.getDiscriminator()); +} + +Result convert(const hal::V1_2::Model& model) { + auto operations = NN_TRY(convert(model.operations)); + + // Verify number of consumers. + const auto numberOfConsumers = + hal::utils::countNumberOfConsumers(model.operands.size(), operations); + CHECK(model.operands.size() == numberOfConsumers.size()); + for (size_t i = 0; i < model.operands.size(); ++i) { + if (model.operands[i].numberOfConsumers != numberOfConsumers[i]) { + return NN_ERROR() << "Invalid numberOfConsumers for operand " << i << ", expected " + << numberOfConsumers[i] << " but found " + << model.operands[i].numberOfConsumers; + } + } + + auto main = Model::Subgraph{ + .operands = NN_TRY(convert(model.operands)), + .operations = std::move(operations), + .inputIndexes = model.inputIndexes, + .outputIndexes = model.outputIndexes, + }; + + return Model{ + .main = std::move(main), + .operandValues = NN_TRY(convert(model.operandValues)), + .pools = NN_TRY(convert(model.pools)), + .relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16, + .extensionNameToPrefix = NN_TRY(convert(model.extensionNameToPrefix)), + }; +} + +Result convert( + const hal::V1_2::Model::ExtensionNameAndPrefix& extensionNameAndPrefix) { + return Model::ExtensionNameAndPrefix{ + .name = extensionNameAndPrefix.name, + .prefix = extensionNameAndPrefix.prefix, + }; +} + +Result convert(const hal::V1_2::OutputShape& outputShape) { + return OutputShape{ + .dimensions = outputShape.dimensions, + .isSufficient = outputShape.isSufficient, + }; +} + +Result convert(const hal::V1_2::MeasureTiming& measureTiming) { + return static_cast(measureTiming); +} + +Result convert(const hal::V1_2::Timing& timing) { + return Timing{.timeOnDevice = timing.timeOnDevice, .timeInDriver = timing.timeInDriver}; +} + +Result convert(const hal::V1_2::Extension& extension) { + return Extension{ + .name = extension.name, + .operandTypes = NN_TRY(convert(extension.operandTypes)), + }; +} + +Result convert( + const hal::V1_2::Extension::OperandTypeInformation& operandTypeInformation) { + return Extension::OperandTypeInformation{ + .type = operandTypeInformation.type, + .isTensor = operandTypeInformation.isTensor, + .byteSize = operandTypeInformation.byteSize, + }; +} + +Result convert(const hidl_handle& handle) { + auto* cloned = native_handle_clone(handle.getNativeHandle()); + return ::android::NativeHandle::create(cloned, /*ownsHandle=*/true); +} + +Result> convert(const hidl_vec& extensions) { + return convertVec(extensions); +} + +Result> convert(const hidl_vec& handles) { + return convertVec(handles); +} + +Result> convert(const hidl_vec& outputShapes) { + return convertVec(outputShapes); +} + +} // namespace android::nn + +namespace android::hardware::neuralnetworks::V1_2::utils { +namespace { + +using utils::convert; + +nn::Result convert(const nn::Operand::LifeTime& lifetime) { + return V1_0::utils::convert(lifetime); +} + +nn::Result convert( + const nn::Capabilities::PerformanceInfo& performanceInfo) { + return V1_0::utils::convert(performanceInfo); +} + +nn::Result convert(const nn::DataLocation& location) { + return V1_0::utils::convert(location); +} + +nn::Result> convert(const nn::Model::OperandValues& operandValues) { + return V1_0::utils::convert(operandValues); +} + +nn::Result convert(const nn::Memory& memory) { + return V1_0::utils::convert(memory); +} + +template +using ConvertOutput = std::decay_t()).value())>; + +template +nn::Result>> convertVec(const std::vector& arguments) { + hidl_vec> halObject(arguments.size()); + for (size_t i = 0; i < arguments.size(); ++i) { + halObject[i] = NN_TRY(convert(arguments[i])); + } + return halObject; +} + +template +nn::Result>> convert(const std::vector& arguments) { + return convertVec(arguments); +} + +nn::Result makeExtraParams(nn::Operand::NoParams /*noParams*/) { + return Operand::ExtraParams{}; +} + +nn::Result makeExtraParams( + const nn::Operand::SymmPerChannelQuantParams& channelQuant) { + Operand::ExtraParams ret; + ret.channelQuant(NN_TRY(convert(channelQuant))); + return ret; +} + +nn::Result makeExtraParams(const nn::Operand::ExtensionParams& extension) { + Operand::ExtraParams ret; + ret.extension(extension); + return ret; +} + +} // anonymous namespace + +nn::Result convert(const nn::OperandType& operandType) { + return static_cast(operandType); +} + +nn::Result convert(const nn::OperationType& operationType) { + return static_cast(operationType); +} + +nn::Result convert(const nn::DeviceType& deviceType) { + switch (deviceType) { + case nn::DeviceType::UNKNOWN: + return NN_ERROR() << "Invalid DeviceType UNKNOWN"; + case nn::DeviceType::OTHER: + case nn::DeviceType::CPU: + case nn::DeviceType::GPU: + case nn::DeviceType::ACCELERATOR: + return static_cast(deviceType); + } + return NN_ERROR() << "Invalid DeviceType " << underlyingType(deviceType); +} + +nn::Result convert(const nn::Capabilities& capabilities) { + std::vector operandPerformance; + operandPerformance.reserve(capabilities.operandPerformance.asVector().size()); + std::copy_if(capabilities.operandPerformance.asVector().begin(), + capabilities.operandPerformance.asVector().end(), + std::back_inserter(operandPerformance), + [](const nn::Capabilities::OperandPerformance& operandPerformance) { + return nn::validOperandType(operandPerformance.type); + }); + + return Capabilities{ + .relaxedFloat32toFloat16PerformanceScalar = + NN_TRY(convert(capabilities.relaxedFloat32toFloat16PerformanceScalar)), + .relaxedFloat32toFloat16PerformanceTensor = + NN_TRY(convert(capabilities.relaxedFloat32toFloat16PerformanceTensor)), + .operandPerformance = NN_TRY(convert(operandPerformance)), + }; +} + +nn::Result convert( + const nn::Capabilities::OperandPerformance& operandPerformance) { + return Capabilities::OperandPerformance{ + .type = NN_TRY(convert(operandPerformance.type)), + .info = NN_TRY(convert(operandPerformance.info)), + }; +} + +nn::Result convert(const nn::Operation& operation) { + return Operation{ + .type = NN_TRY(convert(operation.type)), + .inputs = operation.inputs, + .outputs = operation.outputs, + }; +} + +nn::Result convert( + const nn::Operand::SymmPerChannelQuantParams& symmPerChannelQuantParams) { + return SymmPerChannelQuantParams{ + .scales = symmPerChannelQuantParams.scales, + .channelDim = symmPerChannelQuantParams.channelDim, + }; +} + +nn::Result convert(const nn::Operand& operand) { + return Operand{ + .type = NN_TRY(convert(operand.type)), + .dimensions = operand.dimensions, + .numberOfConsumers = 0, + .scale = operand.scale, + .zeroPoint = operand.zeroPoint, + .lifetime = NN_TRY(convert(operand.lifetime)), + .location = NN_TRY(convert(operand.location)), + .extraParams = NN_TRY(convert(operand.extraParams)), + }; +} + +nn::Result convert(const nn::Operand::ExtraParams& extraParams) { + return std::visit([](const auto& x) { return makeExtraParams(x); }, extraParams); +} + +nn::Result convert(const nn::Model& model) { + if (!hal::utils::hasNoPointerData(model)) { + return NN_ERROR() << "Model cannot be converted because it contains pointer-based memory"; + } + + auto operands = NN_TRY(convert(model.main.operands)); + + // Update number of consumers. + const auto numberOfConsumers = + hal::utils::countNumberOfConsumers(operands.size(), model.main.operations); + CHECK(operands.size() == numberOfConsumers.size()); + for (size_t i = 0; i < operands.size(); ++i) { + operands[i].numberOfConsumers = numberOfConsumers[i]; + } + + return Model{ + .operands = std::move(operands), + .operations = NN_TRY(convert(model.main.operations)), + .inputIndexes = model.main.inputIndexes, + .outputIndexes = model.main.outputIndexes, + .operandValues = NN_TRY(convert(model.operandValues)), + .pools = NN_TRY(convert(model.pools)), + .relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16, + .extensionNameToPrefix = NN_TRY(convert(model.extensionNameToPrefix)), + }; +} + +nn::Result convert( + const nn::Model::ExtensionNameAndPrefix& extensionNameAndPrefix) { + return Model::ExtensionNameAndPrefix{ + .name = extensionNameAndPrefix.name, + .prefix = extensionNameAndPrefix.prefix, + }; +} + +nn::Result convert(const nn::OutputShape& outputShape) { + return OutputShape{.dimensions = outputShape.dimensions, + .isSufficient = outputShape.isSufficient}; +} + +nn::Result convert(const nn::MeasureTiming& measureTiming) { + return static_cast(measureTiming); +} + +nn::Result convert(const nn::Timing& timing) { + return Timing{.timeOnDevice = timing.timeOnDevice, .timeInDriver = timing.timeInDriver}; +} + +nn::Result convert(const nn::Extension& extension) { + return Extension{ + .name = extension.name, + .operandTypes = NN_TRY(convert(extension.operandTypes)), + }; +} + +nn::Result convert( + const nn::Extension::OperandTypeInformation& operandTypeInformation) { + return Extension::OperandTypeInformation{ + .type = operandTypeInformation.type, + .isTensor = operandTypeInformation.isTensor, + .byteSize = operandTypeInformation.byteSize, + }; +} + +nn::Result convert(const nn::NativeHandle& handle) { + const auto hidlHandle = hidl_handle(handle->handle()); + // Copy memory to force the native_handle_t to be copied. + auto copiedHandle = hidlHandle; + return copiedHandle; +} + +nn::Result> convert(const std::vector& extensions) { + return convertVec(extensions); +} + +nn::Result> convert(const std::vector& handles) { + return convertVec(handles); +} + +nn::Result> convert(const std::vector& outputShapes) { + return convertVec(outputShapes); +} + +} // namespace android::hardware::neuralnetworks::V1_2::utils diff --git a/neuralnetworks/1.3/utils/Android.bp b/neuralnetworks/1.3/utils/Android.bp new file mode 100644 index 0000000000..279b250532 --- /dev/null +++ b/neuralnetworks/1.3/utils/Android.bp @@ -0,0 +1,39 @@ +// +// Copyright (C) 2020 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +cc_library_static { + name: "neuralnetworks_utils_hal_1_3", + defaults: ["neuralnetworks_utils_defaults"], + srcs: ["src/*"], + local_include_dirs: ["include/nnapi/hal/1.3/"], + export_include_dirs: ["include"], + static_libs: [ + "neuralnetworks_types", + "neuralnetworks_utils_hal_common", + "neuralnetworks_utils_hal_1_0", + "neuralnetworks_utils_hal_1_1", + "neuralnetworks_utils_hal_1_2", + ], + shared_libs: [ + "android.hardware.neuralnetworks@1.0", + "android.hardware.neuralnetworks@1.1", + "android.hardware.neuralnetworks@1.2", + "android.hardware.neuralnetworks@1.3", + ], + export_static_lib_headers: [ + "neuralnetworks_utils_hal_common", + ], +} diff --git a/neuralnetworks/1.3/utils/OWNERS b/neuralnetworks/1.3/utils/OWNERS new file mode 100644 index 0000000000..e4feee3496 --- /dev/null +++ b/neuralnetworks/1.3/utils/OWNERS @@ -0,0 +1,11 @@ +# Neuralnetworks team +butlermichael@google.com +dgross@google.com +galarragas@google.com +jeanluc@google.com +levp@google.com +miaowang@google.com +pszczepaniak@google.com +slavash@google.com +vddang@google.com +xusongw@google.com diff --git a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Conversions.h b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Conversions.h new file mode 100644 index 0000000000..43987a9727 --- /dev/null +++ b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Conversions.h @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_3_CONVERSIONS_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_3_CONVERSIONS_H + +#include +#include +#include +#include +#include + +namespace android::nn { + +Result convert(const hal::V1_3::OperandType& operandType); +Result convert(const hal::V1_3::OperationType& operationType); +Result convert(const hal::V1_3::Priority& priority); +Result convert(const hal::V1_3::Capabilities& capabilities); +Result convert( + const hal::V1_3::Capabilities::OperandPerformance& operandPerformance); +Result convert(const hal::V1_3::Operation& operation); +Result convert(const hal::V1_3::OperandLifeTime& operandLifeTime); +Result convert(const hal::V1_3::Operand& operand); +Result convert(const hal::V1_3::Model& model); +Result convert(const hal::V1_3::Subgraph& subgraph); +Result convert(const hal::V1_3::BufferDesc& bufferDesc); +Result convert(const hal::V1_3::BufferRole& bufferRole); +Result convert(const hal::V1_3::Request& request); +Result convert(const hal::V1_3::Request::MemoryPool& memoryPool); +Result convert(const hal::V1_3::OptionalTimePoint& optionalTimePoint); +Result convert( + const hal::V1_3::OptionalTimeoutDuration& optionalTimeoutDuration); +Result convert(const hal::V1_3::ErrorStatus& errorStatus); + +Result> convert( + const hardware::hidl_vec& bufferRoles); + +} // namespace android::nn + +namespace android::hardware::neuralnetworks::V1_3::utils { + +nn::Result convert(const nn::OperandType& operandType); +nn::Result convert(const nn::OperationType& operationType); +nn::Result convert(const nn::Priority& priority); +nn::Result convert(const nn::Capabilities& capabilities); +nn::Result convert( + const nn::Capabilities::OperandPerformance& operandPerformance); +nn::Result convert(const nn::Operation& operation); +nn::Result convert(const nn::Operand::LifeTime& operandLifeTime); +nn::Result convert(const nn::Operand& operand); +nn::Result convert(const nn::Model& model); +nn::Result convert(const nn::Model::Subgraph& subgraph); +nn::Result convert(const nn::BufferDesc& bufferDesc); +nn::Result convert(const nn::BufferRole& bufferRole); +nn::Result convert(const nn::Request& request); +nn::Result convert(const nn::Request::MemoryPool& memoryPool); +nn::Result convert(const nn::OptionalTimePoint& optionalTimePoint); +nn::Result convert( + const nn::OptionalTimeoutDuration& optionalTimeoutDuration); +nn::Result convert(const nn::ErrorStatus& errorStatus); + +nn::Result> convert(const std::vector& bufferRoles); + +} // namespace android::hardware::neuralnetworks::V1_3::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_3_CONVERSIONS_H diff --git a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Utils.h b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Utils.h new file mode 100644 index 0000000000..f8c975d5d7 --- /dev/null +++ b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Utils.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_3_UTILS_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_3_UTILS_H + +#include "nnapi/hal/1.3/Conversions.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::V1_3::utils { + +constexpr auto kDefaultPriority = Priority::MEDIUM; +constexpr auto kVersion = nn::Version::ANDROID_R; + +template +nn::Result validate(const Type& halObject) { + const auto canonical = NN_TRY(nn::convert(halObject)); + const auto version = NN_TRY(nn::validate(canonical)); + if (version > utils::kVersion) { + return NN_ERROR() << ""; + } + return {}; +} + +template +bool valid(const Type& halObject) { + const auto result = utils::validate(halObject); + if (!result.has_value()) { + LOG(ERROR) << result.error(); + } + return result.has_value(); +} + +template +decltype(nn::convert(std::declval())) validatedConvertToCanonical(const Type& halObject) { + auto canonical = NN_TRY(nn::convert(halObject)); + const auto version = NN_TRY(nn::validate(canonical)); + if (version > utils::kVersion) { + return NN_ERROR() << ""; + } + return canonical; +} + +} // namespace android::hardware::neuralnetworks::V1_3::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_3_UTILS_H diff --git a/neuralnetworks/1.3/utils/src/Assertions.cpp b/neuralnetworks/1.3/utils/src/Assertions.cpp new file mode 100644 index 0000000000..96d647a7aa --- /dev/null +++ b/neuralnetworks/1.3/utils/src/Assertions.cpp @@ -0,0 +1,218 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +namespace { + +#define COMPARE_ENUMS_TYPES(lhsType, rhsType) \ + static_assert( \ + std::is_same_v< \ + std::underlying_type_t<::android::hardware::neuralnetworks::V1_3::lhsType>, \ + std::underlying_type_t<::android::nn::rhsType>>, \ + "::android::hardware::neuralnetworks::V1_3::" #lhsType \ + " does not have the same underlying type as ::android::nn::" #rhsType) + +COMPARE_ENUMS_TYPES(OperandType, OperandType); +COMPARE_ENUMS_TYPES(OperationType, OperationType); +COMPARE_ENUMS_TYPES(Priority, Priority); +COMPARE_ENUMS_TYPES(OperandLifeTime, Operand::LifeTime); +COMPARE_ENUMS_TYPES(ErrorStatus, ErrorStatus); + +#undef COMPARE_ENUMS_TYPES + +#define COMPARE_ENUMS_FULL(symbol, lhsType, rhsType) \ + static_assert( \ + static_cast< \ + std::underlying_type_t<::android::hardware::neuralnetworks::V1_3::lhsType>>( \ + ::android::hardware::neuralnetworks::V1_3::lhsType::symbol) == \ + static_cast>( \ + ::android::nn::rhsType::symbol), \ + "::android::hardware::neuralnetworks::V1_3::" #lhsType "::" #symbol \ + " does not match ::android::nn::" #rhsType "::" #symbol) + +#define COMPARE_ENUMS(symbol) COMPARE_ENUMS_FULL(symbol, OperandType, OperandType) + +COMPARE_ENUMS(FLOAT32); +COMPARE_ENUMS(INT32); +COMPARE_ENUMS(UINT32); +COMPARE_ENUMS(TENSOR_FLOAT32); +COMPARE_ENUMS(TENSOR_INT32); +COMPARE_ENUMS(TENSOR_QUANT8_ASYMM); +COMPARE_ENUMS(BOOL); +COMPARE_ENUMS(TENSOR_QUANT16_SYMM); +COMPARE_ENUMS(TENSOR_FLOAT16); +COMPARE_ENUMS(TENSOR_BOOL8); +COMPARE_ENUMS(FLOAT16); +COMPARE_ENUMS(TENSOR_QUANT8_SYMM_PER_CHANNEL); +COMPARE_ENUMS(TENSOR_QUANT16_ASYMM); +COMPARE_ENUMS(TENSOR_QUANT8_SYMM); +COMPARE_ENUMS(TENSOR_QUANT8_ASYMM_SIGNED); +COMPARE_ENUMS(SUBGRAPH); +COMPARE_ENUMS(OEM); +COMPARE_ENUMS(TENSOR_OEM_BYTE); + +#undef COMPARE_ENUMS + +#define COMPARE_ENUMS(symbol) COMPARE_ENUMS_FULL(symbol, OperationType, OperationType) + +COMPARE_ENUMS(ADD); +COMPARE_ENUMS(AVERAGE_POOL_2D); +COMPARE_ENUMS(CONCATENATION); +COMPARE_ENUMS(CONV_2D); +COMPARE_ENUMS(DEPTHWISE_CONV_2D); +COMPARE_ENUMS(DEPTH_TO_SPACE); +COMPARE_ENUMS(DEQUANTIZE); +COMPARE_ENUMS(EMBEDDING_LOOKUP); +COMPARE_ENUMS(FLOOR); +COMPARE_ENUMS(FULLY_CONNECTED); +COMPARE_ENUMS(HASHTABLE_LOOKUP); +COMPARE_ENUMS(L2_NORMALIZATION); +COMPARE_ENUMS(L2_POOL_2D); +COMPARE_ENUMS(LOCAL_RESPONSE_NORMALIZATION); +COMPARE_ENUMS(LOGISTIC); +COMPARE_ENUMS(LSH_PROJECTION); +COMPARE_ENUMS(LSTM); +COMPARE_ENUMS(MAX_POOL_2D); +COMPARE_ENUMS(MUL); +COMPARE_ENUMS(RELU); +COMPARE_ENUMS(RELU1); +COMPARE_ENUMS(RELU6); +COMPARE_ENUMS(RESHAPE); +COMPARE_ENUMS(RESIZE_BILINEAR); +COMPARE_ENUMS(RNN); +COMPARE_ENUMS(SOFTMAX); +COMPARE_ENUMS(SPACE_TO_DEPTH); +COMPARE_ENUMS(SVDF); +COMPARE_ENUMS(TANH); +COMPARE_ENUMS(BATCH_TO_SPACE_ND); +COMPARE_ENUMS(DIV); +COMPARE_ENUMS(MEAN); +COMPARE_ENUMS(PAD); +COMPARE_ENUMS(SPACE_TO_BATCH_ND); +COMPARE_ENUMS(SQUEEZE); +COMPARE_ENUMS(STRIDED_SLICE); +COMPARE_ENUMS(SUB); +COMPARE_ENUMS(TRANSPOSE); +COMPARE_ENUMS(ABS); +COMPARE_ENUMS(ARGMAX); +COMPARE_ENUMS(ARGMIN); +COMPARE_ENUMS(AXIS_ALIGNED_BBOX_TRANSFORM); +COMPARE_ENUMS(BIDIRECTIONAL_SEQUENCE_LSTM); +COMPARE_ENUMS(BIDIRECTIONAL_SEQUENCE_RNN); +COMPARE_ENUMS(BOX_WITH_NMS_LIMIT); +COMPARE_ENUMS(CAST); +COMPARE_ENUMS(CHANNEL_SHUFFLE); +COMPARE_ENUMS(DETECTION_POSTPROCESSING); +COMPARE_ENUMS(EQUAL); +COMPARE_ENUMS(EXP); +COMPARE_ENUMS(EXPAND_DIMS); +COMPARE_ENUMS(GATHER); +COMPARE_ENUMS(GENERATE_PROPOSALS); +COMPARE_ENUMS(GREATER); +COMPARE_ENUMS(GREATER_EQUAL); +COMPARE_ENUMS(GROUPED_CONV_2D); +COMPARE_ENUMS(HEATMAP_MAX_KEYPOINT); +COMPARE_ENUMS(INSTANCE_NORMALIZATION); +COMPARE_ENUMS(LESS); +COMPARE_ENUMS(LESS_EQUAL); +COMPARE_ENUMS(LOG); +COMPARE_ENUMS(LOGICAL_AND); +COMPARE_ENUMS(LOGICAL_NOT); +COMPARE_ENUMS(LOGICAL_OR); +COMPARE_ENUMS(LOG_SOFTMAX); +COMPARE_ENUMS(MAXIMUM); +COMPARE_ENUMS(MINIMUM); +COMPARE_ENUMS(NEG); +COMPARE_ENUMS(NOT_EQUAL); +COMPARE_ENUMS(PAD_V2); +COMPARE_ENUMS(POW); +COMPARE_ENUMS(PRELU); +COMPARE_ENUMS(QUANTIZE); +COMPARE_ENUMS(QUANTIZED_16BIT_LSTM); +COMPARE_ENUMS(RANDOM_MULTINOMIAL); +COMPARE_ENUMS(REDUCE_ALL); +COMPARE_ENUMS(REDUCE_ANY); +COMPARE_ENUMS(REDUCE_MAX); +COMPARE_ENUMS(REDUCE_MIN); +COMPARE_ENUMS(REDUCE_PROD); +COMPARE_ENUMS(REDUCE_SUM); +COMPARE_ENUMS(ROI_ALIGN); +COMPARE_ENUMS(ROI_POOLING); +COMPARE_ENUMS(RSQRT); +COMPARE_ENUMS(SELECT); +COMPARE_ENUMS(SIN); +COMPARE_ENUMS(SLICE); +COMPARE_ENUMS(SPLIT); +COMPARE_ENUMS(SQRT); +COMPARE_ENUMS(TILE); +COMPARE_ENUMS(TOPK_V2); +COMPARE_ENUMS(TRANSPOSE_CONV_2D); +COMPARE_ENUMS(UNIDIRECTIONAL_SEQUENCE_LSTM); +COMPARE_ENUMS(UNIDIRECTIONAL_SEQUENCE_RNN); +COMPARE_ENUMS(RESIZE_NEAREST_NEIGHBOR); +COMPARE_ENUMS(QUANTIZED_LSTM); +COMPARE_ENUMS(IF); +COMPARE_ENUMS(WHILE); +COMPARE_ENUMS(ELU); +COMPARE_ENUMS(HARD_SWISH); +COMPARE_ENUMS(FILL); +COMPARE_ENUMS(RANK); +COMPARE_ENUMS(OEM_OPERATION); + +#undef COMPARE_ENUMS + +#define COMPARE_ENUMS(symbol) COMPARE_ENUMS_FULL(symbol, Priority, Priority) + +COMPARE_ENUMS(LOW); +COMPARE_ENUMS(MEDIUM); +COMPARE_ENUMS(HIGH); + +#undef COMPARE_ENUMS + +#define COMPARE_ENUMS(symbol) COMPARE_ENUMS_FULL(symbol, OperandLifeTime, Operand::LifeTime) + +COMPARE_ENUMS(TEMPORARY_VARIABLE); +COMPARE_ENUMS(SUBGRAPH_INPUT); +COMPARE_ENUMS(SUBGRAPH_OUTPUT); +COMPARE_ENUMS(CONSTANT_COPY); +COMPARE_ENUMS(CONSTANT_REFERENCE); +COMPARE_ENUMS(NO_VALUE); +COMPARE_ENUMS(SUBGRAPH); + +#undef COMPARE_ENUMS + +#define COMPARE_ENUMS(symbol) COMPARE_ENUMS_FULL(symbol, ErrorStatus, ErrorStatus) + +COMPARE_ENUMS(NONE); +COMPARE_ENUMS(DEVICE_UNAVAILABLE); +COMPARE_ENUMS(GENERAL_FAILURE); +COMPARE_ENUMS(OUTPUT_INSUFFICIENT_SIZE); +COMPARE_ENUMS(INVALID_ARGUMENT); +COMPARE_ENUMS(MISSED_DEADLINE_TRANSIENT); +COMPARE_ENUMS(MISSED_DEADLINE_PERSISTENT); +COMPARE_ENUMS(RESOURCE_EXHAUSTED_TRANSIENT); +COMPARE_ENUMS(RESOURCE_EXHAUSTED_PERSISTENT); + +#undef COMPARE_ENUMS + +#undef COMPARE_ENUMS_FULL + +} // anonymous namespace diff --git a/neuralnetworks/1.3/utils/src/Conversions.cpp b/neuralnetworks/1.3/utils/src/Conversions.cpp new file mode 100644 index 0000000000..4c54e3b12e --- /dev/null +++ b/neuralnetworks/1.3/utils/src/Conversions.cpp @@ -0,0 +1,552 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Conversions.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace { + +template +constexpr std::underlying_type_t underlyingType(Type value) { + return static_cast>(value); +} + +} // namespace + +namespace android::nn { +namespace { + +constexpr auto validOperandType(nn::OperandType operandType) { + switch (operandType) { + case nn::OperandType::FLOAT32: + case nn::OperandType::INT32: + case nn::OperandType::UINT32: + case nn::OperandType::TENSOR_FLOAT32: + case nn::OperandType::TENSOR_INT32: + case nn::OperandType::TENSOR_QUANT8_ASYMM: + case nn::OperandType::BOOL: + case nn::OperandType::TENSOR_QUANT16_SYMM: + case nn::OperandType::TENSOR_FLOAT16: + case nn::OperandType::TENSOR_BOOL8: + case nn::OperandType::FLOAT16: + case nn::OperandType::TENSOR_QUANT8_SYMM_PER_CHANNEL: + case nn::OperandType::TENSOR_QUANT16_ASYMM: + case nn::OperandType::TENSOR_QUANT8_SYMM: + case nn::OperandType::TENSOR_QUANT8_ASYMM_SIGNED: + case nn::OperandType::SUBGRAPH: + case nn::OperandType::OEM: + case nn::OperandType::TENSOR_OEM_BYTE: + return true; + } + return nn::isExtension(operandType); +} + +using hardware::hidl_vec; + +template +using ConvertOutput = std::decay_t()).value())>; + +template +Result>> convertVec(const hidl_vec& arguments) { + std::vector> canonical; + canonical.reserve(arguments.size()); + for (const auto& argument : arguments) { + canonical.push_back(NN_TRY(nn::convert(argument))); + } + return canonical; +} + +template +Result>> convert(const hidl_vec& arguments) { + return convertVec(arguments); +} + +} // anonymous namespace + +Result convert(const hal::V1_3::OperandType& operandType) { + return static_cast(operandType); +} + +Result convert(const hal::V1_3::OperationType& operationType) { + return static_cast(operationType); +} + +Result convert(const hal::V1_3::Priority& priority) { + return static_cast(priority); +} + +Result convert(const hal::V1_3::Capabilities& capabilities) { + const bool validOperandTypes = std::all_of( + capabilities.operandPerformance.begin(), capabilities.operandPerformance.end(), + [](const hal::V1_3::Capabilities::OperandPerformance& operandPerformance) { + const auto maybeType = convert(operandPerformance.type); + return !maybeType.has_value() ? false : validOperandType(maybeType.value()); + }); + if (!validOperandTypes) { + return NN_ERROR() + << "Invalid OperandType when converting OperandPerformance in Capabilities"; + } + + auto operandPerformance = NN_TRY(convert(capabilities.operandPerformance)); + auto table = + NN_TRY(Capabilities::OperandPerformanceTable::create(std::move(operandPerformance))); + + return Capabilities{ + .relaxedFloat32toFloat16PerformanceScalar = + NN_TRY(convert(capabilities.relaxedFloat32toFloat16PerformanceScalar)), + .relaxedFloat32toFloat16PerformanceTensor = + NN_TRY(convert(capabilities.relaxedFloat32toFloat16PerformanceTensor)), + .operandPerformance = std::move(table), + .ifPerformance = NN_TRY(convert(capabilities.ifPerformance)), + .whilePerformance = NN_TRY(convert(capabilities.whilePerformance)), + }; +} + +Result convert( + const hal::V1_3::Capabilities::OperandPerformance& operandPerformance) { + return Capabilities::OperandPerformance{ + .type = NN_TRY(convert(operandPerformance.type)), + .info = NN_TRY(convert(operandPerformance.info)), + }; +} + +Result convert(const hal::V1_3::Operation& operation) { + return Operation{ + .type = NN_TRY(convert(operation.type)), + .inputs = operation.inputs, + .outputs = operation.outputs, + }; +} + +Result convert(const hal::V1_3::OperandLifeTime& operandLifeTime) { + return static_cast(operandLifeTime); +} + +Result convert(const hal::V1_3::Operand& operand) { + return Operand{ + .type = NN_TRY(convert(operand.type)), + .dimensions = operand.dimensions, + .scale = operand.scale, + .zeroPoint = operand.zeroPoint, + .lifetime = NN_TRY(convert(operand.lifetime)), + .location = NN_TRY(convert(operand.location)), + .extraParams = NN_TRY(convert(operand.extraParams)), + }; +} + +Result convert(const hal::V1_3::Model& model) { + return Model{ + .main = NN_TRY(convert(model.main)), + .referenced = NN_TRY(convert(model.referenced)), + .operandValues = NN_TRY(convert(model.operandValues)), + .pools = NN_TRY(convert(model.pools)), + .relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16, + .extensionNameToPrefix = NN_TRY(convert(model.extensionNameToPrefix)), + }; +} + +Result convert(const hal::V1_3::Subgraph& subgraph) { + auto operations = NN_TRY(convert(subgraph.operations)); + + // Verify number of consumers. + const auto numberOfConsumers = + hal::utils::countNumberOfConsumers(subgraph.operands.size(), operations); + CHECK(subgraph.operands.size() == numberOfConsumers.size()); + for (size_t i = 0; i < subgraph.operands.size(); ++i) { + if (subgraph.operands[i].numberOfConsumers != numberOfConsumers[i]) { + return NN_ERROR() << "Invalid numberOfConsumers for operand " << i << ", expected " + << numberOfConsumers[i] << " but found " + << subgraph.operands[i].numberOfConsumers; + } + } + + return Model::Subgraph{ + .operands = NN_TRY(convert(subgraph.operands)), + .operations = std::move(operations), + .inputIndexes = subgraph.inputIndexes, + .outputIndexes = subgraph.outputIndexes, + }; +} + +Result convert(const hal::V1_3::BufferDesc& bufferDesc) { + return BufferDesc{.dimensions = bufferDesc.dimensions}; +} + +Result convert(const hal::V1_3::BufferRole& bufferRole) { + return BufferRole{ + .modelIndex = bufferRole.modelIndex, + .ioIndex = bufferRole.ioIndex, + .frequency = bufferRole.frequency, + }; +} + +Result convert(const hal::V1_3::Request& request) { + return Request{ + .inputs = NN_TRY(convert(request.inputs)), + .outputs = NN_TRY(convert(request.outputs)), + .pools = NN_TRY(convert(request.pools)), + }; +} + +Result convert(const hal::V1_3::Request::MemoryPool& memoryPool) { + using Discriminator = hal::V1_3::Request::MemoryPool::hidl_discriminator; + switch (memoryPool.getDiscriminator()) { + case Discriminator::hidlMemory: + return createSharedMemoryFromHidlMemory(memoryPool.hidlMemory()); + case Discriminator::token: + return static_cast(memoryPool.token()); + } + return NN_ERROR() << "Invalid Request::MemoryPool discriminator " + << underlyingType(memoryPool.getDiscriminator()); +} + +Result convert(const hal::V1_3::OptionalTimePoint& optionalTimePoint) { + constexpr auto kTimePointMaxCount = TimePoint::max().time_since_epoch().count(); + const auto makeTimePoint = [](uint64_t count) -> Result { + if (count > kTimePointMaxCount) { + return NN_ERROR() + << "Unable to convert OptionalTimePoint because the count exceeds the max"; + } + const auto nanoseconds = std::chrono::nanoseconds{count}; + return TimePoint{nanoseconds}; + }; + + using Discriminator = hal::V1_3::OptionalTimePoint::hidl_discriminator; + switch (optionalTimePoint.getDiscriminator()) { + case Discriminator::none: + return std::nullopt; + case Discriminator::nanosecondsSinceEpoch: + return makeTimePoint(optionalTimePoint.nanosecondsSinceEpoch()); + } + return NN_ERROR() << "Invalid OptionalTimePoint discriminator " + << underlyingType(optionalTimePoint.getDiscriminator()); +} + +Result convert( + const hal::V1_3::OptionalTimeoutDuration& optionalTimeoutDuration) { + constexpr auto kTimeoutDurationMaxCount = TimeoutDuration::max().count(); + const auto makeTimeoutDuration = [](uint64_t count) -> Result { + if (count > kTimeoutDurationMaxCount) { + return NN_ERROR() + << "Unable to convert OptionalTimeoutDuration because the count exceeds the max"; + } + return TimeoutDuration{count}; + }; + + using Discriminator = hal::V1_3::OptionalTimeoutDuration::hidl_discriminator; + switch (optionalTimeoutDuration.getDiscriminator()) { + case Discriminator::none: + return std::nullopt; + case Discriminator::nanoseconds: + return makeTimeoutDuration(optionalTimeoutDuration.nanoseconds()); + } + return NN_ERROR() << "Invalid OptionalTimeoutDuration discriminator " + << underlyingType(optionalTimeoutDuration.getDiscriminator()); +} + +Result convert(const hal::V1_3::ErrorStatus& status) { + switch (status) { + case hal::V1_3::ErrorStatus::NONE: + case hal::V1_3::ErrorStatus::DEVICE_UNAVAILABLE: + case hal::V1_3::ErrorStatus::GENERAL_FAILURE: + case hal::V1_3::ErrorStatus::OUTPUT_INSUFFICIENT_SIZE: + case hal::V1_3::ErrorStatus::INVALID_ARGUMENT: + case hal::V1_3::ErrorStatus::MISSED_DEADLINE_TRANSIENT: + case hal::V1_3::ErrorStatus::MISSED_DEADLINE_PERSISTENT: + case hal::V1_3::ErrorStatus::RESOURCE_EXHAUSTED_TRANSIENT: + case hal::V1_3::ErrorStatus::RESOURCE_EXHAUSTED_PERSISTENT: + return static_cast(status); + } + return NN_ERROR() << "Invalid ErrorStatus " << underlyingType(status); +} + +Result> convert( + const hardware::hidl_vec& bufferRoles) { + return convertVec(bufferRoles); +} + +} // namespace android::nn + +namespace android::hardware::neuralnetworks::V1_3::utils { +namespace { + +using utils::convert; + +nn::Result convert( + const nn::Capabilities::PerformanceInfo& performanceInfo) { + return V1_0::utils::convert(performanceInfo); +} + +nn::Result convert(const nn::DataLocation& dataLocation) { + return V1_0::utils::convert(dataLocation); +} + +nn::Result> convert(const nn::Model::OperandValues& operandValues) { + return V1_0::utils::convert(operandValues); +} + +nn::Result convert(const nn::Memory& memory) { + return V1_0::utils::convert(memory); +} + +nn::Result convert(const nn::Request::Argument& argument) { + return V1_0::utils::convert(argument); +} + +nn::Result convert(const nn::Operand::ExtraParams& extraParams) { + return V1_2::utils::convert(extraParams); +} + +nn::Result convert( + const nn::Model::ExtensionNameAndPrefix& extensionNameAndPrefix) { + return V1_2::utils::convert(extensionNameAndPrefix); +} + +template +using ConvertOutput = std::decay_t()).value())>; + +template +nn::Result>> convertVec(const std::vector& arguments) { + hidl_vec> halObject(arguments.size()); + for (size_t i = 0; i < arguments.size(); ++i) { + halObject[i] = NN_TRY(convert(arguments[i])); + } + return halObject; +} + +template +nn::Result>> convert(const std::vector& arguments) { + return convertVec(arguments); +} + +nn::Result makeMemoryPool(const nn::Memory& memory) { + Request::MemoryPool ret; + ret.hidlMemory(NN_TRY(convert(memory))); + return ret; +} + +nn::Result makeMemoryPool(const nn::Request::MemoryDomainToken& token) { + Request::MemoryPool ret; + ret.token(underlyingType(token)); + return ret; +} + +nn::Result makeMemoryPool( + const std::shared_ptr& /*buffer*/) { + return NN_ERROR() << "Unable to make memory pool from IBuffer"; +} + +} // anonymous namespace + +nn::Result convert(const nn::OperandType& operandType) { + return static_cast(operandType); +} + +nn::Result convert(const nn::OperationType& operationType) { + return static_cast(operationType); +} + +nn::Result convert(const nn::Priority& priority) { + return static_cast(priority); +} + +nn::Result convert(const nn::Capabilities& capabilities) { + std::vector operandPerformance; + operandPerformance.reserve(capabilities.operandPerformance.asVector().size()); + std::copy_if(capabilities.operandPerformance.asVector().begin(), + capabilities.operandPerformance.asVector().end(), + std::back_inserter(operandPerformance), + [](const nn::Capabilities::OperandPerformance& operandPerformance) { + return nn::validOperandType(operandPerformance.type); + }); + + return Capabilities{ + .relaxedFloat32toFloat16PerformanceScalar = + NN_TRY(convert(capabilities.relaxedFloat32toFloat16PerformanceScalar)), + .relaxedFloat32toFloat16PerformanceTensor = + NN_TRY(convert(capabilities.relaxedFloat32toFloat16PerformanceTensor)), + .operandPerformance = NN_TRY(convert(operandPerformance)), + .ifPerformance = NN_TRY(convert(capabilities.ifPerformance)), + .whilePerformance = NN_TRY(convert(capabilities.whilePerformance)), + }; +} + +nn::Result convert( + const nn::Capabilities::OperandPerformance& operandPerformance) { + return Capabilities::OperandPerformance{ + .type = NN_TRY(convert(operandPerformance.type)), + .info = NN_TRY(convert(operandPerformance.info)), + }; +} + +nn::Result convert(const nn::Operation& operation) { + return Operation{ + .type = NN_TRY(convert(operation.type)), + .inputs = operation.inputs, + .outputs = operation.outputs, + }; +} + +nn::Result convert(const nn::Operand::LifeTime& operandLifeTime) { + if (operandLifeTime == nn::Operand::LifeTime::POINTER) { + return NN_ERROR() << "Model cannot be converted because it contains pointer-based memory"; + } + return static_cast(operandLifeTime); +} + +nn::Result convert(const nn::Operand& operand) { + return Operand{ + .type = NN_TRY(convert(operand.type)), + .dimensions = operand.dimensions, + .numberOfConsumers = 0, + .scale = operand.scale, + .zeroPoint = operand.zeroPoint, + .lifetime = NN_TRY(convert(operand.lifetime)), + .location = NN_TRY(convert(operand.location)), + .extraParams = NN_TRY(convert(operand.extraParams)), + }; +} + +nn::Result convert(const nn::Model& model) { + if (!hal::utils::hasNoPointerData(model)) { + return NN_ERROR() << "Model cannot be converted because it contains pointer-based memory"; + } + + return Model{ + .main = NN_TRY(convert(model.main)), + .referenced = NN_TRY(convert(model.referenced)), + .operandValues = NN_TRY(convert(model.operandValues)), + .pools = NN_TRY(convert(model.pools)), + .relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16, + .extensionNameToPrefix = NN_TRY(convert(model.extensionNameToPrefix)), + }; +} + +nn::Result convert(const nn::Model::Subgraph& subgraph) { + auto operands = NN_TRY(convert(subgraph.operands)); + + // Update number of consumers. + const auto numberOfConsumers = + hal::utils::countNumberOfConsumers(operands.size(), subgraph.operations); + CHECK(operands.size() == numberOfConsumers.size()); + for (size_t i = 0; i < operands.size(); ++i) { + operands[i].numberOfConsumers = numberOfConsumers[i]; + } + + return Subgraph{ + .operands = std::move(operands), + .operations = NN_TRY(convert(subgraph.operations)), + .inputIndexes = subgraph.inputIndexes, + .outputIndexes = subgraph.outputIndexes, + }; +} + +nn::Result convert(const nn::BufferDesc& bufferDesc) { + return BufferDesc{.dimensions = bufferDesc.dimensions}; +} + +nn::Result convert(const nn::BufferRole& bufferRole) { + return BufferRole{ + .modelIndex = bufferRole.modelIndex, + .ioIndex = bufferRole.ioIndex, + .frequency = bufferRole.frequency, + }; +} + +nn::Result convert(const nn::Request& request) { + if (!hal::utils::hasNoPointerData(request)) { + return NN_ERROR() << "Request cannot be converted because it contains pointer-based memory"; + } + + return Request{ + .inputs = NN_TRY(convert(request.inputs)), + .outputs = NN_TRY(convert(request.outputs)), + .pools = NN_TRY(convert(request.pools)), + }; +} + +nn::Result convert(const nn::Request::MemoryPool& memoryPool) { + return std::visit([](const auto& o) { return makeMemoryPool(o); }, memoryPool); +} + +nn::Result convert(const nn::OptionalTimePoint& optionalTimePoint) { + OptionalTimePoint ret; + if (optionalTimePoint.has_value()) { + const auto count = optionalTimePoint.value().time_since_epoch().count(); + if (count < 0) { + return NN_ERROR() << "Unable to convert OptionalTimePoint because time since epoch " + "count is negative"; + } + ret.nanosecondsSinceEpoch(count); + } + return ret; +} + +nn::Result convert( + const nn::OptionalTimeoutDuration& optionalTimeoutDuration) { + OptionalTimeoutDuration ret; + if (optionalTimeoutDuration.has_value()) { + const auto count = optionalTimeoutDuration.value().count(); + if (count < 0) { + return NN_ERROR() + << "Unable to convert OptionalTimeoutDuration because count is negative"; + } + ret.nanoseconds(count); + } + return ret; +} + +nn::Result convert(const nn::ErrorStatus& errorStatus) { + switch (errorStatus) { + case nn::ErrorStatus::NONE: + case nn::ErrorStatus::DEVICE_UNAVAILABLE: + case nn::ErrorStatus::GENERAL_FAILURE: + case nn::ErrorStatus::OUTPUT_INSUFFICIENT_SIZE: + case nn::ErrorStatus::INVALID_ARGUMENT: + case nn::ErrorStatus::MISSED_DEADLINE_TRANSIENT: + case nn::ErrorStatus::MISSED_DEADLINE_PERSISTENT: + case nn::ErrorStatus::RESOURCE_EXHAUSTED_TRANSIENT: + case nn::ErrorStatus::RESOURCE_EXHAUSTED_PERSISTENT: + return static_cast(errorStatus); + default: + return ErrorStatus::GENERAL_FAILURE; + } +} + +nn::Result> convert(const std::vector& bufferRoles) { + return convertVec(bufferRoles); +} + +} // namespace android::hardware::neuralnetworks::V1_3::utils diff --git a/neuralnetworks/utils/OWNERS b/neuralnetworks/utils/OWNERS new file mode 100644 index 0000000000..e4feee3496 --- /dev/null +++ b/neuralnetworks/utils/OWNERS @@ -0,0 +1,11 @@ +# Neuralnetworks team +butlermichael@google.com +dgross@google.com +galarragas@google.com +jeanluc@google.com +levp@google.com +miaowang@google.com +pszczepaniak@google.com +slavash@google.com +vddang@google.com +xusongw@google.com diff --git a/neuralnetworks/utils/common/Android.bp b/neuralnetworks/utils/common/Android.bp new file mode 100644 index 0000000000..b61dc970ed --- /dev/null +++ b/neuralnetworks/utils/common/Android.bp @@ -0,0 +1,29 @@ +// +// 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. +// + +cc_library_static { + name: "neuralnetworks_utils_hal_common", + defaults: ["neuralnetworks_utils_defaults"], + srcs: ["src/*"], + local_include_dirs: ["include/nnapi/hal"], + export_include_dirs: ["include"], + static_libs: [ + "neuralnetworks_types", + ], + shared_libs: [ + "libhidlbase", + ], +} diff --git a/neuralnetworks/utils/common/include/nnapi/hal/CommonUtils.h b/neuralnetworks/utils/common/include/nnapi/hal/CommonUtils.h new file mode 100644 index 0000000000..8c013682ce --- /dev/null +++ b/neuralnetworks/utils/common/include/nnapi/hal/CommonUtils.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_COMMON_UTILS_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_COMMON_UTILS_H + +#include +#include +#include + +// Shorthand +namespace android::hardware::neuralnetworks { +namespace hal = ::android::hardware::neuralnetworks; +} // namespace android::hardware::neuralnetworks + +// Shorthand +namespace android::nn { +namespace hal = ::android::hardware::neuralnetworks; +} + +namespace android::hardware::neuralnetworks::utils { + +nn::Capabilities::OperandPerformanceTable makeQuantized8PerformanceConsistentWithP( + const nn::Capabilities::PerformanceInfo& float32Performance, + const nn::Capabilities::PerformanceInfo& quantized8Performance); + +// Indicates if the object contains no pointer-based data that could be relocated to shared memory. +bool hasNoPointerData(const nn::Model& model); +bool hasNoPointerData(const nn::Request& request); + +// Relocate pointer-based data to shared memory. +nn::Result flushDataFromPointerToShared(const nn::Model& model); +nn::Result flushDataFromPointerToShared(const nn::Request& request); + +// Undoes `flushDataFromPointerToShared` on a Request object. More specifically, +// `unflushDataFromSharedToPointer` copies the output shared memory data from the transformed +// Request object back to the output pointer-based memory in the original Request object. +nn::Result unflushDataFromSharedToPointer(const nn::Request& request, + const nn::Request& requestInShared); + +std::vector countNumberOfConsumers(size_t numberOfOperands, + const std::vector& operations); + +} // namespace android::hardware::neuralnetworks::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_COMMON_UTILS_H diff --git a/neuralnetworks/utils/common/src/CommonUtils.cpp b/neuralnetworks/utils/common/src/CommonUtils.cpp new file mode 100644 index 0000000000..667189b2a0 --- /dev/null +++ b/neuralnetworks/utils/common/src/CommonUtils.cpp @@ -0,0 +1,224 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "CommonUtils.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::utils { +namespace { + +bool hasNoPointerData(const nn::Operand& operand); +bool hasNoPointerData(const nn::Model::Subgraph& subgraph); +bool hasNoPointerData(const nn::Request::Argument& argument); + +template +bool hasNoPointerData(const std::vector& objects) { + return std::all_of(objects.begin(), objects.end(), + [](const auto& object) { return hasNoPointerData(object); }); +} + +bool hasNoPointerData(const nn::DataLocation& location) { + return std::visit([](auto ptr) { return ptr == nullptr; }, location.pointer); +} + +bool hasNoPointerData(const nn::Operand& operand) { + return hasNoPointerData(operand.location); +} + +bool hasNoPointerData(const nn::Model::Subgraph& subgraph) { + return hasNoPointerData(subgraph.operands); +} + +bool hasNoPointerData(const nn::Request::Argument& argument) { + return hasNoPointerData(argument.location); +} + +void copyPointersToSharedMemory(nn::Operand* operand, nn::ConstantMemoryBuilder* memoryBuilder) { + CHECK(operand != nullptr); + CHECK(memoryBuilder != nullptr); + + if (operand->lifetime != nn::Operand::LifeTime::POINTER) { + return; + } + + const void* data = std::visit([](auto ptr) { return static_cast(ptr); }, + operand->location.pointer); + CHECK(data != nullptr); + operand->lifetime = nn::Operand::LifeTime::CONSTANT_REFERENCE; + operand->location = memoryBuilder->append(data, operand->location.length); +} + +void copyPointersToSharedMemory(nn::Model::Subgraph* subgraph, + nn::ConstantMemoryBuilder* memoryBuilder) { + CHECK(subgraph != nullptr); + std::for_each(subgraph->operands.begin(), subgraph->operands.end(), + [memoryBuilder](auto& operand) { + copyPointersToSharedMemory(&operand, memoryBuilder); + }); +} + +} // anonymous namespace + +nn::Capabilities::OperandPerformanceTable makeQuantized8PerformanceConsistentWithP( + const nn::Capabilities::PerformanceInfo& float32Performance, + const nn::Capabilities::PerformanceInfo& quantized8Performance) { + // In Android P, most data types are treated as having the same performance as + // TENSOR_QUANT8_ASYMM. This collection must be in sorted order. + std::vector operandPerformances = { + {.type = nn::OperandType::FLOAT32, .info = float32Performance}, + {.type = nn::OperandType::INT32, .info = quantized8Performance}, + {.type = nn::OperandType::UINT32, .info = quantized8Performance}, + {.type = nn::OperandType::TENSOR_FLOAT32, .info = float32Performance}, + {.type = nn::OperandType::TENSOR_INT32, .info = quantized8Performance}, + {.type = nn::OperandType::TENSOR_QUANT8_ASYMM, .info = quantized8Performance}, + {.type = nn::OperandType::OEM, .info = quantized8Performance}, + {.type = nn::OperandType::TENSOR_OEM_BYTE, .info = quantized8Performance}, + }; + return nn::Capabilities::OperandPerformanceTable::create(std::move(operandPerformances)) + .value(); +} + +bool hasNoPointerData(const nn::Model& model) { + return hasNoPointerData(model.main) && hasNoPointerData(model.referenced); +} + +bool hasNoPointerData(const nn::Request& request) { + return hasNoPointerData(request.inputs) && hasNoPointerData(request.outputs); +} + +nn::Result flushDataFromPointerToShared(const nn::Model& model) { + auto modelInShared = model; + + nn::ConstantMemoryBuilder memoryBuilder(modelInShared.pools.size()); + copyPointersToSharedMemory(&modelInShared.main, &memoryBuilder); + std::for_each(modelInShared.referenced.begin(), modelInShared.referenced.end(), + [&memoryBuilder](auto& subgraph) { + copyPointersToSharedMemory(&subgraph, &memoryBuilder); + }); + + if (!memoryBuilder.empty()) { + auto memory = NN_TRY(memoryBuilder.finish()); + modelInShared.pools.push_back(std::move(memory)); + } + + return modelInShared; +} + +nn::Result flushDataFromPointerToShared(const nn::Request& request) { + auto requestInShared = request; + + // Change input pointers to shared memory. + nn::ConstantMemoryBuilder inputBuilder(requestInShared.pools.size()); + for (auto& input : requestInShared.inputs) { + const auto& location = input.location; + if (input.lifetime != nn::Request::Argument::LifeTime::POINTER) { + continue; + } + + input.lifetime = nn::Request::Argument::LifeTime::POOL; + const void* data = std::visit([](auto ptr) { return static_cast(ptr); }, + location.pointer); + CHECK(data != nullptr); + input.location = inputBuilder.append(data, location.length); + } + + // Allocate input memory. + if (!inputBuilder.empty()) { + auto memory = NN_TRY(inputBuilder.finish()); + requestInShared.pools.push_back(std::move(memory)); + } + + // Change output pointers to shared memory. + nn::MutableMemoryBuilder outputBuilder(requestInShared.pools.size()); + for (auto& output : requestInShared.outputs) { + const auto& location = output.location; + if (output.lifetime != nn::Request::Argument::LifeTime::POINTER) { + continue; + } + + output.lifetime = nn::Request::Argument::LifeTime::POOL; + output.location = outputBuilder.append(location.length); + } + + // Allocate output memory. + if (!outputBuilder.empty()) { + auto memory = NN_TRY(outputBuilder.finish()); + requestInShared.pools.push_back(std::move(memory)); + } + + return requestInShared; +} + +nn::Result unflushDataFromSharedToPointer(const nn::Request& request, + const nn::Request& requestInShared) { + if (requestInShared.pools.empty() || + !std::holds_alternative(requestInShared.pools.back())) { + return {}; + } + + // Map the memory. + const auto& outputMemory = std::get(requestInShared.pools.back()); + const auto [pointer, size, context] = NN_TRY(map(outputMemory)); + const uint8_t* constantPointer = + std::visit([](const auto& o) { return static_cast(o); }, pointer); + + // Flush each output pointer. + CHECK_EQ(request.outputs.size(), requestInShared.outputs.size()); + for (size_t i = 0; i < request.outputs.size(); ++i) { + const auto& location = request.outputs[i].location; + const auto& locationInShared = requestInShared.outputs[i].location; + if (!std::holds_alternative(location.pointer)) { + continue; + } + + // Get output pointer and size. + void* data = std::get(location.pointer); + CHECK(data != nullptr); + const size_t length = location.length; + + // Get output pool location. + CHECK(requestInShared.outputs[i].lifetime == nn::Request::Argument::LifeTime::POOL); + const size_t index = locationInShared.poolIndex; + const size_t offset = locationInShared.offset; + const size_t outputPoolIndex = requestInShared.pools.size() - 1; + CHECK(locationInShared.length == length); + CHECK(index == outputPoolIndex); + + // Flush memory. + std::memcpy(data, constantPointer + offset, length); + } + + return {}; +} + +std::vector countNumberOfConsumers(size_t numberOfOperands, + const std::vector& operations) { + return nn::countNumberOfConsumers(numberOfOperands, operations); +} + +} // namespace android::hardware::neuralnetworks::utils -- GitLab From 43e42ff6ec685038921bc375bd660c245e4bc4e7 Mon Sep 17 00:00:00 2001 From: Ady Abraham Date: Fri, 25 Sep 2020 14:28:36 -0700 Subject: [PATCH 188/790] composer: hold a sp from the service itself IComposerClient assumes that IComposer will outlive its life cycle and holds a simple pointer to HwcHal. This change is taking the same approach of newer composer versions (2.2, 2.3, and 2.4) to make sure that IComposer would outlive IComposerClient. Test: coral booting with this change Fixes: 155769496 Change-Id: I3962ede51ce823368c62c4e4e5fb30f7a5680bdf --- graphics/composer/2.1/default/Android.bp | 28 ++++--------------- graphics/composer/2.1/default/passthrough.cpp | 25 ----------------- graphics/composer/2.1/default/service.cpp | 19 +++++++++++-- 3 files changed, 22 insertions(+), 50 deletions(-) delete mode 100644 graphics/composer/2.1/default/passthrough.cpp diff --git a/graphics/composer/2.1/default/Android.bp b/graphics/composer/2.1/default/Android.bp index 533687bb7d..a367457ae9 100644 --- a/graphics/composer/2.1/default/Android.bp +++ b/graphics/composer/2.1/default/Android.bp @@ -1,9 +1,10 @@ -cc_library_shared { - name: "android.hardware.graphics.composer@2.1-impl", +cc_binary { + name: "android.hardware.graphics.composer@2.1-service", defaults: ["hidl_defaults"], vendor: true, relative_install_path: "hw", - srcs: ["passthrough.cpp"], + srcs: ["service.cpp"], + init_rc: ["android.hardware.graphics.composer@2.1-service.rc"], header_libs: [ "android.hardware.graphics.composer@2.1-passthrough", ], @@ -11,32 +12,13 @@ cc_library_shared { "android.hardware.graphics.composer@2.1", "android.hardware.graphics.composer@2.1-resources", "libbase", + "libbinder", "libcutils", "libfmq", "libhardware", "libhidlbase", - "liblog", - "libsync", - "libutils", "libhwc2on1adapter", "libhwc2onfbadapter", - ], - cflags: [ - "-DLOG_TAG=\"ComposerHal\"" - ], -} - -cc_binary { - name: "android.hardware.graphics.composer@2.1-service", - defaults: ["hidl_defaults"], - vendor: true, - relative_install_path: "hw", - srcs: ["service.cpp"], - init_rc: ["android.hardware.graphics.composer@2.1-service.rc"], - shared_libs: [ - "android.hardware.graphics.composer@2.1", - "libbinder", - "libhidlbase", "liblog", "libsync", "libutils", diff --git a/graphics/composer/2.1/default/passthrough.cpp b/graphics/composer/2.1/default/passthrough.cpp deleted file mode 100644 index ef7ed7c87a..0000000000 --- a/graphics/composer/2.1/default/passthrough.cpp +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include - -using android::hardware::graphics::composer::V2_1::IComposer; -using android::hardware::graphics::composer::V2_1::passthrough::HwcLoader; - -extern "C" IComposer* HIDL_FETCH_IComposer(const char* /* name */) { - return HwcLoader::load(); -} diff --git a/graphics/composer/2.1/default/service.cpp b/graphics/composer/2.1/default/service.cpp index 82a33f6a4e..1276d2df7e 100644 --- a/graphics/composer/2.1/default/service.cpp +++ b/graphics/composer/2.1/default/service.cpp @@ -21,10 +21,11 @@ #include #include +#include #include using android::hardware::graphics::composer::V2_1::IComposer; -using android::hardware::defaultPassthroughServiceImplementation; +using android::hardware::graphics::composer::V2_1::passthrough::HwcLoader; int main() { // the conventional HAL might start binder services @@ -40,5 +41,19 @@ int main() { ALOGE("Couldn't set SCHED_FIFO: %d", errno); } - return defaultPassthroughServiceImplementation(4); + android::hardware::configureRpcThreadpool(4, true /* will join */); + + android::sp composer = HwcLoader::load(); + if (composer == nullptr) { + return 1; + } + if (composer->registerAsService() != android::NO_ERROR) { + ALOGE("failed to register service"); + return 1; + } + + android::hardware::joinRpcThreadpool(); + + ALOGE("service is terminating"); + return 1; } -- GitLab From 872784629bd3018a1ca61d0ab5e85c4953c08be7 Mon Sep 17 00:00:00 2001 From: Hao Chen Date: Thu, 24 Sep 2020 17:23:02 -0700 Subject: [PATCH 189/790] Move Emulated User HAL to Emulated Vehicle Connector Class Test: build; manually tested the following commands ``` > adb shell lshal debug android.hardware.automotive.vehicle@2.0::IVehicle/default --user-hal > adb shell lshal debug android.hardware.automotive.vehicle@2.0::IVehicle/default --set 299896583 a 1 i 666 i 1 i 11 ``` Bug: 166706927 Change-Id: Ic5774e56dec7febcfeaf496111ba77907e1b7fac Change-Id: Ib2545b7e0d6b2eea0734fe013451b1365ee0e8ff --- automotive/vehicle/2.0/default/Android.bp | 1 - .../vehicle/2.0/default/VehicleService.cpp | 2 +- .../vhal_v2_0/EmulatedVehicleConnector.cpp | 36 +++++++++++++------ .../impl/vhal_v2_0/EmulatedVehicleConnector.h | 17 +++++++-- .../impl/vhal_v2_0/VehicleHalServer.cpp | 20 ----------- .../default/impl/vhal_v2_0/VehicleHalServer.h | 8 ----- 6 files changed, 41 insertions(+), 43 deletions(-) diff --git a/automotive/vehicle/2.0/default/Android.bp b/automotive/vehicle/2.0/default/Android.bp index 9a0d89d209..590adc58b0 100644 --- a/automotive/vehicle/2.0/default/Android.bp +++ b/automotive/vehicle/2.0/default/Android.bp @@ -137,7 +137,6 @@ cc_library_static { local_include_dirs: ["common/include/vhal_v2_0"], export_include_dirs: ["impl"], srcs: [ - "impl/vhal_v2_0/EmulatedUserHal.cpp", "impl/vhal_v2_0/GeneratorHub.cpp", "impl/vhal_v2_0/JsonFakeValueGenerator.cpp", "impl/vhal_v2_0/LinearFakeValueGenerator.cpp", diff --git a/automotive/vehicle/2.0/default/VehicleService.cpp b/automotive/vehicle/2.0/default/VehicleService.cpp index 62a4f204bc..7e8deb6777 100644 --- a/automotive/vehicle/2.0/default/VehicleService.cpp +++ b/automotive/vehicle/2.0/default/VehicleService.cpp @@ -31,7 +31,7 @@ using namespace android::hardware::automotive::vehicle::V2_0; int main(int /* argc */, char* /* argv */ []) { auto store = std::make_unique(); - auto connector = impl::makeEmulatedPassthroughConnector(); + auto connector = std::make_unique(); auto userHal = connector->getEmulatedUserHal(); auto hal = std::make_unique(store.get(), connector.get(), userHal); auto emulator = std::make_unique(hal.get()); diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.cpp index 7f9362fdf4..ed3f4a2e8f 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.cpp +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.cpp @@ -35,13 +35,33 @@ namespace V2_0 { namespace impl { -class EmulatedPassthroughConnector : public PassthroughConnector { - public: - bool onDump(const hidl_handle& fd, const hidl_vec& options) override; -}; +EmulatedUserHal* EmulatedVehicleConnector::getEmulatedUserHal() { + return &mEmulatedUserHal; +} + +StatusCode EmulatedVehicleConnector::onSetProperty(const VehiclePropValue& value, + bool updateStatus) { + if (mEmulatedUserHal.isSupported(value.prop)) { + LOG(INFO) << "onSetProperty(): property " << value.prop << " will be handled by UserHal"; -bool EmulatedPassthroughConnector::onDump(const hidl_handle& handle, - const hidl_vec& options) { + const auto& ret = mEmulatedUserHal.onSetProperty(value); + if (!ret.ok()) { + LOG(ERROR) << "onSetProperty(): HAL returned error: " << ret.error().message(); + return StatusCode(ret.error().code()); + } + auto updatedValue = ret.value().get(); + if (updatedValue != nullptr) { + LOG(INFO) << "onSetProperty(): updating property returned by HAL: " + << toString(*updatedValue); + onPropertyValueFromCar(*updatedValue, updateStatus); + } + return StatusCode::OK; + } + return this->VehicleHalServer::onSetProperty(value, updateStatus); +} + +bool EmulatedVehicleConnector::onDump(const hidl_handle& handle, + const hidl_vec& options) { int fd = handle->data[0]; if (options.size() > 0) { @@ -68,10 +88,6 @@ bool EmulatedPassthroughConnector::onDump(const hidl_handle& handle, return true; } -PassthroughConnectorPtr makeEmulatedPassthroughConnector() { - return std::make_unique(); -} - } // namespace impl } // namespace V2_0 diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.h index 57cbb8b893..4c6c66150b 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.h +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.h @@ -19,6 +19,7 @@ #include +#include "EmulatedUserHal.h" #include "VehicleHalClient.h" #include "VehicleHalServer.h" @@ -30,10 +31,20 @@ namespace V2_0 { namespace impl { -using PassthroughConnector = IPassThroughConnector; -using PassthroughConnectorPtr = std::unique_ptr; +class EmulatedVehicleConnector : public IPassThroughConnector { + public: + EmulatedVehicleConnector() {} -PassthroughConnectorPtr makeEmulatedPassthroughConnector(); + EmulatedUserHal* getEmulatedUserHal(); + + // Methods from VehicleHalServer + StatusCode onSetProperty(const VehiclePropValue& value, bool updateStatus) override; + + bool onDump(const hidl_handle& fd, const hidl_vec& options) override; + + private: + EmulatedUserHal mEmulatedUserHal; +}; } // namespace impl diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.cpp index 36f25345ae..0ee183596a 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.cpp +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.cpp @@ -41,10 +41,6 @@ VehiclePropValuePool* VehicleHalServer::getValuePool() const { return mValuePool; } -EmulatedUserHal* VehicleHalServer::getEmulatedUserHal() { - return &mEmulatedUserHal; -} - void VehicleHalServer::setValuePool(VehiclePropValuePool* valuePool) { if (!valuePool) { LOG(WARNING) << __func__ << ": Setting value pool to nullptr!"; @@ -185,22 +181,6 @@ VehicleHalServer::VehiclePropValuePtr VehicleHalServer::createHwInputKeyProp( } StatusCode VehicleHalServer::onSetProperty(const VehiclePropValue& value, bool updateStatus) { - if (mEmulatedUserHal.isSupported(value.prop)) { - LOG(INFO) << "onSetProperty(): property " << value.prop << " will be handled by UserHal"; - - const auto& ret = mEmulatedUserHal.onSetProperty(value); - if (!ret.ok()) { - LOG(ERROR) << "onSetProperty(): HAL returned error: " << ret.error().message(); - return StatusCode(ret.error().code()); - } - auto updatedValue = ret.value().get(); - if (updatedValue != nullptr) { - LOG(INFO) << "onSetProperty(): updating property returned by HAL: " - << toString(*updatedValue); - onPropertyValueFromCar(*updatedValue, updateStatus); - } - return StatusCode::OK; - } LOG(DEBUG) << "onSetProperty(" << value.prop << ")"; // Some properties need to be treated non-trivially diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.h index fca78bc822..117eadb1e2 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.h +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.h @@ -19,7 +19,6 @@ #include #include -#include "EmulatedUserHal.h" #include "GeneratorHub.h" namespace android::hardware::automotive::vehicle::V2_0::impl { @@ -38,8 +37,6 @@ class VehicleHalServer : public IVehicleServer { // Set the Property Value Pool used in this server void setValuePool(VehiclePropValuePool* valuePool); - EmulatedUserHal* getEmulatedUserHal(); - private: using VehiclePropValuePtr = recyclable_ptr; @@ -56,11 +53,6 @@ class VehicleHalServer : public IVehicleServer { VehiclePropValuePtr createHwInputKeyProp(VehicleHwKeyInputAction action, int32_t keyCode, int32_t targetDisplay); - // data members - - protected: - EmulatedUserHal mEmulatedUserHal; - private: GeneratorHub mGeneratorHub{ std::bind(&VehicleHalServer::onFakeValueGenerated, this, std::placeholders::_1)}; -- GitLab From 42408279d8149a52bb32451cc5bfdaf718f0b384 Mon Sep 17 00:00:00 2001 From: Benjamin Schwartz Date: Mon, 28 Sep 2020 14:33:59 -0700 Subject: [PATCH 190/790] powerstats: Add EnergyConsumer API Also clean up rest of PowerStats HAL 2.0 API and type names Bug: 168831183 Test: atest VtsHalPowerStatsTargetTest Change-Id: I987f984bf717b107cf55213c7063ac9f310f8d54 --- ...rEntityStateInfo.aidl => ChannelInfo.aidl} | 6 +- .../hardware/powerstats/EnergyConsumerId.aidl | 23 +++++ .../powerstats/EnergyConsumerResult.aidl | 24 +++++ ...EnergyData.aidl => EnergyMeasurement.aidl} | 4 +- .../hardware/powerstats/IPowerStats.aidl | 8 +- .../hardware/powerstats/PowerEntityInfo.aidl | 2 +- .../{RailInfo.aidl => StateInfo.aidl} | 8 +- ...ResidencyData.aidl => StateResidency.aidl} | 4 +- ...yResult.aidl => StateResidencyResult.aidl} | 4 +- .../hardware/powerstats/ChannelInfo.aidl | 32 +++++++ .../hardware/powerstats/EnergyConsumerId.aidl | 24 +++++ ...ailInfo.aidl => EnergyConsumerResult.aidl} | 20 ++--- ...EnergyData.aidl => EnergyMeasurement.aidl} | 7 +- .../hardware/powerstats/IPowerStats.aidl | 89 ++++++++++++------- .../hardware/powerstats/PowerEntityInfo.aidl | 6 +- ...werEntityStateInfo.aidl => StateInfo.aidl} | 11 +-- ...ResidencyData.aidl => StateResidency.aidl} | 17 ++-- ...yResult.aidl => StateResidencyResult.aidl} | 8 +- powerstats/aidl/default/PowerStats.cpp | 31 +++++-- powerstats/aidl/default/PowerStats.h | 14 +-- .../aidl/vts/VtsHalPowerStatsTargetTest.cpp | 33 +++---- 21 files changed, 258 insertions(+), 117 deletions(-) rename powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/{PowerEntityStateInfo.aidl => ChannelInfo.aidl} (92%) create mode 100644 powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/EnergyConsumerId.aidl create mode 100644 powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/EnergyConsumerResult.aidl rename powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/{EnergyData.aidl => EnergyMeasurement.aidl} (95%) rename powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/{RailInfo.aidl => StateInfo.aidl} (91%) rename powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/{PowerEntityStateResidencyData.aidl => StateResidency.aidl} (94%) rename powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/{PowerEntityStateResidencyResult.aidl => StateResidencyResult.aidl} (89%) create mode 100644 powerstats/aidl/android/hardware/powerstats/ChannelInfo.aidl create mode 100644 powerstats/aidl/android/hardware/powerstats/EnergyConsumerId.aidl rename powerstats/aidl/android/hardware/powerstats/{RailInfo.aidl => EnergyConsumerResult.aidl} (67%) rename powerstats/aidl/android/hardware/powerstats/{EnergyData.aidl => EnergyMeasurement.aidl} (86%) rename powerstats/aidl/android/hardware/powerstats/{PowerEntityStateInfo.aidl => StateInfo.aidl} (80%) rename powerstats/aidl/android/hardware/powerstats/{PowerEntityStateResidencyData.aidl => StateResidency.aidl} (74%) rename powerstats/aidl/android/hardware/powerstats/{PowerEntityStateResidencyResult.aidl => StateResidencyResult.aidl} (78%) diff --git a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityStateInfo.aidl b/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/ChannelInfo.aidl similarity index 92% rename from powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityStateInfo.aidl rename to powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/ChannelInfo.aidl index 9de66ba8bc..6681df1875 100644 --- a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityStateInfo.aidl +++ b/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/ChannelInfo.aidl @@ -17,7 +17,7 @@ package android.hardware.powerstats; @VintfStability -parcelable PowerEntityStateInfo { - int powerEntityStateId; - String powerEntityStateName; +parcelable ChannelInfo { + int channelId; + String channelName; } diff --git a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/EnergyConsumerId.aidl b/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/EnergyConsumerId.aidl new file mode 100644 index 0000000000..21e7057684 --- /dev/null +++ b/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/EnergyConsumerId.aidl @@ -0,0 +1,23 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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.powerstats; +@Backing(type="int") @VintfStability +enum EnergyConsumerId { + DISPLAY = 0, + GPS = 1, +} diff --git a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/EnergyConsumerResult.aidl b/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/EnergyConsumerResult.aidl new file mode 100644 index 0000000000..47948982de --- /dev/null +++ b/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/EnergyConsumerResult.aidl @@ -0,0 +1,24 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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.powerstats; +@VintfStability +parcelable EnergyConsumerResult { + android.hardware.powerstats.EnergyConsumerId energyConsumerId; + long timestampMs; + long energyUWs; +} diff --git a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/EnergyData.aidl b/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/EnergyMeasurement.aidl similarity index 95% rename from powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/EnergyData.aidl rename to powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/EnergyMeasurement.aidl index 2e384da5ca..3b1031b1a9 100644 --- a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/EnergyData.aidl +++ b/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/EnergyMeasurement.aidl @@ -17,8 +17,8 @@ package android.hardware.powerstats; @VintfStability -parcelable EnergyData { - int railIndex; +parcelable EnergyMeasurement { + int channelId; long timestampMs; long energyUWs; } diff --git a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/IPowerStats.aidl b/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/IPowerStats.aidl index 6772f6f3c4..2f251f345d 100644 --- a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/IPowerStats.aidl +++ b/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/IPowerStats.aidl @@ -18,8 +18,10 @@ package android.hardware.powerstats; @VintfStability interface IPowerStats { - android.hardware.powerstats.EnergyData[] getEnergyData(in int[] railIndices); android.hardware.powerstats.PowerEntityInfo[] getPowerEntityInfo(); - android.hardware.powerstats.PowerEntityStateResidencyResult[] getPowerEntityStateResidencyData(in int[] powerEntityIds); - android.hardware.powerstats.RailInfo[] getRailInfo(); + android.hardware.powerstats.StateResidencyResult[] getPowerEntityStateResidency(in int[] powerEntityIds); + android.hardware.powerstats.EnergyConsumerId[] getEnergyConsumerInfo(); + android.hardware.powerstats.EnergyConsumerResult[] getEnergyConsumed(in android.hardware.powerstats.EnergyConsumerId[] energyConsumerIds); + android.hardware.powerstats.ChannelInfo[] getEnergyMeterInfo(); + android.hardware.powerstats.EnergyMeasurement[] readEnergyMeters(in int[] channelIds); } diff --git a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityInfo.aidl b/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityInfo.aidl index 016af91839..105bab781b 100644 --- a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityInfo.aidl +++ b/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityInfo.aidl @@ -20,5 +20,5 @@ package android.hardware.powerstats; parcelable PowerEntityInfo { int powerEntityId; String powerEntityName; - android.hardware.powerstats.PowerEntityStateInfo[] states; + android.hardware.powerstats.StateInfo[] states; } diff --git a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/RailInfo.aidl b/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/StateInfo.aidl similarity index 91% rename from powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/RailInfo.aidl rename to powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/StateInfo.aidl index 413ea0dd80..6ad3418450 100644 --- a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/RailInfo.aidl +++ b/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/StateInfo.aidl @@ -17,9 +17,7 @@ package android.hardware.powerstats; @VintfStability -parcelable RailInfo { - int railIndex; - String railName; - String subsysName; - int samplingRateHz; +parcelable StateInfo { + int stateId; + String stateName; } diff --git a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityStateResidencyData.aidl b/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/StateResidency.aidl similarity index 94% rename from powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityStateResidencyData.aidl rename to powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/StateResidency.aidl index 8a3b227ed6..c87547cc03 100644 --- a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityStateResidencyData.aidl +++ b/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/StateResidency.aidl @@ -17,8 +17,8 @@ package android.hardware.powerstats; @VintfStability -parcelable PowerEntityStateResidencyData { - int powerEntityStateId; +parcelable StateResidency { + int stateId; long totalTimeInStateMs; long totalStateEntryCount; long lastEntryTimestampMs; diff --git a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityStateResidencyResult.aidl b/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/StateResidencyResult.aidl similarity index 89% rename from powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityStateResidencyResult.aidl rename to powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/StateResidencyResult.aidl index fbe567ea83..b57d965d57 100644 --- a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityStateResidencyResult.aidl +++ b/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/StateResidencyResult.aidl @@ -17,7 +17,7 @@ package android.hardware.powerstats; @VintfStability -parcelable PowerEntityStateResidencyResult { +parcelable StateResidencyResult { int powerEntityId; - android.hardware.powerstats.PowerEntityStateResidencyData[] stateResidencyData; + android.hardware.powerstats.StateResidency[] stateResidencyData; } diff --git a/powerstats/aidl/android/hardware/powerstats/ChannelInfo.aidl b/powerstats/aidl/android/hardware/powerstats/ChannelInfo.aidl new file mode 100644 index 0000000000..77d2289887 --- /dev/null +++ b/powerstats/aidl/android/hardware/powerstats/ChannelInfo.aidl @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.powerstats; + +@VintfStability +parcelable ChannelInfo { + /** + * Unique ID + */ + int channelId; + /** + * Unique name of the ChannelInfo: + * + * Vendor/device specific. Opaque to framework + */ + String channelName; +} + diff --git a/powerstats/aidl/android/hardware/powerstats/EnergyConsumerId.aidl b/powerstats/aidl/android/hardware/powerstats/EnergyConsumerId.aidl new file mode 100644 index 0000000000..2839a193fd --- /dev/null +++ b/powerstats/aidl/android/hardware/powerstats/EnergyConsumerId.aidl @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.powerstats; + +@VintfStability +@Backing(type="int") +enum EnergyConsumerId { + DISPLAY = 0, + GPS = 1, +} \ No newline at end of file diff --git a/powerstats/aidl/android/hardware/powerstats/RailInfo.aidl b/powerstats/aidl/android/hardware/powerstats/EnergyConsumerResult.aidl similarity index 67% rename from powerstats/aidl/android/hardware/powerstats/RailInfo.aidl rename to powerstats/aidl/android/hardware/powerstats/EnergyConsumerResult.aidl index 4c05bfec87..2c4e9e472a 100644 --- a/powerstats/aidl/android/hardware/powerstats/RailInfo.aidl +++ b/powerstats/aidl/android/hardware/powerstats/EnergyConsumerResult.aidl @@ -16,23 +16,21 @@ package android.hardware.powerstats; +import android.hardware.powerstats.EnergyConsumerId; + @VintfStability -parcelable RailInfo { - /** - * Index corresponding to the rail - */ - int railIndex; +parcelable EnergyConsumerResult { /** - * Name of the rail (opaque to the framework) + * Unique ID associated with the given EnergyMeterInfo */ - String railName; + EnergyConsumerId energyConsumerId; /** - * Name of the subsystem to which this rail belongs (opaque to the framework) + * Time since device boot in milliseconds */ - String subsysName; + long timestampMs; /** - * Hardware sampling rate in Hz + * Accumulated energy since device boot in microwatt-seconds (uWs) */ - int samplingRateHz; + long energyUWs; } diff --git a/powerstats/aidl/android/hardware/powerstats/EnergyData.aidl b/powerstats/aidl/android/hardware/powerstats/EnergyMeasurement.aidl similarity index 86% rename from powerstats/aidl/android/hardware/powerstats/EnergyData.aidl rename to powerstats/aidl/android/hardware/powerstats/EnergyMeasurement.aidl index ec12c5e0b2..3b31b46916 100644 --- a/powerstats/aidl/android/hardware/powerstats/EnergyData.aidl +++ b/powerstats/aidl/android/hardware/powerstats/EnergyMeasurement.aidl @@ -17,12 +17,11 @@ package android.hardware.powerstats; @VintfStability -parcelable EnergyData { +parcelable EnergyMeasurement { /** - * Index corresponding to the rail. This index matches - * the index returned in RailInfo + * Unique ID corresponding to the given ChannelInfo */ - int railIndex; + int channelId; /** * Time since device boot(CLOCK_BOOTTIME) in milli-seconds */ diff --git a/powerstats/aidl/android/hardware/powerstats/IPowerStats.aidl b/powerstats/aidl/android/hardware/powerstats/IPowerStats.aidl index 93d1448376..9943605332 100644 --- a/powerstats/aidl/android/hardware/powerstats/IPowerStats.aidl +++ b/powerstats/aidl/android/hardware/powerstats/IPowerStats.aidl @@ -16,26 +16,16 @@ package android.hardware.powerstats; -import android.hardware.powerstats.EnergyData; +import android.hardware.powerstats.ChannelInfo; +import android.hardware.powerstats.EnergyConsumerId; +import android.hardware.powerstats.EnergyConsumerResult; +import android.hardware.powerstats.EnergyMeasurement; import android.hardware.powerstats.PowerEntityInfo; -import android.hardware.powerstats.PowerEntityStateResidencyResult; -import android.hardware.powerstats.RailInfo; +import android.hardware.powerstats.StateResidencyResult; @VintfStability interface IPowerStats { /** - * Rail level energy measurements for low frequency clients: - * Reports accumulated energy since boot on each rail. - * - * @param railIndices Indices of rails for which data is required. - * To get data for all rails pass an empty vector. Rail name to - * index mapping can be queried from getRailInfo() API. - * @return Energy values since boot for all requested rails. - */ - EnergyData[] getEnergyData(in int[] railIndices); - - /** - * PowerEntity information: * Reports information related to all supported PowerEntity(s) for which * data is available. A PowerEntity is defined as a platform subsystem, * peripheral, or power domain that impacts the total device power @@ -46,29 +36,64 @@ interface IPowerStats { PowerEntityInfo[] getPowerEntityInfo(); /** - * PowerEntity residencies for low frequency clients: * Reports accumulated residency data for each specified PowerEntity. * Each PowerEntity may reside in one of multiple states. It may also - * transition to another state. Residency data is an accumulation of time - * that a specified PowerEntity resided in each of its possible states, - * the number of times that each state was entered, and a timestamp - * corresponding to the last time that state was entered. Data is - * accumulated starting from the last time the PowerEntity was reset. + * transition from one state to another. StateResidency is defined as + * an accumulation of time that a PowerEntity resided in each + * of its possible states, the number of times that each state was + * entered, and a timestamp corresponding to the last time that state + * was entered. Data is accumulated starting from the last time the + * PowerEntity was reset. + * + * @param powerEntityIds IDs of PowerEntities for which data is required. + * To get data for all PowerEntities pass an empty vector. PowerEntity name to + * ID mapping can be queried from getPowerEntityInfo() API. + * @return StateResidency since boot for all requested PowerEntity(s). + */ + StateResidencyResult[] getPowerEntityStateResidency(in int[] powerEntityIds); + + /** + * Reports a list of IDs corresponding to all enabled EnergyConsumers. + * + * @return list of EnergyConsumersIds that are available. + */ + EnergyConsumerId[] getEnergyConsumerInfo(); + + /** + * Returns any available energy consumption results. * - * @param powerEntityId collection of IDs of PowerEntity(s) for which - * residency data is requested. PowerEntity name to ID mapping may - * be queried from getPowerEntityInfo(). To get state residency - * data for all PowerEntity(s) pass an empty vector. - * @return state residency data for each specified - * PowerEntity that provides state residency data. + * @param energyConsumerIds IDs of EnergyConsumers for which data is requested. + * To get data for all EnergyConsumers pass an empty list. + * @return List of EnergyConsumerResults reporting energy consumed since boot for each requested + * EnergyConsumerId. + * + * Returns the following service-specific exceptions: + * STATUS_FAILED_TRANSACTION if any of the requested energy results is unavailable + * STATUS_BAD_VALUE if an invalid EnergyConsumer Id is provided */ - PowerEntityStateResidencyResult[] getPowerEntityStateResidencyData(in int[] powerEntityIds); + EnergyConsumerResult[] getEnergyConsumed(in EnergyConsumerId[] energyConsumerIds); /** - * Rail information: - * Reports information related to the rails being monitored. + * Reports channels monitored by Energy Meters. + * Each channel has a name, which may correspond to the name of a power rail on the device, + * and an Id which is used to relate EnergyMeasurements returned by readEnergyMeters() with a + * given ChannelInfo. + * + * @return Information about channels monitored by Energy Meters. + */ + ChannelInfo[] getEnergyMeterInfo(); + + /** + * Reports accumulated energy since boot for each specified channel. + * + * @param channelIds IDs of channels for which data is requested. + * To get data for all channels pass an empty list. Channel name to + * ID mapping can be queried from getEnergyMeterInfo() API. + * @return Energy measured since boot for all requested channels. * - * @return Information about monitored rails. + * Returns the following service-specific exceptions: + * STATUS_FAILED_TRANSACTION if any of the requested energy measurements are unavailable + * STATUS_BAD_VALUE if an invalid channelId is provided */ - RailInfo[] getRailInfo(); + EnergyMeasurement[] readEnergyMeters(in int[] channelIds); } \ No newline at end of file diff --git a/powerstats/aidl/android/hardware/powerstats/PowerEntityInfo.aidl b/powerstats/aidl/android/hardware/powerstats/PowerEntityInfo.aidl index 72222a627e..a8ca0f62ca 100644 --- a/powerstats/aidl/android/hardware/powerstats/PowerEntityInfo.aidl +++ b/powerstats/aidl/android/hardware/powerstats/PowerEntityInfo.aidl @@ -16,7 +16,7 @@ package android.hardware.powerstats; -import android.hardware.powerstats.PowerEntityStateInfo; +import android.hardware.powerstats.StateInfo; /** * PowerEntityInfo contains information, such as the ID, name, and type of a @@ -29,11 +29,11 @@ parcelable PowerEntityInfo { */ int powerEntityId; /** - * Name of the PowerEntity (opaque to the framework) + * Unique name of the PowerEntity. Vendor/device specific. Opaque to framework. */ String powerEntityName; /** * List of states that the PowerEntity may reside in */ - PowerEntityStateInfo[] states; + StateInfo[] states; } \ No newline at end of file diff --git a/powerstats/aidl/android/hardware/powerstats/PowerEntityStateInfo.aidl b/powerstats/aidl/android/hardware/powerstats/StateInfo.aidl similarity index 80% rename from powerstats/aidl/android/hardware/powerstats/PowerEntityStateInfo.aidl rename to powerstats/aidl/android/hardware/powerstats/StateInfo.aidl index 69fc79828d..756fd873b6 100644 --- a/powerstats/aidl/android/hardware/powerstats/PowerEntityStateInfo.aidl +++ b/powerstats/aidl/android/hardware/powerstats/StateInfo.aidl @@ -17,14 +17,15 @@ package android.hardware.powerstats; @VintfStability -parcelable PowerEntityStateInfo { +parcelable StateInfo { /** - * ID corresponding to the state. Unique for a given PowerEntityStateSpace + * ID corresponding to the state. Unique for a given PowerEntityInfo */ - int powerEntityStateId; + int stateId; /** - * Name of the state (opaque to the framework) + * Unique (for a given PowerEntityInfo) name of the state. Vendor/device specific. + * Opaque to framework. */ - String powerEntityStateName; + String stateName; } diff --git a/powerstats/aidl/android/hardware/powerstats/PowerEntityStateResidencyData.aidl b/powerstats/aidl/android/hardware/powerstats/StateResidency.aidl similarity index 74% rename from powerstats/aidl/android/hardware/powerstats/PowerEntityStateResidencyData.aidl rename to powerstats/aidl/android/hardware/powerstats/StateResidency.aidl index a738457fe9..882ba5b318 100644 --- a/powerstats/aidl/android/hardware/powerstats/PowerEntityStateResidencyData.aidl +++ b/powerstats/aidl/android/hardware/powerstats/StateResidency.aidl @@ -20,25 +20,22 @@ package android.hardware.powerstats; * Contains residency data for a single state */ @VintfStability -parcelable PowerEntityStateResidencyData { +parcelable StateResidency { /** - * Unique ID of the corresponding PowerEntityStateInfo + * ID of the corresponding StateInfo */ - int powerEntityStateId; + int stateId; /** * Total time in milliseconds that the corresponding PowerEntity resided - * in this state since the PowerEntity was reset + * in since device boot */ long totalTimeInStateMs; /** - * Total number of times that the state was entered since the corresponding - * PowerEntity was reset + * Total number of times that the state was entered since device boot */ long totalStateEntryCount; /** - * Last time this state was entered. Time in milliseconds since the - * corresponding PowerEntity was reset + * Last time this state was entered. Time in milliseconds since device boot */ long lastEntryTimestampMs; -} - +} \ No newline at end of file diff --git a/powerstats/aidl/android/hardware/powerstats/PowerEntityStateResidencyResult.aidl b/powerstats/aidl/android/hardware/powerstats/StateResidencyResult.aidl similarity index 78% rename from powerstats/aidl/android/hardware/powerstats/PowerEntityStateResidencyResult.aidl rename to powerstats/aidl/android/hardware/powerstats/StateResidencyResult.aidl index 555ae4c78e..d6ac4eaee0 100644 --- a/powerstats/aidl/android/hardware/powerstats/PowerEntityStateResidencyResult.aidl +++ b/powerstats/aidl/android/hardware/powerstats/StateResidencyResult.aidl @@ -16,17 +16,17 @@ package android.hardware.powerstats; -import android.hardware.powerstats.PowerEntityStateResidencyData; +import android.hardware.powerstats.StateResidency; @VintfStability -parcelable PowerEntityStateResidencyResult { +parcelable StateResidencyResult { /** - * Unique ID of the corresponding PowerEntity + * ID of the corresponding PowerEntity */ int powerEntityId; /** * Residency data for each state the PowerEntity's state space */ - PowerEntityStateResidencyData[] stateResidencyData; + StateResidency[] stateResidencyData; } diff --git a/powerstats/aidl/default/PowerStats.cpp b/powerstats/aidl/default/PowerStats.cpp index 8d6a0ee4aa..9f3e76e380 100644 --- a/powerstats/aidl/default/PowerStats.cpp +++ b/powerstats/aidl/default/PowerStats.cpp @@ -23,27 +23,40 @@ namespace android { namespace hardware { namespace powerstats { -ndk::ScopedAStatus PowerStats::getEnergyData(const std::vector& in_railIndices, - std::vector* _aidl_return) { - (void)in_railIndices; +ndk::ScopedAStatus PowerStats::getPowerEntityInfo(std::vector* _aidl_return) { (void)_aidl_return; return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus PowerStats::getPowerEntityInfo(std::vector* _aidl_return) { +ndk::ScopedAStatus PowerStats::getPowerEntityStateResidency( + const std::vector& in_powerEntityIds, + std::vector* _aidl_return) { + (void)in_powerEntityIds; (void)_aidl_return; return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus PowerStats::getPowerEntityStateResidencyData( - const std::vector& in_powerEntityIds, - std::vector* _aidl_return) { - (void)in_powerEntityIds; +ndk::ScopedAStatus PowerStats::getEnergyConsumerInfo(std::vector* _aidl_return) { + (void)_aidl_return; + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus PowerStats::getEnergyConsumed( + const std::vector& in_energyConsumerIds, + std::vector* _aidl_return) { + (void)in_energyConsumerIds; + (void)_aidl_return; + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus PowerStats::getEnergyMeterInfo(std::vector* _aidl_return) { (void)_aidl_return; return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus PowerStats::getRailInfo(std::vector* _aidl_return) { +ndk::ScopedAStatus PowerStats::readEnergyMeters(const std::vector& in_channelIds, + std::vector* _aidl_return) { + (void)in_channelIds; (void)_aidl_return; return ndk::ScopedAStatus::ok(); } diff --git a/powerstats/aidl/default/PowerStats.h b/powerstats/aidl/default/PowerStats.h index 49240cb718..0007efae2b 100644 --- a/powerstats/aidl/default/PowerStats.h +++ b/powerstats/aidl/default/PowerStats.h @@ -26,13 +26,17 @@ namespace powerstats { class PowerStats : public BnPowerStats { public: PowerStats() = default; - ndk::ScopedAStatus getEnergyData(const std::vector& in_railIndices, - std::vector* _aidl_return) override; + // Methods from aidl::android::hardware::powerstats::IPowerStats ndk::ScopedAStatus getPowerEntityInfo(std::vector* _aidl_return) override; - ndk::ScopedAStatus getPowerEntityStateResidencyData( + ndk::ScopedAStatus getPowerEntityStateResidency( const std::vector& in_powerEntityIds, - std::vector* _aidl_return) override; - ndk::ScopedAStatus getRailInfo(std::vector* _aidl_return) override; + std::vector* _aidl_return) override; + ndk::ScopedAStatus getEnergyConsumerInfo(std::vector* _aidl_return) override; + ndk::ScopedAStatus getEnergyConsumed(const std::vector& in_energyConsumerIds, + std::vector* _aidl_return) override; + ndk::ScopedAStatus getEnergyMeterInfo(std::vector* _aidl_return) override; + ndk::ScopedAStatus readEnergyMeters(const std::vector& in_channelIds, + std::vector* _aidl_return) override; }; } // namespace powerstats diff --git a/powerstats/aidl/vts/VtsHalPowerStatsTargetTest.cpp b/powerstats/aidl/vts/VtsHalPowerStatsTargetTest.cpp index b3cd233945..34d1b22587 100644 --- a/powerstats/aidl/vts/VtsHalPowerStatsTargetTest.cpp +++ b/powerstats/aidl/vts/VtsHalPowerStatsTargetTest.cpp @@ -21,11 +21,12 @@ #include #include -using aidl::android::hardware::powerstats::EnergyData; +using aidl::android::hardware::powerstats::ChannelInfo; +using aidl::android::hardware::powerstats::EnergyMeasurement; using aidl::android::hardware::powerstats::IPowerStats; using aidl::android::hardware::powerstats::PowerEntityInfo; -using aidl::android::hardware::powerstats::PowerEntityStateResidencyResult; -using aidl::android::hardware::powerstats::RailInfo; +using aidl::android::hardware::powerstats::StateResidencyResult; + using ndk::SpAIBinder; class PowerStatsAidl : public testing::TestWithParam { @@ -39,9 +40,9 @@ class PowerStatsAidl : public testing::TestWithParam { std::shared_ptr powerstats; }; -TEST_P(PowerStatsAidl, TestGetEnergyData) { - std::vector data; - ASSERT_TRUE(powerstats->getEnergyData({}, &data).isOk()); +TEST_P(PowerStatsAidl, TestReadEnergyMeter) { + std::vector data; + ASSERT_TRUE(powerstats->readEnergyMeters({}, &data).isOk()); } // Each PowerEntity must have a valid name @@ -83,7 +84,7 @@ TEST_P(PowerStatsAidl, ValidateStateNames) { for (auto info : infos) { for (auto state : info.states) { - EXPECT_NE(state.powerEntityStateName, ""); + EXPECT_NE(state.stateName, ""); } } } @@ -96,7 +97,7 @@ TEST_P(PowerStatsAidl, ValidateStateUniqueNames) { for (auto info : infos) { std::set stateNames; for (auto state : info.states) { - EXPECT_TRUE(stateNames.insert(state.powerEntityStateName).second); + EXPECT_TRUE(stateNames.insert(state.stateName).second); } } } @@ -107,21 +108,21 @@ TEST_P(PowerStatsAidl, ValidateStateUniqueIds) { ASSERT_TRUE(powerstats->getPowerEntityInfo(&infos).isOk()); for (auto info : infos) { - std::set stateIds; + std::set stateIds; for (auto state : info.states) { - EXPECT_TRUE(stateIds.insert(state.powerEntityStateId).second); + EXPECT_TRUE(stateIds.insert(state.stateId).second); } } } -TEST_P(PowerStatsAidl, TestGetPowerEntityStateResidencyData) { - std::vector data; - ASSERT_TRUE(powerstats->getPowerEntityStateResidencyData({}, &data).isOk()); +TEST_P(PowerStatsAidl, TestGetStateResidencyData) { + std::vector data; + ASSERT_TRUE(powerstats->getPowerEntityStateResidency({}, &data).isOk()); } -TEST_P(PowerStatsAidl, TestGetRailInfo) { - std::vector info; - ASSERT_TRUE(powerstats->getRailInfo(&info).isOk()); +TEST_P(PowerStatsAidl, TestGetEnergyMeterInfo) { + std::vector info; + ASSERT_TRUE(powerstats->getEnergyMeterInfo(&info).isOk()); } GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(PowerStatsAidl); -- GitLab From bcbd925087b4f37d3e4e99c5ef32631c9900782b Mon Sep 17 00:00:00 2001 From: Kai Date: Thu, 1 Oct 2020 21:15:09 -0700 Subject: [PATCH 191/790] Add SEAT_OCCUPANCY property into google VHAL Bug: 169903497 Test: check the property value and config in KitchSink Change-Id: Ie947414a3ee517b6711f0632e8b3a71eb6f5cbee --- .../2.0/default/impl/vhal_v2_0/DefaultConfig.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h index e3b559ec8d..411bde9228 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h @@ -306,6 +306,19 @@ const ConfigDeclaration kVehicleProperties[]{ }, .initialValue = {.int32Values = {(int)VehicleUnit::KILOMETERS_PER_HOUR}}}, + {.config = + { + .prop = toInt(VehicleProperty::SEAT_OCCUPANCY), + .access = VehiclePropertyAccess::READ, + .changeMode = VehiclePropertyChangeMode::ON_CHANGE, + .areaConfigs = {VehicleAreaConfig{.areaId = (SEAT_1_LEFT)}, + VehicleAreaConfig{.areaId = (SEAT_1_RIGHT)}}, + }, + .initialAreaValues = {{SEAT_1_LEFT, + {.int32Values = {(int)VehicleSeatOccupancyState::VACANT}}}, + {SEAT_1_RIGHT, + {.int32Values = {(int)VehicleSeatOccupancyState::VACANT}}}}}, + {.config = { .prop = toInt(VehicleProperty::INFO_DRIVER_SEAT), -- GitLab From 854acd7c7dbb51f3dfe0bce90ba6c9dcaf852eb0 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Fri, 2 Oct 2020 13:47:07 -0700 Subject: [PATCH 192/790] wifi: Deprecate older versions of wifi HAL Various wifi protocol MAC randomizations are mandatory in Android 11. So, deprecate older versions of wifi HAL which don't support the corresponding API's. Bug: 169201652 Test: Compiles Change-Id: I20f5b3665650c86fc0f976c544194f87157e6b90 --- compatibility_matrices/compatibility_matrix.current.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index 9400543e7f..0535955f50 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -547,7 +547,7 @@ android.hardware.wifi - 1.0-5 + 1.3-5 IWifi default @@ -563,7 +563,7 @@ android.hardware.wifi.supplicant - 1.0-4 + 1.2-4 ISupplicant default -- GitLab From 5345624e368a522cb41908603178a66c1c27a22f Mon Sep 17 00:00:00 2001 From: Benjamin Schwartz Date: Sat, 3 Oct 2020 12:54:35 -0700 Subject: [PATCH 193/790] powerstats: Refine PowerStats HAL 2.0 documentation Bug: 169864180 Test: m Change-Id: I988ff3508fdb09803a0ffdafc9d40cac3b72e075 --- .../hardware/powerstats/ChannelInfo.aidl | 2 +- .../hardware/powerstats/IPowerStats.aidl | 2 +- .../hardware/powerstats/PowerEntityInfo.aidl | 2 +- .../hardware/powerstats/StateInfo.aidl | 2 +- .../hardware/powerstats/ChannelInfo.aidl | 8 +- .../powerstats/EnergyConsumerResult.aidl | 6 +- .../powerstats/EnergyMeasurement.aidl | 6 +- .../hardware/powerstats/IPowerStats.aidl | 77 +++++++++++-------- .../hardware/powerstats/PowerEntityInfo.aidl | 10 +-- .../hardware/powerstats/StateInfo.aidl | 6 +- .../hardware/powerstats/StateResidency.aidl | 8 +- .../powerstats/StateResidencyResult.aidl | 4 +- powerstats/aidl/default/PowerStats.cpp | 5 +- powerstats/aidl/default/PowerStats.h | 5 +- .../aidl/vts/VtsHalPowerStatsTargetTest.cpp | 6 +- 15 files changed, 77 insertions(+), 72 deletions(-) diff --git a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/ChannelInfo.aidl b/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/ChannelInfo.aidl index 6681df1875..51ac7bf442 100644 --- a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/ChannelInfo.aidl +++ b/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/ChannelInfo.aidl @@ -19,5 +19,5 @@ package android.hardware.powerstats; @VintfStability parcelable ChannelInfo { int channelId; - String channelName; + @utf8InCpp String channelName; } diff --git a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/IPowerStats.aidl b/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/IPowerStats.aidl index 2f251f345d..cc668eac44 100644 --- a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/IPowerStats.aidl +++ b/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/IPowerStats.aidl @@ -19,7 +19,7 @@ package android.hardware.powerstats; @VintfStability interface IPowerStats { android.hardware.powerstats.PowerEntityInfo[] getPowerEntityInfo(); - android.hardware.powerstats.StateResidencyResult[] getPowerEntityStateResidency(in int[] powerEntityIds); + android.hardware.powerstats.StateResidencyResult[] getStateResidency(in int[] powerEntityIds); android.hardware.powerstats.EnergyConsumerId[] getEnergyConsumerInfo(); android.hardware.powerstats.EnergyConsumerResult[] getEnergyConsumed(in android.hardware.powerstats.EnergyConsumerId[] energyConsumerIds); android.hardware.powerstats.ChannelInfo[] getEnergyMeterInfo(); diff --git a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityInfo.aidl b/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityInfo.aidl index 105bab781b..28939a3b4c 100644 --- a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityInfo.aidl +++ b/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityInfo.aidl @@ -19,6 +19,6 @@ package android.hardware.powerstats; @VintfStability parcelable PowerEntityInfo { int powerEntityId; - String powerEntityName; + @utf8InCpp String powerEntityName; android.hardware.powerstats.StateInfo[] states; } diff --git a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/StateInfo.aidl b/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/StateInfo.aidl index 6ad3418450..46d89eec08 100644 --- a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/StateInfo.aidl +++ b/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/StateInfo.aidl @@ -19,5 +19,5 @@ package android.hardware.powerstats; @VintfStability parcelable StateInfo { int stateId; - String stateName; + @utf8InCpp String stateName; } diff --git a/powerstats/aidl/android/hardware/powerstats/ChannelInfo.aidl b/powerstats/aidl/android/hardware/powerstats/ChannelInfo.aidl index 77d2289887..61cce85d1c 100644 --- a/powerstats/aidl/android/hardware/powerstats/ChannelInfo.aidl +++ b/powerstats/aidl/android/hardware/powerstats/ChannelInfo.aidl @@ -19,14 +19,12 @@ package android.hardware.powerstats; @VintfStability parcelable ChannelInfo { /** - * Unique ID + * Unique ID of this ChannelInfo */ int channelId; /** - * Unique name of the ChannelInfo: - * - * Vendor/device specific. Opaque to framework + * Unique name of the ChannelInfo. Vendor/device specific. Opaque to framework */ - String channelName; + @utf8InCpp String channelName; } diff --git a/powerstats/aidl/android/hardware/powerstats/EnergyConsumerResult.aidl b/powerstats/aidl/android/hardware/powerstats/EnergyConsumerResult.aidl index 2c4e9e472a..c52e6385a6 100644 --- a/powerstats/aidl/android/hardware/powerstats/EnergyConsumerResult.aidl +++ b/powerstats/aidl/android/hardware/powerstats/EnergyConsumerResult.aidl @@ -21,15 +21,15 @@ import android.hardware.powerstats.EnergyConsumerId; @VintfStability parcelable EnergyConsumerResult { /** - * Unique ID associated with the given EnergyMeterInfo + * ID of the EnergyConsumer associated with this result */ EnergyConsumerId energyConsumerId; /** - * Time since device boot in milliseconds + * Time since boot in milliseconds */ long timestampMs; /** - * Accumulated energy since device boot in microwatt-seconds (uWs) + * Accumulated energy since boot in microwatt-seconds (uWs) */ long energyUWs; } diff --git a/powerstats/aidl/android/hardware/powerstats/EnergyMeasurement.aidl b/powerstats/aidl/android/hardware/powerstats/EnergyMeasurement.aidl index 3b31b46916..7c98646fbf 100644 --- a/powerstats/aidl/android/hardware/powerstats/EnergyMeasurement.aidl +++ b/powerstats/aidl/android/hardware/powerstats/EnergyMeasurement.aidl @@ -19,15 +19,15 @@ package android.hardware.powerstats; @VintfStability parcelable EnergyMeasurement { /** - * Unique ID corresponding to the given ChannelInfo + * ID of the Channel associated with this measurement */ int channelId; /** - * Time since device boot(CLOCK_BOOTTIME) in milli-seconds + * Time since boot in milliseconds */ long timestampMs; /** - * Accumulated energy since device boot in microwatt-seconds (uWs) + * Accumulated energy since boot in microwatt-seconds (uWs) */ long energyUWs; } diff --git a/powerstats/aidl/android/hardware/powerstats/IPowerStats.aidl b/powerstats/aidl/android/hardware/powerstats/IPowerStats.aidl index 9943605332..bb13b8e741 100644 --- a/powerstats/aidl/android/hardware/powerstats/IPowerStats.aidl +++ b/powerstats/aidl/android/hardware/powerstats/IPowerStats.aidl @@ -26,58 +26,70 @@ import android.hardware.powerstats.StateResidencyResult; @VintfStability interface IPowerStats { /** - * Reports information related to all supported PowerEntity(s) for which - * data is available. A PowerEntity is defined as a platform subsystem, - * peripheral, or power domain that impacts the total device power - * consumption. + * Return information related to all supported PowerEntity(s) for which state residency data + * is available. + * + * A PowerEntity is defined as a platform subsystem, peripheral, or power domain that impacts + * the total device power consumption. * * @return List of information on each PowerEntity */ PowerEntityInfo[] getPowerEntityInfo(); /** - * Reports accumulated residency data for each specified PowerEntity. + * Reports the accumulated state residency for each requested PowerEntity. + * * Each PowerEntity may reside in one of multiple states. It may also * transition from one state to another. StateResidency is defined as * an accumulation of time that a PowerEntity resided in each * of its possible states, the number of times that each state was * entered, and a timestamp corresponding to the last time that state - * was entered. Data is accumulated starting from the last time the - * PowerEntity was reset. + * was entered. + * + * Data is accumulated starting at device boot. + * + * @param powerEntityIds List of IDs of PowerEntities for which data is requested. + * Passing an empty list will return state residency for all available PowerEntitys. + * ID of each PowerEntity is contained in PowerEntityInfo. + * + * @return StateResidency since boot for each requested PowerEntity * - * @param powerEntityIds IDs of PowerEntities for which data is required. - * To get data for all PowerEntities pass an empty vector. PowerEntity name to - * ID mapping can be queried from getPowerEntityInfo() API. - * @return StateResidency since boot for all requested PowerEntity(s). + * Returns the following service-specific exceptions in order of highest priority: + * - STATUS_BAD_VALUE if an invalid powerEntityId is provided + * - STATUS_FAILED_TRANSACTION if any StateResidencyResult fails to be returned */ - StateResidencyResult[] getPowerEntityStateResidency(in int[] powerEntityIds); + StateResidencyResult[] getStateResidency(in int[] powerEntityIds); /** - * Reports a list of IDs corresponding to all enabled EnergyConsumers. + * Return the list IDs for all supported EnergyConsumers for which energy consumption data is + * available. * - * @return list of EnergyConsumersIds that are available. + * An EnergyConsumer is a device subsystem or peripheral that consumes energy. Energy + * consumption data may be used by framework for the purpose of power attribution. + * + * @return List of EnergyConsumersIds that are available. */ EnergyConsumerId[] getEnergyConsumerInfo(); /** - * Returns any available energy consumption results. + * Reports the energy consumed since boot by each requested EnergyConsumer. + * + * @param energyConsumerIds List of IDs of EnergyConsumers for which data is requested. + * Passing an empty list will return state residency for all available EnergyConsumers. * - * @param energyConsumerIds IDs of EnergyConsumers for which data is requested. - * To get data for all EnergyConsumers pass an empty list. - * @return List of EnergyConsumerResults reporting energy consumed since boot for each requested - * EnergyConsumerId. + * @return Energy consumed since boot for each requested EnergyConsumer * - * Returns the following service-specific exceptions: - * STATUS_FAILED_TRANSACTION if any of the requested energy results is unavailable - * STATUS_BAD_VALUE if an invalid EnergyConsumer Id is provided + * Returns the following service-specific exceptions in order of highest priority: + * - STATUS_BAD_VALUE if an invalid energyConsumerId is provided + * - STATUS_FAILED_TRANSACTION if any EnergyConsumerResult fails to be returned */ EnergyConsumerResult[] getEnergyConsumed(in EnergyConsumerId[] energyConsumerIds); /** - * Reports channels monitored by Energy Meters. - * Each channel has a name, which may correspond to the name of a power rail on the device, - * and an Id which is used to relate EnergyMeasurements returned by readEnergyMeters() with a - * given ChannelInfo. + * Return information related to all channels monitored by Energy Meters. + * + * An Energy Meter is a device that monitors energy and may support monitoring multiple + * channels simultaneously. A channel may correspond a bus, sense resistor, or power rail. * * @return Information about channels monitored by Energy Meters. */ @@ -87,13 +99,14 @@ interface IPowerStats { * Reports accumulated energy since boot for each specified channel. * * @param channelIds IDs of channels for which data is requested. - * To get data for all channels pass an empty list. Channel name to - * ID mapping can be queried from getEnergyMeterInfo() API. - * @return Energy measured since boot for all requested channels. + * Passing an empty list will return energy measurements for all available channels. + * ID of each channel is contained in ChannelInfo. + * + * @return Energy measured since boot for each requested channel * - * Returns the following service-specific exceptions: - * STATUS_FAILED_TRANSACTION if any of the requested energy measurements are unavailable - * STATUS_BAD_VALUE if an invalid channelId is provided + * Returns the following service-specific exceptions in order of highest priority: + * - STATUS_BAD_VALUE if an invalid channelId is provided + * - STATUS_FAILED_TRANSACTION if any EnergyMeasurement fails to be returned */ EnergyMeasurement[] readEnergyMeters(in int[] channelIds); } \ No newline at end of file diff --git a/powerstats/aidl/android/hardware/powerstats/PowerEntityInfo.aidl b/powerstats/aidl/android/hardware/powerstats/PowerEntityInfo.aidl index a8ca0f62ca..bd09d66ddc 100644 --- a/powerstats/aidl/android/hardware/powerstats/PowerEntityInfo.aidl +++ b/powerstats/aidl/android/hardware/powerstats/PowerEntityInfo.aidl @@ -18,20 +18,16 @@ package android.hardware.powerstats; import android.hardware.powerstats.StateInfo; -/** - * PowerEntityInfo contains information, such as the ID, name, and type of a - * given PowerEntity. - */ @VintfStability parcelable PowerEntityInfo { /** - * Unique ID corresponding to the PowerEntity + * Unique ID of this PowerEntityInfo */ int powerEntityId; /** - * Unique name of the PowerEntity. Vendor/device specific. Opaque to framework. + * Unique name of the PowerEntity. Vendor/device specific. Opaque to framework */ - String powerEntityName; + @utf8InCpp String powerEntityName; /** * List of states that the PowerEntity may reside in */ diff --git a/powerstats/aidl/android/hardware/powerstats/StateInfo.aidl b/powerstats/aidl/android/hardware/powerstats/StateInfo.aidl index 756fd873b6..5035f7caea 100644 --- a/powerstats/aidl/android/hardware/powerstats/StateInfo.aidl +++ b/powerstats/aidl/android/hardware/powerstats/StateInfo.aidl @@ -19,13 +19,13 @@ package android.hardware.powerstats; @VintfStability parcelable StateInfo { /** - * ID corresponding to the state. Unique for a given PowerEntityInfo + * Unique (for a given PowerEntityInfo) ID of this StateInfo */ int stateId; /** * Unique (for a given PowerEntityInfo) name of the state. Vendor/device specific. - * Opaque to framework. + * Opaque to framework */ - String stateName; + @utf8InCpp String stateName; } diff --git a/powerstats/aidl/android/hardware/powerstats/StateResidency.aidl b/powerstats/aidl/android/hardware/powerstats/StateResidency.aidl index 882ba5b318..2a8f541f50 100644 --- a/powerstats/aidl/android/hardware/powerstats/StateResidency.aidl +++ b/powerstats/aidl/android/hardware/powerstats/StateResidency.aidl @@ -22,20 +22,20 @@ package android.hardware.powerstats; @VintfStability parcelable StateResidency { /** - * ID of the corresponding StateInfo + * ID of the state associated with this residency */ int stateId; /** * Total time in milliseconds that the corresponding PowerEntity resided - * in since device boot + * in this state since boot */ long totalTimeInStateMs; /** - * Total number of times that the state was entered since device boot + * Total number of times that the state was entered since boot */ long totalStateEntryCount; /** - * Last time this state was entered. Time in milliseconds since device boot + * Last time this state was entered. Time in milliseconds since boot */ long lastEntryTimestampMs; } \ No newline at end of file diff --git a/powerstats/aidl/android/hardware/powerstats/StateResidencyResult.aidl b/powerstats/aidl/android/hardware/powerstats/StateResidencyResult.aidl index d6ac4eaee0..b3a9f03d47 100644 --- a/powerstats/aidl/android/hardware/powerstats/StateResidencyResult.aidl +++ b/powerstats/aidl/android/hardware/powerstats/StateResidencyResult.aidl @@ -21,11 +21,11 @@ import android.hardware.powerstats.StateResidency; @VintfStability parcelable StateResidencyResult { /** - * ID of the corresponding PowerEntity + * ID of the PowerEntity associated with this result */ int powerEntityId; /** - * Residency data for each state the PowerEntity's state space + * Residency for each state in the PowerEntity's state space */ StateResidency[] stateResidencyData; } diff --git a/powerstats/aidl/default/PowerStats.cpp b/powerstats/aidl/default/PowerStats.cpp index 9f3e76e380..d1c97db312 100644 --- a/powerstats/aidl/default/PowerStats.cpp +++ b/powerstats/aidl/default/PowerStats.cpp @@ -28,9 +28,8 @@ ndk::ScopedAStatus PowerStats::getPowerEntityInfo(std::vector* return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus PowerStats::getPowerEntityStateResidency( - const std::vector& in_powerEntityIds, - std::vector* _aidl_return) { +ndk::ScopedAStatus PowerStats::getStateResidency(const std::vector& in_powerEntityIds, + std::vector* _aidl_return) { (void)in_powerEntityIds; (void)_aidl_return; return ndk::ScopedAStatus::ok(); diff --git a/powerstats/aidl/default/PowerStats.h b/powerstats/aidl/default/PowerStats.h index 0007efae2b..6d2d460001 100644 --- a/powerstats/aidl/default/PowerStats.h +++ b/powerstats/aidl/default/PowerStats.h @@ -28,9 +28,8 @@ class PowerStats : public BnPowerStats { PowerStats() = default; // Methods from aidl::android::hardware::powerstats::IPowerStats ndk::ScopedAStatus getPowerEntityInfo(std::vector* _aidl_return) override; - ndk::ScopedAStatus getPowerEntityStateResidency( - const std::vector& in_powerEntityIds, - std::vector* _aidl_return) override; + ndk::ScopedAStatus getStateResidency(const std::vector& in_powerEntityIds, + std::vector* _aidl_return) override; ndk::ScopedAStatus getEnergyConsumerInfo(std::vector* _aidl_return) override; ndk::ScopedAStatus getEnergyConsumed(const std::vector& in_energyConsumerIds, std::vector* _aidl_return) override; diff --git a/powerstats/aidl/vts/VtsHalPowerStatsTargetTest.cpp b/powerstats/aidl/vts/VtsHalPowerStatsTargetTest.cpp index 34d1b22587..e71e4953f3 100644 --- a/powerstats/aidl/vts/VtsHalPowerStatsTargetTest.cpp +++ b/powerstats/aidl/vts/VtsHalPowerStatsTargetTest.cpp @@ -115,9 +115,9 @@ TEST_P(PowerStatsAidl, ValidateStateUniqueIds) { } } -TEST_P(PowerStatsAidl, TestGetStateResidencyData) { - std::vector data; - ASSERT_TRUE(powerstats->getPowerEntityStateResidency({}, &data).isOk()); +TEST_P(PowerStatsAidl, TestGetStateResidency) { + std::vector results; + ASSERT_TRUE(powerstats->getStateResidency({}, &results).isOk()); } TEST_P(PowerStatsAidl, TestGetEnergyMeterInfo) { -- GitLab From bcd9053514181b6150a67f5940f6630dd45ec4e3 Mon Sep 17 00:00:00 2001 From: Benjamin Schwartz Date: Mon, 5 Oct 2020 09:20:16 -0700 Subject: [PATCH 194/790] power/stats: Move PowerStats HAL 2.0 to power/stats Bug: 169864180 Test: dumpsys android.hardware.powerstats.IPowerStats/default Change-Id: Icbadece98b09505efb2f6d0863f15d4b77a29df2 --- {powerstats => power/stats}/aidl/Android.bp | 0 .../current/android/hardware/powerstats/ChannelInfo.aidl | 0 .../current/android/hardware/powerstats/EnergyConsumerId.aidl | 0 .../current/android/hardware/powerstats/EnergyConsumerResult.aidl | 0 .../current/android/hardware/powerstats/EnergyMeasurement.aidl | 0 .../current/android/hardware/powerstats/IPowerStats.aidl | 0 .../current/android/hardware/powerstats/PowerEntityInfo.aidl | 0 .../current/android/hardware/powerstats/StateInfo.aidl | 0 .../current/android/hardware/powerstats/StateResidency.aidl | 0 .../current/android/hardware/powerstats/StateResidencyResult.aidl | 0 .../stats}/aidl/android/hardware/powerstats/ChannelInfo.aidl | 0 .../stats}/aidl/android/hardware/powerstats/EnergyConsumerId.aidl | 0 .../aidl/android/hardware/powerstats/EnergyConsumerResult.aidl | 0 .../aidl/android/hardware/powerstats/EnergyMeasurement.aidl | 0 .../stats}/aidl/android/hardware/powerstats/IPowerStats.aidl | 0 .../stats}/aidl/android/hardware/powerstats/PowerEntityInfo.aidl | 0 .../stats}/aidl/android/hardware/powerstats/StateInfo.aidl | 0 .../stats}/aidl/android/hardware/powerstats/StateResidency.aidl | 0 .../aidl/android/hardware/powerstats/StateResidencyResult.aidl | 0 {powerstats => power/stats}/aidl/default/Android.bp | 0 {powerstats => power/stats}/aidl/default/PowerStats.cpp | 0 {powerstats => power/stats}/aidl/default/PowerStats.h | 0 {powerstats => power/stats}/aidl/default/main.cpp | 0 {powerstats => power/stats}/aidl/default/powerstats-default.rc | 0 {powerstats => power/stats}/aidl/default/powerstats-default.xml | 0 {powerstats => power/stats}/aidl/vts/Android.bp | 0 .../stats}/aidl/vts/VtsHalPowerStatsTargetTest.cpp | 0 27 files changed, 0 insertions(+), 0 deletions(-) rename {powerstats => power/stats}/aidl/Android.bp (100%) rename {powerstats => power/stats}/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/ChannelInfo.aidl (100%) rename {powerstats => power/stats}/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/EnergyConsumerId.aidl (100%) rename {powerstats => power/stats}/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/EnergyConsumerResult.aidl (100%) rename {powerstats => power/stats}/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/EnergyMeasurement.aidl (100%) rename {powerstats => power/stats}/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/IPowerStats.aidl (100%) rename {powerstats => power/stats}/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityInfo.aidl (100%) rename {powerstats => power/stats}/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/StateInfo.aidl (100%) rename {powerstats => power/stats}/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/StateResidency.aidl (100%) rename {powerstats => power/stats}/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/StateResidencyResult.aidl (100%) rename {powerstats => power/stats}/aidl/android/hardware/powerstats/ChannelInfo.aidl (100%) rename {powerstats => power/stats}/aidl/android/hardware/powerstats/EnergyConsumerId.aidl (100%) rename {powerstats => power/stats}/aidl/android/hardware/powerstats/EnergyConsumerResult.aidl (100%) rename {powerstats => power/stats}/aidl/android/hardware/powerstats/EnergyMeasurement.aidl (100%) rename {powerstats => power/stats}/aidl/android/hardware/powerstats/IPowerStats.aidl (100%) rename {powerstats => power/stats}/aidl/android/hardware/powerstats/PowerEntityInfo.aidl (100%) rename {powerstats => power/stats}/aidl/android/hardware/powerstats/StateInfo.aidl (100%) rename {powerstats => power/stats}/aidl/android/hardware/powerstats/StateResidency.aidl (100%) rename {powerstats => power/stats}/aidl/android/hardware/powerstats/StateResidencyResult.aidl (100%) rename {powerstats => power/stats}/aidl/default/Android.bp (100%) rename {powerstats => power/stats}/aidl/default/PowerStats.cpp (100%) rename {powerstats => power/stats}/aidl/default/PowerStats.h (100%) rename {powerstats => power/stats}/aidl/default/main.cpp (100%) rename {powerstats => power/stats}/aidl/default/powerstats-default.rc (100%) rename {powerstats => power/stats}/aidl/default/powerstats-default.xml (100%) rename {powerstats => power/stats}/aidl/vts/Android.bp (100%) rename {powerstats => power/stats}/aidl/vts/VtsHalPowerStatsTargetTest.cpp (100%) diff --git a/powerstats/aidl/Android.bp b/power/stats/aidl/Android.bp similarity index 100% rename from powerstats/aidl/Android.bp rename to power/stats/aidl/Android.bp diff --git a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/ChannelInfo.aidl b/power/stats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/ChannelInfo.aidl similarity index 100% rename from powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/ChannelInfo.aidl rename to power/stats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/ChannelInfo.aidl diff --git a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/EnergyConsumerId.aidl b/power/stats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/EnergyConsumerId.aidl similarity index 100% rename from powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/EnergyConsumerId.aidl rename to power/stats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/EnergyConsumerId.aidl diff --git a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/EnergyConsumerResult.aidl b/power/stats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/EnergyConsumerResult.aidl similarity index 100% rename from powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/EnergyConsumerResult.aidl rename to power/stats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/EnergyConsumerResult.aidl diff --git a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/EnergyMeasurement.aidl b/power/stats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/EnergyMeasurement.aidl similarity index 100% rename from powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/EnergyMeasurement.aidl rename to power/stats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/EnergyMeasurement.aidl diff --git a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/IPowerStats.aidl b/power/stats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/IPowerStats.aidl similarity index 100% rename from powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/IPowerStats.aidl rename to power/stats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/IPowerStats.aidl diff --git a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityInfo.aidl b/power/stats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityInfo.aidl similarity index 100% rename from powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityInfo.aidl rename to power/stats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityInfo.aidl diff --git a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/StateInfo.aidl b/power/stats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/StateInfo.aidl similarity index 100% rename from powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/StateInfo.aidl rename to power/stats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/StateInfo.aidl diff --git a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/StateResidency.aidl b/power/stats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/StateResidency.aidl similarity index 100% rename from powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/StateResidency.aidl rename to power/stats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/StateResidency.aidl diff --git a/powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/StateResidencyResult.aidl b/power/stats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/StateResidencyResult.aidl similarity index 100% rename from powerstats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/StateResidencyResult.aidl rename to power/stats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/StateResidencyResult.aidl diff --git a/powerstats/aidl/android/hardware/powerstats/ChannelInfo.aidl b/power/stats/aidl/android/hardware/powerstats/ChannelInfo.aidl similarity index 100% rename from powerstats/aidl/android/hardware/powerstats/ChannelInfo.aidl rename to power/stats/aidl/android/hardware/powerstats/ChannelInfo.aidl diff --git a/powerstats/aidl/android/hardware/powerstats/EnergyConsumerId.aidl b/power/stats/aidl/android/hardware/powerstats/EnergyConsumerId.aidl similarity index 100% rename from powerstats/aidl/android/hardware/powerstats/EnergyConsumerId.aidl rename to power/stats/aidl/android/hardware/powerstats/EnergyConsumerId.aidl diff --git a/powerstats/aidl/android/hardware/powerstats/EnergyConsumerResult.aidl b/power/stats/aidl/android/hardware/powerstats/EnergyConsumerResult.aidl similarity index 100% rename from powerstats/aidl/android/hardware/powerstats/EnergyConsumerResult.aidl rename to power/stats/aidl/android/hardware/powerstats/EnergyConsumerResult.aidl diff --git a/powerstats/aidl/android/hardware/powerstats/EnergyMeasurement.aidl b/power/stats/aidl/android/hardware/powerstats/EnergyMeasurement.aidl similarity index 100% rename from powerstats/aidl/android/hardware/powerstats/EnergyMeasurement.aidl rename to power/stats/aidl/android/hardware/powerstats/EnergyMeasurement.aidl diff --git a/powerstats/aidl/android/hardware/powerstats/IPowerStats.aidl b/power/stats/aidl/android/hardware/powerstats/IPowerStats.aidl similarity index 100% rename from powerstats/aidl/android/hardware/powerstats/IPowerStats.aidl rename to power/stats/aidl/android/hardware/powerstats/IPowerStats.aidl diff --git a/powerstats/aidl/android/hardware/powerstats/PowerEntityInfo.aidl b/power/stats/aidl/android/hardware/powerstats/PowerEntityInfo.aidl similarity index 100% rename from powerstats/aidl/android/hardware/powerstats/PowerEntityInfo.aidl rename to power/stats/aidl/android/hardware/powerstats/PowerEntityInfo.aidl diff --git a/powerstats/aidl/android/hardware/powerstats/StateInfo.aidl b/power/stats/aidl/android/hardware/powerstats/StateInfo.aidl similarity index 100% rename from powerstats/aidl/android/hardware/powerstats/StateInfo.aidl rename to power/stats/aidl/android/hardware/powerstats/StateInfo.aidl diff --git a/powerstats/aidl/android/hardware/powerstats/StateResidency.aidl b/power/stats/aidl/android/hardware/powerstats/StateResidency.aidl similarity index 100% rename from powerstats/aidl/android/hardware/powerstats/StateResidency.aidl rename to power/stats/aidl/android/hardware/powerstats/StateResidency.aidl diff --git a/powerstats/aidl/android/hardware/powerstats/StateResidencyResult.aidl b/power/stats/aidl/android/hardware/powerstats/StateResidencyResult.aidl similarity index 100% rename from powerstats/aidl/android/hardware/powerstats/StateResidencyResult.aidl rename to power/stats/aidl/android/hardware/powerstats/StateResidencyResult.aidl diff --git a/powerstats/aidl/default/Android.bp b/power/stats/aidl/default/Android.bp similarity index 100% rename from powerstats/aidl/default/Android.bp rename to power/stats/aidl/default/Android.bp diff --git a/powerstats/aidl/default/PowerStats.cpp b/power/stats/aidl/default/PowerStats.cpp similarity index 100% rename from powerstats/aidl/default/PowerStats.cpp rename to power/stats/aidl/default/PowerStats.cpp diff --git a/powerstats/aidl/default/PowerStats.h b/power/stats/aidl/default/PowerStats.h similarity index 100% rename from powerstats/aidl/default/PowerStats.h rename to power/stats/aidl/default/PowerStats.h diff --git a/powerstats/aidl/default/main.cpp b/power/stats/aidl/default/main.cpp similarity index 100% rename from powerstats/aidl/default/main.cpp rename to power/stats/aidl/default/main.cpp diff --git a/powerstats/aidl/default/powerstats-default.rc b/power/stats/aidl/default/powerstats-default.rc similarity index 100% rename from powerstats/aidl/default/powerstats-default.rc rename to power/stats/aidl/default/powerstats-default.rc diff --git a/powerstats/aidl/default/powerstats-default.xml b/power/stats/aidl/default/powerstats-default.xml similarity index 100% rename from powerstats/aidl/default/powerstats-default.xml rename to power/stats/aidl/default/powerstats-default.xml diff --git a/powerstats/aidl/vts/Android.bp b/power/stats/aidl/vts/Android.bp similarity index 100% rename from powerstats/aidl/vts/Android.bp rename to power/stats/aidl/vts/Android.bp diff --git a/powerstats/aidl/vts/VtsHalPowerStatsTargetTest.cpp b/power/stats/aidl/vts/VtsHalPowerStatsTargetTest.cpp similarity index 100% rename from powerstats/aidl/vts/VtsHalPowerStatsTargetTest.cpp rename to power/stats/aidl/vts/VtsHalPowerStatsTargetTest.cpp -- GitLab From 7ec2b704faa7bac3d82338cb708f4dc0612c9917 Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Mon, 5 Oct 2020 18:07:20 -0700 Subject: [PATCH 195/790] Add isHighPriority scan message type into Tuner HAL 1.1 Test: atest VtsHalTvTunerV1_1TargetTest Bug: 169868608 Change-Id: I49a82dc9eda0fc9b1f90bc67cd6d1a20bbafcc00 --- tv/tuner/1.1/default/Frontend.cpp | 5 ++++- tv/tuner/1.1/types.hal | 7 ++++++- tv/tuner/1.1/vts/functional/FrontendTests.cpp | 9 ++++++--- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/tv/tuner/1.1/default/Frontend.cpp b/tv/tuner/1.1/default/Frontend.cpp index 971e335700..7c6f8c6f97 100644 --- a/tv/tuner/1.1/default/Frontend.cpp +++ b/tv/tuner/1.1/default/Frontend.cpp @@ -122,9 +122,12 @@ Return Frontend::scan(const FrontendSettings& settings, FrontendScanType V1_1::IFrontendCallback::castFrom(mCallback); if (frontendCallback_v1_1 != NULL) { V1_1::FrontendScanMessageExt1_1 msg; - msg.dvbc(FrontendDvbcModulation::MOD_16QAM); + msg.modulation().dvbc(FrontendDvbcModulation::MOD_16QAM); frontendCallback_v1_1->onScanMessageExt1_1(V1_1::FrontendScanMessageTypeExt1_1::MODULATION, msg); + msg.isHighPriority(true); + frontendCallback_v1_1->onScanMessageExt1_1( + V1_1::FrontendScanMessageTypeExt1_1::HIGH_PRIORITY, msg); } else { ALOGD("[Filter] Couldn't cast to V1_1 IFrontendCallback"); } diff --git a/tv/tuner/1.1/types.hal b/tv/tuner/1.1/types.hal index b20e6252f0..f8fe2aaf9e 100644 --- a/tv/tuner/1.1/types.hal +++ b/tv/tuner/1.1/types.hal @@ -555,6 +555,11 @@ safe_union FrontendStatusExt1_1 { enum FrontendScanMessageTypeExt1_1 : uint32_t { MODULATION = @1.0::FrontendScanMessageType:ATSC3_PLP_INFO + 1, + HIGH_PRIORITY, }; -typedef FrontendModulation FrontendScanMessageExt1_1; +safe_union FrontendScanMessageExt1_1 { + FrontendModulation modulation; + + bool isHighPriority; +}; diff --git a/tv/tuner/1.1/vts/functional/FrontendTests.cpp b/tv/tuner/1.1/vts/functional/FrontendTests.cpp index 3bc7114b17..e5793c1f34 100644 --- a/tv/tuner/1.1/vts/functional/FrontendTests.cpp +++ b/tv/tuner/1.1/vts/functional/FrontendTests.cpp @@ -51,9 +51,12 @@ Return FrontendCallback::onScanMessageExt1_1(FrontendScanMessageTypeExt1_1 const FrontendScanMessageExt1_1& message) { android::Mutex::Autolock autoLock(mMsgLock); ALOGD("[vts] frontend ext1_1 scan message. Type: %d", type); - switch (type) { - case FrontendScanMessageTypeExt1_1::MODULATION: - readFrontendScanMessageExt1_1Modulation(message); + switch (message.getDiscriminator()) { + case FrontendScanMessageExt1_1::hidl_discriminator::modulation: + readFrontendScanMessageExt1_1Modulation(message.modulation()); + break; + case FrontendScanMessageExt1_1::hidl_discriminator::isHighPriority: + ALOGD("[vts] frontend ext1_1 scan message high priority: %d", message.isHighPriority()); break; default: break; -- GitLab From 71c6f8ba6f31222b4036a074d08d314c95d5f4aa Mon Sep 17 00:00:00 2001 From: Benjamin Schwartz Date: Mon, 5 Oct 2020 15:44:19 -0700 Subject: [PATCH 196/790] power/stats: Rename PowerStats HAL Bug: 169864180 Test: m Change-Id: I6abacd82d9bcbc5957dcad891ae5c742bc307316 --- .../compatibility_matrix.current.xml | 2 +- power/stats/aidl/Android.bp | 4 ++-- .../android/hardware/power/stats}/ChannelInfo.aidl | 2 +- .../hardware/power/stats}/EnergyConsumerId.aidl | 2 +- .../power/stats}/EnergyConsumerResult.aidl | 4 ++-- .../hardware/power/stats}/EnergyMeasurement.aidl | 2 +- .../android/hardware/power/stats}/IPowerStats.aidl | 14 +++++++------- .../hardware/power/stats}/PowerEntityInfo.aidl | 4 ++-- .../android/hardware/power/stats}/StateInfo.aidl | 2 +- .../hardware/power/stats}/StateResidency.aidl | 2 +- .../power/stats}/StateResidencyResult.aidl | 4 ++-- .../{powerstats => power/stats}/ChannelInfo.aidl | 2 +- .../stats}/EnergyConsumerId.aidl | 2 +- .../stats}/EnergyConsumerResult.aidl | 4 ++-- .../stats}/EnergyMeasurement.aidl | 2 +- .../{powerstats => power/stats}/IPowerStats.aidl | 14 +++++++------- .../stats}/PowerEntityInfo.aidl | 4 ++-- .../{powerstats => power/stats}/StateInfo.aidl | 2 +- .../stats}/StateResidency.aidl | 2 +- .../stats}/StateResidencyResult.aidl | 4 ++-- power/stats/aidl/default/Android.bp | 8 ++++---- power/stats/aidl/default/PowerStats.cpp | 6 ++++-- power/stats/aidl/default/PowerStats.h | 10 ++++++---- power/stats/aidl/default/main.cpp | 2 +- power/stats/aidl/default/power.stats-default.rc | 4 ++++ ...erstats-default.xml => power.stats-default.xml} | 2 +- power/stats/aidl/default/powerstats-default.rc | 4 ---- power/stats/aidl/vts/Android.bp | 2 +- .../stats/aidl/vts/VtsHalPowerStatsTargetTest.cpp | 12 ++++++------ 29 files changed, 66 insertions(+), 62 deletions(-) rename power/stats/aidl/aidl_api/{android.hardware.powerstats/current/android/hardware/powerstats => android.hardware.power.stats/current/android/hardware/power/stats}/ChannelInfo.aidl (96%) rename power/stats/aidl/aidl_api/{android.hardware.powerstats/current/android/hardware/powerstats => android.hardware.power.stats/current/android/hardware/power/stats}/EnergyConsumerId.aidl (96%) rename power/stats/aidl/aidl_api/{android.hardware.powerstats/current/android/hardware/powerstats => android.hardware.power.stats/current/android/hardware/power/stats}/EnergyConsumerResult.aidl (91%) rename power/stats/aidl/aidl_api/{android.hardware.powerstats/current/android/hardware/powerstats => android.hardware.power.stats/current/android/hardware/power/stats}/EnergyMeasurement.aidl (96%) rename power/stats/aidl/aidl_api/{android.hardware.powerstats/current/android/hardware/powerstats => android.hardware.power.stats/current/android/hardware/power/stats}/IPowerStats.aidl (65%) rename power/stats/aidl/aidl_api/{android.hardware.powerstats/current/android/hardware/powerstats => android.hardware.power.stats/current/android/hardware/power/stats}/PowerEntityInfo.aidl (92%) rename power/stats/aidl/aidl_api/{android.hardware.powerstats/current/android/hardware/powerstats => android.hardware.power.stats/current/android/hardware/power/stats}/StateInfo.aidl (96%) rename power/stats/aidl/aidl_api/{android.hardware.powerstats/current/android/hardware/powerstats => android.hardware.power.stats/current/android/hardware/power/stats}/StateResidency.aidl (96%) rename power/stats/aidl/aidl_api/{android.hardware.powerstats/current/android/hardware/powerstats => android.hardware.power.stats/current/android/hardware/power/stats}/StateResidencyResult.aidl (91%) rename power/stats/aidl/android/hardware/{powerstats => power/stats}/ChannelInfo.aidl (95%) rename power/stats/aidl/android/hardware/{powerstats => power/stats}/EnergyConsumerId.aidl (94%) rename power/stats/aidl/android/hardware/{powerstats => power/stats}/EnergyConsumerResult.aidl (91%) rename power/stats/aidl/android/hardware/{powerstats => power/stats}/EnergyMeasurement.aidl (96%) rename power/stats/aidl/android/hardware/{powerstats => power/stats}/IPowerStats.aidl (92%) rename power/stats/aidl/android/hardware/{powerstats => power/stats}/PowerEntityInfo.aidl (92%) rename power/stats/aidl/android/hardware/{powerstats => power/stats}/StateInfo.aidl (96%) rename power/stats/aidl/android/hardware/{powerstats => power/stats}/StateResidency.aidl (96%) rename power/stats/aidl/android/hardware/{powerstats => power/stats}/StateResidencyResult.aidl (90%) create mode 100644 power/stats/aidl/default/power.stats-default.rc rename power/stats/aidl/default/{powerstats-default.xml => power.stats-default.xml} (72%) delete mode 100644 power/stats/aidl/default/powerstats-default.rc diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index 9400543e7f..375d9c7ed9 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -381,7 +381,7 @@ - android.hardware.powerstats + android.hardware.power.stats IPowerStats default diff --git a/power/stats/aidl/Android.bp b/power/stats/aidl/Android.bp index 1aa58cb063..1688b12d9a 100644 --- a/power/stats/aidl/Android.bp +++ b/power/stats/aidl/Android.bp @@ -13,10 +13,10 @@ // limitations under the License. aidl_interface { - name: "android.hardware.powerstats", + name: "android.hardware.power.stats", vendor_available: true, srcs: [ - "android/hardware/powerstats/*.aidl", + "android/hardware/power/stats/*.aidl", ], stability: "vintf", backend: { diff --git a/power/stats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/ChannelInfo.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/ChannelInfo.aidl similarity index 96% rename from power/stats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/ChannelInfo.aidl rename to power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/ChannelInfo.aidl index 51ac7bf442..209bec4aa7 100644 --- a/power/stats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/ChannelInfo.aidl +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/ChannelInfo.aidl @@ -15,7 +15,7 @@ // 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.powerstats; +package android.hardware.power.stats; @VintfStability parcelable ChannelInfo { int channelId; diff --git a/power/stats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/EnergyConsumerId.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerId.aidl similarity index 96% rename from power/stats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/EnergyConsumerId.aidl rename to power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerId.aidl index 21e7057684..7ca3b15ff1 100644 --- a/power/stats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/EnergyConsumerId.aidl +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerId.aidl @@ -15,7 +15,7 @@ // 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.powerstats; +package android.hardware.power.stats; @Backing(type="int") @VintfStability enum EnergyConsumerId { DISPLAY = 0, diff --git a/power/stats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/EnergyConsumerResult.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerResult.aidl similarity index 91% rename from power/stats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/EnergyConsumerResult.aidl rename to power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerResult.aidl index 47948982de..6289a08439 100644 --- a/power/stats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/EnergyConsumerResult.aidl +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerResult.aidl @@ -15,10 +15,10 @@ // 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.powerstats; +package android.hardware.power.stats; @VintfStability parcelable EnergyConsumerResult { - android.hardware.powerstats.EnergyConsumerId energyConsumerId; + android.hardware.power.stats.EnergyConsumerId energyConsumerId; long timestampMs; long energyUWs; } diff --git a/power/stats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/EnergyMeasurement.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyMeasurement.aidl similarity index 96% rename from power/stats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/EnergyMeasurement.aidl rename to power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyMeasurement.aidl index 3b1031b1a9..341909e180 100644 --- a/power/stats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/EnergyMeasurement.aidl +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyMeasurement.aidl @@ -15,7 +15,7 @@ // 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.powerstats; +package android.hardware.power.stats; @VintfStability parcelable EnergyMeasurement { int channelId; diff --git a/power/stats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/IPowerStats.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/IPowerStats.aidl similarity index 65% rename from power/stats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/IPowerStats.aidl rename to power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/IPowerStats.aidl index cc668eac44..07013b0b45 100644 --- a/power/stats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/IPowerStats.aidl +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/IPowerStats.aidl @@ -15,13 +15,13 @@ // 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.powerstats; +package android.hardware.power.stats; @VintfStability interface IPowerStats { - android.hardware.powerstats.PowerEntityInfo[] getPowerEntityInfo(); - android.hardware.powerstats.StateResidencyResult[] getStateResidency(in int[] powerEntityIds); - android.hardware.powerstats.EnergyConsumerId[] getEnergyConsumerInfo(); - android.hardware.powerstats.EnergyConsumerResult[] getEnergyConsumed(in android.hardware.powerstats.EnergyConsumerId[] energyConsumerIds); - android.hardware.powerstats.ChannelInfo[] getEnergyMeterInfo(); - android.hardware.powerstats.EnergyMeasurement[] readEnergyMeters(in int[] channelIds); + android.hardware.power.stats.PowerEntityInfo[] getPowerEntityInfo(); + android.hardware.power.stats.StateResidencyResult[] getStateResidency(in int[] powerEntityIds); + android.hardware.power.stats.EnergyConsumerId[] getEnergyConsumerInfo(); + android.hardware.power.stats.EnergyConsumerResult[] getEnergyConsumed(in android.hardware.power.stats.EnergyConsumerId[] energyConsumerIds); + android.hardware.power.stats.ChannelInfo[] getEnergyMeterInfo(); + android.hardware.power.stats.EnergyMeasurement[] readEnergyMeters(in int[] channelIds); } diff --git a/power/stats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityInfo.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/PowerEntityInfo.aidl similarity index 92% rename from power/stats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityInfo.aidl rename to power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/PowerEntityInfo.aidl index 28939a3b4c..3b16362046 100644 --- a/power/stats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/PowerEntityInfo.aidl +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/PowerEntityInfo.aidl @@ -15,10 +15,10 @@ // 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.powerstats; +package android.hardware.power.stats; @VintfStability parcelable PowerEntityInfo { int powerEntityId; @utf8InCpp String powerEntityName; - android.hardware.powerstats.StateInfo[] states; + android.hardware.power.stats.StateInfo[] states; } diff --git a/power/stats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/StateInfo.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateInfo.aidl similarity index 96% rename from power/stats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/StateInfo.aidl rename to power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateInfo.aidl index 46d89eec08..0db9ab190d 100644 --- a/power/stats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/StateInfo.aidl +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateInfo.aidl @@ -15,7 +15,7 @@ // 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.powerstats; +package android.hardware.power.stats; @VintfStability parcelable StateInfo { int stateId; diff --git a/power/stats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/StateResidency.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateResidency.aidl similarity index 96% rename from power/stats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/StateResidency.aidl rename to power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateResidency.aidl index c87547cc03..206c974bc5 100644 --- a/power/stats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/StateResidency.aidl +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateResidency.aidl @@ -15,7 +15,7 @@ // 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.powerstats; +package android.hardware.power.stats; @VintfStability parcelable StateResidency { int stateId; diff --git a/power/stats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/StateResidencyResult.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateResidencyResult.aidl similarity index 91% rename from power/stats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/StateResidencyResult.aidl rename to power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateResidencyResult.aidl index b57d965d57..dc41fef557 100644 --- a/power/stats/aidl/aidl_api/android.hardware.powerstats/current/android/hardware/powerstats/StateResidencyResult.aidl +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateResidencyResult.aidl @@ -15,9 +15,9 @@ // 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.powerstats; +package android.hardware.power.stats; @VintfStability parcelable StateResidencyResult { int powerEntityId; - android.hardware.powerstats.StateResidency[] stateResidencyData; + android.hardware.power.stats.StateResidency[] stateResidencyData; } diff --git a/power/stats/aidl/android/hardware/powerstats/ChannelInfo.aidl b/power/stats/aidl/android/hardware/power/stats/ChannelInfo.aidl similarity index 95% rename from power/stats/aidl/android/hardware/powerstats/ChannelInfo.aidl rename to power/stats/aidl/android/hardware/power/stats/ChannelInfo.aidl index 61cce85d1c..a2ca6a63f1 100644 --- a/power/stats/aidl/android/hardware/powerstats/ChannelInfo.aidl +++ b/power/stats/aidl/android/hardware/power/stats/ChannelInfo.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.powerstats; +package android.hardware.power.stats; @VintfStability parcelable ChannelInfo { diff --git a/power/stats/aidl/android/hardware/powerstats/EnergyConsumerId.aidl b/power/stats/aidl/android/hardware/power/stats/EnergyConsumerId.aidl similarity index 94% rename from power/stats/aidl/android/hardware/powerstats/EnergyConsumerId.aidl rename to power/stats/aidl/android/hardware/power/stats/EnergyConsumerId.aidl index 2839a193fd..4a6a67724d 100644 --- a/power/stats/aidl/android/hardware/powerstats/EnergyConsumerId.aidl +++ b/power/stats/aidl/android/hardware/power/stats/EnergyConsumerId.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.powerstats; +package android.hardware.power.stats; @VintfStability @Backing(type="int") diff --git a/power/stats/aidl/android/hardware/powerstats/EnergyConsumerResult.aidl b/power/stats/aidl/android/hardware/power/stats/EnergyConsumerResult.aidl similarity index 91% rename from power/stats/aidl/android/hardware/powerstats/EnergyConsumerResult.aidl rename to power/stats/aidl/android/hardware/power/stats/EnergyConsumerResult.aidl index c52e6385a6..d2b902ae56 100644 --- a/power/stats/aidl/android/hardware/powerstats/EnergyConsumerResult.aidl +++ b/power/stats/aidl/android/hardware/power/stats/EnergyConsumerResult.aidl @@ -14,9 +14,9 @@ * limitations under the License. */ -package android.hardware.powerstats; +package android.hardware.power.stats; -import android.hardware.powerstats.EnergyConsumerId; +import android.hardware.power.stats.EnergyConsumerId; @VintfStability parcelable EnergyConsumerResult { diff --git a/power/stats/aidl/android/hardware/powerstats/EnergyMeasurement.aidl b/power/stats/aidl/android/hardware/power/stats/EnergyMeasurement.aidl similarity index 96% rename from power/stats/aidl/android/hardware/powerstats/EnergyMeasurement.aidl rename to power/stats/aidl/android/hardware/power/stats/EnergyMeasurement.aidl index 7c98646fbf..f873849303 100644 --- a/power/stats/aidl/android/hardware/powerstats/EnergyMeasurement.aidl +++ b/power/stats/aidl/android/hardware/power/stats/EnergyMeasurement.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.powerstats; +package android.hardware.power.stats; @VintfStability parcelable EnergyMeasurement { diff --git a/power/stats/aidl/android/hardware/powerstats/IPowerStats.aidl b/power/stats/aidl/android/hardware/power/stats/IPowerStats.aidl similarity index 92% rename from power/stats/aidl/android/hardware/powerstats/IPowerStats.aidl rename to power/stats/aidl/android/hardware/power/stats/IPowerStats.aidl index bb13b8e741..85a2ce0093 100644 --- a/power/stats/aidl/android/hardware/powerstats/IPowerStats.aidl +++ b/power/stats/aidl/android/hardware/power/stats/IPowerStats.aidl @@ -14,14 +14,14 @@ * limitations under the License. */ -package android.hardware.powerstats; +package android.hardware.power.stats; -import android.hardware.powerstats.ChannelInfo; -import android.hardware.powerstats.EnergyConsumerId; -import android.hardware.powerstats.EnergyConsumerResult; -import android.hardware.powerstats.EnergyMeasurement; -import android.hardware.powerstats.PowerEntityInfo; -import android.hardware.powerstats.StateResidencyResult; +import android.hardware.power.stats.ChannelInfo; +import android.hardware.power.stats.EnergyConsumerId; +import android.hardware.power.stats.EnergyConsumerResult; +import android.hardware.power.stats.EnergyMeasurement; +import android.hardware.power.stats.PowerEntityInfo; +import android.hardware.power.stats.StateResidencyResult; @VintfStability interface IPowerStats { diff --git a/power/stats/aidl/android/hardware/powerstats/PowerEntityInfo.aidl b/power/stats/aidl/android/hardware/power/stats/PowerEntityInfo.aidl similarity index 92% rename from power/stats/aidl/android/hardware/powerstats/PowerEntityInfo.aidl rename to power/stats/aidl/android/hardware/power/stats/PowerEntityInfo.aidl index bd09d66ddc..002b34376e 100644 --- a/power/stats/aidl/android/hardware/powerstats/PowerEntityInfo.aidl +++ b/power/stats/aidl/android/hardware/power/stats/PowerEntityInfo.aidl @@ -14,9 +14,9 @@ * limitations under the License. */ -package android.hardware.powerstats; +package android.hardware.power.stats; -import android.hardware.powerstats.StateInfo; +import android.hardware.power.stats.StateInfo; @VintfStability parcelable PowerEntityInfo { diff --git a/power/stats/aidl/android/hardware/powerstats/StateInfo.aidl b/power/stats/aidl/android/hardware/power/stats/StateInfo.aidl similarity index 96% rename from power/stats/aidl/android/hardware/powerstats/StateInfo.aidl rename to power/stats/aidl/android/hardware/power/stats/StateInfo.aidl index 5035f7caea..5703f1e9bd 100644 --- a/power/stats/aidl/android/hardware/powerstats/StateInfo.aidl +++ b/power/stats/aidl/android/hardware/power/stats/StateInfo.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.powerstats; +package android.hardware.power.stats; @VintfStability parcelable StateInfo { diff --git a/power/stats/aidl/android/hardware/powerstats/StateResidency.aidl b/power/stats/aidl/android/hardware/power/stats/StateResidency.aidl similarity index 96% rename from power/stats/aidl/android/hardware/powerstats/StateResidency.aidl rename to power/stats/aidl/android/hardware/power/stats/StateResidency.aidl index 2a8f541f50..a85ca33b51 100644 --- a/power/stats/aidl/android/hardware/powerstats/StateResidency.aidl +++ b/power/stats/aidl/android/hardware/power/stats/StateResidency.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.powerstats; +package android.hardware.power.stats; /** * Contains residency data for a single state diff --git a/power/stats/aidl/android/hardware/powerstats/StateResidencyResult.aidl b/power/stats/aidl/android/hardware/power/stats/StateResidencyResult.aidl similarity index 90% rename from power/stats/aidl/android/hardware/powerstats/StateResidencyResult.aidl rename to power/stats/aidl/android/hardware/power/stats/StateResidencyResult.aidl index b3a9f03d47..3356405a0a 100644 --- a/power/stats/aidl/android/hardware/powerstats/StateResidencyResult.aidl +++ b/power/stats/aidl/android/hardware/power/stats/StateResidencyResult.aidl @@ -14,9 +14,9 @@ * limitations under the License. */ -package android.hardware.powerstats; +package android.hardware.power.stats; -import android.hardware.powerstats.StateResidency; +import android.hardware.power.stats.StateResidency; @VintfStability parcelable StateResidencyResult { diff --git a/power/stats/aidl/default/Android.bp b/power/stats/aidl/default/Android.bp index caecd88ce9..40b9447b70 100644 --- a/power/stats/aidl/default/Android.bp +++ b/power/stats/aidl/default/Android.bp @@ -13,15 +13,15 @@ // limitations under the License. cc_binary { - name: "android.hardware.powerstats-service.example", + name: "android.hardware.power.stats-service.example", relative_install_path: "hw", - init_rc: ["powerstats-default.rc"], - vintf_fragments: ["powerstats-default.xml"], + init_rc: ["power.stats-default.rc"], + vintf_fragments: ["power.stats-default.xml"], vendor: true, shared_libs: [ "libbase", "libbinder_ndk", - "android.hardware.powerstats-ndk_platform", + "android.hardware.power.stats-ndk_platform", ], srcs: [ "main.cpp", diff --git a/power/stats/aidl/default/PowerStats.cpp b/power/stats/aidl/default/PowerStats.cpp index d1c97db312..367ee95201 100644 --- a/power/stats/aidl/default/PowerStats.cpp +++ b/power/stats/aidl/default/PowerStats.cpp @@ -21,7 +21,8 @@ namespace aidl { namespace android { namespace hardware { -namespace powerstats { +namespace power { +namespace stats { ndk::ScopedAStatus PowerStats::getPowerEntityInfo(std::vector* _aidl_return) { (void)_aidl_return; @@ -60,7 +61,8 @@ ndk::ScopedAStatus PowerStats::readEnergyMeters(const std::vector& in_c return ndk::ScopedAStatus::ok(); } -} // namespace powerstats +} // namespace stats +} // namespace power } // namespace hardware } // namespace android } // namespace aidl diff --git a/power/stats/aidl/default/PowerStats.h b/power/stats/aidl/default/PowerStats.h index 6d2d460001..76ab2cbd95 100644 --- a/power/stats/aidl/default/PowerStats.h +++ b/power/stats/aidl/default/PowerStats.h @@ -16,17 +16,18 @@ #pragma once -#include +#include namespace aidl { namespace android { namespace hardware { -namespace powerstats { +namespace power { +namespace stats { class PowerStats : public BnPowerStats { public: PowerStats() = default; - // Methods from aidl::android::hardware::powerstats::IPowerStats + // Methods from aidl::android::hardware::power::stats::IPowerStats ndk::ScopedAStatus getPowerEntityInfo(std::vector* _aidl_return) override; ndk::ScopedAStatus getStateResidency(const std::vector& in_powerEntityIds, std::vector* _aidl_return) override; @@ -38,7 +39,8 @@ class PowerStats : public BnPowerStats { std::vector* _aidl_return) override; }; -} // namespace powerstats +} // namespace stats +} // namespace power } // namespace hardware } // namespace android } // namespace aidl diff --git a/power/stats/aidl/default/main.cpp b/power/stats/aidl/default/main.cpp index 1496805528..0469b4c21d 100644 --- a/power/stats/aidl/default/main.cpp +++ b/power/stats/aidl/default/main.cpp @@ -20,7 +20,7 @@ #include #include -using aidl::android::hardware::powerstats::PowerStats; +using aidl::android::hardware::power::stats::PowerStats; int main() { ABinderProcess_setThreadPoolMaxThreadCount(0); diff --git a/power/stats/aidl/default/power.stats-default.rc b/power/stats/aidl/default/power.stats-default.rc new file mode 100644 index 0000000000..6ff6754bf9 --- /dev/null +++ b/power/stats/aidl/default/power.stats-default.rc @@ -0,0 +1,4 @@ +service vendor.power.stats-default /vendor/bin/hw/android.hardware.power.stats-service.example + class hal + user system + group system diff --git a/power/stats/aidl/default/powerstats-default.xml b/power/stats/aidl/default/power.stats-default.xml similarity index 72% rename from power/stats/aidl/default/powerstats-default.xml rename to power/stats/aidl/default/power.stats-default.xml index e07513d8fa..3b1a2161ca 100644 --- a/power/stats/aidl/default/powerstats-default.xml +++ b/power/stats/aidl/default/power.stats-default.xml @@ -1,6 +1,6 @@ - android.hardware.powerstats + android.hardware.power.stats IPowerStats/default diff --git a/power/stats/aidl/default/powerstats-default.rc b/power/stats/aidl/default/powerstats-default.rc deleted file mode 100644 index 9b04be374d..0000000000 --- a/power/stats/aidl/default/powerstats-default.rc +++ /dev/null @@ -1,4 +0,0 @@ -service vendor.powerstats-default /vendor/bin/hw/android.hardware.powerstats-service.example - class hal - user system - group system diff --git a/power/stats/aidl/vts/Android.bp b/power/stats/aidl/vts/Android.bp index c61022ec0a..930709f160 100644 --- a/power/stats/aidl/vts/Android.bp +++ b/power/stats/aidl/vts/Android.bp @@ -23,7 +23,7 @@ cc_test { "libbinder_ndk", ], static_libs: [ - "android.hardware.powerstats-ndk_platform", + "android.hardware.power.stats-ndk_platform", ], test_suites: [ "general-tests", diff --git a/power/stats/aidl/vts/VtsHalPowerStatsTargetTest.cpp b/power/stats/aidl/vts/VtsHalPowerStatsTargetTest.cpp index e71e4953f3..1d3082191a 100644 --- a/power/stats/aidl/vts/VtsHalPowerStatsTargetTest.cpp +++ b/power/stats/aidl/vts/VtsHalPowerStatsTargetTest.cpp @@ -16,16 +16,16 @@ #include #include -#include +#include #include #include #include -using aidl::android::hardware::powerstats::ChannelInfo; -using aidl::android::hardware::powerstats::EnergyMeasurement; -using aidl::android::hardware::powerstats::IPowerStats; -using aidl::android::hardware::powerstats::PowerEntityInfo; -using aidl::android::hardware::powerstats::StateResidencyResult; +using aidl::android::hardware::power::stats::ChannelInfo; +using aidl::android::hardware::power::stats::EnergyMeasurement; +using aidl::android::hardware::power::stats::IPowerStats; +using aidl::android::hardware::power::stats::PowerEntityInfo; +using aidl::android::hardware::power::stats::StateResidencyResult; using ndk::SpAIBinder; -- GitLab From e8a5737720c1c14189629fa72463907d685e5ba1 Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Wed, 7 Oct 2020 12:24:48 -0700 Subject: [PATCH 197/790] Support Link/Unlink Cicam to Frontend in Tuner HAL 1.1 The previous linkCicam API does not support local transport stream id return. Added the support in this CL. Also added an unlink API to unlink the cicam when needed. INVALID_LTS_ID will be used on failed operation of linkCicam and in Tuner java framework as the default value Test: make android.hardware.tv.tuner@1.1-service Bug: 158818696 Change-Id: Ief9c5097c667ce41a534b0d1d759869acd79ca7f --- tv/tuner/1.1/IFrontend.hal | 13 ++++++++++++- tv/tuner/1.1/default/Frontend.cpp | 11 ++++++++++- tv/tuner/1.1/default/Frontend.h | 4 +++- tv/tuner/1.1/types.hal | 5 +++++ 4 files changed, 30 insertions(+), 3 deletions(-) diff --git a/tv/tuner/1.1/IFrontend.hal b/tv/tuner/1.1/IFrontend.hal index e9c5e190f5..63f06558d5 100644 --- a/tv/tuner/1.1/IFrontend.hal +++ b/tv/tuner/1.1/IFrontend.hal @@ -77,11 +77,22 @@ interface IFrontend extends @1.0::IFrontend { * directly from the frontend. * * @param ciCamId specify CI-CAM Id to link. + * @return ltsId Local Transport Stream Id. * @return result Result status of the operation. * SUCCESS if successful, * UNKNOWN_ERROR if failed for other reasons. */ - linkCiCam(uint32_t ciCamId) generates (Result result); + linkCiCam(uint32_t ciCamId) generates (Result result, uint32_t ltsId); + + /** + * Unlink Conditional Access Modules (CAM) to Frontend. + * + * @param ciCamId specify CI-CAM Id to unlink. + * @return result Result status of the operation. + * SUCCESS if successful, + * UNKNOWN_ERROR if failed for other reasons. + */ + unlinkCiCam(uint32_t ciCamId) generates (Result result); /** * Get the v1_1 extended statuses of the frontend. diff --git a/tv/tuner/1.1/default/Frontend.cpp b/tv/tuner/1.1/default/Frontend.cpp index 971e335700..86be9ad635 100644 --- a/tv/tuner/1.1/default/Frontend.cpp +++ b/tv/tuner/1.1/default/Frontend.cpp @@ -361,10 +361,19 @@ Return Frontend::setLnb(uint32_t /* lnb */) { return Result::SUCCESS; } -Return Frontend::linkCiCam(uint32_t ciCamId) { +Return Frontend::linkCiCam(uint32_t ciCamId, linkCiCam_cb _hidl_cb) { ALOGV("%s", __FUNCTION__); mCiCamId = ciCamId; + _hidl_cb(Result::SUCCESS, 0 /*ltsId*/); + + return Void(); +} + +Return Frontend::unlinkCiCam(uint32_t /*ciCamId*/) { + ALOGV("%s", __FUNCTION__); + + mCiCamId = -1; return Result::SUCCESS; } diff --git a/tv/tuner/1.1/default/Frontend.h b/tv/tuner/1.1/default/Frontend.h index 4c357189e4..a28fb6483b 100644 --- a/tv/tuner/1.1/default/Frontend.h +++ b/tv/tuner/1.1/default/Frontend.h @@ -66,7 +66,9 @@ class Frontend : public V1_1::IFrontend { virtual Return setLnb(uint32_t lnb) override; - virtual Return linkCiCam(uint32_t ciCamId) override; + virtual Return linkCiCam(uint32_t ciCamId, linkCiCam_cb _hidl_cb) override; + + virtual Return unlinkCiCam(uint32_t ciCamId) override; FrontendType getFrontendType(); diff --git a/tv/tuner/1.1/types.hal b/tv/tuner/1.1/types.hal index b20e6252f0..057351f05a 100644 --- a/tv/tuner/1.1/types.hal +++ b/tv/tuner/1.1/types.hal @@ -58,6 +58,11 @@ enum Constant : @1.0::Constant { * be used to reset the configured ip context id. */ INVALID_IP_FILTER_CONTEXT_ID = 0xFFFFFFFF, + /** + * An invalid local transport stream id used as the return value on a failed operation of + * IFrontend.linkCiCam. + */ + INVALID_LTS_ID = 0xFFFFFFFF, }; @export -- GitLab From 08596b462904e0f23e31c5c84535a05c1c8f61a5 Mon Sep 17 00:00:00 2001 From: Arthur Ishiguro Date: Wed, 30 Sep 2020 10:48:36 -0700 Subject: [PATCH 198/790] Adds Context Hub HAL v1.2 Add support for extended setting changes. Bug: 166845383 Test: Compile Change-Id: I912f01447e4d0e2f345620fa1b5599f50cc9a4f8 --- contexthub/1.2/Android.bp | 16 ++++++++++++++++ contexthub/1.2/IContexthub.hal | 31 +++++++++++++++++++++++++++++++ contexthub/1.2/types.hal | 34 ++++++++++++++++++++++++++++++++++ current.txt | 2 ++ 4 files changed, 83 insertions(+) create mode 100644 contexthub/1.2/Android.bp create mode 100644 contexthub/1.2/IContexthub.hal create mode 100644 contexthub/1.2/types.hal diff --git a/contexthub/1.2/Android.bp b/contexthub/1.2/Android.bp new file mode 100644 index 0000000000..e81948234a --- /dev/null +++ b/contexthub/1.2/Android.bp @@ -0,0 +1,16 @@ +// This file is autogenerated by hidl-gen -Landroidbp. + +hidl_interface { + name: "android.hardware.contexthub@1.2", + root: "android.hardware", + srcs: [ + "types.hal", + "IContexthub.hal", + ], + interfaces: [ + "android.hardware.contexthub@1.0", + "android.hardware.contexthub@1.1", + "android.hidl.base@1.0", + ], + gen_java: true, +} diff --git a/contexthub/1.2/IContexthub.hal b/contexthub/1.2/IContexthub.hal new file mode 100644 index 0000000000..819fc1d6e1 --- /dev/null +++ b/contexthub/1.2/IContexthub.hal @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.contexthub@1.2; + +import @1.1::IContexthub; +import @1.1::SettingValue; + +interface IContexthub extends @1.1::IContexthub { + /** + * Notification sent by the framework to indicate that the user + * has changed a setting. + * + * @param setting User setting that has been modified. + * @param newValue The update value of the user setting. + */ + onSettingChanged_1_2(Setting setting, @1.1::SettingValue newValue); +}; diff --git a/contexthub/1.2/types.hal b/contexthub/1.2/types.hal new file mode 100644 index 0000000000..38f9f7af55 --- /dev/null +++ b/contexthub/1.2/types.hal @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.contexthub@1.2; + +import @1.1::Setting; + +/** + * Used to indicate the type of user setting that has changed. + */ +enum Setting : @1.1::Setting { + /** + * Indicates that the WiFi capabilities can be used in CHRE. This setting + * follows the overall availability of WiFi-related functionality within + * the Android framework, for example if WiFi is disabled for connectivity + * purposes but is enabled for location purposes (scanning), then + * WIFI_AVAILABLE is enabled. + */ + WIFI_AVAILABLE, + AIRPLANE_MODE, +}; diff --git a/current.txt b/current.txt index c9a923ec74..9f03b7f3fc 100644 --- a/current.txt +++ b/current.txt @@ -778,6 +778,8 @@ cd84ab19c590e0e73dd2307b591a3093ee18147ef95e6d5418644463a6620076 android.hardwar # HALs released in Android S # NOTE: waiting to freeze HALs until later in the release # NOTE: new HALs are recommended to be in AIDL +6e64b33f1b720b66b0deb5e08dee37a99deaa94e2e9ebf7806703cabab56e21d android.hardware.contexthub@1.2::IContexthub +3fb83f4539cab2c7bf9fdbecf7265d1c1dd6e8de9694046fe512b493c127ccea android.hardware.contexthub@1.2::types 57d183b10b13ec0a8e542c0b3d61991ae541c60e85dbbc5499bb21dfd068cbb8 android.hardware.wifi.supplicant@1.4::types 17818b6b1952a75e4364ae82c534b9d2f5c0a9765a56256b16faa5a5cf45d3a8 android.hardware.wifi.supplicant@1.4::ISupplicant 8342b5f6ec8f48ad2b741128aede010995d0b5709257b7ec09bb469b4f61ef1a android.hardware.wifi.supplicant@1.4::ISupplicantStaIface -- GitLab From 46c2bd043926693a9dee2514e5079791127d33d4 Mon Sep 17 00:00:00 2001 From: Arthur Ishiguro Date: Tue, 6 Oct 2020 11:05:17 -0700 Subject: [PATCH 199/790] Adds default (mock) Context Hub HAL 1.2 impl Also refactors common code. Bug: 166845383 Test: Compile only (VTS test coming up in future CL) Change-Id: Iae6cf09e2fffb854af61c29e6004ceb062a892b3 --- contexthub/1.1/default/Android.bp | 3 + contexthub/1.1/default/Contexthub.cpp | 75 ----------- contexthub/1.1/default/Contexthub.h | 25 +--- contexthub/1.2/default/Android.bp | 46 +++++++ contexthub/1.2/default/Contexthub.cpp | 38 ++++++ contexthub/1.2/default/Contexthub.h | 45 +++++++ contexthub/1.2/default/OWNERS | 3 + ...android.hardware.contexthub@1.2-service.rc | 7 ++ .../android.hardware.contexthub@1.2.xml | 11 ++ contexthub/1.2/default/service.cpp | 42 +++++++ contexthub/common/default/1.X/Android.bp | 28 +++++ contexthub/common/default/1.X/ContextHub.h | 117 ++++++++++++++++++ 12 files changed, 344 insertions(+), 96 deletions(-) create mode 100644 contexthub/1.2/default/Android.bp create mode 100644 contexthub/1.2/default/Contexthub.cpp create mode 100644 contexthub/1.2/default/Contexthub.h create mode 100644 contexthub/1.2/default/OWNERS create mode 100644 contexthub/1.2/default/android.hardware.contexthub@1.2-service.rc create mode 100644 contexthub/1.2/default/android.hardware.contexthub@1.2.xml create mode 100644 contexthub/1.2/default/service.cpp create mode 100644 contexthub/common/default/1.X/Android.bp create mode 100644 contexthub/common/default/1.X/ContextHub.h diff --git a/contexthub/1.1/default/Android.bp b/contexthub/1.1/default/Android.bp index 86858c0377..5c9ec4e2c7 100644 --- a/contexthub/1.1/default/Android.bp +++ b/contexthub/1.1/default/Android.bp @@ -38,5 +38,8 @@ cc_binary { "liblog", "libutils", ], + header_libs: [ + "android.hardware.contexthub@1.X-common-impl", + ], vintf_fragments: ["android.hardware.contexthub@1.1.xml"], } diff --git a/contexthub/1.1/default/Contexthub.cpp b/contexthub/1.1/default/Contexthub.cpp index 19cc2628d7..e7fde84058 100644 --- a/contexthub/1.1/default/Contexthub.cpp +++ b/contexthub/1.1/default/Contexthub.cpp @@ -23,81 +23,6 @@ namespace contexthub { namespace V1_1 { namespace implementation { -using ::android::hardware::contexthub::V1_0::ContextHub; -using ::android::hardware::contexthub::V1_0::HubAppInfo; -using ::android::hardware::contexthub::V1_0::Result; - -namespace { - -constexpr uint32_t kMockHubId = 0; - -} // anonymous namespace - -Return Contexthub::getHubs(getHubs_cb _hidl_cb) { - ContextHub hub = {}; - hub.name = "Mock Context Hub"; - hub.vendor = "AOSP"; - hub.toolchain = "n/a"; - hub.platformVersion = 1; - hub.toolchainVersion = 1; - hub.hubId = kMockHubId; - hub.peakMips = 1; - hub.peakPowerDrawMw = 1; - hub.maxSupportedMsgLen = 4096; - hub.chrePlatformId = UINT64_C(0x476f6f6754000000); - hub.chreApiMajorVersion = 1; - hub.chreApiMinorVersion = 4; - - // Report a single mock hub - std::vector hubs; - hubs.push_back(hub); - - _hidl_cb(hubs); - return Void(); -} - -Return Contexthub::registerCallback(uint32_t hubId, const sp& cb) { - if (hubId == kMockHubId) { - mCallback = cb; - return Result::OK; - } - return Result::BAD_PARAMS; -} - -// We don't expose any nanoapps, therefore all nanoapp-related API calls return with BAD_PARAMS -Return Contexthub::sendMessageToHub(uint32_t /*hubId*/, const ContextHubMsg& /*msg*/) { - return Result::BAD_PARAMS; -} - -Return Contexthub::loadNanoApp(uint32_t /*hubId*/, const NanoAppBinary& /*appBinary*/, - uint32_t /*transactionId*/) { - return Result::BAD_PARAMS; -} - -Return Contexthub::unloadNanoApp(uint32_t /*hubId*/, uint64_t /*appId*/, - uint32_t /*transactionId*/) { - return Result::BAD_PARAMS; -} - -Return Contexthub::enableNanoApp(uint32_t /*hubId*/, uint64_t /*appId*/, - uint32_t /*transactionId*/) { - return Result::BAD_PARAMS; -} - -Return Contexthub::disableNanoApp(uint32_t /*hubId*/, uint64_t /*appId*/, - uint32_t /*transactionId*/) { - return Result::BAD_PARAMS; -} - -Return Contexthub::queryApps(uint32_t hubId) { - if (hubId == kMockHubId && mCallback != nullptr) { - std::vector nanoapps; - mCallback->handleAppsInfo(nanoapps); - return Result::OK; - } - return Result::BAD_PARAMS; -} - Return Contexthub::onSettingChanged(Setting /*setting*/, SettingValue /*newValue*/) { return Void(); } diff --git a/contexthub/1.1/default/Contexthub.h b/contexthub/1.1/default/Contexthub.h index 0da61d1464..1468fcfc0e 100644 --- a/contexthub/1.1/default/Contexthub.h +++ b/contexthub/1.1/default/Contexthub.h @@ -15,6 +15,8 @@ */ #pragma once +#include "ContextHub.h" + #include namespace android { @@ -23,30 +25,11 @@ namespace contexthub { namespace V1_1 { namespace implementation { -class Contexthub : public V1_1::IContexthub { - using ContextHubMsg = ::android::hardware::contexthub::V1_0::ContextHubMsg; - using IContexthubCallback = ::android::hardware::contexthub::V1_0::IContexthubCallback; - using NanoAppBinary = ::android::hardware::contexthub::V1_0::NanoAppBinary; - using Result = ::android::hardware::contexthub::V1_0::Result; - +class Contexthub + : public ::android::hardware::contexthub::V1_X::implementation::ContextHub { public: - // Methods from V1_0::IContexthub - Return getHubs(getHubs_cb _hidl_cb) override; - Return registerCallback(uint32_t hubId, - const ::android::sp& cb) override; - Return sendMessageToHub(uint32_t hubId, const ContextHubMsg& msg) override; - Return loadNanoApp(uint32_t hubId, const NanoAppBinary& appBinary, - uint32_t transactionId) override; - Return unloadNanoApp(uint32_t hubId, uint64_t appId, uint32_t transactionId) override; - Return enableNanoApp(uint32_t hubId, uint64_t appId, uint32_t transactionId) override; - Return disableNanoApp(uint32_t hubId, uint64_t appId, uint32_t transactionId) override; - Return queryApps(uint32_t hubId) override; - // Methods from V1_1::IContexthub Return onSettingChanged(Setting setting, SettingValue newValue) override; - - private: - sp mCallback; }; } // namespace implementation diff --git a/contexthub/1.2/default/Android.bp b/contexthub/1.2/default/Android.bp new file mode 100644 index 0000000000..49b54fc007 --- /dev/null +++ b/contexthub/1.2/default/Android.bp @@ -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. + */ + +cc_binary { + name: "android.hardware.contexthub@1.2-service.mock", + defaults: ["hidl_defaults"], + vendor: true, + relative_install_path: "hw", + init_rc: ["android.hardware.contexthub@1.2-service.rc"], + srcs: [ + "Contexthub.cpp", + "service.cpp", + ], + cflags: [ + "-Wall", + "-Werror", + ], + shared_libs: [ + "android.hardware.contexthub@1.0", + "android.hardware.contexthub@1.1", + "android.hardware.contexthub@1.2", + "libbase", + "libcutils", + "libhardware", + "libhidlbase", + "liblog", + "libutils", + ], + header_libs: [ + "android.hardware.contexthub@1.X-common-impl", + ], + vintf_fragments: ["android.hardware.contexthub@1.2.xml"], +} diff --git a/contexthub/1.2/default/Contexthub.cpp b/contexthub/1.2/default/Contexthub.cpp new file mode 100644 index 0000000000..d7ac7bf30e --- /dev/null +++ b/contexthub/1.2/default/Contexthub.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "Contexthub.h" + +#include + +namespace android { +namespace hardware { +namespace contexthub { +namespace V1_2 { +namespace implementation { + +Return Contexthub::onSettingChanged(SettingV1_1 /*setting*/, SettingValue /*newValue*/) { + return Void(); +} + +Return Contexthub::onSettingChanged_1_2(Setting /*setting*/, SettingValue /*newValue*/) { + return Void(); +} + +} // namespace implementation +} // namespace V1_2 +} // namespace contexthub +} // namespace hardware +} // namespace android diff --git a/contexthub/1.2/default/Contexthub.h b/contexthub/1.2/default/Contexthub.h new file mode 100644 index 0000000000..d2f8d69afc --- /dev/null +++ b/contexthub/1.2/default/Contexthub.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once + +#include "ContextHub.h" + +#include + +namespace android { +namespace hardware { +namespace contexthub { +namespace V1_2 { +namespace implementation { + +class Contexthub + : public ::android::hardware::contexthub::V1_X::implementation::ContextHub { + using SettingValue = ::android::hardware::contexthub::V1_1::SettingValue; + using SettingV1_1 = ::android::hardware::contexthub::V1_1::Setting; + + public: + // Methods from V1_1::IContexthub + Return onSettingChanged(SettingV1_1 setting, SettingValue newValue) override; + + // Methods from V1_2::IContexthub + Return onSettingChanged_1_2(Setting setting, SettingValue newValue) override; +}; + +} // namespace implementation +} // namespace V1_2 +} // namespace contexthub +} // namespace hardware +} // namespace android diff --git a/contexthub/1.2/default/OWNERS b/contexthub/1.2/default/OWNERS new file mode 100644 index 0000000000..90c233030e --- /dev/null +++ b/contexthub/1.2/default/OWNERS @@ -0,0 +1,3 @@ +arthuri@google.com +bduddie@google.com +stange@google.com diff --git a/contexthub/1.2/default/android.hardware.contexthub@1.2-service.rc b/contexthub/1.2/default/android.hardware.contexthub@1.2-service.rc new file mode 100644 index 0000000000..936222a607 --- /dev/null +++ b/contexthub/1.2/default/android.hardware.contexthub@1.2-service.rc @@ -0,0 +1,7 @@ +service vendor.contexthub-hal-1.2-mock /vendor/bin/hw/android.hardware.contexthub@1.2-service.mock + interface android.hardware.contexthub@1.0::IContexthub default + interface android.hardware.contexthub@1.1::IContexthub default + interface android.hardware.contexthub@1.2::IContexthub default + class hal + user context_hub + group context_hub diff --git a/contexthub/1.2/default/android.hardware.contexthub@1.2.xml b/contexthub/1.2/default/android.hardware.contexthub@1.2.xml new file mode 100644 index 0000000000..ec6c684994 --- /dev/null +++ b/contexthub/1.2/default/android.hardware.contexthub@1.2.xml @@ -0,0 +1,11 @@ + + + android.hardware.contexthub + hwbinder + 1.2 + + IContexthub + default + + + diff --git a/contexthub/1.2/default/service.cpp b/contexthub/1.2/default/service.cpp new file mode 100644 index 0000000000..41cb753159 --- /dev/null +++ b/contexthub/1.2/default/service.cpp @@ -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. + */ + +#define LOG_TAG "android.hardware.contexthub@1.2-service" + +#include +#include +#include +#include +#include "Contexthub.h" + +using ::android::hardware::configureRpcThreadpool; +using ::android::hardware::joinRpcThreadpool; +using ::android::hardware::contexthub::V1_2::IContexthub; +using ::android::hardware::contexthub::V1_2::implementation::Contexthub; + +int main() { + configureRpcThreadpool(1, true /* callerWillJoin */); + + ::android::sp contexthub = new Contexthub(); + if (contexthub->registerAsService() != ::android::OK) { + ALOGE("Failed to register Contexthub HAL instance"); + return 1; + } + + joinRpcThreadpool(); + ALOGE("Service exited"); + return 1; +} diff --git a/contexthub/common/default/1.X/Android.bp b/contexthub/common/default/1.X/Android.bp new file mode 100644 index 0000000000..691a1b7c9d --- /dev/null +++ b/contexthub/common/default/1.X/Android.bp @@ -0,0 +1,28 @@ +// +// Copyright (C) 2020 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +cc_library_headers { + name: "android.hardware.contexthub@1.X-common-impl", + vendor_available: true, + defaults: ["hidl_defaults"], + export_include_dirs: ["."], + shared_libs: [ + "android.hardware.contexthub@1.0", + "libbinder", + "libcutils", + "libhidlbase", + "libutils", + ], +} diff --git a/contexthub/common/default/1.X/ContextHub.h b/contexthub/common/default/1.X/ContextHub.h new file mode 100644 index 0000000000..73d06319dd --- /dev/null +++ b/contexthub/common/default/1.X/ContextHub.h @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_CONTEXTHUB_V1_X_CONTEXTHUB_H +#define ANDROID_HARDWARE_CONTEXTHUB_V1_X_CONTEXTHUB_H + +#include +#include +#include + +namespace android { +namespace hardware { +namespace contexthub { +namespace V1_X { +namespace implementation { + +template +struct ContextHub : public IContextHubInterface { + using ContextHubMsg = ::android::hardware::contexthub::V1_0::ContextHubMsg; + using HubAppInfo = ::android::hardware::contexthub::V1_0::HubAppInfo; + using IContexthubCallback = ::android::hardware::contexthub::V1_0::IContexthubCallback; + using NanoAppBinary = ::android::hardware::contexthub::V1_0::NanoAppBinary; + using Result = ::android::hardware::contexthub::V1_0::Result; + using getHubs_cb = ::android::hardware::contexthub::V1_0::IContexthub::getHubs_cb; + + public: + Return getHubs(getHubs_cb _hidl_cb) override { + ::android::hardware::contexthub::V1_0::ContextHub hub = {}; + hub.name = "Mock Context Hub"; + hub.vendor = "AOSP"; + hub.toolchain = "n/a"; + hub.platformVersion = 1; + hub.toolchainVersion = 1; + hub.hubId = kMockHubId; + hub.peakMips = 1; + hub.peakPowerDrawMw = 1; + hub.maxSupportedMsgLen = 4096; + hub.chrePlatformId = UINT64_C(0x476f6f6754000000); + hub.chreApiMajorVersion = 1; + hub.chreApiMinorVersion = 4; + + // Report a single mock hub + std::vector<::android::hardware::contexthub::V1_0::ContextHub> hubs; + hubs.push_back(hub); + + _hidl_cb(hubs); + return Void(); + } + + Return registerCallback(uint32_t hubId, const sp& cb) override { + if (hubId == kMockHubId) { + mCallback = cb; + return Result::OK; + } + return Result::BAD_PARAMS; + } + + // We don't expose any nanoapps, therefore all nanoapp-related API calls return with BAD_PARAMS + Return sendMessageToHub(uint32_t /*hubId*/, const ContextHubMsg& /*msg*/) override { + return Result::BAD_PARAMS; + } + + Return loadNanoApp(uint32_t /*hubId*/, const NanoAppBinary& /*appBinary*/, + uint32_t /*transactionId*/) override { + return Result::BAD_PARAMS; + } + + Return unloadNanoApp(uint32_t /*hubId*/, uint64_t /*appId*/, + uint32_t /*transactionId*/) override { + return Result::BAD_PARAMS; + } + + Return enableNanoApp(uint32_t /*hubId*/, uint64_t /*appId*/, + uint32_t /*transactionId*/) override { + return Result::BAD_PARAMS; + } + + Return disableNanoApp(uint32_t /*hubId*/, uint64_t /*appId*/, + uint32_t /*transactionId*/) override { + return Result::BAD_PARAMS; + } + + Return queryApps(uint32_t hubId) override { + if (hubId == kMockHubId && mCallback != nullptr) { + std::vector nanoapps; + mCallback->handleAppsInfo(nanoapps); + return Result::OK; + } + return Result::BAD_PARAMS; + } + + private: + static constexpr uint32_t kMockHubId = 0; + + sp mCallback; +}; + +} // namespace implementation +} // namespace V1_X +} // namespace contexthub +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_CONTEXTHUB_V1_X_CONTEXTHUB_H -- GitLab From d06c45e008531aa3f2115260b3789bceab292655 Mon Sep 17 00:00:00 2001 From: Arthur Ishiguro Date: Tue, 6 Oct 2020 13:24:29 -0700 Subject: [PATCH 200/790] Add VTS tests for Context Hub HAL 1.2 Also updates the compatibility matrix. Bug: 166845383 Test: Run test on device with HAL 1.2 implemented, verify pass Change-Id: Iac53e755cfa38fbd1322421279475de76b4bb572 --- .../compatibility_matrix.current.xml | 2 +- contexthub/1.2/vts/functional/Android.bp | 31 +++++++++ contexthub/1.2/vts/functional/OWNERS | 8 +++ .../VtsHalContexthubV1_2TargetTest.cpp | 69 +++++++++++++++++++ 4 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 contexthub/1.2/vts/functional/Android.bp create mode 100644 contexthub/1.2/vts/functional/OWNERS create mode 100644 contexthub/1.2/vts/functional/VtsHalContexthubV1_2TargetTest.cpp diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index 0535955f50..b2a86805b9 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -177,7 +177,7 @@ android.hardware.contexthub - 1.0-1 + 1.0-2 IContexthub default diff --git a/contexthub/1.2/vts/functional/Android.bp b/contexthub/1.2/vts/functional/Android.bp new file mode 100644 index 0000000000..6e425be258 --- /dev/null +++ b/contexthub/1.2/vts/functional/Android.bp @@ -0,0 +1,31 @@ +// +// 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. +// + +cc_test { + name: "VtsHalContexthubV1_2TargetTest", + defaults: ["VtsHalTargetTestDefaults"], + srcs: ["VtsHalContexthubV1_2TargetTest.cpp"], + static_libs: [ + "android.hardware.contexthub@1.0", + "android.hardware.contexthub@1.1", + "android.hardware.contexthub@1.2", + "VtsHalContexthubUtils", + ], + test_suites: [ + "general-tests", + "vts", + ], +} diff --git a/contexthub/1.2/vts/functional/OWNERS b/contexthub/1.2/vts/functional/OWNERS new file mode 100644 index 0000000000..161b2f069d --- /dev/null +++ b/contexthub/1.2/vts/functional/OWNERS @@ -0,0 +1,8 @@ +#Context Hub team +arthuri@google.com +bduddie@google.com +stange@google.com + +#VTS team +dshi@google.com +trong@google.com diff --git a/contexthub/1.2/vts/functional/VtsHalContexthubV1_2TargetTest.cpp b/contexthub/1.2/vts/functional/VtsHalContexthubV1_2TargetTest.cpp new file mode 100644 index 0000000000..77883c2423 --- /dev/null +++ b/contexthub/1.2/vts/functional/VtsHalContexthubV1_2TargetTest.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "contexthub_hidl_hal_test" + +#include "ContexthubCallbackBase.h" +#include "ContexthubHidlTestBase.h" +#include "VtsHalContexthubUtils.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +using ::android::hardware::contexthub::V1_1::SettingValue; +using ::android::hardware::contexthub::V1_2::IContexthub; +using ::android::hardware::contexthub::V1_2::Setting; +using ::android::hardware::contexthub::vts_utils::ContexthubCallbackBase; +using ::android::hardware::contexthub::vts_utils::ContexthubHidlTestBase; +using ::android::hardware::contexthub::vts_utils::getHalAndHubIdList; + +namespace { + +const std::vector> kTestParameters = + getHalAndHubIdList(); + +class ContexthubHidlTest : public ContexthubHidlTestBase {}; + +// In VTS, we only test that sending the values doesn't cause things to blow up - other test +// suites verify the expected E2E behavior in CHRE +TEST_P(ContexthubHidlTest, TestOnWifiSettingChanged) { + ASSERT_OK(registerCallback(new ContexthubCallbackBase())); + hubApi->onSettingChanged_1_2(Setting::WIFI_AVAILABLE, SettingValue::DISABLED); + hubApi->onSettingChanged_1_2(Setting::WIFI_AVAILABLE, SettingValue::ENABLED); + ASSERT_OK(registerCallback(nullptr)); +} + +TEST_P(ContexthubHidlTest, TestOnAirplaneModeSettingChanged) { + ASSERT_OK(registerCallback(new ContexthubCallbackBase())); + hubApi->onSettingChanged_1_2(Setting::AIRPLANE_MODE, SettingValue::DISABLED); + hubApi->onSettingChanged_1_2(Setting::AIRPLANE_MODE, SettingValue::ENABLED); + ASSERT_OK(registerCallback(nullptr)); +} + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ContexthubHidlTest); +INSTANTIATE_TEST_SUITE_P(HubIdSpecificTests, ContexthubHidlTest, testing::ValuesIn(kTestParameters), + android::hardware::PrintInstanceTupleNameToString<>); + +} // anonymous namespace -- GitLab From d459e4eecde81e8b2fc21d16fd6db019f8d22c50 Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Wed, 7 Oct 2020 11:28:31 +0800 Subject: [PATCH 201/790] wifi: check all possible returning codes for connect/cancelConnect Before R, those two calls are not going to work with fake values. After enabling auto-join, it will success always. Bug: 169890122 Test: atest VtsHalWifiSupplicantP2pV1_0TargetTest Change-Id: I7d94e797e140520a5df33bba854d5cb2b015eacf --- .../supplicant_p2p_iface_hidl_test.cpp | 33 ++++++++++++++++--- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_p2p_iface_hidl_test.cpp b/wifi/supplicant/1.0/vts/functional/supplicant_p2p_iface_hidl_test.cpp index e74fd590ab..325f355f4a 100644 --- a/wifi/supplicant/1.0/vts/functional/supplicant_p2p_iface_hidl_test.cpp +++ b/wifi/supplicant/1.0/vts/functional/supplicant_p2p_iface_hidl_test.cpp @@ -282,8 +282,17 @@ TEST_P(SupplicantP2pIfaceHidlTest, Connect) { mac_addr_, ISupplicantP2pIface::WpsProvisionMethod::PBC, kTestConnectPin, false, false, kTestConnectGoIntent, [](const SupplicantStatus& status, const hidl_string& /* pin */) { - // After enabling auto-join, it will succeed always. - EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + /* + * Before R, auto-join is not enabled and it is not going to work + * with fake values. After enabling auto-join, it will succeed + * always. + */ + LOG(INFO) << "ISupplicantP2pIface::connect() ret: " + << toString(status); + if (SupplicantStatusCode::FAILURE_UNKNOWN != status.code && + SupplicantStatusCode::SUCCESS != status.code) { + FAIL(); + } }); } @@ -295,12 +304,26 @@ TEST_P(SupplicantP2pIfaceHidlTest, CancelConnect) { mac_addr_, ISupplicantP2pIface::WpsProvisionMethod::PBC, kTestConnectPin, false, false, kTestConnectGoIntent, [](const SupplicantStatus& status, const hidl_string& /* pin */) { - // After enabling auto-join, it will succeed always. - EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + /* + * Before R, auto-join is not enabled and it is not going to work + * with fake values. After enabling auto-join, it will succeed + * always. + */ + LOG(INFO) << "ISupplicantP2pIface::connect() ret: " + << toString(status); + if (SupplicantStatusCode::FAILURE_UNKNOWN != status.code && + SupplicantStatusCode::SUCCESS != status.code) { + FAIL(); + } }); p2p_iface_->cancelConnect([](const SupplicantStatus& status) { - EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + LOG(INFO) << "ISupplicantP2pIface::cancelConnect() ret: " + << toString(status); + if (SupplicantStatusCode::FAILURE_UNKNOWN != status.code && + SupplicantStatusCode::SUCCESS != status.code) { + FAIL(); + } }); } -- GitLab From 9da19c7cfab19dd49080b33363efdfa60a02fd49 Mon Sep 17 00:00:00 2001 From: Mikhail Naganov Date: Fri, 2 Oct 2020 11:50:15 -0700 Subject: [PATCH 202/790] Convert mask types from uint32_t to enum type This applies to the following types: - audio_gain_mode_t; - audio_flags_mask_t; - audio_channel_representation_t; - audio_channel_mask_t; - audio_devices_t. Enum types are distinct thus proper overloading on the type is possible in C++. Also, assignments to enum types are less prone to errors. Bug: 169889714 Test: basic audio functionality Change-Id: I07e96ae99724f38fe0b40194f4feab7ff68418e7 --- audio/core/all-versions/default/Conversions.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/audio/core/all-versions/default/Conversions.cpp b/audio/core/all-versions/default/Conversions.cpp index eddff556e7..0b6ad80a80 100644 --- a/audio/core/all-versions/default/Conversions.cpp +++ b/audio/core/all-versions/default/Conversions.cpp @@ -31,7 +31,7 @@ std::string deviceAddressToHal(const DeviceAddress& address) { // HAL assumes that the address is NUL-terminated. char halAddress[AUDIO_DEVICE_MAX_ADDRESS_LEN]; memset(halAddress, 0, sizeof(halAddress)); - uint32_t halDevice = static_cast(address.device); + audio_devices_t halDevice = static_cast(address.device); if (getAudioDeviceOutAllA2dpSet().count(halDevice) > 0 || halDevice == AUDIO_DEVICE_IN_BLUETOOTH_A2DP) { snprintf(halAddress, sizeof(halAddress), "%02X:%02X:%02X:%02X:%02X:%02X", -- GitLab From 74c19f576e4ce3138614e91b379ddd98782d644c Mon Sep 17 00:00:00 2001 From: Arthur Ishiguro Date: Thu, 8 Oct 2020 15:11:19 -0700 Subject: [PATCH 203/790] Update ContextHub VTS OWNERS files Bug: 166845383 Test: None Change-Id: If47c3360f47122c07f78934ff90153ff54b14a40 --- contexthub/1.0/vts/functional/OWNERS | 1 - contexthub/1.1/vts/functional/OWNERS | 1 - contexthub/1.2/vts/functional/OWNERS | 1 - 3 files changed, 3 deletions(-) diff --git a/contexthub/1.0/vts/functional/OWNERS b/contexthub/1.0/vts/functional/OWNERS index 161b2f069d..1a33a9e097 100644 --- a/contexthub/1.0/vts/functional/OWNERS +++ b/contexthub/1.0/vts/functional/OWNERS @@ -5,4 +5,3 @@ stange@google.com #VTS team dshi@google.com -trong@google.com diff --git a/contexthub/1.1/vts/functional/OWNERS b/contexthub/1.1/vts/functional/OWNERS index 161b2f069d..1a33a9e097 100644 --- a/contexthub/1.1/vts/functional/OWNERS +++ b/contexthub/1.1/vts/functional/OWNERS @@ -5,4 +5,3 @@ stange@google.com #VTS team dshi@google.com -trong@google.com diff --git a/contexthub/1.2/vts/functional/OWNERS b/contexthub/1.2/vts/functional/OWNERS index 161b2f069d..1a33a9e097 100644 --- a/contexthub/1.2/vts/functional/OWNERS +++ b/contexthub/1.2/vts/functional/OWNERS @@ -5,4 +5,3 @@ stange@google.com #VTS team dshi@google.com -trong@google.com -- GitLab From 3974eacf0839b43d4275e9b6d758aca43417afa0 Mon Sep 17 00:00:00 2001 From: Eric Jeong Date: Thu, 10 Sep 2020 09:26:24 -0700 Subject: [PATCH 204/790] Define VHAL properties for car power policy - POWER_POLICY_REQ: VHAL uses to set a new power policy - POWER_POLICY_GROUP_REQ: VHAL uses to set default power policies per power status transition - CURRENT_POWER_POLICY: carpowerpolicyd updates to tell VHAL the current power policy Bug: 162599168 Test: build okay Change-Id: Ife58cec19bc099129d2cc49bac8821455d6b4194 --- .../default/impl/vhal_v2_0/DefaultConfig.h | 24 +++++++ automotive/vehicle/2.0/types.hal | 63 ++++++++++++++++++- 2 files changed, 85 insertions(+), 2 deletions(-) diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h index e3b559ec8d..80a183138c 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h @@ -1092,6 +1092,30 @@ const ConfigDeclaration kVehicleProperties[]{ .changeMode = VehiclePropertyChangeMode::ON_CHANGE, }, }, + { + .config = + { + .prop = toInt(VehicleProperty::POWER_POLICY_REQ), + .access = VehiclePropertyAccess::READ, + .changeMode = VehiclePropertyChangeMode::ON_CHANGE, + }, + }, + { + .config = + { + .prop = toInt(VehicleProperty::POWER_POLICY_GROUP_REQ), + .access = VehiclePropertyAccess::READ, + .changeMode = VehiclePropertyChangeMode::ON_CHANGE, + }, + }, + { + .config = + { + .prop = toInt(VehicleProperty::CURRENT_POWER_POLICY), + .access = VehiclePropertyAccess::READ_WRITE, + .changeMode = VehiclePropertyChangeMode::ON_CHANGE, + }, + }, { .config = { diff --git a/automotive/vehicle/2.0/types.hal b/automotive/vehicle/2.0/types.hal index 11fe70ef5f..931fee4a23 100644 --- a/automotive/vehicle/2.0/types.hal +++ b/automotive/vehicle/2.0/types.hal @@ -2920,6 +2920,65 @@ enum VehicleProperty : int32_t { | VehiclePropertyType:MIXED | VehicleArea:GLOBAL), + /** + * Defines a request to apply power policy. + * + * VHAL sets this property to change car power policy. Car power policy service subscribes to + * this property and actually changes the power policy. + * The request is made by setting the VehiclePropValue with the ID of a power policy which is + * defined at /vendor/etc/power_policy.xml. If the given ID is not defined, car power policy + * service ignores the request and the current power policy is maintained. + * + * string: "sample_policy_id" // power policy ID + * + * @change_mode VehiclePropertyChangeMode:ON_CHANGE + * @access VehiclePropertyAccess:READ + */ + POWER_POLICY_REQ = ( + 0x0F21 + | VehiclePropertyGroup:SYSTEM + | VehiclePropertyType:STRING + | VehicleArea:GLOBAL), + + /** + * Defines a request to set the power polic group used to decide a default power policy per + * power status transition. + * + * VHAL sets this property with the ID of a power policy group in order to set the default power + * policy applied at power status transition. Power policy groups are defined at + * /vendor/etc/power_policy.xml. If the given ID is not defined, car power policy service + * ignores the request. + * Car power policy service subscribes to this property and sets the power policy group. + * The actual application of power policy takes place when the system power status changes and + * there is a valid mapped power policy for the new power status. + * + * string: "sample_policy_group_id" // power policy group ID + * + * @change_mode VehiclePropertyChangeMode:ON_CHANGE + * @access VehiclePropertyAccess:READ + */ + POWER_POLICY_GROUP_REQ = ( + 0x0F22 + | VehiclePropertyGroup:SYSTEM + | VehiclePropertyType:STRING + | VehicleArea:GLOBAL), + + /** + * Notifies the current power policy to VHAL layer. + * + * Car power policy service sets this property when the current power policy is changed. + * + * string: "sample_policy_id" // power policy ID + * + * @change_mode VehiclePropertyChangeMode:ON_CHANGE + * @access VehiclePropertyAccess:READ_WRITE + */ + CURRENT_POWER_POLICY = ( + 0x0F23 + | VehiclePropertyGroup:SYSTEM + | VehiclePropertyType:STRING + | VehicleArea:GLOBAL), + /** * Defines an event that car watchdog updates to tell it's alive. * @@ -2938,8 +2997,8 @@ enum VehicleProperty : int32_t { /** * Defines a process terminated by car watchdog and the reason of termination. * - * int32Values[0]: 1 // ProcessTerminationReason showing why a process is terminated. - * string: "/system/bin/log" // Process execution command. + * int32Values[0]: 1 // ProcessTerminationReason showing why a process is terminated. + * string: "/system/bin/log" // Process execution command. * * @change_mode VehiclePropertyChangeMode:ON_CHANGE * @access VehiclePropertyAccess:WRITE -- GitLab From 457e9d8530546ad0d74ce98412bb7b23a230cfeb Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Thu, 8 Oct 2020 12:52:04 -0700 Subject: [PATCH 205/790] Define IFace Bug: 168730443 Test: m android.hardware.biometrics.face-update-api Change-Id: I6bd1d1240ef91680d8b96cb84849431c25265358 --- biometrics/face/aidl/Android.bp | 22 ++ .../biometrics/face/AcquiredInfo.aidl | 44 +++ .../hardware/biometrics/face/Error.aidl | 28 ++ .../biometrics/face/FaceSensorType.aidl | 23 ++ .../hardware/biometrics/face/IFace.aidl | 23 ++ .../hardware/biometrics/face/ISession.aidl | 31 ++ .../biometrics/face/ISessionCallback.aidl | 37 ++ .../hardware/biometrics/face/SensorProps.aidl | 24 ++ .../biometrics/face/SessionState.aidl | 33 ++ .../biometrics/face/AcquiredInfo.aidl | 219 +++++++++++ .../hardware/biometrics/face/Error.aidl | 92 +++++ .../biometrics/face/FaceSensorType.aidl | 24 ++ .../hardware/biometrics/face/IFace.aidl | 50 +++ .../hardware/biometrics/face/ISession.aidl | 369 ++++++++++++++++++ .../biometrics/face/ISessionCallback.aidl | 200 ++++++++++ .../hardware/biometrics/face/SensorProps.aidl | 43 ++ .../biometrics/face/SessionState.aidl | 82 ++++ .../compatibility_matrix.current.xml | 7 + 18 files changed, 1351 insertions(+) create mode 100644 biometrics/face/aidl/Android.bp create mode 100644 biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl create mode 100644 biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Error.aidl create mode 100644 biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/FaceSensorType.aidl create mode 100644 biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl create mode 100644 biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl create mode 100644 biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl create mode 100644 biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl create mode 100644 biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SessionState.aidl create mode 100644 biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl create mode 100644 biometrics/face/aidl/android/hardware/biometrics/face/Error.aidl create mode 100644 biometrics/face/aidl/android/hardware/biometrics/face/FaceSensorType.aidl create mode 100644 biometrics/face/aidl/android/hardware/biometrics/face/IFace.aidl create mode 100644 biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl create mode 100644 biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl create mode 100644 biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl create mode 100644 biometrics/face/aidl/android/hardware/biometrics/face/SessionState.aidl diff --git a/biometrics/face/aidl/Android.bp b/biometrics/face/aidl/Android.bp new file mode 100644 index 0000000000..4f8b71ddbb --- /dev/null +++ b/biometrics/face/aidl/Android.bp @@ -0,0 +1,22 @@ +aidl_interface { + name: "android.hardware.biometrics.face", + vendor_available: true, + srcs: [ + "android/hardware/biometrics/face/**/*.aidl", + ], + imports: [ + "android.hardware.biometrics.common", + "android.hardware.common", + "android.hardware.keymaster", + ], + stability: "vintf", + backend: { + java: { + enabled: false, + platform_apis: false, + }, + cpp: { + enabled: false, + }, + }, +} diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl new file mode 100644 index 0000000000..011b7112e5 --- /dev/null +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl @@ -0,0 +1,44 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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.face; +@Backing(type="byte") @VintfStability +enum AcquiredInfo { + GOOD = 0, + INSUFFICIENT = 1, + TOO_BRIGHT = 2, + TOO_DARK = 3, + TOO_CLOSE = 4, + TOO_FAR = 5, + FACE_TOO_HIGH = 6, + FACE_TOO_LOW = 7, + FACE_TOO_RIGHT = 8, + FACE_TOO_LEFT = 9, + POOR_GAZE = 10, + NOT_DETECTED = 11, + TOO_MUCH_MOTION = 12, + RECALIBRATE = 13, + TOO_DIFFERENT = 14, + TOO_SIMILAR = 15, + PAN_TOO_EXTREME = 16, + TILT_TOO_EXTREME = 17, + ROLL_TOO_EXTREME = 18, + FACE_OBSCURED = 19, + START = 20, + SENSOR_DIRTY = 21, + VENDOR = 22, +} diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Error.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Error.aidl new file mode 100644 index 0000000000..15fcbf959a --- /dev/null +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Error.aidl @@ -0,0 +1,28 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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.face; +@Backing(type="byte") @VintfStability +enum Error { + HW_UNAVAILABLE = 1, + UNABLE_TO_PROCESS = 2, + TIMEOUT = 3, + NO_SPACE = 4, + CANCELED = 5, + UNABLE_TO_REMOVE = 6, + VENDOR = 8, +} diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/FaceSensorType.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/FaceSensorType.aidl new file mode 100644 index 0000000000..943129ed8a --- /dev/null +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/FaceSensorType.aidl @@ -0,0 +1,23 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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.face; +@Backing(type="byte") @VintfStability +enum FaceSensorType { + RGB = 0, + IR = 1, +} diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl new file mode 100644 index 0000000000..518fb147f4 --- /dev/null +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl @@ -0,0 +1,23 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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.face; +@VintfStability +interface IFace { + android.hardware.biometrics.face.SensorProps[] getSensorProps(); + android.hardware.biometrics.face.ISession createSession(in int sensorId, in int userId, in android.hardware.biometrics.face.ISessionCallback cb); +} 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 new file mode 100644 index 0000000000..c9b443d67c --- /dev/null +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl @@ -0,0 +1,31 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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.face; +@VintfStability +interface ISession { + void generateChallenge(in int cookie, in int sensorId, in int userId, in int timeoutSec); + void revokeChallenge(in int cookie, in int sensorId, in int userId, in long challenge); + android.hardware.biometrics.common.ICancellationSignal enroll(in int cookie, in android.hardware.keymaster.HardwareAuthToken hat, in android.hardware.common.NativeHandle previewSurface); + android.hardware.biometrics.common.ICancellationSignal authenticate(in int cookie, in long operationId); + android.hardware.biometrics.common.ICancellationSignal detectInteraction(in int cookie); + void enumerateEnrollments(in int cookie); + void removeEnrollments(in int cookie, in int[] enrollmentIds); + void getAuthenticatorId(in int cookie); + void invalidateAuthenticatorId(in int cookie); + void resetLockout(in int cookie, in android.hardware.keymaster.HardwareAuthToken hat); +} diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl new file mode 100644 index 0000000000..477ba5a27f --- /dev/null +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl @@ -0,0 +1,37 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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.face; +@VintfStability +interface ISessionCallback { + void onStateChanged(in int cookie, in android.hardware.biometrics.face.SessionState state); + void onChallengeGenerated(in int sensorId, in int userId, in long challenge); + void onChallengeRevoked(in int sensorId, in int userId, in long challenge); + void onAcquired(in android.hardware.biometrics.face.AcquiredInfo info, in int vendorCode); + void onError(in android.hardware.biometrics.face.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(); +} diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl new file mode 100644 index 0000000000..9f977f54af --- /dev/null +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl @@ -0,0 +1,24 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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.face; +@VintfStability +parcelable SensorProps { + android.hardware.biometrics.common.CommonProps commonProps; + android.hardware.biometrics.face.FaceSensorType sensorType; + boolean halControlsPreview; +} diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SessionState.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SessionState.aidl new file mode 100644 index 0000000000..8e5139b38b --- /dev/null +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SessionState.aidl @@ -0,0 +1,33 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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.face; +@Backing(type="byte") @VintfStability +enum SessionState { + IDLING = 0, + TERMINATED = 1, + GENERATING_CHALLENGE = 2, + REVOKING_CHALLENGE = 3, + ENROLLING = 4, + AUTHENTICATING = 5, + DETECTING_INTERACTION = 6, + ENUMERATING_ENROLLMENTS = 7, + REMOVING_ENROLLMENTS = 8, + GETTING_AUTHENTICATOR_ID = 9, + INVALIDATING_AUTHENTICATOR_ID = 10, + RESETTING_LOCKOUT = 11, +} diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl new file mode 100644 index 0000000000..fffb418c03 --- /dev/null +++ b/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl @@ -0,0 +1,219 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.biometrics.face; + +@VintfStability +@Backing(type="byte") +enum AcquiredInfo { + + /** + * The acquired face data was good, no further user interaction is necessary. + */ + GOOD = 0, + + /** + * The acquired face data was too noisy or did not have sufficient detail. + * This is a catch-all for all acquisition errors not captured by the other + * constants. + */ + INSUFFICIENT = 1, + + /** + * Because there was too much ambient light, the captured face data was too + * bright. It's reasonable to return this after multiple + * AcquiredInfo.INSUFFICIENT. + * + * The user is expected to take action to retry the operation in better + * lighting conditions when this is returned. + */ + TOO_BRIGHT = 2, + + /** + * Because there was not enough illumination, the captured face data was too + * dark. It's reasonable to return this after multiple + * AcquiredInfo.INSUFFICIENT. + * + * The user is expected to take action to retry the operation in better + * lighting conditions when this is returned. + */ + TOO_DARK = 3, + + /** + * The detected face is too close to the sensor, and the image cannot be + * processed. + * + * The user is expected to be informed to move further from the sensor when + * this is returned. + */ + TOO_CLOSE = 4, + + /** + * The detected face is too small, as the user might be too far away from + * the sensor. + * + * The user is expected to be informed to move closer to the sensor when + * this is returned. + */ + TOO_FAR = 5, + + /** + * Only the upper part of the face was detected. The sensor's field of view + * is too high. + * + * The user should be informed to move up with respect to the sensor when + * this is returned. + */ + FACE_TOO_HIGH = 6, + + /** + * Only the lower part of the face was detected. The sensor's field of view + * is too low. + * + * The user should be informed to move down with respect to the sensor when + * this is returned. + */ + FACE_TOO_LOW = 7, + + /** + * Only the right part of the face was detected. The sensor's field of view + * is too far right. + * + * The user should be informed to move to the right with respect to the + * sensor when this is returned. + */ + FACE_TOO_RIGHT = 8, + + /** + * Only the left part of the face was detected. The sensor's field of view + * is too far left. + * + * The user should be informed to move to the left with respect to the + * sensor when this is returned. + */ + FACE_TOO_LEFT = 9, + + /** + * The user's eyes have strayed away from the sensor. If this message is + * sent, the user should be informed to look at the device. If the user + * can't be found in the frame, one of the other acquisition messages + * must be sent, e.g. NOT_DETECTED. + */ + POOR_GAZE = 10, + + /** + * No face was detected within the sensor's field of view. + * + * The user should be informed to point the sensor to a face when this is + * returned. + */ + NOT_DETECTED = 11, + + /** + * Too much motion was detected. + * + * The user should be informed to keep their face steady relative to the + * sensor. + */ + TOO_MUCH_MOTION = 12, + + /** + * The sensor needs to be re-calibrated. This is an unexpected condition, + * and must only be sent if a serious, uncorrectable, and unrecoverable + * calibration issue is detected which requires user intervention, e.g. + * re-enrolling. The expected response to this message is to direct the + * user to re-enroll. + */ + RECALIBRATE = 13, + + /** + * The face is too different from a previous acquisition. This condition + * only applies to enrollment. This can happen if the user passes the + * device to someone else in the middle of enrollment. + */ + TOO_DIFFERENT = 14, + + /** + * The face is too similar to a previous acquisition. This condition only + * applies to enrollment. The user should change their pose. + */ + TOO_SIMILAR = 15, + + /** + * The magnitude of the pan angle of the user’s face with respect to the sensor’s + * capture plane is too high. + * + * The pan angle is defined as the angle swept out by the user’s face turning + * their neck left and right. The pan angle would be zero if the user faced the + * camera directly. + * + * The user should be informed to look more directly at the camera. + */ + PAN_TOO_EXTREME = 16, + + /** + * The magnitude of the tilt angle of the user’s face with respect to the sensor’s + * capture plane is too high. + * + * The tilt angle is defined as the angle swept out by the user’s face looking up + * and down. The tilt angle would be zero if the user faced the camera directly. + * + * The user should be informed to look more directly at the camera. + */ + TILT_TOO_EXTREME = 17, + + /** + * The magnitude of the roll angle of the user’s face with respect to the sensor’s + * capture plane is too high. + * + * The roll angle is defined as the angle swept out by the user’s face tilting their head + * towards their shoulders to the left and right. The roll angle would be zero if the user's + * head is vertically aligned with the camera. + * + * The user should be informed to look more directly at the camera. + */ + ROLL_TOO_EXTREME = 18, + + /** + * The user’s face has been obscured by some object. + * + * The user should be informed to remove any objects from the line of sight from + * the sensor to the user’s face. + */ + FACE_OBSCURED = 19, + + /** + * This message represents the earliest message sent at the beginning of the authentication + * pipeline. It is expected to be used to measure latency. For example, in a camera-based + * authentication system it's expected to be sent prior to camera initialization. Note this + * should be sent whenever authentication is restarted (see IBiometricsFace#userActivity). + * The framework will measure latency based on the time between the last START message and the + * onAuthenticated callback. + */ + START = 20, + + /** + * The sensor is dirty. The user should be informed to clean the sensor. + */ + SENSOR_DIRTY = 21, + + /** + * Vendor-specific acquisition message. See ISessionCallback#onAcquired vendorCode + * documentation. + */ + VENDOR = 22 +} + diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/Error.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/Error.aidl new file mode 100644 index 0000000000..1d02456f6d --- /dev/null +++ b/biometrics/face/aidl/android/hardware/biometrics/face/Error.aidl @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.biometrics.face; + +@VintfStability +@Backing(type="byte") +enum Error { + /** + * Reserved for testing and to keep subsequent numbering consistent with + * older interfaces. + * + * NO_ERROR = 0, + */ + + /** + * A hardware error has occurred that cannot be resolved. Try again later. + */ + HW_UNAVAILABLE = 1, + + /** + * The current enroll or authenticate operation could not be completed, + * e.g. the sensor was unable to process the current image or the HAT was + * invalid. + */ + UNABLE_TO_PROCESS = 2, + + /** + * The current operation took too long to complete. This is intended to + * prevent programs from blocking the face HAL indefinitely. The timeout is + * framework and sensor-specific, but is generally on the order of 30 + * seconds. + * + * The timeout is a device-specific time meant to optimize power. For + * example after 30 seconds of searching for a face it can be use to + * indicate that the implementation is no longer looking and the framework + * should restart the operation on the next user interaction. + */ + TIMEOUT = 3, + + /** + * The current operation could not be completed because there is not enough + * storage space remaining to do so. + */ + NO_SPACE = 4, + + /** + * The current operation has been cancelled. This may happen if a new + * request (authenticate, remove, enumerate, enroll) is initiated while + * an on-going operation is in progress, or if cancel() was called. + */ + CANCELED = 5, + + /** + * The current remove operation could not be completed; the face template + * provided could not be removed. + */ + UNABLE_TO_REMOVE = 6, + + /** + * Reserved to maintain backwards compatibility. See + * ISessionCallback#onLockoutTimed instead. + * + * LOCKOUT = 7, + */ + + /** + * Used to enable a vendor-specific error message. + */ + VENDOR = 8, + + /** + * Reserved to maintain backwards compatibility. See + * ISessionCallback#onLockoutPermanent instead. + * + * LOCKOUT_PERMANENT = 9 + */ +} + diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/FaceSensorType.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/FaceSensorType.aidl new file mode 100644 index 0000000000..766f732a56 --- /dev/null +++ b/biometrics/face/aidl/android/hardware/biometrics/face/FaceSensorType.aidl @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.biometrics.face; + +@VintfStability +@Backing(type="byte") +enum FaceSensorType { + RGB, + IR +} diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/IFace.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/IFace.aidl new file mode 100644 index 0000000000..e9a66e2ea3 --- /dev/null +++ b/biometrics/face/aidl/android/hardware/biometrics/face/IFace.aidl @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.biometrics.face; + +import android.hardware.biometrics.face.ISession; +import android.hardware.biometrics.face.ISessionCallback; +import android.hardware.biometrics.face.SensorProps; + +@VintfStability +interface IFace { + /** + * getSensorProps: + * + * @return A list of properties for all face sensors available to the HAL. + */ + SensorProps[] getSensorProps(); + + /** + * createSession: + * + * Creates a session that can be used by the framework to perform operations such as + * enroll, authenticate, etc. for the given sensorId and userId. + * + * Implementations must store user-specific state or metadata in /data/vendor_de//facedata + * as specified by the SELinux policy. The directory /data/vendor_de is managed by vold (see + * vold_prepare_subdirs.cpp). Implementations may store additional user-specific data, such as + * embeddings or templates in StrongBox. + * + * @param sensorId The sensorId with which this session is being created. + * @param userId The userId with which this session is being created. + * @param cb A callback to notify the framework about the session's results and events. + * @return A new session. + */ + ISession createSession(in int sensorId, in int userId, in ISessionCallback cb); + +} diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl new file mode 100644 index 0000000000..5145b1e94d --- /dev/null +++ b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl @@ -0,0 +1,369 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.biometrics.face; + +import android.hardware.biometrics.common.ICancellationSignal; +import android.hardware.keymaster.HardwareAuthToken; +import android.hardware.common.NativeHandle; + +/** + * A session is a collection of immutable state (sensorId, userId), mutable state (SessionState), + * methods available for the framework to call, and a callback (ISessionCallback) to notify the + * framework about the events and results. A session is used to establish communication between + * the framework and the HAL. + */ +@VintfStability +interface ISession { + /** + * generateChallenge: + * + * Begins a secure transaction request. Note that the challenge by itself is not useful. It only + * becomes useful when wrapped in a verifiable message such as a HardwareAuthToken. + * + * Canonical example: + * 1) User requests an operation, such as face enrollment. + * 2) Face enrollment cannot happen until the user confirms their lockscreen credential + * (PIN/Pattern/Password). + * 3) However, the biometric subsystem does not want just "any" proof of credential + * confirmation. It needs proof that the user explicitly authenticated credential in order + * to allow addition of biometric enrollments. + * To secure this path, the following path is taken: + * 1) Upon user requesting face enroll, the framework requests + * IFace#generateChallenge + * 2) Framework sends the challenge to the credential subsystem, and upon credential + * confirmation, a HAT is created, containing the challenge in the "challenge" field. + * 3) Framework sends the HAT to the HAL, e.g. ISession#enroll. + * 4) Implementation verifies the authenticity and integrity of the HAT. + * 5) Implementation now has confidence that the user entered their credential to allow + * biometric enrollment. + * + * Note that the interface allows multiple in-flight challenges. For example, invoking + * generateChallenge(0, 0, timeoutSec) twice does not invalidate the first challenge. The + * challenge is invalidated only when: + * 1) The provided timeout expires, or + * 2) IFace#revokeChallenge is invoked + * + * For example, the following is a possible table of valid challenges: + * ---------------------------------------------- + * | SensorId | UserId | ValidUntil | Challenge | + * |----------|--------|------------|-----------| + * | 0 | 0 | | | + * | 0 | 0 | | | + * | 1 | 0 | | | + * | 0 | 10 | | | + * ---------------------------------------------- + * + * @param cookie A unique number identifying this operation + * @param sensorId Sensor to associate the challenge with + * @param userId User to associate the challenge with + * @param timeoutSec Duration for which the challenge is valid for + */ + void generateChallenge(in int cookie, in int sensorId, in int userId, in int timeoutSec); + + /** + * revokeChallenge: + * + * Revokes a challenge that was previously generated. Note that if an invalid combination of + * parameters is requested, the implementation must still notify the framework using the + * provided callback. + * + * @param cookie A unique number identifying this operation + * @param sensorId Sensor that the revocation should apply to. + * @param userId User that the revocation should apply to. + * @param challenge Challenge that should be revoked. + */ + void revokeChallenge(in int cookie, in int sensorId, in int userId, in long challenge); + + /** + * enroll: + * + * A request to add a face enrollment. + * + * Once the HAL is able to start processing the enrollment request, it must notify the framework + * via ISessionCallback#onStateChanged with SessionState::ENROLLING. + * + * At any point during enrollment, if a non-recoverable error occurs, the HAL must notify the + * framework via ISessionCallback#onError with the applicable enrollment-specific error, and + * then send ISessionCallback#onStateChanged(cookie, SessionState::IDLING) if no subsequent + * operation is in the queue. + * + * Before capturing face data, the implementation must first verify the authenticity and + * integrity of the provided HardwareAuthToken. In addition, it must check that the challenge + * within the provided HardwareAuthToken is valid. See IFace#generateChallenge. If any of + * the above checks fail, the framework must be notified via ISessionCallback#onError and the + * HAL must notify the framework when it returns to the idle state. See + * Error::UNABLE_TO_PROCESS. + * + * During enrollment, the implementation may notify the framework via + * ISessionCallback#onAcquired with messages that may be used to guide the user. This callback + * can be invoked multiple times if necessary. Similarly, the framework may be notified of + * enrollment progress changes via ISessionCallback#onEnrollmentProgress. Once the framework is + * notified that there are 0 "remaining" steps, the framework may cache the "enrollmentId". See + * ISessionCallback#onEnrollmentProgress for more info. The HAL must notify the framework once + * it returns to the idle state. + * + * When a finger is successfully added and before the framework is notified of remaining=0, the + * implementation MUST update and associate this (sensorId, userId) pair with a new new + * entropy-encoded random identifier. See ISession#getAuthenticatorId for more information. + * + * @param cookie An identifier used to track subsystem operations related to this call path. The + * client must guarantee that it is unique per ISession. + * @param previewSurface A surface provided by the framework if SensorProps#halControlsPreview is + * set to true. The HAL must send the preview frames to previewSurface if + * it's not null. + * @param hat See above documentation. + * @return ICancellationSignal An object that can be used by the framework to cancel this + * operation. + */ + ICancellationSignal enroll(in int cookie, in HardwareAuthToken hat, in NativeHandle previewSurface); + + /** + * authenticate: + * + * A request to start looking for faces to authenticate. + * + * Once the HAL is able to start processing the authentication request, it must notify framework + * via ISessionCallback#onStateChanged with SessionState::AUTHENTICATING. + * + * At any point during authentication, if a non-recoverable error occurs, the HAL must notify + * the framework via ISessionCallback#onError with the applicable authentication-specific error, + * and then send ISessionCallback#onStateChanged(cookie, SessionState::IDLING) if no + * subsequent operation is in the queue. + * + * During authentication, the implementation may notify the framework via + * ISessionCallback#onAcquired with messages that may be used to guide the user. This callback + * can be invoked multiple times if necessary. + * + * The HAL must notify the framework of accepts/rejects via ISessionCallback#onAuthentication*. + * + * The authentication lifecycle ends when either + * 1) A face is accepted, and ISessionCallback#onAuthenticationSucceeded is invoked, or + * 2) Any non-recoverable error occurs (such as lockout). See the full list of + * authentication-specific errors in the Error enum. + * + * Note that upon successful authentication, the lockout counter for this (sensorId, userId) + * pair must be cleared. + * + * Note that upon successful authentication, ONLY sensors configured as SensorStrength::STRONG + * are allowed to create and send a HardwareAuthToken to the framework. See the Android CDD for + * more details. For SensorStrength::STRONG sensors, the HardwareAuthToken's "challenge" field + * must be set with the operationId passed in during #authenticate. If the sensor is NOT + * SensorStrength::STRONG, the HardwareAuthToken MUST be null. + * + * @param cookie An identifier used to track subsystem operations related to this call path. The + * client must guarantee that it is unique per ISession. + * @param operationId For sensors configured as SensorStrength::STRONG, this must be used ONLY + * upon successful authentication and wrapped in the HardwareAuthToken's + * "challenge" field and sent to the framework via + * ISessionCallback#onAuthenticated. The operationId is an opaque identifier + * created from a separate secure subsystem such as, but not limited to + * KeyStore/KeyMaster. The HardwareAuthToken can then be used as an + * attestation for the provided operation. For example, this is used + * to unlock biometric-bound auth-per-use keys (see + * setUserAuthenticationParameters in KeyGenParameterSpec.Builder and + * KeyProtection.Builder. + * @return ICancellationSignal An object that can be used by the framework to cancel this + * operation. + */ + ICancellationSignal authenticate(in int cookie, in long operationId); + + /** + * detectInteraction: + * + * A request to start looking for faces without performing matching. + * + * Once the HAL is able to start processing this request, it must notify the framework via + * ISessionCallback#onStateChanged with SessionState::DETECTING_INTERACTION. + * + * The framework will use this method in cases where determing user presence is required, but + * identifying/authentication is not. For example, when the device is encrypted (first boot) or + * in lockdown mode. + * + * At any point during detectInteraction, if a non-recoverable error occurs, the HAL must notify + * the framework via ISessionCallback#onError with the applicable error, and then send + * ISessionCallback#onStateChanged(cookie, SessionState::IDLING) if no subsequent operation is + * in the queue. + * + * The implementation must only check for a face-like image was detected (e.g. to + * minimize interactions due to non-face objects), and the lockout counter must not + * be modified. + * + * Upon detecting any face, the implementation must invoke + * ISessionCallback#onInteractionDetected. + * + * The lifecycle of this operation ends when either + * 1) Any face is detected and the framework is notified via + * ISessionCallback#onInteractiondetected + * 2) The operation was cancelled by the framework (see ICancellationSignal) + * 3) The HAL ends the operation, for example when a subsequent operation pre-empts this one. + * + * Note that if the operation is canceled, the implementation must notify the framework via + * ISessionCallback#onError with Error::CANCELED. + * + * @param cookie An identifier used to track subsystem operations related to this call path. + * The framework will guarantee that it is unique per ISession. + * @return ICancellationSignal An object that can be used by the framework to cancel this + * operation. + */ + ICancellationSignal detectInteraction(in int cookie); + + /* + * enumerateEnrollments: + * + * A request to enumerate (list) the enrollments for this (sensorId, userId) pair. The + * framework typically uses this to ensure that its cache is in sync with the HAL. + * + * Once the HAL is able to start processing this request, it must notify the framework via + * ISessionCallback#onStateChanged with SessionState::ENUMERATING_ENROLLMENTS. + * + * The implementation must then notify the framework with a list of enrollments applicable + * for the current session via ISessionCallback#onEnrollmentsEnumerated. + * + * @param cookie An identifier used to track subsystem operations related to this call path. + * The framework will guarantee that it is unique per ISession. + */ + void enumerateEnrollments(in int cookie); + + /** + * removeEnrollments: + * + * A request to remove the enrollments for this (sensorId, userId) pair. + * + * Once the HAL is able to start processing this request, it must notify the framework via + * ISessionCallback#onStateChanged with SessionState::REMOVING_ENROLLMENTS. + * + * After removing the enrollmentIds from everywhere necessary (filesystem, secure subsystems, + * etc), the implementation must notify the framework via ISessionCallback#onEnrollmentsRemoved. + * + * @param cookie An identifier used to track subsystem operations related to this call path. + * The framework will guarantee that it is unique per ISession. + */ + void removeEnrollments(in int cookie, in int[] enrollmentIds); + + /** + * getAuthenticatorId: + * + * MUST return 0 via ISessionCallback#onAuthenticatorIdRetrieved for sensors that are configured + * as SensorStrength::WEAK or SensorStrength::CONVENIENCE. + * + * The following only applies to sensors that are configured as SensorStrength::STRONG. + * + * The authenticatorId is a (sensorId, user)-specific identifier which can be used during key + * generation and key import to to associate a key (in KeyStore / KeyMaster) with the current + * set of enrolled faces. For example, the following public Android APIs allow for keys + * to be invalidated when the user adds a new enrollment after the key was created: + * KeyGenParameterSpec.Builder.setInvalidatedByBiometricEnrollment and + * KeyProtection.Builder.setInvalidatedByBiometricEnrollment. + * + * In addition, upon successful face authentication, the signed HAT that is returned to + * the framework via ISessionCallback#onAuthenticated must contain this identifier in the + * authenticatorId field. + * + * Returns an entropy-encoded random identifier associated with the current set of enrollments + * via ISessionCallback#onAuthenticatorIdRetrieved. The authenticatorId + * 1) MUST change whenever a new face is enrolled + * 2) MUST return 0 if no faces are enrolled + * 3) MUST not change if a face is deleted. + * 4) MUST be an entropy-encoded random number + * + * @param cookie An identifier used to track subsystem operations related to this call path. The + * client must guarantee that it is unique per ISession. + */ + void getAuthenticatorId(in int cookie); + + /** + * invalidateAuthenticatorId: + * + * This method only applies to sensors that are configured as SensorStrength::STRONG. If invoked + * by the framework for sensor of other strengths, the HAL should immediately invoke + * ISessionCallback#onAuthenticatorIdInvalidated. + * + * The following only applies to sensors that are configured as SensorStrength::STRONG. + * + * When invoked by the framework, the implementation must perform the following sequence of + * events: + * 1) Verify the authenticity and integrity of the provided HAT. If this check fails, the HAL + * must invoke ISessionCallback#onError with Error::UNABLE_TO_PROCESS and return to + * SessionState::IDLING if no subsequent work is in the queue. + * 2) Verify that the timestamp provided within the HAT is relatively recent (e.g. on the + * order of minutes, not hours). If this check fails, the HAL must invoke + * ISessionCallback#onError with Error::UNABLE_TO_PROCESS and return to + * SessionState::IDLING if no subsequent work is in the queue. + * 3) Update the authenticatorId with a new entropy-encoded random number + * 4) Persist the new authenticatorId to non-ephemeral storage + * 5) Notify the framework that the above is completed, via + * ISessionCallback#onAuthenticatorInvalidated + * + * A practical use case of invalidation would be when the user adds a new enrollment to a sensor + * managed by a different HAL instance. The public android.security.keystore APIs bind keys to + * "all biometrics" rather than "face-only" or "face-only" (see #getAuthenticatorId + * for more details). As such, the framework would coordinate invalidation across multiple + * biometric HALs as necessary. + * + * @param cookie An identifier used to track subsystem operations related to this call path. The + * client must guarantee that it is unique per ISession. + */ + void invalidateAuthenticatorId(in int cookie); + + /** + * resetLockout: + * + * Requests the implementation to clear the lockout counter. Upon receiving this request, the + * implementation must perform the following: + * 1) Verify the authenticity and integrity of the provided HAT + * 2) Verify that the timestamp provided within the HAT is relatively recent (e.g. on the + * order of minutes, not hours). + * If either of the checks fail, the HAL must invoke ISessionCallback#onError with + * Error::UNABLE_TO_PROCESS and return to SessionState::IDLING if no subsequent work is in the + * queue. + * + * Upon successful verification, the HAL must clear the lockout counter and notify the framework + * via ISessionCallback#onLockoutCleared. + * + * Note that lockout is user AND sensor specific. In other words, there is a separate lockout + * state for each (user, sensor) pair. For example, the following is a valid state on a + * multi-sensor device: + * ------------------------------------------------------------------ + * | SensorId | UserId | FailedAttempts | LockedOut | LockedUntil | + * |----------|--------|----------------|-----------|---------------| + * | 0 | 0 | 1 | false | x | + * | 1 | 0 | 5 | true | | + * | 0 | 10 | 0 | false | x | + * | 1 | 10 | 0 | false | x | + * ------------------------------------------------------------------ + * + * Lockout may be cleared in the following ways: + * 1) ISession#resetLockout + * 2) After a period of time, according to a rate-limiter. + * + * Note that the "FailedAttempts" counter must be cleared upon successful face + * authentication. For example, if SensorId=0 UserId=0 FailedAttempts=1, and a successful + * face authentication occurs, the counter for that (SensorId, UserId) pair must be reset + * to 0. + * + * In addition, lockout states MUST persist after device reboots, HAL crashes, etc. + * + * See the Android CDD section 7.3.10 for the full set of lockout and rate-limiting + * requirements. + * + * @param cookie An identifier used to track subsystem operations related to this call path. The + * client must guarantee that it is unique per ISession. + * @param hat HardwareAuthToken See above documentation. + */ + void resetLockout(in int cookie, in HardwareAuthToken hat); +} + diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl new file mode 100644 index 0000000000..2608d5fc7b --- /dev/null +++ b/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl @@ -0,0 +1,200 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.biometrics.face; + +import android.hardware.biometrics.face.AcquiredInfo; +import android.hardware.biometrics.face.Error; +import android.hardware.biometrics.face.SessionState; +import android.hardware.keymaster.HardwareAuthToken; + +@VintfStability +interface ISessionCallback { + /** + * Used to notify the framework of session state changes. See ISession for more information. + */ + void onStateChanged(in int cookie, in SessionState state); + + /** + * Notifies the framework when a challenge is successfully generated. + */ + void onChallengeGenerated(in int sensorId, in int userId, in long challenge); + + /** + * Notifies the framework when a challenge has been revoked. + */ + void onChallengeRevoked(in int sensorId, in int userId, in long challenge); + + /** + * This method must only be used to notify the framework during the following states: + * 1) SessionState::ENROLLING + * 2) SessionState::AUTHENTICATING + * 3) SessionState::DETECTING_INTERACTION + * + * These messages may be used to provide user guidance multiple times if necessary per + * operation. + * + * @param info See the AcquiredInfo enum. + * @param vendorCode Only valid if info == AcquiredInfo::VENDOR. The vendorCode must be used to + * index into the configuration + * com.android.internal.R.array.face_acquired_vendor that's installed + * on the vendor partition. + */ + void onAcquired(in AcquiredInfo info, in int vendorCode); + + /** + * This method must only be used to notify the framework during the following states: + * 1) SessionState::ENROLLING + * 2) SessionState::AUTHENTICATING + * 3) SessionState::DETECTING_INTERACTION + * 4) SessionState::INVALIDATING_AUTHENTICATOR_ID + * 5) SessionState::RESETTING_LOCKOUT + * + * These messages may be used to notify the framework or user that a non-recoverable error + * has occurred. The operation is finished, and the HAL must proceed with the next operation + * or return to SessionState::IDLING if the queue is empty. + * + * Note that cancellation (see common::ICancellationSignal) and preemption most be followed with + * an Error::CANCELED message. + * + * @param error See the Error enum. + * @param vendorCode Only valid if error == Error::VENDOR. The vendorCode must be used to index + * into the configuration + * com.android.internal.R.face_error_vendor that's installed on the + * vendor partition. + */ + void onError(in Error error, in int vendorCode); + + /** + * This method must only be used to notify the framework during the following state: + * 1) SessionState::ENROLLING + * + * @param enrollmentId Unique stable identifier for the enrollment that's being added by this + * ISession#enroll invocation. + * @param remaining Remaining number of steps before enrollment is complete. + */ + void onEnrollmentProgress(in int enrollmentId, int remaining); + + /** + * This method must only be used to notify the framework during SessionState::AUTHENTICATING. + * + * Used to notify the framework upon successful authentication. Note that the authentication + * lifecycle ends when either 1) a face is accepted, or 2) an error occurred. The + * authentication lifecycle does NOT end when a face is rejected. + * + * @param enrollmentId Face that was accepted. + * @param hat If the sensor is configured as SensorStrength::STRONG, a non-null attestation that + * a face was accepted. The HardwareAuthToken's "challenge" field must be set + * with the operationId passed in during ISession#authenticate. If the sensor is NOT + * SensorStrength::STRONG, the HardwareAuthToken MUST be null. + */ + void onAuthenticationSucceeded(in int enrollmentId, in HardwareAuthToken hat); + + /** + * This method must only be used to notify the framework during SessionState::AUTHENTICATING. + * + * Used to notify the framework upon rejected attempts. Note that the authentication + * lifecycle ends when either 1) a face is accepted, or 2) an occurred. The + * authentication lifecycle does NOT end when a face is rejected. + */ + void onAuthenticationFailed(); + + /** + * This method must only be used to notify the framework during SessionState::AUTHENTICATING. + * + * Authentication is locked out due to too many unsuccessful attempts. This is a rate-limiting + * lockout, and authentication can be restarted after a period of time. See + * ISession#resetLockout. + * + * @param sensorId Sensor for which the user is locked out. + * @param userId User for which the sensor is locked out. + * @param durationMillis Remaining duration of the lockout. + */ + void onLockoutTimed(in long durationMillis); + + /** + * This method must only be used to notify the framework during SessionState::AUTHENTICATING. + * + * Authentication is disabled until the user unlocks with their device credential + * (PIN/Pattern/Password). See ISession#resetLockout. + * + * @param sensorId Sensor for which the user is locked out. + * @param userId User for which the sensor is locked out. + */ + void onLockoutPermanent(); + + /** + * Notifies the framework that lockout has been cleared for this (sensorId, userId) pair. + * + * Note that this method can be used to notify the framework during any state. + * + * Lockout can be cleared in the following scenarios: + * 1) A timed lockout has ended (e.g. durationMillis specified in previous #onLockoutTimed + * has expired. + * 2) See ISession#resetLockout. + * + * @param sensorId Sensor for which the user's lockout is cleared. + * @param userId User for the sensor's lockout is cleared. + */ + void onLockoutCleared(); + + /** + * This method must only be used to notify the framework during + * SessionState::DETECTING_INTERACTION + * + * Notifies the framework that user interaction occurred. See ISession#detectInteraction. + */ + void onInteractionDetected(); + + /** + * This method must only be used to notify the framework during + * SessionState::ENUMERATING_ENROLLMENTS. + * + * Notifies the framework of the current enrollments. See ISession#enumerateEnrollments. + * + * @param enrollmentIds A list of enrollments for the session's (userId, sensorId) pair. + */ + void onEnrollmentsEnumerated(in int[] enrollmentIds); + + /** + * This method must only be used to notify the framework during + * SessionState::REMOVING_ENROLLMENTS. + * + * Notifies the framework that the specified enrollments are removed. + * + * @param enrollmentIds The enrollments that were removed. + */ + void onEnrollmentsRemoved(in int[] enrollmentIds); + + /** + * This method must only be used to notify the framework during + * SessionState::GETTING_AUTHENTICATOR_ID. + * + * Notifies the framework with the authenticatorId corresponding to this session's + * (userId, sensorId) pair. + * + * @param authenticatorId See the above documentation. + */ + void onAuthenticatorIdRetrieved(in long authenticatorId); + + /** + * This method must only be used to notify the framework during + * SessionState::INVALIDATING_AUTHENTICATOR_ID. + * + * See ISession#invalidateAuthenticatorId for more information. + */ + void onAuthenticatorIdInvalidated(); +} diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl new file mode 100644 index 0000000000..53cc44e7ec --- /dev/null +++ b/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.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. + */ + +package android.hardware.biometrics.face; + +import android.hardware.biometrics.common.CommonProps; +import android.hardware.biometrics.face.FaceSensorType; + +@VintfStability +parcelable SensorProps { + /** + * Statically configured properties that apply to this face sensor. + */ + CommonProps commonProps; + + /** + * A statically configured sensor type representing this face sensor. + */ + FaceSensorType sensorType; + + /** + * Whether or not the HAL is responsible for showing the face enrollment preview to the user. + * Devices with multiple front camera sensors can set this to false and rely on the framework to + * show the preview with one of the unused cameras. Devices with a single front sensor must set + * this to true and configure their send their camera stream to the preview surface provided by + * the framework. + */ + boolean halControlsPreview; +} + diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/SessionState.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/SessionState.aidl new file mode 100644 index 0000000000..1878f7c823 --- /dev/null +++ b/biometrics/face/aidl/android/hardware/biometrics/face/SessionState.aidl @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.biometrics.face; + +@VintfStability +@Backing(type="byte") +enum SessionState { + /** + * The HAL is not processing any session requests. + */ + IDLING, + + /** + * The session has been terminated by the HAL. + */ + TERMINATED, + + /** + * The HAL is processing the ISession#generateChallenge request. + */ + GENERATING_CHALLENGE, + + /** + * The HAL is processing the ISession#revokeChallenge request. + */ + REVOKING_CHALLENGE, + + /** + * The HAL is processing the ISession#enroll request. + */ + ENROLLING, + + /** + * The HAL is processing the ISession#authenticate request. + */ + AUTHENTICATING, + + /** + * The HAL is processing the ISession#detectInteraction request. + */ + DETECTING_INTERACTION, + + /** + * The HAL is processing the ISession#enumerateEnrollments request. + */ + ENUMERATING_ENROLLMENTS, + + /** + * The HAL is processing the ISession#removeEnrollments request. + */ + REMOVING_ENROLLMENTS, + + /** + * The HAL is processing the ISession#getAuthenticatorId request. + */ + GETTING_AUTHENTICATOR_ID, + + /** + * The HAL is processing the ISession#invalidateAuthenticatorId request. + */ + INVALIDATING_AUTHENTICATOR_ID, + + /** + * The HAL is processing the ISession#resetLockout request. + */ + RESETTING_LOCKOUT +} + diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index 4ac19731e2..a99f8feda4 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -96,6 +96,13 @@ default + + android.hardware.biometrics.face + + IFace + default + + android.hardware.biometrics.fingerprint 2.1-3 -- GitLab From 3b542cd396699e0c6d364be5a549fec30d60edb6 Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Mon, 12 Oct 2020 18:23:46 -0700 Subject: [PATCH 206/790] Add VTS tests skeleton for IFace Bug: 168730443 Test: atest VtsHalBiometricsFaceTargetTest Change-Id: I90ec41b0b7cc461cce50f55f99e7ee2a836fb2e0 --- biometrics/face/aidl/vts/Android.bp | 16 ++ .../vts/VtsHalBiometricsFaceTargetTest.cpp | 157 ++++++++++++++++++ 2 files changed, 173 insertions(+) create mode 100644 biometrics/face/aidl/vts/Android.bp create mode 100644 biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp diff --git a/biometrics/face/aidl/vts/Android.bp b/biometrics/face/aidl/vts/Android.bp new file mode 100644 index 0000000000..427b8785fb --- /dev/null +++ b/biometrics/face/aidl/vts/Android.bp @@ -0,0 +1,16 @@ +cc_test { + name: "VtsHalBiometricsFaceTargetTest", + defaults: [ + "VtsHalTargetTestDefaults", + "use_libaidlvintf_gtest_helper_static", + ], + srcs: ["VtsHalBiometricsFaceTargetTest.cpp"], + shared_libs: [ + "libbinder_ndk", + "android.hardware.biometrics.face-ndk_platform", + ], + test_suites: [ + "general-tests", + "vts", + ], +} diff --git a/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp b/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp new file mode 100644 index 0000000000..c1ba66b004 --- /dev/null +++ b/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include +#include + +#include +#include + +#include + +namespace aidl::android::hardware::biometrics::face { +namespace { + +constexpr int kSensorId = 0; +constexpr int kUserId = 0; +constexpr auto kCallbackTimeout = std::chrono::seconds(1); + +enum class SessionCallbackMethodName { + kOnStateChanged, +}; + +struct SessionCallbackInvocation { + SessionCallbackMethodName method_name; + SessionState state; +}; + +class SessionCallback : public BnSessionCallback { + public: + explicit SessionCallback(std::promise invocation_promise) + : invocation_promise_(std::move(invocation_promise)) {} + ndk::ScopedAStatus onStateChanged(int32_t /*cookie*/, SessionState state) override { + SessionCallbackInvocation invocation = {}; + invocation.method_name = SessionCallbackMethodName::kOnStateChanged; + invocation.state = state; + invocation_promise_.set_value(invocation); + return ndk::ScopedAStatus::ok(); + } + + ndk::ScopedAStatus onChallengeGenerated(int32_t /*sensorId*/, int32_t /*userId*/, + int64_t /*challenge*/) override { + return ndk::ScopedAStatus::ok(); + } + + ndk::ScopedAStatus onChallengeRevoked(int32_t /*sensorId*/, int32_t /*userId*/, + int64_t /*challenge*/) override { + return ndk::ScopedAStatus::ok(); + } + + ndk::ScopedAStatus onAcquired(AcquiredInfo /*info*/, int32_t /*vendorCode*/) override { + return ndk::ScopedAStatus::ok(); + } + + ndk::ScopedAStatus onError(Error /*error*/, int32_t /*vendorCode*/) override { + return ndk::ScopedAStatus::ok(); + } + + ndk::ScopedAStatus onEnrollmentProgress(int32_t /*enrollmentId*/, + int32_t /*remaining*/) override { + return ndk::ScopedAStatus::ok(); + } + + ndk::ScopedAStatus onAuthenticationSucceeded( + int32_t /*enrollmentId*/, const keymaster::HardwareAuthToken& /*hat*/) override { + return ndk::ScopedAStatus::ok(); + } + + ndk::ScopedAStatus onAuthenticationFailed() override { return ndk::ScopedAStatus::ok(); } + + ndk::ScopedAStatus onLockoutTimed(int64_t /*durationMillis*/) override { + return ndk::ScopedAStatus::ok(); + } + + ndk::ScopedAStatus onLockoutPermanent() override { return ndk::ScopedAStatus::ok(); } + + ndk::ScopedAStatus onLockoutCleared() override { return ndk::ScopedAStatus::ok(); } + + ndk::ScopedAStatus onInteractionDetected() override { return ndk::ScopedAStatus::ok(); } + + ndk::ScopedAStatus onEnrollmentsEnumerated( + const std::vector& /*enrollmentIds*/) override { + return ndk::ScopedAStatus::ok(); + } + + ndk::ScopedAStatus onEnrollmentsRemoved( + const std::vector& /*enrollmentIds*/) override { + return ndk::ScopedAStatus::ok(); + } + + ndk::ScopedAStatus onAuthenticatorIdRetrieved(int64_t /*authenticatorId*/) override { + return ndk::ScopedAStatus::ok(); + } + + ndk::ScopedAStatus onAuthenticatorIdInvalidated() override { return ndk::ScopedAStatus::ok(); } + + private: + std::promise invocation_promise_; +}; + +class Face : public testing::TestWithParam { + protected: + void SetUp() override { + AIBinder* binder = AServiceManager_waitForService(GetParam().c_str()); + ASSERT_NE(binder, nullptr); + hal_ = IFace::fromBinder(ndk::SpAIBinder(binder)); + } + + std::shared_ptr hal_; +}; + +TEST_P(Face, AuthenticateTest) { + std::promise invocation_promise; + std::future invocation_future = invocation_promise.get_future(); + std::shared_ptr session_cb = + ndk::SharedRefBase::make(std::move(invocation_promise)); + + std::shared_ptr session; + ASSERT_TRUE(hal_->createSession(kSensorId, kUserId, session_cb, &session).isOk()); + + std::shared_ptr cancel_cb; + ASSERT_TRUE(session->authenticate(0, 0, &cancel_cb).isOk()); + ASSERT_EQ(invocation_future.wait_for(kCallbackTimeout), std::future_status::ready); + + SessionCallbackInvocation invocation = invocation_future.get(); + EXPECT_EQ(invocation.method_name, SessionCallbackMethodName::kOnStateChanged); + EXPECT_EQ(invocation.state, SessionState::AUTHENTICATING); +} + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Face); +INSTANTIATE_TEST_SUITE_P(IFace, Face, + testing::ValuesIn(::android::getAidlHalInstanceNames(IFace::descriptor)), + ::android::PrintInstanceNameToString); + +} // namespace + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + ABinderProcess_setThreadPoolMaxThreadCount(1); + ABinderProcess_startThreadPool(); + return RUN_ALL_TESTS(); +} + +} // namespace aidl::android::hardware::biometrics::face -- GitLab From 0916698222165de89a111e88636582b5073f9252 Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Mon, 12 Oct 2020 13:41:03 -0700 Subject: [PATCH 207/790] Default implementation skeleton for IFace Bug: 168730443 Test: atest VtsHalBiometricsFaceTargetTest Test: atest vts_treble_vintf_vendor_test Test: atest hal_implementation_test Change-Id: I97b2b00da928e7f9e175d9853424111d95f285fb --- biometrics/face/aidl/default/Android.bp | 18 ++++ biometrics/face/aidl/default/Face.cpp | 61 ++++++++++++++ biometrics/face/aidl/default/Face.h | 32 ++++++++ biometrics/face/aidl/default/Session.cpp | 82 +++++++++++++++++++ biometrics/face/aidl/default/Session.h | 67 +++++++++++++++ biometrics/face/aidl/default/face-default.rc | 5 ++ biometrics/face/aidl/default/face-default.xml | 6 ++ biometrics/face/aidl/default/main.cpp | 36 ++++++++ 8 files changed, 307 insertions(+) create mode 100644 biometrics/face/aidl/default/Android.bp create mode 100644 biometrics/face/aidl/default/Face.cpp create mode 100644 biometrics/face/aidl/default/Face.h create mode 100644 biometrics/face/aidl/default/Session.cpp create mode 100644 biometrics/face/aidl/default/Session.h create mode 100644 biometrics/face/aidl/default/face-default.rc create mode 100644 biometrics/face/aidl/default/face-default.xml create mode 100644 biometrics/face/aidl/default/main.cpp diff --git a/biometrics/face/aidl/default/Android.bp b/biometrics/face/aidl/default/Android.bp new file mode 100644 index 0000000000..51a8ef4488 --- /dev/null +++ b/biometrics/face/aidl/default/Android.bp @@ -0,0 +1,18 @@ +cc_binary { + name: "android.hardware.biometrics.face-service.example", + relative_install_path: "hw", + init_rc: ["face-default.rc"], + vintf_fragments: ["face-default.xml"], + vendor: true, + shared_libs: [ + "libbase", + "libbinder_ndk", + "android.hardware.biometrics.face-ndk_platform", + "android.hardware.biometrics.common-unstable-ndk_platform", + ], + srcs: [ + "main.cpp", + "Face.cpp", + "Session.cpp", + ], +} diff --git a/biometrics/face/aidl/default/Face.cpp b/biometrics/face/aidl/default/Face.cpp new file mode 100644 index 0000000000..1526245c70 --- /dev/null +++ b/biometrics/face/aidl/default/Face.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Face.h" +#include "Session.h" + +namespace aidl::android::hardware::biometrics::face { + +const int kSensorId = 0; +const common::SensorStrength kSensorStrength = common::SensorStrength::WEAK; +const int kMaxEnrollmentsPerUser = 5; +const FaceSensorType kSensorType = FaceSensorType::RGB; +const bool kHalControlsPreview = true; +const std::string kHwDeviceName = "faceSensor"; +const std::string kHardwareVersion = "vendor/model/revision"; +const std::string kFirmwareVersion = "1.01"; +const std::string kSerialNumber = "00000001"; + +ndk::ScopedAStatus Face::getSensorProps(std::vector* return_val) { + common::HardwareInfo hardware_info; + hardware_info.deviceName = kHwDeviceName; + hardware_info.hardwareVersion = kHardwareVersion; + hardware_info.firmwareVersion = kFirmwareVersion; + hardware_info.serialNumber = kSerialNumber; + + common::CommonProps commonProps; + commonProps.sensorId = kSensorId; + commonProps.sensorStrength = kSensorStrength; + commonProps.maxEnrollmentsPerUser = kMaxEnrollmentsPerUser; + commonProps.hardwareInfo = {std::move(hardware_info)}; + + SensorProps props; + props.commonProps = std::move(commonProps); + props.sensorType = kSensorType; + props.halControlsPreview = kHalControlsPreview; + + *return_val = {std::move(props)}; + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Face::createSession(int32_t /*sensorId*/, int32_t /*userId*/, + const std::shared_ptr& cb, + std::shared_ptr* return_val) { + *return_val = SharedRefBase::make(cb); + return ndk::ScopedAStatus::ok(); +} + +} // namespace aidl::android::hardware::biometrics::face diff --git a/biometrics/face/aidl/default/Face.h b/biometrics/face/aidl/default/Face.h new file mode 100644 index 0000000000..786b4f89fe --- /dev/null +++ b/biometrics/face/aidl/default/Face.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +namespace aidl::android::hardware::biometrics::face { + +class Face : public BnFace { + public: + ndk::ScopedAStatus getSensorProps(std::vector* _aidl_return) override; + + ndk::ScopedAStatus createSession(int32_t sensorId, int32_t userId, + const std::shared_ptr& cb, + std::shared_ptr* _aidl_return) override; +}; + +} // namespace aidl::android::hardware::biometrics::face diff --git a/biometrics/face/aidl/default/Session.cpp b/biometrics/face/aidl/default/Session.cpp new file mode 100644 index 0000000000..bb895b76ba --- /dev/null +++ b/biometrics/face/aidl/default/Session.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "Session.h" + +namespace aidl::android::hardware::biometrics::face { + +class CancellationSignal : public common::BnCancellationSignal { + public: + ndk::ScopedAStatus cancel() override { return ndk::ScopedAStatus::ok(); } +}; + +Session::Session(std::shared_ptr cb) : cb_(std::move(cb)) {} + +ndk::ScopedAStatus Session::generateChallenge(int32_t /*cookie*/, int32_t /*sensorId*/, + int32_t /*userId*/, int32_t /*timeoutSec*/) { + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Session::revokeChallenge(int32_t /*cookie*/, int32_t /*sensorId*/, + int32_t /*userId*/, int64_t /*challenge*/) { + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Session::enroll(int32_t /*cookie*/, const keymaster::HardwareAuthToken& /*hat*/, + const NativeHandle& /*previewSurface*/, + std::shared_ptr* + /*returnVal*/) { + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Session::authenticate(int32_t /*cookie*/, int64_t /*keystoreOperationId*/, + std::shared_ptr* return_val) { + if (cb_) { + cb_->onStateChanged(0, SessionState::AUTHENTICATING); + } + *return_val = SharedRefBase::make(); + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Session::detectInteraction( + int32_t /*cookie*/, std::shared_ptr* /*return_val*/) { + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Session::enumerateEnrollments(int32_t /*cookie*/) { + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Session::removeEnrollments(int32_t /*cookie*/, + const std::vector& /*enrollmentIds*/) { + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Session::getAuthenticatorId(int32_t /*cookie*/) { + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Session::invalidateAuthenticatorId(int32_t /*cookie*/) { + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Session::resetLockout(int32_t /*cookie*/, + const keymaster::HardwareAuthToken& /*hat*/) { + return ndk::ScopedAStatus::ok(); +} +} // namespace aidl::android::hardware::biometrics::face diff --git a/biometrics/face/aidl/default/Session.h b/biometrics/face/aidl/default/Session.h new file mode 100644 index 0000000000..a91ad8151b --- /dev/null +++ b/biometrics/face/aidl/default/Session.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include + +namespace aidl::android::hardware::biometrics::face { + +namespace common = aidl::android::hardware::biometrics::common; +namespace keymaster = aidl::android::hardware::keymaster; + +using aidl::android::hardware::common::NativeHandle; + +class Session : public BnSession { + public: + explicit Session(std::shared_ptr cb); + + ndk::ScopedAStatus generateChallenge(int32_t cookie, int32_t sensorId, int32_t userId, + int32_t timeoutSec) override; + + ndk::ScopedAStatus revokeChallenge(int32_t cookie, int32_t sensorId, int32_t userId, + int64_t challenge) override; + + ndk::ScopedAStatus enroll( + int32_t cookie, const keymaster::HardwareAuthToken& hat, + const NativeHandle& previewSurface, + std::shared_ptr* returnVal) override; + + ndk::ScopedAStatus authenticate( + int32_t cookie, int64_t keystoreOperationId, + std::shared_ptr* returnVal) override; + + ndk::ScopedAStatus detectInteraction( + int32_t cookie, std::shared_ptr* returnVal) override; + + ndk::ScopedAStatus enumerateEnrollments(int32_t cookie) override; + + ndk::ScopedAStatus removeEnrollments(int32_t cookie, + const std::vector& enrollmentIds) override; + + ndk::ScopedAStatus getAuthenticatorId(int32_t cookie) override; + + ndk::ScopedAStatus invalidateAuthenticatorId(int32_t cookie) override; + + ndk::ScopedAStatus resetLockout(int32_t cookie, + const keymaster::HardwareAuthToken& hat) override; + + private: + std::shared_ptr cb_; +}; + +} // namespace aidl::android::hardware::biometrics::face diff --git a/biometrics/face/aidl/default/face-default.rc b/biometrics/face/aidl/default/face-default.rc new file mode 100644 index 0000000000..f6499f0a09 --- /dev/null +++ b/biometrics/face/aidl/default/face-default.rc @@ -0,0 +1,5 @@ +service vendor.face-default /vendor/bin/hw/android.hardware.biometrics.face-service.example + class hal + user nobody + group nobody + diff --git a/biometrics/face/aidl/default/face-default.xml b/biometrics/face/aidl/default/face-default.xml new file mode 100644 index 0000000000..6915ad0a4d --- /dev/null +++ b/biometrics/face/aidl/default/face-default.xml @@ -0,0 +1,6 @@ + + + android.hardware.biometrics.face + IFace/default + + diff --git a/biometrics/face/aidl/default/main.cpp b/biometrics/face/aidl/default/main.cpp new file mode 100644 index 0000000000..80b153ea1f --- /dev/null +++ b/biometrics/face/aidl/default/main.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Face.h" + +#include +#include +#include + +using aidl::android::hardware::biometrics::face::Face; + +int main() { + LOG(INFO) << "Face HAL started"; + ABinderProcess_setThreadPoolMaxThreadCount(0); + std::shared_ptr hal = ndk::SharedRefBase::make(); + + const std::string instance = std::string(Face::descriptor) + "/default"; + binder_status_t status = AServiceManager_addService(hal->asBinder().get(), instance.c_str()); + CHECK(status == STATUS_OK); + + ABinderProcess_joinThreadPool(); + return EXIT_FAILURE; // should not reach +} -- GitLab From 5bce081dbed5150f2d7399dceedf76c22ad33f8e Mon Sep 17 00:00:00 2001 From: allenwtsu Date: Fri, 25 Sep 2020 17:58:01 +0800 Subject: [PATCH 208/790] [SMS] Define new SMS error code in HAL 1.6 Define 3 SMS failure causes. SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWD ACCESS_BARRED BLOCKED_DUE_TO_CALL Test: build pass Bug: 162364146 Change-Id: I3b8b3f238821f2a516f8590f90cba4d603d3783b --- radio/1.6/IRadio.hal | 64 ++ radio/1.6/IRadioResponse.hal | 136 +++- radio/1.6/types.hal | 25 + radio/1.6/vts/functional/Android.bp | 1 + .../1.6/vts/functional/radio_hidl_hal_api.cpp | 165 ++++- .../vts/functional/radio_hidl_hal_test.cpp | 2 +- .../functional/radio_hidl_hal_utils_v1_6.h | 606 +++++++++------ radio/1.6/vts/functional/radio_response.cpp | 689 +++++++++--------- .../1.6/vts/functional/vts_test_util_v1_6.cpp | 52 ++ radio/1.6/vts/functional/vts_test_util_v1_6.h | 28 + 10 files changed, 1205 insertions(+), 563 deletions(-) create mode 100644 radio/1.6/vts/functional/vts_test_util_v1_6.cpp create mode 100644 radio/1.6/vts/functional/vts_test_util_v1_6.h diff --git a/radio/1.6/IRadio.hal b/radio/1.6/IRadio.hal index c3f15f48ae..002b183635 100644 --- a/radio/1.6/IRadio.hal +++ b/radio/1.6/IRadio.hal @@ -16,6 +16,9 @@ package android.hardware.radio@1.6; + +import @1.0::CdmaSmsMessage; +import @1.0::GsmSmsMessage; import @1.2::DataRequestReason; import @1.5::IRadio; import @1.5::AccessNetwork; @@ -87,4 +90,65 @@ interface IRadio extends @1.5::IRadio { oneway setupDataCall_1_6(int32_t serial, AccessNetwork accessNetwork, DataProfileInfo dataProfileInfo, bool roamingAllowed, DataRequestReason reason, vec addresses, vec dnses); + + /** + * Send an SMS message + * + * @param serial Serial number of request. + * @param message GsmSmsMessage as defined in types.hal + * + * Response function is IRadioResponse.sendSmsResponse_1_6() + * + * Note this API is the same as the 1.0 + * + * Based on the return error, caller decides to resend if sending sms + * fails. RadioError:SMS_SEND_FAIL_RETRY means retry (i.e. error cause is 332) + * and RadioError:GENERIC_FAILURE means no retry (i.e. error cause is 500) + */ + oneway sendSms_1_6(int32_t serial, GsmSmsMessage message); + + /** + * Send an SMS message. Identical to sendSms_1_6, + * except that more messages are expected to be sent soon. If possible, + * keep SMS relay protocol link open (eg TS 27.005 AT+CMMS command) + * + * @param serial Serial number of request. + * @param message GsmSmsMessage as defined in types.hal + * + * Response function is IRadioResponse.sendSMSExpectMoreResponse_1_6() + * + * Note this API is the same as the 1.0 + * + * Based on the return error, caller decides to resend if sending sms + * fails. RadioError:SMS_SEND_FAIL_RETRY means retry (i.e. error cause is 332) + * and RadioError:GENERIC_FAILURE means no retry (i.e. error cause is 500) + */ + oneway sendSMSExpectMore_1_6(int32_t serial, GsmSmsMessage message); + + /** + * Send a CDMA SMS message + * + * @param serial Serial number of request. + * @param sms Cdma Sms to be sent described by CdmaSmsMessage in types.hal + * + * Response callback is IRadioResponse.sendCdmaSmsResponse_1_6() + * + * Note this API is the same as the 1.0 + * + */ + oneway sendCdmaSms_1_6(int32_t serial, CdmaSmsMessage sms); + + /** + * Send an SMS message. Identical to sendCdmaSms_1_6, + * except that more messages are expected to be sent soon. + * + * @param serial Serial number of request. + * @param sms Cdma Sms to be sent described by CdmaSmsMessage in types.hal + * + * Response callback is IRadioResponse.sendCdmaSMSExpectMoreResponse_1_6() + * + * Note this API is the same as the 1.5 + * + */ + oneway sendCdmaSmsExpectMore_1_6(int32_t serial, CdmaSmsMessage sms); }; diff --git a/radio/1.6/IRadioResponse.hal b/radio/1.6/IRadioResponse.hal index e91b9c1a5f..dfacd666d2 100644 --- a/radio/1.6/IRadioResponse.hal +++ b/radio/1.6/IRadioResponse.hal @@ -16,7 +16,8 @@ package android.hardware.radio@1.6; -import @1.0::RadioResponseInfo; +import @1.0::SendSmsResult; +import @1.6::RadioResponseInfo; import @1.5::IRadioResponse; import @1.6::SetupDataCallResult; @@ -54,4 +55,137 @@ interface IRadioResponse extends @1.5::IRadioResponse { * RadioError:SIM_ABSENT */ oneway getDataCallListResponse_1_6(RadioResponseInfo info, vec dcResponse); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param sms Response to sms sent as defined by SendSmsResult in types.hal + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SMS_SEND_FAIL_RETRY + * RadioError:NETWORK_REJECT + * RadioError:INVALID_STATE + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_MEMORY + * RadioError:REQUEST_RATE_LIMITED + * RadioError:INVALID_SMS_FORMAT + * RadioError:SYSTEM_ERR + * RadioError:ENCODING_ERR + * RadioError:INVALID_SMSC_ADDRESS + * RadioError:MODEM_ERR + * RadioError:NETWORK_ERR + * RadioError:INTERNAL_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_MODEM_STATE + * RadioError:NETWORK_NOT_READY + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:SIM_ABSENT + * RadioError:ACCESS_BARRED + * RadioError:BLOCKED_DUE_TO_CALL + */ + oneway sendSmsResponse_1_6(RadioResponseInfo info, SendSmsResult sms); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param sms Response to sms sent as defined by SendSmsResult in types.hal + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SMS_SEND_FAIL_RETRY + * RadioError:NETWORK_REJECT + * RadioError:INVALID_STATE + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_MEMORY + * RadioError:REQUEST_RATE_LIMITED + * RadioError:INVALID_SMS_FORMAT + * RadioError:SYSTEM_ERR + * RadioError:FDN_CHECK_FAILURE + * RadioError:ENCODING_ERR + * RadioError:INVALID_SMSC_ADDRESS + * RadioError:MODEM_ERR + * RadioError:NETWORK_ERR + * RadioError:INTERNAL_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_MODEM_STATE + * RadioError:NETWORK_NOT_READY + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:SIM_ABSENT + * RadioError:ACCESS_BARRED + * RadioError:BLOCKED_DUE_TO_CALL + */ + oneway sendSMSExpectMoreResponse_1_6(RadioResponseInfo info, SendSmsResult sms); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param sms Sms result struct as defined by SendSmsResult in types.hal + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:SMS_SEND_FAIL_RETRY + * RadioError:NETWORK_REJECT + * RadioError:INVALID_STATE + * RadioError:NO_MEMORY + * RadioError:REQUEST_RATE_LIMITED + * RadioError:INVALID_SMS_FORMAT + * RadioError:SYSTEM_ERR + * RadioError:FDN_CHECK_FAILURE + * RadioError:MODEM_ERR + * RadioError:NETWORK_ERR + * RadioError:ENCODING_ERR + * RadioError:INVALID_SMSC_ADDRESS + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:ENCODING_ERR + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:SIM_ABSENT + * RadioError:SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED + * RadioError:ACCESS_BARRED + * RadioError:BLOCKED_DUE_TO_CALL + */ + oneway sendCdmaSmsResponse_1_6(RadioResponseInfo info, SendSmsResult sms); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param sms Response to sms sent as defined by SendSmsResult in types.hal + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SMS_SEND_FAIL_RETRY + * RadioError:NETWORK_REJECT + * RadioError:INVALID_STATE + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_MEMORY + * RadioError:REQUEST_RATE_LIMITED + * RadioError:INVALID_SMS_FORMAT + * RadioError:SYSTEM_ERR + * RadioError:FDN_CHECK_FAILURE + * RadioError:ENCODING_ERR + * RadioError:INVALID_SMSC_ADDRESS + * RadioError:MODEM_ERR + * RadioError:NETWORK_ERR + * RadioError:INTERNAL_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_MODEM_STATE + * RadioError:NETWORK_NOT_READY + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:SIM_ABSENT + * RadioError:SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED + * RadioError:ACCESS_BARRED + * RadioError:BLOCKED_DUE_TO_CALL + */ + oneway sendCdmaSmsExpectMoreResponse_1_6(RadioResponseInfo info, SendSmsResult sms); }; diff --git a/radio/1.6/types.hal b/radio/1.6/types.hal index 4bd3cd6f35..eee958f89f 100644 --- a/radio/1.6/types.hal +++ b/radio/1.6/types.hal @@ -16,6 +16,8 @@ package android.hardware.radio@1.6; +import @1.0::RadioError; +import @1.0::RadioResponseType; import @1.5::SetupDataCallResult; import android.hidl.safe_union@1.0::Monostate; @@ -98,6 +100,29 @@ enum QosPortRange : int32_t { MAX = 65535 }; +enum RadioError : @1.0::RadioError { + /** 1X voice and SMS are not allowed simulteneously. */ + SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED = 67, + + /** Access is barred. */ + ACCESS_BARRED = 68, + + /** + * SMS is blocked due to call control, e.g., resource unavailable + * in the SMR entity. + */ + BLOCKED_DUE_TO_CALL = 69 +}; + +/** + * Overwritten from @1.0::RadioResponseInfo in order to update the RadioError to 1.6 version. + */ +struct RadioResponseInfo { + RadioResponseType type; // Response type + int32_t serial; // Serial number of the request + RadioError error; // Response error +}; + /** * Defines range of ports. start and end are the first and last port numbers * (inclusive) in the range. Both start and end are in QosPortRange.MIN to diff --git a/radio/1.6/vts/functional/Android.bp b/radio/1.6/vts/functional/Android.bp index a6cfc6f631..5fd30ce78f 100644 --- a/radio/1.6/vts/functional/Android.bp +++ b/radio/1.6/vts/functional/Android.bp @@ -23,6 +23,7 @@ cc_test { "radio_response.cpp", "radio_indication.cpp", "VtsHalRadioV1_6TargetTest.cpp", + "vts_test_util_v1_6.cpp", ], static_libs: [ "RadioVtsTestUtilBase", diff --git a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp index 0bfce4d0bf..300f748476 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp +++ b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp @@ -65,12 +65,165 @@ TEST_P(RadioHidlTest_v1_6, setupDataCall_1_6) { EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial); if (cardStatus.base.base.base.cardState == CardState::ABSENT) { - ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_6->rspInfo.error, - {RadioError::SIM_ABSENT, RadioError::RADIO_NOT_AVAILABLE, - RadioError::OP_NOT_ALLOWED_BEFORE_REG_TO_NW})); + ASSERT_TRUE(CheckAnyOfErrors( + radioRsp_v1_6->rspInfo.error, + {::android::hardware::radio::V1_6::RadioError::SIM_ABSENT, + ::android::hardware::radio::V1_6::RadioError::RADIO_NOT_AVAILABLE, + ::android::hardware::radio::V1_6::RadioError::OP_NOT_ALLOWED_BEFORE_REG_TO_NW})); } else if (cardStatus.base.base.base.cardState == CardState::PRESENT) { - ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_6->rspInfo.error, - {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, - RadioError::OP_NOT_ALLOWED_BEFORE_REG_TO_NW})); + ASSERT_TRUE(CheckAnyOfErrors( + radioRsp_v1_6->rspInfo.error, + {::android::hardware::radio::V1_6::RadioError::NONE, + ::android::hardware::radio::V1_6::RadioError::RADIO_NOT_AVAILABLE, + ::android::hardware::radio::V1_6::RadioError::OP_NOT_ALLOWED_BEFORE_REG_TO_NW})); + } +} + +/* + * Test IRadio_1_6.sendSms() for the response returned. + */ +TEST_P(RadioHidlTest_v1_6, sendSms_1_6) { + LOG(DEBUG) << "sendSms"; + serial = GetRandomSerialNumber(); + GsmSmsMessage msg; + msg.smscPdu = ""; + msg.pdu = "01000b916105770203f3000006d4f29c3e9b01"; + + radio_v1_6->sendSms(serial, msg); + + EXPECT_EQ(std::cv_status::no_timeout, wait()); + EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type); + EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial); + + if (cardStatus.base.base.base.cardState == CardState::ABSENT) { + ASSERT_TRUE(CheckAnyOfErrors( + radioRsp_v1_6->rspInfo.error, + {::android::hardware::radio::V1_6::RadioError::INVALID_ARGUMENTS, + ::android::hardware::radio::V1_6::RadioError::INVALID_STATE, + ::android::hardware::radio::V1_6::RadioError::SIM_ABSENT}, + CHECK_GENERAL_ERROR)); + EXPECT_EQ(0, radioRsp_v1_6->sendSmsResult.errorCode); + } + LOG(DEBUG) << "sendSms finished"; +} + +/* + * Test IRadio_1_6.sendSMSExpectMore() for the response returned. + */ +TEST_P(RadioHidlTest_v1_6, sendSMSExpectMore_1_6) { + LOG(DEBUG) << "sendSMSExpectMore"; + serial = GetRandomSerialNumber(); + GsmSmsMessage msg; + msg.smscPdu = ""; + msg.pdu = "01000b916105770203f3000006d4f29c3e9b01"; + + radio_v1_6->sendSMSExpectMore(serial, msg); + + EXPECT_EQ(std::cv_status::no_timeout, wait()); + EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type); + EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial); + + if (cardStatus.base.base.base.cardState == CardState::ABSENT) { + ASSERT_TRUE(CheckAnyOfErrors( + radioRsp_v1_6->rspInfo.error, + {::android::hardware::radio::V1_6::RadioError::INVALID_ARGUMENTS, + ::android::hardware::radio::V1_6::RadioError::INVALID_STATE, + ::android::hardware::radio::V1_6::RadioError::SIM_ABSENT}, + CHECK_GENERAL_ERROR)); + } + LOG(DEBUG) << "sendSMSExpectMore finished"; +} + +/* + * Test IRadio_1_6.sendCdmaSms() for the response returned. + */ +TEST_P(RadioHidlTest_v1_6, sendCdmaSms_1_6) { + LOG(DEBUG) << "sendCdmaSms"; + serial = GetRandomSerialNumber(); + + // Create a CdmaSmsAddress + CdmaSmsAddress cdmaSmsAddress; + cdmaSmsAddress.digitMode = CdmaSmsDigitMode::FOUR_BIT; + cdmaSmsAddress.numberMode = CdmaSmsNumberMode::NOT_DATA_NETWORK; + cdmaSmsAddress.numberType = CdmaSmsNumberType::UNKNOWN; + cdmaSmsAddress.numberPlan = CdmaSmsNumberPlan::UNKNOWN; + cdmaSmsAddress.digits = (std::vector){11, 1, 6, 5, 10, 7, 7, 2, 10, 3, 10, 3}; + + // Create a CdmaSmsSubAddress + CdmaSmsSubaddress cdmaSmsSubaddress; + cdmaSmsSubaddress.subaddressType = CdmaSmsSubaddressType::NSAP; + cdmaSmsSubaddress.odd = false; + cdmaSmsSubaddress.digits = (std::vector){}; + + // Create a CdmaSmsMessage + android::hardware::radio::V1_0::CdmaSmsMessage cdmaSmsMessage; + cdmaSmsMessage.teleserviceId = 4098; + cdmaSmsMessage.isServicePresent = false; + cdmaSmsMessage.serviceCategory = 0; + cdmaSmsMessage.address = cdmaSmsAddress; + cdmaSmsMessage.subAddress = cdmaSmsSubaddress; + cdmaSmsMessage.bearerData = + (std::vector){15, 0, 3, 32, 3, 16, 1, 8, 16, 53, 76, 68, 6, 51, 106, 0}; + + radio_v1_6->sendCdmaSms(serial, cdmaSmsMessage); + + EXPECT_EQ(std::cv_status::no_timeout, wait()); + EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type); + EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial); + + if (cardStatus.base.base.base.cardState == CardState::ABSENT) { + ASSERT_TRUE(CheckAnyOfErrors( + radioRsp_v1_6->rspInfo.error, + {::android::hardware::radio::V1_6::RadioError::INVALID_ARGUMENTS, + ::android::hardware::radio::V1_6::RadioError::INVALID_STATE, + ::android::hardware::radio::V1_6::RadioError::SIM_ABSENT}, + CHECK_GENERAL_ERROR)); + } + LOG(DEBUG) << "sendCdmaSms finished"; +} + +/* + * Test IRadio_1_6.sendCdmaSmsExpectMore() for the response returned. + */ +TEST_P(RadioHidlTest_v1_6, sendCdmaSmsExpectMore_1_6) { + serial = GetRandomSerialNumber(); + + // Create a CdmaSmsAddress + CdmaSmsAddress cdmaSmsAddress; + cdmaSmsAddress.digitMode = CdmaSmsDigitMode::FOUR_BIT; + cdmaSmsAddress.numberMode = CdmaSmsNumberMode::NOT_DATA_NETWORK; + cdmaSmsAddress.numberType = CdmaSmsNumberType::UNKNOWN; + cdmaSmsAddress.numberPlan = CdmaSmsNumberPlan::UNKNOWN; + cdmaSmsAddress.digits = (std::vector){11, 1, 6, 5, 10, 7, 7, 2, 10, 3, 10, 3}; + + // Create a CdmaSmsSubAddress + CdmaSmsSubaddress cdmaSmsSubaddress; + cdmaSmsSubaddress.subaddressType = CdmaSmsSubaddressType::NSAP; + cdmaSmsSubaddress.odd = false; + cdmaSmsSubaddress.digits = (std::vector){}; + + // Create a CdmaSmsMessage + android::hardware::radio::V1_0::CdmaSmsMessage cdmaSmsMessage; + cdmaSmsMessage.teleserviceId = 4098; + cdmaSmsMessage.isServicePresent = false; + cdmaSmsMessage.serviceCategory = 0; + cdmaSmsMessage.address = cdmaSmsAddress; + cdmaSmsMessage.subAddress = cdmaSmsSubaddress; + cdmaSmsMessage.bearerData = + (std::vector){15, 0, 3, 32, 3, 16, 1, 8, 16, 53, 76, 68, 6, 51, 106, 0}; + + radio_v1_6->sendCdmaSmsExpectMore(serial, cdmaSmsMessage); + + EXPECT_EQ(std::cv_status::no_timeout, wait()); + EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type); + EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial); + + if (cardStatus.base.base.base.cardState == CardState::ABSENT) { + ASSERT_TRUE(CheckAnyOfErrors( + radioRsp_v1_6->rspInfo.error, + {::android::hardware::radio::V1_6::RadioError::INVALID_ARGUMENTS, + ::android::hardware::radio::V1_6::RadioError::INVALID_STATE, + ::android::hardware::radio::V1_6::RadioError::SIM_ABSENT}, + CHECK_GENERAL_ERROR)); } } diff --git a/radio/1.6/vts/functional/radio_hidl_hal_test.cpp b/radio/1.6/vts/functional/radio_hidl_hal_test.cpp index 114fd1a551..3d0e71cf8b 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_test.cpp +++ b/radio/1.6/vts/functional/radio_hidl_hal_test.cpp @@ -33,7 +33,7 @@ void RadioHidlTest_v1_6::SetUp() { getDataCallList(); EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type); EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial); - EXPECT_EQ(RadioError::NONE, radioRsp_v1_6->rspInfo.error); + EXPECT_EQ(::android::hardware::radio::V1_6::RadioError::NONE, radioRsp_v1_6->rspInfo.error); sp<::android::hardware::radio::config::V1_1::IRadioConfig> radioConfig = ::android::hardware::radio::config::V1_1::IRadioConfig::getService(); diff --git a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h index 95a2d09beb..16fe8c83b2 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h +++ b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h @@ -33,7 +33,7 @@ #include #include -#include "vts_test_util.h" +#include "vts_test_util_v1_6.h" using namespace ::android::hardware::radio::V1_6; using namespace ::android::hardware::radio::V1_5; @@ -66,11 +66,14 @@ class RadioResponse_v1_6 : public ::android::hardware::radio::V1_6::IRadioRespon public: hidl_vec radioBandModes; - RadioResponseInfo rspInfo; + ::android::hardware::radio::V1_6::RadioResponseInfo rspInfo; // Call hidl_vec<::android::hardware::radio::V1_2::Call> currentCalls; + // Sms + SendSmsResult sendSmsResult; + // Modem bool isModemEnabled; bool enableModemResponseToggle; @@ -99,516 +102,665 @@ class RadioResponse_v1_6 : public ::android::hardware::radio::V1_6::IRadioRespon virtual ~RadioResponse_v1_6() = default; Return getIccCardStatusResponse( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, const ::android::hardware::radio::V1_0::CardStatus& cardStatus); - Return supplyIccPinForAppResponse(const RadioResponseInfo& info, - int32_t remainingRetries); + Return supplyIccPinForAppResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, + int32_t remainingRetries); - Return supplyIccPukForAppResponse(const RadioResponseInfo& info, - int32_t remainingRetries); + Return supplyIccPukForAppResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, + int32_t remainingRetries); - Return supplyIccPin2ForAppResponse(const RadioResponseInfo& info, - int32_t remainingRetries); + Return supplyIccPin2ForAppResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, + int32_t remainingRetries); - Return supplyIccPuk2ForAppResponse(const RadioResponseInfo& info, - int32_t remainingRetries); + Return supplyIccPuk2ForAppResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, + int32_t remainingRetries); - Return changeIccPinForAppResponse(const RadioResponseInfo& info, - int32_t remainingRetries); + Return changeIccPinForAppResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, + int32_t remainingRetries); - Return changeIccPin2ForAppResponse(const RadioResponseInfo& info, - int32_t remainingRetries); + Return changeIccPin2ForAppResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, + int32_t remainingRetries); - Return supplyNetworkDepersonalizationResponse(const RadioResponseInfo& info, - int32_t remainingRetries); + Return supplyNetworkDepersonalizationResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, + int32_t remainingRetries); Return getCurrentCallsResponse( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, const ::android::hardware::hidl_vec<::android::hardware::radio::V1_0::Call>& calls); - Return dialResponse(const RadioResponseInfo& info); + Return dialResponse(const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return getIMSIForAppResponse(const RadioResponseInfo& info, - const ::android::hardware::hidl_string& imsi); + Return getIMSIForAppResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, + const ::android::hardware::hidl_string& imsi); - Return hangupConnectionResponse(const RadioResponseInfo& info); + Return hangupConnectionResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return hangupWaitingOrBackgroundResponse(const RadioResponseInfo& info); + Return hangupWaitingOrBackgroundResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return hangupForegroundResumeBackgroundResponse(const RadioResponseInfo& info); + Return hangupForegroundResumeBackgroundResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return switchWaitingOrHoldingAndActiveResponse(const RadioResponseInfo& info); + Return switchWaitingOrHoldingAndActiveResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return conferenceResponse(const RadioResponseInfo& info); + Return conferenceResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return rejectCallResponse(const RadioResponseInfo& info); + Return rejectCallResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return getLastCallFailCauseResponse(const RadioResponseInfo& info, - const LastCallFailCauseInfo& failCauseInfo); + Return getLastCallFailCauseResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, + const LastCallFailCauseInfo& failCauseInfo); Return getSignalStrengthResponse( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, const ::android::hardware::radio::V1_0::SignalStrength& sigStrength); Return getVoiceRegistrationStateResponse( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, const ::android::hardware::radio::V1_0::VoiceRegStateResult& voiceRegResponse); Return getDataRegistrationStateResponse( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, const ::android::hardware::radio::V1_0::DataRegStateResult& dataRegResponse); - Return getOperatorResponse(const RadioResponseInfo& info, - const ::android::hardware::hidl_string& longName, - const ::android::hardware::hidl_string& shortName, - const ::android::hardware::hidl_string& numeric); + Return getOperatorResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, + const ::android::hardware::hidl_string& longName, + const ::android::hardware::hidl_string& shortName, + const ::android::hardware::hidl_string& numeric); - Return setRadioPowerResponse(const RadioResponseInfo& info); + Return setRadioPowerResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return sendDtmfResponse(const RadioResponseInfo& info); + Return sendDtmfResponse(const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return sendSmsResponse(const RadioResponseInfo& info, const SendSmsResult& sms); + Return sendSmsResponse(const ::android::hardware::radio::V1_0::RadioResponseInfo& info, + const SendSmsResult& sms); - Return sendSMSExpectMoreResponse(const RadioResponseInfo& info, const SendSmsResult& sms); + Return sendSMSExpectMoreResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, + const SendSmsResult& sms); Return setupDataCallResponse( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, const android::hardware::radio::V1_0::SetupDataCallResult& dcResponse); - Return iccIOForAppResponse(const RadioResponseInfo& info, const IccIoResult& iccIo); + Return iccIOForAppResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, + const IccIoResult& iccIo); - Return sendUssdResponse(const RadioResponseInfo& info); + Return sendUssdResponse(const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return cancelPendingUssdResponse(const RadioResponseInfo& info); + Return cancelPendingUssdResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return getClirResponse(const RadioResponseInfo& info, int32_t n, int32_t m); + Return getClirResponse(const ::android::hardware::radio::V1_0::RadioResponseInfo& info, + int32_t n, int32_t m); - Return setClirResponse(const RadioResponseInfo& info); + Return setClirResponse(const ::android::hardware::radio::V1_0::RadioResponseInfo& info); Return getCallForwardStatusResponse( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, const ::android::hardware::hidl_vec& call_forwardInfos); - Return setCallForwardResponse(const RadioResponseInfo& info); + Return setCallForwardResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return getCallWaitingResponse(const RadioResponseInfo& info, bool enable, - int32_t serviceClass); + Return getCallWaitingResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, bool enable, + int32_t serviceClass); - Return setCallWaitingResponse(const RadioResponseInfo& info); + Return setCallWaitingResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return acknowledgeLastIncomingGsmSmsResponse(const RadioResponseInfo& info); + Return acknowledgeLastIncomingGsmSmsResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return acceptCallResponse(const RadioResponseInfo& info); + Return acceptCallResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return deactivateDataCallResponse(const RadioResponseInfo& info); + Return deactivateDataCallResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return getFacilityLockForAppResponse(const RadioResponseInfo& info, int32_t response); + Return getFacilityLockForAppResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, int32_t response); - Return setFacilityLockForAppResponse(const RadioResponseInfo& info, int32_t retry); + Return setFacilityLockForAppResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, int32_t retry); - Return setBarringPasswordResponse(const RadioResponseInfo& info); + Return setBarringPasswordResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return getNetworkSelectionModeResponse(const RadioResponseInfo& info, bool manual); + Return getNetworkSelectionModeResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, bool manual); - Return setNetworkSelectionModeAutomaticResponse(const RadioResponseInfo& info); + Return setNetworkSelectionModeAutomaticResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return setNetworkSelectionModeManualResponse(const RadioResponseInfo& info); + Return setNetworkSelectionModeManualResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); Return getAvailableNetworksResponse( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, const ::android::hardware::hidl_vec& networkInfos); - Return startDtmfResponse(const RadioResponseInfo& info); + Return startDtmfResponse(const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return stopDtmfResponse(const RadioResponseInfo& info); + Return stopDtmfResponse(const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return getBasebandVersionResponse(const RadioResponseInfo& info, - const ::android::hardware::hidl_string& version); + Return getBasebandVersionResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, + const ::android::hardware::hidl_string& version); - Return separateConnectionResponse(const RadioResponseInfo& info); + Return separateConnectionResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return setMuteResponse(const RadioResponseInfo& info); + Return setMuteResponse(const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return getMuteResponse(const RadioResponseInfo& info, bool enable); + Return getMuteResponse(const ::android::hardware::radio::V1_0::RadioResponseInfo& info, + bool enable); - Return getClipResponse(const RadioResponseInfo& info, ClipStatus status); + Return getClipResponse(const ::android::hardware::radio::V1_0::RadioResponseInfo& info, + ClipStatus status); Return getDataCallListResponse( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, const ::android::hardware::hidl_vec< android::hardware::radio::V1_0::SetupDataCallResult>& dcResponse); - Return sendOemRilRequestRawResponse(const RadioResponseInfo& info, - const ::android::hardware::hidl_vec& data); + Return sendOemRilRequestRawResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, + const ::android::hardware::hidl_vec& data); Return sendOemRilRequestStringsResponse( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, const ::android::hardware::hidl_vec<::android::hardware::hidl_string>& data); - Return setSuppServiceNotificationsResponse(const RadioResponseInfo& info); + Return setSuppServiceNotificationsResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return writeSmsToSimResponse(const RadioResponseInfo& info, int32_t index); + Return writeSmsToSimResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, int32_t index); - Return deleteSmsOnSimResponse(const RadioResponseInfo& info); + Return deleteSmsOnSimResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return setBandModeResponse(const RadioResponseInfo& info); + Return setBandModeResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); Return getAvailableBandModesResponse( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, const ::android::hardware::hidl_vec& bandModes); - Return sendEnvelopeResponse(const RadioResponseInfo& info, - const ::android::hardware::hidl_string& commandResponse); + Return sendEnvelopeResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, + const ::android::hardware::hidl_string& commandResponse); - Return sendTerminalResponseToSimResponse(const RadioResponseInfo& info); + Return sendTerminalResponseToSimResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return handleStkCallSetupRequestFromSimResponse(const RadioResponseInfo& info); + Return handleStkCallSetupRequestFromSimResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return explicitCallTransferResponse(const RadioResponseInfo& info); + Return explicitCallTransferResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return setPreferredNetworkTypeResponse(const RadioResponseInfo& info); + Return setPreferredNetworkTypeResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return getPreferredNetworkTypeResponse(const RadioResponseInfo& info, - PreferredNetworkType nwType); + Return getPreferredNetworkTypeResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, + PreferredNetworkType nwType); Return getNeighboringCidsResponse( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, const ::android::hardware::hidl_vec& cells); - Return setLocationUpdatesResponse(const RadioResponseInfo& info); + Return setLocationUpdatesResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return setCdmaSubscriptionSourceResponse(const RadioResponseInfo& info); + Return setCdmaSubscriptionSourceResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return setCdmaRoamingPreferenceResponse(const RadioResponseInfo& info); + Return setCdmaRoamingPreferenceResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return getCdmaRoamingPreferenceResponse(const RadioResponseInfo& info, - CdmaRoamingType type); + Return getCdmaRoamingPreferenceResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, CdmaRoamingType type); - Return setTTYModeResponse(const RadioResponseInfo& info); + Return setTTYModeResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return getTTYModeResponse(const RadioResponseInfo& info, TtyMode mode); + Return getTTYModeResponse(const ::android::hardware::radio::V1_0::RadioResponseInfo& info, + TtyMode mode); - Return setPreferredVoicePrivacyResponse(const RadioResponseInfo& info); + Return setPreferredVoicePrivacyResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return getPreferredVoicePrivacyResponse(const RadioResponseInfo& info, bool enable); + Return getPreferredVoicePrivacyResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, bool enable); - Return sendCDMAFeatureCodeResponse(const RadioResponseInfo& info); + Return sendCDMAFeatureCodeResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return sendBurstDtmfResponse(const RadioResponseInfo& info); + Return sendBurstDtmfResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return sendCdmaSmsResponse(const RadioResponseInfo& info, const SendSmsResult& sms); + Return sendCdmaSmsResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, + const SendSmsResult& sms); - Return acknowledgeLastIncomingCdmaSmsResponse(const RadioResponseInfo& info); + Return acknowledgeLastIncomingCdmaSmsResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); Return getGsmBroadcastConfigResponse( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, const ::android::hardware::hidl_vec& configs); - Return setGsmBroadcastConfigResponse(const RadioResponseInfo& info); + Return setGsmBroadcastConfigResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return setGsmBroadcastActivationResponse(const RadioResponseInfo& info); + Return setGsmBroadcastActivationResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); Return getCdmaBroadcastConfigResponse( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, const ::android::hardware::hidl_vec& configs); - Return setCdmaBroadcastConfigResponse(const RadioResponseInfo& info); + Return setCdmaBroadcastConfigResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return setCdmaBroadcastActivationResponse(const RadioResponseInfo& info); + Return setCdmaBroadcastActivationResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return getCDMASubscriptionResponse(const RadioResponseInfo& info, - const ::android::hardware::hidl_string& mdn, - const ::android::hardware::hidl_string& hSid, - const ::android::hardware::hidl_string& hNid, - const ::android::hardware::hidl_string& min, - const ::android::hardware::hidl_string& prl); + Return getCDMASubscriptionResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, + const ::android::hardware::hidl_string& mdn, + const ::android::hardware::hidl_string& hSid, + const ::android::hardware::hidl_string& hNid, + const ::android::hardware::hidl_string& min, + const ::android::hardware::hidl_string& prl); - Return writeSmsToRuimResponse(const RadioResponseInfo& info, uint32_t index); + Return writeSmsToRuimResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, uint32_t index); - Return deleteSmsOnRuimResponse(const RadioResponseInfo& info); + Return deleteSmsOnRuimResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return getDeviceIdentityResponse(const RadioResponseInfo& info, - const ::android::hardware::hidl_string& imei, - const ::android::hardware::hidl_string& imeisv, - const ::android::hardware::hidl_string& esn, - const ::android::hardware::hidl_string& meid); + Return getDeviceIdentityResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, + const ::android::hardware::hidl_string& imei, + const ::android::hardware::hidl_string& imeisv, + const ::android::hardware::hidl_string& esn, + const ::android::hardware::hidl_string& meid); - Return exitEmergencyCallbackModeResponse(const RadioResponseInfo& info); + Return exitEmergencyCallbackModeResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return getSmscAddressResponse(const RadioResponseInfo& info, - const ::android::hardware::hidl_string& smsc); + Return getSmscAddressResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, + const ::android::hardware::hidl_string& smsc); - Return setSmscAddressResponse(const RadioResponseInfo& info); + Return setSmscAddressResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return reportSmsMemoryStatusResponse(const RadioResponseInfo& info); + Return reportSmsMemoryStatusResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return reportStkServiceIsRunningResponse(const RadioResponseInfo& info); + Return reportStkServiceIsRunningResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return getCdmaSubscriptionSourceResponse(const RadioResponseInfo& info, - CdmaSubscriptionSource source); + Return getCdmaSubscriptionSourceResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, + CdmaSubscriptionSource source); Return requestIsimAuthenticationResponse( - const RadioResponseInfo& info, const ::android::hardware::hidl_string& response); + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, + const ::android::hardware::hidl_string& response); - Return acknowledgeIncomingGsmSmsWithPduResponse(const RadioResponseInfo& info); + Return acknowledgeIncomingGsmSmsWithPduResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return sendEnvelopeWithStatusResponse(const RadioResponseInfo& info, - const IccIoResult& iccIo); + Return sendEnvelopeWithStatusResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, + const IccIoResult& iccIo); Return getVoiceRadioTechnologyResponse( - const RadioResponseInfo& info, ::android::hardware::radio::V1_0::RadioTechnology rat); + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, + ::android::hardware::radio::V1_0::RadioTechnology rat); Return getCellInfoListResponse( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, const ::android::hardware::hidl_vec<::android::hardware::radio::V1_0::CellInfo>& cellInfo); - Return setCellInfoListRateResponse(const RadioResponseInfo& info); + Return setCellInfoListRateResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return setInitialAttachApnResponse(const RadioResponseInfo& info); + Return setInitialAttachApnResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return getImsRegistrationStateResponse(const RadioResponseInfo& info, bool isRegistered, - RadioTechnologyFamily ratFamily); + Return getImsRegistrationStateResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, bool isRegistered, + RadioTechnologyFamily ratFamily); - Return sendImsSmsResponse(const RadioResponseInfo& info, const SendSmsResult& sms); + Return sendImsSmsResponse(const ::android::hardware::radio::V1_0::RadioResponseInfo& info, + const SendSmsResult& sms); - Return iccTransmitApduBasicChannelResponse(const RadioResponseInfo& info, - const IccIoResult& result); + Return iccTransmitApduBasicChannelResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, + const IccIoResult& result); Return iccOpenLogicalChannelResponse( - const RadioResponseInfo& info, int32_t channelId, + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, int32_t channelId, const ::android::hardware::hidl_vec& selectResponse); - Return iccCloseLogicalChannelResponse(const RadioResponseInfo& info); + Return iccCloseLogicalChannelResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return iccTransmitApduLogicalChannelResponse(const RadioResponseInfo& info, - const IccIoResult& result); + Return iccTransmitApduLogicalChannelResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, + const IccIoResult& result); - Return nvReadItemResponse(const RadioResponseInfo& info, + Return nvReadItemResponse(const ::android::hardware::radio::V1_0::RadioResponseInfo& info, const ::android::hardware::hidl_string& result); - Return nvWriteItemResponse(const RadioResponseInfo& info); + Return nvWriteItemResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return nvWriteCdmaPrlResponse(const RadioResponseInfo& info); + Return nvWriteCdmaPrlResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return nvResetConfigResponse(const RadioResponseInfo& info); + Return nvResetConfigResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return setUiccSubscriptionResponse(const RadioResponseInfo& info); + Return setUiccSubscriptionResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return setDataAllowedResponse(const RadioResponseInfo& info); + Return setDataAllowedResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); Return getHardwareConfigResponse( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, const ::android::hardware::hidl_vec& config); - Return requestIccSimAuthenticationResponse(const RadioResponseInfo& info, - const IccIoResult& result); + Return requestIccSimAuthenticationResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, + const IccIoResult& result); - Return setDataProfileResponse(const RadioResponseInfo& info); + Return setDataProfileResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return requestShutdownResponse(const RadioResponseInfo& info); + Return requestShutdownResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); Return getRadioCapabilityResponse( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, const android::hardware::radio::V1_0::RadioCapability& rc); Return setRadioCapabilityResponse( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, const android::hardware::radio::V1_0::RadioCapability& rc); - Return startLceServiceResponse(const RadioResponseInfo& info, - const LceStatusInfo& statusInfo); + Return startLceServiceResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, + const LceStatusInfo& statusInfo); - Return stopLceServiceResponse(const RadioResponseInfo& info, - const LceStatusInfo& statusInfo); + Return stopLceServiceResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, + const LceStatusInfo& statusInfo); - Return pullLceDataResponse(const RadioResponseInfo& info, const LceDataInfo& lceInfo); + Return pullLceDataResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, + const LceDataInfo& lceInfo); - Return getModemActivityInfoResponse(const RadioResponseInfo& info, - const ActivityStatsInfo& activityInfo); + Return getModemActivityInfoResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, + const ActivityStatsInfo& activityInfo); - Return setAllowedCarriersResponse(const RadioResponseInfo& info, int32_t numAllowed); + Return setAllowedCarriersResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, int32_t numAllowed); - Return getAllowedCarriersResponse(const RadioResponseInfo& info, bool allAllowed, - const CarrierRestrictions& carriers); + Return getAllowedCarriersResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, bool allAllowed, + const CarrierRestrictions& carriers); - Return sendDeviceStateResponse(const RadioResponseInfo& info); + Return sendDeviceStateResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return setIndicationFilterResponse(const RadioResponseInfo& info); + Return setIndicationFilterResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return setSimCardPowerResponse(const RadioResponseInfo& info); + Return setSimCardPowerResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); Return acknowledgeRequest(int32_t serial); /* 1.1 Api */ - Return setCarrierInfoForImsiEncryptionResponse(const RadioResponseInfo& info); + Return setCarrierInfoForImsiEncryptionResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return setSimCardPowerResponse_1_1(const RadioResponseInfo& info); + Return setSimCardPowerResponse_1_1( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return startNetworkScanResponse(const RadioResponseInfo& info); + Return startNetworkScanResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return stopNetworkScanResponse(const RadioResponseInfo& info); + Return stopNetworkScanResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return startKeepaliveResponse(const RadioResponseInfo& info, - const KeepaliveStatus& status); + Return startKeepaliveResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, + const KeepaliveStatus& status); - Return stopKeepaliveResponse(const RadioResponseInfo& info); + Return stopKeepaliveResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); /* 1.2 Api */ - Return setSignalStrengthReportingCriteriaResponse(const RadioResponseInfo& info); + Return setSignalStrengthReportingCriteriaResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return setLinkCapacityReportingCriteriaResponse(const RadioResponseInfo& info); + Return setLinkCapacityReportingCriteriaResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); Return getIccCardStatusResponse_1_2( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, const ::android::hardware::radio::V1_2::CardStatus& card_status); Return getCurrentCallsResponse_1_2( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, const ::android::hardware::hidl_vec<::android::hardware::radio::V1_2::Call>& calls); Return getSignalStrengthResponse_1_2( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, const ::android::hardware::radio::V1_2::SignalStrength& sig_strength); Return getSignalStrengthResponse_1_4( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, const ::android::hardware::radio::V1_4::SignalStrength& sig_strength); Return getCellInfoListResponse_1_2( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, const ::android::hardware::hidl_vec<::android::hardware::radio::V1_2::CellInfo>& cellInfo); Return getVoiceRegistrationStateResponse_1_2( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, const ::android::hardware::radio::V1_2::VoiceRegStateResult& voiceRegResponse); Return getDataRegistrationStateResponse_1_2( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, const ::android::hardware::radio::V1_2::DataRegStateResult& dataRegResponse); /* 1.3 Api */ - Return setSystemSelectionChannelsResponse(const RadioResponseInfo& info); + Return setSystemSelectionChannelsResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return enableModemResponse(const RadioResponseInfo& info); + Return enableModemResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return getModemStackStatusResponse(const RadioResponseInfo& info, const bool enabled); + Return getModemStackStatusResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, const bool enabled); /* 1.4 Api */ - Return emergencyDialResponse(const RadioResponseInfo& info); + Return emergencyDialResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return startNetworkScanResponse_1_4(const RadioResponseInfo& info); + Return startNetworkScanResponse_1_4( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); Return getCellInfoListResponse_1_4( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, const ::android::hardware::hidl_vec<::android::hardware::radio::V1_4::CellInfo>& cellInfo); Return getDataRegistrationStateResponse_1_4( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, const ::android::hardware::radio::V1_4::DataRegStateResult& dataRegResponse); Return getIccCardStatusResponse_1_4( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, const ::android::hardware::radio::V1_4::CardStatus& card_status); Return getPreferredNetworkTypeBitmapResponse( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, const ::android::hardware::hidl_bitfield< ::android::hardware::radio::V1_4::RadioAccessFamily> networkTypeBitmap); - Return setPreferredNetworkTypeBitmapResponse(const RadioResponseInfo& info); + Return setPreferredNetworkTypeBitmapResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); Return getDataCallListResponse_1_4( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, const ::android::hardware::hidl_vec< ::android::hardware::radio::V1_4::SetupDataCallResult>& dcResponse); Return setupDataCallResponse_1_4( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, const android::hardware::radio::V1_4::SetupDataCallResult& dcResponse); - Return setAllowedCarriersResponse_1_4(const RadioResponseInfo& info); + Return setAllowedCarriersResponse_1_4( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return getAllowedCarriersResponse_1_4(const RadioResponseInfo& info, - const CarrierRestrictionsWithPriority& carriers, - SimLockMultiSimPolicy multiSimPolicy); + Return getAllowedCarriersResponse_1_4( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, + const CarrierRestrictionsWithPriority& carriers, SimLockMultiSimPolicy multiSimPolicy); /* 1.5 Api */ - Return setSignalStrengthReportingCriteriaResponse_1_5(const RadioResponseInfo& info); + Return setSignalStrengthReportingCriteriaResponse_1_5( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return setLinkCapacityReportingCriteriaResponse_1_5(const RadioResponseInfo& info); + Return setLinkCapacityReportingCriteriaResponse_1_5( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return enableUiccApplicationsResponse(const RadioResponseInfo& info); + Return enableUiccApplicationsResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return areUiccApplicationsEnabledResponse(const RadioResponseInfo& info, bool enabled); + Return areUiccApplicationsEnabledResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, bool enabled); - Return canToggleUiccApplicationsEnablementResponse(const RadioResponseInfo& info, - bool canToggle); + Return canToggleUiccApplicationsEnablementResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, bool canToggle); - Return setSystemSelectionChannelsResponse_1_5(const RadioResponseInfo& info); + Return setSystemSelectionChannelsResponse_1_5( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return startNetworkScanResponse_1_5(const RadioResponseInfo& info); + Return startNetworkScanResponse_1_5( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); Return setupDataCallResponse_1_5( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, const android::hardware::radio::V1_5::SetupDataCallResult& dcResponse); Return getDataCallListResponse_1_5( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, const hidl_vec<::android::hardware::radio::V1_5::SetupDataCallResult>& dcResponse); - Return setInitialAttachApnResponse_1_5(const RadioResponseInfo& info); + Return setInitialAttachApnResponse_1_5( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return setDataProfileResponse_1_5(const RadioResponseInfo& info); + Return setDataProfileResponse_1_5( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return setRadioPowerResponse_1_5(const RadioResponseInfo& info); + Return setRadioPowerResponse_1_5( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return setIndicationFilterResponse_1_5(const RadioResponseInfo& info); + Return setIndicationFilterResponse_1_5( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); Return getBarringInfoResponse( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, const ::android::hardware::radio::V1_5::CellIdentity& cellIdentity, const ::android::hardware::hidl_vec<::android::hardware::radio::V1_5::BarringInfo>& barringInfos); Return getVoiceRegistrationStateResponse_1_5( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, const ::android::hardware::radio::V1_5::RegStateResult& regResponse); Return getDataRegistrationStateResponse_1_5( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, const ::android::hardware::radio::V1_5::RegStateResult& regResponse); Return getCellInfoListResponse_1_5( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, const ::android::hardware::hidl_vec<::android::hardware::radio::V1_5::CellInfo>& cellInfo); - Return setNetworkSelectionModeManualResponse_1_5(const RadioResponseInfo& info); + Return setNetworkSelectionModeManualResponse_1_5( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info); - Return sendCdmaSmsExpectMoreResponse(const RadioResponseInfo& info, - const SendSmsResult& sms); + Return sendCdmaSmsExpectMoreResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, + const SendSmsResult& sms); Return supplySimDepersonalizationResponse( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, ::android::hardware::radio::V1_5::PersoSubstate persoType, int32_t remainingRetries); Return getIccCardStatusResponse_1_5( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, const ::android::hardware::radio::V1_5::CardStatus& card_status); /* 1.6 Api */ Return setupDataCallResponse_1_6( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_6::RadioResponseInfo& info, const android::hardware::radio::V1_6::SetupDataCallResult& dcResponse); Return getDataCallListResponse_1_6( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_6::RadioResponseInfo& info, const hidl_vec<::android::hardware::radio::V1_6::SetupDataCallResult>& dcResponse); + + Return sendSmsResponse_1_6( + const ::android::hardware::radio::V1_6::RadioResponseInfo& info, + const SendSmsResult& sms); + + Return sendSMSExpectMoreResponse_1_6( + const ::android::hardware::radio::V1_6::RadioResponseInfo& info, + const SendSmsResult& sms); + + Return sendCdmaSmsResponse_1_6( + const ::android::hardware::radio::V1_6::RadioResponseInfo& info, + const SendSmsResult& sms); + + Return sendCdmaSmsExpectMoreResponse_1_6( + const ::android::hardware::radio::V1_6::RadioResponseInfo& info, + const SendSmsResult& sms); }; /* Callback class for radio indication */ diff --git a/radio/1.6/vts/functional/radio_response.cpp b/radio/1.6/vts/functional/radio_response.cpp index f53e199c81..a598ac17ea 100644 --- a/radio/1.6/vts/functional/radio_response.cpp +++ b/radio/1.6/vts/functional/radio_response.cpp @@ -22,435 +22,478 @@ RadioResponse_v1_6::RadioResponse_v1_6(RadioHidlTest_v1_6& parent) : parent_v1_6 /* 1.0 Apis */ Return RadioResponse_v1_6::getIccCardStatusResponse( - const RadioResponseInfo& /*info*/, + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, const ::android::hardware::radio::V1_0::CardStatus& /*card_status*/) { return Void(); } -Return RadioResponse_v1_6::supplyIccPinForAppResponse(const RadioResponseInfo& /*info*/, - int32_t /*remainingRetries*/) { +Return RadioResponse_v1_6::supplyIccPinForAppResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, + int32_t /*remainingRetries*/) { return Void(); } -Return RadioResponse_v1_6::supplyIccPukForAppResponse(const RadioResponseInfo& /*info*/, - int32_t /*remainingRetries*/) { +Return RadioResponse_v1_6::supplyIccPukForAppResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, + int32_t /*remainingRetries*/) { return Void(); } -Return RadioResponse_v1_6::supplyIccPin2ForAppResponse(const RadioResponseInfo& /*info*/, - int32_t /*remainingRetries*/) { +Return RadioResponse_v1_6::supplyIccPin2ForAppResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, + int32_t /*remainingRetries*/) { return Void(); } -Return RadioResponse_v1_6::supplyIccPuk2ForAppResponse(const RadioResponseInfo& /*info*/, - int32_t /*remainingRetries*/) { +Return RadioResponse_v1_6::supplyIccPuk2ForAppResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, + int32_t /*remainingRetries*/) { return Void(); } -Return RadioResponse_v1_6::changeIccPinForAppResponse(const RadioResponseInfo& /*info*/, - int32_t /*remainingRetries*/) { +Return RadioResponse_v1_6::changeIccPinForAppResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, + int32_t /*remainingRetries*/) { return Void(); } -Return RadioResponse_v1_6::changeIccPin2ForAppResponse(const RadioResponseInfo& /*info*/, - int32_t /*remainingRetries*/) { +Return RadioResponse_v1_6::changeIccPin2ForAppResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, + int32_t /*remainingRetries*/) { return Void(); } Return RadioResponse_v1_6::supplyNetworkDepersonalizationResponse( - const RadioResponseInfo& /*info*/, int32_t /*remainingRetries*/) { + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, + int32_t /*remainingRetries*/) { return Void(); } Return RadioResponse_v1_6::getCurrentCallsResponse( - const RadioResponseInfo& /*info*/, + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, const ::android::hardware::hidl_vec<::android::hardware::radio::V1_0::Call>& /*calls*/) { return Void(); } -Return RadioResponse_v1_6::dialResponse(const RadioResponseInfo& /*info*/) { +Return RadioResponse_v1_6::dialResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } Return RadioResponse_v1_6::getIMSIForAppResponse( - const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_string& /*imsi*/) { + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, + const ::android::hardware::hidl_string& /*imsi*/) { return Void(); } -Return RadioResponse_v1_6::hangupConnectionResponse(const RadioResponseInfo& info) { - rspInfo = info; - parent_v1_6.notify(info.serial); +Return RadioResponse_v1_6::hangupConnectionResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } Return RadioResponse_v1_6::hangupWaitingOrBackgroundResponse( - const RadioResponseInfo& /*info*/) { + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } Return RadioResponse_v1_6::hangupForegroundResumeBackgroundResponse( - const RadioResponseInfo& /*info*/) { + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } Return RadioResponse_v1_6::switchWaitingOrHoldingAndActiveResponse( - const RadioResponseInfo& /*info*/) { + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } -Return RadioResponse_v1_6::conferenceResponse(const RadioResponseInfo& /*info*/) { +Return RadioResponse_v1_6::conferenceResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } -Return RadioResponse_v1_6::rejectCallResponse(const RadioResponseInfo& /*info*/) { +Return RadioResponse_v1_6::rejectCallResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } Return RadioResponse_v1_6::getLastCallFailCauseResponse( - const RadioResponseInfo& /*info*/, const LastCallFailCauseInfo& /*failCauseInfo*/) { + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, + const LastCallFailCauseInfo& /*failCauseInfo*/) { return Void(); } Return RadioResponse_v1_6::getSignalStrengthResponse( - const RadioResponseInfo& /*info*/, + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, const ::android::hardware::radio::V1_0::SignalStrength& /*sig_strength*/) { return Void(); } Return RadioResponse_v1_6::getVoiceRegistrationStateResponse( - const RadioResponseInfo& /*info*/, + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, const ::android::hardware::radio::V1_0::VoiceRegStateResult& /*voiceRegResponse*/) { return Void(); } Return RadioResponse_v1_6::getDataRegistrationStateResponse( - const RadioResponseInfo& /*info*/, + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, const ::android::hardware::radio::V1_0::DataRegStateResult& /*dataRegResponse*/) { return Void(); } Return RadioResponse_v1_6::getOperatorResponse( - const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_string& /*longName*/, + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, + const ::android::hardware::hidl_string& /*longName*/, const ::android::hardware::hidl_string& /*shortName*/, const ::android::hardware::hidl_string& /*numeric*/) { return Void(); } -Return RadioResponse_v1_6::setRadioPowerResponse(const RadioResponseInfo& /*info*/) { +Return RadioResponse_v1_6::setRadioPowerResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } -Return RadioResponse_v1_6::sendDtmfResponse(const RadioResponseInfo& /*info*/) { +Return RadioResponse_v1_6::sendDtmfResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } -Return RadioResponse_v1_6::sendSmsResponse(const RadioResponseInfo& /*info*/, - const SendSmsResult& /*sms*/) { +Return RadioResponse_v1_6::sendSmsResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, + const SendSmsResult& /*sms*/) { return Void(); } -Return RadioResponse_v1_6::sendSMSExpectMoreResponse(const RadioResponseInfo& /*info*/, - const SendSmsResult& /*sms*/) { +Return RadioResponse_v1_6::sendSMSExpectMoreResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, + const SendSmsResult& /*sms*/) { return Void(); } Return RadioResponse_v1_6::setupDataCallResponse( - const RadioResponseInfo& /*info*/, + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, const android::hardware::radio::V1_0::SetupDataCallResult& /*dcResponse*/) { return Void(); } -Return RadioResponse_v1_6::iccIOForAppResponse(const RadioResponseInfo& /*info*/, - const IccIoResult& /*iccIo*/) { +Return RadioResponse_v1_6::iccIOForAppResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, + const IccIoResult& /*iccIo*/) { return Void(); } -Return RadioResponse_v1_6::sendUssdResponse(const RadioResponseInfo& /*info*/) { +Return RadioResponse_v1_6::sendUssdResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } -Return RadioResponse_v1_6::cancelPendingUssdResponse(const RadioResponseInfo& /*info*/) { +Return RadioResponse_v1_6::cancelPendingUssdResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } -Return RadioResponse_v1_6::getClirResponse(const RadioResponseInfo& /*info*/, int32_t /*n*/, - int32_t /*m*/) { +Return RadioResponse_v1_6::getClirResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, int32_t /*n*/, + int32_t /*m*/) { return Void(); } -Return RadioResponse_v1_6::setClirResponse(const RadioResponseInfo& /*info*/) { +Return RadioResponse_v1_6::setClirResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } Return RadioResponse_v1_6::getCallForwardStatusResponse( - const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_vec& + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, + const ::android::hardware::hidl_vec& /*callForwardInfos*/) { return Void(); } -Return RadioResponse_v1_6::setCallForwardResponse(const RadioResponseInfo& /*info*/) { +Return RadioResponse_v1_6::setCallForwardResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } -Return RadioResponse_v1_6::getCallWaitingResponse(const RadioResponseInfo& /*info*/, - bool /*enable*/, int32_t /*serviceClass*/) { +Return RadioResponse_v1_6::getCallWaitingResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, bool /*enable*/, + int32_t /*serviceClass*/) { return Void(); } -Return RadioResponse_v1_6::setCallWaitingResponse(const RadioResponseInfo& /*info*/) { +Return RadioResponse_v1_6::setCallWaitingResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } Return RadioResponse_v1_6::acknowledgeLastIncomingGsmSmsResponse( - const RadioResponseInfo& /*info*/) { + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } -Return RadioResponse_v1_6::acceptCallResponse(const RadioResponseInfo& /*info*/) { +Return RadioResponse_v1_6::acceptCallResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } -Return RadioResponse_v1_6::deactivateDataCallResponse(const RadioResponseInfo& info) { - rspInfo = info; - parent_v1_6.notify(info.serial); +Return RadioResponse_v1_6::deactivateDataCallResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } -Return RadioResponse_v1_6::getFacilityLockForAppResponse(const RadioResponseInfo& /*info*/, - int32_t /*response*/) { +Return RadioResponse_v1_6::getFacilityLockForAppResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, int32_t /*response*/) { return Void(); } -Return RadioResponse_v1_6::setFacilityLockForAppResponse(const RadioResponseInfo& /*info*/, - int32_t /*retry*/) { +Return RadioResponse_v1_6::setFacilityLockForAppResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, int32_t /*retry*/) { return Void(); } -Return RadioResponse_v1_6::setBarringPasswordResponse(const RadioResponseInfo& /*info*/) { +Return RadioResponse_v1_6::setBarringPasswordResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } -Return RadioResponse_v1_6::getNetworkSelectionModeResponse(const RadioResponseInfo& /*info*/, - bool /*manual*/) { +Return RadioResponse_v1_6::getNetworkSelectionModeResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, bool /*manual*/) { return Void(); } Return RadioResponse_v1_6::setNetworkSelectionModeAutomaticResponse( - const RadioResponseInfo& /*info*/) { + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } Return RadioResponse_v1_6::setNetworkSelectionModeManualResponse( - const RadioResponseInfo& /*info*/) { + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } Return RadioResponse_v1_6::getAvailableNetworksResponse( - const RadioResponseInfo& /*info*/, + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, const ::android::hardware::hidl_vec& /*networkInfos*/) { return Void(); } -Return RadioResponse_v1_6::startDtmfResponse(const RadioResponseInfo& /*info*/) { +Return RadioResponse_v1_6::startDtmfResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } -Return RadioResponse_v1_6::stopDtmfResponse(const RadioResponseInfo& /*info*/) { +Return RadioResponse_v1_6::stopDtmfResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } Return RadioResponse_v1_6::getBasebandVersionResponse( - const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_string& /*version*/) { + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, + const ::android::hardware::hidl_string& /*version*/) { return Void(); } -Return RadioResponse_v1_6::separateConnectionResponse(const RadioResponseInfo& /*info*/) { +Return RadioResponse_v1_6::separateConnectionResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } -Return RadioResponse_v1_6::setMuteResponse(const RadioResponseInfo& /*info*/) { +Return RadioResponse_v1_6::setMuteResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } -Return RadioResponse_v1_6::getMuteResponse(const RadioResponseInfo& /*info*/, - bool /*enable*/) { +Return RadioResponse_v1_6::getMuteResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, bool /*enable*/) { return Void(); } -Return RadioResponse_v1_6::getClipResponse(const RadioResponseInfo& /*info*/, - ClipStatus /*status*/) { +Return RadioResponse_v1_6::getClipResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, + ClipStatus /*status*/) { return Void(); } Return RadioResponse_v1_6::getDataCallListResponse( - const RadioResponseInfo& /*info*/, + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, const ::android::hardware::hidl_vec& /*dcResponse*/) { return Void(); } Return RadioResponse_v1_6::sendOemRilRequestRawResponse( - const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_vec& /*data*/) { + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, + const ::android::hardware::hidl_vec& /*data*/) { return Void(); } Return RadioResponse_v1_6::sendOemRilRequestStringsResponse( - const RadioResponseInfo& /*info*/, + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, const ::android::hardware::hidl_vec<::android::hardware::hidl_string>& /*data*/) { return Void(); } Return RadioResponse_v1_6::setSuppServiceNotificationsResponse( - const RadioResponseInfo& /*info*/) { + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } -Return RadioResponse_v1_6::writeSmsToSimResponse(const RadioResponseInfo& /*info*/, - int32_t /*index*/) { +Return RadioResponse_v1_6::writeSmsToSimResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, int32_t /*index*/) { return Void(); } -Return RadioResponse_v1_6::deleteSmsOnSimResponse(const RadioResponseInfo& /*info*/) { +Return RadioResponse_v1_6::deleteSmsOnSimResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } -Return RadioResponse_v1_6::setBandModeResponse(const RadioResponseInfo& /*info*/) { +Return RadioResponse_v1_6::setBandModeResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } Return RadioResponse_v1_6::getAvailableBandModesResponse( - const RadioResponseInfo& info, - const ::android::hardware::hidl_vec& bandModes) { - rspInfo = info; - radioBandModes = bandModes; - parent_v1_6.notify(info.serial); + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, + const ::android::hardware::hidl_vec& /*bandModes*/) { return Void(); } Return RadioResponse_v1_6::sendEnvelopeResponse( - const RadioResponseInfo& /*info*/, + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, const ::android::hardware::hidl_string& /*commandResponse*/) { return Void(); } Return RadioResponse_v1_6::sendTerminalResponseToSimResponse( - const RadioResponseInfo& /*info*/) { + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } Return RadioResponse_v1_6::handleStkCallSetupRequestFromSimResponse( - const RadioResponseInfo& /*info*/) { + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } -Return RadioResponse_v1_6::explicitCallTransferResponse(const RadioResponseInfo& /*info*/) { +Return RadioResponse_v1_6::explicitCallTransferResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } Return RadioResponse_v1_6::setPreferredNetworkTypeResponse( - const RadioResponseInfo& /*info*/) { + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } -Return RadioResponse_v1_6::getPreferredNetworkTypeResponse(const RadioResponseInfo& /*info*/, - PreferredNetworkType /*nw_type*/) { +Return RadioResponse_v1_6::getPreferredNetworkTypeResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, + PreferredNetworkType /*nw_type*/) { return Void(); } Return RadioResponse_v1_6::getNeighboringCidsResponse( - const RadioResponseInfo& /*info*/, + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, const ::android::hardware::hidl_vec& /*cells*/) { return Void(); } -Return RadioResponse_v1_6::setLocationUpdatesResponse(const RadioResponseInfo& /*info*/) { +Return RadioResponse_v1_6::setLocationUpdatesResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } Return RadioResponse_v1_6::setCdmaSubscriptionSourceResponse( - const RadioResponseInfo& /*info*/) { + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } Return RadioResponse_v1_6::setCdmaRoamingPreferenceResponse( - const RadioResponseInfo& /*info*/) { + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } -Return RadioResponse_v1_6::getCdmaRoamingPreferenceResponse(const RadioResponseInfo& /*info*/, - CdmaRoamingType /*type*/) { +Return RadioResponse_v1_6::getCdmaRoamingPreferenceResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, + CdmaRoamingType /*type*/) { return Void(); } -Return RadioResponse_v1_6::setTTYModeResponse(const RadioResponseInfo& /*info*/) { +Return RadioResponse_v1_6::setTTYModeResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } -Return RadioResponse_v1_6::getTTYModeResponse(const RadioResponseInfo& /*info*/, - TtyMode /*mode*/) { +Return RadioResponse_v1_6::getTTYModeResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, TtyMode /*mode*/) { return Void(); } Return RadioResponse_v1_6::setPreferredVoicePrivacyResponse( - const RadioResponseInfo& /*info*/) { + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } -Return RadioResponse_v1_6::getPreferredVoicePrivacyResponse(const RadioResponseInfo& /*info*/, - bool /*enable*/) { +Return RadioResponse_v1_6::getPreferredVoicePrivacyResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, bool /*enable*/) { return Void(); } -Return RadioResponse_v1_6::sendCDMAFeatureCodeResponse(const RadioResponseInfo& /*info*/) { +Return RadioResponse_v1_6::sendCDMAFeatureCodeResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } -Return RadioResponse_v1_6::sendBurstDtmfResponse(const RadioResponseInfo& /*info*/) { +Return RadioResponse_v1_6::sendBurstDtmfResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } -Return RadioResponse_v1_6::sendCdmaSmsResponse(const RadioResponseInfo& /*info*/, - const SendSmsResult& /*sms*/) { +Return RadioResponse_v1_6::sendCdmaSmsResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, + const SendSmsResult& /*sms*/) { return Void(); } Return RadioResponse_v1_6::acknowledgeLastIncomingCdmaSmsResponse( - const RadioResponseInfo& /*info*/) { + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } Return RadioResponse_v1_6::getGsmBroadcastConfigResponse( - const RadioResponseInfo& /*info*/, + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, const ::android::hardware::hidl_vec& /*configs*/) { return Void(); } -Return RadioResponse_v1_6::setGsmBroadcastConfigResponse(const RadioResponseInfo& /*info*/) { +Return RadioResponse_v1_6::setGsmBroadcastConfigResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } Return RadioResponse_v1_6::setGsmBroadcastActivationResponse( - const RadioResponseInfo& /*info*/) { + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } Return RadioResponse_v1_6::getCdmaBroadcastConfigResponse( - const RadioResponseInfo& /*info*/, + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, const ::android::hardware::hidl_vec& /*configs*/) { return Void(); } -Return RadioResponse_v1_6::setCdmaBroadcastConfigResponse(const RadioResponseInfo& /*info*/) { +Return RadioResponse_v1_6::setCdmaBroadcastConfigResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } Return RadioResponse_v1_6::setCdmaBroadcastActivationResponse( - const RadioResponseInfo& /*info*/) { + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } Return RadioResponse_v1_6::getCDMASubscriptionResponse( - const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_string& /*mdn*/, + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, + const ::android::hardware::hidl_string& /*mdn*/, const ::android::hardware::hidl_string& /*hSid*/, const ::android::hardware::hidl_string& /*hNid*/, const ::android::hardware::hidl_string& /*min*/, @@ -458,17 +501,19 @@ Return RadioResponse_v1_6::getCDMASubscriptionResponse( return Void(); } -Return RadioResponse_v1_6::writeSmsToRuimResponse(const RadioResponseInfo& /*info*/, - uint32_t /*index*/) { +Return RadioResponse_v1_6::writeSmsToRuimResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, uint32_t /*index*/) { return Void(); } -Return RadioResponse_v1_6::deleteSmsOnRuimResponse(const RadioResponseInfo& /*info*/) { +Return RadioResponse_v1_6::deleteSmsOnRuimResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } Return RadioResponse_v1_6::getDeviceIdentityResponse( - const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_string& /*imei*/, + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, + const ::android::hardware::hidl_string& /*imei*/, const ::android::hardware::hidl_string& /*imeisv*/, const ::android::hardware::hidl_string& /*esn*/, const ::android::hardware::hidl_string& /*meid*/) { @@ -476,202 +521,225 @@ Return RadioResponse_v1_6::getDeviceIdentityResponse( } Return RadioResponse_v1_6::exitEmergencyCallbackModeResponse( - const RadioResponseInfo& /*info*/) { + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } Return RadioResponse_v1_6::getSmscAddressResponse( - const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_string& /*smsc*/) { + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, + const ::android::hardware::hidl_string& /*smsc*/) { return Void(); } -Return RadioResponse_v1_6::setSmscAddressResponse(const RadioResponseInfo& /*info*/) { +Return RadioResponse_v1_6::setSmscAddressResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } -Return RadioResponse_v1_6::reportSmsMemoryStatusResponse(const RadioResponseInfo& /*info*/) { +Return RadioResponse_v1_6::reportSmsMemoryStatusResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } Return RadioResponse_v1_6::reportStkServiceIsRunningResponse( - const RadioResponseInfo& /*info*/) { + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } Return RadioResponse_v1_6::getCdmaSubscriptionSourceResponse( - const RadioResponseInfo& /*info*/, CdmaSubscriptionSource /*source*/) { + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, + CdmaSubscriptionSource /*source*/) { return Void(); } Return RadioResponse_v1_6::requestIsimAuthenticationResponse( - const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_string& /*response*/) { + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, + const ::android::hardware::hidl_string& /*response*/) { return Void(); } Return RadioResponse_v1_6::acknowledgeIncomingGsmSmsWithPduResponse( - const RadioResponseInfo& /*info*/) { + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } -Return RadioResponse_v1_6::sendEnvelopeWithStatusResponse(const RadioResponseInfo& /*info*/, - const IccIoResult& /*iccIo*/) { +Return RadioResponse_v1_6::sendEnvelopeWithStatusResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, + const IccIoResult& /*iccIo*/) { return Void(); } Return RadioResponse_v1_6::getVoiceRadioTechnologyResponse( - const RadioResponseInfo& /*info*/, + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, ::android::hardware::radio::V1_0::RadioTechnology /*rat*/) { return Void(); } Return RadioResponse_v1_6::getCellInfoListResponse( - const RadioResponseInfo& /*info*/, + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, const ::android::hardware::hidl_vec< ::android::hardware::radio::V1_0::CellInfo>& /*cellInfo*/) { return Void(); } -Return RadioResponse_v1_6::setCellInfoListRateResponse(const RadioResponseInfo& /*info*/) { +Return RadioResponse_v1_6::setCellInfoListRateResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } -Return RadioResponse_v1_6::setInitialAttachApnResponse(const RadioResponseInfo& info) { - rspInfo = info; - parent_v1_6.notify(info.serial); +Return RadioResponse_v1_6::setInitialAttachApnResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } Return RadioResponse_v1_6::getImsRegistrationStateResponse( - const RadioResponseInfo& /*info*/, bool /*isRegistered*/, + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, bool /*isRegistered*/, RadioTechnologyFamily /*ratFamily*/) { return Void(); } -Return RadioResponse_v1_6::sendImsSmsResponse(const RadioResponseInfo& /*info*/, - const SendSmsResult& /*sms*/) { +Return RadioResponse_v1_6::sendImsSmsResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, + const SendSmsResult& /*sms*/) { return Void(); } Return RadioResponse_v1_6::iccTransmitApduBasicChannelResponse( - const RadioResponseInfo& /*info*/, const IccIoResult& /*result*/) { + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, + const IccIoResult& /*result*/) { return Void(); } Return RadioResponse_v1_6::iccOpenLogicalChannelResponse( - const RadioResponseInfo& /*info*/, int32_t /*channelId*/, + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, int32_t /*channelId*/, const ::android::hardware::hidl_vec& /*selectResponse*/) { return Void(); } -Return RadioResponse_v1_6::iccCloseLogicalChannelResponse(const RadioResponseInfo& /*info*/) { +Return RadioResponse_v1_6::iccCloseLogicalChannelResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } Return RadioResponse_v1_6::iccTransmitApduLogicalChannelResponse( - const RadioResponseInfo& /*info*/, const IccIoResult& /*result*/) { + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, + const IccIoResult& /*result*/) { return Void(); } Return RadioResponse_v1_6::nvReadItemResponse( - const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_string& /*result*/) { + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, + const ::android::hardware::hidl_string& /*result*/) { return Void(); } -Return RadioResponse_v1_6::nvWriteItemResponse(const RadioResponseInfo& /*info*/) { +Return RadioResponse_v1_6::nvWriteItemResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } -Return RadioResponse_v1_6::nvWriteCdmaPrlResponse(const RadioResponseInfo& /*info*/) { +Return RadioResponse_v1_6::nvWriteCdmaPrlResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } -Return RadioResponse_v1_6::nvResetConfigResponse(const RadioResponseInfo& /*info*/) { +Return RadioResponse_v1_6::nvResetConfigResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } -Return RadioResponse_v1_6::setUiccSubscriptionResponse(const RadioResponseInfo& /*info*/) { +Return RadioResponse_v1_6::setUiccSubscriptionResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } -Return RadioResponse_v1_6::setDataAllowedResponse(const RadioResponseInfo& /*info*/) { +Return RadioResponse_v1_6::setDataAllowedResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } Return RadioResponse_v1_6::getHardwareConfigResponse( - const RadioResponseInfo& /*info*/, + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, const ::android::hardware::hidl_vec& /*config*/) { return Void(); } Return RadioResponse_v1_6::requestIccSimAuthenticationResponse( - const RadioResponseInfo& /*info*/, const IccIoResult& /*result*/) { + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, + const IccIoResult& /*result*/) { return Void(); } -Return RadioResponse_v1_6::setDataProfileResponse(const RadioResponseInfo& info) { - rspInfo = info; - parent_v1_6.notify(info.serial); +Return RadioResponse_v1_6::setDataProfileResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } -Return RadioResponse_v1_6::requestShutdownResponse(const RadioResponseInfo& /*info*/) { +Return RadioResponse_v1_6::requestShutdownResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } Return RadioResponse_v1_6::getRadioCapabilityResponse( - const RadioResponseInfo& /*info*/, + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, const android::hardware::radio::V1_0::RadioCapability& /*rc*/) { return Void(); } Return RadioResponse_v1_6::setRadioCapabilityResponse( - const RadioResponseInfo& /*info*/, + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, const android::hardware::radio::V1_0::RadioCapability& /*rc*/) { return Void(); } -Return RadioResponse_v1_6::startLceServiceResponse(const RadioResponseInfo& /*info*/, - const LceStatusInfo& /*statusInfo*/) { +Return RadioResponse_v1_6::startLceServiceResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, + const LceStatusInfo& /*statusInfo*/) { return Void(); } -Return RadioResponse_v1_6::stopLceServiceResponse(const RadioResponseInfo& /*info*/, - const LceStatusInfo& /*statusInfo*/) { +Return RadioResponse_v1_6::stopLceServiceResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, + const LceStatusInfo& /*statusInfo*/) { return Void(); } -Return RadioResponse_v1_6::pullLceDataResponse(const RadioResponseInfo& /*info*/, - const LceDataInfo& /*lceInfo*/) { +Return RadioResponse_v1_6::pullLceDataResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, + const LceDataInfo& /*lceInfo*/) { return Void(); } Return RadioResponse_v1_6::getModemActivityInfoResponse( - const RadioResponseInfo& /*info*/, const ActivityStatsInfo& /*activityInfo*/) { + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, + const ActivityStatsInfo& /*activityInfo*/) { return Void(); } -Return RadioResponse_v1_6::setAllowedCarriersResponse(const RadioResponseInfo& /*info*/, - int32_t /*numAllowed*/) { +Return RadioResponse_v1_6::setAllowedCarriersResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, + int32_t /*numAllowed*/) { return Void(); } Return RadioResponse_v1_6::getAllowedCarriersResponse( - const RadioResponseInfo& /*info*/, bool /*allAllowed*/, + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, bool /*allAllowed*/, const CarrierRestrictions& /*carriers*/) { return Void(); } -Return RadioResponse_v1_6::sendDeviceStateResponse(const RadioResponseInfo& /*info*/) { +Return RadioResponse_v1_6::sendDeviceStateResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } -Return RadioResponse_v1_6::setIndicationFilterResponse(const RadioResponseInfo& info) { - rspInfo = info; - parent_v1_6.notify(info.serial); +Return RadioResponse_v1_6::setIndicationFilterResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } -Return RadioResponse_v1_6::setSimCardPowerResponse(const RadioResponseInfo& /*info*/) { +Return RadioResponse_v1_6::setSimCardPowerResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } @@ -681,368 +749,297 @@ Return RadioResponse_v1_6::acknowledgeRequest(int32_t /*serial*/) { /* 1.1 Apis */ Return RadioResponse_v1_6::setCarrierInfoForImsiEncryptionResponse( - const RadioResponseInfo& /*info*/) { + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } -Return RadioResponse_v1_6::setSimCardPowerResponse_1_1(const RadioResponseInfo& /*info*/) { +Return RadioResponse_v1_6::setSimCardPowerResponse_1_1( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } -Return RadioResponse_v1_6::startNetworkScanResponse(const RadioResponseInfo& /*info*/) { +Return RadioResponse_v1_6::startNetworkScanResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } -Return RadioResponse_v1_6::stopNetworkScanResponse(const RadioResponseInfo& info) { - rspInfo = info; - parent_v1_6.notify(info.serial); +Return RadioResponse_v1_6::stopNetworkScanResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } -Return RadioResponse_v1_6::startKeepaliveResponse(const RadioResponseInfo& /*info*/, - const KeepaliveStatus& /*status*/) { +Return RadioResponse_v1_6::startKeepaliveResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, + const KeepaliveStatus& /*status*/) { return Void(); } -Return RadioResponse_v1_6::stopKeepaliveResponse(const RadioResponseInfo& /*info*/) { +Return RadioResponse_v1_6::stopKeepaliveResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } /* 1.2 Apis */ Return RadioResponse_v1_6::setSignalStrengthReportingCriteriaResponse( - const RadioResponseInfo& info) { - rspInfo = info; - parent_v1_6.notify(info.serial); + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } Return RadioResponse_v1_6::setLinkCapacityReportingCriteriaResponse( - const RadioResponseInfo& info) { - rspInfo = info; - parent_v1_6.notify(info.serial); + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } Return RadioResponse_v1_6::getIccCardStatusResponse_1_2( - const RadioResponseInfo& /*info*/, + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, const ::android::hardware::radio::V1_2::CardStatus& /*card_status*/) { return Void(); } Return RadioResponse_v1_6::getCurrentCallsResponse_1_2( - const RadioResponseInfo& info, - const ::android::hardware::hidl_vec<::android::hardware::radio::V1_2::Call>& calls) { - rspInfo = info; - currentCalls = calls; - parent_v1_6.notify(info.serial); + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, + const ::android::hardware::hidl_vec<::android::hardware::radio::V1_2::Call>& /*calls*/) { return Void(); } Return RadioResponse_v1_6::getSignalStrengthResponse_1_2( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, const ::android::hardware::radio::V1_2::SignalStrength& /*sig_strength*/) { - rspInfo = info; - parent_v1_6.notify(info.serial); return Void(); } Return RadioResponse_v1_6::getSignalStrengthResponse_1_4( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, const ::android::hardware::radio::V1_4::SignalStrength& /*sig_strength*/) { - rspInfo = info; - parent_v1_6.notify(info.serial); return Void(); } Return RadioResponse_v1_6::getCellInfoListResponse_1_2( - const RadioResponseInfo& /*info*/, + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, const ::android::hardware::hidl_vec< ::android::hardware::radio::V1_2::CellInfo>& /*cellInfo*/) { return Void(); } Return RadioResponse_v1_6::getVoiceRegistrationStateResponse_1_2( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, const ::android::hardware::radio::V1_2::VoiceRegStateResult& /*voiceRegResponse*/) { - rspInfo = info; - parent_v1_6.notify(info.serial); return Void(); } Return RadioResponse_v1_6::getDataRegistrationStateResponse_1_2( - const RadioResponseInfo& /*info*/, + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, const ::android::hardware::radio::V1_2::DataRegStateResult& /*dataRegResponse*/) { return Void(); } /* 1.3 Apis */ -Return RadioResponse_v1_6::setSystemSelectionChannelsResponse(const RadioResponseInfo& info) { - rspInfo = info; - parent_v1_6.notify(info.serial); +Return RadioResponse_v1_6::setSystemSelectionChannelsResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } -Return RadioResponse_v1_6::enableModemResponse(const RadioResponseInfo& info) { - rspInfo = info; - parent_v1_6.notify(info.serial); +Return RadioResponse_v1_6::enableModemResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } -Return RadioResponse_v1_6::getModemStackStatusResponse(const RadioResponseInfo& info, - const bool enabled) { - rspInfo = info; - isModemEnabled = enabled; - parent_v1_6.notify(info.serial); +Return RadioResponse_v1_6::getModemStackStatusResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, + const bool /*enabled*/) { return Void(); } /* 1.4 Apis */ -Return RadioResponse_v1_6::emergencyDialResponse(const RadioResponseInfo& info) { - rspInfo = info; - parent_v1_6.notify(info.serial); +Return RadioResponse_v1_6::emergencyDialResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } -Return RadioResponse_v1_6::startNetworkScanResponse_1_4(const RadioResponseInfo& info) { - rspInfo = info; - parent_v1_6.notify(info.serial); +Return RadioResponse_v1_6::startNetworkScanResponse_1_4( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } Return RadioResponse_v1_6::getDataRegistrationStateResponse_1_4( - const RadioResponseInfo& info, - const ::android::hardware::radio::V1_4::DataRegStateResult& dataRegResponse) { - rspInfo = info; - dataRegResp = dataRegResponse; - parent_v1_6.notify(info.serial); + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, + const ::android::hardware::radio::V1_4::DataRegStateResult& /*dataRegResponse*/) { return Void(); } Return RadioResponse_v1_6::getCellInfoListResponse_1_4( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, const ::android::hardware::hidl_vec< ::android::hardware::radio::V1_4::CellInfo>& /*cellInfo*/) { - rspInfo = info; - parent_v1_6.notify(info.serial); return Void(); } Return RadioResponse_v1_6::getIccCardStatusResponse_1_4( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, const ::android::hardware::radio::V1_4::CardStatus& /*card_status*/) { - rspInfo = info; - parent_v1_6.notify(info.serial); return Void(); } Return RadioResponse_v1_6::getPreferredNetworkTypeBitmapResponse( - const RadioResponseInfo& info, const ::android::hardware::hidl_bitfield< - ::android::hardware::radio::V1_4::RadioAccessFamily> - networkTypeBitmap) { - rspInfo = info; - networkTypeBitmapResponse = networkTypeBitmap; - parent_v1_6.notify(info.serial); + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, + const ::android::hardware::hidl_bitfield< + ::android::hardware::radio::V1_4::RadioAccessFamily> + /*networkTypeBitmap*/) { return Void(); } Return RadioResponse_v1_6::setPreferredNetworkTypeBitmapResponse( - const RadioResponseInfo& info) { - rspInfo = info; - parent_v1_6.notify(info.serial); + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } Return RadioResponse_v1_6::getDataCallListResponse_1_4( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, const ::android::hardware::hidl_vec<::android::hardware::radio::V1_4::SetupDataCallResult>& /*dcResponse*/) { - rspInfo = info; - parent_v1_6.notify(info.serial); return Void(); } Return RadioResponse_v1_6::setupDataCallResponse_1_4( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, const android::hardware::radio::V1_4::SetupDataCallResult& /*dcResponse*/) { - rspInfo = info; - parent_v1_6.notify(info.serial); return Void(); } -Return RadioResponse_v1_6::setAllowedCarriersResponse_1_4(const RadioResponseInfo& info) { - rspInfo = info; - parent_v1_6.notify(info.serial); +Return RadioResponse_v1_6::setAllowedCarriersResponse_1_4( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } Return RadioResponse_v1_6::getAllowedCarriersResponse_1_4( - const RadioResponseInfo& info, const CarrierRestrictionsWithPriority& carriers, - SimLockMultiSimPolicy multiSimPolicy) { - rspInfo = info; - carrierRestrictionsResp = carriers; - multiSimPolicyResp = multiSimPolicy; - parent_v1_6.notify(info.serial); + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, + const CarrierRestrictionsWithPriority& /*carriers*/, + SimLockMultiSimPolicy /*multiSimPolicy*/) { return Void(); } /* 1.5 Apis */ Return RadioResponse_v1_6::setSignalStrengthReportingCriteriaResponse_1_5( - const RadioResponseInfo& info) { - rspInfo = info; - parent_v1_6.notify(info.serial); + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } Return RadioResponse_v1_6::setLinkCapacityReportingCriteriaResponse_1_5( - const RadioResponseInfo& info) { - rspInfo = info; - parent_v1_6.notify(info.serial); + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } -Return RadioResponse_v1_6::enableUiccApplicationsResponse(const RadioResponseInfo& info) { - rspInfo = info; - parent_v1_6.notify(info.serial); +Return RadioResponse_v1_6::enableUiccApplicationsResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } -Return RadioResponse_v1_6::areUiccApplicationsEnabledResponse(const RadioResponseInfo& info, - bool enabled) { - rspInfo = info; - areUiccApplicationsEnabled = enabled; - parent_v1_6.notify(info.serial); +Return RadioResponse_v1_6::areUiccApplicationsEnabledResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, bool /*enabled*/) { return Void(); } Return RadioResponse_v1_6::canToggleUiccApplicationsEnablementResponse( - const RadioResponseInfo& info, bool canToggle) { - rspInfo = info; - canToggleUiccApplicationsEnablement = canToggle; - parent_v1_6.notify(info.serial); + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, bool /*canToggle*/) { return Void(); } Return RadioResponse_v1_6::setSystemSelectionChannelsResponse_1_5( - const RadioResponseInfo& info) { - rspInfo = info; - parent_v1_6.notify(info.serial); + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } -Return RadioResponse_v1_6::startNetworkScanResponse_1_5(const RadioResponseInfo& info) { - rspInfo = info; - parent_v1_6.notify(info.serial); +Return RadioResponse_v1_6::startNetworkScanResponse_1_5( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } Return RadioResponse_v1_6::setupDataCallResponse_1_5( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, const android::hardware::radio::V1_5::SetupDataCallResult& /* dcResponse */) { - rspInfo = info; - parent_v1_6.notify(info.serial); return Void(); } Return RadioResponse_v1_6::getDataCallListResponse_1_5( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, const hidl_vec<::android::hardware::radio::V1_5::SetupDataCallResult>& /* dcResponse */) { - rspInfo = info; - parent_v1_6.notify(info.serial); return Void(); } -Return RadioResponse_v1_6::setInitialAttachApnResponse_1_5(const RadioResponseInfo& info) { - rspInfo = info; - parent_v1_6.notify(info.serial); +Return RadioResponse_v1_6::setInitialAttachApnResponse_1_5( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } -Return RadioResponse_v1_6::setDataProfileResponse_1_5(const RadioResponseInfo& info) { - rspInfo = info; - parent_v1_6.notify(info.serial); +Return RadioResponse_v1_6::setDataProfileResponse_1_5( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } -Return RadioResponse_v1_6::setRadioPowerResponse_1_5(const RadioResponseInfo& info) { - rspInfo = info; - parent_v1_6.notify(info.serial); +Return RadioResponse_v1_6::setRadioPowerResponse_1_5( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } -Return RadioResponse_v1_6::setIndicationFilterResponse_1_5(const RadioResponseInfo& info) { - rspInfo = info; - parent_v1_6.notify(info.serial); +Return RadioResponse_v1_6::setIndicationFilterResponse_1_5( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } Return RadioResponse_v1_6::getBarringInfoResponse( - const RadioResponseInfo& info, - const ::android::hardware::radio::V1_5::CellIdentity& cellIdentity, + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, + const ::android::hardware::radio::V1_5::CellIdentity& /*cellIdentity*/, const ::android::hardware::hidl_vec<::android::hardware::radio::V1_5::BarringInfo>& - barringInfos) { - this->barringCellIdentity = cellIdentity; - this->barringInfos = barringInfos; - rspInfo = info; - parent_v1_6.notify(info.serial); + /*barringInfos*/) { return Void(); } Return RadioResponse_v1_6::getVoiceRegistrationStateResponse_1_5( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, const ::android::hardware::radio::V1_5::RegStateResult& /*regResponse*/) { - rspInfo = info; - parent_v1_6.notify(info.serial); return Void(); } Return RadioResponse_v1_6::getDataRegistrationStateResponse_1_5( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, const ::android::hardware::radio::V1_5::RegStateResult& /*regResponse*/) { - rspInfo = info; - parent_v1_6.notify(info.serial); return Void(); } Return RadioResponse_v1_6::getCellInfoListResponse_1_5( - const RadioResponseInfo& /*info*/, + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, const ::android::hardware::hidl_vec< ::android::hardware::radio::V1_5::CellInfo>& /*cellInfo*/) { return Void(); } Return RadioResponse_v1_6::setNetworkSelectionModeManualResponse_1_5( - const RadioResponseInfo& info) { - rspInfo = info; - parent_v1_6.notify(info.serial); + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/) { return Void(); } -Return RadioResponse_v1_6::sendCdmaSmsExpectMoreResponse(const RadioResponseInfo& info, - const SendSmsResult& /*sms*/) { - rspInfo = info; - parent_v1_6.notify(info.serial); +Return RadioResponse_v1_6::sendCdmaSmsExpectMoreResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, + const SendSmsResult& /*sms*/) { return Void(); } Return RadioResponse_v1_6::supplySimDepersonalizationResponse( - const RadioResponseInfo& /*info*/, + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, ::android::hardware::radio::V1_5::PersoSubstate /*persoType*/, int32_t /*remainingRetries*/) { return Void(); } Return RadioResponse_v1_6::getIccCardStatusResponse_1_5( - const RadioResponseInfo& info, - const ::android::hardware::radio::V1_5::CardStatus& card_status) { - rspInfo = info; - cardStatus = card_status; - parent_v1_6.notify(info.serial); + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, + const ::android::hardware::radio::V1_5::CardStatus& /*card_status*/) { return Void(); } /* 1.6 Apis */ Return RadioResponse_v1_6::setupDataCallResponse_1_6( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_6::RadioResponseInfo& info, const android::hardware::radio::V1_6::SetupDataCallResult& /* dcResponse */) { rspInfo = info; parent_v1_6.notify(info.serial); @@ -1050,9 +1047,45 @@ Return RadioResponse_v1_6::setupDataCallResponse_1_6( } Return RadioResponse_v1_6::getDataCallListResponse_1_6( - const RadioResponseInfo& info, + const ::android::hardware::radio::V1_6::RadioResponseInfo& info, const hidl_vec<::android::hardware::radio::V1_6::SetupDataCallResult>& /* dcResponse */) { rspInfo = info; parent_v1_6.notify(info.serial); return Void(); } + +Return RadioResponse_v1_6::sendSmsResponse_1_6( + const ::android::hardware::radio::V1_6::RadioResponseInfo& info, + const SendSmsResult& sms) { + rspInfo = info; + sendSmsResult = sms; + parent_v1_6.notify(info.serial); + return Void(); +} + +Return RadioResponse_v1_6::sendSMSExpectMoreResponse_1_6( + const ::android::hardware::radio::V1_6::RadioResponseInfo& info, + const SendSmsResult& sms) { + rspInfo = info; + sendSmsResult = sms; + parent_v1_6.notify(info.serial); + return Void(); +} + +Return RadioResponse_v1_6::sendCdmaSmsResponse_1_6( + const ::android::hardware::radio::V1_6::RadioResponseInfo& info, + const SendSmsResult& sms) { + rspInfo = info; + sendSmsResult = sms; + parent_v1_6.notify(info.serial); + return Void(); +} + +Return RadioResponse_v1_6::sendCdmaSmsExpectMoreResponse_1_6( + const ::android::hardware::radio::V1_6::RadioResponseInfo& info, + const SendSmsResult& sms) { + rspInfo = info; + sendSmsResult = sms; + parent_v1_6.notify(info.serial); + return Void(); +} diff --git a/radio/1.6/vts/functional/vts_test_util_v1_6.cpp b/radio/1.6/vts/functional/vts_test_util_v1_6.cpp new file mode 100644 index 0000000000..2653865017 --- /dev/null +++ b/radio/1.6/vts/functional/vts_test_util_v1_6.cpp @@ -0,0 +1,52 @@ +/* + * 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 "RadioTest" + +#include +#include +#include "VtsCoreUtil.h" + +::testing::AssertionResult CheckAnyOfErrors( + ::android::hardware::radio::V1_6::RadioError err, + std::vector<::android::hardware::radio::V1_6::RadioError> errors, CheckFlag flag) { + const static vector<::android::hardware::radio::V1_6::RadioError> generalErrors = { + ::android::hardware::radio::V1_6::RadioError::RADIO_NOT_AVAILABLE, + ::android::hardware::radio::V1_6::RadioError::NO_MEMORY, + ::android::hardware::radio::V1_6::RadioError::INTERNAL_ERR, + ::android::hardware::radio::V1_6::RadioError::SYSTEM_ERR, + ::android::hardware::radio::V1_6::RadioError::REQUEST_NOT_SUPPORTED, + ::android::hardware::radio::V1_6::RadioError::CANCELLED}; + if (flag == CHECK_GENERAL_ERROR || flag == CHECK_OEM_AND_GENERAL_ERROR) { + for (size_t i = 0; i < generalErrors.size(); i++) { + if (err == generalErrors[i]) { + return testing::AssertionSuccess(); + } + } + } + if (flag == CHECK_OEM_ERROR || flag == CHECK_OEM_AND_GENERAL_ERROR) { + if (err >= ::android::hardware::radio::V1_6::RadioError::OEM_ERROR_1 && + err <= ::android::hardware::radio::V1_6::RadioError::OEM_ERROR_25) { + return testing::AssertionSuccess(); + } + } + for (size_t i = 0; i < errors.size(); i++) { + if (err == errors[i]) { + return testing::AssertionSuccess(); + } + } + return testing::AssertionFailure() << "RadioError:" + toString(err) + " is returned"; +} diff --git a/radio/1.6/vts/functional/vts_test_util_v1_6.h b/radio/1.6/vts/functional/vts_test_util_v1_6.h new file mode 100644 index 0000000000..e04d201ace --- /dev/null +++ b/radio/1.6/vts/functional/vts_test_util_v1_6.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "vts_test_util.h" + +/* + * Check multiple radio error codes which are possibly returned because of the different + * vendor/devices implementations. It allows optional checks for general errors or/and oem errors. + */ +::testing::AssertionResult CheckAnyOfErrors( + ::android::hardware::radio::V1_6::RadioError err, + std::vector<::android::hardware::radio::V1_6::RadioError> generalError, + CheckFlag flag = CHECK_DEFAULT); -- GitLab From 57909db2e7c684f67cfdbab0630fb5dc7446bcd9 Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Mon, 12 Oct 2020 15:26:17 -0700 Subject: [PATCH 209/790] Add API to configure media filter stream type for Demux Framing Test: atest VtsHalTvTunerV1_1TargetTest Bug: 170339836 Change-Id: Ib42e041ddcd6de36df8af6732715c54097995e92 --- tv/tuner/1.1/IFilter.hal | 11 ++ tv/tuner/1.1/default/Filter.cpp | 21 +++ tv/tuner/1.1/default/Filter.h | 5 + tv/tuner/1.1/types.hal | 127 ++++++++++++++++++ tv/tuner/1.1/vts/functional/FilterTests.cpp | 14 ++ tv/tuner/1.1/vts/functional/FilterTests.h | 2 + .../VtsHalTvTunerV1_1TargetTest.cpp | 1 + .../VtsHalTvTunerV1_1TestConfigurations.h | 6 + 8 files changed, 187 insertions(+) diff --git a/tv/tuner/1.1/IFilter.hal b/tv/tuner/1.1/IFilter.hal index 2ba9bb761d..3ea42094b8 100644 --- a/tv/tuner/1.1/IFilter.hal +++ b/tv/tuner/1.1/IFilter.hal @@ -70,4 +70,15 @@ interface IFilter extends @1.0::IFilter { * memory is not initialized. */ getAvSharedHandle() generates (Result result, handle avMemory, uint64_t avMemSize); + + /** + * Configure A/V filter’s stream type. This API only applies to A/V filters. + * + * @param avStreamType the stream type for A/V. + * @return return result Result status of the operation. + * SUCCESS if successful, + * INVALID_STATE if configure can't be applied, + * UNKNOWN_ERROR if failed for other reasons. + */ + configureAvStreamType(AvStreamType avStreamType) generates (Result result); }; diff --git a/tv/tuner/1.1/default/Filter.cpp b/tv/tuner/1.1/default/Filter.cpp index c69beca12b..11e323c54c 100644 --- a/tv/tuner/1.1/default/Filter.cpp +++ b/tv/tuner/1.1/default/Filter.cpp @@ -228,6 +228,27 @@ Return Filter::getAvSharedHandle(getAvSharedHandle_cb _hidl_cb) { return Void(); } +Return Filter::configureAvStreamType(const V1_1::AvStreamType& avStreamType) { + ALOGV("%s", __FUNCTION__); + + if (!mIsMediaFilter) { + return Result::UNAVAILABLE; + } + + switch (avStreamType.getDiscriminator()) { + case V1_1::AvStreamType::hidl_discriminator::audio: + mAudioStreamType = static_cast(avStreamType.audio()); + break; + case V1_1::AvStreamType::hidl_discriminator::video: + mVideoStreamType = static_cast(avStreamType.video()); + break; + default: + break; + } + + return Result::SUCCESS; +} + bool Filter::createFilterMQ() { ALOGV("%s", __FUNCTION__); diff --git a/tv/tuner/1.1/default/Filter.h b/tv/tuner/1.1/default/Filter.h index f6776661d3..f8b9a651e4 100644 --- a/tv/tuner/1.1/default/Filter.h +++ b/tv/tuner/1.1/default/Filter.h @@ -82,6 +82,8 @@ class Filter : public V1_1::IFilter { virtual Return getAvSharedHandle(getAvSharedHandle_cb _hidl_cb) override; + virtual Return configureAvStreamType(const V1_1::AvStreamType& avStreamType) override; + /** * To create a FilterMQ and its Event Flag. * @@ -225,6 +227,9 @@ class Filter : public V1_1::IFilter { hidl_handle mSharedAvMemHandle; bool mUsingSharedAvMem = true; uint32_t mSharedAvMemOffset = 0; + + uint32_t mAudioStreamType; + uint32_t mVideoStreamType; }; } // namespace implementation diff --git a/tv/tuner/1.1/types.hal b/tv/tuner/1.1/types.hal index 695826ab16..1ed64037e1 100644 --- a/tv/tuner/1.1/types.hal +++ b/tv/tuner/1.1/types.hal @@ -568,3 +568,130 @@ safe_union FrontendScanMessageExt1_1 { bool isHighPriority; }; + +@export +enum VideoStreamType : uint32_t { + UNDEFINED, + /* + * ITU-T | ISO/IEC Reserved + */ + RESERVED, + /* + * ISO/IEC 11172 + */ + MPEG1, + /* + * ITU-T Rec.H.262 and ISO/IEC 13818-2 + */ + MPEG2, + /* + * ISO/IEC 14496-2 (MPEG-4 H.263 based video) + */ + MPEG4P2, + /* + * ITU-T Rec.H.264 and ISO/IEC 14496-10 + */ + AVC, + /* + * ITU-T Rec. H.265 and ISO/IEC 23008-2 + */ + HEVC, + /* + * Microsoft VC.1 + */ + VC1, + /* + * Google VP8 + */ + VP8, + /* + * Google VP9 + */ + VP9, + /* + * AOMedia Video 1 + */ + AV1, + /* + * Chinese Standard + */ + AVS, + /* + * New Chinese Standard + */ + AVS2, +}; + +@export +enum AudioStreamType : uint32_t { + UNDEFINED, + /* + * Uncompressed Audio + */ + PCM, + /* + * MPEG Audio Layer III versions + */ + MP3, + /* + * ISO/IEC 11172 Audio + */ + MPEG1, + /* + * ISO/IEC 13818-3 + */ + MPEG2, + /* + * ISO/IEC 23008-3 (MPEG-H Part 3) + */ + MPEGH, + /* + * ISO/IEC 14496-3 + */ + AAC, + /* + * Dolby Digital + */ + AC3, + /* + * Dolby Digital Plus + */ + EAC3, + /* + * Dolby AC-4 + */ + AC4, + /* + * Basic DTS + */ + DTS, + /* + * High Resolution DTS + */ + DTS_HD, + /* + * Windows Media Audio + */ + WMA, + /* + * Opus Interactive Audio Codec + */ + OPUS, + /* + * VORBIS Interactive Audio Codec + */ + VORBIS, + /* + * SJ/T 11368-2006 + */ + DRA, +}; + +/** + * Stream type for A/V filter. + */ +safe_union AvStreamType { + VideoStreamType video; + + AudioStreamType audio; +}; diff --git a/tv/tuner/1.1/vts/functional/FilterTests.cpp b/tv/tuner/1.1/vts/functional/FilterTests.cpp index 5a8985dc2a..e661735808 100644 --- a/tv/tuner/1.1/vts/functional/FilterTests.cpp +++ b/tv/tuner/1.1/vts/functional/FilterTests.cpp @@ -164,6 +164,20 @@ AssertionResult FilterTests::configFilter(DemuxFilterSettings setting, uint64_t return AssertionResult(status == Result::SUCCESS); } +AssertionResult FilterTests::configAvFilterStreamType(AvStreamType type, uint64_t filterId) { + Result status; + EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first."; + sp filter_v1_1 = + android::hardware::tv::tuner::V1_1::IFilter::castFrom(mFilters[filterId]); + if (filter_v1_1 != NULL) { + status = filter_v1_1->configureAvStreamType(type); + } else { + ALOGW("[vts] Can't cast IFilter into v1_1."); + return failure(); + } + return AssertionResult(status == Result::SUCCESS); +} + AssertionResult FilterTests::configIpFilterCid(uint32_t ipCid, uint64_t filterId) { Result status; EXPECT_TRUE(mFilters[filterId]) << "Open Ip filter first."; diff --git a/tv/tuner/1.1/vts/functional/FilterTests.h b/tv/tuner/1.1/vts/functional/FilterTests.h index bc6db86f9c..3472e4ebb5 100644 --- a/tv/tuner/1.1/vts/functional/FilterTests.h +++ b/tv/tuner/1.1/vts/functional/FilterTests.h @@ -54,6 +54,7 @@ using android::hardware::tv::tuner::V1_0::DemuxTsFilterType; using android::hardware::tv::tuner::V1_0::IDemux; using android::hardware::tv::tuner::V1_0::IFilter; using android::hardware::tv::tuner::V1_0::Result; +using android::hardware::tv::tuner::V1_1::AvStreamType; using android::hardware::tv::tuner::V1_1::DemuxFilterEventExt; using android::hardware::tv::tuner::V1_1::IFilterCallback; using android::hardware::tv::tuner::V1_1::ITuner; @@ -150,6 +151,7 @@ class FilterTests { AssertionResult getSharedAvMemoryHandle(uint64_t filterId); AssertionResult releaseShareAvHandle(uint64_t filterId); AssertionResult configFilter(DemuxFilterSettings setting, uint64_t filterId); + AssertionResult configAvFilterStreamType(AvStreamType type, uint64_t filterId); AssertionResult configIpFilterCid(uint32_t ipCid, uint64_t filterId); AssertionResult getFilterMQDescriptor(uint64_t filterId); AssertionResult startFilter(uint64_t filterId); diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp index 263b0e9a8c..db2ac1bda1 100644 --- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp @@ -69,6 +69,7 @@ void TunerBroadcastHidlTest::mediaFilterUsingSharedMemoryTest(FilterConfig filte ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(filterId)); ASSERT_TRUE(mFilterTests.getSharedAvMemoryHandle(filterId)); ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId)); + ASSERT_TRUE(mFilterTests.configAvFilterStreamType(filterConf.streamType, filterId)); ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId)); ASSERT_TRUE(mFilterTests.startFilter(filterId)); // tune test diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h index a3bfa1f87a..cb86ce8546 100644 --- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h @@ -46,9 +46,12 @@ using android::hardware::tv::tuner::V1_0::FrontendSettings; using android::hardware::tv::tuner::V1_0::FrontendType; using android::hardware::tv::tuner::V1_0::PlaybackSettings; using android::hardware::tv::tuner::V1_0::RecordSettings; +using android::hardware::tv::tuner::V1_1::AudioStreamType; +using android::hardware::tv::tuner::V1_1::AvStreamType; using android::hardware::tv::tuner::V1_1::FrontendSettingsExt1_1; using android::hardware::tv::tuner::V1_1::FrontendStatusExt1_1; using android::hardware::tv::tuner::V1_1::FrontendStatusTypeExt1_1; +using android::hardware::tv::tuner::V1_1::VideoStreamType; using namespace std; @@ -91,6 +94,7 @@ struct FilterConfig { uint32_t bufferSize; DemuxFilterType type; DemuxFilterSettings settings; + AvStreamType streamType; uint32_t ipCid; bool operator<(const FilterConfig& /*c*/) const { return false; } @@ -184,6 +188,7 @@ inline void initFilterConfig() { filterArray[TS_VIDEO1].bufferSize = FMQ_SIZE_16M; filterArray[TS_VIDEO1].settings.ts().tpid = 256; filterArray[TS_VIDEO1].settings.ts().filterSettings.av({.isPassthrough = false}); + filterArray[TS_VIDEO1].streamType.video(VideoStreamType::MPEG1); // TS AUDIO filter setting filterArray[TS_AUDIO0].type.mainType = DemuxFilterMainType::TS; filterArray[TS_AUDIO0].type.subType.tsFilterType(DemuxTsFilterType::AUDIO); @@ -195,6 +200,7 @@ inline void initFilterConfig() { filterArray[TS_AUDIO1].bufferSize = FMQ_SIZE_16M; filterArray[TS_AUDIO1].settings.ts().tpid = 257; filterArray[TS_AUDIO1].settings.ts().filterSettings.av({.isPassthrough = false}); + filterArray[TS_VIDEO1].streamType.audio(AudioStreamType::MP3); // TS PES filter setting filterArray[TS_PES0].type.mainType = DemuxFilterMainType::TS; filterArray[TS_PES0].type.subType.tsFilterType(DemuxTsFilterType::PES); -- GitLab From 8230f8c6f2c7e7afac7b1312bb40bc820d5b465a Mon Sep 17 00:00:00 2001 From: Slava Shklyaev Date: Thu, 20 Aug 2020 11:55:52 +0100 Subject: [PATCH 210/790] Migrate NNAPI to canonical types Bug: 160669906 Test: m Change-Id: Ib5282e5477e7c632485a966b2fef02044ce9fb96 --- neuralnetworks/1.3/vts/functional/GeneratedTestHarness.cpp | 2 +- neuralnetworks/1.3/vts/functional/TestAssertions.cpp | 6 ++++++ neuralnetworks/1.3/vts/functional/ValidateRequest.cpp | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/neuralnetworks/1.3/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/1.3/vts/functional/GeneratedTestHarness.cpp index 914a01a5e6..0a956958f9 100644 --- a/neuralnetworks/1.3/vts/functional/GeneratedTestHarness.cpp +++ b/neuralnetworks/1.3/vts/functional/GeneratedTestHarness.cpp @@ -644,7 +644,7 @@ void EvaluatePreparedModel(const sp& device, const sp& int n; std::tie(n, outputShapes, timing, std::ignore) = controller->compute(request10, testConfig.measureTiming, keys); - executionStatus = nn::convertResultCodeToErrorStatus(n); + executionStatus = nn::convertToV1_3(nn::convertResultCodeToErrorStatus(n)); break; } diff --git a/neuralnetworks/1.3/vts/functional/TestAssertions.cpp b/neuralnetworks/1.3/vts/functional/TestAssertions.cpp index a7569e6dfe..1a40721f7b 100644 --- a/neuralnetworks/1.3/vts/functional/TestAssertions.cpp +++ b/neuralnetworks/1.3/vts/functional/TestAssertions.cpp @@ -15,10 +15,16 @@ */ #include +#include "ControlFlow.h" #include "TestHarness.h" namespace android::hardware::neuralnetworks::V1_3 { +static_assert(static_cast(LoopTimeoutDurationNs::DEFAULT) == + nn::operation_while::kTimeoutNsDefault); +static_assert(static_cast(LoopTimeoutDurationNs::MAXIMUM) == + nn::operation_while::kTimeoutNsMaximum); + // Make sure that the HIDL enums are compatible with the values defined in // frameworks/ml/nn/tools/test_generator/test_harness/include/TestHarness.h. using namespace test_helper; diff --git a/neuralnetworks/1.3/vts/functional/ValidateRequest.cpp b/neuralnetworks/1.3/vts/functional/ValidateRequest.cpp index 1ae8b3f21d..3b441fb6b0 100644 --- a/neuralnetworks/1.3/vts/functional/ValidateRequest.cpp +++ b/neuralnetworks/1.3/vts/functional/ValidateRequest.cpp @@ -116,7 +116,7 @@ static void validate(const sp& preparedModel, const std::string& // execute and verify const auto [n, outputShapes, timing, fallback] = burst->compute(request10, measure, keys); - const ErrorStatus status = nn::convertResultCodeToErrorStatus(n); + const ErrorStatus status = nn::convertToV1_3(nn::convertResultCodeToErrorStatus(n)); EXPECT_EQ(ErrorStatus::INVALID_ARGUMENT, status); EXPECT_EQ(outputShapes.size(), 0); EXPECT_TRUE(badTiming(timing)); -- GitLab From efc13c0bfe3bc9a4641cb43f1bd144c776524bee Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Thu, 15 Oct 2020 10:13:04 +0800 Subject: [PATCH 211/790] wifi: remove Wifi HIDL hash for S wifi HAL is still under working, freezing these wifi intefaces results in unexpected merge conflict and unnecessary hash changes. Bug: 0 Test: build Change-Id: I5d3066651358baf79a6c96feeb4e7c294f6a4c08 --- current.txt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/current.txt b/current.txt index 9f03b7f3fc..d8ca42c8a4 100644 --- a/current.txt +++ b/current.txt @@ -780,7 +780,3 @@ cd84ab19c590e0e73dd2307b591a3093ee18147ef95e6d5418644463a6620076 android.hardwar # NOTE: new HALs are recommended to be in AIDL 6e64b33f1b720b66b0deb5e08dee37a99deaa94e2e9ebf7806703cabab56e21d android.hardware.contexthub@1.2::IContexthub 3fb83f4539cab2c7bf9fdbecf7265d1c1dd6e8de9694046fe512b493c127ccea android.hardware.contexthub@1.2::types -57d183b10b13ec0a8e542c0b3d61991ae541c60e85dbbc5499bb21dfd068cbb8 android.hardware.wifi.supplicant@1.4::types -17818b6b1952a75e4364ae82c534b9d2f5c0a9765a56256b16faa5a5cf45d3a8 android.hardware.wifi.supplicant@1.4::ISupplicant -8342b5f6ec8f48ad2b741128aede010995d0b5709257b7ec09bb469b4f61ef1a android.hardware.wifi.supplicant@1.4::ISupplicantStaIface -6f969b191f0b699ceab0573548f1ac505853e56e704711edc51b51976d4f87ad android.hardware.wifi.supplicant@1.4::ISupplicantStaNetwork -- GitLab From 53af9512bd48d65abf1ed57f30102b526dbafce1 Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Wed, 14 Oct 2020 16:04:33 -0700 Subject: [PATCH 212/790] Create OWNERS files for biometric AIDLs Bug: none Test: none Change-Id: Idbe85483a66365095e0afab9bb64d4ea6068ddf7 --- biometrics/face/aidl/OWNERS | 2 ++ biometrics/fingerprint/aidl/OWNERS | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 biometrics/face/aidl/OWNERS create mode 100644 biometrics/fingerprint/aidl/OWNERS diff --git a/biometrics/face/aidl/OWNERS b/biometrics/face/aidl/OWNERS new file mode 100644 index 0000000000..36d726136f --- /dev/null +++ b/biometrics/face/aidl/OWNERS @@ -0,0 +1,2 @@ +ilyamaty@google.com +kchyn@google.com diff --git a/biometrics/fingerprint/aidl/OWNERS b/biometrics/fingerprint/aidl/OWNERS new file mode 100644 index 0000000000..36d726136f --- /dev/null +++ b/biometrics/fingerprint/aidl/OWNERS @@ -0,0 +1,2 @@ +ilyamaty@google.com +kchyn@google.com -- GitLab From 3ec6781c357ed30e1d4abbef4ea6c1b36fcbba60 Mon Sep 17 00:00:00 2001 From: Nate Jiang Date: Mon, 24 Aug 2020 11:04:31 -0700 Subject: [PATCH 213/790] [AWARE] Add support for instant communication mode Bug: 160725208 Test: atest WifiNanIfaceTest,VtsHalWifiNanV1_0TargetTest, VtsHalWifiNanV1_2TargetTest, VtsHalWifiNanV1_4TargetTest, VtsHalWifiNanV1_5TargetTest Change-Id: I66c8532dcd50d5702edbcd89005b9e7373659594 --- wifi/1.0/vts/functional/Android.bp | 5 + .../functional/wifi_nan_iface_hidl_test.cpp | 11 + wifi/1.4/vts/functional/Android.bp | 1 + .../functional/wifi_nan_iface_hidl_test.cpp | 46 ++ wifi/1.5/Android.bp | 2 + wifi/1.5/IWifiNanIface.hal | 113 ++++ wifi/1.5/IWifiNanIfaceEventCallback.hal | 44 ++ wifi/1.5/default/hidl_struct_util.cpp | 98 ++- wifi/1.5/default/hidl_struct_util.h | 13 +- .../tests/wifi_nan_iface_unit_tests.cpp | 11 +- wifi/1.5/default/wifi_nan_iface.cpp | 96 ++- wifi/1.5/default/wifi_nan_iface.h | 32 +- wifi/1.5/types.hal | 32 + wifi/1.5/vts/OWNERS | 2 + wifi/1.5/vts/functional/Android.bp | 39 ++ .../functional/wifi_nan_iface_hidl_test.cpp | 628 ++++++++++++++++++ 16 files changed, 1127 insertions(+), 46 deletions(-) create mode 100644 wifi/1.5/IWifiNanIface.hal create mode 100644 wifi/1.5/IWifiNanIfaceEventCallback.hal create mode 100644 wifi/1.5/vts/OWNERS create mode 100644 wifi/1.5/vts/functional/Android.bp create mode 100644 wifi/1.5/vts/functional/wifi_nan_iface_hidl_test.cpp diff --git a/wifi/1.0/vts/functional/Android.bp b/wifi/1.0/vts/functional/Android.bp index cad54feb5c..30512a9f1a 100644 --- a/wifi/1.0/vts/functional/Android.bp +++ b/wifi/1.0/vts/functional/Android.bp @@ -73,6 +73,11 @@ cc_test { static_libs: [ "VtsHalWifiV1_0TargetTestUtil", "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", "libwifi-system-iface", ], test_suites: [ diff --git a/wifi/1.0/vts/functional/wifi_nan_iface_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_nan_iface_hidl_test.cpp index 17abbd7096..a74987cf24 100644 --- a/wifi/1.0/vts/functional/wifi_nan_iface_hidl_test.cpp +++ b/wifi/1.0/vts/functional/wifi_nan_iface_hidl_test.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -483,6 +484,16 @@ TEST_P(WifiNanIfaceHidlTest, FailOnIfaceInvalid) { TEST_P(WifiNanIfaceHidlTest, getCapabilitiesRequest) { uint16_t inputCmdId = 10; callbackType = INVALID; + sp<::android::hardware::wifi::V1_5::IWifiNanIface> iface_converted = + ::android::hardware::wifi::V1_5::IWifiNanIface::castFrom(iwifiNanIface); + if (iface_converted != nullptr) { + ASSERT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED, + HIDL_INVOKE(iwifiNanIface, getCapabilitiesRequest, inputCmdId) + .code); + // Skip this test since this API is deprecated in this newer HAL version + return; + } + ASSERT_EQ( WifiStatusCode::SUCCESS, HIDL_INVOKE(iwifiNanIface, getCapabilitiesRequest, inputCmdId).code); diff --git a/wifi/1.4/vts/functional/Android.bp b/wifi/1.4/vts/functional/Android.bp index 59a35e0262..0051d27d6b 100644 --- a/wifi/1.4/vts/functional/Android.bp +++ b/wifi/1.4/vts/functional/Android.bp @@ -52,6 +52,7 @@ cc_test { "android.hardware.wifi@1.2", "android.hardware.wifi@1.3", "android.hardware.wifi@1.4", + "android.hardware.wifi@1.5", "libwifi-system-iface", ], test_suites: [ diff --git a/wifi/1.4/vts/functional/wifi_nan_iface_hidl_test.cpp b/wifi/1.4/vts/functional/wifi_nan_iface_hidl_test.cpp index 9b69f57233..3ac047d2c8 100644 --- a/wifi/1.4/vts/functional/wifi_nan_iface_hidl_test.cpp +++ b/wifi/1.4/vts/functional/wifi_nan_iface_hidl_test.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -488,6 +489,17 @@ TEST_P(WifiNanIfaceHidlTest, enableRequest_1_4InvalidArgs) { callbackType = INVALID; ::android::hardware::wifi::V1_4::NanEnableRequest nanEnableRequest = {}; NanConfigRequestSupplemental nanConfigRequestSupp = {}; + + sp<::android::hardware::wifi::V1_5::IWifiNanIface> iface_converted = + ::android::hardware::wifi::V1_5::IWifiNanIface::castFrom(iwifiNanIface); + if (iface_converted != nullptr) { + ASSERT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED, + HIDL_INVOKE(iwifiNanIface, enableRequest_1_4, inputCmdId, + nanEnableRequest, nanConfigRequestSupp) + .code); + // Skip this test since this API is deprecated in this newer HAL version + return; + } ASSERT_EQ(WifiStatusCode::SUCCESS, HIDL_INVOKE(iwifiNanIface, enableRequest_1_4, inputCmdId, nanEnableRequest, nanConfigRequestSupp) @@ -509,6 +521,17 @@ TEST_P(WifiNanIfaceHidlTest, enableRequest_1_4ShimInvalidArgs) { nanEnableRequest.configParams.numberOfPublishServiceIdsInBeacon = 128; // must be <= 127 NanConfigRequestSupplemental nanConfigRequestSupp = {}; + + sp<::android::hardware::wifi::V1_5::IWifiNanIface> iface_converted = + ::android::hardware::wifi::V1_5::IWifiNanIface::castFrom(iwifiNanIface); + if (iface_converted != nullptr) { + ASSERT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED, + HIDL_INVOKE(iwifiNanIface, enableRequest_1_4, inputCmdId, + nanEnableRequest, nanConfigRequestSupp) + .code); + // Skip this test since this API is deprecated in this newer HAL version + return; + } ASSERT_EQ(WifiStatusCode::ERROR_INVALID_ARGS, HIDL_INVOKE(iwifiNanIface, enableRequest_1_4, inputCmdId, nanEnableRequest, nanConfigRequestSupp) @@ -523,6 +546,17 @@ TEST_P(WifiNanIfaceHidlTest, configRequest_1_4InvalidArgs) { callbackType = INVALID; ::android::hardware::wifi::V1_4::NanConfigRequest nanConfigRequest = {}; NanConfigRequestSupplemental nanConfigRequestSupp = {}; + + sp<::android::hardware::wifi::V1_5::IWifiNanIface> iface_converted = + ::android::hardware::wifi::V1_5::IWifiNanIface::castFrom(iwifiNanIface); + if (iface_converted != nullptr) { + ASSERT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED, + HIDL_INVOKE(iwifiNanIface, configRequest_1_4, inputCmdId, + nanConfigRequest, nanConfigRequestSupp) + .code); + // Skip this test since this API is deprecated in this newer HAL version + return; + } ASSERT_EQ(WifiStatusCode::SUCCESS, HIDL_INVOKE(iwifiNanIface, configRequest_1_4, inputCmdId, nanConfigRequest, nanConfigRequestSupp) @@ -543,6 +577,18 @@ TEST_P(WifiNanIfaceHidlTest, configRequest_1_4ShimInvalidArgs) { ::android::hardware::wifi::V1_4::NanConfigRequest nanConfigRequest = {}; nanConfigRequest.numberOfPublishServiceIdsInBeacon = 128; // must be <= 127 NanConfigRequestSupplemental nanConfigRequestSupp = {}; + + sp<::android::hardware::wifi::V1_5::IWifiNanIface> iface_converted = + ::android::hardware::wifi::V1_5::IWifiNanIface::castFrom(iwifiNanIface); + if (iface_converted != nullptr) { + ASSERT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED, + HIDL_INVOKE(iwifiNanIface, configRequest_1_4, inputCmdId, + nanConfigRequest, nanConfigRequestSupp) + .code); + // Skip this test since this API is deprecated in this newer HAL version + return; + } + ASSERT_EQ(WifiStatusCode::ERROR_INVALID_ARGS, HIDL_INVOKE(iwifiNanIface, configRequest_1_4, inputCmdId, nanConfigRequest, nanConfigRequestSupp) diff --git a/wifi/1.5/Android.bp b/wifi/1.5/Android.bp index 53047603b9..ecb0a35f18 100644 --- a/wifi/1.5/Android.bp +++ b/wifi/1.5/Android.bp @@ -7,6 +7,8 @@ hidl_interface { "types.hal", "IWifi.hal", "IWifiChip.hal", + "IWifiNanIface.hal", + "IWifiNanIfaceEventCallback.hal", ], interfaces: [ "android.hardware.wifi@1.0", diff --git a/wifi/1.5/IWifiNanIface.hal b/wifi/1.5/IWifiNanIface.hal new file mode 100644 index 0000000000..93257b525a --- /dev/null +++ b/wifi/1.5/IWifiNanIface.hal @@ -0,0 +1,113 @@ +/* + * 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. + */ + +package android.hardware.wifi@1.5; + +import @1.0::CommandIdShort; +import @1.0::WifiStatus; +import @1.4::IWifiNanIface; +import @1.4::NanConfigRequest; +import @1.4::NanEnableRequest; +import IWifiNanIfaceEventCallback; +import NanConfigRequestSupplemental; + +/** + * Interface used to represent a single NAN (Neighbour Aware Network) iface. + * + * References to "NAN Spec" are to the Wi-Fi Alliance "Wi-Fi Neighbor Awareness + * Networking (NAN) Technical Specification". + */ +interface IWifiNanIface extends @1.4::IWifiNanIface { + /** + * Enable NAN: configures and activates NAN clustering (does not start + * a discovery session or set up data-interfaces or data-paths). Use the + * |IWifiNanIface.configureRequest| method to change the configuration of an already enabled + * NAN interface. + * Asynchronous response is with |IWifiNanIfaceEventCallback.notifyEnableResponse|. + * + * Note: supersedes the @1.4::IWifiNanIface.enableRequest() method which is deprecated as of + * HAL version 1.5. + * + * @param cmdId command Id to use for this invocation. + * @param msg1 Instance of |NanEnableRequest|. + * @param msg2 Instance of |NanConfigRequestSupplemental|. + * @return status WifiStatus of the operation. + * Possible status codes: + * |WifiStatusCode.SUCCESS|, + * |WifiStatusCode.ERROR_NOT_SUPPORTED|, + * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|, + * |WifiStatusCode.ERROR_INVALID_ARGS|, + * |WifiStatusCode.ERROR_UNKNOWN| + */ + enableRequest_1_5(CommandIdShort cmdId, NanEnableRequest msg1, + NanConfigRequestSupplemental msg2) generates (WifiStatus status); + + /** + * Configure NAN: configures an existing NAN functionality (i.e. assumes + * |IWifiNanIface.enableRequest| already submitted and succeeded). + * Asynchronous response is with |IWifiNanIfaceEventCallback.notifyConfigResponse|. + * + * Note: supersedes the @1.4::IWifiNanIface.configRequest() method which is deprecated as of + * HAL version 1.5. + * + * @param cmdId command Id to use for this invocation. + * @param msg1 Instance of |NanConfigRequest|. + * @param msg2 Instance of |NanConfigRequestSupplemental|. + * @return status WifiStatus of the operation. + * Possible status codes: + * |WifiStatusCode.SUCCESS|, + * |WifiStatusCode.ERROR_NOT_SUPPORTED|, + * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|, + * |WifiStatusCode.ERROR_INVALID_ARGS|, + * |WifiStatusCode.ERROR_UNKNOWN| + */ + configRequest_1_5(CommandIdShort cmdId, NanConfigRequest msg1, + NanConfigRequestSupplemental msg2) generates (WifiStatus status); + + /** + * Requests notifications of significant events on this iface. Multiple calls + * to this must register multiple callbacks each of which must receive all + * events. + * + * Note: supersedes the @1.2::IWifiNanIface.registerEventCallback() method which is deprecated + * as of HAL version 1.5. + * + * @param callback An instance of the |IWifiNanIfaceEventCallback| HIDL interface + * object. + * @return status WifiStatus of the operation. + * Possible status codes: + * |WifiStatusCode.SUCCESS|, + * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID| + */ + registerEventCallback_1_5(IWifiNanIfaceEventCallback callback) + generates (WifiStatus status); + + /** + * Get NAN capabilities. Asynchronous response is with + * |IWifiNanIfaceEventCallback.notifyCapabilitiesResponse|. + + * Note: supersedes the @1.0::IWifiNanIface.getCapabilitiesRequest() method which is deprecated + * as of HAL version 1.5. + * + * @param cmdId command Id to use for this invocation. + * @return status WifiStatus of the operation. + * Possible status codes: + * |WifiStatusCode.SUCCESS|, + * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|, + * |WifiStatusCode.ERROR_UNKNOWN| + */ + getCapabilitiesRequest_1_5(CommandIdShort cmdId) generates (WifiStatus status); +}; \ No newline at end of file diff --git a/wifi/1.5/IWifiNanIfaceEventCallback.hal b/wifi/1.5/IWifiNanIfaceEventCallback.hal new file mode 100644 index 0000000000..867c03c47e --- /dev/null +++ b/wifi/1.5/IWifiNanIfaceEventCallback.hal @@ -0,0 +1,44 @@ +/* + * 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. + */ + +package android.hardware.wifi@1.5; + +import @1.0::CommandIdShort; +import @1.0::WifiNanStatus; +import @1.2::IWifiNanIfaceEventCallback; + +/** + * NAN Response and Asynchronous Event Callbacks. + * + * References to "NAN Spec" are to the Wi-Fi Alliance "Wi-Fi Neighbor Awareness + * Networking (NAN) Technical Specification". + */ +interface IWifiNanIfaceEventCallback extends @1.2::IWifiNanIfaceEventCallback { + /** + * Asynchronous callback invoked in response to a capability request + * |IWifiNanIface.getCapabilitiesRequest|. + * + * Note: supersedes the @1.2::IWifiNanIfaceEventCallback.notifyCapabilitiesResponse() method + * which is deprecated as of HAL version 1.5. + * + * @param cmdId command Id corresponding to the original request. + * @param status WifiNanStatus of the operation. Possible status codes are: + * |NanStatusType.SUCCESS| + * @param capabilities Capability data. + */ + oneway notifyCapabilitiesResponse_1_5(CommandIdShort id, WifiNanStatus status, + NanCapabilities capabilities); +}; \ No newline at end of file diff --git a/wifi/1.5/default/hidl_struct_util.cpp b/wifi/1.5/default/hidl_struct_util.cpp index 91a82a7661..578f3e2f0f 100644 --- a/wifi/1.5/default/hidl_struct_util.cpp +++ b/wifi/1.5/default/hidl_struct_util.cpp @@ -1280,7 +1280,7 @@ bool convertHidlNanEnableRequestToLegacy( bool convertHidlNanEnableRequest_1_4ToLegacy( const V1_4::NanEnableRequest& hidl_request1, - const V1_2::NanConfigRequestSupplemental& hidl_request2, + const NanConfigRequestSupplemental& hidl_request2, legacy_hal::NanEnableRequest* legacy_request) { if (!legacy_request) { LOG(ERROR) @@ -1295,14 +1295,60 @@ bool convertHidlNanEnableRequest_1_4ToLegacy( legacy_request->config_discovery_beacon_int = 1; legacy_request->discovery_beacon_interval = - hidl_request2.discoveryBeaconIntervalMs; + hidl_request2.V1_2.discoveryBeaconIntervalMs; legacy_request->config_nss = 1; - legacy_request->nss = hidl_request2.numberOfSpatialStreamsInDiscovery; + legacy_request->nss = hidl_request2.V1_2.numberOfSpatialStreamsInDiscovery; legacy_request->config_dw_early_termination = 1; legacy_request->enable_dw_termination = - hidl_request2.enableDiscoveryWindowEarlyTermination; + hidl_request2.V1_2.enableDiscoveryWindowEarlyTermination; legacy_request->config_enable_ranging = 1; - legacy_request->enable_ranging = hidl_request2.enableRanging; + 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) { + if (!legacy_request) { + LOG(ERROR) + << "convertHidlNanEnableRequest_1_5ToLegacy: null legacy_request"; + return false; + } + + *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; + + return true; +} + +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"; + return false; + } + + *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; return true; } @@ -1794,7 +1840,7 @@ bool convertHidlNanConfigRequestToLegacy( bool convertHidlNanConfigRequest_1_4ToLegacy( const V1_4::NanConfigRequest& hidl_request1, - const V1_2::NanConfigRequestSupplemental& hidl_request2, + const NanConfigRequestSupplemental& hidl_request2, legacy_hal::NanConfigRequest* legacy_request) { if (!legacy_request) { LOG(ERROR) << "convertHidlNanConfigRequest_1_4ToLegacy: legacy_request " @@ -1809,14 +1855,14 @@ bool convertHidlNanConfigRequest_1_4ToLegacy( legacy_request->config_discovery_beacon_int = 1; legacy_request->discovery_beacon_interval = - hidl_request2.discoveryBeaconIntervalMs; + hidl_request2.V1_2.discoveryBeaconIntervalMs; legacy_request->config_nss = 1; - legacy_request->nss = hidl_request2.numberOfSpatialStreamsInDiscovery; + legacy_request->nss = hidl_request2.V1_2.numberOfSpatialStreamsInDiscovery; legacy_request->config_dw_early_termination = 1; legacy_request->enable_dw_termination = - hidl_request2.enableDiscoveryWindowEarlyTermination; + hidl_request2.V1_2.enableDiscoveryWindowEarlyTermination; legacy_request->config_enable_ranging = 1; - legacy_request->enable_ranging = hidl_request2.enableRanging; + legacy_request->enable_ranging = hidl_request2.V1_2.enableRanging; return true; } @@ -2023,27 +2069,31 @@ bool convertLegacyNanCapabilitiesResponseToHidl( } *hidl_response = {}; - hidl_response->maxConcurrentClusters = + hidl_response->V1_0.maxConcurrentClusters = legacy_response.max_concurrent_nan_clusters; - hidl_response->maxPublishes = legacy_response.max_publishes; - hidl_response->maxSubscribes = legacy_response.max_subscribes; - hidl_response->maxServiceNameLen = legacy_response.max_service_name_len; - hidl_response->maxMatchFilterLen = legacy_response.max_match_filter_len; - hidl_response->maxTotalMatchFilterLen = + 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->maxServiceSpecificInfoLen = + hidl_response->V1_0.maxServiceSpecificInfoLen = legacy_response.max_service_specific_info_len; - hidl_response->maxExtendedServiceSpecificInfoLen = + hidl_response->V1_0.maxExtendedServiceSpecificInfoLen = legacy_response.max_sdea_service_specific_info_len; - hidl_response->maxNdiInterfaces = legacy_response.max_ndi_interfaces; - hidl_response->maxNdpSessions = legacy_response.max_ndp_sessions; - hidl_response->maxAppInfoLen = legacy_response.max_app_info_len; - hidl_response->maxQueuedTransmitFollowupMsgs = + 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->maxSubscribeInterfaceAddresses = + hidl_response->V1_0.maxSubscribeInterfaceAddresses = legacy_response.max_subscribe_address; - hidl_response->supportedCipherSuites = + hidl_response->V1_0.supportedCipherSuites = legacy_response.cipher_suites_supported; + hidl_response->instantCommunicationModeSupportFlag = + legacy_response.is_instant_mode_supported; return true; } diff --git a/wifi/1.5/default/hidl_struct_util.h b/wifi/1.5/default/hidl_struct_util.h index c6dc692367..b0b1d22dfe 100644 --- a/wifi/1.5/default/hidl_struct_util.h +++ b/wifi/1.5/default/hidl_struct_util.h @@ -26,6 +26,7 @@ #include #include #include +#include #include "wifi_legacy_hal.h" @@ -122,11 +123,19 @@ bool convertHidlNanConfigRequestToLegacy( legacy_hal::NanConfigRequest* legacy_request); bool convertHidlNanEnableRequest_1_4ToLegacy( const V1_4::NanEnableRequest& hidl_request1, - const V1_2::NanConfigRequestSupplemental& hidl_request2, + const NanConfigRequestSupplemental& hidl_request2, legacy_hal::NanEnableRequest* legacy_request); bool convertHidlNanConfigRequest_1_4ToLegacy( const V1_4::NanConfigRequest& hidl_request1, - const V1_2::NanConfigRequestSupplemental& hidl_request2, + 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, 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 index 411190b01a..52f0c2bcde 100644 --- a/wifi/1.5/default/tests/wifi_nan_iface_unit_tests.cpp +++ b/wifi/1.5/default/tests/wifi_nan_iface_unit_tests.cpp @@ -41,7 +41,6 @@ namespace wifi { namespace V1_5 { namespace implementation { -using android::hardware::wifi::V1_2::IWifiNanIfaceEventCallback; using android::hardware::wifi::V1_2::NanDataPathConfirmInd; bool CaptureIfaceEventHandlers( @@ -56,9 +55,10 @@ class MockNanIfaceEventCallback : public IWifiNanIfaceEventCallback { public: MockNanIfaceEventCallback() = default; - MOCK_METHOD3(notifyCapabilitiesResponse, - Return(uint16_t, const WifiNanStatus&, - const NanCapabilities&)); + MOCK_METHOD3( + notifyCapabilitiesResponse, + Return(uint16_t, const WifiNanStatus&, + const android::hardware::wifi::V1_0::NanCapabilities&)); MOCK_METHOD2(notifyEnableResponse, Return(uint16_t, const WifiNanStatus&)); MOCK_METHOD2(notifyConfigResponse, @@ -108,6 +108,9 @@ class MockNanIfaceEventCallback : public IWifiNanIfaceEventCallback { Return(const NanDataPathConfirmInd&)); MOCK_METHOD1(eventDataPathScheduleUpdate, Return(const NanDataPathScheduleUpdateInd&)); + MOCK_METHOD3(notifyCapabilitiesResponse_1_5, + Return(uint16_t, const WifiNanStatus&, + const NanCapabilities&)); }; class WifiNanIfaceTest : public Test { diff --git a/wifi/1.5/default/wifi_nan_iface.cpp b/wifi/1.5/default/wifi_nan_iface.cpp index e2b0332a22..0cc6cd5fce 100644 --- a/wifi/1.5/default/wifi_nan_iface.cpp +++ b/wifi/1.5/default/wifi_nan_iface.cpp @@ -166,10 +166,10 @@ WifiNanIface::WifiNanIface( return; } for (const auto& callback : - shared_ptr_this->getEventCallbacks()) { + shared_ptr_this->getEventCallbacks_1_5()) { if (!callback - ->notifyCapabilitiesResponse(id, wifiNanStatus, - hidl_struct) + ->notifyCapabilitiesResponse_1_5(id, wifiNanStatus, + hidl_struct) .isOk()) { LOG(ERROR) << "Failed to invoke the callback"; } @@ -545,6 +545,7 @@ void WifiNanIface::invalidate() { 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. @@ -566,6 +567,10 @@ WifiNanIface::getEventCallbacks_1_2() { return event_cb_handler_1_2_.getCallbacks(); } +std::set> WifiNanIface::getEventCallbacks_1_5() { + return event_cb_handler_1_5_.getCallbacks(); +} + Return WifiNanIface::getName(getName_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, &WifiNanIface::getNameInternal, hidl_status_cb); @@ -738,6 +743,39 @@ Return WifiNanIface::configRequest_1_4( hidl_status_cb, cmd_id, msg1, msg2); } +Return WifiNanIface::registerEventCallback_1_5( + const sp& 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 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 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 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 WifiNanIface::getNameInternal() { return {createWifiStatus(WifiStatusCode::SUCCESS), ifname_}; } @@ -754,10 +792,8 @@ WifiStatus WifiNanIface::registerEventCallbackInternal( return createWifiStatus(WifiStatusCode::SUCCESS); } -WifiStatus WifiNanIface::getCapabilitiesRequestInternal(uint16_t cmd_id) { - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->nanGetCapabilities(ifname_, cmd_id); - return createWifiStatusFromLegacyError(legacy_status); +WifiStatus WifiNanIface::getCapabilitiesRequestInternal(uint16_t /* cmd_id */) { + return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); } WifiStatus WifiNanIface::enableRequestInternal( @@ -890,7 +926,7 @@ WifiStatus WifiNanIface::registerEventCallback_1_2Internal( WifiStatus WifiNanIface::enableRequest_1_2Internal( uint16_t /* cmd_id */, const V1_0::NanEnableRequest& /* msg1 */, - const V1_2::NanConfigRequestSupplemental& /*msg2 */) { + const V1_2::NanConfigRequestSupplemental& /* msg2 */) { return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); } @@ -901,10 +937,44 @@ WifiStatus WifiNanIface::configRequest_1_2Internal( } 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& callback) { + sp callback_1_0 = callback; + if (!event_cb_handler_.addCallback(callback_1_0)) { + return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); + } + sp 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_2::NanConfigRequestSupplemental& msg2) { + const NanConfigRequestSupplemental& msg2) { legacy_hal::NanEnableRequest legacy_msg; - if (!hidl_struct_util::convertHidlNanEnableRequest_1_4ToLegacy( + if (!hidl_struct_util::convertHidlNanEnableRequest_1_5ToLegacy( msg1, msg2, &legacy_msg)) { return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); } @@ -913,11 +983,11 @@ WifiStatus WifiNanIface::enableRequest_1_4Internal( return createWifiStatusFromLegacyError(legacy_status); } -WifiStatus WifiNanIface::configRequest_1_4Internal( +WifiStatus WifiNanIface::configRequest_1_5Internal( uint16_t cmd_id, const V1_4::NanConfigRequest& msg1, - const V1_2::NanConfigRequestSupplemental& msg2) { + const NanConfigRequestSupplemental& msg2) { legacy_hal::NanConfigRequest legacy_msg; - if (!hidl_struct_util::convertHidlNanConfigRequest_1_4ToLegacy( + if (!hidl_struct_util::convertHidlNanConfigRequest_1_5ToLegacy( msg1, msg2, &legacy_msg)) { return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); } diff --git a/wifi/1.5/default/wifi_nan_iface.h b/wifi/1.5/default/wifi_nan_iface.h index efdb2da65e..fb9c047ff6 100644 --- a/wifi/1.5/default/wifi_nan_iface.h +++ b/wifi/1.5/default/wifi_nan_iface.h @@ -18,8 +18,8 @@ #define WIFI_NAN_IFACE_H_ #include -#include -#include +#include +#include #include "hidl_callback_util.h" #include "wifi_iface_util.h" @@ -36,7 +36,7 @@ using namespace android::hardware::wifi::V1_2; /** * HIDL interface object used to control a NAN Iface instance. */ -class WifiNanIface : public V1_4::IWifiNanIface { +class WifiNanIface : public V1_5::IWifiNanIface { public: WifiNanIface(const std::string& ifname, bool is_dedicated_iface, const std::weak_ptr legacy_hal, @@ -112,6 +112,19 @@ class WifiNanIface : public V1_4::IWifiNanIface { uint16_t cmd_id, const V1_4::NanConfigRequest& msg1, const V1_2::NanConfigRequestSupplemental& msg2, configRequest_1_4_cb hidl_status_cb) override; + Return registerEventCallback_1_5( + const sp& callback, + registerEventCallback_1_5_cb hidl_status_cb) override; + Return enableRequest_1_5( + uint16_t cmd_id, const V1_4::NanEnableRequest& msg1, + const NanConfigRequestSupplemental& msg2, + enableRequest_1_4_cb hidl_status_cb) override; + Return configRequest_1_5( + uint16_t cmd_id, const V1_4::NanConfigRequest& msg1, + const NanConfigRequestSupplemental& msg2, + configRequest_1_4_cb hidl_status_cb) override; + Return getCapabilitiesRequest_1_5( + uint16_t cmd_id, getCapabilitiesRequest_cb hidl_status_cb) override; private: // Corresponding worker functions for the HIDL methods. @@ -158,11 +171,22 @@ class WifiNanIface : public V1_4::IWifiNanIface { WifiStatus configRequest_1_4Internal( uint16_t cmd_id, const V1_4::NanConfigRequest& msg, const V1_2::NanConfigRequestSupplemental& msg2); + WifiStatus registerEventCallback_1_5Internal( + const sp& 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> getEventCallbacks(); // all 1_2 and descendant callbacks std::set> getEventCallbacks_1_2(); + // all 1_5 and descendant callbacks + std::set> getEventCallbacks_1_5(); std::string ifname_; bool is_dedicated_iface_; @@ -173,6 +197,8 @@ class WifiNanIface : public V1_4::IWifiNanIface { event_cb_handler_; hidl_callback_util::HidlCallbackHandler event_cb_handler_1_2_; + hidl_callback_util::HidlCallbackHandler + event_cb_handler_1_5_; DISALLOW_COPY_AND_ASSIGN(WifiNanIface); }; diff --git a/wifi/1.5/types.hal b/wifi/1.5/types.hal index 71f0679ed9..5873f79b3b 100644 --- a/wifi/1.5/types.hal +++ b/wifi/1.5/types.hal @@ -17,6 +17,9 @@ package android.hardware.wifi@1.5; import @1.0::WifiBand; +import @1.0::NanCipherSuiteType; +import @1.0::NanCapabilities; +import @1.2::NanConfigRequestSupplemental; /** * Wifi bands defined in 80211 spec. @@ -35,3 +38,32 @@ enum WifiBand : @1.0::WifiBand { */ BAND_24GHZ_5GHZ_WITH_DFS_6GHZ_60GHZ = 31, }; + +/** + * NAN configuration request parameters added in the 1.2 HAL. These are supplemental to previous + * versions. + */ +struct NanConfigRequestSupplemental { + /** + * Baseline information as defined in HAL 1.2. + */ + @1.2::NanConfigRequestSupplemental V1_2; + /** + * Controls whether NAN instant communication mode is enabled. + */ + bool enableInstantCommunicationMode; +}; + +/** + * NDP Capabilities response. + */ +struct NanCapabilities { + /** + * Baseline information as defined in HAL 1.0. + */ + @1.0::NanCapabilities V1_0; + /** + * Flag to indicate id instant communication mode is supported. + */ + bool instantCommunicationModeSupportFlag; +}; \ No newline at end of file diff --git a/wifi/1.5/vts/OWNERS b/wifi/1.5/vts/OWNERS new file mode 100644 index 0000000000..8bfb14882c --- /dev/null +++ b/wifi/1.5/vts/OWNERS @@ -0,0 +1,2 @@ +rpius@google.com +etancohen@google.com diff --git a/wifi/1.5/vts/functional/Android.bp b/wifi/1.5/vts/functional/Android.bp new file mode 100644 index 0000000000..a7ba498103 --- /dev/null +++ b/wifi/1.5/vts/functional/Android.bp @@ -0,0 +1,39 @@ +// +// Copyright (C) 2020 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// These tests are split out so that they can be conditioned on presence of the +// "android.hardware.wifi.aware" feature. +cc_test { + name: "VtsHalWifiNanV1_5TargetTest", + defaults: ["VtsHalTargetTestDefaults"], + srcs: [ + "wifi_nan_iface_hidl_test.cpp", + ], + static_libs: [ + "VtsHalWifiV1_0TargetTestUtil", + "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", + "libwifi-system-iface", + ], + test_suites: [ + "general-tests", + "vts", + ], +} diff --git a/wifi/1.5/vts/functional/wifi_nan_iface_hidl_test.cpp b/wifi/1.5/vts/functional/wifi_nan_iface_hidl_test.cpp new file mode 100644 index 0000000000..803d39df15 --- /dev/null +++ b/wifi/1.5/vts/functional/wifi_nan_iface_hidl_test.cpp @@ -0,0 +1,628 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Nanache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wifi_hidl_call_util.h" +#include "wifi_hidl_test_utils.h" + +using namespace ::android::hardware::wifi::V1_0; +using namespace ::android::hardware::wifi::V1_2; +using namespace ::android::hardware::wifi::V1_4; +using namespace ::android::hardware::wifi::V1_5; + +using ::android::sp; +using ::android::hardware::Return; +using ::android::hardware::Void; + +#define TIMEOUT_PERIOD 10 + +android::sp getWifiNanIface_1_5( + const std::string& instance_name) { + return android::hardware::wifi::V1_5::IWifiNanIface::castFrom( + getWifiNanIface(instance_name)); +} + +/** + * Fixture to use for all NAN Iface HIDL interface tests. + */ +class WifiNanIfaceHidlTest : public ::testing::TestWithParam { + public: + virtual void SetUp() override { + if (!::testing::deviceSupportsFeature("android.hardware.wifi.aware")) + GTEST_SKIP() << "Skipping this test since NAN is not supported."; + // Make sure to start with a clean state + stopWifi(GetInstanceName()); + + iwifiNanIface = getWifiNanIface_1_5(GetInstanceName()); + ASSERT_NE(nullptr, iwifiNanIface.get()); + ASSERT_EQ(WifiStatusCode::SUCCESS, + HIDL_INVOKE(iwifiNanIface, registerEventCallback_1_5, + new WifiNanIfaceEventCallback(*this)) + .code); + } + + virtual void TearDown() override { stopWifi(GetInstanceName()); } + + /* Used as a mechanism to inform the test about data/event callback */ + inline void notify() { + std::unique_lock lock(mtx_); + count_++; + cv_.notify_one(); + } + + enum CallbackType { + INVALID = -2, + ANY_CALLBACK = -1, + + NOTIFY_CAPABILITIES_RESPONSE = 0, + NOTIFY_ENABLE_RESPONSE, + NOTIFY_CONFIG_RESPONSE, + NOTIFY_DISABLE_RESPONSE, + NOTIFY_START_PUBLISH_RESPONSE, + NOTIFY_STOP_PUBLISH_RESPONSE, + NOTIFY_START_SUBSCRIBE_RESPONSE, + NOTIFY_STOP_SUBSCRIBE_RESPONSE, + NOTIFY_TRANSMIT_FOLLOWUP_RESPONSE, + NOTIFY_CREATE_DATA_INTERFACE_RESPONSE, + NOTIFY_DELETE_DATA_INTERFACE_RESPONSE, + NOTIFY_INITIATE_DATA_PATH_RESPONSE, + NOTIFY_RESPOND_TO_DATA_PATH_INDICATION_RESPONSE, + NOTIFY_TERMINATE_DATA_PATH_RESPONSE, + NOTIFY_CAPABILITIES_RESPONSE_1_5, + + EVENT_CLUSTER_EVENT, + EVENT_DISABLED, + EVENT_PUBLISH_TERMINATED, + EVENT_SUBSCRIBE_TERMINATED, + EVENT_MATCH, + EVENT_MATCH_EXPIRED, + EVENT_FOLLOWUP_RECEIVED, + EVENT_TRANSMIT_FOLLOWUP, + EVENT_DATA_PATH_REQUEST, + EVENT_DATA_PATH_CONFIRM, + EVENT_DATA_PATH_TERMINATED, + EVENT_DATA_PATH_CONFIRM_1_2, + EVENT_DATA_PATH_SCHEDULE_UPDATE + }; + + /* Test code calls this function to wait for data/event callback */ + /* Must set callbackType = INVALID before call this function */ + inline std::cv_status wait(CallbackType waitForCallbackType) { + std::unique_lock lock(mtx_); + + EXPECT_NE(INVALID, waitForCallbackType); // can't ASSERT in a + // non-void-returning method + + std::cv_status status = std::cv_status::no_timeout; + auto now = std::chrono::system_clock::now(); + while (count_ == 0) { + status = cv_.wait_until(lock, + now + std::chrono::seconds(TIMEOUT_PERIOD)); + if (status == std::cv_status::timeout) return status; + if (waitForCallbackType != ANY_CALLBACK && + callbackType != INVALID && + callbackType != waitForCallbackType) { + count_--; + } + } + count_--; + return status; + } + + class WifiNanIfaceEventCallback + : public ::android::hardware::wifi::V1_5::IWifiNanIfaceEventCallback { + WifiNanIfaceHidlTest& parent_; + + public: + WifiNanIfaceEventCallback(WifiNanIfaceHidlTest& parent) + : parent_(parent){}; + + virtual ~WifiNanIfaceEventCallback() = default; + + Return notifyCapabilitiesResponse( + uint16_t id, const WifiNanStatus& status, + const ::android::hardware::wifi::V1_0::NanCapabilities& + capabilities) override { + parent_.callbackType = NOTIFY_CAPABILITIES_RESPONSE; + + parent_.id = id; + parent_.status = status; + parent_.capabilities = capabilities; + + parent_.notify(); + return Void(); + } + + Return notifyCapabilitiesResponse_1_5( + uint16_t id, const WifiNanStatus& status, + const ::android::hardware::wifi::V1_5::NanCapabilities& + capabilities) override { + parent_.callbackType = NOTIFY_CAPABILITIES_RESPONSE_1_5; + + parent_.id = id; + parent_.status = status; + parent_.capabilities_1_5 = capabilities; + + parent_.notify(); + return Void(); + } + + Return notifyEnableResponse( + uint16_t id, const WifiNanStatus& status) override { + parent_.callbackType = NOTIFY_ENABLE_RESPONSE; + + parent_.id = id; + parent_.status = status; + + parent_.notify(); + return Void(); + } + + Return notifyConfigResponse( + uint16_t id, const WifiNanStatus& status) override { + parent_.callbackType = NOTIFY_CONFIG_RESPONSE; + + parent_.id = id; + parent_.status = status; + + parent_.notify(); + return Void(); + } + + Return notifyDisableResponse( + uint16_t id, const WifiNanStatus& status) override { + parent_.callbackType = NOTIFY_DISABLE_RESPONSE; + + parent_.id = id; + parent_.status = status; + + parent_.notify(); + return Void(); + } + + Return notifyStartPublishResponse(uint16_t id, + const WifiNanStatus& status, + uint8_t sessionId) override { + parent_.callbackType = NOTIFY_START_PUBLISH_RESPONSE; + + parent_.id = id; + parent_.status = status; + parent_.sessionId = sessionId; + + parent_.notify(); + return Void(); + } + + Return notifyStopPublishResponse( + uint16_t id, const WifiNanStatus& status) override { + parent_.callbackType = NOTIFY_STOP_PUBLISH_RESPONSE; + + parent_.id = id; + parent_.status = status; + + parent_.notify(); + return Void(); + } + + Return notifyStartSubscribeResponse(uint16_t id, + const WifiNanStatus& status, + uint8_t sessionId) override { + parent_.callbackType = NOTIFY_START_SUBSCRIBE_RESPONSE; + + parent_.id = id; + parent_.status = status; + parent_.sessionId = sessionId; + + parent_.notify(); + return Void(); + } + + Return notifyStopSubscribeResponse( + uint16_t id, const WifiNanStatus& status) override { + parent_.callbackType = NOTIFY_STOP_SUBSCRIBE_RESPONSE; + + parent_.id = id; + parent_.status = status; + + parent_.notify(); + return Void(); + } + + Return notifyTransmitFollowupResponse( + uint16_t id, const WifiNanStatus& status) override { + parent_.callbackType = NOTIFY_TRANSMIT_FOLLOWUP_RESPONSE; + + parent_.id = id; + parent_.status = status; + + parent_.notify(); + return Void(); + } + + Return notifyCreateDataInterfaceResponse( + uint16_t id, const WifiNanStatus& status) override { + parent_.callbackType = NOTIFY_CREATE_DATA_INTERFACE_RESPONSE; + + parent_.id = id; + parent_.status = status; + + parent_.notify(); + return Void(); + } + + Return notifyDeleteDataInterfaceResponse( + uint16_t id, const WifiNanStatus& status) override { + parent_.callbackType = NOTIFY_DELETE_DATA_INTERFACE_RESPONSE; + + parent_.id = id; + parent_.status = status; + + parent_.notify(); + return Void(); + } + + Return notifyInitiateDataPathResponse( + uint16_t id, const WifiNanStatus& status, + uint32_t ndpInstanceId) override { + parent_.callbackType = NOTIFY_INITIATE_DATA_PATH_RESPONSE; + + parent_.id = id; + parent_.status = status; + parent_.ndpInstanceId = ndpInstanceId; + + parent_.notify(); + return Void(); + } + + Return notifyRespondToDataPathIndicationResponse( + uint16_t id, const WifiNanStatus& status) override { + parent_.callbackType = + NOTIFY_RESPOND_TO_DATA_PATH_INDICATION_RESPONSE; + + parent_.id = id; + parent_.status = status; + + parent_.notify(); + return Void(); + } + + Return notifyTerminateDataPathResponse( + uint16_t id, const WifiNanStatus& status) override { + parent_.callbackType = NOTIFY_TERMINATE_DATA_PATH_RESPONSE; + + parent_.id = id; + parent_.status = status; + + parent_.notify(); + return Void(); + } + + Return eventClusterEvent( + const NanClusterEventInd& event) override { + parent_.callbackType = EVENT_CLUSTER_EVENT; + + parent_.nanClusterEventInd = event; + + parent_.notify(); + return Void(); + } + + Return eventDisabled(const WifiNanStatus& status) override { + parent_.callbackType = EVENT_DISABLED; + + parent_.status = status; + + parent_.notify(); + return Void(); + } + + Return eventPublishTerminated( + uint8_t sessionId, const WifiNanStatus& status) override { + parent_.callbackType = EVENT_PUBLISH_TERMINATED; + + parent_.sessionId = sessionId; + parent_.status = status; + + parent_.notify(); + return Void(); + } + + Return eventSubscribeTerminated( + uint8_t sessionId, const WifiNanStatus& status) override { + parent_.callbackType = EVENT_SUBSCRIBE_TERMINATED; + + parent_.sessionId = sessionId; + parent_.status = status; + + parent_.notify(); + return Void(); + } + + Return eventMatch(const NanMatchInd& event) override { + parent_.callbackType = EVENT_MATCH; + + parent_.nanMatchInd = event; + + parent_.notify(); + return Void(); + } + + Return eventMatchExpired(uint8_t discoverySessionId, + uint32_t peerId) override { + parent_.callbackType = EVENT_MATCH_EXPIRED; + + parent_.sessionId = discoverySessionId; + parent_.peerId = peerId; + + parent_.notify(); + return Void(); + } + + Return eventFollowupReceived( + const NanFollowupReceivedInd& event) override { + parent_.callbackType = EVENT_FOLLOWUP_RECEIVED; + + parent_.nanFollowupReceivedInd = event; + + parent_.notify(); + return Void(); + } + + Return eventTransmitFollowup( + uint16_t id, const WifiNanStatus& status) override { + parent_.callbackType = EVENT_TRANSMIT_FOLLOWUP; + + parent_.id = id; + parent_.status = status; + + parent_.notify(); + return Void(); + } + + Return eventDataPathRequest( + const NanDataPathRequestInd& event) override { + parent_.callbackType = EVENT_DATA_PATH_REQUEST; + + parent_.nanDataPathRequestInd = event; + + parent_.notify(); + return Void(); + } + + Return eventDataPathConfirm( + const ::android::hardware::wifi::V1_0::NanDataPathConfirmInd& event) + override { + parent_.callbackType = EVENT_DATA_PATH_CONFIRM; + + parent_.nanDataPathConfirmInd = event; + + parent_.notify(); + return Void(); + } + + Return eventDataPathTerminated(uint32_t ndpInstanceId) override { + parent_.callbackType = EVENT_DATA_PATH_TERMINATED; + + parent_.ndpInstanceId = ndpInstanceId; + + parent_.notify(); + return Void(); + } + + Return eventDataPathConfirm_1_2( + const ::android::hardware::wifi::V1_2::NanDataPathConfirmInd& event) + override { + parent_.callbackType = EVENT_DATA_PATH_CONFIRM_1_2; + + parent_.nanDataPathConfirmInd_1_2 = event; + + parent_.notify(); + return Void(); + } + + Return eventDataPathScheduleUpdate( + const NanDataPathScheduleUpdateInd& event) override { + parent_.callbackType = EVENT_DATA_PATH_SCHEDULE_UPDATE; + + parent_.nanDataPathScheduleUpdateInd = event; + + parent_.notify(); + return Void(); + } + }; + + private: + // synchronization objects + std::mutex mtx_; + std::condition_variable cv_; + int count_ = 0; + + protected: + android::sp<::android::hardware::wifi::V1_5::IWifiNanIface> iwifiNanIface; + + // Data from IWifiNanIfaceEventCallback callbacks: this is the collection of + // all arguments to all callbacks. They are set by the callback + // (notifications or events) and can be retrieved by tests. + CallbackType callbackType; + uint16_t id; + WifiNanStatus status; + uint8_t sessionId; + uint32_t ndpInstanceId; + NanClusterEventInd nanClusterEventInd; + NanMatchInd nanMatchInd; + uint32_t peerId; + NanFollowupReceivedInd nanFollowupReceivedInd; + NanDataPathRequestInd nanDataPathRequestInd; + ::android::hardware::wifi::V1_0::NanCapabilities capabilities; + ::android::hardware::wifi::V1_5::NanCapabilities capabilities_1_5; + ::android::hardware::wifi::V1_0::NanDataPathConfirmInd + nanDataPathConfirmInd; + ::android::hardware::wifi::V1_2::NanDataPathConfirmInd + nanDataPathConfirmInd_1_2; + NanDataPathScheduleUpdateInd nanDataPathScheduleUpdateInd; + + std::string GetInstanceName() { return GetParam(); } +}; + +/* + * Create: + * Ensures that an instance of the IWifiNanIface proxy object is + * successfully created. + */ +TEST_P(WifiNanIfaceHidlTest, Create) { + // The creation of a proxy object is tested as part of SetUp method. +} + +/* + * enableRequest_1_5InvalidArgs: validate that fails with invalid arguments + */ +TEST_P(WifiNanIfaceHidlTest, enableRequest_1_5InvalidArgs) { + uint16_t inputCmdId = 10; + callbackType = INVALID; + ::android::hardware::wifi::V1_4::NanEnableRequest nanEnableRequest = {}; + ::android::hardware::wifi::V1_5::NanConfigRequestSupplemental + nanConfigRequestSupp = {}; + const auto& halStatus = + HIDL_INVOKE(iwifiNanIface, enableRequest_1_5, inputCmdId, + nanEnableRequest, nanConfigRequestSupp); + if (halStatus.code != WifiStatusCode::ERROR_NOT_SUPPORTED) { + ASSERT_EQ(WifiStatusCode::SUCCESS, halStatus.code); + + // wait for a callback + ASSERT_EQ(std::cv_status::no_timeout, wait(NOTIFY_ENABLE_RESPONSE)); + ASSERT_EQ(NOTIFY_ENABLE_RESPONSE, callbackType); + ASSERT_EQ(id, inputCmdId); + ASSERT_EQ(status.status, NanStatusType::INVALID_ARGS); + } +} + +/* + * enableRequest_1_5ShimInvalidArgs: validate that fails with invalid arguments + * to the shim + */ +TEST_P(WifiNanIfaceHidlTest, enableRequest_1_5ShimInvalidArgs) { + uint16_t inputCmdId = 10; + ::android::hardware::wifi::V1_4::NanEnableRequest nanEnableRequest = {}; + nanEnableRequest.configParams.numberOfPublishServiceIdsInBeacon = + 128; // must be <= 127 + ::android::hardware::wifi::V1_5::NanConfigRequestSupplemental + nanConfigRequestSupp = {}; + const auto& halStatus = + HIDL_INVOKE(iwifiNanIface, enableRequest_1_5, inputCmdId, + nanEnableRequest, nanConfigRequestSupp); + if (halStatus.code != WifiStatusCode::ERROR_NOT_SUPPORTED) { + ASSERT_EQ(WifiStatusCode::ERROR_INVALID_ARGS, halStatus.code); + } +} + +/* + * configRequest_1_5InvalidArgs: validate that fails with invalid arguments + */ +TEST_P(WifiNanIfaceHidlTest, configRequest_1_5InvalidArgs) { + uint16_t inputCmdId = 10; + callbackType = INVALID; + ::android::hardware::wifi::V1_4::NanConfigRequest nanConfigRequest = {}; + ::android::hardware::wifi::V1_5::NanConfigRequestSupplemental + nanConfigRequestSupp = {}; + const auto& halStatus = + HIDL_INVOKE(iwifiNanIface, configRequest_1_5, inputCmdId, + nanConfigRequest, nanConfigRequestSupp); + + if (halStatus.code != WifiStatusCode::ERROR_NOT_SUPPORTED) { + ASSERT_EQ(WifiStatusCode::SUCCESS, halStatus.code); + + // wait for a callback + ASSERT_EQ(std::cv_status::no_timeout, wait(NOTIFY_CONFIG_RESPONSE)); + ASSERT_EQ(NOTIFY_CONFIG_RESPONSE, callbackType); + ASSERT_EQ(id, inputCmdId); + ASSERT_EQ(status.status, NanStatusType::INVALID_ARGS); + } +} + +/* + * configRequest_1_5ShimInvalidArgs: validate that fails with invalid arguments + * to the shim + */ +TEST_P(WifiNanIfaceHidlTest, configRequest_1_5ShimInvalidArgs) { + uint16_t inputCmdId = 10; + ::android::hardware::wifi::V1_4::NanConfigRequest nanConfigRequest = {}; + nanConfigRequest.numberOfPublishServiceIdsInBeacon = 128; // must be <= 127 + ::android::hardware::wifi::V1_5::NanConfigRequestSupplemental + nanConfigRequestSupp = {}; + const auto& halStatus = + HIDL_INVOKE(iwifiNanIface, configRequest_1_5, inputCmdId, + nanConfigRequest, nanConfigRequestSupp); + if (halStatus.code != WifiStatusCode::ERROR_NOT_SUPPORTED) { + ASSERT_EQ(WifiStatusCode::ERROR_INVALID_ARGS, halStatus.code); + } +} + +/* + * getCapabilitiesRequest: validate that returns capabilities. + */ +TEST_P(WifiNanIfaceHidlTest, getCapabilitiesRequest_1_5) { + uint16_t inputCmdId = 10; + callbackType = INVALID; + const auto& halStatus = + HIDL_INVOKE(iwifiNanIface, getCapabilitiesRequest_1_5, inputCmdId).code; + ASSERT_EQ(WifiStatusCode::SUCCESS, halStatus); + // wait for a callback + ASSERT_EQ(std::cv_status::no_timeout, + wait(NOTIFY_CAPABILITIES_RESPONSE_1_5)); + ASSERT_EQ(NOTIFY_CAPABILITIES_RESPONSE_1_5, callbackType); + ASSERT_EQ(id, inputCmdId); + + // check for reasonable capability values + EXPECT_GT(capabilities_1_5.V1_0.maxConcurrentClusters, (unsigned int)0); + EXPECT_GT(capabilities_1_5.V1_0.maxPublishes, (unsigned int)0); + EXPECT_GT(capabilities_1_5.V1_0.maxSubscribes, (unsigned int)0); + EXPECT_EQ(capabilities_1_5.V1_0.maxServiceNameLen, (unsigned int)255); + EXPECT_EQ(capabilities_1_5.V1_0.maxMatchFilterLen, (unsigned int)255); + EXPECT_GT(capabilities_1_5.V1_0.maxTotalMatchFilterLen, (unsigned int)255); + EXPECT_EQ(capabilities_1_5.V1_0.maxServiceSpecificInfoLen, + (unsigned int)255); + EXPECT_GE(capabilities_1_5.V1_0.maxExtendedServiceSpecificInfoLen, + (unsigned int)255); + EXPECT_GT(capabilities_1_5.V1_0.maxNdiInterfaces, (unsigned int)0); + EXPECT_GT(capabilities_1_5.V1_0.maxNdpSessions, (unsigned int)0); + EXPECT_GT(capabilities_1_5.V1_0.maxAppInfoLen, (unsigned int)0); + EXPECT_GT(capabilities_1_5.V1_0.maxQueuedTransmitFollowupMsgs, + (unsigned int)0); + EXPECT_GT(capabilities_1_5.V1_0.maxSubscribeInterfaceAddresses, + (unsigned int)0); + EXPECT_NE(capabilities_1_5.V1_0.supportedCipherSuites, (unsigned int)0); + EXPECT_TRUE(capabilities_1_5.instantCommunicationModeSupportFlag || + !capabilities_1_5.instantCommunicationModeSupportFlag); +} + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiNanIfaceHidlTest); +INSTANTIATE_TEST_SUITE_P( + PerInstance, WifiNanIfaceHidlTest, + testing::ValuesIn(android::hardware::getAllHalInstanceNames( + ::android::hardware::wifi::V1_5::IWifi::descriptor)), + android::hardware::PrintInstanceNameToString); -- GitLab From 2abc352787d494980d3ba0d11877adb8f351f220 Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Fri, 11 Sep 2020 17:46:34 +0800 Subject: [PATCH 214/790] wifi: add 60GHz Wi-Fi P2P support Bug: 14749550 Test: atest VtsHalWifiSupplicantP2pV1_4TargetTest Change-Id: I9ad8afa194999409c55e3606510ef6ed43f4960e --- wifi/supplicant/1.4/Android.bp | 1 + wifi/supplicant/1.4/ISupplicantP2pIface.hal | 52 +++++++++++++ wifi/supplicant/1.4/vts/functional/Android.bp | 31 ++++++++ .../supplicant_hidl_test_utils_1_4.cpp | 7 ++ .../supplicant_hidl_test_utils_1_4.h | 5 ++ .../supplicant_p2p_iface_hidl_test.cpp | 78 +++++++++++++++++++ 6 files changed, 174 insertions(+) create mode 100644 wifi/supplicant/1.4/ISupplicantP2pIface.hal create mode 100644 wifi/supplicant/1.4/vts/functional/supplicant_p2p_iface_hidl_test.cpp diff --git a/wifi/supplicant/1.4/Android.bp b/wifi/supplicant/1.4/Android.bp index df0b23a8a6..6904f15bad 100644 --- a/wifi/supplicant/1.4/Android.bp +++ b/wifi/supplicant/1.4/Android.bp @@ -6,6 +6,7 @@ hidl_interface { srcs: [ "types.hal", "ISupplicant.hal", + "ISupplicantP2pIface.hal", "ISupplicantStaIface.hal", "ISupplicantStaNetwork.hal", ], diff --git a/wifi/supplicant/1.4/ISupplicantP2pIface.hal b/wifi/supplicant/1.4/ISupplicantP2pIface.hal new file mode 100644 index 0000000000..7c41d1c488 --- /dev/null +++ b/wifi/supplicant/1.4/ISupplicantP2pIface.hal @@ -0,0 +1,52 @@ +/* + * 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. + */ + +package android.hardware.wifi.supplicant@1.4; + +import @1.2::ISupplicantP2pIface; +import @1.0::SupplicantStatus; + +/** + * Interface exposed by the supplicant for each P2P mode network + * interface (e.g p2p0) it controls. + * To use 1.4 features you must cast specific interfaces returned from the + * 1.4 HAL. For example V1_4::ISupplicant::addIface() adds V1_4::ISupplicantIface, + * which can be cast to V1_4::ISupplicantP2pIface. + */ +interface ISupplicantP2pIface extends @1.2::ISupplicantP2pIface { + /** + * Set whether to enable EDMG(802.11ay). Only allowed if hw mode is |HOSTAPD_MODE_IEEE80211AD| + * + * @param enable true to set, false otherwise. + * @return status Status of the operation. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_UNKNOWN|, + * |SupplicantStatusCode.FAILURE_NETWORK_INVALID| + */ + setEdmg(bool enable) generates (SupplicantStatus status); + + /** + * Get whether EDMG(802.11ay) is enabled for this network. + * + * @return status Status of the operation. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_NETWORK_INVALID| + * @return enabled true if set, false otherwise. + */ + getEdmg() generates (SupplicantStatus status, bool enabled); +}; diff --git a/wifi/supplicant/1.4/vts/functional/Android.bp b/wifi/supplicant/1.4/vts/functional/Android.bp index 7f2ba70125..d959285e8b 100644 --- a/wifi/supplicant/1.4/vts/functional/Android.bp +++ b/wifi/supplicant/1.4/vts/functional/Android.bp @@ -69,3 +69,34 @@ cc_test { ], disable_framework: true, } + +cc_test { + name: "VtsHalWifiSupplicantP2pV1_4TargetTest", + defaults: ["VtsHalTargetTestDefaults"], + srcs: [ + "supplicant_p2p_iface_hidl_test.cpp", + ], + static_libs: [ + "VtsHalWifiV1_0TargetTestUtil", + "VtsHalWifiSupplicantV1_0TargetTestUtil", + "VtsHalWifiSupplicantV1_1TargetTestUtil", + "VtsHalWifiSupplicantV1_2TargetTestUtil", + "VtsHalWifiSupplicantV1_3TargetTestUtil", + "VtsHalWifiSupplicantV1_4TargetTestUtil", + "android.hardware.wifi.supplicant@1.0", + "android.hardware.wifi.supplicant@1.1", + "android.hardware.wifi.supplicant@1.2", + "android.hardware.wifi.supplicant@1.3", + "android.hardware.wifi.supplicant@1.4", + "android.hardware.wifi@1.0", + "android.hardware.wifi@1.1", + "libgmock", + "libwifi-system", + "libwifi-system-iface", + ], + test_suites: [ + "general-tests", + "vts", + ], + disable_framework: true, +} diff --git a/wifi/supplicant/1.4/vts/functional/supplicant_hidl_test_utils_1_4.cpp b/wifi/supplicant/1.4/vts/functional/supplicant_hidl_test_utils_1_4.cpp index 3a59bd6297..7e7a465e3f 100644 --- a/wifi/supplicant/1.4/vts/functional/supplicant_hidl_test_utils_1_4.cpp +++ b/wifi/supplicant/1.4/vts/functional/supplicant_hidl_test_utils_1_4.cpp @@ -21,6 +21,7 @@ using ::android::sp; using ::android::hardware::wifi::supplicant::V1_4::ISupplicant; +using ::android::hardware::wifi::supplicant::V1_4::ISupplicantP2pIface; using ::android::hardware::wifi::supplicant::V1_4::ISupplicantStaIface; sp getSupplicantStaIface_1_4( @@ -29,6 +30,12 @@ sp getSupplicantStaIface_1_4( return ISupplicantStaIface::castFrom(getSupplicantStaIface(supplicant)); } +sp getSupplicantP2pIface_1_4( + const android::sp& + supplicant) { + return ISupplicantP2pIface::castFrom(getSupplicantP2pIface(supplicant)); +} + sp getSupplicant_1_4(const std::string& supplicant_instance_name, bool isP2pOn) { return ISupplicant::castFrom( diff --git a/wifi/supplicant/1.4/vts/functional/supplicant_hidl_test_utils_1_4.h b/wifi/supplicant/1.4/vts/functional/supplicant_hidl_test_utils_1_4.h index 60fe1dca65..b3b699033b 100644 --- a/wifi/supplicant/1.4/vts/functional/supplicant_hidl_test_utils_1_4.h +++ b/wifi/supplicant/1.4/vts/functional/supplicant_hidl_test_utils_1_4.h @@ -18,12 +18,17 @@ #define SUPPLICANT_HIDL_TEST_UTILS_1_4_H #include +#include #include android::sp getSupplicantStaIface_1_4( const android::sp& supplicant); +android::sp +getSupplicantP2pIface_1_4( + const android::sp& + supplicant); android::sp getSupplicant_1_4(const std::string& supplicant_instance_name, bool isP2pOn); diff --git a/wifi/supplicant/1.4/vts/functional/supplicant_p2p_iface_hidl_test.cpp b/wifi/supplicant/1.4/vts/functional/supplicant_p2p_iface_hidl_test.cpp new file mode 100644 index 0000000000..17e1b9f94d --- /dev/null +++ b/wifi/supplicant/1.4/vts/functional/supplicant_p2p_iface_hidl_test.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "supplicant_hidl_test_utils.h" +#include "supplicant_hidl_test_utils_1_4.h" + +using ::android::sp; +using ::android::hardware::Void; +using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatus; +using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatusCode; +using ::android::hardware::wifi::supplicant::V1_4::ISupplicantP2pIface; + +class SupplicantP2pIfaceHidlTest : public SupplicantHidlTestBaseV1_4 { + public: + virtual void SetUp() override { + SupplicantHidlTestBaseV1_4::SetUp(); + p2p_iface_ = getSupplicantP2pIface_1_4(supplicant_); + ASSERT_NE(p2p_iface_.get(), nullptr); + } + + protected: + // ISupplicantP2pIface object used for all tests in this fixture. + sp p2p_iface_; +}; + +/* + * SetGetEdmg + */ +TEST_P(SupplicantP2pIfaceHidlTest, SetGetEdmg) { + p2p_iface_->setEdmg(true, [&](const SupplicantStatus& status) { + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + }); + p2p_iface_->getEdmg([&](const SupplicantStatus& status, bool enable) { + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + EXPECT_EQ(true, enable); + }); + p2p_iface_->setEdmg(false, [&](const SupplicantStatus& status) { + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + }); + p2p_iface_->getEdmg([&](const SupplicantStatus& status, bool enable) { + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + EXPECT_EQ(false, enable); + }); +} + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantP2pIfaceHidlTest); +INSTANTIATE_TEST_CASE_P( + PerInstance, SupplicantP2pIfaceHidlTest, + testing::Combine( + testing::ValuesIn(android::hardware::getAllHalInstanceNames( + android::hardware::wifi::V1_0::IWifi::descriptor)), + testing::ValuesIn(android::hardware::getAllHalInstanceNames( + android::hardware::wifi::supplicant::V1_4::ISupplicant:: + descriptor))), + android::hardware::PrintInstanceTupleNameToString<>); -- GitLab From e503481f8772d46a1124c75f0b0c514c9dff9577 Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Thu, 15 Oct 2020 21:45:56 -0700 Subject: [PATCH 215/790] Remove sensorId and userId from all Session methods Bug: 168730443 Test: m android.hardware.biometrics.face-update-api Test: atest VtsHalBiometricsFaceTargetTest Change-Id: Icc4545f46e5de625127553373128663b9b5c9dbe --- .../android/hardware/biometrics/face/ISession.aidl | 4 ++-- .../aidl/android/hardware/biometrics/face/ISession.aidl | 8 ++------ biometrics/face/aidl/default/Session.cpp | 6 ++---- biometrics/face/aidl/default/Session.h | 6 ++---- 4 files changed, 8 insertions(+), 16 deletions(-) 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 c9b443d67c..5d9a430779 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 @@ -18,8 +18,8 @@ package android.hardware.biometrics.face; @VintfStability interface ISession { - void generateChallenge(in int cookie, in int sensorId, in int userId, in int timeoutSec); - void revokeChallenge(in int cookie, in int sensorId, in int userId, in long challenge); + void generateChallenge(in int cookie, in int timeoutSec); + void revokeChallenge(in int cookie, in long challenge); android.hardware.biometrics.common.ICancellationSignal enroll(in int cookie, in android.hardware.keymaster.HardwareAuthToken hat, in android.hardware.common.NativeHandle previewSurface); android.hardware.biometrics.common.ICancellationSignal authenticate(in int cookie, in long operationId); android.hardware.biometrics.common.ICancellationSignal detectInteraction(in int cookie); diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl index 5145b1e94d..c7beae03ed 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl @@ -68,11 +68,9 @@ interface ISession { * ---------------------------------------------- * * @param cookie A unique number identifying this operation - * @param sensorId Sensor to associate the challenge with - * @param userId User to associate the challenge with * @param timeoutSec Duration for which the challenge is valid for */ - void generateChallenge(in int cookie, in int sensorId, in int userId, in int timeoutSec); + void generateChallenge(in int cookie, in int timeoutSec); /** * revokeChallenge: @@ -82,11 +80,9 @@ interface ISession { * provided callback. * * @param cookie A unique number identifying this operation - * @param sensorId Sensor that the revocation should apply to. - * @param userId User that the revocation should apply to. * @param challenge Challenge that should be revoked. */ - void revokeChallenge(in int cookie, in int sensorId, in int userId, in long challenge); + void revokeChallenge(in int cookie, in long challenge); /** * enroll: diff --git a/biometrics/face/aidl/default/Session.cpp b/biometrics/face/aidl/default/Session.cpp index bb895b76ba..2b1d4a7637 100644 --- a/biometrics/face/aidl/default/Session.cpp +++ b/biometrics/face/aidl/default/Session.cpp @@ -27,13 +27,11 @@ class CancellationSignal : public common::BnCancellationSignal { Session::Session(std::shared_ptr cb) : cb_(std::move(cb)) {} -ndk::ScopedAStatus Session::generateChallenge(int32_t /*cookie*/, int32_t /*sensorId*/, - int32_t /*userId*/, int32_t /*timeoutSec*/) { +ndk::ScopedAStatus Session::generateChallenge(int32_t /*cookie*/, int32_t /*timeoutSec*/) { return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::revokeChallenge(int32_t /*cookie*/, int32_t /*sensorId*/, - int32_t /*userId*/, int64_t /*challenge*/) { +ndk::ScopedAStatus Session::revokeChallenge(int32_t /*cookie*/, int64_t /*challenge*/) { return ndk::ScopedAStatus::ok(); } diff --git a/biometrics/face/aidl/default/Session.h b/biometrics/face/aidl/default/Session.h index a91ad8151b..2bb5c42a99 100644 --- a/biometrics/face/aidl/default/Session.h +++ b/biometrics/face/aidl/default/Session.h @@ -30,11 +30,9 @@ class Session : public BnSession { public: explicit Session(std::shared_ptr cb); - ndk::ScopedAStatus generateChallenge(int32_t cookie, int32_t sensorId, int32_t userId, - int32_t timeoutSec) override; + ndk::ScopedAStatus generateChallenge(int32_t cookie, int32_t timeoutSec) override; - ndk::ScopedAStatus revokeChallenge(int32_t cookie, int32_t sensorId, int32_t userId, - int64_t challenge) override; + ndk::ScopedAStatus revokeChallenge(int32_t cookie, int64_t challenge) override; ndk::ScopedAStatus enroll( int32_t cookie, const keymaster::HardwareAuthToken& hat, -- GitLab From 3d54f4576c2f5bf6b332d7c7137c6802e67767e1 Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Thu, 15 Oct 2020 17:32:09 -0700 Subject: [PATCH 216/790] Move [generate|revoke]Challenge under ISession.aidl Bug: 171002801 Test: m android.hardware.biometrics.fingerprint-update-api Test: atest VtsHalBiometricsFingerprintTargetTest Change-Id: I2aa266b7b81003b7fd0ab0328833e5500de99908 --- .../biometrics/fingerprint/IFingerprint.aidl | 2 - .../IGenerateChallengeCallback.aidl | 22 ------- .../fingerprint/IRevokeChallengeCallback.aidl | 22 ------- .../biometrics/fingerprint/ISession.aidl | 2 + .../fingerprint/ISessionCallback.aidl | 2 + .../biometrics/fingerprint/SessionState.aidl | 18 +++--- .../biometrics/fingerprint/IFingerprint.aidl | 62 ------------------- .../IGenerateChallengeCallback.aidl | 26 -------- .../fingerprint/IRevokeChallengeCallback.aidl | 26 -------- .../biometrics/fingerprint/ISession.aidl | 56 +++++++++++++++++ .../fingerprint/ISessionCallback.aidl | 10 +++ .../biometrics/fingerprint/SessionState.aidl | 10 +++ .../fingerprint/aidl/default/Fingerprint.cpp | 13 ---- .../fingerprint/aidl/default/Fingerprint.h | 8 --- .../fingerprint/aidl/default/Session.cpp | 11 +++- biometrics/fingerprint/aidl/default/Session.h | 15 +++-- .../VtsHalBiometricsFingerprintTargetTest.cpp | 8 +++ 17 files changed, 117 insertions(+), 196 deletions(-) delete mode 100644 biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IGenerateChallengeCallback.aidl delete mode 100644 biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IRevokeChallengeCallback.aidl delete mode 100644 biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IGenerateChallengeCallback.aidl delete mode 100644 biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IRevokeChallengeCallback.aidl diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl index 6ca6d16eb3..c5c6786542 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl @@ -20,6 +20,4 @@ package android.hardware.biometrics.fingerprint; 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); - void generateChallenge(in int sensorId, in int userId, in int timeoutSec, in android.hardware.biometrics.fingerprint.IGenerateChallengeCallback cb); - void revokeChallenge(in int sensorId, in int userId, in long challenge, in android.hardware.biometrics.fingerprint.IRevokeChallengeCallback cb); } diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IGenerateChallengeCallback.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IGenerateChallengeCallback.aidl deleted file mode 100644 index 063be60a0f..0000000000 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IGenerateChallengeCallback.aidl +++ /dev/null @@ -1,22 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // -/////////////////////////////////////////////////////////////////////////////// - -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. -// -// You must not make a backward incompatible changes to the AIDL files 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.fingerprint; -@VintfStability -interface IGenerateChallengeCallback { - oneway void onChallengeGenerated(in int sensorId, in int userId, in long challenge); -} diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IRevokeChallengeCallback.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IRevokeChallengeCallback.aidl deleted file mode 100644 index 23fc10f9ae..0000000000 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IRevokeChallengeCallback.aidl +++ /dev/null @@ -1,22 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // -/////////////////////////////////////////////////////////////////////////////// - -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. -// -// You must not make a backward incompatible changes to the AIDL files 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.fingerprint; -@VintfStability -interface IRevokeChallengeCallback { - oneway void onChallengeRevoked(in int sensorId, in int userId, in long challenge); -} 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 c1f66e3b1f..00a08ba886 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 @@ -18,6 +18,8 @@ package android.hardware.biometrics.fingerprint; @VintfStability interface ISession { + void generateChallenge(in int cookie, in int timeoutSec); + void revokeChallenge(in int cookie, in long challenge); android.hardware.biometrics.common.ICancellationSignal enroll(in int cookie, in android.hardware.keymaster.HardwareAuthToken hat); android.hardware.biometrics.common.ICancellationSignal authenticate(in int cookie, in long operationId); android.hardware.biometrics.common.ICancellationSignal detectInteraction(in int cookie); diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl index 74ec07774c..b7a48a5186 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl @@ -19,6 +19,8 @@ package android.hardware.biometrics.fingerprint; @VintfStability interface ISessionCallback { void onStateChanged(in int cookie, in android.hardware.biometrics.fingerprint.SessionState state); + 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); diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.aidl index 97f1a1e987..e9daef1740 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.aidl @@ -19,12 +19,14 @@ package android.hardware.biometrics.fingerprint; @Backing(type="byte") @VintfStability enum SessionState { IDLING = 0, - ENROLLING = 1, - AUTHENTICATING = 2, - DETECTING_INTERACTION = 3, - ENUMERATING_ENROLLMENTS = 4, - REMOVING_ENROLLMENTS = 5, - GETTING_AUTHENTICATOR_ID = 6, - INVALIDATING_AUTHENTICATOR_ID = 7, - RESETTING_LOCKOUT = 8, + GENERATING_CHALLENGE = 1, + REVOKING_CHALLENGE = 2, + ENROLLING = 3, + AUTHENTICATING = 4, + DETECTING_INTERACTION = 5, + ENUMERATING_ENROLLMENTS = 6, + REMOVING_ENROLLMENTS = 7, + GETTING_AUTHENTICATOR_ID = 8, + INVALIDATING_AUTHENTICATOR_ID = 9, + RESETTING_LOCKOUT = 10, } diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl index 4b907b46b5..3675aa4019 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl @@ -16,8 +16,6 @@ package android.hardware.biometrics.fingerprint; -import android.hardware.biometrics.fingerprint.IGenerateChallengeCallback; -import android.hardware.biometrics.fingerprint.IRevokeChallengeCallback; import android.hardware.biometrics.fingerprint.ISession; import android.hardware.biometrics.fingerprint.ISessionCallback; import android.hardware.biometrics.fingerprint.SensorProps; @@ -63,64 +61,4 @@ interface IFingerprint { * @return A new session */ ISession createSession(in int sensorId, in int userId, in ISessionCallback cb); - - /** - * generateChallenge: - * - * Begins a secure transaction request. Note that the challenge by itself is not useful. It only - * becomes useful when wrapped in a verifiable message such as a HardwareAuthToken. - * - * Canonical example: - * 1) User requests an operation, such as fingerprint enrollment. - * 2) Fingerprint enrollment cannot happen until the user confirms their lockscreen credential - * (PIN/Pattern/Password). - * 3) However, the biometric subsystem does not want just "any" proof of credential - * confirmation. It needs proof that the user explicitly authenticated credential in order - * to allow addition of biometric enrollments. - * To secure this path, the following path is taken: - * 1) Upon user requesting fingerprint enroll, the framework requests - * IFingerprint#generateChallenge - * 2) Framework sends the challenge to the credential subsystem, and upon credential - * confirmation, a HAT is created, containing the challenge in the "challenge" field. - * 3) Framework sends the HAT to the HAL, e.g. ISession#enroll. - * 4) Implementation verifies the authenticity and integrity of the HAT. - * 5) Implementation now has confidence that the user entered their credential to allow - * biometric enrollment. - * - * Note that the interface allows multiple in-flight challenges. For example, invoking - * generateChallenge(0, 0, timeoutSec, cb) twice does not invalidate the first challenge. The - * challenge is invalidated only when: - * 1) The provided timeout expires, or - * 2) IFingerprint#revokeChallenge is invoked - * - * For example, the following is a possible table of valid challenges: - * ---------------------------------------------- - * | SensorId | UserId | ValidUntil | Challenge | - * |----------|--------|------------|-----------| - * | 0 | 0 | | | - * | 0 | 0 | | | - * | 1 | 0 | | | - * | 0 | 10 | | | - * ---------------------------------------------- - * - * @param sensorId Sensor to associate the challenge with - * @param userId User to associate the challenge with - * @param timeoutSec Duration for which the challenge is valid for - * @param cb Callback to notify the framework - */ - void generateChallenge(in int sensorId, in int userId, in int timeoutSec, in IGenerateChallengeCallback cb); - - /** - * revokeChallenge: - * - * Revokes a challenge that was previously generated. Note that if an invalid combination of - * parameters is requested, the implementation must still notify the framework using the - * provided callback. - * - * @param sensorId Sensor that the revocation should apply to. - * @param userId User that the revocation should apply to. - * @param challenge Challenge that should be revoked. - * @param cb Used to notify the framework. - */ - void revokeChallenge(in int sensorId, in int userId, in long challenge, in IRevokeChallengeCallback cb); } diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IGenerateChallengeCallback.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IGenerateChallengeCallback.aidl deleted file mode 100644 index a51b188fcf..0000000000 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IGenerateChallengeCallback.aidl +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.hardware.biometrics.fingerprint; - -@VintfStability -oneway interface IGenerateChallengeCallback { - /** - * Notifies the framework when a challenge is successfully generated. - */ - void onChallengeGenerated(in int sensorId, in int userId, in long challenge); -} - diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IRevokeChallengeCallback.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IRevokeChallengeCallback.aidl deleted file mode 100644 index eadba526b3..0000000000 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IRevokeChallengeCallback.aidl +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.hardware.biometrics.fingerprint; - -@VintfStability -oneway interface IRevokeChallengeCallback { - /** - * Notifies the framework when a challenge has been revoked. - */ - void onChallengeRevoked(in int sensorId, in int userId, in long challenge); -} - diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl index 644e214c42..da767bec48 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl @@ -46,6 +46,62 @@ interface ISession { * Methods applicable to any fingerprint type. */ + /** + * generateChallenge: + * + * Begins a secure transaction request. Note that the challenge by itself is not useful. It only + * becomes useful when wrapped in a verifiable message such as a HardwareAuthToken. + * + * Canonical example: + * 1) User requests an operation, such as fingerprint enrollment. + * 2) Fingerprint enrollment cannot happen until the user confirms their lockscreen credential + * (PIN/Pattern/Password). + * 3) However, the biometric subsystem does not want just "any" proof of credential + * confirmation. It needs proof that the user explicitly authenticated credential in order + * to allow addition of biometric enrollments. + * To secure this path, the following path is taken: + * 1) Upon user requesting fingerprint enroll, the framework requests + * IFingerprint#generateChallenge + * 2) Framework sends the challenge to the credential subsystem, and upon credential + * confirmation, a HAT is created, containing the challenge in the "challenge" field. + * 3) Framework sends the HAT to the HAL, e.g. ISession#enroll. + * 4) Implementation verifies the authenticity and integrity of the HAT. + * 5) Implementation now has confidence that the user entered their credential to allow + * biometric enrollment. + * + * Note that the interface allows multiple in-flight challenges. For example, invoking + * generateChallenge(0, 0, timeoutSec, cb) twice does not invalidate the first challenge. The + * challenge is invalidated only when: + * 1) The provided timeout expires, or + * 2) IFingerprint#revokeChallenge is invoked + * + * For example, the following is a possible table of valid challenges: + * ---------------------------------------------- + * | SensorId | UserId | ValidUntil | Challenge | + * |----------|--------|------------|-----------| + * | 0 | 0 | | | + * | 0 | 0 | | | + * | 1 | 0 | | | + * | 0 | 10 | | | + * ---------------------------------------------- + * + * @param cookie A unique number identifying this operation + * @param timeoutSec Duration for which the challenge is valid for + */ + void generateChallenge(in int cookie, in int timeoutSec); + + /** + * revokeChallenge: + * + * Revokes a challenge that was previously generated. Note that if an invalid combination of + * parameters is requested, the implementation must still notify the framework using the + * provided callback. + * + * @param cookie A unique number identifying this operation + * @param challenge Challenge that should be revoked. + */ + void revokeChallenge(in int cookie, in long challenge); + /** * enroll: * diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl index 74792d8d4e..4387f988d0 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl @@ -28,6 +28,16 @@ interface ISessionCallback { */ void onStateChanged(in int cookie, in SessionState state); + /** + * Notifies the framework when a challenge is successfully generated. + */ + void onChallengeGenerated(in long challenge); + + /** + * Notifies the framework when a challenge has been revoked. + */ + void onChallengeRevoked(in long challenge); + /** * This method must only be used to notify the framework during the following states: * 1) SessionState::ENROLLING diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SessionState.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SessionState.aidl index 405b011b31..1de01ad73c 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SessionState.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SessionState.aidl @@ -24,6 +24,16 @@ enum SessionState { */ IDLING, + /** + * The HAL is processing the ISession#generateChallenge request. + */ + GENERATING_CHALLENGE, + + /** + * The HAL is processing the ISession#revokeChallenge request. + */ + REVOKING_CHALLENGE, + /** * The HAL is processing the ISession#enroll request. */ diff --git a/biometrics/fingerprint/aidl/default/Fingerprint.cpp b/biometrics/fingerprint/aidl/default/Fingerprint.cpp index b907bf1d31..18ce0c850e 100644 --- a/biometrics/fingerprint/aidl/default/Fingerprint.cpp +++ b/biometrics/fingerprint/aidl/default/Fingerprint.cpp @@ -60,17 +60,4 @@ ndk::ScopedAStatus Fingerprint::createSession(int32_t /*sensorId*/, int32_t /*us *return_val = SharedRefBase::make(cb); return ndk::ScopedAStatus::ok(); } - -ndk::ScopedAStatus Fingerprint::generateChallenge( - int32_t /*sensorId*/, int32_t /*userId*/, int32_t /*timeoutSec*/, - const std::shared_ptr& /*cb*/) { - return ndk::ScopedAStatus::ok(); -} - -ndk::ScopedAStatus Fingerprint::revokeChallenge( - int32_t /*sensorId*/, int32_t /*userId*/, int64_t /*challenge*/, - const std::shared_ptr& /*cb*/) { - return ndk::ScopedAStatus::ok(); -} - } // namespace aidl::android::hardware::biometrics::fingerprint diff --git a/biometrics/fingerprint/aidl/default/Fingerprint.h b/biometrics/fingerprint/aidl/default/Fingerprint.h index 59cdd441fc..4e952ba74e 100644 --- a/biometrics/fingerprint/aidl/default/Fingerprint.h +++ b/biometrics/fingerprint/aidl/default/Fingerprint.h @@ -27,14 +27,6 @@ class Fingerprint : public BnFingerprint { ndk::ScopedAStatus createSession(int32_t sensorId, int32_t userId, const std::shared_ptr& cb, std::shared_ptr* _aidl_return) override; - - ndk::ScopedAStatus generateChallenge( - int32_t sensorId, int32_t userId, int32_t timeoutSec, - const std::shared_ptr& cb) override; - - ndk::ScopedAStatus revokeChallenge( - int32_t sensorId, int32_t userId, int64_t challenge, - const std::shared_ptr& cb) override; }; } // namespace aidl::android::hardware::biometrics::fingerprint diff --git a/biometrics/fingerprint/aidl/default/Session.cpp b/biometrics/fingerprint/aidl/default/Session.cpp index c2934a8bd7..372066d2d7 100644 --- a/biometrics/fingerprint/aidl/default/Session.cpp +++ b/biometrics/fingerprint/aidl/default/Session.cpp @@ -27,6 +27,14 @@ class CancellationSignal : public common::BnCancellationSignal { Session::Session(std::shared_ptr cb) : cb_(std::move(cb)) {} +ndk::ScopedAStatus Session::generateChallenge(int32_t /*cookie*/, int32_t /*timeoutSec*/) { + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Session::revokeChallenge(int32_t /*cookie*/, int64_t /*challenge*/) { + return ndk::ScopedAStatus::ok(); +} + ndk::ScopedAStatus Session::enroll(int32_t /*cookie*/, const keymaster::HardwareAuthToken& /*hat*/, std::shared_ptr* /*return_val*/) { return ndk::ScopedAStatus::ok(); @@ -60,7 +68,7 @@ ndk::ScopedAStatus Session::getAuthenticatorId(int32_t /*cookie*/) { } ndk::ScopedAStatus Session::invalidateAuthenticatorId(int32_t /*cookie*/, - const keymaster::HardwareAuthToken& /*hat*/) { + const keymaster::HardwareAuthToken& /*hat*/) { return ndk::ScopedAStatus::ok(); } @@ -81,5 +89,4 @@ ndk::ScopedAStatus Session::onPointerUp(int32_t /*pointerId*/) { ndk::ScopedAStatus Session::onUiReady() { return ndk::ScopedAStatus::ok(); } - } // namespace aidl::android::hardware::biometrics::fingerprint diff --git a/biometrics/fingerprint/aidl/default/Session.h b/biometrics/fingerprint/aidl/default/Session.h index f7cba1b801..05c570c8dc 100644 --- a/biometrics/fingerprint/aidl/default/Session.h +++ b/biometrics/fingerprint/aidl/default/Session.h @@ -28,14 +28,19 @@ class Session : public BnSession { public: explicit Session(std::shared_ptr cb); + ndk::ScopedAStatus generateChallenge(int32_t cookie, int32_t timeoutSec) override; + + ndk::ScopedAStatus revokeChallenge(int32_t cookie, int64_t challenge) override; + ndk::ScopedAStatus enroll(int32_t cookie, const keymaster::HardwareAuthToken& hat, std::shared_ptr* return_val) override; - ndk::ScopedAStatus authenticate(int32_t cookie, int64_t keystoreOperationId, - std::shared_ptr* return_val) override; + ndk::ScopedAStatus authenticate( + int32_t cookie, int64_t keystoreOperationId, + std::shared_ptr* return_val) override; - ndk::ScopedAStatus detectInteraction(int32_t cookie, - std::shared_ptr* return_val) override; + ndk::ScopedAStatus detectInteraction( + int32_t cookie, std::shared_ptr* return_val) override; ndk::ScopedAStatus enumerateEnrollments(int32_t cookie) override; @@ -45,7 +50,7 @@ class Session : public BnSession { ndk::ScopedAStatus getAuthenticatorId(int32_t cookie) override; ndk::ScopedAStatus invalidateAuthenticatorId(int32_t cookie, - const keymaster::HardwareAuthToken& hat) override; + const keymaster::HardwareAuthToken& hat) override; ndk::ScopedAStatus resetLockout(int32_t cookie, const keymaster::HardwareAuthToken& hat) override; diff --git a/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp b/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp index 496badc741..adb98ac46f 100644 --- a/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp +++ b/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp @@ -52,6 +52,14 @@ class SessionCallback : public BnSessionCallback { return ndk::ScopedAStatus::ok(); } + ndk::ScopedAStatus onChallengeGenerated(int64_t /*challenge*/) override { + return ndk::ScopedAStatus::ok(); + } + + ndk::ScopedAStatus onChallengeRevoked(int64_t /*challenge*/) override { + return ndk::ScopedAStatus::ok(); + } + ndk::ScopedAStatus onAcquired(AcquiredInfo /*info*/, int32_t /*vendorCode*/) override { return ndk::ScopedAStatus::ok(); } -- GitLab From 1e1a67651d7cb658dc3830cc7351d6e50de7cf1c Mon Sep 17 00:00:00 2001 From: Yu-Han Yang Date: Wed, 30 Sep 2020 17:01:53 -0700 Subject: [PATCH 217/790] Add IGnssConfiguration AIDL HAL (hardware/interfaces) In default implementation, both AIDL HAL and the v2.1 HIDL HAL services are running in the same process. The HIDL HAL implementation is able to interact with the AIDL HAL implementation. Bug: 168111993 Bug: 150192654 Test: on cuttlefish Change-Id: Ib2770780b62a939f6ca447dfb6a6ab888c526fec --- .../hardware/gnss/BlocklistedSource.aidl | 23 + .../hardware/gnss/GnssConstellationType.aidl | 29 ++ .../current/android/hardware/gnss/IGnss.aidl | 4 + .../android/hardware/gnss/IGnssCallback.aidl | 23 + .../hardware/gnss/IGnssConfiguration.aidl | 35 ++ .../android/hardware/gnss/IGnssPsds.aidl | 4 +- .../hardware/gnss/BlocklistedSource.aidl | 36 ++ .../hardware/gnss/GnssConstellationType.aidl | 43 ++ gnss/aidl/android/hardware/gnss/IGnss.aidl | 45 ++ .../android/hardware/gnss/IGnssCallback.aidl | 39 ++ .../hardware/gnss/IGnssConfiguration.aidl | 122 +++++ .../aidl/android/hardware/gnss/IGnssPsds.aidl | 8 +- gnss/aidl/default/Android.bp | 23 +- gnss/aidl/default/Gnss.cpp | 37 ++ gnss/aidl/default/Gnss.h | 12 + gnss/aidl/default/GnssConfiguration.cpp | 52 ++ gnss/aidl/default/GnssConfiguration.h | 73 +++ gnss/aidl/default/GnssHidlHal.cpp | 55 +++ gnss/aidl/default/GnssHidlHal.h | 40 ++ gnss/aidl/default/GnssPsds.cpp | 17 +- gnss/aidl/default/GnssPsds.h | 7 +- gnss/aidl/default/gnss@2.1-service.xml | 12 + gnss/aidl/default/service.cpp | 31 +- gnss/aidl/vts/Android.bp | 10 +- gnss/aidl/vts/GnssCallbackAidl.cpp | 24 + gnss/aidl/vts/GnssCallbackAidl.h | 32 ++ gnss/aidl/vts/VtsHalGnssTargetTest.cpp | 52 +- gnss/aidl/vts/gnss_hal_test.cpp | 56 +++ gnss/aidl/vts/gnss_hal_test.h | 48 ++ gnss/aidl/vts/gnss_hal_test_cases.cpp | 450 ++++++++++++++++++ .../utils/default/include/v2_1/GnssTemplate.h | 30 +- .../vts/include/v2_1/gnss_hal_test_template.h | 2 +- 32 files changed, 1385 insertions(+), 89 deletions(-) create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/BlocklistedSource.aidl create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssConstellationType.aidl create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssConfiguration.aidl create mode 100644 gnss/aidl/android/hardware/gnss/BlocklistedSource.aidl create mode 100644 gnss/aidl/android/hardware/gnss/GnssConstellationType.aidl create mode 100644 gnss/aidl/android/hardware/gnss/IGnssCallback.aidl create mode 100644 gnss/aidl/android/hardware/gnss/IGnssConfiguration.aidl create mode 100644 gnss/aidl/default/GnssConfiguration.cpp create mode 100644 gnss/aidl/default/GnssConfiguration.h create mode 100644 gnss/aidl/default/GnssHidlHal.cpp create mode 100644 gnss/aidl/default/GnssHidlHal.h create mode 100644 gnss/aidl/default/gnss@2.1-service.xml create mode 100644 gnss/aidl/vts/GnssCallbackAidl.cpp create mode 100644 gnss/aidl/vts/GnssCallbackAidl.h create mode 100644 gnss/aidl/vts/gnss_hal_test.cpp create mode 100644 gnss/aidl/vts/gnss_hal_test.h create mode 100644 gnss/aidl/vts/gnss_hal_test_cases.cpp diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/BlocklistedSource.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/BlocklistedSource.aidl new file mode 100644 index 0000000000..89f5d53106 --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/BlocklistedSource.aidl @@ -0,0 +1,23 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.gnss; +@VintfStability +parcelable BlocklistedSource { + android.hardware.gnss.GnssConstellationType constellation; + int svid; +} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssConstellationType.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssConstellationType.aidl new file mode 100644 index 0000000000..30d0227577 --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssConstellationType.aidl @@ -0,0 +1,29 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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; +@Backing(type="int") @VintfStability +enum GnssConstellationType { + UNKNOWN = 0, + GPS = 1, + SBAS = 2, + GLONASS = 3, + QZSS = 4, + BEIDOU = 5, + GALILEO = 6, + IRNSS = 7, +} 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 33377ca906..146577ef90 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 @@ -18,5 +18,9 @@ package android.hardware.gnss; @VintfStability interface IGnss { + void setCallback(in android.hardware.gnss.IGnssCallback callback); + void close(); android.hardware.gnss.IGnssPsds getExtensionPsds(); + android.hardware.gnss.IGnssConfiguration getExtensionGnssConfiguration(); + const int ERROR_INVALID_ARGUMENT = 1; } diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl new file mode 100644 index 0000000000..62870d6871 --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl @@ -0,0 +1,23 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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 IGnssCallback { + void gnssSetCapabilitiesCb(in int capabilities); + const int CAPABILITY_SATELLITE_BLOCKLIST = 1; +} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssConfiguration.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssConfiguration.aidl new file mode 100644 index 0000000000..5af30cf237 --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssConfiguration.aidl @@ -0,0 +1,35 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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 IGnssConfiguration { + void setSuplVersion(in int version); + void setSuplMode(in int mode); + void setLppProfile(in int lppProfile); + void setGlonassPositioningProtocol(in int protocol); + void setEmergencySuplPdn(in boolean enable); + void setEsExtensionSec(in int emergencyExtensionSeconds); + void setBlocklist(in android.hardware.gnss.BlocklistedSource[] blocklist); + const int SUPL_MODE_MSB = 1; + const int SUPL_MODE_MSA = 2; + const int LPP_PROFILE_USER_PLANE = 1; + const int LPP_PROFILE_CONTROL_PLANE = 2; + const int GLONASS_POS_PROTOCOL_RRC_CPLANE = 1; + const int GLONASS_POS_PROTOCOL_RRLP_UPLANE = 2; + const int GLONASS_POS_PROTOCOL_LPP_UPLANE = 4; +} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsds.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsds.aidl index 352a694f0b..ddef9280ed 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsds.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsds.aidl @@ -18,6 +18,6 @@ package android.hardware.gnss; @VintfStability interface IGnssPsds { - boolean injectPsdsData(in android.hardware.gnss.PsdsType psdsType, in byte[] psdsData); - boolean setCallback(in android.hardware.gnss.IGnssPsdsCallback callback); + void injectPsdsData(in android.hardware.gnss.PsdsType psdsType, in byte[] psdsData); + void setCallback(in android.hardware.gnss.IGnssPsdsCallback callback); } diff --git a/gnss/aidl/android/hardware/gnss/BlocklistedSource.aidl b/gnss/aidl/android/hardware/gnss/BlocklistedSource.aidl new file mode 100644 index 0000000000..2fde5b20fd --- /dev/null +++ b/gnss/aidl/android/hardware/gnss/BlocklistedSource.aidl @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.gnss; + +import android.hardware.gnss.GnssConstellationType; + +/** + * Represents a blocklisted source. + */ +@VintfStability +parcelable BlocklistedSource { + /** + * Defines the constellation of the given satellite(s). + */ + GnssConstellationType constellation; + + /** + * Satellite (space vehicle) ID number, as defined in GnssSvInfo::svid, or 0 to blocklist all + * svid's for the specified constellation. + */ + int svid; +} \ No newline at end of file diff --git a/gnss/aidl/android/hardware/gnss/GnssConstellationType.aidl b/gnss/aidl/android/hardware/gnss/GnssConstellationType.aidl new file mode 100644 index 0000000000..af3e089c5e --- /dev/null +++ b/gnss/aidl/android/hardware/gnss/GnssConstellationType.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. + */ + +package android.hardware.gnss; + +/** + * GNSS constellation type + * + * This is to specify the navigation satellite system, for example, as listed in Section 3.5 in + * RINEX Version 3.04. + */ +@VintfStability +@Backing(type="int") +enum GnssConstellationType { + UNKNOWN = 0, + /** Global Positioning System. */ + GPS = 1, + /** Satellite-Based Augmentation System. */ + SBAS = 2, + /** Global Navigation Satellite System. */ + GLONASS = 3, + /** Quasi-Zenith Satellite System. */ + QZSS = 4, + /** BeiDou Navigation Satellite System. */ + BEIDOU = 5, + /** Galileo Navigation Satellite System. */ + GALILEO = 6, + /** Indian Regional Navigation Satellite System. */ + IRNSS = 7, +} \ No newline at end of file diff --git a/gnss/aidl/android/hardware/gnss/IGnss.aidl b/gnss/aidl/android/hardware/gnss/IGnss.aidl index 1da254c7ef..24632aa8d6 100644 --- a/gnss/aidl/android/hardware/gnss/IGnss.aidl +++ b/gnss/aidl/android/hardware/gnss/IGnss.aidl @@ -16,7 +16,9 @@ package android.hardware.gnss; +import android.hardware.gnss.IGnssCallback; import android.hardware.gnss.IGnssPsds; +import android.hardware.gnss.IGnssConfiguration; /** * Represents the standard GNSS (Global Navigation Satellite System) interface. @@ -24,10 +26,53 @@ import android.hardware.gnss.IGnssPsds; @VintfStability interface IGnss { + /** + * All GNSS Binder calls may return a ServiceSpecificException with the following error + * codes. + */ + const int ERROR_INVALID_ARGUMENT = 1; + + /** + * Opens the interface and provides the callback routines to the implementation of this + * interface. + * + * The framework calls this method to instruct the GPS engine to prepare for serving requests + * from the framework. The GNSS HAL implementation must respond to all GNSS requests from the + * framework upon successful return from this method until cleanup() method is called to + * close this interface. + * + * @param callback Callback interface for IGnss. + */ + void setCallback(in IGnssCallback callback); + + /** + * Closes the interface. + * + * The close() method is called by the framework to tell the GNSS HAL implementation to + * clear the callback and not expect any GNSS requests in the immediate future - e.g. this may + * be called when location is disabled by a user setting or low battery conditions. The GNSS HAL + * implementation must immediately stop responding to any existing requests until the + * setCallback() method is called again and the requests are re-initiated by the framework. + * + * After this method is called, the GNSS HAL implementation may choose to modify GNSS hardware + * states to save power. It is expected that when setCallback() method is called again to + * reopen this interface, to serve requests, there may be some minor delays in GNSS response + * requests as hardware readiness states are restored, not to exceed those that occur on normal + * device boot up. + */ + void close(); + /** * This method returns the IGnssPsds interface. * * @return Handle to the IGnssPsds interface. */ IGnssPsds getExtensionPsds(); + + /** + * This method returns the IGnssConfiguration interface. + * + * @return Handle to the IGnssConfiguration interface. + */ + IGnssConfiguration getExtensionGnssConfiguration(); } \ No newline at end of file diff --git a/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl b/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl new file mode 100644 index 0000000000..a46a018141 --- /dev/null +++ b/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.gnss; + +import android.hardware.gnss.IGnssPsds; +import android.hardware.gnss.IGnssConfiguration; + +/** + * This interface is required for the HAL to communicate certain information + * like status and location info back to the framework, the framework implements + * the interfaces and passes a handle to the HAL. + */ +@VintfStability +interface IGnssCallback { + + /** Capability bit mask indicating GNSS supports blocklisting satellites */ + const int CAPABILITY_SATELLITE_BLOCKLIST = 1 << 0; + + /** + * Callback to inform framework of the GNSS HAL implementation's capabilities. + * + * @param capabilities Capability parameter is a bit field of the Capability bit masks. + */ + void gnssSetCapabilitiesCb(in int capabilities); +} \ No newline at end of file diff --git a/gnss/aidl/android/hardware/gnss/IGnssConfiguration.aidl b/gnss/aidl/android/hardware/gnss/IGnssConfiguration.aidl new file mode 100644 index 0000000000..e0ad3575f0 --- /dev/null +++ b/gnss/aidl/android/hardware/gnss/IGnssConfiguration.aidl @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.gnss; + +import android.hardware.gnss.BlocklistedSource; + +/** + * Extended interface for GNSS Configuration support. + */ +@VintfStability +interface IGnssConfiguration { + + /** SUPL mode bitmask for Mobile Station Based. */ + const int SUPL_MODE_MSB = 0x01; + + /** SUPL mode bitmask for Mobile Station Assisted. */ + const int SUPL_MODE_MSA = 0x02; + + /** LPP profile settings bitmask for enabling LTE Positioning Protocol User Plane. */ + const int LPP_PROFILE_USER_PLANE = 0x01; + + /** LPP profile settings bitmask for enabling LTE Positioning Protocol Control Plane. */ + const int LPP_PROFILE_CONTROL_PLANE = 0x02; + + /** A-Glonass positioning protocol bitmask for Radio Resource Control (RRC) Control Plane. */ + const int GLONASS_POS_PROTOCOL_RRC_CPLANE = 0x01; + + /** A-Glonass positioning protocol bitmask for Radio Resource Location User Plane. */ + const int GLONASS_POS_PROTOCOL_RRLP_UPLANE = 0x02; + + /** A-Glonass positioning protocol bitmask for LTE Positioning Protocol User Plane. */ + const int GLONASS_POS_PROTOCOL_LPP_UPLANE = 0x04; + + /** + * This method sets the SUPL version requested by Carrier. The GNSS HAL must use this version + * of the SUPL protocol if supported. + * + * @param version SUPL version requested by carrier. This is a bit mask with bits 0:7 + * representing a service indicator field, bits 8:15 representing the minor version and bits + * 16:23 representing the major version. + */ + void setSuplVersion(in int version); + + /** + * This method sets the SUPL mode. + * + * @param mode Bitmask that specifies the SUPL mode which is set with the SUPL_MODE_* constants. + */ + void setSuplMode(in int mode); + + /** + * This method sets the LTE Positioning Profile configuration. + * + * @param lppProfile Bitmask that specifies the LTE Positioning Profile configuration to be set + * as per the LPP_PROFILE_* constants. If none of the bits are set, the default setting is + * Radio Resource Location Protocol (RRLP). + */ + void setLppProfile(in int lppProfile); + + /** + * This method selects positioning protocol on A-Glonass system. + * + * @param protocol Bitmask that specifies the positioning protocol to be set as per + * GLONASS_POS_PROTOCOL_* constants. + */ + void setGlonassPositioningProtocol(in int protocol); + + /** + * This method configures which PDN to use. + * + * @param enable Use emergency PDN if true and regular PDN if false. + */ + void setEmergencySuplPdn(in boolean enable); + + /** + * This method sets the emergency session extension duration. The GNSS HAL + * implementation must serve emergency SUPL and Control Plane network initiated + * location requests for this extra duration after the user initiated emergency + * session ends. + * + * @param emergencyExtensionSeconds Number of seconds to extend the emergency + * session duration post emergency call. + */ + void setEsExtensionSec(in int emergencyExtensionSeconds); + + /** + * Injects a vector of BlocklistedSource(s) which the HAL must not use to calculate the + * GNSS location output. + * + * The superset of all satellite sources provided, including wildcards, in the latest call + * to this method, is the set of satellites sources that must not be used in calculating + * location. + * + * All measurements from the specified satellites, across frequency bands, are blocklisted + * together. + * + * If this method is never called after the IGnssConfiguration.hal connection is made on boot, + * or is called with an empty vector, then no satellites are to be blocklisted as a result of + * this API. + * + * This blocklist must be considered as an additional source of which satellites + * should not be trusted for location on top of existing sources of similar information + * such as satellite broadcast health being unhealthy and measurement outlier removal. + * + * @param blocklist The BlocklistedSource(s) of satellites the HAL must not use. + */ + void setBlocklist(in BlocklistedSource[] blocklist); +} \ No newline at end of file diff --git a/gnss/aidl/android/hardware/gnss/IGnssPsds.aidl b/gnss/aidl/android/hardware/gnss/IGnssPsds.aidl index 6f53d6faac..7c4609653f 100644 --- a/gnss/aidl/android/hardware/gnss/IGnssPsds.aidl +++ b/gnss/aidl/android/hardware/gnss/IGnssPsds.aidl @@ -32,18 +32,14 @@ interface IGnssPsds { * @param psdsType Type of PSDS data. * @param psdsData GNSS PSDS data. Framework must not parse the data since the data format is * opaque to framework. - * - * @return True if the operation is successful. */ - boolean injectPsdsData(in PsdsType psdsType, in byte[] psdsData); + void injectPsdsData(in PsdsType psdsType, in byte[] psdsData); /** * Opens the PSDS interface and provides the callback routines to the implementation of this * interface. * * @param callback Handle to the IGnssPsdsCallback interface. - * - * @return True if the operation is successful. */ - boolean setCallback(in IGnssPsdsCallback callback); + void setCallback(in IGnssPsdsCallback callback); } \ No newline at end of file diff --git a/gnss/aidl/default/Android.bp b/gnss/aidl/default/Android.bp index 8c4ee405aa..1fe43c37a4 100644 --- a/gnss/aidl/default/Android.bp +++ b/gnss/aidl/default/Android.bp @@ -17,8 +17,13 @@ cc_binary { name: "android.hardware.gnss-service.example", relative_install_path: "hw", - init_rc: ["gnss-default.rc"], - vintf_fragments: ["gnss-default.xml"], + init_rc: [ + "gnss-default.rc", + ], + vintf_fragments: [ + "gnss-default.xml", + "gnss@2.1-service.xml", + ], vendor: true, cflags: [ "-Wall", @@ -27,12 +32,26 @@ cc_binary { shared_libs: [ "libbase", "libbinder_ndk", + "libhidlbase", + "libutils", "liblog", + "android.hardware.gnss@2.1", + "android.hardware.gnss@2.0", + "android.hardware.gnss@1.1", + "android.hardware.gnss@1.0", + "android.hardware.gnss.measurement_corrections@1.1", + "android.hardware.gnss.measurement_corrections@1.0", + "android.hardware.gnss.visibility_control@1.0", "android.hardware.gnss-ndk_platform", ], srcs: [ "Gnss.cpp", + "GnssHidlHal.cpp", "GnssPsds.cpp", + "GnssConfiguration.cpp", "service.cpp", ], + static_libs: [ + "android.hardware.gnss@common-default-lib", + ], } diff --git a/gnss/aidl/default/Gnss.cpp b/gnss/aidl/default/Gnss.cpp index 2a359244ef..b4d92fd62f 100644 --- a/gnss/aidl/default/Gnss.cpp +++ b/gnss/aidl/default/Gnss.cpp @@ -18,14 +18,51 @@ #include "Gnss.h" #include +#include "GnssConfiguration.h" #include "GnssPsds.h" namespace aidl::android::hardware::gnss { +std::shared_ptr Gnss::sGnssCallback = nullptr; + +ndk::ScopedAStatus Gnss::setCallback(const std::shared_ptr& callback) { + ALOGD("Gnss::setCallback"); + if (callback == nullptr) { + ALOGE("%s: Null callback ignored", __func__); + return ndk::ScopedAStatus::fromExceptionCode(STATUS_INVALID_OPERATION); + } + + sGnssCallback = callback; + + int capabilities = (int)IGnssCallback::CAPABILITY_SATELLITE_BLOCKLIST; + auto status = sGnssCallback->gnssSetCapabilitiesCb(capabilities); + if (!status.isOk()) { + ALOGE("%s: Unable to invoke callback.gnssSetCapabilities", __func__); + } + + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Gnss::close() { + ALOGD("Gnss::close"); + sGnssCallback = nullptr; + return ndk::ScopedAStatus::ok(); +} + ndk::ScopedAStatus Gnss::getExtensionPsds(std::shared_ptr* iGnssPsds) { ALOGD("Gnss::getExtensionPsds"); *iGnssPsds = SharedRefBase::make(); return ndk::ScopedAStatus::ok(); } +ndk::ScopedAStatus Gnss::getExtensionGnssConfiguration( + std::shared_ptr* iGnssConfiguration) { + ALOGD("Gnss::getExtensionGnssConfiguration"); + if (mGnssConfiguration == nullptr) { + mGnssConfiguration = SharedRefBase::make(); + } + *iGnssConfiguration = mGnssConfiguration; + return ndk::ScopedAStatus::ok(); +} + } // namespace aidl::android::hardware::gnss diff --git a/gnss/aidl/default/Gnss.h b/gnss/aidl/default/Gnss.h index 9864e9d98c..61d7cf752b 100644 --- a/gnss/aidl/default/Gnss.h +++ b/gnss/aidl/default/Gnss.h @@ -17,12 +17,24 @@ #pragma once #include +#include #include +#include "GnssConfiguration.h" namespace aidl::android::hardware::gnss { class Gnss : public BnGnss { + public: + ndk::ScopedAStatus setCallback(const std::shared_ptr& callback) override; + ndk::ScopedAStatus close() override; ndk::ScopedAStatus getExtensionPsds(std::shared_ptr* iGnssPsds) override; + ndk::ScopedAStatus getExtensionGnssConfiguration( + std::shared_ptr* iGnssConfiguration) override; + + std::shared_ptr mGnssConfiguration; + + private: + static std::shared_ptr sGnssCallback; }; } // namespace aidl::android::hardware::gnss diff --git a/gnss/aidl/default/GnssConfiguration.cpp b/gnss/aidl/default/GnssConfiguration.cpp new file mode 100644 index 0000000000..30e0d8c8b9 --- /dev/null +++ b/gnss/aidl/default/GnssConfiguration.cpp @@ -0,0 +1,52 @@ +/* + * 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 "GnssConfigurationAidl" + +#include "GnssConfiguration.h" +#include + +namespace aidl::android::hardware::gnss { + +ndk::ScopedAStatus GnssConfiguration::setBlocklist(const vector& sourceList) { + ALOGD("GnssConfiguration::setBlocklist"); + std::unique_lock lock(mMutex); + mBlocklistedConstellationSet.clear(); + mBlocklistedSourceSet.clear(); + for (const auto& source : sourceList) { + if (source.svid == 0) { + // Wildcard blocklist, i.e., blocklist entire constellation. + mBlocklistedConstellationSet.insert(source.constellation); + } else { + mBlocklistedSourceSet.insert(source); + } + } + return ndk::ScopedAStatus::ok(); +} + +bool GnssConfiguration::isBlocklistedV2_1(const GnssSvInfoV2_1& gnssSvInfo) const { + std::unique_lock lock(mMutex); + if (mBlocklistedConstellationSet.find(static_cast( + gnssSvInfo.v2_0.constellation)) != mBlocklistedConstellationSet.end()) { + return true; + } + BlocklistedSource source = { + .constellation = static_cast(gnssSvInfo.v2_0.constellation), + .svid = gnssSvInfo.v2_0.v1_0.svid}; + return (mBlocklistedSourceSet.find(source) != mBlocklistedSourceSet.end()); +} + +} // namespace aidl::android::hardware::gnss diff --git a/gnss/aidl/default/GnssConfiguration.h b/gnss/aidl/default/GnssConfiguration.h new file mode 100644 index 0000000000..25fa16e610 --- /dev/null +++ b/gnss/aidl/default/GnssConfiguration.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include +#include +#include + +namespace aidl::android::hardware::gnss { + +using android::hardware::gnss::GnssConstellationType; + +struct BlocklistedSourceHash { + inline int operator()(const BlocklistedSource& source) const { + return int(source.constellation) * 1000 + int(source.svid); + } +}; + +struct BlocklistedSourceEqual { + inline bool operator()(const BlocklistedSource& s1, const BlocklistedSource& s2) const { + return (s1.constellation == s2.constellation) && (s1.svid == s2.svid); + } +}; + +using GnssSvInfoV2_1 = ::android::hardware::gnss::V2_1::IGnssCallback::GnssSvInfo; +using std::vector; +using BlocklistedSourceSet = + std::unordered_set; +using BlocklistedConstellationSet = std::unordered_set; + +struct GnssConfiguration : public BnGnssConfiguration { + public: + ndk::ScopedAStatus setSuplVersion(int) override { return ndk::ScopedAStatus::ok(); } + + ndk::ScopedAStatus setSuplMode(int) override { return ndk::ScopedAStatus::ok(); } + + ndk::ScopedAStatus setLppProfile(int) override { return ndk::ScopedAStatus::ok(); } + + ndk::ScopedAStatus setGlonassPositioningProtocol(int) override { + return ndk::ScopedAStatus::ok(); + } + + ndk::ScopedAStatus setEmergencySuplPdn(bool) override { return ndk::ScopedAStatus::ok(); } + + ndk::ScopedAStatus setEsExtensionSec(int) override { return ndk::ScopedAStatus::ok(); } + + ndk::ScopedAStatus setBlocklist(const vector& blocklist) override; + + bool isBlocklistedV2_1(const GnssSvInfoV2_1& gnssSvInfo) const; + + private: + BlocklistedSourceSet mBlocklistedSourceSet; + BlocklistedConstellationSet mBlocklistedConstellationSet; + mutable std::recursive_mutex mMutex; +}; + +} // namespace aidl::android::hardware::gnss diff --git a/gnss/aidl/default/GnssHidlHal.cpp b/gnss/aidl/default/GnssHidlHal.cpp new file mode 100644 index 0000000000..11fc8064fa --- /dev/null +++ b/gnss/aidl/default/GnssHidlHal.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "GnssHidlHal" + +#include "GnssHidlHal.h" +//#include + +namespace aidl::android::hardware::gnss { + +namespace V1_0 = ::android::hardware::gnss::V1_0; + +GnssHidlHal::GnssHidlHal(const std::shared_ptr& gnssAidl) : mGnssAidl(gnssAidl) { + Gnss* iGnss = mGnssAidl.get(); + std::shared_ptr iGnssConfiguration; + auto status = iGnss->getExtensionGnssConfiguration(&iGnssConfiguration); + if (!status.isOk()) { + ALOGE("Failed to getExtensionGnssConfiguration."); + } else { + mGnssConfigurationAidl = iGnss->mGnssConfiguration; + } +}; + +hidl_vec GnssHidlHal::filterBlocklistedSatellitesV2_1( + hidl_vec gnssSvInfoList) { + ALOGD("filterBlocklistSatellitesV2_1 - overridden by GnssHidlHal class"); + if (mGnssConfigurationAidl == nullptr) { + ALOGE("Handle to AIDL GnssConfiguration is not available."); + return gnssSvInfoList; + } + for (uint32_t i = 0; i < gnssSvInfoList.size(); i++) { + if (mGnssConfigurationAidl->isBlocklistedV2_1(gnssSvInfoList[i])) { + ALOGD("Blocklisted constellation: %d, svid: %d", + (int)gnssSvInfoList[i].v2_0.constellation, gnssSvInfoList[i].v2_0.v1_0.svid); + gnssSvInfoList[i].v2_0.v1_0.svFlag &= + ~static_cast(V1_0::IGnssCallback::GnssSvFlags::USED_IN_FIX); + } + } + return gnssSvInfoList; +} + +} // namespace aidl::android::hardware::gnss diff --git a/gnss/aidl/default/GnssHidlHal.h b/gnss/aidl/default/GnssHidlHal.h new file mode 100644 index 0000000000..50aad3a206 --- /dev/null +++ b/gnss/aidl/default/GnssHidlHal.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "Gnss.h" +#include "GnssConfiguration.h" +#include "v2_1/GnssTemplate.h" + +namespace aidl::android::hardware::gnss { + +using ::android::hardware::gnss::common::implementation::GnssTemplate; +using GnssSvInfo = ::android::hardware::gnss::V2_1::IGnssCallback::GnssSvInfo; + +class GnssHidlHal : public GnssTemplate<::android::hardware::gnss::V2_1::IGnss> { + public: + GnssHidlHal(const std::shared_ptr& gnssAidl); + + private: + hidl_vec filterBlocklistedSatellitesV2_1( + hidl_vec gnssSvInfoList) override; + + std::shared_ptr mGnssAidl; + std::shared_ptr mGnssConfigurationAidl; +}; + +} // namespace aidl::android::hardware::gnss diff --git a/gnss/aidl/default/GnssPsds.cpp b/gnss/aidl/default/GnssPsds.cpp index c354217ebe..6512af610a 100644 --- a/gnss/aidl/default/GnssPsds.cpp +++ b/gnss/aidl/default/GnssPsds.cpp @@ -17,27 +17,28 @@ #define LOG_TAG "GnssPsdsAidl" #include "GnssPsds.h" - +#include #include namespace aidl::android::hardware::gnss { std::shared_ptr GnssPsds::sCallback = nullptr; -ndk::ScopedAStatus GnssPsds::setCallback(const std::shared_ptr& callback, - bool* success) { +ndk::ScopedAStatus GnssPsds::setCallback(const std::shared_ptr& callback) { ALOGD("setCallback"); std::unique_lock lock(mMutex); sCallback = callback; - *success = true; return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus GnssPsds::injectPsdsData(PsdsType psdsType, const std::vector& psdsData, - bool* success) { +ndk::ScopedAStatus GnssPsds::injectPsdsData(PsdsType psdsType, + const std::vector& psdsData) { ALOGD("injectPsdsData. psdsType: %d, psdsData: %d bytes", static_cast(psdsType), static_cast(psdsData.size())); - *success = (psdsData.size() > 0); - return ndk::ScopedAStatus::ok(); + if (psdsData.size() > 0) { + return ndk::ScopedAStatus::ok(); + } else { + return ndk::ScopedAStatus::fromServiceSpecificError(IGnss::ERROR_INVALID_ARGUMENT); + } } } // namespace aidl::android::hardware::gnss diff --git a/gnss/aidl/default/GnssPsds.h b/gnss/aidl/default/GnssPsds.h index fc65bc15db..de9e68f745 100644 --- a/gnss/aidl/default/GnssPsds.h +++ b/gnss/aidl/default/GnssPsds.h @@ -22,10 +22,9 @@ namespace aidl::android::hardware::gnss { struct GnssPsds : public BnGnssPsds { public: - ndk::ScopedAStatus setCallback(const std::shared_ptr& callback, - bool* success) override; - ndk::ScopedAStatus injectPsdsData(PsdsType psdsType, const std::vector& psdsData, - bool* success) override; + ndk::ScopedAStatus setCallback(const std::shared_ptr& callback) override; + ndk::ScopedAStatus injectPsdsData(PsdsType psdsType, + const std::vector& psdsData) override; private: // Guarded by mMutex diff --git a/gnss/aidl/default/gnss@2.1-service.xml b/gnss/aidl/default/gnss@2.1-service.xml new file mode 100644 index 0000000000..12a1fdfa08 --- /dev/null +++ b/gnss/aidl/default/gnss@2.1-service.xml @@ -0,0 +1,12 @@ + + + android.hardware.gnss + hwbinder + 2.1 + 1.1 + + IGnss + default + + + diff --git a/gnss/aidl/default/service.cpp b/gnss/aidl/default/service.cpp index c79a2718c5..09f1ad2b36 100644 --- a/gnss/aidl/default/service.cpp +++ b/gnss/aidl/default/service.cpp @@ -14,22 +14,45 @@ * limitations under the License. */ -#include "Gnss.h" +#define LOG_TAG "Gnss-main" #include #include #include +#include +#include +#include +#include +#include "Gnss.h" +#include "GnssHidlHal.h" using aidl::android::hardware::gnss::Gnss; +using aidl::android::hardware::gnss::GnssHidlHal; +using ::android::OK; +using ::android::sp; +using ::android::hardware::configureRpcThreadpool; +using ::android::hardware::joinRpcThreadpool; +using ::android::hardware::gnss::V2_1::IGnss; int main() { - ABinderProcess_setThreadPoolMaxThreadCount(0); - std::shared_ptr vib = ndk::SharedRefBase::make(); + ABinderProcess_setThreadPoolMaxThreadCount(1); + ABinderProcess_startThreadPool(); + std::shared_ptr gnssAidl = ndk::SharedRefBase::make(); const std::string instance = std::string() + Gnss::descriptor + "/default"; - binder_status_t status = AServiceManager_addService(vib->asBinder().get(), instance.c_str()); + binder_status_t status = + AServiceManager_addService(gnssAidl->asBinder().get(), instance.c_str()); CHECK(status == STATUS_OK); + sp gnss = new GnssHidlHal(gnssAidl); + configureRpcThreadpool(1, true /* will join */); + if (gnss->registerAsService() != OK) { + ALOGE("Could not register gnss 2.1 service."); + return 0; + } + + joinRpcThreadpool(); ABinderProcess_joinThreadPool(); + return EXIT_FAILURE; // should not reach } diff --git a/gnss/aidl/vts/Android.bp b/gnss/aidl/vts/Android.bp index e57b421768..7f3e5ef339 100644 --- a/gnss/aidl/vts/Android.bp +++ b/gnss/aidl/vts/Android.bp @@ -18,14 +18,22 @@ cc_test { "VtsHalTargetTestDefaults", "use_libaidlvintf_gtest_helper_static", ], - srcs: ["VtsHalGnssTargetTest.cpp"], + srcs: [ + "gnss_hal_test.cpp", + "gnss_hal_test_cases.cpp", + "GnssCallbackAidl.cpp", + "VtsHalGnssTargetTest.cpp", + ], shared_libs: [ + "android.hardware.gnss@2.1", "libbinder", ], static_libs: [ "android.hardware.gnss-cpp", + "android.hardware.gnss@common-vts-lib", ], test_suites: [ + "general-tests", "vts", ], } diff --git a/gnss/aidl/vts/GnssCallbackAidl.cpp b/gnss/aidl/vts/GnssCallbackAidl.cpp new file mode 100644 index 0000000000..f5c745b75c --- /dev/null +++ b/gnss/aidl/vts/GnssCallbackAidl.cpp @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "GnssCallbackAidl.h" +#include + +android::binder::Status GnssCallbackAidl::gnssSetCapabilitiesCb(const int capabilities) { + ALOGI("Capabilities received %d", capabilities); + capabilities_cbq_.store(capabilities); + return android::binder::Status::ok(); +} diff --git a/gnss/aidl/vts/GnssCallbackAidl.h b/gnss/aidl/vts/GnssCallbackAidl.h new file mode 100644 index 0000000000..7f802ea02e --- /dev/null +++ b/gnss/aidl/vts/GnssCallbackAidl.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include "GnssCallbackEventQueue.h" + +/* Callback class for data & Event. */ +class GnssCallbackAidl : public android::hardware::gnss::BnGnssCallback { + public: + GnssCallbackAidl() : capabilities_cbq_("capabilities"){}; + ~GnssCallbackAidl(){}; + + android::binder::Status gnssSetCapabilitiesCb(const int capabilities) override; + + int last_capabilities_; + android::hardware::gnss::common::GnssCallbackEventQueue capabilities_cbq_; +}; \ No newline at end of file diff --git a/gnss/aidl/vts/VtsHalGnssTargetTest.cpp b/gnss/aidl/vts/VtsHalGnssTargetTest.cpp index e7ffc05156..4bba92b49b 100644 --- a/gnss/aidl/vts/VtsHalGnssTargetTest.cpp +++ b/gnss/aidl/vts/VtsHalGnssTargetTest.cpp @@ -13,60 +13,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include -#include + +#include "gnss_hal_test.h" #include -#include #include #include using android::ProcessState; -using android::sp; -using android::String16; -using android::binder::Status; -using android::hardware::gnss::IGnss; -using android::hardware::gnss::IGnssPsds; -using android::hardware::gnss::PsdsType; - -class GnssAidlHalTest : public testing::TestWithParam { - public: - virtual void SetUp() override { - gnss_hal_ = android::waitForDeclaredService(String16(GetParam().c_str())); - ASSERT_NE(gnss_hal_, nullptr); - } - - sp gnss_hal_; -}; - -/* - * SetupTeardownCreateCleanup: - * Requests the gnss HAL then calls cleanup - * - * Empty test fixture to verify basic Setup & Teardown - */ -TEST_P(GnssAidlHalTest, SetupTeardownCreateCleanup) {} - -/* - * TestPsdsExtension: - * 1. Gets the PsdsExtension and verifies that it returns a non-null extension. - * 2. Injects empty PSDS data and verifies that it returns false. - */ -TEST_P(GnssAidlHalTest, TestPsdsExtension) { - sp iGnssPsds; - auto status = gnss_hal_->getExtensionPsds(&iGnssPsds); - ASSERT_TRUE(status.isOk()); - ASSERT_TRUE(iGnssPsds != nullptr); - - bool success; - status = iGnssPsds->injectPsdsData(PsdsType::LONG_TERM, std::vector(), &success); - ASSERT_TRUE(status.isOk()); - ASSERT_FALSE(success); -} -GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GnssAidlHalTest); -INSTANTIATE_TEST_SUITE_P(, GnssAidlHalTest, - testing::ValuesIn(android::getAidlHalInstanceNames(IGnss::descriptor)), +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GnssHalTest); +INSTANTIATE_TEST_SUITE_P(, GnssHalTest, + testing::ValuesIn(android::getAidlHalInstanceNames(IGnssAidl::descriptor)), android::PrintInstanceNameToString); int main(int argc, char** argv) { diff --git a/gnss/aidl/vts/gnss_hal_test.cpp b/gnss/aidl/vts/gnss_hal_test.cpp new file mode 100644 index 0000000000..2447bf8c84 --- /dev/null +++ b/gnss/aidl/vts/gnss_hal_test.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "gnss_hal_test.h" +#include + +using GnssConstellationTypeAidl = android::hardware::gnss::GnssConstellationType; + +void GnssHalTest::SetUp() { + // Get AIDL handle + aidl_gnss_hal_ = android::waitForDeclaredService(String16(GetParam().c_str())); + ASSERT_NE(aidl_gnss_hal_, nullptr); + + const auto& hidlInstanceNames = android::hardware::getAllHalInstanceNames( + android::hardware::gnss::V2_1::IGnss::descriptor); + gnss_hal_ = IGnss_V2_1::getService(hidlInstanceNames[0]); + ASSERT_NE(gnss_hal_, nullptr); + + SetUpGnssCallback(); +} + +void GnssHalTest::SetUpGnssCallback() { + aidl_gnss_cb_ = new GnssCallbackAidl(); + ASSERT_NE(aidl_gnss_cb_, nullptr); + + auto status = aidl_gnss_hal_->setCallback(aidl_gnss_cb_); + if (!status.isOk()) { + ALOGE("Failed to setCallback"); + } + + ASSERT_TRUE(status.isOk()); + + /* + * Capabilities callback should trigger. + */ + EXPECT_TRUE(aidl_gnss_cb_->capabilities_cbq_.retrieve(aidl_gnss_cb_->last_capabilities_, + TIMEOUT_SEC)); + + EXPECT_EQ(aidl_gnss_cb_->capabilities_cbq_.calledCount(), 1); + + // Invoke the super method. + GnssHalTestTemplate::SetUpGnssCallback(); +} diff --git a/gnss/aidl/vts/gnss_hal_test.h b/gnss/aidl/vts/gnss_hal_test.h new file mode 100644 index 0000000000..eb5301e2cd --- /dev/null +++ b/gnss/aidl/vts/gnss_hal_test.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include + +#include +#include + +#include +#include "GnssCallbackAidl.h" +#include "v2_1/gnss_hal_test_template.h" + +using IGnss_V2_1 = android::hardware::gnss::V2_1::IGnss; + +using android::ProcessState; +using android::sp; +using android::String16; +using IGnssAidl = android::hardware::gnss::IGnss; +using android::hardware::gnss::BlocklistedSource; +using android::hardware::gnss::IGnssConfiguration; + +// The main test class for GNSS HAL. +class GnssHalTest : public GnssHalTestTemplate { + public: + GnssHalTest(){}; + ~GnssHalTest(){}; + virtual void SetUp() override; + virtual void SetUpGnssCallback() override; + + sp aidl_gnss_hal_; + sp aidl_gnss_cb_; // Primary callback interface +}; diff --git a/gnss/aidl/vts/gnss_hal_test_cases.cpp b/gnss/aidl/vts/gnss_hal_test_cases.cpp new file mode 100644 index 0000000000..2b8a447206 --- /dev/null +++ b/gnss/aidl/vts/gnss_hal_test_cases.cpp @@ -0,0 +1,450 @@ +/* + * 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 "GnssHalTestCases" + +#include +#include "gnss_hal_test.h" + +using android::sp; +using android::hardware::gnss::BlocklistedSource; +using GnssConstellationTypeAidl = android::hardware::gnss::GnssConstellationType; +using android::hardware::gnss::IGnssConfiguration; +using android::hardware::gnss::IGnssPsds; +using android::hardware::gnss::PsdsType; + +/* + * SetupTeardownCreateCleanup: + * Requests the gnss HAL then calls cleanup + * + * Empty test fixture to verify basic Setup & Teardown + */ +TEST_P(GnssHalTest, SetupTeardownCreateCleanup) {} + +/* + * TestPsdsExtension: + * 1. Gets the PsdsExtension and verifies that it returns a non-null extension. + * 2. Injects empty PSDS data and verifies that it returns false. + */ +TEST_P(GnssHalTest, TestPsdsExtension) { + sp iGnssPsds; + auto status = aidl_gnss_hal_->getExtensionPsds(&iGnssPsds); + ASSERT_TRUE(status.isOk()); + ASSERT_TRUE(iGnssPsds != nullptr); + + status = iGnssPsds->injectPsdsData(PsdsType::LONG_TERM, std::vector()); + ASSERT_TRUE(status.isOk()); +} + +/* + * FindStrongFrequentNonGpsSource: + * + * Search through a GnssSvStatus list for the strongest non-GPS satellite observed enough times + * + * returns the strongest source, + * or a source with constellation == UNKNOWN if none are found sufficient times + */ +BlocklistedSource FindStrongFrequentNonGpsSource( + const std::list> sv_info_list, + const int min_observations) { + struct ComparableBlocklistedSource { + BlocklistedSource id; + + ComparableBlocklistedSource() { + id.constellation = GnssConstellationTypeAidl::UNKNOWN; + id.svid = 0; + } + + bool operator<(const ComparableBlocklistedSource& compare) const { + return ((id.svid < compare.id.svid) || ((id.svid == compare.id.svid) && + (id.constellation < compare.id.constellation))); + } + }; + + struct SignalCounts { + int observations; + float max_cn0_dbhz; + }; + + std::map mapSignals; + + for (const auto& sv_info_vec : sv_info_list) { + for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) { + const auto& gnss_sv = sv_info_vec[iSv]; + if ((gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX) && + (gnss_sv.v2_0.constellation != GnssConstellationType::GPS)) { + ComparableBlocklistedSource source; + source.id.svid = gnss_sv.v2_0.v1_0.svid; + source.id.constellation = + static_cast(gnss_sv.v2_0.constellation); + + const auto& itSignal = mapSignals.find(source); + if (itSignal == mapSignals.end()) { + SignalCounts counts; + counts.observations = 1; + counts.max_cn0_dbhz = gnss_sv.v2_0.v1_0.cN0Dbhz; + mapSignals.insert( + std::pair(source, counts)); + } else { + itSignal->second.observations++; + if (itSignal->second.max_cn0_dbhz < gnss_sv.v2_0.v1_0.cN0Dbhz) { + itSignal->second.max_cn0_dbhz = gnss_sv.v2_0.v1_0.cN0Dbhz; + } + } + } + } + } + + float max_cn0_dbhz_with_sufficient_count = 0.; + int total_observation_count = 0; + int blocklisted_source_count_observation = 0; + + ComparableBlocklistedSource source_to_blocklist; // initializes to zero = UNKNOWN constellation + for (auto const& pairSignal : mapSignals) { + total_observation_count += pairSignal.second.observations; + if ((pairSignal.second.observations >= min_observations) && + (pairSignal.second.max_cn0_dbhz > max_cn0_dbhz_with_sufficient_count)) { + source_to_blocklist = pairSignal.first; + blocklisted_source_count_observation = pairSignal.second.observations; + max_cn0_dbhz_with_sufficient_count = pairSignal.second.max_cn0_dbhz; + } + } + ALOGD("Among %d observations, chose svid %d, constellation %d, " + "with %d observations at %.1f max CNo", + total_observation_count, source_to_blocklist.id.svid, + (int)source_to_blocklist.id.constellation, blocklisted_source_count_observation, + max_cn0_dbhz_with_sufficient_count); + + return source_to_blocklist.id; +} + +/* + * BlocklistIndividualSatellites: + * + * 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding + * GnssStatus for common satellites (strongest and one other.) + * 2a & b) Turns off location, and blocklists common satellites. + * 3) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding + * GnssStatus does not use those satellites. + * 4a & b) Turns off location, and send in empty blocklist. + * 5a) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding + * GnssStatus does re-use at least the previously strongest satellite + * 5b) Retry a few times, in case GNSS search strategy takes a while to reacquire even the + * formerly strongest satellite + */ +TEST_P(GnssHalTest, BlocklistIndividualSatellites) { + if (!(aidl_gnss_cb_->last_capabilities_ & + (int)GnssCallbackAidl::CAPABILITY_SATELLITE_BLOCKLIST)) { + ALOGI("Test BlocklistIndividualSatellites skipped. SATELLITE_BLOCKLIST capability not " + "supported."); + return; + } + + const int kLocationsToAwait = 3; + const int kRetriesToUnBlocklist = 10; + + gnss_cb_->location_cbq_.reset(); + StartAndCheckLocations(kLocationsToAwait); + int location_called_count = gnss_cb_->location_cbq_.calledCount(); + + // Tolerate 1 less sv status to handle edge cases in reporting. + int sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size(); + EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait); + ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations (%d received)", + sv_info_list_cbq_size, kLocationsToAwait, location_called_count); + + /* + * Identify strongest SV seen at least kLocationsToAwait -1 times + * Why -1? To avoid test flakiness in case of (plausible) slight flakiness in strongest signal + * observability (one epoch RF null) + */ + + const int kGnssSvInfoListTimeout = 2; + std::list> sv_info_vec_list; + int count = gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec_list, sv_info_list_cbq_size, + kGnssSvInfoListTimeout); + + ASSERT_EQ(count, sv_info_list_cbq_size); + + BlocklistedSource source_to_blocklist = + FindStrongFrequentNonGpsSource(sv_info_vec_list, kLocationsToAwait - 1); + + if (source_to_blocklist.constellation == GnssConstellationTypeAidl::UNKNOWN) { + // Cannot find a non-GPS satellite. Let the test pass. + ALOGD("Cannot find a non-GPS satellite. Letting the test pass."); + return; + } + + // Stop locations, blocklist the common SV + StopAndClearLocations(); + + sp gnss_configuration_hal; + auto status = aidl_gnss_hal_->getExtensionGnssConfiguration(&gnss_configuration_hal); + ASSERT_TRUE(status.isOk()); + ASSERT_NE(gnss_configuration_hal, nullptr); + + std::vector sources; + sources.resize(1); + sources[0] = source_to_blocklist; + + status = gnss_configuration_hal->setBlocklist(sources); + ASSERT_TRUE(status.isOk()); + + // retry and ensure satellite not used + gnss_cb_->sv_info_list_cbq_.reset(); + + gnss_cb_->location_cbq_.reset(); + StartAndCheckLocations(kLocationsToAwait); + + // early exit if test is being run with insufficient signal + location_called_count = gnss_cb_->location_cbq_.calledCount(); + if (location_called_count == 0) { + ALOGE("0 Gnss locations received - ensure sufficient signal and retry"); + } + ASSERT_TRUE(location_called_count > 0); + + // Tolerate 1 less sv status to handle edge cases in reporting. + sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size(); + EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait); + ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations (%d received)", + sv_info_list_cbq_size, kLocationsToAwait, location_called_count); + for (int i = 0; i < sv_info_list_cbq_size; ++i) { + hidl_vec sv_info_vec; + gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout); + for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) { + const auto& gnss_sv = sv_info_vec[iSv]; + EXPECT_FALSE((gnss_sv.v2_0.v1_0.svid == source_to_blocklist.svid) && + (static_cast(gnss_sv.v2_0.constellation) == + source_to_blocklist.constellation) && + (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX)); + } + } + + // clear blocklist and restart - this time updating the blocklist while location is still on + sources.resize(0); + + status = gnss_configuration_hal->setBlocklist(sources); + ASSERT_TRUE(status.isOk()); + + bool strongest_sv_is_reobserved = false; + // do several loops awaiting a few locations, allowing non-immediate reacquisition strategies + int unblocklist_loops_remaining = kRetriesToUnBlocklist; + while (!strongest_sv_is_reobserved && (unblocklist_loops_remaining-- > 0)) { + StopAndClearLocations(); + gnss_cb_->sv_info_list_cbq_.reset(); + + gnss_cb_->location_cbq_.reset(); + StartAndCheckLocations(kLocationsToAwait); + + // early exit loop if test is being run with insufficient signal + location_called_count = gnss_cb_->location_cbq_.calledCount(); + if (location_called_count == 0) { + ALOGE("0 Gnss locations received - ensure sufficient signal and retry"); + } + ASSERT_TRUE(location_called_count > 0); + + // Tolerate 1 less sv status to handle edge cases in reporting. + sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size(); + EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait); + ALOGD("Clear blocklist, observed %d GnssSvInfo, while awaiting %d Locations" + ", tries remaining %d", + sv_info_list_cbq_size, kLocationsToAwait, unblocklist_loops_remaining); + + for (int i = 0; i < sv_info_list_cbq_size; ++i) { + hidl_vec sv_info_vec; + gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout); + for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) { + const auto& gnss_sv = sv_info_vec[iSv]; + if ((gnss_sv.v2_0.v1_0.svid == source_to_blocklist.svid) && + (static_cast(gnss_sv.v2_0.constellation) == + source_to_blocklist.constellation) && + (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX)) { + strongest_sv_is_reobserved = true; + break; + } + } + if (strongest_sv_is_reobserved) break; + } + } + EXPECT_TRUE(strongest_sv_is_reobserved); + StopAndClearLocations(); +} + +/* + * BlocklistConstellationLocationOff: + * + * 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding + * GnssStatus for any non-GPS constellations. + * 2a & b) Turns off location, and blocklist first non-GPS constellations. + * 3) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding + * GnssStatus does not use any constellation but GPS. + * 4a & b) Clean up by turning off location, and send in empty blocklist. + */ +TEST_P(GnssHalTest, BlocklistConstellationLocationOff) { + if (!(aidl_gnss_cb_->last_capabilities_ & + (int)GnssCallbackAidl::CAPABILITY_SATELLITE_BLOCKLIST)) { + ALOGI("Test BlocklistConstellationLocationOff skipped. SATELLITE_BLOCKLIST capability not " + "supported."); + return; + } + + const int kLocationsToAwait = 3; + const int kGnssSvInfoListTimeout = 2; + + // Find first non-GPS constellation to blocklist + GnssConstellationTypeAidl constellation_to_blocklist = static_cast( + startLocationAndGetNonGpsConstellation(kLocationsToAwait, kGnssSvInfoListTimeout)); + + // Turns off location + StopAndClearLocations(); + + BlocklistedSource source_to_blocklist_1; + source_to_blocklist_1.constellation = constellation_to_blocklist; + source_to_blocklist_1.svid = 0; // documented wildcard for all satellites in this constellation + + // IRNSS was added in 2.0. Always attempt to blocklist IRNSS to verify that the new enum is + // supported. + BlocklistedSource source_to_blocklist_2; + source_to_blocklist_2.constellation = GnssConstellationTypeAidl::IRNSS; + source_to_blocklist_2.svid = 0; // documented wildcard for all satellites in this constellation + + sp gnss_configuration_hal; + auto status = aidl_gnss_hal_->getExtensionGnssConfiguration(&gnss_configuration_hal); + ASSERT_TRUE(status.isOk()); + ASSERT_NE(gnss_configuration_hal, nullptr); + + hidl_vec sources; + sources.resize(2); + sources[0] = source_to_blocklist_1; + sources[1] = source_to_blocklist_2; + + status = gnss_configuration_hal->setBlocklist(sources); + ASSERT_TRUE(status.isOk()); + + // retry and ensure constellation not used + gnss_cb_->sv_info_list_cbq_.reset(); + + gnss_cb_->location_cbq_.reset(); + StartAndCheckLocations(kLocationsToAwait); + + // Tolerate 1 less sv status to handle edge cases in reporting. + int sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size(); + EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait); + ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations", sv_info_list_cbq_size, + kLocationsToAwait); + for (int i = 0; i < sv_info_list_cbq_size; ++i) { + hidl_vec sv_info_vec; + gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout); + for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) { + const auto& gnss_sv = sv_info_vec[iSv]; + EXPECT_FALSE((static_cast(gnss_sv.v2_0.constellation) == + source_to_blocklist_1.constellation) && + (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX)); + EXPECT_FALSE((static_cast(gnss_sv.v2_0.constellation) == + source_to_blocklist_2.constellation) && + (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX)); + } + } + + // clean up + StopAndClearLocations(); + sources.resize(0); + status = gnss_configuration_hal->setBlocklist(sources); + ASSERT_TRUE(status.isOk()); +} + +/* + * BlocklistConstellationLocationOn: + * + * 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding + * GnssStatus for any non-GPS constellations. + * 2a & b) Blocklist first non-GPS constellation, and turn off location. + * 3) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding + * GnssStatus does not use any constellation but GPS. + * 4a & b) Clean up by turning off location, and send in empty blocklist. + */ +TEST_P(GnssHalTest, BlocklistConstellationLocationOn) { + if (!(aidl_gnss_cb_->last_capabilities_ & + (int)GnssCallbackAidl::CAPABILITY_SATELLITE_BLOCKLIST)) { + ALOGI("Test BlocklistConstellationLocationOn skipped. SATELLITE_BLOCKLIST capability not " + "supported."); + return; + } + + const int kLocationsToAwait = 3; + const int kGnssSvInfoListTimeout = 2; + + // Find first non-GPS constellation to blocklist + GnssConstellationTypeAidl constellation_to_blocklist = static_cast( + startLocationAndGetNonGpsConstellation(kLocationsToAwait, kGnssSvInfoListTimeout)); + + BlocklistedSource source_to_blocklist_1; + source_to_blocklist_1.constellation = constellation_to_blocklist; + source_to_blocklist_1.svid = 0; // documented wildcard for all satellites in this constellation + + // IRNSS was added in 2.0. Always attempt to blocklist IRNSS to verify that the new enum is + // supported. + BlocklistedSource source_to_blocklist_2; + source_to_blocklist_2.constellation = GnssConstellationTypeAidl::IRNSS; + source_to_blocklist_2.svid = 0; // documented wildcard for all satellites in this constellation + + sp gnss_configuration_hal; + auto status = aidl_gnss_hal_->getExtensionGnssConfiguration(&gnss_configuration_hal); + ASSERT_TRUE(status.isOk()); + ASSERT_NE(gnss_configuration_hal, nullptr); + + hidl_vec sources; + sources.resize(2); + sources[0] = source_to_blocklist_1; + sources[1] = source_to_blocklist_2; + + status = gnss_configuration_hal->setBlocklist(sources); + ASSERT_TRUE(status.isOk()); + + // Turns off location + StopAndClearLocations(); + + // retry and ensure constellation not used + gnss_cb_->sv_info_list_cbq_.reset(); + + gnss_cb_->location_cbq_.reset(); + StartAndCheckLocations(kLocationsToAwait); + + // Tolerate 1 less sv status to handle edge cases in reporting. + int sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size(); + EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait); + ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations", sv_info_list_cbq_size, + kLocationsToAwait); + for (int i = 0; i < sv_info_list_cbq_size; ++i) { + hidl_vec sv_info_vec; + gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout); + for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) { + const auto& gnss_sv = sv_info_vec[iSv]; + EXPECT_FALSE((static_cast(gnss_sv.v2_0.constellation) == + source_to_blocklist_1.constellation) && + (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX)); + EXPECT_FALSE((static_cast(gnss_sv.v2_0.constellation) == + source_to_blocklist_2.constellation) && + (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX)); + } + } + + // clean up + StopAndClearLocations(); + sources.resize(0); + status = gnss_configuration_hal->setBlocklist(sources); + ASSERT_TRUE(status.isOk()); +} diff --git a/gnss/common/utils/default/include/v2_1/GnssTemplate.h b/gnss/common/utils/default/include/v2_1/GnssTemplate.h index 1fe6c3eb87..0128df4812 100644 --- a/gnss/common/utils/default/include/v2_1/GnssTemplate.h +++ b/gnss/common/utils/default/include/v2_1/GnssTemplate.h @@ -127,12 +127,13 @@ struct GnssTemplate : public T_IGnss { std::atomic mMinIntervalMs; sp mGnssConfiguration; std::atomic mIsActive; - std::atomic mHardwareModeOn; + std::atomic mHardwareModeChecked; std::atomic mGnssFd; std::thread mThread; mutable std::mutex mMutex; - hidl_vec filterBlacklistedSatellitesV2_1(hidl_vec gnssSvInfoList); + virtual hidl_vec filterBlocklistedSatellitesV2_1( + hidl_vec gnssSvInfoList); }; template @@ -148,7 +149,7 @@ template GnssTemplate::GnssTemplate() : mMinIntervalMs(1000), mGnssConfiguration{new GnssConfiguration()}, - mHardwareModeOn(false), + mHardwareModeChecked(false), mGnssFd(-1) {} template @@ -159,16 +160,18 @@ GnssTemplate::~GnssTemplate() { template std::unique_ptr GnssTemplate::getLocationFromHW() { char inputBuffer[INPUT_BUFFER_SIZE]; - if (mGnssFd == -1) { + if (!mHardwareModeChecked) { mGnssFd = open(GNSS_PATH, O_RDWR | O_NONBLOCK); + if (mGnssFd == -1) { + ALOGW("Failed to open /dev/gnss0 errno: %d", errno); + } + mHardwareModeChecked = true; } if (mGnssFd == -1) { - ALOGW("Failed to open /dev/gnss0 errno: %d", errno); return nullptr; } - // Indicates it is a hardwareMode, don't report the default location. - mHardwareModeOn = true; + int bytes_write = write(mGnssFd, CMD_GET_LOCATION, strlen(CMD_GET_LOCATION)); if (bytes_write <= 0) { return nullptr; @@ -206,14 +209,12 @@ Return GnssTemplate::start() { mIsActive = true; mThread = std::thread([this]() { while (mIsActive == true) { - auto svStatus = filterBlacklistedSatellitesV2_1(Utils::getMockSvInfoListV2_1()); + auto svStatus = filterBlocklistedSatellitesV2_1(Utils::getMockSvInfoListV2_1()); this->reportSvStatus(svStatus); auto currentLocation = getLocationFromHW(); - if (mHardwareModeOn) { - if (currentLocation != nullptr) { - // Only report location if the return from hardware is valid - this->reportLocation(*currentLocation); - } + if (mGnssFd != -1 && currentLocation != nullptr) { + // Only report location if the return from hardware is valid + this->reportLocation(*currentLocation); } else { if (sGnssCallback_2_1 != nullptr || sGnssCallback_2_0 != nullptr) { const auto location = Utils::getMockLocationV2_0(); @@ -230,8 +231,9 @@ Return GnssTemplate::start() { } template -hidl_vec GnssTemplate::filterBlacklistedSatellitesV2_1( +hidl_vec GnssTemplate::filterBlocklistedSatellitesV2_1( hidl_vec gnssSvInfoList) { + ALOGD("filterBlocklistedSatellitesV2_1"); for (uint32_t i = 0; i < gnssSvInfoList.size(); i++) { if (mGnssConfiguration->isBlacklistedV2_1(gnssSvInfoList[i])) { gnssSvInfoList[i].v2_0.v1_0.svFlag &= diff --git a/gnss/common/utils/vts/include/v2_1/gnss_hal_test_template.h b/gnss/common/utils/vts/include/v2_1/gnss_hal_test_template.h index d057c617be..1439158266 100644 --- a/gnss/common/utils/vts/include/v2_1/gnss_hal_test_template.h +++ b/gnss/common/utils/vts/include/v2_1/gnss_hal_test_template.h @@ -119,7 +119,7 @@ class GnssHalTestTemplate : public testing::TestWithParam { * SetUpGnssCallback: * Set GnssCallback and verify the result. */ - void SetUpGnssCallback(); + virtual void SetUpGnssCallback(); /* * StartAndCheckFirstLocation: -- GitLab From 8d8dfcd8ed79fe97ca40861ffeb0f9294d8384be Mon Sep 17 00:00:00 2001 From: Mikhail Naganov Date: Wed, 30 Sep 2020 20:27:12 +0000 Subject: [PATCH 218/790] audio: Align lists of enum values between framework and HAL Enum values defined in the XSD now correspond to the "no system definitions" lists of enums in system/media/audio/audio-hal-enums.h. Added channel masks that used to be in s/m/a/audio-base-utils.h. Removed use of "vectors of vectors" for channel masks since individual channels are not allowed to be used in the APM config and at the HAL transport level. Fixed definition of the gain mode of audio ports: 1. Since it's a bit mask in the framework, it must be a list in the audio policy configuration XML file. Note that the old definition is compatible with the new one as one element is a valid list. 2. As gain mode is defined in the XSD file, it shouldn't be defined again in types.hal. Added 'AUDIO_SOURCE_HOTWORD'. Bug: 122858783 Bug: 142480271 Test: audio smoke tests Change-Id: Ie5896775b6bc7dfd3ab158c4a7b497dbda827e9d --- audio/7.0/config/api/current.txt | 32 ++++++---- .../7.0/config/audio_policy_configuration.xsd | 61 ++++++++++++------- .../audio_policy_configuration_V7_0-enums.h | 8 +++ audio/common/7.0/types.hal | 28 ++++----- .../vts/functional/AudioPrimaryHidlHalTest.h | 2 +- 5 files changed, 80 insertions(+), 51 deletions(-) diff --git a/audio/7.0/config/api/current.txt b/audio/7.0/config/api/current.txt index ac8dc8ae0c..8c376ef238 100644 --- a/audio/7.0/config/api/current.txt +++ b/audio/7.0/config/api/current.txt @@ -44,10 +44,12 @@ package audio.policy.configuration.V7_0 { enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_IN_VOICE_CALL_MONO; enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_IN_VOICE_DNLINK_MONO; enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_IN_VOICE_UPLINK_MONO; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_NONE; enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_2POINT0POINT2; enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_2POINT1; enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_2POINT1POINT2; enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_3POINT0POINT2; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_3POINT1; enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_3POINT1POINT2; enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_5POINT1; enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_5POINT1POINT2; @@ -70,6 +72,8 @@ package audio.policy.configuration.V7_0 { enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_STEREO_HAPTIC_A; enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_STEREO_HAPTIC_AB; enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_SURROUND; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_TRI; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_TRI_BACK; } public enum AudioContentType { @@ -87,6 +91,7 @@ package audio.policy.configuration.V7_0 { enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET; enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_AUX_DIGITAL; enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_BACK_MIC; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_BLE_HEADSET; enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_BLUETOOTH_A2DP; enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_BLUETOOTH_BLE; enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET; @@ -117,6 +122,8 @@ package audio.policy.configuration.V7_0 { enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET; enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_AUX_DIGITAL; enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_AUX_LINE; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_BLE_HEADSET; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_BLE_SPEAKER; enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_A2DP; enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; @@ -191,7 +198,6 @@ package audio.policy.configuration.V7_0 { enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_APTX_HD; enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_APTX_TWSP; enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_CELT; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DEFAULT; enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DOLBY_TRUEHD; enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DSD; enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DTS; @@ -206,9 +212,11 @@ package audio.policy.configuration.V7_0 { enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_HE_AAC_V1; enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_HE_AAC_V2; enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_IEC61937; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_LC3; enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_LDAC; enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_LHDC; enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_LHDC_LL; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_MAT; enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_MAT_1_0; enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_MAT_2_0; enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_MAT_2_1; @@ -228,6 +236,13 @@ package audio.policy.configuration.V7_0 { enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_WMA_PRO; } + public enum AudioGainMode { + method public String getRawName(); + enum_constant public static final audio.policy.configuration.V7_0.AudioGainMode AUDIO_GAIN_MODE_CHANNELS; + enum_constant public static final audio.policy.configuration.V7_0.AudioGainMode AUDIO_GAIN_MODE_JOINT; + enum_constant public static final audio.policy.configuration.V7_0.AudioGainMode AUDIO_GAIN_MODE_RAMP; + } + public enum AudioInOutFlag { method public String getRawName(); enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_DIRECT; @@ -235,6 +250,7 @@ package audio.policy.configuration.V7_0 { enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_HW_AV_SYNC; enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_HW_HOTWORD; enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_MMAP_NOIRQ; + enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_NONE; enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_RAW; enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_SYNC; enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_VOIP_TX; @@ -247,6 +263,7 @@ package audio.policy.configuration.V7_0 { enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO; enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_INCALL_MUSIC; enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_MMAP_NOIRQ; + enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_NONE; enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_NON_BLOCKING; enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_PRIMARY; enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_RAW; @@ -295,8 +312,6 @@ package audio.policy.configuration.V7_0 { enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_ENFORCED_AUDIBLE; enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_MUSIC; enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_NOTIFICATION; - enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_PATCH; - enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_REROUTING; enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_RING; enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_SYSTEM; enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_TTS; @@ -364,13 +379,6 @@ package audio.policy.configuration.V7_0 { enum_constant public static final audio.policy.configuration.V7_0.EngineSuffix configurable; } - public enum GainMode { - method public String getRawName(); - enum_constant public static final audio.policy.configuration.V7_0.GainMode AUDIO_GAIN_MODE_CHANNELS; - enum_constant public static final audio.policy.configuration.V7_0.GainMode AUDIO_GAIN_MODE_JOINT; - enum_constant public static final audio.policy.configuration.V7_0.GainMode AUDIO_GAIN_MODE_RAMP; - } - public class Gains { ctor public Gains(); method public java.util.List getGain(); @@ -384,7 +392,7 @@ package audio.policy.configuration.V7_0 { method public int getMaxValueMB(); method public int getMinRampMs(); method public int getMinValueMB(); - method public audio.policy.configuration.V7_0.GainMode getMode(); + method public java.util.List getMode(); method public String getName(); method public int getStepValueMB(); method public boolean getUseForVolume(); @@ -394,7 +402,7 @@ package audio.policy.configuration.V7_0 { method public void setMaxValueMB(int); method public void setMinRampMs(int); method public void setMinValueMB(int); - method public void setMode(audio.policy.configuration.V7_0.GainMode); + method public void setMode(java.util.List); method public void setName(String); method public void setStepValueMB(int); method public void setUseForVolume(boolean); diff --git a/audio/7.0/config/audio_policy_configuration.xsd b/audio/7.0/config/audio_policy_configuration.xsd index 20fe02002e..6604bb6e02 100644 --- a/audio/7.0/config/audio_policy_configuration.xsd +++ b/audio/7.0/config/audio_policy_configuration.xsd @@ -159,9 +159,13 @@ The flags indicate suggested stream attributes supported by the profile. + Use of AUDIO_{INPUT|OUTPUT}_FLAG_NONE in the XML file isn't required + as empty flag lists are allowed. However these constants are useful for + representing an empty enum value. + @@ -177,6 +181,7 @@ + @@ -251,8 +256,8 @@ - + @@ -271,6 +276,8 @@ + + @@ -279,8 +286,8 @@ - + @@ -302,6 +309,7 @@ + @@ -321,7 +329,6 @@ - @@ -342,22 +349,14 @@ - - - - - - - - - - - + + + @@ -377,17 +376,26 @@ + + + + + + + + + + + - + - - @@ -397,6 +405,7 @@ + @@ -465,9 +474,13 @@ + + + + @@ -538,19 +551,27 @@ - + + + + + + + + + - + @@ -668,8 +689,6 @@ - - diff --git a/audio/common/7.0/enums/include/audio_policy_configuration_V7_0-enums.h b/audio/common/7.0/enums/include/audio_policy_configuration_V7_0-enums.h index d5fedce100..cedcab3cc2 100644 --- a/audio/common/7.0/enums/include/audio_policy_configuration_V7_0-enums.h +++ b/audio/common/7.0/enums/include/audio_policy_configuration_V7_0-enums.h @@ -25,6 +25,8 @@ namespace audio::policy::configuration::V7_0 { static inline size_t getChannelCount(AudioChannelMask mask) { switch (mask) { + case AudioChannelMask::AUDIO_CHANNEL_NONE: + return 0; case AudioChannelMask::AUDIO_CHANNEL_OUT_MONO: case AudioChannelMask::AUDIO_CHANNEL_IN_MONO: case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_1: @@ -42,9 +44,12 @@ static inline size_t getChannelCount(AudioChannelMask mask) { case AudioChannelMask::AUDIO_CHANNEL_OUT_2POINT1: case AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO_HAPTIC_A: case AudioChannelMask::AUDIO_CHANNEL_OUT_MONO_HAPTIC_AB: + case AudioChannelMask::AUDIO_CHANNEL_OUT_TRI: + case AudioChannelMask::AUDIO_CHANNEL_OUT_TRI_BACK: case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_3: return 3; case AudioChannelMask::AUDIO_CHANNEL_OUT_2POINT0POINT2: + case AudioChannelMask::AUDIO_CHANNEL_OUT_3POINT1: case AudioChannelMask::AUDIO_CHANNEL_OUT_QUAD: case AudioChannelMask::AUDIO_CHANNEL_OUT_QUAD_BACK: case AudioChannelMask::AUDIO_CHANNEL_OUT_QUAD_SIDE: @@ -158,6 +163,8 @@ static inline bool isOutputDevice(AudioDevice device) { case AudioDevice::AUDIO_DEVICE_OUT_USB_HEADSET: case AudioDevice::AUDIO_DEVICE_OUT_HEARING_AID: case AudioDevice::AUDIO_DEVICE_OUT_ECHO_CANCELLER: + case AudioDevice::AUDIO_DEVICE_OUT_BLE_HEADSET: + case AudioDevice::AUDIO_DEVICE_OUT_BLE_SPEAKER: case AudioDevice::AUDIO_DEVICE_OUT_DEFAULT: case AudioDevice::AUDIO_DEVICE_OUT_STUB: return true; @@ -189,6 +196,7 @@ static inline bool isOutputDevice(AudioDevice device) { case AudioDevice::AUDIO_DEVICE_IN_BLUETOOTH_BLE: case AudioDevice::AUDIO_DEVICE_IN_HDMI_ARC: case AudioDevice::AUDIO_DEVICE_IN_ECHO_REFERENCE: + case AudioDevice::AUDIO_DEVICE_IN_BLE_HEADSET: case AudioDevice::AUDIO_DEVICE_IN_DEFAULT: case AudioDevice::AUDIO_DEVICE_IN_STUB: return false; diff --git a/audio/common/7.0/types.hal b/audio/common/7.0/types.hal index 31c7388329..0d0fa7e91c 100644 --- a/audio/common/7.0/types.hal +++ b/audio/common/7.0/types.hal @@ -106,6 +106,8 @@ typedef string AudioFormat; /** * Audio channel mask indicates presence of particular channels. + * Note that every value is already a mask comprised of individual + * channels. * See 'audioChannelMask' in audio_policy_configuration.xsd for the * list of allowed values. */ @@ -127,13 +129,8 @@ struct AudioProfile { AudioFormat format; /** List of the sample rates (in Hz) supported by the profile. */ vec sampleRates; - /** - * List of channel masks supported by the profile. Every subvector might be - * comprised of several individual channel mask entries for non-traditional - * channel masks, e.g. a combination "OUT_FRONT_LEFT,OUT_FRONT_CENTER" which - * doesn't have a corresponding predefined channel mask. - */ - vec> channelMasks; + /** List of channel masks supported by the profile. */ + vec channelMasks; }; /** @@ -299,21 +296,18 @@ struct SinkMetadata { /** * Type of gain control exposed by an audio port. + * See 'audioGainMode' in audio_policy_configuration.xsd for the + * list of allowed values. */ -@export(name="", value_prefix="AUDIO_GAIN_MODE_") -enum AudioGainMode : uint32_t { - JOINT = 0x1, // supports joint channel gain control - CHANNELS = 0x2, // supports separate channel gain control - RAMP = 0x4 // supports gain ramps -}; +typedef string AudioGainMode; /** * An audio_gain struct is a representation of a gain stage. * A gain stage is always attached to an audio port. */ struct AudioGain { - bitfield mode; - vec channelMask; // channels which gain an be controlled + vec mode; // modes of operation + AudioChannelMask channelMask; // channels which gain can be controlled int32_t minValue; // minimum gain value in millibels int32_t maxValue; // maximum gain value in millibels int32_t defaultValue; // default gain value in millibels @@ -328,8 +322,8 @@ struct AudioGain { */ struct AudioGainConfig { int32_t index; // index of the corresponding AudioGain in AudioPort.gains - AudioGainMode mode; - vec channelMask; // channels which gain value follows + vec mode; // modes of operation + AudioChannelMask channelMask; // channels which gain value follows /** * Gain values in millibels for each channel ordered from LSb to MSb in * channel mask. The number of values is 1 in joint mode or diff --git a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h index 5e4b414d29..0a9d5ee166 100644 --- a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h +++ b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h @@ -1150,7 +1150,7 @@ static void testSetAudioProperties(IStream* stream) { for (const auto& channelMask : profile.channelMasks) { AudioConfigBase config{.format = profile.format, .sampleRateHz = sampleRate, - .channelMask = channelMask}; + .channelMask = {{channelMask}}}; auto ret = stream->setAudioProperties(config); EXPECT_TRUE(ret.isOk()); EXPECT_EQ(Result::OK, ret) << config.format << "; " << config.sampleRateHz << "; " -- GitLab From e04821595c9d26e51a2541223aa91ee4b0f4458f Mon Sep 17 00:00:00 2001 From: Steven Moreland Date: Fri, 16 Oct 2020 23:39:53 +0000 Subject: [PATCH 219/790] Update VNDK version for common graphics HALs. We are adding things to them, and in order for core libraries like libui to use them, the newer versions need to be in the VNDK. Bug: 170435409 Test: build Change-Id: I4094240656f357b5ae52194befd0e10627b9fe23 --- common/aidl/Android.bp | 1 + graphics/common/aidl/Android.bp | 1 + graphics/mapper/4.0/vts/functional/Android.bp | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/common/aidl/Android.bp b/common/aidl/Android.bp index 9ea4cdf5c1..0f0fa82cfc 100644 --- a/common/aidl/Android.bp +++ b/common/aidl/Android.bp @@ -6,6 +6,7 @@ aidl_interface { enabled: true, support_system_process: true, }, + vndk_use_version: "2", srcs: [ "android/hardware/common/*.aidl", ], diff --git a/graphics/common/aidl/Android.bp b/graphics/common/aidl/Android.bp index e5942339e7..22e609d758 100644 --- a/graphics/common/aidl/Android.bp +++ b/graphics/common/aidl/Android.bp @@ -6,6 +6,7 @@ aidl_interface { enabled: true, support_system_process: true, }, + vndk_use_version: "2", srcs: [ "android/hardware/graphics/common/*.aidl", ], diff --git a/graphics/mapper/4.0/vts/functional/Android.bp b/graphics/mapper/4.0/vts/functional/Android.bp index 03abc891c0..8bda42556b 100644 --- a/graphics/mapper/4.0/vts/functional/Android.bp +++ b/graphics/mapper/4.0/vts/functional/Android.bp @@ -19,7 +19,7 @@ cc_test { defaults: ["VtsHalTargetTestDefaults"], srcs: ["VtsHalGraphicsMapperV4_0TargetTest.cpp"], static_libs: [ - "android.hardware.graphics.common-ndk_platform", + "android.hardware.graphics.common-unstable-ndk_platform", "android.hardware.graphics.mapper@4.0-vts", "libgralloctypes", "libsync", -- GitLab From b0c4bd081e0f6155dc0f4a8dfd7ffd61c6f4cb97 Mon Sep 17 00:00:00 2001 From: Mikhail Naganov Date: Tue, 20 Oct 2020 01:29:53 +0000 Subject: [PATCH 220/790] Revert "audio: Align lists of enum values between framework and HAL" Revert submission 12851233-hal-enum-strings Reason for revert: breaks slider device Reverted Changes: I4f64a8b61:Use system/audio to/from string converters in Type... Iddaa92bf2:Move enums shared with HAL to audio-hal-enums.h Ie5896775b:audio: Align lists of enum values between framewor... Bug: 171262726 Change-Id: I35c1acf6ed07b533292d1264b6237766458fd711 --- audio/7.0/config/api/current.txt | 32 ++++------ .../7.0/config/audio_policy_configuration.xsd | 61 +++++++------------ .../audio_policy_configuration_V7_0-enums.h | 8 --- audio/common/7.0/types.hal | 28 +++++---- .../vts/functional/AudioPrimaryHidlHalTest.h | 2 +- 5 files changed, 51 insertions(+), 80 deletions(-) diff --git a/audio/7.0/config/api/current.txt b/audio/7.0/config/api/current.txt index 8c376ef238..ac8dc8ae0c 100644 --- a/audio/7.0/config/api/current.txt +++ b/audio/7.0/config/api/current.txt @@ -44,12 +44,10 @@ package audio.policy.configuration.V7_0 { enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_IN_VOICE_CALL_MONO; enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_IN_VOICE_DNLINK_MONO; enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_IN_VOICE_UPLINK_MONO; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_NONE; enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_2POINT0POINT2; enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_2POINT1; enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_2POINT1POINT2; enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_3POINT0POINT2; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_3POINT1; enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_3POINT1POINT2; enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_5POINT1; enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_5POINT1POINT2; @@ -72,8 +70,6 @@ package audio.policy.configuration.V7_0 { enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_STEREO_HAPTIC_A; enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_STEREO_HAPTIC_AB; enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_SURROUND; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_TRI; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_TRI_BACK; } public enum AudioContentType { @@ -91,7 +87,6 @@ package audio.policy.configuration.V7_0 { enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET; enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_AUX_DIGITAL; enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_BACK_MIC; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_BLE_HEADSET; enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_BLUETOOTH_A2DP; enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_BLUETOOTH_BLE; enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET; @@ -122,8 +117,6 @@ package audio.policy.configuration.V7_0 { enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET; enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_AUX_DIGITAL; enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_AUX_LINE; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_BLE_HEADSET; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_BLE_SPEAKER; enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_A2DP; enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; @@ -198,6 +191,7 @@ package audio.policy.configuration.V7_0 { enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_APTX_HD; enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_APTX_TWSP; enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_CELT; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DEFAULT; enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DOLBY_TRUEHD; enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DSD; enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DTS; @@ -212,11 +206,9 @@ package audio.policy.configuration.V7_0 { enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_HE_AAC_V1; enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_HE_AAC_V2; enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_IEC61937; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_LC3; enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_LDAC; enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_LHDC; enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_LHDC_LL; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_MAT; enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_MAT_1_0; enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_MAT_2_0; enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_MAT_2_1; @@ -236,13 +228,6 @@ package audio.policy.configuration.V7_0 { enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_WMA_PRO; } - public enum AudioGainMode { - method public String getRawName(); - enum_constant public static final audio.policy.configuration.V7_0.AudioGainMode AUDIO_GAIN_MODE_CHANNELS; - enum_constant public static final audio.policy.configuration.V7_0.AudioGainMode AUDIO_GAIN_MODE_JOINT; - enum_constant public static final audio.policy.configuration.V7_0.AudioGainMode AUDIO_GAIN_MODE_RAMP; - } - public enum AudioInOutFlag { method public String getRawName(); enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_DIRECT; @@ -250,7 +235,6 @@ package audio.policy.configuration.V7_0 { enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_HW_AV_SYNC; enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_HW_HOTWORD; enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_MMAP_NOIRQ; - enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_NONE; enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_RAW; enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_SYNC; enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_VOIP_TX; @@ -263,7 +247,6 @@ package audio.policy.configuration.V7_0 { enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO; enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_INCALL_MUSIC; enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_MMAP_NOIRQ; - enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_NONE; enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_NON_BLOCKING; enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_PRIMARY; enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_RAW; @@ -312,6 +295,8 @@ package audio.policy.configuration.V7_0 { enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_ENFORCED_AUDIBLE; enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_MUSIC; enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_NOTIFICATION; + enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_PATCH; + enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_REROUTING; enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_RING; enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_SYSTEM; enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_TTS; @@ -379,6 +364,13 @@ package audio.policy.configuration.V7_0 { enum_constant public static final audio.policy.configuration.V7_0.EngineSuffix configurable; } + public enum GainMode { + method public String getRawName(); + enum_constant public static final audio.policy.configuration.V7_0.GainMode AUDIO_GAIN_MODE_CHANNELS; + enum_constant public static final audio.policy.configuration.V7_0.GainMode AUDIO_GAIN_MODE_JOINT; + enum_constant public static final audio.policy.configuration.V7_0.GainMode AUDIO_GAIN_MODE_RAMP; + } + public class Gains { ctor public Gains(); method public java.util.List getGain(); @@ -392,7 +384,7 @@ package audio.policy.configuration.V7_0 { method public int getMaxValueMB(); method public int getMinRampMs(); method public int getMinValueMB(); - method public java.util.List getMode(); + method public audio.policy.configuration.V7_0.GainMode getMode(); method public String getName(); method public int getStepValueMB(); method public boolean getUseForVolume(); @@ -402,7 +394,7 @@ package audio.policy.configuration.V7_0 { method public void setMaxValueMB(int); method public void setMinRampMs(int); method public void setMinValueMB(int); - method public void setMode(java.util.List); + method public void setMode(audio.policy.configuration.V7_0.GainMode); method public void setName(String); method public void setStepValueMB(int); method public void setUseForVolume(boolean); diff --git a/audio/7.0/config/audio_policy_configuration.xsd b/audio/7.0/config/audio_policy_configuration.xsd index 6604bb6e02..20fe02002e 100644 --- a/audio/7.0/config/audio_policy_configuration.xsd +++ b/audio/7.0/config/audio_policy_configuration.xsd @@ -159,13 +159,9 @@ The flags indicate suggested stream attributes supported by the profile. - Use of AUDIO_{INPUT|OUTPUT}_FLAG_NONE in the XML file isn't required - as empty flag lists are allowed. However these constants are useful for - representing an empty enum value. - @@ -181,7 +177,6 @@ - @@ -256,8 +251,8 @@ - + @@ -276,8 +271,6 @@ - - @@ -286,8 +279,8 @@ - + @@ -309,7 +302,6 @@ - @@ -329,6 +321,7 @@ + @@ -349,14 +342,22 @@ - + + + + + + + + + + + - - @@ -376,26 +377,17 @@ - - - - - - - - - - - - + + + @@ -405,7 +397,6 @@ - @@ -474,13 +465,9 @@ - - - - @@ -551,27 +538,19 @@ - + - - - - - - - - - + @@ -689,6 +668,8 @@ + + diff --git a/audio/common/7.0/enums/include/audio_policy_configuration_V7_0-enums.h b/audio/common/7.0/enums/include/audio_policy_configuration_V7_0-enums.h index cedcab3cc2..d5fedce100 100644 --- a/audio/common/7.0/enums/include/audio_policy_configuration_V7_0-enums.h +++ b/audio/common/7.0/enums/include/audio_policy_configuration_V7_0-enums.h @@ -25,8 +25,6 @@ namespace audio::policy::configuration::V7_0 { static inline size_t getChannelCount(AudioChannelMask mask) { switch (mask) { - case AudioChannelMask::AUDIO_CHANNEL_NONE: - return 0; case AudioChannelMask::AUDIO_CHANNEL_OUT_MONO: case AudioChannelMask::AUDIO_CHANNEL_IN_MONO: case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_1: @@ -44,12 +42,9 @@ static inline size_t getChannelCount(AudioChannelMask mask) { case AudioChannelMask::AUDIO_CHANNEL_OUT_2POINT1: case AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO_HAPTIC_A: case AudioChannelMask::AUDIO_CHANNEL_OUT_MONO_HAPTIC_AB: - case AudioChannelMask::AUDIO_CHANNEL_OUT_TRI: - case AudioChannelMask::AUDIO_CHANNEL_OUT_TRI_BACK: case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_3: return 3; case AudioChannelMask::AUDIO_CHANNEL_OUT_2POINT0POINT2: - case AudioChannelMask::AUDIO_CHANNEL_OUT_3POINT1: case AudioChannelMask::AUDIO_CHANNEL_OUT_QUAD: case AudioChannelMask::AUDIO_CHANNEL_OUT_QUAD_BACK: case AudioChannelMask::AUDIO_CHANNEL_OUT_QUAD_SIDE: @@ -163,8 +158,6 @@ static inline bool isOutputDevice(AudioDevice device) { case AudioDevice::AUDIO_DEVICE_OUT_USB_HEADSET: case AudioDevice::AUDIO_DEVICE_OUT_HEARING_AID: case AudioDevice::AUDIO_DEVICE_OUT_ECHO_CANCELLER: - case AudioDevice::AUDIO_DEVICE_OUT_BLE_HEADSET: - case AudioDevice::AUDIO_DEVICE_OUT_BLE_SPEAKER: case AudioDevice::AUDIO_DEVICE_OUT_DEFAULT: case AudioDevice::AUDIO_DEVICE_OUT_STUB: return true; @@ -196,7 +189,6 @@ static inline bool isOutputDevice(AudioDevice device) { case AudioDevice::AUDIO_DEVICE_IN_BLUETOOTH_BLE: case AudioDevice::AUDIO_DEVICE_IN_HDMI_ARC: case AudioDevice::AUDIO_DEVICE_IN_ECHO_REFERENCE: - case AudioDevice::AUDIO_DEVICE_IN_BLE_HEADSET: case AudioDevice::AUDIO_DEVICE_IN_DEFAULT: case AudioDevice::AUDIO_DEVICE_IN_STUB: return false; diff --git a/audio/common/7.0/types.hal b/audio/common/7.0/types.hal index 0d0fa7e91c..31c7388329 100644 --- a/audio/common/7.0/types.hal +++ b/audio/common/7.0/types.hal @@ -106,8 +106,6 @@ typedef string AudioFormat; /** * Audio channel mask indicates presence of particular channels. - * Note that every value is already a mask comprised of individual - * channels. * See 'audioChannelMask' in audio_policy_configuration.xsd for the * list of allowed values. */ @@ -129,8 +127,13 @@ struct AudioProfile { AudioFormat format; /** List of the sample rates (in Hz) supported by the profile. */ vec sampleRates; - /** List of channel masks supported by the profile. */ - vec channelMasks; + /** + * List of channel masks supported by the profile. Every subvector might be + * comprised of several individual channel mask entries for non-traditional + * channel masks, e.g. a combination "OUT_FRONT_LEFT,OUT_FRONT_CENTER" which + * doesn't have a corresponding predefined channel mask. + */ + vec> channelMasks; }; /** @@ -296,18 +299,21 @@ struct SinkMetadata { /** * Type of gain control exposed by an audio port. - * See 'audioGainMode' in audio_policy_configuration.xsd for the - * list of allowed values. */ -typedef string AudioGainMode; +@export(name="", value_prefix="AUDIO_GAIN_MODE_") +enum AudioGainMode : uint32_t { + JOINT = 0x1, // supports joint channel gain control + CHANNELS = 0x2, // supports separate channel gain control + RAMP = 0x4 // supports gain ramps +}; /** * An audio_gain struct is a representation of a gain stage. * A gain stage is always attached to an audio port. */ struct AudioGain { - vec mode; // modes of operation - AudioChannelMask channelMask; // channels which gain can be controlled + bitfield mode; + vec channelMask; // channels which gain an be controlled int32_t minValue; // minimum gain value in millibels int32_t maxValue; // maximum gain value in millibels int32_t defaultValue; // default gain value in millibels @@ -322,8 +328,8 @@ struct AudioGain { */ struct AudioGainConfig { int32_t index; // index of the corresponding AudioGain in AudioPort.gains - vec mode; // modes of operation - AudioChannelMask channelMask; // channels which gain value follows + AudioGainMode mode; + vec channelMask; // channels which gain value follows /** * Gain values in millibels for each channel ordered from LSb to MSb in * channel mask. The number of values is 1 in joint mode or diff --git a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h index 0a9d5ee166..5e4b414d29 100644 --- a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h +++ b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h @@ -1150,7 +1150,7 @@ static void testSetAudioProperties(IStream* stream) { for (const auto& channelMask : profile.channelMasks) { AudioConfigBase config{.format = profile.format, .sampleRateHz = sampleRate, - .channelMask = {{channelMask}}}; + .channelMask = channelMask}; auto ret = stream->setAudioProperties(config); EXPECT_TRUE(ret.isOk()); EXPECT_EQ(Result::OK, ret) << config.format << "; " << config.sampleRateHz << "; " -- GitLab From 44006eea19de43c383a19b94ca17b27b8a95eda4 Mon Sep 17 00:00:00 2001 From: Hui Wang Date: Mon, 19 Oct 2020 09:58:51 -0700 Subject: [PATCH 221/790] Add SUCCESS to the response of SAP VTS test cases Bug: 169106223 Test: atest VtsHalSapV1_0TargetTest Change-Id: I7392c07914ab693f8d43d059263d950dd0116897 --- radio/1.0/vts/functional/sap_hidl_hal_api.cpp | 41 +++++++++++-------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/radio/1.0/vts/functional/sap_hidl_hal_api.cpp b/radio/1.0/vts/functional/sap_hidl_hal_api.cpp index 6c7870d399..5359a87bad 100644 --- a/radio/1.0/vts/functional/sap_hidl_hal_api.cpp +++ b/radio/1.0/vts/functional/sap_hidl_hal_api.cpp @@ -61,10 +61,11 @@ TEST_P(SapHidlTest, apduReq) { EXPECT_EQ(std::cv_status::no_timeout, wait()); EXPECT_EQ(sapCb->sapResponseToken, token); - ASSERT_TRUE( - CheckAnyOfErrors(sapCb->sapResultCode, - {SapResultCode::GENERIC_FAILURE, SapResultCode::CARD_ALREADY_POWERED_OFF, - SapResultCode::CARD_NOT_ACCESSSIBLE, SapResultCode::CARD_REMOVED})); + ASSERT_TRUE(CheckAnyOfErrors( + sapCb->sapResultCode, + {SapResultCode::GENERIC_FAILURE, SapResultCode::CARD_ALREADY_POWERED_OFF, + SapResultCode::CARD_NOT_ACCESSSIBLE, SapResultCode::CARD_REMOVED, + SapResultCode::SUCCESS})); LOG(DEBUG) << "apduReq finished"; } @@ -79,10 +80,10 @@ TEST_P(SapHidlTest, transferAtrReq) { EXPECT_EQ(std::cv_status::no_timeout, wait()); EXPECT_EQ(sapCb->sapResponseToken, token); - ASSERT_TRUE( - CheckAnyOfErrors(sapCb->sapResultCode, - {SapResultCode::GENERIC_FAILURE, SapResultCode::DATA_NOT_AVAILABLE, - SapResultCode::CARD_ALREADY_POWERED_OFF, SapResultCode::CARD_REMOVED})); + ASSERT_TRUE(CheckAnyOfErrors(sapCb->sapResultCode, + {SapResultCode::GENERIC_FAILURE, SapResultCode::DATA_NOT_AVAILABLE, + SapResultCode::CARD_ALREADY_POWERED_OFF, + SapResultCode::CARD_REMOVED, SapResultCode::SUCCESS})); LOG(DEBUG) << "transferAtrReq finished"; } @@ -98,10 +99,11 @@ TEST_P(SapHidlTest, powerReq) { EXPECT_EQ(std::cv_status::no_timeout, wait()); EXPECT_EQ(sapCb->sapResponseToken, token); - ASSERT_TRUE(CheckAnyOfErrors( - sapCb->sapResultCode, {SapResultCode::GENERIC_FAILURE, SapResultCode::CARD_NOT_ACCESSSIBLE, - SapResultCode::CARD_ALREADY_POWERED_OFF, SapResultCode::CARD_REMOVED, - SapResultCode::CARD_ALREADY_POWERED_ON})); + ASSERT_TRUE( + CheckAnyOfErrors(sapCb->sapResultCode, + {SapResultCode::GENERIC_FAILURE, SapResultCode::CARD_NOT_ACCESSSIBLE, + SapResultCode::CARD_ALREADY_POWERED_OFF, SapResultCode::CARD_REMOVED, + SapResultCode::CARD_ALREADY_POWERED_ON, SapResultCode::SUCCESS})); LOG(DEBUG) << "powerReq finished"; } @@ -117,9 +119,10 @@ TEST_P(SapHidlTest, resetSimReq) { EXPECT_EQ(sapCb->sapResponseToken, token); ASSERT_TRUE( - CheckAnyOfErrors(sapCb->sapResultCode, - {SapResultCode::GENERIC_FAILURE, SapResultCode::CARD_NOT_ACCESSSIBLE, - SapResultCode::CARD_ALREADY_POWERED_OFF, SapResultCode::CARD_REMOVED})); + CheckAnyOfErrors(sapCb->sapResultCode, + {SapResultCode::GENERIC_FAILURE, SapResultCode::CARD_NOT_ACCESSSIBLE, + SapResultCode::CARD_ALREADY_POWERED_OFF, SapResultCode::CARD_REMOVED, + SapResultCode::SUCCESS})); LOG(DEBUG) << "resetSimReq finished"; } @@ -134,8 +137,9 @@ TEST_P(SapHidlTest, transferCardReaderStatusReq) { EXPECT_EQ(std::cv_status::no_timeout, wait()); EXPECT_EQ(sapCb->sapResponseToken, token); - ASSERT_TRUE(CheckAnyOfErrors( - sapCb->sapResultCode, {SapResultCode::GENERIC_FAILURE, SapResultCode::DATA_NOT_AVAILABLE})); + ASSERT_TRUE(CheckAnyOfErrors(sapCb->sapResultCode, + {SapResultCode::GENERIC_FAILURE, SapResultCode::DATA_NOT_AVAILABLE, + SapResultCode::SUCCESS})); LOG(DEBUG) << "transferCardReaderStatusReq finished"; } @@ -151,6 +155,7 @@ TEST_P(SapHidlTest, setTransferProtocolReq) { EXPECT_EQ(std::cv_status::no_timeout, wait()); EXPECT_EQ(sapCb->sapResponseToken, token); - EXPECT_EQ(SapResultCode::NOT_SUPPORTED, sapCb->sapResultCode); + ASSERT_TRUE(CheckAnyOfErrors(sapCb->sapResultCode, + {SapResultCode::NOT_SUPPORTED, SapResultCode::SUCCESS})); LOG(DEBUG) << "setTransferProtocolReq finished"; } -- GitLab From 1ea0c17ea4e69770e92bd33a61fe988e9d72c543 Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Fri, 16 Oct 2020 12:55:22 -0700 Subject: [PATCH 222/790] Extend DemuxScIndex in Tuner 1.1 Test: make Bug: 158816517 Change-Id: I0fffd428e18b36b5c4d421d89743de330c854425 --- tv/tuner/1.1/types.hal | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/tv/tuner/1.1/types.hal b/tv/tuner/1.1/types.hal index 1ed64037e1..36f804ea0c 100644 --- a/tv/tuner/1.1/types.hal +++ b/tv/tuner/1.1/types.hal @@ -19,6 +19,7 @@ package android.hardware.tv.tuner@1.1; import @1.0::Constant; import @1.0::DemuxFilterMmtpRecordEvent; import @1.0::DemuxFilterTsRecordEvent; +import @1.0::DemuxScIndex; import @1.0::FrontendAtsc3Bandwidth; import @1.0::FrontendAtsc3Modulation; import @1.0::FrontendAtsc3TimeInterleaveMode; @@ -695,3 +696,30 @@ safe_union AvStreamType { AudioStreamType audio; }; + +/** + * Indexes can be tagged by start point of slice groups according to ISO/IEC 14496-10. + */ +@export +enum DemuxScIndex : @1.0::DemuxScIndex { + /** + * All blocks are coded as I blocks. + */ + I_SLICE = 1 << 4, + /** + * Blocks are coded as I or P blocks. + */ + P_SLICE = 1 << 5, + /** + * Blocks are coded as I, P or B blocks. + */ + B_SLICE = 1 << 6, + /** + * A so-called switching I slice that is coded. + */ + SI_SLICE = 1 << 7, + /** + * A so-called switching P slice that is coded. + */ + SP_SLICE = 1 << 8, +}; -- GitLab From 4a6663fd326260a47671e0837d565363077b0052 Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Mon, 19 Oct 2020 16:13:35 -0700 Subject: [PATCH 223/790] Add the address of the first macroblock as an extended field in Tuner 1.1 Record event Test: atest VtsHalTvTunerV1_1TargetTest Bug: 158816517 Change-Id: I46b77210d5b97325f770bbb4095897f431aa0ee6 --- tv/tuner/1.1/default/Filter.cpp | 12 +++++++----- tv/tuner/1.1/types.hal | 13 +++++++++++-- tv/tuner/1.1/vts/functional/DvrTests.cpp | 5 +++-- tv/tuner/1.1/vts/functional/FilterTests.cpp | 10 ++++++++-- .../vts/functional/VtsHalTvTunerV1_1TargetTest.cpp | 5 +++++ .../vts/functional/VtsHalTvTunerV1_1TargetTest.h | 1 + 6 files changed, 35 insertions(+), 11 deletions(-) diff --git a/tv/tuner/1.1/default/Filter.cpp b/tv/tuner/1.1/default/Filter.cpp index 11e323c54c..54d515b570 100644 --- a/tv/tuner/1.1/default/Filter.cpp +++ b/tv/tuner/1.1/default/Filter.cpp @@ -340,17 +340,17 @@ void Filter::filterThreadLoop() { while (mFilterThreadRunning) { std::lock_guard lock(mFilterEventLock); - if (mFilterEvent.events.size() == 0) { + if (mFilterEvent.events.size() == 0 && mFilterEventExt.events.size() == 0) { continue; } // After successfully write, send a callback and wait for the read to be done - if (mCallback != nullptr) { - mCallback->onFilterEvent(mFilterEvent); - mFilterEvent.events.resize(0); - } else if (mCallback_1_1 != nullptr) { + if (mCallback_1_1 != nullptr) { mCallback_1_1->onFilterEvent_1_1(mFilterEvent, mFilterEventExt); mFilterEventExt.events.resize(0); + } else if (mCallback != nullptr) { + mCallback->onFilterEvent(mFilterEvent); } + mFilterEvent.events.resize(0); break; } // We do not wait for the last read to be done @@ -659,6 +659,8 @@ Result Filter::startRecordFilterHandler() { V1_1::DemuxFilterRecordEventExt recordEventExt; recordEventExt = { .pts = (mPts == 0) ? time(NULL) * 900000 : mPts, + .firstMbInSlice = 0, // random address + .mpuSequenceNumber = 1, // random sequence number }; int size; diff --git a/tv/tuner/1.1/types.hal b/tv/tuner/1.1/types.hal index 36f804ea0c..a53685eb15 100644 --- a/tv/tuner/1.1/types.hal +++ b/tv/tuner/1.1/types.hal @@ -47,9 +47,13 @@ import android.hidl.safe_union@1.0::Monostate; @export enum Constant : @1.0::Constant { /** - * An invalid mpuSequenceNumber in DemuxFilterMmtpRecordEvent. + * An invalid mpuSequenceNumber in DemuxFilterRecordEventExt. */ INVALID_MMTP_RECORD_EVENT_MPT_SEQUENCE_NUM = 0xFFFFFFFF, + /** + * An invalid first macroblock address in DemuxFilterRecordEventExt. + */ + INVALID_FIRST_MACROBLOCK_IN_SLICE = 0xFFFFFFFF, /** * An invalid frenquency that can be used as the default value of the frontend setting. */ @@ -77,7 +81,7 @@ enum Constant64Bit : uint64_t { */ INVALID_AV_SYNC_ID_64BIT = 0xFFFFFFFFFFFFFFFF, /** - * An invalid pts in the DemuxFilterTsRecordEvent or DemuxFilterMmtpRecordEvent. + * An invalid pts. */ INVALID_PRESENTATION_TIME_STAMP = 0xFFFFFFFFFFFFFFFF, }; @@ -96,6 +100,11 @@ struct DemuxFilterRecordEventExt { * MPU sequence number of the filtered data. This is only used for MMTP. */ uint32_t mpuSequenceNumber; + + /** + * Specifies the address of the first macroblock in the slice defined in ITU-T Rec. H.264. + */ + uint32_t firstMbInSlice; }; /** diff --git a/tv/tuner/1.1/vts/functional/DvrTests.cpp b/tv/tuner/1.1/vts/functional/DvrTests.cpp index 0dfc032d19..1e478f56dc 100644 --- a/tv/tuner/1.1/vts/functional/DvrTests.cpp +++ b/tv/tuner/1.1/vts/functional/DvrTests.cpp @@ -192,9 +192,10 @@ void DvrCallback::recordThreadLoop(RecordSettings* /*recordSettings*/, bool* kee bool DvrCallback::readRecordFMQ() { android::Mutex::Autolock autoLock(mMsgLock); bool result = false; + int readSize = mRecordMQ->availableToRead(); mDataOutputBuffer.clear(); - mDataOutputBuffer.resize(mRecordMQ->availableToRead()); - result = mRecordMQ->read(mDataOutputBuffer.data(), mRecordMQ->availableToRead()); + mDataOutputBuffer.resize(readSize); + result = mRecordMQ->read(mDataOutputBuffer.data(), readSize); EXPECT_TRUE(result) << "can't read from Record MQ"; mMsgCondition.signal(); return result; diff --git a/tv/tuner/1.1/vts/functional/FilterTests.cpp b/tv/tuner/1.1/vts/functional/FilterTests.cpp index e661735808..f4ac8bf4b2 100644 --- a/tv/tuner/1.1/vts/functional/FilterTests.cpp +++ b/tv/tuner/1.1/vts/functional/FilterTests.cpp @@ -47,8 +47,14 @@ void FilterCallback::readFilterEventData() { auto eventExt = mFilterEventExt.events[i]; switch (eventExt.getDiscriminator()) { case DemuxFilterEventExt::Event::hidl_discriminator::tsRecord: - ALOGD("[vts] Extended TS record filter event, pts=%" PRIu64 ".", - eventExt.tsRecord().pts); + ALOGD("[vts] Extended TS record filter event, pts=%" PRIu64 ", firstMbInSlice=%d", + eventExt.tsRecord().pts, eventExt.tsRecord().firstMbInSlice); + break; + case DemuxFilterEventExt::Event::hidl_discriminator::mmtpRecord: + ALOGD("[vts] Extended MMTP record filter event, pts=%" PRIu64 + ", firstMbInSlice=%d, mpuSequenceNumber=%d", + eventExt.mmtpRecord().pts, eventExt.mmtpRecord().firstMbInSlice, + eventExt.mmtpRecord().mpuSequenceNumber); break; default: break; diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp index db2ac1bda1..218592047f 100644 --- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp @@ -22,6 +22,10 @@ AssertionResult TunerBroadcastHidlTest::filterDataOutputTest() { return filterDataOutputTestBase(mFilterTests); } +AssertionResult TunerRecordHidlTest::filterDataOutputTest() { + return filterDataOutputTestBase(mFilterTests); +} + void TunerFilterHidlTest::configSingleFilterInDemuxTest(FilterConfig filterConf, FrontendConfig frontendConf) { uint32_t feId; @@ -115,6 +119,7 @@ void TunerRecordHidlTest::recordSingleFilterTest(FilterConfig filterConf, ASSERT_TRUE(mFilterTests.startFilter(filterId)); ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/)); mDvrTests.testRecordOutput(); + ASSERT_TRUE(filterDataOutputTest()); mDvrTests.stopRecordThread(); ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/)); ASSERT_TRUE(mFilterTests.stopFilter(filterId)); diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h index f77a740136..773224e882 100644 --- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h @@ -87,6 +87,7 @@ class TunerRecordHidlTest : public testing::TestWithParam { void recordSingleFilterTest(FilterConfig filterConf, FrontendConfig frontendConf, DvrConfig dvrConf); + AssertionResult filterDataOutputTest(); sp mService; FrontendTests mFrontendTests; -- GitLab From 2576dcc52563c941932519f7e5f14df0d8057324 Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Mon, 19 Oct 2020 15:49:33 -0700 Subject: [PATCH 224/790] Add Dvbc Frontend Bandwidth settings in Tuner 1.1 Test: make -j44 dist Bug: 169868608 Change-Id: Ief4d795a1671d77722d554f6af6536eaa1f8013d --- tv/tuner/1.1/types.hal | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tv/tuner/1.1/types.hal b/tv/tuner/1.1/types.hal index a53685eb15..6e3ddfac3d 100644 --- a/tv/tuner/1.1/types.hal +++ b/tv/tuner/1.1/types.hal @@ -222,6 +222,8 @@ struct FrontendAnalogSettingsExt1_1 { */ struct FrontendDvbcSettingsExt1_1 { FrontendCableTimeInterleaveMode interleaveMode; + + FrontendDvbcBandwidth bandwidth; }; /** @@ -258,6 +260,18 @@ enum FrontendType : @1.0::FrontendType { DTMB, }; +/** + * Bandwidth Type for Cable Frontend. + */ +@export +enum FrontendDvbcBandwidth : uint32_t { + UNDEFINED = 0, + BANDWIDTH_5MHZ = 1 << 0, + BANDWIDTH_6MHZ = 1 << 1, + BANDWIDTH_7MHZ = 1 << 2, + BANDWIDTH_8MHZ = 1 << 3, +}; + /** * Bandwidth Type for DTMB. */ @@ -438,6 +452,8 @@ enum FrontendInnerFec : @1.0::FrontendInnerFec { safe_union FrontendBandwidth { @1.0::FrontendAtsc3Bandwidth atsc3; + FrontendDvbcBandwidth dvbc; + @1.0::FrontendDvbtBandwidth dvbt; @1.0::FrontendIsdbtBandwidth isdbt; -- GitLab From de2610f075e954f5d2ebc040a7c2e21d90dcc199 Mon Sep 17 00:00:00 2001 From: Kevin Chyn Date: Tue, 20 Oct 2020 18:26:50 -0700 Subject: [PATCH 225/790] Add default implementation for several methods Test: atest FingerprintServiceTest Bug: 170518383 Change-Id: If724d26e85967a4b3ec07c22c706efca5cfc3f86 --- biometrics/fingerprint/aidl/default/Session.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/biometrics/fingerprint/aidl/default/Session.cpp b/biometrics/fingerprint/aidl/default/Session.cpp index 372066d2d7..96f1e561b0 100644 --- a/biometrics/fingerprint/aidl/default/Session.cpp +++ b/biometrics/fingerprint/aidl/default/Session.cpp @@ -55,15 +55,27 @@ ndk::ScopedAStatus Session::detectInteraction( } ndk::ScopedAStatus Session::enumerateEnrollments(int32_t /*cookie*/) { + if (cb_) { + cb_->onStateChanged(0, SessionState::ENUMERATING_ENROLLMENTS); + cb_->onEnrollmentsEnumerated(std::vector()); + } return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus Session::removeEnrollments(int32_t /*cookie*/, const std::vector& /*enrollmentIds*/) { + if (cb_) { + cb_->onStateChanged(0, SessionState::REMOVING_ENROLLMENTS); + cb_->onEnrollmentsRemoved(std::vector()); + } return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus Session::getAuthenticatorId(int32_t /*cookie*/) { + if (cb_) { + cb_->onStateChanged(0, SessionState::GETTING_AUTHENTICATOR_ID); + cb_->onAuthenticatorIdRetrieved(0 /* authenticatorId */); + } return ndk::ScopedAStatus::ok(); } -- GitLab From 5383a1bead548e875532d9fa8c7048309a042e62 Mon Sep 17 00:00:00 2001 From: Yu-Han Yang Date: Wed, 21 Oct 2020 10:45:45 -0700 Subject: [PATCH 226/790] Fix build breakage in crosshatch_hwasan-userdebug target Test: the target builds Bug: 171400704 Change-Id: I36d7a89f40f7ee08fc38a8c441a7e9d7233b899f --- gnss/aidl/vts/Android.bp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gnss/aidl/vts/Android.bp b/gnss/aidl/vts/Android.bp index 7f3e5ef339..48a0e21f24 100644 --- a/gnss/aidl/vts/Android.bp +++ b/gnss/aidl/vts/Android.bp @@ -26,6 +26,9 @@ cc_test { ], shared_libs: [ "android.hardware.gnss@2.1", + "android.hardware.gnss@2.0", + "android.hardware.gnss@1.1", + "android.hardware.gnss@1.0", "libbinder", ], static_libs: [ -- GitLab From 8513ef2cc434eb8218d7a10bc5104dc299683782 Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Wed, 21 Oct 2020 16:42:38 -0700 Subject: [PATCH 227/790] Enable the Java backend for IFace Bug: 171335732 Test: m android.hardware.biometrics.face-update-api Change-Id: I4c295513217641c3e494a1b2d83f69aeab4c804e --- biometrics/face/aidl/Android.bp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/biometrics/face/aidl/Android.bp b/biometrics/face/aidl/Android.bp index 4f8b71ddbb..a4fcbfe54b 100644 --- a/biometrics/face/aidl/Android.bp +++ b/biometrics/face/aidl/Android.bp @@ -12,8 +12,7 @@ aidl_interface { stability: "vintf", backend: { java: { - enabled: false, - platform_apis: false, + platform_apis: true, }, cpp: { enabled: false, -- GitLab From 7e669ce5771e8a5af1278779048d4baea17f83ce Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Tue, 20 Oct 2020 16:41:30 -0700 Subject: [PATCH 228/790] Add new Frontend Status Types and a new scan msg in Tuner HAL 1.1 Test: atest VtsHalTvTunerV1_1TargetTest Bug: 169868608 Change-Id: I04b108bab20e6a1969998bb954e48c2f1c5e0772 --- tv/tuner/1.1/default/Frontend.cpp | 24 +++++++++ tv/tuner/1.1/types.hal | 49 ++++++++++++++++++- tv/tuner/1.1/vts/functional/FrontendTests.cpp | 19 +++++++ .../VtsHalTvTunerV1_1TestConfigurations.h | 6 ++- 4 files changed, 96 insertions(+), 2 deletions(-) diff --git a/tv/tuner/1.1/default/Frontend.cpp b/tv/tuner/1.1/default/Frontend.cpp index 069456dde5..6956f30634 100644 --- a/tv/tuner/1.1/default/Frontend.cpp +++ b/tv/tuner/1.1/default/Frontend.cpp @@ -302,6 +302,12 @@ Return Frontend::getStatusExt1_1(const hidl_vec Frontend::getStatusExt1_1(const hidl_vec tsDataRate; + /** + * Roll Off Type status of the frontend. + */ + FrontendRollOff rollOff; + /** + * If the frontend currently supports MISO or not. + */ + bool isMiso; + /** + * If the frontend code rate is linear or not. + */ + bool isLinear; + /** + * If short frames is enabled or not. + */ + bool isShortFrames; }; enum FrontendScanMessageTypeExt1_1 : uint32_t { MODULATION = @1.0::FrontendScanMessageType:ATSC3_PLP_INFO + 1, + DVBC_ANNEX, HIGH_PRIORITY, }; safe_union FrontendScanMessageExt1_1 { FrontendModulation modulation; + @1.0::FrontendDvbcAnnex annex; + bool isHighPriority; }; diff --git a/tv/tuner/1.1/vts/functional/FrontendTests.cpp b/tv/tuner/1.1/vts/functional/FrontendTests.cpp index e5793c1f34..0948f743ad 100644 --- a/tv/tuner/1.1/vts/functional/FrontendTests.cpp +++ b/tv/tuner/1.1/vts/functional/FrontendTests.cpp @@ -58,6 +58,9 @@ Return FrontendCallback::onScanMessageExt1_1(FrontendScanMessageTypeExt1_1 case FrontendScanMessageExt1_1::hidl_discriminator::isHighPriority: ALOGD("[vts] frontend ext1_1 scan message high priority: %d", message.isHighPriority()); break; + case FrontendScanMessageExt1_1::hidl_discriminator::annex: + ALOGD("[vts] frontend ext1_1 scan message dvbc annex: %hhu", message.annex()); + break; default: break; } @@ -374,6 +377,22 @@ void FrontendTests::verifyFrontendStatusExt1_1(vector expectStatuses[i].tsDataRate().begin())); break; } + case FrontendStatusTypeExt1_1::ROLL_OFF: { + // TODO: verify roll off + break; + } + case FrontendStatusTypeExt1_1::IS_MISO: { + ASSERT_TRUE(realStatuses[i].isMiso() == expectStatuses[i].isMiso()); + break; + } + case FrontendStatusTypeExt1_1::IS_LINEAR: { + ASSERT_TRUE(realStatuses[i].isLinear() == expectStatuses[i].isLinear()); + break; + } + case FrontendStatusTypeExt1_1::IS_SHORT_FRAMES: { + ASSERT_TRUE(realStatuses[i].isShortFrames() == expectStatuses[i].isShortFrames()); + break; + } default: { continue; } diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h index cb86ce8546..911d984cce 100644 --- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h @@ -138,10 +138,14 @@ inline void initFrontendConfig() { frontendArray[DVBT].type = FrontendType::DVBT, frontendArray[DVBT].settings.dvbt(dvbtSettings); vector types; types.push_back(FrontendStatusTypeExt1_1::UEC); + types.push_back(FrontendStatusTypeExt1_1::IS_MISO); + vector statuses; FrontendStatusExt1_1 status; status.uec(4); - vector statuses; statuses.push_back(status); + status.isMiso(true); + statuses.push_back(status); + frontendArray[DVBT].tuneStatusTypes = types; frontendArray[DVBT].expectTuneStatuses = statuses; frontendArray[DVBT].isSoftwareFe = true; -- GitLab From bbbec8229f257f6fefb50f2cc22fe38457700cbd Mon Sep 17 00:00:00 2001 From: Mikhail Naganov Date: Wed, 30 Sep 2020 20:27:12 +0000 Subject: [PATCH 229/790] audio: Align lists of enum values between framework and HAL Enum values defined in the XSD now correspond to the "no system definitions" lists of enums in system/media/audio/audio-hal-enums.h. Added channel masks that used to be in s/m/a/audio-base-utils.h. Removed use of "vectors of vectors" for channel masks since individual channels are not allowed to be used in the APM config and at the HAL transport level. Fixed definition of the gain mode of audio ports: 1. Since it's a bit mask in the framework, it must be a list in the audio policy configuration XML file. Note that the old definition is compatible with the new one as one element is a valid list. 2. As gain mode is defined in the XSD file, it shouldn't be defined again in types.hal. Bug: 122858783 Bug: 142480271 Test: audio smoke tests Change-Id: I2df5eb4bc4a393611d3adb0ee30583767197591b --- audio/7.0/config/api/current.txt | 31 ++++++---- .../7.0/config/audio_policy_configuration.xsd | 60 +++++++++++++------ .../audio_policy_configuration_V7_0-enums.h | 8 +++ audio/common/7.0/types.hal | 28 ++++----- .../vts/functional/AudioPrimaryHidlHalTest.h | 2 +- 5 files changed, 82 insertions(+), 47 deletions(-) diff --git a/audio/7.0/config/api/current.txt b/audio/7.0/config/api/current.txt index ac8dc8ae0c..453ed16d4f 100644 --- a/audio/7.0/config/api/current.txt +++ b/audio/7.0/config/api/current.txt @@ -44,10 +44,12 @@ package audio.policy.configuration.V7_0 { enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_IN_VOICE_CALL_MONO; enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_IN_VOICE_DNLINK_MONO; enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_IN_VOICE_UPLINK_MONO; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_NONE; enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_2POINT0POINT2; enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_2POINT1; enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_2POINT1POINT2; enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_3POINT0POINT2; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_3POINT1; enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_3POINT1POINT2; enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_5POINT1; enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_5POINT1POINT2; @@ -70,6 +72,8 @@ package audio.policy.configuration.V7_0 { enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_STEREO_HAPTIC_A; enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_STEREO_HAPTIC_AB; enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_SURROUND; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_TRI; + enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_TRI_BACK; } public enum AudioContentType { @@ -87,6 +91,7 @@ package audio.policy.configuration.V7_0 { enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET; enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_AUX_DIGITAL; enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_BACK_MIC; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_BLE_HEADSET; enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_BLUETOOTH_A2DP; enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_BLUETOOTH_BLE; enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET; @@ -117,6 +122,8 @@ package audio.policy.configuration.V7_0 { enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET; enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_AUX_DIGITAL; enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_AUX_LINE; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_BLE_HEADSET; + enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_BLE_SPEAKER; enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_A2DP; enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; @@ -191,7 +198,6 @@ package audio.policy.configuration.V7_0 { enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_APTX_HD; enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_APTX_TWSP; enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_CELT; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DEFAULT; enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DOLBY_TRUEHD; enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DSD; enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DTS; @@ -206,9 +212,11 @@ package audio.policy.configuration.V7_0 { enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_HE_AAC_V1; enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_HE_AAC_V2; enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_IEC61937; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_LC3; enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_LDAC; enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_LHDC; enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_LHDC_LL; + enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_MAT; enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_MAT_1_0; enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_MAT_2_0; enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_MAT_2_1; @@ -228,6 +236,13 @@ package audio.policy.configuration.V7_0 { enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_WMA_PRO; } + public enum AudioGainMode { + method public String getRawName(); + enum_constant public static final audio.policy.configuration.V7_0.AudioGainMode AUDIO_GAIN_MODE_CHANNELS; + enum_constant public static final audio.policy.configuration.V7_0.AudioGainMode AUDIO_GAIN_MODE_JOINT; + enum_constant public static final audio.policy.configuration.V7_0.AudioGainMode AUDIO_GAIN_MODE_RAMP; + } + public enum AudioInOutFlag { method public String getRawName(); enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_DIRECT; @@ -235,6 +250,7 @@ package audio.policy.configuration.V7_0 { enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_HW_AV_SYNC; enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_HW_HOTWORD; enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_MMAP_NOIRQ; + enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_NONE; enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_RAW; enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_SYNC; enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_VOIP_TX; @@ -247,6 +263,7 @@ package audio.policy.configuration.V7_0 { enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO; enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_INCALL_MUSIC; enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_MMAP_NOIRQ; + enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_NONE; enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_NON_BLOCKING; enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_PRIMARY; enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_RAW; @@ -291,6 +308,7 @@ package audio.policy.configuration.V7_0 { enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_ALARM; enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_ASSISTANT; enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_BLUETOOTH_SCO; + enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_CALL_ASSISTANT; enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_DTMF; enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_ENFORCED_AUDIBLE; enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_MUSIC; @@ -364,13 +382,6 @@ package audio.policy.configuration.V7_0 { enum_constant public static final audio.policy.configuration.V7_0.EngineSuffix configurable; } - public enum GainMode { - method public String getRawName(); - enum_constant public static final audio.policy.configuration.V7_0.GainMode AUDIO_GAIN_MODE_CHANNELS; - enum_constant public static final audio.policy.configuration.V7_0.GainMode AUDIO_GAIN_MODE_JOINT; - enum_constant public static final audio.policy.configuration.V7_0.GainMode AUDIO_GAIN_MODE_RAMP; - } - public class Gains { ctor public Gains(); method public java.util.List getGain(); @@ -384,7 +395,7 @@ package audio.policy.configuration.V7_0 { method public int getMaxValueMB(); method public int getMinRampMs(); method public int getMinValueMB(); - method public audio.policy.configuration.V7_0.GainMode getMode(); + method public java.util.List getMode(); method public String getName(); method public int getStepValueMB(); method public boolean getUseForVolume(); @@ -394,7 +405,7 @@ package audio.policy.configuration.V7_0 { method public void setMaxValueMB(int); method public void setMinRampMs(int); method public void setMinValueMB(int); - method public void setMode(audio.policy.configuration.V7_0.GainMode); + method public void setMode(java.util.List); method public void setName(String); method public void setStepValueMB(int); method public void setUseForVolume(boolean); diff --git a/audio/7.0/config/audio_policy_configuration.xsd b/audio/7.0/config/audio_policy_configuration.xsd index 20fe02002e..67848287ef 100644 --- a/audio/7.0/config/audio_policy_configuration.xsd +++ b/audio/7.0/config/audio_policy_configuration.xsd @@ -159,9 +159,13 @@ The flags indicate suggested stream attributes supported by the profile. + Use of AUDIO_{INPUT|OUTPUT}_FLAG_NONE in the XML file isn't required + as empty flag lists are allowed. However these constants are useful for + representing an empty enum value. + @@ -177,6 +181,7 @@ + @@ -251,8 +256,8 @@ - + @@ -271,6 +276,8 @@ + + @@ -279,8 +286,8 @@ - + @@ -302,6 +309,7 @@ + @@ -321,7 +329,6 @@ - @@ -342,22 +349,14 @@ - - - - - - - - - - - + + + @@ -377,17 +376,26 @@ + + + + + + + + + + + - + - - @@ -397,6 +405,7 @@ + @@ -465,9 +474,13 @@ + + + + @@ -538,19 +551,27 @@ - + + + + + + + + + - + @@ -670,6 +691,7 @@ + diff --git a/audio/common/7.0/enums/include/audio_policy_configuration_V7_0-enums.h b/audio/common/7.0/enums/include/audio_policy_configuration_V7_0-enums.h index d5fedce100..cedcab3cc2 100644 --- a/audio/common/7.0/enums/include/audio_policy_configuration_V7_0-enums.h +++ b/audio/common/7.0/enums/include/audio_policy_configuration_V7_0-enums.h @@ -25,6 +25,8 @@ namespace audio::policy::configuration::V7_0 { static inline size_t getChannelCount(AudioChannelMask mask) { switch (mask) { + case AudioChannelMask::AUDIO_CHANNEL_NONE: + return 0; case AudioChannelMask::AUDIO_CHANNEL_OUT_MONO: case AudioChannelMask::AUDIO_CHANNEL_IN_MONO: case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_1: @@ -42,9 +44,12 @@ static inline size_t getChannelCount(AudioChannelMask mask) { case AudioChannelMask::AUDIO_CHANNEL_OUT_2POINT1: case AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO_HAPTIC_A: case AudioChannelMask::AUDIO_CHANNEL_OUT_MONO_HAPTIC_AB: + case AudioChannelMask::AUDIO_CHANNEL_OUT_TRI: + case AudioChannelMask::AUDIO_CHANNEL_OUT_TRI_BACK: case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_3: return 3; case AudioChannelMask::AUDIO_CHANNEL_OUT_2POINT0POINT2: + case AudioChannelMask::AUDIO_CHANNEL_OUT_3POINT1: case AudioChannelMask::AUDIO_CHANNEL_OUT_QUAD: case AudioChannelMask::AUDIO_CHANNEL_OUT_QUAD_BACK: case AudioChannelMask::AUDIO_CHANNEL_OUT_QUAD_SIDE: @@ -158,6 +163,8 @@ static inline bool isOutputDevice(AudioDevice device) { case AudioDevice::AUDIO_DEVICE_OUT_USB_HEADSET: case AudioDevice::AUDIO_DEVICE_OUT_HEARING_AID: case AudioDevice::AUDIO_DEVICE_OUT_ECHO_CANCELLER: + case AudioDevice::AUDIO_DEVICE_OUT_BLE_HEADSET: + case AudioDevice::AUDIO_DEVICE_OUT_BLE_SPEAKER: case AudioDevice::AUDIO_DEVICE_OUT_DEFAULT: case AudioDevice::AUDIO_DEVICE_OUT_STUB: return true; @@ -189,6 +196,7 @@ static inline bool isOutputDevice(AudioDevice device) { case AudioDevice::AUDIO_DEVICE_IN_BLUETOOTH_BLE: case AudioDevice::AUDIO_DEVICE_IN_HDMI_ARC: case AudioDevice::AUDIO_DEVICE_IN_ECHO_REFERENCE: + case AudioDevice::AUDIO_DEVICE_IN_BLE_HEADSET: case AudioDevice::AUDIO_DEVICE_IN_DEFAULT: case AudioDevice::AUDIO_DEVICE_IN_STUB: return false; diff --git a/audio/common/7.0/types.hal b/audio/common/7.0/types.hal index 31c7388329..0d0fa7e91c 100644 --- a/audio/common/7.0/types.hal +++ b/audio/common/7.0/types.hal @@ -106,6 +106,8 @@ typedef string AudioFormat; /** * Audio channel mask indicates presence of particular channels. + * Note that every value is already a mask comprised of individual + * channels. * See 'audioChannelMask' in audio_policy_configuration.xsd for the * list of allowed values. */ @@ -127,13 +129,8 @@ struct AudioProfile { AudioFormat format; /** List of the sample rates (in Hz) supported by the profile. */ vec sampleRates; - /** - * List of channel masks supported by the profile. Every subvector might be - * comprised of several individual channel mask entries for non-traditional - * channel masks, e.g. a combination "OUT_FRONT_LEFT,OUT_FRONT_CENTER" which - * doesn't have a corresponding predefined channel mask. - */ - vec> channelMasks; + /** List of channel masks supported by the profile. */ + vec channelMasks; }; /** @@ -299,21 +296,18 @@ struct SinkMetadata { /** * Type of gain control exposed by an audio port. + * See 'audioGainMode' in audio_policy_configuration.xsd for the + * list of allowed values. */ -@export(name="", value_prefix="AUDIO_GAIN_MODE_") -enum AudioGainMode : uint32_t { - JOINT = 0x1, // supports joint channel gain control - CHANNELS = 0x2, // supports separate channel gain control - RAMP = 0x4 // supports gain ramps -}; +typedef string AudioGainMode; /** * An audio_gain struct is a representation of a gain stage. * A gain stage is always attached to an audio port. */ struct AudioGain { - bitfield mode; - vec channelMask; // channels which gain an be controlled + vec mode; // modes of operation + AudioChannelMask channelMask; // channels which gain can be controlled int32_t minValue; // minimum gain value in millibels int32_t maxValue; // maximum gain value in millibels int32_t defaultValue; // default gain value in millibels @@ -328,8 +322,8 @@ struct AudioGain { */ struct AudioGainConfig { int32_t index; // index of the corresponding AudioGain in AudioPort.gains - AudioGainMode mode; - vec channelMask; // channels which gain value follows + vec mode; // modes of operation + AudioChannelMask channelMask; // channels which gain value follows /** * Gain values in millibels for each channel ordered from LSb to MSb in * channel mask. The number of values is 1 in joint mode or diff --git a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h index 5e4b414d29..0a9d5ee166 100644 --- a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h +++ b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h @@ -1150,7 +1150,7 @@ static void testSetAudioProperties(IStream* stream) { for (const auto& channelMask : profile.channelMasks) { AudioConfigBase config{.format = profile.format, .sampleRateHz = sampleRate, - .channelMask = channelMask}; + .channelMask = {{channelMask}}}; auto ret = stream->setAudioProperties(config); EXPECT_TRUE(ret.isOk()); EXPECT_EQ(Result::OK, ret) << config.format << "; " << config.sampleRateHz << "; " -- GitLab From 77f2c0780c7594a2d9ce528fb7414e4e62f54bb5 Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Wed, 14 Oct 2020 23:46:36 +0800 Subject: [PATCH 230/790] wifi: add transition disable callback API Bug: 160643860 Test: atest VtsHalWifiSupplicantV1_4TargetTest Change-Id: I66839d6766b39483c78919aaa42d42db032f87a7 --- wifi/supplicant/1.4/Android.bp | 1 + wifi/supplicant/1.4/ISupplicantStaNetwork.hal | 20 ++++ .../1.4/ISupplicantStaNetworkCallback.hal | 46 ++++++++ wifi/supplicant/1.4/vts/functional/Android.bp | 1 + .../supplicant_sta_network_hidl_test.cpp | 101 ++++++++++++++++++ 5 files changed, 169 insertions(+) create mode 100644 wifi/supplicant/1.4/ISupplicantStaNetworkCallback.hal create mode 100644 wifi/supplicant/1.4/vts/functional/supplicant_sta_network_hidl_test.cpp diff --git a/wifi/supplicant/1.4/Android.bp b/wifi/supplicant/1.4/Android.bp index 6904f15bad..0a039de722 100644 --- a/wifi/supplicant/1.4/Android.bp +++ b/wifi/supplicant/1.4/Android.bp @@ -9,6 +9,7 @@ hidl_interface { "ISupplicantP2pIface.hal", "ISupplicantStaIface.hal", "ISupplicantStaNetwork.hal", + "ISupplicantStaNetworkCallback.hal", ], interfaces: [ "android.hardware.wifi.supplicant@1.0", diff --git a/wifi/supplicant/1.4/ISupplicantStaNetwork.hal b/wifi/supplicant/1.4/ISupplicantStaNetwork.hal index 7b043d063e..f12ace46f4 100644 --- a/wifi/supplicant/1.4/ISupplicantStaNetwork.hal +++ b/wifi/supplicant/1.4/ISupplicantStaNetwork.hal @@ -17,6 +17,7 @@ package android.hardware.wifi.supplicant@1.4; import @1.3::ISupplicantStaNetwork; +import @1.4::ISupplicantStaNetworkCallback; import @1.0::SupplicantStatus; /** @@ -123,4 +124,23 @@ interface ISupplicantStaNetwork extends @1.3::ISupplicantStaNetwork { * @return enabled true if set, false otherwise. */ getEdmg() generates (SupplicantStatus status, bool enabled); + + /** + * Register for callbacks from this network. + * + * These callbacks are invoked for events that are specific to this network. + * Registration of multiple callback objects is supported. These objects must + * be automatically deleted when the corresponding client process is dead or + * if this network is removed. + * + * @param callback An instance of the |ISupplicantStaNetworkCallback| HIDL + * interface object. + * @return status Status of the operation. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_UNKNOWN|, + * |SupplicantStatusCode.FAILURE_NETWORK_INVALID| + */ + registerCallback_1_4(ISupplicantStaNetworkCallback callback) + generates (SupplicantStatus status); }; diff --git a/wifi/supplicant/1.4/ISupplicantStaNetworkCallback.hal b/wifi/supplicant/1.4/ISupplicantStaNetworkCallback.hal new file mode 100644 index 0000000000..38cdcf9612 --- /dev/null +++ b/wifi/supplicant/1.4/ISupplicantStaNetworkCallback.hal @@ -0,0 +1,46 @@ +/* + * 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. + */ + +package android.hardware.wifi.supplicant@1.4; + +import @1.0::ISupplicantStaNetworkCallback; + +/** + * Callback Interface exposed by the supplicant service + * for each network (ISupplicantStaNetwork). + * + * Clients need to host an instance of this HIDL interface object and + * pass a reference of the object to the supplicant via the + * corresponding |ISupplicantStaNetwork.registerCallback_1_4| method. + */ +interface ISupplicantStaNetworkCallback extends @1.0::ISupplicantStaNetworkCallback { + /** + * WPA3™ Specification Addendum for WPA3 R3 - Table 3. + * Transition Disable Indication filled in the third + * 4-way handshake message. + */ + enum TransitionDisableIndication : uint32_t { + USE_WPA3_PERSONAL = 1 << 0, + USE_SAE_PK = 1 << 1, + USE_WPA3_ENTERPRISE = 1 << 2, + USE_ENHANCED_OPEN = 1 << 3, + }; + + /** + * Used to notify WPA3 transition disable. + */ + oneway onTransitionDisable(bitfield ind); +}; diff --git a/wifi/supplicant/1.4/vts/functional/Android.bp b/wifi/supplicant/1.4/vts/functional/Android.bp index d959285e8b..d6af0a03d2 100644 --- a/wifi/supplicant/1.4/vts/functional/Android.bp +++ b/wifi/supplicant/1.4/vts/functional/Android.bp @@ -44,6 +44,7 @@ cc_test { defaults: ["VtsHalTargetTestDefaults"], srcs: [ "supplicant_sta_iface_hidl_test.cpp", + "supplicant_sta_network_hidl_test.cpp", ], static_libs: [ "VtsHalWifiV1_0TargetTestUtil", diff --git a/wifi/supplicant/1.4/vts/functional/supplicant_sta_network_hidl_test.cpp b/wifi/supplicant/1.4/vts/functional/supplicant_sta_network_hidl_test.cpp new file mode 100644 index 0000000000..32e4f174f8 --- /dev/null +++ b/wifi/supplicant/1.4/vts/functional/supplicant_sta_network_hidl_test.cpp @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "supplicant_hidl_test_utils.h" +#include "supplicant_hidl_test_utils_1_4.h" + +using ::android::sp; +using ::android::hardware::hidl_array; +using ::android::hardware::hidl_string; +using ::android::hardware::hidl_vec; +using ::android::hardware::Return; +using ::android::hardware::Void; +using ::android::hardware::wifi::supplicant::V1_0::IfaceType; +using ::android::hardware::wifi::supplicant::V1_0::ISupplicant; +using ::android::hardware::wifi::supplicant::V1_0::ISupplicantStaIface; +using ::android::hardware::wifi::supplicant::V1_0::ISupplicantStaNetwork; +using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatus; +using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatusCode; +using ::android::hardware::wifi::supplicant::V1_4:: + ISupplicantStaNetworkCallback; +using ::android::hardware::wifi::V1_0::IWifi; + +class SupplicantStaNetworkHidlTest : public SupplicantHidlTestBaseV1_4 { + public: + virtual void SetUp() override { + SupplicantHidlTestBaseV1_4::SetUp(); + sta_network_ = createSupplicantStaNetwork(supplicant_); + ASSERT_NE(sta_network_.get(), nullptr); + /* variable used to check if the underlying HAL version is 1.4 or + * higher. This is to skip tests which are using deprecated methods. + */ + v1_4 = ::android::hardware::wifi::supplicant::V1_4:: + ISupplicantStaNetwork::castFrom(sta_network_); + } + + protected: + sp<::android::hardware::wifi::supplicant::V1_4::ISupplicantStaNetwork> + v1_4 = nullptr; + // ISupplicantStaNetwork object used for all tests in this fixture. + sp sta_network_; +}; + +class NetworkCallback : public ISupplicantStaNetworkCallback { + Return onNetworkEapSimGsmAuthRequest( + const ISupplicantStaNetworkCallback::NetworkRequestEapSimGsmAuthParams& + /* params */) override { + return Void(); + } + Return onNetworkEapSimUmtsAuthRequest( + const ISupplicantStaNetworkCallback::NetworkRequestEapSimUmtsAuthParams& + /* params */) override { + return Void(); + } + Return onNetworkEapIdentityRequest() override { return Void(); } + Return onTransitionDisable(uint32_t /* params */) override { + return Void(); + } +}; + +/* + * RegisterCallback + */ +TEST_P(SupplicantStaNetworkHidlTest, RegisterCallback_1_4) { + v1_4->registerCallback_1_4( + new NetworkCallback(), [](const SupplicantStatus& status) { + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + }); +} + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantStaNetworkHidlTest); +INSTANTIATE_TEST_CASE_P( + PerInstance, SupplicantStaNetworkHidlTest, + testing::Combine( + testing::ValuesIn( + android::hardware::getAllHalInstanceNames(IWifi::descriptor)), + testing::ValuesIn(android::hardware::getAllHalInstanceNames( + ISupplicant::descriptor))), + android::hardware::PrintInstanceTupleNameToString<>); -- GitLab From 61ef86b6256cd30850d7ba4868de57e889dc612b Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Thu, 15 Oct 2020 16:07:32 +0800 Subject: [PATCH 231/790] wifi: add enable SAE H2E only mode API Bug: 160642700 Test: atest VtsHalWifiSupplicantV1_4TargetTest Change-Id: Ic40d8435d35917a7eb722b102de3c2b7640c1aac --- wifi/supplicant/1.4/ISupplicantStaNetwork.hal | 18 ++++++++++++++++++ .../supplicant_sta_network_hidl_test.cpp | 12 ++++++++++++ 2 files changed, 30 insertions(+) diff --git a/wifi/supplicant/1.4/ISupplicantStaNetwork.hal b/wifi/supplicant/1.4/ISupplicantStaNetwork.hal index f12ace46f4..0cc62c0f12 100644 --- a/wifi/supplicant/1.4/ISupplicantStaNetwork.hal +++ b/wifi/supplicant/1.4/ISupplicantStaNetwork.hal @@ -143,4 +143,22 @@ interface ISupplicantStaNetwork extends @1.3::ISupplicantStaNetwork { */ registerCallback_1_4(ISupplicantStaNetworkCallback callback) generates (SupplicantStatus status); + + /** + * Set whether to enable SAE H2E (Hash-to-Element) only mode. + * + * When enabled, only SAE H2E network is allowed; othewise + * H&P (Hunting and Pecking) and H2E are both allowed. + * H&P only mode is not supported. + * If this API is not called before connecting to a SAE + * network, the behavior is undefined. + * + * @param enable true to set, false otherwise. + * @return status Status of the operation. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_UNKNOWN|, + * |SupplicantStatusCode.FAILURE_NETWORK_INVALID| + */ + enableSaeH2eOnlyMode(bool enable) generates (SupplicantStatus status); }; diff --git a/wifi/supplicant/1.4/vts/functional/supplicant_sta_network_hidl_test.cpp b/wifi/supplicant/1.4/vts/functional/supplicant_sta_network_hidl_test.cpp index 32e4f174f8..aaaccfc19b 100644 --- a/wifi/supplicant/1.4/vts/functional/supplicant_sta_network_hidl_test.cpp +++ b/wifi/supplicant/1.4/vts/functional/supplicant_sta_network_hidl_test.cpp @@ -90,6 +90,18 @@ TEST_P(SupplicantStaNetworkHidlTest, RegisterCallback_1_4) { }); } +/* + * enable SAE H2E (Hash-to-Element) only mode + */ +TEST_P(SupplicantStaNetworkHidlTest, EnableSaeH2eOnlyMode) { + v1_4->enableSaeH2eOnlyMode(true, [&](const SupplicantStatus& status) { + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + }); + v1_4->enableSaeH2eOnlyMode(false, [&](const SupplicantStatus& status) { + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + }); +} + GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantStaNetworkHidlTest); INSTANTIATE_TEST_CASE_P( PerInstance, SupplicantStaNetworkHidlTest, -- GitLab From 3ba5d228ba17b65843a64e2fc4b94e047759d2d9 Mon Sep 17 00:00:00 2001 From: Enrico Granata Date: Wed, 21 Oct 2020 17:20:00 -0600 Subject: [PATCH 232/790] Allow changing the mock location returned by GNSS HAL This CL introduces a new lshal debug command for GNSS HAL location [lat=..] [lon=..] [ele=..] that allows changing the mock location provided by GNSS HAL to clients This can be used manually to configure a single mock location, or in a scripted scenario to, e.g., supply a set of locations from a GPX file to simulate a moving device Bug: None Test: set different locations via command line to Cuttlefish device, e.g. $ adb shell lshal debug android.hardware.gnss@2.1::IGnss/default location lat=46.6317 lon=-114.0789 Change-Id: I7217c59f66f1ee7f5a9bd3f3dd3af7be4b43c024 --- gnss/1.1/default/GnssDebug.cpp | 23 +++---- gnss/common/utils/default/Android.bp | 1 + gnss/common/utils/default/MockLocation.cpp | 25 ++++++++ gnss/common/utils/default/Utils.cpp | 7 ++- gnss/common/utils/default/include/Constants.h | 3 - .../utils/default/include/MockLocation.h | 36 +++++++++++ .../utils/default/include/v2_1/GnssTemplate.h | 61 +++++++++++++++++++ gnss/common/utils/default/v2_1/GnssDebug.cpp | 7 ++- 8 files changed, 143 insertions(+), 20 deletions(-) create mode 100644 gnss/common/utils/default/MockLocation.cpp create mode 100644 gnss/common/utils/default/include/MockLocation.h diff --git a/gnss/1.1/default/GnssDebug.cpp b/gnss/1.1/default/GnssDebug.cpp index 471ed2421d..252f4e6373 100644 --- a/gnss/1.1/default/GnssDebug.cpp +++ b/gnss/1.1/default/GnssDebug.cpp @@ -20,6 +20,7 @@ #include "Constants.h" #include "GnssDebug.h" +#include "MockLocation.h" using namespace ::android::hardware::gnss::common; @@ -32,17 +33,17 @@ namespace implementation { // Methods from ::android::hardware::gnss::V1_0::IGnssDebug follow. Return GnssDebug::getDebugData(V1_0::IGnssDebug::getDebugData_cb _hidl_cb) { PositionDebug positionDebug = { - .valid = true, - .latitudeDegrees = kMockLatitudeDegrees, - .longitudeDegrees = kMockLongitudeDegrees, - .altitudeMeters = kMockAltitudeMeters, - .speedMetersPerSec = kMockSpeedMetersPerSec, - .bearingDegrees = kMockBearingDegrees, - .horizontalAccuracyMeters = kMockHorizontalAccuracyMeters, - .verticalAccuracyMeters = kMockVerticalAccuracyMeters, - .speedAccuracyMetersPerSecond = kMockSpeedAccuracyMetersPerSecond, - .bearingAccuracyDegrees = kMockBearingAccuracyDegrees, - .ageSeconds = 0.99}; + .valid = true, + .latitudeDegrees = gMockLatitudeDegrees, + .longitudeDegrees = gMockLongitudeDegrees, + .altitudeMeters = gMockAltitudeMeters, + .speedMetersPerSec = kMockSpeedMetersPerSec, + .bearingDegrees = kMockBearingDegrees, + .horizontalAccuracyMeters = kMockHorizontalAccuracyMeters, + .verticalAccuracyMeters = kMockVerticalAccuracyMeters, + .speedAccuracyMetersPerSecond = kMockSpeedAccuracyMetersPerSecond, + .bearingAccuracyDegrees = kMockBearingAccuracyDegrees, + .ageSeconds = 0.99}; TimeDebug timeDebug = {.timeEstimate = kMockTimestamp, .timeUncertaintyNs = 1000, diff --git a/gnss/common/utils/default/Android.bp b/gnss/common/utils/default/Android.bp index 8d9d4d46aa..730de4bfed 100644 --- a/gnss/common/utils/default/Android.bp +++ b/gnss/common/utils/default/Android.bp @@ -29,6 +29,7 @@ cc_library_static { "v2_1/GnssDebug.cpp", "v2_1/GnssMeasurement.cpp", "v2_1/GnssMeasurementCorrections.cpp", + "MockLocation.cpp", "Utils.cpp", "NmeaFixInfo.cpp", ], diff --git a/gnss/common/utils/default/MockLocation.cpp b/gnss/common/utils/default/MockLocation.cpp new file mode 100644 index 0000000000..2d8e7c59ea --- /dev/null +++ b/gnss/common/utils/default/MockLocation.cpp @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "MockLocation.h" + +namespace android::hardware::gnss::common { + +float gMockLatitudeDegrees{37.4219999}; +float gMockLongitudeDegrees{-122.0840575}; +float gMockAltitudeMeters{1.60062531}; + +} // namespace android::hardware::gnss::common diff --git a/gnss/common/utils/default/Utils.cpp b/gnss/common/utils/default/Utils.cpp index 386090e486..fa83634024 100644 --- a/gnss/common/utils/default/Utils.cpp +++ b/gnss/common/utils/default/Utils.cpp @@ -15,6 +15,7 @@ */ #include +#include #include #include @@ -141,9 +142,9 @@ V2_0::GnssLocation Utils::getMockLocationV2_0() { V1_0::GnssLocation Utils::getMockLocationV1_0() { V1_0::GnssLocation location = { .gnssLocationFlags = 0xFF, - .latitudeDegrees = kMockLatitudeDegrees, - .longitudeDegrees = kMockLongitudeDegrees, - .altitudeMeters = kMockAltitudeMeters, + .latitudeDegrees = gMockLatitudeDegrees, + .longitudeDegrees = gMockLongitudeDegrees, + .altitudeMeters = gMockAltitudeMeters, .speedMetersPerSec = kMockSpeedMetersPerSec, .bearingDegrees = kMockBearingDegrees, .horizontalAccuracyMeters = kMockHorizontalAccuracyMeters, diff --git a/gnss/common/utils/default/include/Constants.h b/gnss/common/utils/default/include/Constants.h index 000a9ec7d2..ad4e0eb9e9 100644 --- a/gnss/common/utils/default/include/Constants.h +++ b/gnss/common/utils/default/include/Constants.h @@ -24,9 +24,6 @@ namespace hardware { namespace gnss { namespace common { -const float kMockLatitudeDegrees = 37.4219999; -const float kMockLongitudeDegrees = -122.0840575; -const float kMockAltitudeMeters = 1.60062531; const float kMockSpeedMetersPerSec = 0; const float kMockBearingDegrees = 0; const float kMockHorizontalAccuracyMeters = 5; diff --git a/gnss/common/utils/default/include/MockLocation.h b/gnss/common/utils/default/include/MockLocation.h new file mode 100644 index 0000000000..cd8cb5dad1 --- /dev/null +++ b/gnss/common/utils/default/include/MockLocation.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef android_hardware_gnss_common_MockLocation_H_ +#define android_hardware_gnss_common_MockLocation_H_ + +#include + +namespace android { +namespace hardware { +namespace gnss { +namespace common { + +extern float gMockLatitudeDegrees; +extern float gMockLongitudeDegrees; +extern float gMockAltitudeMeters; + +} // namespace common +} // namespace gnss +} // namespace hardware +} // namespace android + +#endif // android_hardware_gnss_common_MockLocation_H_ diff --git a/gnss/common/utils/default/include/v2_1/GnssTemplate.h b/gnss/common/utils/default/include/v2_1/GnssTemplate.h index 0128df4812..7c3c58abcd 100644 --- a/gnss/common/utils/default/include/v2_1/GnssTemplate.h +++ b/gnss/common/utils/default/include/v2_1/GnssTemplate.h @@ -33,6 +33,7 @@ #include "GnssDebug.h" #include "GnssMeasurement.h" #include "GnssMeasurementCorrections.h" +#include "MockLocation.h" #include "NmeaFixInfo.h" #include "Utils.h" @@ -113,12 +114,17 @@ struct GnssTemplate : public T_IGnss { getExtensionMeasurementCorrections_1_1() override; Return> getExtensionGnssAntennaInfo() override; + Return debug(const hidl_handle& fd, const hidl_vec& options) override; + private: std::unique_ptr getLocationFromHW(); void reportLocation(const V2_0::GnssLocation&) const; void reportLocation(const V1_0::GnssLocation&) const; void reportSvStatus(const hidl_vec&) const; + Return help(const hidl_handle& fd); + Return setLocation(const hidl_handle& fd, const hidl_vec& options); + static sp sGnssCallback_2_1; static sp sGnssCallback_2_0; static sp sGnssCallback_1_1; @@ -639,4 +645,59 @@ void GnssTemplate::reportLocation(const V2_0::GnssLocation& location) c } } +template +Return GnssTemplate::setLocation(const hidl_handle& fd, + const hidl_vec& options) { + auto lat = gMockLatitudeDegrees; + auto lon = gMockLongitudeDegrees; + auto ele = gMockAltitudeMeters; + + for (size_t i = 1; i < options.size(); ++i) { + std::string option = options[i]; + if (option.rfind("lat=", 0) == 0) { + option = option.substr(4); + lat = stof(option); + } else if (option.rfind("lon=", 0) == 0) { + option = option.substr(4); + lon = stof(option); + } else if (option.rfind("ele=", 0) == 0) { + option = option.substr(4); + ele = stof(option); + } else { + dprintf(fd->data[0], "unsupported location argument: %s\n", option.c_str()); + } + } + + gMockLatitudeDegrees = lat; + gMockLongitudeDegrees = lon; + gMockAltitudeMeters = ele; + + dprintf(fd->data[0], "mock location updated to lat=%f lon=%f ele=%f\n", gMockLatitudeDegrees, + gMockLongitudeDegrees, gMockAltitudeMeters); + + return Void(); +} + +template +Return GnssTemplate::help(const hidl_handle& fd) { + dprintf(fd->data[0], + "invalid option for Gnss HAL; valid options are:\n" + "location lat=.. lon=.. ele=..\n"); + return Void(); +} + +template +Return GnssTemplate::debug(const hidl_handle& fd, + const hidl_vec& options) { + if (options.size() == 0) { + return help(fd); + } else if (options[0] == "location") { + return setLocation(fd, options); + } else { + return help(fd); + } + + return Void(); +} + } // namespace android::hardware::gnss::common::implementation diff --git a/gnss/common/utils/default/v2_1/GnssDebug.cpp b/gnss/common/utils/default/v2_1/GnssDebug.cpp index 492b970b59..d78b0b6ddc 100644 --- a/gnss/common/utils/default/v2_1/GnssDebug.cpp +++ b/gnss/common/utils/default/v2_1/GnssDebug.cpp @@ -19,6 +19,7 @@ #include #include "Constants.h" +#include "MockLocation.h" #include "v2_1/GnssDebug.h" using namespace ::android::hardware::gnss::common; @@ -29,9 +30,9 @@ namespace android::hardware::gnss::V1_1::implementation { Return GnssDebug::getDebugData(V1_0::IGnssDebug::getDebugData_cb _hidl_cb) { PositionDebug positionDebug = { .valid = true, - .latitudeDegrees = kMockLatitudeDegrees, - .longitudeDegrees = kMockLongitudeDegrees, - .altitudeMeters = kMockAltitudeMeters, + .latitudeDegrees = gMockLatitudeDegrees, + .longitudeDegrees = gMockLongitudeDegrees, + .altitudeMeters = gMockAltitudeMeters, .speedMetersPerSec = kMockSpeedMetersPerSec, .bearingDegrees = kMockBearingDegrees, .horizontalAccuracyMeters = kMockHorizontalAccuracyMeters, -- GitLab From edeee5a914e16dd0a47bac1d133ef6454e68af65 Mon Sep 17 00:00:00 2001 From: Sooraj Sasindran Date: Fri, 14 Aug 2020 11:00:11 -0700 Subject: [PATCH 233/790] Ability to configure NR dual connectivity Provide ability to configure EUTRANR dual connectivity Bug: 162373679 Test: build Change-Id: I628edc2d6157ab2db279c2f32deb57798f2dd9ce --- radio/1.6/IRadio.hal | 24 ++++++++++++ radio/1.6/IRadioResponse.hal | 22 +++++++++++ radio/1.6/types.hal | 21 ++++++++++ .../1.6/vts/functional/radio_hidl_hal_api.cpp | 38 ++++++++++++++++++- .../functional/radio_hidl_hal_utils_v1_6.h | 6 +++ radio/1.6/vts/functional/radio_response.cpp | 14 +++++++ 6 files changed, 124 insertions(+), 1 deletion(-) diff --git a/radio/1.6/IRadio.hal b/radio/1.6/IRadio.hal index 5f5f5c160f..ca40a17b24 100644 --- a/radio/1.6/IRadio.hal +++ b/radio/1.6/IRadio.hal @@ -181,4 +181,28 @@ interface IRadio extends @1.5::IRadio { * */ oneway sendCdmaSmsExpectMore_1_6(int32_t serial, CdmaSmsMessage sms); + + /** + * Enable or disable E-UTRA-NR dual connectivity. If disabled then UE will not connect + * to secondary carrier. + * + * @param serial Serial number of request. + * @param nrDualConnectivityState expected NR dual connectivity state. + * 1. Enable NR dual connectivity {NrDualConnectivityState:ENABLE} + * 2. Disable NR dual connectivity {NrDualConnectivityState:DISABLE} + * 3. Disable NR dual connectivity and force secondary cell to be released + * {NrDualConnectivityState:DISABLE_IMMEDIATE} + + * Response callback is IRadioResponse.enableNRDualConnectivityResponse() + */ + oneway enableNrDualConnectivity(int32_t serial, + NrDualConnectivityState nrDualConnectivityState); + + /** + * Is E-UTRA-NR Dual Connectivity enabled + * + * @param serial Serial number of request. + * Response callback is IRadioResponse.isNRDualConnectivityEnabledResponse() + */ + oneway isNrDualConnectivityEnabled(int32_t serial); }; diff --git a/radio/1.6/IRadioResponse.hal b/radio/1.6/IRadioResponse.hal index fed7e79b54..4ff7e47f12 100644 --- a/radio/1.6/IRadioResponse.hal +++ b/radio/1.6/IRadioResponse.hal @@ -200,4 +200,26 @@ interface IRadioResponse extends @1.5::IRadioResponse { * RadioError:BLOCKED_DUE_TO_CALL */ oneway sendCdmaSmsExpectMoreResponse_1_6(RadioResponseInfo info, SendSmsResult sms); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + */ + oneway enableNrDualConnectivityResponse(RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * @param isEnabled Indicates whether NR dual connectivity is enabled or not, True if enabled + * else false. + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + */ + oneway isNrDualConnectivityEnabledResponse(RadioResponseInfo info, bool isEnabled); }; diff --git a/radio/1.6/types.hal b/radio/1.6/types.hal index c77a86db60..07b49771c5 100644 --- a/radio/1.6/types.hal +++ b/radio/1.6/types.hal @@ -255,3 +255,24 @@ struct SetupDataCallResult { /** Specifies the fallback mode on an IWLAN handover failure. */ HandoverFailureMode handoverFailureMode; }; + +/** + * NR Dual connectivity state + */ +enum NrDualConnectivityState: int32_t { + /** + * Enable NR dual connectivity. Enabled state does not mean dual connectivity + * is active. It means device is allowed to connect to both primary and secondary. + */ + ENABLE = 1, + /** + * Disable NR dual connectivity. Disabled state does not mean secondary cell is released. + * Modem will release it only if current bearer is released to avoid radio link failure. + */ + DISABLE = 2, + /** + * Disable NR dual connectivity and force secondary cell to be released if dual connectivity + * was active. This may result in radio link failure. + */ + DISABLE_IMMEDIATE= 3, +}; diff --git a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp index 8f3b991d42..01236c6a4e 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp +++ b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp @@ -63,7 +63,6 @@ TEST_P(RadioHidlTest_v1_6, setupDataCall_1_6) { EXPECT_EQ(std::cv_status::no_timeout, wait()); EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type); EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial); - if (cardStatus.base.base.base.cardState == CardState::ABSENT) { ASSERT_TRUE(CheckAnyOfErrors( radioRsp_v1_6->rspInfo.error, @@ -259,3 +258,40 @@ TEST_P(RadioHidlTest_v1_6, setRadioPower_1_6_emergencyCall_cancelled) { EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial); EXPECT_EQ(::android::hardware::radio::V1_6::RadioError::NONE, radioRsp_v1_6->rspInfo.error); } + +/* + * Test IRadio.enableNrDualConnectivity() for the response returned. + */ +TEST_P(RadioHidlTest_v1_6, enableNrDualConnectivity) { + serial = GetRandomSerialNumber(); + + Return res = + radio_v1_6->enableNrDualConnectivity(serial, NrDualConnectivityState::DISABLE); + ASSERT_OK(res); + + EXPECT_EQ(std::cv_status::no_timeout, wait()); + EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type); + EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial); + ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_6->rspInfo.error, + {::android::hardware::radio::V1_6::RadioError::RADIO_NOT_AVAILABLE, + ::android::hardware::radio::V1_6::RadioError::INTERNAL_ERR, + ::android::hardware::radio::V1_6::RadioError::NONE})); +} + +/* + * Test IRadio.isNrDualConnectivityEnabled() for the response returned. + */ +TEST_P(RadioHidlTest_v1_6, isNrDualConnectivityEnabled) { + serial = GetRandomSerialNumber(); + + Return res = radio_v1_6->isNrDualConnectivityEnabled(serial); + ASSERT_OK(res); + + EXPECT_EQ(std::cv_status::no_timeout, wait()); + EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type); + EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial); + ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_6->rspInfo.error, + {::android::hardware::radio::V1_6::RadioError::RADIO_NOT_AVAILABLE, + ::android::hardware::radio::V1_6::RadioError::INTERNAL_ERR, + ::android::hardware::radio::V1_6::RadioError::NONE})); +} diff --git a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h index d90aa806dc..784bcd91e8 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h +++ b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h @@ -78,6 +78,7 @@ class RadioResponse_v1_6 : public ::android::hardware::radio::V1_6::IRadioRespon // Modem bool isModemEnabled; bool enableModemResponseToggle; + bool isNRDualConnectivityEnabled; ::android::hardware::hidl_bitfield<::android::hardware::radio::V1_4::RadioAccessFamily> networkTypeBitmapResponse; @@ -765,6 +766,11 @@ class RadioResponse_v1_6 : public ::android::hardware::radio::V1_6::IRadioRespon Return sendCdmaSmsExpectMoreResponse_1_6( const ::android::hardware::radio::V1_6::RadioResponseInfo& info, const SendSmsResult& sms); + + Return enableNrDualConnectivityResponse( + const ::android::hardware::radio::V1_6::RadioResponseInfo& info); + Return isNrDualConnectivityEnabledResponse( + const ::android::hardware::radio::V1_6::RadioResponseInfo& info, bool isEnabled); }; /* Callback class for radio indication */ diff --git a/radio/1.6/vts/functional/radio_response.cpp b/radio/1.6/vts/functional/radio_response.cpp index 574990d5db..ffa384ed9b 100644 --- a/radio/1.6/vts/functional/radio_response.cpp +++ b/radio/1.6/vts/functional/radio_response.cpp @@ -1055,6 +1055,12 @@ Return RadioResponse_v1_6::setupDataCallResponse_1_6( parent_v1_6.notify(info.serial); return Void(); } +Return RadioResponse_v1_6::enableNrDualConnectivityResponse( + const ::android::hardware::radio::V1_6::RadioResponseInfo& info) { + rspInfo = info; + parent_v1_6.notify(info.serial); + return Void(); +} Return RadioResponse_v1_6::getDataCallListResponse_1_6( const ::android::hardware::radio::V1_6::RadioResponseInfo& info, @@ -1099,3 +1105,11 @@ Return RadioResponse_v1_6::sendCdmaSmsExpectMoreResponse_1_6( parent_v1_6.notify(info.serial); return Void(); } + +Return RadioResponse_v1_6::isNrDualConnectivityEnabledResponse( + const ::android::hardware::radio::V1_6::RadioResponseInfo& info, bool isEnabled) { + rspInfo = info; + isNRDualConnectivityEnabled = isEnabled; + parent_v1_6.notify(info.serial); + return Void(); +} -- GitLab From b6d44ea4860ce404f836d9b203a7804778efa71b Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Wed, 21 Oct 2020 17:48:41 -0700 Subject: [PATCH 234/790] Add Scrambling Status Monitor merchanism in Tuner 1.1 Test: atest VtsHalTvTunerV1_1TargetTest Bug: 158779948 Change-Id: Ie6d837dba732e213180ae5fac0ee86f9d310fa33 --- tv/tuner/1.1/IFilter.hal | 17 ++++++++++ tv/tuner/1.1/default/Filter.cpp | 22 +++++++++++++ tv/tuner/1.1/default/Filter.h | 5 +++ tv/tuner/1.1/types.hal | 21 +++++++++++++ tv/tuner/1.1/vts/functional/FilterTests.cpp | 31 +++++++++++++++++++ tv/tuner/1.1/vts/functional/FilterTests.h | 3 ++ .../VtsHalTvTunerV1_1TargetTest.cpp | 3 ++ .../VtsHalTvTunerV1_1TestConfigurations.h | 2 ++ 8 files changed, 104 insertions(+) diff --git a/tv/tuner/1.1/IFilter.hal b/tv/tuner/1.1/IFilter.hal index 3ea42094b8..df736aa86b 100644 --- a/tv/tuner/1.1/IFilter.hal +++ b/tv/tuner/1.1/IFilter.hal @@ -81,4 +81,21 @@ interface IFilter extends @1.0::IFilter { * UNKNOWN_ERROR if failed for other reasons. */ configureAvStreamType(AvStreamType avStreamType) generates (Result result); + + /** + * Configure the filter to monitor specific Scrambling Status. + * + * Scrambling Status should be sent through the filer callback at the following two scenarios: + * 1. When this method is called, the first detected scrambling status should be sent. + * 2. When the filter transits into the monitored statuses configured through this method, + * event should be sent. + * + * @param statuses Scrambling Statuses to monitor. Set corresponding bit to monitor. Reset to + * stop monitoring. + * @return result Result status of the operation. + * SUCCESS if successful, + * INVALID_STATE if configure can't be applied, + * UNKNOWN_ERROR if failed for other reasons. + */ + configureScramblingEvent(bitfield statuses) generates (Result result); }; diff --git a/tv/tuner/1.1/default/Filter.cpp b/tv/tuner/1.1/default/Filter.cpp index 54d515b570..4c377293dc 100644 --- a/tv/tuner/1.1/default/Filter.cpp +++ b/tv/tuner/1.1/default/Filter.cpp @@ -249,6 +249,28 @@ Return Filter::configureAvStreamType(const V1_1::AvStreamType& avStreamT return Result::SUCCESS; } +Return Filter::configureScramblingEvent(uint32_t statuses) { + ALOGV("%s", __FUNCTION__); + + mStatuses = statuses; + if (mCallback_1_1 != nullptr) { + // Assuming current status is always NOT_SCRAMBLED + V1_1::DemuxFilterEventExt filterEventExt; + V1_1::DemuxFilterEventExt::Event event; + event.scramblingStatus(V1_1::ScramblingStatus::NOT_SCRAMBLED); + int size = filterEventExt.events.size(); + filterEventExt.events.resize(size + 1); + filterEventExt.events[size] = event; + DemuxFilterEvent emptyFilterEvent; + + mCallback_1_1->onFilterEvent_1_1(emptyFilterEvent, filterEventExt); + mFilterEventExt.events.resize(0); + } else { + return Result::INVALID_STATE; + } + return Result::SUCCESS; +} + bool Filter::createFilterMQ() { ALOGV("%s", __FUNCTION__); diff --git a/tv/tuner/1.1/default/Filter.h b/tv/tuner/1.1/default/Filter.h index f8b9a651e4..522db354a0 100644 --- a/tv/tuner/1.1/default/Filter.h +++ b/tv/tuner/1.1/default/Filter.h @@ -84,6 +84,8 @@ class Filter : public V1_1::IFilter { virtual Return configureAvStreamType(const V1_1::AvStreamType& avStreamType) override; + virtual Return configureScramblingEvent(uint32_t statuses) override; + /** * To create a FilterMQ and its Event Flag. * @@ -230,6 +232,9 @@ class Filter : public V1_1::IFilter { uint32_t mAudioStreamType; uint32_t mVideoStreamType; + + // Scrambling status to be monitored + uint32_t mStatuses = 0; }; } // namespace implementation diff --git a/tv/tuner/1.1/types.hal b/tv/tuner/1.1/types.hal index 4e677b525b..defc99b14e 100644 --- a/tv/tuner/1.1/types.hal +++ b/tv/tuner/1.1/types.hal @@ -125,6 +125,8 @@ struct DemuxFilterEventExt { DemuxFilterRecordEventExt tsRecord; DemuxFilterRecordEventExt mmtpRecord; + + ScramblingStatus scramblingStatus; }; /** @@ -133,6 +135,25 @@ struct DemuxFilterEventExt { vec events; }; +/** + * Scrambling Status Type. + */ +@export +enum ScramblingStatus : uint32_t { + /** + * Content’s scrambling status is unknown + */ + UNKNOWN = 1 << 0, + /** + * Content is not scrambled. + */ + NOT_SCRAMBLED = 1 << 1, + /** + * Content is scrambled. + */ + SCRAMBLED = 1 << 2, +}; + typedef FrontendDvbcSpectralInversion FrontendSpectralInversion; /** diff --git a/tv/tuner/1.1/vts/functional/FilterTests.cpp b/tv/tuner/1.1/vts/functional/FilterTests.cpp index f4ac8bf4b2..f114a66d76 100644 --- a/tv/tuner/1.1/vts/functional/FilterTests.cpp +++ b/tv/tuner/1.1/vts/functional/FilterTests.cpp @@ -28,6 +28,18 @@ void FilterCallback::testFilterDataOutput() { ALOGW("[vts] pass and stop"); } +void FilterCallback::testFilterScramblingEvent() { + android::Mutex::Autolock autoLock(mMsgLock); + while (mScramblingStatusEvent < 1) { + if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) { + EXPECT_TRUE(false) << "scrambling event does not output within timeout"; + return; + } + } + mScramblingStatusEvent = 0; + ALOGW("[vts] pass and stop"); +} + void FilterCallback::readFilterEventData() { ALOGW("[vts] reading filter event"); // todo separate filter handlers @@ -56,6 +68,9 @@ void FilterCallback::readFilterEventData() { eventExt.mmtpRecord().pts, eventExt.mmtpRecord().firstMbInSlice, eventExt.mmtpRecord().mpuSequenceNumber); break; + case DemuxFilterEventExt::Event::hidl_discriminator::scramblingStatus: + mScramblingStatusEvent++; + break; default: break; } @@ -240,3 +255,19 @@ AssertionResult FilterTests::closeFilter(uint64_t filterId) { } return AssertionResult(status == Result::SUCCESS); } + +AssertionResult FilterTests::configureScramblingEvent(uint64_t filterId, uint32_t statuses) { + EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first."; + Result status; + + sp filter_v1_1 = + android::hardware::tv::tuner::V1_1::IFilter::castFrom(mFilters[filterId]); + if (filter_v1_1 != NULL) { + status = filter_v1_1->configureScramblingEvent(statuses); + mFilterCallbacks[filterId]->testFilterScramblingEvent(); + } else { + ALOGW("[vts] Can't cast IFilter into v1_1."); + return failure(); + } + return AssertionResult(status == Result::SUCCESS); +} diff --git a/tv/tuner/1.1/vts/functional/FilterTests.h b/tv/tuner/1.1/vts/functional/FilterTests.h index 3472e4ebb5..d88f171e10 100644 --- a/tv/tuner/1.1/vts/functional/FilterTests.h +++ b/tv/tuner/1.1/vts/functional/FilterTests.h @@ -117,6 +117,7 @@ class FilterCallback : public IFilterCallback { void setMemSize(uint64_t size) { mAvSharedMemSize = size; } void testFilterDataOutput(); + void testFilterScramblingEvent(); void readFilterEventData(); bool dumpAvData(DemuxFilterMediaEvent event); @@ -136,6 +137,7 @@ class FilterCallback : public IFilterCallback { android::Condition mMsgCondition; int mPidFilterOutputCount = 0; + int mScramblingStatusEvent = 0; }; class FilterTests { @@ -153,6 +155,7 @@ class FilterTests { AssertionResult configFilter(DemuxFilterSettings setting, uint64_t filterId); AssertionResult configAvFilterStreamType(AvStreamType type, uint64_t filterId); AssertionResult configIpFilterCid(uint32_t ipCid, uint64_t filterId); + AssertionResult configureScramblingEvent(uint64_t filterId, uint32_t statuses); AssertionResult getFilterMQDescriptor(uint64_t filterId); AssertionResult startFilter(uint64_t filterId); AssertionResult stopFilter(uint64_t filterId); diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp index 218592047f..17abf49842 100644 --- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp @@ -46,6 +46,9 @@ void TunerFilterHidlTest::configSingleFilterInDemuxTest(FilterConfig filterConf, if (filterConf.type.mainType == DemuxFilterMainType::IP) { ASSERT_TRUE(mFilterTests.configIpFilterCid(filterConf.ipCid, filterId)); } + if (filterConf.statuses > 0) { + ASSERT_TRUE(mFilterTests.configureScramblingEvent(filterId, filterConf.statuses)); + } ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId)); ASSERT_TRUE(mFilterTests.startFilter(filterId)); ASSERT_TRUE(mFilterTests.stopFilter(filterId)); diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h index 911d984cce..76bf765909 100644 --- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h @@ -96,6 +96,7 @@ struct FilterConfig { DemuxFilterSettings settings; AvStreamType streamType; uint32_t ipCid; + uint32_t statuses; bool operator<(const FilterConfig& /*c*/) const { return false; } }; @@ -187,6 +188,7 @@ inline void initFilterConfig() { filterArray[TS_VIDEO0].bufferSize = FMQ_SIZE_16M; filterArray[TS_VIDEO0].settings.ts().tpid = 256; filterArray[TS_VIDEO0].settings.ts().filterSettings.av({.isPassthrough = false}); + filterArray[TS_VIDEO0].statuses = 1; filterArray[TS_VIDEO1].type.mainType = DemuxFilterMainType::TS; filterArray[TS_VIDEO1].type.subType.tsFilterType(DemuxTsFilterType::VIDEO); filterArray[TS_VIDEO1].bufferSize = FMQ_SIZE_16M; -- GitLab From a5273c760c332d7462ab198e1219543630a27d53 Mon Sep 17 00:00:00 2001 From: Mikhail Naganov Date: Mon, 19 Oct 2020 21:27:14 +0000 Subject: [PATCH 235/790] Make audio*-base.h files autogenerated again Major change: audio-base.h is generated from "core" types.hal, new file audio_common-base.h is generated from "common" types.hal. In order to be able to add system-only constants to generated enums, the latter are made anonymous, values got "HAL_" prefix. Then in system/audio.h a full enum is constructed. Removed audio_drain_type_t from exported, as it belongs to libhardware only. Added missing enums that were introduced at the system side only in Android R. Bug: 122858783 Test: m Change-Id: I8c017912395a03beacea077fd562fae2329ad975 --- audio/7.0/types.hal | 3 +-- audio/common/7.0/types.hal | 24 ++++++++++++++++++- audio/core/all-versions/default/StreamOut.cpp | 8 +++---- update-base-files.sh | 7 ++++-- 4 files changed, 33 insertions(+), 9 deletions(-) diff --git a/audio/7.0/types.hal b/audio/7.0/types.hal index 4a9e28915a..7c050c106a 100644 --- a/audio/7.0/types.hal +++ b/audio/7.0/types.hal @@ -30,7 +30,6 @@ enum Result : int32_t { NOT_SUPPORTED }; -@export(name="audio_drain_type_t", value_prefix="AUDIO_DRAIN_") enum AudioDrain : int32_t { /** drain() returns when all data has been played. */ ALL, @@ -315,7 +314,7 @@ enum TimestretchMode : int32_t { * Behavior when the values for speed and / or pitch are out * of applicable range. */ -@export(name="audio_timestretch_fallback_mode_t", value_prefix="AUDIO_TIMESTRETCH_FALLBACK_") +@export(name="", value_prefix="HAL_AUDIO_TIMESTRETCH_FALLBACK_") enum TimestretchFallbackMode : int32_t { // Need to be in sync with AUDIO_FALLBACK_MODE_* constants in // frameworks/base/media/java/android/media/PlaybackParams.java diff --git a/audio/common/7.0/types.hal b/audio/common/7.0/types.hal index 0d0fa7e91c..631d5240a2 100644 --- a/audio/common/7.0/types.hal +++ b/audio/common/7.0/types.hal @@ -78,6 +78,7 @@ typedef string AudioSource; */ typedef int32_t AudioSession; +@export(name="", value_prefix="HAL_AUDIO_SESSION_") enum AudioSessionConsts : int32_t { /** * Session for effects attached to a particular sink or source audio device @@ -137,7 +138,7 @@ struct AudioProfile { * Major modes for a mobile device. The current mode setting affects audio * routing. */ -@export(name="audio_mode_t", value_prefix="AUDIO_MODE_") +@export(name="", value_prefix="HAL_AUDIO_MODE_") enum AudioMode : int32_t { NORMAL = 0, RINGTONE = 1, @@ -221,6 +222,27 @@ enum AudioEncapsulationMode : int32_t { HANDLE = 2, }; +/** + * Enumeration of metadata types permitted for use by + * encapsulation mode audio streams. + */ +@export(name="audio_encapsulation_metadata_type_t", value_prefix="AUDIO_ENCAPSULATION_METADATA_TYPE_") +enum AudioEncapsulationMetadataType : int32_t { + /** + * No metadata. + */ + NONE = 0, + /** + * Encapsulation metadata type for framework tuner information. + */ + FRAMEWORK_TUNER = 1, + /** + * Encapsulation metadata type for DVB AD descriptor. + * This metadata is formatted per ETSI TS 101 154 Table E.1: AD_descriptor. + */ + DVB_AD_DESCRIPTOR = 2, +}; + /** * Additional information about the stream passed to hardware decoders. */ diff --git a/audio/core/all-versions/default/StreamOut.cpp b/audio/core/all-versions/default/StreamOut.cpp index 1519c48e12..007eb4564a 100644 --- a/audio/core/all-versions/default/StreamOut.cpp +++ b/audio/core/all-versions/default/StreamOut.cpp @@ -496,11 +496,11 @@ Return StreamOut::supportsDrain() { } Return StreamOut::drain(AudioDrain type) { + audio_drain_type_t halDrainType = + type == AudioDrain::EARLY_NOTIFY ? AUDIO_DRAIN_EARLY_NOTIFY : AUDIO_DRAIN_ALL; return mStream->drain != NULL - ? Stream::analyzeStatus( - "drain", - mStream->drain(mStream, static_cast(type)), - {ENOSYS} /*ignore*/) + ? Stream::analyzeStatus("drain", mStream->drain(mStream, halDrainType), + {ENOSYS} /*ignore*/) : Result::NOT_SUPPORTED; } diff --git a/update-base-files.sh b/update-base-files.sh index daaa53017b..d01847dd9e 100755 --- a/update-base-files.sh +++ b/update-base-files.sh @@ -41,9 +41,12 @@ hidl-gen $options \ android.hardware.graphics.common@1.2 # system/media +hidl-gen $options \ + -o $ANDROID_BUILD_TOP/system/media/audio/include/system/audio_common-base.h \ + android.hardware.audio.common@7.0 hidl-gen $options \ -o $ANDROID_BUILD_TOP/system/media/audio/include/system/audio-base.h \ - android.hardware.audio.common@2.0 + android.hardware.audio@7.0 hidl-gen $options \ -o $ANDROID_BUILD_TOP/system/media/audio/include/system/audio_effect-base.h \ - android.hardware.audio.effect@2.0 + android.hardware.audio.effect@7.0 -- GitLab From ac6cc1f97ee70717dacccf28faae8d7a9196b48e Mon Sep 17 00:00:00 2001 From: Marin Shalamanov Date: Fri, 23 Oct 2020 17:42:59 +0200 Subject: [PATCH 236/790] Clean ComposerClient cache on hotplug On subsequent hotplug connected event for a display SurfaceFlinger destroys the previous framebuffers and recreates them. When the new buffers are created ComposerClient still holds a handle to the old buffers and they are not destroyed. This way the new framebuffers may get allocated on non continuous memory causing garbled screens for the user. Bug: 160112047 Bug: 169255692 Test: 1. limit cma ion memory to 32 MB 2. flash device 3. plug hdmi out and in 4. verify that the display image is not garbled Change-Id: Idf7cdf7a070ffc83ecec34ac24c8a7d696f68aa6 --- .../include/composer-hal/2.1/ComposerClient.h | 92 +++++++++++++++---- .../2.1/utils/resources/ComposerResources.cpp | 36 ++++++++ .../2.1/ComposerResources.h | 7 +- 3 files changed, 118 insertions(+), 17 deletions(-) diff --git a/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerClient.h b/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerClient.h index 47ead41fb0..3d74af4a41 100644 --- a/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerClient.h +++ b/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerClient.h @@ -87,19 +87,28 @@ class ComposerClientImpl : public Interface { class HalEventCallback : public Hal::EventCallback { public: - HalEventCallback(const sp callback, ComposerResources* resources) - : mCallback(callback), mResources(resources) {} - - void onHotplug(Display display, IComposerCallback::Connection connected) { - if (connected == IComposerCallback::Connection::CONNECTED) { - mResources->addPhysicalDisplay(display); - } else if (connected == IComposerCallback::Connection::DISCONNECTED) { - mResources->removeDisplay(display); - } - - auto ret = mCallback->onHotplug(display, connected); - ALOGE_IF(!ret.isOk(), "failed to send onHotplug: %s", ret.description().c_str()); - } + HalEventCallback(Hal* hal, const sp callback, + ComposerResources* resources) + : mHal(hal), mCallback(callback), mResources(resources) {} + + void onHotplug(Display display, IComposerCallback::Connection connected) { + if (connected == IComposerCallback::Connection::CONNECTED) { + if (mResources->hasDisplay(display)) { + // This is a subsequent hotplug "connected" for a display. This signals a + // display change and thus the framework may want to reallocate buffers. We + // need to free all cached handles, since they are holding a strong reference + // to the underlying buffers. + cleanDisplayResources(display); + mResources->removeDisplay(display); + } + mResources->addPhysicalDisplay(display); + } else if (connected == IComposerCallback::Connection::DISCONNECTED) { + mResources->removeDisplay(display); + } + + auto ret = mCallback->onHotplug(display, connected); + ALOGE_IF(!ret.isOk(), "failed to send onHotplug: %s", ret.description().c_str()); + } void onRefresh(Display display) { mResources->setDisplayMustValidateState(display, true); @@ -113,13 +122,64 @@ class ComposerClientImpl : public Interface { } protected: - const sp mCallback; - ComposerResources* const mResources; + Hal* const mHal; + const sp mCallback; + ComposerResources* const mResources; + + void cleanDisplayResources(Display display) { + size_t cacheSize; + Error err = mResources->getDisplayClientTargetCacheSize(display, &cacheSize); + if (err == Error::NONE) { + for (int slot = 0; slot < cacheSize; slot++) { + ComposerResources::ReplacedHandle replacedBuffer(/*isBuffer*/ true); + // Replace the buffer slots with NULLs. Keep the old handle until it is + // replaced in ComposerHal, otherwise we risk leaving a dangling pointer. + const native_handle_t* clientTarget = nullptr; + err = mResources->getDisplayClientTarget(display, slot, /*useCache*/ true, + /*rawHandle*/ nullptr, &clientTarget, + &replacedBuffer); + if (err != Error::NONE) { + continue; + } + const std::vector damage; + err = mHal->setClientTarget(display, clientTarget, /*fence*/ -1, 0, damage); + ALOGE_IF(err != Error::NONE, + "Can't clean slot %d of the client target buffer" + "cache for display %" PRIu64, + slot, display); + } + } else { + ALOGE("Can't clean client target cache for display %" PRIu64, display); + } + + err = mResources->getDisplayOutputBufferCacheSize(display, &cacheSize); + if (err == Error::NONE) { + for (int slot = 0; slot < cacheSize; slot++) { + // Replace the buffer slots with NULLs. Keep the old handle until it is + // replaced in ComposerHal, otherwise we risk leaving a dangling pointer. + ComposerResources::ReplacedHandle replacedBuffer(/*isBuffer*/ true); + const native_handle_t* outputBuffer = nullptr; + err = mResources->getDisplayOutputBuffer(display, slot, /*useCache*/ true, + /*rawHandle*/ nullptr, &outputBuffer, + &replacedBuffer); + if (err != Error::NONE) { + continue; + } + err = mHal->setOutputBuffer(display, outputBuffer, /*fence*/ -1); + ALOGE_IF(err != Error::NONE, + "Can't clean slot %d of the output buffer cache" + "for display %" PRIu64, + slot, display); + } + } else { + ALOGE("Can't clean output buffer cache for display %" PRIu64, display); + } + } }; Return registerCallback(const sp& callback) override { // no locking as we require this function to be called only once - mHalEventCallback = std::make_unique(callback, mResources.get()); + mHalEventCallback = std::make_unique(mHal, callback, mResources.get()); mHal->registerEventCallback(mHalEventCallback.get()); return Void(); } diff --git a/graphics/composer/2.1/utils/resources/ComposerResources.cpp b/graphics/composer/2.1/utils/resources/ComposerResources.cpp index 21f60355f8..e52bf7124a 100644 --- a/graphics/composer/2.1/utils/resources/ComposerResources.cpp +++ b/graphics/composer/2.1/utils/resources/ComposerResources.cpp @@ -144,6 +144,10 @@ ComposerHandleCache::~ComposerHandleCache() { } } +size_t ComposerHandleCache::getCacheSize() const { + return mHandles.size(); +} + bool ComposerHandleCache::initCache(HandleType type, uint32_t cacheSize) { // already initialized if (mHandleType != HandleType::INVALID) { @@ -220,6 +224,14 @@ bool ComposerDisplayResource::initClientTargetCache(uint32_t cacheSize) { return mClientTargetCache.initCache(ComposerHandleCache::HandleType::BUFFER, cacheSize); } +size_t ComposerDisplayResource::getClientTargetCacheSize() const { + return mClientTargetCache.getCacheSize(); +} + +size_t ComposerDisplayResource::getOutputBufferCacheSize() const { + return mOutputBufferCache.getCacheSize(); +} + bool ComposerDisplayResource::isVirtual() const { return mType == DisplayType::VIRTUAL; } @@ -293,6 +305,10 @@ void ComposerResources::clear(RemoveDisplay removeDisplay) { mDisplayResources.clear(); } +bool ComposerResources::hasDisplay(Display display) { + return mDisplayResources.count(display) > 0; +} + Error ComposerResources::addPhysicalDisplay(Display display) { auto displayResource = createDisplayResource(ComposerDisplayResource::DisplayType::PHYSICAL, 0); @@ -327,6 +343,26 @@ Error ComposerResources::setDisplayClientTargetCacheSize(Display display, : Error::BAD_PARAMETER; } +Error ComposerResources::getDisplayClientTargetCacheSize(Display display, size_t* outCacheSize) { + std::lock_guard lock(mDisplayResourcesMutex); + ComposerDisplayResource* displayResource = findDisplayResourceLocked(display); + if (!displayResource) { + return Error::BAD_DISPLAY; + } + *outCacheSize = displayResource->getClientTargetCacheSize(); + return Error::NONE; +} + +Error ComposerResources::getDisplayOutputBufferCacheSize(Display display, size_t* outCacheSize) { + std::lock_guard lock(mDisplayResourcesMutex); + ComposerDisplayResource* displayResource = findDisplayResourceLocked(display); + if (!displayResource) { + return Error::BAD_DISPLAY; + } + *outCacheSize = displayResource->getOutputBufferCacheSize(); + return Error::NONE; +} + Error ComposerResources::addLayer(Display display, Layer layer, uint32_t bufferCacheSize) { auto layerResource = createLayerResource(bufferCacheSize); diff --git a/graphics/composer/2.1/utils/resources/include/composer-resources/2.1/ComposerResources.h b/graphics/composer/2.1/utils/resources/include/composer-resources/2.1/ComposerResources.h index df5513ea0a..de78a59e91 100644 --- a/graphics/composer/2.1/utils/resources/include/composer-resources/2.1/ComposerResources.h +++ b/graphics/composer/2.1/utils/resources/include/composer-resources/2.1/ComposerResources.h @@ -74,6 +74,7 @@ class ComposerHandleCache { ComposerHandleCache& operator=(const ComposerHandleCache&) = delete; bool initCache(HandleType type, uint32_t cacheSize); + size_t getCacheSize() const; Error lookupCache(uint32_t slot, const native_handle_t** outHandle); Error updateCache(uint32_t slot, const native_handle_t* handle, const native_handle** outReplacedHandle); @@ -120,7 +121,8 @@ class ComposerDisplayResource { uint32_t outputBufferCacheSize); bool initClientTargetCache(uint32_t cacheSize); - + size_t getClientTargetCacheSize() const; + size_t getOutputBufferCacheSize() const; bool isVirtual() const; Error getClientTarget(uint32_t slot, bool fromCache, const native_handle_t* inHandle, @@ -162,12 +164,15 @@ class ComposerResources { std::function& layers)>; void clear(RemoveDisplay removeDisplay); + bool hasDisplay(Display display); Error addPhysicalDisplay(Display display); Error addVirtualDisplay(Display display, uint32_t outputBufferCacheSize); Error removeDisplay(Display display); Error setDisplayClientTargetCacheSize(Display display, uint32_t clientTargetCacheSize); + Error getDisplayClientTargetCacheSize(Display display, size_t* outCacheSize); + Error getDisplayOutputBufferCacheSize(Display display, size_t* outCacheSize); Error addLayer(Display display, Layer layer, uint32_t bufferCacheSize); Error removeLayer(Display display, Layer layer); -- GitLab From 60e4a0b00447888ea95aacd309b50469d2dbb3df Mon Sep 17 00:00:00 2001 From: Benjamin Schwartz Date: Mon, 26 Oct 2020 17:31:30 -0700 Subject: [PATCH 237/790] power/stats: Add duration field to EnergyMeasurement Bug: 168831752 Test: dumpsys android.hardware.power.stats.IPowerStats/default Change-Id: Ie588854d8bbe24c1c3492d547ede4aa249b1d50f --- .../android/hardware/power/stats/EnergyMeasurement.aidl | 1 + .../android/hardware/power/stats/EnergyMeasurement.aidl | 8 ++++++-- .../aidl/android/hardware/power/stats/IPowerStats.aidl | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyMeasurement.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyMeasurement.aidl index 341909e180..4d56ccf379 100644 --- a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyMeasurement.aidl +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyMeasurement.aidl @@ -20,5 +20,6 @@ package android.hardware.power.stats; parcelable EnergyMeasurement { int channelId; long timestampMs; + long durationMs; long energyUWs; } diff --git a/power/stats/aidl/android/hardware/power/stats/EnergyMeasurement.aidl b/power/stats/aidl/android/hardware/power/stats/EnergyMeasurement.aidl index f873849303..d81914d1f0 100644 --- a/power/stats/aidl/android/hardware/power/stats/EnergyMeasurement.aidl +++ b/power/stats/aidl/android/hardware/power/stats/EnergyMeasurement.aidl @@ -23,11 +23,15 @@ parcelable EnergyMeasurement { */ int channelId; /** - * Time since boot in milliseconds + * Approximate time of data capture in millseconds since boot */ long timestampMs; /** - * Accumulated energy since boot in microwatt-seconds (uWs) + * Duration in milliseconds that energy has been accumulated + */ + long durationMs; + /** + * Accumulated energy in microwatt-seconds (uWs) */ long energyUWs; } diff --git a/power/stats/aidl/android/hardware/power/stats/IPowerStats.aidl b/power/stats/aidl/android/hardware/power/stats/IPowerStats.aidl index 85a2ce0093..05e2004b67 100644 --- a/power/stats/aidl/android/hardware/power/stats/IPowerStats.aidl +++ b/power/stats/aidl/android/hardware/power/stats/IPowerStats.aidl @@ -96,7 +96,7 @@ interface IPowerStats { ChannelInfo[] getEnergyMeterInfo(); /** - * Reports accumulated energy since boot for each specified channel. + * Reports accumulated energy for each specified channel. * * @param channelIds IDs of channels for which data is requested. * Passing an empty list will return energy measurements for all available channels. -- GitLab From 990cc41da395a199994f0b72560c821158263ad9 Mon Sep 17 00:00:00 2001 From: Jack Yu Date: Fri, 23 Oct 2020 17:12:20 -0700 Subject: [PATCH 238/790] Added global retry support The retry timer suggested by the network will persist accross network requests. Also changed the retry timer to a 64-bit value to be consistent with types used in Android time APIs. Test: FrameworksTelephonytests Fix: 159672248 Change-Id: I763afdf34378512c60c0838830cb84875b1c66f0 --- radio/1.6/types.hal | 71 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 69 insertions(+), 2 deletions(-) diff --git a/radio/1.6/types.hal b/radio/1.6/types.hal index 07b49771c5..2e2e401b71 100644 --- a/radio/1.6/types.hal +++ b/radio/1.6/types.hal @@ -18,7 +18,10 @@ package android.hardware.radio@1.6; import @1.0::RadioError; import @1.0::RadioResponseType; -import @1.5::SetupDataCallResult; +import @1.4::DataCallFailCause; +import @1.4::DataConnActiveStatus; +import @1.4::PdpProtocolType; +import @1.5::LinkAddress; import android.hidl.safe_union@1.0::Monostate; @@ -240,8 +243,72 @@ enum HandoverFailureMode : int32_t { NO_FALLBACK_RETRY_SETUP_NORMAL = 3 }; +/** + * Overwritten from @1.5::SetupDataCallResult in order to change the suggestedRetryTime + * to 64-bit value. In the future, this must be extended instead of overwritten. + * Also added defaultQos, qosSessions, and handoverFailureMode in this version. + */ struct SetupDataCallResult { - @1.5::SetupDataCallResult base; + /** Data call fail cause. DataCallFailCause.NONE if no error. */ + DataCallFailCause cause; + + /** + * If cause is not DataCallFailCause.NONE, this field indicates the network suggested data + * retry back-off time in milliseconds. Negative value indicates network does not give any + * suggestion. 0 indicates retry should be performed immediately. 0x7fffffffffffffff indicates + * the device should not retry data setup anymore. + */ + uint64_t suggestedRetryTime; + + /** Context ID, uniquely identifies this data connection. */ + int32_t cid; + + /** Data connection active status. */ + DataConnActiveStatus active; + + /** + * PDP protocol type. If cause is DataCallFailCause.ONLY_SINGLE_BEARER_ALLOWED, this is the + * protocol type supported, such as "IP" or "IPV6". + */ + PdpProtocolType type; + + /** The network interface name. */ + string ifname; + + /** + * List of link address. + */ + vec addresses; + + /** + * List of DNS server addresses, e.g., "192.0.1.3" or "192.0.1.11 2001:db8::1". Empty if no dns + * server addresses returned. + */ + vec dnses; + + /** + * List of default gateway addresses, e.g., "192.0.1.3" or "192.0.1.11 2001:db8::1". + * When empty, the addresses represent point to point connections. + */ + vec gateways; + + /** + * List of P-CSCF(Proxy Call State Control Function) addresses via PCO(Protocol Configuration + * Option), e.g., "2001:db8::1 2001:db8::2 2001:db8::3". Empty if not IMS client. + */ + vec pcscf; + + /** + * MTU received from network for IPv4. + * Value <= 0 means network has either not sent a value or sent an invalid value. + */ + int32_t mtuV4; + + /** + * MTU received from network for IPv6. + * Value <= 0 means network has either not sent a value or sent an invalid value. + */ + int32_t mtuV6; /** Default bearer QoS. Applicable to LTE and NR */ Qos defaultQos; -- GitLab From 343f95e23e84b3028cc3f9c2b11d972b09c73095 Mon Sep 17 00:00:00 2001 From: Sasha Kuznetsov Date: Mon, 28 Sep 2020 13:01:14 -0700 Subject: [PATCH 239/790] Clarifiy ADR states in documentation Bug: 167930284 Test: n/a Change-Id: Ifa0633b2cfa7bb80e32d2c68d70992bc1b0c5461 --- current.txt | 2 + gnss/1.0/IGnssMeasurementCallback.hal | 57 ++++++++++++++++++++++++++- gnss/1.1/IGnssMeasurementCallback.hal | 12 +++++- 3 files changed, 69 insertions(+), 2 deletions(-) diff --git a/current.txt b/current.txt index c9a923ec74..fc0cc07467 100644 --- a/current.txt +++ b/current.txt @@ -767,6 +767,8 @@ a64467bae843569f0d465c5be7f0c7a5b987985b55a3ef4794dd5afc68538650 android.hardwar 98592d193a717066facf91428426e5abe211e3bd718bc372e29fb944ddbe6e7c android.hardware.wifi.supplicant@1.3::types # ABI preserving changes to HALs during Android S +1ca372cd67d197df099e87616a613ba6ede6552638a603e18f86c8834302c3d1 android.hardware.gnss@1.0::IGnssMeasurementCallback +6a271e493907e8ba20912e42771bd0d99ae45431a851d5675ef9496d02510a34 android.hardware.gnss@1.1::IGnssMeasurementCallback 3da3ce039247872d95c6bd48621dbfdfa1c2d2a91a90f257862f87ee2bc46300 android.hardware.health@2.1::types cd84ab19c590e0e73dd2307b591a3093ee18147ef95e6d5418644463a6620076 android.hardware.neuralnetworks@1.2::IDevice 9625e85f56515ad2cf87b6a1847906db669f746ea4ab02cd3d4ca25abc9b0109 android.hardware.neuralnetworks@1.2::types diff --git a/gnss/1.0/IGnssMeasurementCallback.hal b/gnss/1.0/IGnssMeasurementCallback.hal index 2d44766987..d219af0bd1 100644 --- a/gnss/1.0/IGnssMeasurementCallback.hal +++ b/gnss/1.0/IGnssMeasurementCallback.hal @@ -106,8 +106,63 @@ interface IGnssMeasurementCallback { STATE_GLO_TOD_KNOWN = 1 << 15, }; - /** + /** * Flags indicating the Accumulated Delta Range's states. + * + * See the table below for a detailed interpretation of each state. + * + * +---------------------+-------------------+-----------------------------+ + * | ADR_STATE | Time of relevance | Interpretation | + * +---------------------+-------------------+-----------------------------+ + * | UNKNOWN | ADR(t) | No valid carrier phase | + * | | | information is available | + * | | | at time t. | + * +---------------------+-------------------+-----------------------------+ + * | VALID | ADR(t) | Valid carrier phase | + * | | | information is available | + * | | | at time t. This indicates | + * | | | that this measurement can | + * | | | be used as a reference for | + * | | | future measurements. | + * | | | However, to compare it to | + * | | | previous measurements to | + * | | | compute delta range, | + * | | | other bits should be | + * | | | checked. Specifically, it | + * | | | can be used for delta range | + * | | | computation if it is valid | + * | | | and has no reset or cycle | + * | | | slip at this epoch i.e. | + * | | | if VALID_BIT == 1 && | + * | | | CYCLE_SLIP_BIT == 0 && | + * | | | RESET_BIT == 0. | + * +---------------------+-------------------+-----------------------------+ + * | RESET | ADR(t) - ADR(t-1) | Carrier phase accumulation | + * | | | has been restarted between | + * | | | current time t and previous | + * | | | time t-1. This indicates | + * | | | that this measurement can | + * | | | be used as a reference for | + * | | | future measurements, but it | + * | | | should not be compared to | + * | | | previous measurements to | + * | | | compute delta range. | + * +---------------------+-------------------+-----------------------------+ + * | CYCLE_SLIP | ADR(t) - ADR(t-1) | Cycle slip(s) have been | + * | | | detected between the | + * | | | current time t and previous | + * | | | time t-1. This indicates | + * | | | that this measurement can | + * | | | be used as a reference for | + * | | | future measurements. | + * | | | Clients can use a | + * | | | measurement with a cycle | + * | | | slip to compute delta range | + * | | | against previous | + * | | | measurements at their own | + * | | | risk. | + * +---------------------+-------------------+-----------------------------+ + * */ @export(name="", value_prefix="GNSS_") enum GnssAccumulatedDeltaRangeState : uint16_t { diff --git a/gnss/1.1/IGnssMeasurementCallback.hal b/gnss/1.1/IGnssMeasurementCallback.hal index 5a60a56bdf..36841ee0e6 100644 --- a/gnss/1.1/IGnssMeasurementCallback.hal +++ b/gnss/1.1/IGnssMeasurementCallback.hal @@ -20,8 +20,18 @@ import @1.0::IGnssMeasurementCallback; /** The callback interface to report measurements from the HAL. */ interface IGnssMeasurementCallback extends @1.0::IGnssMeasurementCallback { - /** + /** * Flags indicating the Accumulated Delta Range's states. + * + * See the table below for a detailed interpretation of each state. This is + * a continuation of the table from 1.1/IGnssMeasurementCallback.hal. + * + * +---------------------+-------------------+-----------------------------+ + * | ADR_STATE | Time of relevance | Interpretation | + * +---------------------+-------------------+-----------------------------+ + * | HALF_CYCLE_RESOLVED | ADR(t) | Half cycle ambiguity is | + * | | | resolved at time t. | + * +---------------------+-------------------+-----------------------------+ */ enum GnssAccumulatedDeltaRangeState : @1.0::IGnssMeasurementCallback.GnssAccumulatedDeltaRangeState { -- GitLab From c279cafa2883f8cccbfd756cb187f48760f6eea6 Mon Sep 17 00:00:00 2001 From: Jordan Liu Date: Wed, 21 Oct 2020 16:28:40 -0700 Subject: [PATCH 240/790] Update CardState HAL and make setSimPower synchronous Bug: 171433370 Test: make; make vts Change-Id: I0d298209a00f5f194547b0d6e368baa44b0c18ec --- current.txt | 2 +- radio/1.0/types.hal | 8 +++- radio/1.6/IRadio.hal | 37 +++++++++++++++++++ radio/1.6/IRadioResponse.hal | 16 ++++++++ .../functional/radio_hidl_hal_utils_v1_6.h | 3 ++ radio/1.6/vts/functional/radio_response.cpp | 7 ++++ 6 files changed, 70 insertions(+), 3 deletions(-) diff --git a/current.txt b/current.txt index 27b2310d43..7ef176bab0 100644 --- a/current.txt +++ b/current.txt @@ -773,7 +773,7 @@ a64467bae843569f0d465c5be7f0c7a5b987985b55a3ef4794dd5afc68538650 android.hardwar cd84ab19c590e0e73dd2307b591a3093ee18147ef95e6d5418644463a6620076 android.hardware.neuralnetworks@1.2::IDevice 9625e85f56515ad2cf87b6a1847906db669f746ea4ab02cd3d4ca25abc9b0109 android.hardware.neuralnetworks@1.2::types 9e758e208d14f7256e0885d6d8ad0b61121b21d8c313864f981727ae55bffd16 android.hardware.neuralnetworks@1.3::types -7da2707d4cf93818eaf8038eb65e2180116a399c310e594a00935c5c981aa340 android.hardware.radio@1.0::types +0f53d70e1eadf8d987766db4bf6ae2048004682168f4cab118da576787def3fa android.hardware.radio@1.0::types 38d65fb20c60a5b823298560fc0825457ecdc49603a4b4e94bf81511790737da android.hardware.radio@1.4::types 954c334efd80e8869b66d1ce5fe2755712d96ba4b3c38d415739c330af5fb4cb android.hardware.radio@1.5::types diff --git a/radio/1.0/types.hal b/radio/1.0/types.hal index 025aa7ccca..cafa5a62d1 100644 --- a/radio/1.0/types.hal +++ b/radio/1.0/types.hal @@ -166,11 +166,15 @@ enum RestrictedState : int32_t { }; enum CardState : int32_t { + /* card is physically absent from device. (Some old modems use CardState.ABSENT when the SIM + is powered off. This is no longer correct, however the platform will still support this + legacy behavior.) */ ABSENT, + /* card is inserted in the device */ PRESENT, ERROR, - RESTRICTED, // card is present but not usable due to carrier - // restrictions + /* card is present but not usable due to carrier restrictions */ + RESTRICTED, }; enum PinState : int32_t { diff --git a/radio/1.6/IRadio.hal b/radio/1.6/IRadio.hal index ca40a17b24..66007b48ac 100644 --- a/radio/1.6/IRadio.hal +++ b/radio/1.6/IRadio.hal @@ -19,6 +19,7 @@ package android.hardware.radio@1.6; import @1.0::CdmaSmsMessage; import @1.0::GsmSmsMessage; +import @1.1::CardPowerState; import @1.2::DataRequestReason; import @1.5::IRadio; import @1.5::AccessNetwork; @@ -182,6 +183,42 @@ interface IRadio extends @1.5::IRadio { */ oneway sendCdmaSmsExpectMore_1_6(int32_t serial, CdmaSmsMessage sms); + /** + * Set SIM card power state. + * Request is used to power off or power on the card. It should not generate + * a CardState.CARDSTATE_ABSENT indication, since the SIM is still physically + * inserted. + * + * @param serial Serial number of request + * @param powerUp POWER_DOWN if powering down the SIM card, + * POWER_UP if powering up the SIM card, + * POWER_UP_PASS_THROUGH if powering up the SIM card in + * pass through mode. + * + * When SIM card is in POWER_UP_PASS_THROUGH, the modem does not send + * any command to it (for example SELECT of MF, or TERMINAL + * CAPABILITY), and the SIM card is controlled completely by Telephony + * sending APDUs directly. The SIM card state must be + * RIL_CARDSTATE_PRESENT and the number of card apps will be 0. + * No new error code is generated. Emergency calls are supported in + * the same way as if the SIM card is absent. + * Pass-through mode is valid only for the specific card session where + * it is activated, and normal behavior occurs at the next SIM + * initialization, unless POWER_UP_PASS_THROUGH is requested again. + * + * The device is required to power down the SIM card before it can + * switch the mode between POWER_UP and POWER_UP_PASS_THROUGH. + * At device power up, the SIM interface is powered up automatically. + * Each subsequent request to this method is processed only after the + * completion of the previous one. + * + * Response callback is IRadioResponse.setSimCardPowerResponse_1_6(). + * Note that this differs from setSimCardPower_1_1 in that the response + * callback should only be sent once the device has finished executing + * the request (the SIM has finished powering on or off). + */ + oneway setSimCardPower_1_6(int32_t serial, CardPowerState powerUp); + /** * Enable or disable E-UTRA-NR dual connectivity. If disabled then UE will not connect * to secondary carrier. diff --git a/radio/1.6/IRadioResponse.hal b/radio/1.6/IRadioResponse.hal index 4ff7e47f12..bc6db11d56 100644 --- a/radio/1.6/IRadioResponse.hal +++ b/radio/1.6/IRadioResponse.hal @@ -201,6 +201,22 @@ interface IRadioResponse extends @1.5::IRadioResponse { */ oneway sendCdmaSmsExpectMoreResponse_1_6(RadioResponseInfo info, SendSmsResult sms); + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_ARGUMENTS + * RadioError:SIM_ERR (indicates a timeout or other issue making the SIM unresponsive) + * + * Note that this differs from setSimCardPowerResponse_1_1 in that the response + * should only be sent once the request from setSimCardPower_1_6 is complete + * (the SIM has finished powering on or off). + */ + oneway setSimCardPowerResponse_1_6(RadioResponseInfo info); + /** * @param info Response info struct containing response type, serial no. and error * diff --git a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h index 784bcd91e8..553e5b7daa 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h +++ b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h @@ -763,6 +763,9 @@ class RadioResponse_v1_6 : public ::android::hardware::radio::V1_6::IRadioRespon const ::android::hardware::radio::V1_6::RadioResponseInfo& info, const SendSmsResult& sms); + Return setSimCardPowerResponse_1_6( + const ::android::hardware::radio::V1_6::RadioResponseInfo& info); + Return sendCdmaSmsExpectMoreResponse_1_6( const ::android::hardware::radio::V1_6::RadioResponseInfo& info, const SendSmsResult& sms); diff --git a/radio/1.6/vts/functional/radio_response.cpp b/radio/1.6/vts/functional/radio_response.cpp index ffa384ed9b..c684584370 100644 --- a/radio/1.6/vts/functional/radio_response.cpp +++ b/radio/1.6/vts/functional/radio_response.cpp @@ -1097,6 +1097,13 @@ Return RadioResponse_v1_6::sendCdmaSmsResponse_1_6( return Void(); } +Return RadioResponse_v1_6::setSimCardPowerResponse_1_6( + const ::android::hardware::radio::V1_6::RadioResponseInfo& info) { + rspInfo = info; + parent_v1_6.notify(info.serial); + return Void(); +} + Return RadioResponse_v1_6::sendCdmaSmsExpectMoreResponse_1_6( const ::android::hardware::radio::V1_6::RadioResponseInfo& info, const SendSmsResult& sms) { -- GitLab From 961125f904086ab3dbcfb98db03eda3d6324efd8 Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Thu, 29 Oct 2020 13:49:34 -0700 Subject: [PATCH 241/790] Add some invalid constants in Tuner HAL 1.1 Test: make Bug: 171866656 Change-Id: I799d45c77bab923869107ae178a979b8f55dc330 --- tv/tuner/1.1/types.hal | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tv/tuner/1.1/types.hal b/tv/tuner/1.1/types.hal index 4e677b525b..d4a14f916c 100644 --- a/tv/tuner/1.1/types.hal +++ b/tv/tuner/1.1/types.hal @@ -72,6 +72,18 @@ enum Constant : @1.0::Constant { * IFrontend.linkCiCam. */ INVALID_LTS_ID = 0xFFFFFFFF, + /** + * An invalid frontend ID. + */ + INVALID_FRONTEND_ID = 0xFFFFFFFF, + /** + * An invalid LNB ID. + */ + INVALID_LNB_ID = 0xFFFFFFFF, + /** + * An invalid key token. It is used to remove the current key from the descrambler. + */ + INVALID_KEYTOKEN = 0x00, }; @export -- GitLab From 996a86c5d138258c3afd17501d1143ef347f2a3b Mon Sep 17 00:00:00 2001 From: Daniel Bright Date: Mon, 26 Oct 2020 11:34:53 -0700 Subject: [PATCH 242/790] Add HAL for pdu session id support * Add in HAL support for AOSP allocating pdu session ids from modem * Add in HAL support that notifies modem when a handover has begun and was cannceled Test: N/A Bug: 161572859 Change-Id: I2771b4773381ba68f482a80e743bdbb05a8e59d1 --- radio/1.6/IRadio.hal | 63 +++++++++++++++++++ radio/1.6/IRadioResponse.hal | 52 +++++++++++++++ radio/1.6/types.hal | 9 ++- .../functional/radio_hidl_hal_utils_v1_6.h | 15 +++++ radio/1.6/vts/functional/radio_response.cpp | 29 +++++++++ 5 files changed, 167 insertions(+), 1 deletion(-) diff --git a/radio/1.6/IRadio.hal b/radio/1.6/IRadio.hal index ca40a17b24..0e421cb86f 100644 --- a/radio/1.6/IRadio.hal +++ b/radio/1.6/IRadio.hal @@ -205,4 +205,67 @@ interface IRadio extends @1.5::IRadio { * Response callback is IRadioResponse.isNRDualConnectivityEnabledResponse() */ oneway isNrDualConnectivityEnabled(int32_t serial); + + /** + * Reserves an unallocated pdu session id from the pool of ids. + * + * The allocated id is returned in the response. + * + * When the id is no longer needed, call releasePduSessionId to + * return it to the pool. + * + * Reference: 3GPP TS 24.007 section 11.2.3.1b + * + * @param serial Serial number of request. + * + * Response function is IRadioResponse.allocatePduSessionIdResponse() + */ + oneway allocatePduSessionId(int32_t serial); + + /** + * Releases a pdu session id that was previously allocated using + * allocatePduSessionId. + * + * Reference: 3GPP TS 24.007 section 11.2.3.1b + * @param serial Serial number of request. + * @param id Pdu session id to release. + * + * Response function is IRadioResponse.releasePduSessionIdResponse() + */ + oneway releasePduSessionId(int32_t serial, int32_t id); + + /** + * Indicates that a handover to the IWLAN transport has begun. + * + * Any resources being transferred to the IWlan transport cannot be released while a + * handover is underway. For example, if a pdu session id needs to be + * transferred to IWlan, then, the modem should not release the id while + * the handover is in progress. + * + * If a handover was unsuccessful, then the framework calls IRadio::cancelHandover. + * The modem retains ownership over any of the resources being transferred to IWlan. + * + * If a handover was successful, the framework calls IRadio::deactivateDataCall with reason + * HANDOVER. The IWlan transport now owns the transferred resources and is responsible for + * releasing them. + * + * @param serial Serial number of request. + * @param id callId The identifier of the data call which is provided in SetupDataCallResult + * + * Response function is IRadioResponse.beginHandoverResponse() + */ + oneway beginHandover(int32_t serial, int32_t callId); + + /** + * Indicates that a handover was cancelled after a call to IRadio::beginHandover. + * + * Since the handover was unsuccessful, the modem retains ownership over any of the resources + * being transferred and is still responsible for releasing them. + * + * @param serial Serial number of request. + * @param id callId The identifier of the data call which is provided in SetupDataCallResult + * + * Response function is IRadioResponse.cancelHandoverResponse() + */ + oneway cancelHandover(int32_t serial, int32_t callId); }; diff --git a/radio/1.6/IRadioResponse.hal b/radio/1.6/IRadioResponse.hal index 4ff7e47f12..7708c46dca 100644 --- a/radio/1.6/IRadioResponse.hal +++ b/radio/1.6/IRadioResponse.hal @@ -222,4 +222,56 @@ interface IRadioResponse extends @1.5::IRadioResponse { * RadioError:INTERNAL_ERR */ oneway isNrDualConnectivityEnabledResponse(RadioResponseInfo info, bool isEnabled); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param id The allocated id. On an error, this is set to -1 + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:NO_RESOURCES- Indicates that no pdu session ids are available + * RadioError:REQUEST_NOT_SUPPORTED + */ + oneway allocatePduSessionIdResponse(RadioResponseInfo info, int32_t id); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:NO_RESOURCES + * RadioError:REQUEST_NOT_SUPPORTED + */ + oneway releasePduSessionIdResponse(RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:NO_RESOURCES + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_CALL_ID + */ + oneway beginHandoverResponse(RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param dcResponse Attributes of data call + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:NO_RESOURCES + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_CALL_ID + */ + oneway cancelHandoverResponse(RadioResponseInfo info); }; diff --git a/radio/1.6/types.hal b/radio/1.6/types.hal index 2e2e401b71..8f842a3989 100644 --- a/radio/1.6/types.hal +++ b/radio/1.6/types.hal @@ -22,7 +22,6 @@ import @1.4::DataCallFailCause; import @1.4::DataConnActiveStatus; import @1.4::PdpProtocolType; import @1.5::LinkAddress; - import android.hidl.safe_union@1.0::Monostate; struct QosBandwidth { @@ -321,6 +320,14 @@ struct SetupDataCallResult { /** Specifies the fallback mode on an IWLAN handover failure. */ HandoverFailureMode handoverFailureMode; + + /** + * The allocated pdu session id for this data call. + * A value of -1 means no pdu session id was attached to this call. + * + * Reference: 3GPP TS 24.007 section 11.2.3.1b + */ + int32_t pduSessionId; }; /** diff --git a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h index 784bcd91e8..7477c5425f 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h +++ b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h @@ -80,6 +80,9 @@ class RadioResponse_v1_6 : public ::android::hardware::radio::V1_6::IRadioRespon bool enableModemResponseToggle; bool isNRDualConnectivityEnabled; + // Pdu Session Id and Handover + int32_t allocatedPduSessionId; + ::android::hardware::hidl_bitfield<::android::hardware::radio::V1_4::RadioAccessFamily> networkTypeBitmapResponse; @@ -771,6 +774,18 @@ class RadioResponse_v1_6 : public ::android::hardware::radio::V1_6::IRadioRespon const ::android::hardware::radio::V1_6::RadioResponseInfo& info); Return isNrDualConnectivityEnabledResponse( const ::android::hardware::radio::V1_6::RadioResponseInfo& info, bool isEnabled); + + Return allocatePduSessionIdResponse( + const ::android::hardware::radio::V1_6::RadioResponseInfo& info, int32_t id); + + Return releasePduSessionIdResponse( + const ::android::hardware::radio::V1_6::RadioResponseInfo& info); + + Return beginHandoverResponse( + const ::android::hardware::radio::V1_6::RadioResponseInfo& info); + + Return cancelHandoverResponse( + const ::android::hardware::radio::V1_6::RadioResponseInfo& info); }; /* Callback class for radio indication */ diff --git a/radio/1.6/vts/functional/radio_response.cpp b/radio/1.6/vts/functional/radio_response.cpp index ffa384ed9b..1cdfeed816 100644 --- a/radio/1.6/vts/functional/radio_response.cpp +++ b/radio/1.6/vts/functional/radio_response.cpp @@ -1113,3 +1113,32 @@ Return RadioResponse_v1_6::isNrDualConnectivityEnabledResponse( parent_v1_6.notify(info.serial); return Void(); } + +Return RadioResponse_v1_6::allocatePduSessionIdResponse( + const ::android::hardware::radio::V1_6::RadioResponseInfo& info, int32_t id) { + rspInfo = info; + allocatedPduSessionId = id; + parent_v1_6.notify(info.serial); + return Void(); +} + +Return RadioResponse_v1_6::releasePduSessionIdResponse( + const ::android::hardware::radio::V1_6::RadioResponseInfo& info) { + rspInfo = info; + parent_v1_6.notify(info.serial); + return Void(); +} + +Return RadioResponse_v1_6::beginHandoverResponse( + const ::android::hardware::radio::V1_6::RadioResponseInfo& info) { + rspInfo = info; + parent_v1_6.notify(info.serial); + return Void(); +} + +Return RadioResponse_v1_6::cancelHandoverResponse( + const ::android::hardware::radio::V1_6::RadioResponseInfo& info) { + rspInfo = info; + parent_v1_6.notify(info.serial); + return Void(); +} -- GitLab From 1cc3ba235ceed3a605bce54cea8071d4f39eac1d Mon Sep 17 00:00:00 2001 From: Hai Shalom Date: Wed, 28 Oct 2020 18:09:26 -0700 Subject: [PATCH 243/790] HAL changes for Passpoint T&C Add SupplicantStaIfaceCallback v1.4 with support for the new Passpoint T&C notification callback. Bug: 171928337 Test: atest VtsHalWifiSupplicantV1_4TargetTest Change-Id: I14f88427a6112b6a097d168c00ece3e36a7bd82f --- wifi/supplicant/1.4/Android.bp | 1 + wifi/supplicant/1.4/ISupplicantStaIface.hal | 19 +++ .../1.4/ISupplicantStaIfaceCallback.hal | 40 +++++ .../supplicant_sta_iface_hidl_test.cpp | 149 +++++++++++++++++- 4 files changed, 208 insertions(+), 1 deletion(-) create mode 100644 wifi/supplicant/1.4/ISupplicantStaIfaceCallback.hal diff --git a/wifi/supplicant/1.4/Android.bp b/wifi/supplicant/1.4/Android.bp index 0a039de722..2867629d4c 100644 --- a/wifi/supplicant/1.4/Android.bp +++ b/wifi/supplicant/1.4/Android.bp @@ -10,6 +10,7 @@ hidl_interface { "ISupplicantStaIface.hal", "ISupplicantStaNetwork.hal", "ISupplicantStaNetworkCallback.hal", + "ISupplicantStaIfaceCallback.hal", ], interfaces: [ "android.hardware.wifi.supplicant@1.0", diff --git a/wifi/supplicant/1.4/ISupplicantStaIface.hal b/wifi/supplicant/1.4/ISupplicantStaIface.hal index 28ef912eae..68fd01d12e 100644 --- a/wifi/supplicant/1.4/ISupplicantStaIface.hal +++ b/wifi/supplicant/1.4/ISupplicantStaIface.hal @@ -17,6 +17,7 @@ package android.hardware.wifi.supplicant@1.4; import @1.0::SupplicantStatus; +import ISupplicantStaIfaceCallback; import @1.3::ISupplicantStaIface; /** @@ -36,4 +37,22 @@ interface ISupplicantStaIface extends @1.3::ISupplicantStaIface { getConnectionCapabilities_1_4() generates (SupplicantStatus status, ConnectionCapabilities capabilities); + /** + * Register for callbacks from this interface. + * + * These callbacks are invoked for events that are specific to this interface. + * Registration of multiple callback objects is supported. These objects must + * be automatically deleted when the corresponding client process is dead or + * if this interface is removed. + * + * @param callback An instance of the |ISupplicantStaIfaceCallback| HIDL + * interface object. + * @return status Status of the operation. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_UNKNOWN|, + * |SupplicantStatusCode.FAILURE_IFACE_INVALID| + */ + registerCallback_1_4(ISupplicantStaIfaceCallback callback) + generates (SupplicantStatus status); }; diff --git a/wifi/supplicant/1.4/ISupplicantStaIfaceCallback.hal b/wifi/supplicant/1.4/ISupplicantStaIfaceCallback.hal new file mode 100644 index 0000000000..20bce34dd7 --- /dev/null +++ b/wifi/supplicant/1.4/ISupplicantStaIfaceCallback.hal @@ -0,0 +1,40 @@ +/* + * 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. + */ + +package android.hardware.wifi.supplicant@1.4; + +import @1.3::ISupplicantStaIfaceCallback; +import @1.0::ISupplicantStaIfaceCallback.State; +import @1.0::Bssid; + +/** + * Callback Interface exposed by the supplicant service + * for each station mode interface (ISupplicantStaIface). + * + * Clients need to host an instance of this HIDL interface object and + * pass a reference of the object to the supplicant via the + * corresponding |ISupplicantStaIface.registerCallback_1_4| method. + */ +interface ISupplicantStaIfaceCallback extends @1.3::ISupplicantStaIfaceCallback { + /** + * Used to indicate a Hotspot 2.0 terms and conditions acceptance is requested from the user + * before allowing the device to get internet access. + * + * @param bssid BSSID of the access point. + * @param url URL of the T&C server. + */ + oneway onHs20TermsAndConditionsAcceptanceRequestedNotification(Bssid bssid, string url); +}; diff --git a/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp index 5b9c750c4e..fbf6445217 100644 --- a/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp +++ b/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -32,13 +33,22 @@ #include "supplicant_hidl_test_utils_1_4.h" using ::android::sp; +using ::android::hardware::hidl_array; +using ::android::hardware::hidl_string; +using ::android::hardware::hidl_vec; +using ::android::hardware::Return; using ::android::hardware::Void; using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatus; using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatusCode; - +using ::android::hardware::wifi::supplicant::V1_2::DppAkm; +using ::android::hardware::wifi::supplicant::V1_2::DppFailureCode; +using ::android::hardware::wifi::supplicant::V1_2::DppNetRole; +using ::android::hardware::wifi::supplicant::V1_2::DppProgressCode; +using ::android::hardware::wifi::supplicant::V1_3::DppSuccessCode; using ::android::hardware::wifi::supplicant::V1_4::ConnectionCapabilities; using ::android::hardware::wifi::supplicant::V1_4::ISupplicant; using ::android::hardware::wifi::supplicant::V1_4::ISupplicantStaIface; +using ::android::hardware::wifi::supplicant::V1_4::ISupplicantStaIfaceCallback; class SupplicantStaIfaceHidlTest : public SupplicantHidlTestBaseV1_4 { public: @@ -53,6 +63,133 @@ class SupplicantStaIfaceHidlTest : public SupplicantHidlTestBaseV1_4 { sp sta_iface_; }; +class IfaceCallback : public ISupplicantStaIfaceCallback { + Return onNetworkAdded(uint32_t /* id */) override { return Void(); } + Return onNetworkRemoved(uint32_t /* id */) override { return Void(); } + Return onStateChanged( + ISupplicantStaIfaceCallback::State /* newState */, + const hidl_array& /*bssid */, uint32_t /* id */, + const hidl_vec& /* ssid */) override { + return Void(); + } + Return onAnqpQueryDone( + const hidl_array& /* bssid */, + const ISupplicantStaIfaceCallback::AnqpData& /* data */, + const ISupplicantStaIfaceCallback::Hs20AnqpData& /* hs20Data */) + override { + return Void(); + } + virtual Return onHs20IconQueryDone( + const hidl_array& /* bssid */, + const hidl_string& /* fileName */, + const hidl_vec& /* data */) override { + return Void(); + } + virtual Return onHs20SubscriptionRemediation( + const hidl_array& /* bssid */, + ISupplicantStaIfaceCallback::OsuMethod /* osuMethod */, + const hidl_string& /* url*/) override { + return Void(); + } + Return onHs20TermsAndConditionsAcceptanceRequestedNotification( + const hidl_array& /* bssid */, + const hidl_string& /* url */) override { + return Void(); + } + Return onHs20DeauthImminentNotice( + const hidl_array& /* bssid */, uint32_t /* reasonCode */, + uint32_t /* reAuthDelayInSec */, + const hidl_string& /* url */) override { + return Void(); + } + Return onDisconnected(const hidl_array& /* bssid */, + bool /* locallyGenerated */, + ISupplicantStaIfaceCallback::ReasonCode + /* reasonCode */) override { + return Void(); + } + Return onAssociationRejected( + const hidl_array& /* bssid */, + ISupplicantStaIfaceCallback::StatusCode /* statusCode */, + bool /*timedOut */) override { + return Void(); + } + Return onAuthenticationTimeout( + const hidl_array& /* bssid */) override { + return Void(); + } + Return onBssidChanged( + ISupplicantStaIfaceCallback::BssidChangeReason /* reason */, + const hidl_array& /* bssid */) override { + return Void(); + } + Return onEapFailure() override { return Void(); } + Return onEapFailure_1_1( + ISupplicantStaIfaceCallback::EapErrorCode /* eapErrorCode */) override { + return Void(); + } + Return onEapFailure_1_3(uint32_t /* eapErrorCode */) override { + return Void(); + } + Return onWpsEventSuccess() override { return Void(); } + Return onWpsEventFail( + const hidl_array& /* bssid */, + ISupplicantStaIfaceCallback::WpsConfigError /* configError */, + ISupplicantStaIfaceCallback::WpsErrorIndication /* errorInd */) + override { + return Void(); + } + Return onWpsEventPbcOverlap() override { return Void(); } + Return onExtRadioWorkStart(uint32_t /* id */) override { + return Void(); + } + Return onExtRadioWorkTimeout(uint32_t /* id*/) override { + return Void(); + } + Return onDppSuccessConfigReceived( + const hidl_vec& /* ssid */, const hidl_string& /* password */, + const hidl_array& /* psk */, + DppAkm /* securityAkm */) override { + return Void(); + } + Return onDppSuccessConfigSent() override { return Void(); } + Return onDppProgress(DppProgressCode /* code */) override { + return Void(); + } + Return onDppFailure(DppFailureCode /* code */) override { + return Void(); + } + Return onDppSuccess(DppSuccessCode /* code */) override { + return Void(); + } + Return onDppProgress_1_3( + ::android::hardware::wifi::supplicant::V1_3::DppProgressCode /* code */) + override { + return Void(); + } + Return onDppFailure_1_3( + ::android::hardware::wifi::supplicant::V1_3::DppFailureCode /* code */, + const hidl_string& /* ssid */, const hidl_string& /* channelList */, + const hidl_vec& /* bandList */) override { + return Void(); + } + Return onPmkCacheAdded( + int64_t /* expirationTimeInSec */, + const hidl_vec& /* serializedEntry */) override { + return Void(); + } + Return onBssTmHandlingDone( + const ISupplicantStaIfaceCallback::BssTmData& /* data */) override { + return Void(); + } + Return onStateChanged_1_3( + ISupplicantStaIfaceCallback::State /* newState */, + const hidl_array& /*bssid */, uint32_t /* id */, + const hidl_vec& /* ssid */, bool /* filsHlpSent */) override { + return Void(); + } +}; + /* * getConnectionCapabilities_1_4 */ @@ -64,6 +201,16 @@ TEST_P(SupplicantStaIfaceHidlTest, GetConnectionCapabilities) { }); } +/* + * RegisterCallback_1_4 + */ +TEST_P(SupplicantStaIfaceHidlTest, RegisterCallback_1_4) { + sta_iface_->registerCallback_1_4( + new IfaceCallback(), [](const SupplicantStatus& status) { + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + }); +} + GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantStaIfaceHidlTest); INSTANTIATE_TEST_CASE_P( PerInstance, SupplicantStaIfaceHidlTest, -- GitLab From 898a2e3dd77973372a0f791701962552d74b6b8b Mon Sep 17 00:00:00 2001 From: Kevin Chyn Date: Fri, 30 Oct 2020 11:39:07 -0700 Subject: [PATCH 244/790] Add FIRST_FRAME_RECEIVED to AcquiredInfo Bug: 164922876 Test: m android.hardware.biometrics.face-update-api Change-Id: Ia98ff7099d125e6a015f67a0aefb43e006b7f727 --- .../hardware/biometrics/face/AcquiredInfo.aidl | 1 + .../hardware/biometrics/face/AcquiredInfo.aidl | 16 ++++++++++------ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl index 011b7112e5..88c066c617 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl @@ -41,4 +41,5 @@ enum AcquiredInfo { START = 20, SENSOR_DIRTY = 21, VENDOR = 22, + FIRST_FRAME_RECEIVED = 23, } diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl index fffb418c03..5897cdcc1a 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl @@ -198,10 +198,9 @@ enum AcquiredInfo { /** * This message represents the earliest message sent at the beginning of the authentication * pipeline. It is expected to be used to measure latency. For example, in a camera-based - * authentication system it's expected to be sent prior to camera initialization. Note this - * should be sent whenever authentication is restarted (see IBiometricsFace#userActivity). - * The framework will measure latency based on the time between the last START message and the - * onAuthenticated callback. + * authentication system it's expected to be sent prior to camera initialization. The framework + * will measure latency based on the time between the last START message and the onAuthenticated + * callback. */ START = 20, @@ -213,7 +212,12 @@ enum AcquiredInfo { /** * Vendor-specific acquisition message. See ISessionCallback#onAcquired vendorCode * documentation. - */ - VENDOR = 22 + */ + VENDOR = 22, + + /** + * The first frame from the camera has been received. + */ + FIRST_FRAME_RECEIVED = 23 } -- GitLab From 063094e1a795a84f950a453a0fea190e7963b023 Mon Sep 17 00:00:00 2001 From: Enrico Granata Date: Fri, 30 Oct 2020 14:42:49 -0600 Subject: [PATCH 245/790] Check the fd handle before attempting to use it in GNSS HAL Bug: 171851344 Test: run vts -a x86 -m vts_ibase_test -t VtsHalBaseV1_0TargetTest#Debug Change-Id: Ieee0977812fe6a9a9ca4bb2fe9ab61899b4d0df5 --- gnss/common/utils/default/include/v2_1/GnssTemplate.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gnss/common/utils/default/include/v2_1/GnssTemplate.h b/gnss/common/utils/default/include/v2_1/GnssTemplate.h index 7c3c58abcd..cbf3933b7f 100644 --- a/gnss/common/utils/default/include/v2_1/GnssTemplate.h +++ b/gnss/common/utils/default/include/v2_1/GnssTemplate.h @@ -689,6 +689,10 @@ Return GnssTemplate::help(const hidl_handle& fd) { template Return GnssTemplate::debug(const hidl_handle& fd, const hidl_vec& options) { + if (fd == nullptr || fd->numFds == 0) { + return Void(); + } + if (options.size() == 0) { return help(fd); } else if (options[0] == "location") { -- GitLab From 72e0239ed6ea99494b6d87daae4bf6fbb291b292 Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Fri, 30 Oct 2020 15:22:53 +0800 Subject: [PATCH 246/790] wifi: fix old vts failure due to deprecated API Bug: 160643860 Test: atest VtsHalWifiSupplicantV1_0TargetTest Change-Id: If47c92981e9a13323bfe5be58e288a77b5adb722 --- wifi/supplicant/1.0/vts/functional/Android.bp | 1 + .../functional/supplicant_sta_network_hidl_test.cpp | 13 +++++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/wifi/supplicant/1.0/vts/functional/Android.bp b/wifi/supplicant/1.0/vts/functional/Android.bp index 6f282bb9d7..42efde451e 100644 --- a/wifi/supplicant/1.0/vts/functional/Android.bp +++ b/wifi/supplicant/1.0/vts/functional/Android.bp @@ -47,6 +47,7 @@ cc_test { "android.hardware.wifi.supplicant@1.1", "android.hardware.wifi.supplicant@1.2", "android.hardware.wifi.supplicant@1.3", + "android.hardware.wifi.supplicant@1.4", "android.hardware.wifi@1.0", "libgmock", "libwifi-system", diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_sta_network_hidl_test.cpp b/wifi/supplicant/1.0/vts/functional/supplicant_sta_network_hidl_test.cpp index 2b4d681017..5aaba22afc 100644 --- a/wifi/supplicant/1.0/vts/functional/supplicant_sta_network_hidl_test.cpp +++ b/wifi/supplicant/1.0/vts/functional/supplicant_sta_network_hidl_test.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -90,6 +91,8 @@ class SupplicantStaNetworkHidlTest : public SupplicantHidlTestBaseV1_0 { */ v1_3 = ::android::hardware::wifi::supplicant::V1_3:: ISupplicantStaNetwork::castFrom(sta_network_); + v1_4 = ::android::hardware::wifi::supplicant::V1_4:: + ISupplicantStaNetwork::castFrom(sta_network_); ssid_.assign(kTestSsidStr, kTestSsidStr + strlen(kTestSsidStr)); } @@ -111,6 +114,8 @@ class SupplicantStaNetworkHidlTest : public SupplicantHidlTestBaseV1_0 { sp<::android::hardware::wifi::supplicant::V1_3::ISupplicantStaNetwork> v1_3 = nullptr; + sp<::android::hardware::wifi::supplicant::V1_4::ISupplicantStaNetwork> + v1_4 = nullptr; // ISupplicantStaNetwork object used for all tests in this fixture. sp sta_network_; // SSID to use for various tests. @@ -151,8 +156,12 @@ TEST_P(SupplicantStaNetworkHidlTest, Create) { */ TEST_P(SupplicantStaNetworkHidlTest, RegisterCallback) { sta_network_->registerCallback( - new NetworkCallback(), [](const SupplicantStatus& status) { - EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + new NetworkCallback(), [&](const SupplicantStatus& status) { + if (nullptr != v1_4) { + EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code); + } else { + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + } }); } -- GitLab From 65caf76788acb107a6c82e5f867805bd01b56e26 Mon Sep 17 00:00:00 2001 From: lesl Date: Fri, 30 Oct 2020 16:45:25 +0800 Subject: [PATCH 247/790] wifi: Create 1.3::IfaceParams to support dual bands (AP+AP Part 1) 1. Add new 1.3::IfaceParams to support AP+AP. 2. Fix vts to match use the 1.3::IfaceParams But the test on dual APs mode needs to add after vendor Hal ready to create two interfaces. AP+AP Part 1 includes: 1. HIDL: Hostapd support dual bands/channels configuration 2. Framework: HostapdHal support only 3. Hostapd deamon: a. Support briged interface query b. Support config dual bands/channel c. Callback use bridge interface in dual APs mode. Bug: 162686273 Test: atest -c VtsHalWifiHostapdV1_3TargetTest Test: atest -c VtsHalWifiHostapdV1_2TargetTest Test: atest -c VtsHalWifiHostapdV1_1TargetTest Test: atest -c VtsHalWifiHostapdV1_0TargetTest Change-Id: I621b303c1e1f36996ca9b7720242f134bbe5fd75 --- wifi/hostapd/1.3/IHostapd.hal | 49 +++++++++++- .../1.3/vts/functional/hostapd_hidl_test.cpp | 77 ++++++++++++++----- 2 files changed, 106 insertions(+), 20 deletions(-) diff --git a/wifi/hostapd/1.3/IHostapd.hal b/wifi/hostapd/1.3/IHostapd.hal index 0309f3b63f..be6fe59a29 100644 --- a/wifi/hostapd/1.3/IHostapd.hal +++ b/wifi/hostapd/1.3/IHostapd.hal @@ -26,6 +26,53 @@ import IHostapdCallback; * Top-level object for managing SoftAPs. */ interface IHostapd extends @1.2::IHostapd { + + /** + * Parameters to control the channel selection for the interface. + */ + struct ChannelParams { + /** + * Baseline information as defined in HAL 1.2. + * + * Includes bandMask and acsChannelFreqRangesMhz + */ + @1.2::IHostapd.ChannelParams V1_2; + + /** + * Whether to enable ACS (Automatic Channel Selection) or not. + * The channel can be selected automatically at run time by setting + * this flag, which must enable the ACS survey based algorithm. + * + * Note: It is used instead of V1_0::ChannelParams.enableAcs inside + * V1_3::IfaceParams.V1_2.V1_1.V1_0. + */ + bool enableAcs; + + /** + * Channel number (IEEE 802.11) to use for the interface. + * If ACS is enabled, this field is ignored. + * + * Note: It is used instead of V1_0::ChannelParams.channel inside + * V1_3::IfaceParams.V1_2.V1_1.V1_0. + */ + uint32_t channel; + }; + + /** + * Parameters to use for setting up the dual access point interfaces. + */ + struct IfaceParams { + /** + * Baseline information as defined in HAL 1.2. + */ + @1.2::IHostapd.IfaceParams V1_2; + + /** + * The list of the channel params for the dual interfaces. + */ + vec channelParamsList; + }; + /** * Parameters to use for setting up the access point network. */ @@ -57,7 +104,7 @@ interface IHostapd extends @1.2::IHostapd { * |HostapdStatusCode.FAILURE_UNKNOWN|, * |HostapdStatusCode.FAILURE_IFACE_EXISTS| */ - addAccessPoint_1_3(@1.2::IHostapd.IfaceParams ifaceParams, NetworkParams nwParams) + addAccessPoint_1_3(IfaceParams ifaceParams, NetworkParams nwParams) generates (HostapdStatus status); /** diff --git a/wifi/hostapd/1.3/vts/functional/hostapd_hidl_test.cpp b/wifi/hostapd/1.3/vts/functional/hostapd_hidl_test.cpp index d6c750f6c7..9234a5bf92 100644 --- a/wifi/hostapd/1.3/vts/functional/hostapd_hidl_test.cpp +++ b/wifi/hostapd/1.3/vts/functional/hostapd_hidl_test.cpp @@ -95,7 +95,16 @@ class HostapdHidlTest iface_params; ::android::hardware::wifi::hostapd::V1_1::IHostapd::IfaceParams iface_params_1_1; - IHostapd::IfaceParams iface_params_1_2; + ::android::hardware::wifi::hostapd::V1_2::IHostapd::IfaceParams + iface_params_1_2; + IHostapd::IfaceParams iface_params_1_3; + + std::vector< + ::android::hardware::wifi::hostapd::V1_3::IHostapd::ChannelParams> + vec_channelParams; + + ::android::hardware::wifi::hostapd::V1_3::IHostapd::ChannelParams + channelParams_1_3; iface_params.ifaceName = getPrimaryWlanIfaceName(); iface_params.hwModeParams.enable80211N = true; @@ -111,23 +120,39 @@ class HostapdHidlTest iface_params_1_2.channelParams.bandMask = 0; iface_params_1_2.channelParams.bandMask |= IHostapd::BandMask::BAND_2_GHZ; - return iface_params_1_2; + + // Newly added attributes in V1_3 + channelParams_1_3.channel = iface_params.channelParams.channel; + channelParams_1_3.enableAcs = iface_params.channelParams.enableAcs; + channelParams_1_3.V1_2 = iface_params_1_2.channelParams; + + vec_channelParams.push_back(channelParams_1_3); + iface_params_1_3.V1_2 = iface_params_1_2; + iface_params_1_3.channelParamsList = vec_channelParams; + return iface_params_1_3; } IHostapd::IfaceParams getIfaceParamsWithAcs() { // First get the settings for WithoutAcs and then make changes - IHostapd::IfaceParams iface_params_1_2 = getIfaceParamsWithoutAcs(); - iface_params_1_2.V1_1.V1_0.channelParams.enableAcs = true; - iface_params_1_2.V1_1.V1_0.channelParams.acsShouldExcludeDfs = true; - iface_params_1_2.V1_1.V1_0.channelParams.channel = 0; - iface_params_1_2.channelParams.bandMask |= + IHostapd::IfaceParams iface_params_1_3 = getIfaceParamsWithoutAcs(); + iface_params_1_3.V1_2.V1_1.V1_0.channelParams.enableAcs = true; + iface_params_1_3.V1_2.V1_1.V1_0.channelParams.acsShouldExcludeDfs = + true; + iface_params_1_3.V1_2.V1_1.V1_0.channelParams.channel = 0; + iface_params_1_3.V1_2.channelParams.bandMask |= IHostapd::BandMask::BAND_5_GHZ; - - return iface_params_1_2; + iface_params_1_3.channelParamsList[0].channel = + iface_params_1_3.V1_2.V1_1.V1_0.channelParams.channel; + iface_params_1_3.channelParamsList[0].enableAcs = + iface_params_1_3.V1_2.V1_1.V1_0.channelParams.enableAcs; + iface_params_1_3.channelParamsList[0].V1_2 = + iface_params_1_3.V1_2.channelParams; + + return iface_params_1_3; } IHostapd::IfaceParams getIfaceParamsWithAcsAndFreqRange() { - IHostapd::IfaceParams iface_params_1_2 = getIfaceParamsWithAcs(); + IHostapd::IfaceParams iface_params_1_3 = getIfaceParamsWithAcs(); ::android::hardware::wifi::hostapd::V1_2::IHostapd::AcsFrequencyRange acsFrequencyRange; acsFrequencyRange.start = 2412; @@ -136,17 +161,23 @@ class HostapdHidlTest AcsFrequencyRange> vec_acsFrequencyRange; vec_acsFrequencyRange.push_back(acsFrequencyRange); - iface_params_1_2.channelParams.acsChannelFreqRangesMhz = + iface_params_1_3.V1_2.channelParams.acsChannelFreqRangesMhz = vec_acsFrequencyRange; - return iface_params_1_2; + iface_params_1_3.channelParamsList[0].V1_2 = + iface_params_1_3.V1_2.channelParams; + return iface_params_1_3; } IHostapd::IfaceParams getIfaceParamsWithAcsAndInvalidFreqRange() { - IHostapd::IfaceParams iface_params_1_2 = + IHostapd::IfaceParams iface_params_1_3 = getIfaceParamsWithAcsAndFreqRange(); - iface_params_1_2.channelParams.acsChannelFreqRangesMhz[0].start = 222; - iface_params_1_2.channelParams.acsChannelFreqRangesMhz[0].end = 999; - return iface_params_1_2; + iface_params_1_3.V1_2.channelParams.acsChannelFreqRangesMhz[0].start = + 222; + iface_params_1_3.V1_2.channelParams.acsChannelFreqRangesMhz[0].end = + 999; + iface_params_1_3.channelParamsList[0].V1_2 = + iface_params_1_3.V1_2.channelParams; + return iface_params_1_3; } IHostapd::NetworkParams getOpenNwParams() { @@ -218,9 +249,12 @@ class HostapdHidlTest } IHostapd::IfaceParams getIfaceParamsWithInvalidChannel() { - IHostapd::IfaceParams iface_params_1_2 = getIfaceParamsWithoutAcs(); - iface_params_1_2.V1_1.V1_0.channelParams.channel = kIfaceInvalidChannel; - return iface_params_1_2; + IHostapd::IfaceParams iface_params_1_3 = getIfaceParamsWithoutAcs(); + iface_params_1_3.V1_2.V1_1.V1_0.channelParams.channel = + kIfaceInvalidChannel; + iface_params_1_3.channelParamsList[0].channel = + iface_params_1_3.V1_2.V1_1.V1_0.channelParams.channel; + return iface_params_1_3; } // IHostapd object used for all tests in this fixture. @@ -422,6 +456,11 @@ TEST_P(HostapdHidlTest, DisconnectClientWhenIfacAvailable) { EXPECT_EQ(HostapdStatusCode::FAILURE_CLIENT_UNKNOWN, status_1_2.code); } +/** + * AddAccessPointWithDualBandConfig should pass + */ +// TODO: Add it after VendorHal ready & add feature support check. + GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(HostapdHidlTest); INSTANTIATE_TEST_CASE_P( PerInstance, HostapdHidlTest, -- GitLab From ed5c514ed19aafdc6cc8c53f6d64bb40194ef053 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thi=C3=A9baud=20Weksteen?= Date: Fri, 21 Aug 2020 16:46:07 +0200 Subject: [PATCH 248/790] Add setAllowedNetworkTypeBitmap There are currently two methods that cover the network family types: setPreferredNetworkType and setPreferredNetworkTypeBitmap. They both serve a similar purpose and have been previously interpreted as a suggestion to the modem on the type of networks requested by the OS. This change introduces a new method (setAllowedNetworkTypeBitmap) which will coexist with these methods. This new method must be interpreted as a strict set of Radio Access Technology (RAT) that should be accepted by the modem. For instance, one may first use setAllowedNetworkTypeBitmap to exclude 2G technology from the list of usable RAT. Then, they may use setPreferredNetworkType to describe their preference for 4G. Test: mm Bug: 171791177 Change-Id: I7f5fdf9bf5a80c47e9ad838b740b2d6e40ffea60 --- radio/1.6/IRadio.hal | 15 +++++++++++++++ radio/1.6/IRadioResponse.hal | 16 ++++++++++++++++ .../vts/functional/radio_hidl_hal_utils_v1_6.h | 5 ++++- radio/1.6/vts/functional/radio_response.cpp | 7 +++++++ 4 files changed, 42 insertions(+), 1 deletion(-) diff --git a/radio/1.6/IRadio.hal b/radio/1.6/IRadio.hal index eb20542e7e..747b2f2ddc 100644 --- a/radio/1.6/IRadio.hal +++ b/radio/1.6/IRadio.hal @@ -21,6 +21,7 @@ import @1.0::CdmaSmsMessage; import @1.0::GsmSmsMessage; import @1.1::CardPowerState; import @1.2::DataRequestReason; +import @1.4::RadioAccessFamily; import @1.5::IRadio; import @1.5::AccessNetwork; import @1.5::DataProfileInfo; @@ -305,4 +306,18 @@ interface IRadio extends @1.5::IRadio { * Response function is IRadioResponse.cancelHandoverResponse() */ oneway cancelHandover(int32_t serial, int32_t callId); + + /** + * Requests to set the network type for searching and registering. + * + * Instruct the radio to *only* accept the types of network provided. This + * is stronger than setPreferredNetworkType which is a suggestion. + * + * @param serial Serial number of request. + * @param networkTypeBitmap a 32-bit bearer bitmap of RadioAccessFamily + * + * Response callbask is IRadioResponse.setNetworkTypeBitmapResponse() + */ + oneway setAllowedNetworkTypeBitmap( + uint32_t serial, bitfield networkTypeBitmap); }; diff --git a/radio/1.6/IRadioResponse.hal b/radio/1.6/IRadioResponse.hal index 07322be29b..523185eab0 100644 --- a/radio/1.6/IRadioResponse.hal +++ b/radio/1.6/IRadioResponse.hal @@ -290,4 +290,20 @@ interface IRadioResponse extends @1.5::IRadioResponse { * RadioError:INVALID_CALL_ID */ oneway cancelHandoverResponse(RadioResponseInfo info); + + /** + * Callback of IRadio.setAllowedNetworkTypeBitmap(int, bitfield) + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:MODE_NOT_SUPPORTED + * RadioError:INTERNAL_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:MODEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + */ + oneway setAllowedNetworkTypeBitmapResponse(RadioResponseInfo info); }; diff --git a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h index 850425dbe4..5682f11da4 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h +++ b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h @@ -58,7 +58,7 @@ using ::android::hardware::Void; class RadioHidlTest_v1_6; extern ::android::hardware::radio::V1_5::CardStatus cardStatus; -/* Callback class for radio response v1_5 */ +/* Callback class for radio response v1_6 */ class RadioResponse_v1_6 : public ::android::hardware::radio::V1_6::IRadioResponse { protected: RadioHidlTest_v1_6& parent_v1_6; @@ -789,6 +789,9 @@ class RadioResponse_v1_6 : public ::android::hardware::radio::V1_6::IRadioRespon Return cancelHandoverResponse( const ::android::hardware::radio::V1_6::RadioResponseInfo& info); + + Return setAllowedNetworkTypeBitmapResponse( + const ::android::hardware::radio::V1_6::RadioResponseInfo& info); }; /* Callback class for radio indication */ diff --git a/radio/1.6/vts/functional/radio_response.cpp b/radio/1.6/vts/functional/radio_response.cpp index fc56947f50..dc4f57db3d 100644 --- a/radio/1.6/vts/functional/radio_response.cpp +++ b/radio/1.6/vts/functional/radio_response.cpp @@ -1149,3 +1149,10 @@ Return RadioResponse_v1_6::cancelHandoverResponse( parent_v1_6.notify(info.serial); return Void(); } + +Return RadioResponse_v1_6::setAllowedNetworkTypeBitmapResponse( + const ::android::hardware::radio::V1_6::RadioResponseInfo& info) { + rspInfo = info; + parent_v1_6.notify(info.serial); + return Void(); +} -- GitLab From 9d9f970ee497c9ecd2cfbb7c8a59dcdd670cd669 Mon Sep 17 00:00:00 2001 From: Mikhail Naganov Date: Mon, 2 Nov 2020 19:56:48 +0000 Subject: [PATCH 249/790] audio: Add @export annotations to microphone-related enums This addresses long-standing TODOs in system/audio.h. Annotated the following enums: - AudioMicrophoneChannelMapping; - AudioMicrophoneLocation; - AudioMicrophoneDirectionality. This allows removing hand-written conversion functions since the values are guaranteed to match between HIDL and system/audio.h. Bug: 122858783 Test: m Change-Id: I2bf250ef9154a7ae86679afa566c80dfd01f1d5b --- audio/7.0/types.hal | 5 +- .../core/all-versions/default/Conversions.cpp | 52 ++----------------- 2 files changed, 7 insertions(+), 50 deletions(-) diff --git a/audio/7.0/types.hal b/audio/7.0/types.hal index 7c050c106a..6cac9c95fe 100644 --- a/audio/7.0/types.hal +++ b/audio/7.0/types.hal @@ -126,16 +126,18 @@ struct AudioMicrophoneCoordinate { * process (e.g. High Pass Filtering, dynamic compression) * Simple processing as constant gain adjustment must be DIRECT. */ +@export(name="audio_microphone_channel_mapping_t", value_prefix="AUDIO_MICROPHONE_CHANNEL_MAPPING_") enum AudioMicrophoneChannelMapping : uint32_t { UNUSED = 0, /* Channel not used */ DIRECT = 1, /* Channel used and signal not processed */ - PROCESSED = 2, /* Channel used and signal has some process */ + PROCESSED = 2, /* Channel used and signal has some processing */ }; /** * Enum to identify locations of microphones in regards to the body of the * android device. */ +@export(name="audio_microphone_location_t", value_prefix="AUDIO_MICROPHONE_LOCATION_") enum AudioMicrophoneLocation : uint32_t { UNKNOWN = 0, MAINBODY = 1, @@ -152,6 +154,7 @@ typedef int32_t AudioMicrophoneGroup; /** * Enum with standard polar patterns of microphones */ +@export(name="audio_microphone_directionality_t", value_prefix="AUDIO_MICROPHONE_DIRECTIONALITY_") enum AudioMicrophoneDirectionality : uint32_t { UNKNOWN = 0, OMNI = 1, diff --git a/audio/core/all-versions/default/Conversions.cpp b/audio/core/all-versions/default/Conversions.cpp index 0b6ad80a80..0db210a58a 100644 --- a/audio/core/all-versions/default/Conversions.cpp +++ b/audio/core/all-versions/default/Conversions.cpp @@ -93,52 +93,6 @@ status_t deviceAddressFromHal(audio_devices_t device, const char* halAddress, return OK; } -AudioMicrophoneChannelMapping halToChannelMapping(audio_microphone_channel_mapping_t mapping) { - switch (mapping) { - case AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED: - return AudioMicrophoneChannelMapping::UNUSED; - case AUDIO_MICROPHONE_CHANNEL_MAPPING_DIRECT: - return AudioMicrophoneChannelMapping::DIRECT; - case AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED: - return AudioMicrophoneChannelMapping::PROCESSED; - default: - ALOGE("Invalid channel mapping type: %d", mapping); - return AudioMicrophoneChannelMapping::UNUSED; - } -} - -AudioMicrophoneLocation halToLocation(audio_microphone_location_t location) { - switch (location) { - default: - case AUDIO_MICROPHONE_LOCATION_UNKNOWN: - return AudioMicrophoneLocation::UNKNOWN; - case AUDIO_MICROPHONE_LOCATION_MAINBODY: - return AudioMicrophoneLocation::MAINBODY; - case AUDIO_MICROPHONE_LOCATION_MAINBODY_MOVABLE: - return AudioMicrophoneLocation::MAINBODY_MOVABLE; - case AUDIO_MICROPHONE_LOCATION_PERIPHERAL: - return AudioMicrophoneLocation::PERIPHERAL; - } -} - -AudioMicrophoneDirectionality halToDirectionality(audio_microphone_directionality_t dir) { - switch (dir) { - default: - case AUDIO_MICROPHONE_DIRECTIONALITY_UNKNOWN: - return AudioMicrophoneDirectionality::UNKNOWN; - case AUDIO_MICROPHONE_DIRECTIONALITY_OMNI: - return AudioMicrophoneDirectionality::OMNI; - case AUDIO_MICROPHONE_DIRECTIONALITY_BI_DIRECTIONAL: - return AudioMicrophoneDirectionality::BI_DIRECTIONAL; - case AUDIO_MICROPHONE_DIRECTIONALITY_CARDIOID: - return AudioMicrophoneDirectionality::CARDIOID; - case AUDIO_MICROPHONE_DIRECTIONALITY_HYPER_CARDIOID: - return AudioMicrophoneDirectionality::HYPER_CARDIOID; - case AUDIO_MICROPHONE_DIRECTIONALITY_SUPER_CARDIOID: - return AudioMicrophoneDirectionality::SUPER_CARDIOID; - } -} - bool halToMicrophoneCharacteristics(MicrophoneInfo* pDst, const struct audio_microphone_characteristic_t& src) { bool status = false; @@ -150,15 +104,15 @@ bool halToMicrophoneCharacteristics(MicrophoneInfo* pDst, } pDst->channelMapping.resize(AUDIO_CHANNEL_COUNT_MAX); for (size_t ch = 0; ch < pDst->channelMapping.size(); ch++) { - pDst->channelMapping[ch] = halToChannelMapping(src.channel_mapping[ch]); + pDst->channelMapping[ch] = AudioMicrophoneChannelMapping(src.channel_mapping[ch]); } - pDst->location = halToLocation(src.location); + pDst->location = AudioMicrophoneLocation(src.location); pDst->group = (AudioMicrophoneGroup)src.group; pDst->indexInTheGroup = (uint32_t)src.index_in_the_group; pDst->sensitivity = src.sensitivity; pDst->maxSpl = src.max_spl; pDst->minSpl = src.min_spl; - pDst->directionality = halToDirectionality(src.directionality); + pDst->directionality = AudioMicrophoneDirectionality(src.directionality); pDst->frequencyResponse.resize(src.num_frequency_responses); for (size_t k = 0; k < src.num_frequency_responses; k++) { pDst->frequencyResponse[k].frequency = src.frequency_responses[0][k]; -- GitLab From 49c845ffa3f3bc29227fb8e6e1c62ef2cd4a6e92 Mon Sep 17 00:00:00 2001 From: Hayden Gomes Date: Tue, 27 Oct 2020 13:01:33 -0700 Subject: [PATCH 250/790] Adding AIDL version of AudioControl HAL - Updated APIs to use strings instead of enum for AudioUsages - Updated dumpsys commands to take strings for usages instead of integers Bug: b/170335834 Test: build and run VTS tests Change-Id: I1773383812e97e7dee6da2eba250ea842d59b8cb --- automotive/audiocontrol/aidl/Android.bp | 13 ++++ .../audiocontrol/AudioFocusChange.aidl | 29 +++++++ .../audiocontrol/IAudioControl.aidl | 25 ++++++ .../audiocontrol/IFocusListener.aidl | 23 ++++++ .../audiocontrol/AudioFocusChange.aidl | 33 ++++++++ .../audiocontrol/IAudioControl.aidl | 77 +++++++++++++++++++ .../audiocontrol/IFocusListener.aidl | 57 ++++++++++++++ .../compatibility_matrix.current.xml | 4 +- 8 files changed, 258 insertions(+), 3 deletions(-) create mode 100644 automotive/audiocontrol/aidl/Android.bp create mode 100644 automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioFocusChange.aidl create mode 100644 automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IAudioControl.aidl create mode 100644 automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IFocusListener.aidl create mode 100644 automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioFocusChange.aidl create mode 100644 automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IAudioControl.aidl create mode 100644 automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IFocusListener.aidl diff --git a/automotive/audiocontrol/aidl/Android.bp b/automotive/audiocontrol/aidl/Android.bp new file mode 100644 index 0000000000..f8240b1cc7 --- /dev/null +++ b/automotive/audiocontrol/aidl/Android.bp @@ -0,0 +1,13 @@ +// This is the expected build file, but it may not be right in all cases + +aidl_interface { + name: "android.hardware.automotive.audiocontrol", + vendor_available: true, + srcs: ["android/hardware/automotive/audiocontrol/*.aidl"], + stability: "vintf", + backend: { + java: { + sdk_version: "module_current", + }, + }, +} diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioFocusChange.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioFocusChange.aidl new file mode 100644 index 0000000000..3dc393a580 --- /dev/null +++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioFocusChange.aidl @@ -0,0 +1,29 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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.automotive.audiocontrol; +@Backing(type="int") @VintfStability +enum AudioFocusChange { + NONE = 0, + GAIN = 1, + GAIN_TRANSIENT = 2, + GAIN_TRANSIENT_MAY_DUCK = 3, + GAIN_TRANSIENT_EXCLUSIVE = 4, + LOSS = -1, + LOSS_TRANSIENT = -2, + LOSS_TRANSIENT_CAN_DUCK = -3, +} diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IAudioControl.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IAudioControl.aidl new file mode 100644 index 0000000000..6916846bcf --- /dev/null +++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IAudioControl.aidl @@ -0,0 +1,25 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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.automotive.audiocontrol; +@VintfStability +interface IAudioControl { + oneway void onAudioFocusChange(in String usage, in int zoneId, in android.hardware.automotive.audiocontrol.AudioFocusChange focusChange); + oneway void registerFocusListener(in android.hardware.automotive.audiocontrol.IFocusListener listener); + oneway void setBalanceTowardRight(in float value); + oneway void setFadeTowardFront(in float value); +} diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IFocusListener.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IFocusListener.aidl new file mode 100644 index 0000000000..f00f042a02 --- /dev/null +++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IFocusListener.aidl @@ -0,0 +1,23 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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.automotive.audiocontrol; +@VintfStability +interface IFocusListener { + oneway void abandonAudioFocus(in String usage, in int zoneId); + oneway void requestAudioFocus(in String usage, in int zoneId, in android.hardware.automotive.audiocontrol.AudioFocusChange focusGain); +} diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioFocusChange.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioFocusChange.aidl new file mode 100644 index 0000000000..fc35fa9048 --- /dev/null +++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioFocusChange.aidl @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.automotive.audiocontrol; + +/** + * Changes in audio focus that can be experienced + */ +@VintfStability +@Backing(type="int") +enum AudioFocusChange { + NONE = 0, + GAIN = 1, + GAIN_TRANSIENT = 2, + GAIN_TRANSIENT_MAY_DUCK = 3, + GAIN_TRANSIENT_EXCLUSIVE = 4, + LOSS = -1, // -1 * GAIN, + LOSS_TRANSIENT = -2, // -1 * GAIN_TRANSIENT, + LOSS_TRANSIENT_CAN_DUCK = -3, // -1 * GAIN_TRANSIENT_MAY_DUCK, +} \ No newline at end of file diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IAudioControl.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IAudioControl.aidl new file mode 100644 index 0000000000..0641691d9c --- /dev/null +++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IAudioControl.aidl @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.automotive.audiocontrol; + +import android.hardware.automotive.audiocontrol.AudioFocusChange; +import android.hardware.automotive.audiocontrol.IFocusListener; + +/** + * Interacts with the car's audio subsystem to manage audio sources and volumes + */ +@VintfStability +interface IAudioControl { + /** + * Notifies HAL of changes in audio focus status for focuses requested or abandoned by the HAL. + * + * This will be called in response to IFocusListener's requestAudioFocus and + * abandonAudioFocus, as well as part of any change in focus being held by the HAL due focus + * request from other activities or services. + * + * The HAL is not required to wait for an callback of AUDIOFOCUS_GAIN before playing audio, nor + * is it required to stop playing audio in the event of a AUDIOFOCUS_LOSS callback is received. + * + * @param usage The audio usage associated with the focus change {@code AttributeUsage}. See + * {@code audioUsage} in audio_policy_configuration.xsd for the list of allowed values. + * @param zoneId The identifier for the audio zone that the HAL is playing the stream in + * @param focusChange the AudioFocusChange that has occurred. + */ + oneway void onAudioFocusChange(in String usage, in int zoneId, in AudioFocusChange focusChange); + + /** + * Registers focus listener to be used by HAL for requesting and abandoning audio focus. + * + * It is expected that there will only ever be a single focus listener registered. If the + * observer dies, the HAL implementation must unregister observer automatically. If called when + * a listener is already registered, the existing one should be unregistered and replaced with + * the new listener. + * + * @param listener the listener interface. + */ + oneway void registerFocusListener(in IFocusListener listener); + + /** + * Control the right/left balance setting of the car speakers. + * + * This is intended to shift the speaker volume toward the right (+) or left (-) side of + * the car. 0.0 means "centered". +1.0 means fully right. -1.0 means fully left. + * + * A value outside the range -1 to 1 must be clamped by the implementation to the -1 to 1 + * range. + */ + oneway void setBalanceTowardRight(in float value); + + /** + * Control the fore/aft fade setting of the car speakers. + * + * This is intended to shift the speaker volume toward the front (+) or back (-) of the car. + * 0.0 means "centered". +1.0 means fully forward. -1.0 means fully rearward. + * + * A value outside the range -1 to 1 must be clamped by the implementation to the -1 to 1 + * range. + */ + oneway void setFadeTowardFront(in float value); +} \ No newline at end of file diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IFocusListener.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IFocusListener.aidl new file mode 100644 index 0000000000..b79295a6da --- /dev/null +++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IFocusListener.aidl @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.automotive.audiocontrol; + +import android.hardware.automotive.audiocontrol.AudioFocusChange; + +/** + * Callback interface for audio focus listener. + * + * For typical configuration, the listener the car audio service. + */ +@VintfStability +interface IFocusListener { + /** + * Called whenever HAL is abandoning focus as it is finished playing audio of a given usage in a + * specific zone. + * + * In response, IAudioControl#onAudioFocusChange will be called with focusChange status. This + * interaction is oneway to avoid blocking HAL so that it is not required to wait for a response + * before stopping audio playback. + * + * @param usage The audio usage for which the HAL is abandoning focus {@code AttributeUsage}. + * See {@code audioUsage} in audio_policy_configuration.xsd for the list of allowed values. + * @param zoneId The identifier for the audio zone that the HAL abandoning focus + */ + oneway void abandonAudioFocus(in String usage, in int zoneId); + + /** + * Called whenever HAL is requesting focus as it is starting to play audio of a given usage in a + * specified zone. + * + * In response, IAudioControl#onAudioFocusChange will be called with focusChange status. This + * interaction is oneway to avoid blocking HAL so that it is not required to wait for a response + * before playing audio. + * + * @param usage The audio usage associated with the focus request {@code AttributeUsage}. See + * {@code audioUsage} in audio_policy_configuration.xsd for the list of allowed values. + * @param zoneId The identifier for the audio zone where the HAL is requesting focus + * @param focusGain The AudioFocusChange associated with this request. Should be one of the + * following: GAIN, GAIN_TRANSIENT, GAIN_TRANSIENT_MAY_DUCK, GAIN_TRANSIENT_EXCLUSIVE. + */ + oneway void requestAudioFocus(in String usage, in int zoneId, in AudioFocusChange focusGain); +} \ No newline at end of file diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index d1d254b04a..57f390c055 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -35,10 +35,8 @@ default - + android.hardware.automotive.audiocontrol - 1.0 - 2.0 IAudioControl default -- GitLab From 3449e1c24c3f2d757c56ec5d17d70bbea84f724e Mon Sep 17 00:00:00 2001 From: Malcolm Chen Date: Mon, 2 Nov 2020 14:17:59 -0800 Subject: [PATCH 251/790] Skip togglingUiccApplicationsSimPresent if it's eSIM empty profile. Bug: 169802419 Test: run vts on dsds device. Change-Id: I2319aa6fe86bfc415b1d1ea0aaefb80f4c7ddff3 --- radio/1.5/vts/functional/radio_hidl_hal_api.cpp | 1 + 1 file changed, 1 insertion(+) 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 ca1593f031..7166654814 100644 --- a/radio/1.5/vts/functional/radio_hidl_hal_api.cpp +++ b/radio/1.5/vts/functional/radio_hidl_hal_api.cpp @@ -437,6 +437,7 @@ TEST_P(RadioHidlTest_v1_5, togglingUiccApplicationsSimAbsent) { TEST_P(RadioHidlTest_v1_5, togglingUiccApplicationsSimPresent) { // This test case only test SIM ABSENT case. if (cardStatus.base.base.base.cardState != CardState::PRESENT) return; + if (cardStatus.applications.size() == 0) return; // Disable Uicc applications. serial = GetRandomSerialNumber(); -- GitLab From b12ccd3e3004c66e3ed0be5b6eef572261aca96c Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Wed, 28 Oct 2020 18:35:52 -0700 Subject: [PATCH 252/790] Get offset of recorded keyframe from MTP table Test: atest VtsHalTvTunerV1_1TargetTest Bug: 158816517 Change-Id: Ia48637554fc5020b6de422feac7efc04c070fae7 --- tv/tuner/1.1/default/Filter.cpp | 5 +- tv/tuner/1.1/default/Filter.h | 2 +- tv/tuner/1.1/types.hal | 60 ++++++++++++++++++--- tv/tuner/1.1/vts/functional/FilterTests.cpp | 4 +- 4 files changed, 59 insertions(+), 12 deletions(-) diff --git a/tv/tuner/1.1/default/Filter.cpp b/tv/tuner/1.1/default/Filter.cpp index 4c377293dc..139e98af99 100644 --- a/tv/tuner/1.1/default/Filter.cpp +++ b/tv/tuner/1.1/default/Filter.cpp @@ -209,6 +209,7 @@ Return Filter::getAvSharedHandle(getAvSharedHandle_cb _hidl_cb) { if (mSharedAvMemHandle.getNativeHandle() != nullptr) { _hidl_cb(Result::SUCCESS, mSharedAvMemHandle, BUFFER_SIZE_16M); + mUsingSharedAvMem = true; return Void(); } @@ -225,6 +226,7 @@ Return Filter::getAvSharedHandle(getAvSharedHandle_cb _hidl_cb) { ::close(av_fd); _hidl_cb(Result::SUCCESS, mSharedAvMemHandle, BUFFER_SIZE_16M); + mUsingSharedAvMem = true; return Void(); } @@ -678,11 +680,10 @@ Result Filter::startRecordFilterHandler() { recordEvent = { .byteNumber = mRecordFilterOutput.size(), }; - V1_1::DemuxFilterRecordEventExt recordEventExt; + V1_1::DemuxFilterTsRecordEventExt recordEventExt; recordEventExt = { .pts = (mPts == 0) ? time(NULL) * 900000 : mPts, .firstMbInSlice = 0, // random address - .mpuSequenceNumber = 1, // random sequence number }; int size; diff --git a/tv/tuner/1.1/default/Filter.h b/tv/tuner/1.1/default/Filter.h index 522db354a0..a7b3fd26d7 100644 --- a/tv/tuner/1.1/default/Filter.h +++ b/tv/tuner/1.1/default/Filter.h @@ -227,7 +227,7 @@ class Filter : public V1_1::IFilter { // Shared A/V memory handle hidl_handle mSharedAvMemHandle; - bool mUsingSharedAvMem = true; + bool mUsingSharedAvMem = false; uint32_t mSharedAvMemOffset = 0; uint32_t mAudioStreamType; diff --git a/tv/tuner/1.1/types.hal b/tv/tuner/1.1/types.hal index defc99b14e..f3769a2f32 100644 --- a/tv/tuner/1.1/types.hal +++ b/tv/tuner/1.1/types.hal @@ -20,6 +20,7 @@ import @1.0::Constant; import @1.0::DemuxFilterMmtpRecordEvent; import @1.0::DemuxFilterTsRecordEvent; import @1.0::DemuxScIndex; +import @1.0::DemuxTsIndex; import @1.0::FrontendIsdbs3Rolloff; import @1.0::FrontendAtsc3Bandwidth; import @1.0::FrontendAtsc3Modulation; @@ -51,11 +52,11 @@ import android.hidl.safe_union@1.0::Monostate; @export enum Constant : @1.0::Constant { /** - * An invalid mpuSequenceNumber in DemuxFilterRecordEventExt. + * An invalid mpuSequenceNumber. */ INVALID_MMTP_RECORD_EVENT_MPT_SEQUENCE_NUM = 0xFFFFFFFF, /** - * An invalid first macroblock address in DemuxFilterRecordEventExt. + * An invalid first macroblock address. */ INVALID_FIRST_MACROBLOCK_IN_SLICE = 0xFFFFFFFF, /** @@ -91,9 +92,25 @@ enum Constant64Bit : uint64_t { }; /** - * Extended Demux Filter Record Event. + * Extended Demux Filter TS Record Event. */ -struct DemuxFilterRecordEventExt { +struct DemuxFilterTsRecordEventExt { + /** + * The Presentation Time Stamp(PTS) for the audio or video frame. It is based on 90KHz + * and has the same format as the PTS in ISO/IEC 13818-1. + */ + uint64_t pts; + + /** + * Specifies the address of the first macroblock in the slice defined in ITU-T Rec. H.264. + */ + uint32_t firstMbInSlice; +}; + +/** + * Extended Demux Filter MMTP Record Event. + */ +struct DemuxFilterMmtpRecordEventExt { /** * The Presentation Time Stamp(PTS) for the audio or video frame. It is based on 90KHz * and has the same format as the PTS in ISO/IEC 13818-1. @@ -109,6 +126,11 @@ struct DemuxFilterRecordEventExt { * Specifies the address of the first macroblock in the slice defined in ITU-T Rec. H.264. */ uint32_t firstMbInSlice; + + /** + * TS index mask. + */ + bitfield<@1.1::DemuxTsIndex> tsIndexMask; }; /** @@ -118,13 +140,13 @@ struct DemuxFilterEventExt { safe_union Event { /** * No extended record filter Event. This is used by the tsRecord or mmtpRecord filter event - * that does not contain the DemuxFilterRecordEventExt information. + * that does not contain the DemuxFilterTs/MmtpRecordEventExt information. */ Monostate noinit; - DemuxFilterRecordEventExt tsRecord; + DemuxFilterTsRecordEventExt tsRecord; - DemuxFilterRecordEventExt mmtpRecord; + DemuxFilterMmtpRecordEventExt mmtpRecord; ScramblingStatus scramblingStatus; }; @@ -816,3 +838,27 @@ enum DemuxScIndex : @1.0::DemuxScIndex { */ SP_SLICE = 1 << 8, }; + +@export +enum DemuxTsIndex : @1.0::DemuxTsIndex { + /** + * Index the address of MMT Packet Table(MPT). + */ + MPT_INDEX_MPT = 1 << 16, + /** + * Index the address of Video. + */ + MPT_INDEX_VIDEO = 1 << 17, + /** + * Index the address of Audio. + */ + MPT_INDEX_AUDIO = 1 << 18, + /** + * Index to indicate this is a target of timestamp extraction for video. + */ + MPT_INDEX_TIMESTAMP_TARGET_VIDEO = 1 << 19, + /** + * Index to indicate this is a target of timestamp extraction for audio. + */ + MPT_INDEX_TIMESTAMP_TARGET_AUDIO = 1 << 20, +}; diff --git a/tv/tuner/1.1/vts/functional/FilterTests.cpp b/tv/tuner/1.1/vts/functional/FilterTests.cpp index f114a66d76..d2535e533b 100644 --- a/tv/tuner/1.1/vts/functional/FilterTests.cpp +++ b/tv/tuner/1.1/vts/functional/FilterTests.cpp @@ -64,9 +64,9 @@ void FilterCallback::readFilterEventData() { break; case DemuxFilterEventExt::Event::hidl_discriminator::mmtpRecord: ALOGD("[vts] Extended MMTP record filter event, pts=%" PRIu64 - ", firstMbInSlice=%d, mpuSequenceNumber=%d", + ", firstMbInSlice=%d, mpuSequenceNumber=%d, tsIndexMask=%d", eventExt.mmtpRecord().pts, eventExt.mmtpRecord().firstMbInSlice, - eventExt.mmtpRecord().mpuSequenceNumber); + eventExt.mmtpRecord().mpuSequenceNumber, eventExt.mmtpRecord().tsIndexMask); break; case DemuxFilterEventExt::Event::hidl_discriminator::scramblingStatus: mScramblingStatusEvent++; -- GitLab From 4d9f1eed0fc2696eba8870c2d67466aad10c5fd9 Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Thu, 29 Oct 2020 18:25:41 +0800 Subject: [PATCH 253/790] wifi: add new status code for unsupported cases Bug: 160642415 Test: atest VtsHalWifiSupplicantV1_4TargetTest \ VtsHalWifiSupplicantP2pV1_4TargetTest Change-Id: I6eac4646df4a3e595f5dd0c359660420b71d444c --- wifi/supplicant/1.4/ISupplicantP2pIface.hal | 1 - wifi/supplicant/1.4/ISupplicantStaIface.hal | 1 - wifi/supplicant/1.4/ISupplicantStaNetwork.hal | 1 - wifi/supplicant/1.4/types.hal | 21 +++++++++++++++++++ .../supplicant_p2p_iface_hidl_test.cpp | 21 ++++++++++++------- .../supplicant_sta_iface_hidl_test.cpp | 13 ++++++++---- .../supplicant_sta_network_hidl_test.cpp | 16 ++++++++------ 7 files changed, 53 insertions(+), 21 deletions(-) diff --git a/wifi/supplicant/1.4/ISupplicantP2pIface.hal b/wifi/supplicant/1.4/ISupplicantP2pIface.hal index 7c41d1c488..65c761da80 100644 --- a/wifi/supplicant/1.4/ISupplicantP2pIface.hal +++ b/wifi/supplicant/1.4/ISupplicantP2pIface.hal @@ -17,7 +17,6 @@ package android.hardware.wifi.supplicant@1.4; import @1.2::ISupplicantP2pIface; -import @1.0::SupplicantStatus; /** * Interface exposed by the supplicant for each P2P mode network diff --git a/wifi/supplicant/1.4/ISupplicantStaIface.hal b/wifi/supplicant/1.4/ISupplicantStaIface.hal index 68fd01d12e..096d8d5480 100644 --- a/wifi/supplicant/1.4/ISupplicantStaIface.hal +++ b/wifi/supplicant/1.4/ISupplicantStaIface.hal @@ -16,7 +16,6 @@ package android.hardware.wifi.supplicant@1.4; -import @1.0::SupplicantStatus; import ISupplicantStaIfaceCallback; import @1.3::ISupplicantStaIface; diff --git a/wifi/supplicant/1.4/ISupplicantStaNetwork.hal b/wifi/supplicant/1.4/ISupplicantStaNetwork.hal index 0cc62c0f12..42958792b6 100644 --- a/wifi/supplicant/1.4/ISupplicantStaNetwork.hal +++ b/wifi/supplicant/1.4/ISupplicantStaNetwork.hal @@ -18,7 +18,6 @@ package android.hardware.wifi.supplicant@1.4; import @1.3::ISupplicantStaNetwork; import @1.4::ISupplicantStaNetworkCallback; -import @1.0::SupplicantStatus; /** * Interface exposed by the supplicant for each station mode network diff --git a/wifi/supplicant/1.4/types.hal b/wifi/supplicant/1.4/types.hal index 79e367aa91..b4b6a365b9 100644 --- a/wifi/supplicant/1.4/types.hal +++ b/wifi/supplicant/1.4/types.hal @@ -16,6 +16,7 @@ package android.hardware.wifi.supplicant@1.4; +import @1.0::SupplicantStatusCode; import @1.3::ConnectionCapabilities; /** @@ -50,3 +51,23 @@ struct ConnectionCapabilities { */ LegacyMode legacyMode; }; + +/** + * Enum values indicating the status of any supplicant operation. + */ +enum SupplicantStatusCode : @1.0::SupplicantStatusCode { + FAILURE_UNSUPPORTED, +}; + +/** + * Generic structure to return the status of any supplicant operation. + */ +struct SupplicantStatus { + SupplicantStatusCode code; + /** + * A vendor specific error message to provide more information beyond the + * status code. + * This will be used for debbuging purposes only. + */ + string debugMessage; +}; diff --git a/wifi/supplicant/1.4/vts/functional/supplicant_p2p_iface_hidl_test.cpp b/wifi/supplicant/1.4/vts/functional/supplicant_p2p_iface_hidl_test.cpp index 17e1b9f94d..9185279f38 100644 --- a/wifi/supplicant/1.4/vts/functional/supplicant_p2p_iface_hidl_test.cpp +++ b/wifi/supplicant/1.4/vts/functional/supplicant_p2p_iface_hidl_test.cpp @@ -33,6 +33,11 @@ using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatus; using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatusCode; using ::android::hardware::wifi::supplicant::V1_4::ISupplicantP2pIface; +using SupplicantStatusV1_4 = + ::android::hardware::wifi::supplicant::V1_4::SupplicantStatus; +using SupplicantStatusCodeV1_4 = + ::android::hardware::wifi::supplicant::V1_4::SupplicantStatusCode; + class SupplicantP2pIfaceHidlTest : public SupplicantHidlTestBaseV1_4 { public: virtual void SetUp() override { @@ -50,18 +55,18 @@ class SupplicantP2pIfaceHidlTest : public SupplicantHidlTestBaseV1_4 { * SetGetEdmg */ TEST_P(SupplicantP2pIfaceHidlTest, SetGetEdmg) { - p2p_iface_->setEdmg(true, [&](const SupplicantStatus& status) { - EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + p2p_iface_->setEdmg(true, [&](const SupplicantStatusV1_4& status) { + EXPECT_EQ(SupplicantStatusCodeV1_4::SUCCESS, status.code); }); - p2p_iface_->getEdmg([&](const SupplicantStatus& status, bool enable) { - EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + p2p_iface_->getEdmg([&](const SupplicantStatusV1_4& status, bool enable) { + EXPECT_EQ(SupplicantStatusCodeV1_4::SUCCESS, status.code); EXPECT_EQ(true, enable); }); - p2p_iface_->setEdmg(false, [&](const SupplicantStatus& status) { - EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + p2p_iface_->setEdmg(false, [&](const SupplicantStatusV1_4& status) { + EXPECT_EQ(SupplicantStatusCodeV1_4::SUCCESS, status.code); }); - p2p_iface_->getEdmg([&](const SupplicantStatus& status, bool enable) { - EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + p2p_iface_->getEdmg([&](const SupplicantStatusV1_4& status, bool enable) { + EXPECT_EQ(SupplicantStatusCodeV1_4::SUCCESS, status.code); EXPECT_EQ(false, enable); }); } diff --git a/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp index fbf6445217..88396b6465 100644 --- a/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp +++ b/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp @@ -50,6 +50,11 @@ using ::android::hardware::wifi::supplicant::V1_4::ISupplicant; using ::android::hardware::wifi::supplicant::V1_4::ISupplicantStaIface; using ::android::hardware::wifi::supplicant::V1_4::ISupplicantStaIfaceCallback; +using SupplicantStatusV1_4 = + ::android::hardware::wifi::supplicant::V1_4::SupplicantStatus; +using SupplicantStatusCodeV1_4 = + ::android::hardware::wifi::supplicant::V1_4::SupplicantStatusCode; + class SupplicantStaIfaceHidlTest : public SupplicantHidlTestBaseV1_4 { public: virtual void SetUp() override { @@ -195,9 +200,9 @@ class IfaceCallback : public ISupplicantStaIfaceCallback { */ TEST_P(SupplicantStaIfaceHidlTest, GetConnectionCapabilities) { sta_iface_->getConnectionCapabilities_1_4( - [&](const SupplicantStatus& status, + [&](const SupplicantStatusV1_4& status, ConnectionCapabilities /* capabilities */) { - EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + EXPECT_EQ(SupplicantStatusCodeV1_4::SUCCESS, status.code); }); } @@ -206,8 +211,8 @@ TEST_P(SupplicantStaIfaceHidlTest, GetConnectionCapabilities) { */ TEST_P(SupplicantStaIfaceHidlTest, RegisterCallback_1_4) { sta_iface_->registerCallback_1_4( - new IfaceCallback(), [](const SupplicantStatus& status) { - EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + new IfaceCallback(), [](const SupplicantStatusV1_4& status) { + EXPECT_EQ(SupplicantStatusCodeV1_4::SUCCESS, status.code); }); } diff --git a/wifi/supplicant/1.4/vts/functional/supplicant_sta_network_hidl_test.cpp b/wifi/supplicant/1.4/vts/functional/supplicant_sta_network_hidl_test.cpp index aaaccfc19b..86314e2451 100644 --- a/wifi/supplicant/1.4/vts/functional/supplicant_sta_network_hidl_test.cpp +++ b/wifi/supplicant/1.4/vts/functional/supplicant_sta_network_hidl_test.cpp @@ -42,6 +42,10 @@ using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatusCode; using ::android::hardware::wifi::supplicant::V1_4:: ISupplicantStaNetworkCallback; using ::android::hardware::wifi::V1_0::IWifi; +using SupplicantStatusV1_4 = + ::android::hardware::wifi::supplicant::V1_4::SupplicantStatus; +using SupplicantStatusCodeV1_4 = + ::android::hardware::wifi::supplicant::V1_4::SupplicantStatusCode; class SupplicantStaNetworkHidlTest : public SupplicantHidlTestBaseV1_4 { public: @@ -85,8 +89,8 @@ class NetworkCallback : public ISupplicantStaNetworkCallback { */ TEST_P(SupplicantStaNetworkHidlTest, RegisterCallback_1_4) { v1_4->registerCallback_1_4( - new NetworkCallback(), [](const SupplicantStatus& status) { - EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + new NetworkCallback(), [](const SupplicantStatusV1_4& status) { + EXPECT_EQ(SupplicantStatusCodeV1_4::SUCCESS, status.code); }); } @@ -94,11 +98,11 @@ TEST_P(SupplicantStaNetworkHidlTest, RegisterCallback_1_4) { * enable SAE H2E (Hash-to-Element) only mode */ TEST_P(SupplicantStaNetworkHidlTest, EnableSaeH2eOnlyMode) { - v1_4->enableSaeH2eOnlyMode(true, [&](const SupplicantStatus& status) { - EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + v1_4->enableSaeH2eOnlyMode(true, [&](const SupplicantStatusV1_4& status) { + EXPECT_EQ(SupplicantStatusCodeV1_4::SUCCESS, status.code); }); - v1_4->enableSaeH2eOnlyMode(false, [&](const SupplicantStatus& status) { - EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + v1_4->enableSaeH2eOnlyMode(false, [&](const SupplicantStatusV1_4& status) { + EXPECT_EQ(SupplicantStatusCodeV1_4::SUCCESS, status.code); }); } -- GitLab From aeeb9b083d82507197f545ec78bfd61f741f2524 Mon Sep 17 00:00:00 2001 From: Hayden Gomes Date: Tue, 27 Oct 2020 13:08:34 -0700 Subject: [PATCH 254/790] Default implementation for AudioControl AIDL HAL Bug: b/170335834 Test: Built in target and ran `adb shell dumpsys android.hardware.automotive.audiocontrol.IAudioControl/default` commands Change-Id: Iccf5784fce7635c78ca8cc0f9066b4dc9f24b3bd --- .../audiocontrol/aidl/default/Android.bp | 36 +++ .../aidl/default/AudioControl.cpp | 224 ++++++++++++++++++ .../audiocontrol/aidl/default/AudioControl.h | 51 ++++ .../aidl/default/audiocontrol-default.rc | 4 + .../aidl/default/audiocontrol-default.xml | 6 + automotive/audiocontrol/aidl/default/main.cpp | 36 +++ 6 files changed, 357 insertions(+) create mode 100644 automotive/audiocontrol/aidl/default/Android.bp create mode 100644 automotive/audiocontrol/aidl/default/AudioControl.cpp create mode 100644 automotive/audiocontrol/aidl/default/AudioControl.h create mode 100644 automotive/audiocontrol/aidl/default/audiocontrol-default.rc create mode 100644 automotive/audiocontrol/aidl/default/audiocontrol-default.xml create mode 100644 automotive/audiocontrol/aidl/default/main.cpp diff --git a/automotive/audiocontrol/aidl/default/Android.bp b/automotive/audiocontrol/aidl/default/Android.bp new file mode 100644 index 0000000000..faf7ad2485 --- /dev/null +++ b/automotive/audiocontrol/aidl/default/Android.bp @@ -0,0 +1,36 @@ +// 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. + +cc_binary { + name: "android.hardware.automotive.audiocontrol-service.example", + relative_install_path: "hw", + init_rc: ["audiocontrol-default.rc"], + vintf_fragments: ["audiocontrol-default.xml"], + vendor: true, + generated_headers: ["audio_policy_configuration_V7_0"], + generated_sources: ["audio_policy_configuration_V7_0"], + header_libs: ["libxsdc-utils"], + shared_libs: [ + "android.hardware.automotive.audiocontrol-ndk_platform", + "libbase", + "libbinder_ndk", + "liblog", + "libcutils", + "libxml2", + ], + srcs: [ + "AudioControl.cpp", + "main.cpp", + ], +} diff --git a/automotive/audiocontrol/aidl/default/AudioControl.cpp b/automotive/audiocontrol/aidl/default/AudioControl.cpp new file mode 100644 index 0000000000..b6373108eb --- /dev/null +++ b/automotive/audiocontrol/aidl/default/AudioControl.cpp @@ -0,0 +1,224 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "AudioControl.h" + +#include +#include + +#include +#include +#include + +#include +#include + +#include + +namespace aidl::android::hardware::automotive::audiocontrol { + +using ::android::base::EqualsIgnoreCase; +using ::android::base::ParseInt; +using ::std::string; + +namespace xsd { +using namespace audio::policy::configuration::V7_0; +} + +namespace { +const float kLowerBound = -1.0f; +const float kUpperBound = 1.0f; +bool checkCallerHasWritePermissions(int fd) { + // Double check that's only called by root - it should be be blocked at debug() level, + // but it doesn't hurt to make sure... + if (AIBinder_getCallingUid() != AID_ROOT) { + dprintf(fd, "Must be root\n"); + return false; + } + return true; +} + +bool isValidValue(float value) { + return (value >= kLowerBound) && (value <= kUpperBound); +} + +bool safelyParseInt(string s, int* out) { + if (!ParseInt(s, out)) { + return false; + } + return true; +} +} // namespace + +ndk::ScopedAStatus AudioControl::registerFocusListener( + const shared_ptr& in_listener) { + LOG(DEBUG) << "registering focus listener"; + + if (in_listener.get()) { + std::atomic_store(&mFocusListener, in_listener); + } else { + LOG(ERROR) << "Unexpected nullptr for listener resulting in no-op."; + } + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus AudioControl::setBalanceTowardRight(float value) { + if (isValidValue(value)) { + // Just log in this default mock implementation + LOG(INFO) << "Balance set to " << value; + } else { + LOG(ERROR) << "Balance value out of range -1 to 1 at " << value; + } + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus AudioControl::setFadeTowardFront(float value) { + if (isValidValue(value)) { + // Just log in this default mock implementation + LOG(INFO) << "Fader set to " << value; + } else { + LOG(ERROR) << "Fader value out of range -1 to 1 at " << value; + } + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus AudioControl::onAudioFocusChange(const string& in_usage, int32_t in_zoneId, + AudioFocusChange in_focusChange) { + LOG(INFO) << "Focus changed: " << toString(in_focusChange).c_str() << " for usage " + << in_usage.c_str() << " in zone " << in_zoneId; + return ndk::ScopedAStatus::ok(); +} + +binder_status_t AudioControl::dump(int fd, const char** args, uint32_t numArgs) { + if (numArgs == 0) { + return dumpsys(fd); + } + + string option = string(args[0]); + if (EqualsIgnoreCase(option, "--help")) { + return cmdHelp(fd); + } else if (EqualsIgnoreCase(option, "--request")) { + return cmdRequestFocus(fd, args, numArgs); + } else if (EqualsIgnoreCase(option, "--abandon")) { + return cmdAbandonFocus(fd, args, numArgs); + } else { + dprintf(fd, "Invalid option: %s\n", option.c_str()); + return STATUS_BAD_VALUE; + } +} + +binder_status_t AudioControl::dumpsys(int fd) { + if (mFocusListener == nullptr) { + dprintf(fd, "No focus listener registered\n"); + } else { + dprintf(fd, "Focus listener registered\n"); + } + return STATUS_OK; +} + +binder_status_t AudioControl::cmdHelp(int fd) const { + dprintf(fd, "Usage: \n\n"); + dprintf(fd, "[no args]: dumps focus listener status\n"); + dprintf(fd, "--help: shows this help\n"); + dprintf(fd, + "--request : requests audio focus for specified " + "usage (string), audio zone ID (int), and focus gain type (int)\n"); + dprintf(fd, + "--abandon : abandons audio focus for specified usage (string) and " + "audio zone ID (int)\n"); + dprintf(fd, "See audio_policy_configuration.xsd for valid AudioUsage values.\n"); + return STATUS_OK; +} + +binder_status_t AudioControl::cmdRequestFocus(int fd, const char** args, uint32_t numArgs) { + if (!checkCallerHasWritePermissions(fd)) { + return STATUS_PERMISSION_DENIED; + } + if (numArgs != 4) { + dprintf(fd, + "Invalid number of arguments: please provide --request " + "\n"); + return STATUS_BAD_VALUE; + } + + string usage = string(args[1]); + if (xsd::stringToAudioUsage(usage) == xsd::AudioUsage::UNKNOWN) { + dprintf(fd, + "Unknown usage provided: %s. Please see audio_policy_configuration.xsd V7_0 " + "for supported values\n", + usage.c_str()); + return STATUS_BAD_VALUE; + } + + int zoneId; + if (!safelyParseInt(string(args[2]), &zoneId)) { + dprintf(fd, "Non-integer zoneId provided with request: %s\n", string(args[2]).c_str()); + return STATUS_BAD_VALUE; + } + + int focusGainValue; + if (!safelyParseInt(string(args[3]), &focusGainValue)) { + dprintf(fd, "Non-integer focusGain provided with request: %s\n", string(args[3]).c_str()); + return STATUS_BAD_VALUE; + } + AudioFocusChange focusGain = AudioFocusChange(focusGainValue); + + if (mFocusListener == nullptr) { + dprintf(fd, "Unable to request focus - no focus listener registered\n"); + return STATUS_BAD_VALUE; + } + + mFocusListener->requestAudioFocus(usage, zoneId, focusGain); + dprintf(fd, "Requested focus for usage %s, zoneId %d, and focusGain %d\n", usage.c_str(), + zoneId, focusGain); + return STATUS_OK; +} + +binder_status_t AudioControl::cmdAbandonFocus(int fd, const char** args, uint32_t numArgs) { + if (!checkCallerHasWritePermissions(fd)) { + return STATUS_PERMISSION_DENIED; + } + if (numArgs != 3) { + dprintf(fd, "Invalid number of arguments: please provide --abandon \n"); + return STATUS_BAD_VALUE; + } + + string usage = string(args[1]); + if (xsd::stringToAudioUsage(usage) == xsd::AudioUsage::UNKNOWN) { + dprintf(fd, + "Unknown usage provided: %s. Please see audio_policy_configuration.xsd V7_0 " + "for supported values\n", + usage.c_str()); + return STATUS_BAD_VALUE; + } + + int zoneId; + if (!safelyParseInt(string(args[2]), &zoneId)) { + dprintf(fd, "Non-integer zoneId provided with abandon: %s\n", string(args[2]).c_str()); + return STATUS_BAD_VALUE; + } + + if (mFocusListener == nullptr) { + dprintf(fd, "Unable to abandon focus - no focus listener registered\n"); + return STATUS_BAD_VALUE; + } + + mFocusListener->abandonAudioFocus(usage, zoneId); + dprintf(fd, "Abandoned focus for usage %s and zoneId %d\n", usage.c_str(), zoneId); + return STATUS_OK; +} + +} // namespace aidl::android::hardware::automotive::audiocontrol diff --git a/automotive/audiocontrol/aidl/default/AudioControl.h b/automotive/audiocontrol/aidl/default/AudioControl.h new file mode 100644 index 0000000000..a77da3e6d1 --- /dev/null +++ b/automotive/audiocontrol/aidl/default/AudioControl.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef ANDROID_HARDWARE_AUTOMOTIVE_AUDIOCONTROL_AUDIOCONTROL_H +#define ANDROID_HARDWARE_AUTOMOTIVE_AUDIOCONTROL_AUDIOCONTROL_H + +#include +#include + +namespace aidl::android::hardware::automotive::audiocontrol { + +using ::std::shared_ptr; + +class AudioControl : public BnAudioControl { + public: + ndk::ScopedAStatus onAudioFocusChange(const std::string& in_usage, int32_t in_zoneId, + AudioFocusChange in_focusChange) override; + ndk::ScopedAStatus registerFocusListener( + const shared_ptr& in_listener) override; + ndk::ScopedAStatus setBalanceTowardRight(float in_value) override; + ndk::ScopedAStatus setFadeTowardFront(float in_value) override; + binder_status_t dump(int fd, const char** args, uint32_t numArgs) override; + + private: + // This focus listener will only be used by this HAL instance to communicate with + // a single instance of CarAudioService. As such, it doesn't have explicit serialization. + // If a different AudioControl implementation were to have multiple threads leveraging this + // listener, then it should also include mutexes or make the listener atomic. + shared_ptr mFocusListener; + + binder_status_t cmdHelp(int fd) const; + binder_status_t cmdRequestFocus(int fd, const char** args, uint32_t numArgs); + binder_status_t cmdAbandonFocus(int fd, const char** args, uint32_t numArgs); + binder_status_t dumpsys(int fd); +}; + +} // namespace aidl::android::hardware::automotive::audiocontrol + +#endif // ANDROID_HARDWARE_AUTOMOTIVE_AUDIOCONTROL_AUDIOCONTROL_H diff --git a/automotive/audiocontrol/aidl/default/audiocontrol-default.rc b/automotive/audiocontrol/aidl/default/audiocontrol-default.rc new file mode 100644 index 0000000000..88d180dbd1 --- /dev/null +++ b/automotive/audiocontrol/aidl/default/audiocontrol-default.rc @@ -0,0 +1,4 @@ +service vendor.audiocontrol-default /vendor/bin/hw/android.hardware.automotive.audiocontrol-service.example + class hal + user audioserver + group system diff --git a/automotive/audiocontrol/aidl/default/audiocontrol-default.xml b/automotive/audiocontrol/aidl/default/audiocontrol-default.xml new file mode 100644 index 0000000000..f95d05fe77 --- /dev/null +++ b/automotive/audiocontrol/aidl/default/audiocontrol-default.xml @@ -0,0 +1,6 @@ + + + android.hardware.automotive.audiocontrol + IAudioControl/default + + diff --git a/automotive/audiocontrol/aidl/default/main.cpp b/automotive/audiocontrol/aidl/default/main.cpp new file mode 100644 index 0000000000..996665fe5c --- /dev/null +++ b/automotive/audiocontrol/aidl/default/main.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "AudioControl.h" + +#include +#include +#include + +using aidl::android::hardware::automotive::audiocontrol::AudioControl; + +int main() { + ABinderProcess_setThreadPoolMaxThreadCount(0); + std::shared_ptr audioControl = ndk::SharedRefBase::make(); + + const std::string instance = std::string() + AudioControl::descriptor + "/default"; + binder_status_t status = + AServiceManager_addService(audioControl->asBinder().get(), instance.c_str()); + CHECK(status == STATUS_OK); + + ABinderProcess_joinThreadPool(); + return EXIT_FAILURE; // should not reach +} -- GitLab From a521acf0eedbbf0a936ee17f49a383a28a284ae7 Mon Sep 17 00:00:00 2001 From: Hayden Gomes Date: Mon, 2 Nov 2020 12:29:05 -0800 Subject: [PATCH 255/790] Adding VTS tests for AudioControl AIDL HAL Bug: b/170335834 Test: atest VtsAidlHalAudioControlTest Change-Id: Ic993934506c242b25dce934498e643f4e50c28bc --- automotive/audiocontrol/aidl/vts/Android.bp | 38 +++++ .../aidl/vts/VtsHalAudioControlTargetTest.cpp | 143 ++++++++++++++++++ 2 files changed, 181 insertions(+) create mode 100644 automotive/audiocontrol/aidl/vts/Android.bp create mode 100644 automotive/audiocontrol/aidl/vts/VtsHalAudioControlTargetTest.cpp diff --git a/automotive/audiocontrol/aidl/vts/Android.bp b/automotive/audiocontrol/aidl/vts/Android.bp new file mode 100644 index 0000000000..3d81e001c1 --- /dev/null +++ b/automotive/audiocontrol/aidl/vts/Android.bp @@ -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. + +cc_test { + name: "VtsAidlHalAudioControlTest", + defaults: [ + "VtsHalTargetTestDefaults", + "use_libaidlvintf_gtest_helper_static", + ], + generated_headers: ["audio_policy_configuration_V7_0"], + generated_sources: ["audio_policy_configuration_V7_0"], + header_libs: ["libxsdc-utils"], + srcs: ["VtsHalAudioControlTargetTest.cpp"], + shared_libs: [ + "libbinder", + "libbase", + "libxml2", + ], + static_libs: [ + "android.hardware.automotive.audiocontrol-cpp", + "libgmock", + ], + test_suites: [ + "general-tests", + "vts", + ], +} diff --git a/automotive/audiocontrol/aidl/vts/VtsHalAudioControlTargetTest.cpp b/automotive/audiocontrol/aidl/vts/VtsHalAudioControlTargetTest.cpp new file mode 100644 index 0000000000..c734e29e29 --- /dev/null +++ b/automotive/audiocontrol/aidl/vts/VtsHalAudioControlTargetTest.cpp @@ -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. + */ +#define LOG_TAG "VtsAidlHalAudioControlTest" + +#include +#include +#include + +#include +#include +#include +#include +#include + +using android::ProcessState; +using android::sp; +using android::String16; +using android::binder::Status; +using android::hardware::automotive::audiocontrol::AudioFocusChange; +using android::hardware::automotive::audiocontrol::BnFocusListener; +using android::hardware::automotive::audiocontrol::IAudioControl; + +#include "audio_policy_configuration_V7_0.h" + +namespace xsd { +using namespace audio::policy::configuration::V7_0; +} + +class AudioControlAidl : public testing::TestWithParam { + public: + virtual void SetUp() override { + audioControl = android::waitForDeclaredService(String16(GetParam().c_str())); + ASSERT_NE(audioControl, nullptr); + } + + sp audioControl; + int32_t capabilities; +}; + +TEST_P(AudioControlAidl, OnSetFadeTowardsFront) { + ALOGI("Fader exercise test (silent)"); + + // Set the fader all the way to the back + ASSERT_TRUE(audioControl->setFadeTowardFront(-1.0f).isOk()); + + // Set the fader all the way to the front + ASSERT_TRUE(audioControl->setFadeTowardFront(1.0f).isOk()); + + // Set the fader part way toward the back + ASSERT_TRUE(audioControl->setFadeTowardFront(-0.333f).isOk()); + + // Set the fader to a out of bounds value (driver should clamp) + ASSERT_TRUE(audioControl->setFadeTowardFront(99999.9f).isOk()); + + // Set the fader to a negative out of bounds value (driver should clamp) + ASSERT_TRUE(audioControl->setFadeTowardFront(-99999.9f).isOk()); + + // Set the fader back to the middle + ASSERT_TRUE(audioControl->setFadeTowardFront(0.0f).isOk()); +} + +TEST_P(AudioControlAidl, OnSetBalanceTowardsRight) { + ALOGI("Balance exercise test (silent)"); + + // Set the balance all the way to the left + ASSERT_TRUE(audioControl->setBalanceTowardRight(-1.0f).isOk()); + + // Set the balance all the way to the right + ASSERT_TRUE(audioControl->setBalanceTowardRight(1.0f).isOk()); + + // Set the balance part way toward the left + ASSERT_TRUE(audioControl->setBalanceTowardRight(-0.333f).isOk()); + + // Set the balance to a out of bounds value (driver should clamp) + ASSERT_TRUE(audioControl->setBalanceTowardRight(99999.9f).isOk()); + + // Set the balance to a negative out of bounds value (driver should clamp) + ASSERT_TRUE(audioControl->setBalanceTowardRight(-99999.9f).isOk()); + + // Set the balance back to the middle + ASSERT_TRUE(audioControl->setBalanceTowardRight(0.0f).isOk()); + + // Set the balance back to the middle + audioControl->setBalanceTowardRight(0.0f).isOk(); +} + +struct FocusListenerMock : BnFocusListener { + MOCK_METHOD(Status, requestAudioFocus, + (const String16& usage, int32_t zoneId, AudioFocusChange focusGain)); + MOCK_METHOD(Status, abandonAudioFocus, (const String16& usage, int32_t zoneId)); +}; + +/* + * Test focus listener registration. + * + * Verifies that: + * - registerFocusListener succeeds; + * - registering a second listener succeeds in replacing the first; + * - closing handle does not crash; + */ +TEST_P(AudioControlAidl, FocusListenerRegistration) { + ALOGI("Focus listener test"); + + sp listener = new FocusListenerMock(); + ASSERT_TRUE(audioControl->registerFocusListener(listener).isOk()); + + sp listener2 = new FocusListenerMock(); + ASSERT_TRUE(audioControl->registerFocusListener(listener2).isOk()); +}; + +TEST_P(AudioControlAidl, FocusChangeExercise) { + ALOGI("Focus Change test"); + + String16 usage = String16(xsd::toString(xsd::AudioUsage::AUDIO_USAGE_MEDIA).c_str()); + ASSERT_TRUE( + audioControl->onAudioFocusChange(usage, 0, AudioFocusChange::GAIN_TRANSIENT).isOk()); +}; + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioControlAidl); +INSTANTIATE_TEST_SUITE_P( + Audiocontrol, AudioControlAidl, + testing::ValuesIn(android::getAidlHalInstanceNames(IAudioControl::descriptor)), + android::PrintInstanceNameToString); + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + ProcessState::self()->setThreadPoolMaxThreadCount(1); + ProcessState::self()->startThreadPool(); + return RUN_ALL_TESTS(); +} -- GitLab From f033b074164f31cc4cbe4380882348f247e89db6 Mon Sep 17 00:00:00 2001 From: Lakshman Annadorai Date: Thu, 22 Oct 2020 15:56:10 -0700 Subject: [PATCH 256/790] Rename CarWatchdog AIDL's build rule name to android.automotive.watchdog. Test: Local build is okay. Bug: 170323141 Change-Id: I793befe57f5389c8de9f2fc2a762c22887569efe --- automotive/vehicle/2.0/default/Android.bp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/automotive/vehicle/2.0/default/Android.bp b/automotive/vehicle/2.0/default/Android.bp index 590adc58b0..8d1693ad42 100644 --- a/automotive/vehicle/2.0/default/Android.bp +++ b/automotive/vehicle/2.0/default/Android.bp @@ -32,7 +32,7 @@ cc_defaults { defaults: ["vhal_v2_0_defaults"], shared_libs: [ "libbinder_ndk", - "carwatchdog_aidl_interface-ndk_platform", + "android.automotive.watchdog-ndk_platform", ], } -- GitLab From 56d4de8e73485be8eff2f691d26faf08105da15f Mon Sep 17 00:00:00 2001 From: Sooraj Sasindran Date: Tue, 3 Nov 2020 20:46:57 -0800 Subject: [PATCH 257/790] Rename enableNrDualConnectivity Rename enableNrDualConnectivity to setNrDualConnectivityState Bug: 162373679 Test: build Change-Id: Ie8722b82cd235557c47528c2529cbc177e025135 --- radio/1.6/IRadio.hal | 4 ++-- radio/1.6/IRadioResponse.hal | 2 +- radio/1.6/vts/functional/radio_hidl_hal_api.cpp | 6 +++--- radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h | 2 +- radio/1.6/vts/functional/radio_response.cpp | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/radio/1.6/IRadio.hal b/radio/1.6/IRadio.hal index eb20542e7e..ce6d748264 100644 --- a/radio/1.6/IRadio.hal +++ b/radio/1.6/IRadio.hal @@ -230,9 +230,9 @@ interface IRadio extends @1.5::IRadio { * 3. Disable NR dual connectivity and force secondary cell to be released * {NrDualConnectivityState:DISABLE_IMMEDIATE} - * Response callback is IRadioResponse.enableNRDualConnectivityResponse() + * Response callback is IRadioResponse.setNRDualConnectivityStateResponse() */ - oneway enableNrDualConnectivity(int32_t serial, + oneway setNrDualConnectivityState(int32_t serial, NrDualConnectivityState nrDualConnectivityState); /** diff --git a/radio/1.6/IRadioResponse.hal b/radio/1.6/IRadioResponse.hal index 07322be29b..4343779982 100644 --- a/radio/1.6/IRadioResponse.hal +++ b/radio/1.6/IRadioResponse.hal @@ -225,7 +225,7 @@ interface IRadioResponse extends @1.5::IRadioResponse { * RadioError:RADIO_NOT_AVAILABLE * RadioError:INTERNAL_ERR */ - oneway enableNrDualConnectivityResponse(RadioResponseInfo info); + oneway setNrDualConnectivityStateResponse(RadioResponseInfo info); /** * @param info Response info struct containing response type, serial no. and error diff --git a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp index 01236c6a4e..6547611b50 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp +++ b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp @@ -260,13 +260,13 @@ TEST_P(RadioHidlTest_v1_6, setRadioPower_1_6_emergencyCall_cancelled) { } /* - * Test IRadio.enableNrDualConnectivity() for the response returned. + * Test IRadio.setNrDualConnectivityState() for the response returned. */ -TEST_P(RadioHidlTest_v1_6, enableNrDualConnectivity) { +TEST_P(RadioHidlTest_v1_6, setNrDualConnectivityState) { serial = GetRandomSerialNumber(); Return res = - radio_v1_6->enableNrDualConnectivity(serial, NrDualConnectivityState::DISABLE); + radio_v1_6->setNrDualConnectivityState(serial, NrDualConnectivityState::DISABLE); ASSERT_OK(res); EXPECT_EQ(std::cv_status::no_timeout, wait()); diff --git a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h index 850425dbe4..0161e619e2 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h +++ b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h @@ -773,7 +773,7 @@ class RadioResponse_v1_6 : public ::android::hardware::radio::V1_6::IRadioRespon const ::android::hardware::radio::V1_6::RadioResponseInfo& info, const SendSmsResult& sms); - Return enableNrDualConnectivityResponse( + Return setNrDualConnectivityStateResponse( const ::android::hardware::radio::V1_6::RadioResponseInfo& info); Return isNrDualConnectivityEnabledResponse( const ::android::hardware::radio::V1_6::RadioResponseInfo& info, bool isEnabled); diff --git a/radio/1.6/vts/functional/radio_response.cpp b/radio/1.6/vts/functional/radio_response.cpp index fc56947f50..819a1e22ca 100644 --- a/radio/1.6/vts/functional/radio_response.cpp +++ b/radio/1.6/vts/functional/radio_response.cpp @@ -1055,7 +1055,7 @@ Return RadioResponse_v1_6::setupDataCallResponse_1_6( parent_v1_6.notify(info.serial); return Void(); } -Return RadioResponse_v1_6::enableNrDualConnectivityResponse( +Return RadioResponse_v1_6::setNrDualConnectivityStateResponse( const ::android::hardware::radio::V1_6::RadioResponseInfo& info) { rspInfo = info; parent_v1_6.notify(info.serial); -- GitLab From 349bc58cb462e1f53dba995e3a2f0b928d909d9b Mon Sep 17 00:00:00 2001 From: Hai Shalom Date: Fri, 30 Oct 2020 15:25:40 -0700 Subject: [PATCH 258/790] Add HAL support for Passpoint venue URL Bug: 162783305 Test: atest VtsHalWifiSupplicantV1_4TargetTest Change-Id: I46e8e6a97c860236129d6761a11946a174985787 --- wifi/supplicant/1.4/ISupplicantStaIface.hal | 21 ++++++++++++- .../1.4/ISupplicantStaIfaceCallback.hal | 27 ++++++++++++++++ .../supplicant_sta_iface_hidl_test.cpp | 31 ++++++++++++++++++- 3 files changed, 77 insertions(+), 2 deletions(-) diff --git a/wifi/supplicant/1.4/ISupplicantStaIface.hal b/wifi/supplicant/1.4/ISupplicantStaIface.hal index 096d8d5480..db9a35b28d 100644 --- a/wifi/supplicant/1.4/ISupplicantStaIface.hal +++ b/wifi/supplicant/1.4/ISupplicantStaIface.hal @@ -16,6 +16,9 @@ package android.hardware.wifi.supplicant@1.4; +import @1.0::SupplicantStatus; +import @1.0::ISupplicantStaIface; +import @1.0::MacAddress; import ISupplicantStaIfaceCallback; import @1.3::ISupplicantStaIface; @@ -24,7 +27,6 @@ import @1.3::ISupplicantStaIface; * interface (e.g wlan0) it controls. */ interface ISupplicantStaIface extends @1.3::ISupplicantStaIface { - /** * Get Connection capabilities * @@ -54,4 +56,21 @@ interface ISupplicantStaIface extends @1.3::ISupplicantStaIface { */ registerCallback_1_4(ISupplicantStaIfaceCallback callback) generates (SupplicantStatus status); + + /** + * Initiate Venue URL ANQP (for IEEE 802.11u Interworking/Hotspot 2.0) query with the + * specified access point. This specific query can be used only post connection, once security + * is established and PMF is enabled, to avoid spoofing preassociation ANQP responses. + * The ANQP data fetched must be returned in the + * |ISupplicantStaIfaceCallback.onAnqpQueryDone| callback. + * + * @param macAddress MAC address of the access point. + * @return status Status of the operation. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_UNKNOWN|, + * |SupplicantStatusCode.FAILURE_IFACE_INVALID| + */ + initiateVenueUrlAnqpQuery(MacAddress macAddress) + generates (SupplicantStatus status); }; diff --git a/wifi/supplicant/1.4/ISupplicantStaIfaceCallback.hal b/wifi/supplicant/1.4/ISupplicantStaIfaceCallback.hal index 20bce34dd7..852696ddce 100644 --- a/wifi/supplicant/1.4/ISupplicantStaIfaceCallback.hal +++ b/wifi/supplicant/1.4/ISupplicantStaIfaceCallback.hal @@ -16,6 +16,8 @@ package android.hardware.wifi.supplicant@1.4; +import @1.0::ISupplicantStaIfaceCallback.AnqpData; +import @1.0::ISupplicantStaIfaceCallback.Hs20AnqpData; import @1.3::ISupplicantStaIfaceCallback; import @1.0::ISupplicantStaIfaceCallback.State; import @1.0::Bssid; @@ -29,6 +31,19 @@ import @1.0::Bssid; * corresponding |ISupplicantStaIface.registerCallback_1_4| method. */ interface ISupplicantStaIfaceCallback extends @1.3::ISupplicantStaIfaceCallback { + /** + * ANQP data for IEEE Std 802.11-2016. + * The format of the data within these elements follows the IEEE + * Std 802.11-2016 standard, section 9.4.5. + */ + struct AnqpData { + /** + * Baseline information as defined in HAL 1.0. + */ + @1.0::ISupplicantStaIfaceCallback.AnqpData V1_0; /* Container for v1.0 of this struct */ + vec venueUrl; /* Venue URL ANQP-element */ + }; + /** * Used to indicate a Hotspot 2.0 terms and conditions acceptance is requested from the user * before allowing the device to get internet access. @@ -37,4 +52,16 @@ interface ISupplicantStaIfaceCallback extends @1.3::ISupplicantStaIfaceCallback * @param url URL of the T&C server. */ oneway onHs20TermsAndConditionsAcceptanceRequestedNotification(Bssid bssid, string url); + + /** + * Used to indicate the result of ANQP (either for IEEE 802.11u Interworking + * or Hotspot 2.0) query. + * + * @param bssid BSSID of the access point. + * @param data ANQP data fetched from the access point. + * All the fields in this struct must be empty if the query failed. + * @param hs20Data ANQP data fetched from the Hotspot 2.0 access point. + * All the fields in this struct must be empty if the query failed. + */ + oneway onAnqpQueryDone_1_4(Bssid bssid, AnqpData data, Hs20AnqpData hs20Data); }; diff --git a/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp index 88396b6465..e079abca48 100644 --- a/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp +++ b/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp @@ -50,6 +50,10 @@ using ::android::hardware::wifi::supplicant::V1_4::ISupplicant; using ::android::hardware::wifi::supplicant::V1_4::ISupplicantStaIface; using ::android::hardware::wifi::supplicant::V1_4::ISupplicantStaIfaceCallback; +namespace { +constexpr uint8_t kTestMacAddr[] = {0x56, 0x67, 0x67, 0xf4, 0x56, 0x92}; +} // namespace + using SupplicantStatusV1_4 = ::android::hardware::wifi::supplicant::V1_4::SupplicantStatus; using SupplicantStatusCodeV1_4 = @@ -61,11 +65,15 @@ class SupplicantStaIfaceHidlTest : public SupplicantHidlTestBaseV1_4 { SupplicantHidlTestBaseV1_4::SetUp(); sta_iface_ = getSupplicantStaIface_1_4(supplicant_); ASSERT_NE(sta_iface_.get(), nullptr); + + memcpy(mac_addr_.data(), kTestMacAddr, mac_addr_.size()); } protected: // ISupplicantStaIface object used for all tests in this fixture. sp sta_iface_; + // MAC address to use for various tests. + std::array mac_addr_; }; class IfaceCallback : public ISupplicantStaIfaceCallback { @@ -79,7 +87,8 @@ class IfaceCallback : public ISupplicantStaIfaceCallback { } Return onAnqpQueryDone( const hidl_array& /* bssid */, - const ISupplicantStaIfaceCallback::AnqpData& /* data */, + const ::android::hardware::wifi::supplicant::V1_0:: + ISupplicantStaIfaceCallback::AnqpData& /* data */, const ISupplicantStaIfaceCallback::Hs20AnqpData& /* hs20Data */) override { return Void(); @@ -193,6 +202,14 @@ class IfaceCallback : public ISupplicantStaIfaceCallback { const hidl_vec& /* ssid */, bool /* filsHlpSent */) override { return Void(); } + Return onAnqpQueryDone_1_4( + const hidl_array& /* bssid */, + const ::android::hardware::wifi::supplicant::V1_4:: + ISupplicantStaIfaceCallback::AnqpData& /* data */, + const ISupplicantStaIfaceCallback::Hs20AnqpData& /* hs20Data */) + override { + return Void(); + } }; /* @@ -216,6 +233,18 @@ TEST_P(SupplicantStaIfaceHidlTest, RegisterCallback_1_4) { }); } +/* + * InitiateVenueUrlAnqpQuery. + */ +TEST_P(SupplicantStaIfaceHidlTest, InitiateVenueUrlAnqpQuery) { + sta_iface_->initiateVenueUrlAnqpQuery( + mac_addr_, [](const SupplicantStatusV1_4& status) { + // These requests will fail unless the BSSID mentioned is actually + // present in scan results. + EXPECT_EQ(SupplicantStatusCodeV1_4::FAILURE_UNKNOWN, status.code); + }); +} + GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantStaIfaceHidlTest); INSTANTIATE_TEST_CASE_P( PerInstance, SupplicantStaIfaceHidlTest, -- GitLab From ca07893589ed8e3131613a548ea9b955a1213c43 Mon Sep 17 00:00:00 2001 From: "chao.meng" Date: Wed, 28 Oct 2020 14:45:24 +0800 Subject: [PATCH 259/790] DO NOT MERGE Add sleep(3) after stopSupplicant when VtsHalWifiSupplicant [root cause ] VtsHalWifiSupplicant first stop supplicant, but framework will restart supplicant, the test will fail, according to Partner IssueTracker 169498893, AOSP suggest to add a blocking [changes ] add sleep(3) [side effects]no [self test ]:yes [download normally]:yes [power on/off normally]:yes [do common repository/branch inspection]:no [is there dependence]:no [confirm dependent commit]:no [board]:unisoc [test case]:VtsHalWifiSupplicant test [reviewers ] chao.meng [change_type ] feature_bugfix [tag_product ] common Bug: 169498893 Change-Id: I7990226d346a3444f606951386e7c223fc87f98f --- wifi/supplicant/1.1/vts/functional/supplicant_hidl_test.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test.cpp b/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test.cpp index 28f980cf85..163c926783 100644 --- a/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test.cpp +++ b/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test.cpp @@ -38,6 +38,7 @@ extern WifiSupplicantHidlEnvironment* gEnv; class SupplicantHidlTest : public ::testing::VtsHalHidlTargetTestBase { public: virtual void SetUp() override { + sleep(3); startSupplicantAndWaitForHidlService(); supplicant_ = getSupplicant_1_1(); ASSERT_NE(supplicant_.get(), nullptr); -- GitLab From 7e792611bb61c379f10d4c5c060505ecd6adb75c Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Fri, 16 Oct 2020 14:09:47 +0800 Subject: [PATCH 260/790] wifi: add enable SAE PK only mode API Bug: 160642415 Test: atest VtsHalWifiSupplicantV1_4TargetTest Change-Id: I9e9fe69bf5ebc1127085b568f02f44a2ab1b08af --- wifi/supplicant/1.3/vts/functional/Android.bp | 1 + .../supplicant_sta_iface_hidl_test.cpp | 37 ++++++++++++++++--- wifi/supplicant/1.4/ISupplicantStaIface.hal | 11 ++++++ wifi/supplicant/1.4/ISupplicantStaNetwork.hal | 28 ++++++++++++++ wifi/supplicant/1.4/types.hal | 11 ++++++ .../supplicant_sta_iface_hidl_test.cpp | 10 +++++ .../supplicant_sta_network_hidl_test.cpp | 31 ++++++++++++++++ 7 files changed, 123 insertions(+), 6 deletions(-) diff --git a/wifi/supplicant/1.3/vts/functional/Android.bp b/wifi/supplicant/1.3/vts/functional/Android.bp index 68c29293ee..1784fad60c 100644 --- a/wifi/supplicant/1.3/vts/functional/Android.bp +++ b/wifi/supplicant/1.3/vts/functional/Android.bp @@ -54,6 +54,7 @@ cc_test { "android.hardware.wifi.supplicant@1.1", "android.hardware.wifi.supplicant@1.2", "android.hardware.wifi.supplicant@1.3", + "android.hardware.wifi.supplicant@1.4", "android.hardware.wifi@1.0", "android.hardware.wifi@1.1", "libgmock", diff --git a/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp index 6dc267c1c6..189e2b9717 100644 --- a/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp +++ b/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include #include #include @@ -61,6 +63,10 @@ class SupplicantStaIfaceHidlTest : public SupplicantHidlTestBaseV1_3 { SupplicantHidlTestBaseV1_3::SetUp(); sta_iface_ = getSupplicantStaIface_1_3(supplicant_); ASSERT_NE(sta_iface_.get(), nullptr); + + /* Variable used to check the underlying HAL version. */ + sta_iface_v1_4_ = ::android::hardware::wifi::supplicant::V1_4:: + ISupplicantStaIface::castFrom(sta_iface_); } int64_t pmkCacheExpirationTimeInSec; @@ -108,6 +114,8 @@ class SupplicantStaIfaceHidlTest : public SupplicantHidlTestBaseV1_3 { protected: // ISupplicantStaIface object used for all tests in this fixture. sp sta_iface_; + sp<::android::hardware::wifi::supplicant::V1_4::ISupplicantStaIface> + sta_iface_v1_4_ = nullptr; bool isDppSupported() { uint32_t keyMgmtMask = 0; @@ -342,9 +350,12 @@ TEST_P(SupplicantStaIfaceHidlTest, GetConnectionCapabilities) { * GetWpaDriverCapabilities */ TEST_P(SupplicantStaIfaceHidlTest, GetWpaDriverCapabilities) { + SupplicantStatusCode expectedCode = + (nullptr != sta_iface_v1_4_) ? SupplicantStatusCode::FAILURE_UNKNOWN + : SupplicantStatusCode::SUCCESS; sta_iface_->getWpaDriverCapabilities( [&](const SupplicantStatus& status, uint32_t) { - EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + EXPECT_EQ(expectedCode, status.code); }); } @@ -355,12 +366,26 @@ TEST_P(SupplicantStaIfaceHidlTest, SetMboCellularDataStatus) { uint32_t driverCapMask = 0; // Get MBO support from the device. - sta_iface_->getWpaDriverCapabilities( - [&](const SupplicantStatus& status, uint32_t driverCapMaskInternal) { - EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + if (nullptr != sta_iface_v1_4_) { + sta_iface_v1_4_->getWpaDriverCapabilities_1_4( + [&](const ::android::hardware::wifi::supplicant::V1_4:: + SupplicantStatus& status, + uint32_t driverCapMaskInternal) { + EXPECT_EQ(::android::hardware::wifi::supplicant::V1_4:: + SupplicantStatusCode::SUCCESS, + status.code); + + driverCapMask = driverCapMaskInternal; + }); + } else { + sta_iface_->getWpaDriverCapabilities( + [&](const SupplicantStatus& status, + uint32_t driverCapMaskInternal) { + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); - driverCapMask = driverCapMaskInternal; - }); + driverCapMask = driverCapMaskInternal; + }); + } SupplicantStatusCode expectedStatusCode = (driverCapMask & WpaDriverCapabilitiesMask::MBO) diff --git a/wifi/supplicant/1.4/ISupplicantStaIface.hal b/wifi/supplicant/1.4/ISupplicantStaIface.hal index db9a35b28d..f9e4c9b696 100644 --- a/wifi/supplicant/1.4/ISupplicantStaIface.hal +++ b/wifi/supplicant/1.4/ISupplicantStaIface.hal @@ -73,4 +73,15 @@ interface ISupplicantStaIface extends @1.3::ISupplicantStaIface { */ initiateVenueUrlAnqpQuery(MacAddress macAddress) generates (SupplicantStatus status); + + /** + * Get wpa driver capabilities. + * + * @return status Status of the operation, and a bitmap of wpa driver features. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_UNKNOWN|, + */ + getWpaDriverCapabilities_1_4() generates (SupplicantStatus status, + bitfield driverCapabilitiesMask); }; diff --git a/wifi/supplicant/1.4/ISupplicantStaNetwork.hal b/wifi/supplicant/1.4/ISupplicantStaNetwork.hal index 42958792b6..80beedf7f7 100644 --- a/wifi/supplicant/1.4/ISupplicantStaNetwork.hal +++ b/wifi/supplicant/1.4/ISupplicantStaNetwork.hal @@ -24,6 +24,16 @@ import @1.4::ISupplicantStaNetworkCallback; * configuration it controls. */ interface ISupplicantStaNetwork extends @1.3::ISupplicantStaNetwork { + /** + * Possible mask of values for KeyMgmt param. + */ + enum KeyMgmtMask : @1.3::ISupplicantStaNetwork.KeyMgmtMask { + /** + * SAE PK mode + */ + SAE_PK, + }; + /** * Possible mask of values for PairwiseCipher param. */ @@ -160,4 +170,22 @@ interface ISupplicantStaNetwork extends @1.3::ISupplicantStaNetwork { * |SupplicantStatusCode.FAILURE_NETWORK_INVALID| */ enableSaeH2eOnlyMode(bool enable) generates (SupplicantStatus status); + + /** + * Set whether to enable SAE PK (Public Key) only mode to enable public AP validation. + * When enabled, only SAE PK network is allowed; otherwise PK is optional. + * If this API is not called before connecting to an SAE + * network, SAE PK mode depends on SAE PK config in wpa_supplicant configuration. + * If SAE PK config of wpa_supplicant configuration is not set, + * the default mode is optional (support for both PK and standard mode). + * + * @param enable true to set, false otherwise. + * @return status Status of the operation. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_UNKNOWN|, + * |SupplicantStatusCode.FAILURE_NETWORK_INVALID|, + * |SupplicantStatusCode.FAILURE_UNSUPPORTED| + */ + enableSaePkOnlyMode(bool enable) generates (SupplicantStatus status); }; diff --git a/wifi/supplicant/1.4/types.hal b/wifi/supplicant/1.4/types.hal index b4b6a365b9..18af8fe393 100644 --- a/wifi/supplicant/1.4/types.hal +++ b/wifi/supplicant/1.4/types.hal @@ -18,6 +18,7 @@ package android.hardware.wifi.supplicant@1.4; import @1.0::SupplicantStatusCode; import @1.3::ConnectionCapabilities; +import @1.3::WpaDriverCapabilitiesMask; /** * Detailed network mode for legacy network @@ -71,3 +72,13 @@ struct SupplicantStatus { */ string debugMessage; }; + +/** + * WPA Driver capability. + */ +enum WpaDriverCapabilitiesMask : @1.3::WpaDriverCapabilitiesMask { + /** + * + */ + SAE_PK = 1 << 2, +}; diff --git a/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp index e079abca48..c0b5a70434 100644 --- a/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp +++ b/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp @@ -245,6 +245,16 @@ TEST_P(SupplicantStaIfaceHidlTest, InitiateVenueUrlAnqpQuery) { }); } +/* + * GetWpaDriverCapabilities + */ +TEST_P(SupplicantStaIfaceHidlTest, GetWpaDriverCapabilities) { + sta_iface_->getWpaDriverCapabilities_1_4( + [&](const SupplicantStatusV1_4& status, uint32_t) { + EXPECT_EQ(SupplicantStatusCodeV1_4::SUCCESS, status.code); + }); +} + GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantStaIfaceHidlTest); INSTANTIATE_TEST_CASE_P( PerInstance, SupplicantStaIfaceHidlTest, diff --git a/wifi/supplicant/1.4/vts/functional/supplicant_sta_network_hidl_test.cpp b/wifi/supplicant/1.4/vts/functional/supplicant_sta_network_hidl_test.cpp index 86314e2451..0e38c4b26b 100644 --- a/wifi/supplicant/1.4/vts/functional/supplicant_sta_network_hidl_test.cpp +++ b/wifi/supplicant/1.4/vts/functional/supplicant_sta_network_hidl_test.cpp @@ -46,11 +46,15 @@ using SupplicantStatusV1_4 = ::android::hardware::wifi::supplicant::V1_4::SupplicantStatus; using SupplicantStatusCodeV1_4 = ::android::hardware::wifi::supplicant::V1_4::SupplicantStatusCode; +using WpaDriverCapabilitiesMaskV1_4 = + ::android::hardware::wifi::supplicant::V1_4::WpaDriverCapabilitiesMask; class SupplicantStaNetworkHidlTest : public SupplicantHidlTestBaseV1_4 { public: virtual void SetUp() override { SupplicantHidlTestBaseV1_4::SetUp(); + sta_iface_ = getSupplicantStaIface_1_4(supplicant_); + ASSERT_NE(nullptr, sta_iface_.get()); sta_network_ = createSupplicantStaNetwork(supplicant_); ASSERT_NE(sta_network_.get(), nullptr); /* variable used to check if the underlying HAL version is 1.4 or @@ -61,10 +65,21 @@ class SupplicantStaNetworkHidlTest : public SupplicantHidlTestBaseV1_4 { } protected: + sp<::android::hardware::wifi::supplicant::V1_4::ISupplicantStaIface> + sta_iface_; sp<::android::hardware::wifi::supplicant::V1_4::ISupplicantStaNetwork> v1_4 = nullptr; // ISupplicantStaNetwork object used for all tests in this fixture. sp sta_network_; + bool isSaePkSupported() { + uint32_t caps; + sta_iface_->getWpaDriverCapabilities_1_4( + [&](const SupplicantStatusV1_4& status, uint32_t capsInternal) { + EXPECT_EQ(SupplicantStatusCodeV1_4::SUCCESS, status.code); + caps = capsInternal; + }); + return !!(caps & WpaDriverCapabilitiesMaskV1_4::SAE_PK); + } }; class NetworkCallback : public ISupplicantStaNetworkCallback { @@ -106,6 +121,22 @@ TEST_P(SupplicantStaNetworkHidlTest, EnableSaeH2eOnlyMode) { }); } +/* + * enable SAE PK only mode + */ +TEST_P(SupplicantStaNetworkHidlTest, EnableSaePkOnlyMode) { + LOG(INFO) << "SAE-PK Supported: " << isSaePkSupported(); + SupplicantStatusCodeV1_4 expectedCode = + isSaePkSupported() ? SupplicantStatusCodeV1_4::SUCCESS + : SupplicantStatusCodeV1_4::FAILURE_UNSUPPORTED; + v1_4->enableSaePkOnlyMode(true, [&](const SupplicantStatusV1_4& status) { + EXPECT_EQ(expectedCode, status.code); + }); + v1_4->enableSaePkOnlyMode(false, [&](const SupplicantStatusV1_4& status) { + EXPECT_EQ(expectedCode, status.code); + }); +} + GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantStaNetworkHidlTest); INSTANTIATE_TEST_CASE_P( PerInstance, SupplicantStaNetworkHidlTest, -- GitLab From 1162d8e903b7cabc4c1ebab13b4ef8fc35b42525 Mon Sep 17 00:00:00 2001 From: Sooraj Sasindran Date: Thu, 22 Oct 2020 15:24:14 -0700 Subject: [PATCH 261/790] Provide secondary link capacity estimation Provide intrface to get secondary link capacity estimation Bug: 162373679 Test: build Change-Id: I371f1f8ad820f8b20c972c3310ebe82b3790a577 --- radio/1.6/IRadioIndication.hal | 14 ++++++ radio/1.6/types.hal | 44 +++++++++++++++++++ .../functional/radio_hidl_hal_utils_v1_6.h | 4 ++ radio/1.6/vts/functional/radio_indication.cpp | 6 +++ 4 files changed, 68 insertions(+) diff --git a/radio/1.6/IRadioIndication.hal b/radio/1.6/IRadioIndication.hal index c135090947..f195c0e665 100644 --- a/radio/1.6/IRadioIndication.hal +++ b/radio/1.6/IRadioIndication.hal @@ -18,6 +18,8 @@ package android.hardware.radio@1.6; import @1.0::RadioIndicationType; import @1.5::IRadioIndication; +import @1.6::SetupDataCallResult; +import @1.6::LinkCapacityEstimate; /** * Interface declaring unsolicited radio indications. @@ -53,4 +55,16 @@ interface IRadioIndication extends @1.5::IRadioIndication { * @param apn Apn to unthrottle */ oneway unthrottleApn(RadioIndicationType type, string apn); + + /** + * Indicates current link capacity estimate. + * This replaces @1.2::IRadioIndication.currentLinkCapacityEstimate(). + * This indication is sent whenever the reporting criteria, as set by + * @1.2::IRadio.setLinkCapacityReportingCriteria, are met and the indication is not + * suppressed by @1.2::IRadio.setIndicationFilter_1_2(). + * + * @param type Type of radio indication + * @param lce LinkCapacityEstimate + */ + oneway currentLinkCapacityEstimate_1_6(RadioIndicationType type, LinkCapacityEstimate lce); }; diff --git a/radio/1.6/types.hal b/radio/1.6/types.hal index 8f842a3989..4f32b3c66f 100644 --- a/radio/1.6/types.hal +++ b/radio/1.6/types.hal @@ -350,3 +350,47 @@ enum NrDualConnectivityState: int32_t { */ DISABLE_IMMEDIATE= 3, }; + +/** + * Overwritten from @1.2::LinkCapacityEstimate to update LinkCapacityEstimate to 1.6 version. + */ +struct LinkCapacityEstimate { + + /** + * Estimated downlink capacity in kbps. In case of a dual connected network, + * this includes capacity of both primary and secondary. This bandwidth estimate shall be + * the estimated maximum sustainable link bandwidth (as would be measured + * at the Upper PDCP or SNDCP SAP). If the DL Aggregate Maximum Bit Rate is known, + * this value shall not exceed the DL-AMBR for the Internet PDN connection. + * This must be filled with -1 if network is not connected. + */ + uint32_t downlinkCapacityKbps; + + /** + * Estimated uplink capacity in kbps. In case of a dual connected network, + * this includes capacity of both primary and secondary. This bandwidth estimate shall be the + * estimated maximum sustainable link bandwidth (as would be measured at the + * Upper PDCP or SNDCP SAP). If the UL Aggregate Maximum Bit Rate is known, + * this value shall not exceed the UL-AMBR for the Internet PDN connection. + * This must be filled with -1 if network is not connected. + */ + uint32_t uplinkCapacityKbps; + + /** + * Estimated downlink capacity of secondary carrier in a dual connected NR mode in kbps. + * This bandwidth estimate shall be the estimated maximum sustainable link bandwidth + * (as would be measured at the Upper PDCP or SNDCP SAP). This is valid only + * in if device is connected to both primary and secodary in dual connected + * mode. This must be filled with -1 if secondary is not connected. + */ + uint32_t secondaryDownlinkCapacityKbps; + + /** + * Estimated uplink capacity secondary carrier in a dual connected NR mode in kbps. + * This bandwidth estimate shall be the estimated + * maximum sustainable link bandwidth (as would be measured at the Upper PDCP or SNDCP SAP). + * This is valid only in if device is connected to both primary and secodary in dual connected + * mode.This must be filled with -1 if secondary is not connected. + */ + uint32_t secondaryUplinkCapacityKbps; +}; diff --git a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h index 989ba6db96..6189be6add 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h +++ b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h @@ -865,6 +865,10 @@ class RadioIndication_v1_6 : public ::android::hardware::radio::V1_6::IRadioIndi RadioIndicationType type, const ::android::hardware::radio::V1_2::LinkCapacityEstimate& lce); + Return currentLinkCapacityEstimate_1_6( + RadioIndicationType type, + const ::android::hardware::radio::V1_6::LinkCapacityEstimate& lce); + Return currentPhysicalChannelConfigs( RadioIndicationType type, const ::android::hardware::hidl_vec< diff --git a/radio/1.6/vts/functional/radio_indication.cpp b/radio/1.6/vts/functional/radio_indication.cpp index b353c821d8..afde291a47 100644 --- a/radio/1.6/vts/functional/radio_indication.cpp +++ b/radio/1.6/vts/functional/radio_indication.cpp @@ -124,6 +124,12 @@ Return RadioIndication_v1_6::currentLinkCapacityEstimate( return Void(); } +Return RadioIndication_v1_6::currentLinkCapacityEstimate_1_6( + RadioIndicationType /*type*/, + const ::android::hardware::radio::V1_6::LinkCapacityEstimate& /*lce*/) { + return Void(); +} + Return RadioIndication_v1_6::currentPhysicalChannelConfigs( RadioIndicationType /*type*/, const ::android::hardware::hidl_vec< -- GitLab From e9d1e7d384e557667e83228a9c3b89936b35a37e Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Wed, 4 Nov 2020 11:44:16 -0800 Subject: [PATCH 262/790] wifi: Add STA + STA HIDL API's Add the HIDL API's + shim + VTS tests. Bug: 170305665 Test: atest VtsHalWifiV1_3TargetTest VtsHalWifiV1_5TargetTest Change-Id: I26ada11aebfe8082bfda251cf7e6990e0aa08a06 --- .../functional/wifi_sta_iface_hidl_test.cpp | 15 +- wifi/1.5/Android.bp | 1 + wifi/1.5/IWifiChip.hal | 79 ++++++++++ wifi/1.5/IWifiNanIface.hal | 9 +- wifi/1.5/IWifiNanIfaceEventCallback.hal | 4 +- wifi/1.5/IWifiStaIface.hal | 44 ++++++ wifi/1.5/default/hidl_struct_util.cpp | 51 +++--- wifi/1.5/default/hidl_struct_util.h | 4 +- .../tests/hidl_struct_util_unit_tests.cpp | 43 ++--- wifi/1.5/default/wifi_chip.cpp | 31 +++- wifi/1.5/default/wifi_chip.h | 12 +- wifi/1.5/default/wifi_legacy_hal.cpp | 11 ++ wifi/1.5/default/wifi_legacy_hal.h | 4 + wifi/1.5/default/wifi_legacy_hal_stubs.cpp | 2 + wifi/1.5/default/wifi_sta_iface.cpp | 14 +- wifi/1.5/default/wifi_sta_iface.h | 8 +- wifi/1.5/types.hal | 42 ++++- wifi/1.5/vts/functional/Android.bp | 23 +++ .../vts/functional/wifi_chip_hidl_test.cpp | 149 ++++++++++++++++++ .../functional/wifi_sta_iface_hidl_test.cpp | 117 ++++++++++++++ 20 files changed, 606 insertions(+), 57 deletions(-) create mode 100644 wifi/1.5/IWifiStaIface.hal create mode 100644 wifi/1.5/vts/functional/wifi_chip_hidl_test.cpp create mode 100644 wifi/1.5/vts/functional/wifi_sta_iface_hidl_test.cpp diff --git a/wifi/1.3/vts/functional/wifi_sta_iface_hidl_test.cpp b/wifi/1.3/vts/functional/wifi_sta_iface_hidl_test.cpp index 22efe0875a..78e62390eb 100644 --- a/wifi/1.3/vts/functional/wifi_sta_iface_hidl_test.cpp +++ b/wifi/1.3/vts/functional/wifi_sta_iface_hidl_test.cpp @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -88,7 +89,6 @@ TEST_P(WifiStaIfaceHidlTest, GetLinkLayerStats_1_3) { // No-op if link layer stats is not supported. return; } - // Enable link layer stats collection. EXPECT_EQ(WifiStatusCode::SUCCESS, HIDL_INVOKE(wifi_sta_iface_, enableLinkLayerStatsCollection, true) @@ -96,8 +96,17 @@ TEST_P(WifiStaIfaceHidlTest, GetLinkLayerStats_1_3) { // Retrieve link layer stats. const auto& status_and_stats = HIDL_INVOKE(wifi_sta_iface_, getLinkLayerStats_1_3); - EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_stats.first.code); - EXPECT_GT(status_and_stats.second.timeStampInMs, 0u); + sp staIface1_5 = + android::hardware::wifi::V1_5::IWifiStaIface::castFrom(wifi_sta_iface_); + if (staIface1_5.get() == nullptr) { + EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_stats.first.code); + EXPECT_GT(status_and_stats.second.timeStampInMs, 0u); + } else { + // not supported on 1.5 HAL. + EXPECT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED, + status_and_stats.first.code); + } + // Disable link layer stats collection. EXPECT_EQ( WifiStatusCode::SUCCESS, diff --git a/wifi/1.5/Android.bp b/wifi/1.5/Android.bp index ecb0a35f18..5a62a3a832 100644 --- a/wifi/1.5/Android.bp +++ b/wifi/1.5/Android.bp @@ -9,6 +9,7 @@ hidl_interface { "IWifiChip.hal", "IWifiNanIface.hal", "IWifiNanIfaceEventCallback.hal", + "IWifiStaIface.hal", ], interfaces: [ "android.hardware.wifi@1.0", diff --git a/wifi/1.5/IWifiChip.hal b/wifi/1.5/IWifiChip.hal index 5243baf7f3..dcc927900a 100644 --- a/wifi/1.5/IWifiChip.hal +++ b/wifi/1.5/IWifiChip.hal @@ -35,6 +35,53 @@ interface IWifiChip extends @1.4::IWifiChip { WIGIG = 1 << 14, }; + /** + * When there are 2 or more simultaneous STA connections, this use case hint indicates what + * use-case is being enabled by the framework. This use case hint can be used by the firmware + * to modify various firmware configurations like: + * - Allowed BSSIDs the firmware can choose for the initial connection/roaming attempts. + * - Duty cycle to choose for the 2 STA connections if the radio is in MCC mode. + * - Whether roaming, APF and other offloads needs to be enabled or not. + * Note: + * - This will be invoked before an active wifi connection is established on the second + * interface. + * - This use-case hint is implicitly void when the second STA interface is brought down. + */ + enum MultiStaUseCase : uint8_t { + /** + * Usage: + * - This will be sent down for make before break use-case. + * - Platform is trying to speculatively connect to a second network and evaluate it without + * disrupting the primary connection. + * Requirements for Firmware: + * - Do not reduce the number of tx/rx chains of primary connection. + * - If using MCC, should set the MCC duty cycle of the primary connection to be higher than + * the secondary connection (maybe 70/30 split). + * - Should pick the best BSSID for the secondary STA (disregard the chip mode) independent + * of the primary STA: + * - Don’t optimize for DBS vs MCC/SCC + * - Should not impact the primary connection’s bssid selection: + * - Don’t downgrade chains of the existing primary connection. + * - Don’t optimize for DBS vs MCC/SCC. + */ + DUAL_STA_TRANSIENT_PREFER_PRIMARY = 0, + /** + * Usage: + * - This will be sent down for any app requested peer to peer connections. + * - In this case, both the connections needs to be allocated equal resources. + * - For the peer to peer use case, BSSID for the secondary connection will be chosen by the + * framework. + * + * Requirements for Firmware: + * - Can choose MCC or DBS mode depending on the MCC efficiency and HW capability. + * - If using MCC, set the MCC duty cycle of the primary connection to be equal to the + * secondary connection. + * - Prefer BSSID candidates which will help provide the best "overall" performance for both + * the connections. + */ + DUAL_STA_NON_TRANSIENT_UNBIASED = 1, + }; + /** * Get the capabilities supported by this chip. * @@ -48,4 +95,36 @@ interface IWifiChip extends @1.4::IWifiChip { */ getCapabilities_1_5() generates (WifiStatus status, bitfield capabilities); + + /** + * Invoked to indicate that the provided iface is the primary STA iface when there are more + * than 1 STA iface concurrently active. + * Note: If the wifi firmware/chip cannot support multiple instances of any offload + * (like roaming, APF, rssi threshold, etc), the firmware should ensure that these + * offloads are at least enabled for the primary interface. If the new primary interface is + * already connected to a network, the firmware must switch all the offloads on + * this new interface without disconnecting. + * + * @param ifname Name of the STA iface. + * @return status WifiStatus of the operation. + * Possible status codes: + * |WifiStatusCode.SUCCESS|, + * |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|, + * |WifiStatusCode.ERROR_INVALID_ARGS| + */ + setMultiStaPrimaryConnection(string ifName) generates (WifiStatus status); + + /** + * Invoked to indicate the STA + STA use-case that is active. + * + * Refer to documentation of |MultiStaUseCase| for details. + * + * @param useCase Use case that is active. + * @return status WifiStatus of the operation. + * Possible status codes: + * |WifiStatusCode.SUCCESS|, + * |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|, + * |WifiStatusCode.ERROR_INVALID_ARGS| + */ + setMultiStaUseCase(MultiStaUseCase useCase) generates (WifiStatus status); }; diff --git a/wifi/1.5/IWifiNanIface.hal b/wifi/1.5/IWifiNanIface.hal index 93257b525a..d7c15de9d8 100644 --- a/wifi/1.5/IWifiNanIface.hal +++ b/wifi/1.5/IWifiNanIface.hal @@ -92,13 +92,12 @@ interface IWifiNanIface extends @1.4::IWifiNanIface { * |WifiStatusCode.SUCCESS|, * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID| */ - registerEventCallback_1_5(IWifiNanIfaceEventCallback callback) - generates (WifiStatus status); + registerEventCallback_1_5(IWifiNanIfaceEventCallback callback) generates (WifiStatus status); /** * Get NAN capabilities. Asynchronous response is with * |IWifiNanIfaceEventCallback.notifyCapabilitiesResponse|. - + * * Note: supersedes the @1.0::IWifiNanIface.getCapabilitiesRequest() method which is deprecated * as of HAL version 1.5. * @@ -109,5 +108,5 @@ interface IWifiNanIface extends @1.4::IWifiNanIface { * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|, * |WifiStatusCode.ERROR_UNKNOWN| */ - getCapabilitiesRequest_1_5(CommandIdShort cmdId) generates (WifiStatus status); -}; \ No newline at end of file + getCapabilitiesRequest_1_5(CommandIdShort cmdId) generates (WifiStatus status); +}; diff --git a/wifi/1.5/IWifiNanIfaceEventCallback.hal b/wifi/1.5/IWifiNanIfaceEventCallback.hal index 867c03c47e..046b702f4f 100644 --- a/wifi/1.5/IWifiNanIfaceEventCallback.hal +++ b/wifi/1.5/IWifiNanIfaceEventCallback.hal @@ -40,5 +40,5 @@ interface IWifiNanIfaceEventCallback extends @1.2::IWifiNanIfaceEventCallback { * @param capabilities Capability data. */ oneway notifyCapabilitiesResponse_1_5(CommandIdShort id, WifiNanStatus status, - NanCapabilities capabilities); -}; \ No newline at end of file + NanCapabilities capabilities); +}; diff --git a/wifi/1.5/IWifiStaIface.hal b/wifi/1.5/IWifiStaIface.hal new file mode 100644 index 0000000000..e9d411e00b --- /dev/null +++ b/wifi/1.5/IWifiStaIface.hal @@ -0,0 +1,44 @@ +/* + * 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. + */ + +package android.hardware.wifi@1.5; + +import @1.0::WifiStatus; +import @1.3::IWifiStaIface; + +/** + * Interface used to represent a single STA iface. + * + * IWifiChip.createStaIface() must return a @1.5::IWifiStaIface when supported. + */ +interface IWifiStaIface extends @1.3::IWifiStaIface { + /** + * Retrieve the latest link layer stats. + * Must fail if |StaIfaceCapabilityMask.LINK_LAYER_STATS| is not set or if + * link layer stats collection hasn't been explicitly enabled. + * + * @return status WifiStatus of the operation. + * Possible status codes: + * |WifiStatusCode.SUCCESS|, + * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|, + * |WifiStatusCode.ERROR_NOT_SUPPORTED|, + * |WifiStatusCode.ERROR_NOT_STARTED|, + * |WifiStatusCode.ERROR_NOT_AVAILABLE|, + * |WifiStatusCode.ERROR_UNKNOWN| + * @return stats Instance of |LinkLayerStats|. + */ + getLinkLayerStats_1_5() generates (WifiStatus status, StaLinkLayerStats stats); +}; diff --git a/wifi/1.5/default/hidl_struct_util.cpp b/wifi/1.5/default/hidl_struct_util.cpp index 578f3e2f0f..83d06fe398 100644 --- a/wifi/1.5/default/hidl_struct_util.cpp +++ b/wifi/1.5/default/hidl_struct_util.cpp @@ -866,46 +866,48 @@ bool convertLegacyLinkLayerRadioStatsToHidl( bool convertLegacyLinkLayerStatsToHidl( const legacy_hal::LinkLayerStats& legacy_stats, - V1_3::StaLinkLayerStats* hidl_stats) { + StaLinkLayerStats* hidl_stats) { if (!hidl_stats) { return false; } *hidl_stats = {}; // iface legacy_stats conversion. - hidl_stats->iface.beaconRx = legacy_stats.iface.beacon_rx; - hidl_stats->iface.avgRssiMgmt = legacy_stats.iface.rssi_mgmt; - hidl_stats->iface.wmeBePktStats.rxMpdu = + 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; - hidl_stats->iface.wmeBePktStats.txMpdu = + hidl_stats->iface.V1_0.wmeBePktStats.txMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].tx_mpdu; - hidl_stats->iface.wmeBePktStats.lostMpdu = + hidl_stats->iface.V1_0.wmeBePktStats.lostMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].mpdu_lost; - hidl_stats->iface.wmeBePktStats.retries = + hidl_stats->iface.V1_0.wmeBePktStats.retries = legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].retries; - hidl_stats->iface.wmeBkPktStats.rxMpdu = + hidl_stats->iface.V1_0.wmeBkPktStats.rxMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].rx_mpdu; - hidl_stats->iface.wmeBkPktStats.txMpdu = + hidl_stats->iface.V1_0.wmeBkPktStats.txMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].tx_mpdu; - hidl_stats->iface.wmeBkPktStats.lostMpdu = + hidl_stats->iface.V1_0.wmeBkPktStats.lostMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].mpdu_lost; - hidl_stats->iface.wmeBkPktStats.retries = + hidl_stats->iface.V1_0.wmeBkPktStats.retries = legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].retries; - hidl_stats->iface.wmeViPktStats.rxMpdu = + hidl_stats->iface.V1_0.wmeViPktStats.rxMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].rx_mpdu; - hidl_stats->iface.wmeViPktStats.txMpdu = + hidl_stats->iface.V1_0.wmeViPktStats.txMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].tx_mpdu; - hidl_stats->iface.wmeViPktStats.lostMpdu = + hidl_stats->iface.V1_0.wmeViPktStats.lostMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].mpdu_lost; - hidl_stats->iface.wmeViPktStats.retries = + hidl_stats->iface.V1_0.wmeViPktStats.retries = legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].retries; - hidl_stats->iface.wmeVoPktStats.rxMpdu = + hidl_stats->iface.V1_0.wmeVoPktStats.rxMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].rx_mpdu; - hidl_stats->iface.wmeVoPktStats.txMpdu = + hidl_stats->iface.V1_0.wmeVoPktStats.txMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].tx_mpdu; - hidl_stats->iface.wmeVoPktStats.lostMpdu = + hidl_stats->iface.V1_0.wmeVoPktStats.lostMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].mpdu_lost; - hidl_stats->iface.wmeVoPktStats.retries = + hidl_stats->iface.V1_0.wmeVoPktStats.retries = legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].retries; + hidl_stats->iface.timeSliceDutyCycleInPercent = + legacy_stats.iface.info.time_slicing_duty_cycle_percent; // radio legacy_stats conversion. std::vector hidl_radios_stats; for (const auto& legacy_radio_stats : legacy_stats.radios) { @@ -2787,6 +2789,17 @@ legacy_hal::wifi_interface_type convertHidlIfaceTypeToLegacy( } CHECK(false); } + +legacy_hal::wifi_multi_sta_use_case convertHidlMultiStaUseCaseToLegacy( + IWifiChip::MultiStaUseCase use_case) { + switch (use_case) { + case IWifiChip::MultiStaUseCase::DUAL_STA_TRANSIENT_PREFER_PRIMARY: + return legacy_hal::WIFI_DUAL_STA_TRANSIENT_PREFER_PRIMARY; + case IWifiChip::MultiStaUseCase::DUAL_STA_NON_TRANSIENT_UNBIASED: + return legacy_hal::WIFI_DUAL_STA_NON_TRANSIENT_UNBIASED; + } + CHECK(false); +} } // namespace hidl_struct_util } // namespace implementation } // namespace V1_5 diff --git a/wifi/1.5/default/hidl_struct_util.h b/wifi/1.5/default/hidl_struct_util.h index b0b1d22dfe..49d8a1213e 100644 --- a/wifi/1.5/default/hidl_struct_util.h +++ b/wifi/1.5/default/hidl_struct_util.h @@ -69,6 +69,8 @@ bool convertLegacyWifiMacInfosToHidl( 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); // STA iface conversion methods. bool convertLegacyFeaturesToHidlStaCapabilities( @@ -96,7 +98,7 @@ bool convertLegacyVectorOfCachedGscanResultsToHidl( std::vector* hidl_scan_datas); bool convertLegacyLinkLayerStatsToHidl( const legacy_hal::LinkLayerStats& legacy_stats, - V1_3::StaLinkLayerStats* hidl_stats); + StaLinkLayerStats* hidl_stats); bool convertLegacyRoamingCapabilitiesToHidl( const legacy_hal::wifi_roaming_capabilities& legacy_caps, StaRoamingCapabilities* hidl_caps); diff --git a/wifi/1.5/default/tests/hidl_struct_util_unit_tests.cpp b/wifi/1.5/default/tests/hidl_struct_util_unit_tests.cpp index 81eb14e8e0..ea84c61f66 100644 --- a/wifi/1.5/default/tests/hidl_struct_util_unit_tests.cpp +++ b/wifi/1.5/default/tests/hidl_struct_util_unit_tests.cpp @@ -154,6 +154,8 @@ TEST_F(HidlStructUtilTest, canConvertLegacyLinkLayerStatsToHidl) { legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].mpdu_lost = rand(); legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].retries = rand(); + legacy_stats.iface.info.time_slicing_duty_cycle_percent = rand(); + for (auto& radio : legacy_stats.radios) { radio.stats.on_time = rand(); radio.stats.tx_time = rand(); @@ -182,46 +184,49 @@ TEST_F(HidlStructUtilTest, canConvertLegacyLinkLayerStatsToHidl) { radio.channel_stats.push_back(channel_stat2); } - V1_3::StaLinkLayerStats converted{}; + V1_5::StaLinkLayerStats converted{}; hidl_struct_util::convertLegacyLinkLayerStatsToHidl(legacy_stats, &converted); - EXPECT_EQ(legacy_stats.iface.beacon_rx, converted.iface.beaconRx); - EXPECT_EQ(legacy_stats.iface.rssi_mgmt, converted.iface.avgRssiMgmt); + 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, - converted.iface.wmeBePktStats.rxMpdu); + converted.iface.V1_0.wmeBePktStats.rxMpdu); EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].tx_mpdu, - converted.iface.wmeBePktStats.txMpdu); + converted.iface.V1_0.wmeBePktStats.txMpdu); EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].mpdu_lost, - converted.iface.wmeBePktStats.lostMpdu); + converted.iface.V1_0.wmeBePktStats.lostMpdu); EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].retries, - converted.iface.wmeBePktStats.retries); + converted.iface.V1_0.wmeBePktStats.retries); EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].rx_mpdu, - converted.iface.wmeBkPktStats.rxMpdu); + converted.iface.V1_0.wmeBkPktStats.rxMpdu); EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].tx_mpdu, - converted.iface.wmeBkPktStats.txMpdu); + converted.iface.V1_0.wmeBkPktStats.txMpdu); EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].mpdu_lost, - converted.iface.wmeBkPktStats.lostMpdu); + converted.iface.V1_0.wmeBkPktStats.lostMpdu); EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].retries, - converted.iface.wmeBkPktStats.retries); + converted.iface.V1_0.wmeBkPktStats.retries); EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].rx_mpdu, - converted.iface.wmeViPktStats.rxMpdu); + converted.iface.V1_0.wmeViPktStats.rxMpdu); EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].tx_mpdu, - converted.iface.wmeViPktStats.txMpdu); + converted.iface.V1_0.wmeViPktStats.txMpdu); EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].mpdu_lost, - converted.iface.wmeViPktStats.lostMpdu); + converted.iface.V1_0.wmeViPktStats.lostMpdu); EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].retries, - converted.iface.wmeViPktStats.retries); + converted.iface.V1_0.wmeViPktStats.retries); EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].rx_mpdu, - converted.iface.wmeVoPktStats.rxMpdu); + converted.iface.V1_0.wmeVoPktStats.rxMpdu); EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].tx_mpdu, - converted.iface.wmeVoPktStats.txMpdu); + converted.iface.V1_0.wmeVoPktStats.txMpdu); EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].mpdu_lost, - converted.iface.wmeVoPktStats.lostMpdu); + converted.iface.V1_0.wmeVoPktStats.lostMpdu); EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].retries, - converted.iface.wmeVoPktStats.retries); + converted.iface.V1_0.wmeVoPktStats.retries); + + 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++) { diff --git a/wifi/1.5/default/wifi_chip.cpp b/wifi/1.5/default/wifi_chip.cpp index ebff722859..1c238c8ec0 100644 --- a/wifi/1.5/default/wifi_chip.cpp +++ b/wifi/1.5/default/wifi_chip.cpp @@ -678,6 +678,20 @@ Return WifiChip::registerEventCallback_1_4( hidl_status_cb, event_callback); } +Return WifiChip::setMultiStaPrimaryConnection( + const hidl_string& ifname, setMultiStaPrimaryConnection_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::setMultiStaPrimaryConnectionInternal, + hidl_status_cb, ifname); +} + +Return 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); +} + void WifiChip::invalidateAndRemoveAllIfaces() { invalidateAndClearAll(ap_ifaces_); invalidateAndClearAll(nan_ifaces_); @@ -1016,7 +1030,7 @@ WifiStatus WifiChip::removeP2pIfaceInternal(const std::string& ifname) { return createWifiStatus(WifiStatusCode::SUCCESS); } -std::pair> +std::pair> WifiChip::createStaIfaceInternal() { if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::STA)) { return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; @@ -1050,7 +1064,7 @@ WifiChip::getStaIfaceNamesInternal() { return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(sta_ifaces_)}; } -std::pair> WifiChip::getStaIfaceInternal( +std::pair> WifiChip::getStaIfaceInternal( const std::string& ifname) { const auto iface = findUsingName(sta_ifaces_, ifname); if (!iface.get()) { @@ -1295,6 +1309,19 @@ WifiStatus WifiChip::registerEventCallbackInternal_1_4( return createWifiStatus(WifiStatusCode::SUCCESS); } +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)); + return createWifiStatusFromLegacyError(legacy_status); +} + WifiStatus WifiChip::handleChipConfiguration( /* NONNULL */ std::unique_lock* lock, ChipModeId mode_id) { diff --git a/wifi/1.5/default/wifi_chip.h b/wifi/1.5/default/wifi_chip.h index 8cc0452df9..693d480bda 100644 --- a/wifi/1.5/default/wifi_chip.h +++ b/wifi/1.5/default/wifi_chip.h @@ -163,6 +163,12 @@ class WifiChip : public V1_5::IWifiChip { Return registerEventCallback_1_4( const sp& event_callback, registerEventCallback_1_4_cb hidl_status_cb) override; + Return setMultiStaPrimaryConnection( + const hidl_string& ifname, + setMultiStaPrimaryConnection_cb hidl_status_cb) override; + Return setMultiStaUseCase( + MultiStaUseCase use_case, + setMultiStaUseCase_cb hidl_status_cb) override; private: void invalidateAndRemoveAllIfaces(); @@ -201,9 +207,9 @@ class WifiChip : public V1_5::IWifiChip { std::pair> getP2pIfaceInternal( const std::string& ifname); WifiStatus removeP2pIfaceInternal(const std::string& ifname); - std::pair> createStaIfaceInternal(); + std::pair> createStaIfaceInternal(); std::pair> getStaIfaceNamesInternal(); - std::pair> getStaIfaceInternal( + std::pair> getStaIfaceInternal( const std::string& ifname); WifiStatus removeStaIfaceInternal(const std::string& ifname); std::pair> @@ -233,6 +239,8 @@ class WifiChip : public V1_5::IWifiChip { createRttControllerInternal_1_4(const sp& bound_iface); WifiStatus registerEventCallbackInternal_1_4( const sp& event_callback); + WifiStatus setMultiStaPrimaryConnectionInternal(const std::string& ifname); + WifiStatus setMultiStaUseCaseInternal(MultiStaUseCase use_case); WifiStatus handleChipConfiguration( std::unique_lock* lock, ChipModeId mode_id); diff --git a/wifi/1.5/default/wifi_legacy_hal.cpp b/wifi/1.5/default/wifi_legacy_hal.cpp index 398bfac3f6..76e718b74a 100644 --- a/wifi/1.5/default/wifi_legacy_hal.cpp +++ b/wifi/1.5/default/wifi_legacy_hal.cpp @@ -1510,6 +1510,17 @@ wifi_error WifiLegacyHal::getSupportedIfaceName(uint32_t iface_type, 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::multiStaSetUseCase(wifi_multi_sta_use_case use_case) { + return global_func_table_.wifi_multi_sta_set_use_case(global_handle_, + use_case); +} + void WifiLegacyHal::invalidate() { global_handle_ = nullptr; iface_name_to_handle_.clear(); diff --git a/wifi/1.5/default/wifi_legacy_hal.h b/wifi/1.5/default/wifi_legacy_hal.h index 9a06efd342..555c540102 100644 --- a/wifi/1.5/default/wifi_legacy_hal.h +++ b/wifi/1.5/default/wifi_legacy_hal.h @@ -382,6 +382,10 @@ class WifiLegacyHal { virtual wifi_error deleteVirtualInterface(const std::string& ifname); wifi_error getSupportedIfaceName(uint32_t iface_type, std::string& ifname); + // STA + STA functions + virtual wifi_error multiStaSetPrimaryConnection(const std::string& ifname); + virtual wifi_error multiStaSetUseCase(wifi_multi_sta_use_case use_case); + private: // Retrieve interface handles for all the available interfaces. wifi_error retrieveIfaceHandles(); diff --git a/wifi/1.5/default/wifi_legacy_hal_stubs.cpp b/wifi/1.5/default/wifi_legacy_hal_stubs.cpp index a1122e97f2..71d2ddf688 100644 --- a/wifi/1.5/default/wifi_legacy_hal_stubs.cpp +++ b/wifi/1.5/default/wifi_legacy_hal_stubs.cpp @@ -147,6 +147,8 @@ bool initHalFuncTableWithStubs(wifi_hal_fn* hal_fn) { populateStubFor(&hal_fn->wifi_get_supported_iface_name); populateStubFor(&hal_fn->wifi_early_initialize); populateStubFor(&hal_fn->wifi_get_chip_feature_set); + populateStubFor(&hal_fn->wifi_multi_sta_set_primary_connection); + populateStubFor(&hal_fn->wifi_multi_sta_set_use_case); return true; } diff --git a/wifi/1.5/default/wifi_sta_iface.cpp b/wifi/1.5/default/wifi_sta_iface.cpp index 04087fda7a..f3dcfc5bca 100644 --- a/wifi/1.5/default/wifi_sta_iface.cpp +++ b/wifi/1.5/default/wifi_sta_iface.cpp @@ -163,6 +163,13 @@ Return WifiStaIface::getLinkLayerStats_1_3( hidl_status_cb); } +Return 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); +} + Return WifiStaIface::startRssiMonitoring( uint32_t cmd_id, int32_t max_rssi, int32_t min_rssi, startRssiMonitoring_cb hidl_status_cb) { @@ -470,6 +477,11 @@ WifiStaIface::getLinkLayerStatsInternal() { std::pair WifiStaIface::getLinkLayerStatsInternal_1_3() { + return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}}; +} + +std::pair +WifiStaIface::getLinkLayerStatsInternal_1_5() { legacy_hal::wifi_error legacy_status; legacy_hal::LinkLayerStats legacy_stats; std::tie(legacy_status, legacy_stats) = @@ -477,7 +489,7 @@ WifiStaIface::getLinkLayerStatsInternal_1_3() { if (legacy_status != legacy_hal::WIFI_SUCCESS) { return {createWifiStatusFromLegacyError(legacy_status), {}}; } - V1_3::StaLinkLayerStats hidl_stats; + V1_5::StaLinkLayerStats hidl_stats; if (!hidl_struct_util::convertLegacyLinkLayerStatsToHidl(legacy_stats, &hidl_stats)) { return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}}; diff --git a/wifi/1.5/default/wifi_sta_iface.h b/wifi/1.5/default/wifi_sta_iface.h index 7695f3c9f1..94873c9494 100644 --- a/wifi/1.5/default/wifi_sta_iface.h +++ b/wifi/1.5/default/wifi_sta_iface.h @@ -19,7 +19,7 @@ #include #include -#include +#include #include "hidl_callback_util.h" #include "wifi_iface_util.h" @@ -35,7 +35,7 @@ using namespace android::hardware::wifi::V1_0; /** * HIDL interface object used to control a STA Iface instance. */ -class WifiStaIface : public V1_3::IWifiStaIface { +class WifiStaIface : public V1_5::IWifiStaIface { public: WifiStaIface(const std::string& ifname, const std::weak_ptr legacy_hal, @@ -78,6 +78,8 @@ class WifiStaIface : public V1_3::IWifiStaIface { getLinkLayerStats_cb hidl_status_cb) override; Return getLinkLayerStats_1_3( getLinkLayerStats_1_3_cb hidl_status_cb) override; + Return getLinkLayerStats_1_5( + getLinkLayerStats_1_5_cb hidl_status_cb) override; Return startRssiMonitoring( uint32_t cmd_id, int32_t max_rssi, int32_t min_rssi, startRssiMonitoring_cb hidl_status_cb) override; @@ -138,6 +140,8 @@ class WifiStaIface : public V1_3::IWifiStaIface { std::pair getLinkLayerStatsInternal(); std::pair getLinkLayerStatsInternal_1_3(); + std::pair + getLinkLayerStatsInternal_1_5(); WifiStatus startRssiMonitoringInternal(uint32_t cmd_id, int32_t max_rssi, int32_t min_rssi); WifiStatus stopRssiMonitoringInternal(uint32_t cmd_id); diff --git a/wifi/1.5/types.hal b/wifi/1.5/types.hal index 5873f79b3b..3fbec82658 100644 --- a/wifi/1.5/types.hal +++ b/wifi/1.5/types.hal @@ -16,10 +16,14 @@ package android.hardware.wifi@1.5; +import @1.0::StaLinkLayerIfaceStats; +import @1.0::StaLinkLayerIfacePacketStats; +import @1.0::TimeStampInMs; import @1.0::WifiBand; import @1.0::NanCipherSuiteType; import @1.0::NanCapabilities; import @1.2::NanConfigRequestSupplemental; +import @1.3::StaLinkLayerRadioStats; /** * Wifi bands defined in 80211 spec. @@ -48,6 +52,7 @@ struct NanConfigRequestSupplemental { * Baseline information as defined in HAL 1.2. */ @1.2::NanConfigRequestSupplemental V1_2; + /** * Controls whether NAN instant communication mode is enabled. */ @@ -62,8 +67,43 @@ struct NanCapabilities { * Baseline information as defined in HAL 1.0. */ @1.0::NanCapabilities V1_0; + /** * Flag to indicate id instant communication mode is supported. */ bool instantCommunicationModeSupportFlag; -}; \ No newline at end of file +}; + +/** + * Iface statistics for the current connection. + */ +struct StaLinkLayerIfaceStats { + /** + * Baseline information as defined in HAL 1.0. + */ + @1.0::StaLinkLayerIfaceStats V1_0; + + /** + * Duty cycle for the iface. + * if this iface is being served using time slicing on a radio with one or more ifaces + * (i.e MCC), then the duty cycle assigned to this iface in %. + * If not using time slicing (i.e SCC or DBS), set to 100. + */ + uint8_t timeSliceDutyCycleInPercent; +}; + +/** + * Link layer stats retrieved via |getLinkLayerStats|. + */ +struct StaLinkLayerStats { + StaLinkLayerIfaceStats iface; + + vec radios; + + /** + * TimeStamp for each stats sample. + * This is the absolute milliseconds from boot when these stats were + * sampled. + */ + TimeStampInMs timeStampInMs; +}; diff --git a/wifi/1.5/vts/functional/Android.bp b/wifi/1.5/vts/functional/Android.bp index a7ba498103..eb595c9082 100644 --- a/wifi/1.5/vts/functional/Android.bp +++ b/wifi/1.5/vts/functional/Android.bp @@ -14,6 +14,29 @@ // limitations under the License. // +cc_test { + name: "VtsHalWifiV1_5TargetTest", + defaults: ["VtsHalTargetTestDefaults"], + srcs: [ + "wifi_chip_hidl_test.cpp", + "wifi_sta_iface_hidl_test.cpp", + ], + static_libs: [ + "VtsHalWifiV1_0TargetTestUtil", + "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", + "libwifi-system-iface", + ], + test_suites: [ + "general-tests", + "vts", + ], +} + // These tests are split out so that they can be conditioned on presence of the // "android.hardware.wifi.aware" feature. cc_test { diff --git a/wifi/1.5/vts/functional/wifi_chip_hidl_test.cpp b/wifi/1.5/vts/functional/wifi_chip_hidl_test.cpp new file mode 100644 index 0000000000..eeaa7e0d38 --- /dev/null +++ b/wifi/1.5/vts/functional/wifi_chip_hidl_test.cpp @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#undef NAN // NAN is defined in bionic/libc/include/math.h:38 + +#include +#include +#include +#include +#include +#include +#include + +#include "wifi_hidl_call_util.h" +#include "wifi_hidl_test_utils.h" + +using ::android::sp; +using ::android::hardware::hidl_string; +using ::android::hardware::hidl_vec; +using ::android::hardware::Return; +using ::android::hardware::Void; +using ::android::hardware::wifi::V1_0::ChipModeId; +using ::android::hardware::wifi::V1_0::IfaceType; +using ::android::hardware::wifi::V1_0::IWifiIface; +using ::android::hardware::wifi::V1_0::IWifiStaIface; +using ::android::hardware::wifi::V1_0::WifiDebugRingBufferStatus; +using ::android::hardware::wifi::V1_0::WifiStatus; +using ::android::hardware::wifi::V1_0::WifiStatusCode; +using ::android::hardware::wifi::V1_4::IWifiChipEventCallback; +using ::android::hardware::wifi::V1_5::IWifiChip; + +/** + * Fixture to use for all Wifi chip HIDL interface tests. + */ +class WifiChipHidlTest : public ::testing::TestWithParam { + public: + virtual void SetUp() override { + // Make sure to start with a clean state + stopWifi(GetInstanceName()); + + wifi_chip_ = IWifiChip::castFrom(getWifiChip(GetInstanceName())); + ASSERT_NE(nullptr, wifi_chip_.get()); + } + + virtual void TearDown() override { stopWifi(GetInstanceName()); } + + protected: + // Helper function to configure the Chip in one of the supported modes. + // Most of the non-mode-configuration-related methods require chip + // to be first configured. + ChipModeId configureChipForIfaceType(IfaceType type, bool expectSuccess) { + ChipModeId mode_id; + EXPECT_EQ(expectSuccess, + configureChipToSupportIfaceType(wifi_chip_, type, &mode_id)); + return mode_id; + } + + WifiStatusCode createStaIface(sp* sta_iface) { + const auto& status_and_iface = HIDL_INVOKE(wifi_chip_, createStaIface); + *sta_iface = status_and_iface.second; + return status_and_iface.first.code; + } + + std::string getIfaceName(const sp& iface) { + const auto& status_and_name = HIDL_INVOKE(iface, getName); + EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_name.first.code); + return status_and_name.second; + } + + std::vector> create2StaIfacesIfPossible() { + configureChipForIfaceType(IfaceType::STA, true); + sp iface1, iface2; + EXPECT_EQ(WifiStatusCode::SUCCESS, createStaIface(&iface1)); + EXPECT_NE(nullptr, iface1.get()); + + // Try to create 2nd iface + auto status = createStaIface(&iface2); + if (status != WifiStatusCode::SUCCESS) { + return {iface1}; + } + EXPECT_NE(nullptr, iface2.get()); + return {iface1, iface2}; + } + + sp wifi_chip_; + + private: + std::string GetInstanceName() { return GetParam(); } +}; + +/* + * setMultiStaPrimaryConnection + * + * Only run if device supports 2 STA ifaces. + */ +TEST_P(WifiChipHidlTest, setMultiStaPrimaryConnection) { + auto ifaces = create2StaIfacesIfPossible(); + if (ifaces.size() < 2) { + GTEST_SKIP() << "Device does not support more than 1 STA concurrently"; + } + + const auto& status = HIDL_INVOKE(wifi_chip_, setMultiStaPrimaryConnection, + getIfaceName(ifaces.front())); + if (status.code != WifiStatusCode::SUCCESS) { + EXPECT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED, status.code); + } +} + +/* + * setMultiStaUseCase + * + * Only run if device supports 2 STA ifaces. + */ +TEST_P(WifiChipHidlTest, setMultiStaUseCase) { + auto ifaces = create2StaIfacesIfPossible(); + if (ifaces.size() < 2) { + GTEST_SKIP() << "Device does not support more than 1 STA concurrently"; + } + + const auto& status = HIDL_INVOKE( + wifi_chip_, setMultiStaUseCase, + IWifiChip::MultiStaUseCase::DUAL_STA_TRANSIENT_PREFER_PRIMARY); + if (status.code != WifiStatusCode::SUCCESS) { + EXPECT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED, status.code); + } +} + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiChipHidlTest); +INSTANTIATE_TEST_SUITE_P( + PerInstance, WifiChipHidlTest, + testing::ValuesIn(android::hardware::getAllHalInstanceNames( + ::android::hardware::wifi::V1_5::IWifi::descriptor)), + android::hardware::PrintInstanceNameToString); diff --git a/wifi/1.5/vts/functional/wifi_sta_iface_hidl_test.cpp b/wifi/1.5/vts/functional/wifi_sta_iface_hidl_test.cpp new file mode 100644 index 0000000000..8cc3300324 --- /dev/null +++ b/wifi/1.5/vts/functional/wifi_sta_iface_hidl_test.cpp @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Staache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include "wifi_hidl_call_util.h" +#include "wifi_hidl_test_utils.h" + +using ::android::sp; +using ::android::hardware::hidl_array; +using ::android::hardware::wifi::V1_0::WifiStatus; +using ::android::hardware::wifi::V1_0::WifiStatusCode; +using ::android::hardware::wifi::V1_5::IWifiChip; +using ::android::hardware::wifi::V1_5::IWifiStaIface; + +/** + * Fixture to use for all STA Iface HIDL interface tests. + */ +class WifiStaIfaceHidlTest : public ::testing::TestWithParam { + public: + virtual void SetUp() override { + // Make sure to start with a clean state + stopWifi(GetInstanceName()); + + wifi_sta_iface_ = + IWifiStaIface::castFrom(getWifiStaIface(GetInstanceName())); + ASSERT_NE(nullptr, wifi_sta_iface_.get()); + } + + virtual void TearDown() override { stopWifi(GetInstanceName()); } + + protected: + bool isCapabilitySupported(IWifiStaIface::StaIfaceCapabilityMask cap_mask) { + const auto& status_and_caps = + HIDL_INVOKE(wifi_sta_iface_, getCapabilities); + EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_caps.first.code); + return (status_and_caps.second & cap_mask) != 0; + } + + WifiStatusCode createStaIface(sp* sta_iface) { + sp wifi_chip = + IWifiChip::castFrom(getWifiChip(GetInstanceName())); + EXPECT_NE(nullptr, wifi_chip.get()); + const auto& status_and_iface = HIDL_INVOKE(wifi_chip, createStaIface); + *sta_iface = IWifiStaIface::castFrom(status_and_iface.second); + return status_and_iface.first.code; + } + + sp wifi_sta_iface_; + + private: + std::string GetInstanceName() { return GetParam(); } +}; + +/* + * GetLinkLayerStats_1_5 + * Ensures that calls to get link layer stats V1_5 will retrieve a non-empty + * StaLinkLayerStats after link layer stats collection is enabled. + */ +TEST_P(WifiStaIfaceHidlTest, GetLinkLayerStats_1_5) { + if (!isCapabilitySupported( + IWifiStaIface::StaIfaceCapabilityMask::LINK_LAYER_STATS)) { + // No-op if link layer stats is not supported. + return; + } + + // Enable link layer stats collection. + EXPECT_EQ(WifiStatusCode::SUCCESS, + HIDL_INVOKE(wifi_sta_iface_, enableLinkLayerStatsCollection, true) + .code); + // Retrieve link layer stats. + const auto& status_and_stats = + HIDL_INVOKE(wifi_sta_iface_, getLinkLayerStats_1_5); + EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_stats.first.code); + EXPECT_GT(status_and_stats.second.timeStampInMs, 0u); + // Try to create 2nd iface. If yes, it should fill in the duty cycle field. + sp iface; + auto status = createStaIface(&iface); + if (status == WifiStatusCode::SUCCESS) { + EXPECT_GT(status_and_stats.second.iface.timeSliceDutyCycleInPercent, + 0u); + } + // Disable link layer stats collection. + EXPECT_EQ( + WifiStatusCode::SUCCESS, + HIDL_INVOKE(wifi_sta_iface_, disableLinkLayerStatsCollection).code); +} + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiStaIfaceHidlTest); +INSTANTIATE_TEST_SUITE_P( + PerInstance, WifiStaIfaceHidlTest, + testing::ValuesIn(android::hardware::getAllHalInstanceNames( + ::android::hardware::wifi::V1_5::IWifi::descriptor)), + android::hardware::PrintInstanceNameToString); -- GitLab From 434cbe6492e1ddc01c740670a2829872c53f33d6 Mon Sep 17 00:00:00 2001 From: raychi Date: Fri, 7 Aug 2020 18:43:57 +0800 Subject: [PATCH 263/790] USB Gadget hal v1.2 interface USB Gadget hal v1.2 include: 1. NCM function support 2. inquiry USB speed 3. inquiry HAL version Bug: 168282708 Test: build pass and functions works normally Change-Id: I16927a06cd3e311ac6ab945f490eb0747638e6da --- .../compatibility_matrix.current.xml | 2 +- usb/gadget/1.2/Android.bp | 17 ++++ usb/gadget/1.2/IUsbGadget.hal | 30 ++++++ usb/gadget/1.2/IUsbGadgetCallback.hal | 33 +++++++ usb/gadget/1.2/types.hal | 92 +++++++++++++++++++ 5 files changed, 173 insertions(+), 1 deletion(-) create mode 100644 usb/gadget/1.2/Android.bp create mode 100644 usb/gadget/1.2/IUsbGadget.hal create mode 100644 usb/gadget/1.2/IUsbGadgetCallback.hal create mode 100644 usb/gadget/1.2/types.hal diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index 57f390c055..7a9feb2eab 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -521,7 +521,7 @@ android.hardware.usb.gadget - 1.0-1 + 1.0-2 IUsbGadget default diff --git a/usb/gadget/1.2/Android.bp b/usb/gadget/1.2/Android.bp new file mode 100644 index 0000000000..386f00fcfc --- /dev/null +++ b/usb/gadget/1.2/Android.bp @@ -0,0 +1,17 @@ +// This file is autogenerated by hidl-gen -Landroidbp. + +hidl_interface { + name: "android.hardware.usb.gadget@1.2", + root: "android.hardware", + srcs: [ + "types.hal", + "IUsbGadget.hal", + "IUsbGadgetCallback.hal", + ], + interfaces: [ + "android.hardware.usb.gadget@1.0", + "android.hardware.usb.gadget@1.1", + "android.hidl.base@1.0", + ], + gen_java: true, +} diff --git a/usb/gadget/1.2/IUsbGadget.hal b/usb/gadget/1.2/IUsbGadget.hal new file mode 100644 index 0000000000..5c6e930b39 --- /dev/null +++ b/usb/gadget/1.2/IUsbGadget.hal @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.usb.gadget@1.2; + +import IUsbGadgetCallback; +import android.hardware.usb.gadget@1.1::IUsbGadget; + +interface IUsbGadget extends @1.1::IUsbGadget { + /** + * The function is used to query current USB speed. + * + * @param callback IUsbGadgetCallback::getUsbSpeedCb used to propagate + * current USB speed. + */ + oneway getUsbSpeed(IUsbGadgetCallback callback); +}; diff --git a/usb/gadget/1.2/IUsbGadgetCallback.hal b/usb/gadget/1.2/IUsbGadgetCallback.hal new file mode 100644 index 0000000000..41705736fb --- /dev/null +++ b/usb/gadget/1.2/IUsbGadgetCallback.hal @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.usb.gadget@1.2; + +import UsbSpeed; +import android.hardware.usb.gadget@1.0::IUsbGadgetCallback; + +interface IUsbGadgetCallback extends @1.0::IUsbGadgetCallback { + /** + * Used to convey the current USB speed to the caller. + * Must be called either when USB state changes due to USB enumeration or + * when caller requested for USB speed through getUsbSpeed. + * + * @param speed USB Speed defined by UsbSpeed showed current USB + * connection speed. + */ + oneway getUsbSpeedCb(UsbSpeed speed); +}; + diff --git a/usb/gadget/1.2/types.hal b/usb/gadget/1.2/types.hal new file mode 100644 index 0000000000..a5c079d9c6 --- /dev/null +++ b/usb/gadget/1.2/types.hal @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.usb.gadget@1.2; + +import android.hardware.usb.gadget@1.0::GadgetFunction; + +enum GadgetFunction : @1.0::GadgetFunction { + /** + * NCM - NCM function. + */ + NCM = 1 << 10, +}; + +enum UsbSpeed : uint32_t { + /** + * UNKNOWN - Not Connected or Unsupported Speed + */ + UNKNOWN = -1, + + /** + * USB Low Speed + */ + LOWSPEED = 0, + + /** + * USB Full Speed + */ + FULLSPEED = 1, + + /** + * USB High Speed + */ + HIGHSPEED = 2, + + /** + * USB Super Speed + */ + SUPERSPEED = 3, + + /** + * USB Super Speed 10Gbps + */ + SUPERSPEED_10Gb = 4, + + /** + * USB Super Speed 20Gbps + */ + SUPERSPEED_20Gb = 5, + + /** + * USB4 Gen2 x 1 (10Gbps) + */ + USB4_GEN2_10Gb = 6, + + /** + * USB4 Gen2 x 2 (20Gbps) + */ + USB4_GEN2_20Gb = 7, + + /** + * USB4 Gen3 x 1 (20Gbps) + */ + USB4_GEN3_20Gb = 8, + + /** + * USB4 Gen3 x 2 (40Gbps) + */ + USB4_GEN3_40Gb = 9, + + /** + * This is a suggestion if needed. + * + * Reserved Speed -- It is a newer speed after USB4 v1.0 announcement. + * If this speed is detected, the HAL implementation should convert current + * speed to above speeds which is lower and the closest. + */ + RESERVED_SPEED = 64, +}; -- GitLab From e96a2a8461f5b3547e2fca54103e4c7ec3528ebd Mon Sep 17 00:00:00 2001 From: raychi Date: Wed, 7 Oct 2020 23:23:56 +0800 Subject: [PATCH 264/790] Add USB Gadget Hal v1.2 default implementation Bug: 168282708 Test: build pass Change-Id: I6894261f1b4fd19664c2a0dcdb737d605a129585 --- usb/gadget/1.2/default/Android.bp | 40 +++ usb/gadget/1.2/default/UsbGadget.cpp | 286 ++++++++++++++++++ usb/gadget/1.2/default/UsbGadget.h | 108 +++++++ ...android.hardware.usb.gadget@1.2-service.rc | 7 + ...ndroid.hardware.usb.gadget@1.2-service.xml | 11 + usb/gadget/1.2/default/lib/Android.bp | 41 +++ usb/gadget/1.2/default/lib/MonitorFfs.cpp | 269 ++++++++++++++++ usb/gadget/1.2/default/lib/UsbGadgetUtils.cpp | 205 +++++++++++++ .../1.2/default/lib/include/UsbGadgetCommon.h | 179 +++++++++++ usb/gadget/1.2/default/service.cpp | 52 ++++ 10 files changed, 1198 insertions(+) create mode 100644 usb/gadget/1.2/default/Android.bp create mode 100644 usb/gadget/1.2/default/UsbGadget.cpp create mode 100644 usb/gadget/1.2/default/UsbGadget.h create mode 100644 usb/gadget/1.2/default/android.hardware.usb.gadget@1.2-service.rc create mode 100644 usb/gadget/1.2/default/android.hardware.usb.gadget@1.2-service.xml create mode 100644 usb/gadget/1.2/default/lib/Android.bp create mode 100644 usb/gadget/1.2/default/lib/MonitorFfs.cpp create mode 100644 usb/gadget/1.2/default/lib/UsbGadgetUtils.cpp create mode 100644 usb/gadget/1.2/default/lib/include/UsbGadgetCommon.h create mode 100644 usb/gadget/1.2/default/service.cpp diff --git a/usb/gadget/1.2/default/Android.bp b/usb/gadget/1.2/default/Android.bp new file mode 100644 index 0000000000..9c73a59dc2 --- /dev/null +++ b/usb/gadget/1.2/default/Android.bp @@ -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. + */ + +cc_binary { + name: "android.hardware.usb.gadget@1.2-service", + defaults: ["hidl_defaults"], + relative_install_path: "hw", + init_rc: ["android.hardware.usb.gadget@1.2-service.rc"], + vintf_fragments: ["android.hardware.usb.gadget@1.2-service.xml"], + vendor: true, + srcs: [ + "service.cpp", + "UsbGadget.cpp", + ], + shared_libs: [ + "android.hardware.usb.gadget@1.0", + "android.hardware.usb.gadget@1.1", + "android.hardware.usb.gadget@1.2", + "libbase", + "libcutils", + "libhardware", + "libhidlbase", + "liblog", + "libutils", + ], + static_libs: ["libusbconfigfs-2"], +} diff --git a/usb/gadget/1.2/default/UsbGadget.cpp b/usb/gadget/1.2/default/UsbGadget.cpp new file mode 100644 index 0000000000..8dd229e0fd --- /dev/null +++ b/usb/gadget/1.2/default/UsbGadget.cpp @@ -0,0 +1,286 @@ +/* + * 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 "android.hardware.usb.gadget@1.2-service" + +#include "UsbGadget.h" +#include +#include +#include +#include +#include +#include +#include +#include + +namespace android { +namespace hardware { +namespace usb { +namespace gadget { +namespace V1_2 { +namespace implementation { + +UsbGadget::UsbGadget() { + if (access(OS_DESC_PATH, R_OK) != 0) { + ALOGE("configfs setup not done yet"); + abort(); + } +} + +void currentFunctionsAppliedCallback(bool functionsApplied, void* payload) { + UsbGadget* gadget = (UsbGadget*)payload; + gadget->mCurrentUsbFunctionsApplied = functionsApplied; +} + +Return UsbGadget::getCurrentUsbFunctions(const sp& callback) { + Return ret = callback->getCurrentUsbFunctionsCb( + mCurrentUsbFunctions, mCurrentUsbFunctionsApplied ? Status::FUNCTIONS_APPLIED + : Status::FUNCTIONS_NOT_APPLIED); + if (!ret.isOk()) ALOGE("Call to getCurrentUsbFunctionsCb failed %s", ret.description().c_str()); + + return Void(); +} + +Return UsbGadget::getUsbSpeed(const sp& callback) { + std::string current_speed; + if (ReadFileToString(SPEED_PATH, ¤t_speed)) { + current_speed = Trim(current_speed); + ALOGI("current USB speed is %s", current_speed.c_str()); + if (current_speed == "low-speed") + mUsbSpeed = UsbSpeed::LOWSPEED; + else if (current_speed == "full-speed") + mUsbSpeed = UsbSpeed::FULLSPEED; + else if (current_speed == "high-speed") + mUsbSpeed = UsbSpeed::HIGHSPEED; + else if (current_speed == "super-speed") + mUsbSpeed = UsbSpeed::SUPERSPEED; + else if (current_speed == "super-speed-plus") + mUsbSpeed = UsbSpeed::SUPERSPEED_10Gb; + else if (current_speed == "UNKNOWN") + mUsbSpeed = UsbSpeed::UNKNOWN; + else { + /** + * This part is used for USB4 or reserved speed. + * + * If reserved speed is detected, it needs to convert to other speeds. + * For example: + * If the bandwidth of new speed is 7G, adding new if + * statement and set mUsbSpeed to SUPERSPEED. + * If the bandwidth of new speed is 80G, adding new if + * statement and set mUsbSpeed to USB4_GEN3_40Gb. + */ + mUsbSpeed = UsbSpeed::RESERVED_SPEED; + } + } else { + ALOGE("Fail to read current speed"); + mUsbSpeed = UsbSpeed::UNKNOWN; + } + + if (callback) { + Return ret = callback->getUsbSpeedCb(mUsbSpeed); + + if (!ret.isOk()) ALOGE("Call to getUsbSpeedCb failed %s", ret.description().c_str()); + } + + return Void(); +} + +V1_0::Status UsbGadget::tearDownGadget() { + if (resetGadget() != V1_0::Status::SUCCESS) return V1_0::Status::ERROR; + + if (monitorFfs.isMonitorRunning()) { + monitorFfs.reset(); + } else { + ALOGI("mMonitor not running"); + } + return V1_0::Status::SUCCESS; +} + +Return UsbGadget::reset() { + if (!WriteStringToFile("none", PULLUP_PATH)) { + ALOGI("Gadget cannot be pulled down"); + return Status::ERROR; + } + + usleep(kDisconnectWaitUs); + + if (!WriteStringToFile(kGadgetName, PULLUP_PATH)) { + ALOGI("Gadget cannot be pulled up"); + return Status::ERROR; + } + + return Status::SUCCESS; +} + +static V1_0::Status validateAndSetVidPid(uint64_t functions) { + V1_0::Status ret = V1_0::Status::SUCCESS; + + switch (functions) { + case static_cast(V1_2::GadgetFunction::MTP): + ret = setVidPid("0x18d1", "0x4ee1"); + break; + case V1_2::GadgetFunction::ADB | V1_2::GadgetFunction::MTP: + ret = setVidPid("0x18d1", "0x4ee2"); + break; + case static_cast(V1_2::GadgetFunction::RNDIS): + ret = setVidPid("0x18d1", "0x4ee3"); + break; + case V1_2::GadgetFunction::ADB | V1_2::GadgetFunction::RNDIS: + ret = setVidPid("0x18d1", "0x4ee4"); + break; + case static_cast(V1_2::GadgetFunction::PTP): + ret = setVidPid("0x18d1", "0x4ee5"); + break; + case V1_2::GadgetFunction::ADB | V1_2::GadgetFunction::PTP: + ret = setVidPid("0x18d1", "0x4ee6"); + break; + case static_cast(V1_2::GadgetFunction::ADB): + ret = setVidPid("0x18d1", "0x4ee7"); + break; + case static_cast(V1_2::GadgetFunction::MIDI): + ret = setVidPid("0x18d1", "0x4ee8"); + break; + case V1_2::GadgetFunction::ADB | V1_2::GadgetFunction::MIDI: + ret = setVidPid("0x18d1", "0x4ee9"); + break; + case static_cast(V1_2::GadgetFunction::NCM): + ret = setVidPid("0x18d1", "0x4eeb"); + break; + case V1_2::GadgetFunction::ADB | V1_2::GadgetFunction::NCM: + ret = setVidPid("0x18d1", "0x4eec"); + break; + case static_cast(V1_2::GadgetFunction::ACCESSORY): + ret = setVidPid("0x18d1", "0x2d00"); + break; + case V1_2::GadgetFunction::ADB | V1_2::GadgetFunction::ACCESSORY: + ret = setVidPid("0x18d1", "0x2d01"); + break; + case static_cast(V1_2::GadgetFunction::AUDIO_SOURCE): + ret = setVidPid("0x18d1", "0x2d02"); + break; + case V1_2::GadgetFunction::ADB | V1_2::GadgetFunction::AUDIO_SOURCE: + ret = setVidPid("0x18d1", "0x2d03"); + break; + case V1_2::GadgetFunction::ACCESSORY | V1_2::GadgetFunction::AUDIO_SOURCE: + ret = setVidPid("0x18d1", "0x2d04"); + break; + case V1_2::GadgetFunction::ADB | V1_2::GadgetFunction::ACCESSORY | + V1_2::GadgetFunction::AUDIO_SOURCE: + ret = setVidPid("0x18d1", "0x2d05"); + break; + default: + ALOGE("Combination not supported"); + ret = V1_0::Status::CONFIGURATION_NOT_SUPPORTED; + } + return ret; +} + +V1_0::Status UsbGadget::setupFunctions(uint64_t functions, + const sp& callback, + uint64_t timeout) { + bool ffsEnabled = false; + int i = 0; + + if (addGenericAndroidFunctions(&monitorFfs, functions, &ffsEnabled, &i) != + V1_0::Status::SUCCESS) + return V1_0::Status::ERROR; + + if ((functions & V1_2::GadgetFunction::ADB) != 0) { + ffsEnabled = true; + if (addAdb(&monitorFfs, &i) != V1_0::Status::SUCCESS) return V1_0::Status::ERROR; + } + + // Pull up the gadget right away when there are no ffs functions. + if (!ffsEnabled) { + if (!WriteStringToFile(kGadgetName, PULLUP_PATH)) return V1_0::Status::ERROR; + mCurrentUsbFunctionsApplied = true; + if (callback) callback->setCurrentUsbFunctionsCb(functions, V1_0::Status::SUCCESS); + return V1_0::Status::SUCCESS; + } + + monitorFfs.registerFunctionsAppliedCallback(¤tFunctionsAppliedCallback, this); + // Monitors the ffs paths to pull up the gadget when descriptors are written. + // Also takes of the pulling up the gadget again if the userspace process + // dies and restarts. + monitorFfs.startMonitor(); + + if (kDebug) ALOGI("Mainthread in Cv"); + + if (callback) { + bool pullup = monitorFfs.waitForPullUp(timeout); + Return ret = callback->setCurrentUsbFunctionsCb( + functions, pullup ? V1_0::Status::SUCCESS : V1_0::Status::ERROR); + if (!ret.isOk()) ALOGE("setCurrentUsbFunctionsCb error %s", ret.description().c_str()); + } + + return V1_0::Status::SUCCESS; +} + +Return UsbGadget::setCurrentUsbFunctions(uint64_t functions, + const sp& callback, + uint64_t timeout) { + std::unique_lock lk(mLockSetCurrentFunction); + + mCurrentUsbFunctions = functions; + mCurrentUsbFunctionsApplied = false; + + // Unlink the gadget and stop the monitor if running. + V1_0::Status status = tearDownGadget(); + if (status != V1_0::Status::SUCCESS) { + goto error; + } + + ALOGI("Returned from tearDown gadget"); + + // Leave the gadget pulled down to give time for the host to sense disconnect. + usleep(kDisconnectWaitUs); + + if (functions == static_cast(V1_2::GadgetFunction::NONE)) { + if (callback == NULL) return Void(); + Return ret = callback->setCurrentUsbFunctionsCb(functions, V1_0::Status::SUCCESS); + if (!ret.isOk()) + ALOGE("Error while calling setCurrentUsbFunctionsCb %s", ret.description().c_str()); + return Void(); + } + + status = validateAndSetVidPid(functions); + + if (status != V1_0::Status::SUCCESS) { + goto error; + } + + status = setupFunctions(functions, callback, timeout); + if (status != V1_0::Status::SUCCESS) { + goto error; + } + + ALOGI("Usb Gadget setcurrent functions called successfully"); + return Void(); + +error: + ALOGI("Usb Gadget setcurrent functions failed"); + if (callback == NULL) return Void(); + Return ret = callback->setCurrentUsbFunctionsCb(functions, status); + if (!ret.isOk()) + ALOGE("Error while calling setCurrentUsbFunctionsCb %s", ret.description().c_str()); + return Void(); +} +} // namespace implementation +} // namespace V1_2 +} // namespace gadget +} // namespace usb +} // namespace hardware +} // namespace android diff --git a/usb/gadget/1.2/default/UsbGadget.h b/usb/gadget/1.2/default/UsbGadget.h new file mode 100644 index 0000000000..12ad8eed61 --- /dev/null +++ b/usb/gadget/1.2/default/UsbGadget.h @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_USB_GADGET_V1_2_USBGADGET_H +#define ANDROID_HARDWARE_USB_GADGET_V1_2_USBGADGET_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace android { +namespace hardware { +namespace usb { +namespace gadget { +namespace V1_2 { +namespace implementation { + +using ::android::sp; +using ::android::base::GetProperty; +using ::android::base::ReadFileToString; +using ::android::base::SetProperty; +using ::android::base::Trim; +using ::android::base::unique_fd; +using ::android::base::WriteStringToFile; +using ::android::hardware::hidl_array; +using ::android::hardware::hidl_memory; +using ::android::hardware::hidl_string; +using ::android::hardware::hidl_vec; +using ::android::hardware::Return; +using ::android::hardware::Void; +using ::android::hardware::usb::gadget::addAdb; +using ::android::hardware::usb::gadget::addEpollFd; +using ::android::hardware::usb::gadget::getVendorFunctions; +using ::android::hardware::usb::gadget::kDebug; +using ::android::hardware::usb::gadget::kDisconnectWaitUs; +using ::android::hardware::usb::gadget::linkFunction; +using ::android::hardware::usb::gadget::MonitorFfs; +using ::android::hardware::usb::gadget::resetGadget; +using ::android::hardware::usb::gadget::setVidPid; +using ::android::hardware::usb::gadget::unlinkFunctions; +using ::std::string; + +constexpr char kGadgetName[] = "11110000.usb"; +static MonitorFfs monitorFfs(kGadgetName); + +#define UDC_PATH "/sys/class/udc/11110000.usb/" +#define SPEED_PATH UDC_PATH "current_speed" + +struct UsbGadget : public IUsbGadget { + UsbGadget(); + + // Makes sure that only one request is processed at a time. + std::mutex mLockSetCurrentFunction; + uint64_t mCurrentUsbFunctions; + bool mCurrentUsbFunctionsApplied; + UsbSpeed mUsbSpeed; + + Return setCurrentUsbFunctions(uint64_t functions, + const sp& callback, + uint64_t timeout) override; + + Return getCurrentUsbFunctions(const sp& callback) override; + + Return reset() override; + + Return getUsbSpeed(const sp& callback) override; + + private: + V1_0::Status tearDownGadget(); + V1_0::Status setupFunctions(uint64_t functions, const sp& callback, + uint64_t timeout); +}; + +} // namespace implementation +} // namespace V1_2 +} // namespace gadget +} // namespace usb +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_USB_V1_2_USBGADGET_H diff --git a/usb/gadget/1.2/default/android.hardware.usb.gadget@1.2-service.rc b/usb/gadget/1.2/default/android.hardware.usb.gadget@1.2-service.rc new file mode 100644 index 0000000000..650b0850cd --- /dev/null +++ b/usb/gadget/1.2/default/android.hardware.usb.gadget@1.2-service.rc @@ -0,0 +1,7 @@ +service vendor.usb-gadget-hal-1-2 /vendor/bin/hw/android.hardware.usb.gadget@1.2-service + interface android.hardware.usb.gadget@1.0::IUsbGadget default + interface android.hardware.usb.gadget@1.1::IUsbGadget default + interface android.hardware.usb.gadget@1.2::IUsbGadget default + class hal + user system + group system shell mtp diff --git a/usb/gadget/1.2/default/android.hardware.usb.gadget@1.2-service.xml b/usb/gadget/1.2/default/android.hardware.usb.gadget@1.2-service.xml new file mode 100644 index 0000000000..8557f6ff50 --- /dev/null +++ b/usb/gadget/1.2/default/android.hardware.usb.gadget@1.2-service.xml @@ -0,0 +1,11 @@ + + + android.hardware.usb.gadget + hwbinder + 1.2 + + IUsbGadget + default + + + diff --git a/usb/gadget/1.2/default/lib/Android.bp b/usb/gadget/1.2/default/lib/Android.bp new file mode 100644 index 0000000000..727de136cb --- /dev/null +++ b/usb/gadget/1.2/default/lib/Android.bp @@ -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. + */ + +cc_library_static { + name: "libusbconfigfs-2", + vendor_available: true, + export_include_dirs: ["include"], + + srcs: [ + "UsbGadgetUtils.cpp", + "MonitorFfs.cpp", + ], + + cflags: [ + "-Wall", + "-Werror", + ], + + shared_libs: [ + "android.hardware.usb.gadget@1.0", + "android.hardware.usb.gadget@1.1", + "android.hardware.usb.gadget@1.2", + "libbase", + "libcutils", + "libhidlbase", + "libutils", + ], +} diff --git a/usb/gadget/1.2/default/lib/MonitorFfs.cpp b/usb/gadget/1.2/default/lib/MonitorFfs.cpp new file mode 100644 index 0000000000..0cdf038de1 --- /dev/null +++ b/usb/gadget/1.2/default/lib/MonitorFfs.cpp @@ -0,0 +1,269 @@ +/* + * 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 "libusbconfigfs" + +#include "include/UsbGadgetCommon.h" + +namespace android { +namespace hardware { +namespace usb { +namespace gadget { + +static volatile bool gadgetPullup; + +MonitorFfs::MonitorFfs(const char* const gadget) + : mWatchFd(), + mEndpointList(), + mLock(), + mCv(), + mLockFd(), + mCurrentUsbFunctionsApplied(false), + mMonitor(), + mCallback(NULL), + mPayload(NULL), + mGadgetName(gadget), + mMonitorRunning(false) { + unique_fd eventFd(eventfd(0, 0)); + if (eventFd == -1) { + ALOGE("mEventFd failed to create %d", errno); + abort(); + } + + unique_fd epollFd(epoll_create(2)); + if (epollFd == -1) { + ALOGE("mEpollFd failed to create %d", errno); + abort(); + } + + unique_fd inotifyFd(inotify_init()); + if (inotifyFd < 0) { + ALOGE("inotify init failed"); + abort(); + } + + if (addEpollFd(epollFd, inotifyFd) == -1) abort(); + + if (addEpollFd(epollFd, eventFd) == -1) abort(); + + mEpollFd = move(epollFd); + mInotifyFd = move(inotifyFd); + mEventFd = move(eventFd); + gadgetPullup = false; +} + +static void displayInotifyEvent(struct inotify_event* i) { + ALOGE(" wd =%2d; ", i->wd); + if (i->cookie > 0) ALOGE("cookie =%4d; ", i->cookie); + + ALOGE("mask = "); + if (i->mask & IN_ACCESS) ALOGE("IN_ACCESS "); + if (i->mask & IN_ATTRIB) ALOGE("IN_ATTRIB "); + if (i->mask & IN_CLOSE_NOWRITE) ALOGE("IN_CLOSE_NOWRITE "); + if (i->mask & IN_CLOSE_WRITE) ALOGE("IN_CLOSE_WRITE "); + if (i->mask & IN_CREATE) ALOGE("IN_CREATE "); + if (i->mask & IN_DELETE) ALOGE("IN_DELETE "); + if (i->mask & IN_DELETE_SELF) ALOGE("IN_DELETE_SELF "); + if (i->mask & IN_IGNORED) ALOGE("IN_IGNORED "); + if (i->mask & IN_ISDIR) ALOGE("IN_ISDIR "); + if (i->mask & IN_MODIFY) ALOGE("IN_MODIFY "); + if (i->mask & IN_MOVE_SELF) ALOGE("IN_MOVE_SELF "); + if (i->mask & IN_MOVED_FROM) ALOGE("IN_MOVED_FROM "); + if (i->mask & IN_MOVED_TO) ALOGE("IN_MOVED_TO "); + if (i->mask & IN_OPEN) ALOGE("IN_OPEN "); + if (i->mask & IN_Q_OVERFLOW) ALOGE("IN_Q_OVERFLOW "); + if (i->mask & IN_UNMOUNT) ALOGE("IN_UNMOUNT "); + ALOGE("\n"); + + if (i->len > 0) ALOGE(" name = %s\n", i->name); +} + +void* MonitorFfs::startMonitorFd(void* param) { + MonitorFfs* monitorFfs = (MonitorFfs*)param; + char buf[kBufferSize]; + bool writeUdc = true, stopMonitor = false; + struct epoll_event events[kEpollEvents]; + steady_clock::time_point disconnect; + + bool descriptorWritten = true; + for (int i = 0; i < static_cast(monitorFfs->mEndpointList.size()); i++) { + if (access(monitorFfs->mEndpointList.at(i).c_str(), R_OK)) { + descriptorWritten = false; + break; + } + } + + // notify here if the endpoints are already present. + if (descriptorWritten) { + usleep(kPullUpDelay); + if (!!WriteStringToFile(monitorFfs->mGadgetName, PULLUP_PATH)) { + lock_guard lock(monitorFfs->mLock); + monitorFfs->mCurrentUsbFunctionsApplied = true; + monitorFfs->mCallback(monitorFfs->mCurrentUsbFunctionsApplied, monitorFfs->mPayload); + gadgetPullup = true; + writeUdc = false; + ALOGI("GADGET pulled up"); + monitorFfs->mCv.notify_all(); + } + } + + while (!stopMonitor) { + int nrEvents = epoll_wait(monitorFfs->mEpollFd, events, kEpollEvents, -1); + + if (nrEvents <= 0) { + ALOGE("epoll wait did not return descriptor number"); + continue; + } + + for (int i = 0; i < nrEvents; i++) { + ALOGI("event=%u on fd=%d\n", events[i].events, events[i].data.fd); + + if (events[i].data.fd == monitorFfs->mInotifyFd) { + // Process all of the events in buffer returned by read(). + int numRead = read(monitorFfs->mInotifyFd, buf, kBufferSize); + for (char* p = buf; p < buf + numRead;) { + struct inotify_event* event = (struct inotify_event*)p; + if (kDebug) displayInotifyEvent(event); + + p += sizeof(struct inotify_event) + event->len; + + bool descriptorPresent = true; + for (int j = 0; j < static_cast(monitorFfs->mEndpointList.size()); j++) { + if (access(monitorFfs->mEndpointList.at(j).c_str(), R_OK)) { + if (kDebug) ALOGI("%s absent", monitorFfs->mEndpointList.at(j).c_str()); + descriptorPresent = false; + break; + } + } + + if (!descriptorPresent && !writeUdc) { + if (kDebug) ALOGI("endpoints not up"); + writeUdc = true; + disconnect = std::chrono::steady_clock::now(); + } else if (descriptorPresent && writeUdc) { + steady_clock::time_point temp = steady_clock::now(); + + if (std::chrono::duration_cast(temp - disconnect).count() < + kPullUpDelay) + usleep(kPullUpDelay); + + if (!!WriteStringToFile(monitorFfs->mGadgetName, PULLUP_PATH)) { + lock_guard lock(monitorFfs->mLock); + monitorFfs->mCurrentUsbFunctionsApplied = true; + monitorFfs->mCallback(monitorFfs->mCurrentUsbFunctionsApplied, + monitorFfs->mPayload); + ALOGI("GADGET pulled up"); + writeUdc = false; + gadgetPullup = true; + // notify the main thread to signal userspace. + monitorFfs->mCv.notify_all(); + } + } + } + } else { + uint64_t flag; + read(monitorFfs->mEventFd, &flag, sizeof(flag)); + if (flag == 100) { + stopMonitor = true; + break; + } + } + } + } + return NULL; +} + +void MonitorFfs::reset() { + lock_guard lock(mLockFd); + uint64_t flag = 100; + unsigned long ret; + + if (mMonitorRunning) { + // Stop the monitor thread by writing into signal fd. + ret = TEMP_FAILURE_RETRY(write(mEventFd, &flag, sizeof(flag))); + if (ret < 0) ALOGE("Error writing eventfd errno=%d", errno); + + ALOGI("mMonitor signalled to exit"); + mMonitor->join(); + ALOGI("mMonitor destroyed"); + mMonitorRunning = false; + } + + for (std::vector::size_type i = 0; i != mWatchFd.size(); i++) + inotify_rm_watch(mInotifyFd, mWatchFd[i]); + + mEndpointList.clear(); + gadgetPullup = false; + mCallback = NULL; + mPayload = NULL; +} + +bool MonitorFfs::startMonitor() { + mMonitor = unique_ptr(new thread(this->startMonitorFd, this)); + mMonitorRunning = true; + return true; +} + +bool MonitorFfs::isMonitorRunning() { + return mMonitorRunning; +} + +bool MonitorFfs::waitForPullUp(int timeout_ms) { + std::unique_lock lk(mLock); + + if (gadgetPullup) return true; + + if (mCv.wait_for(lk, timeout_ms * 1ms, [] { return gadgetPullup; })) { + ALOGI("monitorFfs signalled true"); + return true; + } else { + ALOGI("monitorFfs signalled error"); + // continue monitoring as the descriptors might be written at a later + // point. + return false; + } +} + +bool MonitorFfs::addInotifyFd(string fd) { + lock_guard lock(mLockFd); + int wfd; + + wfd = inotify_add_watch(mInotifyFd, fd.c_str(), IN_ALL_EVENTS); + if (wfd == -1) + return false; + else + mWatchFd.push_back(wfd); + + return true; +} + +void MonitorFfs::addEndPoint(string ep) { + lock_guard lock(mLockFd); + + mEndpointList.push_back(ep); +} + +void MonitorFfs::registerFunctionsAppliedCallback(void (*callback)(bool functionsApplied, + void* payload), + void* payload) { + mCallback = callback; + mPayload = payload; +} + +} // namespace gadget +} // namespace usb +} // namespace hardware +} // namespace android diff --git a/usb/gadget/1.2/default/lib/UsbGadgetUtils.cpp b/usb/gadget/1.2/default/lib/UsbGadgetUtils.cpp new file mode 100644 index 0000000000..898655651c --- /dev/null +++ b/usb/gadget/1.2/default/lib/UsbGadgetUtils.cpp @@ -0,0 +1,205 @@ +/* + * 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 "libusbconfigfs" + +#include "include/UsbGadgetCommon.h" + +namespace android { +namespace hardware { +namespace usb { +namespace gadget { + +int unlinkFunctions(const char* path) { + DIR* config = opendir(path); + struct dirent* function; + char filepath[kMaxFilePathLength]; + int ret = 0; + + if (config == NULL) return -1; + + // d_type does not seems to be supported in /config + // so filtering by name. + while (((function = readdir(config)) != NULL)) { + if ((strstr(function->d_name, FUNCTION_NAME) == NULL)) continue; + // build the path for each file in the folder. + sprintf(filepath, "%s/%s", path, function->d_name); + ret = remove(filepath); + if (ret) { + ALOGE("Unable remove file %s errno:%d", filepath, errno); + break; + } + } + + closedir(config); + return ret; +} + +int addEpollFd(const unique_fd& epfd, const unique_fd& fd) { + struct epoll_event event; + int ret; + + event.data.fd = fd; + event.events = EPOLLIN; + + ret = epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &event); + if (ret) ALOGE("epoll_ctl error %d", errno); + + return ret; +} + +int linkFunction(const char* function, int index) { + char functionPath[kMaxFilePathLength]; + char link[kMaxFilePathLength]; + + sprintf(functionPath, "%s%s", FUNCTIONS_PATH, function); + sprintf(link, "%s%d", FUNCTION_PATH, index); + if (symlink(functionPath, link)) { + ALOGE("Cannot create symlink %s -> %s errno:%d", link, functionPath, errno); + return -1; + } + return 0; +} + +Status setVidPid(const char* vid, const char* pid) { + if (!WriteStringToFile(vid, VENDOR_ID_PATH)) return Status::ERROR; + + if (!WriteStringToFile(pid, PRODUCT_ID_PATH)) return Status::ERROR; + + return Status::SUCCESS; +} + +std::string getVendorFunctions() { + if (GetProperty(kBuildType, "") == "user") return "user"; + + std::string bootMode = GetProperty(PERSISTENT_BOOT_MODE, ""); + std::string persistVendorFunctions = GetProperty(kPersistentVendorConfig, ""); + std::string vendorFunctions = GetProperty(kVendorConfig, ""); + std::string ret = ""; + + if (vendorFunctions != "") { + ret = vendorFunctions; + } else if (bootMode == "usbradio" || bootMode == "factory" || bootMode == "ffbm-00" || + bootMode == "ffbm-01") { + if (persistVendorFunctions != "") + ret = persistVendorFunctions; + else + ret = "diag"; + // vendor.usb.config will reflect the current configured functions + SetProperty(kVendorConfig, ret); + } + + return ret; +} + +Status resetGadget() { + ALOGI("setCurrentUsbFunctions None"); + + if (!WriteStringToFile("none", PULLUP_PATH)) ALOGI("Gadget cannot be pulled down"); + + if (!WriteStringToFile("0", DEVICE_CLASS_PATH)) return Status::ERROR; + + if (!WriteStringToFile("0", DEVICE_SUB_CLASS_PATH)) return Status::ERROR; + + if (!WriteStringToFile("0", DEVICE_PROTOCOL_PATH)) return Status::ERROR; + + if (!WriteStringToFile("0", DESC_USE_PATH)) return Status::ERROR; + + if (unlinkFunctions(CONFIG_PATH)) return Status::ERROR; + + return Status::SUCCESS; +} + +Status addGenericAndroidFunctions(MonitorFfs* monitorFfs, uint64_t functions, bool* ffsEnabled, + int* functionCount) { + if (((functions & GadgetFunction::MTP) != 0)) { + *ffsEnabled = true; + ALOGI("setCurrentUsbFunctions mtp"); + if (!WriteStringToFile("1", DESC_USE_PATH)) return Status::ERROR; + + if (!monitorFfs->addInotifyFd("/dev/usb-ffs/mtp/")) return Status::ERROR; + + if (linkFunction("ffs.mtp", (*functionCount)++)) return Status::ERROR; + + // Add endpoints to be monitored. + monitorFfs->addEndPoint("/dev/usb-ffs/mtp/ep1"); + monitorFfs->addEndPoint("/dev/usb-ffs/mtp/ep2"); + monitorFfs->addEndPoint("/dev/usb-ffs/mtp/ep3"); + } else if (((functions & GadgetFunction::PTP) != 0)) { + *ffsEnabled = true; + ALOGI("setCurrentUsbFunctions ptp"); + if (!WriteStringToFile("1", DESC_USE_PATH)) return Status::ERROR; + + if (!monitorFfs->addInotifyFd("/dev/usb-ffs/ptp/")) return Status::ERROR; + + if (linkFunction("ffs.ptp", (*functionCount)++)) return Status::ERROR; + + // Add endpoints to be monitored. + monitorFfs->addEndPoint("/dev/usb-ffs/ptp/ep1"); + monitorFfs->addEndPoint("/dev/usb-ffs/ptp/ep2"); + monitorFfs->addEndPoint("/dev/usb-ffs/ptp/ep3"); + } + + if ((functions & GadgetFunction::MIDI) != 0) { + ALOGI("setCurrentUsbFunctions MIDI"); + if (linkFunction("midi.gs5", (*functionCount)++)) return Status::ERROR; + } + + if ((functions & GadgetFunction::ACCESSORY) != 0) { + ALOGI("setCurrentUsbFunctions Accessory"); + if (linkFunction("accessory.gs2", (*functionCount)++)) return Status::ERROR; + } + + if ((functions & GadgetFunction::AUDIO_SOURCE) != 0) { + ALOGI("setCurrentUsbFunctions Audio Source"); + if (linkFunction("audio_source.gs3", (*functionCount)++)) return Status::ERROR; + } + + if ((functions & GadgetFunction::RNDIS) != 0) { + ALOGI("setCurrentUsbFunctions rndis"); + if (linkFunction("gsi.rndis", (*functionCount)++)) return Status::ERROR; + std::string rndisFunction = GetProperty(kVendorRndisConfig, ""); + if (rndisFunction != "") { + if (linkFunction(rndisFunction.c_str(), (*functionCount)++)) return Status::ERROR; + } else { + // link gsi.rndis for older pixel projects + if (linkFunction("gsi.rndis", (*functionCount)++)) return Status::ERROR; + } + } + + if ((functions & GadgetFunction::NCM) != 0) { + ALOGI("setCurrentUsbFunctions ncm"); + if (linkFunction("ncm.gs6", (*functionCount)++)) return Status::ERROR; + } + + return Status::SUCCESS; +} + +Status addAdb(MonitorFfs* monitorFfs, int* functionCount) { + ALOGI("setCurrentUsbFunctions Adb"); + if (!monitorFfs->addInotifyFd("/dev/usb-ffs/adb/")) return Status::ERROR; + + if (linkFunction("ffs.adb", (*functionCount)++)) return Status::ERROR; + monitorFfs->addEndPoint("/dev/usb-ffs/adb/ep1"); + monitorFfs->addEndPoint("/dev/usb-ffs/adb/ep2"); + ALOGI("Service started"); + return Status::SUCCESS; +} + +} // namespace gadget +} // namespace usb +} // namespace hardware +} // namespace android diff --git a/usb/gadget/1.2/default/lib/include/UsbGadgetCommon.h b/usb/gadget/1.2/default/lib/include/UsbGadgetCommon.h new file mode 100644 index 0000000000..18b8101ebe --- /dev/null +++ b/usb/gadget/1.2/default/lib/include/UsbGadgetCommon.h @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef HARDWARE_USB_USBGADGETCOMMON_H +#define HARDWARE_USB_USBGADGETCOMMON_H + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace android { +namespace hardware { +namespace usb { +namespace gadget { + +constexpr int kBufferSize = 512; +constexpr int kMaxFilePathLength = 256; +constexpr int kEpollEvents = 10; +constexpr bool kDebug = false; +constexpr int kDisconnectWaitUs = 100000; +constexpr int kPullUpDelay = 500000; +constexpr int kShutdownMonitor = 100; + +constexpr char kBuildType[] = "ro.build.type"; +constexpr char kPersistentVendorConfig[] = "persist.vendor.usb.usbradio.config"; +constexpr char kVendorConfig[] = "vendor.usb.config"; +constexpr char kVendorRndisConfig[] = "vendor.usb.rndis.config"; + +#define GADGET_PATH "/config/usb_gadget/g1/" +#define PULLUP_PATH GADGET_PATH "UDC" +#define PERSISTENT_BOOT_MODE "ro.bootmode" +#define VENDOR_ID_PATH GADGET_PATH "idVendor" +#define PRODUCT_ID_PATH GADGET_PATH "idProduct" +#define DEVICE_CLASS_PATH GADGET_PATH "bDeviceClass" +#define DEVICE_SUB_CLASS_PATH GADGET_PATH "bDeviceSubClass" +#define DEVICE_PROTOCOL_PATH GADGET_PATH "bDeviceProtocol" +#define DESC_USE_PATH GADGET_PATH "os_desc/use" +#define OS_DESC_PATH GADGET_PATH "os_desc/b.1" +#define CONFIG_PATH GADGET_PATH "configs/b.1/" +#define FUNCTIONS_PATH GADGET_PATH "functions/" +#define FUNCTION_NAME "function" +#define FUNCTION_PATH CONFIG_PATH FUNCTION_NAME +#define RNDIS_PATH FUNCTIONS_PATH "gsi.rndis" + +using ::android::base::GetProperty; +using ::android::base::SetProperty; +using ::android::base::unique_fd; +using ::android::base::WriteStringToFile; +using ::android::hardware::usb::gadget::V1_0::Status; +using ::android::hardware::usb::gadget::V1_2::GadgetFunction; + +using ::std::lock_guard; +using ::std::move; +using ::std::mutex; +using ::std::string; +using ::std::thread; +using ::std::unique_ptr; +using ::std::vector; +using ::std::chrono::microseconds; +using ::std::chrono::steady_clock; +using ::std::literals::chrono_literals::operator""ms; + +// MonitorFfs automously manages gadget pullup by monitoring +// the ep file status. Restarts the usb gadget when the ep +// owner restarts. +class MonitorFfs { + private: + // Monitors the endpoints Inotify events. + unique_fd mInotifyFd; + // Control pipe for shutting down the mMonitor thread. + // mMonitor exits when SHUTDOWN_MONITOR is written into + // mEventFd/ + unique_fd mEventFd; + // Pools on mInotifyFd and mEventFd. + unique_fd mEpollFd; + vector mWatchFd; + + // Maintains the list of Endpoints. + vector mEndpointList; + // protects the CV. + std::mutex mLock; + std::condition_variable mCv; + // protects mInotifyFd, mEpollFd. + std::mutex mLockFd; + + // Flag to maintain the current status of gadget pullup. + bool mCurrentUsbFunctionsApplied; + + // Thread object that executes the ep monitoring logic. + unique_ptr mMonitor; + // Callback to be invoked when gadget is pulled up. + void (*mCallback)(bool functionsApplied, void* payload); + void* mPayload; + // Name of the USB gadget. Used for pullup. + const char* const mGadgetName; + // Monitor State + bool mMonitorRunning; + + public: + MonitorFfs(const char* const gadget); + // Inits all the UniqueFds. + void reset(); + // Starts monitoring endpoints and pullup the gadget when + // the descriptors are written. + bool startMonitor(); + // Waits for timeout_ms for gadget pull up to happen. + // Returns immediately if the gadget is already pulled up. + bool waitForPullUp(int timeout_ms); + // Adds the given fd to the watch list. + bool addInotifyFd(string fd); + // Adds the given endpoint to the watch list. + void addEndPoint(string ep); + // Registers the async callback from the caller to notify the caller + // when the gadget pull up happens. + void registerFunctionsAppliedCallback(void (*callback)(bool functionsApplied, void*(payload)), + void* payload); + bool isMonitorRunning(); + // Ep monitoring and the gadget pull up logic. + static void* startMonitorFd(void* param); +}; + +//**************** Helper functions ************************// + +// Adds the given fd to the epollfd(epfd). +int addEpollFd(const unique_fd& epfd, const unique_fd& fd); +// Removes all the usb functions link in the specified path. +int unlinkFunctions(const char* path); +// Craetes a configfs link for the function. +int linkFunction(const char* function, int index); +// Sets the USB VID and PID. +Status setVidPid(const char* vid, const char* pid); +// Extracts vendor functions from the vendor init properties. +std::string getVendorFunctions(); +// Adds Adb to the usb configuration. +Status addAdb(MonitorFfs* monitorFfs, int* functionCount); +// Adds all applicable generic android usb functions other than ADB. +Status addGenericAndroidFunctions(MonitorFfs* monitorFfs, uint64_t functions, bool* ffsEnabled, + int* functionCount); +// Pulls down USB gadget. +Status resetGadget(); + +} // namespace gadget +} // namespace usb +} // namespace hardware +} // namespace android +#endif diff --git a/usb/gadget/1.2/default/service.cpp b/usb/gadget/1.2/default/service.cpp new file mode 100644 index 0000000000..80c56a653f --- /dev/null +++ b/usb/gadget/1.2/default/service.cpp @@ -0,0 +1,52 @@ +/* + * 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 "android.hardware.usb.gadget@1.2-service" + +#include +#include "UsbGadget.h" + +using android::sp; + +// libhwbinder: +using android::hardware::configureRpcThreadpool; +using android::hardware::joinRpcThreadpool; + +// Generated HIDL files +using android::hardware::usb::gadget::V1_2::IUsbGadget; +using android::hardware::usb::gadget::V1_2::implementation::UsbGadget; + +using android::OK; +using android::status_t; + +int main() { + configureRpcThreadpool(1, true /*callerWillJoin*/); + + android::sp service = new UsbGadget(); + + status_t status = service->registerAsService(); + + if (status != OK) { + ALOGE("Cannot register USB Gadget HAL service"); + return 1; + } + + ALOGI("USB Gadget HAL Ready."); + joinRpcThreadpool(); + // Under noraml cases, execution will not reach this line. + ALOGI("USB Gadget HAL failed to join thread pool."); + return 1; +} -- GitLab From a6c5b8c5734e3251669fca6c2bd3c3e1c447eab9 Mon Sep 17 00:00:00 2001 From: lesl Date: Tue, 10 Nov 2020 01:26:34 +0800 Subject: [PATCH 265/790] wifi: Fix incorrect instance version The vts use getAidlInstances to check current HIDL version whether or not exist in the device manifests. When there are no instances installed, the suite won't be instantiated Test: atest -c VtsHalWifiHostapdV1_3TargetTest in S GSI + R build Bug: 172539662 Change-Id: Ia268282eeeb53a092bb5f36ef0426ac213b45a9f --- wifi/hostapd/1.3/vts/functional/hostapd_hidl_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wifi/hostapd/1.3/vts/functional/hostapd_hidl_test.cpp b/wifi/hostapd/1.3/vts/functional/hostapd_hidl_test.cpp index 9234a5bf92..bdbe65128c 100644 --- a/wifi/hostapd/1.3/vts/functional/hostapd_hidl_test.cpp +++ b/wifi/hostapd/1.3/vts/functional/hostapd_hidl_test.cpp @@ -468,5 +468,5 @@ INSTANTIATE_TEST_CASE_P( testing::ValuesIn( android::hardware::getAllHalInstanceNames(IWifi::descriptor)), testing::ValuesIn(android::hardware::getAllHalInstanceNames( - android::hardware::wifi::hostapd::V1_2::IHostapd::descriptor))), + android::hardware::wifi::hostapd::V1_3::IHostapd::descriptor))), android::hardware::PrintInstanceTupleNameToString<>); -- GitLab From a45dd5802ae1dc06eabaa1d7de109a79ebcf7f33 Mon Sep 17 00:00:00 2001 From: xshu Date: Mon, 9 Nov 2020 18:14:28 -0800 Subject: [PATCH 266/790] VTS - avoid same MAC for AP and STA Having the AP and STA set the same MAC address in tests could cause unintended failures when WifiApIfaceHidlTest and WifiStaIfaceHidlTest are executed back to back. Bug: 172528120 Test: atest VtsHalWifiApV1_4TargetTest VtsHalWifiV1_2TargetTest Change-Id: I336d21cd896c46b064f16ecfa184a26dab67deaa --- wifi/1.4/vts/functional/wifi_ap_iface_hidl_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wifi/1.4/vts/functional/wifi_ap_iface_hidl_test.cpp b/wifi/1.4/vts/functional/wifi_ap_iface_hidl_test.cpp index fc7dcd641c..5b0f1736ea 100644 --- a/wifi/1.4/vts/functional/wifi_ap_iface_hidl_test.cpp +++ b/wifi/1.4/vts/functional/wifi_ap_iface_hidl_test.cpp @@ -59,7 +59,7 @@ class WifiApIfaceHidlTest : public ::testing::TestWithParam { * code. */ TEST_P(WifiApIfaceHidlTest, SetMacAddress) { - const hidl_array kMac{{0x12, 0x22, 0x33, 0x52, 0x10, 0x41}}; + const hidl_array kMac{{0x12, 0x22, 0x33, 0x52, 0x10, 0x44}}; EXPECT_EQ(WifiStatusCode::SUCCESS, HIDL_INVOKE(wifi_ap_iface_, setMacAddress, kMac).code); } -- GitLab From 06c9863d8017bbaa855d2497be7929d62cb5d69f Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Wed, 11 Nov 2020 11:01:39 +0800 Subject: [PATCH 267/790] wifi: fix old vts tests for deprecated APIs Bug: 172865706 Test: atest VtsHalWifiSupplicantV1_0TargetTest \ VtsHalWifiSupplicantP2pV1_0TargetTest \ VtsHalWifiSupplicantV1_1TargetTest \ VtsHalWifiSupplicantV1_2TargetTest \ VtsHalWifiSupplicantP2pV1_2TargetTest \ VtsHalWifiSupplicantV1_3TargetTest \ VtsHalWifiSupplicantV1_4TargetTest \ VtsHalWifiSupplicantP2pV1_4TargetTest Change-Id: Icc502cae18338606a98ada312e9a66a5b11f51db --- .../supplicant_sta_iface_hidl_test.cpp | 17 ++++++++++---- wifi/supplicant/1.1/vts/functional/Android.bp | 1 + .../supplicant_sta_iface_hidl_test.cpp | 17 ++++++++++---- .../supplicant_sta_iface_hidl_test.cpp | 22 +++++++++---------- .../supplicant_sta_iface_hidl_test.cpp | 21 ++++++++++++++---- 5 files changed, 55 insertions(+), 23 deletions(-) diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp index 6b85e001dd..1c3141e326 100644 --- a/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp +++ b/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include "supplicant_hidl_call_util.h" #include "supplicant_hidl_test_utils.h" @@ -73,11 +74,16 @@ class SupplicantStaIfaceHidlTest : public SupplicantHidlTestBaseV1_0 { sta_iface_ = getSupplicantStaIface(supplicant_); ASSERT_NE(sta_iface_.get(), nullptr); + v1_1 = ::android::hardware::wifi::supplicant::V1_1:: + ISupplicantStaIface::castFrom(sta_iface_); + memcpy(mac_addr_.data(), kTestMacAddr, mac_addr_.size()); } protected: bool isP2pOn_ = false; + sp<::android::hardware::wifi::supplicant::V1_1::ISupplicantStaIface> v1_1 = + nullptr; // ISupplicantStaIface object used for all tests in this fixture. sp sta_iface_; // MAC address to use for various tests. @@ -175,10 +181,13 @@ TEST_P(SupplicantStaIfaceHidlTest, Create) { * RegisterCallback */ TEST_P(SupplicantStaIfaceHidlTest, RegisterCallback) { - sta_iface_->registerCallback( - new IfaceCallback(), [](const SupplicantStatus& status) { - EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); - }); + SupplicantStatusCode expectedCode = + (nullptr != v1_1) ? SupplicantStatusCode::FAILURE_UNKNOWN + : SupplicantStatusCode::SUCCESS; + sta_iface_->registerCallback(new IfaceCallback(), + [&](const SupplicantStatus& status) { + EXPECT_EQ(expectedCode, status.code); + }); } /* diff --git a/wifi/supplicant/1.1/vts/functional/Android.bp b/wifi/supplicant/1.1/vts/functional/Android.bp index 44b020e021..ee806289ee 100644 --- a/wifi/supplicant/1.1/vts/functional/Android.bp +++ b/wifi/supplicant/1.1/vts/functional/Android.bp @@ -47,6 +47,7 @@ cc_test { "VtsHalWifiSupplicantV1_1TargetTestUtil", "android.hardware.wifi.supplicant@1.0", "android.hardware.wifi.supplicant@1.1", + "android.hardware.wifi.supplicant@1.2", "android.hardware.wifi@1.0", "android.hardware.wifi@1.1", "libgmock", diff --git a/wifi/supplicant/1.1/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.1/vts/functional/supplicant_sta_iface_hidl_test.cpp index db6323c191..418def2f28 100644 --- a/wifi/supplicant/1.1/vts/functional/supplicant_sta_iface_hidl_test.cpp +++ b/wifi/supplicant/1.1/vts/functional/supplicant_sta_iface_hidl_test.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -45,11 +46,16 @@ class SupplicantStaIfaceHidlTest : public SupplicantHidlTestBaseV1_1 { SupplicantHidlTestBaseV1_1::SetUp(); sta_iface_ = getSupplicantStaIface_1_1(supplicant_); ASSERT_NE(sta_iface_.get(), nullptr); + + v1_2 = ::android::hardware::wifi::supplicant::V1_2:: + ISupplicantStaIface::castFrom(sta_iface_); } protected: // ISupplicantStaIface object used for all tests in this fixture. sp sta_iface_; + sp<::android::hardware::wifi::supplicant::V1_2::ISupplicantStaIface> v1_2 = + nullptr; }; class IfaceCallback : public ISupplicantStaIfaceCallback { @@ -133,10 +139,13 @@ class IfaceCallback : public ISupplicantStaIfaceCallback { * RegisterCallback_1_1 */ TEST_P(SupplicantStaIfaceHidlTest, RegisterCallback_1_1) { - sta_iface_->registerCallback_1_1( - new IfaceCallback(), [](const SupplicantStatus& status) { - EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); - }); + SupplicantStatusCode expectedCode = + (nullptr != v1_2) ? SupplicantStatusCode::FAILURE_UNKNOWN + : SupplicantStatusCode::SUCCESS; + sta_iface_->registerCallback_1_1(new IfaceCallback(), + [&](const SupplicantStatus& status) { + EXPECT_EQ(expectedCode, status.code); + }); } GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantStaIfaceHidlTest); diff --git a/wifi/supplicant/1.2/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.2/vts/functional/supplicant_sta_iface_hidl_test.cpp index cd08468938..7799390a2c 100644 --- a/wifi/supplicant/1.2/vts/functional/supplicant_sta_iface_hidl_test.cpp +++ b/wifi/supplicant/1.2/vts/functional/supplicant_sta_iface_hidl_test.cpp @@ -60,6 +60,9 @@ class SupplicantStaIfaceHidlTest : public SupplicantHidlTestBaseV1_2 { sta_iface_ = getSupplicantStaIface_1_2(supplicant_); ASSERT_NE(sta_iface_.get(), nullptr); count_ = 0; + + v1_3 = ::android::hardware::wifi::supplicant::V1_3:: + ISupplicantStaIface::castFrom(sta_iface_); } enum DppCallbackType { @@ -102,6 +105,7 @@ class SupplicantStaIfaceHidlTest : public SupplicantHidlTestBaseV1_2 { protected: // ISupplicantStaIface object used for all tests in this fixture. sp sta_iface_; + sp<::android::hardware::wifi::supplicant::V1_3::ISupplicantStaIface> v1_3; bool isDppSupported() { uint32_t keyMgmtMask = 0; @@ -262,10 +266,13 @@ class IfaceDppCallback : public IfaceCallback { * RegisterCallback_1_2 */ TEST_P(SupplicantStaIfaceHidlTest, RegisterCallback_1_2) { - sta_iface_->registerCallback_1_2( - new IfaceCallback(), [](const SupplicantStatus& status) { - EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); - }); + SupplicantStatusCode expectedCode = + (nullptr != v1_3) ? SupplicantStatusCode::FAILURE_UNKNOWN + : SupplicantStatusCode::SUCCESS; + sta_iface_->registerCallback_1_2(new IfaceCallback(), + [&](const SupplicantStatus& status) { + EXPECT_EQ(expectedCode, status.code); + }); } /* @@ -339,9 +346,6 @@ TEST_P(SupplicantStaIfaceHidlTest, StartDppEnrolleeInitiator) { * it is waiting for will never be called. Note that this test is also * implemented in the 1.3 VTS test. */ - sp<::android::hardware::wifi::supplicant::V1_3::ISupplicantStaIface> v1_3 = - ::android::hardware::wifi::supplicant::V1_3::ISupplicantStaIface:: - castFrom(sta_iface_); if (v1_3 != nullptr) { GTEST_SKIP() << "Test not supported with this HAL version"; } @@ -404,10 +408,6 @@ TEST_P(SupplicantStaIfaceHidlTest, StartDppConfiguratorInitiator) { * it is waiting for will never be called. Note that this test is also * implemented in the 1.3 VTS test. */ - sp<::android::hardware::wifi::supplicant::V1_3::ISupplicantStaIface> v1_3 = - ::android::hardware::wifi::supplicant::V1_3::ISupplicantStaIface:: - castFrom(sta_iface_); - if (v1_3 != nullptr) { GTEST_SKIP() << "Test not supported with this HAL version"; return; diff --git a/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp index 189e2b9717..9ffe0ece09 100644 --- a/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp +++ b/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp @@ -325,10 +325,13 @@ class IfaceBssTmHandlingDoneCallback : public IfaceCallback { * RegisterCallback_1_3 */ TEST_P(SupplicantStaIfaceHidlTest, RegisterCallback_1_3) { - sta_iface_->registerCallback_1_3( - new IfaceCallback(), [](const SupplicantStatus& status) { - EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); - }); + SupplicantStatusCode expectedCode = + (nullptr != sta_iface_v1_4_) ? SupplicantStatusCode::FAILURE_UNKNOWN + : SupplicantStatusCode::SUCCESS; + sta_iface_->registerCallback_1_3(new IfaceCallback(), + [&](const SupplicantStatus& status) { + EXPECT_EQ(expectedCode, status.code); + }); } /* @@ -428,6 +431,11 @@ TEST_P(SupplicantStaIfaceHidlTest, StartDppEnrolleeInitiator) { return; } + if (sta_iface_v1_4_ != nullptr) { + GTEST_SKIP() << "Test not supported with this HAL version"; + return; + } + hidl_string uri = "DPP:C:81/1,117/" "40;M:48d6d5bd1de1;I:G1197843;K:MDkwEwYHKoZIzj0CAQYIKoZIzj" @@ -480,6 +488,11 @@ TEST_P(SupplicantStaIfaceHidlTest, StartDppConfiguratorInitiator) { return; } + if (sta_iface_v1_4_ != nullptr) { + GTEST_SKIP() << "Test not supported with this HAL version"; + return; + } + hidl_string uri = "DPP:C:81/1,117/" "40;M:48d6d5bd1de1;I:G1197843;K:MDkwEwYHKoZIzj0CAQYIKoZIzj" -- GitLab From cd9f4c477229f3397f6058bf7563a130ccfda0d5 Mon Sep 17 00:00:00 2001 From: Yu-Han Yang Date: Wed, 11 Nov 2020 11:53:40 -0800 Subject: [PATCH 268/790] Skip GnssConfiguration v2.1 tests for AIDL HAL - the same tests for AIDL HAL have been added in aidl/vts. Bug: 172989709 Test: atest VtsHalGnssV2_1TargetTest Change-Id: Ib1ace156d9b012a1b751a1f2f31a8b1765f964a4 --- gnss/2.1/vts/functional/Android.bp | 4 ++ gnss/2.1/vts/functional/gnss_hal_test.cpp | 43 +++++++++++++++++++ gnss/2.1/vts/functional/gnss_hal_test.h | 9 +++- .../vts/functional/gnss_hal_test_cases.cpp | 42 ++++++++++++------ 4 files changed, 85 insertions(+), 13 deletions(-) create mode 100644 gnss/2.1/vts/functional/gnss_hal_test.cpp diff --git a/gnss/2.1/vts/functional/Android.bp b/gnss/2.1/vts/functional/Android.bp index 175bc75481..aae35710cd 100644 --- a/gnss/2.1/vts/functional/Android.bp +++ b/gnss/2.1/vts/functional/Android.bp @@ -18,6 +18,7 @@ cc_test { name: "VtsHalGnssV2_1TargetTest", defaults: ["VtsHalTargetTestDefaults"], srcs: [ + "gnss_hal_test.cpp", "gnss_hal_test_cases.cpp", "VtsHalGnssV2_1TargetTest.cpp", ], @@ -31,6 +32,9 @@ cc_test { "android.hardware.gnss@2.1", "android.hardware.gnss@common-vts-lib", ], + shared_libs: [ + "libvintf", + ], test_suites: [ "general-tests", "vts", diff --git a/gnss/2.1/vts/functional/gnss_hal_test.cpp b/gnss/2.1/vts/functional/gnss_hal_test.cpp new file mode 100644 index 0000000000..1154260bc0 --- /dev/null +++ b/gnss/2.1/vts/functional/gnss_hal_test.cpp @@ -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. + */ + +#define LOG_TAG "GnssHalTest" + +#include +#include +#include +#include + +#include "gnss_hal_test.h" + +using ::android::hardware::hidl_string; +using ::android::hidl::manager::V1_2::IServiceManager; + +bool GnssHalTest::IsGnssHalVersion_2_1() const { + sp manager = ::android::hardware::defaultServiceManager1_2(); + bool hasGnssHalVersion_2_1 = false; + manager->listManifestByInterface( + "android.hardware.gnss@2.1::IGnss", + [&hasGnssHalVersion_2_1](const hidl_vec& registered) { + hasGnssHalVersion_2_1 = registered.size() > 0; + }); + + auto deviceManifest = ::android::vintf::VintfObject::GetDeviceHalManifest(); + bool hasGnssAidl = + deviceManifest->getAidlInstances("android.hardware.gnss", "IGnss").size() > 0; + + return hasGnssHalVersion_2_1 && !hasGnssAidl; +} \ No newline at end of file diff --git a/gnss/2.1/vts/functional/gnss_hal_test.h b/gnss/2.1/vts/functional/gnss_hal_test.h index c28e2480f7..7950670983 100644 --- a/gnss/2.1/vts/functional/gnss_hal_test.h +++ b/gnss/2.1/vts/functional/gnss_hal_test.h @@ -22,4 +22,11 @@ using android::hardware::gnss::V2_1::IGnss; // The main test class for GNSS HAL. -class GnssHalTest : public GnssHalTestTemplate {}; +class GnssHalTest : public GnssHalTestTemplate { + public: + /** + * IsGnssHalVersion_2_1: + * returns true if the GNSS HAL version is exactly 2.1. + */ + bool IsGnssHalVersion_2_1() const; +}; diff --git a/gnss/2.1/vts/functional/gnss_hal_test_cases.cpp b/gnss/2.1/vts/functional/gnss_hal_test_cases.cpp index 290280922c..7afd49cb86 100644 --- a/gnss/2.1/vts/functional/gnss_hal_test_cases.cpp +++ b/gnss/2.1/vts/functional/gnss_hal_test_cases.cpp @@ -87,6 +87,10 @@ TEST_P(GnssHalTest, TestGnssMeasurementExtension) { * Gets the GnssConfigurationExtension and verifies that it returns an actual extension. */ TEST_P(GnssHalTest, TestGnssConfigurationExtension) { + if (!IsGnssHalVersion_2_1()) { + ALOGI("Test TestGnssConfigurationExtension skipped. GNSS HAL version is greater than 2.1."); + return; + } auto gnssConfiguration_2_1 = gnss_hal_->getExtensionGnssConfiguration_2_1(); auto gnssConfiguration_2_0 = gnss_hal_->getExtensionGnssConfiguration_2_0(); auto gnssConfiguration_1_1 = gnss_hal_->getExtensionGnssConfiguration_1_1(); @@ -358,20 +362,24 @@ IGnssConfiguration::BlacklistedSource FindStrongFrequentNonGpsSource( } /* - * BlacklistIndividualSatellites: + * BlocklistIndividualSatellites: * * 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding * GnssStatus for common satellites (strongest and one other.) - * 2a & b) Turns off location, and blacklists common satellites. + * 2a & b) Turns off location, and blocklists common satellites. * 3) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding * GnssStatus does not use those satellites. - * 4a & b) Turns off location, and send in empty blacklist. + * 4a & b) Turns off location, and send in empty blocklist. * 5a) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding * GnssStatus does re-use at least the previously strongest satellite * 5b) Retry a few times, in case GNSS search strategy takes a while to reacquire even the * formerly strongest satellite */ -TEST_P(GnssHalTest, BlacklistIndividualSatellites) { +TEST_P(GnssHalTest, BlocklistIndividualSatellites) { + if (!IsGnssHalVersion_2_1()) { + ALOGI("Test BlocklistIndividualSatellites skipped. GNSS HAL version is greater than 2.1."); + return; + } if (!(gnss_cb_->last_capabilities_ & IGnssCallback_2_1::Capabilities::SATELLITE_BLACKLIST)) { ALOGI("Test BlacklistIndividualSatellites skipped. SATELLITE_BLACKLIST capability not " "supported."); @@ -509,16 +517,21 @@ TEST_P(GnssHalTest, BlacklistIndividualSatellites) { } /* - * BlacklistConstellationLocationOff: + * BlocklistConstellationLocationOff: * * 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding * GnssStatus for any non-GPS constellations. - * 2a & b) Turns off location, and blacklist first non-GPS constellations. + * 2a & b) Turns off location, and blocklist first non-GPS constellations. * 3) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding * GnssStatus does not use any constellation but GPS. - * 4a & b) Clean up by turning off location, and send in empty blacklist. + * 4a & b) Clean up by turning off location, and send in empty blocklist. */ -TEST_P(GnssHalTest, BlacklistConstellationLocationOff) { +TEST_P(GnssHalTest, BlocklistConstellationLocationOff) { + if (!IsGnssHalVersion_2_1()) { + ALOGI("Test BlocklistConstellationLocationOff skipped. GNSS HAL version is greater than " + "2.1."); + return; + } if (!(gnss_cb_->last_capabilities_ & IGnssCallback_2_1::Capabilities::SATELLITE_BLACKLIST)) { ALOGI("Test BlacklistConstellationLocationOff skipped. SATELLITE_BLACKLIST capability not " "supported."); @@ -591,16 +604,21 @@ TEST_P(GnssHalTest, BlacklistConstellationLocationOff) { } /* - * BlacklistConstellationLocationOn: + * BlocklistConstellationLocationOn: * * 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding * GnssStatus for any non-GPS constellations. - * 2a & b) Blacklist first non-GPS constellation, and turn off location. + * 2a & b) Blocklist first non-GPS constellation, and turn off location. * 3) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding * GnssStatus does not use any constellation but GPS. - * 4a & b) Clean up by turning off location, and send in empty blacklist. + * 4a & b) Clean up by turning off location, and send in empty blocklist. */ -TEST_P(GnssHalTest, BlacklistConstellationLocationOn) { +TEST_P(GnssHalTest, BlocklistConstellationLocationOn) { + if (!IsGnssHalVersion_2_1()) { + ALOGI("Test BlocklistConstellationLocationOn skipped. GNSS HAL version is greater than " + "2.1."); + return; + } if (!(gnss_cb_->last_capabilities_ & IGnssCallback_2_1::Capabilities::SATELLITE_BLACKLIST)) { ALOGI("Test BlacklistConstellationLocationOn skipped. SATELLITE_BLACKLIST capability not " "supported."); -- GitLab From bad76851cfda2f19e38b758aa95d6e73ddd47c86 Mon Sep 17 00:00:00 2001 From: Kevin Chyn Date: Wed, 11 Nov 2020 13:23:35 -0800 Subject: [PATCH 269/790] Add additional face SensorProps Fixes: 168541000 Test: m android.hardware.biometrics.face-update-api Test: m android.hardware.biometrics.face-service.example Change-Id: I664fe1f641e09217b27aef232e39ba7d6fa1e171 --- .../hardware/biometrics/face/SensorProps.aidl | 5 +++ .../hardware/biometrics/face/SensorProps.aidl | 31 +++++++++++++++++++ biometrics/face/aidl/default/Face.cpp | 5 +++ 3 files changed, 41 insertions(+) diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl index 9f977f54af..365ae58a46 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl @@ -21,4 +21,9 @@ parcelable SensorProps { android.hardware.biometrics.common.CommonProps commonProps; android.hardware.biometrics.face.FaceSensorType sensorType; boolean halControlsPreview; + int enrollPreviewWidth; + int enrollPreviewHeight; + float enrollTranslationX; + float enrollTranslationY; + float enrollPreviewScale; } diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl index 53cc44e7ec..9c2f9a1734 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl @@ -39,5 +39,36 @@ parcelable SensorProps { * the framework. */ boolean halControlsPreview; + + /** + * For implementations where the HAL manages the preview, this is the width, in pixels, of each + * frame that the camera is set up to output. + */ + int enrollPreviewWidth; + + /** + * For implementations where the HAL manages the preview, this is the height, in pixels, of + * each frame that the camera is set up to output. + */ + int enrollPreviewHeight; + + /** + * For implementations where the HAL manages the preview, this is the distance in pixels that + * the enrollment preview should be translated. This is typically used by devices where the + * camera used for enrollment preview is not centered. + */ + float enrollTranslationX; + + /** + * For implementations where the HAL manages the preview, this is the distance in pixels that + * the enrollment preview should be translated. + */ + float enrollTranslationY; + + /** + * For implementations where the HAL manages the preview, this is the scale factor that should + * be applied when configuring the preview texture. + */ + float enrollPreviewScale; } diff --git a/biometrics/face/aidl/default/Face.cpp b/biometrics/face/aidl/default/Face.cpp index 1526245c70..929c7e7703 100644 --- a/biometrics/face/aidl/default/Face.cpp +++ b/biometrics/face/aidl/default/Face.cpp @@ -46,6 +46,11 @@ ndk::ScopedAStatus Face::getSensorProps(std::vector* return_val) { props.commonProps = std::move(commonProps); props.sensorType = kSensorType; props.halControlsPreview = kHalControlsPreview; + props.enrollPreviewWidth = 1080; + props.enrollPreviewHeight = 1920; + props.enrollTranslationX = 100.f; + props.enrollTranslationY = 50.f; + props.enrollPreviewScale = 1.f; *return_val = {std::move(props)}; return ndk::ScopedAStatus::ok(); -- GitLab From 62fd3447114d013082bae1bfaf7dd99a0d080ecf Mon Sep 17 00:00:00 2001 From: Jack Nudelman Date: Thu, 24 Sep 2020 14:23:35 -0700 Subject: [PATCH 270/790] HAL changes for ThermalMitigation API. go/telephony-thermal-mitigation Bug: 158872959 Test: make, vts Change-Id: I914993a6e80305732564e0507ca6a74b1c296439 --- radio/1.6/IRadio.hal | 25 +++++++ radio/1.6/IRadioResponse.hal | 11 ++++ radio/1.6/types.hal | 22 +++++++ .../1.6/vts/functional/radio_hidl_hal_api.cpp | 66 +++++++++++++++++++ .../functional/radio_hidl_hal_utils_v1_6.h | 3 + radio/1.6/vts/functional/radio_response.cpp | 7 ++ 6 files changed, 134 insertions(+) diff --git a/radio/1.6/IRadio.hal b/radio/1.6/IRadio.hal index a093dee18a..91709fabe7 100644 --- a/radio/1.6/IRadio.hal +++ b/radio/1.6/IRadio.hal @@ -320,4 +320,29 @@ interface IRadio extends @1.5::IRadio { */ oneway setAllowedNetworkTypeBitmap( uint32_t serial, bitfield networkTypeBitmap); + + /** + * Control data throttling at modem. + * - DataThrottlingAction:NO_DATA_THROTTLING should clear any existing + * data throttling within the requested completion window. + * - DataThrottlingAction:THROTTLE_SECONDARY_CARRIER: Remove any existing + * throttling on anchor carrier and achieve maximum data throttling on + * secondary carrier within the requested completion window. + * - DataThrottlingAction:THROTTLE_ANCHOR_CARRIER: disable secondary + * carrier and achieve maximum data throttling on anchor carrier by + * requested completion window. + * - DataThrottlingAction:HOLD: Immediately hold on to current level of + * throttling. + * + * @param serial Serial number of request. + * @param dataThrottlingAction DataThrottlingAction as defined in types.hal + * @param completionWindowSecs window, in seconds, in which the requested + * throttling action has to be achieved. This must be 0 when + * dataThrottlingAction is DataThrottlingAction:HOLD. + * + * Response function is IRadioResponse.setDataThrottlingResponse() + */ + oneway setDataThrottling(int32_t serial, + DataThrottlingAction dataThrottlingAction, + int32_t completionWindowSecs); }; diff --git a/radio/1.6/IRadioResponse.hal b/radio/1.6/IRadioResponse.hal index 0379e00329..acae5c7e22 100644 --- a/radio/1.6/IRadioResponse.hal +++ b/radio/1.6/IRadioResponse.hal @@ -306,4 +306,15 @@ interface IRadioResponse extends @1.5::IRadioResponse { * RadioError:NO_RESOURCES */ oneway setAllowedNetworkTypeBitmapResponse(RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:MODEM_ERR + * RadioError:INVALID_ARGUMENTS + */ + oneway setDataThrottlingResponse(RadioResponseInfo info); }; diff --git a/radio/1.6/types.hal b/radio/1.6/types.hal index 4f32b3c66f..2cba9157f2 100644 --- a/radio/1.6/types.hal +++ b/radio/1.6/types.hal @@ -394,3 +394,25 @@ struct LinkCapacityEstimate { */ uint32_t secondaryUplinkCapacityKbps; }; + +enum DataThrottlingAction : int32_t { + /* Clear all existing data throttling. */ + NO_DATA_THROTTLING = 0, + + /** + * Enact secondary carrier data throttling and remove any existing data + * throttling on anchor carrier. + */ + THROTTLE_SECONDARY_CARRIER = 1, + + /** + * Enact anchor carrier data throttling and disable data on secondary + * carrier if currently enabled. + */ + THROTTLE_ANCHOR_CARRIER = 2, + + /** + * Immediately hold on to current level of throttling. + */ + HOLD = 3 +}; diff --git a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp index 6547611b50..ac84417ff8 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp +++ b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp @@ -295,3 +295,69 @@ TEST_P(RadioHidlTest_v1_6, isNrDualConnectivityEnabled) { ::android::hardware::radio::V1_6::RadioError::INTERNAL_ERR, ::android::hardware::radio::V1_6::RadioError::NONE})); } + +/* + * Test IRadio.setDataThrottling() for the response returned. + */ +TEST_P(RadioHidlTest_v1_6, setDataThrottling) { + serial = GetRandomSerialNumber(); + + Return res = radio_v1_6->setDataThrottling( + serial, DataThrottlingAction::THROTTLE_SECONDARY_CARRIER, 60); + ASSERT_OK(res); + + EXPECT_EQ(std::cv_status::no_timeout, wait()); + EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type); + EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial); + ASSERT_TRUE( + CheckAnyOfErrors(radioRsp_v1_6->rspInfo.error, + {::android::hardware::radio::V1_6::RadioError::RADIO_NOT_AVAILABLE, + ::android::hardware::radio::V1_6::RadioError::MODEM_ERR, + ::android::hardware::radio::V1_6::RadioError::NONE, + ::android::hardware::radio::V1_6::RadioError::INVALID_ARGUMENTS})); + + serial = GetRandomSerialNumber(); + + res = radio_v1_6->setDataThrottling(serial, DataThrottlingAction::THROTTLE_ANCHOR_CARRIER, 60); + ASSERT_OK(res); + + EXPECT_EQ(std::cv_status::no_timeout, wait()); + EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type); + EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial); + ASSERT_TRUE( + CheckAnyOfErrors(radioRsp_v1_6->rspInfo.error, + {::android::hardware::radio::V1_6::RadioError::RADIO_NOT_AVAILABLE, + ::android::hardware::radio::V1_6::RadioError::MODEM_ERR, + ::android::hardware::radio::V1_6::RadioError::NONE, + ::android::hardware::radio::V1_6::RadioError::INVALID_ARGUMENTS})); + + serial = GetRandomSerialNumber(); + + res = radio_v1_6->setDataThrottling(serial, DataThrottlingAction::HOLD, 60); + ASSERT_OK(res); + + EXPECT_EQ(std::cv_status::no_timeout, wait()); + EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type); + EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial); + ASSERT_TRUE( + CheckAnyOfErrors(radioRsp_v1_6->rspInfo.error, + {::android::hardware::radio::V1_6::RadioError::RADIO_NOT_AVAILABLE, + ::android::hardware::radio::V1_6::RadioError::MODEM_ERR, + ::android::hardware::radio::V1_6::RadioError::NONE, + ::android::hardware::radio::V1_6::RadioError::INVALID_ARGUMENTS})); + + serial = GetRandomSerialNumber(); + + res = radio_v1_6->setDataThrottling(serial, DataThrottlingAction::NO_DATA_THROTTLING, 60); + ASSERT_OK(res); + + EXPECT_EQ(std::cv_status::no_timeout, wait()); + EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type); + EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial); + ASSERT_TRUE( + CheckAnyOfErrors(radioRsp_v1_6->rspInfo.error, + {::android::hardware::radio::V1_6::RadioError::RADIO_NOT_AVAILABLE, + ::android::hardware::radio::V1_6::RadioError::MODEM_ERR, + ::android::hardware::radio::V1_6::RadioError::NONE, + ::android::hardware::radio::V1_6::RadioError::INVALID_ARGUMENTS})); +} \ No newline at end of file diff --git a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h index 6189be6add..31bb1d7114 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h +++ b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h @@ -792,6 +792,9 @@ class RadioResponse_v1_6 : public ::android::hardware::radio::V1_6::IRadioRespon Return setAllowedNetworkTypeBitmapResponse( const ::android::hardware::radio::V1_6::RadioResponseInfo& info); + + Return setDataThrottlingResponse( + const ::android::hardware::radio::V1_6::RadioResponseInfo& info); }; /* Callback class for radio indication */ diff --git a/radio/1.6/vts/functional/radio_response.cpp b/radio/1.6/vts/functional/radio_response.cpp index 18cda6aae4..09a2baced4 100644 --- a/radio/1.6/vts/functional/radio_response.cpp +++ b/radio/1.6/vts/functional/radio_response.cpp @@ -1156,3 +1156,10 @@ Return RadioResponse_v1_6::setAllowedNetworkTypeBitmapResponse( parent_v1_6.notify(info.serial); return Void(); } + +Return RadioResponse_v1_6::setDataThrottlingResponse( + const ::android::hardware::radio::V1_6::RadioResponseInfo& info) { + rspInfo = info; + parent_v1_6.notify(info.serial); + return Void(); +} -- GitLab From e502a601c9bd123d04b9ce4bee211025cd9f5f90 Mon Sep 17 00:00:00 2001 From: Hayden Gomes Date: Fri, 6 Nov 2020 15:15:26 -0800 Subject: [PATCH 271/790] Changing package for audio_policy_configuration_V7_0 - Changed package to use android. prefix - Added nullability flag to xsd_config Bug: 171572311 Test: built and atest VtsHalAudioEffectV7_0TargetTest VtsHalAudioEffectV7_0TargetTest VtsHalAudioEffectV4_0TargetTest VtsAidlHalAudioControlTest Change-Id: I9ac83a98256404313b5efef17c0a164d2ee72136 --- audio/7.0/config/Android.bp | 3 +- audio/7.0/config/api/current.txt | 878 +++++++++--------- ...d_audio_policy_configuration_V7_0-enums.h} | 12 +- audio/common/7.0/example/Effect.cpp | 4 +- .../4.0/AudioPrimaryHidlHalTest.cpp | 8 +- .../vts/functional/AudioPrimaryHidlHalTest.h | 6 +- .../VtsHalAudioEffectTargetTest.cpp | 10 +- .../aidl/default/AudioControl.cpp | 4 +- .../aidl/vts/VtsHalAudioControlTargetTest.cpp | 4 +- 9 files changed, 465 insertions(+), 464 deletions(-) rename audio/common/7.0/enums/include/{audio_policy_configuration_V7_0-enums.h => android_audio_policy_configuration_V7_0-enums.h} (96%) diff --git a/audio/7.0/config/Android.bp b/audio/7.0/config/Android.bp index 015c4244e8..f67cc7cb49 100644 --- a/audio/7.0/config/Android.bp +++ b/audio/7.0/config/Android.bp @@ -1,5 +1,6 @@ xsd_config { name: "audio_policy_configuration_V7_0", srcs: ["audio_policy_configuration.xsd"], - package_name: "audio.policy.configuration.V7_0", + package_name: "android.audio.policy.configuration.V7_0", + nullability: true, } diff --git a/audio/7.0/config/api/current.txt b/audio/7.0/config/api/current.txt index 453ed16d4f..fea697993e 100644 --- a/audio/7.0/config/api/current.txt +++ b/audio/7.0/config/api/current.txt @@ -1,571 +1,571 @@ // Signature format: 2.0 -package audio.policy.configuration.V7_0 { +package android.audio.policy.configuration.V7_0 { public class AttachedDevices { ctor public AttachedDevices(); - method public java.util.List getItem(); + method @Nullable public java.util.List getItem(); } public enum AudioChannelMask { - method public String getRawName(); - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_1; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_10; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_11; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_12; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_13; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_14; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_15; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_16; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_17; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_18; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_19; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_2; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_20; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_21; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_22; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_23; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_24; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_3; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_4; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_5; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_6; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_7; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_8; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_9; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_IN_2POINT0POINT2; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_IN_2POINT1POINT2; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_IN_3POINT0POINT2; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_IN_3POINT1POINT2; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_IN_5POINT1; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_IN_6; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_IN_FRONT_BACK; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_IN_MONO; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_IN_STEREO; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_IN_VOICE_CALL_MONO; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_IN_VOICE_DNLINK_MONO; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_IN_VOICE_UPLINK_MONO; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_NONE; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_2POINT0POINT2; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_2POINT1; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_2POINT1POINT2; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_3POINT0POINT2; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_3POINT1; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_3POINT1POINT2; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_5POINT1; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_5POINT1POINT2; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_5POINT1POINT4; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_5POINT1_BACK; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_5POINT1_SIDE; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_6POINT1; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_7POINT1; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_7POINT1POINT2; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_7POINT1POINT4; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_HAPTIC_AB; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_MONO; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_MONO_HAPTIC_A; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_MONO_HAPTIC_AB; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_PENTA; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_QUAD; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_QUAD_BACK; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_QUAD_SIDE; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_STEREO; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_STEREO_HAPTIC_A; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_STEREO_HAPTIC_AB; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_SURROUND; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_TRI; - enum_constant public static final audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_TRI_BACK; + method @NonNull public String getRawName(); + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_1; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_10; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_11; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_12; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_13; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_14; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_15; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_16; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_17; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_18; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_19; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_2; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_20; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_21; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_22; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_23; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_24; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_3; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_4; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_5; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_6; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_7; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_8; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_INDEX_MASK_9; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_IN_2POINT0POINT2; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_IN_2POINT1POINT2; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_IN_3POINT0POINT2; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_IN_3POINT1POINT2; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_IN_5POINT1; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_IN_6; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_IN_FRONT_BACK; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_IN_MONO; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_IN_STEREO; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_IN_VOICE_CALL_MONO; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_IN_VOICE_DNLINK_MONO; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_IN_VOICE_UPLINK_MONO; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_NONE; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_2POINT0POINT2; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_2POINT1; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_2POINT1POINT2; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_3POINT0POINT2; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_3POINT1; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_3POINT1POINT2; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_5POINT1; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_5POINT1POINT2; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_5POINT1POINT4; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_5POINT1_BACK; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_5POINT1_SIDE; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_6POINT1; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_7POINT1; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_7POINT1POINT2; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_7POINT1POINT4; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_HAPTIC_AB; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_MONO; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_MONO_HAPTIC_A; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_MONO_HAPTIC_AB; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_PENTA; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_QUAD; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_QUAD_BACK; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_QUAD_SIDE; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_STEREO; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_STEREO_HAPTIC_A; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_STEREO_HAPTIC_AB; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_SURROUND; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_TRI; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_TRI_BACK; } public enum AudioContentType { - method public String getRawName(); - enum_constant public static final audio.policy.configuration.V7_0.AudioContentType AUDIO_CONTENT_TYPE_MOVIE; - enum_constant public static final audio.policy.configuration.V7_0.AudioContentType AUDIO_CONTENT_TYPE_MUSIC; - enum_constant public static final audio.policy.configuration.V7_0.AudioContentType AUDIO_CONTENT_TYPE_SONIFICATION; - enum_constant public static final audio.policy.configuration.V7_0.AudioContentType AUDIO_CONTENT_TYPE_SPEECH; - enum_constant public static final audio.policy.configuration.V7_0.AudioContentType AUDIO_CONTENT_TYPE_UNKNOWN; + method @NonNull public String getRawName(); + enum_constant public static final android.audio.policy.configuration.V7_0.AudioContentType AUDIO_CONTENT_TYPE_MOVIE; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioContentType AUDIO_CONTENT_TYPE_MUSIC; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioContentType AUDIO_CONTENT_TYPE_SONIFICATION; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioContentType AUDIO_CONTENT_TYPE_SPEECH; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioContentType AUDIO_CONTENT_TYPE_UNKNOWN; } public enum AudioDevice { - method public String getRawName(); - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_AMBIENT; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_AUX_DIGITAL; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_BACK_MIC; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_BLE_HEADSET; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_BLUETOOTH_A2DP; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_BLUETOOTH_BLE; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_BUILTIN_MIC; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_BUS; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_COMMUNICATION; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_DEFAULT; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_ECHO_REFERENCE; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_FM_TUNER; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_HDMI; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_HDMI_ARC; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_IP; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_LINE; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_LOOPBACK; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_PROXY; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_REMOTE_SUBMIX; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_SPDIF; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_STUB; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_TELEPHONY_RX; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_TV_TUNER; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_USB_ACCESSORY; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_USB_DEVICE; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_USB_HEADSET; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_VOICE_CALL; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_WIRED_HEADSET; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_NONE; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_AUX_DIGITAL; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_AUX_LINE; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_BLE_HEADSET; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_BLE_SPEAKER; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_A2DP; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_SCO; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_BUS; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_DEFAULT; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_EARPIECE; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_ECHO_CANCELLER; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_FM; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_HDMI; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_HDMI_ARC; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_HEARING_AID; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_IP; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_LINE; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_PROXY; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_REMOTE_SUBMIX; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_SPDIF; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_SPEAKER; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_SPEAKER_SAFE; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_STUB; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_TELEPHONY_TX; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_USB_ACCESSORY; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_USB_DEVICE; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_USB_HEADSET; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_WIRED_HEADPHONE; - enum_constant public static final audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_WIRED_HEADSET; + method @NonNull public String getRawName(); + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_AMBIENT; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_AUX_DIGITAL; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_BACK_MIC; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_BLE_HEADSET; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_BLUETOOTH_A2DP; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_BLUETOOTH_BLE; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_BUILTIN_MIC; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_BUS; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_COMMUNICATION; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_DEFAULT; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_ECHO_REFERENCE; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_FM_TUNER; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_HDMI; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_HDMI_ARC; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_IP; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_LINE; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_LOOPBACK; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_PROXY; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_REMOTE_SUBMIX; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_SPDIF; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_STUB; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_TELEPHONY_RX; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_TV_TUNER; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_USB_ACCESSORY; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_USB_DEVICE; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_USB_HEADSET; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_VOICE_CALL; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_WIRED_HEADSET; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_NONE; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_AUX_DIGITAL; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_AUX_LINE; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_BLE_HEADSET; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_BLE_SPEAKER; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_A2DP; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_SCO; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_BUS; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_DEFAULT; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_EARPIECE; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_ECHO_CANCELLER; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_FM; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_HDMI; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_HDMI_ARC; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_HEARING_AID; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_IP; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_LINE; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_PROXY; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_REMOTE_SUBMIX; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_SPDIF; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_SPEAKER; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_SPEAKER_SAFE; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_STUB; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_TELEPHONY_TX; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_USB_ACCESSORY; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_USB_DEVICE; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_USB_HEADSET; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_WIRED_HEADPHONE; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_WIRED_HEADSET; } public enum AudioFormat { - method public String getRawName(); - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_ADIF; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_ADTS; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_ADTS_ELD; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_ADTS_ERLC; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_ADTS_HE_V1; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_ADTS_HE_V2; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_ADTS_LC; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_ADTS_LD; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_ADTS_LTP; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_ADTS_MAIN; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_ADTS_SCALABLE; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_ADTS_SSR; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_ADTS_XHE; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_ELD; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_ERLC; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_HE_V1; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_HE_V2; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_LATM; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_LATM_HE_V1; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_LATM_HE_V2; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_LATM_LC; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_LC; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_LD; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_LTP; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_MAIN; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_SCALABLE; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_SSR; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_XHE; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AC3; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AC4; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_ALAC; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AMR_NB; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AMR_WB; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AMR_WB_PLUS; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_APE; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_APTX; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_APTX_ADAPTIVE; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_APTX_HD; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_APTX_TWSP; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_CELT; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DOLBY_TRUEHD; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DSD; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DTS; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DTS_HD; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_EVRC; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_EVRCB; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_EVRCNW; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_EVRCWB; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_E_AC3; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_E_AC3_JOC; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_FLAC; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_HE_AAC_V1; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_HE_AAC_V2; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_IEC61937; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_LC3; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_LDAC; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_LHDC; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_LHDC_LL; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_MAT; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_MAT_1_0; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_MAT_2_0; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_MAT_2_1; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_MP2; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_MP3; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_OPUS; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_PCM_16_BIT; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_PCM_24_BIT_PACKED; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_PCM_32_BIT; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_PCM_8_24_BIT; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_PCM_8_BIT; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_PCM_FLOAT; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_QCELP; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_SBC; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_VORBIS; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_WMA; - enum_constant public static final audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_WMA_PRO; + method @NonNull public String getRawName(); + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_ADIF; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_ADTS; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_ADTS_ELD; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_ADTS_ERLC; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_ADTS_HE_V1; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_ADTS_HE_V2; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_ADTS_LC; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_ADTS_LD; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_ADTS_LTP; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_ADTS_MAIN; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_ADTS_SCALABLE; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_ADTS_SSR; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_ADTS_XHE; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_ELD; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_ERLC; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_HE_V1; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_HE_V2; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_LATM; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_LATM_HE_V1; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_LATM_HE_V2; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_LATM_LC; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_LC; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_LD; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_LTP; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_MAIN; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_SCALABLE; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_SSR; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AAC_XHE; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AC3; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AC4; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_ALAC; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AMR_NB; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AMR_WB; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_AMR_WB_PLUS; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_APE; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_APTX; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_APTX_ADAPTIVE; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_APTX_HD; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_APTX_TWSP; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_CELT; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DOLBY_TRUEHD; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DSD; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DTS; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DTS_HD; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_EVRC; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_EVRCB; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_EVRCNW; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_EVRCWB; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_E_AC3; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_E_AC3_JOC; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_FLAC; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_HE_AAC_V1; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_HE_AAC_V2; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_IEC61937; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_LC3; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_LDAC; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_LHDC; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_LHDC_LL; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_MAT; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_MAT_1_0; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_MAT_2_0; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_MAT_2_1; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_MP2; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_MP3; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_OPUS; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_PCM_16_BIT; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_PCM_24_BIT_PACKED; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_PCM_32_BIT; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_PCM_8_24_BIT; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_PCM_8_BIT; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_PCM_FLOAT; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_QCELP; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_SBC; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_VORBIS; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_WMA; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_WMA_PRO; } public enum AudioGainMode { - method public String getRawName(); - enum_constant public static final audio.policy.configuration.V7_0.AudioGainMode AUDIO_GAIN_MODE_CHANNELS; - enum_constant public static final audio.policy.configuration.V7_0.AudioGainMode AUDIO_GAIN_MODE_JOINT; - enum_constant public static final audio.policy.configuration.V7_0.AudioGainMode AUDIO_GAIN_MODE_RAMP; + method @NonNull public String getRawName(); + enum_constant public static final android.audio.policy.configuration.V7_0.AudioGainMode AUDIO_GAIN_MODE_CHANNELS; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioGainMode AUDIO_GAIN_MODE_JOINT; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioGainMode AUDIO_GAIN_MODE_RAMP; } public enum AudioInOutFlag { - method public String getRawName(); - enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_DIRECT; - enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_FAST; - enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_HW_AV_SYNC; - enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_HW_HOTWORD; - enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_MMAP_NOIRQ; - enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_NONE; - enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_RAW; - enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_SYNC; - enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_VOIP_TX; - enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD; - enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_DEEP_BUFFER; - enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_DIRECT; - enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_DIRECT_PCM; - enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_FAST; - enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_HW_AV_SYNC; - enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO; - enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_INCALL_MUSIC; - enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_MMAP_NOIRQ; - enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_NONE; - enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_NON_BLOCKING; - enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_PRIMARY; - enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_RAW; - enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_SYNC; - enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_TTS; - enum_constant public static final audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_VOIP_RX; + method @NonNull public String getRawName(); + enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_DIRECT; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_FAST; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_HW_AV_SYNC; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_HW_HOTWORD; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_MMAP_NOIRQ; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_NONE; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_RAW; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_SYNC; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_VOIP_TX; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_DEEP_BUFFER; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_DIRECT; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_DIRECT_PCM; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_FAST; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_HW_AV_SYNC; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_INCALL_MUSIC; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_MMAP_NOIRQ; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_NONE; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_NON_BLOCKING; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_PRIMARY; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_RAW; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_SYNC; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_TTS; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_VOIP_RX; } public class AudioPolicyConfiguration { ctor public AudioPolicyConfiguration(); - method public audio.policy.configuration.V7_0.GlobalConfiguration getGlobalConfiguration(); - method public java.util.List getModules(); - method public audio.policy.configuration.V7_0.SurroundSound getSurroundSound(); - method public audio.policy.configuration.V7_0.Version getVersion(); - method public java.util.List getVolumes(); - method public void setGlobalConfiguration(audio.policy.configuration.V7_0.GlobalConfiguration); - method public void setSurroundSound(audio.policy.configuration.V7_0.SurroundSound); - method public void setVersion(audio.policy.configuration.V7_0.Version); + method @Nullable public android.audio.policy.configuration.V7_0.GlobalConfiguration getGlobalConfiguration(); + method @Nullable public java.util.List getModules(); + method @Nullable public android.audio.policy.configuration.V7_0.SurroundSound getSurroundSound(); + method @Nullable public android.audio.policy.configuration.V7_0.Version getVersion(); + method @Nullable public java.util.List getVolumes(); + method public void setGlobalConfiguration(@Nullable android.audio.policy.configuration.V7_0.GlobalConfiguration); + method public void setSurroundSound(@Nullable android.audio.policy.configuration.V7_0.SurroundSound); + method public void setVersion(@Nullable android.audio.policy.configuration.V7_0.Version); } public enum AudioSource { - method public String getRawName(); - enum_constant public static final audio.policy.configuration.V7_0.AudioSource AUDIO_SOURCE_CAMCORDER; - enum_constant public static final audio.policy.configuration.V7_0.AudioSource AUDIO_SOURCE_DEFAULT; - enum_constant public static final audio.policy.configuration.V7_0.AudioSource AUDIO_SOURCE_ECHO_REFERENCE; - enum_constant public static final audio.policy.configuration.V7_0.AudioSource AUDIO_SOURCE_FM_TUNER; - enum_constant public static final audio.policy.configuration.V7_0.AudioSource AUDIO_SOURCE_HOTWORD; - enum_constant public static final audio.policy.configuration.V7_0.AudioSource AUDIO_SOURCE_MIC; - enum_constant public static final audio.policy.configuration.V7_0.AudioSource AUDIO_SOURCE_REMOTE_SUBMIX; - enum_constant public static final audio.policy.configuration.V7_0.AudioSource AUDIO_SOURCE_UNPROCESSED; - enum_constant public static final audio.policy.configuration.V7_0.AudioSource AUDIO_SOURCE_VOICE_CALL; - enum_constant public static final audio.policy.configuration.V7_0.AudioSource AUDIO_SOURCE_VOICE_COMMUNICATION; - enum_constant public static final audio.policy.configuration.V7_0.AudioSource AUDIO_SOURCE_VOICE_DOWNLINK; - enum_constant public static final audio.policy.configuration.V7_0.AudioSource AUDIO_SOURCE_VOICE_PERFORMANCE; - enum_constant public static final audio.policy.configuration.V7_0.AudioSource AUDIO_SOURCE_VOICE_RECOGNITION; - enum_constant public static final audio.policy.configuration.V7_0.AudioSource AUDIO_SOURCE_VOICE_UPLINK; + method @NonNull public String getRawName(); + enum_constant public static final android.audio.policy.configuration.V7_0.AudioSource AUDIO_SOURCE_CAMCORDER; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioSource AUDIO_SOURCE_DEFAULT; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioSource AUDIO_SOURCE_ECHO_REFERENCE; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioSource AUDIO_SOURCE_FM_TUNER; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioSource AUDIO_SOURCE_HOTWORD; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioSource AUDIO_SOURCE_MIC; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioSource AUDIO_SOURCE_REMOTE_SUBMIX; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioSource AUDIO_SOURCE_UNPROCESSED; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioSource AUDIO_SOURCE_VOICE_CALL; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioSource AUDIO_SOURCE_VOICE_COMMUNICATION; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioSource AUDIO_SOURCE_VOICE_DOWNLINK; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioSource AUDIO_SOURCE_VOICE_PERFORMANCE; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioSource AUDIO_SOURCE_VOICE_RECOGNITION; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioSource AUDIO_SOURCE_VOICE_UPLINK; } public enum AudioStreamType { - method public String getRawName(); - enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_ACCESSIBILITY; - enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_ALARM; - enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_ASSISTANT; - enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_BLUETOOTH_SCO; - enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_CALL_ASSISTANT; - enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_DTMF; - enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_ENFORCED_AUDIBLE; - enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_MUSIC; - enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_NOTIFICATION; - enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_PATCH; - enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_REROUTING; - enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_RING; - enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_SYSTEM; - enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_TTS; - enum_constant public static final audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_VOICE_CALL; + method @NonNull public String getRawName(); + enum_constant public static final android.audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_ACCESSIBILITY; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_ALARM; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_ASSISTANT; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_BLUETOOTH_SCO; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_CALL_ASSISTANT; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_DTMF; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_ENFORCED_AUDIBLE; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_MUSIC; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_NOTIFICATION; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_PATCH; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_REROUTING; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_RING; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_SYSTEM; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_TTS; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioStreamType AUDIO_STREAM_VOICE_CALL; } public enum AudioUsage { - method public String getRawName(); - enum_constant public static final audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_ALARM; - enum_constant public static final audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_ANNOUNCEMENT; - enum_constant public static final audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY; - enum_constant public static final audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE; - enum_constant public static final audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_ASSISTANCE_SONIFICATION; - enum_constant public static final audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_ASSISTANT; - enum_constant public static final audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_CALL_ASSISTANT; - enum_constant public static final audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_EMERGENCY; - enum_constant public static final audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_GAME; - enum_constant public static final audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_MEDIA; - enum_constant public static final audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_NOTIFICATION; - enum_constant public static final audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE; - enum_constant public static final audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_SAFETY; - enum_constant public static final audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_UNKNOWN; - enum_constant public static final audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_VEHICLE_STATUS; - enum_constant public static final audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_VIRTUAL_SOURCE; - enum_constant public static final audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_VOICE_COMMUNICATION; - enum_constant public static final audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING; + method @NonNull public String getRawName(); + enum_constant public static final android.audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_ALARM; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_ANNOUNCEMENT; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_ASSISTANCE_SONIFICATION; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_ASSISTANT; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_CALL_ASSISTANT; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_EMERGENCY; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_GAME; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_MEDIA; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_NOTIFICATION; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_SAFETY; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_UNKNOWN; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_VEHICLE_STATUS; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_VIRTUAL_SOURCE; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_VOICE_COMMUNICATION; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioUsage AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING; } public enum DeviceCategory { - method public String getRawName(); - enum_constant public static final audio.policy.configuration.V7_0.DeviceCategory DEVICE_CATEGORY_EARPIECE; - enum_constant public static final audio.policy.configuration.V7_0.DeviceCategory DEVICE_CATEGORY_EXT_MEDIA; - enum_constant public static final audio.policy.configuration.V7_0.DeviceCategory DEVICE_CATEGORY_HEADSET; - enum_constant public static final audio.policy.configuration.V7_0.DeviceCategory DEVICE_CATEGORY_HEARING_AID; - enum_constant public static final audio.policy.configuration.V7_0.DeviceCategory DEVICE_CATEGORY_SPEAKER; + method @NonNull public String getRawName(); + enum_constant public static final android.audio.policy.configuration.V7_0.DeviceCategory DEVICE_CATEGORY_EARPIECE; + enum_constant public static final android.audio.policy.configuration.V7_0.DeviceCategory DEVICE_CATEGORY_EXT_MEDIA; + enum_constant public static final android.audio.policy.configuration.V7_0.DeviceCategory DEVICE_CATEGORY_HEADSET; + enum_constant public static final android.audio.policy.configuration.V7_0.DeviceCategory DEVICE_CATEGORY_HEARING_AID; + enum_constant public static final android.audio.policy.configuration.V7_0.DeviceCategory DEVICE_CATEGORY_SPEAKER; } public class DevicePorts { ctor public DevicePorts(); - method public java.util.List getDevicePort(); + method @Nullable public java.util.List getDevicePort(); } public static class DevicePorts.DevicePort { ctor public DevicePorts.DevicePort(); - method public String getAddress(); - method public java.util.List getEncodedFormats(); - method public audio.policy.configuration.V7_0.Gains getGains(); - method public java.util.List getProfile(); - method public audio.policy.configuration.V7_0.Role getRole(); - method public String getTagName(); - method public String getType(); - method public boolean get_default(); - method public void setAddress(String); - method public void setEncodedFormats(java.util.List); - method public void setGains(audio.policy.configuration.V7_0.Gains); - method public void setRole(audio.policy.configuration.V7_0.Role); - method public void setTagName(String); - method public void setType(String); - method public void set_default(boolean); + method @Nullable public String getAddress(); + method @Nullable public java.util.List getEncodedFormats(); + method @Nullable public android.audio.policy.configuration.V7_0.Gains getGains(); + method @Nullable public java.util.List getProfile(); + method @Nullable public android.audio.policy.configuration.V7_0.Role getRole(); + method @Nullable public String getTagName(); + method @Nullable public String getType(); + method @Nullable public boolean get_default(); + method public void setAddress(@Nullable String); + method public void setEncodedFormats(@Nullable java.util.List); + method public void setGains(@Nullable android.audio.policy.configuration.V7_0.Gains); + method public void setRole(@Nullable android.audio.policy.configuration.V7_0.Role); + method public void setTagName(@Nullable String); + method public void setType(@Nullable String); + method public void set_default(@Nullable boolean); } public enum EngineSuffix { - method public String getRawName(); - enum_constant public static final audio.policy.configuration.V7_0.EngineSuffix _default; - enum_constant public static final audio.policy.configuration.V7_0.EngineSuffix configurable; + method @NonNull public String getRawName(); + enum_constant public static final android.audio.policy.configuration.V7_0.EngineSuffix _default; + enum_constant public static final android.audio.policy.configuration.V7_0.EngineSuffix configurable; } public class Gains { ctor public Gains(); - method public java.util.List getGain(); + method @Nullable public java.util.List getGain(); } public static class Gains.Gain { ctor public Gains.Gain(); - method public audio.policy.configuration.V7_0.AudioChannelMask getChannel_mask(); - method public int getDefaultValueMB(); - method public int getMaxRampMs(); - method public int getMaxValueMB(); - method public int getMinRampMs(); - method public int getMinValueMB(); - method public java.util.List getMode(); - method public String getName(); - method public int getStepValueMB(); - method public boolean getUseForVolume(); - method public void setChannel_mask(audio.policy.configuration.V7_0.AudioChannelMask); - method public void setDefaultValueMB(int); - method public void setMaxRampMs(int); - method public void setMaxValueMB(int); - method public void setMinRampMs(int); - method public void setMinValueMB(int); - method public void setMode(java.util.List); - method public void setName(String); - method public void setStepValueMB(int); - method public void setUseForVolume(boolean); + method @Nullable public android.audio.policy.configuration.V7_0.AudioChannelMask getChannel_mask(); + method @Nullable public int getDefaultValueMB(); + method @Nullable public int getMaxRampMs(); + method @Nullable public int getMaxValueMB(); + method @Nullable public int getMinRampMs(); + method @Nullable public int getMinValueMB(); + method @Nullable public java.util.List getMode(); + method @Nullable public String getName(); + method @Nullable public int getStepValueMB(); + method @Nullable public boolean getUseForVolume(); + method public void setChannel_mask(@Nullable android.audio.policy.configuration.V7_0.AudioChannelMask); + method public void setDefaultValueMB(@Nullable int); + method public void setMaxRampMs(@Nullable int); + method public void setMaxValueMB(@Nullable int); + method public void setMinRampMs(@Nullable int); + method public void setMinValueMB(@Nullable int); + method public void setMode(@Nullable java.util.List); + method public void setName(@Nullable String); + method public void setStepValueMB(@Nullable int); + method public void setUseForVolume(@Nullable boolean); } public class GlobalConfiguration { ctor public GlobalConfiguration(); - method public boolean getCall_screen_mode_supported(); - method public audio.policy.configuration.V7_0.EngineSuffix getEngine_library(); - method public boolean getSpeaker_drc_enabled(); - method public void setCall_screen_mode_supported(boolean); - method public void setEngine_library(audio.policy.configuration.V7_0.EngineSuffix); - method public void setSpeaker_drc_enabled(boolean); + method @Nullable public boolean getCall_screen_mode_supported(); + method @Nullable public android.audio.policy.configuration.V7_0.EngineSuffix getEngine_library(); + method @Nullable public boolean getSpeaker_drc_enabled(); + method public void setCall_screen_mode_supported(@Nullable boolean); + method public void setEngine_library(@Nullable android.audio.policy.configuration.V7_0.EngineSuffix); + method public void setSpeaker_drc_enabled(@Nullable boolean); } public enum HalVersion { - method public String getRawName(); - enum_constant public static final audio.policy.configuration.V7_0.HalVersion _2_0; - enum_constant public static final audio.policy.configuration.V7_0.HalVersion _3_0; + method @NonNull public String getRawName(); + enum_constant public static final android.audio.policy.configuration.V7_0.HalVersion _2_0; + enum_constant public static final android.audio.policy.configuration.V7_0.HalVersion _3_0; } public class MixPorts { ctor public MixPorts(); - method public java.util.List getMixPort(); + method @Nullable public java.util.List getMixPort(); } public static class MixPorts.MixPort { ctor public MixPorts.MixPort(); - method public java.util.List getFlags(); - method public audio.policy.configuration.V7_0.Gains getGains(); - method public long getMaxActiveCount(); - method public long getMaxOpenCount(); - method public String getName(); - method public java.util.List getPreferredUsage(); - method public java.util.List getProfile(); - method public audio.policy.configuration.V7_0.Role getRole(); - method public void setFlags(java.util.List); - method public void setGains(audio.policy.configuration.V7_0.Gains); - method public void setMaxActiveCount(long); - method public void setMaxOpenCount(long); - method public void setName(String); - method public void setPreferredUsage(java.util.List); - method public void setRole(audio.policy.configuration.V7_0.Role); + method @Nullable public java.util.List getFlags(); + method @Nullable public android.audio.policy.configuration.V7_0.Gains getGains(); + method @Nullable public long getMaxActiveCount(); + method @Nullable public long getMaxOpenCount(); + method @Nullable public String getName(); + method @Nullable public java.util.List getPreferredUsage(); + method @Nullable public java.util.List getProfile(); + method @Nullable public android.audio.policy.configuration.V7_0.Role getRole(); + method public void setFlags(@Nullable java.util.List); + method public void setGains(@Nullable android.audio.policy.configuration.V7_0.Gains); + method public void setMaxActiveCount(@Nullable long); + method public void setMaxOpenCount(@Nullable long); + method public void setName(@Nullable String); + method public void setPreferredUsage(@Nullable java.util.List); + method public void setRole(@Nullable android.audio.policy.configuration.V7_0.Role); } public enum MixType { - method public String getRawName(); - enum_constant public static final audio.policy.configuration.V7_0.MixType mix; - enum_constant public static final audio.policy.configuration.V7_0.MixType mux; + method @NonNull public String getRawName(); + enum_constant public static final android.audio.policy.configuration.V7_0.MixType mix; + enum_constant public static final android.audio.policy.configuration.V7_0.MixType mux; } public class Modules { ctor public Modules(); - method public java.util.List getModule(); + method @Nullable public java.util.List getModule(); } public static class Modules.Module { ctor public Modules.Module(); - method public audio.policy.configuration.V7_0.AttachedDevices getAttachedDevices(); - method public String getDefaultOutputDevice(); - method public audio.policy.configuration.V7_0.DevicePorts getDevicePorts(); - method public audio.policy.configuration.V7_0.HalVersion getHalVersion(); - method public audio.policy.configuration.V7_0.MixPorts getMixPorts(); - method public String getName(); - method public audio.policy.configuration.V7_0.Routes getRoutes(); - method public void setAttachedDevices(audio.policy.configuration.V7_0.AttachedDevices); - method public void setDefaultOutputDevice(String); - method public void setDevicePorts(audio.policy.configuration.V7_0.DevicePorts); - method public void setHalVersion(audio.policy.configuration.V7_0.HalVersion); - method public void setMixPorts(audio.policy.configuration.V7_0.MixPorts); - method public void setName(String); - method public void setRoutes(audio.policy.configuration.V7_0.Routes); + method @Nullable public android.audio.policy.configuration.V7_0.AttachedDevices getAttachedDevices(); + method @Nullable public String getDefaultOutputDevice(); + method @Nullable public android.audio.policy.configuration.V7_0.DevicePorts getDevicePorts(); + method @Nullable public android.audio.policy.configuration.V7_0.HalVersion getHalVersion(); + method @Nullable public android.audio.policy.configuration.V7_0.MixPorts getMixPorts(); + method @Nullable public String getName(); + method @Nullable public android.audio.policy.configuration.V7_0.Routes getRoutes(); + method public void setAttachedDevices(@Nullable android.audio.policy.configuration.V7_0.AttachedDevices); + method public void setDefaultOutputDevice(@Nullable String); + method public void setDevicePorts(@Nullable android.audio.policy.configuration.V7_0.DevicePorts); + method public void setHalVersion(@Nullable android.audio.policy.configuration.V7_0.HalVersion); + method public void setMixPorts(@Nullable android.audio.policy.configuration.V7_0.MixPorts); + method public void setName(@Nullable String); + method public void setRoutes(@Nullable android.audio.policy.configuration.V7_0.Routes); } public class Profile { ctor public Profile(); - method public java.util.List getChannelMasks(); - method public String getFormat(); - method public String getName(); - method public java.util.List getSamplingRates(); - method public void setChannelMasks(java.util.List); - method public void setFormat(String); - method public void setName(String); - method public void setSamplingRates(java.util.List); + method @Nullable public java.util.List getChannelMasks(); + method @Nullable public String getFormat(); + method @Nullable public String getName(); + method @Nullable public java.util.List getSamplingRates(); + method public void setChannelMasks(@Nullable java.util.List); + method public void setFormat(@Nullable String); + method public void setName(@Nullable String); + method public void setSamplingRates(@Nullable java.util.List); } public class Reference { ctor public Reference(); - method public String getName(); - method public java.util.List getPoint(); - method public void setName(String); + method @Nullable public String getName(); + method @Nullable public java.util.List getPoint(); + method public void setName(@Nullable String); } public enum Role { - method public String getRawName(); - enum_constant public static final audio.policy.configuration.V7_0.Role sink; - enum_constant public static final audio.policy.configuration.V7_0.Role source; + method @NonNull public String getRawName(); + enum_constant public static final android.audio.policy.configuration.V7_0.Role sink; + enum_constant public static final android.audio.policy.configuration.V7_0.Role source; } public class Routes { ctor public Routes(); - method public java.util.List getRoute(); + method @Nullable public java.util.List getRoute(); } public static class Routes.Route { ctor public Routes.Route(); - method public String getSink(); - method public String getSources(); - method public audio.policy.configuration.V7_0.MixType getType(); - method public void setSink(String); - method public void setSources(String); - method public void setType(audio.policy.configuration.V7_0.MixType); + method @Nullable public String getSink(); + method @Nullable public String getSources(); + method @Nullable public android.audio.policy.configuration.V7_0.MixType getType(); + method public void setSink(@Nullable String); + method public void setSources(@Nullable String); + method public void setType(@Nullable android.audio.policy.configuration.V7_0.MixType); } public class SurroundFormats { ctor public SurroundFormats(); - method public java.util.List getFormat(); + method @Nullable public java.util.List getFormat(); } public static class SurroundFormats.Format { ctor public SurroundFormats.Format(); - method public audio.policy.configuration.V7_0.AudioFormat getName(); - method public java.util.List getSubformats(); - method public void setName(audio.policy.configuration.V7_0.AudioFormat); - method public void setSubformats(java.util.List); + method @Nullable public android.audio.policy.configuration.V7_0.AudioFormat getName(); + method @Nullable public java.util.List getSubformats(); + method public void setName(@Nullable android.audio.policy.configuration.V7_0.AudioFormat); + method public void setSubformats(@Nullable java.util.List); } public class SurroundSound { ctor public SurroundSound(); - method public audio.policy.configuration.V7_0.SurroundFormats getFormats(); - method public void setFormats(audio.policy.configuration.V7_0.SurroundFormats); + method @Nullable public android.audio.policy.configuration.V7_0.SurroundFormats getFormats(); + method public void setFormats(@Nullable android.audio.policy.configuration.V7_0.SurroundFormats); } public enum Version { - method public String getRawName(); - enum_constant public static final audio.policy.configuration.V7_0.Version _1_0; + method @NonNull public String getRawName(); + enum_constant public static final android.audio.policy.configuration.V7_0.Version _1_0; } public class Volume { ctor public Volume(); - method public audio.policy.configuration.V7_0.DeviceCategory getDeviceCategory(); - method public java.util.List getPoint(); - method public String getRef(); - method public audio.policy.configuration.V7_0.AudioStreamType getStream(); - method public void setDeviceCategory(audio.policy.configuration.V7_0.DeviceCategory); - method public void setRef(String); - method public void setStream(audio.policy.configuration.V7_0.AudioStreamType); + method @Nullable public android.audio.policy.configuration.V7_0.DeviceCategory getDeviceCategory(); + method @Nullable public java.util.List getPoint(); + method @Nullable public String getRef(); + method @Nullable public android.audio.policy.configuration.V7_0.AudioStreamType getStream(); + method public void setDeviceCategory(@Nullable android.audio.policy.configuration.V7_0.DeviceCategory); + method public void setRef(@Nullable String); + method public void setStream(@Nullable android.audio.policy.configuration.V7_0.AudioStreamType); } public class Volumes { ctor public Volumes(); - method public java.util.List getReference(); - method public java.util.List getVolume(); + method @Nullable public java.util.List getReference(); + method @Nullable public java.util.List getVolume(); } public class XmlParser { ctor public XmlParser(); - method public static audio.policy.configuration.V7_0.AudioPolicyConfiguration read(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException; - method public static String readText(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; - method public static void skip(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; + method @Nullable public static android.audio.policy.configuration.V7_0.AudioPolicyConfiguration read(@NonNull java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException; + method @Nullable public static String readText(@NonNull org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; + method public static void skip(@NonNull org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; } } diff --git a/audio/common/7.0/enums/include/audio_policy_configuration_V7_0-enums.h b/audio/common/7.0/enums/include/android_audio_policy_configuration_V7_0-enums.h similarity index 96% rename from audio/common/7.0/enums/include/audio_policy_configuration_V7_0-enums.h rename to audio/common/7.0/enums/include/android_audio_policy_configuration_V7_0-enums.h index cedcab3cc2..7148d76820 100644 --- a/audio/common/7.0/enums/include/audio_policy_configuration_V7_0-enums.h +++ b/audio/common/7.0/enums/include/android_audio_policy_configuration_V7_0-enums.h @@ -14,14 +14,14 @@ * limitations under the License. */ -#ifndef AUDIO_POLICY_CONFIGURATION_V7_0_ENUMS_H -#define AUDIO_POLICY_CONFIGURATION_V7_0_ENUMS_H +#ifndef ANDROID_AUDIO_POLICY_CONFIGURATION_V7_0_ENUMS_H +#define ANDROID_AUDIO_POLICY_CONFIGURATION_V7_0_ENUMS_H #include -#include +#include -namespace audio::policy::configuration::V7_0 { +namespace android::audio::policy::configuration::V7_0 { static inline size_t getChannelCount(AudioChannelMask mask) { switch (mask) { @@ -210,6 +210,6 @@ static inline bool isOutputDevice(const std::string& device) { return isOutputDevice(stringToAudioDevice(device)); } -} // namespace audio::policy::configuration::V7_0 +} // namespace android::audio::policy::configuration::V7_0 -#endif // AUDIO_POLICY_CONFIGURATION_V7_0_ENUMS_H +#endif // ANDROID_AUDIO_POLICY_CONFIGURATION_V7_0_ENUMS_H diff --git a/audio/common/7.0/example/Effect.cpp b/audio/common/7.0/example/Effect.cpp index 423754d593..9d5ab3198a 100644 --- a/audio/common/7.0/example/Effect.cpp +++ b/audio/common/7.0/example/Effect.cpp @@ -17,7 +17,7 @@ #define LOG_TAG "EffectsFactory7.0" #include -#include +#include #include "Effect.h" @@ -28,7 +28,7 @@ using ::android::hardware::Void; using namespace ::android::hardware::audio::common::V7_0; // Make an alias for enumerations generated from the APM config XSD. namespace xsd { -using namespace ::audio::policy::configuration::V7_0; +using namespace ::android::audio::policy::configuration::V7_0; } namespace android::hardware::audio::effect::V7_0::implementation { diff --git a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp index 2466fd120a..eb8cb3f4f7 100644 --- a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp +++ b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp @@ -17,7 +17,7 @@ #include "AudioPrimaryHidlHalTest.h" #if MAJOR_VERSION >= 7 -#include +#include #include using android::xsdc_enum_range; @@ -236,7 +236,7 @@ TEST_P(InputStreamTest, updateSinkMetadata) { #if MAJOR_VERSION <= 6 hidl_enum_range range; #elif MAJOR_VERSION >= 7 - xsdc_enum_range range; + xsdc_enum_range range; #endif // Test all possible track configuration for (auto source : range) { @@ -272,8 +272,8 @@ TEST_P(OutputStreamTest, updateSourceMetadata) { hidl_enum_range usageRange; hidl_enum_range contentRange; #elif MAJOR_VERSION >= 7 - xsdc_enum_range usageRange; - xsdc_enum_range contentRange; + xsdc_enum_range usageRange; + xsdc_enum_range contentRange; #endif // Test all possible track configuration for (auto usage : usageRange) { diff --git a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h index 0a9d5ee166..1ead47c0ca 100644 --- a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h +++ b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h @@ -43,8 +43,8 @@ #include PATH(android/hardware/audio/FILE_VERSION/types.h) #include PATH(android/hardware/audio/common/FILE_VERSION/types.h) #if MAJOR_VERSION >= 7 -#include -#include +#include +#include #endif #include @@ -91,7 +91,7 @@ using namespace ::android::hardware::audio::CPP_VERSION; #if MAJOR_VERSION >= 7 // Make an alias for enumerations generated from the APM config XSD. namespace xsd { -using namespace ::audio::policy::configuration::CPP_VERSION; +using namespace ::android::audio::policy::configuration::CPP_VERSION; } #endif diff --git a/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp b/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp index b64f105eb4..199a8a52a8 100644 --- a/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp +++ b/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp @@ -28,8 +28,8 @@ #include #include #if MAJOR_VERSION >= 7 -#include -#include +#include +#include #endif #include @@ -54,7 +54,7 @@ using namespace ::android::hardware::audio::effect::CPP_VERSION; #if MAJOR_VERSION >= 7 // Make an alias for enumerations generated from the APM config XSD. namespace xsd { -using namespace ::audio::policy::configuration::CPP_VERSION; +using namespace ::android::audio::policy::configuration::CPP_VERSION; } #endif @@ -262,8 +262,8 @@ void AudioEffectHidlTest::getChannelCount(uint32_t* channelCount) { *channelCount = audio_channel_count_from_out_mask( static_cast(currentConfig.outputCfg.channels)); #else - *channelCount = - audio::policy::configuration::V7_0::getChannelCount(currentConfig.outputCfg.channels); + *channelCount = android::audio::policy::configuration::V7_0::getChannelCount( + currentConfig.outputCfg.channels); ASSERT_NE(*channelCount, 0); #endif } diff --git a/automotive/audiocontrol/aidl/default/AudioControl.cpp b/automotive/audiocontrol/aidl/default/AudioControl.cpp index b6373108eb..5e09b4f6a1 100644 --- a/automotive/audiocontrol/aidl/default/AudioControl.cpp +++ b/automotive/audiocontrol/aidl/default/AudioControl.cpp @@ -23,7 +23,7 @@ #include #include -#include +#include #include #include @@ -35,7 +35,7 @@ using ::android::base::ParseInt; using ::std::string; namespace xsd { -using namespace audio::policy::configuration::V7_0; +using namespace ::android::audio::policy::configuration::V7_0; } namespace { diff --git a/automotive/audiocontrol/aidl/vts/VtsHalAudioControlTargetTest.cpp b/automotive/audiocontrol/aidl/vts/VtsHalAudioControlTargetTest.cpp index c734e29e29..f33b8a5e9d 100644 --- a/automotive/audiocontrol/aidl/vts/VtsHalAudioControlTargetTest.cpp +++ b/automotive/audiocontrol/aidl/vts/VtsHalAudioControlTargetTest.cpp @@ -33,10 +33,10 @@ using android::hardware::automotive::audiocontrol::AudioFocusChange; using android::hardware::automotive::audiocontrol::BnFocusListener; using android::hardware::automotive::audiocontrol::IAudioControl; -#include "audio_policy_configuration_V7_0.h" +#include "android_audio_policy_configuration_V7_0.h" namespace xsd { -using namespace audio::policy::configuration::V7_0; +using namespace android::audio::policy::configuration::V7_0; } class AudioControlAidl : public testing::TestWithParam { -- GitLab From 68dc40f11157facc5b8146dad7e5a2a78e6a2f67 Mon Sep 17 00:00:00 2001 From: Yu-Han Yang Date: Thu, 12 Nov 2020 11:24:49 -0800 Subject: [PATCH 272/790] Add GNSS AIDL HAL VTS to presubmit checks Bug: 171821213 Test: on cuttlefish Change-Id: I0375976671a3556c0ee4a847dcdf88e7cd25c76f --- gnss/aidl/TEST_MAPPING | 7 +++++++ gnss/aidl/vts/gnss_hal_test_cases.cpp | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 gnss/aidl/TEST_MAPPING diff --git a/gnss/aidl/TEST_MAPPING b/gnss/aidl/TEST_MAPPING new file mode 100644 index 0000000000..c21c3e49cc --- /dev/null +++ b/gnss/aidl/TEST_MAPPING @@ -0,0 +1,7 @@ +{ + "presubmit": [ + { + "name": "VtsHalGnssTargetTest" + } + ] +} diff --git a/gnss/aidl/vts/gnss_hal_test_cases.cpp b/gnss/aidl/vts/gnss_hal_test_cases.cpp index 2b8a447206..d621053240 100644 --- a/gnss/aidl/vts/gnss_hal_test_cases.cpp +++ b/gnss/aidl/vts/gnss_hal_test_cases.cpp @@ -46,7 +46,7 @@ TEST_P(GnssHalTest, TestPsdsExtension) { ASSERT_TRUE(iGnssPsds != nullptr); status = iGnssPsds->injectPsdsData(PsdsType::LONG_TERM, std::vector()); - ASSERT_TRUE(status.isOk()); + ASSERT_FALSE(status.isOk()); } /* -- GitLab From ff82d7ca94c4ceeea56499aeca5484ff5201debf Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Wed, 11 Nov 2020 20:01:07 -0800 Subject: [PATCH 273/790] Add startId in Filter Event to work with filter reconfiguration Test: atest VtsHalTvTunerV1_1TargetTest Bug: 172593389 Change-Id: I77e45366b737068aa0aa20c2b384f2e3160c7398 --- tv/tuner/1.1/IFilter.hal | 2 + tv/tuner/1.1/IFilterCallback.hal | 3 +- tv/tuner/1.1/default/Filter.cpp | 12 +++++- tv/tuner/1.1/default/Filter.h | 3 ++ tv/tuner/1.1/types.hal | 8 ++++ tv/tuner/1.1/vts/functional/FilterTests.cpp | 26 +++++++++++- tv/tuner/1.1/vts/functional/FilterTests.h | 3 ++ .../VtsHalTvTunerV1_1TargetTest.cpp | 40 +++++++++++++++++++ .../functional/VtsHalTvTunerV1_1TargetTest.h | 3 +- 9 files changed, 94 insertions(+), 6 deletions(-) diff --git a/tv/tuner/1.1/IFilter.hal b/tv/tuner/1.1/IFilter.hal index df736aa86b..1c6c33fe2b 100644 --- a/tv/tuner/1.1/IFilter.hal +++ b/tv/tuner/1.1/IFilter.hal @@ -26,6 +26,8 @@ import @1.0::Result; * To access the v1.1 IFilter APIs, the implementation can cast the IFilter * interface returned from the @1.0::IDemux openFilter into a v1.1 IFiler * using V1_1::IFilter::castFrom(V1_0::IFilter). + * + * Note that reconfiguring Filter must happen after the Filter is stopped. */ interface IFilter extends @1.0::IFilter { /** diff --git a/tv/tuner/1.1/IFilterCallback.hal b/tv/tuner/1.1/IFilterCallback.hal index 9960a23775..23ae844354 100644 --- a/tv/tuner/1.1/IFilterCallback.hal +++ b/tv/tuner/1.1/IFilterCallback.hal @@ -25,7 +25,8 @@ interface IFilterCallback extends @1.0::IFilterCallback { * Notify the client that a new filter event happened. * * @param filterEvent a v1_0 filter event. - * @param filterEventExt a v1_1 extended filter event. + * @param filterEventExt a v1_1 extended filter event. Send an empty filterEvent along with + * startId or scramblingStatus filterEventExt */ oneway onFilterEvent_1_1(DemuxFilterEvent filterEvent, DemuxFilterEventExt filterEventExt); }; diff --git a/tv/tuner/1.1/default/Filter.cpp b/tv/tuner/1.1/default/Filter.cpp index 139e98af99..e766a8af72 100644 --- a/tv/tuner/1.1/default/Filter.cpp +++ b/tv/tuner/1.1/default/Filter.cpp @@ -131,6 +131,7 @@ Return Filter::configure(const DemuxFilterSettings& settings) { break; } + mConfigured = true; return Result::SUCCESS; } @@ -145,8 +146,6 @@ Return Filter::stop() { mFilterThreadRunning = false; - std::lock_guard lock(mFilterThreadLock); - return Result::SUCCESS; } @@ -321,8 +320,17 @@ void Filter::filterThreadLoop() { usleep(1000 * 1000); continue; } + // After successfully write, send a callback and wait for the read to be done if (mCallback_1_1 != nullptr) { + if (mConfigured) { + DemuxFilterEvent emptyEvent; + V1_1::DemuxFilterEventExt startEvent; + startEvent.events.resize(1); + startEvent.events[0].startId(mStartId++); + mCallback_1_1->onFilterEvent_1_1(emptyEvent, startEvent); + mConfigured = false; + } mCallback_1_1->onFilterEvent_1_1(mFilterEvent, mFilterEventExt); mFilterEventExt.events.resize(0); } else if (mCallback != nullptr) { diff --git a/tv/tuner/1.1/default/Filter.h b/tv/tuner/1.1/default/Filter.h index a7b3fd26d7..1ebc1351a0 100644 --- a/tv/tuner/1.1/default/Filter.h +++ b/tv/tuner/1.1/default/Filter.h @@ -235,6 +235,9 @@ class Filter : public V1_1::IFilter { // Scrambling status to be monitored uint32_t mStatuses = 0; + + bool mConfigured = false; + int mStartId = 0; }; } // namespace implementation diff --git a/tv/tuner/1.1/types.hal b/tv/tuner/1.1/types.hal index 006e59749a..09b87f2ac8 100644 --- a/tv/tuner/1.1/types.hal +++ b/tv/tuner/1.1/types.hal @@ -161,6 +161,14 @@ struct DemuxFilterEventExt { DemuxFilterMmtpRecordEventExt mmtpRecord; ScramblingStatus scramblingStatus; + + /** + * An unique ID to mark the start point of receiving the valid filter events after + * reconfiguring the filter. It must be sent at least once in the first event after the + * filter is restarted. 0 is reserved for the newly opened filter's first start, which is + * optional for HAL to send. + */ + uint32_t startId; }; /** diff --git a/tv/tuner/1.1/vts/functional/FilterTests.cpp b/tv/tuner/1.1/vts/functional/FilterTests.cpp index d2535e533b..cdf3b6998b 100644 --- a/tv/tuner/1.1/vts/functional/FilterTests.cpp +++ b/tv/tuner/1.1/vts/functional/FilterTests.cpp @@ -40,6 +40,18 @@ void FilterCallback::testFilterScramblingEvent() { ALOGW("[vts] pass and stop"); } +void FilterCallback::testStartIdAfterReconfigure() { + android::Mutex::Autolock autoLock(mMsgLock); + while (!mStartIdReceived) { + if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) { + EXPECT_TRUE(false) << "does not receive start id within timeout"; + return; + } + } + mStartIdReceived = false; + ALOGW("[vts] pass and stop"); +} + void FilterCallback::readFilterEventData() { ALOGW("[vts] reading filter event"); // todo separate filter handlers @@ -71,6 +83,10 @@ void FilterCallback::readFilterEventData() { case DemuxFilterEventExt::Event::hidl_discriminator::scramblingStatus: mScramblingStatusEvent++; break; + case DemuxFilterEventExt::Event::hidl_discriminator::startId: + ALOGD("[vts] Extended restart filter event, startId=%d", eventExt.startId()); + mStartIdReceived = true; + break; default: break; } @@ -90,8 +106,8 @@ bool FilterCallback::dumpAvData(DemuxFilterMediaEvent event) { } int av_fd = handle.getNativeHandle()->data[0]; - uint8_t* buffer = - static_cast(mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, av_fd, 0)); + uint8_t* buffer = static_cast( + mmap(NULL, length + offset, PROT_READ | PROT_WRITE, MAP_SHARED, av_fd, 0)); if (buffer == MAP_FAILED) { ALOGE("[vts] fail to allocate av buffer, errno=%d", errno); return false; @@ -271,3 +287,9 @@ AssertionResult FilterTests::configureScramblingEvent(uint64_t filterId, uint32_ } return AssertionResult(status == Result::SUCCESS); } + +AssertionResult FilterTests::startIdTest(uint64_t filterId) { + EXPECT_TRUE(mFilterCallbacks[filterId]) << "Test with getNewlyOpenedFilterId first."; + mFilterCallbacks[filterId]->testStartIdAfterReconfigure(); + return AssertionResult(true); +} diff --git a/tv/tuner/1.1/vts/functional/FilterTests.h b/tv/tuner/1.1/vts/functional/FilterTests.h index d88f171e10..ae57659a38 100644 --- a/tv/tuner/1.1/vts/functional/FilterTests.h +++ b/tv/tuner/1.1/vts/functional/FilterTests.h @@ -118,6 +118,7 @@ class FilterCallback : public IFilterCallback { void testFilterDataOutput(); void testFilterScramblingEvent(); + void testStartIdAfterReconfigure(); void readFilterEventData(); bool dumpAvData(DemuxFilterMediaEvent event); @@ -138,6 +139,7 @@ class FilterCallback : public IFilterCallback { int mPidFilterOutputCount = 0; int mScramblingStatusEvent = 0; + bool mStartIdReceived = false; }; class FilterTests { @@ -160,6 +162,7 @@ class FilterTests { AssertionResult startFilter(uint64_t filterId); AssertionResult stopFilter(uint64_t filterId); AssertionResult closeFilter(uint64_t filterId); + AssertionResult startIdTest(uint64_t filterId); FilterEventType getFilterEventType(DemuxFilterType type) { FilterEventType eventType = FilterEventType::UNDEFINED; diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp index 17abf49842..dda8b60087 100644 --- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp @@ -57,6 +57,39 @@ void TunerFilterHidlTest::configSingleFilterInDemuxTest(FilterConfig filterConf, ASSERT_TRUE(mFrontendTests.closeFrontend()); } +void TunerFilterHidlTest::reconfigSingleFilterInDemuxTest(FilterConfig filterConf, + FilterConfig filterReconf, + FrontendConfig frontendConf) { + uint32_t feId; + uint32_t demuxId; + sp demux; + uint64_t filterId; + + mFrontendTests.getFrontendIdByType(frontendConf.type, feId); + ASSERT_TRUE(feId != INVALID_ID); + ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); + ASSERT_TRUE(mFrontendTests.setFrontendCallback()); + ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); + ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); + mFrontendTests.setDemux(demux); + mFilterTests.setDemux(demux); + ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize)); + ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(filterId)); + ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId)); + ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId)); + ASSERT_TRUE(mFilterTests.startFilter(filterId)); + ASSERT_TRUE(mFilterTests.stopFilter(filterId)); + ASSERT_TRUE(mFilterTests.configFilter(filterReconf.settings, filterId)); + ASSERT_TRUE(mFilterTests.startFilter(filterId)); + ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/)); + ASSERT_TRUE(mFilterTests.startIdTest(filterId)); + ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/)); + ASSERT_TRUE(mFilterTests.stopFilter(filterId)); + ASSERT_TRUE(mFilterTests.closeFilter(filterId)); + ASSERT_TRUE(mDemuxTests.closeDemux()); + ASSERT_TRUE(mFrontendTests.closeFrontend()); +} + void TunerBroadcastHidlTest::mediaFilterUsingSharedMemoryTest(FilterConfig filterConf, FrontendConfig frontendConf) { uint32_t feId; @@ -146,6 +179,13 @@ TEST_P(TunerFilterHidlTest, ConfigIpFilterInDemuxWithCid) { configSingleFilterInDemuxTest(filterArray[IP_IP0], frontendArray[DVBT]); } +TEST_P(TunerFilterHidlTest, ReonfigFilterToReceiveStartId) { + description("Recofigure and restart a filter to test start id."); + // TODO use parameterized tests + reconfigSingleFilterInDemuxTest(filterArray[TS_VIDEO0], filterArray[TS_VIDEO1], + frontendArray[DVBT]); +} + TEST_P(TunerRecordHidlTest, RecordDataFlowWithTsRecordFilterTest) { description("Feed ts data from frontend to recording and test with ts record filter"); recordSingleFilterTest(filterArray[TS_RECORD0], frontendArray[DVBT], dvrArray[DVR_RECORD0]); diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h index 773224e882..d14a2e8779 100644 --- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h @@ -58,7 +58,8 @@ class TunerFilterHidlTest : public testing::TestWithParam { } void configSingleFilterInDemuxTest(FilterConfig filterConf, FrontendConfig frontendConf); - + void reconfigSingleFilterInDemuxTest(FilterConfig filterConf, FilterConfig filterReconf, + FrontendConfig frontendConf); sp mService; FrontendTests mFrontendTests; DemuxTests mDemuxTests; -- GitLab From 2272ff8942e50800615c72027e081a86598591d9 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Thu, 12 Nov 2020 09:37:40 -0800 Subject: [PATCH 274/790] wifi(hal): Use debug property to select one of preset HAL iface combination This will be useful for testing/debugging STA + STA & AP + AP feature. Note: I originally planned to read the entire iface combination from the property (i.e would be much more flexible), but that is way too complex and error prone. So, instead pre-define some combinations that we would want to switch between and use the property as an index. Bug: 173044646 Test: Manual: i) adb shell "/vendor/bin/sh -c '/vendor/bin/setprop persist.vendor.debug.wifi.hal.preset_interface_combination_idx 0'" ii) adb reboot iii) Ensure that AP + AP was enabled. Change-Id: Iea63835c39fce78307a056a5ed94efcbd35cdfb6 --- wifi/1.5/default/wifi_feature_flags.cpp | 75 ++++++++++++++++++++++++- wifi/1.5/default/wifi_feature_flags.h | 3 + 2 files changed, 76 insertions(+), 2 deletions(-) diff --git a/wifi/1.5/default/wifi_feature_flags.cpp b/wifi/1.5/default/wifi_feature_flags.cpp index 9f91bd7dc4..124ba32e9f 100644 --- a/wifi/1.5/default/wifi_feature_flags.cpp +++ b/wifi/1.5/default/wifi_feature_flags.cpp @@ -14,6 +14,11 @@ * limitations under the License. */ +#include + +#include +#include + #include "wifi_feature_flags.h" namespace android { @@ -131,7 +136,7 @@ struct ChipIfaceCombination #define AP IfaceType::AP #define P2P IfaceType::P2P #define NAN IfaceType::NAN -static const std::vector kChipModes{ +static const std::vector kChipModesPrimary{ {kMainModeId, ChipIfaceCombination::make_vec({WIFI_HAL_INTERFACE_COMBINATIONS})}, #ifdef WIFI_HAL_INTERFACE_COMBINATIONS_AP @@ -146,6 +151,50 @@ static const std::vector kChipModesSecondary{ {WIFI_HAL_INTERFACE_COMBINATIONS_SECONDARY_CHIP})}, #endif }; + +constexpr char kDebugPresetInterfaceCombinationIdxProperty[] = + "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. +static const std::vector< + std::pair>> + kDebugChipModes{ + // Legacy combination - No STA/AP concurrencies. + // 0 - (1 AP) or (1 STA + 1 of (P2P or NAN)) + {"No STA/AP Concurrency", + {{kMainModeId, + ChipIfaceCombination::make_vec( + {{{{AP}, 1}}, {{{STA}, 1}, {{P2P, NAN}, 1}}})}}}, + + // STA + AP concurrency + // 1 - (1 STA + 1 AP) or (1 STA + 1 of (P2P or NAN)) + {"STA + AP Concurrency", + {{kMainModeId, + ChipIfaceCombination::make_vec( + {{{{STA}, 1}, {{AP}, 1}}, {{{STA}, 1}, {{P2P, NAN}, 1}}})}}}, + + // STA + STA concurrency + // 2 - (1 STA + 1 AP) or (2 STA + 1 of (P2P or NAN)) + {"Dual STA Concurrency", + {{kMainModeId, + ChipIfaceCombination::make_vec( + {{{{STA}, 1}, {{AP}, 1}}, {{{STA}, 2}, {{P2P, NAN}, 1}}})}}}, + + // AP + AP + STA concurrency + // 3 - (1 STA + 2 AP) or (1 STA + 1 of (P2P or NAN)) + {"Dual AP Concurrency", + {{kMainModeId, + ChipIfaceCombination::make_vec( + {{{{STA}, 1}, {{AP}, 2}}, {{{STA}, 1}, {{P2P, NAN}, 1}}})}}}, + + // STA + STA concurrency and AP + AP + STA concurrency + // 4 - (1 STA + 2 AP) or (2 STA + 1 of (P2P or NAN)) + {"Dual STA & Dual AP Concurrency", + {{kMainModeId, + ChipIfaceCombination::make_vec( + {{{{STA}, 1}, {{AP}, 2}}, {{{STA}, 2}, {{P2P, NAN}, 1}}})}}}}; + #undef STA #undef AP #undef P2P @@ -161,9 +210,31 @@ static const std::vector kChipModesSecondary{ WifiFeatureFlags::WifiFeatureFlags() {} +std::vector WifiFeatureFlags::getChipModesForPrimary() { + std::array buffer; + auto res = property_get(kDebugPresetInterfaceCombinationIdxProperty, + buffer.data(), nullptr); + // Debug propety not set, use the device preset interface combination. + if (res <= 0) return kChipModesPrimary; + + // Debug propety set, use one of the debug preset interface combination. + unsigned long idx = std::stoul(buffer.data()); + if (idx >= kDebugChipModes.size()) { + LOG(ERROR) << "Invalid index set in property: " + << kDebugPresetInterfaceCombinationIdxProperty; + return kChipModesPrimary; + } + std::string name; + std::vector chip_modes; + std::tie(name, chip_modes) = kDebugChipModes[idx]; + LOG(INFO) << "Using debug chip mode: <" << name << "> set via property: " + << kDebugPresetInterfaceCombinationIdxProperty; + return chip_modes; +} + std::vector WifiFeatureFlags::getChipModes( bool is_primary) { - return (is_primary) ? kChipModes : kChipModesSecondary; + return (is_primary) ? getChipModesForPrimary() : kChipModesSecondary; } } // namespace feature_flags diff --git a/wifi/1.5/default/wifi_feature_flags.h b/wifi/1.5/default/wifi_feature_flags.h index cb68b8c0c1..7d561fc949 100644 --- a/wifi/1.5/default/wifi_feature_flags.h +++ b/wifi/1.5/default/wifi_feature_flags.h @@ -44,6 +44,9 @@ class WifiFeatureFlags { virtual std::vector getChipModes( bool is_primary); + + private: + std::vector getChipModesForPrimary(); }; } // namespace feature_flags -- GitLab From 72a47a2e5aad0862337e5a951c2ab26813fb96ee Mon Sep 17 00:00:00 2001 From: Enrico Granata Date: Fri, 13 Nov 2020 12:52:07 -0700 Subject: [PATCH 275/790] Allow setting new values for mock speed and bearing in GNSS HAL Bug: None Test: lshal debug android.hardware.gnss@2.1::IGnss/default location bea=30 spd=40 on Cuttlefish instance Change-Id: Ib954ba44720627e54e69aa29b0a744f203a65704 --- gnss/1.1/default/GnssDebug.cpp | 4 ++-- gnss/common/utils/default/MockLocation.cpp | 2 ++ gnss/common/utils/default/Utils.cpp | 4 ++-- gnss/common/utils/default/include/Constants.h | 2 -- .../common/utils/default/include/MockLocation.h | 2 ++ .../utils/default/include/v2_1/GnssTemplate.h | 17 ++++++++++++++--- gnss/common/utils/default/v2_1/GnssDebug.cpp | 4 ++-- 7 files changed, 24 insertions(+), 11 deletions(-) diff --git a/gnss/1.1/default/GnssDebug.cpp b/gnss/1.1/default/GnssDebug.cpp index 252f4e6373..39efcd232b 100644 --- a/gnss/1.1/default/GnssDebug.cpp +++ b/gnss/1.1/default/GnssDebug.cpp @@ -37,8 +37,8 @@ Return GnssDebug::getDebugData(V1_0::IGnssDebug::getDebugData_cb _hidl_cb) .latitudeDegrees = gMockLatitudeDegrees, .longitudeDegrees = gMockLongitudeDegrees, .altitudeMeters = gMockAltitudeMeters, - .speedMetersPerSec = kMockSpeedMetersPerSec, - .bearingDegrees = kMockBearingDegrees, + .speedMetersPerSec = gMockSpeedMetersPerSec, + .bearingDegrees = gMockBearingDegrees, .horizontalAccuracyMeters = kMockHorizontalAccuracyMeters, .verticalAccuracyMeters = kMockVerticalAccuracyMeters, .speedAccuracyMetersPerSecond = kMockSpeedAccuracyMetersPerSecond, diff --git a/gnss/common/utils/default/MockLocation.cpp b/gnss/common/utils/default/MockLocation.cpp index 2d8e7c59ea..c90075fa84 100644 --- a/gnss/common/utils/default/MockLocation.cpp +++ b/gnss/common/utils/default/MockLocation.cpp @@ -21,5 +21,7 @@ namespace android::hardware::gnss::common { float gMockLatitudeDegrees{37.4219999}; float gMockLongitudeDegrees{-122.0840575}; float gMockAltitudeMeters{1.60062531}; +float gMockBearingDegrees{0}; +float gMockSpeedMetersPerSec{0}; } // namespace android::hardware::gnss::common diff --git a/gnss/common/utils/default/Utils.cpp b/gnss/common/utils/default/Utils.cpp index fa83634024..d336f1bd5b 100644 --- a/gnss/common/utils/default/Utils.cpp +++ b/gnss/common/utils/default/Utils.cpp @@ -145,8 +145,8 @@ V1_0::GnssLocation Utils::getMockLocationV1_0() { .latitudeDegrees = gMockLatitudeDegrees, .longitudeDegrees = gMockLongitudeDegrees, .altitudeMeters = gMockAltitudeMeters, - .speedMetersPerSec = kMockSpeedMetersPerSec, - .bearingDegrees = kMockBearingDegrees, + .speedMetersPerSec = gMockSpeedMetersPerSec, + .bearingDegrees = gMockBearingDegrees, .horizontalAccuracyMeters = kMockHorizontalAccuracyMeters, .verticalAccuracyMeters = kMockVerticalAccuracyMeters, .speedAccuracyMetersPerSecond = kMockSpeedAccuracyMetersPerSecond, diff --git a/gnss/common/utils/default/include/Constants.h b/gnss/common/utils/default/include/Constants.h index ad4e0eb9e9..a290ed243f 100644 --- a/gnss/common/utils/default/include/Constants.h +++ b/gnss/common/utils/default/include/Constants.h @@ -24,8 +24,6 @@ namespace hardware { namespace gnss { namespace common { -const float kMockSpeedMetersPerSec = 0; -const float kMockBearingDegrees = 0; const float kMockHorizontalAccuracyMeters = 5; const float kMockVerticalAccuracyMeters = 5; const float kMockSpeedAccuracyMetersPerSecond = 1; diff --git a/gnss/common/utils/default/include/MockLocation.h b/gnss/common/utils/default/include/MockLocation.h index cd8cb5dad1..0bfdd1a32e 100644 --- a/gnss/common/utils/default/include/MockLocation.h +++ b/gnss/common/utils/default/include/MockLocation.h @@ -27,6 +27,8 @@ namespace common { extern float gMockLatitudeDegrees; extern float gMockLongitudeDegrees; extern float gMockAltitudeMeters; +extern float gMockBearingDegrees; +extern float gMockSpeedMetersPerSec; } // namespace common } // namespace gnss diff --git a/gnss/common/utils/default/include/v2_1/GnssTemplate.h b/gnss/common/utils/default/include/v2_1/GnssTemplate.h index cbf3933b7f..4d1baa713a 100644 --- a/gnss/common/utils/default/include/v2_1/GnssTemplate.h +++ b/gnss/common/utils/default/include/v2_1/GnssTemplate.h @@ -651,6 +651,8 @@ Return GnssTemplate::setLocation(const hidl_handle& fd, auto lat = gMockLatitudeDegrees; auto lon = gMockLongitudeDegrees; auto ele = gMockAltitudeMeters; + auto bea = gMockBearingDegrees; + auto spd = gMockSpeedMetersPerSec; for (size_t i = 1; i < options.size(); ++i) { std::string option = options[i]; @@ -663,6 +665,12 @@ Return GnssTemplate::setLocation(const hidl_handle& fd, } else if (option.rfind("ele=", 0) == 0) { option = option.substr(4); ele = stof(option); + } else if (option.rfind("bea=", 0) == 0) { + option = option.substr(4); + bea = stof(option); + } else if (option.rfind("spd=", 0) == 0) { + option = option.substr(4); + spd = stof(option); } else { dprintf(fd->data[0], "unsupported location argument: %s\n", option.c_str()); } @@ -671,9 +679,12 @@ Return GnssTemplate::setLocation(const hidl_handle& fd, gMockLatitudeDegrees = lat; gMockLongitudeDegrees = lon; gMockAltitudeMeters = ele; + gMockBearingDegrees = bea; + gMockSpeedMetersPerSec = spd; - dprintf(fd->data[0], "mock location updated to lat=%f lon=%f ele=%f\n", gMockLatitudeDegrees, - gMockLongitudeDegrees, gMockAltitudeMeters); + dprintf(fd->data[0], "mock location updated to lat=%f lon=%f ele=%f bea=%f spd=%f\n", + gMockLatitudeDegrees, gMockLongitudeDegrees, gMockAltitudeMeters, gMockBearingDegrees, + gMockSpeedMetersPerSec); return Void(); } @@ -682,7 +693,7 @@ template Return GnssTemplate::help(const hidl_handle& fd) { dprintf(fd->data[0], "invalid option for Gnss HAL; valid options are:\n" - "location lat=.. lon=.. ele=..\n"); + "location [lat=..] [lon=..] [ele=..] [bea=..] [spd=..]\n"); return Void(); } diff --git a/gnss/common/utils/default/v2_1/GnssDebug.cpp b/gnss/common/utils/default/v2_1/GnssDebug.cpp index d78b0b6ddc..537a90c7b0 100644 --- a/gnss/common/utils/default/v2_1/GnssDebug.cpp +++ b/gnss/common/utils/default/v2_1/GnssDebug.cpp @@ -33,8 +33,8 @@ Return GnssDebug::getDebugData(V1_0::IGnssDebug::getDebugData_cb _hidl_cb) .latitudeDegrees = gMockLatitudeDegrees, .longitudeDegrees = gMockLongitudeDegrees, .altitudeMeters = gMockAltitudeMeters, - .speedMetersPerSec = kMockSpeedMetersPerSec, - .bearingDegrees = kMockBearingDegrees, + .speedMetersPerSec = gMockSpeedMetersPerSec, + .bearingDegrees = gMockBearingDegrees, .horizontalAccuracyMeters = kMockHorizontalAccuracyMeters, .verticalAccuracyMeters = kMockVerticalAccuracyMeters, .speedAccuracyMetersPerSecond = kMockSpeedAccuracyMetersPerSecond, -- GitLab From b6064e59c7ba4dcc864eeb62f7e0d03fc815aa5f Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Wed, 11 Nov 2020 21:47:40 -0800 Subject: [PATCH 276/790] Add monitor for ip cid change Previously we added scrambling status monitoring. Now we are merging the configuration of these two monitoring into one. They are going through the same interface by configuring Filter Event Monitoring Type. Test: atest VtsHalTvTunerV1_1TargetTest Bug: 153595125 Change-Id: I5fcd0d4dff55453023a730caa36995f13f074a8f --- tv/tuner/1.1/IFilter.hal | 24 ++++---- tv/tuner/1.1/default/Filter.cpp | 56 +++++++++++++------ tv/tuner/1.1/default/Filter.h | 4 +- tv/tuner/1.1/types.hal | 44 ++++++++++++++- tv/tuner/1.1/vts/functional/FilterTests.cpp | 30 ++++++++-- tv/tuner/1.1/vts/functional/FilterTests.h | 5 +- .../VtsHalTvTunerV1_1TargetTest.cpp | 4 +- .../VtsHalTvTunerV1_1TestConfigurations.h | 6 +- 8 files changed, 134 insertions(+), 39 deletions(-) diff --git a/tv/tuner/1.1/IFilter.hal b/tv/tuner/1.1/IFilter.hal index 1c6c33fe2b..1e941143df 100644 --- a/tv/tuner/1.1/IFilter.hal +++ b/tv/tuner/1.1/IFilter.hal @@ -85,19 +85,23 @@ interface IFilter extends @1.0::IFilter { configureAvStreamType(AvStreamType avStreamType) generates (Result result); /** - * Configure the filter to monitor specific Scrambling Status. + * Configure the monitor event. * - * Scrambling Status should be sent through the filer callback at the following two scenarios: + * The event for Scrambling Status should be sent at the following two scenarios: * 1. When this method is called, the first detected scrambling status should be sent. - * 2. When the filter transits into the monitored statuses configured through this method, - * event should be sent. + * 2. When the Scrambling status transits into different status, event should be sent. * - * @param statuses Scrambling Statuses to monitor. Set corresponding bit to monitor. Reset to - * stop monitoring. + * The event for IP CID change should be sent at the following two scenarios: + * 1. When this method is called, the first detected CID for the IP should be sent. + * 2. When the CID is changed to different value for the IP filter, event should be sent. + * + * @param monitorEventypes the events to monitor. Set corresponding bit of the event to monitor. + * Reset to stop monitoring. * @return result Result status of the operation. - * SUCCESS if successful, - * INVALID_STATE if configure can't be applied, - * UNKNOWN_ERROR if failed for other reasons. + * SUCCESS if successful, + * INVALID_STATE if configure can't be applied, + * UNKNOWN_ERROR if failed for other reasons. */ - configureScramblingEvent(bitfield statuses) generates (Result result); + configureMonitorEvent(bitfield monitorEventTypes) + generates (Result result); }; diff --git a/tv/tuner/1.1/default/Filter.cpp b/tv/tuner/1.1/default/Filter.cpp index e766a8af72..4fa1746dbe 100644 --- a/tv/tuner/1.1/default/Filter.cpp +++ b/tv/tuner/1.1/default/Filter.cpp @@ -250,25 +250,49 @@ Return Filter::configureAvStreamType(const V1_1::AvStreamType& avStreamT return Result::SUCCESS; } -Return Filter::configureScramblingEvent(uint32_t statuses) { +Return Filter::configureMonitorEvent(uint32_t monitorEventTypes) { ALOGV("%s", __FUNCTION__); - mStatuses = statuses; - if (mCallback_1_1 != nullptr) { - // Assuming current status is always NOT_SCRAMBLED - V1_1::DemuxFilterEventExt filterEventExt; - V1_1::DemuxFilterEventExt::Event event; - event.scramblingStatus(V1_1::ScramblingStatus::NOT_SCRAMBLED); - int size = filterEventExt.events.size(); - filterEventExt.events.resize(size + 1); - filterEventExt.events[size] = event; - DemuxFilterEvent emptyFilterEvent; - - mCallback_1_1->onFilterEvent_1_1(emptyFilterEvent, filterEventExt); - mFilterEventExt.events.resize(0); - } else { - return Result::INVALID_STATE; + DemuxFilterEvent emptyFilterEvent; + V1_1::DemuxFilterMonitorEvent monitorEvent; + V1_1::DemuxFilterEventExt eventExt; + + uint32_t newScramblingStatus = + monitorEventTypes & V1_1::DemuxFilterMonitorEventType::SCRAMBLING_STATUS; + uint32_t newIpCid = monitorEventTypes & V1_1::DemuxFilterMonitorEventType::IP_CID_CHANGE; + + // if scrambling status monitoring flipped, record the new state and send msg on enabling + if (newScramblingStatus ^ mScramblingStatusMonitored) { + mScramblingStatusMonitored = newScramblingStatus; + if (mScramblingStatusMonitored) { + if (mCallback_1_1 != nullptr) { + // Assuming current status is always NOT_SCRAMBLED + monitorEvent.scramblingStatus(V1_1::ScramblingStatus::NOT_SCRAMBLED); + eventExt.events.resize(1); + eventExt.events[0].monitorEvent(monitorEvent); + mCallback_1_1->onFilterEvent_1_1(emptyFilterEvent, eventExt); + } else { + return Result::INVALID_STATE; + } + } } + + // if ip cid monitoring flipped, record the new state and send msg on enabling + if (newIpCid ^ mIpCidMonitored) { + mIpCidMonitored = newIpCid; + if (mIpCidMonitored) { + if (mCallback_1_1 != nullptr) { + // Return random cid + monitorEvent.cid(1); + eventExt.events.resize(1); + eventExt.events[0].monitorEvent(monitorEvent); + mCallback_1_1->onFilterEvent_1_1(emptyFilterEvent, eventExt); + } else { + return Result::INVALID_STATE; + } + } + } + return Result::SUCCESS; } diff --git a/tv/tuner/1.1/default/Filter.h b/tv/tuner/1.1/default/Filter.h index 1ebc1351a0..3a4246e095 100644 --- a/tv/tuner/1.1/default/Filter.h +++ b/tv/tuner/1.1/default/Filter.h @@ -84,7 +84,7 @@ class Filter : public V1_1::IFilter { virtual Return configureAvStreamType(const V1_1::AvStreamType& avStreamType) override; - virtual Return configureScramblingEvent(uint32_t statuses) override; + virtual Return configureMonitorEvent(uint32_t monitorEventTypes) override; /** * To create a FilterMQ and its Event Flag. @@ -238,6 +238,8 @@ class Filter : public V1_1::IFilter { bool mConfigured = false; int mStartId = 0; + uint8_t mScramblingStatusMonitored = 0; + uint8_t mIpCidMonitored = 0; }; } // namespace implementation diff --git a/tv/tuner/1.1/types.hal b/tv/tuner/1.1/types.hal index 09b87f2ac8..938cb6e493 100644 --- a/tv/tuner/1.1/types.hal +++ b/tv/tuner/1.1/types.hal @@ -151,22 +151,42 @@ struct DemuxFilterMmtpRecordEventExt { struct DemuxFilterEventExt { safe_union Event { /** - * No extended record filter Event. This is used by the tsRecord or mmtpRecord filter event - * that does not contain the DemuxFilterTs/MmtpRecordEventExt information. + * No extended filter Event. */ Monostate noinit; + /** + * Extended TS Record event sent along with @1.0::DemuxFilterEvent::Event::tsRecord. + * DemuxFilterEventExt.events[i] is corresponding to @1.0::DemuxFilterEvent.events[i]. If + * @1.0::DemuxFilterEvent.events[i] does not have extended event, + * DemuxFilterEventExt.events[i] should use Monostate. + */ DemuxFilterTsRecordEventExt tsRecord; + /** + * Extended MMTP Record event sent along with @1.0::DemuxFilterEvent::Event::mmtpRecord. + * DemuxFilterEventExt.events[i] is corresponding to @1.0::DemuxFilterEvent.events[i]. If + * @1.0::DemuxFilterEvent.events[i] does not have extended event, + * DemuxFilterEventExt.events[i] should use Monostate. + */ DemuxFilterMmtpRecordEventExt mmtpRecord; - ScramblingStatus scramblingStatus; + /** + * Monitor event to notify monitored status change. + * + * When sending monitorEvent, DemuxFilterEventExt.events should only contain one + * monitorEvent. MonitorEvent should be sent with an empty @1.0::DemuxFilterEvent. + */ + DemuxFilterMonitorEvent monitorEvent; /** * An unique ID to mark the start point of receiving the valid filter events after * reconfiguring the filter. It must be sent at least once in the first event after the * filter is restarted. 0 is reserved for the newly opened filter's first start, which is * optional for HAL to send. + * + * When sending starId, DemuxFilterEventExt.events should only contain one startId event. + * StardId event should be sent with an empty @1.0::DemuxFilterEvent. */ uint32_t startId; }; @@ -196,6 +216,24 @@ enum ScramblingStatus : uint32_t { SCRAMBLED = 1 << 2, }; +@export +enum DemuxFilterMonitorEventType : uint32_t { + SCRAMBLING_STATUS = 1 << 0, + IP_CID_CHANGE = 1 << 1, +}; + +safe_union DemuxFilterMonitorEvent { + /** + * New scrambling status. + */ + ScramblingStatus scramblingStatus; + + /** + * New cid for the IP filter. + */ + uint32_t cid; +}; + typedef FrontendDvbcSpectralInversion FrontendSpectralInversion; /** diff --git a/tv/tuner/1.1/vts/functional/FilterTests.cpp b/tv/tuner/1.1/vts/functional/FilterTests.cpp index cdf3b6998b..d8fad3d5d2 100644 --- a/tv/tuner/1.1/vts/functional/FilterTests.cpp +++ b/tv/tuner/1.1/vts/functional/FilterTests.cpp @@ -40,6 +40,18 @@ void FilterCallback::testFilterScramblingEvent() { ALOGW("[vts] pass and stop"); } +void FilterCallback::testFilterIpCidEvent() { + android::Mutex::Autolock autoLock(mMsgLock); + while (mIpCidEvent < 1) { + if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) { + EXPECT_TRUE(false) << "ip cid change event does not output within timeout"; + return; + } + } + mIpCidEvent = 0; + ALOGW("[vts] pass and stop"); +} + void FilterCallback::testStartIdAfterReconfigure() { android::Mutex::Autolock autoLock(mMsgLock); while (!mStartIdReceived) { @@ -80,8 +92,17 @@ void FilterCallback::readFilterEventData() { eventExt.mmtpRecord().pts, eventExt.mmtpRecord().firstMbInSlice, eventExt.mmtpRecord().mpuSequenceNumber, eventExt.mmtpRecord().tsIndexMask); break; - case DemuxFilterEventExt::Event::hidl_discriminator::scramblingStatus: - mScramblingStatusEvent++; + case DemuxFilterEventExt::Event::hidl_discriminator::monitorEvent: + switch (eventExt.monitorEvent().getDiscriminator()) { + case DemuxFilterMonitorEvent::hidl_discriminator::scramblingStatus: + mScramblingStatusEvent++; + break; + case DemuxFilterMonitorEvent::hidl_discriminator::cid: + mIpCidEvent++; + break; + default: + break; + } break; case DemuxFilterEventExt::Event::hidl_discriminator::startId: ALOGD("[vts] Extended restart filter event, startId=%d", eventExt.startId()); @@ -272,15 +293,16 @@ AssertionResult FilterTests::closeFilter(uint64_t filterId) { return AssertionResult(status == Result::SUCCESS); } -AssertionResult FilterTests::configureScramblingEvent(uint64_t filterId, uint32_t statuses) { +AssertionResult FilterTests::configureMonitorEvent(uint64_t filterId, uint32_t monitorEventTypes) { EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first."; Result status; sp filter_v1_1 = android::hardware::tv::tuner::V1_1::IFilter::castFrom(mFilters[filterId]); if (filter_v1_1 != NULL) { - status = filter_v1_1->configureScramblingEvent(statuses); + status = filter_v1_1->configureMonitorEvent(monitorEventTypes); mFilterCallbacks[filterId]->testFilterScramblingEvent(); + mFilterCallbacks[filterId]->testFilterIpCidEvent(); } else { ALOGW("[vts] Can't cast IFilter into v1_1."); return failure(); diff --git a/tv/tuner/1.1/vts/functional/FilterTests.h b/tv/tuner/1.1/vts/functional/FilterTests.h index ae57659a38..6749265661 100644 --- a/tv/tuner/1.1/vts/functional/FilterTests.h +++ b/tv/tuner/1.1/vts/functional/FilterTests.h @@ -56,6 +56,7 @@ using android::hardware::tv::tuner::V1_0::IFilter; using android::hardware::tv::tuner::V1_0::Result; using android::hardware::tv::tuner::V1_1::AvStreamType; using android::hardware::tv::tuner::V1_1::DemuxFilterEventExt; +using android::hardware::tv::tuner::V1_1::DemuxFilterMonitorEvent; using android::hardware::tv::tuner::V1_1::IFilterCallback; using android::hardware::tv::tuner::V1_1::ITuner; @@ -118,6 +119,7 @@ class FilterCallback : public IFilterCallback { void testFilterDataOutput(); void testFilterScramblingEvent(); + void testFilterIpCidEvent(); void testStartIdAfterReconfigure(); void readFilterEventData(); @@ -139,6 +141,7 @@ class FilterCallback : public IFilterCallback { int mPidFilterOutputCount = 0; int mScramblingStatusEvent = 0; + int mIpCidEvent = 0; bool mStartIdReceived = false; }; @@ -157,7 +160,7 @@ class FilterTests { AssertionResult configFilter(DemuxFilterSettings setting, uint64_t filterId); AssertionResult configAvFilterStreamType(AvStreamType type, uint64_t filterId); AssertionResult configIpFilterCid(uint32_t ipCid, uint64_t filterId); - AssertionResult configureScramblingEvent(uint64_t filterId, uint32_t statuses); + AssertionResult configureMonitorEvent(uint64_t filterId, uint32_t monitorEventTypes); AssertionResult getFilterMQDescriptor(uint64_t filterId); AssertionResult startFilter(uint64_t filterId); AssertionResult stopFilter(uint64_t filterId); diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp index dda8b60087..e87276275a 100644 --- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp @@ -46,8 +46,8 @@ void TunerFilterHidlTest::configSingleFilterInDemuxTest(FilterConfig filterConf, if (filterConf.type.mainType == DemuxFilterMainType::IP) { ASSERT_TRUE(mFilterTests.configIpFilterCid(filterConf.ipCid, filterId)); } - if (filterConf.statuses > 0) { - ASSERT_TRUE(mFilterTests.configureScramblingEvent(filterId, filterConf.statuses)); + if (filterConf.monitorEventTypes > 0) { + ASSERT_TRUE(mFilterTests.configureMonitorEvent(filterId, filterConf.monitorEventTypes)); } ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId)); ASSERT_TRUE(mFilterTests.startFilter(filterId)); diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h index 76bf765909..beae223e4b 100644 --- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h @@ -96,7 +96,7 @@ struct FilterConfig { DemuxFilterSettings settings; AvStreamType streamType; uint32_t ipCid; - uint32_t statuses; + uint32_t monitorEventTypes; bool operator<(const FilterConfig& /*c*/) const { return false; } }; @@ -188,7 +188,9 @@ inline void initFilterConfig() { filterArray[TS_VIDEO0].bufferSize = FMQ_SIZE_16M; filterArray[TS_VIDEO0].settings.ts().tpid = 256; filterArray[TS_VIDEO0].settings.ts().filterSettings.av({.isPassthrough = false}); - filterArray[TS_VIDEO0].statuses = 1; + filterArray[TS_VIDEO0].monitorEventTypes = + android::hardware::tv::tuner::V1_1::DemuxFilterMonitorEventType::SCRAMBLING_STATUS | + android::hardware::tv::tuner::V1_1::DemuxFilterMonitorEventType::IP_CID_CHANGE; filterArray[TS_VIDEO1].type.mainType = DemuxFilterMainType::TS; filterArray[TS_VIDEO1].type.subType.tsFilterType(DemuxTsFilterType::VIDEO); filterArray[TS_VIDEO1].bufferSize = FMQ_SIZE_16M; -- GitLab From 2475361d52d831e1ef9306d9b8d827e325eadb32 Mon Sep 17 00:00:00 2001 From: Yu-Han Yang Date: Tue, 27 Oct 2020 14:42:14 -0700 Subject: [PATCH 277/790] Add IGnssPowerIndication AIDL HAL (hardware/interfaces) Bug: 168123084 Bug: 171821213 Bug: 172893736 Test: on Cuttlefish Change-Id: Ia9fd1981a6f93b2cad168bd52dae8d7b8ede0282 --- .../hardware/gnss/ElapsedRealtime.aidl | 24 +++++++ .../android/hardware/gnss/GnssPowerStats.aidl | 28 ++++++++ .../current/android/hardware/gnss/IGnss.aidl | 3 + .../hardware/gnss/IGnssPowerIndication.aidl | 23 +++++++ .../gnss/IGnssPowerIndicationCallback.aidl | 29 ++++++++ .../hardware/gnss/ElapsedRealtime.aidl | 45 +++++++++++++ .../android/hardware/gnss/GnssPowerStats.aidl | 66 +++++++++++++++++++ gnss/aidl/android/hardware/gnss/IGnss.aidl | 18 ++++- .../hardware/gnss/IGnssPowerIndication.aidl | 39 +++++++++++ .../gnss/IGnssPowerIndicationCallback.aidl | 63 ++++++++++++++++++ gnss/aidl/default/Android.bp | 1 + gnss/aidl/default/Gnss.cpp | 9 +++ gnss/aidl/default/Gnss.h | 3 + gnss/aidl/default/GnssPowerIndication.cpp | 62 +++++++++++++++++ gnss/aidl/default/GnssPowerIndication.h | 37 +++++++++++ gnss/aidl/vts/Android.bp | 1 + gnss/aidl/vts/GnssPowerIndicationCallback.cpp | 47 +++++++++++++ gnss/aidl/vts/GnssPowerIndicationCallback.h | 44 +++++++++++++ gnss/aidl/vts/gnss_hal_test_cases.cpp | 33 +++++++++- 19 files changed, 573 insertions(+), 2 deletions(-) create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/ElapsedRealtime.aidl create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssPowerStats.aidl create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndication.aidl create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndicationCallback.aidl create mode 100644 gnss/aidl/android/hardware/gnss/ElapsedRealtime.aidl create mode 100644 gnss/aidl/android/hardware/gnss/GnssPowerStats.aidl create mode 100644 gnss/aidl/android/hardware/gnss/IGnssPowerIndication.aidl create mode 100644 gnss/aidl/android/hardware/gnss/IGnssPowerIndicationCallback.aidl create mode 100644 gnss/aidl/default/GnssPowerIndication.cpp create mode 100644 gnss/aidl/default/GnssPowerIndication.h create mode 100644 gnss/aidl/vts/GnssPowerIndicationCallback.cpp create mode 100644 gnss/aidl/vts/GnssPowerIndicationCallback.h diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/ElapsedRealtime.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/ElapsedRealtime.aidl new file mode 100644 index 0000000000..354c953d77 --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/ElapsedRealtime.aidl @@ -0,0 +1,24 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.gnss; +@VintfStability +parcelable ElapsedRealtime { + int flags; + long timestampNs; + double timeUncertaintyNs; +} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssPowerStats.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssPowerStats.aidl new file mode 100644 index 0000000000..d385fd488c --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssPowerStats.aidl @@ -0,0 +1,28 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.gnss; +@VintfStability +parcelable GnssPowerStats { + android.hardware.gnss.ElapsedRealtime elapsedRealtime; + double totalEnergyMilliJoule; + double singlebandTrackingModeEnergyMilliJoule; + double multibandTrackingModeEnergyMilliJoule; + double singlebandAcquisitionModeEnergyMilliJoule; + double multibandAcquisitionModeEnergyMilliJoule; + double[] otherModesEnergyMilliJoule; +} 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 146577ef90..e1a4b9e99c 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 @@ -22,5 +22,8 @@ interface IGnss { void close(); android.hardware.gnss.IGnssPsds getExtensionPsds(); android.hardware.gnss.IGnssConfiguration getExtensionGnssConfiguration(); + android.hardware.gnss.IGnssPowerIndication getExtensionGnssPowerIndication(); const int ERROR_INVALID_ARGUMENT = 1; + const int ELAPSED_REALTIME_HAS_TIMESTAMP_NS = 1; + const int ELAPSED_REALTIME_HAS_TIME_UNCERTAINTY_NS = 2; } diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndication.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndication.aidl new file mode 100644 index 0000000000..843489e941 --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndication.aidl @@ -0,0 +1,23 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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 IGnssPowerIndication { + void setCallback(in android.hardware.gnss.IGnssPowerIndicationCallback callback); + oneway void requestGnssPowerStats(); +} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndicationCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndicationCallback.aidl new file mode 100644 index 0000000000..5281d29bc6 --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndicationCallback.aidl @@ -0,0 +1,29 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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 IGnssPowerIndicationCallback { + void setCapabilitiesCb(in int capabilities); + oneway void gnssPowerStatsCb(in android.hardware.gnss.GnssPowerStats gnssPowerStats); + const int CAPABILITY_TOTAL = 1; + const int CAPABILITY_SINGLEBAND_TRACKING = 2; + const int CAPABILITY_MULTIBAND_TRACKING = 4; + const int CAPABILITY_SINGLEBAND_ACQUISITION = 8; + const int CAPABILITY_MULTIBAND_ACQUISITION = 16; + const int CAPABILITY_OTHER_MODES = 32; +} diff --git a/gnss/aidl/android/hardware/gnss/ElapsedRealtime.aidl b/gnss/aidl/android/hardware/gnss/ElapsedRealtime.aidl new file mode 100644 index 0000000000..fae14f87a3 --- /dev/null +++ b/gnss/aidl/android/hardware/gnss/ElapsedRealtime.aidl @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.gnss; + +/** + * Cumulative GNSS power statistics since boot. + */ +@VintfStability +parcelable ElapsedRealtime { + + /** + * A bit field of flags indicating the validity of each field in this data structure. + * + * The bit masks are defined in IGnss interface and prefixed with ELAPSED_REALTIME_HAS_. + * + * Fields may have invalid information in them, if not marked as valid by the corresponding bit + * in flags. + */ + int flags; + + /** + * Estimate of the elapsed time since boot value for the corresponding event in nanoseconds. + */ + long timestampNs; + + /** + * Estimate of the relative precision of the alignment of this SystemClock timestamp, with the + * reported measurements in nanoseconds (68% confidence). + */ + double timeUncertaintyNs; +} \ No newline at end of file diff --git a/gnss/aidl/android/hardware/gnss/GnssPowerStats.aidl b/gnss/aidl/android/hardware/gnss/GnssPowerStats.aidl new file mode 100644 index 0000000000..2bea44dbb9 --- /dev/null +++ b/gnss/aidl/android/hardware/gnss/GnssPowerStats.aidl @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.gnss; + +import android.hardware.gnss.ElapsedRealtime; + +/** + * Cumulative GNSS power statistics since boot. + */ +@VintfStability +parcelable GnssPowerStats { + /** + * Timing information of the GnssPowerStats synchronized with SystemClock.elapsedRealtimeNanos() + * clock. + */ + ElapsedRealtime elapsedRealtime; + + /** + * Total GNSS energy consumption in milli-joules (mWatt-seconds). + */ + double totalEnergyMilliJoule; + + /** + * Total energy consumption in milli-joules (mWatt-seconds) for which the GNSS engine is + * tracking signals of a single frequency band. + */ + double singlebandTrackingModeEnergyMilliJoule; + + /** + * Total energy consumption in milli-joules (mWatt-seconds) for which the GNSS engine is + * tracking signals of multiple frequency bands. + */ + double multibandTrackingModeEnergyMilliJoule; + + /** + * Total energy consumption in milli-joules (mWatt-seconds) for which the GNSS engine is + * acquiring signals of a single frequency band. + */ + double singlebandAcquisitionModeEnergyMilliJoule; + + /** + * Total energy consumption in milli-joules (mWatt-seconds) for which the GNSS engine is + * acquiring signals of multiple frequency bands. + */ + double multibandAcquisitionModeEnergyMilliJoule; + + /** + * Total energy consumption in milli-joules (mWatt-seconds) for which the GNSS engine is + * operating in each of the vendor-specific power modes. + */ + double[] otherModesEnergyMilliJoule; +} \ No newline at end of file diff --git a/gnss/aidl/android/hardware/gnss/IGnss.aidl b/gnss/aidl/android/hardware/gnss/IGnss.aidl index 24632aa8d6..2af57b5aab 100644 --- a/gnss/aidl/android/hardware/gnss/IGnss.aidl +++ b/gnss/aidl/android/hardware/gnss/IGnss.aidl @@ -17,6 +17,7 @@ package android.hardware.gnss; import android.hardware.gnss.IGnssCallback; +import android.hardware.gnss.IGnssPowerIndication; import android.hardware.gnss.IGnssPsds; import android.hardware.gnss.IGnssConfiguration; @@ -32,6 +33,14 @@ interface IGnss { */ const int ERROR_INVALID_ARGUMENT = 1; + /** Bit mask indicating a valid timestampNs is stored in the ElapsedRealtime parcelable. */ + const int ELAPSED_REALTIME_HAS_TIMESTAMP_NS = 1 << 0; + + /** + * Bit mask indicating a valid timeUncertaintyNs is stored in the ElapsedRealtime parcelable. + */ + const int ELAPSED_REALTIME_HAS_TIME_UNCERTAINTY_NS = 1 << 1; + /** * Opens the interface and provides the callback routines to the implementation of this * interface. @@ -75,4 +84,11 @@ interface IGnss { * @return Handle to the IGnssConfiguration interface. */ IGnssConfiguration getExtensionGnssConfiguration(); -} \ No newline at end of file + + /** + * This method returns the IGnssPowerIndication interface. + * + * @return Handle to the IGnssPowerIndication interface. + */ + IGnssPowerIndication getExtensionGnssPowerIndication(); +} diff --git a/gnss/aidl/android/hardware/gnss/IGnssPowerIndication.aidl b/gnss/aidl/android/hardware/gnss/IGnssPowerIndication.aidl new file mode 100644 index 0000000000..93fdadc886 --- /dev/null +++ b/gnss/aidl/android/hardware/gnss/IGnssPowerIndication.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.gnss; + +import android.hardware.gnss.IGnssPowerIndicationCallback; + +/** + * Extended interface for GNSS Power Indication support. + */ +@VintfStability +interface IGnssPowerIndication { + + /** + * Opens the IGnssPowerIndication interface and provides the callback routines to the HAL. + * + * @param callback Callback interface for IGnssPowerIndication. + */ + void setCallback(in IGnssPowerIndicationCallback callback); + + /** + * Requests the GNSS power statistics. One request call corresponds to one response callback + * from IGnssPowerIndicationCallback.gnssPowerStatsCb(). + */ + oneway void requestGnssPowerStats(); +} \ No newline at end of file diff --git a/gnss/aidl/android/hardware/gnss/IGnssPowerIndicationCallback.aidl b/gnss/aidl/android/hardware/gnss/IGnssPowerIndicationCallback.aidl new file mode 100644 index 0000000000..4474c0c69c --- /dev/null +++ b/gnss/aidl/android/hardware/gnss/IGnssPowerIndicationCallback.aidl @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.gnss; + +import android.hardware.gnss.GnssPowerStats; + +/** + * The callback interface to report GNSS Power Indication from the HAL. + */ +@VintfStability +interface IGnssPowerIndicationCallback { + + /** Capability bit mask indicating GNSS supports totalEnergyMilliJoule. */ + const int CAPABILITY_TOTAL = 1 << 0; + + /** Capability bit mask indicating GNSS supports singlebandTrackingModeEnergyMilliJoule. */ + const int CAPABILITY_SINGLEBAND_TRACKING = 1 << 1; + + /** Capability bit mask indicating GNSS supports multibandTrackingModeEnergyMilliJoule. */ + const int CAPABILITY_MULTIBAND_TRACKING = 1 << 2; + + /** Capability bit mask indicating GNSS supports singlebandAcquisitionModeEnergyMilliJoule. */ + const int CAPABILITY_SINGLEBAND_ACQUISITION = 1 << 3; + + /** Capability bit mask indicating GNSS supports multibandAcquisitionModeEnergyMilliJoule. */ + const int CAPABILITY_MULTIBAND_ACQUISITION = 1 << 4; + + /** Capability bit mask indicating GNSS supports otherModesEnergyMilliJoule. */ + const int CAPABILITY_OTHER_MODES = 1 << 5; + + /** + * Callback to inform framework the Power Indication specific capabilities of the GNSS HAL + * implementation. + * + * The GNSS HAL must call this method immediately after the framework opens the + * IGnssPowerIndication interface. + * + * @param capabilities Bitmask of CAPABILITY_* specifying the supported GNSS Power Indication + * capabilities. + */ + void setCapabilitiesCb(in int capabilities); + + /** + * Callback for the HAL to pass a GnssPowerStats structure back to the client. + * + * @param gnssPowerStats GNSS power statistics since boot. + */ + oneway void gnssPowerStatsCb(in GnssPowerStats gnssPowerStats); +} \ No newline at end of file diff --git a/gnss/aidl/default/Android.bp b/gnss/aidl/default/Android.bp index 1fe43c37a4..23677ed4cc 100644 --- a/gnss/aidl/default/Android.bp +++ b/gnss/aidl/default/Android.bp @@ -47,6 +47,7 @@ cc_binary { srcs: [ "Gnss.cpp", "GnssHidlHal.cpp", + "GnssPowerIndication.cpp", "GnssPsds.cpp", "GnssConfiguration.cpp", "service.cpp", diff --git a/gnss/aidl/default/Gnss.cpp b/gnss/aidl/default/Gnss.cpp index b4d92fd62f..669372b374 100644 --- a/gnss/aidl/default/Gnss.cpp +++ b/gnss/aidl/default/Gnss.cpp @@ -19,6 +19,7 @@ #include "Gnss.h" #include #include "GnssConfiguration.h" +#include "GnssPowerIndication.h" #include "GnssPsds.h" namespace aidl::android::hardware::gnss { @@ -65,4 +66,12 @@ ndk::ScopedAStatus Gnss::getExtensionGnssConfiguration( return ndk::ScopedAStatus::ok(); } +ndk::ScopedAStatus Gnss::getExtensionGnssPowerIndication( + std::shared_ptr* iGnssPowerIndication) { + ALOGD("Gnss::getExtensionGnssPowerIndication"); + + *iGnssPowerIndication = SharedRefBase::make(); + return ndk::ScopedAStatus::ok(); +} + } // namespace aidl::android::hardware::gnss diff --git a/gnss/aidl/default/Gnss.h b/gnss/aidl/default/Gnss.h index 61d7cf752b..9f6ef0e32f 100644 --- a/gnss/aidl/default/Gnss.h +++ b/gnss/aidl/default/Gnss.h @@ -18,6 +18,7 @@ #include #include +#include #include #include "GnssConfiguration.h" @@ -30,6 +31,8 @@ class Gnss : public BnGnss { ndk::ScopedAStatus getExtensionPsds(std::shared_ptr* iGnssPsds) override; ndk::ScopedAStatus getExtensionGnssConfiguration( std::shared_ptr* iGnssConfiguration) override; + ndk::ScopedAStatus getExtensionGnssPowerIndication( + std::shared_ptr* iGnssPowerIndication) override; std::shared_ptr mGnssConfiguration; diff --git a/gnss/aidl/default/GnssPowerIndication.cpp b/gnss/aidl/default/GnssPowerIndication.cpp new file mode 100644 index 0000000000..8ea60f360a --- /dev/null +++ b/gnss/aidl/default/GnssPowerIndication.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "GnssPowerIndicationAidl" + +#include "GnssPowerIndication.h" +#include +#include + +namespace aidl::android::hardware::gnss { + +std::shared_ptr GnssPowerIndication::sCallback = nullptr; + +ndk::ScopedAStatus GnssPowerIndication::setCallback( + const std::shared_ptr& callback) { + ALOGD("setCallback"); + std::unique_lock lock(mMutex); + sCallback = callback; + sCallback->setCapabilitiesCb(IGnssPowerIndicationCallback::CAPABILITY_TOTAL | + IGnssPowerIndicationCallback::CAPABILITY_SINGLEBAND_TRACKING | + IGnssPowerIndicationCallback::CAPABILITY_MULTIBAND_TRACKING | + IGnssPowerIndicationCallback::CAPABILITY_SINGLEBAND_ACQUISITION | + IGnssPowerIndicationCallback::CAPABILITY_MULTIBAND_ACQUISITION | + IGnssPowerIndicationCallback::CAPABILITY_OTHER_MODES); + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus GnssPowerIndication::requestGnssPowerStats() { + ALOGD("requestGnssPowerStats"); + std::unique_lock lock(mMutex); + + ElapsedRealtime elapsedRealtime = { + .flags = IGnss::ELAPSED_REALTIME_HAS_TIMESTAMP_NS | + IGnss::ELAPSED_REALTIME_HAS_TIME_UNCERTAINTY_NS, + .timestampNs = (long)1323542, + .timeUncertaintyNs = (long)1000, + }; + GnssPowerStats gnssPowerStats = { + .elapsedRealtime = elapsedRealtime, + .totalEnergyMilliJoule = 1.59975e+3, + .singlebandTrackingModeEnergyMilliJoule = 1.2342e+3, + .multibandTrackingModeEnergyMilliJoule = 3.653e+2, + .otherModesEnergyMilliJoule = {1.232e+2, 3.234e+3}, + }; + sCallback->gnssPowerStatsCb(gnssPowerStats); + return ndk::ScopedAStatus::ok(); +} + +} // namespace aidl::android::hardware::gnss diff --git a/gnss/aidl/default/GnssPowerIndication.h b/gnss/aidl/default/GnssPowerIndication.h new file mode 100644 index 0000000000..e32fd72ac0 --- /dev/null +++ b/gnss/aidl/default/GnssPowerIndication.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +namespace aidl::android::hardware::gnss { + +struct GnssPowerIndication : public BnGnssPowerIndication { + public: + ndk::ScopedAStatus setCallback( + const std::shared_ptr& callback) override; + ndk::ScopedAStatus requestGnssPowerStats() override; + + private: + // Guarded by mMutex + static std::shared_ptr sCallback; + + // Synchronization lock for sCallback + mutable std::mutex mMutex; +}; + +} // namespace aidl::android::hardware::gnss diff --git a/gnss/aidl/vts/Android.bp b/gnss/aidl/vts/Android.bp index 48a0e21f24..d102e7f4dd 100644 --- a/gnss/aidl/vts/Android.bp +++ b/gnss/aidl/vts/Android.bp @@ -22,6 +22,7 @@ cc_test { "gnss_hal_test.cpp", "gnss_hal_test_cases.cpp", "GnssCallbackAidl.cpp", + "GnssPowerIndicationCallback.cpp", "VtsHalGnssTargetTest.cpp", ], shared_libs: [ diff --git a/gnss/aidl/vts/GnssPowerIndicationCallback.cpp b/gnss/aidl/vts/GnssPowerIndicationCallback.cpp new file mode 100644 index 0000000000..1cbfc20f8c --- /dev/null +++ b/gnss/aidl/vts/GnssPowerIndicationCallback.cpp @@ -0,0 +1,47 @@ +/* + * 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 "GnssPwrIndCallback" + +#include "GnssPowerIndicationCallback.h" +#include + +using android::hardware::gnss::GnssPowerStats; + +android::binder::Status GnssPowerIndicationCallback::setCapabilitiesCb(const int capabilities) { + ALOGI("Capabilities received %d", capabilities); + capabilities_cbq_.store(capabilities); + return android::binder::Status::ok(); +} + +android::binder::Status GnssPowerIndicationCallback::gnssPowerStatsCb( + const GnssPowerStats& gnssPowerStats) { + ALOGI("gnssPowerStatsCb"); + ALOGI("elapsedRealtime: %ld, totalEnergyMilliJoule: %f", + (long)gnssPowerStats.elapsedRealtime.timestampNs, gnssPowerStats.totalEnergyMilliJoule); + ALOGI("singlebandTrackingModeEnergyMilliJoule: %f, multibandTrackingModeEnergyMilliJoule: %f", + gnssPowerStats.singlebandTrackingModeEnergyMilliJoule, + gnssPowerStats.multibandTrackingModeEnergyMilliJoule); + ALOGI("singlebandAcquisitionModeEnergyMilliJoule: %f, " + "multibandAcquisitionModeEnergyMilliJoule: %f", + gnssPowerStats.singlebandAcquisitionModeEnergyMilliJoule, + gnssPowerStats.multibandAcquisitionModeEnergyMilliJoule); + for (const auto& otherModeEnergyMilliJoule : gnssPowerStats.otherModesEnergyMilliJoule) { + ALOGI("otherModeEnergyMilliJoule: %f", otherModeEnergyMilliJoule); + } + gnss_power_stats_cbq_.store(gnssPowerStats); + return android::binder::Status::ok(); +} diff --git a/gnss/aidl/vts/GnssPowerIndicationCallback.h b/gnss/aidl/vts/GnssPowerIndicationCallback.h new file mode 100644 index 0000000000..d4c4539389 --- /dev/null +++ b/gnss/aidl/vts/GnssPowerIndicationCallback.h @@ -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. + */ + +#pragma once + +#include +#include +#include "GnssCallbackEventQueue.h" + +/** Implementation for IGnssPowerIndicationCallback. */ +class GnssPowerIndicationCallback : public android::hardware::gnss::BnGnssPowerIndicationCallback { + public: + GnssPowerIndicationCallback() + : capabilities_cbq_("capabilities"), + other_mode_names_cbq_("other_mode_names"), + gnss_power_stats_cbq_("gnss_power_stats") {} + ~GnssPowerIndicationCallback() {} + + android::binder::Status setCapabilitiesCb(const int capabilities) override; + android::binder::Status gnssPowerStatsCb( + const android::hardware::gnss::GnssPowerStats& gnssPowerStats) override; + + android::hardware::gnss::common::GnssCallbackEventQueue capabilities_cbq_; + int last_capabilities_; + android::hardware::gnss::common::GnssCallbackEventQueue> + other_mode_names_cbq_; + std::vector last_other_mode_names_; + android::hardware::gnss::common::GnssCallbackEventQueue + gnss_power_stats_cbq_; + android::hardware::gnss::GnssPowerStats last_gnss_power_stats_; +}; diff --git a/gnss/aidl/vts/gnss_hal_test_cases.cpp b/gnss/aidl/vts/gnss_hal_test_cases.cpp index d621053240..4e8d0bd66b 100644 --- a/gnss/aidl/vts/gnss_hal_test_cases.cpp +++ b/gnss/aidl/vts/gnss_hal_test_cases.cpp @@ -16,13 +16,16 @@ #define LOG_TAG "GnssHalTestCases" +#include #include +#include "GnssPowerIndicationCallback.h" #include "gnss_hal_test.h" using android::sp; using android::hardware::gnss::BlocklistedSource; using GnssConstellationTypeAidl = android::hardware::gnss::GnssConstellationType; using android::hardware::gnss::IGnssConfiguration; +using android::hardware::gnss::IGnssPowerIndication; using android::hardware::gnss::IGnssPsds; using android::hardware::gnss::PsdsType; @@ -37,7 +40,7 @@ TEST_P(GnssHalTest, SetupTeardownCreateCleanup) {} /* * TestPsdsExtension: * 1. Gets the PsdsExtension and verifies that it returns a non-null extension. - * 2. Injects empty PSDS data and verifies that it returns false. + * 2. Injects empty PSDS data and verifies that it returns an error. */ TEST_P(GnssHalTest, TestPsdsExtension) { sp iGnssPsds; @@ -49,6 +52,34 @@ TEST_P(GnssHalTest, TestPsdsExtension) { ASSERT_FALSE(status.isOk()); } +/* + * TestGnssPowerIndication + * 1. Gets the GnssPowerIndicationExtension. + * 2. Sets a GnssPowerIndicationCallback. + * 3. + */ +TEST_P(GnssHalTest, TestGnssPowerIndication) { + sp iGnssPowerIndication; + auto status = aidl_gnss_hal_->getExtensionGnssPowerIndication(&iGnssPowerIndication); + ASSERT_TRUE(status.isOk()); + ASSERT_TRUE(iGnssPowerIndication != nullptr); + + auto gnssPowerIndicationCallback = sp::make(); + status = iGnssPowerIndication->setCallback(gnssPowerIndicationCallback); + ASSERT_TRUE(status.isOk()); + + const int kTimeoutSec = 2; + EXPECT_TRUE(gnssPowerIndicationCallback->capabilities_cbq_.retrieve( + gnssPowerIndicationCallback->last_capabilities_, kTimeoutSec)); + + EXPECT_EQ(gnssPowerIndicationCallback->capabilities_cbq_.calledCount(), 1); + + iGnssPowerIndication->requestGnssPowerStats(); + EXPECT_TRUE(gnssPowerIndicationCallback->gnss_power_stats_cbq_.retrieve( + gnssPowerIndicationCallback->last_gnss_power_stats_, kTimeoutSec)); + EXPECT_EQ(gnssPowerIndicationCallback->gnss_power_stats_cbq_.calledCount(), 1); +} + /* * FindStrongFrequentNonGpsSource: * -- GitLab From a67701d0d01f2ba92cb34579f38a4086b89cc671 Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Thu, 5 Nov 2020 16:06:20 +0800 Subject: [PATCH 278/790] hostapd: add 60GHz(WiGig) support Extend the band with 60GHz constant to support starting AP on the 60GHz band. Add channel parameters for EDMG (802.11ay, 60GHz channel bonding). Bug: 147469374 Test: atest VtsHalWifiHostapdV1_3TargetTest Change-Id: I8d3ca0c14766dfb4a79c1febcc2bb05f65ba311e --- wifi/hostapd/1.3/IHostapd.hal | 39 +++++++++++++++++++++++++++++++++++ wifi/hostapd/1.3/types.hal | 6 ++++++ 2 files changed, 45 insertions(+) diff --git a/wifi/hostapd/1.3/IHostapd.hal b/wifi/hostapd/1.3/IHostapd.hal index be6fe59a29..70de7c2ece 100644 --- a/wifi/hostapd/1.3/IHostapd.hal +++ b/wifi/hostapd/1.3/IHostapd.hal @@ -17,6 +17,8 @@ package android.hardware.wifi.hostapd@1.3; import @1.2::HostapdStatus; +import @1.2::IHostapd.BandMask; +import @1.2::IHostapd.HwModeParams; import @1.2::IHostapd.IfaceParams; import @1.2::IHostapd.NetworkParams; import @1.2::IHostapd; @@ -27,6 +29,28 @@ import IHostapdCallback; */ interface IHostapd extends @1.2::IHostapd { + enum BandMask : @1.2::IHostapd.BandMask { + /** + * 60 GHz band. + */ + BAND_60_GHZ = 1 << 3, + }; + + /** + * Parameters to control the HW mode for the interface. + */ + struct HwModeParams { + /** + * Baseline information as defined in HAL 1.2. + */ + @1.2::IHostapd.HwModeParams V1_2; + + /** + * Enable EDMG (802.11ay), this option is only allowed for the 60GHz band. + */ + bool enableEdmg; + }; + /** * Parameters to control the channel selection for the interface. */ @@ -52,10 +76,20 @@ interface IHostapd extends @1.2::IHostapd { * Channel number (IEEE 802.11) to use for the interface. * If ACS is enabled, this field is ignored. * + * If |enableEdmg| is true, the channel must be set. Refer to + * P802.11ay_D4.0 29.3.4. + * * Note: It is used instead of V1_0::ChannelParams.channel inside * V1_3::IfaceParams.V1_2.V1_1.V1_0. */ uint32_t channel; + + /** + * Band to use for the SoftAp operations. + * Note: It is used instead of V1_2::ChannelParams.bandMask inside + * V1_3::IfaceParams.V1_2.channelParams + */ + bitfield bandMask; }; /** @@ -67,6 +101,11 @@ interface IHostapd extends @1.2::IHostapd { */ @1.2::IHostapd.IfaceParams V1_2; + /** + * Additional Hw mode params for the interface + */ + HwModeParams hwModeParams; + /** * The list of the channel params for the dual interfaces. */ diff --git a/wifi/hostapd/1.3/types.hal b/wifi/hostapd/1.3/types.hal index de85043e84..f453df7585 100644 --- a/wifi/hostapd/1.3/types.hal +++ b/wifi/hostapd/1.3/types.hal @@ -26,6 +26,7 @@ package android.hardware.wifi.hostapd@1.3; * [hw_mode is HOSTAPD_MODE_IEEE80211A and VHT is 0]. * WIFI_STANDARD_11AC = hw_mode is HOSTAPD_MODE_IEEE80211A and VHT is 1. * WIFI_STANDARD_11AX = hw_mode is HOSTAPD_MODE_IEEE80211AX. + * WIFI_STANDARD_11AD = hw_mode is HOSTAPD_MODE_IEEE80211AD. */ enum Generation : uint32_t { WIFI_STANDARD_UNKNOWN = -1, @@ -33,6 +34,7 @@ enum Generation : uint32_t { WIFI_STANDARD_11N = 1, WIFI_STANDARD_11AC = 2, WIFI_STANDARD_11AX = 3, + WIFI_STANDARD_11AD = 4, }; /** @@ -46,4 +48,8 @@ enum Bandwidth : uint32_t { WIFI_BANDWIDTH_80 = 4, WIFI_BANDWIDTH_80P80 = 5, WIFI_BANDWIDTH_160 = 6, + WIFI_BANDWIDTH_2160 = 7, + WIFI_BANDWIDTH_4320 = 8, + WIFI_BANDWIDTH_6480 = 9, + WIFI_BANDWIDTH_8640 = 10, }; -- GitLab From 7674b03f384ec66a78da5c54ca7e001829e32880 Mon Sep 17 00:00:00 2001 From: Daniel Bright Date: Tue, 3 Nov 2020 14:56:23 -0800 Subject: [PATCH 279/790] Added pdu session id to setupDataCall The pdu session id needs to be passed to setup data call on handover Test: Tested that handover still worked with logs. IWlan -> Cell + Cell -> IWlan Bug: 161572859 Change-Id: I0e11c8997674cdaad4bb82491d818ca85ee197d1 --- radio/1.6/IRadio.hal | 12 ++++++++---- radio/1.6/IRadioResponse.hal | 4 ++-- radio/1.6/vts/functional/radio_hidl_hal_api.cpp | 2 +- radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h | 2 +- radio/1.6/vts/functional/radio_response.cpp | 2 +- 5 files changed, 13 insertions(+), 9 deletions(-) diff --git a/radio/1.6/IRadio.hal b/radio/1.6/IRadio.hal index 91709fabe7..8afbf22c64 100644 --- a/radio/1.6/IRadio.hal +++ b/radio/1.6/IRadio.hal @@ -114,6 +114,9 @@ interface IRadio extends @1.5::IRadio { * addresses of the existing data connection. The format is defined in RFC-4291 section 2.2. * For example, "192.0.1.3" or "2001:db8::1". This parameter must be ignored unless reason * is DataRequestReason:HANDOVER. + * @param pduSessionId The pdu session id to be used for this data call. A value of 0 means + * no pdu session id was attached to this call. + * Reference: 3GPP TS 24.007 section 11.2.3.1b * * Response function is IRadioResponse.setupDataCallResponse_1_6() * @@ -121,7 +124,8 @@ interface IRadio extends @1.5::IRadio { */ oneway setupDataCall_1_6(int32_t serial, AccessNetwork accessNetwork, DataProfileInfo dataProfileInfo, bool roamingAllowed, - DataRequestReason reason, vec addresses, vec dnses); + DataRequestReason reason, vec addresses, vec dnses, + int32_t pduSessionId); /** * Send an SMS message @@ -290,12 +294,12 @@ interface IRadio extends @1.5::IRadio { * @param serial Serial number of request. * @param id callId The identifier of the data call which is provided in SetupDataCallResult * - * Response function is IRadioResponse.beginHandoverResponse() + * Response function is IRadioResponse.startHandoverResponse() */ - oneway beginHandover(int32_t serial, int32_t callId); + oneway startHandover(int32_t serial, int32_t callId); /** - * Indicates that a handover was cancelled after a call to IRadio::beginHandover. + * Indicates that a handover was cancelled after a call to IRadio::startHandover. * * Since the handover was unsuccessful, the modem retains ownership over any of the resources * being transferred and is still responsible for releasing them. diff --git a/radio/1.6/IRadioResponse.hal b/radio/1.6/IRadioResponse.hal index acae5c7e22..5a71c1fe54 100644 --- a/radio/1.6/IRadioResponse.hal +++ b/radio/1.6/IRadioResponse.hal @@ -241,7 +241,7 @@ interface IRadioResponse extends @1.5::IRadioResponse { /** * @param info Response info struct containing response type, serial no. and error - * @param id The allocated id. On an error, this is set to -1 + * @param id The allocated id. On an error, this is set to 0. * * Valid errors returned: * RadioError:NONE @@ -275,7 +275,7 @@ interface IRadioResponse extends @1.5::IRadioResponse { * RadioError:REQUEST_NOT_SUPPORTED * RadioError:INVALID_CALL_ID */ - oneway beginHandoverResponse(RadioResponseInfo info); + oneway startHandoverResponse(RadioResponseInfo info); /** * @param info Response info struct containing response type, serial no. and error diff --git a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp index ac84417ff8..d3ffba988a 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp +++ b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp @@ -57,7 +57,7 @@ TEST_P(RadioHidlTest_v1_6, setupDataCall_1_6) { ::android::hardware::radio::V1_2::DataRequestReason::NORMAL; Return res = radio_v1_6->setupDataCall_1_6(serial, accessNetwork, dataProfileInfo, - roamingAllowed, reason, addresses, dnses); + roamingAllowed, reason, addresses, dnses, -1); ASSERT_OK(res); EXPECT_EQ(std::cv_status::no_timeout, wait()); diff --git a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h index 31bb1d7114..fcf679c267 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h +++ b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h @@ -784,7 +784,7 @@ class RadioResponse_v1_6 : public ::android::hardware::radio::V1_6::IRadioRespon Return releasePduSessionIdResponse( const ::android::hardware::radio::V1_6::RadioResponseInfo& info); - Return beginHandoverResponse( + Return startHandoverResponse( const ::android::hardware::radio::V1_6::RadioResponseInfo& info); Return cancelHandoverResponse( diff --git a/radio/1.6/vts/functional/radio_response.cpp b/radio/1.6/vts/functional/radio_response.cpp index 09a2baced4..788038a041 100644 --- a/radio/1.6/vts/functional/radio_response.cpp +++ b/radio/1.6/vts/functional/radio_response.cpp @@ -1136,7 +1136,7 @@ Return RadioResponse_v1_6::releasePduSessionIdResponse( return Void(); } -Return RadioResponse_v1_6::beginHandoverResponse( +Return RadioResponse_v1_6::startHandoverResponse( const ::android::hardware::radio::V1_6::RadioResponseInfo& info) { rspInfo = info; parent_v1_6.notify(info.serial); -- GitLab From 3670c385c4b12aef975ab67e5d2b0f5fe79134c2 Mon Sep 17 00:00:00 2001 From: Michael Butler Date: Thu, 6 Aug 2020 23:22:35 -0700 Subject: [PATCH 280/790] Implement NNAPI canonical interfaces This CL implements the canonical IDevice, IPreparedModel, and IBuffer interfaces for the 1.0, 1.1, 1.2, and 1.3 NN HIDL HAL interfaces. Further, it introduces "Resilient" adapter interfaces to automatically retrieve a handle to a recovered interface object after it has died and rebooted. This CL also updates the conversion code from returning nn::Result to nn::GeneralResult, which includes a ErrorStatus code in the case of an error. Finally, this CL introduces a new static library neuralnetworks_utils_hal_service which consists of a single function ::android::nn::hal::getDevices which can be used by the NNAPI runtime to retrieve the HIDL services without knowing the underlying HIDL types. Bug: 160668438 Test: mma Test: NeuralNetworksTest_static Change-Id: Iec6ae739df196b4034ffb35ea76781fd541ffec3 --- neuralnetworks/1.0/utils/Android.bp | 1 + .../utils/include/nnapi/hal/1.0/Callbacks.h | 67 ++++ .../utils/include/nnapi/hal/1.0/Conversions.h | 64 ++-- .../1.0/utils/include/nnapi/hal/1.0/Device.h | 87 +++++ .../include/nnapi/hal/1.0/PreparedModel.h | 64 ++++ .../1.0/utils/include/nnapi/hal/1.0/Service.h | 31 ++ .../1.0/utils/include/nnapi/hal/1.0/Utils.h | 20 +- neuralnetworks/1.0/utils/src/Callbacks.cpp | 97 ++++++ neuralnetworks/1.0/utils/src/Conversions.cpp | 89 ++--- neuralnetworks/1.0/utils/src/Device.cpp | 199 +++++++++++ .../1.0/utils/src/PreparedModel.cpp | 100 ++++++ neuralnetworks/1.0/utils/src/Service.cpp | 41 +++ neuralnetworks/1.1/utils/Android.bp | 1 + .../utils/include/nnapi/hal/1.1/Conversions.h | 21 +- .../1.1/utils/include/nnapi/hal/1.1/Device.h | 87 +++++ .../1.1/utils/include/nnapi/hal/1.1/Service.h | 31 ++ .../1.1/utils/include/nnapi/hal/1.1/Utils.h | 20 +- neuralnetworks/1.1/utils/src/Conversions.cpp | 42 +-- neuralnetworks/1.1/utils/src/Device.cpp | 202 +++++++++++ neuralnetworks/1.1/utils/src/Service.cpp | 41 +++ neuralnetworks/1.2/utils/Android.bp | 1 + .../utils/include/nnapi/hal/1.2/Callbacks.h | 76 +++++ .../utils/include/nnapi/hal/1.2/Conversions.h | 82 ++--- .../1.2/utils/include/nnapi/hal/1.2/Device.h | 98 ++++++ .../include/nnapi/hal/1.2/PreparedModel.h | 70 ++++ .../1.2/utils/include/nnapi/hal/1.2/Service.h | 31 ++ .../1.2/utils/include/nnapi/hal/1.2/Utils.h | 20 +- neuralnetworks/1.2/utils/src/Callbacks.cpp | 147 ++++++++ neuralnetworks/1.2/utils/src/Conversions.cpp | 133 ++++---- neuralnetworks/1.2/utils/src/Device.cpp | 318 ++++++++++++++++++ .../1.2/utils/src/PreparedModel.cpp | 161 +++++++++ neuralnetworks/1.2/utils/src/Service.cpp | 41 +++ neuralnetworks/1.3/utils/Android.bp | 1 + .../1.3/utils/include/nnapi/hal/1.3/Buffer.h | 52 +++ .../utils/include/nnapi/hal/1.3/Callbacks.h | 83 +++++ .../utils/include/nnapi/hal/1.3/Conversions.h | 72 ++-- .../1.3/utils/include/nnapi/hal/1.3/Device.h | 91 +++++ .../include/nnapi/hal/1.3/PreparedModel.h | 71 ++++ .../1.3/utils/include/nnapi/hal/1.3/Service.h | 31 ++ .../1.3/utils/include/nnapi/hal/1.3/Utils.h | 20 +- neuralnetworks/1.3/utils/src/Buffer.cpp | 93 +++++ neuralnetworks/1.3/utils/src/Callbacks.cpp | 184 ++++++++++ neuralnetworks/1.3/utils/src/Conversions.cpp | 160 ++++----- neuralnetworks/1.3/utils/src/Device.cpp | 269 +++++++++++++++ .../1.3/utils/src/PreparedModel.cpp | 267 +++++++++++++++ neuralnetworks/1.3/utils/src/Service.cpp | 41 +++ neuralnetworks/utils/common/Android.bp | 1 + .../common/include/nnapi/hal/CommonUtils.h | 11 +- .../common/include/nnapi/hal/HandleError.h | 101 ++++++ .../include/nnapi/hal/ProtectCallback.h | 90 +++++ .../include/nnapi/hal/ResilientBuffer.h | 62 ++++ .../include/nnapi/hal/ResilientDevice.h | 107 ++++++ .../nnapi/hal/ResilientPreparedModel.h | 70 ++++ .../common/include/nnapi/hal/TransferValue.h | 66 ++++ .../utils/common/src/CommonUtils.cpp | 46 ++- .../utils/common/src/ProtectCallback.cpp | 95 ++++++ .../utils/common/src/ResilientBuffer.cpp | 75 +++++ .../utils/common/src/ResilientDevice.cpp | 236 +++++++++++++ .../common/src/ResilientPreparedModel.cpp | 85 +++++ neuralnetworks/utils/service/Android.bp | 36 ++ .../utils/service/include/nnapi/hal/Service.h | 31 ++ neuralnetworks/utils/service/src/Service.cpp | 94 ++++++ 62 files changed, 4774 insertions(+), 350 deletions(-) create mode 100644 neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Callbacks.h create mode 100644 neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Device.h create mode 100644 neuralnetworks/1.0/utils/include/nnapi/hal/1.0/PreparedModel.h create mode 100644 neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Service.h create mode 100644 neuralnetworks/1.0/utils/src/Callbacks.cpp create mode 100644 neuralnetworks/1.0/utils/src/Device.cpp create mode 100644 neuralnetworks/1.0/utils/src/PreparedModel.cpp create mode 100644 neuralnetworks/1.0/utils/src/Service.cpp create mode 100644 neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Device.h create mode 100644 neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Service.h create mode 100644 neuralnetworks/1.1/utils/src/Device.cpp create mode 100644 neuralnetworks/1.1/utils/src/Service.cpp create mode 100644 neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Callbacks.h create mode 100644 neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Device.h create mode 100644 neuralnetworks/1.2/utils/include/nnapi/hal/1.2/PreparedModel.h create mode 100644 neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Service.h create mode 100644 neuralnetworks/1.2/utils/src/Callbacks.cpp create mode 100644 neuralnetworks/1.2/utils/src/Device.cpp create mode 100644 neuralnetworks/1.2/utils/src/PreparedModel.cpp create mode 100644 neuralnetworks/1.2/utils/src/Service.cpp create mode 100644 neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Buffer.h create mode 100644 neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Callbacks.h create mode 100644 neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Device.h create mode 100644 neuralnetworks/1.3/utils/include/nnapi/hal/1.3/PreparedModel.h create mode 100644 neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Service.h create mode 100644 neuralnetworks/1.3/utils/src/Buffer.cpp create mode 100644 neuralnetworks/1.3/utils/src/Callbacks.cpp create mode 100644 neuralnetworks/1.3/utils/src/Device.cpp create mode 100644 neuralnetworks/1.3/utils/src/PreparedModel.cpp create mode 100644 neuralnetworks/1.3/utils/src/Service.cpp create mode 100644 neuralnetworks/utils/common/include/nnapi/hal/HandleError.h create mode 100644 neuralnetworks/utils/common/include/nnapi/hal/ProtectCallback.h create mode 100644 neuralnetworks/utils/common/include/nnapi/hal/ResilientBuffer.h create mode 100644 neuralnetworks/utils/common/include/nnapi/hal/ResilientDevice.h create mode 100644 neuralnetworks/utils/common/include/nnapi/hal/ResilientPreparedModel.h create mode 100644 neuralnetworks/utils/common/include/nnapi/hal/TransferValue.h create mode 100644 neuralnetworks/utils/common/src/ProtectCallback.cpp create mode 100644 neuralnetworks/utils/common/src/ResilientBuffer.cpp create mode 100644 neuralnetworks/utils/common/src/ResilientDevice.cpp create mode 100644 neuralnetworks/utils/common/src/ResilientPreparedModel.cpp create mode 100644 neuralnetworks/utils/service/Android.bp create mode 100644 neuralnetworks/utils/service/include/nnapi/hal/Service.h create mode 100644 neuralnetworks/utils/service/src/Service.cpp diff --git a/neuralnetworks/1.0/utils/Android.bp b/neuralnetworks/1.0/utils/Android.bp index 57a052f1f5..4d61fc0a94 100644 --- a/neuralnetworks/1.0/utils/Android.bp +++ b/neuralnetworks/1.0/utils/Android.bp @@ -20,6 +20,7 @@ cc_library_static { srcs: ["src/*"], local_include_dirs: ["include/nnapi/hal/1.0/"], export_include_dirs: ["include"], + cflags: ["-Wthread-safety"], static_libs: [ "neuralnetworks_types", "neuralnetworks_utils_hal_common", diff --git a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Callbacks.h b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Callbacks.h new file mode 100644 index 0000000000..65b75e5d82 --- /dev/null +++ b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Callbacks.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_0_UTILS_CALLBACKS_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_0_UTILS_CALLBACKS_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::V1_0::utils { + +class PreparedModelCallback final : public IPreparedModelCallback, + public hal::utils::IProtectedCallback { + public: + using Data = nn::GeneralResult; + + Return notify(ErrorStatus status, const sp& preparedModel) override; + + void notifyAsDeadObject() override; + + Data get(); + + private: + void notifyInternal(Data result); + + hal::utils::TransferValue mData; +}; + +class ExecutionCallback final : public IExecutionCallback, public hal::utils::IProtectedCallback { + public: + using Data = nn::ExecutionResult, nn::Timing>>; + + Return notify(ErrorStatus status) override; + + void notifyAsDeadObject() override; + + Data get(); + + private: + void notifyInternal(Data result); + + hal::utils::TransferValue mData; +}; + +} // namespace android::hardware::neuralnetworks::V1_0::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_0_UTILS_CALLBACKS_H diff --git a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Conversions.h b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Conversions.h index 8ad98cbafc..fb77cb2475 100644 --- a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Conversions.h +++ b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Conversions.h @@ -24,42 +24,44 @@ namespace android::nn { -Result convert(const hal::V1_0::OperandType& operandType); -Result convert(const hal::V1_0::OperationType& operationType); -Result convert(const hal::V1_0::OperandLifeTime& lifetime); -Result convert(const hal::V1_0::DeviceStatus& deviceStatus); -Result convert(const hal::V1_0::PerformanceInfo& performanceInfo); -Result convert(const hal::V1_0::Capabilities& capabilities); -Result convert(const hal::V1_0::DataLocation& location); -Result convert(const hal::V1_0::Operand& operand); -Result convert(const hal::V1_0::Operation& operation); -Result convert(const hardware::hidl_vec& operandValues); -Result convert(const hardware::hidl_memory& memory); -Result convert(const hal::V1_0::Model& model); -Result convert(const hal::V1_0::RequestArgument& requestArgument); -Result convert(const hal::V1_0::Request& request); -Result convert(const hal::V1_0::ErrorStatus& status); +GeneralResult convert(const hal::V1_0::OperandType& operandType); +GeneralResult convert(const hal::V1_0::OperationType& operationType); +GeneralResult convert(const hal::V1_0::OperandLifeTime& lifetime); +GeneralResult convert(const hal::V1_0::DeviceStatus& deviceStatus); +GeneralResult convert( + const hal::V1_0::PerformanceInfo& performanceInfo); +GeneralResult convert(const hal::V1_0::Capabilities& capabilities); +GeneralResult convert(const hal::V1_0::DataLocation& location); +GeneralResult convert(const hal::V1_0::Operand& operand); +GeneralResult convert(const hal::V1_0::Operation& operation); +GeneralResult convert(const hardware::hidl_vec& operandValues); +GeneralResult convert(const hardware::hidl_memory& memory); +GeneralResult convert(const hal::V1_0::Model& model); +GeneralResult convert(const hal::V1_0::RequestArgument& requestArgument); +GeneralResult convert(const hal::V1_0::Request& request); +GeneralResult convert(const hal::V1_0::ErrorStatus& status); } // namespace android::nn namespace android::hardware::neuralnetworks::V1_0::utils { -nn::Result convert(const nn::OperandType& operandType); -nn::Result convert(const nn::OperationType& operationType); -nn::Result convert(const nn::Operand::LifeTime& lifetime); -nn::Result convert(const nn::DeviceStatus& deviceStatus); -nn::Result convert(const nn::Capabilities::PerformanceInfo& performanceInfo); -nn::Result convert(const nn::Capabilities& capabilities); -nn::Result convert(const nn::DataLocation& location); -nn::Result convert(const nn::Operand& operand); -nn::Result convert(const nn::Operation& operation); -nn::Result> convert(const nn::Model::OperandValues& operandValues); -nn::Result convert(const nn::Memory& memory); -nn::Result convert(const nn::Model& model); -nn::Result convert(const nn::Request::Argument& requestArgument); -nn::Result convert(const nn::Request::MemoryPool& memoryPool); -nn::Result convert(const nn::Request& request); -nn::Result convert(const nn::ErrorStatus& status); +nn::GeneralResult convert(const nn::OperandType& operandType); +nn::GeneralResult convert(const nn::OperationType& operationType); +nn::GeneralResult convert(const nn::Operand::LifeTime& lifetime); +nn::GeneralResult convert(const nn::DeviceStatus& deviceStatus); +nn::GeneralResult convert( + const nn::Capabilities::PerformanceInfo& performanceInfo); +nn::GeneralResult convert(const nn::Capabilities& capabilities); +nn::GeneralResult convert(const nn::DataLocation& location); +nn::GeneralResult convert(const nn::Operand& operand); +nn::GeneralResult convert(const nn::Operation& operation); +nn::GeneralResult> convert(const nn::Model::OperandValues& operandValues); +nn::GeneralResult convert(const nn::Memory& memory); +nn::GeneralResult convert(const nn::Model& model); +nn::GeneralResult convert(const nn::Request::Argument& requestArgument); +nn::GeneralResult convert(const nn::Request::MemoryPool& memoryPool); +nn::GeneralResult convert(const nn::Request& request); +nn::GeneralResult convert(const nn::ErrorStatus& status); } // namespace android::hardware::neuralnetworks::V1_0::utils diff --git a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Device.h b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Device.h new file mode 100644 index 0000000000..4403a579cc --- /dev/null +++ b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Device.h @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_0_UTILS_DEVICE_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_0_UTILS_DEVICE_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::V1_0::utils { + +class Device final : public nn::IDevice { + struct PrivateConstructorTag {}; + + public: + static nn::GeneralResult> create(std::string name, + sp device); + + Device(PrivateConstructorTag tag, std::string name, nn::Capabilities capabilities, + sp device, hal::utils::DeathHandler deathHandler); + + const std::string& getName() const override; + const std::string& getVersionString() const override; + nn::Version getFeatureLevel() const override; + nn::DeviceType getType() const override; + const std::vector& getSupportedExtensions() const override; + const nn::Capabilities& getCapabilities() const override; + std::pair getNumberOfCacheFilesNeeded() const override; + + nn::GeneralResult wait() const override; + + nn::GeneralResult> getSupportedOperations( + const nn::Model& model) const override; + + nn::GeneralResult prepareModel( + const nn::Model& model, nn::ExecutionPreference preference, nn::Priority priority, + nn::OptionalTimePoint deadline, const std::vector& modelCache, + const std::vector& dataCache, + const nn::CacheToken& token) const override; + + nn::GeneralResult prepareModelFromCache( + nn::OptionalTimePoint deadline, const std::vector& modelCache, + const std::vector& dataCache, + const nn::CacheToken& token) const override; + + nn::GeneralResult allocate( + const nn::BufferDesc& desc, const std::vector& preparedModels, + const std::vector& inputRoles, + const std::vector& outputRoles) const override; + + private: + const std::string kName; + const std::string kVersionString = "UNKNOWN"; + const std::vector kExtensions; + const nn::Capabilities kCapabilities; + const sp kDevice; + const hal::utils::DeathHandler kDeathHandler; +}; + +} // namespace android::hardware::neuralnetworks::V1_0::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_0_UTILS_DEVICE_H diff --git a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/PreparedModel.h b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/PreparedModel.h new file mode 100644 index 0000000000..31f366dadc --- /dev/null +++ b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/PreparedModel.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_0_UTILS_PREPARED_MODEL_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_0_UTILS_PREPARED_MODEL_H + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::V1_0::utils { + +class PreparedModel final : public nn::IPreparedModel { + struct PrivateConstructorTag {}; + + public: + static nn::GeneralResult> create( + sp preparedModel); + + PreparedModel(PrivateConstructorTag tag, sp preparedModel, + hal::utils::DeathHandler deathHandler); + + nn::ExecutionResult, nn::Timing>> execute( + const nn::Request& request, nn::MeasureTiming measure, + const nn::OptionalTimePoint& deadline, + const nn::OptionalTimeoutDuration& loopTimeoutDuration) const override; + + nn::GeneralResult> executeFenced( + const nn::Request& request, const std::vector& waitFor, + nn::MeasureTiming measure, const nn::OptionalTimePoint& deadline, + const nn::OptionalTimeoutDuration& loopTimeoutDuration, + const nn::OptionalTimeoutDuration& timeoutDurationAfterFence) const override; + + std::any getUnderlyingResource() const override; + + private: + const sp kPreparedModel; + const hal::utils::DeathHandler kDeathHandler; +}; + +} // namespace android::hardware::neuralnetworks::V1_0::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_0_UTILS_PREPARED_MODEL_H diff --git a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Service.h b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Service.h new file mode 100644 index 0000000000..11fbb9edcf --- /dev/null +++ b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Service.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_0_UTILS_SERVICE_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_0_UTILS_SERVICE_H + +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::V1_0::utils { + +nn::GeneralResult getDevice(const std::string& name); + +} // namespace android::hardware::neuralnetworks::V1_0::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_0_UTILS_SERVICE_H diff --git a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Utils.h b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Utils.h index ec8da06ca6..baa2b9523e 100644 --- a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Utils.h +++ b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Utils.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -31,10 +32,14 @@ constexpr auto kVersion = nn::Version::ANDROID_OC_MR1; template nn::Result validate(const Type& halObject) { - const auto canonical = NN_TRY(nn::convert(halObject)); - const auto version = NN_TRY(nn::validate(canonical)); + const auto maybeCanonical = nn::convert(halObject); + if (!maybeCanonical.has_value()) { + return nn::error() << maybeCanonical.error().message; + } + const auto version = NN_TRY(nn::validate(maybeCanonical.value())); if (version > utils::kVersion) { - return NN_ERROR() << ""; + return NN_ERROR() << "Insufficient version: " << version << " vs required " + << utils::kVersion; } return {}; } @@ -51,9 +56,14 @@ bool valid(const Type& halObject) { template decltype(nn::convert(std::declval())) validatedConvertToCanonical(const Type& halObject) { auto canonical = NN_TRY(nn::convert(halObject)); - const auto version = NN_TRY(nn::validate(canonical)); + const auto maybeVersion = nn::validate(canonical); + if (!maybeVersion.has_value()) { + return nn::error() << maybeVersion.error(); + } + const auto version = maybeVersion.value(); if (version > utils::kVersion) { - return NN_ERROR() << ""; + return NN_ERROR() << "Insufficient version: " << version << " vs required " + << utils::kVersion; } return canonical; } diff --git a/neuralnetworks/1.0/utils/src/Callbacks.cpp b/neuralnetworks/1.0/utils/src/Callbacks.cpp new file mode 100644 index 0000000000..f286bcc50e --- /dev/null +++ b/neuralnetworks/1.0/utils/src/Callbacks.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Callbacks.h" + +#include "Conversions.h" +#include "PreparedModel.h" +#include "Utils.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace android::hardware::neuralnetworks::V1_0::utils { +namespace { + +nn::GeneralResult convertPreparedModel( + const sp& preparedModel) { + return NN_TRY(utils::PreparedModel::create(preparedModel)); +} + +} // namespace + +Return PreparedModelCallback::notify(ErrorStatus status, + const sp& preparedModel) { + if (status != ErrorStatus::NONE) { + const auto canonical = + validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + notifyInternal(NN_ERROR(canonical) << "preparedModel failed with " << toString(status)); + } else if (preparedModel == nullptr) { + notifyInternal(NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) + << "Returned preparedModel is nullptr"); + } else { + notifyInternal(convertPreparedModel(preparedModel)); + } + return Void(); +} + +void PreparedModelCallback::notifyAsDeadObject() { + notifyInternal(NN_ERROR(nn::ErrorStatus::DEAD_OBJECT) << "Dead object"); +} + +PreparedModelCallback::Data PreparedModelCallback::get() { + return mData.take(); +} + +void PreparedModelCallback::notifyInternal(PreparedModelCallback::Data result) { + mData.put(std::move(result)); +} + +// ExecutionCallback methods begin here + +Return ExecutionCallback::notify(ErrorStatus status) { + if (status != ErrorStatus::NONE) { + const auto canonical = + validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + notifyInternal(NN_ERROR(canonical) << "execute failed with " << toString(status)); + } else { + notifyInternal({}); + } + return Void(); +} + +void ExecutionCallback::notifyAsDeadObject() { + notifyInternal(NN_ERROR(nn::ErrorStatus::DEAD_OBJECT) << "Dead object"); +} + +ExecutionCallback::Data ExecutionCallback::get() { + return mData.take(); +} + +void ExecutionCallback::notifyInternal(ExecutionCallback::Data result) { + mData.put(std::move(result)); +} + +} // namespace android::hardware::neuralnetworks::V1_0::utils diff --git a/neuralnetworks/1.0/utils/src/Conversions.cpp b/neuralnetworks/1.0/utils/src/Conversions.cpp index 4a58f3b93c..f301065cf9 100644 --- a/neuralnetworks/1.0/utils/src/Conversions.cpp +++ b/neuralnetworks/1.0/utils/src/Conversions.cpp @@ -52,7 +52,7 @@ template using ConvertOutput = std::decay_t()).value())>; template -Result>> convert(const hidl_vec& arguments) { +GeneralResult>> convert(const hidl_vec& arguments) { std::vector> canonical; canonical.reserve(arguments.size()); for (const auto& argument : arguments) { @@ -63,30 +63,31 @@ Result>> convert(const hidl_vec& arguments } // anonymous namespace -Result convert(const hal::V1_0::OperandType& operandType) { +GeneralResult convert(const hal::V1_0::OperandType& operandType) { return static_cast(operandType); } -Result convert(const hal::V1_0::OperationType& operationType) { +GeneralResult convert(const hal::V1_0::OperationType& operationType) { return static_cast(operationType); } -Result convert(const hal::V1_0::OperandLifeTime& lifetime) { +GeneralResult convert(const hal::V1_0::OperandLifeTime& lifetime) { return static_cast(lifetime); } -Result convert(const hal::V1_0::DeviceStatus& deviceStatus) { +GeneralResult convert(const hal::V1_0::DeviceStatus& deviceStatus) { return static_cast(deviceStatus); } -Result convert(const hal::V1_0::PerformanceInfo& performanceInfo) { +GeneralResult convert( + const hal::V1_0::PerformanceInfo& performanceInfo) { return Capabilities::PerformanceInfo{ .execTime = performanceInfo.execTime, .powerUsage = performanceInfo.powerUsage, }; } -Result convert(const hal::V1_0::Capabilities& capabilities) { +GeneralResult convert(const hal::V1_0::Capabilities& capabilities) { const auto quantized8Performance = NN_TRY(convert(capabilities.quantized8Performance)); const auto float32Performance = NN_TRY(convert(capabilities.float32Performance)); @@ -100,7 +101,7 @@ Result convert(const hal::V1_0::Capabilities& capabilities) { }; } -Result convert(const hal::V1_0::DataLocation& location) { +GeneralResult convert(const hal::V1_0::DataLocation& location) { return DataLocation{ .poolIndex = location.poolIndex, .offset = location.offset, @@ -108,7 +109,7 @@ Result convert(const hal::V1_0::DataLocation& location) { }; } -Result convert(const hal::V1_0::Operand& operand) { +GeneralResult convert(const hal::V1_0::Operand& operand) { return Operand{ .type = NN_TRY(convert(operand.type)), .dimensions = operand.dimensions, @@ -119,7 +120,7 @@ Result convert(const hal::V1_0::Operand& operand) { }; } -Result convert(const hal::V1_0::Operation& operation) { +GeneralResult convert(const hal::V1_0::Operation& operation) { return Operation{ .type = NN_TRY(convert(operation.type)), .inputs = operation.inputs, @@ -127,15 +128,15 @@ Result convert(const hal::V1_0::Operation& operation) { }; } -Result convert(const hidl_vec& operandValues) { +GeneralResult convert(const hidl_vec& operandValues) { return Model::OperandValues(operandValues.data(), operandValues.size()); } -Result convert(const hidl_memory& memory) { +GeneralResult convert(const hidl_memory& memory) { return createSharedMemoryFromHidlMemory(memory); } -Result convert(const hal::V1_0::Model& model) { +GeneralResult convert(const hal::V1_0::Model& model) { auto operations = NN_TRY(convert(model.operations)); // Verify number of consumers. @@ -144,9 +145,9 @@ Result convert(const hal::V1_0::Model& model) { CHECK(model.operands.size() == numberOfConsumers.size()); for (size_t i = 0; i < model.operands.size(); ++i) { if (model.operands[i].numberOfConsumers != numberOfConsumers[i]) { - return NN_ERROR() << "Invalid numberOfConsumers for operand " << i << ", expected " - << numberOfConsumers[i] << " but found " - << model.operands[i].numberOfConsumers; + return NN_ERROR(ErrorStatus::GENERAL_FAILURE) + << "Invalid numberOfConsumers for operand " << i << ", expected " + << numberOfConsumers[i] << " but found " << model.operands[i].numberOfConsumers; } } @@ -164,7 +165,7 @@ Result convert(const hal::V1_0::Model& model) { }; } -Result convert(const hal::V1_0::RequestArgument& argument) { +GeneralResult convert(const hal::V1_0::RequestArgument& argument) { const auto lifetime = argument.hasNoValue ? Request::Argument::LifeTime::NO_VALUE : Request::Argument::LifeTime::POOL; return Request::Argument{ @@ -174,7 +175,7 @@ Result convert(const hal::V1_0::RequestArgument& argument) { }; } -Result convert(const hal::V1_0::Request& request) { +GeneralResult convert(const hal::V1_0::Request& request) { auto memories = NN_TRY(convert(request.pools)); std::vector pools; pools.reserve(memories.size()); @@ -187,7 +188,7 @@ Result convert(const hal::V1_0::Request& request) { }; } -Result convert(const hal::V1_0::ErrorStatus& status) { +GeneralResult convert(const hal::V1_0::ErrorStatus& status) { switch (status) { case hal::V1_0::ErrorStatus::NONE: case hal::V1_0::ErrorStatus::DEVICE_UNAVAILABLE: @@ -196,7 +197,8 @@ Result convert(const hal::V1_0::ErrorStatus& status) { case hal::V1_0::ErrorStatus::INVALID_ARGUMENT: return static_cast(status); } - return NN_ERROR() << "Invalid ErrorStatus " << underlyingType(status); + return NN_ERROR(ErrorStatus::GENERAL_FAILURE) + << "Invalid ErrorStatus " << underlyingType(status); } } // namespace android::nn @@ -208,7 +210,7 @@ template using ConvertOutput = std::decay_t()).value())>; template -nn::Result>> convert(const std::vector& arguments) { +nn::GeneralResult>> convert(const std::vector& arguments) { hidl_vec> halObject(arguments.size()); for (size_t i = 0; i < arguments.size(); ++i) { halObject[i] = NN_TRY(utils::convert(arguments[i])); @@ -218,33 +220,35 @@ nn::Result>> convert(const std::vector& argum } // anonymous namespace -nn::Result convert(const nn::OperandType& operandType) { +nn::GeneralResult convert(const nn::OperandType& operandType) { return static_cast(operandType); } -nn::Result convert(const nn::OperationType& operationType) { +nn::GeneralResult convert(const nn::OperationType& operationType) { return static_cast(operationType); } -nn::Result convert(const nn::Operand::LifeTime& lifetime) { +nn::GeneralResult convert(const nn::Operand::LifeTime& lifetime) { if (lifetime == nn::Operand::LifeTime::POINTER) { - return NN_ERROR() << "Model cannot be converted because it contains pointer-based memory"; + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) + << "Model cannot be converted because it contains pointer-based memory"; } return static_cast(lifetime); } -nn::Result convert(const nn::DeviceStatus& deviceStatus) { +nn::GeneralResult convert(const nn::DeviceStatus& deviceStatus) { return static_cast(deviceStatus); } -nn::Result convert(const nn::Capabilities::PerformanceInfo& performanceInfo) { +nn::GeneralResult convert( + const nn::Capabilities::PerformanceInfo& performanceInfo) { return PerformanceInfo{ .execTime = performanceInfo.execTime, .powerUsage = performanceInfo.powerUsage, }; } -nn::Result convert(const nn::Capabilities& capabilities) { +nn::GeneralResult convert(const nn::Capabilities& capabilities) { return Capabilities{ .float32Performance = NN_TRY(convert( capabilities.operandPerformance.lookup(nn::OperandType::TENSOR_FLOAT32))), @@ -253,7 +257,7 @@ nn::Result convert(const nn::Capabilities& capabilities) { }; } -nn::Result convert(const nn::DataLocation& location) { +nn::GeneralResult convert(const nn::DataLocation& location) { return DataLocation{ .poolIndex = location.poolIndex, .offset = location.offset, @@ -261,7 +265,7 @@ nn::Result convert(const nn::DataLocation& location) { }; } -nn::Result convert(const nn::Operand& operand) { +nn::GeneralResult convert(const nn::Operand& operand) { return Operand{ .type = NN_TRY(convert(operand.type)), .dimensions = operand.dimensions, @@ -273,7 +277,7 @@ nn::Result convert(const nn::Operand& operand) { }; } -nn::Result convert(const nn::Operation& operation) { +nn::GeneralResult convert(const nn::Operation& operation) { return Operation{ .type = NN_TRY(convert(operation.type)), .inputs = operation.inputs, @@ -281,20 +285,21 @@ nn::Result convert(const nn::Operation& operation) { }; } -nn::Result> convert(const nn::Model::OperandValues& operandValues) { +nn::GeneralResult> convert(const nn::Model::OperandValues& operandValues) { return hidl_vec(operandValues.data(), operandValues.data() + operandValues.size()); } -nn::Result convert(const nn::Memory& memory) { +nn::GeneralResult convert(const nn::Memory& memory) { const auto hidlMemory = hidl_memory(memory.name, memory.handle->handle(), memory.size); // Copy memory to force the native_handle_t to be copied. auto copiedMemory = hidlMemory; return copiedMemory; } -nn::Result convert(const nn::Model& model) { +nn::GeneralResult convert(const nn::Model& model) { if (!hal::utils::hasNoPointerData(model)) { - return NN_ERROR() << "Mdoel cannot be converted because it contains pointer-based memory"; + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) + << "Mdoel cannot be converted because it contains pointer-based memory"; } auto operands = NN_TRY(convert(model.main.operands)); @@ -317,9 +322,10 @@ nn::Result convert(const nn::Model& model) { }; } -nn::Result convert(const nn::Request::Argument& requestArgument) { +nn::GeneralResult convert(const nn::Request::Argument& requestArgument) { if (requestArgument.lifetime == nn::Request::Argument::LifeTime::POINTER) { - return NN_ERROR() << "Request cannot be converted because it contains pointer-based memory"; + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) + << "Request cannot be converted because it contains pointer-based memory"; } const bool hasNoValue = requestArgument.lifetime == nn::Request::Argument::LifeTime::NO_VALUE; return RequestArgument{ @@ -329,13 +335,14 @@ nn::Result convert(const nn::Request::Argument& requestArgument }; } -nn::Result convert(const nn::Request::MemoryPool& memoryPool) { +nn::GeneralResult convert(const nn::Request::MemoryPool& memoryPool) { return convert(std::get(memoryPool)); } -nn::Result convert(const nn::Request& request) { +nn::GeneralResult convert(const nn::Request& request) { if (!hal::utils::hasNoPointerData(request)) { - return NN_ERROR() << "Request cannot be converted because it contains pointer-based memory"; + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) + << "Request cannot be converted because it contains pointer-based memory"; } return Request{ @@ -345,7 +352,7 @@ nn::Result convert(const nn::Request& request) { }; } -nn::Result convert(const nn::ErrorStatus& status) { +nn::GeneralResult convert(const nn::ErrorStatus& status) { switch (status) { case nn::ErrorStatus::NONE: case nn::ErrorStatus::DEVICE_UNAVAILABLE: diff --git a/neuralnetworks/1.0/utils/src/Device.cpp b/neuralnetworks/1.0/utils/src/Device.cpp new file mode 100644 index 0000000000..8292f170c2 --- /dev/null +++ b/neuralnetworks/1.0/utils/src/Device.cpp @@ -0,0 +1,199 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Device.h" + +#include "Callbacks.h" +#include "Conversions.h" +#include "Utils.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::V1_0::utils { +namespace { + +nn::GeneralResult initCapabilities(V1_0::IDevice* device) { + CHECK(device != nullptr); + + nn::GeneralResult result = NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) + << "uninitialized"; + const auto cb = [&result](ErrorStatus status, const Capabilities& capabilities) { + if (status != ErrorStatus::NONE) { + const auto canonical = + validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + result = NN_ERROR(canonical) << "getCapabilities failed with " << toString(status); + } else { + result = validatedConvertToCanonical(capabilities); + } + }; + + const auto ret = device->getCapabilities(cb); + NN_TRY(hal::utils::handleTransportError(ret)); + + return result; +} + +} // namespace + +nn::GeneralResult> Device::create(std::string name, + sp device) { + if (name.empty()) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) + << "V1_0::utils::Device::create must have non-empty name"; + } + if (device == nullptr) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) + << "V1_0::utils::Device::create must have non-null device"; + } + + auto capabilities = NN_TRY(initCapabilities(device.get())); + + auto deathHandler = NN_TRY(hal::utils::DeathHandler::create(device)); + return std::make_shared(PrivateConstructorTag{}, std::move(name), + std::move(capabilities), std::move(device), + std::move(deathHandler)); +} + +Device::Device(PrivateConstructorTag /*tag*/, std::string name, nn::Capabilities capabilities, + sp device, hal::utils::DeathHandler deathHandler) + : kName(std::move(name)), + kCapabilities(std::move(capabilities)), + kDevice(std::move(device)), + kDeathHandler(std::move(deathHandler)) {} + +const std::string& Device::getName() const { + return kName; +} + +const std::string& Device::getVersionString() const { + return kVersionString; +} + +nn::Version Device::getFeatureLevel() const { + return nn::Version::ANDROID_OC_MR1; +} + +nn::DeviceType Device::getType() const { + return nn::DeviceType::OTHER; +} + +const std::vector& Device::getSupportedExtensions() const { + return kExtensions; +} + +const nn::Capabilities& Device::getCapabilities() const { + return kCapabilities; +} + +std::pair Device::getNumberOfCacheFilesNeeded() const { + return std::make_pair(/*numModelCache=*/0, /*numDataCache=*/0); +} + +nn::GeneralResult Device::wait() const { + const auto ret = kDevice->ping(); + return hal::utils::handleTransportError(ret); +} + +nn::GeneralResult> Device::getSupportedOperations(const nn::Model& model) const { + // Ensure that model is ready for IPC. + std::optional maybeModelInShared; + const nn::Model& modelInShared = + NN_TRY(hal::utils::flushDataFromPointerToShared(&model, &maybeModelInShared)); + + const auto hidlModel = NN_TRY(convert(modelInShared)); + + nn::GeneralResult> result = NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) + << "uninitialized"; + auto cb = [&result, &model](ErrorStatus status, const hidl_vec& supportedOperations) { + if (status != ErrorStatus::NONE) { + const auto canonical = + validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + result = NN_ERROR(canonical) + << "getSupportedOperations failed with " << toString(status); + } else if (supportedOperations.size() != model.main.operations.size()) { + result = NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) + << "getSupportedOperations returned vector of size " + << supportedOperations.size() << " but expected " + << model.main.operations.size(); + } else { + result = supportedOperations; + } + }; + + const auto ret = kDevice->getSupportedOperations(hidlModel, cb); + NN_TRY(hal::utils::handleTransportError(ret)); + + return result; +} + +nn::GeneralResult Device::prepareModel( + const nn::Model& model, nn::ExecutionPreference /*preference*/, nn::Priority /*priority*/, + nn::OptionalTimePoint /*deadline*/, const std::vector& /*modelCache*/, + const std::vector& /*dataCache*/, const nn::CacheToken& /*token*/) const { + // Ensure that model is ready for IPC. + std::optional maybeModelInShared; + const nn::Model& modelInShared = + NN_TRY(hal::utils::flushDataFromPointerToShared(&model, &maybeModelInShared)); + + const auto hidlModel = NN_TRY(convert(modelInShared)); + + const auto cb = sp::make(); + const auto scoped = kDeathHandler.protectCallback(cb.get()); + + const auto ret = kDevice->prepareModel(hidlModel, cb); + const auto status = NN_TRY(hal::utils::handleTransportError(ret)); + if (status != ErrorStatus::NONE) { + const auto canonical = + validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + return NN_ERROR(canonical) << "prepareModel failed with " << toString(status); + } + + return cb->get(); +} + +nn::GeneralResult Device::prepareModelFromCache( + nn::OptionalTimePoint /*deadline*/, const std::vector& /*modelCache*/, + const std::vector& /*dataCache*/, const nn::CacheToken& /*token*/) const { + return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) + << "IDevice::prepareModelFromCache not supported on 1.0 HAL service"; +} + +nn::GeneralResult Device::allocate( + const nn::BufferDesc& /*desc*/, + const std::vector& /*preparedModels*/, + const std::vector& /*inputRoles*/, + const std::vector& /*outputRoles*/) const { + return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) + << "IDevice::allocate not supported on 1.0 HAL service"; +} + +} // namespace android::hardware::neuralnetworks::V1_0::utils diff --git a/neuralnetworks/1.0/utils/src/PreparedModel.cpp b/neuralnetworks/1.0/utils/src/PreparedModel.cpp new file mode 100644 index 0000000000..11ccbe3221 --- /dev/null +++ b/neuralnetworks/1.0/utils/src/PreparedModel.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "PreparedModel.h" + +#include "Callbacks.h" +#include "Conversions.h" +#include "Utils.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::V1_0::utils { + +nn::GeneralResult> PreparedModel::create( + sp preparedModel) { + if (preparedModel == nullptr) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) + << "V1_0::utils::PreparedModel::create must have non-null preparedModel"; + } + + auto deathHandler = NN_TRY(hal::utils::DeathHandler::create(preparedModel)); + return std::make_shared(PrivateConstructorTag{}, std::move(preparedModel), + std::move(deathHandler)); +} + +PreparedModel::PreparedModel(PrivateConstructorTag /*tag*/, sp preparedModel, + hal::utils::DeathHandler deathHandler) + : kPreparedModel(std::move(preparedModel)), kDeathHandler(std::move(deathHandler)) {} + +nn::ExecutionResult, nn::Timing>> PreparedModel::execute( + const nn::Request& request, nn::MeasureTiming /*measure*/, + const nn::OptionalTimePoint& /*deadline*/, + const nn::OptionalTimeoutDuration& /*loopTimeoutDuration*/) const { + // Ensure that request is ready for IPC. + std::optional maybeRequestInShared; + const nn::Request& requestInShared = NN_TRY(hal::utils::makeExecutionFailure( + hal::utils::flushDataFromPointerToShared(&request, &maybeRequestInShared))); + + const auto hidlRequest = NN_TRY(hal::utils::makeExecutionFailure(convert(requestInShared))); + + const auto cb = sp::make(); + const auto scoped = kDeathHandler.protectCallback(cb.get()); + + const auto ret = kPreparedModel->execute(hidlRequest, cb); + const auto status = + NN_TRY(hal::utils::makeExecutionFailure(hal::utils::handleTransportError(ret))); + if (status != ErrorStatus::NONE) { + const auto canonical = + validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + return NN_ERROR(canonical) << "execute failed with " << toString(status); + } + + auto result = NN_TRY(cb->get()); + NN_TRY(hal::utils::makeExecutionFailure( + hal::utils::unflushDataFromSharedToPointer(request, maybeRequestInShared))); + + return result; +} + +nn::GeneralResult> +PreparedModel::executeFenced( + const nn::Request& /*request*/, const std::vector& /*waitFor*/, + nn::MeasureTiming /*measure*/, const nn::OptionalTimePoint& /*deadline*/, + const nn::OptionalTimeoutDuration& /*loopTimeoutDuration*/, + const nn::OptionalTimeoutDuration& /*timeoutDurationAfterFence*/) const { + return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) + << "IPreparedModel::executeFenced is not supported on 1.0 HAL service"; +} + +std::any PreparedModel::getUnderlyingResource() const { + sp resource = kPreparedModel; + return resource; +} + +} // namespace android::hardware::neuralnetworks::V1_0::utils diff --git a/neuralnetworks/1.0/utils/src/Service.cpp b/neuralnetworks/1.0/utils/src/Service.cpp new file mode 100644 index 0000000000..ec28b1d206 --- /dev/null +++ b/neuralnetworks/1.0/utils/src/Service.cpp @@ -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. + */ + +#include "Service.h" + +#include +#include +#include +#include +#include +#include "Device.h" + +namespace android::hardware::neuralnetworks::V1_0::utils { + +nn::GeneralResult getDevice(const std::string& name) { + hal::utils::ResilientDevice::Factory makeDevice = + [name](bool blocking) -> nn::GeneralResult { + auto service = blocking ? IDevice::getService(name) : IDevice::tryGetService(name); + if (service == nullptr) { + return NN_ERROR() << (blocking ? "getService" : "tryGetService") << " returned nullptr"; + } + return Device::create(name, std::move(service)); + }; + + return hal::utils::ResilientDevice::create(std::move(makeDevice)); +} + +} // namespace android::hardware::neuralnetworks::V1_0::utils diff --git a/neuralnetworks/1.1/utils/Android.bp b/neuralnetworks/1.1/utils/Android.bp index 85a32c5834..909575b634 100644 --- a/neuralnetworks/1.1/utils/Android.bp +++ b/neuralnetworks/1.1/utils/Android.bp @@ -20,6 +20,7 @@ cc_library_static { srcs: ["src/*"], local_include_dirs: ["include/nnapi/hal/1.1/"], export_include_dirs: ["include"], + cflags: ["-Wthread-safety"], static_libs: [ "neuralnetworks_types", "neuralnetworks_utils_hal_common", diff --git a/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Conversions.h b/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Conversions.h index d0c5397faf..16ddd53496 100644 --- a/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Conversions.h +++ b/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Conversions.h @@ -24,21 +24,22 @@ namespace android::nn { -Result convert(const hal::V1_1::OperationType& operationType); -Result convert(const hal::V1_1::Capabilities& capabilities); -Result convert(const hal::V1_1::Operation& operation); -Result convert(const hal::V1_1::Model& model); -Result convert(const hal::V1_1::ExecutionPreference& executionPreference); +GeneralResult convert(const hal::V1_1::OperationType& operationType); +GeneralResult convert(const hal::V1_1::Capabilities& capabilities); +GeneralResult convert(const hal::V1_1::Operation& operation); +GeneralResult convert(const hal::V1_1::Model& model); +GeneralResult convert( + const hal::V1_1::ExecutionPreference& executionPreference); } // namespace android::nn namespace android::hardware::neuralnetworks::V1_1::utils { -nn::Result convert(const nn::OperationType& operationType); -nn::Result convert(const nn::Capabilities& capabilities); -nn::Result convert(const nn::Operation& operation); -nn::Result convert(const nn::Model& model); -nn::Result convert(const nn::ExecutionPreference& executionPreference); +nn::GeneralResult convert(const nn::OperationType& operationType); +nn::GeneralResult convert(const nn::Capabilities& capabilities); +nn::GeneralResult convert(const nn::Operation& operation); +nn::GeneralResult convert(const nn::Model& model); +nn::GeneralResult convert(const nn::ExecutionPreference& executionPreference); } // namespace android::hardware::neuralnetworks::V1_1::utils diff --git a/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Device.h b/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Device.h new file mode 100644 index 0000000000..f55ac6cb6d --- /dev/null +++ b/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Device.h @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_1_UTILS_DEVICE_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_1_UTILS_DEVICE_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::V1_1::utils { + +class Device final : public nn::IDevice { + struct PrivateConstructorTag {}; + + public: + static nn::GeneralResult> create(std::string name, + sp device); + + Device(PrivateConstructorTag tag, std::string name, nn::Capabilities capabilities, + sp device, hal::utils::DeathHandler deathHandler); + + const std::string& getName() const override; + const std::string& getVersionString() const override; + nn::Version getFeatureLevel() const override; + nn::DeviceType getType() const override; + const std::vector& getSupportedExtensions() const override; + const nn::Capabilities& getCapabilities() const override; + std::pair getNumberOfCacheFilesNeeded() const override; + + nn::GeneralResult wait() const override; + + nn::GeneralResult> getSupportedOperations( + const nn::Model& model) const override; + + nn::GeneralResult prepareModel( + const nn::Model& model, nn::ExecutionPreference preference, nn::Priority priority, + nn::OptionalTimePoint deadline, const std::vector& modelCache, + const std::vector& dataCache, + const nn::CacheToken& token) const override; + + nn::GeneralResult prepareModelFromCache( + nn::OptionalTimePoint deadline, const std::vector& modelCache, + const std::vector& dataCache, + const nn::CacheToken& token) const override; + + nn::GeneralResult allocate( + const nn::BufferDesc& desc, const std::vector& preparedModels, + const std::vector& inputRoles, + const std::vector& outputRoles) const override; + + private: + const std::string kName; + const std::string kVersionString = "UNKNOWN"; + const std::vector kExtensions; + const nn::Capabilities kCapabilities; + const sp kDevice; + const hal::utils::DeathHandler kDeathHandler; +}; + +} // namespace android::hardware::neuralnetworks::V1_1::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_1_UTILS_DEVICE_H diff --git a/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Service.h b/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Service.h new file mode 100644 index 0000000000..a3ad3cfb2d --- /dev/null +++ b/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Service.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_1_UTILS_SERVICE_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_1_UTILS_SERVICE_H + +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::V1_1::utils { + +nn::GeneralResult getDevice(const std::string& name); + +} // namespace android::hardware::neuralnetworks::V1_1::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_1_UTILS_SERVICE_H diff --git a/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Utils.h b/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Utils.h index 6f9aa602d8..0fee628eb6 100644 --- a/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Utils.h +++ b/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Utils.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -33,10 +34,14 @@ constexpr auto kVersion = nn::Version::ANDROID_P; template nn::Result validate(const Type& halObject) { - const auto canonical = NN_TRY(nn::convert(halObject)); - const auto version = NN_TRY(nn::validate(canonical)); + const auto maybeCanonical = nn::convert(halObject); + if (!maybeCanonical.has_value()) { + return nn::error() << maybeCanonical.error().message; + } + const auto version = NN_TRY(nn::validate(maybeCanonical.value())); if (version > utils::kVersion) { - return NN_ERROR() << ""; + return NN_ERROR() << "Insufficient version: " << version << " vs required " + << utils::kVersion; } return {}; } @@ -53,9 +58,14 @@ bool valid(const Type& halObject) { template decltype(nn::convert(std::declval())) validatedConvertToCanonical(const Type& halObject) { auto canonical = NN_TRY(nn::convert(halObject)); - const auto version = NN_TRY(nn::validate(canonical)); + const auto maybeVersion = nn::validate(canonical); + if (!maybeVersion.has_value()) { + return nn::error() << maybeVersion.error(); + } + const auto version = maybeVersion.value(); if (version > utils::kVersion) { - return NN_ERROR() << ""; + return NN_ERROR() << "Insufficient version: " << version << " vs required " + << utils::kVersion; } return canonical; } diff --git a/neuralnetworks/1.1/utils/src/Conversions.cpp b/neuralnetworks/1.1/utils/src/Conversions.cpp index 7fee16b5f2..ffe0752c11 100644 --- a/neuralnetworks/1.1/utils/src/Conversions.cpp +++ b/neuralnetworks/1.1/utils/src/Conversions.cpp @@ -42,7 +42,7 @@ template using convertOutput = std::decay_t()).value())>; template -Result>> convert(const hidl_vec& arguments) { +GeneralResult>> convert(const hidl_vec& arguments) { std::vector> canonical; canonical.reserve(arguments.size()); for (const auto& argument : arguments) { @@ -53,11 +53,11 @@ Result>> convert(const hidl_vec& arguments } // anonymous namespace -Result convert(const hal::V1_1::OperationType& operationType) { +GeneralResult convert(const hal::V1_1::OperationType& operationType) { return static_cast(operationType); } -Result convert(const hal::V1_1::Capabilities& capabilities) { +GeneralResult convert(const hal::V1_1::Capabilities& capabilities) { const auto quantized8Performance = NN_TRY(convert(capabilities.quantized8Performance)); const auto float32Performance = NN_TRY(convert(capabilities.float32Performance)); const auto relaxedFloat32toFloat16Performance = @@ -73,7 +73,7 @@ Result convert(const hal::V1_1::Capabilities& capabilities) { }; } -Result convert(const hal::V1_1::Operation& operation) { +GeneralResult convert(const hal::V1_1::Operation& operation) { return Operation{ .type = NN_TRY(convert(operation.type)), .inputs = operation.inputs, @@ -81,7 +81,7 @@ Result convert(const hal::V1_1::Operation& operation) { }; } -Result convert(const hal::V1_1::Model& model) { +GeneralResult convert(const hal::V1_1::Model& model) { auto operations = NN_TRY(convert(model.operations)); // Verify number of consumers. @@ -90,9 +90,9 @@ Result convert(const hal::V1_1::Model& model) { CHECK(model.operands.size() == numberOfConsumers.size()); for (size_t i = 0; i < model.operands.size(); ++i) { if (model.operands[i].numberOfConsumers != numberOfConsumers[i]) { - return NN_ERROR() << "Invalid numberOfConsumers for operand " << i << ", expected " - << numberOfConsumers[i] << " but found " - << model.operands[i].numberOfConsumers; + return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) + << "Invalid numberOfConsumers for operand " << i << ", expected " + << numberOfConsumers[i] << " but found " << model.operands[i].numberOfConsumers; } } @@ -111,7 +111,8 @@ Result convert(const hal::V1_1::Model& model) { }; } -Result convert(const hal::V1_1::ExecutionPreference& executionPreference) { +GeneralResult convert( + const hal::V1_1::ExecutionPreference& executionPreference) { return static_cast(executionPreference); } @@ -122,20 +123,20 @@ namespace { using utils::convert; -nn::Result convert( +nn::GeneralResult convert( const nn::Capabilities::PerformanceInfo& performanceInfo) { return V1_0::utils::convert(performanceInfo); } -nn::Result convert(const nn::Operand& operand) { +nn::GeneralResult convert(const nn::Operand& operand) { return V1_0::utils::convert(operand); } -nn::Result> convert(const nn::Model::OperandValues& operandValues) { +nn::GeneralResult> convert(const nn::Model::OperandValues& operandValues) { return V1_0::utils::convert(operandValues); } -nn::Result convert(const nn::Memory& memory) { +nn::GeneralResult convert(const nn::Memory& memory) { return V1_0::utils::convert(memory); } @@ -143,7 +144,7 @@ template using convertOutput = std::decay_t()).value())>; template -nn::Result>> convert(const std::vector& arguments) { +nn::GeneralResult>> convert(const std::vector& arguments) { hidl_vec> halObject(arguments.size()); for (size_t i = 0; i < arguments.size(); ++i) { halObject[i] = NN_TRY(convert(arguments[i])); @@ -153,11 +154,11 @@ nn::Result>> convert(const std::vector& argum } // anonymous namespace -nn::Result convert(const nn::OperationType& operationType) { +nn::GeneralResult convert(const nn::OperationType& operationType) { return static_cast(operationType); } -nn::Result convert(const nn::Capabilities& capabilities) { +nn::GeneralResult convert(const nn::Capabilities& capabilities) { return Capabilities{ .float32Performance = NN_TRY(convert( capabilities.operandPerformance.lookup(nn::OperandType::TENSOR_FLOAT32))), @@ -168,7 +169,7 @@ nn::Result convert(const nn::Capabilities& capabilities) { }; } -nn::Result convert(const nn::Operation& operation) { +nn::GeneralResult convert(const nn::Operation& operation) { return Operation{ .type = NN_TRY(convert(operation.type)), .inputs = operation.inputs, @@ -176,9 +177,10 @@ nn::Result convert(const nn::Operation& operation) { }; } -nn::Result convert(const nn::Model& model) { +nn::GeneralResult convert(const nn::Model& model) { if (!hal::utils::hasNoPointerData(model)) { - return NN_ERROR() << "Mdoel cannot be converted because it contains pointer-based memory"; + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) + << "Mdoel cannot be converted because it contains pointer-based memory"; } auto operands = NN_TRY(convert(model.main.operands)); @@ -202,7 +204,7 @@ nn::Result convert(const nn::Model& model) { }; } -nn::Result convert(const nn::ExecutionPreference& executionPreference) { +nn::GeneralResult convert(const nn::ExecutionPreference& executionPreference) { return static_cast(executionPreference); } diff --git a/neuralnetworks/1.1/utils/src/Device.cpp b/neuralnetworks/1.1/utils/src/Device.cpp new file mode 100644 index 0000000000..03b0d6eb8e --- /dev/null +++ b/neuralnetworks/1.1/utils/src/Device.cpp @@ -0,0 +1,202 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Device.h" + +#include "Conversions.h" +#include "Utils.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::V1_1::utils { +namespace { + +nn::GeneralResult initCapabilities(V1_1::IDevice* device) { + CHECK(device != nullptr); + + nn::GeneralResult result = NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) + << "uninitialized"; + const auto cb = [&result](V1_0::ErrorStatus status, const Capabilities& capabilities) { + if (status != V1_0::ErrorStatus::NONE) { + const auto canonical = + validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + result = NN_ERROR(canonical) << "getCapabilities_1_1 failed with " << toString(status); + } else { + result = validatedConvertToCanonical(capabilities); + } + }; + + const auto ret = device->getCapabilities_1_1(cb); + NN_TRY(hal::utils::handleTransportError(ret)); + + return result; +} + +} // namespace + +nn::GeneralResult> Device::create(std::string name, + sp device) { + if (name.empty()) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) + << "V1_1::utils::Device::create must have non-empty name"; + } + if (device == nullptr) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) + << "V1_1::utils::Device::create must have non-null device"; + } + + auto capabilities = NN_TRY(initCapabilities(device.get())); + + auto deathHandler = NN_TRY(hal::utils::DeathHandler::create(device)); + return std::make_shared(PrivateConstructorTag{}, std::move(name), + std::move(capabilities), std::move(device), + std::move(deathHandler)); +} + +Device::Device(PrivateConstructorTag /*tag*/, std::string name, nn::Capabilities capabilities, + sp device, hal::utils::DeathHandler deathHandler) + : kName(std::move(name)), + kCapabilities(std::move(capabilities)), + kDevice(std::move(device)), + kDeathHandler(std::move(deathHandler)) {} + +const std::string& Device::getName() const { + return kName; +} + +const std::string& Device::getVersionString() const { + return kVersionString; +} + +nn::Version Device::getFeatureLevel() const { + return nn::Version::ANDROID_P; +} + +nn::DeviceType Device::getType() const { + return nn::DeviceType::UNKNOWN; +} + +const std::vector& Device::getSupportedExtensions() const { + return kExtensions; +} + +const nn::Capabilities& Device::getCapabilities() const { + return kCapabilities; +} + +std::pair Device::getNumberOfCacheFilesNeeded() const { + return std::make_pair(/*numModelCache=*/0, /*numDataCache=*/0); +} + +nn::GeneralResult Device::wait() const { + const auto ret = kDevice->ping(); + return hal::utils::handleTransportError(ret); +} + +nn::GeneralResult> Device::getSupportedOperations(const nn::Model& model) const { + // Ensure that model is ready for IPC. + std::optional maybeModelInShared; + const nn::Model& modelInShared = + NN_TRY(hal::utils::flushDataFromPointerToShared(&model, &maybeModelInShared)); + + const auto hidlModel = NN_TRY(convert(modelInShared)); + + nn::GeneralResult> result = NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) + << "uninitialized"; + auto cb = [&result, &model](V1_0::ErrorStatus status, + const hidl_vec& supportedOperations) { + if (status != V1_0::ErrorStatus::NONE) { + const auto canonical = + validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + result = NN_ERROR(canonical) + << "getSupportedOperations_1_1 failed with " << toString(status); + } else if (supportedOperations.size() != model.main.operations.size()) { + result = NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) + << "getSupportedOperations_1_1 returned vector of size " + << supportedOperations.size() << " but expected " + << model.main.operations.size(); + } else { + result = supportedOperations; + } + }; + + const auto ret = kDevice->getSupportedOperations_1_1(hidlModel, cb); + NN_TRY(hal::utils::handleTransportError(ret)); + + return result; +} + +nn::GeneralResult Device::prepareModel( + const nn::Model& model, nn::ExecutionPreference preference, nn::Priority /*priority*/, + nn::OptionalTimePoint /*deadline*/, const std::vector& /*modelCache*/, + const std::vector& /*dataCache*/, const nn::CacheToken& /*token*/) const { + // Ensure that model is ready for IPC. + std::optional maybeModelInShared; + const nn::Model& modelInShared = + NN_TRY(hal::utils::flushDataFromPointerToShared(&model, &maybeModelInShared)); + + const auto hidlModel = NN_TRY(convert(modelInShared)); + const auto hidlPreference = NN_TRY(convert(preference)); + + const auto cb = sp::make(); + const auto scoped = kDeathHandler.protectCallback(cb.get()); + + const auto ret = kDevice->prepareModel_1_1(hidlModel, hidlPreference, cb); + const auto status = NN_TRY(hal::utils::handleTransportError(ret)); + if (status != V1_0::ErrorStatus::NONE) { + const auto canonical = + validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + return NN_ERROR(canonical) << "prepareModel failed with " << toString(status); + } + + return cb->get(); +} + +nn::GeneralResult Device::prepareModelFromCache( + nn::OptionalTimePoint /*deadline*/, const std::vector& /*modelCache*/, + const std::vector& /*dataCache*/, const nn::CacheToken& /*token*/) const { + return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) + << "IDevice::prepareModelFromCache not supported on 1.1 HAL service"; +} + +nn::GeneralResult Device::allocate( + const nn::BufferDesc& /*desc*/, + const std::vector& /*preparedModels*/, + const std::vector& /*inputRoles*/, + const std::vector& /*outputRoles*/) const { + return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) + << "IDevice::allocate not supported on 1.1 HAL service"; +} + +} // namespace android::hardware::neuralnetworks::V1_1::utils diff --git a/neuralnetworks/1.1/utils/src/Service.cpp b/neuralnetworks/1.1/utils/src/Service.cpp new file mode 100644 index 0000000000..e2d3240647 --- /dev/null +++ b/neuralnetworks/1.1/utils/src/Service.cpp @@ -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. + */ + +#include "Service.h" + +#include +#include +#include +#include +#include +#include "Device.h" + +namespace android::hardware::neuralnetworks::V1_1::utils { + +nn::GeneralResult getDevice(const std::string& name) { + hal::utils::ResilientDevice::Factory makeDevice = + [name](bool blocking) -> nn::GeneralResult { + auto service = blocking ? IDevice::getService(name) : IDevice::tryGetService(name); + if (service == nullptr) { + return NN_ERROR() << (blocking ? "getService" : "tryGetService") << " returned nullptr"; + } + return Device::create(name, std::move(service)); + }; + + return hal::utils::ResilientDevice::create(std::move(makeDevice)); +} + +} // namespace android::hardware::neuralnetworks::V1_1::utils diff --git a/neuralnetworks/1.2/utils/Android.bp b/neuralnetworks/1.2/utils/Android.bp index a1dd3d0b0d..22e8659557 100644 --- a/neuralnetworks/1.2/utils/Android.bp +++ b/neuralnetworks/1.2/utils/Android.bp @@ -20,6 +20,7 @@ cc_library_static { srcs: ["src/*"], local_include_dirs: ["include/nnapi/hal/1.2/"], export_include_dirs: ["include"], + cflags: ["-Wthread-safety"], static_libs: [ "neuralnetworks_types", "neuralnetworks_utils_hal_common", diff --git a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Callbacks.h b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Callbacks.h new file mode 100644 index 0000000000..bc7d92ac83 --- /dev/null +++ b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Callbacks.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_2_UTILS_CALLBACKS_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_2_UTILS_CALLBACKS_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::V1_2::utils { + +class PreparedModelCallback final : public IPreparedModelCallback, + public hal::utils::IProtectedCallback { + public: + using Data = nn::GeneralResult; + + Return notify(V1_0::ErrorStatus status, + const sp& preparedModel) override; + Return notify_1_2(V1_0::ErrorStatus status, + const sp& preparedModel) override; + + void notifyAsDeadObject() override; + + Data get(); + + private: + void notifyInternal(Data result); + + hal::utils::TransferValue mData; +}; + +class ExecutionCallback final : public IExecutionCallback, public hal::utils::IProtectedCallback { + public: + using Data = nn::ExecutionResult, nn::Timing>>; + + Return notify(V1_0::ErrorStatus status) override; + Return notify_1_2(V1_0::ErrorStatus status, const hidl_vec& outputShapes, + const Timing& timing) override; + + void notifyAsDeadObject() override; + + Data get(); + + private: + void notifyInternal(Data result); + + hal::utils::TransferValue mData; +}; + +} // namespace android::hardware::neuralnetworks::V1_2::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_2_UTILS_CALLBACKS_H diff --git a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Conversions.h b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Conversions.h index 81bf7928f6..e6de011f9c 100644 --- a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Conversions.h +++ b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Conversions.h @@ -24,62 +24,64 @@ namespace android::nn { -Result convert(const hal::V1_2::OperandType& operandType); -Result convert(const hal::V1_2::OperationType& operationType); -Result convert(const hal::V1_2::DeviceType& deviceType); -Result convert(const hal::V1_2::Capabilities& capabilities); -Result convert( +GeneralResult convert(const hal::V1_2::OperandType& operandType); +GeneralResult convert(const hal::V1_2::OperationType& operationType); +GeneralResult convert(const hal::V1_2::DeviceType& deviceType); +GeneralResult convert(const hal::V1_2::Capabilities& capabilities); +GeneralResult convert( const hal::V1_2::Capabilities::OperandPerformance& operandPerformance); -Result convert(const hal::V1_2::Operation& operation); -Result convert( +GeneralResult convert(const hal::V1_2::Operation& operation); +GeneralResult convert( const hal::V1_2::SymmPerChannelQuantParams& symmPerChannelQuantParams); -Result convert(const hal::V1_2::Operand& operand); -Result convert(const hal::V1_2::Operand::ExtraParams& extraParams); -Result convert(const hal::V1_2::Model& model); -Result convert( +GeneralResult convert(const hal::V1_2::Operand& operand); +GeneralResult convert(const hal::V1_2::Operand::ExtraParams& extraParams); +GeneralResult convert(const hal::V1_2::Model& model); +GeneralResult convert( const hal::V1_2::Model::ExtensionNameAndPrefix& extensionNameAndPrefix); -Result convert(const hal::V1_2::OutputShape& outputShape); -Result convert(const hal::V1_2::MeasureTiming& measureTiming); -Result convert(const hal::V1_2::Timing& timing); -Result convert(const hal::V1_2::Extension& extension); -Result convert( +GeneralResult convert(const hal::V1_2::OutputShape& outputShape); +GeneralResult convert(const hal::V1_2::MeasureTiming& measureTiming); +GeneralResult convert(const hal::V1_2::Timing& timing); +GeneralResult convert(const hal::V1_2::Extension& extension); +GeneralResult convert( const hal::V1_2::Extension::OperandTypeInformation& operandTypeInformation); -Result convert(const hardware::hidl_handle& handle); +GeneralResult convert(const hardware::hidl_handle& handle); -Result> convert(const hardware::hidl_vec& extensions); -Result> convert(const hardware::hidl_vec& handles); -Result> convert( +GeneralResult> convert( + const hardware::hidl_vec& extensions); +GeneralResult> convert( + const hardware::hidl_vec& handles); +GeneralResult> convert( const hardware::hidl_vec& outputShapes); } // namespace android::nn namespace android::hardware::neuralnetworks::V1_2::utils { -nn::Result convert(const nn::OperandType& operandType); -nn::Result convert(const nn::OperationType& operationType); -nn::Result convert(const nn::DeviceType& deviceType); -nn::Result convert(const nn::Capabilities& capabilities); -nn::Result convert( +nn::GeneralResult convert(const nn::OperandType& operandType); +nn::GeneralResult convert(const nn::OperationType& operationType); +nn::GeneralResult convert(const nn::DeviceType& deviceType); +nn::GeneralResult convert(const nn::Capabilities& capabilities); +nn::GeneralResult convert( const nn::Capabilities::OperandPerformance& operandPerformance); -nn::Result convert(const nn::Operation& operation); -nn::Result convert( +nn::GeneralResult convert(const nn::Operation& operation); +nn::GeneralResult convert( const nn::Operand::SymmPerChannelQuantParams& symmPerChannelQuantParams); -nn::Result convert(const nn::Operand& operand); -nn::Result convert(const nn::Operand::ExtraParams& extraParams); -nn::Result convert(const nn::Model& model); -nn::Result convert( +nn::GeneralResult convert(const nn::Operand& operand); +nn::GeneralResult convert(const nn::Operand::ExtraParams& extraParams); +nn::GeneralResult convert(const nn::Model& model); +nn::GeneralResult convert( const nn::Model::ExtensionNameAndPrefix& extensionNameAndPrefix); -nn::Result convert(const nn::OutputShape& outputShape); -nn::Result convert(const nn::MeasureTiming& measureTiming); -nn::Result convert(const nn::Timing& timing); -nn::Result convert(const nn::Extension& extension); -nn::Result convert( +nn::GeneralResult convert(const nn::OutputShape& outputShape); +nn::GeneralResult convert(const nn::MeasureTiming& measureTiming); +nn::GeneralResult convert(const nn::Timing& timing); +nn::GeneralResult convert(const nn::Extension& extension); +nn::GeneralResult convert( const nn::Extension::OperandTypeInformation& operandTypeInformation); -nn::Result convert(const nn::NativeHandle& handle); +nn::GeneralResult convert(const nn::NativeHandle& handle); -nn::Result> convert(const std::vector& extensions); -nn::Result> convert(const std::vector& handles); -nn::Result> convert(const std::vector& outputShapes); +nn::GeneralResult> convert(const std::vector& extensions); +nn::GeneralResult> convert(const std::vector& handles); +nn::GeneralResult> convert(const std::vector& outputShapes); } // namespace android::hardware::neuralnetworks::V1_2::utils diff --git a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Device.h b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Device.h new file mode 100644 index 0000000000..eb317b12cf --- /dev/null +++ b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Device.h @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_2_UTILS_DEVICE_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_2_UTILS_DEVICE_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::V1_2::utils { + +nn::GeneralResult initVersionString(V1_2::IDevice* device); +nn::GeneralResult initDeviceType(V1_2::IDevice* device); +nn::GeneralResult> initExtensions(V1_2::IDevice* device); +nn::GeneralResult initCapabilities(V1_2::IDevice* device); +nn::GeneralResult> initNumberOfCacheFilesNeeded( + V1_2::IDevice* device); + +class Device final : public nn::IDevice { + struct PrivateConstructorTag {}; + + public: + static nn::GeneralResult> create(std::string name, + sp device); + + Device(PrivateConstructorTag tag, std::string name, std::string versionString, + nn::DeviceType deviceType, std::vector extensions, + nn::Capabilities capabilities, std::pair numberOfCacheFilesNeeded, + sp device, hal::utils::DeathHandler deathHandler); + + const std::string& getName() const override; + const std::string& getVersionString() const override; + nn::Version getFeatureLevel() const override; + nn::DeviceType getType() const override; + const std::vector& getSupportedExtensions() const override; + const nn::Capabilities& getCapabilities() const override; + std::pair getNumberOfCacheFilesNeeded() const override; + + nn::GeneralResult wait() const override; + + nn::GeneralResult> getSupportedOperations( + const nn::Model& model) const override; + + nn::GeneralResult prepareModel( + const nn::Model& model, nn::ExecutionPreference preference, nn::Priority priority, + nn::OptionalTimePoint deadline, const std::vector& modelCache, + const std::vector& dataCache, + const nn::CacheToken& token) const override; + + nn::GeneralResult prepareModelFromCache( + nn::OptionalTimePoint deadline, const std::vector& modelCache, + const std::vector& dataCache, + const nn::CacheToken& token) const override; + + nn::GeneralResult allocate( + const nn::BufferDesc& desc, const std::vector& preparedModels, + const std::vector& inputRoles, + const std::vector& outputRoles) const override; + + private: + const std::string kName; + const std::string kVersionString; + const nn::DeviceType kDeviceType; + const std::vector kExtensions; + const nn::Capabilities kCapabilities; + const std::pair kNumberOfCacheFilesNeeded; + const sp kDevice; + const hal::utils::DeathHandler kDeathHandler; +}; + +} // namespace android::hardware::neuralnetworks::V1_2::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_2_UTILS_DEVICE_H diff --git a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/PreparedModel.h b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/PreparedModel.h new file mode 100644 index 0000000000..65e1e8aa3f --- /dev/null +++ b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/PreparedModel.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_2_UTILS_PREPARED_MODEL_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_2_UTILS_PREPARED_MODEL_H + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::V1_2::utils { + +class PreparedModel final : public nn::IPreparedModel { + struct PrivateConstructorTag {}; + + public: + static nn::GeneralResult> create( + sp preparedModel); + + PreparedModel(PrivateConstructorTag tag, sp preparedModel, + hal::utils::DeathHandler deathHandler); + + nn::ExecutionResult, nn::Timing>> execute( + const nn::Request& request, nn::MeasureTiming measure, + const nn::OptionalTimePoint& deadline, + const nn::OptionalTimeoutDuration& loopTimeoutDuration) const override; + + nn::GeneralResult> executeFenced( + const nn::Request& request, const std::vector& waitFor, + nn::MeasureTiming measure, const nn::OptionalTimePoint& deadline, + const nn::OptionalTimeoutDuration& loopTimeoutDuration, + const nn::OptionalTimeoutDuration& timeoutDurationAfterFence) const override; + + std::any getUnderlyingResource() const override; + + private: + nn::ExecutionResult, nn::Timing>> executeSynchronously( + const V1_0::Request& request, MeasureTiming measure) const; + nn::ExecutionResult, nn::Timing>> executeAsynchronously( + const V1_0::Request& request, MeasureTiming measure) const; + + const sp kPreparedModel; + const hal::utils::DeathHandler kDeathHandler; +}; + +} // namespace android::hardware::neuralnetworks::V1_2::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_2_UTILS_PREPARED_MODEL_H diff --git a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Service.h b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Service.h new file mode 100644 index 0000000000..44f004f034 --- /dev/null +++ b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Service.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_2_UTILS_SERVICE_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_2_UTILS_SERVICE_H + +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::V1_2::utils { + +nn::GeneralResult getDevice(const std::string& name); + +} // namespace android::hardware::neuralnetworks::V1_2::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_2_UTILS_SERVICE_H diff --git a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Utils.h b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Utils.h index b1c2f1a81a..a9a6baeccc 100644 --- a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Utils.h +++ b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Utils.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -38,10 +39,14 @@ constexpr auto kVersion = nn::Version::ANDROID_Q; template nn::Result validate(const Type& halObject) { - const auto canonical = NN_TRY(nn::convert(halObject)); - const auto version = NN_TRY(nn::validate(canonical)); + const auto maybeCanonical = nn::convert(halObject); + if (!maybeCanonical.has_value()) { + return nn::error() << maybeCanonical.error().message; + } + const auto version = NN_TRY(nn::validate(maybeCanonical.value())); if (version > utils::kVersion) { - return NN_ERROR() << ""; + return NN_ERROR() << "Insufficient version: " << version << " vs required " + << utils::kVersion; } return {}; } @@ -58,9 +63,14 @@ bool valid(const Type& halObject) { template decltype(nn::convert(std::declval())) validatedConvertToCanonical(const Type& halObject) { auto canonical = NN_TRY(nn::convert(halObject)); - const auto version = NN_TRY(nn::validate(canonical)); + const auto maybeVersion = nn::validate(canonical); + if (!maybeVersion.has_value()) { + return nn::error() << maybeVersion.error(); + } + const auto version = maybeVersion.value(); if (version > utils::kVersion) { - return NN_ERROR() << ""; + return NN_ERROR() << "Insufficient version: " << version << " vs required " + << utils::kVersion; } return canonical; } diff --git a/neuralnetworks/1.2/utils/src/Callbacks.cpp b/neuralnetworks/1.2/utils/src/Callbacks.cpp new file mode 100644 index 0000000000..cb739f0eeb --- /dev/null +++ b/neuralnetworks/1.2/utils/src/Callbacks.cpp @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Callbacks.h" + +#include "Conversions.h" +#include "PreparedModel.h" +#include "Utils.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace android::hardware::neuralnetworks::V1_2::utils { +namespace { + +nn::GeneralResult convertPreparedModel( + const sp& preparedModel) { + return NN_TRY(V1_0::utils::PreparedModel::create(preparedModel)); +} + +nn::GeneralResult convertPreparedModel( + const sp& preparedModel) { + return NN_TRY(utils::PreparedModel::create(preparedModel)); +} + +nn::GeneralResult, nn::Timing>> +convertExecutionGeneralResultsHelper(const hidl_vec& outputShapes, + const Timing& timing) { + return std::make_pair(NN_TRY(validatedConvertToCanonical(outputShapes)), + NN_TRY(validatedConvertToCanonical(timing))); +} + +nn::ExecutionResult, nn::Timing>> +convertExecutionGeneralResults(const hidl_vec& outputShapes, const Timing& timing) { + return hal::utils::makeExecutionFailure( + convertExecutionGeneralResultsHelper(outputShapes, timing)); +} + +} // namespace + +Return PreparedModelCallback::notify(V1_0::ErrorStatus status, + const sp& preparedModel) { + if (status != V1_0::ErrorStatus::NONE) { + const auto canonical = + validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + notifyInternal(NN_ERROR(canonical) << "preparedModel failed with " << toString(status)); + } else if (preparedModel == nullptr) { + notifyInternal(NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) + << "Returned preparedModel is nullptr"); + } else { + notifyInternal(convertPreparedModel(preparedModel)); + } + return Void(); +} + +Return PreparedModelCallback::notify_1_2(V1_0::ErrorStatus status, + const sp& preparedModel) { + if (status != V1_0::ErrorStatus::NONE) { + const auto canonical = + validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + notifyInternal(NN_ERROR(canonical) << "preparedModel failed with " << toString(status)); + } else if (preparedModel == nullptr) { + notifyInternal(NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) + << "Returned preparedModel is nullptr"); + } else { + notifyInternal(convertPreparedModel(preparedModel)); + } + return Void(); +} + +void PreparedModelCallback::notifyAsDeadObject() { + notifyInternal(NN_ERROR(nn::ErrorStatus::DEAD_OBJECT) << "Dead object"); +} + +PreparedModelCallback::Data PreparedModelCallback::get() { + return mData.take(); +} + +void PreparedModelCallback::notifyInternal(PreparedModelCallback::Data result) { + mData.put(std::move(result)); +} + +// ExecutionCallback methods begin here + +Return ExecutionCallback::notify(V1_0::ErrorStatus status) { + if (status != V1_0::ErrorStatus::NONE) { + const auto canonical = + validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + notifyInternal(NN_ERROR(canonical) << "execute failed with " << toString(status)); + } else { + notifyInternal({}); + } + return Void(); +} + +Return ExecutionCallback::notify_1_2(V1_0::ErrorStatus status, + const hidl_vec& outputShapes, + const Timing& timing) { + if (status != V1_0::ErrorStatus::NONE) { + const auto canonical = + validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + notifyInternal(NN_ERROR(canonical) << "execute failed with " << toString(status)); + } else { + notifyInternal(convertExecutionGeneralResults(outputShapes, timing)); + } + return Void(); +} + +void ExecutionCallback::notifyAsDeadObject() { + notifyInternal(NN_ERROR(nn::ErrorStatus::DEAD_OBJECT) << "Dead object"); +} + +ExecutionCallback::Data ExecutionCallback::get() { + return mData.take(); +} + +void ExecutionCallback::notifyInternal(ExecutionCallback::Data result) { + mData.put(std::move(result)); +} + +} // namespace android::hardware::neuralnetworks::V1_2::utils diff --git a/neuralnetworks/1.2/utils/src/Conversions.cpp b/neuralnetworks/1.2/utils/src/Conversions.cpp index fed314b7c1..378719afc9 100644 --- a/neuralnetworks/1.2/utils/src/Conversions.cpp +++ b/neuralnetworks/1.2/utils/src/Conversions.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -78,7 +79,7 @@ template using ConvertOutput = std::decay_t()).value())>; template -Result>> convertVec(const hidl_vec& arguments) { +GeneralResult>> convertVec(const hidl_vec& arguments) { std::vector> canonical; canonical.reserve(arguments.size()); for (const auto& argument : arguments) { @@ -88,25 +89,25 @@ Result>> convertVec(const hidl_vec& argume } template -Result>> convert(const hidl_vec& arguments) { +GeneralResult>> convert(const hidl_vec& arguments) { return convertVec(arguments); } } // anonymous namespace -Result convert(const hal::V1_2::OperandType& operandType) { +GeneralResult convert(const hal::V1_2::OperandType& operandType) { return static_cast(operandType); } -Result convert(const hal::V1_2::OperationType& operationType) { +GeneralResult convert(const hal::V1_2::OperationType& operationType) { return static_cast(operationType); } -Result convert(const hal::V1_2::DeviceType& deviceType) { +GeneralResult convert(const hal::V1_2::DeviceType& deviceType) { return static_cast(deviceType); } -Result convert(const hal::V1_2::Capabilities& capabilities) { +GeneralResult convert(const hal::V1_2::Capabilities& capabilities) { const bool validOperandTypes = std::all_of( capabilities.operandPerformance.begin(), capabilities.operandPerformance.end(), [](const hal::V1_2::Capabilities::OperandPerformance& operandPerformance) { @@ -114,7 +115,7 @@ Result convert(const hal::V1_2::Capabilities& capabilities) { return !maybeType.has_value() ? false : validOperandType(maybeType.value()); }); if (!validOperandTypes) { - return NN_ERROR() + return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "Invalid OperandType when converting OperandPerformance in Capabilities"; } @@ -124,8 +125,9 @@ Result convert(const hal::V1_2::Capabilities& capabilities) { NN_TRY(convert(capabilities.relaxedFloat32toFloat16PerformanceTensor)); auto operandPerformance = NN_TRY(convert(capabilities.operandPerformance)); - auto table = - NN_TRY(Capabilities::OperandPerformanceTable::create(std::move(operandPerformance))); + auto table = NN_TRY(hal::utils::makeGeneralFailure( + Capabilities::OperandPerformanceTable::create(std::move(operandPerformance)), + nn::ErrorStatus::GENERAL_FAILURE)); return Capabilities{ .relaxedFloat32toFloat16PerformanceScalar = relaxedFloat32toFloat16PerformanceScalar, @@ -134,7 +136,7 @@ Result convert(const hal::V1_2::Capabilities& capabilities) { }; } -Result convert( +GeneralResult convert( const hal::V1_2::Capabilities::OperandPerformance& operandPerformance) { return Capabilities::OperandPerformance{ .type = NN_TRY(convert(operandPerformance.type)), @@ -142,7 +144,7 @@ Result convert( }; } -Result convert(const hal::V1_2::Operation& operation) { +GeneralResult convert(const hal::V1_2::Operation& operation) { return Operation{ .type = NN_TRY(convert(operation.type)), .inputs = operation.inputs, @@ -150,7 +152,7 @@ Result convert(const hal::V1_2::Operation& operation) { }; } -Result convert( +GeneralResult convert( const hal::V1_2::SymmPerChannelQuantParams& symmPerChannelQuantParams) { return Operand::SymmPerChannelQuantParams{ .scales = symmPerChannelQuantParams.scales, @@ -158,7 +160,7 @@ Result convert( }; } -Result convert(const hal::V1_2::Operand& operand) { +GeneralResult convert(const hal::V1_2::Operand& operand) { return Operand{ .type = NN_TRY(convert(operand.type)), .dimensions = operand.dimensions, @@ -170,7 +172,7 @@ Result convert(const hal::V1_2::Operand& operand) { }; } -Result convert(const hal::V1_2::Operand::ExtraParams& extraParams) { +GeneralResult convert(const hal::V1_2::Operand::ExtraParams& extraParams) { using Discriminator = hal::V1_2::Operand::ExtraParams::hidl_discriminator; switch (extraParams.getDiscriminator()) { case Discriminator::none: @@ -180,11 +182,12 @@ Result convert(const hal::V1_2::Operand::ExtraParams& extr case Discriminator::extension: return extraParams.extension(); } - return NN_ERROR() << "Unrecognized Operand::ExtraParams discriminator: " - << underlyingType(extraParams.getDiscriminator()); + return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) + << "Unrecognized Operand::ExtraParams discriminator: " + << underlyingType(extraParams.getDiscriminator()); } -Result convert(const hal::V1_2::Model& model) { +GeneralResult convert(const hal::V1_2::Model& model) { auto operations = NN_TRY(convert(model.operations)); // Verify number of consumers. @@ -193,9 +196,9 @@ Result convert(const hal::V1_2::Model& model) { CHECK(model.operands.size() == numberOfConsumers.size()); for (size_t i = 0; i < model.operands.size(); ++i) { if (model.operands[i].numberOfConsumers != numberOfConsumers[i]) { - return NN_ERROR() << "Invalid numberOfConsumers for operand " << i << ", expected " - << numberOfConsumers[i] << " but found " - << model.operands[i].numberOfConsumers; + return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) + << "Invalid numberOfConsumers for operand " << i << ", expected " + << numberOfConsumers[i] << " but found " << model.operands[i].numberOfConsumers; } } @@ -215,7 +218,7 @@ Result convert(const hal::V1_2::Model& model) { }; } -Result convert( +GeneralResult convert( const hal::V1_2::Model::ExtensionNameAndPrefix& extensionNameAndPrefix) { return Model::ExtensionNameAndPrefix{ .name = extensionNameAndPrefix.name, @@ -223,29 +226,29 @@ Result convert( }; } -Result convert(const hal::V1_2::OutputShape& outputShape) { +GeneralResult convert(const hal::V1_2::OutputShape& outputShape) { return OutputShape{ .dimensions = outputShape.dimensions, .isSufficient = outputShape.isSufficient, }; } -Result convert(const hal::V1_2::MeasureTiming& measureTiming) { +GeneralResult convert(const hal::V1_2::MeasureTiming& measureTiming) { return static_cast(measureTiming); } -Result convert(const hal::V1_2::Timing& timing) { +GeneralResult convert(const hal::V1_2::Timing& timing) { return Timing{.timeOnDevice = timing.timeOnDevice, .timeInDriver = timing.timeInDriver}; } -Result convert(const hal::V1_2::Extension& extension) { +GeneralResult convert(const hal::V1_2::Extension& extension) { return Extension{ .name = extension.name, .operandTypes = NN_TRY(convert(extension.operandTypes)), }; } -Result convert( +GeneralResult convert( const hal::V1_2::Extension::OperandTypeInformation& operandTypeInformation) { return Extension::OperandTypeInformation{ .type = operandTypeInformation.type, @@ -254,20 +257,21 @@ Result convert( }; } -Result convert(const hidl_handle& handle) { +GeneralResult convert(const hidl_handle& handle) { auto* cloned = native_handle_clone(handle.getNativeHandle()); return ::android::NativeHandle::create(cloned, /*ownsHandle=*/true); } -Result> convert(const hidl_vec& extensions) { +GeneralResult> convert(const hidl_vec& extensions) { return convertVec(extensions); } -Result> convert(const hidl_vec& handles) { +GeneralResult> convert(const hidl_vec& handles) { return convertVec(handles); } -Result> convert(const hidl_vec& outputShapes) { +GeneralResult> convert( + const hidl_vec& outputShapes) { return convertVec(outputShapes); } @@ -278,24 +282,24 @@ namespace { using utils::convert; -nn::Result convert(const nn::Operand::LifeTime& lifetime) { +nn::GeneralResult convert(const nn::Operand::LifeTime& lifetime) { return V1_0::utils::convert(lifetime); } -nn::Result convert( +nn::GeneralResult convert( const nn::Capabilities::PerformanceInfo& performanceInfo) { return V1_0::utils::convert(performanceInfo); } -nn::Result convert(const nn::DataLocation& location) { +nn::GeneralResult convert(const nn::DataLocation& location) { return V1_0::utils::convert(location); } -nn::Result> convert(const nn::Model::OperandValues& operandValues) { +nn::GeneralResult> convert(const nn::Model::OperandValues& operandValues) { return V1_0::utils::convert(operandValues); } -nn::Result convert(const nn::Memory& memory) { +nn::GeneralResult convert(const nn::Memory& memory) { return V1_0::utils::convert(memory); } @@ -303,7 +307,7 @@ template using ConvertOutput = std::decay_t()).value())>; template -nn::Result>> convertVec(const std::vector& arguments) { +nn::GeneralResult>> convertVec(const std::vector& arguments) { hidl_vec> halObject(arguments.size()); for (size_t i = 0; i < arguments.size(); ++i) { halObject[i] = NN_TRY(convert(arguments[i])); @@ -312,22 +316,23 @@ nn::Result>> convertVec(const std::vector& ar } template -nn::Result>> convert(const std::vector& arguments) { +nn::GeneralResult>> convert(const std::vector& arguments) { return convertVec(arguments); } -nn::Result makeExtraParams(nn::Operand::NoParams /*noParams*/) { +nn::GeneralResult makeExtraParams(nn::Operand::NoParams /*noParams*/) { return Operand::ExtraParams{}; } -nn::Result makeExtraParams( +nn::GeneralResult makeExtraParams( const nn::Operand::SymmPerChannelQuantParams& channelQuant) { Operand::ExtraParams ret; ret.channelQuant(NN_TRY(convert(channelQuant))); return ret; } -nn::Result makeExtraParams(const nn::Operand::ExtensionParams& extension) { +nn::GeneralResult makeExtraParams( + const nn::Operand::ExtensionParams& extension) { Operand::ExtraParams ret; ret.extension(extension); return ret; @@ -335,28 +340,29 @@ nn::Result makeExtraParams(const nn::Operand::ExtensionPar } // anonymous namespace -nn::Result convert(const nn::OperandType& operandType) { +nn::GeneralResult convert(const nn::OperandType& operandType) { return static_cast(operandType); } -nn::Result convert(const nn::OperationType& operationType) { +nn::GeneralResult convert(const nn::OperationType& operationType) { return static_cast(operationType); } -nn::Result convert(const nn::DeviceType& deviceType) { +nn::GeneralResult convert(const nn::DeviceType& deviceType) { switch (deviceType) { case nn::DeviceType::UNKNOWN: - return NN_ERROR() << "Invalid DeviceType UNKNOWN"; + return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "Invalid DeviceType UNKNOWN"; case nn::DeviceType::OTHER: case nn::DeviceType::CPU: case nn::DeviceType::GPU: case nn::DeviceType::ACCELERATOR: return static_cast(deviceType); } - return NN_ERROR() << "Invalid DeviceType " << underlyingType(deviceType); + return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) + << "Invalid DeviceType " << underlyingType(deviceType); } -nn::Result convert(const nn::Capabilities& capabilities) { +nn::GeneralResult convert(const nn::Capabilities& capabilities) { std::vector operandPerformance; operandPerformance.reserve(capabilities.operandPerformance.asVector().size()); std::copy_if(capabilities.operandPerformance.asVector().begin(), @@ -375,7 +381,7 @@ nn::Result convert(const nn::Capabilities& capabilities) { }; } -nn::Result convert( +nn::GeneralResult convert( const nn::Capabilities::OperandPerformance& operandPerformance) { return Capabilities::OperandPerformance{ .type = NN_TRY(convert(operandPerformance.type)), @@ -383,7 +389,7 @@ nn::Result convert( }; } -nn::Result convert(const nn::Operation& operation) { +nn::GeneralResult convert(const nn::Operation& operation) { return Operation{ .type = NN_TRY(convert(operation.type)), .inputs = operation.inputs, @@ -391,7 +397,7 @@ nn::Result convert(const nn::Operation& operation) { }; } -nn::Result convert( +nn::GeneralResult convert( const nn::Operand::SymmPerChannelQuantParams& symmPerChannelQuantParams) { return SymmPerChannelQuantParams{ .scales = symmPerChannelQuantParams.scales, @@ -399,7 +405,7 @@ nn::Result convert( }; } -nn::Result convert(const nn::Operand& operand) { +nn::GeneralResult convert(const nn::Operand& operand) { return Operand{ .type = NN_TRY(convert(operand.type)), .dimensions = operand.dimensions, @@ -412,13 +418,14 @@ nn::Result convert(const nn::Operand& operand) { }; } -nn::Result convert(const nn::Operand::ExtraParams& extraParams) { +nn::GeneralResult convert(const nn::Operand::ExtraParams& extraParams) { return std::visit([](const auto& x) { return makeExtraParams(x); }, extraParams); } -nn::Result convert(const nn::Model& model) { +nn::GeneralResult convert(const nn::Model& model) { if (!hal::utils::hasNoPointerData(model)) { - return NN_ERROR() << "Model cannot be converted because it contains pointer-based memory"; + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) + << "Model cannot be converted because it contains pointer-based memory"; } auto operands = NN_TRY(convert(model.main.operands)); @@ -443,7 +450,7 @@ nn::Result convert(const nn::Model& model) { }; } -nn::Result convert( +nn::GeneralResult convert( const nn::Model::ExtensionNameAndPrefix& extensionNameAndPrefix) { return Model::ExtensionNameAndPrefix{ .name = extensionNameAndPrefix.name, @@ -451,27 +458,27 @@ nn::Result convert( }; } -nn::Result convert(const nn::OutputShape& outputShape) { +nn::GeneralResult convert(const nn::OutputShape& outputShape) { return OutputShape{.dimensions = outputShape.dimensions, .isSufficient = outputShape.isSufficient}; } -nn::Result convert(const nn::MeasureTiming& measureTiming) { +nn::GeneralResult convert(const nn::MeasureTiming& measureTiming) { return static_cast(measureTiming); } -nn::Result convert(const nn::Timing& timing) { +nn::GeneralResult convert(const nn::Timing& timing) { return Timing{.timeOnDevice = timing.timeOnDevice, .timeInDriver = timing.timeInDriver}; } -nn::Result convert(const nn::Extension& extension) { +nn::GeneralResult convert(const nn::Extension& extension) { return Extension{ .name = extension.name, .operandTypes = NN_TRY(convert(extension.operandTypes)), }; } -nn::Result convert( +nn::GeneralResult convert( const nn::Extension::OperandTypeInformation& operandTypeInformation) { return Extension::OperandTypeInformation{ .type = operandTypeInformation.type, @@ -480,22 +487,22 @@ nn::Result convert( }; } -nn::Result convert(const nn::NativeHandle& handle) { +nn::GeneralResult convert(const nn::NativeHandle& handle) { const auto hidlHandle = hidl_handle(handle->handle()); // Copy memory to force the native_handle_t to be copied. auto copiedHandle = hidlHandle; return copiedHandle; } -nn::Result> convert(const std::vector& extensions) { +nn::GeneralResult> convert(const std::vector& extensions) { return convertVec(extensions); } -nn::Result> convert(const std::vector& handles) { +nn::GeneralResult> convert(const std::vector& handles) { return convertVec(handles); } -nn::Result> convert(const std::vector& outputShapes) { +nn::GeneralResult> convert(const std::vector& outputShapes) { return convertVec(outputShapes); } diff --git a/neuralnetworks/1.2/utils/src/Device.cpp b/neuralnetworks/1.2/utils/src/Device.cpp new file mode 100644 index 0000000000..ca236f17c6 --- /dev/null +++ b/neuralnetworks/1.2/utils/src/Device.cpp @@ -0,0 +1,318 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Device.h" + +#include "Callbacks.h" +#include "Conversions.h" +#include "Utils.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::V1_2::utils { + +nn::GeneralResult initVersionString(V1_2::IDevice* device) { + CHECK(device != nullptr); + + nn::GeneralResult result = NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) + << "uninitialized"; + const auto cb = [&result](V1_0::ErrorStatus status, const hidl_string& versionString) { + if (status != V1_0::ErrorStatus::NONE) { + const auto canonical = + validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + result = NN_ERROR(canonical) << "getVersionString failed with " << toString(status); + } else { + result = versionString; + } + }; + + const auto ret = device->getVersionString(cb); + NN_TRY(hal::utils::handleTransportError(ret)); + + return result; +} + +nn::GeneralResult initDeviceType(V1_2::IDevice* device) { + CHECK(device != nullptr); + + nn::GeneralResult result = NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) + << "uninitialized"; + const auto cb = [&result](V1_0::ErrorStatus status, DeviceType deviceType) { + if (status != V1_0::ErrorStatus::NONE) { + const auto canonical = + validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + result = NN_ERROR(canonical) << "getDeviceType failed with " << toString(status); + } else { + result = nn::convert(deviceType); + } + }; + + const auto ret = device->getType(cb); + NN_TRY(hal::utils::handleTransportError(ret)); + + return result; +} + +nn::GeneralResult> initExtensions(V1_2::IDevice* device) { + CHECK(device != nullptr); + + nn::GeneralResult> result = + NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "uninitialized"; + const auto cb = [&result](V1_0::ErrorStatus status, const hidl_vec& extensions) { + if (status != V1_0::ErrorStatus::NONE) { + const auto canonical = + validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + result = NN_ERROR(canonical) << "getExtensions failed with " << toString(status); + } else { + result = nn::convert(extensions); + } + }; + + const auto ret = device->getSupportedExtensions(cb); + NN_TRY(hal::utils::handleTransportError(ret)); + + return result; +} + +nn::GeneralResult initCapabilities(V1_2::IDevice* device) { + CHECK(device != nullptr); + + nn::GeneralResult result = NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) + << "uninitialized"; + const auto cb = [&result](V1_0::ErrorStatus status, const Capabilities& capabilities) { + if (status != V1_0::ErrorStatus::NONE) { + const auto canonical = + validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + result = NN_ERROR(canonical) << "getCapabilities_1_2 failed with " << toString(status); + } else { + result = validatedConvertToCanonical(capabilities); + } + }; + + const auto ret = device->getCapabilities_1_2(cb); + NN_TRY(hal::utils::handleTransportError(ret)); + + return result; +} + +nn::GeneralResult> initNumberOfCacheFilesNeeded( + V1_2::IDevice* device) { + CHECK(device != nullptr); + + nn::GeneralResult> result = + NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "uninitialized"; + const auto cb = [&result](V1_0::ErrorStatus status, uint32_t numModelCache, + uint32_t numDataCache) { + if (status != V1_0::ErrorStatus::NONE) { + const auto canonical = + validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + result = NN_ERROR(canonical) + << "getNumberOfCacheFilesNeeded failed with " << toString(status); + } else { + result = std::make_pair(numModelCache, numDataCache); + } + }; + + const auto ret = device->getNumberOfCacheFilesNeeded(cb); + NN_TRY(hal::utils::handleTransportError(ret)); + + return result; +} + +nn::GeneralResult> Device::create(std::string name, + sp device) { + if (name.empty()) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) + << "V1_2::utils::Device::create must have non-empty name"; + } + if (device == nullptr) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) + << "V1_2::utils::Device::create must have non-null device"; + } + + auto versionString = NN_TRY(initVersionString(device.get())); + const auto deviceType = NN_TRY(initDeviceType(device.get())); + auto extensions = NN_TRY(initExtensions(device.get())); + auto capabilities = NN_TRY(initCapabilities(device.get())); + const auto numberOfCacheFilesNeeded = NN_TRY(initNumberOfCacheFilesNeeded(device.get())); + + auto deathHandler = NN_TRY(hal::utils::DeathHandler::create(device)); + return std::make_shared( + PrivateConstructorTag{}, std::move(name), std::move(versionString), deviceType, + std::move(extensions), std::move(capabilities), numberOfCacheFilesNeeded, + std::move(device), std::move(deathHandler)); +} + +Device::Device(PrivateConstructorTag /*tag*/, std::string name, std::string versionString, + nn::DeviceType deviceType, std::vector extensions, + nn::Capabilities capabilities, + std::pair numberOfCacheFilesNeeded, sp device, + hal::utils::DeathHandler deathHandler) + : kName(std::move(name)), + kVersionString(std::move(versionString)), + kDeviceType(deviceType), + kExtensions(std::move(extensions)), + kCapabilities(std::move(capabilities)), + kNumberOfCacheFilesNeeded(numberOfCacheFilesNeeded), + kDevice(std::move(device)), + kDeathHandler(std::move(deathHandler)) {} + +const std::string& Device::getName() const { + return kName; +} + +const std::string& Device::getVersionString() const { + return kVersionString; +} + +nn::Version Device::getFeatureLevel() const { + return nn::Version::ANDROID_Q; +} + +nn::DeviceType Device::getType() const { + return kDeviceType; +} + +const std::vector& Device::getSupportedExtensions() const { + return kExtensions; +} + +const nn::Capabilities& Device::getCapabilities() const { + return kCapabilities; +} + +std::pair Device::getNumberOfCacheFilesNeeded() const { + return kNumberOfCacheFilesNeeded; +} + +nn::GeneralResult Device::wait() const { + const auto ret = kDevice->ping(); + return hal::utils::handleTransportError(ret); +} + +nn::GeneralResult> Device::getSupportedOperations(const nn::Model& model) const { + // Ensure that model is ready for IPC. + std::optional maybeModelInShared; + const nn::Model& modelInShared = + NN_TRY(hal::utils::flushDataFromPointerToShared(&model, &maybeModelInShared)); + + const auto hidlModel = NN_TRY(convert(modelInShared)); + + nn::GeneralResult> result = NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) + << "uninitialized"; + auto cb = [&result, &model](V1_0::ErrorStatus status, + const hidl_vec& supportedOperations) { + if (status != V1_0::ErrorStatus::NONE) { + const auto canonical = + validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + result = NN_ERROR(canonical) + << "getSupportedOperations_1_2 failed with " << toString(status); + } else if (supportedOperations.size() != model.main.operations.size()) { + result = NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) + << "getSupportedOperations_1_2 returned vector of size " + << supportedOperations.size() << " but expected " + << model.main.operations.size(); + } else { + result = supportedOperations; + } + }; + + const auto ret = kDevice->getSupportedOperations_1_2(hidlModel, cb); + NN_TRY(hal::utils::handleTransportError(ret)); + + return result; +} + +nn::GeneralResult Device::prepareModel( + const nn::Model& model, nn::ExecutionPreference preference, nn::Priority /*priority*/, + nn::OptionalTimePoint /*deadline*/, const std::vector& modelCache, + const std::vector& dataCache, const nn::CacheToken& token) const { + // Ensure that model is ready for IPC. + std::optional maybeModelInShared; + const nn::Model& modelInShared = + NN_TRY(hal::utils::flushDataFromPointerToShared(&model, &maybeModelInShared)); + + const auto hidlModel = NN_TRY(convert(modelInShared)); + const auto hidlPreference = NN_TRY(V1_1::utils::convert(preference)); + const auto hidlModelCache = NN_TRY(convert(modelCache)); + const auto hidlDataCache = NN_TRY(convert(dataCache)); + const auto hidlToken = token; + + const auto cb = sp::make(); + const auto scoped = kDeathHandler.protectCallback(cb.get()); + + const auto ret = kDevice->prepareModel_1_2(hidlModel, hidlPreference, hidlModelCache, + hidlDataCache, hidlToken, cb); + const auto status = NN_TRY(hal::utils::handleTransportError(ret)); + if (status != V1_0::ErrorStatus::NONE) { + const auto canonical = + validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + return NN_ERROR(canonical) << "prepareModel_1_2 failed with " << toString(status); + } + + return cb->get(); +} + +nn::GeneralResult Device::prepareModelFromCache( + nn::OptionalTimePoint /*deadline*/, const std::vector& modelCache, + const std::vector& dataCache, const nn::CacheToken& token) const { + const auto hidlModelCache = NN_TRY(convert(modelCache)); + const auto hidlDataCache = NN_TRY(convert(dataCache)); + const auto hidlToken = token; + + const auto cb = sp::make(); + const auto scoped = kDeathHandler.protectCallback(cb.get()); + + const auto ret = kDevice->prepareModelFromCache(hidlModelCache, hidlDataCache, hidlToken, cb); + const auto status = NN_TRY(hal::utils::handleTransportError(ret)); + if (status != V1_0::ErrorStatus::NONE) { + const auto canonical = + validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + return NN_ERROR(canonical) << "prepareModelFromCache failed with " << toString(status); + } + + return cb->get(); +} + +nn::GeneralResult Device::allocate( + const nn::BufferDesc& /*desc*/, + const std::vector& /*preparedModels*/, + const std::vector& /*inputRoles*/, + const std::vector& /*outputRoles*/) const { + return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) + << "IDevice::allocate not supported on 1.2 HAL service"; +} + +} // namespace android::hardware::neuralnetworks::V1_2::utils diff --git a/neuralnetworks/1.2/utils/src/PreparedModel.cpp b/neuralnetworks/1.2/utils/src/PreparedModel.cpp new file mode 100644 index 0000000000..ff9db215a2 --- /dev/null +++ b/neuralnetworks/1.2/utils/src/PreparedModel.cpp @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "PreparedModel.h" + +#include "Callbacks.h" +#include "Conversions.h" +#include "Utils.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::V1_2::utils { +namespace { + +nn::GeneralResult, nn::Timing>> +convertExecutionResultsHelper(const hidl_vec& outputShapes, const Timing& timing) { + return std::make_pair(NN_TRY(validatedConvertToCanonical(outputShapes)), + NN_TRY(validatedConvertToCanonical(timing))); +} + +nn::ExecutionResult, nn::Timing>> convertExecutionResults( + const hidl_vec& outputShapes, const Timing& timing) { + return hal::utils::makeExecutionFailure(convertExecutionResultsHelper(outputShapes, timing)); +} + +} // namespace + +nn::GeneralResult> PreparedModel::create( + sp preparedModel) { + if (preparedModel == nullptr) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) + << "V1_2::utils::PreparedModel::create must have non-null preparedModel"; + } + + auto deathHandler = NN_TRY(hal::utils::DeathHandler::create(preparedModel)); + return std::make_shared(PrivateConstructorTag{}, std::move(preparedModel), + std::move(deathHandler)); +} + +PreparedModel::PreparedModel(PrivateConstructorTag /*tag*/, sp preparedModel, + hal::utils::DeathHandler deathHandler) + : kPreparedModel(std::move(preparedModel)), kDeathHandler(std::move(deathHandler)) {} + +nn::ExecutionResult, nn::Timing>> +PreparedModel::executeSynchronously(const V1_0::Request& request, MeasureTiming measure) const { + nn::ExecutionResult, nn::Timing>> result = + NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "uninitialized"; + const auto cb = [&result](V1_0::ErrorStatus status, const hidl_vec& outputShapes, + const Timing& timing) { + if (status != V1_0::ErrorStatus::NONE) { + const auto canonical = + validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + result = NN_ERROR(canonical) << "executeSynchronously failed with " << toString(status); + } else { + result = convertExecutionResults(outputShapes, timing); + } + }; + + const auto ret = kPreparedModel->executeSynchronously(request, measure, cb); + NN_TRY(hal::utils::makeExecutionFailure(hal::utils::handleTransportError(ret))); + + return result; +} + +nn::ExecutionResult, nn::Timing>> +PreparedModel::executeAsynchronously(const V1_0::Request& request, MeasureTiming measure) const { + const auto cb = sp::make(); + const auto scoped = kDeathHandler.protectCallback(cb.get()); + + const auto ret = kPreparedModel->execute_1_2(request, measure, cb); + const auto status = + NN_TRY(hal::utils::makeExecutionFailure(hal::utils::handleTransportError(ret))); + if (status != V1_0::ErrorStatus::NONE) { + const auto canonical = + validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + return NN_ERROR(canonical) << "execute failed with " << toString(status); + } + + return cb->get(); +} + +nn::ExecutionResult, nn::Timing>> PreparedModel::execute( + const nn::Request& request, nn::MeasureTiming measure, + const nn::OptionalTimePoint& /*deadline*/, + const nn::OptionalTimeoutDuration& /*loopTimeoutDuration*/) const { + // Ensure that request is ready for IPC. + std::optional maybeRequestInShared; + const nn::Request& requestInShared = NN_TRY(hal::utils::makeExecutionFailure( + hal::utils::flushDataFromPointerToShared(&request, &maybeRequestInShared))); + + const auto hidlRequest = + NN_TRY(hal::utils::makeExecutionFailure(V1_0::utils::convert(requestInShared))); + const auto hidlMeasure = NN_TRY(hal::utils::makeExecutionFailure(convert(measure))); + + nn::ExecutionResult, nn::Timing>> result = + NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "uninitialized"; + const bool preferSynchronous = true; + + // Execute synchronously if allowed. + if (preferSynchronous) { + result = executeSynchronously(hidlRequest, hidlMeasure); + } + + // Run asymchronous execution if execution has not already completed. + if (!result.has_value()) { + result = executeAsynchronously(hidlRequest, hidlMeasure); + } + + // Flush output buffers if suxcessful execution. + if (result.has_value()) { + NN_TRY(hal::utils::makeExecutionFailure( + hal::utils::unflushDataFromSharedToPointer(request, maybeRequestInShared))); + } + + return result; +} + +nn::GeneralResult> +PreparedModel::executeFenced( + const nn::Request& /*request*/, const std::vector& /*waitFor*/, + nn::MeasureTiming /*measure*/, const nn::OptionalTimePoint& /*deadline*/, + const nn::OptionalTimeoutDuration& /*loopTimeoutDuration*/, + const nn::OptionalTimeoutDuration& /*timeoutDurationAfterFence*/) const { + return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) + << "IPreparedModel::executeFenced is not supported on 1.2 HAL service"; +} + +std::any PreparedModel::getUnderlyingResource() const { + sp resource = kPreparedModel; + return resource; +} + +} // namespace android::hardware::neuralnetworks::V1_2::utils diff --git a/neuralnetworks/1.2/utils/src/Service.cpp b/neuralnetworks/1.2/utils/src/Service.cpp new file mode 100644 index 0000000000..110188f4f1 --- /dev/null +++ b/neuralnetworks/1.2/utils/src/Service.cpp @@ -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. + */ + +#include "Service.h" + +#include +#include +#include +#include +#include +#include "Device.h" + +namespace android::hardware::neuralnetworks::V1_2::utils { + +nn::GeneralResult getDevice(const std::string& name) { + hal::utils::ResilientDevice::Factory makeDevice = + [name](bool blocking) -> nn::GeneralResult { + auto service = blocking ? IDevice::getService(name) : IDevice::tryGetService(name); + if (service == nullptr) { + return NN_ERROR() << (blocking ? "getService" : "tryGetService") << " returned nullptr"; + } + return Device::create(name, std::move(service)); + }; + + return hal::utils::ResilientDevice::create(std::move(makeDevice)); +} + +} // namespace android::hardware::neuralnetworks::V1_2::utils diff --git a/neuralnetworks/1.3/utils/Android.bp b/neuralnetworks/1.3/utils/Android.bp index 279b250532..d5d897d470 100644 --- a/neuralnetworks/1.3/utils/Android.bp +++ b/neuralnetworks/1.3/utils/Android.bp @@ -20,6 +20,7 @@ cc_library_static { srcs: ["src/*"], local_include_dirs: ["include/nnapi/hal/1.3/"], export_include_dirs: ["include"], + cflags: ["-Wthread-safety"], static_libs: [ "neuralnetworks_types", "neuralnetworks_utils_hal_common", diff --git a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Buffer.h b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Buffer.h new file mode 100644 index 0000000000..637179de33 --- /dev/null +++ b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Buffer.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_3_UTILS_BUFFER_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_3_UTILS_BUFFER_H + +#include +#include +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::V1_3::utils { + +class Buffer final : public nn::IBuffer { + struct PrivateConstructorTag {}; + + public: + static nn::GeneralResult> create( + sp buffer, nn::Request::MemoryDomainToken token); + + Buffer(PrivateConstructorTag tag, sp buffer, + nn::Request::MemoryDomainToken token); + + nn::Request::MemoryDomainToken getToken() const override; + + nn::GeneralResult copyTo(const nn::Memory& dst) const override; + nn::GeneralResult copyFrom(const nn::Memory& src, + const nn::Dimensions& dimensions) const override; + + private: + const sp kBuffer; + const nn::Request::MemoryDomainToken kToken; +}; + +} // namespace android::hardware::neuralnetworks::V1_3::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_3_UTILS_BUFFER_H diff --git a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Callbacks.h b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Callbacks.h new file mode 100644 index 0000000000..d46b111701 --- /dev/null +++ b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Callbacks.h @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_3_UTILS_CALLBACKS_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_3_UTILS_CALLBACKS_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::V1_3::utils { + +class PreparedModelCallback final : public IPreparedModelCallback, + public hal::utils::IProtectedCallback { + public: + using Data = nn::GeneralResult; + + Return notify(V1_0::ErrorStatus status, + const sp& preparedModel) override; + Return notify_1_2(V1_0::ErrorStatus status, + const sp& preparedModel) override; + Return notify_1_3(ErrorStatus status, const sp& preparedModel) override; + + void notifyAsDeadObject() override; + + Data get(); + + private: + void notifyInternal(Data result); + + hal::utils::TransferValue mData; +}; + +class ExecutionCallback final : public IExecutionCallback, public hal::utils::IProtectedCallback { + public: + using Data = nn::ExecutionResult, nn::Timing>>; + + Return notify(V1_0::ErrorStatus status) override; + Return notify_1_2(V1_0::ErrorStatus status, + const hidl_vec& outputShapes, + const V1_2::Timing& timing) override; + Return notify_1_3(ErrorStatus status, const hidl_vec& outputShapes, + const V1_2::Timing& timing) override; + + void notifyAsDeadObject() override; + + Data get(); + + private: + void notifyInternal(Data result); + + hal::utils::TransferValue mData; +}; + +} // namespace android::hardware::neuralnetworks::V1_3::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_3_UTILS_CALLBACKS_H diff --git a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Conversions.h b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Conversions.h index 43987a9727..64aa96e61a 100644 --- a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Conversions.h +++ b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Conversions.h @@ -25,54 +25,54 @@ namespace android::nn { -Result convert(const hal::V1_3::OperandType& operandType); -Result convert(const hal::V1_3::OperationType& operationType); -Result convert(const hal::V1_3::Priority& priority); -Result convert(const hal::V1_3::Capabilities& capabilities); -Result convert( +GeneralResult convert(const hal::V1_3::OperandType& operandType); +GeneralResult convert(const hal::V1_3::OperationType& operationType); +GeneralResult convert(const hal::V1_3::Priority& priority); +GeneralResult convert(const hal::V1_3::Capabilities& capabilities); +GeneralResult convert( const hal::V1_3::Capabilities::OperandPerformance& operandPerformance); -Result convert(const hal::V1_3::Operation& operation); -Result convert(const hal::V1_3::OperandLifeTime& operandLifeTime); -Result convert(const hal::V1_3::Operand& operand); -Result convert(const hal::V1_3::Model& model); -Result convert(const hal::V1_3::Subgraph& subgraph); -Result convert(const hal::V1_3::BufferDesc& bufferDesc); -Result convert(const hal::V1_3::BufferRole& bufferRole); -Result convert(const hal::V1_3::Request& request); -Result convert(const hal::V1_3::Request::MemoryPool& memoryPool); -Result convert(const hal::V1_3::OptionalTimePoint& optionalTimePoint); -Result convert( +GeneralResult convert(const hal::V1_3::Operation& operation); +GeneralResult convert(const hal::V1_3::OperandLifeTime& operandLifeTime); +GeneralResult convert(const hal::V1_3::Operand& operand); +GeneralResult convert(const hal::V1_3::Model& model); +GeneralResult convert(const hal::V1_3::Subgraph& subgraph); +GeneralResult convert(const hal::V1_3::BufferDesc& bufferDesc); +GeneralResult convert(const hal::V1_3::BufferRole& bufferRole); +GeneralResult convert(const hal::V1_3::Request& request); +GeneralResult convert(const hal::V1_3::Request::MemoryPool& memoryPool); +GeneralResult convert(const hal::V1_3::OptionalTimePoint& optionalTimePoint); +GeneralResult convert( const hal::V1_3::OptionalTimeoutDuration& optionalTimeoutDuration); -Result convert(const hal::V1_3::ErrorStatus& errorStatus); +GeneralResult convert(const hal::V1_3::ErrorStatus& errorStatus); -Result> convert( +GeneralResult> convert( const hardware::hidl_vec& bufferRoles); } // namespace android::nn namespace android::hardware::neuralnetworks::V1_3::utils { -nn::Result convert(const nn::OperandType& operandType); -nn::Result convert(const nn::OperationType& operationType); -nn::Result convert(const nn::Priority& priority); -nn::Result convert(const nn::Capabilities& capabilities); -nn::Result convert( +nn::GeneralResult convert(const nn::OperandType& operandType); +nn::GeneralResult convert(const nn::OperationType& operationType); +nn::GeneralResult convert(const nn::Priority& priority); +nn::GeneralResult convert(const nn::Capabilities& capabilities); +nn::GeneralResult convert( const nn::Capabilities::OperandPerformance& operandPerformance); -nn::Result convert(const nn::Operation& operation); -nn::Result convert(const nn::Operand::LifeTime& operandLifeTime); -nn::Result convert(const nn::Operand& operand); -nn::Result convert(const nn::Model& model); -nn::Result convert(const nn::Model::Subgraph& subgraph); -nn::Result convert(const nn::BufferDesc& bufferDesc); -nn::Result convert(const nn::BufferRole& bufferRole); -nn::Result convert(const nn::Request& request); -nn::Result convert(const nn::Request::MemoryPool& memoryPool); -nn::Result convert(const nn::OptionalTimePoint& optionalTimePoint); -nn::Result convert( +nn::GeneralResult convert(const nn::Operation& operation); +nn::GeneralResult convert(const nn::Operand::LifeTime& operandLifeTime); +nn::GeneralResult convert(const nn::Operand& operand); +nn::GeneralResult convert(const nn::Model& model); +nn::GeneralResult convert(const nn::Model::Subgraph& subgraph); +nn::GeneralResult convert(const nn::BufferDesc& bufferDesc); +nn::GeneralResult convert(const nn::BufferRole& bufferRole); +nn::GeneralResult convert(const nn::Request& request); +nn::GeneralResult convert(const nn::Request::MemoryPool& memoryPool); +nn::GeneralResult convert(const nn::OptionalTimePoint& optionalTimePoint); +nn::GeneralResult convert( const nn::OptionalTimeoutDuration& optionalTimeoutDuration); -nn::Result convert(const nn::ErrorStatus& errorStatus); +nn::GeneralResult convert(const nn::ErrorStatus& errorStatus); -nn::Result> convert(const std::vector& bufferRoles); +nn::GeneralResult> convert(const std::vector& bufferRoles); } // namespace android::hardware::neuralnetworks::V1_3::utils diff --git a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Device.h b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Device.h new file mode 100644 index 0000000000..2f6c46a858 --- /dev/null +++ b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Device.h @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_3_UTILS_DEVICE_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_3_UTILS_DEVICE_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::V1_3::utils { + +class Device final : public nn::IDevice { + struct PrivateConstructorTag {}; + + public: + static nn::GeneralResult> create(std::string name, + sp device); + + Device(PrivateConstructorTag tag, std::string name, std::string versionString, + nn::DeviceType deviceType, std::vector extensions, + nn::Capabilities capabilities, std::pair numberOfCacheFilesNeeded, + sp device, hal::utils::DeathHandler deathHandler); + + const std::string& getName() const override; + const std::string& getVersionString() const override; + nn::Version getFeatureLevel() const override; + nn::DeviceType getType() const override; + const std::vector& getSupportedExtensions() const override; + const nn::Capabilities& getCapabilities() const override; + std::pair getNumberOfCacheFilesNeeded() const override; + + nn::GeneralResult wait() const override; + + nn::GeneralResult> getSupportedOperations( + const nn::Model& model) const override; + + nn::GeneralResult prepareModel( + const nn::Model& model, nn::ExecutionPreference preference, nn::Priority priority, + nn::OptionalTimePoint deadline, const std::vector& modelCache, + const std::vector& dataCache, + const nn::CacheToken& token) const override; + + nn::GeneralResult prepareModelFromCache( + nn::OptionalTimePoint deadline, const std::vector& modelCache, + const std::vector& dataCache, + const nn::CacheToken& token) const override; + + nn::GeneralResult allocate( + const nn::BufferDesc& desc, const std::vector& preparedModels, + const std::vector& inputRoles, + const std::vector& outputRoles) const override; + + private: + const std::string kName; + const std::string kVersionString; + const nn::DeviceType kDeviceType; + const std::vector kExtensions; + const nn::Capabilities kCapabilities; + const std::pair kNumberOfCacheFilesNeeded; + const sp kDevice; + const hal::utils::DeathHandler kDeathHandler; +}; + +} // namespace android::hardware::neuralnetworks::V1_3::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_3_UTILS_DEVICE_H diff --git a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/PreparedModel.h b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/PreparedModel.h new file mode 100644 index 0000000000..e0d69dd7c6 --- /dev/null +++ b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/PreparedModel.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_3_UTILS_PREPARED_MODEL_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_3_UTILS_PREPARED_MODEL_H + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::V1_3::utils { + +class PreparedModel final : public nn::IPreparedModel { + struct PrivateConstructorTag {}; + + public: + static nn::GeneralResult> create( + sp preparedModel); + + PreparedModel(PrivateConstructorTag tag, sp preparedModel, + hal::utils::DeathHandler deathHandler); + + nn::ExecutionResult, nn::Timing>> execute( + const nn::Request& request, nn::MeasureTiming measure, + const nn::OptionalTimePoint& deadline, + const nn::OptionalTimeoutDuration& loopTimeoutDuration) const override; + + nn::GeneralResult> executeFenced( + const nn::Request& request, const std::vector& waitFor, + nn::MeasureTiming measure, const nn::OptionalTimePoint& deadline, + const nn::OptionalTimeoutDuration& loopTimeoutDuration, + const nn::OptionalTimeoutDuration& timeoutDurationAfterFence) const override; + + std::any getUnderlyingResource() const override; + + private: + nn::ExecutionResult, nn::Timing>> executeSynchronously( + const Request& request, V1_2::MeasureTiming measure, const OptionalTimePoint& deadline, + const OptionalTimeoutDuration& loopTimeoutDuration) const; + nn::ExecutionResult, nn::Timing>> executeAsynchronously( + const Request& request, V1_2::MeasureTiming measure, const OptionalTimePoint& deadline, + const OptionalTimeoutDuration& loopTimeoutDuration) const; + + const sp kPreparedModel; + const hal::utils::DeathHandler kDeathHandler; +}; + +} // namespace android::hardware::neuralnetworks::V1_3::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_3_UTILS_PREPARED_MODEL_H diff --git a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Service.h b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Service.h new file mode 100644 index 0000000000..2bc32574ff --- /dev/null +++ b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Service.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_3_UTILS_SERVICE_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_3_UTILS_SERVICE_H + +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::V1_3::utils { + +nn::GeneralResult getDevice(const std::string& name); + +} // namespace android::hardware::neuralnetworks::V1_3::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_3_UTILS_SERVICE_H diff --git a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Utils.h b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Utils.h index f8c975d5d7..e61859d5f9 100644 --- a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Utils.h +++ b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Utils.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -35,10 +36,14 @@ constexpr auto kVersion = nn::Version::ANDROID_R; template nn::Result validate(const Type& halObject) { - const auto canonical = NN_TRY(nn::convert(halObject)); - const auto version = NN_TRY(nn::validate(canonical)); + const auto maybeCanonical = nn::convert(halObject); + if (!maybeCanonical.has_value()) { + return nn::error() << maybeCanonical.error().message; + } + const auto version = NN_TRY(nn::validate(maybeCanonical.value())); if (version > utils::kVersion) { - return NN_ERROR() << ""; + return NN_ERROR() << "Insufficient version: " << version << " vs required " + << utils::kVersion; } return {}; } @@ -55,9 +60,14 @@ bool valid(const Type& halObject) { template decltype(nn::convert(std::declval())) validatedConvertToCanonical(const Type& halObject) { auto canonical = NN_TRY(nn::convert(halObject)); - const auto version = NN_TRY(nn::validate(canonical)); + const auto maybeVersion = nn::validate(canonical); + if (!maybeVersion.has_value()) { + return nn::error() << maybeVersion.error(); + } + const auto version = maybeVersion.value(); if (version > utils::kVersion) { - return NN_ERROR() << ""; + return NN_ERROR() << "Insufficient version: " << version << " vs required " + << utils::kVersion; } return canonical; } diff --git a/neuralnetworks/1.3/utils/src/Buffer.cpp b/neuralnetworks/1.3/utils/src/Buffer.cpp new file mode 100644 index 0000000000..f3fe9b5112 --- /dev/null +++ b/neuralnetworks/1.3/utils/src/Buffer.cpp @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Buffer.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Conversions.h" +#include "Utils.h" + +#include +#include + +namespace android::hardware::neuralnetworks::V1_3::utils { + +nn::GeneralResult> Buffer::create( + sp buffer, nn::Request::MemoryDomainToken token) { + if (buffer == nullptr) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) + << "V1_3::utils::Buffer::create must have non-null buffer"; + } + if (token == static_cast(0)) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) + << "V1_3::utils::Buffer::create must have non-zero token"; + } + + return std::make_shared(PrivateConstructorTag{}, std::move(buffer), token); +} + +Buffer::Buffer(PrivateConstructorTag /*tag*/, sp buffer, + nn::Request::MemoryDomainToken token) + : kBuffer(std::move(buffer)), kToken(token) { + CHECK(kBuffer != nullptr); + CHECK(kToken != static_cast(0)); +} + +nn::Request::MemoryDomainToken Buffer::getToken() const { + return kToken; +} + +nn::GeneralResult Buffer::copyTo(const nn::Memory& dst) const { + const auto hidlDst = NN_TRY(V1_0::utils::convert(dst)); + + const auto ret = kBuffer->copyTo(hidlDst); + const auto status = NN_TRY(hal::utils::handleTransportError(ret)); + if (status != ErrorStatus::NONE) { + const auto canonical = + validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + return NN_ERROR(canonical) << "IBuffer::copyTo failed with " << toString(status); + } + + return {}; +} + +nn::GeneralResult Buffer::copyFrom(const nn::Memory& src, + const nn::Dimensions& dimensions) const { + const auto hidlSrc = NN_TRY(V1_0::utils::convert(src)); + const auto hidlDimensions = hidl_vec(dimensions); + + const auto ret = kBuffer->copyFrom(hidlSrc, hidlDimensions); + const auto status = NN_TRY(hal::utils::handleTransportError(ret)); + if (status != ErrorStatus::NONE) { + const auto canonical = + validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + return NN_ERROR(canonical) << "IBuffer::copyFrom failed with " << toString(status); + } + + return {}; +} + +} // namespace android::hardware::neuralnetworks::V1_3::utils diff --git a/neuralnetworks/1.3/utils/src/Callbacks.cpp b/neuralnetworks/1.3/utils/src/Callbacks.cpp new file mode 100644 index 0000000000..ff81275335 --- /dev/null +++ b/neuralnetworks/1.3/utils/src/Callbacks.cpp @@ -0,0 +1,184 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Callbacks.h" + +#include "Conversions.h" +#include "PreparedModel.h" +#include "Utils.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace android::hardware::neuralnetworks::V1_3::utils { +namespace { + +nn::GeneralResult convertPreparedModel( + const sp& preparedModel) { + return NN_TRY(V1_0::utils::PreparedModel::create(preparedModel)); +} + +nn::GeneralResult convertPreparedModel( + const sp& preparedModel) { + return NN_TRY(V1_2::utils::PreparedModel::create(preparedModel)); +} + +nn::GeneralResult convertPreparedModel( + const sp& preparedModel) { + return NN_TRY(utils::PreparedModel::create(preparedModel)); +} + +nn::GeneralResult, nn::Timing>> +convertExecutionGeneralResultsHelper(const hidl_vec& outputShapes, + const V1_2::Timing& timing) { + return std::make_pair(NN_TRY(validatedConvertToCanonical(outputShapes)), + NN_TRY(validatedConvertToCanonical(timing))); +} + +nn::ExecutionResult, nn::Timing>> +convertExecutionGeneralResults(const hidl_vec& outputShapes, + const V1_2::Timing& timing) { + return hal::utils::makeExecutionFailure( + convertExecutionGeneralResultsHelper(outputShapes, timing)); +} + +} // namespace + +Return PreparedModelCallback::notify(V1_0::ErrorStatus status, + const sp& preparedModel) { + if (status != V1_0::ErrorStatus::NONE) { + const auto canonical = + validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + notifyInternal(NN_ERROR(canonical) << "preparedModel failed with " << toString(status)); + } else if (preparedModel == nullptr) { + notifyInternal(NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) + << "Returned preparedModel is nullptr"); + } else { + notifyInternal(convertPreparedModel(preparedModel)); + } + return Void(); +} + +Return PreparedModelCallback::notify_1_2(V1_0::ErrorStatus status, + const sp& preparedModel) { + if (status != V1_0::ErrorStatus::NONE) { + const auto canonical = + validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + notifyInternal(NN_ERROR(canonical) << "preparedModel failed with " << toString(status)); + } else if (preparedModel == nullptr) { + notifyInternal(NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) + << "Returned preparedModel is nullptr"); + } else { + notifyInternal(convertPreparedModel(preparedModel)); + } + return Void(); +} + +Return PreparedModelCallback::notify_1_3(ErrorStatus status, + const sp& preparedModel) { + if (status != ErrorStatus::NONE) { + const auto canonical = + validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + notifyInternal(NN_ERROR(canonical) << "preparedModel failed with " << toString(status)); + } else if (preparedModel == nullptr) { + notifyInternal(NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) + << "Returned preparedModel is nullptr"); + } else { + notifyInternal(convertPreparedModel(preparedModel)); + } + return Void(); +} + +void PreparedModelCallback::notifyAsDeadObject() { + notifyInternal(NN_ERROR(nn::ErrorStatus::DEAD_OBJECT) << "Dead object"); +} + +PreparedModelCallback::Data PreparedModelCallback::get() { + return mData.take(); +} + +void PreparedModelCallback::notifyInternal(PreparedModelCallback::Data result) { + mData.put(std::move(result)); +} + +// ExecutionCallback methods begin here + +Return ExecutionCallback::notify(V1_0::ErrorStatus status) { + if (status != V1_0::ErrorStatus::NONE) { + const auto canonical = + validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + notifyInternal(NN_ERROR(canonical) << "execute failed with " << toString(status)); + } else { + notifyInternal({}); + } + return Void(); +} + +Return ExecutionCallback::notify_1_2(V1_0::ErrorStatus status, + const hidl_vec& outputShapes, + const V1_2::Timing& timing) { + if (status != V1_0::ErrorStatus::NONE) { + const auto canonical = + validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + notifyInternal(NN_ERROR(canonical) << "execute failed with " << toString(status)); + } else { + notifyInternal(convertExecutionGeneralResults(outputShapes, timing)); + } + return Void(); +} + +Return ExecutionCallback::notify_1_3(ErrorStatus status, + const hidl_vec& outputShapes, + const V1_2::Timing& timing) { + if (status != ErrorStatus::NONE) { + const auto canonical = + validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + notifyInternal(NN_ERROR(canonical) << "execute failed with " << toString(status)); + } else { + notifyInternal(convertExecutionGeneralResults(outputShapes, timing)); + } + return Void(); +} + +void ExecutionCallback::notifyAsDeadObject() { + notifyInternal(NN_ERROR(nn::ErrorStatus::DEAD_OBJECT) << "Dead object"); +} + +ExecutionCallback::Data ExecutionCallback::get() { + return mData.take(); +} + +void ExecutionCallback::notifyInternal(ExecutionCallback::Data result) { + mData.put(std::move(result)); +} + +} // namespace android::hardware::neuralnetworks::V1_3::utils diff --git a/neuralnetworks/1.3/utils/src/Conversions.cpp b/neuralnetworks/1.3/utils/src/Conversions.cpp index 4c54e3b12e..0dc078534c 100644 --- a/neuralnetworks/1.3/utils/src/Conversions.cpp +++ b/neuralnetworks/1.3/utils/src/Conversions.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -79,7 +80,7 @@ template using ConvertOutput = std::decay_t()).value())>; template -Result>> convertVec(const hidl_vec& arguments) { +GeneralResult>> convertVec(const hidl_vec& arguments) { std::vector> canonical; canonical.reserve(arguments.size()); for (const auto& argument : arguments) { @@ -89,25 +90,25 @@ Result>> convertVec(const hidl_vec& argume } template -Result>> convert(const hidl_vec& arguments) { +GeneralResult>> convert(const hidl_vec& arguments) { return convertVec(arguments); } } // anonymous namespace -Result convert(const hal::V1_3::OperandType& operandType) { +GeneralResult convert(const hal::V1_3::OperandType& operandType) { return static_cast(operandType); } -Result convert(const hal::V1_3::OperationType& operationType) { +GeneralResult convert(const hal::V1_3::OperationType& operationType) { return static_cast(operationType); } -Result convert(const hal::V1_3::Priority& priority) { +GeneralResult convert(const hal::V1_3::Priority& priority) { return static_cast(priority); } -Result convert(const hal::V1_3::Capabilities& capabilities) { +GeneralResult convert(const hal::V1_3::Capabilities& capabilities) { const bool validOperandTypes = std::all_of( capabilities.operandPerformance.begin(), capabilities.operandPerformance.end(), [](const hal::V1_3::Capabilities::OperandPerformance& operandPerformance) { @@ -115,13 +116,14 @@ Result convert(const hal::V1_3::Capabilities& capabilities) { return !maybeType.has_value() ? false : validOperandType(maybeType.value()); }); if (!validOperandTypes) { - return NN_ERROR() + return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "Invalid OperandType when converting OperandPerformance in Capabilities"; } auto operandPerformance = NN_TRY(convert(capabilities.operandPerformance)); - auto table = - NN_TRY(Capabilities::OperandPerformanceTable::create(std::move(operandPerformance))); + auto table = NN_TRY(hal::utils::makeGeneralFailure( + Capabilities::OperandPerformanceTable::create(std::move(operandPerformance)), + nn::ErrorStatus::GENERAL_FAILURE)); return Capabilities{ .relaxedFloat32toFloat16PerformanceScalar = @@ -134,7 +136,7 @@ Result convert(const hal::V1_3::Capabilities& capabilities) { }; } -Result convert( +GeneralResult convert( const hal::V1_3::Capabilities::OperandPerformance& operandPerformance) { return Capabilities::OperandPerformance{ .type = NN_TRY(convert(operandPerformance.type)), @@ -142,7 +144,7 @@ Result convert( }; } -Result convert(const hal::V1_3::Operation& operation) { +GeneralResult convert(const hal::V1_3::Operation& operation) { return Operation{ .type = NN_TRY(convert(operation.type)), .inputs = operation.inputs, @@ -150,11 +152,11 @@ Result convert(const hal::V1_3::Operation& operation) { }; } -Result convert(const hal::V1_3::OperandLifeTime& operandLifeTime) { +GeneralResult convert(const hal::V1_3::OperandLifeTime& operandLifeTime) { return static_cast(operandLifeTime); } -Result convert(const hal::V1_3::Operand& operand) { +GeneralResult convert(const hal::V1_3::Operand& operand) { return Operand{ .type = NN_TRY(convert(operand.type)), .dimensions = operand.dimensions, @@ -166,7 +168,7 @@ Result convert(const hal::V1_3::Operand& operand) { }; } -Result convert(const hal::V1_3::Model& model) { +GeneralResult convert(const hal::V1_3::Model& model) { return Model{ .main = NN_TRY(convert(model.main)), .referenced = NN_TRY(convert(model.referenced)), @@ -177,7 +179,7 @@ Result convert(const hal::V1_3::Model& model) { }; } -Result convert(const hal::V1_3::Subgraph& subgraph) { +GeneralResult convert(const hal::V1_3::Subgraph& subgraph) { auto operations = NN_TRY(convert(subgraph.operations)); // Verify number of consumers. @@ -186,9 +188,10 @@ Result convert(const hal::V1_3::Subgraph& subgraph) { CHECK(subgraph.operands.size() == numberOfConsumers.size()); for (size_t i = 0; i < subgraph.operands.size(); ++i) { if (subgraph.operands[i].numberOfConsumers != numberOfConsumers[i]) { - return NN_ERROR() << "Invalid numberOfConsumers for operand " << i << ", expected " - << numberOfConsumers[i] << " but found " - << subgraph.operands[i].numberOfConsumers; + return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) + << "Invalid numberOfConsumers for operand " << i << ", expected " + << numberOfConsumers[i] << " but found " + << subgraph.operands[i].numberOfConsumers; } } @@ -200,11 +203,11 @@ Result convert(const hal::V1_3::Subgraph& subgraph) { }; } -Result convert(const hal::V1_3::BufferDesc& bufferDesc) { +GeneralResult convert(const hal::V1_3::BufferDesc& bufferDesc) { return BufferDesc{.dimensions = bufferDesc.dimensions}; } -Result convert(const hal::V1_3::BufferRole& bufferRole) { +GeneralResult convert(const hal::V1_3::BufferRole& bufferRole) { return BufferRole{ .modelIndex = bufferRole.modelIndex, .ioIndex = bufferRole.ioIndex, @@ -212,7 +215,7 @@ Result convert(const hal::V1_3::BufferRole& bufferRole) { }; } -Result convert(const hal::V1_3::Request& request) { +GeneralResult convert(const hal::V1_3::Request& request) { return Request{ .inputs = NN_TRY(convert(request.inputs)), .outputs = NN_TRY(convert(request.outputs)), @@ -220,7 +223,7 @@ Result convert(const hal::V1_3::Request& request) { }; } -Result convert(const hal::V1_3::Request::MemoryPool& memoryPool) { +GeneralResult convert(const hal::V1_3::Request::MemoryPool& memoryPool) { using Discriminator = hal::V1_3::Request::MemoryPool::hidl_discriminator; switch (memoryPool.getDiscriminator()) { case Discriminator::hidlMemory: @@ -228,15 +231,16 @@ Result convert(const hal::V1_3::Request::MemoryPool& memory case Discriminator::token: return static_cast(memoryPool.token()); } - return NN_ERROR() << "Invalid Request::MemoryPool discriminator " - << underlyingType(memoryPool.getDiscriminator()); + return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) + << "Invalid Request::MemoryPool discriminator " + << underlyingType(memoryPool.getDiscriminator()); } -Result convert(const hal::V1_3::OptionalTimePoint& optionalTimePoint) { +GeneralResult convert(const hal::V1_3::OptionalTimePoint& optionalTimePoint) { constexpr auto kTimePointMaxCount = TimePoint::max().time_since_epoch().count(); - const auto makeTimePoint = [](uint64_t count) -> Result { + const auto makeTimePoint = [](uint64_t count) -> GeneralResult { if (count > kTimePointMaxCount) { - return NN_ERROR() + return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "Unable to convert OptionalTimePoint because the count exceeds the max"; } const auto nanoseconds = std::chrono::nanoseconds{count}; @@ -250,16 +254,17 @@ Result convert(const hal::V1_3::OptionalTimePoint& optionalTi case Discriminator::nanosecondsSinceEpoch: return makeTimePoint(optionalTimePoint.nanosecondsSinceEpoch()); } - return NN_ERROR() << "Invalid OptionalTimePoint discriminator " - << underlyingType(optionalTimePoint.getDiscriminator()); + return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) + << "Invalid OptionalTimePoint discriminator " + << underlyingType(optionalTimePoint.getDiscriminator()); } -Result convert( +GeneralResult convert( const hal::V1_3::OptionalTimeoutDuration& optionalTimeoutDuration) { constexpr auto kTimeoutDurationMaxCount = TimeoutDuration::max().count(); - const auto makeTimeoutDuration = [](uint64_t count) -> Result { + const auto makeTimeoutDuration = [](uint64_t count) -> GeneralResult { if (count > kTimeoutDurationMaxCount) { - return NN_ERROR() + return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "Unable to convert OptionalTimeoutDuration because the count exceeds the max"; } return TimeoutDuration{count}; @@ -272,11 +277,12 @@ Result convert( case Discriminator::nanoseconds: return makeTimeoutDuration(optionalTimeoutDuration.nanoseconds()); } - return NN_ERROR() << "Invalid OptionalTimeoutDuration discriminator " - << underlyingType(optionalTimeoutDuration.getDiscriminator()); + return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) + << "Invalid OptionalTimeoutDuration discriminator " + << underlyingType(optionalTimeoutDuration.getDiscriminator()); } -Result convert(const hal::V1_3::ErrorStatus& status) { +GeneralResult convert(const hal::V1_3::ErrorStatus& status) { switch (status) { case hal::V1_3::ErrorStatus::NONE: case hal::V1_3::ErrorStatus::DEVICE_UNAVAILABLE: @@ -289,10 +295,11 @@ Result convert(const hal::V1_3::ErrorStatus& status) { case hal::V1_3::ErrorStatus::RESOURCE_EXHAUSTED_PERSISTENT: return static_cast(status); } - return NN_ERROR() << "Invalid ErrorStatus " << underlyingType(status); + return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) + << "Invalid ErrorStatus " << underlyingType(status); } -Result> convert( +GeneralResult> convert( const hardware::hidl_vec& bufferRoles) { return convertVec(bufferRoles); } @@ -304,32 +311,32 @@ namespace { using utils::convert; -nn::Result convert( +nn::GeneralResult convert( const nn::Capabilities::PerformanceInfo& performanceInfo) { return V1_0::utils::convert(performanceInfo); } -nn::Result convert(const nn::DataLocation& dataLocation) { +nn::GeneralResult convert(const nn::DataLocation& dataLocation) { return V1_0::utils::convert(dataLocation); } -nn::Result> convert(const nn::Model::OperandValues& operandValues) { +nn::GeneralResult> convert(const nn::Model::OperandValues& operandValues) { return V1_0::utils::convert(operandValues); } -nn::Result convert(const nn::Memory& memory) { +nn::GeneralResult convert(const nn::Memory& memory) { return V1_0::utils::convert(memory); } -nn::Result convert(const nn::Request::Argument& argument) { +nn::GeneralResult convert(const nn::Request::Argument& argument) { return V1_0::utils::convert(argument); } -nn::Result convert(const nn::Operand::ExtraParams& extraParams) { +nn::GeneralResult convert(const nn::Operand::ExtraParams& extraParams) { return V1_2::utils::convert(extraParams); } -nn::Result convert( +nn::GeneralResult convert( const nn::Model::ExtensionNameAndPrefix& extensionNameAndPrefix) { return V1_2::utils::convert(extensionNameAndPrefix); } @@ -338,7 +345,7 @@ template using ConvertOutput = std::decay_t()).value())>; template -nn::Result>> convertVec(const std::vector& arguments) { +nn::GeneralResult>> convertVec(const std::vector& arguments) { hidl_vec> halObject(arguments.size()); for (size_t i = 0; i < arguments.size(); ++i) { halObject[i] = NN_TRY(convert(arguments[i])); @@ -347,42 +354,41 @@ nn::Result>> convertVec(const std::vector& ar } template -nn::Result>> convert(const std::vector& arguments) { +nn::GeneralResult>> convert(const std::vector& arguments) { return convertVec(arguments); } -nn::Result makeMemoryPool(const nn::Memory& memory) { +nn::GeneralResult makeMemoryPool(const nn::Memory& memory) { Request::MemoryPool ret; ret.hidlMemory(NN_TRY(convert(memory))); return ret; } -nn::Result makeMemoryPool(const nn::Request::MemoryDomainToken& token) { +nn::GeneralResult makeMemoryPool(const nn::Request::MemoryDomainToken& token) { Request::MemoryPool ret; ret.token(underlyingType(token)); return ret; } -nn::Result makeMemoryPool( - const std::shared_ptr& /*buffer*/) { - return NN_ERROR() << "Unable to make memory pool from IBuffer"; +nn::GeneralResult makeMemoryPool(const nn::SharedBuffer& /*buffer*/) { + return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "Unable to make memory pool from IBuffer"; } } // anonymous namespace -nn::Result convert(const nn::OperandType& operandType) { +nn::GeneralResult convert(const nn::OperandType& operandType) { return static_cast(operandType); } -nn::Result convert(const nn::OperationType& operationType) { +nn::GeneralResult convert(const nn::OperationType& operationType) { return static_cast(operationType); } -nn::Result convert(const nn::Priority& priority) { +nn::GeneralResult convert(const nn::Priority& priority) { return static_cast(priority); } -nn::Result convert(const nn::Capabilities& capabilities) { +nn::GeneralResult convert(const nn::Capabilities& capabilities) { std::vector operandPerformance; operandPerformance.reserve(capabilities.operandPerformance.asVector().size()); std::copy_if(capabilities.operandPerformance.asVector().begin(), @@ -403,7 +409,7 @@ nn::Result convert(const nn::Capabilities& capabilities) { }; } -nn::Result convert( +nn::GeneralResult convert( const nn::Capabilities::OperandPerformance& operandPerformance) { return Capabilities::OperandPerformance{ .type = NN_TRY(convert(operandPerformance.type)), @@ -411,7 +417,7 @@ nn::Result convert( }; } -nn::Result convert(const nn::Operation& operation) { +nn::GeneralResult convert(const nn::Operation& operation) { return Operation{ .type = NN_TRY(convert(operation.type)), .inputs = operation.inputs, @@ -419,14 +425,15 @@ nn::Result convert(const nn::Operation& operation) { }; } -nn::Result convert(const nn::Operand::LifeTime& operandLifeTime) { +nn::GeneralResult convert(const nn::Operand::LifeTime& operandLifeTime) { if (operandLifeTime == nn::Operand::LifeTime::POINTER) { - return NN_ERROR() << "Model cannot be converted because it contains pointer-based memory"; + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) + << "Model cannot be converted because it contains pointer-based memory"; } return static_cast(operandLifeTime); } -nn::Result convert(const nn::Operand& operand) { +nn::GeneralResult convert(const nn::Operand& operand) { return Operand{ .type = NN_TRY(convert(operand.type)), .dimensions = operand.dimensions, @@ -439,9 +446,10 @@ nn::Result convert(const nn::Operand& operand) { }; } -nn::Result convert(const nn::Model& model) { +nn::GeneralResult convert(const nn::Model& model) { if (!hal::utils::hasNoPointerData(model)) { - return NN_ERROR() << "Model cannot be converted because it contains pointer-based memory"; + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) + << "Model cannot be converted because it contains pointer-based memory"; } return Model{ @@ -454,7 +462,7 @@ nn::Result convert(const nn::Model& model) { }; } -nn::Result convert(const nn::Model::Subgraph& subgraph) { +nn::GeneralResult convert(const nn::Model::Subgraph& subgraph) { auto operands = NN_TRY(convert(subgraph.operands)); // Update number of consumers. @@ -473,11 +481,11 @@ nn::Result convert(const nn::Model::Subgraph& subgraph) { }; } -nn::Result convert(const nn::BufferDesc& bufferDesc) { +nn::GeneralResult convert(const nn::BufferDesc& bufferDesc) { return BufferDesc{.dimensions = bufferDesc.dimensions}; } -nn::Result convert(const nn::BufferRole& bufferRole) { +nn::GeneralResult convert(const nn::BufferRole& bufferRole) { return BufferRole{ .modelIndex = bufferRole.modelIndex, .ioIndex = bufferRole.ioIndex, @@ -485,9 +493,10 @@ nn::Result convert(const nn::BufferRole& bufferRole) { }; } -nn::Result convert(const nn::Request& request) { +nn::GeneralResult convert(const nn::Request& request) { if (!hal::utils::hasNoPointerData(request)) { - return NN_ERROR() << "Request cannot be converted because it contains pointer-based memory"; + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) + << "Request cannot be converted because it contains pointer-based memory"; } return Request{ @@ -497,30 +506,31 @@ nn::Result convert(const nn::Request& request) { }; } -nn::Result convert(const nn::Request::MemoryPool& memoryPool) { +nn::GeneralResult convert(const nn::Request::MemoryPool& memoryPool) { return std::visit([](const auto& o) { return makeMemoryPool(o); }, memoryPool); } -nn::Result convert(const nn::OptionalTimePoint& optionalTimePoint) { +nn::GeneralResult convert(const nn::OptionalTimePoint& optionalTimePoint) { OptionalTimePoint ret; if (optionalTimePoint.has_value()) { const auto count = optionalTimePoint.value().time_since_epoch().count(); if (count < 0) { - return NN_ERROR() << "Unable to convert OptionalTimePoint because time since epoch " - "count is negative"; + return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) + << "Unable to convert OptionalTimePoint because time since epoch count is " + "negative"; } ret.nanosecondsSinceEpoch(count); } return ret; } -nn::Result convert( +nn::GeneralResult convert( const nn::OptionalTimeoutDuration& optionalTimeoutDuration) { OptionalTimeoutDuration ret; if (optionalTimeoutDuration.has_value()) { const auto count = optionalTimeoutDuration.value().count(); if (count < 0) { - return NN_ERROR() + return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "Unable to convert OptionalTimeoutDuration because count is negative"; } ret.nanoseconds(count); @@ -528,7 +538,7 @@ nn::Result convert( return ret; } -nn::Result convert(const nn::ErrorStatus& errorStatus) { +nn::GeneralResult convert(const nn::ErrorStatus& errorStatus) { switch (errorStatus) { case nn::ErrorStatus::NONE: case nn::ErrorStatus::DEVICE_UNAVAILABLE: @@ -545,7 +555,7 @@ nn::Result convert(const nn::ErrorStatus& errorStatus) { } } -nn::Result> convert(const std::vector& bufferRoles) { +nn::GeneralResult> convert(const std::vector& bufferRoles) { return convertVec(bufferRoles); } diff --git a/neuralnetworks/1.3/utils/src/Device.cpp b/neuralnetworks/1.3/utils/src/Device.cpp new file mode 100644 index 0000000000..c215f39ecf --- /dev/null +++ b/neuralnetworks/1.3/utils/src/Device.cpp @@ -0,0 +1,269 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Device.h" + +#include "Buffer.h" +#include "Callbacks.h" +#include "Conversions.h" +#include "PreparedModel.h" +#include "Utils.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::V1_3::utils { +namespace { + +nn::GeneralResult>> convert( + const std::vector& preparedModels) { + hidl_vec> hidlPreparedModels(preparedModels.size()); + for (size_t i = 0; i < preparedModels.size(); ++i) { + std::any underlyingResource = preparedModels[i]->getUnderlyingResource(); + if (const auto* hidlPreparedModel = + std::any_cast>(&underlyingResource)) { + hidlPreparedModels[i] = *hidlPreparedModel; + } else { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) + << "Unable to convert from nn::IPreparedModel to V1_3::IPreparedModel"; + } + } + return hidlPreparedModels; +} + +nn::GeneralResult convert( + nn::GeneralResult> result) { + return NN_TRY(std::move(result)); +} + +} // namespace + +nn::GeneralResult> Device::create(std::string name, + sp device) { + if (name.empty()) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) + << "V1_3::utils::Device::create must have non-empty name"; + } + if (device == nullptr) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) + << "V1_3::utils::Device::create must have non-null device"; + } + + auto versionString = NN_TRY(V1_2::utils::initVersionString(device.get())); + const auto deviceType = NN_TRY(V1_2::utils::initDeviceType(device.get())); + auto extensions = NN_TRY(V1_2::utils::initExtensions(device.get())); + auto capabilities = NN_TRY(V1_2::utils::initCapabilities(device.get())); + const auto numberOfCacheFilesNeeded = + NN_TRY(V1_2::utils::initNumberOfCacheFilesNeeded(device.get())); + + auto deathHandler = NN_TRY(hal::utils::DeathHandler::create(device)); + return std::make_shared( + PrivateConstructorTag{}, std::move(name), std::move(versionString), deviceType, + std::move(extensions), std::move(capabilities), numberOfCacheFilesNeeded, + std::move(device), std::move(deathHandler)); +} + +Device::Device(PrivateConstructorTag /*tag*/, std::string name, std::string versionString, + nn::DeviceType deviceType, std::vector extensions, + nn::Capabilities capabilities, + std::pair numberOfCacheFilesNeeded, sp device, + hal::utils::DeathHandler deathHandler) + : kName(std::move(name)), + kVersionString(std::move(versionString)), + kDeviceType(deviceType), + kExtensions(std::move(extensions)), + kCapabilities(std::move(capabilities)), + kNumberOfCacheFilesNeeded(numberOfCacheFilesNeeded), + kDevice(std::move(device)), + kDeathHandler(std::move(deathHandler)) {} + +const std::string& Device::getName() const { + return kName; +} + +const std::string& Device::getVersionString() const { + return kVersionString; +} + +nn::Version Device::getFeatureLevel() const { + return nn::Version::ANDROID_R; +} + +nn::DeviceType Device::getType() const { + return kDeviceType; +} + +const std::vector& Device::getSupportedExtensions() const { + return kExtensions; +} + +const nn::Capabilities& Device::getCapabilities() const { + return kCapabilities; +} + +std::pair Device::getNumberOfCacheFilesNeeded() const { + return kNumberOfCacheFilesNeeded; +} + +nn::GeneralResult Device::wait() const { + const auto ret = kDevice->ping(); + return hal::utils::handleTransportError(ret); +} + +nn::GeneralResult> Device::getSupportedOperations(const nn::Model& model) const { + // Ensure that model is ready for IPC. + std::optional maybeModelInShared; + const nn::Model& modelInShared = + NN_TRY(hal::utils::flushDataFromPointerToShared(&model, &maybeModelInShared)); + + const auto hidlModel = NN_TRY(convert(modelInShared)); + + nn::GeneralResult> result = NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) + << "uninitialized"; + auto cb = [&result, &model](ErrorStatus status, const hidl_vec& supportedOperations) { + if (status != ErrorStatus::NONE) { + const auto canonical = + validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + result = NN_ERROR(canonical) + << "IDevice::getSupportedOperations_1_3 failed with " << toString(status); + } else if (supportedOperations.size() != model.main.operations.size()) { + result = NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) + << "IDevice::getSupportedOperations_1_3 returned vector of size " + << supportedOperations.size() << " but expected " + << model.main.operations.size(); + } else { + result = supportedOperations; + } + }; + + const auto ret = kDevice->getSupportedOperations_1_3(hidlModel, cb); + NN_TRY(hal::utils::handleTransportError(ret)); + + return result; +} + +nn::GeneralResult Device::prepareModel( + const nn::Model& model, nn::ExecutionPreference preference, nn::Priority priority, + nn::OptionalTimePoint deadline, const std::vector& modelCache, + const std::vector& dataCache, const nn::CacheToken& token) const { + // Ensure that model is ready for IPC. + std::optional maybeModelInShared; + const nn::Model& modelInShared = + NN_TRY(hal::utils::flushDataFromPointerToShared(&model, &maybeModelInShared)); + + const auto hidlModel = NN_TRY(convert(modelInShared)); + const auto hidlPreference = NN_TRY(V1_1::utils::convert(preference)); + const auto hidlPriority = NN_TRY(convert(priority)); + const auto hidlDeadline = NN_TRY(convert(deadline)); + const auto hidlModelCache = NN_TRY(V1_2::utils::convert(modelCache)); + const auto hidlDataCache = NN_TRY(V1_2::utils::convert(dataCache)); + const auto hidlToken = token; + + const auto cb = sp::make(); + const auto scoped = kDeathHandler.protectCallback(cb.get()); + + const auto ret = + kDevice->prepareModel_1_3(hidlModel, hidlPreference, hidlPriority, hidlDeadline, + hidlModelCache, hidlDataCache, hidlToken, cb); + const auto status = NN_TRY(hal::utils::handleTransportError(ret)); + if (status != ErrorStatus::NONE) { + const auto canonical = + validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + return NN_ERROR(canonical) << "prepareModel_1_3 failed with " << toString(status); + } + + return cb->get(); +} + +nn::GeneralResult Device::prepareModelFromCache( + nn::OptionalTimePoint deadline, const std::vector& modelCache, + const std::vector& dataCache, const nn::CacheToken& token) const { + const auto hidlDeadline = NN_TRY(convert(deadline)); + const auto hidlModelCache = NN_TRY(V1_2::utils::convert(modelCache)); + const auto hidlDataCache = NN_TRY(V1_2::utils::convert(dataCache)); + const auto hidlToken = token; + + const auto cb = sp::make(); + const auto scoped = kDeathHandler.protectCallback(cb.get()); + + const auto ret = kDevice->prepareModelFromCache_1_3(hidlDeadline, hidlModelCache, hidlDataCache, + hidlToken, cb); + const auto status = NN_TRY(hal::utils::handleTransportError(ret)); + if (status != ErrorStatus::NONE) { + const auto canonical = + validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + return NN_ERROR(canonical) << "prepareModelFromCache_1_3 failed with " << toString(status); + } + + return cb->get(); +} + +nn::GeneralResult Device::allocate( + const nn::BufferDesc& desc, const std::vector& preparedModels, + const std::vector& inputRoles, + const std::vector& outputRoles) const { + const auto hidlDesc = NN_TRY(convert(desc)); + const auto hidlPreparedModels = NN_TRY(convert(preparedModels)); + const auto hidlInputRoles = NN_TRY(convert(inputRoles)); + const auto hidlOutputRoles = NN_TRY(convert(outputRoles)); + + nn::GeneralResult result = NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) + << "uninitialized"; + auto cb = [&result](ErrorStatus status, const sp& buffer, uint32_t token) { + if (status != ErrorStatus::NONE) { + const auto canonical = + validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + result = NN_ERROR(canonical) << "IDevice::allocate failed with " << toString(status); + } else if (buffer == nullptr) { + result = NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "Returned buffer is nullptr"; + } else if (token == 0) { + result = NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "Returned token is invalid (0)"; + } else { + result = convert( + Buffer::create(buffer, static_cast(token))); + } + }; + + const auto ret = + kDevice->allocate(hidlDesc, hidlPreparedModels, hidlInputRoles, hidlOutputRoles, cb); + NN_TRY(hal::utils::handleTransportError(ret)); + + return result; +} + +} // namespace android::hardware::neuralnetworks::V1_3::utils diff --git a/neuralnetworks/1.3/utils/src/PreparedModel.cpp b/neuralnetworks/1.3/utils/src/PreparedModel.cpp new file mode 100644 index 0000000000..df9b280119 --- /dev/null +++ b/neuralnetworks/1.3/utils/src/PreparedModel.cpp @@ -0,0 +1,267 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "PreparedModel.h" + +#include "Callbacks.h" +#include "Conversions.h" +#include "Utils.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::V1_3::utils { +namespace { + +nn::GeneralResult, nn::Timing>> +convertExecutionResultsHelper(const hidl_vec& outputShapes, + const V1_2::Timing& timing) { + return std::make_pair(NN_TRY(validatedConvertToCanonical(outputShapes)), + NN_TRY(validatedConvertToCanonical(timing))); +} + +nn::ExecutionResult, nn::Timing>> convertExecutionResults( + const hidl_vec& outputShapes, const V1_2::Timing& timing) { + return hal::utils::makeExecutionFailure(convertExecutionResultsHelper(outputShapes, timing)); +} + +nn::GeneralResult> convertSyncFences( + const std::vector& syncFences) { + hidl_vec handles(syncFences.size()); + for (size_t i = 0; i < syncFences.size(); ++i) { + handles[i] = NN_TRY(V1_2::utils::convert(syncFences[i].getHandle())); + } + return handles; +} + +nn::GeneralResult> convertFencedExecutionCallbackResults( + const V1_2::Timing& timingLaunched, const V1_2::Timing& timingFenced) { + return std::make_pair(NN_TRY(validatedConvertToCanonical(timingLaunched)), + NN_TRY(validatedConvertToCanonical(timingFenced))); +} + +nn::GeneralResult> +convertExecuteFencedResults(const hidl_handle& syncFence, + const sp& callback) { + auto resultSyncFence = nn::SyncFence::createAsSignaled(); + if (syncFence.getNativeHandle() != nullptr) { + auto nativeHandle = NN_TRY(validatedConvertToCanonical(syncFence)); + resultSyncFence = NN_TRY(hal::utils::makeGeneralFailure( + nn::SyncFence::create(std::move(nativeHandle)), nn::ErrorStatus::GENERAL_FAILURE)); + } + + if (callback == nullptr) { + return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "callback is null"; + } + + // Create callback which can be used to retrieve the execution error status and timings. + nn::ExecuteFencedInfoCallback resultCallback = + [callback]() -> nn::GeneralResult> { + nn::GeneralResult> result = + NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "uninitialized"; + auto cb = [&result](ErrorStatus status, const V1_2::Timing& timingLaunched, + const V1_2::Timing& timingFenced) { + if (status != ErrorStatus::NONE) { + const auto canonical = validatedConvertToCanonical(status).value_or( + nn::ErrorStatus::GENERAL_FAILURE); + result = NN_ERROR(canonical) << "getExecutionInfo failed with " << toString(status); + } else { + result = convertFencedExecutionCallbackResults(timingLaunched, timingFenced); + } + }; + + const auto ret = callback->getExecutionInfo(cb); + NN_TRY(hal::utils::handleTransportError(ret)); + + return result; + }; + + return std::make_pair(std::move(resultSyncFence), std::move(resultCallback)); +} + +} // namespace + +nn::GeneralResult> PreparedModel::create( + sp preparedModel) { + if (preparedModel == nullptr) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) + << "V1_3::utils::PreparedModel::create must have non-null preparedModel"; + } + + auto deathHandler = NN_TRY(hal::utils::DeathHandler::create(preparedModel)); + return std::make_shared(PrivateConstructorTag{}, std::move(preparedModel), + std::move(deathHandler)); +} + +PreparedModel::PreparedModel(PrivateConstructorTag /*tag*/, sp preparedModel, + hal::utils::DeathHandler deathHandler) + : kPreparedModel(std::move(preparedModel)), kDeathHandler(std::move(deathHandler)) {} + +nn::ExecutionResult, nn::Timing>> +PreparedModel::executeSynchronously(const Request& request, V1_2::MeasureTiming measure, + const OptionalTimePoint& deadline, + const OptionalTimeoutDuration& loopTimeoutDuration) const { + nn::ExecutionResult, nn::Timing>> result = + NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "uninitialized"; + const auto cb = [&result](ErrorStatus status, const hidl_vec& outputShapes, + const V1_2::Timing& timing) { + if (status != ErrorStatus::NONE) { + const auto canonical = + validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + result = NN_ERROR(canonical) << "executeSynchronously failed with " << toString(status); + } else { + result = convertExecutionResults(outputShapes, timing); + } + }; + + const auto ret = kPreparedModel->executeSynchronously_1_3(request, measure, deadline, + loopTimeoutDuration, cb); + NN_TRY(hal::utils::makeExecutionFailure(hal::utils::handleTransportError(ret))); + + return result; +} + +nn::ExecutionResult, nn::Timing>> +PreparedModel::executeAsynchronously(const Request& request, V1_2::MeasureTiming measure, + const OptionalTimePoint& deadline, + const OptionalTimeoutDuration& loopTimeoutDuration) const { + const auto cb = sp::make(); + const auto scoped = kDeathHandler.protectCallback(cb.get()); + + const auto ret = + kPreparedModel->execute_1_3(request, measure, deadline, loopTimeoutDuration, cb); + const auto status = + NN_TRY(hal::utils::makeExecutionFailure(hal::utils::handleTransportError(ret))); + if (status != ErrorStatus::NONE) { + const auto canonical = + validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + return NN_ERROR(canonical) << "executeAsynchronously failed with " << toString(status); + } + + return cb->get(); +} + +nn::ExecutionResult, nn::Timing>> PreparedModel::execute( + const nn::Request& request, nn::MeasureTiming measure, + const nn::OptionalTimePoint& deadline, + const nn::OptionalTimeoutDuration& loopTimeoutDuration) const { + // Ensure that request is ready for IPC. + std::optional maybeRequestInShared; + const nn::Request& requestInShared = NN_TRY(hal::utils::makeExecutionFailure( + hal::utils::flushDataFromPointerToShared(&request, &maybeRequestInShared))); + + const auto hidlRequest = NN_TRY(hal::utils::makeExecutionFailure(convert(requestInShared))); + const auto hidlMeasure = + NN_TRY(hal::utils::makeExecutionFailure(V1_2::utils::convert(measure))); + const auto hidlDeadline = NN_TRY(hal::utils::makeExecutionFailure(convert(deadline))); + const auto hidlLoopTimeoutDuration = + NN_TRY(hal::utils::makeExecutionFailure(convert(loopTimeoutDuration))); + + nn::ExecutionResult, nn::Timing>> result = + NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "uninitialized"; + const bool preferSynchronous = true; + + // Execute synchronously if allowed. + if (preferSynchronous) { + result = executeSynchronously(hidlRequest, hidlMeasure, hidlDeadline, + hidlLoopTimeoutDuration); + } + + // Run asymchronous execution if execution has not already completed. + if (!result.has_value()) { + result = executeAsynchronously(hidlRequest, hidlMeasure, hidlDeadline, + hidlLoopTimeoutDuration); + } + + // Flush output buffers if suxcessful execution. + if (result.has_value()) { + NN_TRY(hal::utils::makeExecutionFailure( + hal::utils::unflushDataFromSharedToPointer(request, maybeRequestInShared))); + } + + return result; +} + +nn::GeneralResult> +PreparedModel::executeFenced(const nn::Request& request, const std::vector& waitFor, + nn::MeasureTiming measure, const nn::OptionalTimePoint& deadline, + const nn::OptionalTimeoutDuration& loopTimeoutDuration, + const nn::OptionalTimeoutDuration& timeoutDurationAfterFence) const { + // Ensure that request is ready for IPC. + std::optional maybeRequestInShared; + const nn::Request& requestInShared = + NN_TRY(hal::utils::flushDataFromPointerToShared(&request, &maybeRequestInShared)); + + const auto hidlRequest = NN_TRY(convert(requestInShared)); + const auto hidlWaitFor = NN_TRY(convertSyncFences(waitFor)); + const auto hidlMeasure = NN_TRY(V1_2::utils::convert(measure)); + const auto hidlDeadline = NN_TRY(convert(deadline)); + const auto hidlLoopTimeoutDuration = NN_TRY(convert(loopTimeoutDuration)); + const auto hidlTimeoutDurationAfterFence = NN_TRY(convert(timeoutDurationAfterFence)); + + nn::GeneralResult> result = + NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "uninitialized"; + auto cb = [&result](ErrorStatus status, const hidl_handle& syncFence, + const sp& callback) { + if (status != ErrorStatus::NONE) { + const auto canonical = + validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + result = NN_ERROR(canonical) << "executeFenced failed with " << toString(status); + } else { + result = convertExecuteFencedResults(syncFence, callback); + } + }; + + const auto ret = kPreparedModel->executeFenced(hidlRequest, hidlWaitFor, hidlMeasure, + hidlDeadline, hidlLoopTimeoutDuration, + hidlTimeoutDurationAfterFence, cb); + NN_TRY(hal::utils::handleTransportError(ret)); + auto [syncFence, callback] = NN_TRY(std::move(result)); + + // 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 (maybeRequestInShared.has_value()) { + const auto state = syncFence.syncWait({}); + if (state != nn::SyncFence::FenceState::SIGNALED) { + return NN_ERROR() << "syncWait failed with " << state; + } + NN_TRY(hal::utils::unflushDataFromSharedToPointer(request, maybeRequestInShared)); + } + + return std::make_pair(std::move(syncFence), std::move(callback)); +} + +std::any PreparedModel::getUnderlyingResource() const { + sp resource = kPreparedModel; + return resource; +} + +} // namespace android::hardware::neuralnetworks::V1_3::utils diff --git a/neuralnetworks/1.3/utils/src/Service.cpp b/neuralnetworks/1.3/utils/src/Service.cpp new file mode 100644 index 0000000000..62887fb41a --- /dev/null +++ b/neuralnetworks/1.3/utils/src/Service.cpp @@ -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. + */ + +#include "Service.h" + +#include +#include +#include +#include +#include +#include "Device.h" + +namespace android::hardware::neuralnetworks::V1_3::utils { + +nn::GeneralResult getDevice(const std::string& name) { + hal::utils::ResilientDevice::Factory makeDevice = + [name](bool blocking) -> nn::GeneralResult { + auto service = blocking ? IDevice::getService(name) : IDevice::tryGetService(name); + if (service == nullptr) { + return NN_ERROR() << (blocking ? "getService" : "tryGetService") << " returned nullptr"; + } + return Device::create(name, std::move(service)); + }; + + return hal::utils::ResilientDevice::create(std::move(makeDevice)); +} + +} // namespace android::hardware::neuralnetworks::V1_3::utils diff --git a/neuralnetworks/utils/common/Android.bp b/neuralnetworks/utils/common/Android.bp index b61dc970ed..21562cffaf 100644 --- a/neuralnetworks/utils/common/Android.bp +++ b/neuralnetworks/utils/common/Android.bp @@ -20,6 +20,7 @@ cc_library_static { srcs: ["src/*"], local_include_dirs: ["include/nnapi/hal"], export_include_dirs: ["include"], + cflags: ["-Wthread-safety"], static_libs: [ "neuralnetworks_types", ], diff --git a/neuralnetworks/utils/common/include/nnapi/hal/CommonUtils.h b/neuralnetworks/utils/common/include/nnapi/hal/CommonUtils.h index 8c013682ce..254a3d4acf 100644 --- a/neuralnetworks/utils/common/include/nnapi/hal/CommonUtils.h +++ b/neuralnetworks/utils/common/include/nnapi/hal/CommonUtils.h @@ -19,6 +19,7 @@ #include #include +#include #include // Shorthand @@ -42,14 +43,16 @@ bool hasNoPointerData(const nn::Model& model); bool hasNoPointerData(const nn::Request& request); // Relocate pointer-based data to shared memory. -nn::Result flushDataFromPointerToShared(const nn::Model& model); -nn::Result flushDataFromPointerToShared(const nn::Request& request); +nn::GeneralResult> flushDataFromPointerToShared( + const nn::Model* model, std::optional* maybeModelInSharedOut); +nn::GeneralResult> flushDataFromPointerToShared( + const nn::Request* request, std::optional* maybeRequestInSharedOut); // Undoes `flushDataFromPointerToShared` on a Request object. More specifically, // `unflushDataFromSharedToPointer` copies the output shared memory data from the transformed // Request object back to the output pointer-based memory in the original Request object. -nn::Result unflushDataFromSharedToPointer(const nn::Request& request, - const nn::Request& requestInShared); +nn::GeneralResult unflushDataFromSharedToPointer( + const nn::Request& request, const std::optional& maybeRequestInShared); std::vector countNumberOfConsumers(size_t numberOfOperands, const std::vector& operations); diff --git a/neuralnetworks/utils/common/include/nnapi/hal/HandleError.h b/neuralnetworks/utils/common/include/nnapi/hal/HandleError.h new file mode 100644 index 0000000000..e4046b5407 --- /dev/null +++ b/neuralnetworks/utils/common/include/nnapi/hal/HandleError.h @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::utils { + +template +nn::GeneralResult handleTransportError(const hardware::Return& ret) { + if (ret.isDeadObject()) { + return NN_ERROR(nn::ErrorStatus::DEAD_OBJECT) + << "Return<>::isDeadObject returned true: " << ret.description(); + } + if (!ret.isOk()) { + return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) + << "Return<>::isOk returned false: " << ret.description(); + } + return ret; +} + +template <> +inline nn::GeneralResult handleTransportError(const hardware::Return& ret) { + if (ret.isDeadObject()) { + return NN_ERROR(nn::ErrorStatus::DEAD_OBJECT) + << "Return<>::isDeadObject returned true: " << ret.description(); + } + if (!ret.isOk()) { + return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) + << "Return<>::isOk returned false: " << ret.description(); + } + return {}; +} + +template +nn::GeneralResult makeGeneralFailure(nn::Result result, nn::ErrorStatus status) { + if (!result.has_value()) { + return nn::error(status) << std::move(result).error(); + } + return std::move(result).value(); +} + +template <> +inline nn::GeneralResult makeGeneralFailure(nn::Result result, nn::ErrorStatus status) { + if (!result.has_value()) { + return nn::error(status) << std::move(result).error(); + } + return {}; +} + +template +nn::ExecutionResult makeExecutionFailure(nn::Result result, nn::ErrorStatus status) { + if (!result.has_value()) { + return nn::error(status) << std::move(result).error(); + } + return std::move(result).value(); +} + +template <> +inline nn::ExecutionResult makeExecutionFailure(nn::Result result, + nn::ErrorStatus status) { + if (!result.has_value()) { + return nn::error(status) << std::move(result).error(); + } + return {}; +} + +template +nn::ExecutionResult makeExecutionFailure(nn::GeneralResult result) { + if (!result.has_value()) { + const auto [message, status] = std::move(result).error(); + return nn::error(status) << message; + } + return std::move(result).value(); +} + +template <> +inline nn::ExecutionResult makeExecutionFailure(nn::GeneralResult result) { + if (!result.has_value()) { + const auto [message, status] = std::move(result).error(); + return nn::error(status) << message; + } + return {}; +} + +} // namespace android::hardware::neuralnetworks::utils \ No newline at end of file diff --git a/neuralnetworks/utils/common/include/nnapi/hal/ProtectCallback.h b/neuralnetworks/utils/common/include/nnapi/hal/ProtectCallback.h new file mode 100644 index 0000000000..85bd6137ee --- /dev/null +++ b/neuralnetworks/utils/common/include/nnapi/hal/ProtectCallback.h @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_PROTECT_CALLBACK_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_PROTECT_CALLBACK_H + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace android::hardware::neuralnetworks::utils { + +class IProtectedCallback { + public: + /** + * Marks this object as a dead object. + */ + virtual void notifyAsDeadObject() = 0; + + // Public virtual destructor to allow objects to be stored (and destroyed) as smart pointers. + // E.g., std::unique_ptr. + virtual ~IProtectedCallback() = default; + + protected: + // Protect the non-destructor special member functions to prevent object slicing. + IProtectedCallback() = default; + IProtectedCallback(const IProtectedCallback&) = default; + IProtectedCallback(IProtectedCallback&&) noexcept = default; + IProtectedCallback& operator=(const IProtectedCallback&) = default; + IProtectedCallback& operator=(IProtectedCallback&&) noexcept = default; +}; + +// Thread safe class +class DeathRecipient final : public hidl_death_recipient { + public: + void serviceDied(uint64_t /*cookie*/, const wp& /*who*/) override; + // Precondition: `killable` must be non-null. + void add(IProtectedCallback* killable) const; + // Precondition: `killable` must be non-null. + void remove(IProtectedCallback* killable) const; + + private: + mutable std::mutex mMutex; + mutable std::vector mObjects GUARDED_BY(mMutex); +}; + +class DeathHandler final { + public: + static nn::GeneralResult create(sp object); + + DeathHandler(const DeathHandler&) = delete; + DeathHandler(DeathHandler&&) noexcept = default; + DeathHandler& operator=(const DeathHandler&) = delete; + DeathHandler& operator=(DeathHandler&&) noexcept = delete; + ~DeathHandler(); + + using Cleanup = std::function; + // Precondition: `killable` must be non-null. + [[nodiscard]] base::ScopeGuard protectCallback(IProtectedCallback* killable) const; + + private: + DeathHandler(sp object, sp deathRecipient); + + sp kObject; + sp kDeathRecipient; +}; + +} // namespace android::hardware::neuralnetworks::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_PROTECT_CALLBACK_H diff --git a/neuralnetworks/utils/common/include/nnapi/hal/ResilientBuffer.h b/neuralnetworks/utils/common/include/nnapi/hal/ResilientBuffer.h new file mode 100644 index 0000000000..996ec1ee81 --- /dev/null +++ b/neuralnetworks/utils/common/include/nnapi/hal/ResilientBuffer.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_RESILIENT_BUFFER_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_RESILIENT_BUFFER_H + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::utils { + +class ResilientBuffer final : public nn::IBuffer { + struct PrivateConstructorTag {}; + + public: + using Factory = std::function(bool blocking)>; + + static nn::GeneralResult> create(Factory makeBuffer); + + explicit ResilientBuffer(PrivateConstructorTag tag, Factory makeBuffer, + nn::SharedBuffer buffer); + + nn::SharedBuffer getBuffer() const; + nn::SharedBuffer recover(const nn::IBuffer* failingBuffer, bool blocking) const; + + nn::Request::MemoryDomainToken getToken() const override; + + nn::GeneralResult copyTo(const nn::Memory& dst) const override; + + nn::GeneralResult copyFrom(const nn::Memory& src, + const nn::Dimensions& dimensions) const override; + + private: + const Factory kMakeBuffer; + mutable std::mutex mMutex; + mutable nn::SharedBuffer mBuffer GUARDED_BY(mMutex); +}; + +} // namespace android::hardware::neuralnetworks::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_RESILIENT_BUFFER_H diff --git a/neuralnetworks/utils/common/include/nnapi/hal/ResilientDevice.h b/neuralnetworks/utils/common/include/nnapi/hal/ResilientDevice.h new file mode 100644 index 0000000000..4f1afb983a --- /dev/null +++ b/neuralnetworks/utils/common/include/nnapi/hal/ResilientDevice.h @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_RESILIENT_DEVICE_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_RESILIENT_DEVICE_H + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::utils { + +class ResilientDevice final : public nn::IDevice, + public std::enable_shared_from_this { + struct PrivateConstructorTag {}; + + public: + using Factory = std::function(bool blocking)>; + + static nn::GeneralResult> create(Factory makeDevice); + + explicit ResilientDevice(PrivateConstructorTag tag, Factory makeDevice, std::string name, + std::string versionString, std::vector extensions, + nn::Capabilities capabilities, nn::SharedDevice device); + + nn::SharedDevice getDevice() const; + nn::SharedDevice recover(const nn::IDevice* failingDevice, bool blocking) const; + + const std::string& getName() const override; + const std::string& getVersionString() const override; + nn::Version getFeatureLevel() const override; + nn::DeviceType getType() const override; + const std::vector& getSupportedExtensions() const override; + const nn::Capabilities& getCapabilities() const override; + std::pair getNumberOfCacheFilesNeeded() const override; + + nn::GeneralResult wait() const override; + + nn::GeneralResult> getSupportedOperations( + const nn::Model& model) const override; + + nn::GeneralResult prepareModel( + const nn::Model& model, nn::ExecutionPreference preference, nn::Priority priority, + nn::OptionalTimePoint deadline, const std::vector& modelCache, + const std::vector& dataCache, + const nn::CacheToken& token) const override; + + nn::GeneralResult prepareModelFromCache( + nn::OptionalTimePoint deadline, const std::vector& modelCache, + const std::vector& dataCache, + const nn::CacheToken& token) const override; + + nn::GeneralResult allocate( + const nn::BufferDesc& desc, const std::vector& preparedModels, + const std::vector& inputRoles, + const std::vector& outputRoles) const override; + + private: + nn::GeneralResult prepareModelInternal( + bool blocking, const nn::Model& model, nn::ExecutionPreference preference, + nn::Priority priority, nn::OptionalTimePoint deadline, + const std::vector& modelCache, + const std::vector& dataCache, const nn::CacheToken& token) const; + nn::GeneralResult prepareModelFromCacheInternal( + bool blocking, nn::OptionalTimePoint deadline, + const std::vector& modelCache, + const std::vector& dataCache, const nn::CacheToken& token) const; + nn::GeneralResult allocateInternal( + bool blocking, const nn::BufferDesc& desc, + const std::vector& preparedModels, + const std::vector& inputRoles, + const std::vector& outputRoles) const; + + const Factory kMakeDevice; + const std::string kName; + const std::string kVersionString; + const std::vector kExtensions; + const nn::Capabilities kCapabilities; + mutable std::mutex mMutex; + mutable nn::SharedDevice mDevice GUARDED_BY(mMutex); +}; + +} // namespace android::hardware::neuralnetworks::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_RESILIENT_DEVICE_H diff --git a/neuralnetworks/utils/common/include/nnapi/hal/ResilientPreparedModel.h b/neuralnetworks/utils/common/include/nnapi/hal/ResilientPreparedModel.h new file mode 100644 index 0000000000..c2940d16bc --- /dev/null +++ b/neuralnetworks/utils/common/include/nnapi/hal/ResilientPreparedModel.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_RESILIENT_PREPARED_MODEL_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_RESILIENT_PREPARED_MODEL_H + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::utils { + +class ResilientPreparedModel final : public nn::IPreparedModel { + struct PrivateConstructorTag {}; + + public: + using Factory = std::function(bool blocking)>; + + static nn::GeneralResult> create( + Factory makePreparedModel); + + explicit ResilientPreparedModel(PrivateConstructorTag tag, Factory makePreparedModel, + nn::SharedPreparedModel preparedModel); + + nn::SharedPreparedModel getPreparedModel() const; + nn::SharedPreparedModel recover(const nn::IPreparedModel* failingPreparedModel, + bool blocking) const; + + nn::ExecutionResult, nn::Timing>> execute( + const nn::Request& request, nn::MeasureTiming measure, + const nn::OptionalTimePoint& deadline, + const nn::OptionalTimeoutDuration& loopTimeoutDuration) const override; + + nn::GeneralResult> executeFenced( + const nn::Request& request, const std::vector& waitFor, + nn::MeasureTiming measure, const nn::OptionalTimePoint& deadline, + const nn::OptionalTimeoutDuration& loopTimeoutDuration, + const nn::OptionalTimeoutDuration& timeoutDurationAfterFence) const override; + + std::any getUnderlyingResource() const override; + + private: + const Factory kMakePreparedModel; + mutable std::mutex mMutex; + mutable nn::SharedPreparedModel mPreparedModel GUARDED_BY(mMutex); +}; + +} // namespace android::hardware::neuralnetworks::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_RESILIENT_PREPARED_MODEL_H diff --git a/neuralnetworks/utils/common/include/nnapi/hal/TransferValue.h b/neuralnetworks/utils/common/include/nnapi/hal/TransferValue.h new file mode 100644 index 0000000000..7103c6b375 --- /dev/null +++ b/neuralnetworks/utils/common/include/nnapi/hal/TransferValue.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_TRANSFER_VALUE_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_TRANSFER_VALUE_H + +#include + +#include +#include +#include + +namespace android::hardware::neuralnetworks::utils { + +// This class is thread safe. +template +class TransferValue final { + public: + void put(Type object) const; + [[nodiscard]] Type take() const; + + private: + mutable std::mutex mMutex; + mutable std::condition_variable mCondition; + mutable std::optional mObject GUARDED_BY(mMutex); +}; + +// template implementation + +template +void TransferValue::put(Type object) const { + { + std::lock_guard guard(mMutex); + // Immediately return if value already exists. + if (mObject.has_value()) return; + mObject.emplace(std::move(object)); + } + mCondition.notify_all(); +} + +template +Type TransferValue::take() const { + std::unique_lock lock(mMutex); + base::ScopedLockAssertion lockAssertion(mMutex); + mCondition.wait(lock, [this]() REQUIRES(mMutex) { return mObject.has_value(); }); + std::optional object; + std::swap(object, mObject); + return std::move(object).value(); +} + +} // namespace android::hardware::neuralnetworks::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_TRANSFER_VALUE_H diff --git a/neuralnetworks/utils/common/src/CommonUtils.cpp b/neuralnetworks/utils/common/src/CommonUtils.cpp index 667189b2a0..25659728c3 100644 --- a/neuralnetworks/utils/common/src/CommonUtils.cpp +++ b/neuralnetworks/utils/common/src/CommonUtils.cpp @@ -16,6 +16,8 @@ #include "CommonUtils.h" +#include "HandleError.h" + #include #include #include @@ -25,6 +27,7 @@ #include #include +#include #include #include #include @@ -111,8 +114,18 @@ bool hasNoPointerData(const nn::Request& request) { return hasNoPointerData(request.inputs) && hasNoPointerData(request.outputs); } -nn::Result flushDataFromPointerToShared(const nn::Model& model) { - auto modelInShared = model; +nn::GeneralResult> flushDataFromPointerToShared( + const nn::Model* model, std::optional* maybeModelInSharedOut) { + CHECK(model != nullptr); + CHECK(maybeModelInSharedOut != nullptr); + + if (hasNoPointerData(*model)) { + return *model; + } + + // Make a copy of the model in order to make modifications. The modified model is returned to + // the caller through `maybeModelInSharedOut` if the function succeeds. + nn::Model modelInShared = *model; nn::ConstantMemoryBuilder memoryBuilder(modelInShared.pools.size()); copyPointersToSharedMemory(&modelInShared.main, &memoryBuilder); @@ -126,11 +139,22 @@ nn::Result flushDataFromPointerToShared(const nn::Model& model) { modelInShared.pools.push_back(std::move(memory)); } - return modelInShared; + *maybeModelInSharedOut = modelInShared; + return **maybeModelInSharedOut; } -nn::Result flushDataFromPointerToShared(const nn::Request& request) { - auto requestInShared = request; +nn::GeneralResult> flushDataFromPointerToShared( + const nn::Request* request, std::optional* maybeRequestInSharedOut) { + CHECK(request != nullptr); + CHECK(maybeRequestInSharedOut != nullptr); + + if (hasNoPointerData(*request)) { + return *request; + } + + // Make a copy of the request in order to make modifications. The modified request is returned + // to the caller through `maybeRequestInSharedOut` if the function succeeds. + nn::Request requestInShared = *request; // Change input pointers to shared memory. nn::ConstantMemoryBuilder inputBuilder(requestInShared.pools.size()); @@ -171,15 +195,17 @@ nn::Result flushDataFromPointerToShared(const nn::Request& request) requestInShared.pools.push_back(std::move(memory)); } - return requestInShared; + *maybeRequestInSharedOut = requestInShared; + return **maybeRequestInSharedOut; } -nn::Result unflushDataFromSharedToPointer(const nn::Request& request, - const nn::Request& requestInShared) { - if (requestInShared.pools.empty() || - !std::holds_alternative(requestInShared.pools.back())) { +nn::GeneralResult unflushDataFromSharedToPointer( + const nn::Request& request, const std::optional& maybeRequestInShared) { + if (!maybeRequestInShared.has_value() || maybeRequestInShared->pools.empty() || + !std::holds_alternative(maybeRequestInShared->pools.back())) { return {}; } + const auto& requestInShared = *maybeRequestInShared; // Map the memory. const auto& outputMemory = std::get(requestInShared.pools.back()); diff --git a/neuralnetworks/utils/common/src/ProtectCallback.cpp b/neuralnetworks/utils/common/src/ProtectCallback.cpp new file mode 100644 index 0000000000..1d9a3074db --- /dev/null +++ b/neuralnetworks/utils/common/src/ProtectCallback.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ProtectCallback.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::utils { + +void DeathRecipient::serviceDied(uint64_t /*cookie*/, const wp& /*who*/) { + std::lock_guard guard(mMutex); + std::for_each(mObjects.begin(), mObjects.end(), + [](IProtectedCallback* killable) { killable->notifyAsDeadObject(); }); +} + +void DeathRecipient::add(IProtectedCallback* killable) const { + CHECK(killable != nullptr); + std::lock_guard guard(mMutex); + mObjects.push_back(killable); +} + +void DeathRecipient::remove(IProtectedCallback* killable) const { + CHECK(killable != nullptr); + std::lock_guard guard(mMutex); + const auto removedIter = std::remove(mObjects.begin(), mObjects.end(), killable); + mObjects.erase(removedIter); +} + +nn::GeneralResult DeathHandler::create(sp object) { + if (object == nullptr) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) + << "utils::DeathHandler::create must have non-null object"; + } + auto deathRecipient = sp::make(); + + const auto ret = object->linkToDeath(deathRecipient, /*cookie=*/0); + const bool success = NN_TRY(handleTransportError(ret)); + if (!success) { + return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "IBase::linkToDeath returned false"; + } + + return DeathHandler(std::move(object), std::move(deathRecipient)); +} + +DeathHandler::DeathHandler(sp object, sp deathRecipient) + : kObject(std::move(object)), kDeathRecipient(std::move(deathRecipient)) { + CHECK(kObject != nullptr); + CHECK(kDeathRecipient != nullptr); +} + +DeathHandler::~DeathHandler() { + if (kObject != nullptr && kDeathRecipient != nullptr) { + const auto ret = kObject->unlinkToDeath(kDeathRecipient); + const auto maybeSuccess = handleTransportError(ret); + if (!maybeSuccess.has_value()) { + LOG(ERROR) << maybeSuccess.error().message; + } else if (!maybeSuccess.value()) { + LOG(ERROR) << "IBase::linkToDeath returned false"; + } + } +} + +[[nodiscard]] base::ScopeGuard DeathHandler::protectCallback( + IProtectedCallback* killable) const { + CHECK(killable != nullptr); + kDeathRecipient->add(killable); + return base::make_scope_guard( + [deathRecipient = kDeathRecipient, killable] { deathRecipient->remove(killable); }); +} + +} // namespace android::hardware::neuralnetworks::utils diff --git a/neuralnetworks/utils/common/src/ResilientBuffer.cpp b/neuralnetworks/utils/common/src/ResilientBuffer.cpp new file mode 100644 index 0000000000..984295b729 --- /dev/null +++ b/neuralnetworks/utils/common/src/ResilientBuffer.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ResilientBuffer.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::utils { + +nn::GeneralResult> ResilientBuffer::create( + Factory makeBuffer) { + if (makeBuffer == nullptr) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) + << "utils::ResilientBuffer::create must have non-empty makeBuffer"; + } + auto buffer = NN_TRY(makeBuffer(/*blocking=*/true)); + CHECK(buffer != nullptr); + return std::make_shared(PrivateConstructorTag{}, std::move(makeBuffer), + std::move(buffer)); +} + +ResilientBuffer::ResilientBuffer(PrivateConstructorTag /*tag*/, Factory makeBuffer, + nn::SharedBuffer buffer) + : kMakeBuffer(std::move(makeBuffer)), mBuffer(std::move(buffer)) { + CHECK(kMakeBuffer != nullptr); + CHECK(mBuffer != nullptr); +} + +nn::SharedBuffer ResilientBuffer::getBuffer() const { + std::lock_guard guard(mMutex); + return mBuffer; +} +nn::SharedBuffer ResilientBuffer::recover(const nn::IBuffer* /*failingBuffer*/, + bool /*blocking*/) const { + std::lock_guard guard(mMutex); + return mBuffer; +} + +nn::Request::MemoryDomainToken ResilientBuffer::getToken() const { + return getBuffer()->getToken(); +} + +nn::GeneralResult ResilientBuffer::copyTo(const nn::Memory& dst) const { + return getBuffer()->copyTo(dst); +} + +nn::GeneralResult ResilientBuffer::copyFrom(const nn::Memory& src, + const nn::Dimensions& dimensions) const { + return getBuffer()->copyFrom(src, dimensions); +} + +} // namespace android::hardware::neuralnetworks::utils diff --git a/neuralnetworks/utils/common/src/ResilientDevice.cpp b/neuralnetworks/utils/common/src/ResilientDevice.cpp new file mode 100644 index 0000000000..95662d96bd --- /dev/null +++ b/neuralnetworks/utils/common/src/ResilientDevice.cpp @@ -0,0 +1,236 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ResilientDevice.h" + +#include "ResilientBuffer.h" +#include "ResilientPreparedModel.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::utils { +namespace { + +template +auto protect(const ResilientDevice& resilientDevice, const FnType& fn, bool blocking) + -> decltype(fn(*resilientDevice.getDevice())) { + auto device = resilientDevice.getDevice(); + auto result = fn(*device); + + // Immediately return if device is not dead. + if (result.has_value() || result.error().code != nn::ErrorStatus::DEAD_OBJECT) { + return result; + } + + device = resilientDevice.recover(device.get(), blocking); + return fn(*device); +} + +} // namespace + +nn::GeneralResult> ResilientDevice::create( + Factory makeDevice) { + if (makeDevice == nullptr) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) + << "utils::ResilientDevice::create must have non-empty makeDevice"; + } + auto device = NN_TRY(makeDevice(/*blocking=*/true)); + CHECK(device != nullptr); + + auto name = device->getName(); + auto versionString = device->getVersionString(); + auto extensions = device->getSupportedExtensions(); + auto capabilities = device->getCapabilities(); + + return std::make_shared(PrivateConstructorTag{}, std::move(makeDevice), + std::move(name), std::move(versionString), + std::move(extensions), std::move(capabilities), + std::move(device)); +} + +ResilientDevice::ResilientDevice(PrivateConstructorTag /*tag*/, Factory makeDevice, + std::string name, std::string versionString, + std::vector extensions, + nn::Capabilities capabilities, nn::SharedDevice device) + : kMakeDevice(std::move(makeDevice)), + kName(std::move(name)), + kVersionString(std::move(versionString)), + kExtensions(std::move(extensions)), + kCapabilities(std::move(capabilities)), + mDevice(std::move(device)) { + CHECK(kMakeDevice != nullptr); + CHECK(mDevice != nullptr); +} + +nn::SharedDevice ResilientDevice::getDevice() const { + std::lock_guard guard(mMutex); + return mDevice; +} + +nn::SharedDevice ResilientDevice::recover(const nn::IDevice* failingDevice, bool blocking) const { + std::lock_guard guard(mMutex); + + // Another caller updated the failing device. + if (mDevice.get() != failingDevice) { + return mDevice; + } + + auto maybeDevice = kMakeDevice(blocking); + if (!maybeDevice.has_value()) { + const auto& [message, code] = maybeDevice.error(); + LOG(ERROR) << "Failed to recover dead device with error " << code << ": " << message; + return mDevice; + } + auto device = std::move(maybeDevice).value(); + + // TODO(b/173081926): Instead of CHECKing to ensure the cache has not been changed, return an + // invalid/"null" IDevice object that always fails. + CHECK_EQ(kName, device->getName()); + CHECK_EQ(kVersionString, device->getVersionString()); + CHECK(kExtensions == device->getSupportedExtensions()); + CHECK_EQ(kCapabilities, device->getCapabilities()); + + mDevice = std::move(device); + return mDevice; +} + +const std::string& ResilientDevice::getName() const { + return kName; +} + +const std::string& ResilientDevice::getVersionString() const { + return kVersionString; +} + +nn::Version ResilientDevice::getFeatureLevel() const { + return getDevice()->getFeatureLevel(); +} + +nn::DeviceType ResilientDevice::getType() const { + return getDevice()->getType(); +} + +const std::vector& ResilientDevice::getSupportedExtensions() const { + return kExtensions; +} + +const nn::Capabilities& ResilientDevice::getCapabilities() const { + return kCapabilities; +} + +std::pair ResilientDevice::getNumberOfCacheFilesNeeded() const { + return getDevice()->getNumberOfCacheFilesNeeded(); +} + +nn::GeneralResult ResilientDevice::wait() const { + const auto fn = [](const nn::IDevice& device) { return device.wait(); }; + return protect(*this, fn, /*blocking=*/true); +} + +nn::GeneralResult> ResilientDevice::getSupportedOperations( + const nn::Model& model) const { + const auto fn = [&model](const nn::IDevice& device) { + return device.getSupportedOperations(model); + }; + return protect(*this, fn, /*blocking=*/false); +} + +nn::GeneralResult ResilientDevice::prepareModel( + const nn::Model& model, nn::ExecutionPreference preference, nn::Priority priority, + nn::OptionalTimePoint deadline, const std::vector& modelCache, + const std::vector& dataCache, const nn::CacheToken& token) const { + auto self = shared_from_this(); + ResilientPreparedModel::Factory makePreparedModel = + [device = std::move(self), model, preference, priority, deadline, modelCache, dataCache, + token](bool blocking) -> nn::GeneralResult { + return device->prepareModelInternal(blocking, model, preference, priority, deadline, + modelCache, dataCache, token); + }; + return ResilientPreparedModel::create(std::move(makePreparedModel)); +} + +nn::GeneralResult ResilientDevice::prepareModelFromCache( + nn::OptionalTimePoint deadline, const std::vector& modelCache, + const std::vector& dataCache, const nn::CacheToken& token) const { + auto self = shared_from_this(); + ResilientPreparedModel::Factory makePreparedModel = + [device = std::move(self), deadline, modelCache, dataCache, + token](bool blocking) -> nn::GeneralResult { + return device->prepareModelFromCacheInternal(blocking, deadline, modelCache, dataCache, + token); + }; + return ResilientPreparedModel::create(std::move(makePreparedModel)); +} + +nn::GeneralResult ResilientDevice::allocate( + const nn::BufferDesc& desc, const std::vector& preparedModels, + const std::vector& inputRoles, + const std::vector& outputRoles) const { + auto self = shared_from_this(); + ResilientBuffer::Factory makeBuffer = + [device = std::move(self), desc, preparedModels, inputRoles, + outputRoles](bool blocking) -> nn::GeneralResult { + return device->allocateInternal(blocking, desc, preparedModels, inputRoles, outputRoles); + }; + return ResilientBuffer::create(std::move(makeBuffer)); +} + +nn::GeneralResult ResilientDevice::prepareModelInternal( + bool blocking, const nn::Model& model, nn::ExecutionPreference preference, + nn::Priority priority, nn::OptionalTimePoint deadline, + const std::vector& modelCache, + const std::vector& dataCache, const nn::CacheToken& token) const { + const auto fn = [&model, preference, priority, deadline, &modelCache, &dataCache, + token](const nn::IDevice& device) { + return device.prepareModel(model, preference, priority, deadline, modelCache, dataCache, + token); + }; + return protect(*this, fn, blocking); +} + +nn::GeneralResult ResilientDevice::prepareModelFromCacheInternal( + bool blocking, nn::OptionalTimePoint deadline, + const std::vector& modelCache, + const std::vector& dataCache, const nn::CacheToken& token) const { + const auto fn = [deadline, &modelCache, &dataCache, token](const nn::IDevice& device) { + return device.prepareModelFromCache(deadline, modelCache, dataCache, token); + }; + return protect(*this, fn, blocking); +} + +nn::GeneralResult ResilientDevice::allocateInternal( + bool blocking, const nn::BufferDesc& desc, + const std::vector& preparedModels, + const std::vector& inputRoles, + const std::vector& outputRoles) const { + const auto fn = [&desc, &preparedModels, &inputRoles, &outputRoles](const nn::IDevice& device) { + return device.allocate(desc, preparedModels, inputRoles, outputRoles); + }; + return protect(*this, fn, blocking); +} + +} // namespace android::hardware::neuralnetworks::utils diff --git a/neuralnetworks/utils/common/src/ResilientPreparedModel.cpp b/neuralnetworks/utils/common/src/ResilientPreparedModel.cpp new file mode 100644 index 0000000000..1c9ecba4f6 --- /dev/null +++ b/neuralnetworks/utils/common/src/ResilientPreparedModel.cpp @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ResilientPreparedModel.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::utils { + +nn::GeneralResult> ResilientPreparedModel::create( + Factory makePreparedModel) { + if (makePreparedModel == nullptr) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) + << "utils::ResilientPreparedModel::create must have non-empty makePreparedModel"; + } + auto preparedModel = NN_TRY(makePreparedModel(/*blocking=*/true)); + CHECK(preparedModel != nullptr); + return std::make_shared( + PrivateConstructorTag{}, std::move(makePreparedModel), std::move(preparedModel)); +} + +ResilientPreparedModel::ResilientPreparedModel(PrivateConstructorTag /*tag*/, + Factory makePreparedModel, + nn::SharedPreparedModel preparedModel) + : kMakePreparedModel(std::move(makePreparedModel)), mPreparedModel(std::move(preparedModel)) { + CHECK(kMakePreparedModel != nullptr); + CHECK(mPreparedModel != nullptr); +} + +nn::SharedPreparedModel ResilientPreparedModel::getPreparedModel() const { + std::lock_guard guard(mMutex); + return mPreparedModel; +} + +nn::SharedPreparedModel ResilientPreparedModel::recover( + const nn::IPreparedModel* /*failingPreparedModel*/, bool /*blocking*/) const { + std::lock_guard guard(mMutex); + return mPreparedModel; +} + +nn::ExecutionResult, nn::Timing>> +ResilientPreparedModel::execute(const nn::Request& request, nn::MeasureTiming measure, + const nn::OptionalTimePoint& deadline, + const nn::OptionalTimeoutDuration& loopTimeoutDuration) const { + return getPreparedModel()->execute(request, measure, deadline, loopTimeoutDuration); +} + +nn::GeneralResult> +ResilientPreparedModel::executeFenced( + const nn::Request& request, const std::vector& waitFor, + nn::MeasureTiming measure, const nn::OptionalTimePoint& deadline, + const nn::OptionalTimeoutDuration& loopTimeoutDuration, + const nn::OptionalTimeoutDuration& timeoutDurationAfterFence) const { + return getPreparedModel()->executeFenced(request, waitFor, measure, deadline, + loopTimeoutDuration, timeoutDurationAfterFence); +} + +std::any ResilientPreparedModel::getUnderlyingResource() const { + return getPreparedModel()->getUnderlyingResource(); +} + +} // namespace android::hardware::neuralnetworks::utils diff --git a/neuralnetworks/utils/service/Android.bp b/neuralnetworks/utils/service/Android.bp new file mode 100644 index 0000000000..87d27c7ac3 --- /dev/null +++ b/neuralnetworks/utils/service/Android.bp @@ -0,0 +1,36 @@ +// +// 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. +// + +cc_library_static { + name: "neuralnetworks_utils_hal_service", + defaults: ["neuralnetworks_utils_defaults"], + srcs: ["src/*"], + local_include_dirs: ["include/nnapi/hal"], + export_include_dirs: ["include"], + static_libs: [ + "neuralnetworks_types", + "neuralnetworks_utils_hal_1_0", + "neuralnetworks_utils_hal_1_1", + "neuralnetworks_utils_hal_1_2", + "neuralnetworks_utils_hal_1_3", + ], + shared_libs: [ + "android.hardware.neuralnetworks@1.0", + "android.hardware.neuralnetworks@1.1", + "android.hardware.neuralnetworks@1.2", + "android.hardware.neuralnetworks@1.3", + ], +} diff --git a/neuralnetworks/utils/service/include/nnapi/hal/Service.h b/neuralnetworks/utils/service/include/nnapi/hal/Service.h new file mode 100644 index 0000000000..e339627fd0 --- /dev/null +++ b/neuralnetworks/utils/service/include/nnapi/hal/Service.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_SERVICE_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_SERVICE_H + +#include +#include +#include +#include + +namespace android::nn::hal { + +std::vector getDevices(); + +} // namespace android::nn::hal + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_SERVICE_H diff --git a/neuralnetworks/utils/service/src/Service.cpp b/neuralnetworks/utils/service/src/Service.cpp new file mode 100644 index 0000000000..a59549dbf9 --- /dev/null +++ b/neuralnetworks/utils/service/src/Service.cpp @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Service.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::service { +namespace { + +using getDeviceFn = std::add_pointer_t(const std::string&)>; + +void getDevicesForVersion(const std::string& descriptor, getDeviceFn getDevice, + std::vector* devices, + std::unordered_set* registeredDevices) { + CHECK(devices != nullptr); + CHECK(registeredDevices != nullptr); + + const auto names = getAllHalInstanceNames(descriptor); + for (const auto& name : names) { + if (const auto [it, unregistered] = registeredDevices->insert(name); unregistered) { + auto maybeDevice = getDevice(name); + if (maybeDevice.has_value()) { + auto device = std::move(maybeDevice).value(); + CHECK(device != nullptr); + devices->push_back(std::move(device)); + } else { + LOG(ERROR) << "getDevice(" << name << ") failed with " << maybeDevice.error().code + << ": " << maybeDevice.error().message; + } + } + } +} + +std::vector getDevices() { + std::vector devices; + std::unordered_set registeredDevices; + + getDevicesForVersion(V1_3::IDevice::descriptor, &V1_3::utils::getDevice, &devices, + ®isteredDevices); + getDevicesForVersion(V1_2::IDevice::descriptor, &V1_2::utils::getDevice, &devices, + ®isteredDevices); + getDevicesForVersion(V1_1::IDevice::descriptor, &V1_1::utils::getDevice, &devices, + ®isteredDevices); + getDevicesForVersion(V1_0::IDevice::descriptor, &V1_0::utils::getDevice, &devices, + ®isteredDevices); + + return devices; +} + +} // namespace +} // namespace android::hardware::neuralnetworks::service + +namespace android::nn::hal { + +std::vector getDevices() { + return hardware::neuralnetworks::service::getDevices(); +} + +} // namespace android::nn::hal -- GitLab From 80b1861b20ad521da43f695ff6acb74d2ee9b0a9 Mon Sep 17 00:00:00 2001 From: Lais Andrade Date: Mon, 12 Oct 2020 18:44:40 +0000 Subject: [PATCH 281/790] Introduce IVibratorManager.aidl Introduce interface for vibrator manager HAL. A default implementation is made available to the existing android.hardware.vibrator-service.example, which now provides a top level devault IVibrator and a top level IVibratorManager with a different vibrator in it. VTS tests were also introduced for the new manager, and existing tests for IVibrator where changed to run in all top level and managed HAL instances found on a device. Bug: 166586119 Test: atest VtsHalVibratorTargetTest atest VtsHalVibratorManagerTargetTest Change-Id: Iec9175167e795bc03c4f3d873e2ac6682ed52512 --- .../compatibility_matrix.current.xml | 7 + .../vibrator/aidl/default/Android.bp | 4 +- vibrator/aidl/TEST_MAPPING | 3 + .../hardware/vibrator/IVibratorManager.aidl | 35 +++ .../hardware/vibrator/IVibratorManager.aidl | 102 ++++++++ vibrator/aidl/default/Android.bp | 9 +- vibrator/aidl/default/VibratorManager.cpp | 87 +++++++ .../include/vibrator-impl/VibratorManager.h | 44 ++++ vibrator/aidl/default/main.cpp | 16 +- vibrator/aidl/default/vibrator-default.xml | 4 + vibrator/aidl/vts/Android.bp | 21 +- .../vts/VtsHalVibratorManagerTargetTest.cpp | 220 ++++++++++++++++++ .../aidl/vts/VtsHalVibratorTargetTest.cpp | 61 ++++- 13 files changed, 599 insertions(+), 14 deletions(-) create mode 100644 vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibratorManager.aidl create mode 100644 vibrator/aidl/android/hardware/vibrator/IVibratorManager.aidl create mode 100644 vibrator/aidl/default/VibratorManager.cpp create mode 100644 vibrator/aidl/default/include/vibrator-impl/VibratorManager.h create mode 100644 vibrator/aidl/vts/VtsHalVibratorManagerTargetTest.cpp diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index 7a9feb2eab..ff925d90f1 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -534,6 +534,13 @@ default + + android.hardware.vibrator + + IVibratorManager + default + + android.hardware.vr 1.0 diff --git a/tests/extension/vibrator/aidl/default/Android.bp b/tests/extension/vibrator/aidl/default/Android.bp index ed40d259ab..80f7727646 100644 --- a/tests/extension/vibrator/aidl/default/Android.bp +++ b/tests/extension/vibrator/aidl/default/Android.bp @@ -19,7 +19,7 @@ cc_binary { shared_libs: [ "libbase", "libbinder_ndk", - "android.hardware.vibrator-ndk_platform", - "android.hardware.tests.extension.vibrator-ndk_platform", + "android.hardware.vibrator-unstable-ndk_platform", + "android.hardware.tests.extension.vibrator-unstable-ndk_platform", ], } diff --git a/vibrator/aidl/TEST_MAPPING b/vibrator/aidl/TEST_MAPPING index 5ae32e744c..2414b8464f 100644 --- a/vibrator/aidl/TEST_MAPPING +++ b/vibrator/aidl/TEST_MAPPING @@ -2,6 +2,9 @@ "presubmit": [ { "name": "VtsHalVibratorTargetTest" + }, + { + "name": "VtsHalVibratorManagerTargetTest" } ] } diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibratorManager.aidl b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibratorManager.aidl new file mode 100644 index 0000000000..99cd448f41 --- /dev/null +++ b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibratorManager.aidl @@ -0,0 +1,35 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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.vibrator; +@VintfStability +interface IVibratorManager { + int getCapabilities(); + int[] getVibratorIds(); + android.hardware.vibrator.IVibrator getVibrator(in int vibratorId); + void prepareSynced(in int[] vibratorIds); + void triggerSynced(in android.hardware.vibrator.IVibratorCallback callback); + void cancelSynced(); + const int CAP_SYNC = 1; + const int CAP_PREPARE_ON = 2; + const int CAP_PREPARE_PERFORM = 4; + const int CAP_PREPARE_COMPOSE = 8; + const int CAP_MIXED_TRIGGER_ON = 16; + const int CAP_MIXED_TRIGGER_PERFORM = 32; + const int CAP_MIXED_TRIGGER_COMPOSE = 64; + const int CAP_TRIGGER_CALLBACK = 128; +} diff --git a/vibrator/aidl/android/hardware/vibrator/IVibratorManager.aidl b/vibrator/aidl/android/hardware/vibrator/IVibratorManager.aidl new file mode 100644 index 0000000000..eb5e9ccd3f --- /dev/null +++ b/vibrator/aidl/android/hardware/vibrator/IVibratorManager.aidl @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.vibrator; + +import android.hardware.vibrator.IVibrator; +import android.hardware.vibrator.IVibratorCallback; + +@VintfStability +interface IVibratorManager { + /** + * Whether prepare/trigger synced are supported. + */ + const int CAP_SYNC = 1 << 0; + /** + * Whether IVibrator 'on' can be used with 'prepareSynced' function. + */ + const int CAP_PREPARE_ON = 1 << 1; + /** + * Whether IVibrator 'perform' can be used with 'prepareSynced' function. + */ + const int CAP_PREPARE_PERFORM = 1 << 2; + /** + * Whether IVibrator 'compose' can be used with 'prepareSynced' function. + */ + const int CAP_PREPARE_COMPOSE = 1 << 3; + /** + * Whether IVibrator 'on' can be triggered with other functions in sync with 'triggerSynced'. + */ + const int CAP_MIXED_TRIGGER_ON = 1 << 4; + /** + * Whether IVibrator 'perform' can be triggered with other functions in sync with 'triggerSynced'. + */ + const int CAP_MIXED_TRIGGER_PERFORM = 1 << 5; + /** + * Whether IVibrator 'compose' can be triggered with other functions in sync with 'triggerSynced'. + */ + const int CAP_MIXED_TRIGGER_COMPOSE = 1 << 6; + /** + * Whether on w/ IVibratorCallback can be used w/ 'trigerSynced' function. + */ + const int CAP_TRIGGER_CALLBACK = 1 << 7; + + /** + * Determine capabilities of the vibrator manager HAL (CAP_* mask) + */ + int getCapabilities(); + + /** + * List the id of available vibrators. This result should be static and not change. + */ + int[] getVibratorIds(); + + /** + * Return an available vibrator identified with given id. + */ + IVibrator getVibrator(in int vibratorId); + + /** + * Start preparation for a synced vibration + * + * This function must only be called after the previous synced vibration was triggered or + * canceled (through cancelSynced()). + * + * Doing this operation while any of the specified vibrators is already on is undefined behavior. + * Clients should explicitly call off in each vibrator. + * + * @param vibratorIds ids of the vibrators to play vibrations in sync. + */ + void prepareSynced(in int[] vibratorIds); + + /** + * Trigger a prepared synced vibration + * + * Trigger a previously-started preparation for synced vibration, if any. + * A callback is only expected to be supported when getCapabilities CAP_TRIGGER_CALLBACK + * is specified. + * + * @param callback A callback used to inform Frameworks of state change, if supported. + */ + void triggerSynced(in IVibratorCallback callback); + + /** + * Cancel preparation of synced vibration + * + * Cancel a previously-started preparation for synced vibration, if any. + */ + void cancelSynced(); +} diff --git a/vibrator/aidl/default/Android.bp b/vibrator/aidl/default/Android.bp index 9e6d9cf2d9..f9d45bb001 100644 --- a/vibrator/aidl/default/Android.bp +++ b/vibrator/aidl/default/Android.bp @@ -4,10 +4,13 @@ cc_library_static { shared_libs: [ "libbase", "libbinder_ndk", - "android.hardware.vibrator-ndk_platform", + "android.hardware.vibrator-unstable-ndk_platform", ], export_include_dirs: ["include"], - srcs: ["Vibrator.cpp"], + srcs: [ + "Vibrator.cpp", + "VibratorManager.cpp", + ], visibility: [ ":__subpackages__", "//hardware/interfaces/tests/extension/vibrator:__subpackages__", @@ -23,7 +26,7 @@ cc_binary { shared_libs: [ "libbase", "libbinder_ndk", - "android.hardware.vibrator-ndk_platform", + "android.hardware.vibrator-unstable-ndk_platform", ], static_libs: [ "libvibratorexampleimpl", diff --git a/vibrator/aidl/default/VibratorManager.cpp b/vibrator/aidl/default/VibratorManager.cpp new file mode 100644 index 0000000000..7cf9e6a5d8 --- /dev/null +++ b/vibrator/aidl/default/VibratorManager.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "vibrator-impl/VibratorManager.h" + +#include +#include + +namespace aidl { +namespace android { +namespace hardware { +namespace vibrator { + +static constexpr int32_t kDefaultVibratorId = 1; + +ndk::ScopedAStatus VibratorManager::getCapabilities(int32_t* _aidl_return) { + LOG(INFO) << "Vibrator manager reporting capabilities"; + *_aidl_return = + IVibratorManager::CAP_SYNC | IVibratorManager::CAP_PREPARE_ON | + IVibratorManager::CAP_PREPARE_PERFORM | IVibratorManager::CAP_PREPARE_COMPOSE | + IVibratorManager::CAP_MIXED_TRIGGER_ON | IVibratorManager::CAP_MIXED_TRIGGER_PERFORM | + IVibratorManager::CAP_MIXED_TRIGGER_COMPOSE | IVibratorManager::CAP_TRIGGER_CALLBACK; + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus VibratorManager::getVibratorIds(std::vector* _aidl_return) { + LOG(INFO) << "Vibrator manager getting vibrator ids"; + *_aidl_return = {kDefaultVibratorId}; + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus VibratorManager::getVibrator(int32_t vibratorId, + std::shared_ptr* _aidl_return) { + LOG(INFO) << "Vibrator manager getting vibrator " << vibratorId; + if (vibratorId == kDefaultVibratorId) { + *_aidl_return = mDefaultVibrator; + return ndk::ScopedAStatus::ok(); + } else { + *_aidl_return = nullptr; + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + } +} + +ndk::ScopedAStatus VibratorManager::prepareSynced(const std::vector& vibratorIds) { + LOG(INFO) << "Vibrator Manager prepare synced"; + if (vibratorIds.size() == 1 && vibratorIds[0] == kDefaultVibratorId) { + return ndk::ScopedAStatus::ok(); + } else { + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + } +} + +ndk::ScopedAStatus VibratorManager::triggerSynced( + const std::shared_ptr& callback) { + LOG(INFO) << "Vibrator Manager trigger synced"; + std::thread([=] { + if (callback != nullptr) { + LOG(INFO) << "Notifying perform complete"; + callback->onComplete(); + } + }).detach(); + + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus VibratorManager::cancelSynced() { + LOG(INFO) << "Vibrator Manager cancel synced"; + return ndk::ScopedAStatus::ok(); +} + +} // namespace vibrator +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/vibrator/aidl/default/include/vibrator-impl/VibratorManager.h b/vibrator/aidl/default/include/vibrator-impl/VibratorManager.h new file mode 100644 index 0000000000..319eb05c1f --- /dev/null +++ b/vibrator/aidl/default/include/vibrator-impl/VibratorManager.h @@ -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. + */ + +#pragma once + +#include + +namespace aidl { +namespace android { +namespace hardware { +namespace vibrator { + +class VibratorManager : public BnVibratorManager { + public: + VibratorManager(std::shared_ptr vibrator) : mDefaultVibrator(std::move(vibrator)){}; + ndk::ScopedAStatus getCapabilities(int32_t* _aidl_return) override; + ndk::ScopedAStatus getVibratorIds(std::vector* _aidl_return) override; + ndk::ScopedAStatus getVibrator(int32_t vibratorId, + std::shared_ptr* _aidl_return) override; + ndk::ScopedAStatus prepareSynced(const std::vector& vibratorIds) override; + ndk::ScopedAStatus triggerSynced(const std::shared_ptr& callback) override; + ndk::ScopedAStatus cancelSynced() override; + + private: + std::shared_ptr mDefaultVibrator; +}; + +} // namespace vibrator +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/vibrator/aidl/default/main.cpp b/vibrator/aidl/default/main.cpp index ebb0905a3a..bd834d2a21 100644 --- a/vibrator/aidl/default/main.cpp +++ b/vibrator/aidl/default/main.cpp @@ -15,19 +15,29 @@ */ #include "vibrator-impl/Vibrator.h" +#include "vibrator-impl/VibratorManager.h" #include #include #include using aidl::android::hardware::vibrator::Vibrator; +using aidl::android::hardware::vibrator::VibratorManager; int main() { ABinderProcess_setThreadPoolMaxThreadCount(0); - std::shared_ptr vib = ndk::SharedRefBase::make(); - const std::string instance = std::string() + Vibrator::descriptor + "/default"; - binder_status_t status = AServiceManager_addService(vib->asBinder().get(), instance.c_str()); + // make a default vibrator service + auto vib = ndk::SharedRefBase::make(); + const std::string vibName = std::string() + Vibrator::descriptor + "/default"; + binder_status_t status = AServiceManager_addService(vib->asBinder().get(), vibName.c_str()); + CHECK(status == STATUS_OK); + + // make the vibrator manager service with a different vibrator + auto managedVib = ndk::SharedRefBase::make(); + auto vibManager = ndk::SharedRefBase::make(std::move(managedVib)); + const std::string vibManagerName = std::string() + VibratorManager::descriptor + "/default"; + status = AServiceManager_addService(vibManager->asBinder().get(), vibManagerName.c_str()); CHECK(status == STATUS_OK); ABinderProcess_joinThreadPool(); diff --git a/vibrator/aidl/default/vibrator-default.xml b/vibrator/aidl/default/vibrator-default.xml index 49b11ec8da..9f9cd40c4e 100644 --- a/vibrator/aidl/default/vibrator-default.xml +++ b/vibrator/aidl/default/vibrator-default.xml @@ -3,4 +3,8 @@ android.hardware.vibrator IVibrator/default + + android.hardware.vibrator + IVibratorManager/default + diff --git a/vibrator/aidl/vts/Android.bp b/vibrator/aidl/vts/Android.bp index 28cb4d9856..d06b50efe3 100644 --- a/vibrator/aidl/vts/Android.bp +++ b/vibrator/aidl/vts/Android.bp @@ -9,7 +9,26 @@ cc_test { "libbinder", ], static_libs: [ - "android.hardware.vibrator-cpp", + "android.hardware.vibrator-unstable-cpp", + ], + test_suites: [ + "general-tests", + "vts", + ], +} + +cc_test { + name: "VtsHalVibratorManagerTargetTest", + defaults: [ + "VtsHalTargetTestDefaults", + "use_libaidlvintf_gtest_helper_static", + ], + srcs: ["VtsHalVibratorManagerTargetTest.cpp"], + shared_libs: [ + "libbinder", + ], + static_libs: [ + "android.hardware.vibrator-unstable-cpp", ], test_suites: [ "general-tests", diff --git a/vibrator/aidl/vts/VtsHalVibratorManagerTargetTest.cpp b/vibrator/aidl/vts/VtsHalVibratorManagerTargetTest.cpp new file mode 100644 index 0000000000..9789188858 --- /dev/null +++ b/vibrator/aidl/vts/VtsHalVibratorManagerTargetTest.cpp @@ -0,0 +1,220 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +using android::ProcessState; +using android::sp; +using android::String16; +using android::binder::Status; +using android::hardware::vibrator::BnVibratorCallback; +using android::hardware::vibrator::CompositeEffect; +using android::hardware::vibrator::CompositePrimitive; +using android::hardware::vibrator::Effect; +using android::hardware::vibrator::EffectStrength; +using android::hardware::vibrator::IVibrator; +using android::hardware::vibrator::IVibratorManager; +using std::chrono::high_resolution_clock; + +const std::vector kEffects{android::enum_range().begin(), + android::enum_range().end()}; +const std::vector kEffectStrengths{android::enum_range().begin(), + android::enum_range().end()}; +const std::vector kPrimitives{android::enum_range().begin(), + android::enum_range().end()}; + +class CompletionCallback : public BnVibratorCallback { + public: + CompletionCallback(const std::function& callback) : mCallback(callback) {} + Status onComplete() override { + mCallback(); + return Status::ok(); + } + + private: + std::function mCallback; +}; + +class VibratorAidl : public testing::TestWithParam { + public: + virtual void SetUp() override { + manager = android::waitForDeclaredService(String16(GetParam().c_str())); + ASSERT_NE(manager, nullptr); + ASSERT_TRUE(manager->getCapabilities(&capabilities).isOk()); + EXPECT_TRUE(manager->getVibratorIds(&vibratorIds).isOk()); + } + + sp manager; + int32_t capabilities; + std::vector vibratorIds; +}; + +TEST_P(VibratorAidl, ValidateExistingVibrators) { + sp vibrator; + for (auto& id : vibratorIds) { + EXPECT_TRUE(manager->getVibrator(id, &vibrator).isOk()); + ASSERT_NE(vibrator, nullptr); + } +} + +TEST_P(VibratorAidl, GetVibratorWithInvalidId) { + int32_t invalidId = *max_element(vibratorIds.begin(), vibratorIds.end()) + 1; + sp vibrator; + EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, + manager->getVibrator(invalidId, &vibrator).exceptionCode()); + ASSERT_EQ(vibrator, nullptr); +} + +TEST_P(VibratorAidl, ValidatePrepareSyncedExistingVibrators) { + if (!(capabilities & IVibratorManager::CAP_SYNC)) return; + if (vibratorIds.empty()) return; + EXPECT_TRUE(manager->prepareSynced(vibratorIds).isOk()); +} + +TEST_P(VibratorAidl, PrepareSyncedEmptySetIsInvalid) { + if (!(capabilities & IVibratorManager::CAP_SYNC)) return; + std::vector emptyIds; + EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, manager->prepareSynced(emptyIds).exceptionCode()); +} + +TEST_P(VibratorAidl, PrepareSyncedNotSupported) { + if (!(capabilities & IVibratorManager::CAP_SYNC)) { + EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION, + manager->prepareSynced(vibratorIds).exceptionCode()); + } +} + +TEST_P(VibratorAidl, PrepareOnNotSupported) { + if (vibratorIds.empty()) return; + if (!(capabilities & IVibratorManager::CAP_SYNC)) return; + if (!(capabilities & IVibratorManager::CAP_PREPARE_ON)) { + uint32_t durationMs = 250; + EXPECT_TRUE(manager->prepareSynced(vibratorIds).isOk()); + sp vibrator; + for (auto& id : vibratorIds) { + EXPECT_TRUE(manager->getVibrator(id, &vibrator).isOk()); + ASSERT_NE(vibrator, nullptr); + EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION, + vibrator->on(durationMs, nullptr).exceptionCode()); + } + EXPECT_TRUE(manager->cancelSynced().isOk()); + } +} + +TEST_P(VibratorAidl, PreparePerformNotSupported) { + if (vibratorIds.empty()) return; + if (!(capabilities & IVibratorManager::CAP_SYNC)) return; + if (!(capabilities & IVibratorManager::CAP_PREPARE_ON)) { + EXPECT_TRUE(manager->prepareSynced(vibratorIds).isOk()); + sp vibrator; + for (auto& id : vibratorIds) { + EXPECT_TRUE(manager->getVibrator(id, &vibrator).isOk()); + ASSERT_NE(vibrator, nullptr); + int32_t lengthMs = 0; + Status status = vibrator->perform(kEffects[0], kEffectStrengths[0], nullptr, &lengthMs); + EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION, status.exceptionCode()); + } + EXPECT_TRUE(manager->cancelSynced().isOk()); + } +} + +TEST_P(VibratorAidl, PrepareComposeNotSupported) { + if (vibratorIds.empty()) return; + if (!(capabilities & IVibratorManager::CAP_SYNC)) return; + if (!(capabilities & IVibratorManager::CAP_PREPARE_ON)) { + std::vector composite; + CompositeEffect effect; + effect.delayMs = 10; + effect.primitive = kPrimitives[0]; + effect.scale = 1.0f; + composite.emplace_back(effect); + + EXPECT_TRUE(manager->prepareSynced(vibratorIds).isOk()); + sp vibrator; + for (auto& id : vibratorIds) { + EXPECT_TRUE(manager->getVibrator(id, &vibrator).isOk()); + ASSERT_NE(vibrator, nullptr); + Status status = vibrator->compose(composite, nullptr); + EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION, status.exceptionCode()); + } + EXPECT_TRUE(manager->cancelSynced().isOk()); + } +} + +TEST_P(VibratorAidl, TriggerWithCallback) { + if (!(capabilities & IVibratorManager::CAP_SYNC)) return; + if (!(capabilities & IVibratorManager::CAP_PREPARE_ON)) return; + if (!(capabilities & IVibratorManager::CAP_TRIGGER_CALLBACK)) return; + if (vibratorIds.empty()) return; + + std::promise completionPromise; + std::future completionFuture{completionPromise.get_future()}; + sp callback = + new CompletionCallback([&completionPromise] { completionPromise.set_value(); }); + uint32_t durationMs = 250; + std::chrono::milliseconds timeout{durationMs * 2}; + + EXPECT_TRUE(manager->prepareSynced(vibratorIds).isOk()); + sp vibrator; + for (auto& id : vibratorIds) { + EXPECT_TRUE(manager->getVibrator(id, &vibrator).isOk()); + ASSERT_NE(vibrator, nullptr); + EXPECT_TRUE(vibrator->on(durationMs, nullptr).isOk()); + } + + EXPECT_TRUE(manager->triggerSynced(callback).isOk()); + EXPECT_EQ(completionFuture.wait_for(timeout), std::future_status::ready); + EXPECT_TRUE(manager->cancelSynced().isOk()); +} + +TEST_P(VibratorAidl, TriggerSyncNotSupported) { + if (!(capabilities & IVibratorManager::CAP_SYNC)) { + EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION, + manager->triggerSynced(nullptr).exceptionCode()); + } +} + +TEST_P(VibratorAidl, TriggerCallbackNotSupported) { + if (!(capabilities & IVibratorManager::CAP_SYNC)) return; + if (!(capabilities & IVibratorManager::CAP_TRIGGER_CALLBACK)) { + sp callback = new CompletionCallback([] {}); + EXPECT_TRUE(manager->prepareSynced(vibratorIds).isOk()); + EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION, + manager->triggerSynced(callback).exceptionCode()); + } +} + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VibratorAidl); +INSTANTIATE_TEST_SUITE_P( + Vibrator, VibratorAidl, + testing::ValuesIn(android::getAidlHalInstanceNames(IVibratorManager::descriptor)), + android::PrintInstanceNameToString); + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + ProcessState::self()->setThreadPoolMaxThreadCount(1); + ProcessState::self()->startThreadPool(); + return RUN_ALL_TESTS(); +} diff --git a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp index 888a4031bf..dfd2524114 100644 --- a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp +++ b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -34,6 +35,7 @@ using android::hardware::vibrator::CompositePrimitive; using android::hardware::vibrator::Effect; using android::hardware::vibrator::EffectStrength; using android::hardware::vibrator::IVibrator; +using android::hardware::vibrator::IVibratorManager; using std::chrono::high_resolution_clock; const std::vector kEffects{android::enum_range().begin(), @@ -77,10 +79,28 @@ class CompletionCallback : public BnVibratorCallback { std::function mCallback; }; -class VibratorAidl : public testing::TestWithParam { +class VibratorAidl : public testing::TestWithParam> { public: virtual void SetUp() override { - vibrator = android::waitForDeclaredService(String16(GetParam().c_str())); + int32_t managerIdx = std::get<0>(GetParam()); + int32_t vibratorId = std::get<1>(GetParam()); + auto managerAidlNames = android::getAidlHalInstanceNames(IVibratorManager::descriptor); + + if (managerIdx < 0) { + // Testing a unmanaged vibrator, using vibratorId as index from registered HALs + auto vibratorAidlNames = android::getAidlHalInstanceNames(IVibrator::descriptor); + ASSERT_LT(vibratorId, vibratorAidlNames.size()); + auto vibratorName = String16(vibratorAidlNames[vibratorId].c_str()); + vibrator = android::waitForDeclaredService(vibratorName); + } else { + // Testing a managed vibrator, using vibratorId to retrieve it from the manager + ASSERT_LT(managerIdx, managerAidlNames.size()); + auto managerName = String16(managerAidlNames[managerIdx].c_str()); + auto vibratorManager = android::waitForDeclaredService(managerName); + auto vibratorResult = vibratorManager->getVibrator(vibratorId, &vibrator); + ASSERT_TRUE(vibratorResult.isOk()); + } + ASSERT_NE(vibrator, nullptr); ASSERT_TRUE(vibrator->getCapabilities(&capabilities).isOk()); } @@ -518,10 +538,41 @@ TEST_P(VibratorAidl, AlwaysOn) { } } +std::vector> GenerateVibratorMapping() { + std::vector> tuples; + auto managerAidlNames = android::getAidlHalInstanceNames(IVibratorManager::descriptor); + std::vector vibratorIds; + + for (int i = 0; i < managerAidlNames.size(); i++) { + auto managerName = String16(managerAidlNames[i].c_str()); + auto vibratorManager = android::waitForDeclaredService(managerName); + if (vibratorManager->getVibratorIds(&vibratorIds).isOk()) { + for (auto& vibratorId : vibratorIds) { + tuples.push_back(std::make_tuple(i, vibratorId)); + } + } + } + + auto vibratorAidlNames = android::getAidlHalInstanceNames(IVibrator::descriptor); + for (int i = 0; i < vibratorAidlNames.size(); i++) { + tuples.push_back(std::make_tuple(-1, i)); + } + + return tuples; +} + +std::string PrintGeneratedTest(const testing::TestParamInfo& info) { + const auto& [managerIdx, vibratorId] = info.param; + if (managerIdx < 0) { + return std::string("TOP_LEVEL_VIBRATOR_") + std::to_string(vibratorId); + } + return std::string("MANAGER_") + std::to_string(managerIdx) + "_VIBRATOR_ID_" + + std::to_string(vibratorId); +} + GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VibratorAidl); -INSTANTIATE_TEST_SUITE_P(Vibrator, VibratorAidl, - testing::ValuesIn(android::getAidlHalInstanceNames(IVibrator::descriptor)), - android::PrintInstanceNameToString); +INSTANTIATE_TEST_SUITE_P(Vibrator, VibratorAidl, testing::ValuesIn(GenerateVibratorMapping()), + PrintGeneratedTest); int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); -- GitLab From d4290b8bf8f9da1b7b34db3963762810258b132e Mon Sep 17 00:00:00 2001 From: Slava Shklyaev Date: Tue, 27 Oct 2020 18:44:01 +0000 Subject: [PATCH 282/790] Replace nn::NativeHandle with nn::SharedHandle Bug: 160669116 Test: mma Change-Id: I73b2b93aab6cbf37d3c145e15ee9ae45228954f1 --- .../1.0/utils/include/nnapi/hal/1.0/Device.h | 8 +-- neuralnetworks/1.0/utils/src/Conversions.cpp | 6 +- neuralnetworks/1.0/utils/src/Device.cpp | 8 +-- .../1.1/utils/include/nnapi/hal/1.1/Device.h | 8 +-- neuralnetworks/1.1/utils/src/Device.cpp | 8 +-- .../utils/include/nnapi/hal/1.2/Conversions.h | 8 +-- .../1.2/utils/include/nnapi/hal/1.2/Device.h | 8 +-- neuralnetworks/1.2/utils/src/Conversions.cpp | 16 ++--- neuralnetworks/1.2/utils/src/Device.cpp | 8 +-- .../1.3/utils/include/nnapi/hal/1.3/Device.h | 8 +-- neuralnetworks/1.3/utils/src/Device.cpp | 8 +-- .../1.3/utils/src/PreparedModel.cpp | 11 +--- .../common/include/nnapi/hal/CommonUtils.h | 9 +++ .../include/nnapi/hal/ResilientDevice.h | 16 ++--- .../utils/common/src/CommonUtils.cpp | 64 +++++++++++++++++++ .../utils/common/src/ResilientDevice.cpp | 16 ++--- neuralnetworks/utils/service/Android.bp | 1 + 17 files changed, 135 insertions(+), 76 deletions(-) diff --git a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Device.h b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Device.h index 4403a579cc..ee103bacf5 100644 --- a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Device.h +++ b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Device.h @@ -59,13 +59,13 @@ class Device final : public nn::IDevice { nn::GeneralResult prepareModel( const nn::Model& model, nn::ExecutionPreference preference, nn::Priority priority, - nn::OptionalTimePoint deadline, const std::vector& modelCache, - const std::vector& dataCache, + nn::OptionalTimePoint deadline, const std::vector& modelCache, + const std::vector& dataCache, const nn::CacheToken& token) const override; nn::GeneralResult prepareModelFromCache( - nn::OptionalTimePoint deadline, const std::vector& modelCache, - const std::vector& dataCache, + nn::OptionalTimePoint deadline, const std::vector& modelCache, + const std::vector& dataCache, const nn::CacheToken& token) const override; nn::GeneralResult allocate( diff --git a/neuralnetworks/1.0/utils/src/Conversions.cpp b/neuralnetworks/1.0/utils/src/Conversions.cpp index f301065cf9..6cf907380e 100644 --- a/neuralnetworks/1.0/utils/src/Conversions.cpp +++ b/neuralnetworks/1.0/utils/src/Conversions.cpp @@ -290,10 +290,8 @@ nn::GeneralResult> convert(const nn::Model::OperandValues& ope } nn::GeneralResult convert(const nn::Memory& memory) { - const auto hidlMemory = hidl_memory(memory.name, memory.handle->handle(), memory.size); - // Copy memory to force the native_handle_t to be copied. - auto copiedMemory = hidlMemory; - return copiedMemory; + return hidl_memory(memory.name, NN_TRY(hal::utils::hidlHandleFromSharedHandle(memory.handle)), + memory.size); } nn::GeneralResult convert(const nn::Model& model) { diff --git a/neuralnetworks/1.0/utils/src/Device.cpp b/neuralnetworks/1.0/utils/src/Device.cpp index 8292f170c2..671416b9eb 100644 --- a/neuralnetworks/1.0/utils/src/Device.cpp +++ b/neuralnetworks/1.0/utils/src/Device.cpp @@ -157,8 +157,8 @@ nn::GeneralResult> Device::getSupportedOperations(const nn::Mo nn::GeneralResult Device::prepareModel( const nn::Model& model, nn::ExecutionPreference /*preference*/, nn::Priority /*priority*/, - nn::OptionalTimePoint /*deadline*/, const std::vector& /*modelCache*/, - const std::vector& /*dataCache*/, const nn::CacheToken& /*token*/) const { + nn::OptionalTimePoint /*deadline*/, const std::vector& /*modelCache*/, + const std::vector& /*dataCache*/, const nn::CacheToken& /*token*/) const { // Ensure that model is ready for IPC. std::optional maybeModelInShared; const nn::Model& modelInShared = @@ -181,8 +181,8 @@ nn::GeneralResult Device::prepareModel( } nn::GeneralResult Device::prepareModelFromCache( - nn::OptionalTimePoint /*deadline*/, const std::vector& /*modelCache*/, - const std::vector& /*dataCache*/, const nn::CacheToken& /*token*/) const { + nn::OptionalTimePoint /*deadline*/, const std::vector& /*modelCache*/, + const std::vector& /*dataCache*/, const nn::CacheToken& /*token*/) const { return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "IDevice::prepareModelFromCache not supported on 1.0 HAL service"; } diff --git a/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Device.h b/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Device.h index f55ac6cb6d..c1e95fe1a5 100644 --- a/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Device.h +++ b/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Device.h @@ -59,13 +59,13 @@ class Device final : public nn::IDevice { nn::GeneralResult prepareModel( const nn::Model& model, nn::ExecutionPreference preference, nn::Priority priority, - nn::OptionalTimePoint deadline, const std::vector& modelCache, - const std::vector& dataCache, + nn::OptionalTimePoint deadline, const std::vector& modelCache, + const std::vector& dataCache, const nn::CacheToken& token) const override; nn::GeneralResult prepareModelFromCache( - nn::OptionalTimePoint deadline, const std::vector& modelCache, - const std::vector& dataCache, + nn::OptionalTimePoint deadline, const std::vector& modelCache, + const std::vector& dataCache, const nn::CacheToken& token) const override; nn::GeneralResult allocate( diff --git a/neuralnetworks/1.1/utils/src/Device.cpp b/neuralnetworks/1.1/utils/src/Device.cpp index 03b0d6eb8e..a0378c94a0 100644 --- a/neuralnetworks/1.1/utils/src/Device.cpp +++ b/neuralnetworks/1.1/utils/src/Device.cpp @@ -159,8 +159,8 @@ nn::GeneralResult> Device::getSupportedOperations(const nn::Mo nn::GeneralResult Device::prepareModel( const nn::Model& model, nn::ExecutionPreference preference, nn::Priority /*priority*/, - nn::OptionalTimePoint /*deadline*/, const std::vector& /*modelCache*/, - const std::vector& /*dataCache*/, const nn::CacheToken& /*token*/) const { + nn::OptionalTimePoint /*deadline*/, const std::vector& /*modelCache*/, + const std::vector& /*dataCache*/, const nn::CacheToken& /*token*/) const { // Ensure that model is ready for IPC. std::optional maybeModelInShared; const nn::Model& modelInShared = @@ -184,8 +184,8 @@ nn::GeneralResult Device::prepareModel( } nn::GeneralResult Device::prepareModelFromCache( - nn::OptionalTimePoint /*deadline*/, const std::vector& /*modelCache*/, - const std::vector& /*dataCache*/, const nn::CacheToken& /*token*/) const { + nn::OptionalTimePoint /*deadline*/, const std::vector& /*modelCache*/, + const std::vector& /*dataCache*/, const nn::CacheToken& /*token*/) const { return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "IDevice::prepareModelFromCache not supported on 1.1 HAL service"; } diff --git a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Conversions.h b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Conversions.h index e6de011f9c..24911fea08 100644 --- a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Conversions.h +++ b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Conversions.h @@ -44,11 +44,11 @@ GeneralResult convert(const hal::V1_2::Timing& timing); GeneralResult convert(const hal::V1_2::Extension& extension); GeneralResult convert( const hal::V1_2::Extension::OperandTypeInformation& operandTypeInformation); -GeneralResult convert(const hardware::hidl_handle& handle); +GeneralResult convert(const hardware::hidl_handle& handle); GeneralResult> convert( const hardware::hidl_vec& extensions); -GeneralResult> convert( +GeneralResult> convert( const hardware::hidl_vec& handles); GeneralResult> convert( const hardware::hidl_vec& outputShapes); @@ -77,10 +77,10 @@ nn::GeneralResult convert(const nn::Timing& timing); nn::GeneralResult convert(const nn::Extension& extension); nn::GeneralResult convert( const nn::Extension::OperandTypeInformation& operandTypeInformation); -nn::GeneralResult convert(const nn::NativeHandle& handle); +nn::GeneralResult convert(const nn::SharedHandle& handle); nn::GeneralResult> convert(const std::vector& extensions); -nn::GeneralResult> convert(const std::vector& handles); +nn::GeneralResult> convert(const std::vector& handles); nn::GeneralResult> convert(const std::vector& outputShapes); } // namespace android::hardware::neuralnetworks::V1_2::utils diff --git a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Device.h b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Device.h index eb317b12cf..bbd534335b 100644 --- a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Device.h +++ b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Device.h @@ -68,13 +68,13 @@ class Device final : public nn::IDevice { nn::GeneralResult prepareModel( const nn::Model& model, nn::ExecutionPreference preference, nn::Priority priority, - nn::OptionalTimePoint deadline, const std::vector& modelCache, - const std::vector& dataCache, + nn::OptionalTimePoint deadline, const std::vector& modelCache, + const std::vector& dataCache, const nn::CacheToken& token) const override; nn::GeneralResult prepareModelFromCache( - nn::OptionalTimePoint deadline, const std::vector& modelCache, - const std::vector& dataCache, + nn::OptionalTimePoint deadline, const std::vector& modelCache, + const std::vector& dataCache, const nn::CacheToken& token) const override; nn::GeneralResult allocate( diff --git a/neuralnetworks/1.2/utils/src/Conversions.cpp b/neuralnetworks/1.2/utils/src/Conversions.cpp index 378719afc9..08c94dec33 100644 --- a/neuralnetworks/1.2/utils/src/Conversions.cpp +++ b/neuralnetworks/1.2/utils/src/Conversions.cpp @@ -257,16 +257,15 @@ GeneralResult convert( }; } -GeneralResult convert(const hidl_handle& handle) { - auto* cloned = native_handle_clone(handle.getNativeHandle()); - return ::android::NativeHandle::create(cloned, /*ownsHandle=*/true); +GeneralResult convert(const hidl_handle& hidlHandle) { + return hal::utils::sharedHandleFromNativeHandle(hidlHandle.getNativeHandle()); } GeneralResult> convert(const hidl_vec& extensions) { return convertVec(extensions); } -GeneralResult> convert(const hidl_vec& handles) { +GeneralResult> convert(const hidl_vec& handles) { return convertVec(handles); } @@ -487,18 +486,15 @@ nn::GeneralResult convert( }; } -nn::GeneralResult convert(const nn::NativeHandle& handle) { - const auto hidlHandle = hidl_handle(handle->handle()); - // Copy memory to force the native_handle_t to be copied. - auto copiedHandle = hidlHandle; - return copiedHandle; +nn::GeneralResult convert(const nn::SharedHandle& handle) { + return hal::utils::hidlHandleFromSharedHandle(handle); } nn::GeneralResult> convert(const std::vector& extensions) { return convertVec(extensions); } -nn::GeneralResult> convert(const std::vector& handles) { +nn::GeneralResult> convert(const std::vector& handles) { return convertVec(handles); } diff --git a/neuralnetworks/1.2/utils/src/Device.cpp b/neuralnetworks/1.2/utils/src/Device.cpp index ca236f17c6..517d61f85c 100644 --- a/neuralnetworks/1.2/utils/src/Device.cpp +++ b/neuralnetworks/1.2/utils/src/Device.cpp @@ -257,8 +257,8 @@ nn::GeneralResult> Device::getSupportedOperations(const nn::Mo nn::GeneralResult Device::prepareModel( const nn::Model& model, nn::ExecutionPreference preference, nn::Priority /*priority*/, - nn::OptionalTimePoint /*deadline*/, const std::vector& modelCache, - const std::vector& dataCache, const nn::CacheToken& token) const { + nn::OptionalTimePoint /*deadline*/, const std::vector& modelCache, + const std::vector& dataCache, const nn::CacheToken& token) const { // Ensure that model is ready for IPC. std::optional maybeModelInShared; const nn::Model& modelInShared = @@ -286,8 +286,8 @@ nn::GeneralResult Device::prepareModel( } nn::GeneralResult Device::prepareModelFromCache( - nn::OptionalTimePoint /*deadline*/, const std::vector& modelCache, - const std::vector& dataCache, const nn::CacheToken& token) const { + nn::OptionalTimePoint /*deadline*/, const std::vector& modelCache, + const std::vector& dataCache, const nn::CacheToken& token) const { const auto hidlModelCache = NN_TRY(convert(modelCache)); const auto hidlDataCache = NN_TRY(convert(dataCache)); const auto hidlToken = token; diff --git a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Device.h b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Device.h index 2f6c46a858..0f5234bd26 100644 --- a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Device.h +++ b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Device.h @@ -61,13 +61,13 @@ class Device final : public nn::IDevice { nn::GeneralResult prepareModel( const nn::Model& model, nn::ExecutionPreference preference, nn::Priority priority, - nn::OptionalTimePoint deadline, const std::vector& modelCache, - const std::vector& dataCache, + nn::OptionalTimePoint deadline, const std::vector& modelCache, + const std::vector& dataCache, const nn::CacheToken& token) const override; nn::GeneralResult prepareModelFromCache( - nn::OptionalTimePoint deadline, const std::vector& modelCache, - const std::vector& dataCache, + nn::OptionalTimePoint deadline, const std::vector& modelCache, + const std::vector& dataCache, const nn::CacheToken& token) const override; nn::GeneralResult allocate( diff --git a/neuralnetworks/1.3/utils/src/Device.cpp b/neuralnetworks/1.3/utils/src/Device.cpp index c215f39ecf..5e3d5c2ce2 100644 --- a/neuralnetworks/1.3/utils/src/Device.cpp +++ b/neuralnetworks/1.3/utils/src/Device.cpp @@ -179,8 +179,8 @@ nn::GeneralResult> Device::getSupportedOperations(const nn::Mo nn::GeneralResult Device::prepareModel( const nn::Model& model, nn::ExecutionPreference preference, nn::Priority priority, - nn::OptionalTimePoint deadline, const std::vector& modelCache, - const std::vector& dataCache, const nn::CacheToken& token) const { + nn::OptionalTimePoint deadline, const std::vector& modelCache, + const std::vector& dataCache, const nn::CacheToken& token) const { // Ensure that model is ready for IPC. std::optional maybeModelInShared; const nn::Model& modelInShared = @@ -211,8 +211,8 @@ nn::GeneralResult Device::prepareModel( } nn::GeneralResult Device::prepareModelFromCache( - nn::OptionalTimePoint deadline, const std::vector& modelCache, - const std::vector& dataCache, const nn::CacheToken& token) const { + nn::OptionalTimePoint deadline, const std::vector& modelCache, + const std::vector& dataCache, const nn::CacheToken& token) const { const auto hidlDeadline = NN_TRY(convert(deadline)); const auto hidlModelCache = NN_TRY(V1_2::utils::convert(modelCache)); const auto hidlDataCache = NN_TRY(V1_2::utils::convert(dataCache)); diff --git a/neuralnetworks/1.3/utils/src/PreparedModel.cpp b/neuralnetworks/1.3/utils/src/PreparedModel.cpp index df9b280119..2781053d07 100644 --- a/neuralnetworks/1.3/utils/src/PreparedModel.cpp +++ b/neuralnetworks/1.3/utils/src/PreparedModel.cpp @@ -53,15 +53,6 @@ nn::ExecutionResult, nn::Timing>> convert return hal::utils::makeExecutionFailure(convertExecutionResultsHelper(outputShapes, timing)); } -nn::GeneralResult> convertSyncFences( - const std::vector& syncFences) { - hidl_vec handles(syncFences.size()); - for (size_t i = 0; i < syncFences.size(); ++i) { - handles[i] = NN_TRY(V1_2::utils::convert(syncFences[i].getHandle())); - } - return handles; -} - nn::GeneralResult> convertFencedExecutionCallbackResults( const V1_2::Timing& timingLaunched, const V1_2::Timing& timingFenced) { return std::make_pair(NN_TRY(validatedConvertToCanonical(timingLaunched)), @@ -221,7 +212,7 @@ PreparedModel::executeFenced(const nn::Request& request, const std::vector +#include #include #include #include @@ -57,6 +59,13 @@ nn::GeneralResult unflushDataFromSharedToPointer( std::vector countNumberOfConsumers(size_t numberOfOperands, const std::vector& operations); +nn::GeneralResult createSharedMemoryFromHidlMemory(const hidl_memory& memory); + +nn::GeneralResult hidlHandleFromSharedHandle(const nn::SharedHandle& handle); +nn::GeneralResult sharedHandleFromNativeHandle(const native_handle_t* handle); +nn::GeneralResult> convertSyncFences( + const std::vector& fences); + } // namespace android::hardware::neuralnetworks::utils #endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_COMMON_UTILS_H diff --git a/neuralnetworks/utils/common/include/nnapi/hal/ResilientDevice.h b/neuralnetworks/utils/common/include/nnapi/hal/ResilientDevice.h index 4f1afb983a..4a84e4dacc 100644 --- a/neuralnetworks/utils/common/include/nnapi/hal/ResilientDevice.h +++ b/neuralnetworks/utils/common/include/nnapi/hal/ResilientDevice.h @@ -63,13 +63,13 @@ class ResilientDevice final : public nn::IDevice, nn::GeneralResult prepareModel( const nn::Model& model, nn::ExecutionPreference preference, nn::Priority priority, - nn::OptionalTimePoint deadline, const std::vector& modelCache, - const std::vector& dataCache, + nn::OptionalTimePoint deadline, const std::vector& modelCache, + const std::vector& dataCache, const nn::CacheToken& token) const override; nn::GeneralResult prepareModelFromCache( - nn::OptionalTimePoint deadline, const std::vector& modelCache, - const std::vector& dataCache, + nn::OptionalTimePoint deadline, const std::vector& modelCache, + const std::vector& dataCache, const nn::CacheToken& token) const override; nn::GeneralResult allocate( @@ -81,12 +81,12 @@ class ResilientDevice final : public nn::IDevice, nn::GeneralResult prepareModelInternal( bool blocking, const nn::Model& model, nn::ExecutionPreference preference, nn::Priority priority, nn::OptionalTimePoint deadline, - const std::vector& modelCache, - const std::vector& dataCache, const nn::CacheToken& token) const; + const std::vector& modelCache, + const std::vector& dataCache, const nn::CacheToken& token) const; nn::GeneralResult prepareModelFromCacheInternal( bool blocking, nn::OptionalTimePoint deadline, - const std::vector& modelCache, - const std::vector& dataCache, const nn::CacheToken& token) const; + const std::vector& modelCache, + const std::vector& dataCache, const nn::CacheToken& token) const; nn::GeneralResult allocateInternal( bool blocking, const nn::BufferDesc& desc, const std::vector& preparedModels, diff --git a/neuralnetworks/utils/common/src/CommonUtils.cpp b/neuralnetworks/utils/common/src/CommonUtils.cpp index 25659728c3..c04c8dfa8b 100644 --- a/neuralnetworks/utils/common/src/CommonUtils.cpp +++ b/neuralnetworks/utils/common/src/CommonUtils.cpp @@ -19,6 +19,7 @@ #include "HandleError.h" #include +#include #include #include #include @@ -247,4 +248,67 @@ std::vector countNumberOfConsumers(size_t numberOfOperands, return nn::countNumberOfConsumers(numberOfOperands, operations); } +nn::GeneralResult hidlHandleFromSharedHandle(const nn::SharedHandle& handle) { + if (handle == nullptr) { + return {}; + } + + std::vector fds; + fds.reserve(handle->fds.size()); + for (const auto& fd : handle->fds) { + int dupFd = dup(fd); + if (dupFd == -1) { + return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "Failed to dup the fd"; + } + fds.emplace_back(dupFd); + } + + native_handle_t* nativeHandle = native_handle_create(handle->fds.size(), handle->ints.size()); + if (nativeHandle == nullptr) { + return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "Failed to create native_handle"; + } + for (size_t i = 0; i < fds.size(); ++i) { + nativeHandle->data[i] = fds[i].release(); + } + std::copy(handle->ints.begin(), handle->ints.end(), &nativeHandle->data[nativeHandle->numFds]); + + hidl_handle hidlHandle; + hidlHandle.setTo(nativeHandle, /*shouldOwn=*/true); + return hidlHandle; +} + +nn::GeneralResult sharedHandleFromNativeHandle(const native_handle_t* handle) { + if (handle == nullptr) { + return nullptr; + } + + std::vector fds; + fds.reserve(handle->numFds); + for (int i = 0; i < handle->numFds; ++i) { + int dupFd = dup(handle->data[i]); + if (dupFd == -1) { + return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "Failed to dup the fd"; + } + fds.emplace_back(dupFd); + } + + std::vector ints(&handle->data[handle->numFds], + &handle->data[handle->numFds + handle->numInts]); + + return std::make_shared(nn::Handle{ + .fds = std::move(fds), + .ints = std::move(ints), + }); +} + +nn::GeneralResult> convertSyncFences( + const std::vector& syncFences) { + hidl_vec handles(syncFences.size()); + for (size_t i = 0; i < syncFences.size(); ++i) { + handles[i] = + NN_TRY(hal::utils::hidlHandleFromSharedHandle(syncFences[i].getSharedHandle())); + } + return handles; +} + } // namespace android::hardware::neuralnetworks::utils diff --git a/neuralnetworks/utils/common/src/ResilientDevice.cpp b/neuralnetworks/utils/common/src/ResilientDevice.cpp index 95662d96bd..26025a5026 100644 --- a/neuralnetworks/utils/common/src/ResilientDevice.cpp +++ b/neuralnetworks/utils/common/src/ResilientDevice.cpp @@ -161,8 +161,8 @@ nn::GeneralResult> ResilientDevice::getSupportedOperations( nn::GeneralResult ResilientDevice::prepareModel( const nn::Model& model, nn::ExecutionPreference preference, nn::Priority priority, - nn::OptionalTimePoint deadline, const std::vector& modelCache, - const std::vector& dataCache, const nn::CacheToken& token) const { + nn::OptionalTimePoint deadline, const std::vector& modelCache, + const std::vector& dataCache, const nn::CacheToken& token) const { auto self = shared_from_this(); ResilientPreparedModel::Factory makePreparedModel = [device = std::move(self), model, preference, priority, deadline, modelCache, dataCache, @@ -174,8 +174,8 @@ nn::GeneralResult ResilientDevice::prepareModel( } nn::GeneralResult ResilientDevice::prepareModelFromCache( - nn::OptionalTimePoint deadline, const std::vector& modelCache, - const std::vector& dataCache, const nn::CacheToken& token) const { + nn::OptionalTimePoint deadline, const std::vector& modelCache, + const std::vector& dataCache, const nn::CacheToken& token) const { auto self = shared_from_this(); ResilientPreparedModel::Factory makePreparedModel = [device = std::move(self), deadline, modelCache, dataCache, @@ -202,8 +202,8 @@ nn::GeneralResult ResilientDevice::allocate( nn::GeneralResult ResilientDevice::prepareModelInternal( bool blocking, const nn::Model& model, nn::ExecutionPreference preference, nn::Priority priority, nn::OptionalTimePoint deadline, - const std::vector& modelCache, - const std::vector& dataCache, const nn::CacheToken& token) const { + const std::vector& modelCache, + const std::vector& dataCache, const nn::CacheToken& token) const { const auto fn = [&model, preference, priority, deadline, &modelCache, &dataCache, token](const nn::IDevice& device) { return device.prepareModel(model, preference, priority, deadline, modelCache, dataCache, @@ -214,8 +214,8 @@ nn::GeneralResult ResilientDevice::prepareModelInternal nn::GeneralResult ResilientDevice::prepareModelFromCacheInternal( bool blocking, nn::OptionalTimePoint deadline, - const std::vector& modelCache, - const std::vector& dataCache, const nn::CacheToken& token) const { + const std::vector& modelCache, + const std::vector& dataCache, const nn::CacheToken& token) const { const auto fn = [deadline, &modelCache, &dataCache, token](const nn::IDevice& device) { return device.prepareModelFromCache(deadline, modelCache, dataCache, token); }; diff --git a/neuralnetworks/utils/service/Android.bp b/neuralnetworks/utils/service/Android.bp index 87d27c7ac3..402598c7aa 100644 --- a/neuralnetworks/utils/service/Android.bp +++ b/neuralnetworks/utils/service/Android.bp @@ -26,6 +26,7 @@ cc_library_static { "neuralnetworks_utils_hal_1_1", "neuralnetworks_utils_hal_1_2", "neuralnetworks_utils_hal_1_3", + "neuralnetworks_utils_hal_common", ], shared_libs: [ "android.hardware.neuralnetworks@1.0", -- GitLab From 6f906c15ab56bc41955a3666614f58ed4ebaaa9f Mon Sep 17 00:00:00 2001 From: Shuzhen Wang Date: Fri, 13 Nov 2020 17:58:40 -0800 Subject: [PATCH 283/790] VTS: Verify no duplicate entries between partial results Partial results are appended together. If there are duplicate entries between partial results, there will be more than more entries for a tag in the final result. This can cause undefined behavior, especially when they have different values. Test: Run Camera VTS test on Pixel devices Bug: 170575182 Change-Id: I931660cef16a90ee0c247e3c4513a88adb7211ab --- .../VtsHalCameraProviderV2_4TargetTest.cpp | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp index aa5c48fbcd..a18e45792e 100644 --- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp +++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp @@ -1260,9 +1260,27 @@ bool CameraHidlTest::DeviceCb::processCaptureResultLocked(const CaptureResult& r ADD_FAILURE(); return notify; } - request->collectedResult.append( - reinterpret_cast( - resultMetadata.data())); + + // Verify no duplicate tags between partial results + const camera_metadata_t* partialMetadata = + reinterpret_cast(resultMetadata.data()); + const camera_metadata_t* collectedMetadata = request->collectedResult.getAndLock(); + camera_metadata_ro_entry_t searchEntry, foundEntry; + for (size_t i = 0; i < get_camera_metadata_size(partialMetadata); i++) { + if (0 != get_camera_metadata_ro_entry(partialMetadata, i, &searchEntry)) { + ADD_FAILURE(); + request->collectedResult.unlock(collectedMetadata); + return notify; + } + if (-ENOENT != + find_camera_metadata_ro_entry(collectedMetadata, searchEntry.tag, &foundEntry)) { + ADD_FAILURE(); + request->collectedResult.unlock(collectedMetadata); + return notify; + } + } + request->collectedResult.unlock(collectedMetadata); + request->collectedResult.append(partialMetadata); isPartialResult = (results.partialResult < request->numPartialResults); -- GitLab From 4d0df26150b5af1f0486cff76f7819f838d301a5 Mon Sep 17 00:00:00 2001 From: Kevin Chyn Date: Mon, 16 Nov 2020 12:39:44 -0800 Subject: [PATCH 284/790] Remove HAT from invalidateAuthenticatorId and correct documentation 1) Removes HAT param from fingerprint AIDL 2) Update documentation for fingerprint and face AIDL Fixes: 173432893 Test: m android.hardware.biometrics.face-update-api Test: m android.hardware.biometrics.fingerprint-service.example Change-Id: I9c5e219c6f7a59609b6ff9d692f5a931f4bcea24 --- .../hardware/biometrics/face/ISession.aidl | 13 +++---------- .../biometrics/fingerprint/ISession.aidl | 2 +- .../biometrics/fingerprint/ISession.aidl | 16 ++++------------ biometrics/fingerprint/aidl/default/Session.cpp | 3 +-- biometrics/fingerprint/aidl/default/Session.h | 3 +-- 5 files changed, 10 insertions(+), 27 deletions(-) diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl index c7beae03ed..425b3525eb 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl @@ -292,16 +292,9 @@ interface ISession { * * When invoked by the framework, the implementation must perform the following sequence of * events: - * 1) Verify the authenticity and integrity of the provided HAT. If this check fails, the HAL - * must invoke ISessionCallback#onError with Error::UNABLE_TO_PROCESS and return to - * SessionState::IDLING if no subsequent work is in the queue. - * 2) Verify that the timestamp provided within the HAT is relatively recent (e.g. on the - * order of minutes, not hours). If this check fails, the HAL must invoke - * ISessionCallback#onError with Error::UNABLE_TO_PROCESS and return to - * SessionState::IDLING if no subsequent work is in the queue. - * 3) Update the authenticatorId with a new entropy-encoded random number - * 4) Persist the new authenticatorId to non-ephemeral storage - * 5) Notify the framework that the above is completed, via + * 1) Update the authenticatorId with a new entropy-encoded random number + * 2) Persist the new authenticatorId to non-ephemeral storage + * 3) Notify the framework that the above is completed, via * ISessionCallback#onAuthenticatorInvalidated * * A practical use case of invalidation would be when the user adds a new enrollment to a sensor 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 00a08ba886..4df79817bf 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 @@ -26,7 +26,7 @@ interface ISession { void enumerateEnrollments(in int cookie); void removeEnrollments(in int cookie, in int[] enrollmentIds); void getAuthenticatorId(in int cookie); - void invalidateAuthenticatorId(in int cookie, in android.hardware.keymaster.HardwareAuthToken hat); + void invalidateAuthenticatorId(in int cookie); void resetLockout(in int cookie, in android.hardware.keymaster.HardwareAuthToken hat); void onPointerDown(in int pointerId, in int x, in int y, in float minor, in float major); void onPointerUp(in int pointerId); diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl index da767bec48..09bd04d4ef 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl @@ -301,16 +301,9 @@ interface ISession { * * When invoked by the framework, the implementation must perform the following sequence of * events: - * 1) Verify the authenticity and integrity of the provided HAT. If this check fails, the HAL - * must invoke ISessionCallback#onError with Error::UNABLE_TO_PROCESS and return to - * SessionState::IDLING if no subsequent work is in the queue. - * 2) Verify that the timestamp provided within the HAT is relatively recent (e.g. on the - * order of minutes, not hours). If this check fails, the HAL must invoke - * ISessionCallback#onError with Error::UNABLE_TO_PROCESS and return to - * SessionState::IDLING if no subsequent work is in the queue. - * 3) Update the authenticatorId with a new entropy-encoded random number - * 4) Persist the new authenticatorId to non-ephemeral storage - * 5) Notify the framework that the above is completed, via + * 1) Update the authenticatorId with a new entropy-encoded random number + * 2) Persist the new authenticatorId to non-ephemeral storage + * 3) Notify the framework that the above is completed, via * ISessionCallback#onAuthenticatorInvalidated * * A practical use case of invalidation would be when the user adds a new enrollment to a sensor @@ -321,9 +314,8 @@ interface ISession { * * @param cookie An identifier used to track subsystem operations related to this call path. The * client must guarantee that it is unique per ISession. - * @param hat HardwareAuthToken that must be validated before proceeding with this operation. */ - void invalidateAuthenticatorId(in int cookie, in HardwareAuthToken hat); + void invalidateAuthenticatorId(in int cookie); /** * resetLockout: diff --git a/biometrics/fingerprint/aidl/default/Session.cpp b/biometrics/fingerprint/aidl/default/Session.cpp index 96f1e561b0..bf08203707 100644 --- a/biometrics/fingerprint/aidl/default/Session.cpp +++ b/biometrics/fingerprint/aidl/default/Session.cpp @@ -79,8 +79,7 @@ ndk::ScopedAStatus Session::getAuthenticatorId(int32_t /*cookie*/) { return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::invalidateAuthenticatorId(int32_t /*cookie*/, - const keymaster::HardwareAuthToken& /*hat*/) { +ndk::ScopedAStatus Session::invalidateAuthenticatorId(int32_t /*cookie*/) { return ndk::ScopedAStatus::ok(); } diff --git a/biometrics/fingerprint/aidl/default/Session.h b/biometrics/fingerprint/aidl/default/Session.h index 05c570c8dc..ed3ae3fd7e 100644 --- a/biometrics/fingerprint/aidl/default/Session.h +++ b/biometrics/fingerprint/aidl/default/Session.h @@ -49,8 +49,7 @@ class Session : public BnSession { ndk::ScopedAStatus getAuthenticatorId(int32_t cookie) override; - ndk::ScopedAStatus invalidateAuthenticatorId(int32_t cookie, - const keymaster::HardwareAuthToken& hat) override; + ndk::ScopedAStatus invalidateAuthenticatorId(int32_t cookie) override; ndk::ScopedAStatus resetLockout(int32_t cookie, const keymaster::HardwareAuthToken& hat) override; -- GitLab From d1d3f70fd3271612228e5ad454157ff958c81b72 Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Mon, 16 Nov 2020 23:16:37 +0000 Subject: [PATCH 285/790] Revert "Add monitor for ip cid change" This CL will be re-revert once the corresponding JNI and framework CL are ready to commit This reverts commit b6064e59c7ba4dcc864eeb62f7e0d03fc815aa5f. Reason for revert: build breakage Change-Id: I9b1e2493f1bc93393b634d6b841a56c6d0171542 --- tv/tuner/1.1/IFilter.hal | 24 ++++---- tv/tuner/1.1/default/Filter.cpp | 56 ++++++------------- tv/tuner/1.1/default/Filter.h | 4 +- tv/tuner/1.1/types.hal | 44 +-------------- tv/tuner/1.1/vts/functional/FilterTests.cpp | 30 ++-------- tv/tuner/1.1/vts/functional/FilterTests.h | 5 +- .../VtsHalTvTunerV1_1TargetTest.cpp | 4 +- .../VtsHalTvTunerV1_1TestConfigurations.h | 6 +- 8 files changed, 39 insertions(+), 134 deletions(-) diff --git a/tv/tuner/1.1/IFilter.hal b/tv/tuner/1.1/IFilter.hal index 1e941143df..1c6c33fe2b 100644 --- a/tv/tuner/1.1/IFilter.hal +++ b/tv/tuner/1.1/IFilter.hal @@ -85,23 +85,19 @@ interface IFilter extends @1.0::IFilter { configureAvStreamType(AvStreamType avStreamType) generates (Result result); /** - * Configure the monitor event. + * Configure the filter to monitor specific Scrambling Status. * - * The event for Scrambling Status should be sent at the following two scenarios: + * Scrambling Status should be sent through the filer callback at the following two scenarios: * 1. When this method is called, the first detected scrambling status should be sent. - * 2. When the Scrambling status transits into different status, event should be sent. + * 2. When the filter transits into the monitored statuses configured through this method, + * event should be sent. * - * The event for IP CID change should be sent at the following two scenarios: - * 1. When this method is called, the first detected CID for the IP should be sent. - * 2. When the CID is changed to different value for the IP filter, event should be sent. - * - * @param monitorEventypes the events to monitor. Set corresponding bit of the event to monitor. - * Reset to stop monitoring. + * @param statuses Scrambling Statuses to monitor. Set corresponding bit to monitor. Reset to + * stop monitoring. * @return result Result status of the operation. - * SUCCESS if successful, - * INVALID_STATE if configure can't be applied, - * UNKNOWN_ERROR if failed for other reasons. + * SUCCESS if successful, + * INVALID_STATE if configure can't be applied, + * UNKNOWN_ERROR if failed for other reasons. */ - configureMonitorEvent(bitfield monitorEventTypes) - generates (Result result); + configureScramblingEvent(bitfield statuses) generates (Result result); }; diff --git a/tv/tuner/1.1/default/Filter.cpp b/tv/tuner/1.1/default/Filter.cpp index 4fa1746dbe..e766a8af72 100644 --- a/tv/tuner/1.1/default/Filter.cpp +++ b/tv/tuner/1.1/default/Filter.cpp @@ -250,49 +250,25 @@ Return Filter::configureAvStreamType(const V1_1::AvStreamType& avStreamT return Result::SUCCESS; } -Return Filter::configureMonitorEvent(uint32_t monitorEventTypes) { +Return Filter::configureScramblingEvent(uint32_t statuses) { ALOGV("%s", __FUNCTION__); - DemuxFilterEvent emptyFilterEvent; - V1_1::DemuxFilterMonitorEvent monitorEvent; - V1_1::DemuxFilterEventExt eventExt; - - uint32_t newScramblingStatus = - monitorEventTypes & V1_1::DemuxFilterMonitorEventType::SCRAMBLING_STATUS; - uint32_t newIpCid = monitorEventTypes & V1_1::DemuxFilterMonitorEventType::IP_CID_CHANGE; - - // if scrambling status monitoring flipped, record the new state and send msg on enabling - if (newScramblingStatus ^ mScramblingStatusMonitored) { - mScramblingStatusMonitored = newScramblingStatus; - if (mScramblingStatusMonitored) { - if (mCallback_1_1 != nullptr) { - // Assuming current status is always NOT_SCRAMBLED - monitorEvent.scramblingStatus(V1_1::ScramblingStatus::NOT_SCRAMBLED); - eventExt.events.resize(1); - eventExt.events[0].monitorEvent(monitorEvent); - mCallback_1_1->onFilterEvent_1_1(emptyFilterEvent, eventExt); - } else { - return Result::INVALID_STATE; - } - } - } - - // if ip cid monitoring flipped, record the new state and send msg on enabling - if (newIpCid ^ mIpCidMonitored) { - mIpCidMonitored = newIpCid; - if (mIpCidMonitored) { - if (mCallback_1_1 != nullptr) { - // Return random cid - monitorEvent.cid(1); - eventExt.events.resize(1); - eventExt.events[0].monitorEvent(monitorEvent); - mCallback_1_1->onFilterEvent_1_1(emptyFilterEvent, eventExt); - } else { - return Result::INVALID_STATE; - } - } + mStatuses = statuses; + if (mCallback_1_1 != nullptr) { + // Assuming current status is always NOT_SCRAMBLED + V1_1::DemuxFilterEventExt filterEventExt; + V1_1::DemuxFilterEventExt::Event event; + event.scramblingStatus(V1_1::ScramblingStatus::NOT_SCRAMBLED); + int size = filterEventExt.events.size(); + filterEventExt.events.resize(size + 1); + filterEventExt.events[size] = event; + DemuxFilterEvent emptyFilterEvent; + + mCallback_1_1->onFilterEvent_1_1(emptyFilterEvent, filterEventExt); + mFilterEventExt.events.resize(0); + } else { + return Result::INVALID_STATE; } - return Result::SUCCESS; } diff --git a/tv/tuner/1.1/default/Filter.h b/tv/tuner/1.1/default/Filter.h index 3a4246e095..1ebc1351a0 100644 --- a/tv/tuner/1.1/default/Filter.h +++ b/tv/tuner/1.1/default/Filter.h @@ -84,7 +84,7 @@ class Filter : public V1_1::IFilter { virtual Return configureAvStreamType(const V1_1::AvStreamType& avStreamType) override; - virtual Return configureMonitorEvent(uint32_t monitorEventTypes) override; + virtual Return configureScramblingEvent(uint32_t statuses) override; /** * To create a FilterMQ and its Event Flag. @@ -238,8 +238,6 @@ class Filter : public V1_1::IFilter { bool mConfigured = false; int mStartId = 0; - uint8_t mScramblingStatusMonitored = 0; - uint8_t mIpCidMonitored = 0; }; } // namespace implementation diff --git a/tv/tuner/1.1/types.hal b/tv/tuner/1.1/types.hal index 938cb6e493..09b87f2ac8 100644 --- a/tv/tuner/1.1/types.hal +++ b/tv/tuner/1.1/types.hal @@ -151,42 +151,22 @@ struct DemuxFilterMmtpRecordEventExt { struct DemuxFilterEventExt { safe_union Event { /** - * No extended filter Event. + * No extended record filter Event. This is used by the tsRecord or mmtpRecord filter event + * that does not contain the DemuxFilterTs/MmtpRecordEventExt information. */ Monostate noinit; - /** - * Extended TS Record event sent along with @1.0::DemuxFilterEvent::Event::tsRecord. - * DemuxFilterEventExt.events[i] is corresponding to @1.0::DemuxFilterEvent.events[i]. If - * @1.0::DemuxFilterEvent.events[i] does not have extended event, - * DemuxFilterEventExt.events[i] should use Monostate. - */ DemuxFilterTsRecordEventExt tsRecord; - /** - * Extended MMTP Record event sent along with @1.0::DemuxFilterEvent::Event::mmtpRecord. - * DemuxFilterEventExt.events[i] is corresponding to @1.0::DemuxFilterEvent.events[i]. If - * @1.0::DemuxFilterEvent.events[i] does not have extended event, - * DemuxFilterEventExt.events[i] should use Monostate. - */ DemuxFilterMmtpRecordEventExt mmtpRecord; - /** - * Monitor event to notify monitored status change. - * - * When sending monitorEvent, DemuxFilterEventExt.events should only contain one - * monitorEvent. MonitorEvent should be sent with an empty @1.0::DemuxFilterEvent. - */ - DemuxFilterMonitorEvent monitorEvent; + ScramblingStatus scramblingStatus; /** * An unique ID to mark the start point of receiving the valid filter events after * reconfiguring the filter. It must be sent at least once in the first event after the * filter is restarted. 0 is reserved for the newly opened filter's first start, which is * optional for HAL to send. - * - * When sending starId, DemuxFilterEventExt.events should only contain one startId event. - * StardId event should be sent with an empty @1.0::DemuxFilterEvent. */ uint32_t startId; }; @@ -216,24 +196,6 @@ enum ScramblingStatus : uint32_t { SCRAMBLED = 1 << 2, }; -@export -enum DemuxFilterMonitorEventType : uint32_t { - SCRAMBLING_STATUS = 1 << 0, - IP_CID_CHANGE = 1 << 1, -}; - -safe_union DemuxFilterMonitorEvent { - /** - * New scrambling status. - */ - ScramblingStatus scramblingStatus; - - /** - * New cid for the IP filter. - */ - uint32_t cid; -}; - typedef FrontendDvbcSpectralInversion FrontendSpectralInversion; /** diff --git a/tv/tuner/1.1/vts/functional/FilterTests.cpp b/tv/tuner/1.1/vts/functional/FilterTests.cpp index d8fad3d5d2..cdf3b6998b 100644 --- a/tv/tuner/1.1/vts/functional/FilterTests.cpp +++ b/tv/tuner/1.1/vts/functional/FilterTests.cpp @@ -40,18 +40,6 @@ void FilterCallback::testFilterScramblingEvent() { ALOGW("[vts] pass and stop"); } -void FilterCallback::testFilterIpCidEvent() { - android::Mutex::Autolock autoLock(mMsgLock); - while (mIpCidEvent < 1) { - if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) { - EXPECT_TRUE(false) << "ip cid change event does not output within timeout"; - return; - } - } - mIpCidEvent = 0; - ALOGW("[vts] pass and stop"); -} - void FilterCallback::testStartIdAfterReconfigure() { android::Mutex::Autolock autoLock(mMsgLock); while (!mStartIdReceived) { @@ -92,17 +80,8 @@ void FilterCallback::readFilterEventData() { eventExt.mmtpRecord().pts, eventExt.mmtpRecord().firstMbInSlice, eventExt.mmtpRecord().mpuSequenceNumber, eventExt.mmtpRecord().tsIndexMask); break; - case DemuxFilterEventExt::Event::hidl_discriminator::monitorEvent: - switch (eventExt.monitorEvent().getDiscriminator()) { - case DemuxFilterMonitorEvent::hidl_discriminator::scramblingStatus: - mScramblingStatusEvent++; - break; - case DemuxFilterMonitorEvent::hidl_discriminator::cid: - mIpCidEvent++; - break; - default: - break; - } + case DemuxFilterEventExt::Event::hidl_discriminator::scramblingStatus: + mScramblingStatusEvent++; break; case DemuxFilterEventExt::Event::hidl_discriminator::startId: ALOGD("[vts] Extended restart filter event, startId=%d", eventExt.startId()); @@ -293,16 +272,15 @@ AssertionResult FilterTests::closeFilter(uint64_t filterId) { return AssertionResult(status == Result::SUCCESS); } -AssertionResult FilterTests::configureMonitorEvent(uint64_t filterId, uint32_t monitorEventTypes) { +AssertionResult FilterTests::configureScramblingEvent(uint64_t filterId, uint32_t statuses) { EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first."; Result status; sp filter_v1_1 = android::hardware::tv::tuner::V1_1::IFilter::castFrom(mFilters[filterId]); if (filter_v1_1 != NULL) { - status = filter_v1_1->configureMonitorEvent(monitorEventTypes); + status = filter_v1_1->configureScramblingEvent(statuses); mFilterCallbacks[filterId]->testFilterScramblingEvent(); - mFilterCallbacks[filterId]->testFilterIpCidEvent(); } else { ALOGW("[vts] Can't cast IFilter into v1_1."); return failure(); diff --git a/tv/tuner/1.1/vts/functional/FilterTests.h b/tv/tuner/1.1/vts/functional/FilterTests.h index 6749265661..ae57659a38 100644 --- a/tv/tuner/1.1/vts/functional/FilterTests.h +++ b/tv/tuner/1.1/vts/functional/FilterTests.h @@ -56,7 +56,6 @@ using android::hardware::tv::tuner::V1_0::IFilter; using android::hardware::tv::tuner::V1_0::Result; using android::hardware::tv::tuner::V1_1::AvStreamType; using android::hardware::tv::tuner::V1_1::DemuxFilterEventExt; -using android::hardware::tv::tuner::V1_1::DemuxFilterMonitorEvent; using android::hardware::tv::tuner::V1_1::IFilterCallback; using android::hardware::tv::tuner::V1_1::ITuner; @@ -119,7 +118,6 @@ class FilterCallback : public IFilterCallback { void testFilterDataOutput(); void testFilterScramblingEvent(); - void testFilterIpCidEvent(); void testStartIdAfterReconfigure(); void readFilterEventData(); @@ -141,7 +139,6 @@ class FilterCallback : public IFilterCallback { int mPidFilterOutputCount = 0; int mScramblingStatusEvent = 0; - int mIpCidEvent = 0; bool mStartIdReceived = false; }; @@ -160,7 +157,7 @@ class FilterTests { AssertionResult configFilter(DemuxFilterSettings setting, uint64_t filterId); AssertionResult configAvFilterStreamType(AvStreamType type, uint64_t filterId); AssertionResult configIpFilterCid(uint32_t ipCid, uint64_t filterId); - AssertionResult configureMonitorEvent(uint64_t filterId, uint32_t monitorEventTypes); + AssertionResult configureScramblingEvent(uint64_t filterId, uint32_t statuses); AssertionResult getFilterMQDescriptor(uint64_t filterId); AssertionResult startFilter(uint64_t filterId); AssertionResult stopFilter(uint64_t filterId); diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp index e87276275a..dda8b60087 100644 --- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp @@ -46,8 +46,8 @@ void TunerFilterHidlTest::configSingleFilterInDemuxTest(FilterConfig filterConf, if (filterConf.type.mainType == DemuxFilterMainType::IP) { ASSERT_TRUE(mFilterTests.configIpFilterCid(filterConf.ipCid, filterId)); } - if (filterConf.monitorEventTypes > 0) { - ASSERT_TRUE(mFilterTests.configureMonitorEvent(filterId, filterConf.monitorEventTypes)); + if (filterConf.statuses > 0) { + ASSERT_TRUE(mFilterTests.configureScramblingEvent(filterId, filterConf.statuses)); } ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId)); ASSERT_TRUE(mFilterTests.startFilter(filterId)); diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h index beae223e4b..76bf765909 100644 --- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h @@ -96,7 +96,7 @@ struct FilterConfig { DemuxFilterSettings settings; AvStreamType streamType; uint32_t ipCid; - uint32_t monitorEventTypes; + uint32_t statuses; bool operator<(const FilterConfig& /*c*/) const { return false; } }; @@ -188,9 +188,7 @@ inline void initFilterConfig() { filterArray[TS_VIDEO0].bufferSize = FMQ_SIZE_16M; filterArray[TS_VIDEO0].settings.ts().tpid = 256; filterArray[TS_VIDEO0].settings.ts().filterSettings.av({.isPassthrough = false}); - filterArray[TS_VIDEO0].monitorEventTypes = - android::hardware::tv::tuner::V1_1::DemuxFilterMonitorEventType::SCRAMBLING_STATUS | - android::hardware::tv::tuner::V1_1::DemuxFilterMonitorEventType::IP_CID_CHANGE; + filterArray[TS_VIDEO0].statuses = 1; filterArray[TS_VIDEO1].type.mainType = DemuxFilterMainType::TS; filterArray[TS_VIDEO1].type.subType.tsFilterType(DemuxTsFilterType::VIDEO); filterArray[TS_VIDEO1].bufferSize = FMQ_SIZE_16M; -- GitLab From 39bd464d0cb20d080d88c43fc347ad6aea1481ae Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Mon, 16 Nov 2020 23:27:11 +0000 Subject: [PATCH 286/790] Revert "Revert "Add monitor for ip cid change"" This reverts commit d1d3f70fd3271612228e5ad454157ff958c81b72. Reason for revert: I5fcd0d4dff55453023a730caa36995f13f074a8f broke the build since the java framework and JNI side of the codes have not been merged yet. I9b1e2493f1bc93393b634d6b841a56c6d0171542 reverted I5fcd0d4dff55453023a730caa36995f13f074a8f to fix the breakage. This double revert would be committed with the jni code in the same topic. Change-Id: Ic5263ea9f18c097c3584356fa113a4f019f08692 --- tv/tuner/1.1/IFilter.hal | 24 ++++---- tv/tuner/1.1/default/Filter.cpp | 56 +++++++++++++------ tv/tuner/1.1/default/Filter.h | 4 +- tv/tuner/1.1/types.hal | 44 ++++++++++++++- tv/tuner/1.1/vts/functional/FilterTests.cpp | 30 ++++++++-- tv/tuner/1.1/vts/functional/FilterTests.h | 5 +- .../VtsHalTvTunerV1_1TargetTest.cpp | 4 +- .../VtsHalTvTunerV1_1TestConfigurations.h | 6 +- 8 files changed, 134 insertions(+), 39 deletions(-) diff --git a/tv/tuner/1.1/IFilter.hal b/tv/tuner/1.1/IFilter.hal index 1c6c33fe2b..1e941143df 100644 --- a/tv/tuner/1.1/IFilter.hal +++ b/tv/tuner/1.1/IFilter.hal @@ -85,19 +85,23 @@ interface IFilter extends @1.0::IFilter { configureAvStreamType(AvStreamType avStreamType) generates (Result result); /** - * Configure the filter to monitor specific Scrambling Status. + * Configure the monitor event. * - * Scrambling Status should be sent through the filer callback at the following two scenarios: + * The event for Scrambling Status should be sent at the following two scenarios: * 1. When this method is called, the first detected scrambling status should be sent. - * 2. When the filter transits into the monitored statuses configured through this method, - * event should be sent. + * 2. When the Scrambling status transits into different status, event should be sent. * - * @param statuses Scrambling Statuses to monitor. Set corresponding bit to monitor. Reset to - * stop monitoring. + * The event for IP CID change should be sent at the following two scenarios: + * 1. When this method is called, the first detected CID for the IP should be sent. + * 2. When the CID is changed to different value for the IP filter, event should be sent. + * + * @param monitorEventypes the events to monitor. Set corresponding bit of the event to monitor. + * Reset to stop monitoring. * @return result Result status of the operation. - * SUCCESS if successful, - * INVALID_STATE if configure can't be applied, - * UNKNOWN_ERROR if failed for other reasons. + * SUCCESS if successful, + * INVALID_STATE if configure can't be applied, + * UNKNOWN_ERROR if failed for other reasons. */ - configureScramblingEvent(bitfield statuses) generates (Result result); + configureMonitorEvent(bitfield monitorEventTypes) + generates (Result result); }; diff --git a/tv/tuner/1.1/default/Filter.cpp b/tv/tuner/1.1/default/Filter.cpp index e766a8af72..4fa1746dbe 100644 --- a/tv/tuner/1.1/default/Filter.cpp +++ b/tv/tuner/1.1/default/Filter.cpp @@ -250,25 +250,49 @@ Return Filter::configureAvStreamType(const V1_1::AvStreamType& avStreamT return Result::SUCCESS; } -Return Filter::configureScramblingEvent(uint32_t statuses) { +Return Filter::configureMonitorEvent(uint32_t monitorEventTypes) { ALOGV("%s", __FUNCTION__); - mStatuses = statuses; - if (mCallback_1_1 != nullptr) { - // Assuming current status is always NOT_SCRAMBLED - V1_1::DemuxFilterEventExt filterEventExt; - V1_1::DemuxFilterEventExt::Event event; - event.scramblingStatus(V1_1::ScramblingStatus::NOT_SCRAMBLED); - int size = filterEventExt.events.size(); - filterEventExt.events.resize(size + 1); - filterEventExt.events[size] = event; - DemuxFilterEvent emptyFilterEvent; - - mCallback_1_1->onFilterEvent_1_1(emptyFilterEvent, filterEventExt); - mFilterEventExt.events.resize(0); - } else { - return Result::INVALID_STATE; + DemuxFilterEvent emptyFilterEvent; + V1_1::DemuxFilterMonitorEvent monitorEvent; + V1_1::DemuxFilterEventExt eventExt; + + uint32_t newScramblingStatus = + monitorEventTypes & V1_1::DemuxFilterMonitorEventType::SCRAMBLING_STATUS; + uint32_t newIpCid = monitorEventTypes & V1_1::DemuxFilterMonitorEventType::IP_CID_CHANGE; + + // if scrambling status monitoring flipped, record the new state and send msg on enabling + if (newScramblingStatus ^ mScramblingStatusMonitored) { + mScramblingStatusMonitored = newScramblingStatus; + if (mScramblingStatusMonitored) { + if (mCallback_1_1 != nullptr) { + // Assuming current status is always NOT_SCRAMBLED + monitorEvent.scramblingStatus(V1_1::ScramblingStatus::NOT_SCRAMBLED); + eventExt.events.resize(1); + eventExt.events[0].monitorEvent(monitorEvent); + mCallback_1_1->onFilterEvent_1_1(emptyFilterEvent, eventExt); + } else { + return Result::INVALID_STATE; + } + } } + + // if ip cid monitoring flipped, record the new state and send msg on enabling + if (newIpCid ^ mIpCidMonitored) { + mIpCidMonitored = newIpCid; + if (mIpCidMonitored) { + if (mCallback_1_1 != nullptr) { + // Return random cid + monitorEvent.cid(1); + eventExt.events.resize(1); + eventExt.events[0].monitorEvent(monitorEvent); + mCallback_1_1->onFilterEvent_1_1(emptyFilterEvent, eventExt); + } else { + return Result::INVALID_STATE; + } + } + } + return Result::SUCCESS; } diff --git a/tv/tuner/1.1/default/Filter.h b/tv/tuner/1.1/default/Filter.h index 1ebc1351a0..3a4246e095 100644 --- a/tv/tuner/1.1/default/Filter.h +++ b/tv/tuner/1.1/default/Filter.h @@ -84,7 +84,7 @@ class Filter : public V1_1::IFilter { virtual Return configureAvStreamType(const V1_1::AvStreamType& avStreamType) override; - virtual Return configureScramblingEvent(uint32_t statuses) override; + virtual Return configureMonitorEvent(uint32_t monitorEventTypes) override; /** * To create a FilterMQ and its Event Flag. @@ -238,6 +238,8 @@ class Filter : public V1_1::IFilter { bool mConfigured = false; int mStartId = 0; + uint8_t mScramblingStatusMonitored = 0; + uint8_t mIpCidMonitored = 0; }; } // namespace implementation diff --git a/tv/tuner/1.1/types.hal b/tv/tuner/1.1/types.hal index 09b87f2ac8..938cb6e493 100644 --- a/tv/tuner/1.1/types.hal +++ b/tv/tuner/1.1/types.hal @@ -151,22 +151,42 @@ struct DemuxFilterMmtpRecordEventExt { struct DemuxFilterEventExt { safe_union Event { /** - * No extended record filter Event. This is used by the tsRecord or mmtpRecord filter event - * that does not contain the DemuxFilterTs/MmtpRecordEventExt information. + * No extended filter Event. */ Monostate noinit; + /** + * Extended TS Record event sent along with @1.0::DemuxFilterEvent::Event::tsRecord. + * DemuxFilterEventExt.events[i] is corresponding to @1.0::DemuxFilterEvent.events[i]. If + * @1.0::DemuxFilterEvent.events[i] does not have extended event, + * DemuxFilterEventExt.events[i] should use Monostate. + */ DemuxFilterTsRecordEventExt tsRecord; + /** + * Extended MMTP Record event sent along with @1.0::DemuxFilterEvent::Event::mmtpRecord. + * DemuxFilterEventExt.events[i] is corresponding to @1.0::DemuxFilterEvent.events[i]. If + * @1.0::DemuxFilterEvent.events[i] does not have extended event, + * DemuxFilterEventExt.events[i] should use Monostate. + */ DemuxFilterMmtpRecordEventExt mmtpRecord; - ScramblingStatus scramblingStatus; + /** + * Monitor event to notify monitored status change. + * + * When sending monitorEvent, DemuxFilterEventExt.events should only contain one + * monitorEvent. MonitorEvent should be sent with an empty @1.0::DemuxFilterEvent. + */ + DemuxFilterMonitorEvent monitorEvent; /** * An unique ID to mark the start point of receiving the valid filter events after * reconfiguring the filter. It must be sent at least once in the first event after the * filter is restarted. 0 is reserved for the newly opened filter's first start, which is * optional for HAL to send. + * + * When sending starId, DemuxFilterEventExt.events should only contain one startId event. + * StardId event should be sent with an empty @1.0::DemuxFilterEvent. */ uint32_t startId; }; @@ -196,6 +216,24 @@ enum ScramblingStatus : uint32_t { SCRAMBLED = 1 << 2, }; +@export +enum DemuxFilterMonitorEventType : uint32_t { + SCRAMBLING_STATUS = 1 << 0, + IP_CID_CHANGE = 1 << 1, +}; + +safe_union DemuxFilterMonitorEvent { + /** + * New scrambling status. + */ + ScramblingStatus scramblingStatus; + + /** + * New cid for the IP filter. + */ + uint32_t cid; +}; + typedef FrontendDvbcSpectralInversion FrontendSpectralInversion; /** diff --git a/tv/tuner/1.1/vts/functional/FilterTests.cpp b/tv/tuner/1.1/vts/functional/FilterTests.cpp index cdf3b6998b..d8fad3d5d2 100644 --- a/tv/tuner/1.1/vts/functional/FilterTests.cpp +++ b/tv/tuner/1.1/vts/functional/FilterTests.cpp @@ -40,6 +40,18 @@ void FilterCallback::testFilterScramblingEvent() { ALOGW("[vts] pass and stop"); } +void FilterCallback::testFilterIpCidEvent() { + android::Mutex::Autolock autoLock(mMsgLock); + while (mIpCidEvent < 1) { + if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) { + EXPECT_TRUE(false) << "ip cid change event does not output within timeout"; + return; + } + } + mIpCidEvent = 0; + ALOGW("[vts] pass and stop"); +} + void FilterCallback::testStartIdAfterReconfigure() { android::Mutex::Autolock autoLock(mMsgLock); while (!mStartIdReceived) { @@ -80,8 +92,17 @@ void FilterCallback::readFilterEventData() { eventExt.mmtpRecord().pts, eventExt.mmtpRecord().firstMbInSlice, eventExt.mmtpRecord().mpuSequenceNumber, eventExt.mmtpRecord().tsIndexMask); break; - case DemuxFilterEventExt::Event::hidl_discriminator::scramblingStatus: - mScramblingStatusEvent++; + case DemuxFilterEventExt::Event::hidl_discriminator::monitorEvent: + switch (eventExt.monitorEvent().getDiscriminator()) { + case DemuxFilterMonitorEvent::hidl_discriminator::scramblingStatus: + mScramblingStatusEvent++; + break; + case DemuxFilterMonitorEvent::hidl_discriminator::cid: + mIpCidEvent++; + break; + default: + break; + } break; case DemuxFilterEventExt::Event::hidl_discriminator::startId: ALOGD("[vts] Extended restart filter event, startId=%d", eventExt.startId()); @@ -272,15 +293,16 @@ AssertionResult FilterTests::closeFilter(uint64_t filterId) { return AssertionResult(status == Result::SUCCESS); } -AssertionResult FilterTests::configureScramblingEvent(uint64_t filterId, uint32_t statuses) { +AssertionResult FilterTests::configureMonitorEvent(uint64_t filterId, uint32_t monitorEventTypes) { EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first."; Result status; sp filter_v1_1 = android::hardware::tv::tuner::V1_1::IFilter::castFrom(mFilters[filterId]); if (filter_v1_1 != NULL) { - status = filter_v1_1->configureScramblingEvent(statuses); + status = filter_v1_1->configureMonitorEvent(monitorEventTypes); mFilterCallbacks[filterId]->testFilterScramblingEvent(); + mFilterCallbacks[filterId]->testFilterIpCidEvent(); } else { ALOGW("[vts] Can't cast IFilter into v1_1."); return failure(); diff --git a/tv/tuner/1.1/vts/functional/FilterTests.h b/tv/tuner/1.1/vts/functional/FilterTests.h index ae57659a38..6749265661 100644 --- a/tv/tuner/1.1/vts/functional/FilterTests.h +++ b/tv/tuner/1.1/vts/functional/FilterTests.h @@ -56,6 +56,7 @@ using android::hardware::tv::tuner::V1_0::IFilter; using android::hardware::tv::tuner::V1_0::Result; using android::hardware::tv::tuner::V1_1::AvStreamType; using android::hardware::tv::tuner::V1_1::DemuxFilterEventExt; +using android::hardware::tv::tuner::V1_1::DemuxFilterMonitorEvent; using android::hardware::tv::tuner::V1_1::IFilterCallback; using android::hardware::tv::tuner::V1_1::ITuner; @@ -118,6 +119,7 @@ class FilterCallback : public IFilterCallback { void testFilterDataOutput(); void testFilterScramblingEvent(); + void testFilterIpCidEvent(); void testStartIdAfterReconfigure(); void readFilterEventData(); @@ -139,6 +141,7 @@ class FilterCallback : public IFilterCallback { int mPidFilterOutputCount = 0; int mScramblingStatusEvent = 0; + int mIpCidEvent = 0; bool mStartIdReceived = false; }; @@ -157,7 +160,7 @@ class FilterTests { AssertionResult configFilter(DemuxFilterSettings setting, uint64_t filterId); AssertionResult configAvFilterStreamType(AvStreamType type, uint64_t filterId); AssertionResult configIpFilterCid(uint32_t ipCid, uint64_t filterId); - AssertionResult configureScramblingEvent(uint64_t filterId, uint32_t statuses); + AssertionResult configureMonitorEvent(uint64_t filterId, uint32_t monitorEventTypes); AssertionResult getFilterMQDescriptor(uint64_t filterId); AssertionResult startFilter(uint64_t filterId); AssertionResult stopFilter(uint64_t filterId); diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp index dda8b60087..e87276275a 100644 --- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp @@ -46,8 +46,8 @@ void TunerFilterHidlTest::configSingleFilterInDemuxTest(FilterConfig filterConf, if (filterConf.type.mainType == DemuxFilterMainType::IP) { ASSERT_TRUE(mFilterTests.configIpFilterCid(filterConf.ipCid, filterId)); } - if (filterConf.statuses > 0) { - ASSERT_TRUE(mFilterTests.configureScramblingEvent(filterId, filterConf.statuses)); + if (filterConf.monitorEventTypes > 0) { + ASSERT_TRUE(mFilterTests.configureMonitorEvent(filterId, filterConf.monitorEventTypes)); } ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId)); ASSERT_TRUE(mFilterTests.startFilter(filterId)); diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h index 76bf765909..beae223e4b 100644 --- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h @@ -96,7 +96,7 @@ struct FilterConfig { DemuxFilterSettings settings; AvStreamType streamType; uint32_t ipCid; - uint32_t statuses; + uint32_t monitorEventTypes; bool operator<(const FilterConfig& /*c*/) const { return false; } }; @@ -188,7 +188,9 @@ inline void initFilterConfig() { filterArray[TS_VIDEO0].bufferSize = FMQ_SIZE_16M; filterArray[TS_VIDEO0].settings.ts().tpid = 256; filterArray[TS_VIDEO0].settings.ts().filterSettings.av({.isPassthrough = false}); - filterArray[TS_VIDEO0].statuses = 1; + filterArray[TS_VIDEO0].monitorEventTypes = + android::hardware::tv::tuner::V1_1::DemuxFilterMonitorEventType::SCRAMBLING_STATUS | + android::hardware::tv::tuner::V1_1::DemuxFilterMonitorEventType::IP_CID_CHANGE; filterArray[TS_VIDEO1].type.mainType = DemuxFilterMainType::TS; filterArray[TS_VIDEO1].type.subType.tsFilterType(DemuxTsFilterType::VIDEO); filterArray[TS_VIDEO1].bufferSize = FMQ_SIZE_16M; -- GitLab From c92aa85a6efe9ac46fa239a621c6b7882ff38992 Mon Sep 17 00:00:00 2001 From: lesl Date: Mon, 16 Nov 2020 15:20:33 +0800 Subject: [PATCH 287/790] wiif: Add AP bridge operations support (AP+AP Part 2) AP+AP Part 2 includes: 1. Support bridge in libwifi_system_iface 2. WifiHal a. createApIface_1_5 (Support create bridge mode AP) b. removeApIface_1_5 (Support remove one of the instance in bridge) 3. Framework: Create bridge AP when multi-bands configured. Bug: 162686273 Test: Manual Test (SAP enable normally) Change-Id: I518417add566ce4780a7e2e83af14460e6e8a217 --- wifi/1.5/default/wifi_iface_util.cpp | 30 ++++++++++++++++++++++++++++ wifi/1.5/default/wifi_iface_util.h | 10 ++++++++++ 2 files changed, 40 insertions(+) diff --git a/wifi/1.5/default/wifi_iface_util.cpp b/wifi/1.5/default/wifi_iface_util.cpp index 07175e489f..2a0aef8906 100644 --- a/wifi/1.5/default/wifi_iface_util.cpp +++ b/wifi/1.5/default/wifi_iface_util.cpp @@ -127,6 +127,36 @@ bool WifiIfaceUtil::setUpState(const std::string& iface_name, bool request_up) { unsigned WifiIfaceUtil::ifNameToIndex(const std::string& iface_name) { return if_nametoindex(iface_name.c_str()); } + +bool WifiIfaceUtil::createBridge(const std::string& br_name) { + if (!iface_tool_.lock()->createBridge(br_name)) { + return false; + } + + if (!iface_tool_.lock()->SetUpState(br_name.c_str(), true)) { + LOG(ERROR) << "bridge SetUpState(true) failed."; + } + return true; +} + +bool WifiIfaceUtil::deleteBridge(const std::string& br_name) { + if (!iface_tool_.lock()->SetUpState(br_name.c_str(), false)) { + LOG(INFO) << "SetUpState(false) failed for bridge=" << br_name.c_str(); + } + + return iface_tool_.lock()->deleteBridge(br_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) { + return iface_tool_.lock()->removeIfaceFromBridge(br_name, if_name); +} + } // namespace iface_util } // namespace implementation } // namespace V1_5 diff --git a/wifi/1.5/default/wifi_iface_util.h b/wifi/1.5/default/wifi_iface_util.h index 7b812fa7d6..296d1821d0 100644 --- a/wifi/1.5/default/wifi_iface_util.h +++ b/wifi/1.5/default/wifi_iface_util.h @@ -59,6 +59,16 @@ class WifiIfaceUtil { virtual bool setUpState(const std::string& iface_name, bool request_up); virtual unsigned ifNameToIndex(const std::string& iface_name); + virtual bool createBridge(const std::string& br_name); + + virtual bool deleteBridge(const std::string& br_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); + private: std::array createRandomMacAddress(); -- GitLab From 0d13e044f1439c487f0ebf6eccdc5d6afc4ae330 Mon Sep 17 00:00:00 2001 From: Kevin Chyn Date: Tue, 17 Nov 2020 15:14:23 -0800 Subject: [PATCH 288/790] Remove sensorId, userId from onChallenge* These methods were moved into ISession, but forgot to remove the sensorId, userId parameters Bug: 173453845 Test: m android.hardware.biometrics.face-update-api Test: m android.hardware.biometrics.face-service.example Test: m VtsHalBiometricsFaceTargetTest Change-Id: I78efd095e0b86f8a8568c8d74d946fd8436f6e65 --- .../android/hardware/biometrics/face/ISessionCallback.aidl | 4 ++-- .../android/hardware/biometrics/face/ISessionCallback.aidl | 4 ++-- biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp | 6 ++---- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl index 477ba5a27f..caf65aea1c 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl @@ -19,8 +19,8 @@ package android.hardware.biometrics.face; @VintfStability interface ISessionCallback { void onStateChanged(in int cookie, in android.hardware.biometrics.face.SessionState state); - void onChallengeGenerated(in int sensorId, in int userId, in long challenge); - void onChallengeRevoked(in int sensorId, in int userId, in long challenge); + void onChallengeGenerated(in long challenge); + void onChallengeRevoked(in long challenge); void onAcquired(in android.hardware.biometrics.face.AcquiredInfo info, in int vendorCode); void onError(in android.hardware.biometrics.face.Error error, in int vendorCode); void onEnrollmentProgress(in int enrollmentId, int remaining); diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl index 2608d5fc7b..fd4a648843 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl @@ -31,12 +31,12 @@ interface ISessionCallback { /** * Notifies the framework when a challenge is successfully generated. */ - void onChallengeGenerated(in int sensorId, in int userId, in long challenge); + void onChallengeGenerated(in long challenge); /** * Notifies the framework when a challenge has been revoked. */ - void onChallengeRevoked(in int sensorId, in int userId, in long challenge); + void onChallengeRevoked(in long challenge); /** * This method must only be used to notify the framework during the following states: diff --git a/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp b/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp index c1ba66b004..5f1030620d 100644 --- a/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp +++ b/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp @@ -51,13 +51,11 @@ class SessionCallback : public BnSessionCallback { return ndk::ScopedAStatus::ok(); } - ndk::ScopedAStatus onChallengeGenerated(int32_t /*sensorId*/, int32_t /*userId*/, - int64_t /*challenge*/) override { + ndk::ScopedAStatus onChallengeGenerated(int64_t /*challenge*/) override { return ndk::ScopedAStatus::ok(); } - ndk::ScopedAStatus onChallengeRevoked(int32_t /*sensorId*/, int32_t /*userId*/, - int64_t /*challenge*/) override { + ndk::ScopedAStatus onChallengeRevoked(int64_t /*challenge*/) override { return ndk::ScopedAStatus::ok(); } -- GitLab From 3529f26b3b43cb3fda6d69e907b2cb11598bbcbb Mon Sep 17 00:00:00 2001 From: Daniel Bright Date: Thu, 12 Nov 2020 16:11:29 -0800 Subject: [PATCH 289/790] Introduce Radio Hal Device Capabilities * Asks the device what set of capabilities are supported on the device with respect to the Radio Hal * The capabilities struct is left empty and will be filled in once the first set of radio hal capabilities are nailed down later in Android S Test: Added cts, ran cts, and std tests Bug: 163085807 Change-Id: I867f26bc649005e89ebf7a0b74f6fbeb2f44ac93 --- .../compatibility_matrix.current.xml | 8 ++ radio/config/1.3/Android.bp | 21 +++ radio/config/1.3/IRadioConfig.hal | 42 ++++++ radio/config/1.3/IRadioConfigResponse.hal | 39 +++++ radio/config/1.3/types.hal | 22 +++ radio/config/1.3/vts/functional/Android.bp | 39 +++++ .../VtsHalRadioConfigV1_3TargetTest.cpp | 23 +++ .../functional/radio_config_hidl_hal_api.cpp | 30 ++++ .../functional/radio_config_hidl_hal_test.cpp | 62 ++++++++ .../functional/radio_config_hidl_hal_utils.h | 135 ++++++++++++++++++ .../functional/radio_config_indication.cpp | 25 ++++ .../vts/functional/radio_config_response.cpp | 70 +++++++++ 12 files changed, 516 insertions(+) create mode 100644 radio/config/1.3/Android.bp create mode 100644 radio/config/1.3/IRadioConfig.hal create mode 100644 radio/config/1.3/IRadioConfigResponse.hal create mode 100644 radio/config/1.3/types.hal create mode 100644 radio/config/1.3/vts/functional/Android.bp create mode 100644 radio/config/1.3/vts/functional/VtsHalRadioConfigV1_3TargetTest.cpp create mode 100644 radio/config/1.3/vts/functional/radio_config_hidl_hal_api.cpp create mode 100644 radio/config/1.3/vts/functional/radio_config_hidl_hal_test.cpp create mode 100644 radio/config/1.3/vts/functional/radio_config_hidl_hal_utils.h create mode 100644 radio/config/1.3/vts/functional/radio_config_indication.cpp create mode 100644 radio/config/1.3/vts/functional/radio_config_response.cpp diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index ff925d90f1..42b575db0a 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -421,6 +421,14 @@ default + + android.hardware.radio.config + 1.3 + + IRadioConfig + default + + android.hardware.renderscript 1.0 diff --git a/radio/config/1.3/Android.bp b/radio/config/1.3/Android.bp new file mode 100644 index 0000000000..ace0de96f9 --- /dev/null +++ b/radio/config/1.3/Android.bp @@ -0,0 +1,21 @@ +// This file is autogenerated by hidl-gen -Landroidbp. + +hidl_interface { + name: "android.hardware.radio.config@1.3", + root: "android.hardware", + srcs: [ + "types.hal", + "IRadioConfig.hal", + "IRadioConfigResponse.hal", + ], + interfaces: [ + "android.hardware.radio.config@1.0", + "android.hardware.radio.config@1.1", + "android.hardware.radio.config@1.2", + "android.hardware.radio@1.0", + "android.hardware.radio@1.6", + "android.hidl.base@1.0", + ], + gen_java: true, + system_ext_specific: true, +} diff --git a/radio/config/1.3/IRadioConfig.hal b/radio/config/1.3/IRadioConfig.hal new file mode 100644 index 0000000000..83bcf92726 --- /dev/null +++ b/radio/config/1.3/IRadioConfig.hal @@ -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 interface is used by telephony and telecom to talk to cellular radio for the purpose of + * radio configuration, and it is not associated with any specific modem or slot. + * All the functions have minimum one parameter: + * serial: which corresponds to serial no. of request. Serial numbers must only be memorized for the + * duration of a method call. If clients provide colliding serials (including passing the same + * serial to different methods), multiple responses (one for each method call) must still be served. + */ + +package android.hardware.radio.config@1.3; + +import @1.1::IRadioConfig; +import IRadioConfigResponse; + +interface IRadioConfig extends @1.1::IRadioConfig { + /** + * Gets the available Radio Hal capabilities on the current device. + * + * This is called once per device boot up. + * + * @param serial Serial number of request + * + * Response callback is + * IRadioConfigResponse.getHalDeviceCapabilitiesResponse() + */ + oneway getHalDeviceCapabilities(int32_t serial); +}; diff --git a/radio/config/1.3/IRadioConfigResponse.hal b/radio/config/1.3/IRadioConfigResponse.hal new file mode 100644 index 0000000000..863754f374 --- /dev/null +++ b/radio/config/1.3/IRadioConfigResponse.hal @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.radio.config@1.3; + +import android.hardware.radio@1.6::RadioResponseInfo; +import @1.2::IRadioConfigResponse; +import HalDeviceCapabilities; + +/** + * Interface declaring response functions to solicited radio config requests. + */ +interface IRadioConfigResponse extends @1.2::IRadioConfigResponse { + /** + * @param info Response info struct containing response type, serial no. and error + * @param capabilities Capabilities struct containing the capabilities of the + * device related to the Radio HAL + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + */ + oneway getHalDeviceCapabilitiesResponse(RadioResponseInfo info, + HalDeviceCapabilities capabilities); +}; diff --git a/radio/config/1.3/types.hal b/radio/config/1.3/types.hal new file mode 100644 index 0000000000..bedb70922e --- /dev/null +++ b/radio/config/1.3/types.hal @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.radio.config@1.3; + +/** + * Contains the device capabilities with respect to the Radio HAL. + */ +struct HalDeviceCapabilities {}; diff --git a/radio/config/1.3/vts/functional/Android.bp b/radio/config/1.3/vts/functional/Android.bp new file mode 100644 index 0000000000..abd081f9df --- /dev/null +++ b/radio/config/1.3/vts/functional/Android.bp @@ -0,0 +1,39 @@ +// +// 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. +// + +cc_test { + name: "VtsHalRadioConfigV1_3TargetTest", + defaults: ["VtsHalTargetTestDefaults"], + srcs: [ + "radio_config_hidl_hal_api.cpp", + "radio_config_hidl_hal_test.cpp", + "radio_config_response.cpp", + "radio_config_indication.cpp", + "VtsHalRadioConfigV1_3TargetTest.cpp", + ], + static_libs: [ + "RadioVtsTestUtilBase", + "android.hardware.radio.config@1.0", + "android.hardware.radio.config@1.1", + "android.hardware.radio.config@1.2", + "android.hardware.radio.config@1.3", + ], + header_libs: ["radio.util.header@1.0"], + test_suites: [ + "general-tests", + "vts", + ], +} diff --git a/radio/config/1.3/vts/functional/VtsHalRadioConfigV1_3TargetTest.cpp b/radio/config/1.3/vts/functional/VtsHalRadioConfigV1_3TargetTest.cpp new file mode 100644 index 0000000000..5772d08c11 --- /dev/null +++ b/radio/config/1.3/vts/functional/VtsHalRadioConfigV1_3TargetTest.cpp @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(RadioConfigHidlTest); +INSTANTIATE_TEST_SUITE_P( + PerInstance, RadioConfigHidlTest, + testing::ValuesIn(android::hardware::getAllHalInstanceNames(IRadioConfig::descriptor)), + android::hardware::PrintInstanceNameToString); diff --git a/radio/config/1.3/vts/functional/radio_config_hidl_hal_api.cpp b/radio/config/1.3/vts/functional/radio_config_hidl_hal_api.cpp new file mode 100644 index 0000000000..8df02ddacc --- /dev/null +++ b/radio/config/1.3/vts/functional/radio_config_hidl_hal_api.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk()) + +/* + * Test IRadioConfig.getHalDeviceCapabilities() + */ +TEST_P(RadioConfigHidlTest, getHalDeviceCapabilities) { + const int serial = GetRandomSerialNumber(); + Return res = radioConfig->getHalDeviceCapabilities(serial); + ASSERT_OK(res); + ALOGI("getHalDeviceCapabilities, rspInfo.error = %s\n", + toString(radioConfigRsp->rspInfo.error).c_str()); +} diff --git a/radio/config/1.3/vts/functional/radio_config_hidl_hal_test.cpp b/radio/config/1.3/vts/functional/radio_config_hidl_hal_test.cpp new file mode 100644 index 0000000000..de8365aee8 --- /dev/null +++ b/radio/config/1.3/vts/functional/radio_config_hidl_hal_test.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +void RadioConfigHidlTest::SetUp() { + radioConfig = IRadioConfig::getService(GetParam()); + if (radioConfig == NULL) { + sleep(60); + radioConfig = IRadioConfig::getService(GetParam()); + } + ASSERT_NE(nullptr, radioConfig.get()); + + radioConfigRsp = new (std::nothrow) RadioConfigResponse(*this); + ASSERT_NE(nullptr, radioConfigRsp.get()); + + count_ = 0; + + radioConfig->setResponseFunctions(radioConfigRsp, nullptr); +} + +/* + * Notify that the response message is received. + */ +void RadioConfigHidlTest::notify(int receivedSerial) { + std::unique_lock lock(mtx_); + if (serial == receivedSerial) { + count_++; + cv_.notify_one(); + } +} + +/* + * Wait till the response message is notified or till TIMEOUT_PERIOD. + */ +std::cv_status RadioConfigHidlTest::wait() { + std::unique_lock lock(mtx_); + + std::cv_status status = std::cv_status::no_timeout; + auto now = std::chrono::system_clock::now(); + while (count_ == 0) { + status = cv_.wait_until(lock, now + std::chrono::seconds(TIMEOUT_PERIOD)); + if (status == std::cv_status::timeout) { + return status; + } + } + count_--; + return status; +} diff --git a/radio/config/1.3/vts/functional/radio_config_hidl_hal_utils.h b/radio/config/1.3/vts/functional/radio_config_hidl_hal_utils.h new file mode 100644 index 0000000000..439eb705b6 --- /dev/null +++ b/radio/config/1.3/vts/functional/radio_config_hidl_hal_utils.h @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "vts_test_util.h" + +using namespace ::android::hardware::radio::config::V1_2; + +using ::android::sp; +using ::android::hardware::hidl_string; +using ::android::hardware::hidl_vec; +using ::android::hardware::Return; +using ::android::hardware::Void; +using ::android::hardware::radio::config::V1_1::ModemsConfig; +using ::android::hardware::radio::config::V1_1::PhoneCapability; +using ::android::hardware::radio::config::V1_2::SimSlotStatus; +using ::android::hardware::radio::config::V1_3::HalDeviceCapabilities; +using ::android::hardware::radio::config::V1_3::IRadioConfig; +using ::android::hardware::radio::V1_0::RadioResponseInfo; + +#define TIMEOUT_PERIOD 75 +#define RADIO_SERVICE_NAME "slot1" + +class RadioConfigHidlTest; + +/* Callback class for radio config response */ +class RadioConfigResponse : public IRadioConfigResponse { + protected: + RadioConfigHidlTest& parent; + + public: + RadioResponseInfo rspInfo; + PhoneCapability phoneCap; + + RadioConfigResponse(RadioConfigHidlTest& parent); + virtual ~RadioConfigResponse() = default; + + Return getSimSlotsStatusResponse( + const RadioResponseInfo& info, + const ::android::hardware::hidl_vec< + ::android::hardware::radio::config::V1_0::SimSlotStatus>& slotStatus); + + Return getSimSlotsStatusResponse_1_2( + const RadioResponseInfo& info, + const ::android::hardware::hidl_vec& slotStatus); + + Return setSimSlotsMappingResponse(const RadioResponseInfo& info); + + Return getPhoneCapabilityResponse(const RadioResponseInfo& info, + const PhoneCapability& phoneCapability); + + Return setPreferredDataModemResponse(const RadioResponseInfo& info); + + Return getModemsConfigResponse(const RadioResponseInfo& info, + const ModemsConfig& mConfig); + + Return setModemsConfigResponse(const RadioResponseInfo& info); + + Return getHalDeviceCapabilitiesResponse( + const ::android::hardware::radio::V1_6::RadioResponseInfo& info, + const HalDeviceCapabilities& halDeviceCapabilities); +}; + +/* Callback class for radio config indication */ +class RadioConfigIndication : public IRadioConfigIndication { + protected: + RadioConfigHidlTest& parent; + + public: + RadioConfigIndication(RadioConfigHidlTest& parent); + virtual ~RadioConfigIndication() = default; + + Return simSlotsStatusChanged_1_2( + ::android::hardware::radio::V1_0::RadioIndicationType type, + const ::android::hardware::hidl_vec& slotStatus); +}; + +// The main test class for Radio config HIDL. +class RadioConfigHidlTest : public ::testing::TestWithParam { + protected: + std::mutex mtx_; + std::condition_variable cv_; + int count_; + + public: + virtual void SetUp() override; + + /* Used as a mechanism to inform the test about data/event callback */ + void notify(int receivedSerial); + + /* Test code calls this function to wait for response */ + std::cv_status wait(); + + void updateSimCardStatus(); + + /* Serial number for radio request */ + int serial; + + /* radio config service handle */ + sp radioConfig; + + /* radio config response handle */ + sp radioConfigRsp; +}; diff --git a/radio/config/1.3/vts/functional/radio_config_indication.cpp b/radio/config/1.3/vts/functional/radio_config_indication.cpp new file mode 100644 index 0000000000..6fa443c276 --- /dev/null +++ b/radio/config/1.3/vts/functional/radio_config_indication.cpp @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +RadioConfigIndication::RadioConfigIndication(RadioConfigHidlTest& parent) : parent(parent) {} + +Return RadioConfigIndication::simSlotsStatusChanged_1_2( + ::android::hardware::radio::V1_0::RadioIndicationType /*type*/, + const ::android::hardware::hidl_vec& /*slotStatus*/) { + return Void(); +} diff --git a/radio/config/1.3/vts/functional/radio_config_response.cpp b/radio/config/1.3/vts/functional/radio_config_response.cpp new file mode 100644 index 0000000000..2a8b28ba7c --- /dev/null +++ b/radio/config/1.3/vts/functional/radio_config_response.cpp @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +// SimSlotStatus slotStatus; + +RadioConfigResponse::RadioConfigResponse(RadioConfigHidlTest& parent) : parent(parent) {} + +Return RadioConfigResponse::getSimSlotsStatusResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /* info */, + const ::android::hardware::hidl_vec< + ::android::hardware::radio::config::V1_0::SimSlotStatus>& /* slotStatus */) { + return Void(); +} + +Return RadioConfigResponse::getSimSlotsStatusResponse_1_2( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /* info */, + const ::android::hardware::hidl_vec& /* slotStatus */) { + return Void(); +} + +Return RadioConfigResponse::setSimSlotsMappingResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /* info */) { + return Void(); +} + +Return RadioConfigResponse::getPhoneCapabilityResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, + const PhoneCapability& phoneCapability) { + rspInfo = info; + phoneCap = phoneCapability; + parent.notify(info.serial); + return Void(); +} + +Return RadioConfigResponse::setPreferredDataModemResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /* info */) { + return Void(); +} + +Return RadioConfigResponse::getModemsConfigResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /* info */, + const ModemsConfig& /* mConfig */) { + return Void(); +} + +Return RadioConfigResponse::setModemsConfigResponse( + const ::android::hardware::radio::V1_0::RadioResponseInfo& /* info */) { + return Void(); +} + +Return RadioConfigResponse::getHalDeviceCapabilitiesResponse( + const ::android::hardware::radio::V1_6::RadioResponseInfo& /* info */, + const ::android::hardware::radio::config::V1_3::HalDeviceCapabilities& /* capabilities */) { + return Void(); +} \ No newline at end of file -- GitLab From cfb5499a45df3ce206e7c652822acc8e32ec45cb Mon Sep 17 00:00:00 2001 From: Kevin Chyn Date: Tue, 17 Nov 2020 13:06:23 -0800 Subject: [PATCH 290/790] Update default face implementation Note that we're configuring this default HAL as "STRONG" so that the framework can eventually test multi-sensor authenticatorId invalidation Bug: 173453845 Test: atest CtsBiometricsTestCases Change-Id: Idd7b74f0a22c5078dc5c2b0b99f62fdc4b51e25d --- biometrics/face/aidl/default/Face.cpp | 2 +- biometrics/face/aidl/default/Session.cpp | 44 ++++++++++++++++++++++-- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/biometrics/face/aidl/default/Face.cpp b/biometrics/face/aidl/default/Face.cpp index 929c7e7703..d3883d64c9 100644 --- a/biometrics/face/aidl/default/Face.cpp +++ b/biometrics/face/aidl/default/Face.cpp @@ -20,7 +20,7 @@ namespace aidl::android::hardware::biometrics::face { const int kSensorId = 0; -const common::SensorStrength kSensorStrength = common::SensorStrength::WEAK; +const common::SensorStrength kSensorStrength = common::SensorStrength::STRONG; const int kMaxEnrollmentsPerUser = 5; const FaceSensorType kSensorType = FaceSensorType::RGB; const bool kHalControlsPreview = true; diff --git a/biometrics/face/aidl/default/Session.cpp b/biometrics/face/aidl/default/Session.cpp index 2b1d4a7637..c5d7d23ecb 100644 --- a/biometrics/face/aidl/default/Session.cpp +++ b/biometrics/face/aidl/default/Session.cpp @@ -21,17 +21,35 @@ namespace aidl::android::hardware::biometrics::face { class CancellationSignal : public common::BnCancellationSignal { + private: + std::shared_ptr cb_; public: - ndk::ScopedAStatus cancel() override { return ndk::ScopedAStatus::ok(); } + explicit CancellationSignal(std::shared_ptr cb) : cb_(std::move(cb)) {} + + ndk::ScopedAStatus cancel() override { + cb_->onError(Error::CANCELED, 0 /* vendorCode */); + cb_->onStateChanged(0, SessionState::IDLING); + return ndk::ScopedAStatus::ok(); + } }; Session::Session(std::shared_ptr cb) : cb_(std::move(cb)) {} ndk::ScopedAStatus Session::generateChallenge(int32_t /*cookie*/, int32_t /*timeoutSec*/) { + if (cb_) { + cb_->onStateChanged(0, SessionState::GENERATING_CHALLENGE); + cb_->onChallengeGenerated(0); + cb_->onStateChanged(0, SessionState::IDLING); + } return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::revokeChallenge(int32_t /*cookie*/, int64_t /*challenge*/) { +ndk::ScopedAStatus Session::revokeChallenge(int32_t /*cookie*/, int64_t challenge) { + if (cb_) { + cb_->onStateChanged(0, SessionState::REVOKING_CHALLENGE); + cb_->onChallengeRevoked(challenge); + cb_->onStateChanged(0, SessionState::IDLING); + } return ndk::ScopedAStatus::ok(); } @@ -47,7 +65,7 @@ ndk::ScopedAStatus Session::authenticate(int32_t /*cookie*/, int64_t /*keystoreO if (cb_) { cb_->onStateChanged(0, SessionState::AUTHENTICATING); } - *return_val = SharedRefBase::make(); + *return_val = SharedRefBase::make(cb_); return ndk::ScopedAStatus::ok(); } @@ -57,15 +75,30 @@ ndk::ScopedAStatus Session::detectInteraction( } ndk::ScopedAStatus Session::enumerateEnrollments(int32_t /*cookie*/) { + if (cb_) { + cb_->onStateChanged(0, SessionState::ENUMERATING_ENROLLMENTS); + cb_->onEnrollmentsEnumerated(std::vector()); + cb_->onStateChanged(0, SessionState::IDLING); + } return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus Session::removeEnrollments(int32_t /*cookie*/, const std::vector& /*enrollmentIds*/) { + if (cb_) { + cb_->onStateChanged(0, SessionState::REMOVING_ENROLLMENTS); + cb_->onEnrollmentsRemoved(std::vector()); + cb_->onStateChanged(0, SessionState::IDLING); + } return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus Session::getAuthenticatorId(int32_t /*cookie*/) { + if (cb_) { + cb_->onStateChanged(0, SessionState::GETTING_AUTHENTICATOR_ID); + cb_->onAuthenticatorIdRetrieved(0 /* authenticatorId */); + cb_->onStateChanged(0, SessionState::IDLING); + } return ndk::ScopedAStatus::ok(); } @@ -75,6 +108,11 @@ ndk::ScopedAStatus Session::invalidateAuthenticatorId(int32_t /*cookie*/) { ndk::ScopedAStatus Session::resetLockout(int32_t /*cookie*/, const keymaster::HardwareAuthToken& /*hat*/) { + if (cb_) { + cb_->onStateChanged(0, SessionState::RESETTING_LOCKOUT); + cb_->onLockoutCleared(); + cb_->onStateChanged(0, SessionState::IDLING); + } return ndk::ScopedAStatus::ok(); } } // namespace aidl::android::hardware::biometrics::face -- GitLab From 657404c22ca49bcafdfc06a7a6d088231edf246b Mon Sep 17 00:00:00 2001 From: Marin Shalamanov Date: Fri, 13 Nov 2020 19:38:53 +0100 Subject: [PATCH 291/790] Clarify the ComposerClient comment for CONFIG_GROUP Clarify that configs with the same group should differ only by refresh rate. Test: n/a Change-Id: I2b09689825fc9564665324ff18eb1907765b9016 --- current.txt | 1 + graphics/composer/2.4/IComposerClient.hal | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/current.txt b/current.txt index 7ef176bab0..073beb7681 100644 --- a/current.txt +++ b/current.txt @@ -769,6 +769,7 @@ a64467bae843569f0d465c5be7f0c7a5b987985b55a3ef4794dd5afc68538650 android.hardwar # ABI preserving changes to HALs during Android S 1ca372cd67d197df099e87616a613ba6ede6552638a603e18f86c8834302c3d1 android.hardware.gnss@1.0::IGnssMeasurementCallback 6a271e493907e8ba20912e42771bd0d99ae45431a851d5675ef9496d02510a34 android.hardware.gnss@1.1::IGnssMeasurementCallback +2c331a9605f3a08d9c1e0a36169ca57758bc43c11a78ef3f3730509885e52c15 android.hardware.graphics.composer@2.4::IComposerClient 3da3ce039247872d95c6bd48621dbfdfa1c2d2a91a90f257862f87ee2bc46300 android.hardware.health@2.1::types cd84ab19c590e0e73dd2307b591a3093ee18147ef95e6d5418644463a6620076 android.hardware.neuralnetworks@1.2::IDevice 9625e85f56515ad2cf87b6a1847906db669f746ea4ab02cd3d4ca25abc9b0109 android.hardware.neuralnetworks@1.2::types diff --git a/graphics/composer/2.4/IComposerClient.hal b/graphics/composer/2.4/IComposerClient.hal index 9e3cf0e083..1a59bbde80 100644 --- a/graphics/composer/2.4/IComposerClient.hal +++ b/graphics/composer/2.4/IComposerClient.hal @@ -34,7 +34,9 @@ interface IComposerClient extends @2.3::IComposerClient { /** * The configuration group ID (as int32_t) this config is associated to. * Switching between configurations within the same group may be done seamlessly - * in some conditions via setActiveConfigWithConstraints. + * in some conditions via setActiveConfigWithConstraints. Configurations which + * share the same config group are similar in all attributes except for the + * vsync period. */ CONFIG_GROUP = 7, }; -- GitLab From f30af28640407b63fd9f993bd406e38611a98ae0 Mon Sep 17 00:00:00 2001 From: Ytai Ben-Tsvi Date: Tue, 17 Nov 2020 16:51:32 -0800 Subject: [PATCH 292/790] Add dependencies to VtsHalAudioTargetTest_defaults Needed in response to libaudioclient/libaudiofoundation refactor. Test: Compiles Change-Id: I57ef815e932a2e775a70c38fb8e3c7cdda06db54 --- audio/core/all-versions/vts/functional/Android.bp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/audio/core/all-versions/vts/functional/Android.bp b/audio/core/all-versions/vts/functional/Android.bp index c7bfe08889..a809a92558 100644 --- a/audio/core/all-versions/vts/functional/Android.bp +++ b/audio/core/all-versions/vts/functional/Android.bp @@ -22,6 +22,8 @@ cc_defaults { "libxml2", ], shared_libs: [ + "audioclient-types-aidl-unstable-cpp", + "libaudioclient_aidl_conversion", "libbinder", "libfmq", ], -- GitLab From 95e4fe64de2e4e42c7a8b02760270827b313db13 Mon Sep 17 00:00:00 2001 From: Mikhail Naganov Date: Thu, 29 Oct 2020 12:37:00 -0700 Subject: [PATCH 293/790] Move UUID conversions into their own class Mechanical extraction of HidlUtils::uuidFrom/ToHal into a dedicated class UuidUtils. Bug: 142480271 Test: m Change-Id: Ic5333ba32dc293f32c5562d0ef05bde8e5f9b302 --- audio/common/all-versions/default/Android.bp | 1 + .../common/all-versions/default/HidlUtils.cpp | 16 ------ audio/common/all-versions/default/HidlUtils.h | 2 - .../common/all-versions/default/UuidUtils.cpp | 50 +++++++++++++++++++ audio/common/all-versions/default/UuidUtils.h | 50 +++++++++++++++++++ .../all-versions/default/Conversions.cpp | 8 +-- .../all-versions/default/EffectsFactory.cpp | 8 +-- 7 files changed, 109 insertions(+), 26 deletions(-) create mode 100644 audio/common/all-versions/default/UuidUtils.cpp create mode 100644 audio/common/all-versions/default/UuidUtils.h diff --git a/audio/common/all-versions/default/Android.bp b/audio/common/all-versions/default/Android.bp index a72c8dc989..afaa7bb41a 100644 --- a/audio/common/all-versions/default/Android.bp +++ b/audio/common/all-versions/default/Android.bp @@ -46,6 +46,7 @@ cc_defaults { vendor_available: true, srcs: [ "HidlUtils.cpp", + "UuidUtils.cpp", ], export_include_dirs: ["."], diff --git a/audio/common/all-versions/default/HidlUtils.cpp b/audio/common/all-versions/default/HidlUtils.cpp index a470c9cb78..7530d050ff 100644 --- a/audio/common/all-versions/default/HidlUtils.cpp +++ b/audio/common/all-versions/default/HidlUtils.cpp @@ -358,22 +358,6 @@ void HidlUtils::audioPortToHal(const AudioPort& port, struct audio_port* halPort } } -void HidlUtils::uuidFromHal(const audio_uuid_t& halUuid, Uuid* uuid) { - uuid->timeLow = halUuid.timeLow; - uuid->timeMid = halUuid.timeMid; - uuid->versionAndTimeHigh = halUuid.timeHiAndVersion; - uuid->variantAndClockSeqHigh = halUuid.clockSeq; - memcpy(uuid->node.data(), halUuid.node, uuid->node.size()); -} - -void HidlUtils::uuidToHal(const Uuid& uuid, audio_uuid_t* halUuid) { - halUuid->timeLow = uuid.timeLow; - halUuid->timeMid = uuid.timeMid; - halUuid->timeHiAndVersion = uuid.versionAndTimeHigh; - halUuid->clockSeq = uuid.variantAndClockSeqHigh; - memcpy(halUuid->node, uuid.node.data(), uuid.node.size()); -} - } // namespace implementation } // namespace CPP_VERSION } // namespace common diff --git a/audio/common/all-versions/default/HidlUtils.h b/audio/common/all-versions/default/HidlUtils.h index ef6dee3706..20fddef1ab 100644 --- a/audio/common/all-versions/default/HidlUtils.h +++ b/audio/common/all-versions/default/HidlUtils.h @@ -66,8 +66,6 @@ class HidlUtils { const hidl_vec& configs); static void audioPortFromHal(const struct audio_port& halPort, AudioPort* port); static void audioPortToHal(const AudioPort& port, struct audio_port* halPort); - static void uuidFromHal(const audio_uuid_t& halUuid, Uuid* uuid); - static void uuidToHal(const Uuid& uuid, audio_uuid_t* halUuid); }; } // namespace implementation diff --git a/audio/common/all-versions/default/UuidUtils.cpp b/audio/common/all-versions/default/UuidUtils.cpp new file mode 100644 index 0000000000..85edc7b2f4 --- /dev/null +++ b/audio/common/all-versions/default/UuidUtils.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "UuidUtils.h" + +#include +#include + +namespace android { +namespace hardware { +namespace audio { +namespace common { +namespace CPP_VERSION { +namespace implementation { + +void UuidUtils::uuidFromHal(const audio_uuid_t& halUuid, Uuid* uuid) { + uuid->timeLow = halUuid.timeLow; + uuid->timeMid = halUuid.timeMid; + uuid->versionAndTimeHigh = halUuid.timeHiAndVersion; + uuid->variantAndClockSeqHigh = halUuid.clockSeq; + memcpy(uuid->node.data(), halUuid.node, uuid->node.size()); +} + +void UuidUtils::uuidToHal(const Uuid& uuid, audio_uuid_t* halUuid) { + halUuid->timeLow = uuid.timeLow; + halUuid->timeMid = uuid.timeMid; + halUuid->timeHiAndVersion = uuid.versionAndTimeHigh; + halUuid->clockSeq = uuid.variantAndClockSeqHigh; + memcpy(halUuid->node, uuid.node.data(), uuid.node.size()); +} + +} // namespace implementation +} // namespace CPP_VERSION +} // namespace common +} // namespace audio +} // namespace hardware +} // namespace android diff --git a/audio/common/all-versions/default/UuidUtils.h b/audio/common/all-versions/default/UuidUtils.h new file mode 100644 index 0000000000..38db48a730 --- /dev/null +++ b/audio/common/all-versions/default/UuidUtils.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef android_hardware_audio_Uuid_Utils_H_ +#define android_hardware_audio_Uuid_Utils_H_ + +// clang-format off +#include PATH(android/hardware/audio/common/FILE_VERSION/types.h) +// clang-format on + +#include + +using ::android::hardware::hidl_vec; + +namespace android { +namespace hardware { +namespace audio { +namespace common { +namespace CPP_VERSION { +namespace implementation { + +using namespace ::android::hardware::audio::common::CPP_VERSION; + +class UuidUtils { + public: + static void uuidFromHal(const audio_uuid_t& halUuid, Uuid* uuid); + static void uuidToHal(const Uuid& uuid, audio_uuid_t* halUuid); +}; + +} // namespace implementation +} // namespace CPP_VERSION +} // namespace common +} // namespace audio +} // namespace hardware +} // namespace android + +#endif // android_hardware_audio_Uuid_Utils_H_ diff --git a/audio/effect/all-versions/default/Conversions.cpp b/audio/effect/all-versions/default/Conversions.cpp index b1c0b0dc13..0cc8767e8d 100644 --- a/audio/effect/all-versions/default/Conversions.cpp +++ b/audio/effect/all-versions/default/Conversions.cpp @@ -15,7 +15,7 @@ */ #include "Conversions.h" -#include "HidlUtils.h" +#include "UuidUtils.h" #include #include @@ -31,12 +31,12 @@ namespace effect { namespace CPP_VERSION { namespace implementation { -using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils; +using ::android::hardware::audio::common::CPP_VERSION::implementation::UuidUtils; void effectDescriptorFromHal(const effect_descriptor_t& halDescriptor, EffectDescriptor* descriptor) { - HidlUtils::uuidFromHal(halDescriptor.type, &descriptor->type); - HidlUtils::uuidFromHal(halDescriptor.uuid, &descriptor->uuid); + UuidUtils::uuidFromHal(halDescriptor.type, &descriptor->type); + UuidUtils::uuidFromHal(halDescriptor.uuid, &descriptor->uuid); descriptor->flags = EnumBitfield(halDescriptor.flags); descriptor->cpuLoad = halDescriptor.cpuLoad; descriptor->memoryUsage = halDescriptor.memoryUsage; diff --git a/audio/effect/all-versions/default/EffectsFactory.cpp b/audio/effect/all-versions/default/EffectsFactory.cpp index acce7deaad..b265d3d921 100644 --- a/audio/effect/all-versions/default/EffectsFactory.cpp +++ b/audio/effect/all-versions/default/EffectsFactory.cpp @@ -24,10 +24,10 @@ #include "Effect.h" #include "EnvironmentalReverbEffect.h" #include "EqualizerEffect.h" -#include "HidlUtils.h" #include "LoudnessEnhancerEffect.h" #include "NoiseSuppressionEffect.h" #include "PresetReverbEffect.h" +#include "UuidUtils.h" #include "VirtualizerEffect.h" #include "VisualizerEffect.h" #include "common/all-versions/default/EffectMap.h" @@ -53,7 +53,7 @@ namespace effect { namespace CPP_VERSION { namespace implementation { -using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils; +using ::android::hardware::audio::common::CPP_VERSION::implementation::UuidUtils; // static sp EffectsFactory::dispatchEffectInstanceCreation(const effect_descriptor_t& halDescriptor, @@ -135,7 +135,7 @@ exit: Return EffectsFactory::getDescriptor(const Uuid& uuid, getDescriptor_cb _hidl_cb) { effect_uuid_t halUuid; - HidlUtils::uuidToHal(uuid, &halUuid); + UuidUtils::uuidToHal(uuid, &halUuid); effect_descriptor_t halDescriptor; status_t status = EffectGetDescriptor(&halUuid, &halDescriptor); EffectDescriptor descriptor; @@ -170,7 +170,7 @@ Return EffectsFactory::createEffect(const Uuid& uuid, int32_t session, int Return EffectsFactory::createEffectImpl(const Uuid& uuid, int32_t session, int32_t ioHandle, int32_t device, createEffect_cb _hidl_cb) { effect_uuid_t halUuid; - HidlUtils::uuidToHal(uuid, &halUuid); + UuidUtils::uuidToHal(uuid, &halUuid); effect_handle_t handle; Result retval(Result::OK); status_t status; -- GitLab From becd2f136b6b189034329866a8d62929e5f952e0 Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Fri, 20 Nov 2020 01:45:55 +0800 Subject: [PATCH 294/790] wifi: fix old vts tests on newer HAL Older registerCallback is not deprecated until V1.4 HAL correctly. As a result, their returning codes are still SUCCESS. Bug: 173570755 Test: atest VtsHalWifiSupplicantV1_0TargetTest \ VtsHalWifiSupplicantV1_1TargetTest \ VtsHalWifiSupplicantV1_2TargetTest Change-Id: Ib23821d64f53c144d74818fa3ed9aca06cd25a27 --- .../vts/functional/supplicant_sta_iface_hidl_test.cpp | 9 +++++---- wifi/supplicant/1.1/vts/functional/Android.bp | 2 ++ .../vts/functional/supplicant_sta_iface_hidl_test.cpp | 9 +++++---- wifi/supplicant/1.2/vts/functional/Android.bp | 1 + .../vts/functional/supplicant_sta_iface_hidl_test.cpp | 7 ++++++- 5 files changed, 19 insertions(+), 9 deletions(-) diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp index 1c3141e326..b9c7b30968 100644 --- a/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp +++ b/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include "supplicant_hidl_call_util.h" #include "supplicant_hidl_test_utils.h" @@ -74,7 +74,7 @@ class SupplicantStaIfaceHidlTest : public SupplicantHidlTestBaseV1_0 { sta_iface_ = getSupplicantStaIface(supplicant_); ASSERT_NE(sta_iface_.get(), nullptr); - v1_1 = ::android::hardware::wifi::supplicant::V1_1:: + v1_4 = ::android::hardware::wifi::supplicant::V1_4:: ISupplicantStaIface::castFrom(sta_iface_); memcpy(mac_addr_.data(), kTestMacAddr, mac_addr_.size()); @@ -82,7 +82,7 @@ class SupplicantStaIfaceHidlTest : public SupplicantHidlTestBaseV1_0 { protected: bool isP2pOn_ = false; - sp<::android::hardware::wifi::supplicant::V1_1::ISupplicantStaIface> v1_1 = + sp<::android::hardware::wifi::supplicant::V1_4::ISupplicantStaIface> v1_4 = nullptr; // ISupplicantStaIface object used for all tests in this fixture. sp sta_iface_; @@ -181,8 +181,9 @@ TEST_P(SupplicantStaIfaceHidlTest, Create) { * RegisterCallback */ TEST_P(SupplicantStaIfaceHidlTest, RegisterCallback) { + // This API is deprecated from v1.4 HAL. SupplicantStatusCode expectedCode = - (nullptr != v1_1) ? SupplicantStatusCode::FAILURE_UNKNOWN + (nullptr != v1_4) ? SupplicantStatusCode::FAILURE_UNKNOWN : SupplicantStatusCode::SUCCESS; sta_iface_->registerCallback(new IfaceCallback(), [&](const SupplicantStatus& status) { diff --git a/wifi/supplicant/1.1/vts/functional/Android.bp b/wifi/supplicant/1.1/vts/functional/Android.bp index ee806289ee..d9ae3e029c 100644 --- a/wifi/supplicant/1.1/vts/functional/Android.bp +++ b/wifi/supplicant/1.1/vts/functional/Android.bp @@ -48,6 +48,8 @@ cc_test { "android.hardware.wifi.supplicant@1.0", "android.hardware.wifi.supplicant@1.1", "android.hardware.wifi.supplicant@1.2", + "android.hardware.wifi.supplicant@1.3", + "android.hardware.wifi.supplicant@1.4", "android.hardware.wifi@1.0", "android.hardware.wifi@1.1", "libgmock", diff --git a/wifi/supplicant/1.1/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.1/vts/functional/supplicant_sta_iface_hidl_test.cpp index 418def2f28..7e6e3e47b9 100644 --- a/wifi/supplicant/1.1/vts/functional/supplicant_sta_iface_hidl_test.cpp +++ b/wifi/supplicant/1.1/vts/functional/supplicant_sta_iface_hidl_test.cpp @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include #include @@ -47,14 +47,14 @@ class SupplicantStaIfaceHidlTest : public SupplicantHidlTestBaseV1_1 { sta_iface_ = getSupplicantStaIface_1_1(supplicant_); ASSERT_NE(sta_iface_.get(), nullptr); - v1_2 = ::android::hardware::wifi::supplicant::V1_2:: + v1_4 = ::android::hardware::wifi::supplicant::V1_4:: ISupplicantStaIface::castFrom(sta_iface_); } protected: // ISupplicantStaIface object used for all tests in this fixture. sp sta_iface_; - sp<::android::hardware::wifi::supplicant::V1_2::ISupplicantStaIface> v1_2 = + sp<::android::hardware::wifi::supplicant::V1_4::ISupplicantStaIface> v1_4 = nullptr; }; @@ -139,8 +139,9 @@ class IfaceCallback : public ISupplicantStaIfaceCallback { * RegisterCallback_1_1 */ TEST_P(SupplicantStaIfaceHidlTest, RegisterCallback_1_1) { + // This API is deprecated from v1.4 HAL. SupplicantStatusCode expectedCode = - (nullptr != v1_2) ? SupplicantStatusCode::FAILURE_UNKNOWN + (nullptr != v1_4) ? SupplicantStatusCode::FAILURE_UNKNOWN : SupplicantStatusCode::SUCCESS; sta_iface_->registerCallback_1_1(new IfaceCallback(), [&](const SupplicantStatus& status) { diff --git a/wifi/supplicant/1.2/vts/functional/Android.bp b/wifi/supplicant/1.2/vts/functional/Android.bp index c23585aaef..2592a2b08c 100644 --- a/wifi/supplicant/1.2/vts/functional/Android.bp +++ b/wifi/supplicant/1.2/vts/functional/Android.bp @@ -51,6 +51,7 @@ cc_test { "android.hardware.wifi.supplicant@1.1", "android.hardware.wifi.supplicant@1.2", "android.hardware.wifi.supplicant@1.3", + "android.hardware.wifi.supplicant@1.4", "android.hardware.wifi@1.0", "android.hardware.wifi@1.1", "libgmock", diff --git a/wifi/supplicant/1.2/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.2/vts/functional/supplicant_sta_iface_hidl_test.cpp index 7799390a2c..7f81206deb 100644 --- a/wifi/supplicant/1.2/vts/functional/supplicant_sta_iface_hidl_test.cpp +++ b/wifi/supplicant/1.2/vts/functional/supplicant_sta_iface_hidl_test.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -63,6 +64,8 @@ class SupplicantStaIfaceHidlTest : public SupplicantHidlTestBaseV1_2 { v1_3 = ::android::hardware::wifi::supplicant::V1_3:: ISupplicantStaIface::castFrom(sta_iface_); + v1_4 = ::android::hardware::wifi::supplicant::V1_4:: + ISupplicantStaIface::castFrom(sta_iface_); } enum DppCallbackType { @@ -106,6 +109,7 @@ class SupplicantStaIfaceHidlTest : public SupplicantHidlTestBaseV1_2 { // ISupplicantStaIface object used for all tests in this fixture. sp sta_iface_; sp<::android::hardware::wifi::supplicant::V1_3::ISupplicantStaIface> v1_3; + sp<::android::hardware::wifi::supplicant::V1_4::ISupplicantStaIface> v1_4; bool isDppSupported() { uint32_t keyMgmtMask = 0; @@ -266,8 +270,9 @@ class IfaceDppCallback : public IfaceCallback { * RegisterCallback_1_2 */ TEST_P(SupplicantStaIfaceHidlTest, RegisterCallback_1_2) { + // This API is deprecated from v1.4 HAL. SupplicantStatusCode expectedCode = - (nullptr != v1_3) ? SupplicantStatusCode::FAILURE_UNKNOWN + (nullptr != v1_4) ? SupplicantStatusCode::FAILURE_UNKNOWN : SupplicantStatusCode::SUCCESS; sta_iface_->registerCallback_1_2(new IfaceCallback(), [&](const SupplicantStatus& status) { -- GitLab From e92c13a4d070bd16a086a8e14d4dd18530aef7b4 Mon Sep 17 00:00:00 2001 From: Sarah Chin Date: Wed, 18 Nov 2020 13:40:15 -0800 Subject: [PATCH 295/790] Create getSystemSelectionChannel API Test: atest TelephonyManagerTest Test: atest VtsHalRadioV1_6TargetTest Bug: 152813408 Change-Id: I6f3f70b7ff1b876ec98086431ed5c557875fca85 --- radio/1.6/IRadio.hal | 9 +++++++++ radio/1.6/IRadioResponse.hal | 11 +++++++++++ radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h | 3 +++ radio/1.6/vts/functional/radio_response.cpp | 7 +++++++ 4 files changed, 30 insertions(+) diff --git a/radio/1.6/IRadio.hal b/radio/1.6/IRadio.hal index 8afbf22c64..7f874c64e9 100644 --- a/radio/1.6/IRadio.hal +++ b/radio/1.6/IRadio.hal @@ -349,4 +349,13 @@ interface IRadio extends @1.5::IRadio { oneway setDataThrottling(int32_t serial, DataThrottlingAction dataThrottlingAction, int32_t completionWindowSecs); + + /** + * Get which bands the modem's background scan is acting on. + * + * @param serial Serial number of request. + * + * Response callback is IRadioResponse.getSystemSelectionChannelsResponse() + */ + oneway getSystemSelectionChannels(int32_t serial); }; diff --git a/radio/1.6/IRadioResponse.hal b/radio/1.6/IRadioResponse.hal index 5a71c1fe54..c545db02ef 100644 --- a/radio/1.6/IRadioResponse.hal +++ b/radio/1.6/IRadioResponse.hal @@ -317,4 +317,15 @@ interface IRadioResponse extends @1.5::IRadioResponse { * RadioError:INVALID_ARGUMENTS */ oneway setDataThrottlingResponse(RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:INVALID_ARGUMENTS + */ + oneway getSystemSelectionChannelsResponse(RadioResponseInfo info); }; diff --git a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h index fcf679c267..85be903e9e 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h +++ b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h @@ -795,6 +795,9 @@ class RadioResponse_v1_6 : public ::android::hardware::radio::V1_6::IRadioRespon Return setDataThrottlingResponse( const ::android::hardware::radio::V1_6::RadioResponseInfo& info); + + Return getSystemSelectionChannelsResponse( + const ::android::hardware::radio::V1_6::RadioResponseInfo& info); }; /* Callback class for radio indication */ diff --git a/radio/1.6/vts/functional/radio_response.cpp b/radio/1.6/vts/functional/radio_response.cpp index 788038a041..7da675ea12 100644 --- a/radio/1.6/vts/functional/radio_response.cpp +++ b/radio/1.6/vts/functional/radio_response.cpp @@ -1163,3 +1163,10 @@ Return RadioResponse_v1_6::setDataThrottlingResponse( parent_v1_6.notify(info.serial); return Void(); } + +Return RadioResponse_v1_6::getSystemSelectionChannelsResponse( + const ::android::hardware::radio::V1_6::RadioResponseInfo& info) { + rspInfo = info; + parent_v1_6.notify(info.serial); + return Void(); +} -- GitLab From 3c44b5f8c37a3b45fd0cad8a8859e44332a40cde Mon Sep 17 00:00:00 2001 From: Roman Kiryanov Date: Thu, 19 Nov 2020 11:04:18 -0800 Subject: [PATCH 296/790] Move a.h.g.composer@2.1-resources into system_ext it is not a part of the system according to generic_system.mk. Bug: 173538619 Bug: 167689596 Test: presubmit Signed-off-by: Roman Kiryanov Change-Id: I407d3a99c8b458d31fbc0ae891ae7a685ffb2660 --- graphics/composer/2.1/utils/resources/Android.bp | 1 + 1 file changed, 1 insertion(+) diff --git a/graphics/composer/2.1/utils/resources/Android.bp b/graphics/composer/2.1/utils/resources/Android.bp index dc20eaebed..d77bff07bc 100644 --- a/graphics/composer/2.1/utils/resources/Android.bp +++ b/graphics/composer/2.1/utils/resources/Android.bp @@ -15,6 +15,7 @@ cc_library { name: "android.hardware.graphics.composer@2.1-resources", + system_ext_specific: true, defaults: ["hidl_defaults"], vendor_available: true, shared_libs: [ -- GitLab From 5b8a144d8ca5c99c1d3149ef74399b9a38b05cdc Mon Sep 17 00:00:00 2001 From: Mikhail Naganov Date: Thu, 29 Oct 2020 13:08:05 -0700 Subject: [PATCH 297/790] Implement a.h.audio.common@7.0-util module This includes a rewrite of HidlUtils for V7. A unit test is added for its conversion functions. Made necessary minor adjustments to the HAL V7 types. Also, fixed definition of 'audioFormatsList' to allow for vendor extensions. Bug: 142480271 Bug: 173647783 Test: m && atest android.hardware.audio.common@7.0-util_tests Change-Id: Ib883f1c246fce78c004846516699aa724d4b5d44 --- audio/7.0/config/api/current.txt | 12 +- .../7.0/config/audio_policy_configuration.xsd | 4 +- audio/7.0/types.hal | 35 +- ...id_audio_policy_configuration_V7_0-enums.h | 39 + audio/common/7.0/types.hal | 30 +- .../all-versions/default/7.0/HidlUtils.cpp | 847 ++++++++++++++++++ audio/common/all-versions/default/Android.bp | 58 +- .../common/all-versions/default/HidlUtils.cpp | 69 +- audio/common/all-versions/default/HidlUtils.h | 135 ++- .../common/all-versions/default/TEST_MAPPING | 7 + .../default/tests/hidlutils_tests.cpp | 631 +++++++++++++ .../core/all-versions/default/Conversions.cpp | 1 + audio/core/all-versions/default/Device.cpp | 6 +- .../4.0/AudioPrimaryHidlHalTest.cpp | 3 +- .../7.0/AudioPrimaryHidlHalTest.cpp | 3 +- 15 files changed, 1771 insertions(+), 109 deletions(-) create mode 100644 audio/common/all-versions/default/7.0/HidlUtils.cpp create mode 100644 audio/common/all-versions/default/TEST_MAPPING create mode 100644 audio/common/all-versions/default/tests/hidlutils_tests.cpp diff --git a/audio/7.0/config/api/current.txt b/audio/7.0/config/api/current.txt index fea697993e..1da8b095bc 100644 --- a/audio/7.0/config/api/current.txt +++ b/audio/7.0/config/api/current.txt @@ -360,7 +360,7 @@ package android.audio.policy.configuration.V7_0 { public static class DevicePorts.DevicePort { ctor public DevicePorts.DevicePort(); method @Nullable public String getAddress(); - method @Nullable public java.util.List getEncodedFormats(); + method @Nullable public java.util.List getEncodedFormats(); method @Nullable public android.audio.policy.configuration.V7_0.Gains getGains(); method @Nullable public java.util.List getProfile(); method @Nullable public android.audio.policy.configuration.V7_0.Role getRole(); @@ -368,7 +368,7 @@ package android.audio.policy.configuration.V7_0 { method @Nullable public String getType(); method @Nullable public boolean get_default(); method public void setAddress(@Nullable String); - method public void setEncodedFormats(@Nullable java.util.List); + method public void setEncodedFormats(@Nullable java.util.List); method public void setGains(@Nullable android.audio.policy.configuration.V7_0.Gains); method public void setRole(@Nullable android.audio.policy.configuration.V7_0.Role); method public void setTagName(@Nullable String); @@ -527,10 +527,10 @@ package android.audio.policy.configuration.V7_0 { public static class SurroundFormats.Format { ctor public SurroundFormats.Format(); - method @Nullable public android.audio.policy.configuration.V7_0.AudioFormat getName(); - method @Nullable public java.util.List getSubformats(); - method public void setName(@Nullable android.audio.policy.configuration.V7_0.AudioFormat); - method public void setSubformats(@Nullable java.util.List); + method @Nullable public String getName(); + method @Nullable public java.util.List getSubformats(); + method public void setName(@Nullable String); + method public void setSubformats(@Nullable java.util.List); } public class SurroundSound { diff --git a/audio/7.0/config/audio_policy_configuration.xsd b/audio/7.0/config/audio_policy_configuration.xsd index 67848287ef..56b3a27161 100644 --- a/audio/7.0/config/audio_policy_configuration.xsd +++ b/audio/7.0/config/audio_policy_configuration.xsd @@ -774,13 +774,13 @@ - + - + diff --git a/audio/7.0/types.hal b/audio/7.0/types.hal index 6cac9c95fe..1ae7bad310 100644 --- a/audio/7.0/types.hal +++ b/audio/7.0/types.hal @@ -179,7 +179,8 @@ struct AudioFrequencyResponsePoint { * Used by StreamIn and Device */ struct MicrophoneInfo { - /** Unique alphanumeric id for microphone. Guaranteed to be the same + /** + * Unique alphanumeric id for microphone. Guaranteed to be the same * even after rebooting. */ string deviceId; @@ -187,18 +188,21 @@ struct MicrophoneInfo { * Device specific information */ DeviceAddress deviceAddress; - /** Each element of the vector must describe the channel with the same - * index. + /** + * Each element of the vector must describe the channel with the same + * index. */ vec channelMapping; /** Location of the microphone in regard to the body of the device */ AudioMicrophoneLocation location; - /** Identifier to help group related microphones together - * e.g. microphone arrays should belong to the same group + /** + * Identifier to help group related microphones together + * e.g. microphone arrays should belong to the same group */ AudioMicrophoneGroup group; - /** Index of this microphone within the group. - * (group, index) must be unique within the same device. + /** + * Index of this microphone within the group. + * (group, index) must be unique within the same device. */ uint32_t indexInTheGroup; /** Level in dBFS produced by a 1000 Hz tone at 94 dB SPL */ @@ -209,17 +213,20 @@ struct MicrophoneInfo { float minSpl; /** Standard polar pattern of the microphone */ AudioMicrophoneDirectionality directionality; - /** Vector with ordered frequency responses (from low to high frequencies) - * with the frequency response of the microphone. - * Levels are in dB, relative to level at 1000 Hz + /** + * Vector with ordered frequency responses (from low to high frequencies) + * with the frequency response of the microphone. + * Levels are in dB, relative to level at 1000 Hz */ vec frequencyResponse; - /** Position of the microphone's capsule in meters, from the - * bottom-left-back corner of the bounding box of device. + /** + * Position of the microphone's capsule in meters, from the + * bottom-left-back corner of the bounding box of device. */ AudioMicrophoneCoordinate position; - /** Normalized point to signal the main orientation of the microphone's - * capsule. sqrt(x^2 + y^2 + z^2) = 1 + /** + * Normalized point to signal the main orientation of the microphone's + * capsule. sqrt(x^2 + y^2 + z^2) = 1 */ AudioMicrophoneCoordinate orientation; }; diff --git a/audio/common/7.0/enums/include/android_audio_policy_configuration_V7_0-enums.h b/audio/common/7.0/enums/include/android_audio_policy_configuration_V7_0-enums.h index 7148d76820..414eede6d1 100644 --- a/audio/common/7.0/enums/include/android_audio_policy_configuration_V7_0-enums.h +++ b/audio/common/7.0/enums/include/android_audio_policy_configuration_V7_0-enums.h @@ -18,6 +18,8 @@ #define ANDROID_AUDIO_POLICY_CONFIGURATION_V7_0_ENUMS_H #include +#include +#include #include @@ -210,6 +212,43 @@ static inline bool isOutputDevice(const std::string& device) { return isOutputDevice(stringToAudioDevice(device)); } +static inline bool isVendorExtension(const std::string& device) { + // Must match the "vendorExtension" rule from the XSD file. + static const std::string vendorPrefix = "VX_"; + return device.size() > vendorPrefix.size() && + device.substr(0, vendorPrefix.size()) == vendorPrefix && + std::all_of(device.begin() + vendorPrefix.size(), device.end(), + [](unsigned char c) { return c == '_' || std::isalnum(c); }); +} + +static inline bool isUnknownAudioChannelMask(const std::string& mask) { + return stringToAudioChannelMask(mask) == AudioChannelMask::UNKNOWN; +} + +static inline bool isUnknownAudioDevice(const std::string& device) { + return stringToAudioDevice(device) == AudioDevice::UNKNOWN && !isVendorExtension(device); +} + +static inline bool isUnknownAudioFormat(const std::string& format) { + return stringToAudioFormat(format) == AudioFormat::UNKNOWN && !isVendorExtension(format); +} + +static inline bool isUnknownAudioGainMode(const std::string& mode) { + return stringToAudioGainMode(mode) == AudioGainMode::UNKNOWN; +} + +static inline bool isUnknownAudioSource(const std::string& source) { + return stringToAudioSource(source) == AudioSource::UNKNOWN; +} + +static inline bool isUnknownAudioStreamType(const std::string& streamType) { + return stringToAudioStreamType(streamType) == AudioStreamType::UNKNOWN; +} + +static inline bool isUnknownAudioUsage(const std::string& usage) { + return stringToAudioUsage(usage) == AudioUsage::UNKNOWN; +} + } // namespace android::audio::policy::configuration::V7_0 #endif // ANDROID_AUDIO_POLICY_CONFIGURATION_V7_0_ENUMS_H diff --git a/audio/common/7.0/types.hal b/audio/common/7.0/types.hal index 631d5240a2..2da9815cbd 100644 --- a/audio/common/7.0/types.hal +++ b/audio/common/7.0/types.hal @@ -118,9 +118,9 @@ typedef string AudioChannelMask; * Base configuration attributes applicable to any stream of audio. */ struct AudioConfigBase { - AudioFormat format; // 'DEFAULT' means 'unspecified' + AudioFormat format; // empty means 'unspecified' uint32_t sampleRateHz; // 0 means 'unspecified' - vec channelMask; // empty means 'unspecified' + AudioChannelMask channelMask; // empty means 'unspecified' }; /** @@ -167,10 +167,18 @@ struct DeviceAddress { AudioDevice deviceType; safe_union Address { /** - * The address may be left unspecified if 'device' specifies - * a physical device unambiguously. + * String uniquely identifying the device among other devices + * of the same type. Can be empty in case there is only one device + * of this type. + * + * Depending on the device type, its id may be assigned by the framework + * (this is done for REMOTE_SUBMIX), or specified in the audio policy + * configuration file (typically done for BUS devices), or assigned + * by the HAL service. In any case, both framework and HAL must + * never attempt to parse the value of the id. If the address must + * be parsed, one of the members below must be used instead of 'id'. */ - Monostate unspecified; + string id; /** IEEE 802 MAC address. Set for Bluetooth devices. */ uint8_t[6] mac; /** IPv4 Address. Set for IPv4 devices. */ @@ -182,10 +190,6 @@ struct DeviceAddress { int32_t card; int32_t device; } alsa; - /** Arbitrary BUS device unique address. Not interpreted by the framework. */ - string bus; - /** Arbitrary REMOTE_SUBMIX device unique address. Not interpreted by the HAL. */ - string rSubmix; } address; }; @@ -349,9 +353,9 @@ struct AudioGainConfig { /** * Gain values in millibels for each channel ordered from LSb to MSb in * channel mask. The number of values is 1 in joint mode or - * popcount(channel_mask). + * the number of channels in the channel mask. */ - int32_t[4 * 8] values; + vec values; uint32_t rampDurationMs; // ramp duration in ms }; @@ -409,7 +413,7 @@ struct AudioPortConfig { * parameters (or none) may be set. See the documentation of the * AudioConfigBase struct. */ - AudioConfigBase config; + AudioConfigBase base; /** Associated gain control. */ safe_union OptionalGain { Monostate unspecified; @@ -439,6 +443,8 @@ struct AudioPort { vec profiles; /** List of gain controls attached to the port. */ vec gains; + /** Parameters that depend on the actual port role. */ + AudioPortExtendedInfo ext; /** * Current configuration of the audio port, may have all the fields left * unspecified. diff --git a/audio/common/all-versions/default/7.0/HidlUtils.cpp b/audio/common/all-versions/default/7.0/HidlUtils.cpp new file mode 100644 index 0000000000..1a662825bd --- /dev/null +++ b/audio/common/all-versions/default/7.0/HidlUtils.cpp @@ -0,0 +1,847 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#define LOG_TAG "HidlUtils" +#include + +#include +#include + +#include "HidlUtils.h" + +namespace android { +namespace hardware { +namespace audio { +namespace common { +namespace CPP_VERSION { +namespace implementation { + +namespace xsd { +using namespace ::android::audio::policy::configuration::V7_0; +} + +#define CONVERT_CHECKED(expr, result) \ + if (status_t status = (expr); status != NO_ERROR) { \ + result = status; \ + } + +status_t HidlUtils::audioIndexChannelMaskFromHal(audio_channel_mask_t halChannelMask, + AudioChannelMask* channelMask) { + *channelMask = audio_channel_index_mask_to_string(halChannelMask); + if (!channelMask->empty() && !xsd::isUnknownAudioChannelMask(*channelMask)) { + return NO_ERROR; + } + ALOGE("Unknown index channel mask value 0x%X", halChannelMask); + *channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_NONE); + return BAD_VALUE; +} + +status_t HidlUtils::audioInputChannelMaskFromHal(audio_channel_mask_t halChannelMask, + AudioChannelMask* channelMask) { + *channelMask = audio_channel_in_mask_to_string(halChannelMask); + if (!channelMask->empty() && !xsd::isUnknownAudioChannelMask(*channelMask)) { + return NO_ERROR; + } + ALOGE("Unknown input channel mask value 0x%X", halChannelMask); + *channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_NONE); + return BAD_VALUE; +} + +status_t HidlUtils::audioOutputChannelMaskFromHal(audio_channel_mask_t halChannelMask, + AudioChannelMask* channelMask) { + *channelMask = audio_channel_out_mask_to_string(halChannelMask); + if (!channelMask->empty() && !xsd::isUnknownAudioChannelMask(*channelMask)) { + return NO_ERROR; + } + ALOGE("Unknown output channel mask value 0x%X", halChannelMask); + *channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_NONE); + return BAD_VALUE; +} + +status_t HidlUtils::audioChannelMaskFromHal(audio_channel_mask_t halChannelMask, bool isInput, + AudioChannelMask* channelMask) { + if (halChannelMask != AUDIO_CHANNEL_NONE) { + if (audio_channel_mask_is_valid(halChannelMask)) { + switch (audio_channel_mask_get_representation(halChannelMask)) { + case AUDIO_CHANNEL_REPRESENTATION_POSITION: + return isInput ? audioInputChannelMaskFromHal(halChannelMask, channelMask) + : audioOutputChannelMaskFromHal(halChannelMask, channelMask); + case AUDIO_CHANNEL_REPRESENTATION_INDEX: + // Index masks do not have direction. + return audioIndexChannelMaskFromHal(halChannelMask, channelMask); + // no default + } + } + *channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_NONE); + return BAD_VALUE; + } + *channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_NONE); + return NO_ERROR; +} + +status_t HidlUtils::audioChannelMaskToHal(const AudioChannelMask& channelMask, + audio_channel_mask_t* halChannelMask) { + if (!xsd::isUnknownAudioChannelMask(channelMask) && + audio_channel_mask_from_string(channelMask.c_str(), halChannelMask)) { + return NO_ERROR; + } + ALOGE("Unknown channel mask \"%s\"", channelMask.c_str()); + *halChannelMask = AUDIO_CHANNEL_NONE; + return BAD_VALUE; +} + +status_t HidlUtils::audioConfigBaseFromHal(const audio_config_base_t& halConfigBase, bool isInput, + AudioConfigBase* configBase) { + status_t result = NO_ERROR; + configBase->sampleRateHz = halConfigBase.sample_rate; + CONVERT_CHECKED( + audioChannelMaskFromHal(halConfigBase.channel_mask, isInput, &configBase->channelMask), + result); + CONVERT_CHECKED(audioFormatFromHal(halConfigBase.format, &configBase->format), result); + return result; +} + +status_t HidlUtils::audioConfigBaseToHal(const AudioConfigBase& configBase, + audio_config_base_t* halConfigBase) { + status_t result = NO_ERROR; + halConfigBase->sample_rate = configBase.sampleRateHz; + CONVERT_CHECKED(audioChannelMaskToHal(configBase.channelMask, &halConfigBase->channel_mask), + result); + CONVERT_CHECKED(audioFormatToHal(configBase.format, &halConfigBase->format), result); + return result; +} + +status_t HidlUtils::audioDeviceTypeFromHal(audio_devices_t halDevice, AudioDevice* device) { + *device = audio_device_to_string(halDevice); + if (!device->empty() && !xsd::isUnknownAudioDevice(*device)) { + return NO_ERROR; + } + ALOGE("Unknown audio device value 0x%X", halDevice); + *device = toString(xsd::AudioDevice::AUDIO_DEVICE_NONE); + return BAD_VALUE; +} + +status_t HidlUtils::audioDeviceTypeToHal(const AudioDevice& device, audio_devices_t* halDevice) { + if (!xsd::isUnknownAudioDevice(device) && audio_device_from_string(device.c_str(), halDevice)) { + return NO_ERROR; + } + ALOGE("Unknown audio device \"%s\"", device.c_str()); + *halDevice = AUDIO_DEVICE_NONE; + return BAD_VALUE; +} + +status_t HidlUtils::audioFormatFromHal(audio_format_t halFormat, AudioFormat* format) { + *format = audio_format_to_string(halFormat); + if (!format->empty() && !xsd::isUnknownAudioFormat(*format)) { + return NO_ERROR; + } + ALOGE("Unknown audio format value 0x%X", halFormat); + return BAD_VALUE; +} + +status_t HidlUtils::audioFormatToHal(const AudioFormat& format, audio_format_t* halFormat) { + if (!xsd::isUnknownAudioFormat(format) && audio_format_from_string(format.c_str(), halFormat)) { + return NO_ERROR; + } + ALOGE("Unknown audio format \"%s\"", format.c_str()); + *halFormat = AUDIO_FORMAT_DEFAULT; + return BAD_VALUE; +} + +status_t HidlUtils::audioGainModeMaskFromHal(audio_gain_mode_t halGainModeMask, + hidl_vec* gainModeMask) { + status_t status = NO_ERROR; + std::vector result; + for (uint32_t bit = 0; bit < sizeof(audio_gain_mode_t) * 8; ++bit) { + audio_gain_mode_t flag = static_cast(1u << bit); + if ((flag & halGainModeMask) == flag) { + AudioGainMode flagStr = audio_gain_mode_to_string(flag); + if (!flagStr.empty() && !xsd::isUnknownAudioGainMode(flagStr)) { + result.push_back(flagStr); + } else { + ALOGE("Unknown audio gain mode value 0x%X", flag); + status = BAD_VALUE; + } + } + } + *gainModeMask = result; + return status; +} + +status_t HidlUtils::audioGainModeMaskToHal(const hidl_vec& gainModeMask, + audio_gain_mode_t* halGainModeMask) { + status_t status = NO_ERROR; + *halGainModeMask = {}; + for (const auto& gainMode : gainModeMask) { + audio_gain_mode_t halGainMode; + if (!xsd::isUnknownAudioGainMode(gainMode) && + audio_gain_mode_from_string(gainMode.c_str(), &halGainMode)) { + *halGainModeMask = static_cast(*halGainModeMask | halGainMode); + } else { + ALOGE("Unknown audio gain mode \"%s\"", gainMode.c_str()); + status = BAD_VALUE; + } + } + return status; +} + +status_t HidlUtils::audioSourceFromHal(audio_source_t halSource, AudioSource* source) { + *source = audio_source_to_string(halSource); + if (!source->empty() && !xsd::isUnknownAudioSource(*source)) { + return NO_ERROR; + } + ALOGE("Unknown audio source value 0x%X", halSource); + *source = toString(xsd::AudioSource::AUDIO_SOURCE_DEFAULT); + return BAD_VALUE; +} + +status_t HidlUtils::audioSourceToHal(const AudioSource& source, audio_source_t* halSource) { + if (!xsd::isUnknownAudioSource(source) && audio_source_from_string(source.c_str(), halSource)) { + return NO_ERROR; + } + ALOGE("Unknown audio source \"%s\"", source.c_str()); + *halSource = AUDIO_SOURCE_DEFAULT; + return BAD_VALUE; +} + +status_t HidlUtils::audioStreamTypeFromHal(audio_stream_type_t halStreamType, + AudioStreamType* streamType) { + *streamType = audio_stream_type_to_string(halStreamType); + if (!streamType->empty() && !xsd::isUnknownAudioStreamType(*streamType)) { + return NO_ERROR; + } + ALOGE("Unknown audio stream type value 0x%X", halStreamType); + return BAD_VALUE; +} + +status_t HidlUtils::audioStreamTypeToHal(const AudioStreamType& streamType, + audio_stream_type_t* halStreamType) { + if (!xsd::isUnknownAudioStreamType(streamType) && + audio_stream_type_from_string(streamType.c_str(), halStreamType)) { + return NO_ERROR; + } + ALOGE("Unknown audio stream type \"%s\"", streamType.c_str()); + *halStreamType = AUDIO_STREAM_DEFAULT; + return BAD_VALUE; +} + +status_t HidlUtils::audioConfigFromHal(const audio_config_t& halConfig, bool isInput, + AudioConfig* config) { + status_t result = NO_ERROR; + audio_config_base_t halConfigBase = {halConfig.sample_rate, halConfig.channel_mask, + halConfig.format}; + CONVERT_CHECKED(audioConfigBaseFromHal(halConfigBase, isInput, &config->base), result); + CONVERT_CHECKED(audioOffloadInfoFromHal(halConfig.offload_info, &config->offloadInfo), result); + config->frameCount = halConfig.frame_count; + return result; +} + +status_t HidlUtils::audioConfigToHal(const AudioConfig& config, audio_config_t* halConfig) { + status_t result = NO_ERROR; + *halConfig = AUDIO_CONFIG_INITIALIZER; + audio_config_base_t halConfigBase = AUDIO_CONFIG_BASE_INITIALIZER; + CONVERT_CHECKED(audioConfigBaseToHal(config.base, &halConfigBase), result); + halConfig->sample_rate = halConfigBase.sample_rate; + halConfig->channel_mask = halConfigBase.channel_mask; + halConfig->format = halConfigBase.format; + CONVERT_CHECKED(audioOffloadInfoToHal(config.offloadInfo, &halConfig->offload_info), result); + halConfig->frame_count = config.frameCount; + return result; +} + +status_t HidlUtils::audioGainConfigFromHal(const struct audio_gain_config& halConfig, bool isInput, + AudioGainConfig* config) { + status_t result = NO_ERROR; + config->index = halConfig.index; + CONVERT_CHECKED(audioGainModeMaskFromHal(halConfig.mode, &config->mode), result); + CONVERT_CHECKED(audioChannelMaskFromHal(halConfig.channel_mask, isInput, &config->channelMask), + result); + if (halConfig.mode & AUDIO_GAIN_MODE_JOINT) { + config->values.resize(1); + config->values[0] = halConfig.values[0]; + } + if (halConfig.mode & (AUDIO_GAIN_MODE_CHANNELS | AUDIO_GAIN_MODE_RAMP)) { + config->values.resize(__builtin_popcount(halConfig.channel_mask)); + for (size_t i = 0; i < config->values.size(); ++i) { + config->values[i] = halConfig.values[i]; + } + } + config->rampDurationMs = halConfig.ramp_duration_ms; + return result; +} + +status_t HidlUtils::audioGainConfigToHal(const AudioGainConfig& config, + struct audio_gain_config* halConfig) { + status_t result = NO_ERROR; + halConfig->index = config.index; + CONVERT_CHECKED(audioGainModeMaskToHal(config.mode, &halConfig->mode), result); + CONVERT_CHECKED(audioChannelMaskToHal(config.channelMask, &halConfig->channel_mask), result); + memset(halConfig->values, 0, sizeof(halConfig->values)); + if (halConfig->mode & AUDIO_GAIN_MODE_JOINT) { + if (config.values.size() > 0) { + halConfig->values[0] = config.values[0]; + } else { + ALOGE("Empty values vector in AudioGainConfig"); + result = BAD_VALUE; + } + } + if (halConfig->mode & (AUDIO_GAIN_MODE_CHANNELS | AUDIO_GAIN_MODE_RAMP)) { + size_t channelCount = __builtin_popcount(halConfig->channel_mask); + size_t valuesCount = config.values.size(); + if (channelCount != valuesCount) { + ALOGE("Wrong number of values in AudioGainConfig, expected: %zu, found: %zu", + channelCount, valuesCount); + result = BAD_VALUE; + if (channelCount < valuesCount) { + valuesCount = channelCount; + } + } + for (size_t i = 0; i < valuesCount; ++i) { + halConfig->values[i] = config.values[i]; + } + } + halConfig->ramp_duration_ms = config.rampDurationMs; + return result; +} + +status_t HidlUtils::audioGainFromHal(const struct audio_gain& halGain, bool isInput, + AudioGain* gain) { + status_t result = NO_ERROR; + CONVERT_CHECKED(audioGainModeMaskFromHal(halGain.mode, &gain->mode), result); + CONVERT_CHECKED(audioChannelMaskFromHal(halGain.channel_mask, isInput, &gain->channelMask), + result); + gain->minValue = halGain.min_value; + gain->maxValue = halGain.max_value; + gain->defaultValue = halGain.default_value; + gain->stepValue = halGain.step_value; + gain->minRampMs = halGain.min_ramp_ms; + gain->maxRampMs = halGain.max_ramp_ms; + return result; +} + +status_t HidlUtils::audioGainToHal(const AudioGain& gain, struct audio_gain* halGain) { + status_t result = NO_ERROR; + CONVERT_CHECKED(audioGainModeMaskToHal(gain.mode, &halGain->mode), result); + CONVERT_CHECKED(audioChannelMaskToHal(gain.channelMask, &halGain->channel_mask), result); + halGain->min_value = gain.minValue; + halGain->max_value = gain.maxValue; + halGain->default_value = gain.defaultValue; + halGain->step_value = gain.stepValue; + halGain->min_ramp_ms = gain.minRampMs; + halGain->max_ramp_ms = gain.maxRampMs; + return result; +} + +status_t HidlUtils::audioUsageFromHal(audio_usage_t halUsage, AudioUsage* usage) { + if (halUsage == AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST || + halUsage == AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT || + halUsage == AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED || + halUsage == AUDIO_USAGE_NOTIFICATION_EVENT) { + halUsage = AUDIO_USAGE_NOTIFICATION; + } + *usage = audio_usage_to_string(halUsage); + if (!usage->empty() && !xsd::isUnknownAudioUsage(*usage)) { + return NO_ERROR; + } + ALOGE("Unknown audio usage %d", halUsage); + *usage = toString(xsd::AudioUsage::AUDIO_USAGE_UNKNOWN); + return BAD_VALUE; +} + +status_t HidlUtils::audioUsageToHal(const AudioUsage& usage, audio_usage_t* halUsage) { + if (!xsd::isUnknownAudioUsage(usage) && audio_usage_from_string(usage.c_str(), halUsage)) { + return NO_ERROR; + } + ALOGE("Unknown audio usage \"%s\"", usage.c_str()); + *halUsage = AUDIO_USAGE_UNKNOWN; + return BAD_VALUE; +} + +status_t HidlUtils::audioOffloadInfoFromHal(const audio_offload_info_t& halOffload, + AudioOffloadInfo* offload) { + status_t result = NO_ERROR; + audio_config_base_t halConfigBase = {halOffload.sample_rate, halOffload.channel_mask, + halOffload.format}; + CONVERT_CHECKED(audioConfigBaseFromHal(halConfigBase, false /*isInput*/, &offload->base), + result); + CONVERT_CHECKED(audioStreamTypeFromHal(halOffload.stream_type, &offload->streamType), result); + offload->bitRatePerSecond = halOffload.bit_rate; + offload->durationMicroseconds = halOffload.duration_us; + offload->hasVideo = halOffload.has_video; + offload->isStreaming = halOffload.is_streaming; + offload->bitWidth = halOffload.bit_width; + offload->bufferSize = halOffload.offload_buffer_size; + CONVERT_CHECKED(audioUsageFromHal(halOffload.usage, &offload->usage), result); + if (halOffload.version >= AUDIO_OFFLOAD_INFO_VERSION_0_2) { + offload->encapsulationMode = + static_cast(halOffload.encapsulation_mode); + offload->contentId = halOffload.content_id; + offload->syncId = halOffload.sync_id; + } else { + offload->encapsulationMode = AudioEncapsulationMode::NONE; + offload->contentId = 0; + offload->syncId = 0; + } + return result; +} + +status_t HidlUtils::audioOffloadInfoToHal(const AudioOffloadInfo& offload, + audio_offload_info_t* halOffload) { + status_t result = NO_ERROR; + *halOffload = AUDIO_INFO_INITIALIZER; + audio_config_base_t halConfigBase = AUDIO_CONFIG_BASE_INITIALIZER; + CONVERT_CHECKED(audioConfigBaseToHal(offload.base, &halConfigBase), result); + halOffload->sample_rate = halConfigBase.sample_rate; + halOffload->channel_mask = halConfigBase.channel_mask; + halOffload->format = halConfigBase.format; + CONVERT_CHECKED(audioStreamTypeToHal(offload.streamType, &halOffload->stream_type), result); + halOffload->bit_rate = offload.bitRatePerSecond; + halOffload->duration_us = offload.durationMicroseconds; + halOffload->has_video = offload.hasVideo; + halOffload->is_streaming = offload.isStreaming; + halOffload->bit_width = offload.bitWidth; + halOffload->offload_buffer_size = offload.bufferSize; + CONVERT_CHECKED(audioUsageToHal(offload.usage, &halOffload->usage), result); + halOffload->encapsulation_mode = + static_cast(offload.encapsulationMode); + halOffload->content_id = offload.contentId; + halOffload->sync_id = offload.syncId; + return result; +} + +status_t HidlUtils::audioPortConfigFromHal(const struct audio_port_config& halConfig, + AudioPortConfig* config) { + status_t result = NO_ERROR; + bool isInput = false; + config->id = halConfig.id; + CONVERT_CHECKED(audioPortExtendedInfoFromHal(halConfig.role, halConfig.type, + halConfig.ext.device, halConfig.ext.mix, + halConfig.ext.session, &config->ext, &isInput), + result); + if (audio_port_config_has_input_direction(&halConfig) != isInput) { + ALOGE("Inconsistent port config direction data, is input: %d (hal) != %d (converter)", + audio_port_config_has_input_direction(&halConfig), isInput); + result = BAD_VALUE; + } + if (halConfig.config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) { + config->base.sampleRateHz = halConfig.sample_rate; + } else { + config->base.sampleRateHz = {}; + } + if (halConfig.config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) { + CONVERT_CHECKED( + audioChannelMaskFromHal(halConfig.channel_mask, isInput, &config->base.channelMask), + result); + } else { + config->base.channelMask = {}; + } + if (halConfig.config_mask & AUDIO_PORT_CONFIG_FORMAT) { + CONVERT_CHECKED(audioFormatFromHal(halConfig.format, &config->base.format), result); + } else { + config->base.format = {}; + } + if (halConfig.config_mask & AUDIO_PORT_CONFIG_GAIN) { + config->gain.config({}); + CONVERT_CHECKED(audioGainConfigFromHal(halConfig.gain, isInput, &config->gain.config()), + result); + } else { + config->gain.unspecified({}); + } + return result; +} + +status_t HidlUtils::audioPortConfigToHal(const AudioPortConfig& config, + struct audio_port_config* halConfig) { + status_t result = NO_ERROR; + memset(halConfig, 0, sizeof(audio_port_config)); + halConfig->id = config.id; + halConfig->config_mask = {}; + if (config.base.sampleRateHz != 0) { + halConfig->config_mask |= AUDIO_PORT_CONFIG_SAMPLE_RATE; + halConfig->sample_rate = config.base.sampleRateHz; + } + if (!config.base.channelMask.empty()) { + halConfig->config_mask |= AUDIO_PORT_CONFIG_CHANNEL_MASK; + CONVERT_CHECKED(audioChannelMaskToHal(config.base.channelMask, &halConfig->channel_mask), + result); + } + if (!config.base.format.empty()) { + halConfig->config_mask |= AUDIO_PORT_CONFIG_FORMAT; + CONVERT_CHECKED(audioFormatToHal(config.base.format, &halConfig->format), result); + } + if (config.gain.getDiscriminator() == + AudioPortConfig::OptionalGain::hidl_discriminator::config) { + halConfig->config_mask |= AUDIO_PORT_CONFIG_GAIN; + CONVERT_CHECKED(audioGainConfigToHal(config.gain.config(), &halConfig->gain), result); + } + CONVERT_CHECKED(audioPortExtendedInfoToHal(config.ext, &halConfig->role, &halConfig->type, + &halConfig->ext.device, &halConfig->ext.mix, + &halConfig->ext.session), + result); + return result; +} + +status_t HidlUtils::audioPortExtendedInfoFromHal( + audio_port_role_t role, audio_port_type_t type, + const struct audio_port_config_device_ext& device, + const struct audio_port_config_mix_ext& mix, + const struct audio_port_config_session_ext& session, AudioPortExtendedInfo* ext, + bool* isInput) { + status_t result = NO_ERROR; + *isInput = false; + switch (type) { + case AUDIO_PORT_TYPE_NONE: + ext->unspecified({}); + break; + case AUDIO_PORT_TYPE_DEVICE: { + *isInput = role == AUDIO_PORT_ROLE_SOURCE; + ext->device({}); + CONVERT_CHECKED(deviceAddressFromHal(device.type, device.address, &ext->device()), + result); + break; + } + case AUDIO_PORT_TYPE_MIX: { + *isInput = role == AUDIO_PORT_ROLE_SINK; + ext->mix({}); + ext->mix().ioHandle = mix.handle; + if (role == AUDIO_PORT_ROLE_SOURCE) { + ext->mix().useCase.stream({}); + CONVERT_CHECKED( + audioStreamTypeFromHal(mix.usecase.stream, &ext->mix().useCase.stream()), + result); + } else if (role == AUDIO_PORT_ROLE_SINK) { + ext->mix().useCase.source({}); + CONVERT_CHECKED( + audioSourceFromHal(mix.usecase.source, &ext->mix().useCase.source()), + result); + } + break; + } + case AUDIO_PORT_TYPE_SESSION: { + ext->session(session.session); + break; + } + } + return result; +} + +status_t HidlUtils::audioPortExtendedInfoToHal(const AudioPortExtendedInfo& ext, + audio_port_role_t* role, audio_port_type_t* type, + struct audio_port_config_device_ext* device, + struct audio_port_config_mix_ext* mix, + struct audio_port_config_session_ext* session) { + status_t result = NO_ERROR; + switch (ext.getDiscriminator()) { + case AudioPortExtendedInfo::hidl_discriminator::unspecified: + *role = AUDIO_PORT_ROLE_NONE; + *type = AUDIO_PORT_TYPE_NONE; + break; + case AudioPortExtendedInfo::hidl_discriminator::device: + *role = xsd::isOutputDevice(ext.device().deviceType) ? AUDIO_PORT_ROLE_SINK + : AUDIO_PORT_ROLE_SOURCE; + *type = AUDIO_PORT_TYPE_DEVICE; + CONVERT_CHECKED(deviceAddressToHal(ext.device(), &device->type, device->address), + result); + break; + case AudioPortExtendedInfo::hidl_discriminator::mix: + *type = AUDIO_PORT_TYPE_MIX; + switch (ext.mix().useCase.getDiscriminator()) { + case AudioPortExtendedInfo::AudioPortMixExt::UseCase::hidl_discriminator::stream: + *role = AUDIO_PORT_ROLE_SOURCE; + CONVERT_CHECKED( + audioStreamTypeToHal(ext.mix().useCase.stream(), &mix->usecase.stream), + result); + break; + case AudioPortExtendedInfo::AudioPortMixExt::UseCase::hidl_discriminator::source: + *role = AUDIO_PORT_ROLE_SINK; + CONVERT_CHECKED( + audioSourceToHal(ext.mix().useCase.source(), &mix->usecase.source), + result); + break; + } + mix->handle = ext.mix().ioHandle; + break; + case AudioPortExtendedInfo::hidl_discriminator::session: + *role = AUDIO_PORT_ROLE_NONE; + *type = AUDIO_PORT_TYPE_SESSION; + session->session = static_cast(ext.session()); + break; + } + return result; +} + +status_t HidlUtils::audioPortFromHal(const struct audio_port& halPort, AudioPort* port) { + struct audio_port_v7 halPortV7 = {}; + audio_populate_audio_port_v7(&halPort, &halPortV7); + return audioPortFromHal(halPortV7, port); +} + +status_t HidlUtils::audioPortToHal(const AudioPort& port, struct audio_port* halPort) { + status_t result = NO_ERROR; + struct audio_port_v7 halPortV7 = {}; + CONVERT_CHECKED(audioPortToHal(port, &halPortV7), result); + if (!audio_populate_audio_port(&halPortV7, halPort)) { + result = BAD_VALUE; + } + return result; +} + +status_t HidlUtils::audioPortFromHal(const struct audio_port_v7& halPort, AudioPort* port) { + status_t result = NO_ERROR; + bool isInput = false; + port->id = halPort.id; + port->name.setToExternal(halPort.name, strlen(halPort.name)); + // HAL uses slightly different but convertible structures for the extended info in port + // and port config structures. + struct audio_port_config_device_ext halDevice = {}; + struct audio_port_config_mix_ext halMix = {}; + struct audio_port_config_session_ext halSession = {}; + switch (halPort.type) { + case AUDIO_PORT_TYPE_NONE: + break; + case AUDIO_PORT_TYPE_DEVICE: + halDevice.type = halPort.ext.device.type; + memcpy(halDevice.address, halPort.ext.device.address, AUDIO_DEVICE_MAX_ADDRESS_LEN); + break; + case AUDIO_PORT_TYPE_MIX: + halMix.handle = halPort.ext.mix.handle; + break; + case AUDIO_PORT_TYPE_SESSION: + halSession.session = halPort.ext.session.session; + break; + } + CONVERT_CHECKED(audioPortExtendedInfoFromHal(halPort.role, halPort.type, halDevice, halMix, + halSession, &port->ext, &isInput), + result); + port->profiles.resize(halPort.num_audio_profiles); + for (size_t i = 0; i < halPort.num_audio_profiles; ++i) { + CONVERT_CHECKED(audioProfileFromHal(halPort.audio_profiles[i], isInput, &port->profiles[i]), + result); + } + port->gains.resize(halPort.num_gains); + for (size_t i = 0; i < halPort.num_gains; ++i) { + CONVERT_CHECKED(audioGainFromHal(halPort.gains[i], isInput, &port->gains[i]), result); + } + CONVERT_CHECKED(audioPortConfigFromHal(halPort.active_config, &port->activeConfig), result); + return result; +} + +status_t HidlUtils::audioPortToHal(const AudioPort& port, struct audio_port_v7* halPort) { + status_t result = NO_ERROR; + halPort->id = port.id; + strncpy(halPort->name, port.name.c_str(), AUDIO_PORT_MAX_NAME_LEN); + halPort->name[AUDIO_PORT_MAX_NAME_LEN - 1] = '\0'; + if (port.name.size() >= AUDIO_PORT_MAX_NAME_LEN) { + ALOGE("HIDL Audio Port name is too long: %zu", port.name.size()); + result = BAD_VALUE; + } + halPort->num_audio_profiles = port.profiles.size(); + if (halPort->num_audio_profiles > AUDIO_PORT_MAX_AUDIO_PROFILES) { + ALOGE("HIDL Audio Port has too many profiles: %u", halPort->num_audio_profiles); + halPort->num_audio_profiles = AUDIO_PORT_MAX_AUDIO_PROFILES; + result = BAD_VALUE; + } + for (size_t i = 0; i < halPort->num_audio_profiles; ++i) { + CONVERT_CHECKED(audioProfileToHal(port.profiles[i], &halPort->audio_profiles[i]), result); + } + halPort->num_gains = port.gains.size(); + if (halPort->num_gains > AUDIO_PORT_MAX_GAINS) { + ALOGE("HIDL Audio Port has too many gains: %u", halPort->num_gains); + halPort->num_gains = AUDIO_PORT_MAX_GAINS; + result = BAD_VALUE; + } + for (size_t i = 0; i < halPort->num_gains; ++i) { + CONVERT_CHECKED(audioGainToHal(port.gains[i], &halPort->gains[i]), result); + } + // HAL uses slightly different but convertible structures for the extended info in port + // and port config structures. + struct audio_port_config_device_ext halDevice = {}; + struct audio_port_config_mix_ext halMix = {}; + struct audio_port_config_session_ext halSession = {}; + CONVERT_CHECKED(audioPortExtendedInfoToHal(port.ext, &halPort->role, &halPort->type, &halDevice, + &halMix, &halSession), + result); + switch (halPort->type) { + case AUDIO_PORT_TYPE_NONE: + break; + case AUDIO_PORT_TYPE_DEVICE: + halPort->ext.device.type = halDevice.type; + memcpy(halPort->ext.device.address, halDevice.address, AUDIO_DEVICE_MAX_ADDRESS_LEN); + break; + case AUDIO_PORT_TYPE_MIX: + halPort->ext.mix.handle = halMix.handle; + break; + case AUDIO_PORT_TYPE_SESSION: + halPort->ext.session.session = halSession.session; + break; + } + CONVERT_CHECKED(audioPortConfigToHal(port.activeConfig, &halPort->active_config), result); + return result; +} + +status_t HidlUtils::audioProfileFromHal(const struct audio_profile& halProfile, bool isInput, + AudioProfile* profile) { + status_t result = NO_ERROR; + CONVERT_CHECKED(audioFormatFromHal(halProfile.format, &profile->format), result); + profile->sampleRates.resize(halProfile.num_sample_rates); + for (size_t i = 0; i < halProfile.num_sample_rates; ++i) { + profile->sampleRates[i] = halProfile.sample_rates[i]; + } + profile->channelMasks.resize(halProfile.num_channel_masks); + for (size_t i = 0; i < halProfile.num_channel_masks; ++i) { + CONVERT_CHECKED(audioChannelMaskFromHal(halProfile.channel_masks[i], isInput, + &profile->channelMasks[i]), + result); + } + return result; +} + +status_t HidlUtils::audioProfileToHal(const AudioProfile& profile, + struct audio_profile* halProfile) { + status_t result = NO_ERROR; + CONVERT_CHECKED(audioFormatToHal(profile.format, &halProfile->format), result); + memset(halProfile->sample_rates, 0, sizeof(halProfile->sample_rates)); + halProfile->num_sample_rates = profile.sampleRates.size(); + if (halProfile->num_sample_rates > AUDIO_PORT_MAX_SAMPLING_RATES) { + ALOGE("HIDL Audio profile has too many sample rates: %u", halProfile->num_sample_rates); + halProfile->num_sample_rates = AUDIO_PORT_MAX_SAMPLING_RATES; + result = BAD_VALUE; + } + for (size_t i = 0; i < halProfile->num_sample_rates; ++i) { + halProfile->sample_rates[i] = profile.sampleRates[i]; + } + memset(halProfile->channel_masks, 0, sizeof(halProfile->channel_masks)); + halProfile->num_channel_masks = profile.channelMasks.size(); + if (halProfile->num_channel_masks > AUDIO_PORT_MAX_CHANNEL_MASKS) { + ALOGE("HIDL Audio profile has too many channel masks: %u", halProfile->num_channel_masks); + halProfile->num_channel_masks = AUDIO_PORT_MAX_CHANNEL_MASKS; + result = BAD_VALUE; + } + for (size_t i = 0; i < halProfile->num_channel_masks; ++i) { + CONVERT_CHECKED( + audioChannelMaskToHal(profile.channelMasks[i], &halProfile->channel_masks[i]), + status); + } + return result; +} + +status_t HidlUtils::deviceAddressFromHal(audio_devices_t halDeviceType, + const char* halDeviceAddress, DeviceAddress* device) { + status_t result = NO_ERROR; + CONVERT_CHECKED(audioDeviceTypeFromHal(halDeviceType, &device->deviceType), result); + if (audio_is_a2dp_out_device(halDeviceType) || audio_is_a2dp_in_device(halDeviceType)) { + device->address.mac({}); + if (halDeviceAddress != nullptr) { + auto& mac = device->address.mac(); + int status = sscanf(halDeviceAddress, "%hhX:%hhX:%hhX:%hhX:%hhX:%hhX", &mac[0], &mac[1], + &mac[2], &mac[3], &mac[4], &mac[5]); + if (status != 6) { + ALOGE("BT A2DP device \"%s\" MAC address \"%s\" is invalid", + device->deviceType.c_str(), halDeviceAddress); + result = BAD_VALUE; + } + } else { + ALOGE("BT A2DP device \"%s\" does not have a MAC address", halDeviceAddress); + result = BAD_VALUE; + } + } else if (halDeviceType == AUDIO_DEVICE_OUT_IP || halDeviceType == AUDIO_DEVICE_IN_IP) { + device->address.ipv4({}); + if (halDeviceAddress != nullptr) { + auto& ipv4 = device->address.ipv4(); + int status = sscanf(halDeviceAddress, "%hhu.%hhu.%hhu.%hhu", &ipv4[0], &ipv4[1], + &ipv4[2], &ipv4[3]); + if (status != 4) { + ALOGE("IP device \"%s\" IPv4 address \"%s\" is invalid", device->deviceType.c_str(), + halDeviceAddress); + result = BAD_VALUE; + } + } else { + ALOGE("IP device \"%s\" does not have an IPv4 address", device->deviceType.c_str()); + result = BAD_VALUE; + } + } else if (audio_is_usb_out_device(halDeviceType) || audio_is_usb_in_device(halDeviceType)) { + device->address.alsa({}); + if (halDeviceAddress != nullptr) { + auto& alsa = device->address.alsa(); + int status = sscanf(halDeviceAddress, "card=%d;device=%d", &alsa.card, &alsa.device); + if (status != 2) { + ALOGE("USB device \"%s\" ALSA address \"%s\" is invalid", + device->deviceType.c_str(), halDeviceAddress); + result = BAD_VALUE; + } + } else { + ALOGE("USB device \"%s\" does not have ALSA address", device->deviceType.c_str()); + result = BAD_VALUE; + } + } else { + // Any other device type uses the 'id' field. + device->address.id(halDeviceAddress != nullptr ? halDeviceAddress : ""); + } + return result; +} + +status_t HidlUtils::deviceAddressToHal(const DeviceAddress& device, audio_devices_t* halDeviceType, + char* halDeviceAddress) { + status_t result = NO_ERROR; + CONVERT_CHECKED(audioDeviceTypeToHal(device.deviceType, halDeviceType), result); + memset(halDeviceAddress, 0, AUDIO_DEVICE_MAX_ADDRESS_LEN); + if (audio_is_a2dp_out_device(*halDeviceType) || audio_is_a2dp_in_device(*halDeviceType)) { + if (device.address.getDiscriminator() == DeviceAddress::Address::hidl_discriminator::mac) { + const auto& mac = device.address.mac(); + snprintf(halDeviceAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN, + "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], + mac[5]); + } else { + ALOGE("BT A2DP device \"%s\" does not have MAC address set", device.deviceType.c_str()); + result = BAD_VALUE; + } + } else if (*halDeviceType == AUDIO_DEVICE_OUT_IP || *halDeviceType == AUDIO_DEVICE_IN_IP) { + if (device.address.getDiscriminator() == DeviceAddress::Address::hidl_discriminator::ipv4) { + const auto& ipv4 = device.address.ipv4(); + snprintf(halDeviceAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN, "%d.%d.%d.%d", ipv4[0], + ipv4[1], ipv4[2], ipv4[3]); + } else { + ALOGE("IP device \"%s\" does not have IPv4 address set", device.deviceType.c_str()); + result = BAD_VALUE; + } + } else if (audio_is_usb_out_device(*halDeviceType) || audio_is_usb_in_device(*halDeviceType)) { + if (device.address.getDiscriminator() == DeviceAddress::Address::hidl_discriminator::alsa) { + const auto& alsa = device.address.alsa(); + snprintf(halDeviceAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN, "card=%d;device=%d", alsa.card, + alsa.device); + } else { + ALOGE("USB device \"%s\" does not have ALSA address set", device.deviceType.c_str()); + result = BAD_VALUE; + } + } else { + // Any other device type uses the 'id' field. + if (device.address.getDiscriminator() == DeviceAddress::Address::hidl_discriminator::id) { + snprintf(halDeviceAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN, "%s", + device.address.id().c_str()); + } + } + return result; +} + +} // namespace implementation +} // namespace CPP_VERSION +} // namespace common +} // namespace audio +} // namespace hardware +} // namespace android diff --git a/audio/common/all-versions/default/Android.bp b/audio/common/all-versions/default/Android.bp index afaa7bb41a..b83a58a3ec 100644 --- a/audio/common/all-versions/default/Android.bp +++ b/audio/common/all-versions/default/Android.bp @@ -39,15 +39,19 @@ cc_library_shared { ], } +filegroup { + name: "android.hardware.audio.common-util@2-6", + srcs: [ + "HidlUtils.cpp", + "UuidUtils.cpp", + ], +} + cc_defaults { name: "android.hardware.audio.common-util_default", defaults: ["hidl_defaults"], vendor_available: true, - srcs: [ - "HidlUtils.cpp", - "UuidUtils.cpp", - ], export_include_dirs: ["."], @@ -70,6 +74,7 @@ cc_defaults { cc_library_shared { name: "android.hardware.audio.common@2.0-util", defaults: ["android.hardware.audio.common-util_default"], + srcs: [":android.hardware.audio.common-util@2-6"], shared_libs: [ "android.hardware.audio.common@2.0", ], @@ -83,6 +88,7 @@ cc_library_shared { cc_library_shared { name: "android.hardware.audio.common@4.0-util", defaults: ["android.hardware.audio.common-util_default"], + srcs: [":android.hardware.audio.common-util@2-6"], shared_libs: [ "android.hardware.audio.common@4.0", ], @@ -96,6 +102,7 @@ cc_library_shared { cc_library_shared { name: "android.hardware.audio.common@5.0-util", defaults: ["android.hardware.audio.common-util_default"], + srcs: [":android.hardware.audio.common-util@2-6"], shared_libs: [ "android.hardware.audio.common@5.0", ], @@ -109,6 +116,7 @@ cc_library_shared { cc_library_shared { name: "android.hardware.audio.common@6.0-util", defaults: ["android.hardware.audio.common-util_default"], + srcs: [":android.hardware.audio.common-util@2-6"], shared_libs: [ "android.hardware.audio.common@6.0", ], @@ -119,12 +127,18 @@ cc_library_shared { ], } -cc_library_shared { - enabled: false, +cc_library { name: "android.hardware.audio.common@7.0-util", defaults: ["android.hardware.audio.common-util_default"], + srcs: [ + "7.0/HidlUtils.cpp", + "UuidUtils.cpp", + ], shared_libs: [ "android.hardware.audio.common@7.0", + "android.hardware.audio.common@7.0-enums", + "libbase", + "libxml2", ], cflags: [ "-DMAJOR_VERSION=7", @@ -132,3 +146,35 @@ cc_library_shared { "-include common/all-versions/VersionMacro.h", ], } + +// Note: this isn't a VTS test, but rather a unit test +// to verify correctness of conversion utilities. +cc_test { + name: "android.hardware.audio.common@7.0-util_tests", + defaults: ["android.hardware.audio.common-util_default"], + + srcs: ["tests/hidlutils_tests.cpp"], + + // Use static linking to allow running in presubmit on + // targets that don't have HAL V7. + static_libs: [ + "android.hardware.audio.common@7.0-enums", + "android.hardware.audio.common@7.0-util", + "android.hardware.audio.common@7.0", + ], + + shared_libs: [ + "libbase", + "libxml2", + ], + + cflags: [ + "-Werror", + "-Wall", + "-DMAJOR_VERSION=7", + "-DMINOR_VERSION=0", + "-include common/all-versions/VersionMacro.h", + ], + + test_suites: ["device-tests"], +} diff --git a/audio/common/all-versions/default/HidlUtils.cpp b/audio/common/all-versions/default/HidlUtils.cpp index 7530d050ff..ab3c1c7b33 100644 --- a/audio/common/all-versions/default/HidlUtils.cpp +++ b/audio/common/all-versions/default/HidlUtils.cpp @@ -37,13 +37,14 @@ status_t HidlUtils::audioConfigFromHal(const audio_config_t& halConfig, AudioCon return status; } -void HidlUtils::audioConfigToHal(const AudioConfig& config, audio_config_t* halConfig) { +status_t HidlUtils::audioConfigToHal(const AudioConfig& config, audio_config_t* halConfig) { memset(halConfig, 0, sizeof(audio_config_t)); halConfig->sample_rate = config.sampleRateHz; halConfig->channel_mask = static_cast(config.channelMask); halConfig->format = static_cast(config.format); audioOffloadInfoToHal(config.offloadInfo, &halConfig->offload_info); halConfig->frame_count = config.frameCount; + return NO_ERROR; } void HidlUtils::audioGainConfigFromHal(const struct audio_gain_config& halConfig, @@ -57,8 +58,8 @@ void HidlUtils::audioGainConfigFromHal(const struct audio_gain_config& halConfig config->rampDurationMs = halConfig.ramp_duration_ms; } -void HidlUtils::audioGainConfigToHal(const AudioGainConfig& config, - struct audio_gain_config* halConfig) { +status_t HidlUtils::audioGainConfigToHal(const AudioGainConfig& config, + struct audio_gain_config* halConfig) { halConfig->index = config.index; halConfig->mode = static_cast(config.mode); halConfig->channel_mask = static_cast(config.channelMask); @@ -67,6 +68,7 @@ void HidlUtils::audioGainConfigToHal(const AudioGainConfig& config, halConfig->values[i] = config.values[i]; } halConfig->ramp_duration_ms = config.rampDurationMs; + return NO_ERROR; } void HidlUtils::audioGainFromHal(const struct audio_gain& halGain, AudioGain* gain) { @@ -80,7 +82,7 @@ void HidlUtils::audioGainFromHal(const struct audio_gain& halGain, AudioGain* ga gain->maxRampMs = halGain.max_ramp_ms; } -void HidlUtils::audioGainToHal(const AudioGain& gain, struct audio_gain* halGain) { +status_t HidlUtils::audioGainToHal(const AudioGain& gain, struct audio_gain* halGain) { halGain->mode = static_cast(gain.mode); halGain->channel_mask = static_cast(gain.channelMask); halGain->min_value = gain.minValue; @@ -89,22 +91,26 @@ void HidlUtils::audioGainToHal(const AudioGain& gain, struct audio_gain* halGain halGain->step_value = gain.stepValue; halGain->min_ramp_ms = gain.minRampMs; halGain->max_ramp_ms = gain.maxRampMs; + return NO_ERROR; } -AudioUsage HidlUtils::audioUsageFromHal(const audio_usage_t halUsage) { +status_t HidlUtils::audioUsageFromHal(audio_usage_t halUsage, AudioUsage* usage) { switch (halUsage) { case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST: case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT: case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED: case AUDIO_USAGE_NOTIFICATION_EVENT: - return AudioUsage::NOTIFICATION; + *usage = AudioUsage::NOTIFICATION; + break; default: - return static_cast(halUsage); + *usage = static_cast(halUsage); } + return NO_ERROR; } -audio_usage_t HidlUtils::audioUsageToHal(const AudioUsage usage) { - return static_cast(usage); +status_t HidlUtils::audioUsageToHal(const AudioUsage& usage, audio_usage_t* halUsage) { + *halUsage = static_cast(usage); + return NO_ERROR; } status_t HidlUtils::audioOffloadInfoFromHal(const audio_offload_info_t& halOffload, @@ -119,7 +125,7 @@ status_t HidlUtils::audioOffloadInfoFromHal(const audio_offload_info_t& halOfflo offload->isStreaming = halOffload.is_streaming; offload->bitWidth = halOffload.bit_width; offload->bufferSize = halOffload.offload_buffer_size; - offload->usage = audioUsageFromHal(halOffload.usage); + audioUsageFromHal(halOffload.usage, &offload->usage); #if MAJOR_VERSION >= 6 if (halOffload.version >= AUDIO_OFFLOAD_INFO_VERSION_0_2) { offload->encapsulationMode = @@ -139,11 +145,11 @@ status_t HidlUtils::audioOffloadInfoFromHal(const audio_offload_info_t& halOfflo return BAD_VALUE; } #endif - return OK; + return NO_ERROR; } -void HidlUtils::audioOffloadInfoToHal(const AudioOffloadInfo& offload, - audio_offload_info_t* halOffload) { +status_t HidlUtils::audioOffloadInfoToHal(const AudioOffloadInfo& offload, + audio_offload_info_t* halOffload) { *halOffload = AUDIO_INFO_INITIALIZER; halOffload->sample_rate = offload.sampleRateHz; halOffload->channel_mask = static_cast(offload.channelMask); @@ -155,7 +161,7 @@ void HidlUtils::audioOffloadInfoToHal(const AudioOffloadInfo& offload, halOffload->is_streaming = offload.isStreaming; halOffload->bit_width = offload.bitWidth; halOffload->offload_buffer_size = offload.bufferSize; - halOffload->usage = audioUsageToHal(offload.usage); + audioUsageToHal(offload.usage, &halOffload->usage); #if MAJOR_VERSION >= 6 halOffload->encapsulation_mode = static_cast(offload.encapsulationMode); @@ -164,10 +170,11 @@ void HidlUtils::audioOffloadInfoToHal(const AudioOffloadInfo& offload, #else // offload doesn't contain encapsulationMode, contentId, syncId, so this is OK. #endif + return NO_ERROR; } -void HidlUtils::audioPortConfigFromHal(const struct audio_port_config& halConfig, - AudioPortConfig* config) { +status_t HidlUtils::audioPortConfigFromHal(const struct audio_port_config& halConfig, + AudioPortConfig* config) { config->id = halConfig.id; config->role = AudioPortRole(halConfig.role); config->type = AudioPortType(halConfig.type); @@ -201,10 +208,11 @@ void HidlUtils::audioPortConfigFromHal(const struct audio_port_config& halConfig break; } } + return NO_ERROR; } -void HidlUtils::audioPortConfigToHal(const AudioPortConfig& config, - struct audio_port_config* halConfig) { +status_t HidlUtils::audioPortConfigToHal(const AudioPortConfig& config, + struct audio_port_config* halConfig) { memset(halConfig, 0, sizeof(audio_port_config)); halConfig->id = config.id; halConfig->role = static_cast(config.role); @@ -242,27 +250,10 @@ void HidlUtils::audioPortConfigToHal(const AudioPortConfig& config, break; } } + return NO_ERROR; } -void HidlUtils::audioPortConfigsFromHal(unsigned int numHalConfigs, - const struct audio_port_config* halConfigs, - hidl_vec* configs) { - configs->resize(numHalConfigs); - for (unsigned int i = 0; i < numHalConfigs; ++i) { - audioPortConfigFromHal(halConfigs[i], &(*configs)[i]); - } -} - -std::unique_ptr HidlUtils::audioPortConfigsToHal( - const hidl_vec& configs) { - std::unique_ptr halConfigs(new audio_port_config[configs.size()]); - for (size_t i = 0; i < configs.size(); ++i) { - audioPortConfigToHal(configs[i], &halConfigs[i]); - } - return halConfigs; -} - -void HidlUtils::audioPortFromHal(const struct audio_port& halPort, AudioPort* port) { +status_t HidlUtils::audioPortFromHal(const struct audio_port& halPort, AudioPort* port) { port->id = halPort.id; port->role = AudioPortRole(halPort.role); port->type = AudioPortType(halPort.type); @@ -305,9 +296,10 @@ void HidlUtils::audioPortFromHal(const struct audio_port& halPort, AudioPort* po break; } } + return NO_ERROR; } -void HidlUtils::audioPortToHal(const AudioPort& port, struct audio_port* halPort) { +status_t HidlUtils::audioPortToHal(const AudioPort& port, struct audio_port* halPort) { memset(halPort, 0, sizeof(audio_port)); halPort->id = port.id; halPort->role = static_cast(port.role); @@ -356,6 +348,7 @@ void HidlUtils::audioPortToHal(const AudioPort& port, struct audio_port* halPort break; } } + return NO_ERROR; } } // namespace implementation diff --git a/audio/common/all-versions/default/HidlUtils.h b/audio/common/all-versions/default/HidlUtils.h index 20fddef1ab..4e609ca4fd 100644 --- a/audio/common/all-versions/default/HidlUtils.h +++ b/audio/common/all-versions/default/HidlUtils.h @@ -34,38 +34,123 @@ namespace implementation { using namespace ::android::hardware::audio::common::CPP_VERSION; -class HidlUtils { - public: - // A failure here indicates a platform config that is incompatible with - // the compiled HIDL interface version. +struct HidlUtils { +#if MAJOR_VERSION < 7 static status_t audioConfigFromHal(const audio_config_t& halConfig, AudioConfig* config); - - static void audioConfigToHal(const AudioConfig& config, audio_config_t* halConfig); static void audioGainConfigFromHal(const struct audio_gain_config& halConfig, AudioGainConfig* config); - static void audioGainConfigToHal(const AudioGainConfig& config, - struct audio_gain_config* halConfig); static void audioGainFromHal(const struct audio_gain& halGain, AudioGain* gain); - static void audioGainToHal(const AudioGain& gain, struct audio_gain* halGain); - static AudioUsage audioUsageFromHal(const audio_usage_t halUsage); - static audio_usage_t audioUsageToHal(const AudioUsage usage); - // A failure here indicates a platform offload info that is incompatible with - // the compiled HIDL interface version. +#else + static status_t audioConfigFromHal(const audio_config_t& halConfig, bool isInput, + AudioConfig* config); + static status_t audioGainConfigFromHal(const struct audio_gain_config& halConfig, bool isInput, + AudioGainConfig* config); + static status_t audioGainFromHal(const struct audio_gain& halGain, bool isInput, + AudioGain* gain); +#endif + static status_t audioConfigToHal(const AudioConfig& config, audio_config_t* halConfig); + static status_t audioGainConfigToHal(const AudioGainConfig& config, + struct audio_gain_config* halConfig); + static status_t audioGainToHal(const AudioGain& gain, struct audio_gain* halGain); + static status_t audioUsageFromHal(audio_usage_t halUsage, AudioUsage* usage); + static status_t audioUsageToHal(const AudioUsage& usage, audio_usage_t* halUsage); static status_t audioOffloadInfoFromHal(const audio_offload_info_t& halOffload, AudioOffloadInfo* offload); - static void audioOffloadInfoToHal(const AudioOffloadInfo& offload, - audio_offload_info_t* halOffload); - static void audioPortConfigFromHal(const struct audio_port_config& halConfig, - AudioPortConfig* config); - static void audioPortConfigToHal(const AudioPortConfig& config, - struct audio_port_config* halConfig); - static void audioPortConfigsFromHal(unsigned int numHalConfigs, - const struct audio_port_config* halConfigs, - hidl_vec* configs); + static status_t audioOffloadInfoToHal(const AudioOffloadInfo& offload, + audio_offload_info_t* halOffload); + static status_t audioPortConfigFromHal(const struct audio_port_config& halConfig, + AudioPortConfig* config); + static status_t audioPortConfigToHal(const AudioPortConfig& config, + struct audio_port_config* halConfig); + static status_t audioPortConfigsFromHal(unsigned int numHalConfigs, + const struct audio_port_config* halConfigs, + hidl_vec* configs) { + status_t result = NO_ERROR; + configs->resize(numHalConfigs); + for (unsigned int i = 0; i < numHalConfigs; ++i) { + if (status_t status = audioPortConfigFromHal(halConfigs[i], &(*configs)[i]); + status != NO_ERROR) { + result = status; + } + } + return result; + } + static status_t audioPortConfigsToHal(const hidl_vec& configs, + std::unique_ptr* halConfigs) { + status_t result = NO_ERROR; + halConfigs->reset(new audio_port_config[configs.size()]); + for (size_t i = 0; i < configs.size(); ++i) { + if (status_t status = audioPortConfigToHal(configs[i], &(*halConfigs)[i]); + status != NO_ERROR) { + result = status; + } + } + return result; + } + + // PLEASE DO NOT USE, will be removed in a couple of days static std::unique_ptr audioPortConfigsToHal( - const hidl_vec& configs); - static void audioPortFromHal(const struct audio_port& halPort, AudioPort* port); - static void audioPortToHal(const AudioPort& port, struct audio_port* halPort); + const hidl_vec& configs) { + std::unique_ptr halConfigs; + (void)audioPortConfigsToHal(configs, &halConfigs); + return halConfigs; + } + + static status_t audioPortFromHal(const struct audio_port& halPort, AudioPort* port); + static status_t audioPortToHal(const AudioPort& port, struct audio_port* halPort); +#if MAJOR_VERSION >= 7 + static status_t audioChannelMaskFromHal(audio_channel_mask_t halChannelMask, bool isInput, + AudioChannelMask* channelMask); + static status_t audioChannelMaskToHal(const AudioChannelMask& channelMask, + audio_channel_mask_t* halChannelMask); + static status_t audioConfigBaseFromHal(const audio_config_base_t& halConfigBase, bool isInput, + AudioConfigBase* configBase); + static status_t audioConfigBaseToHal(const AudioConfigBase& configBase, + audio_config_base_t* halConfigBase); + static status_t audioDeviceTypeFromHal(audio_devices_t halDevice, AudioDevice* device); + static status_t audioDeviceTypeToHal(const AudioDevice& device, audio_devices_t* halDevice); + static status_t audioFormatFromHal(audio_format_t halFormat, AudioFormat* format); + static status_t audioFormatToHal(const AudioFormat& format, audio_format_t* halFormat); + static status_t audioGainModeMaskFromHal(audio_gain_mode_t halGainModeMask, + hidl_vec* gainModeMask); + static status_t audioGainModeMaskToHal(const hidl_vec& gainModeMask, + audio_gain_mode_t* halGainModeMask); + static status_t audioPortFromHal(const struct audio_port_v7& halPort, AudioPort* port); + static status_t audioPortToHal(const AudioPort& port, struct audio_port_v7* halPort); + static status_t audioProfileFromHal(const struct audio_profile& halProfile, bool isInput, + AudioProfile* profile); + static status_t audioProfileToHal(const AudioProfile& profile, + struct audio_profile* halProfile); + static status_t audioSourceFromHal(audio_source_t halSource, AudioSource* source); + static status_t audioSourceToHal(const AudioSource& source, audio_source_t* halSource); + static status_t audioStreamTypeFromHal(audio_stream_type_t halStreamType, + AudioStreamType* streamType); + static status_t audioStreamTypeToHal(const AudioStreamType& streamType, + audio_stream_type_t* halStreamType); + static status_t deviceAddressToHal(const DeviceAddress& device, audio_devices_t* halDeviceType, + char* halDeviceAddress); + static status_t deviceAddressFromHal(audio_devices_t halDeviceType, + const char* halDeviceAddress, DeviceAddress* device); + + private: + static status_t audioIndexChannelMaskFromHal(audio_channel_mask_t halChannelMask, + AudioChannelMask* channelMask); + static status_t audioInputChannelMaskFromHal(audio_channel_mask_t halChannelMask, + AudioChannelMask* channelMask); + static status_t audioOutputChannelMaskFromHal(audio_channel_mask_t halChannelMask, + AudioChannelMask* channelMask); + static status_t audioPortExtendedInfoFromHal( + audio_port_role_t role, audio_port_type_t type, + const struct audio_port_config_device_ext& device, + const struct audio_port_config_mix_ext& mix, + const struct audio_port_config_session_ext& session, AudioPortExtendedInfo* ext, + bool* isInput); + static status_t audioPortExtendedInfoToHal(const AudioPortExtendedInfo& ext, + audio_port_role_t* role, audio_port_type_t* type, + struct audio_port_config_device_ext* device, + struct audio_port_config_mix_ext* mix, + struct audio_port_config_session_ext* session); +#endif }; } // namespace implementation diff --git a/audio/common/all-versions/default/TEST_MAPPING b/audio/common/all-versions/default/TEST_MAPPING new file mode 100644 index 0000000000..4316ccf4f5 --- /dev/null +++ b/audio/common/all-versions/default/TEST_MAPPING @@ -0,0 +1,7 @@ +{ + "presubmit": [ + { + "name": "android.hardware.audio.common@7.0-util_tests" + } + ] +} diff --git a/audio/common/all-versions/default/tests/hidlutils_tests.cpp b/audio/common/all-versions/default/tests/hidlutils_tests.cpp new file mode 100644 index 0000000000..bfc99e6b48 --- /dev/null +++ b/audio/common/all-versions/default/tests/hidlutils_tests.cpp @@ -0,0 +1,631 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include + +#define LOG_TAG "HidlUtils_Test" +#include + +#include +#include +#include +#include + +using namespace android; +using namespace ::android::hardware::audio::common::CPP_VERSION; +using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils; +namespace xsd { +using namespace ::android::audio::policy::configuration::V7_0; +} + +static constexpr audio_channel_mask_t kInvalidHalChannelMask = + static_cast(0xFFFFFFFFU); +static constexpr audio_devices_t kInvalidHalDevice = static_cast(0xFFFFFFFFU); +static constexpr audio_format_t kInvalidHalFormat = static_cast(0xFFFFFFFFU); +static constexpr audio_gain_mode_t kInvalidHalGainMode = + static_cast(0xFFFFFFFFU); +static constexpr audio_source_t kInvalidHalSource = static_cast(0xFFFFFFFFU); +static constexpr audio_stream_type_t kInvalidHalStreamType = + static_cast(0xFFFFFFFFU); +static constexpr audio_usage_t kInvalidHalUsage = static_cast(0xFFFFFFFFU); + +TEST(HidlUtils, ConvertInvalidChannelMask) { + AudioChannelMask invalid; + EXPECT_EQ(BAD_VALUE, HidlUtils::audioChannelMaskFromHal(AUDIO_CHANNEL_INVALID, + false /*isInput*/, &invalid)); + EXPECT_EQ(BAD_VALUE, HidlUtils::audioChannelMaskFromHal(AUDIO_CHANNEL_INVALID, true /*isInput*/, + &invalid)); + EXPECT_EQ(BAD_VALUE, HidlUtils::audioChannelMaskFromHal(kInvalidHalChannelMask, + false /*isInput*/, &invalid)); + EXPECT_EQ(BAD_VALUE, HidlUtils::audioChannelMaskFromHal(kInvalidHalChannelMask, + true /*isInput*/, &invalid)); + audio_channel_mask_t halInvalid; + // INVALID channel mask is not in XSD thus it's not allowed for transfer over HIDL. + EXPECT_EQ(BAD_VALUE, HidlUtils::audioChannelMaskToHal("AUDIO_CHANNEL_INVALID", &halInvalid)); + EXPECT_EQ(BAD_VALUE, HidlUtils::audioChannelMaskToHal("random string", &halInvalid)); +} + +// Might move these to the audio_policy_configuration_V7_0-enums library +// if there would be usages in the default wrapper code. In that case, +// it would be better to reimplement these methods using a proper switch statement +// over all known enum values. +static bool isInputChannelMask(xsd::AudioChannelMask channelMask) { + return toString(channelMask).find("_CHANNEL_IN_") != std::string::npos; +} + +static bool isOutputChannelMask(xsd::AudioChannelMask channelMask) { + return toString(channelMask).find("_CHANNEL_OUT_") != std::string::npos; +} + +static bool isIndexChannelMask(xsd::AudioChannelMask channelMask) { + return toString(channelMask).find("_CHANNEL_INDEX_") != std::string::npos; +} + +TEST(HidlUtils, ConvertChannelMask) { + for (const auto enumVal : xsdc_enum_range{}) { + const AudioChannelMask channelMask = toString(enumVal); + audio_channel_mask_t halChannelMask, halChannelMaskBack; + AudioChannelMask channelMaskBack; + EXPECT_EQ(NO_ERROR, HidlUtils::audioChannelMaskToHal(channelMask, &halChannelMask)) + << "Conversion of \"" << channelMask << "\" failed"; + EXPECT_EQ(enumVal != xsd::AudioChannelMask::AUDIO_CHANNEL_NONE, + audio_channel_mask_is_valid(halChannelMask)) + << "Validity of \"" << channelMask << "\" is not as expected"; + if (bool isInput = isInputChannelMask(enumVal); isInput || isOutputChannelMask(enumVal)) { + EXPECT_EQ(NO_ERROR, + HidlUtils::audioChannelMaskFromHal(halChannelMask, isInput, &channelMaskBack)) + << "Conversion of " << (isInput ? "input" : "output") << " channel mask " + << halChannelMask << " failed"; + // Due to aliased values, the result of 'fromHal' might not be the same + // as 'channelMask', thus we need to compare the results of 'toHal' conversion instead. + EXPECT_EQ(NO_ERROR, + HidlUtils::audioChannelMaskToHal(channelMaskBack, &halChannelMaskBack)) + << "Conversion of \"" << channelMaskBack << "\" failed"; + EXPECT_EQ(halChannelMask, halChannelMaskBack); + } else if (isIndexChannelMask(enumVal) || + enumVal == xsd::AudioChannelMask::AUDIO_CHANNEL_NONE) { + // Conversions for indexed masks and "none" must not depend on the provided direction. + EXPECT_EQ(NO_ERROR, HidlUtils::audioChannelMaskFromHal(halChannelMask, true /*isInput*/, + &channelMaskBack)) + << "Conversion of indexed / none channel mask " << halChannelMask + << " failed (as input channel mask)"; + EXPECT_EQ(channelMask, channelMaskBack); + EXPECT_EQ(NO_ERROR, HidlUtils::audioChannelMaskFromHal( + halChannelMask, false /*isInput*/, &channelMaskBack)) + << "Conversion of indexed / none channel mask " << halChannelMask + << " failed (as output channel mask)"; + EXPECT_EQ(channelMask, channelMaskBack); + } else { + FAIL() << "Unrecognized channel mask \"" << channelMask << "\""; + } + } +} + +TEST(HidlUtils, ConvertInvalidConfigBase) { + AudioConfigBase invalid; + EXPECT_EQ(BAD_VALUE, HidlUtils::audioConfigBaseFromHal({.sample_rate = 0, + .channel_mask = kInvalidHalChannelMask, + .format = kInvalidHalFormat}, + false /*isInput*/, &invalid)); + EXPECT_EQ(BAD_VALUE, HidlUtils::audioConfigBaseFromHal({.sample_rate = 0, + .channel_mask = kInvalidHalChannelMask, + .format = kInvalidHalFormat}, + true /*isInput*/, &invalid)); + audio_config_base_t halInvalid; + invalid.sampleRateHz = 0; + invalid.channelMask = "random string"; + invalid.format = "random string"; + EXPECT_EQ(BAD_VALUE, HidlUtils::audioConfigBaseToHal(invalid, &halInvalid)); +} + +TEST(HidlUtils, ConvertConfigBase) { + AudioConfigBase configBase; + configBase.sampleRateHz = 44100; + configBase.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO); + configBase.format = toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT); + audio_config_base_t halConfigBase; + EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigBaseToHal(configBase, &halConfigBase)); + AudioConfigBase configBaseBack; + EXPECT_EQ(NO_ERROR, + HidlUtils::audioConfigBaseFromHal(halConfigBase, false /*isInput*/, &configBaseBack)); + EXPECT_EQ(configBase, configBaseBack); +} + +TEST(HidlUtils, ConvertInvalidDeviceType) { + AudioDevice invalid; + EXPECT_EQ(BAD_VALUE, HidlUtils::audioDeviceTypeFromHal(kInvalidHalDevice, &invalid)); + audio_devices_t halInvalid; + EXPECT_EQ(BAD_VALUE, HidlUtils::audioDeviceTypeToHal("random string", &halInvalid)); +} + +TEST(HidlUtils, ConvertDeviceType) { + for (const auto enumVal : xsdc_enum_range{}) { + const AudioDevice deviceType = toString(enumVal); + audio_devices_t halDeviceType, halDeviceTypeBack; + AudioDevice deviceTypeBack; + EXPECT_EQ(NO_ERROR, HidlUtils::audioDeviceTypeToHal(deviceType, &halDeviceType)) + << "Conversion of \"" << deviceType << "\" failed"; + if (enumVal != xsd::AudioDevice::AUDIO_DEVICE_NONE) { + EXPECT_TRUE(audio_is_input_device(halDeviceType) || + audio_is_output_device(halDeviceType)) + << "Device \"" << deviceType << "\" is neither input, nor output device"; + } else { + EXPECT_FALSE(audio_is_input_device(halDeviceType)); + EXPECT_FALSE(audio_is_output_device(halDeviceType)); + } + EXPECT_EQ(NO_ERROR, HidlUtils::audioDeviceTypeFromHal(halDeviceType, &deviceTypeBack)) + << "Conversion of device type " << halDeviceType << " failed"; + // Due to aliased values, the result of 'fromHal' might not be the same + // as 'deviceType', thus we need to compare the results of 'toHal' conversion instead. + EXPECT_EQ(NO_ERROR, HidlUtils::audioDeviceTypeToHal(deviceTypeBack, &halDeviceTypeBack)) + << "Conversion of \"" << deviceTypeBack << "\" failed"; + EXPECT_EQ(halDeviceType, halDeviceTypeBack); + } +} + +// The enums module is too small to have unit tests on its own. +TEST(HidlUtils, VendorExtension) { + EXPECT_TRUE(xsd::isVendorExtension("VX_GOOGLE_VR_42")); + EXPECT_FALSE(xsd::isVendorExtension("random string")); + EXPECT_FALSE(xsd::isVendorExtension("VX_")); + EXPECT_FALSE(xsd::isVendorExtension("VX_GOOGLE_$$")); +} + +TEST(HidlUtils, ConvertInvalidDeviceAddress) { + DeviceAddress invalid; + EXPECT_EQ(BAD_VALUE, HidlUtils::deviceAddressFromHal(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER, + nullptr, &invalid)); + EXPECT_EQ(BAD_VALUE, HidlUtils::deviceAddressFromHal(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER, + "", &invalid)); + EXPECT_EQ(BAD_VALUE, HidlUtils::deviceAddressFromHal(AUDIO_DEVICE_OUT_IP, nullptr, &invalid)); + EXPECT_EQ(BAD_VALUE, HidlUtils::deviceAddressFromHal(AUDIO_DEVICE_OUT_IP, "", &invalid)); + EXPECT_EQ(BAD_VALUE, + HidlUtils::deviceAddressFromHal(AUDIO_DEVICE_OUT_USB_HEADSET, nullptr, &invalid)); + EXPECT_EQ(BAD_VALUE, + HidlUtils::deviceAddressFromHal(AUDIO_DEVICE_OUT_USB_HEADSET, "", &invalid)); + + audio_devices_t halInvalid; + char halAddress[AUDIO_DEVICE_MAX_ADDRESS_LEN] = {}; + invalid = {}; + invalid.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER); + EXPECT_EQ(BAD_VALUE, HidlUtils::deviceAddressToHal(invalid, &halInvalid, halAddress)); + invalid.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_OUT_IP); + EXPECT_EQ(BAD_VALUE, HidlUtils::deviceAddressToHal(invalid, &halInvalid, halAddress)); + invalid.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_OUT_USB_HEADSET); + EXPECT_EQ(BAD_VALUE, HidlUtils::deviceAddressToHal(invalid, &halInvalid, halAddress)); +} + +static void ConvertDeviceAddress(const DeviceAddress& device) { + audio_devices_t halDeviceType; + char halDeviceAddress[AUDIO_DEVICE_MAX_ADDRESS_LEN] = {}; + EXPECT_EQ(NO_ERROR, HidlUtils::deviceAddressToHal(device, &halDeviceType, halDeviceAddress)); + DeviceAddress deviceBack; + EXPECT_EQ(NO_ERROR, + HidlUtils::deviceAddressFromHal(halDeviceType, halDeviceAddress, &deviceBack)); + EXPECT_EQ(device, deviceBack); +} + +TEST(HidlUtils, ConvertUniqueDeviceAddress) { + DeviceAddress speaker; + speaker.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_OUT_SPEAKER); + ConvertDeviceAddress(speaker); +} + +TEST(HidlUtils, ConvertA2dpDeviceAddress) { + DeviceAddress a2dpSpeaker; + a2dpSpeaker.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER); + a2dpSpeaker.address.mac(std::array{1, 2, 3, 4, 5, 6}); + ConvertDeviceAddress(a2dpSpeaker); +} + +TEST(HidlUtils, ConvertIpv4DeviceAddress) { + DeviceAddress ipv4; + ipv4.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_OUT_IP); + ipv4.address.ipv4(std::array{1, 2, 3, 4}); + ConvertDeviceAddress(ipv4); +} + +TEST(HidlUtils, ConvertUsbDeviceAddress) { + DeviceAddress usbHeadset; + usbHeadset.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_OUT_USB_HEADSET); + usbHeadset.address.alsa({1, 2}); + ConvertDeviceAddress(usbHeadset); +} + +TEST(HidlUtils, ConvertBusDeviceAddress) { + DeviceAddress bus; + bus.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_OUT_BUS); + bus.address.id("bus_device"); + ConvertDeviceAddress(bus); +} + +TEST(HidlUtils, ConvertRSubmixDeviceAddress) { + DeviceAddress rSubmix; + rSubmix.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_OUT_REMOTE_SUBMIX); + rSubmix.address.id(AUDIO_REMOTE_SUBMIX_DEVICE_ADDRESS); + ConvertDeviceAddress(rSubmix); +} + +TEST(HidlUtils, ConvertVendorDeviceAddress) { + // The address part is not mandatory, both cases must work. + { + DeviceAddress vendor; + vendor.deviceType = "VX_GOOGLE_VR"; + audio_devices_t halDeviceType; + char halDeviceAddress[AUDIO_DEVICE_MAX_ADDRESS_LEN] = {}; + // Ignore the result. Vendors will also add the extended device into + // the list of devices in audio-hal-enums.h. Without that, the conversion + // officially fails, but it still maps the device type to NONE. + (void)HidlUtils::deviceAddressToHal(vendor, &halDeviceType, halDeviceAddress); + EXPECT_EQ(AUDIO_DEVICE_NONE, halDeviceType); + EXPECT_EQ(0, strnlen(halDeviceAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN)); + } + { + DeviceAddress vendor; + vendor.deviceType = "VX_GOOGLE_VR"; + vendor.address.id("vr1"); + audio_devices_t halDeviceType; + char halDeviceAddress[AUDIO_DEVICE_MAX_ADDRESS_LEN] = {}; + // Ignore the result. Vendors will also add the extended device into + // the list of devices in audio-hal-enums.h. Without that, the conversion + // officially fails, but it still maps the device type to NONE and converts + // the address. + (void)HidlUtils::deviceAddressToHal(vendor, &halDeviceType, halDeviceAddress); + EXPECT_EQ(AUDIO_DEVICE_NONE, halDeviceType); + EXPECT_EQ(0, strncmp("vr1", halDeviceAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN)); + } +} + +TEST(HidlUtils, ConvertInvalidFormat) { + AudioFormat invalid; + EXPECT_EQ(BAD_VALUE, HidlUtils::audioFormatFromHal(kInvalidHalFormat, &invalid)); + audio_format_t halInvalid; + EXPECT_EQ(BAD_VALUE, HidlUtils::audioFormatToHal("random string", &halInvalid)); +} + +TEST(HidlUtils, ConvertFormat) { + for (const auto enumVal : xsdc_enum_range{}) { + const AudioFormat format = toString(enumVal); + audio_format_t halFormat; + AudioFormat formatBack; + EXPECT_EQ(NO_ERROR, HidlUtils::audioFormatToHal(format, &halFormat)) + << "Conversion of \"" << format << "\" failed"; + EXPECT_TRUE(audio_is_valid_format(halFormat)) + << "Converted format \"" << format << "\" is invalid"; + EXPECT_EQ(NO_ERROR, HidlUtils::audioFormatFromHal(halFormat, &formatBack)) + << "Conversion of format " << halFormat << " failed"; + EXPECT_EQ(format, formatBack); + } +} + +TEST(HidlUtils, ConvertInvalidGainModeMask) { + hidl_vec invalid; + EXPECT_EQ(BAD_VALUE, HidlUtils::audioGainModeMaskFromHal(kInvalidHalGainMode, &invalid)); + audio_gain_mode_t halInvalid; + invalid.resize(1); + invalid[0] = "random string"; + EXPECT_EQ(BAD_VALUE, HidlUtils::audioGainModeMaskToHal(invalid, &halInvalid)); +} + +TEST(HidlUtils, ConvertGainModeMask) { + hidl_vec emptyGainModes; + audio_gain_mode_t halEmptyGainModes; + EXPECT_EQ(NO_ERROR, HidlUtils::audioGainModeMaskToHal(emptyGainModes, &halEmptyGainModes)); + hidl_vec emptyGainModesBack; + EXPECT_EQ(NO_ERROR, + HidlUtils::audioGainModeMaskFromHal(halEmptyGainModes, &emptyGainModesBack)); + EXPECT_EQ(emptyGainModes, emptyGainModesBack); + + std::vector allEnumValues; + for (const auto enumVal : xsdc_enum_range{}) { + allEnumValues.push_back(toString(enumVal)); + } + hidl_vec allGainModes; + allGainModes.resize(allEnumValues.size()); + for (size_t i = 0; i < allEnumValues.size(); ++i) { + allGainModes[i] = allEnumValues[i]; + } + audio_gain_mode_t halAllGainModes; + EXPECT_EQ(NO_ERROR, HidlUtils::audioGainModeMaskToHal(allGainModes, &halAllGainModes)); + hidl_vec allGainModesBack; + EXPECT_EQ(NO_ERROR, HidlUtils::audioGainModeMaskFromHal(halAllGainModes, &allGainModesBack)); + EXPECT_EQ(allGainModes, allGainModesBack); +} + +TEST(HidlUtils, ConvertInvalidSource) { + AudioSource invalid; + EXPECT_EQ(BAD_VALUE, HidlUtils::audioSourceFromHal(kInvalidHalSource, &invalid)); + audio_source_t halInvalid; + EXPECT_EQ(BAD_VALUE, HidlUtils::audioSourceToHal("random string", &halInvalid)); +} + +TEST(HidlUtils, ConvertSource) { + for (const auto enumVal : xsdc_enum_range{}) { + const AudioSource source = toString(enumVal); + audio_source_t halSource; + AudioSource sourceBack; + EXPECT_EQ(NO_ERROR, HidlUtils::audioSourceToHal(source, &halSource)) + << "Conversion of \"" << source << "\" failed"; + EXPECT_EQ(enumVal != xsd::AudioSource::AUDIO_SOURCE_DEFAULT, + audio_is_valid_audio_source(halSource)) + << "Validity of \"" << source << "\" is not as expected"; + EXPECT_EQ(NO_ERROR, HidlUtils::audioSourceFromHal(halSource, &sourceBack)) + << "Conversion of source " << halSource << " failed"; + EXPECT_EQ(source, sourceBack); + } +} + +TEST(HidlUtils, ConvertInvalidStreamType) { + AudioStreamType invalid; + EXPECT_EQ(BAD_VALUE, HidlUtils::audioStreamTypeFromHal(kInvalidHalStreamType, &invalid)); + audio_stream_type_t halInvalid; + EXPECT_EQ(BAD_VALUE, HidlUtils::audioStreamTypeToHal("random string", &halInvalid)); +} + +TEST(HidlUtils, ConvertStreamType) { + for (const auto enumVal : xsdc_enum_range{}) { + const AudioStreamType streamType = toString(enumVal); + audio_stream_type_t halStreamType; + AudioStreamType streamTypeBack; + EXPECT_EQ(NO_ERROR, HidlUtils::audioStreamTypeToHal(streamType, &halStreamType)) + << "Conversion of \"" << streamType << "\" failed"; + EXPECT_EQ(NO_ERROR, HidlUtils::audioStreamTypeFromHal(halStreamType, &streamTypeBack)) + << "Conversion of stream type " << halStreamType << " failed"; + EXPECT_EQ(streamType, streamTypeBack); + } +} + +TEST(HidlUtils, ConvertInvalidGain) { + AudioGain invalid; + EXPECT_EQ(BAD_VALUE, HidlUtils::audioGainFromHal({.mode = kInvalidHalGainMode}, + false /*isInput*/, &invalid)); + EXPECT_EQ(BAD_VALUE, HidlUtils::audioGainFromHal({.mode = kInvalidHalGainMode}, + true /*isInput*/, &invalid)); + struct audio_gain halInvalid; + invalid.mode.resize(1); + invalid.mode[0] = "random string"; + EXPECT_EQ(BAD_VALUE, HidlUtils::audioGainToHal(invalid, &halInvalid)); +} + +TEST(HidlUtils, ConvertGain) { + AudioGain gain = {}; + gain.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO); + struct audio_gain halGain; + EXPECT_EQ(NO_ERROR, HidlUtils::audioGainToHal(gain, &halGain)); + AudioGain gainBack; + EXPECT_EQ(NO_ERROR, HidlUtils::audioGainFromHal(halGain, false /*isInput*/, &gainBack)); + EXPECT_EQ(gain, gainBack); + struct audio_gain halGainBack; + EXPECT_EQ(NO_ERROR, HidlUtils::audioGainToHal(gainBack, &halGainBack)); + EXPECT_TRUE(audio_gains_are_equal(&halGain, &halGainBack)); +} + +TEST(HidlUtils, ConvertInvalidGainConfig) { + AudioGainConfig invalid; + EXPECT_EQ(BAD_VALUE, HidlUtils::audioGainConfigFromHal({.mode = kInvalidHalGainMode}, + false /*isInput*/, &invalid)); + EXPECT_EQ(BAD_VALUE, HidlUtils::audioGainConfigFromHal({.mode = kInvalidHalGainMode}, + true /*isInput*/, &invalid)); + struct audio_gain_config halInvalid; + invalid.mode.resize(1); + invalid.mode[0] = "random string"; + EXPECT_EQ(BAD_VALUE, HidlUtils::audioGainConfigToHal(invalid, &halInvalid)); +} + +TEST(HidlUtils, ConvertGainConfig) { + AudioGainConfig gainConfig = {}; + gainConfig.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO); + struct audio_gain_config halGainConfig; + EXPECT_EQ(NO_ERROR, HidlUtils::audioGainConfigToHal(gainConfig, &halGainConfig)); + AudioGainConfig gainConfigBack; + EXPECT_EQ(NO_ERROR, + HidlUtils::audioGainConfigFromHal(halGainConfig, false /*isInput*/, &gainConfigBack)); + EXPECT_EQ(gainConfig, gainConfigBack); + struct audio_gain_config halGainConfigBack; + EXPECT_EQ(NO_ERROR, HidlUtils::audioGainConfigToHal(gainConfigBack, &halGainConfigBack)); + EXPECT_TRUE(audio_gain_config_are_equal(&halGainConfig, &halGainConfigBack)); +} + +TEST(HidlUtils, ConvertInvalidUsage) { + AudioUsage invalid; + EXPECT_EQ(BAD_VALUE, HidlUtils::audioUsageFromHal(kInvalidHalUsage, &invalid)); + audio_usage_t halInvalid; + EXPECT_EQ(BAD_VALUE, HidlUtils::audioUsageToHal("random string", &halInvalid)); +} + +TEST(HidlUtils, ConvertUsage) { + for (const auto enumVal : xsdc_enum_range{}) { + const AudioUsage usage = toString(enumVal); + audio_usage_t halUsage; + AudioUsage usageBack; + EXPECT_EQ(NO_ERROR, HidlUtils::audioUsageToHal(usage, &halUsage)) + << "Conversion of \"" << usage << "\" failed"; + EXPECT_EQ(NO_ERROR, HidlUtils::audioUsageFromHal(halUsage, &usageBack)) + << "Conversion of usage " << halUsage << " failed"; + EXPECT_EQ(usage, usageBack); + } +} + +TEST(HidlUtils, ConvertInvalidOffloadInfo) { + AudioOffloadInfo invalid; + audio_offload_info_t halInvalid = AUDIO_INFO_INITIALIZER; + halInvalid.channel_mask = AUDIO_CHANNEL_INVALID; + halInvalid.format = kInvalidHalFormat; + EXPECT_EQ(BAD_VALUE, HidlUtils::audioOffloadInfoFromHal(halInvalid, &invalid)); + invalid.base.channelMask = "random string"; + invalid.base.format = "random string"; + EXPECT_EQ(BAD_VALUE, HidlUtils::audioOffloadInfoToHal(invalid, &halInvalid)); +} + +TEST(HidlUtils, ConvertOffloadInfo) { + AudioOffloadInfo offloadInfo = {}; + offloadInfo.base.sampleRateHz = 44100; + offloadInfo.base.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO); + offloadInfo.base.format = toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT); + offloadInfo.streamType = toString(xsd::AudioStreamType::AUDIO_STREAM_MUSIC); + offloadInfo.bitRatePerSecond = 320; + offloadInfo.durationMicroseconds = -1; + offloadInfo.bitWidth = 16; + offloadInfo.bufferSize = 1024; + offloadInfo.usage = toString(xsd::AudioUsage::AUDIO_USAGE_MEDIA); + offloadInfo.encapsulationMode = AudioEncapsulationMode::ELEMENTARY_STREAM; + offloadInfo.contentId = 42; + offloadInfo.syncId = 13; + audio_offload_info_t halOffloadInfo; + EXPECT_EQ(NO_ERROR, HidlUtils::audioOffloadInfoToHal(offloadInfo, &halOffloadInfo)); + AudioOffloadInfo offloadInfoBack; + EXPECT_EQ(NO_ERROR, HidlUtils::audioOffloadInfoFromHal(halOffloadInfo, &offloadInfoBack)); + EXPECT_EQ(offloadInfo, offloadInfoBack); +} + +TEST(HidlUtils, ConvertInvalidConfig) { + AudioConfig invalid; + audio_config_t halInvalid = AUDIO_CONFIG_INITIALIZER; + halInvalid.channel_mask = AUDIO_CHANNEL_INVALID; + halInvalid.format = kInvalidHalFormat; + EXPECT_EQ(BAD_VALUE, HidlUtils::audioConfigFromHal(halInvalid, false /*isInput*/, &invalid)); + EXPECT_EQ(BAD_VALUE, HidlUtils::audioConfigFromHal(halInvalid, true /*isInput*/, &invalid)); + invalid.base.channelMask = "random string"; + invalid.base.format = "random string"; + EXPECT_EQ(BAD_VALUE, HidlUtils::audioConfigToHal(invalid, &halInvalid)); +} + +TEST(HidlUtils, ConvertConfig) { + AudioConfig config = {}; + config.base.sampleRateHz = 44100; + config.base.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO); + config.base.format = toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT); + config.offloadInfo.base = config.base; + config.offloadInfo.streamType = toString(xsd::AudioStreamType::AUDIO_STREAM_MUSIC); + config.offloadInfo.bitRatePerSecond = 320; + config.offloadInfo.durationMicroseconds = -1; + config.offloadInfo.bitWidth = 16; + config.offloadInfo.bufferSize = 1024; + config.offloadInfo.usage = toString(xsd::AudioUsage::AUDIO_USAGE_MEDIA); + config.offloadInfo.encapsulationMode = AudioEncapsulationMode::ELEMENTARY_STREAM; + config.offloadInfo.contentId = 42; + config.offloadInfo.syncId = 13; + audio_config_t halConfig; + EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigToHal(config, &halConfig)); + AudioConfig configBack; + EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigFromHal(halConfig, false /*isInput*/, &configBack)); + EXPECT_EQ(config, configBack); +} + +TEST(HidlUtils, ConvertInvalidAudioProfile) { + AudioProfile invalid; + struct audio_profile halInvalid = {}; + halInvalid.format = kInvalidHalFormat; + halInvalid.num_sample_rates = 0; + halInvalid.num_channel_masks = 1; + halInvalid.channel_masks[0] = kInvalidHalChannelMask; + EXPECT_EQ(BAD_VALUE, HidlUtils::audioProfileFromHal(halInvalid, false /*isInput*/, &invalid)); + EXPECT_EQ(BAD_VALUE, HidlUtils::audioProfileFromHal(halInvalid, true /*isInput*/, &invalid)); + invalid.format = "random string"; + EXPECT_EQ(BAD_VALUE, HidlUtils::audioProfileToHal(invalid, &halInvalid)); +} + +TEST(HidlUtils, ConvertAudioProfile) { + AudioProfile profile = {}; + profile.format = toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT); + profile.sampleRates.resize(2); + profile.sampleRates[0] = 44100; + profile.sampleRates[1] = 48000; + profile.channelMasks.resize(2); + profile.channelMasks[0] = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_MONO); + profile.channelMasks[1] = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO); + struct audio_profile halProfile; + EXPECT_EQ(NO_ERROR, HidlUtils::audioProfileToHal(profile, &halProfile)); + AudioProfile profileBack; + EXPECT_EQ(NO_ERROR, + HidlUtils::audioProfileFromHal(halProfile, false /*isInput*/, &profileBack)); + EXPECT_EQ(profile, profileBack); +} + +TEST(HidlUtils, ConvertInvalidAudioPortConfig) { + AudioPortConfig invalid; + struct audio_port_config halInvalid = {}; + halInvalid.type = AUDIO_PORT_TYPE_MIX; + halInvalid.role = AUDIO_PORT_ROLE_NONE; // note: this is valid. + halInvalid.config_mask = AUDIO_PORT_CONFIG_CHANNEL_MASK; + halInvalid.channel_mask = AUDIO_CHANNEL_INVALID; + EXPECT_EQ(BAD_VALUE, HidlUtils::audioPortConfigFromHal(halInvalid, &invalid)); + invalid.base.channelMask = "random string"; + EXPECT_EQ(BAD_VALUE, HidlUtils::audioPortConfigToHal(invalid, &halInvalid)); +} + +TEST(HidlUtils, ConvertAudioPortConfig) { + AudioPortConfig config = {}; + config.id = 42; + config.base.sampleRateHz = 44100; + config.base.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO); + config.base.format = toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT); + config.gain.config({}); + config.gain.config().channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO); + config.ext.device({}); + config.ext.device().deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_OUT_SPEAKER); + struct audio_port_config halConfig; + EXPECT_EQ(NO_ERROR, HidlUtils::audioPortConfigToHal(config, &halConfig)); + AudioPortConfig configBack; + EXPECT_EQ(NO_ERROR, HidlUtils::audioPortConfigFromHal(halConfig, &configBack)); + EXPECT_EQ(config, configBack); + struct audio_port_config halConfigBack; + EXPECT_EQ(NO_ERROR, HidlUtils::audioPortConfigToHal(configBack, &halConfigBack)); + EXPECT_TRUE(audio_port_configs_are_equal(&halConfig, &halConfigBack)); +} + +TEST(HidlUtils, ConvertInvalidAudioPort) { + AudioPort invalid; + struct audio_port_v7 halInvalid = {}; + halInvalid.type = AUDIO_PORT_TYPE_MIX; + halInvalid.role = AUDIO_PORT_ROLE_NONE; // note: this is valid. + halInvalid.num_audio_profiles = 1; + halInvalid.audio_profiles[0].format = kInvalidHalFormat; + EXPECT_EQ(BAD_VALUE, HidlUtils::audioPortFromHal(halInvalid, &invalid)); + invalid.profiles.resize(1); + invalid.profiles[0].format = "random string"; + EXPECT_EQ(BAD_VALUE, HidlUtils::audioPortToHal(invalid, &halInvalid)); +} + +TEST(HidlUtils, ConvertAudioPort) { + AudioPort port = {}; + port.id = 42; + port.name = "test"; + port.profiles.resize(1); + port.profiles[0].format = toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT); + port.profiles[0].sampleRates.resize(2); + port.profiles[0].sampleRates[0] = 44100; + port.profiles[0].sampleRates[1] = 48000; + port.profiles[0].channelMasks.resize(2); + port.profiles[0].channelMasks[0] = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_MONO); + port.profiles[0].channelMasks[1] = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO); + port.gains.resize(1); + port.gains[0].channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO); + port.ext.device({}); + port.ext.device().deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_OUT_SPEAKER); + // active config left unspecified. + struct audio_port_v7 halPort; + EXPECT_EQ(NO_ERROR, HidlUtils::audioPortToHal(port, &halPort)); + AudioPort portBack; + EXPECT_EQ(NO_ERROR, HidlUtils::audioPortFromHal(halPort, &portBack)); + EXPECT_EQ(port, portBack); + struct audio_port_v7 halPortBack; + EXPECT_EQ(NO_ERROR, HidlUtils::audioPortToHal(portBack, &halPortBack)); + EXPECT_TRUE(audio_ports_v7_are_equal(&halPort, &halPortBack)); +} diff --git a/audio/core/all-versions/default/Conversions.cpp b/audio/core/all-versions/default/Conversions.cpp index 0db210a58a..28d8f78bbc 100644 --- a/audio/core/all-versions/default/Conversions.cpp +++ b/audio/core/all-versions/default/Conversions.cpp @@ -27,6 +27,7 @@ namespace audio { namespace CPP_VERSION { namespace implementation { +// TODO(mnaganov): Use method from HidlUtils for V7 std::string deviceAddressToHal(const DeviceAddress& address) { // HAL assumes that the address is NUL-terminated. char halAddress[AUDIO_DEVICE_MAX_ADDRESS_LEN]; diff --git a/audio/core/all-versions/default/Device.cpp b/audio/core/all-versions/default/Device.cpp index 6260ba1979..3c28159816 100644 --- a/audio/core/all-versions/default/Device.cpp +++ b/audio/core/all-versions/default/Device.cpp @@ -283,8 +283,10 @@ std::tuple Device::createOrUpdateAudioPatch( const hidl_vec& sinks) { Result retval(Result::NOT_SUPPORTED); if (version() >= AUDIO_DEVICE_API_VERSION_3_0) { - std::unique_ptr halSources(HidlUtils::audioPortConfigsToHal(sources)); - std::unique_ptr halSinks(HidlUtils::audioPortConfigsToHal(sinks)); + std::unique_ptr halSources; + HidlUtils::audioPortConfigsToHal(sources, &halSources); + std::unique_ptr halSinks; + HidlUtils::audioPortConfigsToHal(sinks, &halSinks); audio_patch_handle_t halPatch = static_cast(patch); retval = analyzeStatus("create_audio_patch", mDevice->create_audio_patch(mDevice, sources.size(), &halSources[0], diff --git a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp index eb8cb3f4f7..1612d3c30c 100644 --- a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp +++ b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp @@ -67,8 +67,7 @@ TEST_P(AudioHidlDeviceTest, GetMicrophonesTest) { auto flags = hidl_bitfield(AudioInputFlag::NONE); const SinkMetadata initMetadata = {{{.source = AudioSource::MIC, .gain = 1}}}; #elif MAJOR_VERSION >= 7 - config.base.channelMask.resize(1); - config.base.channelMask[0] = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_IN_MONO); + config.base.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_IN_MONO); config.base.sampleRateHz = 8000; config.base.format = toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT); hidl_vec flags; diff --git a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp index 63eaea8acc..941c4bdbc9 100644 --- a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp +++ b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp @@ -26,8 +26,7 @@ static std::vector combineAudioConfig(std::vector Date: Tue, 17 Nov 2020 19:06:53 -0800 Subject: [PATCH 298/790] Update fingerprint AIDL for CTS Bug: 173453845 Test: atest CtsBiometricsTestCases Change-Id: I9132d366e862b38ccb7fe72082f7a4cb9c7e160f --- biometrics/fingerprint/aidl/default/Fingerprint.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biometrics/fingerprint/aidl/default/Fingerprint.cpp b/biometrics/fingerprint/aidl/default/Fingerprint.cpp index 18ce0c850e..6eb35d970f 100644 --- a/biometrics/fingerprint/aidl/default/Fingerprint.cpp +++ b/biometrics/fingerprint/aidl/default/Fingerprint.cpp @@ -19,7 +19,7 @@ namespace aidl::android::hardware::biometrics::fingerprint { -const int kSensorId = 0; +const int kSensorId = 1; const common::SensorStrength kSensorStrength = common::SensorStrength::STRONG; const int kMaxEnrollmentsPerUser = 5; const FingerprintSensorType kSensorType = FingerprintSensorType::REAR; -- GitLab From 237cdaf678040885b6c6e8e2682864e8728839e8 Mon Sep 17 00:00:00 2001 From: Jack Nudelman Date: Wed, 18 Nov 2020 16:21:06 -0800 Subject: [PATCH 299/790] Change setDataThrottling window parameter to a long millisecond. As requested by Android Council review of API. Test: vts Change-Id: I1f633856c31623ef95f459b2195743f53b5d85fc --- radio/1.6/IRadio.hal | 6 +++--- radio/1.6/vts/functional/radio_hidl_hal_api.cpp | 9 +++++---- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/radio/1.6/IRadio.hal b/radio/1.6/IRadio.hal index 7f874c64e9..c73745af5f 100644 --- a/radio/1.6/IRadio.hal +++ b/radio/1.6/IRadio.hal @@ -340,15 +340,15 @@ interface IRadio extends @1.5::IRadio { * * @param serial Serial number of request. * @param dataThrottlingAction DataThrottlingAction as defined in types.hal - * @param completionWindowSecs window, in seconds, in which the requested - * throttling action has to be achieved. This must be 0 when + * @param completionDurationMillis window, in milliseconds, in which the + * requested throttling action has to be achieved. This must be 0 when * dataThrottlingAction is DataThrottlingAction:HOLD. * * Response function is IRadioResponse.setDataThrottlingResponse() */ oneway setDataThrottling(int32_t serial, DataThrottlingAction dataThrottlingAction, - int32_t completionWindowSecs); + int64_t completionDurationMillis); /** * Get which bands the modem's background scan is acting on. diff --git a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp index d3ffba988a..6b1ff27f58 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp +++ b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp @@ -303,7 +303,7 @@ TEST_P(RadioHidlTest_v1_6, setDataThrottling) { serial = GetRandomSerialNumber(); Return res = radio_v1_6->setDataThrottling( - serial, DataThrottlingAction::THROTTLE_SECONDARY_CARRIER, 60); + serial, DataThrottlingAction::THROTTLE_SECONDARY_CARRIER, 60000); ASSERT_OK(res); EXPECT_EQ(std::cv_status::no_timeout, wait()); @@ -318,7 +318,8 @@ TEST_P(RadioHidlTest_v1_6, setDataThrottling) { serial = GetRandomSerialNumber(); - res = radio_v1_6->setDataThrottling(serial, DataThrottlingAction::THROTTLE_ANCHOR_CARRIER, 60); + res = radio_v1_6->setDataThrottling(serial, DataThrottlingAction::THROTTLE_ANCHOR_CARRIER, + 60000); ASSERT_OK(res); EXPECT_EQ(std::cv_status::no_timeout, wait()); @@ -333,7 +334,7 @@ TEST_P(RadioHidlTest_v1_6, setDataThrottling) { serial = GetRandomSerialNumber(); - res = radio_v1_6->setDataThrottling(serial, DataThrottlingAction::HOLD, 60); + res = radio_v1_6->setDataThrottling(serial, DataThrottlingAction::HOLD, 60000); ASSERT_OK(res); EXPECT_EQ(std::cv_status::no_timeout, wait()); @@ -348,7 +349,7 @@ TEST_P(RadioHidlTest_v1_6, setDataThrottling) { serial = GetRandomSerialNumber(); - res = radio_v1_6->setDataThrottling(serial, DataThrottlingAction::NO_DATA_THROTTLING, 60); + res = radio_v1_6->setDataThrottling(serial, DataThrottlingAction::NO_DATA_THROTTLING, 60000); ASSERT_OK(res); EXPECT_EQ(std::cv_status::no_timeout, wait()); -- GitLab From 8e85d1f5a53ecdd5ac3f9b5c0cea7f526a95dfd1 Mon Sep 17 00:00:00 2001 From: Mikhail Naganov Date: Fri, 20 Nov 2020 15:26:14 -0800 Subject: [PATCH 300/790] audio: Use docstrings instead of comments in types.hal files Converted comments into docstrings for enums and structures in Audio HAL V7 definition. Bug: 142480271 Test: m Change-Id: Id5e36e7a42e2600ab69612819f8260110871c711 --- audio/7.0/types.hal | 22 ++++++++----- audio/common/7.0/types.hal | 36 ++++++++++++++-------- audio/effect/7.0/types.hal | 63 ++++++++++++++++++++++++-------------- 3 files changed, 78 insertions(+), 43 deletions(-) diff --git a/audio/7.0/types.hal b/audio/7.0/types.hal index 1ae7bad310..2d421296a7 100644 --- a/audio/7.0/types.hal +++ b/audio/7.0/types.hal @@ -44,8 +44,10 @@ enum AudioDrain : int32_t { * A substitute for POSIX timespec. */ struct TimeSpec { - uint64_t tvSec; // seconds - uint64_t tvNSec; // nanoseconds + /** Seconds. */ + uint64_t tvSec; + /** Nanoseconds. */ + uint64_t tvNSec; }; struct ParameterValue { @@ -85,8 +87,10 @@ struct MmapBufferInfo { * Used by streams opened in mmap mode. */ struct MmapPosition { - int64_t timeNanoseconds; // time stamp in ns, CLOCK_MONOTONIC - int32_t positionFrames; // increasing 32 bit frame count reset when IStream.stop() is called + /** Timestamp in ns, CLOCK_MONOTONIC. */ + int64_t timeNanoseconds; + /** Increasing 32 bit frame count reset when IStream.stop() is called. */ + int32_t positionFrames; }; /** @@ -128,9 +132,12 @@ struct AudioMicrophoneCoordinate { */ @export(name="audio_microphone_channel_mapping_t", value_prefix="AUDIO_MICROPHONE_CHANNEL_MAPPING_") enum AudioMicrophoneChannelMapping : uint32_t { - UNUSED = 0, /* Channel not used */ - DIRECT = 1, /* Channel used and signal not processed */ - PROCESSED = 2, /* Channel used and signal has some processing */ + /** Channel not used. */ + UNUSED = 0, + /** Channel used and signal not processed. */ + DIRECT = 1, + /** Channel used and signal has some processing. */ + PROCESSED = 2, }; /** @@ -269,7 +276,6 @@ enum DualMonoMode : int32_t { // frameworks/base/media/java/android/media/AudioTrack.java /** * Disable any Dual Mono presentation effect. - * */ OFF = 0, /** diff --git a/audio/common/7.0/types.hal b/audio/common/7.0/types.hal index 2da9815cbd..ed56c7320f 100644 --- a/audio/common/7.0/types.hal +++ b/audio/common/7.0/types.hal @@ -332,14 +332,22 @@ typedef string AudioGainMode; * A gain stage is always attached to an audio port. */ struct AudioGain { - vec mode; // modes of operation - AudioChannelMask channelMask; // channels which gain can be controlled - int32_t minValue; // minimum gain value in millibels - int32_t maxValue; // maximum gain value in millibels - int32_t defaultValue; // default gain value in millibels - uint32_t stepValue; // gain step in millibels - uint32_t minRampMs; // minimum ramp duration in ms - uint32_t maxRampMs; // maximum ramp duration in ms + /** Modes of operation. */ + vec mode; + /** Channels which gain can be controlled. */ + AudioChannelMask channelMask; + /** Minimum gain value in millibels. */ + int32_t minValue; + /** Maximum gain value in millibels. */ + int32_t maxValue; + /** Default gain value in millibels. */ + int32_t defaultValue; + /** Gain step in millibels. */ + uint32_t stepValue; + /** Ramp duration in ms. */ + uint32_t minRampMs; + /** Maximum ramp duration in ms. */ + uint32_t maxRampMs; }; /** @@ -347,16 +355,20 @@ struct AudioGain { * given port. */ struct AudioGainConfig { - int32_t index; // index of the corresponding AudioGain in AudioPort.gains - vec mode; // modes of operation - AudioChannelMask channelMask; // channels which gain value follows + /** Index of the corresponding AudioGain in AudioPort.gains. */ + int32_t index; + /** Modes of operation. */ + vec mode; + /** Channels which gain value follows. */ + AudioChannelMask channelMask; /** * Gain values in millibels for each channel ordered from LSb to MSb in * channel mask. The number of values is 1 in joint mode or * the number of channels in the channel mask. */ vec values; - uint32_t rampDurationMs; // ramp duration in ms + /** Ramp duration in ms. */ + uint32_t rampDurationMs; }; diff --git a/audio/effect/7.0/types.hal b/audio/effect/7.0/types.hal index fe4ee51584..b0a0709c31 100644 --- a/audio/effect/7.0/types.hal +++ b/audio/effect/7.0/types.hal @@ -202,16 +202,26 @@ enum EffectFlags : int32_t { * enumeration of the effect engines present in a library. */ struct EffectDescriptor { - Uuid type; // UUID of to the OpenSL ES interface implemented - // by this effect - Uuid uuid; // UUID for this particular implementation - bitfield flags; // effect engine capabilities/requirements flags - uint16_t cpuLoad; // CPU load indication expressed in 0.1 MIPS units - // as estimated on an ARM9E core (ARMv5TE) with 0 WS - uint16_t memoryUsage; // data memory usage expressed in KB and includes - // only dynamically allocated memory - uint8_t[64] name; // human readable effect name - uint8_t[64] implementor; // human readable effect implementor name + /** UUID of to the OpenSL ES interface implemented by this effect. */ + Uuid type; + /** UUID for this particular implementation. */ + Uuid uuid; + /** Effect engine capabilities/requirements flags. */ + bitfield flags; + /** + * CPU load indication expressed in 0.1 MIPS units as estimated on + * an ARM9E core (ARMv5TE) with 0 WS. + */ + uint16_t cpuLoad; + /** + * Data memory usage expressed in KB and includes only dynamically + * allocated memory. + */ + uint16_t memoryUsage; + /** Human readable effect name. */ + uint8_t[64] name; + /** Human readable effect implementor name. */ + uint8_t[64] implementor; }; /** @@ -242,11 +252,16 @@ enum EffectBufferAccess : int32_t { */ @export(name="", value_prefix="EFFECT_CONFIG_") enum EffectConfigParameters : int32_t { - BUFFER = 0x0001, // buffer field - SMP_RATE = 0x0002, // samplingRate - CHANNELS = 0x0004, // channels - FORMAT = 0x0008, // format - ACC_MODE = 0x0010, // accessMode + /** Buffer field. */ + BUFFER = 0x0001, + /** Sampling rate. */ + SMP_RATE = 0x0002, + /** Channels. */ + CHANNELS = 0x0004, + /** Format. */ + FORMAT = 0x0008, + /** Access mode. */ + ACC_MODE = 0x0010, // Note that the 2.0 ALL have been moved to an helper function }; @@ -270,21 +285,23 @@ struct EffectConfig { @export(name="effect_feature_e", value_prefix="EFFECT_FEATURE_") enum EffectFeature : int32_t { - AUX_CHANNELS, // supports auxiliary channels - // (e.g. dual mic noise suppressor) + /** Supports auxiliary channels (e.g. dual mic noise suppressor). */ + AUX_CHANNELS, CNT }; struct EffectAuxChannelsConfig { - vec mainChannels; // channel mask for main channels - vec auxChannels; // channel mask for auxiliary channels + /** Channel mask for main channels. */ + vec mainChannels; + /** Channel mask for auxiliary channels. */ + vec auxChannels; }; struct EffectOffloadParameter { - bool isOffload; // true if the playback thread the effect - // is attached to is offloaded - AudioIoHandle ioHandle; // io handle of the playback thread - // the effect is attached to + /** True if the playback thread the effect is attached to is offloaded. */ + bool isOffload; + /** I/O handle of the playback thread the effect is attached to. */ + AudioIoHandle ioHandle; }; /** -- GitLab From 5a74c0fb0f23474a89471c49111e5ab526735392 Mon Sep 17 00:00:00 2001 From: Michael Butler Date: Thu, 19 Nov 2020 20:46:58 -0800 Subject: [PATCH 301/790] Invalidate NN interface objects on cache mismatch Currently, if an IDevice object is a DEAD_OBJECT, the runtime attempts to re-retrieve the handle to the rebooted IDevice service. If an update occurs after the IDevice was originally created, the rebooted IDevice object may have different metadata and behavior. This is problematic because the original metadata is cached in the runtime. Further, an application might have made decisions based on that metadata and behavior. (Note that a driver service that is functionally the same but has a different underlying implementation such as having more optimized code will have different `getVersionString` metadata.) Instead, this CL invalidates the IDevice object on cache mismatch, and always returns an error if it is used. Bug: 173081926 Test: mma Change-Id: I805987361c627c32d45e1b7c7aed230376fc66ad --- .../common/include/nnapi/hal/InvalidBuffer.h | 42 +++++++ .../common/include/nnapi/hal/InvalidDevice.h | 80 +++++++++++++ .../include/nnapi/hal/InvalidPreparedModel.h | 48 ++++++++ .../include/nnapi/hal/ResilientDevice.h | 7 +- .../utils/common/src/InvalidBuffer.cpp | 42 +++++++ .../utils/common/src/InvalidDevice.cpp | 105 ++++++++++++++++++ .../utils/common/src/InvalidPreparedModel.cpp | 49 ++++++++ .../utils/common/src/ResilientDevice.cpp | 38 ++++++- 8 files changed, 403 insertions(+), 8 deletions(-) create mode 100644 neuralnetworks/utils/common/include/nnapi/hal/InvalidBuffer.h create mode 100644 neuralnetworks/utils/common/include/nnapi/hal/InvalidDevice.h create mode 100644 neuralnetworks/utils/common/include/nnapi/hal/InvalidPreparedModel.h create mode 100644 neuralnetworks/utils/common/src/InvalidBuffer.cpp create mode 100644 neuralnetworks/utils/common/src/InvalidDevice.cpp create mode 100644 neuralnetworks/utils/common/src/InvalidPreparedModel.cpp diff --git a/neuralnetworks/utils/common/include/nnapi/hal/InvalidBuffer.h b/neuralnetworks/utils/common/include/nnapi/hal/InvalidBuffer.h new file mode 100644 index 0000000000..8c04b8887b --- /dev/null +++ b/neuralnetworks/utils/common/include/nnapi/hal/InvalidBuffer.h @@ -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. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_INVALID_BUFFER_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_INVALID_BUFFER_H + +#include +#include +#include + +#include +#include +#include + +namespace android::hardware::neuralnetworks::utils { + +class InvalidBuffer final : public nn::IBuffer { + public: + nn::Request::MemoryDomainToken getToken() const override; + + nn::GeneralResult copyTo(const nn::Memory& dst) const override; + + nn::GeneralResult copyFrom(const nn::Memory& src, + const nn::Dimensions& dimensions) const override; +}; + +} // namespace android::hardware::neuralnetworks::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_INVALID_BUFFER_H diff --git a/neuralnetworks/utils/common/include/nnapi/hal/InvalidDevice.h b/neuralnetworks/utils/common/include/nnapi/hal/InvalidDevice.h new file mode 100644 index 0000000000..5e62b9ae0b --- /dev/null +++ b/neuralnetworks/utils/common/include/nnapi/hal/InvalidDevice.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_INVALID_DEVICE_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_INVALID_DEVICE_H + +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace android::hardware::neuralnetworks::utils { + +class InvalidDevice final : public nn::IDevice { + public: + InvalidDevice(std::string name, std::string versionString, nn::Version featureLevel, + nn::DeviceType type, std::vector extensions, + nn::Capabilities capabilities, + std::pair numberOfCacheFilesNeeded); + + const std::string& getName() const override; + const std::string& getVersionString() const override; + nn::Version getFeatureLevel() const override; + nn::DeviceType getType() const override; + const std::vector& getSupportedExtensions() const override; + const nn::Capabilities& getCapabilities() const override; + std::pair getNumberOfCacheFilesNeeded() const override; + + nn::GeneralResult wait() const override; + + nn::GeneralResult> getSupportedOperations( + const nn::Model& model) const override; + + nn::GeneralResult prepareModel( + const nn::Model& model, nn::ExecutionPreference preference, nn::Priority priority, + nn::OptionalTimePoint deadline, const std::vector& modelCache, + const std::vector& dataCache, + const nn::CacheToken& token) const override; + + nn::GeneralResult prepareModelFromCache( + nn::OptionalTimePoint deadline, const std::vector& modelCache, + const std::vector& dataCache, + const nn::CacheToken& token) const override; + + nn::GeneralResult allocate( + const nn::BufferDesc& desc, const std::vector& preparedModels, + const std::vector& inputRoles, + const std::vector& outputRoles) const override; + + private: + const std::string kName; + const std::string kVersionString; + const nn::Version kFeatureLevel; + const nn::DeviceType kType; + const std::vector kExtensions; + const nn::Capabilities kCapabilities; + const std::pair kNumberOfCacheFilesNeeded; +}; + +} // namespace android::hardware::neuralnetworks::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_INVALID_DEVICE_H diff --git a/neuralnetworks/utils/common/include/nnapi/hal/InvalidPreparedModel.h b/neuralnetworks/utils/common/include/nnapi/hal/InvalidPreparedModel.h new file mode 100644 index 0000000000..4b32b4e3af --- /dev/null +++ b/neuralnetworks/utils/common/include/nnapi/hal/InvalidPreparedModel.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_INVALID_PREPARED_MODEL_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_INVALID_PREPARED_MODEL_H + +#include +#include +#include + +#include +#include +#include + +namespace android::hardware::neuralnetworks::utils { + +class InvalidPreparedModel final : public nn::IPreparedModel { + public: + nn::ExecutionResult, nn::Timing>> execute( + const nn::Request& request, nn::MeasureTiming measure, + const nn::OptionalTimePoint& deadline, + const nn::OptionalTimeoutDuration& loopTimeoutDuration) const override; + + nn::GeneralResult> executeFenced( + const nn::Request& request, const std::vector& waitFor, + nn::MeasureTiming measure, const nn::OptionalTimePoint& deadline, + const nn::OptionalTimeoutDuration& loopTimeoutDuration, + const nn::OptionalTimeoutDuration& timeoutDurationAfterFence) const override; + + std::any getUnderlyingResource() const override; +}; + +} // namespace android::hardware::neuralnetworks::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_INVALID_PREPARED_MODEL_H diff --git a/neuralnetworks/utils/common/include/nnapi/hal/ResilientDevice.h b/neuralnetworks/utils/common/include/nnapi/hal/ResilientDevice.h index 4a84e4dacc..4bfed6cd51 100644 --- a/neuralnetworks/utils/common/include/nnapi/hal/ResilientDevice.h +++ b/neuralnetworks/utils/common/include/nnapi/hal/ResilientDevice.h @@ -45,8 +45,9 @@ class ResilientDevice final : public nn::IDevice, std::string versionString, std::vector extensions, nn::Capabilities capabilities, nn::SharedDevice device); - nn::SharedDevice getDevice() const; - nn::SharedDevice recover(const nn::IDevice* failingDevice, bool blocking) const; + nn::SharedDevice getDevice() const EXCLUDES(mMutex); + nn::SharedDevice recover(const nn::IDevice* failingDevice, bool blocking) const + EXCLUDES(mMutex); const std::string& getName() const override; const std::string& getVersionString() const override; @@ -78,6 +79,7 @@ class ResilientDevice final : public nn::IDevice, const std::vector& outputRoles) const override; private: + bool isValidInternal() const EXCLUDES(mMutex); nn::GeneralResult prepareModelInternal( bool blocking, const nn::Model& model, nn::ExecutionPreference preference, nn::Priority priority, nn::OptionalTimePoint deadline, @@ -100,6 +102,7 @@ class ResilientDevice final : public nn::IDevice, const nn::Capabilities kCapabilities; mutable std::mutex mMutex; mutable nn::SharedDevice mDevice GUARDED_BY(mMutex); + mutable bool mIsValid GUARDED_BY(mMutex) = true; }; } // namespace android::hardware::neuralnetworks::utils diff --git a/neuralnetworks/utils/common/src/InvalidBuffer.cpp b/neuralnetworks/utils/common/src/InvalidBuffer.cpp new file mode 100644 index 0000000000..c6f75d7137 --- /dev/null +++ b/neuralnetworks/utils/common/src/InvalidBuffer.cpp @@ -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. + */ + +#include "InvalidBuffer.h" + +#include +#include +#include + +#include +#include +#include + +namespace android::hardware::neuralnetworks::utils { + +nn::Request::MemoryDomainToken InvalidBuffer::getToken() const { + return nn::Request::MemoryDomainToken{}; +} + +nn::GeneralResult InvalidBuffer::copyTo(const nn::Memory& /*dst*/) const { + return NN_ERROR() << "InvalidBuffer"; +} + +nn::GeneralResult InvalidBuffer::copyFrom(const nn::Memory& /*src*/, + const nn::Dimensions& /*dimensions*/) const { + return NN_ERROR() << "InvalidBuffer"; +} + +} // namespace android::hardware::neuralnetworks::utils diff --git a/neuralnetworks/utils/common/src/InvalidDevice.cpp b/neuralnetworks/utils/common/src/InvalidDevice.cpp new file mode 100644 index 0000000000..535ccb41c7 --- /dev/null +++ b/neuralnetworks/utils/common/src/InvalidDevice.cpp @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "InvalidDevice.h" + +#include "InvalidBuffer.h" +#include "InvalidPreparedModel.h" + +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace android::hardware::neuralnetworks::utils { + +InvalidDevice::InvalidDevice(std::string name, std::string versionString, nn::Version featureLevel, + nn::DeviceType type, std::vector extensions, + nn::Capabilities capabilities, + std::pair numberOfCacheFilesNeeded) + : kName(std::move(name)), + kVersionString(std::move(versionString)), + kFeatureLevel(featureLevel), + kType(type), + kExtensions(std::move(extensions)), + kCapabilities(std::move(capabilities)), + kNumberOfCacheFilesNeeded(numberOfCacheFilesNeeded) {} + +const std::string& InvalidDevice::getName() const { + return kName; +} + +const std::string& InvalidDevice::getVersionString() const { + return kVersionString; +} + +nn::Version InvalidDevice::getFeatureLevel() const { + return kFeatureLevel; +} + +nn::DeviceType InvalidDevice::getType() const { + return kType; +} + +const std::vector& InvalidDevice::getSupportedExtensions() const { + return kExtensions; +} + +const nn::Capabilities& InvalidDevice::getCapabilities() const { + return kCapabilities; +} + +std::pair InvalidDevice::getNumberOfCacheFilesNeeded() const { + return kNumberOfCacheFilesNeeded; +} + +nn::GeneralResult InvalidDevice::wait() const { + return NN_ERROR() << "InvalidDevice"; +} + +nn::GeneralResult> InvalidDevice::getSupportedOperations( + const nn::Model& /*model*/) const { + return NN_ERROR() << "InvalidDevice"; +} + +nn::GeneralResult InvalidDevice::prepareModel( + const nn::Model& /*model*/, nn::ExecutionPreference /*preference*/, + nn::Priority /*priority*/, nn::OptionalTimePoint /*deadline*/, + const std::vector& /*modelCache*/, + const std::vector& /*dataCache*/, const nn::CacheToken& /*token*/) const { + return NN_ERROR() << "InvalidDevice"; +} + +nn::GeneralResult InvalidDevice::prepareModelFromCache( + nn::OptionalTimePoint /*deadline*/, const std::vector& /*modelCache*/, + const std::vector& /*dataCache*/, const nn::CacheToken& /*token*/) const { + return NN_ERROR() << "InvalidDevice"; +} + +nn::GeneralResult InvalidDevice::allocate( + const nn::BufferDesc& /*desc*/, + const std::vector& /*preparedModels*/, + const std::vector& /*inputRoles*/, + const std::vector& /*outputRoles*/) const { + return NN_ERROR() << "InvalidDevice"; +} + +} // namespace android::hardware::neuralnetworks::utils diff --git a/neuralnetworks/utils/common/src/InvalidPreparedModel.cpp b/neuralnetworks/utils/common/src/InvalidPreparedModel.cpp new file mode 100644 index 0000000000..9ae7a63949 --- /dev/null +++ b/neuralnetworks/utils/common/src/InvalidPreparedModel.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "InvalidPreparedModel.h" + +#include +#include +#include + +#include +#include +#include + +namespace android::hardware::neuralnetworks::utils { + +nn::ExecutionResult, nn::Timing>> +InvalidPreparedModel::execute(const nn::Request& /*request*/, nn::MeasureTiming /*measure*/, + const nn::OptionalTimePoint& /*deadline*/, + const nn::OptionalTimeoutDuration& /*loopTimeoutDuration*/) const { + return NN_ERROR() << "InvalidPreparedModel"; +} + +nn::GeneralResult> +InvalidPreparedModel::executeFenced( + const nn::Request& /*request*/, const std::vector& /*waitFor*/, + nn::MeasureTiming /*measure*/, const nn::OptionalTimePoint& /*deadline*/, + const nn::OptionalTimeoutDuration& /*loopTimeoutDuration*/, + const nn::OptionalTimeoutDuration& /*timeoutDurationAfterFence*/) const { + return NN_ERROR() << "InvalidPreparedModel"; +} + +std::any InvalidPreparedModel::getUnderlyingResource() const { + return {}; +} + +} // namespace android::hardware::neuralnetworks::utils diff --git a/neuralnetworks/utils/common/src/ResilientDevice.cpp b/neuralnetworks/utils/common/src/ResilientDevice.cpp index 26025a5026..2f83c5c5bd 100644 --- a/neuralnetworks/utils/common/src/ResilientDevice.cpp +++ b/neuralnetworks/utils/common/src/ResilientDevice.cpp @@ -16,6 +16,9 @@ #include "ResilientDevice.h" +#include "InvalidBuffer.h" +#include "InvalidDevice.h" +#include "InvalidPreparedModel.h" #include "ResilientBuffer.h" #include "ResilientPreparedModel.h" @@ -107,12 +110,21 @@ nn::SharedDevice ResilientDevice::recover(const nn::IDevice* failingDevice, bool } auto device = std::move(maybeDevice).value(); - // TODO(b/173081926): Instead of CHECKing to ensure the cache has not been changed, return an - // invalid/"null" IDevice object that always fails. - CHECK_EQ(kName, device->getName()); - CHECK_EQ(kVersionString, device->getVersionString()); - CHECK(kExtensions == device->getSupportedExtensions()); - CHECK_EQ(kCapabilities, device->getCapabilities()); + // If recovered device has different metadata than what is cached (i.e., because it was + // updated), mark the device as invalid and preserve the cached data. + auto compare = [this, &device](auto fn) REQUIRES(mMutex) { + return std::invoke(fn, mDevice) != std::invoke(fn, device); + }; + if (compare(&IDevice::getName) || compare(&IDevice::getVersionString) || + compare(&IDevice::getFeatureLevel) || compare(&IDevice::getType) || + compare(&IDevice::getSupportedExtensions) || compare(&IDevice::getCapabilities)) { + LOG(ERROR) << "Recovered device has different metadata than what is cached. Marking " + "IDevice object as invalid."; + device = std::make_shared( + kName, kVersionString, mDevice->getFeatureLevel(), mDevice->getType(), kExtensions, + kCapabilities, mDevice->getNumberOfCacheFilesNeeded()); + mIsValid = false; + } mDevice = std::move(device); return mDevice; @@ -199,11 +211,19 @@ nn::GeneralResult ResilientDevice::allocate( return ResilientBuffer::create(std::move(makeBuffer)); } +bool ResilientDevice::isValidInternal() const { + std::lock_guard hold(mMutex); + return mIsValid; +} + nn::GeneralResult ResilientDevice::prepareModelInternal( bool blocking, const nn::Model& model, nn::ExecutionPreference preference, nn::Priority priority, nn::OptionalTimePoint deadline, const std::vector& modelCache, const std::vector& dataCache, const nn::CacheToken& token) const { + if (!isValidInternal()) { + return std::make_shared(); + } const auto fn = [&model, preference, priority, deadline, &modelCache, &dataCache, token](const nn::IDevice& device) { return device.prepareModel(model, preference, priority, deadline, modelCache, dataCache, @@ -216,6 +236,9 @@ nn::GeneralResult ResilientDevice::prepareModelFromCach bool blocking, nn::OptionalTimePoint deadline, const std::vector& modelCache, const std::vector& dataCache, const nn::CacheToken& token) const { + if (!isValidInternal()) { + return std::make_shared(); + } const auto fn = [deadline, &modelCache, &dataCache, token](const nn::IDevice& device) { return device.prepareModelFromCache(deadline, modelCache, dataCache, token); }; @@ -227,6 +250,9 @@ nn::GeneralResult ResilientDevice::allocateInternal( const std::vector& preparedModels, const std::vector& inputRoles, const std::vector& outputRoles) const { + if (!isValidInternal()) { + return std::make_shared(); + } const auto fn = [&desc, &preparedModels, &inputRoles, &outputRoles](const nn::IDevice& device) { return device.allocate(desc, preparedModels, inputRoles, outputRoles); }; -- GitLab From 94d2824a663f6603ba8b5a931414a0f7008b9bcb Mon Sep 17 00:00:00 2001 From: lesl Date: Wed, 18 Nov 2020 22:17:37 +0800 Subject: [PATCH 302/790] wifi: Add AP bridge operations support (AP+AP Part 2) The bridge interface name will take "ap_br_" + ap interface name. ex: The ap interface name is "wlan1". The bridge interface name will be "ap_br_wlan1" When OEM customize the ap interface name via property "ro.vendor.wifi.sap.interface". It will only apply on single AP mode. i.e. "ro.vendor.wifi.sap.interface" = "sap0" Single AP mode: ap interface name = "sap0" Dual AP mode: bridge interface name = "ap_br_sap0" first ap instance name: get from "getSupportedIfaceName" + idx ex: sap0 second ap instance name: get from "getSupportedIfaceName" + idx + 1 ex: sap1 PS: The VtsHalWifiApV1_5TargetTest will be added in another CL which will update another SAP related HAL:IWifiApIface.hal. AP+AP Part 2 includes: 1. Support bridge in libwifi_system_iface 2. WifiHal API a. createBridgedApIface (Support create bridge mode AP) b. removeIfaceInstanceFromBridgedApIface (Support remove one of the instance in bridge) 3. Framework: Create bridge AP when multi-bands configured. Bug: 162686273 Test: Manual Test (SAP enable normally) Test: atest -c VtsHalWifiApV1_0TargetTest Test: atest -c VtsHalWifiApV1_4TargetTest Change-Id: I8be510778e9772bcf1539e4915384949cbe13127 --- wifi/1.5/IWifiChip.hal | 40 ++++++++ wifi/1.5/default/wifi_chip.cpp | 182 ++++++++++++++++++++++++++++++--- wifi/1.5/default/wifi_chip.h | 15 ++- 3 files changed, 219 insertions(+), 18 deletions(-) diff --git a/wifi/1.5/IWifiChip.hal b/wifi/1.5/IWifiChip.hal index dcc927900a..7cf81b572a 100644 --- a/wifi/1.5/IWifiChip.hal +++ b/wifi/1.5/IWifiChip.hal @@ -17,6 +17,7 @@ package android.hardware.wifi@1.5; import @1.0::WifiStatus; +import @1.0::IWifiApIface; import @1.0::IWifiIface; import @1.3::IWifiChip; import @1.4::IWifiChip; @@ -127,4 +128,43 @@ interface IWifiChip extends @1.4::IWifiChip { * |WifiStatusCode.ERROR_INVALID_ARGS| */ setMultiStaUseCase(MultiStaUseCase useCase) generates (WifiStatus status); + + + /** + * Create bridged IWifiApIface. + * + * Depending on the mode the chip is configured in, the interface creation + * may fail (code: |ERROR_NOT_AVAILABLE|) if we've already reached the maximum + * allowed (specified in |ChipIfaceCombination|) number of ifaces of the AP + * type. + * + * @return status WifiStatus of the operation. + * Possible status codes: + * |WifiStatusCode.SUCCESS|, + * |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|, + * |WifiStatusCode.ERROR_NOT_SUPPORTED|, + * |WifiStatusCode.ERROR_NOT_AVAILABLE| + * @return iface HIDL interface object representing the iface if + * successful, null otherwise. + */ + createBridgedApIface() generates (WifiStatus status, IWifiApIface iface); + + /** + * Removes one of the instance on the AP Iface with the provided ifaceName and + * ifaceInstanceName. + * + * Use the API: removeApIface with brIfaceName in the V1_0::WifiChip.hal to remove bridge Iface. + * + * @param brIfaceName Name of the bridged AP iface. + * @param ifaceInstanceName Name of the instance. The empty instance is + * invalid. + * @return status WifiStatus of the operation. + * Possible status codes: + * |WifiStatusCode.SUCCESS|, + * |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|, + * |WifiStatusCode.ERROR_INVALID_ARGS|, + * |WifiStatusCode.ERROR_NOT_AVAILABLE| + */ + removeIfaceInstanceFromBridgedApIface(string brIfaceName, string ifaceInstanceName) + generates (WifiStatus status); }; diff --git a/wifi/1.5/default/wifi_chip.cpp b/wifi/1.5/default/wifi_chip.cpp index 1c238c8ec0..f5842fe934 100644 --- a/wifi/1.5/default/wifi_chip.cpp +++ b/wifi/1.5/default/wifi_chip.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -44,6 +45,7 @@ constexpr char kTombstoneFolderPath[] = "/data/vendor/tombstones/wifi/"; constexpr char kActiveWlanIfaceNameProperty[] = "wifi.active.interface"; constexpr char kNoActiveWlanIfaceNamePropertyValue[] = ""; constexpr unsigned kMaxWlanIfaces = 5; +constexpr char kApBridgeIfacePrefix[] = "ap_br_"; template void invalidateAndClear(std::vector>& ifaces, sp iface) { @@ -434,6 +436,13 @@ Return WifiChip::createApIface(createApIface_cb hidl_status_cb) { &WifiChip::createApIfaceInternal, hidl_status_cb); } +Return WifiChip::createBridgedApIface( + createBridgedApIface_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::createBridgedApIfaceInternal, + hidl_status_cb); +} + Return WifiChip::getApIfaceNames(getApIfaceNames_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, &WifiChip::getApIfaceNamesInternal, hidl_status_cb); @@ -453,6 +462,15 @@ Return WifiChip::removeApIface(const hidl_string& ifname, ifname); } +Return 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); +} + Return WifiChip::createNanIface(createNanIface_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, &WifiChip::createNanIfaceInternal, hidl_status_cb); @@ -693,6 +711,7 @@ Return WifiChip::setMultiStaUseCase( } void WifiChip::invalidateAndRemoveAllIfaces() { + invalidateAndClearBridgedApAll(); invalidateAndClearAll(ap_ifaces_); invalidateAndClearAll(nan_ifaces_); invalidateAndClearAll(p2p_ifaces_); @@ -861,20 +880,20 @@ WifiChip::requestFirmwareDebugDumpInternal() { return {createWifiStatus(WifiStatusCode::SUCCESS), firmware_dump}; } -std::pair> WifiChip::createApIfaceInternal() { - if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::AP)) { - return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; - } - std::string ifname = allocateApIfaceName(); - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->createVirtualInterface( - ifname, - hidl_struct_util::convertHidlIfaceTypeToLegacy(IfaceType::AP)); +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)); if (legacy_status != legacy_hal::WIFI_SUCCESS) { - LOG(ERROR) << "Failed to add interface: " << ifname << " " + LOG(ERROR) << "Failed to add interface: " << apVirtIf << " " << legacyErrorToString(legacy_status); - return {createWifiStatusFromLegacyError(legacy_status), {}}; + return createWifiStatusFromLegacyError(legacy_status); } + return createWifiStatus(WifiStatusCode::SUCCESS); +} + +sp WifiChip::newWifiApIface(std::string& ifname) { sp iface = new WifiApIface(ifname, legacy_hal_, iface_util_); ap_ifaces_.push_back(iface); for (const auto& callback : event_cb_handler_.getCallbacks()) { @@ -883,6 +902,60 @@ std::pair> WifiChip::createApIfaceInternal() { } } setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName()); + return iface; +} + +std::pair> WifiChip::createApIfaceInternal() { + if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::AP)) { + return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; + } + std::string ifname = allocateApIfaceName(); + WifiStatus status = createVirtualApInterface(ifname); + if (status.code != WifiStatusCode::SUCCESS) { + return {status, {}}; + } + sp iface = newWifiApIface(ifname); + return {createWifiStatus(WifiStatusCode::SUCCESS), iface}; +} + +std::pair> +WifiChip::createBridgedApIfaceInternal() { + if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::AP)) { + return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; + } + std::string br_ifname = kApBridgeIfacePrefix + allocateApIfaceName(); + std::vector ap_instances; + for (int i = 0; i < 2; i++) { + // TODO: b/173999527, it should use idx from 2 when STA+STA support, but + // need to check vendor support or not. + std::string ifaceInstanceName = allocateApOrStaIfaceName( + IfaceType::AP, isStaApConcurrencyAllowedInCurrentMode() ? 1 : 0); + WifiStatus status = createVirtualApInterface(ifaceInstanceName); + if (status.code != WifiStatusCode::SUCCESS) { + if (ap_instances.size() != 0) { + legacy_hal_.lock()->deleteVirtualInterface( + ap_instances.front()); + } + return {status, {}}; + } + ap_instances.push_back(ifaceInstanceName); + } + br_ifaces_ap_instances_[br_ifname] = ap_instances; + if (!iface_util_.lock()->createBridge(br_ifname)) { + LOG(ERROR) << "Failed createBridge - br_name=" << br_ifname.c_str(); + invalidateAndClearBridgedAp(br_ifname); + return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; + } + for (auto const& instance : ap_instances) { + // Bind ap instance interface to AP bridge + if (!iface_util_.lock()->addIfaceToBridge(br_ifname, instance)) { + LOG(ERROR) << "Failed add if to Bridge - if_name=" + << instance.c_str(); + invalidateAndClearBridgedAp(br_ifname); + return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; + } + } + sp iface = newWifiApIface(br_ifname); return {createWifiStatus(WifiStatusCode::SUCCESS), iface}; } @@ -913,12 +986,8 @@ 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); - 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); - } + // Clear the bridge interface and the iface instance. + invalidateAndClearBridgedAp(ifname); invalidateAndClear(ap_ifaces_, iface); for (const auto& callback : event_cb_handler_.getCallbacks()) { if (!callback->onIfaceRemoved(IfaceType::AP, ifname).isOk()) { @@ -929,6 +998,42 @@ WifiStatus WifiChip::removeApIfaceInternal(const std::string& ifname) { return createWifiStatus(WifiStatusCode::SUCCESS); } +WifiStatus WifiChip::removeIfaceInstanceFromBridgedApIfaceInternal( + const std::string& ifname, const std::string& ifInstanceName) { + legacy_hal::wifi_error legacy_status; + const auto iface = findUsingName(ap_ifaces_, ifname); + if (!iface.get() || !ifInstanceName.empty()) { + return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); + } + // Requires to remove one of the instance in bridge mode + for (auto const& it : br_ifaces_ap_instances_) { + if (it.first == ifname) { + for (auto const& iface : it.second) { + if (iface == ifInstanceName) { + if (!iface_util_.lock()->removeIfaceFromBridge(it.first, + iface)) { + LOG(ERROR) << "Failed to remove interface: " << iface + << " from " << ifname << ", error: " + << legacyErrorToString(legacy_status); + return createWifiStatus( + WifiStatusCode::ERROR_NOT_AVAILABLE); + } + legacy_status = + legacy_hal_.lock()->deleteVirtualInterface(iface); + if (legacy_status != legacy_hal::WIFI_SUCCESS) { + LOG(ERROR) << "Failed to del interface: " << iface + << " " << legacyErrorToString(legacy_status); + return createWifiStatusFromLegacyError(legacy_status); + } + } + } + break; + } + } + br_ifaces_ap_instances_.erase(ifInstanceName); + return createWifiStatus(WifiStatusCode::SUCCESS); +} + std::pair> WifiChip::createNanIfaceInternal() { if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::NAN)) { @@ -1653,6 +1758,7 @@ 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; if (findUsingName(ap_ifaces_, ifname)) continue; if (findUsingName(sta_ifaces_, ifname)) continue; return ifname; @@ -1727,6 +1833,48 @@ std::string WifiChip::getWlanIfaceNameWithType(IfaceType type, unsigned idx) { return getWlanIfaceName(idx); } +void WifiChip::invalidateAndClearBridgedApAll() { + for (auto const& it : br_ifaces_ap_instances_) { + for (auto const& iface : it.second) { + iface_util_.lock()->removeIfaceFromBridge(it.first, iface); + legacy_hal_.lock()->deleteVirtualInterface(iface); + } + iface_util_.lock()->deleteBridge(it.first); + } + br_ifaces_ap_instances_.clear(); +} + +void WifiChip::invalidateAndClearBridgedAp(const std::string& br_name) { + if (br_name.empty()) return; + // delete managed interfaces + for (auto const& it : br_ifaces_ap_instances_) { + if (it.first == br_name) { + for (auto const& iface : it.second) { + iface_util_.lock()->removeIfaceFromBridge(br_name, iface); + legacy_hal_.lock()->deleteVirtualInterface(iface); + } + iface_util_.lock()->deleteBridge(br_name); + br_ifaces_ap_instances_.erase(br_name); + break; + } + } + return; +} + +bool WifiChip::findUsingNameFromBridgedApInstances(const std::string& name) { + for (auto const& it : br_ifaces_ap_instances_) { + if (it.first == name) { + return true; + } + for (auto const& iface : it.second) { + if (iface == name) { + return true; + } + } + } + return false; +} + } // namespace implementation } // namespace V1_5 } // namespace wifi diff --git a/wifi/1.5/default/wifi_chip.h b/wifi/1.5/default/wifi_chip.h index 693d480bda..b7a9ac8e2b 100644 --- a/wifi/1.5/default/wifi_chip.h +++ b/wifi/1.5/default/wifi_chip.h @@ -94,11 +94,16 @@ class WifiChip : public V1_5::IWifiChip { Return requestFirmwareDebugDump( requestFirmwareDebugDump_cb hidl_status_cb) override; Return createApIface(createApIface_cb hidl_status_cb) override; + Return createBridgedApIface( + createBridgedApIface_cb hidl_status_cb) override; Return getApIfaceNames(getApIfaceNames_cb hidl_status_cb) override; Return getApIface(const hidl_string& ifname, getApIface_cb hidl_status_cb) override; Return removeApIface(const hidl_string& ifname, removeApIface_cb hidl_status_cb) override; + Return removeIfaceInstanceFromBridgedApIface( + const hidl_string& brIfaceName, const hidl_string& ifaceInstanceName, + removeIfaceInstanceFromBridgedApIface_cb hidl_status_cb) override; Return createNanIface(createNanIface_cb hidl_status_cb) override; Return getNanIfaceNames(getNanIfaceNames_cb hidl_status_cb) override; Return getNanIface(const hidl_string& ifname, @@ -192,11 +197,16 @@ class WifiChip : public V1_5::IWifiChip { requestDriverDebugDumpInternal(); std::pair> requestFirmwareDebugDumpInternal(); + sp newWifiApIface(std::string& ifname); + WifiStatus createVirtualApInterface(const std::string& apVirtIf); std::pair> createApIfaceInternal(); + std::pair> createBridgedApIfaceInternal(); std::pair> getApIfaceNamesInternal(); std::pair> getApIfaceInternal( const std::string& ifname); WifiStatus removeApIfaceInternal(const std::string& ifname); + WifiStatus removeIfaceInstanceFromBridgedApIfaceInternal( + const std::string& brIfaceName, const std::string& ifInstanceName); std::pair> createNanIfaceInternal(); std::pair> getNanIfaceNamesInternal(); std::pair> getNanIfaceInternal( @@ -272,6 +282,9 @@ class WifiChip : public V1_5::IWifiChip { std::string allocateStaIfaceName(); bool writeRingbufferFilesInternal(); std::string getWlanIfaceNameWithType(IfaceType type, unsigned idx); + void invalidateAndClearBridgedApAll(); + void invalidateAndClearBridgedAp(const std::string& br_name); + bool findUsingNameFromBridgedApInstances(const std::string& name); ChipId chip_id_; std::weak_ptr legacy_hal_; @@ -296,7 +309,7 @@ class WifiChip : public V1_5::IWifiChip { event_cb_handler_; const std::function subsystemCallbackHandler_; - + std::map> br_ifaces_ap_instances_; DISALLOW_COPY_AND_ASSIGN(WifiChip); }; -- GitLab From c476ff3857857cc1c62bc93b59846f480f87b547 Mon Sep 17 00:00:00 2001 From: Daniel Cardenas Date: Fri, 2 Mar 2018 17:10:45 -0800 Subject: [PATCH 303/790] Increase default timeout for changeStateIdletoExecute() from 100ms to 400ms Bug: 70933963 Test: vts-tradefed run vts -m VtsHalMediaOmxV1_0Host Change-Id: I2f01b5fcd72b03148750589a8eabbc8037f61e6f --- .../1.0/vts/functional/common/media_hidl_test_common.cpp | 2 +- .../omx/1.0/vts/functional/common/media_hidl_test_common.h | 2 ++ .../component/VtsHalMediaOmxV1_0TargetComponentTest.cpp | 6 ++---- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/media/omx/1.0/vts/functional/common/media_hidl_test_common.cpp b/media/omx/1.0/vts/functional/common/media_hidl_test_common.cpp index 29be2a09b3..f299e36f23 100644 --- a/media/omx/1.0/vts/functional/common/media_hidl_test_common.cpp +++ b/media/omx/1.0/vts/functional/common/media_hidl_test_common.cpp @@ -492,7 +492,7 @@ void changeStateIdletoExecute(sp omxNode, status = omxNode->sendCommand(toRawCommandType(OMX_CommandStateSet), OMX_StateExecuting); ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK); - status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT); + status = observer->dequeueMessage(&msg, RELAXED_TIMEOUT); ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK); ASSERT_EQ(msg.type, Message::Type::EVENT); ASSERT_EQ(msg.data.eventData.event, OMX_EventCmdComplete); diff --git a/media/omx/1.0/vts/functional/common/media_hidl_test_common.h b/media/omx/1.0/vts/functional/common/media_hidl_test_common.h index c276ad3829..42d9e2a5b1 100644 --- a/media/omx/1.0/vts/functional/common/media_hidl_test_common.h +++ b/media/omx/1.0/vts/functional/common/media_hidl_test_common.h @@ -41,6 +41,8 @@ /* As component is switching states (loaded<->idle<->execute), dequeueMessage() * expects the events to be received within this duration */ #define DEFAULT_TIMEOUT 150000 +// b/70933963 +#define RELAXED_TIMEOUT 400000 /* Time interval between successive Input/Output enqueues */ #define DEFAULT_TIMEOUT_Q 2000 /* While the component is amidst a process call, asynchronous commands like diff --git a/media/omx/1.0/vts/functional/component/VtsHalMediaOmxV1_0TargetComponentTest.cpp b/media/omx/1.0/vts/functional/component/VtsHalMediaOmxV1_0TargetComponentTest.cpp index 2223583740..1c1d39b4e0 100644 --- a/media/omx/1.0/vts/functional/component/VtsHalMediaOmxV1_0TargetComponentTest.cpp +++ b/media/omx/1.0/vts/functional/component/VtsHalMediaOmxV1_0TargetComponentTest.cpp @@ -1165,15 +1165,13 @@ TEST_F(ComponentHidlTest, PortEnableDisable_Execute) { ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK); // do not enable the port until all the buffers are supplied - status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, - &pBuffer[0], &pBuffer[1]); + status = observer->dequeueMessage(&msg, RELAXED_TIMEOUT, &pBuffer[0], &pBuffer[1]); ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::TIMED_OUT); ASSERT_NO_FATAL_FAILURE(allocatePortBuffers( omxNode, &pBuffer[i - portBase], i, portMode[i - portBase])); - status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, - &pBuffer[0], &pBuffer[1]); + status = observer->dequeueMessage(&msg, RELAXED_TIMEOUT, &pBuffer[0], &pBuffer[1]); ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK); ASSERT_EQ(msg.type, Message::Type::EVENT); ASSERT_EQ(msg.data.eventData.data1, OMX_CommandPortEnable); -- GitLab From a0ff4be4b38b0fdda25edabfbba700cd4feab085 Mon Sep 17 00:00:00 2001 From: Eric Laurent Date: Thu, 26 Nov 2020 20:12:55 +0100 Subject: [PATCH 304/790] audio HAL: add output flag indicating support for gapless transitions Add output profile flag AUDIO_OUTPUT_FLAG_GAPLESS_OFFLOAD to be used in conjunction with AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD to indicate that gapless transitions are supported when playing compressed audio. Bug: 158191844 Test: make Change-Id: Ifa551ff36d8571062cac3ad38f89be2f3addb960 --- audio/7.0/config/api/current.txt | 1 + audio/7.0/config/audio_policy_configuration.xsd | 1 + 2 files changed, 2 insertions(+) diff --git a/audio/7.0/config/api/current.txt b/audio/7.0/config/api/current.txt index 1da8b095bc..0b2e4a4d85 100644 --- a/audio/7.0/config/api/current.txt +++ b/audio/7.0/config/api/current.txt @@ -259,6 +259,7 @@ package android.audio.policy.configuration.V7_0 { enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_DIRECT; enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_DIRECT_PCM; enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_FAST; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_GAPLESS_OFFLOAD; enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_HW_AV_SYNC; enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO; enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_INCALL_MUSIC; diff --git a/audio/7.0/config/audio_policy_configuration.xsd b/audio/7.0/config/audio_policy_configuration.xsd index 56b3a27161..a735c6de39 100644 --- a/audio/7.0/config/audio_policy_configuration.xsd +++ b/audio/7.0/config/audio_policy_configuration.xsd @@ -181,6 +181,7 @@ + -- GitLab From 75915c31349cdb48ef695ec524f6549c75cc98d1 Mon Sep 17 00:00:00 2001 From: lesl Date: Mon, 30 Nov 2020 19:09:31 +0800 Subject: [PATCH 305/790] wifi: ignore SIGPIPE when dumping stats to dumpstate If dumpstate closes the reading end of the pipe (likely due to timeout) and wifi vendor hal attempts to write to the fd it received from dumpstate, it will receive sig 13 (SIGPIPE), and is then killed. We should protect wifi vendor hal from the abnormally behaved clients. Sync patch from ag/12321138. Reference from b/172972545 & b/161336019#comment29 Bug: 161336019 Bug: 172972545 Test: Manuel Test, Wifi works normally Change-Id: Ie7de040ac4320f83500c18e74e3c58d63b4df1b7 --- wifi/1.5/default/service.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/wifi/1.5/default/service.cpp b/wifi/1.5/default/service.cpp index 8539a37647..23e2b47ee4 100644 --- a/wifi/1.5/default/service.cpp +++ b/wifi/1.5/default/service.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -45,6 +46,7 @@ const bool kLazyService = false; #endif int main(int /*argc*/, char** argv) { + signal(SIGPIPE, SIG_IGN); android::base::InitLogging( argv, android::base::LogdLogger(android::base::SYSTEM)); LOG(INFO) << "Wifi Hal is booting up..."; -- GitLab From f14d9a0f8ed02bb06fc7c4d8484372209141881f Mon Sep 17 00:00:00 2001 From: Sunil Ravi Date: Sun, 8 Nov 2020 22:33:25 -0800 Subject: [PATCH 306/790] Wifi: DPP STA Enrollee-Responder mode Added below HIDL APIs for DPP STA Enrollee-Responder mode 1. API to start DPP in Enrollee-Responder mode 2. API to generate DPP bootstrap URI 3. API to stop DPP in Enrollee-Responder mode which internally remove the bootstrap and stop listen. Bug: 162686712 Test: VTS test Change-Id: I979b6a7a2fe90f48d478f48da73269fd3f5cb347 --- wifi/supplicant/1.4/ISupplicantStaIface.hal | 54 +++++++++++++++- .../1.4/ISupplicantStaIfaceCallback.hal | 8 ++- wifi/supplicant/1.4/ISupplicantStaNetwork.hal | 2 +- wifi/supplicant/1.4/types.hal | 62 +++++++++++++++--- .../supplicant_sta_iface_hidl_test.cpp | 64 +++++++++++++++++++ 5 files changed, 177 insertions(+), 13 deletions(-) diff --git a/wifi/supplicant/1.4/ISupplicantStaIface.hal b/wifi/supplicant/1.4/ISupplicantStaIface.hal index f9e4c9b696..7441ba5f2c 100644 --- a/wifi/supplicant/1.4/ISupplicantStaIface.hal +++ b/wifi/supplicant/1.4/ISupplicantStaIface.hal @@ -71,8 +71,7 @@ interface ISupplicantStaIface extends @1.3::ISupplicantStaIface { * |SupplicantStatusCode.FAILURE_UNKNOWN|, * |SupplicantStatusCode.FAILURE_IFACE_INVALID| */ - initiateVenueUrlAnqpQuery(MacAddress macAddress) - generates (SupplicantStatus status); + initiateVenueUrlAnqpQuery(MacAddress macAddress) generates (SupplicantStatus status); /** * Get wpa driver capabilities. @@ -84,4 +83,55 @@ interface ISupplicantStaIface extends @1.3::ISupplicantStaIface { */ getWpaDriverCapabilities_1_4() generates (SupplicantStatus status, bitfield driverCapabilitiesMask); + + /** + * Generates DPP bootstrap information: Bootstrap ID, DPP URI and listen + * channel for responder mode. + * + * @param MacAddress MAC address of the interface for the DPP operation. + * @param deviceInfo Device specific information. + * As per DPP Specification V1.0 section 5.2, + * allowed Range of ASCII characters in deviceInfo - %x20-7E + * semicolon is not allowed. + * @param DppCurve Elliptic curve cryptography type used to generate DPP + * public/private key pair. + * @return status of operation and bootstrap info. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_IFACE_INVALID|, + * |SupplicantStatusCode.FAILURE_UNKNOWN| + * |SupplicantStatusCode.FAILURE_UNSUPPORTED| + */ + generateDppBootstrapInfoForResponder(MacAddress macAddress, string deviceInfo, DppCurve curve) + generates (SupplicantStatus status, DppResponderBootstrapInfo bootstrapInfo); + + /** + * Start DPP in Enrollee-Responder mode. + * Framework must first call |generateDppBootstrapInfoForResponder| to generate + * the bootstrapping information: Bootstrap ID, DPP URI and the listen channel. + * Then call this API with derived listen channel to start listening for + * authentication request from Peer initiator. + * + * @param listenChannel DPP listen channel. + * @return status Status of the operation. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_UNKNOWN|, + * |SupplicantStatusCode.FAILURE_IFACE_INVALID| + * |SupplicantStatusCode.FAILURE_UNSUPPORTED| + */ + startDppEnrolleeResponder(uint32_t listenChannel) generates (SupplicantStatus status); + + /** + * Stop DPP Responder operation - Remove the bootstrap code and stop listening. + * + * @param ownBootstrapId Local device's URI ID obtained through + * |generateDppBootstrapInfoForResponder| call. + * @return status Status of the operation. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_IFACE_INVALID| + * |SupplicantStatusCode.FAILURE_UNSUPPORTED| + */ + stopDppResponder(uint32_t ownBootstrapId) generates (SupplicantStatus status); }; diff --git a/wifi/supplicant/1.4/ISupplicantStaIfaceCallback.hal b/wifi/supplicant/1.4/ISupplicantStaIfaceCallback.hal index 852696ddce..efcebdac00 100644 --- a/wifi/supplicant/1.4/ISupplicantStaIfaceCallback.hal +++ b/wifi/supplicant/1.4/ISupplicantStaIfaceCallback.hal @@ -40,8 +40,12 @@ interface ISupplicantStaIfaceCallback extends @1.3::ISupplicantStaIfaceCallback /** * Baseline information as defined in HAL 1.0. */ - @1.0::ISupplicantStaIfaceCallback.AnqpData V1_0; /* Container for v1.0 of this struct */ - vec venueUrl; /* Venue URL ANQP-element */ + @1.0::ISupplicantStaIfaceCallback.AnqpData V1_0; + + /* + * Container for v1.0 of this struct + */ + vec venueUrl; }; /** diff --git a/wifi/supplicant/1.4/ISupplicantStaNetwork.hal b/wifi/supplicant/1.4/ISupplicantStaNetwork.hal index 80beedf7f7..6bed5ab887 100644 --- a/wifi/supplicant/1.4/ISupplicantStaNetwork.hal +++ b/wifi/supplicant/1.4/ISupplicantStaNetwork.hal @@ -17,7 +17,7 @@ package android.hardware.wifi.supplicant@1.4; import @1.3::ISupplicantStaNetwork; -import @1.4::ISupplicantStaNetworkCallback; +import ISupplicantStaNetworkCallback; /** * Interface exposed by the supplicant for each station mode network diff --git a/wifi/supplicant/1.4/types.hal b/wifi/supplicant/1.4/types.hal index 18af8fe393..aec61c4121 100644 --- a/wifi/supplicant/1.4/types.hal +++ b/wifi/supplicant/1.4/types.hal @@ -18,6 +18,7 @@ package android.hardware.wifi.supplicant@1.4; import @1.0::SupplicantStatusCode; import @1.3::ConnectionCapabilities; +import @1.3::DppFailureCode; import @1.3::WpaDriverCapabilitiesMask; /** @@ -39,6 +40,29 @@ enum LegacyMode : uint32_t { G_MODE = 3, }; +/** + * DppFailureCode: Error codes for DPP (Easy Connect) + */ +enum DppFailureCode : @1.3::DppFailureCode { + /** + * Failure to generate a DPP URI. + */ + URI_GENERATION, +}; + +/** + * DppCurve: Elliptic curve cryptography type used to generate DPP + * public/private key pair. + */ +enum DppCurve : uint32_t { + PRIME256V1, + SECP384R1, + SECP521R1, + BRAINPOOLP256R1, + BRAINPOOLP384R1, + BRAINPOOLP512R1, +}; + /** * Connection Capabilities supported by current network and device */ @@ -47,6 +71,7 @@ struct ConnectionCapabilities { * Baseline information as defined in HAL 1.3. */ @1.3::ConnectionCapabilities V1_3; + /** * detailed network mode for legacy network */ @@ -64,13 +89,14 @@ enum SupplicantStatusCode : @1.0::SupplicantStatusCode { * Generic structure to return the status of any supplicant operation. */ struct SupplicantStatus { - SupplicantStatusCode code; - /** - * A vendor specific error message to provide more information beyond the - * status code. - * This will be used for debbuging purposes only. - */ - string debugMessage; + SupplicantStatusCode code; + + /** + * A vendor specific error message to provide more information beyond the + * status code. + * This will be used for debbuging purposes only. + */ + string debugMessage; }; /** @@ -78,7 +104,27 @@ struct SupplicantStatus { */ enum WpaDriverCapabilitiesMask : @1.3::WpaDriverCapabilitiesMask { /** - * */ SAE_PK = 1 << 2, }; + +/** + * DPP bootstrap info generated for responder mode operation + */ +struct DppResponderBootstrapInfo { + /** + * Generated bootstrap identifier + */ + uint32_t bootstrapId; + + /** + * The Wi-Fi channel that the DPP responder is listening on. + */ + uint32_t listenChannel; + + /** + * Bootstrapping URI per DPP specification, "section 5.2 Bootstrapping + * information", may contain listen channel, MAC address, public key, or other information. + */ + string uri; +}; diff --git a/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp index c0b5a70434..ccd469d4b3 100644 --- a/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp +++ b/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -45,7 +46,10 @@ using ::android::hardware::wifi::supplicant::V1_2::DppFailureCode; using ::android::hardware::wifi::supplicant::V1_2::DppNetRole; using ::android::hardware::wifi::supplicant::V1_2::DppProgressCode; using ::android::hardware::wifi::supplicant::V1_3::DppSuccessCode; +using ::android::hardware::wifi::supplicant::V1_3::ISupplicantStaNetwork; using ::android::hardware::wifi::supplicant::V1_4::ConnectionCapabilities; +using ::android::hardware::wifi::supplicant::V1_4::DppCurve; +using ::android::hardware::wifi::supplicant::V1_4::DppResponderBootstrapInfo; using ::android::hardware::wifi::supplicant::V1_4::ISupplicant; using ::android::hardware::wifi::supplicant::V1_4::ISupplicantStaIface; using ::android::hardware::wifi::supplicant::V1_4::ISupplicantStaIfaceCallback; @@ -74,6 +78,24 @@ class SupplicantStaIfaceHidlTest : public SupplicantHidlTestBaseV1_4 { sp sta_iface_; // MAC address to use for various tests. std::array mac_addr_; + + bool isDppSupported() { + uint32_t keyMgmtMask = 0; + + // We need to first get the key management capabilities from the device. + // If DPP is not supported, we just pass the test. + sta_iface_->getKeyMgmtCapabilities_1_3( + [&](const SupplicantStatus& status, uint32_t keyMgmtMaskInternal) { + EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code); + keyMgmtMask = keyMgmtMaskInternal; + }); + + if (!(keyMgmtMask & ISupplicantStaNetwork::KeyMgmtMask::DPP)) { + // DPP not supported + return false; + } + return true; + } }; class IfaceCallback : public ISupplicantStaIfaceCallback { @@ -255,6 +277,48 @@ TEST_P(SupplicantStaIfaceHidlTest, GetWpaDriverCapabilities) { }); } +/* + * StartDppEnrolleeResponder + */ +TEST_P(SupplicantStaIfaceHidlTest, StartDppEnrolleeResponder) { + // We need to first get the key management capabilities from the device. + // If DPP is not supported, we just pass the test. + if (!isDppSupported()) { + // DPP not supported + return; + } + + hidl_string deviceInfo = "DPP_Responder_Mode_VTS_Test"; + uint32_t bootstrap_id = 0; + uint32_t listen_channel = 0; + uint8_t mac_address[6] = {0x22, 0x33, 0x44, 0x55, 0x66, 0x77}; + + // Generate DPP bootstrap information + sta_iface_->generateDppBootstrapInfoForResponder( + mac_address, deviceInfo, DppCurve::PRIME256V1, + [&](const SupplicantStatusV1_4& status, + DppResponderBootstrapInfo bootstrapInfo) { + EXPECT_EQ(SupplicantStatusCodeV1_4::SUCCESS, status.code); + EXPECT_NE(-1, bootstrapInfo.bootstrapId); + EXPECT_NE(0, bootstrapInfo.bootstrapId); + bootstrap_id = bootstrapInfo.bootstrapId; + listen_channel = bootstrapInfo.listenChannel; + EXPECT_NE(0, bootstrapInfo.listenChannel); + }); + + // Start DPP as Enrollee-Responder. + sta_iface_->startDppEnrolleeResponder( + listen_channel, [&](const SupplicantStatusV1_4& status) { + EXPECT_EQ(SupplicantStatusCodeV1_4::SUCCESS, status.code); + }); + + // Stop DPP Enrollee-Responder mode, ie remove the URI and stop listen. + sta_iface_->stopDppResponder( + bootstrap_id, [&](const SupplicantStatusV1_4& status) { + EXPECT_EQ(SupplicantStatusCodeV1_4::SUCCESS, status.code); + }); +} + GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantStaIfaceHidlTest); INSTANTIATE_TEST_CASE_P( PerInstance, SupplicantStaIfaceHidlTest, -- GitLab From d594cd0a4d30081ab90983075e03769b00f13ab7 Mon Sep 17 00:00:00 2001 From: Slava Shklyaev Date: Mon, 30 Nov 2020 15:33:17 +0000 Subject: [PATCH 307/790] Fix a bug where 1.3 Device ignores 1.3 capabilities Bug: 170289677 Test: NNT_static --gtest_filter=PartitioningTest.Perf Change-Id: I476c7ab6ae807b4fd3ed27ec4d63aa6c04d0c7e1 --- .../1.2/utils/include/nnapi/hal/1.2/Device.h | 1 - neuralnetworks/1.2/utils/src/Device.cpp | 45 ++++++++++--------- neuralnetworks/1.3/utils/src/Device.cpp | 23 +++++++++- 3 files changed, 46 insertions(+), 23 deletions(-) diff --git a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Device.h b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Device.h index bbd534335b..a68830d86e 100644 --- a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Device.h +++ b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Device.h @@ -37,7 +37,6 @@ namespace android::hardware::neuralnetworks::V1_2::utils { nn::GeneralResult initVersionString(V1_2::IDevice* device); nn::GeneralResult initDeviceType(V1_2::IDevice* device); nn::GeneralResult> initExtensions(V1_2::IDevice* device); -nn::GeneralResult initCapabilities(V1_2::IDevice* device); nn::GeneralResult> initNumberOfCacheFilesNeeded( V1_2::IDevice* device); diff --git a/neuralnetworks/1.2/utils/src/Device.cpp b/neuralnetworks/1.2/utils/src/Device.cpp index 517d61f85c..a9e537752e 100644 --- a/neuralnetworks/1.2/utils/src/Device.cpp +++ b/neuralnetworks/1.2/utils/src/Device.cpp @@ -42,6 +42,30 @@ #include namespace android::hardware::neuralnetworks::V1_2::utils { +namespace { + +nn::GeneralResult initCapabilities(V1_2::IDevice* device) { + CHECK(device != nullptr); + + nn::GeneralResult result = NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) + << "uninitialized"; + const auto cb = [&result](V1_0::ErrorStatus status, const Capabilities& capabilities) { + if (status != V1_0::ErrorStatus::NONE) { + const auto canonical = + validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + result = NN_ERROR(canonical) << "getCapabilities_1_2 failed with " << toString(status); + } else { + result = validatedConvertToCanonical(capabilities); + } + }; + + const auto ret = device->getCapabilities_1_2(cb); + NN_TRY(hal::utils::handleTransportError(ret)); + + return result; +} + +} // namespace nn::GeneralResult initVersionString(V1_2::IDevice* device) { CHECK(device != nullptr); @@ -106,27 +130,6 @@ nn::GeneralResult> initExtensions(V1_2::IDevice* devi return result; } -nn::GeneralResult initCapabilities(V1_2::IDevice* device) { - CHECK(device != nullptr); - - nn::GeneralResult result = NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) - << "uninitialized"; - const auto cb = [&result](V1_0::ErrorStatus status, const Capabilities& capabilities) { - if (status != V1_0::ErrorStatus::NONE) { - const auto canonical = - validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); - result = NN_ERROR(canonical) << "getCapabilities_1_2 failed with " << toString(status); - } else { - result = validatedConvertToCanonical(capabilities); - } - }; - - const auto ret = device->getCapabilities_1_2(cb); - NN_TRY(hal::utils::handleTransportError(ret)); - - return result; -} - nn::GeneralResult> initNumberOfCacheFilesNeeded( V1_2::IDevice* device) { CHECK(device != nullptr); diff --git a/neuralnetworks/1.3/utils/src/Device.cpp b/neuralnetworks/1.3/utils/src/Device.cpp index 5e3d5c2ce2..0fa244d891 100644 --- a/neuralnetworks/1.3/utils/src/Device.cpp +++ b/neuralnetworks/1.3/utils/src/Device.cpp @@ -71,6 +71,27 @@ nn::GeneralResult convert( return NN_TRY(std::move(result)); } +nn::GeneralResult initCapabilities(V1_3::IDevice* device) { + CHECK(device != nullptr); + + nn::GeneralResult result = NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) + << "uninitialized"; + const auto cb = [&result](ErrorStatus status, const Capabilities& capabilities) { + if (status != ErrorStatus::NONE) { + const auto canonical = + validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + result = NN_ERROR(canonical) << "getCapabilities_1_3 failed with " << toString(status); + } else { + result = validatedConvertToCanonical(capabilities); + } + }; + + const auto ret = device->getCapabilities_1_3(cb); + NN_TRY(hal::utils::handleTransportError(ret)); + + return result; +} + } // namespace nn::GeneralResult> Device::create(std::string name, @@ -87,7 +108,7 @@ nn::GeneralResult> Device::create(std::string name auto versionString = NN_TRY(V1_2::utils::initVersionString(device.get())); const auto deviceType = NN_TRY(V1_2::utils::initDeviceType(device.get())); auto extensions = NN_TRY(V1_2::utils::initExtensions(device.get())); - auto capabilities = NN_TRY(V1_2::utils::initCapabilities(device.get())); + auto capabilities = NN_TRY(initCapabilities(device.get())); const auto numberOfCacheFilesNeeded = NN_TRY(V1_2::utils::initNumberOfCacheFilesNeeded(device.get())); -- GitLab From 7128d3ac8b033c35083c7521d55d9ed4590f3a88 Mon Sep 17 00:00:00 2001 From: Mingming Cai Date: Tue, 1 Dec 2020 14:04:38 -0800 Subject: [PATCH 308/790] Add an empty line to match AOSP Bug: 170771377 Test: make Change-Id: I1ec8caca20de9c3c190869229fd2c746900838c3 --- radio/1.6/types.hal | 1 + 1 file changed, 1 insertion(+) diff --git a/radio/1.6/types.hal b/radio/1.6/types.hal index 2cba9157f2..556d8a322e 100644 --- a/radio/1.6/types.hal +++ b/radio/1.6/types.hal @@ -22,6 +22,7 @@ import @1.4::DataCallFailCause; import @1.4::DataConnActiveStatus; import @1.4::PdpProtocolType; import @1.5::LinkAddress; + import android.hidl.safe_union@1.0::Monostate; struct QosBandwidth { -- GitLab From 39e88771f25c10e14c10a94c753dd0974f5d4227 Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Mon, 23 Nov 2020 17:37:30 -0800 Subject: [PATCH 309/790] Add new AcquiredInfo constants Bug: 173711478 Test: m android.hardware.biometrics.face-update-api Change-Id: Iac8a6f423744782883f141e0012e037630fb43a7 --- .../biometrics/face/AcquiredInfo.aidl | 4 +++ .../biometrics/face/AcquiredInfo.aidl | 26 ++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl index 88c066c617..a05fad9da9 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl @@ -42,4 +42,8 @@ enum AcquiredInfo { SENSOR_DIRTY = 21, VENDOR = 22, FIRST_FRAME_RECEIVED = 23, + DARK_GLASSES_DETECTED = 24, + FACE_COVERING_DETECTED = 25, + EYES_NOT_VISIBLE = 26, + MOUTH_NOT_VISIBLE = 27, } diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl index 5897cdcc1a..56a600f824 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl @@ -218,6 +218,30 @@ enum AcquiredInfo { /** * The first frame from the camera has been received. */ - FIRST_FRAME_RECEIVED = 23 + FIRST_FRAME_RECEIVED = 23, + + /** + * Dark glasses detected. This can be useful for providing relevant feedback to the user and + * enabling an alternative authentication logic if the implementation supports it. + */ + DARK_GLASSES_DETECTED = 24, + + /** + * A face mask or face covering detected. This can be useful for providing relevant feedback to + * the user and enabling an alternative authentication logic if the implementation supports it. + */ + FACE_COVERING_DETECTED = 25, + + /** + * Either one or both eyes are not visible in the frame. Prefer to use DARK_GLASSES_DETECTED if + * the eyes are not visible due to dark glasses. + */ + EYES_NOT_VISIBLE = 26, + + /** + * The mouth is not visible in the frame. Prefer to use MASK_DETECTED if the mouth is not + * visible due to a mask. + */ + MOUTH_NOT_VISIBLE = 27, } -- GitLab From 420c4fc3a7c03fab377b5f6724372dbc98d90189 Mon Sep 17 00:00:00 2001 From: lesl Date: Mon, 23 Nov 2020 19:33:04 +0800 Subject: [PATCH 310/790] wifi: Add resetFactoryMac support (AP+AP Part 3) Support HAL API:resetToFactoryMacAddress to reset the MAC to factory MAC on each instances in IWifiApIface. AP+AP Part 3 includes: 1. Support resetToFactoryMac in IWifiApIface.Hal. 2. Vts support for non bridged API. 3. Framework support resetToFactoryMac in bridged Ap. Test: atest -c VtsHalWifiApV1_5TargetTest Test: atest -c VtsHalWifiApV1_4TargetTest Test: atest -c VtsHalWifiApV1_0TargetTest Bug: 162686273 Change-Id: Ic7f2c0d6f1d8bf46fabfbc874d5f2b74068e43cc --- wifi/1.5/Android.bp | 1 + wifi/1.5/IWifiApIface.hal | 40 ++++++ wifi/1.5/IWifiChip.hal | 2 +- wifi/1.5/default/wifi_ap_iface.cpp | 62 ++++++++-- wifi/1.5/default/wifi_ap_iface.h | 13 +- wifi/1.5/default/wifi_chip.cpp | 16 ++- wifi/1.5/default/wifi_chip.h | 7 +- wifi/1.5/vts/functional/Android.bp | 23 ++++ .../vts/functional/wifi_chip_hidl_ap_test.cpp | 115 ++++++++++++++++++ 9 files changed, 260 insertions(+), 19 deletions(-) create mode 100644 wifi/1.5/IWifiApIface.hal create mode 100644 wifi/1.5/vts/functional/wifi_chip_hidl_ap_test.cpp diff --git a/wifi/1.5/Android.bp b/wifi/1.5/Android.bp index 5a62a3a832..e2c38cecc0 100644 --- a/wifi/1.5/Android.bp +++ b/wifi/1.5/Android.bp @@ -7,6 +7,7 @@ hidl_interface { "types.hal", "IWifi.hal", "IWifiChip.hal", + "IWifiApIface.hal", "IWifiNanIface.hal", "IWifiNanIfaceEventCallback.hal", "IWifiStaIface.hal", diff --git a/wifi/1.5/IWifiApIface.hal b/wifi/1.5/IWifiApIface.hal new file mode 100644 index 0000000000..9625a6b712 --- /dev/null +++ b/wifi/1.5/IWifiApIface.hal @@ -0,0 +1,40 @@ +/* + * 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. + */ + +package android.hardware.wifi@1.5; + +import @1.4::IWifiApIface; +import @1.0::MacAddress; +import @1.0::WifiStatus; + +/** + * Represents a network interface in AP mode. + * + * This can be obtained through @1.0::IWifiChip.getApIface() and casting + * IWifiApIface up to 1.5. + */ +interface IWifiApIface extends @1.4::IWifiApIface { + /** + * Reset all of the AP interfaces MAC address to the factory MAC address. + * + * @return status WifiStatus of the operation + * Possible status codes: + * |WifiStatusCode.SUCCESS|, + * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|, + * |WifiStatusCode.ERROR_UNKNOWN| + */ + resetToFactoryMacAddress() generates (WifiStatus status); +}; diff --git a/wifi/1.5/IWifiChip.hal b/wifi/1.5/IWifiChip.hal index 7cf81b572a..2702759c41 100644 --- a/wifi/1.5/IWifiChip.hal +++ b/wifi/1.5/IWifiChip.hal @@ -17,7 +17,7 @@ package android.hardware.wifi@1.5; import @1.0::WifiStatus; -import @1.0::IWifiApIface; +import @1.5::IWifiApIface; import @1.0::IWifiIface; import @1.3::IWifiChip; import @1.4::IWifiChip; diff --git a/wifi/1.5/default/wifi_ap_iface.cpp b/wifi/1.5/default/wifi_ap_iface.cpp index 04e382a659..d98aa4579a 100644 --- a/wifi/1.5/default/wifi_ap_iface.cpp +++ b/wifi/1.5/default/wifi_ap_iface.cpp @@ -29,10 +29,11 @@ namespace implementation { using hidl_return_util::validateAndCall; WifiApIface::WifiApIface( - const std::string& ifname, + const std::string& ifname, const std::vector& instances, const std::weak_ptr legacy_hal, const std::weak_ptr iface_util) : ifname_(ifname), + instances_(instances), legacy_hal_(legacy_hal), iface_util_(iface_util), is_valid_(true) {} @@ -81,6 +82,14 @@ Return WifiApIface::getFactoryMacAddress( getFactoryMacAddress_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, &WifiApIface::getFactoryMacAddressInternal, + hidl_status_cb, + instances_.size() > 0 ? instances_[0] : ifname_); +} + +Return WifiApIface::resetToFactoryMacAddress( + resetToFactoryMacAddress_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiApIface::resetToFactoryMacAddressInternal, hidl_status_cb); } @@ -94,8 +103,8 @@ std::pair WifiApIface::getTypeInternal() { WifiStatus WifiApIface::setCountryCodeInternal( const std::array& code) { - legacy_hal::wifi_error legacy_status = - legacy_hal_.lock()->setCountryCode(ifname_, code); + legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->setCountryCode( + instances_.size() > 0 ? instances_[0] : ifname_, code); return createWifiStatusFromLegacyError(legacy_status); } @@ -107,13 +116,30 @@ WifiApIface::getValidFrequenciesForBandInternal(V1_0::WifiBand band) { std::vector valid_frequencies; std::tie(legacy_status, valid_frequencies) = legacy_hal_.lock()->getValidFrequenciesForBand( - ifname_, hidl_struct_util::convertHidlWifiBandToLegacy(band)); + instances_.size() > 0 ? instances_[0] : ifname_, + hidl_struct_util::convertHidlWifiBandToLegacy(band)); return {createWifiStatusFromLegacyError(legacy_status), valid_frequencies}; } WifiStatus WifiApIface::setMacAddressInternal( const std::array& mac) { - bool status = iface_util_.lock()->setMacAddress(ifname_, mac); + bool status; + // Support random MAC up to 2 interfaces + if (instances_.size() == 2) { + int rbyte = 1; + for (auto const& intf : instances_) { + std::array rmac = mac; + // reverse the bits to avoid clision + rmac[rbyte] = 0xff - rmac[rbyte]; + status = iface_util_.lock()->setMacAddress(intf, rmac); + if (!status) { + LOG(INFO) << "Failed to set random mac address on " << intf; + } + rbyte++; + } + } else { + status = iface_util_.lock()->setMacAddress(ifname_, mac); + } if (!status) { return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); } @@ -121,15 +147,37 @@ WifiStatus WifiApIface::setMacAddressInternal( } std::pair> -WifiApIface::getFactoryMacAddressInternal() { +WifiApIface::getFactoryMacAddressInternal(const std::string& ifaceName) { std::array mac = - iface_util_.lock()->getFactoryMacAddress(ifname_); + 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}; } + +WifiStatus WifiApIface::resetToFactoryMacAddressInternal() { + std::pair> getMacResult; + if (instances_.size() == 2) { + for (auto const& intf : instances_) { + getMacResult = getFactoryMacAddressInternal(intf); + LOG(DEBUG) << "Reset MAC to factory MAC on " << intf; + if (getMacResult.first.code != WifiStatusCode::SUCCESS || + !iface_util_.lock()->setMacAddress(intf, getMacResult.second)) { + return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); + } + } + } else { + getMacResult = getFactoryMacAddressInternal(ifname_); + LOG(DEBUG) << "Reset MAC to factory MAC on " << ifname_; + if (getMacResult.first.code != WifiStatusCode::SUCCESS || + !iface_util_.lock()->setMacAddress(ifname_, getMacResult.second)) { + return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); + } + } + return createWifiStatus(WifiStatusCode::SUCCESS); +} } // namespace implementation } // namespace V1_5 } // namespace wifi diff --git a/wifi/1.5/default/wifi_ap_iface.h b/wifi/1.5/default/wifi_ap_iface.h index 48b444a66c..02fb2d8edc 100644 --- a/wifi/1.5/default/wifi_ap_iface.h +++ b/wifi/1.5/default/wifi_ap_iface.h @@ -18,7 +18,7 @@ #define WIFI_AP_IFACE_H_ #include -#include +#include #include "wifi_iface_util.h" #include "wifi_legacy_hal.h" @@ -33,9 +33,10 @@ using namespace android::hardware::wifi::V1_0; /** * HIDL interface object used to control a AP Iface instance. */ -class WifiApIface : public V1_4::IWifiApIface { +class WifiApIface : public V1_5::IWifiApIface { public: WifiApIface(const std::string& ifname, + const std::vector& instances, const std::weak_ptr legacy_hal, const std::weak_ptr iface_util); // Refer to |WifiChip::invalidate()|. @@ -55,6 +56,8 @@ class WifiApIface : public V1_4::IWifiApIface { setMacAddress_cb hidl_status_cb) override; Return getFactoryMacAddress( getFactoryMacAddress_cb hidl_status_cb) override; + Return resetToFactoryMacAddress( + resetToFactoryMacAddress_cb hidl_status_cb) override; private: // Corresponding worker functions for the HIDL methods. @@ -64,10 +67,12 @@ class WifiApIface : public V1_4::IWifiApIface { std::pair> getValidFrequenciesForBandInternal(V1_0::WifiBand band); WifiStatus setMacAddressInternal(const std::array& mac); - std::pair> - getFactoryMacAddressInternal(); + std::pair> getFactoryMacAddressInternal( + const std::string& ifaceName); + WifiStatus resetToFactoryMacAddressInternal(); std::string ifname_; + std::vector instances_; std::weak_ptr legacy_hal_; std::weak_ptr iface_util_; bool is_valid_; diff --git a/wifi/1.5/default/wifi_chip.cpp b/wifi/1.5/default/wifi_chip.cpp index f5842fe934..5d9d315e40 100644 --- a/wifi/1.5/default/wifi_chip.cpp +++ b/wifi/1.5/default/wifi_chip.cpp @@ -894,7 +894,14 @@ WifiStatus WifiChip::createVirtualApInterface(const std::string& apVirtIf) { } sp WifiChip::newWifiApIface(std::string& ifname) { - sp iface = new WifiApIface(ifname, legacy_hal_, iface_util_); + std::vector ap_instances; + for (auto const& it : br_ifaces_ap_instances_) { + if (it.first == ifname) { + ap_instances = it.second; + } + } + sp 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()) { @@ -905,7 +912,8 @@ sp WifiChip::newWifiApIface(std::string& ifname) { return iface; } -std::pair> WifiChip::createApIfaceInternal() { +std::pair> +WifiChip::createApIfaceInternal() { if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::AP)) { return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; } @@ -918,7 +926,7 @@ std::pair> WifiChip::createApIfaceInternal() { return {createWifiStatus(WifiStatusCode::SUCCESS), iface}; } -std::pair> +std::pair> WifiChip::createBridgedApIfaceInternal() { if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::AP)) { return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; @@ -967,7 +975,7 @@ WifiChip::getApIfaceNamesInternal() { return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(ap_ifaces_)}; } -std::pair> WifiChip::getApIfaceInternal( +std::pair> WifiChip::getApIfaceInternal( const std::string& ifname) { const auto iface = findUsingName(ap_ifaces_, ifname); if (!iface.get()) { diff --git a/wifi/1.5/default/wifi_chip.h b/wifi/1.5/default/wifi_chip.h index b7a9ac8e2b..70b221d26b 100644 --- a/wifi/1.5/default/wifi_chip.h +++ b/wifi/1.5/default/wifi_chip.h @@ -199,10 +199,11 @@ class WifiChip : public V1_5::IWifiChip { requestFirmwareDebugDumpInternal(); sp newWifiApIface(std::string& ifname); WifiStatus createVirtualApInterface(const std::string& apVirtIf); - std::pair> createApIfaceInternal(); - std::pair> createBridgedApIfaceInternal(); + std::pair> createApIfaceInternal(); + std::pair> + createBridgedApIfaceInternal(); std::pair> getApIfaceNamesInternal(); - std::pair> getApIfaceInternal( + std::pair> getApIfaceInternal( const std::string& ifname); WifiStatus removeApIfaceInternal(const std::string& ifname); WifiStatus removeIfaceInstanceFromBridgedApIfaceInternal( diff --git a/wifi/1.5/vts/functional/Android.bp b/wifi/1.5/vts/functional/Android.bp index eb595c9082..2d8b412abb 100644 --- a/wifi/1.5/vts/functional/Android.bp +++ b/wifi/1.5/vts/functional/Android.bp @@ -60,3 +60,26 @@ cc_test { "vts", ], } + +// SoftAP-specific tests, similar to VtsHalWifiApV1_0TargetTest. +cc_test { + name: "VtsHalWifiApV1_5TargetTest", + defaults: ["VtsHalTargetTestDefaults"], + srcs: [ + "wifi_chip_hidl_ap_test.cpp", + ], + static_libs: [ + "VtsHalWifiV1_0TargetTestUtil", + "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", + "libwifi-system-iface", + ], + test_suites: [ + "general-tests", + "vts", + ], +} diff --git a/wifi/1.5/vts/functional/wifi_chip_hidl_ap_test.cpp b/wifi/1.5/vts/functional/wifi_chip_hidl_ap_test.cpp new file mode 100644 index 0000000000..395d317065 --- /dev/null +++ b/wifi/1.5/vts/functional/wifi_chip_hidl_ap_test.cpp @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#undef NAN // NAN is defined in bionic/libc/include/math.h:38 + +#include +#include +#include +#include +#include +#include +#include + +#include "wifi_hidl_call_util.h" +#include "wifi_hidl_test_utils.h" + +using ::android::sp; +using ::android::hardware::hidl_string; +using ::android::hardware::hidl_vec; +using ::android::hardware::Return; +using ::android::hardware::Void; +using ::android::hardware::wifi::V1_0::ChipModeId; +using ::android::hardware::wifi::V1_0::IfaceType; +using ::android::hardware::wifi::V1_0::IWifiIface; +using ::android::hardware::wifi::V1_0::WifiDebugRingBufferStatus; +using ::android::hardware::wifi::V1_0::WifiStatus; +using ::android::hardware::wifi::V1_0::WifiStatusCode; +using ::android::hardware::wifi::V1_4::IWifiChipEventCallback; +using ::android::hardware::wifi::V1_5::IWifiApIface; +using ::android::hardware::wifi::V1_5::IWifiChip; + +/** + * Fixture for IWifiChip tests that are conditioned on SoftAP support. + */ +class WifiChipHidlTest : public ::testing::TestWithParam { + public: + virtual void SetUp() override { + // Make sure to start with a clean state + stopWifi(GetInstanceName()); + + wifi_chip_ = IWifiChip::castFrom(getWifiChip(GetInstanceName())); + ASSERT_NE(nullptr, wifi_chip_.get()); + } + + virtual void TearDown() override { stopWifi(GetInstanceName()); } + + protected: + // Helper function to configure the Chip in one of the supported modes. + // Most of the non-mode-configuration-related methods require chip + // to be first configured. + ChipModeId configureChipForIfaceType(IfaceType type, bool expectSuccess) { + ChipModeId mode_id; + EXPECT_EQ(expectSuccess, + configureChipToSupportIfaceType(wifi_chip_, type, &mode_id)); + return mode_id; + } + + WifiStatusCode createApIface(sp* ap_iface) { + configureChipForIfaceType(IfaceType::AP, true); + const auto& status_and_iface = HIDL_INVOKE(wifi_chip_, createApIface); + *ap_iface = IWifiApIface::castFrom(status_and_iface.second); + return status_and_iface.first.code; + } + + WifiStatusCode createBridgedApIface(sp* ap_iface) { + configureChipForIfaceType(IfaceType::AP, true); + const auto& status_and_iface = + HIDL_INVOKE(wifi_chip_, createBridgedApIface); + *ap_iface = status_and_iface.second; + return status_and_iface.first.code; + } + + sp wifi_chip_; + + private: + std::string GetInstanceName() { return GetParam(); } +}; + +// TODO: b/173999527. Add test for bridged API. + +/* + * resetToFactoryMacAddress + */ +TEST_P(WifiChipHidlTest, resetToFactoryMacAddressTest) { + sp wifi_ap_iface; + const auto& status_code = createApIface(&wifi_ap_iface); + if (status_code != WifiStatusCode::SUCCESS) { + EXPECT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED, status_code); + } + const auto& status = HIDL_INVOKE(wifi_ap_iface, resetToFactoryMacAddress); + EXPECT_EQ(WifiStatusCode::SUCCESS, status.code); +} + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiChipHidlTest); +INSTANTIATE_TEST_SUITE_P( + PerInstance, WifiChipHidlTest, + testing::ValuesIn(android::hardware::getAllHalInstanceNames( + ::android::hardware::wifi::V1_5::IWifi::descriptor)), + android::hardware::PrintInstanceNameToString); -- GitLab From e852ece374065aa9f881be6f9f27726fc2ea0f8e Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Tue, 1 Dec 2020 14:55:10 -0800 Subject: [PATCH 311/790] Add Tuner VTS test assets and configure the push file preparer Test: atest VtsHalTvTunerV1_0TargetTest Test: atest VtsHalTvTunerV1_1TargetTest Bug: 161745584 Change-Id: I5fe55bc846ef8b4b3336ea65b2efb63c2de829ac --- tv/tuner/1.0/vts/functional/Android.bp | 3 ++ tv/tuner/1.0/vts/functional/AndroidTest.xml | 34 ++++++++++++++++++ tv/tuner/1.1/default/Filter.cpp | 3 +- tv/tuner/1.1/vts/functional/Android.bp | 3 ++ tv/tuner/1.1/vts/functional/AndroidTest.xml | 33 +++++++++++++++++ .../VtsHalTvTunerV1_1TargetTest.cpp | 2 +- tv/tuner/assets/Android.bp | 17 +++++++++ tv/tuner/assets/tuner_frontend_input.es | Bin 0 -> 597465 bytes tv/tuner/assets/tuner_frontend_input.ts | Bin 0 -> 673792 bytes 9 files changed, 93 insertions(+), 2 deletions(-) create mode 100644 tv/tuner/1.0/vts/functional/AndroidTest.xml create mode 100644 tv/tuner/1.1/vts/functional/AndroidTest.xml create mode 100644 tv/tuner/assets/Android.bp create mode 100644 tv/tuner/assets/tuner_frontend_input.es create mode 100644 tv/tuner/assets/tuner_frontend_input.ts diff --git a/tv/tuner/1.0/vts/functional/Android.bp b/tv/tuner/1.0/vts/functional/Android.bp index 17659153cf..7b130ea00b 100644 --- a/tv/tuner/1.0/vts/functional/Android.bp +++ b/tv/tuner/1.0/vts/functional/Android.bp @@ -41,6 +41,9 @@ cc_test { shared_libs: [ "libbinder", ], + data: [ + ":tuner_frontend_input_ts", + ], test_suites: [ "general-tests", "vts", diff --git a/tv/tuner/1.0/vts/functional/AndroidTest.xml b/tv/tuner/1.0/vts/functional/AndroidTest.xml new file mode 100644 index 0000000000..3a2db27440 --- /dev/null +++ b/tv/tuner/1.0/vts/functional/AndroidTest.xml @@ -0,0 +1,34 @@ + + + + diff --git a/tv/tuner/1.1/default/Filter.cpp b/tv/tuner/1.1/default/Filter.cpp index 4fa1746dbe..6b2413c97e 100644 --- a/tv/tuner/1.1/default/Filter.cpp +++ b/tv/tuner/1.1/default/Filter.cpp @@ -165,8 +165,9 @@ Return Filter::flush() { Return Filter::releaseAvHandle(const hidl_handle& avMemory, uint64_t avDataId) { ALOGV("%s", __FUNCTION__); - if ((avMemory.getNativeHandle()->numFds > 0) && + if (mSharedAvMemHandle != NULL && avMemory != NULL && (mSharedAvMemHandle.getNativeHandle()->numFds > 0) && + (avMemory.getNativeHandle()->numFds > 0) && (sameFile(avMemory.getNativeHandle()->data[0], mSharedAvMemHandle.getNativeHandle()->data[0]))) { freeSharedAvHandle(); diff --git a/tv/tuner/1.1/vts/functional/Android.bp b/tv/tuner/1.1/vts/functional/Android.bp index 1fc36f10e5..73cd0578c1 100644 --- a/tv/tuner/1.1/vts/functional/Android.bp +++ b/tv/tuner/1.1/vts/functional/Android.bp @@ -40,6 +40,9 @@ cc_test { shared_libs: [ "libbinder", ], + data: [ + ":tuner_frontend_input_es", + ], test_suites: [ "general-tests", "vts", diff --git a/tv/tuner/1.1/vts/functional/AndroidTest.xml b/tv/tuner/1.1/vts/functional/AndroidTest.xml new file mode 100644 index 0000000000..28f95db8a3 --- /dev/null +++ b/tv/tuner/1.1/vts/functional/AndroidTest.xml @@ -0,0 +1,33 @@ + + + + diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp index e87276275a..2dcb9a14e5 100644 --- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp @@ -179,7 +179,7 @@ TEST_P(TunerFilterHidlTest, ConfigIpFilterInDemuxWithCid) { configSingleFilterInDemuxTest(filterArray[IP_IP0], frontendArray[DVBT]); } -TEST_P(TunerFilterHidlTest, ReonfigFilterToReceiveStartId) { +TEST_P(TunerFilterHidlTest, ReconfigFilterToReceiveStartId) { description("Recofigure and restart a filter to test start id."); // TODO use parameterized tests reconfigSingleFilterInDemuxTest(filterArray[TS_VIDEO0], filterArray[TS_VIDEO1], diff --git a/tv/tuner/assets/Android.bp b/tv/tuner/assets/Android.bp new file mode 100644 index 0000000000..b58b645515 --- /dev/null +++ b/tv/tuner/assets/Android.bp @@ -0,0 +1,17 @@ +genrule { + name: "tuner_frontend_input_es", + srcs: ["tuner_frontend_input.es"], + out: [ + "test.es", + ], + cmd: "cp -f $(in) $(genDir)/test.es", +} + +genrule { + name: "tuner_frontend_input_ts", + srcs: ["tuner_frontend_input.ts"], + out: [ + "segment000000.ts", + ], + cmd: "cp -f $(in) $(genDir)/segment000000.ts", +} diff --git a/tv/tuner/assets/tuner_frontend_input.es b/tv/tuner/assets/tuner_frontend_input.es new file mode 100644 index 0000000000000000000000000000000000000000..b53c957350c063eeb631d744a41d41340c13b044 GIT binary patch literal 597465 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 z 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%0A)aKOgs`85=~Hf@ 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

    V3#3OB1 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 E;VPuLtSLh^md|X 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 z zyMK-8OPRupOPNNOYzvTcDN&@O^QAAPl_+7cjyxajF)LRJvwIRx0UYZ&#j@x8%N=B= zJu}JKINij<(FX0f-^6JYDcMZH1+Rra8`@GV2dK6tHQ>)U;{#Y{YEvC7pIdC7bfT*w zq&d+@Ie~ryBPqdx=|6irAUk6~u~*r%OWRhu@@z3Pfp*zJ9Fiu`ucV(zW9x|WenNi{ zWpR;Q37=Kr&vuBUiNEaWN^WwKM0sYZ04HqL+4Rxx-)1Sg#?5C52&#o}GKmX>3XPuF z;^j|c9S9-|BBF!SF|RXR#6KoC*|aj1i@&gpm3SI0*eCFusY`oJlIu&MyQ(;bEW)r# zSd_33+Uj;4Z~yJwyCs;D?%?bixh)Y1df$h_j`xZSxlD%2C0$?X*R$6_cBa5tRvH2T z&(!7n$4*Umc4D;RM>ffGv+ByL)r2K3VX{Tzgq{UHm5C0b5iVzfT}Dd^h88N@3zmmn z;nt5zAdUHWUL`#%u|GrA@D62jiCs|he34e+i^TwhG7G^e zg}ST8b{@4K{wo@U&h6qAuP4k?4jeWmSEZ|qI(`!~90TDF zCMOBd@XJc0k?jOf`UKAocGF(*vh%M;_8-7rPBNm2o-jT8HMAIL%GBj5=Phh~ROx=K zdTT|uEWU6*Vkb$#&i<~t(`w$ZNLBQeTS%X2V$nF}va5WZ!#y^-BL&11CMB`^x4(!f zdzLDPO|ziS8HGf7Frxsbo&{YT@ts#)A}#^{)W#7f`<7c2el#iuYO}%e>ca*?FCzD^O`QTu7w) z?X?WJ#q3JA*l}*wc3ewBumcc-9x~yOd>gm7IYZy3H4`v>$bT`B5_J2%hEf~{s&%8B z_*~_T@>=l_WpVH=z^hXu{9*Yp@zAEW&{4virl<58g69-9AuEsVlfWqM{OoAJwZ0MJ z=o<+kqh@&4TW|*Xmb5HGfzR(MfYECg@&?&iL8~+xg22R)v-s4%Ttp`^@kc@Fd&WsN z=8jdttX;Q7yNI(V;-rgJ)5SOqR%$+e>zG-KHEtGlTUOLs{YR7yq|IiN+AQbQP`aFd zZhQ(;lchvQiinj8jVZ2E?pg65SGFUz_!++j*Sb zVd3LN!xpk-;8dM&!SaE&<`FTwRj4HU(8JU)S}3+=uL3uGH8=$wKHa$3{+_Jn8cLby z;RwjiR;)VE;+vUOCuzURy=u2M{5aGz-m3nRzJ|BW0M=4Q)CeAW-`y5d<3$zfiNfD6 zU;Wy24q3M7j(Br@z-e<$=^lQ8n0(yY=3H}1cSde3U+Wgd+i0i4h91|P44z+Pz|YT} z;&2;C9s^(7R3_&h^J||#8u7=!KSk%hAxyJ9-USwAfNW)vEeW-vZOMG%eBIMG=($s=Z{bQ*6zzhyjNH0>y~A#TT0RAvf(xixg6y6SeqGbWp@{a)K; z0A0i6s`ZApvMr3VZ_37o#g^nsJ0J1a!6IUFyIOUE_vs%lF^u=5?gxq1HkH7OsbNRH zm!}SwrTSBEHibdfxY-L@zx)nUd0Z#3ov}6bMeecnprU_U2g7Fx3Xq+nq5ss)nx`4p zNRs%l2ROlJYmYaYON!@s}S&x8h!k6AnSf{6y_OSJgPq;!U^> z*{2n5*i5~tw{2O*V?kZPTgCA`tTGRiQ1@Hhh)FnChSW)NB#Oh{yzRLfNvkt8YIw0; z#`8}TqP-m zQ>1NdPGk*`dW9>XR}kqY?{;zIodw6Cx&6<0lHZU|?Hijgs#a3f2-j}@OdQU_w9wWN zlzt+vHzHTA++Z&H_N8g$9(;95%3JMxuCpu2vf!Q+y8$}BUgDCOl*5>yGrnXN&fVjY zLv>V_xS_(=`*ZVQmgLscoZA+ATvrr=smgQKr?w)-1I+ZVo-vkm zi?QY^#4RhYo5>Jj`4OJL*Q)wdnJKsH%UQJ0=eMs%un#cFZ`NEXz^UHpJxw1BNJuR6 zRtfbVe?t6`ytvTsohAMhZu4+1^UC>m=d4>VsxVtbPsK>p?|d#9ZRwP#dHwa()YThz zP59^wKI9*~p+9+c*(avAW|)LN{8zfHqTb2Giy^B!=*J4=4e*56{cA3gi_95~Vazo| zznHol%U*r_bH{@9B2SO@J5*8K`%yR4Vi%kt5FYzD=I;&V7-gn+D>SYyoknIyn8oK-3sDlrDQ&g-+Pb@Co z7AG7hJs|C;Y$S2v3Y>kUUIO5Bk-2egah+K6Z^QH7<|n@(FkBR&2qyqtid|pL*jaDO z0wXmy$Vdn#cMXC{<3)DF8qs@LYyP04R3`!iYC?;0DsFt z+O%J%6DJ+>Qi!JkKtCHC(sf@eRQ`@{W zcg0E==?kwDBw`5OZM@%_BO$y*Tt&NHt{Q0|ni%<0Hc1BAqJ<}?S_`Cn7^73=s`K~3!YEs6OW(=i+hq@theU%s|T zMxbkStu5aFNTKT7LDvgiurs3cFJjAE5&#|Q?j^%OnM}3pB8_#u@j%5vIUNKCGl_^8 zrO?v#|Bt%&42!DUx_?C1;SJBuNq^=NttJBxeL9OMxIDk`yE;l7nOr zR5BDuk{rYWirT%=_dVx)x9`{YK40J4-KT!RL#R<}uf6u1bBsBrPyKn- zf0^88s>U;I#odF?EajS9A4OFh5$zdKh(|CR2v}^uhsNdcWeew0^!@I*1ya`S@gcw zrk&m1YyU{p6LKSb6n)x`aQRZ!NdCg8P4~|R?0Tabb&XN#jab{Wf-cN~MvXU$K~Txf z52&BITiI-qZ6JjW0ARESnkTI8SB<4k92CTiAr%o*z%_QIu0XO&xjvTo{aADP*wwle zt0pHn)%=9g%hr{%-GqjTo)wC;Y4uvm;|bzjCKmj@Yg{8e#nPDfYa#8POSiJ=Jog&1 zG(has9_)h^Tmp&@5awJkpw{^r<M@+%h@H8pdVo0AiIa1_>Q}A^RuT{Va-IFv$h3t>d8HO2#oFFc!0VEy5IqF_Je zSARivu6?!F2#B3-OWhN{E95DT0B$$U?gpFy)-MMj9E)h>l)MC6od)rk(CEO{e>qyo zK>Ru?Knz$v)PU4;70MYHy{GNAWY$0lM6eW9ZU_qCRXd0YF&NIzUTz-r7Qc_tCAL;p z<_6_HUNFZ+Ca-O@aK!O0rx2@(IX6XrG5{dd!|_!M*#Y5(Li1;F_Cw|u_{+F^Em#tB z+87ZymorJnmEGzzIWd{lXY@}K|32?Q?DSVIH+^t8xVsMbfA0bOZQ4uFWdexi!hW_$ z_blt4b<($|wap5deN%@JJn z-ZHT7t9GMIVj3+noU=B0R{dL1ONV2$Mo$?8G-5(@qNnxlVd(0eJ%zWg13g;0CSoxI z#@D!MfGfE=d~8Mf&lNc+Na{&CLx$aG0;2t%jrrPyN9^n;+(}M7oF5Us2?JXYnSQoC z1`w4zSqK5!g%BfpG2krwaV>vC>G+}=}cP;d|yf248hL%e)F__A7_W74cxX{|W(+3b6wh`?tXa;umZ*UB&E zx|(tL-erlSqx%LAU)&{AvI=iF3jkX&AlkJJ>kM;S+LCs!&c8q>2|o!mMNJR8-6)+u zZ2A4Dzq;yILNYXr>^L+Z;mUL83yB2AuGuxQ=8S9B^LPg#2JEGW1vLFlZnp?%2XN=# zZiCpF#5jJ&deTY+lZC#tRC_CCt(PzDcSjaYeXz2pqMrh45+v5S z@D*3@Bg~hQoqlaL{Ul{&(8>}y+{Q29oz&F^kLcZ|Mi9HK^#4pO1_n&Nlasn28|=2* z1av(YJDCI!I&-0JU}&f9EG#vQVdZKVFKy!)q0_3FG+Q@{|ykOvvo4uZJfQ5f#DHE?Jy z&)&I-AKsd@vc(x)I%WHdARdUhC-G*a5dP%QU!AZ75?t1JcQhDRWFs;6vs z0;oO5L}u_5@89Zw@kv|Y$NoC2XZz1m^D4hgctpuAd6{(Vp@YL-fQ9Ab_30I#=G*bd zdToREe>gu`;WVD7;Q-pcMRzW%*%E0eiVDeoN>Ig0$IMOp;-a0w+uS^5OMTEI!3_1h zYgKe0g8p)BGAP_vYa>LLB6T3wFnGDKbcimV-W<#@^XuN(x)t{2i5Jh;@An~&{tUNa z+tuU|!mPwqXTHvUZh8jxxov4B7 zl*U9z_MYWU(ayik%6A+gBr>w%`1r6fnC8>{mYVa46k|B-CmAL~h0wq~{Kngpg@OL> zODvY$h0pr+e>9z7Sg%DS>#L@TG|T7M@CwZ*hBiEy?ia4;q6D$i94DnA^ihgAvu*XQ*^>t(Il|U7KKN`-Ko?4*-DfMKG`z6eyJvY{&lmGzS{FZedx51)1 z_lS{qq(+ZUt^!f_qva5U$J-sVTUF6djH5+x%ZCJ(pO5n|Q+wokD8-N;JXI>{RAke9 zjjv3*>7P;)=0TuURvFBV#X+h!yw96!2uBz0R;cp%4kdh{E{o>eLc_<%ijyli?D?tCE^V7l?eK=-gH!nNm5}) zml;(Ws!*owh6wlBHb4#K<~4A*{hJR-Gxq2u^~^OZq-Esze=zn;1B4|v4(@+3khaRZ z!4h_}T5l<9^EOerY~6rhfx)U*h^iM?nT-F0c8BV>yw*Moa>Y{g>``NfP4Y~y_p~1& zyP|$>Xoyy3d}p*WZU*eb_V7iY4z9+#w@jeH)1F7=>ig15 zvHCDP6L76Iu@T!c3x7VNM;z-%*$?e|GPCep@RxJV&2ZxDkLUukd9vpZzk2t_)>j_w zyR-NO-et6J?5VNNFoC9 zZZhSRr*|85(}4rGc^E-qQPuIC^fOtm+zc=2Qy62v(yx&FLe?SfH%#CAWxEZM-6S?= zpuQz3G`h34N&Fmwb6cMP&o>sAv}O#$GrlFD(F#isCL7cq&Q^4k1{bSj=EJ6Dsx1<) z{py1Zr7~U~sfUPEs!+)(*n`*^e697A%wY_jrl;opT5n#ImxNH&-$30=5T;;!Jazi+ z`9Oe=nmj8hy&?n~qj8X*=z|Qlnv*G83bt(YkIl%;{4?_{EU#cMvoDZ=AkHV6Susc^%-rLSMK@}xBmJZh@BDV zB{uD5F+KK|q?4Na^Lw=IA*T%1Qb>wd6VpqfPZyjQy{cX(D?Fgg-%XEXm&y<%JAW)F z{7YwHp?|#i0b>B__LuoNkCTR)5u9cSnIVQPQm51KNybR!>r&!i_)y&!g`j;qDtLWn`mCF0T^DBxJcHg_V6;RsG9S2|SVZJiMidSmZlAg=ZHpwGyH0k=* za4P+Ss%fr!M4jyZyXs#&!=L*G{Iu(a)XwTM4A}vL}$~cF+{rP5m$&Dlvo+ zw%a2!2es6conK;xot~1G`syx87s54ZTq z&HkXcjSjq8GiIBsz5~+9UXUHW09}2Pa|3m3V8axsK|~gnowU94HM=v>k(jcbF{ldEbLCQ^B-;y5PsmI6{o-IY=1=0~aw?3I!a93c0C#V#%rt6<~M-qPwR! zBXu$=2!!!4r5_ZMH(T%MJefqZA!l=_i73TgrbaUvO2AclrE=?SuUS zn?Ym3YcU%X4UmdHY6)QJm-p_pe&)fcmxhvl3)*A#W{`E?8F09FXBKd4)`hTG+T0z7 zl}3)vpLhw@0{AeX{G zwQxV!@yzCta!3O(j*_Mlv{B@U+vBFv-4H<;hJ1nhNxwu)hj)2n+#J8skW+Yv4M~;# zT*G2RNT>Ca!2qxfyUs|;u&uT>Z_^$vB&RAXBcb~++otu7;8Xy?vcx&Ncv+LjS7}go z8N$uR2JWPR*Io4x$sdDWVP*ornd3Zfct(o;-1?-)>qCw~-$@;+jt|E3-=H1l=d+|8 z!orpaS4qrH3-DLNFY zF;0fRp#$&u4%<^?dV7{K-l?~{ZvXHZT2~bXJ9sK;Rfs>XhD?Iemuzg{uVm&LwpW`W zb?&9Q8`|DnND2Ty9hxGCTzarw0Nb*U6R9V!<|KDxMkpXNVD}kDBd6~~0@aQ^+N(~-`!o!GH?Tq!edqycbu{ls`9&26O*eoD+ zs;(Rx{_l9WT5~|xwBlF$uuaE;`9lFRzFkCU9_5WE@vJ}UcV%rfX3CyhPL zC)BwGbV|_Dsc810JSbLvFcV>pC9?HZDv7g|aybrC(E$@5MHIcB&`(TFyspZeD zJCK9x?(X|ZF_3(L2JY%cEtinf*x`E&>qoLivxHH0s9SGbpWvR8EpJ#NSPp-IxkfL} z+P*vIfxmp^f->jf)~pYjgm0}JBU1^Kp}bhXd!7SdyU?lJs@F#yMtee&o$(in-!_>I z-dEEcFwa1~ro)N;(EpyY!#9btu4gvoCxr*|(GT>{%SDPwjffFCQUz#xAB>yupb)QB zLh^VBIg{SIfZuWf;n1po#2lt6EksdZQCh)zgB1O8_sKczyBUcU-;a3aFZuQTiS~Cn zie=hA8!9vlOlZXO)A~!M$$i`{*1j1^`0H#%ND~iBYe9baHF^t^hTxUs<{_QW6mK|D z+g8!phqgQ9$2aOLW(E~}qqd;^E1{$Wi~6yIrD#W=e(=QYPA^g44pM$cj&24E$P-(z z#BKI7I(D*HoA>V?m@-?Km1jM4;jX$9-dk1$W6I-jdCFqQQ)ct1-AhX3(P}&bIJM_!l%=@&P}Am1bv4Hdc~?4gyH)(U8Jz9m z?wexrinaI$YfqO07lq_M8CdJ2234%;7ROXFgcj7YX(Pt>in&gWrou5}+Gm8JcwWso zFP-*k>H;0S!q^J?-$yNhi+VbETn1gfP_@W$m(=f)@!!=+5c}=g|6)Az|Ejy>|A$}t zyP^ulGYnVp45sCuc!mM?uknl({eku%>8wldY2K{!^~m}zVK!;Vb%})lOQcS~2D-Uk zy`Me_O?rsH43&0Sl5vST*1yHcN!11Va(GQK%L<*_vA~!~*^p{Kd6C2?Ir>NNGooa% zFmpd)8|VjVVQ0ChVQHZ@I^|9SWnICg6Rm}hVB~?9v6n&;38yi2JtAj{S;R?NvBksX z<>`Zm)Q7daPkDPNjdH?9L?gn%b!S8?#;|#YdPYdHj*~Uzt`0;yQoRl0(SZTUzZOiy z!46N&gU=q_#K%!ssmkA<$~N1@8}4G^I>!`FG4Dv47gql+ef}c$>4b; z98Td`h%ZcA%B`|(#)KdsC&m35^yEB_&u=QAPt)=-)emC3lNwcKJ|r@_4WHl?N>7X@ zSGb=(t(Es=iHd6xJ{mtUISeIQBV{=AO7I&=QN&`uV8D=`F@KK`maM~i;A)xqeNM&{QdE2?tSR8OT` znb|YsV8DvAN>-f$$~7?mopJN0P+aW}jDw#QYvwz_1*Ecqv9vWZM8A47`~#;Qdz#Y^ z*PrNr!wZ_G&#v|EpDnj*@9(BA@sbsSs3Ai?OK_)>JaJBBx23l7H^?KiK)xU4is{zF zuE6(_xi&STU#DZ!y~!H#v4a+NBG61z)|_%X>^X>CHu!(vekY9J_dce>sMjw(%o1sd z9DLC&=`0OZZ^R=G=ft=ehi0PYEmtpI^Cx~}Que~hkP?mi{=GytOyl?>0qG3xceyJa z$3*R4Iu4OP`(9-KU-y0ZZyiUyb-lRtm4xH!8TZfABk=0WtC=d79~=MS?UkeZ_Z=k{ zwE`hBD?SRf>=v{WW!XO{(^_;4Ht~Ibta}THuEVX@D-lnqDobzy$w6B9*ZiztLjT@3 z9%wG^t0*5-)oT2_4n%1^{9fr-@IjxOu!pw@hRBpzB6S4Uoz#fVR%RVPuV(7#ckdBs z!+$`w4~GL!l4zMdmH={grq3lu%Mf;FKt(*JL^wFG@K2(FyqffKjvX~BqEW9{p~H%y zdTd1=qK-$SIl`IimpaI5D!lF4fQ2-=N726Dxnd-os*|k-0CCxWeJqMNjO+DySa6cr zm}loAfeb%XYmny-nRwTD!_z`t+n4V@rJt)rh)h~)#X*N|$?N zvBcPqz1sM^RiK7>tNJ+L0tv&-cK%7YgzSq{2i&NsLdtc3JJFs5J;`qskn@(&J&kWC?u@thimi2C-8B z-4*hna);A_{|*^UbXvw@mXt!MKK4jT5NKjrdNO;+k}hRm+ZgNL3)B_5F-q{dhW}ej zYRrI0^U9}cl1=uVZ3UUwq7xw&JWr!KI1p=KA=M6g^50K)*m!@Zt8jHVFmyh<|GnW* z@sq8n16+;Z$j+CoxXx>8L=|l>kfFWT1JJ3pAa=@kI!Cp01cE5;!E)5C-g4y<)Sr$2 zTbabP2TjeLEu(osk%p1_OLy-ZgGjtpJY0-C92_r#z%HG+;#s(d$%btN*y*saXPBV==P*I`;7j4;mZ6UAC)D_FzQd0`8<7!6Cp0 z@6bX8n7*(C-C^8Z;PBg$sp(d{m>m(iQRK{|BtZyQEZLtu=!=k&iO7ui z=|=H}T~7#JXOH%9OP)hO(_mZ6Phk$l5B|O(!4sz^2#k;jtQ2b;f$pCiRHm@b_SPG$ z*MJg&ed9^>12LX`qe`|^FKujkD$ahh=vnJvOW?GzGl!doVju>HohFiQ zB7fWSvwzjl&n7tm*?;JH{<__w<)*@_T!5~8TCm559Jv9ykE1Eh8^D;DnK1{4#KLIN zhuMy^JTEeQ5<$!eJ6vAAF`yfD;CD2Et-l=O22(W@kIIMz4Z`fircK6b&u-vPQ7Y*T zeISe~iX_p3D0}JbW?r75b#C__JFC*+>DE07HeJGhaDq_5Fcibd0{n2aBIrEm!=mTw2!&PO(J@ZvrnaY!zukja*(K{b8W=|uV}CAgfWJHJY(Qv zppNgFKWNh%Z0s%sIoIOrs(JVNQsngB_dXbr*Esfij8Mi1-1Hjcz7cQXB{w0~canjr zyEX6nDL$3A`Eocu)h&Y)FJlSczm?W+IdtsT~G#DDt8Z81K3FB<7bDQte&(-ccvLg^@ovg^z4ySdJ6e|r`2@G zL+Od+CkOfPyGO-&<6#c^Uw@LEGVLIdW=R#CF(Q!HIOQ;>IsL;LPD{{dEl}6`oU7cU9@XucvZzDN+NX=> zxhu;X(ZNeSs&x-*V1d1Im?>NFEV}8h_{6&W%L*;#wu?qweE3x>dj091yK@saYkuqF zfBeJi*+|fgX-j-d@&P}0KcWC~TSgdY~ zm3~Td^SnB}{J8|1D6APtVW6Kp&m?q~s9|o+85Q`$ zXB+QC-sf#ZTcUPm&d0-XW0dWlT@%?2 zt%lLzoAnCV)on}7PYOAP^9FJeDsQsF?DD^ZkwiVgK=r?bT&V=s^G(1%LbHQ1rXkqw>D-^HYtDnK zs^TSp^iu{qYR;{tAdHSjfq+Fv1OuWiftsR&KxWgcY3VS#VkWf_>=VJ1qmx?)n7{Ay z;Zc;2KxPLBtT->^O)dgwvWr{F2?X}2JI*e|^L?D&xo-dZW=ROHI}_*vyECh=RR8kT zY^CLua1*}=)66Izwc1;Syg!tb^a8ZO$~naNBG(v6%gL{jj4T~OXfb~53VrqT`Q5M9 z7&^MX-&}nvDTH0{&E*KJ47Q7#Dw|%*Jhc;G290H;? zQplerfllt=1Q(jJ0Dy`9NSRf9hnp4e*Vq^^Muwle(dC25{cHtQ$05~)5yMp0Y${Kd zs*Vb)9Jn)?{(hIvPU2zMm4^#+CTp+*6MV#kEoS{!*4rqA6p$p_4iIRed})3e7 zNF8HeFaQK2QaEU?8w?5@$KH|_kouqdxoMa<%x=3=b|llNuMs%l@mMbUQ3&hk%Reer$#5Jw?ZoYNw~rB7skId01^#nKl!Y{Q8E--FuAyj- zK2FplOCY+8v?2Ci?7ffew{NuSK-6Hs z<0(*Uc|`_vd6T7HRmtx)gmZfjy6_giviqF&;bA*UOII#6J^x^k^#K&o5-vQ!EVFuf z@uD!Cr4}&{xpaDg{iAJ8_ge)3+eqy8lGjySKj&Ppsnwk;n+ugA`cA#Nbm@;{8i+@z z4P%kUY36i&4w43@JOnSZiSLX?{M@p6|H^~~hCdo+$O>0N$D-+1Kwg{j--2t6)%C9s~PKyI3g)1L`1tbIF}=KjO5#y!J3E$E`!LMCkQ{)lhTS3^R79 z0&G(7DVO6SsQci4Cx43vfMV^FrA9J5d7=4m;?TqhuT%lv z!%2an5qYojV)qBCOAF6kQVVm# z#5Hw4M}3F-zd??3yqvjiZxJ(sXvMe@)MeR}T)O=s*hVm=q1xQ~5&zu_#60wF(slFF zg>$bbPUx2r@9MlV;k-HfKDwhUSg9+Pra8!68Hj>o3VDFSs*O#5HCcAwwI6f^GTw~c zw`3)JSk6K06cD)S{h^{IqUMws{<;s;E44D$?eryH34fFK*p3#WzBlV3$Iu%lTN`sw zP#aZ4ZMl>2*JUE=!SH8WhV{2xFuhA?fb+srH|6B$)y!qWB~JK4T4PL+U&Cn6cp@;L z$~qs%d_PI{NxV)(22*3;^{j!iyou$W?$eG6M6NOJy?H?r&U!qHm}h;@N|%{O2jx+y zip4iJB@9Y#eU-bTt=|l3z?Kq|B2R46Mlp)aZS4 z0&`9a)?CtLx!zr?;E1Nm{l3#ZLx(3COK3&ZjxAq$kx)`*csKss;f>ALL3bdbNm@YPfaS=`#xI}ZxIzc(>3AzVFeSzx09nT!cH3S_L`m;bN|V%c1zBp7 z0uaNH&?V2$wHHBm;z8_GMu9GRekc`Gg{jubG@Z&qT{e zOnY`Zo`uY;P;FA8S*(zt{PhhbDBQP!(B!WjC`-9YTr!50|Z1k02T zSa;AdDTbGN1WrCgS^_tzI&A8q-? zgY9uh_POUeCQTK|Y10MXI^SMJ4~U&+T0wM+Qw-Vp=vi2v53Fya>IO}Fp+fOGp^fAy zlx2Mqws&d$kTY!qza*U&YA5rMn4y3xupw|jKYW&#J^o}x<`Jj0_%S9nNX3!jHW62l z8_-^kK7WlRezu&O?p9`56!TIk0kY}=fpOF z*lC4H!(rn?WQc|sHl-O~Ny9X{6Vi_c+)0)AG}mh~s)Y4sBb8+FDu*I)58J+1bAQ zr0^)mS?VW+Pyj&|i3a_0EqsPR;oZ;&3FJe+Bo{IO_6K}ObsSk0v z*&ro`#LHx#o!kbJGIcf2v1cURQ{OU}{vczr=lvdI3TMqbDeU;-Y249jD~q6jW2 z!6_awr4{wr%&yxYc6xfv+$D}CrJGEN#)sJ>#+%c_-4pwV$cI5XVK zQN$SR%o&qzV6VLPbE3(AqVBvYe~06}*eTmguZNzsic{jWR;TuO1(j8jedZvqT9&ni z?pN1GqDMN@9Qh zT#ja?*u8uB%M{BWqdAQR9>0{$xAvx>o^QWb>qaO43VlGtKz!ME3z6w-dU?0g|~07W*{*tKaDHTboNN|<0{79T71%qcY5b;MpjP*7)@=%&)=s7`V*TguF%ApUkwmv3)F|Gl+JpL5nR*g z0Gm-?6b(5Y?E}%2%;{Oh0>A8c9Dr!*3jv3_`Z90iXJJ5`Kq_pKaAuEv*w}6+atEQ) zXNnFj_NO8Q|3o;ezc2SCuo3m&iEe(Ej=+4C`6^$d(4%_^k>vnD=K1q?I>Pp z7-+EY589#YseBq^1+eN!i{DOQmC@gkx(l{n?mVKpTrH%lmzn!#j- z8;QsU>EUp-SdCkkOij5jwMvI{(fr@U`!V5XL`D?0AK=JO6El;Y=xLn2U@Bc>%dUU ziEp~dy-FA2Eu8GbZow~@dUz!{mUqt@=aEiXg?|_kIEbAT)U5nix>s0!trrU}KMIh^w#? zL%qyKoSNlrD9w}pFLzPgg0Vj9%VSqPh=^H1qEE7lEX;(|XK(UwH;+WUZ1Z08rs^*-bJ)Re$+~u&1S@)w=Kb`tOcF)?AkjgD#D-et+u3?I>gEVAbwQ=N}zyuL|lSf zpQfR&8ca*fZBgI5aWJ2D7cs5&kt6^>w=p=uew(GG#=QWslixT#YxE!pla{m>6!oOO zF#?Qet%vM}!7|L&OFX}`(mSnn3^Jqvq0gQMi&YvK=`U(Z$CpE6ll3Ls6Pf>_p;^Sy}gk5sjf6j7VwdhAD%kzrkz|0 z?8h0buDJb9b3p7AV5$>=;-8P1E@Ct4n^>CjSUkZ2EEqblJa% zhhWeu7%HQAa9E`^)*^a*AZZVXmvNje6m$V^ov1uM;n=_{RG8sQ6DrMRv*z+2nIjbC1!AYfexQ`pfj>H)34hg; zbZ&WhfbWKG9a1^j!p9vW^tg#1Cgggyw={%zw#g#bzgDw(=5qc~(w!BPZ_aQ7Nc~lo zBWDMm(6rw~9)*pCDE+)}*c3c3E0{V);4wT6760~;yc?RKVm8CWPB_vN4l^2=I7=hP{i`eN6goOSmIR~`d`d{>QTKxNvFCGL z&Scj~p6UnBjM|nM8MKOn*r~>VVO#5;Kl}G!_(K5Lktr9m4xq*Dib_tm#hbbVl|Nj2 zdJbJu_6M4W%_K0i0zXz_Hn( z_(<((1pjSdbuyo5g7(PLN?pYN0lDoscL9&*PnXwNd4%=?+Cl%m^4s<|xTphBJ zzlt>5#$tsqg&Mxp-MvuzWfBq*(HNOw$yCVHK_p>R>Ftue(k>AyGCOhQIZDliD9r@+ zGsmZ=Yp6P}$F0;q!D$@sTZD61oAa?_I{tW%W%UVDe+?KV`DFQp;6p_V z>UiVukWv9Z$i@9&oi^iW&qfYV){<@ub(bq5L^efjfL)!B#+r2n4-r*gO7e;jAUT7w z9Rg6n-wrP&<)cb1)Ng_L^-qQSJwFz0< z>w9r1ItOTF|B%?yZ5#fQjC%#p0kPABwY5D!`e58JM;*Dq(BbX*$1Z2*{8IcOGese1 z#ZA%X1pLJs} zsO5gI+>hw8F5zl_`t-bv2x7`UBW4;fb-+V`JO*=|eN^yCe6}-}=uQb;el&uwy{uqq zHRy}AiDiZlhQVEjn^HDZ69iV+OdQh%Az>be9%b>{vxr+gI!BDMO$oyfk6afKBu0)efuG2( zANhm1&TGS1a=dkqP=9VKJ|= zEFPx)QbuI#1UBu^5RV||(TmM*(%1jV`t%Pd=N;)^>#HpuB^7f6fN`u z+Jtkpgm#5561jT&cJjH-gPv5(?El@&>@c{ypToR z!otEN9^oLkUooiYD9HT;PwQ@!xNcomKgIY*x^7Vgdka4{Hk%tU#0U-hJ!yIz9WIWa zg4{f@U6AbT_(Mjk@B-u8c$mC(Khm^%eJqqKQWHbK9wEpb$^Swe`8&pBfqKcn#5v;l zJaH{7ptVL1jPA2V3#xFdXg6&iVq$((`sx`PK5KUsVuEodX>)YXO)&ZdzuBJ88U9J8 zo;!aLx4P3`#a#c5wD{Dlhf4A5!<-e8=J+E*QF~Fz`$}}qVKRci7{OnR<3BIpZ^;-K zM@nC5P*#=xXix~O|HP9)a{n4nE?@B<^quh{JQ@5ia*3<{@EX74LC`xypHnn*K|a5FWcdM$yC_$!gjJ-p%BFxW*S(hTZ70BfCjAs_C;p|%w5vznGl0)U$8 z?ytxHFrkpYoqHFy7WDzd&P=!VP})KUuPE%J$DI%fR?b}9F!)CFtxIWc3ZTno>kri+ zt?q<}ejllZqw&C&=(%>_S_O%a0#Cl)C8IO1_yOx?vG6 za^^|RcJ{v2y&w#tcCwz94XQrm5OO5ZGIHo3q>e6tC<|GKqsjX4x^E(0ajowUC*8$g zy{e1L3Sq>5AAUXm90@%32@uSDz={s(kxFU^UDECHenOIC!blckNezH-mqPva#4~{R z8D=%$n3AlHNQbSBS(mRBlc4$km`I>W(Gp^A;CqxnxW@OO%XY9=9>h+zNYQaErb)ON ztt~evJNcA9E#?5vaNS_3aj~HNF}l~}JtL2({54m9xXSD%(dEG&#IaT=K|y*8_Q1UE zeejUn!8&B*=xx9^ZnVCcTlO*(>T=mKJ2wD5n-C)IgA^hss$4IQl)g1a`0awK4y~VWEtbZJ8n+~( zA6ff@))9;e5Yg9O!V>4@V2==l{66eg2M4Cx=~>c-@%03jlpInER?ch0uSd&=HsDP< zi!R+H@Yr%OVzDkpg!;S(ICrD;9viW<$M)PW_kyXYEf#6ZR4$@+MDWN@RG$>(?8DjI zcq!o6@$0P@uj^kg)8p~pcvO(Xo0t`%HqjmJi7RcA-d3o6S3TY~s$aMpX^sENL)W96 zaAU!Gn5<8g`7r_9J;K6ZtF}8KTE^VvHJ2r@HZW~Ts(bsUOxEM*IXLKIh~Eq0zM2U` zv2H#P;zom7$~(W5^IDRVy|W+tS#W(|1)TOn3$c?~lbxIN*vi*#qw1#YO=i7>qqxH# zt;*;HA&xuSHER=Jeh2 zt8;kOHb}uHulTJW9CG9;C#@r^*$6! z$qjLCuTLgluE$V!u$cMv!BMkr2x&|P%bV|PV+Wu|d+LgTcw4zLOLIqig;y;t8TgC| zrJ$7!5SN3)`;12yqNLW5)$dx@U`J=-ln`>3K}?W#!6EkfU7`7Crl93WTBRh%Nq>f_ zx*VDz4NBxh>)xI<98grz+P-MwPf*XBKZ@dJ#h^2ouHUyr35szERLJlPOI!xr3-pb# z-C;P{0kKnwbm6|+Wt}!vVLH@opNthE1;T+#OXOpXK5G}6cevsvn$ySu!=65J{kAf6v8 zhA@VA?X&}g%24`>pFWN*bJ~>PgJjs{X14x{aIG1r#(F+ANcL^av8-@X@$vRSBjj_% z=*LjG^B{z@JIFDC*OqN7u>AY{1C!-NWPhj{z9o1sfY_<=B2O}c!J}ez)21WC$^bL& zo_rZ^H2OO_P;2N(CqC9J+fR<<$OrphHI?TdT2z)nLZVjrEI}E+N zIfrN5Fu(B(C&Rbu+FJ#}Nq-*i{!;z2g+xS>YNac)oiHhs`r!GaQ@D0?7X9w7-llAA zK@!adAKiN7J+%*+Aa)wQU5WBr4sF`iET8ASDZc{4TIWsniVzD1E*f9B62_DU>^-il zZtDvHo`kbwTXlVP=pc1g5{vfg#tlWac+{4Io{?<7+T{*i!44OBJk$H_ zug-&{ip_lELvF;ROPy}*f)=zm54L8x&)ha_sz0`Z20R}}BAqU)-R`+Msbc!{piQzoB zW050|*~~V@VLzQ5VD3R79F_3tQJId-uehnnsgs_N*5$j=*hyuUZA|wQokc&qW>hhJ ziG1bkJ+WrO`lM8RQ9S+t&!P=&w2*@TQRFg=RbEi9*C~6=>8bh93Kfnio6=5$VvNYd zRqFCr9s}O1w~ha+dDH*XCT9x_!NX*owUw@)IB7w%53_(XmK;_%zw+Ci^cz`vF$vY! z4c^ZJMPWKa{Bf3o=QKc9T+7z8Et!)67XYDhA#4t-Yez-}C(OJimXwy((k;^LEaebFS-pFPDNuC(S$` zlgBT2o^OLlHkC>T4zJ0HaF_Bu;k~{N+7u?shdaHbAK#+Z3{f*ZO%I^9SJL;6wafys zZYP*dr7w75;@w~7YqQ@(MF!3?8*SQ&`~Un?kvdkgTEHS_a%yf%*}iqkQtH?u zUc0(S;mG@nhZ5z6{J?AGgV^M*EA!_cZEaRO^6xV!M?D`#cWs%_mJ|0@dT!{}o#G8~ zR}~h%Lz*^^Ec!M2JuTCoEg|BU$mh@p8*Ey3rwbu4Wl$<`|KJ;IXnx^Wij&1T_0d4y zmjjXVE~aXD_T@hAZI*}1||`k4T*BnNK||CY*a>(`KtpSxb%dmbp%njyAYLw6}4b&X^%#0Zn1Op`0i2&}0 zDx}=MS_^PWAEnNJ3c1;OjqWs*=BF-KJKxzGpe*8s%Zf3s4hJUOL0+w|lWsA!9OQx6 z5ug?i?9S9VVCoul)NlAhcvilrpkp6N&XD}z^AcuVsPhS*1dezJ?tE(d@+3;}$1^MI|S|604KlTvEIeFgAK)2fG61Ri>z*v z8O|?$6b%ThmK23Ne`g;{V0>)Qw9Js+&sg3@X8CI0DT&x=oYL^Mr|8VQJv-AGEcajDF~ zZk51BnQkQuh#`BF-j=UjtPYe9@YP9v3vMQBjG|#32eGs7tflP>i|bw?`t_E5F1%wM z^o$(ZZme7^sriv?sB2L)5rG$$zU~+p63C{uykFK_2Zd zA&Gq{Y7*z52|Xjz%)ee5l_9hiO>qVjJ6&(H`!x*E1DFJju+z2>g)Un!UZq#Vyh_<% zQ7c^)-?`cPx?u||sLyc0K(WI9k{mnwNGzFj`8E$tUe6?^7EHUNpQVX3AdaD{4jKy0 zI$0p?6V4!Z4j`BsN^RpNE>N4n8g-UVPTG3kq>ZN{l@@OxJXdH!tz-_!?$@$^*6^PJ z`hg+Nmb^V{Kgg$N@=ps&w2&oNdV=Y0xPubY?#;Gi;VqH0|E%UKH+C7LzDykA=ZyQ^ z)>YLiQF#tv=mN<1!6_Gi(|jcVdF*bwTf+RD*YU->-x?_#XUxrL5!HN}y|VzcQ5EVx z7i-M=TCJ1?TlGZFq!q*D`O4%e$Y_3HeDO(DIeVeMnk#BW`p4JjmFKE*cgBf7PE{44 zJ997hXY*u6n?_{|X*9;buqoz}2 zznusfDi;3HY(L-DXbqNbzU3d`%J%<2C;Lq5MJni5#v_k9$)=LqkWI z9GXV}3*Gi;v>7vK20T&I#YtHd?fn=(sV-Bx1<3flkf8{q!xSXXeGq!4QvVaZSv+>? z?ih)bPxPCg7Ev(9O{9WKy0|hJ7lfPg@ye&S-tU0AOK?C|7n&w1NF|&!hp(1}YI`Kb zL|bZzFKIOeHwAwj1hMl-+x=*4e3I>{6q%grSgj`_!_9pqPRU$oGn?tRxnx)9pE-Ep zwUn8cdN)jiLn1|(cLiaICk!&Koxn&s7?=zb&t*IGp83iCB+U1I#Z8DM9h^D| zae~)URf+2Sb=BvFNR!6c9zn|r2~+6`Q#%H7kN9rq!J16?^U#u7g-Gld`X1`Vxm=9K zb8X_M4%t3NwnUvciRCM&p%5Eda=!c7*ad`)M51U6jf_+e{iOLlsw*U`ArL#Sdna*_ zCH~QtkIZeDRg(DZd8N?)rPjs>Zacp#z93x%aiXzq)2KJ}Y z66je=tHm?=o{dxPmZM1e+%}KUY`Q`QQ6eFyKLi@MALUfuKrSbPL+UvW9$FhwnuhA< z{DQ*yGyAPfcHglvnir{;Sy}nY9>-?pIZq{_Z;Yfjm0B1fY#;ZGoLXSmxhH1EuvHoz znQhP*^VlsT>gt_K7vfb0#Z)sUIj-VPf!O)Dy^jt|UNftFmn^Q^9t84+7v|qW99%p1~Yj2_xJzy84UW7_YUN@yK{K%v)dV+TL z!WFVyqO3|XH{OiIewp#hld?@jlvJT?zd9YgqO*U8Y`3y?hm^SJ%X_@CV{9i`;iufw zRaQgp?6E$VDA9hZAX#Ek#VUK72V*Ev*bnVPW|2A+Eb|OBPkpA(9ZqS4z|8MRreDl0 za`=(Mcg#`#f9GuUjqWShu*t{Pz)3Mw-`O?P@;EaU67BxsW&Vq#nQb@XHwQCVM=L*3 zPR^a?4RY+U@4BPx`fg`O)^7Oe$pP`hcV@h3$&1U`236MCW%B7fOL{28%mm`(SR)5io{y7lF_AIdTh%js=`O_p1n36;T~*D;Go@; z10IzfsEv!3ZFH3-+!>h@VHnJKb{ILK@&~4X!gsSM&#W-sk}X?QjwVA>AQlhQw%YgS z863`m5kCDj^aIq#K6ycpI98lb?H|mX_Br!>0Kj(BUJJGYK6@?3%80-U)HA{ZT35Y4 zqVeYJ334*`G=`iWA@>P_7G?&yesYvs^6L$q$1n0jQb47gFMlS0eXCH_>l^GVEec2c zmNGVISeuuAI>RyK@m;$b`&eas#-4HlcjpCJx^)^k14^q%$U&>&()G8`qyUDu2d|aE z2b?Z@0YJXmIR;U4?S6Y&@)7f&U+PG<)8KM%_~6%Z3R1rL>e6xkyU=Ha4k(Sb*%L6u z`t6si_3G0gbsp{Z7D<}9m$nTq{Ag0_-y8F^(E&pVr0`j`U}QEZ5a}$g1&7(&{%qg+ zv-aKMMkW*ug9S`4B^>AvB~k;5#tqN7FyfYKYfmG?rx zo_F;CIQsU6CXwIy-k`$;dNqKH5wvM7CvH-1`N=nQ{@`x>K5D_?IA(G7CJ^Tq_Y)0( zGhdLM5)VzIOnv~d3lC{nF&_fiwN5T?!FjI0Ln!+o7Ypu!1WXnqRVJ)d@eQ|9aX*yvYp`~I>jyqpy z&>Q)ye%zAXQ4BJ{|4m_8Yp(n1IX!G z7hKx#;V@*+MWp(nPfsv+1c!sBp7?c7-Ti%s^%bHO@L;w%=Eb8m=Z^Q^P45`y=X9g} z(}wgB%Q=jXSzR02wTy0|T(EZPQDK$BNZ4Qf#Z zpC}4-r%sktJs0!Si9iElXA3I0(9)knVgJ-jINIBv2S3hI2*JH~e2mH)6t6gY`&|?9 zSKPNe4j)-zG_Er|l|^Us3T)ex@TZ4$b#Jrfy;oJV)NWhHc10luJl^rEWPR6lCIe9y z^7p_DqK%O>)A-~T_^mE0HK9uhm@Q{P= zmzM;a*;kys6OEi2>z$K*8tGZ4f&L zJXNHaIV>pTj<#gg1>t)-U_gWT!8US#eg65gsEIQTjl7SxyLV&*oSaA ziv)%sXCol(X$>NzY2MJVasG4cAloDI*$0dnn9CjuO7(-tF$)`Dz|EnPiqtY+=NsHf z+UjhCpUe)J7z6Agqw&pjLBcJW&OJY!O|LH*JARvuA43tQ;c~f6DW8M(s`o)lkIjJw zMIcMD|G>M7qUc?pZ?CjJwv07OeX~DNg~Ef_Ikgc>vPWlq#?-Z$fdbVroo4l(N}XQM zuDYcy1s6wywS6pl=zylxvlja7!8an_x4cVY6$pk3LFarg#F&^cXN`#S=yd(+&n z=|nyn8?04MS$pC-74Mh)We+6d(iaAPpfjzu3B^TnLtS9}?H-YG1&tDX@y+q@iIi7abpj*d>tU7^MMPB~5 zBaGg(AfFfarnjx1wOP2r*CB-*wz?L{o(`F@NJe@AaZ9ls;Ys?xEAFK)M8U*<7o0@y zP%u4dG*@la<;dOt$uuE0_gnRGl4NDT3-0^W4>S`L6!aJ zSH1_v+`qZv$mvwlOYXVq-(>T5{`A&XN()Ib+|O8UQx%vNcWrDC(H5!$7kaqL6L_pH zpnk=bVMwHO8rG+7b_*v^a)rYQ+65HMm#WbQ7O|zbjs3u{>^6bbwg@dUxJPc2{@_KZhmS17q#vtI7kR8p#rf+; z+r76?`{AQDjq{LDVgipl&*|tceo*)H3zN;|eFk)|egfBPzNEAP32CK>1Nz*OPgpu_ z)8I5K8;6H9){YN;|3N-=iI?V)%}5Y_kV`LWTKbSiCgwW>jWq9FrIOxZ>#LkPaXk2Z z_JT_at=BTpt%5PzVA#r~u&F17!*n5ld=mp4X$bvC6IxotSlJetcC5HSww!A^?yuQ<^ z!O_z^EKJQ|%d9GQOH9f0uz@WEoIo5PBCJm!+AXOsxth8JDVy@c;~tZ>(@`w8R193a zismV7244DA@^R0zYFK}>YWSO~r#==n%IVG$XO9k`W{6;;bC9|8vnC(__Dr^DFJ$TD z8G+Pu2{~IWRy9nTuM?WwyUTgfd1jyg@e>9Rs!lUq#H2+YjQ~Bmhd_w*;ks4ukeJE2 zeEFjSm)B^+x-ieFXT9&n;M<$k4uUiZX&`pKSuJOw%NWw0^sk*N(qv-*LV4vTt^u$( z)M5)q)9xJx4#%CO0-wKqjS(COaKvsBXSEoqCz7KKstQ_KuS~N1fDlwrluy>BVo^Cp$#LUh2X!p4%|1 z?C;cr*!jP_9)>mk9zXq^&T3*mJQ!g_$6Vup&-I5jB8-xwq!wk`pH*FbUtMPQo-NY= zSN;|;n_pTyw2$CpZG6sb-SxuM=;Dx~s~4l@?0hf1L0?B=uqebbZi_vxh9CktVfmO< z+0i>(QVNP-{~WDX=d0`iZf8}}R^iZ#7vd437Atq)LBz1qi7*z&EyRxa8$wS$FP^P! zOk%E*qQdBK1=F23>1SxAzhqWJPG)7 z008d#`n#;P*8Rz(q)EwlYdvlctcrR6&g%ZN0Ri_NKm`B#4p#r^Ilcq`-gDgMJ?=R= z9y)7*&I9^|zk}+|-1~CCe_tujfo<|Ts{fZgK247~7s{g-t*Uj&yRA2ir`~>ZQ2@ep z4g!fX7nw|rUvP+VTH_aH5QC(JlL3JFR#?y(9{7(4OyWm6Y5FNo52~rd;5d5YAER`Y zv67{`Huc0+G&wYSHCu0hJkv|ankRa^C)?A6fyZ5l`4gn`x0*#ikb~JjVe|r^yCZhe z6SQ-_*&oRjJ@hNKKuE`Wo$UE%8uzBqK&>oO_^)1gjq$}-of ze=Qs=;Nld|Jl?x|gsEcassiSF?1XaR@?R}(-aDwad0N*uvU9je968yHlT{f`%ct|6 z@Cm@ANd^_5=fArSmJ58KMcPDigBP>eqecAT@x;mi0;4yw^BaDGGA?M3yXPkN|W!Tqmmgo1AJ( zYBXxZejjvfitu7P&c2r~ZkU%8yw%Ts3OyhSOTntl;1$k zDldP~O8SVZ<|+5H!8ad^+vF#Tv$W4fU0lv@yX8J}7_rk2u(PMl8D4Ol*$ii^9WE9* zyHZ`nx~HrkP;;+X&ReAMo0`d|{db%lh#r9slYNIwZa<(?!TGOzQ+7cD{M4Y+RG=_jKOd7`L+>H6KY^#6-rhWJb#lqxA=D`r^E#d4%NeT;)&B4&S?Gq` zd5Xm8ZF0ZSaH3S26z0~)l_7>OG9i^c1rk@-Ipu5j^Zp1cO7XS|-E})2|8?M0qV|`< zbkMv%3t|Ve71q$HB}6M-W4STaNRNlqq6S7BF;sGxqejmA8|?gXY>*56s9`=fUByfw zUrH+iahYG~POINjRs9bKy*-^by=49|&a*#+2Zfd=DnBzO?zY8_nz5#elV1YNpWtm7 zet^k6)*=+TSV3qI1|Rh!Z{fS7p?UircPw;&hNJOKwg9mQPnSs7jKTLoxIZNAXS%#q zPQ&mQohzih0xS`Z{3k=$=X+GXYi^xeCSC{fqK|jSa$2C&LgG9C?U>S~H2$iq8x!1L z0j#g!Ui}nuYa-B)Kr6~%?3jAG0JF8VbTerLMa#3yavQpL@Aa}UqnEcC%jw1i$ukOE z^A~j|2sk9!?cL0APqk0pqyf903>n44ZFkn&_KDNH9iie@hLa(ZNK!}j#DgM4&k8Wc zzpgBa*(4j^7$Z?G-7J?WY7Vc?Ighu_B%|$oNV}%656CVfylIKa$-3bR>j9+&47e4I zKkqZ?_i_FVm%q~i<9rMKY*GHWIwjfIdpm_&>#w!Jpo5A%{ z!h@J)^TB8Vh06FzIHb@u=9S?A!%~lKYwr@U5^PxUjFs6ye|er(+9Rwj>4HlzA}Dhbn%&_U?Jk&S=#k=$8n-<}=@Y?!zCG*XPr zpZvVp`CbnZg z4iNT65d`zig380V_G-9)Y1|pHGvBMW_fMUASoft_iNQ=sue)QHfu}TK-M>@$w)aWT zt3^}N?fw^IJ13gdd5rb(iw9Ju9D38#pEwNCmvT;*TD-rj_ewV~@sM^|Ad-hZcs1S+h4WP1lRe#vs ziyk0FWxLGfqYb5K;_`k7cu4)S$@XMpR9TY9ZETE*t*+jRlUkf}f;S(;Bz8C&PuiWC zU*J1QBxfmHs63Xxgi1sT4M)mfpsG1KbyPpUSVB7t2yL^J5y$0^C9++taQZ_vFgsz+ zAK_X4g=`sR(r76nlbrm#vOG5OWm#TuQwDdDGCArxY|dE(_g-W~GGhV6&TFjK(O#P= z&K8~GV9)L=^(*t`ARsGkmBQMuWL}Hp=vH>rlE@=fh_q)VKhS7D(8oQuI+>ekSRqBr zs4~DJ%jH}lQY+ivuOzN#nY)SXG3y+ME{ZO*R7cY0@_+Jo9B5vFlR7l2Ly8Td8i~xU z97UxQNTrjSe1zs(e}tF2;N)7y{#X)(TEu9i1FGeC_CAAiCk(}tVUv^Cq2ZY;%bn35 z|Lh6!c5}ko>tW*M36&O0X2zWG}x~hH#d==XXzWT5C8tnhR_qUY)eNv;(Nx{{al&s_=Uz43j zHg=M9bJa*|Oiq*?%p;WbnQQ<6;!@A~YVOZH_U6X9H94*-x?MIHMw<})KQf8`E?Pn( zkGX@tx+MnmKlS?`zkjdaqmJu$p+RtEK;|(~0I~+4`~w%}^Dl1)s5|-3a=wHX0!b6m zXP^!+@lu~l{i@5>-^=6=kt#Scxilg&KPcoL6%zTYOWli;{L}b{gPtb&)%7t{!@;Re zPx=Z;cCSBgwi|8qCV&sFILDt6Eg#6Ba?=PZxcq5p_8wET4V}0Mxl!{&^ofs>kHO zcI%+45-g;_$w-%`5PK$QE57@YdEnSHA&9D@*%&7uUR1uS_DRCNzy|A_Q0s;Qz!(lB zDz5s$xZ2UXJPLceSV&{IObP%r6l~;>%+#2z`1Y27$B~S?v4mQ`sOZ5L0K*A`TlFJB z!1AL`P*{#8yz+J4-Uf(5k!?@UruRguwdtAchi`%w7rzJaWP-KUB2%@YM8_r3-BA?1R{a z9t9jPPJZkw*v{Xqi+NE`nVvjc9ougR16mOUNVRh$ojXU%@YP^!p%*Rq))zE&K)h#kJ4i zGpN`_$m6CVi{0gfi%&EOj4w^Tj#;s);bWQNw36Bsz(W51O~KV6>P1G zmgRl+_<$x%MzKx|y4mA=kh3SpD7R<%+}61F1MZ$!1lon*oIW{9=FPb_eQ^UEPKBE3 z#gEay#K(LZx>tz7##!*zUt24?1l$9vAIuwD>pB#Ol^dwHf1_G?>wSihp>&J0meVKD zNDe-?!q}|$+`&2oa~V7<9KcQ&dn&~JsEwrzqF;|ocpFKXIZzW;KqXY$Wy<}G$nVEppThdvf-mTxB`N`ZF6DS2_SZXzw$UUh@HI`UUu5drwzB;AUHoMe{I+<+Z}ab5TQ>`tEgxl(!7YWKjuK$;#ISPu+RVKWeOA}nLsM=h!c9`o*= zE%jqV21{>|6oiyoU;z55&Yke^8u}7NXB5uWNpT6v9(bL<+X^j#H|dZnb?cp0Wa1 z%A%fJS^m~=ntJU|Q60F82f}gnfM}tMIAoq1{9>ECda(TH?-*(dx!e)8c3s}NYjtpr zhyu1?Q!<+#0Nt#lkNjn*&e?G3S-)Fg1O-K>I3_pJrsqQ;TF<2NV)bN{RQSUtbL=o? zFdU(nV;^}}U6}2nkRMoMUi0QK{EMJ}w3~yUB!`~M%Vb5|Aq6a z%A3>6>W43G>ElNkU#f&=D0pDE*WADLB>EZ#FnRpVUhRfBY-A(xiVXq1u!TAf z%LfCK3KB=MGxMQIuTRs=6r}7MqrER6-X>Z>g!#n_!9hLf!8m_6KbVLAHHTM9SutaRD7LaOv4gpyE{D-E z3m-GQEREw~d?N>?V3dCxHH$~7zf;VkHq2;1`tyTgD8vKi4 zVv=Vb=jyK;cY#*sE99pFM}{o459LA=CVG| z9g-+K$_df?kcnFAyOV$tCCAjuP1*a86V35{51!YeM(^B}%cdFHa}}S(n+qfv#9lBj zX1!yPK%4D#qB?vpy2CY!uAhm37YV=`O64ih(OG_pr{QwRlPPr-AIVCLNv6)D*xAH& zI$g@a#>Lyj89p#4Y++@)&e1y*`Zu3nT#T2#KQ9Bj7ng^B&><3UFwe-e&Z;Qe&twrj zP^*!`7Kn$0@}6+F$>fH9r|v4Y$##d$%7PX6c@gk{7TGC>JaA1EvE*`@J4LO0N6}2l zkej2k_aum2)8PNT2L6wd_<#HDKy??jR3d`8!Wc~CIsUIp;omIIf2-g%MuU?Y9EY!+ z2Ph}OB6!X<@}zE$tA+D@WMVCEevcV%xO8&qm&hY(;P=UaWJwhyn{{8_&y-;px3>C! zn4SNbW)r{~SPS$#LutJJ(a*q?{?@|G)HDBH3zzT_E^l?hG{&2~rjaI}jF_pCTdk`O zN-F9~FV)-(Ok}FFZMGvd58O{gXVu7x$)qU->mcj{zwmRaycJs;8;v1%Cwwp4 z)fVg3gGWjXg&!!NIw*T_R;G*gVb?eCxbs`GG}xkeDqbkf_a)8!p*%eMa7L7rz)feZ z80sYCPEq^(K=^9kAl0S4w8OVncdWizSp@m_^X>0gr-Z0pC!e6OjzWyp;S+97X9a2e zuXTq1?E4ia$Ip(hcu|IZU~qBc9IfLWq6L@H=+(YA1DQnZn8Gly-~ZG zyd1Oesb+IqY9{sRe#s7jv{>nMmd>21I(H@Iozr}>05WA%?LsG)LMhLy-p$kSjojOX z5gows9wC9ts#-x;Xs(|xO$8$~KD(zgTT7}c^+Q+QH$!+Lg&Sm_-hw+jszRu8vtc)Q zelXKI;x)JviKZ_CIoM-^ha(TjUt6WcpSpw?(Tnt`QwM2(uF`DM?X(PRA0Xg3uD~%%#5T5*W)EuQ-|;`_e&TC>KHf>26x5_M#n&I*+DU zEH#sUrbEN&4x`csf^Zs*7lIW^_Tdqmr0tQ}V4AqKz=~Q$5W7yv|Nra#fBPZ$KlUbe zUZwo}f{G(-gnnOl^s>W6L;VkLIgfk3zgba?^8Z}tf~bGL&fEXtY`%fn#>2Bp=4Job z3uakj{$=vV|7-1p6}Yxx_rI7N@3X1UR0!S}0C>sLaZusqMc|PA+>Zb~7GL$p*C;r; zL)@>4qk2#kCU@>)aqb4HZ6#*~Zw#?nQgBnZoAAJ`??DpvB4DedA^!dyGPh&Z;ioj5 zjIYB*;%zZv@l>r0OzX$KVd1Z~wze+nFk_g_CUG_gZ0!sf7~fhay(f#5B!3mZQjhxu zvxK^j)L;dW@cidGxACdM(bzzTY7}F?(wzY-j$Wl9et-6l+kg}R+y&>w!GX~A7k+!X z>)Xj=s94pU0;^5C;7K_i1i)_KE=&M6w?;V+!98!_Q$SZ5rW5)YI^)-wYbvwMGlBZ~ zecBpz+k{E_)G*ngYro?*)Ld-D=Fn{e^!Wn`mte=+>T>R^fa}d5$JY$vkDx>g+Bd?_ z51T7WSa5oGZpxz)xX@N9WJ<;O;{Al4)EFpp>DrJi$U&n0D7wMI>MkS-)k~na?7QL) zfJ{sT6ZZSFB4O+mGl?8k^DVkCsYd2icND~PJYxtm;U|9TZj~c@yU_TU= zhN!a;E!f)5APL_n^q@p;IA6f9OGCp4=35@G`rHpHw7(DRnh-{)*7w_h*#g<07SR#z ziFk9}evpnwlg~!q-&l$`*1EABuuKRc$E5Hsaw?u7@3n9n*dJ0_<^0Mo)f_7Q$gH_6 zD-<^4p-lG%@@iW437mN)sB40BZtqM08{UVVpr5#Ng*Xg0d^}K>72RoIAD@GL3eMd1 zzik6^g7)L;$m&c?=Ns+znwvH6QZ>YOGFoADG#-`p(|*51HJ_I@y+AB^bB<$j^|j#X zJt=PP6&|y>EKoy73y$V%YtJWZUpU0Ilg=;3YbO^mL#_0qD>l7zRsA@RGrCS>Z?>QL z3hvT#q0eo;zuQ`5bwr+-%c{)q<|a=G^(pYQdwLuO-#__bayxZpX7v$gN6?d^9t zIySX{qOJ-wdim)@8j*CjcNd^}0m>*Texfpl0~xOPNa(kezP47|6b`w&Kt7%~0c&_s zYn1Tku}7`?vf-lgbl~|+o7&?nK=$}jOf-)poy7(2bQ<@|uNNq`6{pqO7y~EOn0umV znLp7=iBC`Q)np!BRdqZJ6h|evK-xpIYg<>ZrrO(&k)F|Cu$!Jq@TVs_+kfV&d*a}!!DX$}8oMMc!_ zKRo1YFR4!3)b^{VyJou?9b57i2QZXH@#vHf?u?&0s@Xvu4sejQVIzu8(j`d!+Lq-qw~Hw1e&{aP}#f{ zb|Dj`AwN2yaK#zE%A|-dlXm$o^tS%My!)# zwR>h>x3OMgrLQ`k1|&E|2`!gR@p}V(<8}EjdudcqWThwpUp4>r-J_4wDfnilg<|!K zQyVLb@2jv32>Io)iNViqJ|D{_dx;o4jiAcCmvUo;5Qx=u5qvLPf4u8rEHJwY?H=<_nr;DB618w9tKl+#wi4SwR>FO-Mw?gpQ?bx3CA9K zJWJ(@o>DOKMRhA5&cwMuT-~1H_Lm>rez4_T&K!WWsb?A z9`_@>E}^;Bq&J$}nx~G!eCc@3X+OIky!A5*#Lj(khpZWW$#TY|pJHgTB5~6b zL%I*GuW(s?cNn-DHX;c$(48D(U04}NICBYEtan9vZF!gIdhcnb#b>|CpTrklgNrSZ z&f??&U0v@(8ILK{w|xJu5*mejFOpjNHz-k!KJAL`Ln*`8v-Z%zRjd1=#R_0?zf25F zMB^P|hhvt5dj=|X*>_47e)85DDS!U+0w^HZnkc4i+UGyGdh? z&E5_0^Q0^1JOg6qdGzi2*m^@@l>*3gU#-d5Sxi2vN30bq{nWI|tRy^?g;A@jeQQhn zq#ySbe)>K!0=c!5_S7I4QQxDYaJ1Hje=iA;TO(62YQsdsGY8>n7mES}t7fpd67N`^ zZBXW9sc)f$K7)7vrF5RdNPd5ub*~k606XhO4v>)QzR<4@DBYL7`(=r-*YdL7lU8Dp z#Q8MUR|kRU#_q3zwB~#8%6ql<-wAP7{yJB6`Ih<54+5SW_)|yJ1t71@{Xdx3=Kded zYx9!PS2$nyWal=N)W6qezQDC#F=curFB6E~(0YAVpjrM>p(eMHMnJ)6xp^B({m6tD z+u(}O){noa-Q@)58iMl{cNAJ5)jB#Li8a~yo{&|!^w2E|T2>+^6!#$^L$&?_scqphl<1(2mmY^Om&|FG99J z2fK5E*a~$ZfjW{(&!x{B8QL)ly;pi*og{IxJtxD0dik=e_o9+@#G`X&Dg(7r3#-%% zW1_kj&&Pn+`CoJA)A1 z^Ye}*E4Y(Eudll^YOA=jk*Y26LmpD317!%X4V(j)^mJ^etWE}-0f(R`2b?W1$aj}# zGhKWp#jpIT7jL6S$M^D0Yu^rV2p93-1N99qf^&79=heyk2KHXUF|^0 zrO0f0wN17gTeM70B`Ytt0_dk9Hgau-h?aKU#+15Vbm7hct%U)dTbtA(mJgYVu%Dum zF(pkQqtPHCmcsU9qsO?r|ErY(H^*1oTJFo1=b7O7s@l$Auz>6RoQICNxe$1*0{7!P z1GctSn=ty6p#j%`V{TZ-?Ehfj^sn@@Ic^4NC)xZ^4`A~+QGg68-E>?B0K`?=*Nb2< zV@-NwPVbL$`PQF%4PB0s9-<7c5q+24=9C>-nySb~xdY#ot^3Kwd0gpX&=7p{f6Cmz zC*MC@+26j2{vVG&vufMF_f50MeG{Eh#l^p5*e_ONtw|!dwCu_Ha_BK=` zCcOkzz+7Yzw>UR92mYJSolj6yf4kCPf!vf~Q3X2bb|{k?pb!eZ-cUbrGH1O3QCe|B zz;a9us3?|nQMGP0dKVlBXAK32AtgUvvb^7&i8>p_&7c_*y-M?5pqoTF6@>+^zv4uI6d=oz1*yxB3a$k9c}74Vmk+ZWE&8mHSsJvB83Yk~o|n&KGxge#}Cb1Iz0S z&R&7!v~oxw$ybA$%|LC;7gL{OK_T|yHFZO?+sK;AK{gZX^OC^o=3Bxa*!?5Y&pqIP zs?8qMQ0S*~`DpFo5jW*+y2AqnjyOQ<2>)Id(EH(Y<}4@_TwW*qO@`ZAxi6m+d=rlU z{HXMW560RBTt?i;-yc;182|LXS5l2hSQ=H9X%{Ym4Ww1y6Wd3QYc6u#+0bw@@?s)~N|x5I|~$ zM6~I`w0F*MMx(_mjv{o~iMPL2VR^WJKdN5`epS-RX>E_;-^0!?svL#|?H})%VEbNF zzyEOth;Mo~&LabIlScN(L)vh2iTXSgD6xa|eo&JvrcAxV`gJx&WP2Y1WN`W_!vV9u z8@ApL%o7mrHzQ=k){3x;;y=+J)iNaWnEj{%xWcYg3yt-{+c0AG?kRQNM!6h#3;yFVSS%MvVu`k zR&W-|d_dA8P$@`y2?a2NGr%W4N$)!E4l3#gGRy11#$0!A%Vh7L(dBP{^z@#MFJ_nc zyXr7tVbtMJcB~Vlrz=))_M}6b{B@^;kSIJSEgg4Go3kgw!FA@((8}IR{kt>U+kQuy zv5FUlH3US9&#jJU$_|E-wPvYTLIVX%*50hWsc*htU^IU6665fVaIvUWirK-vc!KqL z5Ieid-r=VF4k;1*@Nx-@XrM-yloyG_TD07g`2^*g5j{8nzIGw@^l}K>L-I^<&c}(FGuZ zPZA|mVxu$@W_fWs9HtYl$&f)mQ_!mSHGDY z3G(qCP|m2j?-Sqo-5^CqUso%^dsGoxemS}GPPjMt+ZO80owm41nfSYEOMQiOkzX*m z?nd~DuUkN;%6Pu8aQi*`{W<@60c!KR5v|4fk+#_FXu zNIyKh#%bm;4(=iPdDbFpzoDh!=5G5v)b^6bgZz%WAa*WyQo_*mp?Ay${Sd5APaiCP z_Yuh_3oaKPCa8bt;H}%1!3*xOf{K0l0APS(b+B)kL$t#n-_*~pw1HPB-=@7Obse}$ z6`{T{kdFalVBt4j>Z(_bQTV^D z6pXz{()|o#=k8bETT-XfOO|)}6wDW&0Y7|~pmU=zqiSUkxcnie1m#C2Y#p3lkz~7M1IpO-r;iiliZ9P^mvDF^r+}o!? zclaR2O6bvJG)kRpd`*g_KNFIW{$)~HpC#rZIt+YU^&aRAH@ZaHXqH*j#0dXgTNye! ze|J3z90V0~22*iY(wUh1kte+CaUP(1%OnE@6n+WO3Yr74^Z2vXJ_ckH)9J&kUjE&} z7FQnS_62qC&(S&<(EN!#*S=kP%VDMb&FdU|=nV!Q{W;Xdnmd~Tkw3R`8!J>R15Q^X zAlu*$cyC*)%eO0J64nEXrOwCYmF@u+lZ|(w3eeXw5;h`!ZzO5+ zZMg2)Nj%}SyKtu@s$zzfg=JzXt9k59(iRDp2Q@{|(bvZ5x^-@|araq2l3(g=3|ZW_ zmsi)Cf6l>xlE}Pv6U5FN`rcczixQ7g8PH$M3vm@u)J`{3GG9q@$aaaBc^HvWXewnY z4saJeaJ5O)NI4_+n^pB3n}6J5UN7STuWY~afH?wA9Ae?lcFYT|kQc$b1}qY>!TYC| zD~oMqIC%Q4rjQhlzKs0OE|+M5&M>9ND1emMEXM;04Dz|>^c*>M5cnA;9JUqm*KRY` zv%GH*LlvD{A@k5NK2mJK>ez*`fgI{|*-E(m7!If7O*43{?P0_QV&{X3Q}O&hF~QjX z4c_@e_Ty|FeGG#&FW$6}Re)NoWD{>`$|oQc?3NXm*HPNBfER`nH2fo@sig8;1F#RH z4KtVG@?6bnQzgY~9lE-j<()OEts|IUv%vJ z=<6-!0C}lwo(c}SXrbHE4q^HST+UC8==l@|!bMm{HZ!mw8D%94g0|A`2I)7R#%M>8 zM0&RyDGwc47~J4`X5IZtAojCo{y)``=EV@0P4N{jM^h27e{iIT=qu*+#SZUic#XH*=43zB%j=!jA;wS%~>PRROst39z+8Me2PT=V&`oN~Go+w@$LQ+pp4>MwkeNfi1 z?JuYzxsX*M9iabY{Z_vR{6x~*)7MToJgX9@`CRiY_0fCv_uDdR{8|B!)*k*7&Y#_{ z*?sKH5FDOvUHG156kmQN_}pr_uiv2z%j|s&5B=p%s)&Ob(YRoN2D)z_XfE-ID zI%zEb(9tpIO2oA^9^KNk2^iw30TUz>r``OC1*;6pgjJ{&9KCnVl$Y6z#NeNqK%s~d z@k&K3d~5C5;Mcx}sqa7kFY4YqsLAeK8%-ee-b3$II!KdV1eGeFqErC^6#-G2KmyW1 zL{NGMDJp`36e$T^1OyFIq=ep--XSF4!grV7-hZ5#b7p^MW;@Ifk^!%*JhPsA-S<@v z-Z-;yxfZ1Ux`qjS6?B&)DELWUXVk2ZehRDWE$$m9p%g6So5m-F$N~l@>lltQX)k6U zc6ai40ZgLWc*D*fUq?qsUAjl=+IA4#RUvIiI59P!e9!dXCE+&$OH$w$_lWJPxHd#A zt?5Tc1grJr4_S$!q!srrvdReJTBlDGM0J{Ml$EK|PRmiWkc z88*&OSXQt7s* z-`^l$a!I_Cp^GGf%)=s0GG@Q=*4>aYPs{iyxkic?WhRxm_RJHC+)QKuJLB1c2oQ_~{{}Q8(ds4|l7N=i+J%#-KiOOper9ohTJ;EqlUD(f&E=th&ri?VAv!RI-$L}L9y ze!gugF-g|;-{RDWg>Z4~Dq0&2)_)RzokQ;ui7r5&EtG@~1T0iiYMeUH3*!9cGFevI zB&%mr)(R3n&4Rfq7MAB3NLYp|^=>BZ>RPD!jK5|063f4J=X1rE*{Yi_1+z0Nm_vTp z=m6}@<`18YD#%X!exE_D=SuW0T(QG{JRIt(+~r#H)zEJMw|J-lPxv@;%O7W>xf2t} zZ~H6#kxv-E*iNlTw66PaTwQ6~k9L8p2I?vH126BU)s?I(E^s#-S z6`e`>toZe?CqAs+eM;GBZ75U87)>oZRIh(2A@v0@Z2Jp6%tJ%{^U%mt^+>C0cunZ! zT~}hR`r`8f-=%l=BU&A6Gp+8hPi5~IsJ_1CIy?V+JN#_jS*Z8KJc^We=V6?BXgRUo z!v2>Q6S&DAaK(L}U$jhxsa&eW!dy#KV)`GM(KjHI#y^N?au68mBA#1SNhNZPEhtF| zZDT5kU)B%S0;2xED=P@WL2%0Hwe@z%G=*Uv;qS&NAN;6!*9>i8fW2wx{3c0dM5A!= zn#yg@(d`$p=Psrxa;x-Ce4}2Lk+ICo4XHqv-?*DF_DS(tq|CC7CFzB^u<(_%VU?|8&LhRI%$*oqD|Ykb0#DZD%Tp_(Qot2cidKrU6$3u zdzte19rd*z##l@wzy!3#B3nsH-hW1fu7$}S#u+d9A|Ji@yI+a%4MA`KJDYM+ZM_C5 znPJ#+e&)r?N!;o08S{tf`AOcE?Wj%jx$Fm9a;)78txlNRshF@>&9XM3{9=*@@hM=w zVe|EX`X{Z-a>l2Ki*ZPU@pGnTAJU{dU%EzGIWyM1Wzp&z`la|aOXJ3eCd*fp#KlkU zQqSF%Z+E|(?#Ud>dOG`5!(5x5fswzoVfnXy(5D`524>^3$m-UftVdr%Y~(OgYRH9L zy&8JOSv;jb-KwM5O&3upxxm&%$1st0Nq`;hO|PL=6&N|r(o;N%VG){5cM9IbIxY;F zP(6hwT2i%qf|=n zl7We4#sous!Lu)HRECB$O~s2o67+&nEh$!c#?%cAtc+ZenCv;rm&#lNC9}pzeWT>R z3(3QGcy^K1%(KvPm)oS4N?Rn4f3T(e$WPLg7Bm8(o%M)&_QZA#ZgaeGJ7+SfQfGCa-{xUHY{dXDs6Q0`3(fovV1+;ES@*+tHCKdMo`qaY^nRTZSQUYJMrhdjb#T zu8n=WY8ogymtbU1&vyP?VawR^P2HO#;h93UPzrJd9fnHC%i}h_kKdJhN ztxnhr>*j>iS#NZatsI&0q=WO*!h$lrNv1n0$F)T(uCFiGM9PPKTmm_9P_B^d8FSY` z;?G}ORl1C(Z+>(lBNFoA#ES8j zp1gQ$xs{1&))V3W3W^6psO6sPd-thw0Cw)#Bv>Xgn*UGkK-gD*nX?Os4@wS&fGYAW z6J=Zb2iY?3XR6WqRafgSSzG@QYbs8*E@u2>S~M+{XgZc{@xc9lb&0on{oPNYH#iJm z{E~}#mEHWD&E>qppO3mS51M2Qur!aE44N-hy-xceFy(M5=oBWn*|6ahrMYy^a?7;8 z#LWNVv5=L9_1(?~F-5W-(YM0Tw^us+EKDK#R$?gJI|mg_66k!-=*q57Q@vZ){|!4P!}yEsj77Iw^RLImt%{^Xg8XLb{Amay!CTbfS=$fp7&^{~ zJX5`N^dux+?mGWc<<~s6&pen710hnE^}x&J%)iM29%BP4_}NT=^q}AvCO~pgR>y;f74EkiYAp3fKlhe4Dqzi9j9s~PJw?oHD@Y{ zzun+}UQGWtcTZl(6C@LHR2Kx=K@5SO_ES61{v&lhEm}zdokQdWK60cO|3lnr5k$-z z+MdpKL)@WwpCG{Cp;d?GhS0tST_-M;{H8Z+Axh)pzjqID(2FSFFsr*QSaNV~;ud3n zV1v)}+aygQh8oIV$mxPQi49V+-3yz!2r>T^%{*T*?%9Y~VFP*;@!1+ed@gYjWe&x+ z`dwLQJH1F zhICOz5^Z;!?1`DYBSJzV*dbbzQyRIbEZ@R2`F1q3VlQH8xW==x|L_R%<3A&!DWLNA zzLfILqSha&c$5w_VJm#&oclAMN!-ZmMe<36plCiKVW&Hn`law}`!7$nE;DTdi6D_d znLp>TCkBH-G+|Gj$v14OYOH&#UOKB-j_+^{telU`Yn|(+8;|?5C3O29J_+aZEO%Ju z{%8VksqK^uq18q|+mA9}`n=XZB5;76UJQ2hJL@PXUujLimCDg{_DeB${&)f1dMC|i zUP@;dGrXqjp%-+q7j@)_jlB-SMP-R92Bc>ogz+paUY@3HPs!wBpMx~DHW|fIgYV3c z`El?qEi=Lqi;i-gajsT=?1^Vv(C+Bv&+-_t)37O(I(!kB^zdlz_T;1r_zI86; zX=OcYmzlljBA2Bh=synzGk6cSz$=q;JP%l7S*Tw5#7xRQq}#R;1>ks`>XzSb$EN-=Sc8q@9c>7|5?$4;y9kGW%OE=( zMcc>HceTGE;#U9F(CD%5b?o_j_Xx!$m@C@pA-q_^(=J&DjEHs(WPa1^RT4Iv74e*w z2txDM1dgh@HhD01*y&h78@AH-1b&)l25-a-GGOuNf!A)Jo9#s!CmMMn=4q{&kB^7% zXxBP`36!D862~LV=}8ERavDZ+4`638*IPCIlCia2Tay!XV1?ZQls2=Qj;|UG-{j=e%!{llOaBqa3;)IVB4&f5AkK^ z>?*}d?04DUPSJM=h3?gGo$o4F#$SGXccaS1_X$c=Wch4KrB z<@?*`BN)DiFRbgo-QAoB5V&v&G38LIW4LyRe-%3J{gla}x8XTmUJlU=SNaQZdz%(^ z1K3&l%5-lUtbjZvat<$vp3)Vpop+FYlL`Rjam0NaM z?CAVBpDoOhSvQJ}%~IP#k}&E5_T4!6m@NO8yJC#$?oj$_j- zpHi=RsJ)0zMFf59=jm?=tQLl>AtW;C_SD{wI`Y_i0Cu*Hr@|Qv;XAt*+7^Kf+S2fG zz*T#D>DNn43~<)liZU`+w|pLw5+$Cns}Hoj6s&*D-<@m*+vcB;k!g5Z#g?A#z`!rg z%SVsVyn5O~A0&xyD1r3M96qo;J%8G?Gt)plFpRocux)=bH=$X=r@RktiXe!HoCi}n z@u4&%Z^jn-RHEeMv}aIAx)bj(dq4?`1g&f4&O~)RLP@6TtGYW? zfS=JTCr{phh!h3<6hwSyZ)b0BXJ@Cpwrw-_Vb3vJTAZ_C`1V%V_ZL1sJ`cCJWHw(L zEEx25wjGAUdo<$9WQ1o|eqM4Gn4LdruNO(0yCee|GVnL4w-FuWB222X8EusCUYU|S z(E7e3@2m>kGzovT7xXtzTmI>eZ**Kr=+D6Ol`AL#?5aNh*X#HHUh6w6OfX_xQ*PUT zNZQL$8#2gHnUh(+B$u%-(0Av4m)opZflJ@^y?=Dk|4;pQ2*;Uc5hdiGy4^YNU+Z>0 z_~tw4yt_CII#KuEw9cSlr*!(yXQLl}2ked@ZAGFUSQpY9O`=Q5y?brkvj#I$gUEA0 z9ew})3_hZn7vM=he~U0aYVwL5u$d=pCs}>Rz<93v+ba9e*?g6gS<4C8cR5@);eElhUFxYp zclRb2pAvI$=yZz37LK@$D2XY1U65Ca);Sw{(4j~X+y5;1_V>7~4g6ls@W|q~@0KMw znp_U}OwTVaQP)RJwtTko$8gGAOq7+H8*6Lbq;(q|av&TE=1@0(l6H$QL#?=d+QQYU z75SwrFrk#7;%NT)6cx#ArZw*Q(e=yV8XxC36X6M`4ufhM6xj4=>Gt_`}WvpUhMW= zzB?g`IP3zRvZu3)($efOn@X}=H~oneAe!KrvQ>VZYUKe&ekox$ymjoMcM$H0l-3xQ zVmk9@31Mv<1Xn@NjpXlRG2>p+IT=kToJJN+Hjp*XaNPS*gs9DHrOUy#p8gbvt=)GHW{Aj5(DbggDJvqK|<6f|I{l)Datc1 zq&`TSB*?5?4N*HD0vQpWoY-MWIc-wVx?T?mtuQnJ~r?AS|_)4~Z-)imDNYsLU z38HkbOw5JX3kiCxBW4(; z>NlR_UeC~3K?u5Uu6mo>nx4(z9p3Erj1MIvG*n?Ty%+UI5lC*mF z1L7cKP)_>LCkEsbQSAkbZvw&V%IprXH9@|Z$3-nd;m-1zgtgj9`Fw@6@x1WgYKk7DCKOPWU??7e|)kfX4x!ntF_ZXWx}S{?ZS zspA`za>N*712Moy!Bf908f8x~xqvuxzl{_mZu#`ugcsLgK;(79dyFM8ppwgRz6IM3 zCnqt%mI5C&&zg+*O{{v@`%g~_r%=&cB9bk}sDZ|i7Ql&SA5goEgo_KECdLho&cfZY z6|b{=LEEFe_R!qg{IJ(#!8`Lqpjklch<+0aA*0ER?oW0E^=CSf7{Jc(SdNQjy0-aq zh$iF@zfpr~Lm+xf+j9XqyXEH_oz~?pM4Xl0#uV+?RMTRs@AYQo=izF`%iT^YPRJ z3g;F44x8Mf*3}i)(t*^qjGAF=T`l|&ouSb!zy{X8VLXND*<;H4FO#>1%sM5J+^Z zWJXzisj?wtrq&x!bv6!AgPeygOlTAT$0L)cHBDQA;Qdf`!R#9_r|Ws`$q>fJCIc#y zjRS;FrF3ikhbvrdq5(y{>6I~P{l-gMG-V=pPvafFi>~Tp@J!|m82Kltyc2(bohjg= z2vGdQ*z)r^OJ-{{JKZN|-O3PgSiu9|QolK2Q9_VFNMJe4e0Q5d9+9GENjb|fqe1jQ zrgO7VjNCNuJU-K_1xS*S-2=Cr_qWEIc}rS)`w6yoKh!VQwLJ`o4!(D4t01t>2#6v0 zRsU;`*ad19<_&o7P)wW(-JKP=>8$rb;h8C(u^iRCr*m`h7lo9Zmv+*mFFK=i@PhO? zaf|WK*S~6d;YzKe?>&?ngP4YU_zbRwpLr`VFDz$-=6W4A?MJ)zk?Ccn*ABq$D^}*7R#uZJuXc zg?9<`f=d1`Y@KmS9&U8&sCZ`el5h7}lr;$`)RN>hb;@!PR&D&dh56#! zybDXo6oEe|f*9W+0FlIs+sNKQ{X)!UjU!{_(WO%@%#1o%ch<0Q6kt%LlWu3xm#(Z1 zY^jb$Y?Tc(Yt-VM@j<@f4_&_54v>STv$_<$Fu~6!E=S8phW-Aoh=}MfPbBwTI55}& zWvd(IPf^m;}@mdjjiOJdV5nN;n@tyn82_lAi?wfs@qr1 z=rkwFB_ngj2Ue!|k2*3N=$Hda!~rckK30Ncsmnml$Jn-Mr?Xe#xr_{h92;|Q=Y~&m zUy~u=7ke{aM{2X5)sa42q7YwA3KbL1CCmmsy6|##Nr)mR;G7m= z@oTBBCC?wuIp!K4-6%o?dTfdO zf#)*C@7xJ4n2!=EBz41>y=UBUQ(^|S&sYAYYzxLK-D6%cjikY&-#%JaHv=s9wBf*53B`PAXV;_5{M!`01o=m&XPy_Z!GX`{`0+wM^gg9|gvq zV_3LuWq)9G%eHHwS6AyP@lxOQLbaU(Tu0*wqwQFK9!s8PXz0DA0dbO(@&}dc4a$uR znRI)0+>je4f5~#dpDq9NezBB5qN(6{m1byQOzueXQA?rlQ`9;kEA3o^?~C`h?ObN{ zQCiYcCjAv^N3{>my_Occc>mX@`OjmA+7-7OLU%B8^Lz(h^5KC4DE(g34o+dAPo)dL zs{wY7yuFUwx#xW{Iv&v*Yu+P$Wb{DN)XCpgJYS~n^^agfegn;2Nq)7&GCaeuS_(Jc zaW<(-D~h{#6OB%Q3qE_#vg&!Dvr4gvyDCItf2TI_bk0DH^DA2^2BBzB*#qnsy#M2R|L^CU|4Tm?FAjd` zWxu~qMFwtMJ2X|<7vz~QnLoYldT&$}tND z9-IF@1o=DX`1^t-AZnlGO#mCIew-_gnZ(y+6shhF>E;qE!1^&g!Vq$3+TG28Uu@c~ zaZh>N=ZPRG30zmobHmpTVZTzj%e_A{6OY>w)|7VbqM22C5q)lQMI2w_s_#DWoTd$+ zj(G|ZVwtgyD`;B#Q7yT5I1Sk~~U;IN#;D%0!sL+~{O@;<;HEZDww#G`@@3 zB!Lh+F$3B;mv=W^tIk{g*ec`j5S=@!iQbt=i4*n3+Ob<+gmeT~OL3aUyRko9qp|mP zcMu!9oR!*u{|7RsXvKI_!uC&LxtT$rg8p{K%nQg4Hm3+43RK?ct|t%KXhjZTl#c^+ z^!|MOcCW5I0_o*3ICd~DO~_#o$-6#H=S>HR&f`N8MLZ6rR9Jifu=5yqAxUVgX^2F~ zZ#Vj&ArW2_z^Kw_b8easxflTsddBv^cny-(Wp;!*sQpnlC>Ea*=bG{I%3S&qI)Z{C z3zp5*t#S|I>$9_Wa38<6vfOEcAdH?)JBB8&$62ITwS0BsjP9RV)4{e4x zoA9tEArHT4IuIU#ShNGh=91HcVN`pi7e2367h&Kvz!@z$f1lEdV_}JEBzwKYf-( z)77*Z(&2MHVv5zoAr zpDW^6vPBASnrPZWa*FeptkW86=F~n0bEn6j-`_Y0Egn2>=AEY8INa77>fC!D0F=@c z+!m+1EKrU5jGbN}wcOfjt!_=9cIsTK(~9aL;*|4RsSODUEiYXnova-M*coYeXSm2S z>L#I%5tmBq0Ac&>{`y;lG7j51Ui&JvygzN{hxc$=nizJHji%laOJ(=xIOtK)pQzY+ zy~?QxjWA-`1VA1qSPf_G<47Ph=4PE3Bl{vbH0^zL`X9_)z4-C8+Vc*hk9t^@RSO^@FIJ5x(8HfR^m;8xa+SUkkv%m4lwd!DMYgZZ@ij)MGd zg=|k*n(};cpJg`548m-h){*S1%7iE zwn(T`^GEYps47MhT?Opc@Adw_36PBDRoNo=`f~d90S`Tc!-Z^~d zLIxpbPj#&3=8I$hxZbV6fgcs_KJH(^t$tXze=YB+*SKG{MzBcdAp!9>3ld;wMrcLN zLAAR3zHjehH~d;9P0T_!e}~h=9ET|GbNEfJU;C*AWZ&&C(3B@VX?A88y;d-0m0mM9 za*aX}qpH*C9RvO0!1>0RT<}NbfF(PcQ=6KZ9}XdrErE=^)eG{dGg+ShIt(e~H+nj& zt;p!BbSp3N)%Dvd(0PhCvJgsAqCp}U^X!oV)BOIFblEf+ts`|sMf^zz^Z4E9sbkDV zls%g_DV2xvNZny{FTx<>EIkE};8g_JSsbzHBa}vv_R3FR+&g{7wa!w_^E~+R4}&xF zen(bCZt!Fx4rV?#y`4NI1d_ZQ*pgGl@zWD&m|ykT@g)!& zsgjKHBK8+L+#wwH%yAv6b5}s|r0VE;#ZA2yYa#OSGTQ@4Mbk0e|bv^)3Rm~#h zlrWcb6fyf74^Up|rGn~*Kf`YhtYj-qTYKGzD~(Q7lhN-UZa^JP{^AxAcpU#N|2n|V z+RH(>c7@cicpd-uST;MmO8d0rNx0?b35(^yfW?O61^=Pv;^$=-MOH5y0>235!{eW1 zckXXj!bRCd?DwjE4s4RvnHAlOy!tY6^2fe?&D)cGd9mA3|M7LnGEqw|C6SdgM$||F z(K);m?fQkH?u)O8>^Q%60Poem0|W4`EoNqxwx^hZr}zGNDHCTp9-%xllYK<#^vA4j zeD8_x?ULa35~FwIzP^=b9SVS*EkXckyvJ$D-xBmHku!LzEn`wpJRbC$KG7>F?@jdlF6mit}+d@08U# zAN0cK;pOE1=ys@#u}3mYf&337I7dsSo)cYR63KU5mG}kTyBOHTs-4`rc*8Yof&Y$u zV0$mQcEXeak7(~&`HzGaD-CiY6BPj&a~vPVB7!agdYz)NQLK9Td&;7`y^1th7r+j; zH54qAqw3v%TK<8Zvyh5@+4#z&B{+FdbOU81bSt?}%$cee^w~Q&7*ho2&lI8yOQU)0 z0q7m!h%>iQYFo2BxNyeAV;B?TcE4NXPH&_jB=KXcR_Sr@Hd1fByIFabg?o{URng51FU&)Hp{7S z{I;x6_Vr_2L4FgCeL#`TDd8inBbaNm|1X|vv;QxiYqR6Uda(HgS9-q*G4qQUL~-NM`x2$x}F;wujfEVBpWF6p8=Nbn0Hir7cVv&?d-|Cy@&&*)~4K|}#u z?`nSkf1f@6InpSBs5{|pxB3L*{`9^BVVk^|bMoH%Ho(Gm=+48w13$OJ*s{KP!2-XX z_OrI&Upt1gjr~6!fV0OxKDB}WoH@!j{`Jg({Cno8{!eZdGvS#0jBu51NmwZ@$u^AC zB6xY$1OM8;CPq#ZHR8#6C!Roro1O6Y_|e%m!?t#)0&z}!418$AzP>#HqlgIBjL`7_ z;*X@1-~}Y{q#*LQru#lgUV!cE9ZG{^%dSriEFpoCn8QQ{`zAx5I_KiuNxknm~Z z=dmM8-!vVuX~)5oe61HD%qr_u)=S@P!5tAz6wL!0&PP)FbQEqnlE~iV*WbFbb?bS| zx{?SH7IrcIY*;flnpt`D9fZT3MRN>XoAIDBQQTdt8~>Ye#~m_E4+>ac5;`24ujr=hzV>Xv?jJ?)acQ;Nj{V`lXL^V6tGt?)GsDdM z@g4VEv&75AuYh&uAw*h{`F|Vt@&bCtPG|X<8}*>rSxQrPye!;cw$v&@FrP;uqtBgr<`KjcQ!57Z9l)Z{7NC>q!%Dy^zv-3&09;r{vMf~fH}D9 zJ&SaEmQEn_&r5A@YCn)+(geQ4ObM`f9qjo2%Hn%I2O}qAhhOdKFt%GXr$H--=0UoV zylFae7`eH2#n>+v-T8LVMoL?qMs}_{1#8Qmk{(}wQ-sGxztEN(ev86?Qj_pntE2f! zI-iNbj`yy|4KSwWq-i=hRAZ3S#7Yu}@A3d!}VM{dj&k z)i%~QHy?NUBAeE5V=HnL06TpI&FseaTdQ$qVHU~#8adwaNQK64sA;GzYO{e7ULqCx z5mChTeTL9>t)U#4dcqCPoIMj@%{Sd|L5I_>1)My3yAwocaPIF9$BnADObd|uJbdDN z)cC@1Xx2=LBlDzbjG6mpMN9T~0{!7#f=7BMgDBpWL_>R%;@!EQe)Ys(!jn@}p1wGo zU7jXmis1MWDSL29&7%{AM>0*5C;7sv>y1le9!i93LsB;dpyn*r_nyfo8UW1%gkeq& z39*zV(nY$z_(PxB)S4@+m$hlw=(5BJ>uSY`(?@%Rh(~E?PH3n+sjf)FZ<(JPIW%c~ zT%v(L!EGIys*v8(5H`{JvA8(^1 z5*;&3-o;C`t99JV^k(BNjHDflo9!EVfLVr}wz#S;bO4x{ng6u zArYF4Uymv!D=kh=CoPr6V8||eW?`!+tX`;%@&rR)O}F(uOR2XtA9*^6QUW@I*v1bK9Ja<4ba3^pfGDEizd& zG2nPG!$qi2rEVv@r5lmUQ_xWhmV7W=9Tp8WhEl+OVyUiQgs?PjQIvI$R(J&bhdAdTPzoXd5ovLY)5mNrGp4 z32hFtSUMYA1vH7n8Io&KR(^PD9p2Q=zE&Xm=Us&-Ccu&;J*#;=Z+}r1?PL_JZkp@N z@Me*QWCq_*-EB}xB(-{A_ZyQC$p7I(5pQLt!)*A@bCHIJRFf1i)KHb0VNVXf3c~C| z1hbqTXx{6AF^74toQkSoVPIH5A~#=wdn|vEtGAk$SXMgxVzB(1Qn8VYrzX)6q zy1>K4b>LN1eo$3IM7)1^3%b-Ge*9?if_tzk^1SEj%Fy>Uf*;5M3Dh>besH2Z@)Px) zwpmM)BFah^?kw4omnlg3yv_T%D@F#ZNp8CQJQs;r>(FFP7vSkyS;2$+c5G^(*L`6~n3nYrN4`64N7Eg)$g`(*Qy!+1jDd%!$@8L2d zEvdICO<5CNW_)~d+}vlO>rB=&>fIVxMMj_2f(cl@HA>XjDKz|r@!7bdYJl339x#r8 z?AF*7XjOgWB)jjo>`uuCci@>)BXsW4iPH{N3oB~%_6@DTE$bQJl18CP!m%?Z)1n=x zV`a^AdVSk`q7m9a@>@;GDoPUG*QC?_bWW6!;!a3-znF)*yN|g~`yW=fcooXq@FC6M<1y79i9wN=^&4td+8U=B|aE)NF7CO!<&9 zj$pxi2dIgPBW%)uJq@c{3S(b2GtOnM#}wH1R!eqvOp5~(VSAg@+p~CiQ*9_+j|kNn zt4gPBi-pJxNUeM2x6Ht#NHq2D>?lSMW_wAF4b0L&&20t=WFTUX_-1^^JN)-bDKLux z*j0`Gr)prIGpiZkJR{j<>?W7WMxd2a+{F;Ut_+?&c<8LqB+MWp={m+c1Po??18s** z#IT)+;)k@q0SG_?-2XoKFZm7mWZF<3YN8r8I8+Zw zn~$cws?3n3^zK$&+uWAy6DY?iI-+~ZCU&7d-Y91i2v2klJ+!pS|%Ar3aSEOz!=q}s+k*1sPRrXya@Hu-YR zh_B`W1{5Q08DUKsVCVWoJ}tWVWv)%m!7Lu#EzNabBHuVmdWPWTwZ)?uu$WcHfuNKp zl3lPm4nmZ+1zf(>fyYkaZ1{)l7)+j{y;k=>BO*3whpm-Rc8zs=9MG6UFItQi{=iTR zGfjo0p;Un;dM^@j1*v?+?(dIx)T|I7t`H-@M%q>MmP5}d%CcNXoM6L#P*9ZBAL9Io z+$QjpaV7PHQ<^+g`IhRUVnT=by4R;l921+8NiI_!0f!GnK0Yr6uya#PTfZbeJs5wW zdE;dYP-U3vv_HOgihu;uTL))|__Ha|LY%dE;VdZ%C!Nme?1+K!&*(>C=8DGGG&*$o zW$s(=6G5sJNoaE2@As$nPJy`1_&CQSq6X9;gGTs|N(q0QQ2xDMcbOBA3@cm&@dDD2OhI<*w<$1v?e+8fSt#SS=u2Sn&L+5NUL!{H5T%hNn$5P@*Z3r%LJ@H|Ph z7#~CwI3%bPF64Bq#4je2v8m8W80$RrqW^hU?4CHs{?CdfQb)bnVxo*JZYJm8iQEkp zCbJPxyeI5aonH4Q@yB6nhbU(59xtS++k6a!a#UJ&fpl$0Q|Gk0d#IgGfSnh#xzRAT z1*HfgJ~uYeI<2gE8EWHs&Kbm;S*p)%*!}A|t2=duDMh0~U zrK84$nM>M;ZA;UvIkgeF?5+5j4c91@G9gI1N_eu#4tmRYV(!3K)*RxCc;7I$ zfkoK(Vb=OWh|A!EGmM$nFGRRioYlbe!rDu%6q8I{z?Mw^v98Cl2Vo#A^*CT+L^6IQ zf+bN&hTf3q3tQdh98zou`^)~cG2}O>#zU1Jhl&6ALD`0Z8K z=N_9YXavgn_#VSPdmaZ&T|OV=Q>*IQwZhLTWaN&&s&1Jb6GLG7awL|{0WIfPIua#& zBJ_|@sQ_`o4G#NYmaoYw5ML91lXs+#dto7-3th+j_h7Y8R`-cs!ot|i z%MxJ55`cCn(8~Nouf9Ri?h=r<X}6IkFWeNhs726m_I;UXxx;B%`V)Ho*9-;SUbip6j`j6GWc}-XEy^)(11~nPo}c z0BP@wD|?dx=U9B~IPF1ayoxZB{=T$dklv!qq?A3srP%}Hx`ue?^^FXCN*8_ z<5ED*Ib)uj5k=sj1=jGKgd#9}=7D~yk+Een_21TK9K7J{H6YNK1w0Rwv%r6Lv&C-D zxB50!Gtb+5?XgV_uG_*$$R3&9YQ0GVc}C+N{fz235am#`nZCUw?GG-7Ybt&CV~6mf z`GCCkRfX^w^+sj~fs<_Yc}adzgeSQ&-t4tQDB2|K3l+qME?v?a@$sDRK*Xq7n04#h zq9D1@c&<(|V#qCG*$I1FhSrDHR>QBiS--KRZQsXM0Be*vtNIyku816%y!H<4*lFQgqX{Y4sw#ON;d>iM*fzmxF-Hd%ir!jSS%r zDfIw5i#>tz%6yZZL1)KB@_O*EF<*KeAD&jD^+Jss230wdxx<#06fUBZ;jk2;-7VMA zwP^9fZD$_LZmImTPBm7xZn&mK$|Bip%LlJGB3x$$b_&AMN}sh^pwla7EHQ^ou;;h7 zSY}qV4Z&oKpr!Rg3n8=hB$5bhprC%tO`saKIs2$ww%Zx^AIM#FwX(M(QLiefUdS-L zh~hJUoe>z6`_NQT?e?RNYBq*K$X1|qu~P$WH^9#7KiU&e5*o2JodXvQ3=I59wrm69 zxn!6Y7EU9DmtGMqY)ebCM({1SUWoh?cE>^DmJA`1|I&*yKGZ6ONbHlySs}KoR{#%w z$Zua>T3Y&zy|jo9<*5)x4+0TTOx}AR{^H@jA31q8cd{8=cxm*S>?2wBSB9Z{+H=AQ z&CbFJE&KtI|7jw4MtGM|*9Xa2!Pn$ZL7+gc@qWiO`8$sjKFXhV*Z}rBF;3^IfuD#!ow;4JSz0PD`KLJI%wBWWZg@O#HOK%n%~JF-8|HM zjd|*}-qb#Al$^aRYKUj87Y=q{)Dskt$ctgm2kF~Y#F~%fRY(;nBZrtM!#|add+o+) z=m;wPk&wUu>>NOXWC5fC=MrF<{ZHqB!P|RJlf3cqx*0AejfcQfamSO#L4riJ`n^im z8^@PgfVZx4EpYdQfDg#-&O59W`r|DLWN}hZR14Dx!4ri4M*1I|)J1qRp*GMECQAZO ze(XJ~yyF08$g>Zp=e@iR)^moq(8w4?KE-qTu*iywP;Dd~Onb|)d&Zbiilna23oj^Q z=%mCN76&i?@Z^9l-$Ch4yPFzEF=)E>&{#4t0t0g~&7L z=($Bjbw3>XVUSe}Mw3F@?Ru_R#=ebyur?pZTNJh1 zfQ@%Gy!e_s37=FYrsm)TDnUk%cH#;Sy+kP_stU)+v(pK}p;n6(a6oW`b z${3c$teRnCIQ(8q=;R_>XB*d=HoBy@8v8;h+2bq=tb8~Ww5sk4%qUJ&HQ;l?B7|Yc z>^3t=S-&N&6h-gF8#$XKzwMgeluWK4l^6px@ylt>l?y@+p3jP@t^nR#3nqAlMH|8Wn&Gpm?7Bq&SG}1jgz|K&sm6i## zOfDXZ_pLbHVd&o*x-OMZ4TIH_)0^CE9XEsOmDzAW9#N}YO>T_4JsUjt)3?5FP#a=Q z97f{n;};SI3!P(o(L(6PB%)f*wTI8Tf=#8RrLtMY3-r@@Uv)3X4LTYmX8|960nyneIHR zxV=eVcoMp`6UL}>$P<3HvVT-SV}_I{%&Pvp_{~d#wX$@Ogq({sznXI7 znRV*zuvt^8A_!#~nn9LQoz$FCjq-}@$g^HenpjtZ^UMlORjyH>Wa{%C)I_ejr6wKOfZc(3tI*dbBA7{3+4+WJYe?Ic-vAOAqQuZpxf_A(yJCTZym zY(w^E>J+#Suusm!E92e0cA&sSC@*~(q#qqjt?&=zmk?dVjn2`Pv{D4V)b&wEpa=t+ zu3UZCQ*sIstpA2-6{#as4i=gA3v7}$k&g894kW?#59B`Kna%mvpr=3aBN(MYCZuf) z3{sY8_ax`a>thv&_Zy^jMKr)p->mh2sC(~ts{g-#{5a0B$1x8g$DY|C83&cUS4L)( zC_9v#<75+}>`h1mNw#BeAwp4BRv=+iY*4SaDX`cb9$>hMj3%ko|ZX6xnEs z@ykp5#t0~>7C~U-68;#9j-*4|;9gbuo9QrYXrSrnA!?hv5TcgTHzNXs=m^W8Nk;_N zb#-*OOK#%qeb?2=Swiw=$E4PO=xy^qb~j)r59TxF)c?S~2@$S|9+F8(Pi(jhE_@Djd|Cjd;j(582>S$<#5L44c4M4N7Yycv=vau^Ke zm8TL>NnL=Q{`7)g=5J`K={LWJaeCt_8Jo+)mV~~jl)c%@)V~4Qa*Df`3PYxD=Wis7jTrfdkP?@$ zaD}?0&OT_=grTT#y(0~Z=XwC;rSCt|+Sqzekm!Ec69up{IEbr6ETy>s6+IyC3j)H5 zxOHqwP82W0esHj@m~H#R;l!Z!h6YsxC##AI5*aLE&?iZPJGHrXf>rXys?TC~rM6Ij z@DDzt9d2c@@GXGbU}wD3_#28M-xFkrLk{7XhbMaF+n-n_N~~WJ6jDhvs1-O^O37LHZd-(408N-@ zST3ImSwDJfB@F)8@g#4Rr`Wii0YI3;EX z0Q%7MJhz0nI8p_AK&J`16frSh+_Pgi1+bc5(I>f;>38;9OsMHfe1g_GbbHI!-=+Zg zX)3-HzZjt@kVL=jjX-6jG=db=x^&TOx)*Ji`@_*}zDE>^f|4Ja9 zk4?+zVUhCUoD=P$1JP@m^ZYlqSoyv2k#SNkcb%la>;e@o@8H$infU+GbNpfHfooGm-pP&#|fU_nu>hWpi8t_4y`G9+yq6vj2Ng{zSQsm+vl2FVfuv-oXb8htJ7# zMDl5y$m*UyPI1)9VEZ6M`b94%!yiZ;`11ntJ0_Ifl>-A(rcLeURIgZhk1&31BwH-h z$!-%rxIpl-nPxg6SDc6mcHbSRacNsLT}k@=qu>>#mD1Lgp0pFg&p5tU7Hh}9431TN z_Y>5;kF0|lYHbpoq$lD_-ks)qAnhDAj(@ePNuAj2H(uD0eK3#{C71kLNcbaP0^J!t z)B(eC{_3pAiuv)eu?p8gO`Nq}@PYK@qoz+;Wo4-=3nx+s-d6^_bazY&dJdw+H~xR zOgyHo8E)OicbFMhk;J#UQFAx=}-q@W|L8`U4qF;R zPBHW6U&eWp@uf!FL*E?DpfsYUWAF3TF9*?u21=ONIp-{&iWQwrET&N*!L^}R;?BHi%P3^bh$f;Gd;b|)@PzZpEq%p_TlVAvXTbyF{ZgSX+A@x zX<3H3&B{^su$mIrE9s+IVV;O zN7!?uvvVJ`9y+_v%iotZw(~RCh-J(r^FZMot>&b=cn!s;+BMP%{PJ3>k@3-=X)7ID zhrsdvm)89ApW~gDwCr!kdphLrJ+=^GJ54CFNZaL4hyAyujS!$>PTu*)wL*XZf86+P zHo(S4-x`Rak31pg*nu=*{f_^;Nz4hmA!4sR@%Y`|xo_1GD zd_*5%&8a6tPYKb4$P)Q|KFw^ihf_gHd|*q$8FwcMb$q;s!3aan@0OTi8o`@6YOZ@s zO|*^5hHH>T*JL?sWgEc2nvc#nwkt_)yQ zQC7V#3Nu4?K_t6qTwRNc4+>tVV@~ULc3}x(wwfcdtkR_5FY;5$?>o#r4i{!J1|9{d z6W?1HF_`axJuF4g9Vw@XYmv?Ii1vP}tpJj@G z*i8Fopt_o{82*)o9U&$ljiMjl_iNUEo+$G`X5{$YCm@u-TD~;7f3mhV6HcOQ+Ot0` z=RW%Kvj!Z!aurqb^45J+hV2JkMBCK3f#P9? z9~ZA37F+*r^T9rGrs4g4GN@-Q40}IP9hk^T6f33m(dymT;AB2HF*6uLcdOxv^(u~E z#igHIG{9s<0ky-~Y&0G9g2J-5;n}C>)(-E2y%Fum77MTL!{Qj=vla5qgYYD@JX#pN zQ4He9YMMpgx?w!NFFt>=3G6|c>Mc2cEVzBLm>7S zmzJg_0CvtA(5N9kBnesVH!NRGT44ydjZW%aBdk8JCEPg!wrWQ;BaoRx3>B0bi( zYH&)mPDcPfRIAm`@Z)s~L)MP5sS~H>XyPUMz;gZc-vB$}SzpKP>dwpwF>(1>T>aR2 z=vzWRiNns0_3D@XCieko)V*Vp(3Hb#^eOmI#*1@YkqW>NCKRj0C+bRC3^qB^2kT4U z1A}u8x$z#&3<)f%E?ga)TQ(Nz={UfMa*{9^T@0Bik8pZ4g>Q1j850p<+38nq3Z!mt zN>II5URlrHvlL$0TU;6(EDy2RD$_f-G${Kj@RR!69{kTE0pwAwqAj-sU6z>vj&m6N zL1bMJIgI9b_o=4^9Tg>6C_!blEgH)I?sxFs-pS9EBe#%?GTm-2tk=K%^0rO@w?2rW9GHp?Gpw^^rfwY#&=&-R{F&_XOCaIU*Hf+DC2lLdDH~y z$|Ixb#pQFt&x$Z*oU;NVZ;1M=PR&aTWMI|4P%=l2)f+)l2$YioVdG`mQ11AU!?@+0 zP)X7It9{Zpzmv{hCFzGvNTT1~N^;&;x+ejl7G*5gzGD-)2qs`}$!P(0dUQ$ak`Jii zz4R{2Ck+KKpNWEfNyJZHj!f&Zl6-K=@>Fq4IE}m?%ev>fwOpA?=Ux=K z83Gxv13S1qC)AO$%o%T};)?NYFZ0?5cYhje*|^$ygntSo5XQ$_vt^wL1i6qYOi7%L z`NI0)N{R=dZ94zHM>?b6P;Pif_qmi&E<~N`O;#C(P!QmV=6A76c~eDLuEz3`i6*h8 zzW%A379U46ghbn8ABU0G)B)@ai+$6Gqi%a5bEXh93vTLQ_7*T}`uLE{LGT@UveTObxy!)I)>Yh6nu6OGke*a2KeQh5m1HUQQ^z)uPdl!1o{x=EJ!tZgd{$=ZGSjcL2b>u0-y zYQ2{9Q&bSa_%@L@e2h`zbYW6c1p1$tCS4ss^8G512**kydkFGd|p);5Nq7hIhGpgK3#|W<0hUcA59D^vt!y2~cQ%Lj!Je45V=5O0aH%FH1&Km`&8MRv#8|q5sBa$Cp+&!UBfKeSQ zN3~7vRMfa0!zdNN2rB;&XktWqX>)FX2kI8)M^ z);11U4@{1YDziZs0d}M=;dfuho-Z01Fud$fls@(5`5s};)D`)2+0cT8{@M7R-1%?4GLXk2G5;}d#tw}ww?c7T61ZAs1 z0MZ#-B#*rbKd+jjjQ}0aGTEuRos9i@MaoO?uQjGKI~{WbC{6z*bUXW7%bwpHPi*v} z?VRY~={gK_dXsdYGU&X5xhs;SE4hCmjBq_p{!!M&UC5(Lyge5h+nHkVk(H#MUS8LG z3b0?u`480Z|CeK;|KpGUA2?TkvcYxh|Dkzy_^XcRq!rgJiKXFEh14xZNPV5W zAN+OFA=%JymvA<3?i@u$TYT?>Q1zNyLYob6Zg}j=Uw*5X?g+Hb#`B8U^{W+NGS^O-khX^mYc} zqrj}`T}D}Xsx1+SrHGZFU?*yF(gwgb?HD*93Q4G>6y*%yv9efAGRGzv z3hI_+c)7$=Mj$)zj3Z}2t;-xXg11PKx27D_GQh7XbRh@W^MPZAJ%=#4{X+osJEuww ztS@9HR-Qzj6fMYT&);Vtdxc0H^5UU8y^no1ZT!IYx#><+mR`;);f#4g0h6072FdPZ zCh?#dpZhC=8wg_JlX09Q24qr@r^&#l5Nks-{PImn;Dvsv}|y)(8dajRu=7-^t9ERq!Lu7pgO17)PjB5 zi5UeGM=UpF-e?P8=fIju#{ExH}MWpN0M zY*DndYm>Jy`WLCRjN7Zyvt``F$w zBucS-nDHew%7_R}JWBWE3||jKz6CDvBUemVb9&_P?!Nu*%3978z<&0_om@e|;^!B* zNZm7%s~37>iJljqu#!T`Vqz+34vW6emCW2FzRo_Auo18i{54mS!UeP3vnmJ3s2gMov?cvL(psQM(tgY$}$=7{c!< z69}QTOiv_M$xv3*StCkT*sJOF8gi z>CoA=ENtZ`LP$!N&%PKtxQ~$;xVd~@n!G_TCat?_a`m3Np)+BiY=AEe_vH`Gi?F>~ zww7$OnavO@NlJM4)CW}MgRg>hlTH;2I{_g9Qx&sfFJv`RW`deqJ4Tjv{1e>9QD5E7 z#*RoL%_sdjf!kDW!1M!`E)#agCpjJiX6V+W(TN)!+f%G}x!9rR4MS^c^Z+}e%?eqR z1H#2Pdn@XESN8Vi4x`=?Xzc5Hv?+uqpY-&PAIrSL??W~1GvnqKKZ=gpM0!FNHYqhJ zkGSo4<;?Lh$4mT60-xwa8(x>bhnJnPiwFPlx=`T{)%|+Dh?O+Q?#`E++2BSg2 zXKoM{2)g*{i@>TpCJ^|r5yd5~Y^om$#0<{QGvr?DiQF4s1+6E5Vn7ZTj=Ngm@Nw}5v&gicY_k`yV<(Bf0`Y^Cl_9LKCYkNm4Yl30oG zTg)RTH`PtL9uZSs^LBJNw$4q}Bx~_BRCnube5L`RgpNr%i~dw+_u*4~JA zUx=-gO(&hX3Uz>#;95(6>00;$eihYJhy7i!u{8^-bTQHzk~B(JzfxTWm;dc1mvIst zASf>DMZ>I4!4uMWH>=JSgr<*_ftNT}HSQ&Lu*KYOfjFPeA1R+}hU}sRth$|qlNjlaa&w!wwk9f(K-w4?e zMnO%w9^7YSPNt?L5QmOh7~hfseG!^Ul0Y=~h;Ji#3B9dJ$`?E)%xEcMh0wtR*0k6xzKpEci`hU^?= zX2_lDh8Zotxa3PMK6h1Qrh|+|5CRj#9*ms#j6+P`kkK%lnR58pDgO0x@tQ*iSnZK-qd&zF2)A*i8;ll2TMBSU%}Lv*;XL>0m^7%R(0fjk)Bo+$Pt%g-J(J zgrLc}cF4Ar*~g0>?w3|gDX@%5m0gNqf{X7j@*Pp2%%L@k5#e(Svs)#3Q8KSpbE3t? zP#)V8wn7b_bB}2&dq&Fo8KX`Ews>b9K;~9n3$_TvwF1(-B$1@N#NBGvQ%6yfh$T=) z2Q^;L-;!o{4zM%R>>LdB)s%~C0xk2>+?=+0A$>nVoPi8#Yb!p{2V%S$Y_8DG*ginv zRKd;ycrLZ@2plS~D)vbiz_wLYfP_K1M&~+)FV(ae-nSItb=E_1G(ew`HE0wBT%VTX zRFcUOb*@K2RbW+I4%xqpGh*0r5vsTayU=8m#HpzHArmvGjEJT=P#FWZ3D`0JWDCp* zADZ&lZwmN7SYHs@(|63@Y`9?a(N|O*b-gdyCTC;Bk zf^SY^)Jz!rB=TB-lA|*s+j9R;H)gT|D)J_*$fjsyE?Ch#@bKcg7Eu2HO#5KvkyX zNS+#Xbr3cSZEV(Px9G_~BNNjorMAw)4&d*x5dG%Hf5nOgbH6CvoIB1zuSJ- zrQ(Tgz`y0Te_!6rfW0=*-u|!MYoGaFyVq7d)%X+5kazyobI8X3z2`vxyXOc)65fHR z;lI=)5|Nyytzwa)+EAFM&Xk=n~60E5jQn#Tm&7y=WiO`Pb;ZTuqV$uZOs7%+(s zL~K&4(lZ+3#eahcyz+b;*Y)+ayBjNDDnBfB{B9ObekoSimw;6g$C1c$;*6h5^D{^` zOE$|_$=#bEK|;PkW-hTXN{A3g+B2Gg4~{A!iwvq7||Ya3KAE0C+ps5W;IM?Ilb$hT|r6!T*zW+x7HE(6%l7|eeoI(x8h zDzri%3(2IXFBMak5O&9(wCFdQo0`em5p?WcS1oB63F`Zz*R52b=V)#sW0`K(xo+)? zcz3^DJ6eZMsytqY-F<7Cb^;96QKHY?skjWakjR=D7Q7rm-|OdonOq4v$1dY{m;oQ-~o2_O}&`KK}B1-*f`0m2Y50;c+PG6A5ph*s$*OE_g&iF zK->l>Q+5fr84J2J8r^;!9|%}x^w82 zDpYGF(@H^x2_+wXKmWSuB) z4d#!)nooksPQo*mdy){rNV*y~q9-##Xumsoa&yeCHHK+>NxOc#oACrR5inHddlA`l zmO+ z?tq?lGZu?{K;|{0N=k|{Jt6>&7R{=+;O>csF#o3?D&`icUa>9`5=?wz@7xUbhCL=d zT4xh1C@n-Mtc`q`A?$6mivT+UF}(Wa*FyY|y(|pPJW~?h zT~o9!kp5!mDv>E!o4jaG3Z-zsx9*omlQ%)eu{f4zV^$4W@A&(nYd~F0WfZ&k-GY!A zzGjqt?zIj70yN}Z3kwDMCH@C;w3>2I#pce4$iz!MN zE_OL8;dj>#YVyf^(4pt<5{xID(Ve?T){kBteiVKQ6@{`evE(qeZ>{&M?|Ra*LED+1 zUaD<4lOoIxp}48wOyPAerS$pRnhozQ?>sQk&xN6M_=7ay)a{4z>^;X21i+U1=R0nLZ`5>K@ z;;dsPWd2{Rg@Pv2nz1Gg@mHEhu88mRD+P{xWgo>USpJZz{(Nb$IkGW9vXGG-z~i0% zJ<7k{VFa*)UY^6$^6>*ler3jg&FqCD=LMhiCe_%9dW0mAkTOypA4Qfq4gcE)$U2};|?AwdX9qldS|Qs1k|2S+q~nl9G% z;o!X?k)wgXLhj3gZCA`v$xH07ycofT%yynjJ49wJ8B>6WVZ1u`cQHru^z8jr3%M;6u;t zmJ?NJX&vddz`%i-xY=f&4v+;i_DRpfOvLH!PYG6Fgh_4EqkQ zC$J*T7+AP@>2H?kV<9?Ymq!nx0t4`|Sxf!;zYNoN#l>k;Qti0s<~;eDr0nKJ_`bjX zZYRtt71N`3AW+6Cj^yP9v;{1L)shEbm;Fz0P>5VTPrHXLC^=9i^Z$QKw%sYO#7?^s zToNOq;R??>7_UeEq7zAbP{GcB%jWX)Gh^TI6ETvopLZPxAG}dFSvcv@N?VCczh(D< z-=~GB3 zf)W4~;T?D@dg;4MC{{4k6ra5ewY#=)=r~=ici{=LQj3Wp0`bYWwARg1c6_-<@zaF_}qyZh{00gGiog zkBQm^h1+W2trGON^5-FWSX0GF&OE}%o%9>puDko1PiW37$?VSZT{2y(PSGikor&0G zmLS?Y@kkLL5-npZ)&s0dLW_*u&zQDgRYk6dH+_5iYUqem)7{CfXomBScOaXnxEGJ8 zZi>JpE??tnem`$2`ywsAJs;=4&UKz<0S`Dj?SdZXX6kcjQ)@txH^Tw2v$lkiQ=Cq% z&!C`RAC*K$7d^giebU1FsW%Nz5T+Y98&}{MAe`VX&#lfelHSnKnKNr&W*{0e1d~=~&4xg#=P_!IlZqizZ@&;um>0Y8y7Qwv^dIzAJ<7?+7$Gw#aU66 zXCK{moV8Ma_{$LvDGxv1&@cqp+44gUt?%v;wxl9HO_?)DKA*n}`2o2Ul1rk^0{$cj zQ)?W<%Tm*fXD2Ba$l$BmXIjoaQ&}P0t~!~TZq@(kX^(%krrD+|mK{uUvI)nYf&WB$ zUcIFFHvS686UYw*vys=3XH)q7 z%PoF%-#F}Y8v92&RDGo98?I2Fk==+T5!EVsx0?}L(Z*^R!rRs<$jZ(ei$^pN!x1ny(w_VANZ!Gy>Z`?T8bK+n}tYziLERNM6=p9 zO8p{y-GcREm?nq~A$h7deTT(NIRd68kphpg_I@Y9(`lXlWEj=T@$Xj~3^E5Oo&DO`dlYDa(R^K=LeXd}cIOVB#uTa`& zDdBTzAuL4QnsoFYr$fz=XB-gpz^|CTs_Ik!NOtiSHJR0n#ftcT4JxLeefTA3=oh*6 z;b}s-zK;{>&h>p~gW?2c zy(A2D)eWgHOidhGR4sJJLBrEA0}P5c3Yh|ZuAR8wA5gt8mW5}DMl`BjmP^^Ekv-VK z`y@Ujgfpgr($RpRS#(x%XPW%+aS(int>wD8;HaOi$otm(b_oc%C&LV{ssoc(zjKEE z`tlGlz|N5?LWGi~BodqKpt5n*0mJBKLr5gt54m-n>eO z9W*eI3%%HKmu$7bAl=hQvYAMRtfx_-nGH+3X^yV){%Pc`X5#yW?JN~qBTsM$BD87d z`pi7b-ycXRreMt^q4bZ7I~*%r*Ll#8T#GR7>T`{@0Q*^H)2;Vc2R{$zLX31~$mz*W z7`cm$E0QeSZN*s%kh04&0ptl3n%vA{FTfq0!K&g=JgOIX-~R&NWik>&OfU00f-}Ep zqL^Vh;p**7elHo!mPen|afA0G)@LSpf!}DKKi;sj<9u&HP_*?(`)&$T_{T;ijV|JNRQm5=jFgW_Km=93kbnJpnyzP58*PhGe>c#;M3DEkPs6Sc zB<9zs)57%N06V9~*_?ibC&vc45pGqsE_){|EkeB?cIOHDWX|6E38rM8IyiOVTVk=$ zGMK%Bs+L*6#am~${*0f?uhXd7(QPOzTbTjPZ*gnl4I_3&MXepbo=+ep!E-X)81w1= zo4dC7*TASyY2_p*p1)BgTR>)CEn9#RM#)~=llXqoEHw->>2)`L*?t%aN-8yOadj z>AWT9`IM8s`cqyY|ETvj21qzq!=E)EL+3@`$hI6HupcSXVd&!W`&H5pmiguyY9l=9 z{T-+Ygjvj1>KXqPQ*~@s8rsM$o%;pv&IgKx_w$omKdLr%DgxBFfeD=#RkOM!4+A$* zF!eX`Gb#81!f}FxYz-Vq7g6w4$JOFzIWNQsn*bX!cQ{-4Ah@|Op`~EhE-4N+Bmn20 zTSYPyxI7{yb|`=J(vlME_U!Wb>HM9Z+b@_?JYV=~cQ)r*j}G_FX<5}b2wsG}bTvd9 zu7lFY<~RJ?5Lqvg*llcUn=kVilxW^Rk;@MHMqICKOZrnZ_C}ESgff87oa0jERW=$X#n0h+(KaN+OKLqmwN!e;1`i5gEpA2Y^$k> z7VN*bO29GbWG)vzK}FIbUFn1fp>*JVn?PQ|>vs>+GdcOng>b$|IK(I}<3SU^&fv|d zxUVL7zSrQmVZh_*h1o%~Z`UznJJJ8-aD48TEvW-fFAyeto+p+p_U=KTt~WH9u99AD zKM06J_M{4YFd(p5N3a}itBSUEL@nx?0<#&ZeywlAWZKrWGP;am^D!q_R-yuIDe2wwbyQuvTD-Tt!N{DVFYGurmp>m7 z$uj|b94YL$93}baVYD?F~CL8=7I|K?8i?$V@U_>;i&BDt@{z2Seyrv{W*gvK4--`rU zC!M;3-%e-0qMa`NF2R3AWo^VcA6=sU<(ie+f267nSo}sQKk3-jTzu2mV+LUt{%*ba zuURmtBhR1ehHVZ0;zAJL{HvaH_V{}}iA8SW|K&q-oqmZDzdP`TFm~@GO=c?e%L3tQ z%7d-*+8(*;CMNpg30e|quLo+kO43aiyqtCTod*+xR_Waav+3yi5?yp>883zSv5qny zcSQcq6YHKfF$fp$IJU{wB%}!punK)I((Vg-9Gpy!ipil3*R|0_ko}qy zBIb5~Kc>;iW`ln&sSF->W(W4#g;tNb{jzu7N`Z>a3C3eFS$oD`kET9+B^cwL`Y}Y# zd+S!*HQ?P5{OPB6609PgJCz$%8+17So9`l$d}Z=ojj(i6o$uV6l*D%w>tBBbG(A3- zpJ36REs{f>ibqJ@#t~UQ|Lj{<%-BQlaJ-ss@X13+Z}9Nk%i$?H;}O-pM<1oEoVE84 z7SNPM*wj6w-uZF#NqSRXZ@6-*W6Rp#yW*hxV(|AvT^qYmfE`Kq zcth}FLh^@wUS-`PwiXhc5BA{+X-0qfNlu@q&5g&ELUKV-@my|eBPr@@Q)x*Ty!bj2 zYORX*$aD=#?KdwOOJ0PvOp4FyeW(5OG{8-4rA)s7Va+rVHN zhRgB|yeH(nG!XQa=|&ELV56Gx;g$DlxL)9)NA$e>$59icIQe$Pf`gaZQ^WJ}$D|T% z^TMU2rOze4l976iRVvWYqRu~o0_-fy&SqwAQq~8=xaBKF9b~$4yZ8p5C%hBxKtbC zq3f1ND4pZv4}K(>phvrg>2Bg8VQU$|YLGddOvnvys(sVYJN@n}^a%-8tiDM+mY90b zfsDM_h55VKi+J$3p9xnu@T>O;AneLN;*`1uq|LojlOBtBOk1AvtH83fugaV=k&6Q^ z;b)}tBR;u~lD@0QniB~|_}7ox8_onX)~_Fy#+1gy#8R*@Ne~F?t7~F48$~(#nUWDw zqq~H?em>8s*+%h6j}ZgAk+uM_w*%G3CwyNpIJ#Rh#Ox5t`GvB*O_E%eD_|u6@i$E6 zTkMP8Iwe>AghA}fAw0|U2DpZxo6y(G^g3}OOp(z%^AfN@3;rtrJ3G<79rXPp%w+xT z1$XYeUx}yoDrd0KoN|#JSIz_P8AwjrRJg|dhfnO0Mz5R5?)DLuCoU+Jci!2%y zgMk#n$oS%b+ZJWa6W#;OE;3D6>D*}MIf6t^mOfb~(`C8ctpH|USESRheYjL<&TQ3R z{pTI9bp2}6B*l_xSGtRArGURW!w(o5sn{Br99WnHW8)B2r#p^EZR`Ce4scr5)2U4J zMYJc}$a?+Q6kzAD0W2nV!*hKkYt^^k5vu76SBiJ!8@TYxTp7adCt{|OYwvQ>W-+uw zQ=bkh0*A+o7dHrDP}-|6FDQEj@NyWMwhM|I4`t@fYy4i>o3;6Nd+iwC-)6Ayt?rIx zyl1aqH*#EIp0c~}scJK+!M-hYtRYsWV`Q*p`U|iFYnG(O9ow+QB)>sjr{6LcJ|cfy z*hj^2b*|#$Q=|^9C>8KD3UqkHOVhD7u)R+`#K?%$CR_Z3@`^hHu%DIOT9_n3sOX5v zm-)(c?5EUvJe;|DC1jF2Nb|sca7+w`g+#Pw+MKgkFFrdQ_@-}axUJPtH^?0L&c5pE zf-JJA=k!rp{1o*k>(e<5l9|cUIpg+I?*ZH5{&l;~gBtuI;H0B89W|I_2pJpGyOe7_ zHx#TLFp9Ryg7k{)jlcmxW4xK}%(YF)4?+@CU5d z`rYziid$N}imOF`SvR;{GY`NKZixuIrBH_e_5!n(O)-*}Ec>01)gY6JHZEC+%LU`Ieu z>TjQZS}ghngRro}Js#pYf)8*+kRldtj;8%AWN)IYoUZj^)CWIpxOv_0F@X$Ii(E!D zx2Gm}=zZlO^!?r`)ZXQK3vGsWtrSGky-E6O_)Qp=N)@c2a22@_6G!_*iiRn3!7nkU zsduS!S{%U{>Pfv!i?F(k9C*_|tcoHcHv~jPhqi=muvc*9lk0nFz#SdWgk41iF zp3VN$z$eI{I8?=|fQffz)o1L-R|AhaG=%+s@m`z#f9+ly^i6!fG*S+|YH0N~n?zb! zxPOwTtbu1FbUo}OlfV50NF8Q7QTICMOh0IWS13Qsj%Em+iunvzc}@yvBxMWwIzi=V zNVJMHK0@KJP)Q}+QqAE?#+pt2_A&EfcELOYj)dfD*_1WQ$uxSA9`}Yu%(iIZWTj4q zmK5axo4b8^ZiC|y1lsH1S+d!dz?CHRtu}h=QSs4exQpkT4j8%LxlbR1&*6W-nn??Z z8Hsa+{Hk8m0M?68JviR!Go-=Jg6}RxTZkE{a$ znYY14kD=z-pt4Xbt%<;+_Xl{Tz(Mj`?$a-d_S(wlpQ`K=f5ydp{8H^6bknC}j?R}3 zhWbnqp=eR%;eQ2!NEKuu!leEhuU~xJx{Ou*s!T(`^f{!!2ICG1$A9!5u21Eeu(G$V z4nbt|DUKUcmTHliv zSS6(FVk!?|p0Tk{)@@8h$uFInPE2CM%HlB%7Td)?TW{t@y)+Qt`xF#ZiOV^7L--9h zJN6ljPxmw#Ilyxs(IIN=Qs@qn>w^)dY<#auOFfH^Cd^hh(QX(qCp){Bd(u#w;hSk! z^07%W4uLEsM(7ltEc~&519;pSwHZRWq2>WZB~EKQ9JI}fh>*Ve=<#QSt3O~HC;64~ zCa`(!?{b9vjSyZqnTVvrxYzx!7uo)Va$H>ZxPQu$VLzD;X(zW&uWJG_mwqh!E851@ z*M#t}n~z0Sd8O44X0{`AZD|8mp#l|lzu-CimGh9RI2ONOsKV zjF>?Ut!r)5{!I{))!Khd*-nSEok0W9xSa8yn*esE(}_af>88mmFCdQHLHeJgf>X&n z5S7c@3PtjBFYI`YDnP$_Z4~}m=ye8_Q{QpT<;>74Aak1YU{#k1F+-t2xR}G$qvkL2 zhH!kltavdVa!_dhGOWit4Rc2+TlkD?@m5mHxiGq@>~v$y{-sc;!qhH)Ofj4YGM4?# zW4QqjA>b0o8qvy-gw}AL4yuM_8haa(p%Jp3Bcbj!xTJT#$z5F_ZCBEnI283^5&_tm zQN{p$dQ4K#vOiBlI@f6)M!P40kXu-(I4H`Icd!U_?tu#n3#moCC4A>-LG;1CJ-3X4 zs$rPGj4uw8q(*cx;u35h+Y^wj(wex5kJ`lPFciSD73sCEhFe4h29EI_z#5JzzibvB zb9@7`5%@R##9nFGjIVtS`bHz15A1UCdFcWldnwP6)%7;|0}Q(fWvfT@#!W^#_L zYj{aS0O_s(Ue;wWH`mbSbl>NPH2Smm^E1;*`S{J~Dena~O{6Xp=wA%jc3+05B|9!{ z0$q!Z4fxb;2mhH6PAvccua2^B!5}qB4JIz0uq# z@XrexszfS8Xs~f=rr7w?eNbQOA#B;81+f#rH7()o3#zk^NFC8{OSBpBS6mAm8wvTR>JadYeV#zu!`uJ3F}kpw68p=UmcA3rGBU_j7F0 zpPssY`TS8WF@+fM=#H6cLnfwUM>(CyC5P)etK=;Aa{VviN0PpU$@yJ%>F-~z&dX6! zRqLxmP&oQC4bNc=(YE9gXKr$=_qxrBrJLm_X%wlFUIN-%B82&J-u2gd5fxXu^J>)P zQ&EBHH`#RO`85k#+m&Fd0wk;wQGuW`H{@Fyvy}tJt+H5ecX|0ob+gCH3~o^Q5Gwk0a;ICgeme(l>+m zEUpz4ND7z8NUx9xX#?zZ4ni)UGhF#yHP3%IQN(TkJbSS!v|0|U?N&0@-(sM7J<(Ry zGF9M9Z<|C*0fpiBXGvatkZ^@bqJ{T$9R2NnV-k#uH?@V8(o(sy8f{biYXnS1f_vX? zUWUIA)zu8Jx4M&iK%1J$8vF($d^y^9(2yZrV^##MwzGgkWvr@~@P-@J6(~~WmBZe<~ zGZNh-BrNm=;*9}k6HFom^Otm*_BQyd0Ct80@t2#^Nvui%{E=@pD?SXBj}i5T8)^91 zKaWUEbs2+H%lFdV;BvWOeJJ#d!?mCKsz}z?}+(mYEt53kiE`w>bh{T{;j))(pe(uquro#Mm!m1)b^6vVBi&d+CqZf;tX+qe1O&*99T;pXA?5lXDRl7BLE1xaCm-PiZ2i5UcLgZcX#dSo^g%35EqqKN>OotWQCHYf{n*W@1=m{cbxzH!|l+596 z<;@cb%v7Y>T*LTlV^29YyhpD*agE{QR$ecrsVV<>U&zO*^Tqq?vdaRUXV@Yto3-3V zA-vTQqUqc|x0N+!wO@i>n~2$Jy;#fXX!&`|>)RjKc_kQ`Y+${ls1_Y+&ZR42nJD4R z_56FnIhpkf%`e7}M%A(>LL`f%75(!*?hdq{hm%t4>e{WSS$QUtNt$LZkNmhOl`i9O z0h3}>+0-e6`(pF9@}q{!Z_VfF0d?a&gA8{L@6WyDeVpS<6jrTL%nd=^Q2aa^^(n;g zMv3*#?8i1@q6S~jd(adnG)s2?-wWm=zo{omAvwxTr++;^s`>QrNVqS`7TOB1BfA?>5YldETT%0;iuE?!0?8;ZX^^JGIE1$QQf(&D%cylFq zq+2zEFWvHrfxs{9dLEArlkmWbuA*M%<)#d>81qw0`&v;!=sS7RSkXTy}*nA85GcG-PRTex+gKfp{(BAD6fPgxZh(*A&Rwb>z=5-Q;N$ReU8$x&rRsZI= zFx|P3IP3Fu^DyeN~8QePZuIG2uyRDK;;v3Pxv$&36)Qc8z(5`D^Jw;JR27#n;RlPOEDZ6Qqu?;}y; z+_*QdmjQNGN8jWS?B<5D4nt;QxoZH-U!w|Nq6`vtY(L7|m3c$-XZU z$~JaF$eQe-RVX6cj6vB#D5SC^TMMNH+1G?9TZ^(~OLj8W`M;*V-~0XC^S}Rl?m73K zd;Y&UofLD-V_svtpUY!;={7KQ=RLQsq&DVQU=Cl`yx20*_wIaH3mflhpSbPKbF)%s{)@z5~q-*hgQ(5)?mUzTIY% zozD!<)dZwb_?EZH9n5V2}rr|Z)v)9ev^z}UqJyfucss4Q9 zoBmO&j#7d0+7N}}?_4Q=jzBQy69jl1uzf1YW#^^&DNQ-`pB)t0V|?5T{co{!UBui% zi`X>pkD1NA%Cs-BahQ=3s~(EnEm|7PvzpV4IHK^d?8Spu-B0=lc*_**4!?x4IfogH zNzX3-a7zl*l6`!d{Ju}5d0Hn!c&YpD$9M+qyL+4GZ4laVkAE$%SDfz=VhxFgN(9B& zDn=aAj0f8yV~vXqm>JFpKj*od>cQS(7B(C#JC>-pj~Q>o|Gf5tNA2(OlT(Kw%Nr3B zkIT!S0FEJSzo=fXQi(e|rPyNcGnQm&#aF3R$kYzGOoii7=*O(UPcVPa`EH`odg2TR z@+aKdol+$%bc=lAUh@SJ3#YXoeVv<$3~6Kx=56?|^|Jne4u?;U^q&v@5h_Gg$#_+v z!H93_W3~KVjpu53+(D?&UROq5NU?cio2cme>Q0LJ%`x-1=2cdokJvhULB32V(m_iKd%9J~!H zW2^^J2HQ))RKJT)fS7?;Y_d*ZhvW9Wt1AUAUlJQYP8nV&-tQ>s2<6@F7>n-?3Pj$k z=hGyfF|*-*q04N|zOD5eB9LU}oMdKlGBX1&t4b&aj?r~!L$D28AYG?0@~pVentRvc zEmWS)ot*pz`lfwKt8run=pf-C;Qj-fy9k34KvwgG4)k~%Lah*kH6E6LgeL;V*vMrB zBrf`>sAA+4yr2z7%W=^RID4x0PS}ylT3a-R;7LxqUNdzealq(bU+s-gQ#0kUuT`i( zkm1k)!G1b9AFdhUJ=}6p2@*d8Nn$KorEuP_cE}QBac$^8+_!NeJi--PJVeewhFJpu z``~5FWo*g%htz#p`BsWBS{GjsMlu4d)%I8ok2>xH*!TaUYc-llmOu#(bNs2wC=W?- zaUq2R+Yor3k@6OLCp-pn3-H^YNy`lp=Lh)`?0P3@v{IWLyS#0kyO9F2uX*Nw3)@6uCJ2Y;Tz;F@yXz$| z+ms5uB!|KX3FgSV3=j`n%0r>8vFb3-nNexA)EgfKkR{&MS>;&6~5+|tT8 z+2!}wtGNx9$C#J5+~t+`YaI(uOMt~m01_F%&X;-SSu=68ZB;YN>ijqcFQKs#dV(G0 z{f;YCVhkL*oI`wkeB3Fh71l+g0Yw1GJibvuE2eJGXdQE_B15|gr@}e(P=;GC@Jn{( zTzK#y$fw*iw-FDEp8mpBL+hpIvBieNBw@~cLa~=}W=7YI_4`3i9}}rzI5x0TF8mpS=HtGP)hW*tZ+o`4ZG0oUbsYfoQYjPc-#38_e4iEKY-WP^lY z^!+NohbeL@M%?1tYo`+9-slSUs(*_bPh!h7p*R2chj?} zO_OFxV`Gv24Zq!KKSZL~zVtsJUBAmJ?c!a&%?bsuv|KzFQb9nV_jNOc+iY$mYFX{T zhc6VxD(z^xDXyI$*qqwXEcfb{>XqAqEbqvHozM>g zR779qWm(77FCWTJ%~1p49zTBeo!!w|_1LL(fsPKL(ix)Uc;d61sR@$6gGZI28vdTe zYwW&irCVw;BbiBQMb9Tm;fT%dO^acOs(na*+g1t(Yp80a0DE0oiMr`S9f)~;`$HhyQVTrmTSxQod2yg_%Mbg?u z!KST3Di`|w0Cr5!$f<~~b3rdOu0NWz86)ZDAF{9dK*{V4{~8uGEy~=fS{ZboMUBuGLNvJH`7Nfp*{+yPp~S4@8Wb=Y#gB= zA6;Bm_IUhyYXnCYiAH~3rlo%@0Sc1{^NCaS&2?$^uBQ+g?h|f}~yDkHA85!cXWrcT>7rrN^Gt9fa+TO94*O%!-{J+8;2ua z(LCE=Za!Jq`eq~Ha(1c1ZO?-xnDj%u;v`w01;gyZuIuQ#5R>xEy5pA{IA4Y#IG}{} zTJrYwRhA3zLaNnFDo?~vEzrO{`*?+A^4+HoKlIf3P=BA0t&8R)8O6P= zb$q1n2`A%kx<+F=U`GAy0$G9N601lWV;||6A)G$Kc&G2^xq@)zf-|z9@xCz=Lh6h? zzh;tq?XO1--Ka(_I+I$FiL5T?Cj3>q{%bf5%tg(8QR+awI|Cgrkv}J?X4kR6GQ+3c@o0p(y{VVw%0Pz1WH-Q$wTi^& zM9-?fE#b5f8_2c1ojutqdRBu=-tL>JoLQZ6UD7X{-5{y0+hwk$rN^9;7j?;2Nksv~ zQg4v**0v^T)DuYucS~UUx#Gbx6T-JhN+OHmE&2aB-famy%@z+Ye3eUZY2U1-|F^9Cg=|!}wNL zmrFOBnkNYC#c{fpr>tz7Vvu(n1;-`;cAl|`i61NDB0u-DbbO1ZKi`VGEKLRe&Loyi z!1KphjUzW0ORE`2%C=&0&yXW6|E5;4h`>NXwynT-d% zcJFTsEPEL6b(oC_Y;u@HzZVq4RHkwi-s8f=A$N_%Tzs-wYXm47J-5QYt3Z)QBiFN7 z#8mBFEx@3;Md6r!7iA2<(5-y9*Z3{v=H(fdiG)3uWSzy}$32|%Cw{r8^PqA2C+DyO!RgUe0)%_HSNpENrCZDHw(6asD*~YJhzHOzI87}Elw{*OYyMseAJ z7_dJinQfOdpR?F*{wo+xA{N*^z8caQ!+!pgECTsLuG)U}ZLm(Q(0UE{PQZlaYOlG< zwk8T6JlWo#@qY6%X@NZ=EbMZgbO9;GVq6B3Tm3?Zd}^ra00ZmuZ@uP=$YO@R(mqFD zc_WD19&sd(9e*(t!)e%AiS=zhK8^Xd)U*%mwfX)F@3r~<3-7h}+K?~QTf*;%_vGd< z=)~>wtOE|B=1>!i(-6VSJ{pB28rrnALOeDIqPWN(l`{_}w^#DOiMIEcx7XPfz7LP8 zb3c*os-gKbo98f*S)oMEKO7|1Ma65{*cX7sa|Xg$Pza}Z1g++_VZN+LmB2(s76`5m ze~iQ!9e)Wtwr_lYY@yL-go%s6(K~}hn2zKRJ_*5R&wkNUB^Qgt_U)j zKC?W2mPS5y4L)0&H#RoTERaRpVSMCdt0vjI?XCf^?>};*zPv9Um_oc86JnbvV^oFn za=O0(O&)~wy~Z7EfHPmZ$S9E_Xmb4oLn$1@a4VlNc(ygj)o?<LqI`U+!W=I{&%fHRHVYiS$L_iuEOzM4;zrvNa z0OJs&;O1(1@fS`j@iyC4UPM_nO6bG8>kzv}T1JBI@5M0!N6PKh-mMV-_^&G*>f!#^ zN_N(ssLZXR$fDv#Vu}Dee_UVfGk;K2vY{A4_ngG#XT=46+Xn^hfl|=tc4~ z;Ay5c&CtX2gP3fsKOl96D(eEudA$NKmgq^VR~-Ep~`ORUBSq@lL6_9EZcM z2Vlp-m?&LF0@;~m4$cRfTC%@h+#h>CoA%0jrf}&e+P^dX^-`#N#>Qz`+TCk#rp47@ z^?_^<3Z0SzBDDkN*9seiL;!Y-*2*b|Yq^W>Y2F8u?!u4P9^bXL`$}B{w#}}K%E%l} zDB)8LuNoK&7{JuI(#_Vv1rw2F^;-enA0y`c^20{d=KHc`?s^IHdgvs}gH?^Z-{caMJ>NwYcV(mQ_Y414$F6u{0|mvq8V zYocu;)3l`QqSPwy{Gn{S3 z++3Y^Mnn@Ns%Td64My9QmBj@XaTM+<5KPWiz(VzX=Ghf&qcB^fvdY!>*sFVQzOUCv zaJRjM)MS2F?{>oglZEaNWK?*j;d9EVx;p?nclDL*_tB&1M{A>^t~7?7>ThK|ETckp zAVskhDjiK`4su1*qgf?lmdw(6B&AWV(h-)ieKBXE=_P$jm(J>_Bk{PbM0`;q?vqa% zJ%B-w0P6f1oyo?O&h2U|9O#q$0&tv!_}H=&>FYW9HP(8RK;Gn9la4-9$|K2L%57Gz z<+YTh0JiUY0yvqPksHWbnuQMMm(vYsJPB}B?Eh$Y5; zWFFJLN+pehhn>f8EiZwgNCw)1D2>5gJ%T~j4Ap!dL$V*V?-&3P6DSF^T&i)k`$zF; zQ9aO3fSOwT1*oQIf7*>PVW4IK>SwuU*xLtJ_bSfyde$wZ(5?*r(l)-Y+77TQC;s2+ zJ^t6G^Ua~EMF-mlP3-t@UpVDMJ4yPV=xlIwy*9Jr-=3pM?jJoz7Q{oJzyCYu8MGDb z6S?{{5E}fSE{xuZFuM)C-u?QY0B9;A523>fDh`MTB_3j{>HqbrQq~AN1+41H>b@h|?f)L_)>|jEzYLT4&@$2v1VOvJ>1=P!;kyAvFZ4<))af^?* z6Z)Z}5cr(y!X5QGs)R&&m+7MENDamnrW?_O@4Bb7Nt%dP5Er^f=Q8gFi2y>Jh)QES zV%7Y%6PVD-OTi$f5#7L``rM6LyPIKbYsxP$AcJSSS7(n7*+TYsE8px?PKW8C+_1B z36QEE@w>!H(%0Vr`@XHC*(3NEDWPE-8(^G(w`c@r6t`d6oFA~C#~b23PD#uZ(rzh| zNUO|;pI6Vs)|Z!9;^mHi(qI+u0i`!;tn7CnjuLIqX>ULjdhg$!ZXQ?7;zn*6c!Z-+ z7_+vw`DjWyFBK2BpE=}T`J4~cTEvCD6XG>P-FHBH@1IG0*-K%+HemV>W>fnKS0pIe zN5#qT&2h^oQZ9iF-|7xJNcbh1Cik!vz%wrRmKI04EzLSu5#+=w1> z$4uQ}!%-eIn*4U<2jLu$1l zn5bH^Wxv5E*|pW|aMN3@SpYllm9LX+F0)NK!2$0R(7X3s%f!*9>-`S$3Yu=1sTOnGjoYL%}E2(jQ_MZ1To37Jt$X7kxUBajy zhNo`OCf}Kptz5Ia)@F?gB=VPC2i?5GFGz0y?EH@q+#DJE*p8bloq4@NN@T_xj_Ee` z*N&+=mt+-8_i(^tK$v1+Ab6?=GDuMzJ!cBqtU64s1kAK1@85DM`Oq9t-XBzMAQ_xk zX*f5Zl(lWsyF=*|W#K0y6(h$eCs^VKf3V@HQN$8?OnBbTKXb(<`vxOJOWq!C! z8Xt)O*aaM2o@kA4yvyDg#&vnkB7PKcx46$%+qqa6HJ6Zn!G;+z7r6J#w)BObfwfc^ z`j6T-zu)KokSc-*v828HMx&8XRc_J>T8v(BLh~JSCM4CAnEv*cK*Y3Vf>v%yFfdu zi~ZI`;J6k~iZWjmn|s0wjlQyYX9{M*NxPMw%(ar@0CvpXQc~OV54hFs>5V$81oliF zhVF&xa*12E!l!O*qP(u{z5pe$w`yl6C6`(nwtYI2Qp|pbBoDG&Fj4Y$SyQsvlcrj7 z4RSV$N20MXgE|Y^)^}Gy+7>G9O85R4-3UG@Gu9$hwn6mey27nO{Yo-?=qInBhSa*) z6Ul}Q-bM;iApK3nlm32{KtCV@7s(NWrh#qsMWhI(7wCB4yu1<3oC{{)SDM=uq6ps| zSyJ7PIE^g2{|u+AU(}H^2QNjMRvB3TW+h(it^eW@Q1@8!LxKOJ-}{`RQD7!MW{w3y zU`J|$$V$o%T)Ve;3FGvX8xu@+^{WQQR)Sb2q#Wg}gLD^Y7TY?6!t3^0jgK+B`yD z%M*j`Ig9gXE2*e^c!taFCXYdpUlqX4#hy5sbSGglHmdka^_ShCE1W5w{4Imv!k>+~ z4rB93Fzm!!tsw@kchMGK1l)-AvJB~2ghe+N)e`^D zZ{#9Lm?kIpx)ob(+FV^dPPYrq21cNfF!~G|E6OmDeIqv62kv#bknTN2ggZd@sB)o- z_(jNWTs!{Iq-C%%^#!n4RY2D2b?SpgrH=|B9qVYA1H#YU6zTOGHY)F591G(=Gv#f) zj4^fNV2@OSoFA9RkJi%_iKd@#hPVs2q|_=bFbn3~Kl>&tM&ri*x+9kJ0Q;f;pVh#$ z9R>XLz5bbdv!7x4{rEfY2MGZa?f*B6oC-K7e{$jwT7PTcFWLXBfeE-p%NELoe1pt$ znUbDk2;su~bd)*N%o_ zzAuaZBvck}m2@Aw@olF&ol04m41F4-r*C<1vC(p(w1dVysIcNiYR(fgDRKB%$WW#q z*88gL_-pRel0o7thwyX4gA|!_aT<%46!GN++_Af7_ysm|k!Hd999EDFICtFB;EJHU^|c0k!e=2d@uakh(u!Q>ep$7soul_#?%A5Q z$LUubP@Y!{b-vN};_6DB@WEdpIFsFi(v(LQT{lJYs|uX`SQg|qSRPR&p2*CdkTT{T z`)Y3)JrA^B0Y zQ*Tj+Vb}Y2MLk3CGnwZz#~GKsk#A2f8h^`=Nl>g~-L^}Yaa+J&RhA*7^~CY?}W1mMWD_|G(5Rtg#_4-9REMxuMV)O zQmyu}`ZMOR!TFH3?9g3&7n4`Sb4SgCAHw;s5e06G%@fKv8I>5=9%{Q;lxZ~^MmA)i z(Fj`?lwD-oCuNT)|6dns$Hn zBJf|kvVgzu*=3G@zGsPl`qsa^F>G@l_ESaeqmssW+E*X%iof#ndMp!&lBWmUZK4V; zWlCiHA(X`|2|zw%U+tS@5cmMI7>iK*p$OvTzFeW{TRErLLemI{tsVnxesal>lMX7P z?5&thote@ktx*I1vHRXhA8It)`tntL;dU4ioA?HFa>sz=33>Fc?nYoUKEJgy5WEmJi@V$*d)p_9~IkKO;%sA!RM^S_MKBbHi)opahnk1<}M4C z$3&9LqU~#?DD}__!WhIdvK1|*$Vpb+efmD@MFEO?TK$+~R_s7_2#PDc>+Yu-jb=54 z?s{}<8R6^Jjy9{({C$y;g?Tc-E+7bT@?zYB#xLl;39Mlxrg%^v@r1*D4=S~`H;|Jj z8a_53pu|Z%K9Y5fW0>Vf8o70|9|1VHfI>FxO{L8`{^}uj!CQ= zM4wFV81C}#9S{vW%G@;C&=_jbqTq`;U`iX>tsi1tlhOdp{BRSfV-1?$Yn1@rt<{FMK(;*eR62kZ<2RqC1{B05)6eNJJ`EN|b7@ zGMCRWt=F%OYU+3h=qdj7A{K&l1ImN@=F37G%WJAv*tOs45m*#MKg-FT2+kdOPUVUa z-yhjfc5XkOMbKRAqB{6_=Q7!v2nVGN%Ww%NYN-c_t0IZZ=$F1PZS)K z4o5a1TJf$%_vJ!vo4Q9njC|#$$Y=WjVQC=5G+#9-1IL_$@*stga#1mFfSubos!eP9 z6xm@!1|B6RT2$$Ek|*opvp~DEu0H}S)F@dny#K5x?whO>&Z*7T^Jf{_+Pa4(8=xrD zCjI3%2q5)iMrG02PH%=PE}o$8??C*f=*p`*=A@bUt6^M&bFa~=%lH;x)U40eyJvXG zWB)#hB!efkq~M*PBo)UE3$cA_*ujcYiosD5pnG{gMo^Cb{^*9!5Q!_E+dj?Ha^g|H z9_c~cLSXo$p;bV}$!%=9c~{g;fE{akxHNS~FktX$u{LXo=4E%e!d*AV(Mg|VH<6ja zr`7$fI5jx5^JG%$M@#tlTIc!Prx6cNEAGgq6euI)?S;`4%8wn#WDgc%A2T5nUeios z)9Cj5c#j=IYNF3-VQinygYCYeAk#+y*Ag(F_}mnBcd25dm^7djFIPB~twPob$J-N> z%YCeK)(>Xd5*(KruB`hH-pR`6NXgzPOTc#KFeQCcx%7RvMk}jyiaU~#XXcXWi$6ZK z=n7G}0ov-^>#pC@SEAtp_MaQnW|)x&$YcC<$(#k+xf_BH#f=MNV+F{%@R8I zk;P;)# z0fabu+y$Kkh{JIc-d0qVO1>$h@9x04?*X5sf62+kR(^EZk`S!mi5aA5JB2!SK zrv;@oeXchPVvcim+@DGFf*)C3_4P`?yf58i2$|gqIt@3hXa!EjCNcW#D)!n$lP}rd zYqJxQk*Cc#L@j@rot&XYw-{kq-dskm$kU=}W`? z*jvS(#%w}fzlg8An5prN$cl`(7%`hKpReIl47g6%9?m?YEn0JAucrL581xdw*k9fon zw`d20tQ{qVPg2Wc(yP0dbmfj!_yFv9q?bQwGj;0p?ss?5kDtPiQ6jYeyb^w3v-sx) z(VLM5tG4{e1U-9qot27EqP@0U%JQ0B$GQ^(vom4T>qItQtQp9}t#HhI9N@+7bO9^0 z=1zU3R^4&rILMK2FOf*kZY9n#fSnzQ<%hC)jL=f(^{KImU#^Df_Y~wbwMCOjK!6WS zi?NohMsE@N`Lw^e^vdrO?HrtdrN`RzHS z=*N&b7c-vlCg!<-PZF2raC5-@$xQ@liOXI5#Ff+C$jX06&cj7P@9{TZ`^cZ3gA+~q zXV2lv19JK5>6=5HF^uS+McK3<-PFnvruE0;>d%^t209RWt6`8RbXYv$GsQxQ0BTW) z!Cp85c@TAxN@q1O|KeO8a)m(<0%9IfCH{C20o;V*qIej=A`L{+vW)NgYacFNv5K)c z`qBW3VT8wHOi5MX_4D!gL7zl#D$H&<4#%xDu{u^XXmY zWerzEUMykuvKkdE0oZxZbbd;AMM*M$Ok`Aoiss63kt242zi-4nZCoNVuroy<;dtgl zHa3=i5xOg+U2Dy%*{A*rF6LR1k)E6TZDwcr?uB?SF<(;UC0gX&fLMK*l)7WnNUSNF z%c61&p~7Xn zom`Y2EZm#vX|CI(cI!!JZyM?K(na=%#+L)s{n&n8eYA3#yFEBmw*qLN;`Y~B5Z%#r zu~&CGsDkxLh@$h#%uQdcxgegkxH?z@O6QvLdsgIiUfUyOFLB3Ir2xB()p#P~Gh2K_ zD>E}&M=C==OPj)jC`b6Og1r3zJAeArdc6(IdXKd^+x7dxp%(5h)1rSULnjg+JOn#5 zl_wfcDGnjK=*A+Wda&0!913RRvc^SN&V`cr1cjz74q8sdt%<@1iHDQb&+5?f?ni!C_iOx4!pc8wz)#phi5+FN3ca=^2sXzy8wvi zOQ{{JPJrMrg}c#5-Ib?(bV~=1+WLBBg#gjYM)Z1b4)@|wwg|Ta4pV-PnLogu>W=?I z3v73-)y0=H%NxGf1O11b0!Fe@I}TpztcD3iv^>8dDAMw7|B}_d(RHtE_3)saOU}Tn zHfZGY$1GZV2MQJX>7}ytqNbY}Wy?FeDWANr`n^*7>tI@80{)qV#;fk}#0#hTniePf zgYOF7A$9yf?&!mB6u+t57XN;;9;}gMnE3&AjN_&6^HNx!#!pXL@L)BA<`>CT6?WtG$0J-i(#O&;CV*Pi7BX<_ArK_V&fy|F0I!4Q`UvN?OoT+$h zE5#%4fppc2mQ*Ue&wt{EWOUGDyRUJ}Xb2wP;AnntCC0bHzJuQ}o*cwN7Je%s{!}Ws z|M&F5xow9D<+Nr(6q}=FSWvWZoby}7VOBg~ zd3HGRn`UM*7OfmOlLo@4RV6vjRg!n?qKT(s2Y!B>fu|W{ZzOfc6dTU%%$2Hqurptk z<{?WUl_+C(;`n-lTfUhUA|}q|lyS_L%9HUXg^pO3y7~PQ_sGLAQD~svG+M3NP^I?A zZ|Upx@K53qIUIx{ovg8+d2{g<+3Ni8t~KfuK}L(|4{u3`XDg`EHJ@j!PqRS8s<=8> z!)H6BSD;Q!_G0C7jvd;4_S>vE#Xz)h_rfXp?!{+5E0;bESm^)caDRR?>xN(Ys2@){ z|H9o)3us~&-CVfw{7jK<+JRig!6!in$`Z!wBMuCkZ}-2~JXcPkI5@w+q&g!u-E>OZ z{nyN--<}aX51X-G<_5y(BgGH z#Nk}J;8~h7=kzHHb-ZWu`s($<6`cxkTL>oH2wQYSxcvcV?>An# zXwur^(bnoa$t&_rcEtdugnxG;Im_wneb`;R`>9n{6dkr+IN)nE%D!xlCaje$fc zglQ!4HWk~(hncNlP z&TtlspGdIeOuvD+$G|Epd(+?1an^!5$6jAO&t-Bw^@VUc#~CEYUK}7D(QoqPr+nOt zqM53#Cd~$HP{gOVbUGTiRVkk3F5En9IbNA6j%2?^UwVLB!{u<`A%u^%xTDjVYI#~o z%HWnnGDOiJHowxGhlKuA1z^WxE6{RGOo5cepphf z`8d^SqKTP!K}!JGdBDrhC=q2z)=fXgUGQ~xe+Gd^No$vuzTUAY(}TyOlJ`Ru9rn3V zt?#f(ck{7a^+a-G>t4MLuEWHt+wR+)Hw@5afe&xkrX^_`Ra7LkU-#>D0=7r@osH9+ zot*`>r%qxIhJ(WE81A;`*aepK^!WJO?qi}FtnumDNSLO)$waFxA-ywZc|(r-{WX&| zcb04DVd0dr`+9O>ZyT9AjX$EnmPnU*mw_J6H^UG?P6r#Njz9H#yPVEh!W~EPn3G5L z9s#L*B;k3!rb&^hCg7v=k&lqsgZ0wFi!3dII#nv&oLa4X!{%mZ`}%ey zTqgr~m&?9o0na2pW(_Cje9g;P2Sjqa2>Q#}u=F|B>Tio%^2*6!oB91Q$c*Av%GlUg zCP>R`@S^RNZhkBL5u7`YQyR~;yupbVzMDvaZhKAkJ~%OHqDE&4}(g-7~LF@`B4 zG2dwjdH-#-9$1=%x>DPhDE<_)H0Qwd^yp&XlKh5Uh|%PIeVQDI*K@Y6k+>(>-ZT#G zKkX_qi%);pl}bxU2M7K(gMb28oI3Aw;1G@)fowc2%B}iOGt=CJ7xXym+M!I% zOySnkuLS9C$($g)`Y}Bo&s}P7sB2ldmb(JLu6q6dL=F7E#s&MI-b>{10Y%M>_=AyM zheQ%;u}*0UzC#Obv?)sH|G;dCq(ufb@ZX%c@xL`NVd0-OFd0kdiMj`zF&i~&H}OJY z;(+_5YOHfRQf##s*tb{T3Qsw{eMnp33Od+4KY0WOtQVi28C+T<)_2VL?7W&BU3v_^ zU1QfDAc^zEVst~=poYOG*1nx3oJe0?Yq}P3U%j}#H0uEoJOkrIdc6ceLd;%BpFW5m z-*d}k1OsWAm(UB$l4!RmfIw3mYh&$X?da&H%bc~ev&y|@n~uq^oYFXhtrsRsYVUao zs%|o5W8n5NLo(hk$)t=ChLkY)OUYU(+<|kQFY^$_!1Z|*0Ff;BnhhSNOXP9oA!Bkz zlpkDUukk(h;2PK-(5{_dd$6>8z1n(aSK+j&7h|PS;x7c56GnuKV0>H2w%m06>VEVg zOTQ*wbv%M>+2^F+($dz-qe7c-Ehwp)u^y()1P@dVCce+rvzq)0gwQVRY=(tf-m8IR zH*F(9LPd=sh~X;~=EU`y{gyL#yBA)VX>b(t^6g1CUhXT6?hj-%zh03)08|wbu88;a zM@@pBl5;GZ7?wVT-Ilr05I{Idc7{eCTvH8VATWTS4_VbyWM20qB@uf#1e0f;UjW>? z_?xVf=c9KqYz&j#PJFH6&dt+5edzNUUQ&;_Q|NM}^*bq1dpNP@bjh`PEW15~LQo41 ze>B%0d82njGNW)xeJSOvp|ix|%p3d47!lpV!e%vB4v5hyde&hc#j2pPK~>u&E7hwK zDQvpdQH!>`FNzo;q{gO0Z;u!kED5S$Kzfc{ja6m8tsDrVd$=d=2pws(aImYs?;DbM z$_7=z@Yzfcw+%wcfGdZbtn{Z3|C)kJ?uSk;+O@Q|N6)u&{to0ZU{VsxZb0V%?0gAp z4gMqQ&2VPh@#C@8fheLPIibb(&Fq ze}nP;jq1;DK=r!F5+xyLe!?%H=z(m>J6(XC-vSR^M$%M6c{byiNL?LkTP%EGw&^(a zD_x9Dgq^6fE2C=%Lvi`-V=Eiu2;hQG`Z3XRezK)2UY#R>RT}s8!mjtw6KFQ|iP!th zrG$}8jaM_RcR%d}1)UG?H#{YxL~9t52& zh1$j)F)vzEh|$=?Vd2?deSG9sAP$BeL7~-a5ueaKI_f-}3;n8Z&Kn}i+}Z07jaV}~ z&2OHH2iOJD=gYOBD?AmFUCT|l;~{Y^UZ)^bkZ62r=f$xE%XqQ{blKpPdB%MZ3KtW$ zx^?w)quUMrRhOhDEVa0IJ2>L#>_`2%jln$~rengap1FJBml?|TGBHt7H+B{jbb}!e zk@T-;uT<7o#-!g>%&-?P9XQD@2&EnOSTpxYqJcv7Hw*)5=O{rkZaTo#Q+7SS%4aFZ zw{IlY-0t_+&5aKSsqjsxI%Xo#&?glvDcoWZ0Uoa9`8?k_36!{7a0tmb;MbCRx2NLTL19w&U%{> zMMTL}(pRV645?iD^_BPYFEmOH58*BmOzGmzNi@^`3|RMST@LKtm06Is+o_g~6Tqt1 z(H>eZxP0xNN@{z?{q8&MUba$bqcB>x(Y~_$&8&F>R?!@clkK{n&`JVL>-NaR-@l-9 z{qd6|X6BH&X5>bbT=QSGulEb&$de=Bgu}=o-J1sAK@2mC*Hf+R zvhJ|_yDM&v+&Jx-*PG#d7R-k>y*89JcdRTwwS-rO!pwk8g?z-skhn(+|GZfGn`RAZ zKhV&=V90SqCgTZ7k!Ssma6)NyLF)EWLoz3C-|uq@s)wF5$fclJKG)ItV3!!R7D%_W zo=Qh^1kJ=-e3Kuzy7Vh;2iPE=GfwksYrq(fRm^3Y>Df~at$)`7>|8a0T`y1RN_2;O zUwz^;iA~fv6(wX^FghwOhpag>@AFKakq-=5`z$hVuz$M6cCaTAHRIqhI=68hf{yX) zZraS8zSlKY6_E=Y*r^fP3mE4=g69f%#3lQ-+&UJ zTbMhaYeP5^4zP0@drI!ZQ~yj*E9j;1l<&MG3kynQ>?f06&5h+h{+=Lz%srzb9?*I! zTJW~oH@G!d|678{*i@&r$2d>7ZiRWmEk@C8b$OJdP`bwSwgI}v_Rf)gt$U|ALmpbH za%r?CT#5H;kQ7k06y@ifM8GH}tM9Ie;bR!rTArzTPItm{!=|%Ao4bJ1}RK&xwWfGPWvqc>`x7 zhqJK^q*~-<{vhhptvp-NvIN7sXAho8k2a4V9v4)yR}l61h17;@aHtppa}GrSvj=0N z!|~B9Lqc65t>BF4x?C#@O6o?WeanUPE{Wx@yWtRkyUt`Z(kdevWegX~ z>jc<&Qh!wsZLg{uF&EXDZ){U#dJj}%9=R^;sArSrCZ$LmZBDxdyD}i-U7J|;NA>Vl z-zpIZstY9Yo)s7~Qr}gj9(2z8`E>b$)@S3zTySLusU~_9SrW@39CIsIdUnL=VP+5g z$QNSI<#4x-;L+Q1a+>mX3YvJZm;bQu| z2b+BPdC&OTJ%uGaBW{MSw_3VJEtd!lI2pS((66h?qW^1kL~&=QM#LO7rbhF3;TtnT*a} z&%(l!7frpwDop!c9aG5R+T3 zWC6!U9D6{fe=(Fj@ElH$&H!L{LBdNykQzfkc5rDIehE&&9aVLEOx;Yx$ANRlTZ|>X z_I~}9CQw}XYFLgeaSnTwa&%smQBXv&RcnVa-sW`5l+JOJ*V70hl9luO5`8+Rs(sR? zaAumRhZirb2TH=j*LQh^k>4LZzC<{bX`rB&mlVsl(Ytwd=xBkW3SX)mMee%pIaLt0 z19O6L0HFbJ>G6mtjJeASC1bt=?KQ+)|Nl_;9zadLU$^L+5Fqpbp|{YB(vhM_FVcHc zdJ_c&RHOMxs zgXqfR`zCAez4lrg$aJu!OIbsSMP{0{%Pyi)DIpBdGf+oR;H-!(;n@vCnKDZs-q@}F z5xiQeqplh~Bc!n*0Kq^H7J?BV*b$cT0zHh>@QSO;Z3+vI8@I2xc}Pin^^EKNmxaUs zg>QnHJkNjQnLN*b;%}GRRLVK^;oo9}5;7;{vLY5EZx=*0HzLh; zcPo}GhcR6znGW8cgMKfgwZ&KK>W*6>Ec7%17(4+2aMM&rjAf-$=)yuADTG>((si`# z-_YUUCTB0326rL-;4FLfmhMdN*|xflX+g7gYOh(#J1o$P$YHd%K_)r%d#9>$U24A# zN+cKBi%b#L{hniIs@Dk_<+``~sl1Rt_r&Mm`@Ci|91B+j_bNNnk7FxP#KpT<=*~%g z^tQTW_59y!lm3(Fhj#)tS(yX;8AZ3+v1L-)EE2Lpef86>C=#bc_suFEkA$pdx{GZ6 zw6)N^G?N8jIQAxe2OsD54$hkt>kWiY!b3xAzDpxxJ$~PQ@wo3#nRk#1nT#rz{~@i{ zK`T&lrYJ=fW0yQUvYzv`_miNdHDSE3YX+fvAk%vO9W=+;gV%*AzQ4go%Xi#_x3G*E z{o85}7f}G%IqVX_PAQP*+_5p`^tIeujUeu;^cPRlVmaa7O_Q6kiZ_EIicpuVK$L_$ z=UL(Ys@6vPsjd@>#+5;WcbK446`$z{6LAMxAn2@wwpB{aEQW;Y<4cB?()Py{E=m2r~&wcgk@rd^wb+b-fL+bFQv#OLh?ux~-|xS4g2( z4_x~}5+2xr&1hG!;gB@0n4SH#B{D9=@?H~EDK~acob!GiF?(m9JMn1^Ds^$)t@yOC zPkxMhu)7>8%|rMtx!j@>pYE7pHO)Ay zKB`@Tl2Z}PMID8Ad!L7=qf^zRWP5^1lGS*AVd(=4fUC=nGWy;T~B z`pPgGD<(y%Q#K8-b3vL|11uv_w5-+e(1;%-zLDiebK*p$EGmeW^jBbf6oZMSEI#%( zIq6`YFf-E73I7{iO-+SrP#lRY<<(8z`Q>V~Yg2tSzZ!(gzEIPnHr5dle6w%;&juZW zdF9e~&R)M9#ZSJ6Q=2zFhO1Ir%$AyLyLJ5<7JE!DJih7m@{MYC?)f$ar_JBWnid0} z(xtYMKAp#VQJCqCqLYaIoK$DH;L70V@Ydo~Ptn*rwexL`Eh<-+0d{U7iTd2(tAr0A z24(|^MR1B>{C#R!0t2o3`>!Ny$&n=H((Aq!mbLG8F~uTgTys=*IoZ%7xX4e0jn zO9`85<}aV_nQYm=83&)Pntj!C_0yFz7eO8+n2b;lthzh>VE5Q-n+QAs*ip^$(@{&+ zdkH6PRT6%CaXyz~mttyP;OomdxOY(1i#Nj+2~@1tB8s_c*+(ygpM4&l)#k8TI`y)@J^<`ED(EdRPf( zXIb0Kwbmz=ofV85uUdA-Dz`BKF}#~4Q*Dknj@L6gAuOwm(tX2Nh$&J4DH1vc?Y!w2nqn$>0|Bg3ed|k#$$7x4K?_C|7KhJgX}kZ;)Vg}rQf4E z`Ww)MgpH<4eA-MfZMoBcvQ+gBF)Ds_uS+mq{45*V_ z{ZUMP6oEo{$2OfaEG-9$H*cMIPp7rW`=Xx|Eb{9=^*eFo)n&fs$rX-FQ*@)>RAV)6 zIWka^k)`%X^z4;7FhqsEyKlR(l9E75Cg*Xyg}*?zOX}>Iv6J5g#t_eZO??qN>8dub;@&rNk$axvm?l z(k!z=$j<=-PF+Xz7Xvf;51&(0Qh}G0Y!LuH*zE0FEFGP4Mn%kSY~G`*adeD$++%60 z%=nDu-AU>6N#}hP$J?Z{7_4A+P{X8S1g)YdFkO<2NCHEI+25=(j>WS-=a(gzMg#GE zjaj%ETmi_9&U_cV6Wu1#5M*HW1pVM0>6WpCgh9MthxwKrvL%W%8eo^x`TtgX{I8fI zi%Uqr9N#wI?Cej>yHC`QFWhEOkCL4+P|hr?Z$K;E1rnYO$@{@X6R4s8mlW&cclW*H zi)>`J3|B9$#>c&!8sgdMcK7SA<=g3Y^}H%`G8qI!g#Wqsu_*;=4<_QyGl}~@HHXR2 zzt$YUb5sYdmUS+J0JIxG8J?!tmlkVin@o`GKGOTCtMN^Nz||9crRoHEP)=`?XMRP2 zK)HA8!LpGMp)tzcYKBiQ+y{TUICQ0=bc_M%8_c+zv#jMY>wC4bW>&=C`1UwqEkN$z z$}#G0*k{LruhEt^kK4!GOPo3Wgnd7~J9^$pTKX*v)NN7gs@l@?d-jakoSa2s5oUPl zRPG&x(vqc-{$n>ym5S+Z zW@1Dtr)+?o5yk2yqcI+HN&Jfp^MES2P{D@%b=w;0j_*-eg@fbG0PbtnJ)OM=@I~Iw zUh?cIw(hPY54v&AkH0jQ&VDKd*jZar8>AeztnDijkk+|Zq*cTd%497a|-Fr^8{PVba!&~NAC`tvgKiskpOQeftANq(#2jtoYVN!2&ZJ6k& zTRFR)wRa}%TT;HswGwlI?uDDgES0R2&tYTyW0H<0dC6|Qq>zE?80Y`cT&4YUuU=OD z*LxLsqJeqSYX@tz(_jCAf1DeLL%3#`-#=0;7F5B+D~%c8LG;%gjRn;RO+sZbBqJs1 zm!>g!Z?k+-T9O=A?8b&#=bzFpPvz%zM*;;hmAXc%GoG4OTE#Jq5n z={*}q$ISj|uE=*VZBU#$VGcnyDC9Rz}n#DgV`VaS@C7o0l>v1y*sC7MXTc=q*RaeUnVr)5IV(C<}p<&;|3Sb8sZ+n(GFF1rRToC4Hp3D`qB{s{l6L znany(-lx7Jy9ke>24Qe&!QD+#g zW7-hjCo+kDX06BuuyelZxWK3m2lFs7@eU6I{!QCJafP>%i}W_;B~G!|OV#>SrbEDYS#xbtPS|XnYd)tl#tXhsntIlvY z7mW>Sn!Xx|fkd$wTcOq;KPJ!+>ojBo_BftjuwZeO$}ZQP&f2C(1L29}Xj4-V|K9t+ihgl4r=7mMuI5UflX3AFaN0Uxbo$b4 znD3pQrVBFM7d{y7K>5%A}aT* z1ZY1+r;}do?N zuL7FG;wb57%p8U9hnm?tn6sce)SwG(l>YwQYnPac96w86bgl7BhHgVK?FLW-S>FYs zN)2bKMRlff%8G@Rb^2z+vEtwIQLgPpX}&Hfx{hAPbscQGP>cIUm-OuR>a+GU$-W3a zn%X)s`_N+DoF-b}&^6E-^^m&H*N&X6gm)AaiI zHdQR)6H+el(&rH6(xLmC%W(b0aKpCotm5f-*Gbj>luzF+cx(1X9x>f*mhzh6XdNY0}5`C6R zoCqB0Q$Htu<^BFyF^}y?F6s@MWyerLN}&;hxedAJQ&t}DMYfhk^wit9WVaoJqJ$m7 zOKVXPCmlkKVJDIRJBr$Z>T=@SmuesauKPFa21&dc6PZ{=#e-3zHwPIrbo2T=dPb3P zOkR?yC3yG~MX8Tf_0Mk$Z@1~XV!Y~v0!Wc1dHc09IcKe0;7&QGZh9Do+)=70|3FSA zV0?UM4vic?R1(pkWDj>+ZIinRbG${OxxO4WRZRJ3U84hYjutmVJ6re69;J?Diabr> zTpj55`o@RZIwnw5#$p**r4SgwNRvyQ1?GFVJ=esEvNl^!%Go(8fSq1t_VvX?TM_7- zDX04M#fxK}g-DXlPM-qqZ9*e~B~w2J|56i;U&`U;QHf+pV-Ts=!3E*pABNwSlnx3f z3-ZDUe+litNCi=v{911woUd2suU3!`f78$oc|KH)g*xO<8tw&Ug-Ar&oqG(Kj4#M) ze=3ZTa@M$G5KXw}ad_16K97AmNq?)r(Z8)BskxY;Y12JgOINL>QM5}`M>6$&GAN@31_=^pm!ttjCMzQ;) zmo)bFX6r_^3b*fQ@SG*x4&7A{ufC3_yn*W=%1D}ed_hI|RIN5*ut&(9v~-gsJcR>}?;VRI?EBBdfjCbyw!&IutDbi~SHGK#es*^g$q_MFJY812!% zgG&!tyA*GWq@3j38X+yXNzuN+`{)CX!?AI}HEm_^V*R~G>CFMp8pH+VGM1hO95nZ} zScxx4IrF~`$)%+rWQ|lKNFr-&tzL8eT3%5rqAoyC&i^s-e^z)bZX_$n02v??NfjCe zaIcw~#v6g&Yhd_5^S8qK7d_Rg;O+YB**wY**Y}Siv`?9Ao6yfama56GXj@{YTyT`# z5hT%k^RTM?`dhG4$NNk+tCMS$r4)$n7jgl1^yYxNhM)Fiwh@J9mbw}y`3P&J&ASC+LFsDo;0DD9u8{Jqtyz!=IvK3bIKc zCJfa%YFqX77`}g7HV{qlamIIOQn{Y?TA_YtKYhWsR~zgmp!_V*{nEw;6Y47JKriM* zNqq9}E(7>-BN*k^s-;Cvm7qn_09FGE**{L z9aSk(6J;8yn0KuQ9^BnyBb!ODd|6*zigU&C?$qw=HHP?}JUp4?$U+GZ&Jos+C-?fN z9U<%t#2<+upBAQnTa|D*s8r-Vz|Nf65k#eCPx1XU(|wn?+jJq7y#BYM1{yhh^NYYt zkcDx6egO%WkQ9?}6jGO5j}csU6wL&$|IyuDm%BSL^ULc=neVf39k}keUaE9dPp{yw z3o@Fw&Is6DWW`$uO8eC~=SgP^M#J-?ZbxYBu@2PZ6qy4{OCk2$sq0T0n}vWEovOOjho&HwsEOqT zpt76Ys<~YA za1?5f?~wHCa6ugC06(;SNf!FTBT)gW33YpGE@`4;!&%oMf!+Hu)Xz9mHj16`0%HXu zV4AwcS`WOKd)+_2NSO)6L75+%*ep>30K1~Z{}u-(tej>QlD?1YyoC$vwPa-Iw3rhZ z;j=5ik(@>`n_;nnE7T>H&Gsg&Qepp=ct_-&#F5!w`>=nMVE*aHGH7x4N1;4#es?we zDIas?*WyWIdy<1U%2ybn=RrvJ%9z?l)TJ5~1~hLNA%wO_1D)uc>>Oz{ZX)4=J+i7+%i-T*Qr4kzDedJ+@Kkqw%5cC;VVizUf9 zipaOV`0Ta^kn(H6FJh+I_EK4JvlWN+KtT4v_a5O(ngQ6%wK;Nn)4NBMu~dc3v;8No(@5 zeH^tm%-Kqeo7ozR?`rUd3?VEM6TO)axzIo`Sn8H3cU!dI!JRJFsyzIWRLR(Z=@J6E zm#DB!I0PPVE2VFEziOrOu?`Pjp*b@$G_)U^c4eeD%5hUz;DZ#-{aCYq;}Iq5`+Qbf z3VSE(YD`!CzDovcTECQ;+U;igcT4b^H;R|LlJbqIi>8j{2yaBypS7vBl0#q$`=HEe z9@qi^{+`m$vF3}(hXixV0!YuiQMECCZn4-S+=k~@Sp%0T6hwhFM6L(n+i88<>}_1G zSzTOQ^F3mm@dXA~9t6Cwcz7-Ffj#zqpQY^$WUGQ`ucbT++n?iFN)c2jo8A0FS`?N( z!Kgg+@OVvHO}}wcaNE5LzfaCUeye;dvl#^kLgKUbC)HRLh}%W;Rbxe!eZ_Nj$Z{DG z6L2V(n2S^LY&{NYG#nM7R4vw(`SSfrWB36@-f4iHJ2PB=AJ#*AhcVD8=&QyWU#ZdzB9(zdj874)-PCMYyUjdaw`4UT(jz`?iFz6@m0#7}VIco1lv&BhLW? z5V^;F(QqrpRNpkQ$}m){Xz8^^|HL3sTHJ%lKjjy%cnw1<%!qtzgS21$*Jp#y){!WvQ%I7jQ;*W|5AVr-`v=RFCkX^lFD2&2KM>u}2-G?eU#yizQ*F$!W3oT& zNd!qnw!cK?4H2Yn^qPu#k6Q)TE_A=_$$pi&>Bv&;Xn9kvxAtfWU`Np~oQV6VOgZ~O zS{PR-7xz>a(8Dzoe@8MbH_Qq84Nq&jWU*WrnS7HfIw%$_EhPx&-X3UPs7%y}V^3+! zVOX{Tc2>^$*^9Esq=-wN-ESUVX;UaQU9@M8K}v|0mCU}HFv;-u=gDwi6gW%rn>t?r zjx)KZKjAo{)#FiWi=P?XwKdSRR9VZ++0%KrbVvq?sC^`jWwCOYeEQO5dV`AQJ>-5o z-U^JmCvB?_uk{Xzok|gU1?JkQ|HgA|6a=qf`Ku?Gfi@rx;upFZ*ajr2)sXYQ>izy- z{XV#6=n08k%g(RRbD+m=LEuq-v$sE-J5rTf_V6ARhqNTq3L?4m#EYz8fUb~E-VKr(!WIbXoHL)<=K@FYHV7Zz71=GQb|~OmEX<9D*82HNSTLNO#TcJz}}~# z{!EM~>1W=7BQ$;Z%Ws9M42Y*VCa3wVAhm&Fzc$h_JKa+q+#QS zOtAm)ErNo5gd;OLyl&#FUHbbdPy1?jJsA8z~buiV^tveXt_s_cKBm+I5{h-f}) znpG0{sl5E_Q`Vr%W91eK$NrAUgchz&r9d(xLe{Q9SeJ8V$kX5Lia4CwuTJ;6^}FqE z!$l=H?@v55Y$_*Hp$nW$CY>-11IOxWwE@wlri95mZ)JS~ZaG5?rsG(xLV)wFPcHa-k82ew<_?+0ZA z81#VYRQ4CzRCBh*xr1aRPLk;(K8C`|h<*CQz?(Dbd@I+zQH7QAjEb6yoT&8ySn=6` z8N^{*vp(2awzqLk%oI8DHKrHA>a|5HNMRnI0oc(z5$nH9TDI_CUf^DiWj6=4M7dT zK~K)o73ct0;MA931sRN?=nF!nfGw8=%UN|5R{|UHDewa*t!~mz5?Pt2w>BT_u(@kZ z@;qi0UcBX;nVE$PkLx?d9rH8WVop{J%;KJc{HPL4O|Nlkm^%oLHpDqPi8%=`I-+0t z-yH$inb=ZdmRRa$l|M5P&YOm1&RKdq2tb#<8;A@F;8S-wH{3mYDc1B(VbQ zOgAM^JlsRMHg(hhYfaU3+cnrlSijM%hJokUi-*IgzhnpaZ<*aRSRse3hM5bs1 z;(ulB-lXi_;$g*>N26IH>^}_3H#_xuIP_1b3&z457H6V_W`mq$BqV1MVn09d z$EQ(bOJ)D1@e^8EHEBPym*P*oQ_gsi`3H2R2f?W3L$?#dtNvOQw5{%%6XAr@l5wzI zgTNV)x1>+l^*zZ-l-6yeSdKb$m1bie$UO!4I}35%L}Bw!4?BbBUwJ!*5$p|b`DQU* zt$7M2)#KOyy?nrm{!>Ya6#RA9^^he}cd$XRfq=*nESw~qT*L5O5>x()xmYQ3HA;v^ zEmZ)>^GUKI2&F4d7xC&2*9dYEyAJS54yw{Yg0dhk@8V|(UabbKo=8;IGzkc`2UfGw z&M&5~mM!qN3eY=j4rrxg3P$=@520aLJ8JlTJCTdAstKC9ktB#rvtl5m7o`*mqoxD; zy^9PCuQ}h6l<`I8vp5`EdQej)nV#w4I~Na%ZZu5l!kq~(V4_575_{Ma?fjEfgh*9M z{qep%uLxiv*@OSe%XQy)UNV0*jz#7N$*jYWaJwTl(cg&nSSK+-)!@Dfy2m%;QLiz%qWFd{m#3g zKY)+#uQ0J)DaE@2Ss)ceewUJunuPrvHHjL9EeqO@`bsCIp<&A#d^6+O3Nb$lH4Y%c z^P`p4aK1YIMmm+nvZhBD8io=`{cWEgJh!xu_b^l?d;}=Q_Ui}-q@<3`eanE$y{xEy z9yCC+LbU1({xvl7(kl3dw0^`4HT~~q34onFZ(-oTMHQjt__*sCmRge8`!!+c&$xa_ zsB1M8h?Uo*ckr&~r#AU(mTO)t`_cbWQ?qtlz2+={=AR!503~Vc?Dd0vR_IFgk~sAOscCv z27$PS&Hi_vBvl{q|6UVIB6*xU1x>&(jLQ`jPr-#p2Yr5Wx*0DXPRHQlz8JuztLlD}j=Ss4t2!|qtqKCzV8 z-xbez_qZ2=AyBp9w0XXrVw86^$SPIt;EPEg?M0y|znV6++Sgajx0=JTFuj8AiF(cW z&+`2TD@9(FzI6k!MPgPP>^wi73%4QghL5H;Z${G)3|E~sapvcm`s=@w;cV%g8TfBJ zb`Q{=pG`W-DrBT@cZT(k?c*;0lEO;sc7g{xPZVOM5ksX$G^vftuclCcJd7h{Rt(Pwsk{* zNp5lhb59|*)av?U-I*R~zCYu$zlv`5CuxX|-W(CVi}%C3k}mIsA3OK?1;I;)PWWLY z3-yoN6`r;jp4Za-W&CjE@YA$Wy2_7cxHA-^ZWbM8@6dDol;mlT`BpwEtb>|76c7Bc zZ(j}zTUnI3Bawc4Sn8{(hA${G%B>jtra9k}dDfUQ`qBdI+}~Fv86rySO>wh9*X`C! zuFpUAl$;jvWSWan`l@#62pUC4MFXBt|ST zy**PoTbEc7#vpx0bqD%dhQ@Uci@I-< z{zL{amcNg}dyK*^rvy!6K&uci7zv3AA@zqWR_h>p?C+zZqO86#riiW0>1c)}^ZfD0 z+q@c{RRB9ZzdiLY-d|?*$lCIz(>fI28@Fk(1z9d#J!AA3dXdk!LRomOmEvQ=G*DbS z7E-@`es@40yIbKG$PBPm)KD4>OVRC@@`Tcxn$pLGgIa|IazUF-6?Max?Vb(P#Jr`x z|H4LHKd~%3zP{l*%e&B;R!e)}lVbf>bz|6VbXU?0)o#%LHr5z#E;ro$pp&}kyjiG` zj@oMobt~4>Wewy#?KOBMN$AX^M&CD1;kajbf=$P&!mQsLqOpsf# z;WA6XV3Hciz$t+naW~#setwJe>*H?S6q8L~)|PdRIPb4kGPNXZ=JT>7pm%`cbE4N$ zRok7y=H(*OK}+pak` z|1}&w51eL+o<)qEY4||8nNL)#W;Z;IQw@GLE2(Jwb~!<3rp+^EK5z#=*K%`ChE1B} zK5d*>9$07q7A@amF9_GmBVcK!8Di*|_*VDx!CYiBxcrZVm{W04XM-iFG~hy~PfK9> zv+P~6W}+lM;LShWQZvRuRqnqnQ52`^O@6-nE+o9;swUg z{y#kOdCI@?NHrpl{P|b(fasWbxv=~XoxG+d$*Hk{cwR>47Jq5>psJEml5nl%&8)I+ zyWI3Gb^mthj{fPZH0t-vL4XwqNpK+s1>B?}OwF%U+jpbq(Dm-!qBo?~#XFd7SmSAK zn|(lJ3AOxnuY^r=A&JSuk+?~CNMU6Bdz9Iilf!Fx+IZpRCZM1eDDfxeN>!B_4!s5E z&K$SH{rP4DULUBHyvOn>AZ6fA^A=i0N1D%13MFNedwvJgm)^&XxZ7gH%s*2@>FgUSgMOaid2QILJS=9|zPY)WSai|%Y z3{jK&{rZIhbg>$x@Vk-1X8r}ReAI^7ML@=GvN9>W{j++tqVc)+MJdZk*pYl9W6#*G zWAZGzo2}W85O=sBhkcM5q4h*fW}n}lUP2FGXF13Gp2kxz9aFM$c&+;Z$ESR%3oI~g zU23o26eQ|MHFWSzqA?JNAmRdKib+m$Z!obcJxzw(Ad=}A6cA0U zknAx0_yU|gS(&gHD2Q^lZkNbcyZbzhZqO4J|2*_QD6H?H?9pE)9d=4v=EV0T;?1{cSHKPvQ+OdQ<)3>oQvUY< zc2?!%R+r+N#s2wY&D1x3KZa`*4VC1q zY6-mtRS8M^G2)4Y6ty!q>}w3sk|(4Bgl=pb9Cb~XI+YU*Z=yPFKE#vXs`Vi3Q0(r% zbj9pzZfQ^7pPmzv&@5B$?~2EwUS6}98UonaPL9+b5(NgZX2>hHhm5wltocuEMS0c+ z1W~}gxG!x45C&AKr8~%8SDcKGZw66@mX3Jdr$emz$T=JvMp_-8BS9i=v8pRZs`#(| zI^wzjK?7dye8y*Ac{RWIQTi#UGQOcbv%(%*Xe)|iJU`Kg0z%?G66kxW6_;5shy9DZ zilHP(DTE*;ec}a+z7n$HI9v3f?&wl>GI%Au+?7?Wf4aaww@n&VZ{ca388NAdgs;N%6#-@;Qba?i0@8qIkNf37 zo7VQ3zS^QVbX6@A7nIi5BRB;F1$Gf6$lJdGb`G?8LXWqEc03y56clmRkxwAT7@N;{ znt2tJdOkERD80-R>*%1`9bB8WyLmyZdVIE~UmQ6=;q@BZo=6_EP3Uz|6x7SALnd8e z7js$W-Ed?V6t1ow-=Oe=^O9=OZ~BK$w64YDdb%TNxX!Z8@@jFm*N_}B(FZ21iWTcZ z+pr_i%AU>wyHF!*(9TJ6gW#_zQMC+yCK+7DCVBHuiZ=t)@B7FjyE}1!aNdry3S{bG zZ6TgJ=dd4=SI)-FmW9%B_bAwxv(|?b_LGiUgwHo^FX6|iwOpeVSgGjZru)!Uyh(da zKhkOT+2rZCQ^wh&Nk-uE>~Uh={{-KAFz?<;BJ>zWMo$)zfk19VyC;WjBRDF~;hAap$ zIl2@#+TF0RD#K?V@`W&nU+MI-mNNMAL-sK2eI=xP=3>5GadkV6vzHZ$U|whox#AS+}u^W7xTkBaUfiZM%Ny$w=-t@kX zj)?kmfk4Jc@~1b%yFTJLkbIA055lEc`2cnviIz8ldE6;Zb-k!hC2pok)KjjfC>UEa zSa>6;Zic^n8R6kh_!fr1(!7Ql!T3nj7~^NyhDgukiZ+QLIb}e?re1&y5=mTwt?vb{ z{Z7=f1&X(bAqO)diT8PfLoy#EM+P4O(KT=!Ot{M5)Bo4OVbrPD;HQ1MWv{K2he;CC zIrt{KBJTDRSqV(}CeE=60h82LMbtZIJ}%0vPHGagDQb4GHqy>;2}PdD!gt0vOBn#{ zsCQQ#pUxCIJ36wxMZ8qs$Jg)7giSd*b*SlH+d?&enQo_D_uhEnyySy+r+b)8RQ0i_O0>}!aZSmwVwu=wP?!O+b4%y^Wc zP{99FCC*QCiC2Av?a9}KUUgr|loxWlVXIU0D~e{CY|g&F*jA=CBk=wq(W`dryCl!X zPM+5t$BT(1zD*5?ppk5S&mUTRbUvf6{};~w-#tB+ApkxH${&vYQm%_X;RjYnJjcbYQ&G@Qymw(6B16@~5=+h+~wp5m%qCkN-w zI0f&En2e3#t7P2Jkj^OK4EgemU)S(8X>>(k)Axv$0}bvbh$HL9K0$ zccwcXX;b!|zZ>`meZYUm_7(;5OWyV0Pq$7I^oX?wI=qAR-Va$qs;$wa|DW?u5mR-MlW{>H(ih1G#^83LV2O zrSi{ukJuha@7Qhu>`W&2K4lN)3%lQ9AibB2OJj@jaVCkxNKGYhUzMBbUIt7n*AGs#6)J*s^~ z%G0c@^@psL_1n%@b0fZQw+bpoOpZ3i*<3?}8*Vj~4@et}mmXbL5vn8z&!jOwzBSmk zKxOJB8$lYPJH;(AHacf1(8g~56njCBbM2fwoAKgTHy3@|V0u}@oH?HgfL;FL|GB!U z-Sfe(a`H0KXJ>smHMc7aQ*t&8%WQ1og}pvL1q9<6?~dPuy)G# zfA3PdL^Hysy&69Zf=(2&MsujSab2k$cI>>gN!Md^s*z7W`iyN)5A#k=sr)4U32+-7a8E0fFZ}2oja-a6J0ROjTi|{lf zN=AxWQfGe2+Usv3HSONZX3VLCXenH-V5Jgyxz?{|+W7)w!4s&nKU-8##@)irtXKNx z+O2OjmoT_oQ?BUWcUbi#?v8PaR`*p$uNj4p)&CIRS+~$(J^N;-B*fwxxZW8~wG*#E zQS3Byq>%b%fr}zWCsI1!kPCD3YUs}Ro#O5(0_DZ0|nBLh1fBSbVJ9eost5$(=Ai?+O z<9ZV8H&OaZLlLfwSjIRHDodNj-c{+!Wc1C`36~vz`?7t@hh&2Fhx9*mUA!n3#ju|5 zR`j~3zX1pPDB5pZU>{= zR2VK&ZN1DiL*22!IgKO1CyK`G@t4NCt8?B0SruK>tJOR4nEXw2KWp*lbg??Pm)c?B zm*v0}dp=eVjC>fIHzmPrI|0N7R4%TP;ei*x)czJBMi8&ZxXLA1Yz%YaA+_Nj0$y3Kx zrlXD-2A@y*OCoPDi(ZzuQX?TJ9)SRM0~|qoYR_qg?yiCwpVMp%WSs>g^6#y6e$QuG zHcgaWwbUN5?>yTurk?eD#6_&WL}W}*k1g@ZV?&-XTZONrhoxS=$~`I*&%}EILe`_+ z8r+p_Ixe}t+#JIk@-UU$wRZboc@*Hf*QN0|BEN;Nflp8 zQ;lU#Lca!2Tzt<*#g`$~MRUXXG*iy#;I+WnoRxdUJ)N(fXR_b;vZ#8RFiMErbb5YJ z(mWTN!FFH3y(pnY_lxpsUgvlP-aggR_g-m2gmMv+JD!hn^X+ zyPa%)|GfDlU~ur}|K|)v99*qENs5JvN{jcC$f+9@<=@ReHgZ~~A>z-2oH!UuYjdKe zl)h})x36Qo>{ltg4;plZ-`>>id1u8+7Ba+uO3n7W3`ccSKk(-Dic~^fL-6@OqV%DK z*C+f*d-1@+Gxg`#fe_({$0>P9luD8RKF{Obe287<+2r{&Y`hwZ+Tceys4M6s_)lV-H*@gi^1Wuvf-(zl(iHhQnJeYg~3sn}>7!wsiKMN+Y6 zWqj83j7Z!LS1FBPeDSR~;YGHkIR+xT4|XPCtdG^VcIG6Ed;;!xo>m=FIK~G|^xt#- z0Ffb~$W-_*;z1oOLA{P0n#=p{B z`1$e)HWFf+jQVB)&(OOT@wL@b?^QF?;=^nBYLsd2qQHd-6^~~t$`{RjeBw`gn!dvr zMkV^n1MF=5)A#b+-X!OFpN)L{&T2l0Y3Tc;ob5d9ls|iaRo++c7)68VGdkuM&XNz) zTzbTDm!69C#-!2uaGX<}O=9oVkBC9%zK8n9#)Vy90s`0OUS~>6DY>`DF3$;)&35|X z`(_m~cz*3wzIpaR@AdHR*uAmOXiQGj0^655$+p&*MKwi!N4m z48Fjt9__BTA02rp=erjTz9}=Hrb~d#6CAyh*xohs6(nW^lwU z;}_HB_t!ICJQkQ$S_m;}-yTxIU~~KX6?iC6g|_rC$1=6wc?~h>u~*xDw|_0!lRUpI(w ztf~55(O&-)Di6;0@?loW)9$J>KS~GaQtzP#bL8!QqCOlJEsDF!aYRz8$(iQ_Z3xsG znj`bj2CO0`Mju}0-tOwRjJ8Pgh`j-Y9jIQm-mEA6SY6R1kRee@-+Jwj3`$&CkDdbM z=*jRv=#J|d_a|FP?4!V^k~mMX9jHBET>M%Ys!z`ed@R&^k|V>j)mlQ|ElO)fd&$*t zlAji5Z&3Fz!|9>*{XH$Jk8|)(*|WE~+%|OSQIXU8_jW{iyAAb(ibS^qeqL? z24xSQJ?M`&v_}3KP``_O@RO=t--I{wWuB3%s0cSzQjq`?=AuG zcBa!;pP#YfE9Sfv#i1K`=K2jx^D*_J*Zt6h;`~H)s)dg6&qBHkW7*3K+1x zhR*2V0Ctt<|L5wa|H-)M|IgF23DmBRMb-?k_J7wcQMUfm+nDhE*WSiouUE={GS-ND z57Tsv(PvldmSHbvXq&E`z)nVC)c!n>F(*itJeL9T)Z32V{0$CY*gkPI9UwTk#VSG@ z2rT@*F7T-$w-*E2CFl>_ANZ6)O09}&(g=!k0|`&j-`JvE)5DgfQLK~6ej)UTv(3)H zBtnT}AjOYB z)$9k&AWV6xZ10+!z#upr1)>tjqbsB+IY~-bDPZl4la&=j`8;PlS+co`w9Si6{x*lU z-iG~ardk|0kXQyb7GU;2W77|OPZH-szB@LUem@NR_#t#|SnFdjq7ds`bDJcLDkDLW!!JG+&szn8(I`{eo5XZHBTV8qVv%ur zf=kCby@fL&?bX{ z#o`P`WvX*`eNZfGw;Rq1a$FzFlca2_iCf|;|ceSP<) zaGs0@bo|v_1%)Ljy6L(=LQpd)7@!$rQY#N&7`Q!WhxXO=AmGRZ8zc}AujguMVd*&B zx!tk_MJ^~_4XvN-7CFkGHcGL}f?lqWiM8w^95Vy#>=mzfZGYFhaAq%+j7QAXme&!E zv?HuWE!@(j`fhbkf0n6143iWh>h4U=VIi!5AA}O^wB3kiEmqxD9g`c78oP7L;lv>) zDPpqgso3z=?&%~G6N!X|7be1C&c-c&G94{xY30@ge^rKkhd+3fN8)}iw2XEB>sWFh zeayiQPyQKrA@}=0QsoPNT+EanS$U^_>fEN@;KRwpRHng7lyGlp8Q{N*>A>zm9pq27 zeK^bmIm3f2iU4*F!}v~qTnaj1Hi9?~sW`<*YIRzA?^kK%x^mh7pzb}RntZ#q&nqE; z00Bb?BuEQQkX|f^2%&?5fOMoc3o0O>h?Ed|uSyZ5s8khDQKW`y0R#m_r3DbAsDO%e zGH3kX_cQmrvu4(MpP4Vu^(i7Qcdo1?``r6Den)F~p0B>?Hm1;VN?V$-;DQq|aM6Ww z>MZ^1TpghBca{6R{NY1aU_IYbOVAzO|8y%nHqj{rE61YOt8w>&Y7*4`{7}Q%FM4Au zlWfCCd?;C&bQtPlnhTbqF3DvKRr$>pT4C9^Z;NdUhW}zpRitiKxc>OOqu@8rORe>xzIhjS@mW~u3BmBq$jb+#X-~2$9|b*v$O7z;7(AVY?@QC;LkVa6L@sZF zxZHPlNEMH<8?o&|Pj=GW|ON@XN*`fTsE8Rk`&mxeg84@>mNY^k=~!qqonk7>)9 zuPZosPb?!ZAjl-;x*=1XLo;a|h294V1B5J%%tmgKxt|jAgr~;mF(}o zT;aI!7<{inf}dBVg--ia9e3X*y>_WW@i&*Zl)jNPn*TiqI{?|jG5V5BwQ@RS=3cHM zmd&;Z3#UIRNIV^F$Ytk0IQV<;8SR^jsa+XKvpIBeZFYDYX~-PKOV~(!@?+`nEfyuJ zT2w?FM$60iy1?n9E4Fud5)^yQx+nwa8sVaKIEi)gR9Towh_y(Y2Np8MlJgKss@y@c zL@B0fHlC?w@4JS2eK}Mzb?TG;9-}Ph<5NRkC8dF#qO)(@LG41rUBpV+R-dSv9@%HR zZtWAO_5<3#C$cqInK?-<;Y;L~NOA@c%Q5X0kc>#m@OGy69zqJ#D+u0u;B&(83VPyM z@0nvFw&p4)q#cJJ4t!vW4-Y2?L1u9O4|PE__x!Hu^|>21b!%Zqy>8c;bD;V-KYvd4 zTuU?qcH@(ypW>v3&fl+pcXjsrbN{%iRU@?+1B%&Q1Ejizf?T)EVOdoGW%6qeLyDM? z(ZOe*9{AC`G#WC|*wiNoY8SR9+DqM8ThX|ESdJP%Hf?i>U;*>~ChL`x3T-rApPh-j zYK|i8{9&x&2~Q`*#W79eb2nS}Wx78%?-q6VA#5S(tGgT!QrG&+`uPrTz2T?$tAUAw zffTKb!ga?i#OqS$9{S<&AH9&s_hn{w(@|gdhVbrr9=3W;NR?8|wtp(-WXq33u}329 zV#orL8U?NQlM~ZWh>tJ$y?6;(ik?q*Z(YAQ{g|%;DF-b`#67&-GS|pij>xPAwPOw* zepYSVS}EyV)qB1n+=K<8P?r-qW4Z|^A7Fy^MhMbIpJ};plZ^Nk*Vrc1` zT8~GdQLaU%@~kVTTfT0C2=bUuTI}a`=}pgmcWj8nyLBvh*b}ehWMd{jdx#thpsSy} zR8OZ-r6d-EXDF=~TU;H^&4qH7Jx~Y~%s-~&lXGEmIDdKE!Sus;A&rVA<{9IEd8M%M zN5H(+Q^NbA>u4mO~DC;pA`N@4T9!({F%XnXUFAxOO5WFt5@G#Qihx|CNl zOW=>%*~+@@Siqv~@73@qqc*`pwn`kV-b&@gq8UQ`MrQPV(c={&8VtxR_;V?!9ScPD zvzBQZ1lDUm(G#hKfa#Plw*I4A%IC`hucu&v6Mff%AhX)ZV$cXYDMHp!Z7U7Gb-Mgx-ImonoLXMy6U+NJJ6RqIjvI&SqXmOA^yd?cIe zr|!z^-W2|Z_$bE&A>yR=d;bl$va$p|SuyToXs}r;2gNtsuS~4`jgtao9HVY1@gpP|a_2E7rJ4$x5DWqZ9-jD!0W7ojshj=g=Lr ziIgl?0snJK*>5#1BPG3pW5q8@M1r}s+v!><*xL1peQ3mz11}$2NC1TbM`V}8?X}gi zb9GJs$^NH5eEA-kES)YvLMfNKaoe-M`BKS@6yH#F=|M^MI;%^wOJC(m%c8mj{o_06 z!yd%wCIkxJd{2|?CjIVq>q43f z4~>kw6k_KQ4Rf%%_6QNM)C+v|iea+IZ(x^K-*15y1RDF0jHsyB_Y>0qnV2VvyMo}Z z>?8@I(lw*N5>nm?mvquOT5>L{wcS)uFi!n-oK{9;D{Ju7>OvF{+{#@Ae-Iy{!F@l-1bSeW_FLkI65}F7h=z4&ykt9+F~N&* zK*4)m6JALSbNC)9o*@07`Oca*}&&IsW&)iO8-9%uRuc2Ncl>A!57xaOCfjH|Jll1sN?t#?r zf6j~)^nXjAz2E=oz)j^%H`#sxkKSKx^5L5QtNS*v|0~0L`!^e$wf~mN0W-uTL#98a0p+MN+`u}|&qn_{dzi*bK)}&J@k`}FNg3XEo%lVtj3|P0 zF+^9F*L4Gz^MDEqnni_iV+N$}v;s4LPUZ}*7*jr_gxRavasl~KPm8k}0ApY@831GE zA6F&Fh6qS~&C$~O9HZ|v5<)DtUmN+k?Mu)}W9(P)xH~|1L>A~6^<5sg`u>{5(~&D9 zx9B@e95#4o!KdRRVK4&x6p`jm7KSfNH~!eM(nq49@-HN}pZd~D27KXote}4O;qBsY za*I}FT@_ip{c-I+bbHTL?_p`>BoQXlL*zr4{aQk60#KU^w7>}xib2K!%vw<(>(CuC zVSq)kMPfM0)yJv49lJh|kNbdH1uf+P_#H)+cjD%3+Gy(`H)6<3ODo#LrG+{?o`6$? zKiLz(@ZJ)}HXrDLII0L+DVP+y8qjVrE>F8^`u08V#mX1%^}SirUMqvUsI9l7x?}@6 zJq;$F)f~773SdNm!XxS=d(%nGz$hRC{k6(6AAoh2A9P4Q2E$;|SAj~aUbyJ#QYDBh zF5-!R#DOo6B}NB|1EyNg^3wPrp`x@K<>1Z;`W}#)RfN}YlEjg^JdJ>wVnr}(FZElY zm)tCU<-Bmfe8?@0k}?}kpX>V2Y9A;7YUeBcYCJ(-E(qR)zQKe95x~C-0Kll}eE$RW zf3ylUH?CX^T3>Q~caeQDPNn6xBahz~a$L}twFtC;`{;>&>x~lf1r`l0tp`g?0**=N zBM$BZBpZrvaeNgztKv)oAv32ef!WqAW3e=Iu8yDPKPE5l(rh7>FM0lDj4aFDdu4GbyZuG)zX*3AhKJHZ zZ|xH7(x$zqeuY@Ttv(zcoNz(s?14IQ90@8*6`@NC-LR0>< z*~?K9AD!u&fu;t=Vep~r(j}?C7o*x-qizF>cirhOf_SkAqSe)s^(Nchy1Wn77lT#( zE>lb;Hv^O_UAzPl;tGw)MF>ch06BBSP5JpTn4|pBO2G-;@AYPylA(%VI=PYJU4Pp% zSG6fpoD;-ZU8=Ne{blNT%;sT3hV3!jcUL@c<4th?nN5m7UY^4;ogW@L~M z$T=t-Cc%Zu8VwK(O>4dQcq;)(I?lFg=u?)&#=^@GZGBnV$`hGoWj%Yq;!I!O5lyT^ zche*Fg_?-Qr|(t*<84gK4ylVA`D3myv34QkVUly%WEAOQk}2QJ z_YQ0bz5r?$U>%TF={o22WwpH5g~c=K<4B8);~-DsEsHQwDF|3|d1%U15trLM(nj|# zL|-}-%h}!GA_3#{--{uzupWnh=l|}g;gcAUs9ccG+mU)3by0KnMd84=$Zls$@r3To z$7+>5tU6RNLj{|OCIXksa?8$Sk{F@_7*Tgr$i-bW;a7X*a&?ZRt@p8@a;l#tx@CU< zbu!p$NIRAp;nd`;-nwm%g$ubL9;G>X!NvPb56FEG-<#!Mtur z=uAaeL=bd#tM?gyQ%OB3bmV@nf< z^M1nZGPqi{uG(FXBy$mKNU2u%plbZ(Gb|Ba^zw!vIR#AZ^m^4Lh6@^-989~*xov+; zx&U+7w9NBG8o6M3=2O@;(1ymCksOE@s_X&^m98EN3Yk7YA7JumQ0& z?2m0r$f>MS=yn832HbZcjC{coPr|5q!W>PY1$LqqV@lCk0ZA*W&mpbr1L3vj_?nnY zu6L(6d^+(vvm%yB{tQf-{kqqL8ZPYz9P-}uxzwz@TYi)7&|URF=`9q2HAYSFm3*rDdWm z#ilZLzf`v>LS-H67lt=-YQok!;%Ll1N0jAe<|nrGN`#+H615M!*_w!j(dy>?fMl+^ zRPgQ(53hBz$Cpq{DB#hKmln7^b@W_V61fR*5SljCfWpeA{q>l3Bs1mpJ=b@^R>DQ&!)XZRzS-WegqwaHgD z2cyhw4Gb>+-hRFD4)#z{_u|j4$35;6i5J|6#@z`yc4??*vV@i~O*%&}N+D5Aq2#7; z_QXfDB5zR?v!W~xRCpxW(oqt2?e1@!m`E=}1C{u)A?d8Vg81ELu-C@^58i8I|L5+t zAubLnMsgT1_U;3Soc$m_EIVEdG0#F5P@?mxY59o?7JtM8SsFmKesOU427fepJ4X9Y z?UyYlIt|5vtnLP$tDjFH6Aon;5g%5uF)T2>b}N}uu87u*Rs0Pru2<>dY&c+Wj-CM?j42N;KR@63byIfb z6_eCxQE}|g6=ifq&~=CXLCNgBiXKglz={!fSK=o27jI#Y-cN3Qoj(|lCS%HiqDyum zv9+jFyCwo*$RORajc}%!=75Z|S3wP}wHb!XCuYFs^h-tkz3d+qPvzfpX#=&ZsQve6 z*b17rl`Ci2KWc$+;H<)d7QJD#=+9L=eg)1N^~U&r)#`yJep@&9%d0KSDUUB**j6{$ zm$eD4Pp5&;W2Y9En-{&C6MyvupVZnPv0JXso3EYOd8DuGb&Zz&e{0{v)xQ2(2mSj2 zhEDIri+^-_teC%jJU6@PfA;ZI?&T&}pKlb-=Hh>0bN(jy{u>(E1S9=}ljI#>DcVCS zjT9rhM^bATv+Ea7kP^%c40<7$d4fitTAbOS9Hzbt#VkvCJt@ zoGrCel;f1h%E!!i(1qnLLz#lrS` za+VY=r8E+}y2zune+Z5}=x^gX_PHU8IRFmM}mw0CV!taP+%Hw-7H1(&J# z#%?Kda`^|fz)^hO_kGG*p|cDo9f7B~mgK&$oflQ#ddS8Xz(pcHyc(RY-o>0!J74og zVY}Kb^|~$23jO8;36Kn)7-t zn*su1v+=UN$zfzp5SFS*vfv_(d1x3IbRuz_(a-Qz zAsBvI&8OjxZ8v!uE%WgE@F^}=8O`=mb&iXm9@D}#Z?6j@t>w7}pMMF3u@u;-Y>i)V zwvy&w_1AwYej82knKN}{xgzuZD9S>S^V|vy>yquWHWLL zjFYwRX})8vA7I$TYL&BNIH;#&c)9|!;qM>y9asq(Dd* z*U}wtm^PCc7NiUwJw*6wMja4U`yF=vtroAMQr=$C;aj{nEv-zy_Z3r;_4@41pKXt> zT)n}w69VUKkHRUj+~jk8`TR%_;JfFP+5x@&)??w+GL<;)v9Z*qi%bb-ugS?akvm&e zw;269zZ}dOPkAgC7<$gUBbCY)YU0Hy3*M}^W^RVFvo8$GK9n=5ungw5r1#MUjdVq$mm&$!qbgnv>ms>2&4h?&OS)g$9+jqYT$lvgqBtu=ejETn@Z72-Ljmom59 zHhYo};?BoFFo_@xEnDFozI+;FQ&W;BcVbVpRGnGv?s^?xkS)~9{?7FW{kFr(k=E$~ z=Dn3Iyt~cCeHGL$bfIS(rim)h2vO|3BOtVL zNGgMwN%4>-@A?W)b@1lago`58DHd{qGdP{4xCiI=zbxe|oIYGsERic)1nOvbeMcgu zJrK24)=Bx^htRbX~%iv*R zQV~muB=myXh2zt_Y!w|@6+q}Z@S8XsFWmPcbviA*Ugfdu!?WwIlsPVEf3fm+XN*4v zL+epua`C#zOWer@i12y?zo08QmfeQzV}|oN&wc6aS630I2dFiS8G1{le94!E$IHbI z86G)Kp)rKaZtUyW#FrWNj6PGRJ!AC-S8;F~Lg9u2Uco$&-hLC!qkpP5`o@Fy!EWC^gihGI%%UFjZ86~4t|+&>(OY>5sq}d6`CMsFAShrAQ`!E;e(@Hem_T1RjPC}2Q|VEW^)J$*0%Sn;)k>#! zL(BCTMvEjQ4CDZ0kR;1FAzu(|)i5*WUpYD{? z=WxTTU}UO`+I$A}!j2e#c_8Z~XTX8#k+Jij6$@exK#EGy_zwhaggG?_cHPgJ;hagx zi9Te;LPM3n7l2d&^6L~cT{e2JkK|+_ud`4a*4|sXm{IQ&pby9b@bUrNj>XfXT>Vo# zv-BN5$saq5R9Q$583StPwpzQ+=s-EoZIo?uEw;#Y-1Gj}j_bs|K8E3TKK<;^%BQ=Q z7cNH+S#r~`b5cJ59MR=*6z*EWRyeS&idljgDbj>KIN;GZeCG|EiY-B-0l~r>zRH-_ z*6g8*BZse+HzXz%Y4uJy6GG*zY^tlbwWGZWMQ2V)n#($gN=8t*i#y2RNpR6TVD^Bk z0*I0!5eB`Q*}e!eKbrfN9IL8b5)&8SkV#|&^v!y3`>DbQ+JKbz;Tf9=stj4F&FE^N{iseJ zcx8i7JRhB3#|&MM;ws_={5G@Srg7>Kw{D`MWrIB^dj!l!uN`xW&+Eh#sI~2nMEFX=kTt_QFjDS9NseC ziB4#!HZ6F;8}hB6`xbo{d)R6PG4)8I1{uXp5NA(%aLL+Ia~PLo&Da zAE*;(`@m?x7Poru)DQL5n~`d*S{HQBtUmj|g@)hZ9pnD-Lk8FW^_?mU*_y;n6yr{I z`v%OZHrSjUO`!NO+xPI>B2+~Fi4fB=u#z+>#KI$G$P`!%YwuvDSf%##H2DgKGXf#c zHdT8%p)>U6RUQz+BU(h>0}sNq;bcy2((e22LDX1T?u-RQco0}E*)j~z~r+Ycc@4qWwS%-gHM}7_? zqEZ@CV53ZPP=4E$y5<+)6XdjV$~mi96&>#t^e&1n-R~)9?QAe4Y-i=t%4AkKB%XOHI#KtbO>gapkY&jNT-a>Fue= zY+;0=Zp2ddPP(75nXq3rRLTqg*=E3Qb01_>O}lA-P8Cfy8@y{dB+6v0%%&^9mCf5A ze!P@Crw!ods{W|K*Aw|84+6Iz@}1$xz1Ujz`Rk+IdO0Slgv5`k6!2Na;rbr3P}{wA za^mOayv<^+b)x0QO6k~lo2JQx@PPnC80rhCoo|I@Zs15t{HpEbYPI2~cg{>(fBulo zDD@JuEf3m4gJ_V&p+Yvvn)lw7fMeo{e2oTkccEWnbPb_zUlaS*r`u}=jFy~xTP8TA z+>M=fnxE2FH$z^WPpRU*?dG%;`r!xMmb1K^=68wt^6Nw0Qk>o5FCQc7!&qF>nqOSd zkLW#zsm85~jn5bxp}1~8?~p#QNnZ{9g?J~R**CTmRyy3gl%wm#7KG5INKVz|5GX60 zGRuc_Xiq@xdp{de**4wd)#Yi1KlQ@s^KY5cQ$}VVy50pHn7^N&Nlr%R{_LA>qHthz zl<%0&J^d%Ko6joEOaoQlFg33c3_?fET0BhlX`>SpAG3qj>ZMyd`ZWue60uD~tC|mw z2Vb}Q@Q*UuB9$wf!SDRN0N4cdIrZ@@&^1U&OUguV#V>e;x_~GEi!}2}X5q}*dTiK@ z)i^Wxal<6k?XnhfFl6wJ%iCU6;9F6TC-#dN4%E(HeDkVcl)5J67JDreGxw-)t@UQl z;&&vH{h$8@EbsrhzR$S|xcAnG_yywaD-(+oK{hKut~hm4z)&ef#_lLESbj&+hqa9U zraqPKkDm+z)#bE_%Oqhm|ZT9T?OQjJlats4MkfNe7)YuQV&y9@cz4gFSpX&ANzGLA4PIoXHJ`+F+QK_ zk!~{BrEY~VULW$iC+)Toos`BEVWO=Cf^T>2oNOPd-24M5~QUpjeu0ox?IaBAioK>`fPSHjjK zSS2c#OXlax=zNV@v$u3xK9xdNzFM|kNh2#f!a0h{=gT1CG)fdz57jpNw!CsGw^ug*j zjMt5~W9_hXwvOsd3(W%ddSBl8xJC@bzV;jo(BB+dO4w{P%a~cd zQMLz;v;66%yz?2g5w?%NLQWrbdf^u!(%mpib;$eB5Lo@H(Za`A*ZN_)#H{ttoW|Dk z0Y4|+s+BgzBz-bbKk=RQ>JUC-;ry{#fl@hoJgVw;x_#|8l6E*BF|MZjG_jhZ#Qf&CiRbcK zla)<_vu;Q$_s?xiMqS4h&G&-iZLEj#T%I$>+}@!;MqkY~b8Zrb-SS@DKsalAKX}s7 z6LRmY&5CZJ+81K1oQ-ucsGZA$U$FF>_TsnfM%RKNEC4yGeK7QXhuPem{bafap+6hD z%YW$nHJiay_jZBH$M+6&Xq(+9Rg@d?fk(k;!D;&-pYaI+MlIAShq^EQWf_j(&i z2<^MDXRk{jm+8{X^jQJGx%2yyTtcjl{s#Zlb$NeLtgC8BnBgTtfAj$HUCS~Vc`S;|}xylaV9_?QhyeWkjf6zIQDMQCQoD<)! zpK8}iZFT@&;Rnt7lx@vq*^eEbvEm~zl~ayyDe%%?Nvnb0|G!(o|E+${9o-4GL^*SiH*M;HBj{{HFoKl69C_>=W{);YRsLcnMX&mGnVx&8nKwEw(i%^-F z29KB$bm2?Z22xvxy4{2X$6|2egYji$^w$YB!jJ>Vg@o8rbeR)8wwYh1nefy<7+WEm z$wER*4$LkhjngsgFq%E?PRv!5lO@B1tcx9n4uXTA&JZ!jY7~_K1^Jl?#<6Q`1uZu{f>%Kl2jvHuGSy znS?aixVXj2|KM8GBVVf55 z1N=_dB*vcgudRFIrLiq9a;P zZ_$3ydA*DKtMLeZCthuJb;@(k10h7;)J&$(BUFyJxpn9|OOVnY^`cqc6%p7~7Z(n_U2a->HP+KJv?P~l-7V_^%bseD{>qAY)3QWQ zbkU8V+ySoe4M}@-p6l)W zqkdxiPvMea>aKIFp+ydT=g`R2!Eu5v{QSfj3;M;z>t}f=F7_y`OUA!EfDrpB!WUDF zQAVO~edaMqyd}MGZ$Xk=f>!5&c98|6{H*>|D2B=7;re|HjHG=ZNnml}Xj7NAT;x-1 z?Iut~+;u^GZNuF+kETe!Bhn=HxTNYA&`VWD=dBA5_pNBodmam1{i@hhv=zSo3Pk9D z+WG6ym4ZA5J<`g9rap(uysEi!U4D3F!)Z+e=Wpz$v1tU3LP$NWcijw`M4Zxcx(_ z?iS}8n2OrjtrdFoj&o#O8s&E3#QGUL;^FFLUS-?Xekou4XMOXQ!M;VHTTI{~FL{bAGHujF6f>*%da;31u1fjm)S zDTHnLmvD%o(-Zt6coZ15xDH+Hc<<{N-D9;R?X^tBEl5Vow+017L6-wZeJ)L8gCu2l zhm$$8SpuS=LAC6-){Q7yQp&QmrKOA5903M;$^K4PDgZvf&7qDsKh-=!T z6J{5RiE7CaG?I)NMNr=N`RwMWBaZ)3uD%<3u;S^M$ln!_ZYPMk>UuLNk^UA&!ql^O z?iKQVyb^`Sy^31v%#n}Fi~_X__h!D~ZIN03SpPi3u)ZOF&G%~gTVj2^;~1-5iP`VL zaG=2Y*2MvznwgsU`Ft(_gB0;ERsKug2S;~+);iB6W|`~E28EDhEwNGW{RAAYsKPq2 z{Bm*89Qh&wdF9{fol-s(QRZ*lJa;t7%TUT4F_P-1SzZ-{Q!$Ub<$-oj(pA%(;BW|`99^ghL4=V0V3B@IxlyYKH- znHB53qRi}`?YazC3m&~6rVCl(S53G&2x46`}50skn{$&8)P52@pNecOZXDVPx&e zN~fr=Q|I}p-4HpHjE|OWIW;K|Y;GM@zIg z>UE=YW*Hs*8YB0Cdn0 z@*PhI7)g+*wcDP13N571k3zvqlr4STWMPr=cce@MuD0j)C-K~{@?%No-V171R{Y;R zdz7zf78QGRa#3nOUMhYU|IIlK%sEP;6`Mb4A9Pu2e<@6me+b`QkI(_4o8j{3R~USP&-OjdH%Rf^?#?>2V~KM4j$MD>qk7_ z{x_KGza9*07Wjg*2k2+OzG?fPGsn3-|9R#hfqj#r)aP?l{2D57#D{^9)$+cZ-6>nc z5ep6&4;5~4T5UmW%idfX3sI1USJ=|Y` z_cmANRYrOiJg8GkRR2g3CrKBJ(AsmAfaHYsFx7BCI#*wyc{#}#Dl18sE$b{!zMTyl zIr#eV_h;Qw{KHqyaINiWV`56&0{0y^m(_e=qdJwYm1;G8FUd^L(_R{(&g{a=6^r(r zgHw@YEIA#xWi3B$&G^0D@#?qj3c9yX{|z!cB1c>hl7+}*VmS?rsSVVk?#I`fE-za+ zJ6xghl5x_EWfD)fD4eS%?lFaY90d^F?j$IMm>y$`km8o2cIwd1vdn=c%|~%wmgB&Z z0P9rsI?_;CbnPbP`sQ@Lf}5@t`3#g1r%IrOutAwt=47x3ss@J9hVs`0P&*F~)eyco zURiaa(>Z&i$7<2(s9@**IF-q=a`+(A$Ah}yEFo}-BX4gQ8mOUE0Z&+U@7g~4rDIwK zHqu<#Go#}Ut?e_8{+^IZ$i2B(%IlR+_}|O;UhGvrGP7ts2bJq=N6Z1X8UoQ5_bX!)y^j$Rd%137{OJ9w6&7)@5K}HiAij zZN84{V*7ZfzDdKw|1flb`Nhg|rJl$rjmvZ~t;4NL{2Z0>S54YuoUcN_*I14$G1f^Np zv}NsY><8lgv?F6(Jxa#;X`dJPr4D7QqB$brF;##1C*dT=xe(L1?4@ApA11^7mw0&M zYp*Fj3trJsiic!hyX2kxU8?bU?c{^L=hKgNeur?qeZeHaDc9~{)#gdN1P8U_DblL` zA^y;od}Y;E%BR+zZHa{zF^CgbYp1_*)g)$NT)BUxpX}co z!6m~*wFaxA3nIsje*QY!BGRcH$yNnwC)oWJ5v82li0xjr`f-~it#DHqp!m&O+oJh=eC-;b zGM;{p?CW;TqJy*R&p4FszUIsK%%<}xPp5nu=DT%6>CrpYEK-lSO-|w2AR6X5QmthL zLvvs!uOe+OE-1{4E5ec>kk_CRYKqy;@l`+8t+^LLxWB+1!bm=t73E7ua~ zc+%ovJ@sV#ohUNV04Vs6dRqIePQOG|z2FD6?>*>JS%=|?FZ%GlamYT=M5EyOlQ$iC zt;oB_?u6(xuFf*Oi_ObFsX6ZGe0kZP1JnHD(x%Du+f!L@f;a1i1Pw3hNW+-s`$N}S z18+T5D)i+go{UDAtOQyGJ)D|)5(6>^Fnt|Vcz|KRlM;u)n||9?xB7&%=+T{<)q=I& z(r%w-jK4*!Du;~V`T3qO`*os_a4MZuwC%QracBMMeo8Y{1WkkaAjm>co!+*euWt|n z#=L#HyB5^WFVe(ml5i@Ex}V5hbc*PxH)Oz9;C&~S{SCs7<4E%X`qCja62|$7{3lQI z@}fJW2uf~E3hhiR*QFbk6IU>Q;E_ib9*i}&Dm*Ydvoowz-r1+pC#5Q)QI(U^L#LWS zG00~_x5dU&SU6}*=kA$GM27$V{d?}yPSZyT#MgSO6j{IPft7#ORVS7d`!|JamVB(% zR=Z!k`}xrq<5nr&Yxbg3vFKFrPN%(_zk?2uX}ivi zx7|Yh#`j@*tR=k9#^37N(XpSKJ1rh;dt%q4CYFXPz1LbUNtfmz+9UYBU)yG`C*qcx z*gKtK^qaGLBTAejhBB^2?nXq`e7|BgP{pyB{Yuz0`9zs6AJ}yPj;aM)h`Tj1hM0Cj zx%X#Do36>*pIVje6r96tW9dmyyP)3{G_U&#Oaa8{^z^*S*wIe+yGCpSD=zjCi8jc9 z5Q*;4#fxXNGxl6Sjm_xlW&p+B(ds(T`MlSAmEcrb)R>cg#qGtNWtNxlCN9K~^E6rD za#ZCZ<5HSGKp=DRZrbq2+&%$R2>15x91Y5s*o==YK&!0>-I}(|wcwhy=oZ$Xh)a8E z3CD73FZ~KDGo}tr?At=cc{%UKurYckaIv2S`Y3q?(F^$BiW$z*@}PDh@PoTb)`Z6F z*Z;DN-aI3Km;L*^9rg>Mp8sT@S#4?01hG>qmw%Ot=Kf*t`r@GLlIhITi6<;7(4!@$ z#JOws&4qNf7=kpR4Ta401H4%J41M|TdYj}EZs2M(a&L3c-7`29(z&Fj<)EvU-pS{O zpnq!x!luO6j5}gFRRNf=?d|d*krRCQqtRatC1$>MvtA2%*%-qb5^Hz{J+bZEMl!AJ z%Y5M{t-juu?EVYXE{r15nsp>C+g%S&nM3IdpMBn(DY?y+ zV_Ro9R|%E?7gS_sr7q8FB0L{@nfz9i1^G}W^4JY?zd!+%gA(oVrSo@W@|YuXBp+6B zD_2RM4KgcRZkht3GADT)F#=y{A!`zcSCH+}+}_VkP<9f_xWd^{D*AQ3;nV|(xwsyB z_R{G7v{yVX>qK-b1ie}}22af~dO8Be{^UgACfkWu>MkVi`$oYLpms%$|4Sc9DU32W2*c$wXuEBk;z}QCUe zgCY;hnc@wCqyMH6&{*9Wb8Ft`*G+<2E*$de@PvG!9YbYRSQ2cKq%K7RU=SuM5Rfww zAZg60_jJ=Zb0;P$LOTU0V^H^*U4%eKNq`XAN`$>CQkyUr7akV#4gn~LK=qXZA@@PS z393TAp$sv#60R5tqwDfMW6}&KLk0>X@*eFM) z0;?nBmw+6#iq->2eeVjkCRb5$UZuy8;r-J2Y5I%b@o_67n$&}k6cGMUp%!J*z}g!a z0w#*O8Z?;ZZa?nUc~vTEboKqViv)SJzBr~;HRe|;|E`S>eh$@ zo#qu*ZCi1mRKlqSlJ$!+?Ni*@sCrNuQqaoM!Rc{$_U}^hN=X_%oCg*Cqdo;h70#kW9;9!5kR!WkN(! zn^f`6PBH>$$NB&`0&arw?T)rZrzxqaf-YDPK`Gh=Dt&Sgb3OBd;$#Y}Tk7CGJw01E zM3hb#8(TFGG|!UQpC3-w3AAz^PPQqVM3|RG-l+x>Q2Khq@Q1n-zfuW1;GKnMRDTHQ zeulo31p;RUMn?^A-9rGC@6E0>g3LccH=F1S?-*T-gIEVqHBRZEWAeMc^5QrqR^>7lPEKCW zpX|*<0|AG}XFUZ?HdAXXBkr`0K8Iwrt^+DR2~91Q4p$1?$2Rt-B*dLz@O&K>s7G3M z^>OxoojEaGqLX~tV_hm?s@ZK?i7doSntJ=jhd$S4WM$)UrMu+Cg$eq6<^%6)2kqnl zeT_u^RHCwUBB-4w4OmO4f{HBSs^^;Z(;%wwo%k?LvNK2g<%efRZTwCbU1e{Z*gYnI zdFHsj6XyAc^mTbc{;EHjZ)pP9+2%Kqi;ZE62Y8$ZsqHXT#4Ov;50m4@3EdH-gzQO( z#2!IDp31L7nq6IguEpFEZESoWn;ILjU$CVP=?+GG>+s{aySL>p;*&^IB3jW_9!i-a z?s{-CQ_k$|$3DqZ3$3G;_5D}DbThv91b9iZnr-Z-pGv&A$(Swi`c;~K1!K-P=lpEn z-bRV|Mm8R={C8j2PLq#RnReW()8+ip3+1XawwAEs?ekNj3 zOa)CL-!c-%XbKxa7|*n)Qrz1pyH=E{Rb=!tAFZ0f2wD4l%Uva_6bBVF1t zu|t9HMrR07kta@b^Ftj@zkn*KC`fEPJnTm$P$BiwU7w;2@5RM0>#n2|er1ho;jPqt zWEm=3?;*A}^AzfcvJ6l5&7K~=_fte!dnru${HxycQfANKv3x~wSDl?=_r8B{YDw6% ztS`q@plew0(uDt&GQbyE@hwIw_ttbB#0@!^0cElU-rO(r6JxeSfbDbKGlf`_49mug zNqK6q*;W_sE?%s?NHroqK!O=nSJ&9sRDRA;7V_ipA7Ar%XL>7k9$#y5VqZ2p?C2Ni z{?rEP^5^p9o4jxg1F*A*lTzFEBODX9~bzK@9SBj#!MmHZ-lGh-8$k6JRTuPNoO;541D15($$tgIs@1FZ0<+K9qAR>I6>gb zqaU(yPRgz@RZvH4WWDG@W$Mw53QA(e!nh4 zsF*^DrIy`?FE+10`AoDUG6tOTW;{FNhNT-iJN(Y}>%9(l(A2;<3oMYkTt5S9-}~4? zeK&-A(Wz#E;#Ig`5$5ftM?$IA0%qp>Seq}&G<7u7Y-s>T) zuvA|{TDh6^!ct;_$B#98<{8EC0mUnt)sM2_l1`#+HiJXw9j*Tca)JTe0z;wWcA`s3 z4Zq&bUYWuct@lyOZ2f*>l~gp6b7~ga6!s}ZBSlbA3iFTH6Amht4gx#>FMhHsF11csPkMN zgIyESyPs6ue#6}F8W)D^3dYjW@?@-`r0){FJ+nT9;w;(CUhd?)k09~$N`mZVP`dz~ zFOa({$TZCs#Uz~=9f=&eiLv&K5e*861U;fGhA-_&kisoBF*bZ}c13Vbq(TcNH$8B# zHJbYlGK$CQuphH$_}qSlg9I&w%&sFnlR!&{*E+0I?I*%L2r*R3F9Mr;AUXzY9 zzr}@+F;|A)f5sD~W3BhN-)+MJ-O1dcOrMU|{OX!(`if4E^wJwJQjRM|Mu?)ne7ON#Zk*~C9%Fcn{ zk9czN_bXc#`IO>+qRR;?%32g{)}O4~8NZp^9B<=tz&Npn| zYd`(qGyb(6ilq}M+Ob)$1za!mmpd3rx`o#8*! zO~+zyf8sJAaoQ3xb>C*A56?Jd<5quG%pzRKJMhPDSS@;c%M!JE?Dx>j`hW1q|Dm4f zf9u<|=cD9DjL$|U4{5Ofzcfq7&P3;eoOi_rv)U!A4u2)5iZ~?gqYA2wH}7C zWD!#PhiDdEZZ7j3Mt4mJ&lJEuK@dT7vZ&A=sDx}|<4?wdgd@9Y->0IlYBE8L$|7U8 zBFU2gbILxChMcIJNkQaw>vrwIfOAKAc@5EHrMe#FpzwrZir)H2kESd zfWRHc2TcWm4+v~VEMS=FC6DvB=&dhYzjev;0#?DN=Zo?G*5&d4_2&XJdG>$fnLPWy z@l2j2sSnRT3l*AI8%=x<%}b4cZ9{H<$;Q^MMe zhx`vakjVM|SI-Gb82I8fycOo-wW%+I3wWw-?P?q@tsSO7K-H{mHw5Yc^GuhRio3HFjjK0xUzthOad3|i&ngN;%=A%^1V}e`RKaB`qbfGUD?+{y32sK1qnSv5xrB-R#U zq(oo4)cTbpg(i1xW=Ny2?Pyo808~l%1jCy7e%yw6;xrgQI0P^#IO)@FGiglRzT4H} zC(DsIHm~kZDCv@KpZ#Q&1M#O%w-?3RKF0&t+3|+6Uqeb8gLp_0n&NY_mm}u5D_22b zAU?~o2iv!@H}PGg3a8g?BPe1Z%uL>TEwM8=$IYx$2t=lN%W;C!ZYF5bn#=S85(Hs@ zxtk;4jxXecI6hVk$g}$Rqrvuk1PNU64o^uCiHM^~_A9%~HF!b|hlR#FZ~yYkUvCJx zSQI@O*!JTY8jR(p!_>!iXkNYD3G8_5-dVuzAPEnr!)z%NXYYZ~DxyIzKsY#RQ~-)` z00Da@fOVrGMi=IjseM=@AO?jSR80w>WMtVobJlx7TR5|AtFJP;qbwwtWV004-D~Ax z>ONJ8&L$GKqK!rRKmFM;zzT_2-DT+oMYQ`tY{?PCaJO=2KHzx+bf|fwI}O^p5+P10 zXQppQOmmWto6|NRJ3(#O!lwd`rn;cS`R_s)`infS> z)v!*5$1_Wn`gcfI3qASk)zS#r&;>5M{j2h1P%J3ExWRFNNXNi`_I_;VAT@Fys=JrX z+$ZxR$#R1}!0*}1=~Ehv7-yJgbQFQ)DRWEu*2hhDB98vt+8?)?qdM2o8BhDCEU?Ct ze3dn1DGVFIRKk_?Jf-A-xmW=#xXcBO{1mMvfphQBKJ~QeQ5Ui}iFHCA5Lg_X9h}q7 zch`naWx8HHaXc&IirfF=Ue|ap&trV|)u09Geeg`k#=f?tW2Co1vC|hnioHY;q*>gJ;VgY2D0`nNnu2$RXIjw%=WiI}PrZWns zP8}>>_0@}Dj_oYiKKLthP`g$-c{<|5_>VtymeI6@Pn>|Ax~pi46tTl3Q<Z!6LtYb&(+60CsfsLHOytw(M}A z^Grv)qhWB=_H2AL%vX(}TB$(XUIL0~v2I(F(UXtFxs@|s*a0LAxw0FHl$FzS<5v@o zBnW9L3j{m)bjf3rt1;n`WRZeQ&yWa<`UwMi?=$`_4Xeqh(lB6?y|a%J@(n2`ohTQv z1+3K?b@BC)xF9^sB=@N7K#~hD&c$_sq3gz+6b~PqMg%i(dJnK$058h`MI_L0&B@3l zXaM`ms&w8}TM9(gM!7oOjz1+eqbhv;y20Uc`U z!G+O0F2GEB8*j-125bw99c$&6CFS{i+;QCMSeI|R3Gb0b=X1llTY-(S%6XU3iHHwg zHr=HV;SGaXkx(pMbbAL&=>3LDp*<4?U6Ta%>)4Cp>pthylPw>bl*AL#T&nlN0>lqi zx&!__A|nF=0&aZcJ`IGdI2Rhz-wOUp8pB`knjoFC+T81RL$Eu`dx=B- z?A(g^zWDZ*K-W6~Oil^n$;IRSO}sHcS~%wI8&Xmd@f!BV0T)6idWVn$tPMkuwS#Vo zv^bkTKtfw}w)9sp{YMc3b6)9@9Bizvu4>&6(lHohQI|6KcbF&FNRK@ocGdrdDYWO7qyx!`hb z)A4S1Y%O~&n7_OcQuy}i+M?dj1(tPUSI4BJ_r(}4ZJwNphk9tpt=gm<>Otx0VMd7->V=yFf=#c&p^3^d`l+v^rUVo z>F>BHBVad|D>g@jZZ?U$+T5&TvCxL*w2jLzUnBCibB(1{bC#e5drHn{nX(Sr4T~=7 zlGsV7r?RyAKl=8ZZg*?SZ+qUp_rk*Pz3~HWgYBT80h2u{(d>gmID7vpNjSSh>^K+V z#N)Nuj|%M1%;J+p*Uhk~R)}=N9XDol(I#W4<6E(SYgAd^qr_EW zet~pe^la$6!p=O()K;l;jd)w@+u&ig_SJ5!q=!GL+{>@tVBNko08_bAYG=Ng^w6(E z$HYuZv`+Ky9q~-AG3Qg~&wA~RWu^ZRa=Qstz1eP66f{;C8&dU?(A zasEe9&;D*xv7gF|DM5>b_>@&ue`80R2P3|E@MGYmvB6*QYy^ zK4WHZSZ&sw^HQ`F92c!m(I34k@&PBj@i7BDSil7uVDbLWhJ)0)hI@N)G2;AiLRYKi z$==%AHzOO*&}sqLQOr13gkr+U*f^U@Zfvtk+d13u2Osy>xkQ+vt6Gdf+i)&^l~14F#Z!uh2}>L-W7`FwA^mri{(c3OyJq-`=cih zV#32dH}6j^x~Z$l!OxL;Hm+9;d-iqkKbbe|44bzuKNGR`lRFY*X#rqYQ1~BzR{ft= z)yGEbzOKC@(%x}JCSVL?o9J6|ZcUq?ag^&+)`5SJN#o~B)M!ullU&%|@(U#QC7L3r ztr88R{J{DarrXr8TT&5a#p-5S(3x}|{mxVDBo!#rfkBnSZIPjG5*{d}O)Kkbzdfk& zsYnUt5k~uEqQk7(moZetycD3e$QJ`s5SRb?to9E5>t~hB3ha5V4}i1N zT^}x`ZhZkVLjMlJfLq$lfto#n2ovz<_3($I$J(X8|9A`+wbA;tj}*}erH#9Z_mv0S z?=<9-6w_lB4qYTg2ngyVgKgGuWs%7s4#Eq>@o-A*Ib`nCo71TlCgQFP(y4kh6;D(B zAY>L$v9_$pgY5u<#V|;yo<6bzX*=6Qmf&QL^asQ_UBJ1sah(?hUtBtseWr1z2Xg4K zby0vijAgCfeCu@WoaPzbm8S}>`C&kQJ$ojpHg$fD0gLe{X+AdAYchfZ_z#a838q?9 zguoK%`Dmp_TYj*%p$7FwZ+HAm87x>_6ps%8tRA4*^$DwqPZ#OH2N0LzrOKc-RL8{x z(17`iK2#Q0pOkZAWQAoH3tjPR6)+lQ$Va21f|Gk<8}Lq0r%@r%$)qf+3BLvh%>!qk zPT66(yLrsT*x9j&dRCe>!!bjJY=1%A20a7bu}|WWO(x`P z1d>33=E`MF?jw}>j@=n7L*iP!duMQIr#@!VZHTNf5$bjDEk1zsi%E-LSKsXiB^?bM zZ3Hy>74Byl0v1W(AaJ-hEw%kR)?)=L5SvLq)M{7xXm~)->|jCBUx2y_Jn#oUA+huv z&#eo2ctC^YTf>h!?~K z!4K3-NA~!~Z9k17ky(9&4R1i1Jl9v$h129#L|L2`CZEu>L>~RxcF#=VWl-#b!D!$- z{U5s3r53s|2>aV~yHD=yLd8^Cf940$o{T0Zb9H#ZgF?myO(0v*R5L&V%dXH@!22-o zNof}X+;QcFpS3*e?dkL}e*y+NK1Nq}8r~VR+ja)SlYVLX;q}?|c$#>jsnxLKov9`X z5nSaGssMIQj&@akK#E+^VdH#1@AM;SQ#*FgL?uvVQ~KICG`p{f?N(W=g8b$VD@(sX z!9c~XQFGmrlj{EYwI?CtCJWTaaA>Ptx5V%6fr5kJ;7s}Dk6fL%DqD}X*C(X&`Lrg| z{jFxhFG8`8d;V6AX9$WN6Y9UKT&t35u^Fiq_bL7lj1Mzc`9Rkm?GxOy)zA!N-Z>|G8k|N;wk2XsLHW?&!dU}41!~HEwN0TCiU8}l`McE-H^3m^?3icgpZw@C{kQfJA zoDtOemO@$zXbr3F>;~+cHjsFqI6(Y}E{6PK@RjH4xsptfVAAwgU4n4iwkLHks83Wq zV3&KZ5%)lIJl>+$Q8f3$eOn!*Gg+`->M=?;(#tyd11gKN_S(nlk6FF|c5b9oT#Qen z=PZe5M{siMht_dfdC=>=ryD)4lvH=8)rzNVI-(d!;KQ1Qj6LrItz3=A4okS_$rE}n0lgF=!vew=_855HuP_+?JFoK zkSWbBlxM744dY+Wug7$q_qdnJ0}Q^}S1zs@XxaZvvZ|C4O1c;5pY&a3C3^kOz%}!Q z#~XX{(b4yPUIe{t_-VsR6B2=?^AVxKtO-X&bH{aOgXfdI#4n&NnzdmDl!f5sS3op` z1`nYLW@sK*yHz>|lDHA`38bevc=dDW)(~}G$4^1xSnu%&2t(Nm`xD(!I-+g%&E6~J z+Si7e7I69ebV1v6^JV+K@j=%tH_PHkw!`sUSfbm&?mdq0p!|s&s_g;ss5^B4cHRy+ z5_MdMl0E=ie;3pgF!bltZ+N5-e)s=uFPNU(o-_Ye!PtaSE#9GOh_?TsTYhl=65^Kg zH1!+OZuM;PciLO>O6!N3yz~gAqE?u|mzgmrz4h#mFGoex4=)rg=!(7hWQ=My3bWVZ zWj?;td|npEB>~f_VNSKcn&`{ z*mUMkYYk&t;r59<^q1rSrJeI8*Sg?gLcqrA1T1^Ee@jb)%zy%vD4A5~6R@HIM4NUt zcGZi*zG~ZVh_#B`8zz&zT{4GXH@#fLv96ms8^p}bB40B>Vg zLh~npVUjc;%T$z;mpUFvkw_(^GB|xWNCSu7qVE(^liY6Sqe<-)e2(lbjf}f~DwjHU ztbgZ+w1!JXtj!X=8*29ULW1`0s6roaWV`}B1J^Q+NKp7Lvq^at7O>4!fzn!-B=xaO@*pW88k_;-O2S_TH_iAbq?@N(>R=W-sKw<5u)JXVZUOfOc`hxTUGxdK6_Wn; z2>3VyKo6RarVq=Bkwt{z^heD_y}D>k0PH7<5cXKJScvO6k8?gb7Dtk2$kkC`O<SQ}!mekH_*0 zlPL|q^z(@I?xJ^T2TExvg$^oBrqu=4sW%AqE@Vl4SF)Vr6mIq^Sv9o(~-@E*!cln?8tm(a)Ld!e@6)p>Egc2 z10)m3xpF;qkXN8EV77TYi~T? z)gSiS6~$_uLXB6z=Jj#QTv#J6|EK_>1B{PJCx9Jm`#Ie~j%cjf|BxK2T?1 zw?(&C<6UdjbjjmeU-Lk&6A3pxn)f@yy(e#qO@jEa=%@C@nW@V? zTUG}9?f(bORnhUROyPJ|b`bR+v$E)axbT$Lzj9&9F&C~3V9){vW-9LRD1U+bI@4UA zFZ=xEzVe_Sk>}}-<4tIySwIc<#5KR%0TDqu5%daYX_~+ya)(}vv z91wd10&yhk(U~T&0B%?~(ZMI>>%Fq^1h8N+Xnx0_g#}2ivlu=BUZNogEtSPGteqlI zEW3EE4FlHp7#-alwSMj%-y>PmsJM8?_4nOE5IgB^4~$&77WoPoYzTDtOKIFKfDBLn zUYH#?klq-uxqh=C#%TW3nw{;khK; zD$!zj$eN(@$HZEL zr-SJ^Ky=SUqF8xIa@dkcJ4)$u7n?8^iU^3zkhnc&+Ymu5$KxFV>}<=V4Zz_LDmZm9 z>!!Z|!3k<$83qvSfC&eE{T6yjLx7*c{A1xk7w<_&0DKn(|6}%?FL3J@OBVgK(Sjn5RG#fw% zT7>Ve5ZUi^o9W@*dVRkQ-ZhMaQ1g(=rS*{#En>eV41+L9gsk7YY z7GhCH_C`rHms!dZvW5!|EE7titM_`|a*f(BoNBY!dKTHifv?dCIG`EdKiaYCb)6$wzn7U!MOHnfptphkQTy`0@yh<5%cpZAE4>(+~HJCotXTQ)D~8LK;P%*$|J$_X{{By%Uwig z7oRjpouQ=b-#81nFcf=}@$FoL#HDH&?xJMokH&~8P!?H;(mDJFK^G zY!kA}KTiD%(2F<9Ko{4iQTz!OA4#mh8Sun&04V%pv} zV7v0e?w#`}Hs_B1ii76K&@21OH};mIkjt&xeqc0+0K$>&p?aDy0)U;%w)!N945|vF ztz`9AiN<+oyFGSZwZ!$W2Y?*w2g3p18>7o8kzll**g0pXQqC&Ds%46#y57EAEWVs<7dRTCO{T;Y{x8O-F z{3o8%RIOO_+4ong^3;E5Yg?h9auk?V@kv;|JaJ@u54brcvH?{q?;w?BP4M#mCeI@` zFog?O2E#u3wsW_4)aCDv3_HNx0;030jfBw`@H}=AEqL}FZKJ1zDAD!_mSk6aYvfA3fu}Ak&@c=4nEDezf7Wes^SKc(xr{ zaOP@p`mJm0q%Mpjm88YfldP!OT{Y2>PLDFhSSOJ_YHE?)AvfN)OjPU)19NSTf8)6} z$G`Dhn;Ur}Pxp=OzTQ&vxGUVxuOxkeQ9Fg4%ROBng54lkgm3MC*niYwLUkcTf|(e) zW^`mV%xi*QJ{4a!Wb#yF8Ih!!kRNyI#c1!f5#1%e!ERixHjxKrQgeV@IcqF8x@%*= z{L131wq4b46)Hs^Ryaa;1(TChgkOH5tI{Y*^s-KV{AU3u0F?a8&epYf0u{i5l>+JW z%R$IM9reS)p!C;^8kYRu`z9M(5FjCKdfz>@fF_vMaes!#Tj32?aOFEW3v&Ns&t+^b zZNp5o)+!Q3a4U0jqV6+QnhqU3|Ij{N_hkVg5-dI;bCOzjB+3W-^eo>EQV-0dqIr{; zqELaUtOvXSfd+y@2Tk@RH67L_u3l z#LM$=KNXGQTQ>-WqXCdHl|HOL6VT`Vp?{@E`2Jw2nQ?m*gU!N3|Ie`|#XQ|N{T zNeBKkDOt#am?urwju?_HOvki}c#Hz-{knQFd`z!df?g(EKwc=jPFcBgnz_ZJvoewk z6n>{@^-u7=>V(gmN%bQ)Dz<}oJe~T_*HX1B`yz|aST8_X0bhOTj8C*f1g8IXNY(9~ zraW4_{#)$;+OzxI@@#)Z=Z4~2fbCb}KZGsmD=Gl&eBj^#U@w-bw^y#bq6cCiUi24c zC`SCX;!3uDm&izh9AFNRn`MBjwTF3ib7u$nV~}sti4DTq=k1UJhzmB+ToQS9C~uqI zlOpIdNijMBc*{AM-pe<=YBUu&Li{Nfx>lt7y%##?;KFYcpHbPcMk?P`E>a8WPY;|I zbFkhIuA&JM>?cHI4Qw398Xrz~y1nzr(t3|d&p!;4-~lqhfk<-Tg||XCOmvd+Q!%91 zuh4ml`qlt;{sm zorib8j|p_4E=)vdc==yQ%;s&kX*j8~c|!1JkF&b%rlD zP;LTGb?K>jg@3ZYYJ2<7-p@EUcNbPit#+M$BMe~I4FBKZ@Bb~5Po>6%Q-GBh^C;_c zmr#EU8`xQnEcw=lLn0&+FD*sh2!~LIpu7KNx&5y%#t=NoWIJpPX1e8fS_4<5Y7=H5hP2^>NowF_4XfM@PF>lVwx}gC;bNm z&u0SGXi=Dvad&}$8#+QI)3GRQr~cSr>ksaeaJdlXk>98W!}*Jme(elP02{M{XhDh6 z9CNWi47)mLJkp&P8VT%&1rl}wX%^Ai*Hh6lC!lMrL=mvHMp?qO@|C_BHp zR`GU@x_7azCVUxPZ29I}wmlQbvXl`L2U>=U0^MH?C_xFT8s^^%1{@Xl`S6HXDFv%A zXJhOlNw)74f9JkiC^h?m!45#P2S2t3|LTNC)r<^%nQOSk5{L>A3I7zMyf#$F`LcGybtd|8%!FocMs_o}d5$lOR zlkQ&=X`!P4*jeb6w1KE2X$S@)1}m>|U9$l3q=3NSLK-p+&_(@gw!M}`h?om!tb{xI zR=XW)Jfl_r!)$(a=BxOnht%5DUCyG}HHUP4XIiW*RCLS`>n-@>9|o^QcU3a)Qo<@_ zn7iz_5~=*EI&(uFTnr1;2D~XNXejtKC*Zh6Tacv)7!(}H2I0bU>sXPc$r!MNT4)t@?ggr^_y7UlGf?STuFcshac2;Skn?G`6!e>;z62Z+*)U|C^Ic}=o3wfGSD z)!CZ8TL7~|R_z3zo2+gV{@R8u;U8Q-$`iknWqUYn!>7%;9XgDtx8b6j(E&n(S_R!6 ze+~0rU{ie8VDRDDtHY4);8BL{-B}$&^)*9|S4~}Lx+oB@QDd)~vItG1pze&0pzcHX zrwgV>x9I@vY*rrM7=}3+R%mcEUQl;--Pjv9cKH+tf(Ld4F$%KSHjGsJgaF)2!{oNt ze7yq5phqV|Z+An>Wap4#{Y;Ny>q2B~!m z%hl7NO>{U0(ESuxq~qfT)(|Wrhb-i-xFSF-Mq?DUuUr=QYv8j61!sdIaAAb^U?}~< zfgLF=m9L$!2p&83m2uR=K!UR`SkpBeA`aNuCq_=UnWIs>@R!;go46AF0Fvp-^@;AX zG)&q(r>&j1?zhO5(gm>FYhckYA-xUWDw2*k6tZZ45adO6Ptnc9F~jrO|->uO67pf z`?Enoyt)Vq8^s97m7wtFc2R7*veGsk=lHzk2hBI4llBka&oxvU;KTqnxcX&5EgFBS zl5Xq$od;7Z9_hC?Ysp6tC@-2qT?D+aNVNINi$jgYH(vSsH_(=HVUyzfV^_#6 zboGYKfj}rf*nDbBjhifsxwrjMPBD(@Dq2VIcXmX$#HxqFuhibDnu5sh9UAQUtsD5i zUKJZQ1+67fw`=(cGtl||r|oVoK%aPyh0J~M^X5vY8{JodVl$==qaN37E}(U+oiPjv z0Ug9@ldVLzH}UpO&6zNTTP!|dzER^KJB$Fi{J1{=T=pHNKcLReyU<;zb4!ac21q4p zd22iZR)|la^>T@3-MzttX>xChngL7^v4Au7u1FK{Ny#XGznXic9QVa=SN2SfUcevG zk)oikZ9~a(@5sY+MCbxM(?}H15DC-U0q4$*UEuU0(xgFO3-^KMuzD`|6~E&6Upw-> ze==s-RgXkaCTvSeu?zUP3TV=LeGCU;dZE^S2PC~!^G>C!4Jf#2(OkF^Qzmy%{jU5 zuT#YETD^EZ1Nu-}hN_c7OBy?*diR{2fmj43QZ$!y@Wd2{`4 zMdKjclY5H@OY$PdHkg zk^jyU9b?a!rb`2vT>`e%u=O}xBAKTE3MJb|3fb0P?K?xauun@h9pV;mYKJ8y{CRfw zIxshgQN*GUZ_}7z-b8u4LIUgA1Iavm29o9WT`b|)<9}NCzrn?%#PEiU{A&-pXq`Q} zlcBw$SvlG=OntNvH*gbih1!{CUCsqP-XxU=h_fcp43Z*IPeW%+NtHAHK)8&z0YkLB zL$<0joJ((=)>u}g35eh?ftd}+*HLHLqZ=(*7V1RTd)@r>b!ty-$3kYAzciZ;nchu{ zxF9OTlyv%c8(}QDUApVX(a{@Wmi|i@_Xp}?+<{&y-!T`1eEQ49I2ZwD1_INs9sjPK zk6~TI59_oggf4v_J1RFP-E^gwYVC{~qJ3aM<2K@Ct*i2=+*=`fPrP(0>~+e5t!Cmj z%igqycQxy&=N=C(Uvs(ZcQ*AN%kE~0(a?zM(u}0P-Z`7DP`jt*KaGR6gbzFlwS$gW-`F zmx>c588~T^$dn$Otpr z*-RU~fQC;FafL@XimFbT3&uJ$YA#h_sn#ezz5+3iNcs2PZo_gXd1yU2%;$0G@cH*~ z2{V=2QL{>Hv`kN_J95>umWA#v&Nr)ln-MSigVvJb2iL*pl*a(e7@MYn?xOW_I3@f7i;<5IbOjA+!=(sv84d{qu za-Vj+A`0IzX0wwExT&H9ERw%_p_OTXF}b=yWJ_2V?Q?hRx{uI;xWG;4#)sxrwk9PE zd)b=S=VO&eBa7-?Q3HN2PxLLlZF8d{xbT+Wxr^qs(>Xi7m@lNR1pNbsPvg z;wu{X=SxU~o4zeJWrbxl0Cp|VbLDA-!yM9Gp(B1lIWs+*B}w9zO_0`U*0>l^C<{^S z-7G`GqR<7}kF|m}pUOPsjhp3TgyGHz90ybbWv261!OE1pFzCd3$km|_F^&>xwP4U@`K#G3amq@04yY?(FB1_wJ??>Ucx`GG#6aVO5%6b*|}DOs!&uh-xwgpnD; zSxD1w{Ke~4CEB-4rTxOs&%aBv8T5ZyjrULSel;VbyeO=lA3y(I>)~9W0Si(g5?x;v z5~6&wiXp4t@!s&8#B`Y?e>RoAKdw4n&43OYj9M@=_M1L2aq@?zQ-2SqqCLAc2Q7Q3 z+>B4ggz-7AI9a`p+Abc=a!++Ks70tsZ@$QF-u3*odwP*zZ|Fx$B4-T`>8wZO^>25i z!?&(&U+Og~%Tj2HY?c_wx@`G$5snDEtUW(JxGExtn@=&c)H8P(TzL>tXp3Pqt+u&Z zBF>7xPP`eMNSU?9T@87}*@FMhAIHU0ST%Kgh5{YzV32CGO|^zl9Bc#|Xv&X{hu|3} z@fLK_0CtvlQnk`HG0qvkC?X>1G>+S6CSvY$PDf{)Gn%SUTYC8_#QH;uhgfY&nm@*8 zXwQ26WG)HMakr3{dCQcaauzpt`NNFlRk>aA#fJyzXP7G}e`mU})?kJ7zzmXSP7V#onS>#s?<0dGen;5})ke7%n( z#9P5e@%}nVb*(q_>nlzyc5B)bD}~Pr?Hd_@N;_njPpr)U0(`FLzr=bx$<*(FLm4bmg487K5k^QX9D<|TVU6o0-ec(tF0eVtXG!$mHb zX{Uy!+Fb);?M_tH$4Zlf|ajF@n+aacrzT zBqiDuNJp}wh)Zh9WQV=fWqa1pq%X*!&UY$nTffsvZ-A;S< zev~Jr^wnKj^8~j%`&+f)lV_NOi#%mbUj)QUi<}>PYvWN+mu*}t&rEAMYfNSR2_?D0pb@e@{F;kk!bA!kTr)FM%Tf zY;EuDzwLp`8Ih$JU?fiAiXcg{lDZ!lT7hgdFvrt#-(CybvRR345xOYh4e-jV_eKxB zPsH6m@7-K|-r#<%e-VW~cHg#f?aY_g9Qpb30;;>sI3LzD5G1OJ_3y;o0YXw)$hG?$bt9AI9G_s!_ z8|m0Y_t=cKVnQ>mP=3Ye(eU)WnxpXXE5^|1AT8}n@NW095emEmc2xNC+e`x59CFkb$N+n^ll{1p_O5i1V_PSEs zzUO?oM`=Wg?~7$65BgS5t5>DIoPJ~7nyLJB0-=zpp2gw-3R4 z=?lJ{NKTVaMzF{gws~(cXSbneayA2%*t~AP`?d>g3JE+3a4|3!$T;PahZkh?qch0= z_)0uM*#RA?mTYmJp+$BQo{-f&{Te?g+V;5Ma$iDO8N^-uK@AVYp`?%(Tbi5(PwQ=6 z+FsrSBimECcr(UeEDWYb`FV8@Y@?MTX!QR zAME;%DrMJx7nSJhJUjeU=1Om?0>2JJ)-%|I+x_p12BI_%&p&x_XUt&W;`xM>6f6GU zuot<0&=0d#Ne%>#c#H2t0Cu#9%*f`C`tQx9@W%#`*1^1x6~|_=Ol&~$L_QQ1nPrx) zNjlk>8=G<$_ZS@yFU!AR41Ep)CvA3CnX`8=rkS`^#=e=fw=Bc}u@lE{eFhDtRgKT8 zmSIhz{}7K8LKRC~L5^9nDF?Qs+n+NW_If&DqQ7rl-yrkr=#^82l)|Zz!hY%6M&uD#&zbK zz4hXlq0Ty>1g`vM9?0#}kTSdQQCs6i6#E8xMii#9l;kH38zDQE(3ImnGW z&7q={Zd9!PAfz?#mY#$NwtVsooXPp^)FpaDg1x`l?77l-*x5aBeAVOk`a}FP<(r)u zt%BJ+T;Qw>i+=4N4DP~;3AOW|MIBinkxn*oIHJb!TNjKJ0UfBOXM>SEQIHEivettP zZh;hQF4$*#RT|Rw)mKL0r&vxNgtSHh*m<~?SWj)+cFLHwX`Op>GAe;!c64{a_7RUO z-JSIOn*pBLb9{LlXG2~f_@Zu;HzZD+X=31w=3L$4ZW!--EX1&`%!1VmPVdx~quIQE zJ2uxR0ePbr+YppydqdXf{<2NKL*2(e4^9-mtGr%POCP7^Ic@&x$n&t$hV7xmioVnK zI_Xy9NAr(qb;>x|(aG`h; z3$8E`V2==(mtyqpItSw@&r-S=>Fd?APeI;v3O7Kyr=80`-5lC63gA-1;;@wCGr@Ey z0iT5QtX^dVy>6re@PuZKGq8HW*mwhQ?v=2fbbz;BWW4=b%I#aew-@Dka{gtSZT`2T z3gP5_CAWiXS6q|1J3u zCCL@0S}pOpzqhv5n?p<(ebv)0E6ERsQu`5K%T=shg~9;3R4^Z^I4ZU6<9MA&d=zbx zITG`WT^Tui&luHzcbCV{s}WASt_^4WLN9JzC)f48O2*;K5_)^(@;AJVzqmADL_!lD zSjiFcXK1|~FJ-A#Er_u9{mMKYjYSuu^wu8i^GQ&GMLlq4IYL?U@0WZ>-^aWqczpeP zb%1fld@t*jFd_;yQXly6N`4R z6sVSqN`RKQVs>TC@9K=Jr6XMHsmgkon>nGbIH~(dKTrj?4hkI?becOa3HdQ^OJ=+f za1h8vX|2OK@ z|K=dzfBoB3ET={LUb(b=@q(uU^(q$7{y>$E1|G0^w2B~mjHIcVgb5D5nVbUd{anh^R zpqGKz=&c#%PW4`kOip?A%*1C^Fm0o=E(h$+cC9u!L3qd7QlYSE54p`+7Njo=t)M`O zciY*z8!o;{%hew}*#dyMHs`RxbH(1azq>*9t&eZ?rVmujo*y=B_LIW3wXfsWn%f+;nVaQabi#jt9%R`b zP?31qz*Ez(9!=k^CvT1pX^lfBcAvL*FxqD5Q_7nk=iRJzgLUI?V+PJs>dXpi^L6d3 z6&sUsY(xbxTMjkti$;3Fv*BGOj6w^f%~AX3&-$rrx|4@Fd#KA>e7{%KxPI(qj=sE9 z1Gztatm9xkr4`qqDll+^KdmM%=~aNU%hBTsq({%%hbd=q{WC7{HMXw~Sm9%;ztVEj zpe|pRgU(2vVWW0Nf4(%0|5&3i%C*!NzODKE;$m$W`;~Dno4SruIgXQxn>Q%Q;jT6t zKxe@E#E@+3;Rb86ZClKPGs5=YQ98el;tlU-U4QiOwXRo$qjT&SeyD4HKO9o}qjC9Z zUZjlJ5`42d^$5OAe_Q#AVOmqPb~gSeTiZb5zIW}CiIjiO)5`#MHkZlmg&k4K{tM%w zciG~Nyl_j5!HO2A+nI1bqYu9ip23Le23G5rXs z2*#w(kVS>!C+4u~Jz6DHa$EHMqRu}k(|oWWO33G2Qd2_A#_+W$S^>s$fwa2S-xAf2 zRBe8t+xXs&4+E^}vx6Z`EQ+`ra8bud^)zkj%v z>sVcR)lTJf7rTl$2;{D;W6JV-TX!UA7t1SDf%d+c(oz>mS!)56~M0Y@APbPpE}ypU^_Nv9S8!?Ca&XNDoyr3 z&!p4Te|;vobFA6arxiq_EVS0E;rsO@%yIAmQ{Eo3=z~?2Ky$7Oo!)e(DBNvPw zJRcj}I~{haS|lTElE>S4*m1Ja+-7uhdg_{y@sH;0Ga(PVZ+|M>>qHqpyzww+|DmAR zl-r<(1dG+#)mr>B;M~#5>RP(I!@^UmD{)4bB5=w257zdi8IDxoR}b*TF5&N=WlCd& zr&?c3GCO&7Xx80!x@jLR%AZ-5QF9afaC+IuFq}W*j&L3Qul>)f^0o1c88rik)7wkW z1H{KwLl$_p@8AridE=)!d*6T8pXzV-$giuY?tf_d(f5;bj&W(~2qU64rO>m41@~~n zd_V#u!bI}Nrlkmt9E^sj7;>g+G&ny?y#r|%kw z(9&uG+@5`dkxyPMWvh{MTO4b zgkgWC=nsO@T+=>`-G`uWPy(61{hRJPTbcfK+&pM6;- zM%veI)j6`G+&y)C;*=oP9@|=+*7p=7c*ZlJgs&*4J1qHiQmHh|dd#C51NNp;+e8L> z8qAxD(lfX+?)2LRaC*y(oiEo4PpB$i+K*I1@e?7>stB3IYiyjCF2Y>y!%;tPI}d&G zwpM8cu=8HB7D#>;@U8Hqj>MUsvA$md?$|-{kyBjp=}z*`LiUQ-8+Ej*L|8seh$BqL zz30y@zg~UT_i9vFhTcgsX9q?&t@>0Yg`w|bjKu4mwzpx+(#fIw62x?`FJ>W8zf9)E zKZ#3tUraiWI_tA}>h5mX9mm~>H^R(LhKSlk|F%S-7*$eS*MPzbxr_pFQ5HS+3KA>J4oEa6U6nWw@PfygWFzdiiJJXsd(cz>L<{+-RAxZyd(8+oGkJ zK_NLTir>c53rI)qhOPS{@(+P?KM~R_rJvdTOt15q*$2JX^lCF7r=IwP)wEp`)H|17 zcFVDQ`nTkAkXS2Jx_^C2hVR0BalF2+Q%sBGd3pnMc1(Bf%p5-sB%PNA>cXX9l^ze! zyint8c~TuS^Nqtn!cB+X5pqgT*3)x4UGxhtgYeuTfgp<>4$EHJ%&*g#xf}idky}jr z<2VNSLB!5AC*{pvWU!mb^^@s$Ay5UA*CYXIas*&)s_5&dtqS7@2ZcP&hVlo9_bO6t*>qjDB71sfqZB*5uVE z@m`}ccD}cqr%cB6-b1)+rkd`^DjoO|mOqn_8!#~08%)k|*#Cas^!LLfj4nH%wAVF`%Xs5=^UgKR8_my{+W3E zSdDmexM0`w7srT|J{KtugoW9dZzWKYjoio3`&eCF*Scm(Os;B@BW-r}ElJu4R}a40 zfod0d>aE3}AC(JXcru^%N?&%~S?ife{!&XRz)ookpgj^d292y1@B_PYpb z?n;d5$C8u|AzrVAln%U&9;VDwPy%IJV{>54q`gt+BoF^gOquA0xNCXfIEfr!A}qjx z(h{uV)v%*@lA*yk@Y!sP$$UH&9?6jJQ4^PH1xV#Ju=B0SeNdw}^+Gv|uufQW~ON6|53=YPiOh^~9E@I2w7s zkLXdu>vIlT3-+Tzr{3`X=iRzIq;`)Hw6yHp*wSYHnh{YoM4r~fGN{ds{X?w^>*9c3 z&~nRLZn47x8hpEgZt-jIEd+td?W=If`LL>Br0CG*MW~^T>o`_~UO^kJkqN<5Kx?Dn#DjLjIS$(bS z21)(G5bxI**F$+*!T*}EByOv^-{j!<+!Ij}mxVjLdY#57PJ0^ndG2Gzj-!X;*$TK( zDAQyACXg$R_Ox}jI0lJby!OA>yLyCp%Ch1RaD}W5|A+tn`X7FQ>i(NwddcAi#n@`K z2+(_z(n%xM`Dd-g49yD`3^OdgHn&e~5NEt9LKao3zKR4YYUT*0 z8X&!C6E}yIP>^)bJuUAfZ-8uxX3KG{Iy3L_QvrY?+59qF{Ou~!XiY%1Uv)gbNjE9a zLcj-)2Sx4MU^Nv&Qsw=doPIGLqbCItpPAcmZk{R~+aS&cSCoJ7#01Kx4kU-FW7y4+--# zO-c(M8}?NIT2izu;dw^U*ZgX<*{vu|__Jq%Iwd^vh3p|jbON!Vk)Y?2_(siKUy=gW z<0)8OrW8{_IMeF^j|X}v#71snsLl~k-QJI7a%$drvOEIo5U~}I#RvB#2$lTGfoj(8 zv|ddT55DjHjIO}kx5cU~0OKT5ibB}n`(H}Tl>_3htX)AcT$OToU z&5xlIk0PH^OToIG0(L~4lhw4seo4}PrI!fFn#0M>3nb#QuZo0F;d<_E-F9PdsVty0 zUd`6qA+gicG1W*-yW@`7o~u8uWkTZr?a!0OJl-G?oF(bn^R_`Q0>wjmlhczJii zCs`POeDWdf@ut7g?iY`}i1yt-pUZ#?T%SZITytO6+{qa*Q@vz}^Nh@ts&pBH;mxol z2hVFz>s@id#C3*I(88A>eU+(Dsu>~B!#OZBjDi5|G0)7_Tf}e{G&Q@HEufk~!w}*0 z0w(mH@zCkCL!MJ8xU=!Jh5#dkRGWY<5LdY;Jm?3Lbp;YT?UxXhNJ@PF%oZzD7i?N} z;|lD=(>)iaNI%00HIbkjS_so4Vse!?N^|czKU`*13?;)9DDaByj>0Q2AOO?2VZO|s zq2JtBs}&{eOc^qwm*14huS(nQNzr6ap%#EM(#F+RF^uwZ%MzY%w4Gunr2a&c$*m7w z%-x^_FG-+gocys5?BHY71%W8h20V4`HXRgC;q$iz@?>z!p z6T;rcMVPqAf0q26?1scHQ~%$KXAlU2kVivx8)pCMzXN{!!!xgY{>?M%lz%i{M?uV( z#MYL>Nv?xF-sv><3MH}LYsi)N)6s-G3G}i3e(leD5Z@z_;sm%UD58ifW)TDXm;08S ze!JyuJ{<|$_A?#`!-V`ISxq9~+?)44S@bu~Evv;{&tQif8DXW&C0_!3`f#$F%IE1b zI7dxC22Hbd{oL6-s)o|kO7onqPUZ~V_mc&l;{Z6(j`fjoDHFpP^j zKS^+)dmHQ41XS;pZl$P$5uI8Qoo^M$R>t8xHs&K^mo|HRRZyEgYz0i_2 zn#k!!6~WZ?z5JO(ST$70qDr@zV0nkW+QRw93-exo%~Bz$=c#&;y}5TA{|C*>`BQ>w zBYA?~keGS-kty1ipSSCAYzZHORqLz-9Ff==XAQU$iM5OhZYVi@HUgL|oGsce9l^{3 z-adHkceAt;V&j${Qwzg;T2F9!D<`1LIqlNH3t=-24p;FH%@e*IVL~l$JmO43EPY8B zECMAK48&y%p9Y<|1uXqD#n+R|5ZYOg(kG$Eo9%CBtELr1en3IL zvr1>ekl2aoPh>uZ2#D96Y9lJg+jFtj0Jhx2-t$JlI2sI#Z&S$hGNpN>UCb0=!*MJ- zF&92;*yTpVt8f1*u&cu*V*0a1kyL##+f~5Phjjz=v7=*{lW-prJJ3_+7b(MK>E-gu+KfTg z#L6*{Gb@#w|6xD#$=Y7&?s*ADya?^i`&%ezdF4TTb~o(~{**Rg4nvh>9btv;jS=2p z+g@%5j(T(xHoO(y&<|;huUhAzogi%ZX2sSJ^YeASGp0N(Bu)i0rK=4Vpr~93v84jL zH0gz-b;hHW`V9OwDVajh8oArjn%1`yrr6!%PY{IPmn+0#VA6%XTk?y-4aMf*R``U? zGhm46Nd=#VajVA;{_$r>>YpUgKBv02be4+QahQ-|U`%V^kg?|5vMF#C%7`Vaa$VpJ3r1Xg1EjI$`45v0&~Vq2G)< zAY!|prs9|}hkL?wXk87iW-IV@s9#v~^Z^DiRn{Ypv|C76bFhZOhl{5_AhCO3gH{wQL$?e03I-}tY(e~?a7#t_vuC!8V~0?5t`dw5X%NO<1y&Gt@tW+@d1;|Y zRVKx;KH_LA$!q59r#BZ4Hbm?fgQf(X$=zS&`v}qLt$)loA1x@0_Zkoqp>4 zqe&7BAM)7j2q2p(> zaJ0OCaZdh<_Nxvq zIJzjb)~`hzX`cBh=B|Q0m0iojI7j_DPJK1nDJ;z6V%YH=vM#p;n@Ds6@c$6Ek2grZ_laf zd&ul~02}ug`O4ZmW}eGUmu{@)2(8|H6kDsyP1W7*dcbzhIhuH2g(iiB@SfpjGvi5_ z8bXyDg$(S#EJJ2>oITgroY{p>k0*XJUz$@2#DBWaSlS<}qi`3eZ|!xXy_SjQ-}$UF z;ZY|y^sQ4jVh65*RS_U+Qt?!w{7S|tNj3Oe^ zZbc7F?uYn%^$P{pS1{giZ`ztRA`K`i;o$XRL$eWgdKvU?Hf6fcBr98Cp<+r4Yfj8e zYQ|dOD!_DV_xWyD1bS?LdW)4r*i8k?Kw8%wOE`*i$Jg~s)>Np0zoc;6hvm?p$Pqy% zn49DVery7>g%v*m6`rkfTwABz(*!}|V_2ST<5vwy&aTQZ&1}srG!24sC!Fmkg3TGj zICwiWFYzG5(19(FNexGk;8*w;Q#|`e6@PYqQHl;!^@_)l!>|Nx+WBvQz;qsRkN)g5 z7Z~?QVjh5S_za7NN^`vp4zHG7@;$r2^6SrzSRNbFP_w^z^1!bnf-I2idRGgMU8U-c!YzG?|yTd%1&&2i>OHzAZ#{cf`kg=OVR zAh$v6pF~=u$RA7&wZ!B4QoAqQQJ6&Mp_#4D&Xm0WHVsd27_OC=%kt-Kqi#m-$3Z_x zmSlWYXFVtyS~0e5$B3(KN$Z~e=2L!k3Jt7INl$7%8J9S$s?EZUdlp86FTuMOgpoh+ zg)lk1?>E&WwB8CR2f+UO6ID-TCgBNgr%RaA4L9yBHiWL+Cs_oyd8LH( z05ty3gysL+U#RIJv7^;f{>8q50!N|!^MPms6^I>}Bgi7O*1gU9~HtXU?;y5)*Hk})78mJTZoz2ExIdCQf8 z;-1`zet)ky4pVyRu7>;p423xRlu5p;XCFtdkB>|_;fqWw`|zar{<}9u7h$-6G+b!@ z)XM&I?qIa&-@ML*td*TG5KqQ+j(Quuba}^pLbp)n&6PUnU)|_#2Gg*ZQ3cm(o{;Es zR=qo6JQ21(y(pI|);GQQS}opX@G}@OLpxrZu5nu1I;}i^A!bE*Z14=cdRLh4QX-(9A*b+E#{=qsz{ODL|M7E}f^L^#7#^7@P({tsx*J5MeWMB!)ZRyYbSvZa!`h_2M zK7CxUzE}z51cprn{LvDjtzMyMr2QDi)Z|!#{s|Cj3qQEvee^MLOPj7>AE;BGc3W3? zm8W%Ycx}x8)grji1C}92JPuO$oT$z-7F9lhwZ*!TyRd>!xaG7=EQqr^;ywI{@Mb(G z2lF-luUJ%q961r<1C2+*^~PD~2_c)=nRy>W;>3h%-Y^qgA+gJ%=t!Ebi=(-K^oOU&X)rGobV28Dh;&)| zMa>q?!#|-@3k)}hb=rqv+HSz3)lc;(VC;4~DS%tcafXo!&uru>XWLACijBhdu#IG4 zT^lCZuat&dpP8m7_~sj{_cqMokftj{`;}GBgFf-fmI#=^vCuik^{#}+LXPo8>p`YB z2<=Q~|MoExM*x%PyY8K^08Q2;6z;?ufAf!4$O&jtp7%ZYB(>qeL%^c9KFa(~mxCT$ zb${}GB5Moe~^+vAK zLvUw#pC(RdpWr6`8uU-iefiUrGp>#W5n4JNSW{$r!xMH-6LfYi^WlQeL^o4qWr5T5 z>HA6*xJr58+Fi@BdrvXD2Fcha@kq)2-1Fy-rZ+t^BQ7g}_Er;W^r?AqN%?pgYl5*p zyZ1iSYZg0TB|{Q{96ldEzv(|dFyq&b!7`oJD$X=A+)wJk_N%ru5YE#8nIV2@+EWuS z`=*R4_<@;-ht-_d%FhJy?vp)@1EP~1G7ifAObquP}zA-2@c&b{3i@_0-xgh3CR1)yu$Vw{^Ws) z;hkl~oac}^umbr;IswGoWC|xP>_u|*iwYEgQGIdDk5$5LL2V(}UJN=~uL6V)9edF| zB2?7h=02LEhA8j~P4EM{!Z3YRGTv?^(?gcW-ujiHC(skLjc^_mXr7i!Up~EL3)0Ea z80G5&Q(=nZ(^q*o7H2=Icv%+XcaDP|tJiZM^L>$nh!_B8RN?~YSww6$i&PSJ3^SMF zbEP@Tq2xZsSeKcyTXs#`FnC*otm;~f`e)}Ou>+T$Bjosz72ZN2o#zyYDJo>@HcTJL zQd+*Unj$sAaC{xAZ-o8Lw4@EL4_SKbTho*3@Gb1_iLz=bqYr`qC(JqjCfF!b5k_yD z#?};E+ejYvXkd$(q1~(-_W%oD=UG%m zQLifF@QO>slS-;SOud=Z$g88^8^W%0JuNNy?_0yOq2Y%ICCs#mrW^awx3c-lQAG?r zt8`YZ&f-Yy!Y}{7ew+SlFWR%5s-1hpPjdNlee%GB&Kv@xn4=rYZ-Yv%H=>bKUXABo z#KRjd@lR6_mk)fV6yT<~sOJk0PBibr7I;D+d@_Gx50O8yhvJw2h&}$%#U{TD`?t+P z$l=DdT~RX3-n8$Z-O%OMsP^ci1#PvZlgFv5g{A}!ZF!QGan>0JS%GiJm%sU_H!G;E zEc1PhV6U_}=FA8@ytb3bu(~v>R_0x+c%tO7^3V`aXAK@_jv7-@K7~a&16dx2?$-6> zm#vt9q4F}XgK{$6pZtOnm__+kS3UIMNQ9mSQ1a|s%+v^jAn&pfCz(Ylv&eHN+rV}G z>Z&vN0-z|M+-HB5@uE|a^%v*GFQW@*Z1C5`=Cu#%&2_V9bW<0O#$^+)1SWHOti!k( z%t0uskr7L_1YYasfe%5hX`S`1ulC}s$=e4nztE3mtThXbKySB&WrYu>+0S_0TIRYL zb6;&#_KSWNw8T$|4OhZ`W)~b1h>Nne$8OD+$K-%Gsh4|`0PnUNai73v1?3V868j}i zs%29?;or2|)IyuxeCibv|8?I}w>XC+QUQsbyt|BPRT2do7BHQS8M}wADR;7oizcrW z;Dkd*5JI$3qYp9rC6W(G#e7k0TO-m-+V`=De18e|oeBc5Vei1sr7!>=vQ#O;aX{^o zaZ65xM-48^qt;W>3ycyA(gFIERodyf-cP^toY)*^igVb|ynErK;52(RLZ5ky)Pu-n zhIEToaxt)atav(!eLK7<-buoU0^BwUs5Efl_A9ll1ohjI{d^O$u-LIQrt9;Q}w@;$Cu3H7}Hc60E_f|MM3;_-doZz#(cKfwC zwx=rx1<&=rr$RR;bon^7RedP?idJxWLVQB9NG=A0$!IRSmaYV6HJ4UGbc?vhk>^g` znuAbCJN%w%T#SKS(j3)7>cB3C@Oa)jV1qTOl;gx0lmjO3qdslmyP!{5vzJ&pTMz>y z_dy3>9c_${u8cP8dOY2xaJ#R3r8D95?FJikuD_HWN5}TQn^9-+w@g>0m>&+qrQgLB zTSq7CMu-5e>;0puW1F{#`&^M@e|r;>rp;UCxRK&wUMuZYh5V9Q#%N+BsdTFX4FR2hn%f zs_u}f$oRa6pC}l7tb~**HimVtBbe1Yu z6lyO>eMN48DMP|?6{aB)^9ZBfS?|^3WHx`sG8Ji9b`qF!z0h=lq&r(%z^$VzcS@msSpCboU1e18>`3zV;ve>fTJ~ z5_&JX7nXea9bs&E<@T)9=)DFKJ3V-kEa;9yLj0wQUm72>HPxfPOtBq57}aoJZ9Ycj zWUp?Kb^(5*dRMG62hX$4Wf8o4f=-%q*R&P>4(UMqgaXvI*Lcy(BtCC-SA9xeH3@ zt(H%OCc8Dhcek)rO?YmT?gL{l>GRf~xV_Z9D0RerW8!+|+D8m_@DV&=Zo47VA4u$S z@&9Fx{I5AG|L4CYe9aS!_7Fg!@s{zSEpGAdI=nb}|F)LV*#fa38@hBI=9gM`X@ruU zgkUfF+dsqjH}?1^hf2u-{x?U$DB!Bhj$hm2@*Q%nQrq`{)N~O27zP=Y)acY_$1wu1l79iqFIareKwXDHRt{on3L2a`{{4TdTr(ioj zFKXhEiBo3sV676wCI-??`Gqi%y=L2UHZYx~{$Ba>RKR2V*L6s6R;caMo%$sjYQ^=n zwR^({m9d-$-m97e+it56T*+s*0OYw7zxpxWQY#P#urhhn!=XDk-Awy7fK2hWX0>4T zLf}9l>T*`IEm^(P>ZY*r=zO2@st=DWou)z#Tivm_zW7c>DqoGM zG9o~caEq7?`)|z@un-wytZ8^b-}6!VUTcw*R8drjyogP9KL>invO_U)BC@Ywa?ZA& zcQg&7(S-H){x4|d4gv?`Bg+9jW7Lc7E_7zmmrnf*BGt{5(}$Q+7DUm9`V4B*4BnAv zy&Pv3xgx)Dor^n;z_jF2IO-JnZ|G5ZNYo9u2#KPR*hyH=64odpDToe11)Z7L(d&;h zENJ@HrivpUvBwUR1-Cf?Q)#bWq)O2FqmVg0xx*nC=+VZapo(}eu!j+84U9zOl40PB zwl|{*Quu2W=f5O;k2kh{>kWJD!MtgK9Ld?ae#}hThwE9HgNBf?&3~8N^CQmUWpd9a z{{qp$-*xrTf5M#)4^*?=M?xz2x)zh~7S+(YrloN^ZbNN7Pu=yQggQ*rXMr4wnkU4tVQm)UyeFQV&uVmt1==xhKBpr3yt>V0~s%& zC}m0H0uCi|K*>(2P~2v!X%8I9Us9=6JD}Iwbm8^0)crKkmu*Z#C%L{;D##~#2O{Z4 z#Zk)`xXvK1%*aAEgh=cp506#k3hx-qy|aJEWjab#G=RSEd4@H^T%yNtiib_+Lf`D> zE);?1uhsBvKvj%vnaIy;gxu%~9U!ul8<8`z82j|#toXF2gC@-qY#Cru;$|c zIg!m4avtR(_y~c%CLh}7&{AU(ZhdWGTg$U{ELXW>ZBlah5GIIQnxXJw= zpG{>jA`pjUps>`*Kji`*6~lHt?Vm-$?`~HZQna-(ghQ-|D5FsZrU*g4@8sTJ8Q7GjDf+7qnUGRR6Jj zalx+X#QDk+S^r15T4`z@v}rEDE37X=7HKaZiKBsfB7VTR(DqoS?d)}jRV+n*z)|QkQx`}fz!aw0z{FxD=tS8)Ro)$*k7TZKFEjd}j zlV!n_uk+Y)HHO6;lH#q$Q+kkl*o2|nkJ!J7;~$I+I=*>d2a zR(J?X*X=GzO)s+Z`iN2IBmlWtWMUm!l!y0_xpP|U=}uf&i%%;ElEVtIU%5JP2b-d8 z#XF$Mg6u%Jg6{3tP}Wi4J^pL2uVloI6I;h93v|y^1y|Aliw(I0VU~dDOHi((JEPOw z(_--?Z+qH@MOx6Gx;B*(3sVzi*f~TY@B@W*fDIYMl1wCZ*G*~y2BYOySkyJNu@rIs zAY(l7Kus`O@@Blu*@1LZ%WvPpXPge0RHgcE3j68#)*4bS7Yb5CX%Y;`oS62*XYQjh z;5L%l^Z)!w{T$Fw*wYLaKtwsu7~QIS!6PvHVqqL;fYqt6qz!>L6?J&owWLpuJ*VgF zC5iVC7;TIu#6B|25K_Td^IRXCGIcD!#O1RX@ZqO%`nLqu&k7@rmwkjS? zcCl3#0Y<&zy2vJgAO3*0jVZ$G7$T@b#B=b=I-BEF0&x1sN0}o9Zv8_0FpYKIE7K_p z$86gQOdg9f4EJ!w5i!ukW6)e~M#d!3%VquM%PmbEe|uLVkP6BU5NLY!Y)hO&uHv2! zlWfu1!%2DJWb9R6X2sL6zqa}} z|Bf#6kBu73|Jz2_Dd75_a6gDMN(2sSJxv6fr2@_3kBxVLR)FyWWBNqPf_>%|>94I8 zV5x2Hf`=~FeeiGBa^|pOfJ4X44TS}3alzW;Q9EyUSvRh9S&~D_(k3e3Wyt1fh)%`^ zUYKR6U&sD;gBi_LX41x6(ktfGn}Z_j>Ny?j6r-B?8L5e#S{!@cj-FVqBDK)RS7FV% zviIO$0~zy9174O1?~vzCJ3k)t!lN!|tg2`s4t!17ZF|Vk=-Oacp^PaRat<6l!;}Ir z7Fb6TDuscExf#WKMxjofJA7-k+KWXx4GaaQ9{U1yPHZDXi!y2XLpa5sW6Y%R!~N}g zHTy1@i;4lAq_WPgH;E}ZVZ)!H10jjcj}0vdgu^apwt62vgRM}BTKE_e(TNna;AFp) zocB*M(!dJ!(GiC>-|;NN3W-+nA?*DleWo@zm{c$1uVXi2j<0&zQQb{#kl5)+ew-T` zNXET>+OuY)th-L&4yL9-@8#BzhWM+-di z48%(CJZX~1@nwJqhV!lOXH$+6(}GaK5tF?m1L$61?kM#bG3Ybguad~$+Jhg2=jm`_ z-ZJ0`LDK6U2&P&RisQ~kdBe4^i3CZJ*y)u{vSZD77FkjVqF7K&!Y2qmsAzMw;R=#- zio|^;C0kzN?D>)M=VO;-((rnEi^E0(eK+%!m-^1V(rh|-xv*${YA>oHg1ra0{;3g`TtK@&R9!zo4Y`+yG&pfDx zg~Tpr{J*i)|8rkFO$8B*c#w3sR@SpE<^1txED@?BmfMM_~W--Op8g zg8T2Oe{A(XHH+{l|EV5O+5DYh-%$S}?%?@`U6^p_OSC3^#51(hpRU*uKXT8u{R((> z;y%bRnm(DD=aV*Fpyonfci4rA5N$I-$40zuE~v9xC>iGAo{q#8DY(6HUqg9GrQe6&$vVlz z6p{ur$}Mpi=l;P;a^3J7&%2H8|<;Wkh9=b(qpZ6S8CwPQY8!V%jIg46YJyw>pV`9b{-QHgsDiLMzuM_|aD8k(pm|QfgI4*+!m~e#6QR(JV{< zg3hqF+$Kf#&esvdu;-{8qY1V-@|}oOfY`i*{Puek2ZDOa{MHX(J^Zp*d99% z5VL$v^kFZJf413n^7~akGz!QK5ngw{c>dZjQoPP3P-A5zI?rRY9pgj^gUZr~S25$G zZ<+BL6-ra1UN#FO(-C&mf#2&m0POLXC`uY97$4{7rW!j2s_-qS5So;rFafKf-##v6N7Z(XX8oQXpC=hCu( z1d)nSY0cHFgz0GYeWIT9Bv`6+`*bHdMxtf_3Xsc=Z;uTA#Y2&p#y$|DWU{@YOnZot zM1wu`tc}q(QUpQ|lb`0j>3KnDH!}}Xl?+xt)^>r`%CIz$xw1Xvgw7n=y+NbU!pE9+ z9qgQ;spX21&GKy~moRHPWq*l-n^#AO49TBqCFY!Jr+~c zICJbbHG91F`4rNmy*z^#p8{Sm`YCSFqn6=^gAy&x6F7R90F|Yj$=Gd-m=s37F@f72 zOp6s{8p>>~TU&Im=H4kTDLqj#AEWVLGF0J|mkmeCaWUV>xqX*3v<2epVQ(3*2g-lz zc#g$tpf(|Wa@s@s*OXa6qDXejOba3)93x1pUzZXm!BSVOAIIk&5O!9X7ghNAB1E3;dn1rs^8^MMl@`yFZv6lQvuOi5P=ACI)DxM<`KJ>lsUN|#s zu|lvl-s}<@l_xz@FUoGY1xL7rKK^O)DtDLR!J6^Uec^?`{~?pLA zMx*Bm6%G^nXrrKCwVHa?GC#=YDQp71Y&JaA)rPtT8bLF^hkJmEV6OP_~P-#jQxQ;f85~UJ7=HIjW2lo5a0;qu*L+~bQ%LW>QO9dcx9gVG^$`H2~|Cqo6l#ol|6`V5imWN*7u~B2|MnIvlp^I5|vUq zSm_Dsb1J(+NkVo5nYnsm^uL#nt#=(+6v=E3Vk3wL+4NDX^D$NBPxH3B@~o#Z^NgyK z?Jx3Qb6lx?k*^Z1l~+fZfV{69Qx)^6e<2-l)!V|t^~5GDDBhJIYE+3BolUZSbpB~R zhLFRQ9O~LT)w?-&1-dXBm z;ggkE65!2Pvl6?|6Ex>&CepjGAlECwCM0&MaRDtVHQ#HvPp7-vJ!*)$0_Tgaf}7VB ziU3mH>QgTZvLw{r$uwgWoJu)sy4{y3ZXSpE6^fjkUSjBt*T_)mHH)hgX@<(V(c>kb zv2gJeB=AgUUEGDV1_HrkHGY5B8S*uvs z$Y1h;t^Xk}?0@1Y(#Qd>WCI+Qq6Fb#ajVn804RVasXA zl_!oR5GBp}#6^~wV5lGllHr=!AdC9i2lge5ZoDMMV%bkdr|Q$5T=35=Q-9G01w(V; z^{nu@@VM8L4C&?%4~y8IOd@PpEL@7_F5Gj9;HM_>gY3f0DD?$uerED2XN*X}kBew- z0vWEgH>Y7WepX@katw<*o_4xC`2u(bBIZ|#!Cw4G>@>xcR`W65OcujzsUkqAIp30n zq7BRM`=}7jW}jk{0zUJV5}vld%+A<*hrC9`FU@2zu@oVTMtU3+2}-4UdkN2e(r>pr zlIPU$CG6DZRml2SbnNeg2BbWwhuBYM@zI{Y?#Kax6|0wKUn6Ud%6&wM%FBsJ5;H7phj7 zq7(jx_{yiLLj^RdbTnXHAsIezZN5)k-LuLdv7rwlZ~CL3q#N^@>7P%0sWu(Bqj)Pd zpWhfq&I}EU(l?lKWkUt^{<$8^HrRi-s=1ng1-H0C-7JrjB54ryrNeBMo|~28nSgyq z++!aD)Gr&HGa@fZbc#`8-7L$OI@wK3vzvW+N!>-qjV(8Ljb9?M(?KJFqbWuhg42yA zp^C2!b4@-@n!M$%qN&1}>AF$DP~oV^Yp zxr-z?8BHjZd%z2CoB&Qdzi2(GDG!R!#xpP^YKoQz?j!E++Foy$W~K{%u8&k^xhI;^ zqeWRVxo6JDk7MF}$G2e?8TS}km5H0cWgr*gK(i`Pb|JaIa4xzG#DuP5=@+eGvUCSnfaE!i-9WawCzO*}=v?JP^K@E5$|_r)1n~M|oi2J)Qzi2x;kCO-GpLhHQ**wUi>3w^lDr>sjA_6;^K43ATB z@vL&`s1NiKSVd$J#9M8gG$WVAGS1OdGO8s4GW&;?UTrlLz`E_0$B_^U)${ce`wYI&FU*iYYW8zc*7QBYwqX!YtA$ z?85bStw2;IxuPOcC9>oaw1Kx%Z`H(OkiSvY^qnulH3SaV!<-|#HYwbZ@Bg}YkOFfX{6AkreGS)w!RXe2Vv!)6Gj~HOGSmTsjE1OvS$Vhokk3yabDngMQ-WmlAv8Zf*MmmhNb3`=*&Dv_UE!=1N5dB3viLNeKjB4r4%&*hybt zVVKA|wMidSVfjyhJTM@@NL;NmA0}M1b-J_7G8ih(OA+XtVz~dMiJZEbi zFMk&cq@A{Q8M%bjzi}eH^3qd+;Fwj8ruR_ahrtj&I5$695&NeeZ@WuL5*@Awoir`( zHeg0UzrCmccYC*OpJ#3*laFLe!?2&SNFuR|X8qshnSW8vfBnnVo*%%9dRcSRVY!Uu zwP-S?dDJd9_i7(__tU2VhJOPvb7Cdf1VS~M~8 zK#g+u)1q6Pxnx?GYXCCMQC)EeSDMH~=r4UFY7Php5KO=14+wQq{P8sohrqWC<55qQ zwD*HRwai?LKmy;l-x53a#`kI-FD6|wthLsDWMJlvAT~UHqO#g-kuw`51DCgQa*c#| z>Ns|Etck3rSjg~ztZZwWx<8y7EOiQNtz?e%++^{b(<%*cn@L>itbNWzJZZgH)-Sk} z+lSH~NeAbI^-*YUwSa+0?36h(SZ+NvxdQLbwJG;nJf37C00E8PfVevx;GG+qlv0K% z_Mo$V9qb_z%@x*Qpw(&l+{dc4!BMRl9OYp%$eX>@(?Wi9CddKOz|u zi&p2ilo(?$Ub3h#K$+-y?zUL$<>*+{c$tL4+<)QvqT^+%6`YLMny zJTKjY#sWtVRLF{ELqpq#vdH0d$6L=WdP-$bgFpDPSBJlBd&?)rgP&T3*Jug4<)^lx z4yWpbGF?`FnID{a!7h zv{;>600u7n@D1wK3Tl!tMqbL&(D8_M91=UVywtsf_p(>SfJS2I3%*|wMpG%O(-g5{ zwge$mxe-FjTwV+#OCdYi$FKw$`4L?m!WH?UAD!2CQ3(iu!OUrSLRY2XAX!u_T%B0a z8;z(Ay4b7aiK*B~`|Q*@*v9-9{c~Cm6HMIo!96VY_GNS5&l@$72aL&Y-F)&yaGOy$ zQQ>JKP^vtX%5V+^ud796*fNvpkwSrNW3f1-I@qmL5M5!Q0Zd0OvMtNP@IwhE1_iX5 zq0KoXvD0XP6pUO7sN6lLheGR=^#o}5*x7vnj=gO41t{iyy5SpCOqMGB2WU0AbF<-v zwaEde5tk_Y@S&tKGcqNN?}He540FQ#Sf;A2|q$P*PL_rGm0#( z55(BPnTVORCE{@*e9u0C;M*AqCN=4L3prhj@n{ZDh1-^$aOB9x68N(}hYVJqxrBO| zr^v3=VgqDnU_RJ5IMcxWy6MP*x-Fev9gGnRNPJWCgc=e%?IAdb9fU!TA{mC~LYSdo zoZsS5?YnHAtW#dJmi&t;`b-P$f`Cka9F4Fya5O914+kJepk^*A8;+u+gx1}c&?>y- zzgiqmZH2-t%e^v#(91LYNGHzTiC5i? z97`e`HTHn1|Irr}49RqQ{pL3P9jah%g0L+&Yzz{CemDxA5gb5LzeYaOJTz9Gy%eoJ zk|F~GF6^mXUM*oeAhFA!I2#)KH#K)HrO~||rhYHOCo!wh$0hIxoI=iE)WV>y#@G=< zhS;)+bEH92^5zMZBX}b0HnsR&N7)lCntX0-d=CdaS8)kxz+GJ#vJ0z@2tIk9vNZ|Y<<__YKuM%Po)(V_$OJz5`e2cBp z1D>lk|HF|Cj9yhSZ<{u!E9!V28;FmIE6RAKSKRszg?20i6%ePj_8IfvccRyVl435rzEw&4C4#Fh2jv$D%RVEPly~NVf zPn`@aRJZ9^$6%O=_y5!z!F7i!t>%45$<^nKVR6%l&TY@W$@-D_@B^&oB?J0i2U6~f zyfg_}xK_Z18@_m_Bn4qWv8Q2*fTzry;^o2*XVE0DLFg!d`Xd=_&$v)Ep~L8#*s^^5 zn#(;0yNHasQJTtF1Y=VQrIkcewgJL4i4V;uu@ln!1YjX(5WjaZRZa=p@K@~1r;PP@ z2#+>L%)-_InveRx(SiWb{u6R^YDU3f^!+hCdH}rdT~`UJUw_&h+?RB;77ZuDiI8e6 z^i-Re2G2x(*#KkbQUf1+cy${vp=YPS?Bu0~5eM?1f1IeatchEG%7ARkCtd3daegxORUD0Lj8LR z+CQRrBWHkv)usev(Nj2vzvIYdO@EF8!xjnt`BtefmOcKc0MG|sk1f`%%jp+h-)X^k zo}Rd6Qv!vwro!xOK0+;YJRkYDwQ(At#;Yyekyy@RpWZW~C}E_wQg{(pegBHyd9Ykp(rnn26ebx@fW$83`Tw^s zb{*d2-F0%e$((IQ=9Bzc=G$;-AF@m2jn_xo9~Axvc&Bj@GsEFOCmAs1_NJKQtJALT z)@~%@8z)~^RRHd2?sdf#b+`Za?vwoOb({XjRvQujwp9qS_oU8(g0*=tly%UBsoSkB zsb|*igQCnDNU410ORQLTX7iK01>U`fcEnN^rJ=EgV!^iZVTf&K-aMtzWyiS&b1&B7!^3@#1U+8?}) z^h0MlByW#{+nJGZCvA373n-!Bzveg7qiahAZ>p8Vo%=^eV@3vipNh-}>QV(iO*kKW zYPAWxevf;#l?URsHl8pYg@LA?ZdQ$s9535GROJ+#zXhlHg3ZPsErhJC<{bnFfma^H zX-)T7s8od55dfky`2mTgr;b!u^t*jcAk7=-B@1|Gl3L?kngy1TY}e3Cj1PWL@8+0b z^#&)C2d_vjDl5|&=FEfQ2e2eS9dFMPGV!vD;`M3?C;sYZri_xrJS02WCkuLo2SF#o zeqjJi1i&d1rY0i^TGH~f6hZH;e)ILYy#Cyr1aJ1ivuw`?T{HRf)Saos$9ai{vd}Js!sIh>{)qIKj!M<}OqqUEu}>`h z%QQjcuKA_5!xlqV^e4;c_<2DlPwm{lt;m|-daXn0xmWgjqxhNg-^yWCQCN>yn$u8cyzqs zOPKk%?3O=KYUsN}Q6j*YCDdkOR02Um=1ddI*QbK(Q;{YFm|@ufVHKk&uKGxi=q`}% zXu{mVTCw=0g-slfyrpT9e1O^eUXxHe;^(hTRHpnM1#I+LOdhs~{X{T(wt0p_(Og~l z7|-Jxo$0^7xOzyY<;&dAxE-`ah^Q1@h(UoJC6WP1c5(mz(>n7%AAZ|Ia8ij>6wnFc z@?xyV_#)a`{1hD;CW)5v(aYW?%( zlla@~=9~IIdfiI?)tfQ5|J0i>q(8w2Ue&l=)mrD)IK@l}c?HbQ6y@r3Yaux4fnPFm z((hxy?z_)}wci)SDVWb_LMMN~!hg!*U>g#GKshkk6>n(cnLi8gC z&AGXm2(2k|M{DH+Rx>+W=PCQV8V|3NB(mp};|t2zT0NQY8}~>~&MC85I?veN*LO2Z zTj2*EpH@FV9zV&@kW!T+CPz^?Wko^#XI>kDg8C3fsz!{8q3LLC?ZSL-<;P98KX2!Uoz$pPs8cYf5o86eRDv+Np zQfFv%U(1Qs*yp^PlUtzut(J0g0<+#YF(W(@OH=-_F-(Pzt{CK--}6*adFd34<1QzI z1zm_i`;*&QzHySp%K2K2bWfoF?Cy^ihKM~O(;O=!hFDl+W~~{eN3r1f3#@sZWT5-G z{((Mqj|H=36qwuV-Z#Hpk?c(mWdGcw_v1NSO*AZc+Xrjo5I>TdKb_;k@|yxipoJI> zCLG&8DJE@_N;Y>K1kx4IobK#Fd2qDAMo(;_9>8crveQ0NF$ZBj@qa0YO2GPkr^U*M zkC=4;=aAMz`DUZ+1EgRMedbvF>FSv@0&hF3g{oTf=Si#-)H9zZcb~%)6*NWCvM|ik zwAOU|0y1ENx{|Hl+-x^b=UrG-QTZ4^o6SnsGq<}R5RAHUsdMRID< za*SfA3{G>Il~eVQBxYY>WDzm2?KEoOke&whlOGT@8M*UTqR)84#>SvdUUorid$I-wwUD{oUt+| zw;n8xg##(udvpIi*leca5c0cYDUa_%wI@F(_sf5`N}6a{N8i@$sH7Y>dKJk~hbL&lwvhA`xze)%Dv zw*a0t8`?KJL+zBD4M^T^-cxoCz2{Ec%F!&jh9!sQ4*83d zc(3e!eb&K}vpHe=TF;@2jG9;;#U4GYX<#4l<5bnJL#{r?xB1Fy{Uqs}os6_SxZ_(r zJd)k{{!*|*?OTtWihb}3x|ziNV`|ExsH@3Z#)L%Xphpu24AAd?9 zl*%}XXh1ygEN?#TH;#zl1mn=(cM}l`M7{*(h0Y+4oamg;I2l$2JYd4k$r!w>1|^r! z4AF4B6V4eoe7(#IVMb|(38Pg9G{W2}C{bMN3WQ5d~1%d#cf`Z&(P8K~#jTV)dtyqQ8-^I-<`a9E?pg6>}wbA6X~jl>bR(mKJZM zw>8X$A)Hqhk1qg~=JS*xrShQ&=ytTkB?Pj?VPLacj>8d9d<=KOt>*AeyjAj&_X+Ju zHPugIxE*8GK(Y(l{~ywsS=2d^?DU0*L(-#=ku>9%=Ak9OLC)ETnBI)lFS zug=`+{HMWBLW%~J7Fz5F9md}WNdxav=Dr!GLhBz$AfAzWjGy`R zu^T7Y^nPFUvCpYG?GAjt^xAE`OBt&5;`&C?oP0+iPj-`UD%$7!yt&IKZr>`HsP>YH z^R9J3!Pn#Gb~!TcU3t{EFz7} zp7z_l`%@v3I{6boak0J8hw}dS$YOvo6kk+DHtR;NFLUVa2_6O-XavuXE=Ul>hqfHv zL>#+>4;cZvu&kyqMz+@CU1mV}0RD+PrF9Tctt0IE3|(zQ@avqTa*oiI?1qJ+$GfcWrPGXj>n&;(b%qt_aki9fgEbcMb^dyqB9%0GPvOU7Ky zreUAzv#sWG^icWSiJ+zX^dd5eBqfSPVTKVWi&{?vq2|qzQ8vbDdw!aJH18=(8{Py6 zui^A05TRB7Xa%w%{Jdu*vFEV$pvDi%pu?9nMAhd4mN+&jnD6r!ZhEMNqk4?}MPiV{#TRcO;J9_csFOHC z_&;|sslR!Gc$WW>Cm8)lE2)W~|EZNo&sT%@N@hS@x7wNSMdIFrZnfV(+%;mGPm6~> zzn&~GN!a)LVBHN*%I3G;ET~!v*Ni43Y;r38PHG`N)2nk)b<>S4Lt2tUG=DU{hhJBi% zyfA)o`SJ}@5!AS+c}I_iCIuOHx|?`U$GFFU`Hu3vV0Q&Bp5iFVdBM#KlG=ypPrPx`|fLx!o6fAX%Rep;1@j1rxlSVsrs`G6|=J!I9yp@M(SP^*%aG z#uJr{;qk4tlDrvUli=H)cYR9hgZ%PvNdXh_*v^ljI-~QNBen+}Xf1}>)u|jwlZrK& zU7{pr|C~PeN6O*RU-k;8@{E8;`4@Qv0z#>yiZ^XGjl6R*_gnhbx5PI;^hzxvqLA$L z(-HCbtDCsoSe_bVbjq@2hd5?>CyZg-B0B>_ht^}#8#le@rQ86A`;p(+fK`1|f-M|u z*@RwFY?1Dj=+c?5ahb#`aI-YXs76-kX}qRO->n`)WW{P>49Zz=OG@M+(;@YChq>sj zTs|G%9+(_1Yvt?Cr*{7v1(lj%msCShjj~wi5^y%NafmL>h!Q%iDA8nJg*hGAK(>d6 z`Vp(qo1gm^9!t-uE~_M-yNvTjO*-Tk&-CWsnP&!c%fM3iVbzxu^x8cTcudyNkc_*P zgVg}gl@0|v366E938;!>bjPd?&l5qvxrmW#DNB`Dp_UR7-@);5L z1QSORxiSh2%;n=pn1h$Qn{sQCUD8U5JxpiSh7o zGvFG4)c!LZC4n*v1)y8Lnu{v1_AZotpHMMVHji7x!8(L7T_f6}tO86WK-2WG)E{#i zG8c|obb(}N96D(GHtqM8)gcxxB!B%j%IsC-#ZRHFB`XqrXh14DJ(jpDCM-%6Z%UnR36K|b@ijzn-6Fm zlEN9bPL|(GNwvF;vQjBdH7ye42}s&bknP9}Zui(%ufb4^ruHLuF(Ol?ZD*qC2wZ^)cvNce4{XE_z_97$Poa!wSx9z)|9kn!il%ol;ID|g z%%D5u9ZXld7H1ACMmBl3!$#&kxEs+bIH>f!$3MTIYF;dXd{o8O^6ZuY939Z z&;5?a6zmDor(Te%XqtJcV-ALlARP3 z$$9^5aCo9>-@G4T+zeG-?Db>KLxChmXYLu|CT?q%m1Q7QZ4d{9s zBv*t;z@>yq_m-mU0j^QX7y~C+6gE`un}m4KN4%zd%R4Ij zbz-}!{`aD*5xwSY7anpNkzTUH4x+ufU7@SCTJ;v#Ef?mgJq*g9!`SX;6yL9GB8P#J~GG;ew_uKa(}g+PvT(37%Mn)EPe6(!SQwBpdzs zt-qdhtesKOjL1aTJ;Rq=-o7!yW{eiGr5X%MiMMa_6x1DYTHJ_tl)5D&$xYafkO*ZW?;K zqm>gCH%+`xz5QZg-@m)n|B}3&?)vNdO5-Y818r!7N4Wgt>`O3_yI%p~v-t#zz|k)wb$g zdR1k43@Be}-dy2{(^vCwt(AeOZwFg3BI@QGZP_BsmDG5MXdEn8Sfvb;GWB;H8F4w@ z9oQPKg42K~Oc``d2X?;{Qw{R@5k+Klq=#guhTln`%dkrDavHa7QDBP0CyTCnZ7yhu z`p-BN&B{;mCrHzEl3;Imjr;u%Rnay9eiy?IG-NpVk$$zqdIJHwc4T}a=&K~B1~jL0=9u1^cp{9+63-i)5nD@7GEF5M#m`h zw>RT&9+-y2q8TQ^i_NJ?GE(kGuqwLi-wAPn`fjkJ2+-Rx2<0%+uJ-&w3)d5<$C{^1 zBOO2^f4+qvA)O+Zc*>LexI*b+eiQO6U)lAksI{yidZ9 zL$Y#8rkK%;&sn6MbwaS}e?@p_-VSOqgm86(S4ZNYg{lCzR}nXjL7RWlUrs+rl+np< znnL`Dn+I=K9AQ;M=6qF%yE|Dcw86MA$GXau3q6kx=nVk5rC^!YZXqmSxjZA3 z?35e)$Ahj6%b8xx1j+vNzu7Jxbc$=%1NgsQBGP}~P5G_=zMIf_{?!{}!vEA8If_%$ zxLollR_}*!tl-A|XN}=#LEm@S9`vMI3eA;`2MyKRnyG`xQkHGwzQ&zl>wAyU7Sq)j zxh7E~D6c}|j(=;Fap>IVTXDv#rc;AIOY$&cV$`82*HC$DVBR$4LDTD~PvzGCynjtaq6>E0UvCS5VF5&rGtU?57l^z(%E>-^8Z&L@g0F4GAlKKsiVVv3 z*XM*$b_v0c%XpIh(i$O|Pu_HADIT}E#pLuqSAOu2&0Vmc9MQ~7)YG@}piS8&90&6g zL!10VVADtU6S%;X77oaoJ_Bk8Fyqv%V&%aSGjj{hGVI-)n`RjU+aOxBqPa!n3)JCi z(W^ka)m>Kv6kD-WqYO_@H*g91k?f3Q4ve@O%pL)Rc`P0mKpyU~QrV6}JP}%XN&uj{ z5BVIa{iT|(S*#E}sWWai7t+6`cB!~tE=N+PFYF)4ubZK@0LNx`6B0~KVhNFV=p#() znY^{VE;sLKD<+go6Cn8ZW%Uggl-f~FrNM3OF>>uvn;KnNU_k6vq5dn(PHbI4`)tu* z7&ds;)@Ou2NyRmD{wsq@>e&EVX(0JafFnkK)0Nt^b{JyV56Ju?0iB}89)}+gu`Y#V zCkjJ%=vLG zM&2HrZ5Tq)F&vOx_p>#w#yr@$^XG7j+9pruL=a5KEt*>`jeZoE(dbdJLB)6we@8fD zJDW`gxarArE}LVr;u8lfVPp8aKcGoeD3?KHu~mn9y5e`&2DkGLuuxMmu}a^a4F>`p zd@P;hiYm|Ye$3uD5e)ne*Dfx#k{CT$dDv)vMAo&DejNX8XU%E;8`rgo!SaUj-pIZ^ z0vjJ@1AG71&6@-+TId}FJa@=mmox$SzSXvouwe9Ol04hh8UtI|EHHN;Hc)W1-YX1< zd{)hjLi5Rn4a<(MwVJ+zQ1ZSx#aaG*6hY)7kxr!Q8-aVD$H<>h^cjLLJ^B={-X2j0 zaivTMuMxJVNUoxXr48y6rFOR8cf8_n0M$mVU;gXd{`|7ngOW$>|0}wNi8FCR)alSB)Xo_J~DM(r*_s#8f zWK(i`)VC^u{$VBA67hAz1|WrK(Qy1BQ9mT~{vZDt(!cLj%=mwG{dMSn>bfP>X`@^P zH&HwE><*o-(um0eH_qJp9tVtQ{jy|2C2KhPnq}}Y+S_8F#XF zMEjZe`|A&^fc1z#)5A43bIqmcO9O0ahqeFGuH_A-Jyh$qu=A#WYqaYAfN z-DAg?$XAA3R!VLfiO*l|%A!lPYS&s@1ccDZ@`F3Q9z>kKYd-k(XWHLx(&Y?%SQwxg z&i15Bq+3R;mAAg*!#MZaf}YB&cDHC}wRk9S`fr=1^NnxL5OdnlXD+;1Yr5Rmx_Y-) zQs=!^bTYfMat2EEsr_-==)8Vdr8e^PbN~Gh=~GU|7meiz(zWE7k$ymzW9%`hxCQQz zg_U&NY1rSHIEo{q$iR^YUe%Te&%LK5o@HI0LNas=ZShS7?jGKx&zwFZ^*#SC6>PwW-q~SwMJ|~d zhjAr(rOi;=f8NLXdgps1KAl}iZDuPXCWy&7+qEuqotL^XQ6z{s-^}{1J%S_xrGIz# zMjso>>5rN0*YomAlL;qmgr?2AHW08?p+Hw3D6ny<5ZAcjH9m)Ar<@IY26>MSXem)2 zs9UGgiaU|+qzN*W6YN9l6Ip#3BG%v-2J0uNkwEv7fU$4lgtM8xM!`_Rk`T-+6L_Hc zF^{0N)Lo-eCz8_+@^ckgO6&6zABm-3MFW^jaSzAU%~UlZZLiwMP6uy%x`epnSH;m4 z_gZEcL}<&J1UM_NEHk2AP4G%(30)oBRZJy7{1gPGha%*Fr`Q32ldlR-$tsjYhfW}?Jac_8h~4lU)-Dr7LUW>ZCYnPF?Uz?1`GRR?p--61Gjv#87grI9k4f%AN~*f~ zPR@(kws@3!!+y$N;(h&{p28^0<^%fOW_a;xMPbhulKgN$62 z2d*9$FP^qo!h=rN*n0Ry`3#|F7+VtsXEGK%hm28AE?Q=^)H7{J^%06YJ7+P*_WZll z-O|mqE<%Y2e&l+^sQsD7$+DL#7?@4Af~iP$8bh5^y{v>WbR}RL3MuY}TK;$UQMe<< z2f@jxe4>Pi=k62**m;f8p<5|q;Tx+X>w7TtwOO1>2`Y>YZJE)irK|N@f!Gj~VqRwd zqKgN#HI*3u4{RCqEvL^@2xkS{jSiX=gq9pehG_vf@@lx!H09qg&OT3fqtqq`h@rED z1?BkvfEb#~eB(0cl_lFC^~+Qui>2L;qgo;+)P}`2-p?gKY4wpq7?OWD;Fx973aAd2 z9O!63JS02q^@D$~wIP>btfOa(U&l-3~>_E~sSrGjNVh@_P6jt+zaKE1QrC zrT(`A%p#eN=4`n@$RGxLA*a2muhTRuvH9@I+-)Yz@n%nEiR0MadwRpU5D%4;UM(Ys z-5#~%IQ&<6*5p{?v}q)!RFh3#w`eJ8y`l}C*R3ZPAs4^a3Vn$EAI?EiBL99IO{1Ui zatRMRp{vhAOZJFrB_Xo$RbS8F_BYJ2)fFm)pzFDWoyId^B>U6S|NXi8zh+tfZ~hlb z>_BY!^3oCJC>ys$8T_Xo72XbtwnWzC|Jest}7nEJzZuuClEWvo}?;ra0dLk)h>r4_mTY6UK zF_CPS=T{idHV(--3%_plP$i`ilARIGc|9;@EqQJ;A)Jy!`8b6Qz=2Yqd=JKK60i_> z9hq%PNr(S6OI$F^3lD zgDF4ccHPX={Nu^rRj9N7{wa=o`{>;)Jwepv?ZiA_+jLg0NT}-m8|`$^F|&5+nV2Wc z=_vKv2L6i>oH)Hdcs7qtHRZ_pKuT2g{CCpY;T3aC; z_`cYbD9=yn@F)gAbr`|tFp3YgD(M#O7lR4qlu`gJCpjW8GIxPcYJrZ<*$3ZO*o0{g z4q{o0Klj5!_)8T(E~P(JAI#f0k{e-6ZPKFZ5*H8w5@6_(;5aA5$(H183NyziJd6n^ew76`{eeDkSH zk{jNf3Uy+NMsCocEKP%uFlUE^rFVzR8lO%@yRtTho|N;Wh5S?3{%1!rU33Jy&p+Nxw=G?GI~&Y}VXS{$2KQ4XS2w#AfJr_3dB_7WkcEi}r)D zwt4$=W;=LO$vv_1ZmTjLj_>kA%g&0?vq6@Mu3MgFRGf3aEb9x;XYrII(=QjGEP>I+{({%RXn96mT6tp)yJA z$hea+sk&8!)-S`cgHlgeqaPq_dS$A2k(y7#{s8R+Yy^{8V_Ds7Lizse~QMZ4RSwe;9j2f)mNjZNUVB znwD9Y*S$!`p9C)@%#i%4X!z@%oum{;7zrv~(LlMpoQ?8DzeTU6T#3pse}toM!u4GR z6lCH6-FqO*ibb+h91f4h3Q{Sr%Iq+Iv-*X__ClYA6i@QZs-unY+%lXA1F%^6L}VcG z!M;?$r*x@U-A}4MM%dY*uPzD9)QTq*C0Xw7^g?!*g$~Ei2{l|P_H=`(2n8NB8W&`1 zNE}{7_P9zBwsr}3(P4!3pNWUC>wB}jj#m3l%MhxZO#aJwU$;l&3@d&n+H<+bqIS~o zv-_$7@wuIfi^rXfWT?a^zmf5R*#%D4Nds$n{PmIH5sfJOZwaMR>qvIWc$iL>Jw4Us zr*eqaMn!#D-kx+sY}1JKzEXR-P;g07mR}IMOoUvDN6bK+nWH=%5k8u8p}@0Nd~L1u~`f4FlIWw)%r7x|9>hcVmxr_lqPujOZjj}L}#(0erp zM!j*+DlMW`a=$ny!p~x}Q3ZADknB_}h}re9w$+Z?7_uM9VwYl*F8r19CCfD$b*8^rth2!M+=`jZU}Qa(clpwiKCOMWPni)k2#@2j7coHio7 zhb+8y<9i`xkUN{($q@p<>=I#59H5re@T=PI9Ju{hsO%hIKD|9DDtnQka@(;)7~(;P zis(YX*FC!)hcb-UD&o4*RvT`<>)JuBm26&%<6#^<cgRZNo@>8OxC|x2_{|DRt3su7x~}n`_phiR8wamSvf^7>WtKB!PL77fsZ| znY2S6t6vxF2*C7o)etw)ZLf5V$mUq*CGfyycO`JyRKP`+?YPFlqE7A=()Wkxq}J|9 zwqLF_PnI;U=L?$kd>Re8e)zT*5r&BFGtxi2wycUmtYq@?ENdpt#b%!2RL=TAPgojo zxLLE)NW7>m0qEb~a5s*hD_FNmnh%Mx1C)pXI7AanaHne)I~*?*6s|NPk|;71_rF15 zMJ4(hl&nr%8ua0&Qd?dvvgn8i-QBS|d-o%p&s8Kzzns;v>uY&7_WR;~KVdAK)I!J) zy|((X#Y4%QkKRHG_bmrV^uI@6M()T!B_1EwzRQ?T`)Wcp`ZHuXf2;U~o^Y7hp10P= z2VCM|;$T^4Z6}BLQp@#LtW`x${1IO`Vy5pCaIg?6f$l&Y33o$jyaNxEoLaZmWd=3Ek8z$I)bAjgb}qEGL)T+Pq)tq;+1$y{Uq z3yNeXsfLOUlI=IS>V!pZ&5<|EsbR38D61a8gZ_zA9}0484(V`;%g{fNzNpJjArc)~ zt{dm|YXSzg5f~bMg-UcCd(&%VZ_ogf}VQT8MiLb;S9eW8& zC(klPvL2B8Y*5Ky382@r_5(gnUf)DP$!tTz*iVRluRASk|yev+lp)4CFUn& z9HW_4u29Cbvp08tc86cmn-{keJZYYvOkPi>MX}VMWRYYp)UFerj_m@sb+lm=hvDk+ z{c$DtT*F%@Es2s+A3_Zid}S1|x6L&4_9JP(<4WI7E4HBRu!nIqBm)Is@U{A)y_Fs- zVWXBaWi1qcI%U#LuZ(>%ObHz=O};qc(G%%?`=u?Y=1IM{941u+lAWCRYj6#EHHMs| zTZS2o?zsB!u>@|?Qi_iDSTS5t9Cu>#^SLi*eO29hak73D!ZDXSCjuNk5)OpIDPF9K`4 z=!v#QPNsLwtC^T+g?B|kp-iW6xkt~n4}>RfCb_c%yIEG)n6ItM8i8nuVqj^0SADK+ z)e+pVW_G}bz#vOlCLM7%0Le~4EGoM~fh{il`e}Brs<+gfm;NyYHi52^K?QekpTRwf(WIWnrzCKF#8Y~IAQnkUtpzF($$ znVs@z)^>EF%|SEmn*3Di2b87IGHb$oF1Pwgh4F%Y$I%B_^5)dS`5(Y8pDn+m+4-^C zZdc2OrY^yWg}L#8U{)*2;@?=L!Q_-NP8PeJ4O|Z75o{#s_J8BS9JYy!M;fwU43)AU z9~dt$uUl$FPD(vcu7~2KP+M3(%~P|_yVGsb*UtH9x%>1E zO+BS3rxp0eZ}I|XQq-1nlwECYpLl_>@<;G`6Cv#NEMim^$oAgu4dBqB$5P4b(5BOXsxN_3fto! zTMCp~Be|c$iXBw3Qi3SuU%vF?L)~bTgkT-xcmm^2-#h2Zjp+j4Fb`mOOqtXcftv-Q zP>s+9Smx;d`K?%@RQf=p zE81C@j4;L?&w)Wh!cU8{307*7qW5TvghqlyCqPEJZVTv(r(GP(bUhAz*3WuXNZ;v` zY8$GNh#=Xi5zTEITA#8Mb2W`9)Bqi(4-OVIrY*V(=Uj*t{zkJd zA?1)iU$S`dd95eD(Qz}%QCS3{d4C&y(rxgTyg`UbgYHBaNLwPoS8qdl>` zzB5l8)x}4PParg6(35F36)*jmHvNtomEx^#Co{`J-X7G&PpI@iTTr}AH%r4$lTMUE z2|~19W~+1YIY>AY&7dj#qd_2~TB9Swaq}{I2-Ql$OB2aXLq!meR)OcnHqRCHftwWn z=mXm(MWL4H&S>sY6J-#B`4SC7ogvSLpZNW7ze(VFSRo&%?0};>_j`zWwGtk46Pn8N z&fWP=lz9)eFVX5yG-}BNCZ6O?tp&uyv+Eee!e4oGUKEMgU7}IxSJH&g>)HGSlKyPQ z`81S@_9+SWvVG*Z>9)f5=OFS3{MP z`N=Kjx%!i+UM`wHQ)@_eS_4Vije)Dsfi$uedR79W29~$T&2=Qrdq}mGLV) z3%k{(!!mjH=_;bdZYtsDXBE-d-PqH=KMtwu~y+GhVB%sF@Qcjhvmz! zozDq8SD9y*`H%O7Hf6iJq8MJEk$jej){W)mcvp%_Gy0ls=i>5C)IR%Ch*kAYboSA@ zVyVS43#H*FDvu8R*&X1Wp=XKd%9{uceP$oRCpC;^ZA+TgiAs~Iw1)+i$TuGgj6C?1=&5z|4XfN$e9@O zBKThM)ADihNAiq~a1NKoryTKQ&3w{&;%zS~hXM+}*ETc1B%%FXeF)Jk($s+Zz~320 z#1n@%)IjDIorKc|I>GPWzAg`Gyp(yWNartX)KQsfNK#D1sOcqas^|X1QUG96N|}pp z8QaL#tnK`Et7=yuI|^K_-LN3-!+#pzpN?dwuNytIuPD-CCz;<>@o*U9e#0o!`B?Zj zsGzW4e;qc{0(luC(bAe4xY@~Ym6@k&MZC6wcKlw8x&#VofTC)N#cjqBR9|9$J)sQ(}BJ8*uvP@=EF<|kauNSY``nG3eBB8tZdD~KKnB=(v} z%Wlf0#bCo9<#H+Y#g5W+Cu64rY8|CtmTX8&E_%@}C9zwFXI0?Y^ZxN#Zk6r&#%e>( zSyKq^A1h9n-_gxO-&K=9=CJ?SO@c1)Z%(P@+kfVidXYJ$Q2Kdg;?nf*#|d6%IEF>D z_Mybnk2k3i(({2P9n7}PI7Jp8Ib#oo;*?aKT6LD|AK*U0YIXeguQEpy5(g{4b}n4%y>;9sVARKLf9PP+faxkP zabcR%^KyqdG!Txzt15lDRnKsYj!BEtKuOw0p?A7OKww6IhR#>=sbmoAfj(Z9#`}nv ziZZtP0iq>FHBIoY*?pgKIASrllmx>>JPa*JjydO&_IjEq(#slsN*+2#e}=4Owy-t5*nduaQPhNOgvO<97dm>{Q-KGRXKlFBSWAk*%7( zA4KDpIY$>}(20ZgN+C9(rgYBfdeTWK;Y|-T3`p~>Sau!p=Uwq+Vl25N z{*2}~$M^U2%bKJoh;$Yb#3K-C0U(eo@N&}b`vWVhiqGVf1mF-FO{NXUyv$fZ<@qe= zyCL~X;HB)t-#yPn|IDxI{Hrq)vj3?wt4QybsHe)W&KO*kybC^pB6Q!e?5aMeZ)H=D zYfz{<6OGfap2Og->|!IHY-T|J zNZx-P66^^IYHq;})p8btq??6wW#R?SpD0T~$Evz=juqmT4>Bj{eyxUE{DJn{6CQcd z5jm%I(A+i@%ozT(5J)i~CDkPu!bZ~jVVv&i|`wUY@fdC6O8$B z6e+iYi6`-Q#~n!qEg+#+UIjYvp8VvrvgrwCgd@gQ=_qeJuC zPuZk7h&alz8(SFn8{j&;-53+uQ(W-S0N)48_hT~QGe&s(VMn{bB=3PFSLL8lmn!TzM){5qWc%ojTdD1|iXA4+^1YAU z0FHZZiuKEvff1ABR;Ts#!xd{r*0&qO_ju$Ux}v?7bmd>3Ze`U>RO>v1#59?kP+4G8 zTWg_gQ*idfa+C7}9{6?b@6Z;NE~)kS4-Rl7 z3VYGX*C|L)|5b97-j&eXcd#|`w!yX#++)3YhNm;AupngdXfeGJBWOe2_JSta|J8?^ z*L|h09wgv+xnSlz-%}HV2&PeIdxdq~yU}sMwCE*-C?P~=7`=C*_Zra!QAQ^^A*AReTJ&z1JNbOh zJ?nedU3Z=H$2n)+-+x#$)?UwA@BO^q&uc$>w?|5Xeq=Yk7x$`S41pV_N$}E8IfivI z=VO@ZaMQBN3d{_(y*z-=^mLf*{HO*>=<~KToBiEIB=b+Ji?1Vj#JK;!7~}*n$CnVw znS?@1Ee~oLuIM1MJ(t+GS=BXLV*sFe(H*K+vp39l*xO^3P7s5tzS1}~7fYBnfHB-q z6O}6rxC`Vb6Tak0_bowhIKX{=<=X_{>>gO9a!v+VF1{Cw_iot~ZVe4mkK)bYx}6zt zgNA)7IKSIr95UTL=nn?N#u)34#oXn;{;YqnKmg|$y+JAYr$|VCLH*Vqc{!cw`hMb$ z^H6OWamKdFjm9q0`2Wd~|BvDE|DS#lEO`HqPEYi&4!djR-+MkR#J^m*QTHEQnGK*k zIwZ#xHrH1bby#d~`@;6Ln1Zms5T8hvH(~jQ9}F4{2nM+UIDWj=-u}FhRxx?Q)Pv9u zZaGqYM7+d&&TQ7Ap7FZ!Pixdo!mQ)9aX?4Kxr7m9cf$DaSX_zsx9!%!CGoK^U1myD zx?jSuPvi>kxltd3$*vZ-qiuh0QmN=qe$_qA@>f!4gHSq(JKBctzgh0K&~>M@tC)FK z;z1ORdcT&`^quy2{;BDh%GXSigoG8@q61mWFTDJ?cIUlRuKjN6JPp2g?$?5;Td2>b z-b?K#$>PIS7BP+@Kb|zgdUahdhbJ=nA|xLe;irF2so$9OySg_P_rIIDQcU|6aJ|#L z8kWsXR!mnEXLsFX;0=^nysB6&i#(9X|p=ihQ=zjKoL z<7PFjso&N2%WBj@vyJUqNB8ePnZs*cq-g9^=L|}ytEXBKmGh(o9^j$OZBmBx*zrF7 z4jz0#&jNzR3u%O9>EQys!Wbayot9H-QPg2wQe9J58k}@xfOecb|Du!JBJz>_t&tYJ zLhVZUxFNB_647elV-NE>0&`$jAhy(tg#BC+>Wercw43}F0blvBW~~H6E@iLytRR9H zhDLpvt==9m#XvTJK-ze-^8Tk9u143bmhc@E59Bw-t;nD5q))o$Jh#dc0mLuHy&h3K zGCCLQMq{Tg{;{@K8c*Qy^_%h7efH-C{#F>sM!+M-eM^S-$k?%lF1kp2j_*0!YgfjE zfl4~SCqB_DpV*bIp~i5zAy|plvnW0+%>a9>8UnnuE8hC&ZXsVGJt7f5Z%GI?G>DDx zhKBw1+lHr2VQF(DmCNYSknG6;3a63`;mhB$WLz zLlT4!MIAomN?UnZp3GSmNdahbIFex(yirzdN?>uaL{Tj*4K=3Grv#;z ziGmnD?(Z6$jaPDjI3HI9NaviS66y9iAU&jijWpDyPZcvSZ86UuAIR{Xk?r>Z!8Rp+ zuMba;4rU^O+V3A>u%Vkwu1!Dg+#TKIIDLC36J5GFB8T0zMnVgSq-)@VDh!syg^KG=haJn4@5ga24LODaB zP^%RWhlBuX0hOS6^%vpz6vgrMNG>Lkzq{u24@s`Jadd~X^xXp>#vsn@I zOQa_=#fpu1ye$-|`Q&M!#uZBP`=D;+NYSHTtQ(>(Mln;Qd0XA2eOlpN&gXI)ZcYBJ zK+FF#=N!%mmr%e0D%_1ym&R-B|C(`(Ad1prUMZY)={4YmW}Ed zkl2TzvCCHf*Xd0ICN#oFR?@e+h`N7z)4%8U)PH-@EyI8IBu2E>ZCo&B%+H<7TS?-n z<*)4bRlwZ_TuGl;3v;7iV;YMIm4_CU;ZG5k>|dFSmGqyaOZbnW?ltD^K`P!Q9-mhl zdGeJdINxAs!K8g#&YE6)K35GWjG4<+yE$P_7nKU{xQ~iic`prDT;ibXC^1@!zx;h~ z6qw%VKVT5qz}<;Js#kcE?xk+4kiF4BG1u21ifmhK*rIq-H>U{Ebtmq^W$f%q)lcxK z5|$mSSJLQ`=0OA=@0+sb-Cq-$kmn+xWz#HR6W`zFH)ot04M-#PTf281twwB~pP1-Y zHd`_wfgZ)V3?hxcMQBiWGGG&D0p6W#2Gh1s@U(on%Tbk0w?wBN%)aHln{MFJnZ<>h zs`qT9U77d7O6oKVPq(C>9;820`&#(MR32v`hL>!S9eh;X|Dw=VJ|EMPPbn07!)-!m z$QL0q0f>RtTi@AELM4<*$Syqpyl0s*ahO{m>6 zaqAJlX&nv)adJ+8wTZ@3dl=t4zrZ9UtBX%RS}DbK2nqD7wY(x1$_@0Guqteg!eJdczSkmNqOp@o zEn|ES?W35dc!WU_x5A+)aeh2k2g6kvki_P+er;@KCRzt3UF-r9%B<3`Mi=9Oc#obn zhp>Lm0dgcHWrVTayAVGsyk68ixZ~!LepaXZV>jLDNJHgzS<h&6>Q?b%j z$?ej7h@%5oB0OdIl|C=cW6LcgQx>Y@y9lZRH1-D-@KI7Be4HXORKm<&&uWcdJ^u{M z9D={+$sx}tzM7&lm^>|KeiA-W@H^VEuibU!bO={R_lMHuxs=zMS)&=^bfEe7nRXDJ z4)naS;LGKYRSS`@KBzzE3=UvoP$$Jw%K&V&A-=Q}2FdcZWfRwaHillh;y+ zWDi!fnk|DECg!Vvs0l`2o$mDteZe1%#yji|E^R{l8S>ShDPwa1iN8j~k;!vo(ox_= z5F#Iki7u+3v6FcmL9+ze86?@$QmNs~k91G?Wi#PzS0dA;2Sy(U59(5G1bNQkFq1j+1ew3}18n$rDY63UQ)+T3& z&hwXJX__hQJQu%67^@olh){I5FtHQC4(StAgAgkZG@?Z(ak8v@VNKHWy3g>0NAngb zv+i5)av*AxDS*kn1oN$xEIOf;4+g$XSruOz$wnQ{EHuMLX%ha+i7691DUwn$=Xa@`#^Ip`enrYkK{> z>TzRkwcrxWC;ww~1nX=%l;T-M^mIWcs+U;A^*q0;E-8QqI4`^Bxw(5jU0hMDihhS@ zhOXQ!deL@lSL_+pnrzWL_D3$m7#{A&OWz!mSq7o&PKgXD3}5b^!6xtpnZUefJjX=u zFrL;2@fOP>3|??un%^|=e~_&X2sow+)?V0_a zEQk(0Q4CmS?B~nucY(Z#?o;JhtCZ>!iPRu~nIZV{if>f4>Rek}W+r@rgyR#FkAgOl z2)+c(c8YOZ6`7#~Z*!1ZuS#S!c8(Rl{dI{B127(nbY|=SL9DbO2T$+?8(?_IlUBwn zHck+P;maIvqp?#lq*=O^f|piisCi6uPU*!Pu_-&bT2&%kQ^=2hK$1#5!Ouf>dhz6gYhTo&GUaXmp%1fodcS@!hN~o&JvsCE?w#5nOBTnjozjcJjd44TX z)THvypQmH#-p@sM*&`54@MnZLNmD4Wms6bV?9uoWvcovUy;>-I!}lIiA|0q+`2es?Ipt|WxUNRT{IEQvbs#+W_w$!TnR?zXuM z@o)R^u)poa-mrpn!ZFOI*YWyaF)(yt)cCx(8kq{oDb0<*xv;G33%4;O9#$6(wbH_R zjHwd)8w7eG%NWIA-=aMU;VxEJ0KI82)sNY`sW87Kw*U0$I{nesnd|mjKYYRI;u4bT zaz6)ZagTl)&>MHDUM%WnPs0SI!Ty}gY4&U@?-j5}zHhB)_R0nuwBq{*Xz7?ILp;82 zziyUeTK$PQ#nfCr=MbZ{QZGpQTeA|Bz|F>R3E4bA#_6tHyp?H z`@FR{T&%?DA1IOpu`yN2>w$6H!pGA(=BVSmillnDOwT1skwE*<>d=PvV1PDYDf=aVy5hfMzh7*%raJmYus-GejGps~|d zVl84?g}iZYAH{Hd7+!yOh0h=S_-e+kvqA5QaZo`X$m6zO=R8_TG%H95ts4q)*w(i= zItN55=j(c&)mXZCfPj2ff|+w@+sQ2kIDv6Po4C>d?K-FBcq~f(fmJ`j_%pKnEE_^H zVp4x0iZP1B1kVCfw81qABNnab;}f|DmMm_UXyG!r_^F@98ga!;JCDYNI|UWy7V@4h zNRjR{QY`_qqH+Qy`kA8Cm4w*9@h9w<%w zkAzBXnF8i3@4MMgu*Fx_%*?=C??Luvfx7EsSTr$E(9Bhgp=S#F1jrh#`xZW4fK$1$mazT9#)~ha@b#1FA~*%nkG`$oJnX zEGlIs+fu!GWiwA9zln7vc0Kz9A_s0GaK$)&>~hpt6>wx%=F5!?`#)?lm)*Q2%_w+Q zs;all2KHEd^~dQ?K~S<@HCsT82_p6LnX0dplER%@_rhali1_UjML!MFz0nGs`Pl6; ztdmRzfh7>nH8LMvcZO?Dqn-5^BwM3qmE$-0H|+FsYQpq8dfU%L&uHR(tdPXrldum# z`pSP=Z%T)!h;z=DyZpEWQN?6j?%a6~b27BKKF@vDzN2Ybz7}C&Mg-0cJ&yAn%dvR) z?!aiW_|q}N+2rANOKfde>|v1k+jjd881gx}L##4kd^1FrQ}!BbzN$@N4k5P(5D>$Z z(}rC6SxZ}&=Yu4oNq(^_7B5SZ6C;2F&6Cz=%=c^vnvgtEFz>cYE+sA+J9L#Y^2e6c zW*heL*TjADqB_DvvcmqIb0Ob%=V#cxab#MQSBul49X&1pK)k}VD6sOoV`oS_#w3W- zWpLTD3rWrd>X6;g2?>YdRahDqN zQa)o&J&L5nWLjm-woB)rkYh@E4?tOLt1&~C^5|--=23HA${NI%oz3T(PN~!HS4!_5 z@beAy@3Z{koN;fHjZ2CxmfQDw{5=>EmwAf?P^EkXy=GxeI>g@XIHq*4HlS%uDx~2$ z66t(EUSkiz?+FB6_CD<$`C>n*yVgLML&XGWywbYp0*3(9z*z8CMw4VDU!u43krJ!y zo`Fu@7eA01ttgUz-kXkN+@(oZ*59&673l5yD$Z4XD(q2otntl2loNlPOOc^rHq5p? zZZx%&zwX6+XO1ym7$RCTrG=^=nDBf>5FAfb_-8}6r+Fep_l}Vg*eEMp@&U9s8EuJ87jjDaH2=>yh5x;d?El%}F%syV<^4tZr zs1kG^|KsqCRjGoQ4b#O&<+a2|)coK5CZYcVUfvwCHcIk|ro(zd^%V!ZA4(#BTK==o zNA}MhCC9%#N&fYJ_M~96-x8GNo$|WWQkaw~`nJ+WN+olJc>R%*9+-~q?TRG_$Y@D+ zV)luFI_|}Nu}o=Zm>rNtLJ$*+j^oD#tj1_OLTvwn*y-M)y1zwxYqO(U<7x`euQDle zoV~STI;?uLWHN0m@s6C=^op%(CG$s1*Nk3diMPT1LB){&$@{~yKR(Pnnr2=HQRk^| z?m19K6}wY#!QVnV^45?4dKQt>tl{a7Fm394e@#Yx$$VB}xu77C6BKoByA-jgB>5BF zmjJcrwKB$WJsg4F=^#S9vGXxABfFEYU8EV==hoF_CUD7vMVDyMBaYwqw1Ky>DYON# zbXjV>ENx%|e7f#j!g(`5N;niTK-nhh)F$G<-Kxjbd5}N`t#;tp{F$;H`9Y zA5LQYZi(tr{jbeJD`f`Xjh$cVjdK3YxT7d^ z+g@clQK&y6aF(y62q5CTIx_FK5I7>s5^G`nRtSm6=l_F`=N8|$@J1^_;iyMnj$V)s zBRF)%p37mEo#!Wmp)`(%S2@RCO6)NM*~-Aiq8+pN7t_`gUx((nT=C24!jjX(cu}YL zpl~0hzB@)C>Qs>AmJcJ>d?$O)<)Gq}N(7U&n2RWk;A@rbGsL1?Hl`z%zkOGmmua*! zI|e=dJ&$sF0MzHq0c#^BoQb4Zcxb1$neQ1IJLNN$eu$|h?uq@odG(bgVBHWFgy(8> z?1)QFIP}oUnsz>Te9nY2!dE#$I!a!!_z~pT2px^&W`V!>P$&=bcmPBpT2G-FG> z$mfp~$Xl^q-u7oYfp{+aTkTpFj=2b~q!^rfX!jc&=0_WHZ{MAamyDg)x^-4d|1cKQy$`)+RjHMjA?U+r^-yAx0i0p!HN*2IBxzg z+Q?oscB-d7Z7}g3?waAgLAMgixTpg%HpYucjB3xOK=wO-HS=h;5~}p z9+%D0%s@MX7`Sj8h~-@#%gObS3q7A^v5;{Bq(}Hk&~HpL6fUXb*|-64c)#dY1(DYi zM+`^A&oTxtYUF=GW%vFNJyEC3C1Xy+|2%PXh1CAYlB9?r8R)`B`ZH0ez%cQDeQMDDVHa-m}ywaG%LzC@hiW6(ouF^<=fF=&YUcP+=6|pA|Wj%YrL|(=BdkU z_gHc|n&4R2qqUg$X|yid;dRh5_o{&1ETEJ9`RV7qBDKR_4ke!lI8NbD@96e_UZ1S= zznr0CmPFcQ1PQ ztNdoWr1{;N!qa6#$#tn_S(IW5P9$fm{@Ae*GMpca=p^~_D7fv4(X74ER}o_+l;G12 zdz!TCN+hzHq^qhQ*minQiY#A3QaX4`ab_nwBnSMoG)V>Jiw@v_Ih%n$si*8)pVHjO~vQGg=nYo*#CTk4a z)A8+h*Tp}Ol-}NgSdk-%%EKRbnuL4hxg@_<1<7`dJ$>Cq9Rv}J%p``ji#0hjC8?e? ztlw~q@Y9no|IN6g5BuSZb(C?i<9PMDBVF~>^h34VsbR~=TlMbq92iKcAa4r#;C(N> zphpFf_$QvOgS?2F{HsS~{t4u0SGxYi*sEU&rSK{_dt~c zB_By4wFy&150}Q_9lnF0?IwGTVOT&|UTL_cm zkSGmUENVG_9%Z3=Dx7HZgkf!UK&qy-^m!*vT&8&tZFby_&unApI-Uq~W-gQv;%Oex zCJio$cDAdr8NL@0;kN!d??AvulSntkAFNGp^`4B<#F^9J|h**I%OZ2cg;Fo3pXEBk73(>*VZ#DRc$Y!I`miHvrld`Nv>=Xg zH&Tlxtm}_HMD%a2IjLM-r1e>|g@_fv1ORNqs^sH~>@^jg_9Rwb)xx)80n~rzXnHt0 zI*Wq82VxxMB#Ye~p9AhuV~tscNjJtg*8COoRRcKu z(^a^7TYU66V&UI$LcYJdK9q8sEyF`afZfY38a(jGVcl6jT5D^D2E?ZkCT zfck6>-RW*_Ihs`B>U&;|Sb4=mYcz+hJNd%8c+jin8{WApU98Q8XQ2xzX)kNl2k=Oq zBiltPyDf>66pL3tFT1F|JXf>TIA>OZ!F!#$MVvpN2T-d~iXB_T$;KzfGAxT4O% zUnXkD3eck1r=66l*jfcUZ?|r!;sj6}U#$bYA@4SP7$GB4edD(bJPfuQtH(HX8!PXl zjD^G%GRQ_ptl>6FZ4Ou&t+YOC)Ib|~d@!u;DwzKuKhiPLdsV8MZqukF`GA{@6 z0WsMx^AbPzS-5ycJI?Q<;=WE2CA? zpeyOsnr_RO? z@jrwp<`xS%xI5Cbtgek>5n(-hKQmeTO$m=~s6TNEZVJef$YyjN>WhHYBPl zSZ$ulR|NxjfdpL?J6NDsMk7At-LP z2bag#dwB=7xO%k1;Dj_Roi;0{qK?wLw?u7f4Zt~tk>S!78wyI6A?&rEU}Zk$11@rA zclSSylRii`p7vHt1Mcpzo!%k$-l2E10FvhaTRHOPR<)Z}2YB|KKJaw^O8T|jZRW4v zjv#h{5lTB$9qc}s@_~PDM5vUdSdxY-XA0)nNB@hQGdf0S#M#sMpuA_KjBI(k>CV=e zPU^JWufJsR6e)&}$nnb!!YW^AD_X?G zkuySGF%E(FRQ;*-GVoyJt0@@oBq*mQnLUown z%6#Pe1WR*&d(sdZ<4Nh|Wa`6p*eYq8wiI{WJkyLs(F2;wWz5115orZDIZgX`p!9D0sLUyD235}Ri{ zy&U_aG0iM|kh^DcK@8^8r@WoOq`bM}fB$$S zJhpRvEsW@JP?uFXn-cGF;M`l#k3QgHXf*TmFlLz+{`4aiBaG1*80ec^(zImO7-^-R zh!xS58&3|Nofg>`+t}4PaL@7Ny!HMK8ap)Fu{T^U*wL!_4ekm#CL-6BIC$X)IGE zdfHbLSi)H`%~Y1obtWPsGRgW5e<`Roz%?v!X4Y&?)adUiLSBs5DFrt_P|?JqKKMrqApb%m`NJY+TtKa1mV+Yd^bg83 zAXnRHd(9a9Z9gpX7IQDKl}wKcI)?11HzM_-X|Nba&;Hjkn>VnJxZ{GU5{o@$@G3nLBr zz)5`#dl5bm6+X{hidw#u5laMeIptx8oJZdTQ$c+|6ssD+e+``t2@ z!+|P!g9oNd-!A4x6OMVuPR!D7pOtSnD|wZ{&6l^2e{^zL1}SR#-*eXD)O>2(Z<_&vodV%hXuRyGN`)KSus*>d#tAk?xwMX|YQ{x`}X zQ~%iDW%8T-QZ97e9}sYy??1QbSvoMF%lu^cnP(YUFnc~7m1$61Mg$7)`ch_~75nT4 zR&ldf$6mKmWIUg`cW;8)`>w>Q)(T_6D&T15X{koEH}X1J7FB4=rBYQR)!T^^GLvan zSJDztOybAaZ&18UBa%TvA$L#wF9K;w%6`RC4bzm5xX>Tl52=`tTNU;c*HNqsXc|Q= z6qnOC-c}>?>_{RiG=iAu$kxVjKR5=8ik=}?Tk9Hcxv#-zEe6Jk4ruITjKlqH`(~Hj z;{n9@;gP{iGs2$4KtNptF=Of3QE$bDUyf*RaHhyvBh7bZ9phe|lG1VvECHh3ic}SY z$l;qLls@rzfPFKlPG84s8A=WLej2MJ+cucgU)u&=mywC_OxdtUY(6R$$Qu<+H2VL&VAR= zUe8RXrzdjmC<_zSM*+fr1L22!WaIrIHx!1``-l!hfXvM{OXiAuJiSXDEI?U2I)-uo zA*wPZjs5WQoUXfS*677n#k`oe-&FvskhXZ+C*7XVu`t!1nJ#Ry<0z0w1lg7myloNW zAZBa3)pby)Ni-hkEHtefK+-?k?J6wTa@qUXjqArm;(cL(xddGcB55GpkkF`>r~hwX zrHIsmkHCG~RLDTMvx-1<&wDd9Et7z(y0Ob=8P-%7p#ne=P% zQ(>Po7O&%JMb-1eRktq73gxNKF~Y~_f>q#T4vb^bZ=>P(_}^_sg6P9)2)`f6c{^-+ zMK&{V%3P17O^QqnEs8A#m81%BZv2AxCdu<3(i~2&+8>~frXDPL-!B z2erf({AZfQ%r7loJ9j;6n(;MlX6>P2n7Cg;>AjP$Y!-$!<59XGux0q zOA{VU5cTl6yeLQktQOYF2hUBt`-sH4B;>SxnC<6|+S~DQms7qC@>!r|huzLzUxtxM zK75<8(mtL$mA1~5c4}?`%Kj6i{5r_{E{BBi1G#(1Og6WpBD?P5x-Kf0Ycy6oh%?7H_<{cdKbX zQMZ#?v5O;NCS895QoH$pz_`c{5FVX6W>#_|>IjjMCSiO&0 z`}MX~dfhKt*d2DM@K*W9g4faZEz$xcRlm++huA7J|H*`r_^Y2e$@y`{zptzj7JMCJ{VOu7SW;@Gi9A1xybm@B@*T-GPyH8pf!*>Guq%XI+8PwMA4ZiT24 zeD#KEtiu1TxguGPJY8YA`F?C!eIGuS#|l%(g}&bd~4RE>(|I;NLp z5ya>{1OD=PEAQ>*LM?75v8DTuX^Ts*o#%G~c2}&O`EGXi>nPslhvC1*?h#cC=x3D% z{)kQ|z$;vXcge4@wY)=j1i`j4L)Ud({2-g!{*-BDe)eLMHPZju$(-V&Q^z&Ni=~qW zgmFi;B}`e`bi{8A`;#+{x0K-2%2HjG>~0Cj=e`0KXgHiqLOM*jm`K=O}N z1SqE~@uKVY1gas0xQB>0%6TuX^fS}@sKVxV+joq9?O%64)Pk*Qc5#o`BwUR+J$*n* zhlkr1`JP$ispsI4A^9raZQO{UmU+K(QIpkIty6lq<7(9x|-z^OJYY?+LVHo4=l6_Jx}q z*#+goBE?4AEBf8(ws%R>0TCcSJ=<>L>S=pQHuYdX{u%z8!#!|cVfrT=n=^}oAL|b) zy#rG}=iC;?6`k|hgj*E+)HFm!+jK)sKqnrR=6(NAFYdu88*V}{&Y>7_0e~Yig9e6}lSSW*g=7O{5^(90Q&xbS}1UJXjsnU_;M9G|;X| zFc>;|lXOPX7aJZj!^ z@XgIi>}Mu|++W5aJTtkx^;vA6^g%ASl!joRfM2YgY?}^|W%ZX}2D;|POnij7?Tc9q z!o3Vbll_2*h|s>_@eDhM(B3!RIdUy&}pTiOTm#gDcbYbGgwNz30O-IjPFM z$4Q%I_3{}p;>|iTR8Mwd7r$F#Wiy9i`1X*~Y7-Q}tu8rLafTG5^q&L5RsncQ43Bx}D>*wJNBOgR>Ng!Sf z9Cls!jNiLy+31a$m#yGN_W0;c~RLVdbA!!T`2k?3R8G?>X0w-fcO3_)-DWH!kMkvoBps& zF&%J8=ulQ6wdOkz)cRqua z{4cLh68$Hy%TXQuCdX~EZW5tkB5e2U7_0d8N2uMmq1f%+OVN}2ZkywcXYMAiWtyMA zj$*3XJttx8Z0BHCe-g9F4PmwmP|c#e{EQGDJeiGT!#1uhO{|4LvQtVJn7&TP@@rsz zIb&>bQ=S~8yWy&FR>rSe+=Qy!d?S92_F#YGuJ@7biYU%RG$bWe_Q0V=ny-Y&WLbq07 za9z;8pOy~qlF=^~#Mbu!L{9XA*qr-qQBg24c4 z$%h@Z{^DmDGW!@+Q;&+eQhHW&*;z``P+PSCM=ytV99yp-u163IhyUbEi0_oQecrw; zYO57uzU0S&LAA^R7hba0y;&_885HC%3v$QpU|i5PvhyiiQIu#`8A zEG-cBxXsB&Y}Q7*t(8$ER^Q7!FYS{OlUv8R^+24>m?y%4$DS#+a(47`#=dxDgQt`c zb!&@Y48nDTFlQFY^BEFZyPwT(#c!HWwLJV6uleHz?m1`qj>)<|2}mBbQ<&mfbhjHH zHKb|{`N%xrCRCTP`=EQY6&zvwcTPYiT-b+j7D9YddXJQ~%9l4_x#1)T6VWY=Ou5k! zzQVM|BkAIeM{9J#JPmZH2>?S%{Xi6FuZt2hsJ}Y4?82smdF|OzGsmO=&MUeXY~jj4 zsat~HXnLuLzm;FL=A9)v{NOR%>!{j?olX*u;qXn34S-SAj~To1DzKB@)7EBV zrjPv1_{;Dj!8m?iV1FWrXVX7|t66ew2O|yulmtnKyhy}*NNG|uGm03PXTyyu0HWX! z%<<{r)lmxg%d9gS6-*1kwv!hkomp*+byB=M$7hc$7~VPTb)`>H0t>|ygWW)@V?cl# zOp{rDc&xi1!#d0jz=`br$e~)FpKN8}*mNzh@YgSuf*@{4X-}8>p1$dAUtdKaygnAG4NTJPt8TkZ-bUX`q-#@*r#n+!ef!r7*SzM<5|x8f~} z-772#c?~rN)A;mS`K|)p5XQFHYVCx?_OU+Ss~B93szGTQD<1%u=W^3J72)zXVGlm5 zi4T8=;}|Pk4o7!NDV73yoIx0+49Oe~eMg%DX_!UXUz=&ahcLT2!G;V%LLPpsrLw#Q zTAzth5IzM_qOns3w%?-_Jfy)7L6pqzDep~ zbEkreWy%7J0|vJ!iqa6OBacrriP)a276PNs8n^UB=+0gYgD6{5uHL+PK_dXx(4@Ra zY`nn75$MIlTwF$xHc3h*KsL* zIZ2+#T>))>GSL8lE32VyB}*W>Oc!}-U_w79HhcRv|L@Ul@puyEPl5%w{g+~4)1-ap z;Uby8&4Qjw@}dUJT&yX6(-1*rO;%$LcdzW_ch9e^OTt&t{Qi&M5|-4z{JsVIPku*d z@t}q7J|!TY$L_SoiNuSEP;jeH_x0Yjg#R9AqA1u28YfA25R))lM>vY1?m;+zh$^8k zXwu@Tg%D(ZiR3L;>-0Y~Ws zqzYZzZ7=!;vQ*5zU-~g4`cT;bBCh?}(7RLqdL#^eBJa$X)8IY(KqnT({;|sU`b%py zy6!Y?=@qBHdqv!Vfh+2DTc6prRU1zKywxi%PAEDiy!5|bMU)CTnWSk=9Ajv-y4J@) zUaNf3INTIO@W#w`QQW5fT>6kytgUrTB%Qf@M-0}Y>;ChmTKSF4d$EM3_xI0O%FZvn zM6wS)zLqto>df9u@+Vk$BuhULTXzRa{{Gzmen$PamZhPCn&b4ud&G3<=1fxlV`{@~ zCnA*}aunf1mJmG_cewqPaXs_Y1T9Py&pdGy9ZMAALu03{#G6M(u}d0UrDPV|9ct(4 zeO}&q)o8$*`FZn-70gY;9B0b_@}OLWz>efOXSrUaK!D}KOC@@Z*uw(pP{?Op@^}QSXJX(IrDP(3?!i6n{PtSC(l>#Sr1B#W!9Z-*dV1k zan9lsv(|ku{6*8?$dKF%M`e8X`Xu;vk&&B3{~B;O{dizpX`}98GgKvuDLZ-$5E|WO z`|^W8VgsY~$JfVb>~t-JbCuI9P;Ikz->U4r?ot#=-_?aZ!i077`a?S^u3JXH$(on6 zYpSW=O$7$0?@3s=T3iHvt227Yk(giywSo*;dcnnuW*ha(lt=lc?;lLR&d-YcN%1S~!{GunroP8>m-Sr^<{1-2}<@Qp&C4yG0}V2Bp=( zXU_be4c4AGToT1ozdfM$EJ(J+{_ee zYrsVa*;gswFU(ae#}{xl(Rb6UOp72Lib(6A5S*izeHmc#;zH4`pDpCR$@vyPOTG3U zMJ|dOB9P9(cexHqaz8yk2On+Wvq32##xAP?ML&e&6#mdUL^O`gDL-HdY1I%(LH&Sh zIlu*_Sj9(a$wC4S?3WWRhVA}f#6KGe&2>y|fHhD5wB(EMskN-~O1~$I_x;xI>k6!I zCwezYc<+bA|L*jLm+}I88mhVW2b=`fm|1nI8IueHF&)W0HR-i3kqJOBxUD# zeQ(nLeueKcvSgjRh_qLZe+`|A@pc^}IG|ud*Tjy)37ws8HbLdU<>X%4k5RR1-}WH$ zTNyQXrz?gZ8$1TnlGI#2Qxi3N}E38<{|k-*oj^DGqzlF?Bz1ld=wnvMT%F5 z#ttnqw*+&ZvORftb9doRd8*1NOV{egvNi~4nOo98wWMLFT2>>uGj{o$vO4NeNab1r zv&O2i3ls^ntgGp&ZIeOpN|Ks>QQK4bZ2l?Hl$!XZ^0U}4_O~Qt!8b3j+dL)93a2b@ zP&j96MP!mss{K|<8TxP%g2tk~F!ezc%kGRB0E$=6Ih}Q=O)tGz&3oBxo1jFqMA0wr zLGO~G0y<4%iJf3^RAiies`kjZg6Iuugq5T>>#w&0f8hTtzyGf|b^pKqN8?IX-3_b~ z`NsL0<~n?)BKB-!0B&Y2HjvrbdS1U0**$Edr1NPSAx+GP(!1+ee*MmwBTdei;|i@o z`M-V0aToq!c&ak@zs`{yJ+;Jo^&ZGy6doO|{|{oPgfl8Mx8I;n7kI;LLN zM)pFC{)qn5(s#x|uV1v`w)-dM7t&~5k} zNdN%&7eCmj?#Sgj^zB}@`$WB~QlXkedtXBRx-*+8Z6$IwNgMRz7;`iuJ169+6e(^d zkC+*QBYH#&xfy+PEOnf{Nn)@|rwgCrC$L6NoLG6|4VgI9tHqolQ8V9s=N)Zx^}c|Z zt0<;SFBdHP&G^Ald?spSYf~K}6Fp6joTg|LmIDlE%Y7f~ENK&Ez4tNfMDsh4q+uq(aNdx?=Va}H6!O+3 zYeFf?8VXWU=*@UjaJUV2eAhFhHUgG7toz!@rd8|I7O-)AOZWY|wB%M%1-qt(+3-WS z)4x{S^sE0Ezoxz8i^1*>u1D92J-WY`e>>gYUNgbrtC)3lRi{=4{7pyG@g^@3)qEGf ztFooIot>|H9vyw!xy+%ZiP@rI@23&b#|yL6iFni1&dQ(%ps}Cz0Jhq9$*@n z^jT+wGFIAGGRxEd`U{UJW4D%UZQy=&3?A?x627 z0``4pdXN#K)n034LGtCTQ79ab8ebih)-|ebw)w3OxP~8}&WHtI#3XeXg$ z{6u}8YVkx>R(VO76NyAp8}tKNl z0_Anyp^c&m`ug1Jb?g~&a)@8Q_ECWcCiXuN}Uu123{3 zV~Bs`ZTh}n6y||tYBIX_I4wWeCMhm#PqfTwuP3>4kn}0~rpQ%G+PluJp^W2aDFnp# zB90M&PrOM(m+x`+ha`ubP9|yJ}C(d?!@H(XXDOuXW#RJ?pv(wWq(9Vd4aFd^qHQ zs*mJqAA)m+Ld2C3t!Yd{L`n$c?bvEwq0fYJY44sHA82|HRn?oOWzghtxXnzNZZIav zpXFAg?cgT-aV~{OFP6J2F9SBQeY?`;&ri<4m_*t}BXS|(K?pnE_*7Jn&pn>qt~z6z zrBudkhkd)UVo^9IB|Pn>4a>GqY;?m-?k#-nG3y4VneD0D_mC~m`IfV_Xv3_syBZ$; z!7CX*iVZHerL|era!doau76ymDU7-xHp<^zweTQHC9adMg@uhQUEpLHZG?5`rkg?_ zi;3s6S&auj>^0TJN0QP5MY~!p=S>kVtVCpfm#gQDOdnuAF_Llbe@>dnVjY&H%qo3q zIN&OZiB_!a=@DaFF9Bi4m)|pyM}+&8)^+n6FV#5;P}Xlhu~`{~qlN`7onmr$WxD+K zEgea+t>Se-1s^8EP7H<$5C|6lW<$k+HS1rGB%qqw588*jBkI?21!cOmy`pn`U;WVE zmta?Atha7noMqpeFy}DcHh_nkY!=Nzel7!)QCD<}R?^urjG4E8AFcwP+0V9ES(Rdq zgXe%%@-^cT`&VYVYX5bSW=8G{NaRrAGDC`oF&e8cKbuYMuD^${6ZjCeFptzWiZa1z zTjQ6w*dz*!dAr_;AJ63)C1nI+_txwXQzK^lSP)~URUyR`SA6WZ^a#d__)(4zV-`G;V(O&g=1{NBo(*BMs7LK_VV=jRG`4%%J5R{DM-JGJbBieiNN=Nm`a)dvyf z@X60ocp)bFc}DLT@nd=mR1Ri!+vTgKivzyKGMa`L;m~HxKD)B_7m0VhO^~e-&(|nf zPA6D=N3|IdqrPvcp0Q0E#ozu(T-QIGqmfouS4P*opgo~73>%EECGbt7*$W2J(}N~* zM9QtnB^v87Vk&~e`HuPtrog#u9j|=lI8qzexEC|st?BIp12svl(nmNMk>P$HxUA!MVM5%zLi_N1NpVkZcyp;@#JBLuWt5VXUCPb(Wn)f% zJW#3CR(Q(JbhNCEkD?vEjMRwMbe;GDS;!uKyJl3L?Ky-ztR;8zDj^fz+7RdH{_8%T z_Xnaq@eMZb&=4f3IBefBks$R2_?I<|EJ4_bBaJj+0;COA*izue9;kS_oM9itg z>7s0W+gCibVW2^d*HB@i3yOh;vvRB`8~kx$?KJe|JRdcV$ORfz@85krj*w zHuTuyQ&gA8a;2VmoovGKpv+7DcPL6|GkSrOTPb4LJfh*ov8_d|xLaUEpCPJR#{BZ3 z!TN^`qf9MXzy!7UsQa5j-Wc{(erH#@90GGx6~?#I!vjk`cGR=P9{Ts@p64go4u!X_ z>&B0TUm@%yB$!dTmHh&-;U>B{DB;X_(MEJLWGCJxZ@#aN#S!{@w@#V2ujGa~$F=&F zjh=snn6hgJ5}c9T*i3>A6X>{LW=TMeHdugpkR2jz(t`HOc2=!d6Hbi%Y4 zTnSB?{;@t0gka%)g=$hZ~b4=4R7_;rs89q z2Fb-^RYJFUv$B;T>||FXQzFawJ_4u;4VE>-I%-{s(n~uce1_g!^tZ+9q!YQzPv#?= zw8x)g1+-6ZoTG;$HcOcN*;qeoZ+$< z5=T5RX_@)XW1&|o1mC0&H{LM~v;kN2+tj~~>G`u*8BrpVBq3>n&gGko7#2R1#04!B zbobxp1{ezZ#UDo&3mWc|m5H%ClDfIGyOpUq2d8EKvfTf4^!`8m2gppG{J-%`p8UV> zOdeX~|N0zIj4iA8eFlB~Vg8cI`}X{@m4)r0khLvHPmc>SlZOSc|JO|3@!#Iw%lUuy z_WU897MbH)LR31z*h)2j+>`ji6NA;Fi)9{v%4WZ6Yvi}I=-g}atp7>tXl&P_(Ojcp zU$QdNzZCiM2&U3FYXRKI|qFx7JetX7(l^-f5k@j$n2FYbHi;T`*vGxfO;Yh z*2!gP7oD$u#cZ56Z(rk#*y-`1mPJ~>-%N*j0!dZx4FPz4Lz`EM{ojaqDyEe|L z?n-MXh`G5kxTTL!f8jiU6FKX{C%JU*oh0U*E2im3DUsK&Zj-cYCr{v&MFI?F{!?A7 zk##AB!<~}K@KS_gA?*`Ywh8b1ozcf%$L3N>t(+bJ^jY1ZcSg=*>_-qh0xLOLMM-3C=aO~A|PjAC|nu+caHE=$X%Z(BI6}uRbk|vHa8xo z)A{`!hbT&JY#-pg(`*n)VVjd+;p0cFaFo}+_;$7GzR$!ZkYjcEH#+>mCl>{Bn&j@w!z+!2~z<322_`+=ID} zNZKxLi5$ypHCL0?p=rTpCfKmzmQ(}d$;tx+q2_&NJmxA7;tQ%iycc4WA*J^Vm;0rG zLzB!jVK5MOJS_q@7vf3G?J93RcvQD*5&i&z^*`kX>ZP-yCYqGDM@`poC4>wLkCCH5 zWHl>Tt62X@G~=E3nFybMMU42KSP1HfL||HbXkaeRO7=S3ptT$|ZMrW>1?#*JUh_~;Ay`|4fx}m5Fa3Qe zMO~8g#~ZqWw=i*YB$;e?aDh|T1;*A5;YLCf$y5JDiP~iX_y`*PqSxP<`vd18iBE**`+;ABHq6wuwjHYG&YmZgU?9?C}FQp8a#Ix1uny2okh$M><~P~<*y$rS>&}rMD^AuS{6d01sVhJ_mZ5>ARhVsiE|)?oj>CL zXkY9WyH+L#B?#$X}MEs;Pu0>1DQnebw)vePXAti8(BTfWatM~IK4z7gbptGY=d#m#-$y^MBRyX!x5)-~JIi`X zxz>>!MJ}WGiIQxaufhi(HCetwL-Mq<84k)_fm=4|a_%5DyH~kU@H^!ZJHB+!B)Cgo zm@S%ZT)`P-1@@Vmlk2~IU}A^N%+n`^mz?>Vk2Dl7RxtZIh(M`+BzQAGjz zkYhQAwBsw{`=+Fk@TZ4LF{;+rU1|9=$_(ur@#T$Nv$ONqb$U6!$P|~1d*yp7NSa4d z5(8w=J^D5hZnE1`v;zmr7;|8GiaN5ZA2?2b2}zh#k~xs5n~V+qim3_N!D#wDbf?G` zso}Wg`*g*m)=~`a3vWLMac1v^$quhqkoW602@v}F&`TYwvLau8ky6wJHC#i2K>6svw&h!VqtpJ*J5?7U2d(IF1!Zq{HPC5G{z6evSO z?FuAm{xg5k>~Rq~z=27Tf{j8-SIcJk0AVL(O1GBF!wRBiMpW zeHVP$JbB5<2GiO`Yn;mu7#~4|g$0sE83yTtQk~Mi?WYUygVC$NH}7G!@WMjeyL9Zn z(R5)=)+f&F)E_J>vl;bcZHriA3aG_nd;p4NJ;8FW%4WUbEX30QU>fvWCq~GPT6(th zoc_*+$)vI$oIpTe->4#7<3wj#z?VGbYOw`L;@kc0l92k#LWy#>%?Vbn)9JGr@pc|p zHQRCdm3z^k#vr2HK$JGKX4MSrMIO0ss}|zI2WjshvrE1S zb+T_X1jvJ>glpc&n8LXQ$)F;V`^2Ft0Ez1YoV}bEQg6IxrPM62l8kj@lHo1Lu<%&e zUA%}G%(worw=H|BgNq;rAbF9ORFWr9M zYyAo`1=^^zGOx@KiXrS23OCEdNihvEn5i(spF@!mr9}}HTmmSYLwZoCCmPogS^a9l z@OwT@zgU(|fxE_j=Le~$9Wh_M@aOSSynk?{7scBMT{i65HG1**Mg+K z@a#$}1+&WAbfo!1(9f~hMNxwIPNo`E@Xta_-16|0_^bur+D7g-Yrtl_ilF6?;PCSxsMAjSiEb}g zD`vuy^?&?{?v@kJoU<_x1Wr&1>?S`s*##w&lABsxd*&;W)5&)}q4g&RlZ> zF(mdj2Ry3oZJv$uGrS;nc8cQY?ep+sz4uW_34dsar^0SE6;13~+jrO7ljOS=Jb@ja z882srtEB>m>W)YThNSWuzuOV<&+U-sj%_Oq9ARvGy_7m-OrBj=y#?BV8tFSZr3Wo{CWDTMg8azVlPO`T8FVq1KDt11IL&n?K_ zt1bz?0-XgYQ#to3`p$r`T%nd^p9>hy&NmHg$Fh{ndGo7BxCkMEvj!Iy2jHhpXX@a~ zU+ufU#Z(M|MJ96EoCECJB{d4;d-x`(L<$yU3TZn>Atzii;tcebJ$t3hFttW%Ng*N< zfBhqIkFS-?ezgF^0zsp}y%L}dCYHps5t!`rcQgrqFGPRN`r(%JK#BuFlx4i9?+D}&hh z+dQ$i`9`(&S%s(H;o5A^#>kA3uTC62R!A?-ILwJPnQ-HAuuzWoe8mC_3MC2r*O@O| zZi_f(9KkJ_7r>9fNy4U=eR!i5(pljv^QJY$leR=io)C82iv=N)N(h25@#09hT|t1` zeL=Jv_~G4mRCsb;xVmuhXwSO(nR7{bi)AN-I_EwplrF;?({5hNE;_IJ*RE(QPn-p& zU*vbN2vj$CHz%AEu8^}f2T!Py8deKvscu46*sP2dFZlBThux`4P5CE0SV%tA0JQmC z0k<#{aQ-)A+2~#GRn%tPr$0dmKyww#C-l@t9a|zs$)uVc5n}t;usi#J!Q$F90RNqL zAPC0*Z@`EjJ@~J84jvk>=et@n05oSA0+&FWAADlXeGdVqjy<}MKO~+_Y(pRJ3heh@ zEFV1>Kk#x-PXm^lu4;l^Wx>*I$1hhAos@k&FhpVT8{#HYacB^B{Ge)1_U#A9 z26zkMko%GZ1wZ_4_@hNbfAO0XMJ6Tipcx6^ni`am{F|HY!G$=UcM?#_>7?%79Qqj#J$9RI~G_COtQ%C%yoE# zzY>4E30E_#P1w{M)$xt2!ZneXXCBzV={3f=r}v~S90*`0lxhyXNMZl+k*Nl~@;|mN{J<4O_k(O*aqy0A69X{7K|z72en7||eNv37Z!Z?jqCAID_3vGq z|9|h^u<_tE$V5Xn+DT~V@#AITTioLsTM?0Wc^L95@RIsH)Q_Q6Dbc;}_k5cI_Y+C> zbfSCU$pmsj`CA80KZvM-9p}$cP_SU^TuW~Y>D`zflUm%ar}&g}|M5oq@VCc-*ZXge z11{=cotG5-Po3W&x~MWE4A3qv|604?XK2eS5lJ=*I-veGVpgIsL?YsR`;lb|6}it> zW~GIbLc{$h1K`6ovybBX%DB&R#RJfa<+SE7j`JETHd+#4N*<%^#A74X+F3mteSGnp z{UVo_d#)x+jq~y8jkLqCgSGHA-rCSW{Y1dI{qd z+F(6D1bObn+l2^wGbAzTo4Sxd^-h#3@LTn8+6S;CPFO7Kj795&6auWi*45(MYc~N8 zlV3snaZjT|>wbqfm(_f|RcD|g_n~&6Nk^C$;pwVch=r`|wok*vx0V6){^O~Z z<7&j3Gt}!&rs}ZE&&#dz>hwS%nVqSD z+g6LWCVhP38;4)qcE58GN0si2z~7}eqZ?KyQakzT+lDaHA?zdx2j{GKoa>vJd{>z% z^q)YzoP{-#K#|W6`oDATJjknOFuJj<^zVB!iR0*`hxM6Yk?8VxEAr?5xtkk(p#Fe zgOH<(OqHKQJ4m;G!Sn*cPI`?%{fuQV2u5+vu#WbDYX@1Y-sNgkbdv>9W5W|L8?_?U z6$`f6ckLTbAm6XQvt99Wgp41OwP*jRJNHV_yFD@~3Nd^L^SlJ=_i_)2M~#=5r()!y z>F~mH>l?F&?n?}2^HapIC{&?UBVv7lUMle3-JBIAhw<(DEtN`ei<)Hw$NbK9`(Sdi zM*jBwHVutleEuJe(V%Kb&~pvzEHWc@#Uz>-wKg6qRGGgY?`*mwXBS}}p=YQ;tW`L$~%31KJy0?>80L0rEZx73N2LHw`0_6ypV8qVB}YFWWX)TT2sBq4B`2fPFT$7bs%v^C7_%K_Zv1OKG^;Nh&t`CdS3K_ z$2U*a`w<0#U>25{bY6rEzC|17&++npmrZo#Ni0jwB*e7iduqefDI@Ae&ePzAp=Vz; zW0?QzokQUV8zfxKt3P@EMpTIbHDwzs5~yweBRGWsD+w8aJ#0@akP-@gVOqitpq~K; z6}F)~s>aL3FnIo5uGpMWM!B~!LlF-kAF;rX6qwx#1DeOR$<@=zx~wa$MCvC_3=)e| z57P!Tz>3q(Mx@19)AZjnDSEQ`2^4)0SRlk@5$q@b4t0Rv3R?LmhoyNd?1v_Qy5k@E3SaSmu0Vq5+2SF2KY)T!~r2a$lP_5x`j z&mB9zL&eGx2hpRh-;Y!8iSrz!R%{vU{VMH|*tAN<@4!a0_oK7Vd3p8eGf0h~lkL2P z%kVj=9KR#8bjre&rX=$9sf3|Z5X1g_{g~bUAVN}k9+VF&oDv^iV->I|c}&zUM;m{_a3YV6l$X;o~Cv4Cj~iKniXVmLv)?P)~?_ zR823Y@jJ9%&~^o|Hk&)B7*GZP8~yovq&>UDNG44<;gnsnKmmrsoioax zs2{;U5B$2ujbg@W+^0z|z_`AtBxfNdz)^$A=pG7-W^7eEeXsoRASsn3R*uOYUqd~T zI_b|ef8<#K!{;Fn^^3wNmVhZz<3;lQiRF6@Zfd3g4&!k8xGXkG1AYyNk;5CEv_}@l zd$Pgqrrj4DtLoR#@mAI91P`Wsr0;(|3}#TD3BCh0|M^v}&pE9VYzkq=`+I<1G8KL$ z$^~RmnRq*%=z@-M6nws2wCIH2{9^8$K{I@XIv-fEz1<`*g?Ud4YmEO6W@f19a}Kx* z^*8{QduDD-xCX8f2^yngfqaC~0+#}S)ume;8xb6jl^{Nc*3E*@St<6EY&eTb$1ohhqO@Owftxi`7PUvGSd~(w5vKty&IS!}a z=o2>6pXE4Ap&$56yJLvLz5riT2s{3$)*plDxG;6eFb(Y5$gmP=b}~I(l==3g{w$_~ z&z35lKWVxIUTg!!e+y#;1(@*p@^-Hdtd&5MFDUo#=bxt_wtQ>5sYDcb#VX4qj8H@N zf8OnYw+O}u+dW@Hj?X`}C-$)%hen-YooPHA*MEf92rx68vwAl3y&@qelW59VqUzaB zfYY{!UOP8UjPw1Re4cVm7-h9g-V}(w!r_oq;b3#w++Ivz{yGFlAa55VP9fbA62CS> z*!d{`R~otU5v)Jxy?pz8Dyq<%9o?j68ofM z!+4#>sN#7g6OU-57@-npS83 zc-IsD)8h#LS0kM%{!=3%JGYvVdx(?)*bswy_Dd{*A_|RB2_c#4;Vq#xyNG;p8sJuw zQ%?I#pE%jkI2k1U=r@yR(`{Mnc`EvkM|^f^k<42%~0#~=2-2sR?;Krkf5)yxZ3+QvBq!iTftW>MenOHwi^RmZ^GAuo@-FY zZUI`ELos+pZzP-hCFA}87c$p|(EhjGHK+LRJJ*IH!uDA+Tr$91!UG=*Bav0G=SkVD zPUwM|TWYGltXM+z?gv5p05I&HFJ@LeUR&*+3R-QLOVOi0CY1WBhe^F(Ycyt^_6wJ| zKXl_~?CdKTF0go_g>2*rgShIa$YKWj#E>7Gj&zHh*sqXlcTHEO-xzoRaMzNIN|=`d zn)g%lQ$KHzxF?A|sfkLlc9aiC(JKjs?1%J$QAv!#0(|4GaH#wUhLO;X zk>I6T!B7H13K+?AgVIzc;KF}<`C=DMW$J!f#19b}Nd)f6GZ0>Zh}@@dAf$c+M+Y$j zTQ**7?2eG)m4@1Cc8t3M?*@;rfEZHc`$=M9Cypv#}J z$&S6-{;@3*by*yYXCg3%xH`#-?17zGCOnZSNyAePc@gUR;^w6gb`o)ShAZ%ksp$?H zZIMwiH+ZKVJ_y!7kYg6M+|OG+Y>^QY1a0Us;NwNGEpA|T!f?jRsK34~FM|Oa)Dnq# z*&IC$zWuJlhqZ#pkC2Qcg3W6@8LOgtJ!N-iYVQJ+q-nl{om!M!kUU&KFS3lqCYMZk z3}w(gg71gD{Kk%YyU>1zHsc6I9uP|{oS+GJWBkKQu@KN7V27KV!zCRisaMNyrWy6M zS@l^m`{(Tq-wC#v&X<#6QUHXV6b(+Ko}>CKkRM@5Al*8{>e;N1gjM7%Fg;|{hCM54 zuXtLa$9*pmUaE4E=Mn*({p+L!BG#nUA~pac?3oBvmMDl{B2OPNnDR^I`LM|ndottX zS8vASfw|aUNG>bz2|fp$TC2p(wW*B$lT=MA$!pE+&;%P__oL_q~JjN0zuK3HqhVuP;z=+&sPYvaey|v_J_=wX4MQ zE{**W7Pfv8Tlgd2^eC}*3BOI;H=1p2$PS9eZ-GCzFH3fN?;1b9eE5+`VEY{LP3Z*_ z2T{|7|F^AJ%bx!yd(BUGrtpqOSCdGz#G|jC+P%*$(0NLw4~>CjWEAtlKEBt))BJ5~ zUp+hNIQ@-&86rQR0i@wE^*96gO^_NbVk^xg_1_@uO<*J@PXEQ3%Hg=&7Enl zLL!>ljo-d!foI{ehC?lAvbQk1-Rr~=?Ptud@rd~Jz;M|nWvmTXD5qS#xMPC=VoDpI zrb>*xFFi70k$8B}_oLnl!0p#ZgU5A5M&DG>A5r!`HY%TuD5$faGUxnS!p^Bmqn;v* zd%=4r>l9@MY2f7uZ0gK&l>y&9*sg^7fi1|+G)#tW-ZT)_0GN&vKzn%f5-6paDCXBN zQ~V-Pz7e@33Sk%J{9o18{~X``^SKEP2@CBgrwENC<-wftMd97I#S>XAD4JqD2}SbC z++C$o@Y64^K^_u^`6ZEyttR1*e|qLMTS&643LpK1vlV^u7{KK>&q;C}ec>5#>ioth zv@jCka>ZXCob){Q{tSFNb^>#G6Vtqj9u>6T)qw9rau=p7@M)lZ;MZw??w@g@YZ>DC zL+&0Ne|t*|+W*yCV*aUAH$Tak3$PsFZbg)rb{uf`QpOUzpH|C5Dq%lA2#C1?Ts^O9utpR$Woud zY1}&HD`XXxv@E0#KSEGn%p}tlMq?7O0Crtz`4Xz2>=!QGBG4hc@@LXW;9q^mZu+QE zZX^AsBH8|9(2beS6&Do9f?Srn5vJ*T5uwB)uX22$nioDK<|#(B&B(_z7_MmRtgEiU zC1yFVExs`KeAtSP?HERiB zdM^gDdySR%`u&_`qzod!WU-rh1oeW3oIZi@r`v=50^=^^QuQe?aD&a68dTwEn6K@2 zJGyI)N0%nsa8$4WNI#;oXeOhNItO&{A?!H9$uL*bbG#~q7jOEA4)1m+KT|{p3X`Ql z&0+A{`uIPg5_Fexm_m8dT0S^;fhG+%cA(J-YT*X+;`82V#iTu*1(h+wfX=FG(n=|A zM}ezvZ%DD-aRiL` zwNU}j0-kRKc?$Rb3Y^B@@Y4PIc^u5*jJfRb_oWTd_Yo-{mZo$j#RTHSIQ>I>RYocS zDae04)N$dqw_Z2ua2`g>qq@Mf&acIEKK3&HEKqv!Rp{zs?r(h^`m~eSxPirb{!rEM zYmc-kx}XQUpS3EJQQZD&*Au9MF@vW$Ut~i6SK53|i))E{ zh(rzARN?2`?uFs#`J7gZl~2RGoePecs5ISi(=~PlgiWJYZh^?3!xq#!Xefw;}!0<;@&RG>0GrGBPipysVcDw9KLKjK_0bIp3lk8$hbWvFZ||tes-631LkbBNub4VY17EiDt@Tyk`c;i^PP==a@ zcX4)`z`5iA{U`Qq;)TDFa@9f1!@jhu(C)6mWuj&seEZ0EM=Mn)1TC^Gcm~dm#tuK7Q@b=i_Wo;RpJ^Yy+;{Asrr*wGzf)`tyHAS(1V5Q*m zk7v=p_a>u%bv+OKpSo@Y(e>~OEO$z*U_O`9aP_1cDi!&}E!?DPBbn5+Poy6U>#^1s zc|S?S4!U+4zTdgbY0IgAoc+#ONjFq>B}jlPfj3{Sp1=2zMuc5ods~Tr9A9joDjL1} zl-GMo#{Vwm&*_L9_mQ=Y3}K2@5~#{a1SppJB?`{x0?#9$2CN z16OK`xbS&VR=F1|%a{n(-#tnql+xRzu|U~Vci(k7WGD8QC2-$YpOpExpKP5gAq9m$ zCmXDru0>c9e-4umK67S0-|k;|tEKFIl;_!Ny?J0=70@mgPV+8{{w7p?)7F+m#10y?EHX-J3bnsGq>aP7U!jvsREN_Je6Uz6|F)N+{jU!EoCUbBfvB&pHt?IS4!P z!YY$OgvRJkX0cD3FKme;-UY@gmN!xs<8M+A z9ReuC)=}p@nToMG`W)IQ*9TS>*^?yRPM21Sk%?OR35kUBrZJ`nn7gI<8SG^Fp&3q~g1V15`pghe> zh|?dYVaJs_00H96cm2|)qP?9Gyp(7QJ!VsZ5O$JtA}xH5&W#cQ-FLxaZGHIsl7ZMT zxjsUlX~pT{7SS-cFBUy8CwWOwcTsittORaxvit(G`W}K#7xP&A)HXGh-CV%oxtH+= z!b7DJT(J})dqA}+gfAkz_T5X*i3e63A{5COmTuzS@tA}w$b*A*aBgTfjfqks`m>+P zy^$@^{o~@gR8k^f5K&+NtKAb~$g;Xq)u`wRsEBc2JJ)#@j)7 zM-mkX(7_mlgN7ivO*n8btQ)dw%ZWxc>qtlJA$dG^6_9K@6Kxrpj~LmLbeG@BNCr z!7vRX&@-_{?XMdIdseAkTnIZkLcBFVO_nU4e%=M(3Cg`HqRTz>g=KQh_Tv=?an@@Cq~Zs|A76+;}&%S@LQ}k^U4I_Ac&ivWJjg#*t`s!n%4@tHCoVi%b{{q?7 z-tI!5C5ax-dAoncrw+{6&;LF(k@=h?ZZlCw&D|e8PD>c=FZq}gyE^Px2|2(2lMN0( z_^-YeNoY+Poyx_=cotSwVPH>m`|X9XM@Q z*XrR9CZCe3-yel1a%6YjNMLINGL}F2XtZ4IgAyCQZ^Y#eP*z6^GT*2!oEo%*dCPm4=Tj*t?=61bZv=Vo*wO55Ru(PQnr z{oEyJkLG;8q9ga|gZhym?%ar%`{f6FW1?S2F6{f~yMmpYY-dX^5`_&-a0IEDt=S@W z=bIf;F}-NRrJ=&iFARg1ZQ#uU;qyDY(Lh+Ie6(Ou)4RFynfcD@5EzXIy6JY33C@en zLvFv0@X69GIEyt&#SSC|`TOS6%4i^)gY{mo_NSA9FHFLjOZxarBHj>o>|6wg+$7Fk zM(_ho9&dRHOTMW_!o5BgqVLptdADz(;tRc&{p+f;soxv<^;2nU+lh7P`><^hg=ltR1ehc2dB<4yQckDJu8A}1vBB^B>MbY;4zi}6kYJd#pEdAetGdzsYB1a zFV(9zMmaA-^Wl%q*o%bHqkg3*suHyaqyYTV?7@+Y>A;_{=k;{&2AF!_Qx}nJLDc`97M=s5)iH8l&KD z`nGVXR=KYxeR0bTdpPA}&_F!(l#1g(;W*MYiD>lC++)y$B3%Z?Ym6>5S#G^jzBZZ# z0VNQ{^{~;QJunGBdtyB`Lvk~5H2qYOcYR(|+gK2E5MEb}(i4(HB)-1QWu$QHTz2t0 zj?w_osbgX8BcN$w?1-utRYJ2S`nFBkmZ~}~k76WmqnLB?#S4__(RQS)cp+}VX{1y{ z5+;kn+$#<{MLo;EZKKh`Wy5Q-ZGuORi_y10aZ`qBL=Nx6N9OWW#R>-bsA&02|GXC@ zN?_YrqHk9%`}-a?KHC&m!2Sdz(@ZXx<2R|Kqfg0Y8AfiHF+w9~(*!kYH3%>khcp)= zP_l}eVb(zUd<4d@AYx$|SPYtl`dZ*`)aCz!kYZm1L02w7!;=7C@a6&4)4sA&9iXQ}j!JQgLW4GJfmW>STj1d%LkK|laowZIfO zSRl!m`GhjCZA2!Aq%ewWh~7v7k5X4ayx43Us8u+O+qo$phI5;R31KHd$mhU{XJoLz z{3w%-=M{aaiGGvTfV0|-sEzAXb&*}Tk25jKFrE{FCqjsol#wZ(s_Sg*LHWt}@?xh* zUPk|mTM4NAIQ&zH?$_v$>xwYM?u~(atE?$&FseIByaI;_QP>5Mx~%mmx1FYZOympa zY%n^nb4jCXLOhMC_#YP(UE?N&F3KWs69?2V!k3z$~>Zg7+JWR|atxZU89h|gchfwS>sVaGh1w%jL}X)7 z1-lEenKGUK9fI!<;pB3Q2I)Mk{5S^6`~fAJEdm4m4r-%_A5eY|P+e!h=T>!n_Kh?M z`v;T%ZFTj3T&E~tq3)M9CcP=>Hf9Ru0mXWBAWfEsjIH|&WI_8b6L;syR@@b(6)mS=hMGju3*?=!A4kc7~_2DuATSO0pw!tx*g zS6}S&zx8!u{Xgq#9^r*%xH#2Lxm5V_?H_li9gQ3+EV4_)g4QEJU)9xXd(TMrYn)4J zI&_)arqty1I6x1ael6@;5|g4?g;~l?i36ON&dx_1q7&D??JfGwf-? zM9k-U+TqfWnLo}s%hp%p0Q5)8bD$#U55ChaKt*iAbanP&nh-WIi?0_TaX;%;ISF*s z7#gV#tbsgtl3PvZ-TUN^MZH06Bh8IqS8B#+r`TeB+1PW2xyP zy>rLx>wS9le9BlI&(jm^)y%Wq0`c=5jv5d*xZp)<-oWteIKM!^wdxX{4}G`zZMjMc ztZ}G|dwA~aWuBU?{7SfS>?M)wypP>E5beo^HHfBy2PK0N1z{(}00h?(v4F=2<3HKL z$v&aOU%|9)hqea62t95=(?LyBxs!n~5g+`ln@`A}12H2kRiH@K*}FCKUw(eQ#Qz>U zuTjy-Rjg1LrC#GTtd9?ehgMf#-^<%8&Vj{xu5TM2KgGMdxQ7T^K+G*h1uDe{`vV)p zXU*ZIL&#eKnvE|)0~xDD^u2I`C7YVdGEj?ImADDpfZb+cUy;6az0z(5xxk9P7zP@n zW9eABLXz2l;X2s>B@8nNJ6ZdI&n4ovj8b-Iu!y8NHmeZM+I>6Ol!G4AqleQMuVcTr z!0Zd<)FgR+C<%&nVr@kh>Qdoh`p};P)ba)30f+Y9^UVk>tt4vfhId z?)Yj18ol%yVlo=Q$!6X*;nP6m!Ek4c?LZ79NA%h?$^eu}0`}V8r)E=9Nidur)WRU5 z&v^)1IL6iCM#qC%rQ3~v$noPBG|mTiB&qyWZOei#%pCd!oa+kISTAG=d?E-t`EGoj z6*!=jHF$;7bGfQ^rOJXbz(BVUwq)L;-pO!Gh|?GDBhMBW_z!S6O@v`1ZX$eO?SQf8 z)p5IQ5#ih`vl*(e6(TdIGMEa5r}L0n8RCw~o5o zc_VIjJ%nVWfNLBr-1cqX3-MxDV&8h#PZ#6Aybs^;9c@Den1GS>F&uyLL6%gu90!dQ zBobm+$XR;MOCCWlOm-Ea-#++Oq)h6;{PmBdsOIK|}rMpwIY|V~7_Xy)9A| zJJJ_nYv~2mug7;p-|G=J+ly*0!$v=K3Cwe!i!C6D!V!8KNa$hWpc6)JZ8hL}Zv-x; z_XV*NQc4`HPlR<%qAJw5I0z3c@^{MpsJIMq47|)xSs;=Pqw*;i;ty+yg`;3J0-D(^ zTVIHy=R?>rZS^FiD;^}xmum1+>pEEzX`gu*S8wnN@8NKn9=JrPd>$Z;G7EZqpkJR( z0`B3Szd4UbJFq`i;9bE5$ur_Y0vsyBJwD^d_xpS|U=ggFAcES9}Kc{!DQbPV5TSPQQG7&SE3h z2JegG%83w|cl!1H;%1Xl{x*L}rF#HXC}7{2wj^(tsjlI13z=&}?jHYb=h_e_?^=R? z_T)FAE}%&M{=nFTzJOwvYRUW`#pVCT50L*EPObkvb=7Zhn*L(TfBgC9ZFri#_zDpG z5Hf3OyUmvU3;YTO+kkFprPHi&FtB+`UU*5AswWu_ehbrrz~f+aMz3Xu@$$;ZPw10d z&tIET2ejG2%ZH`A*fbbJ7{Wi--N9w||J2ogJa*y#YtFQ<{Gas{va6yV%rw9hNLX`} z#V^^%X-d1iIS>7e1CJ!elyd(yhl6 zvs+EtR>Vl}c?;nD-8Ydy#`%5H?|$odrnj|C?g!Q73>q_u8EGEhSs~9I2RJ3?v3wx! zS8u|fDMBW(-6s8osmZUbV{a~8(7|sgGHV7{Dk54lm8V&gwvn4A*p&8CLegx7$bcCt zh*sD6X14)DRB^7p8Tsn&9U1H+!x2i^S^KOiukM*`P?#VRu2CJC+8ijNqq=TR;j;xx z%ja?P$sD*d|0n`k%J4=>t0{{2#be&~2$dV=DHR5HOFe%;k}#G216vFVVI;NG5#`ZC zghLbxX=kf-WvyLL7LOJBvxo{0g0SOS!O0q|j!+77?a^NBK2LXA7B&@gYUHRr2Ai9T zzMMT;&0gfmX@*MR6-lLixxvMeKr3s%Xei#?kyM*2!%60N=~zd@@w43AG`jOw^&IMv zoRY_zPv5$M)yi#CUQT+^C)Pu(Yx9D&=IPHu$J8_ST5g52BZFywe?|h%ypz$ESo*Xfr3m`@=CYkDsry;cvNvlmyW` zFLHv77uG1>Sx^Dv(%G1{Tt*Qr5Mj={v=Thun&*Xp|sHR{XVhS8C1ra5YW)CjHN7Mi)yWNZ%oQr1PpkwK-+Al%=?8uUc^BMG?DSJUa;1i$s&D}~t#r`cH2X2r`(P{HF=^c*(L=R2vz>VuwqUT6?iytgG zl^Dw3HoLzuxjZT&Lf8ou-L4Zrq+fb95zCJs`hH>`;dN7J`pWB=j%R$MA>&w-d1?qf zn=L?X-$?ig{C}u>tDv^qzFRm!gS%UBx1vRZQ=9_Dy~QbREfCzjXrZ`Mv{0-_fI=zm zP@uTG6(?VM-|wDzzJqigASU~9u(oW%? z7o`~rc7f>I{MD-f7HsqU9;8_vJZ$}i;)Hgx_|jl59E*d3AG1wH`+7mw3PUTe3=fG& zZV^hB-m@VZrPOI9y3R~$2<+r=s*n*h3OQ>_+|?dT=}+ylwsNHobX6ux%cS3R+xfA!BILdf%+21nosVV>r3i&6jT5dX;NzlisMq`@I>~ zQ+Js+k3;EiFpyJ(du;r?lKKxUG;6lcS{VH8cLh7El-($!cu=duT@ZopXPH(6b_(ds zcXpxoy+X{D>_lSbt|s2#WJsP;II+|a@sHsyB=~8_+%LyS(#7}A@Pn&4#7u+h`bhm= zRTO-as61v_;z4Zcp-}dV!b4kvux<10O`o)s%f-Nn1fr(Uh47=IIoEvvTboa(Yn0V} z!ob&_Vggh>YF-?PEad%uo4Zr>7|DY0&KUd|*!AQNn_HE;e^F4Co+t9u7d1@rtMwyN z#SN>ThK;WWsLQ20{vHRq$e#CrNj&x~dk2ACOzFRgn+P#nm;??|0=rh4J2YnkpZgrG z_c@nMP;MZbN)JeU9SM-Tc(-z>t5v58YM;A>*E*t^oIv5y$M8a(9UdxV^Re4u(J#ii zpCc|e-__=2HvL$+sO3C@Kk;9Z&DRsL)M6hO55+p3{d@_3sG%47s~-uV`e(-Q>EB%M zsp~(vX_f3$cMTNNr;j36X=KykSCtymzOQ%&NO8w*Eb54o=Wt^=4R@&WO=L(DVu>H_ zP{}oC%?$tb&Yc$@1Eq5d9ZDGWN&jHGfnEDsl-#XxA z3DEZ%mgi51-~9!IsnSpMz%FipL!kZK9|y*UR?G|$&K_q3wY^1XqXB40#+@5Ox2eb@ z?3vWK-tj(SM}S;VlWKQu{EAE!eXWsiSh_u^u#Wkvm6YWOL+th6GuM-?@JLFpC~dW0 z-LFf}Z54F3VMxPXEqa-Wf|yZ{^R~7a`N%@v7NY7{Mwso$N*Bm|e58Fy36bkP70Y#@ z=%Uq%@xA**w~}W@J+z!+UeRUxh???fzV=~;3{C-UjCAQADhTS-osrwC10c0*j;rGp zh>7ON%~~SE>25Cc3X3W^{qg0Z{T)n%4QQ=s6@vGY&1O);u|E^v&#Syvs)>I;+xEg2 zJgoaHr-f(&4+Xa>f<2c?)Zi3f;U0D3am%sHH zI^KMZ&3u#q*2O;bd|zbHO)i`Y6%`rdU}~405fAt^8ojAN+0%VMX=QNQco}OP&mFqF7?=deKVWxKmA69$X8TWIb$}E4||%bgX*d z@oprvr4O=Z*&5rLjk5D2j|ioF_P}05tq^+g%yX4L-*=q3ceE4b!vni7Kn%pC#TREa zF>bLkjht^t5Mhz;HSt59)=S~oiuVy!XbErpZ!Csile+~V(~kW5n(cS#oxj1`C5l1k z_=i~=c;!aD5Um-0APL6r{*e~KPo_?DL7}LTTF)(yMu1f$g>UO`Uhuv-{`GNJ6pE^C zy=^P0_32Ll#+e^%w)!*3>Eo0A0J5tiW4R9BXTni3pp!@rDG`&f7pNM&%>w zr`B#D^c-`W!4?3eL(=5PjO z+p*f;^uFOz^6bwL^fR@^FXHb5M-~8N5*SX64Q$<8DMS+pcf@Q;fI0N z2&Lirr1>P(d16#!GnagO6nNk=1_AMe)`%AKYKPOZGkRxORK7)!)!ui~)$Tyf7c@sPUHOfe(H%2F<=y`yKbCIirR2C< z)Eu{~bWn)~$D}eT&q2hM#u;-QGxtF_3%Vjpuwwqc175KE-GxV!XiHIb zWs1OO=z;-p?j%<$Lw;iE_weyl!aGv`*0DS4LMD!xa*!jCJEa=srEF^7ZZV<6g>oaoTwWp3U#`Q zj`U}z;T6I0z>Fm8P3n{SmRcwALA81Olxm6J=X*ca3S^!Hi5i675cX&6QmOqojOa&+ zX3EL+k6N_~q3PziZ7j1VPOi`1#I5tJtHgv4=*t`OftqKnki9PX%Q-xJW%kO5d6^lc<@kAgBw8hib z3Qe|3D$Ot9-Beb5^(AxiXN*Ls%a4KS#_MVq)>M^bq1v|XJ!!&QgF8&iQ-zppYuAob z3qxbMafS~9d>Qj^q$H6aa-@&ZjiM60hMgy8t5NI+Yfm94bmYMTC9|Fd4hoqWYM(MstD}l zA2b}$UBR#1Q7?9uS40yf8=0I!tR=wG*40L9*MSK4bDO zbGpx;JLlf)Q`OuL{~z;a!M^kZKaTLP`%`_nZ*D}AtSq`6UWx7z;zw`;nS#W(7vTMQ zf#e+}cKc^-D8=-jqDr5DED*~YGKUoA3Mvq3kqA$=94^t99-g?Y%PB~ze!L?zJ{YP# zf;E5x#Gle5WX-cA2=M~i(Czod5`3jeZxNV4V5hKhHV=PEfip9|pS;;9$4x@ybSFaM ztMjf-c7RT=PGWTFSvArp?9*|9ig8F{|9fXJ6DYR6{3%q5SbV+G#ppN^CgXZ+{)@Y{ zuOXW%rMhToXX-dhxXAUz3!b~r4VK)u0Vx%{;Vo0lYMoAEjF!x-PNl}W@);+m6PSXZ z*6-z)yLdh)JrH_OG2O3OB_JzA{Av_|kSRyj*DQ&7_p9y?cn;Iz_`fX><;x$(9~YJ5 z({3$S-q6uSV5bzNPm3%u^|Dtj5d}L8ap3A}Dy-JVC340K>D0se317XWO9)9v4oFhy zMW4sP_X?h8bi$Ygeyy?0z6uj?5x+|J0A+RxmmB^#|CZxDeoMAj{ys=ZufD}nz6#xC zn4_hbbE_t*P|80%(N2AZYW20p_R3?qeZ4*k0Jw`KQz|ln8GtWr(;K&ooL3W}Lm`;L zKi)rlV;VQ(W-AR*q=Lv5@S}8!>}$*|sWI2BYQS(a;Qc;!7D@>0RNwPIFh|;k@Sh!1 zeCB6VydxKy;PIx}4UK|W`E?}+@2euo9*p5r#qC&qY}VYE?B_bq z)l$dceQl&h$Y+?cTI(N(PS06ZKi#uKpU`Z8eCUnV*%F^J5aWleb6OX_N#L4~@VF;k z^|4hA0TbwYSkwkmK7ZNR%#8!iSBaQov5o^w=$Aff8Rcx`;{_%#FK~51^YxCVrpVS4 zjEXNwHQ&LDg|s%6vsAV=2aeJAUDaO@m-TLd-%;QrRj{VxbtOl1tkE8vEa{=~^r=QN)M>WoO z2o^oV3HDU!lxe$bk~--h!8fMFg4a&|qd$Z2(gd!e&-}|t+C% zzOJDe18pTr>HGK2Jy>RWIcx<>%}%1Y1q&eZ+I%OYQOUfFq6ogws(@Y(oiol&i?@h^N z_ih+FHfwX_O=d+SPa=Q*@oDG$YL>*@%>7Q`w-?E;unP><#ZzUaC2z#J)7DrGU6f}$ zPl3n5N3F{rMMmjzApu|KR?F|(SK3R=Fa+KxxqK1tf?1locmHUZnplbWd1jEV4^co*-S(R4F0)Z05%( zVvqcSfb5az);Nk-@l3HRscY=3iUZjij@wIKj#sSydPhO71OntnHTpgD};O#fLTr+X< zh{X#}>y}elrq7abapfl?HrLnfkJ^jtnu<*$vDroD^ptIM;SG}`yN8m`*cwjzK0n94 zHr%LKgWf&!;)RRh4~+VGxc>CzJso8G0TSL=3sdOeNVaHcj{ga!=L{w4bECqKz{b!> zpksjvpwV1y7;t^$7>AI+kOg}mbq%2Lv2{OgBBI&F5!eZs*p$2(H(YVDGBV}l8J*)P ztwPBtCFeQW3(kKj2o7L`1urFEx^%cx^->dmcNRj<4JMm-Mn@Lkh?@pIv|M2e7PM@^ z6vPxUaFh*T2H%zAE~%q^RXU}ETeM}VEOZZreCZFxKo|~iycqe$V%@tm(M=g9QYL*Q zH5VldG!5HMSqXob4p?72qtU$f$b^&VY4i@|zSFuYt%TF7%nh9?aF-RXBxP`V!SG+q z({$drS7V1!7^!t3uoIH9fHwqh*wZ4tk$m{>*C5V&toK73HnKrBEuF-=ds_Iz>ij|$ zzY|~Wa#UM5 zV*i$n(IaP`a;ak{a?SS!)>ZmZ>#i+uFGFb9P+eV9787$lMALVZbr^x2h+K+>%?sNq z^c84YcU%P^Xg6UGqH4r&Es5}V7*X=2gt@t<1!C<0kc987e8FK(Vx7Q7e%Hx_k5$og z@8Q_STSExq%V*fIO+Xa#)vYzdse$4UflZhOtnr00MG|`yOS{Tbe|Ie zQ?1|w_@e?h9OLf*KuYvR5N0(ak8f?J|R(l%$)hH)nYcgxO zRA9BR2YcOAhkL;#CpLHLdhnY0$m0*QIAv_z?tHHVe z%!N#faROjvNbC$30Q>do5-)(?zw~)%Q7tc?G8x#7dAU*Li}XcE$~cvsAk$?cISck_ za1%us<}xOM1*F2=D$q@J??ZqWoWN(>n$_%<$0A5N!d1{!$Ll5_m~K!@SRZwa6<>!) zmBOxToxfgloPn*!yidEcwnioED*$lm%RIKT#`YgxJUjnH1yl#Of7R*fArFXe6~tGC zLyOs)EMve!iW?oWX0fN&_FBi?*VHiJwDW8_`I#)oXqD-EZLiMKLF3=IlkP4IE(Qpgtd8z7L%h z!Hs@@y#H}wADK^Bs5kE+Z})}`)nX{pJuOpFmte8QMy8*jsrX*F50qTk%&qEwF&;`_O*fdSYd^@1yRTBs;o#vf?C)-S|y8_9*xwjk=?HhQGb^Ae*Yt8 zl)WZUO`d|3{JlKtYc);hq$}}DJmaPA-BY5fr1fa(Aq|fY~B8=E~hYy&i@N_L%;Cwt-wPuKm)xS`=r| z?T6~hbHjTX-DCwgOLxlNCQsXW=8Y+EV-D)~1Rir$O0HEko zLXz5_539a$4DXSbx#^gv%7fh>8fdJgzB*HMd*!tE))Lp~U4L<#VNytfmneb!iwB)z zbiqpj`VH(|{kEhpp;(}2`Jc69KQjwk4R67=jvB^IAC2txz^59lZ1imR(1oL}oHBp~ zfZJD+LE8op1}sTt>63S0#JLFO(?TUo`W#&2R1~lHETjm>R=M?1)J9EU?Pt`7gXcdG z``SPvt4H^3jHGfN%*A{aGb(K2iQUo=#PK0F288i6t!);{4z;pRq$ZZ z%3fvxfMuspXJn6yw?>s6UytS8zk*pQ^ugiqDvLr@0LtRS}4=Ht|0?=X)Md8i! z@7gq1YU>y)f(PnKd~y3_dUK|zS%bw}WxRod(Z&eu#H}xroy&ff!i9#6Lv3l_QWkn? zk91Y0ZyDN_`~67~lFP48E4>v^YszsUUK~}|q%e7k?~xnzXziU9`a0bT)*RN$ol8G& z5|RqO*Z+LOMFd9bC*lZ=83GV-?YoYDY!(g!dmP5W(jecK#5H5UiA?5n5T}tv8byJLWz7#`Vk5`GL6HGc zm~FDwdzS&{gb^p&(J4hQgpEG(i{+4Q27l5P5dPYsznSB+j?A^!u*{`p|)BoT5;Xp@VCzGeQnb*rLZLn7t(dV3)UZyU}u{KQKVNOzlSqaX{Oe3(9dvNpPcYo%) z*6hA|yqf$jqWomvTmXy${FETWmxA{`Zs2v3wl7@)=8=D z*z|*z^!!Y5G!)6d(H&mB{H%IhbI@?t_|vr4mPquDf>n%6u*ceB+8tc(ANP4uLPMs* z`rd241||=P3|IaH+qNcQAtYi^=foXTrC~^qiE|IpVTzLs382SNar;Ug=cDSp*%A|P z6q6&w;%BaN5Wp*1AEZSR5_9qQnV|pzd1c>7mO{?3E9Chv$9Q=;bM}S7KPJo`TqA?b zxqaN8r_Q6qdU;qBs1I`*6_rj5ys%+jNaLzLn}YASF`^KW2{H7++TR*{ubdvkPIE06 zCwH%WEe6Z!j?$A!wC?KZ;3$dJ^kWMG0E>Z6QT*~j(cOQ)Khx?V;EzaFx;G6*q?I-# z)18J2Umj>1aC|{#(uT?1tVv~_UF93W+Sm-1?e8HC776GG-VwYGoZTSJxJns9>}CNe zzZ0bGe{_38eZ@{yRkS0>9*-m(wqs_~ssh%IdKLRxlnhgH-1j^Lza`|WRg0gM29Nk% zX06ftqOqF+f~bQq^*AL6E9DR3{pGhY6>JPZ z2xT8~^|k*3^GW8{374rk?$vgl97*9-(dl}FMFG-}#|ps^VtE+Hx0yUSI9YnVa69Y1 z@1yleD@3_J7)7yjjjW~mgFDtjPoiSdb5aM8JOVqFO24v6?!lYbzWgxd9C8=R9gdUW zv$*+nSvjgy5vM?Jp~gG&*57A z3|aT! zeVt!^YHEL|FF&A?h0Uig$RNdkgUKPu5kFN@)^=4GN#Abo+LvPHbL zu9@3T6-HpEPQm8^qfwgQujq!6*?gs@6$}D2i`-sw)T)@sY*uOC?p(JgzeXy-uuBaM z3Vp^?Bqh!_qL=-y^Fem@i<>3?MVgiBi5Tbv>FjK$j&)9)lN@Ak!G|llO=?%yRnN}U zx-dhl0W44sE7x*!xH_DoVVMdil2T#8c11P$`{*zRT_S!uS;8uUB;iPPt>o@3#OU$` z1OWA&_}{v~G_Ikk*(Haqo!C9s3N`>o3gJs5`gZ<9B3C~OguQ)^l)rCEJIGF$N<8Nd~yj|`-Mk$*s7mrDB2yy^d>S@(bIv&a$)PNYn_9$_NsBG{vC=Y1n;R%iO{ zA*yZtCkMJTf&xf=5H8@~y@P-Dwf}2Al1>5dKWnKFgce{N-yXakG@yV>uk?0b+&4_u zs`;~Q{L6YkTtcFf|8K@Vc36INrvro5Tr|P9Sy+OkRYfOC z^kqUyhFo~%*F^xf+t4map3fNi(E9ymyLpDsC6-`CF(O~3NT@LLghFCY%Jfq}FMJYy zwpV7fpOIM=*BrMOmK+qC5GJocH|ke762`Vz4oVF>_Dz+nJCmhP6?xr^Je&8lRgKqQ zvUL_5s?82vC8H4h>Y5mGc>&U>=Oz(5n42NHmBINFtbXDZcJl2uFqvR^_gj*z&Di;H`}8_BFyk3=Suj{C=NPazdmf?TaM<7wqf?niXwb`IBo+CRi+xvo6RCDw!9OVfPyhyY<+5|eHIZc z5#=~pU!7(?F6T6EMlF_J-xYN+uQYww&!Hz}3RC-4^t4ko zW?oH?F;~dg#kYP(H`hsxD0-3XVC(<*T&X5amztap>9<*8T(1EkCEz1G?hw<?KYph4g`BVai0|Fx6DCwAoi_7nqnVJ-<1-E=W z0-!Yt`aL4**}~h{Xeb=m-P7httnZEQulHL;%+pUg9xi=09?kvjlzqu)RB%JVU~KLX z_rteNgLDZXe$P8kHG})TGI&T1dWue`d{m(<#AOBb6*gn9)t6~J4y5F)%AQ7PF#OkP z@t6FM0Y%?wgB)oCSTe^&GB~ss31r3**r~7kUE}3^3=mt=!lAC>B&v7*4EE6$mb;_| zq7$rN?Bm5S+Le}&$u4TfyMK9^jGNckclT#ovc?HwpAfQs%k60rI#gYSFgtK<_n1(*l9eie5XaEsL+@E)z4E1A`g zHx_}N=4exAq$b2WRy(eH4$lvH3jLcxe%i`iD&&xJT010M`X!U}5k{{a4-IP-qUrH# zG<6D2h!BXx#Ur+w3VKuKUZ<>DrJ1oNt#{Z-u&DCc;mUfx=A?*w=z0e2uCaoA()Ep? z^Osr_N)$0;ounzCYTO%ZIS3uzvzJt(d~=aIGFBoR?&3^F~1#0N_njZA)9&X2ext zlJry*07`RJ##{0o%2!wWy_fi2yqS_mRqkt&@=1Cp7)h#mhv{Td&2IxGUA7P^8CXIy z4L0y8z@j*7#gZvw+suF|_{N53zZ(juK3^e5ER~btntwwNqEYZ~{MCyvG+En2!D%qA zU9*n5zXr*hVJiGT(M8yf-C+pTn^IheTIcf?)hOHd6 z#G41M-_dN?!8{a+Pi_n>2YxRbhx*&4fBAQ96Ed*A_aU1acnI*X!+be4?D)haFL(Fz zbts24xr1JUxWKEHlT-LjGC6I0?=MZAzz2ke2mo~;c1bnuURF(SY~m&yft~NaYd$hZ z8Zv$`5zy5UOQ4un3&A6NN^OVKzCxjZI?$0a!h$Ls)SKWgYfrLy5RsdD0&wyk*A>d7 zxkQ)SDgh;YvFTphs!yr{>O~cJ+wbx2=_@*iKtdI zc=5Pt-A^i*qMHY0(RYFpr#N9K+5_d5ltgK#liJ_$x#wU8x8=d<1r) zy4O_J=zY7qa+GA`*sqf=VuAVHjf@@M1OcS_#%)oP))6)(GVrmP?h^0v1fykQl=^XpYzEFPlwI zK|y_CcN!_em7DH zjnF_voKKbcU@@8f$R{CHl&EYHeM-g;Js7Enl6%yq$OV_8O$6UjFn7H}K)sW}bf`&| zgTRTY4bf01v>1HvP;})u6wLfcSD0{jvM&Zxq1RTSsLTE*-*El-q`^*T$pF+90!}la zb1}eLwVWrblI@MUlxFJwP`kmorD9Y)g}|vo#~Pan;w8@bw|2|Z+MOu`#r;dY<^c~UX9)Ltv>^aM*1T~ zY;D-_pBnjnE^CVxY6qSZ(Y$@1ivz{{e&(0&lLPFw^ur0A{lf>bAzT^mNi*+1B=dI zuW>x1bE5iVTllvU7PsyR_ZX+!ODCF7_pqGO)pj}ggScOoIEwZ@@zz)7>zNSvwbNm} zPL`A_j#vD6FBc|IMi-82iG{#UrjyJDK1V}xYso0pxqT8QsJG8rB?o;vr4!$7M0XaE z?0(;7!+f|C6pLIVkw_3yLnHm_`2V9hrd{bb6OUWhT7UHHZcg#!wP z^IXsA2&GN`xA%4h+-=d>#hu@rTZty0gbCN?ov?)r=%S`Wy4TsC4GT0~qNS55`{4`O zaL>Sol5X}-hlB$7*h{sGyaeZR`ikWzU${R$#*f)8)RfjOnJfc41}%)rx!dSc{`R%W zF6BN0$>U41(OkK+14Q1or2k|CKkbi1_Sj!9}C60v%X4uwrlc z2b{)m69fZd-MCud2+6@1sL_&sPnEt0U0qc%%C@$~# zXbVo;_PY(1>p)5|7Y3RmH@zwFbgSj@fh=I@S`&V5&Hdb(&Xz8cwy9dz% z;QjBBU!&*2Mp7vctoJryRd=;!d;0e$hS9}1S!q^eL=j1;3mqy zGbm`G|8kPY$$xTE5Mr<18 zg$W$v+04u!Rg0b8??HWVd(}R4X7b`C2bAHNcvISn_jvBQciVXt26S&`z)anZGNlsw z1Um5<+E3VmZ#{o^VT(9-s%u^!#FV{fg=(5r#ABA^vB`IzS(f5CS#tNAymMj#ACFKo zoz6c!(i0PvJdC3tdDYAPQYh0$B~E?zniUxRbFizZ-@*Ca!IHj@&%Ro(@2H_r%o!@C zkGSVl&p#}?67mBKnKGP@bcd!iWa82r@xP$P0aICMLaTW;gmradckZp?_U`nxwwt=pLc z!oWG@9xo~` zp{&WMbo;l^s(fYb2En)=^LA?wPIeIp>@?%RSLx+YRPw8WZa)19!Iv!fdSO}fl=t86 zkzK)bSnEbeQA9!3lLJlN1u#pb z`#p%j4?vP7P*6xv{*pWDY?s&$F`$QIPVx!*t07Kfl1dC74r6*h$ zyCHu=?H)&1t(T*+CP%`{`uNm(kBBU+N5&c*k0h z9xuwa78W#r@&qFHnDlQB0G2r6!QN7(Zb3BanBSguRj(xhcWtS@zjIf%T}EVuIG-`2 zlBCFzOsL+);N%AfWisTObvfcQqiEB3pQwDf6MZpuwlZ|NyiD+S=bh^*tAceN^f-DJUFmI9%#Yjvz@_pHnmTLTd zT>6lYKYuns!lGMKq8PlG9At<}&dj7S7gvQM2LoE%%#Gy_eVdu)r+f?R8+x36kmKZ4 zstEB%Qu;ZN5p6?}LC1*`HFR*>B-NWsQ^m7z@<8Z9c`mX4?q+yVU4IDfo?9xICVjeN zUvl994M`MsLKCNTMPSE&hw4_L+W6-)H4Qxg;%28X-?GL$NOb0r;{(fw9m+*Fsu5w0Yxh4>vGSxWNuh*3S!izAe}iDhN1rb!1pzMz*YJCJ(fHG8?1 z<%WdW%zVGIFiOUi_Z|C+y^ZM+1bi!%-77wuVrLm*y0r+R2}zZ;Cl+p&rO61;lx9f)*fop zS~R5wQ6o{yyKl35ifuEl?xR5TXK=S=R-`kAaqM80in&N~r;tzFy_(CL;ZBO?RCiy~ z%Bv!IBO>?^+9uBqPQzOd>CqzH@U9adz-8b6L~bGU19*saQrJ_n5Q}0+5?*xU{OEH?8 zvV-}@?|f#&znNRPy?0Hj`wVJcv5-_!=Rt>-QdfMGQ@J7+l!l%$g=}*zt@4@QX|6aw zaVf_|OzQtWFM2{4^R9gd32DMaxLk^@xlz+3=F$8vj(*G6D{NJkU{`dUd|9?1h@W~Ys&k+B!i@5r4JQHjFpYcpS z+3CxhF#^LF!X4{`5(3kxtMX{yq{zxSD}qQD0$oN^diKd#^SfGed6jzFxG?=O^Rc;M z=Ie}o8O*jK8czPO!F#yie1eWXifrz6wa?w3dP0(ujFojScYl%hGiEDE#)MRR>B+B3 zQK39n;5dENtCX>J2NzvNte@`1QcKy4QYC{;%eYU?1`I6634dTXds0<}3Cqt2mhbhd z|L*gVG_deIoA_a#-l`Q++;q5GhH9ti=VE(ixH@Z6)XrOrALHs543;%_d8CnYjU9d70?*`<=PMRW$UfYMVm%NqD?!H^dd(XWuI|{@NUeS9XAb zmM_y7M4yl9ld-8RfW3byAd`T4_-2WnGi3M73@G!PH+7(5qzKcos@`jCB|m4Q9|Ss< z!(fcdvE2;}2HcfWp@H_^;+ZmIGT;?-N&t4#T;&P=&cBmN>|Uk)exlcQy1O|o31?;* z(oK=^l`mxpdO;i^X5!urAqU!p;`KIx!JP3XsX@WdnJ`|+8i|?E^YbwU?wSQm!YSqn z$tCfX7P1d)kuBKML}{jeh)Z?JWWp^nwh3@~;Yf&5Su$*+A(2%IL{H0Jphb;aNf935 zlCaIj1gbr7vYUd3u-PNMf1QGU5Rx_e#L{5)Rt2NPEQVkGv*vYQX2wS;Vl4HCVZ+LG zvXAEe_SQ&rB;ZK|b~2aAarscZ;4d%qf0j_Be1rBciz&)4C|F203M~@u=6n?e|R-9SdW&0^Lqq;f0OIDx*QftEuju(N@ z#@2;7q0ok1@BjcCve-K#EpK~k>jpL&vob|NwCv6PBkJ>f%*8F$rM}jKmt;KrYRjiitSX zJz`GA(U(YhTZ$az=&L;w&m-sg3`zF5NDdBA$k_9E$Zx#0LvEm*vy?3m&u5iE`QFw_ zInwHhxsuHrZs%tPZw7QDJJ!)8xR`#V32LdK0PO~4E=nQ|aXjgg9tCzKak9jJ3#}q2 z_p8D6&1%toj!vuF3zBSm&KfS}*^!V0)hb;rOQ;3lCD;QA)Qxc-sP{+*jf#!A!aWC$dTnalmaz7N}FPRv|egyw*~B8VM9F@7ZrqhINLT3gByC2+4eM#o?e`8@zefVOW=p|4vW~mm2?v_Wg)# z6110wYG9S6V3R?;>711U^NT;T_#=@>m8-=~!xtxhblE+>d#T_ulFoTbUFxo6@cn-PIU zWX{=Wd|jyOmlY?jHXdrvLNgX_dBXFxT1~Ecv;OJXj9Jy;2I587v>FF<`uI+2vKN-HvsXB89yTitL zR`S-Ri+fe^4$@`@_BS3Fj}RAQCdJowSQixV5uSj(KbU<5;PhdZ*E4xEb8kBxv1>=O zT@|_HnGjB_54nlkyavB7O1swkeDTFS^%LNF;tp!ON;kd+Q4?K??;3XC7Cd=f2*ni9 z0;&ML0C1HR!sr6A?~(lf95-DY`fb2xp1GX4YEq-x{*zssJR$Pze=5NLmVs-${`M#( z|JH$>%l@qcqo@4KQH5jw$x+=Dr(=8^BN06w-Vs?KOi>?h_}AZyc5G|^wekTu&hCto zzde?ALa^OXg0^F!XS6hm=`ZC6!WRKx38e|lJYAp45beI#YsnJRG!*5!G-C#*BT$xzjncB`p?G9 z>1VPBLC;eE*2QQsF2b!4IsqT_5h{kB-w3HhVs&1HQHSXdIzPGBUmehyUPJM;2KTeT ziie9f?_H``Zyn1{Ul}>mX85#!w>RNYZDa4pGP=#*u#Kz=z#(42wzc>zZZleWeFbC2 zbs?R46I~?hbTf)ZG8Guf3i%m((zEHA?Sq z+hUILJ)m?^E@6g?AZ60Muol<%^dodp_z45UQy0!QE2c1pZ~OX>izWb|A9!$DDOd2{XqK_O7ano%OB*O3ISst!NWN9^^_qy{Sgm|Jd(F#9 zYrJNtrmC87^jt@G>bf^XK!)&15?>PyF9JJ62bEajh|f|6Uw{rl2k%&Vdx@-(Ri%@w zfHPn0U$ea(x_jFf$Rp{9#i-fCUx|bf2E3x|-3*xh&|j znxWagTwr=WqG+Dku(K}i@~rHE&+sBch=mTmhTWy=@aAeFS>^oIfQeQ~<#<7{^0!j9 z-rDU?L?}aB$+8$^y*`vQpGo1-OcG>BCiZ6JuR>8gn=C~zNLB^I3Dm5Tk^xO2k9MMk zDz*-;mQnu62DTs+TfNgV^4{nfni1b+BnuuBmV7H$86s1yK57=EZsVdhoV9tJo*@Kw zf}!G|y7-C;Kx@BJl%& z${pyZ6fZ@`GlBLTgG3wUr+X0@-OtYvMN^TWT=bIsCG*~ig2L0ENv_nJgjxB|v?Zut zAjcc5!>RFmnTO;$X=^-+EG#vjf;6ziqEHG}{i~z3Q=(g}$~#@B$u>Oj;{?BfiJg$@ z;dPE~D6pmAFt1jvSLU=My)_^-f5l*4r0EH8;9t*PLd34iCt$r&eD?0mxG}k^CNx3o zGYw^a#6Et7K}+=EZE#)0fW6A*$KaP> zGXi8y5UEV6kS;3Zn_;X6HoW(tunfN(7rQV$&O$~gw!B+1p816<{~_1Q-@-u~;JEr& zMeOIH6lQpbxCrb-rFnAmb~A)M&exsh8+PHgZaQECn@Gw z-iceKIg;NNEYZpm(}aK7@5KhBuxhR*X0SEyVDeJP!*S+cXvSXZ(K??(UKCPIr$t&* zDPfn|U=t@Hd%^NJoMaA<3@JQCm>9~|)@Qr~GCvC8T1Ht11aG3EA+QrGT1rDV+F8wd z;;2TR`%dD=HI}p3J-n{DtboD#T6eX$ToG=U>O~kbW4KR@5N-ZUgS*#_<-Al8QaGrQ zn1CKGJTli?MeTwmEN+9Ud{+Xs%JwiL3ZEz81m-UiQui&Cxd3rFb&y-|VcUmi{5y+ZXWY2tSzPHa`4Mxe01}Gn=SKNMfxlkY=2lFyeC7Cag?b(M$3?lFSg~j3 z4ofwBNRykB@CEaIM2T|GH?1P>QY(1xBhBe_&Jj6&0-BP!%4_m-97^RQRr|QQF=#9U z6|+P4dL5zD?{e&KBm*IvVrUZMjbbPkM{<1e62HxHln1)*t)qo%$T#I9g2wriWCbB= zdDNtWR2a`p(KWi&9g(jJG8Y6_Fcsq}?fYB)KkD8ps?D}**G7W7yF10bxI=-KVuey5 zXp4JsNC@t*vdG#$DPc1UGtph zS>hNhFA-l7Y49Y>101H@6C;M;&d;Iy`x{BAnQ#yejKN#Gvm9+fP09#fJ+bSP*vQ=H!2%a3esHw-ZYE?N z_R~iyTCaU!LJ%+650{_XI@Ex$Sbq(??keF>bx)cyzNsb8$6b0|Nw(Z)zxK+6Fi^nd zGfiUwIO}#LDO+1n;NZ>iT0VB818NlKNN??jf+omW)3ZX%derZ&`|tk53%DCwwba^F z@UxS(BiSYYTeD&ET9h>^_IKUO)6^sf3AK+(#AS9d!OSNV4PX5)YQQ-G6TcCN8N>>V zwVazOxkC!Z(kwJKHz)Yz%6*!7)Abu!$FwXE5xt&)dZ9xU(vWxaph3{zeKU8XuYl+g zl%jw#7PmcK*~pUqy?#H$Rz&s$|LT^0|Jw_+D*R_Jutt6Q>=$lRLd06MOb%pkFs6`; zkVU_0^vx{mxnub)a#67rNYb)_^p^gj$}6+M-6?}mJrAg&yj#6hLVj&>Rgy{H)C)cZ z4b{vR^HxZ4X|)J%9#vax!aZ#;D}02QT>;83KoNK~%`+P7{1No3Y4GpLFB;h{nn? z<+0e$T5Lqjelx-@a)aIxaE_*8E-g5tdK*qD3GEfgs%T@53Te|@+_ImkYb3PNhW0bJWrwitbO@2}HzH4eqho&c%t7-L| z1>;58(C@YQR@OGFQgYY<2A$lu?0+V~=}WapNAAXR)8lfPlxkjhkbPw3gki3NUcc@xc96kN23(bFQWDqnUAsn!f(1G>kVet~+05W2?5 zh%Jp{(qrb-kR;og0ih7}TA!J`*c`e(y0}y4X+wVB3&bXd@;ryyLNdOo3xys8)#EI5 z{H)k=o*-QO!&+EDB1-;SDuGLUX3qz=BGVUhTRAhQ#Zeyl!uh|FrOEN-P>}3&eN2LD z(sZcQAI~S@dd1@zho*+>s~K~v;*WZN>>Gaos?>V~&ItsGD7y=ig(!MiA$4o-l=wpT zH1OX^Fpltvg1DI=KmD-{i5z;yWLckA615Lttmr%E#2nlg*wFtdpwPJHJe?Z4A+=l1?SQHn8_=zy1=BAk+4>xfiPTl&9;f9Cd-T9 zV@zQ*TO!?&(LRtpl`dFx6I%}T)P%wh$xcsp*{Pc#=K$jiH}gC$>ecG)D~^3tmhX+e9~s4uCB;BNM0{ayOP(0P76U{FuyLT+O^xFgp4WZ&XWpKf?(0u< z036y&s0z<_{BGn%#{eV2Ai+scC`JMLYbO1>)z6P)fh=A9X=S zX(_fh=_)$}U>}nSN|cX78(i*JExX$~%ce_on?HSY3&Cdfb7VW4-JUXC0jr@k{YnkP z7n{-64c2cE{sw{ zF&`A@nY$;|Qs$zO>`d=o3}T4f8CAx?*q^HXWQPNBNyMJis8?d$5&JA~OT;r4)N>_g zGV^MsW8xZK+)s?L`YuQjWQBHUsB+rs)H9ZsC*>9++MRzy`q%pA>tMNKZ&9#Su`;1C z4)SATQTLm@&Xz%B<6S>B<-X5uv+>d-fH*q_`;d3P*$YiVKUqyxJU(;dO6G?6fo}$0 z2w5e6Wf$bc$~Okr8q72Np%W8*o1C^cawEY?K|*5>{S_SWz#5p>7xxLtPW+f*OrchR zU?s7Sd?s@LobbLEuN0W~k0?ui*z04E(<}E%=^ZeEz_52bj2la;g;Xad37H_=P@MJhS!6yidOe&iN@H~ z3U?mvNZBm$@j-H7QpU88$p>cd9~z#QN2VEyw1YPLcox5 z5Y_zsek(fq@d7k{Q%y35)8U8=w&ll5^(d*{R(RY3n_6Er{Jj#Ws`5IUCQ}!SBpM7B zbGSEK03kZW5T9}WnQALAA?xbDeyKVC*44?H|EQ~3D9C$YhIo`Xv+iYs)x`}(6h&5S z6!a#f?dpb9+Gd9zSp9{WR+(Zv=`&UD*v~8m+qVTofY5SJ=4nN%D8tj8osFm4c)fmFzbA%27W zYfioz$ldU@fKt1@Zg^|`RC?OgWmJ<|4{8y)t0KM4v>y=s*0%a(8*agpWg5)Jg)ymL zJZ1!cy29rvvgL6X|E1yw(PVUJdN^(g@US4jmBb}IY#Rer$TwdvG++4E^~Pp`trd69 z^YK7;k2TkArQZLw#os(ia#huq5YUaD!X<7meX>Ps1x9aRKSnO9`e4hzlPI9drj^wt z^~CEnUd(!2LWf%ZD%sk7ZH*2y9vf|qF3+p{ z6Ob#7NRzQF-y}_UGAI+4)9P@1E@)~o{5TVZ{tBlsCu4K!xm4^4eVQuz0Fs>|Qa*g0 z=E$L}`xt)-cx0uLynIL6bM^d(1q!NBmN$Y@Xi7z`p5T74uKAOD=1Aol^dpilu?phjj5A% zTR*lEd7Pzq|dTQ!#p~%eAZS(t?8epXCC0= zv~`ge%@JHZVVq);@pBMzeZ+n`9N|8*DS$uW7rJi3uae>wVsxvx7J^!ZH49mgs0=vx z$wMrEf5i#(^C3ewzg`Rko#(&XFSTHJsakidt9$%NeTVCsC-{hvdLwo3Y1_$PYyt## z&z4Ie*{KHe2QYjc645s&nzo6N{|1gvtQ(kh7lK!>&(6|-A2pAStF2RhxS3*d66F1! zpKvcK(i;ceLiB;-#O)Np%Uvdx7{l?!3Q`d10Ra-#zVonsaN)L5%V8VZ+)KXSGqY!I z2cW6nxxu?;KRJcSmOKQ*@nE#~Go&|M&B3g%+@-LG$_Q9Sye47GsNy?(Wg<8oL@lKO z@2~B|r$TudS+3tMfr!@~>s_%D!ihOxx7IJSKOBXQIV0JrX#r&I>>IfN+_>ue4TT?A9#L5>XQ&3h=23`I&z~?f8AntbQx~L`W7S?EaLW)qF!7W zstbIZVsM9{|F(P91MAiEPT*m0tE!Q{zi#=@7wIBV39QEJugiKI7S(Z(7t;WS8CkAA zo;&PKwOLMFnJr19k{rI`-H9j5j$vAP??`J$9devI!U^MpJ`CAY_AUxp$_qt9aVKVK z3quRn(;0>A!876%vKopcR4B@)>?o)`e}5biD5wu$GEEXx3>^n+D<2#KJ5L`68#^Ik z`yY$X{yXEk|K6t{XYyqKi)Zp=|BGkxG<8bo+VVvtufu2N4N$-GO-SLru{83lvDRM- z5i)v$7tf*@p1%-h`30um?0%_3+%M-CC(225&m1bZeGYrIolh91)f~o1^EQZwmeQR+ z^Ht8L0Ij@bEP}Prqn(m>y)iIkSd_C+3PN#;r+CneA)8!qyoBOJ9U>}yzk4A33as%aqKv~| z>}>`Q4Bt=Gk)e7WdNC?uih2{^8aH)*M+(#_uZ%eF-<6dX!_srA#Dir**tK`ZtyL{F zQGp9Byr84Iz;1AtZwCVcRL3fQDq6a92@WYt40!w)0WtCYGNgn+2V3cDr2!ES;?KrS z^s&FX%FmuWjtCW0MeZv|XYvCDvzS~P5chOKO?(<)B)d$)|4=XX|Lt4J442wOnf#C( zHNp^3E^veR_e$em`TJjW;a{Dh8T>s`3y$IF>3Ml`hs-9uSPz1h8P6d*5N(_ zud(t#`M#bxG$;L5Q)59-p-VpS$?BGfX%INp&v|kcLMF3|S$y-WGRWe@q_L(Sb3D;T z8_w{eh8P!9h|{ASg8$l3DP6X^GCRlen>)`gMRww5R?rGV+z+%^b~_VHUc60Av~Jys zh|F`^G9FAK=1y&Hj&O+K?wn-uI$5M_)}v{Zpue8+ckz zUxD{aH|leZpm2{8q zUxT&eMPYdouJ=-cC~ci4*pWCZQzFGYA!PY!Ei*{T9b8X4Nh zj&6RvS;lgQc1(5MzKq>3SzT!*P?$qtY(M>}wf^U2Rube3T?XRC^MeQy^oKAwG z!+U@|o2}Wz(0kZO_ovD-b=*P->b$RT^QA9;KAp~7B-Vh}hbc?@k+j+*08vAj;tV7M zfn;au^%y)jN6bHAo$7g>-@u%3(gCK8#YV5d<0tN>ZTJqm-`UpT#$^1qZ$hF-fkuIS zkm=2&$r-2oq>>FB`djhkp43WSa@T3@BmTjjArm15%ImB>;6qrEe8lH=^0_#QHN|5t zjeJs7KYuk~eZKfk-jrz=hlE)Sq%u%F&09NEW72`zc= z^F=022@Q>YMbcFmxJNv}Pahvdu`bLq9;bwKfPJ~1Z#Y*K!qmgwoqrTY5Jy)jhQK!I z#m89gjy>(IZMpDzDk_TiK6IEHRh6>)WJMwri}-|_Usnv0Pe4FVyLIX@P%L)F2u86? zZ4hx%%kVTT2lXP^Ns<-fGQcPf>wk=Y6TI(Tb1+vv?wfwE{05VZi~rfrj&lU;)&yU- z0_n3Avgu*ZlN9PTu3GdRk}3U*c?E;+Y8WBhk0tgtwOT6G^BrBHx!@-<;T^Lghj+n^Tpm^^8?{Z{R12s>Z?6douLr;{ncfT+1e$_S?9qI$ycO6v%T`^=Y0*+s5s( zQ*q3S-8HSpmOuf)tWTtacxFs+N3<=sdrI~b%F)A6Qxzf~oVj10z5Kh+M{0-Ws2~?y za)sX7g<-8ljFr5e==yR7O@O~`6+3e#FRhH({tb4@XxW6jc#lho@FjWvv-QPQ9RY#? z8Pp@wQRevS@O@Z(C10gD$Xvq&QYXE`SO__g?g{JYV=w z3<;`~BoA|1z70lO3b{WVkpshW!U^S9?eZ?)!u}L z7Mk3!{jS>=_NV6&BbG(346mN z7YLe7gF~L>MfkQj9PZBU-$@$< ziExbXbulKewaVb@(iSid4l*bQA+unJZ)LkaS`@2kbG2F&>&~b^&g(#1`-8(9c_3xh zTdIsMi;hmCevL$hU7NyS!KYDf^^y<7pNwBn9eAJf7zAb;zu{nGilmC_vtdZ@&N!Pg znC|2oK|2zz4aMbk89_UotL%K9V?@k(soT7N4>vQca%2S^mKyx^?WD@Ps?pREH$wn8 zUyI~W#;9}_7uh0)AKdPQekf)NEpS2sUKy7Ai5YIEN>cThe0$U`7z>d6!KGi~x~O=w zAp{xQB35w(etaLJZ80aJdL#PU!c0Py0tx!u1upS$Nv@x)3Q$Kn;?vSn5Xf5X8&p-s7WXA6!696ESP?H;Wc&R@nFgPiNFCh)wLqTGM;7mY%sCx>gVTPj7SM-J~{56hC z9~EiXuQlI&#pC7)(r+%P_NoO%qWhuF_+r)$@62aT8Z1B6pUK2;?Jx|eV)alLY#`Zb z4j=b~US3e?N>^xf2^PMkSqdSolz6J{Ouc8i=N+^%`L!|9kV;$XCfwuvUMbUdC=n{f z5=M*B6b*wam0@~D&J>xAB0*M z`})W+L!0(w(?e^@LDOIKlW!)BMZ0Ny`Kj>^pmrBItS0b*_4&{>?UJQz%${R+-ObL* zm>m#ys6_XTTof8#0jgkaWQ8yc{jBK|+IZvxu|&d^tVLKvPjfYCLvJ-UE93&q#t2nyT zo(`3Z;AJL~o$j?J!=)N23eejcfqdT93(St z+pliLvZwWuS>&GR$jT~PiE?sm6eMB%*bI6G4OSoCNffEkAK3DJ!0931)emfcu(fxRH1 zJ<6xpt0&`8)&&v*9yrWLvNH@Qx!B9{vAFkC-@R5*Y&UHXX^xK~@xMUEXCt%YJV4lwgNQevGgfBDgsP3^ZwpB7(mBNq~j2@=}5Chor(*tdO6v^iAw8 z=y0i`s3LRv5eN4oLsd}kl0eQ+zOx3g@!E1u?4BWpLduPxp6d4_0$vw+z z&xDwTH9CI&CZ7lGjU|?Q^QldBWRWIU()acue!HC$^l+;E?}qa~TDO1BdWX4Q$hr1E zI&9?W4(V+i@o!zFLi}f4wWK*+72=&y#i07DZ41c$njId-F?<6ug#K_7C%O3DnW}D) zQXTLp)_(=ueFFbjl3u2G1PZ9k`J$a&%{?vCx%!2kNw(3h5F|J>xW&fW!)*b2R$PpC zMHxJt-4(mwy|2*!ars6wH!ekTr6C!Xb&crH(pkwEc|mWQI1#$g%p!Yzmir`Q{PSo= z>so3}@ROn^32n$=N?FWl5D>B7C+-pIT6PYn+bORV#>hWego_~1~U$0M7BiOlg0rb?&{}32AocTUWLS_3nmpo7wRnhg)Dd#72>Uq=L z+l|Ja*8-2rL;gyq#`CLzD=|_6><=x&+F$5jQTZ$%ccq$tA?d;h7dUP|?f8|LN`>@w zLm>(Hrc_!L93$hKlJoNT-d2xxo2qU2?u?7G-X8>GVdGr!hVfneh6bFMx<4N}lQ)F1 zlLj%^#gNtD(DwSsYXx!Huz%XG;^^UF*d?YvZc3FEUU0Ia(_8(mX*&pU(pf~VeZEYo z0Yo(agzKZ&{&4Ts>PcEmWyZzsL4^RV9iqL@TkL64SU^4OP#W~kz6qWD`+|ufCaT!0 zKp0!W$;+Ur-J6cb7|D4Bn(-J@YhIPrJ?cdTVJsv&DK8>3-qz;q{%IgX@}I6>sz;KS zyhc6mEaSw2^WT~nr23;9+PiZ>6A}`JpDhgXbU&AyD2fy#0)VSqt~`6K;J&C)8UJ|{lpIyWbO!qXiO z@!%>-C`NegUa293GwjyFa~^zP`C!%YtC6h5(s~xmyzIpAlCsk?4fPJo$jUWHK(~~w zwWc~QpFagXuCuf$Q$h<_H*UV7VW%Ez*qxytAw@xMdIMLgrrY~kfgSXGr$@*uViEQS z=RPVtK{WM>y(IU$7Ys??OlZmsqe6*Ny*DbqR9zc=_R}%CJq69ABH77#Cj(C_i+2q} zU-Ks|S>9B>$dEE(xbs=n`{X(M6FC>(hjnnCBc>gRY+BWZB!E=K8?rF7d1bHBeuR_? zuy2Tc6#yuh{K7+tJ=ANVpkyQ+?{8ZktZ@3Uen~g_#XK<7jRBnFF3HzSV9D(kDO)Lp z9e{b)t;29?W!W?NlI8S3u|fs+ah>_vAt9UzcZQySD-M#tkE7Z;D}&<78THc$S3h3? zKn+j|sh)#*b43fU@ zrhdBzt$n2Xy)<8PX-)T3%ALb9#+V&gfMKB3&qzDGM@GF~GKGMdr4+IjC5xv*P8EM* zV~L(;(Wv)62zlF+V~Us+^2EJS)V>s@q9bdBg{0G|EQLvKd+B)84({`2*t3Qks3F-Y z@u8h>S^6k~QK&J&HegTpzUt5k+K;S# zPH=qDkXqX|do2lUsWKpJbbH`OpJEwCLL_5$EPI%y?E5@sCl%97e zoG9o&*E%`pUjg#6*445=-PEQ>WHl z;aX2zkJehd5uOmg#1r1W#Fs8*K=xv^&U8`v!QE0=+(wq}4B_@{*mx>0$(k>|Fd>C8 zs@`d2pWH7nC?ld6h^We=!fK+0WmPDs62ey|2_cp&JsK0X*cd(w*=UtT{9mxUmBcE77V~CpE9oBe@8YtedE9AP#=XVX{%%gOw_4 zjGJlEGM=LhLtG3ajJeixF&l-)1S9@{E@r;ybX^Te-gDumvLM-?n*C3nwW08?sM5-z z648gS4e1nb5bkk-S6p{=o8aXBT=6QA_!Xd&qo}ho1=NY-jDk{)l4LYsCYa~3A%lkY z5qpr$`Pfx(gA?YOgf-VSPXWg+Bv5$Kp0XkD#}UDdJZt}x4W2yye|=C${_PC}-Tt#T z03*G+qR+6|Q>BuKpYH_?oIKe;mAxI)8}(PMm|>XKD2wji{fzaFs8Qk!J4(&m*q}7p z&^Ly-@O!l0VhqU)g|wFFDp|N*kI=8AiRZ_SlBeoy-VO!}BpI1pfy;<#tuKiSO=-M8 zoz9cOofa>lf248PzBy0`R{62C$8bXn=MHqeb=7XuI4j0ehT3X%TV=bn+T~r4&z){% z)wgx$+thJPf1Iyx$D>xBq))Z+!pCq9{YTIK^K-;uM*pqCBY~PY8NbggaVdg33Pf`L zNJpUcGx4Rr_`Cq?vi8b;-v?bcVCsvM>TtqoSe^x^uF|X+`i_Qy!kz7%_ZrmTGhY4H zrJ^c}n^alXaK>Rd^!EPh7IdzM^$zz?@Z*jAtP%Hj0h?XnkcXG-I9LWX`sn08^%|+5 z#MC8uMi?apouLU)?+wALJBu!7C|}m2^r`={)8|Q}@pQq!uR9V=n1k$gaxfps_BeBW zWPGacWUh6oPN3(nXR0iqRkv0w!-h2=Ro|JUnji{`Da_xxQBh|XyvU#|a75eFvsu0y z)qx{HA%=>CWov;$sZmfopQHGKslqifh|)fJ6v3JNoVuFp5t<(r3|#*}1`vD( zA6;r&?`>pleJEC6by~H+eV0EkR?wjGnohBOs>3}Y=OYbO8IqmRqi_+ee+~_$p+BbZ z?lUAc+4G^KuANIs(Ta+3?9?Da)|oJe+83KLOCS3-$WHlL)TaSTlWsf_cb_DlozU9Y zkG(yOeJ!+Wrp7mDOxQC7T?b*D4c}hD=|ExwCFh(hPu_MupNVinmoSvj269W;> zNSug0E=+OI5e_TYR1zHN!HB{nCHm3{tX|qVnPRG4{k+}K2J*E$2D!=~9~4;|+03`j zNbu8AygZhEgK!dX{Xw8hm~ZV;)IKviI{GRv$W;!e49M@!LzJE*t#UueiRG~6V%ZV= z5JNajh}dAc(Q!|Gcu7Ip6qym3IAy?5&Dj8$7Yb!%jrQ`(8d%t%#bO{HHtLfASNOodU zu}gmsKM(Nrz^6Yn6W?5CoECQEo!(zy2DaYDC%u4MUw@vp{9}Igv@oklm_M?;tHUwZ zoBlULAG0iMl3YgKUrP|?oVmG^5wI5I0lM(U525Oz`s^&r6Imy}o~0gXMVe#z#5t=R z4GL*hFQ1&}iOFuexqacMUJNJa6rx&?{UDnN(Z=|SJ9-V8NCjBNva=@zk-r!rxcGKa zc2i}Uev4+Pl}FS24$GS;BDh-?l?Ur>R)K{ga;}ZsU;SUZYfk>Zc&<(2+}uZ(E~Qj} z@A`UEo_I1!&mt;Jz7UIdQ@1GEq*orN-PKJO*V(4z@H->LOL=f9dss9q;#k3{FZG@X zCpW7uL)QJHDGgspe}wIGNw3mWxC}Ub*l> zCffG9#~2b!qaA!9x+NAiS;^H491`?{#bMVy5N3p~ZPywsR zi{h}S`&pnju<>ota;`@lPFmdygQ<-m*wtn}I2>22S9?93E*zy{UXd&QONgyqmv*SSxJR*9J7B%^hAtZ3u z@Yko>hLDKpZ||R3*=LsLbchN)K6wTzl~q&imQ%)q~Xc!+Y8-=2Gdp9EY92>u-sD9WR>sID@1B z5S+LKRV4vbL+-B)#Py)apA!eT6OwoO5YBO$9}pt7fTJ}qOQiD*8SYd`?-q083e#pt zQ3Idg=U!pS$kE`ZHxs&L6HqDlxAqs{mPQjD*1^F2jQ45e*T4hyN308j#z2u*lUkJ% zHzSmP2q1Zo-}9o}&SihF!VCZI2vI~{tJ*Zs_E%a9*{NzpNC&HSN-)kmOxcB#t zgK}Pb=c2RMi>gRUO$l{H5M)JwhMg(-6?{Cwi^jRx19)XF#mhR4j*y4E!z%T?=kU%G zxGBpUx{~&9L=X~AlR6~*LJ*7B0YPB9*8utL*Dr*ylQC7X|n7_&13g#D75F8U9!ep|gEqXA~aA;ak8OoryNddCk z%H?ST+OmqsURQJB!ws>5i391bfE^*to{S~RUv{ePk<)U=wZNac-FdP$(Vs&BVTG&` zSSPcn$3NeVX_eEF>bw>E#kS`hS9~qRvTBt_jpIukh*0bivqs2a*w02zqlfcnD8efe zmKrDr1Z(dJOr=#{E^*>i8NV^wKR)hBDWB4X>B`5aRQ)k>n>@t3(+i(rSb!bqUCOEbf|gEMPKfOg=Qg%&+Y<}x zGu4g_f+u}?_4${tp%YHK0x#EHBGbb+`(*H}xu*ad7J@jVcB7eZjnVp{U^ql-aSWR( z6(@JqkOB)VhcbA17QrIv3!fC~WB!nW6#1sdXfuf=G|NnyVD`Ytcb=y}aGx@6L`q4_ zf@vb2!|wSuN5MaF=b!&#F6!ffAMW7mz3!aSeRw8<|NBZo_#DYjbL^~fd$=>_)*=Z4 zVpE{E9Y6gk^Jeerxx^=g8tdf4)rh=|3uvv&)zN1CH-QU5(HvYbKFo7o)qNHV#$4)v z4(4>=7=YG%paumkJuwf%-ok^8xvF-a3s=t_G5Z)WP1qP41r7|ycfrLn7t3Y8_kk() zlDfslhl9H50K$0#_;0pbW5w^(n$MXw*-k!Vt`p!#OgQ##a@3P8gRf`&-#Al8AkC@k zS_EkbSiUnWt#z1TQqR)CknFSvrkwZ!0D^bYr<4MPidoF;m|jmSu0w`u>Y51>^4oaW z&+%At<7Gu4@w@gcZ>57;+AOn~gs-uuA1HP86{ekq!{oZfn1fIAXFxAi+hz7I6LtFrp*AF( z9Y=u_KQ+2G?#WOSyJXRY^pfEb>xYSsQe3R&&E46^pTa&6-+@jG`$FW=fVN0>8Or~6 zZPIG9iaskt93qYwtyP~rabBXi%;=s=)V&}#)~rMHM?<6QLP*FR11x$d`Bax^5t>gM zza$=aEu{q!7#s!1kuV(iVBJ3q7(9EkdWoEo7Bk3nzQ2keyc0$|K<|I@sh>Kv)cYP# zr(c_c&Je^DcAvRUSA7$*5I^};C7g!Y2JT&mR^byg>=MxmxICyWq@E!2(LnBMrS8kv zj(Z>?!V+1V=>Mrro&VM*3*G;$P2EUuG*3cbSPe2MRwH`uEgQ7oUz&6HLBm=M5v{5b zuzih2uK z5A7=UEWn{sh^a!OtCsPs5rmSEM5{6+9&8(w0-4$KVC{-*@@9pt(PR?P?Q@9Mi?hX{ zFCbRdmrx&pvSaI~{VY82Qf)Jq0yN}vXHfn1!mOH^__$H4g+khlIJ2XJVRbL!1CEqz zl*s$TJb&@Myy@o%Xy6a4N48{ z;!}&Obv`Jn_OU!TKFij*9)gx9*`e+fvoWC)xGD76d zdv}oRj8yUABA7jmRz#?KK`RE~0e|-4vDg96zD%Eil=Xno)k=i-bNOr999Tf;&49M9 z*g-On-62+Q@j6~S!mgR%>+SQbVx|Wk_Dp~yIny7+9H2Vz@U6Y%6d6@Hn;!!hlBPfu zNaTrvDm2Ox(~7f+6B$4jl~nLXxy$Qz}>%F51G5z`gm36hM3-n%gT>kDc8hwMv{4QK3CRO@2p zm$+8NbaWSrre~VJUr@FMFVxyz?5b^Ylim7v^Wfgr%5=Y5TTZU9JX`#YMgo=beqT%V zh;C}`H~vM9@vQc^t=X=}+u3Vxa+q$WdX9(OmwCdeHY*P9k_gQ(eRf8R04Z@*lX32g zh5!)+dc?}Joi0*;^U8<`REB%RLUnut&bb;_0T?V8$AfWEioYczd)(lLzm#8g_nj82 zGs>y0gc;(xy_(YKH`sUPHsQQ@lsml&pN=xYYf+d?MDKlTDVx;(`)$T&3ss;M=0>jd zS!%RE2T=*YWz7#?4>y`h$*B+3a*eUfK=$itG#gx6k!tt`rp^ZllcOcZt*e_5IuFv& z_(3k(P85vUSH_z+H@9KRz4hBoqEfdWDXecXW#B?f4MX zZa%Aq5XL=DdFrc5`L*a1Bh6bx-|u&X(ckAsu^0h_sI{IneX00LiF8DJ*nYufU1cbS zMARW7+tMHUlohSe<0V6mb?i5o(!`PMq{VV3R!nqYj$-C>5dYvp4ERTNR3!S!2Jx1h z5gXRsy{d?zuJ&tHOeyN&{ZKMzuUqPl{xPBek*j{r@ZU&H50~q;%vH^Ngw0y))az-V z#=V+-p#Hpj6Cv97o}syjKW?iN+#&&Q{ChV08tsFu*2fIP$_bB?bjqc^(+O6b4vrKO zs`wbvq$tdbu{31FGXYK)Kqb#Dj1+D0O)V8V>3F2RY)U8_pv@4D3PE= z4P-fO@(`nSf+slZ>Y~>alRMvnpe)~5EnH~l(RQYz^#ka5Fd<+SJ5w-Q2%DKL8F-J_ z52wrF>+NFbr)PQZwCLW{y`tm!$W&g}GEMeFmSRDnHhH*b4Igt97G6DOD|IVz9n{b$ z-EuWQ|C5-AQr`9zz5<%*lW1rn3tg!kRCLlUMHA4d#s zwB;!;r%j8`qD!b**?NaUO^Uk0(eoG*X8r_DN&lS(mM^FwlG!YhZ;*#E$z>-^IXVE{ z>P4XBO?Y_pd^iD2bB?jUZ$p*b&J2CQyCg*Fq6~n=7_?vW7=t?i8h81_&noJ4>mls$ zsgu`sDZ0OHo9sJM+qGe9PM3h%j3DZRB4#J>h;=)y5b&^9lb&rm*k32l`atEg3xVi& z)n2Y`kHc0nM;(8AF>$B=cU}Dt@za0rPvw4Hm$kQl23!@;+pPU_)4Kvw+Cz5l`5>w) z?$$$`z{jel!ad2yQ~`pEzF0YzFmFLBOU~~qW)I#Erk?mjmOIiJh`afgwn6!S&U_Mo z^}t_j{_j1o-M{tqeb;~1*EOnBjS<{N6FtPOPU@HehlqvZ{>7~;{3b;YjjD#^+YTk~ z_4DOUTW>fE1!b;ZlBBi7g*2v_qB@z+T8$sSs zVahJxdIlIn^L@M}Ky)BRK7-);atA*nWh$Ob4Q~iurPO5n2|Asd|KfUU0(u$%1f@6K zFU3Z0ei%;(iSP-tHp?!<&c_7&#)l)`NLJKw2pLvP}Ms`qVHJx;-e>( zyx2Du^zU5?PWIo}gzFe67^+Kk1z&2u3m$;K8S0NYBd4=cfYWX~1_(~J8Wq`msnJ__ zQTVNzopRgy2&!=#_#2Vq375)43c@xcJbzt^fKmN=9(XLNeXurvhR7}{SWY0>sj02e1ClvS z-@pFmts7#fvZ5Ov<=F1ta{BB~VoaI5Ii!FHQR3D#S{?1-Dj zR;y5~vWD#^`pr>2Rr~jzI+5!&4lhPmL7G|)ku)j3dQ`@Q_$!<+f`Z(~__K3(s1R9H zyprFE)df-WG2YAjSCsxE^3dkO5bpZb451`6DFDxuu1lAp&nNLKUYkEE-mt5*jCH~; z;D{@*Kj0QkOu{!V!K1|l2!>SkbqM43}H~@{d2)t-doUbue9;l zI^zTSFN0W~XHbL^#2vtpk(Zdum#Zv=2d6s{lj6Ndk2f4>-uyE>x7L(Edd~R^i1A9N zNQ#wDFN#-o2z#qEKj9LG6UU%rosRy6G~c?tsxU(FTWndds0Bsii(-*$u|w6tSLsQ# zPHSoF^B9GZdqG_{39MQ5RB?#{ETKjzpRuV4Y`}|WE5iMht=@)-?LA0#hO7kyBu3+4 z6ti?t$OeVd-p})gGm!4-%MYKIpznH!20{kafT%oNvf*O~702 zn9gK)1kJBKgSZCwU$li_0_lQ*IkH(#Q=}% zADJf6U(_fH59oXq4Mq{k%9lthu|t=p?v*B46a4ty!!CJ0KAa$j?3ONg83O5%4SVq) z`Kwd^R3#=6(BD8P79|vv2g&f473>69%2xAh&QA%`R9Pm`m(zVS0@K+#Jl=?jw3g*QST{gaHBq4_c;AEtzV^|pkluq;6_%K zwJ;lRptcDNzEN+;4Z3McUiv2ol*@7n6-_d;A&`J3M#PSWo@7 zn6xC7A;&&#dF7+x!`TsPZ>m*R6)ir(W}%|~11x$NoE*XKw&bs4q@HnUS9PN{^jQ|k zPLlS+Nm!427nS zZK2UwsTf&Fzsf~-z~QVG68@34W$M1mHhikHTa;C<)30y&*(@S{fybUILQp<3w{#m) z?eE(xtue<$F!_7(tpoCVo_E~+>NQ|dD_2x0gy&r{(Dhm#bE}xnma}ikM1OaDcqefE zLZaL5-B0(AnA0eFiehx*d}5wky1sb^3v0rIT z`*!UeVuL@jO%{BEzh0p*hk7!_=`<}hx*GWYeW94vE|DRH;i=c`7%^5>f5Yj>F~SOo z_u_>5a*Q;^-*}j3%{m&p>s-9ZdUQ6HPggqc82WRzlyvYZ4H7uxMb~uHegW&nT<>Wn zw*UPtspr-Pi}a+BqmupHL4Pd5I~M!>=j~25g>!$J)Qu@0dg3JxOzAp*hr+LyJ-@Vs z5nax*MG#gDWNktviw{_`c-vrt9nDP8XQ+qycDbRSoe0B8%t)N@IPqkb=ZPVqd%AXl zK<&|d1EtdC_Q^L@ZLKiQ>&UN7Ps;Et3Vb7c61Z)T__fW(h;;Xb7vl1GM1Sq24yTjg zFmqc+IGKEWs!K|AZjkj6oplVCmns#^NB_@viUkGv7DcCC(j)Wvl!TqRIT_RHqDMce z8pd$=m@i07GiS`16ZUUuOL8)AX}p-ZTnc#d-e28P7+B2lN5G5}$xdFr)OHq}F~BfU zSRQRK*=f+wAy9l!+b@!Zp#dkma5C?tx#bSQ^{u8J1VjXSUy zHm246mg^{Le<6t^g6KkY ztGB3$PFN*sl!%DFS`ZRl2%>kw>Wj7e+kC$7dFL~8W_~m0cg~!d_rLvP&0O=$WAFR9 zuKT{O5b=sYE^j|>v5KNkg*sYuE2$aU0Jd(q(G=&$l;ygNT}qG3b+GgzCNSM9K+>Kj z%ycQQsi@d9Y0kJS4CH^7+M?7mD-3mKze3sz^5%ovqUq(cjy$>#HGc=h3;;>VG_ez& zW3bb>b9K*^>=7uxUYi_f{d*w1%JW!6m;*uR#R0!ILUToFiGcm3faaGqd09_&J8H#$ zet+?+{?*3Az?)tBRaF!=?kBL$SaeWnM_Y9dA5>sV{v$^n6Cu`JhlY$#RU_A__5IK{ zVbVSH?ccnoxSQrel|6op`oG%zgrJbBwdn>6n_BZ);Bv%8vp51Lu<>oe>j7oV)U zf~(GjtfIY7X$o$ur(o#8^Vgz)oa=Pld67;p^k)wQnvJw;Bt2`oI!Db`X`#H*;7&)16+ z2)IvHcI({*QQJTtGE7OSJNk()_>)Q7q z0Pv|@a-gZ}rrNIK$adiD4rUJX9)S7+C<<*+KH40GI%SkGs4kZ zyqQA7Iz4bh{P^t;FU8oernR-x+QO!lmcLBsq5#+n#WfwX%eyQ=hJm9sBpDPLA!aerk+<>K@MzL-=v;xpR+m7 z;Sh!CGDMPNlhi4S@n`iwLM&{@Ex#P+wFap)0rNxIrCLt729JC*riST` zED$fYG%vdp7@Lb#0pexwG#V}K0hM(|I znJha9S4f<=LH|IO#D})`mHL{ioD}0xYabq9YOk)Mz;mzpQ5vr2V^?}G!}aCPh1a$7 zVM>mS1Jvosh%9^sJiAs?RJWPwbkcyk{a-1)&~q#%OaZJFqK?MFT-UTRp{68A7BWIab+ zCT1qiW_)ZamER$d-PgSop#n&@Bv!9*;?Wh5FVGz+rQjskzAM0RsaT9!+HA4(!oMs7 zt8!g=s#NiDanqZ#y)~VL6_gUUl2yFpK)9pEk^e;1viBhWmcsN9O!jJ2r1q*iA6eo+ z?^NuQVEbY5gXAMb=aHMKZ(G#P+t}+<^2I6s&mEoc6KjoNDQC6f-^x~P&g>0p4{D3- zJ$Py8yqI5yF^Li7UGTW(N!Cj};&Y~~laG1#jquX~O;9~fHc*Ku@5?VGpFo7tu~^JUg`OZVRR2HW(lBX zm;szU5m4GIPK}%h(T9I@{T%s|kzeOWC<`jdT!!p#2>o75WW6~g&e8R6OM{QFTG5^+rDh^AWlU?GIn8eONeahQY2_{{JJV_kYX|Qo!PlPcLu%&*yYLitF&y z10!THS{ds<`yLbj;qp>M{>9}L0O;X6WY{0(-TyN8+SGQ$80ipYiF8ZV)thhlTyF=8PzN^`BfR+?DFy15ab7NZbQD^4Cyy` zKNC&zd$}It8vJt2{1jBxV4y&e!-ILRf~pQ{X9j8~K3dWu^U%S|Y;+550;~;6=o+bI z4wX4STXHxh3d{ z@c3mb`_2%5==%T$@O_pFN&&Alr$}P#-EMQe?O5Kl-N*7*k3ZHY2D>FO|Iva71 zjKW~2$PBfTHl#RSwCZbB>p2Srsv9LL!9 z6~Awthn@MwWb7AgZC!i&ZAk~he&R<6Hm-=?)v*sj)L(bU0K`Ie#5V{ZDpIP4JrSkZ zUj`SMh(`t%)`tk-w9ZrojnrX8H}9SNj?K-oZIA znknAGaPtUf6KP35{My`!4oJwQFW_jo9zu487liZOJrWc9y```0;&7;z#f z^5Vv4#~RqS|KhCLF1LVjGK4S(!xI2#3{;bfH63@Z5T1tQ1QfBPDnRI5&LbQdtS2eb zfv=2>8kv27&%l=?y8Tb}ad>M{aT)v*E3rJ^#l}^4iF#*CnF6;iSm`9WolF?X;pv5e zYnq6EH;6_t@m?`Y3@B(6a#qk2AFQA1%LkpHboa%9LssY8n zcZPPEIl^Ftmded72jq{owap@KcSXmnf4TgM?05((bU?{nH2j#R2Vr<(xZ|T&2(LF~ zV#MWg<46l34kk{fgxz7bP?1KpovTg5!^Fm4#T(8fg780?vT{YD$2!=Pob-&Dw1Z?q z8t;E(4T%xt3bL%UB?y<9;IFpWU*hEQTQX$$!qw;ocMaouyKzcVn7cnDlMI~ia{m#Y z2D@$2*|Bk|RYaf7{r+^k;its~Wr$k~Cg=x#H~Gs)(p3ho-nTzFnZ~xcDG9`o%^&5+ z)l6`R{87}8R6B5|7I&%Q^A)Nr5Q~Hn*|9D0CBGCtMWvMzh(W%_Npm>P?8cLtE6(56 zo_yx)oy|P4%ffLbup}~EnhgU=47gf>YocujQH~dgh0~Y#rfSV$cI+ldT^4AJAOX+j@I6T^khOjjQ8Gf4=ys$EUKsNJddtA?D-Z08%G!27d2 zSsKk44>czKzxjONnWq#p8))1wAszXrE2I?Vgpj+uI6|5_ykZg;JXzrWw-_!RqJq&s zrljP37rvUf1Q#Eaa31wjkK~zrMS%++Xk&cH@-)fCaJ38Zizl;ZA zJz98*87X`JB{o4^c$=jsE@4W=*wTK?3r%zkqUdq8!BI{#ze^RxV82iCf9nZkHv=nF zjBW3iBu>$2sP%?V^xrVx*{Ms$S~FPe`+b~@LM(gGrKF}TtZxuDk$&{UC3~+qLO{Cx zU9h@#QpyYdV?X_?n7zC29>=Wtnwe0wEP{iA$8|E~TmHccu~;eB zIBYhJs0Y&%{F5z+&-S05puG6sJpmhL&m)fv96i80D_fkP$=o^A@TE8~I>AN?z5SCr zFvhRj!!0nCOEqU+IL!PQTpFVk=l3(5`rt9eR_sx26+R<^x@zz-Of?+&QZTh_z z&+B8jtxGhW9^aX?5Rn~sZ{hoEd7{G#uF;D^l7G6V*#0z_)Mn6#UyFY$SB*G+BvO}? zzAaB@22IxZ64-S|C}-CBc@p32UdJZY-}y+!TA3^x5JEfeEZAg(ykAn*fCPE?7;F*6q!I=??> z>zKq64pH;OEpmHwL(8#Q+6;!XN`hGq6N!E2=4$XBd^>!ARmH`u7#m-iGdLlm=Gxc` z72g41urqlNMxDJb@NwYh$@ccvFqd-Z>WqGs4=K-<<>>@v{Eqp8;Odaafv~X?eQ6_n zqLqp+e#m;02$j@ueC2+j$YUmwmDWpEztPf~C(Bnlq7v}?mcgVg%IM9S9r_8vxAz_c zh~GzQx)SX zjExujT=WAapq8v13k$hCji0gIs&|mrqjC?gYQjR2nYsgmof%egnIjs96TxjcW0Qw_3n=kv5mBbJh3fTn;%CKE*&M`*_24Au#0PI7+Al zUX4TqHX1#iIc&-}agp%LrhvOm$=b9--EGNQA%mA#6j;ABiSc^3N%;V{-fRMD%FTJT zSl7EC`B=KxSj`M;StCgDti4TC1L^FzJLyTFjbp@}Bi2h^`z4SG$p(K+ZuN~*1I z=0AVQ)(yBl>19(jY81ex60U4Vr`+7^#d*gvElc1F8Ni!36 z3>dcLo#GNmms_d)OOEXNs$1d4uGd6er_Pm z{iSgvIU)kraG$wdO;ULsU;WA!O_#%5Rh*Bcn|hX{W#^aJI=8Dy7V z;EH`o-z5p`A}I}0S&osTWx!3&A^WQhgI=30k&;N%$3l_RhK38QQ6Ge%`cuTpZK3wM zt+eem?cm@5?~L~p0QPc0vup;*vrk)Gza$%yn}>X&HLd6yL?+88RWHkPT>!X-)%FfRTV|UOd^I=MOV~}j&W0_9m_|{>Y281Zd6@Q;Rxe4 z`mTl>8K><$pTQiDMRPXSyF5-UW2kt1%$7lMUHGx(7wiQeDU2 z4q!)Gt^wmZ4*5vz`xfJ!Ae%uOYvr{j-yg1&AoT~vNq4%kO-Yl;$J1EFT**#{Tv?k` zF!|1bBoXRFQqGaYK zGTnH(a!1>TlMGFf29GnYHi6w1_ftLYS#F_oRK;3Twrsi>vx_>5yeuI#v{?ZM)&yN- zyC|Ku=7#J?SUd4y!5o@ zrHyQoK=Idv49KE2$Xk}E@6JAe*fkJKT!cJ11vf76jQ_LpnAJLN*(NJ|6EGC>3dfPj zUG_R|zeL#r2e^L2LG+&Vyj}DU=FZSo3sPhzD`o{;Xn8m^C)^Wqy}Gbs16dY!_TEf3 z+hf7g9^k8f@87tm&Z^Ko8IA2H$0&MZ$WvBE)XKpZTdW|;_JHX1&chPzLHhB#F569k%xV%rZbcTE4()gjDM z&?!aV87;29e)8Tlf#hdAF2x2rPJ%0;SZxPyIK!v}Mx|0Wfel%cRzrh`bJ>U@RLuJ^ z*y(lyL)4vaYX)=Z+!}gZI7mKEjJ2`ZIhk8nksXtX0zds!N0($E{*({9Mg>1f>a=Tq zJ=zSCn_32xlBo3tGx~tw@zIad*d3ZvjP;@RK4t_>I4}2Zu@`J59`X5KWMm=D7406-s9U_mCg4LG$mIf23OtU-S2C2 zOGfVH9!bzLT)!rPO<;D63_kCMT9~V?O(fw-3IENR00)Nk1D+<^K>9zf*KipQmPZGF z5R_B|#6?`=@99Mz?=x4hhhe3?2n!CF|HV4!=|Y3R&xsZlipX5#C94g?3I(p350AFG zgl2t=5sIPa>Qohf}UZuBsMWnX4uWmZ%*@za0Z?oJzJb$O~ja@H(#KbvbcS`;lf5Ixi#{1O z^oa?NRS>JkiLH?mt`J~zqM-z{6*qnU+lE@;VRKObtZ4Q+Xo`LfgPq|m?lE+MO|E3I zDLIOcg*9UaM^jND8)pN5m8pmq@10LI6{?}!VNhc$?z_}3C0%E0t@CS_ty?*%Ao_i4 zFX`5CNb?)g9Gdn4y~^|J&R;*fLPRcB`->*m$^piy{EoC~gOiU*swACzRYXq(ir>MI zisq}ktGHN=^n<2x@7t(I$0Tlkn0S0yBNA)0oM4tD2y!83If`_u?!%56X*Lo4EVQxC zK3`!JO7q>L^<^CPR7E2TgHs{}20P>Cv!C;JB}2~Fc#ak>gkc@*-#dsXMJ-=2?~T-y%U;7lT$0@YKrF6Gf#vb?n2`t#Jti$E^Z&+^#Y#>&e254 zsVa_jUxLMp<>IYlgnCb!7wvi+0!-IJaEBn(C_tEp^ndLKtyaGfrbYJ)EaxDh*`B$d|Lh2 zTY>3!BF1-!>JK5s(vQI^(&A%;_{X=?DQFbmW7F_kH0xEAJqIT+g6;8h*Bh^GL0wWY zTYIE-GQ||mcs;BgsfYtFRUXxko#{@MgGUF2vbxspT_?&s%^!*S6Tkyu*v>YPp2XO zuBUc%aE-4~brmi73H@!3+id<*H2aj8)cX?#6p!k|LYRsTM}o;I2aUpP!U?Ty)#m2K z06|BIYnYEx8TV;S{Vi-b1;v(>=Nn4-vVVCFr7k4oZ*Z@lf~#`n&z~0IT2L%CQJZ1v zQZ(56%CmmK^>#n?$U;OrF|_`8=}kaxs0&+&Y(^U7Vp9$O#io4DH4n(D8(n&wsKFm{ z88mZ)Id|4iHIL_ZVKGliD-Dxmm22>-)aoP`y>fMN^lg=4*mxmlq38)3gNg#;w#FBy z2c(|1H%^nOM1gPLip-Q>%m{=XoxN}Jx?@T^y$dUqSnjyVzUgvMQ0|r=rkZvIdX#-V z_cadnFG~}7Ql`vs=9>)K56crsgM^l@_^n$$e*eIfUBB63*(>Vcea9mqJv{I29rZry zG9>NVYPh}mOWX;%luqgo34LZ5c9eS84$AfRmaKPWYW3dV*?rJse8;=InbtKdCYW%U z_shY%I4JXy{s)P4fFvtnkN?&W+Q%T3vM#Nwk<1HMbGnog8?>GfYD$~^^fIQT^|>b~ zE~j=^YVbrqDCAFP$7&fV6fWQEp_AS7VDv=MdRS2JoJyzY-bKx70ylwG$*{3e6@fNmXDYpsUc9l5skG1bjgIb~mKXwz&_1TQ^-=y}4`wYKJpvk+nd z&`B%l>DdFNjQ@ICr`ajB4m`b9VS8ks0qAqm_-)7*P7F!j)uLzXc^6HX zE6+2vg1PUMwU&UVU*{DZdOqzJ9gQLi_Wf>B$2#f>`p7@7!M7E(QfOH@9H?vK zuSx@;hb@tl&OgAP8q$&WSIV7~!)d&1gv5>j{4rMOwT}31q2aG>XVsMaNF;JWSWZlS zFS%>Mtrs^L+B;Xu#s7f;k;`8t_Os4M<00n?D*6;VS1pA`&2c-*#Q{}-clwR7_JBbW z9m`FGH*v$MQt>*ubcE66VMKZLr^sN!Jz+$sQ<>b^CAr!#20N7_yL`$G?{(G(+8rP% zV1qeSl7t+3Z-nOCjnbzWx|1qyAAi!f59dzIBIX{=t&MiK=@$D)aQ%jU#bI>YAF`;Q z_sALe9xaX#;U)-Qnz4I%RQ&Qa>XAIg6*&Y;sU*nUwS8Ltvg`bDS$x#66F}Or$77^9 z+%qFu);^B?D6iwj5YEV^z#=nixPncR5U?13inkSw)`%7u0NNv{joNV;KR;2Qfd^9re{qE?2RZ< zjCQnlsn^V!HX_EYx}6X^8QKt3EN^YL{jgptvC+#*!U7Z@h&yBS#_eD(jGYR4kbny$ z-O8enpI;uV_%uISJ%m&iYMu+x4W<5d9OC6#bsZMqvIT+Jc298acQu?d)k}(&?!`W{ zJy(rUxVVnv;$SkEdlEJEL%blueE2uHNEAT~NJ@WTo16Dy+!DW0KRol<)!GOKJB{I$ z8+sQsFEm*GDlj|BZDZMI!b1AYDqbA@rnNn6&E&5HLNf;O1N@nT6e;ek41vnwi%2S z@_0sV&WIIHbt>8Ul=(3p2y^iY7Ty~YqZV=kg^AOuty7{rDJz9Oj>q|r_u)_O<6`a5 zGJ|y1Z^bQNN-&bda4ttySfHfE&jTZVw}LR(X^G$}v~+)XRqLc310;Wr>Upqwr@#5l z&42wv!eT)-5`-J(3R9};%Z^UM7Foo+eH(J`Tfxu=S}WJf^sa+~dlPSGZdQ=m>`|qG zE2Alt^gTI?C&EiCfl%d$*x zz@hf*M?E%f!bz%69E7_xqgw z{NXO!zdqzLjQ^W{<}ft>#}OBZkb*e4cKW72g*8kB8Iv8wI*<_GZtIRmoZb;GsO76l zsvNc*E(N*Ix<}Skyit5hOEZX>vNTpNXJ@@A?u&w|U(GjqmGbj-afCQwBUsNRRBg zj|Vuo$=Il=Qg=ol_Gj39P#Ir(r?gI{F_{Xv;X8S~LbEQ9NYM;QOwiyJpjeIWV;Ofu zKAoHxx`c_;1t}7wnHfj#aH6Fb;A4lC?^BF#6AxT0re~i86wCc&e;n^Dj>=uDc@iaX zZ;WW5dg}Go&AqN?HS)(8e*Q)TJ%1_5xeRo}oI8Ex>5I1SuzR0ZW7LkL<9L!xPG}%b zzh(9)4){0sFH`-mQd}$h6*)9kzFq}<{FyOb-(b>#;Gl2vLzzPEeGBFvKrRz91{#0& z6n9#`>-Gi^Uq4DsHJkp?PT(TR+)EMga>bo&W<>y?QB!_Hk|Dk8G$_a$-brMnvVLs*opG!xSKyY8Z~ zmqxwbmBery40eWiHq2|SZ9U==$XbUDgnaUkt}Y4Y7s=p8guOh6O)P_c_as{dHO`R? zN34q1Q`@`55rTNY15FNkGIzM{Vs<8yqBAgjM>qT}Jec&trix^>Tv01$*V3zsyW4GI zr|}qMpj9$SA)yG^g8i*%O5|7F#6leR`lUFmDlqby9horhE&(+$q05r`5D|;TTk4W$ zS~z=>qR&8xeTCsuAX&6>|Ev34t*(J25&a#j_+k~dw?kL#l7BP57&la{Y;T-ZG7QD@ zT=~LLeG=FRjs6R@t#>TUwx|q%Pa}C))TkPOD?-pTC5~+bV@iM}NG!qD~%QZ-&Kk75?RSiP0b# z%3G1U?NUgeBsuR5%hP5uB9qGJ8X21*7nrU&)u|| z;pmP&fqJ(NO>nEb6VU6?F}Q{&JIk)x5FZFK9|3_1T{XAb`Zlddy&&fglM3kA+O&vM z|D@b_{m4R}sJo=BU=oSY5kdT2Ih^ODD>>*s>d%bo(XC!9myvFx`#8$dKshbMm|f7& zm=iYLjghHF01Ez?Q@`a>jy8C<&5Q|tDz`kR%^e45Xg z)9O3vWz}x1bd~|366bl|d2uK15s_heCCsWU-yLoWMWLn^IHiP`gYgTZEb zyFubCuEuvO7i?;K@8Al^L(xW2Fk2|u`;B92pn>f>Vz6gZ+-GE{$%LGfz;^DhVF?gI zsJEi`9ep&j%;=h;{dwRo?@ou+S=zP4zdN8TZ@J^7q_?LW#f{KI{Du|xn#ZEMMnt`M zJjs4lXY0t@{i(Z&^|q*aIB;n5UMFm*Qfu*|E{?dmX?skhdD>&M;l&cAsf*K)wz!7{ z>;x7L-Ua)B>YR5OTKW|yVEs;wNq8o&*6t-xoEo4ga!pMhX7EWVZz)J}{Ze&HAQ!o8 zC$iKHW;P`6F$8V{@#i^h=$*Wz>h*GwZ?PMP;tvFxXieNVUx>yawM8t-mfmXFt*`R#x0FiVkE; zx33!f1m!CyXfyx|5|IEhaIMdbKE@?KEtmER(!#Sxx`#e(bVwoIA*sH=G8BUvgiWee zoh2Ao0moU}!n+RpX<|shN7E(f!L*s*fnf~OM@<4IKDT<)Bg_l5608Dbt&p~R;W_s?xaFR>Jel< zgIcDyKD3Jy*Q{R=Q#ecSRyLoOI>;XR`4Gy^Vy+@LJ4S9AWM-|I0fJccAVz)= z+@YuoH+;m{apZ74++BEU{W@q^G5KNgv=wE5Z&b(Z)`0E(S;>RrlEgIovgXjS;U-WxlWid%7OO zY-B1Cab;hU91MzV$5F?{Kko?7p3TfrItO%g)bkrLcB0Rp1#Akx2-~V$`w}Xep4X?6+2(u!UMJ)2qLK$0l4oYow%Rl;S;aEW(P%eU}j6mf1QCxVNlfIjloW%rBx$Fz0*HO7IV1kGOl9CJAZ9Rpif^3 z5WaObtFf<86t|Czx}rF>FYPlY;PHI~V2&m*R;%XDo;19jaq{*iUK4vyfPEwX^TLPc z=*=dTp1_tw$tlucha>42Eqds!7|sffcQAAZ5_mFGW;eToyf;mf@zuMl4Eqh%qFTGD zq;VL;O`$V>@a2&dO84bAj+0&AK&o#wyikgSHD{j$ z%82IxKZLeW$-aolN`0@aP_C%#4wPjA4kj}}h-RgNp=ukmv7uqnjf~jXtysIH=6{xG zHNBM~^a2}QII@^wvv~R^fbSvm&*YOs;nJAtJ2Py!ihaM~*I^H5W64#Ht0(Gk(v&dp zqYvAh2Zh4&LXwN_H&<7Sdj8aDF+ok)>~XdtWVkH`bfY@##euw=!UZlrJOFL*-%*N& zG@gpRx%orrl*agY40doA5up=}W*#F+c}xBLD#C8MA$vBe)VwjAct0Au=PABT2adoX z1r2$uT31|(945D37K`DOZbHmZB!Lq51~~StnOnIK#b{1s4szIuIHbHqg7k?jY0N*AZ8-L}%5v~T zHsa+fzUSSrq5fmhH4J5spE`Z?BYw&ox~QM#`<;oEF!rJC);QsKQOgDfJN?gs%f0>N zyugo72|oSMT9SEHS&EXpW==*pJQdn%%IGLmeWvO>CniX5jvwN$2p+`G`B5Y<951!7 zcIAPO6^No&owj`A`#M9)Zkb{=sDB!MMNeMcIjx4(u1y%DgzY@U-uyI7yH)Z&4z^{Z zsG_vbHp#5vUcey@o-6<_((|RZ7E4CYU}k%q$dgHGQ3PKmbHv~vOT^Oq6!E^|=Q!=; z1}7}hV4R2^$2A(YOdDxg-$*|%N_%SzcFevK=;ecq&InEtAuNmtcB8p@POLQ;yWyr` ztBlab0RtUVs_~*ynVX5?-VU0BNN_9xqz|tuq$Gda$fzVQqRPAU%Z=HvUNC;&HK2=_ zhBj*x+c7#*yKL1DzeY(`J4e5066o)mB_S3vth!)Pv{Lefbf-j{40v!s_HA0`m8Q(b zQv7n^?9~OkT;}l`&b;tm8Q)7ss)Y2;?_EuMqCcSk3YoRfpT7iwZnLN~q3<5sq zDZpT7%+!>Wof2V~u`=!^Na@oAZ-~@$9&D`kROEarX5FAN9W0Ito3$woM2nch>(9M( zs@3x$Yh9KNfAWjKoV=6v>QOZ+H1>7t?a;VhY;4-=qa}MZftfpEQav&YPdNe+SZ?^r z#R5&>d8uPGakFeZ{jcZ6I`hrWCbRskdh4!FUzyX@4t+| z_6eN}Nu$;2SxbuPZj)j#aCR2T26@6GH&a zR2(*f2!L1jeTjPZPBz3Z$|Fpy6@@aV)&zV%j5)#z^6rH(?|epNvR|jrufkG`>sz11 z@HHBhhu=)q135rJB+cPBS5H@y{saYh-(KB?tcw6~CGf*~3A+nydr1?(B=d*_-3^~R zLjbu7#7t2&5rh3f*#F~x=3lMN|Lc!0?}lvLh#KHCJ2+IMTZlRTzQ!d17xs6-i|IH0 z1!d^Cl9}rd5y7bZXf3!}KfvdhhB(T6l~JzG`@eOM{QvYZ^yB~TV|u`F6GTe*7Zueq z7LQ<%$q7-&fS5D7;72t!LGs@=)} zWQ7+57!Z=gIKlql4@Z|k6s70hlNV3F9hg!*csu;Q{ZiAXd%Klueyh~*3Ghj0^@oLO zpduSK5?)G1PPpz3SCGx;D>JBqR6+9I9My1B{8xem88^klH@pP%mw z3rfx`Hxy=Dst_4)`85Uy|Z6*1^Tgc)PGN8SHEn*=m$vUMM2=s_sM6h)`QL_4!?A z0*niHFfk-n;Xc6LRlQfaSi>oQk>W10C1%_n?SK>F*Z;teUJzS*K0XFVSlEzrM!|mlI`+<3FSPnUft^D>(0s zNZRFjp`VaZPdHF;?ONL9dq*H>X{uiBmCkFX6!j)ipW%4Jd4IOb0s1E>%xFl40o&JlpAe3&1fRPi5Jami)CErWY+lX9wUBG%1RBYlB-a z+Pg|S)K^4W;1Q{AmvttZ3BG(AiJ(b~R<^|B@x(cj0dyr1qt!;TW|b0+E03d;Z@u=|>LHEA9;!~P#4N!__oHWT*=#rLu#U)#$;>O!U3lhG$Bod8<;RV~m|1i0P z_si+f9KI?;USrOkN@;@39$2v26eVtqM_Zmk9$iB%mf)nUECNSGMR)pvJ)U)DP{`2L zMnZOEq>v&J%jtoSKQd!+xISP^bI=Gq;9jxoZ;i+$VpULs9O9OV?w>*phT>$G`_cWa zJ!b?RC`&7FINjM-XggjkNnJF5^Z_}q_Wh7^+P0{RcL^62(|@K1#$>CJ?JLgWTT@39 z(@JEn420Qhe#M*o3%&A}M zM{a1|vm~7{GvwbogLK8@AnL*iyPbSw?6clLS=U`z5CW5t^q}$g%%Jd75!{&h41$+k zX9aX-4FuHBtSL8SbDn>^uaZxlm$T~RJ~Xyh4O!JdSa(k_aaQ-G~7fM&F#Qi-T;Oa{?y zVJmZy=woGq1fE(+jX{{vtEGKC^q!HqAlhw9_!HrQ9gu}9ly0W%DR$R%D_sa_R%_1z zAFw6UW&8#=#*$qEj}+gW6Hax#ZvkS&x>RzB_~z+Myma)OMcOUm#-%WJEn>p`Z%;rQ zKkSvCviiPDrPB0%SMVfSI?fbVE%F6cc>RXA?u97*uXIN z-4Q2lJLOLcVzxJaE0k6}jeT=VJ~5|uFLB)#HE63BsIu%osDNLG@1}CxS%%Xx2$E%z zPWrGZ0Ji{M)t+T$gi0P_X#|MbR*lB9GX_5V6G{B*a!<)1qlr>4Ln*yg$?otNdw#hmQUIeW&Z)u_-$}z&Jv}2Sc)K<812Xus*6pejnd6~0clw{7xXU72n{GK9U@-7{>S||2f%-40 z@qdjLVum6xnZ0NAf9D}Ex;EYaU|pN;f2^*p0-*mpgMx?pPcJ5>^zUA56_ZDa$;RL{ z`LI|`!ZsJ?e=a1qF2}AerZBODpR$~4^lPsC z$DGFT<_Cj>E*tqdLrnVAd191A$KISN#HI^d{J}}+myX|$f@=Ek82jB`U5B8ixDPze{wS3Qv}gV;*Y&o^EK6}~lH$dw`AW`d zhu5z06l5bIlB|2dqZ2@kU*pf#Dg^zC^YWNc|`~VL@7^Y!vx370IuBq;u6q zYPpmFegSidoo{?&^CdnYjhu6w+0&9+{+Sm$t`4JhBET(Ykcx6OT;FT7H^ITLoDk^o zPziZw_&hTSQFbbqKtLQq(Z|ek2%ND~;cV$^ICQH1u_YZTNS=I%P0=_$MYy?2=-AL` z!Ga%$9psnbc`kTR;n>}OZwY1%9Ch5v=CfAXqmY#cRqA)&;SFDXLfBTcre_{n^~33V z0T2S(`+StpK?QkUK|h3Sp(&ITsx0zk-Ts&Sb9W*MJfgvT@?JA#`%JkQl)D{Ikw5?? z8WD&&cc#ygQ*}Fy<_LdswVoCk##pz_nR&WFO+e6~AUJb;fTpZ}ES6M`zyF#evq6kQ5pZH8ZFd;){RrWa9 zErm}d+9@y6lforZTw}m*yJd-Xhl6sS_Tm;#7BMt2&xyg#JcSk+?1>7M);Hu%!qGJP zl3u22JEi=I4TYO#mxoq+peB4s+1Pf(mCBd}#B1goS4Q0s6lGtRxE6sXCbCkKGe+@-|P8cq`&!g9*pmKW>%lq$MZc?xy#P>NyQfvZrDkUlM#F zS5yhzOH`NVI@+=ZIqPLplOppN+u?A!{#+iiV3e4UdV8WN#QwXd=j3#5 zMImD{MCHx%ul5hVVqvhe+-#g0I!MI6i~@`)&dt8^qu8^F>(gQ!mpvA>4~ORr$H?F0 zett^maTZNS08)@+q>74)oKTSoe{VW22h|>8`FJU_;YXXbz5=l9bGJyVVMJEJAMaA) zzPzn0x&)o((b)Lph5K{2LJ~R3l%TYv=4NKJ?X1a|p}P?fm5sLDe<{yy^59Q>|}HApfoDmW;QVdhspB#*5~d@c*y?OEr7_$*0e?i8`MY?PehlGqm-3`d(EHL}CG71+7=2mJ3_kt1VIug3h+Mr}pV`1gRH z2J-&d*M6O%_Fozek%NwX`eVmR*q!4kx-SV_1)ix$qN^^@yWxR(Wp%aTQo5t1!uLTBLm~>(W<#X z(sM4#0i|rdL~+~Rr6hBx#BT9E>VHx9mO*i@ZMR@|Jl-3cBb z(2(FEXb8cbUF}e=ce;LO$yP-=Mm23 zy3)_{@V9t5*2ugzW4{#_Q^>i>NnyJ?5ZN9P8GfCoR>^Ljy@%KnlB=huHKQ)69(l~^ zG;5HO$T)z@y^q}Os$q6Qz_pR7-O?ogXgmLhbK*bmGf;r=-<{1O_q}CiS?eW*FTZg^w*g1_4PN!^jZ;bHS@=@0t22OhlT#_N+z{V z3#ngVdZ$do&;!p4jnms%YJvKzY(i%V#|IO zWX5-a%&0Y+S$rr{2NJqKHX0~KQ9gE_($tBxe3642iqx2O3wKw&?SyGwPbg^fIV~N09ZlnG&GEEiq*q~2T0Qz<8(G;mj^jK`lca!a z4xgUaiFKyId<76gZ5g+Q6QiyU`}^p)(#n&Sf={?lSN|%6Ne&0;dk_Gq`G(@>1Jy- z1g)cgOdUHK)sK^Qhc1S)N0`n)hT5M_VfnB-WfdiRu87u0lyEZ>u*}5_C0Pxx znGZc1=0aj8e=QYJ&MK`lzyD1&Agxxno`=w( z@b*2EkJ@4CF=EE7R6j+~_!US;+an8L@Uof*XJo($?Yb|xH3#>EHH9bC_|u>bQg^WN zHy@6(B}`o&fj7!g_M0GQYCt;nM`7idh^WAuQ=h=dU%1Qxmo`l^hu5#59Ho;K`FwW_ zM~mI={rD1(hmt`}vEE22$SfcqW9oUNptI35sXM5YyMyOwCloZWLtLwm=5r1a#+#$)7 zVKp^6O+pMMLGO=iLkyROF{phz0AnD(F~JfQK?p~7O%mpua=X|NM&;?QQ)S%MiHlhJfVb0+0_RxDS`sB-(ZW19!QwhW# zxwglf5daAG>7^Yiw%-a8J0){mFJkShHSpTQ7-Hi_J%Ly<-p5U^%64DuoptXHwq9c9 zOc+s(qv(Ag$$TL*JPoma=LT@adHoprjD0%-52(k;%g2>eBdV2*K{0*8Jw8pmI2>dZ z<%{?hdo@mj!6Y#zHzmlh=K0WHGFQy-O8=dMy2#Y+jaTdJEl>Q^Bgpw&<+kae(tgmK-6n*WYk zL6(*4M+YieLA*^fZM3klAjWfgRF9^st}dT1R<41wI#FU6d5@@*p*@Dk;NYZc5`+2& zY^+7a&cY-IH5sY4XCFPS???LCCx`f37?Iei`Iv=a2QBm%FWv^RrPxMKfQ9|{@TVEL z9k4=D-oGm>EZufjyePWE2ja(qq{-T{L<1@;f~RFhzmF*APW)8h>3J?NXs?3F`a(EI zfbh;Nd9?YM16BnQ-T^v8$fE_-~*-ERXOoI&4)3HkSFn;9S zgN#EZkl1N@x4V&l-T^qRWdzGA{lo;<8RB8z{r*AzMqE-rZ6^WVe-ZeS=zgbF^5kCc zkkL*N`lB-TwjrLEQ7BcM>KHK?t*Dgp0aT76hK?*xv-Efqu{Xr8Md0;_MKolc<_-@B z;r!8V>pw6%AG;wkX`A44fO@!PN<8D-~v z3Zk+?WRc@3HL^SI*DS7@Sx>xD>(d=a?R9u^uK)4O!LKX-8SLDbbR7Oiq%TIh<*xH< zaE2%i*1sR5@)cj)iuXFo3LAI4=_oXMBIB*w0dav7a5KxTeh8$4T{sD+Qn9CL9T zHRxC6@4Z%YiMTLC2qMp&KEVIo(_II$u`8W0T)NI%>BNfekY_KRZ~ZRD`r;^;9xNLL z6?39wXGm{W!9|o9O?#fkJhg;qMzB`Qbcx~~lvzEMh&(-s3MEeKzCC$Sf$86|EOB&6 zSNrBTY+>qpdTU)VU~1=Ezn4w&UWPI;MudW!ogwk$im4T~V`vJ5LF?j2pp7JcW_FST z<@M&&WH}f%U;gI}TEl2|FcqgCWf@aj)kmS$H_WL1O7`7H47nGGvKx0= zfjDs!&igSZ%EkzrXmGs8e18iST0I*I83iA+`R!XN#5UvG^F4`}!z&vqv|{W8k|at7 z4go1V&Lxt56#i>J()R$WH@`8i+B?qUc}{n*VscOyWHA87`TRPSL@faoh+uv8`F%?= z@#(i8hSFCqk(DZlXr@+r&1_RlaxmI04H7#c2TI{v5SN{(6T#z{g46qWXR1s?337gL zSr>q3QWko-@djcj8U<<>U(%L6v%z!rwh<65)6TZ^1I(UgkAr9cbb(F^&V$O;0$^im zqN{;vWo>CMKr27Cxq1hxG@%$lW)aHz?B>S32fB&7xFvI|Q)id57vh2h`#juheWLTO z<56#HafhTro#NIcdDuhTanvy9fuXd5M} z9MgZh8i=&rmu|x4S?s~CX$c^5+Kka(;?XL7r(sRms$;%=7rk(B?f`hiZ^;t9KaJw| z_I|fj6b5Tg%E4C=GvaUd?(rzFurPSnGuX_)zG95aqz@4+s`AsoCN7rKtdUv;-I(&^ zoftT}Ql6Z3&(qcqMc0ClLjYK7T5naI4{_s-EMCA^T=ozqUc}GjB5oxTe?;B_ozz_r ze(IQ_?!TViEoiY_VcvIA$6bc@@-BRGT}FLvREjew_E-BuTv9j7M4#j`Y|fNdY%yYP zTW@deVN%qviMgl0#5k09Mj^p)^82;l_vC=3S$~V|_*EhN7 zRH??(&`Na%$TlO}bAhb_6R%QpIJ^xp+AxK-Zx^X7`vaRE^#b$U}KfTMl0bn6c+Xn(P*(L8FM`J%-g3RC8a*-$F0e;>%B^wq~DaGlJij;OO`;wp#%MoCe90 zIaI%LOFBDQL-i&47*|FEqSxVVSr(P%WWf9hwh<#Tf!NOTLw;Z@`2%WBVNJu%dL6IQ zPz*L-Vm1F*pQrv5L40t%!Je)rK-GOaM$lw51r|Ucpmk#;g1-_!&C2n-&PQPK?AJ7G zQDE~=l(Y5T_&`y787eKqKlnzRu@q_{v6CT^h-el=@lTv1eSTjidtI?8pW=-@2?1kI z-W5sOB4zZ?ZGp$cube{l&uC)c5~@jbZ=R(Nt|Jh=D`Np<4+Dx?7e^0jHCypf{F_Rc z^_F^w`a1N+sPfXU4;g)FTiJDp`y|YyJ=H`|4_tVP?hr3j?w;hawHKmM^q4}_6cvc` z`-Q=I(M=QiwRyykH$ABKzZrgL?Ei|uMvg%U5TyhruJ0v3?ysoYBOY;xL;^ndi<_*< zJUk$=ixvET!>j)j%KhK`DDBu}+SwX8fdA`7{6DGnpZPn|>5tsWBj@kH4NSLxc{L#8 zKY0~Gb#fAmovJZ0l{>X8CQldP@nPzltrFtsW7~J`3ovC>;`?|q(jFq&!;cJ(1@Ik4TxIDp`zccZo2bPvRyf58qzho8h z?hs*L-rMeSACwj_9Kn%l@-+HInieLia@(I=uM?xXV?XDKR9_@^Do$y_<$8*Sz}{`A zzU}5)R$FE)y2{hJV$CTpMDge2VKcqGUg9&ZVycK{f4YW(!RGfMXrN6hZX~oZ(q=|m zKtW*qX}C=!TSIg*^6jmeHfBvg7h7T@B4t|bk0;8geS|1#rYB=wW*DA&*M(iLs&Nx$ z_3<~R9u^`EUPp?4(sPyPz}erqL2o}ia8h=v7&}__oW12H47CVlg^6ezGk?;%jpwF~ zwxVQ`K^4G5KNHn&ewl!f`DgwfznhiJ5sqCiK%|VLVh$9580#+pfwN^jYS@ol!2U?AqJ4D=5@!$lTirR5K9#BM6v7Z623h(|K#5GNJf=%#k9 zg#!m*O8sanE%_{L$gxeIDJCce8%nu{C45@J0bq>n5I}_)*i-3$?TTNyzJ_hsDWC6l zQXK$&%yEimI{@M>h8ckp2R;~A*KUhhLWyI@0%htMK;8Xxjjl@rH#5zBsz*zf1d^nBxSqRgE za&Q`KWK_kN&m0PrT{#7a3C!M+OUso54cAqp=`)hfv~rXy5l+9oZI*#ij?kPF9PR^-W13(O$MP*BPCKIp7;t}`mb76s z!6wwxZ5xGZQ!c)u)84pdQM2P?_j9o@CL*!Z(i)ZFN`%EOBSi@`c+|CmKxqMo_cam? zr6V(on^`TZW`^&Y2b|7Mmh|Nh8dk@+PWH8*`dqu@JU{V3IyGXb7bjl=8%X!X`N33_ z@97kR=xfJqHnZkV+jy452=>s$^!mF#LI&s3K?40N67uh*rAq@KBjXLYDvtD(xhTrI z5LJ69kDV9z!9m&NSE_hU42A?6Zd|o1;4+pgh6cM&6p+6WQvgw=WM=R-kBW|`HRd(l zJ0bq7C!iapz%`gk4g4O3m1(bV^GqJnt@^4WvaPmNMM7*wK=B=Rd{>9z^35|o{KXMb zDL1&jlGEfPYWa;~jsZ@qOn#II0ELFkXwLpGKTv>%2#Gz!vDFaDZMd@6X_ z%|#SXOvl(A`A!o6_yJU&_$=yJEcwpxi44jYLV^T$kQo1GN_t65$@pYB==Ism!O4|g zC8V#Ov6UkY{X@)mDC%{8OtXFk;^dKT`OFN0ZCIR}FpJE31<<#i0s&17UuNpy;J(~Z zd{k>SG(~#tco3Mxd0H+kW8|}ff`Q3t8)_?m{HyG6YqUV9URjYJi-7jTE^UFrgxxOK zkW@zyrg5NyNz;L5lGez;2@!dQieiYZ>y`&22j!-#AQLOmH`!2d77FDMP!YR)iBWK( zpU}#KfCuhd+KM&)KXX)Fia*4ECW!Z#JGCReWz>OjE^wP|`|J_0K>IoOIc*?T)+^WO zlUw0@e9d$2Y}wAEQY3cpjmcCjA(_+pWRAB_#O)snjpaHxd#!#R$t#_>O978P2hoPl z$spSFhJN7ohty{V@>bl@dm4X`&;ZG(f`YO`yPg+QEjJ6)#;Jony_dQtK42rOQ z2nL~8*QctUxeS8GKvw7+73y|WN}_F7R7xh7%WLt%w3|VFl}$J0>Otgv9Eum~B;3%L zrXzO~tP9ArlDa4W&U@{u>m@-Z^fU1`;zDPc6k+;zb)ODZnCj8YpTp^q*a^!WWKiBY z;k3@Se$H7G%yi6uAoZg2c-y#>Z%u35vNO$o^CO{OlxB71vqTRu>={Ev&*)|d`jg@N zFJARvm$!uEWgAgLd!f)ysV{=x7aNW|%*C>7-s42b>kIhlr8Z3(+IHZe#tO-p*0 zw~?MQTeK;GALQL%t{Lhcjq1!PA&&ROMokyz2otnX4D35cXB}tNq7g-)66Zz|-+*kK z45-G5R7x2A>J&`bimXzi(sDG0Cg>^M{jJ!uQRn;^fdLVW+VJ8&#LsLy69k?REP$Nu{{V1H)c1i>0hIpn|iwxORl zhB9S=f{%Bufr!Kv#oGNNQZql!J1c*JAaZ83!wr3B#nP)=Piw%!(SxyqSlmV+;(Q8h zH|y{%pPXpJM>7#DBeRz`$)n_*{ir;02iGh@aaqa^2o~mkua1r_!7^{z$i$4&kkAty zYzXoW{Ljv2ujSvJ4F>SvyKp+!n6b zsg4yPa&a@nh-^odRys%uHxv}Q&{OqkWl7vIxPSDe-s-h_IU%9(`#tCxleTSzRLKNW%vhqbj+;hY$?xv=DDZW4BxNormu}*$ zH?0Nw50$*uuy}k5VOrb6USLYK*hmS;6?$CB?bg^G3lrOlAlpJghxv@ohXUyPXfh@f zZSx83H59QU1EZe5q~m2!SJF6%nBS0$I6$LQ#-SZ5iDE_eUyL(|MJx+;%9=gFEV;#* z(s`d)ETf;mm-G_X=X2uSS>Alw$#KaSOe|GP4*aM+N`=85w_Pgvq#cfMOtEy3{NEiV z8LBuM3Nje6Z_|cBeKQH2$qj+?8?^`seCBK=7F~tw$DxkNzNXqq|SU>x=r4Gb7sU>y-|p#)E)iTfNADgdE4r#C!TR zu|Q`mNDcu>D&YVa>I{S=U;6RjjqtEz(?;|OHX*T-qpa|5E-zSZ_B)RLYvxzC0#l*D%7>Mw4Pt131j`f zBQ6pBK~CvzZxj_CV!4FrqQa?CHAnga9`3#1Sldur?@rWu3@`=gCBDH9;yPfbmJ=n}@7-G+PQzJ=sMnzww@GQS zbVZvfswiz@Qop|kT`eV0!7=ZEWGbP;qw*LHuaO zn4~jX69(}@%zJjfKYd~~RWA=B5_Q@vfw{4qjG#rTG(Wk`V^nq z%G+Hb@VEVyVI~McWn&A??;3hbqKSe?I~Y-Z6c$kk-WUtkqQkfou9_!?|hQ8@yx$I-{BaXS*$f_x0iBR`xBrEg{ zTq+Uca+{}Rr#xPA_mK?jmMW6A@MEA>Wxwo=S->i-msU z+L_`%lj_9taheoJBCDYhvx$q_pWNg+i-*Kc(Q+@=N%@jDaM*i_GsH)0 z-S&uBC_UM#a%j2@Z@kw+EK=tG&3H&fAr8+#H@YgIaO*0+K1LR|vf&*ifH^vyLN(wK z)q-$YQhkiRRYLiXtuE8T@7IsM-^rb~ark!WA*E9sz=&=iFG(}g{ripwD|@fuHj6GW?r;7XDRS^Y&VO^R{+%r$ZLEJ&B>ygL{`yz{ z-Px@D%cqrI|H-G36eniM61p(^TZx5Gc_!X-CdujKAe%2~n_x1%k7mogyyVqib=Uh@p>P-y|;c-~MPG^!99;%2| zRv#VCt}kpu-}x^kard6xt!|;o9LX*A)b3h!hugnQ!_emvmU>T|z`RM1_XU9{pMP}o z^D0xDo#oO$i~n;=dyhPK`g)Iob@TPGfcgi?!3>FJq}yaTeZ{3m;iYbeASGiINMi5; zN3wY{iw4Zc1I|i0EVzC5mYkN|@10O^Q|Bl8$0Gi9b*OM7d?@P}-taDWlGqrFNV$W` zmF|o3>vVKqL15FDDRf!|N!|7Brbf!X5{E1>w%TUUDT5}pO)JJW(-(`l1g6m-i<3$m z5mZs^2Dh|#Ocx?FN*i4iOWF(t^T4!}J&eV%q;Muem%a1oC6UILQM*52$w=&Aqm2Z) z*@|xx*8EAR`C(+#wKl=CzhCn4aE_FlwRn%7FK$n>EV=coIZ!aVl)b0MT(VE45vR+j zBXqF~7`Q8Il|93*=NP3N?8RKpu^+G}@uPrUqTuNumej#<9vgg=QT`~1H5M+nZM6*Mp69eVxvs zpn`k|B2bBVYi$**bR!F&B<+fRjKN{gYC+LlMGVc}3E$xtzY=W9vi#|*yQjY=xV1TP zC@9I`e-qxnBVy`E|8vHXx@-mzaUT}wFL*@(Q;`R~Yrc-9kzc$Zg)NDVC!sjLk|u!y z9GH;Ui9%r2SWgHzl$v_^Q{VB@>e$=3Q=XScHZAVN+7J-VBQQslD-H10Ikq;A+{fb+ zv=%@v99<6ao+y;`c}OupJWt6i4&V(ehRYWzfM@0FQ@_!~{WdY@J0yUE((KE@fV1bk zHLm-VIqN;u8k^6KvRUhofywSc`=-M^@h3{FIR11Wrx-EBg5Yx{XR7)9tF6S=#xf<9 zB9=PT`6fLvPv_M{8Ao5DlUwh=yF{R=J+&3XnF&bW84^2jjmR)f9b7|8u0Os8*@wvV ztA|RReM9StMZ<{k!lLYol+o}UuiZO_+)6^QYPe6_wglJT^y_|b_i4LN5G{CRrnond zbt666(D)9$KW}mVE@O{#L@u)-X^6|(gZwE*@H6hG0p9Z>n%a+qMROSG$?(KUo;9NKGIYha*=IIPL%+B--1x?Cg0<5^W66e#bRKc| zsBJ2G3_#-uPKW6MkV<;;j=BTa)wsZ6A(Y56qY6L9D#xJdrO+BC+uzJ0(gw09VIb{F z+zlP%&Kt53p6ZddZ=1)S=t1|qj)|e3noxN-9%+O)pz~)gJ%=Ug;NPs$SJ8s@s%^?% z8tzh#?E4B~ryLQQ3Cj=aq-D1KkhE=#^k?i7K%D_L(u7z(uN13Uc8s7^FsWj*dact- zlehi3vyrL~4l3&>Ji3Qz13B_+OQew99gX_F^tPEpQbmRkZ-&>HPi)bKtBPl)UVtc7 zabk|;p`@g<^LX0lm5hOL;fj2JH7I13am6#eg9zkO1s`v|Znfbtq99$I1>Nh%;$m+C zDRahsNKc?Xv0~#AcG+E^shU*2*7C=jZvDnMK@Oi2MR`-zuKiI6 z&o<(WO_2XF^E{Cw&GFg`vu_>c%sL_yB=dm+9h>>Ym_^b4!!*}i>H7%1 z8g!ubt6?yCjreoqI<}WcB-3_Ko0ic7vk|_t5bI=HZyn-s=bgp%ZuHZ?VG#eZw)xAd z$T-Qr`H}zZY|vZ(<<;)>|KwE|Qd^ik6u6BB4rkO`EznLZI0Yo8Uq>(o1Z)vztv$2- zG3553GBdM^Lv;Ms5LtSVZ1Ib9$LTOX;Bs-7U&6`@o_d*dR`)>o=R9V;J*~mj++>|U z-{cWTot%FmiZY?=bY1BW{JK7iRb!k-x>RM1ke71*n?c1J;_Kt^WX|^TdqwVGy&vOA z_e0F-qoML#h9OLh2EJnnl(P&U|7O=yuEQl3BoVjLk%{&_erGN(^Y?Zz@*_?@r)8H^ ziAP+jgnO)Sd93Gy6HlQrI)M7RSRP`(FCx8pU-A=A=@~|XV)po$lVC|Ri$du?#LtmC zq-(k!jkSq0Yx8rbul;y?6?LkNKM+W_Kwy2K=RgM9BLcS-(eEf`+33lp3sG5PX7ael zE^LNJhHTWHKtv%yAO`rQElKJzL0QTYKg{yPB(|7dA4YkD7q>9LAr5fP#l}%1*>FZ; zr!uHjDgQ*ML{^KaHS#V@;Bs}_O?FIY=)I2K$c^y@q!JRpP5%}Mdp!_Jy)2OTL4XJzGh7oF`QmmY^P{O;4$KE-bC_0mBpP9pZGym7I0;93ofW7A zItgtb-;soGCa(^l{npbtM(nwlMZsROf7^)U1%JYcMm;UAavN?T(ILIOFtsl4Mg|dS zQG-tbnM}v8B|WF~DjMcDdaS1I-_!iEr-*Cc{;S=mz7U4ze$CMv-J7 z(2reX?gUmsDwyL@5Zg`tSwHz-j!n0;)fA^7wi-<}x8=wQbY&u=!-e~|F0h2C=KAwM zPZH6#>T%I0DW9`NDgYNy?&7FGr`GvfZnd13my}gs$gOWKGt9o)B<5t}3Y}yi?H?x3 zcdtJ`T_zHkdO{KHqNS}B=?ef-VhTTy96IsC7^8p6pvkr&&|ba7&-Kn`Vo{*>3RAUi zDE^Kyw+nlcfy7R;Ik)Wq4uvH_L#4%CHCNQzar9y~VT{vF)~_K;rZ*%@vA-5MsA%yX}w& zwvqa<)SGWHj+D~UEBKVkM39fLo^yjMf=)x1?d9Tv)wE(i6O4{lRLz|{2xlk@1nZuL z0jBM;{Hm>j+akOk_%roT^q;EJxwO26-T%Jmx}pd7w|vvWtV8QXVyE?)j@I3}lM5!u z+#Cp^V2%5>iI!D}-WBdFz@uVEWm&M1T9h~uET3-RYD0rti*L9_3u_g-X%Sf(|S zf~|K@w782@W$j4fahaqJt~!Kb0O|z_1bD;vE03LJ7R|D#tmP+sTt;;O;on-r=pK{kNJ(jrJ%tm=_iENM9?V(9TWIQkEYUYN1+!Q3M=E& zD16qrB8qv}(Lv)I39yg=5yum4MA>lQlvzQ6{s(-L*dwx)p-uT$-)Fhdkun>W=cWhB zUV}l@?a#1e&-Sh)m z%N0p9*67(v1P#QghUTqYIoW-jFuFPFv#pFkZGsqSNK1+*9Za3 zU<;erU1Svh^#em!ujCtKNx_@=dPfDLH@W27<=$Yvt= zOGszK{y>N994>dt#IZZAXFoA&dZN+$b^0YWbDvYz-bQfb?bNe}2sUu}Y^%&SY{gUjDg&nZ7=vv;<*kvl*76FejO2NZcIGQ@cP8&$-SYB^f zSid46rzQXEvk~zB|BzSzpHnafOTw^-6~=Gy1)+RTT5WHWO`d?9;kEGhz*l%Ry~kCx zx*w~8`F*@KXz~89wEA#>lo|T}qlEy<0U^k3O&^ZbKg`M)^iM@38|36~(QjsmAbRv* znIMkT1amw%B3GNeaim{57_PKdP;c& z5|W21kubgWYG}INYh6J#$|p5xbMrf}qTIhLmhkxyI~H5TNyysv!}We<+=3yIzuqQw zwV-bXzdvz?_ZyMOf&uz7zFqW`?<#10=1h2r%V@j8D&GIpBQw~d0`ZaEzizyYC<=|R zy*xT@4AtZ@1Jr0wm!c4pw5q2HgUA9HxPJo@I}tOP!ByaSz4;q9Q)W4ady}f5ABx>< zQ?Q?`*4nnW>{3G!P8gqN7;MzdT8F$THAYb{^g!jLwx5%MpFg^l*UOZcZqo^!&swLv zmUN2aA{KT^A-=J#Ci@f|xsE5yB3v$^i{dG%w$k3Ht75x8arVZ2$(9Yc@wi7ZY%xd> z5Q5JUsrWJz6*6rFaodJQdMS50FSJphykbD(ex>)$YO*B~H^HVjb6SR7@iS;dm2oc; zpCdjIJ&zNKomewY4H;7e(u8;&zQMCBY#2Vo;Tjm3&L$%z)D8XH6wS@h_qPT)Cj}ST zF=`8WCm@N76=SOhDc~R@Pg1gRa({kkTu^VM|L46)KroA3SgZj$9BAHlMP>fWW+&uZ z@MZAIQh|74Ui7l9Dr%N&J#$ON45!YhEKTxr*ShW7eZ@E)T_>bZV_TU;lPMT`_rjx( zI7Rd0vHT|}pp}IU^%Fe;qn&lTk~oEOzBKA1Bz8uAqgcoeiJj#4FATpo@6pDAP?SVl zVL&OPqftHQVj$}o9o~}!T0XS%H<@~>o>1<$KRA<=?60WzLI(iR9&^@eYzd7d45--4uI zTeu4k#4MEzli>Bw_~$IdrONp7(*g|QI6;W5LJk=}_=`k`Wn&UH_xfV(O3A0!E`knP zDT!&Tk7g+)6Ix1q?e0je8<4b~diXQNKee`WeS3ck&Hak-sFHwoss&l13>fN_xmjys z<%R0RpPp3I@y#RVzBV?ueWg=Mjv>Zt)8Z*vE1hX|i2Q@{X?asN&~8ls>LP`qC4Zot zw!9DX#IYy*MN%IgsRq6XWy{gJ?g2z52i)7rqO_5C+&+GXyK+_Lvj66&S`}0ISo%;- ze$uk?!Y!snV*<1Ji}O~hA{QI$Y{Y2TmM0@RVB;8@!I3zegzV3ak_EGp3lck7O)+cn zC^NK1=z;Qj|SU<-ptP5 z+J>oQ!+MOb{6!>V1;$onO$AoVw~SU9<2i%#$8tRJb(xz9tA;akJhhmL(zf`b-z?E< ziOxOG>d3drrABDJ7WdK<*Rn^6Rv^kH)DZ>Vp)%uZwdVfdcCheIHlKTUXG7Kxg%@6YjvN zmxWe2AEa){(p2;H_{C2{2HH(;D*@%yeZO}asY)2E2(|WNnx^OQ569;}ttL`N;=M-^ zuy-YJC}04{oLRWNWH|Zz9b*Kd0x`uCTYs^}CD`fp74Y#gqoFd+&@8|G^}QJTX{w4W zJ#w#&^gRE!-D^|*_uXp)DHdzLJx7@cO1-~Ft1t}&nQrt-KuM<+4AHbG4(=HlByqo2 z2__}l$?5Pyn9?EcM!4l=6B91xb3wnU*kA|q!~~uj0S5$}zh;h+OYY>ht;iui!Cj>p zF&2eX8)TYGX2hTw8UWB6A0C`oGh!*$*(3g~`SPfRP_4}?#b0N7Wh6Hb^mYrd1R zBlCGLGdCS5MP}c_ulxy&@rH+}#6m#T!LZUw9AUkF^B|=gIna5$Re1bi82P+YR+n-= zy!cG~!CE#dnt_GNOjk#f#903IZmtFnX;=Q!$3x=fH`Yn&Trvco-T-t+oV>Kx{F zH^XWwwV`CJg$}-r_DVcaweQjjc)=~8V>h2s&dVo2I##CIe8mey0Q}pWQz4)C-1oL1 zK}UCHjfI;g%7QcBi+R5Nc}QAXJ<=d^-1&vMvYLl&PAB)NT+>E4)6rs$!}p%wDq!Ww zr#Xs!!fCi1`PKhi3pg0&|DI1yhyro+V3UNd0P=j4P$1Qc4h~9aT+Mbjlit4yXM&K} zsV9lM=2H)r_|ixcHF%9;W>+Z<*8+SC-bEcDos!QZ&$>JC-frtXYs2Gp z^+>2V!TII`OTr!^h1>6J-T-Z$i}Al6i9v53c+IV+Cc}?E^=iO}C1)-L` znCw;eLAOZZdgI*E{!Iv#5aBzXB1(VoLEuPil?@U*%~nKf`?F^?qxu6jl3(-(HX&)` z4*@7<@n`dlZ!2C+U^7dQH(^Js3aIr3peWN;Up@&=>%FfE)2h-6AD&3_Dvr_a{F1iTAXZMju8l z6DTcuEWItfzjOUOIR5F^>bKpzN*$Qk>?pK9wcYceM)v+&tf(02J}D&cm#+7A`$+SX z-wv8gJcZfFem)>A%XmcPHK_vT&uK^^WVj2O5;NOWIi@J4aH(T6m5PV0;z?TQ^1Pl| zNGq|hJHD68)4V$`PQ*q8SEcJSuJpS=-#*;P>WKA`2_E9!(vRpE#vA$C+Ju*t+tpqB zEW{Uz0(<570(%gkIj1rmt}p4f>jXuU#08NkVB1NNVMP*iNR7~HXRxbAp+Fytw_h<5 z7bQ_oJ{dP1>!#j_K!;l6*-xrH=s&#A0qa7ZLD>uHC)n|W$elcpPQp}|oHPkE1a)4L zH8ERZ<*ON?uK(kvv>=KZ>`Y1y7_V*Sd+45V7I&|GgO6AMXBNtV3$iRmc zwUD7r=2*W&hCaOMpMAd@SmKWZD21Faq4|8%0Cov)&%1AndQZ}Sg?P}|G&qS!vgGdX zCQkkI?Q6lNUEEDSM2F~aie~8TU-`>yGtOlfvy52`vk3Mgf_=ZuF}M_PS^ScUANs@i zx;nT+>uAkSM~mTf_oR_A^(zv)tn~kz_a+(k7h56elguw}#_Dobr-r%Qc-NC3RBWr| zs{+t*lDJi~ygJY&+c{(ixXlMXSW7)GiCJw9LGQz4euw)yvXWi($Hlqt6ppKAGG-hD zB?Kk1o^)KyrMSjFPZAMEr_k{v|D>~9d!-=3a@@H4V6}eHVwC2`vsbZaU4h7Xq~KrA z^PS57(9hugJD2>X^Ph9cKIB|dp4b1aP^L{yn_0S2ieJPK{Z;*Il~YW0sV$=BbIv&( zqeQ`LWZe55=iK}!(LLRx8Bjpj>O%=D>2;DprS%6-IHu?I6PcZQSEkd$O<}{m{OhiQ zVGT=c+pPNUq%VHf74fKyRlTG`ie;orgM;Peeo5Y)d#y1wDM_q{<{p_aRPmYbTwdrc z9XTlGzb_y9-Wz~?UnM@7PMxZ_?ddkcUCepfy1;bCh&4BKp~D~6kpI)+XVrN1@mK5o z1?yW;4*Uy6?ZYZ!UBrNK$YR;olPD3w8%R9Zrxh#SfJ4;Qcp4IFN!joCDx~Z1WFE(Z zrY@O6cX9Wb@Q5G>1tI3GA}Pu6I^2Bh94)~AyY@vdtBYCq46{qo3t5BV=M%>Wg^CO9 z_t+c;o8zWJsTBAvn_I=G@Aw&F+E#OHnkGd#_Q&ezEbs6rzn4PQ>QMgrS4m{J(q)xQ zKidy~?+93wwVtn2tEG=$^3yKAjX?Q2iO-KT)OWOks^5@eKM?B*yzCSE0u3A$&uS9A z9lCi%@epgXeXQlJZ$_fSSM-_Dj$79{)JZEAM;Ze#>OLS&b!W@k`+KB|%ZUjr($rhl zoDmzD>SygMb%>%H$%Q2co8Wn~i>~J{vOW58WQjI>K#o-#1;62{RWHN!!+V|w8=xG) zXD>hkXzmP8MWHRWN6hW$rpG>;;GZ2Oscc1a15{AyL;*6(x*s++bnKLsGQ?$MRb$-a zrA#&W{PF#Be%QF7$JHmqA8A54w|>@W&6sg5nG>j_xdVk_ifjKYv9_I?#fAf_G6%v%ruQiZ4Z^CW!7~x%Lca$atErD`F4o~45nHl0m2;NV z?#Oc|BXAI~jvjCpO2kIRNd4loqu}|C?qp_PFawSCVn7+EFG#lZv{@_0hbQc7qL(}k zffqAT@2`0^`IY-mp?-wV&P*W5dcg`?Zv64g^3Y%2uS+}e6|RH>?m1jGtSQc|Rh_vq zQ_f)(TTQ9mHuU`&ozgZpOBWxbsX^ND;i2RwPND7$-aPA#LiEs8XTBJNa;8;it0W|v zAmFuV-0Ywl)KS7wAACong8Hax8i)s5LX9WuggNulBC(SfeVzi!sj3}edMPY?5C-4O z&tmiAUt6A8kPn`!ymd?jsS(iVb??Yqol$J4QYn%hn~yVMY5%cLluSR9{IpU0Eq=)=QkjbCSSWkyNCg>n+!%t;`kba#|! zu`#^i+%}ONyoo!bqD_p#(QoyXeGM9cx5W6#s>kzsG40oF#G*>f(tuG4NQ9C8hrrb1 zL3%6=4@RvD%jmDa-Yg1vtVfKdB~px`69}PY%E%0GhOo&vg0tx>;>W-RDz<3a zNW;*_;V)Am36r|w7&FpxapnRgZ)Hz2ZvF@+HP5J6DBa+;cQe{q$4P_SKUacLb?Cv< zTnc^tr^Sr`$-Q0JDe3%_#^HqKlGvo{Q%noi$2jcW(I1`Loe6m}D_30C6B_2WN%P+V zUrfOeoIW)UWc>FymX8)D%iC>55et$h*4=ASIZ4LIPpGZG*-kCv4gJkfr<^i(`Q6(O z6{%LZAfOUyv__!O28z~DhFeI;+QFO|#+z~aS!vWL0R*9ho`$;glv-?&c$8B)V^1k2 z1#NL36T94%<`zGl?|79(sra*jMo^x{C-4dt)J2h}_}MPhMP$|Q{{kcSL^Iae zt4}?`^&S}Df7TaIQ#G!J63LmkiKVpUK2hkclOd|&mZIBAr<;h1#j@7A>qaYZ8%n*- z&1LlA5x1cy8l_(cbdkJD^N%+x=3hQN?EOzZ-9QS?1-Ou|EF4Rbhm}>s;uV*yNX=L^^IN9zD9Q1BW_IF zOFZ8Rz3q95$gC?)f9%I|Q#uJM-(} z?#$x3-8_4vmd-Z@k1%_im)5r4Z>F&}Yi{U?d^19xJ1ycRGyXa%O~nh7=3b)%cruoX zzL(A*lTKQ2T{{0xIF@ubSqQr@7#~;7|8e4R-La#Bz^U`$+mBPU+B|8h9uL~RU-ovvxQ-T8<$he~=5A^CE>sHZ)8?b}+rML?&x|M|h($~Co8#j*-VaZbPkK+6!?Dqy0QWwp z`n9)Gyp$VdcE-iNt@%0mqO21!)!l&hg5;U-&&i&|R%JOtw=WFr_Fh{- z1qvbHFNM7ud7N#Fifb*(oS$x%}y4QSk@h1&w-$(FJjOl?kjG;m(CNU)XA_BF~`ZhO* z0C)F9+;o)ugUfy-xkWznne3o70P@_yK!Jc}ehNy;bl)6EdLD;(3G?G0!aCQ~i_&Pk zq_U0HC@CE`> zcPft$7i_6>!cJX<672M40H5ed+lxK`SAP@fUH(~F;I zK-0!r^9MHECJgsOtlq$nU=Is~Ky2+4`>e}8yq_WrPE&Ym-8e`PYvZ=QLQYu)#{ z*0t((iK8O9dX-YysN(q#58&o3i~X7RT-s?~lNr)Yp&AKnZCE~fD`}ou$Of9CbfN_K z;U*mlj0IGL2^0FZb+5HelpZ%c>BDjJ1V9OHm4+az;=VLjHx`yZA$lD}Y`B3byLa(t z?_ssYQXr$a-V-pIkj7jsH#|H^jB?1(=@o$;DV;E)h>gOoje6V?#6@m>bMrP~ zv;(_V->iO&b{+w5xfx*-LHeCUi!LiH^o4Gp7L8Y&?LB$*iXi410O8UpL3c9`g%*j- zcN-KVDDEiQ5IPheZFQ$2W0NA6^&>2|2N?c^>3D4+x%2+g`NkOC=Oa8jeMBIM;Q60# z?PxPM=Rg;;KvE?T4y&-w;X;j^HSD?|KdnVBpzJj*D!~OvGz%nnE z*q^@nK|}0Qvm{pCfsx>})K_fZK7DGQ;xz%q1+fzruNlpr)mp2|XmtbKd7&(+W5%OT zSNEw?uLZ~n9Du7Nm7IETKX$6!0X#dyxqqwP(f#>U8eW;Kl7LNqm?+(LWGMD4IDhlE z!siy)=k?+KFrM$34$JG-LE@2e_XVQpahgM{@OLA0-zr@9rL6|abXKw z>Y=Ef`otznw}-O~#l93`^HX80p(cv& zQTY=pbk`CslMV;=8m3)%pI&V;)azjwUoMhlwHY!k^gda;`Q-&QV=|$r7*xoTy?~{8 z0?*DEZ-rq()l-pFsl^DTOo5>+gtPjldhladW}Kh zBB_b|2BM8pOlX0Eh-daIpGk-N2|0l5L{t%E_=q6{^|x{%@K&=7dCmJ$(**3=Gc&nQ z;o**M3M(D7+*FzILNN);N}AkbkfD+UiYwFo5}0KA#3wZGucL7O;EmDOm0z0_bKdfj z4IBo6POv~R+oz(RMA)r47Br|H=1vx*HShgcj!G`VvolEp!Sf+e#j5oba8reuXVta! zGElVJ^NN*a<|l5G3$<)(C+EK~==M z@UdzI@mecJ2JVuiP88EGCX zb3W?e7Zx;h`9pOYj8Apy1T-Sl+n)eKGUx^qbuEgr>-*T~!PjJf<5TJRYam*HZbToU zn>g9@%dedCyzU{JWWaXVqw*2n7#mKiZ zA{Q~%uE>JW1^8Ye%3q30e}Cuv_Ln!}I}VZAuD9qK>wE|^__+A=?|c&&kw^RVGJWK; zhIlAq=638$PJ4aD!@9kQof3^hs+Q(4798f3+E6nEV?=e}H*<9U;VA+%pY};v8U)GRviLs^`Pc{e~K7RN;{UcmE6%b3Ds=?9Od=X zi)?6F&66rZ{l@Tq*y^)r0>jh-5s>hjCPUC8U=2)!cV_j(f8Y4lTjqP`C&{8cuFlxH zVMOA`ZC|ti_YF2Tr66 z-FI|?k@qHVa(IJX8YE7>c=u}cD729)fIKCv_~F~)yk3UZrB#IT^d@3KlIWA$0s+_8 z02dmVacIyxlz})yrdw+~+Tc}9>VyES-c@yg-|C{wDN?(FgqAPY#h2@${1V*26we^mVGIKH9?&5t&e#+X=F52XhvgYrR2b0F7 zw%#MB<~QPq>dl^zn$QOm8IdJf9n1Fz!paI$iSX>~AU`5tV~RJNyC}B|?N#EW=b$&= z1CZPtPfyUjXO~q{*6}pb%A^l^|F|rKBw&UO^(daL_bU_=jMCV(cU|z2!cm3$6vdMC zOVg?;{SrPY*K)$b-59^Bm0w|%?p-`Ak_Qf+%-7^&rB!TbzFbVB-EM=@xm^8Tj+8aZ ze|iUtO^Tr0ndBuqs;aaN1KcbSeJ@{u4aIE@Eg3T2lfihm8)^hlZ}am+G;jIkxP8F~ zYOhit!g25s+Fm#BLW&A) z`NHzLO6~(kRogl5p9X_d%m{I+$>jMl%+Ss5H+MG}A{MU%Qt7N0uR44WGM1DwOwXU~ z@Z!I&FX(qAIArKHwb!}XSvV$)5_?2}kP;GJ_t;8yBeV>SPQ#|?HcFodF z)XGFjO={0fyr!+e28gDOs2~}00VyO}_*Xr&E9JN4y)bBvVuKtsS6QLk^a$IojHMK_ z%fyqFcOoj4DF7-Kh#!#%5=GyLjNY{XnpraXs-}r9?MSq3xhUzLLPC!k(|JX+5<_82 z&?VV@`6Y_}v8Inzu%8M3tax@V!~AQawDPHmRE5op+SB@e_PVzm{vu}0_!V2Rhhd0u zk<6D1F{GE8k!5L?relVWip&vn5EBlEv8N`l$`Y53hohsDIv$<-!GC1aLgyrPgyX*6 zSS}K^2dXSvm6J(~AxV{hfh;#c*T*1qFn80&#C8*a*=>c`h)^;SnNhG=tN-b%&I4`} zpv(1|R7Tqif7sj{!Gq*B9VgprSIVJUX+}p+o=D^0PhZT!L8SyPX8@fWYddbucy?|I z3+ZzJGd=v|2CL2)$*=Sh;mqa1i4-lcL8GTSzq}4XxaT zEwxJu<=+BF?Wrtqf&rl!&lJ&v_Kac#=mfmbLN=*)W+uSa&Yl#0-xZ=#5CG&An3}>} zt5zd^V9;>`(j{elJoRJk#wb8fF$^tyYXr|uTZ0uunOXPST+L;g*llAE#?F_O>c%k1 zT5m-U&-RRyX5YY!p3%SZBNjEm1^Lx!KRm^aXEy1YvidJgjT-4EcZXu8o3H5kz6(qd zUu}`2UT5Yk1*0=(^2Z)WP)V;2B)$epa2ww^lpctSMQ0e2grdZ+FZj3FsEfzR+fl2r z!KNn}I9LmF$s^L(L4^;maOi7UMDdT=Vchm?NkqKCVB*Ecw6ygYH9en>^OZqDCQ%cc zS{~>IzOT*pzqqf>_P@8UO(2{0U)N&)ecRgq=qI}o2l(iU*3K?X$I=+?>Qt(;Zy$rdHzgzmdTM$4w{~tNE@PBGD_L6_E$$0+OWNi$eS81W8 z>$JKzFhkuKUA0>S94~Bz5EyN#4gH^Y(|;MvChi#};)CIXj2j@zl-@F?^gU)xp6}oUZMu;BM>2Y#AAeb!2kh zqglOOrxJj9yE4^V94h1S>2)~o9oqgSo0w7ENjWWjUFw(k?{3D99aI1iP^@}F8HWii&RUl?CbUq=w}z-N~XM3QXQcORzd=f)BeLy(l4!zanWLp=0#)nfbRfp+#Uu&nF6tP% zTyYYn_ZSUhH%Ff-o+znd%G&N~f0?0%C$1&1#E)z5NhmSr&n3#5`2C*IWJ&8CR@$z) zq>BIm@OVs*fM(|c{gyP>0zzjprdZbU#% zY@+)y<25&mL@I*VrBeObp2u>GlK^=!f0z>d8#qI5l%7h^ z0A~S-k*RO0n*aa;9j)=*5Sl2oqU0 zRvx?j(VKiotm{uU0Ay%P^=r);lh#b$B{}B)_-FT{WB^h!ziCP> zAY}Wdf*4W|S)SgFk0^}#si`8WB}fePpZEkMyF~AjqO_sEoUAAmV|~CX?%Y*(^f?-@ zTi#mAw7Laq-|e}%`#xecx2V2iOm=slaq3pc@0MBEcIe9k{bxGUSq{s(;oJ*@wGb!c@}cx;A`o=1h0T<>0ftK=2jox^yAf5 zCUaD_1p1%FMSDSTz%6hn`zawHUH)2Uj|I#$Bn1%eV<2TP*`@Ytzz7Dc$9#HlK^!A} zUTY)fJ^C%MtZ1^VreyyNK4laH1O@ONjM zs(@yzS*nV6qs2O0wngScPUS)krxqN0;6H-MG>Hn+OFTPxl5+8kOqGB9^I`?;a*xqz z=i_M3iy)~{_s%(kSeqnijR1Ke`OBuSXt&4Ne}4S7ddv#IUBTdTkKHn;{mNh_ogr!0t~x0Q%~@$y==CrpQZ`d6`D zU-^EBOF!BiL8tSJv3eDfR|-d!OcR>P=#sMvvu;eK)lUosQS;Mv(O*KkeM zB?F0*56v>TKTRJt9q|dy(6!3UZ}dRDsP@;c=u+q^PZr2}znV>WL%VHoML1X8D%qD* zoXll9g4(iEIO#udwXWW?6e{#3+EyB4oSZ$V7TPr*;vyZ=!t=bUe4Q(1VFpLh8|WmlMhSr{b4E}_kib(5zk9@ z{hFI!<8_teZ_kFb_a8l#r}=k1)n-B2tZF&)4|tiAGH|)&$QaLJW62kPo#$gL^dGYn zeWLhWd93wROPcoXuNH0q-{(tM{f!-`qA$Z`W(&^I%0XP)Ca?SXFYsV;@bjD9DGuJ_)JTWp-KIu zXAGNc<>h4L<3*Vi_VMWU1XtzEA>-fPFegj;yV%;HOGku9SBd$rg0hi!}LjHmel_nbOBLvzhhi=pNs*$Yl{iw8Z2AAxYX^|9H ztSFN#x-;vMq>Nw&zbhwd1^>px{CS#hSK4s=>iqEYz4ErD@tar<$thWq$Que%Oz7Lw z*#^4L{iE$h^T=*d4^$xl1-}Zp!-ejZ^nL@nCvz(4#FSb~mS$dIduO#bk~2luKPcZs?0n3!!O~ zR8IN$IDNDrNN37z+wBcWRUsw_EX>?b7rv8yJBtB7o**7I9?0LWEleNoIz7z_PP%5gCP`HL zl0)Uqs#BV<{OEcYVq!iEedPi|v*ryJ4bRDQTtA{=_20utf}tVLd}!6EOb^jpw*G?3 zN+r6!Tr%81fCs12dObJf(?P^ugEYZCr| z7%{^A-@6EibuxU62_#H<^xs3r^Oh?r3b%i=sH9*{F@1W?S|D$FnO4Hk(%SK8-24j5 zw7P1kyTU5v^_zloOjk5qNEW3XzQ!MeBX`;#mwLT))Oe@07557W)X8@lf7lFm5iucM z$FnmScyr#2*+DFd-{yT4k2Iu-`7M8wGK|Q|*-^I_&hOS8)7*I^2VFCRs^O2(^|qr{d>!z!c37-ZY6r8=lG&Gt&oM+|_+Q5DglU33)JMtGxCs&J+n) ziivj8oulo*ZvJjs5r2yK$$j8(VFSM5?v(2G(`#Q=xwD%p{y8##&MWP?T);~(dDZG7 z+wWD)@uaBND*eD0ZU$z}{rz>gm0tM=sso~)VYpo=WhjVn;V{$r>6X=V2c2!RRpYmNg7{)jq?Najf&+tR(v)9In zmho=F(57cRQwm`MR#|jP%Zfw;XRvQF@Qk&diviuQUn2dtu54u9`?l{Hr{)!ZAit{= z6haeTX0#F3i0wmXkqpT^r^UovRP{t8(FuBeuOSnJ+&lj~a|`hYu`<}AK1KRaZXLll z>;wCx(H!Ot!y+JYcy`5y|Ic)lIc(WCaq!g~XNUc=#!vIKy7r|_H)Y&)1_Luc=d|(R zrLn~97hFA^TDnaJln&hwJYkuV-t+KoS!Olalq>;^Iu&h z`zQZh&;<7Hx(a1MjR#U7@CntkQtj)jSB9fMSQ2&GdU#D}XcO}uhh)&kX%)~x!qtru zc^}T|GPW1>0dGzXgy>B>xDC0{7IdPb6Ct>*U~CxXG87y8QVOB3#`z`*2N(Z!nRc|d zw{*I@F$}f{KZb3BE4Oj_JN}PvB|uXxej0R{q|fGC=FSV>v8#I*8}6zWab#Tgv)GW` z1BZ%Pk}g#~MgN_nWGU`2JMV+NNqiaH@P+SieM%rf%SH%ywGBRIY<;zKzT*oaV&OYC@pOwjJ#z7=Cu0I!Y+z=7uNUK0byxE;?u=%RnH6YH0=XescOu)<_`C-Lub1pLahXO~J z0co!{?TyT>;Syt(y|FECRZU};Lf_mQ-=1f0IEWj@KSeob@7`nd;R4~=!QNY3+&u6s zqf_J^&P@QI|0|`{jUO%30E@gX#Ozfo<`1m!d&)g}fI<#Tr17^RrJkwbRzqz z0j8n+OlU$=ZFqsd-DyX7o@Z=0pC`DQqJyxMF6x1;;23QD(+}>qTtKEZ1*)OpxHd8Z zF(u*yK>`I9?f97cM_5Ee?BZ$CrQDMr2EW3E(nTW<3YRMbMk-ti28l$XM+AIH<_}%K zp==&6yew!jF&!jn6-8E2Y5<|j z?nPSMLhr#4BVn%t`tlgvPk6k2NXn|}w}oEX+MMcoNQfRGB$`NE(_yN@ZS<4qgdv-s z5_Dt&lTk^?1qa17X#u$Zdh>m5R)ABH8Y^KNUDP^D`Za81J9g64@vIh`yBWb?aAe0_fK^u?-_Q zhF339ZyZDJ(}qf=xlE?h#D_VxS~fq>@#*Tq>L6WvV+I^rS|wI@n5y zIAphAgpakIZ%T7c*sGueZ)Y{P_u@NViLDMA+Wn&MJI^XcVkn*+tbvxwhoR)wd7@0i z*MJ~K062wnU?@%;$)xkBvT^s4Brwhq3}wqus2{G6MCQscXEc95y>9;H{ImbXW5_HK z>6&KkpPk`pjLzG%>qc{ z`3bn6ImZJFT`?gdQK@-?TvkO=*R%TbwYfF}c>)lZZ17V`ju+kelY2dgv<}+uQ3-S8 z#2PA81miqU!LjL_pZR;Guu&&OO;zrusA@nPXCdggLqsgJnEu1V@UXAQYZD7+ zyUkG%taRwit&t+)MfB2Y6FR4qmgRBPZZ!jie+_!%)1PdL zQ8y&+WK_J!4N82?CbzVl^W43G2E^34LZk%!+NO|Zo_MK~+M-Bbs&~`_lmK(Cz7BG` zP3hnz1&IBHPMZ8Al*Q9)v4&^oY7qL0UV;NhrwKo&@oV$@K2`AVBXtzHO}`?nZx7MV zhi77*QTqZzaQ7U0A}>@U?jFS4n%IvdSJl(& z84dR(tX5zZc?D#SBAC!CBO)7)Or&(BE>m=czm{mThQ$Y7#|hjW4o@5Ef`V(wSuINi ziJa4!DqT5;BHsiiI1R2Ir>u$lT6Z+)5KX{aaN-1HAp|6YdkkA*$c|hn;`sWnhn(BR z%#6~?*EXFv`qhD@c(`4prF#wK{GKn8*jzCHY;b$q zhbNXsG-aTS6KPz+km_gv6qSuo!1~V+cZ&KV%%BtKEZRq|ZW^Tm%1W@!6A%@H)6k)o ztNyLngiRjAuko-wQ@FYT>CaJ!{h4u@6fLJW)piFFR)_cQpFqdo(a!Qz_oyzfM60jp z$%ChMeG-p;ii(Uqee(ff{9YiAn^#Mt!`K+lE@SmST@$1wLehpIv{Q{P9lcr@#7i87 z}~OCVi1lc%Hz%T^#TsNYAj&DZg(noNP#Mn6c9-`9I**`gcUF(`t7YkdTg_! z)vF#Q!)n(6!|fTTT(75}SAAzST2bA8S@h|f_reH99A6XsojU+<`u%f<4aEI(=5{&! z_u3$e6*U)2kp@={nG(u!WxVk`ylkN(U*}s0v-H_^Qvy|fs~pVi(N$(XEH?1!;Nb9{ ziqArMj`a^*{I|=uS8m%|Pmj{@JYH{h&ZXZe~^ zV8khRmkKymT>euY+a$dlyWX&FU{^Lb4B$U}_?19Q~Z_Il{?lN9`O zr$43MsQN6Nx=Q>p<>bh0P0_}s*hBp79f1MU{$~XX=v(p)Xy+|o%v_4D=ML#+x?8{d zM)t{wCA!6P-45A}O@_@b-i0$``@e9}l1R057UzB;rma+2Duq zixS1q7%ksH?#0!@)luA(`N+$Ck1Bs-6T4x*_;wSVqd6LyesCBJ3G-Wv zpKxmMJXGaoe6TQUx@TuAFXT)(NmANmE*JqKkLT*kL*^iyJq)C|H zXP9?BSWPNdfhs?`H<0d(PgPlYYr`{-G`-;JVPP0~nm(9Ejq?}8C>^7qVxC{_L3Qq# zZ~WwSS($4_(YLcYdaPU$WY2M^8BjJG5{VGJD=wmei|3_~$O$`hmI5bA=V~Li6iNEV zi~0$dX;Jqb@$8JvG7-Z-nN|SBfHNo0mf!R2C{?Q}0s#Oqfl&%!MwlAtLy|Oro_d^a zC}*s8ZQ_bhnk40cZo=WbiZ&aD4&eC6qKo(O`*g>rCCmA5pY9#lT|9w#H%f2Ck@fQp zkN3zt0)MQ*+B~*?YPcWDzE(kUQX3{v64bDYgURT5u96{1_V2`wo<3*T`gqjH@OIp- zcX^F8`k}}s+AB4Nq1osnDY#FAZFC#IzdHgRQ%cxRC#P9X%1+9FXJ?9Wkp%5AdYV_4 z9QA9vM7N?{qs&O|1L-<$d1S9Svz`}pU0L$oVMWKntKQOh-e|at>hh4;#)#`GM{~7a?nVZE1Oy~)i#Zt zAf-Nfnv<$4qGC*1d+J@klHgfvpom4lLH@2FIuX7cE~#W{J7$F#auo$0Nw(YWMybMC z&4I!z&K&Sy_^7{nOw@|>dJm~#xU|cTfC9rIGkJ$gT$2ZR@~B6@UQOPu!ZbnBhQ!>i8%As9ied(XWh6N@&*F6t~SDElVG4M;0^5lxwc)gF>7 zbN5*h;QO$NWhm6SU(ap}`jZkO%Sh$EdS3IYqOykzhq~}&bU(GDn~u5-Vm1>bz_7DM z+N*!#5gTb*dGR~QtbSF?qHqM(&r8K)^M`X52#E#MB%HBCiw?r zzj94yMFlQ*M0bwh zq@q0z_I*M_iJt%3rETA{+O4p6}2iFh%QjGRBG1aFo z`oIiE=pbtGbUtKw zFoTUBOGwaqx~a=@RE_qtd++aRAv1m#j<;3*&hfqUKX`?MExC0<475f3ghf z5cY0DoLU^93@>(b_2A@+G9VG9rmjlhFyW$nHfqgSHnJoQ*HB7(iP8&4rL08!{K6=58LiuozI78d;L_t_%7E)s;U4h2OHf1Hy{5ID^TV9W&zWO3E1eOhD(Tcwey5z zmW>F8kA_F%**P2o$nI+}?daTUtEy{>rqicEKA{gJAoye!LmJ(&MavWlT22|X65vVy zjD0?|YcyD!{k!4KoqGqgbMSDMTTCNeKw zFnej%6N0jbe$Ca&^aOuvV_EZ`e9|Aa*lR^`mn~X~CM+7{F4XqTI>E8V?Aq%Vb-_hV zUyiPr`WFZ45>?wMf*&#l#=3ed^Lg4&R|5ml_V7ZU zZ}9KPJl$KNbkkOPHV^V`EMJ-AfNx;=K?ejHtdAmMhtZWQiSCXD{zV+DXF8dLLz+)bOLE1#M-Pe8llTDKWr z19SbW-<0}K?fVS!@3n6!7&R*+HhmMxZR=tqP3I8HWK!$IG9Wtjwa45y@$ahPGA36s zzxn`9gs$!3cy+|$<70bXgK)&cPC z->=Fyabf4P^~`r?YJQ!=-dqDY>lP`x_s!!!ha0Vqr@slq)NIy%KTJ!Fqap;Wo9AkV zLxpCDxw(~N38QA?nHLq0V~0nSCXj@va~05OIANEA0#zJtW{edU(t4j&l63g1|0s|V zsUdm89hiLHolAG9pZ;At*KYZUE$M3Czg@vM`MQt^+XJoo1|+^bpP|Xgh$Y9f(?Zf; zWwIPKHy=-xmg$N38dCF16_aX5+Pbk!hx|%YP=(cdML)KTre^)Z2unY1@rwH5cGG{) zlh?r{%9&h(h~1#&5V2}Gslyn&la8Tt`cspL#g7<#-bYurGtc_YiaEA>EyR(&*vk%9f#hGfvqB?~j$AS*}TBSU*?Z=LC8J zN`?EKCpvTz_QT9m-6PwnIJhbN?*cfY;-m5GbdqM(@gCZKUo9n=Q>Mrs&ZhS6WRzwq*&+MG9z3DQ7zr1QFBk4(70u+(~xeiuN%rrwU zQe-~ZV1c!OXfpb7D;g{?SxFv7lQw5EzU34`QU^l&2mz4&vZ{s6ey;57{!v;j0(QQ) zu1Um*ipgrV9c5gtd_14se4I*3MG^H{;#kiOWBJ|p?yqQP!on^IQf%+JIEM^JB|=w( zBR*Nx63MRspMWf%W8IDcc>^(u^ndyzxBYq}NAOWH9f zSLY~WupRadNVTAPlT`Ov(AE@g8XJnnTo!O(SQwub^%6{}29nA!s^Rb>O}*|w@`~i` zs2J233u(HnOX(y1#YB)1w?B%+?e=mjdhK@(RV3r?6!d#u@Eq;l(M0L)AdXPbd94`s z#vp`$iQPC>w7-yuaP17B*$Qbjm4|0%!1eTHrF^?ZIIdLCD*{F> zc-8cIQ+R_yly|OBl^TV0TH7FSb92R(3#^ zi!0M)A;=REu`)wA3<~1l??KGTZ_+xyt9>8D(@+;MOvoGY6&YdjGy&Vw}WW3x?e zE_!qn^Vzn#6EWN4>|)oo3DKG@y{*jyk?i@y9ZAlTUuTo?l#rX#)Cie?s)~Uo;M<8^ z*%QAfK;*09@QNrrJ0l75RCkTYFd@-q1jlOA@FiAO@te0o;KfTa%b07smwd)!B;!0U zmeyB5%;AN+M@1t1)Wjk_k8t}5Q?n%(FbwUJZ#vZMMM$uh8Zik6AA&sOdi8x?vww>bjgLo#^9>SHIs=-&j|+tv8b$ zD8cYf9z3Pwd8A$DW)|T+0k?88dNPP-XC64EXV5AE^4m{YZvM&P_Y%Y}2ByBLu&(!J zG~!B2r$*xh^;JtGiwO$k$80o(pnw|JH?HW9DGV`F%A5FPUNw~PBkRp>P3>TlyC(wr zgF^>9XptGc5!QP)2{l%SaBe;`3ckx%m=@2l7m9k*UK)(+pR|VO1 zQFXFKr?oVqKMEyaOrB`hqC@>r|B$eyL_}uCU{c1xfIUG11EwseeeN0V9wi6entmLc z|K|_rqEj}17M=v0dgt`8_zFY&$poOS2JcT8L>~o4h3d<08N`3;W9PdkZ;yx^bU9&o zZzWltx6|$wNB*Z+Ocu}1Zn-f9aX}V!;;59~j6KG(dShhxxuy9WmgnG*iDhK~@iL+i zAM_qWmLep`f)-4tHjj>~P~jn;oe1ualrO)SeDCg~xZ?HkLD!lHOL%;N<(rN%nHEAq zxpXcs{(NXA7LF+-11u<^r!IT;0r>6w0N!_p(6QM!fkLN^_%EBIt6-@yzeo1 z%i^O4blbw5=>!AtuK?x~mQqGSo}_{Ziu(K!Z&^fr(a6u`)c(m*h{{h}JUd728Tc3e z{!gi3tS$6Hq3DG2%i-dQR~K{!QK^=FNA4i+S{y_BfSL7K3-1Ft3zwE8<3`3gknIL`Cx_kug zE0(j

    eq#B<7&I|6)@6E0>n7G5F}g1jVAX+fA9+%+f~yI*=wM*>{Ga7>g-yvf-kY zrjomUD_rxel(}>_h68f}=@HgdwNL^)JEu)%>rv)ck09?L1zO%Yt``-L&93UwNHPXy zAdkzns3*pX!-2}QzMn&sSNK`3Q6%r~iS;N=y^f8D_4B>-k3Mi!*FuDf_&ZtJ?AIU* zA=_{e8gn*Fn44nKWw)WwnkS9%ImkJjewO=|?YPNs?>nw<;W`C69qJZXD20omTxuIX ze!u90dwmyWyLe!8mo(7U{ju~f{G{xkRF+S)WcT7@=u>tRRI@l0hwneZ!M%2dZ2`+q zAtZQquBXq0qqW}tz&`e%9Uh$7>}NXjm7PcHJ zKjDjIzvXe{(fjo9=gZa--w+95K$A(1d3F5hkU~+)>%%8It0K`UYjUxazP6<{w0xAa zp$(L>lDF38E$lM{;E@P+XR*k)=`+$0^IrJ;7ER*9y8X4kOcAutq{w6MLX zR}+W*NokI6hPZ_(_le82b9c~2%i9jG4EDr4k$EaJQgvzmI&7x|wVAN$M51_H5a?@u$th_<5C!+77=F-08{GeiHA1_G8Ns?me*^N@Q0o z=&aHsNkyGr_A9nkeSi2CBReOqWaXm0T&Y@~tx@X)h94Nou@*qdD4%GdQ?98DOu=Nh zVFldEUoXVJ`X186|KZ)Q_(!8^wf;A_iHx4~bX*5z|1Gl)pc-Lfwtv9uM-O z`mC&y!Svg$J?sus*F1ktD4hxIPVCLpHwhJtt-NuqxH}%=mi5oiH%!tmPcEusPQVKU%a&5uC*gAz1c}6UEVV?o{Psi6d$8&d)-1i?D1xsF@#6590V5vb0E{Qqw zU#IosttY^r9+2J38QKMN-oO1O`gc!my&?BJ)W4YMpB8!K1WfK!yK%QmCq8f^r01{_ zqhtC!V`G!nhzP)7^;H=LXa^I}ZWB#|nhe*dgEd(V+sF2;EfBF8!4@NCR{RvORF zfSY~reSq^Amq=G3z*vLz&&H(QBtcqxy#^HWj1v5@($3LC3xjLL5Jz1>uH$ClPkkm* za4MdnMZ(9VLrdIP6?Fj+GZE&7cmkqA``440yAQOosadef;%{glXGq68(0@4hrqx{eU@)gU(KL;PMW|{*Z~!|h5!Y*9HHJ^| zL{Oe$vA$27_T!=pTC%Q0jP&DmcbWaQokaASJIoaAciZRZQ%UNkEXNHDt@IZauAb0= zb}@Z}fxq$WOxcdFHjj5BFn#j2TNB}QJ~Xz6A6lX!V>f!#WLM7%c3`c!kN|KBgh@6n?^ldLs7+1hHfP>;!n-QEcp_b${P66|ILY%Z6{kh>I^4KG z&(hkh3`vS|zjuUV*9Hsx$hV170r`}Z zE`&sbEUK4*WuJT=8l12)Qdczew;a3ek%+mVKPX4_)6OBzxJ#d#dItApl?EjAQS;$sLRh~4%Ox7I=_WWZNtv6%){e^>_eWQ^Xbu?j?j%|?!2aD>b* zX9t?G4Qw@(w(GFdWPFpvv$Hhce_jrmh0|!NZY$BWNqZj8lNWKLc@8ek*?|T|gn{HPQY5d|?nJW@mczG*ptq{Epi8}$6p5G;H(x-bvwP07T zRqaFLQq8rc)it}y`lM~LI@{(LA|Z11Lza_p9`l>Mlmu;q@Qc+QV=*1t4%(3c61C!|5G<06v0|5dH@ez#p>(Z= z4PYm#;mIM63Anh2I8WH(3gzg{Bu5fehUdm8U%G#Ox0FmKeDprfSyPR0Og3s55FAh3 zthS7lRVS?u99oE)XRUW=wZwSjIV;x^5R2+poii%FAU5Le(pf}g3!Gm?{7YB=mA6D1^pBn*n*L2s3kg{M-lYz`xSzQKrN)Cyy^-`y=m%SB#l+^z#cjpTI4;ovlO1Bed&dN?i`Pnb^`rBB7~iH z*2X8CHf8i4r`lY@5|tcjBME{HI6rs|O6yvRA1UPrcR$5Du{As1V550bri>yyuESaU zBH6Rz-+*_XyBccbd;fAbS~p7QJ5J2T&(y$gCL06kt;bT+L8mt49IA~<;3@YHoiVfV z_@(faBk0F6TSqQX$?(geDQDmoCsetaR!ifWM$O~IS%cp zu-Ms?#^Uj|rJhP45qoqH)hwZ>?ZFnnnZfpf@HlW)LURh5n3z`(S}o)+*CTZ^0@ZB&S~St-!#%X-B>?CsK`S#%nb0CXBs zKCJ>PTGZi^`;#!4lrq}%M1Tr5k`;A=g1PYs7i88_TOs9;gED-ak2yYR(H#EQAIVjE z7<#;IEJ|v%Q1&bnZ7FiIVBc*`krD6!+c8OE`SO9jalVJ7vH>pX6uS$dA)%8n)tx;n ztX#yVR=a$+!g!G0@o|cpD89of^^mOj#;`ke>7;;iv$f+N-lJ>~UG3**Xa>^nVq~pv zfKv6XDhm1YeR3LBtJ-yMsminnZZ@*oUl;!c6$6m6j`ZSldOxI>|Mp=fa!bk6j7^Cj<( zlN?FTck=!sVg9V_-1oirb*;VD>cy)eweY~Smq1)m@nzj7o?r?*jY;~Oij%6eXHS1a zV5j}Oh<0Z&pffAf#!r+KCQ)A-hk@oMTqOUyG2gMA(K6`t3rO|Dr9UiIXVXDG#hG4c zpHWp8tKgn~M!JjOOVN@eF6H;IWHVINk5Bkb>?+J0);~~dmp|G!&HU2DLSu{Q5wLd^ zUG+M&vUk91P2+n}GS6@j@T2A!>b2lcdw>Bi| zndp=TbtgO1Zn;g)*?G(gno)~g_Z{xcc>PptJ>*^rswI78%hS69nTd0kEmKynDmV_e z5pci~m{PcZ8@o4S+Dr>dW2boY3-(L(5sMw0gS_Qkf5 zw7adoh9IAs@w=5qJVVto>god1f7v;*mu2h$7HNz(Y5;lA{O~=_--Ui;i5PV396TNd zlTcdwR`t%{iXeDxghuE;me;2G59YP;8IQS4DPPit_Z1H1ayqO(5wZOF^JF^rgQRUS zDs%6qoRn{PCC;) z85$?9l}f#*cQ^H7pZWRlV*EvB9**q>q_qH5mkPg~_Cwr-S_;i8Ar6_8;k_xdcqA`I z5>&*yN-)ymu!2ZgTzZWsPV&ypPE$(K(RJXu2zc_&oXsk^(AsbI6%Ju3&zn)cS13)C z9Ec@Tve(pQXMEei^&h{+2l${0IZnq>lbw3_Q4060wv|N)FSE;?&iKJ6VjSX0O0;Ai z&D@{D35dVH;Ul;Ft#0FI^}xf5&_P_z-hPi+Mh=$JN&owOC&Y6N^M7QR%2dX#bQ=7?60RZCCn7_j z@n(&Xa4FNMYmB#+wdINGIreZf7k&zS0nRMN(D)u(6Mpw7Bd4J7o;S}WOOYAwzIigf zWawWFx8-MG@*nl>%)K>QvsW0;J7eH~)5Li>gHUFT!#6M-4BYSGQbd1~)(}ZBw-1Pj zwbn(Ml8M%br*IhrcA+o-f9IM1*^KkQ@xQkoh-NRExm9DE*e-9St72(!%nWT|7_DL;222I32+0D0#kIr7h zSy}U5B;F3m{N4{El4_oy<663$5sTP<%vKDOe`QD?SFOi@!_c!`a~}L$NG6iLCHpbV;j|&{^N0{$JzzcvnXZwjXc&d9<~;azY<>*9Y*Doo`=5P1;D4#C!*1L3nusNYPd=qBl}k+aymnTD$7BxSv|( z^4NO2AuzildTe#4ZuH}DDwB1w9Nx)CHOx)MFQG3s;-ZXw{9w$T1U?_0ccHs;ldTSx zZ-1MxUC$H_F=^<}tbat82;s58!yl~T>i$XhyhS!uDu8+=P!|?d&WWRg5i#Ku@9r=R z!xiq#k84>nvc9sT^e+}^CZiqPP5=m@b_+C+k5f{BMR7GVQ_5ym-bn-n;%-DqsYLAk z1~UPWi|~k13=!DLsDwbx47H)~!3naWrKzX%5{(8V&whiqgzk-Kkk}GkFeA;i2rQR@gy>oJFVV#vly8cch)?ob=Lk z7RRKk=%D)CPq0wOr)>z_9c*keROMCCqwl6Skqy?u=U=|%-xcEUq z23P@g($0;)7~XL1iA=(q;yq!0V%S`^>#tgOw28y_zFU=3p@m@~5v2Xlork;4S8XDW z^z6paeZ!E2(8%V-*w>3QFA>-&$dxR?m|9X5-d~Pu!`}!K89eYt*ljfjAT9H%MW+8b z`D08%lpzoM-FIhTGW?3Uo2Z9@Q#?qd(5hv;7cU3SOGy{y4q-d6bs3Y1mkiby;(d}Xwv_qnZ+72R?UUZW`&C@xJ3^2~iphrABQCagSiLaxSKmbG zraBb0;>JYzo0K}SG#}>3k3Hpv+vR;Kn3p!`xrZ7_O5R1vwqfI;sq4{#(eFG3?aNFV z17L?S@A&BbaB~_QpJGN%v4*^eE<*Vfwpnvb~yPj+!@N=bz6FPH!cWq4dBg zM2^#|)+&q&Ck1u!Y(D+=#liT}x4nT`Q%1?>&#@_yNSi_`N|Y=>;n*~S>;ciCc-5Ga z76F{{fra&Ui0PLXwH9?_hj^gEP>RBJ2xI?xy;7BNRC;Z*H&Dd*0 z$pTCxF45&ZQ@j0gbm*5*1cJU)ER<kiuCs$GNoBI9oP2^=GAYHdVL5Z5I7V(9dpr^&76;j3Cm%{w zE-5eO$iG|}b;H0$W+a6sJB>yNB6yCnzNjWTAs)(R=2-W_^+yyc-QAT{ygFq1ZB})y zp?z6g+uaN;?O=DF2VC2hLTba~YLA2#OHuG%=d}L;!0>2xo@8q2O#-BI)fU#Qvsx~N zoD7beP(OMFnk{ob&!ryTx}+lHL2wf$mLpA%-2_CESU}!U2k78*pLhHec3$J!g zxQ%D{mSq!XB8bsrShvk;g z;43R8`6uNyr;Ts$Sv#TFEeF;gMTmIZl{L;HF(Wejx9y)~1XUNAxZ5xF93DiuF~G?F zM58QjZTrUNF>6nar?RT|oofenEb9*(#$8!PwA{W=K}ojj2y$k6PQYnmK3k#56Un-ET^^0t5wg!9WF-Fs>2<%^=yi26Yaa`MOfrE$1xNtWSCLXlrP04CD9%#9K>l%7 zwE`Kl;!lhZG!wJWSwkY{qz6^VBw2d#D;|dc8sHDnS#u9%cj$Yo z&*s8hq0h9V(V?_AbHXhVQ;Oi^$kkNcZ3W-OwAFWE7;f>VS{z#%f=K0BfNV?zcD$Nw zYQcjb*osy!<#pu(t+Sy}>ImN}PYgQcuw6LTIzqnxW!)5xeP!}qXx3^YmqKoIT}i^6 z745sTTWR><*iXKL4OmaUR5xGZ5YJBvAp>53Tsn{sC1W50Kp0N&5s}$3$SJ@#hPOA) zP8e63x0wReLlevR_^X+~S3={(!k{-T0ijT$GFz`}RqA1p41?!QFq)o;--a?XH z0Abk6h$0stEy-K=zv}C9rAiD=5%HX&l2?cQ@Js~evq{{o*-l;ZwlMkrZtfp^Q7j?e>F#HT|@7GzGZPbmDA}Ze?NEl?1`d@qS7ajD3rl{v;r-HIQ z%iCLI=|5*YA2~XWJ{i=u*^3*G8@#OU4|v_L*@&-V#Hh~86+4Mr&T1T%n3eM~Xe0AJ zbts%Lq1mlwK+z(R&_A?#`L?5Vc6#j!^iK7rbz|Vz;}RXWz5Js>f}HM9e?WE2Lp9DB zWgdvdf98FU(CMwED??XhGotQ9aFxX1SAVXiwcdm)Udo1EDf?$V*G2?gv=URF7k&!E zmm9d5Qol+7#k6OW!5eaV$h7?>`2MIvH+gwGZ+m#I{MHOE9`))z;>qXXnHsJ`i-xQY znja!!Cc_^RCfgC8o&`S4>+!H@&8`O`9gJk_;MC|ofCmK{JgRkQyL=^LP+56u&^9%; z5gxLMBt<53Du>^kBVjR;3TL_5ZFuSoBucKg%4QC}dkCQ8K;nbwDrGTDstpPtuoElY zdsYm=Rz%};Xd%w1zl1`!z~8TMqS#-@c`Fw^58rkqfov85usVF`evBNe5RiS^vf)G1 zgSiB~EqFqADgWW&Vp1;DNr=;I(HsFizaZtK3&Go_^U#rb(8N~5^zXs9yo9s!dKq_m zv}_gdUE%itW)v2mYL;m^I*9Zj`UULgMQ|9)8yveM%3clalUOw=tRiYaTNA(?gqc%A z{Q~9eYW|6+XckyUB1E;9t$6{QU$l4djhG5qK)0#P1BuG!bVirl9!t(ouw}#z zX8)Ao1N%Jt5It)+KNnUj2G6fD-i%TmNKZ2VdlIyhST@r3G3ktP%ME$E&abG{JE&xi zX6WsYf3cHNYGrR7tZ#fO<^4e0jJ*jkWs7sEvhj)PKWbreYSImUd>| z^sFdXEfyu+C&z!Ip%@mBSWFHZx50se@FxEdqNKNF6Llz->4^6XBV6!g<7>up&*>4w(hwu&mZu0VC%MAxG$BMTGY9ZFnZi&I9HDY9*#R=)uU%WVzKjdwSM#?#~dP7cHe%MIYTHff`p zbhMHgxXp^XaH%P9(=^Y6-qI}FPZ*?wrWblz837PUCXe((#sA#H2WA;K_$;#iHPv{a z!H>JB3C>%zs$=|0WZKA!o2=i}-0F#VJFLULY0B2;>r&neI4EYB;!J<*o*jXmVmu|l ztwlrVxF%+54xtP6jeSWnB5T9ioTO&@`o$e9=-SvCHoX`OBIS}=nY8TbBVE|2KE^I{ znEnVIAeb@mjzcylB27&lw`^2}NB!)M;Gg0ej2R#e;g`?DR5>K6ILYB4@o+P<%CMB^ zAr4Iy0niG2J!tY*PUA+UiMZrRZfbO65GWXGkyEqv-eakQ^=hMO3G>RTk;aPZQzN!u zE4^se0D4B^g)jAyfIA{-PcQ^8#W&voft`|EdH5bOxRb-k$^LQJ_({`~Qj4!04khpX+GS!D-HK?9!vR{(Y%txWJ*>VIr0tsPL4hs^_2cl#W zKfMs#b_S11dqnx;GGq@uMP;UYe4BIV6P;fzZvmo0+$O%i>2$=-wwWr3Kj2oFpdivn zGD?GPdKY(TYA0Ap_ixFY>a*%-Jzl^ccL*59LRPSEr!40n87P3f<|&sWhVA>FQp$yD z_$30n6v{t+l}Vv~4zt~_@DN%Ua=O)&BP-Ka6I7TI0)Mn4xWn92VgB;0dJ{2IKUv*! z@SDtrN-Ski5x&*;P0o_{y4T5n8@p*^A6GjU@zzfc=h^)en@ZBlLV@e#q>!{H_lp#1 zUyT!Y?LTlFPGj#d(aVgXJ9MH-xqSDVJ}o77+<5q*`sYw|d;(Sro=q0>-}M`zbK;z1 zaQO3%qKEK{gmn7Bh{?vsRrq@Ux777o9e0_Z{{Qez)c@=l{_B2*6$Sq9{S@J8vB<`; ztr^mR$o0@p+MS3@5g<)CQxSRXm&TfKMq~HdN+bKWLpfoun31>7Y%!t3;TPMJ+a|96 zR7^*@{EYWH*6}J^P_=udd{sNto7UcLG8Hq7D@9Aoht&C1Y}uB zz&^%mmthYL13MEpa^m5NPMPl)L6HeZf4$LYqr+n`)kLse8^=_N;*%4<{cfD$v*yNu zF-~%)$+E?S73j>LT;ql?MsUcZJf&}+Adf1RhN%NVANY=_fxi7AIhBMQVpd1WeQwYP zR4=+IEPDMPu6dHmgW##g&E`8ZcX#8om%)D`npXruVheC?c;Icx83G9w=l09;j zm%gVq2<&(})xvd->$_H9jUbyw8RDGyT|S)w*6SO%f+FTTYoT#zG)mue&kI=}?>duV zJ%*I0XiP@esk~TkB&2L4Dln#Vrs$oEP?LnS?R{<_Zf}t@7>#e6W-glATG$;=jm!jA z?}+Dz<@TyYa`VAv-<0%c8M^O}BZzZ?Y!zb>>e3neU!?@$~r4Q(- z1S89m&JN_(F_eKXb(9g<2~0>rqaE!|Pz5C3;SV9BNRY1vW9zVB;D0{J7VnD)A7LgR zvT1KWzjqK?wV)XqeA6-s#ddhtrD@aH#~do*lOg(4;@GxtYV-_~p@|aJj|9JqK)W$|9Tq}!nYe1 zFj4of2S;OyaFaGS?@4I1C+b{l8&GAhzFHsOgQbi6QUkneKfjwPfLkC*yA9+`dKtVd zU%6`k@p-rVYScksxuzuV(X&fn3Wi7}o<G z*-R*oFbu&iK@o}XX+x8JkAxWsu(rrNM_?y{FD=a7R?c~RaLd`V+R zvEd;_2Drh(tt($0M|+GnFzL$E5dQ}4eGS9FjPC?))9W-|bYUcF3G4IT zdEqt>27;;0^*u@QJ#$ene!F#7ClXXJSx&q3D*v|gw&*2Ydz%JzEjxaXmywDdpS0b* z(XjN-{LXi?ORC$Bi^rata=r*`vQx&_+%^5;1WCPi_gH)L-9U zy$A#-J&wM=gXO7ei>0emxL*X$->YA{q!SoSr-Z%rRm8?^q`Fu)KvJx)V1dkq1Ee_ljxjrUSP+gYDpNg^s}+Q~-&J9Db{ z4lx6eDr9y>=mYB}a+fET@}yTI(_>KaIrUOmsUVO;L=Gq(aLnubbU9|chcK}8wVL~~ z{|?32l|U)Vw3V5W+H5&C{FSD~#G~Bz6F8nxI&6*jx89~}6w9aadVH@|hadheYRo`=y~sk{mpi`$MA|P+3>CmwM%8Ak(sE zfl2S!ca!TE`0QMuTN8xyNAqK`=vWb@&}EQ(K~XD@!!XDvIz6R5-E>PmTip3P(ZYv^ zDN7%53f`)wQ-C4 z9)bVv-w~WVVix<4<>aaVb2)h+KJxL~_Ti{$z7&^1U9->QAEo1|owhZ!bWEb-T654A zokoCfY$#Mz9*_+@r4o$Nhb7C*>2wbb#oGw3+twl>I_6t?T-&U<%xWn-eHZ(AhhpW% zcr9+=4qLkCMNeI8`#-Xak?FcKKXv6@9Dn50`p~&%=q;*XctnGF#zH4f4|4Yb$D(4` zaGosC*?Q19gXpXcP(pUAH?ESCxo*0N~gb~A&P+K$r!@!#(Zo%I|-`IMeJ{0tS{#-pi}OB^R9x*W1MCdG!a%!<9U zdh@kK(#jw5aPkuc^^vk(ye`yr>D$lp^u=qTg-^oN^j) zPq359tcaTI@x&SN z3>TBwGD6P>B!b)<(;x0u)ZN#08lGz|s8^u>_^qabpswWqgg2OC{qNZY<*tg;% zq+~+n0SH>3;}2d9Ko)SPJZ}DSIw7cNm_wMFQC!Vh(GBl=KM<#8pJ2HsyoyTXVxE=0 z$V5%FSO`qv4R`o9YVP=%EBOngkF8fQ#!mdt>DtAu|Dq6%Txw-M9nG*${`9a$QtU6Y z!Ed~tKHBUrw{_aWG7T~Io?HKucTTqfL*$*O=eDR}pxAhnBCr#iYmn0<#%xZ5M_wAN zvVC~1q3$Kdn9n&j!AiJiOJ2De?4d-`EBb9US^>NFJJyEmjBAV7K=cR+8E)Pl5>2)+ z31fyhdJ3*vSd$%Sl7Dezzz3&c8?#!!UhA zN%ws&KAyqqm(IoMsFD8s8h{#rZ=Cy4L2Vr8??b`1G5q)4$X*ggL9vVEx0hfcLWzpR zuSX6S<)BmCG5EUN*8ahUur7D>j_hPu%*(!QI<(I(Vnk>mn@%kV(mRe8WRw(xOG|hb z6>%WtWTb}C&-nSh^YDtdO5_8G2T5J-XH29M$eRTn%vcqC?|n8oZ3?<$nn7SEonlJ} z{NujYg8Y4Rve^8&1Ib1ia1o<^%sab+9eBKQIff4&8)AAzg*BysavMq@$n-*C<8-lX5{ z##v6SH!3PRE=aElwc6wk{R4bgzKtZ8kw&L1Gy#DioPfiaS4Zq6^PLmD4+1-xt54B2&ITzb9zg_1p>^tOtp&~Bax&93 z12IGs{DRb3dVg8hSgVL&peR<5t5HT8dN7L{Qy6}%O9&0zFa%jAE8Wdet2n+h4_!YT zi|?}LD3WPy6tLf%IH7&3#%Z{$@k=s3hb=z=xztK1^VJ|rL4D2J&76Bt0%d{r&At0C zj2fA<@I3*)nHyRN$D?! z5yfr<`f?L5ohqQewC`*g+E;2Qh9oPW0&m>-->a_mnRtg#Ja``3gTQ>OI#KSzvy=An z4#y5>x-xy&yI-9w%o^;N)tuA>N%-Gv%P4$jo&}O)Bp3ZH7H#(!;#Ew@ZKHdQ+V>Ii zlZ%KjCaQcI&&QS!W0g(EWU9Sv-@+bfx#L&^TM0R z!xm6?d%M`UbSk@z ziB#ir_zkAPb}!@Pzmvy=IOhW{7Mt zVI$#)1(gBzl6Nb_fl6`m9Dnq76l%UL0(xH^c5uH=)3$jnsZ4)BPsu1zj4D5TH;koh z2}ll?1=G#EBB*H$(tQZY61k@6Kyx9Gvo+JVC$T3LXrWU$eSQ{>6PR0(#o>6<#svAL z0HEHiSi>n5GQX9wFoT=aOkR8(MmBiq)%7QsMr@wyR(Ye}e^c}7td4S}6{+xUp@*}-Tz4$r4F;gF;R6j1s{^+~i?^hOcnt+Z+*`A>`36R?RDOrmY?swA;KT>57+CFpW7bnQwAja<>hdx61??sO4 zX)&SIcNScpSy604S&yP)kx^nsY+uC+n6Ji3v~%<*Cg@_yvbE5cjD_Qi1(Q)AHnEQ6 zGqUG2_|ArHXF>%-OBG@h5Rj+8WkC)ec8`+1Aeu0;W8XJl(+SWk(3?&NDX4oN^~KyV z0=sm?|F1LOe+~Sui{i`W?>JaJpM1T8-xFoT`@BeTvYI?Socm5ltXs9dwgx>ii$v#3 zfAFjK!B{)y(QySwaCaj(O45JsQV0Gy@v&07|NC8P1nKD<@1ICry|!j2+2+l~1i8!) zjQu{0{Yb%`YZsC7g$np872gsTluZ*pg;IWcm{U@oM^|fA^*@;_y<-R(J)FrA95&fgy?W{l&e?&zy?Tn-raB0N2tZtrl;?~d_YmfT;Z_E;^u{L^30BC;(qV+I197k!bKBN^es z)%^?sXTZ)Gg`sm(b6E$v!QycIOKy&x2361>^IB*WEjLDq?sEGM80pY?NZWL;SD59T zf$vl&)DQ(rTbarGC`D!?n$7R5v@R;5BgiE*3ftDn5T-UCnO$*OB2&2eXb7~3rV+!w z!{EQcYRuXX2$Eee64%fxB|+l5Kz&d7nBfbBGSH;n%6)!`bG_Yi=cUW*ANJ04uT~cm zu6X}}6w@$90Lw%-HxYrIJS=b|sYlmt{8Y@C{8KzqDlSukDMM-dMuEJ8g6To=^Fnp^ z(}f=~-7FTZVy)d+7!_V6hf*oDV*ltwTSK@@3eIAqXeZ#j?$WZ(7hnak05-Bnx4 zwYp>(Le=u*w6oJf6Y#;c?xlGlv5*&D3oZ0re#kea&(lMp*bF}!MOJ3uy$j&7m9#u8 z>2~GyJx0yQ=q6ss7@eA|_d#gv)FDU!ONAnRH7>nl2~3M5?jHf|Klp_5*SC`*_^v;o z#1QJ+C(9y4bY-(G=nHwGEoB1Qw_$^%gQ*GKUTTvyHhE#uJxmsN$@t~2#~-nf9ry#L zJogmr1^MXskh+$!=r0z}-o7>rpj(>4#Ns65YS3HW98xSZw=sXQk@m4F`rhMB++sl*WP42=df>>c~PVrjT`mGgv}=CcFZZjkHzAsdx-RYN{>qZ znOe8S^d)FBThtzp<>m7V#-2GmH0vHCe(V4!nN{Nm9iPp+*lC*a+vM-s&?AU(^CAoX z^#}qxl?ycg>hgP6>FfKS`*E1v-xk3n zwFd;INrASw*<$*-v5MODIW}BYF4{bx+aTYK!7MD>_o}H3tq8`QTc|PN5~1Bi)g)i# z6yC&2!8Q=Eb!sEyB#X6wb+tVorz^PZ7j(Mm_#N5nY!d#1kzqqk2BsGqO`)ER^D|sO z53>FfQz61!;jCS|+b+6)BeAyrt*bWeCD9JzOmeUIcORJABo=o3XHNb-Vc$ldS5>+E znpDp`TGKlq(X7&^z9RvOm~I>7yk-8LE~}HWFJ%QsOx^E-v<2#rQQt45I3pFQZr}C* zv`QpCju1&65GUv9mvB*LN7I}$5bDm~#X66^q-&0DvB^!tD`2myyF0=sNO?R>nYsP! z(uhfnoYt%pLebCtJ^3B^EZl-%rvhy;j_aT;(NI`uR^%}toH;}dj68t{RvnezC3Hb# z;|!eI@lO31ZDP!vLSUz%ku{39)cSx2a9w6E_jrj!tcb%`xROuDC5yD{(4hVpVAq1G zuee;+eJ4E)d|<0N0GU+U zpqWcpzoJa>PS&Cg!|Z5@ldlE~Nx`v5sbr#ilm_*_!v}T3FtK{66PhGYZe%q0M@Scr+?#%RWRT(Qhi{_IK0fp+kcLEDants0 z$$fSC^s{6{1f+Us_i!Tvzr0(#CKy0q=d=Is=&K2XGEB6m22ed?(T%RV@=^ao{iis0 zgia7M?0)v?g_`lHXU(Yn4cyVnZC++7{lkL@OLZUmOmw_)Q-Sd$@8WK-(@l{{%FTzA z>T{8|5~uhbod2aY*W>)x?hnfMfAv?P^?&cLrKG2;+aJMn9-g!e0;yvKgbcE&t~9rY)K6ezIzOC{Wu@jLBE~w{9;Qg!TT0}Hcp>iZ*eBez<*tz z;N)8u9shIAMH10MaRKsd=@}V#^_iRTshWh5gtiv-VJKmKUgycBkH6RV;9G8}rI)y7 z?RC*@uLCFLidkV;8*A5>_vbY4_Tig|x)T&~s>;m13`;qf;jl2PogKWLo?e%rCN1fQ zrK@O?!2k?~{q?wV6PPmuIYBw>(zT10rZWOobvhwL;1%=k2)5AEep`fJ;IA_@vKF~6 z&x~y^tNb_ExH-ib^>i`)1Z3}3lP?k-=x$04sTlZ3H^e{B@D1U{zIKl3_#A91dyRzD zjMg>lwktC>G+CTvhX1LdIegBKQxYT^;Ko5W~b9QX+7@20o z<_YKP=cc7s9rOf5~ww7aq-SW($> zM7K?o{u`p^-@!*?e)*5b?lKO2(b=^2{RPd?3J0HKo@H{lMs533nZ=~Ke{cqd{>k~H zUp`a&*;QNX>88b>ss;GI$;^81E}4A;-DQz1GZ~$~%#rn^d8|^D4R#D}Ps~PyJ9805 zRBh;2?DEB4NiyF+OECJtlzRgeNzDVZ?6`|5Tl5Fomm)IAhqyQs`d4e0K}%5ktzUi@Lh*xS_;a#%Dk-4a6Fw;xiIfT%kO_s}T3 zMhJWdW%9m5CJ(=F*?fsYW2oDJk-VVLE_CaAg#|`~WTK8GcsFWKD`c)BUdD#2_tK%* z55`trmO~OJ!Vm4EU?vFIlb};`2-)36U?)}adEozKO1Dh^1C3hvY-=U4Vd9=+CT zkA$ph%j>ObLR|hO`X)f5h=juQt7FoVTptyluW)avmMW>NC_3`Fk#ibwFyk#oUzW^mlTS6*!$9JAHUFW zAAY4NbDW6Bqzt^G84_gTuEn0drbt&w99uA-MrBI*c1^fahxrj|tKiFnySQ#X4a+2g zF;B`Vn5gkAtD7NPiC!`()-5ZqWCc*_6+We%S}@E_zlXC!i!bh___&nxFUDJL0?hlc z??QSN-1robR~TB;+(%qeW|r?LNbd=V3xzOh#e%I-%~ufE#Y_J?deeWM@BVN80uRF~ z2$s?wPSyX>XN61rHb+Rah!MSs;_sOcef3{GNkjYJdr~*~>74sUDY3Vs+kuuPPQ!;r zLbHt`PSz7o#LkyL&w57m{f9eNt&VqDF7LF!6Dc_Z37fy@&v>lLgZ1a9^&YBAC`Nk~ z3-4bBI3=nG-+NtK-FjHEs#{; zjGmF>RsOA7fG$OG#W$Vex_}9~h=zSU943^j5h?6@NJAZPZKA)*HNw zikdbj_Io?#a9lV0dZX?#a9Akt)7t=^PN^nYm&sUFg`09=+THyywa<_Eq>U&J{_cLt z2v)cX7wrEM+TI#iJDavO6x!f9)Xfs|@Ox(g;C=W9R6 zM_BqrNr8<>taWvu<~}Z& zgVa0ri;wOOpto_3g#MnB>!+K6_m4t{Th3Qp@L{P@ZJ#BoUrNeCWILYX+RB{q#8rQJj22@8w%f`2PkMeqkN~npC ziyCW}P}!O^3Nv=?vjpDW!P(7iia-HN7{kftRyP~0&Ls)i(-hUcF9ZvzcdDOSRGL-+ zKj4SQ9PTiF=L11{Z*UV+b-7H9cJc*{X*j5zdhO$n7j5;AL}o!BC}!h*n+X~VKR?7g zH-RzIhl@#5QJvE^E;!J*CX*XPpq^DFCxjvHumLoRkz?Hiqn=A|fR$uIgz92=JY{63 zb4|xIo>||s;TSEGp9&Ow08Gs8WtkMfY4<|U z*JKi;0<1vdURrD!*zmAZL|z0*4La}FlzpeWJt9&H*$2F|_rpfgAyEzzzCXfyB^-kn z<&?gSZ@C2`u+#SQZibaW$=-X^Y-45H&_!A^NFW^pkkK};$$AuQ*$6LT!4My2w&h6t zqamPe&wwmvvW%@M!A$Q)-?p9Y)#e=v*IFfZB)}BRR)gN%dLZ%A^)2Z68)x5T=@#A$ zi?}y{3mi}@Ea^BomSdrdKQ&Z;uvRQ}fHstE^b^Ug4@t`mq^w%#H4^y|v-G5pd=A4@; z*5N4-Qwxtxt=ma zZAsHBBV#!iHSP4>+Vpu{{@^kteA~|%?-CFh@%9y@+qWCr=2WrtnQ0~pTA!^EsnlGd z*QzsbN~xNKM??ihf}qZsX}r0nR0aeSMF_thx2&NqaaAYcgD`5lm{d#%o-;yl7b}}? z^M|KwH$DO|R^%D8U*C2}gW$Dk{)2gKn*Us08-RaDE*gYAuk*qN#isx{M-rEYPnd&8I>ZYorKJoXI9RkqA`|d@TEcfm zIt2-s>caEL1gmUha6k)h;HDZ+&`xcuS&|!=$B#rDN8M1d_~*9+#uRD}TZD?jo2hbg z<}UZpzk$MWl3#*9_OqxtJ%}iWa!$T~gr365-|R88QYH#AP;FI#gYXAN6ze)(QVC1N zYRir#^XnjC6ztsd)~CaHBfF$PBsM_Huw)7!{a8A>DMgJNv}(1Ze|6hNQa zX(WXwh1B*9_-m5(@Vaqm#im7d?h2>i_X694VIq=3h4r^yn*iogQ84&t1B;h|Z18&g zX{|Nhy*C;r&H*RdK^4^qyazb^GOQ##h?v^PBf${BDezpA=5z8;`kJ;FYm6f zzH?6B;BlXD;QM|eO+zZ)L`r4Kk^42pZmXvLy-S32^r~AUWZDx&FZ1S!_gkdP@oMO9f*q z(`|1|Z$Zv8WDT$o7eJ^aW*`S5u$?y9S^3_VDc<-IesXLgX&7PB6yNyl90c;B(EMeX zv;wxa6|97_z4*}0Erk`BLG>IH-#A|5%~$^ z(PIu&B{`vc+(l1~$pMW6=B$_Rvcz;l_yJGXNB-Q~_HrE_{yLaQ#5AIOPkhb@?8NZF z1+-XeSZ9vM&tPl{15+v7!Je-a)8rVu-8&QldQz*6)Jy?q#@jC4xiS86sAFz;WTfht z)gRA!HK0Cz&X?;c-3ui+z#Y^xVTP451MfXtdeln!KVQUpFYPe;)?r3MGFfcp)}zBd zbFfm>cw;)*`!7Fkxoc z5liYiTO?`#fY*1UO?Xto)WH;=O*wLDG^TVHgWj-?^r4-X87d!XydybR8{WlMqBX<; zM6N@Tc6Q-JV~ZQdJ_be_6nP=PYWmdxx<^9u91Gv2NM4&|DM(26)5UBFDymZaP}3g) zk};edS=GjL50_#YtR+$GYRlsst z+zbZnuU=b}>;GhaXY}k%X0|PF5%5^TlaEKUjEDIW$=wqifkAXP-rIgaBMIxvF*1zq zh4W_6n}`|JmzW_qZ_Q!-{DJf}Xe>Yap!Yu}GV_E~8%TRrfFPp81`QBMQZI-x$&|U~T%KV$hZuGzA zcRT36&+i)u?|OuP;RKmuybMDqiLAs8j6a?Kd=69Gd6{xvlE-O( z6hmDs+{YCBS&U)*h8>E+=%|$y@3cOVRWf|;tzP|>A)D`BjzU)?dt>O& z>n+W?%&dL9Ohnzu3-*1?YB5LiF6FHHIXt$chUNdRSgriDkeeCL5TcJv@|c4oi^JmoFc*69x_(P~ipKZ^Wel-#hn}W651}F0<-k2bn=1>xxyz;k38xk zHYPqJi>>0+A=6@#ki(b6dMu%o%2bl2qw1hQ;kjmexU^CRLn ze#42WG7g(?foX+H_z|x52<()n&ms0;Jmo_xe1nPAd6k{TxNwBJ>`ZEmGC^BVMV_rS9PQ?IVY<5&3fYMKeKoTu8c= zVoEuTQD_AD1x@U_xbc$Q;_t@v=13q$RbKrfDvbyll9R)dkq29p&C>{N@e z?_EJpnk?7oOqrH;n_~`p9+1kgUG^XG-%>ugMq5VOG#viWq;j85i(=cPMyX#Ex7vjW zn3Ng@+TFnSI!~3Vs$2Xb}{lx`AUEW4U zkm%}URy&M=dp&Ql6Xk>n>_kKMKd5`JpeEe5-Io%23%x_=MS2J69g&WJfCQvB>AeI( zmEHtIgwUH(1Ph9UqJYwyAVqpnP(lwOBs;$Uz4p8Z>zn!ZDhKaTW-^nR-#n9fuKT&$ z^+@4WOEDbB&bglaIp85AH7Z@C=ht`p+yLw^_&G?*h6O?z$~wZ44lT&uiS6fM>)5+%NeSvRUU(uygC_*Kl{N_h9)V z@jjHZc9zv-9!s64Z74SyYhpgztJsiW?M0W=QNn7(D2X$^>C$4yC&^`RR2}@9WHbA8 zgJNNgRqX9&IO$h%Zth`40?)htYDB@n!;env<(VeKjUi`b37;L}Sz3tIBfVAyXGee2 z6yMU@$m!F1^T#=S6AYpK8xwGoOP^*ATEC%-61`x9SrqhI?g6vQRfX?R&L>h3C7;6B<2t`5aF7@E~KeiQ~ifAG?*e^vwk8w&3opq1Q@(K zQcifcKBuzZwJDyKtbYOg?!IwH4u2v)Q-@W7rT#37Ye%PY`$hOP3L^f%Z48*hVz%<70Jx-6uS8Fn0yqdR&0x;*X-g^(NpH z+^~(McQBX?Xl{UtCW!;)V--;x__D%ZYA(V1hFQ2y_ZRMPDMTp$j2ISK#bZ}o*k+v? zg?uKw);_-N<@XV@x5O zaHhnI&r^xYYc?PL(bpKsf791zxP6BE+T=|o8y@!^ie+gVM^A$U4>na3 zrE;1oQ3X0fO+Im0V1~m;ddZhf#R29v!2Hy4d-RPW@T(}!zj&>nu^aN`{Wjm8(SFmw zWdXn5zTL{z&O}R`7K_nZkY$)&OG~BgVTHpCS8n^VBx1J#I}_)7;%`<)8lzo6B;Pc< zAZp#!uoiLnc6tvgf_VD;_L*tp(mw9o=_`t9?%a;*(HetiLtAE!NqDaeC?Z2%ZQ^qh zaC4K0L4ILZlH(!q=bvC1U?JTXaKMAnnV&BTK5En|f89iNIyTv=#Xk{=WQKlEz^hG^ zyMMpqa$Hz^pF6Xij;-B|TNk%M6Mq|-_|yKi@lpfjQ%}hoI-9$P)ZJS*lwF*TI z8no1=9k7JiZ)umW?k2PWI@+zyy!a`DPRY{JUuiKsxuaz7IB7anGp~eQ$a-l5VbH7; zXZmDpX4}h7VJ-`_B}%24P?8tg)!;*)pD-&qXAy}qznAq~@667K+WPFosr}iN6aNO0 zVn=3B-?hjw+Rr|D!vR#uN8F==Vdh^X;^}|(*%&4aBgC;YcH;celcuC#k-nxa`^2*1 zL=5mt=q>!x$j?ji_M5Q*dRo#Mv0Eh}HvTg;K~8*(qevP5E1C>S#TyB0N6lsiw`vvIgZmiD8|w zCo2M_44&KHLt`CvCXd>#i{^ik<#xHbd^q{d7)=2b@}#Irzv+GE8X+R-e1Jr03^)q) zT`MLnK9VvxD6e$yQQ_}oRAtjv}eiP8s#N6~di2&;Xe?V0+{ zc`i{jiGo(Y3v-P-8n)*Rn_2q?2A}WjK7y|eO??JV*KS4^zCsfp1LhOy68JmobtJf4 z#PJ{D5ffS@w3$htQV)K~ruaN&QZSrFoM5rLSAuv>Wcaqk0@nL3_WXDTlRSI!PFsoc zh;ND|_{s-A2~S>EH_ud^v#+|pn=CN9>~}~_2=@<~9qgf6&h?6^%U}|Yo!Kqc{Tp1m z*$7#ReEt2IjwOSJ3%k~rO_Opu4WF_4LrX6FB3DNh+492A7LwgPM zO8tVW4~XJ`%Mtf4Zy5-fOpplPo0_TQ;8~OkrYnDtq{pD$PMa{lPR=jqhmlfBaqyutyBf#Na`R%7G%j9#n!8b0CG=~OVe+A>1q)Mfvhe5c z>{fNFTLLWBrv8*HU99*&`J5gmAUKnV*^_mzbB}HaD-@DIc=vJ?i4E_kR#+saCTc2{ zCJL_nd2`G<7!hMXE9QL@t^mVh+-Tsfm!n+DukPUm>MLz9y8dLg>aJL~wib}#t-~!! zUc$q-r$SKS=E=Eif}nv%)y}~Q(657H9U@OH-mDWSHm~fw=Xhb zx9jp0k_@=u*C&-XI1VRV9weV~*9>r=0_?-y+Ae`dw)XsGjL7z|mdi#&(Nm-p>W(yN-Uf2;{VQO z{q=Oj`Kn0&qe%so|E@_OT%TUNsq?)O3fk!XveVq0U>__HzOSuvds78SY7&9{^!Eh_ zc-GT$F3~|M`yeAK1Tv?fGLGK(IgD+o67G6nu?Dr5pIa;rjsI2Ri_&-bmGg~S6Ydf>Du z6-k~q=9^D%){dgrke9V6+_`fskcQq{`#HKG5dQvT0l-V!YmI_6?5DZ*nvY*v#lO3(e*w+us?O?R9$p z+~D49}gjzA8M zL_Mz*v;aFL$#FHN|MIaEI0HL<_K?kE%?`)TRiwMI^Wp65R#+#b4XRn}=dm}yZ~c{L zCM%k?6Ri~E4Y{Jp{pfps1QjJPtZu*lg#|EyhDeekDSnZP)8LCFsdOACtmwrW#PJ8O zWlu#=m9DUC-wiN#Phx&}e+?h*%w>6JEOPsLOj^B_iJQ6I6G(5WF?ZJ`N{ zl!F2-j&a1mP~y9vAX+TesL=XK^f2RCr%zN^55k;Jk;ChoobJ;gmz<+YP6)*)UFnupSzC~Z)*?I=;M^FU~4p)#7mMz$Fv3gzcJ&f$2xxRml8g z@6m?I>SYW(BKX;Q#jKN$P)R>6UqAdj)UKB)r$j0$k@WiahzZB-(>_IXphE*P#Qz3a zGHRsNmKvUwiQRY272WTlV=lS9g>x+aSed%Mu1KXx?k4#*&yL^FiB@~VPpAYtAUE|G z0s0k^pQVt;dy>ugZiv%KLg_adF9WeUhg`{u;V4pSYfJm7mLEsm8tOMAvyL3ComL`q zFFXQIFH-VopD!=+Z=H{pW!Z*MNe4sAtC2|A^y#4GVi`Po!_fFmdIx6*Ay#Wd0_kuL|6bvhI_WD`k`g=D(oFdXJX_vKDmr7O`t zT{tGnVnLk^zG%^StJE5CN`Y}Zg9tQlgl0d@Mo1yuUQPNFC$k$Qnd7?cF|U|3AT}c| zl2X0$Xml&NN@7zAsB_R}Gcx_#Y>kfBGQp^ZBw^Y5927g*HpZ_H#lQUYj*4RqBmTqS z3Xm?Gd5SJ!%tqz?AP#tYqw(Fj9mg)K`M;}8hPi1CEsr0q&1>7(V2>qZ#7x}LMpB?} z#24@mUO6od`BbIj`$2dgggT7^YnVD|BMwfO%FJg9>x?G8CANOk}$h z#OPm|op0*ev7X8WTKj$jDoz5ramufP+xLpw@;dpiR)T-p3UJ!Q@GosL{zsddY5rZC zG?@`A@fx%r(oaEiTzpoh8Rg1}v~A(XjOn%~l0Lwx{N-07Rs*C>gmg@6KY;Tw&tCEn z5yKbCQxtFLmS7NZD~M!1t4j3z4AT>j>G%(Bv>E89c55-cMcrdX>USF!d1OBm%yZS+ALvRgLC$B+Rdu`3 zorhh%$LiiJ-ntqmOSPXj#Azq{l(mw}iN08hyB)+WY#*TD@S?evZP9FKnK2$g)UQ=s zxJA#|+2wqEft>^k&R&cC=u=lIyqij8ZmcVXQZ3&Ccn&D_$$Q=!A^`A?7vi5$_u5}B zz%uk-v9+|OYD|d4dOZvra&L81!(**v3lXp`a&)wdmcy|#=~9yTrhVp--Ew_x81_>o zl;z9APZp{XL(`%iKsX)*15JXz2I3Kq)VdSJp|7ZP`zsiU(j8^VXO;)B$tq^4_ zz0SsdX!P}6=|cO(aC-dPF$TXKeqtRwm`ya`Rutu!dyI7wxp&}q9mZS92xhZbg|W=S zqteBTe-*l8yv1Pez? zeZqos1}_keqza`z0rqSRe_9!ji<1um6TW6q(jKo_SO>jbTGvsMlAujQn!y5BBp2@v zR+CVqxpK4n^bH%oOmZylZy>1ScQD)+=4p3}`ht2IY+{#@8E-o~c`!G@&QA9k*eCLfj=)i3+Mjms2b74S8Fhht}<=nt3C zp7n5Wkt&Ah9I~cTCNpSAF0*HrG@g@v7^`HmQu!&OFB*cpHFmk089pMV7P9@%8KI&PSWF12GX8R<-AU z?iM}6=KeYQxHCx=5mVgk4?l0yvahS{E?8a060r~YnVFHmoOP*^JOnf?rrOUh7IQKr z0qy(qy)o)jBVIAP!u!}NP3D1bfvXr?U7PzqxUS9pA6(aF<)-qRfP@?hvgyqBMx)b9 zA3IASjVonD0#2Bu*)xX<4Oc|VwafF&l=2?BbsTBCTrhQ+9 ze5{m^Ap6$5TJMq?aiSpLelUk{hV#noxi*slx==OpLKaZl1l{LROkbK)dNHY;8usn4D_kC4 z3ZtwOBQn9_Rp{~Ix9_DXGZ18jpNL$IgXRcCYcv2UlbUxg^v$4ycM}zQaO~{U(t^y# zvF-_3IizRdECkN|^Y&F4VGjUuj12UW+OTH*Lilkf@!242*1(siT{Pt%@#R3kY#3y6 zky2yD{VJbFq!3m|sTw97a|lqSWuUUU2TG(&su&PkMObN$sHZTZNCWRTi)BUL0z*kv zKLO)S8=1LJYr<3&ggQVOK#EG+%|&FWag~m?izJj*jf|Gvtsk4ab(;PrL7`4QMvIKC zF(A@#Q+}ljzW#jm`V!0YDdKDUs2Pr3Rq($T6SSe|cwt%de*&m%n%sEewRk}hqoT?` ztLi3}ujxQtEI{|Rukm{2Wn9^@Z@1}qZJr8)*SJ<6(~^l6(+#h<0pbxN2WTbOy?_tc z%dbd;ZOC56eIJ7>Z_B5)*z*GHV%`f`w@r6{p6w&#_nI-1kFR|pVE^lV!yKgWM~Rn3 zgjc%hZ)76o6Nqpd=hY(xQb4$vK<#fXHO%UtTq-HkKe0hSbg%*9zw@krq2EK z=18FQ^NYUX@VR|#KWp$EVWTj|hRI*&pEEjf0r#t(n=%#kS@$%k$W59t!r5hv1sT5Hr3b)gTVw|mL9jMXp25r0a5ZFn;)e#o|%(OpBIiwl%N_G{iw z1l4f(fANk|Jl8WwPQK5@b=Vr)(}he_jyCd+$~r-9h_m;`ASJ$i*#k{4ZN%+B*-l-} zCx~g}E5zXXrXLLg%F;((M#TjDx*fX%-r$0_DSf^X(>xfhRMxnz z*sOPfuKGCeBr5Y&!j0_TS{ZkxB1a@9XeS5#tzr#&>xZ^^2a_38yQZhfk;!AC%g4=7 z^>Xg#Nq~+c-JbhtV?={`OljDIS6TTc6%d{kL`qVRx^Q^?geUTqO|f9#u35_0yeULg z573jF_YJGPjK62|_o~D`=s|9ek-8@K|Q5;@sk%pARh4lEp{$l^53_)-6*Vb|+lYjm7Y7f!|189yG=! zR?Z*}6E1m5&9Y+6MzR6P`8by&4uDgA1r&}(M%E0a7297-CHnCU-nM8vmt2oRUWrM) zl~Ai{F7}AtMcmZTR>_x&IkV+)B`)eYJ&meKs!nAa>c_JOGAh)Uxo}Hv@yf-Lbci_@ zt`7{cJDQA4X+GJK1(4Fb+LB<|`pk_j(ZaFQzM}4zNsN@-+L(vQ0aSPlIT8f8p8u#s z%Q_6n)P?6XjBuu4k(2Q>&SCFk9=1tRoNWJ+I%Rt@KYKX_-1vkC5w21aLaW=qkxTOs z5F_*H)m*Z^(K+oFL_bm|e!(W;v5wcZMLeOh;T?%b*7Be-{1Khx+zXlCfA-eqK<1Ka z;kDRU<`Ggcde$W3A$6jqYf_Z9`OOyW$G~&aR%bY?TfB2UoA&z*h$PL|!RdCD6XvXZ zHtxaQRvbGWZg_LoUiO;?O3ZVRv3_x+k~!Yj7fZ~-=T&KR77}MrTq!VnryFPVt+P?N z+Ejpck~5cbpaGFxo-Ta(iFUSqChPw2+r8b_gGtIk5I@=OsIfgJ_{pA2<;Dl%)IZ&a z%LmZgA5M^7<+KVunZJ|8Q6LkRSfFiYw5prl8zJ`nhV_51a1s}}z8D`El{sCO4o zkmfDVHrKtGzGEA<>7L-n+p8BG4xq_2AHyy_0y{z)UCq8GCKCPCB0z5t;9*!5LDlTW z{`#AfWS8GN_#UJL>7gJte5;YrGY#N|O6d49(FSTtFi1?9;y2l#>+F5wJYH+=2~#-I zH7|026k$}Qbm)6r@{?E;$IdXs3?(pt0-UQy)Sr)pjL`w>B({R?5wsy=$g-B*xea1g zM}9s$bu6}PpTm%4WM2l3a`C!XUj>9}C~}N{ie-5q$%@M?+c&+r3GD486e0)S>xVXc z^TiTv<5~dMS@jkbcq308#a8{clJ@F7kq@EH*(Mw%HhIHo4}Gz0_wchVXsIw403vb` zG`?tfqLR1aE0A%$3oSx!@$7x2E9af4+{b-nHT{RM#5p|1zV$x3P=j?1T4fwN<2FIL zlrS*(gYoIYgf^*$7>mFZTFhpiTF$-iKzu26#vkdNNI0(=c$JuJD!RH+hvFIc(g4sW zN<+VG%W_`zztEx>B(3^F*V z>pWq&&Cr}GLY0$;MTQ5PMTh>GkM~W%u`|JWk4!S)<*gxwV8rf@PP49DS<@QgemEUW zryn-pJe1gBkSj?TF^Ht{`YDXn9Pr@o4ywlM`pUxMx$*Nrw^A3N>nYkxsp|Yz(;74< zxx-uLvu6LG#|7~*A!sUKf6ERQJfpw$SOa0aa^FIAosb|Qd<00%P38E-OTmcF0QdI= znVtR&rx*!OvTAgsys2@`NgA`99Ob0t+<+qc4)t6@jdxls4UmyT%vK~YV*+0hn7-V| z5RRQW0Rq=$@HDZb7<|)uyie#z&7ugngbBV$eF4n;Es1YFB!*n^QUcJ$(m>b#De?8+{8L`jNbS#JA8r{$ZvNVx}~HC(>q zb*VZV<>usUx*#*?D6|jTC*S=n_t#<-s)^`lD7|~?Le$~ic4H|CP!e2ZWB5q|PHhj{ zUCT0dsoZP!Y``$~%|U9M=AndhQFfj;=a6^Tg=7#MyHd=5FP`}y`S1UupYHtT+GtEP z@<9n!AluF^dgB>BG0;7Vp4=UaXiZIt>225YLg`x8VQR47Is%P32t9G*61aRvYgqQ* z{5$KvavZe(#4(FU{~pIAupq3S-H*vLOfck%xy}S;)Q^UZL~3*Bj^bF!G;_?plJCgE zCD9*+pITVGG?^q>yH6+hv^OZ^_twuwcVp1*tu?dic93EW7F zRPc}+M64AqSnE1{SU5jAyu8MpJDclBw}Zv^3`+~692hdUT4O}V>X_Sl;}`mQ{^S|0 znO!A{=N`oRr##q0F!sczH)vXPvkiTr?jRyk(E1UfYne*9Ka~0~X}vc=KuHRy`o@`N z%`l1VNwj8G{GTVDcb){J_^-s3)oz;I_mpQXAqzZhPM;ne?Yz7)i8x1?O2v*p8S!B; z>LzT!y6!ai%TmxS3$l;Pw)D%lWWzWt_EspcWOjPRc32|4>|773lv5(YM&__8tv@(+ z_NK&)1umojj3*JmLZOjG@c=`?^Nz{MT+3MjU!D5QI|YIn{&M#zqsk1b4%P6HK>B{B z;NB#7eMk?XEnKq`LIj`3z>$92DTK}eCv$_fK(Bb(DV8{mk9hSiximcMDw5>-2{L#q zT&tnNQ_sf8T^pUt-ibF+PjOe0dm+&G{m2N%+o=;$2i_kCW)ZsIpVS!S@ZN9a;|S!7 zdgn-XbNI!k1$(S<2IXU@JA31VRWgb{wVGf1dq;ApUK@ivWN8N7zv!}K+2d#x15)3N z6oO$|r9F2n5Rz0nvuRVxkl%u{2qV#2LV*Y*IEN-YtB>8{feNzUA#;%Sy}7z7=Jli3 zKn;xaFcwi%O?VF4LOoH@Dq! z$M}TlzN9UVowH(ZE44#o+7(SpFZJ`WMn8XpzS*Mu9?4asE4`;_rIwf%a7SVO#bcc& zN^6!FqN0vrxd|Z-K{GR{wu^Dafw{J*A)h#3kfu?bCDhbaXsq`&!gh7#X3hA+w-)Bn zw0afo-hLrvz@c)<&s(o$CSBbD_=Xi(KNZ=u?&kRrE3rfv5ey9~_nT8;Nn`03fqJ&CI@MaelJN17&Vm%8>y!hrF5Yqc|wb02jVSP zs?u$F|Kw>m9$pP}I8qUO#G=j<>3BUo@Xp7ci)a}Uo!(dgDWnM zv4eY5&d{$B6MqA^Lqxu6-xH4*nPAI z(fx6*bZK0G@Oei;R4{3$` zO~C*4UHkjdiqj^#zuH7p{f{;w!2hmIxEXWns~&A?163`GI|q!L_|%uCU3}ABl~vT& zCy#1mu=kvJ3rHi9)j#)q-=vm~FTY-Y8}q99-O=uCYtvTW5AfpL8268k6}no>jt%cn z${IXhu`zrvo{gfI30umEuzF!?&Ojn>8Of<4m6!=}I#3nd|@tmlfM_44rt=*{hT{;dH z#u)d;APb|Ly{~CESn-zRf?}Ow{BPW^AV@>;aUF{UIFGr@DmQGq^I(gn_|Ixw5Tmog za2mIFWOl;LovfrY6itzHOdnn1_r}C#AmWCv+Mb#D(3Rk0&fmQdjEYhZO)DsF08Ivz zjWb#=Wv?Q>x}4|igldtHN+|gz?FL8qBo?gY{lHnuK z7}4cznuxgR50dqA1;J$`{%s|gPFj9HS_)*7I|n5V0h>=^TnwXTo(adpCkI76V^LqX zMr18Tj`@{9h7a3I7om^TH(EZMtH%1-;HfA%$-0!OvL93=?NwTkM@Bz^M{sGH0tf`> zAR8y>0bYWA;CGy6un&-#MqpDiuo8kh~u+k$e*Q z!MzlZFh}J`fe(MKD*+FF?DgwiZi%%>o=57pT%4^=L(qOm1?hHQTPtZp6Jf7_DorBs1O zs2Tij)*(%JIOSv@aW&S@;rao=>G1dH@XD*O_Xw9izx_FVU1g4Md`Q!?IX{I}>V|CO z_#I}1leYLp&i#^HQ5^0k^zR;iI*%cxSv_YvosZHylN6ekIKXfSx&a(sevpG~iKUkP z>?#0knzG1IQ8|mz{)`2doQIMs&F&Hkqd))c2WC-}#b4%-4S1t|k2yXUyxl2^&}kwR z?!{6q)&uGI!5dkxXOW}_x!}L0>FimF zO+l5x!o-$c!QgJx5GADj2^sl**QK6#-VgW;Ht*e-d8@k9^VoR%D@dO4#%s?srZ8wk z7`$VhBf@s=8hiGuc-HQ3U#iOATx#mxKe<$5n}6N&A|#Xle$V$YBdn5DVAD2UpWIeD z$V0bjH|2%4MIz!smp5{2rL_^roE?>5)P7UnN6Qrcv{;mlb zsn^dEANij7jAKraE?;$mHs#e6k}nm?%1 z0EqR$^h_H4{``Z7)|VX)CF0+GB~V(DJD4`x(aS5PWAd~El7VmZd}YWnr)y)%Gx`4e zZfCO3V0`J0gwkXLc<*eIj?!vBk=*YWRGlV>P+B4)JN~i?>EL{$e$ye zn}0(~O*zARQlT_h0Tsimo;##z7%0Ary!%;c&H|W84Jm29Z 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 z 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 z zul8pxaoxZgIk}GD;z9md73X$m3Otqk+`R7PKpV4rQIFVlK{fK$m*ynW`h{Oy750yz z>Pj*{^L4LFii9VRWu;^TpIfVTd0`^`RY0(?fSYy<+>dD3xs5bcadZO}14ME|%elL0 zB5W#0T5kMw4yiXbID&$3iP!s##4BJp{m^#Kyol+((=&rGGnC#g$VMV$d!ZtYgS>cd?EWW9K${JwtQ*WM7doWTL& zF|BGa8OfgJ(aoKHi-w&C*Z+pDCvAXb3C)ca!q8l5S8@ZhSRapGInAdO9f-l5QL#zZ zbLTA@Hgw}G@z{2y$6{u42Ou{u2o!z^j;R6UdTDa8qp>xR9Kcv=VGe_%O91cLdTl|O z+feboy(0hD`MqzS`@u`zP!Sfg8VmuBL<~E<++_iu`Nr6x)*f!kwF(8b9zucO0ItM0 zHhcm3jcxjpZ?Kh{T0Ys#LhZH?_MQB9ZJ7T#?BQ6ANqg2v90x}VN60A}c6B-$kE|OV zOigw;U9g$H>42HL_PW?)?8C71wTp0Sop9IewDoU6OW{ZE(oIFwg)F=x%Xn~448+BM z|1r~%4T}#rLO^6d$$F0+ZtH&QX3nekcbA_%W*R8lqy53|82sRBT`T)y1br z1?^HY^PQp(zGRHVSJVKX{JfD+ZZ%~a*CU)PnI5smy!L8W&Evv#^zH9o_9S8qkFNKG z%C)d1^FWf9#3%iwA87XB?lR0WSKMnyDzW9Z5>hpI`?cvaCy$F}N-TcHfX+R1G_Xt+ z8$H(Ev-W7+Rz_lFG3gO49fozPQiKA;I82IX1tI>>^>W_Htc@B35qo76Cza}NeiZ8v zZ+Lvi!O(#?^7&LbN8s79#X}4%4V$$ zTIXB-5JDBV`ee9q;*aDvzIl4Tu7$UE?MB#hw5)kLT~Oh>ukOb^*vbcaLAue>XTepH zLP4kJ7^>Q52Nkb=12UfhxD@SsZ1fd8#P@_o8j7xGg5lGh*D>ael$w zMJ3L0v~S>cmW&v% z`X;8^6|*{`*H6@=g-ah@eZWP-E(nsF@W=$Jjbc&?RggCJ0eUDuF3@5gp;f=0Z zD&()l%_XqSR|5zJ^XmtZni2w(iwEJ-f-n57UKkBQ!P|AR`_41>JW#ccrAKC-Vk|f@U(WFMlY`nTe*ayHrN~f1gdly%vK$ayLUW3NJB#L$n$N>+pCg%{ ztbgDJCPzVM`z5q!&BbxJ;^wH4sq4L0<2%kA<5P0IQ!3lzopecRzTzNt8T<&Hw%f=m z1`j{$C>D0`ZUA^m0sat3+0J>D1*w5QMz;w$8lB_Dgy*4VUWfo5AON`Q$`NrrXpUMS<&q@0Y!OqAP-%lztBS1KZa=nq!lVd_%1x7Ikc zANhWC?Q2qTTyleWS(hRkt^RLy{jT^t5<)du(^i%3b9_3mOBo9VAiSkVJ z0+pc3_ce~&Uw`xddU1jK!rkFo}XfA0N^1-;xjdc^Pd z1M23F;R;0r`EUKsy&8D0zeIBxm8IQpj@D_CuH$UF)w;Fj*x_%P6j~(HZ~%d8{?5B)S$2FuAla< z_kQhwVbY9`kJ!HuRj)5n#JkJ}y1$~6q2t-0v%utcFY#;Fs7-D?P2`O$+`|~XB@I+B z$JOl$Zk+?pQq5-{qym!)@}0BBF39$-S$8u(xQ38+aCv^uHPIo}2YJ7AZc(HCRpzw& z;RC&k?KmpLmMyW(7{kgB&?BD$00}3D5)}YE!m*pM0wERwo*vg=c0Li;0=#_WTi12U-S9mRq%yn;d{mp$LdVlYV$o&J%(eX z+=jbP4QGE{C!Q`@ncT=RdAEtlc|E_AB+jO?`9pZ%)9(}K;ib1vs7H&6U*nFx^{vh7 zsAa6Y)!Lz14y8ZSqBu_SH-u?@pS?eBaf7!8{9KL`SaGyFJ&u3$rhl__6pZ}yG}ceK3m-0?vll7!UHRu)7ziky)Tqb17@bU>-PDx5~|&GriD93 zhM6>&cU*Ye;JFDk{hu=!xDeC7*R~nI&hmt7oyRzDYkJEvyy=q-9HYv9YI?e_<-pc) zk_*Afw38DlUXh1Xc~knt1f+)Ede^AsW=b&5zkGn_cwh2S(fCL;V$N`n-i(xvPWXKc=)y#`_#TsD}q3z|in&jB=K|v?7i|y`Rm{5p z4Ty=yW1A|R(!N6#5d*r3uijipVL(#EU~h_FKv_LiuRPYD=Rs@MkbAgnBAr(rW;fOi zX~mu4$>dhE6P8j0IqZMP)RNMXHRa&x+a}$puJl;35Oha*Yclw$=F6;Netx5o%w#M( z=soxMU=5iNg+dZwUGBmZ{0HkXM_pjxQdF>b3}nt?$G^U^F}1Ei;7NajDyCQyn-Gp4 z8TNE`ukg>MVdsvTWfJbp^=}efGd~7vqc_hSyJzbvN{)Sq;XJdsn!R7ALSl@0(yMb2 z8*oRb%@rcBVk6BT+$ndA#TyL5lY0HvCqPe)T!<=~G^FJZ=ELhJ~(}b_{quDU(h~gA_>>&+1&%9QmZ1IN+O)TK* ztl!$I;qJ47XXA#Y6orCF8FGhO%3Zr;UXgMBa}TsR@vtlK-TYTatej34c3ZIoA{5=Z#c0bQ^2hs)GzhciXghvTvF z)6-`jceu>>BI2F=R!;N2f$L6+#BUL8Gb;e=IzVTz&8-+*;y2_typ=C4Q8x=e!zK`8Q1}SxZWlt>Tus`FyW;bHIg`$+Q(jhr*f5 zGNAKpNdeX~D&W1CC(#Bs;dBnQQ4y?UTJH<3uO0bL7%NIXG=e43LWX^9E??lb);@jZ zhWpmXxNmIu_jFcYz}BJ3%<|2(VZx_)!t<<~S_}4;gpas|p9zQ%d4K)#v}R+^pke3R z{J{CPKFXyhtLO^3G;sc4cwfFEaF=-M*_CYlrl*4he-6mP4bpzJBPeXVS}b|&HI0G6 zW=?Uar0M|xWo|e(u6pQB*#ON{L_7Oq&P)CkY`>fP!hL`Ar80WQ=|{7n90~P%!*FQ* zEZ>Z$luM~P{S#+xY9iRK#Q=JZVJ3cvyv*Kh;ZLh}H@+kGSN7d;cVG*+G|Vn3;wJbj z-GP=#e9dL5<&=B;1e(T0@PR+s0GB(cKALf|9_@!nNLmsRumtd)I%1QD6zdx zs?>|LkU@g4+$?N-hq-vib6M8sff)Oe9!I>|u=r#Ea{Z!rrzic74*4n6)~NwJz29}d zt3Q(Ah@I0u3+HcNjE$p)+=)`&D!JYm1uzN8_PV>r6Wb^jeD1T};H%JYi2`#MTU!j( zSZW1d+&U#Amnx)2zNt=dv=0P^?un`>4#S!D5Ec9d`j#wVXU^NbyWFMs;)h~94=wu= zDEJ0Eh^Xi&;5`)?5Ukw@)vLN4_d|WsFt+C6NV`pG`GwxrMgO0t#7nCMFZz1n;YXQ%0U-4Cbg`YFU)p7x~fB@aikz`D5)=>=wvPD8*cjcaZvkZe%34i zvJb>b%3_g)W}hslXe9v1sG5>{os-uX6hXvV(y$A0Ddw0J&oxImM2iP;@=0et*FRKS zn=#W&(=+O2Szg+SJ|}%i_VM6On=bdOGBfDMDiD4nTkDl4Qy8^kc~F$S?%Y}1&*O$4 zsv5gh&sA6OOAb6(pA=MjNlxq~jh%M!<7v{*d-7)=E+H20$2FjmD=Dgug{nNPB?6?L zUb*SPI{@_%Ng1tXaul2gzgT&qW(@u1v$y-Y)u!Au%;HOqsXd$|uJpZF;Z1}0JxLFv z{EnnSqzP~&iH03%Y`=R8A~N$g<9c!>j8DsWqmb%$_h7XSXZ=p#r_0BzIZMuM;?2`e zXIT4PJf1vxc;@qMK3PeWTX0B|Gr57B88O`2!22fQjv!Ujzj&`l~a+W87)jS(7T|YX0{8K4!%i z*?G^iFH??Q_s_Tlm?^EEsZ5ix`nEVm=sDU9eR8Au$0bLjBGH=f9egF-IiLJ}%GmIL zTi^*7HF_YlkP-Oz>YRckd|dG_w=mW5v ztc*w!^rY1~GJ{#*CWw{=2xJp>k>ffANv#pdd#-A#Z>Cz!^j`cFd&6{FZovlN*#$jz ztk&5tG~p>wZyqa1T( zjRB!~yMH$>Io2yaQr9mxPn@}!YhT|y>aw3+=5r zkiF7NWTKo!-6!uMxONT3I0nM>1xxX;(}M}Pl?o|Nt{a{OAx{f! z-7bY+ZR3Vn$F?UN8y@ck3Kq5wT8tHUe}Giqmu=|wNiARb{iFKRZFwBZP=46;QRUP# z5<45)^43@OJdvBM1z#itkc;2)pvBeq!0&y;Y1lco%B#9{K_#85hne@^qP0Pw`+Nm! zY07uqCRo*t&+6?RSSG3T)m*H8on04~$dxspAt#t`+Oj)c_zjqhwRjeN&iJNY|T3@=tKh4S0I9@X;BMr;Q)&JDKwC zatyM!44A6ue|>y`y&||5!^j~mjQPgarI`QhVgoLGx_)Gt-XjFJ+Mo8zE=8gRvNT_>M3 z>rxJ`Wcu8`bt5SzHaZdP$~Xq;J$%_V6!%;~;_?$G1MY@)1UAo=#hmrJWq;QB4uQw= z2xYc>bS25emZxLoYbVRS7t_Gj@_XrQ177)iA;V|&kzZ4i*qr=sJfcS5R!oqzYfih( zWMNrQzFwZ`BTjlKRo51fk-D>5Zq4$%pe3b>zq*>k3yuk}r};R5T-U-FzBUbcwvWEN zEQaBX<9Jp7>U(&(EkpzfHOXBok^3b1?)w{i`7>Wn%Vk(6330;wi2a^ z{}*-d9Srx|{(bM-wHB+lRdWtHe<5hY4O)QGZL^co2gZCCFif*`CC62b~1k_Z+- zLZXL==tM%IgjjW-&G-7<&s_KKp1EhPd1juO-#`AqnAd!K_B@aCd>_aAU1O83@vvB` z(1N|sgDOE+@~|z@XDK4bVm6%C)BFjMX6-bb@x0%wum^klgzJZ|yf{j`l1wUMjWkv? zXaSiO;5gUk9h)WWf9z)vDhUowc^-w%`ZWKnSzYavJn592L7}Wn8 z4R0G8Pmg+93Og4%)bC=^+g{;eXEgR@DniVF@bFBYByL4`HC)mcwA$8h6~sovMGa@x z5-kZIDHi5zcqnvsa+AjwqDP~r=CgRX`_-pw@>i4pHvrw8#*XC&`Rgl}U~Y8uq3pi{ zpSfp9-J-Ac${3LH-+q%`vwU2gpd3p)^|(tf+1&qhYxgQObCP4-wJTJ&58rjeK1`o` z*)m9YvDol%-toFTAN#`$smNGaBTlK+l=@yjks~nyojI~B_Y3xkXB2jLbc{~(e(b}q zJEw2#J~J1K#|x}>IU!qbQrY)BVMi_n!6JJyp!2;iCS?oKQ) zQCidveM?~INZyQp&G_ifz@nO=;C;o>j5o~3BJvUyaBQuj32#D|LI&v`+ol)l*J=BB zGfPWHL-ER&kdg}9VZI}Np6~4f6n1X=Ue_miUq3~t6k59H`C134^?;S)6!4WkqbLB- z)h4-&UL5OTnNQr#SZ?{l*mFa=g6mvql30w!;Sa$JYP)iGG|U~j|7=aVUE3}CUJsM$ zlzc+0SRZB0k#PAPoEaNnIeieJotmF0)~| zA`W%hf4lwnSs?KX|EyPqchb6n7LAnMjWJbE*JAyxd*iC%OupxNyU%Y6a?)PUQ|`rp zJkACM5nF8X_I5X%FiK-q;oL)#i!eJK`Qv3Hfwqfcy=X+&z2ds#{aVYcM2|gInPqLZ z$NH#yH{)$rTL4%@(C$ljhhgCSR>`1MR;6lgV{g1_*gXk7#+KEKwS5T=a!cX8(~M3g z+m=r+J$LPLd2NX@rZW8c!uxhAedr$>@Ulg4GT?%0%dxI?Vu~L@HSPky4al$e8~1cL zZrO|*%PP;}Ho5Vt6oFW^_IkuFC*n8p%crBEa-PD@D_kIb{N{C2{e1X%g<5sOdEZxt z2@~$zXWCz&fP{1Zd~C##Eq{ZyTUOXv^@w=9Kjp=sPQd0gTH}!PFZ|nI{aVt}YzVkA zUOMw*(N6L^mDLb=ntB6#D-UWcK0^11ZtKW-4VPz%y7Omk^Oh+6t+#{#IuRkYi8=59 zbEugXs;Oq-qV(}M_0gA?FP18{(L9pcMlkg`ZdMv+s6=>u_m|oo~yP%C*PUca(#K-_vSqLJ~6%~4AB+$VEs>7d~p#Q z9%<#oGxTgc>gBN4n@M%AE4bfcFkAroNsgM zva>+v@Kxxfc$JM`5B)wCOfc~p5SY9;t-|uNKoZC%3 z)0c%9?))7AJ-cjnackwC&px|v4cLWHCB=U;R=4T9+Le~vgZHuy*7KeB<{EN_*I#ND zU)6rIVwHSW^>zNjuGD5$5K^3_(Y?IgntwrrHXCJDr~zv<;{n0}9D*u^&l=-fI72~) zIKHTB+b~?E=kY@cI`x+wN#xSBtUaLzv2Ky?R*fVBg$EC=TsYEe`a4&~|FUzx;EbHk z9(S=P*za2vpeyur9!C!$(q^{nqI2AVW!+-%$@sxl6ZaM7(~L%YrFXi6A%OA>rVI$e zD~Nj<)@K%js!s&o;0iwcg;kyA1ER8TnSrJyTJ(BwPnOSJu;2rZTA0S|fFk`nztdkL z+&3vT*BQE8E;RjO-onUceDn40Ef<@fMH8UN6{&0-w5sWi@f7DMMflK@7KinXToN9l z_lZ9kd4kOYqd?XS@gL-nD*cWWb^$2QpG3eRjQ&eEu)o&y!lkgx7zjeE$1uq$4+T?wB#cE6Jehc+LNH&ytrqh+a_|r2)$gsr8TY* zXs11(ylx>A}TT<8& zk9owBsK|n1{VV52O)%(b#qq{RY=z8Rte)>EFQ^^0Bq(n2Mvi^Nxt*qC5pw#J+K)MmcS=lxpIc;Q4$y z+M*1BYi*lX#oq@cyiXfVy%@%lTr;j0C*J7ILt$qwUm2y+eUJ@0O^zyXX2pke{{Z3d zbEd+d6S?h0(|pA{_~iH%9Nu-V3R8TZj9 zcx5e~B2?*nXDWQ+lE$AXVMre_e)>$WF}TNh_TeLyJNc|d@Wr>ai*?!G2tOIQ{VAR9 zf=Vn;yasMl{JW!L(#|^Go33}BiF|^pCf!)9vP;BaAOvQ+97lSz3$P9bO*tiry-x)p zaLM$KnVKo=ER=C~#dOr6xfT9W+|-yW?14y{=R(c(l&Y%}ExP#Y9Y>JsZ9zNKcV4qY zEOCv<7}}I0G^Yid(z`P`bjTfU!zkVM=pGCq_=)9^tTK!iPy8IL)1yQBl9+>}Qsruo zUcff`(Vt&Qif!ANpyYE9H6se|GJE$b-*X7b5v;X=;-b2s@v>e4@OpsaQssVTiHqZ={Iud zx3@u8t;v{%VD`%0?5{ZSGb**&4z?T@@3>wD5Wj3*0&h7tL_{o;3ANQpE`LJ>D=+I} zCXw6d8eg_CZjLBY+kL3?{!Eb85+GMZ(iu_`Erv|rL_GPxKz)Oz1PTt6s~Ne{reuo} z`v`Vm54MR1$H%K_mI0B2?dna(wjgN?T9`lj~8Xm$ycl`zO4I9d)2Oa_LRgHP-g z6M%re`l8!Z+nm-23Ok#t`bg8_{xX{@*odZ0S#JIN*aqLx0Z}joKuztZxY)MN|BH6+ z!sE~9&tk9DH}M>=vpViII%~u6p)Tlb^QgJVBPd5apKJ~vxXZ4m1UH4L#PpjcQDJbl zob1Qg9g_kzt{Fwy)>m&k4`s6*AH+Jbp_K~=&INC1#5Z}Lm}L%5?JqtS+vcoPROKXm zjU|9vr&|1vorUT?T&jb;OZaff_e-qv?J60SqZwOuLWf+{1J|Rxmm+_)GNtJMwm1EM z7J~kxKVVvR8OK^$Jn79m?0>MoZQ)?ne_)uJ?;ZE>ysXe}PT=jR6@G-@5{HHi{8g`9 zDf9oP9dP`k9X$N!W=URa>)-dJIF9XaDDg?dHC4lonECyoNG&0QU55II_^VrHkHYrabDq;^q*NNe_SCra$jR;=xB zDFJu7!f37m7U2=WrS%?V<^`rq$UZh6@P6rA&U384_E-0vtsKXQSF@T#t->IMT~6%_ zcP_{8-em}Ea}%lJ7isByt{A>YtN!>W<+*cK7YtNBn=k%w=wWxPd*Q4n@iUC`{y1O3 zF8MH300It}qArulv>#b_~v=;!&B=nWys^uZk1n=M~cQ z#i0}cpSUChqr7!q%T19z1t6I;xw%J^3vCU{n@sh**{l~6gaas_g+iI66UX>VYt+q{ zbJT+a+CJzIB88p%_aJ%vwE_+Vj1Zd^T-uFqqGpt(h!1z8V(dy!l11JBynD0$zRv}` zRCW5Qgs_)je*5^^Y3Sj=6Qp71iP&{_`9?QEAsiqZ;7IdVP!Hqn1JRp#tHc3ABB0^t zS{#T+w!?FQ!$kJ@Z(t?54#$d#N93bLRcVZN6w!Dw%+)D;K;%pt z$Ap(|Y&_{qMMoHJ-PTJpt=w+;{HJqjgLjdj)o{aT{;TI#w{Z$P4_WLyUJl#>tC|*E zPgkT@n)_Dq5oOPi0AWaz?mTP#qhR5a3Im=8<6}=Nci(<;O2EN; z&7+es6+{NcR?gjiAPxV0hB8_U<-m*zsyK@g9bP`>;03|PjxP5{+)5Hp;e&>0h9Mp7 zw@c^A^ivsfaUVqjg5PE)NbP-_dm$tAa^9itCOGMW#V$~DkYAU{ur1oyMaM5BHI^it z3CPal+`?7h@79c1@FuUTQ*>?q|G~O8|NmfJn-`DRV?;UG@4>%XeUD!g;n8~zc&xrU zh9HC4ZBUensYmrxR#1-j-d`lVFRwAWoMjpO4YW8>^J$PZ7bNVbFH|+X%rfJ>L<Z#^@<2T8d z^k`{s+Edg!yS z5q2Yl(JI59m2}AErp);tMmBHOmy|6Xro!XhT{QTjv`BA1{WC?=LQdrR_K8eN?50C_ z-WTaianTn1n~~vj@PbUq8*EGLrWdlhd=|peN>O7^){)Qgo!{OPrGr2JZ*w*j&1Utl zCQo_afeZBirODg4{QJI&hyV4Y>%Xc(9mXQA4WrAJMW``9IkF5S2}yp+JE|d>Jinhf z1;*76zallic^dep=c}0ZE~z6&8};IH&%xK)Te-Jw4z6=JtjJ6~F)cW^sQG#KTj5O5 z>W5d$?|jr29#)m@ONAS#M_)?+T`YOy*0@}2TWGrMzFPB{2%+`h8foL>TP=~V8E*(y zVm%;X!RYu2t}X77^C#Yw4mJ^#=PrO0MTPVM)T&YI7J@Ins89hqzmEu3aN!s;G(ZO^ zrRKP47-rY!4DYn_b}pwcihX8H?IpJGi~jd{YNvj^B;~7)K!#Rn&TT&JBcA&a!V*3& ze?5}j(tGKn-gMC|272%$w@p~M{)(LRvze)dG{ZeBM`K-Fc9tnVo^4&6h>sC}(V@!J zLcQ!hmD8i%Q>Bj@)w!u`rPGQKs{tZ)68kqHEK( zRVgFL)83ka$%l7e4rR@`;^~-cI-ZYA}VJ8GS3!hB{H5#aK9T6dS12p4S-B z27ps-^_g%o=$2*9exT-)eh`_KquhBY$MIXSr$bmAe2YX24O)Dz^Kqe#%3d(b;I&zB zl)Mc1o}(789;kcgS={W>Cc@_@qKN=M8e)WvAxrl-nQ=(F zN=TfM3iFoeL}6!%_eQ1Nehk;huKmi@pu1YLWAGvO+pO8=)&3JB+iJpy$-%d?j_M#c z&AhcD^RZRhb~|rqEPEn)Y%e)8(i6lPfg|QhjQ~D{Hb(%3owX}&AcQ&^gr8R_ z+y0pVXXC(k4gx_}u8rWiM`($3jo#8r1Tw=6vJ$A2mQ}v(t*94D@p%NYFDz)nKp2+K z-J|a(vwz~dnNE&;3M8Y@=0C$P+L9Wo_N&@NpcWPnYWC+DJ&Eh|nJ;>46|IQC7G)|~ zy!-N6{0x0L1LOci$FlorZ^5Um@BV`%8R}~q5J^^plXW`Pck=Iy=68x4ElI~9%$V^C zCsnnA6YERUD6Rd(er|?g3OgIbY92Y3E%iNOv@?C7I#I$f6SNOn{^d5}!5Pf%4X92!u_~O80l>kN4yH@vkwj6$KR6=KB)ZlRoK3geUJ*16&^H zj}Gh;Gx}+~w;33YZvOcMdKx@M&_xl>t2M<7(hnX@1jTy087!T=Y>H)M9jc+Qv->*s zVb7M>TwrXOJ}APJ@KOckmsg$UaXfNl7w_vbL#yDB%Y#wNf2)<+ux^Oma>#xFjWfm8ljdomHtvqx?h2ceDzF$$c|q<9nwT4T7^*3^Z_#^xrEM z*P-e~j8EH=m8_hd*fIJSh{de@zZMJ&|9VPu_)3#zu#})K8@Si+z7r-}w>!(i5%WLs zgC^!{n`cYL{_yNSFj0~Kr&LJs`HT3LDXQGQ4yA12p4Rx|9NS_AsoChb_9bFlX=&|x zpfJVZtj83>S>!|pGYfw@J)sv~i^p`U&?JcWyOzc;V@AU~9=o>1l6e=~SlUaX)bjwN z(u_(RkYIF6?qWVDu3!V}z5LAb2Yflf(0E#jJ^EIUe{10lIg1!WKD_(cMyJ(wPuL*o zjq5uKJLe9eL)k~hW&4G9FYnCvo3CQOJ(*-O-R_$tGlY&#yuMVJC|-9Wd1ZCg_2{a> zvjF8p`?^g#`n_BczKaF(pJu#I;Bb3Ys20>USU`V3!;XsXn8TrdII{x7d}3$PBk`$s z|N2uf1pgufW12DpWn@`qz}0fkg=9o}yDXauyG}Bk-G*#Cb?J7gYO|>YtzkVt&(Ws3 zBcY9+nLg{}z5)LjhO7mB-IB_^LN2D3yez4K8v!(Sz`tj0uI~?o6r-C-Uxpl@JTxPF z%(tkF57~s*huZv=o}5^mYfM7uqNnRYs3*5PL-o$0MedCQQ%+)q(=^6Pl z7uud|TU$fNNeq=R;iu-a8ssks9-}ybHMWb39$B_R5D2oo2{oPLp43GxyiQ!bD@eDX zl)786v&sBLhc{SEmlVhw=a-(f6Ax_Re5#0oqT>jR2-|?CDT8LIvq3WjedGF}7#aIu zXD53XXJhYUur#+Vg&mHdQ)m=&0MPAzj|?6O_r>_Vmn5GA;A=sBfZyl>og1>WmkU*u z)@@Zmu7wR`nl%G>`m#R*8ze(vhk8>9zyMSl6R~=ZVX<{8*Hw7^tTDxUwp-d0Bd7lO z?)AYpJ#VI!pMK$lMLs%spY!p~(z*-jS|aOeRiJ?N>Zcj6jgq^uS<9AhKVDe5^60wf zPlvi~mlB-hW21g;|L59evE5DInp>RvwV$7`6N#JuemJ82&=;HeSo7@uTE;(?$Dps(QP0ITuLCARk^ZtQ$X!g%7b! z#vmr!*n@A>bdA76V1r5A`Vp(A@pOJXq%Q-iC#I>&p0n=}1vA@S-a<5Ud!{WtqmQ2b z=+UstT-;NrVkMG2VaLH`mut-NvDf)1>^%Ae_l?!A--sRi^~X`;ClX&pX|ZddjAWX2 z+q=`3mO#zCQ8)bMTVW;>;ioXt9CLh0cCc6ibXq0d?Q1k|h8pp=)Crvb>Fj6f3nDb9-FN`hc3|!;!nb^|- zdkFThZEBj~rs=0DrWq3UPS^!9x*;QWq3sQC9F^SkG~w219gV$~jOkRF*?5oLgX0lgD}H%Y`Opo{Og~z zk14AAud0-`OCz(b*J$sX4@BJ@_(PQy5O30-p7K4MAW7zj(+3A3SKti@igP>-6|*Wo zAN{IGFkSY5MByNo2$VQ|GAQ%b{2X-~M~o;9i%>OQ=%h{S<%M5nMN? zUH2`psz_d1(pNIwdjSVHbn#|AQ!N$jA#96xRQGQ!rpfz%so!O)+XMTeIPVoJ<^C%F z5N~(o0nJ(fIqmhn|BJ=fbGa2y2&X&WZDeI#aoEw&!QLyTuf zmVe!k`49hl9p6RitrgNuSnjjHLDNF64EoWc8GT^x0Ufd1VVpyz`wKZpB0D9Z4z9hzPMT8qP3;85vtZsM@B||R(Q70X zVgtEJdF}$0Ur)iLt_z_on2^Avw?g-$BLgnlOrbWWD$>4Hb)HFL8GC0g788L8A+%HG z_AJ>PnS*LGtWL3Ex(_g~OV?A1Q1~u~&$QyGSr#vAwKrafUd}$Ew?ycKftQXv6bmDX zfGGC+A)Y`PSn#ZHuy!U;^$n)~XFx18;+-MzTsi0HR9@p1x#<*k@1#fk4bM{U4@?EEX*(axnk~^ORKro$DvNQ(8;TavdMJ?%cClm9t z2zRfAop|spUdKf!s@j5h0Sp9L)~r!r(f8!^Hce{#Yaca`a+|x_f?%s8v8naP?N?2N zx$j38&PofD8~^qgGE1VI9K4Z{PcHvD3Up8!>O5n`+Xg>U%*H{=evqA6`w+aTjrxzq zsdfL*(-Bo~a(sNY@LJb`Wyrz3J;Go5pxdtS9uOYoffR$rLI;9M03akugX*vwx&STL zosNnMRxDQ4T(kuYric{tw9#i`6^Wpgk?XQpKHQue_~6z~M~Cn;x&pa<>Cz0=Nb%oWKOhT>Sz_EW{_=`U~6KG-RFa;88`xOAMj(*HF2 z%R7|JLO<|EhD%zH29RP()CkvR8HwmJ^(KlR(JF9LL#kfIrD5D~yK}nawnhhQ6Vg8_ZTGHIM2Gs1{(x z&RYi)JJ08m*Azg8>JFUoJAZwDSfMFK>+-pa>vRsVN=~|}#v>lqg<)VAYy30mO1bQ~ z;~WF#~CIqJ%AmeDxowOo$PWuZL3NYg4#BcOg zya%`}x8Ki!BB@2R*@-?)a}VBYywh{Zh-VIRCxbo1?;Jx}5;SQ5C0uypN`RC{l+l<7X9n8bsm)6U5bkw()?f7_kfx^z7J4zc8PPaKDA><1=uCh*R+K45&jcZt0 z|E{iYjpxQjNB)sf+G`-+i}K`UWL)9vHPGdo0B1$TP@>75b#Jp>1ZF4s`lcU1co@rc zWr_#GI!s^FPhV&tR%VQ!gi%KJtFCXO`Fe)ni2-(i;V4g##s)B*8s#z(KdZ_F6hWr~ z@~I07XSEfmVptZC*&xU`H}@>9DZ}9t75Q;NApSMKU8N(Dai|wJbbD9XePNrQG}DM> zPol7MP*o-EDp6gbzg(Hd|En)97yna(iX-#F4{|O(-r@(@lzuG**)xL1D~Vqh0NG9& zOr3GeNa4s;Z?0jH?(^D-x?`0`RW?F#apClql7l!v1 zfVaY7S=1tr{a(?ZNujarj5O2oIqe-T>5bPB=S&OkB70Z3U|d#x^PxBzcVhV+XgF{V zP{31Q=^NJ4{tS<@=($Cv`+5xi^-?LRv*&g4C@6xC!miBx-}lvkcMt4#+Dg@z&dGZR zO?2a3lIrL+;(m<2IGd77@`R%dD=&IcTB8ZZ4+)dEAAv2$esQV$zCdK0+STqm*MSwk zQ8WU&yK;j|o+9_?!_9*)MS7o>7*1tvO{dIcyxY0f^up0dpMPa*Q36m%lC6|3uRyB z`bTf_{nvh)p!4th=>lax^%%c55MXPuO7W#|*r;8)KsPC4zk7u5QN4dPLqdy`a$<_oeihRrXIWt)jGO+JQ`y__9IA&*~Fx+xy%}W zW%<*i$hURI?^WvRE(Xqv4t7;z&29=ir1D5c0FS(sW(9f9B&7-`6=w&gZizz zadBIa2(Egb8kUI*RP6Lreq%b9Hy{1Bk{TovI(TyHrj6yJ`gd=mK7x1$qmJCtw24`F z&m5y(x%3()XO-{Q7w^4)X>@WA#;erMYGE7SC^x$Yb#38)gpJDQEP>Kzb1=#M86!FC ze1w8>?olV`@#L^sm`fIwTS93VSh!ZUwl0%oU|Sn*xM_v~*-x4ves5{(yOq2MYMBN^ zqFah5LXNyjrZjzlRTwN5ymm7laGSSK*m=YodBTQ-d z2$Dokh$J++9D5F5D$N~7S-czF&rwbZ!n_F<)@)4Hu`_Fj`-B{pJ5}~>m+Hn8JUv7G zoMP{-(VFRsA7}2d;l0@ur~uj22l1TQ;V^`3NFtRt*##_ye9us6In+tsP6T0k-E@Kh ztW*@Mw*}SFTf`X25E4T|hUjv57}W@Cr5wULao`fw8Wa>n4S^NM^}| zYV%VU!su=TYKWUw>1T4z{In)h&3$JJfc#Q_`94zq5hdb04C$St{#YFroTy7eS1vy6 zS>1KO{@mqOO~8ceH*~92>1{%+FoK5x2Fo&Y0*xBq5wbQ+8Iml?b58X!e!5cWOE*Up z<{9ORK6TL2!-W=CHx}98GcSy;fCQJgCjqtcG!%Be59q}KFUkI`)Q|pAjeDG6za0(w z+NFl7HY0r_a%p{QG~r}?_{Z%TvzvrNHRz)@zpC6~hf^`{Qr|FjVqtE@$<18!`gzYu zY7WbV4|6W$LGszK%d*_#n6}%3ULr@!1H@$SX2u@%HGmnZeHJ5*QD<6|%Ip$i@Lm=y zN*;AbF6gXlIZJk^iXTC%;Hw)Mgx2$H2Yb-;G6A)Le6>k8l92KcDoNz$?@s~G&z=RH z!BnQd80!D+ z;LEH>KRG+-=v%H$zWQa_e8S3A%)9nOvx82ZaOsM0NBu69cJo#Pg58Cwv9=zd-yT6h8gwQf| zO#fgF)5^KtJHG{eh+3ng zGf8h+u2ej}L3MkC_w(s(pMz6EvBM9S5&S4NWI^L3;?>4N-0xfgA+)~CF*Mo6zaZ

    N+lq73|*7& ztXqY4RFy=Fr)twu*)NUdbGzz)=5L=S%` z`DRc?hZ4;~M^{qHdzdTB;_u6Z+RMLmRC42NNu644nc2>N?)>_EB!Vl z-{}+-z9JMtVm%QGW4qM;a6V`4#<3eeVb|w(n#+f3MM~fkACv_bHyZ|3U@nC3)LFOK1iptIDtD%)7Kx)ceCX8;Xbz+FFasm@&GO79Z8T3M+-m_ zNJHxQl6+}?Wu~6dPY!;oFEZnZc)uk%RCh-*UvBb3t2*~Vb_p(&a(1l^6X;OE%#wD4 zsHe>Qp^ydY5o1)KtTk}?41U>JKq%!jhjZ_tXsaqNc13cE5VM*~c3l$YKBtJ+Uas0+ zIty_bJc_lQE^^r(`s>mRQGdY~%vn7_rZzw-@RSWlrt2Cqc0GozP~La;!t--DO>0(2 zD0F(or$4Q&0C}VXz5=6+E?nN8v!pW<>R=kR`oks(%EKKfpC-{V5*6w>H?HxxGu+>t{rNc6&vp!kwuMpaoa*AutiqwvLg5AQ?Yij4pa#J-kq1!AeQ)#$n10 z=?&>VC6q6k;rdN$qmQYtP(|}-yE#}ZCV?*TVIQPAUPy2Y3(yT9;~Z!o+%kQD=`XN0 z?znXK+_zQbVh8f)>mqs1JgdDFc8nR(Y|>s(`wE66m}Jv|EMN-Pes$ z6RZn^Rf6}91b>uSFH{y&yKCE@N(cI|cTld?(86bN?he<&E2;9oV%hZ&PHbw6j>`fTy-0N|4l;kmPw3V*=<3L7Y z{9o1N3ZS0Cprr+W0{2dhXALJ&MAz}q%M!QSo!a36oQseJgty$;Dgclf`JK##8d&%8 z0`BI*@Dz5QKYw&Mq05I!qN)OCSS4y+ng00jX%qZOp+QgR(cP6X`|-h|j@Q5O4-B4^ z{~QqO;c=zUeZFT2zv}(-22VHk?i6`P2sL)Q4HgkQ+0YQpF`Uw0mca(_1BL50a_RC* z^EVaYGw9GgImZWp`_xswAHIT7{pcv(?kOq+e=MwPe0)7-+tS#ha$!n9+wyl@p)ykq zx+|Y0QP0(t$meyDoZ;Z!>$t~0I5ru4tuzdpkfJly%_rtVVdwqfQ`#&s;+ingZzw`@ z>bR#-nhA$@*-r=Z$y!q%;DB+Iy5$qBsyGe3DGU!f1Fb9O_;wjDqY&;=@Gf?0aXEA{ zNOhXOJtpC)^h3^C9v$d%z&fXHnwcB}u#j1LhT*pZT5v3U6!)Bv|11jmd@py69J_7s zBg|;P^=i;J=2w(!$IQkGtn7lyEArl6-#M=nWxcOLFuR@a(=l`+l{DxqL04G>IZ6UE zEtK67<$6FsNF&>sDeQbo@|Zr{*aAWw_FkcfXhw|7MF~h!f+QfB;69LA1x}Vx4xQyX zLA&o*Q%#nD#F>7i*-oZ$&BVn&6PHge!$-sNc*d{w?#n~LErI!#^^ZgfrMlb z+!}(A0i<4lwAHoh>F4Z5Yu06tpW7eSit>5zTW2`-o`w0mVAR1z0lqvRzP*bVqIX33 z&1{Mi_1O+TWhcv}WKb(pwa~`PTyUj#mc-^of3Ng3?e`v1WZqc*XWk=4A8eL?Da&6=J`_1pM}9o?8$w~zXM zaSt@);*%aN@7uVwUH_;@2dTVrP(jYZd&9TATp`_?N1AvXihEuwTBJ&DH7kJ@t-;_e zYUjl-qO?8czsbUaQyo~?wMD=qj#)3ribu&G9#-u9 zs3mX>8P9`m=Le94m-}q&D#Mb8?DURryjow#3vqn+;9Y!1hkatCcw(8Xo3ptq1wMC%> z%kh8jfmvQf+@NLVOpWamxZw})LgCAFs6AYjRRv~(;x1?bwi`ItY1CNhEi^k2L)vcU z&(Xg|OVypEIoBM6>X0rszMm5$gHJrz?UA~Y3q@aZX^@ty?_}z##YqHu?6>=ZD zYEn!U074a~Y~J-E`5y9n`@C*ac{4+K@H)+iVe)bqIG;P>8WEu1l#nDCwXFh$F7Plz zy2_sZ89w{QJj*!AHXTwm*>YFz7c0-l@oT25l-7pJ`GqG+cQH?|2DvQ7(3<()j8=^h ztL49OTZ3}W6(A@oKME^uLom>q7hs~{>uaLbE+;tOk^sfKuDVe*d^zA(QJ zBgvgeuxS-6<6lA79;?&E;WSk&83kW@i^Zc7-nxbulW!~}L_6QNHroB$Prz<>V(7RN zv>5>oL4Cq~||Khy^buguwIUzw-Y6*rC*z&N!dsYADBo(OjF;^$v|UP6}IaqDxGY z(?OE0_b+Qdx^bxr!SunCy(3cuBP=`TCSwVftd1eJ!PmT~+rHD?YR&=;R0OfOf6j+h}K zCmu`GQ=v|E4M%uwlkZ0jJZDZ8&w8D4h9QVX27T@Q>v^pa&u33+ex%jM>V@qAk?J(8)S^l{%-g!E zxGLqs?3`$=7*&=`n?;xFyhk*^buC~mpRWVI(%$%utABKOi=GDV23X@h=V2Q27z8Qo zoPU@nM4>(DTQKg(y^G%>q$rb)ORgm47Znzslz~whp~L5LMs)kllbsveOUc|pM-CVLMhqri)sg(|1RmF^vFE;=$mG%N zyJOZq`{|7JNBeD!o+NPv{>!HT)1pKI$xi&F+={}^1s$12SvY^Uzu8$%P7;TDGoAn| zn0gi*;F1m{=;d?SBxfayYQ6haPtu_)IWG*2dK}cgT2XS)X{m0cSJcs)i7vS1@2t0g zn*(0Cvl(B~S~gKf&Cwx7O)oTi$5ogxKXrr!3vtaYE_)h6j|Q9~_APn0WR#qhmBIb` zwMN-VBf~?l8LHDSqAx+}Bhf0ELT^gW`?QYqnH_Muu#sls8oSs432O`(`00zStx|JYvtw1HcBsJN)rTyP7Mc<$?A%=z-BKjQ>`ZE1 z6PN_HyG-n)iZ^w0(#~Q0Ky+ESq$_p zXfR#YOJ9Yz>qg(5dv&I)r2SYWFO66JE@p$Skfvm({YjFMQ3<`qPuYj1t>;18-;IEt zI5@q>A36yj%k#!`Z<5RQCWW16;>S)^gv3I0Tzb3&z6^F?vmG{|iKk)q&It~rT}B5Zf3Dnh=T#wqojzc$Ay8tHIv`G`V)D(0gZjYlKBW9 zQ&jy$Zd*48eZ`ThkSAI0jzqm=AhOO_NUH8c%fmN}Hlt_bI{aK0YA(cR5XNTtMj}a# zwN#s>Py*SzIEi#@OE3p+4{py74osFvDY6Pzis?kFct$FiCmBzDA zbl$`KK=U83=?hXyRa#BQ5BXK19w`B={Hp7*KdReGyY2m=*kKJ$8H&a>-DVh5A z{!8S+8F$HD+$(&7XdU51Gjjj;3ZS_^h>S?+IKsH}U9AMnD6excrqsy}_b;%v3F(eAKWBUzR=YKYiD0d@-SkRZwog zp4^UnV{zepV`se=?(eL*&h!7ge*Zs(n*ZOwb0S93Z2qa=A*cVU-xtaMUcX}~_c9jZ z>y{I9L82}VPZ(m$pIn)=WUfqNEp88?zMnjIxv-sMcM4^AB~V1$*+s>pfmXfN?yKMD zZ>9m&WxJuxDK3VDQKpcU&k`$FxbE5?*8JHJ>lUIk6PaDqwY5x{-Zk9zV6cqA-;ZGz z9@N03-lRd?hBD!+5eD}+W=Hx%*|+Z$+8^LQf%JO1bCx2x9-p_k7Cr`SajMvGXrnxL z7B91BQ!J08C805U%-ey`ChXpgSW4n^ZdLty3*PO2(bMZkQqP<2G;{aFD zP6?jWZPBHhaG(4U(L%-Ssj-dFZh_NdR<`KBxhkxSp>q6BIob)s2@5Imh?1@CvPSpS zg)jPsjA#7nirH{x6+QqY4Unz>?DI}&*?FDrd{%z?VA`H70UmFe0gIDBeYL`kt$V_UJJU8O$;wfDfSl#hrB5pd1s_eIy@#CTZ(j zw#V`oCr<21sZY(pJ|(I=FRFuWgSrsqvy_&Bmw&bav^%5{`Zy(@U37<8r<9|)54bJL*r-Bbn@d;dBsx-mxU03rrU2W-paLd*qU4tKo|bBEn+fwHKQb>>qs?cV z4=Io|9^BX&DeYf>Fwz=r)Ak_+c2Dp*kH5NGXPz93i5oA3djH_`Y$55XWVCyr!CgE)MoirmJt1Xr_)TASGInOGWUX_m+aKiZKOTR+9GJ{eD3j(C!ra@s zP+ie-M$s453x)b1XKFh`C@tj@*|vnT=_ngq(>A)a9W>6ooms%jC;QZeKG~XDqtL=# zwlD3bP$lL);P(|0i}LY}xvuWA3CpwUwm0T3Og1`Prjk9#jC=(@Z#{;p&^)M6qBmgMx{fYVn9mgdeK<1#I zl)45PJ4+OU{jabcH1j;Y9mC$3b7)Jr{c;@kStn=_?w&WNDzv-=Nql?UevoUo z-3wCqD#ZT&cgMpWy0(Bf`itAAw>ZHfZOYx;Vmpeij%4htg4ZeG0}03_lnik(%br?< zM%_9ujauKrhS#o%K8omz)E)v4oK0y|NUAqq4l0J~=2f zI~X6X5!OZ=FsFzKCwI(VQk*(c(2aTfCd|$0semKas9nA4Q(L=6kGLsak@H)ISvh<|h9*mfSWg^83-x0Ks-FYt>@irj_AE44lfZRiW8)74hHV@t7d&LaLv z{HGfHsbY-PX=i+7pq12TwsEqikcW~pGN?%uu2bPp>xFRPkLNT&9>#N^SPJ)&nyf)J z6`aS+VG|s*y8{PiHkmva;v${eVq=mr8`Z@iKOM2b=H|GAtx#<=KYcs^|me z_o}3FTc;pij7|XYgb?-!LAWm?fA2zJFV9PXxa?l;pL1(M>AX@iD!rPaR=+Jpg$L+} ze7|=B4>+<=BzUIxKHg1cj^s!8Uau-F-}$wI^a;(3S<++5BNNt^KXjPQ0F>@j`9ayB zQQf|@=PRBESA3yszvMgcNlt(66xKX_40?Wj`K1`Kx$H3I3#Ov}cc!OaY0;C$#%Io@ zI}#q8`MF9TA#=O~5GvOy(9ZrnxFHv^;>G}7a>Fcf`2_ts{8%U>?Og*%Jqd))Y zhmmygbhRrN3L(Q)lxya$BuU+3%5{eM4Sab(TgsBMzcC6MWz5)0w37>f-n zfj*tx^W+}&*-NHjFF1PnjY5gN0N8!do$o&e6s-?0?{e1IzCM}BHPh;u(_+y2Qg;iJ z!Sv|u-Jpa?XPvmx{GS@9`S&q69bS93d+&MRo7_~`8kfMVD^G>E!S99E0$^A^O#Yr* zoD{G|kM}LG5qCL^?u`yunq+GbkChwr7J-v_Z8AIaADa!1`VZ!{If>s0P7wNTl}t*~ zrfWD}?rz}hRa}#X1|PU4yl`6#q>8wvU))O%emJkYwgbE1`RQog0cGY6}BW?hn z*k~>!dl1il5TYUwBfxs**+^#m0JLx!{2IP~N2bklUJ-dR472Im`5oebtF^)XdW)}> z*{AUD^YTLM4TV()o$vqkh2WC1iLGWGP`msR5^@y0G)=3Y_J$lH`SnmWO|KV9(e^U{ z9N-A71iVWkk)0iE98s>|q+DKJXsI%N?f6LXg0WLao~eWAqj6rIZ4J!!6LaLggrCEca|ir=9WXA+4<$xTE(}jq*;XW>IA9-1vMz z3cf%Tey;TkO|5qf)4_%}aqoMv2Jo1A zeUexEG|Jc0#nT{=mtwDGN%RTf)dlvS-Y3-=tNY8HBl1G8$5MwaE{|;X6a-f~o+C_m zpyFMLJ8FpMbPudcPWXCT$ibN#5dwexuzAMErfx)((sFRq%s;0+k&Ado0azroH^{xj zYC48d;b!2ri!rby`Iw|xsrFf;$o$KbBQNJh1;jsoTcoCyb{KN-rL>VS3WO{Ec}(F; zAu`-fV#{WwVZXx_o~TKE+UAQ059Dzqy0JY6y1|rLAQ~EG&|wWbdD>}{R4(a>NV^j0 z6L1RrHWTgLxXQ`&*Z}Go%g+<9uQjHo`PKC8j=yHRaVEd(s3P!%3)|XTS@K=O*fw0O zXDptK9c73<*Oz0{X!B*vj{t9iyyFY0@ONdNDCs{;FNceL$(m%))EgLWher@;LhBuS zX>bA)1XdcrN2p@RLozWn2+>-SYWVPZPy=UR*Fj|U-bp>LMqwmCimW_E5LnNe7~HoB zC)L&A!l(+3+$qi63inT^%B!O=3a;4*Gj#^MAujKmUTOa45F!&apq!~6zT87UjYDQ?1=Qh!fkPoGP}5TaJcXbU@oPM zL|~)WQPhc*xKkS((7p4LZZt?y7I{#-Jma*DOnF-$2MMbwf6BHd;>lFiVQG?UEz0~Q zbK6P)srw)mrFb;I5!HFO9PZEF08>VF>=-|$2AFH}?KQ;2b{HH=Qjb_~p9a?3oKo7z zu_FnR9XqY}r^y3$h7BC#Ig%uNtGykAb_*u^QDx=H%Z=5k?~kn4ZIPua{Hv89`^%1` zn3YejoJvBC{&K?%#inCyc-z;7XW1urA4L_D!W)jfq8yO@22$27=e7OgZ$7J~YflkU zw*p_^q!3R>b03(p6molPbhUm;EM)xJvL1_ROT9oVOSVQbH^?Nd2~E0kimhqZxYg5n z%<$a2P;&l)yUbuRVAe!zfxg_;rRkkVaq)mvqr26@!zx2gCC58YHg3j>c_8&QTz-+W zJK>clc|X*UH62F57M)jvA$f31S{6>;3SxfA%#qr2%9Th~Dc*$0}O4X*!xQWN~| z?$o-Ev4m^Nre5YtcHMJdnlyYfEZ^>uwkQowtBm5JZ!t!&Exq_j>J;yD(T|al$kso- z%I8gXhiKe>87bQ>Yp)VdB6b0%zSo;a?Daj*R2*oJ4U=Slk9xrrOl%NJT(3#77;#@z!)4k=_^}4Z*m#QnrjH$|hWE@(3FQW3;cSU_IrF8U@rr zq@gRe5^G8z8u-M>kofjoL3h>}#Ru}bGp8&A*Sgov&?sO}&k!Z1#*e*vpD zMMsV1nx+b}=k!fd{WzK15iz&T*bP!c!6!h7`GU-78W1^Qvqu?|mub~@iM!_*%*#V| zhiKKujg-o;1j#|_hNsl&QM!uarv%d4<^;DhEl5|xOw6J8C@A)1_ zqQ>sNez|t(uq!UD9 zLq+au<%yVJpg3%e(u=$Bx83pT1a;uMS%+ZRNY!!ZbMCp*d7<6m(o^QN_~vSMNr;o+ z&f%Gvkl)Z4F?b0N#BRZEdtyRMF?e*KBD!Chnl)?QHGu$oL5@e zV&eM@LR{YUL%|CsB&Pk3SlJRpqR#1u*}h8cu#`f>mIOKP{182-$9HpE+H~gp<{o0} z#9WXN^V34U%A{?q$eXSW zkEh|qT(q-t*ZYj`v0Ka61X2`9tihsgjHonlufYgP6z5@G+LRjsDmbqRxl&*_w>Fot zz2}Wo{g&D>f-*~pZrH3AdEJph5QuZ?DCR9C5RD{Sg@o$1?)~XSFC$p?DY+G#7OhYd z-Z0gQ=|OU~6dSI5BjLd!$D&M%@w6N*t`gVaN`>3zU6O7AKfgZOYK%_k-XcIbKLAhi zv6o@j0KT9eyqN;wR{;{3&VFi>-W|pXUrWBqjmNdT*vaZzkpdDo7Pf`ygmK=%G@e{& zNmm*2+?I(Ty{z|7S`?CogAQj*HXF$s^HhaD`dxDEc3{hx8X>Lx?j-A9A484~pRD*S z5y9`x>od~a4s>=R%sPVC6Kxlu4WN)3`*|d_;O!mgbx;D#T%RE~VWkvY{@pjLzEIN} zuQsE(eY)JE-z)Pj*6=fbTLe&f=OxbqD%6sIOTYX=lFO=D40N&e+TEic+teMS`*Nhw zpweJBv=2<A(UJ9^*SIm_*&p2d?$?MRzU5 zyXV*&rk#J=3(jqS4`;d&7o9_jlCP?KuR+p#eTAm_Eb{dy(;0isBRWm9Qz68eOUQ3h zwcF1p(*n(BWiHG}Q|SZK92M@z@Lj~s8y9lzk1d(}0y~77C!IdlPx9LoW@9c_f05Rm zb#MMi#?DpkCv{kUU@jtwth@NGZhZM?RWG_xZ2t$tPv85A_4_cG+k+=w!((*v+!{2J zyx%;yYCL*aB79)K-y|C=ma=b$jUx@?Unx2%ym|HRE>+h{eAX|k5Me%s<-v)@$JM?K zC!fMZ!IYoK#>4YxAzXxXL7{s(_k!5>sdfoXzXPq9EqVWpw2)KQ7uXOD*R?m_crMG* zC`gk=$odoMyh|z7X+gn^{OV&Ti@Wn(Gb7hXm74Q9^mSdbWb7B?|8La<|GRqO|LgC3 zoLzHT&VyBiM;5F#ylJ#;>|2?WZCu*pdA&kfAIhD&CY<&#RD)6Z zM^4>LQ}+dIvLDZa2p>wv`Tf*A`-6>1c(B`WdGFIFgN;KMk66yBJJI@#IwE1+0le-uY{k)zmK<~8oWSNfj@*5Jh*1AQNDPOhnkzzqvF%SMrVv% zBdkB0)M zh(}QaT2*)DnfC&zyRK*0psXJxlw3ayuYJw-^8V8!ogcSWmga(A&f7akrp7Suu6-%t17U^>PiYqj!PY{-btm-+^cy7(Ls%-T+;sBZ85W0QPeJ#g0y9 zt&qIO10>1R_Z zYhkCIcX-q!DWh+rRq^1A=R*?*ddYGAZLoZ>S(bC8`76hDImbc(ScnGTdUkyu8{Kt8)(J zwQqBTgs3ks`Rd9Llydm^g$LW_6PM#oMRgf>?1ro;t+D6*8b#*jeBSUMl)EnmWgp*^ z)^b6X0My!yzyO8XgDKl*9P1)P?3mrU=b9L*QO6$lMNB4q8YDQdJo0wge>K|S08Gd|pCaulKKJRYR z^^W_cHxOHNT=P*E)6@RN>&9O_0h8!_L8U;{CrwsuMw>P>+8>L{z!U*&EbMobuHFc+ zyKQFNdZg5s*E{F};SPVAIaPw~+C@}Pk6sHvAJKubrDZc^d}I+Jz4T0s(g4X%n4X!>yQRWb2G<=YZ>PaHs-sDe;Ip+ozV7gm{GzIvB{hUqdGFI;_b7H5 zS!um}Qk`N4l`3tUnee6@aNly98RfQP)CUg^s?_%JixlX=3jx13O*>X!VfW|<|JF0i zJe{AbN#xKrFx_z=-y5`T0wtPAgx4TMkb2*OtuMYByGRlTS*Gj#p6{=EC9fhiL^i#e zRB-sf#8~*9)c#TNS>j`?5)ysdv7aqKzYq20o`AqET{NS< zYX8#tl02$qE*J zZ?&<{fX*iqq`h^rMMZ8o{)`Z{isB^&GMm#<-gKGPvb3gctLXEsPS{_aDn2ha zZ>}A2pN;W5d;V6S`gnQ!j{Vay-oR$)YoXPP%A|(JQkb?f)GwO%g}HZAccNJ2hpOhP z+2Tx}sn9%J_^FW*UsQVV#qLDsLyCmh1he;MQ$c1OUeB;>rs7L_%)N5(q-DXo@>^fh zE0w13NlCKiU&+{6twp_`-_5tHd0?}!PNP9<+&=N{D9~DD+ME7)h|!_`LsO}tP-O#m z!y8Vo(+rb%?S8b!`+xS%)ZnJu-3TV6@qvN4o?}^EV|40lvL0pmDLh}mFZCI(KfEK| zMDx;sv1dM_=j12pV6{D#eE=~L=t@osB;03OFff!NI~y)sVqOaSde2NY;;8Qeqo#6n zuvq*PxxG~MOl8*Qg0!HY`p(g*evH75asiF_ZsEOO(@~^Vh5`kTmQFHurM&-6=j#7_ z{z|Jeu3Db|>uCMws;x@?_|HV*-*fe!xr2$tfA!yKg#UHEYPS6Q`AT5luJNX*KEEL( zm)>WTp`0JH)egH0-p;H$6H;Ndb}3N4;#5vrRk}g8qe*%q9m)rLXF4HMrnYluy#C55 zB2^CB6V=8r6Yxwgh;w?fE@T3km6f}`uyOALS$-Nf-)4R?^fbNj^nOz_|3X8vIei+N z%%=MjqWMSHN_V!i9i2W${ZE0{VRSKNL9Z#txDUPzn;k#6OP0Eg#VgRtycMg{) zqmuw}t$-#a?d@Nb$$^EC$aoi?rFvk-;o`e5TLE4-JM4cpk$&}6H@ZGeXXRi}|gcNyUd zTdG_rF1`bS?M7qMNQ@r^dLb%T!-XzmYv&yWhpPohtaW+Ch<6d^Q$zrJ#XMeHL^bnr~uW9CoSDQuoQHb!dQ@QH4>G9J-L z3O5(lmHS=)Hr+h*n|L?x+0$U+hfQqN#kpShkElAnFXP2k%v^1w_R{ZDF#M0m*g2zL zOJuTLLH4U(My*qF0+XN&7J-s>Y{emGq3ln^6n%aKuU6-n_NerpYFMOfn~Ox@*k3R0 z*j7gtjZltEfoUHh-^PQ#j2hIa9upsHu$FQ`1KFoSC&3sIC{A$vl#$U(;d)~6cdTr< zsXeA+(IK85(=UeEPr?a{(DPzft=MmLX!7Cf=Ho%5g<&vM$tDTkWu4F}v%3QL=4+Z6 zk^$1u6WCP_e&3x;05DU)WmGBTB86R4X;Wum=o6U*7I5Rvd}wiF)s;q~=%^9@ zomZn6F<^}O?$7K?ffp$5$swaqj+(RCz4QYiJv?kr_MLigOS8iu(xMSohRwgIk~paxu{;d-h`U#e2`a$KKfQ;zp`@OA@S)> zu~#=B14PFGQAAEF=FG=a`~Vs&rz|VzHk(hW@$)`5AcUHF2qF#SJpoG{s>cG;T`s znMQ7PGWzJETh)e5TXc`Aq_5T zMrkxxh_bqaX~Lz{O$4G=2fvlca^Q2TGcHb(CKH=*0(hqN3Yxparn#+?$4i@_Of-!R zQ&5Fz(FP=8uIZJm&*P)gls zFzb5Qh{h#1{}kIke@bjgD_1DyU=S8aT#|aBii#H$CA3 zcE;;FZ*cuG!*marTqN~vm3b|olvh^SQFsyfPw@@u(G5(KCt>Hsy{7WW*5)GVeFiKH zdqu`eK9mZ*a11{58E`!aujcgdPa&xBUvklmrro>KZGiw6_EYM3Q>UxOJGw}au`||Q zOGt(kArcjU^Hfyv{w@*@ASU{75BdX}%YRr?lB(B{Au~S5rA~{Q=hP3{xMat;A#EG0 z{BfRlNGNAfX4g@fHnZ?b|8k?5WkHiWG2)8D_sZ&sPxRlU$H}~3z9N9koxrclUT|XA z$XbUA>lUXz-2agMDAxo6=0J{@2L18n20IPTbuY+w&K)9kSTgcuFHpg{<}+S3XgXDU z58G^o9`z-~`Xm((nc_02<#~LgpKh!$ak-FrZL-$wKbF@<{0H;eOw)xO2QLZc*7(ma zB#{A+L5NYrBNr3vSJ$Kg*PF*8Vssa_e~FA#4x4tmR! zpdQ>k*6U9>CYkH+4wDSo#k5Igm!ach<_Zr-P`drP^q zG7ok-y4&14e1D|-^U|C#%$zeMi|myubAn_^m`XfNE26m|A-h2$Cju_dvrosTHCllM z-Pa3#1z_xCn*tZ?dmRfXUL=3tnN2Xc7q9a$mhZd;^kCIrzhk!Aj2zT>3O zglDhor=*%iw68#6NEb0+)>AB%piB+7A^297xx>`P*!=MZGe8gyiJSxP;96SOrfF1o8sif$lNd&{llNs+C}h2D0~L7x>aba8 z6gj_tyYTZxYjDR!^&6!WCdKc*iE}(0dXRn2qQ*{S_Y#92t-QKI>hjTF;ubzLKdEu0 z&7!3uL~isJNQY|kzIe79F$dp46%IL;`e9U z!WJGc4c^_Izz{-yxge`&t&b?i1%p4fuwOO<{q>|%O#Sb7_uyjh8Q949F{|%b*g<2Y zQoMsAon7ox;dff+tvkIxC^SaMWd7?P`H#;P6#B0_hne)h-8pgrtlJf=wnp(1Tg4X7 zFACUmgfdhIm{jC9N6?yVrfS^hZ9z#9ZNqu1uul!L5|3PL)Fb9+0!|~x^5eFS852+I zzO9G5RiPLu7y=M42tr9YLxOMbNQ#((Cc`2ovI)OQe?})Fa zT^vWOxic!)P8l45PVUeYcp7{{#*XZ#`jC_pPjBbnHhe-58fQnq1m$|Z^ehR3{n`v3 z3erugj~Z%g)_kpo%t&g*t^%N7w+^KB5L34-umYH@-{tckY1W z=lM{Bs=c3$Wy`rN_Lzc){wb)5R~OQHOYeAoGC7c{;8o}tuLG$)pW?oW9xZ~1>86D9 znBfJ2?K^N9lyx#yn==U)K2WDNASlLUSm` zZPbI$|8s~hL75E;oN-^{Pb6j-LNZIPrAk+q5$e%#B3-hnB3mdz_6iuEZ?!Ch-Z*6( zWL7>c;^eE{+&Sb~6`<%@P&I~fc<D|LtLO$#rl659#7wq^Fe>A^awAZOXEM*xH8#nhO3HuXLqy^1$k-M(2*rGu}ka zdbS-N4RY%n*=m#4O-fx8bCA(**@a`0on-rpV&6!ghPZfrf!7!N#_x_VJtP{#9{f?fiCC~%kPRXM_8o~kpHj)5-4fu&p z++CLb#37qlDIVN4tkG&e|C~|$>t(zLT_sHrzt1WPNoL&0*ty%Y9m&qW!JzC;?-*q} zlJCzzUccu4$9hkIRm{9&uEm+Zqe96Rpcw?5Sk5%DiE8zNmx(<5+D@7xRnsp6jU=@&}cbFs=7=sMOZ{ZS*z%q=;50?d)@ z{!^CE&u_ftYq5#k8(*>h^QHOIL2z~yHEl!$H`TnDKE>cd|K%t=nZeVbtn$n~y_O&2 zle7<`BYU$Tm_b{*%Vg|4#bMqHeWE>hMVb)W#H4W92qV=|tj%P|vNjLpd8p0ypxo66 zb5*$Gb4tUA7XbpN!3ls*AVsY*N|829efNyIW$OvV9O^6gQpexO5`1mF@j{t(C?{pb zFKly2q#aCCo!j9v(vy^5=N^0rEq>Qr1@*qf37eA=g&=jxZKWU4sqU4xnW~0`Y;zBi zEdkILxNP=m?A(F`({*M5rIttJoS-Quq!hfk&n+8<@<8R@HOHvJ+WyYOp_ta_GXg^5 zIe1`ju$A3b^?ajx&tf52(@qn`G0qe-<_!7yH&d!Wzs%*miS8@KvQ^f^Bbc@FKn=nQ ztVc-IFu1krgpRkSCJ3{se4s6yK@q|*(MCiG(?i#aUE_0?znO3oueY@yP%MJKDEqR! zl%T=>K2XdaIe$!+iybfR)BMGbD8#Bk_JdUf>{~~caf?5>3$~n=3({}KJj%N?hrjI{ z5bMl4Ks9$6YoSOxHmu)RtC2o((94bx&d?NWFG^`{HeF10yQ=Z)xCHs*j|!MSOQppt zqM_{UX1MsW#7W)$8LRAALuleL=(*V^*e|;HQl1x?7avQm9atQ;_(n@qtxY}VR(@!% z+y3!m-sif6AmwT&3lqMpE4^wJyruzb6O_8#mF@{?y)VbkPID?c8tlVLS;y9fZ{<0PZQqVE zhxuMfWLtWr|I66?`j5_N#`epmrq{&hyS~jCwj9_7uQG@mr8ze9JJXQO&F*`)oHO5E zlaa>Hw2%;=@-Br(Up8@m^AUYSo{Xmv?L)b5Fm92^e`yi6-+hs^@6GirO~dvg7glHE zvVgStOl{WM)~Gu&$eUp$Vn~DdM)`Vh>9=l$EfN{KY|4MTdM1gHU$u`bGyf@#_vuxC zp}*4Q|57lMe+)PNOT0wT!vZe?F=Upqm8R;SibjT4>2GqbU~AFe6yf@4*;KG#O>cH7 z8;q9X#TY=>=O#~vU3uK^w;x#^)!w>`ImIbTJKAoAr*V85@wpYthSVY6r(4PDTuc%y ziB?xvFmNpVk;LzBEHPxW&YMzstDO8o6@Dx~U4!3dy*aGhUBCaF?XEj(|KU`U_+I`s zzb0>UzIYs<1}tY|;;rep+wbP%|Ezyy&1m*ylK7)Cp5{6eA0>46@o+SNoE^)fvVWzP z3&6+G)nwBd9hw?6@YKA9B4)XuaYYw^5$$5OPpOiAm14eFsSB=FTW_*9SnZHW;~jPh z)4KBZt{T4aS!oUPRIYsh&%@i8KfQq1dr%Ar9HPU7r}(>#)C8Sk=BnZ z>cLixQ+vPu+zpL`X*oSmBm7+{9(?EDl}bO9PoT8(L4Q}(p^G1^`l@U3YD=;*4n0L| znwnQp{lalbQ}m?5l|A(muDHs9JOc_umDU)Tu!>a(7uP5T3{WN4O?IMHUO4|c6UBtQ zT%&5rOnr!kdo#FAdn%3Shdg^ve#OUmhqGrq^ii z|1R>*ojFX~G27vRgM07K$&AZ`8qa>WGQV}c$REqZ%2e|G>=pBIkEGt#A8W5cc~zj= zMVu04A~mIe!oJGUOb3ry)P7n-Cu3Ve@RqZwM``{(S|vFGGfHWk$NeRcl#+r&bL83e z18QFhZ2l?)#)eE4RDEl%zHWVOX;x2;LPyp_mLEjkBY_OCrQaf$JGA*v1httFwnBy; zE1qK1b!8uz5-{MvnRu&b+?%kQhc6#eRZ3J>vi3S)uNwVzFW(0JyAEAXGjt#wvt-BG{i7d72d z=@d?$KL2LHu7)}zV`n^nhcp$Ge&{@V_yh8_z1>Cyj&F+`IVmVw3*%}9l}JCC9R6LK zlhdo94$21di59aYFY>vGQh9sv$rkB@KCfpVrbUDr4i$lUfGqs&Mv(8ys22V%HE)i* zx0=BjYahD9`KWK-WMNU=IHMgdzs>Z7ZZ7d4X6LBKSr?JhDtFH?888du%LRXVc;{Gv zrPR}{_2)25hf&hRvr6UYXY_PLbjAgiesPt57Ko2`^KY&BCSa1C zslj^}0e7JIK~Y<+&vV7XcNQXP7|@5WH^e#24VUrBerCM*E9042sJtd2fW8i$8v>U) zsjBlO;$#wYHZ+$zeRV`M z#MI|$Gu&7&(U0yxK!FUgJ;8Jd1}BQis^T0-b^!lu4tan5`?~P)5`iG4^m=y|4w#*f zxkJ1X45m+^_*K;0*mSIy_CcV50o6~tiQf75{ib_X>E-R>z1d|NW>QO!fv&gTjePJE zZ_q-hl(MpvoLjqP&YQoM%ouiObd2B3zE;eogBaG0a1w2$I-uGW#9y+Xf?EywlCiU- zD>L8LmCMzRA$@88(>M=nuyEQ*U)C*1Bb-YQ{9as)HvzK5q4{61Ueeg+0x#s=fmC4|?FZM4A9HRzJcyv}y-!y&2wf|guB77*+&zP9mf<#=v$})QR z%KH}_2ghn$eTO#9l6-Qkz#G>zk*E!#0toT>ase3Y4jwfnyU^GW9B%z{#EA0tl1a$) z^Z__)pI{B%!9x&E9R|dT_+I@Mt0V%XB>Q0lS*v)Y6E0y+cO{yOr_5p`>zv~!pt`^=%pV*JqmtB)~F#2A1-i#V42%@Ir~qeEtTjFx?I$~)53d*ILog$^8IeV`MRq1K534v*2bkv+R7YM zcC1w&+Z#{JCBOCj6RY42@1o6w2OsBo%Yt=L}xPo01=EOLTjNMRp%6R^2 zV3y=fG22hZ&URSgxYQf3ow*p(<24^)8cQ*F^|?9!yX0t#_MP;HNb~qVO|PZz`TP#$ zj0d#=v8^Vppc+}z_p2fIa4~mR`LmfzTxq@-fIka)4)RsBiBa7=OArYyEByeIX)Vrc zo|iEgyp#lO{(6Hq$N8UtcNFIDW*nXT1kM-*s%?!%s|bQ4iev!KGF0w5+DW?>(}ZU= zuUce)`?^B!X57CU5q7E34b8V1kKs@nn?~MqiRe1VgXc%d*x6O}jz4`X{GJRyXVz{n z(@8KCT(uOv3(NP03ncMa(@S(CY8{N8Q6BEKwMR0;Ehb?4Y)@!owUAo#*s;xSl zvv@ewk^^9Ll(KM*>Bjx6NCw2h9o)B`dG@*HwmldT9d%1 zs6YH3)OI~5>D596jIRCtXC7CnY#h=@CZCYDw|w@lv$fTRAAt|MOM3s)3s|7^$}>eJ z{L-Va0$gs^HRqaP?j_ZD0Iql96{yI{v zZdc1W2M^&0!)+^knV%nwW{CX#NSsFU)T+f7N zSM3Y7npM51n{39!4#vc=!p>`N^8!HRazd!L_|<2M_41^V8|^Gr$`@sX$k;jHW$*hp zzq-Bt4P|~%_C|@F@rAV7_<~={(hlc)UHNW?1oUgS8y|+hGJG{6;G(}9P&>lrJbbzu zfwhzfz$E~O2?Tei^DQu!m9NFXh`{yFrbE~!zh}`mnVIQ27kEc)t|~Icgocjcvdtns z`(H_UD5F!{jG+=oPsD-idP;2wa-H+xbiF5yQ}&lbvo*H zHLknCiDBS-ez(1EmHzVg2ROQkntmcTwFl?=XbrT{xj0L5p(tb(C$Nq{?*gFSMcvW zJzmyrla&p$K6;@=LA^jEGefHLDKxHcX)oX+h2$Om`R9KU=b0tkU#>~-2EZA6H54_E z)bp?Q_Ec(`_f2z%&mC){KW)7AyYXej><5G6Qk4i+7d!2rIll*0X(!)5p>13U7&ac< zAY;XT85dFG%*3XMRwp@{g(LN}%8Rl7gCOs0YI(V5y5`blbaTua1y&Twf8xSwj;MX% zxWBzr=G3j7@BVUY_AeLO&>u4M!!SESTBNLH1hsM0IJEQDHHD4uP3GY|Zs{V5xA#x4 zU#QPFDm(^3)Y<0ZMQ9X4=Kt`F%TtU|H?vgbP&al!!f>rIr}V*C9H0WMwkCW`ag4O7 z?Q;N$YdZoR6=IU`_oZcIk^x?9q3cEz4ULOS!XMlv$DRgis8EUu zFht+G$R&47)s)`)D(f>+v5?H(Tuw^TnD_3&ykXNcCSzy8&QCwBtr-r%FplQAu*aio z8Y7~wWmVvCf*zv2vUV#C(qXDLyx)~B0CyJDc_p!EbWK{+PB3Q=mo}ITf?3|0gwB_H6Y~Ki{?@$FPBfr$!zI#m?!W6MfoLZUsWVM9> znuxku@{kI!;6FMJR%|8sa8aN)h#oIJV&*A5mo9wMf)*?>Zc>f~tZI+#Fu3J6Uqmn* z+cN(mO?p2qbaIils9=Z?ro(%pfgV!F*tIV~<)P^MhAGm;;0wj$wI3#v;`qrS){iMfjx`ti>HA7yp4Efd;lr|&GAsTb{3?{4A+4z-G4Hk*1OqVVCR@6%alx=H;Ub_Aalm`}9h~}X z(!wU+?);;qnpjZ#MX1)8@|1A0+{ASA=>FCnkmI<)U`u6LTMKCa{gA6=)iw4YVwhuF z_rRYp&G1bgue0zQPLjlz$ysFV?8-z}Sbt^MuA%Iw-PRTmSB-kI6F zx{0PS84sZ zXIv=`UzN5-Olxz4J6Qx9;`KIuyK&7e2%%7O-hvFeup#0{h_-3G206C^ot5KF-P4b@ z;@(Ng>cMAofUdhTU>?hb0^*aNzoeR<^>M{yOO&RG#JZP-e(7;^6K++k2ALWgm9jFS zhnJ$-Oas%~k5h2M6jbI&3rXW2k=zodjgP^}w84Xr@0wO>tdW!z%5-SUqdpyqplu_^Z z_kby~dzYHDoEP0G-SxKorKVNLtJ#S8`LO@Z8(kq%sM_T;<>tq$Q|EQO6Z`LPg(OH< z#Iad2+zhNP{PSkF;9AR=SsC7#*WhInfTCn^(s4{~#*gj89=iYec+X1SLM(oWnvbT0f_ZK7bytxj5xKc5rr{<7xnj13B}spqsax^Jfsyb@;<{8 z(qtXU6}KhX_;%EP22{B<&7qaj8VIq?IP8g^7K61}Lh>VuPa)S+j4ejP_mUDLBD|cp zlJIIWHJ#Dss@k+*VcoW{hV%RRZyt+W%{W=+FQzlTTp;S>JD@pd$|rs47WWr)XG)F7 zspwB;o3(7l_@qmyd@S$20Fpisy9hIe}3b&t@2)9%_xY@dQHECU=w8dY@ z-vW=n_M$^5z>g~Sd-IqCBkY=~-yCoLoJkg9{DYX+V>{|&LW8er>x%J(kl8RkO8h|J zLs9BM8C)`Tap7EKTYw0n6ul{P1xy@YqCn&%17t@pvEe1c5`*M`3xD02Q=7QKj(b4m!6^=KuKTt7z88ALC8m29`!|N74$!h*uK2aOQY&lF084rr9G2|Zc(7C8yQAr)|?8>pq=sh z%Euf^k__W}io%|NlOXZRP`CTQRxc5v`tlv2lS{qFD4Ss*S`zDequUHPBPg#+mWL>( zb_891($Z_We@nt_@BApV?Cpj*M)Xrt%b6M4#s=~r<&eGuJgy-$ZojGC+gaA6rc5O4 z{JJ#Q&YG-C(;SMfJBo^T4gOy2;^2WW1e#l#!$hNr#J~D?1`z#?%e1&KdfnE7x|@-~ z#0~QJJ$jszgm;uqW^dnqE@T@WcC_Ywy?tf0;h##6zGQ5zG8nNH+0Oald|IZM=#ll| z{1;Ew6qm6cUbBSs&BgYPq@lQX z(yyymlUIg9#wXe*wCM_^$WB{=(xv%Bnsc>0o8-G+jhQacb9$T}9G8hY@$d53J8BYV zQcMaQ_|~YR)?ZVQu`_bFqq;tK%daWS1Gx|oT%KW=E2KhbFgmy!QP12V0!oNq@}ABx zU{}B{UgN9j0Qx)OgX@uRtdo7;6Z!BiAgoh7Q#Bz}+a#Wq;=T$lf1 zfePUXIj>2`_wmDtCV|Uz?YkUGm|B}2TYq360To%quSx~b!w}f1G~`&S&qn8dhX(l5 zx9=tu_QDnLZx0h%LM>-8I1yS7$e$tnv+Uq@Rm`U0c3Rl%|3lq-N3-Goeg6_c2x5yJ zv#1eU)ky43t*R<98>?t(X(?i_TCG*BsI4`s+Tx>#*fXUqof4y^+SgT< zu5<2l-{-pjxc-l710w8JZ+@=D^*&=A6y*J36bLiN;B|0IPmjz}C z9e9iLiN6Ja#g;GWnPaYdo?enx&#A>L*1Re``n31#<$7R5)9nIZE2^f~p#gtl2OkR~ z{vRp8Zd}fN_Jn)g2j)1fY}HXjEHlogd$sVpIcdZ5=oj4^V&~=-JXHH3D zf_s)X*$eKbmGN9i(v))ks^LNF zZMIfT=ULo^q1No*%C{MoRhWV>hmEgFbX?^nTAo2f4#hUJ<0;LI&0g_%BXB>4?A8{37N5l??$C;?o6QH}g1!(n}l)p&J^4;>VKA^4gpDBfCs7-`7 zdCpTOHwYg?CnfX^4aZ`w2$}4w-Fgb;%GAk{{nOi(1;%>oY-J|r$4Ygl>*YNMggKpV z$9eN}RP0?YPhkDSd_A%DV4KFSS^xj?Uj1*pqN!B8ZQOsZOf1mmeE-rdG5xO|$D_D^ zzfaM;8xEdFTE%9D9A3wz4GaCsw>*|K>ro=BkJEL(qWE6_F$$E9s*~WplRsbF*))t! zArDZZbsyVA$Ec=~^de$>B`v?69IMNH4BeZ!>-hAZ-4lZw{MWzVyjJP+DtSi@D#7oO zl9v0?B2+9smG!YnaWv~{^Mwpj#oBV$(6O%!I=UJ zKid>sn=O9WG}0t}VLlTqzvES<7{^~+z?{m9(G>h%97~T%#~$_3;P-DOsWy87L zu@SYqa;K@B^RFj%fOkXR_aCZgXdW_O?30Fp)j{MFfrRT&g?n51n>YQyycKay?CANN z>>{HUd;lLuLtI@f@}b(O43un0?uS0!Kw7%v%~=X0D_!UqjNGlSQ%t#j_5cxZwnQl0 zE)33`qL8G4ytP=zS@ldmYVInAbqOS+-|Z%Q{;_I;MjD4}?^RXwt^1%Z)fN%PG>k%- zpShbNsB!UQ%FouLXWcY*!72ydi%E#-V#V^kgSeB~NGSbxlW#(0Amuw0>e$SNpmfz~ z+n;Ma2nTz2_Ron!gNDq{Sl0~u2p5YQ`m_fGmE($S)jHTXN)ywCK%kG+_y%Hj5u#xA6Lhf2zK zSVX-$51Fan{58WZF3XPst_Wxa$V*-2@Z^-$PY|Xh@BU#phVd*Fn*fJ0PqE1N%Tqg= zUX)(6G#*xPKdco;C(1>hzs^NcjvoS^1g-wVX22XM+O>}(%pAw4pj8&CdiS$fHFo17b-b5XH2Tus5E3QCoQ*Bda4{8=SO;;l3D^WnY)=XI!kzCvR9*B1#VPhiZX zX4nP$U|2oj)upyPU8YfVAK9zrD~(-vM}m}8NlgjDjb1QId;XIDl(Wn~cn-GulzHh> zKzxFWH#X+^^K<|KeS8Ig%et`mLr_(g2|9$~@y)K#105G2a}(N#e$iB{LV5VY9nkox z#y_bmhJ0x@ZO^6jF6&dTMQ3JPMlbS?nRE_5{2G@J)(P-eF}tVk?|%4gp5keo zuJ|YpOVU|{$EI8HF(IsgzvN;iMoRs;nfew4`d>J;eRi^cEEQ`+lXl^$;E1vGnu^p2^=jI3d=>FgPZ@Zy;7k_lxO z2)`XTZazd}#lGl^Ah%~H>t6^3mP1GBxHH?%b#){xUi)mSuEs(beN@{ro)UER!pJo>YJ}<9yM1#SyJ!HYG>+U_t-@HPPOv=j++(Sh zn)cA#uv%>Y-3^h<#^_<;r(7lvn7&YcVy^D6+nb85(#)q5712sj2Qps%ELilMO6zhI zn#gC53N5wwr6bL z>R7irDZip#kmtAJ6IZ+*y>fJc3@*6ydDvK-dy&8?NdHxozNY6B(*}}VBf7l3CU&aa zv3M$39f)Vl{aX`=txV^}xv9Px>NR+ih+$sQWM?6N!%ta)CB6dodrwfBU`6@?^pF$b z+IUURNBTQ2X!*ZuoTfh~q{Gqx&GhUDpKJ$KVb zt&2gPism1nmd(N$oj&MMu2pLI#r%zh89SM@_0tGiql=J% zjqcdzS{*4r37{sv_#57#QgTWamNL73A$Tg8w?uB>mooLygOY=2O?&a#PZVoN=C`p~KoEI)8 zWlofJKLFjmP^SL8>r#o~3fMVOM`z(A!Bfj$eY#yr&MXfbB6JenmvylpWLNg_@W6!o zj%&$J`RS9elbOw!yu)jjwXaG8GpVCj=E+m+#(uGvtw>oHn1X*XJ~&AFT+AWHAi+V2 zrJXx>T*2lOF+)pst?m|(MMsFTtT9&1?c)DD3`0udK)u{3J^viVBa=^p7PAfK z-8p}@-TEvSVAHG-v{E{c=j8mpdRO8@qjkRrCqaIn#?CYSpsDi!%cLRUa?CY%Pvzb~ z=(BFl34aD{FGnEp4mKF8!;fV)m1V{X^1sbrH9QjP!iDjIG+28C1JIS5)y$u8`bWQu zxwKgmUwlqljrsnHY3Gn0M=I|MT$p>9{o+ejc8X_z zo)0$nf}4DHy0~kHdSyTMS!~yicyVpkTl8%`x%*+z;_6*HQkImr1zYl?a`p#_Vt^g? z_)?&kg8&<`FD|>9f9#jpMe=FCKddBX!NL}^B*;_qb}^7`YTJH=o&hWa!|L04f@4y9W1%J6OxZ+v0m6;L~!7Sfs#%Pt<T53CE!V0#4Oe}CKn^VZglXA#**0zgM~f6utw!Y z#R-_cqCY1XWcUWun-Wiwl&Fu7&!>!Cck<+?FrD)j~B-y}frl z4xOST(lCBBO0SPRE<`XwYZa!qgT0EOxs=gd#}Qr zDWrkTq_#RiW397uvi&1Q5JLuerg3@?whjL5v(<=PE%rNvv9F*ewVsKOkC2G8;CRYv z_49C<6lnH6UTcYp=g26~uJ-8Jxt~_7O!P>tho+lX`j2=cYr5meCrn7A>UT_8Sw+|e zgxB0+xBIpE)WyY`_@&) z?YVo_`_|&92T4BN+XGo+Ws#M;w4?9vtSVb#XSEl3rnIP@vdH-YO|m#qX`CI39M+D z)LBecWW67L>)tacD{va%%r(?^A&Z`x-K$xYfRL|Jt2T1NH+)fv|CqynP5o^uV7J`+ zxWy9j*BebxUt|XqA;Zx%*vXdgEvhAUbT(&})yi<=)WPPglxl52QWh@0zg}8Y&66LE zP27HPH@w61*5>ny0y?D3q!`N_^%0pj^@7K)ezHb02+C3327adUOFo@vq>qJSxvRVt zqYI?>%$BLN7Xq;fm|D{Tbm&+}!1utb-;BbTu}pH+G9R-e`fV3X&-Cp9S;hBoW%o5R zcJ0vH^!yGk&PXb$kAxK8Q3;hqEgB8EIL=T(JghRy+kbsKg;IC*m7gSW@t7e*iratb zwnnUu3`g4!Ys~}g>E!TUZEF}xTc;Rb6OAwdCO81lQ!Z;>35@I z4QtK&=j-5)i;6@(tPNVbm0z|xh1@7@y&~#7 zW#80;PE;oYF?aAOX~7*nswhSy8|C*mV**gzcGB%Ad#=E6bSPjUD#l*rCcU8iifLKw z@4jseybcm5Xd_eg_ihrNp|b23nEq4hGcb>|5(~61+L@?(7YdzZKw8qPJ`2%DKeJ#J zYLm7tk)&qVI6$lg{z3V?ur&IaJ5{oo*L$n7<%7*9uiPv36p7-PWEl=L1x_rcW3FgX zQQ2WhA=ZhKTHERTOssOU_H|goRuiZC zOtgR4GvpoqshT#jK;W2vRIQA|Ea@ine)RBrq!%jNKS2K8t2NVlx!43Zxc z$6JnIc$NSrzE{|jc4vm4gs|XjY3!nExl}>0NVjHthwlmlt6DmvnUF)h2XvFO#iNv;z*vdrdEq_RksDnxw@~6` zDXAX{otSXTgu2qQQaPViZi?CjKS8P_EDne|WwX9JV{^A7!}IuEB#IL1n{Q<;R!U9t__J9e`i0kXjm|H;iVlE2|pmXKk?QxhuB# ze2oqiVYIFHWlrC)GEAgfFp>oqx6n+^G=_f_T?;fS&8`lK38?^Rdxu?-K$8xtI1SKt zS%$ZL)hg!AAW3oc{tYpk;CF1V@~3=HguE!9Ftrb&o?jxoO0MtFMDksK3#9IasUyEJ z?L9QsDJ2P%{*HB=Cuw@^HM4QxQFW(%v}ckDjh*AG&9OgSu4+!ZA5aj&%8WT*+-akA zK@31;KYB$|Z5HOi_Qgi^Ct?Q^EDUfjdwBqNBK@ACVtSfhA1a7}S{qz)j2r?!Zdkin z8R_bF^K}2-hQI7tML6-^*fdNLVoVDVg%LxqFMGR>AXdok%j%J27e!aOYpjgrl1Y}q26Rz z3YFQ~Ge~fs)ba$6yNDVJ@wWEO#}Ij_OiM?RQF#%XeGKC4l0G|S=SQzu&|rC^T)jQY_GV(5HVhgd`ByZCV*jm zMS#f{Zsu2o`+dJTn)ZKixIc4g+N(9{ey`J&)~{=z{LjjD=fzjPn)etn!M~F7UD!ri zAd3pH-go>6hN^45GiqTBxU$~XVLfK-MzVy^W8A#3Qlf(6`OUc$`+Q z2MGNE9YqlaH9?d>y#1eOb8XtY>3{65IoJQ-xi$~IeJAAcm{KkR~$6O&T7S@M#!h4aIzJZ{!BG3^C*2_%=5k%g-MRRl;gZpW*OF)oeRQ-D zKu(*@6~&JIxZ#ZGCh-Gy)V46mxON#fWGK1(bq5n9k*BgwyfQ<$H<>uYagdpMJ@|w#PiKRCjQM;;cLI#$STNoDX!~59vsIU z6MJ7#KV^a)%yI<+t=w+#7L1VR4d$w^gLRu_QI^JM~zc4<$MfZq>uP#d~ z?h(z`<;r5Gl-40Lh7P#^MUfPvWD}IB+rg-~)TZ2D$KN=(&81|@lW}{--pU}3>|W~S zd|Od3$C~(A;EeJijh!Ff?-gxAf42|J#nM&$t0$HTSMc~O;yLsCj8?`i|L!YFr{HWA z?Nz^d7L43*7H*IY<8+SU1tDk*u$R&cSR++E6CtDaHxphbvO*Aje!bKn0{h~d&6aVs zP6)8k?(@(mz1~<0FN8}nszr(wy7Bfx;)L>P@U^$HEcCm#7p_Wk@)4QoQs@n`ia=O@ z^c6sE>_D&m@v$x z1dRQ0Bu7^>sli>yjHKH;uAXu=^)96Z07&oy0Vjb_+{3p`;LX;BJt{k&xAL=ZzU5@Y zs1<0g--ZNDEl=9yoE)@3U#ohGTpNL`a$D zF2o4Q?24@v1R`e(Tliz-aNB2qVLR3nfvAe)HumLDkbpN){$a@dzEW-mOFG(9cK~&d zUs}M;VC8&xY~udfMx#_){<~5e>ep$#!}gh5{CH5ya{n8wAnTt1Hubz)H76Fgw(c&8 zBi9zxz9x!+#E8sh$GqEV@ZW%U-d(Rwm{DaV#gEPX>r^gruVjmi#3>uL}M3Z zK5gE;z1XO4@QdL+(O+y7uFu;nhM>oBwLXat`$El_;kg!ceDWy?ws>?Rq`MH=$qg5c@s;pODH@D*Lt7NQuDJP>s_!8#~FB&@;e#goT_SRtq#Nldi@w!Z?GS)=j$FqsR*zku z(TVxQpd>vEY3?3e@6p&qFYg8BW3jv@{o&UiB(TlFzPzf=gGQWd2v$L9^e@x{MKn1+ zTUma-R`i)@`sN`h`%!7M@ilmYS^f%7)I>?k$E^2p48pa2hYy6+O)fPQ5bYZf^2Ivm zx+juun2Wf%IL#(2?cbU@-E6*@j*nR4Uk_Av+m4!jiZ@Mo2J4PbEst$xVE89j#1FluJ6TNmftY0%&xPryVNgNUAO<^lx8~a@QegbCC##y{6X6*Z zx!5>{uFx+L?P1|jdGz;H$@}?J>+G^7M|WY{H?j_Ye08C&Ssh>McfG8*y`EEs0su z_=oX$&p)Dhu+2>97k2Rl`pVl;7f!nWu7kS&4SJ>->Sg`y1OLmXR`6ea;KiwbuOEA9 z`u9ng14C(GCucuc>S)L2eE`_g?OVafPs;<1@32u$Z|c&@Ro&F)@9z$DAMLHl*tAZ} z{<@^1_!hvnZ>u%3wC8Eyj_ylj0mH5{O#u`k5M#MBN4;LISHp&I6%T$L`^RTN#Mo$B zkZrERnjHoE<#B_PQCqg<&&?y=oMO3!lB4VCEZZs?>Q#*9g@LC&K^|)}`Oc2&&voDBsu(`jdQE-2beY+U6%_U_9Z*Qap{F11IR}VMXU{O5|%oQ@D3miQzpx zEVc%&x;gNcpp=`~_wj)iciBMGvO-pEa;RP-uTJHPRZrE*?pJ>-|K!;&%gON{q`U3o zQ(A?+PbMp45dP&}2p>rnpyxTt(Ym{=eZLwNeJ=>W(}mNH)!k!r4CrJV%ADj)%V%FM zHawqqeA9vS3lc5^u`dG}F_CyKS2q9A<`c!PuykO9Jm99%;h83{IPAx&s#MFj?i2fSj7F9q}Fi8{bryRR?rF;~G3Ldj3_{5uau zEBeN=!#^VWf&(vBt_^?d9evM2^DdhHeY;C^!NsK}$@CS}&MA=$V z5y&cW)ZGIk1soHJtfuCq&L~!Hu?o@xGKa$JpztHr4Re>+8q z1p0nSUD|JRSV@+ZX(#$CSjPQa_L$xK$y)gmg%E0W)5Tw$S17HgJw@xD-=$qam0~i} zl6jlULy7TMBgRVy2V>hhmRQNcfge6P|KgfD*tI##WS&svef+-x3U<($Psy&I*xo|YBY+46Mb`#9|< z6g_TOoG5`YBErxw*gq`iyZ?NCwyRQ-)qFUxalyXa&QzK)g=;g0YnbO;_^Y4K(Q{GV zx6^Ed;Ew%?T+c~TH^#%G`R-1ol{x87{!HsA2N88OW)#dRs)JL_&-I{Ef^XW98; zme+-gwaLG=c3s;$mhvPjozZ3&oEBC_)2(E{f3^F(y~~~MD*nGppFDJk)I14DQdpm` z6CG{HT;T`a^%?7-g8hGAUQmGFqQ@a9SzKYbv%NJKwyii9 z>?DPJDyh&H+~cpRt6l#Q!(sI2ijSe2GSwkK>m)sPM7L-PA5B?IOI!5JDf0Zm>EAD; zQu2*`a;f+BB#mA3;{T(&iO0Tw+uGMGY(TcgliHVgaNEF&n#vcl{p^JLp`51HT0hzX z5iV;QQ2FAx$mtIc4IW)zSt=KJJSky~-bpVvC`*>1?@;>p`{=Jx!K?u-c8zBDszdru z-ICV7?xrJyf4`eZyc^E3JBeajN*+(G_zw7#C8*OqC0+;WaA)VpR#*`$&T97loY-9ST!^=9ky`?Ql+-WGz~oF`3B*;dUyu8j(%uZ$CVHYD110*j&L;6SoWm$x;)2VZi?wlK@FU$QH z*_)yAldL+Fcn%40Qj!scztdp55msegv`mkbAJyJ>e>}rzEFy+9!5Xja-~ZBJ=tuL*Ee zLa}|NS}I=D+bDTLOB9@@V^#-P`}wOj4`3oX3$|B-6#KMz72Yw#T~pT=c+ZGUW?fvA z^a485DG~h^DUFQUb&^?g9)ejZ^u4MehFC>Oxs@|5SKGmaUqp52KzRP@lXoQXd>XsZ zAJ8ZG?Hu9nXM9b6-|Pr_f1ELN%A6*_n@_ZWJt&Xid63k~oy&EZt@bM_-<*^2mOjf> z5GUyu@nPz;kj`h$m`uB#_^PDbNC`1d?9;xRkXTpf?e5jj z6ADB(i#3!2koGN31V=VOOA5t5E)4xw|)7XVi9IWsLc`&O{PP3Cd)yJ5P@h(0cnl0Mk(~&)l&`Kn#v+AV8 z9rm<%A@8Yy?$S?^H>LnB9K6WsMm>Yg5~lG73G}APPnj2g#?xy^TH$+xN=usMWo{1WoEgJtE zbA>!_A>=HcrK?YvbtW7m62w)-P$|K;3yc{cVYF!h%^4#Sl8J#FT0 zlv=3SRFAjZsW3-dIBtO zL~u2R5>$MN?E<87!1+!bsiCbWiJS<5PQ58(^j49)Z_wn)GOF@YVN&Rw^@tYLv8K@2 zW9&#~ZT9_P63hObH-N$%8oSsw1Bk^tI(aJ93UT=ad!{k$N#_mG^uiZ44SgjJmu3BH zKd8v+Xo+zU@xI@jrpa00xSLDt;v&8^r;STf@6nY$ij1sG$>S z^~AwMj?`WtQ;M$;-psY36}@%Ap~my)%4f#$$VR0riK^FDBFXoB5Nfd)7UxI zhfY8&>oF4o4Tk1bs};6V$c5P~=GIdINkYaW-A@D`tJWM1DlJfTN6N&I2XKqzSGe({ z*00pBN3NU-DPlQ0f}llS?_Tkwe*7X-qFa>8?^j<$-L5)16}D%DUIec~P7zMV98)gX-My_^ek|Jz@2%A{pcYl8wG^mHUHlO_ z363i>j>d^BE1p{az{dQio%*Z+ja{YT|4~iwfBZ)M-+#lu$^nB%H)#1Pf8VQr=N^pA z<^OB$QSl$Ofd*Ieztsk%bi5lq2-%6;YMM{O$(noGbC(1$3zAcjWlU^%G^cRhb;xpF zLNVFjK%g0sm{;bDR-4WI1G~>5s%vlnnKHSDT2jsev7JOS&2(2N{#oC*BDf!T20I_t z)1-8qg14`HdG*wUy0pdPz#zdje|)y)!O{c%Tb~Xbc2Qf^*Oqrh%gJXSidWl1b)M_m5q?Q|s z0At`^q4am-2+6KKUv`w=c%&)$%ePr|+u3X}wBu?2L(fSG83M`S5vGkd7@5l1c`<=Qbxs7P;cc?z3vGWK*h+WD4sxFy~ zZ*#C?=Zv{H5ekLaC>Ow3E5p1PPM#UXWzHJVin+@K9)g~f9yb^6?Bpz^?D={q2l3lNm}OE5xF z)B+1iy6}6L18cb4|F8;19!R(LX*&!mGOd~sDVQ`lov^BWul~vA)%3NV>7HSW-`G^* zN9OQZ3#reRD4LF;nzta#--Wx5Hn6k6V6FZP~Pega76upW#)9Y)D24v?%; zi-^7=qb0mXna6%GJaZH@@$liUn0EYMpIZJemcnZE7#?&x0)gmny3wg(bLAu*0R01pyi^sSrdUPX4+UCJ|4rkN;CRX z1pGEzbR_8s5^1dz_6(x;C2EZ^e9c5AoA8U#BvB<|_Hc!(KqMbq)J@epwGnT25Z(Xk z-gx3pF;mfr$a{HJbPSgc6DJCEb%14sQr~(fPPL0BuXu1~b(6FO8T0IZoogQQuuV3y zpr^6J&<6>z65#2r`*q|U&E`ReG}8dMg|J})fjA*(<6%a*EN5J1ip409_j8o9t@eVl z7L#{V=g!hc9S!FO5cX`8o^@CzzUcK(^~%ewMwO7FANnJaJIuJ(*!xjX3gn4{=$sC8 zV3z&{xa%BpTpY<8uM!52smg&WFPxD~wVykVQ0u*QssFp=_dvhd)5D!>@A-uCXMgGH ze2r`Ou#{Xwz@y_|mfHlI?4DUszqF119P*Hg#p?Y>|6M%q#utjE*P)9uD0QAjZ7P>ACG~TyZF90^OExTNAeb5NUygkqaW@nUc&k7Ybd2TU5#{6tg zg0@g5HZ3CCZ{IMkN+U-#BWgtpJ3XgKRfSA?#aAa$g%(Dc9s>6gdcR5}Ios72#nlC> zt?!H9FXkN6CfaKwFqT+w|cD%LSzaj{1B()}S?U9AtjXtj`imOlP`Xrh1w@ zZUk$^rw~!kM@r-Kyd%y8i_KS$1O67c(-hG>Ao}v*>87Evk(@*i`pZ~fChm$%k@yoqD%nJ`E%-se zpMoiwI4W)BX)|?%_89M|So~&9n`_fDO#jEuwYmQX&$V^6|8HwCvWe}OU$Y*~%4|Dd zO!Qd0BK>>u1jGw)Ceo7{uzz~*&^!2bGLK53^=;29%GBfIOCteyJSQc(>f(>K5Bfce z%Gs@caO!IZ3Hecyx6=k8O|;E!li`$)k-qssv{8xY%89|L67yopf3#)(E|mR;e*8Zg zG=I0ZX|p`UW{b?L~Tg`JV#TaUB~ zenyO~82zaUE!=5-@yv5sS?dbB&$5b90iB)Mz@kp1lt#Z9R~UYWTcjClsQCTfvD%$M z+`XgI4%I8i`v((_b|a%RzC9i?0y2O6PqaK4VqSc<963{U_MysyW6q4WY_&7vGPexV zw4%!kFz2|M&{64~1{tB_~q`_>4J zAm$f|lVX8dyeLjLdfK!Bj^%7|_tOZCpnT$yb2C^puh@a#y2?xf>K<7@OcC0A?p?UY zFpq$mqKUG`LYpvizekI{U`|qg@M7v0?8O`gbL1RN_D5#iY5C&Pbr`~L!P{3AxffPm zA>n&Jl(1v}4ILmRK*n6Y5-uCSF*#^RA9b1LoFWo)ZSmHc$${ea>^C8D-x?K*jvv%~ z`?ddOi^eV%%d!9Nr6d)L%q6-yWn+!m7i_x>Qonb8D0&6N%}H|lrW-tDS~!@06bkwr zSPxB^dt^(wWol1%pFtI!hGCLOE2O!wc4FHm z5TA&gh3*!94t&j5QN)}|!rs(le4$K@DWyO#MV;?fIKZ8*Qn=7<++t#HCvD!7E-vG*_$^S3| zbOY{tCrFLIRa|UD7{FZIW8~g3%G-kJr;winGM%X`?u`qqI?O|JlEpC1D|mrBJI`E= ze*IK5MoiOm$cf{BKQo*u8eP)8ofW%i&F%XzfQ+*)ht3h8W+n$)1i^dcU5uh*f4cdxlGtm^SW` zKedELbiA;M;O=7*3XLzA=W_ltyIhgUp1@cwLTb+L9;L^@EYN$JY;{)HUVdomXc$s{ zK#t3v2M^3fAp{M#U4)|8fu2K;eRT&sRMEdcUirp6X?)1lvKwggei}R1C#4Og7CsEL zZ!=exjm@0f&}$4yWMNaOY@iOUE_yLd!rTzMjA{6OOs>#I7m2O~tSVnG;8n6yb`J2N zWUs`ghImjrXQx>X;jBvQf#kkBYVab9{-6Yl4|!T0iLbX8r8efJa5Fp;Gy-^8n6FEi z$gF4w-N-yfv6u&UUiD)_BROAZ12Ja_%i&c(0y9+^%#62X=k=Db&L}+^&2TL=<+vd%#?Hgx z2YD-RUr`9M7toa$*l@7-9=Y}X_U_pvru<~DIZHR#<^)3V5>>E3QF^*M?bNYa*u=&ThJ_(vB01u1xu`2PBlW@%On2kU&zr1L4K_8p zJDV>P-g_ydZVNwW=Ot-MR6XCp#m&SA#=CXhY1yp~eD>6fDiqGkn85?8n_<2S*YIf` zhWDCE05zzz}ac-@ES1$g;uhSq7v5q4NBF`8K5k}Xp`z>=9ROJ8JS zth82PM~f998BAcg3#sK}Y)9YgmhbBedt&=Rjno%rjR8mOY4hbtw?@@P`kG}t-yEx; zPMRn^P?{gxsU|NBnWfD~n=4n2Wu;z<+`LW2%M^eqKSu5xpZU6~K8v+^xVEr5nZETk zYzH>~_ivT&=~k+5nDmNtDkH>R1M8n$D$pBX@7z9b%8R{ts#&F0`(Om^_$tK<9be*D z*NZ$#WW43LajbZfTJYI~8+0Q;O*dqLRR+uc7?NqsbdM3Zby(@hVrYo(RRuFoH!;kp z#x43FSLs4bfVkO|OvWysNhSQ{%?diArAdOPY0LN^#^dhdC%>AC_vAZgm(GZ9;R!Kq zRKjw{yP=x0;btid^G1T=J4JNIIF+=eEc2R2iKV`IiSgRKnY-^ zAHI!+-^bqW0V%9gc_z*^)&({RJ*|R%*r;3|?;kV=m(R@B=nt-N{rZrLu7u zN8UEJp*b*}H8C#Wv24E?^IL;7$fy$(d_Mk5&T-ckCGfiB;xZGvTqHfTf+zV@Gnimt zo!|1R3L(4i=la;f{x3W1g3;N!0f#v{Ch-?A9io)|+n}6a>#I~D|CV+qdLbj4n2hy& z$QVK1Ji(rAcm2L@8N59=mVpBFELe9BPILmQ!y07ay+w@fALpy-(Wsxf2%{B-=>ro! zdd&RFUCsE)cv3Kak=YOzDXdLQ2$Qz1uBzhBNorqUA--tKcH8#c*op30;y{OhzLJ?< zWMM2HdU31`axM&CzDfDoVrM~zlgidl5iAU{VH8E@i-P(KY#tbzzaKR zSBiaJ?N>YmU+VI7a=| z#L*P1Nt61D)~EYzxoTI#^lgNWjq~Sz{jgZb6gexU`cgR$Fc5I!D_%*G?6vg2c&*cBUt50Lst^B{O-~ac$&;Pcs@RWXKCXM2W zUf!;L%tGs=o<=6Y|Nr`(>0jC(4OGs**YAIQmNIth)nUyZ_wFus#--(cYPMYTZ49}f zBjfoKl}to}87kn}3klK}C4$NbX>k0Pp4>~%x2Qvcvho{d;X|K5?L9QF%%Ap;o1b`n zMAkapEsYD3)DAeaA6$;8_KfweTSc9#`jgG{-r)9%_t~Z$#tZw2x@H1Osl7HSXOXd& z52A!Y)3xh(oA~GMOfxWr75%p#*cMMw(-7p}IiKjU@sg_~v^@^ld!!T-9e}tC!ZSwN zPm8>6%T=QrHBiYd4O{c9GCZn~tr{V;OFF*MoVRJNT?TwQx;?J{>AlSZ=iOh!hUeW0 zS?S6HEV__RvbXGhhWty0u81Yo=Zfq~jRh z&M;A6Iu@pcJd8DRH=uwC`j?opRB?(L--4ZZlb3ReW&yYu+n&70Egs1;2j`CAU_5hl z)Pdp6yMHqs#jbdyNcM1XEhbVbDRojoNwgsd>ME=yD1MVZKn5%q4DHJwwUT{~$^hhT zeHR@?1oJ5;UC*qGFLdmFkDQeXVr{w6PX2bA+x2A;IdfcW?YgKqi{YOjh&tMuM4Rf_q#sigj~xTsdUEk+!IF!y2>#4A^vboE zDs*Q>(86#HJV$6n96bmrU|qvQ(gW+&I(HnYlHlX4yT2< zQKO1d{ICI&J@v*~9F3imY+J#~*fE0P&q<|evq)O>y!SFNx_T-b$MTSQArU;L=rH6u+V|LGbd5Dd%S%lyleS8hdbDZ(4mgOVI7OQsI1>HYA}J z`|5LO^-r=n`%ZKL*jL3xGy&6&;Kyuo|9{lIcQ738`}b>YQFisVdauztQC9CIL3CCP zAzBC#Wv$*tw1~uN5haL7B8XjG2o^y|(L<2vvHG+5e4caWJI|Rp^Lyqzb7p@3@0izK zbKC2_ukwBibQ_6t`19@BcoFV)gSNAt#uM4;5zj@U$?_|6#}0B?J-U*(F<9>FtP4;~ z9H9>rrxmbHY$rpG>sbxOIb5XjkQIm(Y~JzWjc}j{B+0Ongp`9&1&t8H|1@jz4eBLo2LCNplT7+nSfLcrHs$(l~2T!ZIDKA zO^GU9FgCqwAJYZM$JhycWXI; z_gm_0%5S9m^A|V}O%_0&a7k8d)Te6k!Zxr!M_)$)k)83*INQQQ<@5Q4bT<`!l?!{5 zlGyzjF1hS8W*_n{5T=Xpak-xTgC-M%dpju^`755+)xerG?$P?OLvu0Xc61$M3;iUFu z;f*ZefX?uPMJL^;CO7<3FDG>@<&dV1Mn*ygv?zXp)$GmXOzlEZRdhht?2m(L&*Fda{V1RoMSXd0Gqs9 z)dLMPNMb>hzlAXkJPMAqo7-DwWfaS(9T~tpc_I}>w@+)^N$hqok^JaXlO)@IEWLZH zH-F)wTMlgvgY!D$ZP^^}?|Mt~h>8luoiX+{dLE?12gJjp`E?U?%=12?U)>nJzGI-U+-!Z{c=1H^o^f$ zeU(xQAy&bN9x_}$)$_??PkMeA9`|~joSPVo1~XDzXa-2~-uXvl>0e=m|4YH}|MsX> z`rD&qm;1Lz2`T-zK4y3MpZOKZyko=2*Ua;StBp^zYh0Cw|Lv_`UlaIdCOSLQ35oiV zjZz29KiG#$lE^&-@muPH;_*`NQDHo%LR3;vo7HkW-R7VJ1eGfF@Fl0A#_L6SK_2xo zu-Rexe8Wn^`nUaj<;c5F)cEHvLFH-bJRcPjN5F{9WfA-c+?XV_?1^R21GT8BqDb-} ztetaNd{5*(_>NL<8Zqv0>Y3zlw?`d}R@r@Ays2bU*}^oqz$cI)Nk0T2m1*lzFvDVe(|H?Ia6Ht#i{g&AemM)Nh^r0*pek~=k<#WE7q1*2Kc z#>dDZWOBIs;*swkcX>f*vQOA@Qv2n(Z5TcywUqqhry`EKlzQS~zx-Syva@<^7aqob zewp7;k6j)hdo@RXT@k%5FO*3C%}T5HBTXiVk*Qo$cXnv4@!-H1GLcOK{P`_#{osBav!{~`foOBG6S!c zj3XltrF9DT!a++lh;L~O(x;xR!EgU+d9&U88qtb`UffR5&EVc;0CH$aH*`<9mG&~C zn&bKVy5o3m8EK~DWm)vZ9$0$vYvIm3)u~TWxjpBVoN-|^2oXcjwKIS5Cg%z~u{D|1 z5o)bzIkt+oR)qErI$Jg%Fv>dtqK0H>I>u1eV{%jHjP9H5$TF^sTQiMCf|)?Ax|g9j z0!i8l%j-q3U@00rM7t~1PpmdRt_^Cy*$Yrza zJq6)Ij~~17uHI9nDfw&=e@xlaahqjId?ZSX%so?ad{1)ZvZIa$t-<_Nqx*BpMO=}` zqGpL(-n-QVW!;Y0VZ6-Vc9dXI^wTk(%e1UG*&Jmc&Ii=h%qH2PU!KzBFR*)#xJ1f? z7)$r^uW>GSq&rW)_KbSrG>yqF7=ITP26U_7>B@{FvUA8PXrY>X;Y|~<^}nL@(X0YZ z&0R03F3f@mSw5QFcy#LEJ}urYPl>IB{K{ODwNxlXTD65c={a4s%4@=Hje43RgZ`&6 z6qJu3G%O#DdbΎqHe;<5m1Ew=zAQJPM61f&SmX|^xPaNT9u?9&4DIUhZIm}fY~ zS<8q!|FyHP7jabe33eEklfX20M<@33lUz%4^%Ift#?`tg=BHV8Enn)5^34McT#<#l zON-u?{2!#@^AtpO&aF{Kw_x1(I{CA9upT?ya)Bc>J6`!1IwgAdIMpbwYITYpI+eCD z51UOYOP>B&G~_iu=2Tora6l`Q$od~Os7O4%pfA6Yq1HqKQ%h0>qW+v*iMCrUeQfGz zv5lFs9V+%s*(OZbQQCWfK%cWEpoo6^gho54CH8YyrlE3=E%GzvNjqwat7QZWiUdNz+T+8V41 zmjvo4tqo*&mr9fD7NJaeSwl|1VY9DZ@wUE(n(8%ziI!*+1WUySTQ@p9S{_7k7^H(uV2Bza z^m`=iujGHA>_*`+0FlLI@jkVD0Ux-+tewqc3_T*};C?uh-qHhff&GMCcyWrz^sqcy zkpOBv?5XR!2Vf~UIf0fRR)m_z_?ynqjB+TP&5B+5d5PxJ*i!maqkT?yJ{@?bjQn(Y zj>tP$imlB18AZRJUF0waM1JJp+*|PY8+Uq9^LVW9{g;i21HlAp5QhEF+{AiRgggjW zPJyXHu*`#Rn3HmG9e}x{>=afOce=-;LR*h|9xQF3Z;YQ=7`wE%g?qiZw9`c+>b&1+ zm!5k#ksq0Zk=T4!?JF~dTf7|P41Xx0H$_1eYbB8JbQ<;|xEm#&dtHS}Ffw?ghwW1w zxt8D0x0WKLyA0V)Op0uvAS7G^JgGy|LB3F3aKn|rJLF7~pLj$#p_UK8h>-WPE7B$Z z;3l#&U~6;ud@fvtAIA?p;$TSmtqMidbNZF;nYwVH@bbWR2!mtAjo!HUC z22lLfW9pxxxJfjNn73EwE6 ziRD?k2wTj6<121nPinT)%p1h>&eSZmDltJ2ZH*~Uv=e^>tSghIC#i>eGA|H}gZDFZ ze7FNCc^FlngfDr5KovXe-tzX+dPtfUmgQ#v4s0DOwd?}IluG#&ASDrXLy-&smwax? z2IfE?Fj#Clght}F)z%d}23y!2W-LV#SQe=`Wk>qfDZyG)N_NE8 z0m0(B<`B<1qmPpIj$1Ka(QxrgQ{kX|#?a=wD{IweLSMX_tENVV`MzQW3PV^fnldVQ z0=p+iX^jmlU}PNG94VG|gsd)(wj5?ok{h~FI3H-gxfbH*$AAP?S%m50v%p`RXU(KQ zJ+inn`XOIH#nS`B$wr|yozp8rJem}_ZpWEKc9uNplDlLPZ968M#I5kp5~NVf_e)m9 zp_>r~CC(l3jcs8^g6$&-Me>kbnU2aCtwY!fGox&dv6f5*BoU@ey7`E1`GU6SCA5PR z&`7JFM3zlcDlPSZ!s97hzxser9qpsbaq41WknWFB0)K-%GiHN*3E8%+UyL1fI=x*O zJ815=lWBiP+xL5rR}_7xYjyWMh0m_BLy1 zPh1J!O+41p-wM=~jmPyRW-ed?54uVEpX!cH6tfl1Trg!7)Ee}olaA$XAA68_sDxp= zr{AP$vgAn=jQlDM>#?Sh412YGk)Bug@S}W=%!o|>bl&$fiobn6R@}IvtIs13=GW2v z$1`W~p8eO9#`RHWW^fq~KGJWSwU14PkHb0vizDePO%CF05Hf(i@lV;Z!%DXeIw|aM6U)!}`C67R~ zSR97JSE?1omM1nY;yAe)h$Btks}wz4;+SMFr~D32>KR!$RJLHkN0DE|4(<4t+sWE$ zu^6KfdToiA4&m@o59&%mXCk|*^#AUChIDj|XL*?=#vSIU{1R;_+A>|D+^SLQ70g8x zxr%jB&b}P1^NR++Myc{y5 zy-dE$)9pHxDn52iWX_H7Fdd4$h)#Y*TyU?|G`O?4ytO2p(tQf4Py7>3*h}yAu za;IL9c%Nba=RQ;S?|mkD{y*&`Z+_=7WMSbnJ}{U#}>o#cw3{@IJHa4u5;- ztU3Si6J1)}R|Y4CYCB!aXjiQ!@76ED&EgUA6c8$CzdnVYQ^aES(tef8ip-YFH&QYZ zDmu0BGc|A%^edOoWPEam_eZ7pDg0mE9}d2U!!@y(B;FwBWOq@Aqqzymcsvu?qOy3` z6LBbY#pXcH{%?RjB7WH|PwpF0DHf2X@w%=K(DGhw;S5RLGr7Jlt`QaZlj6=qpBp`t z;>Zb89J_a)sJ&*)^xpHZ`uzbCm%y@tMTcb3gjIb~OkeI<2E5zN*SA7jNEK@F+^4CB zF{pfGpH5Ut@9-o@ApXQfjAjFWJp|NAGD+I~^u!0miNh{;vZUuTqTm=s(w&0_Y1e+c zzdakyu1~5gDb6_4B5CIXC{2%iE7>9^ByKoV7v6e>TG2Jha^wy8+!G97vazYH=#+kM zb1S*GD}quXa5GJ@X0q{KY%jEMOF|yYW(`}2lX*igO~4@*)X_-7Zs-=02NUoi9G`Rz zRuI3%IA;_KSAZ<8Y6*6nXD3L&C!DSf-dMp7U_DK(ZC1jjN5AWigBF_Hxu~HN_`?&*UbT(+{gt* z`bANI2cS@^B$`w!=boq59og1S39#~oTjc#v3B*IYDNpy;{j@0iDGFP(@pQhhU65#8 zAk}d#_xSBc;;x%4FLnEM)PS7Bmw7K(nb1cMR^hnl=Bz>}*(JIt81`{K<9Eb%0j@I$ zQ4+&7$(OAAw@1mHo>syQV=NMY3AjD6MG5!o(2nJioI^DDf`}so8XaLpEL8ouI*_1H z6Lj_B>A=1c%cE;Pc$cnh5T)wrx-1F6Haq{Gp#<65HG%;L)a)j>L=<5`BPq3Rw*Yn5 z-_GgwGr5!II;VK@2kW>W`LxqYf4V*+rlJCgMK9{ zyDiqT#_R#h;#->FKO8f`4T?fxyC1?PP9(;1M(lXWrG{zv=JAeXD?{WWoP=VMr#^(w zVK|z)t7S1?6VU87_ri1on~Cgn3XN#v7o_QJN8^r*)xu2Qt97lc5<(Dp9 z)3&n}U)fD()J&!*aQbXYJo07^6P-Xyib!*?v*2Hp8P59#S3Lx>bg>91okcrMVp+hKhVno29W6@_`De*xH8dW&5M zOcb0gcr-}8{bShVl2DeVbg8Xt-69|VRpV#WlCD*oF3S&Bw*trRG={&Q6@g4VF^<-H zetAJY%4g#a+H;18wJx6hCOr2&RZdwJXkFed$R6dJ)cF<7ezuaJ9X`v8HGC^JWt#$|=!lO@%%F2D81s z5Y6bFFzo*E2NmHpH3p)j#os+4V!@!^lbBZ({?^~c2mYN)|wZG&8DAi^&Wl!W%q5EOQgm=6hEgOC+g-eY)Hf~p=T7qA1n91&X4Sk(;1s#sd zw;B8p`1ES$n!_J+T|&U0D534g@1sf{ISE%=7)gP>EN)Euua<|oM~dnmj;fUQ%$f5L zL}Z2yfB=+-_8icJ>X=bgexN6J(6`F1aiyi>^=KOvee84K?maEAH8JkY+0TFt;Sry( zuFRC$kuPo)_!~!0XH$)`d0~H6PonExZeNTG4xj1tu3oI95cq|vd=m?YaTS7a41w>< zv#c2v#lkP4zuLT0&>=RFc_hpl89hB{yw<@krB7dl>uW0VCxp=cmwSXobd$I&D$L#@ z&UTNs|3HHiPy3mg{vif|FG`X_Aw2}k3kaL0%S!zTbM9fbh;YrtbsRZfaQS>uE`tdJ z^KN8Xhjaunini)ICtvnh2mj4YEJ4pDOA7T3*upRwlVAK68Zskvet}4lBu+uAa4rPD z^s*$^%{~eRHP;E=X<3Go4(P}1?`0R504>EGt9b$x)W!N;|h`R5tmxO zB_pB8hPC#+sY}ozI9i0UKaF&YaAhw3UC5Mgol@ZqmI(Uc#quU5QV~wip@*2P0#c)R zih{;&Mp7Ovj2T=ArUGKf;P>eE`yP_TDNMLKaVxF{RU|(SDw{@0K`ecFVx=Aa_T=Hf z?k#LjQ#dCljD?g0FO*_PBRxE>LIQAl@od)lf;O`t3Kaa{Wsr+n7a=WR2kOF*lSoOU zMV)iIl^pl7BS#U!g+%Gs)%ez)rc^|KGqIqnthG+nI-9QBUU(HYU0Y|)M7fa`yesV@ z6&BD&Uqhvgl=>r*b@SF`yWasF1y7MFnyg4gXOXf$hCq>gz=l#{-??rbC`V#sIl@Q- zNgU5{ZP5PELu~v$jf7g+52~J+ev_gxFfb>wv$pUak&qNcqe^7&h|_u`RPDodC+Cw* zw6c>5W_>8`Ealo|Dj;t4CEjCxocT^(nwS>4^)rCpP zg8?x=t+7c`z~hKJOt>u#43(kuq)^A=f|vYk4C9uO_$kX16<50arQAHGcr97ozVZc)2~Y53xb%MMyWKU`n7t!-++Gxr!J2 zDGkZhM0PgnC-cpF4!$uIYM+!ljjF0PLI+;TDyVDjfv&j9)VY#Bva=)>ep=$$q-cdw zpe8Z$wa`Rl*vErwoMsWftbOHhKQ~Bp5aT^pEor^I#Kj+u-@4+q!U&ONqmJKgqtfc& z|5hJK@YD7nN~em0e{h4vB-r3q+j`BjY@R39u+Pa8ry`a(qzFr9ChAdqs%OX5)==J{ zOLXevgF6Yl7hF`39mIkJQ-=t3Qm-#v0Pp1e<}ZZLTUsJScJ@Ou!2U=TVq@Y!_h&F?@Su-aA^4g;d;G1tIFmmsW8m;y)Tr#c_sex%i3@F@@lXJ2$mkW+dMsVZ&3qM=M@Hn#Nj-dwbNqI)Q*sw zYBe*Kg-tsbWe&}2J@27<@P#ppfw*AYGb&{p_|1~&J-nWw8>YBXi`G$@Oy}H z*-xC!{#Ixw_X`8Z0bL5xb8Ctoa}WS2h+Ob7*_N_&Q$IMn!YY~LrA!L}0}==<7hO%x z4*K^m7X!+MeR$-RcNS&U^@o@uaT_n1`o3DaK;1TvW;z|nD)GlgolJl01f1DEWU#Wt zI71XSi%(&uiknL1;oDMbioN(1?sO2T~X`c_L8VMX)Ir$)=2aoNaBFQHM9zSmN zZQwZr+9%In%rWK}b-up;Yhdv5s?|p#I~U6=LZZ4fOw)2z;=r3YLz?&v>ITNeQ8x-y zDBPeDLz5139hiqw-1Fc4!|h+U&juS2PUyJ3M3Jpw@&X~V8+3&yNB7gz(3R0;!H8Ym z#I-)W7$N2mCR=l{_nk#71IkRMlM{oymAQCYjNMJ}JzPvQ^uY!3=d!`TiJ$Vbg-K20 z*0iRPJ-=5t0rT1HYIv`%9!pd7-7RQlU;&1N*??`x0qn?~;L~M_U84|-4$0cIa4U9e zA+mGt_!QvI)EBPC8I++q7LJkzSEhspYZEUQo`t0KJ?y{6yX@9JdK=FUDuT)4wAfMK zcFwxu?r6x$Wu)%|)kCZ`{A@`{1tB+S>-0VjUG8+rAh%z=dpdNh4A02{E-GFx+=ka zmNafK;-CnIY&8H|vy?ux6QYU`$Iy{CQ6?q9N?h3kiR`r3Ne3lq9xr=t{tP8RcJ^Kt z#_^DKZ)>U!i0pK;P_0`)fP=`9Mho*@-MWZ5UB?IB)O`Zil;@L5d@k{{KW%RV zhfzx+@>fCasYseCohx=rMn?*d%uMH@qa2E4x>SSLYwQ4ON*P;xIs)t1{^|G@kWSb2 zB=BR_NsB4nXzosqZu5*$k*otMvm9@5@!Pi$uCJG)0)_P3r)bVvJ&Tg`wQrhG`jKn3 z8;`2m6*r4(1{Q}s$w{ZbP0ZMJd0oI?p@l}j`Bm95l&5};Z7tuZPmcRrkEE}6BLpRR zdcG*hl=_g`t`-oNOxrQr#QGfI#QKKTI_*pZFL9ArL^MhhJa7I6+)2a$Y6RrIVL+j+ z(Ut)y=0cPUyg3u%B{;GmC(`)L@GXHSD~$@EtOH~vqwX?>DWj}WOt|sJep+?aLZBM0 zp-g~0GtoWSQt2^baTVHrpqdpFx8ugcv%8zlss3J}&)!TrY3csXTiL@O?>S?X&xk&O zt1jL-OEe^>%Q37X$?+ePgOI`(cNxEAn7B3WY$H7q@&N8{ z6Mq)T9kHQL&OSbypQhWM)JHOcw?NyIO$UWJg zQ{;^-VN^f7jLqDwC)ImQrOQUiW?=)Y*1DR;JL{`=A$6Ujvc}wFsouU{!aPe=O@sMy z(-@JRaZ)R#k~0-nht zJwx&k_h%g$p!>t?KE2q>NT34 zq@r>p;nVGhKycja9aUgi3ol#IjU#`9yZ6_^Eg}RdK(mv7_a{Kz`udlhH(f_e`6RO>19(>`%PR5zC<#;Ie87*7IHE~PESM;jgFbucNu!u+qx9|g@_1MuKlr9*aZ1l4`>REH(2D!` zHIDfsi8P7vtJO=-waDLzdg5tu0d%GXxns(%HYhSve`>f( zi_(_kd%h*Lu>4_i_J$*cS+nv0|D^=-Dy3LDQ*PajqxozXx*s}>EDS-sh~du{LYS~D z{h9cexW54rM6HmVDJ59ez*tiSnsR*1#V8@#J;BnJJe=?^y|v-_!B!mR#`qQrK>?P= zIGns`*26}RRA(L4Y<7i9ks)!A*`Im=_d$L)-8MaXC~?LRz~%dAn}V;wxGHUv+_KDW z)j5Ana}d-&cUcpbqi-L4Kk)6oQN~Ux{&r`-y`m4gLB1?W-dqL|N6QP8kqV0%{a4#&vv+*tH_mF92E zL{P0H7fLB%5WzehQa6O9EHgtUx}0P^In1#3*-nqGz3k2>w2QN0OpxZ?1bfVCuEE?J z%GK28b)OD-zo>k9eBtWKrbl0Xr!VoEY_M@=>em*2!!|IO`ZoE4RNe~5H|igp-UPYv z>sEY@UhKhjEVIWNS{Y=Dlp#p2=O-J!{S#&j&<2#j1#gPG#5STD$gTK5oxI4d&F=5ma}J*XEcqhu5P6b-p#4P;}Js z!L?;WA=f|~7k<`~!|%*g;176Sr3{ZJRhRE7JI}agh2KbfW1C?<)RSGYvJf0?zOs1l ztB@(*oebFx&9}>2Q)3eMdc=2)GiVLL=M1+^*BO|YaZ|0dy_x>}>sjVCk=>!j$0d z3OW+gyF<^v8(T!`=;~#hoa;nVYQpmrV zx7zc@GFIO|Mdl{0hV4Mr;4Q-h5U_x0{kI~CFcsDf%~bd0tN9yWGsdn=I1H{`U7A;2 zGfqi6c_p;Yey8o}tIskcS@t*Na#7{Eh`HnA&QSy?$(t8)d;jQ*uboxHWX&7WH0J%FI(QTwp`k98`#kQc%j)xfP1Ny;}e0*Yku&4xg`# z$ee!TOf>q|R9DhGiC>Ozq4}{kC_A7g`H4w^>dup?KQ7_wB_54^Z+?H$*x;Xz2#hBnDg zz3mco)%o(J@XZIwF^fg+u*G%z++Sz<4ZqhWmy=#O*iFRUFS>{=xnuszn%DAc+M2>> zKt;6w7<-AKm6!WV63{n^cWoup)$#~hK(uKwk)3hj@Bc10>LY+eDd$a^YFaWc;jPwTi;I6|lb?GrEE+cJeF9+A8`G z)gZ?dSMVmgwp!gVV3NUlAB-KqaAvvPVfd@KCm-NL)XuKd=&-=7D$@HYnp&GBV{mYUw#39wL7XvZNj zq1v1b@ZSyD!!}+)$m>gbPS3SwPItI0_+N|3TZl;>#Bf$5f85%g54lu85p7IC?Ff*Y zZ=dS9jU67OY(0J$*TY5f4ILmBd2!kA!F*Qgh!GZD?ieAmGY=ew{NSVS-|haE8A6c? zXCr|+XqE82_1jaymIerf9JB5P-!PKj2oLS={La-YRt|C!U{km7l)0B3-S8q50Zr}P zd^4tZ6@}Kw08m|Sv`{#Pea#PpdkHT&%KC8s^{+ufae4in!!3fGMqut^f z+}QCS#}Tg_w49uK@myEb`c9|th0;z#P0Ig-f#=}wF}SPhSKh6K&ao2_q6GIm19ouB z_=~5R`nr4OmN^mGS#G{9<+&rsIQ>K-5*v5rC%^w4<52l<(GWJH(PDB*i%_DGj_7#b zBemI*TP^OC*C4KIqr+D-d?`#r4?o|&VqURz#<-k&-=grK<=IT9e0llF{9-AExn_n4 zPEnqpp^zdefpIVFOQ!sOobHD~y+!e5l5fCe)_deZ{1(vC!~ljed9nx_Mx|N{j`g>g z(kZ&1kBhPLBnG1Ar5j&wv{8(#uCMiH)|mZbw*?5?DZ6XJnKSw9d4(Nueg*&!09k_E z>s3Z#S1WUb43Fmsw?;W$yyqPI;k#DV#9#~lClErY&j658*29+*fg7C{;h2 zc0HrJE=Tlwzst{>(D&>4l5dU{Sam2V?H^WLxE=3`Y^LA1?RR8m2=DBhVU`ll>8`k7 z{*?xgFTlMwxEjL4E0*|z+PaIAN#u2t*=&%zwTPCR_3?Eyk{p*bf1;8H!~5@f1v^v* zQ7bdwLbq_C-`@ZBv0*J`J&zES=}u&4rL`e{z!1=FUia0@zxE`rz0ykH*UC#z@#A%_mqv77L_g5+`jIM_xISO)wxv|h-a2GJ=}Lo?eCv4W z`B6SU>ZnCuH8buw?H(p3;g9#GRo*x*vp#)9Pg>x8*n6W|`NA{mzK%Sg}>rbE<{WzHG>ksEU;&kLf2-}EHDSK-VkF{(;A z($Zz(Zg%IG6S_W4SHJn5hKPi8eGkDq7CUv(c+|Da z8W*G1+GT)Q=l#>M(yQgapvj7%duPfB!Q1zxYfTLRucF;NxV8#f}&Q&Vg>2M%@SZ$H*Ah|BI_UrF% z7F(@o{_%itY)?QSTFaEqpeDS@fFsaEv*_;J0rw`l{ReFxvQ=vf!qr?D9~bK(M1k?B zG?qT0wHjD=qMU#_V$t0L!xIn*A?xBd>4v6JqNqpm_m+C$@|@DWN`wf!bcc%kg3G4K zTf#7oM8?V}ex20`cw!jsQc=l-N;VisUM^da6Q*yK=J{Kr1APsi0tglNXkonr3P{kT#JT4|PVzy$ z??d$%E3=vL&0ma@F&}mg#jc~lAZ^N=nvb%u#l)x&_KKI3p)eYny^qSttqwGzv7`=U zLEs$U?gLPLBEm8%YCikj4hM^++ENi0%M&|zmS!7xAy<0^LPNj69c2TPY9Kl*XJaRO zi27%g(x9BKJD6}I)g8l7D4h9x=a@QCmZm9(JpKUV;WglM{lz1I{^jn&@t`oqcuS{J z0N$U?>F?|hhk;f}t1`@={RmCQ04AF2$;0u=ye&#GME5d67{}vtK|~UDl-UzYxN6*C zD-Sd2j;$^`c1C$!iDVDx#N$bL?kfJNJ>UFjlH;BevaqG zbRm-LTHeJ)`^`+zgaAE)E}2yB#KXv?fW(EBrWoOp&v>`5emUUZE01uOXumc9PtkJ^ zlC7eo%iKmGHMypI7LC(Mg5P!awq;1sWtSu$nk2U!1c{LI%$GmvVtOz*N(92T0tilFZ)on=?7g>{g(6Jz(;gclU3_4@tkO&e4SLB}jE$2&8FE<~$J`xAYgY0l(6HWQosGmVJs9O;6Wk<8W=L9eB~jX902HR8Cl`U{57BZ%zWLKq{N zCk)F=>6cwv@GBLIPzJgvBj+Dam$YUf_y?ruI`OWz^CgT+J*SS9Y= z2sLTo#rI&Qgna+^1jXU?B{86Ow-fU3?2mNV{~vkv|B-Te71ZWOPdr`jJhbQEPf3!# zalEkoWbNu|^(Y^({aN-@r{+yM)a)a1iEIS&`O}PWc&ze?|MAjdcVl(i>LB zcdkAE(qKiR;v*LhbtPU?_@UF;SDqf3TQ>p^Yd_317VHI{^NvRGdG4G@C6PQDGR*r) zl}y$jR2;XxHMD?Tj4C~!v;ayc$B!Mcy@|WqLGhH=8pt`bP#1E3RY^NQJVXE>5sblz z3{tkzLZpasr%yq5$hDGsYvW~>w)+j@)y-bO{2dWNu=0-_xgydPsyJ>vn(9g^QTb~M z4Ktro$6B5SgFCk-ZPu~Ti@f?gO+I{CAAN-~BZg}h`l0%?Y?P$bU30w6G^ofyo(;}H z#=*PaJJ>%J6NXSJaqFhNK^8-1lFudNX>k@1`7lG?3CzzX>EkZIP7D)|%^_r~0pVkKEnQL38DjPU_KC{j=0R0VA zJ}=f2L?(5gYUL6{2DS1)?0PIH0n*@wH*px=rf(A3`s|kr1QRaUpt2$Sxdb$EAr4K( zYzAMR&b;__tatp1#o^Oz%|ekq--hXUR53^RUeR4tyw&zTWmguwwyiNyd{ADTLz2^C zcZ;>}sl2()RX`{sxDfNS0t7*q&@wKVAoJFEO0+8S+_&K>br~hGqG5mg+DxePdl8xX zxZSdeJdBJ1%@b5CmswXb_h;!SlO_*LkhB8otyV-a83(!Cz*mih-w5~kTpEfg8@~mC z$UoE6RVD6T$6;;fv7+x>8)65qV6+IXPhiFH6xv|Rh`})c-jKlqiF7#SxYpFX!!R(e zb*6$eTUJMEszWRhXIQ+@4qeLF#i)A1t5!Xc$kSKeT8>-%gFKZwnWjdLQio193nVpM zPCds4XL@#yPOOLVeam7b#z2%Hv6f20d_6lG;$|6yS6*;ErTjf|{^D0ZHru@K)K(R3 zx{?~>Dw&Y${B+Idmh16myMEQhVYl*a*hUBY!rfwWud5O?zF8f571E6U{RsW|8!VTh zDg}>eCXbLF%S$**mh3fVUx`XqAype?X@X7;vV@Zq^>U_aowYxTHXn3Q+nNh^gb9Ck z%VW5lGx&y|tV-H#y@h0>7g0)Hs%)$BVpyWdiHGJwHY-?it-F~M zB~VEM5?oddpi5WxRJh>CV9_L&=>%9#`VP|_d63U~Xmy@im(@yp_lycsDb-BUHLjx3 zHF16{JM*ko#5O|sWHZb@DX$(X8awtArzQ@=rEhd0`Xw!2QA?EEVD1Mu%P;IjIp zQ?|*BZHSBN8UK-(QD;>(_vH5ZH8%&|iJESCwg=Wv)S5~(o=vhgVE3-ysiM5!qAz;# z#2}{g!H3AU7ZIrAk{(UFo6KVP_g2=XEn<FgUX495Y3Jmy1H{;$tzJ-x~~AbUmQj_!dRD(Rl!=%P&*xr)a!Mj;X}Kq>)E z9UIc_?o>z}NyAPeJ8R;`rWjZguOPb&dvqS1>cRT0#%oE2I~s z?!bkpp%&#!nTl~7zFW`#@HbvuQezCcJZRh;H&~ZD1#@7E5Lx86`v?N`zc*m=aTQ=h zzeXF4*Y@14GnXIyno8wb+jrLg0he_lgof&5JGDK^<*Sw{<%g5)m zmt)8Ft4CYAE&DNXBe(R-@J2~Q*qR2NM8V@4`NtQd{AEJ))3SEM$A9nds%rmV@~U!% zLVi?q;~Jf7(dkucO^sldwYbdE-=%AG(2!%f{ami6jr+N4V`Jg zG)MWVObq&aq5HWZIwM52&L1Lng?l$EQW9Sqt#rsAB{He9L!PQj{J@_5-7)y9^YiZ} z<-gLM|LjuYi0{>_f9E4L9RH_2LGZu%b+zv|zf)#nVI z?hTnf1B(YdquL4l?H4+9zzi&pSiMUe+IH;S+rR@Pf*!pfFM4t!0St~|FU9lc(SkFd znO+}mNPc-k&%oDcT2C}txQoWyNSNBf76p%oUc0{fw+7X`>Vbo}gVneA%5N#+{=FINC;oivMs4G5HQy^dCpK$$hhpR|U0t z@SmgCrJwxpMOR+L3C43v^qXwgl{F}5$Kdk@ur(7-25sZ$-1$Yrbyrh#tX69UfW$(l ziSCAE2G`~%MqC$)(=ZAt_{(*wY6w3Atw!fwvz-NAiI8 zp5L;-lV_wTqUocapo{=)C06APT}J|{@SC>_shX~^+4_7a-5 z)PC{m&JW?@`3t^=54D?(l^~kz^hS$myj$Ah8Kx(N3S{Y=GXi9nT(~m4h6&Voh0&zS zLG95YIis~+P_3ogqQ$_8V>vbZ}- z`)}s%n5$RR^`BlzGLNGvq;UwDCv?NzaUqnz<&hO`j7PjWuvRjM1Gs0d5xi^Z+6Gb7 zkGmk>B8od`Y=lqKIGjfWwl^-De)WE>erNNZd{XWE+|M5=DK=^y z)jt%LTGKJ1#32YV%xkx{NX7r5%9V>wN@{dYD5R^HBSu<>aUQGZp*8{#!?$amW+Or19R@e z8@dzgvNVm+$~Pyl7=sBDv9$)`-oc^Roi3rR^L>+0AGSq_+5X`Z>UiT0YoB)!Qq5}X z+-S!xvuk34#O>t0rocAc(S7?}Q*Etca*#B_uklMqfmT6g_HKg6MlT_vie+=bkz9Ju|=g zotf|4|Lo2%)??oD-uHFAuJU~9@>>SvE_@-eGo=bS?D}WUh>pike|g1Kq|!pY)vp78 zy3*BUjpOWcefj7+r{fj<&fn?W@ovqN#R+@n>fxw08BShWAO5Ir2pu1$o)hg(zhv%a z6Xo}D=N$iyG}RWdka?;7b9%>i*)61I6N9VK*NgM+z?kO`o}Q*NzcAS>Y#fa|EroqN zy8qjti->_11c7|5}hD9kxWk;(9!q~>JYyVRkEHq{itU&bw%ADBxGWwW<6r6IVZDz)u#%= zq3A&cdWy%_xVopo`4r)#>(1Kkq)QW~pNkI;9dmfX&LW7-A~3ZKH#KXmnK~gPsn1JI zn|1@&d76(|J!o~&w(s>gh9*t#?upS-)6AVYHaz<%$2@mP>umZ?@5NY($l4-|@1zO) zcpkPjb+#z1yp$dzLT_@os*))C?44#;(*RxQAO~{PXt(yc-ePXCYn(Fsg&&8(M?>%2 z)yENG%W+~Aq9Ug%slc-_&i;O0gL^*0AJ4YWj^~Ti{vP!H1}D<|{%8|PQyR|9Po_-} zCL_oF4Ms#V@-q~xAu~B8sW0LfL~Y^fALQ=rDl6yK`_<_Gb>#dX{sE~c&+#AJljr!) z?a7lVVE<2YvHywt=ARJ3B7|f*gzMdf_o~Rv70{j z-V*1)$5SqplNOcR55Y@ULo^`6EI=NUduahpl$iiN@+0bHf5tRU-68wf?uykjawf=9 z>}3BBt&ewu<}&P2`kcP7WoD?%=AT%_nzqLqn_D4T?Rt`98zHf`8XML*-V%@LE$K+^ zG32?#elx|DF+@47K;hgmmWhg-t9zS?73@IOUB7lefRk*U^qk>fHYoj^!#QKHiz9oE zS$8Fud114&JDyq;iZ8{78`2ejk#ncIFqUxZH%ULyG5_(wKKbkF`5nCQz<&E4@!X4p z4vyEC7-VM!Jopu=1D0hij58AnOOCDrvZypj$jdHSuJOo56I1ZaIEtG%dj<7!>gXLH zd#pwDxr4=;K&Sfdh5xej&2SyV$EUyuz?KVMoyug9v z&vf~B_p$aT$9-g{XQDVE%vYWQ^YH-HKy-N`wn#UClFTX-9{uiv%=IwxJWO%E9kV9lkaGP6S8Pi!w$&-G;q@J~{H@X(U?^5^>gG?? z$O|Fln}?VnKN^5}mc>n?r-*-Syvgg7&d7vRRC1g<+>MRS?L?qvg}>C!?;4o-&wAM} zjkrz(ZR}P3RICOoru9~oKGZIDlxjB*z)MG9pulXvhxt^7fw;qz8+64LGV{=w*ANk= z>_~@ES}4B)=aV#uUhF2^CT4|5+J_t>v2#8DQoS4YU1Kimt&C5}G-+2eF0B6MdZ6U& zwAFg%u&$f1GcLFGi8yKBu!U z>UB|iBS#`2fND9sm9o#^PGYAQ*^!O~C?&f7!vOl82UG3>WIdqM$Ep$?O6KyQ-f_CpOC#%L*1BorMWjn%2CC!!J14NSop%!x+@u= z^RG4#ul!esq=-V}UP5(i?P>pBy<>?4ENX*&M!KcvKA1uF5Q^ zlV_8J8K#GVP{Y@PKb-p>X^%%u#Oq_Ok@5T1xY}!~L2L!=cnBMJa+sWFU|rM&G>^3J z_=jd%$=fXo=6v-z$&DA7dR!Hj1y8!i7*ai|rV3^3pD&>~h+2W($Iul!Xw8MENTa&H zRO!;Ak~EKQqNX#&K@{`lxaUK}c{HvTs{YZ8R|(v;MPlb+6qiMv-iO|Ma;f&E>>WC5 zrNqai!4B1wtjM?4)P|e*Q=pZLKH$B17)u}7E{e>tk%=-IQ6t^hUKj2(wE1xuB0j}X z*Y$$hNYG?jwCo%tJ?L9SbBW6Z?hp2q-U_mf+^~2sR#-Z*b0MT$|B8vf;ovdQ!ilS3 zrP3w5zxc||6nm9e4N?0}xzP5(+%PRrqH>{?CNT%jEouXzcsLBcTsK-Tw|k4qH}`2> z7M1JJ1Cc9d(W)VTcM*9lcz(O@SCIrcFv39ro&@wdcgBIBT=R_vm{KW&s z9cA9SPkF*Whxnsi2Mq(@*qtY^m6M+y;ZqK3}+82A55YzlPP_OUHW!JMs5srcVpHk^kzqhuf-|8U;{W$KUm6OZY zkIZ$pu+tnJNgWq#W(E5`L2p*Mc2ge_y!iee~M1wR7Gl z_hXsi*A93roQE1YiRvu>6yX0>4M^;o75_1D^{+k2-wg7N&%cssN0pMj9vD^Y~Rx?Ykf)noIn%tH*jN{aSKPub!uSR^WAyON?xOvVZM=-L2 zhaQPkZoamx0S6QeHM&$bUzA;><%x^3T|mJ0{B7T~KHd3PyJSIH3pLZ1HV1S|1IcCa z^StD46lCUMtN}v>;J~%RNWu?XpGo0`#Apdl%Wtn*HII+`?W#lavBpGIJKEJW-X-oe zBKweZ-I?+e$}}f$&aDcyhl(L7zZ$tK8id9fPHvx0O)69KSWYw$uIcc8`-v8%%&#|R zKQk-jH60y<1uzb~WH1j%v1`hsJaFhl03=b|LDq~JMdq&Z*b#f>5@lh$H$T%pqn6V7{hK%tTowwAXWF`OMiPY9OQA7O)#OXl{9 zc@cb+aF+ONP1Uf=a3ykCRbOw%duezcGMbW9OeL35-qc8RJNuI4cN^WO)G|*ATDwQK z!I7<3?J0NFur{*rPUfD&B(SEEiX>8rIk+3k^wB9;7Rp#JJ55c{SX7ad1Af!InV8NW z$(qQ5Il}VobD~J>EMCf$m?Ycfm6C9@+UKy82MSg`Jo`H4ffr4CBC$nm%5$% zzO#AP9jQYClyTwev#8pehfAU|Mcz;S2sC79rOWFjP%c$+RR2P#0IKcJ&mW<3gnLp6 zZq&~veI2l0MZ0XG$ak~fev=6#v9p2Z*Hbh2UHhCP6jU~b@>8zt#xL+wwFO(~5i?r!WYfTX;A-EXO>u}&YHP3D(j6C~s}XWorA&XvFEwjSVatg*u@HoHuSuu4 zg-*)+nlp?u4o2jTB#Hf|n@8%k@qvK!Iqc3WNUg$qeYANFRifswoxF~l-bX)3GgoBn zAK$`z?e3bvrS$MEj4waqm+y~hG1Ci^yLC(O8$-?;+)>yD zo-)2vp~FaqObT08{oZ;{gN`w{p2B!oyP}iw3S*aw-yRV@gJ=x%~)p9esav>N?ZQWL9U*gZcS_T)8*f~Jvi)aAukp985C{3_9JA>w#3XC-^ zHEMRROG#~tx$}Wilc4EIhBtDRt=Ty<{CAez;aBgru?@Xh`=cL_)@V>-1{-jZOUZ1#*I4}-vHb!&}=|ZVUv_A&wP9@efEid%-n^F0917nUr^X7DMRf~FwKsi zpuV}L`lu-fC6E16UR`A?MtT4=h3MeQiMnD+sO%KOH> zrklU$czm>$9$R7i&ZxJcZd5A2+yhYdU3{D)lI^>zBl&;7tB`E`y>QJvwt|?@^9a8^ z9{4N*^~Y9C;HUGKR|BTq%J5m2)j_uh$Rp|c&&$F}Q!ymNH#avfLxl%{^xy7sD?bU5 z@Z$P-Tt1R&MXELG+$45$xX`iD$1LgfQaCCOD!k7ja#>$K`<)F?8>H}cW)$EC2RrE< z+1G=V=55O-SnBCxso~ktI{rZ!(P?vNDG;xYB(I1Uf5FlNAT2rUMmtD}tzuufAsAiW zW~(N>d;2S+So3U!J($GKCH1Io*u8`-Pkz@jen!rSR@hII7+aV4nHn?XRu#jJt{}-$ zAKqdM)48BcCC!-2f*q+AD!}i<8o^?j4xV()Htm`44oWmqRhg%u?~!v zWg4L0j*w8ONFzAD+(mzqgMP@Hh;GpV?YYsAC5I$r$Og~b5P3@ICVk7Gw%%qMj1!}eaPh&FtsNX0vr!|2eY-^zFsS^RM8$LSfHeq`&r`A z->EDp$<4e37wM1;x7v>-^3N{GtqqXadG0+`i=#n#Uy=^d<*1D00^ zQeQ8!rp6LB{lIixnIwX*QC|S0Wq%p_Iw@gt=(!0`ow(wf?P2$Mb!4{!6MpMZG41Df zzsT-)2`WZWE25HG{*!QW!z4Ub;g;4zn)s>adqjfGR4IN+My7qzo=&N9-pR%?amS*J8pYC|5d5^nbf=pB+Mw{wY;iS?U^Fu zgUvV+J8!bgSVLeY>8W6?X<(xRuPQn&cP#sO^yxs%=dU6_vpBURKiixr@VR8GFXJ+rrIHzszPC; zmSB-OtAEMN`6W+^1}_t>HtintP_>#*0p7F#HMe_8d zR5TzdF)`)!=Q~9U$JU$m_VodteVE6zLn@94PPh>GtWZji!@)j zuAJ9Kb!2f%r?<;l>Rwq+RKrTCu32w->~AKkqzrLT49}C&S01nYI=UO)v1{CF3KLeT zuytv=;3>|F=H_cFrqd|oyiQo*qF&KYEGjo)kHIwq3{D))Tla#si|60dK*NSMo2BL=8(5 za~a~;%`4q{k;HE?&kBjRB(}en9VH6FA7GNRGdDKpggdGdP&?yY?t2GM@=UguY!4!7 z@UD%`if_)5RVzdTl1uf!vUj^p9#UOQ>u-IswYm7!ZtTn)n+7lijKv^5QS&LApij;1WXm2e7 zMoS8VgO)Uzgy%o51#6N;yNOXksg|KM1}G`(J8{)g9#WXUeGjGrIDopH%Gg7zn9XKe z3`LF-r@o+ZNZp@X(^}>V9s$+uVmgT->9`P3%aYKdcQ-*gPS#F@-?s%AMVHRa$Rmv< zsmJlf*`(%}0V~SSLV4)Zb7i=y;Wg#%xC-fty^dlr)4Rh4b2xTo58F4l!Ia{|j9YBg zS0;I(7vQ1#%=pupn>;$IT>v^N);?N81*S3RLvZ(sGD6Yt_WV{Jm;&SQct!&2jzP6T zpkC2g`74-GewA;=kaPuQ>Ht1j^W`6TL6jIgD7u zUt?PPb00uRE&ZIdi}Im+{OsDRG(O*R3b#|T1DUxs!L-jt%6CWm2?;mN*Hb|YO}^Yf zmym}wY*HA_S!X@~rA3%{4kKr}EZgtLSD4(i7~;+EhNWd*Fa3SKv-H`h&!r98 zD%^-hNYU*`CfieHP|EZ~t}(@$m`uF6FmBJjXpiq1e4#+Z+nhhxb!t3CT*rD+Ff_tz z%)!s9yCFSVDyPV1a#@blUu1 zj~zBD)nZ()1t%X}&dbcyOjpxH3N}d?+~o@=JMVms4+FqY=g|s0DcD0x_hUB+I9wp+ z{g^c2UeE?3B7ji6$^yfkc`ud-mty8>r5DQdA~4gr_Nd=Q>1iL%G_GdV@|$8-|LUNy z;Z!Ljd4A^C0!dQSS5D^aUtHeTe$d{=6bHQ*l@d#&eEuHGC8t0uiBOIw#-RBR}?D^f^Za4kI@xB*T9fv+*`Pu%+Tn@85XJUyQRP?u=g63n}Z}+ zsGzbV)eJIGVk`R19KMgVAG?J9!LH1$ALP3evqy<90|TrzFB_1|KpC|)cTIuJ8BDk1 z0Nt{D%xix&r8%gqG6aI>p4!xV5SL_mV>|oDFf0Atv_0JPXukL(01991mX$(Qr_6Hp_&?TKA}N)jD(H$vJsCO{4x(QP0b}Y=dSXgG93o&P99bum_ zk8I|{{9m_gHS|}ia*+p3=eMN-t_PlbPzO<8doYhM;Pk+n^pV&($uWOejEdUZ4t8Fy zn0(QLvgDGS_cl<5T*IQk9SIgaQ09^JQsMx%Wk?y#M^>68_Q){c<`l z$IAl={(`7-gF7;?k@P=xC;7{CtZDXH?H|>1G{;|u!UPW8*3`ZDDFPSI8p1XYZe1P; zd1sYd?^SsY=)wrC)(4tLO(_1MI<-1Og7dZ)uPd7SybLPB@v+c2pya~7HvE2=FDH%m zf1<&%{-gD_;yY||Sclb;@hXWO0&Cw}`7uph_~E6kQ4TSYNj7ZYxToNx;HDNn6Y^E2 z`Nb-W;5_c0V_NP)Z_G(E)f=%XT;#;En%_@C&5{rCT~XqFz;uz73ya$dG+dYobbQmfx-1pF zaD3pbM>;2GD{V_fpL9V+5`qeCK@#X|rp#6J5o z0da5_1!Cd!{6U@U9iab4Z~LNsiRc%nk;`=clvb*m*Zt$@NRf+bi6)eSS4wa_Ej9~~ z8!H3=;4scB6XNeXRuvZ{uFWXo8bJ=47fge+`kfw@%m`23YqZu8z1oQZotnNZmdqm; ze9^w(3Mk~B`uzqPSo^fgstjpv~qy>c}PMUcCt^&3Ay1q)6 zgYt>%ZyfcwY5&gD@+ov39un7Yentx<90%@xOp6lYBcqy6!wn%CzC=_FIAq9mEs-Bz z5*|%HAoj7L7xF$Vq36o*uJECLp}0OxFQL?6eZ+6DnFKx1N!7d@%xa9jf0X__0*)x? z-^@pwlN5%&zX;u&sM~uK(eg*b*yYsq!ilK`+%2I))pdnYC7G7-^*uEC8PLH)t(nbC z5vzrZYXq^Gvts3zc42Ou4qc5MRA-U3@IJCXmw$1;nOc5zb)j#So5aq)`+^7Dhz?>N zbYchkmD11i<_!Go>yrB8o0P(uMAmn^WKeXVJOoxf07So+DPC zwSq$jf;Cm_t<8;q9e!Ejw(K1)f*Bz}T0Y z7~x=XNt#}M;+3m4-j{0keuFPP-bHnWiDlS6Lmk8IscGZxkJDdBL}fUt$Y%m+fSNq; zb9rU0X_9fw^@9O^NfFiizR>E2^M&1VVzZvf^YPi}Q7LbFX|JhjokF(;&crU&Ea$gd zbG3B3YtqA7I*wow&%U?0LBb`be=aFF<^){joOR22dfh{a_m3^-lnP8s@~H`FY>ULs zL^7)L!$6O5RTU|*Z@&_|Zzp<;2)uc>6G835tz+d!*~3SfQ;}6`zszDXvG;o*TC@#F z*8qRPe9Oi=_2bJmHe(?9lcsIIrpDN?q zr4@6wxUX3(p2A+izDFI)*D@a5{bD<%`r#m0_$P^-xleS;b))_`csd6xru|Afc_g9@ zXuJyho$HMo7Wy;0wZ>t%%2?bAy@Y$2T&ewXC+}Ip<#}wWzIKG$8dn`4ycC(pB;H>- z*UOq3sjZ8kU747>y2RO&P~lNp@@+M)(NAYh8KF4^80$!0|7sREK|HrGy%5%AeqlKU zxRsl3Etj5cm?V~6|ClQN{3usBEOJ4Q&QwuLr}$b2F_v?Ldu3Z_M25J~ivVrJh_^S$ z6Hl@t*A`_uN$m0l|3BpfExGz~VsRZR3EOTO8=d7>N1&sE3j?jD}0)!6Yg|8*f%-PK7flZRbm^>JW+FL+hxILKm zqcj(CgtR+b**oYr|4Uj;Y8BR45?^{!dpoyy?+sJK8nOnKsXiu0p3|D%J`!NHO`9^Zc>TAF=7`sN!J z^An%|Q;ORrkk~okD}qF7H)^3LX_?l@ z7*P&)5XxHDrMWgJCHt{xP%JCjD_af5+7XbrZ*qxaI&o^T`coF?@6efN$kM{|4TXaJ^E zv2p90WD#Vgr<*){e9wVqkeKjpNQf?93}nn7m}d_l4zs>fTGo4~5vf69hxm~mX2ing zionQ-HXMJbdDFqe`6qoh-{mCFJaUBO_a&qD%au~8pl+B323=&sg{J(Eq{tf7I8GIF z$h?5Rt1A7nDg0l?=spgDP( z!mU?uU%TcOxInQ8j2G)z+VN`{PKS4fQe0;&{jsrz_tj(&lDwXP5mR9zqxZaAXZuwS z5ax<+MTWb{KCp95<6E|$Hhav2QHIDBogcpuAXP)6Xf990+Kgbkd2^L zpo_UAKv>!PsX1|7M21-Oy~O7aX>MTgq+bJYN1XQ+=Mxo}-$63+&m+&(nlFDg^%XSY zKRw>Sn%(p&sqa^ySrMaqCypJI8h~RaYKj$tRnHDTOrK~t`+u!H3A9J96OndRHTG?C zmt?OLY_!a$R6Vac)@0hNOGzqt#F7z7>7;n;(t=7fud>=H9#(rdZ|4nHj!{n1S!3tl zvo?2?>6*|m6EKt-dbzpmBdt$n^dC%?S_r7$iE6(rC7v;E)h0ftTpR#-2tx)(Do*MpGz#*_j6OjcGv(p2;{2%|e8-rZ)}Zg=Cw zQ)}^`U2T;fMIKo5v2t2nmGNKuJoQtE_FQ*NvT5bWN71W%R_Gfu!;zjisNJb?^Y;D& zbyppNd0*Qtea<#Xr2Ubsv`Jr|7}oQ+L4%s*{ik-=Q^Fo1sq7Vi9zyrW{bWXIQ@EIB*}U=cFSGdu-Jj5m1Ee*fMzs{S(Up?ac8> zcr-_Rp5e47{vH|pyPb!1X`qZ;_82YO#VOo&A&EnFCzbS$|k-1FDFw{{axd4{oOJ8|K1TQ z`zOBoYyEqCohO~So2syNb)|Qine&l7p||&|L)yY(lcr@75A5&1ag)oP=w0TxY}O;^ zgd@V@CEDV zqJ!Tc2>1mb)r@W_* zyC?aE4h(=-FqGn&eU%X#R)a{=jflGFG-Iel2Z34A*?sS!@U*-%P*!mmRu?)B^QJ7* z_UvL>WSIV_iNmGYVRYa@xO@QC(Emg$0;b=actT=_vibmIO)NFqhm)HBqm zrg5Sw5;KC9O1;DE`=J-(ABMGw$k|ORnx}J*z8x($HqXC`D~SJlZesTJRnB!g`B=|R zF|6sB&l>tDb4{UTh`8|h$}AOPR#lunqKj+aXcCQ(TU^4dY{3w9X%ulv6eoM@1^t$k zd4O5MLA1ld{;{mJiws@yj4vhCm$XcaGqI?z;h4v&RDDq;3ldjBzmu0iN8e&he7Hs9 zwxcQPZBmozK-D1ziCnZ2UbCia>%~EI)1NhmMwWhs+O>O5i0tzuJu?dI8O|F!5^4+o z#=KoQg^4v2IIQP>c~QhI-4;t?XIaiS07Ksz(_)#jIq{9-Wzow8lnYIO4`>SH%S#z; zErhM|c#{_lQ8V}BY_2r!RlG8);l+K6aImf8-@M?*GRM&>u6z^o-AVvNVR+@^oEBEj z>SPFx?m@m3)GF#?X88LymStSLRx+k`>^jY0H+o-sM~bM`b9dPo+(Yi}+FG}^Z_9^l z?})2{{g!JT)1NLHyV5DH(qbhMZh_|9?xkcFCi9M|{n5g-t10;Q_Z<&NrWQ5~j!Qx%^gM zX#G?E&9>_Fj%-Aox{}cmcM3XTc`)}*g-i`j_ZnK}2_RUkK*rM-2PE9RXWb-T9c}FL z+P3zX;{4Vvk9uxQ+{*j&3-r;`tqbCBVryWt$oW3sY#nV+(h zKEzw|l{{&TvSOU`e#K$OwD^-qyl5IznK%kRM`CC5+?cA>F)DuISDBYgyMzO<31b}B zxb-ybZ%IGM-RH`X<=Qm#j$G!6t9)Pi&RWRhYb~o~NX^aL*NK?dJVEDyQ$JtiUAV8g zF7xXrU+)VzDNrT1I-U(QdMKWZ*Z*8O`C_Auv*PUurfts`mEi8qLGI_?J-3c zb)NY@>byv)SPfKh2_)D>;{ZC|yOC{orN3cMN+@7&PK?pb-p zJn<>0y~iW2DdtiNHaCX5jisHFrJkJ^BZuj@!hB#odyn6+`XuF0AOd$~@BL4pQr_cE=)3%k75w=i;4f{?~!O*M8sc zde)`K9;fm}RR=Vq;N;L0H*+KF4DnEiu8V7i5|x*~aE!an%M=Kgj;a9g2Gd|DQN6#p z>o1^rZ3gk_DC|c{m8?WowbyAj#27!U14azJ#pDiZM%@F%Efij`V4Z&%z>$7$ACR@e z5A&xY5|@vK+kgD5JZF91vKto4De3ek%ZbF!P1L=13x~*=yN2aU+xB9)Rh)+~%0&~h z|tRXj?0&R(qPNS9~sYx(!QbN zpn$1sUV(3Zb$E(e#}(+!Pz2BzT$vn=RP5eIZffB6ms=EU@X^s2YqqE!YksAoZCfv#jB~GXjtXvRBdF(yO4L|EN{-fJvCi7 z|2}QUN@C}sv7Pdq1NP|H5%ZvwuUn(<2hl~vLAzpoVR@Phe^T5PP^Q^+RC)509=CLS z;(r1u(cH#!?if|P^AhY;7+2`c#0UhySov6zWVIIA@6t_p1le^M<--_Is+yt)02H(0 zlHM0xv53n;adZL;B;Bo;Fga|xg}40v;8QK!4fLb*&Kr={LX;%aI7=O=pf&@`cy!O{ zXhsg6xnKtJ+<`qf|18XWES@wvGV*j(rQ(9;#aIS{7eQj@&7r&<8)9fEcdd7gfu-R3 zo5%%E0Elgi*O=m_>=x&l(4?@N;i$R-#9HP?z3h06MRxCK@6lJFMoOI7qZubI)5Uph zf;Z?k8M;#8d(qaJQjtaVtDG?EluHop_{G-l-G<_Yn?Q+f5egbJAB5%In6Izx=c1;PLr;wDU41;TN}b8g1og{20>hI630fZSpN88q zz5#sGlD`wH%^BDJ_q)oM8hb^be#2j?PWdU6t_5FBN8OToTo$eOh*ZFKY+-GYiUtKEKgyt`iYxfQESVf#2;{n_v7 z?qK@9$4g#$vR6&zf6_Z5=amVgKLN8~umbKLfIng`ev(`W5p;E6?5Pe(RX&q~<)^QM z{*s0xZO3U#4oAX+fKT~>W^+qk5I=gWZixik*Rhiv%Fo5t3{m0_q9E=SBzAth3DSLM zuW^qRq;>R_YWTF1q5BLt;Z`m;kMm}Wfm+iGTp&esKFo8!k!T{Ow%U@}@!jP7@c@-g zzNm0eBVAmTwrI^D47tj9{WVyl@a!u5>XW=IAztn;7mB3WI$OM_(pT;fNlM8#ve0zR zAh5t7Oj5YN?-utBk9jQ~m)z7}Dbz~cItUko zQX~5*($ZMaoC^F}fLfAZEP&6WBk%haK>{Mdh50xU%PV+ojf#4V%AodLpl!#3d&+a4 zycVcMesxaM?+dWE)}JnWV?~EigKjQMD-FeA7rKCTt>)=55A!Rqpqs=oyC8Xz-UvD; zXM9k{Hx6>efc|Qc_u>Whfn&DdLPxcObfcFy1jAUwbCYwy6-ZI0<0oOQLvqmBwvpjM55alEyYF^eWq&i$!7y_`qa9LVP5NRE~N>fVr6|!qoYxAQAlob z^;2?-XhQ5kx8axEt|Bu;^dbW$d!HVYZjc59rr}ZI{76OzuInYf-$78_@AVGxGJOwY zyCOenu6=3@mA|_NQ{YgC+{qrtt-`(8?j=dxg1#{R{h*e{L7XK+oS!1NF9c>PN^^1% zhIx3oxb*1ef{6#KKIk;ha(*a52@k>o_9=z5H*HDm%-q&$jj(XCC4S-Lp`sLFY?LyRA=B_Jv49g}Dh!g5|qDyrFzM-Dkm6|2e6 z9as&!e7%5_F<|mGWAeByKdp)u5V_KGd!fPSAd-%iNq4AbTLC15@kR8fGe{`8hDKfI zV_V+2Gm+M?m_t_3+6CAHzTQcOjm*V`VTKn-s&vkdUZ`MDncphvxvA${ z0oV?$MQp$B6}|S#-6k8eQ(Ez!*z?_e5c|nI?5g7%Iu0)0688;XZ`BvN5mK z6g+*J0bCFwJl^Bw0aVy|jxaE3jH~i~U3AjB#`0-c&Obt?K%K@ceWA_R&bPuON(aJzgH>7r z2gvZl5L$9cn@k?7$kZn?PbkPS70LYZWC#j!)$7zTm?*tqOEN%aiToA!RIex^kTvhQ zn#u{D39k*~`XHue+&L>=)^r4p}2UH)`Jl8RwEuEcF8UPhkj#qmEWJZx9n{uAp! zI(v}x2}rx2W@t=avb8l!x zqZ!M7v!o|eV#8^aH0`8dwKCZtnhz%mGVP|YLjO1cJ4nupGEW!htI z>mb*3PKcP>aN*lW4GpT5^!j}o7gwnK7lcxY2jb~i_$kWBOfv_S^g55b_%YrS!Nn4p z9&>rsCaB9IvCp2ZZ#cY&sBe&$(srJRoXM|ACl~mO8v^bYkTs32o zqi4c8QMEDyhI~Daf>O5Y+vLBTE0-DdYSRI$0)OgJC#|(i)-(-b%ycGE{^^j(v$^MKZEh7Sv z;7YfE3S~jf$xIWacro3XTP!)zzHw>*>J^g}I}U@Pe2PA@>l8fXd+0SQxQ>G+LF)qS z#ohIj8>Pal2@W|l|0A0s!Nsg*z++#u@#2!aW$TNBxxkko5#A%p+C4`Gp$wu3XyER1} zUx3W_0Y;G@(l@cypT6CnC~YaQ+Cq2Hw5#!0n_w5>DZ;5SQQAp@>s-(r8}Vk$ zL9H2vW!{isF0CZefcJgMuS z&PfHz-?g}N?6)UM)*5E5zH|+?5ooJL-V{HGILn-VK}iqIQ8}HbEJ`7<^SpFmMa^hZ zO^#uN=r9r>{}CvuWZW28vs&})!;k5fGnNO&Mi%8h8j7!+FM~T~n$o~e#xsJ|dc|dc z7Plc@!lpZVsjb1BbsA_MMk>E|OH@b3c)V>BTRoKj24m1JFZwqJI84^^5vFi+rQ#96 zR^MS;*RK-$eTeEvVvsb)-RIAU^#W4I`Vlzw==$5KAJXzh031p%WXLcLhcpo$#>6Yu zHn8U2-rVnF73^PvH(rjNc9HeClh}E+pU0kcynL!y_T7Jjnx0qMo%i&skN`qzb!BiO$4OUw8)EdJHg z(qy(&45ukr$ZINxSvIyl=9ic^ML&8Po{@KG@dIvBbY*_y zV(7pM9$!D*26+1|=1Yo1R2tZ0wrt20-r{&EL2T;O%E{Z7vDB(M;Ukj#`XvBvDW7U|J}1cn8j%v?-szm`OMlRI})7n76N`PZ)V9Dl6^=8eHNcHnPqh1&dT zg^kKW1!E{LXjHZy`Y6S*?F0$K(XXC~{7J0Lt1ntTr)HK7_Wmf_mN};>GQe4R^u*c- zL_-qB3mYpkU>1G2@H?Iz$WyH}8^SyI21%?gxJVNWTiALx5NvK{s&Je|H?f0pzD_*u zF<|Y~Y8&s{I*~XmQ%S@y+QiR@r*CNT+6!7hxy7zW9u|?NP2}QQLp%94?yS9(5%#yH zQ4P{}**{853vww)+k+_~5RC7k8(?;85Ht?(Xi);OXFW)?54e>5o(Ut4kEsh!|xl!?D2A1eA(WEz=J zkeNgm2fai&A{a;iGo~f8<<+-hmrZ5~Gq>PQ>G?*J>4aJQ%m=vCu=ws%zr2vkR>WDv zsnHA+COWt~csq@xrd)bWzA!(`OD7(A0LXGef!q^a`TtAFDm22~px z5zn0Desf))}w0NVt2hqn(D(rQosbI_%ui-n#Tpw)K~=khv6XWM zu&ao{8RU?0Qb$=>AZt`cX2AgUKVk0E@-bnSUJTSj408!$j8$FW(bdjv#yfiihFxZH zoi+V-b$%W7iu`hyTgFe9o&zcXHOF@pB3fo)KbZFmqeKVk9{Rr^)zc70))pkSE(AM~mby-*w{4}6m&GG`@R~3q$*-GI)MQXmB(;g~dq`%bRi7!(b`UBXgv{i!pjZ zrGUmuo?HYSe%O$IAq^icZ1tP2dkXtv(P41beY|ng1+Q!|?SGOb4|}&GiA;`VG+}In zLWv3Oi;SW7j+_7)m}#lSphK9+Ll*R?=sxQ~b5d{J^6q<-_r8s4-2Mb zSLuXbQ1D8+GJCf1M-iiznIPCnuJ1Fp7s7JA%Hmaz+cA$&DM(cCHBarMq~g{ceD+RP z(|)2%s6g}9S!1DU&$XweDU8W^j|>-;)mZVU0BD!0k+w*jc!j8W@MeNY$j~k)u$VjKF-X)>|~ernfu>R4L71jHd{yT+KfNQGr6;$ zJsMzf$f+ylp`yLRxOqt#*1%y7Q?Om7!sT_nT(K;zvOr8-;#aG~b1{3@%08a)=I^QU zfv?W*>{X8l@7i%a3YB3fINE#`&FLW|*0OE(A2~l9&IuN%!)4_Ssm&Hgl*&ON69F~&C5t-3Mv^JCg=#H)Zf})H z)JyLBK{UvU*z z2*S4#yk0rm!4Y2-iL<$xV>@IX$o5|vDF2K~UezPm#p?dgh^zmznEM}}{XcqT|L%JT z{u@u{;r|&=ElJMxWw{fsNtOI2zfek-M|0FIuK{E7z&|EeVWO#_tYeW<{96kxII)4q zBT6&eQpDSoL-4H0Z%v-3x+D#9L~$bh&ZB-l=A8y|%a}s&v$YA1w{Jr6<&GQ-4|c*x zFJhqT35{arNt{7EcPhQok3hUhh=qlX&v=Q2-qYD{y<(n{m7z~N(v3NhDMCj?q*nK0 zpc%fiNYM%Sb=ajG6$cWMY;=4$!+_B?B>moN;q$Fck&RXO(n4=TsYvDeM6}WFA$gDE z9x+Z4s+=(k%Q!cgO8A~#5wN4Mn|%H^F=jf^GKUE zC*9hP*BDh!QhN+_f{(VhOxS<@S823=uLYB#TVpEC%b-A9=h)F|QBKRzz(50^lytJM z)8(SDupHz-UT2R}dN#JC;qO(uI7XmgvJ!wf02Rs>UOV&&%^RCeV4Wdy4bAV~err%| z09qJ2&_fjF5dq=T;zuF0ypKq1;M`_LT^_@IIXq!cy&Mn}5rnKYu8XigxpGRLeyZK7 zKF$bu444RcC}8Y&s8tu<5aKCjVeug>%p24zW2T@2Q4ik(EnW16rw;~9QYVZFJQ3`) zGGLTPZ@Aw>Zla7BY8gq>p+C+X9Z!3qZI^%kZ3(FF77c1opcb2Ub7hM`7-fid27HKq z6U9e_cb?p@ze6sO`5yWU4Kvo!m_NCiYRRAc@cU=I{)rV0G9`Bv z{r3E2NB?SGL^m+l2)lUW2xiMbWgUxQEhYfUrURLiUL~u#vgXUN)E=x>2b$Q6n?6@& zS3SSKNPY#k;Wj>94tq5S@F$v3`uh8bPzUXAj}rV8gEQX84@(8y4Y-1#_UH$w16q{W zUmzrrq8$%b7oX9k+^~p2A3Y!%sLuf?77b_w>07$6R!jl?++-#T1(#TU~JPsNF((?dt}H*Kv4zgLoRY^+S>+<8Gf1Hi|f4C z_xLm@LSetJGIaANzV+YS{O~i~*LC^;2TFc3WvcO4!w_d<-lNrulG-~YD}HVcX1Q7o7TH!p;p}` z#;;xAs5IU^e6z&BEmX=vIvf)1hij}K4au*XWHoH@0_%N|Ew&QV-yLvA9YZ3{&t;!;8h5}jzefP+0+N5=xVXS*HcIpqxbW~iB9%3!T zyN(bRRMXxty9)Fw9VW$LA)h7xW#Kc?|6o2wup7~C5c%F`;@WLLFS1vsrS$wqw*9!k z*QB|sD$xvN(Ax_ChU1MFAHpqgx#C4$-ooBIg=@wJ&6|_KGqe+IUq!Io6Ebe>6%DOS zJ}4)g_1;|!nLnH*Fu7&6BiQ*R|CeHu1ukpXe&#+=snWDj00+FrcI%X&Q2P%XANplK zYwAaHpRK&pT^`7gkx4nW-P#b=gLvig*&o*UJ)WH&lATeDv#Pw}hNsfYwQ2Z16U}7! z6hr94^^e8#-N`bcW%x=veE*O&`R?8GbKQTm)FTiJiT_xXoDd-HeE;qp`28E34n6)e zHbMWdy@QZ@UVZ0UNMfx~&*w!<{najdP}{Z5YMyYEKFjaTw#tJ`a;um))$2Y@NKqUb z@9@O)do;Yb34#71^|8;wS&FiP;9!>JpEC2W8HDd|YO@(@YC>8y9qHhF7g~1UGak52 z0%R;oeCZ+s$4L;_*?)abJQ9bz7M&=CbBz@(Zpu=F=HnX%O6T1irHG6BL>6l~L*|Tl z?!;JtI63(W9{LVRnJZ@%3@*PL>w25xUN=vKOk@M_kBh$ki;9u(P&pyIpUzHN2$k?x zE|G1UFpj7|i~C=xhl89$M5M9HkHA!s>lDyow3cPx;kaH*w2Q;Nmg!Ha#b2I47{n#X zUZmjSA?Pr7 zKSNsuwW96{EK>9CMu_6T9PmbmzVR{o^XAlB{3QLgpqU4s-Tj3NE#{|Z>>5%yYf4up zsF?gsXUs{1axu!rNU%>q*)y<)%96=PmT_(ZruDM{7RNXGSSCHL5)|3B;zsdaU=(&E zp~w_kO{f;XEkLl7$}@>der$H+gFHt=Y6uIejhYK2LGyxR`lfHKYvDq@e$~G13yVAD zrZ_DYLfjSmsgv{=WH+CtEv>gRoqcsvhU^{()lAZc&v-PpFf22Ukz`4nDjWJ0v5bT$ zVm~w~7FsT`3dk?*mEwd&LAEzZgU0N@Cp!#jQ;*^fkLi2@@DFJA^+QFEL*m)?dtORj?#3E|74J|9d>bIsI!SyU4PXaFVb-sbk z0S(;S*(hE%EqF3sPRyflU^Kaw@uJtdlujS{0!B8}ksmh2(@>_kc>BgA7o-I#Aqlk= zaeGGj5+knYYCwwy!x!DU$Pp;}-C?;fk;SNXwBF3)9%DiyN{Tq_jX)+i-iTs@6}MK5 zOt|vIeuXFUMFW`*$?1o?<5wS)U*GSW=3)st-oex>oGU97R$D6GVfnc@X6x4+|J8+{ zNbX-!L7uB4LLRHB;T#&@U~k(lirKwQ#jXmNE$3tu5`RCLxLE6Fd=X}-|B=|ZrcK`? zQj+;YqxOoQY4^$lH2+0|@mkho{k`JBDmYSVS>KdFT`y5TGpfp^+#(9MW`e(KDP_^l zYJ;lcFhweAh0aolAyuEvkXqAJA6}eOK*Io-Sb-A|LhxZ z3rg;vVUqvLPL-Hl{42vS;8Z!WT^?-~-Y@9Iza>qykp8!R`()m;%bAv=%D7=29p98M zS^ftYQgyzYD)=WH9Qthn>+y!C%6pZSk#@c+&~=MT@7 zWRRXCK@g4L0c^s5G8&;erGLDNp__nvgk^IQF}Z?Oc2i*iBW`lY!IV8c)Xc=CmBFq! zxck?obSlymX}w@}d&}Vzu($4BfpsYG=ns-*i<;tf!_3`RawFkteo`-~zULu^VJ$Gs zY_si@48fol`?m1e%kceJAO7*8F?O7+&Vl!>!D-%i5igRlS!J-3FL%bPetVQ0?@Qd2 zToW)T4&`9>ygc}$sfPi%SEff(sgBP}CKFbBo`p|bZ_F5jYy=M+$9(GN6)Inv&=KnE&$UaFEzGrh z8hF2)+zv_w|JcG6!V(H+ldAm3!khu}k9Bo+5++(~S<|GEG7E8rBK;x;g#BBk^EtO} zFSg=A?Mpwx5_-uXQs-~zDGc55V*4_BidoaXa;*|?Fi^GFfAPs$I?4D*;BDo;W4-@< z{5X1s@Lxru{Wc;YJWIcUY43`Ew5`>4c`&Fo7#a?T;GziW+roM&?sPiIOAAukjb~N>WC*`l!<5owY`<9T>`#l= zkJ2iERsu!6t@hbXlt=El=>ySYQ+K_Z4b;?cQHHA0r(|M|3_M zZhaYYO)~dmcJZ&ZTkg}uEF5kDe;8vmLs&f~vcIQ9{7&E(2zIb3gmHWQuNiS}E)5Q< zO(vbC1`AOPaL}__5JGy-LY;})|HwnP5q$J#T(8IR?k zU-9;x?eI9_9zIw~YDBJi(+T1#0NgbreJk(Z=QVtHa9(dr9;(u|i((?0nv|b)^y#$_ ze4n%xWOv#nJ=M|0N9XQ}OZtJ@mJa{N_vZ@+z$h&R>@!9%8OydEN%Ql9iW!H}j3_ zWF}xmgLvxJe?7AS33`6}iaF`c-#UAuUr-qIE3_k{3o;de1FFoda2~gq_F?{_gP+;j z4fBltxD-=Z!vp}f)k*#1*Zgd|5%Cg5Yt@1nVs|Yk$upU-^W~95=0KI5Ls0~#-rGw_ z)jAWx`A$~PIaLR3ws!POaa7cij_&%Nzbvvr;^|CbL5?)THOv|1E}J4EWl?p6e|bFD*0EA zrG2=1ZMnfTw-S{FyLCI}m)y3U;Vv1LzRpjZs!r1>g&)4&iB)6k6RF)JR1!)vCh|!* zxi1Um1m1vnKi5s41>5sk!IE_js^hC25bT5@d!%JQE8Tc!-WwRy?F6nT#2k&-+SldF zDM@js)^ETVBI_h7Jd_?4)yn$1PP$5MFaZDhrb9*mzeKXzD`-$-Y%&M(y-66bmFWS^ zy?1pIdyV-;b}0lH3{o!UGF>~ryLddfthab78YxyQ7`j#VF3NHFH=5N@f#H)OEN`SN z$gyBVb`Ec*6^U(GC2&-qMOoCmwcI1#&40Q7%r~}GQbAz4`%#Hk^(E zz9=`)l{&krw~nq14f0xLZyBeIA59U|G`$HCAmThDG+rjr;2Teg7@w!<_=JNsP9z9z zn~#v=Fh@hX6b`}xH-$~uH9V)FTxPID`R62}gMLK96^Zw);=>w)!HR6-sj%WBix=sV z#Rb{ss?JAEe-5n~s<3uyaXMWbZi|~~EWZlTM9c#t5o2V22~;tNX#Q$G>^V;|%njP3 zSQpR}0a`=IJS4HUc?C$@ew7}vi#vX=LDc*Iviqd)qbYN zOSHZK#J0y!s_9cD$&`3JxA7S<{%#3(G1`|q02n+cK>;}lz@rvwrKaus5$TtKyJ80Mcsrb zq?uZ2@Lgo01TeWQGK&UdWFN=s=Z5Dq(9a-C4bfjg-URa5lO+d%qFxz}If zE##)vP|dvcnOi2;{XYaF*vUAHco99mt7OfJ&F~k&=t)A`(wfNK_W<5bOC0Fhwrt{! zx|H4?8C7@X!IoW5DYe>e{^8>7+i{Nc32P0%Yz>OBaJ&_%$Ksb}cC~|TkrXJH)4nR- zr(~3wg?s_lZzb$=l)niVAVE$ewte&M45DA-q+VR!>74~XL=1gBiMB|3A42;@CpmXsmb$)m?U zJNEreVpt(PfLoDbe|E`C&`1Vdp&B`6I`aP8S8QKi7f|88?pmtt^&)XHK+|6R#L`9G z;?{i5+>)gdxeOD%N?qQ1Mxs&240MfQNI+W@Ae77)loQa$wV^!CK~JPB(qgzw4rXGg z=}>qMpi58MKj$CgWiz49O!toFCMGgoI`iq8Jr zZsf>rQ2G8~{~_$p*^{za3^OSsu(Y9T9>GpA8S{9yq7KN&s|!~l%=8(~Ot3PH1@|4& zCD)9GtEQoBW4Qr^f_+V5-{!`)(+>G|biE)@wIndP{rX!M`!#!$!FsZ`TZ@1E9u0Tr zev}L{Lv`X8C~#kFP&*xohwb;<=fBhl3O^Z+=G~qB&@Z6e)LAh!d^)@57A@At<&m1M z9vyd7k;FOW7)>q)6b^X)eTpoWMSlbR-0 z-*=Vr%Vu^Qg~u9!9wFzCq#UYmghd#OXR{QF5Pu3?U_ym`*S)qakV)Bp4-OY>&7 zYeO;6$>wcfhqIA^XNi~rHJv_<9TO7jH2G>kLRSanlxU+ZUp^*v|KOv8VvpwMqY|U| zq<2dpc_-#ixbUiu1h}I4#Y@QLOQZRd!64gMv|}tpjRQ%-?te@Ej<0DVL@?4~zyRfy z4fIq!EMbv#Pent6A_382eL7JH=N^@`@?XhgyqAw5@H5y{_r^%DG3co3)bUv}*Y5!6 zl?R)%#2;;8;LSqpU2+K*kOmO-$ba^=qig@2LBSIJw=Vg#^`CXgBC_){NDUuFkt|u8 zUhg3FtED=kNmGK)rr)nJ!V6vMULsMDJ{np)urpf(yjLuCZQVa@J|7rKMZ#PcsgK$t z+!8?pPQKgie`WMte}~8h_4D`?hzf^RSLV=?&(dLWaOZsWGKuH4ZetJ0luXzRZV)jo zG){qHD#v@b@Hxr;xG^PaMO*n|RLU1#{CuwA1**vgNH!v_0%%u{Yn8)pTpG2z^?j?( z261X?^zBY#k8>?{OMb6p?nr1PW*P4^O{6nXSoS48cU_|x!+2xl@sSL0WVG#mzyuS` zOJ+~c%SO17<9!04L6y`t{ojZO_5c~Se$$VoU9`%4hZlKLfKOI#zbuWCej@vH{#9|A zHq9oVk3oSjZ(Kf!q&=-6k_tFv1P%z>v6a4-r1|-5;<~+4i!ldTl4dKbwRaz$IJ@WE zropIpY_VvUj_+0eN;(0-4qm+O_m=7W*aTjqBxJ_A+!ev!uH?Ow@!S^3RKQk1nNym< zKu@<<^%p6t2&Br<@%?!S$-2|%J7bR3l{((Mp@)2KUv*WlRA!HJZE6jd`34J3MpE#5TkGYyzp1~F!@_zNHGKTEtW7Mw|!#xB${%>=& zY0ZB9IWCGn8xoz7)XYs*Z;2@&axxm!YD7 zSAj5mcY~ z(J5qJ%Q_t5DtoK-AT6$#uhLHwBr4Aq5$pug7U8uPx+oiwq=GWvt#4V!Esu%=kY|%0 zbkZURNh&mFq*{TA7uGSL?>-GyIe@R@!*-sm+qFe`JB+a?wA@`izK;4G-3d|#$lL?| zAi?OqxII5&Et>3tMx$lOPJZmJ0=TVou&?6hy9Y8a*1IUwZ5TBQtZX^7FSvb{X^Nc8 z>|NYtp6CNA-OK>OSrQutSRh906LTiMYcky9A++Tbe%TYT)9K!dp6R4z&QP9*)Pc4Q zVJ}6n6K;|?YL@#FfddN><=w{(zg@KRfv)uu=QjQGfnz5-%EE#tVJ8JbT50rIKG@w%`w&sXQ)omJ zWzdgC4b0o{gwXnDjpWmQrn?xo=fU?olhhHwXS`h1;nhM-TcRA`6xU3rbW`!pJXEp&lJ{1PFGb#$+6;M;ZEfSLAg!$%a5K zEsGJ!BL(V+BFMdo=*;{r9W%ncOQfII*OhZ2lOFv$c?wH%jfxNn0k^C5<=E>ZG#Fiv z1vTvjLXM_Ddd~QJGJHkDwe#Y=SD{HQwQ>w%`{k98q-U{)8T;(AVS(h0T(kSTogrQs zBM(+++MqLUlr_&2W#da$EdaZXseVNCDgKU!j144ckEjpBl`x%xo)X;xwFNt$bPm}e z2Pc$=K~F{?^?l#p*?nRM3o2R?<`g}$*pbvIp$2>|4=yt)eVx46@_En?wxq&7^L30F*!4ht`%R9INeM_k%s1L+Su+ z=vNHn)mm1{mr-cY40S?A*NBTY0OuA&qb-FK0}HC$fy~g}P>ynhEg{nnyk=qUIQ0sT z64SGKHz0;R<%^3O(bmm= zQ}T338#}*a!l5o`H&{<+T;bOKilx7EB0UHu_YuKPj(?EGvGawXnoDrD0GVHhQj0hH zh2!;Na>xAbru)6NC}f7;Dn*s=+o;oAscg3~9B*kZQrNkoepIBu1^z7HTzg3cPv>I0 z+2K2R8s&1%&*JXyf$ctQYPPw<`xuusD3$mer9b)&vk8E0<=DUDzj#1{|q0` zRn%=7{~|TE%=ImPH7Hdn1O?ICXQGp~To>T8K+Pr`b9}!2y=4a$-i}_oU9W9#k{{wJ zL(5~s0L;LfM&$1Riu_Qbi~Q~pG^aTF-y(y0(Roo#G@bF0O8GxN@2OQxMj?@tp$xE@ zEhNOB8bN=yIPs>%Zbyu*Mh6wS$nw$&#|yi?sSZR@h0 zoR+mZFg!3hm9*TcWC%iiJO@DTrB~5gptRWe)Nv{4obu7hn{dF>gdV|8iSfCl|2$ei zz!$9OtAK%>O1*0I0pnooxukEsKXtSpk@)>OS!Azl27#s^%M1CczCPl@R7u@SZyc&& zQZzKp9R3WCXjb`}+Zr6+Z&f(N{Z-OIf;HI%c=yTE45E@v@oxu@1iRiAW zR8pVx7IYZ$oZzt%^4FNrvsj{N0n*l|km0 z%}_f|`P+}Iq7q756VLKpDW-4sOXO+2>k(o+>8;8HN}CqxH`hNieOv5VHN@@KKuf9? zT!Qzqw5?WTg;5KP2+5yWcX&}UbQ(?EjF}pn$sYRdV!@9(&x$g(E=Lu@DL}dpeSr&Y zPr`vBo;yvV>7Tuhi)Ur6UC=@o)-GR7Uux7ntSd@nF?I)T?N2nwbgNe0HIQ{QioJEt zZ2YJoFVQ6+jePz^dNl6HTY<))+WYoi-Vb#K>%SWsB0xa;Rya}SMnvBoBM&^erxL=* zkU$9b)uRFV;-1kmLe+qmtW@6-9~JJ!R6UyrsOS*BJ4%5?$>0JW0FNJ37<)+r+s{COy3~wxPi4_NKcK!K2{*%7LIgW46_i=V86_e)YFCRGz0n4W z)PkWszzZ9D(nDj0xfD^_H3T1V8;tej*o#&^NpAgNg+v{a^8oIF1`0sn=vS4Sn__0G z1!7lRKuTIp-zUl4$}xZuVm0WNCQvp3c`rG9xAx5s+{C8EqCyO6 zCqtKOGKt{YNJ4dWn#{HnE6=v5+$byPT~fn1KJzuk3x8H-8O?~)@lUv_KWOEeo}fKh zct#kb5B65a$`t?P@5Eht0_oRMTuYYY#*(^cr);n~$R)cO+ZDcRno(Qv>@B%%Zvn$8NsdM?nx5K^@OJv9r& z;5qWAMAN=9penGAV1=Gh1ySM+kbed5M&HfT%`zt)t(X#(8j0cRD^RsF5m1&0Rcx zuyBn}ceVgys+p@;aL{66W7o}yzFUX925Luo6R$sG#hJ<&#{1T>F^M)mq`SC#ML33? zwcudAH#)9^M6!cS=e~H4*H{5745u7u>%j;5#=qw^=G9MDN_U<$bzsHAGke0g+*;|q z<0<{w@fr;wW7SIiE6JEST01Tm<>K)`i)Gs?0uOI5O8l~=Wc|6q*AWd2w)C#^ShQA(*NShI_`L`Gdi;tqd# zu0?^>VNz5co(?Sjm4FUZh7}?Ol|k-@xiSW2m56OoCH9V!s&G+i0O$*HbgZY$5ejDw zJ}Wgv>0{vWVF|K%J!%uBlVrB(sH$*b3oSuU|0+xp6jlhy36hG=H=25v-CsC+B#fhx zq@Y_Jlye=~NI;&Dm7KXaKFiFi3MW}08F%O({iH1HMs_D6 zO0z#FtF^1!xvkB1mp32E&n%SAN`4RdWLf@b^W^~sG}<}oZl_uuhu`)IlI8)TYW*IO zCA1s#-}yn(Ae)H3Hew$5zpV~A<$vS8HnC?HylA77Dz}j37Jfu<97VwR6{f^0Xp7(V z!VRF$#;JfTbm7Y#ZIm8e3%0*GVMzKV37)qbAudv|Lp8 zOJnw5^L~c?3d1CzZBAqDN~Wf)JmXD&-?q~&Bu=JsBp$;Lf6z=|vi%YKB*T<0`0!(# zT7IYHU@@967h!Q9#W@eDO3#2O2z%In*ZXET4bUWNVsf62xA;RgMGH}s01 z6;pUT?DGA3JE?RP|4wX7^KB{v#v?!Ol~SDPq9#I?`5ztTf1FqU8a4d08TW*kNBNtJ z{iAb*n*DDs#?}9yx!5*h7cQPoSARw$;YA4&o{qJChC$ae`Q@83jcap@mmmh-mzjFU z?<=7BSi%(dh_VG7!dk^PzD9 zeIywB-4GthKwtf%?3^A7;Gp48A@k%JapY?rsYIe*FXT_szg302N{-!oU4FFSlBY)s zgGVU4cNerBr)HB3h3Ok2o;&&F&t~l$nz~RJL)ykZ{Nh%Mdv;F^-wE9rkgptd&My9Y z336{)a%38L>PWtBvZ=fs0ql$$!%l^vG!9z6#abKDsRF4pL8>Pnv5=qcq9dq>05D69 zRgZhKfMRR$uP|OlkhBSK_9=PpKm;kxXL+qTUi5YVK6J5IxuO-%0}fSjrx1Ob&;!4W zs2x(Ue1(sXhGzAMHwfHghlWA(r3A^%rK)&Nfw+Uw4*_lACQ9Ha9Nv$(f9LclkQ~`w z&DfH294bur5tWjoz15Oo3mkM9Hc}+Q{QAA=Pk6@)Qg&xqj-tcvMkw=6T+K<(Wdj|;GGVnKVzdQFsNeE3q?~Ty zh)N*;7f~a5l|b6%%kg_#G`cuyNWRx2%}$nh&3h+04LJ2XnWA+gZSnVTP+*p4@*uaW zDX)y>9#R}veuq8!#t~lix2-(*5I<-b!A?oRyg*zzKK|n69vfraQ{R*bJM?}#RUBmj zmjg`3dXJ{_QiYnxJZ6DewhkOVw81@_ zKIm7`&xZNIm|)_$t^>~m`gv}X<&2atDGgGPzarW*IiZuahS~r!u3t$JwSES-s-=1$ zw}wyzI~BpV{$5Jh7+4LBE9Az6g&j0vgnngogfD^XZ!Cyx0PMHT_jJ1u9emg*7&tO) z&@)&RAH8wkZY@y79a;+tZO7#|9l))a_PdFFE&^E>#1BLM5&HGrpq&=v#xg*b7K5ko z^JtMcXk`61SXfCTGTTA4Gghz7k}E>FduPU#ms)7HLg2(KP89R!|MFERY zVlVol-f{z%qA&V>ELl!ZI|VhhWnbUj|LI_9Gjy)|+R;3r(N+GUsIcd@v&CGU+wttS z=T(F){Kb}0AJ(jm9$Gs^x}HR?qEh#sEjfEL-6Jb0XW>U)RFRaU<^4=~& z2JGt3^wt*E3l(rooAU7J_{MA#=$oGfa6*Q!YZQ+{p+nN49*0bR5p(K70pSRCDdzuA z=X>;NldQ_~2vTolmFQk-C41Mwljkz$C2`BMghye2#@aRESgf+}hSQe_#qd>pr_r6)v7<6C~i$|xj{jLJR0M;Q@4TP0wew`w>|ZZ z$H(Eip)M|b`4$FpypmyM`!pe3Ky6R|7rO;k`Lk^Uvn}Mx@GJ%mZ^RJFOO0>St&sVS1GBjw?BH!zJY*_3vo1*8Tb#up0~$hKu& zJA38!&~#xOK-ycPh3A4X{K#x2i7BzZo|}IN$dMAaKMZ(M+mEjoV7PYjBG`%iqHMW) zS|IGWIhuN9g6a=hYt*@+^S^>jvUK5+Zs{9-kMAukLJ5@~k#1|_Pw^Xr(KyL+#}lJ| zmYgVl4!@Ph_jeK^_IiN`rCd#!uYkB}jY4R=n)zqx@L-{B!E`G+3AYahvKO9SSAW{BLF_fe0~ zwPY5pQRac~N3VAOEPrw-PweK1GEI0yuoF)WPg~4u3ozJ6{MgT-TnMnD38c9Camt+F z*Kjfz8l6#a@M$iqK&+OhK`@^&7u`@MfirK?YW&emZA>{AykgW0#wV`wZB{MX62c`n zP}h(?`l9eX%sIH7eHpI$=|uIRaux{sG<`o2uQMeb9vknjXm4rl^PNOBikjy_KWL7A zG4n%WA54iOw_rm@bPcmVpmM1KWWHQUc(`G-Trz82m}9~@BMHGCIWu_4?7B| zYn(ocXVtf7yQ@JF@CydE=6U92Id3>2We1;YkB)Q1Rkt$hBVxtZ_DIqADRs|oX>5M~ zw1ocj!>#<)^0hWuM`qo}z&idXEmaP+xcA%aE`+9KOc5BXuOEbWQyG#<-su$Rf7rCF zM@QJaLSMdFxy#2rO_kRRy z?;if|{C)A?bKUgaf1c}f#OGS{p_@wkn9kkBgkPj7_*V2o@h^gw_l4Zs{1ig_&7QqP zW@uXNWl0v$I)a#@E^xC5Q(R=gkvj0XDW(^NiTIOgQ+y&(wi;X>?crctOgYKL4S~RD zTmQ_u6F z00tI>5C?LlWEBh4Q04F#Af7w9w2cF5C=2eQfrozDZU(|)F!y2Wa<#S#|H%$+yf)}q zfnirptAiPL`g!{UC2KOSY>wU${`%Fb#h*zk5G^tvd&3SVZ)^yZ3i1_MLG8zU2& zjZfsyu?$A=Pa99FzF=|dL}?s3Ouhby)!y`SiqzE; z$BB1IxY$S>NcDICW(y3|a+o4AbJ}5W{&Up3wWzy;ie%EbTdDaVgVD7fjY-S5ugMlk z>a+Bz+`pSHMZr4CETMV_o9N=u{nb)7!?1_sx%21H^lJEWenhwS#MFuBspGg>>|J zZjGF&4%Z?f6;krMmsrfm6yW82Qm=h3XZ0flJ0%X~HO3{L@mfR4iud_9frilwEzg&O z{7^2GBSy=O=ZFzK}LTs|~EDZhK(v$v05m;zMy3Q{yY9kbNz52}wc4kUo`Auf%t2vO}^*0CrAJM~5WhG(M&xTc8bN$3Ya zpC6osP;s31#f)O*4q0&v59NS-UH$$3Hv5h0N3PmXzK@!G&&l)> zs>g41xXmG|HTAPWE*55sCc8(U%4vQ=o`a9+%}(e%~oe0zU|a%yHs-+ zY1_0prhkp=3HlI?K{fWrcjpiT96ERY8(}xpn$9eoQjfJ5rqPy{RVBx-7reCwACLH) z%IvLTsqH>gtF^|Jg!d3z<)=#O7_47$^ zy+)5i1Gx^_ZhtToKBxtTan76)e;B<4B4Ne`e`4La?I#-TmZW+!rjV~O^tTR7%S4zM zk0TZ^Af>N)>dPem8*L+m4SjKwZaDni;$~3ky%^I_>CR|l+){9M#^xH_=n#Ioos0D4 zMXUq1iZp|-7x}c(P%Y2=A(LCyWC$w7KRG=!SVP1EKF1(64^-C_3e$M3x$-Z~wmd|dY@$9*RUwF1)MSS}@s4_H4Ftku)5^R7DwmA7<6RvB?+jKVuVw?EC{S z`-)La!v1l^!TB;*b>z{PaCN=qT_n=~LEU>sHT||*gCr!O_ZDjC0@9=l2nk(KI!Y&i zCn*35d>oOjMwSgf_V z*ZsS%viG&GuU5Rrg7TBEcc*_{+_q5(5?cQpKo?-WaCO~rufW*JOiA}QqtQg;WLm>Q zoT#=IZ$u-2{yFvTdS)@(8rt*(e>*TD@`JrFRED&N_X~j0-Q!0sx4|Wf9(RSiepb5q z+zqA_{>+#mED`pDk|lv767H&9Xddg68&4=NlR4v!wIXm=^+!UXD)cR|I{5k(>a+!03LrKCV3r~# z$pdN`#<9sP8KvowmjH@%r`<*PnIe8ZSeiDFh>!|;=u6+bP{%$%T)ayQa;oC66%PiX z@d%`M!#q(A9YGcc*W02gf#c>@BBnyKy$O`Db=UR1qk@a2ck0-V1=fcxmhxeLzE=dj zbGR*=v$*j=#{SisFbO;Jr$OTl{Ids^IW1oH?q(!n@PSye7`M0JK>Mfn+~ABAQ*C3D z?pGRI)JhEg^t{HG3|5S#7lOs;MxW#-pKHQ9#MHh=vICWUd_N`Zx9PX=N@^8~sE4ZiK4gr$oKlexK*<-4cY)6rjydy8IAYepI3_()F041w z4a>;fQfY#X@{g+uy=3z1^)eD}WX|NnUzw15JGF%`8RR|H4|Fv6ApnyiVP|0{Qv#x$ z?xaRw{MTYkT|3jmwut0HbemKfs~Yo=hEtT>aiwSR4=aG*HYUTAi!AT0tjvM zlzR~=a>)<-z9rJy#VE^k_>)uk5*UwH1#!K09n5qjO-|if71ul2)^jn_@M~BAc}Qsd zJMG@P>9FiOv&Gv8(z5U@$vsOxC;DOdPnTB=JnpPI`^eRPU;I!dG zay|xsu(k>rMTcKz;;Z_|^wam@_)Zdb)(9aKRrJhtAPjKIV83s2EhRSm8Pzx4pRG#w zWnN3z{%$6`-!9S*GyhfeC_1CZOmjg?x_{JH>}^-&XSW9LQB?$&GHkq^JRvtBg54+F#jS9SY;&=0xqz^nq z!>lU54KAfb)bgU2?RaXHYu9I){T$!ttuP)J)J4M19@E;f{0IoT#x|f6$x72hlb5jlPm=lWH`ysl~uB-FgjJ_rpQCeF1CpX;Zn^onfX_>J@ z4Q1)dg$iYl&?{?m8{uiMCUa_T*%G@`3R6UZVpvSH&%I6QVZ19igI1;?XrARZ#iV2d zb=K*UQG@`Fgq_2Ey7z$5%{}1HAQ^B<5J9p!%dcn{og}D6LW9vxirF?k3RQZMm4b|B zaA&-8qzbhBiK$A!~+a88(apGuG zN$2!YEO`F$P0%gvZ<JJ8Lb7Xj{9Ta+!UO&z49bQMa1MVZLviwh*fNNCuKcR z3-syv?BK_RH{@#y7m~+R=rrls#yR^E_wjHz*9$xZIOduO#~vUqm+B zG23U;5IP^GqTUk|NM;%F`8Mst5P_>7Q$h9dv!G|>3lYp@KWaI#WFcdeOQ8LTCN&aA z+@Zi-n{sUJ=&J30y>oKVz5ChJwUx>*RiQRYFf_FR3#C$wPp>Z7OS&ny{P1&CoBMyD zO1g}&J2UrJw+YOG+x5_ZniOF4ctt?e}oq&*4HW2De%@Tp*lhztHgm}{LL4fmY~ z7?Ym}W6S((osMrsCV`jOF;F(y5P5)@C!i^p$Y6@SypQPQ%7~S{vUlOma%G3mVkM)L z+aPp#Vr9I4rOZP#_t@ZvGOhAeH9(MU8vY?oR%`<}x_p`l3bm5M>pE!6fv$|Kp^wkC zVGP!HGkbXtX*>Q<0weyseXMOx#OeYH6nPB+;&EMgCzUVcg^}rKMQQp1aT0c}I&H7B zg=s3mTV#}33;`&^muN?dEHd(Oo-D!pFBFOAOy0#D6AWlzHCN2No0n!DkX%i6$G8Uw zw)CCqitO!Exd*+;Q7S?;1VTk{CA-Oum1P=>?(ABx*w*clO+KYSJ+_d6D@6BT+`5U*e#_7^3UVG?cv+S0T7-;mRgoFw58hXt;6 zG8>7&cIxnm`$ev*Y}b9rG9Wz>7}cl_wnypr^`?26L;{k5;DyubRkdhziOM>5@x8%4 z$q5mCI1`La3olFt!2V5Sh-85C2o?h-0QiQ7i}PbD3pc;V9TP5tlq z9f_0Y{%_35bN@HyAHlb_C-fy8I7=tM{_l`GJA11$MFmmQ_0Q5{g=-YoLOFI z*Y-d2)WjFrJUSOo`14N5e#ok2kE3jHmFgHl(${^a?ECa)Ypdox+O8?SmCn5R88JPiZ}pn<|0CYx zf8|C~`3806)7xA=)g3vuL<(|Q)oXT#kBOcW53n32ki2CRl-T3@1;jsdik}N zZUy(r5kClW`eHQXNa0RsXKvRd;b>B(EQGm-I!*?Wc69_ALF$WX{PlV*9{q>+pqT%s z26-O-?==XLBw)=uE3bCKB8?)um`Y?!5az{5COE>4QerYu>Je}wZJ`~fU5C=~; zS4yEf`CCx>ltI#qZLV>@Ym%x0g8FoXw5OI+i@yr;M$&q7grPk^i}Z+8Q)D#$(#WPV zg&D03wY4N;bJe9SsAdBZU`zQNRM@z9H`tU_?feo6JEJ}`3g1qj!nu;+N1(m~xz8`j z?u!Z2a1Q7?0}q*Vc}>r8PAjAxje`Nrf+K4&1~LBryZ}3e_}|qG*ZsCK1fp%)I`c`r z{Ui?jc{M}bp{Vc08;}b5rr^}=1z>S8##QTm!76uTIN}Mm3x<@6z-eJIMo3qy4kDP9 zmLdPVt!0|Ak(E)OPtK19%fD$~7P)k@jdGgGV*5-{!1$m^JY^K}7!9?bC#z*cd{t@5 z)OdwG@45nL$EV*!seplR|{mGL!7gYwagMyrEO_2Bu)FP zJ2$xGM?07Do*dF`m4qdCp9Q)ikqQk zZ>1<=!aje8aQoD?whFfk_8i@5=L`y+KpudLX{(7S^w|TaAy!5Fp{~R>L z;l+1%h7}OLaI5jb84~N`W>vnk(`k?&aeCB59 zFtp;a_RCN~E)%@&t2dLZB$ZxI5k-!MI#5ijDDBa3yM_B8B&M04+9L#x^16w`X0ewS0t5?`;m*?o@#G7 zLT;hcyMEkx7Cj{;qy{<;rPZQ(^oJm)(T|Q%r4s=G<|TQbQJCJ~jeLSWA#XP$Qrpae zw65w8YP8>ljmI2ABAbu}K2jG^GJwOs%ah+LkRy2D+I|O3bFLppHX{{x*h$z~)ip5= z6p$=li`dg+qo-driz>5*_v~xZuF7E9Np5)!&k9>fR)X9@Ebi}APMjf&YiNmXR?%a< z{;*_tXM2q3PWJpamO+O%y)s}zqDn+ME3_pXnWbT`4te@e*u=t)q@YSRR?>LNz-oQ` z{^`M=}p5kn_WK^kPBhDUsmyDuZCyTsHuk;HC$Bqy@JCA6NC2Raiv(P z1`>AmKQV(-Ow@a9>Jf$6&kJItFU2SSndK`HCayZs4i35U?Umq!3Wl6OEn$T1pUuI# ze)p&j+LguA4?^RaHB`pD{PKVynH5z=On8R!HsPbQR3)z3f zFU*s4-8(L*QW5Dvi?xcwpZTqKL5&}x?(K??%8Xk9gT0q9d$;ODIdi#eN4ySB@i*)! zeeI-7X%||#HZ{AmL^gj9FMuteI7RK3-&PhYv5qDsBP82xHRB@KH^)%}bV{Vj6XL-ouB<(FMg zblEhx9eeL=8{YOtx<#mEtX;=YDrI8`Ku#>)2>kY&nIu|Yz9H)sl67;TD?({DbZ>_U zkt!g*6{e}k_st+-haR4zbZ+ns6RsrZ31g$5cErO^s?FkVEF4L)lywl>2n9^qBN@wc zam+%A)p$nLy%i=Ao6Bw|d$FwiGOyvn>tCciW{l7oSuz z`%PckR0G6a0{$@S_Ki@Xh5QB#H-!e--G9%7bul}PA;)EbL?8@xYwmK%$7!Fib^PaO zF`7JcREL}3Fz!cMD*Ez;$+Ex1QpnCXZK$M%;=Of*v7fXVMuqmNt{u%()v^53! z_XRPJFhtl){WOpalH zJJ08Fa_YSm2TlC-4^)zC7C=;K84 za-1r=5KYa_mlA_QHP%C)qvu_~nd}k_H?w{&0#2@^l+Vw{wtXIIr~~D`TvWsEXa_fy zEI!>O9+VZb-gS!BWY?qi)a9blRav~8ro!$n0aW=i>#K`Nk!>ehPLa_nQ3g%sFS!xa z(l#AZdyZ!IyabRZXbD0?l#TeI?$?Zg&mMjo{jW&adB32T*Gq1+&W2NEAx_};vqMIM$ z2|Ze@M8+g8fxm(lXkvnu>Avw&hkuB@OR~qs^GQ%+FY`IJMZ$j_xjTN@`(~e&yH$}f zH*)J&S*Xj#j+_a3%Wz@Ba!3n9++p2;E3R*#ATU9Gr7q92Z6xz3YLm|}X^Y@8OAt$B z1hauDkWPy$?@8GCdaZD7Sl0PHtv`ph0Q#8iKlZm@bfGf{ZX5eSvj~y7XuQ3fV_aLL zxsC8o8;RDKvV7D`p{VD1=7|p>dODLsu#j=!MT{mK#U8^!HZRRGs7c|ndeB|;CAGBpk{|$bx0 znTFNpes6`FYtOcTSNqid!QCRuvFvZLs~0hP9Dzos zpe&WA8RX2d>>yYSMk+U3H=fgZZX&A6eG#>K9FR3{~^x%$DelZUt&E?5_|Sn zht2$#D}&Jf^S(Da{rmflVZ}RCIG#sO zf8*C0@+pD1i@ph}1G`6Iq_u{0uc4Mfe#uoVY8MO_epD5=LAF)n;u~KFMqb!7^O&C& zd*g~vg*LE=pNCY+beLDpyQ#+kPc&w3h zy8ZxzsRrg8Pd74D2CPk&Ny(q2v%kP7SEfr@*EW+}LEv3v$tIYa$nF8EoNH;9&`abd(h3f6z_y+lptw^Q&H1b{Jo ziLQk>XYbe0<=s(ZxuDMu34wCaMB4j&E{wF#$KA^C>+o-s{qyr3fd=BcaJ~b;+>6D; zYwT{XI>Dqps=RRWv@lAX5DV?4pQF(C!n6xyE-m}cN^~q|{7e2+X_5Yy_2?En=ES1QwjwfX+kN z5ZCjofylB|;f_E3C^zC4&<@6BFS+L{2d#CGYFI(!jXd-}}zdGho2*{*Quy;?b1xGmFi( zo-}6#KT8;@B)aAe5~r4qdgKWl(QM&vsJXG@=Rs$!^sUVK!>BR0_`8kMM$ku0E5OpL zIp=P5fbq>H^kFc`4B#mBX#r*JNZCyiCoZ*&G~v**%Lm$)zhBZ8TaF!hTn6^PuXZOb zAw%hx2|WMO^*gS-Ht8gxblPd<{VJo<&5gs1W3ly8ubSr*b=K7v*McWLJZJM9ej;88 za!U_cB!`@?%1TuH^>Bfz<38sv+>_F~(8P(3CEN)IOjt@PVjrpDS7_<|C!E4LNAW+M zQE30mEPLsr2^$v_hI%`BdFKL$N+mDMhAv%zwnqo^KER!CHSH>~T5#UY^z9+QyWjQb zjm>>#nK&aqEoZXL3L7}+L;U2ebLnG<4OTaOS4${kAZ^a3eckb8E@*<-bufM-yem;W z>=dhe_~2c$W=eCa#e4yUm*`?7vg=N`8cu9NO9=gpvWoG)W+vXhPc#O! zq!IhHj_1WTOWvrn`UD_VYao|9%BXWtZkP1JXLz48V0sX74~HLEdi!_(Zq?GEHh_L| zIIhST64s@WjK1cGGSt&xZ>5*!Sp9MLw76jXBsIO2XcxZFb-Ep1L#I)eGP6yzTq0)c zhi*+4e8xY>Xfn;k@n|# z;rl)L6_vQ2yh9hS`dHRW;a|6A=59ERjO3oLO`hAc4rBi=B>BJM)5*VdhNRH+uf17n ze|xE)@BN2{JoBFzHT>=0V^kX}sRp5LuyM1WtZ?s@xY#gAHWJ7w69``(=pH!CwFSrY zJTJ0Aj+fkr}O$+>CXor3&;eO|1Pv(<1hDUt>bQrIXCiD)dW zu{{Y0K6z}wA1H$pmUKJu891e4DGl>QjzUmeth*^mK#Nkgn&>|75vrPL(g-oX*$e6)lx zc>Tea?mU$2W19;U58KfC;V5e?Mmde0VYty286;ix9MK4{)x(GU?ThiQ3be`cakfqa zG~j0X6LsN=b3J`We&)+0u{(Vw=56zFujX&4Oy~A2z`5|mwSa{r->z&r&2Dv=65s4@ zpGJ_qm+ts6-qu0RLzitsFj#ea!fN_t9+m+G_>)h3MbKrbF`^2mUNSU|X>pa@cBtg9 zYFoS47vt4oL9p1oBrZgg{(>eU;sTr*Mp9ggoeW?snHTb_n?wAhcU(AkUmoo;w;8KC z9YS+r!10Jtej>e!_?GQk*a-j?y0@pz zBbF*ASy%acRAjyU&6;(oh##{mlpck5mapaURn1_d+tHjjO4ocnlHXsF@eT|BVj z?&T5hwR6U!pvEJRon`)M|M39Hs5XVvZrfeJTRa`4Mh>|GHU^@#e-W5_&LiD0cR9za z?3rI~8lQc{rwR$=lG*6bRpku1_yRDQmlL+Dv`sX>>oK^7e(sfMKUF2|o5@kSvP(0Y zIJ>p==&jNS&vOFhS6;pY^BNfF(eU$!>*HOW`u#LWj98#NS1#&=3`}CYgCW?gxRqg& zJ2`=RYg@oCp-fDIj)x-t^Di6edhd;*?Z4W6#*#YC_2(6yll2=JnM_uD8S)?&YOku_zFs?oC%g-yh5isa9V~^XL+~{Cg z*nN?ll9nO$DKm+PxIcbB`l@Pt>SN9I3~$?6m+`=1m(zni-?*ytY4oQ?hBsDU0rAU) zzISeoCgg|X%qv!@(n|QpDbsOxJ>&7?m#rRZ|Ngc*oB8kvcEz{wy)^nQ?M(ih=%3?9 zZ`guv;2HkvQkht-Ew8XAXvosbe|$BAF-dATzh&BHe53Z6`|g^LGe*$(QQNGI1vDyD z3V7X&+^PHPx6G_7Pr}zDFIhcW{8N%wkv7TiVp9{Qz$o;=IRA#3D$CT6a(75m?kcPE zYZ~VR>oUPo8B`M6aqg>d&|Wps&&+U?4lSuXU;PaxO&YIxGTl~|UsXoQ{y8ee@?`3y zGcIRo58DuZoXQ;4ysKN8t&<9AvCp3l2+h{n)^N`W3-e|AWb!SRgkA1GuRTO7n;3ag z2Bgk=m?&7VmV^T-C!|454npg7IKh``$LeHh^Mb8Sv*n#$Cox^#{UlYklN5~rYJ_vn zSEJYb>nDlj5AKY3_Y1}Pnj}|dx)S%fBED@OI^FK@4HtHN`0=v{cjdBKfW6y^@-L>^ z!;r8WqgW3ez34g!(|C#^%TY8-TU5*&=id1|2Yexok_doCY zn&!X1>+>A=PUSqBIQaX{XfOvcwxEnF;{^)WD6*|c;jQ<+S%$-E+$w0y zgUdMC9>P+F#A}nhME={(n)CcO=CxUUPxXy}?KuuN1=4EpH=nSJ+)*LNbfLwtXA7i< z3X;-5;bPQ&rj^;N9XOsoSJBT!i(-7evp42M_Yr0p*ox6zUICs@S2vzV&3f}k>xW?K zpWI1&lyT!oz~0L zJ44}==sVF${V?xK32fD-U|uvi+bNHq_6k0)mdcc9ZNA;2qEXxAp=HmYw#px-p-N8r zR@qh=&nCLsIlBQ5+*PRkMFx)5s4W{gwWvPU4%=g1i<{Twe1EN<_!7x&5b;cbrCc!2 z8n_M|tzWAOiz<|D=?27*O`Rs|N15xu&)z%KTb>PmD85Aak1p>9M~W5YkOILE)eii3GDQcTqkAe&m%6LEKS_G zTNKj9v1kba7iJta^#Ng=*in~bbK1zt*`zto#X%(O?B8<_@>%~Z%(VTvS*$fo9!l+K zPNV&)%>odLFKl1sPR>WD)63IGmjouAkO8;>``i(xpeA0@((>sM0Z_hd{O%~Sz3IvW z!NkZPUb9OQ=y15uLPW|m$M!@LpQGFYTml$ls#+D-ZZZY4x*_q;TWU20w~d6mf-5xZw4%4H!; zgfM-K+fz_VR#gBTPPH?ft5s4fT=#8dPo@)db-w3|HepwuPManulev$ft%~~E$Z%%! z9^#eU5sW9X-Uqu5-|-HS7Ag^|AcmeK@2Oy_qO($hOzF5~*3LD{l3ftnlkoGa=?(aO zDM;B1O{{ZC%F|dH%_~B*PvHW;C6QD_C+Mv#`klLQco0O6wUVEN9hw1wnp9mZoeC-A zomUfulUyRTo#5{L+Vzp+OHT!GwMo{Mnj3&$eEb!nAF{k=HIL_#5>x=6+sSqq$hpZ~ z6eD-hKP47L<&upZD!FAD!LW%jhCHLDAj**NEf5&VR}Q!YqDf`ZUc9>ea{d}-K zcVmCht!Pay>WJ9h$jnD3(5q;5fH)zzrQBv?{#|q4uc26W$O9g^=K1=VwhOxheCDmP zZy6R7KfauyO!&s-?3uwrfA_?33QN$zkHTZ)_T5)SDT4(^Sw#~h9$b$yC(h?{$4r*W z{A2_(MH;-gAn>u*@X%7!`rzA6^ura!I=CcS@eWAQ1dfPVa^%p>Z%LB#n0~us&sZK- z@*o(!KxmMCB{%eK5*pF{B{8pAZnC?>U4cdiY;(7Es)P1!MtqqjxQ=tJm3AP)2lW0) zQ_AhOFzeZ5Y+dP4%H43AN8PFOk(k&H+ssv}Wj^5b0`PU8eX4LrjTXyCw859UN!Yo1 zIv^20b=zv%B2}rdm!MPb=|0>P1Lz^SBE56N*5k)*kzDlbb4j&_DTWRaWT(dqOO*>^ zy4Wl+DFq;dK&CY{+Wv~{_>W)1n{&A);SE9s;XOXr6J@rOYd>FqFj6}}xEwujza*KJ zckM;(#e>4(WB+!{Fop>Ld}DlBW}G(vnD-@kOoei7@6i7%jN3pd-gmr-PoCT!N_lD3 zIW~4+&@9gY+0}UjYU0{q7b<$ozzd<6WGVhc!p^-Xg!JqH;C~cWI(fuARrbv7Fh@~?3dfQNJddUrXN!V()2+_d)>+0Me`gTYQy0of~Bmf264>iGR|D~$Z$+ur&_RR zZ12b8;MxZLC51_d4lOK!7Z7WHJofetzsSD-y*b)lUT(+l8dZ~}sH=OQ@yp9ehAw3f z*>7qt*lm)q^Wdij6Yahbu`&kxBhrCC-<)gS_xk)Nx;E1Ay4{jU?75|XjXU_!AJl>R z0Hp0+lsm;Eh64T(%Nr83QAm-ZGk^w1wO-2cY7Sq|=$!}2SPe6CG%IlG;kPQ$7bAa# ztb8xk)h%?PGfpZ_=}x5ec`5;iBF>qMmc~J1ms>`_{2S-$+6>TL$dVH6(k4&TL(Z0V zqwSkA+`1-Ey&TYeVAG{3V$2~qPPP**+w(g8(Pf zgCj?KD53!yhj)h4DtD@r-3)l69w41D^@n8S;cC>jZ%v52?q>$Hd1N@wuADm1_Vp^G z?9%TZ#p?^r!?mq%>?+%rN2r2^?(wa<3BRT7T|B$VoEsBdb#IEk=~GJ50BNXn!hy)( zX%k%x)z<YhePt`xYN z_@o1Jm|8=lhu)6;)JTT$3cT8K9MY%LNkfCrm32`SNOqUON_I}UbLTithA6_0#{5Jz z2{ip!-uJM_kBYJ!!WV2oV+g(CCif6a74<#^&LZNmW8`}p)xfJOhvh=q zKPnpyv>wf#`;S)zUzNXEF;J70l{%!l2?*7OT;Q(4h~M5=b21awFCJs)St1J7}5 zHh6O-?Gqd2k}CAxY<_>+x(UMN`HiH~Tjks&?2M~p-R45kM68n#k99921e^5wNeJ6= zbaagQ#w~yNxaUpCUjH4sh|OWTsD=bLZ^7YnD8{eHJp!%XkpRGq4+{9^`N9 zibn7nF*hi^GNOEGd3+abs*4Fz;W!QxL^wcF9+9(dCq?A(J=A>F?e=MLZYe-i0pYLm ze$$=Rww#2Wse8&`i9e_)jY2dgYspJ;a>;ort6J|kU{pRyPE)XA`ZhOjh>|O_#kTbYwM~9(NG`|q%ba?xG;+-nWUXEl7G4S%- zRBz&lxIUi&6b@X9r1x+67|0a%bnpB?^nC_#dH!vY-P0eh_d35>Y=oCMm%7WrTz7bn zK=ob58lAj^uJLoZfl#a@MSuKMS7_8rWy0}uDX9)xg5V7e9};%Cn*Wru`JeIO|Nr>e z;QoU3|5-Ody8cx+sgYIwTiujJ@>IA<>W6Koj|M?hKmYz+JSZ$zwqE*dcGC6*NZ6yu z5)6V#4d`7(LloTIiJ(lI1yB za?`d9WoS29x_ZZ|U5VKmo^ngpzKwM5tRZb85jSMd&RGv2{MxEVY5nAUwD)Ngh02Si zdA~i&v>|uSR%-o0ksjD?p3FlZ*=8*EzLW8D&&74NP#MteJveXLH}d0pHO>W4@TzT_yX1~;;7rFa2U$R<*#>Al2VMS$)qa}=q}wmfNAAR_*lWUo6h zHdJffQiu*1T zHPsI)n?fkE=I=-03H|m;k*d*TGf5d#EWZg!=qV~-5EglPXE|mYihG&}eh32= z_0rZSyB_5d~P?qYIN0H!|k5Lb=8#QiX1tk!z%Ma^E| zn`mJ{b^D3sT`B`9(P-KVaG@OVE}6f0Q9af^qLZq#Jb*B=4O!}XlQ=Vsw_6gG-gyNa z`xsF{{s}N$!}pzn{K#vWnSr2cGoTY=kWrPwCELzsI1t;(wzaj%(GE&!QVUm($lkx- z=8Oolg($H@>1gF;6fhrg-S#a5jSw@y<|sq9_%9=l;KuIL`Uw(tsA53k4)nV=Wr&g3 zZq+xG8pxED_gOubKA8XUHfoMrKw*3X_lNvhai5$E^xgy0CV@{t$l>kKA;h6wYqvw~ zQ<}|tL+h8@ad4(A+KZ*U$VmRkqnNPvb7vlP?9rPiajVw0h{HXO7+T~*_r1inCbx)t zo1oDv__@NEQ8KF;dGTbd$PjQZnF%QvCG&-6;iqotD&e#~>|prav7gxqMRAd?hbBHj zDTbNMQF`e{rXh9_TLPl^n*(!Ngx~kwr(3d5`mMWj?{2*GxK)TLx@~Ue zAyGQf8(myg4DG#;kiKDwKKOXN3$(t~XCX4ed*v|~XpY53sSIpoQ@VnFb7{t2WR~%~ za$<3%D1O|$NN7@T{jHfzLmT!$xI68r@K{L7S{`~-sdd7S9rs3!%mjZw!kCNSBVp%q zPLXBHs;j;%hXd)V?!%7t%Ekf8 z`L?Udwjaf1c<)^>R9M|EA1Q8s`G)T0wT{;X>t!<`p@ppFF~lbwmxZs7EZuMXYGrk6 zROsHPx0S0_*<*?e(-8Xs%=NLUpQuM+w`v>lW=WQ)2Yqatp&!toyVuxCtA6X$4Y;~2 zoNhY0al3qt8EOW$<5(J(3)DKm@AfH0HqTTH{(6aU2NmMtucW($5)cKg;5u(Vva`R{HNNALgcGIJMEX1&6#eu9+-3I2mWSi{`#c4*6U7)7uWJG zNdGQ>a?^3#sn{yzjgaLW`AJN)cqfG6dDUmQS;|~r1=q(`S$(Sy8!v1tH^*$xM+PS=a!nh3UL>8G^0 z73tjh$lUi5UbNjOr&w~;Ty*DkzSk7WBiH&ZEmD>lB4@v1@E{kYSkYtqd+H=IgVS~b z{`K20$4SR#6cU}N_^X=%Jzri!Q{w?D`gsLDmP&ucNTj|%uYHiTlE9k!L#H+PL=R_| z_>q^PJz#i$l?sra(gtHSCTse50#c+2wr1I7Kra=8tOa(zVj`quO&}J?a|;Hwg8^bM zGSSm8V64z%t22+k`UThN0$DW#ht%z8y$}O(N`HAq!Vc?q`qg_)jQD(t2nj(iTI!!HNg?t)g#1pA_j74$sAnMX5Z0#<6-7 zFvWbnOP<0(6*M<#GQXwYekDSCeMUa}Dl47!Q4E5(AlJZwknM2)U^b8CkzPCGO9uRG zyYpLih!H|UPr}Z~#ZdXeVgY(X0pE2~^FcEMNncmwSfXvFGw!$G$79JrJQlF35pjsV z2$t0{Uy44p+Iat0GaJ|;2A~}7BzfOS#HS%kQ4ix6EIzUMX47#lbf9R zrp=oJBTNfJ8(;JJGp^D&Uo&NheW$GwBF{a2$ef^Y@va0q7xlc`sAAgRg%#Nid=4PU z(+Wg#OT!A4u1!fW+>MM$*|b)UxI+o!#B{?Ee?)Ggb(|M4o7hAOS8T)KB8>AfWt%8j zxAiPU0Vqud0ef}aCLROzaect|Dz7oD`zdMdza&CKNz+9nrqxWd^-+4af7m&zY*mRY7irvCxquR>|`S~81^IK%k9anME&&CBR zuZ7HHo_Oz*M)9YFQ%7nuT3sqcdJvJd>@maW`JBiGb|pF2ss;Tt-*+K0JmBV)tw_Ou zfr`_qN-7&-Ma7yei&gg?@kW_pVa}%>w=M#Y2ukr*hE2JgAe{v9_#x5(bb>Q{J#0t3 zX7|Z~fcBm2s@-_*w0h-=Ac~|RGE*`U{9OB;K)u3cYtt$#m9^N8Wv!;Ij;X+tu(KdS zLV~KYVp5h|w*AHCzH3bC3PWsVWcG8*hOET%tP1T-?sIq}5@SXR+ zVt#x-nEznqaGT4(E+6(n`@H!se<*{5>Q|EzO*C~Cr$(8Ha$JB6-lq3~>cn+WzPBSf z>f5`nKF2k@%8%|TDi)*jQ5x1Yd`aoRm_Mzuw;9j-pPb{ z;sdW_P$15?ci2?t$-a0eqVYgfsqzEr$Y*Sa zC0+JP2y4J!ogQ0PSAQkW%vS~dCBFNme9UNUUQC0;ppw#cgz;&iEy*)ULcc$Yy;RbP}< zx;x1KR=6dJZHf@Xm1{aem9|nmcBQzOn6CRIMXgbMwMuHA_4eQUu9Wg$5?B9U)VUS~ zb5FlM^dt^DxQco|M`bSj;|KWRe^7lS6~{k3-#=cjgn#0xO!B|SQ#dQ$q@ViZyT%I6 zyFkn$tON0K&hU=f+0#z9(`^Bz44utfosMxI9VSVcV-{K)!pLr^ zZWiq^_@1^W*Q$sVF08?78 zC!h=B3ZN>%pkQ09rBKS)i3p3RfzZ=oB26{a$;Bx$Gh+8SBLLz_rgn718D zYYm!4hyV;Jm!fU@Z3eNi$Kd?>&FO)jkv*11h1+HqADLqMm{adm0l6vsq-Z;9N>dWu z#a}z`1Wzbuy7T6F&EjTnbVO`0>CSL+t#LFt!zlfEtOe#zfV~>L@WMj+c@~OO--*Z{ zoHL7Jtpm#TqAa!tj zRi-0>1`Q$MB7}0#pBwm+1bbb zL#G=Xt5QF^I;zxH)!=WTYvG8XFl-{jvu7gODz`y2cy3B*cnI5sw>`PgvhIW0H-x{u zHrGx3V-@<2WpER+%~-hnnO6L^WnB&Lb_Q{pg3QV1XyD2vhzg~&$o!`^v$p%cV4M^H z%}$B} ze2V>=&lDbF{sc0qT`rt|l|MA+2c}TixiwcHsE>r5`;pAt0yC?V&J^Cc_Fg;QdnbGO z4e~6hZafO)1BcRK$Y2PJ>#xa#a%z9}{w0(5bmS%EMKaGRrld~6IZ70O?yTRu@8GTo z@10o?&K4vejb;N+Mp4ZyEVi4U+~z<080vCb|IMLbyRI52z3p_(PJx?GQh3rgrc@(!R)3&)YJ$)O?aFqFUfyQwQB@20@vTAzqc@=w6 zb}d-=&SxKf60gns-;%xSBQfvPKL2<`nG8G)v=fx-w95Y9a*xo0aN0yCw?fqp0^&vif!sVWq-Hg z6Fz*w3w_E~cd+rZ8EEYJd6n^Q{)S@esq(-xgYaIS34u>VzAwTD)&fw#mHzLpRNr&_ z9UkOQp5k?fWjwJ`fay0=v{UPkTj%qyrBhMsW>vjrrn&i+8e%-DCyINhy2|b&*;%2$ zfCptA83KL}=F@2T#6*7n(1lfg{qyuLd4|HHNG7KcJkv#{9nI`#1nrA6i!uIN){QXRh0 zS6&k2i+~hfFMemCc`_2}een$R@zd>Zu|rM9Jf>%o61_6f$1LF|ECRX5sVpl3qE7cM z7IZb3?y#d6%yWs^y2l~ka?^D@l~=$Vk`FiV`SoFmTO*VDzn^m7;tVGa83~ULoU~Wn z3{~OSe@J!09(WZ&!mjz~e?v|%IKE4*6FYZk#&S0+Z{2fM&l>wj=2z%0NAY)XJF{=p}V`099p`&L8MDSLSkSjX$2%iIwS;Cl#rOA zOS(jm7Nomj_ITgVTKoTDuf6vBVZZPDe4{@6*0qM~yv{lfU;jE(V*NjN44v`Drt!B)KvJrrb7B|#Ga8}mjQTwmWV{^2{naQ3HEt?=)6>FhRj zCku%NQ;>h+mMhc%pcDOo5!YV!C}zInL-~Nx<6sD0y!m$X=<>*T{ifq!sNYm_{*@+= z^OJ`T`uP?Rp79pV$n&jlHQ7%i$kC?ym|pYLba_=*dU9!~z%jQJJ`jU`{Nqr}2`~HW zP@Fl-9*4mO8ORahCZkqy1mpz&{-bT|<=||4*7CK4v=K))z$~trHzK44C*Tg(l~Z&< z>*cT@zI_IqiF{T>m-v0E8{W1!CliUC-Syi0uQBgqJb$-{$6)q*9#}9bE5d=rbxVT} z-K#z*b_SWOo-d!KJ2>}ciJJDSa-?VxCl_R-?E zfn>?8vGy$DQ-GxY`-E>!o#WGPK@x^BJKmoOrLRMqut@u?ucy!0 zF$VzuoFbz=90-yu`AWrx6U*!{sIN)S9cL=}D$2-FjQG&Z^}RsI?mV@og`&9h*ALa7 z*Gx1)YyLed@+|j0;CQ+W;{IX=N;2rzujX0(28FoVV`ylh4c-qXI7^3e zW_iPd-)_E$Sa>{EjRsk2wd^PQ&Thsi8(@k=qf~U}O6=Un^WOKHv7}6retqfo^|rm5 z7#j;i69_1FPOuy^L$MQI0=Ue0Z-XpIxN?)dPw}fu$V<$g2A}$UrWpN=N{zPkfAnjBDEPcuoXb@@*_AHk@>Sk;S>W`c7)c zzjb&FUYx!o5kD^32GA3ep8+P|xB1Yh!1qD`|KaY-j>k7S{*wTjE*%s*iA9Xs@}+IvVJgIlHzCNVGo^Pj)|bmhmRBGbHPIJG_%r$iMH6@X*oE{dHrI!DVG9jWXO0IdAIVweGN)D@HY{Jl_O*M`HR zT4{D}PBC9_d@N#5tefVs%vqayyd%hP=x@Sx%u34B zbqJ_Eu)Q4|wt#FEUabVAn>26m*W1 zCG;oq7-g!gN`8_&@32EZ37*&Z<{jc>#KR)$>Zd^VJ!QmtO6Fy&8d>SPN%us$BB5~< zJ8C`>183a5&p%6(1CPluurBPI% zvi(Hp$@x?4uY#QwA`@u~g;^FXm9=LYAAKbo_kMo+@i2VBg$-wI{pT!L06nO)h(S4D z$HprThaE9NvRPlTkbu_Ri*Z{ycWuw}T%iyC8ux42Y^v4U_#ckRkEIM3yN&{Bu9r6~= zc0j`7RbwpozDt>Gk`<7|D_0HQVZC3>IT)7K9}-RaYNM`KG9*xy#04m6Y@O-0kxOea z<OtlVRtS&g9BDYw3D?r-;?9q{6ETct(> z_W;UgR0B08noJ(&DOtX+Kid{l#w#E-3$tGHRg(@JM~f}j6QAipTfz9($D0j4jk--@ z-f+1lc5^@wo;;Gc7}2W+V2JX5Yo}O6R_tnVO=9&w4P*gI?n38>efrqP~0FSZxi0d-=ds#0h<(@PDPTR$a7a`f1 zaTpd+sYAwyXK9aOry6DPm15KA-`SO(YxKZfNzWLyn7+>ZoO3|YM%xk>;$qPy{9%}w z3;|@vM}+Dne}dwoY6$@6RepVX5!(mzn#^oD8#3G&E9!9n{-T@;NxYt7f?pJUW6gV) zu5O+xs+3RuSnDFMZ9a)wsD$EfSDQUz+dFlVp0>v<0>F9yJQ{L@&wMi;HHwY))D6n% z^}whdNy+-TJiBLBL!FLYlTPgqWlb9;gZy*vvH%u=ERwYiFYpOb?BK4l26(v;H7QPa ziQo3GzG2g&uY9zQ>V$P#%H}5WM)q?zl5}PNd zFByU&A4O&6s#XiN37Rd*b$5AvCozdJ8T#Bjw2=4hP8~WZOvCNnrjmP>G1w$En*WB; zycfsiPvk-;_k<}+&_d&&@^91}2auY`vMzVqZd6>B&i3WBXnd^hXn*Z_i;d|LxT^&F z8zYa3hni&|ENrzPG%O`Q-#6j?N1apObWN?ABmw5{vhDeq@J9Si=Evjz+$v0fBOsS# zZQ~zajOi-Cc45u$6t{@ar4FAHb37^ioBn34Hsj;z`p`Ic~%La0;x1O{ez#s2O}u)-qiu4n z?IGE?^>#ytm%d$*-e_WR(H?p^a^z4yjREbf34BIc6`+OW+Fc4l=@t}kUhRP7?XC>q z($LW-2T zR;G4OS;q8$GbD6#I{xG{bVbZl)>~R()Hb?rAo)t04WIDmcK0952edg9JE`6CQI8W{ z#qh#6idG;A^Dyg*90P0t#|;pH-I~~uc2{UURSJUFQ!dd3uW%KpHrre!U1!cRTQy@b z5p5mj=yM8=8xqo&&98JI#Mj1Jm6prJ0cUcCl&$&@&T|de31G{|Pp)*)S0tiI%TX%r zOuA&*t;zx+s#FQ9)Vi0ikDz&R!AunYO09@f25(vd(_C18+4qJZZ1j|EE2uf-eZXe;YeO;tB(+*O@({ly^H%!moOfiHC-I& za3hxBW=+HNgs$H;Lz~KVV3auqcd2sjCd_@&LPKJF4lQ z-hof8MYzID#|uBxEfUz{Mnr1y?z`4b-o5B%qBy@Qhc!E6G5u+ zDy;hD)F_x_mq+%=NS2P!LCyW+m9j+7_otjjX9Ims;aJ6=j};bo1i1Ib0xG6lmP@v& z{A49)^|DZ|MEvwrls7mtFEnSoX%~bs=}?1j*VSzu_mAs524_6lgZTu-IeL7xM1*N= z1)58VlJ{;v&!ti9l(%y%<;LEcp%^N?vr$q^xI-Td47a%*KE|@LbbC+|I7g><^1nql zc`?pW=Q)z+#BjyC`9jtgVo#o~99qvPC<>~N)}7xJx^l0%^i&eQj;Q`q6u4UYUK^15xx#HD>~PT~$?l zLdzq2?P)9GL0;1j1q!yrJ5v@PgC}rn@Sh8LE=YKk5H^RKlC$g6$hxA~sfc;1r6ibw zA9r2Sw6cA#C-^1**@neuE?U?8=lG`&ao?DXf z1Qn6>6*?E3Pe)lmKAT&w%J041{Oq_>71xovk=C7v7O77= zi^$?;^b$=%eh4W=O0lQ)J?pN21pHfnm-6{Pi%tIznlAtQKmA_W8Q!7jpRdk7!_Q!H z7dv^+h|AY!?NW?Jxp#;hqWJYE%!_j;$0-T5di%es&!CDmcc_Vo6;y0`^mq4mG40=3 z2wdiWW0bAWf5s>%<R+&LISL5 zv~YB&|7z0Fe4j8nvT#&W=L4Qb_b_YkTk{SpHc}CF;5cKLqU!)fwc%sm1`*h%yXrFs z*Lkgx7?Gxk`AE)mHImo?l-S=Az*LZU(QO0_R@kk6Y9DtoVwmCCYzNjC?PV0~a2LzxrtFgh7d+r($ zwhMJbCq$_13GZ74Qpo8}r;5(5hV)I{{YDZ4ibi&BJNH#T(%Pu|8q zVp^s5x9ma0}zvBF>fSAj(*?7}}adtH?>DMF?Oxl@$=BgoG z%kOV9A$eNAJkNQ|2tn^jF{Q0V?{|g~ZlwSg3CjG(Wr?Dt{;MSo4n3lkb3ewxKTHv6 zv61o2g2jD_0v+h>3!^$b;&*E3+8xqr9{6HeDp*%~{lG$6*VAZ5w(iU8B7-CC__S>T zKN^Axi9}*noe@53T1I??26tssWpsKfik;yZu~<7T)d`Z~3APg&@wqB?X}xhht!79;ugQ~73nqu6K?1gmHKElJX(pw;yV+MM~HARD&`z^53X z@yjXXvp-;u)7PD;x6iJ_KEG3Kocg-pws9AdE*=B9lN10|6_=cm=z{goSRpSyYA!^M z;hJFNLuVQz?b#;BQ7;lEU%qJ~`;TF==CsUEej}Q38WcM*9J(#*i%!RLq=S*k<|-QZ zRTPQmiXT@B{px_z6ch-A=-gE~ukmPe?nG9-01lCk19Sdb$2 z8^N7%4b#6nF>HTh%!`nU_-exG-%GxDFALjMfqguTuIlo$E4()Mp{A61%!OTgA%%_u z17cl{8Dw}_89AWXNsP{Muhv!MExEngJFV4IMVCD9z#f5GNuK>X_o4ATX*Qn^f5%I^ zsXpKJxicvvbex#1ioIHT#dbnTz=oyI=Gu@i4U6ug4h#L9Z}!yP?18bd^|7HjQz*Ke z;{p+9OjI4&4QqP1VjNOUg}Xh)7TNu(SY=$%z84Z~Hm+HOpFMQc zcs!XFLpC?B&>WL=y?a)e%@vZsJD)kcWHhF5v}V6pJyY!o}GVZ)g6T>w#o zeK1-~SkP^8RlYR{5hHq*UeO&D%==CZ7z`bklmcK}1N4$IR#Ttha%%{Y9z8dg@6Z-i zc=@G6g6&;vw!b0XsL60u#O73r@H8=rivUerBrOo;wveNsIP}#+*ym1kTKDY?B1G8gsk`Lyuvhx*TLW=aZ3#dY`+m9zAb`ftZ>1;^j?Aw%Qd>YCX>kYH&zo5) zy&1qA61n;yc~Mu9?Wz+L@Xaz1KDX5s^E-R>GE zy|)AQF^2p1Zhlx1hBRxnL9EbI@N@yP=LuznR1Pwh^_bvVi z#ZE39V?d+dY!b|x=UARiA2!lrpI<*Zs>Ek()DHwlzKFtsp! zF*!0*^V}9*?|Y@jvymJ`#r1J8@9A|D{25KKQ+FD|#S;q9_)*)QlDhB)Ep;7buHojA zt=5}t2f|Dpsb|+mGMqeF6v;uZ-bG{84`(X5o6J5HezyYs8qvA_l*D@VM(Qe_KGADs z25cDf*!z|&y+`M9EA!rmO!!@7Hd3HGOlQKxvON0^vcgq!C++L@ya~KlN=+yE6FO2e zcz2W}P76ju;H*^RDxsr8UN)wkMl6PBT^SPa!yaVxuGQoG0VabEi7tuwwN~EH{#uBq zhEiYo7t2RO5^!&6v2Rs)kv>P2MySs_rE=m2NL=Yi`ix^#8ZNH$N=Gfzq?6M?hNa4^ z&(#YHOxJVUJovCSs$cjn*4mPg|Xj3ohYE|4WdEu|{OuGgJeou09^ij8>GJ-~ zIRcmeGv_FxIMN!yZJ@8S_{cgoeD)`L|ANBghS_p%g6@2S%JSU9*yTosVpg~=k@<4t zj3kp7GpaPI0N(=_y%i)wGTx1TJTcB_F8emT+;(mCUdypzY|@YztZ=#wT|L9CW8i)U z1LH&DU^4xuF+d>z2hit_^%?Pia6U1}v)PtO-WP!Hb-bfFI6gNgi6H!%|A9H})IX=J zxfN3y9T{|mI(KTG#qMfAoHX$H#7jgHqe6#lHFR%-vRSB#5i`cpMkM_i{@s)CHy=uw z5(X{&p07&@ru+m71<0tTMGvAz!J>0afS1WsObqDIPo!YXlVlrF!59$RV6d3@E$)2aPdMhCgsgsAiFJ2LTdzr1sc1Pw3@^wV9IMvHqZM&v)5I-JnwWs zn^c=sYWND&Ux@0D^1&bO>P+bs=bypgwtmuJHE1#(^swJvl!Nxve!d#F*^Rq414U`OgmJ)Awej1+Lh+_An2HGluYxlqjsf5PJZEC4HNtlp-hc6w-=ypa>I0Z8jX<Fn?ds`$t%~JCA#U$NU`StE31yxtB8cttTc_vsw$$>2l%D-V-+kq_yO;e_#M_Y1; zIQ~syF90xUlp1t;;K;xNIKh{&8kE`6ux&-idHYp27}nDY(4{21td9b4-WAuaquA-} zsT9kiBdKEQppJ-q38FzEhk;68#^e}Jq7bASEzAbJSYNm(>WX;Vhp2SX)(%Nl)xS)Y zVlx|-9VR@IEtp2(Jd%m+OF3o2HYvqe0aX`0 z)1o9F8j77k+cmhz{?5KRDdCEh6~o&4K8(texe-rl4YT8lHx)Bn{Vsx)fHd4zt#BD+ zheIfNPK7XQLfr*rl+l1%nTt| zx2XoRvKb9?`!f{6@@h%5C@P05g!eja^!YblSF@IFWHDbVJZhh1{{%$~L^YN15rqO=~iIE|?f_)k?wr z#vB`m)Eb;7yru%iru~UxCniF^TOEVq@7tukJiK62PjFIzNxeo*Qnf{fC*-13QI(L( zg%3!@Ojn-fG%Uv|A(S=ZUFXqSrLukK(1P^SS1e+Y_tI%iD0w6qjfeBo)frc*qIcIj zX(=>!naCM2S5gi66Xz__*0&bp*T^aLBL(@`$qtoRk#U>OhalRay4p1%+wv9< zwi7!6I^%6gMNFhEvI)6M_)YI_jR{Raw+VUU;Moa;Vwz-8U58$EetgtpjA9o~`~O*7 zeaigc^7ejEe0!stmH*7pUbGWg_(R40db@b5^va9r6ruY!#2&?<;_5$IuNW2o#?=(P z|BS0B9lgh_b@nD*N;^J+mJ?T<0&Z9?LvvZOR`@%uEUY&-m&8vVx3jdnl3ahjLB190 zqkk7<8&B90mDKIm$HwSNpl{h0Vek-bW;l*$3o|CsFt<*vPqpyb{ZT*yXcxdw8tF8scy4+#$Olx$~w+2B}ol_PlcIOL^G zhbRsH9v85$&>J$dZAJXwY;~QaYf2azs)v7slE0 zjSJK__yJwYKK4v>8tTw^XB@RWtxx|l8p^5Y*M4^(=uH;!f`vKJ7&Ame&=3`n8kiR{7`NpVZNX@$MDL zeRS9>WaLQrkX>;MSa3y85W+#F-k{-RlpLm{uzrSGYRjZ!eD#AkY{Q;A0(nN4{3i5? zXe;T~9Fngn%6>tCKFcF+jvye#{ij#cO|AFN(gRMYuuGDd*W#DCS;1H?k^vMuWhRw& zQ_(4DT3jeTv_GdUdYLS&6jXZ0N_53O;#mv`*_Hs~gJ!y)R}kyf$%!Q-9oZCQk_>P% z9hg4I>qi^9ZhJ%}#^g~ea1W~A5N^;U$AG<#J0yVVS(GUNG$T4K1GD>R@Szx$(qb^{ z21dU9@G}wqG3$<&aHPcdh!;=i7duaXHjXo%AiE!R%x-qk1|pL?q|t2ki&l&r{G$Pr zt8Cgw(}YKsD?GnNbj~MO>Yi;%R@CIhJk-1?L+NjjaO7_E=ut_#9hvmYI`%E>RlmRL z5QJ2;?$kK*d@<*!{!}No-62r=gE+d2$fUYR&t#{DsyMU;vvv4q!o)U8v&vK4%PLS}I$kU8(kkEfXv*G4s)MP_8fTx$0T$5DlN8{ILyV~to; z&&}oPwb~$0&(`)D2g6(FH4K!Ca@(a2EFFF%T>tG6%0+z@#r}xwe{sL}Le+LBVw!>& z*Spn`RpJWQJx_wQHYo?M$NeC>$WGiRMEM;zBzbiA$PEKb>8h`a6+7>71FOzn|ntn;xU59j_@$1-nTf6iy4at0D zC=|v|va+k!*J!;hs0(cpt(n}YjUi5Rb#2)WAyhm-Ok^s%5^F^rZ~_2303yg+FN|bN zGop{t!)mTvcw3dWf^A-WOK3VF~zo3rxo9R5cs^8K4L>%aL9iyqh;4*$f9wB7o zx;?7ydb-V7!YEK&P}qZVe|M=kMyXA8b+3|UMu3dyVa*LsspVx8U!mCPOl*nAMTyEg zM{^@%H|I4hUgSe_uXr+L257pOuv1ydg6L425Kjpw*eCt>*@e;s?vtL!I@1x~VK~in) z>ifsJBB<{{*HNfNLdhTX#n+Y8EMzfQoQnRHB^lYF=iBSqkH6i6v*oz(y2*%&{PJDJ zWzPjGsaz3u9G$D0m=OC0PmD|o6g$14+S+#d{V)K=d=c_U@#uYa-3LWG0F*j1XAoEC#(mBe^VWby_I*6eVt^3r*#V z68qVZuySgTj2?xLD(Did2&6#=Ul3tPU<>2#)FuqxqYuf-Q!fS!q!W{4m)l1r+l^~> zfm|P~=#7-6ItuJ|^3E5}&jvf1<^+?Nadh=uxH|I`{iBiCnUBzS=b4X+eP^QxVuw)d z45Sw*@oRj}q8GR0E+8P7UM4QUiFKvh&>6YT&(tOYZ?qHFBzBfJp3Ww6Z4ANcqV-P( z2k#o;n`4tnhAk`0$~-bLtiR=0XHG+S+dDN=@hAiM82gXE(J>0$qtk~&M03)E1MqP# zdugb9U6HqT@=aGB@@9d*Kf4(N3m5jCPB+o;fEkt3Hx6gy)%w@5Z*It~X2bOm5_QQ`qpVsO@> z!YxTfdSH1xsR;%`1*zTmp^1cJ-XgZ*^=5}W-guKRkpJ0rKxFjpjTBt*htILxa>!%= zX@g=6gS(WS@>r*wYYGQi_N@9dABp z8d{Jw#clA`HpU?sdrVZMv+!)Q}CVn(SYQ3?mN05-3GIn^Dh*yapGT(FbdDZM_^Ky`hf)l#> z7Z>CNZwS99e#A8~ZFWQ2d@}wN6>fsz-XdKS?pBd^bL7xZ1+%E%)e+U(`S4<#Jp(6C zBmBh8Y*tV$-6`+xvjOm-#`cY1txXR_$)YFULVEy?j_Cv$RZBgJodjc|wt5hUA`Lr# zRi1XWN1EHvdMI){A}{Nwh0^t>-Wulau{s}_FyXPbq`8-Khw0=7r4srKA6)2p@wO$b z*&MSP$o<{Yl$sSQZ0d^|#m?<`8fRYxCUms9@Rzz7Za5Q(nb&lys8@ZAOyxIiukL;a zB#>m7=pOMuxi`^Y%DJB0sZiN-#GIH$X%i*h8NrxR-&`$F3Wvw@NaL?7 zSDwb@mEqlyYviTCC>|+)dS!}YCk-Pv9iMAsz1bXHyD0NC`tu|)_%$)hP_p^*C~KNn zP#Wg^+!nj=YsM{*q@r3U|E5&JttC;0g4D|dn7_c6j!3Cg3Fk3iuk0T^#@xVG1)SyU z!Q{qpI^IxOt?=VzOs#_288ps2l5tKCQ>??~I&-5Ot)hrmFm93AP#h?_+| z%4kCEmU?~rKxQm$iv*zX^M>e_yy(%C(UH#^+cgOOi|qLut`vK1Zz4`O1W3}wuBRuQC zeyHwCcJEW9&0|(^=?fjX!Hn_Gy7-}+jP~pZtMm{;1voiuJxv}OpU^#?Js=6MYwN_bOyei#1Y->SHiL#Z;>R+%udLUL!CPX;sV%emnr}uZqUI*JrCABX~&g; z5zsbfZkhfqHhn97Qk+;!`>{1nYA$hFXe{-+23cM7FY@x(eLJ-wE$r2E114HI>Rhf> zF;NebyQ^WE*-z)v(xiA&FMnQ>;J;~o-C75U3zh!OUul0wVnv2gMD-y!8MeAz;SB&q z->sv36rKnwnhyrRbv^)*WQ+phtR3{ls00kvEomw(xdPN3*MM+Yj2h<)+-LK)kw&R2E7+MR?o4u}k9EtgsBIiS`#wj@LnrY!s1&wYjzyEpsn1 zt_9Cm7tLYbpxJrAvHFNNYRPhxZ6^RqMGr#wc%YNASD>95&z#OWYhpb^+uXgM*(F2G zFnlUwjCitbDFihRiAMs@irg&-tSnS|Cl_l-^)6T)QSdqRWirs0g>t#7S=Mbs>EF{pboh@X~ zYv{zvz;^Sb%_g*pdoG=u)RpSCl0ev@X#qH6C`N4O{t;x7m)Mfi@zUfEGFrNN;mgUJ znqxT=^b$L&-=#qYp|*8i`O{Y1mTt^V3@CP*Xe9{(lV?MB_0ekg`4*1&cqm%U2Wq z{i#xUZzJkr;=xyoL*LpjdynhANLNt%vh`KOSKjZD56{$oC@4rJ#@%k1Ufn)oV*}jZ z`OKa9kwh%%K(s%!Ut$f{kM4m$dBdj(@nQ0#vJ>~@YFbNN5s55!Cp=F>r4o*^!tMo8 z5)5L=-UhPR{K0wM%r^KN0D#boxJQlz(e_Cva3>8>LS4 z-&Tj5@xN_fTk-FnJa7fq`QJCeRN;TV379C4<|uJnK1C0N;2QRVemgQG+VkBndST;EMdSLMx)}(7*}UV2*rQiqIzY-BeGWn^pFWe1D=I98cxoe( z?Fcb_P;xW<*WZ~+Q71CV@*;)==#ZEMbf$q7)aRYSYpS@g8lR8RaCb+!2mS@Vys8yt zd14JTjsiHyiXbpb4?yp+wE@l z&`Pv%L!5~B_@nnkVsMK_5t*b%vgR|79qg}5VTY}+J1LEX>=nr%lycc8_&rDkW1RmYrHDp-$R z;x#(bDQ`{k3O8$2J%BqDZ$$BVqjJO5zw;9HZi5CJTB4Hq;@bFwkD8moD@IroiXu?< z9CsTe_PD{(n~7L-E*{bqg-!HeCVYvstAXoh1xPJrALaQ@2#TFp70W*-m1-SmfHL#K zsQIBX5?}hoklyUXctkLA#$eeNK}FGOQYV(K`cqG@=>Z2#f0D*i{)&sk0o8rpCYXeP zJ4gpKXvh23NR*EZu>4~%b%9S2jCAvx(V2HLKs#aUNGO8O?lOY#zKn9 z)gl~V&;VAvOwo^!HXsL}6#@0JrK1u7mSlDir>AX#MCO53`_SSEEGCIjK&kS!Cq7U( z=*%hLC$bgZ)I1BR|ND+4*PSe0l7b=ov<%|@2fNXdMd@}Fk4>d zU6c3DHQ@?U{I2xzAH_|Nlrzod

    x&}NePIa&+0 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

    3!zB!DbA5@A0)0$|J8g!BQ{+JLe91Qm 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 literal 0 HcmV?d00001 -- GitLab From be3fce4193718d162b971b5d36ee4abfc95ef24b Mon Sep 17 00:00:00 2001 From: Ady Abraham Date: Tue, 1 Dec 2020 20:43:34 -0800 Subject: [PATCH 312/790] composer: fix 2.4 vts for multi-display Fix the way the test handles multi-displays by caching all the hotplug events received when registering the callback Test: VTS on Pixel 4 Bug: 174174253 Change-Id: I9a69b18bcef0722e603f2ca58cfbd176ea60f5f2 --- .../VtsHalGraphicsComposerV2_4TargetTest.cpp | 358 +++++++++--------- 1 file changed, 182 insertions(+), 176 deletions(-) diff --git a/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp b/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp index e6ecf933b3..f6b70e691e 100644 --- a/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp +++ b/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp @@ -57,6 +57,25 @@ using V2_2::vts::Gralloc; using ContentType = IComposerClient::ContentType; using DisplayCapability = IComposerClient::DisplayCapability; +class VtsDisplay { + public: + VtsDisplay(Display display, int32_t displayWidth, int32_t displayHeight) + : mDisplay(display), mDisplayWidth(displayWidth), mDisplayHeight(displayHeight) {} + + Display get() const { return mDisplay; } + + IComposerClient::FRect getCrop() const { + return {0, 0, static_cast(mDisplayWidth), static_cast(mDisplayHeight)}; + } + + IComposerClient::Rect getFrameRect() const { return {0, 0, mDisplayWidth, mDisplayHeight}; } + + private: + const Display mDisplay; + const int32_t mDisplayWidth; + const int32_t mDisplayHeight; +}; + class GraphicsComposerHidlTest : public ::testing::TestWithParam { protected: void SetUp() override { @@ -67,15 +86,19 @@ class GraphicsComposerHidlTest : public ::testing::TestWithParam { mComposerCallback = new GraphicsComposerCallback; mComposerClient->registerCallback_2_4(mComposerCallback); - // assume the first display is primary and is never removed - mPrimaryDisplay = waitForFirstDisplay(); + // assume the first displays are built-in and are never removed + mDisplays = waitForDisplays(); mInvalidDisplayId = GetInvalidDisplayId(); // explicitly disable vsync - mComposerClient->setVsyncEnabled(mPrimaryDisplay, false); + for (const auto& display : mDisplays) { + mComposerClient->setVsyncEnabled(display.get(), false); + } mComposerCallback->setVsyncAllowed(false); + ASSERT_NO_FATAL_FAILURE(mGralloc = std::make_unique()); + mWriter = std::make_unique(1024); mReader = std::make_unique(); } @@ -83,6 +106,7 @@ class GraphicsComposerHidlTest : public ::testing::TestWithParam { void TearDown() override { ASSERT_EQ(0, mReader->mErrors.size()); ASSERT_EQ(0, mReader->mCompositionChanges.size()); + if (mComposerCallback != nullptr) { EXPECT_EQ(0, mComposerCallback->getInvalidHotplugCount()); EXPECT_EQ(0, mComposerCallback->getInvalidRefreshCount()); @@ -97,10 +121,10 @@ class GraphicsComposerHidlTest : public ::testing::TestWithParam { // display. Currently assuming that a device will never have close to // std::numeric_limit::max() displays registered while running tests Display GetInvalidDisplayId() { - std::vector validDisplays = mComposerCallback->getDisplays(); uint64_t id = std::numeric_limits::max(); while (id > 0) { - if (std::find(validDisplays.begin(), validDisplays.end(), id) == validDisplays.end()) { + if (std::none_of(mDisplays.begin(), mDisplays.end(), + [&](const VtsDisplay& display) { return id == display.get(); })) { return id; } id--; @@ -127,6 +151,30 @@ class GraphicsComposerHidlTest : public ::testing::TestWithParam { void execute() { mComposerClient->execute(mReader.get(), mWriter.get()); } + const native_handle_t* allocate() { + return mGralloc->allocate( + /*width*/ 64, /*height*/ 64, /*layerCount*/ 1, + static_cast(PixelFormat::RGBA_8888), + static_cast(BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN)); + } + + struct TestParameters { + nsecs_t delayForChange; + bool refreshMiss; + }; + + void Test_setActiveConfigWithConstraints(const TestParameters& params); + + void sendRefreshFrame(const VtsDisplay& display, const VsyncPeriodChangeTimeline*); + + void waitForVsyncPeriodChange(Display display, const VsyncPeriodChangeTimeline& timeline, + int64_t desiredTimeNanos, int64_t oldPeriodNanos, + int64_t newPeriodNanos); + + std::unique_ptr mComposerClient; + std::vector mDisplays; + Display mInvalidDisplayId; + void forEachTwoConfigs(Display display, std::function func) { const auto displayConfigs = mComposerClient->getDisplayConfigs(display); for (const Config config1 : displayConfigs) { @@ -138,88 +186,44 @@ class GraphicsComposerHidlTest : public ::testing::TestWithParam { } } - // use the slot count usually set by SF - static constexpr uint32_t kBufferSlotCount = 64; - void Test_setContentType(const ContentType& contentType, const char* contentTypeStr); void Test_setContentTypeForDisplay(const Display& display, const std::vector& capabilities, const ContentType& contentType, const char* contentTypeStr); - std::unique_ptr mComposer; - std::unique_ptr mComposerClient; - sp mComposerCallback; - // the first display and is assumed never to be removed - Display mPrimaryDisplay; - Display mInvalidDisplayId; - std::unique_ptr mWriter; - std::unique_ptr mReader; - private: - Display waitForFirstDisplay() { + // use the slot count usually set by SF + static constexpr uint32_t kBufferSlotCount = 64; + + std::vector waitForDisplays() { while (true) { + // Sleep for a small period of time to allow all built-in displays + // to post hotplug events + std::this_thread::sleep_for(5ms); std::vector displays = mComposerCallback->getDisplays(); if (displays.empty()) { - usleep(5 * 1000); continue; } - return displays[0]; - } - } -}; - -// Tests for IComposerClient::Command. -class GraphicsComposerHidlCommandTest : public GraphicsComposerHidlTest { - protected: - void SetUp() override { - ASSERT_NO_FATAL_FAILURE(GraphicsComposerHidlTest::SetUp()); - - ASSERT_NO_FATAL_FAILURE(mGralloc = std::make_unique()); - - const Config activeConfig = mComposerClient->getActiveConfig(mPrimaryDisplay); - mDisplayWidth = mComposerClient->getDisplayAttribute_2_4(mPrimaryDisplay, activeConfig, - IComposerClient::Attribute::WIDTH); - mDisplayHeight = mComposerClient->getDisplayAttribute_2_4( - mPrimaryDisplay, activeConfig, IComposerClient::Attribute::HEIGHT); - - mWriter = std::make_unique(1024); - mReader = std::make_unique(); - } - - void TearDown() override { - ASSERT_EQ(0, mReader->mErrors.size()); - ASSERT_NO_FATAL_FAILURE(GraphicsComposerHidlTest::TearDown()); - } + std::vector vtsDisplays; + vtsDisplays.reserve(displays.size()); + for (Display display : displays) { + const Config activeConfig = mComposerClient->getActiveConfig(display); + const int32_t displayWidth = mComposerClient->getDisplayAttribute_2_4( + display, activeConfig, IComposerClient::Attribute::WIDTH); + const int32_t displayHeight = mComposerClient->getDisplayAttribute_2_4( + display, activeConfig, IComposerClient::Attribute::HEIGHT); + vtsDisplays.emplace_back(VtsDisplay{display, displayWidth, displayHeight}); + } - const native_handle_t* allocate() { - return mGralloc->allocate( - /*width*/ 64, /*height*/ 64, /*layerCount*/ 1, - static_cast(PixelFormat::RGBA_8888), - static_cast(BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN)); + return vtsDisplays; + } } - void execute() { mComposerClient->execute(mReader.get(), mWriter.get()); } - - struct TestParameters { - nsecs_t delayForChange; - bool refreshMiss; - }; - - void Test_setActiveConfigWithConstraints(const TestParameters& params); - - void sendRefreshFrame(const VsyncPeriodChangeTimeline*); - - void waitForVsyncPeriodChange(Display display, const VsyncPeriodChangeTimeline& timeline, - int64_t desiredTimeNanos, int64_t oldPeriodNanos, - int64_t newPeriodNanos); - + std::unique_ptr mComposer; std::unique_ptr mWriter; std::unique_ptr mReader; - int32_t mDisplayWidth; - int32_t mDisplayHeight; - - private: + sp mComposerCallback; std::unique_ptr mGralloc; }; @@ -230,9 +234,10 @@ TEST_P(GraphicsComposerHidlTest, getDisplayCapabilitiesBadDisplay) { } TEST_P(GraphicsComposerHidlTest, getDisplayCapabilities) { - for (Display display : mComposerCallback->getDisplays()) { + for (const auto& display : mDisplays) { std::vector capabilities; - EXPECT_EQ(Error::NONE, mComposerClient->getDisplayCapabilities(display, &capabilities)); + EXPECT_EQ(Error::NONE, + mComposerClient->getDisplayCapabilities(display.get(), &capabilities)); } } @@ -241,38 +246,40 @@ TEST_P(GraphicsComposerHidlTest, getDisplayConnectionType) { EXPECT_EQ(Error::BAD_DISPLAY, mComposerClient->getDisplayConnectionType(mInvalidDisplayId, &type)); - for (Display display : mComposerCallback->getDisplays()) { - EXPECT_EQ(Error::NONE, mComposerClient->getDisplayConnectionType(display, &type)); + for (const auto& display : mDisplays) { + EXPECT_EQ(Error::NONE, mComposerClient->getDisplayConnectionType(display.get(), &type)); } } TEST_P(GraphicsComposerHidlTest, GetDisplayAttribute_2_4) { - std::vector configs = mComposerClient->getDisplayConfigs(mPrimaryDisplay); - for (auto config : configs) { - const std::array requiredAttributes = {{ - IComposerClient::Attribute::WIDTH, - IComposerClient::Attribute::HEIGHT, - IComposerClient::Attribute::VSYNC_PERIOD, - IComposerClient::Attribute::CONFIG_GROUP, - }}; - for (auto attribute : requiredAttributes) { - mComposerClient->getRaw()->getDisplayAttribute_2_4( - mPrimaryDisplay, config, attribute, - [&](const auto& tmpError, const auto& value) { - EXPECT_EQ(Error::NONE, tmpError); - EXPECT_NE(-1, value); - }); - } + for (const auto& display : mDisplays) { + std::vector configs = mComposerClient->getDisplayConfigs(display.get()); + for (auto config : configs) { + const std::array requiredAttributes = {{ + IComposerClient::Attribute::WIDTH, + IComposerClient::Attribute::HEIGHT, + IComposerClient::Attribute::VSYNC_PERIOD, + IComposerClient::Attribute::CONFIG_GROUP, + }}; + for (auto attribute : requiredAttributes) { + mComposerClient->getRaw()->getDisplayAttribute_2_4( + display.get(), config, attribute, + [&](const auto& tmpError, const auto& value) { + EXPECT_EQ(Error::NONE, tmpError); + EXPECT_NE(-1, value); + }); + } - const std::array optionalAttributes = {{ - IComposerClient::Attribute::DPI_X, - IComposerClient::Attribute::DPI_Y, - }}; - for (auto attribute : optionalAttributes) { - mComposerClient->getRaw()->getDisplayAttribute_2_4( - mPrimaryDisplay, config, attribute, [&](const auto& tmpError, const auto&) { - EXPECT_TRUE(tmpError == Error::NONE || tmpError == Error::UNSUPPORTED); - }); + const std::array optionalAttributes = {{ + IComposerClient::Attribute::DPI_X, + IComposerClient::Attribute::DPI_Y, + }}; + for (auto attribute : optionalAttributes) { + mComposerClient->getRaw()->getDisplayAttribute_2_4( + display.get(), config, attribute, [&](const auto& tmpError, const auto&) { + EXPECT_TRUE(tmpError == Error::NONE || tmpError == Error::UNSUPPORTED); + }); + } } } } @@ -283,11 +290,12 @@ TEST_P(GraphicsComposerHidlTest, getDisplayVsyncPeriod_BadDisplay) { mComposerClient->getDisplayVsyncPeriod(mInvalidDisplayId, &vsyncPeriodNanos)); } -TEST_P(GraphicsComposerHidlCommandTest, getDisplayVsyncPeriod) { - for (Display display : mComposerCallback->getDisplays()) { - for (Config config : mComposerClient->getDisplayConfigs(display)) { +TEST_P(GraphicsComposerHidlTest, getDisplayVsyncPeriod) { + for (const auto& display : mDisplays) { + for (Config config : mComposerClient->getDisplayConfigs(display.get())) { VsyncPeriodNanos expectedVsyncPeriodNanos = mComposerClient->getDisplayAttribute_2_4( - display, config, IComposerClient::IComposerClient::Attribute::VSYNC_PERIOD); + display.get(), config, + IComposerClient::IComposerClient::Attribute::VSYNC_PERIOD); VsyncPeriodChangeTimeline timeline; IComposerClient::VsyncPeriodChangeConstraints constraints; @@ -295,12 +303,12 @@ TEST_P(GraphicsComposerHidlCommandTest, getDisplayVsyncPeriod) { constraints.desiredTimeNanos = systemTime(); constraints.seamlessRequired = false; EXPECT_EQ(Error::NONE, mComposerClient->setActiveConfigWithConstraints( - display, config, constraints, &timeline)); + display.get(), config, constraints, &timeline)); if (timeline.refreshRequired) { - sendRefreshFrame(&timeline); + sendRefreshFrame(display, &timeline); } - waitForVsyncPeriodChange(display, timeline, constraints.desiredTimeNanos, 0, + waitForVsyncPeriodChange(display.get(), timeline, constraints.desiredTimeNanos, 0, expectedVsyncPeriodNanos); VsyncPeriodNanos vsyncPeriodNanos; @@ -309,7 +317,7 @@ TEST_P(GraphicsComposerHidlCommandTest, getDisplayVsyncPeriod) { std::this_thread::sleep_for(10ms); vsyncPeriodNanos = 0; EXPECT_EQ(Error::NONE, - mComposerClient->getDisplayVsyncPeriod(display, &vsyncPeriodNanos)); + mComposerClient->getDisplayVsyncPeriod(display.get(), &vsyncPeriodNanos)); --retryCount; } while (vsyncPeriodNanos != expectedVsyncPeriodNanos && retryCount > 0); @@ -322,7 +330,7 @@ TEST_P(GraphicsComposerHidlCommandTest, getDisplayVsyncPeriod) { timeout *= 2; vsyncPeriodNanos = 0; EXPECT_EQ(Error::NONE, - mComposerClient->getDisplayVsyncPeriod(display, &vsyncPeriodNanos)); + mComposerClient->getDisplayVsyncPeriod(display.get(), &vsyncPeriodNanos)); EXPECT_EQ(vsyncPeriodNanos, expectedVsyncPeriodNanos); } } @@ -347,31 +355,34 @@ TEST_P(GraphicsComposerHidlTest, setActiveConfigWithConstraints_BadConfig) { constraints.seamlessRequired = false; constraints.desiredTimeNanos = systemTime(); - for (Display display : mComposerCallback->getDisplays()) { - Config invalidConfigId = GetInvalidConfigId(display); - EXPECT_EQ(Error::BAD_CONFIG, mComposerClient->setActiveConfigWithConstraints( - display, invalidConfigId, constraints, &timeline)); + for (const auto& display : mDisplays) { + Config invalidConfigId = GetInvalidConfigId(display.get()); + EXPECT_EQ(Error::BAD_CONFIG, + mComposerClient->setActiveConfigWithConstraints(display.get(), invalidConfigId, + constraints, &timeline)); } } -TEST_P(GraphicsComposerHidlCommandTest, setActiveConfigWithConstraints_SeamlessNotAllowed) { +TEST_P(GraphicsComposerHidlTest, setActiveConfigWithConstraints_SeamlessNotAllowed) { VsyncPeriodChangeTimeline timeline; IComposerClient::VsyncPeriodChangeConstraints constraints; constraints.seamlessRequired = true; constraints.desiredTimeNanos = systemTime(); - for (Display display : mComposerCallback->getDisplays()) { - forEachTwoConfigs(display, [&](Config config1, Config config2) { + for (const auto& display : mDisplays) { + forEachTwoConfigs(display.get(), [&](Config config1, Config config2) { const auto configGroup1 = mComposerClient->getDisplayAttribute_2_4( - display, config1, IComposerClient::IComposerClient::Attribute::CONFIG_GROUP); + display.get(), config1, + IComposerClient::IComposerClient::Attribute::CONFIG_GROUP); const auto configGroup2 = mComposerClient->getDisplayAttribute_2_4( - display, config2, IComposerClient::IComposerClient::Attribute::CONFIG_GROUP); + display.get(), config2, + IComposerClient::IComposerClient::Attribute::CONFIG_GROUP); if (configGroup1 != configGroup2) { - mComposerClient->setActiveConfig(display, config1); - sendRefreshFrame(nullptr); + mComposerClient->setActiveConfig(display.get(), config1); + sendRefreshFrame(display, nullptr); EXPECT_EQ(Error::SEAMLESS_NOT_ALLOWED, - mComposerClient->setActiveConfigWithConstraints(display, config2, + mComposerClient->setActiveConfigWithConstraints(display.get(), config2, constraints, &timeline)); } }); @@ -382,7 +393,8 @@ static inline auto toTimePoint(nsecs_t time) { return std::chrono::time_point(std::chrono::nanoseconds(time)); } -void GraphicsComposerHidlCommandTest::sendRefreshFrame(const VsyncPeriodChangeTimeline* timeline) { +void GraphicsComposerHidlTest::sendRefreshFrame(const VtsDisplay& display, + const VsyncPeriodChangeTimeline* timeline) { if (timeline != nullptr) { // Refresh time should be before newVsyncAppliedTimeNanos EXPECT_LT(timeline->refreshTimeNanos, timeline->newVsyncAppliedTimeNanos); @@ -390,29 +402,25 @@ void GraphicsComposerHidlCommandTest::sendRefreshFrame(const VsyncPeriodChangeTi std::this_thread::sleep_until(toTimePoint(timeline->refreshTimeNanos)); } - mWriter->selectDisplay(mPrimaryDisplay); - mComposerClient->setPowerMode(mPrimaryDisplay, V2_1::IComposerClient::PowerMode::ON); - mComposerClient->setColorMode_2_3(mPrimaryDisplay, ColorMode::NATIVE, - RenderIntent::COLORIMETRIC); + mWriter->selectDisplay(display.get()); + mComposerClient->setPowerMode(display.get(), V2_1::IComposerClient::PowerMode::ON); + mComposerClient->setColorMode_2_3(display.get(), ColorMode::NATIVE, RenderIntent::COLORIMETRIC); auto handle = allocate(); ASSERT_NE(nullptr, handle); - IComposerClient::Rect displayFrame{0, 0, mDisplayWidth, mDisplayHeight}; - Layer layer; - ASSERT_NO_FATAL_FAILURE( - layer = mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount)); + ASSERT_NO_FATAL_FAILURE(layer = mComposerClient->createLayer(display.get(), kBufferSlotCount)); mWriter->selectLayer(layer); mWriter->setLayerCompositionType(IComposerClient::Composition::DEVICE); - mWriter->setLayerDisplayFrame(displayFrame); + mWriter->setLayerDisplayFrame(display.getFrameRect()); mWriter->setLayerPlaneAlpha(1); - mWriter->setLayerSourceCrop({0, 0, (float)mDisplayWidth, (float)mDisplayHeight}); + mWriter->setLayerSourceCrop(display.getCrop()); mWriter->setLayerTransform(static_cast(0)); - mWriter->setLayerVisibleRegion(std::vector(1, displayFrame)); + mWriter->setLayerVisibleRegion(std::vector(1, display.getFrameRect())); mWriter->setLayerZOrder(10); mWriter->setLayerBlendMode(IComposerClient::BlendMode::NONE); - mWriter->setLayerSurfaceDamage(std::vector(1, displayFrame)); + mWriter->setLayerSurfaceDamage(std::vector(1, display.getFrameRect())); mWriter->setLayerBuffer(0, handle, -1); mWriter->setLayerDataspace(Dataspace::UNKNOWN); @@ -440,9 +448,11 @@ void GraphicsComposerHidlCommandTest::sendRefreshFrame(const VsyncPeriodChangeTi execute(); } -void GraphicsComposerHidlCommandTest::waitForVsyncPeriodChange( - Display display, const VsyncPeriodChangeTimeline& timeline, int64_t desiredTimeNanos, - int64_t oldPeriodNanos, int64_t newPeriodNanos) { +void GraphicsComposerHidlTest::waitForVsyncPeriodChange(Display display, + const VsyncPeriodChangeTimeline& timeline, + int64_t desiredTimeNanos, + int64_t oldPeriodNanos, + int64_t newPeriodNanos) { const auto CHANGE_DEADLINE = toTimePoint(timeline.newVsyncAppliedTimeNanos) + 100ms; while (std::chrono::steady_clock::now() <= CHANGE_DEADLINE) { VsyncPeriodNanos vsyncPeriodNanos; @@ -456,17 +466,18 @@ void GraphicsComposerHidlCommandTest::waitForVsyncPeriodChange( } } -void GraphicsComposerHidlCommandTest::Test_setActiveConfigWithConstraints( - const TestParameters& params) { - for (Display display : mComposerCallback->getDisplays()) { - forEachTwoConfigs(display, [&](Config config1, Config config2) { - mComposerClient->setActiveConfig(display, config1); - sendRefreshFrame(nullptr); +void GraphicsComposerHidlTest::Test_setActiveConfigWithConstraints(const TestParameters& params) { + for (const auto& display : mDisplays) { + forEachTwoConfigs(display.get(), [&](Config config1, Config config2) { + mComposerClient->setActiveConfig(display.get(), config1); + sendRefreshFrame(display, nullptr); int32_t vsyncPeriod1 = mComposerClient->getDisplayAttribute_2_4( - display, config1, IComposerClient::IComposerClient::Attribute::VSYNC_PERIOD); + display.get(), config1, + IComposerClient::IComposerClient::Attribute::VSYNC_PERIOD); int32_t vsyncPeriod2 = mComposerClient->getDisplayAttribute_2_4( - display, config2, IComposerClient::IComposerClient::Attribute::VSYNC_PERIOD); + display.get(), config2, + IComposerClient::IComposerClient::Attribute::VSYNC_PERIOD); if (vsyncPeriod1 == vsyncPeriod2) { return; // continue @@ -477,7 +488,7 @@ void GraphicsComposerHidlCommandTest::Test_setActiveConfigWithConstraints( .desiredTimeNanos = systemTime() + params.delayForChange, .seamlessRequired = false}; EXPECT_EQ(Error::NONE, mComposerClient->setActiveConfigWithConstraints( - display, config2, constraints, &timeline)); + display.get(), config2, constraints, &timeline)); EXPECT_TRUE(timeline.newVsyncAppliedTimeNanos >= constraints.desiredTimeNanos); // Refresh rate should change within a reasonable time @@ -491,10 +502,10 @@ void GraphicsComposerHidlCommandTest::Test_setActiveConfigWithConstraints( // callback std::this_thread::sleep_until(toTimePoint(timeline.refreshTimeNanos) + 100ms); } - sendRefreshFrame(&timeline); + sendRefreshFrame(display, &timeline); } - waitForVsyncPeriodChange(display, timeline, constraints.desiredTimeNanos, vsyncPeriod1, - vsyncPeriod2); + waitForVsyncPeriodChange(display.get(), timeline, constraints.desiredTimeNanos, + vsyncPeriod1, vsyncPeriod2); // At this point the refresh rate should have changed already, however in rare // cases the implementation might have missed the deadline. In this case a new @@ -506,30 +517,30 @@ void GraphicsComposerHidlCommandTest::Test_setActiveConfigWithConstraints( if (newTimeline.has_value()) { if (newTimeline->refreshRequired) { - sendRefreshFrame(&newTimeline.value()); + sendRefreshFrame(display, &newTimeline.value()); } - waitForVsyncPeriodChange(display, newTimeline.value(), constraints.desiredTimeNanos, - vsyncPeriod1, vsyncPeriod2); + waitForVsyncPeriodChange(display.get(), newTimeline.value(), + constraints.desiredTimeNanos, vsyncPeriod1, vsyncPeriod2); } VsyncPeriodNanos vsyncPeriodNanos; EXPECT_EQ(Error::NONE, - mComposerClient->getDisplayVsyncPeriod(display, &vsyncPeriodNanos)); + mComposerClient->getDisplayVsyncPeriod(display.get(), &vsyncPeriodNanos)); EXPECT_EQ(vsyncPeriodNanos, vsyncPeriod2); }); } } -TEST_P(GraphicsComposerHidlCommandTest, setActiveConfigWithConstraints) { +TEST_P(GraphicsComposerHidlTest, setActiveConfigWithConstraints) { Test_setActiveConfigWithConstraints({.delayForChange = 0, .refreshMiss = false}); } -TEST_P(GraphicsComposerHidlCommandTest, setActiveConfigWithConstraints_Delayed) { +TEST_P(GraphicsComposerHidlTest, setActiveConfigWithConstraints_Delayed) { Test_setActiveConfigWithConstraints({.delayForChange = 300'000'000, // 300ms .refreshMiss = false}); } -TEST_P(GraphicsComposerHidlCommandTest, setActiveConfigWithConstraints_MissRefresh) { +TEST_P(GraphicsComposerHidlTest, setActiveConfigWithConstraints_MissRefresh) { Test_setActiveConfigWithConstraints({.delayForChange = 0, .refreshMiss = true}); } @@ -539,9 +550,9 @@ TEST_P(GraphicsComposerHidlTest, setAutoLowLatencyModeBadDisplay) { } TEST_P(GraphicsComposerHidlTest, setAutoLowLatencyMode) { - for (Display display : mComposerCallback->getDisplays()) { + for (const auto& display : mDisplays) { std::vector capabilities; - const auto error = mComposerClient->getDisplayCapabilities(display, &capabilities); + const auto error = mComposerClient->getDisplayCapabilities(display.get(), &capabilities); EXPECT_EQ(Error::NONE, error); const bool allmSupport = @@ -550,16 +561,16 @@ TEST_P(GraphicsComposerHidlTest, setAutoLowLatencyMode) { if (!allmSupport) { EXPECT_EQ(Error::UNSUPPORTED, - mComposerClient->setAutoLowLatencyMode(mPrimaryDisplay, true)); + mComposerClient->setAutoLowLatencyMode(display.get(), true)); EXPECT_EQ(Error::UNSUPPORTED, - mComposerClient->setAutoLowLatencyMode(mPrimaryDisplay, false)); + mComposerClient->setAutoLowLatencyMode(display.get(), false)); GTEST_SUCCEED() << "Auto Low Latency Mode is not supported on display " - << std::to_string(display) << ", skipping test"; + << std::to_string(display.get()) << ", skipping test"; return; } - EXPECT_EQ(Error::NONE, mComposerClient->setAutoLowLatencyMode(mPrimaryDisplay, true)); - EXPECT_EQ(Error::NONE, mComposerClient->setAutoLowLatencyMode(mPrimaryDisplay, false)); + EXPECT_EQ(Error::NONE, mComposerClient->setAutoLowLatencyMode(display.get(), true)); + EXPECT_EQ(Error::NONE, mComposerClient->setAutoLowLatencyMode(display.get(), false)); } } @@ -572,10 +583,10 @@ TEST_P(GraphicsComposerHidlTest, getSupportedContentTypesBadDisplay) { TEST_P(GraphicsComposerHidlTest, getSupportedContentTypes) { std::vector supportedContentTypes; - for (Display display : mComposerCallback->getDisplays()) { + for (const auto& display : mDisplays) { supportedContentTypes.clear(); const auto error = - mComposerClient->getSupportedContentTypes(display, &supportedContentTypes); + mComposerClient->getSupportedContentTypes(display.get(), &supportedContentTypes); const bool noneSupported = std::find(supportedContentTypes.begin(), supportedContentTypes.end(), ContentType::NONE) != supportedContentTypes.end(); @@ -585,8 +596,8 @@ TEST_P(GraphicsComposerHidlTest, getSupportedContentTypes) { } TEST_P(GraphicsComposerHidlTest, setContentTypeNoneAlwaysAccepted) { - for (Display display : mComposerCallback->getDisplays()) { - const auto error = mComposerClient->setContentType(display, ContentType::NONE); + for (const auto& display : mDisplays) { + const auto error = mComposerClient->setContentType(display.get(), ContentType::NONE); EXPECT_NE(Error::UNSUPPORTED, error); } } @@ -618,13 +629,14 @@ void GraphicsComposerHidlTest::Test_setContentTypeForDisplay( void GraphicsComposerHidlTest::Test_setContentType(const ContentType& contentType, const char* contentTypeStr) { - for (Display display : mComposerCallback->getDisplays()) { + for (const auto& display : mDisplays) { std::vector supportedContentTypes; const auto error = - mComposerClient->getSupportedContentTypes(display, &supportedContentTypes); + mComposerClient->getSupportedContentTypes(display.get(), &supportedContentTypes); EXPECT_EQ(Error::NONE, error); - Test_setContentTypeForDisplay(display, supportedContentTypes, contentType, contentTypeStr); + Test_setContentTypeForDisplay(display.get(), supportedContentTypes, contentType, + contentTypeStr); } } @@ -650,13 +662,7 @@ INSTANTIATE_TEST_SUITE_P( testing::ValuesIn(android::hardware::getAllHalInstanceNames(IComposer::descriptor)), android::hardware::PrintInstanceNameToString); -GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerHidlCommandTest); -INSTANTIATE_TEST_SUITE_P( - PerInstance, GraphicsComposerHidlCommandTest, - testing::ValuesIn(android::hardware::getAllHalInstanceNames(IComposer::descriptor)), - android::hardware::PrintInstanceNameToString); - -TEST_P(GraphicsComposerHidlCommandTest, getLayerGenericMetadataKeys) { +TEST_P(GraphicsComposerHidlTest, getLayerGenericMetadataKeys) { std::vector keys; mComposerClient->getLayerGenericMetadataKeys(&keys); -- GitLab From 261818bfafd393bc55d8f184dc8a1b9dce5889bd Mon Sep 17 00:00:00 2001 From: lesl Date: Fri, 27 Nov 2020 12:37:35 +0800 Subject: [PATCH 313/790] wifi: Add AP interface idx mechanism & predefine interface support. SAP Interface idx mechanism. STA+STA support, AP+AP will use wlan2 & wlan3, single AP use wlan2 STA+STA doesn't support, AP+AP use wlan1 & wlan 2, single AP use wlan 1 STA+AP doesn't support, AP + AP will take wlan0 & wlan 1 but single AP use wlan0 (Ideally it should not happen) Add predefine interface support for bridged AP interface. (property: ro.vendor.sap.concurrent.interface) PS: Rename: getApIfaceName to getPredefinedApIfaceName since it duplicates public HAL API: getApIfaceName AP+AP Part 4 includes: 1. Support API to indicate Bridged AP supported or not 2. SAP Interface idx mechanism. Bug: 162686273 Bug: 173999527 Test: atest -c VtsHalWifiApV1_0TargetTest Test: atest -c VtsHalWifiApV1_4TargetTest Test: atest -c VtsHalWifiApV1_5TargetTest Change-Id: I115e294ac2be201cfa3a58cfa0a8a98b481b29de --- wifi/1.5/default/wifi_chip.cpp | 101 +++++++++++++++++++++++---------- wifi/1.5/default/wifi_chip.h | 4 +- 2 files changed, 73 insertions(+), 32 deletions(-) diff --git a/wifi/1.5/default/wifi_chip.cpp b/wifi/1.5/default/wifi_chip.cpp index 5d9d315e40..dd39551571 100644 --- a/wifi/1.5/default/wifi_chip.cpp +++ b/wifi/1.5/default/wifi_chip.cpp @@ -103,24 +103,36 @@ std::string getWlanIfaceName(unsigned idx) { return "wlan" + std::to_string(idx); } -// Returns the dedicated iface name if one is defined. -std::string getApIfaceName() { +// Returns the dedicated iface name if defined. +// Returns two ifaces in bridged mode. +std::vector getPredefinedApIfaceNames(bool is_bridged) { + std::vector ifnames; std::array buffer; + buffer.fill(0); if (property_get("ro.vendor.wifi.sap.interface", buffer.data(), nullptr) == 0) { - return {}; + return ifnames; + } + ifnames.push_back(buffer.data()); + if (is_bridged) { + buffer.fill(0); + if (property_get("ro.vendor.wifi.sap.concurrent.interface", + buffer.data(), nullptr) == 0) { + return ifnames; + } + ifnames.push_back(buffer.data()); } - return buffer.data(); + return ifnames; } -std::string getP2pIfaceName() { +std::string getPredefinedP2pIfaceName() { std::array buffer; property_get("wifi.direct.interface", buffer.data(), "p2p0"); return buffer.data(); } // Returns the dedicated iface name if one is defined. -std::string getNanIfaceName() { +std::string getPredefinedNanIfaceName() { std::array buffer; if (property_get("wifi.aware.interface", buffer.data(), nullptr) == 0) { return {}; @@ -931,22 +943,22 @@ WifiChip::createBridgedApIfaceInternal() { if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::AP)) { return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; } - std::string br_ifname = kApBridgeIfacePrefix + allocateApIfaceName(); - std::vector ap_instances; + std::vector ap_instances = allocateBridgedApInstanceNames(); + if (ap_instances.size() < 2) { + LOG(ERROR) << "Fail to allocate two instances"; + return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; + } + std::string br_ifname = kApBridgeIfacePrefix + ap_instances[0]; for (int i = 0; i < 2; i++) { - // TODO: b/173999527, it should use idx from 2 when STA+STA support, but - // need to check vendor support or not. - std::string ifaceInstanceName = allocateApOrStaIfaceName( - IfaceType::AP, isStaApConcurrencyAllowedInCurrentMode() ? 1 : 0); - WifiStatus status = createVirtualApInterface(ifaceInstanceName); + WifiStatus status = createVirtualApInterface(ap_instances[i]); if (status.code != WifiStatusCode::SUCCESS) { - if (ap_instances.size() != 0) { + if (i != 0) { // The failure happened when creating second virtual + // iface. legacy_hal_.lock()->deleteVirtualInterface( - ap_instances.front()); + ap_instances.front()); // Remove the first virtual iface. } return {status, {}}; } - ap_instances.push_back(ifaceInstanceName); } br_ifaces_ap_instances_[br_ifname] = ap_instances; if (!iface_util_.lock()->createBridge(br_ifname)) { @@ -1048,7 +1060,7 @@ WifiChip::createNanIfaceInternal() { return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; } bool is_dedicated_iface = true; - std::string ifname = getNanIfaceName(); + std::string ifname = getPredefinedNanIfaceName(); if (ifname.empty() || !iface_util_.lock()->ifNameToIndex(ifname)) { // Use the first shared STA iface (wlan0) if a dedicated aware iface is // not defined. @@ -1101,7 +1113,7 @@ std::pair> WifiChip::createP2pIfaceInternal() { if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::P2P)) { return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; } - std::string ifname = getP2pIfaceName(); + std::string ifname = getPredefinedP2pIfaceName(); sp iface = new WifiP2pIface(ifname, legacy_hal_); p2p_ifaces_.push_back(iface); for (const auto& callback : event_cb_handler_.getCallbacks()) { @@ -1720,7 +1732,7 @@ bool WifiChip::canCurrentModeSupportIfaceCombo( // ChipIfaceCombination. // b) Check if the requested iface type can be added to the current mode. bool WifiChip::canCurrentModeSupportIfaceOfType(IfaceType requested_type) { - // Check if we can support atleast 1 iface of type. + // Check if we can support at least 1 iface of type. std::map req_iface_combo; req_iface_combo[requested_type] = 1; return canCurrentModeSupportIfaceCombo(req_iface_combo); @@ -1736,17 +1748,17 @@ bool WifiChip::isValidModeId(ChipModeId mode_id) { } bool WifiChip::isStaApConcurrencyAllowedInCurrentMode() { - // Check if we can support atleast 1 STA & 1 AP concurrently. + // Check if we can support at least 1 STA & 1 AP concurrently. std::map req_iface_combo; req_iface_combo[IfaceType::AP] = 1; req_iface_combo[IfaceType::STA] = 1; return canCurrentModeSupportIfaceCombo(req_iface_combo); } -bool WifiChip::isDualApAllowedInCurrentMode() { - // Check if we can support atleast 1 STA & 1 AP concurrently. +bool WifiChip::isDualStaConcurrencyAllowedInCurrentMode() { + // Check if we can support at least 2 STA concurrently. std::map req_iface_combo; - req_iface_combo[IfaceType::AP] = 2; + req_iface_combo[IfaceType::STA] = 2; return canCurrentModeSupportIfaceCombo(req_iface_combo); } @@ -1776,19 +1788,46 @@ std::string WifiChip::allocateApOrStaIfaceName(IfaceType type, return {}; } +uint32_t WifiChip::startIdxOfApIface() { + if (isDualStaConcurrencyAllowedInCurrentMode()) { + // When the HAL support dual STAs, AP should start with idx 2. + return 2; + } else if (isStaApConcurrencyAllowedInCurrentMode()) { + // When the HAL support STA + AP but it doesn't support dual STAs. + // AP should start with idx 1. + return 1; + } + // No concurrency support. + return 0; +} + // AP iface names start with idx 1 for modes supporting // 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::string ifname = getApIfaceName(); - if (!ifname.empty()) { - return ifname; + std::vector ifnames = getPredefinedApIfaceNames(false); + if (!ifnames.empty()) { + return ifnames[0]; + } + return allocateApOrStaIfaceName(IfaceType::AP, startIdxOfApIface()); +} + +std::vector WifiChip::allocateBridgedApInstanceNames() { + // Check if we have a dedicated iface for AP. + std::vector instances = getPredefinedApIfaceNames(true); + if (instances.size() == 2) { + return instances; + } 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()); + if (!instance_name.empty()) { + instances.push_back(instance_name); + } + } } - return allocateApOrStaIfaceName(IfaceType::AP, - (isStaApConcurrencyAllowedInCurrentMode() && - !isDualApAllowedInCurrentMode()) - ? 1 - : 0); + return instances; } // STA iface names start with idx 0. diff --git a/wifi/1.5/default/wifi_chip.h b/wifi/1.5/default/wifi_chip.h index 70b221d26b..bff8d680a3 100644 --- a/wifi/1.5/default/wifi_chip.h +++ b/wifi/1.5/default/wifi_chip.h @@ -276,10 +276,12 @@ class WifiChip : public V1_5::IWifiChip { bool canCurrentModeSupportIfaceOfType(IfaceType requested_type); bool isValidModeId(ChipModeId mode_id); bool isStaApConcurrencyAllowedInCurrentMode(); - bool isDualApAllowedInCurrentMode(); + bool isDualStaConcurrencyAllowedInCurrentMode(); + uint32_t startIdxOfApIface(); std::string getFirstActiveWlanIfaceName(); std::string allocateApOrStaIfaceName(IfaceType type, uint32_t start_idx); std::string allocateApIfaceName(); + std::vector allocateBridgedApInstanceNames(); std::string allocateStaIfaceName(); bool writeRingbufferFilesInternal(); std::string getWlanIfaceNameWithType(IfaceType type, unsigned idx); -- GitLab From 32acc0614402a35eed3407116ec359f4fdb60ecc Mon Sep 17 00:00:00 2001 From: Michael Butler Date: Sun, 22 Nov 2020 19:36:30 -0800 Subject: [PATCH 314/790] Validate during NN conversions by default -- hal This change renames all `convert` functions to `unvalidatedConvert`. This change also introduces new `convert` functions that act only on the types that appear in the NN HIDL methods directly. These new `convert` functions perform validation. Specifically, if either the source or destination value is invalid, then the conversion fails. Bug: 160667419 Test: mma Test: NeuralNetworksTest_static Change-Id: I492956ff60ad1466c67893993d28cdd6f3860708 --- .../utils/include/nnapi/hal/1.0/Conversions.h | 61 ++- .../1.0/utils/include/nnapi/hal/1.0/Utils.h | 24 -- neuralnetworks/1.0/utils/src/Callbacks.cpp | 6 +- neuralnetworks/1.0/utils/src/Conversions.cpp | 222 ++++++---- neuralnetworks/1.0/utils/src/Device.cpp | 11 +- .../1.0/utils/src/PreparedModel.cpp | 3 +- .../utils/include/nnapi/hal/1.1/Conversions.h | 18 +- .../1.1/utils/include/nnapi/hal/1.1/Utils.h | 23 - neuralnetworks/1.1/utils/src/Conversions.cpp | 157 +++++-- neuralnetworks/1.1/utils/src/Device.cpp | 11 +- .../utils/include/nnapi/hal/1.2/Conversions.h | 78 ++-- .../1.2/utils/include/nnapi/hal/1.2/Utils.h | 23 - neuralnetworks/1.2/utils/src/Callbacks.cpp | 15 +- neuralnetworks/1.2/utils/src/Conversions.cpp | 302 ++++++++----- neuralnetworks/1.2/utils/src/Device.cpp | 26 +- .../1.2/utils/src/PreparedModel.cpp | 9 +- .../utils/include/nnapi/hal/1.3/Conversions.h | 69 ++- .../1.3/utils/include/nnapi/hal/1.3/Utils.h | 23 - neuralnetworks/1.3/utils/src/Buffer.cpp | 10 +- neuralnetworks/1.3/utils/src/Callbacks.cpp | 21 +- neuralnetworks/1.3/utils/src/Conversions.cpp | 400 ++++++++++++------ neuralnetworks/1.3/utils/src/Device.cpp | 17 +- .../1.3/utils/src/PreparedModel.cpp | 24 +- neuralnetworks/utils/README.md | 50 +++ 24 files changed, 994 insertions(+), 609 deletions(-) create mode 100644 neuralnetworks/utils/README.md diff --git a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Conversions.h b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Conversions.h index fb77cb2475..d3d933b22c 100644 --- a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Conversions.h +++ b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Conversions.h @@ -24,20 +24,28 @@ namespace android::nn { -GeneralResult convert(const hal::V1_0::OperandType& operandType); -GeneralResult convert(const hal::V1_0::OperationType& operationType); -GeneralResult convert(const hal::V1_0::OperandLifeTime& lifetime); -GeneralResult convert(const hal::V1_0::DeviceStatus& deviceStatus); -GeneralResult convert( +GeneralResult unvalidatedConvert(const hal::V1_0::OperandType& operandType); +GeneralResult unvalidatedConvert(const hal::V1_0::OperationType& operationType); +GeneralResult unvalidatedConvert(const hal::V1_0::OperandLifeTime& lifetime); +GeneralResult unvalidatedConvert(const hal::V1_0::DeviceStatus& deviceStatus); +GeneralResult unvalidatedConvert( const hal::V1_0::PerformanceInfo& performanceInfo); +GeneralResult unvalidatedConvert(const hal::V1_0::Capabilities& capabilities); +GeneralResult unvalidatedConvert(const hal::V1_0::DataLocation& location); +GeneralResult unvalidatedConvert(const hal::V1_0::Operand& operand); +GeneralResult unvalidatedConvert(const hal::V1_0::Operation& operation); +GeneralResult unvalidatedConvert( + const hardware::hidl_vec& operandValues); +GeneralResult unvalidatedConvert(const hardware::hidl_memory& memory); +GeneralResult unvalidatedConvert(const hal::V1_0::Model& model); +GeneralResult unvalidatedConvert( + const hal::V1_0::RequestArgument& requestArgument); +GeneralResult unvalidatedConvert(const hal::V1_0::Request& request); +GeneralResult unvalidatedConvert(const hal::V1_0::ErrorStatus& status); + +GeneralResult convert(const hal::V1_0::DeviceStatus& deviceStatus); GeneralResult convert(const hal::V1_0::Capabilities& capabilities); -GeneralResult convert(const hal::V1_0::DataLocation& location); -GeneralResult convert(const hal::V1_0::Operand& operand); -GeneralResult convert(const hal::V1_0::Operation& operation); -GeneralResult convert(const hardware::hidl_vec& operandValues); -GeneralResult convert(const hardware::hidl_memory& memory); GeneralResult convert(const hal::V1_0::Model& model); -GeneralResult convert(const hal::V1_0::RequestArgument& requestArgument); GeneralResult convert(const hal::V1_0::Request& request); GeneralResult convert(const hal::V1_0::ErrorStatus& status); @@ -45,21 +53,28 @@ GeneralResult convert(const hal::V1_0::ErrorStatus& status); namespace android::hardware::neuralnetworks::V1_0::utils { -nn::GeneralResult convert(const nn::OperandType& operandType); -nn::GeneralResult convert(const nn::OperationType& operationType); -nn::GeneralResult convert(const nn::Operand::LifeTime& lifetime); -nn::GeneralResult convert(const nn::DeviceStatus& deviceStatus); -nn::GeneralResult convert( +nn::GeneralResult unvalidatedConvert(const nn::OperandType& operandType); +nn::GeneralResult unvalidatedConvert(const nn::OperationType& operationType); +nn::GeneralResult unvalidatedConvert(const nn::Operand::LifeTime& lifetime); +nn::GeneralResult unvalidatedConvert(const nn::DeviceStatus& deviceStatus); +nn::GeneralResult unvalidatedConvert( const nn::Capabilities::PerformanceInfo& performanceInfo); +nn::GeneralResult unvalidatedConvert(const nn::Capabilities& capabilities); +nn::GeneralResult unvalidatedConvert(const nn::DataLocation& location); +nn::GeneralResult unvalidatedConvert(const nn::Operand& operand); +nn::GeneralResult unvalidatedConvert(const nn::Operation& operation); +nn::GeneralResult> unvalidatedConvert( + const nn::Model::OperandValues& operandValues); +nn::GeneralResult unvalidatedConvert(const nn::Memory& memory); +nn::GeneralResult unvalidatedConvert(const nn::Model& model); +nn::GeneralResult unvalidatedConvert(const nn::Request::Argument& requestArgument); +nn::GeneralResult unvalidatedConvert(const nn::Request::MemoryPool& memoryPool); +nn::GeneralResult unvalidatedConvert(const nn::Request& request); +nn::GeneralResult unvalidatedConvert(const nn::ErrorStatus& status); + +nn::GeneralResult convert(const nn::DeviceStatus& deviceStatus); nn::GeneralResult convert(const nn::Capabilities& capabilities); -nn::GeneralResult convert(const nn::DataLocation& location); -nn::GeneralResult convert(const nn::Operand& operand); -nn::GeneralResult convert(const nn::Operation& operation); -nn::GeneralResult> convert(const nn::Model::OperandValues& operandValues); -nn::GeneralResult convert(const nn::Memory& memory); nn::GeneralResult convert(const nn::Model& model); -nn::GeneralResult convert(const nn::Request::Argument& requestArgument); -nn::GeneralResult convert(const nn::Request::MemoryPool& memoryPool); nn::GeneralResult convert(const nn::Request& request); nn::GeneralResult convert(const nn::ErrorStatus& status); diff --git a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Utils.h b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Utils.h index baa2b9523e..4cec545cf0 100644 --- a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Utils.h +++ b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Utils.h @@ -22,25 +22,16 @@ #include #include #include -#include #include -#include namespace android::hardware::neuralnetworks::V1_0::utils { -constexpr auto kVersion = nn::Version::ANDROID_OC_MR1; - template nn::Result validate(const Type& halObject) { const auto maybeCanonical = nn::convert(halObject); if (!maybeCanonical.has_value()) { return nn::error() << maybeCanonical.error().message; } - const auto version = NN_TRY(nn::validate(maybeCanonical.value())); - if (version > utils::kVersion) { - return NN_ERROR() << "Insufficient version: " << version << " vs required " - << utils::kVersion; - } return {}; } @@ -53,21 +44,6 @@ bool valid(const Type& halObject) { return result.has_value(); } -template -decltype(nn::convert(std::declval())) validatedConvertToCanonical(const Type& halObject) { - auto canonical = NN_TRY(nn::convert(halObject)); - const auto maybeVersion = nn::validate(canonical); - if (!maybeVersion.has_value()) { - return nn::error() << maybeVersion.error(); - } - const auto version = maybeVersion.value(); - if (version > utils::kVersion) { - return NN_ERROR() << "Insufficient version: " << version << " vs required " - << utils::kVersion; - } - return canonical; -} - } // namespace android::hardware::neuralnetworks::V1_0::utils #endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_0_UTILS_H diff --git a/neuralnetworks/1.0/utils/src/Callbacks.cpp b/neuralnetworks/1.0/utils/src/Callbacks.cpp index f286bcc50e..b1259c3c56 100644 --- a/neuralnetworks/1.0/utils/src/Callbacks.cpp +++ b/neuralnetworks/1.0/utils/src/Callbacks.cpp @@ -45,8 +45,7 @@ nn::GeneralResult convertPreparedModel( Return PreparedModelCallback::notify(ErrorStatus status, const sp& preparedModel) { if (status != ErrorStatus::NONE) { - const auto canonical = - validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); notifyInternal(NN_ERROR(canonical) << "preparedModel failed with " << toString(status)); } else if (preparedModel == nullptr) { notifyInternal(NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) @@ -73,8 +72,7 @@ void PreparedModelCallback::notifyInternal(PreparedModelCallback::Data result) { Return ExecutionCallback::notify(ErrorStatus status) { if (status != ErrorStatus::NONE) { - const auto canonical = - validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); notifyInternal(NN_ERROR(canonical) << "execute failed with " << toString(status)); } else { notifyInternal({}); diff --git a/neuralnetworks/1.0/utils/src/Conversions.cpp b/neuralnetworks/1.0/utils/src/Conversions.cpp index 6cf907380e..fde7346470 100644 --- a/neuralnetworks/1.0/utils/src/Conversions.cpp +++ b/neuralnetworks/1.0/utils/src/Conversions.cpp @@ -22,7 +22,9 @@ #include #include #include +#include #include +#include #include #include @@ -40,6 +42,8 @@ constexpr std::underlying_type_t underlyingType(Type value) { return static_cast>(value); } +constexpr auto kVersion = android::nn::Version::ANDROID_OC_MR1; + } // namespace namespace android::nn { @@ -49,37 +53,53 @@ using hardware::hidl_memory; using hardware::hidl_vec; template -using ConvertOutput = std::decay_t()).value())>; +using unvalidatedConvertOutput = + std::decay_t()).value())>; template -GeneralResult>> convert(const hidl_vec& arguments) { - std::vector> canonical; +GeneralResult>> unvalidatedConvert( + const hidl_vec& arguments) { + std::vector> canonical; canonical.reserve(arguments.size()); for (const auto& argument : arguments) { - canonical.push_back(NN_TRY(nn::convert(argument))); + canonical.push_back(NN_TRY(nn::unvalidatedConvert(argument))); + } + return canonical; +} + +template +decltype(nn::unvalidatedConvert(std::declval())) validatedConvert(const Type& halObject) { + auto canonical = NN_TRY(nn::unvalidatedConvert(halObject)); + const auto maybeVersion = validate(canonical); + if (!maybeVersion.has_value()) { + return error() << maybeVersion.error(); + } + const auto version = maybeVersion.value(); + if (version > kVersion) { + return NN_ERROR() << "Insufficient version: " << version << " vs required " << kVersion; } return canonical; } } // anonymous namespace -GeneralResult convert(const hal::V1_0::OperandType& operandType) { +GeneralResult unvalidatedConvert(const hal::V1_0::OperandType& operandType) { return static_cast(operandType); } -GeneralResult convert(const hal::V1_0::OperationType& operationType) { +GeneralResult unvalidatedConvert(const hal::V1_0::OperationType& operationType) { return static_cast(operationType); } -GeneralResult convert(const hal::V1_0::OperandLifeTime& lifetime) { +GeneralResult unvalidatedConvert(const hal::V1_0::OperandLifeTime& lifetime) { return static_cast(lifetime); } -GeneralResult convert(const hal::V1_0::DeviceStatus& deviceStatus) { +GeneralResult unvalidatedConvert(const hal::V1_0::DeviceStatus& deviceStatus) { return static_cast(deviceStatus); } -GeneralResult convert( +GeneralResult unvalidatedConvert( const hal::V1_0::PerformanceInfo& performanceInfo) { return Capabilities::PerformanceInfo{ .execTime = performanceInfo.execTime, @@ -87,9 +107,10 @@ GeneralResult convert( }; } -GeneralResult convert(const hal::V1_0::Capabilities& capabilities) { - const auto quantized8Performance = NN_TRY(convert(capabilities.quantized8Performance)); - const auto float32Performance = NN_TRY(convert(capabilities.float32Performance)); +GeneralResult unvalidatedConvert(const hal::V1_0::Capabilities& capabilities) { + const auto quantized8Performance = + NN_TRY(unvalidatedConvert(capabilities.quantized8Performance)); + const auto float32Performance = NN_TRY(unvalidatedConvert(capabilities.float32Performance)); auto table = hal::utils::makeQuantized8PerformanceConsistentWithP(float32Performance, quantized8Performance); @@ -101,7 +122,7 @@ GeneralResult convert(const hal::V1_0::Capabilities& capabilities) }; } -GeneralResult convert(const hal::V1_0::DataLocation& location) { +GeneralResult unvalidatedConvert(const hal::V1_0::DataLocation& location) { return DataLocation{ .poolIndex = location.poolIndex, .offset = location.offset, @@ -109,35 +130,35 @@ GeneralResult convert(const hal::V1_0::DataLocation& location) { }; } -GeneralResult convert(const hal::V1_0::Operand& operand) { +GeneralResult unvalidatedConvert(const hal::V1_0::Operand& operand) { return Operand{ - .type = NN_TRY(convert(operand.type)), + .type = NN_TRY(unvalidatedConvert(operand.type)), .dimensions = operand.dimensions, .scale = operand.scale, .zeroPoint = operand.zeroPoint, - .lifetime = NN_TRY(convert(operand.lifetime)), - .location = NN_TRY(convert(operand.location)), + .lifetime = NN_TRY(unvalidatedConvert(operand.lifetime)), + .location = NN_TRY(unvalidatedConvert(operand.location)), }; } -GeneralResult convert(const hal::V1_0::Operation& operation) { +GeneralResult unvalidatedConvert(const hal::V1_0::Operation& operation) { return Operation{ - .type = NN_TRY(convert(operation.type)), + .type = NN_TRY(unvalidatedConvert(operation.type)), .inputs = operation.inputs, .outputs = operation.outputs, }; } -GeneralResult convert(const hidl_vec& operandValues) { +GeneralResult unvalidatedConvert(const hidl_vec& operandValues) { return Model::OperandValues(operandValues.data(), operandValues.size()); } -GeneralResult convert(const hidl_memory& memory) { +GeneralResult unvalidatedConvert(const hidl_memory& memory) { return createSharedMemoryFromHidlMemory(memory); } -GeneralResult convert(const hal::V1_0::Model& model) { - auto operations = NN_TRY(convert(model.operations)); +GeneralResult unvalidatedConvert(const hal::V1_0::Model& model) { + auto operations = NN_TRY(unvalidatedConvert(model.operations)); // Verify number of consumers. const auto numberOfConsumers = @@ -152,7 +173,7 @@ GeneralResult convert(const hal::V1_0::Model& model) { } auto main = Model::Subgraph{ - .operands = NN_TRY(convert(model.operands)), + .operands = NN_TRY(unvalidatedConvert(model.operands)), .operations = std::move(operations), .inputIndexes = model.inputIndexes, .outputIndexes = model.outputIndexes, @@ -160,35 +181,35 @@ GeneralResult convert(const hal::V1_0::Model& model) { return Model{ .main = std::move(main), - .operandValues = NN_TRY(convert(model.operandValues)), - .pools = NN_TRY(convert(model.pools)), + .operandValues = NN_TRY(unvalidatedConvert(model.operandValues)), + .pools = NN_TRY(unvalidatedConvert(model.pools)), }; } -GeneralResult convert(const hal::V1_0::RequestArgument& argument) { +GeneralResult unvalidatedConvert(const hal::V1_0::RequestArgument& argument) { const auto lifetime = argument.hasNoValue ? Request::Argument::LifeTime::NO_VALUE : Request::Argument::LifeTime::POOL; return Request::Argument{ .lifetime = lifetime, - .location = NN_TRY(convert(argument.location)), + .location = NN_TRY(unvalidatedConvert(argument.location)), .dimensions = argument.dimensions, }; } -GeneralResult convert(const hal::V1_0::Request& request) { - auto memories = NN_TRY(convert(request.pools)); +GeneralResult unvalidatedConvert(const hal::V1_0::Request& request) { + auto memories = NN_TRY(unvalidatedConvert(request.pools)); std::vector pools; pools.reserve(memories.size()); std::move(memories.begin(), memories.end(), std::back_inserter(pools)); return Request{ - .inputs = NN_TRY(convert(request.inputs)), - .outputs = NN_TRY(convert(request.outputs)), + .inputs = NN_TRY(unvalidatedConvert(request.inputs)), + .outputs = NN_TRY(unvalidatedConvert(request.outputs)), .pools = std::move(pools), }; } -GeneralResult convert(const hal::V1_0::ErrorStatus& status) { +GeneralResult unvalidatedConvert(const hal::V1_0::ErrorStatus& status) { switch (status) { case hal::V1_0::ErrorStatus::NONE: case hal::V1_0::ErrorStatus::DEVICE_UNAVAILABLE: @@ -201,46 +222,81 @@ GeneralResult convert(const hal::V1_0::ErrorStatus& status) { << "Invalid ErrorStatus " << underlyingType(status); } +GeneralResult convert(const hal::V1_0::DeviceStatus& deviceStatus) { + return validatedConvert(deviceStatus); +} + +GeneralResult convert(const hal::V1_0::Capabilities& capabilities) { + return validatedConvert(capabilities); +} + +GeneralResult convert(const hal::V1_0::Model& model) { + return validatedConvert(model); +} + +GeneralResult convert(const hal::V1_0::Request& request) { + return validatedConvert(request); +} + +GeneralResult convert(const hal::V1_0::ErrorStatus& status) { + return validatedConvert(status); +} + } // namespace android::nn namespace android::hardware::neuralnetworks::V1_0::utils { namespace { template -using ConvertOutput = std::decay_t()).value())>; +using unvalidatedConvertOutput = + std::decay_t()).value())>; template -nn::GeneralResult>> convert(const std::vector& arguments) { - hidl_vec> halObject(arguments.size()); +nn::GeneralResult>> unvalidatedConvert( + const std::vector& arguments) { + hidl_vec> halObject(arguments.size()); for (size_t i = 0; i < arguments.size(); ++i) { - halObject[i] = NN_TRY(utils::convert(arguments[i])); + halObject[i] = NN_TRY(utils::unvalidatedConvert(arguments[i])); } return halObject; } +template +decltype(utils::unvalidatedConvert(std::declval())) validatedConvert(const Type& canonical) { + const auto maybeVersion = nn::validate(canonical); + if (!maybeVersion.has_value()) { + return nn::error() << maybeVersion.error(); + } + const auto version = maybeVersion.value(); + if (version > kVersion) { + return NN_ERROR() << "Insufficient version: " << version << " vs required " << kVersion; + } + return utils::unvalidatedConvert(canonical); +} + } // anonymous namespace -nn::GeneralResult convert(const nn::OperandType& operandType) { +nn::GeneralResult unvalidatedConvert(const nn::OperandType& operandType) { return static_cast(operandType); } -nn::GeneralResult convert(const nn::OperationType& operationType) { +nn::GeneralResult unvalidatedConvert(const nn::OperationType& operationType) { return static_cast(operationType); } -nn::GeneralResult convert(const nn::Operand::LifeTime& lifetime) { +nn::GeneralResult unvalidatedConvert(const nn::Operand::LifeTime& lifetime) { if (lifetime == nn::Operand::LifeTime::POINTER) { return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) - << "Model cannot be converted because it contains pointer-based memory"; + << "Model cannot be unvalidatedConverted because it contains pointer-based memory"; } return static_cast(lifetime); } -nn::GeneralResult convert(const nn::DeviceStatus& deviceStatus) { +nn::GeneralResult unvalidatedConvert(const nn::DeviceStatus& deviceStatus) { return static_cast(deviceStatus); } -nn::GeneralResult convert( +nn::GeneralResult unvalidatedConvert( const nn::Capabilities::PerformanceInfo& performanceInfo) { return PerformanceInfo{ .execTime = performanceInfo.execTime, @@ -248,16 +304,16 @@ nn::GeneralResult convert( }; } -nn::GeneralResult convert(const nn::Capabilities& capabilities) { +nn::GeneralResult unvalidatedConvert(const nn::Capabilities& capabilities) { return Capabilities{ - .float32Performance = NN_TRY(convert( + .float32Performance = NN_TRY(unvalidatedConvert( capabilities.operandPerformance.lookup(nn::OperandType::TENSOR_FLOAT32))), - .quantized8Performance = NN_TRY(convert( + .quantized8Performance = NN_TRY(unvalidatedConvert( capabilities.operandPerformance.lookup(nn::OperandType::TENSOR_QUANT8_ASYMM))), }; } -nn::GeneralResult convert(const nn::DataLocation& location) { +nn::GeneralResult unvalidatedConvert(const nn::DataLocation& location) { return DataLocation{ .poolIndex = location.poolIndex, .offset = location.offset, @@ -265,42 +321,43 @@ nn::GeneralResult convert(const nn::DataLocation& location) { }; } -nn::GeneralResult convert(const nn::Operand& operand) { +nn::GeneralResult unvalidatedConvert(const nn::Operand& operand) { return Operand{ - .type = NN_TRY(convert(operand.type)), + .type = NN_TRY(unvalidatedConvert(operand.type)), .dimensions = operand.dimensions, .numberOfConsumers = 0, .scale = operand.scale, .zeroPoint = operand.zeroPoint, - .lifetime = NN_TRY(convert(operand.lifetime)), - .location = NN_TRY(convert(operand.location)), + .lifetime = NN_TRY(unvalidatedConvert(operand.lifetime)), + .location = NN_TRY(unvalidatedConvert(operand.location)), }; } -nn::GeneralResult convert(const nn::Operation& operation) { +nn::GeneralResult unvalidatedConvert(const nn::Operation& operation) { return Operation{ - .type = NN_TRY(convert(operation.type)), + .type = NN_TRY(unvalidatedConvert(operation.type)), .inputs = operation.inputs, .outputs = operation.outputs, }; } -nn::GeneralResult> convert(const nn::Model::OperandValues& operandValues) { +nn::GeneralResult> unvalidatedConvert( + const nn::Model::OperandValues& operandValues) { return hidl_vec(operandValues.data(), operandValues.data() + operandValues.size()); } -nn::GeneralResult convert(const nn::Memory& memory) { +nn::GeneralResult unvalidatedConvert(const nn::Memory& memory) { return hidl_memory(memory.name, NN_TRY(hal::utils::hidlHandleFromSharedHandle(memory.handle)), memory.size); } -nn::GeneralResult convert(const nn::Model& model) { +nn::GeneralResult unvalidatedConvert(const nn::Model& model) { if (!hal::utils::hasNoPointerData(model)) { return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) - << "Mdoel cannot be converted because it contains pointer-based memory"; + << "Mdoel cannot be unvalidatedConverted because it contains pointer-based memory"; } - auto operands = NN_TRY(convert(model.main.operands)); + auto operands = NN_TRY(unvalidatedConvert(model.main.operands)); // Update number of consumers. const auto numberOfConsumers = @@ -312,45 +369,46 @@ nn::GeneralResult convert(const nn::Model& model) { return Model{ .operands = std::move(operands), - .operations = NN_TRY(convert(model.main.operations)), + .operations = NN_TRY(unvalidatedConvert(model.main.operations)), .inputIndexes = model.main.inputIndexes, .outputIndexes = model.main.outputIndexes, - .operandValues = NN_TRY(convert(model.operandValues)), - .pools = NN_TRY(convert(model.pools)), + .operandValues = NN_TRY(unvalidatedConvert(model.operandValues)), + .pools = NN_TRY(unvalidatedConvert(model.pools)), }; } -nn::GeneralResult convert(const nn::Request::Argument& requestArgument) { +nn::GeneralResult unvalidatedConvert( + const nn::Request::Argument& requestArgument) { if (requestArgument.lifetime == nn::Request::Argument::LifeTime::POINTER) { return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) - << "Request cannot be converted because it contains pointer-based memory"; + << "Request cannot be unvalidatedConverted because it contains pointer-based memory"; } const bool hasNoValue = requestArgument.lifetime == nn::Request::Argument::LifeTime::NO_VALUE; return RequestArgument{ .hasNoValue = hasNoValue, - .location = NN_TRY(convert(requestArgument.location)), + .location = NN_TRY(unvalidatedConvert(requestArgument.location)), .dimensions = requestArgument.dimensions, }; } -nn::GeneralResult convert(const nn::Request::MemoryPool& memoryPool) { - return convert(std::get(memoryPool)); +nn::GeneralResult unvalidatedConvert(const nn::Request::MemoryPool& memoryPool) { + return unvalidatedConvert(std::get(memoryPool)); } -nn::GeneralResult convert(const nn::Request& request) { +nn::GeneralResult unvalidatedConvert(const nn::Request& request) { if (!hal::utils::hasNoPointerData(request)) { return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) - << "Request cannot be converted because it contains pointer-based memory"; + << "Request cannot be unvalidatedConverted because it contains pointer-based memory"; } return Request{ - .inputs = NN_TRY(convert(request.inputs)), - .outputs = NN_TRY(convert(request.outputs)), - .pools = NN_TRY(convert(request.pools)), + .inputs = NN_TRY(unvalidatedConvert(request.inputs)), + .outputs = NN_TRY(unvalidatedConvert(request.outputs)), + .pools = NN_TRY(unvalidatedConvert(request.pools)), }; } -nn::GeneralResult convert(const nn::ErrorStatus& status) { +nn::GeneralResult unvalidatedConvert(const nn::ErrorStatus& status) { switch (status) { case nn::ErrorStatus::NONE: case nn::ErrorStatus::DEVICE_UNAVAILABLE: @@ -363,4 +421,24 @@ nn::GeneralResult convert(const nn::ErrorStatus& status) { } } +nn::GeneralResult convert(const nn::DeviceStatus& deviceStatus) { + return validatedConvert(deviceStatus); +} + +nn::GeneralResult convert(const nn::Capabilities& capabilities) { + return validatedConvert(capabilities); +} + +nn::GeneralResult convert(const nn::Model& model) { + return validatedConvert(model); +} + +nn::GeneralResult convert(const nn::Request& request) { + return validatedConvert(request); +} + +nn::GeneralResult convert(const nn::ErrorStatus& status) { + return validatedConvert(status); +} + } // namespace android::hardware::neuralnetworks::V1_0::utils diff --git a/neuralnetworks/1.0/utils/src/Device.cpp b/neuralnetworks/1.0/utils/src/Device.cpp index 671416b9eb..ab3f5afb23 100644 --- a/neuralnetworks/1.0/utils/src/Device.cpp +++ b/neuralnetworks/1.0/utils/src/Device.cpp @@ -48,11 +48,10 @@ nn::GeneralResult initCapabilities(V1_0::IDevice* device) { << "uninitialized"; const auto cb = [&result](ErrorStatus status, const Capabilities& capabilities) { if (status != ErrorStatus::NONE) { - const auto canonical = - validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); result = NN_ERROR(canonical) << "getCapabilities failed with " << toString(status); } else { - result = validatedConvertToCanonical(capabilities); + result = nn::convert(capabilities); } }; @@ -135,8 +134,7 @@ nn::GeneralResult> Device::getSupportedOperations(const nn::Mo << "uninitialized"; auto cb = [&result, &model](ErrorStatus status, const hidl_vec& supportedOperations) { if (status != ErrorStatus::NONE) { - const auto canonical = - validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); result = NN_ERROR(canonical) << "getSupportedOperations failed with " << toString(status); } else if (supportedOperations.size() != model.main.operations.size()) { @@ -172,8 +170,7 @@ nn::GeneralResult Device::prepareModel( const auto ret = kDevice->prepareModel(hidlModel, cb); const auto status = NN_TRY(hal::utils::handleTransportError(ret)); if (status != ErrorStatus::NONE) { - const auto canonical = - validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); return NN_ERROR(canonical) << "prepareModel failed with " << toString(status); } diff --git a/neuralnetworks/1.0/utils/src/PreparedModel.cpp b/neuralnetworks/1.0/utils/src/PreparedModel.cpp index 11ccbe3221..80f885a64e 100644 --- a/neuralnetworks/1.0/utils/src/PreparedModel.cpp +++ b/neuralnetworks/1.0/utils/src/PreparedModel.cpp @@ -70,8 +70,7 @@ nn::ExecutionResult, nn::Timing>> Prepare const auto status = NN_TRY(hal::utils::makeExecutionFailure(hal::utils::handleTransportError(ret))); if (status != ErrorStatus::NONE) { - const auto canonical = - validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); return NN_ERROR(canonical) << "execute failed with " << toString(status); } diff --git a/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Conversions.h b/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Conversions.h index 16ddd53496..f64646257f 100644 --- a/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Conversions.h +++ b/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Conversions.h @@ -24,9 +24,14 @@ namespace android::nn { -GeneralResult convert(const hal::V1_1::OperationType& operationType); +GeneralResult unvalidatedConvert(const hal::V1_1::OperationType& operationType); +GeneralResult unvalidatedConvert(const hal::V1_1::Capabilities& capabilities); +GeneralResult unvalidatedConvert(const hal::V1_1::Operation& operation); +GeneralResult unvalidatedConvert(const hal::V1_1::Model& model); +GeneralResult unvalidatedConvert( + const hal::V1_1::ExecutionPreference& executionPreference); + GeneralResult convert(const hal::V1_1::Capabilities& capabilities); -GeneralResult convert(const hal::V1_1::Operation& operation); GeneralResult convert(const hal::V1_1::Model& model); GeneralResult convert( const hal::V1_1::ExecutionPreference& executionPreference); @@ -35,9 +40,14 @@ GeneralResult convert( namespace android::hardware::neuralnetworks::V1_1::utils { -nn::GeneralResult convert(const nn::OperationType& operationType); +nn::GeneralResult unvalidatedConvert(const nn::OperationType& operationType); +nn::GeneralResult unvalidatedConvert(const nn::Capabilities& capabilities); +nn::GeneralResult unvalidatedConvert(const nn::Operation& operation); +nn::GeneralResult unvalidatedConvert(const nn::Model& model); +nn::GeneralResult unvalidatedConvert( + const nn::ExecutionPreference& executionPreference); + nn::GeneralResult convert(const nn::Capabilities& capabilities); -nn::GeneralResult convert(const nn::Operation& operation); nn::GeneralResult convert(const nn::Model& model); nn::GeneralResult convert(const nn::ExecutionPreference& executionPreference); diff --git a/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Utils.h b/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Utils.h index 0fee628eb6..052d88e922 100644 --- a/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Utils.h +++ b/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Utils.h @@ -22,15 +22,12 @@ #include #include #include -#include #include -#include #include namespace android::hardware::neuralnetworks::V1_1::utils { constexpr auto kDefaultExecutionPreference = ExecutionPreference::FAST_SINGLE_ANSWER; -constexpr auto kVersion = nn::Version::ANDROID_P; template nn::Result validate(const Type& halObject) { @@ -38,11 +35,6 @@ nn::Result validate(const Type& halObject) { if (!maybeCanonical.has_value()) { return nn::error() << maybeCanonical.error().message; } - const auto version = NN_TRY(nn::validate(maybeCanonical.value())); - if (version > utils::kVersion) { - return NN_ERROR() << "Insufficient version: " << version << " vs required " - << utils::kVersion; - } return {}; } @@ -55,21 +47,6 @@ bool valid(const Type& halObject) { return result.has_value(); } -template -decltype(nn::convert(std::declval())) validatedConvertToCanonical(const Type& halObject) { - auto canonical = NN_TRY(nn::convert(halObject)); - const auto maybeVersion = nn::validate(canonical); - if (!maybeVersion.has_value()) { - return nn::error() << maybeVersion.error(); - } - const auto version = maybeVersion.value(); - if (version > utils::kVersion) { - return NN_ERROR() << "Insufficient version: " << version << " vs required " - << utils::kVersion; - } - return canonical; -} - } // namespace android::hardware::neuralnetworks::V1_1::utils #endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_1_UTILS_H diff --git a/neuralnetworks/1.1/utils/src/Conversions.cpp b/neuralnetworks/1.1/utils/src/Conversions.cpp index ffe0752c11..359f68ad4d 100644 --- a/neuralnetworks/1.1/utils/src/Conversions.cpp +++ b/neuralnetworks/1.1/utils/src/Conversions.cpp @@ -23,7 +23,9 @@ #include #include #include +#include #include +#include #include #include @@ -33,35 +35,58 @@ #include #include +namespace { + +constexpr auto kVersion = android::nn::Version::ANDROID_P; + +} // namespace + namespace android::nn { namespace { using hardware::hidl_vec; template -using convertOutput = std::decay_t()).value())>; +using unvalidatedConvertOutput = + std::decay_t()).value())>; template -GeneralResult>> convert(const hidl_vec& arguments) { - std::vector> canonical; +GeneralResult>> unvalidatedConvert( + const hidl_vec& arguments) { + std::vector> canonical; canonical.reserve(arguments.size()); for (const auto& argument : arguments) { - canonical.push_back(NN_TRY(nn::convert(argument))); + canonical.push_back(NN_TRY(nn::unvalidatedConvert(argument))); + } + return canonical; +} + +template +decltype(nn::unvalidatedConvert(std::declval())) validatedConvert(const Type& halObject) { + auto canonical = NN_TRY(nn::unvalidatedConvert(halObject)); + const auto maybeVersion = validate(canonical); + if (!maybeVersion.has_value()) { + return error() << maybeVersion.error(); + } + const auto version = maybeVersion.value(); + if (version > kVersion) { + return NN_ERROR() << "Insufficient version: " << version << " vs required " << kVersion; } return canonical; } } // anonymous namespace -GeneralResult convert(const hal::V1_1::OperationType& operationType) { +GeneralResult unvalidatedConvert(const hal::V1_1::OperationType& operationType) { return static_cast(operationType); } -GeneralResult convert(const hal::V1_1::Capabilities& capabilities) { - const auto quantized8Performance = NN_TRY(convert(capabilities.quantized8Performance)); - const auto float32Performance = NN_TRY(convert(capabilities.float32Performance)); +GeneralResult unvalidatedConvert(const hal::V1_1::Capabilities& capabilities) { + const auto quantized8Performance = + NN_TRY(unvalidatedConvert(capabilities.quantized8Performance)); + const auto float32Performance = NN_TRY(unvalidatedConvert(capabilities.float32Performance)); const auto relaxedFloat32toFloat16Performance = - NN_TRY(convert(capabilities.relaxedFloat32toFloat16Performance)); + NN_TRY(unvalidatedConvert(capabilities.relaxedFloat32toFloat16Performance)); auto table = hal::utils::makeQuantized8PerformanceConsistentWithP(float32Performance, quantized8Performance); @@ -73,16 +98,16 @@ GeneralResult convert(const hal::V1_1::Capabilities& capabilities) }; } -GeneralResult convert(const hal::V1_1::Operation& operation) { +GeneralResult unvalidatedConvert(const hal::V1_1::Operation& operation) { return Operation{ - .type = NN_TRY(convert(operation.type)), + .type = NN_TRY(unvalidatedConvert(operation.type)), .inputs = operation.inputs, .outputs = operation.outputs, }; } -GeneralResult convert(const hal::V1_1::Model& model) { - auto operations = NN_TRY(convert(model.operations)); +GeneralResult unvalidatedConvert(const hal::V1_1::Model& model) { + auto operations = NN_TRY(unvalidatedConvert(model.operations)); // Verify number of consumers. const auto numberOfConsumers = @@ -97,7 +122,7 @@ GeneralResult convert(const hal::V1_1::Model& model) { } auto main = Model::Subgraph{ - .operands = NN_TRY(convert(model.operands)), + .operands = NN_TRY(unvalidatedConvert(model.operands)), .operations = std::move(operations), .inputIndexes = model.inputIndexes, .outputIndexes = model.outputIndexes, @@ -105,85 +130,114 @@ GeneralResult convert(const hal::V1_1::Model& model) { return Model{ .main = std::move(main), - .operandValues = NN_TRY(convert(model.operandValues)), - .pools = NN_TRY(convert(model.pools)), + .operandValues = NN_TRY(unvalidatedConvert(model.operandValues)), + .pools = NN_TRY(unvalidatedConvert(model.pools)), .relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16, }; } -GeneralResult convert( +GeneralResult unvalidatedConvert( const hal::V1_1::ExecutionPreference& executionPreference) { return static_cast(executionPreference); } +GeneralResult convert(const hal::V1_1::Capabilities& capabilities) { + return validatedConvert(capabilities); +} + +GeneralResult convert(const hal::V1_1::Model& model) { + return validatedConvert(model); +} + +GeneralResult convert( + const hal::V1_1::ExecutionPreference& executionPreference) { + return validatedConvert(executionPreference); +} + } // namespace android::nn namespace android::hardware::neuralnetworks::V1_1::utils { namespace { -using utils::convert; +using utils::unvalidatedConvert; -nn::GeneralResult convert( +nn::GeneralResult unvalidatedConvert( const nn::Capabilities::PerformanceInfo& performanceInfo) { - return V1_0::utils::convert(performanceInfo); + return V1_0::utils::unvalidatedConvert(performanceInfo); } -nn::GeneralResult convert(const nn::Operand& operand) { - return V1_0::utils::convert(operand); +nn::GeneralResult unvalidatedConvert(const nn::Operand& operand) { + return V1_0::utils::unvalidatedConvert(operand); } -nn::GeneralResult> convert(const nn::Model::OperandValues& operandValues) { - return V1_0::utils::convert(operandValues); +nn::GeneralResult> unvalidatedConvert( + const nn::Model::OperandValues& operandValues) { + return V1_0::utils::unvalidatedConvert(operandValues); } -nn::GeneralResult convert(const nn::Memory& memory) { - return V1_0::utils::convert(memory); +nn::GeneralResult unvalidatedConvert(const nn::Memory& memory) { + return V1_0::utils::unvalidatedConvert(memory); } template -using convertOutput = std::decay_t()).value())>; +using unvalidatedConvertOutput = + std::decay_t()).value())>; template -nn::GeneralResult>> convert(const std::vector& arguments) { - hidl_vec> halObject(arguments.size()); +nn::GeneralResult>> unvalidatedConvert( + const std::vector& arguments) { + hidl_vec> halObject(arguments.size()); for (size_t i = 0; i < arguments.size(); ++i) { - halObject[i] = NN_TRY(convert(arguments[i])); + halObject[i] = NN_TRY(unvalidatedConvert(arguments[i])); } return halObject; } +template +decltype(utils::unvalidatedConvert(std::declval())) validatedConvert(const Type& canonical) { + const auto maybeVersion = nn::validate(canonical); + if (!maybeVersion.has_value()) { + return nn::error() << maybeVersion.error(); + } + const auto version = maybeVersion.value(); + if (version > kVersion) { + return NN_ERROR() << "Insufficient version: " << version << " vs required " << kVersion; + } + return utils::unvalidatedConvert(canonical); +} + } // anonymous namespace -nn::GeneralResult convert(const nn::OperationType& operationType) { +nn::GeneralResult unvalidatedConvert(const nn::OperationType& operationType) { return static_cast(operationType); } -nn::GeneralResult convert(const nn::Capabilities& capabilities) { +nn::GeneralResult unvalidatedConvert(const nn::Capabilities& capabilities) { return Capabilities{ - .float32Performance = NN_TRY(convert( + .float32Performance = NN_TRY(unvalidatedConvert( capabilities.operandPerformance.lookup(nn::OperandType::TENSOR_FLOAT32))), - .quantized8Performance = NN_TRY(convert( + .quantized8Performance = NN_TRY(unvalidatedConvert( capabilities.operandPerformance.lookup(nn::OperandType::TENSOR_QUANT8_ASYMM))), - .relaxedFloat32toFloat16Performance = - NN_TRY(convert(capabilities.relaxedFloat32toFloat16PerformanceTensor)), + .relaxedFloat32toFloat16Performance = NN_TRY( + unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceTensor)), }; } -nn::GeneralResult convert(const nn::Operation& operation) { +nn::GeneralResult unvalidatedConvert(const nn::Operation& operation) { return Operation{ - .type = NN_TRY(convert(operation.type)), + .type = NN_TRY(unvalidatedConvert(operation.type)), .inputs = operation.inputs, .outputs = operation.outputs, }; } -nn::GeneralResult convert(const nn::Model& model) { +nn::GeneralResult unvalidatedConvert(const nn::Model& model) { if (!hal::utils::hasNoPointerData(model)) { return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) - << "Mdoel cannot be converted because it contains pointer-based memory"; + << "Mdoel cannot be unvalidatedConverted because it contains pointer-based memory"; } - auto operands = NN_TRY(convert(model.main.operands)); + auto operands = NN_TRY(unvalidatedConvert(model.main.operands)); // Update number of consumers. const auto numberOfConsumers = @@ -195,17 +249,30 @@ nn::GeneralResult convert(const nn::Model& model) { return Model{ .operands = std::move(operands), - .operations = NN_TRY(convert(model.main.operations)), + .operations = NN_TRY(unvalidatedConvert(model.main.operations)), .inputIndexes = model.main.inputIndexes, .outputIndexes = model.main.outputIndexes, - .operandValues = NN_TRY(convert(model.operandValues)), - .pools = NN_TRY(convert(model.pools)), + .operandValues = NN_TRY(unvalidatedConvert(model.operandValues)), + .pools = NN_TRY(unvalidatedConvert(model.pools)), .relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16, }; } -nn::GeneralResult convert(const nn::ExecutionPreference& executionPreference) { +nn::GeneralResult unvalidatedConvert( + const nn::ExecutionPreference& executionPreference) { return static_cast(executionPreference); } +nn::GeneralResult convert(const nn::Capabilities& capabilities) { + return validatedConvert(capabilities); +} + +nn::GeneralResult convert(const nn::Model& model) { + return validatedConvert(model); +} + +nn::GeneralResult convert(const nn::ExecutionPreference& executionPreference) { + return validatedConvert(executionPreference); +} + } // namespace android::hardware::neuralnetworks::V1_1::utils diff --git a/neuralnetworks/1.1/utils/src/Device.cpp b/neuralnetworks/1.1/utils/src/Device.cpp index a0378c94a0..e45b17ec6e 100644 --- a/neuralnetworks/1.1/utils/src/Device.cpp +++ b/neuralnetworks/1.1/utils/src/Device.cpp @@ -49,11 +49,10 @@ nn::GeneralResult initCapabilities(V1_1::IDevice* device) { << "uninitialized"; const auto cb = [&result](V1_0::ErrorStatus status, const Capabilities& capabilities) { if (status != V1_0::ErrorStatus::NONE) { - const auto canonical = - validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); result = NN_ERROR(canonical) << "getCapabilities_1_1 failed with " << toString(status); } else { - result = validatedConvertToCanonical(capabilities); + result = nn::convert(capabilities); } }; @@ -137,8 +136,7 @@ nn::GeneralResult> Device::getSupportedOperations(const nn::Mo auto cb = [&result, &model](V1_0::ErrorStatus status, const hidl_vec& supportedOperations) { if (status != V1_0::ErrorStatus::NONE) { - const auto canonical = - validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); result = NN_ERROR(canonical) << "getSupportedOperations_1_1 failed with " << toString(status); } else if (supportedOperations.size() != model.main.operations.size()) { @@ -175,8 +173,7 @@ nn::GeneralResult Device::prepareModel( const auto ret = kDevice->prepareModel_1_1(hidlModel, hidlPreference, cb); const auto status = NN_TRY(hal::utils::handleTransportError(ret)); if (status != V1_0::ErrorStatus::NONE) { - const auto canonical = - validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); return NN_ERROR(canonical) << "prepareModel failed with " << toString(status); } diff --git a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Conversions.h b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Conversions.h index 24911fea08..5dcbc0bb79 100644 --- a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Conversions.h +++ b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Conversions.h @@ -24,27 +24,34 @@ namespace android::nn { -GeneralResult convert(const hal::V1_2::OperandType& operandType); -GeneralResult convert(const hal::V1_2::OperationType& operationType); -GeneralResult convert(const hal::V1_2::DeviceType& deviceType); -GeneralResult convert(const hal::V1_2::Capabilities& capabilities); -GeneralResult convert( +GeneralResult unvalidatedConvert(const hal::V1_2::OperandType& operandType); +GeneralResult unvalidatedConvert(const hal::V1_2::OperationType& operationType); +GeneralResult unvalidatedConvert(const hal::V1_2::DeviceType& deviceType); +GeneralResult unvalidatedConvert(const hal::V1_2::Capabilities& capabilities); +GeneralResult unvalidatedConvert( const hal::V1_2::Capabilities::OperandPerformance& operandPerformance); -GeneralResult convert(const hal::V1_2::Operation& operation); -GeneralResult convert( +GeneralResult unvalidatedConvert(const hal::V1_2::Operation& operation); +GeneralResult unvalidatedConvert( const hal::V1_2::SymmPerChannelQuantParams& symmPerChannelQuantParams); -GeneralResult convert(const hal::V1_2::Operand& operand); -GeneralResult convert(const hal::V1_2::Operand::ExtraParams& extraParams); -GeneralResult convert(const hal::V1_2::Model& model); -GeneralResult convert( +GeneralResult unvalidatedConvert(const hal::V1_2::Operand& operand); +GeneralResult unvalidatedConvert( + const hal::V1_2::Operand::ExtraParams& extraParams); +GeneralResult unvalidatedConvert(const hal::V1_2::Model& model); +GeneralResult unvalidatedConvert( const hal::V1_2::Model::ExtensionNameAndPrefix& extensionNameAndPrefix); -GeneralResult convert(const hal::V1_2::OutputShape& outputShape); +GeneralResult unvalidatedConvert(const hal::V1_2::OutputShape& outputShape); +GeneralResult unvalidatedConvert(const hal::V1_2::MeasureTiming& measureTiming); +GeneralResult unvalidatedConvert(const hal::V1_2::Timing& timing); +GeneralResult unvalidatedConvert(const hal::V1_2::Extension& extension); +GeneralResult unvalidatedConvert( + const hal::V1_2::Extension::OperandTypeInformation& operandTypeInformation); +GeneralResult unvalidatedConvert(const hardware::hidl_handle& handle); + +GeneralResult convert(const hal::V1_2::DeviceType& deviceType); +GeneralResult convert(const hal::V1_2::Capabilities& capabilities); +GeneralResult convert(const hal::V1_2::Model& model); GeneralResult convert(const hal::V1_2::MeasureTiming& measureTiming); GeneralResult convert(const hal::V1_2::Timing& timing); -GeneralResult convert(const hal::V1_2::Extension& extension); -GeneralResult convert( - const hal::V1_2::Extension::OperandTypeInformation& operandTypeInformation); -GeneralResult convert(const hardware::hidl_handle& handle); GeneralResult> convert( const hardware::hidl_vec& extensions); @@ -57,27 +64,34 @@ GeneralResult> convert( namespace android::hardware::neuralnetworks::V1_2::utils { -nn::GeneralResult convert(const nn::OperandType& operandType); -nn::GeneralResult convert(const nn::OperationType& operationType); -nn::GeneralResult convert(const nn::DeviceType& deviceType); -nn::GeneralResult convert(const nn::Capabilities& capabilities); -nn::GeneralResult convert( +nn::GeneralResult unvalidatedConvert(const nn::OperandType& operandType); +nn::GeneralResult unvalidatedConvert(const nn::OperationType& operationType); +nn::GeneralResult unvalidatedConvert(const nn::DeviceType& deviceType); +nn::GeneralResult unvalidatedConvert(const nn::Capabilities& capabilities); +nn::GeneralResult unvalidatedConvert( const nn::Capabilities::OperandPerformance& operandPerformance); -nn::GeneralResult convert(const nn::Operation& operation); -nn::GeneralResult convert( +nn::GeneralResult unvalidatedConvert(const nn::Operation& operation); +nn::GeneralResult unvalidatedConvert( const nn::Operand::SymmPerChannelQuantParams& symmPerChannelQuantParams); -nn::GeneralResult convert(const nn::Operand& operand); -nn::GeneralResult convert(const nn::Operand::ExtraParams& extraParams); -nn::GeneralResult convert(const nn::Model& model); -nn::GeneralResult convert( +nn::GeneralResult unvalidatedConvert(const nn::Operand& operand); +nn::GeneralResult unvalidatedConvert( + const nn::Operand::ExtraParams& extraParams); +nn::GeneralResult unvalidatedConvert(const nn::Model& model); +nn::GeneralResult unvalidatedConvert( const nn::Model::ExtensionNameAndPrefix& extensionNameAndPrefix); -nn::GeneralResult convert(const nn::OutputShape& outputShape); +nn::GeneralResult unvalidatedConvert(const nn::OutputShape& outputShape); +nn::GeneralResult unvalidatedConvert(const nn::MeasureTiming& measureTiming); +nn::GeneralResult unvalidatedConvert(const nn::Timing& timing); +nn::GeneralResult unvalidatedConvert(const nn::Extension& extension); +nn::GeneralResult unvalidatedConvert( + const nn::Extension::OperandTypeInformation& operandTypeInformation); +nn::GeneralResult unvalidatedConvert(const nn::SharedHandle& handle); + +nn::GeneralResult convert(const nn::DeviceType& deviceType); +nn::GeneralResult convert(const nn::Capabilities& capabilities); +nn::GeneralResult convert(const nn::Model& model); nn::GeneralResult convert(const nn::MeasureTiming& measureTiming); nn::GeneralResult convert(const nn::Timing& timing); -nn::GeneralResult convert(const nn::Extension& extension); -nn::GeneralResult convert( - const nn::Extension::OperandTypeInformation& operandTypeInformation); -nn::GeneralResult convert(const nn::SharedHandle& handle); nn::GeneralResult> convert(const std::vector& extensions); nn::GeneralResult> convert(const std::vector& handles); diff --git a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Utils.h b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Utils.h index a9a6baeccc..70149a2d3a 100644 --- a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Utils.h +++ b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Utils.h @@ -22,9 +22,7 @@ #include #include #include -#include #include -#include #include #include @@ -35,7 +33,6 @@ namespace android::hardware::neuralnetworks::V1_2::utils { constexpr auto kDefaultMesaureTiming = MeasureTiming::NO; constexpr auto kNoTiming = Timing{.timeOnDevice = std::numeric_limits::max(), .timeInDriver = std::numeric_limits::max()}; -constexpr auto kVersion = nn::Version::ANDROID_Q; template nn::Result validate(const Type& halObject) { @@ -43,11 +40,6 @@ nn::Result validate(const Type& halObject) { if (!maybeCanonical.has_value()) { return nn::error() << maybeCanonical.error().message; } - const auto version = NN_TRY(nn::validate(maybeCanonical.value())); - if (version > utils::kVersion) { - return NN_ERROR() << "Insufficient version: " << version << " vs required " - << utils::kVersion; - } return {}; } @@ -60,21 +52,6 @@ bool valid(const Type& halObject) { return result.has_value(); } -template -decltype(nn::convert(std::declval())) validatedConvertToCanonical(const Type& halObject) { - auto canonical = NN_TRY(nn::convert(halObject)); - const auto maybeVersion = nn::validate(canonical); - if (!maybeVersion.has_value()) { - return nn::error() << maybeVersion.error(); - } - const auto version = maybeVersion.value(); - if (version > utils::kVersion) { - return NN_ERROR() << "Insufficient version: " << version << " vs required " - << utils::kVersion; - } - return canonical; -} - } // namespace android::hardware::neuralnetworks::V1_2::utils #endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_2_UTILS_H diff --git a/neuralnetworks/1.2/utils/src/Callbacks.cpp b/neuralnetworks/1.2/utils/src/Callbacks.cpp index cb739f0eeb..39f88c2c5e 100644 --- a/neuralnetworks/1.2/utils/src/Callbacks.cpp +++ b/neuralnetworks/1.2/utils/src/Callbacks.cpp @@ -52,8 +52,7 @@ nn::GeneralResult convertPreparedModel( nn::GeneralResult, nn::Timing>> convertExecutionGeneralResultsHelper(const hidl_vec& outputShapes, const Timing& timing) { - return std::make_pair(NN_TRY(validatedConvertToCanonical(outputShapes)), - NN_TRY(validatedConvertToCanonical(timing))); + return std::make_pair(NN_TRY(nn::convert(outputShapes)), NN_TRY(nn::convert(timing))); } nn::ExecutionResult, nn::Timing>> @@ -67,8 +66,7 @@ convertExecutionGeneralResults(const hidl_vec& outputShapes, const Return PreparedModelCallback::notify(V1_0::ErrorStatus status, const sp& preparedModel) { if (status != V1_0::ErrorStatus::NONE) { - const auto canonical = - validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); notifyInternal(NN_ERROR(canonical) << "preparedModel failed with " << toString(status)); } else if (preparedModel == nullptr) { notifyInternal(NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) @@ -82,8 +80,7 @@ Return PreparedModelCallback::notify(V1_0::ErrorStatus status, Return PreparedModelCallback::notify_1_2(V1_0::ErrorStatus status, const sp& preparedModel) { if (status != V1_0::ErrorStatus::NONE) { - const auto canonical = - validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); notifyInternal(NN_ERROR(canonical) << "preparedModel failed with " << toString(status)); } else if (preparedModel == nullptr) { notifyInternal(NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) @@ -110,8 +107,7 @@ void PreparedModelCallback::notifyInternal(PreparedModelCallback::Data result) { Return ExecutionCallback::notify(V1_0::ErrorStatus status) { if (status != V1_0::ErrorStatus::NONE) { - const auto canonical = - validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); notifyInternal(NN_ERROR(canonical) << "execute failed with " << toString(status)); } else { notifyInternal({}); @@ -123,8 +119,7 @@ Return ExecutionCallback::notify_1_2(V1_0::ErrorStatus status, const hidl_vec& outputShapes, const Timing& timing) { if (status != V1_0::ErrorStatus::NONE) { - const auto canonical = - validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); notifyInternal(NN_ERROR(canonical) << "execute failed with " << toString(status)); } else { notifyInternal(convertExecutionGeneralResults(outputShapes, timing)); diff --git a/neuralnetworks/1.2/utils/src/Conversions.cpp b/neuralnetworks/1.2/utils/src/Conversions.cpp index 08c94dec33..f11474fd60 100644 --- a/neuralnetworks/1.2/utils/src/Conversions.cpp +++ b/neuralnetworks/1.2/utils/src/Conversions.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -42,6 +43,8 @@ constexpr std::underlying_type_t underlyingType(Type value) { return static_cast>(value); } +constexpr auto kVersion = android::nn::Version::ANDROID_Q; + } // namespace namespace android::nn { @@ -76,42 +79,70 @@ using hardware::hidl_handle; using hardware::hidl_vec; template -using ConvertOutput = std::decay_t()).value())>; +using unvalidatedConvertOutput = + std::decay_t()).value())>; template -GeneralResult>> convertVec(const hidl_vec& arguments) { - std::vector> canonical; +GeneralResult>> unvalidatedConvertVec( + const hidl_vec& arguments) { + std::vector> canonical; canonical.reserve(arguments.size()); for (const auto& argument : arguments) { - canonical.push_back(NN_TRY(nn::convert(argument))); + canonical.push_back(NN_TRY(nn::unvalidatedConvert(argument))); } return canonical; } template -GeneralResult>> convert(const hidl_vec& arguments) { - return convertVec(arguments); +GeneralResult>> unvalidatedConvert( + const hidl_vec& arguments) { + return unvalidatedConvertVec(arguments); +} + +template +decltype(nn::unvalidatedConvert(std::declval())) validatedConvert(const Type& halObject) { + auto canonical = NN_TRY(nn::unvalidatedConvert(halObject)); + const auto maybeVersion = validate(canonical); + if (!maybeVersion.has_value()) { + return error() << maybeVersion.error(); + } + const auto version = maybeVersion.value(); + if (version > kVersion) { + return NN_ERROR() << "Insufficient version: " << version << " vs required " << kVersion; + } + return canonical; +} + +template +GeneralResult>> validatedConvert( + const hidl_vec& arguments) { + std::vector> canonical; + canonical.reserve(arguments.size()); + for (const auto& argument : arguments) { + canonical.push_back(NN_TRY(validatedConvert(argument))); + } + return canonical; } } // anonymous namespace -GeneralResult convert(const hal::V1_2::OperandType& operandType) { +GeneralResult unvalidatedConvert(const hal::V1_2::OperandType& operandType) { return static_cast(operandType); } -GeneralResult convert(const hal::V1_2::OperationType& operationType) { +GeneralResult unvalidatedConvert(const hal::V1_2::OperationType& operationType) { return static_cast(operationType); } -GeneralResult convert(const hal::V1_2::DeviceType& deviceType) { +GeneralResult unvalidatedConvert(const hal::V1_2::DeviceType& deviceType) { return static_cast(deviceType); } -GeneralResult convert(const hal::V1_2::Capabilities& capabilities) { +GeneralResult unvalidatedConvert(const hal::V1_2::Capabilities& capabilities) { const bool validOperandTypes = std::all_of( capabilities.operandPerformance.begin(), capabilities.operandPerformance.end(), [](const hal::V1_2::Capabilities::OperandPerformance& operandPerformance) { - const auto maybeType = convert(operandPerformance.type); + const auto maybeType = unvalidatedConvert(operandPerformance.type); return !maybeType.has_value() ? false : validOperandType(maybeType.value()); }); if (!validOperandTypes) { @@ -120,10 +151,10 @@ GeneralResult convert(const hal::V1_2::Capabilities& capabilities) } const auto relaxedFloat32toFloat16PerformanceScalar = - NN_TRY(convert(capabilities.relaxedFloat32toFloat16PerformanceScalar)); + NN_TRY(unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceScalar)); const auto relaxedFloat32toFloat16PerformanceTensor = - NN_TRY(convert(capabilities.relaxedFloat32toFloat16PerformanceTensor)); - auto operandPerformance = NN_TRY(convert(capabilities.operandPerformance)); + NN_TRY(unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceTensor)); + auto operandPerformance = NN_TRY(unvalidatedConvert(capabilities.operandPerformance)); auto table = NN_TRY(hal::utils::makeGeneralFailure( Capabilities::OperandPerformanceTable::create(std::move(operandPerformance)), @@ -136,23 +167,23 @@ GeneralResult convert(const hal::V1_2::Capabilities& capabilities) }; } -GeneralResult convert( +GeneralResult unvalidatedConvert( const hal::V1_2::Capabilities::OperandPerformance& operandPerformance) { return Capabilities::OperandPerformance{ - .type = NN_TRY(convert(operandPerformance.type)), - .info = NN_TRY(convert(operandPerformance.info)), + .type = NN_TRY(unvalidatedConvert(operandPerformance.type)), + .info = NN_TRY(unvalidatedConvert(operandPerformance.info)), }; } -GeneralResult convert(const hal::V1_2::Operation& operation) { +GeneralResult unvalidatedConvert(const hal::V1_2::Operation& operation) { return Operation{ - .type = NN_TRY(convert(operation.type)), + .type = NN_TRY(unvalidatedConvert(operation.type)), .inputs = operation.inputs, .outputs = operation.outputs, }; } -GeneralResult convert( +GeneralResult unvalidatedConvert( const hal::V1_2::SymmPerChannelQuantParams& symmPerChannelQuantParams) { return Operand::SymmPerChannelQuantParams{ .scales = symmPerChannelQuantParams.scales, @@ -160,25 +191,26 @@ GeneralResult convert( }; } -GeneralResult convert(const hal::V1_2::Operand& operand) { +GeneralResult unvalidatedConvert(const hal::V1_2::Operand& operand) { return Operand{ - .type = NN_TRY(convert(operand.type)), + .type = NN_TRY(unvalidatedConvert(operand.type)), .dimensions = operand.dimensions, .scale = operand.scale, .zeroPoint = operand.zeroPoint, - .lifetime = NN_TRY(convert(operand.lifetime)), - .location = NN_TRY(convert(operand.location)), - .extraParams = NN_TRY(convert(operand.extraParams)), + .lifetime = NN_TRY(unvalidatedConvert(operand.lifetime)), + .location = NN_TRY(unvalidatedConvert(operand.location)), + .extraParams = NN_TRY(unvalidatedConvert(operand.extraParams)), }; } -GeneralResult convert(const hal::V1_2::Operand::ExtraParams& extraParams) { +GeneralResult unvalidatedConvert( + const hal::V1_2::Operand::ExtraParams& extraParams) { using Discriminator = hal::V1_2::Operand::ExtraParams::hidl_discriminator; switch (extraParams.getDiscriminator()) { case Discriminator::none: return Operand::NoParams{}; case Discriminator::channelQuant: - return convert(extraParams.channelQuant()); + return unvalidatedConvert(extraParams.channelQuant()); case Discriminator::extension: return extraParams.extension(); } @@ -187,8 +219,8 @@ GeneralResult convert(const hal::V1_2::Operand::ExtraParam << underlyingType(extraParams.getDiscriminator()); } -GeneralResult convert(const hal::V1_2::Model& model) { - auto operations = NN_TRY(convert(model.operations)); +GeneralResult unvalidatedConvert(const hal::V1_2::Model& model) { + auto operations = NN_TRY(unvalidatedConvert(model.operations)); // Verify number of consumers. const auto numberOfConsumers = @@ -203,7 +235,7 @@ GeneralResult convert(const hal::V1_2::Model& model) { } auto main = Model::Subgraph{ - .operands = NN_TRY(convert(model.operands)), + .operands = NN_TRY(unvalidatedConvert(model.operands)), .operations = std::move(operations), .inputIndexes = model.inputIndexes, .outputIndexes = model.outputIndexes, @@ -211,14 +243,14 @@ GeneralResult convert(const hal::V1_2::Model& model) { return Model{ .main = std::move(main), - .operandValues = NN_TRY(convert(model.operandValues)), - .pools = NN_TRY(convert(model.pools)), + .operandValues = NN_TRY(unvalidatedConvert(model.operandValues)), + .pools = NN_TRY(unvalidatedConvert(model.pools)), .relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16, - .extensionNameToPrefix = NN_TRY(convert(model.extensionNameToPrefix)), + .extensionNameToPrefix = NN_TRY(unvalidatedConvert(model.extensionNameToPrefix)), }; } -GeneralResult convert( +GeneralResult unvalidatedConvert( const hal::V1_2::Model::ExtensionNameAndPrefix& extensionNameAndPrefix) { return Model::ExtensionNameAndPrefix{ .name = extensionNameAndPrefix.name, @@ -226,29 +258,29 @@ GeneralResult convert( }; } -GeneralResult convert(const hal::V1_2::OutputShape& outputShape) { +GeneralResult unvalidatedConvert(const hal::V1_2::OutputShape& outputShape) { return OutputShape{ .dimensions = outputShape.dimensions, .isSufficient = outputShape.isSufficient, }; } -GeneralResult convert(const hal::V1_2::MeasureTiming& measureTiming) { +GeneralResult unvalidatedConvert(const hal::V1_2::MeasureTiming& measureTiming) { return static_cast(measureTiming); } -GeneralResult convert(const hal::V1_2::Timing& timing) { +GeneralResult unvalidatedConvert(const hal::V1_2::Timing& timing) { return Timing{.timeOnDevice = timing.timeOnDevice, .timeInDriver = timing.timeInDriver}; } -GeneralResult convert(const hal::V1_2::Extension& extension) { +GeneralResult unvalidatedConvert(const hal::V1_2::Extension& extension) { return Extension{ .name = extension.name, - .operandTypes = NN_TRY(convert(extension.operandTypes)), + .operandTypes = NN_TRY(unvalidatedConvert(extension.operandTypes)), }; } -GeneralResult convert( +GeneralResult unvalidatedConvert( const hal::V1_2::Extension::OperandTypeInformation& operandTypeInformation) { return Extension::OperandTypeInformation{ .type = operandTypeInformation.type, @@ -257,21 +289,41 @@ GeneralResult convert( }; } -GeneralResult convert(const hidl_handle& hidlHandle) { +GeneralResult unvalidatedConvert(const hidl_handle& hidlHandle) { return hal::utils::sharedHandleFromNativeHandle(hidlHandle.getNativeHandle()); } +GeneralResult convert(const hal::V1_2::DeviceType& deviceType) { + return validatedConvert(deviceType); +} + +GeneralResult convert(const hal::V1_2::Capabilities& capabilities) { + return validatedConvert(capabilities); +} + +GeneralResult convert(const hal::V1_2::Model& model) { + return validatedConvert(model); +} + +GeneralResult convert(const hal::V1_2::MeasureTiming& measureTiming) { + return validatedConvert(measureTiming); +} + +GeneralResult convert(const hal::V1_2::Timing& timing) { + return validatedConvert(timing); +} + GeneralResult> convert(const hidl_vec& extensions) { - return convertVec(extensions); + return validatedConvert(extensions); } GeneralResult> convert(const hidl_vec& handles) { - return convertVec(handles); + return validatedConvert(handles); } GeneralResult> convert( const hidl_vec& outputShapes) { - return convertVec(outputShapes); + return validatedConvert(outputShapes); } } // namespace android::nn @@ -279,44 +331,48 @@ GeneralResult> convert( namespace android::hardware::neuralnetworks::V1_2::utils { namespace { -using utils::convert; +using utils::unvalidatedConvert; -nn::GeneralResult convert(const nn::Operand::LifeTime& lifetime) { - return V1_0::utils::convert(lifetime); +nn::GeneralResult unvalidatedConvert(const nn::Operand::LifeTime& lifetime) { + return V1_0::utils::unvalidatedConvert(lifetime); } -nn::GeneralResult convert( +nn::GeneralResult unvalidatedConvert( const nn::Capabilities::PerformanceInfo& performanceInfo) { - return V1_0::utils::convert(performanceInfo); + return V1_0::utils::unvalidatedConvert(performanceInfo); } -nn::GeneralResult convert(const nn::DataLocation& location) { - return V1_0::utils::convert(location); +nn::GeneralResult unvalidatedConvert(const nn::DataLocation& location) { + return V1_0::utils::unvalidatedConvert(location); } -nn::GeneralResult> convert(const nn::Model::OperandValues& operandValues) { - return V1_0::utils::convert(operandValues); +nn::GeneralResult> unvalidatedConvert( + const nn::Model::OperandValues& operandValues) { + return V1_0::utils::unvalidatedConvert(operandValues); } -nn::GeneralResult convert(const nn::Memory& memory) { - return V1_0::utils::convert(memory); +nn::GeneralResult unvalidatedConvert(const nn::Memory& memory) { + return V1_0::utils::unvalidatedConvert(memory); } template -using ConvertOutput = std::decay_t()).value())>; +using unvalidatedConvertOutput = + std::decay_t()).value())>; template -nn::GeneralResult>> convertVec(const std::vector& arguments) { - hidl_vec> halObject(arguments.size()); +nn::GeneralResult>> unvalidatedConvertVec( + const std::vector& arguments) { + hidl_vec> halObject(arguments.size()); for (size_t i = 0; i < arguments.size(); ++i) { - halObject[i] = NN_TRY(convert(arguments[i])); + halObject[i] = NN_TRY(unvalidatedConvert(arguments[i])); } return halObject; } template -nn::GeneralResult>> convert(const std::vector& arguments) { - return convertVec(arguments); +nn::GeneralResult>> unvalidatedConvert( + const std::vector& arguments) { + return unvalidatedConvertVec(arguments); } nn::GeneralResult makeExtraParams(nn::Operand::NoParams /*noParams*/) { @@ -326,7 +382,7 @@ nn::GeneralResult makeExtraParams(nn::Operand::NoParams /* nn::GeneralResult makeExtraParams( const nn::Operand::SymmPerChannelQuantParams& channelQuant) { Operand::ExtraParams ret; - ret.channelQuant(NN_TRY(convert(channelQuant))); + ret.channelQuant(NN_TRY(unvalidatedConvert(channelQuant))); return ret; } @@ -337,17 +393,40 @@ nn::GeneralResult makeExtraParams( return ret; } +template +decltype(utils::unvalidatedConvert(std::declval())) validatedConvert(const Type& canonical) { + const auto maybeVersion = nn::validate(canonical); + if (!maybeVersion.has_value()) { + return nn::error() << maybeVersion.error(); + } + const auto version = maybeVersion.value(); + if (version > kVersion) { + return NN_ERROR() << "Insufficient version: " << version << " vs required " << kVersion; + } + return utils::unvalidatedConvert(canonical); +} + +template +nn::GeneralResult>> validatedConvert( + const std::vector& arguments) { + hidl_vec> halObject(arguments.size()); + for (size_t i = 0; i < arguments.size(); ++i) { + halObject[i] = NN_TRY(validatedConvert(arguments[i])); + } + return halObject; +} + } // anonymous namespace -nn::GeneralResult convert(const nn::OperandType& operandType) { +nn::GeneralResult unvalidatedConvert(const nn::OperandType& operandType) { return static_cast(operandType); } -nn::GeneralResult convert(const nn::OperationType& operationType) { +nn::GeneralResult unvalidatedConvert(const nn::OperationType& operationType) { return static_cast(operationType); } -nn::GeneralResult convert(const nn::DeviceType& deviceType) { +nn::GeneralResult unvalidatedConvert(const nn::DeviceType& deviceType) { switch (deviceType) { case nn::DeviceType::UNKNOWN: return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "Invalid DeviceType UNKNOWN"; @@ -361,7 +440,7 @@ nn::GeneralResult convert(const nn::DeviceType& deviceType) { << "Invalid DeviceType " << underlyingType(deviceType); } -nn::GeneralResult convert(const nn::Capabilities& capabilities) { +nn::GeneralResult unvalidatedConvert(const nn::Capabilities& capabilities) { std::vector operandPerformance; operandPerformance.reserve(capabilities.operandPerformance.asVector().size()); std::copy_if(capabilities.operandPerformance.asVector().begin(), @@ -372,31 +451,31 @@ nn::GeneralResult convert(const nn::Capabilities& capabilities) { }); return Capabilities{ - .relaxedFloat32toFloat16PerformanceScalar = - NN_TRY(convert(capabilities.relaxedFloat32toFloat16PerformanceScalar)), - .relaxedFloat32toFloat16PerformanceTensor = - NN_TRY(convert(capabilities.relaxedFloat32toFloat16PerformanceTensor)), - .operandPerformance = NN_TRY(convert(operandPerformance)), + .relaxedFloat32toFloat16PerformanceScalar = NN_TRY( + unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceScalar)), + .relaxedFloat32toFloat16PerformanceTensor = NN_TRY( + unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceTensor)), + .operandPerformance = NN_TRY(unvalidatedConvert(operandPerformance)), }; } -nn::GeneralResult convert( +nn::GeneralResult unvalidatedConvert( const nn::Capabilities::OperandPerformance& operandPerformance) { return Capabilities::OperandPerformance{ - .type = NN_TRY(convert(operandPerformance.type)), - .info = NN_TRY(convert(operandPerformance.info)), + .type = NN_TRY(unvalidatedConvert(operandPerformance.type)), + .info = NN_TRY(unvalidatedConvert(operandPerformance.info)), }; } -nn::GeneralResult convert(const nn::Operation& operation) { +nn::GeneralResult unvalidatedConvert(const nn::Operation& operation) { return Operation{ - .type = NN_TRY(convert(operation.type)), + .type = NN_TRY(unvalidatedConvert(operation.type)), .inputs = operation.inputs, .outputs = operation.outputs, }; } -nn::GeneralResult convert( +nn::GeneralResult unvalidatedConvert( const nn::Operand::SymmPerChannelQuantParams& symmPerChannelQuantParams) { return SymmPerChannelQuantParams{ .scales = symmPerChannelQuantParams.scales, @@ -404,30 +483,31 @@ nn::GeneralResult convert( }; } -nn::GeneralResult convert(const nn::Operand& operand) { +nn::GeneralResult unvalidatedConvert(const nn::Operand& operand) { return Operand{ - .type = NN_TRY(convert(operand.type)), + .type = NN_TRY(unvalidatedConvert(operand.type)), .dimensions = operand.dimensions, .numberOfConsumers = 0, .scale = operand.scale, .zeroPoint = operand.zeroPoint, - .lifetime = NN_TRY(convert(operand.lifetime)), - .location = NN_TRY(convert(operand.location)), - .extraParams = NN_TRY(convert(operand.extraParams)), + .lifetime = NN_TRY(unvalidatedConvert(operand.lifetime)), + .location = NN_TRY(unvalidatedConvert(operand.location)), + .extraParams = NN_TRY(unvalidatedConvert(operand.extraParams)), }; } -nn::GeneralResult convert(const nn::Operand::ExtraParams& extraParams) { +nn::GeneralResult unvalidatedConvert( + const nn::Operand::ExtraParams& extraParams) { return std::visit([](const auto& x) { return makeExtraParams(x); }, extraParams); } -nn::GeneralResult convert(const nn::Model& model) { +nn::GeneralResult unvalidatedConvert(const nn::Model& model) { if (!hal::utils::hasNoPointerData(model)) { return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) - << "Model cannot be converted because it contains pointer-based memory"; + << "Model cannot be unvalidatedConverted because it contains pointer-based memory"; } - auto operands = NN_TRY(convert(model.main.operands)); + auto operands = NN_TRY(unvalidatedConvert(model.main.operands)); // Update number of consumers. const auto numberOfConsumers = @@ -439,17 +519,17 @@ nn::GeneralResult convert(const nn::Model& model) { return Model{ .operands = std::move(operands), - .operations = NN_TRY(convert(model.main.operations)), + .operations = NN_TRY(unvalidatedConvert(model.main.operations)), .inputIndexes = model.main.inputIndexes, .outputIndexes = model.main.outputIndexes, - .operandValues = NN_TRY(convert(model.operandValues)), - .pools = NN_TRY(convert(model.pools)), + .operandValues = NN_TRY(unvalidatedConvert(model.operandValues)), + .pools = NN_TRY(unvalidatedConvert(model.pools)), .relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16, - .extensionNameToPrefix = NN_TRY(convert(model.extensionNameToPrefix)), + .extensionNameToPrefix = NN_TRY(unvalidatedConvert(model.extensionNameToPrefix)), }; } -nn::GeneralResult convert( +nn::GeneralResult unvalidatedConvert( const nn::Model::ExtensionNameAndPrefix& extensionNameAndPrefix) { return Model::ExtensionNameAndPrefix{ .name = extensionNameAndPrefix.name, @@ -457,27 +537,27 @@ nn::GeneralResult convert( }; } -nn::GeneralResult convert(const nn::OutputShape& outputShape) { +nn::GeneralResult unvalidatedConvert(const nn::OutputShape& outputShape) { return OutputShape{.dimensions = outputShape.dimensions, .isSufficient = outputShape.isSufficient}; } -nn::GeneralResult convert(const nn::MeasureTiming& measureTiming) { +nn::GeneralResult unvalidatedConvert(const nn::MeasureTiming& measureTiming) { return static_cast(measureTiming); } -nn::GeneralResult convert(const nn::Timing& timing) { +nn::GeneralResult unvalidatedConvert(const nn::Timing& timing) { return Timing{.timeOnDevice = timing.timeOnDevice, .timeInDriver = timing.timeInDriver}; } -nn::GeneralResult convert(const nn::Extension& extension) { +nn::GeneralResult unvalidatedConvert(const nn::Extension& extension) { return Extension{ .name = extension.name, - .operandTypes = NN_TRY(convert(extension.operandTypes)), + .operandTypes = NN_TRY(unvalidatedConvert(extension.operandTypes)), }; } -nn::GeneralResult convert( +nn::GeneralResult unvalidatedConvert( const nn::Extension::OperandTypeInformation& operandTypeInformation) { return Extension::OperandTypeInformation{ .type = operandTypeInformation.type, @@ -486,20 +566,40 @@ nn::GeneralResult convert( }; } -nn::GeneralResult convert(const nn::SharedHandle& handle) { +nn::GeneralResult unvalidatedConvert(const nn::SharedHandle& handle) { return hal::utils::hidlHandleFromSharedHandle(handle); } +nn::GeneralResult convert(const nn::DeviceType& deviceType) { + return validatedConvert(deviceType); +} + +nn::GeneralResult convert(const nn::Capabilities& capabilities) { + return validatedConvert(capabilities); +} + +nn::GeneralResult convert(const nn::Model& model) { + return validatedConvert(model); +} + +nn::GeneralResult convert(const nn::MeasureTiming& measureTiming) { + return validatedConvert(measureTiming); +} + +nn::GeneralResult convert(const nn::Timing& timing) { + return validatedConvert(timing); +} + nn::GeneralResult> convert(const std::vector& extensions) { - return convertVec(extensions); + return validatedConvert(extensions); } nn::GeneralResult> convert(const std::vector& handles) { - return convertVec(handles); + return validatedConvert(handles); } nn::GeneralResult> convert(const std::vector& outputShapes) { - return convertVec(outputShapes); + return validatedConvert(outputShapes); } } // namespace android::hardware::neuralnetworks::V1_2::utils diff --git a/neuralnetworks/1.2/utils/src/Device.cpp b/neuralnetworks/1.2/utils/src/Device.cpp index a9e537752e..967a252c88 100644 --- a/neuralnetworks/1.2/utils/src/Device.cpp +++ b/neuralnetworks/1.2/utils/src/Device.cpp @@ -51,11 +51,10 @@ nn::GeneralResult initCapabilities(V1_2::IDevice* device) { << "uninitialized"; const auto cb = [&result](V1_0::ErrorStatus status, const Capabilities& capabilities) { if (status != V1_0::ErrorStatus::NONE) { - const auto canonical = - validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); result = NN_ERROR(canonical) << "getCapabilities_1_2 failed with " << toString(status); } else { - result = validatedConvertToCanonical(capabilities); + result = nn::convert(capabilities); } }; @@ -74,8 +73,7 @@ nn::GeneralResult initVersionString(V1_2::IDevice* device) { << "uninitialized"; const auto cb = [&result](V1_0::ErrorStatus status, const hidl_string& versionString) { if (status != V1_0::ErrorStatus::NONE) { - const auto canonical = - validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); result = NN_ERROR(canonical) << "getVersionString failed with " << toString(status); } else { result = versionString; @@ -95,8 +93,7 @@ nn::GeneralResult initDeviceType(V1_2::IDevice* device) { << "uninitialized"; const auto cb = [&result](V1_0::ErrorStatus status, DeviceType deviceType) { if (status != V1_0::ErrorStatus::NONE) { - const auto canonical = - validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); result = NN_ERROR(canonical) << "getDeviceType failed with " << toString(status); } else { result = nn::convert(deviceType); @@ -116,8 +113,7 @@ nn::GeneralResult> initExtensions(V1_2::IDevice* devi NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "uninitialized"; const auto cb = [&result](V1_0::ErrorStatus status, const hidl_vec& extensions) { if (status != V1_0::ErrorStatus::NONE) { - const auto canonical = - validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); result = NN_ERROR(canonical) << "getExtensions failed with " << toString(status); } else { result = nn::convert(extensions); @@ -139,8 +135,7 @@ nn::GeneralResult> initNumberOfCacheFilesNeeded( const auto cb = [&result](V1_0::ErrorStatus status, uint32_t numModelCache, uint32_t numDataCache) { if (status != V1_0::ErrorStatus::NONE) { - const auto canonical = - validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); result = NN_ERROR(canonical) << "getNumberOfCacheFilesNeeded failed with " << toString(status); } else { @@ -238,8 +233,7 @@ nn::GeneralResult> Device::getSupportedOperations(const nn::Mo auto cb = [&result, &model](V1_0::ErrorStatus status, const hidl_vec& supportedOperations) { if (status != V1_0::ErrorStatus::NONE) { - const auto canonical = - validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); result = NN_ERROR(canonical) << "getSupportedOperations_1_2 failed with " << toString(status); } else if (supportedOperations.size() != model.main.operations.size()) { @@ -280,8 +274,7 @@ nn::GeneralResult Device::prepareModel( hidlDataCache, hidlToken, cb); const auto status = NN_TRY(hal::utils::handleTransportError(ret)); if (status != V1_0::ErrorStatus::NONE) { - const auto canonical = - validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); return NN_ERROR(canonical) << "prepareModel_1_2 failed with " << toString(status); } @@ -301,8 +294,7 @@ nn::GeneralResult Device::prepareModelFromCache( const auto ret = kDevice->prepareModelFromCache(hidlModelCache, hidlDataCache, hidlToken, cb); const auto status = NN_TRY(hal::utils::handleTransportError(ret)); if (status != V1_0::ErrorStatus::NONE) { - const auto canonical = - validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); return NN_ERROR(canonical) << "prepareModelFromCache failed with " << toString(status); } diff --git a/neuralnetworks/1.2/utils/src/PreparedModel.cpp b/neuralnetworks/1.2/utils/src/PreparedModel.cpp index ff9db215a2..b5a3389e6c 100644 --- a/neuralnetworks/1.2/utils/src/PreparedModel.cpp +++ b/neuralnetworks/1.2/utils/src/PreparedModel.cpp @@ -42,8 +42,7 @@ namespace { nn::GeneralResult, nn::Timing>> convertExecutionResultsHelper(const hidl_vec& outputShapes, const Timing& timing) { - return std::make_pair(NN_TRY(validatedConvertToCanonical(outputShapes)), - NN_TRY(validatedConvertToCanonical(timing))); + return std::make_pair(NN_TRY(nn::convert(outputShapes)), NN_TRY(nn::convert(timing))); } nn::ExecutionResult, nn::Timing>> convertExecutionResults( @@ -76,8 +75,7 @@ PreparedModel::executeSynchronously(const V1_0::Request& request, MeasureTiming const auto cb = [&result](V1_0::ErrorStatus status, const hidl_vec& outputShapes, const Timing& timing) { if (status != V1_0::ErrorStatus::NONE) { - const auto canonical = - validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); result = NN_ERROR(canonical) << "executeSynchronously failed with " << toString(status); } else { result = convertExecutionResults(outputShapes, timing); @@ -99,8 +97,7 @@ PreparedModel::executeAsynchronously(const V1_0::Request& request, MeasureTiming const auto status = NN_TRY(hal::utils::makeExecutionFailure(hal::utils::handleTransportError(ret))); if (status != V1_0::ErrorStatus::NONE) { - const auto canonical = - validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); return NN_ERROR(canonical) << "execute failed with " << toString(status); } diff --git a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Conversions.h b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Conversions.h index 64aa96e61a..9653a05da7 100644 --- a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Conversions.h +++ b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Conversions.h @@ -25,26 +25,41 @@ namespace android::nn { -GeneralResult convert(const hal::V1_3::OperandType& operandType); -GeneralResult convert(const hal::V1_3::OperationType& operationType); +GeneralResult unvalidatedConvert(const hal::V1_3::OperandType& operandType); +GeneralResult unvalidatedConvert(const hal::V1_3::OperationType& operationType); +GeneralResult unvalidatedConvert(const hal::V1_3::Priority& priority); +GeneralResult unvalidatedConvert(const hal::V1_3::Capabilities& capabilities); +GeneralResult unvalidatedConvert( + const hal::V1_3::Capabilities::OperandPerformance& operandPerformance); +GeneralResult unvalidatedConvert(const hal::V1_3::Operation& operation); +GeneralResult unvalidatedConvert( + const hal::V1_3::OperandLifeTime& operandLifeTime); +GeneralResult unvalidatedConvert(const hal::V1_3::Operand& operand); +GeneralResult unvalidatedConvert(const hal::V1_3::Model& model); +GeneralResult unvalidatedConvert(const hal::V1_3::Subgraph& subgraph); +GeneralResult unvalidatedConvert(const hal::V1_3::BufferDesc& bufferDesc); +GeneralResult unvalidatedConvert(const hal::V1_3::BufferRole& bufferRole); +GeneralResult unvalidatedConvert(const hal::V1_3::Request& request); +GeneralResult unvalidatedConvert( + const hal::V1_3::Request::MemoryPool& memoryPool); +GeneralResult unvalidatedConvert( + const hal::V1_3::OptionalTimePoint& optionalTimePoint); +GeneralResult unvalidatedConvert( + const hal::V1_3::OptionalTimeoutDuration& optionalTimeoutDuration); +GeneralResult unvalidatedConvert(const hal::V1_3::ErrorStatus& errorStatus); + GeneralResult convert(const hal::V1_3::Priority& priority); GeneralResult convert(const hal::V1_3::Capabilities& capabilities); -GeneralResult convert( - const hal::V1_3::Capabilities::OperandPerformance& operandPerformance); -GeneralResult convert(const hal::V1_3::Operation& operation); -GeneralResult convert(const hal::V1_3::OperandLifeTime& operandLifeTime); -GeneralResult convert(const hal::V1_3::Operand& operand); GeneralResult convert(const hal::V1_3::Model& model); -GeneralResult convert(const hal::V1_3::Subgraph& subgraph); GeneralResult convert(const hal::V1_3::BufferDesc& bufferDesc); -GeneralResult convert(const hal::V1_3::BufferRole& bufferRole); GeneralResult convert(const hal::V1_3::Request& request); -GeneralResult convert(const hal::V1_3::Request::MemoryPool& memoryPool); GeneralResult convert(const hal::V1_3::OptionalTimePoint& optionalTimePoint); GeneralResult convert( const hal::V1_3::OptionalTimeoutDuration& optionalTimeoutDuration); GeneralResult convert(const hal::V1_3::ErrorStatus& errorStatus); +GeneralResult convert(const hardware::hidl_handle& handle); +GeneralResult convert(const hardware::hidl_memory& memory); GeneralResult> convert( const hardware::hidl_vec& bufferRoles); @@ -52,26 +67,40 @@ GeneralResult> convert( namespace android::hardware::neuralnetworks::V1_3::utils { -nn::GeneralResult convert(const nn::OperandType& operandType); -nn::GeneralResult convert(const nn::OperationType& operationType); +nn::GeneralResult unvalidatedConvert(const nn::OperandType& operandType); +nn::GeneralResult unvalidatedConvert(const nn::OperationType& operationType); +nn::GeneralResult unvalidatedConvert(const nn::Priority& priority); +nn::GeneralResult unvalidatedConvert(const nn::Capabilities& capabilities); +nn::GeneralResult unvalidatedConvert( + const nn::Capabilities::OperandPerformance& operandPerformance); +nn::GeneralResult unvalidatedConvert(const nn::Operation& operation); +nn::GeneralResult unvalidatedConvert(const nn::Operand::LifeTime& operandLifeTime); +nn::GeneralResult unvalidatedConvert(const nn::Operand& operand); +nn::GeneralResult unvalidatedConvert(const nn::Model& model); +nn::GeneralResult unvalidatedConvert(const nn::Model::Subgraph& subgraph); +nn::GeneralResult unvalidatedConvert(const nn::BufferDesc& bufferDesc); +nn::GeneralResult unvalidatedConvert(const nn::BufferRole& bufferRole); +nn::GeneralResult unvalidatedConvert(const nn::Request& request); +nn::GeneralResult unvalidatedConvert( + const nn::Request::MemoryPool& memoryPool); +nn::GeneralResult unvalidatedConvert( + const nn::OptionalTimePoint& optionalTimePoint); +nn::GeneralResult unvalidatedConvert( + const nn::OptionalTimeoutDuration& optionalTimeoutDuration); +nn::GeneralResult unvalidatedConvert(const nn::ErrorStatus& errorStatus); + nn::GeneralResult convert(const nn::Priority& priority); nn::GeneralResult convert(const nn::Capabilities& capabilities); -nn::GeneralResult convert( - const nn::Capabilities::OperandPerformance& operandPerformance); -nn::GeneralResult convert(const nn::Operation& operation); -nn::GeneralResult convert(const nn::Operand::LifeTime& operandLifeTime); -nn::GeneralResult convert(const nn::Operand& operand); nn::GeneralResult convert(const nn::Model& model); -nn::GeneralResult convert(const nn::Model::Subgraph& subgraph); nn::GeneralResult convert(const nn::BufferDesc& bufferDesc); -nn::GeneralResult convert(const nn::BufferRole& bufferRole); nn::GeneralResult convert(const nn::Request& request); -nn::GeneralResult convert(const nn::Request::MemoryPool& memoryPool); nn::GeneralResult convert(const nn::OptionalTimePoint& optionalTimePoint); nn::GeneralResult convert( const nn::OptionalTimeoutDuration& optionalTimeoutDuration); nn::GeneralResult convert(const nn::ErrorStatus& errorStatus); +nn::GeneralResult convert(const nn::SharedHandle& handle); +nn::GeneralResult convert(const nn::Memory& memory); nn::GeneralResult> convert(const std::vector& bufferRoles); } // namespace android::hardware::neuralnetworks::V1_3::utils diff --git a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Utils.h b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Utils.h index e61859d5f9..29b0c806ff 100644 --- a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Utils.h +++ b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Utils.h @@ -22,9 +22,7 @@ #include #include #include -#include #include -#include #include #include #include @@ -32,7 +30,6 @@ namespace android::hardware::neuralnetworks::V1_3::utils { constexpr auto kDefaultPriority = Priority::MEDIUM; -constexpr auto kVersion = nn::Version::ANDROID_R; template nn::Result validate(const Type& halObject) { @@ -40,11 +37,6 @@ nn::Result validate(const Type& halObject) { if (!maybeCanonical.has_value()) { return nn::error() << maybeCanonical.error().message; } - const auto version = NN_TRY(nn::validate(maybeCanonical.value())); - if (version > utils::kVersion) { - return NN_ERROR() << "Insufficient version: " << version << " vs required " - << utils::kVersion; - } return {}; } @@ -57,21 +49,6 @@ bool valid(const Type& halObject) { return result.has_value(); } -template -decltype(nn::convert(std::declval())) validatedConvertToCanonical(const Type& halObject) { - auto canonical = NN_TRY(nn::convert(halObject)); - const auto maybeVersion = nn::validate(canonical); - if (!maybeVersion.has_value()) { - return nn::error() << maybeVersion.error(); - } - const auto version = maybeVersion.value(); - if (version > utils::kVersion) { - return NN_ERROR() << "Insufficient version: " << version << " vs required " - << utils::kVersion; - } - return canonical; -} - } // namespace android::hardware::neuralnetworks::V1_3::utils #endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_3_UTILS_H diff --git a/neuralnetworks/1.3/utils/src/Buffer.cpp b/neuralnetworks/1.3/utils/src/Buffer.cpp index f3fe9b5112..a880031ad7 100644 --- a/neuralnetworks/1.3/utils/src/Buffer.cpp +++ b/neuralnetworks/1.3/utils/src/Buffer.cpp @@ -61,13 +61,12 @@ nn::Request::MemoryDomainToken Buffer::getToken() const { } nn::GeneralResult Buffer::copyTo(const nn::Memory& dst) const { - const auto hidlDst = NN_TRY(V1_0::utils::convert(dst)); + const auto hidlDst = NN_TRY(convert(dst)); const auto ret = kBuffer->copyTo(hidlDst); const auto status = NN_TRY(hal::utils::handleTransportError(ret)); if (status != ErrorStatus::NONE) { - const auto canonical = - validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); return NN_ERROR(canonical) << "IBuffer::copyTo failed with " << toString(status); } @@ -76,14 +75,13 @@ nn::GeneralResult Buffer::copyTo(const nn::Memory& dst) const { nn::GeneralResult Buffer::copyFrom(const nn::Memory& src, const nn::Dimensions& dimensions) const { - const auto hidlSrc = NN_TRY(V1_0::utils::convert(src)); + const auto hidlSrc = NN_TRY(convert(src)); const auto hidlDimensions = hidl_vec(dimensions); const auto ret = kBuffer->copyFrom(hidlSrc, hidlDimensions); const auto status = NN_TRY(hal::utils::handleTransportError(ret)); if (status != ErrorStatus::NONE) { - const auto canonical = - validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); return NN_ERROR(canonical) << "IBuffer::copyFrom failed with " << toString(status); } diff --git a/neuralnetworks/1.3/utils/src/Callbacks.cpp b/neuralnetworks/1.3/utils/src/Callbacks.cpp index ff81275335..e3c6074549 100644 --- a/neuralnetworks/1.3/utils/src/Callbacks.cpp +++ b/neuralnetworks/1.3/utils/src/Callbacks.cpp @@ -60,8 +60,7 @@ nn::GeneralResult convertPreparedModel( nn::GeneralResult, nn::Timing>> convertExecutionGeneralResultsHelper(const hidl_vec& outputShapes, const V1_2::Timing& timing) { - return std::make_pair(NN_TRY(validatedConvertToCanonical(outputShapes)), - NN_TRY(validatedConvertToCanonical(timing))); + return std::make_pair(NN_TRY(nn::convert(outputShapes)), NN_TRY(nn::convert(timing))); } nn::ExecutionResult, nn::Timing>> @@ -76,8 +75,7 @@ convertExecutionGeneralResults(const hidl_vec& outputShapes, Return PreparedModelCallback::notify(V1_0::ErrorStatus status, const sp& preparedModel) { if (status != V1_0::ErrorStatus::NONE) { - const auto canonical = - validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); notifyInternal(NN_ERROR(canonical) << "preparedModel failed with " << toString(status)); } else if (preparedModel == nullptr) { notifyInternal(NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) @@ -91,8 +89,7 @@ Return PreparedModelCallback::notify(V1_0::ErrorStatus status, Return PreparedModelCallback::notify_1_2(V1_0::ErrorStatus status, const sp& preparedModel) { if (status != V1_0::ErrorStatus::NONE) { - const auto canonical = - validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); notifyInternal(NN_ERROR(canonical) << "preparedModel failed with " << toString(status)); } else if (preparedModel == nullptr) { notifyInternal(NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) @@ -106,8 +103,7 @@ Return PreparedModelCallback::notify_1_2(V1_0::ErrorStatus status, Return PreparedModelCallback::notify_1_3(ErrorStatus status, const sp& preparedModel) { if (status != ErrorStatus::NONE) { - const auto canonical = - validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); notifyInternal(NN_ERROR(canonical) << "preparedModel failed with " << toString(status)); } else if (preparedModel == nullptr) { notifyInternal(NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) @@ -134,8 +130,7 @@ void PreparedModelCallback::notifyInternal(PreparedModelCallback::Data result) { Return ExecutionCallback::notify(V1_0::ErrorStatus status) { if (status != V1_0::ErrorStatus::NONE) { - const auto canonical = - validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); notifyInternal(NN_ERROR(canonical) << "execute failed with " << toString(status)); } else { notifyInternal({}); @@ -147,8 +142,7 @@ Return ExecutionCallback::notify_1_2(V1_0::ErrorStatus status, const hidl_vec& outputShapes, const V1_2::Timing& timing) { if (status != V1_0::ErrorStatus::NONE) { - const auto canonical = - validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); notifyInternal(NN_ERROR(canonical) << "execute failed with " << toString(status)); } else { notifyInternal(convertExecutionGeneralResults(outputShapes, timing)); @@ -160,8 +154,7 @@ Return ExecutionCallback::notify_1_3(ErrorStatus status, const hidl_vec& outputShapes, const V1_2::Timing& timing) { if (status != ErrorStatus::NONE) { - const auto canonical = - validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); notifyInternal(NN_ERROR(canonical) << "execute failed with " << toString(status)); } else { notifyInternal(convertExecutionGeneralResults(outputShapes, timing)); diff --git a/neuralnetworks/1.3/utils/src/Conversions.cpp b/neuralnetworks/1.3/utils/src/Conversions.cpp index 0dc078534c..949dd0d1ed 100644 --- a/neuralnetworks/1.3/utils/src/Conversions.cpp +++ b/neuralnetworks/1.3/utils/src/Conversions.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -44,6 +45,8 @@ constexpr std::underlying_type_t underlyingType(Type value) { return static_cast>(value); } +constexpr auto kVersion = android::nn::Version::ANDROID_R; + } // namespace namespace android::nn { @@ -77,110 +80,140 @@ constexpr auto validOperandType(nn::OperandType operandType) { using hardware::hidl_vec; template -using ConvertOutput = std::decay_t()).value())>; +using unvalidatedConvertOutput = + std::decay_t()).value())>; template -GeneralResult>> convertVec(const hidl_vec& arguments) { - std::vector> canonical; +GeneralResult>> unvalidatedConvertVec( + const hidl_vec& arguments) { + std::vector> canonical; canonical.reserve(arguments.size()); for (const auto& argument : arguments) { - canonical.push_back(NN_TRY(nn::convert(argument))); + canonical.push_back(NN_TRY(nn::unvalidatedConvert(argument))); } return canonical; } template -GeneralResult>> convert(const hidl_vec& arguments) { - return convertVec(arguments); +GeneralResult>> unvalidatedConvert( + const hidl_vec& arguments) { + return unvalidatedConvertVec(arguments); +} + +template +decltype(nn::unvalidatedConvert(std::declval())) validatedConvert(const Type& halObject) { + auto canonical = NN_TRY(nn::unvalidatedConvert(halObject)); + const auto maybeVersion = validate(canonical); + if (!maybeVersion.has_value()) { + return error() << maybeVersion.error(); + } + const auto version = maybeVersion.value(); + if (version > kVersion) { + return NN_ERROR() << "Insufficient version: " << version << " vs required " << kVersion; + } + return canonical; +} + +template +GeneralResult>> validatedConvert( + const hidl_vec& arguments) { + std::vector> canonical; + canonical.reserve(arguments.size()); + for (const auto& argument : arguments) { + canonical.push_back(NN_TRY(validatedConvert(argument))); + } + return canonical; } } // anonymous namespace -GeneralResult convert(const hal::V1_3::OperandType& operandType) { +GeneralResult unvalidatedConvert(const hal::V1_3::OperandType& operandType) { return static_cast(operandType); } -GeneralResult convert(const hal::V1_3::OperationType& operationType) { +GeneralResult unvalidatedConvert(const hal::V1_3::OperationType& operationType) { return static_cast(operationType); } -GeneralResult convert(const hal::V1_3::Priority& priority) { +GeneralResult unvalidatedConvert(const hal::V1_3::Priority& priority) { return static_cast(priority); } -GeneralResult convert(const hal::V1_3::Capabilities& capabilities) { +GeneralResult unvalidatedConvert(const hal::V1_3::Capabilities& capabilities) { const bool validOperandTypes = std::all_of( capabilities.operandPerformance.begin(), capabilities.operandPerformance.end(), [](const hal::V1_3::Capabilities::OperandPerformance& operandPerformance) { - const auto maybeType = convert(operandPerformance.type); + const auto maybeType = unvalidatedConvert(operandPerformance.type); return !maybeType.has_value() ? false : validOperandType(maybeType.value()); }); if (!validOperandTypes) { return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) - << "Invalid OperandType when converting OperandPerformance in Capabilities"; + << "Invalid OperandType when unvalidatedConverting OperandPerformance in " + "Capabilities"; } - auto operandPerformance = NN_TRY(convert(capabilities.operandPerformance)); + auto operandPerformance = NN_TRY(unvalidatedConvert(capabilities.operandPerformance)); auto table = NN_TRY(hal::utils::makeGeneralFailure( Capabilities::OperandPerformanceTable::create(std::move(operandPerformance)), nn::ErrorStatus::GENERAL_FAILURE)); return Capabilities{ - .relaxedFloat32toFloat16PerformanceScalar = - NN_TRY(convert(capabilities.relaxedFloat32toFloat16PerformanceScalar)), - .relaxedFloat32toFloat16PerformanceTensor = - NN_TRY(convert(capabilities.relaxedFloat32toFloat16PerformanceTensor)), + .relaxedFloat32toFloat16PerformanceScalar = NN_TRY( + unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceScalar)), + .relaxedFloat32toFloat16PerformanceTensor = NN_TRY( + unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceTensor)), .operandPerformance = std::move(table), - .ifPerformance = NN_TRY(convert(capabilities.ifPerformance)), - .whilePerformance = NN_TRY(convert(capabilities.whilePerformance)), + .ifPerformance = NN_TRY(unvalidatedConvert(capabilities.ifPerformance)), + .whilePerformance = NN_TRY(unvalidatedConvert(capabilities.whilePerformance)), }; } -GeneralResult convert( +GeneralResult unvalidatedConvert( const hal::V1_3::Capabilities::OperandPerformance& operandPerformance) { return Capabilities::OperandPerformance{ - .type = NN_TRY(convert(operandPerformance.type)), - .info = NN_TRY(convert(operandPerformance.info)), + .type = NN_TRY(unvalidatedConvert(operandPerformance.type)), + .info = NN_TRY(unvalidatedConvert(operandPerformance.info)), }; } -GeneralResult convert(const hal::V1_3::Operation& operation) { +GeneralResult unvalidatedConvert(const hal::V1_3::Operation& operation) { return Operation{ - .type = NN_TRY(convert(operation.type)), + .type = NN_TRY(unvalidatedConvert(operation.type)), .inputs = operation.inputs, .outputs = operation.outputs, }; } -GeneralResult convert(const hal::V1_3::OperandLifeTime& operandLifeTime) { +GeneralResult unvalidatedConvert( + const hal::V1_3::OperandLifeTime& operandLifeTime) { return static_cast(operandLifeTime); } -GeneralResult convert(const hal::V1_3::Operand& operand) { +GeneralResult unvalidatedConvert(const hal::V1_3::Operand& operand) { return Operand{ - .type = NN_TRY(convert(operand.type)), + .type = NN_TRY(unvalidatedConvert(operand.type)), .dimensions = operand.dimensions, .scale = operand.scale, .zeroPoint = operand.zeroPoint, - .lifetime = NN_TRY(convert(operand.lifetime)), - .location = NN_TRY(convert(operand.location)), - .extraParams = NN_TRY(convert(operand.extraParams)), + .lifetime = NN_TRY(unvalidatedConvert(operand.lifetime)), + .location = NN_TRY(unvalidatedConvert(operand.location)), + .extraParams = NN_TRY(unvalidatedConvert(operand.extraParams)), }; } -GeneralResult convert(const hal::V1_3::Model& model) { +GeneralResult unvalidatedConvert(const hal::V1_3::Model& model) { return Model{ - .main = NN_TRY(convert(model.main)), - .referenced = NN_TRY(convert(model.referenced)), - .operandValues = NN_TRY(convert(model.operandValues)), - .pools = NN_TRY(convert(model.pools)), + .main = NN_TRY(unvalidatedConvert(model.main)), + .referenced = NN_TRY(unvalidatedConvert(model.referenced)), + .operandValues = NN_TRY(unvalidatedConvert(model.operandValues)), + .pools = NN_TRY(unvalidatedConvert(model.pools)), .relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16, - .extensionNameToPrefix = NN_TRY(convert(model.extensionNameToPrefix)), + .extensionNameToPrefix = NN_TRY(unvalidatedConvert(model.extensionNameToPrefix)), }; } -GeneralResult convert(const hal::V1_3::Subgraph& subgraph) { - auto operations = NN_TRY(convert(subgraph.operations)); +GeneralResult unvalidatedConvert(const hal::V1_3::Subgraph& subgraph) { + auto operations = NN_TRY(unvalidatedConvert(subgraph.operations)); // Verify number of consumers. const auto numberOfConsumers = @@ -196,18 +229,18 @@ GeneralResult convert(const hal::V1_3::Subgraph& subgraph) { } return Model::Subgraph{ - .operands = NN_TRY(convert(subgraph.operands)), + .operands = NN_TRY(unvalidatedConvert(subgraph.operands)), .operations = std::move(operations), .inputIndexes = subgraph.inputIndexes, .outputIndexes = subgraph.outputIndexes, }; } -GeneralResult convert(const hal::V1_3::BufferDesc& bufferDesc) { +GeneralResult unvalidatedConvert(const hal::V1_3::BufferDesc& bufferDesc) { return BufferDesc{.dimensions = bufferDesc.dimensions}; } -GeneralResult convert(const hal::V1_3::BufferRole& bufferRole) { +GeneralResult unvalidatedConvert(const hal::V1_3::BufferRole& bufferRole) { return BufferRole{ .modelIndex = bufferRole.modelIndex, .ioIndex = bufferRole.ioIndex, @@ -215,15 +248,16 @@ GeneralResult convert(const hal::V1_3::BufferRole& bufferRole) { }; } -GeneralResult convert(const hal::V1_3::Request& request) { +GeneralResult unvalidatedConvert(const hal::V1_3::Request& request) { return Request{ - .inputs = NN_TRY(convert(request.inputs)), - .outputs = NN_TRY(convert(request.outputs)), - .pools = NN_TRY(convert(request.pools)), + .inputs = NN_TRY(unvalidatedConvert(request.inputs)), + .outputs = NN_TRY(unvalidatedConvert(request.outputs)), + .pools = NN_TRY(unvalidatedConvert(request.pools)), }; } -GeneralResult convert(const hal::V1_3::Request::MemoryPool& memoryPool) { +GeneralResult unvalidatedConvert( + const hal::V1_3::Request::MemoryPool& memoryPool) { using Discriminator = hal::V1_3::Request::MemoryPool::hidl_discriminator; switch (memoryPool.getDiscriminator()) { case Discriminator::hidlMemory: @@ -236,12 +270,14 @@ GeneralResult convert(const hal::V1_3::Request::MemoryPool& << underlyingType(memoryPool.getDiscriminator()); } -GeneralResult convert(const hal::V1_3::OptionalTimePoint& optionalTimePoint) { +GeneralResult unvalidatedConvert( + const hal::V1_3::OptionalTimePoint& optionalTimePoint) { constexpr auto kTimePointMaxCount = TimePoint::max().time_since_epoch().count(); const auto makeTimePoint = [](uint64_t count) -> GeneralResult { if (count > kTimePointMaxCount) { return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) - << "Unable to convert OptionalTimePoint because the count exceeds the max"; + << "Unable to unvalidatedConvert OptionalTimePoint because the count exceeds " + "the max"; } const auto nanoseconds = std::chrono::nanoseconds{count}; return TimePoint{nanoseconds}; @@ -259,13 +295,14 @@ GeneralResult convert(const hal::V1_3::OptionalTimePoint& opt << underlyingType(optionalTimePoint.getDiscriminator()); } -GeneralResult convert( +GeneralResult unvalidatedConvert( const hal::V1_3::OptionalTimeoutDuration& optionalTimeoutDuration) { constexpr auto kTimeoutDurationMaxCount = TimeoutDuration::max().count(); const auto makeTimeoutDuration = [](uint64_t count) -> GeneralResult { if (count > kTimeoutDurationMaxCount) { return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) - << "Unable to convert OptionalTimeoutDuration because the count exceeds the max"; + << "Unable to unvalidatedConvert OptionalTimeoutDuration because the count " + "exceeds the max"; } return TimeoutDuration{count}; }; @@ -282,7 +319,7 @@ GeneralResult convert( << underlyingType(optionalTimeoutDuration.getDiscriminator()); } -GeneralResult convert(const hal::V1_3::ErrorStatus& status) { +GeneralResult unvalidatedConvert(const hal::V1_3::ErrorStatus& status) { switch (status) { case hal::V1_3::ErrorStatus::NONE: case hal::V1_3::ErrorStatus::DEVICE_UNAVAILABLE: @@ -299,9 +336,50 @@ GeneralResult convert(const hal::V1_3::ErrorStatus& status) { << "Invalid ErrorStatus " << underlyingType(status); } +GeneralResult convert(const hal::V1_3::Priority& priority) { + return validatedConvert(priority); +} + +GeneralResult convert(const hal::V1_3::Capabilities& capabilities) { + return validatedConvert(capabilities); +} + +GeneralResult convert(const hal::V1_3::Model& model) { + return validatedConvert(model); +} + +GeneralResult convert(const hal::V1_3::BufferDesc& bufferDesc) { + return validatedConvert(bufferDesc); +} + +GeneralResult convert(const hal::V1_3::Request& request) { + return validatedConvert(request); +} + +GeneralResult convert(const hal::V1_3::OptionalTimePoint& optionalTimePoint) { + return validatedConvert(optionalTimePoint); +} + +GeneralResult convert( + const hal::V1_3::OptionalTimeoutDuration& optionalTimeoutDuration) { + return validatedConvert(optionalTimeoutDuration); +} + +GeneralResult convert(const hal::V1_3::ErrorStatus& errorStatus) { + return validatedConvert(errorStatus); +} + +GeneralResult convert(const hardware::hidl_handle& handle) { + return validatedConvert(handle); +} + +GeneralResult convert(const hardware::hidl_memory& memory) { + return validatedConvert(memory); +} + GeneralResult> convert( const hardware::hidl_vec& bufferRoles) { - return convertVec(bufferRoles); + return validatedConvert(bufferRoles); } } // namespace android::nn @@ -309,58 +387,67 @@ GeneralResult> convert( namespace android::hardware::neuralnetworks::V1_3::utils { namespace { -using utils::convert; +using utils::unvalidatedConvert; -nn::GeneralResult convert( +nn::GeneralResult unvalidatedConvert( const nn::Capabilities::PerformanceInfo& performanceInfo) { - return V1_0::utils::convert(performanceInfo); + return V1_0::utils::unvalidatedConvert(performanceInfo); } -nn::GeneralResult convert(const nn::DataLocation& dataLocation) { - return V1_0::utils::convert(dataLocation); +nn::GeneralResult unvalidatedConvert(const nn::DataLocation& dataLocation) { + return V1_0::utils::unvalidatedConvert(dataLocation); } -nn::GeneralResult> convert(const nn::Model::OperandValues& operandValues) { - return V1_0::utils::convert(operandValues); +nn::GeneralResult> unvalidatedConvert( + const nn::Model::OperandValues& operandValues) { + return V1_0::utils::unvalidatedConvert(operandValues); } -nn::GeneralResult convert(const nn::Memory& memory) { - return V1_0::utils::convert(memory); +nn::GeneralResult unvalidatedConvert(const nn::SharedHandle& handle) { + return V1_2::utils::unvalidatedConvert(handle); +} + +nn::GeneralResult unvalidatedConvert(const nn::Memory& memory) { + return V1_0::utils::unvalidatedConvert(memory); } -nn::GeneralResult convert(const nn::Request::Argument& argument) { - return V1_0::utils::convert(argument); +nn::GeneralResult unvalidatedConvert(const nn::Request::Argument& argument) { + return V1_0::utils::unvalidatedConvert(argument); } -nn::GeneralResult convert(const nn::Operand::ExtraParams& extraParams) { - return V1_2::utils::convert(extraParams); +nn::GeneralResult unvalidatedConvert( + const nn::Operand::ExtraParams& extraParams) { + return V1_2::utils::unvalidatedConvert(extraParams); } -nn::GeneralResult convert( +nn::GeneralResult unvalidatedConvert( const nn::Model::ExtensionNameAndPrefix& extensionNameAndPrefix) { - return V1_2::utils::convert(extensionNameAndPrefix); + return V1_2::utils::unvalidatedConvert(extensionNameAndPrefix); } template -using ConvertOutput = std::decay_t()).value())>; +using unvalidatedConvertOutput = + std::decay_t()).value())>; template -nn::GeneralResult>> convertVec(const std::vector& arguments) { - hidl_vec> halObject(arguments.size()); +nn::GeneralResult>> unvalidatedConvertVec( + const std::vector& arguments) { + hidl_vec> halObject(arguments.size()); for (size_t i = 0; i < arguments.size(); ++i) { - halObject[i] = NN_TRY(convert(arguments[i])); + halObject[i] = NN_TRY(unvalidatedConvert(arguments[i])); } return halObject; } template -nn::GeneralResult>> convert(const std::vector& arguments) { - return convertVec(arguments); +nn::GeneralResult>> unvalidatedConvert( + const std::vector& arguments) { + return unvalidatedConvertVec(arguments); } nn::GeneralResult makeMemoryPool(const nn::Memory& memory) { Request::MemoryPool ret; - ret.hidlMemory(NN_TRY(convert(memory))); + ret.hidlMemory(NN_TRY(unvalidatedConvert(memory))); return ret; } @@ -374,21 +461,46 @@ nn::GeneralResult makeMemoryPool(const nn::SharedBuffer& /* return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "Unable to make memory pool from IBuffer"; } +using utils::unvalidatedConvert; + +template +decltype(unvalidatedConvert(std::declval())) validatedConvert(const Type& canonical) { + const auto maybeVersion = nn::validate(canonical); + if (!maybeVersion.has_value()) { + return nn::error() << maybeVersion.error(); + } + const auto version = maybeVersion.value(); + if (version > kVersion) { + return NN_ERROR() << "Insufficient version: " << version << " vs required " << kVersion; + } + return unvalidatedConvert(canonical); +} + +template +nn::GeneralResult>> validatedConvert( + const std::vector& arguments) { + hidl_vec> halObject(arguments.size()); + for (size_t i = 0; i < arguments.size(); ++i) { + halObject[i] = NN_TRY(validatedConvert(arguments[i])); + } + return halObject; +} + } // anonymous namespace -nn::GeneralResult convert(const nn::OperandType& operandType) { +nn::GeneralResult unvalidatedConvert(const nn::OperandType& operandType) { return static_cast(operandType); } -nn::GeneralResult convert(const nn::OperationType& operationType) { +nn::GeneralResult unvalidatedConvert(const nn::OperationType& operationType) { return static_cast(operationType); } -nn::GeneralResult convert(const nn::Priority& priority) { +nn::GeneralResult unvalidatedConvert(const nn::Priority& priority) { return static_cast(priority); } -nn::GeneralResult convert(const nn::Capabilities& capabilities) { +nn::GeneralResult unvalidatedConvert(const nn::Capabilities& capabilities) { std::vector operandPerformance; operandPerformance.reserve(capabilities.operandPerformance.asVector().size()); std::copy_if(capabilities.operandPerformance.asVector().begin(), @@ -399,71 +511,72 @@ nn::GeneralResult convert(const nn::Capabilities& capabilities) { }); return Capabilities{ - .relaxedFloat32toFloat16PerformanceScalar = - NN_TRY(convert(capabilities.relaxedFloat32toFloat16PerformanceScalar)), - .relaxedFloat32toFloat16PerformanceTensor = - NN_TRY(convert(capabilities.relaxedFloat32toFloat16PerformanceTensor)), - .operandPerformance = NN_TRY(convert(operandPerformance)), - .ifPerformance = NN_TRY(convert(capabilities.ifPerformance)), - .whilePerformance = NN_TRY(convert(capabilities.whilePerformance)), + .relaxedFloat32toFloat16PerformanceScalar = NN_TRY( + unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceScalar)), + .relaxedFloat32toFloat16PerformanceTensor = NN_TRY( + unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceTensor)), + .operandPerformance = NN_TRY(unvalidatedConvert(operandPerformance)), + .ifPerformance = NN_TRY(unvalidatedConvert(capabilities.ifPerformance)), + .whilePerformance = NN_TRY(unvalidatedConvert(capabilities.whilePerformance)), }; } -nn::GeneralResult convert( +nn::GeneralResult unvalidatedConvert( const nn::Capabilities::OperandPerformance& operandPerformance) { return Capabilities::OperandPerformance{ - .type = NN_TRY(convert(operandPerformance.type)), - .info = NN_TRY(convert(operandPerformance.info)), + .type = NN_TRY(unvalidatedConvert(operandPerformance.type)), + .info = NN_TRY(unvalidatedConvert(operandPerformance.info)), }; } -nn::GeneralResult convert(const nn::Operation& operation) { +nn::GeneralResult unvalidatedConvert(const nn::Operation& operation) { return Operation{ - .type = NN_TRY(convert(operation.type)), + .type = NN_TRY(unvalidatedConvert(operation.type)), .inputs = operation.inputs, .outputs = operation.outputs, }; } -nn::GeneralResult convert(const nn::Operand::LifeTime& operandLifeTime) { +nn::GeneralResult unvalidatedConvert( + const nn::Operand::LifeTime& operandLifeTime) { if (operandLifeTime == nn::Operand::LifeTime::POINTER) { return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) - << "Model cannot be converted because it contains pointer-based memory"; + << "Model cannot be unvalidatedConverted because it contains pointer-based memory"; } return static_cast(operandLifeTime); } -nn::GeneralResult convert(const nn::Operand& operand) { +nn::GeneralResult unvalidatedConvert(const nn::Operand& operand) { return Operand{ - .type = NN_TRY(convert(operand.type)), + .type = NN_TRY(unvalidatedConvert(operand.type)), .dimensions = operand.dimensions, .numberOfConsumers = 0, .scale = operand.scale, .zeroPoint = operand.zeroPoint, - .lifetime = NN_TRY(convert(operand.lifetime)), - .location = NN_TRY(convert(operand.location)), - .extraParams = NN_TRY(convert(operand.extraParams)), + .lifetime = NN_TRY(unvalidatedConvert(operand.lifetime)), + .location = NN_TRY(unvalidatedConvert(operand.location)), + .extraParams = NN_TRY(unvalidatedConvert(operand.extraParams)), }; } -nn::GeneralResult convert(const nn::Model& model) { +nn::GeneralResult unvalidatedConvert(const nn::Model& model) { if (!hal::utils::hasNoPointerData(model)) { return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) - << "Model cannot be converted because it contains pointer-based memory"; + << "Model cannot be unvalidatedConverted because it contains pointer-based memory"; } return Model{ - .main = NN_TRY(convert(model.main)), - .referenced = NN_TRY(convert(model.referenced)), - .operandValues = NN_TRY(convert(model.operandValues)), - .pools = NN_TRY(convert(model.pools)), + .main = NN_TRY(unvalidatedConvert(model.main)), + .referenced = NN_TRY(unvalidatedConvert(model.referenced)), + .operandValues = NN_TRY(unvalidatedConvert(model.operandValues)), + .pools = NN_TRY(unvalidatedConvert(model.pools)), .relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16, - .extensionNameToPrefix = NN_TRY(convert(model.extensionNameToPrefix)), + .extensionNameToPrefix = NN_TRY(unvalidatedConvert(model.extensionNameToPrefix)), }; } -nn::GeneralResult convert(const nn::Model::Subgraph& subgraph) { - auto operands = NN_TRY(convert(subgraph.operands)); +nn::GeneralResult unvalidatedConvert(const nn::Model::Subgraph& subgraph) { + auto operands = NN_TRY(unvalidatedConvert(subgraph.operands)); // Update number of consumers. const auto numberOfConsumers = @@ -475,17 +588,17 @@ nn::GeneralResult convert(const nn::Model::Subgraph& subgraph) { return Subgraph{ .operands = std::move(operands), - .operations = NN_TRY(convert(subgraph.operations)), + .operations = NN_TRY(unvalidatedConvert(subgraph.operations)), .inputIndexes = subgraph.inputIndexes, .outputIndexes = subgraph.outputIndexes, }; } -nn::GeneralResult convert(const nn::BufferDesc& bufferDesc) { +nn::GeneralResult unvalidatedConvert(const nn::BufferDesc& bufferDesc) { return BufferDesc{.dimensions = bufferDesc.dimensions}; } -nn::GeneralResult convert(const nn::BufferRole& bufferRole) { +nn::GeneralResult unvalidatedConvert(const nn::BufferRole& bufferRole) { return BufferRole{ .modelIndex = bufferRole.modelIndex, .ioIndex = bufferRole.ioIndex, @@ -493,30 +606,33 @@ nn::GeneralResult convert(const nn::BufferRole& bufferRole) { }; } -nn::GeneralResult convert(const nn::Request& request) { +nn::GeneralResult unvalidatedConvert(const nn::Request& request) { if (!hal::utils::hasNoPointerData(request)) { return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) - << "Request cannot be converted because it contains pointer-based memory"; + << "Request cannot be unvalidatedConverted because it contains pointer-based memory"; } return Request{ - .inputs = NN_TRY(convert(request.inputs)), - .outputs = NN_TRY(convert(request.outputs)), - .pools = NN_TRY(convert(request.pools)), + .inputs = NN_TRY(unvalidatedConvert(request.inputs)), + .outputs = NN_TRY(unvalidatedConvert(request.outputs)), + .pools = NN_TRY(unvalidatedConvert(request.pools)), }; } -nn::GeneralResult convert(const nn::Request::MemoryPool& memoryPool) { +nn::GeneralResult unvalidatedConvert( + const nn::Request::MemoryPool& memoryPool) { return std::visit([](const auto& o) { return makeMemoryPool(o); }, memoryPool); } -nn::GeneralResult convert(const nn::OptionalTimePoint& optionalTimePoint) { +nn::GeneralResult unvalidatedConvert( + const nn::OptionalTimePoint& optionalTimePoint) { OptionalTimePoint ret; if (optionalTimePoint.has_value()) { const auto count = optionalTimePoint.value().time_since_epoch().count(); if (count < 0) { return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) - << "Unable to convert OptionalTimePoint because time since epoch count is " + << "Unable to unvalidatedConvert OptionalTimePoint because time since epoch " + "count is " "negative"; } ret.nanosecondsSinceEpoch(count); @@ -524,21 +640,22 @@ nn::GeneralResult convert(const nn::OptionalTimePoint& option return ret; } -nn::GeneralResult convert( +nn::GeneralResult unvalidatedConvert( const nn::OptionalTimeoutDuration& optionalTimeoutDuration) { OptionalTimeoutDuration ret; if (optionalTimeoutDuration.has_value()) { const auto count = optionalTimeoutDuration.value().count(); if (count < 0) { return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) - << "Unable to convert OptionalTimeoutDuration because count is negative"; + << "Unable to unvalidatedConvert OptionalTimeoutDuration because count is " + "negative"; } ret.nanoseconds(count); } return ret; } -nn::GeneralResult convert(const nn::ErrorStatus& errorStatus) { +nn::GeneralResult unvalidatedConvert(const nn::ErrorStatus& errorStatus) { switch (errorStatus) { case nn::ErrorStatus::NONE: case nn::ErrorStatus::DEVICE_UNAVAILABLE: @@ -555,8 +672,49 @@ nn::GeneralResult convert(const nn::ErrorStatus& errorStatus) { } } +nn::GeneralResult convert(const nn::Priority& priority) { + return validatedConvert(priority); +} + +nn::GeneralResult convert(const nn::Capabilities& capabilities) { + return validatedConvert(capabilities); +} + +nn::GeneralResult convert(const nn::Model& model) { + return validatedConvert(model); +} + +nn::GeneralResult convert(const nn::BufferDesc& bufferDesc) { + return validatedConvert(bufferDesc); +} + +nn::GeneralResult convert(const nn::Request& request) { + return validatedConvert(request); +} + +nn::GeneralResult convert(const nn::OptionalTimePoint& optionalTimePoint) { + return validatedConvert(optionalTimePoint); +} + +nn::GeneralResult convert( + const nn::OptionalTimeoutDuration& optionalTimeoutDuration) { + return validatedConvert(optionalTimeoutDuration); +} + +nn::GeneralResult convert(const nn::ErrorStatus& errorStatus) { + return validatedConvert(errorStatus); +} + +nn::GeneralResult convert(const nn::SharedHandle& handle) { + return validatedConvert(handle); +} + +nn::GeneralResult convert(const nn::Memory& memory) { + return validatedConvert(memory); +} + nn::GeneralResult> convert(const std::vector& bufferRoles) { - return convertVec(bufferRoles); + return validatedConvert(bufferRoles); } } // namespace android::hardware::neuralnetworks::V1_3::utils diff --git a/neuralnetworks/1.3/utils/src/Device.cpp b/neuralnetworks/1.3/utils/src/Device.cpp index 0fa244d891..7a7e2514ef 100644 --- a/neuralnetworks/1.3/utils/src/Device.cpp +++ b/neuralnetworks/1.3/utils/src/Device.cpp @@ -78,11 +78,10 @@ nn::GeneralResult initCapabilities(V1_3::IDevice* device) { << "uninitialized"; const auto cb = [&result](ErrorStatus status, const Capabilities& capabilities) { if (status != ErrorStatus::NONE) { - const auto canonical = - validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); result = NN_ERROR(canonical) << "getCapabilities_1_3 failed with " << toString(status); } else { - result = validatedConvertToCanonical(capabilities); + result = nn::convert(capabilities); } }; @@ -178,8 +177,7 @@ nn::GeneralResult> Device::getSupportedOperations(const nn::Mo << "uninitialized"; auto cb = [&result, &model](ErrorStatus status, const hidl_vec& supportedOperations) { if (status != ErrorStatus::NONE) { - const auto canonical = - validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); result = NN_ERROR(canonical) << "IDevice::getSupportedOperations_1_3 failed with " << toString(status); } else if (supportedOperations.size() != model.main.operations.size()) { @@ -223,8 +221,7 @@ nn::GeneralResult Device::prepareModel( hidlModelCache, hidlDataCache, hidlToken, cb); const auto status = NN_TRY(hal::utils::handleTransportError(ret)); if (status != ErrorStatus::NONE) { - const auto canonical = - validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); return NN_ERROR(canonical) << "prepareModel_1_3 failed with " << toString(status); } @@ -246,8 +243,7 @@ nn::GeneralResult Device::prepareModelFromCache( hidlToken, cb); const auto status = NN_TRY(hal::utils::handleTransportError(ret)); if (status != ErrorStatus::NONE) { - const auto canonical = - validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); return NN_ERROR(canonical) << "prepareModelFromCache_1_3 failed with " << toString(status); } @@ -267,8 +263,7 @@ nn::GeneralResult Device::allocate( << "uninitialized"; auto cb = [&result](ErrorStatus status, const sp& buffer, uint32_t token) { if (status != ErrorStatus::NONE) { - const auto canonical = - validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); result = NN_ERROR(canonical) << "IDevice::allocate failed with " << toString(status); } else if (buffer == nullptr) { result = NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "Returned buffer is nullptr"; diff --git a/neuralnetworks/1.3/utils/src/PreparedModel.cpp b/neuralnetworks/1.3/utils/src/PreparedModel.cpp index 2781053d07..5d82110829 100644 --- a/neuralnetworks/1.3/utils/src/PreparedModel.cpp +++ b/neuralnetworks/1.3/utils/src/PreparedModel.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -44,8 +45,7 @@ namespace { nn::GeneralResult, nn::Timing>> convertExecutionResultsHelper(const hidl_vec& outputShapes, const V1_2::Timing& timing) { - return std::make_pair(NN_TRY(validatedConvertToCanonical(outputShapes)), - NN_TRY(validatedConvertToCanonical(timing))); + return std::make_pair(NN_TRY(nn::convert(outputShapes)), NN_TRY(nn::convert(timing))); } nn::ExecutionResult, nn::Timing>> convertExecutionResults( @@ -55,8 +55,7 @@ nn::ExecutionResult, nn::Timing>> convert nn::GeneralResult> convertFencedExecutionCallbackResults( const V1_2::Timing& timingLaunched, const V1_2::Timing& timingFenced) { - return std::make_pair(NN_TRY(validatedConvertToCanonical(timingLaunched)), - NN_TRY(validatedConvertToCanonical(timingFenced))); + return std::make_pair(NN_TRY(nn::convert(timingLaunched)), NN_TRY(nn::convert(timingFenced))); } nn::GeneralResult> @@ -64,9 +63,9 @@ convertExecuteFencedResults(const hidl_handle& syncFence, const sp& callback) { auto resultSyncFence = nn::SyncFence::createAsSignaled(); if (syncFence.getNativeHandle() != nullptr) { - auto nativeHandle = NN_TRY(validatedConvertToCanonical(syncFence)); + auto sharedHandle = NN_TRY(nn::convert(syncFence)); resultSyncFence = NN_TRY(hal::utils::makeGeneralFailure( - nn::SyncFence::create(std::move(nativeHandle)), nn::ErrorStatus::GENERAL_FAILURE)); + nn::SyncFence::create(std::move(sharedHandle)), nn::ErrorStatus::GENERAL_FAILURE)); } if (callback == nullptr) { @@ -81,8 +80,8 @@ convertExecuteFencedResults(const hidl_handle& syncFence, auto cb = [&result](ErrorStatus status, const V1_2::Timing& timingLaunched, const V1_2::Timing& timingFenced) { if (status != ErrorStatus::NONE) { - const auto canonical = validatedConvertToCanonical(status).value_or( - nn::ErrorStatus::GENERAL_FAILURE); + const auto canonical = + nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); result = NN_ERROR(canonical) << "getExecutionInfo failed with " << toString(status); } else { result = convertFencedExecutionCallbackResults(timingLaunched, timingFenced); @@ -125,8 +124,7 @@ PreparedModel::executeSynchronously(const Request& request, V1_2::MeasureTiming const auto cb = [&result](ErrorStatus status, const hidl_vec& outputShapes, const V1_2::Timing& timing) { if (status != ErrorStatus::NONE) { - const auto canonical = - validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); result = NN_ERROR(canonical) << "executeSynchronously failed with " << toString(status); } else { result = convertExecutionResults(outputShapes, timing); @@ -152,8 +150,7 @@ PreparedModel::executeAsynchronously(const Request& request, V1_2::MeasureTiming const auto status = NN_TRY(hal::utils::makeExecutionFailure(hal::utils::handleTransportError(ret))); if (status != ErrorStatus::NONE) { - const auto canonical = - validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); return NN_ERROR(canonical) << "executeAsynchronously failed with " << toString(status); } @@ -223,8 +220,7 @@ PreparedModel::executeFenced(const nn::Request& request, const std::vector& callback) { if (status != ErrorStatus::NONE) { - const auto canonical = - validatedConvertToCanonical(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); + const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); result = NN_ERROR(canonical) << "executeFenced failed with " << toString(status); } else { result = convertExecuteFencedResults(syncFence, callback); diff --git a/neuralnetworks/utils/README.md b/neuralnetworks/utils/README.md new file mode 100644 index 0000000000..0dee103811 --- /dev/null +++ b/neuralnetworks/utils/README.md @@ -0,0 +1,50 @@ +# NNAPI Conversions + +`convert` fails if either the source type or the destination type is invalid, and it yields a valid +object if the conversion succeeds. For example, let's say that an enumeration in the current +version has fewer possible values than the "same" canonical enumeration, such as `OperationType`. +The new value of `HARD_SWISH` (introduced in Android R / NN HAL 1.3) does not map to any valid +existing value in `OperationType`, but an older value of `ADD` (introduced in Android OC-MR1 / NN +HAL 1.0) is valid. This can be seen in the following model conversions: + +```cpp +// Unsuccessful conversion +const nn::Model canonicalModel = createModelWhichHasV1_3Operations(); +const nn::Result maybeVersionedModel = V1_0::utils::convert(canonicalModel); +EXPECT_FALSE(maybeVersionedModel.has_value()); +``` +```cpp +// Successful conversion +const nn::Model canonicalModel = createModelWhichHasOnlyV1_0Operations(); +const nn::Result maybeVersionedModel = V1_0::utils::convert(canonicalModel); +ASSERT_TRUE(maybeVersionedModel.has_value()); +const V1_0::Model& versionedModel = maybeVersionedModel.value(); +EXPECT_TRUE(V1_0::utils::valid(versionedModel)); +``` + +`V1_X::utils::convert` does not guarantee that all information is preserved. For example, In the +case of `nn::ErrorStatus`, the new value of `MISSED_DEADLINE_TRANSIENT` can be represented by the +existing value of `V1_0::GENERAL_FAILURE`: + +```cpp +// Lossy Canonical -> HAL -> Canonical conversion +const nn::ErrorStatus canonicalBefore = nn::ErrorStatus::MISSED_DEADLINE_TRANSIENT; +const V1_0::ErrorStatus versioned = V1_0::utils::convert(canonicalBefore).value(); +const nn::ErrorStatus canonicalAfter = nn::convert(versioned).value(); +EXPECT_NE(canonicalBefore, canonicalAfter); +``` + +However, `nn::convert` is guaranteed to preserve all information: + +```cpp +// Lossless HAL -> Canonical -> HAL conversion +const V1_0::ErrorStatus versionedBefore = V1_0::ErrorStatus::GENERAL_FAILURE; +const nn::ErrorStatus canonical = nn::convert(versionedBefore).value(); +const V1_0::ErrorStatus versionedAfter = V1_0::utils::convert(canonical).value(); +EXPECT_EQ(versionedBefore, versionedAfter); +``` + +The `convert` functions operate only on types that used in a HIDL method call directly. The +`unvalidatedConvert` functions operate on types that are either used in a HIDL method call directly +(i.e., not as a nested class) or used in a subsequent version of the NN HAL. Prefer using `convert` +over `unvalidatedConvert`. -- GitLab From 22a57205e93cf6b9f4d3278b3e38a2e95f4ae4b4 Mon Sep 17 00:00:00 2001 From: Kevin Chyn Date: Wed, 2 Dec 2020 17:39:53 -0800 Subject: [PATCH 315/790] Add example IBiometricsFingerprint@2.2 HAL The exisitng 2.1 default implementation assumes that the device has a pre-HIDL HAL. Keep this implementation intact for vendors with legacy implementations. This change adds a new example 2.2 HAL that does not assume the existance of a pre-HIDL HAL, which can be used by cuttlefish and CTS. Bug: 172957689 Test: make -j android.hardware.biometrics.fingerprint@2.2-service.example Test: atest CtsBiometricsTestCases Test: m vts -j && vts-tradefed run commandAndExit vts -m VtsHalBiometricsFingerprintV2_1Target Test: m vts -j && vts-tradefed run commandAndExit vts -m VtsHalBiometricsFingerprintV2_2Target Change-Id: I4d87028d70fdb5c03759080e53e69751cf5e4307 --- biometrics/fingerprint/2.1/default/README.md | 6 + biometrics/fingerprint/2.2/default/Android.bp | 22 ++++ .../2.2/default/BiometricsFingerprint.cpp | 114 ++++++++++++++++++ .../2.2/default/BiometricsFingerprint.h | 73 +++++++++++ ...ware.biometrics.fingerprint@2.2-service.rc | 4 + ...are.biometrics.fingerprint@2.2-service.xml | 27 +++++ .../fingerprint/2.2/default/service.cpp | 44 +++++++ 7 files changed, 290 insertions(+) create mode 100644 biometrics/fingerprint/2.1/default/README.md create mode 100644 biometrics/fingerprint/2.2/default/Android.bp create mode 100644 biometrics/fingerprint/2.2/default/BiometricsFingerprint.cpp create mode 100644 biometrics/fingerprint/2.2/default/BiometricsFingerprint.h create mode 100644 biometrics/fingerprint/2.2/default/android.hardware.biometrics.fingerprint@2.2-service.rc create mode 100644 biometrics/fingerprint/2.2/default/android.hardware.biometrics.fingerprint@2.2-service.xml create mode 100644 biometrics/fingerprint/2.2/default/service.cpp diff --git a/biometrics/fingerprint/2.1/default/README.md b/biometrics/fingerprint/2.1/default/README.md new file mode 100644 index 0000000000..c41664e0fc --- /dev/null +++ b/biometrics/fingerprint/2.1/default/README.md @@ -0,0 +1,6 @@ +## Default IBiometricsFingerprint@2.1 HAL ## +--- + +## Overview: ## + +Provides a default implementation that loads pre-HIDL HALs and exposes it to the framework. \ No newline at end of file diff --git a/biometrics/fingerprint/2.2/default/Android.bp b/biometrics/fingerprint/2.2/default/Android.bp new file mode 100644 index 0000000000..8931308936 --- /dev/null +++ b/biometrics/fingerprint/2.2/default/Android.bp @@ -0,0 +1,22 @@ +cc_binary { + name: "android.hardware.biometrics.fingerprint@2.2-service.example", + defaults: ["hidl_defaults"], + init_rc: ["android.hardware.biometrics.fingerprint@2.2-service.rc"], + vintf_fragments: ["android.hardware.biometrics.fingerprint@2.2-service.xml"], + vendor: true, + relative_install_path: "hw", + srcs: [ + "BiometricsFingerprint.cpp", + "service.cpp", + ], + + shared_libs: [ + "libcutils", + "liblog", + "libhidlbase", + "libhardware", + "libutils", + "android.hardware.biometrics.fingerprint@2.2", + ], + +} diff --git a/biometrics/fingerprint/2.2/default/BiometricsFingerprint.cpp b/biometrics/fingerprint/2.2/default/BiometricsFingerprint.cpp new file mode 100644 index 0000000000..b07a17ce07 --- /dev/null +++ b/biometrics/fingerprint/2.2/default/BiometricsFingerprint.cpp @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#define LOG_TAG "android.hardware.biometrics.fingerprint@2.2-service" +#define LOG_VERBOSE "android.hardware.biometrics.fingerprint@2.2-service" + +#include + +#include +#include +#include +#include "BiometricsFingerprint.h" + +#include +#include +#include +#include + +namespace android { +namespace hardware { +namespace biometrics { +namespace fingerprint { +namespace V2_2 { +namespace implementation { + +using RequestStatus = android::hardware::biometrics::fingerprint::V2_1::RequestStatus; +using FingerprintError = android::hardware::biometrics::fingerprint::V2_1::FingerprintError; + +constexpr uint64_t kDeviceId = 1; + +BiometricsFingerprint::BiometricsFingerprint() { + +} + +BiometricsFingerprint::~BiometricsFingerprint() { + +} + +Return BiometricsFingerprint::setNotify( + const sp& clientCallback) { + mClientCallback = clientCallback; + return kDeviceId; +} + +Return BiometricsFingerprint::preEnroll() { + // On a real implementation, this must be generated and stored in the TEE or its equivalent. + return rand(); +} + +Return BiometricsFingerprint::enroll(const hidl_array& /* hat */, + uint32_t /* gid */, uint32_t /* timeoutSec */) { + // On a real implementation, the HAT must be checked in the TEE or its equivalent. + mClientCallback->onError(kDeviceId, FingerprintError::ERROR_UNABLE_TO_PROCESS, + 0 /* vendorCode */); + return RequestStatus::SYS_OK; +} + +Return BiometricsFingerprint::postEnroll() { + return RequestStatus::SYS_OK; +} + +Return BiometricsFingerprint::getAuthenticatorId() { + return 1; +} + +Return BiometricsFingerprint::cancel() { + mClientCallback->onError(kDeviceId, FingerprintError::ERROR_CANCELED, 0 /* vendorCode */); + return RequestStatus::SYS_OK; +} + +Return BiometricsFingerprint::enumerate() { + mClientCallback->onEnumerate(kDeviceId, 0 /* fingerId */, 0 /* groupId */, + 0 /* remaining */); + return RequestStatus::SYS_OK; +} + +Return BiometricsFingerprint::remove(uint32_t gid, uint32_t fid) { + mClientCallback->onRemoved(kDeviceId, fid, gid, 0 /* remaining */); + return RequestStatus::SYS_OK; +} + +Return BiometricsFingerprint::setActiveGroup(uint32_t /* gid */, + const hidl_string& storePath) { + // Return invalid for paths that the HAL is unable to write to. + std::string path = storePath.c_str(); + if (path.compare("") == 0 || path.compare("/") == 0) { + return RequestStatus::SYS_EINVAL; + } + return RequestStatus::SYS_OK; +} + +Return BiometricsFingerprint::authenticate(uint64_t /* operationId */, + uint32_t /* gid */) { + return RequestStatus::SYS_OK; +} + +} // namespace implementation +} // namespace V2_2 +} // namespace fingerprint +} // namespace biometrics +} // namespace hardware +} // namespace android diff --git a/biometrics/fingerprint/2.2/default/BiometricsFingerprint.h b/biometrics/fingerprint/2.2/default/BiometricsFingerprint.h new file mode 100644 index 0000000000..a6861b32ba --- /dev/null +++ b/biometrics/fingerprint/2.2/default/BiometricsFingerprint.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_BIOMETRICS_FINGERPRINT_V2_2_BIOMETRICSFINGERPRINT_H +#define ANDROID_HARDWARE_BIOMETRICS_FINGERPRINT_V2_2_BIOMETRICSFINGERPRINT_H + +#include +#include +#include +#include +#include +#include +#include + +namespace android { +namespace hardware { +namespace biometrics { +namespace fingerprint { +namespace V2_2 { +namespace implementation { + +using ::android::hardware::biometrics::fingerprint::V2_2::IBiometricsFingerprint; +using ::android::hardware::biometrics::fingerprint::V2_1::IBiometricsFingerprintClientCallback; +using ::android::hardware::biometrics::fingerprint::V2_1::RequestStatus; +using ::android::hardware::Return; +using ::android::hardware::Void; +using ::android::hardware::hidl_vec; +using ::android::hardware::hidl_string; +using ::android::sp; + +struct BiometricsFingerprint : public IBiometricsFingerprint { +public: + BiometricsFingerprint(); + ~BiometricsFingerprint(); + + // Methods from ::android::hardware::biometrics::fingerprint::V2_2::IBiometricsFingerprint follow. + Return setNotify(const sp& clientCallback) override; + Return preEnroll() override; + Return enroll(const hidl_array& hat, uint32_t gid, uint32_t timeoutSec) override; + Return postEnroll() override; + Return getAuthenticatorId() override; + Return cancel() override; + Return enumerate() override; + Return remove(uint32_t gid, uint32_t fid) override; + Return setActiveGroup(uint32_t gid, const hidl_string& storePath) override; + Return authenticate(uint64_t operationId, uint32_t gid) override; + +private: + sp mClientCallback; + +}; + +} // namespace implementation +} // namespace V2_2 +} // namespace fingerprint +} // namespace biometrics +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_BIOMETRICS_FINGERPRINT_V2_2_BIOMETRICSFINGERPRINT_H diff --git a/biometrics/fingerprint/2.2/default/android.hardware.biometrics.fingerprint@2.2-service.rc b/biometrics/fingerprint/2.2/default/android.hardware.biometrics.fingerprint@2.2-service.rc new file mode 100644 index 0000000000..1b406b08d0 --- /dev/null +++ b/biometrics/fingerprint/2.2/default/android.hardware.biometrics.fingerprint@2.2-service.rc @@ -0,0 +1,4 @@ +service vendor.fps_hal /vendor/bin/hw/android.hardware.biometrics.fingerprint@2.2-service.example + class hal + user nobody + group nobody diff --git a/biometrics/fingerprint/2.2/default/android.hardware.biometrics.fingerprint@2.2-service.xml b/biometrics/fingerprint/2.2/default/android.hardware.biometrics.fingerprint@2.2-service.xml new file mode 100644 index 0000000000..5e69a1ee5d --- /dev/null +++ b/biometrics/fingerprint/2.2/default/android.hardware.biometrics.fingerprint@2.2-service.xml @@ -0,0 +1,27 @@ + + + + + android.hardware.biometrics.fingerprint + hwbinder + 2.2 + + IBiometricsFingerprint + default + + + diff --git a/biometrics/fingerprint/2.2/default/service.cpp b/biometrics/fingerprint/2.2/default/service.cpp new file mode 100644 index 0000000000..5bc69a0719 --- /dev/null +++ b/biometrics/fingerprint/2.2/default/service.cpp @@ -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. + */ + +#define LOG_TAG "android.hardware.biometrics.fingerprint@2.2-service" + +#include +#include +#include +#include +#include +#include "BiometricsFingerprint.h" + +using android::hardware::biometrics::fingerprint::V2_2::IBiometricsFingerprint; +using android::hardware::biometrics::fingerprint::V2_2::implementation::BiometricsFingerprint; +using android::hardware::configureRpcThreadpool; +using android::hardware::joinRpcThreadpool; +using android::sp; + +int main() { + android::sp bio = new BiometricsFingerprint(); + + configureRpcThreadpool(1, true /*callerWillJoin*/); + + if (::android::OK != bio->registerAsService()) { + return 1; + } + + joinRpcThreadpool(); + + return 0; // should never get here +} -- GitLab From f5405b2123d6c5a8cad31f19e8519dd6496fe705 Mon Sep 17 00:00:00 2001 From: Kevin Chyn Date: Thu, 3 Dec 2020 19:55:06 -0800 Subject: [PATCH 316/790] Default face lockout should be duration==0 The default HAL never actually gets rejects, so should not have a non-zero lockout Bug: 172957689 Test: atest CtsBiometricsTestCases Change-Id: I74af8bd0a8a25f509b5572543dfef7d621f24c4e --- biometrics/face/1.1/default/BiometricsFace.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/biometrics/face/1.1/default/BiometricsFace.cpp b/biometrics/face/1.1/default/BiometricsFace.cpp index 2143880514..57b3a92690 100644 --- a/biometrics/face/1.1/default/BiometricsFace.cpp +++ b/biometrics/face/1.1/default/BiometricsFace.cpp @@ -24,8 +24,8 @@ using android::hardware::biometrics::face::V1_0::OptionalUint64; constexpr uint64_t kDeviceId = 123; // Arbitrary value. constexpr uint64_t kAuthenticatorId = 987; -// Arbitrary value. -constexpr uint64_t kLockoutDuration = 555; +// Not locked out. +constexpr uint64_t kLockoutDuration = 0; BiometricsFace::BiometricsFace() : mRandom(std::mt19937::default_seed) {} -- GitLab From 22ccb3cbc385a44a05c9dbade9217c8528dacf6d Mon Sep 17 00:00:00 2001 From: Tomasz Wasilczyk Date: Tue, 1 Dec 2020 12:27:37 -0800 Subject: [PATCH 317/790] Implement NL80211 protocol printer Also: - fix MessageGenre enum entries case - don't print verbose attributes Bug: 173144731 Test: logcat Change-Id: I6839a899ab3065cb988b85a0b8a2dcb135b49aa8 --- automotive/can/1.0/default/libnl++/Android.bp | 1 + .../can/1.0/default/libnl++/printer.cpp | 40 +- .../libnl++/protocols/MessageDefinition.cpp | 8 +- .../libnl++/protocols/MessageDefinition.h | 66 +- .../libnl++/protocols/NetlinkProtocol.cpp | 4 +- .../libnl++/protocols/NetlinkProtocol.h | 8 +- .../libnl++/protocols/common/Empty.cpp | 6 +- .../libnl++/protocols/common/Error.cpp | 2 +- .../libnl++/protocols/generic/Ctrl.cpp | 34 +- .../default/libnl++/protocols/generic/Ctrl.h | 8 +- .../libnl++/protocols/generic/Generic.cpp | 7 +- .../libnl++/protocols/generic/Generic.h | 6 +- .../protocols/generic/GenericMessageBase.cpp | 17 +- .../protocols/generic/families/Nl80211.cpp | 1009 +++++++++++++++++ .../protocols/generic/families/Nl80211.h | 28 + .../default/libnl++/protocols/route/Link.cpp | 7 +- .../default/libnl++/protocols/route/structs.h | 10 - .../1.0/default/libnl++/protocols/structs.h | 33 + 18 files changed, 1239 insertions(+), 55 deletions(-) create mode 100644 automotive/can/1.0/default/libnl++/protocols/generic/families/Nl80211.cpp create mode 100644 automotive/can/1.0/default/libnl++/protocols/generic/families/Nl80211.h create mode 100644 automotive/can/1.0/default/libnl++/protocols/structs.h diff --git a/automotive/can/1.0/default/libnl++/Android.bp b/automotive/can/1.0/default/libnl++/Android.bp index 4042b169d6..90e1002508 100644 --- a/automotive/can/1.0/default/libnl++/Android.bp +++ b/automotive/can/1.0/default/libnl++/Android.bp @@ -25,6 +25,7 @@ cc_library_static { "protocols/generic/Generic.cpp", "protocols/generic/GenericMessageBase.cpp", "protocols/generic/Unknown.cpp", + "protocols/generic/families/Nl80211.cpp", "protocols/route/Link.cpp", "protocols/route/Route.cpp", "protocols/route/structs.cpp", diff --git a/automotive/can/1.0/default/libnl++/printer.cpp b/automotive/can/1.0/default/libnl++/printer.cpp index e6cada2801..f08897e951 100644 --- a/automotive/can/1.0/default/libnl++/printer.cpp +++ b/automotive/can/1.0/default/libnl++/printer.cpp @@ -51,24 +51,24 @@ static void flagsToStream(std::stringstream& ss, __u16 nlmsg_flags, protocols::M printFlag(NLM_F_DUMP_FILTERED, "DUMP_FILTERED"); switch (genre) { - case protocols::MessageGenre::UNKNOWN: + case protocols::MessageGenre::Unknown: break; - case protocols::MessageGenre::GET: + case protocols::MessageGenre::Get: printFlag(NLM_F_DUMP, "DUMP"); // ROOT | MATCH printFlag(NLM_F_ROOT, "ROOT"); printFlag(NLM_F_MATCH, "MATCH"); printFlag(NLM_F_ATOMIC, "ATOMIC"); break; - case protocols::MessageGenre::NEW: + case protocols::MessageGenre::New: printFlag(NLM_F_REPLACE, "REPLACE"); printFlag(NLM_F_EXCL, "EXCL"); printFlag(NLM_F_CREATE, "CREATE"); printFlag(NLM_F_APPEND, "APPEND"); break; - case protocols::MessageGenre::DELETE: + case protocols::MessageGenre::Delete: printFlag(NLM_F_NONREC, "NONREC"); break; - case protocols::MessageGenre::ACK: + case protocols::MessageGenre::Ack: printFlag(NLM_F_CAPPED, "CAPPED"); printFlag(NLM_F_ACK_TLVS, "ACK_TLVS"); break; @@ -99,11 +99,25 @@ static void toStream(std::stringstream& ss, const Buffer data) { static void toStream(std::stringstream& ss, const Buffer attr, const protocols::AttributeMap& attrMap) { using DataType = protocols::AttributeDefinition::DataType; + using Flags = protocols::AttributeDefinition::Flags; const auto attrtype = attrMap[attr->nla_type]; - ss << attrtype.name << ": "; + ss << attrtype.name; + + if (attrtype.dataType == DataType::Flag && attr.data().getRaw().len() == 0) return; + ss << ": "; + + if (attrtype.flags == Flags::Verbose) { + const auto raw = attr.data(); + ss << "{len=" << raw.getRaw().len(); + ss << ", crc=" << std::hex << std::setw(4) << crc16(raw) << std::dec; + ss << "}"; + return; + } + switch (attrtype.dataType) { case DataType::Raw: + case DataType::Flag: toStream(ss, attr.data()); break; case DataType::Nested: { @@ -117,13 +131,19 @@ static void toStream(std::stringstream& ss, const Buffer attr, ss << '}'; break; } + case DataType::StringNul: case DataType::String: { const auto str = attr.data().getRaw(); - ss << '"' << printableOnly({str.ptr(), str.len()}) << '"'; + auto len = str.len(); + if (attrtype.dataType == DataType::StringNul && len > 0 && str.ptr()[len - 1] == '\0') { + len--; + } + + ss << '"' << printableOnly({str.ptr(), len}) << '"'; break; } case DataType::Uint: - ss << attr.data().copyFirst(); + ss << attr.data().copyFirst(); break; case DataType::Struct: { const auto structToStream = @@ -147,10 +167,12 @@ std::string toString(const Buffer hdr, int protocol, bool printPayload } protocols::NetlinkProtocol& protocolDescr = *protocolMaybe; - const auto msgDescMaybe = protocolDescr.getMessageDescriptor(hdr->nlmsg_type); + auto msgDescMaybe = protocolDescr.getMessageDescriptor(hdr->nlmsg_type); const auto msgDetails = protocols::MessageDescriptor::getMessageDetails(msgDescMaybe, hdr->nlmsg_type); + if (msgDescMaybe.has_value()) msgDescMaybe->get().track(hdr); + ss << "nlmsg{" << protocolDescr.getName() << " "; ss << "hdr={"; diff --git a/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.cpp b/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.cpp index c93d86561e..aaf24a53aa 100644 --- a/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.cpp +++ b/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.cpp @@ -56,15 +56,17 @@ const AttributeMap& MessageDescriptor::getAttributeMap() const { MessageDescriptor::MessageDetails MessageDescriptor::getMessageDetails(nlmsgtype_t msgtype) const { const auto it = mMessageDetails.find(msgtype); - if (it == mMessageDetails.end()) return {std::to_string(msgtype), MessageGenre::UNKNOWN}; + if (it == mMessageDetails.end()) return {std::to_string(msgtype), MessageGenre::Unknown}; return it->second; } MessageDescriptor::MessageDetails MessageDescriptor::getMessageDetails( - const std::optional>& msgDescMaybe, + const std::optional>& msgDescMaybe, nlmsgtype_t msgtype) { if (msgDescMaybe.has_value()) return msgDescMaybe->get().getMessageDetails(msgtype); - return {std::to_string(msgtype), protocols::MessageGenre::UNKNOWN}; + return {std::to_string(msgtype), protocols::MessageGenre::Unknown}; } +void MessageDescriptor::track(const Buffer /* hdr */) {} + } // namespace android::nl::protocols diff --git a/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.h b/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.h index bd0e60f9cf..8bed5e7a7e 100644 --- a/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.h +++ b/automotive/can/1.0/default/libnl++/protocols/MessageDefinition.h @@ -54,17 +54,64 @@ class AttributeMap : private std::map, AttributeDefi */ struct AttributeDefinition { enum class DataType : uint8_t { + /** + * Binary blob (or attribute of unknown type). + */ Raw, + + /** + * Nested attribute (with or without NLA_F_NESTED). + */ Nested, + + /** + * Non-null terminated string. + * + * The length of the string is determined by the size of an attribute. + */ String, + + /** + * Null terminated string. + */ + StringNul, + + /** + * Unsigned integer of size 8, 16, 32 or 64 bits. + */ Uint, + + /** + * Structure which printer is defined in ops ToStream variant. + */ Struct, + + /** + * Flag attribute. + * + * The attribute doesn't have any contents. The flag is set when the attribute is present, + * it's not when it's absent from attribute list. + */ + Flag, + }; + enum class Flags : uint8_t { + Verbose = (1 << 0), }; using ToStream = std::function attr)>; std::string name; DataType dataType = DataType::Raw; std::variant ops = AttributeMap{}; + + /** + * Attribute flags. + * + * It's not really a bitmask flag set (since you are not supposed to compare enum class by + * bitmask), but std::set bumps compile time from 16s to 3m. Let's leave it as-is for + * now and revisit if we get some flags that can be used in pairs. When it happens, review all + * uses of the flags field to include the "&" operator and not "==". + */ + Flags flags = {}; }; /** @@ -74,11 +121,11 @@ struct AttributeDefinition { * section in linux/netlink.h. */ enum class MessageGenre { - UNKNOWN, - GET, - NEW, - DELETE, - ACK, + Unknown, + Get, + New, + Delete, + Ack, }; /** @@ -103,8 +150,15 @@ class MessageDescriptor { MessageDetails getMessageDetails(nlmsgtype_t msgtype) const; virtual void dataToStream(std::stringstream& ss, const Buffer hdr) const = 0; + /** + * Message tracking for stateful protocols (such as NETLINK_GENERIC). + * + * \param hdr Message to track + */ + virtual void track(const Buffer hdr); + static MessageDetails getMessageDetails( - const std::optional>& msgDescMaybe, + const std::optional>& msgDescMaybe, nlmsgtype_t msgtype); protected: diff --git a/automotive/can/1.0/default/libnl++/protocols/NetlinkProtocol.cpp b/automotive/can/1.0/default/libnl++/protocols/NetlinkProtocol.cpp index cd2e8c6860..16208aba14 100644 --- a/automotive/can/1.0/default/libnl++/protocols/NetlinkProtocol.cpp +++ b/automotive/can/1.0/default/libnl++/protocols/NetlinkProtocol.cpp @@ -32,7 +32,7 @@ const std::string& NetlinkProtocol::getName() const { return mName; } -const std::optional> +const std::optional> NetlinkProtocol::getMessageDescriptor(nlmsgtype_t nlmsg_type) { if (mMessageDescrs.count(nlmsg_type) == 0) return std::nullopt; return *mMessageDescrs.find(nlmsg_type)->second; @@ -41,7 +41,7 @@ NetlinkProtocol::getMessageDescriptor(nlmsgtype_t nlmsg_type) { NetlinkProtocol::MessageDescriptorMap NetlinkProtocol::toMap( const NetlinkProtocol::MessageDescriptorList& descrs, int protocol) { MessageDescriptorMap map; - for (const auto& descr : descrs) { + for (auto& descr : descrs) { for (const auto& [mtype, mdet] : descr->getMessageDetailsMap()) { map.emplace(mtype, descr); } diff --git a/automotive/can/1.0/default/libnl++/protocols/NetlinkProtocol.h b/automotive/can/1.0/default/libnl++/protocols/NetlinkProtocol.h index c969547393..b173b91270 100644 --- a/automotive/can/1.0/default/libnl++/protocols/NetlinkProtocol.h +++ b/automotive/can/1.0/default/libnl++/protocols/NetlinkProtocol.h @@ -40,17 +40,17 @@ class NetlinkProtocol { const std::string& getName() const; - virtual const std::optional> - getMessageDescriptor(nlmsgtype_t nlmsg_type); + virtual const std::optional> getMessageDescriptor( + nlmsgtype_t nlmsg_type); protected: - typedef std::vector> MessageDescriptorList; + typedef std::vector> MessageDescriptorList; NetlinkProtocol(int protocol, const std::string& name, const MessageDescriptorList&& messageDescrs); private: - typedef std::map> MessageDescriptorMap; + typedef std::map> MessageDescriptorMap; const int mProtocol; const std::string mName; diff --git a/automotive/can/1.0/default/libnl++/protocols/common/Empty.cpp b/automotive/can/1.0/default/libnl++/protocols/common/Empty.cpp index 8a672d3864..4b509c9069 100644 --- a/automotive/can/1.0/default/libnl++/protocols/common/Empty.cpp +++ b/automotive/can/1.0/default/libnl++/protocols/common/Empty.cpp @@ -20,9 +20,9 @@ namespace android::nl::protocols::base { // clang-format off Empty::Empty() : MessageDefinition("nlmsg", { - {NLMSG_NOOP, {"NOOP", MessageGenre::UNKNOWN}}, - {NLMSG_DONE, {"DONE", MessageGenre::UNKNOWN}}, - {NLMSG_OVERRUN, {"OVERRUN", MessageGenre::UNKNOWN}}, + {NLMSG_NOOP, {"NOOP", MessageGenre::Unknown}}, + {NLMSG_DONE, {"DONE", MessageGenre::Unknown}}, + {NLMSG_OVERRUN, {"OVERRUN", MessageGenre::Unknown}}, }) {} // clang-format on diff --git a/automotive/can/1.0/default/libnl++/protocols/common/Error.cpp b/automotive/can/1.0/default/libnl++/protocols/common/Error.cpp index 44708a3a9c..47a989609a 100644 --- a/automotive/can/1.0/default/libnl++/protocols/common/Error.cpp +++ b/automotive/can/1.0/default/libnl++/protocols/common/Error.cpp @@ -26,7 +26,7 @@ using DataType = AttributeDefinition::DataType; // clang-format off Error::Error(int protocol) : MessageDefinition("nlmsg", { - {NLMSG_ERROR, {"ERROR", MessageGenre::ACK}}, + {NLMSG_ERROR, {"ERROR", MessageGenre::Ack}}, }, { {NLMSGERR_ATTR_MSG, {"MSG", DataType::String}}, {NLMSGERR_ATTR_OFFS, {"OFFS", DataType::Uint}}, diff --git a/automotive/can/1.0/default/libnl++/protocols/generic/Ctrl.cpp b/automotive/can/1.0/default/libnl++/protocols/generic/Ctrl.cpp index a3c6736cef..1e1ad12c84 100644 --- a/automotive/can/1.0/default/libnl++/protocols/generic/Ctrl.cpp +++ b/automotive/can/1.0/default/libnl++/protocols/generic/Ctrl.cpp @@ -16,12 +16,19 @@ #include "Ctrl.h" +#include "families/Nl80211.h" + +#include + namespace android::nl::protocols::generic { using DataType = AttributeDefinition::DataType; +using Flags = AttributeDefinition::Flags; // clang-format off -Ctrl::Ctrl() : GenericMessageBase(GENL_ID_CTRL, "ID_CTRL", { +Ctrl::Ctrl(Generic::FamilyRegister& familyRegister) + : GenericMessageBase(GENL_ID_CTRL, "ID_CTRL", +{ {CTRL_CMD_NEWFAMILY, "NEWFAMILY"}, {CTRL_CMD_DELFAMILY, "DELFAMILY"}, {CTRL_CMD_GETFAMILY, "GETFAMILY"}, @@ -33,7 +40,7 @@ Ctrl::Ctrl() : GenericMessageBase(GENL_ID_CTRL, "ID_CTRL", { {CTRL_CMD_GETMCAST_GRP, "GETMCAST_GRP"}, }, { {CTRL_ATTR_FAMILY_ID, {"FAMILY_ID", DataType::Uint}}, - {CTRL_ATTR_FAMILY_NAME, {"FAMILY_NAME", DataType::String}}, + {CTRL_ATTR_FAMILY_NAME, {"FAMILY_NAME", DataType::StringNul}}, {CTRL_ATTR_VERSION, {"VERSION", DataType::Uint}}, {CTRL_ATTR_HDRSIZE, {"HDRSIZE", DataType::Uint}}, {CTRL_ATTR_MAXATTR, {"MAXATTR", DataType::Uint}}, @@ -42,14 +49,31 @@ Ctrl::Ctrl() : GenericMessageBase(GENL_ID_CTRL, "ID_CTRL", { {CTRL_ATTR_OP_ID, {"ID", DataType::Uint}}, {CTRL_ATTR_OP_FLAGS, {"FLAGS", DataType::Uint}}, }}}, - }}}, + }, Flags::Verbose}}, {CTRL_ATTR_MCAST_GROUPS, {"MCAST_GROUPS", DataType::Nested, AttributeMap{ {std::nullopt, {"GRP", DataType::Nested, AttributeMap{ - {CTRL_ATTR_MCAST_GRP_NAME, {"NAME", DataType::String}}, + {CTRL_ATTR_MCAST_GRP_NAME, {"NAME", DataType::StringNul}}, {CTRL_ATTR_MCAST_GRP_ID, {"ID", DataType::Uint}}, }}}, }}}, -}) {} +}), mFamilyRegister(familyRegister) {} // clang-format on +void Ctrl::track(const Buffer hdr) { + const auto msgMaybe = Message::parse(hdr, {GENL_ID_CTRL}); + if (!msgMaybe.has_value()) return; + const auto msg = *msgMaybe; + + if (msg->cmd != CTRL_CMD_NEWFAMILY) return; + const auto familyId = msg.attributes.get(CTRL_ATTR_FAMILY_ID); + const auto familyName = msg.attributes.get(CTRL_ATTR_FAMILY_NAME); + + /* For now, we support just a single family. But if you add more, please define proper + * abstraction and not hardcode every name and class here. + */ + if (familyName == "nl80211") { + mFamilyRegister[familyId] = std::make_shared(familyId); + } +} + } // namespace android::nl::protocols::generic diff --git a/automotive/can/1.0/default/libnl++/protocols/generic/Ctrl.h b/automotive/can/1.0/default/libnl++/protocols/generic/Ctrl.h index 6af87a8bb8..b13df02282 100644 --- a/automotive/can/1.0/default/libnl++/protocols/generic/Ctrl.h +++ b/automotive/can/1.0/default/libnl++/protocols/generic/Ctrl.h @@ -16,13 +16,19 @@ #pragma once +#include "Generic.h" #include "GenericMessageBase.h" namespace android::nl::protocols::generic { class Ctrl : public GenericMessageBase { public: - Ctrl(); + Ctrl(Generic::FamilyRegister& familyRegister); + + void track(const Buffer hdr) override; + + private: + Generic::FamilyRegister& mFamilyRegister; }; } // namespace android::nl::protocols::generic diff --git a/automotive/can/1.0/default/libnl++/protocols/generic/Generic.cpp b/automotive/can/1.0/default/libnl++/protocols/generic/Generic.cpp index 1a24914ab7..5e34a1fe5d 100644 --- a/automotive/can/1.0/default/libnl++/protocols/generic/Generic.cpp +++ b/automotive/can/1.0/default/libnl++/protocols/generic/Generic.cpp @@ -21,11 +21,12 @@ namespace android::nl::protocols::generic { -Generic::Generic() : NetlinkProtocol(NETLINK_GENERIC, "GENERIC", {std::make_shared()}) {} +Generic::Generic() + : NetlinkProtocol(NETLINK_GENERIC, "GENERIC", {std::make_shared(mFamilyRegister)}) {} -const std::optional> Generic::getMessageDescriptor( +const std::optional> Generic::getMessageDescriptor( nlmsgtype_t nlmsg_type) { - const auto desc = NetlinkProtocol::getMessageDescriptor(nlmsg_type); + auto desc = NetlinkProtocol::getMessageDescriptor(nlmsg_type); if (desc.has_value()) return desc; auto it = mFamilyRegister.find(nlmsg_type); diff --git a/automotive/can/1.0/default/libnl++/protocols/generic/Generic.h b/automotive/can/1.0/default/libnl++/protocols/generic/Generic.h index 593c92d3e8..2cdd584ef1 100644 --- a/automotive/can/1.0/default/libnl++/protocols/generic/Generic.h +++ b/automotive/can/1.0/default/libnl++/protocols/generic/Generic.h @@ -25,13 +25,15 @@ namespace android::nl::protocols::generic { */ class Generic : public NetlinkProtocol { public: + typedef std::map> FamilyRegister; + Generic(); - const std::optional> getMessageDescriptor( + const std::optional> getMessageDescriptor( nlmsgtype_t nlmsg_type); private: - std::map> mFamilyRegister; + FamilyRegister mFamilyRegister; }; } // namespace android::nl::protocols::generic diff --git a/automotive/can/1.0/default/libnl++/protocols/generic/GenericMessageBase.cpp b/automotive/can/1.0/default/libnl++/protocols/generic/GenericMessageBase.cpp index 134638e45b..b7b811b629 100644 --- a/automotive/can/1.0/default/libnl++/protocols/generic/GenericMessageBase.cpp +++ b/automotive/can/1.0/default/libnl++/protocols/generic/GenericMessageBase.cpp @@ -22,16 +22,27 @@ GenericMessageBase::GenericMessageBase( nlmsgtype_t msgtype, const std::string&& msgname, const std::initializer_list commandNames, const std::initializer_list attrTypes) - : MessageDefinition(msgname, {{msgtype, {msgname, MessageGenre::UNKNOWN}}}, + : MessageDefinition(msgname, {{msgtype, {msgname, MessageGenre::Unknown}}}, attrTypes), mCommandNames(commandNames) {} void GenericMessageBase::toStream(std::stringstream& ss, const genlmsghdr& data) const { + const auto commandNameIt = mCommandNames.find(data.cmd); + const auto commandName = (commandNameIt == mCommandNames.end()) + ? std::nullopt + : std::optional(commandNameIt->second); + + if (commandName.has_value() && data.version == 1 && data.reserved == 0) { + // short version + ss << *commandName; + return; + } + ss << "genlmsghdr{"; - if (mCommandNames.count(data.cmd) == 0) { + if (commandName.has_value()) { ss << "cmd=" << unsigned(data.cmd); } else { - ss << "cmd=" << mCommandNames.find(data.cmd)->second; + ss << "cmd=" << *commandName; } ss << ", version=" << unsigned(data.version); if (data.reserved != 0) ss << ", reserved=" << data.reserved; diff --git a/automotive/can/1.0/default/libnl++/protocols/generic/families/Nl80211.cpp b/automotive/can/1.0/default/libnl++/protocols/generic/families/Nl80211.cpp new file mode 100644 index 0000000000..23ec66f4d6 --- /dev/null +++ b/automotive/can/1.0/default/libnl++/protocols/generic/families/Nl80211.cpp @@ -0,0 +1,1009 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Nl80211.h" + +#include "../../structs.h" +#include "common.h" + +#include + +#include + +namespace android::nl::protocols::generic::families { + +/** + * Reduce verbosity of printed Information Elements. + */ +static constexpr bool kCompactIE = true; + +enum { + // broken compatibility in Aug 2020 + NL80211_ATTR_CNTDWN_OFFS_BEACON = NL80211_ATTR_CSA_C_OFF_BEACON, + NL80211_ATTR_CNTDWN_OFFS_PRESP = NL80211_ATTR_CSA_C_OFF_PRESP, + + // new fields not available in current Android + NL80211_ATTR_FILS_DISCOVERY = NL80211_ATTR_HE_6GHZ_CAPABILITY + 1, + NL80211_ATTR_UNSOL_BCAST_PROBE_RESP, + NL80211_ATTR_S1G_CAPABILITY, + NL80211_ATTR_S1G_CAPABILITY_MASK, + + NL80211_FREQUENCY_ATTR_1MHZ = NL80211_FREQUENCY_ATTR_OFFSET + 1, + NL80211_FREQUENCY_ATTR_2MHZ, + NL80211_FREQUENCY_ATTR_4MHZ, + NL80211_FREQUENCY_ATTR_8MHZ, + NL80211_FREQUENCY_ATTR_16MHZ, +}; + +enum ieee80211_eid { + WLAN_EID_SSID = 0, +}; + +using DataType = AttributeDefinition::DataType; +using Flags = AttributeDefinition::Flags; + +static void informationElementsToStream(std::stringstream& ss, const Buffer attr); +static void nl80211_pattern_supportToStream(std::stringstream& ss, const Buffer attr); + +static const AttributeMap iftypes{ + {NL80211_IFTYPE_UNSPECIFIED, {"UNSPECIFIED", DataType::Flag}}, + {NL80211_IFTYPE_ADHOC, {"ADHOC", DataType::Flag}}, + {NL80211_IFTYPE_STATION, {"STATION", DataType::Flag}}, + {NL80211_IFTYPE_AP, {"AP", DataType::Flag}}, + {NL80211_IFTYPE_AP_VLAN, {"AP_VLAN", DataType::Flag}}, + {NL80211_IFTYPE_WDS, {"WDS", DataType::Flag}}, + {NL80211_IFTYPE_MONITOR, {"MONITOR", DataType::Flag}}, + {NL80211_IFTYPE_MESH_POINT, {"MESH_POINT", DataType::Flag}}, + {NL80211_IFTYPE_P2P_CLIENT, {"P2P_CLIENT", DataType::Flag}}, + {NL80211_IFTYPE_P2P_GO, {"P2P_GO", DataType::Flag}}, + {NL80211_IFTYPE_P2P_DEVICE, {"P2P_DEVICE", DataType::Flag}}, + {NL80211_IFTYPE_OCB, {"OCB", DataType::Flag}}, + {NL80211_IFTYPE_NAN, {"NAN", DataType::Flag}}, +}; + +// clang-format off +Nl80211::Nl80211(nlmsgtype_t familyId) : GenericMessageBase(familyId, "nl80211", { + /* Script to generate the (initial) top-level list from linux/nl80211.h: + * sed -e 's/^ NL80211_CMD_\(.*\),$/ {NL80211_CMD_\1, "\1"},/g' + */ + {NL80211_CMD_UNSPEC, "UNSPEC"}, + + {NL80211_CMD_GET_WIPHY, "GET_WIPHY"}, + {NL80211_CMD_SET_WIPHY, "SET_WIPHY"}, + {NL80211_CMD_NEW_WIPHY, "NEW_WIPHY"}, + {NL80211_CMD_DEL_WIPHY, "DEL_WIPHY"}, + + {NL80211_CMD_GET_INTERFACE, "GET_INTERFACE"}, + {NL80211_CMD_SET_INTERFACE, "SET_INTERFACE"}, + {NL80211_CMD_NEW_INTERFACE, "NEW_INTERFACE"}, + {NL80211_CMD_DEL_INTERFACE, "DEL_INTERFACE"}, + + {NL80211_CMD_GET_KEY, "GET_KEY"}, + {NL80211_CMD_SET_KEY, "SET_KEY"}, + {NL80211_CMD_NEW_KEY, "NEW_KEY"}, + {NL80211_CMD_DEL_KEY, "DEL_KEY"}, + + {NL80211_CMD_GET_BEACON, "GET_BEACON"}, + {NL80211_CMD_SET_BEACON, "SET_BEACON"}, + {NL80211_CMD_START_AP, "START_AP"}, + {NL80211_CMD_STOP_AP, "STOP_AP"}, + + {NL80211_CMD_GET_STATION, "GET_STATION"}, + {NL80211_CMD_SET_STATION, "SET_STATION"}, + {NL80211_CMD_NEW_STATION, "NEW_STATION"}, + {NL80211_CMD_DEL_STATION, "DEL_STATION"}, + + {NL80211_CMD_GET_MPATH, "GET_MPATH"}, + {NL80211_CMD_SET_MPATH, "SET_MPATH"}, + {NL80211_CMD_NEW_MPATH, "NEW_MPATH"}, + {NL80211_CMD_DEL_MPATH, "DEL_MPATH"}, + + {NL80211_CMD_SET_BSS, "SET_BSS"}, + + {NL80211_CMD_SET_REG, "SET_REG"}, + {NL80211_CMD_REQ_SET_REG, "REQ_SET_REG"}, + + {NL80211_CMD_GET_MESH_CONFIG, "GET_MESH_CONFIG"}, + {NL80211_CMD_SET_MESH_CONFIG, "SET_MESH_CONFIG"}, + + {NL80211_CMD_SET_MGMT_EXTRA_IE, "SET_MGMT_EXTRA_IE"}, + + {NL80211_CMD_GET_REG, "GET_REG"}, + + {NL80211_CMD_GET_SCAN, "GET_SCAN"}, + {NL80211_CMD_TRIGGER_SCAN, "TRIGGER_SCAN"}, + {NL80211_CMD_NEW_SCAN_RESULTS, "NEW_SCAN_RESULTS"}, + {NL80211_CMD_SCAN_ABORTED, "SCAN_ABORTED"}, + + {NL80211_CMD_REG_CHANGE, "REG_CHANGE"}, + + {NL80211_CMD_AUTHENTICATE, "AUTHENTICATE"}, + {NL80211_CMD_ASSOCIATE, "ASSOCIATE"}, + {NL80211_CMD_DEAUTHENTICATE, "DEAUTHENTICATE"}, + {NL80211_CMD_DISASSOCIATE, "DISASSOCIATE"}, + + {NL80211_CMD_MICHAEL_MIC_FAILURE, "MICHAEL_MIC_FAILURE"}, + + {NL80211_CMD_REG_BEACON_HINT, "REG_BEACON_HINT"}, + + {NL80211_CMD_JOIN_IBSS, "JOIN_IBSS"}, + {NL80211_CMD_LEAVE_IBSS, "LEAVE_IBSS"}, + + {NL80211_CMD_TESTMODE, "TESTMODE"}, + + {NL80211_CMD_CONNECT, "CONNECT"}, + {NL80211_CMD_ROAM, "ROAM"}, + {NL80211_CMD_DISCONNECT, "DISCONNECT"}, + + {NL80211_CMD_SET_WIPHY_NETNS, "SET_WIPHY_NETNS"}, + + {NL80211_CMD_GET_SURVEY, "GET_SURVEY"}, + {NL80211_CMD_NEW_SURVEY_RESULTS, "NEW_SURVEY_RESULTS"}, + + {NL80211_CMD_SET_PMKSA, "SET_PMKSA"}, + {NL80211_CMD_DEL_PMKSA, "DEL_PMKSA"}, + {NL80211_CMD_FLUSH_PMKSA, "FLUSH_PMKSA"}, + + {NL80211_CMD_REMAIN_ON_CHANNEL, "REMAIN_ON_CHANNEL"}, + {NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL, "CANCEL_REMAIN_ON_CHANNEL"}, + + {NL80211_CMD_SET_TX_BITRATE_MASK, "SET_TX_BITRATE_MASK"}, + + {NL80211_CMD_REGISTER_FRAME, "REGISTER_FRAME"}, + {NL80211_CMD_FRAME, "FRAME"}, + {NL80211_CMD_FRAME_TX_STATUS, "FRAME_TX_STATUS"}, + + {NL80211_CMD_SET_POWER_SAVE, "SET_POWER_SAVE"}, + {NL80211_CMD_GET_POWER_SAVE, "GET_POWER_SAVE"}, + + {NL80211_CMD_SET_CQM, "SET_CQM"}, + {NL80211_CMD_NOTIFY_CQM, "NOTIFY_CQM"}, + + {NL80211_CMD_SET_CHANNEL, "SET_CHANNEL"}, + {NL80211_CMD_SET_WDS_PEER, "SET_WDS_PEER"}, + + {NL80211_CMD_FRAME_WAIT_CANCEL, "FRAME_WAIT_CANCEL"}, + + {NL80211_CMD_JOIN_MESH, "JOIN_MESH"}, + {NL80211_CMD_LEAVE_MESH, "LEAVE_MESH"}, + + {NL80211_CMD_UNPROT_DEAUTHENTICATE, "UNPROT_DEAUTHENTICATE"}, + {NL80211_CMD_UNPROT_DISASSOCIATE, "UNPROT_DISASSOCIATE"}, + + {NL80211_CMD_NEW_PEER_CANDIDATE, "NEW_PEER_CANDIDATE"}, + + {NL80211_CMD_GET_WOWLAN, "GET_WOWLAN"}, + {NL80211_CMD_SET_WOWLAN, "SET_WOWLAN"}, + + {NL80211_CMD_START_SCHED_SCAN, "START_SCHED_SCAN"}, + {NL80211_CMD_STOP_SCHED_SCAN, "STOP_SCHED_SCAN"}, + {NL80211_CMD_SCHED_SCAN_RESULTS, "SCHED_SCAN_RESULTS"}, + {NL80211_CMD_SCHED_SCAN_STOPPED, "SCHED_SCAN_STOPPED"}, + + {NL80211_CMD_SET_REKEY_OFFLOAD, "SET_REKEY_OFFLOAD"}, + + {NL80211_CMD_PMKSA_CANDIDATE, "PMKSA_CANDIDATE"}, + + {NL80211_CMD_TDLS_OPER, "TDLS_OPER"}, + {NL80211_CMD_TDLS_MGMT, "TDLS_MGMT"}, + + {NL80211_CMD_UNEXPECTED_FRAME, "UNEXPECTED_FRAME"}, + + {NL80211_CMD_PROBE_CLIENT, "PROBE_CLIENT"}, + + {NL80211_CMD_REGISTER_BEACONS, "REGISTER_BEACONS"}, + + {NL80211_CMD_UNEXPECTED_4ADDR_FRAME, "UNEXPECTED_4ADDR_FRAME"}, + + {NL80211_CMD_SET_NOACK_MAP, "SET_NOACK_MAP"}, + + {NL80211_CMD_CH_SWITCH_NOTIFY, "CH_SWITCH_NOTIFY"}, + + {NL80211_CMD_START_P2P_DEVICE, "START_P2P_DEVICE"}, + {NL80211_CMD_STOP_P2P_DEVICE, "STOP_P2P_DEVICE"}, + + {NL80211_CMD_CONN_FAILED, "CONN_FAILED"}, + + {NL80211_CMD_SET_MCAST_RATE, "SET_MCAST_RATE"}, + + {NL80211_CMD_SET_MAC_ACL, "SET_MAC_ACL"}, + + {NL80211_CMD_RADAR_DETECT, "RADAR_DETECT"}, + + {NL80211_CMD_GET_PROTOCOL_FEATURES, "GET_PROTOCOL_FEATURES"}, + + {NL80211_CMD_UPDATE_FT_IES, "UPDATE_FT_IES"}, + {NL80211_CMD_FT_EVENT, "FT_EVENT"}, + + {NL80211_CMD_CRIT_PROTOCOL_START, "CRIT_PROTOCOL_START"}, + {NL80211_CMD_CRIT_PROTOCOL_STOP, "CRIT_PROTOCOL_STOP"}, + + {NL80211_CMD_GET_COALESCE, "GET_COALESCE"}, + {NL80211_CMD_SET_COALESCE, "SET_COALESCE"}, + + {NL80211_CMD_CHANNEL_SWITCH, "CHANNEL_SWITCH"}, + + {NL80211_CMD_VENDOR, "VENDOR"}, + + {NL80211_CMD_SET_QOS_MAP, "SET_QOS_MAP"}, + + {NL80211_CMD_ADD_TX_TS, "ADD_TX_TS"}, + {NL80211_CMD_DEL_TX_TS, "DEL_TX_TS"}, + + {NL80211_CMD_GET_MPP, "GET_MPP"}, + + {NL80211_CMD_JOIN_OCB, "JOIN_OCB"}, + {NL80211_CMD_LEAVE_OCB, "LEAVE_OCB"}, + + {NL80211_CMD_CH_SWITCH_STARTED_NOTIFY, "CH_SWITCH_STARTED_NOTIFY"}, + + {NL80211_CMD_TDLS_CHANNEL_SWITCH, "TDLS_CHANNEL_SWITCH"}, + {NL80211_CMD_TDLS_CANCEL_CHANNEL_SWITCH, "TDLS_CANCEL_CHANNEL_SWITCH"}, + + {NL80211_CMD_WIPHY_REG_CHANGE, "WIPHY_REG_CHANGE"}, + + {NL80211_CMD_ABORT_SCAN, "ABORT_SCAN"}, + + {NL80211_CMD_START_NAN, "START_NAN"}, + {NL80211_CMD_STOP_NAN, "STOP_NAN"}, + {NL80211_CMD_ADD_NAN_FUNCTION, "ADD_NAN_FUNCTION"}, + {NL80211_CMD_DEL_NAN_FUNCTION, "DEL_NAN_FUNCTION"}, + {NL80211_CMD_CHANGE_NAN_CONFIG, "CHANGE_NAN_CONFIG"}, + {NL80211_CMD_NAN_MATCH, "NAN_MATCH"}, + + {NL80211_CMD_SET_MULTICAST_TO_UNICAST, "SET_MULTICAST_TO_UNICAST"}, + + {NL80211_CMD_UPDATE_CONNECT_PARAMS, "UPDATE_CONNECT_PARAMS"}, + + {NL80211_CMD_SET_PMK, "SET_PMK"}, + {NL80211_CMD_DEL_PMK, "DEL_PMK"}, + + {NL80211_CMD_PORT_AUTHORIZED, "PORT_AUTHORIZED"}, + + {NL80211_CMD_RELOAD_REGDB, "RELOAD_REGDB"}, + + {NL80211_CMD_EXTERNAL_AUTH, "EXTERNAL_AUTH"}, + + {NL80211_CMD_STA_OPMODE_CHANGED, "STA_OPMODE_CHANGED"}, + + {NL80211_CMD_CONTROL_PORT_FRAME, "CONTROL_PORT_FRAME"}, + + {NL80211_CMD_GET_FTM_RESPONDER_STATS, "GET_FTM_RESPONDER_STATS"}, + + {NL80211_CMD_PEER_MEASUREMENT_START, "PEER_MEASUREMENT_START"}, + {NL80211_CMD_PEER_MEASUREMENT_RESULT, "PEER_MEASUREMENT_RESULT"}, + {NL80211_CMD_PEER_MEASUREMENT_COMPLETE, "PEER_MEASUREMENT_COMPLETE"}, + + {NL80211_CMD_NOTIFY_RADAR, "NOTIFY_RADAR"}, + + {NL80211_CMD_UPDATE_OWE_INFO, "UPDATE_OWE_INFO"}, + + {NL80211_CMD_PROBE_MESH_LINK, "PROBE_MESH_LINK"}, + + {NL80211_CMD_SET_TID_CONFIG, "SET_TID_CONFIG"}, + + {NL80211_CMD_UNPROT_BEACON, "UNPROT_BEACON"}, + + {NL80211_CMD_CONTROL_PORT_FRAME_TX_STATUS, "CONTROL_PORT_FRAME_TX_STATUS"}, +}, { + /* Script to generate the (initial) top-level list from linux/nl80211.h: + * sed -e 's/^\tNL80211_ATTR_\(.*\),$/ {NL80211_ATTR_\1, {"\1"}},/g' + */ + {NL80211_ATTR_UNSPEC, {"UNSPEC"}}, + + {NL80211_ATTR_WIPHY, {"WIPHY", DataType::Uint}}, + {NL80211_ATTR_WIPHY_NAME, {"WIPHY_NAME", DataType::StringNul}}, + + {NL80211_ATTR_IFINDEX, {"IFINDEX", DataType::Uint}}, + {NL80211_ATTR_IFNAME, {"IFNAME", DataType::StringNul}}, + {NL80211_ATTR_IFTYPE, {"IFTYPE", DataType::Uint}}, + + {NL80211_ATTR_MAC, {"MAC", DataType::Raw}}, + + {NL80211_ATTR_KEY_DATA, {"KEY_DATA"}}, + {NL80211_ATTR_KEY_IDX, {"KEY_IDX"}}, + {NL80211_ATTR_KEY_CIPHER, {"KEY_CIPHER"}}, + {NL80211_ATTR_KEY_SEQ, {"KEY_SEQ"}}, + {NL80211_ATTR_KEY_DEFAULT, {"KEY_DEFAULT"}}, + + {NL80211_ATTR_BEACON_INTERVAL, {"BEACON_INTERVAL"}}, + {NL80211_ATTR_DTIM_PERIOD, {"DTIM_PERIOD"}}, + {NL80211_ATTR_BEACON_HEAD, {"BEACON_HEAD"}}, + {NL80211_ATTR_BEACON_TAIL, {"BEACON_TAIL"}}, + + {NL80211_ATTR_STA_AID, {"STA_AID"}}, + {NL80211_ATTR_STA_FLAGS, {"STA_FLAGS"}}, + {NL80211_ATTR_STA_LISTEN_INTERVAL, {"STA_LISTEN_INTERVAL"}}, + {NL80211_ATTR_STA_SUPPORTED_RATES, {"STA_SUPPORTED_RATES"}}, + {NL80211_ATTR_STA_VLAN, {"STA_VLAN"}}, + {NL80211_ATTR_STA_INFO, {"STA_INFO"}}, + + {NL80211_ATTR_WIPHY_BANDS, {"WIPHY_BANDS", DataType::Nested, AttributeMap{ + {std::nullopt, {"BAND", DataType::Nested, AttributeMap{ + {NL80211_BAND_ATTR_FREQS, {"FREQS", DataType::Nested, AttributeMap{ + {std::nullopt, {"FQ", DataType::Nested, AttributeMap{ + {NL80211_FREQUENCY_ATTR_FREQ, {"FREQ", DataType::Uint}}, + {NL80211_FREQUENCY_ATTR_DISABLED, {"DISABLED", DataType::Flag}}, + {NL80211_FREQUENCY_ATTR_NO_IR, {"NO_IR", DataType::Flag}}, + {__NL80211_FREQUENCY_ATTR_NO_IBSS, {"_NO_IBSS", DataType::Flag}}, + {NL80211_FREQUENCY_ATTR_RADAR, {"RADAR", DataType::Flag}}, + {NL80211_FREQUENCY_ATTR_MAX_TX_POWER, {"MAX_TX_POWER", DataType::Uint}}, + {NL80211_FREQUENCY_ATTR_DFS_STATE, {"DFS_STATE", DataType::Uint}}, + {NL80211_FREQUENCY_ATTR_DFS_TIME, {"DFS_TIME", DataType::Uint}}, + {NL80211_FREQUENCY_ATTR_NO_HT40_MINUS, {"NO_HT40_MINUS", DataType::Flag}}, + {NL80211_FREQUENCY_ATTR_NO_HT40_PLUS, {"NO_HT40_PLUS", DataType::Flag}}, + {NL80211_FREQUENCY_ATTR_NO_80MHZ, {"NO_80MHZ", DataType::Flag}}, + {NL80211_FREQUENCY_ATTR_NO_160MHZ, {"NO_160MHZ", DataType::Flag}}, + {NL80211_FREQUENCY_ATTR_DFS_CAC_TIME, {"DFS_CAC_TIME", DataType::Uint}}, + {NL80211_FREQUENCY_ATTR_INDOOR_ONLY, {"INDOOR_ONLY", DataType::Flag}}, + {NL80211_FREQUENCY_ATTR_IR_CONCURRENT, {"IR_CONCURRENT", DataType::Flag}}, + {NL80211_FREQUENCY_ATTR_NO_20MHZ, {"NO_20MHZ", DataType::Flag}}, + {NL80211_FREQUENCY_ATTR_NO_10MHZ, {"NO_10MHZ", DataType::Flag}}, + {NL80211_FREQUENCY_ATTR_WMM, {"WMM"}}, + {NL80211_FREQUENCY_ATTR_NO_HE, {"NO_HE", DataType::Flag}}, + {NL80211_FREQUENCY_ATTR_OFFSET, {"OFFSET", DataType::Uint}}, + {NL80211_FREQUENCY_ATTR_1MHZ, {"1MHZ", DataType::Flag}}, + {NL80211_FREQUENCY_ATTR_2MHZ, {"2MHZ", DataType::Flag}}, + {NL80211_FREQUENCY_ATTR_4MHZ, {"4MHZ", DataType::Flag}}, + {NL80211_FREQUENCY_ATTR_8MHZ, {"8MHZ", DataType::Flag}}, + {NL80211_FREQUENCY_ATTR_16MHZ, {"16MHZ", DataType::Flag}}, + }}}, + }, Flags::Verbose}}, + {NL80211_BAND_ATTR_RATES, {"RATES", DataType::Nested, AttributeMap{ + {std::nullopt, {"RATE", DataType::Nested, AttributeMap{ + {NL80211_BITRATE_ATTR_RATE, {"RATE", DataType::Uint}}, + {NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE, + {"2GHZ_SHORTPREAMBLE", DataType::Flag}}, + }}}, + }}}, + + {NL80211_BAND_ATTR_HT_MCS_SET, {"HT_MCS_SET"}}, // struct ieee80211_mcs_info + {NL80211_BAND_ATTR_HT_CAPA, {"HT_CAPA", DataType::Uint}}, + {NL80211_BAND_ATTR_HT_AMPDU_FACTOR, {"HT_AMPDU_FACTOR", DataType::Uint}}, + {NL80211_BAND_ATTR_HT_AMPDU_DENSITY, {"HT_AMPDU_DENSITY", DataType::Uint}}, + + {NL80211_BAND_ATTR_VHT_MCS_SET, {"VHT_MCS_SET"}}, // struct ieee80211_vht_mcs_info + {NL80211_BAND_ATTR_VHT_CAPA, {"VHT_CAPA", DataType::Uint}}, + {NL80211_BAND_ATTR_IFTYPE_DATA, {"IFTYPE_DATA"}}, + + {NL80211_BAND_ATTR_EDMG_CHANNELS, {"EDMG_CHANNELS"}}, + {NL80211_BAND_ATTR_EDMG_BW_CONFIG, {"EDMG_BW_CONFIG"}}, + }}}, + }, Flags::Verbose}}, + + {NL80211_ATTR_MNTR_FLAGS, {"MNTR_FLAGS"}}, + + {NL80211_ATTR_MESH_ID, {"MESH_ID"}}, + {NL80211_ATTR_STA_PLINK_ACTION, {"STA_PLINK_ACTION"}}, + {NL80211_ATTR_MPATH_NEXT_HOP, {"MPATH_NEXT_HOP"}}, + {NL80211_ATTR_MPATH_INFO, {"MPATH_INFO"}}, + + {NL80211_ATTR_BSS_CTS_PROT, {"BSS_CTS_PROT"}}, + {NL80211_ATTR_BSS_SHORT_PREAMBLE, {"BSS_SHORT_PREAMBLE"}}, + {NL80211_ATTR_BSS_SHORT_SLOT_TIME, {"BSS_SHORT_SLOT_TIME"}}, + + {NL80211_ATTR_HT_CAPABILITY, {"HT_CAPABILITY"}}, + + {NL80211_ATTR_SUPPORTED_IFTYPES, {"SUPPORTED_IFTYPES", DataType::Nested, iftypes}}, + + {NL80211_ATTR_REG_ALPHA2, {"REG_ALPHA2"}}, + {NL80211_ATTR_REG_RULES, {"REG_RULES"}}, + + {NL80211_ATTR_MESH_CONFIG, {"MESH_CONFIG"}}, + + {NL80211_ATTR_BSS_BASIC_RATES, {"BSS_BASIC_RATES"}}, + + {NL80211_ATTR_WIPHY_TXQ_PARAMS, {"WIPHY_TXQ_PARAMS"}}, + {NL80211_ATTR_WIPHY_FREQ, {"WIPHY_FREQ"}}, + {NL80211_ATTR_WIPHY_CHANNEL_TYPE, {"WIPHY_CHANNEL_TYPE"}}, + + {NL80211_ATTR_KEY_DEFAULT_MGMT, {"KEY_DEFAULT_MGMT"}}, + + {NL80211_ATTR_MGMT_SUBTYPE, {"MGMT_SUBTYPE"}}, + {NL80211_ATTR_IE, {"IE"}}, + + {NL80211_ATTR_MAX_NUM_SCAN_SSIDS, {"MAX_NUM_SCAN_SSIDS", DataType::Uint}}, + + {NL80211_ATTR_SCAN_FREQUENCIES, {"SCAN_FREQUENCIES", DataType::Nested, AttributeMap{ + {std::nullopt, {"FQ", DataType::Uint}}, + }, Flags::Verbose}}, + {NL80211_ATTR_SCAN_SSIDS, {"SCAN_SSIDS", DataType::Nested, AttributeMap{ + {std::nullopt, {"SSID", DataType::String}}, + }}}, + {NL80211_ATTR_GENERATION, {"GENERATION", DataType::Uint}}, + {NL80211_ATTR_BSS, {"BSS", DataType::Nested, AttributeMap{ + {NL80211_BSS_BSSID, {"BSSID", DataType::Raw}}, + {NL80211_BSS_FREQUENCY, {"FREQUENCY", DataType::Uint}}, + {NL80211_BSS_TSF, {"TSF", DataType::Uint}}, + {NL80211_BSS_BEACON_INTERVAL, {"BEACON_INTERVAL", DataType::Uint}}, + {NL80211_BSS_CAPABILITY, {"CAPABILITY", DataType::Uint}}, + {NL80211_BSS_INFORMATION_ELEMENTS, {"INFORMATION_ELEMENTS", + DataType::Struct, informationElementsToStream}}, + {NL80211_BSS_SIGNAL_MBM, {"SIGNAL_MBM", DataType::Uint}}, + {NL80211_BSS_SIGNAL_UNSPEC, {"SIGNAL_UNSPEC", DataType::Uint}}, + {NL80211_BSS_STATUS, {"STATUS", DataType::Uint}}, // enum nl80211_bss_status + {NL80211_BSS_SEEN_MS_AGO, {"SEEN_MS_AGO", DataType::Uint}}, + {NL80211_BSS_BEACON_IES, {"BEACON_IES", DataType::Struct, informationElementsToStream}}, + {NL80211_BSS_CHAN_WIDTH, {"CHAN_WIDTH", DataType::Uint}}, + {NL80211_BSS_BEACON_TSF, {"BEACON_TSF", DataType::Uint}}, + {NL80211_BSS_PRESP_DATA, {"PRESP_DATA", DataType::Flag}}, + {NL80211_BSS_LAST_SEEN_BOOTTIME, {"LAST_SEEN_BOOTTIME", DataType::Uint}}, + {NL80211_BSS_PAD, {"PAD"}}, + {NL80211_BSS_PARENT_TSF, {"PARENT_TSF"}}, + {NL80211_BSS_PARENT_BSSID, {"PARENT_BSSID"}}, + {NL80211_BSS_CHAIN_SIGNAL, {"CHAIN_SIGNAL", DataType::Nested, AttributeMap{ + {std::nullopt, {"SIG", DataType::Uint}}, + }}}, + {NL80211_BSS_FREQUENCY_OFFSET, {"FREQUENCY_OFFSET"}}, + }}}, + + {NL80211_ATTR_REG_INITIATOR, {"REG_INITIATOR"}}, + {NL80211_ATTR_REG_TYPE, {"REG_TYPE"}}, + + {NL80211_ATTR_SUPPORTED_COMMANDS, {"SUPPORTED_COMMANDS", DataType::Nested,AttributeMap{ + {std::nullopt, {"CMD", DataType::Uint}}, // enum nl80211_commands + }}}, + + {NL80211_ATTR_FRAME, {"FRAME"}}, + {NL80211_ATTR_SSID, {"SSID"}}, + {NL80211_ATTR_AUTH_TYPE, {"AUTH_TYPE"}}, + {NL80211_ATTR_REASON_CODE, {"REASON_CODE"}}, + + {NL80211_ATTR_KEY_TYPE, {"KEY_TYPE"}}, + + {NL80211_ATTR_MAX_SCAN_IE_LEN, {"MAX_SCAN_IE_LEN", DataType::Uint}}, + {NL80211_ATTR_CIPHER_SUITES, {"CIPHER_SUITES", DataType::Struct, arrayToStream}}, + + {NL80211_ATTR_FREQ_BEFORE, {"FREQ_BEFORE"}}, + {NL80211_ATTR_FREQ_AFTER, {"FREQ_AFTER"}}, + + {NL80211_ATTR_FREQ_FIXED, {"FREQ_FIXED"}}, + + {NL80211_ATTR_WIPHY_RETRY_SHORT, {"WIPHY_RETRY_SHORT", DataType::Uint}}, + {NL80211_ATTR_WIPHY_RETRY_LONG, {"WIPHY_RETRY_LONG", DataType::Uint}}, + {NL80211_ATTR_WIPHY_FRAG_THRESHOLD, {"WIPHY_FRAG_THRESHOLD", DataType::Uint}}, + {NL80211_ATTR_WIPHY_RTS_THRESHOLD, {"WIPHY_RTS_THRESHOLD", DataType::Uint}}, + + {NL80211_ATTR_TIMED_OUT, {"TIMED_OUT"}}, + + {NL80211_ATTR_USE_MFP, {"USE_MFP"}}, + + {NL80211_ATTR_STA_FLAGS2, {"STA_FLAGS2"}}, + + {NL80211_ATTR_CONTROL_PORT, {"CONTROL_PORT"}}, + + {NL80211_ATTR_TESTDATA, {"TESTDATA"}}, + + {NL80211_ATTR_PRIVACY, {"PRIVACY"}}, + + {NL80211_ATTR_DISCONNECTED_BY_AP, {"DISCONNECTED_BY_AP"}}, + {NL80211_ATTR_STATUS_CODE, {"STATUS_CODE"}}, + + {NL80211_ATTR_CIPHER_SUITES_PAIRWISE, {"CIPHER_SUITES_PAIRWISE"}}, + {NL80211_ATTR_CIPHER_SUITE_GROUP, {"CIPHER_SUITE_GROUP"}}, + {NL80211_ATTR_WPA_VERSIONS, {"WPA_VERSIONS"}}, + {NL80211_ATTR_AKM_SUITES, {"AKM_SUITES"}}, + + {NL80211_ATTR_REQ_IE, {"REQ_IE"}}, + {NL80211_ATTR_RESP_IE, {"RESP_IE"}}, + + {NL80211_ATTR_PREV_BSSID, {"PREV_BSSID"}}, + + {NL80211_ATTR_KEY, {"KEY"}}, + {NL80211_ATTR_KEYS, {"KEYS"}}, + + {NL80211_ATTR_PID, {"PID"}}, + + {NL80211_ATTR_4ADDR, {"4ADDR"}}, + + {NL80211_ATTR_SURVEY_INFO, {"SURVEY_INFO"}}, + + {NL80211_ATTR_PMKID, {"PMKID"}}, + {NL80211_ATTR_MAX_NUM_PMKIDS, {"MAX_NUM_PMKIDS", DataType::Uint}}, + + {NL80211_ATTR_DURATION, {"DURATION"}}, + + {NL80211_ATTR_COOKIE, {"COOKIE"}}, + + {NL80211_ATTR_WIPHY_COVERAGE_CLASS, {"WIPHY_COVERAGE_CLASS", DataType::Uint}}, + + {NL80211_ATTR_TX_RATES, {"TX_RATES"}}, + + {NL80211_ATTR_FRAME_MATCH, {"FRAME_MATCH"}}, + + {NL80211_ATTR_ACK, {"ACK"}}, + + {NL80211_ATTR_PS_STATE, {"PS_STATE"}}, + + {NL80211_ATTR_CQM, {"CQM"}}, + + {NL80211_ATTR_LOCAL_STATE_CHANGE, {"LOCAL_STATE_CHANGE"}}, + + {NL80211_ATTR_AP_ISOLATE, {"AP_ISOLATE"}}, + + {NL80211_ATTR_WIPHY_TX_POWER_SETTING, {"WIPHY_TX_POWER_SETTING"}}, + {NL80211_ATTR_WIPHY_TX_POWER_LEVEL, {"WIPHY_TX_POWER_LEVEL"}}, + + {NL80211_ATTR_TX_FRAME_TYPES, {"TX_FRAME_TYPES", DataType::Nested, AttributeMap{ + {std::nullopt, {"TFT", DataType::Nested, AttributeMap{ + {NL80211_ATTR_FRAME_TYPE, {"FRAME_TYPE", DataType::Uint}}, + }}}, + }, Flags::Verbose}}, + {NL80211_ATTR_RX_FRAME_TYPES, {"RX_FRAME_TYPES", DataType::Nested, AttributeMap{ + {std::nullopt, {"RFT", DataType::Nested, AttributeMap{ + {NL80211_ATTR_FRAME_TYPE, {"FRAME_TYPE", DataType::Uint}}, + }}}, + }, Flags::Verbose}}, + + {NL80211_ATTR_FRAME_TYPE, {"FRAME_TYPE", DataType::Uint}}, + + {NL80211_ATTR_CONTROL_PORT_ETHERTYPE, {"CONTROL_PORT_ETHERTYPE"}}, + {NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT, {"CONTROL_PORT_NO_ENCRYPT"}}, + + {NL80211_ATTR_SUPPORT_IBSS_RSN, {"SUPPORT_IBSS_RSN"}}, + + {NL80211_ATTR_WIPHY_ANTENNA_TX, {"WIPHY_ANTENNA_TX"}}, + {NL80211_ATTR_WIPHY_ANTENNA_RX, {"WIPHY_ANTENNA_RX"}}, + + {NL80211_ATTR_MCAST_RATE, {"MCAST_RATE"}}, + + {NL80211_ATTR_OFFCHANNEL_TX_OK, {"OFFCHANNEL_TX_OK", DataType::Flag}}, + + {NL80211_ATTR_BSS_HT_OPMODE, {"BSS_HT_OPMODE"}}, + + {NL80211_ATTR_KEY_DEFAULT_TYPES, {"KEY_DEFAULT_TYPES"}}, + + {NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION, + {"MAX_REMAIN_ON_CHANNEL_DURATION", DataType::Uint}}, + + {NL80211_ATTR_MESH_SETUP, {"MESH_SETUP"}}, + + {NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX, {"WIPHY_ANTENNA_AVAIL_TX", DataType::Uint}}, + {NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX, {"WIPHY_ANTENNA_AVAIL_RX", DataType::Uint}}, + + {NL80211_ATTR_SUPPORT_MESH_AUTH, {"SUPPORT_MESH_AUTH"}}, + {NL80211_ATTR_STA_PLINK_STATE, {"STA_PLINK_STATE"}}, + + {NL80211_ATTR_WOWLAN_TRIGGERS, {"WOWLAN_TRIGGERS"}}, + {NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED, + {"WOWLAN_TRIGGERS_SUPPORTED", DataType::Nested, AttributeMap{ + {NL80211_WOWLAN_TRIG_ANY, {"ANY", DataType::Flag}}, + {NL80211_WOWLAN_TRIG_DISCONNECT, {"DISCONNECT", DataType::Flag}}, + {NL80211_WOWLAN_TRIG_MAGIC_PKT, {"MAGIC_PKT", DataType::Flag}}, + {NL80211_WOWLAN_TRIG_PKT_PATTERN, + {"PKT_PATTERN", DataType::Struct, nl80211_pattern_supportToStream}}, + {NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED, {"GTK_REKEY_SUPPORTED", DataType::Flag}}, + {NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE, {"GTK_REKEY_FAILURE", DataType::Flag}}, + {NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST, {"EAP_IDENT_REQUEST", DataType::Flag}}, + {NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE, {"4WAY_HANDSHAKE", DataType::Flag}}, + {NL80211_WOWLAN_TRIG_RFKILL_RELEASE, {"RFKILL_RELEASE", DataType::Flag}}, + {NL80211_WOWLAN_TRIG_TCP_CONNECTION, {"TCP_CONNECTION", DataType::Nested, AttributeMap{ + {NL80211_WOWLAN_TCP_SRC_IPV4, {"SRC_IPV4"}}, + {NL80211_WOWLAN_TCP_DST_IPV4, {"DST_IPV4"}}, + {NL80211_WOWLAN_TCP_DST_MAC, {"DST_MAC"}}, + {NL80211_WOWLAN_TCP_SRC_PORT, {"SRC_PORT", DataType::Uint}}, + {NL80211_WOWLAN_TCP_DST_PORT, {"DST_PORT", DataType::Uint}}, + {NL80211_WOWLAN_TCP_DATA_PAYLOAD, {"DATA_PAYLOAD"}}, + {NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ, {"DATA_PAYLOAD_SEQ"}}, + {NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN, {"DATA_PAYLOAD_TOKEN"}}, + {NL80211_WOWLAN_TCP_DATA_INTERVAL, {"DATA_INTERVAL", DataType::Uint}}, + {NL80211_WOWLAN_TCP_WAKE_PAYLOAD, {"WAKE_PAYLOAD"}}, + {NL80211_WOWLAN_TCP_WAKE_MASK, {"WAKE_MASK"}}, + }}}, + {NL80211_WOWLAN_TRIG_NET_DETECT, {"NET_DETECT", DataType::Uint}}, + + /* Not in WOWLAN_TRIGGERS_SUPPORTED: + * - NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211 + * - NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211_LEN + * - NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023 + * - NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023_LEN + * - NL80211_WOWLAN_TRIG_WAKEUP_TCP_MATCH + * - NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST + * - NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS + * - NL80211_WOWLAN_TRIG_NET_DETECT_RESULTS + */ + }}}, + + {NL80211_ATTR_SCHED_SCAN_INTERVAL, {"SCHED_SCAN_INTERVAL"}}, + + {NL80211_ATTR_INTERFACE_COMBINATIONS, {"INTERFACE_COMBINATIONS", DataType::Nested, AttributeMap{ + {std::nullopt, {"IC", DataType::Nested, AttributeMap{ + {NL80211_IFACE_COMB_UNSPEC, {"UNSPEC"}}, + {NL80211_IFACE_COMB_LIMITS, {"LIMITS", DataType::Nested, AttributeMap{ + {std::nullopt, {"LT", DataType::Nested, AttributeMap{ + {NL80211_IFACE_LIMIT_UNSPEC, {"UNSPEC"}}, + {NL80211_IFACE_LIMIT_MAX, {"MAX", DataType::Uint}}, + {NL80211_IFACE_LIMIT_TYPES, {"TYPES", DataType::Nested, iftypes}}, + }}}, + }}}, + {NL80211_IFACE_COMB_MAXNUM, {"MAXNUM", DataType::Uint}}, + {NL80211_IFACE_COMB_STA_AP_BI_MATCH, {"STA_AP_BI_MATCH", DataType::Flag}}, + {NL80211_IFACE_COMB_NUM_CHANNELS, {"NUM_CHANNELS", DataType::Uint}}, + {NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS, {"RADAR_DETECT_WIDTHS", DataType::Uint}}, + {NL80211_IFACE_COMB_RADAR_DETECT_REGIONS, {"RADAR_DETECT_REGIONS", DataType::Uint}}, + {NL80211_IFACE_COMB_BI_MIN_GCD, {"BI_MIN_GCD"}}, + }}}, + }, Flags::Verbose}}, + {NL80211_ATTR_SOFTWARE_IFTYPES, {"SOFTWARE_IFTYPES", DataType::Nested, iftypes}}, + + {NL80211_ATTR_REKEY_DATA, {"REKEY_DATA"}}, + + {NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS, {"MAX_NUM_SCHED_SCAN_SSIDS", DataType::Uint}}, + {NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN, {"MAX_SCHED_SCAN_IE_LEN", DataType::Uint}}, + + {NL80211_ATTR_SCAN_SUPP_RATES, {"SCAN_SUPP_RATES"}}, + + {NL80211_ATTR_HIDDEN_SSID, {"HIDDEN_SSID"}}, + + {NL80211_ATTR_IE_PROBE_RESP, {"IE_PROBE_RESP"}}, + {NL80211_ATTR_IE_ASSOC_RESP, {"IE_ASSOC_RESP"}}, + + {NL80211_ATTR_STA_WME, {"STA_WME"}}, + {NL80211_ATTR_SUPPORT_AP_UAPSD, {"SUPPORT_AP_UAPSD"}}, + + {NL80211_ATTR_ROAM_SUPPORT, {"ROAM_SUPPORT", DataType::Flag}}, + + {NL80211_ATTR_SCHED_SCAN_MATCH, {"SCHED_SCAN_MATCH"}}, + {NL80211_ATTR_MAX_MATCH_SETS, {"MAX_MATCH_SETS", DataType::Uint}}, + + {NL80211_ATTR_PMKSA_CANDIDATE, {"PMKSA_CANDIDATE"}}, + + {NL80211_ATTR_TX_NO_CCK_RATE, {"TX_NO_CCK_RATE"}}, + + {NL80211_ATTR_TDLS_ACTION, {"TDLS_ACTION"}}, + {NL80211_ATTR_TDLS_DIALOG_TOKEN, {"TDLS_DIALOG_TOKEN"}}, + {NL80211_ATTR_TDLS_OPERATION, {"TDLS_OPERATION"}}, + {NL80211_ATTR_TDLS_SUPPORT, {"TDLS_SUPPORT", DataType::Flag}}, + {NL80211_ATTR_TDLS_EXTERNAL_SETUP, {"TDLS_EXTERNAL_SETUP", DataType::Flag}}, + + {NL80211_ATTR_DEVICE_AP_SME, {"DEVICE_AP_SME", DataType::Uint}}, + + {NL80211_ATTR_DONT_WAIT_FOR_ACK, {"DONT_WAIT_FOR_ACK"}}, + + {NL80211_ATTR_FEATURE_FLAGS, {"FEATURE_FLAGS", DataType::Uint}}, + + {NL80211_ATTR_PROBE_RESP_OFFLOAD, {"PROBE_RESP_OFFLOAD", DataType::Uint}}, + + {NL80211_ATTR_PROBE_RESP, {"PROBE_RESP"}}, + + {NL80211_ATTR_DFS_REGION, {"DFS_REGION"}}, + + {NL80211_ATTR_DISABLE_HT, {"DISABLE_HT"}}, + {NL80211_ATTR_HT_CAPABILITY_MASK, {"HT_CAPABILITY_MASK"}}, + + {NL80211_ATTR_NOACK_MAP, {"NOACK_MAP"}}, + + {NL80211_ATTR_INACTIVITY_TIMEOUT, {"INACTIVITY_TIMEOUT"}}, + + {NL80211_ATTR_RX_SIGNAL_DBM, {"RX_SIGNAL_DBM"}}, + + {NL80211_ATTR_BG_SCAN_PERIOD, {"BG_SCAN_PERIOD"}}, + + {NL80211_ATTR_WDEV, {"WDEV", DataType::Uint}}, + + {NL80211_ATTR_USER_REG_HINT_TYPE, {"USER_REG_HINT_TYPE"}}, + + {NL80211_ATTR_CONN_FAILED_REASON, {"CONN_FAILED_REASON"}}, + + {NL80211_ATTR_AUTH_DATA, {"AUTH_DATA"}}, + + {NL80211_ATTR_VHT_CAPABILITY, {"VHT_CAPABILITY"}}, + + {NL80211_ATTR_SCAN_FLAGS, {"SCAN_FLAGS", DataType::Uint}}, + + {NL80211_ATTR_CHANNEL_WIDTH, {"CHANNEL_WIDTH"}}, + {NL80211_ATTR_CENTER_FREQ1, {"CENTER_FREQ1"}}, + {NL80211_ATTR_CENTER_FREQ2, {"CENTER_FREQ2"}}, + + {NL80211_ATTR_P2P_CTWINDOW, {"P2P_CTWINDOW"}}, + {NL80211_ATTR_P2P_OPPPS, {"P2P_OPPPS"}}, + + {NL80211_ATTR_LOCAL_MESH_POWER_MODE, {"LOCAL_MESH_POWER_MODE"}}, + + {NL80211_ATTR_ACL_POLICY, {"ACL_POLICY"}}, + + {NL80211_ATTR_MAC_ADDRS, {"MAC_ADDRS"}}, + + {NL80211_ATTR_MAC_ACL_MAX, {"MAC_ACL_MAX", DataType::Uint}}, + + {NL80211_ATTR_RADAR_EVENT, {"RADAR_EVENT"}}, + + {NL80211_ATTR_EXT_CAPA, {"EXT_CAPA"}}, + {NL80211_ATTR_EXT_CAPA_MASK, {"EXT_CAPA_MASK"}}, + + {NL80211_ATTR_STA_CAPABILITY, {"STA_CAPABILITY"}}, + {NL80211_ATTR_STA_EXT_CAPABILITY, {"STA_EXT_CAPABILITY"}}, + + {NL80211_ATTR_PROTOCOL_FEATURES, {"PROTOCOL_FEATURES", DataType::Uint}}, + {NL80211_ATTR_SPLIT_WIPHY_DUMP, {"SPLIT_WIPHY_DUMP", DataType::Flag}}, + + {NL80211_ATTR_DISABLE_VHT, {"DISABLE_VHT", DataType::Flag}}, + {NL80211_ATTR_VHT_CAPABILITY_MASK, {"VHT_CAPABILITY_MASK"}}, + + {NL80211_ATTR_MDID, {"MDID"}}, + {NL80211_ATTR_IE_RIC, {"IE_RIC"}}, + + {NL80211_ATTR_CRIT_PROT_ID, {"CRIT_PROT_ID"}}, + {NL80211_ATTR_MAX_CRIT_PROT_DURATION, {"MAX_CRIT_PROT_DURATION"}}, + + {NL80211_ATTR_PEER_AID, {"PEER_AID"}}, + + {NL80211_ATTR_COALESCE_RULE, {"COALESCE_RULE"}}, + + {NL80211_ATTR_CH_SWITCH_COUNT, {"CH_SWITCH_COUNT"}}, + {NL80211_ATTR_CH_SWITCH_BLOCK_TX, {"CH_SWITCH_BLOCK_TX"}}, + {NL80211_ATTR_CSA_IES, {"CSA_IES"}}, + {NL80211_ATTR_CNTDWN_OFFS_BEACON, {"CNTDWN_OFFS_BEACON"}}, + {NL80211_ATTR_CNTDWN_OFFS_PRESP, {"CNTDWN_OFFS_PRESP"}}, + + {NL80211_ATTR_RXMGMT_FLAGS, {"RXMGMT_FLAGS"}}, + + {NL80211_ATTR_STA_SUPPORTED_CHANNELS, {"STA_SUPPORTED_CHANNELS"}}, + + {NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES, {"STA_SUPPORTED_OPER_CLASSES"}}, + + {NL80211_ATTR_HANDLE_DFS, {"HANDLE_DFS"}}, + + {NL80211_ATTR_SUPPORT_5_MHZ, {"SUPPORT_5_MHZ"}}, + {NL80211_ATTR_SUPPORT_10_MHZ, {"SUPPORT_10_MHZ"}}, + + {NL80211_ATTR_OPMODE_NOTIF, {"OPMODE_NOTIF"}}, + + {NL80211_ATTR_VENDOR_ID, {"VENDOR_ID"}}, + {NL80211_ATTR_VENDOR_SUBCMD, {"VENDOR_SUBCMD"}}, + {NL80211_ATTR_VENDOR_DATA, {"VENDOR_DATA", DataType::Raw, AttributeMap{}, Flags::Verbose}}, + {NL80211_ATTR_VENDOR_EVENTS, {"VENDOR_EVENTS", DataType::Nested, AttributeMap{}, + Flags::Verbose}}, + + {NL80211_ATTR_QOS_MAP, {"QOS_MAP"}}, + + {NL80211_ATTR_MAC_HINT, {"MAC_HINT"}}, + {NL80211_ATTR_WIPHY_FREQ_HINT, {"WIPHY_FREQ_HINT"}}, + + {NL80211_ATTR_MAX_AP_ASSOC_STA, {"MAX_AP_ASSOC_STA"}}, + + {NL80211_ATTR_TDLS_PEER_CAPABILITY, {"TDLS_PEER_CAPABILITY"}}, + + {NL80211_ATTR_SOCKET_OWNER, {"SOCKET_OWNER"}}, + + {NL80211_ATTR_CSA_C_OFFSETS_TX, {"CSA_C_OFFSETS_TX"}}, + {NL80211_ATTR_MAX_CSA_COUNTERS, {"MAX_CSA_COUNTERS"}}, + + {NL80211_ATTR_TDLS_INITIATOR, {"TDLS_INITIATOR"}}, + + {NL80211_ATTR_USE_RRM, {"USE_RRM"}}, + + {NL80211_ATTR_WIPHY_DYN_ACK, {"WIPHY_DYN_ACK"}}, + + {NL80211_ATTR_TSID, {"TSID"}}, + {NL80211_ATTR_USER_PRIO, {"USER_PRIO"}}, + {NL80211_ATTR_ADMITTED_TIME, {"ADMITTED_TIME"}}, + + {NL80211_ATTR_SMPS_MODE, {"SMPS_MODE"}}, + + {NL80211_ATTR_OPER_CLASS, {"OPER_CLASS"}}, + + {NL80211_ATTR_MAC_MASK, {"MAC_MASK"}}, + + {NL80211_ATTR_WIPHY_SELF_MANAGED_REG, {"WIPHY_SELF_MANAGED_REG"}}, + + {NL80211_ATTR_EXT_FEATURES, {"EXT_FEATURES"}}, + + {NL80211_ATTR_SURVEY_RADIO_STATS, {"SURVEY_RADIO_STATS"}}, + + {NL80211_ATTR_NETNS_FD, {"NETNS_FD"}}, + + {NL80211_ATTR_SCHED_SCAN_DELAY, {"SCHED_SCAN_DELAY"}}, + + {NL80211_ATTR_REG_INDOOR, {"REG_INDOOR"}}, + + {NL80211_ATTR_MAX_NUM_SCHED_SCAN_PLANS, {"MAX_NUM_SCHED_SCAN_PLANS", DataType::Uint}}, + {NL80211_ATTR_MAX_SCAN_PLAN_INTERVAL, {"MAX_SCAN_PLAN_INTERVAL", DataType::Uint}}, + {NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS, {"MAX_SCAN_PLAN_ITERATIONS", DataType::Uint}}, + {NL80211_ATTR_SCHED_SCAN_PLANS, {"SCHED_SCAN_PLANS"}}, + + {NL80211_ATTR_PBSS, {"PBSS"}}, + + {NL80211_ATTR_BSS_SELECT, {"BSS_SELECT"}}, + + {NL80211_ATTR_STA_SUPPORT_P2P_PS, {"STA_SUPPORT_P2P_PS"}}, + + {NL80211_ATTR_PAD, {"PAD"}}, + + {NL80211_ATTR_IFTYPE_EXT_CAPA, {"IFTYPE_EXT_CAPA"}}, + + {NL80211_ATTR_MU_MIMO_GROUP_DATA, {"MU_MIMO_GROUP_DATA"}}, + {NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR, {"MU_MIMO_FOLLOW_MAC_ADDR"}}, + + {NL80211_ATTR_SCAN_START_TIME_TSF, {"SCAN_START_TIME_TSF"}}, + {NL80211_ATTR_SCAN_START_TIME_TSF_BSSID, {"SCAN_START_TIME_TSF_BSSID"}}, + {NL80211_ATTR_MEASUREMENT_DURATION, {"MEASUREMENT_DURATION"}}, + {NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY, {"MEASUREMENT_DURATION_MANDATORY"}}, + + {NL80211_ATTR_MESH_PEER_AID, {"MESH_PEER_AID"}}, + + {NL80211_ATTR_NAN_MASTER_PREF, {"NAN_MASTER_PREF"}}, + {NL80211_ATTR_BANDS, {"BANDS"}}, + {NL80211_ATTR_NAN_FUNC, {"NAN_FUNC"}}, + {NL80211_ATTR_NAN_MATCH, {"NAN_MATCH"}}, + + {NL80211_ATTR_FILS_KEK, {"FILS_KEK"}}, + {NL80211_ATTR_FILS_NONCES, {"FILS_NONCES"}}, + + {NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED, {"MULTICAST_TO_UNICAST_ENABLED"}}, + + {NL80211_ATTR_BSSID, {"BSSID"}}, + + {NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI, {"SCHED_SCAN_RELATIVE_RSSI"}}, + {NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST, {"SCHED_SCAN_RSSI_ADJUST"}}, + + {NL80211_ATTR_TIMEOUT_REASON, {"TIMEOUT_REASON"}}, + + {NL80211_ATTR_FILS_ERP_USERNAME, {"FILS_ERP_USERNAME"}}, + {NL80211_ATTR_FILS_ERP_REALM, {"FILS_ERP_REALM"}}, + {NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM, {"FILS_ERP_NEXT_SEQ_NUM"}}, + {NL80211_ATTR_FILS_ERP_RRK, {"FILS_ERP_RRK"}}, + {NL80211_ATTR_FILS_CACHE_ID, {"FILS_CACHE_ID"}}, + + {NL80211_ATTR_PMK, {"PMK"}}, + + {NL80211_ATTR_SCHED_SCAN_MULTI, {"SCHED_SCAN_MULTI"}}, + {NL80211_ATTR_SCHED_SCAN_MAX_REQS, {"SCHED_SCAN_MAX_REQS"}}, + + {NL80211_ATTR_WANT_1X_4WAY_HS, {"WANT_1X_4WAY_HS"}}, + {NL80211_ATTR_PMKR0_NAME, {"PMKR0_NAME"}}, + {NL80211_ATTR_PORT_AUTHORIZED, {"PORT_AUTHORIZED"}}, + + {NL80211_ATTR_EXTERNAL_AUTH_ACTION, {"EXTERNAL_AUTH_ACTION"}}, + {NL80211_ATTR_EXTERNAL_AUTH_SUPPORT, {"EXTERNAL_AUTH_SUPPORT"}}, + + {NL80211_ATTR_NSS, {"NSS"}}, + {NL80211_ATTR_ACK_SIGNAL, {"ACK_SIGNAL"}}, + + {NL80211_ATTR_CONTROL_PORT_OVER_NL80211, {"CONTROL_PORT_OVER_NL80211"}}, + + {NL80211_ATTR_TXQ_STATS, {"TXQ_STATS"}}, + {NL80211_ATTR_TXQ_LIMIT, {"TXQ_LIMIT"}}, + {NL80211_ATTR_TXQ_MEMORY_LIMIT, {"TXQ_MEMORY_LIMIT"}}, + {NL80211_ATTR_TXQ_QUANTUM, {"TXQ_QUANTUM"}}, + + {NL80211_ATTR_HE_CAPABILITY, {"HE_CAPABILITY"}}, + + {NL80211_ATTR_FTM_RESPONDER, {"FTM_RESPONDER"}}, + + {NL80211_ATTR_FTM_RESPONDER_STATS, {"FTM_RESPONDER_STATS"}}, + + {NL80211_ATTR_TIMEOUT, {"TIMEOUT"}}, + + {NL80211_ATTR_PEER_MEASUREMENTS, {"PEER_MEASUREMENTS"}}, + + {NL80211_ATTR_AIRTIME_WEIGHT, {"AIRTIME_WEIGHT"}}, + {NL80211_ATTR_STA_TX_POWER_SETTING, {"STA_TX_POWER_SETTING"}}, + {NL80211_ATTR_STA_TX_POWER, {"STA_TX_POWER"}}, + + {NL80211_ATTR_SAE_PASSWORD, {"SAE_PASSWORD"}}, + + {NL80211_ATTR_TWT_RESPONDER, {"TWT_RESPONDER"}}, + + {NL80211_ATTR_HE_OBSS_PD, {"HE_OBSS_PD"}}, + + {NL80211_ATTR_WIPHY_EDMG_CHANNELS, {"WIPHY_EDMG_CHANNELS"}}, + {NL80211_ATTR_WIPHY_EDMG_BW_CONFIG, {"WIPHY_EDMG_BW_CONFIG"}}, + + {NL80211_ATTR_VLAN_ID, {"VLAN_ID"}}, + + {NL80211_ATTR_HE_BSS_COLOR, {"HE_BSS_COLOR"}}, + + {NL80211_ATTR_IFTYPE_AKM_SUITES, {"IFTYPE_AKM_SUITES"}}, + + {NL80211_ATTR_TID_CONFIG, {"TID_CONFIG"}}, + + {NL80211_ATTR_CONTROL_PORT_NO_PREAUTH, {"CONTROL_PORT_NO_PREAUTH"}}, + + {NL80211_ATTR_PMK_LIFETIME, {"PMK_LIFETIME"}}, + {NL80211_ATTR_PMK_REAUTH_THRESHOLD, {"PMK_REAUTH_THRESHOLD"}}, + + {NL80211_ATTR_RECEIVE_MULTICAST, {"RECEIVE_MULTICAST"}}, + {NL80211_ATTR_WIPHY_FREQ_OFFSET, {"WIPHY_FREQ_OFFSET"}}, + {NL80211_ATTR_CENTER_FREQ1_OFFSET, {"CENTER_FREQ1_OFFSET"}}, + {NL80211_ATTR_SCAN_FREQ_KHZ, {"SCAN_FREQ_KHZ"}}, + + {NL80211_ATTR_HE_6GHZ_CAPABILITY, {"HE_6GHZ_CAPABILITY"}}, + + {NL80211_ATTR_FILS_DISCOVERY, {"FILS_DISCOVERY"}}, + + {NL80211_ATTR_UNSOL_BCAST_PROBE_RESP, {"UNSOL_BCAST_PROBE_RESP"}}, + + {NL80211_ATTR_S1G_CAPABILITY, {"S1G_CAPABILITY"}}, + {NL80211_ATTR_S1G_CAPABILITY_MASK, {"S1G_CAPABILITY_MASK"}}, +}) {} +// clang-format on + +static void informationElementsToStream(std::stringstream& ss, const Buffer attr) { + struct IEHeader { + uint8_t elementId; + uint8_t length; + } __attribute__((packed)); + static_assert(sizeof(IEHeader) == 2); + + const auto alldata = attr.data(); + const auto bytes = alldata.getRaw(); + + ss << '{'; + + if constexpr (kCompactIE) { + ss << "len=" << bytes.len() << ", "; + ss << "crc=" << std::hex << std::setw(4) << crc16(alldata) << std::dec << ", "; + } + + bool first = true; + auto printComma = [&first, &ss]() { + // put separator at every but first entry + if (!first) ss << ", "; + first = false; + }; + + for (size_t offset = 0; offset < bytes.len();) { + const auto ptr = bytes.ptr() + offset; + const auto remainingLen = bytes.len() - offset; + + // can we fit one more header? + if (sizeof(IEHeader) > remainingLen) break; + IEHeader ieHeader; + memcpy(&ieHeader, ptr, sizeof(IEHeader)); + if (sizeof(IEHeader) + ieHeader.length > remainingLen) { + printComma(); + ss << "ERR"; + break; + } + offset += sizeof(IEHeader) + ieHeader.length; + + const Buffer data(ptr + sizeof(IEHeader), ieHeader.length); + + if (ieHeader.elementId == WLAN_EID_SSID) { + printComma(); + + const auto str = data.getRaw(); + const std::string ssid(reinterpret_cast(str.ptr()), str.len()); + ss << "SSID=\"" << printableOnly(ssid) << '"'; + + continue; + } + + if constexpr (kCompactIE) continue; + + // print entry ID:LENGTH/CRC16 + printComma(); + ss << (int)ieHeader.elementId << ':' << (int)ieHeader.length << '/'; + ss << std::hex << std::setw(4) << crc16(data) << std::dec; + } + ss << '}'; +} + +static void nl80211_pattern_supportToStream(std::stringstream& ss, const Buffer attr) { + const auto& [ok, data] = attr.data().getFirst(); + if (!ok) { + ss << "invalid structure"; + return; + } + ss << '{' // + << data.max_patterns << ',' // + << data.min_pattern_len << ',' // + << data.max_pattern_len << ',' // + << data.max_pkt_offset << '}'; +} + +} // namespace android::nl::protocols::generic::families diff --git a/automotive/can/1.0/default/libnl++/protocols/generic/families/Nl80211.h b/automotive/can/1.0/default/libnl++/protocols/generic/families/Nl80211.h new file mode 100644 index 0000000000..8a9608cde6 --- /dev/null +++ b/automotive/can/1.0/default/libnl++/protocols/generic/families/Nl80211.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "../GenericMessageBase.h" + +namespace android::nl::protocols::generic::families { + +class Nl80211 : public GenericMessageBase { + public: + Nl80211(nlmsgtype_t familyId); +}; + +} // namespace android::nl::protocols::generic::families diff --git a/automotive/can/1.0/default/libnl++/protocols/route/Link.cpp b/automotive/can/1.0/default/libnl++/protocols/route/Link.cpp index 7db487ae39..9cc05da027 100644 --- a/automotive/can/1.0/default/libnl++/protocols/route/Link.cpp +++ b/automotive/can/1.0/default/libnl++/protocols/route/Link.cpp @@ -16,6 +16,7 @@ #include "Link.h" +#include "../structs.h" #include "structs.h" #include @@ -26,9 +27,9 @@ using DataType = AttributeDefinition::DataType; // clang-format off Link::Link() : MessageDefinition("link", { - {RTM_NEWLINK, {"NEWLINK", MessageGenre::NEW}}, - {RTM_DELLINK, {"DELLINK", MessageGenre::DELETE}}, - {RTM_GETLINK, {"GETLINK", MessageGenre::GET}}, + {RTM_NEWLINK, {"NEWLINK", MessageGenre::New}}, + {RTM_DELLINK, {"DELLINK", MessageGenre::Delete}}, + {RTM_GETLINK, {"GETLINK", MessageGenre::Get}}, }, { {IFLA_ADDRESS, {"ADDRESS"}}, {IFLA_BROADCAST, {"BROADCAST"}}, diff --git a/automotive/can/1.0/default/libnl++/protocols/route/structs.h b/automotive/can/1.0/default/libnl++/protocols/route/structs.h index b9d622a739..fea2ce130c 100644 --- a/automotive/can/1.0/default/libnl++/protocols/route/structs.h +++ b/automotive/can/1.0/default/libnl++/protocols/route/structs.h @@ -30,16 +30,6 @@ void mapToStream(std::stringstream& ss, const Buffer attr); // ifla_cacheinfo void ifla_cacheinfoToStream(std::stringstream& ss, const Buffer attr); -template -void arrayToStream(std::stringstream& ss, const Buffer attr) { - ss << '{'; - for (const auto it : attr.data().getRaw()) { - ss << it << ','; - } - ss.seekp(-1, std::ios_base::cur); - ss << '}'; -} - // rtnl_link_stats or rtnl_link_stats64 template void statsToStream(std::stringstream& ss, const Buffer attr) { diff --git a/automotive/can/1.0/default/libnl++/protocols/structs.h b/automotive/can/1.0/default/libnl++/protocols/structs.h new file mode 100644 index 0000000000..44c17b84b9 --- /dev/null +++ b/automotive/can/1.0/default/libnl++/protocols/structs.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +namespace android::nl::protocols { + +template +void arrayToStream(std::stringstream& ss, const Buffer attr) { + ss << '{'; + for (const auto it : attr.data().getRaw()) { + ss << it << ','; + } + ss.seekp(-1, std::ios_base::cur); + ss << '}'; +} + +} // namespace android::nl::protocols -- GitLab From 9ab672581572fc1007021a02e414438868e160f0 Mon Sep 17 00:00:00 2001 From: Tomasz Wasilczyk Date: Thu, 3 Dec 2020 09:45:44 -0800 Subject: [PATCH 318/790] Print error names instead of numbers Bug: 173144731 Test: logcat Change-Id: I56edff813d400cd839d5604e32f2a8c782199cb5 --- .../libnl++/protocols/common/Error.cpp | 153 +++++++++++++++++- 1 file changed, 151 insertions(+), 2 deletions(-) diff --git a/automotive/can/1.0/default/libnl++/protocols/common/Error.cpp b/automotive/can/1.0/default/libnl++/protocols/common/Error.cpp index 47a989609a..77451edbeb 100644 --- a/automotive/can/1.0/default/libnl++/protocols/common/Error.cpp +++ b/automotive/can/1.0/default/libnl++/protocols/common/Error.cpp @@ -20,6 +20,8 @@ #include +#include + namespace android::nl::protocols::base { using DataType = AttributeDefinition::DataType; @@ -34,9 +36,156 @@ Error::Error(int protocol) : MessageDefinition("nlmsg", { }), mProtocol(protocol) {} // clang-format on +std::map errnoNames{ + {EPERM, "EPERM"}, // Operation not permitted + {ENOENT, "ENOENT"}, // No such file or directory + {ESRCH, "ESRCH"}, // No such process + {EINTR, "EINTR"}, // Interrupted system call + {EIO, "EIO"}, // I/O error + {ENXIO, "ENXIO"}, // No such device or address + {E2BIG, "E2BIG"}, // Argument list too long + {ENOEXEC, "ENOEXEC"}, // Exec format error + {EBADF, "EBADF"}, // Bad file number + {ECHILD, "ECHILD"}, // No child processes + {EAGAIN, "EAGAIN"}, // Try again + {ENOMEM, "ENOMEM"}, // Out of memory + {EACCES, "EACCES"}, // Permission denied + {EFAULT, "EFAULT"}, // Bad address + {ENOTBLK, "ENOTBLK"}, // Block device required + {EBUSY, "EBUSY"}, // Device or resource busy + {EEXIST, "EEXIST"}, // File exists + {EXDEV, "EXDEV"}, // Cross-device link + {ENODEV, "ENODEV"}, // No such device + {ENOTDIR, "ENOTDIR"}, // Not a directory + {EISDIR, "EISDIR"}, // Is a directory + {EINVAL, "EINVAL"}, // Invalid argument + {ENFILE, "ENFILE"}, // File table overflow + {EMFILE, "EMFILE"}, // Too many open files + {ENOTTY, "ENOTTY"}, // Not a typewriter + {ETXTBSY, "ETXTBSY"}, // Text file busy + {EFBIG, "EFBIG"}, // File too large + {ENOSPC, "ENOSPC"}, // No space left on device + {ESPIPE, "ESPIPE"}, // Illegal seek + {EROFS, "EROFS"}, // Read-only file system + {EMLINK, "EMLINK"}, // Too many links + {EPIPE, "EPIPE"}, // Broken pipe + {EDOM, "EDOM"}, // Math argument out of domain of func + {ERANGE, "ERANGE"}, // Math result not representable + {EDEADLK, "EDEADLK"}, // Resource deadlock would occur + {ENAMETOOLONG, "ENAMETOOLONG"}, // File name too long + {ENOLCK, "ENOLCK"}, // No record locks available + {ENOSYS, "ENOSYS"}, // Invalid system call number + {ENOTEMPTY, "ENOTEMPTY"}, // Directory not empty + {ELOOP, "ELOOP"}, // Too many symbolic links encountered + {ENOMSG, "ENOMSG"}, // No message of desired type + {EIDRM, "EIDRM"}, // Identifier removed + {ECHRNG, "ECHRNG"}, // Channel number out of range + {EL2NSYNC, "EL2NSYNC"}, // Level 2 not synchronized + {EL3HLT, "EL3HLT"}, // Level 3 halted + {EL3RST, "EL3RST"}, // Level 3 reset + {ELNRNG, "ELNRNG"}, // Link number out of range + {EUNATCH, "EUNATCH"}, // Protocol driver not attached + {ENOCSI, "ENOCSI"}, // No CSI structure available + {EL2HLT, "EL2HLT"}, // Level 2 halted + {EBADE, "EBADE"}, // Invalid exchange + {EBADR, "EBADR"}, // Invalid request descriptor + {EXFULL, "EXFULL"}, // Exchange full + {ENOANO, "ENOANO"}, // No anode + {EBADRQC, "EBADRQC"}, // Invalid request code + {EBADSLT, "EBADSLT"}, // Invalid slot + {EBFONT, "EBFONT"}, // Bad font file format + {ENOSTR, "ENOSTR"}, // Device not a stream + {ENODATA, "ENODATA"}, // No data available + {ETIME, "ETIME"}, // Timer expired + {ENOSR, "ENOSR"}, // Out of streams resources + {ENONET, "ENONET"}, // Machine is not on the network + {ENOPKG, "ENOPKG"}, // Package not installed + {EREMOTE, "EREMOTE"}, // Object is remote + {ENOLINK, "ENOLINK"}, // Link has been severed + {EADV, "EADV"}, // Advertise error + {ESRMNT, "ESRMNT"}, // Srmount error + {ECOMM, "ECOMM"}, // Communication error on send + {EPROTO, "EPROTO"}, // Protocol error + {EMULTIHOP, "EMULTIHOP"}, // Multihop attempted + {EDOTDOT, "EDOTDOT"}, // RFS specific error + {EBADMSG, "EBADMSG"}, // Not a data message + {EOVERFLOW, "EOVERFLOW"}, // Value too large for defined data type + {ENOTUNIQ, "ENOTUNIQ"}, // Name not unique on network + {EBADFD, "EBADFD"}, // File descriptor in bad state + {EREMCHG, "EREMCHG"}, // Remote address changed + {ELIBACC, "ELIBACC"}, // Can not access a needed shared library + {ELIBBAD, "ELIBBAD"}, // Accessing a corrupted shared library + {ELIBSCN, "ELIBSCN"}, // .lib section in a.out corrupted + {ELIBMAX, "ELIBMAX"}, // Attempting to link in too many shared libraries + {ELIBEXEC, "ELIBEXEC"}, // Cannot exec a shared library directly + {EILSEQ, "EILSEQ"}, // Illegal byte sequence + {ERESTART, "ERESTART"}, // Interrupted system call should be restarted + {ESTRPIPE, "ESTRPIPE"}, // Streams pipe error + {EUSERS, "EUSERS"}, // Too many users + {ENOTSOCK, "ENOTSOCK"}, // Socket operation on non-socket + {EDESTADDRREQ, "EDESTADDRREQ"}, // Destination address required + {EMSGSIZE, "EMSGSIZE"}, // Message too long + {EPROTOTYPE, "EPROTOTYPE"}, // Protocol wrong type for socket + {ENOPROTOOPT, "ENOPROTOOPT"}, // Protocol not available + {EPROTONOSUPPORT, "EPROTONOSUPPORT"}, // Protocol not supported + {ESOCKTNOSUPPORT, "ESOCKTNOSUPPORT"}, // Socket type not supported + {EOPNOTSUPP, "EOPNOTSUPP"}, // Operation not supported on transport endpoint + {EPFNOSUPPORT, "EPFNOSUPPORT"}, // Protocol family not supported + {EAFNOSUPPORT, "EAFNOSUPPORT"}, // Address family not supported by protocol + {EADDRINUSE, "EADDRINUSE"}, // Address already in use + {EADDRNOTAVAIL, "EADDRNOTAVAIL"}, // Cannot assign requested address + {ENETDOWN, "ENETDOWN"}, // Network is down + {ENETUNREACH, "ENETUNREACH"}, // Network is unreachable + {ENETRESET, "ENETRESET"}, // Network dropped connection because of reset + {ECONNABORTED, "ECONNABORTED"}, // Software caused connection abort + {ECONNRESET, "ECONNRESET"}, // Connection reset by peer + {ENOBUFS, "ENOBUFS"}, // No buffer space available + {EISCONN, "EISCONN"}, // Transport endpoint is already connected + {ENOTCONN, "ENOTCONN"}, // Transport endpoint is not connected + {ESHUTDOWN, "ESHUTDOWN"}, // Cannot send after transport endpoint shutdown + {ETOOMANYREFS, "ETOOMANYREFS"}, // Too many references: cannot splice + {ETIMEDOUT, "ETIMEDOUT"}, // Connection timed out + {ECONNREFUSED, "ECONNREFUSED"}, // Connection refused + {EHOSTDOWN, "EHOSTDOWN"}, // Host is down + {EHOSTUNREACH, "EHOSTUNREACH"}, // No route to host + {EALREADY, "EALREADY"}, // Operation already in progress + {EINPROGRESS, "EINPROGRESS"}, // Operation now in progress + {ESTALE, "ESTALE"}, // Stale file handle + {EUCLEAN, "EUCLEAN"}, // Structure needs cleaning + {ENOTNAM, "ENOTNAM"}, // Not a XENIX named type file + {ENAVAIL, "ENAVAIL"}, // No XENIX semaphores available + {EISNAM, "EISNAM"}, // Is a named type file + {EREMOTEIO, "EREMOTEIO"}, // Remote I/O error + {EDQUOT, "EDQUOT"}, // Quota exceeded + {ENOMEDIUM, "ENOMEDIUM"}, // No medium found + {EMEDIUMTYPE, "EMEDIUMTYPE"}, // Wrong medium type + {ECANCELED, "ECANCELED"}, // Operation Canceled + {ENOKEY, "ENOKEY"}, // Required key not available + {EKEYEXPIRED, "EKEYEXPIRED"}, // Key has expired + {EKEYREVOKED, "EKEYREVOKED"}, // Key has been revoked + {EKEYREJECTED, "EKEYREJECTED"}, // Key was rejected by service + {EOWNERDEAD, "EOWNERDEAD"}, // Owner died + {ENOTRECOVERABLE, "ENOTRECOVERABLE"}, // State not recoverable + {ERFKILL, "ERFKILL"}, // Operation not possible due to RF-kill + {EHWPOISON, "EHWPOISON"}, // Memory page has hardware error + + // Duplicates: EWOULDBLOCK (Operation would block), EDEADLOCK +}; + void Error::toStream(std::stringstream& ss, const nlmsgerr& data) const { - ss << "nlmsgerr{error=" << data.error - << ", msg=" << toString({&data.msg, sizeof(data.msg)}, mProtocol, false) << "}"; + ss << "nlmsgerr{"; + if (data.error == 0) { + ss << "ACK"; + } else { + ss << "error="; + const auto nameIt = errnoNames.find(-data.error); + if (nameIt == errnoNames.end()) { + ss << data.error; + } else { + ss << nameIt->second; + } + } + ss << ", msg=" << toString({&data.msg, sizeof(data.msg)}, mProtocol, false) << "}"; } } // namespace android::nl::protocols::base -- GitLab From 0483230c2c9d2bc5f5f252e6f03513308077dd25 Mon Sep 17 00:00:00 2001 From: Yu-Han Yang Date: Fri, 20 Nov 2020 09:51:18 -0800 Subject: [PATCH 319/790] Add GnssMeasurement AIDL HAL BYPASS_INCLUSIVE_LANGUAGE_REASON=refactoring Bug: 173797017 Test: on cuttlefish Change-Id: I21de890f1064d761d7ddd1cd73e57396c1974c81 --- gnss/1.1/default/Android.bp | 1 + gnss/2.0/default/Android.bp | 5 +- gnss/2.1/default/Android.bp | 1 + gnss/2.1/vts/functional/gnss_hal_test.h | 5 +- .../vts/functional/gnss_hal_test_cases.cpp | 3 + gnss/3.0/default/Android.bp | 1 + gnss/3.0/vts/functional/gnss_hal_test.h | 5 +- .../hardware/gnss/ElapsedRealtime.aidl | 2 + .../android/hardware/gnss/GnssClock.aidl | 39 ++ .../android/hardware/gnss/GnssData.aidl | 24 + .../hardware/gnss/GnssMeasurement.aidl | 79 +++ .../hardware/gnss/GnssMultipathIndicator.aidl | 24 + .../android/hardware/gnss/GnssSignalType.aidl | 40 ++ .../current/android/hardware/gnss/IGnss.aidl | 3 +- .../gnss/IGnssMeasurementCallback.aidl | 22 + .../gnss/IGnssMeasurementInterface.aidl | 23 + .../hardware/gnss/ElapsedRealtime.aidl | 10 +- .../aidl/android/hardware/gnss/GnssClock.aidl | 203 ++++++ gnss/aidl/android/hardware/gnss/GnssData.aidl | 44 ++ .../hardware/gnss/GnssMeasurement.aidl | 634 ++++++++++++++++++ .../hardware/gnss/GnssMultipathIndicator.aidl | 32 + .../android/hardware/gnss/GnssSignalType.aidl | 149 ++++ gnss/aidl/android/hardware/gnss/IGnss.aidl | 26 +- .../gnss/IGnssMeasurementCallback.aidl | 32 + .../gnss/IGnssMeasurementInterface.aidl | 55 ++ gnss/aidl/default/Android.bp | 1 + gnss/aidl/default/Gnss.cpp | 9 + gnss/aidl/default/Gnss.h | 3 + gnss/aidl/default/GnssConfiguration.h | 5 +- gnss/aidl/default/GnssHidlHal.cpp | 7 +- gnss/aidl/default/GnssHidlHal.h | 12 +- .../aidl/default/GnssMeasurementInterface.cpp | 90 +++ gnss/aidl/default/GnssMeasurementInterface.h | 51 ++ gnss/aidl/default/GnssPowerIndication.cpp | 8 +- gnss/aidl/vts/Android.bp | 1 + gnss/aidl/vts/GnssMeasurementCallbackAidl.cpp | 35 + gnss/aidl/vts/GnssMeasurementCallbackAidl.h | 33 + gnss/aidl/vts/GnssPowerIndicationCallback.h | 4 - gnss/aidl/vts/gnss_hal_test.h | 2 +- gnss/aidl/vts/gnss_hal_test_cases.cpp | 69 +- gnss/common/utils/default/Android.bp | 1 + gnss/common/utils/default/Utils.cpp | 63 +- .../utils/default/include/NmeaFixInfo.h | 5 - gnss/common/utils/default/include/Utils.h | 33 +- .../default/include/v2_1/GnssAntennaInfo.h | 16 +- .../default/include/v2_1/GnssConfiguration.h | 30 +- .../utils/default/include/v2_1/GnssDebug.h | 9 +- .../default/include/v2_1/GnssMeasurement.h | 15 +- .../include/v2_1/GnssMeasurementCorrections.h | 3 - .../utils/default/include/v2_1/GnssTemplate.h | 39 +- .../utils/default/v2_1/GnssConfiguration.cpp | 5 +- .../utils/default/v2_1/GnssMeasurement.cpp | 4 +- .../vts/include/v2_1/gnss_hal_test_template.h | 83 +-- 53 files changed, 1897 insertions(+), 201 deletions(-) create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssClock.aidl create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssData.aidl create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMeasurement.aidl create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMultipathIndicator.aidl create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssSignalType.aidl create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementCallback.aidl create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementInterface.aidl create mode 100644 gnss/aidl/android/hardware/gnss/GnssClock.aidl create mode 100644 gnss/aidl/android/hardware/gnss/GnssData.aidl create mode 100644 gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl create mode 100644 gnss/aidl/android/hardware/gnss/GnssMultipathIndicator.aidl create mode 100644 gnss/aidl/android/hardware/gnss/GnssSignalType.aidl create mode 100644 gnss/aidl/android/hardware/gnss/IGnssMeasurementCallback.aidl create mode 100644 gnss/aidl/android/hardware/gnss/IGnssMeasurementInterface.aidl create mode 100644 gnss/aidl/default/GnssMeasurementInterface.cpp create mode 100644 gnss/aidl/default/GnssMeasurementInterface.h create mode 100644 gnss/aidl/vts/GnssMeasurementCallbackAidl.cpp create mode 100644 gnss/aidl/vts/GnssMeasurementCallbackAidl.h diff --git a/gnss/1.1/default/Android.bp b/gnss/1.1/default/Android.bp index 9c498d58a0..ef43a34947 100644 --- a/gnss/1.1/default/Android.bp +++ b/gnss/1.1/default/Android.bp @@ -18,6 +18,7 @@ cc_binary { "android.hardware.gnss@2.0", "android.hardware.gnss@1.1", "android.hardware.gnss@1.0", + "android.hardware.gnss-ndk_platform", ], static_libs: [ "android.hardware.gnss@common-default-lib", diff --git a/gnss/2.0/default/Android.bp b/gnss/2.0/default/Android.bp index 37de55dfe3..7da462f977 100644 --- a/gnss/2.0/default/Android.bp +++ b/gnss/2.0/default/Android.bp @@ -29,7 +29,7 @@ cc_binary { "GnssMeasurement.cpp", "GnssMeasurementCorrections.cpp", "GnssVisibilityControl.cpp", - "service.cpp" + "service.cpp", ], shared_libs: [ "libhidlbase", @@ -39,8 +39,9 @@ cc_binary { "android.hardware.gnss.visibility_control@1.0", "android.hardware.gnss@2.1", "android.hardware.gnss@2.0", - "android.hardware.gnss@1.0", "android.hardware.gnss@1.1", + "android.hardware.gnss@1.0", + "android.hardware.gnss-ndk_platform", ], static_libs: [ "android.hardware.gnss@common-default-lib", diff --git a/gnss/2.1/default/Android.bp b/gnss/2.1/default/Android.bp index 7739f908a7..63e5013276 100644 --- a/gnss/2.1/default/Android.bp +++ b/gnss/2.1/default/Android.bp @@ -34,6 +34,7 @@ cc_binary { "android.hardware.gnss@1.0", "android.hardware.gnss@1.1", "android.hardware.gnss@2.0", + "android.hardware.gnss-ndk_platform", ], static_libs: [ "android.hardware.gnss@common-default-lib", diff --git a/gnss/2.1/vts/functional/gnss_hal_test.h b/gnss/2.1/vts/functional/gnss_hal_test.h index 7950670983..2bcecf4ba2 100644 --- a/gnss/2.1/vts/functional/gnss_hal_test.h +++ b/gnss/2.1/vts/functional/gnss_hal_test.h @@ -19,10 +19,9 @@ #include #include "v2_1/gnss_hal_test_template.h" -using android::hardware::gnss::V2_1::IGnss; - // The main test class for GNSS HAL. -class GnssHalTest : public GnssHalTestTemplate { +class GnssHalTest : public android::hardware::gnss::common::GnssHalTestTemplate< + android::hardware::gnss::V2_1::IGnss> { public: /** * IsGnssHalVersion_2_1: diff --git a/gnss/2.1/vts/functional/gnss_hal_test_cases.cpp b/gnss/2.1/vts/functional/gnss_hal_test_cases.cpp index 7afd49cb86..deb80e8a0b 100644 --- a/gnss/2.1/vts/functional/gnss_hal_test_cases.cpp +++ b/gnss/2.1/vts/functional/gnss_hal_test_cases.cpp @@ -27,6 +27,9 @@ using android::hardware::hidl_vec; using android::hardware::gnss::common::Utils; +using android::hardware::gnss::V2_1::IGnssAntennaInfo; +using android::hardware::gnss::V2_1::IGnssAntennaInfoCallback; + using IGnssMeasurement_2_1 = android::hardware::gnss::V2_1::IGnssMeasurement; using IGnssMeasurement_2_0 = android::hardware::gnss::V2_0::IGnssMeasurement; using IGnssMeasurement_1_1 = android::hardware::gnss::V1_1::IGnssMeasurement; diff --git a/gnss/3.0/default/Android.bp b/gnss/3.0/default/Android.bp index 2b33b32058..bb3c467923 100644 --- a/gnss/3.0/default/Android.bp +++ b/gnss/3.0/default/Android.bp @@ -36,6 +36,7 @@ cc_binary { "android.hardware.gnss@3.0", "android.hardware.gnss.measurement_corrections@1.1", "android.hardware.gnss.measurement_corrections@1.0", + "android.hardware.gnss-ndk_platform", ], static_libs: [ "android.hardware.gnss@common-default-lib", diff --git a/gnss/3.0/vts/functional/gnss_hal_test.h b/gnss/3.0/vts/functional/gnss_hal_test.h index 387214eba2..be6d38cfac 100644 --- a/gnss/3.0/vts/functional/gnss_hal_test.h +++ b/gnss/3.0/vts/functional/gnss_hal_test.h @@ -19,7 +19,6 @@ #include #include "v2_1/gnss_hal_test_template.h" -using android::hardware::gnss::V3_0::IGnss; - // The main test class for GNSS HAL. -class GnssHalTest : public GnssHalTestTemplate {}; \ No newline at end of file +class GnssHalTest : public android::hardware::gnss::common::GnssHalTestTemplate< + android::hardware::gnss::V3_0::IGnss> {}; \ No newline at end of file diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/ElapsedRealtime.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/ElapsedRealtime.aidl index 354c953d77..a0e8de41a3 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/ElapsedRealtime.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/ElapsedRealtime.aidl @@ -21,4 +21,6 @@ parcelable ElapsedRealtime { int flags; long timestampNs; double timeUncertaintyNs; + const int HAS_TIMESTAMP_NS = 1; + const int HAS_TIME_UNCERTAINTY_NS = 2; } diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssClock.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssClock.aidl new file mode 100644 index 0000000000..42b940e886 --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssClock.aidl @@ -0,0 +1,39 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.gnss; +@VintfStability +parcelable GnssClock { + int gnssClockFlags; + int leapSecond; + long timeNs; + double timeUncertaintyNs; + long fullBiasNs; + double biasNs; + double biasUncertaintyNs; + double driftNsps; + double driftUncertaintyNsps; + int hwClockDiscontinuityCount; + android.hardware.gnss.GnssSignalType referenceSignalTypeForIsb; + const int HAS_LEAP_SECOND = 1; + const int HAS_TIME_UNCERTAINTY = 2; + const int HAS_FULL_BIAS = 4; + const int HAS_BIAS = 8; + const int HAS_BIAS_UNCERTAINTY = 16; + const int HAS_DRIFT = 32; + const int HAS_DRIFT_UNCERTAINTY = 64; +} 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 new file mode 100644 index 0000000000..7ffabd2a3c --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssData.aidl @@ -0,0 +1,24 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.gnss; +@VintfStability +parcelable GnssData { + android.hardware.gnss.GnssMeasurement[] measurements; + android.hardware.gnss.GnssClock clock; + android.hardware.gnss.ElapsedRealtime elapsedRealtime; +} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMeasurement.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMeasurement.aidl new file mode 100644 index 0000000000..7d15855b5d --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMeasurement.aidl @@ -0,0 +1,79 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.gnss; +@VintfStability +parcelable GnssMeasurement { + int flags; + int svid; + android.hardware.gnss.GnssSignalType signalType; + double timeOffsetNs; + int state; + long receivedSvTimeInNs; + long receivedSvTimeUncertaintyInNs; + double antennaCN0DbHz; + double basebandCN0DbHz; + double pseudorangeRateMps; + double pseudorangeRateUncertaintyMps; + int accumulatedDeltaRangeState; + double accumulatedDeltaRangeM; + double accumulatedDeltaRangeUncertaintyM; + float carrierFrequencyHz; + long carrierCycles; + double carrierPhase; + double carrierPhaseUncertainty; + android.hardware.gnss.GnssMultipathIndicator multipathIndicator; + double snrDb; + double agcLevelDb; + double fullInterSignalBiasNs; + double fullInterSignalBiasUncertaintyNs; + double satelliteInterSignalBiasNs; + double satelliteInterSignalBiasUncertaintyNs; + const int HAS_SNR = 1; + const int HAS_CARRIER_FREQUENCY = 512; + const int HAS_CARRIER_CYCLES = 1024; + const int HAS_CARRIER_PHASE = 2048; + const int HAS_CARRIER_PHASE_UNCERTAINTY = 4096; + const int HAS_AUTOMATIC_GAIN_CONTROL = 8192; + const int HAS_FULL_ISB = 65536; + const int HAS_FULL_ISB_UNCERTAINTY = 131072; + const int HAS_SATELLITE_ISB = 262144; + const int HAS_SATELLITE_ISB_UNCERTAINTY = 524288; + const int STATE_UNKNOWN = 0; + const int STATE_CODE_LOCK = 1; + const int STATE_BIT_SYNC = 2; + const int STATE_SUBFRAME_SYNC = 4; + const int STATE_TOW_DECODED = 8; + const int STATE_MSEC_AMBIGUOUS = 16; + const int STATE_SYMBOL_SYNC = 32; + const int STATE_GLO_STRING_SYNC = 64; + const int STATE_GLO_TOD_DECODED = 128; + const int STATE_BDS_D2_BIT_SYNC = 256; + const int STATE_BDS_D2_SUBFRAME_SYNC = 512; + const int STATE_GAL_E1BC_CODE_LOCK = 1024; + const int STATE_GAL_E1C_2ND_CODE_LOCK = 2048; + const int STATE_GAL_E1B_PAGE_SYNC = 4096; + const int STATE_SBAS_SYNC = 8192; + const int STATE_TOW_KNOWN = 16384; + const int STATE_GLO_TOD_KNOWN = 32768; + const int STATE_2ND_CODE_LOCK = 65536; + const int ADR_STATE_UNKNOWN = 0; + const int ADR_STATE_VALID = 1; + const int ADR_STATE_RESET = 2; + const int ADR_STATE_CYCLE_SLIP = 4; + const int ADR_STATE_HALF_CYCLE_RESOLVED = 8; +} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMultipathIndicator.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMultipathIndicator.aidl new file mode 100644 index 0000000000..75ca3afbc3 --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMultipathIndicator.aidl @@ -0,0 +1,24 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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; +@Backing(type="int") @VintfStability +enum GnssMultipathIndicator { + UNKNOWN = 0, + PRESENT = 1, + NOT_PRESENT = 2, +} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssSignalType.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssSignalType.aidl new file mode 100644 index 0000000000..3e66c4a73c --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssSignalType.aidl @@ -0,0 +1,40 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.gnss; +@VintfStability +parcelable GnssSignalType { + android.hardware.gnss.GnssConstellationType constellation; + double carrierFrequencyHz; + String codeType; + const String CODE_TYPE_A = "A"; + const String CODE_TYPE_B = "B"; + const String CODE_TYPE_C = "C"; + const String CODE_TYPE_D = "D"; + const String CODE_TYPE_I = "I"; + const String CODE_TYPE_L = "L"; + const String CODE_TYPE_M = "M"; + const String CODE_TYPE_N = "N"; + const String CODE_TYPE_P = "P"; + const String CODE_TYPE_Q = "Q"; + const String CODE_TYPE_S = "S"; + const String CODE_TYPE_W = "W"; + const String CODE_TYPE_X = "X"; + const String CODE_TYPE_Y = "Y"; + const String CODE_TYPE_Z = "Z"; + const String CODE_TYPE_UNKNOWN = "UNKNOWN"; +} 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 e1a4b9e99c..10ac150a53 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 @@ -22,8 +22,7 @@ interface IGnss { void close(); android.hardware.gnss.IGnssPsds getExtensionPsds(); android.hardware.gnss.IGnssConfiguration getExtensionGnssConfiguration(); + android.hardware.gnss.IGnssMeasurementInterface getExtensionGnssMeasurement(); android.hardware.gnss.IGnssPowerIndication getExtensionGnssPowerIndication(); const int ERROR_INVALID_ARGUMENT = 1; - const int ELAPSED_REALTIME_HAS_TIMESTAMP_NS = 1; - const int ELAPSED_REALTIME_HAS_TIME_UNCERTAINTY_NS = 2; } diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementCallback.aidl new file mode 100644 index 0000000000..e05e9b9954 --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementCallback.aidl @@ -0,0 +1,22 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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 IGnssMeasurementCallback { + void gnssMeasurementCb(in android.hardware.gnss.GnssData data); +} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementInterface.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementInterface.aidl new file mode 100644 index 0000000000..9576205772 --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementInterface.aidl @@ -0,0 +1,23 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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 IGnssMeasurementInterface { + void setCallback(in android.hardware.gnss.IGnssMeasurementCallback callback, in boolean enableFullTracking); + void close(); +} diff --git a/gnss/aidl/android/hardware/gnss/ElapsedRealtime.aidl b/gnss/aidl/android/hardware/gnss/ElapsedRealtime.aidl index fae14f87a3..67d090eb24 100644 --- a/gnss/aidl/android/hardware/gnss/ElapsedRealtime.aidl +++ b/gnss/aidl/android/hardware/gnss/ElapsedRealtime.aidl @@ -22,10 +22,18 @@ package android.hardware.gnss; @VintfStability parcelable ElapsedRealtime { + /** Bit mask indicating a valid timestampNs is stored in the ElapsedRealtime parcelable. */ + const int HAS_TIMESTAMP_NS = 1 << 0; + + /** + * Bit mask indicating a valid timeUncertaintyNs is stored in the ElapsedRealtime parcelable. + */ + const int HAS_TIME_UNCERTAINTY_NS = 1 << 1; + /** * A bit field of flags indicating the validity of each field in this data structure. * - * The bit masks are defined in IGnss interface and prefixed with ELAPSED_REALTIME_HAS_. + * The bit masks are the constants with prefix HAS_. * * Fields may have invalid information in them, if not marked as valid by the corresponding bit * in flags. diff --git a/gnss/aidl/android/hardware/gnss/GnssClock.aidl b/gnss/aidl/android/hardware/gnss/GnssClock.aidl new file mode 100644 index 0000000000..f416e08e5f --- /dev/null +++ b/gnss/aidl/android/hardware/gnss/GnssClock.aidl @@ -0,0 +1,203 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.gnss; + +import android.hardware.gnss.GnssSignalType; + +/** + * Represents an estimate of the GNSS clock time. + */ +@VintfStability +parcelable GnssClock { + /** Bit mask indicating a valid 'leap second' is stored in the GnssClock. */ + const int HAS_LEAP_SECOND = 1 << 0; + /** Bit mask indicating a valid 'time uncertainty' is stored in the GnssClock. */ + const int HAS_TIME_UNCERTAINTY = 1 << 1; + /** Bit mask indicating a valid 'full bias' is stored in the GnssClock. */ + const int HAS_FULL_BIAS = 1 << 2; + /** Bit mask indicating a valid 'bias' is stored in the GnssClock. */ + const int HAS_BIAS = 1 << 3; + /** Bit mask indicating a valid 'bias uncertainty' is stored in the GnssClock. */ + const int HAS_BIAS_UNCERTAINTY = 1 << 4; + /** Bit mask indicating a valid 'drift' is stored in the GnssClock. */ + const int HAS_DRIFT = 1 << 5; + /** Bit mask indicating a valid 'drift uncertainty' is stored in the GnssClock. */ + const int HAS_DRIFT_UNCERTAINTY = 1 << 6; + + /** + * A bitfield of flags indicating the validity of the fields in this data + * structure. + * + * The bit masks are the constants with perfix HAS_. + * + * Fields for which there is no corresponding flag must be filled in + * with a valid value. For convenience, these are marked as mandatory. + * + * Others fields may have invalid information in them, if not marked as + * valid by the corresponding bit in gnssClockFlags. + */ + int gnssClockFlags; + + /** + * Leap second data. + * The sign of the value is defined by the following equation: + * utcTimeNs = timeNs - (fullBiasNs + biasNs) - leapSecond * + * 1,000,000,000 + * + * If this data is available, gnssClockFlags must contain + * HAS_LEAP_SECOND. + */ + int leapSecond; + + /** + * The GNSS receiver internal clock value. This is the local hardware clock + * value. + * + * For local hardware clock, this value is expected to be monotonically + * increasing while the hardware clock remains powered on. (For the case of a + * HW clock that is not continuously on, see the + * hwClockDiscontinuityCount field). The receiver's estimate of GNSS time + * can be derived by subtracting the sum of fullBiasNs and biasNs (when + * available) from this value. + * + * This GNSS time must be the best estimate of current GNSS time + * that GNSS receiver can achieve. + * + * Sub-nanosecond accuracy can be provided by means of the 'biasNs' field. + * The value contains the timeUncertaintyNs in it. + * + * This value is mandatory. + */ + long timeNs; + + /** + * 1-Sigma uncertainty associated with the clock's time in nanoseconds. + * The uncertainty is represented as an absolute (single sided) value. + * + * If the data is available, gnssClockFlags must contain + * HAS_TIME_UNCERTAINTY. Ths value is ideally zero, as the time + * 'latched' by timeNs is defined as the reference clock vs. which all + * other times (and corresponding uncertainties) are measured. + */ + double timeUncertaintyNs; + + /** + * The difference between hardware clock ('time' field) inside GNSS receiver + * and the true GPS time since 0000Z, January 6, 1980, in nanoseconds. + * + * The sign of the value is defined by the following equation: + * local estimate of GPS time = timeNs - (fullBiasNs + biasNs) + * + * If receiver has computed time for a non-GPS constellation, the time offset of + * that constellation versus GPS time must be applied to fill this value. + * + * The error estimate for the sum of this and the biasNs is the biasUncertaintyNs. + * + * If the data is available gnssClockFlags must contain HAS_FULL_BIAS. + * + * This value is mandatory if the receiver has estimated GPS time. + */ + long fullBiasNs; + + /** + * Sub-nanosecond bias - used with fullBiasNS, see fullBiasNs for details. + * + * The error estimate for the sum of this and the fullBiasNs is the + * biasUncertaintyNs. + * + * If the data is available gnssClockFlags must contain HAS_BIAS. + * + * This value is mandatory if the receiver has estimated GPS time. + */ + double biasNs; + + /** + * 1-Sigma uncertainty associated with the local estimate of GNSS time (clock + * bias) in nanoseconds. The uncertainty is represented as an absolute + * (single sided) value. + * + * The caller is responsible for using this uncertainty (it can be very + * large before the GPS time has been fully resolved.) + * + * If the data is available gnssClockFlags must contain HAS_BIAS_UNCERTAINTY. + * + * This value is mandatory if the receiver has estimated GPS time. + */ + double biasUncertaintyNs; + + /** + * The clock's drift in nanoseconds (per second). + * + * A positive value means that the frequency is higher than the nominal + * frequency, and that the (fullBiasNs + biasNs) is growing more positive + * over time. + * + * If the data is available gnssClockFlags must contain HAS_DRIFT. + * + * This value is mandatory if the receiver has estimated GPS time. + */ + double driftNsps; + + /** + * 1-Sigma uncertainty associated with the clock's drift in nanoseconds (per + * second). + * The uncertainty is represented as an absolute (single sided) value. + * + * If the data is available gnssClockFlags must contain HAS_DRIFT_UNCERTAINTY. + * + * This value is mandatory if the receiver has estimated GPS time. + */ + double driftUncertaintyNsps; + + /** + * This field must be incremented, when there are discontinuities in the + * hardware clock. + * + * A "discontinuity" is meant to cover the case of a switch from one source + * of clock to another. A single free-running crystal oscillator (XO) + * will generally not have any discontinuities, and this can be set and + * left at 0. + * + * If, however, the timeNs value (HW clock) is derived from a composite of + * sources, that is not as smooth as a typical XO, or is otherwise stopped & + * restarted, then this value shall be incremented each time a discontinuity + * occurs. (E.g. this value can start at zero at device boot-up and + * increment each time there is a change in clock continuity. In the + * unlikely event that this value reaches full scale, rollover (not + * clamping) is required, such that this value continues to change, during + * subsequent discontinuity events.) + * + * While this number stays the same, between GnssClock reports, it can be + * safely assumed that the timeNs value has been running continuously, e.g. + * derived from a single, high quality clock (XO like, or better, that is + * typically used during continuous GNSS signal sampling.) + * + * It is expected, esp. during periods where there are few GNSS signals + * available, that the HW clock be discontinuity-free as long as possible, + * as this avoids the need to use (waste) a GNSS measurement to fully + * re-solve for the GNSS clock bias and drift, when using the accompanying + * measurements, from consecutive GnssData reports. + * + * This value is mandatory. + */ + int hwClockDiscontinuityCount; + + /** + * Reference GNSS signal type for inter-signal bias. + */ + GnssSignalType referenceSignalTypeForIsb; +} \ No newline at end of file diff --git a/gnss/aidl/android/hardware/gnss/GnssData.aidl b/gnss/aidl/android/hardware/gnss/GnssData.aidl new file mode 100644 index 0000000000..ed30c989f8 --- /dev/null +++ b/gnss/aidl/android/hardware/gnss/GnssData.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. + */ + +package android.hardware.gnss; + +import android.hardware.gnss.ElapsedRealtime; +import android.hardware.gnss.GnssClock; +import android.hardware.gnss.GnssMeasurement; + +/** + * Represents a reading of GNSS measurements. For devices launched in Android Q or newer, it is + * mandatory that these be provided, on request, when the GNSS receiver is searching/tracking + * signals. + * + * - Reporting of GNSS constellation measurements is mandatory. + * - Reporting of all tracked constellations are encouraged. + */ +@VintfStability +parcelable GnssData { + /** The array of measurements. */ + GnssMeasurement[] measurements; + + /** The GNSS clock time reading. */ + GnssClock clock; + + /** + * Timing information of the GNSS data synchronized with SystemClock.elapsedRealtimeNanos() + * clock. + */ + ElapsedRealtime elapsedRealtime; +} \ No newline at end of file diff --git a/gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl b/gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl new file mode 100644 index 0000000000..fae862b07e --- /dev/null +++ b/gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl @@ -0,0 +1,634 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.gnss; + +import android.hardware.gnss.GnssConstellationType; +import android.hardware.gnss.GnssSignalType; +import android.hardware.gnss.GnssMultipathIndicator; + +/** + * Represents a GNSS Measurement, it contains raw and computed information. + * + * All signal measurement information (e.g. svTime, pseudorangeRate, multipathIndicator) reported in + * this struct must be based on GNSS signal measurements only. You must not synthesize measurements + * by calculating or reporting expected measurements based on known or estimated position, velocity, + * or time. + */ +@VintfStability +parcelable GnssMeasurement { + /** Bit mask indicating a valid 'snr' is stored in the GnssMeasurement. */ + const int HAS_SNR = 1 << 0; + /** Bit mask indicating a valid 'carrier frequency' is stored in the GnssMeasurement. */ + const int HAS_CARRIER_FREQUENCY = 1 << 9; + /** Bit mask indicating a valid 'carrier cycles' is stored in the GnssMeasurement. */ + const int HAS_CARRIER_CYCLES = 1 << 10; + /** Bit mask indicating a valid 'carrier phase' is stored in the GnssMeasurement. */ + const int HAS_CARRIER_PHASE = 1 << 11; + /** Bit mask indicating a valid 'carrier phase uncertainty' is stored in the GnssMeasurement. */ + const int HAS_CARRIER_PHASE_UNCERTAINTY = 1 << 12; + /** Bit mask indicating a valid automatic gain control is stored in the GnssMeasurement. */ + const int HAS_AUTOMATIC_GAIN_CONTROL = 1 << 13; + /** Bit mask indicating a valid full inter-signal bias is stored in the GnssMeasurement. */ + const int HAS_FULL_ISB = 1 << 16; + /** + * Bit mask indicating a valid full inter-signal bias uncertainty is stored in the + * GnssMeasurement. + */ + const int HAS_FULL_ISB_UNCERTAINTY = 1 << 17; + /** + * Bit mask indicating a valid satellite inter-signal bias is stored in the GnssMeasurement. + */ + const int HAS_SATELLITE_ISB = 1 << 18; + /** + * Bit mask indicating a valid satellite inter-signal bias uncertainty is stored in the + * GnssMeasurement. + */ + const int HAS_SATELLITE_ISB_UNCERTAINTY = 1 << 19; + + /** + * A bitfield of flags indicating the validity of the fields in this GnssMeasurement. The bit + * masks are defined in the constants with prefix HAS_* + * + * Fields for which there is no corresponding flag must be filled in with a valid value. For + * convenience, these are marked as mandatory. + * + * Others fields may have invalid information in them, if not marked as valid by the + * corresponding bit in flags. + */ + int flags; + + /** + * Satellite vehicle ID number, as defined in GnssSvInfo::svid + * + * This value is mandatory. + */ + int svid; + + /** + * Defines the constellation of the given SV. + * + * This value is mandatory. + */ + GnssSignalType signalType; + + /** + * Time offset at which the measurement was taken in nanoseconds. + * The reference receiver's time is specified by GnssData::clock::timeNs. + * + * The sign of timeOffsetNs is given by the following equation: + * measurement time = GnssClock::timeNs + timeOffsetNs + * + * It provides an individual time-stamp for the measurement, and allows + * sub-nanosecond accuracy. It may be zero if all measurements are + * aligned to a common time. + * + * This value is mandatory. + */ + double timeOffsetNs; + + /** + * Flags indicating the GNSS measurement state. + * + * The expected behavior here is for GNSS HAL to set all the flags that apply. For example, if + * the state for a satellite is only C/A code locked and bit synchronized, and there is still + * millisecond ambiguity, the state must be set as: + * + * STATE_CODE_LOCK | STATE_BIT_SYNC | STATE_MSEC_AMBIGUOUS + * + * If GNSS is still searching for a satellite, the corresponding state must be set to + * STATE_UNKNOWN(0). + * + * The received satellite time is relative to the beginning of the system week for all + * constellations except for Glonass where it is relative to the beginning of the Glonass system + * day. + * + * The table below indicates the valid range of the received GNSS satellite time. These ranges + * depend on the constellation and code being tracked and the state of the tracking algorithms + * given by the getState method. If the state flag is set, then the valid measurement range is + * zero to the value in the table. The state flag with the widest range indicates the range of + * the received GNSS satellite time value. + * + * +---------------------------+--------------------+-----+-----------+--------------------+------+ + * | |GPS/QZSS |GLNS |BDS |GAL |SBAS | + * +---------------------------+------+------+------+-----+------+----+------+------+------+------+ + * |State Flag |L1 |L5I |L5Q |L1OF |B1I |B1I |E1B |E1C |E5AQ |L1 | + * | |C/A | | | |(D1) |(D2)| | | |C/A | + * |---------------------------+------+------+------+-----+------+----+------+------+------+------+ + * |STATE_UNKNOWN |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 | + * |---------------------------+------+------+------+-----+------+----+------+------+------+------+ + * |STATE_CODE_LOCK |1ms |1 ms |1 ms |1 ms |1 ms |1 ms|- |- |1 ms |1 ms | + * |---------------------------+------+------+------+-----+------+----+------+------+------+------+ + * |STATE_SYMBOL_SYNC |20ms |10 ms |1 ms |10 ms|20 ms |2 ms|4 ms |4 ms |1 ms |2 ms | + * | |(opt.)| |(opt.)| |(opt.)| |(opt.)|(opt.)|(opt.)| | + * |---------------------------+------+------+------+-----+------+----+------+------+------+------+ + * |STATE_BIT_SYNC |20 ms |20 ms |1 ms |20 ms|20 ms |- |8 ms |- |1 ms |4 ms | + * | | | |(opt.)| | | | | |(opt.)| | + * |---------------------------+------+------+------+-----+------+----+------+------+------+------+ + * |STATE_SUBFRAME_SYNC |6s |6s |- |2 s |6 s |- |- |- |100 ms|- | + * |---------------------------+------+------+------+-----+------+----+------+------+------+------+ + * |STATE_TOW_DECODED |1 week|- |- |1 day|1 week|- |1 week|- |- |1 week| + * |---------------------------+------+------+------+-----+------+----+------+------+------+------+ + * |STATE_TOW_KNOWN |1 week|- |- |1 day|1 week|- |1 week|- |- |1 week| + * |---------------------------+------+------+------+-----+------+----+------+------+------+------+ + * |STATE_GLO_STRING_SYNC |- |- |- |2 s |- |- |- |- |- |- | + * |---------------------------+------+------+------+-----+------+----+------+------+------+------+ + * |STATE_GLO_TOD_DECODED |- |- |- |1 day|- |- |- |- |- |- | + * |---------------------------+------+------+------+-----+------+----+------+------+------+------+ + * |STATE_GLO_TOD_KNOWN |- |- |- |1 day|- |- |- |- |- |- | + * |---------------------------+------+------+------+-----+------+----+------+------+------+------+ + * |STATE_BDS_D2_BIT_SYNC |- |- |- |- |- |2 ms|- |- |- |- | + * |---------------------------+------+------+------+-----+------+----+------+------+------+------+ + * |STATE_BDS_D2_SUBFRAME_SYNC |- |- |- |- |- |600 |- |- |- |- | + * | | | | | | |ms | | | | | + * |---------------------------+------+------+------+-----+------+----+------+------+------+------+ + * |STATE_GAL_E1BC_CODE_LOCK |- |- |- |- |- |- |4 ms |4 ms |- |- | + * |---------------------------+------+------+------+-----+------+----+------+------+------+------+ + * |STATE_GAL_E1C_2ND_CODE_LOCK|- |- |- |- |- |- |- |100 ms|- |- | + * |---------------------------+------+------+------+-----+------+----+------+------+------+------+ + * |STATE_2ND_CODE_LOCK |- |10 ms |20 ms |- |- |- |- |100 ms|100 ms|- | + * | | |(opt.)| | | | | |(opt.)| | | + * |---------------------------+------+------+------+-----+------+----+------+------+------+------+ + * |STATE_GAL_E1B_PAGE_SYNC |- |- |- |- |- |- |2 s |- |- |- | + * |---------------------------+------+------+------+-----+------+----+------+------+------+------+ + * |STATE_SBAS_SYNC |- |- |- |- |- |- |- |- |- |1s | + * +---------------------------+------+------+------+-----+------+----+------+------+------+------+ + * + * Note: TOW Known refers to the case where TOW is possibly not decoded over the air but has + * been determined from other sources. If TOW decoded is set then TOW Known must also be set. + * + * Note well: if there is any ambiguity in integer millisecond, STATE_MSEC_AMBIGUOUS must be + * set accordingly, in the 'state' field. This value must be populated if 'state' != + * STATE_UNKNOWN. + * + * Note on optional flags: + * - For L1 C/A and B1I, STATE_SYMBOL_SYNC is optional since the symbol length is the + * same as the bit length. + * - For L5Q and E5aQ, STATE_BIT_SYNC and STATE_SYMBOL_SYNC are optional since they are + * implied by STATE_CODE_LOCK. + * - STATE_2ND_CODE_LOCK for L5I is optional since it is implied by STATE_SYMBOL_SYNC. + * - STATE_2ND_CODE_LOCK for E1C is optional since it is implied by + * STATE_GAL_E1C_2ND_CODE_LOCK. + * - For E1B and E1C, STATE_SYMBOL_SYNC is optional, because it is implied by + * STATE_GAL_E1BC_CODE_LOCK. + */ + const int STATE_UNKNOWN = 0; + const int STATE_CODE_LOCK = 1 << 0; + const int STATE_BIT_SYNC = 1 << 1; + const int STATE_SUBFRAME_SYNC = 1 << 2; + const int STATE_TOW_DECODED = 1 << 3; + const int STATE_MSEC_AMBIGUOUS = 1 << 4; + const int STATE_SYMBOL_SYNC = 1 << 5; + const int STATE_GLO_STRING_SYNC = 1 << 6; + const int STATE_GLO_TOD_DECODED = 1 << 7; + const int STATE_BDS_D2_BIT_SYNC = 1 << 8; + const int STATE_BDS_D2_SUBFRAME_SYNC = 1 << 9; + const int STATE_GAL_E1BC_CODE_LOCK = 1 << 10; + const int STATE_GAL_E1C_2ND_CODE_LOCK = 1 << 11; + const int STATE_GAL_E1B_PAGE_SYNC = 1 << 12; + const int STATE_SBAS_SYNC = 1 << 13; + const int STATE_TOW_KNOWN = 1 << 14; + const int STATE_GLO_TOD_KNOWN = 1 << 15; + const int STATE_2ND_CODE_LOCK = 1 << 16; + + /** + * A bitfield of flags indicating the GnssMeasurementState per satellite sync state. It + * represents the current sync state for the associated satellite. + * + * Based on the sync state, the 'received GNSS tow' field must be interpreted accordingly. + * + * The bit masks are defined in the constants with prefix STATE_. + * + * This value is mandatory. + */ + int state; + + /** + * The received GNSS Time-of-Week at the measurement time, in nanoseconds. + * For GNSS & QZSS, this is the received GNSS Time-of-Week at the + * measurement time, in nanoseconds. The value is relative to the + * beginning of the current GNSS week. + * + * Given the highest sync state that can be achieved, per each satellite, + * valid range for this field can be: + * Searching : [ 0 ] : STATE_UNKNOWN + * C/A code lock : [ 0 1ms ] : STATE_CODE_LOCK set + * Bit sync : [ 0 20ms ] : STATE_BIT_SYNC set + * Subframe sync : [ 0 6s ] : STATE_SUBFRAME_SYNC set + * TOW decoded : [ 0 1week ] : STATE_TOW_DECODED set + * TOW Known : [ 0 1week ] : STATE_TOW_KNOWN set + * + * Note: TOW Known refers to the case where TOW is possibly not decoded + * over the air but has been determined from other sources. If TOW + * decoded is set then TOW Known must also be set. + * + * Note: If there is any ambiguity in integer millisecond, + * STATE_MSEC_AMBIGUOUS must be set accordingly, in the + * 'state' field. + * + * This value must be populated if 'state' != STATE_UNKNOWN. + * + * For Glonass, this is the received Glonass time of day, at the + * measurement time in nanoseconds. + * + * Given the highest sync state that can be achieved, per each satellite, + * valid range for this field can be: + * Searching : [ 0 ] : STATE_UNKNOWN set + * C/A code lock : [ 0 1ms ] : STATE_CODE_LOCK set + * Symbol sync : [ 0 10ms ] : STATE_SYMBOL_SYNC set + * Bit sync : [ 0 20ms ] : STATE_BIT_SYNC set + * String sync : [ 0 2s ] : STATE_GLO_STRING_SYNC set + * Time of day decoded : [ 0 1day ] : STATE_GLO_TOD_DECODED set + * Time of day known : [ 0 1day ] : STATE_GLO_TOD_KNOWN set + * + * Note: Time of day known refers to the case where it is possibly not + * decoded over the air but has been determined from other sources. If + * Time of day decoded is set then Time of day known must also be set. + * + * For Beidou, this is the received Beidou time of week, + * at the measurement time in nanoseconds. + * + * Given the highest sync state that can be achieved, per each satellite, + * valid range for this field can be: + * Searching : [ 0 ] : STATE_UNKNOWN set. + * C/A code lock : [ 0 1ms ] : STATE_CODE_LOCK set. + * Bit sync (D2) : [ 0 2ms ] : STATE_BDS_D2_BIT_SYNC set. + * Bit sync (D1) : [ 0 20ms ] : STATE_BIT_SYNC set. + * Subframe (D2) : [ 0 0.6s ] : STATE_BDS_D2_SUBFRAME_SYNC set. + * Subframe (D1) : [ 0 6s ] : STATE_SUBFRAME_SYNC set. + * Time of week decoded : [ 0 1week ] : STATE_TOW_DECODED set. + * Time of week known : [ 0 1week ] : STATE_TOW_KNOWN set + * + * Note: TOW Known refers to the case where TOW is possibly not decoded + * over the air but has been determined from other sources. If TOW + * decoded is set then TOW Known must also be set. + * + * For Galileo, this is the received Galileo time of week, + * at the measurement time in nanoseconds. + * + * E1BC code lock : [ 0 4ms ] : STATE_GAL_E1BC_CODE_LOCK set. + * E1C 2nd code lock : [ 0 100ms] : STATE_GAL_E1C_2ND_CODE_LOCK set. + * E1B page : [ 0 2s ] : STATE_GAL_E1B_PAGE_SYNC set. + * Time of week decoded : [ 0 1week] : STATE_TOW_DECODED is set. + * Time of week known : [ 0 1week] : STATE_TOW_KNOWN set + * + * Note: TOW Known refers to the case where TOW is possibly not decoded + * over the air but has been determined from other sources. If TOW + * decoded is set then TOW Known must also be set. + * + * For SBAS, this is received SBAS time, at the measurement time in + * nanoseconds. + * + * Given the highest sync state that can be achieved, per each satellite, + * valid range for this field can be: + * Searching : [ 0 ] : STATE_UNKNOWN + * C/A code lock: [ 0 1ms ] : STATE_CODE_LOCK is set + * Symbol sync : [ 0 2ms ] : STATE_SYMBOL_SYNC is set + * Message : [ 0 1s ] : STATE_SBAS_SYNC is set + */ + long receivedSvTimeInNs; + + /** + * 1-Sigma uncertainty of the Received GNSS Time-of-Week in nanoseconds. + * + * This value must be populated if 'state' != STATE_UNKNOWN. + */ + long receivedSvTimeUncertaintyInNs; + + /** + * Carrier-to-noise density in dB-Hz, typically in the range [0, 63]. + * It contains the measured C/N0 value for the signal at the antenna port. + * + * If a signal has separate components (e.g. Pilot and Data channels) and + * the receiver only processes one of the components, then the reported + * antennaCN0DbHz reflects only the component that is processed. + * + * This value is mandatory. + */ + double antennaCN0DbHz; + + /** + * Baseband Carrier-to-noise density in dB-Hz, typically in the range [0, 63]. It contains the + * measured C/N0 value for the signal measured at the baseband. + * + * This is typically a few dB weaker than the value estimated for C/N0 at the antenna port, + * which is reported in cN0DbHz. + * + * If a signal has separate components (e.g. Pilot and Data channels) and the receiver only + * processes one of the components, then the reported basebandCN0DbHz reflects only the + * component that is processed. + * + * This value is mandatory. + */ + double basebandCN0DbHz; + + /** + * Pseudorange rate at the timestamp in m/s. The correction of a given + * Pseudorange Rate value includes corrections for receiver and satellite + * clock frequency errors. Ensure that this field is independent (see + * comment at top of GnssMeasurement struct.) + * + * It is mandatory to provide the 'uncorrected' 'pseudorange rate', and + * provide GnssClock's 'drift' field as well. When providing the + * uncorrected pseudorange rate, do not apply the corrections described above.) + * + * The value includes the 'pseudorange rate uncertainty' in it. + * A positive 'uncorrected' value indicates that the SV is moving away from + * the receiver. + * + * The sign of the 'uncorrected' 'pseudorange rate' and its relation to the + * sign of 'doppler shift' is given by the equation: + * pseudorange rate = -k * doppler shift (where k is a constant) + * + * This must be the most accurate pseudorange rate available, based on + * fresh signal measurements from this channel. + * + * It is mandatory that this value be provided at typical carrier phase PRR + * quality (few cm/sec per second of uncertainty, or better) - when signals + * are sufficiently strong & stable, e.g. signals from a GNSS simulator at >= + * 35 dB-Hz. + */ + double pseudorangeRateMps; + + /** + * 1-Sigma uncertainty of the pseudorangeRateMps. + * The uncertainty is represented as an absolute (single sided) value. + * + * This value is mandatory. + */ + double pseudorangeRateUncertaintyMps; + + + /** + * Flags indicating the Accumulated Delta Range's states. + * + * See the table below for a detailed interpretation of each state. + * + * +---------------------+-------------------+-----------------------------+ + * | ADR_STATE | Time of relevance | Interpretation | + * +---------------------+-------------------+-----------------------------+ + * | UNKNOWN | ADR(t) | No valid carrier phase | + * | | | information is available | + * | | | at time t. | + * +---------------------+-------------------+-----------------------------+ + * | VALID | ADR(t) | Valid carrier phase | + * | | | information is available | + * | | | at time t. This indicates | + * | | | that this measurement can | + * | | | be used as a reference for | + * | | | future measurements. | + * | | | However, to compare it to | + * | | | previous measurements to | + * | | | compute delta range, | + * | | | other bits should be | + * | | | checked. Specifically, it | + * | | | can be used for delta range | + * | | | computation if it is valid | + * | | | and has no reset or cycle | + * | | | slip at this epoch i.e. | + * | | | if VALID_BIT == 1 && | + * | | | CYCLE_SLIP_BIT == 0 && | + * | | | RESET_BIT == 0. | + * +---------------------+-------------------+-----------------------------+ + * | RESET | ADR(t) - ADR(t-1) | Carrier phase accumulation | + * | | | has been restarted between | + * | | | current time t and previous | + * | | | time t-1. This indicates | + * | | | that this measurement can | + * | | | be used as a reference for | + * | | | future measurements, but it | + * | | | should not be compared to | + * | | | previous measurements to | + * | | | compute delta range. | + * +---------------------+-------------------+-----------------------------+ + * | CYCLE_SLIP | ADR(t) - ADR(t-1) | Cycle slip(s) have been | + * | | | detected between the | + * | | | current time t and previous | + * | | | time t-1. This indicates | + * | | | that this measurement can | + * | | | be used as a reference for | + * | | | future measurements. | + * | | | Clients can use a | + * | | | measurement with a cycle | + * | | | slip to compute delta range | + * | | | against previous | + * | | | measurements at their own | + * | | | risk. | + * +---------------------+-------------------+-----------------------------+ + * | HALF_CYCLE_RESOLVED | ADR(t) | Half cycle ambiguity is | + * | | | resolved at time t. | + * +---------------------+-------------------+-----------------------------+ + */ + const int ADR_STATE_UNKNOWN = 0; + const int ADR_STATE_VALID = 1 << 0; + const int ADR_STATE_RESET = 1 << 1; + const int ADR_STATE_CYCLE_SLIP = 1 << 2; + const int ADR_STATE_HALF_CYCLE_RESOLVED = 1 << 3; + + /** + * A bitfield of flags indicating the accumulated delta range's state. It indicates whether ADR + * is reset or there is a cycle slip(indicating loss of lock). + * + * The bit masks are defined in constants with prefix ADR_STATE_. + * + * This value is mandatory. + */ + int accumulatedDeltaRangeState; + + /** + * Accumulated delta range since the last channel reset in meters. + * A positive value indicates that the SV is moving away from the receiver. + * + * The sign of the 'accumulated delta range' and its relation to the sign of + * 'carrier phase' is given by the equation: + * accumulated delta range = -k * carrier phase (where k is a constant) + * + * This value must be populated if 'accumulated delta range state' != + * ADR_STATE_UNKNOWN. + * However, it is expected that the data is only accurate when: + * 'accumulated delta range state' == ADR_STATE_VALID. + * + * The alignment of the phase measurement will not be adjusted by the receiver so the in-phase + * and quadrature phase components will have a quarter cycle offset as they do when transmitted + * from the satellites. If the measurement is from a combination of the in-phase and quadrature + * phase components, then the alignment of the phase measurement will be aligned to the in-phase + * component. + */ + double accumulatedDeltaRangeM; + + /** + * 1-Sigma uncertainty of the accumulated delta range in meters. + * This value must be populated if 'accumulated delta range state' != + * ADR_STATE_UNKNOWN. + */ + double accumulatedDeltaRangeUncertaintyM; + + /** + * 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. + * + * If the data is available, gnssMeasurementFlags must contain + * HAS_CARRIER_FREQUENCY. + */ + float carrierFrequencyHz; + + /** + * The number of full carrier cycles between the satellite and the + * receiver. The reference frequency is given by the field + * 'carrierFrequencyHz'. Indications of possible cycle slips and + * resets in the accumulation of this value can be inferred from the + * accumulatedDeltaRangeState flags. + * + * If the data is available, gnssMeasurementFlags must contain + * HAS_CARRIER_CYCLES. + */ + long carrierCycles; + + /** + * The RF phase detected by the receiver, in the range [0.0, 1.0]. + * This is usually the fractional part of the complete carrier phase + * measurement. + * + * The reference frequency is given by the field 'carrierFrequencyHz'. + * The value contains the 'carrier-phase uncertainty' in it. + * + * If the data is available, gnssMeasurementFlags must contain + * HAS_CARRIER_PHASE. + */ + double carrierPhase; + + /** + * 1-Sigma uncertainty of the carrier-phase. + * If the data is available, gnssMeasurementFlags must contain + * HAS_CARRIER_PHASE_UNCERTAINTY. + */ + double carrierPhaseUncertainty; + + /** + * An enumeration that indicates the 'multipath' state of the event. + * + * The multipath Indicator is intended to report the presence of overlapping + * signals that manifest as distorted correlation peaks. + * + * - if there is a distorted correlation peak shape, report that multipath + * is MULTIPATH_INDICATOR_PRESENT. + * - if there is no distorted correlation peak shape, report + * MULTIPATH_INDICATOR_NOT_PRESENT + * - if signals are too weak to discern this information, report + * MULTIPATH_INDICATOR_UNKNOWN + * + * Example: when doing the standardized overlapping Multipath Performance + * test (3GPP TS 34.171) the Multipath indicator must report + * MULTIPATH_INDICATOR_PRESENT for those signals that are tracked, and + * contain multipath, and MULTIPATH_INDICATOR_NOT_PRESENT for those + * signals that are tracked and do not contain multipath. + */ + GnssMultipathIndicator multipathIndicator; + + /** + * Signal-to-noise ratio at correlator output in dB. + * If the data is available, GnssMeasurementFlags must contain HAS_SNR. + * This is the power ratio of the "correlation peak height above the + * observed noise floor" to "the noise RMS". + */ + double snrDb; + + /** + * 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. When AGC is at a + * nominal level, this value must be set as 0. 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. + * + * 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; + + /** + * The full inter-signal bias (ISB) in nanoseconds. + * + * This value is the sum of the estimated receiver-side and the space-segment-side inter-system + * bias, inter-frequency bias and inter-code bias, including + * + * - Receiver inter-constellation bias (with respect to the constellation in + * GnssClock.referenceSignalTypeForIsb) + * - Receiver inter-frequency bias (with respect to the carrier frequency in + * GnssClock.referenceSignalTypeForIsb) + * - Receiver inter-code bias (with respect to the code type in + * GnssClock.referenceSignalTypeForIsb) + * - Master clock bias (e.g., GPS-GAL Time Offset (GGTO), GPS-UTC Time Offset (TauGps), BDS-GLO + * Time Offset (BGTO)) (with respect to the constellation in + * GnssClock.referenceSignalTypeForIsb) + * - Group delay (e.g., Total Group Delay (TGD)) + * - Satellite inter-frequency bias (GLO only) (with respect to the carrier frequency in + * GnssClock.referenceSignalTypeForIsb) + * - Satellite inter-code bias (e.g., Differential Code Bias (DCB)) (with respect to the code + * type in GnssClock.referenceSignalTypeForIsb) + * + * If a component of the above is already compensated in the provided + * GnssMeasurement.receivedSvTimeInNs, then it must not be included in the reported full ISB. + * + * The value does not include the inter-frequency Ionospheric bias. + * + * The full ISB of GnssClock.referenceSignalTypeForIsb is defined to be 0.0 nanoseconds. + */ + double fullInterSignalBiasNs; + + /** + * 1-sigma uncertainty associated with the full inter-signal bias in nanoseconds. + */ + double fullInterSignalBiasUncertaintyNs; + + /** + * The satellite inter-signal bias in nanoseconds. + * + * This value is the sum of the space-segment-side inter-system bias, inter-frequency bias + * and inter-code bias, including + * + * - Master clock bias (e.g., GPS-GAL Time Offset (GGTO), GPS-UTC Time Offset (TauGps), BDS-GLO + * Time Offset (BGTO)) (with respect to the constellation in + * GnssClock.referenceSignalTypeForIsb) + * - Group delay (e.g., Total Group Delay (TGD)) + * - Satellite inter-frequency bias (GLO only) (with respect to the carrier frequency in + * GnssClock.referenceSignalTypeForIsb) + * - Satellite inter-code bias (e.g., Differential Code Bias (DCB)) (with respect to the code + * type in GnssClock.referenceSignalTypeForIsb) + * + * The satellite ISB of GnssClock.referenceSignalTypeForIsb is defined to be 0.0 nanoseconds. + */ + double satelliteInterSignalBiasNs; + + /** + * 1-sigma uncertainty associated with the satellite inter-signal bias in nanoseconds. + */ + double satelliteInterSignalBiasUncertaintyNs; +} \ No newline at end of file diff --git a/gnss/aidl/android/hardware/gnss/GnssMultipathIndicator.aidl b/gnss/aidl/android/hardware/gnss/GnssMultipathIndicator.aidl new file mode 100644 index 0000000000..ec1ce62705 --- /dev/null +++ b/gnss/aidl/android/hardware/gnss/GnssMultipathIndicator.aidl @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.gnss; + +/** + * Enumeration of available values for the GNSS Measurement's multipath + * indicator. + */ +@VintfStability +@Backing(type="int") +enum GnssMultipathIndicator { + /** The indicator is not available or unknown. */ + UNKNOWN = 0, + /** The measurement is indicated to be affected by multipath. */ + PRESENT = 1, + /** The measurement is indicated to be not affected by multipath. */ + NOT_PRESENT = 2, +} \ No newline at end of file diff --git a/gnss/aidl/android/hardware/gnss/GnssSignalType.aidl b/gnss/aidl/android/hardware/gnss/GnssSignalType.aidl new file mode 100644 index 0000000000..a284fedc3f --- /dev/null +++ b/gnss/aidl/android/hardware/gnss/GnssSignalType.aidl @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.gnss; + +import android.hardware.gnss.GnssConstellationType; + +/** + * Represents a GNSS signal type. + */ +@VintfStability +parcelable GnssSignalType { + /** + * Constellation type of the SV that transmits the signal. + */ + GnssConstellationType constellation; + + /** + * 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. + */ + double carrierFrequencyHz; + + /** + * GNSS signal code type "A" representing GALILEO E1A, GALILEO E6A, IRNSS L5A, IRNSS SA. + */ + const String CODE_TYPE_A = "A"; + + /** + * GNSS signal code type "B" representing GALILEO E1B, GALILEO E6B, IRNSS L5B, IRNSS SB. + */ + const String CODE_TYPE_B = "B"; + + /** + * GNSS signal code type "C" representing GPS L1 C/A, GPS L2 C/A, GLONASS G1 C/A, + * GLONASS G2 C/A, GALILEO E1C, GALILEO E6C, SBAS L1 C/A, QZSS L1 C/A, IRNSS L5C. + */ + const String CODE_TYPE_C = "C"; + + /** + * GNSS signal code type "D" representing BDS B1C D. + */ + const String CODE_TYPE_D = "D"; + + /** + * GNSS signal code type "I" representing GPS L5 I, GLONASS G3 I, GALILEO E5a I, GALILEO E5b I, + * GALILEO E5a+b I, SBAS L5 I, QZSS L5 I, BDS B1 I, BDS B2 I, BDS B3 I. + */ + const String CODE_TYPE_I = "I"; + + /** + * GNSS signal code type "L" representing GPS L1C (P), GPS L2C (L), QZSS L1C (P), QZSS L2C (L), + * LEX(6) L. + */ + const String CODE_TYPE_L = "L"; + + /** + * GNSS signal code type "M" representing GPS L1M, GPS L2M. + */ + const String CODE_TYPE_M = "M"; + + /** + * GNSS signal code type "N" representing GPS L1 codeless, GPS L2 codeless. + */ + const String CODE_TYPE_N = "N"; + + /** + * GNSS signal code type "P" representing GPS L1P, GPS L2P, GLONASS G1P, GLONASS G2P, BDS B1C P. + */ + const String CODE_TYPE_P = "P"; + + /** + * GNSS signal code type "Q" representing GPS L5 Q, GLONASS G3 Q, GALILEO E5a Q, GALILEO E5b Q, + * GALILEO E5a+b Q, SBAS L5 Q, QZSS L5 Q, BDS B1 Q, BDS B2 Q, BDS B3 Q. + */ + const String CODE_TYPE_Q = "Q"; + + /** + * GNSS signal code type "S" represents GPS L1C (D), GPS L2C (M), QZSS L1C (D), QZSS L2C (M), + * LEX(6) S. + */ + const String CODE_TYPE_S = "S"; + + /** + * GNSS signal code type "W" representing GPS L1 Z-tracking, GPS L2 Z-tracking. + */ + const String CODE_TYPE_W = "W"; + + /** + * GNSS signal code type "X" representing GPS L1C (D+P), GPS L2C (M+L), GPS L5 (I+Q), + * GLONASS G3 (I+Q), GALILEO E1 (B+C), GALILEO E5a (I+Q), GALILEO E5b (I+Q), GALILEO E5a+b(I+Q), + * GALILEO E6 (B+C), SBAS L5 (I+Q), QZSS L1C (D+P), QZSS L2C (M+L), QZSS L5 (I+Q), + * LEX(6) (S+L), BDS B1 (I+Q), BDS B1C (D+P), BDS B2 (I+Q), BDS B3 (I+Q), IRNSS L5 (B+C). + */ + const String CODE_TYPE_X = "X"; + + /** + * GNSS signal code type "Y" representing GPS L1Y, GPS L2Y. + */ + const String CODE_TYPE_Y = "Y"; + + /** + * GNSS signal code type "Z" representing GALILEO E1 (A+B+C), GALILEO E6 (A+B+C), QZSS L1-SAIF. + */ + const String CODE_TYPE_Z = "Z"; + + /** + * GNSS signal code type "UNKNOWN" representing the GNSS Measurement's code type is unknown. + */ + const String CODE_TYPE_UNKNOWN = "UNKNOWN"; + + /** + * The type of code that is currently being tracked in the GNSS signal. + * + * For high precision applications the type of code being tracked needs to be considered + * in-order to properly apply code specific corrections to the pseudorange measurements. + * + * The value is one of the constant Strings with prefix CODE_TYPE_ defined in this parcelable. + * + * This is used to specify the observation descriptor defined in GNSS Observation Data File + * Header Section Description in the RINEX standard (Version 3.XX). In RINEX Version 3.03, + * in Appendix Table A2 Attributes are listed as uppercase letters (for instance, "A" for + * "A channel"). In the future, if for instance a code "G" was added in the official RINEX + * standard, "G" could be specified here. + */ + String codeType; +} diff --git a/gnss/aidl/android/hardware/gnss/IGnss.aidl b/gnss/aidl/android/hardware/gnss/IGnss.aidl index 2af57b5aab..c815e2dc93 100644 --- a/gnss/aidl/android/hardware/gnss/IGnss.aidl +++ b/gnss/aidl/android/hardware/gnss/IGnss.aidl @@ -17,9 +17,10 @@ package android.hardware.gnss; import android.hardware.gnss.IGnssCallback; +import android.hardware.gnss.IGnssConfiguration; +import android.hardware.gnss.IGnssMeasurementInterface; import android.hardware.gnss.IGnssPowerIndication; import android.hardware.gnss.IGnssPsds; -import android.hardware.gnss.IGnssConfiguration; /** * Represents the standard GNSS (Global Navigation Satellite System) interface. @@ -33,14 +34,6 @@ interface IGnss { */ const int ERROR_INVALID_ARGUMENT = 1; - /** Bit mask indicating a valid timestampNs is stored in the ElapsedRealtime parcelable. */ - const int ELAPSED_REALTIME_HAS_TIMESTAMP_NS = 1 << 0; - - /** - * Bit mask indicating a valid timeUncertaintyNs is stored in the ElapsedRealtime parcelable. - */ - const int ELAPSED_REALTIME_HAS_TIME_UNCERTAINTY_NS = 1 << 1; - /** * Opens the interface and provides the callback routines to the implementation of this * interface. @@ -74,6 +67,8 @@ interface IGnss { /** * This method returns the IGnssPsds interface. * + * This method must return non-null. + * * @return Handle to the IGnssPsds interface. */ IGnssPsds getExtensionPsds(); @@ -81,13 +76,26 @@ interface IGnss { /** * This method returns the IGnssConfiguration interface. * + * This method must return non-null. + * * @return Handle to the IGnssConfiguration interface. */ IGnssConfiguration getExtensionGnssConfiguration(); + /** + * This methods returns the IGnssMeasurementInterface interface. + * + * This method must return non-null. + * + * @return Handle to the IGnssMeasurementInterface interface. + */ + IGnssMeasurementInterface getExtensionGnssMeasurement(); + /** * This method returns the IGnssPowerIndication interface. * + * This method must return non-null. + * * @return Handle to the IGnssPowerIndication interface. */ IGnssPowerIndication getExtensionGnssPowerIndication(); diff --git a/gnss/aidl/android/hardware/gnss/IGnssMeasurementCallback.aidl b/gnss/aidl/android/hardware/gnss/IGnssMeasurementCallback.aidl new file mode 100644 index 0000000000..328cf2abad --- /dev/null +++ b/gnss/aidl/android/hardware/gnss/IGnssMeasurementCallback.aidl @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.gnss; + +import android.hardware.gnss.GnssData; + +/** + * The callback interface to report GNSS Measurement from the HAL. + */ +@VintfStability +interface IGnssMeasurementCallback { + /** + * Callback for the hal to pass a GnssData structure back to the client. + * + * @param data Contains a reading of GNSS measurements. + */ + void gnssMeasurementCb(in GnssData data); +} \ No newline at end of file diff --git a/gnss/aidl/android/hardware/gnss/IGnssMeasurementInterface.aidl b/gnss/aidl/android/hardware/gnss/IGnssMeasurementInterface.aidl new file mode 100644 index 0000000000..fdeebde8ae --- /dev/null +++ b/gnss/aidl/android/hardware/gnss/IGnssMeasurementInterface.aidl @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.gnss; + +import android.hardware.gnss.IGnssMeasurementCallback; + +/** + * Extended interface for GNSS Measurement support. + */ +@VintfStability +interface IGnssMeasurementInterface { + /** + * Initializes the interface and registers the callback routines with the HAL. After a + * successful call to 'setCallback' the HAL must begin to provide updates at an average + * output rate of 1Hz (occasional intra-measurement time offsets in the range from 0-2000msec + * can be tolerated.) + * + * @param callback Handle to GnssMeasurement callback interface. + * @param enableFullTracking If true, GNSS chipset must switch off duty cycling. In such mode + * no clock discontinuities are expected and, when supported, carrier phase should be + * continuous in good signal conditions. All non-blocklisted, healthy constellations, + * satellites and frequency bands that the chipset supports must be reported in this mode. + * The GNSS chipset is allowed to consume more power in this mode. If false, API must + * optimize power via duty cycling, constellations and frequency limits, etc. + * + * @return initRet Returns SUCCESS if successful. Returns ERROR_ALREADY_INIT if a callback has + * already been registered without a corresponding call to 'close'. Returns ERROR_GENERIC + * for any other error. The HAL must not generate any other updates upon returning this + * error code. + */ + void setCallback(in IGnssMeasurementCallback callback, in boolean enableFullTracking); + + /** + * 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(); +} \ No newline at end of file diff --git a/gnss/aidl/default/Android.bp b/gnss/aidl/default/Android.bp index 23677ed4cc..6694ce619c 100644 --- a/gnss/aidl/default/Android.bp +++ b/gnss/aidl/default/Android.bp @@ -50,6 +50,7 @@ cc_binary { "GnssPowerIndication.cpp", "GnssPsds.cpp", "GnssConfiguration.cpp", + "GnssMeasurementInterface.cpp", "service.cpp", ], static_libs: [ diff --git a/gnss/aidl/default/Gnss.cpp b/gnss/aidl/default/Gnss.cpp index 669372b374..02bad6031d 100644 --- a/gnss/aidl/default/Gnss.cpp +++ b/gnss/aidl/default/Gnss.cpp @@ -19,6 +19,7 @@ #include "Gnss.h" #include #include "GnssConfiguration.h" +#include "GnssMeasurementInterface.h" #include "GnssPowerIndication.h" #include "GnssPsds.h" @@ -74,4 +75,12 @@ ndk::ScopedAStatus Gnss::getExtensionGnssPowerIndication( return ndk::ScopedAStatus::ok(); } +ndk::ScopedAStatus Gnss::getExtensionGnssMeasurement( + std::shared_ptr* iGnssMeasurement) { + ALOGD("Gnss::getExtensionGnssMeasurement"); + + *iGnssMeasurement = SharedRefBase::make(); + return ndk::ScopedAStatus::ok(); +} + } // namespace aidl::android::hardware::gnss diff --git a/gnss/aidl/default/Gnss.h b/gnss/aidl/default/Gnss.h index 9f6ef0e32f..bccc7f2007 100644 --- a/gnss/aidl/default/Gnss.h +++ b/gnss/aidl/default/Gnss.h @@ -18,6 +18,7 @@ #include #include +#include #include #include #include "GnssConfiguration.h" @@ -33,6 +34,8 @@ class Gnss : public BnGnss { std::shared_ptr* iGnssConfiguration) override; ndk::ScopedAStatus getExtensionGnssPowerIndication( std::shared_ptr* iGnssPowerIndication) override; + ndk::ScopedAStatus getExtensionGnssMeasurement( + std::shared_ptr* iGnssMeasurement) override; std::shared_ptr mGnssConfiguration; diff --git a/gnss/aidl/default/GnssConfiguration.h b/gnss/aidl/default/GnssConfiguration.h index 25fa16e610..491733c9ca 100644 --- a/gnss/aidl/default/GnssConfiguration.h +++ b/gnss/aidl/default/GnssConfiguration.h @@ -24,8 +24,6 @@ namespace aidl::android::hardware::gnss { -using android::hardware::gnss::GnssConstellationType; - struct BlocklistedSourceHash { inline int operator()(const BlocklistedSource& source) const { return int(source.constellation) * 1000 + int(source.svid); @@ -42,7 +40,8 @@ using GnssSvInfoV2_1 = ::android::hardware::gnss::V2_1::IGnssCallback::GnssSvInf using std::vector; using BlocklistedSourceSet = std::unordered_set; -using BlocklistedConstellationSet = std::unordered_set; +using BlocklistedConstellationSet = + std::unordered_set; struct GnssConfiguration : public BnGnssConfiguration { public: diff --git a/gnss/aidl/default/GnssHidlHal.cpp b/gnss/aidl/default/GnssHidlHal.cpp index 11fc8064fa..9529ec9f33 100644 --- a/gnss/aidl/default/GnssHidlHal.cpp +++ b/gnss/aidl/default/GnssHidlHal.cpp @@ -17,11 +17,10 @@ #define LOG_TAG "GnssHidlHal" #include "GnssHidlHal.h" -//#include namespace aidl::android::hardware::gnss { -namespace V1_0 = ::android::hardware::gnss::V1_0; +using GnssSvInfo = ::android::hardware::gnss::V2_1::IGnssCallback::GnssSvInfo; GnssHidlHal::GnssHidlHal(const std::shared_ptr& gnssAidl) : mGnssAidl(gnssAidl) { Gnss* iGnss = mGnssAidl.get(); @@ -45,8 +44,8 @@ hidl_vec GnssHidlHal::filterBlocklistedSatellitesV2_1( if (mGnssConfigurationAidl->isBlocklistedV2_1(gnssSvInfoList[i])) { ALOGD("Blocklisted constellation: %d, svid: %d", (int)gnssSvInfoList[i].v2_0.constellation, gnssSvInfoList[i].v2_0.v1_0.svid); - gnssSvInfoList[i].v2_0.v1_0.svFlag &= - ~static_cast(V1_0::IGnssCallback::GnssSvFlags::USED_IN_FIX); + gnssSvInfoList[i].v2_0.v1_0.svFlag &= ~static_cast( + ::android::hardware::gnss::V1_0::IGnssCallback::GnssSvFlags::USED_IN_FIX); } } return gnssSvInfoList; diff --git a/gnss/aidl/default/GnssHidlHal.h b/gnss/aidl/default/GnssHidlHal.h index 50aad3a206..93a79a150a 100644 --- a/gnss/aidl/default/GnssHidlHal.h +++ b/gnss/aidl/default/GnssHidlHal.h @@ -22,16 +22,16 @@ namespace aidl::android::hardware::gnss { -using ::android::hardware::gnss::common::implementation::GnssTemplate; -using GnssSvInfo = ::android::hardware::gnss::V2_1::IGnssCallback::GnssSvInfo; - -class GnssHidlHal : public GnssTemplate<::android::hardware::gnss::V2_1::IGnss> { +class GnssHidlHal : public ::android::hardware::gnss::common::implementation::GnssTemplate< + ::android::hardware::gnss::V2_1::IGnss> { public: GnssHidlHal(const std::shared_ptr& gnssAidl); private: - hidl_vec filterBlocklistedSatellitesV2_1( - hidl_vec gnssSvInfoList) override; + hidl_vec<::android::hardware::gnss::V2_1::IGnssCallback::GnssSvInfo> + filterBlocklistedSatellitesV2_1( + hidl_vec<::android::hardware::gnss::V2_1::IGnssCallback::GnssSvInfo> gnssSvInfoList) + override; std::shared_ptr mGnssAidl; std::shared_ptr mGnssConfigurationAidl; diff --git a/gnss/aidl/default/GnssMeasurementInterface.cpp b/gnss/aidl/default/GnssMeasurementInterface.cpp new file mode 100644 index 0000000000..d726d9502f --- /dev/null +++ b/gnss/aidl/default/GnssMeasurementInterface.cpp @@ -0,0 +1,90 @@ +/* + * 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 "GnssMeasIfaceAidl" + +#include "GnssMeasurementInterface.h" +#include +#include +#include "Utils.h" + +namespace aidl::android::hardware::gnss { + +using Utils = ::android::hardware::gnss::common::Utils; + +std::shared_ptr GnssMeasurementInterface::sCallback = nullptr; + +GnssMeasurementInterface::GnssMeasurementInterface() : mMinIntervalMillis(1000) {} + +GnssMeasurementInterface::~GnssMeasurementInterface() { + stop(); +} + +ndk::ScopedAStatus GnssMeasurementInterface::setCallback( + const std::shared_ptr& callback, const bool enableFullTracking) { + ALOGD("setCallback: enableFullTracking: %d", (int)enableFullTracking); + std::unique_lock lock(mMutex); + sCallback = callback; + + if (mIsActive) { + ALOGW("GnssMeasurement callback already set. Resetting the callback..."); + stop(); + } + start(); + + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus GnssMeasurementInterface::close() { + ALOGD("close"); + stop(); + std::unique_lock lock(mMutex); + sCallback = nullptr; + return ndk::ScopedAStatus::ok(); +} + +void GnssMeasurementInterface::start() { + ALOGD("start"); + mIsActive = true; + mThread = std::thread([this]() { + while (mIsActive == true) { + auto measurement = Utils::getMockMeasurement(); + this->reportMeasurement(measurement); + + std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMillis)); + } + }); +} + +void GnssMeasurementInterface::stop() { + ALOGD("stop"); + mIsActive = false; + if (mThread.joinable()) { + mThread.join(); + } +} + +void GnssMeasurementInterface::reportMeasurement(const GnssData& data) { + ALOGD("reportMeasurement()"); + std::unique_lock lock(mMutex); + if (sCallback == nullptr) { + ALOGE("%s: GnssMeasurement::sCallback is null.", __func__); + return; + } + sCallback->gnssMeasurementCb(data); +} + +} // namespace aidl::android::hardware::gnss diff --git a/gnss/aidl/default/GnssMeasurementInterface.h b/gnss/aidl/default/GnssMeasurementInterface.h new file mode 100644 index 0000000000..69cd871c96 --- /dev/null +++ b/gnss/aidl/default/GnssMeasurementInterface.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include +#include +#include + +namespace aidl::android::hardware::gnss { + +struct GnssMeasurementInterface : public BnGnssMeasurementInterface { + public: + GnssMeasurementInterface(); + ~GnssMeasurementInterface(); + ndk::ScopedAStatus setCallback(const std::shared_ptr& callback, + const bool enableFullTracking) override; + ndk::ScopedAStatus close() override; + + private: + void start(); + void stop(); + void reportMeasurement(const GnssData&); + + std::atomic mMinIntervalMillis; + std::atomic mIsActive; + std::thread mThread; + + // Guarded by mMutex + static std::shared_ptr sCallback; + + // Synchronization lock for sCallback + mutable std::mutex mMutex; +}; + +} // namespace aidl::android::hardware::gnss diff --git a/gnss/aidl/default/GnssPowerIndication.cpp b/gnss/aidl/default/GnssPowerIndication.cpp index 8ea60f360a..429cc8c0e0 100644 --- a/gnss/aidl/default/GnssPowerIndication.cpp +++ b/gnss/aidl/default/GnssPowerIndication.cpp @@ -19,6 +19,7 @@ #include "GnssPowerIndication.h" #include #include +#include namespace aidl::android::hardware::gnss { @@ -43,10 +44,9 @@ ndk::ScopedAStatus GnssPowerIndication::requestGnssPowerStats() { std::unique_lock lock(mMutex); ElapsedRealtime elapsedRealtime = { - .flags = IGnss::ELAPSED_REALTIME_HAS_TIMESTAMP_NS | - IGnss::ELAPSED_REALTIME_HAS_TIME_UNCERTAINTY_NS, - .timestampNs = (long)1323542, - .timeUncertaintyNs = (long)1000, + .flags = ElapsedRealtime::HAS_TIMESTAMP_NS | ElapsedRealtime::HAS_TIME_UNCERTAINTY_NS, + .timestampNs = ::android::elapsedRealtimeNano(), + .timeUncertaintyNs = 1000, }; GnssPowerStats gnssPowerStats = { .elapsedRealtime = elapsedRealtime, diff --git a/gnss/aidl/vts/Android.bp b/gnss/aidl/vts/Android.bp index d102e7f4dd..c10e809725 100644 --- a/gnss/aidl/vts/Android.bp +++ b/gnss/aidl/vts/Android.bp @@ -22,6 +22,7 @@ cc_test { "gnss_hal_test.cpp", "gnss_hal_test_cases.cpp", "GnssCallbackAidl.cpp", + "GnssMeasurementCallbackAidl.cpp", "GnssPowerIndicationCallback.cpp", "VtsHalGnssTargetTest.cpp", ], diff --git a/gnss/aidl/vts/GnssMeasurementCallbackAidl.cpp b/gnss/aidl/vts/GnssMeasurementCallbackAidl.cpp new file mode 100644 index 0000000000..c4fad7fb35 --- /dev/null +++ b/gnss/aidl/vts/GnssMeasurementCallbackAidl.cpp @@ -0,0 +1,35 @@ +/* + * 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 "GnssMeasurementCallbackAidl" + +#include "GnssMeasurementCallbackAidl.h" +#include +#include + +using android::hardware::gnss::GnssData; + +android::binder::Status GnssMeasurementCallbackAidl::gnssMeasurementCb(const GnssData& gnssData) { + ALOGI("gnssMeasurementCb"); + ALOGI("elapsedRealtime: flags = %d, timestampNs: %" PRId64 ", timeUncertaintyNs=%lf", + gnssData.elapsedRealtime.flags, gnssData.elapsedRealtime.timestampNs, + gnssData.elapsedRealtime.timeUncertaintyNs); + for (const auto& measurement : gnssData.measurements) { + ALOGI("measurement.receivedSvTimeInNs=%" PRId64, measurement.receivedSvTimeInNs); + } + gnss_data_cbq_.store(gnssData); + return android::binder::Status::ok(); +} diff --git a/gnss/aidl/vts/GnssMeasurementCallbackAidl.h b/gnss/aidl/vts/GnssMeasurementCallbackAidl.h new file mode 100644 index 0000000000..f6c79cfaf2 --- /dev/null +++ b/gnss/aidl/vts/GnssMeasurementCallbackAidl.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include "GnssCallbackEventQueue.h" + +/** Implementation for IGnssMeasurementCallback. */ +class GnssMeasurementCallbackAidl : public android::hardware::gnss::BnGnssMeasurementCallback { + public: + GnssMeasurementCallbackAidl() : gnss_data_cbq_("gnss_data") {} + ~GnssMeasurementCallbackAidl() {} + + android::binder::Status gnssMeasurementCb( + const android::hardware::gnss::GnssData& gnssData) override; + + android::hardware::gnss::common::GnssCallbackEventQueue + gnss_data_cbq_; +}; diff --git a/gnss/aidl/vts/GnssPowerIndicationCallback.h b/gnss/aidl/vts/GnssPowerIndicationCallback.h index d4c4539389..3416f17230 100644 --- a/gnss/aidl/vts/GnssPowerIndicationCallback.h +++ b/gnss/aidl/vts/GnssPowerIndicationCallback.h @@ -25,7 +25,6 @@ class GnssPowerIndicationCallback : public android::hardware::gnss::BnGnssPowerI public: GnssPowerIndicationCallback() : capabilities_cbq_("capabilities"), - other_mode_names_cbq_("other_mode_names"), gnss_power_stats_cbq_("gnss_power_stats") {} ~GnssPowerIndicationCallback() {} @@ -35,9 +34,6 @@ class GnssPowerIndicationCallback : public android::hardware::gnss::BnGnssPowerI android::hardware::gnss::common::GnssCallbackEventQueue capabilities_cbq_; int last_capabilities_; - android::hardware::gnss::common::GnssCallbackEventQueue> - other_mode_names_cbq_; - std::vector last_other_mode_names_; android::hardware::gnss::common::GnssCallbackEventQueue gnss_power_stats_cbq_; android::hardware::gnss::GnssPowerStats last_gnss_power_stats_; diff --git a/gnss/aidl/vts/gnss_hal_test.h b/gnss/aidl/vts/gnss_hal_test.h index eb5301e2cd..f72f7fe4e8 100644 --- a/gnss/aidl/vts/gnss_hal_test.h +++ b/gnss/aidl/vts/gnss_hal_test.h @@ -36,7 +36,7 @@ using android::hardware::gnss::BlocklistedSource; using android::hardware::gnss::IGnssConfiguration; // The main test class for GNSS HAL. -class GnssHalTest : public GnssHalTestTemplate { +class GnssHalTest : public android::hardware::gnss::common::GnssHalTestTemplate { public: GnssHalTest(){}; ~GnssHalTest(){}; diff --git a/gnss/aidl/vts/gnss_hal_test_cases.cpp b/gnss/aidl/vts/gnss_hal_test_cases.cpp index 4e8d0bd66b..857c74208b 100644 --- a/gnss/aidl/vts/gnss_hal_test_cases.cpp +++ b/gnss/aidl/vts/gnss_hal_test_cases.cpp @@ -16,19 +16,30 @@ #define LOG_TAG "GnssHalTestCases" +#include +#include +#include #include #include +#include "GnssMeasurementCallbackAidl.h" #include "GnssPowerIndicationCallback.h" #include "gnss_hal_test.h" using android::sp; using android::hardware::gnss::BlocklistedSource; -using GnssConstellationTypeAidl = android::hardware::gnss::GnssConstellationType; +using android::hardware::gnss::ElapsedRealtime; +using android::hardware::gnss::GnssClock; +using android::hardware::gnss::GnssMeasurement; +using android::hardware::gnss::IGnss; using android::hardware::gnss::IGnssConfiguration; +using android::hardware::gnss::IGnssMeasurementCallback; +using android::hardware::gnss::IGnssMeasurementInterface; using android::hardware::gnss::IGnssPowerIndication; using android::hardware::gnss::IGnssPsds; using android::hardware::gnss::PsdsType; +using GnssConstellationTypeAidl = android::hardware::gnss::GnssConstellationType; + /* * SetupTeardownCreateCleanup: * Requests the gnss HAL then calls cleanup @@ -52,6 +63,62 @@ TEST_P(GnssHalTest, TestPsdsExtension) { ASSERT_FALSE(status.isOk()); } +/* + * TestGnssMeasurementExtension: + * 1. Gets the GnssMeasurementExtension and verifies that it returns a non-null extension. + * 2. Sets a GnssMeasurementCallback, waits for a measurement, and verifies fields are valid. + */ +TEST_P(GnssHalTest, TestGnssMeasurementExtension) { + const int kFirstGnssMeasurementTimeoutSeconds = 10; + sp iGnssMeasurement; + auto status = aidl_gnss_hal_->getExtensionGnssMeasurement(&iGnssMeasurement); + ASSERT_TRUE(status.isOk()); + ASSERT_TRUE(iGnssMeasurement != nullptr); + + auto callback = sp::make(); + status = iGnssMeasurement->setCallback(callback, /* enableFullTracking= */ true); + ASSERT_TRUE(status.isOk()); + + android::hardware::gnss::GnssData lastMeasurement; + ASSERT_TRUE(callback->gnss_data_cbq_.retrieve(lastMeasurement, + kFirstGnssMeasurementTimeoutSeconds)); + EXPECT_EQ(callback->gnss_data_cbq_.calledCount(), 1); + ASSERT_TRUE(lastMeasurement.measurements.size() > 0); + + // Validity check GnssData fields + ASSERT_TRUE( + lastMeasurement.elapsedRealtime.flags >= 0 && + lastMeasurement.elapsedRealtime.flags <= + (ElapsedRealtime::HAS_TIMESTAMP_NS | ElapsedRealtime::HAS_TIME_UNCERTAINTY_NS)); + if (lastMeasurement.elapsedRealtime.flags & ElapsedRealtime::HAS_TIMESTAMP_NS) { + ASSERT_TRUE(lastMeasurement.elapsedRealtime.timestampNs > 0); + } + if (lastMeasurement.elapsedRealtime.flags & ElapsedRealtime::HAS_TIME_UNCERTAINTY_NS) { + ASSERT_TRUE(lastMeasurement.elapsedRealtime.timeUncertaintyNs > 0); + } + ASSERT_TRUE(lastMeasurement.clock.gnssClockFlags >= 0 && + lastMeasurement.clock.gnssClockFlags <= + (GnssClock::HAS_LEAP_SECOND | GnssClock::HAS_TIME_UNCERTAINTY | + GnssClock::HAS_FULL_BIAS | GnssClock::HAS_BIAS | + GnssClock::HAS_BIAS_UNCERTAINTY | GnssClock::HAS_DRIFT | + GnssClock::HAS_DRIFT_UNCERTAINTY)); + for (const auto& measurement : lastMeasurement.measurements) { + ASSERT_TRUE( + measurement.flags >= 0 && + measurement.flags <= + (GnssMeasurement::HAS_SNR | GnssMeasurement::HAS_CARRIER_FREQUENCY | + GnssMeasurement::HAS_CARRIER_CYCLES | GnssMeasurement::HAS_CARRIER_PHASE | + GnssMeasurement::HAS_CARRIER_PHASE_UNCERTAINTY | + GnssMeasurement::HAS_AUTOMATIC_GAIN_CONTROL | + GnssMeasurement::HAS_FULL_ISB | GnssMeasurement::HAS_FULL_ISB_UNCERTAINTY | + GnssMeasurement::HAS_SATELLITE_ISB | + GnssMeasurement::HAS_SATELLITE_ISB_UNCERTAINTY)); + } + + status = iGnssMeasurement->close(); + ASSERT_TRUE(status.isOk()); +} + /* * TestGnssPowerIndication * 1. Gets the GnssPowerIndicationExtension. diff --git a/gnss/common/utils/default/Android.bp b/gnss/common/utils/default/Android.bp index 730de4bfed..be1d532288 100644 --- a/gnss/common/utils/default/Android.bp +++ b/gnss/common/utils/default/Android.bp @@ -42,5 +42,6 @@ cc_library_static { "android.hardware.gnss@2.1", "android.hardware.gnss.measurement_corrections@1.1", "android.hardware.gnss.measurement_corrections@1.0", + "android.hardware.gnss-ndk_platform", ], } diff --git a/gnss/common/utils/default/Utils.cpp b/gnss/common/utils/default/Utils.cpp index d336f1bd5b..dd932d447b 100644 --- a/gnss/common/utils/default/Utils.cpp +++ b/gnss/common/utils/default/Utils.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include namespace android { @@ -24,16 +25,28 @@ namespace hardware { namespace gnss { namespace common { +using IGnss = aidl::android::hardware::gnss::IGnss; +using IGnssMeasurementCallback = aidl::android::hardware::gnss::IGnssMeasurementCallback; +using GnssMeasurement = aidl::android::hardware::gnss::GnssMeasurement; using GnssSvFlags = V1_0::IGnssCallback::GnssSvFlags; using GnssMeasurementFlagsV1_0 = V1_0::IGnssMeasurementCallback::GnssMeasurementFlags; using GnssMeasurementFlagsV2_1 = V2_1::IGnssMeasurementCallback::GnssMeasurementFlags; using GnssMeasurementStateV2_0 = V2_0::IGnssMeasurementCallback::GnssMeasurementState; -using ElapsedRealtime = V2_0::ElapsedRealtime; +using ElapsedRealtime = aidl::android::hardware::gnss::ElapsedRealtime; using ElapsedRealtimeFlags = V2_0::ElapsedRealtimeFlags; using GnssConstellationTypeV2_0 = V2_0::GnssConstellationType; using IGnssMeasurementCallbackV2_0 = V2_0::IGnssMeasurementCallback; using GnssSignalType = V2_1::GnssSignalType; +using GnssDataV2_0 = V2_0::IGnssMeasurementCallback::GnssData; +using GnssDataV2_1 = V2_1::IGnssMeasurementCallback::GnssData; +using GnssSvInfoV1_0 = V1_0::IGnssCallback::GnssSvInfo; +using GnssSvInfoV2_0 = V2_0::IGnssCallback::GnssSvInfo; +using GnssSvInfoV2_1 = V2_1::IGnssCallback::GnssSvInfo; +using GnssAntennaInfo = ::android::hardware::gnss::V2_1::IGnssAntennaInfoCallback::GnssAntennaInfo; +using Row = V2_1::IGnssAntennaInfoCallback::Row; +using Coord = V2_1::IGnssAntennaInfoCallback::Coord; + GnssDataV2_1 Utils::getMockMeasurementV2_1() { GnssDataV2_0 gnssDataV2_0 = Utils::getMockMeasurementV2_0(); V2_1::IGnssMeasurementCallback::GnssMeasurement gnssMeasurementV2_1 = { @@ -110,7 +123,7 @@ GnssDataV2_0 Utils::getMockMeasurementV2_0() { .driftUncertaintyNsps = 310.64968328491528, .hwClockDiscontinuityCount = 1}; - ElapsedRealtime timestamp = { + V2_0::ElapsedRealtime timestamp = { .flags = ElapsedRealtimeFlags::HAS_TIMESTAMP_NS | ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS, .timestampNs = static_cast(::android::elapsedRealtimeNano()), @@ -124,6 +137,52 @@ GnssDataV2_0 Utils::getMockMeasurementV2_0() { return gnssData; } +aidl::android::hardware::gnss::GnssData Utils::getMockMeasurement() { + aidl::android::hardware::gnss::GnssSignalType signalType = { + .constellation = aidl::android::hardware::gnss::GnssConstellationType::GLONASS, + .carrierFrequencyHz = 1.59975e+09, + .codeType = aidl::android::hardware::gnss::GnssSignalType::CODE_TYPE_C, + }; + aidl::android::hardware::gnss::GnssMeasurement measurement = { + .flags = GnssMeasurement::HAS_CARRIER_FREQUENCY, + .svid = 6, + .signalType = signalType, + .timeOffsetNs = 0.0, + .receivedSvTimeInNs = 8195997131077, + .receivedSvTimeUncertaintyInNs = 15, + .antennaCN0DbHz = 30.0, + .pseudorangeRateMps = -484.13739013671875, + .pseudorangeRateUncertaintyMps = 1.0379999876022339, + .accumulatedDeltaRangeState = GnssMeasurement::ADR_STATE_UNKNOWN, + .accumulatedDeltaRangeM = 0.0, + .accumulatedDeltaRangeUncertaintyM = 0.0, + .multipathIndicator = aidl::android::hardware::gnss::GnssMultipathIndicator::UNKNOWN, + .state = GnssMeasurement::STATE_CODE_LOCK | GnssMeasurement::STATE_BIT_SYNC | + GnssMeasurement::STATE_SUBFRAME_SYNC | GnssMeasurement::STATE_TOW_DECODED | + GnssMeasurement::STATE_GLO_STRING_SYNC | + GnssMeasurement::STATE_GLO_TOD_DECODED}; + + aidl::android::hardware::gnss::GnssClock clock = {.timeNs = 2713545000000, + .fullBiasNs = -1226701900521857520, + .biasNs = 0.59689998626708984, + .biasUncertaintyNs = 47514.989972114563, + .driftNsps = -51.757811607455452, + .driftUncertaintyNsps = 310.64968328491528, + .hwClockDiscontinuityCount = 1}; + + ElapsedRealtime timestamp = { + .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 = 1000000}; + + aidl::android::hardware::gnss::GnssData gnssData = { + .measurements = {measurement}, .clock = clock, .elapsedRealtime = timestamp}; + return gnssData; +} + V2_0::GnssLocation Utils::getMockLocationV2_0() { const V2_0::ElapsedRealtime timestamp = { .flags = V2_0::ElapsedRealtimeFlags::HAS_TIMESTAMP_NS | diff --git a/gnss/common/utils/default/include/NmeaFixInfo.h b/gnss/common/utils/default/include/NmeaFixInfo.h index fb2c1a4491..06eae7eda9 100644 --- a/gnss/common/utils/default/include/NmeaFixInfo.h +++ b/gnss/common/utils/default/include/NmeaFixInfo.h @@ -26,11 +26,6 @@ namespace android { namespace hardware { namespace gnss { namespace common { -using ::android::sp; -using ::android::hardware::hidl_string; -using ::android::hardware::hidl_vec; -using ::android::hardware::Return; -using ::android::hardware::Void; constexpr char GPGA_RECORD_TAG[] = "$GPGGA"; constexpr char GPRMC_RECORD_TAG[] = "$GPRMC"; diff --git a/gnss/common/utils/default/include/Utils.h b/gnss/common/utils/default/include/Utils.h index d9ad5a5a66..0ca1b00e32 100644 --- a/gnss/common/utils/default/include/Utils.h +++ b/gnss/common/utils/default/include/Utils.h @@ -17,6 +17,7 @@ #ifndef android_hardware_gnss_common_default_Utils_H_ #define android_hardware_gnss_common_default_Utils_H_ +#include #include #include #include @@ -28,28 +29,22 @@ namespace hardware { namespace gnss { namespace common { -using GnssDataV2_0 = V2_0::IGnssMeasurementCallback::GnssData; -using GnssDataV2_1 = V2_1::IGnssMeasurementCallback::GnssData; -using GnssSvInfoV1_0 = V1_0::IGnssCallback::GnssSvInfo; -using GnssSvInfoV2_0 = V2_0::IGnssCallback::GnssSvInfo; -using GnssSvInfoV2_1 = V2_1::IGnssCallback::GnssSvInfo; -using GnssAntennaInfo = ::android::hardware::gnss::V2_1::IGnssAntennaInfoCallback::GnssAntennaInfo; -using Row = ::android::hardware::gnss::V2_1::IGnssAntennaInfoCallback::Row; -using Coord = ::android::hardware::gnss::V2_1::IGnssAntennaInfoCallback::Coord; - struct Utils { - static GnssDataV2_0 getMockMeasurementV2_0(); - static GnssDataV2_1 getMockMeasurementV2_1(); + static aidl::android::hardware::gnss::GnssData getMockMeasurement(); + static V2_0::IGnssMeasurementCallback::GnssData getMockMeasurementV2_0(); + static V2_1::IGnssMeasurementCallback::GnssData getMockMeasurementV2_1(); static V2_0::GnssLocation getMockLocationV2_0(); static V1_0::GnssLocation getMockLocationV1_0(); - static hidl_vec getMockSvInfoListV2_1(); - static GnssSvInfoV2_1 getMockSvInfoV2_1(GnssSvInfoV2_0 gnssSvInfoV2_0, float basebandCN0DbHz); - static GnssSvInfoV2_0 getMockSvInfoV2_0(GnssSvInfoV1_0 gnssSvInfoV1_0, - V2_0::GnssConstellationType type); - static GnssSvInfoV1_0 getMockSvInfoV1_0(int16_t svid, V1_0::GnssConstellationType type, - float cN0DbHz, float elevationDegrees, - float azimuthDegrees); - static hidl_vec getMockAntennaInfos(); + static hidl_vec getMockSvInfoListV2_1(); + static V2_1::IGnssCallback::GnssSvInfo getMockSvInfoV2_1( + V2_0::IGnssCallback::GnssSvInfo gnssSvInfoV2_0, float basebandCN0DbHz); + static V2_0::IGnssCallback::GnssSvInfo getMockSvInfoV2_0( + V1_0::IGnssCallback::GnssSvInfo gnssSvInfoV1_0, V2_0::GnssConstellationType type); + static V1_0::IGnssCallback::GnssSvInfo getMockSvInfoV1_0(int16_t svid, + V1_0::GnssConstellationType type, + float cN0DbHz, float elevationDegrees, + float azimuthDegrees); + static hidl_vec getMockAntennaInfos(); }; } // namespace common diff --git a/gnss/common/utils/default/include/v2_1/GnssAntennaInfo.h b/gnss/common/utils/default/include/v2_1/GnssAntennaInfo.h index e74ff54839..a2324994cc 100644 --- a/gnss/common/utils/default/include/v2_1/GnssAntennaInfo.h +++ b/gnss/common/utils/default/include/v2_1/GnssAntennaInfo.h @@ -23,29 +23,25 @@ namespace android::hardware::gnss::V2_1::implementation { -using ::android::sp; -using ::android::hardware::Return; -using ::android::hardware::Void; -using IGnssAntennaInfo = ::android::hardware::gnss::V2_1::IGnssAntennaInfo; -using IGnssAntennaInfoCallback = ::android::hardware::gnss::V2_1::IGnssAntennaInfoCallback; - -struct GnssAntennaInfo : public IGnssAntennaInfo { +struct GnssAntennaInfo : public ::android::hardware::gnss::V2_1::IGnssAntennaInfo { GnssAntennaInfo(); ~GnssAntennaInfo(); // Methods from ::android::hardware::gnss::V2_1::IGnssAntennaInfo follow. Return setCallback( - const sp& callback) override; + const sp<::android::hardware::gnss::V2_1::IGnssAntennaInfoCallback>& callback) override; Return close() override; private: void start(); void stop(); void reportAntennaInfo( - const hidl_vec& antennaInfo) const; + const hidl_vec< + ::android::hardware::gnss::V2_1::IGnssAntennaInfoCallback::GnssAntennaInfo>& + antennaInfo) const; // Guarded by mMutex - static sp sCallback; + static sp<::android::hardware::gnss::V2_1::IGnssAntennaInfoCallback> sCallback; std::atomic mMinIntervalMillis; std::atomic mIsActive; diff --git a/gnss/common/utils/default/include/v2_1/GnssConfiguration.h b/gnss/common/utils/default/include/v2_1/GnssConfiguration.h index 8463a5caa2..2cfb38f4f9 100644 --- a/gnss/common/utils/default/include/v2_1/GnssConfiguration.h +++ b/gnss/common/utils/default/include/v2_1/GnssConfiguration.h @@ -25,35 +25,27 @@ namespace android::hardware::gnss::V2_1::implementation { -using ::android::sp; -using ::android::hardware::hidl_array; -using ::android::hardware::hidl_memory; -using ::android::hardware::hidl_string; -using ::android::hardware::hidl_vec; -using ::android::hardware::Return; -using ::android::hardware::Void; - -using BlacklistedSourceV2_1 = - ::android::hardware::gnss::V2_1::IGnssConfiguration::BlacklistedSource; -using GnssConstellationTypeV2_0 = V2_0::GnssConstellationType; -using GnssSvInfoV2_1 = V2_1::IGnssCallback::GnssSvInfo; - struct BlacklistedSourceHashV2_1 { - inline int operator()(const BlacklistedSourceV2_1& source) const { + inline int operator()( + const ::android::hardware::gnss::V2_1::IGnssConfiguration::BlacklistedSource& source) + const { return int(source.constellation) * 1000 + int(source.svid); } }; struct BlacklistedSourceEqualV2_1 { - inline bool operator()(const BlacklistedSourceV2_1& s1, const BlacklistedSourceV2_1& s2) const { + inline bool operator()( + const ::android::hardware::gnss::V2_1::IGnssConfiguration::BlacklistedSource& s1, + const ::android::hardware::gnss::V2_1::IGnssConfiguration::BlacklistedSource& s2) + const { return (s1.constellation == s2.constellation) && (s1.svid == s2.svid); } }; using BlacklistedSourceSetV2_1 = - std::unordered_set; -using BlacklistedConstellationSetV2_1 = std::unordered_set; + std::unordered_set<::android::hardware::gnss::V2_1::IGnssConfiguration::BlacklistedSource, + BlacklistedSourceHashV2_1, BlacklistedSourceEqualV2_1>; +using BlacklistedConstellationSetV2_1 = std::unordered_set; struct GnssConfiguration : public IGnssConfiguration { // Methods from ::android::hardware::gnss::V1_0::IGnssConfiguration follow. @@ -78,7 +70,7 @@ struct GnssConfiguration : public IGnssConfiguration { Return setBlacklist_2_1( const hidl_vec& blacklist) override; - Return isBlacklistedV2_1(const GnssSvInfoV2_1& gnssSvInfo) const; + Return isBlacklistedV2_1(const V2_1::IGnssCallback::GnssSvInfo& gnssSvInfo) const; private: mutable std::recursive_mutex mMutex; diff --git a/gnss/common/utils/default/include/v2_1/GnssDebug.h b/gnss/common/utils/default/include/v2_1/GnssDebug.h index 8580989c6a..481de59901 100644 --- a/gnss/common/utils/default/include/v2_1/GnssDebug.h +++ b/gnss/common/utils/default/include/v2_1/GnssDebug.h @@ -21,15 +21,8 @@ namespace android::hardware::gnss::V1_1::implementation { -using ::android::sp; -using ::android::hardware::hidl_string; -using ::android::hardware::hidl_vec; -using ::android::hardware::Return; -using ::android::hardware::Void; -using V1_0::IGnssDebug; - /* Interface for GNSS Debug support. */ -struct GnssDebug : public IGnssDebug { +struct GnssDebug : public V1_0::IGnssDebug { /* * Methods from ::android::hardware::gnss::V1_0::IGnssDebug follow. * These declarations were generated from IGnssDebug.hal. diff --git a/gnss/common/utils/default/include/v2_1/GnssMeasurement.h b/gnss/common/utils/default/include/v2_1/GnssMeasurement.h index 1d1fc9d712..db8407b4ef 100644 --- a/gnss/common/utils/default/include/v2_1/GnssMeasurement.h +++ b/gnss/common/utils/default/include/v2_1/GnssMeasurement.h @@ -25,17 +25,6 @@ namespace android::hardware::gnss::V2_1::implementation { -using GnssDataV2_1 = V2_1::IGnssMeasurementCallback::GnssData; -using GnssDataV2_0 = V2_0::IGnssMeasurementCallback::GnssData; - -using ::android::sp; -using ::android::hardware::hidl_array; -using ::android::hardware::hidl_memory; -using ::android::hardware::hidl_string; -using ::android::hardware::hidl_vec; -using ::android::hardware::Return; -using ::android::hardware::Void; - struct GnssMeasurement : public IGnssMeasurement { GnssMeasurement(); ~GnssMeasurement(); @@ -59,8 +48,8 @@ struct GnssMeasurement : public IGnssMeasurement { private: void start(); void stop(); - void reportMeasurement(const GnssDataV2_0&); - void reportMeasurement(const GnssDataV2_1&); + void reportMeasurement(const V2_0::IGnssMeasurementCallback::GnssData&); + void reportMeasurement(const V2_1::IGnssMeasurementCallback::GnssData&); // Guarded by mMutex static sp sCallback_2_1; diff --git a/gnss/common/utils/default/include/v2_1/GnssMeasurementCorrections.h b/gnss/common/utils/default/include/v2_1/GnssMeasurementCorrections.h index eaa7659c6b..54045ad897 100644 --- a/gnss/common/utils/default/include/v2_1/GnssMeasurementCorrections.h +++ b/gnss/common/utils/default/include/v2_1/GnssMeasurementCorrections.h @@ -22,9 +22,6 @@ namespace android::hardware::gnss::measurement_corrections::V1_1::implementation { -using ::android::sp; -using ::android::hardware::Return; - struct GnssMeasurementCorrections : public IMeasurementCorrections { GnssMeasurementCorrections(); ~GnssMeasurementCorrections(); diff --git a/gnss/common/utils/default/include/v2_1/GnssTemplate.h b/gnss/common/utils/default/include/v2_1/GnssTemplate.h index 4d1baa713a..4d4ec93593 100644 --- a/gnss/common/utils/default/include/v2_1/GnssTemplate.h +++ b/gnss/common/utils/default/include/v2_1/GnssTemplate.h @@ -39,16 +39,6 @@ namespace android::hardware::gnss::common::implementation { -using GnssSvInfo = V2_1::IGnssCallback::GnssSvInfo; - -using common::NmeaFixInfo; -using common::Utils; -using measurement_corrections::V1_1::implementation::GnssMeasurementCorrections; - -using V2_1::implementation::GnssAntennaInfo; -using V2_1::implementation::GnssConfiguration; -using V2_1::implementation::GnssMeasurement; - constexpr int INPUT_BUFFER_SIZE = 128; constexpr char CMD_GET_LOCATION[] = "CMD_GET_LOCATION"; constexpr char GNSS_PATH[] = "/dev/gnss0"; @@ -120,7 +110,7 @@ struct GnssTemplate : public T_IGnss { std::unique_ptr getLocationFromHW(); void reportLocation(const V2_0::GnssLocation&) const; void reportLocation(const V1_0::GnssLocation&) const; - void reportSvStatus(const hidl_vec&) const; + void reportSvStatus(const hidl_vec&) const; Return help(const hidl_handle& fd); Return setLocation(const hidl_handle& fd, const hidl_vec& options); @@ -131,15 +121,15 @@ struct GnssTemplate : public T_IGnss { static sp sGnssCallback_1_0; std::atomic mMinIntervalMs; - sp mGnssConfiguration; + sp mGnssConfiguration; std::atomic mIsActive; std::atomic mHardwareModeChecked; std::atomic mGnssFd; std::thread mThread; mutable std::mutex mMutex; - virtual hidl_vec filterBlocklistedSatellitesV2_1( - hidl_vec gnssSvInfoList); + virtual hidl_vec filterBlocklistedSatellitesV2_1( + hidl_vec gnssSvInfoList); }; template @@ -154,7 +144,7 @@ sp GnssTemplate::sGnssCallback_1_0 = nullptr; template GnssTemplate::GnssTemplate() : mMinIntervalMs(1000), - mGnssConfiguration{new GnssConfiguration()}, + mGnssConfiguration{new V2_1::implementation::GnssConfiguration()}, mHardwareModeChecked(false), mGnssFd(-1) {} @@ -237,8 +227,8 @@ Return GnssTemplate::start() { } template -hidl_vec GnssTemplate::filterBlocklistedSatellitesV2_1( - hidl_vec gnssSvInfoList) { +hidl_vec GnssTemplate::filterBlocklistedSatellitesV2_1( + hidl_vec gnssSvInfoList) { ALOGD("filterBlocklistedSatellitesV2_1"); for (uint32_t i = 0; i < gnssSvInfoList.size(); i++) { if (mGnssConfiguration->isBlacklistedV2_1(gnssSvInfoList[i])) { @@ -348,7 +338,7 @@ Return> GnssTemplate::getExtensionGnssNi() { template Return> GnssTemplate::getExtensionGnssMeasurement() { ALOGD("Gnss::getExtensionGnssMeasurement"); - return new GnssMeasurement(); + return new V2_1::implementation::GnssMeasurement(); } template @@ -501,14 +491,14 @@ Return> GnssTemplate::getExtensionAGnssRil_2_0() { template Return> GnssTemplate::getExtensionGnssMeasurement_2_0() { ALOGD("Gnss::getExtensionGnssMeasurement_2_0"); - return new GnssMeasurement(); + return new V2_1::implementation::GnssMeasurement(); } template Return> GnssTemplate::getExtensionMeasurementCorrections() { ALOGD("Gnss::getExtensionMeasurementCorrections()"); - return new GnssMeasurementCorrections(); + return new measurement_corrections::V1_1::implementation::GnssMeasurementCorrections(); } template @@ -569,7 +559,7 @@ Return GnssTemplate::setCallback_2_1(const sp Return> GnssTemplate::getExtensionGnssMeasurement_2_1() { ALOGD("Gnss::getExtensionGnssMeasurement_2_1"); - return new GnssMeasurement(); + return new V2_1::implementation::GnssMeasurement(); } template @@ -582,17 +572,18 @@ template Return> GnssTemplate::getExtensionMeasurementCorrections_1_1() { ALOGD("Gnss::getExtensionMeasurementCorrections_1_1()"); - return new GnssMeasurementCorrections(); + return new measurement_corrections::V1_1::implementation::GnssMeasurementCorrections(); } template Return> GnssTemplate::getExtensionGnssAntennaInfo() { ALOGD("Gnss::getExtensionGnssAntennaInfo"); - return new GnssAntennaInfo(); + return new V2_1::implementation::GnssAntennaInfo(); } template -void GnssTemplate::reportSvStatus(const hidl_vec& svInfoList) const { +void GnssTemplate::reportSvStatus( + const hidl_vec& svInfoList) const { std::unique_lock lock(mMutex); // TODO(skz): update this to call 2_0 callback if non-null if (sGnssCallback_2_1 == nullptr) { diff --git a/gnss/common/utils/default/v2_1/GnssConfiguration.cpp b/gnss/common/utils/default/v2_1/GnssConfiguration.cpp index 8b30701ea1..be974bcdb2 100644 --- a/gnss/common/utils/default/v2_1/GnssConfiguration.cpp +++ b/gnss/common/utils/default/v2_1/GnssConfiguration.cpp @@ -21,6 +21,9 @@ namespace android::hardware::gnss::V2_1::implementation { +using GnssSvInfoV2_1 = V2_1::IGnssCallback::GnssSvInfo; +using BlacklistedSourceV2_1 = V2_1::IGnssConfiguration::BlacklistedSource; + // Methods from ::android::hardware::gnss::V1_0::IGnssConfiguration follow. Return GnssConfiguration::setSuplEs(bool enable) { ALOGD("setSuplEs enable: %d", enable); @@ -69,7 +72,7 @@ Return GnssConfiguration::setEsExtensionSec(uint32_t emergencyExtensionSec // Methods from ::android::hardware::gnss::V2_1::IGnssConfiguration follow. Return GnssConfiguration::setBlacklist_2_1( - const hidl_vec& sourceList) { + const hidl_vec& sourceList) { std::unique_lock lock(mMutex); mBlacklistedConstellationSet.clear(); mBlacklistedSourceSet.clear(); diff --git a/gnss/common/utils/default/v2_1/GnssMeasurement.cpp b/gnss/common/utils/default/v2_1/GnssMeasurement.cpp index 7d3a002ea7..887cb5a136 100644 --- a/gnss/common/utils/default/v2_1/GnssMeasurement.cpp +++ b/gnss/common/utils/default/v2_1/GnssMeasurement.cpp @@ -114,7 +114,7 @@ void GnssMeasurement::stop() { } } -void GnssMeasurement::reportMeasurement(const GnssDataV2_0& data) { +void GnssMeasurement::reportMeasurement(const V2_0::IGnssMeasurementCallback::GnssData& data) { ALOGD("reportMeasurement()"); std::unique_lock lock(mMutex); if (sCallback_2_0 == nullptr) { @@ -127,7 +127,7 @@ void GnssMeasurement::reportMeasurement(const GnssDataV2_0& data) { } } -void GnssMeasurement::reportMeasurement(const GnssDataV2_1& data) { +void GnssMeasurement::reportMeasurement(const V2_1::IGnssMeasurementCallback::GnssData& data) { ALOGD("reportMeasurement()"); std::unique_lock lock(mMutex); if (sCallback_2_1 == nullptr) { diff --git a/gnss/common/utils/vts/include/v2_1/gnss_hal_test_template.h b/gnss/common/utils/vts/include/v2_1/gnss_hal_test_template.h index 1439158266..fec3503cd6 100644 --- a/gnss/common/utils/vts/include/v2_1/gnss_hal_test_template.h +++ b/gnss/common/utils/vts/include/v2_1/gnss_hal_test_template.h @@ -23,36 +23,10 @@ #include #include -using ::android::hardware::gnss::common::Utils; - -using android::hardware::hidl_vec; -using android::hardware::Return; -using android::hardware::Void; - -using android::hardware::gnss::common::GnssCallback; -using android::hardware::gnss::common::GnssCallbackEventQueue; -using android::hardware::gnss::measurement_corrections::V1_0::IMeasurementCorrectionsCallback; -using android::hardware::gnss::V1_0::GnssLocationFlags; -using android::hardware::gnss::V2_0::GnssConstellationType; -using android::hardware::gnss::V2_1::IGnssAntennaInfo; -using android::hardware::gnss::V2_1::IGnssAntennaInfoCallback; - -using GnssLocation_1_0 = android::hardware::gnss::V1_0::GnssLocation; -using GnssLocation_2_0 = android::hardware::gnss::V2_0::GnssLocation; - -using IGnssCallback_1_0 = android::hardware::gnss::V1_0::IGnssCallback; -using IGnssCallback_2_0 = android::hardware::gnss::V2_0::IGnssCallback; -using IGnssCallback_2_1 = android::hardware::gnss::V2_1::IGnssCallback; - -using IGnssMeasurementCallback_1_0 = android::hardware::gnss::V1_0::IGnssMeasurementCallback; -using IGnssMeasurementCallback_1_1 = android::hardware::gnss::V1_1::IGnssMeasurementCallback; -using IGnssMeasurementCallback_2_0 = android::hardware::gnss::V2_0::IGnssMeasurementCallback; -using IGnssMeasurementCallback_2_1 = android::hardware::gnss::V2_1::IGnssMeasurementCallback; - -using android::sp; - #define TIMEOUT_SEC 2 // for basic commands/responses +namespace android::hardware::gnss::common { + // The main test class for GNSS HAL. template class GnssHalTestTemplate : public testing::TestWithParam { @@ -62,34 +36,37 @@ class GnssHalTestTemplate : public testing::TestWithParam { virtual void TearDown() override; /* Callback class for GnssMeasurement. */ - class GnssMeasurementCallback : public IGnssMeasurementCallback_2_1 { + class GnssMeasurementCallback : public V2_1::IGnssMeasurementCallback { public: - GnssCallbackEventQueue measurement_cbq_; + GnssCallbackEventQueue measurement_cbq_; GnssMeasurementCallback() : measurement_cbq_("measurement"){}; virtual ~GnssMeasurementCallback() = default; // Methods from V1_0::IGnssMeasurementCallback follow. - Return GnssMeasurementCb(const IGnssMeasurementCallback_1_0::GnssData&) override { + Return GnssMeasurementCb(const V1_0::IGnssMeasurementCallback::GnssData&) override { return Void(); } // Methods from V1_1::IGnssMeasurementCallback follow. - Return gnssMeasurementCb(const IGnssMeasurementCallback_1_1::GnssData&) override { + Return gnssMeasurementCb(const V1_1::IGnssMeasurementCallback::GnssData&) override { return Void(); } // Methods from V2_0::IGnssMeasurementCallback follow. - Return gnssMeasurementCb_2_0(const IGnssMeasurementCallback_2_0::GnssData&) override { + Return gnssMeasurementCb_2_0( + const V2_0::IGnssMeasurementCallback::GnssData&) override { return Void(); } // Methods from V2_1::IGnssMeasurementCallback follow. - Return gnssMeasurementCb_2_1(const IGnssMeasurementCallback_2_1::GnssData&) override; + Return gnssMeasurementCb_2_1( + const V2_1::IGnssMeasurementCallback::GnssData&) override; }; /* Callback class for GnssMeasurementCorrections. */ - class GnssMeasurementCorrectionsCallback : public IMeasurementCorrectionsCallback { + class GnssMeasurementCorrectionsCallback + : public measurement_corrections::V1_0::IMeasurementCorrectionsCallback { public: uint32_t last_capabilities_; GnssCallbackEventQueue capabilities_cbq_; @@ -102,9 +79,9 @@ class GnssHalTestTemplate : public testing::TestWithParam { }; /* Callback class for GnssAntennaInfo. */ - class GnssAntennaInfoCallback : public IGnssAntennaInfoCallback { + class GnssAntennaInfoCallback : public V2_1::IGnssAntennaInfoCallback { public: - GnssCallbackEventQueue> + GnssCallbackEventQueue> antenna_info_cbq_; GnssAntennaInfoCallback() : antenna_info_cbq_("info"){}; @@ -112,7 +89,7 @@ class GnssHalTestTemplate : public testing::TestWithParam { // Methods from V2_1::GnssAntennaInfoCallback follow. Return gnssAntennaInfoCb( - const hidl_vec& gnssAntennaInfos); + const hidl_vec& gnssAntennaInfos); }; /* @@ -138,7 +115,7 @@ class GnssHalTestTemplate : public testing::TestWithParam { * * check_speed: true if speed related fields are also verified. */ - void CheckLocation(const GnssLocation_2_0& location, const bool check_speed); + void CheckLocation(const V2_0::GnssLocation& location, const bool check_speed); /* * StartAndCheckLocations: @@ -170,7 +147,7 @@ class GnssHalTestTemplate : public testing::TestWithParam { * Note that location is not stopped in this method. The client should call * StopAndClearLocations() after the call. */ - GnssConstellationType startLocationAndGetNonGpsConstellation( + V2_0::GnssConstellationType startLocationAndGetNonGpsConstellation( const int locations_to_await, const int gnss_sv_info_list_timeout); sp gnss_hal_; // GNSS HAL to call into @@ -283,7 +260,7 @@ bool GnssHalTestTemplate::StartAndCheckFirstLocation() { } template -void GnssHalTestTemplate::CheckLocation(const GnssLocation_2_0& location, +void GnssHalTestTemplate::CheckLocation(const V2_0::GnssLocation& location, bool check_speed) { const bool check_more_accuracies = (gnss_cb_->info_cbq_.calledCount() > 0 && gnss_cb_->last_info_.yearOfHw >= 2017); @@ -315,7 +292,7 @@ void GnssHalTestTemplate::StartAndCheckLocations(int count) { } template -GnssConstellationType GnssHalTestTemplate::startLocationAndGetNonGpsConstellation( +V2_0::GnssConstellationType GnssHalTestTemplate::startLocationAndGetNonGpsConstellation( const int locations_to_await, const int gnss_sv_info_list_timeout) { gnss_cb_->location_cbq_.reset(); StartAndCheckLocations(locations_to_await); @@ -328,29 +305,29 @@ GnssConstellationType GnssHalTestTemplate::startLocationAndGetNonGpsCon sv_info_list_cbq_size, locations_to_await, location_called_count); // Find first non-GPS constellation to blacklist - GnssConstellationType constellation_to_blacklist = GnssConstellationType::UNKNOWN; + V2_0::GnssConstellationType constellation_to_blacklist = V2_0::GnssConstellationType::UNKNOWN; for (int i = 0; i < sv_info_list_cbq_size; ++i) { - hidl_vec sv_info_vec; + hidl_vec sv_info_vec; gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, gnss_sv_info_list_timeout); for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) { const auto& gnss_sv = sv_info_vec[iSv]; - if ((gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX) && - (gnss_sv.v2_0.constellation != GnssConstellationType::UNKNOWN) && - (gnss_sv.v2_0.constellation != GnssConstellationType::GPS)) { + if ((gnss_sv.v2_0.v1_0.svFlag & V1_0::IGnssCallback::GnssSvFlags::USED_IN_FIX) && + (gnss_sv.v2_0.constellation != V2_0::GnssConstellationType::UNKNOWN) && + (gnss_sv.v2_0.constellation != V2_0::GnssConstellationType::GPS)) { // found a non-GPS constellation constellation_to_blacklist = gnss_sv.v2_0.constellation; break; } } - if (constellation_to_blacklist != GnssConstellationType::UNKNOWN) { + if (constellation_to_blacklist != V2_0::GnssConstellationType::UNKNOWN) { break; } } - if (constellation_to_blacklist == GnssConstellationType::UNKNOWN) { + if (constellation_to_blacklist == V2_0::GnssConstellationType::UNKNOWN) { ALOGI("No non-GPS constellations found, constellation blacklist test less effective."); // Proceed functionally to blacklist something. - constellation_to_blacklist = GnssConstellationType::GLONASS; + constellation_to_blacklist = V2_0::GnssConstellationType::GLONASS; } return constellation_to_blacklist; @@ -358,7 +335,7 @@ GnssConstellationType GnssHalTestTemplate::startLocationAndGetNonGpsCon template Return GnssHalTestTemplate::GnssMeasurementCallback::gnssMeasurementCb_2_1( - const IGnssMeasurementCallback_2_1::GnssData& data) { + const V2_1::IGnssMeasurementCallback::GnssData& data) { ALOGD("GnssMeasurement v2.1 received. Size = %d", (int)data.measurements.size()); measurement_cbq_.store(data); return Void(); @@ -374,8 +351,10 @@ Return GnssHalTestTemplate::GnssMeasurementCorrectionsCallback::s template Return GnssHalTestTemplate::GnssAntennaInfoCallback::gnssAntennaInfoCb( - const hidl_vec& gnssAntennaInfos) { + const hidl_vec& gnssAntennaInfos) { ALOGD("GnssAntennaInfo v2.1 received. Size = %d", (int)gnssAntennaInfos.size()); antenna_info_cbq_.store(gnssAntennaInfos); return Void(); } + +} // namespace android::hardware::gnss::common -- GitLab From 61f508e018cff89c93a7e08b3dbde1eb6a2155df Mon Sep 17 00:00:00 2001 From: Michael Butler Date: Sun, 22 Nov 2020 20:25:34 -0800 Subject: [PATCH 320/790] Cleanup how transport errors are handled in NN utils Prior to this change, whenever the NN utility code encountered a HIDL transport error, the error message would display the file and line number of the "handleTransportError" function itself. This change introduces a new macro "HANDLE_TRANSPORT_FAILURE" that handles the transport error in a similar way but now the error message displays the file and line number of where the macro is called. Bug: N/A Test: mma Change-Id: I35b34f8f5be52b7fcff0fbb58a37ab2b8c7dd8bb --- neuralnetworks/1.0/utils/src/Device.cpp | 9 ++- .../1.0/utils/src/PreparedModel.cpp | 3 +- neuralnetworks/1.1/utils/src/Device.cpp | 9 ++- neuralnetworks/1.2/utils/src/Device.cpp | 19 ++--- .../1.2/utils/src/PreparedModel.cpp | 5 +- neuralnetworks/1.3/utils/src/Buffer.cpp | 4 +- neuralnetworks/1.3/utils/src/Device.cpp | 13 ++-- .../1.3/utils/src/PreparedModel.cpp | 9 +-- .../common/include/nnapi/hal/HandleError.h | 77 +++++++------------ .../utils/common/src/ProtectCallback.cpp | 2 +- 10 files changed, 66 insertions(+), 84 deletions(-) diff --git a/neuralnetworks/1.0/utils/src/Device.cpp b/neuralnetworks/1.0/utils/src/Device.cpp index ab3f5afb23..285c515c20 100644 --- a/neuralnetworks/1.0/utils/src/Device.cpp +++ b/neuralnetworks/1.0/utils/src/Device.cpp @@ -56,7 +56,7 @@ nn::GeneralResult initCapabilities(V1_0::IDevice* device) { }; const auto ret = device->getCapabilities(cb); - NN_TRY(hal::utils::handleTransportError(ret)); + HANDLE_TRANSPORT_FAILURE(ret); return result; } @@ -119,7 +119,8 @@ std::pair Device::getNumberOfCacheFilesNeeded() const { nn::GeneralResult Device::wait() const { const auto ret = kDevice->ping(); - return hal::utils::handleTransportError(ret); + HANDLE_TRANSPORT_FAILURE(ret); + return {}; } nn::GeneralResult> Device::getSupportedOperations(const nn::Model& model) const { @@ -148,7 +149,7 @@ nn::GeneralResult> Device::getSupportedOperations(const nn::Mo }; const auto ret = kDevice->getSupportedOperations(hidlModel, cb); - NN_TRY(hal::utils::handleTransportError(ret)); + HANDLE_TRANSPORT_FAILURE(ret); return result; } @@ -168,7 +169,7 @@ nn::GeneralResult Device::prepareModel( const auto scoped = kDeathHandler.protectCallback(cb.get()); const auto ret = kDevice->prepareModel(hidlModel, cb); - const auto status = NN_TRY(hal::utils::handleTransportError(ret)); + const auto status = HANDLE_TRANSPORT_FAILURE(ret); if (status != ErrorStatus::NONE) { const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); return NN_ERROR(canonical) << "prepareModel failed with " << toString(status); diff --git a/neuralnetworks/1.0/utils/src/PreparedModel.cpp b/neuralnetworks/1.0/utils/src/PreparedModel.cpp index 80f885a64e..46dd3f8254 100644 --- a/neuralnetworks/1.0/utils/src/PreparedModel.cpp +++ b/neuralnetworks/1.0/utils/src/PreparedModel.cpp @@ -67,8 +67,7 @@ nn::ExecutionResult, nn::Timing>> Prepare const auto scoped = kDeathHandler.protectCallback(cb.get()); const auto ret = kPreparedModel->execute(hidlRequest, cb); - const auto status = - NN_TRY(hal::utils::makeExecutionFailure(hal::utils::handleTransportError(ret))); + const auto status = HANDLE_TRANSPORT_FAILURE(ret); if (status != ErrorStatus::NONE) { const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); return NN_ERROR(canonical) << "execute failed with " << toString(status); diff --git a/neuralnetworks/1.1/utils/src/Device.cpp b/neuralnetworks/1.1/utils/src/Device.cpp index e45b17ec6e..f73d3f8253 100644 --- a/neuralnetworks/1.1/utils/src/Device.cpp +++ b/neuralnetworks/1.1/utils/src/Device.cpp @@ -57,7 +57,7 @@ nn::GeneralResult initCapabilities(V1_1::IDevice* device) { }; const auto ret = device->getCapabilities_1_1(cb); - NN_TRY(hal::utils::handleTransportError(ret)); + HANDLE_TRANSPORT_FAILURE(ret); return result; } @@ -120,7 +120,8 @@ std::pair Device::getNumberOfCacheFilesNeeded() const { nn::GeneralResult Device::wait() const { const auto ret = kDevice->ping(); - return hal::utils::handleTransportError(ret); + HANDLE_TRANSPORT_FAILURE(ret); + return {}; } nn::GeneralResult> Device::getSupportedOperations(const nn::Model& model) const { @@ -150,7 +151,7 @@ nn::GeneralResult> Device::getSupportedOperations(const nn::Mo }; const auto ret = kDevice->getSupportedOperations_1_1(hidlModel, cb); - NN_TRY(hal::utils::handleTransportError(ret)); + HANDLE_TRANSPORT_FAILURE(ret); return result; } @@ -171,7 +172,7 @@ nn::GeneralResult Device::prepareModel( const auto scoped = kDeathHandler.protectCallback(cb.get()); const auto ret = kDevice->prepareModel_1_1(hidlModel, hidlPreference, cb); - const auto status = NN_TRY(hal::utils::handleTransportError(ret)); + const auto status = HANDLE_TRANSPORT_FAILURE(ret); if (status != V1_0::ErrorStatus::NONE) { const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); return NN_ERROR(canonical) << "prepareModel failed with " << toString(status); diff --git a/neuralnetworks/1.2/utils/src/Device.cpp b/neuralnetworks/1.2/utils/src/Device.cpp index 967a252c88..0061065f0b 100644 --- a/neuralnetworks/1.2/utils/src/Device.cpp +++ b/neuralnetworks/1.2/utils/src/Device.cpp @@ -59,7 +59,7 @@ nn::GeneralResult initCapabilities(V1_2::IDevice* device) { }; const auto ret = device->getCapabilities_1_2(cb); - NN_TRY(hal::utils::handleTransportError(ret)); + HANDLE_TRANSPORT_FAILURE(ret); return result; } @@ -81,7 +81,7 @@ nn::GeneralResult initVersionString(V1_2::IDevice* device) { }; const auto ret = device->getVersionString(cb); - NN_TRY(hal::utils::handleTransportError(ret)); + HANDLE_TRANSPORT_FAILURE(ret); return result; } @@ -101,7 +101,7 @@ nn::GeneralResult initDeviceType(V1_2::IDevice* device) { }; const auto ret = device->getType(cb); - NN_TRY(hal::utils::handleTransportError(ret)); + HANDLE_TRANSPORT_FAILURE(ret); return result; } @@ -121,7 +121,7 @@ nn::GeneralResult> initExtensions(V1_2::IDevice* devi }; const auto ret = device->getSupportedExtensions(cb); - NN_TRY(hal::utils::handleTransportError(ret)); + HANDLE_TRANSPORT_FAILURE(ret); return result; } @@ -144,7 +144,7 @@ nn::GeneralResult> initNumberOfCacheFilesNeeded( }; const auto ret = device->getNumberOfCacheFilesNeeded(cb); - NN_TRY(hal::utils::handleTransportError(ret)); + HANDLE_TRANSPORT_FAILURE(ret); return result; } @@ -217,7 +217,8 @@ std::pair Device::getNumberOfCacheFilesNeeded() const { nn::GeneralResult Device::wait() const { const auto ret = kDevice->ping(); - return hal::utils::handleTransportError(ret); + HANDLE_TRANSPORT_FAILURE(ret); + return {}; } nn::GeneralResult> Device::getSupportedOperations(const nn::Model& model) const { @@ -247,7 +248,7 @@ nn::GeneralResult> Device::getSupportedOperations(const nn::Mo }; const auto ret = kDevice->getSupportedOperations_1_2(hidlModel, cb); - NN_TRY(hal::utils::handleTransportError(ret)); + HANDLE_TRANSPORT_FAILURE(ret); return result; } @@ -272,7 +273,7 @@ nn::GeneralResult Device::prepareModel( const auto ret = kDevice->prepareModel_1_2(hidlModel, hidlPreference, hidlModelCache, hidlDataCache, hidlToken, cb); - const auto status = NN_TRY(hal::utils::handleTransportError(ret)); + const auto status = HANDLE_TRANSPORT_FAILURE(ret); if (status != V1_0::ErrorStatus::NONE) { const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); return NN_ERROR(canonical) << "prepareModel_1_2 failed with " << toString(status); @@ -292,7 +293,7 @@ nn::GeneralResult Device::prepareModelFromCache( const auto scoped = kDeathHandler.protectCallback(cb.get()); const auto ret = kDevice->prepareModelFromCache(hidlModelCache, hidlDataCache, hidlToken, cb); - const auto status = NN_TRY(hal::utils::handleTransportError(ret)); + const auto status = HANDLE_TRANSPORT_FAILURE(ret); if (status != V1_0::ErrorStatus::NONE) { const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); return NN_ERROR(canonical) << "prepareModelFromCache failed with " << toString(status); diff --git a/neuralnetworks/1.2/utils/src/PreparedModel.cpp b/neuralnetworks/1.2/utils/src/PreparedModel.cpp index b5a3389e6c..dad9a7e74b 100644 --- a/neuralnetworks/1.2/utils/src/PreparedModel.cpp +++ b/neuralnetworks/1.2/utils/src/PreparedModel.cpp @@ -83,7 +83,7 @@ PreparedModel::executeSynchronously(const V1_0::Request& request, MeasureTiming }; const auto ret = kPreparedModel->executeSynchronously(request, measure, cb); - NN_TRY(hal::utils::makeExecutionFailure(hal::utils::handleTransportError(ret))); + HANDLE_TRANSPORT_FAILURE(ret); return result; } @@ -94,8 +94,7 @@ PreparedModel::executeAsynchronously(const V1_0::Request& request, MeasureTiming const auto scoped = kDeathHandler.protectCallback(cb.get()); const auto ret = kPreparedModel->execute_1_2(request, measure, cb); - const auto status = - NN_TRY(hal::utils::makeExecutionFailure(hal::utils::handleTransportError(ret))); + const auto status = HANDLE_TRANSPORT_FAILURE(ret); if (status != V1_0::ErrorStatus::NONE) { const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); return NN_ERROR(canonical) << "execute failed with " << toString(status); diff --git a/neuralnetworks/1.3/utils/src/Buffer.cpp b/neuralnetworks/1.3/utils/src/Buffer.cpp index a880031ad7..ffdeccdf62 100644 --- a/neuralnetworks/1.3/utils/src/Buffer.cpp +++ b/neuralnetworks/1.3/utils/src/Buffer.cpp @@ -64,7 +64,7 @@ nn::GeneralResult Buffer::copyTo(const nn::Memory& dst) const { const auto hidlDst = NN_TRY(convert(dst)); const auto ret = kBuffer->copyTo(hidlDst); - const auto status = NN_TRY(hal::utils::handleTransportError(ret)); + const auto status = HANDLE_TRANSPORT_FAILURE(ret); if (status != ErrorStatus::NONE) { const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); return NN_ERROR(canonical) << "IBuffer::copyTo failed with " << toString(status); @@ -79,7 +79,7 @@ nn::GeneralResult Buffer::copyFrom(const nn::Memory& src, const auto hidlDimensions = hidl_vec(dimensions); const auto ret = kBuffer->copyFrom(hidlSrc, hidlDimensions); - const auto status = NN_TRY(hal::utils::handleTransportError(ret)); + const auto status = HANDLE_TRANSPORT_FAILURE(ret); if (status != ErrorStatus::NONE) { const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); return NN_ERROR(canonical) << "IBuffer::copyFrom failed with " << toString(status); diff --git a/neuralnetworks/1.3/utils/src/Device.cpp b/neuralnetworks/1.3/utils/src/Device.cpp index 7a7e2514ef..82837bac73 100644 --- a/neuralnetworks/1.3/utils/src/Device.cpp +++ b/neuralnetworks/1.3/utils/src/Device.cpp @@ -86,7 +86,7 @@ nn::GeneralResult initCapabilities(V1_3::IDevice* device) { }; const auto ret = device->getCapabilities_1_3(cb); - NN_TRY(hal::utils::handleTransportError(ret)); + HANDLE_TRANSPORT_FAILURE(ret); return result; } @@ -162,7 +162,8 @@ std::pair Device::getNumberOfCacheFilesNeeded() const { nn::GeneralResult Device::wait() const { const auto ret = kDevice->ping(); - return hal::utils::handleTransportError(ret); + HANDLE_TRANSPORT_FAILURE(ret); + return {}; } nn::GeneralResult> Device::getSupportedOperations(const nn::Model& model) const { @@ -191,7 +192,7 @@ nn::GeneralResult> Device::getSupportedOperations(const nn::Mo }; const auto ret = kDevice->getSupportedOperations_1_3(hidlModel, cb); - NN_TRY(hal::utils::handleTransportError(ret)); + HANDLE_TRANSPORT_FAILURE(ret); return result; } @@ -219,7 +220,7 @@ nn::GeneralResult Device::prepareModel( const auto ret = kDevice->prepareModel_1_3(hidlModel, hidlPreference, hidlPriority, hidlDeadline, hidlModelCache, hidlDataCache, hidlToken, cb); - const auto status = NN_TRY(hal::utils::handleTransportError(ret)); + const auto status = HANDLE_TRANSPORT_FAILURE(ret); if (status != ErrorStatus::NONE) { const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); return NN_ERROR(canonical) << "prepareModel_1_3 failed with " << toString(status); @@ -241,7 +242,7 @@ nn::GeneralResult Device::prepareModelFromCache( const auto ret = kDevice->prepareModelFromCache_1_3(hidlDeadline, hidlModelCache, hidlDataCache, hidlToken, cb); - const auto status = NN_TRY(hal::utils::handleTransportError(ret)); + const auto status = HANDLE_TRANSPORT_FAILURE(ret); if (status != ErrorStatus::NONE) { const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); return NN_ERROR(canonical) << "prepareModelFromCache_1_3 failed with " << toString(status); @@ -277,7 +278,7 @@ nn::GeneralResult Device::allocate( const auto ret = kDevice->allocate(hidlDesc, hidlPreparedModels, hidlInputRoles, hidlOutputRoles, cb); - NN_TRY(hal::utils::handleTransportError(ret)); + HANDLE_TRANSPORT_FAILURE(ret); return result; } diff --git a/neuralnetworks/1.3/utils/src/PreparedModel.cpp b/neuralnetworks/1.3/utils/src/PreparedModel.cpp index 5d82110829..49b9b0bcc3 100644 --- a/neuralnetworks/1.3/utils/src/PreparedModel.cpp +++ b/neuralnetworks/1.3/utils/src/PreparedModel.cpp @@ -89,7 +89,7 @@ convertExecuteFencedResults(const hidl_handle& syncFence, }; const auto ret = callback->getExecutionInfo(cb); - NN_TRY(hal::utils::handleTransportError(ret)); + HANDLE_TRANSPORT_FAILURE(ret); return result; }; @@ -133,7 +133,7 @@ PreparedModel::executeSynchronously(const Request& request, V1_2::MeasureTiming const auto ret = kPreparedModel->executeSynchronously_1_3(request, measure, deadline, loopTimeoutDuration, cb); - NN_TRY(hal::utils::makeExecutionFailure(hal::utils::handleTransportError(ret))); + HANDLE_TRANSPORT_FAILURE(ret); return result; } @@ -147,8 +147,7 @@ PreparedModel::executeAsynchronously(const Request& request, V1_2::MeasureTiming const auto ret = kPreparedModel->execute_1_3(request, measure, deadline, loopTimeoutDuration, cb); - const auto status = - NN_TRY(hal::utils::makeExecutionFailure(hal::utils::handleTransportError(ret))); + const auto status = HANDLE_TRANSPORT_FAILURE(ret); if (status != ErrorStatus::NONE) { const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); return NN_ERROR(canonical) << "executeAsynchronously failed with " << toString(status); @@ -230,7 +229,7 @@ PreparedModel::executeFenced(const nn::Request& request, const std::vectorexecuteFenced(hidlRequest, hidlWaitFor, hidlMeasure, hidlDeadline, hidlLoopTimeoutDuration, hidlTimeoutDurationAfterFence, cb); - NN_TRY(hal::utils::handleTransportError(ret)); + HANDLE_TRANSPORT_FAILURE(ret); auto [syncFence, callback] = NN_TRY(std::move(result)); // If executeFenced required the request memory to be moved into shared memory, block here until diff --git a/neuralnetworks/utils/common/include/nnapi/hal/HandleError.h b/neuralnetworks/utils/common/include/nnapi/hal/HandleError.h index e4046b5407..78b2a12918 100644 --- a/neuralnetworks/utils/common/include/nnapi/hal/HandleError.h +++ b/neuralnetworks/utils/common/include/nnapi/hal/HandleError.h @@ -19,65 +19,46 @@ #include #include +#include + namespace android::hardware::neuralnetworks::utils { template nn::GeneralResult handleTransportError(const hardware::Return& ret) { if (ret.isDeadObject()) { - return NN_ERROR(nn::ErrorStatus::DEAD_OBJECT) - << "Return<>::isDeadObject returned true: " << ret.description(); - } - if (!ret.isOk()) { - return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) - << "Return<>::isOk returned false: " << ret.description(); - } - return ret; -} - -template <> -inline nn::GeneralResult handleTransportError(const hardware::Return& ret) { - if (ret.isDeadObject()) { - return NN_ERROR(nn::ErrorStatus::DEAD_OBJECT) + return nn::error(nn::ErrorStatus::DEAD_OBJECT) << "Return<>::isDeadObject returned true: " << ret.description(); } if (!ret.isOk()) { - return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) + return nn::error(nn::ErrorStatus::GENERAL_FAILURE) << "Return<>::isOk returned false: " << ret.description(); } - return {}; -} - -template -nn::GeneralResult makeGeneralFailure(nn::Result result, nn::ErrorStatus status) { - if (!result.has_value()) { - return nn::error(status) << std::move(result).error(); + if constexpr (!std::is_same_v) { + return static_cast(ret); + } else { + return {}; } - return std::move(result).value(); } -template <> -inline nn::GeneralResult makeGeneralFailure(nn::Result result, nn::ErrorStatus status) { - if (!result.has_value()) { - return nn::error(status) << std::move(result).error(); - } - return {}; -} +#define HANDLE_TRANSPORT_FAILURE(ret) \ + ({ \ + auto result = ::android::hardware::neuralnetworks::utils::handleTransportError(ret); \ + if (!result.has_value()) { \ + return NN_ERROR(result.error().code) << result.error().message; \ + } \ + std::move(result).value(); \ + }) template -nn::ExecutionResult makeExecutionFailure(nn::Result result, nn::ErrorStatus status) { +nn::GeneralResult makeGeneralFailure(nn::Result result, nn::ErrorStatus status) { if (!result.has_value()) { return nn::error(status) << std::move(result).error(); } - return std::move(result).value(); -} - -template <> -inline nn::ExecutionResult makeExecutionFailure(nn::Result result, - nn::ErrorStatus status) { - if (!result.has_value()) { - return nn::error(status) << std::move(result).error(); + if constexpr (!std::is_same_v) { + return std::move(result).value(); + } else { + return {}; } - return {}; } template @@ -86,16 +67,16 @@ nn::ExecutionResult makeExecutionFailure(nn::GeneralResult result) { const auto [message, status] = std::move(result).error(); return nn::error(status) << message; } - return std::move(result).value(); + if constexpr (!std::is_same_v) { + return std::move(result).value(); + } else { + return {}; + } } -template <> -inline nn::ExecutionResult makeExecutionFailure(nn::GeneralResult result) { - if (!result.has_value()) { - const auto [message, status] = std::move(result).error(); - return nn::error(status) << message; - } - return {}; +template +nn::ExecutionResult makeExecutionFailure(nn::Result result, nn::ErrorStatus status) { + return makeExecutionFailure(makeGeneralFailure(result, status)); } } // namespace android::hardware::neuralnetworks::utils \ No newline at end of file diff --git a/neuralnetworks/utils/common/src/ProtectCallback.cpp b/neuralnetworks/utils/common/src/ProtectCallback.cpp index 1d9a3074db..abe4cb675e 100644 --- a/neuralnetworks/utils/common/src/ProtectCallback.cpp +++ b/neuralnetworks/utils/common/src/ProtectCallback.cpp @@ -58,7 +58,7 @@ nn::GeneralResult DeathHandler::create(sp auto deathRecipient = sp::make(); const auto ret = object->linkToDeath(deathRecipient, /*cookie=*/0); - const bool success = NN_TRY(handleTransportError(ret)); + const bool success = HANDLE_TRANSPORT_FAILURE(ret); if (!success) { return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "IBase::linkToDeath returned false"; } -- GitLab From b01ec1acdd1ca10562c37fcb8d13f2be5a7ffa5f Mon Sep 17 00:00:00 2001 From: Hayden Gomes Date: Mon, 7 Dec 2020 15:53:12 -0800 Subject: [PATCH 321/790] Use enumerator for AudioFocusChange Bug: 175064011 Test: built & atest VtsAidlHalAudioControlTest Change-Id: Id25ece4649981fcf7fecf070697712d5041c6ea4 --- .../hardware/automotive/audiocontrol/AudioFocusChange.aidl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioFocusChange.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioFocusChange.aidl index fc35fa9048..98fa4e83e3 100644 --- a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioFocusChange.aidl +++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioFocusChange.aidl @@ -27,7 +27,7 @@ enum AudioFocusChange { GAIN_TRANSIENT = 2, GAIN_TRANSIENT_MAY_DUCK = 3, GAIN_TRANSIENT_EXCLUSIVE = 4, - LOSS = -1, // -1 * GAIN, - LOSS_TRANSIENT = -2, // -1 * GAIN_TRANSIENT, - LOSS_TRANSIENT_CAN_DUCK = -3, // -1 * GAIN_TRANSIENT_MAY_DUCK, + LOSS = -1 * GAIN, + LOSS_TRANSIENT = -1 * GAIN_TRANSIENT, + LOSS_TRANSIENT_CAN_DUCK = -1 * GAIN_TRANSIENT_MAY_DUCK, } \ No newline at end of file -- GitLab From 94bcce5ec248994af5c74c0df256e8a4dfd94a84 Mon Sep 17 00:00:00 2001 From: Quang Luong Date: Wed, 25 Nov 2020 17:52:19 -0800 Subject: [PATCH 322/790] [WifiCoex] Add WifiChip HIDL APIs for coex Add HIDL APIs to convey a list of unsafe Wifi channels to the driver for coex channel avoidance. Bug: 153651001 Test: build Change-Id: I8b14f0e2d8855c1f1e363d612617256d8e928f30 --- wifi/1.5/IWifiChip.hal | 45 +++++++++++++++++++++- wifi/1.5/default/hidl_struct_util.cpp | 41 ++++++++++++++++++++ wifi/1.5/default/hidl_struct_util.h | 6 +++ wifi/1.5/default/wifi_chip.cpp | 21 ++++++++++ wifi/1.5/default/wifi_chip.h | 6 +++ wifi/1.5/default/wifi_legacy_hal.cpp | 8 ++++ wifi/1.5/default/wifi_legacy_hal.h | 5 +++ wifi/1.5/default/wifi_legacy_hal_stubs.cpp | 1 + 8 files changed, 132 insertions(+), 1 deletion(-) diff --git a/wifi/1.5/IWifiChip.hal b/wifi/1.5/IWifiChip.hal index 2702759c41..e9caa3deb5 100644 --- a/wifi/1.5/IWifiChip.hal +++ b/wifi/1.5/IWifiChip.hal @@ -17,6 +17,7 @@ package android.hardware.wifi@1.5; import @1.0::WifiStatus; +import @1.0::IfaceType; import @1.5::IWifiApIface; import @1.0::IWifiIface; import @1.3::IWifiChip; @@ -129,7 +130,6 @@ interface IWifiChip extends @1.4::IWifiChip { */ setMultiStaUseCase(MultiStaUseCase useCase) generates (WifiStatus status); - /** * Create bridged IWifiApIface. * @@ -167,4 +167,47 @@ interface IWifiChip extends @1.4::IWifiChip { */ removeIfaceInstanceFromBridgedApIface(string brIfaceName, string ifaceInstanceName) generates (WifiStatus status); + + /** + * Representation of a Wi-Fi channel for Wi-Fi coex channel avoidance. + */ + struct CoexUnsafeChannel { + /* The band of the channel */ + WifiBand band; + /* The channel number */ + uint32_t channel; + /** The power cap will be a maximum power value in dbm that is allowed to be transmitted by + the chip on this channel. A value of PowerCapConstant.NO_POWER_CAP means no limitation + on transmitted power is needed by the chip for this channel. + */ + int32_t powerCapDbm; + }; + + enum PowerCapConstant : int32_t { + NO_POWER_CAP = 0x7FFFFFFF, + }; + + /** + * Invoked to indicate that the provided |CoexUnsafeChannels| should be avoided with the + * specified restrictions. + * + * Channel avoidance is a suggestion and should be done on a best-effort approach. If a provided + * channel is used, then the specified power cap should be applied. + * + * In addition, hard restrictions on the Wifi modes may be indicated by |IfaceType| bits + * (STA, AP, P2P, NAN, etc) in the |restrictions| bitfield. If a hard restriction is provided, + * then the channels should be completely avoided for the provided Wifi modes instead of by + * best-effort. + * + * @param unsafeChannels List of |CoexUnsafeChannels| to avoid. + * @param restrictions Bitset of |IfaceType| values indicating Wifi modes to completely avoid. + * @return status WifiStatus of the operation. + * Possible status codes: + * |WifiStatusCode.SUCCESS|, + * |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|, + * |WifiStatusCode.ERROR_INVALID_ARGS|, + */ + setCoexUnsafeChannels( + vec unsafeChannels, bitfield restrictions) + generates (WifiStatus status); }; diff --git a/wifi/1.5/default/hidl_struct_util.cpp b/wifi/1.5/default/hidl_struct_util.cpp index 83d06fe398..8e2e647cc5 100644 --- a/wifi/1.5/default/hidl_struct_util.cpp +++ b/wifi/1.5/default/hidl_struct_util.cpp @@ -2800,6 +2800,47 @@ legacy_hal::wifi_multi_sta_use_case convertHidlMultiStaUseCaseToLegacy( } CHECK(false); } + +bool convertHidlCoexUnsafeChannelToLegacy( + const 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: + legacy_unsafe_channel->band = legacy_hal::WLAN_MAC_2_4_BAND; + break; + case WifiBand::BAND_5GHZ: + legacy_unsafe_channel->band = legacy_hal::WLAN_MAC_5_0_BAND; + break; + default: + return false; + }; + legacy_unsafe_channel->channel = hidl_unsafe_channel.channel; + legacy_unsafe_channel->power_cap_dbm = hidl_unsafe_channel.powerCapDbm; + return true; +} + +bool convertHidlVectorOfCoexUnsafeChannelToLegacy( + const std::vector& hidl_unsafe_channels, + std::vector* 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)) { + return false; + } + legacy_unsafe_channels->push_back(legacy_unsafe_channel); + } + return true; +} + } // namespace hidl_struct_util } // namespace implementation } // namespace V1_5 diff --git a/wifi/1.5/default/hidl_struct_util.h b/wifi/1.5/default/hidl_struct_util.h index 49d8a1213e..feb47ef7ab 100644 --- a/wifi/1.5/default/hidl_struct_util.h +++ b/wifi/1.5/default/hidl_struct_util.h @@ -71,6 +71,12 @@ 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& hidl_unsafe_channels, + std::vector* legacy_unsafe_channels); // STA iface conversion methods. bool convertLegacyFeaturesToHidlStaCapabilities( diff --git a/wifi/1.5/default/wifi_chip.cpp b/wifi/1.5/default/wifi_chip.cpp index dd39551571..1b0353b353 100644 --- a/wifi/1.5/default/wifi_chip.cpp +++ b/wifi/1.5/default/wifi_chip.cpp @@ -722,6 +722,15 @@ Return WifiChip::setMultiStaUseCase( hidl_status_cb, use_case); } +Return WifiChip::setCoexUnsafeChannels( + const hidl_vec& unsafeChannels, + hidl_bitfield restrictions, + setCoexUnsafeChannels_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::setCoexUnsafeChannelsInternal, + hidl_status_cb, unsafeChannels, restrictions); +} + void WifiChip::invalidateAndRemoveAllIfaces() { invalidateAndClearBridgedApAll(); invalidateAndClearAll(ap_ifaces_); @@ -1447,6 +1456,18 @@ WifiStatus WifiChip::setMultiStaUseCaseInternal(MultiStaUseCase use_case) { return createWifiStatusFromLegacyError(legacy_status); } +WifiStatus WifiChip::setCoexUnsafeChannelsInternal( + std::vector unsafe_channels, uint32_t restrictions) { + std::vector legacy_unsafe_channels; + if (!hidl_struct_util::convertHidlVectorOfCoexUnsafeChannelToLegacy( + unsafe_channels, &legacy_unsafe_channels)) { + return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); + } + auto legacy_status = legacy_hal_.lock()->setCoexUnsafeChannels( + legacy_unsafe_channels, restrictions); + return createWifiStatusFromLegacyError(legacy_status); +} + WifiStatus WifiChip::handleChipConfiguration( /* NONNULL */ std::unique_lock* lock, ChipModeId mode_id) { diff --git a/wifi/1.5/default/wifi_chip.h b/wifi/1.5/default/wifi_chip.h index bff8d680a3..95c122d2b1 100644 --- a/wifi/1.5/default/wifi_chip.h +++ b/wifi/1.5/default/wifi_chip.h @@ -174,6 +174,10 @@ class WifiChip : public V1_5::IWifiChip { Return setMultiStaUseCase( MultiStaUseCase use_case, setMultiStaUseCase_cb hidl_status_cb) override; + Return setCoexUnsafeChannels( + const hidl_vec& unsafe_channels, + hidl_bitfield restrictions, + setCoexUnsafeChannels_cb hidl_status_cb) override; private: void invalidateAndRemoveAllIfaces(); @@ -252,6 +256,8 @@ class WifiChip : public V1_5::IWifiChip { const sp& event_callback); WifiStatus setMultiStaPrimaryConnectionInternal(const std::string& ifname); WifiStatus setMultiStaUseCaseInternal(MultiStaUseCase use_case); + WifiStatus setCoexUnsafeChannelsInternal( + std::vector unsafe_channels, uint32_t restrictions); WifiStatus handleChipConfiguration( std::unique_lock* lock, ChipModeId mode_id); diff --git a/wifi/1.5/default/wifi_legacy_hal.cpp b/wifi/1.5/default/wifi_legacy_hal.cpp index 76e718b74a..773dd9b4f3 100644 --- a/wifi/1.5/default/wifi_legacy_hal.cpp +++ b/wifi/1.5/default/wifi_legacy_hal.cpp @@ -1521,6 +1521,14 @@ wifi_error WifiLegacyHal::multiStaSetUseCase(wifi_multi_sta_use_case use_case) { use_case); } +wifi_error WifiLegacyHal::setCoexUnsafeChannels( + std::vector unsafe_channels, + uint32_t restrictions) { + return global_func_table_.wifi_set_coex_unsafe_channels( + global_handle_, unsafe_channels.size(), unsafe_channels.data(), + restrictions); +} + void WifiLegacyHal::invalidate() { global_handle_ = nullptr; iface_name_to_handle_.clear(); diff --git a/wifi/1.5/default/wifi_legacy_hal.h b/wifi/1.5/default/wifi_legacy_hal.h index 555c540102..6266cf6fd5 100644 --- a/wifi/1.5/default/wifi_legacy_hal.h +++ b/wifi/1.5/default/wifi_legacy_hal.h @@ -386,6 +386,11 @@ class WifiLegacyHal { virtual wifi_error multiStaSetPrimaryConnection(const std::string& ifname); virtual wifi_error multiStaSetUseCase(wifi_multi_sta_use_case use_case); + // Coex functions. + virtual wifi_error setCoexUnsafeChannels( + std::vector unsafe_channels, + uint32_t restrictions); + private: // Retrieve interface handles for all the available interfaces. wifi_error retrieveIfaceHandles(); diff --git a/wifi/1.5/default/wifi_legacy_hal_stubs.cpp b/wifi/1.5/default/wifi_legacy_hal_stubs.cpp index 71d2ddf688..b6c908b0d2 100644 --- a/wifi/1.5/default/wifi_legacy_hal_stubs.cpp +++ b/wifi/1.5/default/wifi_legacy_hal_stubs.cpp @@ -149,6 +149,7 @@ bool initHalFuncTableWithStubs(wifi_hal_fn* hal_fn) { populateStubFor(&hal_fn->wifi_get_chip_feature_set); populateStubFor(&hal_fn->wifi_multi_sta_set_primary_connection); populateStubFor(&hal_fn->wifi_multi_sta_set_use_case); + populateStubFor(&hal_fn->wifi_set_coex_unsafe_channels); return true; } -- GitLab From 5cc53baceaf2d32dd7dc91e379033bb6718ef064 Mon Sep 17 00:00:00 2001 From: Yomna Nasser Date: Tue, 17 Nov 2020 22:00:55 +0000 Subject: [PATCH 323/790] Add getAllowedNetworkTypesBitmap HAL API Adds corresponding query API getAllowedNetworkTypesBitmap to existing setAllowedNetworkTypeBitmap. Test: atest Bug: 171791177 Change-Id: Ib8f0075dda41d4876a14f7223a067e34626a4675 --- radio/1.6/IRadio.hal | 16 +++++++++++++++- radio/1.6/IRadioResponse.hal | 18 ++++++++++++++++++ .../vts/functional/radio_hidl_hal_utils_v1_6.h | 6 ++++++ radio/1.6/vts/functional/radio_response.cpp | 8 ++++++++ 4 files changed, 47 insertions(+), 1 deletion(-) diff --git a/radio/1.6/IRadio.hal b/radio/1.6/IRadio.hal index 2c8ac5ea35..456655825e 100644 --- a/radio/1.6/IRadio.hal +++ b/radio/1.6/IRadio.hal @@ -327,11 +327,25 @@ interface IRadio extends @1.5::IRadio { * @param serial Serial number of request. * @param networkTypeBitmap a 32-bit bearer bitmap of RadioAccessFamily * - * Response callbask is IRadioResponse.setNetworkTypeBitmapResponse() + * Response callback is IRadioResponse.setNetworkTypeBitmapResponse() */ oneway setAllowedNetworkTypeBitmap( uint32_t serial, bitfield networkTypeBitmap); + /** + * Requests bitmap representing the currently allowed network types. + * + * Requests the bitmap set by the corresponding method + * setAllowedNetworkTypeBitmap, which sets a strict set of RATs for the + * radio to use. Differs from getPreferredNetworkType and getPreferredNetworkTypeBitmap + * in that those request *preferences*. + * + * @param serial Serial number of request. + * + * Response callback is IRadioResponse.getNetworkTypeBitmapResponse() + */ + oneway getAllowedNetworkTypeBitmap(uint32_t serial); + /** * Control data throttling at modem. * - DataThrottlingAction:NO_DATA_THROTTLING should clear any existing diff --git a/radio/1.6/IRadioResponse.hal b/radio/1.6/IRadioResponse.hal index 3b2061f32d..f13ee2b527 100644 --- a/radio/1.6/IRadioResponse.hal +++ b/radio/1.6/IRadioResponse.hal @@ -17,6 +17,7 @@ package android.hardware.radio@1.6; import @1.0::SendSmsResult; +import @1.4::RadioAccessFamily; import @1.5::IRadioResponse; import @1.6::CellInfo; import @1.6::RegStateResult; @@ -309,6 +310,23 @@ interface IRadioResponse extends @1.5::IRadioResponse { */ oneway setAllowedNetworkTypeBitmapResponse(RadioResponseInfo info); + /** + * Callback of IRadio.getAllowedNetworkTypeBitmap(int, bitfield) + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:MODE_NOT_SUPPORTED + * RadioError:INTERNAL_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:MODEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + */ + oneway getAllowedNetworkTypeBitmapResponse( + RadioResponseInfo info, bitfield networkTypeBitmap); + /** * @param info Response info struct containing response type, serial no. and error * diff --git a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h index 111fcd1325..ab56540067 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h +++ b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h @@ -793,6 +793,12 @@ class RadioResponse_v1_6 : public ::android::hardware::radio::V1_6::IRadioRespon Return setAllowedNetworkTypeBitmapResponse( const ::android::hardware::radio::V1_6::RadioResponseInfo& info); + Return getAllowedNetworkTypeBitmapResponse( + const ::android::hardware::radio::V1_6::RadioResponseInfo& info, + const ::android::hardware::hidl_bitfield< + ::android::hardware::radio::V1_4::RadioAccessFamily> + networkTypeBitmap); + Return setDataThrottlingResponse( const ::android::hardware::radio::V1_6::RadioResponseInfo& info); diff --git a/radio/1.6/vts/functional/radio_response.cpp b/radio/1.6/vts/functional/radio_response.cpp index 68d1f202b7..e37efdd9f0 100644 --- a/radio/1.6/vts/functional/radio_response.cpp +++ b/radio/1.6/vts/functional/radio_response.cpp @@ -1157,6 +1157,14 @@ Return RadioResponse_v1_6::setAllowedNetworkTypeBitmapResponse( return Void(); } +Return RadioResponse_v1_6::getAllowedNetworkTypeBitmapResponse( + const ::android::hardware::radio::V1_6::RadioResponseInfo& /*info*/, + const ::android::hardware::hidl_bitfield< + ::android::hardware::radio::V1_4::RadioAccessFamily> + /*networkTypeBitmap*/) { + return Void(); +} + Return RadioResponse_v1_6::setDataThrottlingResponse( const ::android::hardware::radio::V1_6::RadioResponseInfo& info) { rspInfo = info; -- GitLab From 7236d0760a814e8c2b2a8d9b2466ee9d86659eb6 Mon Sep 17 00:00:00 2001 From: Mikhail Naganov Date: Thu, 10 Dec 2020 16:10:08 -0800 Subject: [PATCH 324/790] audio: Extend HidlUtils for the default wrapper needs Add conversions used by the default wrapper. Promote some conversions to pre-V7 interface to reduce version-based forking in the default wrapper code. Bug: 142480271 Test: atest android.hardware.audio.common@7.0-util_tests Change-Id: I93c482eeaf08442271be2656693be5395ca53762 --- ...id_audio_policy_configuration_V7_0-enums.h | 8 + .../all-versions/default/7.0/HidlUtils.cpp | 59 ++++++ audio/common/all-versions/default/Android.bp | 2 + .../common/all-versions/default/HidlUtils.cpp | 26 ++- audio/common/all-versions/default/HidlUtils.h | 183 +++++++++++++----- .../all-versions/default/HidlUtilsCommon.cpp | 58 ++++++ .../default/tests/hidlutils_tests.cpp | 78 ++++++++ 7 files changed, 363 insertions(+), 51 deletions(-) create mode 100644 audio/common/all-versions/default/HidlUtilsCommon.cpp diff --git a/audio/common/7.0/enums/include/android_audio_policy_configuration_V7_0-enums.h b/audio/common/7.0/enums/include/android_audio_policy_configuration_V7_0-enums.h index 414eede6d1..b7c1cc97bc 100644 --- a/audio/common/7.0/enums/include/android_audio_policy_configuration_V7_0-enums.h +++ b/audio/common/7.0/enums/include/android_audio_policy_configuration_V7_0-enums.h @@ -225,6 +225,10 @@ static inline bool isUnknownAudioChannelMask(const std::string& mask) { return stringToAudioChannelMask(mask) == AudioChannelMask::UNKNOWN; } +static inline bool isUnknownAudioContentType(const std::string& contentType) { + return stringToAudioContentType(contentType) == AudioContentType::UNKNOWN; +} + static inline bool isUnknownAudioDevice(const std::string& device) { return stringToAudioDevice(device) == AudioDevice::UNKNOWN && !isVendorExtension(device); } @@ -237,6 +241,10 @@ static inline bool isUnknownAudioGainMode(const std::string& mode) { return stringToAudioGainMode(mode) == AudioGainMode::UNKNOWN; } +static inline bool isUnknownAudioInOutFlag(const std::string& flag) { + return stringToAudioInOutFlag(flag) == AudioInOutFlag::UNKNOWN; +} + static inline bool isUnknownAudioSource(const std::string& source) { return stringToAudioSource(source) == AudioSource::UNKNOWN; } diff --git a/audio/common/all-versions/default/7.0/HidlUtils.cpp b/audio/common/all-versions/default/7.0/HidlUtils.cpp index 1a662825bd..c985a7027a 100644 --- a/audio/common/all-versions/default/7.0/HidlUtils.cpp +++ b/audio/common/all-versions/default/7.0/HidlUtils.cpp @@ -95,6 +95,25 @@ status_t HidlUtils::audioChannelMaskFromHal(audio_channel_mask_t halChannelMask, return NO_ERROR; } +status_t HidlUtils::audioChannelMasksFromHal(const std::vector& halChannelMasks, + hidl_vec* channelMasks) { + hidl_vec tempChannelMasks; + tempChannelMasks.resize(halChannelMasks.size()); + size_t tempPos = 0; + for (const auto& halChannelMask : halChannelMasks) { + if (!halChannelMask.empty() && !xsd::isUnknownAudioChannelMask(halChannelMask)) { + tempChannelMasks[tempPos++] = halChannelMask; + } + } + if (tempPos == tempChannelMasks.size()) { + *channelMasks = std::move(tempChannelMasks); + } else { + *channelMasks = hidl_vec(tempChannelMasks.begin(), + tempChannelMasks.begin() + tempPos); + } + return halChannelMasks.size() == channelMasks->size() ? NO_ERROR : BAD_VALUE; +} + status_t HidlUtils::audioChannelMaskToHal(const AudioChannelMask& channelMask, audio_channel_mask_t* halChannelMask) { if (!xsd::isUnknownAudioChannelMask(channelMask) && @@ -127,6 +146,28 @@ status_t HidlUtils::audioConfigBaseToHal(const AudioConfigBase& configBase, return result; } +status_t HidlUtils::audioContentTypeFromHal(const audio_content_type_t halContentType, + AudioContentType* contentType) { + *contentType = audio_content_type_to_string(halContentType); + if (!contentType->empty() && !xsd::isUnknownAudioContentType(*contentType)) { + return NO_ERROR; + } + ALOGE("Unknown audio content type value 0x%X", halContentType); + *contentType = toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_UNKNOWN); + return BAD_VALUE; +} + +status_t HidlUtils::audioContentTypeToHal(const AudioContentType& contentType, + audio_content_type_t* halContentType) { + if (!xsd::isUnknownAudioContentType(contentType) && + audio_content_type_from_string(contentType.c_str(), halContentType)) { + return NO_ERROR; + } + ALOGE("Unknown audio content type \"%s\"", contentType.c_str()); + *halContentType = AUDIO_CONTENT_TYPE_UNKNOWN; + return BAD_VALUE; +} + status_t HidlUtils::audioDeviceTypeFromHal(audio_devices_t halDevice, AudioDevice* device) { *device = audio_device_to_string(halDevice); if (!device->empty() && !xsd::isUnknownAudioDevice(*device)) { @@ -155,6 +196,24 @@ status_t HidlUtils::audioFormatFromHal(audio_format_t halFormat, AudioFormat* fo return BAD_VALUE; } +status_t HidlUtils::audioFormatsFromHal(const std::vector& halFormats, + hidl_vec* formats) { + hidl_vec tempFormats; + tempFormats.resize(halFormats.size()); + size_t tempPos = 0; + for (const auto& halFormat : halFormats) { + if (!halFormat.empty() && !xsd::isUnknownAudioFormat(halFormat)) { + tempFormats[tempPos++] = halFormat; + } + } + if (tempPos == tempFormats.size()) { + *formats = std::move(tempFormats); + } else { + *formats = hidl_vec(tempFormats.begin(), tempFormats.begin() + tempPos); + } + return halFormats.size() == formats->size() ? NO_ERROR : BAD_VALUE; +} + status_t HidlUtils::audioFormatToHal(const AudioFormat& format, audio_format_t* halFormat) { if (!xsd::isUnknownAudioFormat(format) && audio_format_from_string(format.c_str(), halFormat)) { return NO_ERROR; diff --git a/audio/common/all-versions/default/Android.bp b/audio/common/all-versions/default/Android.bp index b83a58a3ec..45f0b8f297 100644 --- a/audio/common/all-versions/default/Android.bp +++ b/audio/common/all-versions/default/Android.bp @@ -43,6 +43,7 @@ filegroup { name: "android.hardware.audio.common-util@2-6", srcs: [ "HidlUtils.cpp", + "HidlUtilsCommon.cpp", "UuidUtils.cpp", ], } @@ -132,6 +133,7 @@ cc_library { defaults: ["android.hardware.audio.common-util_default"], srcs: [ "7.0/HidlUtils.cpp", + "HidlUtilsCommon.cpp", "UuidUtils.cpp", ], shared_libs: [ diff --git a/audio/common/all-versions/default/HidlUtils.cpp b/audio/common/all-versions/default/HidlUtils.cpp index ab3c1c7b33..c0dcd80ac0 100644 --- a/audio/common/all-versions/default/HidlUtils.cpp +++ b/audio/common/all-versions/default/HidlUtils.cpp @@ -28,7 +28,7 @@ namespace common { namespace CPP_VERSION { namespace implementation { -status_t HidlUtils::audioConfigFromHal(const audio_config_t& halConfig, AudioConfig* config) { +status_t HidlUtils::audioConfigFromHal(const audio_config_t& halConfig, bool, AudioConfig* config) { config->sampleRateHz = halConfig.sample_rate; config->channelMask = EnumBitfield(halConfig.channel_mask); config->format = AudioFormat(halConfig.format); @@ -47,8 +47,8 @@ status_t HidlUtils::audioConfigToHal(const AudioConfig& config, audio_config_t* return NO_ERROR; } -void HidlUtils::audioGainConfigFromHal(const struct audio_gain_config& halConfig, - AudioGainConfig* config) { +status_t HidlUtils::audioGainConfigFromHal(const struct audio_gain_config& halConfig, bool, + AudioGainConfig* config) { config->index = halConfig.index; config->mode = EnumBitfield(halConfig.mode); config->channelMask = EnumBitfield(halConfig.channel_mask); @@ -56,6 +56,7 @@ void HidlUtils::audioGainConfigFromHal(const struct audio_gain_config& halConfig config->values[i] = halConfig.values[i]; } config->rampDurationMs = halConfig.ramp_duration_ms; + return NO_ERROR; } status_t HidlUtils::audioGainConfigToHal(const AudioGainConfig& config, @@ -71,7 +72,7 @@ status_t HidlUtils::audioGainConfigToHal(const AudioGainConfig& config, return NO_ERROR; } -void HidlUtils::audioGainFromHal(const struct audio_gain& halGain, AudioGain* gain) { +status_t HidlUtils::audioGainFromHal(const struct audio_gain& halGain, bool, AudioGain* gain) { gain->mode = EnumBitfield(halGain.mode); gain->channelMask = EnumBitfield(halGain.channel_mask); gain->minValue = halGain.min_value; @@ -80,6 +81,7 @@ void HidlUtils::audioGainFromHal(const struct audio_gain& halGain, AudioGain* ga gain->stepValue = halGain.step_value; gain->minRampMs = halGain.min_ramp_ms; gain->maxRampMs = halGain.max_ramp_ms; + return NO_ERROR; } status_t HidlUtils::audioGainToHal(const AudioGain& gain, struct audio_gain* halGain) { @@ -182,7 +184,7 @@ status_t HidlUtils::audioPortConfigFromHal(const struct audio_port_config& halCo config->sampleRateHz = halConfig.sample_rate; config->channelMask = EnumBitfield(halConfig.channel_mask); config->format = AudioFormat(halConfig.format); - audioGainConfigFromHal(halConfig.gain, &config->gain); + audioGainConfigFromHal(halConfig.gain, false /*isInput--ignored*/, &config->gain); switch (halConfig.type) { case AUDIO_PORT_TYPE_NONE: break; @@ -272,7 +274,7 @@ status_t HidlUtils::audioPortFromHal(const struct audio_port& halPort, AudioPort } port->gains.resize(halPort.num_gains); for (size_t i = 0; i < halPort.num_gains; ++i) { - audioGainFromHal(halPort.gains[i], &port->gains[i]); + audioGainFromHal(halPort.gains[i], false /*isInput--ignored*/, &port->gains[i]); } audioPortConfigFromHal(halPort.active_config, &port->activeConfig); switch (halPort.type) { @@ -351,6 +353,18 @@ status_t HidlUtils::audioPortToHal(const AudioPort& port, struct audio_port* hal return NO_ERROR; } +#if MAJOR_VERSION >= 5 +status_t HidlUtils::deviceAddressToHal(const DeviceAddress& device, audio_devices_t* halDeviceType, + char* halDeviceAddress) { + return deviceAddressToHalImpl(device, halDeviceType, halDeviceAddress); +} + +status_t HidlUtils::deviceAddressFromHal(audio_devices_t halDeviceType, + const char* halDeviceAddress, DeviceAddress* device) { + return deviceAddressFromHalImpl(halDeviceType, halDeviceAddress, device); +} +#endif + } // namespace implementation } // namespace CPP_VERSION } // namespace common diff --git a/audio/common/all-versions/default/HidlUtils.h b/audio/common/all-versions/default/HidlUtils.h index 4e609ca4fd..c420a2f712 100644 --- a/audio/common/all-versions/default/HidlUtils.h +++ b/audio/common/all-versions/default/HidlUtils.h @@ -23,8 +23,6 @@ #include -using ::android::hardware::hidl_vec; - namespace android { namespace hardware { namespace audio { @@ -32,25 +30,25 @@ namespace common { namespace CPP_VERSION { namespace implementation { +using ::android::hardware::hidl_vec; using namespace ::android::hardware::audio::common::CPP_VERSION; struct HidlUtils { -#if MAJOR_VERSION < 7 - static status_t audioConfigFromHal(const audio_config_t& halConfig, AudioConfig* config); - static void audioGainConfigFromHal(const struct audio_gain_config& halConfig, - AudioGainConfig* config); - static void audioGainFromHal(const struct audio_gain& halGain, AudioGain* gain); -#else static status_t audioConfigFromHal(const audio_config_t& halConfig, bool isInput, AudioConfig* config); + static status_t audioConfigToHal(const AudioConfig& config, audio_config_t* halConfig); +#if MAJOR_VERSION >= 4 + static status_t audioContentTypeFromHal(const audio_content_type_t halContentType, + AudioContentType* contentType); + static status_t audioContentTypeToHal(const AudioContentType& contentType, + audio_content_type_t* halContentType); +#endif static status_t audioGainConfigFromHal(const struct audio_gain_config& halConfig, bool isInput, AudioGainConfig* config); - static status_t audioGainFromHal(const struct audio_gain& halGain, bool isInput, - AudioGain* gain); -#endif - static status_t audioConfigToHal(const AudioConfig& config, audio_config_t* halConfig); static status_t audioGainConfigToHal(const AudioGainConfig& config, struct audio_gain_config* halConfig); + static status_t audioGainFromHal(const struct audio_gain& halGain, bool isInput, + AudioGain* gain); static status_t audioGainToHal(const AudioGain& gain, struct audio_gain* halGain); static status_t audioUsageFromHal(audio_usage_t halUsage, AudioUsage* usage); static status_t audioUsageToHal(const AudioUsage& usage, audio_usage_t* halUsage); @@ -64,43 +62,37 @@ struct HidlUtils { struct audio_port_config* halConfig); static status_t audioPortConfigsFromHal(unsigned int numHalConfigs, const struct audio_port_config* halConfigs, - hidl_vec* configs) { - status_t result = NO_ERROR; - configs->resize(numHalConfigs); - for (unsigned int i = 0; i < numHalConfigs; ++i) { - if (status_t status = audioPortConfigFromHal(halConfigs[i], &(*configs)[i]); - status != NO_ERROR) { - result = status; - } - } - return result; - } + hidl_vec* configs); static status_t audioPortConfigsToHal(const hidl_vec& configs, - std::unique_ptr* halConfigs) { - status_t result = NO_ERROR; - halConfigs->reset(new audio_port_config[configs.size()]); - for (size_t i = 0; i < configs.size(); ++i) { - if (status_t status = audioPortConfigToHal(configs[i], &(*halConfigs)[i]); - status != NO_ERROR) { - result = status; - } - } - return result; - } + std::unique_ptr* halConfigs); + static status_t audioPortFromHal(const struct audio_port& halPort, AudioPort* port); + static status_t audioPortToHal(const AudioPort& port, struct audio_port* halPort); + static status_t audioSourceFromHal(audio_source_t halSource, AudioSource* source); + static status_t audioSourceToHal(const AudioSource& source, audio_source_t* halSource); +#if MAJOR_VERSION >= 5 + static status_t deviceAddressToHal(const DeviceAddress& device, audio_devices_t* halDeviceType, + char* halDeviceAddress); + static status_t deviceAddressFromHal(audio_devices_t halDeviceType, + const char* halDeviceAddress, DeviceAddress* device); +#endif - // PLEASE DO NOT USE, will be removed in a couple of days +#if MAJOR_VERSION <= 6 + // Temporary versions for compatibility with forks of the default implementation. + // Will be removed, do not use! + static status_t audioConfigFromHal(const audio_config_t& halConfig, AudioConfig* config) { + return audioConfigFromHal(halConfig, false /*isInput--ignored*/, config); + } static std::unique_ptr audioPortConfigsToHal( const hidl_vec& configs) { std::unique_ptr halConfigs; (void)audioPortConfigsToHal(configs, &halConfigs); return halConfigs; } - - static status_t audioPortFromHal(const struct audio_port& halPort, AudioPort* port); - static status_t audioPortToHal(const AudioPort& port, struct audio_port* halPort); -#if MAJOR_VERSION >= 7 +#else // V7 and above static status_t audioChannelMaskFromHal(audio_channel_mask_t halChannelMask, bool isInput, AudioChannelMask* channelMask); + static status_t audioChannelMasksFromHal(const std::vector& halChannelMasks, + hidl_vec* channelMasks); static status_t audioChannelMaskToHal(const AudioChannelMask& channelMask, audio_channel_mask_t* halChannelMask); static status_t audioConfigBaseFromHal(const audio_config_base_t& halConfigBase, bool isInput, @@ -110,6 +102,8 @@ struct HidlUtils { static status_t audioDeviceTypeFromHal(audio_devices_t halDevice, AudioDevice* device); static status_t audioDeviceTypeToHal(const AudioDevice& device, audio_devices_t* halDevice); static status_t audioFormatFromHal(audio_format_t halFormat, AudioFormat* format); + static status_t audioFormatsFromHal(const std::vector& halFormats, + hidl_vec* formats); static status_t audioFormatToHal(const AudioFormat& format, audio_format_t* halFormat); static status_t audioGainModeMaskFromHal(audio_gain_mode_t halGainModeMask, hidl_vec* gainModeMask); @@ -121,16 +115,10 @@ struct HidlUtils { AudioProfile* profile); static status_t audioProfileToHal(const AudioProfile& profile, struct audio_profile* halProfile); - static status_t audioSourceFromHal(audio_source_t halSource, AudioSource* source); - static status_t audioSourceToHal(const AudioSource& source, audio_source_t* halSource); static status_t audioStreamTypeFromHal(audio_stream_type_t halStreamType, AudioStreamType* streamType); static status_t audioStreamTypeToHal(const AudioStreamType& streamType, audio_stream_type_t* halStreamType); - static status_t deviceAddressToHal(const DeviceAddress& device, audio_devices_t* halDeviceType, - char* halDeviceAddress); - static status_t deviceAddressFromHal(audio_devices_t halDeviceType, - const char* halDeviceAddress, DeviceAddress* device); private: static status_t audioIndexChannelMaskFromHal(audio_channel_mask_t halChannelMask, @@ -151,8 +139,113 @@ struct HidlUtils { struct audio_port_config_mix_ext* mix, struct audio_port_config_session_ext* session); #endif + + // V4 and below have DeviceAddress defined in the 'core' interface. + // To avoid duplicating code, the implementations of deviceAddressTo/FromHal + // are defined as templates. These templates can be only used directly by V4 + // and below. +#if MAJOR_VERSION >= 5 + private: +#endif + template + static status_t deviceAddressToHalImpl(const DA& device, audio_devices_t* halDeviceType, + char* halDeviceAddress); + template + static status_t deviceAddressFromHalImpl(audio_devices_t halDeviceType, + const char* halDeviceAddress, DA* device); }; +#if MAJOR_VERSION <= 6 +#if MAJOR_VERSION >= 4 +inline status_t HidlUtils::audioContentTypeFromHal(const audio_content_type_t halContentType, + AudioContentType* contentType) { + *contentType = AudioContentType(halContentType); + return NO_ERROR; +} + +inline status_t HidlUtils::audioContentTypeToHal(const AudioContentType& contentType, + audio_content_type_t* halContentType) { + *halContentType = static_cast(contentType); + return NO_ERROR; +} +#endif + +inline status_t HidlUtils::audioSourceFromHal(audio_source_t halSource, AudioSource* source) { + *source = AudioSource(halSource); + return NO_ERROR; +} + +inline status_t HidlUtils::audioSourceToHal(const AudioSource& source, audio_source_t* halSource) { + *halSource = static_cast(source); + return NO_ERROR; +} + +template +status_t HidlUtils::deviceAddressToHalImpl(const DA& device, audio_devices_t* halDeviceType, + char* halDeviceAddress) { + *halDeviceType = static_cast(device.device); + memset(halDeviceAddress, 0, AUDIO_DEVICE_MAX_ADDRESS_LEN); + if (audio_is_a2dp_out_device(*halDeviceType) || audio_is_a2dp_in_device(*halDeviceType)) { + snprintf(halDeviceAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN, "%02X:%02X:%02X:%02X:%02X:%02X", + device.address.mac[0], device.address.mac[1], device.address.mac[2], + device.address.mac[3], device.address.mac[4], device.address.mac[5]); + } else if (*halDeviceType == AUDIO_DEVICE_OUT_IP || *halDeviceType == AUDIO_DEVICE_IN_IP) { + snprintf(halDeviceAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN, "%d.%d.%d.%d", + device.address.ipv4[0], device.address.ipv4[1], device.address.ipv4[2], + device.address.ipv4[3]); + } else if (audio_is_usb_out_device(*halDeviceType) || audio_is_usb_in_device(*halDeviceType)) { + snprintf(halDeviceAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN, "card=%d;device=%d", + device.address.alsa.card, device.address.alsa.device); + } else if (*halDeviceType == AUDIO_DEVICE_OUT_BUS || *halDeviceType == AUDIO_DEVICE_IN_BUS) { + snprintf(halDeviceAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN, "%s", device.busAddress.c_str()); + } else if (*halDeviceType == AUDIO_DEVICE_OUT_REMOTE_SUBMIX || + *halDeviceType == AUDIO_DEVICE_IN_REMOTE_SUBMIX) { + snprintf(halDeviceAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN, "%s", + device.rSubmixAddress.c_str()); + } + return NO_ERROR; +} + +template +status_t HidlUtils::deviceAddressFromHalImpl(audio_devices_t halDeviceType, + const char* halDeviceAddress, DA* device) { + if (device == nullptr) { + return BAD_VALUE; + } + device->device = AudioDevice(halDeviceType); + if (halDeviceAddress == nullptr || + strnlen(halDeviceAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0) { + return NO_ERROR; + } + + if (audio_is_a2dp_out_device(halDeviceType) || audio_is_a2dp_in_device(halDeviceType)) { + int status = + sscanf(halDeviceAddress, "%hhX:%hhX:%hhX:%hhX:%hhX:%hhX", &device->address.mac[0], + &device->address.mac[1], &device->address.mac[2], &device->address.mac[3], + &device->address.mac[4], &device->address.mac[5]); + return status == 6 ? OK : BAD_VALUE; + } else if (halDeviceType == AUDIO_DEVICE_OUT_IP || halDeviceType == AUDIO_DEVICE_IN_IP) { + int status = sscanf(halDeviceAddress, "%hhu.%hhu.%hhu.%hhu", &device->address.ipv4[0], + &device->address.ipv4[1], &device->address.ipv4[2], + &device->address.ipv4[3]); + return status == 4 ? OK : BAD_VALUE; + } else if (audio_is_usb_out_device(halDeviceType) || audio_is_usb_in_device(halDeviceType)) { + int status = sscanf(halDeviceAddress, "card=%d;device=%d", &device->address.alsa.card, + &device->address.alsa.device); + return status == 2 ? OK : BAD_VALUE; + } else if (halDeviceType == AUDIO_DEVICE_OUT_BUS || halDeviceType == AUDIO_DEVICE_IN_BUS) { + device->busAddress = halDeviceAddress; + return OK; + } else if (halDeviceType == AUDIO_DEVICE_OUT_REMOTE_SUBMIX || + halDeviceType == AUDIO_DEVICE_IN_REMOTE_SUBMIX) { + device->rSubmixAddress = halDeviceAddress; + return OK; + } + device->busAddress = halDeviceAddress; + return NO_ERROR; +} +#endif // MAJOR_VERSION <= 6 + } // namespace implementation } // namespace CPP_VERSION } // namespace common diff --git a/audio/common/all-versions/default/HidlUtilsCommon.cpp b/audio/common/all-versions/default/HidlUtilsCommon.cpp new file mode 100644 index 0000000000..d2da1939f5 --- /dev/null +++ b/audio/common/all-versions/default/HidlUtilsCommon.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "HidlUtils.h" + +namespace android { +namespace hardware { +namespace audio { +namespace common { +namespace CPP_VERSION { +namespace implementation { + +status_t HidlUtils::audioPortConfigsFromHal(unsigned int numHalConfigs, + const struct audio_port_config* halConfigs, + hidl_vec* configs) { + status_t result = NO_ERROR; + configs->resize(numHalConfigs); + for (unsigned int i = 0; i < numHalConfigs; ++i) { + if (status_t status = audioPortConfigFromHal(halConfigs[i], &(*configs)[i]); + status != NO_ERROR) { + result = status; + } + } + return result; +} + +status_t HidlUtils::audioPortConfigsToHal(const hidl_vec& configs, + std::unique_ptr* halConfigs) { + status_t result = NO_ERROR; + halConfigs->reset(new audio_port_config[configs.size()]); + for (size_t i = 0; i < configs.size(); ++i) { + if (status_t status = audioPortConfigToHal(configs[i], &(*halConfigs)[i]); + status != NO_ERROR) { + result = status; + } + } + return result; +} + +} // namespace implementation +} // namespace CPP_VERSION +} // namespace common +} // namespace audio +} // namespace hardware +} // namespace android diff --git a/audio/common/all-versions/default/tests/hidlutils_tests.cpp b/audio/common/all-versions/default/tests/hidlutils_tests.cpp index bfc99e6b48..22571c0411 100644 --- a/audio/common/all-versions/default/tests/hidlutils_tests.cpp +++ b/audio/common/all-versions/default/tests/hidlutils_tests.cpp @@ -28,6 +28,7 @@ #include using namespace android; +using ::android::hardware::hidl_vec; using namespace ::android::hardware::audio::common::CPP_VERSION; using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils; namespace xsd { @@ -36,6 +37,8 @@ using namespace ::android::audio::policy::configuration::V7_0; static constexpr audio_channel_mask_t kInvalidHalChannelMask = static_cast(0xFFFFFFFFU); +static constexpr audio_content_type_t kInvalidHalContentType = + static_cast(0xFFFFFFFFU); static constexpr audio_devices_t kInvalidHalDevice = static_cast(0xFFFFFFFFU); static constexpr audio_format_t kInvalidHalFormat = static_cast(0xFFFFFFFFU); static constexpr audio_gain_mode_t kInvalidHalGainMode = @@ -117,6 +120,34 @@ TEST(HidlUtils, ConvertChannelMask) { } } +TEST(HidlUtils, ConvertInvalidChannelMasksFromHal) { + std::vector validAndInvalidChannelMasks = { + toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO), "random string", ""}; + hidl_vec validChannelMask; + EXPECT_EQ(BAD_VALUE, + HidlUtils::audioChannelMasksFromHal(validAndInvalidChannelMasks, &validChannelMask)); + EXPECT_EQ(1, validChannelMask.size()); + EXPECT_EQ(validAndInvalidChannelMasks[0], validChannelMask[0]); + + std::vector invalidChannelMasks = {"random string", ""}; + hidl_vec empty; + EXPECT_EQ(BAD_VALUE, HidlUtils::audioChannelMasksFromHal(invalidChannelMasks, &empty)); + EXPECT_EQ(0, empty.size()); +} + +TEST(HidlUtils, ConvertChannelMasksFromHal) { + std::vector allHalChannelMasks; + for (const auto enumVal : xsdc_enum_range{}) { + allHalChannelMasks.push_back(toString(enumVal)); + } + hidl_vec allChannelMasks; + EXPECT_EQ(NO_ERROR, HidlUtils::audioChannelMasksFromHal(allHalChannelMasks, &allChannelMasks)); + EXPECT_EQ(allHalChannelMasks.size(), allChannelMasks.size()); + for (size_t i = 0; i < allHalChannelMasks.size(); ++i) { + EXPECT_EQ(allHalChannelMasks[i], allChannelMasks[i]); + } +} + TEST(HidlUtils, ConvertInvalidConfigBase) { AudioConfigBase invalid; EXPECT_EQ(BAD_VALUE, HidlUtils::audioConfigBaseFromHal({.sample_rate = 0, @@ -147,6 +178,26 @@ TEST(HidlUtils, ConvertConfigBase) { EXPECT_EQ(configBase, configBaseBack); } +TEST(HidlUtils, ConvertInvalidContentType) { + AudioContentType invalid; + EXPECT_EQ(BAD_VALUE, HidlUtils::audioContentTypeFromHal(kInvalidHalContentType, &invalid)); + audio_content_type_t halInvalid; + EXPECT_EQ(BAD_VALUE, HidlUtils::audioContentTypeToHal("random string", &halInvalid)); +} + +TEST(HidlUtils, ConvertContentType) { + for (const auto enumVal : xsdc_enum_range{}) { + const AudioContentType contentType = toString(enumVal); + audio_content_type_t halContentType; + AudioContentType contentTypeBack; + EXPECT_EQ(NO_ERROR, HidlUtils::audioContentTypeToHal(contentType, &halContentType)) + << "Conversion of \"" << contentType << "\" failed"; + EXPECT_EQ(NO_ERROR, HidlUtils::audioContentTypeFromHal(halContentType, &contentTypeBack)) + << "Conversion of content type " << halContentType << " failed"; + EXPECT_EQ(contentType, contentTypeBack); + } +} + TEST(HidlUtils, ConvertInvalidDeviceType) { AudioDevice invalid; EXPECT_EQ(BAD_VALUE, HidlUtils::audioDeviceTypeFromHal(kInvalidHalDevice, &invalid)); @@ -314,6 +365,33 @@ TEST(HidlUtils, ConvertFormat) { } } +TEST(HidlUtils, ConvertInvalidFormatsFromHal) { + std::vector validAndInvalidFormats = { + toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT), "random string", ""}; + hidl_vec validFormat; + EXPECT_EQ(BAD_VALUE, HidlUtils::audioFormatsFromHal(validAndInvalidFormats, &validFormat)); + EXPECT_EQ(1, validFormat.size()); + EXPECT_EQ(validAndInvalidFormats[0], validFormat[0]); + + std::vector invalidFormats = {"random string", ""}; + hidl_vec empty; + EXPECT_EQ(BAD_VALUE, HidlUtils::audioFormatsFromHal(invalidFormats, &empty)); + EXPECT_EQ(0, empty.size()); +} + +TEST(HidlUtils, ConvertFormatsFromHal) { + std::vector allHalFormats; + for (const auto enumVal : xsdc_enum_range{}) { + allHalFormats.push_back(toString(enumVal)); + } + hidl_vec allFormats; + EXPECT_EQ(NO_ERROR, HidlUtils::audioFormatsFromHal(allHalFormats, &allFormats)); + EXPECT_EQ(allHalFormats.size(), allFormats.size()); + for (size_t i = 0; i < allHalFormats.size(); ++i) { + EXPECT_EQ(allHalFormats[i], allFormats[i]); + } +} + TEST(HidlUtils, ConvertInvalidGainModeMask) { hidl_vec invalid; EXPECT_EQ(BAD_VALUE, HidlUtils::audioGainModeMaskFromHal(kInvalidHalGainMode, &invalid)); -- GitLab From 77d6f101e7b823e81104d325cf0c24ebd10ffc9e Mon Sep 17 00:00:00 2001 From: Mikhail Naganov Date: Thu, 10 Dec 2020 17:25:40 -0800 Subject: [PATCH 325/790] audio: Update default wrapper to support V7 During this conversion, the functionality of the V7 wrapper hasn't been tested yet. This will be done in a separate CL that will also include required updates to the VTS tests. Since the changes were made to the code shared with pre-V7 versions, verified that V6 HAL didn't regress. Bug: 142480271 Test: atest VtsHalAudioV6_0TargetTest Test: m VtsHalAudioV7_0TargetTest Change-Id: I0e42fe1279912ffa78ce40c69f6aa2054e84d385 --- audio/7.0/IStream.hal | 3 +- audio/core/all-versions/default/Android.bp | 4 +- .../core/all-versions/default/Conversions.cpp | 124 +++++++++--------- audio/core/all-versions/default/Device.cpp | 89 ++++++++----- .../all-versions/default/ParametersUtil.cpp | 10 +- .../all-versions/default/PrimaryDevice.cpp | 18 ++- audio/core/all-versions/default/Stream.cpp | 111 +++++++++++++++- audio/core/all-versions/default/StreamIn.cpp | 45 +++++-- audio/core/all-versions/default/StreamOut.cpp | 38 +++++- .../include/core/default/Conversions.h | 32 +++++ .../default/include/core/default/Device.h | 45 ++++--- .../include/core/default/PrimaryDevice.h | 24 ++-- .../default/include/core/default/Stream.h | 20 ++- .../default/include/core/default/StreamIn.h | 5 + .../default/include/core/default/StreamOut.h | 5 + .../default/include/core/default/Util.h | 12 ++ .../vts/functional/AudioPrimaryHidlHalTest.h | 4 +- 17 files changed, 430 insertions(+), 159 deletions(-) diff --git a/audio/7.0/IStream.hal b/audio/7.0/IStream.hal index 4fe8218b28..ab9aa7dae3 100644 --- a/audio/7.0/IStream.hal +++ b/audio/7.0/IStream.hal @@ -66,9 +66,10 @@ interface IStream { * Retrieves basic stream configuration: sample rate, audio format, * channel mask. * + * @return retval operation completion status. * @return config basic stream configuration. */ - getAudioProperties() generates (AudioConfigBase config); + getAudioProperties() generates (Result retval, AudioConfigBase config); /** * Sets stream parameters. Only sets parameters that are specified. diff --git a/audio/core/all-versions/default/Android.bp b/audio/core/all-versions/default/Android.bp index 6be0628b35..e0f086094c 100644 --- a/audio/core/all-versions/default/Android.bp +++ b/audio/core/all-versions/default/Android.bp @@ -125,13 +125,15 @@ cc_library_shared { } cc_library_shared { - enabled: false, name: "android.hardware.audio@7.0-impl", defaults: ["android.hardware.audio-impl_default"], shared_libs: [ "android.hardware.audio@7.0", "android.hardware.audio.common@7.0", + "android.hardware.audio.common@7.0-enums", "android.hardware.audio.common@7.0-util", + "libbase", + "libxml2", ], cflags: [ "-DMAJOR_VERSION=7", diff --git a/audio/core/all-versions/default/Conversions.cpp b/audio/core/all-versions/default/Conversions.cpp index 28d8f78bbc..8e0a140f0b 100644 --- a/audio/core/all-versions/default/Conversions.cpp +++ b/audio/core/all-versions/default/Conversions.cpp @@ -18,8 +18,11 @@ #include +#if MAJOR_VERSION >= 7 +#include +#endif +#include #include -#include namespace android { namespace hardware { @@ -27,73 +30,36 @@ namespace audio { namespace CPP_VERSION { namespace implementation { -// TODO(mnaganov): Use method from HidlUtils for V7 +using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils; + +#if MAJOR_VERSION <= 6 std::string deviceAddressToHal(const DeviceAddress& address) { - // HAL assumes that the address is NUL-terminated. + audio_devices_t halDevice; char halAddress[AUDIO_DEVICE_MAX_ADDRESS_LEN]; - memset(halAddress, 0, sizeof(halAddress)); - audio_devices_t halDevice = static_cast(address.device); - if (getAudioDeviceOutAllA2dpSet().count(halDevice) > 0 || - halDevice == AUDIO_DEVICE_IN_BLUETOOTH_A2DP) { - snprintf(halAddress, sizeof(halAddress), "%02X:%02X:%02X:%02X:%02X:%02X", - address.address.mac[0], address.address.mac[1], address.address.mac[2], - address.address.mac[3], address.address.mac[4], address.address.mac[5]); - } else if (halDevice == AUDIO_DEVICE_OUT_IP || halDevice == AUDIO_DEVICE_IN_IP) { - snprintf(halAddress, sizeof(halAddress), "%d.%d.%d.%d", address.address.ipv4[0], - address.address.ipv4[1], address.address.ipv4[2], address.address.ipv4[3]); - } else if (getAudioDeviceOutAllUsbSet().count(halDevice) > 0 || - getAudioDeviceInAllUsbSet().count(halDevice) > 0) { - snprintf(halAddress, sizeof(halAddress), "card=%d;device=%d", address.address.alsa.card, - address.address.alsa.device); - } else if (halDevice == AUDIO_DEVICE_OUT_BUS || halDevice == AUDIO_DEVICE_IN_BUS) { - snprintf(halAddress, sizeof(halAddress), "%s", address.busAddress.c_str()); - } else if (halDevice == AUDIO_DEVICE_OUT_REMOTE_SUBMIX || - halDevice == AUDIO_DEVICE_IN_REMOTE_SUBMIX) { - snprintf(halAddress, sizeof(halAddress), "%s", address.rSubmixAddress.c_str()); - } + (void)deviceAddressToHal(address, &halDevice, halAddress); return halAddress; } +#endif -#if MAJOR_VERSION >= 4 -status_t deviceAddressFromHal(audio_devices_t device, const char* halAddress, - DeviceAddress* address) { - if (address == nullptr) { - return BAD_VALUE; - } - address->device = AudioDevice(device); - if (halAddress == nullptr || strnlen(halAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0) { - return OK; - } +status_t deviceAddressToHal(const DeviceAddress& device, audio_devices_t* halDeviceType, + char* halDeviceAddress) { +#if MAJOR_VERSION >= 5 + return HidlUtils::deviceAddressToHal(device, halDeviceType, halDeviceAddress); +#else + return HidlUtils::deviceAddressToHalImpl(device, halDeviceType, halDeviceAddress); +#endif +} - if (getAudioDeviceOutAllA2dpSet().count(device) > 0 || - device == AUDIO_DEVICE_IN_BLUETOOTH_A2DP) { - int status = - sscanf(halAddress, "%hhX:%hhX:%hhX:%hhX:%hhX:%hhX", &address->address.mac[0], - &address->address.mac[1], &address->address.mac[2], &address->address.mac[3], - &address->address.mac[4], &address->address.mac[5]); - return status == 6 ? OK : BAD_VALUE; - } else if (device == AUDIO_DEVICE_OUT_IP || device == AUDIO_DEVICE_IN_IP) { - int status = - sscanf(halAddress, "%hhu.%hhu.%hhu.%hhu", &address->address.ipv4[0], - &address->address.ipv4[1], &address->address.ipv4[2], &address->address.ipv4[3]); - return status == 4 ? OK : BAD_VALUE; - } else if (getAudioDeviceOutAllUsbSet().count(device) > 0 || - getAudioDeviceInAllUsbSet().count(device) > 0) { - int status = sscanf(halAddress, "card=%d;device=%d", &address->address.alsa.card, - &address->address.alsa.device); - return status == 2 ? OK : BAD_VALUE; - } else if (device == AUDIO_DEVICE_OUT_BUS || device == AUDIO_DEVICE_IN_BUS) { - address->busAddress = halAddress; - return OK; - } else if (device == AUDIO_DEVICE_OUT_REMOTE_SUBMIX || - device == AUDIO_DEVICE_IN_REMOTE_SUBMIX) { - address->rSubmixAddress = halAddress; - return OK; - } - address->busAddress = halAddress; - return OK; +status_t deviceAddressFromHal(audio_devices_t halDeviceType, const char* halDeviceAddress, + DeviceAddress* device) { +#if MAJOR_VERSION >= 5 + return HidlUtils::deviceAddressFromHal(halDeviceType, halDeviceAddress, device); +#else + return HidlUtils::deviceAddressFromHalImpl(halDeviceType, halDeviceAddress, device); +#endif } +#if MAJOR_VERSION >= 4 bool halToMicrophoneCharacteristics(MicrophoneInfo* pDst, const struct audio_microphone_characteristic_t& src) { bool status = false; @@ -131,6 +97,44 @@ bool halToMicrophoneCharacteristics(MicrophoneInfo* pDst, } return status; } +#endif // MAJOR_VERSION >= 4 + +#if MAJOR_VERSION >= 7 +namespace xsd { +using namespace ::android::audio::policy::configuration::V7_0; +} + +bool audioInputFlagsToHal(const hidl_vec& flags, audio_input_flags_t* halFlags) { + bool success = true; + *halFlags = {}; + for (const auto& flag : flags) { + audio_input_flags_t halFlag; + if (!xsd::isUnknownAudioInOutFlag(flag) && + audio_input_flag_from_string(flag.c_str(), &halFlag)) { + *halFlags = static_cast(*halFlags | halFlag); + } else { + ALOGE("Unknown audio input flag \"%s\"", flag.c_str()); + success = false; + } + } + return success; +} + +bool audioOutputFlagsToHal(const hidl_vec& flags, audio_output_flags_t* halFlags) { + bool success = true; + *halFlags = {}; + for (const auto& flag : flags) { + audio_output_flags_t halFlag; + if (!xsd::isUnknownAudioInOutFlag(flag) && + audio_output_flag_from_string(flag.c_str(), &halFlag)) { + *halFlags = static_cast(*halFlags | halFlag); + } else { + ALOGE("Unknown audio output flag \"%s\"", flag.c_str()); + success = false; + } + } + return success; +} #endif } // namespace implementation diff --git a/audio/core/all-versions/default/Device.cpp b/audio/core/all-versions/default/Device.cpp index 3c28159816..bb69f0b88d 100644 --- a/audio/core/all-versions/default/Device.cpp +++ b/audio/core/all-versions/default/Device.cpp @@ -150,63 +150,76 @@ Return Device::getInputBufferSize(const AudioConfig& config, getInputBuffe std::tuple> Device::openOutputStreamImpl(int32_t ioHandle, const DeviceAddress& device, const AudioConfig& config, - AudioOutputFlagBitfield flags, + const AudioOutputFlags& flags, AudioConfig* suggestedConfig) { audio_config_t halConfig; HidlUtils::audioConfigToHal(config, &halConfig); audio_stream_out_t* halStream; - ALOGV( - "open_output_stream handle: %d devices: %x flags: %#x " - "srate: %d format %#x channels %x address %s", - ioHandle, static_cast(device.device), - static_cast(flags), halConfig.sample_rate, halConfig.format, - halConfig.channel_mask, deviceAddressToHal(device).c_str()); - int status = - mDevice->open_output_stream(mDevice, ioHandle, static_cast(device.device), - static_cast(flags), &halConfig, - &halStream, deviceAddressToHal(device).c_str()); + audio_devices_t halDevice; + char halDeviceAddress[AUDIO_DEVICE_MAX_ADDRESS_LEN]; + if (deviceAddressToHal(device, &halDevice, halDeviceAddress) != NO_ERROR) { + return {Result::INVALID_ARGUMENTS, nullptr}; + } + audio_output_flags_t halFlags; + if (!audioOutputFlagsToHal(flags, &halFlags)) { + return {Result::INVALID_ARGUMENTS, nullptr}; + } + ALOGV("open_output_stream handle: %d devices: %x flags: %#x " + "srate: %d format %#x channels %x address %s", + ioHandle, halDevice, halFlags, halConfig.sample_rate, halConfig.format, + halConfig.channel_mask, halDeviceAddress); + int status = mDevice->open_output_stream(mDevice, ioHandle, halDevice, halFlags, &halConfig, + &halStream, halDeviceAddress); ALOGV("open_output_stream status %d stream %p", status, halStream); sp streamOut; if (status == OK) { streamOut = new StreamOut(this, halStream); ++mOpenedStreamsCount; } - status_t convertStatus = HidlUtils::audioConfigFromHal(halConfig, suggestedConfig); + status_t convertStatus = + HidlUtils::audioConfigFromHal(halConfig, false /*isInput*/, suggestedConfig); ALOGW_IF(convertStatus != OK, "%s: suggested config with incompatible fields", __func__); return {analyzeStatus("open_output_stream", status, {EINVAL} /*ignore*/), streamOut}; } std::tuple> Device::openInputStreamImpl( - int32_t ioHandle, const DeviceAddress& device, const AudioConfig& config, - AudioInputFlagBitfield flags, AudioSource source, AudioConfig* suggestedConfig) { + int32_t ioHandle, const DeviceAddress& device, const AudioConfig& config, + const AudioInputFlags& flags, AudioSource source, AudioConfig* suggestedConfig) { audio_config_t halConfig; HidlUtils::audioConfigToHal(config, &halConfig); audio_stream_in_t* halStream; - ALOGV( - "open_input_stream handle: %d devices: %x flags: %#x " - "srate: %d format %#x channels %x address %s source %d", - ioHandle, static_cast(device.device), - static_cast(flags), halConfig.sample_rate, halConfig.format, - halConfig.channel_mask, deviceAddressToHal(device).c_str(), - static_cast(source)); - int status = mDevice->open_input_stream( - mDevice, ioHandle, static_cast(device.device), &halConfig, &halStream, - static_cast(flags), deviceAddressToHal(device).c_str(), - static_cast(source)); + audio_devices_t halDevice; + char halDeviceAddress[AUDIO_DEVICE_MAX_ADDRESS_LEN]; + if (deviceAddressToHal(device, &halDevice, halDeviceAddress) != NO_ERROR) { + return {Result::INVALID_ARGUMENTS, nullptr}; + } + audio_input_flags_t halFlags; + audio_source_t halSource; + if (!audioInputFlagsToHal(flags, &halFlags) || + HidlUtils::audioSourceToHal(source, &halSource) != NO_ERROR) { + return {Result::INVALID_ARGUMENTS, nullptr}; + } + ALOGV("open_input_stream handle: %d devices: %x flags: %#x " + "srate: %d format %#x channels %x address %s source %d", + ioHandle, halDevice, halFlags, halConfig.sample_rate, halConfig.format, + halConfig.channel_mask, halDeviceAddress, halSource); + int status = mDevice->open_input_stream(mDevice, ioHandle, halDevice, &halConfig, &halStream, + halFlags, halDeviceAddress, halSource); ALOGV("open_input_stream status %d stream %p", status, halStream); sp streamIn; if (status == OK) { streamIn = new StreamIn(this, halStream); ++mOpenedStreamsCount; } - status_t convertStatus = HidlUtils::audioConfigFromHal(halConfig, suggestedConfig); + status_t convertStatus = + HidlUtils::audioConfigFromHal(halConfig, true /*isInput*/, suggestedConfig); ALOGW_IF(convertStatus != OK, "%s: suggested config with incompatible fields", __func__); return {analyzeStatus("open_input_stream", status, {EINVAL} /*ignore*/), streamIn}; } #if MAJOR_VERSION == 2 Return Device::openOutputStream(int32_t ioHandle, const DeviceAddress& device, - const AudioConfig& config, AudioOutputFlagBitfield flags, + const AudioConfig& config, AudioOutputFlags flags, openOutputStream_cb _hidl_cb) { AudioConfig suggestedConfig; auto [result, streamOut] = @@ -216,7 +229,7 @@ Return Device::openOutputStream(int32_t ioHandle, const DeviceAddress& dev } Return Device::openInputStream(int32_t ioHandle, const DeviceAddress& device, - const AudioConfig& config, AudioInputFlagBitfield flags, + const AudioConfig& config, AudioInputFlags flags, AudioSource source, openInputStream_cb _hidl_cb) { AudioConfig suggestedConfig; auto [result, streamIn] = @@ -227,7 +240,12 @@ Return Device::openInputStream(int32_t ioHandle, const DeviceAddress& devi #elif MAJOR_VERSION >= 4 Return Device::openOutputStream(int32_t ioHandle, const DeviceAddress& device, - const AudioConfig& config, AudioOutputFlagBitfield flags, + const AudioConfig& config, +#if MAJOR_VERSION <= 6 + AudioOutputFlags flags, +#else + const AudioOutputFlags& flags, +#endif const SourceMetadata& sourceMetadata, openOutputStream_cb _hidl_cb) { AudioConfig suggestedConfig; @@ -241,7 +259,12 @@ Return Device::openOutputStream(int32_t ioHandle, const DeviceAddress& dev } Return Device::openInputStream(int32_t ioHandle, const DeviceAddress& device, - const AudioConfig& config, AudioInputFlagBitfield flags, + const AudioConfig& config, +#if MAJOR_VERSION <= 6 + AudioInputFlags flags, +#else + const AudioInputFlags& flags, +#endif const SinkMetadata& sinkMetadata, openInputStream_cb _hidl_cb) { if (sinkMetadata.tracks.size() == 0) { @@ -271,9 +294,7 @@ Return Device::supportsAudioPatches() { Return Device::createAudioPatch(const hidl_vec& sources, const hidl_vec& sinks, createAudioPatch_cb _hidl_cb) { - auto [retval, patch] = createOrUpdateAudioPatch( - static_cast(AudioHandleConsts::AUDIO_PATCH_HANDLE_NONE), sources, - sinks); + auto [retval, patch] = createOrUpdateAudioPatch(AudioPatchHandle{}, sources, sinks); _hidl_cb(retval, patch); return Void(); } @@ -454,7 +475,7 @@ Return Device::updateAudioPatch(int32_t previousPatch, const hidl_vec& sources, const hidl_vec& sinks, createAudioPatch_cb _hidl_cb) { - if (previousPatch != static_cast(AudioHandleConsts::AUDIO_PATCH_HANDLE_NONE)) { + if (previousPatch != static_cast(AudioPatchHandle{})) { auto [retval, patch] = createOrUpdateAudioPatch(previousPatch, sources, sinks); _hidl_cb(retval, patch); } else { diff --git a/audio/core/all-versions/default/ParametersUtil.cpp b/audio/core/all-versions/default/ParametersUtil.cpp index 0c8e28af8b..694eb73aee 100644 --- a/audio/core/all-versions/default/ParametersUtil.cpp +++ b/audio/core/all-versions/default/ParametersUtil.cpp @@ -149,9 +149,15 @@ Result ParametersUtil::setParametersImpl(const hidl_vec& context } return setParams(params); } + Result ParametersUtil::setParam(const char* name, const DeviceAddress& address) { - AudioParameter params(String8(deviceAddressToHal(address).c_str())); - params.addInt(String8(name), int(address.device)); + audio_devices_t halDeviceType; + char halDeviceAddress[AUDIO_DEVICE_MAX_ADDRESS_LEN]; + if (deviceAddressToHal(address, &halDeviceType, halDeviceAddress) != NO_ERROR) { + return Result::INVALID_ARGUMENTS; + } + AudioParameter params{String8(halDeviceAddress)}; + params.addInt(String8(name), halDeviceType); return setParams(params); } diff --git a/audio/core/all-versions/default/PrimaryDevice.cpp b/audio/core/all-versions/default/PrimaryDevice.cpp index 11c1c5a4df..fe56177975 100644 --- a/audio/core/all-versions/default/PrimaryDevice.cpp +++ b/audio/core/all-versions/default/PrimaryDevice.cpp @@ -73,28 +73,36 @@ Return PrimaryDevice::getInputBufferSize(const AudioConfig& config, #if MAJOR_VERSION == 2 Return PrimaryDevice::openOutputStream(int32_t ioHandle, const DeviceAddress& device, - const AudioConfig& config, - AudioOutputFlagBitfield flags, + const AudioConfig& config, AudioOutputFlags flags, openOutputStream_cb _hidl_cb) { return mDevice->openOutputStream(ioHandle, device, config, flags, _hidl_cb); } Return PrimaryDevice::openInputStream(int32_t ioHandle, const DeviceAddress& device, - const AudioConfig& config, AudioInputFlagBitfield flags, + const AudioConfig& config, AudioInputFlags flags, AudioSource source, openInputStream_cb _hidl_cb) { return mDevice->openInputStream(ioHandle, device, config, flags, source, _hidl_cb); } #elif MAJOR_VERSION >= 4 Return PrimaryDevice::openOutputStream(int32_t ioHandle, const DeviceAddress& device, const AudioConfig& config, - AudioOutputFlagBitfield flags, +#if MAJOR_VERSION <= 6 + AudioOutputFlags flags, +#else + const AudioOutputFlags& flags, +#endif const SourceMetadata& sourceMetadata, openOutputStream_cb _hidl_cb) { return mDevice->openOutputStream(ioHandle, device, config, flags, sourceMetadata, _hidl_cb); } Return PrimaryDevice::openInputStream(int32_t ioHandle, const DeviceAddress& device, - const AudioConfig& config, AudioInputFlagBitfield flags, + const AudioConfig& config, +#if MAJOR_VERSION <= 6 + AudioInputFlags flags, +#else + const AudioInputFlags& flags, +#endif const SinkMetadata& sinkMetadata, openInputStream_cb _hidl_cb) { return mDevice->openInputStream(ioHandle, device, config, flags, sinkMetadata, _hidl_cb); diff --git a/audio/core/all-versions/default/Stream.cpp b/audio/core/all-versions/default/Stream.cpp index 74e59450f0..c74079d9ce 100644 --- a/audio/core/all-versions/default/Stream.cpp +++ b/audio/core/all-versions/default/Stream.cpp @@ -23,6 +23,7 @@ #include +#include #include #include #include @@ -35,7 +36,11 @@ namespace audio { namespace CPP_VERSION { namespace implementation { -Stream::Stream(audio_stream_t* stream) : mStream(stream) {} +using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils; + +Stream::Stream(bool isInput, audio_stream_t* stream) : mIsInput(isInput), mStream(stream) { + (void)mIsInput; // prevent 'unused field' warnings in pre-V7 versions. +} Stream::~Stream() { mStream = nullptr; @@ -78,6 +83,7 @@ Return Stream::getBufferSize() { return mStream->get_buffer_size(mStream); } +#if MAJOR_VERSION <= 6 Return Stream::getSampleRate() { return mStream->get_sample_rate(mStream); } @@ -201,6 +207,96 @@ Return Stream::getAudioProperties(getAudioProperties_cb _hidl_cb) { return Void(); } +#else // MAJOR_VERSION <= 6 + +Return Stream::getSupportedProfiles(getSupportedProfiles_cb _hidl_cb) { + String8 halListValue; + Result result = getParam(AudioParameter::keyStreamSupportedFormats, &halListValue); + hidl_vec profiles; + if (result != Result::OK) { + _hidl_cb(result, profiles); + return Void(); + } + // Ensure that the separator is one character, despite that it's defined as a C string. + static_assert(sizeof(AUDIO_PARAMETER_VALUE_LIST_SEPARATOR) == 2); + std::vector halFormats = + util::splitString(halListValue.string(), AUDIO_PARAMETER_VALUE_LIST_SEPARATOR[0]); + hidl_vec formats; + (void)HidlUtils::audioFormatsFromHal(halFormats, &formats); + std::vector tempProfiles; + for (const auto& format : formats) { + audio_format_t halFormat; + if (status_t status = HidlUtils::audioFormatToHal(format, &halFormat); status != NO_ERROR) { + continue; + } + AudioParameter context; + context.addInt(String8(AUDIO_PARAMETER_STREAM_FORMAT), int(halFormat)); + // Query supported sample rates for the format. + result = getParam(AudioParameter::keyStreamSupportedSamplingRates, &halListValue, context); + if (result != Result::OK) break; + std::vector halSampleRates = + util::splitString(halListValue.string(), AUDIO_PARAMETER_VALUE_LIST_SEPARATOR[0]); + hidl_vec sampleRates; + sampleRates.resize(halSampleRates.size()); + for (size_t i = 0; i < sampleRates.size(); ++i) { + sampleRates[i] = std::stoi(halSampleRates[i]); + } + // Query supported channel masks for the format. + result = getParam(AudioParameter::keyStreamSupportedChannels, &halListValue, context); + if (result != Result::OK) break; + std::vector halChannelMasks = + util::splitString(halListValue.string(), AUDIO_PARAMETER_VALUE_LIST_SEPARATOR[0]); + hidl_vec channelMasks; + (void)HidlUtils::audioChannelMasksFromHal(halChannelMasks, &channelMasks); + // Create a profile. + if (channelMasks.size() != 0 && sampleRates.size() != 0) { + tempProfiles.push_back({.format = format, + .sampleRates = std::move(sampleRates), + .channelMasks = std::move(channelMasks)}); + } + } + // Legacy get_parameter does not return a status_t, thus can not advertise of failure. + // Note that the method must not return an empty list if this capability is supported. + if (!tempProfiles.empty()) { + profiles = tempProfiles; + } else { + result = Result::NOT_SUPPORTED; + } + _hidl_cb(result, profiles); + return Void(); +} + +Return Stream::getAudioProperties(getAudioProperties_cb _hidl_cb) { + audio_config_base_t halConfigBase = {mStream->get_sample_rate(mStream), + mStream->get_channels(mStream), + mStream->get_format(mStream)}; + AudioConfigBase configBase = {}; + status_t status = HidlUtils::audioConfigBaseFromHal(halConfigBase, mIsInput, &configBase); + _hidl_cb(Stream::analyzeStatus("get_audio_properties", status), configBase); + return Void(); +} + +Return Stream::setAudioProperties(const AudioConfigBase& config) { + audio_config_base_t halConfigBase = {}; + status_t status = HidlUtils::audioConfigBaseToHal(config, &halConfigBase); + if (status != NO_ERROR) { + return Stream::analyzeStatus("set_audio_properties", status); + } + if (Result result = setParam(AudioParameter::keySamplingRate, + static_cast(halConfigBase.sample_rate)); + result != Result::OK) { + return result; + } + if (Result result = + setParam(AudioParameter::keyChannels, static_cast(halConfigBase.channel_mask)); + result != Result::OK) { + return result; + } + return setParam(AudioParameter::keyFormat, static_cast(halConfigBase.format)); +} + +#endif // MAJOR_VERSION <= 6 + Return Stream::addEffect(uint64_t effectId) { effect_handle_t halEffect = EffectMap::getInstance().get(effectId); if (halEffect != NULL) { @@ -257,12 +353,14 @@ Return Stream::setConnectedState(const DeviceAddress& address, bool conn } #elif MAJOR_VERSION >= 4 Return Stream::getDevices(getDevices_cb _hidl_cb) { - int device = 0; - Result retval = getParam(AudioParameter::keyRouting, &device); + int halDevice = 0; + Result retval = getParam(AudioParameter::keyRouting, &halDevice); hidl_vec devices; if (retval == Result::OK) { devices.resize(1); - devices[0].device = static_cast(device); + retval = Stream::analyzeStatus("get_devices", + deviceAddressFromHal(static_cast(halDevice), + nullptr, &devices[0])); } _hidl_cb(retval, devices); return Void(); @@ -273,14 +371,13 @@ Return Stream::setDevices(const hidl_vec& devices) { if (devices.size() > 1) { return Result::NOT_SUPPORTED; } - DeviceAddress address; + DeviceAddress address{}; if (devices.size() == 1) { address = devices[0]; - } else { - address.device = AudioDevice::NONE; } return setParam(AudioParameter::keyRouting, address); } + Return Stream::getParameters(const hidl_vec& context, const hidl_vec& keys, getParameters_cb _hidl_cb) { getParametersImpl(context, keys, _hidl_cb); diff --git a/audio/core/all-versions/default/StreamIn.cpp b/audio/core/all-versions/default/StreamIn.cpp index f1152ca542..ead7204712 100644 --- a/audio/core/all-versions/default/StreamIn.cpp +++ b/audio/core/all-versions/default/StreamIn.cpp @@ -24,11 +24,12 @@ //#define LOG_NDEBUG 0 #define ATRACE_TAG ATRACE_TAG_AUDIO +#include #include #include #include -#include #include +#include namespace android { namespace hardware { @@ -36,6 +37,8 @@ namespace audio { namespace CPP_VERSION { namespace implementation { +using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils; + namespace { class ReadThread : public Thread { @@ -141,7 +144,7 @@ bool ReadThread::threadLoop() { StreamIn::StreamIn(const sp& device, audio_stream_in_t* stream) : mDevice(device), mStream(stream), - mStreamCommon(new Stream(&stream->common)), + mStreamCommon(new Stream(true /*isInput*/, &stream->common)), mStreamMmap(new StreamMmap(stream)), mEfGroup(nullptr), mStopReadThread(false) {} @@ -177,6 +180,7 @@ Return StreamIn::getBufferSize() { return mStreamCommon->getBufferSize(); } +#if MAJOR_VERSION <= 6 Return StreamIn::getSampleRate() { return mStreamCommon->getSampleRate(); } @@ -223,6 +227,18 @@ Return StreamIn::setFormat(AudioFormat format) { return mStreamCommon->setFormat(format); } +#else + +Return StreamIn::getSupportedProfiles(getSupportedProfiles_cb _hidl_cb) { + return mStreamCommon->getSupportedProfiles(_hidl_cb); +} + +Return StreamIn::setAudioProperties(const AudioConfigBase& config) { + return mStreamCommon->setAudioProperties(config); +} + +#endif // MAJOR_VERSION <= 6 + Return StreamIn::getAudioProperties(getAudioProperties_cb _hidl_cb) { return mStreamCommon->getAudioProperties(_hidl_cb); } @@ -321,9 +337,11 @@ Return StreamIn::close() { Return StreamIn::getAudioSource(getAudioSource_cb _hidl_cb) { int halSource; Result retval = mStreamCommon->getParam(AudioParameter::keyInputSource, &halSource); - AudioSource source(AudioSource::DEFAULT); + AudioSource source = {}; if (retval == Result::OK) { - source = AudioSource(halSource); + retval = Stream::analyzeStatus( + "get_audio_source", + HidlUtils::audioSourceFromHal(static_cast(halSource), &source)); } _hidl_cb(retval, source); return Void(); @@ -340,7 +358,11 @@ Return StreamIn::setGain(float gain) { Return StreamIn::prepareForReading(uint32_t frameSize, uint32_t framesCount, prepareForReading_cb _hidl_cb) { status_t status; +#if MAJOR_VERSION <= 6 ThreadInfo threadInfo = {0, 0}; +#else + int32_t threadInfo = 0; +#endif // Wrap the _hidl_cb to return an error auto sendError = [&threadInfo, &_hidl_cb](Result result) { @@ -410,8 +432,12 @@ Return StreamIn::prepareForReading(uint32_t frameSize, uint32_t framesCoun mStatusMQ = std::move(tempStatusMQ); mReadThread = tempReadThread.release(); mEfGroup = tempElfGroup.release(); +#if MAJOR_VERSION <= 6 threadInfo.pid = getpid(); threadInfo.tid = mReadThread->getTid(); +#else + threadInfo = mReadThread->getTid(); +#endif _hidl_cb(Result::OK, *mCommandMQ->getDesc(), *mDataMQ->getDesc(), *mStatusMQ->getDesc(), threadInfo); return Void(); @@ -459,16 +485,13 @@ Return StreamIn::updateSinkMetadata(const SinkMetadata& sinkMetadata) { std::vector halTracks; halTracks.reserve(sinkMetadata.tracks.size()); for (auto& metadata : sinkMetadata.tracks) { - record_track_metadata halTrackMetadata = { - .source = static_cast(metadata.source), .gain = metadata.gain}; + record_track_metadata halTrackMetadata = {.gain = metadata.gain}; + (void)HidlUtils::audioSourceToHal(metadata.source, &halTrackMetadata.source); #if MAJOR_VERSION >= 5 if (metadata.destination.getDiscriminator() == RecordTrackMetadata::Destination::hidl_discriminator::device) { - halTrackMetadata.dest_device = - static_cast(metadata.destination.device().device); - strncpy(halTrackMetadata.dest_device_address, - deviceAddressToHal(metadata.destination.device()).c_str(), - AUDIO_DEVICE_MAX_ADDRESS_LEN); + (void)deviceAddressToHal(metadata.destination.device(), &halTrackMetadata.dest_device, + halTrackMetadata.dest_device_address); } #endif halTracks.push_back(halTrackMetadata); diff --git a/audio/core/all-versions/default/StreamOut.cpp b/audio/core/all-versions/default/StreamOut.cpp index 007eb4564a..5633cbb4b7 100644 --- a/audio/core/all-versions/default/StreamOut.cpp +++ b/audio/core/all-versions/default/StreamOut.cpp @@ -26,6 +26,7 @@ #include +#include #include #include #include @@ -36,6 +37,8 @@ namespace audio { namespace CPP_VERSION { namespace implementation { +using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils; + namespace { class WriteThread : public Thread { @@ -142,7 +145,7 @@ bool WriteThread::threadLoop() { StreamOut::StreamOut(const sp& device, audio_stream_out_t* stream) : mDevice(device), mStream(stream), - mStreamCommon(new Stream(&stream->common)), + mStreamCommon(new Stream(false /*isInput*/, &stream->common)), mStreamMmap(new StreamMmap(stream)), mEfGroup(nullptr), mStopWriteThread(false) {} @@ -182,6 +185,7 @@ Return StreamOut::getBufferSize() { return mStreamCommon->getBufferSize(); } +#if MAJOR_VERSION <= 6 Return StreamOut::getSampleRate() { return mStreamCommon->getSampleRate(); } @@ -228,6 +232,18 @@ Return StreamOut::setFormat(AudioFormat format) { return mStreamCommon->setFormat(format); } +#else + +Return StreamOut::getSupportedProfiles(getSupportedProfiles_cb _hidl_cb) { + return mStreamCommon->getSupportedProfiles(_hidl_cb); +} + +Return StreamOut::setAudioProperties(const AudioConfigBase& config) { + return mStreamCommon->setAudioProperties(config); +} + +#endif // MAJOR_VERSION <= 6 + Return StreamOut::getAudioProperties(getAudioProperties_cb _hidl_cb) { return mStreamCommon->getAudioProperties(_hidl_cb); } @@ -327,7 +343,11 @@ Return StreamOut::setVolume(float left, float right) { Return StreamOut::prepareForWriting(uint32_t frameSize, uint32_t framesCount, prepareForWriting_cb _hidl_cb) { status_t status; +#if MAJOR_VERSION <= 6 ThreadInfo threadInfo = {0, 0}; +#else + int32_t threadInfo = 0; +#endif // Wrap the _hidl_cb to return an error auto sendError = [&threadInfo, &_hidl_cb](Result result) { @@ -396,8 +416,12 @@ Return StreamOut::prepareForWriting(uint32_t frameSize, uint32_t framesCou mStatusMQ = std::move(tempStatusMQ); mWriteThread = tempWriteThread.release(); mEfGroup = tempElfGroup.release(); +#if MAJOR_VERSION <= 6 threadInfo.pid = getpid(); threadInfo.tid = mWriteThread->getTid(); +#else + threadInfo = mWriteThread->getTid(); +#endif _hidl_cb(Result::OK, *mCommandMQ->getDesc(), *mDataMQ->getDesc(), *mStatusMQ->getDesc(), threadInfo); return Void(); @@ -565,14 +589,14 @@ Return StreamOut::updateSourceMetadata(const SourceMetadata& sourceMetadat if (mStream->update_source_metadata == nullptr) { return Void(); // not supported by the HAL } - std::vector halTracks; + std::vector halTracks; halTracks.reserve(sourceMetadata.tracks.size()); for (auto& metadata : sourceMetadata.tracks) { - halTracks.push_back({ - .usage = static_cast(metadata.usage), - .content_type = static_cast(metadata.contentType), - .gain = metadata.gain, - }); + playback_track_metadata_t halTrackMetadata = {.gain = metadata.gain}; + (void)HidlUtils::audioUsageToHal(metadata.usage, &halTrackMetadata.usage); + (void)HidlUtils::audioContentTypeToHal(metadata.contentType, + &halTrackMetadata.content_type); + halTracks.push_back(std::move(halTrackMetadata)); } const source_metadata_t halMetadata = { .track_count = halTracks.size(), diff --git a/audio/core/all-versions/default/include/core/default/Conversions.h b/audio/core/all-versions/default/include/core/default/Conversions.h index cb7914fceb..2372771b85 100644 --- a/audio/core/all-versions/default/include/core/default/Conversions.h +++ b/audio/core/all-versions/default/include/core/default/Conversions.h @@ -23,22 +23,54 @@ #include +#include + namespace android { namespace hardware { namespace audio { namespace CPP_VERSION { namespace implementation { +using ::android::hardware::hidl_vec; using namespace ::android::hardware::audio::common::CPP_VERSION; using namespace ::android::hardware::audio::CPP_VERSION; +#if MAJOR_VERSION <= 6 +// Temporary version for compatibility with forks of the default implementation. +// Will be removed, do not use! std::string deviceAddressToHal(const DeviceAddress& address); +#endif + +status_t deviceAddressToHal(const DeviceAddress& device, audio_devices_t* halDeviceType, + char* halDeviceAddress); +status_t deviceAddressFromHal(audio_devices_t halDeviceType, const char* halDeviceAddress, + DeviceAddress* device); #if MAJOR_VERSION >= 4 bool halToMicrophoneCharacteristics(MicrophoneInfo* pDst, const struct audio_microphone_characteristic_t& src); #endif +#if MAJOR_VERSION <= 6 +using AudioInputFlags = + ::android::hardware::audio::common::CPP_VERSION::implementation::AudioInputFlagBitfield; +using AudioOutputFlags = + ::android::hardware::audio::common::CPP_VERSION::implementation::AudioOutputFlagBitfield; + +inline bool audioInputFlagsToHal(AudioInputFlags flags, audio_input_flags_t* halFlags) { + *halFlags = static_cast(flags); + return true; +} + +inline bool audioOutputFlagsToHal(AudioOutputFlags flags, audio_output_flags_t* halFlags) { + *halFlags = static_cast(flags); + return true; +} +#else +bool audioInputFlagsToHal(const hidl_vec& flags, audio_input_flags_t* halFlags); +bool audioOutputFlagsToHal(const hidl_vec& flags, audio_output_flags_t* halFlags); +#endif + } // namespace implementation } // namespace CPP_VERSION } // namespace audio diff --git a/audio/core/all-versions/default/include/core/default/Device.h b/audio/core/all-versions/default/include/core/default/Device.h index 907acd7d7d..461c253768 100644 --- a/audio/core/all-versions/default/include/core/default/Device.h +++ b/audio/core/all-versions/default/include/core/default/Device.h @@ -44,8 +44,13 @@ using ::android::hardware::hidl_vec; using ::android::hardware::Return; using ::android::hardware::Void; #if MAJOR_VERSION <= 6 -using ::android::hardware::audio::common::CPP_VERSION::implementation::AudioInputFlagBitfield; -using ::android::hardware::audio::common::CPP_VERSION::implementation::AudioOutputFlagBitfield; +using AudioInputFlags = + ::android::hardware::audio::common::CPP_VERSION::implementation::AudioInputFlagBitfield; +using AudioOutputFlags = + ::android::hardware::audio::common::CPP_VERSION::implementation::AudioOutputFlagBitfield; +#else +using AudioInputFlags = hidl_vec<::android::hardware::audio::CPP_VERSION::AudioInOutFlag>; +using AudioOutputFlags = hidl_vec<::android::hardware::audio::CPP_VERSION::AudioInOutFlag>; #endif using namespace ::android::hardware::audio::common::CPP_VERSION; using namespace ::android::hardware::audio::CPP_VERSION; @@ -67,28 +72,36 @@ struct Device : public IDevice, public ParametersUtil { std::tuple> openOutputStreamImpl(int32_t ioHandle, const DeviceAddress& device, const AudioConfig& config, - AudioOutputFlagBitfield flags, + const AudioOutputFlags& flags, AudioConfig* suggestedConfig); std::tuple> openInputStreamImpl( - int32_t ioHandle, const DeviceAddress& device, const AudioConfig& config, - AudioInputFlagBitfield flags, AudioSource source, AudioConfig* suggestedConfig); -#if MAJOR_VERSION == 2 - Return openOutputStream(int32_t ioHandle, const DeviceAddress& device, - const AudioConfig& config, AudioOutputFlagBitfield flags, - openOutputStream_cb _hidl_cb) override; - Return openInputStream(int32_t ioHandle, const DeviceAddress& device, - const AudioConfig& config, AudioInputFlagBitfield flags, - AudioSource source, openInputStream_cb _hidl_cb) override; -#elif MAJOR_VERSION >= 4 + int32_t ioHandle, const DeviceAddress& device, const AudioConfig& config, + const AudioInputFlags& flags, AudioSource source, AudioConfig* suggestedConfig); + Return openOutputStream(int32_t ioHandle, const DeviceAddress& device, - const AudioConfig& config, AudioOutputFlagBitfield flags, + const AudioConfig& config, +#if MAJOR_VERSION <= 6 + AudioOutputFlags flags, +#else + const AudioOutputFlags& flags, +#endif +#if MAJOR_VERSION >= 4 const SourceMetadata& sourceMetadata, +#endif openOutputStream_cb _hidl_cb) override; Return openInputStream(int32_t ioHandle, const DeviceAddress& device, - const AudioConfig& config, AudioInputFlagBitfield flags, + const AudioConfig& config, +#if MAJOR_VERSION <= 6 + AudioInputFlags flags, +#else + const AudioInputFlags& flags, +#endif +#if MAJOR_VERSION == 2 + AudioSource source, +#elif MAJOR_VERSION >= 4 const SinkMetadata& sinkMetadata, - openInputStream_cb _hidl_cb) override; #endif + openInputStream_cb _hidl_cb) override; Return supportsAudioPatches() override; Return createAudioPatch(const hidl_vec& sources, diff --git a/audio/core/all-versions/default/include/core/default/PrimaryDevice.h b/audio/core/all-versions/default/include/core/default/PrimaryDevice.h index ccdb7b26c1..5f65acfcf1 100644 --- a/audio/core/all-versions/default/include/core/default/PrimaryDevice.h +++ b/audio/core/all-versions/default/include/core/default/PrimaryDevice.h @@ -54,21 +54,29 @@ struct PrimaryDevice : public IPrimaryDevice { getInputBufferSize_cb _hidl_cb) override; Return openOutputStream(int32_t ioHandle, const DeviceAddress& device, - const AudioConfig& config, AudioOutputFlagBitfield flags, + const AudioConfig& config, +#if MAJOR_VERSION <= 6 + AudioOutputFlags flags, +#else + const AudioOutputFlags& flags, +#endif #if MAJOR_VERSION >= 4 const SourceMetadata& sourceMetadata, #endif openOutputStream_cb _hidl_cb) override; - Return openInputStream(int32_t ioHandle, const DeviceAddress& device, - const AudioConfig& config, AudioInputFlagBitfield flags, - AudioSource source, openInputStream_cb _hidl_cb); -#if MAJOR_VERSION >= 4 - Return openInputStream(int32_t ioHandle, const DeviceAddress& device, - const AudioConfig& config, AudioInputFlagBitfield flags, + const AudioConfig& config, +#if MAJOR_VERSION <= 6 + AudioInputFlags flags, +#else + const AudioInputFlags& flags, +#endif +#if MAJOR_VERSION == 2 + AudioSource source, +#elif MAJOR_VERSION >= 4 const SinkMetadata& sinkMetadata, - openInputStream_cb _hidl_cb) override; #endif + openInputStream_cb _hidl_cb) override; Return supportsAudioPatches() override; Return createAudioPatch(const hidl_vec& sources, diff --git a/audio/core/all-versions/default/include/core/default/Stream.h b/audio/core/all-versions/default/include/core/default/Stream.h index ce0003bfbf..0865992f95 100644 --- a/audio/core/all-versions/default/include/core/default/Stream.h +++ b/audio/core/all-versions/default/include/core/default/Stream.h @@ -41,12 +41,14 @@ using ::android::hardware::hidl_string; using ::android::hardware::hidl_vec; using ::android::hardware::Return; using ::android::hardware::Void; +#if MAJOR_VERSION <= 6 using ::android::hardware::audio::common::CPP_VERSION::implementation::AudioChannelBitfield; +#endif using namespace ::android::hardware::audio::common::CPP_VERSION; using namespace ::android::hardware::audio::CPP_VERSION; struct Stream : public IStream, public ParametersUtil { - explicit Stream(audio_stream_t* stream); + Stream(bool isInput, audio_stream_t* stream); /** 1GiB is the maximum buffer size the HAL client is allowed to request. * This value has been chosen to be under SIZE_MAX and still big enough @@ -59,6 +61,7 @@ struct Stream : public IStream, public ParametersUtil { Return getFrameSize() override; Return getFrameCount() override; Return getBufferSize() override; +#if MAJOR_VERSION <= 6 Return getSampleRate() override; #if MAJOR_VERSION == 2 Return getSupportedSampleRates(getSupportedSampleRates_cb _hidl_cb) override; @@ -72,6 +75,10 @@ struct Stream : public IStream, public ParametersUtil { Return getFormat() override; Return getSupportedFormats(getSupportedFormats_cb _hidl_cb) override; Return setFormat(AudioFormat format) override; +#else + Return getSupportedProfiles(getSupportedProfiles_cb _hidl_cb) override; + Return setAudioProperties(const AudioConfigBase& config) override; +#endif // MAJOR_VERSION <= 6 Return getAudioProperties(getAudioProperties_cb _hidl_cb) override; Return addEffect(uint64_t effectId) override; Return removeEffect(uint64_t effectId) override; @@ -110,13 +117,14 @@ struct Stream : public IStream, public ParametersUtil { const std::vector& ignoreErrors); private: - audio_stream_t* mStream; + const bool mIsInput; + audio_stream_t* mStream; - virtual ~Stream(); + virtual ~Stream(); - // Methods from ParametersUtil. - char* halGetParameters(const char* keys) override; - int halSetParameters(const char* keysAndValues) override; + // Methods from ParametersUtil. + char* halGetParameters(const char* keys) override; + int halSetParameters(const char* keysAndValues) override; }; template diff --git a/audio/core/all-versions/default/include/core/default/StreamIn.h b/audio/core/all-versions/default/include/core/default/StreamIn.h index 24f994406c..b861c6cc2b 100644 --- a/audio/core/all-versions/default/include/core/default/StreamIn.h +++ b/audio/core/all-versions/default/include/core/default/StreamIn.h @@ -56,6 +56,7 @@ struct StreamIn : public IStreamIn { Return getFrameSize() override; Return getFrameCount() override; Return getBufferSize() override; +#if MAJOR_VERSION <= 6 Return getSampleRate() override; #if MAJOR_VERSION == 2 Return getSupportedSampleRates(getSupportedSampleRates_cb _hidl_cb) override; @@ -69,6 +70,10 @@ struct StreamIn : public IStreamIn { Return getFormat() override; Return getSupportedFormats(getSupportedFormats_cb _hidl_cb) override; Return setFormat(AudioFormat format) override; +#else + Return getSupportedProfiles(getSupportedProfiles_cb _hidl_cb) override; + Return setAudioProperties(const AudioConfigBase& config) override; +#endif // MAJOR_VERSION <= 6 Return getAudioProperties(getAudioProperties_cb _hidl_cb) override; Return addEffect(uint64_t effectId) override; Return removeEffect(uint64_t effectId) override; diff --git a/audio/core/all-versions/default/include/core/default/StreamOut.h b/audio/core/all-versions/default/include/core/default/StreamOut.h index e647da9b96..9f64e3e77d 100644 --- a/audio/core/all-versions/default/include/core/default/StreamOut.h +++ b/audio/core/all-versions/default/include/core/default/StreamOut.h @@ -56,6 +56,7 @@ struct StreamOut : public IStreamOut { Return getFrameSize() override; Return getFrameCount() override; Return getBufferSize() override; +#if MAJOR_VERSION <= 6 Return getSampleRate() override; #if MAJOR_VERSION == 2 Return getSupportedSampleRates(getSupportedSampleRates_cb _hidl_cb) override; @@ -69,6 +70,10 @@ struct StreamOut : public IStreamOut { Return getFormat() override; Return getSupportedFormats(getSupportedFormats_cb _hidl_cb) override; Return setFormat(AudioFormat format) override; +#else + Return getSupportedProfiles(getSupportedProfiles_cb _hidl_cb) override; + Return setAudioProperties(const AudioConfigBase& config) override; +#endif // MAJOR_VERSION <= 6 Return getAudioProperties(getAudioProperties_cb _hidl_cb) override; Return addEffect(uint64_t effectId) override; Return removeEffect(uint64_t effectId) override; diff --git a/audio/core/all-versions/default/include/core/default/Util.h b/audio/core/all-versions/default/include/core/default/Util.h index 78ae03eab2..3d629cdefd 100644 --- a/audio/core/all-versions/default/include/core/default/Util.h +++ b/audio/core/all-versions/default/include/core/default/Util.h @@ -20,6 +20,8 @@ #include PATH(android/hardware/audio/FILE_VERSION/types.h) #include +#include +#include #include #include @@ -70,6 +72,16 @@ static inline Result analyzeStatus(const char* className, const char* funcName, return analyzeStatus(status); } +static inline std::vector splitString(const std::string& s, char separator) { + std::istringstream iss(s); + std::string t; + std::vector result; + while (std::getline(iss, t, separator)) { + result.push_back(std::move(t)); + } + return result; +} + } // namespace util } // namespace implementation } // namespace CPP_VERSION diff --git a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h index 1ead47c0ca..05c9bf7e2e 100644 --- a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h +++ b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h @@ -1179,9 +1179,11 @@ static void testGetAudioProperties(IStream* stream, AudioConfig expectedConfig) EXPECT_EQ(expectedConfig.channelMask, mask); EXPECT_EQ(expectedConfig.format, format); #elif MAJOR_VERSION >= 7 + Result res; AudioConfigBase actualConfig{}; - auto ret = stream->getAudioProperties(returnIn(actualConfig)); + auto ret = stream->getAudioProperties(returnIn(res, actualConfig)); EXPECT_TRUE(ret.isOk()); + EXPECT_EQ(Result::OK, res); EXPECT_EQ(expectedConfig.base.sampleRateHz, actualConfig.sampleRateHz); EXPECT_EQ(expectedConfig.base.channelMask, actualConfig.channelMask); EXPECT_EQ(expectedConfig.base.format, actualConfig.format); -- GitLab From 9036edac049693039e5e348eff280210bd6de856 Mon Sep 17 00:00:00 2001 From: Mikhail Naganov Date: Thu, 10 Dec 2020 18:47:51 -0800 Subject: [PATCH 326/790] audio: Update default effect HAL wrapper to support V7 During this conversion, the functionality of the V7 wrapper hasn't been tested yet. This will be done in a separate CL that will also include required updates to the VTS tests. Since the changes were made to the code shared with pre-V7 versions, verified that V6 HAL didn't regress. Bug: 142480271 Test: atest VtsHalAudioEffectV6_0TargetTest Test: m VtsHalAudioEffectV7_0TargetTest Test: m android.hardware.audio@7.0-service.example Change-Id: I72389c8d564596bef22b47dfdcb2e77d636ef0a3 --- audio/common/7.0/example/Effect.cpp | 16 +- audio/effect/7.0/IVirtualizerEffect.hal | 37 ++-- audio/effect/7.0/types.hal | 8 +- .../default/AcousticEchoCancelerEffect.cpp | 34 ++-- .../default/AcousticEchoCancelerEffect.h | 12 +- audio/effect/all-versions/default/Android.bp | 1 - .../default/AutomaticGainControlEffect.cpp | 34 ++-- .../default/AutomaticGainControlEffect.h | 12 +- .../all-versions/default/BassBoostEffect.cpp | 35 ++-- .../all-versions/default/BassBoostEffect.h | 12 +- .../all-versions/default/DownmixEffect.cpp | 35 ++-- .../all-versions/default/DownmixEffect.h | 12 +- audio/effect/all-versions/default/Effect.cpp | 130 ++++++++++++-- audio/effect/all-versions/default/Effect.h | 30 ++-- .../all-versions/default/EffectsFactory.cpp | 4 +- .../default/EnvironmentalReverbEffect.cpp | 34 ++-- .../default/EnvironmentalReverbEffect.h | 12 +- .../all-versions/default/EqualizerEffect.cpp | 35 ++-- .../all-versions/default/EqualizerEffect.h | 12 +- .../default/LoudnessEnhancerEffect.cpp | 34 ++-- .../default/LoudnessEnhancerEffect.h | 12 +- .../default/NoiseSuppressionEffect.cpp | 34 ++-- .../default/NoiseSuppressionEffect.h | 12 +- .../default/PresetReverbEffect.cpp | 35 ++-- .../all-versions/default/PresetReverbEffect.h | 12 +- .../default/VirtualizerEffect.cpp | 169 +++++++++++++----- .../all-versions/default/VirtualizerEffect.h | 31 +++- .../all-versions/default/VisualizerEffect.cpp | 36 ++-- .../all-versions/default/VisualizerEffect.h | 12 +- .../VtsHalAudioEffectTargetTest.cpp | 12 +- 30 files changed, 658 insertions(+), 246 deletions(-) diff --git a/audio/common/7.0/example/Effect.cpp b/audio/common/7.0/example/Effect.cpp index 9d5ab3198a..27f28c6ea6 100644 --- a/audio/common/7.0/example/Effect.cpp +++ b/audio/common/7.0/example/Effect.cpp @@ -107,14 +107,14 @@ Return Effect::setInputDevice(const DeviceAddress& device) { } Return Effect::getConfig(getConfig_cb _hidl_cb) { - const EffectConfig config = {{} /* inputCfg */, - // outputCfg - {{} /* buffer */, - 48000 /* samplingRateHz */, - toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO), - toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT), - EffectBufferAccess::ACCESS_ACCUMULATE, - 0 /* mask */}}; + const EffectConfig config = { + {} /* inputCfg */, + // outputCfg + {{} /* buffer */, + {toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT), 48000 /* samplingRateHz */, + toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO)}, /* base */ + EffectBufferAccess::ACCESS_ACCUMULATE, + 0 /* mask */}}; _hidl_cb(Result::OK, config); return Void(); } diff --git a/audio/effect/7.0/IVirtualizerEffect.hal b/audio/effect/7.0/IVirtualizerEffect.hal index 141b4e6797..5d11435986 100644 --- a/audio/effect/7.0/IVirtualizerEffect.hal +++ b/audio/effect/7.0/IVirtualizerEffect.hal @@ -46,23 +46,38 @@ interface IVirtualizerEffect extends IEffect { */ getStrength() generates (Result retval, uint16_t strength); - struct SpeakerAngle { + struct SpeakerAngles { /** Speaker channel mask */ - vec mask; - // all angles are expressed in degrees and - // are relative to the listener. - int16_t azimuth; // 0 is the direction the listener faces - // 180 is behind the listener - // -90 is to their left - int16_t elevation; // 0 is the horizontal plane - // +90 is above the listener, -90 is below + AudioChannelMask mask; + /** + * Horizontal speaker position angles for each channel ordered from LSb + * to MSb in the channel mask. The number of values is the number of + * channels in the channel mask. + * + * All angles are expressed in degrees and are relative to the listener. + * - 0 is the direction the listener faces; + * - 180 is behind the listener; + * - -90 is to their left. + */ + vec azimuth; + /** + * Vertical speaker position angles for each channel ordered from LSb + * to MSb in the channel mask. The number of values is the number of + * channels in the channel mask. + * + * All angles are expressed in degrees and are relative to the listener. + * - 0 is the horizontal plane of the listener; + * - +90 is above the listener; + * - -90 is below the listener. + */ + vec elevation; }; /** * Retrieves virtual speaker angles for the given channel mask on the * specified device. */ - getVirtualSpeakerAngles(vec mask, DeviceAddress device) - generates (Result retval, vec speakerAngles); + getVirtualSpeakerAngles(AudioChannelMask mask, DeviceAddress device) + generates (Result retval, SpeakerAngles speakerAngles); /** * Forces the virtualizer effect for the given output device. diff --git a/audio/effect/7.0/types.hal b/audio/effect/7.0/types.hal index b0a0709c31..c4cb213a86 100644 --- a/audio/effect/7.0/types.hal +++ b/audio/effect/7.0/types.hal @@ -271,9 +271,7 @@ enum EffectConfigParameters : int32_t { */ struct EffectBufferConfig { AudioBuffer buffer; - uint32_t samplingRateHz; - AudioChannelMask channels; - AudioFormat format; + AudioConfigBase base; EffectBufferAccess accessMode; bitfield mask; }; @@ -292,9 +290,9 @@ enum EffectFeature : int32_t { struct EffectAuxChannelsConfig { /** Channel mask for main channels. */ - vec mainChannels; + AudioChannelMask mainChannels; /** Channel mask for auxiliary channels. */ - vec auxChannels; + AudioChannelMask auxChannels; }; struct EffectOffloadParameter { diff --git a/audio/effect/all-versions/default/AcousticEchoCancelerEffect.cpp b/audio/effect/all-versions/default/AcousticEchoCancelerEffect.cpp index 137ea246f6..c1a8b559b1 100644 --- a/audio/effect/all-versions/default/AcousticEchoCancelerEffect.cpp +++ b/audio/effect/all-versions/default/AcousticEchoCancelerEffect.cpp @@ -31,9 +31,7 @@ namespace CPP_VERSION { namespace implementation { AcousticEchoCancelerEffect::AcousticEchoCancelerEffect(effect_handle_t handle) - : mEffect(new Effect(handle)) {} - -AcousticEchoCancelerEffect::~AcousticEchoCancelerEffect() {} + : mEffect(new Effect(true /*isInput*/, handle)) {} // Methods from ::android::hardware::audio::effect::CPP_VERSION::IEffect follow. Return AcousticEchoCancelerEffect::init() { @@ -58,10 +56,32 @@ Return AcousticEchoCancelerEffect::disable() { return mEffect->disable(); } +#if MAJOR_VERSION <= 6 +Return AcousticEchoCancelerEffect::setAudioSource(AudioSource source) { + return mEffect->setAudioSource(source); +} + Return AcousticEchoCancelerEffect::setDevice(AudioDeviceBitfield device) { return mEffect->setDevice(device); } +Return AcousticEchoCancelerEffect::setInputDevice(AudioDeviceBitfield device) { + return mEffect->setInputDevice(device); +} +#else +Return AcousticEchoCancelerEffect::setAudioSource(const AudioSource& source) { + return mEffect->setAudioSource(source); +} + +Return AcousticEchoCancelerEffect::setDevice(const DeviceAddress& device) { + return mEffect->setDevice(device); +} + +Return AcousticEchoCancelerEffect::setInputDevice(const DeviceAddress& device) { + return mEffect->setInputDevice(device); +} +#endif + Return AcousticEchoCancelerEffect::setAndGetVolume(const hidl_vec& volumes, setAndGetVolume_cb _hidl_cb) { return mEffect->setAndGetVolume(volumes, _hidl_cb); @@ -82,10 +102,6 @@ Return AcousticEchoCancelerEffect::setConfigReverse( return mEffect->setConfigReverse(config, inputBufferProvider, outputBufferProvider); } -Return AcousticEchoCancelerEffect::setInputDevice(AudioDeviceBitfield device) { - return mEffect->setInputDevice(device); -} - Return AcousticEchoCancelerEffect::getConfig(getConfig_cb _hidl_cb) { return mEffect->getConfig(_hidl_cb); } @@ -108,10 +124,6 @@ Return AcousticEchoCancelerEffect::setAuxChannelsConfig( return mEffect->setAuxChannelsConfig(config); } -Return AcousticEchoCancelerEffect::setAudioSource(AudioSource source) { - return mEffect->setAudioSource(source); -} - Return AcousticEchoCancelerEffect::offload(const EffectOffloadParameter& param) { return mEffect->offload(param); } diff --git a/audio/effect/all-versions/default/AcousticEchoCancelerEffect.h b/audio/effect/all-versions/default/AcousticEchoCancelerEffect.h index 971f64de80..d7a84f295a 100644 --- a/audio/effect/all-versions/default/AcousticEchoCancelerEffect.h +++ b/audio/effect/all-versions/default/AcousticEchoCancelerEffect.h @@ -53,7 +53,15 @@ struct AcousticEchoCancelerEffect : public IAcousticEchoCancelerEffect { Return reset() override; Return enable() override; Return disable() override; +#if MAJOR_VERSION <= 6 + Return setAudioSource(AudioSource source) override; Return setDevice(AudioDeviceBitfield device) override; + Return setInputDevice(AudioDeviceBitfield device) override; +#else + Return setAudioSource(const AudioSource& source) override; + Return setDevice(const DeviceAddress& device) override; + Return setInputDevice(const DeviceAddress& device) override; +#endif Return setAndGetVolume(const hidl_vec& volumes, setAndGetVolume_cb _hidl_cb) override; Return volumeChangeNotification(const hidl_vec& volumes) override; @@ -61,14 +69,12 @@ struct AcousticEchoCancelerEffect : public IAcousticEchoCancelerEffect { Return setConfigReverse( const EffectConfig& config, const sp& inputBufferProvider, const sp& outputBufferProvider) override; - Return setInputDevice(AudioDeviceBitfield device) override; Return getConfig(getConfig_cb _hidl_cb) override; Return getConfigReverse(getConfigReverse_cb _hidl_cb) override; Return getSupportedAuxChannelsConfigs( uint32_t maxConfigs, getSupportedAuxChannelsConfigs_cb _hidl_cb) override; Return getAuxChannelsConfig(getAuxChannelsConfig_cb _hidl_cb) override; Return setAuxChannelsConfig(const EffectAuxChannelsConfig& config) override; - Return setAudioSource(AudioSource source) override; Return offload(const EffectOffloadParameter& param) override; Return getDescriptor(getDescriptor_cb _hidl_cb) override; Return prepareForProcessing(prepareForProcessing_cb _hidl_cb) override; @@ -98,7 +104,7 @@ struct AcousticEchoCancelerEffect : public IAcousticEchoCancelerEffect { private: sp mEffect; - virtual ~AcousticEchoCancelerEffect(); + virtual ~AcousticEchoCancelerEffect() = default; }; } // namespace implementation diff --git a/audio/effect/all-versions/default/Android.bp b/audio/effect/all-versions/default/Android.bp index 1c3dc74f17..a0cd6120e2 100644 --- a/audio/effect/all-versions/default/Android.bp +++ b/audio/effect/all-versions/default/Android.bp @@ -105,7 +105,6 @@ cc_library_shared { } cc_library_shared { - enabled: false, name: "android.hardware.audio.effect@7.0-impl", defaults: ["android.hardware.audio.effect-impl_default"], shared_libs: [ diff --git a/audio/effect/all-versions/default/AutomaticGainControlEffect.cpp b/audio/effect/all-versions/default/AutomaticGainControlEffect.cpp index 655a4cd0b1..110b1b66e2 100644 --- a/audio/effect/all-versions/default/AutomaticGainControlEffect.cpp +++ b/audio/effect/all-versions/default/AutomaticGainControlEffect.cpp @@ -30,9 +30,7 @@ namespace CPP_VERSION { namespace implementation { AutomaticGainControlEffect::AutomaticGainControlEffect(effect_handle_t handle) - : mEffect(new Effect(handle)) {} - -AutomaticGainControlEffect::~AutomaticGainControlEffect() {} + : mEffect(new Effect(true /*isInput*/, handle)) {} void AutomaticGainControlEffect::propertiesFromHal( const t_agc_settings& halProperties, IAutomaticGainControlEffect::AllProperties* properties) { @@ -71,10 +69,32 @@ Return AutomaticGainControlEffect::disable() { return mEffect->disable(); } +#if MAJOR_VERSION <= 6 +Return AutomaticGainControlEffect::setAudioSource(AudioSource source) { + return mEffect->setAudioSource(source); +} + Return AutomaticGainControlEffect::setDevice(AudioDeviceBitfield device) { return mEffect->setDevice(device); } +Return AutomaticGainControlEffect::setInputDevice(AudioDeviceBitfield device) { + return mEffect->setInputDevice(device); +} +#else +Return AutomaticGainControlEffect::setAudioSource(const AudioSource& source) { + return mEffect->setAudioSource(source); +} + +Return AutomaticGainControlEffect::setDevice(const DeviceAddress& device) { + return mEffect->setDevice(device); +} + +Return AutomaticGainControlEffect::setInputDevice(const DeviceAddress& device) { + return mEffect->setInputDevice(device); +} +#endif + Return AutomaticGainControlEffect::setAndGetVolume(const hidl_vec& volumes, setAndGetVolume_cb _hidl_cb) { return mEffect->setAndGetVolume(volumes, _hidl_cb); @@ -95,10 +115,6 @@ Return AutomaticGainControlEffect::setConfigReverse( return mEffect->setConfigReverse(config, inputBufferProvider, outputBufferProvider); } -Return AutomaticGainControlEffect::setInputDevice(AudioDeviceBitfield device) { - return mEffect->setInputDevice(device); -} - Return AutomaticGainControlEffect::getConfig(getConfig_cb _hidl_cb) { return mEffect->getConfig(_hidl_cb); } @@ -121,10 +137,6 @@ Return AutomaticGainControlEffect::setAuxChannelsConfig( return mEffect->setAuxChannelsConfig(config); } -Return AutomaticGainControlEffect::setAudioSource(AudioSource source) { - return mEffect->setAudioSource(source); -} - Return AutomaticGainControlEffect::offload(const EffectOffloadParameter& param) { return mEffect->offload(param); } diff --git a/audio/effect/all-versions/default/AutomaticGainControlEffect.h b/audio/effect/all-versions/default/AutomaticGainControlEffect.h index 67e260aa20..f30d7a51fe 100644 --- a/audio/effect/all-versions/default/AutomaticGainControlEffect.h +++ b/audio/effect/all-versions/default/AutomaticGainControlEffect.h @@ -55,7 +55,15 @@ struct AutomaticGainControlEffect : public IAutomaticGainControlEffect { Return reset() override; Return enable() override; Return disable() override; +#if MAJOR_VERSION <= 6 + Return setAudioSource(AudioSource source) override; Return setDevice(AudioDeviceBitfield device) override; + Return setInputDevice(AudioDeviceBitfield device) override; +#else + Return setAudioSource(const AudioSource& source) override; + Return setDevice(const DeviceAddress& device) override; + Return setInputDevice(const DeviceAddress& device) override; +#endif Return setAndGetVolume(const hidl_vec& volumes, setAndGetVolume_cb _hidl_cb) override; Return volumeChangeNotification(const hidl_vec& volumes) override; @@ -63,14 +71,12 @@ struct AutomaticGainControlEffect : public IAutomaticGainControlEffect { Return setConfigReverse( const EffectConfig& config, const sp& inputBufferProvider, const sp& outputBufferProvider) override; - Return setInputDevice(AudioDeviceBitfield device) override; Return getConfig(getConfig_cb _hidl_cb) override; Return getConfigReverse(getConfigReverse_cb _hidl_cb) override; Return getSupportedAuxChannelsConfigs( uint32_t maxConfigs, getSupportedAuxChannelsConfigs_cb _hidl_cb) override; Return getAuxChannelsConfig(getAuxChannelsConfig_cb _hidl_cb) override; Return setAuxChannelsConfig(const EffectAuxChannelsConfig& config) override; - Return setAudioSource(AudioSource source) override; Return offload(const EffectOffloadParameter& param) override; Return getDescriptor(getDescriptor_cb _hidl_cb) override; Return prepareForProcessing(prepareForProcessing_cb _hidl_cb) override; @@ -107,7 +113,7 @@ struct AutomaticGainControlEffect : public IAutomaticGainControlEffect { private: sp mEffect; - virtual ~AutomaticGainControlEffect(); + virtual ~AutomaticGainControlEffect() = default; void propertiesFromHal(const t_agc_settings& halProperties, IAutomaticGainControlEffect::AllProperties* properties); diff --git a/audio/effect/all-versions/default/BassBoostEffect.cpp b/audio/effect/all-versions/default/BassBoostEffect.cpp index 04fd48615a..33fea3baa4 100644 --- a/audio/effect/all-versions/default/BassBoostEffect.cpp +++ b/audio/effect/all-versions/default/BassBoostEffect.cpp @@ -30,9 +30,8 @@ namespace effect { namespace CPP_VERSION { namespace implementation { -BassBoostEffect::BassBoostEffect(effect_handle_t handle) : mEffect(new Effect(handle)) {} - -BassBoostEffect::~BassBoostEffect() {} +BassBoostEffect::BassBoostEffect(effect_handle_t handle) + : mEffect(new Effect(false /*isInput*/, handle)) {} // Methods from ::android::hardware::audio::effect::CPP_VERSION::IEffect follow. Return BassBoostEffect::init() { @@ -57,10 +56,32 @@ Return BassBoostEffect::disable() { return mEffect->disable(); } +#if MAJOR_VERSION <= 6 +Return BassBoostEffect::setAudioSource(AudioSource source) { + return mEffect->setAudioSource(source); +} + Return BassBoostEffect::setDevice(AudioDeviceBitfield device) { return mEffect->setDevice(device); } +Return BassBoostEffect::setInputDevice(AudioDeviceBitfield device) { + return mEffect->setInputDevice(device); +} +#else +Return BassBoostEffect::setAudioSource(const AudioSource& source) { + return mEffect->setAudioSource(source); +} + +Return BassBoostEffect::setDevice(const DeviceAddress& device) { + return mEffect->setDevice(device); +} + +Return BassBoostEffect::setInputDevice(const DeviceAddress& device) { + return mEffect->setInputDevice(device); +} +#endif + Return BassBoostEffect::setAndGetVolume(const hidl_vec& volumes, setAndGetVolume_cb _hidl_cb) { return mEffect->setAndGetVolume(volumes, _hidl_cb); @@ -80,10 +101,6 @@ Return BassBoostEffect::setConfigReverse( return mEffect->setConfigReverse(config, inputBufferProvider, outputBufferProvider); } -Return BassBoostEffect::setInputDevice(AudioDeviceBitfield device) { - return mEffect->setInputDevice(device); -} - Return BassBoostEffect::getConfig(getConfig_cb _hidl_cb) { return mEffect->getConfig(_hidl_cb); } @@ -105,10 +122,6 @@ Return BassBoostEffect::setAuxChannelsConfig(const EffectAuxChannelsConf return mEffect->setAuxChannelsConfig(config); } -Return BassBoostEffect::setAudioSource(AudioSource source) { - return mEffect->setAudioSource(source); -} - Return BassBoostEffect::offload(const EffectOffloadParameter& param) { return mEffect->offload(param); } diff --git a/audio/effect/all-versions/default/BassBoostEffect.h b/audio/effect/all-versions/default/BassBoostEffect.h index b89bb2212f..48f586c133 100644 --- a/audio/effect/all-versions/default/BassBoostEffect.h +++ b/audio/effect/all-versions/default/BassBoostEffect.h @@ -55,7 +55,15 @@ struct BassBoostEffect : public IBassBoostEffect { Return reset() override; Return enable() override; Return disable() override; +#if MAJOR_VERSION <= 6 + Return setAudioSource(AudioSource source) override; Return setDevice(AudioDeviceBitfield device) override; + Return setInputDevice(AudioDeviceBitfield device) override; +#else + Return setAudioSource(const AudioSource& source) override; + Return setDevice(const DeviceAddress& device) override; + Return setInputDevice(const DeviceAddress& device) override; +#endif Return setAndGetVolume(const hidl_vec& volumes, setAndGetVolume_cb _hidl_cb) override; Return volumeChangeNotification(const hidl_vec& volumes) override; @@ -63,14 +71,12 @@ struct BassBoostEffect : public IBassBoostEffect { Return setConfigReverse( const EffectConfig& config, const sp& inputBufferProvider, const sp& outputBufferProvider) override; - Return setInputDevice(AudioDeviceBitfield device) override; Return getConfig(getConfig_cb _hidl_cb) override; Return getConfigReverse(getConfigReverse_cb _hidl_cb) override; Return getSupportedAuxChannelsConfigs( uint32_t maxConfigs, getSupportedAuxChannelsConfigs_cb _hidl_cb) override; Return getAuxChannelsConfig(getAuxChannelsConfig_cb _hidl_cb) override; Return setAuxChannelsConfig(const EffectAuxChannelsConfig& config) override; - Return setAudioSource(AudioSource source) override; Return offload(const EffectOffloadParameter& param) override; Return getDescriptor(getDescriptor_cb _hidl_cb) override; Return prepareForProcessing(prepareForProcessing_cb _hidl_cb) override; @@ -100,7 +106,7 @@ struct BassBoostEffect : public IBassBoostEffect { private: sp mEffect; - virtual ~BassBoostEffect(); + virtual ~BassBoostEffect() = default; }; } // namespace implementation diff --git a/audio/effect/all-versions/default/DownmixEffect.cpp b/audio/effect/all-versions/default/DownmixEffect.cpp index c001a5f4dc..f324cff424 100644 --- a/audio/effect/all-versions/default/DownmixEffect.cpp +++ b/audio/effect/all-versions/default/DownmixEffect.cpp @@ -30,9 +30,8 @@ namespace effect { namespace CPP_VERSION { namespace implementation { -DownmixEffect::DownmixEffect(effect_handle_t handle) : mEffect(new Effect(handle)) {} - -DownmixEffect::~DownmixEffect() {} +DownmixEffect::DownmixEffect(effect_handle_t handle) + : mEffect(new Effect(false /*isInput*/, handle)) {} // Methods from ::android::hardware::audio::effect::CPP_VERSION::IEffect follow. Return DownmixEffect::init() { @@ -57,10 +56,32 @@ Return DownmixEffect::disable() { return mEffect->disable(); } +#if MAJOR_VERSION <= 6 +Return DownmixEffect::setAudioSource(AudioSource source) { + return mEffect->setAudioSource(source); +} + Return DownmixEffect::setDevice(AudioDeviceBitfield device) { return mEffect->setDevice(device); } +Return DownmixEffect::setInputDevice(AudioDeviceBitfield device) { + return mEffect->setInputDevice(device); +} +#else +Return DownmixEffect::setAudioSource(const AudioSource& source) { + return mEffect->setAudioSource(source); +} + +Return DownmixEffect::setDevice(const DeviceAddress& device) { + return mEffect->setDevice(device); +} + +Return DownmixEffect::setInputDevice(const DeviceAddress& device) { + return mEffect->setInputDevice(device); +} +#endif + Return DownmixEffect::setAndGetVolume(const hidl_vec& volumes, setAndGetVolume_cb _hidl_cb) { return mEffect->setAndGetVolume(volumes, _hidl_cb); @@ -80,10 +101,6 @@ Return DownmixEffect::setConfigReverse( return mEffect->setConfigReverse(config, inputBufferProvider, outputBufferProvider); } -Return DownmixEffect::setInputDevice(AudioDeviceBitfield device) { - return mEffect->setInputDevice(device); -} - Return DownmixEffect::getConfig(getConfig_cb _hidl_cb) { return mEffect->getConfig(_hidl_cb); } @@ -105,10 +122,6 @@ Return DownmixEffect::setAuxChannelsConfig(const EffectAuxChannelsConfig return mEffect->setAuxChannelsConfig(config); } -Return DownmixEffect::setAudioSource(AudioSource source) { - return mEffect->setAudioSource(source); -} - Return DownmixEffect::offload(const EffectOffloadParameter& param) { return mEffect->offload(param); } diff --git a/audio/effect/all-versions/default/DownmixEffect.h b/audio/effect/all-versions/default/DownmixEffect.h index 40e462ea41..caacd06126 100644 --- a/audio/effect/all-versions/default/DownmixEffect.h +++ b/audio/effect/all-versions/default/DownmixEffect.h @@ -53,7 +53,15 @@ struct DownmixEffect : public IDownmixEffect { Return reset() override; Return enable() override; Return disable() override; +#if MAJOR_VERSION <= 6 + Return setAudioSource(AudioSource source) override; Return setDevice(AudioDeviceBitfield device) override; + Return setInputDevice(AudioDeviceBitfield device) override; +#else + Return setAudioSource(const AudioSource& source) override; + Return setDevice(const DeviceAddress& device) override; + Return setInputDevice(const DeviceAddress& device) override; +#endif Return setAndGetVolume(const hidl_vec& volumes, setAndGetVolume_cb _hidl_cb) override; Return volumeChangeNotification(const hidl_vec& volumes) override; @@ -61,14 +69,12 @@ struct DownmixEffect : public IDownmixEffect { Return setConfigReverse( const EffectConfig& config, const sp& inputBufferProvider, const sp& outputBufferProvider) override; - Return setInputDevice(AudioDeviceBitfield device) override; Return getConfig(getConfig_cb _hidl_cb) override; Return getConfigReverse(getConfigReverse_cb _hidl_cb) override; Return getSupportedAuxChannelsConfigs( uint32_t maxConfigs, getSupportedAuxChannelsConfigs_cb _hidl_cb) override; Return getAuxChannelsConfig(getAuxChannelsConfig_cb _hidl_cb) override; Return setAuxChannelsConfig(const EffectAuxChannelsConfig& config) override; - Return setAudioSource(AudioSource source) override; Return offload(const EffectOffloadParameter& param) override; Return getDescriptor(getDescriptor_cb _hidl_cb) override; Return prepareForProcessing(prepareForProcessing_cb _hidl_cb) override; @@ -97,7 +103,7 @@ struct DownmixEffect : public IDownmixEffect { private: sp mEffect; - virtual ~DownmixEffect(); + virtual ~DownmixEffect() = default; }; } // namespace implementation diff --git a/audio/effect/all-versions/default/Effect.cpp b/audio/effect/all-versions/default/Effect.cpp index 406a571bef..edd364cd9b 100644 --- a/audio/effect/all-versions/default/Effect.cpp +++ b/audio/effect/all-versions/default/Effect.cpp @@ -27,6 +27,7 @@ #define ATRACE_TAG ATRACE_TAG_AUDIO +#include #include #include #include @@ -40,7 +41,10 @@ namespace effect { namespace CPP_VERSION { namespace implementation { +#if MAJOR_VERSION <= 6 using ::android::hardware::audio::common::CPP_VERSION::implementation::AudioChannelBitfield; +#endif +using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils; namespace { @@ -136,9 +140,12 @@ bool ProcessThread::threadLoop() { const char* Effect::sContextResultOfCommand = "returned status"; const char* Effect::sContextCallToCommand = "error"; const char* Effect::sContextCallFunction = sContextCallToCommand; +const char* Effect::sContextConversion = "conversion"; -Effect::Effect(effect_handle_t handle) - : mHandle(handle), mEfGroup(nullptr), mStopProcessThread(false) {} +Effect::Effect(bool isInput, effect_handle_t handle) + : mIsInput(isInput), mHandle(handle), mEfGroup(nullptr), mStopProcessThread(false) { + (void)mIsInput; // prevent 'unused field' warnings in pre-V7 versions. +} Effect::~Effect() { ATRACE_CALL(); @@ -180,7 +187,8 @@ std::unique_ptr Effect::hidlVecToHal(const hidl_vec& vec, uint32_t return halData; } -// static +#if MAJOR_VERSION <= 6 + void Effect::effectAuxChannelsConfigFromHal(const channel_config_t& halConfig, EffectAuxChannelsConfig* config) { config->mainChannels = AudioChannelBitfield(halConfig.main_channels); @@ -194,7 +202,6 @@ void Effect::effectAuxChannelsConfigToHal(const EffectAuxChannelsConfig& config, halConfig->aux_channels = static_cast(config.auxChannels); } -// static void Effect::effectBufferConfigFromHal(const buffer_config_t& halConfig, EffectBufferConfig* config) { config->buffer.id = 0; @@ -223,7 +230,56 @@ void Effect::effectBufferConfigToHal(const EffectBufferConfig& config, buffer_co halConfig->mask = static_cast(config.mask); } +#else // MAJOR_VERSION <= 6 + +void Effect::effectAuxChannelsConfigFromHal(const channel_config_t& halConfig, + EffectAuxChannelsConfig* config) { + (void)HidlUtils::audioChannelMaskFromHal(halConfig.main_channels, mIsInput, + &config->mainChannels); + (void)HidlUtils::audioChannelMaskFromHal(halConfig.aux_channels, mIsInput, + &config->auxChannels); +} + +// static +void Effect::effectAuxChannelsConfigToHal(const EffectAuxChannelsConfig& config, + channel_config_t* halConfig) { + (void)HidlUtils::audioChannelMaskToHal(config.mainChannels, &halConfig->main_channels); + (void)HidlUtils::audioChannelMaskToHal(config.auxChannels, &halConfig->aux_channels); +} + +void Effect::effectBufferConfigFromHal(const buffer_config_t& halConfig, + EffectBufferConfig* config) { + config->buffer.id = 0; + config->buffer.frameCount = 0; + audio_config_base_t halConfigBase = {halConfig.samplingRate, + static_cast(halConfig.channels), + static_cast(halConfig.format)}; + (void)HidlUtils::audioConfigBaseFromHal(halConfigBase, mIsInput, &config->base); + config->accessMode = EffectBufferAccess(halConfig.accessMode); + config->mask = static_castmask)>(halConfig.mask); +} + // static +void Effect::effectBufferConfigToHal(const EffectBufferConfig& config, buffer_config_t* halConfig) { + // Note: setting the buffers directly is considered obsolete. They need to be set + // using 'setProcessBuffers'. + halConfig->buffer.frameCount = 0; + halConfig->buffer.raw = nullptr; + audio_config_base_t halConfigBase; + (void)HidlUtils::audioConfigBaseToHal(config.base, &halConfigBase); + halConfig->samplingRate = halConfigBase.sample_rate; + halConfig->channels = halConfigBase.channel_mask; + halConfig->format = halConfigBase.format; + // Note: The framework code does not use BP. + halConfig->bufferProvider.cookie = nullptr; + halConfig->bufferProvider.getBuffer = nullptr; + halConfig->bufferProvider.releaseBuffer = nullptr; + halConfig->accessMode = static_cast(config.accessMode); + halConfig->mask = static_cast(config.mask); +} + +#endif // MAJOR_VERSION <= 6 + void Effect::effectConfigFromHal(const effect_config_t& halConfig, EffectConfig* config) { effectBufferConfigFromHal(halConfig.inputCfg, &config->inputCfg); effectBufferConfigFromHal(halConfig.outputCfg, &config->outputCfg); @@ -507,11 +563,65 @@ Return Effect::disable() { return sendCommandReturningStatus(EFFECT_CMD_DISABLE, "DISABLE"); } +Return Effect::setAudioSource( +#if MAJOR_VERSION <= 6 + AudioSource source +#else + const AudioSource& source +#endif +) { + audio_source_t halSource; + if (status_t status = HidlUtils::audioSourceToHal(source, &halSource); status == NO_ERROR) { + uint32_t halSourceParam = static_cast(halSource); + return sendCommand(EFFECT_CMD_SET_AUDIO_SOURCE, "SET_AUDIO_SOURCE", sizeof(uint32_t), + &halSourceParam); + } else { + return analyzeStatus(__func__, "audioSourceToHal", sContextConversion, status); + } +} + +#if MAJOR_VERSION <= 6 + Return Effect::setDevice(AudioDeviceBitfield device) { uint32_t halDevice = static_cast(device); return sendCommand(EFFECT_CMD_SET_DEVICE, "SET_DEVICE", sizeof(uint32_t), &halDevice); } +Return Effect::setInputDevice(AudioDeviceBitfield device) { + uint32_t halDevice = static_cast(device); + return sendCommand(EFFECT_CMD_SET_INPUT_DEVICE, "SET_INPUT_DEVICE", sizeof(uint32_t), + &halDevice); +} + +#else // MAJOR_VERSION <= 6 + +Return Effect::setDevice(const DeviceAddress& device) { + audio_devices_t halDevice; + char halDeviceAddress[AUDIO_DEVICE_MAX_ADDRESS_LEN]; + if (status_t status = HidlUtils::deviceAddressToHal(device, &halDevice, halDeviceAddress); + status == NO_ERROR) { + uint32_t halDeviceParam = static_cast(halDevice); + return sendCommand(EFFECT_CMD_SET_DEVICE, "SET_DEVICE", sizeof(uint32_t), &halDeviceParam); + } else { + return analyzeStatus(__func__, "deviceAddressToHal", sContextConversion, status); + } +} + +Return Effect::setInputDevice(const DeviceAddress& device) { + audio_devices_t halDevice; + char halDeviceAddress[AUDIO_DEVICE_MAX_ADDRESS_LEN]; + if (status_t status = HidlUtils::deviceAddressToHal(device, &halDevice, halDeviceAddress); + status == NO_ERROR) { + uint32_t halDeviceParam = static_cast(halDevice); + return sendCommand(EFFECT_CMD_SET_INPUT_DEVICE, "SET_INPUT_DEVICE", sizeof(uint32_t), + &halDeviceParam); + } else { + return analyzeStatus(__func__, "deviceAddressToHal", sContextConversion, status); + } +} + +#endif // MAJOR_VERSION <= 6 + Return Effect::setAndGetVolume(const hidl_vec& volumes, setAndGetVolume_cb _hidl_cb) { uint32_t halDataSize; @@ -546,12 +656,6 @@ Return Effect::setConfigReverse( inputBufferProvider, outputBufferProvider); } -Return Effect::setInputDevice(AudioDeviceBitfield device) { - uint32_t halDevice = static_cast(device); - return sendCommand(EFFECT_CMD_SET_INPUT_DEVICE, "SET_INPUT_DEVICE", sizeof(uint32_t), - &halDevice); -} - Return Effect::getConfig(getConfig_cb _hidl_cb) { getConfigImpl(EFFECT_CMD_GET_CONFIG, "GET_CONFIG", _hidl_cb); return Void(); @@ -598,12 +702,6 @@ Return Effect::setAuxChannelsConfig(const EffectAuxChannelsConfig& confi "SET_FEATURE_CONFIG AUX_CHANNELS", halCmd.size(), &halCmd[0]); } -Return Effect::setAudioSource(AudioSource source) { - uint32_t halSource = static_cast(source); - return sendCommand(EFFECT_CMD_SET_AUDIO_SOURCE, "SET_AUDIO_SOURCE", sizeof(uint32_t), - &halSource); -} - Return Effect::offload(const EffectOffloadParameter& param) { effect_offload_param_t halParam; effectOffloadParamToHal(param, &halParam); diff --git a/audio/effect/all-versions/default/Effect.h b/audio/effect/all-versions/default/Effect.h index 181e54241a..9aa47ea7d9 100644 --- a/audio/effect/all-versions/default/Effect.h +++ b/audio/effect/all-versions/default/Effect.h @@ -47,7 +47,9 @@ using ::android::hardware::hidl_string; using ::android::hardware::hidl_vec; using ::android::hardware::Return; using ::android::hardware::Void; +#if MAJOR_VERSION <= 6 using ::android::hardware::audio::common::CPP_VERSION::implementation::AudioDeviceBitfield; +#endif using namespace ::android::hardware::audio::common::CPP_VERSION; using namespace ::android::hardware::audio::effect::CPP_VERSION; @@ -56,7 +58,7 @@ struct Effect : public IEffect { using GetParameterSuccessCallback = std::function; - explicit Effect(effect_handle_t handle); + Effect(bool isInput, effect_handle_t handle); // Methods from ::android::hardware::audio::effect::CPP_VERSION::IEffect follow. Return init() override; @@ -66,7 +68,15 @@ struct Effect : public IEffect { Return reset() override; Return enable() override; Return disable() override; +#if MAJOR_VERSION <= 6 + Return setAudioSource(AudioSource source) override; Return setDevice(AudioDeviceBitfield device) override; + Return setInputDevice(AudioDeviceBitfield device) override; +#else + Return setAudioSource(const AudioSource& source) override; + Return setDevice(const DeviceAddress& device) override; + Return setInputDevice(const DeviceAddress& device) override; +#endif Return setAndGetVolume(const hidl_vec& volumes, setAndGetVolume_cb _hidl_cb) override; Return volumeChangeNotification(const hidl_vec& volumes) override; @@ -74,14 +84,12 @@ struct Effect : public IEffect { Return setConfigReverse( const EffectConfig& config, const sp& inputBufferProvider, const sp& outputBufferProvider) override; - Return setInputDevice(AudioDeviceBitfield device) override; Return getConfig(getConfig_cb _hidl_cb) override; Return getConfigReverse(getConfigReverse_cb _hidl_cb) override; Return getSupportedAuxChannelsConfigs( uint32_t maxConfigs, getSupportedAuxChannelsConfigs_cb _hidl_cb) override; Return getAuxChannelsConfig(getAuxChannelsConfig_cb _hidl_cb) override; Return setAuxChannelsConfig(const EffectAuxChannelsConfig& config) override; - Return setAudioSource(AudioSource source) override; Return offload(const EffectOffloadParameter& param) override; Return getDescriptor(getDescriptor_cb _hidl_cb) override; Return prepareForProcessing(prepareForProcessing_cb _hidl_cb) override; @@ -104,6 +112,10 @@ struct Effect : public IEffect { Return debug(const hidl_handle& fd, const hidl_vec& options) override; // Utility methods for extending interfaces. + static const char* sContextConversion; + + Result analyzeStatus(const char* funcName, const char* subFuncName, + const char* contextDescription, status_t status); template Return getIntegerParam(uint32_t paramId, std::function cb) { @@ -170,6 +182,7 @@ struct Effect : public IEffect { static const char* sContextCallToCommand; static const char* sContextCallFunction; + const bool mIsInput; effect_handle_t mHandle; sp mInBuffer; sp mOutBuffer; @@ -186,15 +199,14 @@ struct Effect : public IEffect { static size_t alignedSizeIn(size_t s); template std::unique_ptr hidlVecToHal(const hidl_vec& vec, uint32_t* halDataSize); - static void effectAuxChannelsConfigFromHal(const channel_config_t& halConfig, - EffectAuxChannelsConfig* config); + void effectAuxChannelsConfigFromHal(const channel_config_t& halConfig, + EffectAuxChannelsConfig* config); static void effectAuxChannelsConfigToHal(const EffectAuxChannelsConfig& config, channel_config_t* halConfig); - static void effectBufferConfigFromHal(const buffer_config_t& halConfig, - EffectBufferConfig* config); + void effectBufferConfigFromHal(const buffer_config_t& halConfig, EffectBufferConfig* config); static void effectBufferConfigToHal(const EffectBufferConfig& config, buffer_config_t* halConfig); - static void effectConfigFromHal(const effect_config_t& halConfig, EffectConfig* config); + void effectConfigFromHal(const effect_config_t& halConfig, EffectConfig* config); static void effectConfigToHal(const EffectConfig& config, effect_config_t* halConfig); static void effectOffloadParamToHal(const EffectOffloadParameter& offload, effect_offload_param_t* halOffload); @@ -202,8 +214,6 @@ struct Effect : public IEffect { uint32_t valueSize, const void** valueData); Result analyzeCommandStatus(const char* commandName, const char* context, status_t status); - Result analyzeStatus(const char* funcName, const char* subFuncName, - const char* contextDescription, status_t status); void getConfigImpl(int commandCode, const char* commandName, GetConfigCallback cb); Result getCurrentConfigImpl(uint32_t featureId, uint32_t configSize, GetCurrentConfigSuccessCallback onSuccess); diff --git a/audio/effect/all-versions/default/EffectsFactory.cpp b/audio/effect/all-versions/default/EffectsFactory.cpp index b265d3d921..1ea990b3b6 100644 --- a/audio/effect/all-versions/default/EffectsFactory.cpp +++ b/audio/effect/all-versions/default/EffectsFactory.cpp @@ -82,7 +82,9 @@ sp EffectsFactory::dispatchEffectInstanceCreation(const effect_descript } else if (memcmp(halUuid, SL_IID_VISUALIZATION, sizeof(effect_uuid_t)) == 0) { return new VisualizerEffect(handle); } - return new Effect(handle); + const bool isInput = + (halDescriptor.flags & EFFECT_FLAG_TYPE_PRE_PROC) == EFFECT_FLAG_TYPE_PRE_PROC; + return new Effect(isInput, handle); } // Methods from ::android::hardware::audio::effect::CPP_VERSION::IEffectsFactory follow. diff --git a/audio/effect/all-versions/default/EnvironmentalReverbEffect.cpp b/audio/effect/all-versions/default/EnvironmentalReverbEffect.cpp index 78122d4b79..e95a267e38 100644 --- a/audio/effect/all-versions/default/EnvironmentalReverbEffect.cpp +++ b/audio/effect/all-versions/default/EnvironmentalReverbEffect.cpp @@ -31,9 +31,7 @@ namespace CPP_VERSION { namespace implementation { EnvironmentalReverbEffect::EnvironmentalReverbEffect(effect_handle_t handle) - : mEffect(new Effect(handle)) {} - -EnvironmentalReverbEffect::~EnvironmentalReverbEffect() {} + : mEffect(new Effect(false /*isInput*/, handle)) {} void EnvironmentalReverbEffect::propertiesFromHal( const t_reverb_settings& halProperties, IEnvironmentalReverbEffect::AllProperties* properties) { @@ -86,10 +84,32 @@ Return EnvironmentalReverbEffect::disable() { return mEffect->disable(); } +#if MAJOR_VERSION <= 6 +Return EnvironmentalReverbEffect::setAudioSource(AudioSource source) { + return mEffect->setAudioSource(source); +} + Return EnvironmentalReverbEffect::setDevice(AudioDeviceBitfield device) { return mEffect->setDevice(device); } +Return EnvironmentalReverbEffect::setInputDevice(AudioDeviceBitfield device) { + return mEffect->setInputDevice(device); +} +#else +Return EnvironmentalReverbEffect::setAudioSource(const AudioSource& source) { + return mEffect->setAudioSource(source); +} + +Return EnvironmentalReverbEffect::setDevice(const DeviceAddress& device) { + return mEffect->setDevice(device); +} + +Return EnvironmentalReverbEffect::setInputDevice(const DeviceAddress& device) { + return mEffect->setInputDevice(device); +} +#endif + Return EnvironmentalReverbEffect::setAndGetVolume(const hidl_vec& volumes, setAndGetVolume_cb _hidl_cb) { return mEffect->setAndGetVolume(volumes, _hidl_cb); @@ -110,10 +130,6 @@ Return EnvironmentalReverbEffect::setConfigReverse( return mEffect->setConfigReverse(config, inputBufferProvider, outputBufferProvider); } -Return EnvironmentalReverbEffect::setInputDevice(AudioDeviceBitfield device) { - return mEffect->setInputDevice(device); -} - Return EnvironmentalReverbEffect::getConfig(getConfig_cb _hidl_cb) { return mEffect->getConfig(_hidl_cb); } @@ -136,10 +152,6 @@ Return EnvironmentalReverbEffect::setAuxChannelsConfig( return mEffect->setAuxChannelsConfig(config); } -Return EnvironmentalReverbEffect::setAudioSource(AudioSource source) { - return mEffect->setAudioSource(source); -} - Return EnvironmentalReverbEffect::offload(const EffectOffloadParameter& param) { return mEffect->offload(param); } diff --git a/audio/effect/all-versions/default/EnvironmentalReverbEffect.h b/audio/effect/all-versions/default/EnvironmentalReverbEffect.h index bb422d46bc..9694b5d8c1 100644 --- a/audio/effect/all-versions/default/EnvironmentalReverbEffect.h +++ b/audio/effect/all-versions/default/EnvironmentalReverbEffect.h @@ -57,7 +57,15 @@ struct EnvironmentalReverbEffect : public IEnvironmentalReverbEffect { Return reset() override; Return enable() override; Return disable() override; +#if MAJOR_VERSION <= 6 + Return setAudioSource(AudioSource source) override; Return setDevice(AudioDeviceBitfield device) override; + Return setInputDevice(AudioDeviceBitfield device) override; +#else + Return setAudioSource(const AudioSource& source) override; + Return setDevice(const DeviceAddress& device) override; + Return setInputDevice(const DeviceAddress& device) override; +#endif Return setAndGetVolume(const hidl_vec& volumes, setAndGetVolume_cb _hidl_cb) override; Return volumeChangeNotification(const hidl_vec& volumes) override; @@ -65,14 +73,12 @@ struct EnvironmentalReverbEffect : public IEnvironmentalReverbEffect { Return setConfigReverse( const EffectConfig& config, const sp& inputBufferProvider, const sp& outputBufferProvider) override; - Return setInputDevice(AudioDeviceBitfield device) override; Return getConfig(getConfig_cb _hidl_cb) override; Return getConfigReverse(getConfigReverse_cb _hidl_cb) override; Return getSupportedAuxChannelsConfigs( uint32_t maxConfigs, getSupportedAuxChannelsConfigs_cb _hidl_cb) override; Return getAuxChannelsConfig(getAuxChannelsConfig_cb _hidl_cb) override; Return setAuxChannelsConfig(const EffectAuxChannelsConfig& config) override; - Return setAudioSource(AudioSource source) override; Return offload(const EffectOffloadParameter& param) override; Return getDescriptor(getDescriptor_cb _hidl_cb) override; Return prepareForProcessing(prepareForProcessing_cb _hidl_cb) override; @@ -125,7 +131,7 @@ struct EnvironmentalReverbEffect : public IEnvironmentalReverbEffect { private: sp mEffect; - virtual ~EnvironmentalReverbEffect(); + virtual ~EnvironmentalReverbEffect() = default; void propertiesFromHal(const t_reverb_settings& halProperties, IEnvironmentalReverbEffect::AllProperties* properties); diff --git a/audio/effect/all-versions/default/EqualizerEffect.cpp b/audio/effect/all-versions/default/EqualizerEffect.cpp index 1b983ec5eb..fffe8cd884 100644 --- a/audio/effect/all-versions/default/EqualizerEffect.cpp +++ b/audio/effect/all-versions/default/EqualizerEffect.cpp @@ -31,9 +31,8 @@ namespace effect { namespace CPP_VERSION { namespace implementation { -EqualizerEffect::EqualizerEffect(effect_handle_t handle) : mEffect(new Effect(handle)) {} - -EqualizerEffect::~EqualizerEffect() {} +EqualizerEffect::EqualizerEffect(effect_handle_t handle) + : mEffect(new Effect(false /*isInput*/, handle)) {} void EqualizerEffect::propertiesFromHal(const t_equalizer_settings& halProperties, IEqualizerEffect::AllProperties* properties) { @@ -80,10 +79,32 @@ Return EqualizerEffect::disable() { return mEffect->disable(); } +#if MAJOR_VERSION <= 6 +Return EqualizerEffect::setAudioSource(AudioSource source) { + return mEffect->setAudioSource(source); +} + Return EqualizerEffect::setDevice(AudioDeviceBitfield device) { return mEffect->setDevice(device); } +Return EqualizerEffect::setInputDevice(AudioDeviceBitfield device) { + return mEffect->setInputDevice(device); +} +#else +Return EqualizerEffect::setAudioSource(const AudioSource& source) { + return mEffect->setAudioSource(source); +} + +Return EqualizerEffect::setDevice(const DeviceAddress& device) { + return mEffect->setDevice(device); +} + +Return EqualizerEffect::setInputDevice(const DeviceAddress& device) { + return mEffect->setInputDevice(device); +} +#endif + Return EqualizerEffect::setAndGetVolume(const hidl_vec& volumes, setAndGetVolume_cb _hidl_cb) { return mEffect->setAndGetVolume(volumes, _hidl_cb); @@ -103,10 +124,6 @@ Return EqualizerEffect::setConfigReverse( return mEffect->setConfigReverse(config, inputBufferProvider, outputBufferProvider); } -Return EqualizerEffect::setInputDevice(AudioDeviceBitfield device) { - return mEffect->setInputDevice(device); -} - Return EqualizerEffect::getConfig(getConfig_cb _hidl_cb) { return mEffect->getConfig(_hidl_cb); } @@ -128,10 +145,6 @@ Return EqualizerEffect::setAuxChannelsConfig(const EffectAuxChannelsConf return mEffect->setAuxChannelsConfig(config); } -Return EqualizerEffect::setAudioSource(AudioSource source) { - return mEffect->setAudioSource(source); -} - Return EqualizerEffect::offload(const EffectOffloadParameter& param) { return mEffect->offload(param); } diff --git a/audio/effect/all-versions/default/EqualizerEffect.h b/audio/effect/all-versions/default/EqualizerEffect.h index b1cbefd1f6..7a6bc0a8b0 100644 --- a/audio/effect/all-versions/default/EqualizerEffect.h +++ b/audio/effect/all-versions/default/EqualizerEffect.h @@ -57,7 +57,15 @@ struct EqualizerEffect : public IEqualizerEffect { Return reset() override; Return enable() override; Return disable() override; +#if MAJOR_VERSION <= 6 + Return setAudioSource(AudioSource source) override; Return setDevice(AudioDeviceBitfield device) override; + Return setInputDevice(AudioDeviceBitfield device) override; +#else + Return setAudioSource(const AudioSource& source) override; + Return setDevice(const DeviceAddress& device) override; + Return setInputDevice(const DeviceAddress& device) override; +#endif Return setAndGetVolume(const hidl_vec& volumes, setAndGetVolume_cb _hidl_cb) override; Return volumeChangeNotification(const hidl_vec& volumes) override; @@ -65,14 +73,12 @@ struct EqualizerEffect : public IEqualizerEffect { Return setConfigReverse( const EffectConfig& config, const sp& inputBufferProvider, const sp& outputBufferProvider) override; - Return setInputDevice(AudioDeviceBitfield device) override; Return getConfig(getConfig_cb _hidl_cb) override; Return getConfigReverse(getConfigReverse_cb _hidl_cb) override; Return getSupportedAuxChannelsConfigs( uint32_t maxConfigs, getSupportedAuxChannelsConfigs_cb _hidl_cb) override; Return getAuxChannelsConfig(getAuxChannelsConfig_cb _hidl_cb) override; Return setAuxChannelsConfig(const EffectAuxChannelsConfig& config) override; - Return setAudioSource(AudioSource source) override; Return offload(const EffectOffloadParameter& param) override; Return getDescriptor(getDescriptor_cb _hidl_cb) override; Return prepareForProcessing(prepareForProcessing_cb _hidl_cb) override; @@ -111,7 +117,7 @@ struct EqualizerEffect : public IEqualizerEffect { private: sp mEffect; - virtual ~EqualizerEffect(); + virtual ~EqualizerEffect() = default; void propertiesFromHal(const t_equalizer_settings& halProperties, IEqualizerEffect::AllProperties* properties); diff --git a/audio/effect/all-versions/default/LoudnessEnhancerEffect.cpp b/audio/effect/all-versions/default/LoudnessEnhancerEffect.cpp index ebd519766e..c7add86334 100644 --- a/audio/effect/all-versions/default/LoudnessEnhancerEffect.cpp +++ b/audio/effect/all-versions/default/LoudnessEnhancerEffect.cpp @@ -33,9 +33,7 @@ namespace CPP_VERSION { namespace implementation { LoudnessEnhancerEffect::LoudnessEnhancerEffect(effect_handle_t handle) - : mEffect(new Effect(handle)) {} - -LoudnessEnhancerEffect::~LoudnessEnhancerEffect() {} + : mEffect(new Effect(false /*isInput*/, handle)) {} // Methods from ::android::hardware::audio::effect::CPP_VERSION::IEffect follow. Return LoudnessEnhancerEffect::init() { @@ -60,10 +58,32 @@ Return LoudnessEnhancerEffect::disable() { return mEffect->disable(); } +#if MAJOR_VERSION <= 6 +Return LoudnessEnhancerEffect::setAudioSource(AudioSource source) { + return mEffect->setAudioSource(source); +} + Return LoudnessEnhancerEffect::setDevice(AudioDeviceBitfield device) { return mEffect->setDevice(device); } +Return LoudnessEnhancerEffect::setInputDevice(AudioDeviceBitfield device) { + return mEffect->setInputDevice(device); +} +#else +Return LoudnessEnhancerEffect::setAudioSource(const AudioSource& source) { + return mEffect->setAudioSource(source); +} + +Return LoudnessEnhancerEffect::setDevice(const DeviceAddress& device) { + return mEffect->setDevice(device); +} + +Return LoudnessEnhancerEffect::setInputDevice(const DeviceAddress& device) { + return mEffect->setInputDevice(device); +} +#endif + Return LoudnessEnhancerEffect::setAndGetVolume(const hidl_vec& volumes, setAndGetVolume_cb _hidl_cb) { return mEffect->setAndGetVolume(volumes, _hidl_cb); @@ -83,10 +103,6 @@ Return LoudnessEnhancerEffect::setConfigReverse( return mEffect->setConfigReverse(config, inputBufferProvider, outputBufferProvider); } -Return LoudnessEnhancerEffect::setInputDevice(AudioDeviceBitfield device) { - return mEffect->setInputDevice(device); -} - Return LoudnessEnhancerEffect::getConfig(getConfig_cb _hidl_cb) { return mEffect->getConfig(_hidl_cb); } @@ -108,10 +124,6 @@ Return LoudnessEnhancerEffect::setAuxChannelsConfig(const EffectAuxChann return mEffect->setAuxChannelsConfig(config); } -Return LoudnessEnhancerEffect::setAudioSource(AudioSource source) { - return mEffect->setAudioSource(source); -} - Return LoudnessEnhancerEffect::offload(const EffectOffloadParameter& param) { return mEffect->offload(param); } diff --git a/audio/effect/all-versions/default/LoudnessEnhancerEffect.h b/audio/effect/all-versions/default/LoudnessEnhancerEffect.h index 8baf12839d..6d80207dc3 100644 --- a/audio/effect/all-versions/default/LoudnessEnhancerEffect.h +++ b/audio/effect/all-versions/default/LoudnessEnhancerEffect.h @@ -53,7 +53,15 @@ struct LoudnessEnhancerEffect : public ILoudnessEnhancerEffect { Return reset() override; Return enable() override; Return disable() override; +#if MAJOR_VERSION <= 6 + Return setAudioSource(AudioSource source) override; Return setDevice(AudioDeviceBitfield device) override; + Return setInputDevice(AudioDeviceBitfield device) override; +#else + Return setAudioSource(const AudioSource& source) override; + Return setDevice(const DeviceAddress& device) override; + Return setInputDevice(const DeviceAddress& device) override; +#endif Return setAndGetVolume(const hidl_vec& volumes, setAndGetVolume_cb _hidl_cb) override; Return volumeChangeNotification(const hidl_vec& volumes) override; @@ -61,14 +69,12 @@ struct LoudnessEnhancerEffect : public ILoudnessEnhancerEffect { Return setConfigReverse( const EffectConfig& config, const sp& inputBufferProvider, const sp& outputBufferProvider) override; - Return setInputDevice(AudioDeviceBitfield device) override; Return getConfig(getConfig_cb _hidl_cb) override; Return getConfigReverse(getConfigReverse_cb _hidl_cb) override; Return getSupportedAuxChannelsConfigs( uint32_t maxConfigs, getSupportedAuxChannelsConfigs_cb _hidl_cb) override; Return getAuxChannelsConfig(getAuxChannelsConfig_cb _hidl_cb) override; Return setAuxChannelsConfig(const EffectAuxChannelsConfig& config) override; - Return setAudioSource(AudioSource source) override; Return offload(const EffectOffloadParameter& param) override; Return getDescriptor(getDescriptor_cb _hidl_cb) override; Return prepareForProcessing(prepareForProcessing_cb _hidl_cb) override; @@ -98,7 +104,7 @@ struct LoudnessEnhancerEffect : public ILoudnessEnhancerEffect { private: sp mEffect; - virtual ~LoudnessEnhancerEffect(); + virtual ~LoudnessEnhancerEffect() = default; }; } // namespace implementation diff --git a/audio/effect/all-versions/default/NoiseSuppressionEffect.cpp b/audio/effect/all-versions/default/NoiseSuppressionEffect.cpp index d01bbe5e94..9e75237b0e 100644 --- a/audio/effect/all-versions/default/NoiseSuppressionEffect.cpp +++ b/audio/effect/all-versions/default/NoiseSuppressionEffect.cpp @@ -30,9 +30,7 @@ namespace CPP_VERSION { namespace implementation { NoiseSuppressionEffect::NoiseSuppressionEffect(effect_handle_t handle) - : mEffect(new Effect(handle)) {} - -NoiseSuppressionEffect::~NoiseSuppressionEffect() {} + : mEffect(new Effect(true /*isInput*/, handle)) {} void NoiseSuppressionEffect::propertiesFromHal(const t_ns_settings& halProperties, INoiseSuppressionEffect::AllProperties* properties) { @@ -69,10 +67,32 @@ Return NoiseSuppressionEffect::disable() { return mEffect->disable(); } +#if MAJOR_VERSION <= 6 +Return NoiseSuppressionEffect::setAudioSource(AudioSource source) { + return mEffect->setAudioSource(source); +} + Return NoiseSuppressionEffect::setDevice(AudioDeviceBitfield device) { return mEffect->setDevice(device); } +Return NoiseSuppressionEffect::setInputDevice(AudioDeviceBitfield device) { + return mEffect->setInputDevice(device); +} +#else +Return NoiseSuppressionEffect::setAudioSource(const AudioSource& source) { + return mEffect->setAudioSource(source); +} + +Return NoiseSuppressionEffect::setDevice(const DeviceAddress& device) { + return mEffect->setDevice(device); +} + +Return NoiseSuppressionEffect::setInputDevice(const DeviceAddress& device) { + return mEffect->setInputDevice(device); +} +#endif + Return NoiseSuppressionEffect::setAndGetVolume(const hidl_vec& volumes, setAndGetVolume_cb _hidl_cb) { return mEffect->setAndGetVolume(volumes, _hidl_cb); @@ -92,10 +112,6 @@ Return NoiseSuppressionEffect::setConfigReverse( return mEffect->setConfigReverse(config, inputBufferProvider, outputBufferProvider); } -Return NoiseSuppressionEffect::setInputDevice(AudioDeviceBitfield device) { - return mEffect->setInputDevice(device); -} - Return NoiseSuppressionEffect::getConfig(getConfig_cb _hidl_cb) { return mEffect->getConfig(_hidl_cb); } @@ -117,10 +133,6 @@ Return NoiseSuppressionEffect::setAuxChannelsConfig(const EffectAuxChann return mEffect->setAuxChannelsConfig(config); } -Return NoiseSuppressionEffect::setAudioSource(AudioSource source) { - return mEffect->setAudioSource(source); -} - Return NoiseSuppressionEffect::offload(const EffectOffloadParameter& param) { return mEffect->offload(param); } diff --git a/audio/effect/all-versions/default/NoiseSuppressionEffect.h b/audio/effect/all-versions/default/NoiseSuppressionEffect.h index c49bf7bd6c..6cc45b983c 100644 --- a/audio/effect/all-versions/default/NoiseSuppressionEffect.h +++ b/audio/effect/all-versions/default/NoiseSuppressionEffect.h @@ -55,7 +55,15 @@ struct NoiseSuppressionEffect : public INoiseSuppressionEffect { Return reset() override; Return enable() override; Return disable() override; +#if MAJOR_VERSION <= 6 + Return setAudioSource(AudioSource source) override; Return setDevice(AudioDeviceBitfield device) override; + Return setInputDevice(AudioDeviceBitfield device) override; +#else + Return setAudioSource(const AudioSource& source) override; + Return setDevice(const DeviceAddress& device) override; + Return setInputDevice(const DeviceAddress& device) override; +#endif Return setAndGetVolume(const hidl_vec& volumes, setAndGetVolume_cb _hidl_cb) override; Return volumeChangeNotification(const hidl_vec& volumes) override; @@ -63,14 +71,12 @@ struct NoiseSuppressionEffect : public INoiseSuppressionEffect { Return setConfigReverse( const EffectConfig& config, const sp& inputBufferProvider, const sp& outputBufferProvider) override; - Return setInputDevice(AudioDeviceBitfield device) override; Return getConfig(getConfig_cb _hidl_cb) override; Return getConfigReverse(getConfigReverse_cb _hidl_cb) override; Return getSupportedAuxChannelsConfigs( uint32_t maxConfigs, getSupportedAuxChannelsConfigs_cb _hidl_cb) override; Return getAuxChannelsConfig(getAuxChannelsConfig_cb _hidl_cb) override; Return setAuxChannelsConfig(const EffectAuxChannelsConfig& config) override; - Return setAudioSource(AudioSource source) override; Return offload(const EffectOffloadParameter& param) override; Return getDescriptor(getDescriptor_cb _hidl_cb) override; Return prepareForProcessing(prepareForProcessing_cb _hidl_cb) override; @@ -105,7 +111,7 @@ struct NoiseSuppressionEffect : public INoiseSuppressionEffect { private: sp mEffect; - virtual ~NoiseSuppressionEffect(); + virtual ~NoiseSuppressionEffect() = default; void propertiesFromHal(const t_ns_settings& halProperties, INoiseSuppressionEffect::AllProperties* properties); diff --git a/audio/effect/all-versions/default/PresetReverbEffect.cpp b/audio/effect/all-versions/default/PresetReverbEffect.cpp index 4a2a3a42a9..1ae8492d6f 100644 --- a/audio/effect/all-versions/default/PresetReverbEffect.cpp +++ b/audio/effect/all-versions/default/PresetReverbEffect.cpp @@ -30,9 +30,8 @@ namespace effect { namespace CPP_VERSION { namespace implementation { -PresetReverbEffect::PresetReverbEffect(effect_handle_t handle) : mEffect(new Effect(handle)) {} - -PresetReverbEffect::~PresetReverbEffect() {} +PresetReverbEffect::PresetReverbEffect(effect_handle_t handle) + : mEffect(new Effect(false /*isInput*/, handle)) {} // Methods from ::android::hardware::audio::effect::CPP_VERSION::IEffect follow. Return PresetReverbEffect::init() { @@ -57,10 +56,32 @@ Return PresetReverbEffect::disable() { return mEffect->disable(); } +#if MAJOR_VERSION <= 6 +Return PresetReverbEffect::setAudioSource(AudioSource source) { + return mEffect->setAudioSource(source); +} + Return PresetReverbEffect::setDevice(AudioDeviceBitfield device) { return mEffect->setDevice(device); } +Return PresetReverbEffect::setInputDevice(AudioDeviceBitfield device) { + return mEffect->setInputDevice(device); +} +#else +Return PresetReverbEffect::setAudioSource(const AudioSource& source) { + return mEffect->setAudioSource(source); +} + +Return PresetReverbEffect::setDevice(const DeviceAddress& device) { + return mEffect->setDevice(device); +} + +Return PresetReverbEffect::setInputDevice(const DeviceAddress& device) { + return mEffect->setInputDevice(device); +} +#endif + Return PresetReverbEffect::setAndGetVolume(const hidl_vec& volumes, setAndGetVolume_cb _hidl_cb) { return mEffect->setAndGetVolume(volumes, _hidl_cb); @@ -80,10 +101,6 @@ Return PresetReverbEffect::setConfigReverse( return mEffect->setConfigReverse(config, inputBufferProvider, outputBufferProvider); } -Return PresetReverbEffect::setInputDevice(AudioDeviceBitfield device) { - return mEffect->setInputDevice(device); -} - Return PresetReverbEffect::getConfig(getConfig_cb _hidl_cb) { return mEffect->getConfig(_hidl_cb); } @@ -105,10 +122,6 @@ Return PresetReverbEffect::setAuxChannelsConfig(const EffectAuxChannelsC return mEffect->setAuxChannelsConfig(config); } -Return PresetReverbEffect::setAudioSource(AudioSource source) { - return mEffect->setAudioSource(source); -} - Return PresetReverbEffect::offload(const EffectOffloadParameter& param) { return mEffect->offload(param); } diff --git a/audio/effect/all-versions/default/PresetReverbEffect.h b/audio/effect/all-versions/default/PresetReverbEffect.h index 58a6829a83..eb55e20fe2 100644 --- a/audio/effect/all-versions/default/PresetReverbEffect.h +++ b/audio/effect/all-versions/default/PresetReverbEffect.h @@ -53,7 +53,15 @@ struct PresetReverbEffect : public IPresetReverbEffect { Return reset() override; Return enable() override; Return disable() override; +#if MAJOR_VERSION <= 6 + Return setAudioSource(AudioSource source) override; Return setDevice(AudioDeviceBitfield device) override; + Return setInputDevice(AudioDeviceBitfield device) override; +#else + Return setAudioSource(const AudioSource& source) override; + Return setDevice(const DeviceAddress& device) override; + Return setInputDevice(const DeviceAddress& device) override; +#endif Return setAndGetVolume(const hidl_vec& volumes, setAndGetVolume_cb _hidl_cb) override; Return volumeChangeNotification(const hidl_vec& volumes) override; @@ -61,14 +69,12 @@ struct PresetReverbEffect : public IPresetReverbEffect { Return setConfigReverse( const EffectConfig& config, const sp& inputBufferProvider, const sp& outputBufferProvider) override; - Return setInputDevice(AudioDeviceBitfield device) override; Return getConfig(getConfig_cb _hidl_cb) override; Return getConfigReverse(getConfigReverse_cb _hidl_cb) override; Return getSupportedAuxChannelsConfigs( uint32_t maxConfigs, getSupportedAuxChannelsConfigs_cb _hidl_cb) override; Return getAuxChannelsConfig(getAuxChannelsConfig_cb _hidl_cb) override; Return setAuxChannelsConfig(const EffectAuxChannelsConfig& config) override; - Return setAudioSource(AudioSource source) override; Return offload(const EffectOffloadParameter& param) override; Return getDescriptor(getDescriptor_cb _hidl_cb) override; Return prepareForProcessing(prepareForProcessing_cb _hidl_cb) override; @@ -98,7 +104,7 @@ struct PresetReverbEffect : public IPresetReverbEffect { private: sp mEffect; - virtual ~PresetReverbEffect(); + virtual ~PresetReverbEffect() = default; }; } // namespace implementation diff --git a/audio/effect/all-versions/default/VirtualizerEffect.cpp b/audio/effect/all-versions/default/VirtualizerEffect.cpp index 1b69a9033c..1dce1810ea 100644 --- a/audio/effect/all-versions/default/VirtualizerEffect.cpp +++ b/audio/effect/all-versions/default/VirtualizerEffect.cpp @@ -19,7 +19,9 @@ #include "VirtualizerEffect.h" #include +#include +#include #include #include @@ -32,19 +34,10 @@ namespace effect { namespace CPP_VERSION { namespace implementation { -VirtualizerEffect::VirtualizerEffect(effect_handle_t handle) : mEffect(new Effect(handle)) {} +using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils; -VirtualizerEffect::~VirtualizerEffect() {} - -void VirtualizerEffect::speakerAnglesFromHal(const int32_t* halAngles, uint32_t channelCount, - hidl_vec& speakerAngles) { - speakerAngles.resize(channelCount); - for (uint32_t i = 0; i < channelCount; ++i) { - speakerAngles[i].mask = AudioChannelBitfield(*halAngles++); - speakerAngles[i].azimuth = *halAngles++; - speakerAngles[i].elevation = *halAngles++; - } -} +VirtualizerEffect::VirtualizerEffect(effect_handle_t handle) + : mEffect(new Effect(false /*isInput*/, handle)) {} // Methods from ::android::hardware::audio::effect::CPP_VERSION::IEffect follow. Return VirtualizerEffect::init() { @@ -69,10 +62,32 @@ Return VirtualizerEffect::disable() { return mEffect->disable(); } +#if MAJOR_VERSION <= 6 +Return VirtualizerEffect::setAudioSource(AudioSource source) { + return mEffect->setAudioSource(source); +} + Return VirtualizerEffect::setDevice(AudioDeviceBitfield device) { return mEffect->setDevice(device); } +Return VirtualizerEffect::setInputDevice(AudioDeviceBitfield device) { + return mEffect->setInputDevice(device); +} +#else +Return VirtualizerEffect::setAudioSource(const AudioSource& source) { + return mEffect->setAudioSource(source); +} + +Return VirtualizerEffect::setDevice(const DeviceAddress& device) { + return mEffect->setDevice(device); +} + +Return VirtualizerEffect::setInputDevice(const DeviceAddress& device) { + return mEffect->setInputDevice(device); +} +#endif + Return VirtualizerEffect::setAndGetVolume(const hidl_vec& volumes, setAndGetVolume_cb _hidl_cb) { return mEffect->setAndGetVolume(volumes, _hidl_cb); @@ -92,10 +107,6 @@ Return VirtualizerEffect::setConfigReverse( return mEffect->setConfigReverse(config, inputBufferProvider, outputBufferProvider); } -Return VirtualizerEffect::setInputDevice(AudioDeviceBitfield device) { - return mEffect->setInputDevice(device); -} - Return VirtualizerEffect::getConfig(getConfig_cb _hidl_cb) { return mEffect->getConfig(_hidl_cb); } @@ -117,10 +128,6 @@ Return VirtualizerEffect::setAuxChannelsConfig(const EffectAuxChannelsCo return mEffect->setAuxChannelsConfig(config); } -Return VirtualizerEffect::setAudioSource(AudioSource source) { - return mEffect->setAudioSource(source); -} - Return VirtualizerEffect::offload(const EffectOffloadParameter& param) { return mEffect->offload(param); } @@ -192,43 +199,117 @@ Return VirtualizerEffect::getStrength(getStrength_cb _hidl_cb) { return mEffect->getIntegerParam(VIRTUALIZER_PARAM_STRENGTH, _hidl_cb); } -Return VirtualizerEffect::getVirtualSpeakerAngles(AudioChannelBitfield mask, - AudioDevice device, - getVirtualSpeakerAngles_cb _hidl_cb) { - uint32_t channelCount = - audio_channel_count_from_out_mask(static_cast(mask)); +Return VirtualizerEffect::getVirtualSpeakerAngles( +#if MAJOR_VERSION <= 6 + AudioChannelBitfield mask, AudioDevice device, getVirtualSpeakerAngles_cb _hidl_cb) { + audio_channel_mask_t halChannelMask = static_cast(mask); + audio_devices_t halDeviceType = static_cast(device); +#else + const AudioChannelMask& mask, const DeviceAddress& device, + getVirtualSpeakerAngles_cb _hidl_cb) { + audio_channel_mask_t halChannelMask; + if (status_t status = HidlUtils::audioChannelMaskToHal(mask, &halChannelMask); + status != NO_ERROR) { + _hidl_cb(mEffect->analyzeStatus(__func__, "audioChannelMaskToHal", + Effect::sContextConversion, status), + SpeakerAngles{}); + return Void(); + } + audio_devices_t halDeviceType; + char halDeviceAddress[AUDIO_DEVICE_MAX_ADDRESS_LEN]; + if (status_t status = HidlUtils::deviceAddressToHal(device, &halDeviceType, halDeviceAddress); + status != NO_ERROR) { + _hidl_cb(mEffect->analyzeStatus(__func__, "deviceAddressToHal", Effect::sContextConversion, + status), + SpeakerAngles{}); + return Void(); + } +#endif + uint32_t channelCount = audio_channel_count_from_out_mask(halChannelMask); size_t halSpeakerAnglesSize = sizeof(int32_t) * 3 * channelCount; - uint32_t halParam[3] = {VIRTUALIZER_PARAM_VIRTUAL_SPEAKER_ANGLES, - static_cast(mask), - static_cast(device)}; - hidl_vec speakerAngles; + uint32_t halParam[3] = {VIRTUALIZER_PARAM_VIRTUAL_SPEAKER_ANGLES, halChannelMask, + halDeviceType}; + SpeakerAngles speakerAngles; + status_t status = NO_ERROR; Result retval = mEffect->getParameterImpl( - sizeof(halParam), halParam, halSpeakerAnglesSize, - [&](uint32_t valueSize, const void* valueData) { - if (valueSize > halSpeakerAnglesSize) { - valueSize = halSpeakerAnglesSize; - } else if (valueSize < halSpeakerAnglesSize) { - channelCount = valueSize / (sizeof(int32_t) * 3); - } - speakerAnglesFromHal(reinterpret_cast(valueData), channelCount, - speakerAngles); - }); + sizeof(halParam), halParam, halSpeakerAnglesSize, + [&](uint32_t valueSize, const void* valueData) { + if (valueSize < halSpeakerAnglesSize) { + channelCount = valueSize / (sizeof(int32_t) * 3); + } + status = speakerAnglesFromHal(reinterpret_cast(valueData), + channelCount, speakerAngles); + }); + if (retval == Result::OK) { + retval = mEffect->analyzeStatus(__func__, "speakerAnglesFromHal", "", status); + } _hidl_cb(retval, speakerAngles); return Void(); } -Return VirtualizerEffect::forceVirtualizationMode(AudioDevice device) { - return mEffect->setParam(VIRTUALIZER_PARAM_FORCE_VIRTUALIZATION_MODE, - static_cast(device)); -} - Return VirtualizerEffect::getVirtualizationMode(getVirtualizationMode_cb _hidl_cb) { uint32_t halMode = 0; Result retval = mEffect->getParam(VIRTUALIZER_PARAM_FORCE_VIRTUALIZATION_MODE, halMode); +#if MAJOR_VERSION <= 6 _hidl_cb(retval, AudioDevice(halMode)); +#else + DeviceAddress device; + (void)HidlUtils::deviceAddressFromHal(static_cast(halMode), nullptr, &device); + _hidl_cb(retval, device); +#endif return Void(); } +Return VirtualizerEffect::forceVirtualizationMode( +#if MAJOR_VERSION <= 6 + AudioDevice device) { + audio_devices_t halDeviceType = static_cast(device); +#else + const DeviceAddress& device) { + audio_devices_t halDeviceType; + char halDeviceAddress[AUDIO_DEVICE_MAX_ADDRESS_LEN]; + (void)HidlUtils::deviceAddressToHal(device, &halDeviceType, halDeviceAddress); +#endif + return mEffect->setParam(VIRTUALIZER_PARAM_FORCE_VIRTUALIZATION_MODE, halDeviceType); +} + +#if MAJOR_VERSION <= 6 +// static +status_t VirtualizerEffect::speakerAnglesFromHal(const int32_t* halAngles, uint32_t channelCount, + hidl_vec& speakerAngles) { + speakerAngles.resize(channelCount); + for (uint32_t i = 0; i < channelCount; ++i) { + speakerAngles[i].mask = AudioChannelBitfield(*halAngles++); + speakerAngles[i].azimuth = *halAngles++; + speakerAngles[i].elevation = *halAngles++; + } + return NO_ERROR; +} +#else +static int compare_channels(const void* lhs, const void* rhs) { + return *(int32_t*)lhs - *(int32_t*)rhs; +} + +// static +status_t VirtualizerEffect::speakerAnglesFromHal(const int32_t* halAngles, uint32_t channelCount, + SpeakerAngles& speakerAngles) { + speakerAngles.azimuth.resize(channelCount); + speakerAngles.elevation.resize(channelCount); + int32_t halAnglesSorted[channelCount * 3]; + memcpy(halAnglesSorted, halAngles, sizeof(halAnglesSorted)); + // Ensure that channels are ordered from LSb to MSb. + qsort(halAnglesSorted, channelCount, sizeof(int32_t) * 3, compare_channels); + audio_channel_mask_t halMask = AUDIO_CHANNEL_NONE; + int32_t* halAnglesPtr = halAnglesSorted; + for (uint32_t i = 0; i < channelCount; ++i) { + halMask = static_cast(halMask | *halAnglesPtr++); + speakerAngles.azimuth[i] = *halAnglesPtr++; + speakerAngles.elevation[i] = *halAnglesPtr++; + } + return HidlUtils::audioChannelMaskFromHal(halMask, false /*isInput*/, &speakerAngles.mask); +} +#endif + } // namespace implementation } // namespace CPP_VERSION } // namespace effect diff --git a/audio/effect/all-versions/default/VirtualizerEffect.h b/audio/effect/all-versions/default/VirtualizerEffect.h index c630b2e353..3ed06d147f 100644 --- a/audio/effect/all-versions/default/VirtualizerEffect.h +++ b/audio/effect/all-versions/default/VirtualizerEffect.h @@ -39,7 +39,9 @@ using ::android::hardware::hidl_string; using ::android::hardware::hidl_vec; using ::android::hardware::Return; using ::android::hardware::Void; +#if MAJOR_VERSION <= 6 using ::android::hardware::audio::common::CPP_VERSION::implementation::AudioChannelBitfield; +#endif using namespace ::android::hardware::audio::common::CPP_VERSION; using namespace ::android::hardware::audio::effect::CPP_VERSION; @@ -54,7 +56,15 @@ struct VirtualizerEffect : public IVirtualizerEffect { Return reset() override; Return enable() override; Return disable() override; +#if MAJOR_VERSION <= 6 + Return setAudioSource(AudioSource source) override; Return setDevice(AudioDeviceBitfield device) override; + Return setInputDevice(AudioDeviceBitfield device) override; +#else + Return setAudioSource(const AudioSource& source) override; + Return setDevice(const DeviceAddress& device) override; + Return setInputDevice(const DeviceAddress& device) override; +#endif Return setAndGetVolume(const hidl_vec& volumes, setAndGetVolume_cb _hidl_cb) override; Return volumeChangeNotification(const hidl_vec& volumes) override; @@ -62,14 +72,12 @@ struct VirtualizerEffect : public IVirtualizerEffect { Return setConfigReverse( const EffectConfig& config, const sp& inputBufferProvider, const sp& outputBufferProvider) override; - Return setInputDevice(AudioDeviceBitfield device) override; Return getConfig(getConfig_cb _hidl_cb) override; Return getConfigReverse(getConfigReverse_cb _hidl_cb) override; Return getSupportedAuxChannelsConfigs( uint32_t maxConfigs, getSupportedAuxChannelsConfigs_cb _hidl_cb) override; Return getAuxChannelsConfig(getAuxChannelsConfig_cb _hidl_cb) override; Return setAuxChannelsConfig(const EffectAuxChannelsConfig& config) override; - Return setAudioSource(AudioSource source) override; Return offload(const EffectOffloadParameter& param) override; Return getDescriptor(getDescriptor_cb _hidl_cb) override; Return prepareForProcessing(prepareForProcessing_cb _hidl_cb) override; @@ -96,18 +104,27 @@ struct VirtualizerEffect : public IVirtualizerEffect { Return isStrengthSupported() override; Return setStrength(uint16_t strength) override; Return getStrength(getStrength_cb _hidl_cb) override; + Return getVirtualizationMode(getVirtualizationMode_cb _hidl_cb) override; +#if MAJOR_VERSION <= 6 Return getVirtualSpeakerAngles(AudioChannelBitfield mask, AudioDevice device, getVirtualSpeakerAngles_cb _hidl_cb) override; Return forceVirtualizationMode(AudioDevice device) override; - Return getVirtualizationMode(getVirtualizationMode_cb _hidl_cb) override; +#else + Return getVirtualSpeakerAngles(const AudioChannelMask& mask, const DeviceAddress& device, + getVirtualSpeakerAngles_cb _hidl_cb) override; + Return forceVirtualizationMode(const DeviceAddress& device) override; +#endif - private: + private: sp mEffect; - virtual ~VirtualizerEffect(); + virtual ~VirtualizerEffect() = default; - void speakerAnglesFromHal(const int32_t* halAngles, uint32_t channelCount, - hidl_vec& speakerAngles); +#if MAJOR_VERSION <= 6 + using SpeakerAngles = hidl_vec; +#endif + static status_t speakerAnglesFromHal(const int32_t* halAngles, uint32_t channelCount, + SpeakerAngles& speakerAngles); }; } // namespace implementation diff --git a/audio/effect/all-versions/default/VisualizerEffect.cpp b/audio/effect/all-versions/default/VisualizerEffect.cpp index ae533bf946..80c8637f38 100644 --- a/audio/effect/all-versions/default/VisualizerEffect.cpp +++ b/audio/effect/all-versions/default/VisualizerEffect.cpp @@ -31,9 +31,9 @@ namespace CPP_VERSION { namespace implementation { VisualizerEffect::VisualizerEffect(effect_handle_t handle) - : mEffect(new Effect(handle)), mCaptureSize(0), mMeasurementMode(MeasurementMode::NONE) {} - -VisualizerEffect::~VisualizerEffect() {} + : mEffect(new Effect(false /*isInput*/, handle)), + mCaptureSize(0), + mMeasurementMode(MeasurementMode::NONE) {} // Methods from ::android::hardware::audio::effect::CPP_VERSION::IEffect follow. Return VisualizerEffect::init() { @@ -58,10 +58,32 @@ Return VisualizerEffect::disable() { return mEffect->disable(); } +#if MAJOR_VERSION <= 6 +Return VisualizerEffect::setAudioSource(AudioSource source) { + return mEffect->setAudioSource(source); +} + Return VisualizerEffect::setDevice(AudioDeviceBitfield device) { return mEffect->setDevice(device); } +Return VisualizerEffect::setInputDevice(AudioDeviceBitfield device) { + return mEffect->setInputDevice(device); +} +#else +Return VisualizerEffect::setAudioSource(const AudioSource& source) { + return mEffect->setAudioSource(source); +} + +Return VisualizerEffect::setDevice(const DeviceAddress& device) { + return mEffect->setDevice(device); +} + +Return VisualizerEffect::setInputDevice(const DeviceAddress& device) { + return mEffect->setInputDevice(device); +} +#endif + Return VisualizerEffect::setAndGetVolume(const hidl_vec& volumes, setAndGetVolume_cb _hidl_cb) { return mEffect->setAndGetVolume(volumes, _hidl_cb); @@ -81,10 +103,6 @@ Return VisualizerEffect::setConfigReverse( return mEffect->setConfigReverse(config, inputBufferProvider, outputBufferProvider); } -Return VisualizerEffect::setInputDevice(AudioDeviceBitfield device) { - return mEffect->setInputDevice(device); -} - Return VisualizerEffect::getConfig(getConfig_cb _hidl_cb) { return mEffect->getConfig(_hidl_cb); } @@ -106,10 +124,6 @@ Return VisualizerEffect::setAuxChannelsConfig(const EffectAuxChannelsCon return mEffect->setAuxChannelsConfig(config); } -Return VisualizerEffect::setAudioSource(AudioSource source) { - return mEffect->setAudioSource(source); -} - Return VisualizerEffect::offload(const EffectOffloadParameter& param) { return mEffect->offload(param); } diff --git a/audio/effect/all-versions/default/VisualizerEffect.h b/audio/effect/all-versions/default/VisualizerEffect.h index 315f84452a..3ae4b08193 100644 --- a/audio/effect/all-versions/default/VisualizerEffect.h +++ b/audio/effect/all-versions/default/VisualizerEffect.h @@ -53,7 +53,15 @@ struct VisualizerEffect : public IVisualizerEffect { Return reset() override; Return enable() override; Return disable() override; +#if MAJOR_VERSION <= 6 + Return setAudioSource(AudioSource source) override; Return setDevice(AudioDeviceBitfield device) override; + Return setInputDevice(AudioDeviceBitfield device) override; +#else + Return setAudioSource(const AudioSource& source) override; + Return setDevice(const DeviceAddress& device) override; + Return setInputDevice(const DeviceAddress& device) override; +#endif Return setAndGetVolume(const hidl_vec& volumes, setAndGetVolume_cb _hidl_cb) override; Return volumeChangeNotification(const hidl_vec& volumes) override; @@ -61,14 +69,12 @@ struct VisualizerEffect : public IVisualizerEffect { Return setConfigReverse( const EffectConfig& config, const sp& inputBufferProvider, const sp& outputBufferProvider) override; - Return setInputDevice(AudioDeviceBitfield device) override; Return getConfig(getConfig_cb _hidl_cb) override; Return getConfigReverse(getConfigReverse_cb _hidl_cb) override; Return getSupportedAuxChannelsConfigs( uint32_t maxConfigs, getSupportedAuxChannelsConfigs_cb _hidl_cb) override; Return getAuxChannelsConfig(getAuxChannelsConfig_cb _hidl_cb) override; Return setAuxChannelsConfig(const EffectAuxChannelsConfig& config) override; - Return setAudioSource(AudioSource source) override; Return offload(const EffectOffloadParameter& param) override; Return getDescriptor(getDescriptor_cb _hidl_cb) override; Return prepareForProcessing(prepareForProcessing_cb _hidl_cb) override; @@ -107,7 +113,7 @@ struct VisualizerEffect : public IVisualizerEffect { uint16_t mCaptureSize; MeasurementMode mMeasurementMode; - virtual ~VisualizerEffect(); + virtual ~VisualizerEffect() = default; }; } // namespace implementation diff --git a/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp b/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp index 199a8a52a8..d39fbcd5c3 100644 --- a/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp +++ b/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp @@ -263,7 +263,7 @@ void AudioEffectHidlTest::getChannelCount(uint32_t* channelCount) { static_cast(currentConfig.outputCfg.channels)); #else *channelCount = android::audio::policy::configuration::V7_0::getChannelCount( - currentConfig.outputCfg.channels); + currentConfig.outputCfg.base.channelMask); ASSERT_NE(*channelCount, 0); #endif } @@ -353,8 +353,14 @@ inline bool operator==(const AudioBuffer& lhs, const AudioBuffer& rhs) { } inline bool operator==(const EffectBufferConfig& lhs, const EffectBufferConfig& rhs) { - return lhs.buffer == rhs.buffer && lhs.samplingRateHz == rhs.samplingRateHz && - lhs.channels == rhs.channels && lhs.format == rhs.format && + return lhs.buffer == rhs.buffer && +#if MAJOR_VERSION <= 6 + lhs.samplingRateHz == rhs.samplingRateHz && lhs.channels == rhs.channels && + lhs.format == rhs.format && +#else + lhs.base.sampleRateHz == rhs.base.sampleRateHz && + lhs.base.channelMask == rhs.base.channelMask && lhs.base.format == rhs.base.format && +#endif lhs.accessMode == rhs.accessMode && lhs.mask == rhs.mask; } -- GitLab From 4e7c0167589437d3035b53e93287b8ea76325f18 Mon Sep 17 00:00:00 2001 From: Kevin Chyn Date: Fri, 11 Dec 2020 15:45:54 -0800 Subject: [PATCH 327/790] Change default face sensorId to 4 Fixes: 174816040 Test: atest CtsBiometricsTestCases Change-Id: Ib3139dd10752f488ac9da220e8ab5d9104279d0f --- biometrics/face/aidl/default/Face.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biometrics/face/aidl/default/Face.cpp b/biometrics/face/aidl/default/Face.cpp index d3883d64c9..773359e89c 100644 --- a/biometrics/face/aidl/default/Face.cpp +++ b/biometrics/face/aidl/default/Face.cpp @@ -19,7 +19,7 @@ namespace aidl::android::hardware::biometrics::face { -const int kSensorId = 0; +const int kSensorId = 4; const common::SensorStrength kSensorStrength = common::SensorStrength::STRONG; const int kMaxEnrollmentsPerUser = 5; const FaceSensorType kSensorType = FaceSensorType::RGB; -- GitLab From 5a46c958e28858eaadb7a19b86ef1f7e6b486cad Mon Sep 17 00:00:00 2001 From: lesl Date: Mon, 14 Dec 2020 17:14:12 +0800 Subject: [PATCH 328/790] wifi: Fix bridged interface property and allociation 1. The concurrent property name over the limitation. Rename the property name. 2. When allocate bridged iface name, it needs to increase the idx to avoid two ifaces use the same name. Bug: 162686273 Test: atest -c VtsHalWifiApV1_0TargetTest Test: atest -c VtsHalWifiApV1_4TargetTest Test: atest -c VtsHalWifiApV1_5TargetTest Change-Id: I388cdd812bd0448c03ad5ae982547629c1e5eff9 --- wifi/1.5/default/wifi_chip.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/wifi/1.5/default/wifi_chip.cpp b/wifi/1.5/default/wifi_chip.cpp index 1b0353b353..95478a419d 100644 --- a/wifi/1.5/default/wifi_chip.cpp +++ b/wifi/1.5/default/wifi_chip.cpp @@ -116,8 +116,8 @@ std::vector getPredefinedApIfaceNames(bool is_bridged) { ifnames.push_back(buffer.data()); if (is_bridged) { buffer.fill(0); - if (property_get("ro.vendor.wifi.sap.concurrent.interface", - buffer.data(), nullptr) == 0) { + if (property_get("ro.vendor.wifi.sap.concurrent.iface", buffer.data(), + nullptr) == 0) { return ifnames; } ifnames.push_back(buffer.data()); @@ -1841,8 +1841,8 @@ std::vector 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()); + std::string instance_name = allocateApOrStaIfaceName( + IfaceType::AP, startIdxOfApIface() + i); if (!instance_name.empty()) { instances.push_back(instance_name); } -- GitLab From ca11420785834a3ca2588bb9df12f7a83299a058 Mon Sep 17 00:00:00 2001 From: Michael Butler Date: Fri, 4 Dec 2020 17:38:20 -0800 Subject: [PATCH 329/790] Change NN canonical timings to nanoseconds -- hal A sibling CL to this CL changes the definition of nn::TimePoint to the same type as std::chrono::steady_clock::time_point but has changed the underlying duration representation to use uint64_t. That sibling CL also renames nn::OptionalTimeoutDuration to nn::OptionalDuration, and changes the definition to the same type as std::nanoseconds except the underlying duration representation now uses uint64_t. This CL makes changes to the NN HAL utility code in response to the changes in the sibling CL. Bug: 174297663 Test: mma Test: NeuralNetworksTest_static Change-Id: If44d9aefadb2c78b632ff289b5ff5a49f766525c --- .../include/nnapi/hal/1.0/PreparedModel.h | 6 +-- .../1.0/utils/src/PreparedModel.cpp | 13 ++--- .../include/nnapi/hal/1.2/PreparedModel.h | 6 +-- neuralnetworks/1.2/utils/src/Conversions.cpp | 24 +++++++++- .../1.2/utils/src/PreparedModel.cpp | 13 ++--- .../utils/include/nnapi/hal/1.3/Conversions.h | 8 ++-- .../include/nnapi/hal/1.3/PreparedModel.h | 6 +-- neuralnetworks/1.3/utils/src/Conversions.cpp | 48 ++++--------------- .../1.3/utils/src/PreparedModel.cpp | 6 +-- .../include/nnapi/hal/InvalidPreparedModel.h | 6 +-- .../nnapi/hal/ResilientPreparedModel.h | 6 +-- .../utils/common/src/InvalidPreparedModel.cpp | 6 +-- .../common/src/ResilientPreparedModel.cpp | 13 ++--- 13 files changed, 76 insertions(+), 85 deletions(-) diff --git a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/PreparedModel.h b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/PreparedModel.h index 31f366dadc..198cbc8e81 100644 --- a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/PreparedModel.h +++ b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/PreparedModel.h @@ -44,13 +44,13 @@ class PreparedModel final : public nn::IPreparedModel { nn::ExecutionResult, nn::Timing>> execute( const nn::Request& request, nn::MeasureTiming measure, const nn::OptionalTimePoint& deadline, - const nn::OptionalTimeoutDuration& loopTimeoutDuration) const override; + const nn::OptionalDuration& loopTimeoutDuration) const override; nn::GeneralResult> executeFenced( const nn::Request& request, const std::vector& waitFor, nn::MeasureTiming measure, const nn::OptionalTimePoint& deadline, - const nn::OptionalTimeoutDuration& loopTimeoutDuration, - const nn::OptionalTimeoutDuration& timeoutDurationAfterFence) const override; + const nn::OptionalDuration& loopTimeoutDuration, + const nn::OptionalDuration& timeoutDurationAfterFence) const override; std::any getUnderlyingResource() const override; diff --git a/neuralnetworks/1.0/utils/src/PreparedModel.cpp b/neuralnetworks/1.0/utils/src/PreparedModel.cpp index 46dd3f8254..add827567e 100644 --- a/neuralnetworks/1.0/utils/src/PreparedModel.cpp +++ b/neuralnetworks/1.0/utils/src/PreparedModel.cpp @@ -55,7 +55,7 @@ PreparedModel::PreparedModel(PrivateConstructorTag /*tag*/, sp, nn::Timing>> PreparedModel::execute( const nn::Request& request, nn::MeasureTiming /*measure*/, const nn::OptionalTimePoint& /*deadline*/, - const nn::OptionalTimeoutDuration& /*loopTimeoutDuration*/) const { + const nn::OptionalDuration& /*loopTimeoutDuration*/) const { // Ensure that request is ready for IPC. std::optional maybeRequestInShared; const nn::Request& requestInShared = NN_TRY(hal::utils::makeExecutionFailure( @@ -81,11 +81,12 @@ nn::ExecutionResult, nn::Timing>> Prepare } nn::GeneralResult> -PreparedModel::executeFenced( - const nn::Request& /*request*/, const std::vector& /*waitFor*/, - nn::MeasureTiming /*measure*/, const nn::OptionalTimePoint& /*deadline*/, - const nn::OptionalTimeoutDuration& /*loopTimeoutDuration*/, - const nn::OptionalTimeoutDuration& /*timeoutDurationAfterFence*/) const { +PreparedModel::executeFenced(const nn::Request& /*request*/, + const std::vector& /*waitFor*/, + nn::MeasureTiming /*measure*/, + const nn::OptionalTimePoint& /*deadline*/, + const nn::OptionalDuration& /*loopTimeoutDuration*/, + const nn::OptionalDuration& /*timeoutDurationAfterFence*/) const { return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "IPreparedModel::executeFenced is not supported on 1.0 HAL service"; } diff --git a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/PreparedModel.h b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/PreparedModel.h index 65e1e8aa3f..53bd4d12ef 100644 --- a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/PreparedModel.h +++ b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/PreparedModel.h @@ -45,13 +45,13 @@ class PreparedModel final : public nn::IPreparedModel { nn::ExecutionResult, nn::Timing>> execute( const nn::Request& request, nn::MeasureTiming measure, const nn::OptionalTimePoint& deadline, - const nn::OptionalTimeoutDuration& loopTimeoutDuration) const override; + const nn::OptionalDuration& loopTimeoutDuration) const override; nn::GeneralResult> executeFenced( const nn::Request& request, const std::vector& waitFor, nn::MeasureTiming measure, const nn::OptionalTimePoint& deadline, - const nn::OptionalTimeoutDuration& loopTimeoutDuration, - const nn::OptionalTimeoutDuration& timeoutDurationAfterFence) const override; + const nn::OptionalDuration& loopTimeoutDuration, + const nn::OptionalDuration& timeoutDurationAfterFence) const override; std::any getUnderlyingResource() const override; diff --git a/neuralnetworks/1.2/utils/src/Conversions.cpp b/neuralnetworks/1.2/utils/src/Conversions.cpp index f11474fd60..3790d1f61e 100644 --- a/neuralnetworks/1.2/utils/src/Conversions.cpp +++ b/neuralnetworks/1.2/utils/src/Conversions.cpp @@ -43,7 +43,9 @@ constexpr std::underlying_type_t underlyingType(Type value) { return static_cast>(value); } +using HalDuration = std::chrono::duration; constexpr auto kVersion = android::nn::Version::ANDROID_Q; +constexpr uint64_t kNoTiming = std::numeric_limits::max(); } // namespace @@ -270,7 +272,18 @@ GeneralResult unvalidatedConvert(const hal::V1_2::MeasureTiming& } GeneralResult unvalidatedConvert(const hal::V1_2::Timing& timing) { - return Timing{.timeOnDevice = timing.timeOnDevice, .timeInDriver = timing.timeInDriver}; + constexpr uint64_t kMaxTiming = std::chrono::floor(Duration::max()).count(); + constexpr auto convertTiming = [](uint64_t halTiming) -> OptionalDuration { + if (halTiming == kNoTiming) { + return {}; + } + if (halTiming > kMaxTiming) { + return Duration::max(); + } + return HalDuration{halTiming}; + }; + return Timing{.timeOnDevice = convertTiming(timing.timeOnDevice), + .timeInDriver = convertTiming(timing.timeInDriver)}; } GeneralResult unvalidatedConvert(const hal::V1_2::Extension& extension) { @@ -547,7 +560,14 @@ nn::GeneralResult unvalidatedConvert(const nn::MeasureTiming& mea } nn::GeneralResult unvalidatedConvert(const nn::Timing& timing) { - return Timing{.timeOnDevice = timing.timeOnDevice, .timeInDriver = timing.timeInDriver}; + constexpr auto convertTiming = [](nn::OptionalDuration canonicalTiming) -> uint64_t { + if (!canonicalTiming.has_value()) { + return kNoTiming; + } + return std::chrono::ceil(*canonicalTiming).count(); + }; + return Timing{.timeOnDevice = convertTiming(timing.timeOnDevice), + .timeInDriver = convertTiming(timing.timeInDriver)}; } nn::GeneralResult unvalidatedConvert(const nn::Extension& extension) { diff --git a/neuralnetworks/1.2/utils/src/PreparedModel.cpp b/neuralnetworks/1.2/utils/src/PreparedModel.cpp index dad9a7e74b..32c2651950 100644 --- a/neuralnetworks/1.2/utils/src/PreparedModel.cpp +++ b/neuralnetworks/1.2/utils/src/PreparedModel.cpp @@ -106,7 +106,7 @@ PreparedModel::executeAsynchronously(const V1_0::Request& request, MeasureTiming nn::ExecutionResult, nn::Timing>> PreparedModel::execute( const nn::Request& request, nn::MeasureTiming measure, const nn::OptionalTimePoint& /*deadline*/, - const nn::OptionalTimeoutDuration& /*loopTimeoutDuration*/) const { + const nn::OptionalDuration& /*loopTimeoutDuration*/) const { // Ensure that request is ready for IPC. std::optional maybeRequestInShared; const nn::Request& requestInShared = NN_TRY(hal::utils::makeExecutionFailure( @@ -140,11 +140,12 @@ nn::ExecutionResult, nn::Timing>> Prepare } nn::GeneralResult> -PreparedModel::executeFenced( - const nn::Request& /*request*/, const std::vector& /*waitFor*/, - nn::MeasureTiming /*measure*/, const nn::OptionalTimePoint& /*deadline*/, - const nn::OptionalTimeoutDuration& /*loopTimeoutDuration*/, - const nn::OptionalTimeoutDuration& /*timeoutDurationAfterFence*/) const { +PreparedModel::executeFenced(const nn::Request& /*request*/, + const std::vector& /*waitFor*/, + nn::MeasureTiming /*measure*/, + const nn::OptionalTimePoint& /*deadline*/, + const nn::OptionalDuration& /*loopTimeoutDuration*/, + const nn::OptionalDuration& /*timeoutDurationAfterFence*/) const { return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "IPreparedModel::executeFenced is not supported on 1.2 HAL service"; } diff --git a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Conversions.h b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Conversions.h index 9653a05da7..477bb7b6e0 100644 --- a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Conversions.h +++ b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Conversions.h @@ -44,7 +44,7 @@ GeneralResult unvalidatedConvert( const hal::V1_3::Request::MemoryPool& memoryPool); GeneralResult unvalidatedConvert( const hal::V1_3::OptionalTimePoint& optionalTimePoint); -GeneralResult unvalidatedConvert( +GeneralResult unvalidatedConvert( const hal::V1_3::OptionalTimeoutDuration& optionalTimeoutDuration); GeneralResult unvalidatedConvert(const hal::V1_3::ErrorStatus& errorStatus); @@ -54,7 +54,7 @@ GeneralResult convert(const hal::V1_3::Model& model); GeneralResult convert(const hal::V1_3::BufferDesc& bufferDesc); GeneralResult convert(const hal::V1_3::Request& request); GeneralResult convert(const hal::V1_3::OptionalTimePoint& optionalTimePoint); -GeneralResult convert( +GeneralResult convert( const hal::V1_3::OptionalTimeoutDuration& optionalTimeoutDuration); GeneralResult convert(const hal::V1_3::ErrorStatus& errorStatus); @@ -86,7 +86,7 @@ nn::GeneralResult unvalidatedConvert( nn::GeneralResult unvalidatedConvert( const nn::OptionalTimePoint& optionalTimePoint); nn::GeneralResult unvalidatedConvert( - const nn::OptionalTimeoutDuration& optionalTimeoutDuration); + const nn::OptionalDuration& optionalTimeoutDuration); nn::GeneralResult unvalidatedConvert(const nn::ErrorStatus& errorStatus); nn::GeneralResult convert(const nn::Priority& priority); @@ -96,7 +96,7 @@ nn::GeneralResult convert(const nn::BufferDesc& bufferDesc); nn::GeneralResult convert(const nn::Request& request); nn::GeneralResult convert(const nn::OptionalTimePoint& optionalTimePoint); nn::GeneralResult convert( - const nn::OptionalTimeoutDuration& optionalTimeoutDuration); + const nn::OptionalDuration& optionalTimeoutDuration); nn::GeneralResult convert(const nn::ErrorStatus& errorStatus); nn::GeneralResult convert(const nn::SharedHandle& handle); diff --git a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/PreparedModel.h b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/PreparedModel.h index e0d69dd7c6..09360eceb8 100644 --- a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/PreparedModel.h +++ b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/PreparedModel.h @@ -44,13 +44,13 @@ class PreparedModel final : public nn::IPreparedModel { nn::ExecutionResult, nn::Timing>> execute( const nn::Request& request, nn::MeasureTiming measure, const nn::OptionalTimePoint& deadline, - const nn::OptionalTimeoutDuration& loopTimeoutDuration) const override; + const nn::OptionalDuration& loopTimeoutDuration) const override; nn::GeneralResult> executeFenced( const nn::Request& request, const std::vector& waitFor, nn::MeasureTiming measure, const nn::OptionalTimePoint& deadline, - const nn::OptionalTimeoutDuration& loopTimeoutDuration, - const nn::OptionalTimeoutDuration& timeoutDurationAfterFence) const override; + const nn::OptionalDuration& loopTimeoutDuration, + const nn::OptionalDuration& timeoutDurationAfterFence) const override; std::any getUnderlyingResource() const override; diff --git a/neuralnetworks/1.3/utils/src/Conversions.cpp b/neuralnetworks/1.3/utils/src/Conversions.cpp index 949dd0d1ed..c89a69f28b 100644 --- a/neuralnetworks/1.3/utils/src/Conversions.cpp +++ b/neuralnetworks/1.3/utils/src/Conversions.cpp @@ -272,47 +272,26 @@ GeneralResult unvalidatedConvert( GeneralResult unvalidatedConvert( const hal::V1_3::OptionalTimePoint& optionalTimePoint) { - constexpr auto kTimePointMaxCount = TimePoint::max().time_since_epoch().count(); - const auto makeTimePoint = [](uint64_t count) -> GeneralResult { - if (count > kTimePointMaxCount) { - return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) - << "Unable to unvalidatedConvert OptionalTimePoint because the count exceeds " - "the max"; - } - const auto nanoseconds = std::chrono::nanoseconds{count}; - return TimePoint{nanoseconds}; - }; - using Discriminator = hal::V1_3::OptionalTimePoint::hidl_discriminator; switch (optionalTimePoint.getDiscriminator()) { case Discriminator::none: - return std::nullopt; + return {}; case Discriminator::nanosecondsSinceEpoch: - return makeTimePoint(optionalTimePoint.nanosecondsSinceEpoch()); + return TimePoint{Duration{optionalTimePoint.nanosecondsSinceEpoch()}}; } return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "Invalid OptionalTimePoint discriminator " << underlyingType(optionalTimePoint.getDiscriminator()); } -GeneralResult unvalidatedConvert( +GeneralResult unvalidatedConvert( const hal::V1_3::OptionalTimeoutDuration& optionalTimeoutDuration) { - constexpr auto kTimeoutDurationMaxCount = TimeoutDuration::max().count(); - const auto makeTimeoutDuration = [](uint64_t count) -> GeneralResult { - if (count > kTimeoutDurationMaxCount) { - return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) - << "Unable to unvalidatedConvert OptionalTimeoutDuration because the count " - "exceeds the max"; - } - return TimeoutDuration{count}; - }; - using Discriminator = hal::V1_3::OptionalTimeoutDuration::hidl_discriminator; switch (optionalTimeoutDuration.getDiscriminator()) { case Discriminator::none: - return std::nullopt; + return {}; case Discriminator::nanoseconds: - return makeTimeoutDuration(optionalTimeoutDuration.nanoseconds()); + return Duration(optionalTimeoutDuration.nanoseconds()); } return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "Invalid OptionalTimeoutDuration discriminator " @@ -360,7 +339,7 @@ GeneralResult convert(const hal::V1_3::OptionalTimePoint& opt return validatedConvert(optionalTimePoint); } -GeneralResult convert( +GeneralResult convert( const hal::V1_3::OptionalTimeoutDuration& optionalTimeoutDuration) { return validatedConvert(optionalTimeoutDuration); } @@ -629,27 +608,16 @@ nn::GeneralResult unvalidatedConvert( OptionalTimePoint ret; if (optionalTimePoint.has_value()) { const auto count = optionalTimePoint.value().time_since_epoch().count(); - if (count < 0) { - return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) - << "Unable to unvalidatedConvert OptionalTimePoint because time since epoch " - "count is " - "negative"; - } ret.nanosecondsSinceEpoch(count); } return ret; } nn::GeneralResult unvalidatedConvert( - const nn::OptionalTimeoutDuration& optionalTimeoutDuration) { + const nn::OptionalDuration& optionalTimeoutDuration) { OptionalTimeoutDuration ret; if (optionalTimeoutDuration.has_value()) { const auto count = optionalTimeoutDuration.value().count(); - if (count < 0) { - return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) - << "Unable to unvalidatedConvert OptionalTimeoutDuration because count is " - "negative"; - } ret.nanoseconds(count); } return ret; @@ -697,7 +665,7 @@ nn::GeneralResult convert(const nn::OptionalTimePoint& option } nn::GeneralResult convert( - const nn::OptionalTimeoutDuration& optionalTimeoutDuration) { + const nn::OptionalDuration& optionalTimeoutDuration) { return validatedConvert(optionalTimeoutDuration); } diff --git a/neuralnetworks/1.3/utils/src/PreparedModel.cpp b/neuralnetworks/1.3/utils/src/PreparedModel.cpp index 49b9b0bcc3..124a8db263 100644 --- a/neuralnetworks/1.3/utils/src/PreparedModel.cpp +++ b/neuralnetworks/1.3/utils/src/PreparedModel.cpp @@ -159,7 +159,7 @@ PreparedModel::executeAsynchronously(const Request& request, V1_2::MeasureTiming nn::ExecutionResult, nn::Timing>> PreparedModel::execute( const nn::Request& request, nn::MeasureTiming measure, const nn::OptionalTimePoint& deadline, - const nn::OptionalTimeoutDuration& loopTimeoutDuration) const { + const nn::OptionalDuration& loopTimeoutDuration) const { // Ensure that request is ready for IPC. std::optional maybeRequestInShared; const nn::Request& requestInShared = NN_TRY(hal::utils::makeExecutionFailure( @@ -200,8 +200,8 @@ nn::ExecutionResult, nn::Timing>> Prepare nn::GeneralResult> PreparedModel::executeFenced(const nn::Request& request, const std::vector& waitFor, nn::MeasureTiming measure, const nn::OptionalTimePoint& deadline, - const nn::OptionalTimeoutDuration& loopTimeoutDuration, - const nn::OptionalTimeoutDuration& timeoutDurationAfterFence) const { + const nn::OptionalDuration& loopTimeoutDuration, + const nn::OptionalDuration& timeoutDurationAfterFence) const { // Ensure that request is ready for IPC. std::optional maybeRequestInShared; const nn::Request& requestInShared = diff --git a/neuralnetworks/utils/common/include/nnapi/hal/InvalidPreparedModel.h b/neuralnetworks/utils/common/include/nnapi/hal/InvalidPreparedModel.h index 4b32b4e3af..985cddb2c2 100644 --- a/neuralnetworks/utils/common/include/nnapi/hal/InvalidPreparedModel.h +++ b/neuralnetworks/utils/common/include/nnapi/hal/InvalidPreparedModel.h @@ -32,13 +32,13 @@ class InvalidPreparedModel final : public nn::IPreparedModel { nn::ExecutionResult, nn::Timing>> execute( const nn::Request& request, nn::MeasureTiming measure, const nn::OptionalTimePoint& deadline, - const nn::OptionalTimeoutDuration& loopTimeoutDuration) const override; + const nn::OptionalDuration& loopTimeoutDuration) const override; nn::GeneralResult> executeFenced( const nn::Request& request, const std::vector& waitFor, nn::MeasureTiming measure, const nn::OptionalTimePoint& deadline, - const nn::OptionalTimeoutDuration& loopTimeoutDuration, - const nn::OptionalTimeoutDuration& timeoutDurationAfterFence) const override; + const nn::OptionalDuration& loopTimeoutDuration, + const nn::OptionalDuration& timeoutDurationAfterFence) const override; std::any getUnderlyingResource() const override; }; diff --git a/neuralnetworks/utils/common/include/nnapi/hal/ResilientPreparedModel.h b/neuralnetworks/utils/common/include/nnapi/hal/ResilientPreparedModel.h index c2940d16bc..d86c88be32 100644 --- a/neuralnetworks/utils/common/include/nnapi/hal/ResilientPreparedModel.h +++ b/neuralnetworks/utils/common/include/nnapi/hal/ResilientPreparedModel.h @@ -49,13 +49,13 @@ class ResilientPreparedModel final : public nn::IPreparedModel { nn::ExecutionResult, nn::Timing>> execute( const nn::Request& request, nn::MeasureTiming measure, const nn::OptionalTimePoint& deadline, - const nn::OptionalTimeoutDuration& loopTimeoutDuration) const override; + const nn::OptionalDuration& loopTimeoutDuration) const override; nn::GeneralResult> executeFenced( const nn::Request& request, const std::vector& waitFor, nn::MeasureTiming measure, const nn::OptionalTimePoint& deadline, - const nn::OptionalTimeoutDuration& loopTimeoutDuration, - const nn::OptionalTimeoutDuration& timeoutDurationAfterFence) const override; + const nn::OptionalDuration& loopTimeoutDuration, + const nn::OptionalDuration& timeoutDurationAfterFence) const override; std::any getUnderlyingResource() const override; diff --git a/neuralnetworks/utils/common/src/InvalidPreparedModel.cpp b/neuralnetworks/utils/common/src/InvalidPreparedModel.cpp index 9ae7a63949..a46f4ac574 100644 --- a/neuralnetworks/utils/common/src/InvalidPreparedModel.cpp +++ b/neuralnetworks/utils/common/src/InvalidPreparedModel.cpp @@ -29,7 +29,7 @@ namespace android::hardware::neuralnetworks::utils { nn::ExecutionResult, nn::Timing>> InvalidPreparedModel::execute(const nn::Request& /*request*/, nn::MeasureTiming /*measure*/, const nn::OptionalTimePoint& /*deadline*/, - const nn::OptionalTimeoutDuration& /*loopTimeoutDuration*/) const { + const nn::OptionalDuration& /*loopTimeoutDuration*/) const { return NN_ERROR() << "InvalidPreparedModel"; } @@ -37,8 +37,8 @@ nn::GeneralResult> InvalidPreparedModel::executeFenced( const nn::Request& /*request*/, const std::vector& /*waitFor*/, nn::MeasureTiming /*measure*/, const nn::OptionalTimePoint& /*deadline*/, - const nn::OptionalTimeoutDuration& /*loopTimeoutDuration*/, - const nn::OptionalTimeoutDuration& /*timeoutDurationAfterFence*/) const { + const nn::OptionalDuration& /*loopTimeoutDuration*/, + const nn::OptionalDuration& /*timeoutDurationAfterFence*/) const { return NN_ERROR() << "InvalidPreparedModel"; } diff --git a/neuralnetworks/utils/common/src/ResilientPreparedModel.cpp b/neuralnetworks/utils/common/src/ResilientPreparedModel.cpp index 1c9ecba4f6..012a1dedc3 100644 --- a/neuralnetworks/utils/common/src/ResilientPreparedModel.cpp +++ b/neuralnetworks/utils/common/src/ResilientPreparedModel.cpp @@ -64,16 +64,17 @@ nn::SharedPreparedModel ResilientPreparedModel::recover( nn::ExecutionResult, nn::Timing>> ResilientPreparedModel::execute(const nn::Request& request, nn::MeasureTiming measure, const nn::OptionalTimePoint& deadline, - const nn::OptionalTimeoutDuration& loopTimeoutDuration) const { + const nn::OptionalDuration& loopTimeoutDuration) const { return getPreparedModel()->execute(request, measure, deadline, loopTimeoutDuration); } nn::GeneralResult> -ResilientPreparedModel::executeFenced( - const nn::Request& request, const std::vector& waitFor, - nn::MeasureTiming measure, const nn::OptionalTimePoint& deadline, - const nn::OptionalTimeoutDuration& loopTimeoutDuration, - const nn::OptionalTimeoutDuration& timeoutDurationAfterFence) const { +ResilientPreparedModel::executeFenced(const nn::Request& request, + const std::vector& waitFor, + nn::MeasureTiming measure, + const nn::OptionalTimePoint& deadline, + const nn::OptionalDuration& loopTimeoutDuration, + const nn::OptionalDuration& timeoutDurationAfterFence) const { return getPreparedModel()->executeFenced(request, waitFor, measure, deadline, loopTimeoutDuration, timeoutDurationAfterFence); } -- GitLab From 7a655bb3d4752e0c373ad3fdbcf4508eb7050afc Mon Sep 17 00:00:00 2001 From: Michael Butler Date: Sun, 13 Dec 2020 23:06:06 -0800 Subject: [PATCH 330/790] Add HIDL lifetime and protecting callback info to NN README This CL copies information from packages/modules/NeuralNetworks/runtime/VersionedInterfaces.cpp and modifies the description to be more appropriate for the NN HAL utility code. Specific sections added to the README: * "HIDL Interface Lifetimes across Processes" * "Protecting Asynchronous Calls across HIDL" Bug: 170289677 Test: mma Change-Id: Id381895535d708b627f4746687b4d12e16560639 --- .../utils/include/nnapi/hal/1.0/Callbacks.h | 3 + .../1.0/utils/include/nnapi/hal/1.0/Device.h | 4 ++ .../include/nnapi/hal/1.0/PreparedModel.h | 4 ++ neuralnetworks/1.0/utils/src/Callbacks.cpp | 3 + neuralnetworks/1.0/utils/src/Device.cpp | 3 + .../1.0/utils/src/PreparedModel.cpp | 3 + .../1.1/utils/include/nnapi/hal/1.1/Device.h | 4 ++ neuralnetworks/1.1/utils/src/Device.cpp | 3 + .../utils/include/nnapi/hal/1.2/Callbacks.h | 3 + .../1.2/utils/include/nnapi/hal/1.2/Device.h | 4 ++ .../include/nnapi/hal/1.2/PreparedModel.h | 4 ++ neuralnetworks/1.2/utils/src/Callbacks.cpp | 3 + neuralnetworks/1.2/utils/src/Device.cpp | 3 + .../1.2/utils/src/PreparedModel.cpp | 3 + .../1.3/utils/include/nnapi/hal/1.3/Buffer.h | 4 ++ .../utils/include/nnapi/hal/1.3/Callbacks.h | 3 + .../1.3/utils/include/nnapi/hal/1.3/Device.h | 4 ++ .../include/nnapi/hal/1.3/PreparedModel.h | 4 ++ neuralnetworks/1.3/utils/src/Buffer.cpp | 3 + neuralnetworks/1.3/utils/src/Callbacks.cpp | 3 + neuralnetworks/1.3/utils/src/Device.cpp | 3 + .../1.3/utils/src/PreparedModel.cpp | 3 + neuralnetworks/utils/README.md | 57 +++++++++++++++++-- .../include/nnapi/hal/ProtectCallback.h | 3 + 24 files changed, 129 insertions(+), 5 deletions(-) diff --git a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Callbacks.h b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Callbacks.h index 65b75e5d82..2e00fcecf3 100644 --- a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Callbacks.h +++ b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Callbacks.h @@ -27,6 +27,9 @@ #include #include +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface +// lifetimes across processes and for protecting asynchronous calls across HIDL. + namespace android::hardware::neuralnetworks::V1_0::utils { class PreparedModelCallback final : public IPreparedModelCallback, diff --git a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Device.h b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Device.h index ee103bacf5..db3b2ad44f 100644 --- a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Device.h +++ b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Device.h @@ -32,8 +32,12 @@ #include #include +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface +// lifetimes across processes and for protecting asynchronous calls across HIDL. + namespace android::hardware::neuralnetworks::V1_0::utils { +// Class that adapts V1_0::IDevice to nn::IDevice. class Device final : public nn::IDevice { struct PrivateConstructorTag {}; diff --git a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/PreparedModel.h b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/PreparedModel.h index 31f366dadc..3c1f9b823a 100644 --- a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/PreparedModel.h +++ b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/PreparedModel.h @@ -29,8 +29,12 @@ #include #include +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface +// lifetimes across processes and for protecting asynchronous calls across HIDL. + namespace android::hardware::neuralnetworks::V1_0::utils { +// Class that adapts V1_0::IPreparedModel to nn::IPreparedModel. class PreparedModel final : public nn::IPreparedModel { struct PrivateConstructorTag {}; diff --git a/neuralnetworks/1.0/utils/src/Callbacks.cpp b/neuralnetworks/1.0/utils/src/Callbacks.cpp index b1259c3c56..a0bdb3cd99 100644 --- a/neuralnetworks/1.0/utils/src/Callbacks.cpp +++ b/neuralnetworks/1.0/utils/src/Callbacks.cpp @@ -32,6 +32,9 @@ #include +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface +// lifetimes across processes and for protecting asynchronous calls across HIDL. + namespace android::hardware::neuralnetworks::V1_0::utils { namespace { diff --git a/neuralnetworks/1.0/utils/src/Device.cpp b/neuralnetworks/1.0/utils/src/Device.cpp index 285c515c20..83e0015689 100644 --- a/neuralnetworks/1.0/utils/src/Device.cpp +++ b/neuralnetworks/1.0/utils/src/Device.cpp @@ -38,6 +38,9 @@ #include #include +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface +// lifetimes across processes and for protecting asynchronous calls across HIDL. + namespace android::hardware::neuralnetworks::V1_0::utils { namespace { diff --git a/neuralnetworks/1.0/utils/src/PreparedModel.cpp b/neuralnetworks/1.0/utils/src/PreparedModel.cpp index 46dd3f8254..c595353192 100644 --- a/neuralnetworks/1.0/utils/src/PreparedModel.cpp +++ b/neuralnetworks/1.0/utils/src/PreparedModel.cpp @@ -34,6 +34,9 @@ #include #include +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface +// lifetimes across processes and for protecting asynchronous calls across HIDL. + namespace android::hardware::neuralnetworks::V1_0::utils { nn::GeneralResult> PreparedModel::create( diff --git a/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Device.h b/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Device.h index c1e95fe1a5..5e224b5018 100644 --- a/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Device.h +++ b/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Device.h @@ -32,8 +32,12 @@ #include #include +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface +// lifetimes across processes and for protecting asynchronous calls across HIDL. + namespace android::hardware::neuralnetworks::V1_1::utils { +// Class that adapts V1_1::IDevice to nn::IDevice. class Device final : public nn::IDevice { struct PrivateConstructorTag {}; diff --git a/neuralnetworks/1.1/utils/src/Device.cpp b/neuralnetworks/1.1/utils/src/Device.cpp index f73d3f8253..b57c7f4c54 100644 --- a/neuralnetworks/1.1/utils/src/Device.cpp +++ b/neuralnetworks/1.1/utils/src/Device.cpp @@ -39,6 +39,9 @@ #include #include +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface +// lifetimes across processes and for protecting asynchronous calls across HIDL. + namespace android::hardware::neuralnetworks::V1_1::utils { namespace { diff --git a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Callbacks.h b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Callbacks.h index bc7d92ac83..1162bc33b3 100644 --- a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Callbacks.h +++ b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Callbacks.h @@ -31,6 +31,9 @@ #include #include +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface +// lifetimes across processes and for protecting asynchronous calls across HIDL. + namespace android::hardware::neuralnetworks::V1_2::utils { class PreparedModelCallback final : public IPreparedModelCallback, diff --git a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Device.h b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Device.h index a68830d86e..79c3b041ad 100644 --- a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Device.h +++ b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Device.h @@ -32,6 +32,9 @@ #include #include +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface +// lifetimes across processes and for protecting asynchronous calls across HIDL. + namespace android::hardware::neuralnetworks::V1_2::utils { nn::GeneralResult initVersionString(V1_2::IDevice* device); @@ -40,6 +43,7 @@ nn::GeneralResult> initExtensions(V1_2::IDevice* devi nn::GeneralResult> initNumberOfCacheFilesNeeded( V1_2::IDevice* device); +// Class that adapts V1_2::IDevice to nn::IDevice. class Device final : public nn::IDevice { struct PrivateConstructorTag {}; diff --git a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/PreparedModel.h b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/PreparedModel.h index 65e1e8aa3f..71d033b6cc 100644 --- a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/PreparedModel.h +++ b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/PreparedModel.h @@ -30,8 +30,12 @@ #include #include +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface +// lifetimes across processes and for protecting asynchronous calls across HIDL. + namespace android::hardware::neuralnetworks::V1_2::utils { +// Class that adapts V1_2::IPreparedModel to nn::IPreparedModel. class PreparedModel final : public nn::IPreparedModel { struct PrivateConstructorTag {}; diff --git a/neuralnetworks/1.2/utils/src/Callbacks.cpp b/neuralnetworks/1.2/utils/src/Callbacks.cpp index 39f88c2c5e..ab3e0ca879 100644 --- a/neuralnetworks/1.2/utils/src/Callbacks.cpp +++ b/neuralnetworks/1.2/utils/src/Callbacks.cpp @@ -36,6 +36,9 @@ #include +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface +// lifetimes across processes and for protecting asynchronous calls across HIDL. + namespace android::hardware::neuralnetworks::V1_2::utils { namespace { diff --git a/neuralnetworks/1.2/utils/src/Device.cpp b/neuralnetworks/1.2/utils/src/Device.cpp index 0061065f0b..6cca841aba 100644 --- a/neuralnetworks/1.2/utils/src/Device.cpp +++ b/neuralnetworks/1.2/utils/src/Device.cpp @@ -41,6 +41,9 @@ #include #include +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface +// lifetimes across processes and for protecting asynchronous calls across HIDL. + namespace android::hardware::neuralnetworks::V1_2::utils { namespace { diff --git a/neuralnetworks/1.2/utils/src/PreparedModel.cpp b/neuralnetworks/1.2/utils/src/PreparedModel.cpp index dad9a7e74b..88f897f0cf 100644 --- a/neuralnetworks/1.2/utils/src/PreparedModel.cpp +++ b/neuralnetworks/1.2/utils/src/PreparedModel.cpp @@ -37,6 +37,9 @@ #include #include +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface +// lifetimes across processes and for protecting asynchronous calls across HIDL. + namespace android::hardware::neuralnetworks::V1_2::utils { namespace { diff --git a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Buffer.h b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Buffer.h index 637179de33..fda79c88c1 100644 --- a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Buffer.h +++ b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Buffer.h @@ -24,8 +24,12 @@ #include #include +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface +// lifetimes across processes. + namespace android::hardware::neuralnetworks::V1_3::utils { +// Class that adapts V1_3::IBuffer to nn::IBuffer. class Buffer final : public nn::IBuffer { struct PrivateConstructorTag {}; diff --git a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Callbacks.h b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Callbacks.h index d46b111701..cb2a56a2e2 100644 --- a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Callbacks.h +++ b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Callbacks.h @@ -34,6 +34,9 @@ #include #include +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface +// lifetimes across processes and for protecting asynchronous calls across HIDL. + namespace android::hardware::neuralnetworks::V1_3::utils { class PreparedModelCallback final : public IPreparedModelCallback, diff --git a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Device.h b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Device.h index 0f5234bd26..84f606a357 100644 --- a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Device.h +++ b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Device.h @@ -32,8 +32,12 @@ #include #include +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface +// lifetimes across processes and for protecting asynchronous calls across HIDL. + namespace android::hardware::neuralnetworks::V1_3::utils { +// Class that adapts V1_3::IDevice to nn::IDevice. class Device final : public nn::IDevice { struct PrivateConstructorTag {}; diff --git a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/PreparedModel.h b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/PreparedModel.h index e0d69dd7c6..fd21a238c6 100644 --- a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/PreparedModel.h +++ b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/PreparedModel.h @@ -29,8 +29,12 @@ #include #include +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface +// lifetimes across processes and for protecting asynchronous calls across HIDL. + namespace android::hardware::neuralnetworks::V1_3::utils { +// Class that adapts V1_3::IPreparedModel to nn::IPreparedModel. class PreparedModel final : public nn::IPreparedModel { struct PrivateConstructorTag {}; diff --git a/neuralnetworks/1.3/utils/src/Buffer.cpp b/neuralnetworks/1.3/utils/src/Buffer.cpp index ffdeccdf62..4ef54a2c93 100644 --- a/neuralnetworks/1.3/utils/src/Buffer.cpp +++ b/neuralnetworks/1.3/utils/src/Buffer.cpp @@ -33,6 +33,9 @@ #include #include +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface +// lifetimes across processes. + namespace android::hardware::neuralnetworks::V1_3::utils { nn::GeneralResult> Buffer::create( diff --git a/neuralnetworks/1.3/utils/src/Callbacks.cpp b/neuralnetworks/1.3/utils/src/Callbacks.cpp index e3c6074549..17c20fba68 100644 --- a/neuralnetworks/1.3/utils/src/Callbacks.cpp +++ b/neuralnetworks/1.3/utils/src/Callbacks.cpp @@ -39,6 +39,9 @@ #include +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface +// lifetimes across processes and for protecting asynchronous calls across HIDL. + namespace android::hardware::neuralnetworks::V1_3::utils { namespace { diff --git a/neuralnetworks/1.3/utils/src/Device.cpp b/neuralnetworks/1.3/utils/src/Device.cpp index 82837bac73..60564985de 100644 --- a/neuralnetworks/1.3/utils/src/Device.cpp +++ b/neuralnetworks/1.3/utils/src/Device.cpp @@ -47,6 +47,9 @@ #include #include +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface +// lifetimes across processes and for protecting asynchronous calls across HIDL. + namespace android::hardware::neuralnetworks::V1_3::utils { namespace { diff --git a/neuralnetworks/1.3/utils/src/PreparedModel.cpp b/neuralnetworks/1.3/utils/src/PreparedModel.cpp index 49b9b0bcc3..99aaa8bca0 100644 --- a/neuralnetworks/1.3/utils/src/PreparedModel.cpp +++ b/neuralnetworks/1.3/utils/src/PreparedModel.cpp @@ -39,6 +39,9 @@ #include #include +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface +// lifetimes across processes and for protecting asynchronous calls across HIDL. + namespace android::hardware::neuralnetworks::V1_3::utils { namespace { diff --git a/neuralnetworks/utils/README.md b/neuralnetworks/utils/README.md index 0dee103811..45ca0b442f 100644 --- a/neuralnetworks/utils/README.md +++ b/neuralnetworks/utils/README.md @@ -1,11 +1,11 @@ # NNAPI Conversions `convert` fails if either the source type or the destination type is invalid, and it yields a valid -object if the conversion succeeds. For example, let's say that an enumeration in the current -version has fewer possible values than the "same" canonical enumeration, such as `OperationType`. -The new value of `HARD_SWISH` (introduced in Android R / NN HAL 1.3) does not map to any valid -existing value in `OperationType`, but an older value of `ADD` (introduced in Android OC-MR1 / NN -HAL 1.0) is valid. This can be seen in the following model conversions: +object if the conversion succeeds. For example, let's say that an enumeration in the current version +has fewer possible values than the "same" canonical enumeration, such as `OperationType`. The new +value of `HARD_SWISH` (introduced in Android R / NN HAL 1.3) does not map to any valid existing +value in `OperationType`, but an older value of `ADD` (introduced in Android OC-MR1 / NN HAL 1.0) is +valid. This can be seen in the following model conversions: ```cpp // Unsuccessful conversion @@ -48,3 +48,50 @@ The `convert` functions operate only on types that used in a HIDL method call di `unvalidatedConvert` functions operate on types that are either used in a HIDL method call directly (i.e., not as a nested class) or used in a subsequent version of the NN HAL. Prefer using `convert` over `unvalidatedConvert`. + +# HIDL Interface Lifetimes across Processes + +Some notes about HIDL interface objects and lifetimes across processes: + +All HIDL interface objects inherit from `IBase`, which itself inherits from `::android::RefBase`. As +such, all HIDL interface objects are reference counted and must be owned through `::android::sp` (or +referenced through `::android::wp`). Allocating `RefBase` objects on the stack will log errors and +may result in crashes, and deleting a `RefBase` object through another means (e.g., "delete", +"free", or RAII-cleanup through `std::unique_ptr` or some equivalent) will result in double-free +and/or use-after-free undefined behavior. + +HIDL/Binder manages the reference count of HIDL interface objects automatically across processes. If +a process that references (but did not create) the HIDL interface object dies, HIDL/Binder ensures +any reference count it held is properly released. (Caveat: it might be possible that HIDL/Binder +behave strangely with `::android::wp` references.) + +If the process which created the HIDL interface object dies, any call on this object from another +process will result in a HIDL transport error with the code `DEAD_OBJECT`. + +# Protecting Asynchronous Calls across HIDL + +Some notes about asynchronous calls across HIDL: + +For synchronous calls across HIDL, if an error occurs after the function was called but before it +returns, HIDL will return a transport error. For example, if the message cannot be delivered to the +server process or if the server process dies before returning a result, HIDL will return from the +function with the appropriate transport error in the `Return<>` object, which can be queried with +`Return<>::isOk()`, `Return<>::isDeadObject()`, `Return<>::description()`, etc. + +However, HIDL offers no such error management in the case of asynchronous calls. By default, if the +client launches an asynchronous task and the server fails to return a result through the callback, +the client will be left waiting indefinitely for a result it will never receive. + +In the NNAPI, `IDevice::prepareModel*` and `IPreparedModel::execute*` (but not +`IPreparedModel::executeSynchronously*`) are asynchronous calls across HIDL. Specifically, these +asynchronous functions are called with a HIDL interface callback object (`IPrepareModelCallback` for +`IDevice::prepareModel*` and `IExecutionCallback` for `IPreparedModel::execute*`) and are expected +to quickly return, and the results are returned at a later time through these callback objects. + +To protect against the case when the server dies after the asynchronous task was called successfully +but before the results could be returned, HIDL provides an object called a "`hidl_death_recipient`," +which can be used to detect when an interface object (and more generally, the server process) has +died. nnapi/hal/ProtectCallback.h's `DeathHandler` uses `hidl_death_recipient`s to detect when the +driver process has died, and `DeathHandler` will unblock any thread waiting on the results of an +`IProtectedCallback` callback object that may otherwise not be signaled. In order for this to work, +the `IProtectedCallback` object must have been registered via `DeathHandler::protectCallback()`. diff --git a/neuralnetworks/utils/common/include/nnapi/hal/ProtectCallback.h b/neuralnetworks/utils/common/include/nnapi/hal/ProtectCallback.h index 85bd6137ee..c9218857ac 100644 --- a/neuralnetworks/utils/common/include/nnapi/hal/ProtectCallback.h +++ b/neuralnetworks/utils/common/include/nnapi/hal/ProtectCallback.h @@ -28,6 +28,9 @@ #include #include +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface +// lifetimes across processes and for protecting asynchronous calls across HIDL. + namespace android::hardware::neuralnetworks::utils { class IProtectedCallback { -- GitLab From 35a3a77811322b867e23faa9673237e1e308175b Mon Sep 17 00:00:00 2001 From: Mikhail Naganov Date: Mon, 14 Dec 2020 23:18:30 +0000 Subject: [PATCH 331/790] HidlUtils: remove temporary conversion functions Remove temporary conversion functions and update the code that was using them. Bug: 142480271 Test: m Change-Id: Idf36dbac398efbc03bd6da68c79f6fb1ddc24e9c --- audio/common/all-versions/default/HidlUtils.h | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/audio/common/all-versions/default/HidlUtils.h b/audio/common/all-versions/default/HidlUtils.h index c420a2f712..a0bd1bc27e 100644 --- a/audio/common/all-versions/default/HidlUtils.h +++ b/audio/common/all-versions/default/HidlUtils.h @@ -76,19 +76,7 @@ struct HidlUtils { const char* halDeviceAddress, DeviceAddress* device); #endif -#if MAJOR_VERSION <= 6 - // Temporary versions for compatibility with forks of the default implementation. - // Will be removed, do not use! - static status_t audioConfigFromHal(const audio_config_t& halConfig, AudioConfig* config) { - return audioConfigFromHal(halConfig, false /*isInput--ignored*/, config); - } - static std::unique_ptr audioPortConfigsToHal( - const hidl_vec& configs) { - std::unique_ptr halConfigs; - (void)audioPortConfigsToHal(configs, &halConfigs); - return halConfigs; - } -#else // V7 and above +#if MAJOR_VERSION >= 7 static status_t audioChannelMaskFromHal(audio_channel_mask_t halChannelMask, bool isInput, AudioChannelMask* channelMask); static status_t audioChannelMasksFromHal(const std::vector& halChannelMasks, @@ -138,7 +126,7 @@ struct HidlUtils { struct audio_port_config_device_ext* device, struct audio_port_config_mix_ext* mix, struct audio_port_config_session_ext* session); -#endif +#endif // MAJOR_VERSION >= 7 // V4 and below have DeviceAddress defined in the 'core' interface. // To avoid duplicating code, the implementations of deviceAddressTo/FromHal -- GitLab From cfca8a758d7ff92431f16ca7cd4a0fe8cf3d8d8a Mon Sep 17 00:00:00 2001 From: Yu-Han Yang Date: Sat, 12 Dec 2020 09:36:28 -0800 Subject: [PATCH 332/790] Add @utf8InCpp to String fields Also updated the following - remove carrierFrequencyHz since signalType already includes it. - update default implementation's mockMeasurement. Bug: 173797017 Test: on cuttlefish Change-Id: I60b11f51c5cf414b197ac9ca248a55c2dc1352a1 --- .../hardware/gnss/GnssMeasurement.aidl | 1 - .../android/hardware/gnss/GnssSignalType.aidl | 34 +++++------ .../hardware/gnss/GnssMeasurement.aidl | 19 ------ .../android/hardware/gnss/GnssSignalType.aidl | 34 +++++------ gnss/common/utils/default/Utils.cpp | 58 ++++++++++++------- 5 files changed, 72 insertions(+), 74 deletions(-) diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMeasurement.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMeasurement.aidl index 7d15855b5d..73d8a86187 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMeasurement.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMeasurement.aidl @@ -32,7 +32,6 @@ parcelable GnssMeasurement { int accumulatedDeltaRangeState; double accumulatedDeltaRangeM; double accumulatedDeltaRangeUncertaintyM; - float carrierFrequencyHz; long carrierCycles; double carrierPhase; double carrierPhaseUncertainty; diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssSignalType.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssSignalType.aidl index 3e66c4a73c..f10b9430dd 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssSignalType.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssSignalType.aidl @@ -20,21 +20,21 @@ package android.hardware.gnss; parcelable GnssSignalType { android.hardware.gnss.GnssConstellationType constellation; double carrierFrequencyHz; - String codeType; - const String CODE_TYPE_A = "A"; - const String CODE_TYPE_B = "B"; - const String CODE_TYPE_C = "C"; - const String CODE_TYPE_D = "D"; - const String CODE_TYPE_I = "I"; - const String CODE_TYPE_L = "L"; - const String CODE_TYPE_M = "M"; - const String CODE_TYPE_N = "N"; - const String CODE_TYPE_P = "P"; - const String CODE_TYPE_Q = "Q"; - const String CODE_TYPE_S = "S"; - const String CODE_TYPE_W = "W"; - const String CODE_TYPE_X = "X"; - const String CODE_TYPE_Y = "Y"; - const String CODE_TYPE_Z = "Z"; - const String CODE_TYPE_UNKNOWN = "UNKNOWN"; + @utf8InCpp String codeType; + const @utf8InCpp String CODE_TYPE_A = "A"; + const @utf8InCpp String CODE_TYPE_B = "B"; + const @utf8InCpp String CODE_TYPE_C = "C"; + const @utf8InCpp String CODE_TYPE_D = "D"; + const @utf8InCpp String CODE_TYPE_I = "I"; + const @utf8InCpp String CODE_TYPE_L = "L"; + const @utf8InCpp String CODE_TYPE_M = "M"; + const @utf8InCpp String CODE_TYPE_N = "N"; + const @utf8InCpp String CODE_TYPE_P = "P"; + const @utf8InCpp String CODE_TYPE_Q = "Q"; + const @utf8InCpp String CODE_TYPE_S = "S"; + const @utf8InCpp String CODE_TYPE_W = "W"; + const @utf8InCpp String CODE_TYPE_X = "X"; + const @utf8InCpp String CODE_TYPE_Y = "Y"; + const @utf8InCpp String CODE_TYPE_Z = "Z"; + const @utf8InCpp String CODE_TYPE_UNKNOWN = "UNKNOWN"; } diff --git a/gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl b/gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl index fae862b07e..ce88647162 100644 --- a/gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl +++ b/gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl @@ -16,7 +16,6 @@ package android.hardware.gnss; -import android.hardware.gnss.GnssConstellationType; import android.hardware.gnss.GnssSignalType; import android.hardware.gnss.GnssMultipathIndicator; @@ -476,24 +475,6 @@ parcelable GnssMeasurement { */ double accumulatedDeltaRangeUncertaintyM; - /** - * 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. - * - * If the data is available, gnssMeasurementFlags must contain - * HAS_CARRIER_FREQUENCY. - */ - float carrierFrequencyHz; - /** * The number of full carrier cycles between the satellite and the * receiver. The reference frequency is given by the field diff --git a/gnss/aidl/android/hardware/gnss/GnssSignalType.aidl b/gnss/aidl/android/hardware/gnss/GnssSignalType.aidl index a284fedc3f..9c68db1f54 100644 --- a/gnss/aidl/android/hardware/gnss/GnssSignalType.aidl +++ b/gnss/aidl/android/hardware/gnss/GnssSignalType.aidl @@ -46,67 +46,67 @@ parcelable GnssSignalType { /** * GNSS signal code type "A" representing GALILEO E1A, GALILEO E6A, IRNSS L5A, IRNSS SA. */ - const String CODE_TYPE_A = "A"; + const @utf8InCpp String CODE_TYPE_A = "A"; /** * GNSS signal code type "B" representing GALILEO E1B, GALILEO E6B, IRNSS L5B, IRNSS SB. */ - const String CODE_TYPE_B = "B"; + const @utf8InCpp String CODE_TYPE_B = "B"; /** * GNSS signal code type "C" representing GPS L1 C/A, GPS L2 C/A, GLONASS G1 C/A, * GLONASS G2 C/A, GALILEO E1C, GALILEO E6C, SBAS L1 C/A, QZSS L1 C/A, IRNSS L5C. */ - const String CODE_TYPE_C = "C"; + const @utf8InCpp String CODE_TYPE_C = "C"; /** * GNSS signal code type "D" representing BDS B1C D. */ - const String CODE_TYPE_D = "D"; + const @utf8InCpp String CODE_TYPE_D = "D"; /** * GNSS signal code type "I" representing GPS L5 I, GLONASS G3 I, GALILEO E5a I, GALILEO E5b I, * GALILEO E5a+b I, SBAS L5 I, QZSS L5 I, BDS B1 I, BDS B2 I, BDS B3 I. */ - const String CODE_TYPE_I = "I"; + const @utf8InCpp String CODE_TYPE_I = "I"; /** * GNSS signal code type "L" representing GPS L1C (P), GPS L2C (L), QZSS L1C (P), QZSS L2C (L), * LEX(6) L. */ - const String CODE_TYPE_L = "L"; + const @utf8InCpp String CODE_TYPE_L = "L"; /** * GNSS signal code type "M" representing GPS L1M, GPS L2M. */ - const String CODE_TYPE_M = "M"; + const @utf8InCpp String CODE_TYPE_M = "M"; /** * GNSS signal code type "N" representing GPS L1 codeless, GPS L2 codeless. */ - const String CODE_TYPE_N = "N"; + const @utf8InCpp String CODE_TYPE_N = "N"; /** * GNSS signal code type "P" representing GPS L1P, GPS L2P, GLONASS G1P, GLONASS G2P, BDS B1C P. */ - const String CODE_TYPE_P = "P"; + const @utf8InCpp String CODE_TYPE_P = "P"; /** * GNSS signal code type "Q" representing GPS L5 Q, GLONASS G3 Q, GALILEO E5a Q, GALILEO E5b Q, * GALILEO E5a+b Q, SBAS L5 Q, QZSS L5 Q, BDS B1 Q, BDS B2 Q, BDS B3 Q. */ - const String CODE_TYPE_Q = "Q"; + const @utf8InCpp String CODE_TYPE_Q = "Q"; /** * GNSS signal code type "S" represents GPS L1C (D), GPS L2C (M), QZSS L1C (D), QZSS L2C (M), * LEX(6) S. */ - const String CODE_TYPE_S = "S"; + const @utf8InCpp String CODE_TYPE_S = "S"; /** * GNSS signal code type "W" representing GPS L1 Z-tracking, GPS L2 Z-tracking. */ - const String CODE_TYPE_W = "W"; + const @utf8InCpp String CODE_TYPE_W = "W"; /** * GNSS signal code type "X" representing GPS L1C (D+P), GPS L2C (M+L), GPS L5 (I+Q), @@ -114,22 +114,22 @@ parcelable GnssSignalType { * GALILEO E6 (B+C), SBAS L5 (I+Q), QZSS L1C (D+P), QZSS L2C (M+L), QZSS L5 (I+Q), * LEX(6) (S+L), BDS B1 (I+Q), BDS B1C (D+P), BDS B2 (I+Q), BDS B3 (I+Q), IRNSS L5 (B+C). */ - const String CODE_TYPE_X = "X"; + const @utf8InCpp String CODE_TYPE_X = "X"; /** * GNSS signal code type "Y" representing GPS L1Y, GPS L2Y. */ - const String CODE_TYPE_Y = "Y"; + const @utf8InCpp String CODE_TYPE_Y = "Y"; /** * GNSS signal code type "Z" representing GALILEO E1 (A+B+C), GALILEO E6 (A+B+C), QZSS L1-SAIF. */ - const String CODE_TYPE_Z = "Z"; + const @utf8InCpp String CODE_TYPE_Z = "Z"; /** * GNSS signal code type "UNKNOWN" representing the GNSS Measurement's code type is unknown. */ - const String CODE_TYPE_UNKNOWN = "UNKNOWN"; + const @utf8InCpp String CODE_TYPE_UNKNOWN = "UNKNOWN"; /** * The type of code that is currently being tracked in the GNSS signal. @@ -145,5 +145,5 @@ parcelable GnssSignalType { * "A channel"). In the future, if for instance a code "G" was added in the official RINEX * standard, "G" could be specified here. */ - String codeType; + @utf8InCpp String codeType; } diff --git a/gnss/common/utils/default/Utils.cpp b/gnss/common/utils/default/Utils.cpp index dd932d447b..e383d516ea 100644 --- a/gnss/common/utils/default/Utils.cpp +++ b/gnss/common/utils/default/Utils.cpp @@ -25,14 +25,17 @@ namespace hardware { namespace gnss { namespace common { -using IGnss = aidl::android::hardware::gnss::IGnss; -using IGnssMeasurementCallback = aidl::android::hardware::gnss::IGnssMeasurementCallback; -using GnssMeasurement = aidl::android::hardware::gnss::GnssMeasurement; +using aidl::android::hardware::gnss::ElapsedRealtime; +using aidl::android::hardware::gnss::GnssClock; +using aidl::android::hardware::gnss::GnssData; +using aidl::android::hardware::gnss::GnssMeasurement; +using aidl::android::hardware::gnss::IGnss; +using aidl::android::hardware::gnss::IGnssMeasurementCallback; + using GnssSvFlags = V1_0::IGnssCallback::GnssSvFlags; using GnssMeasurementFlagsV1_0 = V1_0::IGnssMeasurementCallback::GnssMeasurementFlags; using GnssMeasurementFlagsV2_1 = V2_1::IGnssMeasurementCallback::GnssMeasurementFlags; using GnssMeasurementStateV2_0 = V2_0::IGnssMeasurementCallback::GnssMeasurementState; -using ElapsedRealtime = aidl::android::hardware::gnss::ElapsedRealtime; using ElapsedRealtimeFlags = V2_0::ElapsedRealtimeFlags; using GnssConstellationTypeV2_0 = V2_0::GnssConstellationType; using IGnssMeasurementCallbackV2_0 = V2_0::IGnssMeasurementCallback; @@ -137,38 +140,53 @@ GnssDataV2_0 Utils::getMockMeasurementV2_0() { return gnssData; } -aidl::android::hardware::gnss::GnssData Utils::getMockMeasurement() { +GnssData Utils::getMockMeasurement() { aidl::android::hardware::gnss::GnssSignalType signalType = { .constellation = aidl::android::hardware::gnss::GnssConstellationType::GLONASS, .carrierFrequencyHz = 1.59975e+09, .codeType = aidl::android::hardware::gnss::GnssSignalType::CODE_TYPE_C, }; - aidl::android::hardware::gnss::GnssMeasurement measurement = { - .flags = GnssMeasurement::HAS_CARRIER_FREQUENCY, - .svid = 6, + GnssMeasurement measurement = { + .flags = GnssMeasurement::HAS_AUTOMATIC_GAIN_CONTROL | + GnssMeasurement::HAS_CARRIER_FREQUENCY | GnssMeasurement::HAS_CARRIER_PHASE | + GnssMeasurement::HAS_CARRIER_PHASE_UNCERTAINTY | + GnssMeasurement::HAS_FULL_ISB | GnssMeasurement::HAS_FULL_ISB_UNCERTAINTY | + GnssMeasurement::HAS_SATELLITE_ISB | + GnssMeasurement::HAS_SATELLITE_ISB_UNCERTAINTY, + .svid = 13, .signalType = signalType, .timeOffsetNs = 0.0, .receivedSvTimeInNs = 8195997131077, .receivedSvTimeUncertaintyInNs = 15, .antennaCN0DbHz = 30.0, + .basebandCN0DbHz = 26.5, + .agcLevelDb = 2.3, .pseudorangeRateMps = -484.13739013671875, .pseudorangeRateUncertaintyMps = 1.0379999876022339, .accumulatedDeltaRangeState = GnssMeasurement::ADR_STATE_UNKNOWN, - .accumulatedDeltaRangeM = 0.0, - .accumulatedDeltaRangeUncertaintyM = 0.0, + .accumulatedDeltaRangeM = 1.52, + .accumulatedDeltaRangeUncertaintyM = 2.43, .multipathIndicator = aidl::android::hardware::gnss::GnssMultipathIndicator::UNKNOWN, .state = GnssMeasurement::STATE_CODE_LOCK | GnssMeasurement::STATE_BIT_SYNC | GnssMeasurement::STATE_SUBFRAME_SYNC | GnssMeasurement::STATE_TOW_DECODED | GnssMeasurement::STATE_GLO_STRING_SYNC | - GnssMeasurement::STATE_GLO_TOD_DECODED}; + GnssMeasurement::STATE_GLO_TOD_DECODED, + .fullInterSignalBiasNs = 21.5, + .fullInterSignalBiasUncertaintyNs = 792.0, + .satelliteInterSignalBiasNs = 233.9, + .satelliteInterSignalBiasUncertaintyNs = 921.2, + }; - aidl::android::hardware::gnss::GnssClock clock = {.timeNs = 2713545000000, - .fullBiasNs = -1226701900521857520, - .biasNs = 0.59689998626708984, - .biasUncertaintyNs = 47514.989972114563, - .driftNsps = -51.757811607455452, - .driftUncertaintyNsps = 310.64968328491528, - .hwClockDiscontinuityCount = 1}; + GnssClock clock = {.gnssClockFlags = GnssClock::HAS_FULL_BIAS | GnssClock::HAS_FULL_BIAS | + GnssClock::HAS_BIAS_UNCERTAINTY | GnssClock::HAS_DRIFT | + GnssClock::HAS_DRIFT_UNCERTAINTY, + .timeNs = 35854545000000, + .fullBiasNs = -234621900521857520, + .biasNs = 0.2352389998626708984, + .biasUncertaintyNs = 274.989972114563, + .driftNsps = -124.3742360, + .driftUncertaintyNsps = 239.6234285828, + .hwClockDiscontinuityCount = 999}; ElapsedRealtime timestamp = { .flags = ElapsedRealtime::HAS_TIMESTAMP_NS | ElapsedRealtime::HAS_TIME_UNCERTAINTY_NS, @@ -176,9 +194,9 @@ aidl::android::hardware::gnss::GnssData Utils::getMockMeasurement() { // 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 = 1000000}; + .timeUncertaintyNs = 1020400}; - aidl::android::hardware::gnss::GnssData gnssData = { + GnssData gnssData = { .measurements = {measurement}, .clock = clock, .elapsedRealtime = timestamp}; return gnssData; } -- GitLab From ab70a83b053f00834e12ccfb14b572f2c1cf55c4 Mon Sep 17 00:00:00 2001 From: Quang Luong Date: Mon, 14 Dec 2020 13:01:32 -0800 Subject: [PATCH 333/790] [WifiCoex] Add enum for wifi coex restrictions Add custom enum for wifi coex restrictions since IfaceType is not suitable for use as a bitmask flag since it does not represent bit positions. Bug: 153651001 Test: build Change-Id: I15575ea12784a778a3b358eea1b05b75319aa95b --- wifi/1.5/IWifiChip.hal | 20 +++++++++++++------- wifi/1.5/default/wifi_chip.cpp | 14 ++++++++++++-- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/wifi/1.5/IWifiChip.hal b/wifi/1.5/IWifiChip.hal index e9caa3deb5..80f2ca448c 100644 --- a/wifi/1.5/IWifiChip.hal +++ b/wifi/1.5/IWifiChip.hal @@ -17,7 +17,6 @@ package android.hardware.wifi@1.5; import @1.0::WifiStatus; -import @1.0::IfaceType; import @1.5::IWifiApIface; import @1.0::IWifiIface; import @1.3::IWifiChip; @@ -187,6 +186,12 @@ interface IWifiChip extends @1.4::IWifiChip { NO_POWER_CAP = 0x7FFFFFFF, }; + enum CoexRestriction : uint32_t { + WIFI_DIRECT = 1 << 0, + SOFTAP = 1 << 1, + WIFI_AWARE = 1 << 2 + }; + /** * Invoked to indicate that the provided |CoexUnsafeChannels| should be avoided with the * specified restrictions. @@ -194,13 +199,14 @@ interface IWifiChip extends @1.4::IWifiChip { * Channel avoidance is a suggestion and should be done on a best-effort approach. If a provided * channel is used, then the specified power cap should be applied. * - * In addition, hard restrictions on the Wifi modes may be indicated by |IfaceType| bits - * (STA, AP, P2P, NAN, etc) in the |restrictions| bitfield. If a hard restriction is provided, - * then the channels should be completely avoided for the provided Wifi modes instead of by - * best-effort. + * In addition, hard restrictions on the Wifi modes may be indicated by |CoexRestriction| bits + * (WIFI_DIRECT, SOFTAP, WIFI_AWARE) in the |restrictions| bitfield. If a hard restriction is + * provided, then the channels should be completely avoided for the provided Wifi modes instead + * of by best-effort. * * @param unsafeChannels List of |CoexUnsafeChannels| to avoid. - * @param restrictions Bitset of |IfaceType| values indicating Wifi modes to completely avoid. + * @param restrictions Bitset of |CoexRestriction| values indicating Wifi interfaces to + * completely avoid. * @return status WifiStatus of the operation. * Possible status codes: * |WifiStatusCode.SUCCESS|, @@ -208,6 +214,6 @@ interface IWifiChip extends @1.4::IWifiChip { * |WifiStatusCode.ERROR_INVALID_ARGS|, */ setCoexUnsafeChannels( - vec unsafeChannels, bitfield restrictions) + vec unsafeChannels, bitfield restrictions) generates (WifiStatus status); }; diff --git a/wifi/1.5/default/wifi_chip.cpp b/wifi/1.5/default/wifi_chip.cpp index 1b0353b353..44cd5cf61f 100644 --- a/wifi/1.5/default/wifi_chip.cpp +++ b/wifi/1.5/default/wifi_chip.cpp @@ -724,7 +724,7 @@ Return WifiChip::setMultiStaUseCase( Return WifiChip::setCoexUnsafeChannels( const hidl_vec& unsafeChannels, - hidl_bitfield restrictions, + hidl_bitfield restrictions, setCoexUnsafeChannels_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, &WifiChip::setCoexUnsafeChannelsInternal, @@ -1463,8 +1463,18 @@ WifiStatus WifiChip::setCoexUnsafeChannelsInternal( unsafe_channels, &legacy_unsafe_channels)) { return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); } + uint32_t legacy_restrictions = 0; + if (restrictions & CoexRestriction::WIFI_DIRECT) { + legacy_restrictions |= legacy_hal::wifi_coex_restriction::WIFI_DIRECT; + } + if (restrictions & CoexRestriction::SOFTAP) { + legacy_restrictions |= legacy_hal::wifi_coex_restriction::SOFTAP; + } + if (restrictions & CoexRestriction::WIFI_AWARE) { + legacy_restrictions |= legacy_hal::wifi_coex_restriction::WIFI_AWARE; + } auto legacy_status = legacy_hal_.lock()->setCoexUnsafeChannels( - legacy_unsafe_channels, restrictions); + legacy_unsafe_channels, legacy_restrictions); return createWifiStatusFromLegacyError(legacy_status); } -- GitLab From ad81670318560ccf204f76bbf66ce02fc19bfed0 Mon Sep 17 00:00:00 2001 From: Hayden Gomes Date: Mon, 14 Dec 2020 15:29:29 -0800 Subject: [PATCH 334/790] Adding IAudioControl#onDevicesToDuckChange Introducing new API and parcelable for informing the HAL when to duck audio for automotive targets. Bug: 158242859 Test: atest VtsAidlHalAudioControlTest Change-Id: I5799c556e338d768ea8010e1f035af8584a240dd --- .../automotive/audiocontrol/DuckingInfo.aidl | 25 +++++++++ .../audiocontrol/IAudioControl.aidl | 1 + .../automotive/audiocontrol/DuckingInfo.aidl | 54 +++++++++++++++++++ .../audiocontrol/IAudioControl.aidl | 12 +++++ .../aidl/default/AudioControl.cpp | 22 ++++++++ .../audiocontrol/aidl/default/AudioControl.h | 3 ++ .../aidl/vts/VtsHalAudioControlTargetTest.cpp | 17 ++++++ 7 files changed, 134 insertions(+) create mode 100644 automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/DuckingInfo.aidl create mode 100644 automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/DuckingInfo.aidl diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/DuckingInfo.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/DuckingInfo.aidl new file mode 100644 index 0000000000..6d729e2205 --- /dev/null +++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/DuckingInfo.aidl @@ -0,0 +1,25 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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.automotive.audiocontrol; +@VintfStability +parcelable DuckingInfo { + int zoneId; + String[] deviceAddressesToDuck; + String[] deviceAddressesToUnduck; + String[] usagesHoldingFocus; +} diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IAudioControl.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IAudioControl.aidl index 6916846bcf..e5a0451618 100644 --- a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IAudioControl.aidl +++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IAudioControl.aidl @@ -19,6 +19,7 @@ package android.hardware.automotive.audiocontrol; @VintfStability interface IAudioControl { oneway void onAudioFocusChange(in String usage, in int zoneId, in android.hardware.automotive.audiocontrol.AudioFocusChange focusChange); + oneway void onDevicesToDuckChange(in android.hardware.automotive.audiocontrol.DuckingInfo[] duckingInfos); oneway void registerFocusListener(in android.hardware.automotive.audiocontrol.IFocusListener listener); oneway void setBalanceTowardRight(in float value); oneway void setFadeTowardFront(in float value); diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/DuckingInfo.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/DuckingInfo.aidl new file mode 100644 index 0000000000..e95fe9bb2e --- /dev/null +++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/DuckingInfo.aidl @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + package android.hardware.automotive.audiocontrol; + + /** + * The current ducking information for a single audio zone. + * + *

    This includes devices to duck, as well as unduck based on the contents of a previous + * {@link DuckingInfo}. Additionally, the current usages holding focus in the specified zone are + * included, which were used to determine which addresses to duck. + */ + @VintfStability + parcelable DuckingInfo { + /** + * ID of the associated audio zone + */ + int zoneId; + + /** + * List of addresses for audio output devices that should be ducked. + * + *

    The provided address strings are defined in audio_policy_configuration.xml. + */ + String[] deviceAddressesToDuck; + + /** + * List of addresses for audio output devices that were previously be ducked and should now be + * unducked. + * + *

    The provided address strings are defined in audio_policy_configuration.xml. + */ + String[] deviceAddressesToUnduck; + + /** + * List of usages currently holding focus for this audio zone. + * + *

    See {@code audioUsage} in audio_policy_configuration.xsd for the list of allowed values. + */ + String[] usagesHoldingFocus; + } \ No newline at end of file diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IAudioControl.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IAudioControl.aidl index 0641691d9c..4b03af11a4 100644 --- a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IAudioControl.aidl +++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IAudioControl.aidl @@ -17,6 +17,7 @@ package android.hardware.automotive.audiocontrol; import android.hardware.automotive.audiocontrol.AudioFocusChange; +import android.hardware.automotive.audiocontrol.DuckingInfo; import android.hardware.automotive.audiocontrol.IFocusListener; /** @@ -41,6 +42,17 @@ interface IAudioControl { */ oneway void onAudioFocusChange(in String usage, in int zoneId, in AudioFocusChange focusChange); + /** + * Notifies HAL of changes in output devices that the HAL should apply ducking to. + * + * This will be called in response to changes in audio focus, and will include a + * {@link DuckingInfo} object per audio zone that experienced a change in audo focus. + * + * @param duckingInfos an array of {@link DuckingInfo} objects for the audio zones where audio + * focus has changed. + */ + oneway void onDevicesToDuckChange(in DuckingInfo[] duckingInfos); + /** * Registers focus listener to be used by HAL for requesting and abandoning audio focus. * diff --git a/automotive/audiocontrol/aidl/default/AudioControl.cpp b/automotive/audiocontrol/aidl/default/AudioControl.cpp index 5e09b4f6a1..748947cb2e 100644 --- a/automotive/audiocontrol/aidl/default/AudioControl.cpp +++ b/automotive/audiocontrol/aidl/default/AudioControl.cpp @@ -17,6 +17,7 @@ #include "AudioControl.h" #include +#include #include #include @@ -102,6 +103,27 @@ ndk::ScopedAStatus AudioControl::onAudioFocusChange(const string& in_usage, int3 return ndk::ScopedAStatus::ok(); } +ndk::ScopedAStatus AudioControl::onDevicesToDuckChange( + const std::vector& in_duckingInfos) { + LOG(INFO) << "AudioControl::onDevicesToDuckChange"; + for (const DuckingInfo& duckingInfo : in_duckingInfos) { + LOG(INFO) << "zone: " << duckingInfo.zoneId; + LOG(INFO) << "Devices to duck:"; + for (auto& addressToDuck : duckingInfo.deviceAddressesToDuck) { + LOG(INFO) << addressToDuck; + } + LOG(INFO) << "Devices to unduck:"; + for (auto& addressToUnduck : duckingInfo.deviceAddressesToUnduck) { + LOG(INFO) << addressToUnduck; + } + LOG(INFO) << "Usages holding focus:"; + for (auto& usage : duckingInfo.usagesHoldingFocus) { + LOG(INFO) << usage; + } + } + return ndk::ScopedAStatus::ok(); +} + binder_status_t AudioControl::dump(int fd, const char** args, uint32_t numArgs) { if (numArgs == 0) { return dumpsys(fd); diff --git a/automotive/audiocontrol/aidl/default/AudioControl.h b/automotive/audiocontrol/aidl/default/AudioControl.h index a77da3e6d1..cf5694762d 100644 --- a/automotive/audiocontrol/aidl/default/AudioControl.h +++ b/automotive/audiocontrol/aidl/default/AudioControl.h @@ -18,6 +18,7 @@ #include #include +#include namespace aidl::android::hardware::automotive::audiocontrol { @@ -27,6 +28,8 @@ class AudioControl : public BnAudioControl { public: ndk::ScopedAStatus onAudioFocusChange(const std::string& in_usage, int32_t in_zoneId, AudioFocusChange in_focusChange) override; + ndk::ScopedAStatus onDevicesToDuckChange( + const std::vector& in_duckingInfos) override; ndk::ScopedAStatus registerFocusListener( const shared_ptr& in_listener) override; ndk::ScopedAStatus setBalanceTowardRight(float in_value) override; diff --git a/automotive/audiocontrol/aidl/vts/VtsHalAudioControlTargetTest.cpp b/automotive/audiocontrol/aidl/vts/VtsHalAudioControlTargetTest.cpp index f33b8a5e9d..f23280d1c9 100644 --- a/automotive/audiocontrol/aidl/vts/VtsHalAudioControlTargetTest.cpp +++ b/automotive/audiocontrol/aidl/vts/VtsHalAudioControlTargetTest.cpp @@ -31,6 +31,7 @@ using android::String16; using android::binder::Status; using android::hardware::automotive::audiocontrol::AudioFocusChange; using android::hardware::automotive::audiocontrol::BnFocusListener; +using android::hardware::automotive::audiocontrol::DuckingInfo; using android::hardware::automotive::audiocontrol::IAudioControl; #include "android_audio_policy_configuration_V7_0.h" @@ -129,6 +130,22 @@ TEST_P(AudioControlAidl, FocusChangeExercise) { audioControl->onAudioFocusChange(usage, 0, AudioFocusChange::GAIN_TRANSIENT).isOk()); }; +TEST_P(AudioControlAidl, DuckChangeExercise) { + ALOGI("Duck change test"); + + DuckingInfo duckingInfo; + duckingInfo.zoneId = 0; + duckingInfo.deviceAddressesToDuck = {String16("address 1"), String16("address 2")}; + duckingInfo.deviceAddressesToUnduck = {String16("address 3"), String16("address 4")}; + duckingInfo.usagesHoldingFocus = { + String16(xsd::toString(xsd::AudioUsage::AUDIO_USAGE_MEDIA).c_str()), + String16(xsd::toString(xsd::AudioUsage::AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE) + .c_str())}; + std::vector duckingInfos = {duckingInfo}; + ALOGI("Duck change test start"); + ASSERT_TRUE(audioControl->onDevicesToDuckChange(duckingInfos).isOk()); +} + GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioControlAidl); INSTANTIATE_TEST_SUITE_P( Audiocontrol, AudioControlAidl, -- GitLab From 4c7c64e7fd901d7a1213c4812a0271ee4e5d847d Mon Sep 17 00:00:00 2001 From: Sunil Ravi Date: Tue, 15 Dec 2020 16:52:08 -0800 Subject: [PATCH 335/790] wifi: Added 2 seconds wait time in RTT tests Added 2 seconds delay in RTT tests. This helps drivers finish the current test and process the next test. Bug: 175605811 Test: VTS test - VtsHalWifiRttV1_4TargetTest Change-Id: I3bb719b5b75ba960913bd405b2c8a41047689682 --- wifi/1.4/vts/functional/wifi_rtt_controller_hidl_test.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/wifi/1.4/vts/functional/wifi_rtt_controller_hidl_test.cpp b/wifi/1.4/vts/functional/wifi_rtt_controller_hidl_test.cpp index 3977cdd857..72cde3ca71 100644 --- a/wifi/1.4/vts/functional/wifi_rtt_controller_hidl_test.cpp +++ b/wifi/1.4/vts/functional/wifi_rtt_controller_hidl_test.cpp @@ -191,6 +191,8 @@ TEST_P(WifiRttControllerHidlTest, Request2SidedRangeMeasurement) { const auto& status = HIDL_INVOKE(wifi_rtt_controller_, rangeRequest_1_4, cmdId, configs); EXPECT_EQ(WifiStatusCode::SUCCESS, status.code); + // sleep for 2 seconds to wait for driver/firmware to complete RTT + sleep(2); } /* * rangeRequest_1_4 @@ -242,6 +244,8 @@ TEST_P(WifiRttControllerHidlTest, RangeRequest_1_4) { const auto& status = HIDL_INVOKE(wifi_rtt_controller_, rangeRequest_1_4, cmdId, configs); EXPECT_EQ(WifiStatusCode::SUCCESS, status.code); + // sleep for 2 seconds to wait for driver/firmware to complete RTT + sleep(2); } /* -- GitLab From 26cd156744c17d1b5c3a8eec22e2a1778a2246cb Mon Sep 17 00:00:00 2001 From: Quang Luong Date: Fri, 11 Dec 2020 18:42:10 -0800 Subject: [PATCH 336/790] Add VTS test for IWifiChip::setCoexUnsafeChannels Bug: 153651001 Test: atest VtsHalWifiV1_5TargetTest Change-Id: Iaffbff3cf68b00572674ca423587387ef6569302 --- .../vts/functional/wifi_chip_hidl_test.cpp | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/wifi/1.5/vts/functional/wifi_chip_hidl_test.cpp b/wifi/1.5/vts/functional/wifi_chip_hidl_test.cpp index eeaa7e0d38..a0657218f4 100644 --- a/wifi/1.5/vts/functional/wifi_chip_hidl_test.cpp +++ b/wifi/1.5/vts/functional/wifi_chip_hidl_test.cpp @@ -44,6 +44,7 @@ using ::android::hardware::wifi::V1_0::WifiStatus; using ::android::hardware::wifi::V1_0::WifiStatusCode; using ::android::hardware::wifi::V1_4::IWifiChipEventCallback; using ::android::hardware::wifi::V1_5::IWifiChip; +using ::android::hardware::wifi::V1_5::WifiBand; /** * Fixture to use for all Wifi chip HIDL interface tests. @@ -141,6 +142,37 @@ TEST_P(WifiChipHidlTest, setMultiStaUseCase) { } } +/* + * setCoexUnsafeChannels + */ +TEST_P(WifiChipHidlTest, setCoexUnsafeChannels) { + // Test with empty vector of CoexUnsafeChannels + std::vector vec; + const auto& statusEmpty = + HIDL_INVOKE(wifi_chip_, setCoexUnsafeChannels, vec, 0); + if (statusEmpty.code != WifiStatusCode::SUCCESS) { + EXPECT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED, statusEmpty.code); + } + + // Test with non-empty vector of CoexUnsafeChannels + IWifiChip::CoexUnsafeChannel unsafeChannel24Ghz; + unsafeChannel24Ghz.band = WifiBand::BAND_24GHZ; + unsafeChannel24Ghz.channel = 6; + vec.push_back(unsafeChannel24Ghz); + IWifiChip::CoexUnsafeChannel unsafeChannel5Ghz; + unsafeChannel5Ghz.band = WifiBand::BAND_5GHZ; + unsafeChannel5Ghz.channel = 36; + vec.push_back(unsafeChannel5Ghz); + uint32_t restrictions = IWifiChip::CoexRestriction::WIFI_AWARE | + IWifiChip::CoexRestriction::SOFTAP | + IWifiChip::CoexRestriction::WIFI_DIRECT; + const auto& statusNonEmpty = + HIDL_INVOKE(wifi_chip_, setCoexUnsafeChannels, vec, restrictions); + if (statusNonEmpty.code != WifiStatusCode::SUCCESS) { + EXPECT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED, statusNonEmpty.code); + } +} + GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiChipHidlTest); INSTANTIATE_TEST_SUITE_P( PerInstance, WifiChipHidlTest, -- GitLab From e84d9bb2ce4c8b3fe472c4f8ce980fd2c8a74b8e Mon Sep 17 00:00:00 2001 From: Kalesh Singh Date: Wed, 16 Dec 2020 00:19:38 +0000 Subject: [PATCH 337/790] Revert "Memtrack HAL: Add stable AIDL implementation" Revert "libmemtrack: Add support for AIDL memtrack HAL" Revert "Add stable aidl memtrack HAL to product packages" Revert "Add stable aidl memtrack hal to vndk list" Revert "Memtrack HAL stable aidl sepolicy" Revert "Add android.hardware.memtrack-unstable-ndk_platform" Revert submission 1518702-memtrack-aidl Reason for revert: Broken tests and boot time regressions Reverted Changes: Ic4dd70e2c:Add android.hardware.memtrack-unstable-ndk_platfor... Iaf99d0ca4:Add stable aidl memtrack HAL to product packages Iac54ae2ba:Add stable aidl memtrack hal to vndk list If310210a3:libmemtrack: Add support for AIDL memtrack HAL Ib6c634def:Memtrack HAL: Add stable AIDL implementation I5e1d0e006:Memtrack HAL stable aidl sepolicy Change-Id: I4a9e3522afe9e9189b7eddc9520d5ef2e2b74520 (cherry picked from commit 28641ffb0859b1198572d79670181c9852ad0e3a) --- .../compatibility_matrix.current.xml | 7 -- memtrack/aidl/Android.bp | 33 ------- .../android/hardware/memtrack/DeviceInfo.aidl | 23 ----- .../android/hardware/memtrack/IMemtrack.aidl | 23 ----- .../hardware/memtrack/MemtrackRecord.aidl | 32 ------- .../hardware/memtrack/MemtrackType.aidl | 27 ------ .../android/hardware/memtrack/DeviceInfo.aidl | 29 ------ .../android/hardware/memtrack/IMemtrack.aidl | 82 ----------------- .../hardware/memtrack/MemtrackRecord.aidl | 43 --------- .../hardware/memtrack/MemtrackType.aidl | 31 ------- memtrack/aidl/default/Android.bp | 30 ------- memtrack/aidl/default/Memtrack.cpp | 44 --------- memtrack/aidl/default/Memtrack.h | 39 -------- memtrack/aidl/default/main.cpp | 36 -------- memtrack/aidl/default/memtrack-default.rc | 4 - memtrack/aidl/default/memtrack-default.xml | 7 -- memtrack/aidl/vts/Android.bp | 17 ---- .../aidl/vts/VtsHalMemtrackTargetTest.cpp | 90 ------------------- 18 files changed, 597 deletions(-) delete mode 100644 memtrack/aidl/Android.bp delete mode 100644 memtrack/aidl/aidl_api/android.hardware.memtrack/current/android/hardware/memtrack/DeviceInfo.aidl delete mode 100644 memtrack/aidl/aidl_api/android.hardware.memtrack/current/android/hardware/memtrack/IMemtrack.aidl delete mode 100644 memtrack/aidl/aidl_api/android.hardware.memtrack/current/android/hardware/memtrack/MemtrackRecord.aidl delete mode 100644 memtrack/aidl/aidl_api/android.hardware.memtrack/current/android/hardware/memtrack/MemtrackType.aidl delete mode 100644 memtrack/aidl/android/hardware/memtrack/DeviceInfo.aidl delete mode 100644 memtrack/aidl/android/hardware/memtrack/IMemtrack.aidl delete mode 100644 memtrack/aidl/android/hardware/memtrack/MemtrackRecord.aidl delete mode 100644 memtrack/aidl/android/hardware/memtrack/MemtrackType.aidl delete mode 100644 memtrack/aidl/default/Android.bp delete mode 100644 memtrack/aidl/default/Memtrack.cpp delete mode 100644 memtrack/aidl/default/Memtrack.h delete mode 100644 memtrack/aidl/default/main.cpp delete mode 100644 memtrack/aidl/default/memtrack-default.rc delete mode 100644 memtrack/aidl/default/memtrack-default.xml delete mode 100644 memtrack/aidl/vts/Android.bp delete mode 100644 memtrack/aidl/vts/VtsHalMemtrackTargetTest.cpp diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index e12d92081d..b16ae400e7 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -354,13 +354,6 @@ default - - android.hardware.memtrack - - IMemtrack - default - - android.hardware.memtrack 1.0 diff --git a/memtrack/aidl/Android.bp b/memtrack/aidl/Android.bp deleted file mode 100644 index fe4d01bad1..0000000000 --- a/memtrack/aidl/Android.bp +++ /dev/null @@ -1,33 +0,0 @@ -// 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. - -aidl_interface { - name: "android.hardware.memtrack", - vendor_available: true, - srcs: ["android/hardware/memtrack/*.aidl"], - stability: "vintf", - backend: { - cpp: { - enabled: false, - }, - java: { - enabled: false, - }, - ndk: { - vndk: { - enabled: true, - }, - }, - }, -} diff --git a/memtrack/aidl/aidl_api/android.hardware.memtrack/current/android/hardware/memtrack/DeviceInfo.aidl b/memtrack/aidl/aidl_api/android.hardware.memtrack/current/android/hardware/memtrack/DeviceInfo.aidl deleted file mode 100644 index 00abff9edc..0000000000 --- a/memtrack/aidl/aidl_api/android.hardware.memtrack/current/android/hardware/memtrack/DeviceInfo.aidl +++ /dev/null @@ -1,23 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // -/////////////////////////////////////////////////////////////////////////////// - -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. -// -// You must not make a backward incompatible changes to the AIDL files 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.memtrack; -@VintfStability -parcelable DeviceInfo { - int id; - @utf8InCpp String name; -} diff --git a/memtrack/aidl/aidl_api/android.hardware.memtrack/current/android/hardware/memtrack/IMemtrack.aidl b/memtrack/aidl/aidl_api/android.hardware.memtrack/current/android/hardware/memtrack/IMemtrack.aidl deleted file mode 100644 index 844a1bb3d4..0000000000 --- a/memtrack/aidl/aidl_api/android.hardware.memtrack/current/android/hardware/memtrack/IMemtrack.aidl +++ /dev/null @@ -1,23 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // -/////////////////////////////////////////////////////////////////////////////// - -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. -// -// You must not make a backward incompatible changes to the AIDL files 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.memtrack; -@VintfStability -interface IMemtrack { - android.hardware.memtrack.MemtrackRecord[] getMemory(in int pid, in android.hardware.memtrack.MemtrackType type); - android.hardware.memtrack.DeviceInfo[] getGpuDeviceInfo(); -} diff --git a/memtrack/aidl/aidl_api/android.hardware.memtrack/current/android/hardware/memtrack/MemtrackRecord.aidl b/memtrack/aidl/aidl_api/android.hardware.memtrack/current/android/hardware/memtrack/MemtrackRecord.aidl deleted file mode 100644 index 09ecefc6c4..0000000000 --- a/memtrack/aidl/aidl_api/android.hardware.memtrack/current/android/hardware/memtrack/MemtrackRecord.aidl +++ /dev/null @@ -1,32 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // -/////////////////////////////////////////////////////////////////////////////// - -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. -// -// You must not make a backward incompatible changes to the AIDL files 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.memtrack; -@VintfStability -parcelable MemtrackRecord { - int flags; - long sizeInBytes; - const int FLAG_SMAPS_ACCOUNTED = 2; - const int FLAG_SMAPS_UNACCOUNTED = 4; - const int FLAG_SHARED = 8; - const int FLAG_SHARED_PSS = 16; - const int FLAG_PRIVATE = 32; - const int FLAG_SYSTEM = 64; - const int FLAG_DEDICATED = 128; - const int FLAG_NONSECURE = 256; - const int FLAG_SECURE = 512; -} diff --git a/memtrack/aidl/aidl_api/android.hardware.memtrack/current/android/hardware/memtrack/MemtrackType.aidl b/memtrack/aidl/aidl_api/android.hardware.memtrack/current/android/hardware/memtrack/MemtrackType.aidl deleted file mode 100644 index 7f3f93904f..0000000000 --- a/memtrack/aidl/aidl_api/android.hardware.memtrack/current/android/hardware/memtrack/MemtrackType.aidl +++ /dev/null @@ -1,27 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // -/////////////////////////////////////////////////////////////////////////////// - -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. -// -// You must not make a backward incompatible changes to the AIDL files 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.memtrack; -@Backing(type="int") @VintfStability -enum MemtrackType { - OTHER = 0, - GL = 1, - GRAPHICS = 2, - MULTIMEDIA = 3, - CAMERA = 4, - NUM_TYPES = 5, -} diff --git a/memtrack/aidl/android/hardware/memtrack/DeviceInfo.aidl b/memtrack/aidl/android/hardware/memtrack/DeviceInfo.aidl deleted file mode 100644 index aec11e988b..0000000000 --- a/memtrack/aidl/android/hardware/memtrack/DeviceInfo.aidl +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.hardware.memtrack; - -/* - * A vector of DeviceInfo is returned by the function getGpuDeviceInfo(). - * Each entry consists of the device name and the device id. - * See getGpuDeviceInfo() for further details. - */ -@VintfStability -parcelable DeviceInfo { - int id; - @utf8InCpp String name; -} - diff --git a/memtrack/aidl/android/hardware/memtrack/IMemtrack.aidl b/memtrack/aidl/android/hardware/memtrack/IMemtrack.aidl deleted file mode 100644 index 33c6956d8c..0000000000 --- a/memtrack/aidl/android/hardware/memtrack/IMemtrack.aidl +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.hardware.memtrack; - -import android.hardware.memtrack.DeviceInfo; -import android.hardware.memtrack.MemtrackRecord; -import android.hardware.memtrack.MemtrackType; - -/** - * The Memory Tracker HAL is designed to return information about - * device-specific memory usage. - * The primary goal is to be able to track memory that is not - * trackable in any other way, for example texture memory that is allocated by - * a process, but not mapped in to that process's address space. - * A secondary goal is to be able to categorize memory used by a process into - * GL, graphics, etc. All memory sizes must be in real memory usage, - * accounting for stride, bit depth, rounding up to page size, etc. - * - * Constructor for the interface should be used to perform memtrack management - * setup actions and is called once before any calls to getMemory(). - */ -@VintfStability -interface IMemtrack { - /** - * getMemory() populates MemtrackRecord vector with the sizes of memory - * plus associated flags for that memory. - * - * A process collecting memory statistics will call getMemory for each - * combination of pid and memory type. For each memory type that it - * recognizes, the HAL must fill out an array of memtrack_record - * structures breaking down the statistics of that memory type as much as - * possible. For example, - * getMemory(, GL) might return: - * { { 4096, ACCOUNTED | PRIVATE | SYSTEM }, - * { 40960, UNACCOUNTED | PRIVATE | SYSTEM }, - * { 8192, ACCOUNTED | PRIVATE | DEDICATED }, - * { 8192, UNACCOUNTED | PRIVATE | DEDICATED } } - * If the HAL cannot differentiate between SYSTEM and DEDICATED memory, it - * could return: - * { { 12288, ACCOUNTED | PRIVATE }, - * { 49152, UNACCOUNTED | PRIVATE } } - * - * Memory must not overlap between types. For example, a graphics buffer - * that has been mapped into the GPU as a surface must show up when - * GRAPHICS is requested and not when GL - * is requested. - * - * @param pid process for which memory information is requested - * @param type memory type that information is being requested about - * @return vector of MemtrackRecord containing memory information - */ - MemtrackRecord[] getMemory(in int pid, in MemtrackType type); - - /** - * getGpuDeviceInfo() populates DeviceInfo with the ID and name - * of each GPU device. - * - * For example, getGpuDeviceInfor, might return: - * { { 0, }, - * { 1, } } - * - * This information is used to identify GPU devices for GPU specific - * memory accounting (e.g. DMA buffer usage). - * - * @return vector of DeviceInfo populated for all GPU devices. - */ - DeviceInfo[] getGpuDeviceInfo(); -} diff --git a/memtrack/aidl/android/hardware/memtrack/MemtrackRecord.aidl b/memtrack/aidl/android/hardware/memtrack/MemtrackRecord.aidl deleted file mode 100644 index 95254e9399..0000000000 --- a/memtrack/aidl/android/hardware/memtrack/MemtrackRecord.aidl +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.hardware.memtrack; - -/* - * A vector of MemtrackRecord is returned by the function getMemory(). - * Each record consists of the size of the memory used by the process and - * flags indicate all the MemtrackFlags that are valid for this record. - * see getMemory() comments for further details. - */ -@VintfStability -parcelable MemtrackRecord { - /* Memtrack Flags */ - const int FLAG_SMAPS_ACCOUNTED = 1 << 1; - const int FLAG_SMAPS_UNACCOUNTED = 1 << 2; - const int FLAG_SHARED = 1 << 3; - const int FLAG_SHARED_PSS = 1 << 4; - const int FLAG_PRIVATE = 1 << 5; - const int FLAG_SYSTEM = 1 << 6; - const int FLAG_DEDICATED = 1 << 7; - const int FLAG_NONSECURE = 1 << 8; - const int FLAG_SECURE = 1 << 9; - - /* Bitfield indicating all flags that are valid for this record */ - int flags; - - long sizeInBytes; -} - diff --git a/memtrack/aidl/android/hardware/memtrack/MemtrackType.aidl b/memtrack/aidl/android/hardware/memtrack/MemtrackType.aidl deleted file mode 100644 index 715c6bff43..0000000000 --- a/memtrack/aidl/android/hardware/memtrack/MemtrackType.aidl +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.hardware.memtrack; - -/** - * Tags which define the usage of the memory buffers. - */ -@VintfStability -@Backing(type="int") -enum MemtrackType { - OTHER = 0, - GL = 1, - GRAPHICS = 2, - MULTIMEDIA = 3, - CAMERA = 4, - NUM_TYPES, -} diff --git a/memtrack/aidl/default/Android.bp b/memtrack/aidl/default/Android.bp deleted file mode 100644 index 52f88c8097..0000000000 --- a/memtrack/aidl/default/Android.bp +++ /dev/null @@ -1,30 +0,0 @@ -// 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. - -cc_binary { - name: "android.hardware.memtrack-service.example", - relative_install_path: "hw", - init_rc: ["memtrack-default.rc"], - vintf_fragments: ["memtrack-default.xml"], - vendor: true, - shared_libs: [ - "libbase", - "libbinder_ndk", - "android.hardware.memtrack-ndk_platform", - ], - srcs: [ - "main.cpp", - "Memtrack.cpp", - ], -} diff --git a/memtrack/aidl/default/Memtrack.cpp b/memtrack/aidl/default/Memtrack.cpp deleted file mode 100644 index 7361719002..0000000000 --- a/memtrack/aidl/default/Memtrack.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "Memtrack.h" - -namespace aidl { -namespace android { -namespace hardware { -namespace memtrack { - -ndk::ScopedAStatus Memtrack::getMemory(int pid, MemtrackType type, - std::vector* _aidl_return) { - if (pid < 0) { - return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT)); - } - if (type < MemtrackType::OTHER || type >= MemtrackType::NUM_TYPES) { - return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION)); - } - _aidl_return->clear(); - return ndk::ScopedAStatus::ok(); -} - -ndk::ScopedAStatus Memtrack::getGpuDeviceInfo(std::vector* _aidl_return) { - _aidl_return->clear(); - return ndk::ScopedAStatus::ok(); -} - -} // namespace memtrack -} // namespace hardware -} // namespace android -} // namespace aidl diff --git a/memtrack/aidl/default/Memtrack.h b/memtrack/aidl/default/Memtrack.h deleted file mode 100644 index f2ef60e005..0000000000 --- a/memtrack/aidl/default/Memtrack.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include -#include -#include -#include - -namespace aidl { -namespace android { -namespace hardware { -namespace memtrack { - -class Memtrack : public BnMemtrack { - ndk::ScopedAStatus getMemory(int pid, MemtrackType type, - std::vector* _aidl_return) override; - - ndk::ScopedAStatus getGpuDeviceInfo(std::vector* _aidl_return) override; -}; - -} // namespace memtrack -} // namespace hardware -} // namespace android -} // namespace aidl diff --git a/memtrack/aidl/default/main.cpp b/memtrack/aidl/default/main.cpp deleted file mode 100644 index d063d2aeda..0000000000 --- a/memtrack/aidl/default/main.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "Memtrack.h" - -#include -#include -#include - -using aidl::android::hardware::memtrack::Memtrack; - -int main() { - ABinderProcess_setThreadPoolMaxThreadCount(0); - std::shared_ptr memtrack = ndk::SharedRefBase::make(); - - const std::string instance = std::string() + Memtrack::descriptor + "/default"; - binder_status_t status = - AServiceManager_addService(memtrack->asBinder().get(), instance.c_str()); - CHECK(status == STATUS_OK); - - ABinderProcess_joinThreadPool(); - return EXIT_FAILURE; // Unreachable -} diff --git a/memtrack/aidl/default/memtrack-default.rc b/memtrack/aidl/default/memtrack-default.rc deleted file mode 100644 index 1725cd00f7..0000000000 --- a/memtrack/aidl/default/memtrack-default.rc +++ /dev/null @@ -1,4 +0,0 @@ -service vendor.memtrack-default /vendor/bin/hw/android.hardware.memtrack-service.example - class hal - user nobody - group system diff --git a/memtrack/aidl/default/memtrack-default.xml b/memtrack/aidl/default/memtrack-default.xml deleted file mode 100644 index 3e3e0f6c1c..0000000000 --- a/memtrack/aidl/default/memtrack-default.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - android.hardware.memtrack - IMemtrack/default - - - diff --git a/memtrack/aidl/vts/Android.bp b/memtrack/aidl/vts/Android.bp deleted file mode 100644 index ea36677237..0000000000 --- a/memtrack/aidl/vts/Android.bp +++ /dev/null @@ -1,17 +0,0 @@ -cc_test { - name: "VtsHalMemtrackTargetTest", - defaults: [ - "VtsHalTargetTestDefaults", - "use_libaidlvintf_gtest_helper_static", - ], - srcs: ["VtsHalMemtrackTargetTest.cpp"], - shared_libs: [ - "libbinder_ndk", - ], - static_libs: [ - "android.hardware.memtrack-unstable-ndk_platform", - ], - test_suites: [ - "vts-core", - ], -} diff --git a/memtrack/aidl/vts/VtsHalMemtrackTargetTest.cpp b/memtrack/aidl/vts/VtsHalMemtrackTargetTest.cpp deleted file mode 100644 index a3bd29318d..0000000000 --- a/memtrack/aidl/vts/VtsHalMemtrackTargetTest.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include -#include - -#include -#include -#include -#include -#include - -using aidl::android::hardware::memtrack::DeviceInfo; -using aidl::android::hardware::memtrack::IMemtrack; -using aidl::android::hardware::memtrack::MemtrackRecord; -using aidl::android::hardware::memtrack::MemtrackType; - -class MemtrackAidlTest : public testing::TestWithParam { - public: - virtual void SetUp() override { - const auto instance = std::string() + IMemtrack::descriptor + "/default"; - auto memtrackBinder = ndk::SpAIBinder(AServiceManager_getService(instance.c_str())); - memtrack_ = IMemtrack::fromBinder(memtrackBinder); - ASSERT_NE(memtrack_, nullptr); - } - - std::shared_ptr memtrack_; -}; - -TEST_P(MemtrackAidlTest, GetMemoryInvalidPid) { - int pid = -1; - MemtrackType type = MemtrackType::OTHER; - std::vector records; - - auto status = memtrack_->getMemory(pid, type, &records); - - EXPECT_EQ(status.getExceptionCode(), EX_ILLEGAL_ARGUMENT); -} - -TEST_P(MemtrackAidlTest, GetMemoryInvalidType) { - int pid = 1; - MemtrackType type = MemtrackType::NUM_TYPES; - std::vector records; - - auto status = memtrack_->getMemory(pid, type, &records); - - EXPECT_EQ(status.getExceptionCode(), EX_UNSUPPORTED_OPERATION); -} - -TEST_P(MemtrackAidlTest, GetMemory) { - int pid = 1; - MemtrackType type = MemtrackType::OTHER; - std::vector records; - - auto status = memtrack_->getMemory(pid, type, &records); - - EXPECT_TRUE(status.isOk()); -} - -TEST_P(MemtrackAidlTest, GetGpuDeviceInfo) { - std::vector device_info; - - auto status = memtrack_->getGpuDeviceInfo(&device_info); - - EXPECT_TRUE(status.isOk()); -} - -GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MemtrackAidlTest); -INSTANTIATE_TEST_SUITE_P(PerInstance, MemtrackAidlTest, - testing::ValuesIn(android::getAidlHalInstanceNames(IMemtrack::descriptor)), - android::PrintInstanceNameToString); - -int main(int argc, char** argv) { - ::testing::InitGoogleTest(&argc, argv); - ABinderProcess_setThreadPoolMaxThreadCount(1); - ABinderProcess_startThreadPool(); - return RUN_ALL_TESTS(); -} -- GitLab From b8e5cd08bdcb1f5aa5e8c430e1456ff9e1414adb Mon Sep 17 00:00:00 2001 From: Oscar Azucena Date: Wed, 16 Dec 2020 13:53:14 -0800 Subject: [PATCH 338/790] Added IAudioControl#onDevicesToMuteChange Added new API and parceable for informing the HAL when to mute and unmute audio for automotive targets. Also added default implementation to log information passed on. Bug: 173141906 Test: atest VtsAidlHalAudioControlTest Change-Id: I4c20320d33417616eef7a980a375ab9303b43eab --- .../audiocontrol/IAudioControl.aidl | 1 + .../automotive/audiocontrol/MutingInfo.aidl | 24 ++++++++++ .../audiocontrol/IAudioControl.aidl | 13 ++++++ .../automotive/audiocontrol/MutingInfo.aidl | 46 +++++++++++++++++++ .../aidl/default/AudioControl.cpp | 23 ++++++++-- .../audiocontrol/aidl/default/AudioControl.h | 3 ++ .../aidl/vts/VtsHalAudioControlTargetTest.cpp | 13 ++++++ 7 files changed, 120 insertions(+), 3 deletions(-) create mode 100644 automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/MutingInfo.aidl create mode 100644 automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/MutingInfo.aidl diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IAudioControl.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IAudioControl.aidl index e5a0451618..bc4162bc8b 100644 --- a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IAudioControl.aidl +++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IAudioControl.aidl @@ -20,6 +20,7 @@ package android.hardware.automotive.audiocontrol; interface IAudioControl { oneway void onAudioFocusChange(in String usage, in int zoneId, in android.hardware.automotive.audiocontrol.AudioFocusChange focusChange); oneway void onDevicesToDuckChange(in android.hardware.automotive.audiocontrol.DuckingInfo[] duckingInfos); + oneway void onDevicesToMuteChange(in android.hardware.automotive.audiocontrol.MutingInfo[] mutingInfos); oneway void registerFocusListener(in android.hardware.automotive.audiocontrol.IFocusListener listener); oneway void setBalanceTowardRight(in float value); oneway void setFadeTowardFront(in float value); diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/MutingInfo.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/MutingInfo.aidl new file mode 100644 index 0000000000..ab902ec971 --- /dev/null +++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/MutingInfo.aidl @@ -0,0 +1,24 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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.automotive.audiocontrol; +@VintfStability +parcelable MutingInfo { + int zoneId; + String[] deviceAddressesToMute; + String[] deviceAddressesToUnmute; +} diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IAudioControl.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IAudioControl.aidl index 4b03af11a4..3a0224557f 100644 --- a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IAudioControl.aidl +++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IAudioControl.aidl @@ -18,6 +18,7 @@ package android.hardware.automotive.audiocontrol; import android.hardware.automotive.audiocontrol.AudioFocusChange; import android.hardware.automotive.audiocontrol.DuckingInfo; +import android.hardware.automotive.audiocontrol.MutingInfo; import android.hardware.automotive.audiocontrol.IFocusListener; /** @@ -53,6 +54,18 @@ interface IAudioControl { */ oneway void onDevicesToDuckChange(in DuckingInfo[] duckingInfos); + /** + * Notifies HAL of changes in output devices that the HAL should apply muting to. + * + * This will be called in response to changes in audio mute state for each volume group + * and will include a {@link MutingInfo} object per audio zone that experienced a mute state + * event. + * + * @param mutingInfos an array of {@link MutingInfo} objects for the audio zones where audio + * mute state has changed. + */ + oneway void onDevicesToMuteChange(in MutingInfo[] mutingInfos); + /** * Registers focus listener to be used by HAL for requesting and abandoning audio focus. * diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/MutingInfo.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/MutingInfo.aidl new file mode 100644 index 0000000000..783640fcfe --- /dev/null +++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/MutingInfo.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. + */ + + package android.hardware.automotive.audiocontrol; + + /** + * The current muting information for a single audio zone. + * + *

    This includes devices to mute, as well as mute based on the contents of a previous + * {@link MutingInfo}. + */ + @VintfStability + parcelable MutingInfo { + /** + * ID of the associated audio zone + */ + int zoneId; + + /** + * List of addresses for audio output devices that should be muted. + * + *

    The provided address strings are defined in audio_policy_configuration.xml. + */ + String[] deviceAddressesToMute; + + /** + * List of addresses for audio output devices that were previously be muted and should now be + * unmuted. + * + *

    The provided address strings are defined in audio_policy_configuration.xml. + */ + String[] deviceAddressesToUnmute; + } \ No newline at end of file diff --git a/automotive/audiocontrol/aidl/default/AudioControl.cpp b/automotive/audiocontrol/aidl/default/AudioControl.cpp index 748947cb2e..b076d01282 100644 --- a/automotive/audiocontrol/aidl/default/AudioControl.cpp +++ b/automotive/audiocontrol/aidl/default/AudioControl.cpp @@ -109,21 +109,38 @@ ndk::ScopedAStatus AudioControl::onDevicesToDuckChange( for (const DuckingInfo& duckingInfo : in_duckingInfos) { LOG(INFO) << "zone: " << duckingInfo.zoneId; LOG(INFO) << "Devices to duck:"; - for (auto& addressToDuck : duckingInfo.deviceAddressesToDuck) { + for (const auto& addressToDuck : duckingInfo.deviceAddressesToDuck) { LOG(INFO) << addressToDuck; } LOG(INFO) << "Devices to unduck:"; - for (auto& addressToUnduck : duckingInfo.deviceAddressesToUnduck) { + for (const auto& addressToUnduck : duckingInfo.deviceAddressesToUnduck) { LOG(INFO) << addressToUnduck; } LOG(INFO) << "Usages holding focus:"; - for (auto& usage : duckingInfo.usagesHoldingFocus) { + for (const auto& usage : duckingInfo.usagesHoldingFocus) { LOG(INFO) << usage; } } return ndk::ScopedAStatus::ok(); } +ndk::ScopedAStatus AudioControl::onDevicesToMuteChange( + const std::vector& in_mutingInfos) { + LOG(INFO) << "AudioControl::onDevicesToMuteChange"; + for (const MutingInfo& mutingInfo : in_mutingInfos) { + LOG(INFO) << "zone: " << mutingInfo.zoneId; + LOG(INFO) << "Devices to mute:"; + for (const auto& addressToMute : mutingInfo.deviceAddressesToMute) { + LOG(INFO) << addressToMute; + } + LOG(INFO) << "Devices to unmute:"; + for (const auto& addressToUnmute : mutingInfo.deviceAddressesToUnmute) { + LOG(INFO) << addressToUnmute; + } + } + return ndk::ScopedAStatus::ok(); +} + binder_status_t AudioControl::dump(int fd, const char** args, uint32_t numArgs) { if (numArgs == 0) { return dumpsys(fd); diff --git a/automotive/audiocontrol/aidl/default/AudioControl.h b/automotive/audiocontrol/aidl/default/AudioControl.h index cf5694762d..ab0b1b3051 100644 --- a/automotive/audiocontrol/aidl/default/AudioControl.h +++ b/automotive/audiocontrol/aidl/default/AudioControl.h @@ -19,6 +19,7 @@ #include #include #include +#include namespace aidl::android::hardware::automotive::audiocontrol { @@ -30,6 +31,8 @@ class AudioControl : public BnAudioControl { AudioFocusChange in_focusChange) override; ndk::ScopedAStatus onDevicesToDuckChange( const std::vector& in_duckingInfos) override; + ndk::ScopedAStatus onDevicesToMuteChange( + const std::vector& in_mutingInfos) override; ndk::ScopedAStatus registerFocusListener( const shared_ptr& in_listener) override; ndk::ScopedAStatus setBalanceTowardRight(float in_value) override; diff --git a/automotive/audiocontrol/aidl/vts/VtsHalAudioControlTargetTest.cpp b/automotive/audiocontrol/aidl/vts/VtsHalAudioControlTargetTest.cpp index f23280d1c9..ae53c68528 100644 --- a/automotive/audiocontrol/aidl/vts/VtsHalAudioControlTargetTest.cpp +++ b/automotive/audiocontrol/aidl/vts/VtsHalAudioControlTargetTest.cpp @@ -33,6 +33,7 @@ using android::hardware::automotive::audiocontrol::AudioFocusChange; using android::hardware::automotive::audiocontrol::BnFocusListener; using android::hardware::automotive::audiocontrol::DuckingInfo; using android::hardware::automotive::audiocontrol::IAudioControl; +using android::hardware::automotive::audiocontrol::MutingInfo; #include "android_audio_policy_configuration_V7_0.h" @@ -130,6 +131,18 @@ TEST_P(AudioControlAidl, FocusChangeExercise) { audioControl->onAudioFocusChange(usage, 0, AudioFocusChange::GAIN_TRANSIENT).isOk()); }; +TEST_P(AudioControlAidl, MuteChangeExercise) { + ALOGI("Mute change test"); + + MutingInfo mutingInfo; + mutingInfo.zoneId = 0; + mutingInfo.deviceAddressesToMute = {String16("address 1"), String16("address 2")}; + mutingInfo.deviceAddressesToUnmute = {String16("address 3"), String16("address 4")}; + std::vector mutingInfos = {mutingInfo}; + ALOGI("Mute change test start"); + ASSERT_TRUE(audioControl->onDevicesToMuteChange(mutingInfos).isOk()); +} + TEST_P(AudioControlAidl, DuckChangeExercise) { ALOGI("Duck change test"); -- GitLab From 98ed9baf5de85599847b2b2f53585243c3b7b776 Mon Sep 17 00:00:00 2001 From: Michael Butler Date: Sun, 6 Dec 2020 21:50:59 -0800 Subject: [PATCH 339/790] Cleanup NN callback error handling This CL introduces a new templated class CallbackValue to handle HIDL "return value" callbacks in a terser and more readable way. This CL also introduces a new macro HANDLE_HAL_STATUS to return from the current function when an error is present with the ability to append a more descriptive error message. Finally, this CL changes the behavior of synchronous executions. Prior to this CL, IPreparedModel fell back to an asynchronous execution if the synchronous execution was allowed and failed. This change instead returns a failure if synchronous execution is allowed and fails. Bug: 173084343 Test: mma Change-Id: I62714a932e71dfc77401bbcb9eaaaf3d94fb9707 --- .../utils/include/nnapi/hal/1.0/Callbacks.h | 25 ++- neuralnetworks/1.0/utils/src/Callbacks.cpp | 50 +++--- neuralnetworks/1.0/utils/src/Device.cpp | 48 ++---- .../1.0/utils/src/PreparedModel.cpp | 8 +- .../utils/include/nnapi/hal/1.1/Conversions.h | 4 + neuralnetworks/1.1/utils/src/Conversions.cpp | 12 ++ neuralnetworks/1.1/utils/src/Device.cpp | 48 ++---- .../utils/include/nnapi/hal/1.2/Callbacks.h | 18 +- .../utils/include/nnapi/hal/1.2/Conversions.h | 6 + .../1.2/utils/include/nnapi/hal/1.2/Device.h | 19 +- .../include/nnapi/hal/1.2/PreparedModel.h | 7 +- .../1.2/utils/include/nnapi/hal/1.2/Utils.h | 2 + neuralnetworks/1.2/utils/src/Callbacks.cpp | 78 +++------ neuralnetworks/1.2/utils/src/Conversions.cpp | 18 ++ neuralnetworks/1.2/utils/src/Device.cpp | 163 +++++++----------- .../1.2/utils/src/PreparedModel.cpp | 78 +++------ .../utils/include/nnapi/hal/1.3/Callbacks.h | 25 ++- .../utils/include/nnapi/hal/1.3/Conversions.h | 11 ++ .../include/nnapi/hal/1.3/PreparedModel.h | 7 +- neuralnetworks/1.3/utils/src/Buffer.cpp | 16 +- neuralnetworks/1.3/utils/src/Callbacks.cpp | 106 ++++-------- neuralnetworks/1.3/utils/src/Conversions.cpp | 34 ++++ neuralnetworks/1.3/utils/src/Device.cpp | 100 ++++------- .../1.3/utils/src/PreparedModel.cpp | 121 ++++--------- .../common/include/nnapi/hal/CommonUtils.h | 11 +- .../common/include/nnapi/hal/HandleError.h | 7 + .../common/include/nnapi/hal/TransferValue.h | 62 ++++++- 27 files changed, 507 insertions(+), 577 deletions(-) diff --git a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Callbacks.h b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Callbacks.h index 2e00fcecf3..3b32e1dbf9 100644 --- a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Callbacks.h +++ b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Callbacks.h @@ -32,6 +32,26 @@ namespace android::hardware::neuralnetworks::V1_0::utils { +// Converts the results of IDevice::getSupportedOperations* to the NN canonical format. On success, +// this function returns with the supported operations as indicated by a driver. On failure, this +// function returns with the appropriate nn::GeneralError. +nn::GeneralResult> supportedOperationsCallback( + ErrorStatus status, const hidl_vec& supportedOperations); + +// Converts the results of IDevice::prepareModel* to the NN canonical format. On success, this +// function returns with a non-null nn::SharedPreparedModel with a feature level of +// nn::Version::ANDROID_OC_MR1. On failure, this function returns with the appropriate +// nn::GeneralError. +nn::GeneralResult prepareModelCallback( + ErrorStatus status, const sp& preparedModel); + +// Converts the results of IDevice::execute* to the NN canonical format. On success, this function +// returns with an empty output shape vector and no timing information. On failure, this function +// returns with the appropriate nn::ExecutionError. +nn::ExecutionResult, nn::Timing>> executionCallback( + ErrorStatus status); + +// A HIDL callback class to receive the results of IDevice::prepareModel asynchronously. class PreparedModelCallback final : public IPreparedModelCallback, public hal::utils::IProtectedCallback { public: @@ -44,11 +64,10 @@ class PreparedModelCallback final : public IPreparedModelCallback, Data get(); private: - void notifyInternal(Data result); - hal::utils::TransferValue mData; }; +// A HIDL callback class to receive the results of IDevice::execute asynchronously. class ExecutionCallback final : public IExecutionCallback, public hal::utils::IProtectedCallback { public: using Data = nn::ExecutionResult, nn::Timing>>; @@ -60,8 +79,6 @@ class ExecutionCallback final : public IExecutionCallback, public hal::utils::IP Data get(); private: - void notifyInternal(Data result); - hal::utils::TransferValue mData; }; diff --git a/neuralnetworks/1.0/utils/src/Callbacks.cpp b/neuralnetworks/1.0/utils/src/Callbacks.cpp index a0bdb3cd99..ea3ea56de6 100644 --- a/neuralnetworks/1.0/utils/src/Callbacks.cpp +++ b/neuralnetworks/1.0/utils/src/Callbacks.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -36,63 +37,52 @@ // lifetimes across processes and for protecting asynchronous calls across HIDL. namespace android::hardware::neuralnetworks::V1_0::utils { -namespace { -nn::GeneralResult convertPreparedModel( - const sp& preparedModel) { - return NN_TRY(utils::PreparedModel::create(preparedModel)); +nn::GeneralResult> supportedOperationsCallback( + ErrorStatus status, const hidl_vec& supportedOperations) { + HANDLE_HAL_STATUS(status) << "get supported operations failed with " << toString(status); + return supportedOperations; } -} // namespace +nn::GeneralResult prepareModelCallback( + ErrorStatus status, const sp& preparedModel) { + HANDLE_HAL_STATUS(status) << "model preparation failed with " << toString(status); + return NN_TRY(PreparedModel::create(preparedModel)); +} + +nn::ExecutionResult, nn::Timing>> executionCallback( + ErrorStatus status) { + HANDLE_HAL_STATUS(status) << "execution failed with " << toString(status); + return {}; +} Return PreparedModelCallback::notify(ErrorStatus status, const sp& preparedModel) { - if (status != ErrorStatus::NONE) { - const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); - notifyInternal(NN_ERROR(canonical) << "preparedModel failed with " << toString(status)); - } else if (preparedModel == nullptr) { - notifyInternal(NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) - << "Returned preparedModel is nullptr"); - } else { - notifyInternal(convertPreparedModel(preparedModel)); - } + mData.put(prepareModelCallback(status, preparedModel)); return Void(); } void PreparedModelCallback::notifyAsDeadObject() { - notifyInternal(NN_ERROR(nn::ErrorStatus::DEAD_OBJECT) << "Dead object"); + mData.put(NN_ERROR(nn::ErrorStatus::DEAD_OBJECT) << "Dead object"); } PreparedModelCallback::Data PreparedModelCallback::get() { return mData.take(); } -void PreparedModelCallback::notifyInternal(PreparedModelCallback::Data result) { - mData.put(std::move(result)); -} - // ExecutionCallback methods begin here Return ExecutionCallback::notify(ErrorStatus status) { - if (status != ErrorStatus::NONE) { - const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); - notifyInternal(NN_ERROR(canonical) << "execute failed with " << toString(status)); - } else { - notifyInternal({}); - } + mData.put(executionCallback(status)); return Void(); } void ExecutionCallback::notifyAsDeadObject() { - notifyInternal(NN_ERROR(nn::ErrorStatus::DEAD_OBJECT) << "Dead object"); + mData.put(NN_ERROR(nn::ErrorStatus::DEAD_OBJECT) << "Dead object"); } ExecutionCallback::Data ExecutionCallback::get() { return mData.take(); } -void ExecutionCallback::notifyInternal(ExecutionCallback::Data result) { - mData.put(std::move(result)); -} - } // namespace android::hardware::neuralnetworks::V1_0::utils diff --git a/neuralnetworks/1.0/utils/src/Device.cpp b/neuralnetworks/1.0/utils/src/Device.cpp index 83e0015689..93bd81a19c 100644 --- a/neuralnetworks/1.0/utils/src/Device.cpp +++ b/neuralnetworks/1.0/utils/src/Device.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -44,24 +45,21 @@ namespace android::hardware::neuralnetworks::V1_0::utils { namespace { -nn::GeneralResult initCapabilities(V1_0::IDevice* device) { +nn::GeneralResult capabilitiesCallback(ErrorStatus status, + const Capabilities& capabilities) { + HANDLE_HAL_STATUS(status) << "getting capabilities failed with " << toString(status); + return nn::convert(capabilities); +} + +nn::GeneralResult getCapabilitiesFrom(V1_0::IDevice* device) { CHECK(device != nullptr); - nn::GeneralResult result = NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) - << "uninitialized"; - const auto cb = [&result](ErrorStatus status, const Capabilities& capabilities) { - if (status != ErrorStatus::NONE) { - const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); - result = NN_ERROR(canonical) << "getCapabilities failed with " << toString(status); - } else { - result = nn::convert(capabilities); - } - }; + auto cb = hal::utils::CallbackValue(capabilitiesCallback); const auto ret = device->getCapabilities(cb); HANDLE_TRANSPORT_FAILURE(ret); - return result; + return cb.take(); } } // namespace @@ -77,7 +75,7 @@ nn::GeneralResult> Device::create(std::string name << "V1_0::utils::Device::create must have non-null device"; } - auto capabilities = NN_TRY(initCapabilities(device.get())); + auto capabilities = NN_TRY(getCapabilitiesFrom(device.get())); auto deathHandler = NN_TRY(hal::utils::DeathHandler::create(device)); return std::make_shared(PrivateConstructorTag{}, std::move(name), @@ -134,27 +132,12 @@ nn::GeneralResult> Device::getSupportedOperations(const nn::Mo const auto hidlModel = NN_TRY(convert(modelInShared)); - nn::GeneralResult> result = NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) - << "uninitialized"; - auto cb = [&result, &model](ErrorStatus status, const hidl_vec& supportedOperations) { - if (status != ErrorStatus::NONE) { - const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); - result = NN_ERROR(canonical) - << "getSupportedOperations failed with " << toString(status); - } else if (supportedOperations.size() != model.main.operations.size()) { - result = NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) - << "getSupportedOperations returned vector of size " - << supportedOperations.size() << " but expected " - << model.main.operations.size(); - } else { - result = supportedOperations; - } - }; + auto cb = hal::utils::CallbackValue(supportedOperationsCallback); const auto ret = kDevice->getSupportedOperations(hidlModel, cb); HANDLE_TRANSPORT_FAILURE(ret); - return result; + return cb.take(); } nn::GeneralResult Device::prepareModel( @@ -173,10 +156,7 @@ nn::GeneralResult Device::prepareModel( const auto ret = kDevice->prepareModel(hidlModel, cb); const auto status = HANDLE_TRANSPORT_FAILURE(ret); - if (status != ErrorStatus::NONE) { - const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); - return NN_ERROR(canonical) << "prepareModel failed with " << toString(status); - } + HANDLE_HAL_STATUS(status) << "model preparation failed with " << toString(status); return cb->get(); } diff --git a/neuralnetworks/1.0/utils/src/PreparedModel.cpp b/neuralnetworks/1.0/utils/src/PreparedModel.cpp index c1dd1d9e70..c0c22fbd6a 100644 --- a/neuralnetworks/1.0/utils/src/PreparedModel.cpp +++ b/neuralnetworks/1.0/utils/src/PreparedModel.cpp @@ -42,8 +42,7 @@ namespace android::hardware::neuralnetworks::V1_0::utils { nn::GeneralResult> PreparedModel::create( sp preparedModel) { if (preparedModel == nullptr) { - return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) - << "V1_0::utils::PreparedModel::create must have non-null preparedModel"; + return NN_ERROR() << "V1_0::utils::PreparedModel::create must have non-null preparedModel"; } auto deathHandler = NN_TRY(hal::utils::DeathHandler::create(preparedModel)); @@ -71,10 +70,7 @@ nn::ExecutionResult, nn::Timing>> Prepare const auto ret = kPreparedModel->execute(hidlRequest, cb); const auto status = HANDLE_TRANSPORT_FAILURE(ret); - if (status != ErrorStatus::NONE) { - const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); - return NN_ERROR(canonical) << "execute failed with " << toString(status); - } + HANDLE_HAL_STATUS(status) << "execution failed with " << toString(status); auto result = NN_TRY(cb->get()); NN_TRY(hal::utils::makeExecutionFailure( diff --git a/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Conversions.h b/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Conversions.h index f64646257f..5d0769f14c 100644 --- a/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Conversions.h +++ b/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Conversions.h @@ -51,6 +51,10 @@ nn::GeneralResult convert(const nn::Capabilities& capabilities); nn::GeneralResult convert(const nn::Model& model); nn::GeneralResult convert(const nn::ExecutionPreference& executionPreference); +nn::GeneralResult convert(const nn::DeviceStatus& deviceStatus); +nn::GeneralResult convert(const nn::Request& request); +nn::GeneralResult convert(const nn::ErrorStatus& status); + } // namespace android::hardware::neuralnetworks::V1_1::utils #endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_1_CONVERSIONS_H diff --git a/neuralnetworks/1.1/utils/src/Conversions.cpp b/neuralnetworks/1.1/utils/src/Conversions.cpp index 359f68ad4d..b47f25a68c 100644 --- a/neuralnetworks/1.1/utils/src/Conversions.cpp +++ b/neuralnetworks/1.1/utils/src/Conversions.cpp @@ -275,4 +275,16 @@ nn::GeneralResult convert(const nn::ExecutionPreference& ex return validatedConvert(executionPreference); } +nn::GeneralResult convert(const nn::DeviceStatus& deviceStatus) { + return V1_0::utils::convert(deviceStatus); +} + +nn::GeneralResult convert(const nn::Request& request) { + return V1_0::utils::convert(request); +} + +nn::GeneralResult convert(const nn::ErrorStatus& status) { + return V1_0::utils::convert(status); +} + } // namespace android::hardware::neuralnetworks::V1_1::utils diff --git a/neuralnetworks/1.1/utils/src/Device.cpp b/neuralnetworks/1.1/utils/src/Device.cpp index b57c7f4c54..3197ef4ac3 100644 --- a/neuralnetworks/1.1/utils/src/Device.cpp +++ b/neuralnetworks/1.1/utils/src/Device.cpp @@ -45,24 +45,21 @@ namespace android::hardware::neuralnetworks::V1_1::utils { namespace { -nn::GeneralResult initCapabilities(V1_1::IDevice* device) { +nn::GeneralResult capabilitiesCallback(V1_0::ErrorStatus status, + const Capabilities& capabilities) { + HANDLE_HAL_STATUS(status) << "getting capabilities failed with " << toString(status); + return nn::convert(capabilities); +} + +nn::GeneralResult getCapabilitiesFrom(V1_1::IDevice* device) { CHECK(device != nullptr); - nn::GeneralResult result = NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) - << "uninitialized"; - const auto cb = [&result](V1_0::ErrorStatus status, const Capabilities& capabilities) { - if (status != V1_0::ErrorStatus::NONE) { - const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); - result = NN_ERROR(canonical) << "getCapabilities_1_1 failed with " << toString(status); - } else { - result = nn::convert(capabilities); - } - }; + auto cb = hal::utils::CallbackValue(capabilitiesCallback); const auto ret = device->getCapabilities_1_1(cb); HANDLE_TRANSPORT_FAILURE(ret); - return result; + return cb.take(); } } // namespace @@ -78,7 +75,7 @@ nn::GeneralResult> Device::create(std::string name << "V1_1::utils::Device::create must have non-null device"; } - auto capabilities = NN_TRY(initCapabilities(device.get())); + auto capabilities = NN_TRY(getCapabilitiesFrom(device.get())); auto deathHandler = NN_TRY(hal::utils::DeathHandler::create(device)); return std::make_shared(PrivateConstructorTag{}, std::move(name), @@ -135,28 +132,12 @@ nn::GeneralResult> Device::getSupportedOperations(const nn::Mo const auto hidlModel = NN_TRY(convert(modelInShared)); - nn::GeneralResult> result = NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) - << "uninitialized"; - auto cb = [&result, &model](V1_0::ErrorStatus status, - const hidl_vec& supportedOperations) { - if (status != V1_0::ErrorStatus::NONE) { - const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); - result = NN_ERROR(canonical) - << "getSupportedOperations_1_1 failed with " << toString(status); - } else if (supportedOperations.size() != model.main.operations.size()) { - result = NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) - << "getSupportedOperations_1_1 returned vector of size " - << supportedOperations.size() << " but expected " - << model.main.operations.size(); - } else { - result = supportedOperations; - } - }; + auto cb = hal::utils::CallbackValue(V1_0::utils::supportedOperationsCallback); const auto ret = kDevice->getSupportedOperations_1_1(hidlModel, cb); HANDLE_TRANSPORT_FAILURE(ret); - return result; + return cb.take(); } nn::GeneralResult Device::prepareModel( @@ -176,10 +157,7 @@ nn::GeneralResult Device::prepareModel( const auto ret = kDevice->prepareModel_1_1(hidlModel, hidlPreference, cb); const auto status = HANDLE_TRANSPORT_FAILURE(ret); - if (status != V1_0::ErrorStatus::NONE) { - const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); - return NN_ERROR(canonical) << "prepareModel failed with " << toString(status); - } + HANDLE_HAL_STATUS(status) << "model preparation failed with " << toString(status); return cb->get(); } diff --git a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Callbacks.h b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Callbacks.h index 1162bc33b3..ba3c1ba1db 100644 --- a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Callbacks.h +++ b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Callbacks.h @@ -36,6 +36,19 @@ namespace android::hardware::neuralnetworks::V1_2::utils { +// Converts the results of IDevice::prepareModel* to the NN canonical format. On success, this +// function returns with a non-null nn::SharedPreparedModel with a feature level of +// nn::Version::ANDROID_Q. On failure, this function returns with the appropriate nn::GeneralError. +nn::GeneralResult prepareModelCallback( + V1_0::ErrorStatus status, const sp& preparedModel); + +// Converts the results of IDevice::execute* to the NN canonical format. On success, this function +// returns with the output shapes and the timing information. On failure, this function returns with +// the appropriate nn::ExecutionError. +nn::ExecutionResult, nn::Timing>> executionCallback( + V1_0::ErrorStatus status, const hidl_vec& outputShapes, const Timing& timing); + +// A HIDL callback class to receive the results of IDevice::prepareModel* asynchronously. class PreparedModelCallback final : public IPreparedModelCallback, public hal::utils::IProtectedCallback { public: @@ -51,11 +64,10 @@ class PreparedModelCallback final : public IPreparedModelCallback, Data get(); private: - void notifyInternal(Data result); - hal::utils::TransferValue mData; }; +// A HIDL callback class to receive the results of IDevice::execute_1_2 asynchronously. class ExecutionCallback final : public IExecutionCallback, public hal::utils::IProtectedCallback { public: using Data = nn::ExecutionResult, nn::Timing>>; @@ -69,8 +81,6 @@ class ExecutionCallback final : public IExecutionCallback, public hal::utils::IP Data get(); private: - void notifyInternal(Data result); - hal::utils::TransferValue mData; }; diff --git a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Conversions.h b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Conversions.h index 5dcbc0bb79..6fd13379ef 100644 --- a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Conversions.h +++ b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Conversions.h @@ -97,6 +97,12 @@ nn::GeneralResult> convert(const std::vector& nn::GeneralResult> convert(const std::vector& handles); nn::GeneralResult> convert(const std::vector& outputShapes); +nn::GeneralResult convert(const nn::DeviceStatus& deviceStatus); +nn::GeneralResult convert(const nn::Request& request); +nn::GeneralResult convert(const nn::ErrorStatus& status); +nn::GeneralResult convert( + const nn::ExecutionPreference& executionPreference); + } // namespace android::hardware::neuralnetworks::V1_2::utils #endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_2_CONVERSIONS_H diff --git a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Device.h b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Device.h index 79c3b041ad..b4bef5ee0a 100644 --- a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Device.h +++ b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Device.h @@ -37,10 +37,21 @@ namespace android::hardware::neuralnetworks::V1_2::utils { -nn::GeneralResult initVersionString(V1_2::IDevice* device); -nn::GeneralResult initDeviceType(V1_2::IDevice* device); -nn::GeneralResult> initExtensions(V1_2::IDevice* device); -nn::GeneralResult> initNumberOfCacheFilesNeeded( +// Retrieves the version string from the provided device object. On failure, this function returns +// with the appropriate nn::GeneralError. +nn::GeneralResult getVersionStringFrom(V1_2::IDevice* device); + +// Retrieves the device type from the provided device object. On failure, this function returns with +// the appropriate nn::GeneralError. +nn::GeneralResult getDeviceTypeFrom(V1_2::IDevice* device); + +// Retrieves the extensions supported by the provided device object. On failure, this function +// returns with the appropriate nn::GeneralError. +nn::GeneralResult> getSupportedExtensionsFrom(V1_2::IDevice* device); + +// Retrieves the number of model cache files and data cache files needed by the provided device +// object. On failure, this function returns with the appropriate nn::GeneralError. +nn::GeneralResult> getNumberOfCacheFilesNeededFrom( V1_2::IDevice* device); // Class that adapts V1_2::IDevice to nn::IDevice. diff --git a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/PreparedModel.h b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/PreparedModel.h index 8ed5ca7f97..6a56a82f99 100644 --- a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/PreparedModel.h +++ b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/PreparedModel.h @@ -41,10 +41,10 @@ class PreparedModel final : public nn::IPreparedModel { public: static nn::GeneralResult> create( - sp preparedModel); + sp preparedModel, bool executeSynchronously); - PreparedModel(PrivateConstructorTag tag, sp preparedModel, - hal::utils::DeathHandler deathHandler); + PreparedModel(PrivateConstructorTag tag, bool executeSynchronously, + sp preparedModel, hal::utils::DeathHandler deathHandler); nn::ExecutionResult, nn::Timing>> execute( const nn::Request& request, nn::MeasureTiming measure, @@ -65,6 +65,7 @@ class PreparedModel final : public nn::IPreparedModel { nn::ExecutionResult, nn::Timing>> executeAsynchronously( const V1_0::Request& request, MeasureTiming measure) const; + const bool kExecuteSynchronously; const sp kPreparedModel; const hal::utils::DeathHandler kDeathHandler; }; diff --git a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Utils.h b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Utils.h index 70149a2d3a..c289fc89ab 100644 --- a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Utils.h +++ b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Utils.h @@ -30,6 +30,8 @@ namespace android::hardware::neuralnetworks::V1_2::utils { +using CacheToken = hidl_array(Constant::BYTE_SIZE_OF_CACHE_TOKEN)>; + constexpr auto kDefaultMesaureTiming = MeasureTiming::NO; constexpr auto kNoTiming = Timing{.timeOnDevice = std::numeric_limits::max(), .timeInDriver = std::numeric_limits::max()}; diff --git a/neuralnetworks/1.2/utils/src/Callbacks.cpp b/neuralnetworks/1.2/utils/src/Callbacks.cpp index ab3e0ca879..fefa122101 100644 --- a/neuralnetworks/1.2/utils/src/Callbacks.cpp +++ b/neuralnetworks/1.2/utils/src/Callbacks.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -42,104 +43,73 @@ namespace android::hardware::neuralnetworks::V1_2::utils { namespace { -nn::GeneralResult convertPreparedModel( - const sp& preparedModel) { - return NN_TRY(V1_0::utils::PreparedModel::create(preparedModel)); -} - -nn::GeneralResult convertPreparedModel( - const sp& preparedModel) { - return NN_TRY(utils::PreparedModel::create(preparedModel)); -} - nn::GeneralResult, nn::Timing>> convertExecutionGeneralResultsHelper(const hidl_vec& outputShapes, const Timing& timing) { return std::make_pair(NN_TRY(nn::convert(outputShapes)), NN_TRY(nn::convert(timing))); } -nn::ExecutionResult, nn::Timing>> -convertExecutionGeneralResults(const hidl_vec& outputShapes, const Timing& timing) { +} // namespace + +nn::GeneralResult prepareModelCallback( + V1_0::ErrorStatus status, const sp& preparedModel) { + HANDLE_HAL_STATUS(status) << "model preparation failed with " << toString(status); + return NN_TRY(PreparedModel::create(preparedModel, /*executeSynchronously=*/true)); +} + +nn::ExecutionResult, nn::Timing>> executionCallback( + V1_0::ErrorStatus status, const hidl_vec& outputShapes, const Timing& timing) { + if (status == V1_0::ErrorStatus::OUTPUT_INSUFFICIENT_SIZE) { + auto canonicalOutputShapes = + nn::convert(outputShapes).value_or(std::vector{}); + return NN_ERROR(nn::ErrorStatus::OUTPUT_INSUFFICIENT_SIZE, std::move(canonicalOutputShapes)) + << "execution failed with " << toString(status); + } + HANDLE_HAL_STATUS(status) << "execution failed with " << toString(status); return hal::utils::makeExecutionFailure( convertExecutionGeneralResultsHelper(outputShapes, timing)); } -} // namespace - Return PreparedModelCallback::notify(V1_0::ErrorStatus status, const sp& preparedModel) { - if (status != V1_0::ErrorStatus::NONE) { - const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); - notifyInternal(NN_ERROR(canonical) << "preparedModel failed with " << toString(status)); - } else if (preparedModel == nullptr) { - notifyInternal(NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) - << "Returned preparedModel is nullptr"); - } else { - notifyInternal(convertPreparedModel(preparedModel)); - } + mData.put(V1_0::utils::prepareModelCallback(status, preparedModel)); return Void(); } Return PreparedModelCallback::notify_1_2(V1_0::ErrorStatus status, const sp& preparedModel) { - if (status != V1_0::ErrorStatus::NONE) { - const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); - notifyInternal(NN_ERROR(canonical) << "preparedModel failed with " << toString(status)); - } else if (preparedModel == nullptr) { - notifyInternal(NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) - << "Returned preparedModel is nullptr"); - } else { - notifyInternal(convertPreparedModel(preparedModel)); - } + mData.put(prepareModelCallback(status, preparedModel)); return Void(); } void PreparedModelCallback::notifyAsDeadObject() { - notifyInternal(NN_ERROR(nn::ErrorStatus::DEAD_OBJECT) << "Dead object"); + mData.put(NN_ERROR(nn::ErrorStatus::DEAD_OBJECT) << "Dead object"); } PreparedModelCallback::Data PreparedModelCallback::get() { return mData.take(); } -void PreparedModelCallback::notifyInternal(PreparedModelCallback::Data result) { - mData.put(std::move(result)); -} - // ExecutionCallback methods begin here Return ExecutionCallback::notify(V1_0::ErrorStatus status) { - if (status != V1_0::ErrorStatus::NONE) { - const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); - notifyInternal(NN_ERROR(canonical) << "execute failed with " << toString(status)); - } else { - notifyInternal({}); - } + mData.put(V1_0::utils::executionCallback(status)); return Void(); } Return ExecutionCallback::notify_1_2(V1_0::ErrorStatus status, const hidl_vec& outputShapes, const Timing& timing) { - if (status != V1_0::ErrorStatus::NONE) { - const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); - notifyInternal(NN_ERROR(canonical) << "execute failed with " << toString(status)); - } else { - notifyInternal(convertExecutionGeneralResults(outputShapes, timing)); - } + mData.put(executionCallback(status, outputShapes, timing)); return Void(); } void ExecutionCallback::notifyAsDeadObject() { - notifyInternal(NN_ERROR(nn::ErrorStatus::DEAD_OBJECT) << "Dead object"); + mData.put(NN_ERROR(nn::ErrorStatus::DEAD_OBJECT) << "Dead object"); } ExecutionCallback::Data ExecutionCallback::get() { return mData.take(); } -void ExecutionCallback::notifyInternal(ExecutionCallback::Data result) { - mData.put(std::move(result)); -} - } // namespace android::hardware::neuralnetworks::V1_2::utils diff --git a/neuralnetworks/1.2/utils/src/Conversions.cpp b/neuralnetworks/1.2/utils/src/Conversions.cpp index 3790d1f61e..062f6f712f 100644 --- a/neuralnetworks/1.2/utils/src/Conversions.cpp +++ b/neuralnetworks/1.2/utils/src/Conversions.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -622,4 +623,21 @@ nn::GeneralResult> convert(const std::vector convert(const nn::DeviceStatus& deviceStatus) { + return V1_1::utils::convert(deviceStatus); +} + +nn::GeneralResult convert(const nn::Request& request) { + return V1_1::utils::convert(request); +} + +nn::GeneralResult convert(const nn::ErrorStatus& status) { + return V1_1::utils::convert(status); +} + +nn::GeneralResult convert( + const nn::ExecutionPreference& executionPreference) { + return V1_1::utils::convert(executionPreference); +} + } // namespace android::hardware::neuralnetworks::V1_2::utils diff --git a/neuralnetworks/1.2/utils/src/Device.cpp b/neuralnetworks/1.2/utils/src/Device.cpp index 6cca841aba..9fe0de25b3 100644 --- a/neuralnetworks/1.2/utils/src/Device.cpp +++ b/neuralnetworks/1.2/utils/src/Device.cpp @@ -47,109 +47,102 @@ namespace android::hardware::neuralnetworks::V1_2::utils { namespace { -nn::GeneralResult initCapabilities(V1_2::IDevice* device) { +nn::GeneralResult capabilitiesCallback(V1_0::ErrorStatus status, + const Capabilities& capabilities) { + HANDLE_HAL_STATUS(status) << "getting capabilities failed with " << toString(status); + return nn::convert(capabilities); +} + +nn::GeneralResult versionStringCallback(V1_0::ErrorStatus status, + const hidl_string& versionString) { + HANDLE_HAL_STATUS(status) << "getVersionString failed with " << toString(status); + return versionString; +} + +nn::GeneralResult deviceTypeCallback(V1_0::ErrorStatus status, + DeviceType deviceType) { + HANDLE_HAL_STATUS(status) << "getDeviceType failed with " << toString(status); + return nn::convert(deviceType); +} + +nn::GeneralResult> supportedExtensionsCallback( + V1_0::ErrorStatus status, const hidl_vec& extensions) { + HANDLE_HAL_STATUS(status) << "getExtensions failed with " << toString(status); + return nn::convert(extensions); +} + +nn::GeneralResult> numberOfCacheFilesNeededCallback( + V1_0::ErrorStatus status, uint32_t numModelCache, uint32_t numDataCache) { + HANDLE_HAL_STATUS(status) << "getNumberOfCacheFilesNeeded failed with " << toString(status); + if (numModelCache > nn::kMaxNumberOfCacheFiles) { + return NN_ERROR() << "getNumberOfCacheFilesNeeded returned numModelCache files greater " + "than allowed max (" + << numModelCache << " vs " << nn::kMaxNumberOfCacheFiles << ")"; + } + if (numDataCache > nn::kMaxNumberOfCacheFiles) { + return NN_ERROR() << "getNumberOfCacheFilesNeeded returned numDataCache files greater " + "than allowed max (" + << numDataCache << " vs " << nn::kMaxNumberOfCacheFiles << ")"; + } + return std::make_pair(numModelCache, numDataCache); +} + +nn::GeneralResult getCapabilitiesFrom(V1_2::IDevice* device) { CHECK(device != nullptr); - nn::GeneralResult result = NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) - << "uninitialized"; - const auto cb = [&result](V1_0::ErrorStatus status, const Capabilities& capabilities) { - if (status != V1_0::ErrorStatus::NONE) { - const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); - result = NN_ERROR(canonical) << "getCapabilities_1_2 failed with " << toString(status); - } else { - result = nn::convert(capabilities); - } - }; + auto cb = hal::utils::CallbackValue(capabilitiesCallback); const auto ret = device->getCapabilities_1_2(cb); HANDLE_TRANSPORT_FAILURE(ret); - return result; + return cb.take(); } } // namespace -nn::GeneralResult initVersionString(V1_2::IDevice* device) { +nn::GeneralResult getVersionStringFrom(V1_2::IDevice* device) { CHECK(device != nullptr); - nn::GeneralResult result = NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) - << "uninitialized"; - const auto cb = [&result](V1_0::ErrorStatus status, const hidl_string& versionString) { - if (status != V1_0::ErrorStatus::NONE) { - const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); - result = NN_ERROR(canonical) << "getVersionString failed with " << toString(status); - } else { - result = versionString; - } - }; + auto cb = hal::utils::CallbackValue(versionStringCallback); const auto ret = device->getVersionString(cb); HANDLE_TRANSPORT_FAILURE(ret); - return result; + return cb.take(); } -nn::GeneralResult initDeviceType(V1_2::IDevice* device) { +nn::GeneralResult getDeviceTypeFrom(V1_2::IDevice* device) { CHECK(device != nullptr); - nn::GeneralResult result = NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) - << "uninitialized"; - const auto cb = [&result](V1_0::ErrorStatus status, DeviceType deviceType) { - if (status != V1_0::ErrorStatus::NONE) { - const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); - result = NN_ERROR(canonical) << "getDeviceType failed with " << toString(status); - } else { - result = nn::convert(deviceType); - } - }; + auto cb = hal::utils::CallbackValue(deviceTypeCallback); const auto ret = device->getType(cb); HANDLE_TRANSPORT_FAILURE(ret); - return result; + return cb.take(); } -nn::GeneralResult> initExtensions(V1_2::IDevice* device) { +nn::GeneralResult> getSupportedExtensionsFrom(V1_2::IDevice* device) { CHECK(device != nullptr); - nn::GeneralResult> result = - NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "uninitialized"; - const auto cb = [&result](V1_0::ErrorStatus status, const hidl_vec& extensions) { - if (status != V1_0::ErrorStatus::NONE) { - const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); - result = NN_ERROR(canonical) << "getExtensions failed with " << toString(status); - } else { - result = nn::convert(extensions); - } - }; + auto cb = hal::utils::CallbackValue(supportedExtensionsCallback); const auto ret = device->getSupportedExtensions(cb); HANDLE_TRANSPORT_FAILURE(ret); - return result; + return cb.take(); } -nn::GeneralResult> initNumberOfCacheFilesNeeded( +nn::GeneralResult> getNumberOfCacheFilesNeededFrom( V1_2::IDevice* device) { CHECK(device != nullptr); - nn::GeneralResult> result = - NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "uninitialized"; - const auto cb = [&result](V1_0::ErrorStatus status, uint32_t numModelCache, - uint32_t numDataCache) { - if (status != V1_0::ErrorStatus::NONE) { - const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); - result = NN_ERROR(canonical) - << "getNumberOfCacheFilesNeeded failed with " << toString(status); - } else { - result = std::make_pair(numModelCache, numDataCache); - } - }; + auto cb = hal::utils::CallbackValue(numberOfCacheFilesNeededCallback); const auto ret = device->getNumberOfCacheFilesNeeded(cb); HANDLE_TRANSPORT_FAILURE(ret); - return result; + return cb.take(); } nn::GeneralResult> Device::create(std::string name, @@ -163,11 +156,11 @@ nn::GeneralResult> Device::create(std::string name << "V1_2::utils::Device::create must have non-null device"; } - auto versionString = NN_TRY(initVersionString(device.get())); - const auto deviceType = NN_TRY(initDeviceType(device.get())); - auto extensions = NN_TRY(initExtensions(device.get())); - auto capabilities = NN_TRY(initCapabilities(device.get())); - const auto numberOfCacheFilesNeeded = NN_TRY(initNumberOfCacheFilesNeeded(device.get())); + auto versionString = NN_TRY(getVersionStringFrom(device.get())); + const auto deviceType = NN_TRY(getDeviceTypeFrom(device.get())); + auto extensions = NN_TRY(getSupportedExtensionsFrom(device.get())); + auto capabilities = NN_TRY(getCapabilitiesFrom(device.get())); + const auto numberOfCacheFilesNeeded = NN_TRY(getNumberOfCacheFilesNeededFrom(device.get())); auto deathHandler = NN_TRY(hal::utils::DeathHandler::create(device)); return std::make_shared( @@ -232,28 +225,12 @@ nn::GeneralResult> Device::getSupportedOperations(const nn::Mo const auto hidlModel = NN_TRY(convert(modelInShared)); - nn::GeneralResult> result = NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) - << "uninitialized"; - auto cb = [&result, &model](V1_0::ErrorStatus status, - const hidl_vec& supportedOperations) { - if (status != V1_0::ErrorStatus::NONE) { - const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); - result = NN_ERROR(canonical) - << "getSupportedOperations_1_2 failed with " << toString(status); - } else if (supportedOperations.size() != model.main.operations.size()) { - result = NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) - << "getSupportedOperations_1_2 returned vector of size " - << supportedOperations.size() << " but expected " - << model.main.operations.size(); - } else { - result = supportedOperations; - } - }; + auto cb = hal::utils::CallbackValue(V1_0::utils::supportedOperationsCallback); const auto ret = kDevice->getSupportedOperations_1_2(hidlModel, cb); HANDLE_TRANSPORT_FAILURE(ret); - return result; + return cb.take(); } nn::GeneralResult Device::prepareModel( @@ -266,10 +243,10 @@ nn::GeneralResult Device::prepareModel( NN_TRY(hal::utils::flushDataFromPointerToShared(&model, &maybeModelInShared)); const auto hidlModel = NN_TRY(convert(modelInShared)); - const auto hidlPreference = NN_TRY(V1_1::utils::convert(preference)); + const auto hidlPreference = NN_TRY(convert(preference)); const auto hidlModelCache = NN_TRY(convert(modelCache)); const auto hidlDataCache = NN_TRY(convert(dataCache)); - const auto hidlToken = token; + const auto hidlToken = CacheToken{token}; const auto cb = sp::make(); const auto scoped = kDeathHandler.protectCallback(cb.get()); @@ -277,10 +254,7 @@ nn::GeneralResult Device::prepareModel( const auto ret = kDevice->prepareModel_1_2(hidlModel, hidlPreference, hidlModelCache, hidlDataCache, hidlToken, cb); const auto status = HANDLE_TRANSPORT_FAILURE(ret); - if (status != V1_0::ErrorStatus::NONE) { - const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); - return NN_ERROR(canonical) << "prepareModel_1_2 failed with " << toString(status); - } + HANDLE_HAL_STATUS(status) << "model preparation failed with " << toString(status); return cb->get(); } @@ -290,17 +264,14 @@ nn::GeneralResult Device::prepareModelFromCache( const std::vector& dataCache, const nn::CacheToken& token) const { const auto hidlModelCache = NN_TRY(convert(modelCache)); const auto hidlDataCache = NN_TRY(convert(dataCache)); - const auto hidlToken = token; + const auto hidlToken = CacheToken{token}; const auto cb = sp::make(); const auto scoped = kDeathHandler.protectCallback(cb.get()); const auto ret = kDevice->prepareModelFromCache(hidlModelCache, hidlDataCache, hidlToken, cb); const auto status = HANDLE_TRANSPORT_FAILURE(ret); - if (status != V1_0::ErrorStatus::NONE) { - const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); - return NN_ERROR(canonical) << "prepareModelFromCache failed with " << toString(status); - } + HANDLE_HAL_STATUS(status) << "model preparation from cache failed with " << toString(status); return cb->get(); } diff --git a/neuralnetworks/1.2/utils/src/PreparedModel.cpp b/neuralnetworks/1.2/utils/src/PreparedModel.cpp index b422cedefa..6d00082a5f 100644 --- a/neuralnetworks/1.2/utils/src/PreparedModel.cpp +++ b/neuralnetworks/1.2/utils/src/PreparedModel.cpp @@ -41,54 +41,33 @@ // lifetimes across processes and for protecting asynchronous calls across HIDL. namespace android::hardware::neuralnetworks::V1_2::utils { -namespace { - -nn::GeneralResult, nn::Timing>> -convertExecutionResultsHelper(const hidl_vec& outputShapes, const Timing& timing) { - return std::make_pair(NN_TRY(nn::convert(outputShapes)), NN_TRY(nn::convert(timing))); -} - -nn::ExecutionResult, nn::Timing>> convertExecutionResults( - const hidl_vec& outputShapes, const Timing& timing) { - return hal::utils::makeExecutionFailure(convertExecutionResultsHelper(outputShapes, timing)); -} - -} // namespace nn::GeneralResult> PreparedModel::create( - sp preparedModel) { + sp preparedModel, bool executeSynchronously) { if (preparedModel == nullptr) { - return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) - << "V1_2::utils::PreparedModel::create must have non-null preparedModel"; + return NN_ERROR() << "V1_2::utils::PreparedModel::create must have non-null preparedModel"; } auto deathHandler = NN_TRY(hal::utils::DeathHandler::create(preparedModel)); - return std::make_shared(PrivateConstructorTag{}, std::move(preparedModel), - std::move(deathHandler)); + return std::make_shared(PrivateConstructorTag{}, executeSynchronously, + std::move(preparedModel), std::move(deathHandler)); } -PreparedModel::PreparedModel(PrivateConstructorTag /*tag*/, sp preparedModel, +PreparedModel::PreparedModel(PrivateConstructorTag /*tag*/, bool executeSynchronously, + sp preparedModel, hal::utils::DeathHandler deathHandler) - : kPreparedModel(std::move(preparedModel)), kDeathHandler(std::move(deathHandler)) {} + : kExecuteSynchronously(executeSynchronously), + kPreparedModel(std::move(preparedModel)), + kDeathHandler(std::move(deathHandler)) {} nn::ExecutionResult, nn::Timing>> PreparedModel::executeSynchronously(const V1_0::Request& request, MeasureTiming measure) const { - nn::ExecutionResult, nn::Timing>> result = - NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "uninitialized"; - const auto cb = [&result](V1_0::ErrorStatus status, const hidl_vec& outputShapes, - const Timing& timing) { - if (status != V1_0::ErrorStatus::NONE) { - const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); - result = NN_ERROR(canonical) << "executeSynchronously failed with " << toString(status); - } else { - result = convertExecutionResults(outputShapes, timing); - } - }; + auto cb = hal::utils::CallbackValue(executionCallback); const auto ret = kPreparedModel->executeSynchronously(request, measure, cb); HANDLE_TRANSPORT_FAILURE(ret); - return result; + return cb.take(); } nn::ExecutionResult, nn::Timing>> @@ -98,9 +77,8 @@ PreparedModel::executeAsynchronously(const V1_0::Request& request, MeasureTiming const auto ret = kPreparedModel->execute_1_2(request, measure, cb); const auto status = HANDLE_TRANSPORT_FAILURE(ret); - if (status != V1_0::ErrorStatus::NONE) { - const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); - return NN_ERROR(canonical) << "execute failed with " << toString(status); + if (status != V1_0::ErrorStatus::OUTPUT_INSUFFICIENT_SIZE) { + HANDLE_HAL_STATUS(status) << "execution failed with " << toString(status); } return cb->get(); @@ -115,31 +93,17 @@ nn::ExecutionResult, nn::Timing>> Prepare const nn::Request& requestInShared = NN_TRY(hal::utils::makeExecutionFailure( hal::utils::flushDataFromPointerToShared(&request, &maybeRequestInShared))); - const auto hidlRequest = - NN_TRY(hal::utils::makeExecutionFailure(V1_0::utils::convert(requestInShared))); + const auto hidlRequest = NN_TRY(hal::utils::makeExecutionFailure(convert(requestInShared))); const auto hidlMeasure = NN_TRY(hal::utils::makeExecutionFailure(convert(measure))); - nn::ExecutionResult, nn::Timing>> result = - NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "uninitialized"; - const bool preferSynchronous = true; + auto result = kExecuteSynchronously ? executeSynchronously(hidlRequest, hidlMeasure) + : executeAsynchronously(hidlRequest, hidlMeasure); + auto [outputShapes, timing] = NN_TRY(std::move(result)); - // Execute synchronously if allowed. - if (preferSynchronous) { - result = executeSynchronously(hidlRequest, hidlMeasure); - } - - // Run asymchronous execution if execution has not already completed. - if (!result.has_value()) { - result = executeAsynchronously(hidlRequest, hidlMeasure); - } - - // Flush output buffers if suxcessful execution. - if (result.has_value()) { - NN_TRY(hal::utils::makeExecutionFailure( - hal::utils::unflushDataFromSharedToPointer(request, maybeRequestInShared))); - } + NN_TRY(hal::utils::makeExecutionFailure( + hal::utils::unflushDataFromSharedToPointer(request, maybeRequestInShared))); - return result; + return std::make_pair(std::move(outputShapes), timing); } nn::GeneralResult> @@ -154,7 +118,7 @@ PreparedModel::executeFenced(const nn::Request& /*request*/, } std::any PreparedModel::getUnderlyingResource() const { - sp resource = kPreparedModel; + sp resource = kPreparedModel; return resource; } diff --git a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Callbacks.h b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Callbacks.h index cb2a56a2e2..643172e192 100644 --- a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Callbacks.h +++ b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Callbacks.h @@ -39,6 +39,26 @@ namespace android::hardware::neuralnetworks::V1_3::utils { +// Converts the results of IDevice::getSupportedOperations* to the NN canonical format. On success, +// this function returns with the supported operations as indicated by a driver. On failure, this +// function returns with the appropriate nn::GeneralError. +nn::GeneralResult> supportedOperationsCallback( + ErrorStatus status, const hidl_vec& supportedOperations); + +// Converts the results of IDevice::prepareModel* to the NN canonical format. On success, this +// function returns with a non-null nn::SharedPreparedModel with a feature level of +// nn::Version::ANDROID_R. On failure, this function returns with the appropriate nn::GeneralError. +nn::GeneralResult prepareModelCallback( + ErrorStatus status, const sp& preparedModel); + +// Converts the results of IDevice::execute* to the NN canonical format. On success, this function +// returns with the output shapes and the timing information. On failure, this function returns with +// the appropriate nn::ExecutionError. +nn::ExecutionResult, nn::Timing>> executionCallback( + ErrorStatus status, const hidl_vec& outputShapes, + const V1_2::Timing& timing); + +// A HIDL callback class to receive the results of IDevice::prepareModel* asynchronously. class PreparedModelCallback final : public IPreparedModelCallback, public hal::utils::IProtectedCallback { public: @@ -55,11 +75,10 @@ class PreparedModelCallback final : public IPreparedModelCallback, Data get(); private: - void notifyInternal(Data result); - hal::utils::TransferValue mData; }; +// A HIDL callback class to receive the results of IDevice::execute_1_3 asynchronously. class ExecutionCallback final : public IExecutionCallback, public hal::utils::IProtectedCallback { public: using Data = nn::ExecutionResult, nn::Timing>>; @@ -76,8 +95,6 @@ class ExecutionCallback final : public IExecutionCallback, public hal::utils::IP Data get(); private: - void notifyInternal(Data result); - hal::utils::TransferValue mData; }; diff --git a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Conversions.h b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Conversions.h index 477bb7b6e0..74a6534aff 100644 --- a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Conversions.h +++ b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Conversions.h @@ -103,6 +103,17 @@ nn::GeneralResult convert(const nn::SharedHandle& handle); nn::GeneralResult convert(const nn::Memory& memory); nn::GeneralResult> convert(const std::vector& bufferRoles); +nn::GeneralResult convert(const nn::DeviceStatus& deviceStatus); +nn::GeneralResult convert( + const nn::ExecutionPreference& executionPreference); +nn::GeneralResult> convert(const std::vector& extensions); +nn::GeneralResult> convert(const std::vector& handles); +nn::GeneralResult> convert( + const std::vector& outputShapes); +nn::GeneralResult convert(const nn::DeviceType& deviceType); +nn::GeneralResult convert(const nn::MeasureTiming& measureTiming); +nn::GeneralResult convert(const nn::Timing& timing); + } // namespace android::hardware::neuralnetworks::V1_3::utils #endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_3_CONVERSIONS_H diff --git a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/PreparedModel.h b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/PreparedModel.h index c4ba483463..664d87a7c2 100644 --- a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/PreparedModel.h +++ b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/PreparedModel.h @@ -40,10 +40,10 @@ class PreparedModel final : public nn::IPreparedModel { public: static nn::GeneralResult> create( - sp preparedModel); + sp preparedModel, bool executeSynchronously); - PreparedModel(PrivateConstructorTag tag, sp preparedModel, - hal::utils::DeathHandler deathHandler); + PreparedModel(PrivateConstructorTag tag, bool executeSynchronously, + sp preparedModel, hal::utils::DeathHandler deathHandler); nn::ExecutionResult, nn::Timing>> execute( const nn::Request& request, nn::MeasureTiming measure, @@ -66,6 +66,7 @@ class PreparedModel final : public nn::IPreparedModel { const Request& request, V1_2::MeasureTiming measure, const OptionalTimePoint& deadline, const OptionalTimeoutDuration& loopTimeoutDuration) const; + const bool kExecuteSynchronously; const sp kPreparedModel; const hal::utils::DeathHandler kDeathHandler; }; diff --git a/neuralnetworks/1.3/utils/src/Buffer.cpp b/neuralnetworks/1.3/utils/src/Buffer.cpp index 4ef54a2c93..614033e268 100644 --- a/neuralnetworks/1.3/utils/src/Buffer.cpp +++ b/neuralnetworks/1.3/utils/src/Buffer.cpp @@ -41,12 +41,10 @@ namespace android::hardware::neuralnetworks::V1_3::utils { nn::GeneralResult> Buffer::create( sp buffer, nn::Request::MemoryDomainToken token) { if (buffer == nullptr) { - return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) - << "V1_3::utils::Buffer::create must have non-null buffer"; + return NN_ERROR() << "V1_3::utils::Buffer::create must have non-null buffer"; } if (token == static_cast(0)) { - return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) - << "V1_3::utils::Buffer::create must have non-zero token"; + return NN_ERROR() << "V1_3::utils::Buffer::create must have non-zero token"; } return std::make_shared(PrivateConstructorTag{}, std::move(buffer), token); @@ -68,10 +66,7 @@ nn::GeneralResult Buffer::copyTo(const nn::Memory& dst) const { const auto ret = kBuffer->copyTo(hidlDst); const auto status = HANDLE_TRANSPORT_FAILURE(ret); - if (status != ErrorStatus::NONE) { - const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); - return NN_ERROR(canonical) << "IBuffer::copyTo failed with " << toString(status); - } + HANDLE_HAL_STATUS(status) << "IBuffer::copyTo failed with " << toString(status); return {}; } @@ -83,10 +78,7 @@ nn::GeneralResult Buffer::copyFrom(const nn::Memory& src, const auto ret = kBuffer->copyFrom(hidlSrc, hidlDimensions); const auto status = HANDLE_TRANSPORT_FAILURE(ret); - if (status != ErrorStatus::NONE) { - const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); - return NN_ERROR(canonical) << "IBuffer::copyFrom failed with " << toString(status); - } + HANDLE_HAL_STATUS(status) << "IBuffer::copyFrom failed with " << toString(status); return {}; } diff --git a/neuralnetworks/1.3/utils/src/Callbacks.cpp b/neuralnetworks/1.3/utils/src/Callbacks.cpp index 17c20fba68..af76e6a87e 100644 --- a/neuralnetworks/1.3/utils/src/Callbacks.cpp +++ b/neuralnetworks/1.3/utils/src/Callbacks.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -45,136 +46,93 @@ namespace android::hardware::neuralnetworks::V1_3::utils { namespace { -nn::GeneralResult convertPreparedModel( - const sp& preparedModel) { - return NN_TRY(V1_0::utils::PreparedModel::create(preparedModel)); +nn::GeneralResult, nn::Timing>> +convertExecutionGeneralResultsHelper(const hidl_vec& outputShapes, + const V1_2::Timing& timing) { + return std::make_pair(NN_TRY(nn::convert(outputShapes)), NN_TRY(nn::convert(timing))); } -nn::GeneralResult convertPreparedModel( - const sp& preparedModel) { - return NN_TRY(V1_2::utils::PreparedModel::create(preparedModel)); -} +} // namespace -nn::GeneralResult convertPreparedModel( - const sp& preparedModel) { - return NN_TRY(utils::PreparedModel::create(preparedModel)); +nn::GeneralResult> supportedOperationsCallback( + ErrorStatus status, const hidl_vec& supportedOperations) { + HANDLE_HAL_STATUS(status) << "get supported operations failed with " << toString(status); + return supportedOperations; } -nn::GeneralResult, nn::Timing>> -convertExecutionGeneralResultsHelper(const hidl_vec& outputShapes, - const V1_2::Timing& timing) { - return std::make_pair(NN_TRY(nn::convert(outputShapes)), NN_TRY(nn::convert(timing))); +nn::GeneralResult prepareModelCallback( + ErrorStatus status, const sp& preparedModel) { + HANDLE_HAL_STATUS(status) << "model preparation failed with " << toString(status); + return NN_TRY(PreparedModel::create(preparedModel, /*executeSynchronously=*/true)); } -nn::ExecutionResult, nn::Timing>> -convertExecutionGeneralResults(const hidl_vec& outputShapes, - const V1_2::Timing& timing) { +nn::ExecutionResult, nn::Timing>> executionCallback( + ErrorStatus status, const hidl_vec& outputShapes, + const V1_2::Timing& timing) { + if (status == ErrorStatus::OUTPUT_INSUFFICIENT_SIZE) { + auto canonicalOutputShapes = + nn::convert(outputShapes).value_or(std::vector{}); + return NN_ERROR(nn::ErrorStatus::OUTPUT_INSUFFICIENT_SIZE, std::move(canonicalOutputShapes)) + << "execution failed with " << toString(status); + } + HANDLE_HAL_STATUS(status) << "execution failed with " << toString(status); return hal::utils::makeExecutionFailure( convertExecutionGeneralResultsHelper(outputShapes, timing)); } -} // namespace - Return PreparedModelCallback::notify(V1_0::ErrorStatus status, const sp& preparedModel) { - if (status != V1_0::ErrorStatus::NONE) { - const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); - notifyInternal(NN_ERROR(canonical) << "preparedModel failed with " << toString(status)); - } else if (preparedModel == nullptr) { - notifyInternal(NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) - << "Returned preparedModel is nullptr"); - } else { - notifyInternal(convertPreparedModel(preparedModel)); - } + mData.put(V1_0::utils::prepareModelCallback(status, preparedModel)); return Void(); } Return PreparedModelCallback::notify_1_2(V1_0::ErrorStatus status, const sp& preparedModel) { - if (status != V1_0::ErrorStatus::NONE) { - const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); - notifyInternal(NN_ERROR(canonical) << "preparedModel failed with " << toString(status)); - } else if (preparedModel == nullptr) { - notifyInternal(NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) - << "Returned preparedModel is nullptr"); - } else { - notifyInternal(convertPreparedModel(preparedModel)); - } + mData.put(V1_2::utils::prepareModelCallback(status, preparedModel)); return Void(); } Return PreparedModelCallback::notify_1_3(ErrorStatus status, const sp& preparedModel) { - if (status != ErrorStatus::NONE) { - const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); - notifyInternal(NN_ERROR(canonical) << "preparedModel failed with " << toString(status)); - } else if (preparedModel == nullptr) { - notifyInternal(NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) - << "Returned preparedModel is nullptr"); - } else { - notifyInternal(convertPreparedModel(preparedModel)); - } + mData.put(prepareModelCallback(status, preparedModel)); return Void(); } void PreparedModelCallback::notifyAsDeadObject() { - notifyInternal(NN_ERROR(nn::ErrorStatus::DEAD_OBJECT) << "Dead object"); + mData.put(NN_ERROR(nn::ErrorStatus::DEAD_OBJECT) << "Dead object"); } PreparedModelCallback::Data PreparedModelCallback::get() { return mData.take(); } -void PreparedModelCallback::notifyInternal(PreparedModelCallback::Data result) { - mData.put(std::move(result)); -} - // ExecutionCallback methods begin here Return ExecutionCallback::notify(V1_0::ErrorStatus status) { - if (status != V1_0::ErrorStatus::NONE) { - const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); - notifyInternal(NN_ERROR(canonical) << "execute failed with " << toString(status)); - } else { - notifyInternal({}); - } + mData.put(V1_0::utils::executionCallback(status)); return Void(); } Return ExecutionCallback::notify_1_2(V1_0::ErrorStatus status, const hidl_vec& outputShapes, const V1_2::Timing& timing) { - if (status != V1_0::ErrorStatus::NONE) { - const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); - notifyInternal(NN_ERROR(canonical) << "execute failed with " << toString(status)); - } else { - notifyInternal(convertExecutionGeneralResults(outputShapes, timing)); - } + mData.put(V1_2::utils::executionCallback(status, outputShapes, timing)); return Void(); } Return ExecutionCallback::notify_1_3(ErrorStatus status, const hidl_vec& outputShapes, const V1_2::Timing& timing) { - if (status != ErrorStatus::NONE) { - const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); - notifyInternal(NN_ERROR(canonical) << "execute failed with " << toString(status)); - } else { - notifyInternal(convertExecutionGeneralResults(outputShapes, timing)); - } + mData.put(executionCallback(status, outputShapes, timing)); return Void(); } void ExecutionCallback::notifyAsDeadObject() { - notifyInternal(NN_ERROR(nn::ErrorStatus::DEAD_OBJECT) << "Dead object"); + mData.put(NN_ERROR(nn::ErrorStatus::DEAD_OBJECT) << "Dead object"); } ExecutionCallback::Data ExecutionCallback::get() { return mData.take(); } -void ExecutionCallback::notifyInternal(ExecutionCallback::Data result) { - mData.put(std::move(result)); -} - } // namespace android::hardware::neuralnetworks::V1_3::utils diff --git a/neuralnetworks/1.3/utils/src/Conversions.cpp b/neuralnetworks/1.3/utils/src/Conversions.cpp index c89a69f28b..8b7db2b90e 100644 --- a/neuralnetworks/1.3/utils/src/Conversions.cpp +++ b/neuralnetworks/1.3/utils/src/Conversions.cpp @@ -685,4 +685,38 @@ nn::GeneralResult> convert(const std::vector convert(const nn::DeviceStatus& deviceStatus) { + return V1_2::utils::convert(deviceStatus); +} + +nn::GeneralResult convert( + const nn::ExecutionPreference& executionPreference) { + return V1_2::utils::convert(executionPreference); +} + +nn::GeneralResult> convert(const std::vector& extensions) { + return V1_2::utils::convert(extensions); +} + +nn::GeneralResult> convert(const std::vector& handles) { + return V1_2::utils::convert(handles); +} + +nn::GeneralResult> convert( + const std::vector& outputShapes) { + return V1_2::utils::convert(outputShapes); +} + +nn::GeneralResult convert(const nn::DeviceType& deviceType) { + return V1_2::utils::convert(deviceType); +} + +nn::GeneralResult convert(const nn::MeasureTiming& measureTiming) { + return V1_2::utils::convert(measureTiming); +} + +nn::GeneralResult convert(const nn::Timing& timing) { + return V1_2::utils::convert(timing); +} + } // namespace android::hardware::neuralnetworks::V1_3::utils diff --git a/neuralnetworks/1.3/utils/src/Device.cpp b/neuralnetworks/1.3/utils/src/Device.cpp index 60564985de..d710b85070 100644 --- a/neuralnetworks/1.3/utils/src/Device.cpp +++ b/neuralnetworks/1.3/utils/src/Device.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -69,29 +70,27 @@ nn::GeneralResult>> convert( return hidlPreparedModels; } -nn::GeneralResult convert( - nn::GeneralResult> result) { - return NN_TRY(std::move(result)); +nn::GeneralResult capabilitiesCallback(ErrorStatus status, + const Capabilities& capabilities) { + HANDLE_HAL_STATUS(status) << "getting capabilities failed with " << toString(status); + return nn::convert(capabilities); } -nn::GeneralResult initCapabilities(V1_3::IDevice* device) { +nn::GeneralResult getCapabilitiesFrom(V1_3::IDevice* device) { CHECK(device != nullptr); - nn::GeneralResult result = NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) - << "uninitialized"; - const auto cb = [&result](ErrorStatus status, const Capabilities& capabilities) { - if (status != ErrorStatus::NONE) { - const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); - result = NN_ERROR(canonical) << "getCapabilities_1_3 failed with " << toString(status); - } else { - result = nn::convert(capabilities); - } - }; + auto cb = hal::utils::CallbackValue(capabilitiesCallback); const auto ret = device->getCapabilities_1_3(cb); HANDLE_TRANSPORT_FAILURE(ret); - return result; + return cb.take(); +} + +nn::GeneralResult allocationCallback(ErrorStatus status, + const sp& buffer, uint32_t token) { + HANDLE_HAL_STATUS(status) << "IDevice::allocate failed with " << toString(status); + return Buffer::create(buffer, static_cast(token)); } } // namespace @@ -107,12 +106,12 @@ nn::GeneralResult> Device::create(std::string name << "V1_3::utils::Device::create must have non-null device"; } - auto versionString = NN_TRY(V1_2::utils::initVersionString(device.get())); - const auto deviceType = NN_TRY(V1_2::utils::initDeviceType(device.get())); - auto extensions = NN_TRY(V1_2::utils::initExtensions(device.get())); - auto capabilities = NN_TRY(initCapabilities(device.get())); + auto versionString = NN_TRY(V1_2::utils::getVersionStringFrom(device.get())); + const auto deviceType = NN_TRY(V1_2::utils::getDeviceTypeFrom(device.get())); + auto extensions = NN_TRY(V1_2::utils::getSupportedExtensionsFrom(device.get())); + auto capabilities = NN_TRY(getCapabilitiesFrom(device.get())); const auto numberOfCacheFilesNeeded = - NN_TRY(V1_2::utils::initNumberOfCacheFilesNeeded(device.get())); + NN_TRY(V1_2::utils::getNumberOfCacheFilesNeededFrom(device.get())); auto deathHandler = NN_TRY(hal::utils::DeathHandler::create(device)); return std::make_shared( @@ -177,27 +176,12 @@ nn::GeneralResult> Device::getSupportedOperations(const nn::Mo const auto hidlModel = NN_TRY(convert(modelInShared)); - nn::GeneralResult> result = NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) - << "uninitialized"; - auto cb = [&result, &model](ErrorStatus status, const hidl_vec& supportedOperations) { - if (status != ErrorStatus::NONE) { - const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); - result = NN_ERROR(canonical) - << "IDevice::getSupportedOperations_1_3 failed with " << toString(status); - } else if (supportedOperations.size() != model.main.operations.size()) { - result = NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) - << "IDevice::getSupportedOperations_1_3 returned vector of size " - << supportedOperations.size() << " but expected " - << model.main.operations.size(); - } else { - result = supportedOperations; - } - }; + auto cb = hal::utils::CallbackValue(supportedOperationsCallback); const auto ret = kDevice->getSupportedOperations_1_3(hidlModel, cb); HANDLE_TRANSPORT_FAILURE(ret); - return result; + return cb.take(); } nn::GeneralResult Device::prepareModel( @@ -210,12 +194,12 @@ nn::GeneralResult Device::prepareModel( NN_TRY(hal::utils::flushDataFromPointerToShared(&model, &maybeModelInShared)); const auto hidlModel = NN_TRY(convert(modelInShared)); - const auto hidlPreference = NN_TRY(V1_1::utils::convert(preference)); + const auto hidlPreference = NN_TRY(convert(preference)); const auto hidlPriority = NN_TRY(convert(priority)); const auto hidlDeadline = NN_TRY(convert(deadline)); - const auto hidlModelCache = NN_TRY(V1_2::utils::convert(modelCache)); - const auto hidlDataCache = NN_TRY(V1_2::utils::convert(dataCache)); - const auto hidlToken = token; + const auto hidlModelCache = NN_TRY(convert(modelCache)); + const auto hidlDataCache = NN_TRY(convert(dataCache)); + const auto hidlToken = V1_2::utils::CacheToken{token}; const auto cb = sp::make(); const auto scoped = kDeathHandler.protectCallback(cb.get()); @@ -224,10 +208,7 @@ nn::GeneralResult Device::prepareModel( kDevice->prepareModel_1_3(hidlModel, hidlPreference, hidlPriority, hidlDeadline, hidlModelCache, hidlDataCache, hidlToken, cb); const auto status = HANDLE_TRANSPORT_FAILURE(ret); - if (status != ErrorStatus::NONE) { - const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); - return NN_ERROR(canonical) << "prepareModel_1_3 failed with " << toString(status); - } + HANDLE_HAL_STATUS(status) << "model preparation failed with " << toString(status); return cb->get(); } @@ -236,9 +217,9 @@ nn::GeneralResult Device::prepareModelFromCache( nn::OptionalTimePoint deadline, const std::vector& modelCache, const std::vector& dataCache, const nn::CacheToken& token) const { const auto hidlDeadline = NN_TRY(convert(deadline)); - const auto hidlModelCache = NN_TRY(V1_2::utils::convert(modelCache)); - const auto hidlDataCache = NN_TRY(V1_2::utils::convert(dataCache)); - const auto hidlToken = token; + const auto hidlModelCache = NN_TRY(convert(modelCache)); + const auto hidlDataCache = NN_TRY(convert(dataCache)); + const auto hidlToken = V1_2::utils::CacheToken{token}; const auto cb = sp::make(); const auto scoped = kDeathHandler.protectCallback(cb.get()); @@ -246,10 +227,7 @@ nn::GeneralResult Device::prepareModelFromCache( const auto ret = kDevice->prepareModelFromCache_1_3(hidlDeadline, hidlModelCache, hidlDataCache, hidlToken, cb); const auto status = HANDLE_TRANSPORT_FAILURE(ret); - if (status != ErrorStatus::NONE) { - const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); - return NN_ERROR(canonical) << "prepareModelFromCache_1_3 failed with " << toString(status); - } + HANDLE_HAL_STATUS(status) << "model preparation from cache failed with " << toString(status); return cb->get(); } @@ -263,27 +241,13 @@ nn::GeneralResult Device::allocate( const auto hidlInputRoles = NN_TRY(convert(inputRoles)); const auto hidlOutputRoles = NN_TRY(convert(outputRoles)); - nn::GeneralResult result = NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) - << "uninitialized"; - auto cb = [&result](ErrorStatus status, const sp& buffer, uint32_t token) { - if (status != ErrorStatus::NONE) { - const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); - result = NN_ERROR(canonical) << "IDevice::allocate failed with " << toString(status); - } else if (buffer == nullptr) { - result = NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "Returned buffer is nullptr"; - } else if (token == 0) { - result = NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "Returned token is invalid (0)"; - } else { - result = convert( - Buffer::create(buffer, static_cast(token))); - } - }; + auto cb = hal::utils::CallbackValue(allocationCallback); const auto ret = kDevice->allocate(hidlDesc, hidlPreparedModels, hidlInputRoles, hidlOutputRoles, cb); HANDLE_TRANSPORT_FAILURE(ret); - return result; + return cb.take(); } } // namespace android::hardware::neuralnetworks::V1_3::utils diff --git a/neuralnetworks/1.3/utils/src/PreparedModel.cpp b/neuralnetworks/1.3/utils/src/PreparedModel.cpp index 0bae95de87..7b4b7bac3b 100644 --- a/neuralnetworks/1.3/utils/src/PreparedModel.cpp +++ b/neuralnetworks/1.3/utils/src/PreparedModel.cpp @@ -45,25 +45,17 @@ namespace android::hardware::neuralnetworks::V1_3::utils { namespace { -nn::GeneralResult, nn::Timing>> -convertExecutionResultsHelper(const hidl_vec& outputShapes, - const V1_2::Timing& timing) { - return std::make_pair(NN_TRY(nn::convert(outputShapes)), NN_TRY(nn::convert(timing))); -} - -nn::ExecutionResult, nn::Timing>> convertExecutionResults( - const hidl_vec& outputShapes, const V1_2::Timing& timing) { - return hal::utils::makeExecutionFailure(convertExecutionResultsHelper(outputShapes, timing)); -} - nn::GeneralResult> convertFencedExecutionCallbackResults( - const V1_2::Timing& timingLaunched, const V1_2::Timing& timingFenced) { + ErrorStatus status, const V1_2::Timing& timingLaunched, const V1_2::Timing& timingFenced) { + HANDLE_HAL_STATUS(status) << "fenced execution callback info failed with " << toString(status); return std::make_pair(NN_TRY(nn::convert(timingLaunched)), NN_TRY(nn::convert(timingFenced))); } -nn::GeneralResult> -convertExecuteFencedResults(const hidl_handle& syncFence, - const sp& callback) { +nn::GeneralResult> fencedExecutionCallback( + ErrorStatus status, const hidl_handle& syncFence, + const sp& callback) { + HANDLE_HAL_STATUS(status) << "fenced execution failed with " << toString(status); + auto resultSyncFence = nn::SyncFence::createAsSignaled(); if (syncFence.getNativeHandle() != nullptr) { auto sharedHandle = NN_TRY(nn::convert(syncFence)); @@ -78,23 +70,12 @@ convertExecuteFencedResults(const hidl_handle& syncFence, // Create callback which can be used to retrieve the execution error status and timings. nn::ExecuteFencedInfoCallback resultCallback = [callback]() -> nn::GeneralResult> { - nn::GeneralResult> result = - NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "uninitialized"; - auto cb = [&result](ErrorStatus status, const V1_2::Timing& timingLaunched, - const V1_2::Timing& timingFenced) { - if (status != ErrorStatus::NONE) { - const auto canonical = - nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); - result = NN_ERROR(canonical) << "getExecutionInfo failed with " << toString(status); - } else { - result = convertFencedExecutionCallbackResults(timingLaunched, timingFenced); - } - }; + auto cb = hal::utils::CallbackValue(convertFencedExecutionCallbackResults); const auto ret = callback->getExecutionInfo(cb); HANDLE_TRANSPORT_FAILURE(ret); - return result; + return cb.take(); }; return std::make_pair(std::move(resultSyncFence), std::move(resultCallback)); @@ -103,42 +84,34 @@ convertExecuteFencedResults(const hidl_handle& syncFence, } // namespace nn::GeneralResult> PreparedModel::create( - sp preparedModel) { + sp preparedModel, bool executeSynchronously) { if (preparedModel == nullptr) { - return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) - << "V1_3::utils::PreparedModel::create must have non-null preparedModel"; + return NN_ERROR() << "V1_3::utils::PreparedModel::create must have non-null preparedModel"; } auto deathHandler = NN_TRY(hal::utils::DeathHandler::create(preparedModel)); - return std::make_shared(PrivateConstructorTag{}, std::move(preparedModel), - std::move(deathHandler)); + return std::make_shared(PrivateConstructorTag{}, executeSynchronously, + std::move(preparedModel), std::move(deathHandler)); } -PreparedModel::PreparedModel(PrivateConstructorTag /*tag*/, sp preparedModel, +PreparedModel::PreparedModel(PrivateConstructorTag /*tag*/, bool executeSynchronously, + sp preparedModel, hal::utils::DeathHandler deathHandler) - : kPreparedModel(std::move(preparedModel)), kDeathHandler(std::move(deathHandler)) {} + : kExecuteSynchronously(executeSynchronously), + kPreparedModel(std::move(preparedModel)), + kDeathHandler(std::move(deathHandler)) {} nn::ExecutionResult, nn::Timing>> PreparedModel::executeSynchronously(const Request& request, V1_2::MeasureTiming measure, const OptionalTimePoint& deadline, const OptionalTimeoutDuration& loopTimeoutDuration) const { - nn::ExecutionResult, nn::Timing>> result = - NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "uninitialized"; - const auto cb = [&result](ErrorStatus status, const hidl_vec& outputShapes, - const V1_2::Timing& timing) { - if (status != ErrorStatus::NONE) { - const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); - result = NN_ERROR(canonical) << "executeSynchronously failed with " << toString(status); - } else { - result = convertExecutionResults(outputShapes, timing); - } - }; + auto cb = hal::utils::CallbackValue(executionCallback); const auto ret = kPreparedModel->executeSynchronously_1_3(request, measure, deadline, loopTimeoutDuration, cb); HANDLE_TRANSPORT_FAILURE(ret); - return result; + return cb.take(); } nn::ExecutionResult, nn::Timing>> @@ -151,9 +124,8 @@ PreparedModel::executeAsynchronously(const Request& request, V1_2::MeasureTiming const auto ret = kPreparedModel->execute_1_3(request, measure, deadline, loopTimeoutDuration, cb); const auto status = HANDLE_TRANSPORT_FAILURE(ret); - if (status != ErrorStatus::NONE) { - const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); - return NN_ERROR(canonical) << "executeAsynchronously failed with " << toString(status); + if (status != ErrorStatus::OUTPUT_INSUFFICIENT_SIZE) { + HANDLE_HAL_STATUS(status) << "execution failed with " << toString(status); } return cb->get(); @@ -169,35 +141,22 @@ nn::ExecutionResult, nn::Timing>> Prepare hal::utils::flushDataFromPointerToShared(&request, &maybeRequestInShared))); const auto hidlRequest = NN_TRY(hal::utils::makeExecutionFailure(convert(requestInShared))); - const auto hidlMeasure = - NN_TRY(hal::utils::makeExecutionFailure(V1_2::utils::convert(measure))); + const auto hidlMeasure = NN_TRY(hal::utils::makeExecutionFailure(convert(measure))); const auto hidlDeadline = NN_TRY(hal::utils::makeExecutionFailure(convert(deadline))); const auto hidlLoopTimeoutDuration = NN_TRY(hal::utils::makeExecutionFailure(convert(loopTimeoutDuration))); - nn::ExecutionResult, nn::Timing>> result = - NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "uninitialized"; - const bool preferSynchronous = true; + auto result = kExecuteSynchronously + ? executeSynchronously(hidlRequest, hidlMeasure, hidlDeadline, + hidlLoopTimeoutDuration) + : executeAsynchronously(hidlRequest, hidlMeasure, hidlDeadline, + hidlLoopTimeoutDuration); + auto [outputShapes, timing] = NN_TRY(std::move(result)); - // Execute synchronously if allowed. - if (preferSynchronous) { - result = executeSynchronously(hidlRequest, hidlMeasure, hidlDeadline, - hidlLoopTimeoutDuration); - } - - // Run asymchronous execution if execution has not already completed. - if (!result.has_value()) { - result = executeAsynchronously(hidlRequest, hidlMeasure, hidlDeadline, - hidlLoopTimeoutDuration); - } + NN_TRY(hal::utils::makeExecutionFailure( + hal::utils::unflushDataFromSharedToPointer(request, maybeRequestInShared))); - // Flush output buffers if suxcessful execution. - if (result.has_value()) { - NN_TRY(hal::utils::makeExecutionFailure( - hal::utils::unflushDataFromSharedToPointer(request, maybeRequestInShared))); - } - - return result; + return std::make_pair(std::move(outputShapes), timing); } nn::GeneralResult> @@ -212,28 +171,18 @@ PreparedModel::executeFenced(const nn::Request& request, const std::vector> result = - NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "uninitialized"; - auto cb = [&result](ErrorStatus status, const hidl_handle& syncFence, - const sp& callback) { - if (status != ErrorStatus::NONE) { - const auto canonical = nn::convert(status).value_or(nn::ErrorStatus::GENERAL_FAILURE); - result = NN_ERROR(canonical) << "executeFenced failed with " << toString(status); - } else { - result = convertExecuteFencedResults(syncFence, callback); - } - }; + auto cb = hal::utils::CallbackValue(fencedExecutionCallback); const auto ret = kPreparedModel->executeFenced(hidlRequest, hidlWaitFor, hidlMeasure, hidlDeadline, hidlLoopTimeoutDuration, hidlTimeoutDurationAfterFence, cb); HANDLE_TRANSPORT_FAILURE(ret); - auto [syncFence, callback] = NN_TRY(std::move(result)); + auto [syncFence, callback] = NN_TRY(cb.take()); // 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. diff --git a/neuralnetworks/utils/common/include/nnapi/hal/CommonUtils.h b/neuralnetworks/utils/common/include/nnapi/hal/CommonUtils.h index 43bb0c677a..b3989e5878 100644 --- a/neuralnetworks/utils/common/include/nnapi/hal/CommonUtils.h +++ b/neuralnetworks/utils/common/include/nnapi/hal/CommonUtils.h @@ -44,9 +44,18 @@ nn::Capabilities::OperandPerformanceTable makeQuantized8PerformanceConsistentWit bool hasNoPointerData(const nn::Model& model); bool hasNoPointerData(const nn::Request& request); -// Relocate pointer-based data to shared memory. +// Relocate pointer-based data to shared memory. If `model` has no Operand::LifeTime::POINTER data, +// the function returns with a reference to `model`. If `model` has Operand::LifeTime::POINTER data, +// the model is copied to `maybeModelInSharedOut` with the POINTER data relocated to a memory pool, +// and the function returns with a reference to `*maybeModelInSharedOut`. nn::GeneralResult> flushDataFromPointerToShared( const nn::Model* model, std::optional* maybeModelInSharedOut); + +// Relocate pointer-based data to shared memory. If `request` has no +// Request::Argument::LifeTime::POINTER data, the function returns with a reference to `request`. If +// `request` has Request::Argument::LifeTime::POINTER data, the request is copied to +// `maybeRequestInSharedOut` with the POINTER data relocated to a memory pool, and the function +// returns with a reference to `*maybeRequestInSharedOut`. nn::GeneralResult> flushDataFromPointerToShared( const nn::Request* request, std::optional* maybeRequestInSharedOut); diff --git a/neuralnetworks/utils/common/include/nnapi/hal/HandleError.h b/neuralnetworks/utils/common/include/nnapi/hal/HandleError.h index 78b2a12918..95a20a8f80 100644 --- a/neuralnetworks/utils/common/include/nnapi/hal/HandleError.h +++ b/neuralnetworks/utils/common/include/nnapi/hal/HandleError.h @@ -79,4 +79,11 @@ nn::ExecutionResult makeExecutionFailure(nn::Result result, nn::Erro return makeExecutionFailure(makeGeneralFailure(result, status)); } +#define HANDLE_HAL_STATUS(status) \ + if (const auto canonical = ::android::nn::convert(status).value_or( \ + ::android::nn::ErrorStatus::GENERAL_FAILURE); \ + canonical == ::android::nn::ErrorStatus::NONE) { \ + } else \ + return NN_ERROR(canonical) + } // namespace android::hardware::neuralnetworks::utils \ No newline at end of file diff --git a/neuralnetworks/utils/common/include/nnapi/hal/TransferValue.h b/neuralnetworks/utils/common/include/nnapi/hal/TransferValue.h index 7103c6b375..6679afefec 100644 --- a/neuralnetworks/utils/common/include/nnapi/hal/TransferValue.h +++ b/neuralnetworks/utils/common/include/nnapi/hal/TransferValue.h @@ -17,19 +17,60 @@ #ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_TRANSFER_VALUE_H #define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_TRANSFER_VALUE_H +#include #include #include +#include #include #include +#include namespace android::hardware::neuralnetworks::utils { -// This class is thread safe. +// This class adapts a function pointer and offers two affordances: +// 1) This class object can be used to generate a callback (via the implicit conversion operator) +// that can be used to send the result to `CallbackValue` when called. +// 2) This class object can be used to retrieve the result of the callback with `take`. +// +// This class is thread compatible. +template +class CallbackValue final { + public: + using FunctionType = std::add_pointer_t; + using CallbackType = std::function; + + explicit CallbackValue(FunctionType fn); + + // Creates a callback that forwards its arguments to `mFunction` and stores the result in + // `mReturnValue`. + /*implicit*/ operator CallbackType(); // NOLINT(google-explicit-constructor) + + // Take the result of calling `mFunction`. + // Precondition: mReturnValue.has_value() + // Postcondition: !mReturnValue.has_value() + [[nodiscard]] ReturnType take(); + + private: + std::optional mReturnValue; + FunctionType mFunction; +}; + +// Deduction guidelines for CallbackValue when constructed with a function pointer. +template +CallbackValue(ReturnType (*)(ArgTypes...))->CallbackValue; + +// Thread-safe container to pass a value between threads. template class TransferValue final { public: + // Put the value in `TransferValue`. If `TransferValue` already has a value, this function is a + // no-op. void put(Type object) const; + + // Take the value stored in `TransferValue`. If no value is available, this function will block + // until the value becomes available. + // Postcondition: !mObject.has_value() [[nodiscard]] Type take() const; private: @@ -38,7 +79,23 @@ class TransferValue final { mutable std::optional mObject GUARDED_BY(mMutex); }; -// template implementation +// template implementations + +template +CallbackValue::CallbackValue(FunctionType fn) : mFunction(fn) {} + +template +CallbackValue::operator CallbackType() { + return [this](ArgTypes... args) { mReturnValue = mFunction(args...); }; +} + +template +ReturnType CallbackValue::take() { + CHECK(mReturnValue.has_value()); + std::optional object; + std::swap(object, mReturnValue); + return std::move(object).value(); +} template void TransferValue::put(Type object) const { @@ -56,6 +113,7 @@ Type TransferValue::take() const { std::unique_lock lock(mMutex); base::ScopedLockAssertion lockAssertion(mMutex); mCondition.wait(lock, [this]() REQUIRES(mMutex) { return mObject.has_value(); }); + CHECK(mObject.has_value()); std::optional object; std::swap(object, mObject); return std::move(object).value(); -- GitLab From 11761e37a864761382303a75ab29bb0fc0f716c3 Mon Sep 17 00:00:00 2001 From: Michael Butler Date: Tue, 15 Dec 2020 15:20:26 -0800 Subject: [PATCH 340/790] Remove 'blocking' param from NN ResilientPreparedModel and *Buffer This change removes the 'blocking' parameter for the ResilientPreparedModel::Factory and ResilientBuffer::Factory. The 'blocking' parameter is only useful for ResilientDevice::Factory, which behind the scenes chooses between the HIDL calls IDevice::getService and IDevice::tryGetService. The equivalent calls for IPreparedModel and IBuffer are not used, as both are created from the IDevice object. This change also modifies the ResilientDevice's device recovery behavior. Prior to this change, ResilientDevice's recovery mechanism had the following behavior: * attempt to call a function * if the function did not return a DEAD_OBJECT error, return * if the function returned a DEAD_OBJECT error, attempt to recover the device * whether or not the recovery succeeded, call the function again This CL changes the behavior so that if device recovery fails, ResilientDevice will not call the function the second time. Bug: N/A Test: mma Change-Id: Icf37d05c884c740178324fcd046ea56914ef7d44 --- .../include/nnapi/hal/ResilientBuffer.h | 2 +- .../include/nnapi/hal/ResilientDevice.h | 15 ++--- .../nnapi/hal/ResilientPreparedModel.h | 2 +- .../utils/common/src/ResilientBuffer.cpp | 2 +- .../utils/common/src/ResilientDevice.cpp | 65 +++++++++---------- .../common/src/ResilientPreparedModel.cpp | 2 +- 6 files changed, 42 insertions(+), 46 deletions(-) diff --git a/neuralnetworks/utils/common/include/nnapi/hal/ResilientBuffer.h b/neuralnetworks/utils/common/include/nnapi/hal/ResilientBuffer.h index 996ec1ee81..9d5e3e6a05 100644 --- a/neuralnetworks/utils/common/include/nnapi/hal/ResilientBuffer.h +++ b/neuralnetworks/utils/common/include/nnapi/hal/ResilientBuffer.h @@ -34,7 +34,7 @@ class ResilientBuffer final : public nn::IBuffer { struct PrivateConstructorTag {}; public: - using Factory = std::function(bool blocking)>; + using Factory = std::function()>; static nn::GeneralResult> create(Factory makeBuffer); diff --git a/neuralnetworks/utils/common/include/nnapi/hal/ResilientDevice.h b/neuralnetworks/utils/common/include/nnapi/hal/ResilientDevice.h index 4bfed6cd51..84ae799aad 100644 --- a/neuralnetworks/utils/common/include/nnapi/hal/ResilientDevice.h +++ b/neuralnetworks/utils/common/include/nnapi/hal/ResilientDevice.h @@ -46,8 +46,8 @@ class ResilientDevice final : public nn::IDevice, nn::Capabilities capabilities, nn::SharedDevice device); nn::SharedDevice getDevice() const EXCLUDES(mMutex); - nn::SharedDevice recover(const nn::IDevice* failingDevice, bool blocking) const - EXCLUDES(mMutex); + nn::GeneralResult recover(const nn::IDevice* failingDevice, + bool blocking) const EXCLUDES(mMutex); const std::string& getName() const override; const std::string& getVersionString() const override; @@ -81,17 +81,14 @@ class ResilientDevice final : public nn::IDevice, private: bool isValidInternal() const EXCLUDES(mMutex); nn::GeneralResult prepareModelInternal( - bool blocking, const nn::Model& model, nn::ExecutionPreference preference, - nn::Priority priority, nn::OptionalTimePoint deadline, - const std::vector& modelCache, + const nn::Model& model, nn::ExecutionPreference preference, nn::Priority priority, + nn::OptionalTimePoint deadline, const std::vector& modelCache, const std::vector& dataCache, const nn::CacheToken& token) const; nn::GeneralResult prepareModelFromCacheInternal( - bool blocking, nn::OptionalTimePoint deadline, - const std::vector& modelCache, + nn::OptionalTimePoint deadline, const std::vector& modelCache, const std::vector& dataCache, const nn::CacheToken& token) const; nn::GeneralResult allocateInternal( - bool blocking, const nn::BufferDesc& desc, - const std::vector& preparedModels, + const nn::BufferDesc& desc, const std::vector& preparedModels, const std::vector& inputRoles, const std::vector& outputRoles) const; diff --git a/neuralnetworks/utils/common/include/nnapi/hal/ResilientPreparedModel.h b/neuralnetworks/utils/common/include/nnapi/hal/ResilientPreparedModel.h index d86c88be32..faae673ba7 100644 --- a/neuralnetworks/utils/common/include/nnapi/hal/ResilientPreparedModel.h +++ b/neuralnetworks/utils/common/include/nnapi/hal/ResilientPreparedModel.h @@ -34,7 +34,7 @@ class ResilientPreparedModel final : public nn::IPreparedModel { struct PrivateConstructorTag {}; public: - using Factory = std::function(bool blocking)>; + using Factory = std::function()>; static nn::GeneralResult> create( Factory makePreparedModel); diff --git a/neuralnetworks/utils/common/src/ResilientBuffer.cpp b/neuralnetworks/utils/common/src/ResilientBuffer.cpp index 984295b729..cf5496ac39 100644 --- a/neuralnetworks/utils/common/src/ResilientBuffer.cpp +++ b/neuralnetworks/utils/common/src/ResilientBuffer.cpp @@ -36,7 +36,7 @@ nn::GeneralResult> ResilientBuffer::creat return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "utils::ResilientBuffer::create must have non-empty makeBuffer"; } - auto buffer = NN_TRY(makeBuffer(/*blocking=*/true)); + auto buffer = NN_TRY(makeBuffer()); CHECK(buffer != nullptr); return std::make_shared(PrivateConstructorTag{}, std::move(makeBuffer), std::move(buffer)); diff --git a/neuralnetworks/utils/common/src/ResilientDevice.cpp b/neuralnetworks/utils/common/src/ResilientDevice.cpp index 2f83c5c5bd..6ad3fadee6 100644 --- a/neuralnetworks/utils/common/src/ResilientDevice.cpp +++ b/neuralnetworks/utils/common/src/ResilientDevice.cpp @@ -49,7 +49,17 @@ auto protect(const ResilientDevice& resilientDevice, const FnType& fn, bool bloc return result; } - device = resilientDevice.recover(device.get(), blocking); + // Attempt recovery and return if it fails. + auto maybeDevice = resilientDevice.recover(device.get(), blocking); + if (!maybeDevice.has_value()) { + const auto& [resultErrorMessage, resultErrorCode] = result.error(); + const auto& [recoveryErrorMessage, recoveryErrorCode] = maybeDevice.error(); + return nn::error(resultErrorCode) + << resultErrorMessage << ", and failed to recover dead device with error " + << recoveryErrorCode << ": " << recoveryErrorMessage; + } + device = std::move(maybeDevice).value(); + return fn(*device); } @@ -94,7 +104,8 @@ nn::SharedDevice ResilientDevice::getDevice() const { return mDevice; } -nn::SharedDevice ResilientDevice::recover(const nn::IDevice* failingDevice, bool blocking) const { +nn::GeneralResult ResilientDevice::recover(const nn::IDevice* failingDevice, + bool blocking) const { std::lock_guard guard(mMutex); // Another caller updated the failing device. @@ -102,13 +113,7 @@ nn::SharedDevice ResilientDevice::recover(const nn::IDevice* failingDevice, bool return mDevice; } - auto maybeDevice = kMakeDevice(blocking); - if (!maybeDevice.has_value()) { - const auto& [message, code] = maybeDevice.error(); - LOG(ERROR) << "Failed to recover dead device with error " << code << ": " << message; - return mDevice; - } - auto device = std::move(maybeDevice).value(); + auto device = NN_TRY(kMakeDevice(blocking)); // If recovered device has different metadata than what is cached (i.e., because it was // updated), mark the device as invalid and preserve the cached data. @@ -176,11 +181,11 @@ nn::GeneralResult ResilientDevice::prepareModel( nn::OptionalTimePoint deadline, const std::vector& modelCache, const std::vector& dataCache, const nn::CacheToken& token) const { auto self = shared_from_this(); - ResilientPreparedModel::Factory makePreparedModel = - [device = std::move(self), model, preference, priority, deadline, modelCache, dataCache, - token](bool blocking) -> nn::GeneralResult { - return device->prepareModelInternal(blocking, model, preference, priority, deadline, - modelCache, dataCache, token); + ResilientPreparedModel::Factory makePreparedModel = [device = std::move(self), model, + preference, priority, deadline, modelCache, + dataCache, token] { + return device->prepareModelInternal(model, preference, priority, deadline, modelCache, + dataCache, token); }; return ResilientPreparedModel::create(std::move(makePreparedModel)); } @@ -189,11 +194,9 @@ nn::GeneralResult ResilientDevice::prepareModelFromCach nn::OptionalTimePoint deadline, const std::vector& modelCache, const std::vector& dataCache, const nn::CacheToken& token) const { auto self = shared_from_this(); - ResilientPreparedModel::Factory makePreparedModel = - [device = std::move(self), deadline, modelCache, dataCache, - token](bool blocking) -> nn::GeneralResult { - return device->prepareModelFromCacheInternal(blocking, deadline, modelCache, dataCache, - token); + ResilientPreparedModel::Factory makePreparedModel = [device = std::move(self), deadline, + modelCache, dataCache, token] { + return device->prepareModelFromCacheInternal(deadline, modelCache, dataCache, token); }; return ResilientPreparedModel::create(std::move(makePreparedModel)); } @@ -203,10 +206,9 @@ nn::GeneralResult ResilientDevice::allocate( const std::vector& inputRoles, const std::vector& outputRoles) const { auto self = shared_from_this(); - ResilientBuffer::Factory makeBuffer = - [device = std::move(self), desc, preparedModels, inputRoles, - outputRoles](bool blocking) -> nn::GeneralResult { - return device->allocateInternal(blocking, desc, preparedModels, inputRoles, outputRoles); + ResilientBuffer::Factory makeBuffer = [device = std::move(self), desc, preparedModels, + inputRoles, outputRoles] { + return device->allocateInternal(desc, preparedModels, inputRoles, outputRoles); }; return ResilientBuffer::create(std::move(makeBuffer)); } @@ -217,9 +219,8 @@ bool ResilientDevice::isValidInternal() const { } nn::GeneralResult ResilientDevice::prepareModelInternal( - bool blocking, const nn::Model& model, nn::ExecutionPreference preference, - nn::Priority priority, nn::OptionalTimePoint deadline, - const std::vector& modelCache, + const nn::Model& model, nn::ExecutionPreference preference, nn::Priority priority, + nn::OptionalTimePoint deadline, const std::vector& modelCache, const std::vector& dataCache, const nn::CacheToken& token) const { if (!isValidInternal()) { return std::make_shared(); @@ -229,12 +230,11 @@ nn::GeneralResult ResilientDevice::prepareModelInternal return device.prepareModel(model, preference, priority, deadline, modelCache, dataCache, token); }; - return protect(*this, fn, blocking); + return protect(*this, fn, /*blocking=*/false); } nn::GeneralResult ResilientDevice::prepareModelFromCacheInternal( - bool blocking, nn::OptionalTimePoint deadline, - const std::vector& modelCache, + nn::OptionalTimePoint deadline, const std::vector& modelCache, const std::vector& dataCache, const nn::CacheToken& token) const { if (!isValidInternal()) { return std::make_shared(); @@ -242,12 +242,11 @@ nn::GeneralResult ResilientDevice::prepareModelFromCach const auto fn = [deadline, &modelCache, &dataCache, token](const nn::IDevice& device) { return device.prepareModelFromCache(deadline, modelCache, dataCache, token); }; - return protect(*this, fn, blocking); + return protect(*this, fn, /*blocking=*/false); } nn::GeneralResult ResilientDevice::allocateInternal( - bool blocking, const nn::BufferDesc& desc, - const std::vector& preparedModels, + const nn::BufferDesc& desc, const std::vector& preparedModels, const std::vector& inputRoles, const std::vector& outputRoles) const { if (!isValidInternal()) { @@ -256,7 +255,7 @@ nn::GeneralResult ResilientDevice::allocateInternal( const auto fn = [&desc, &preparedModels, &inputRoles, &outputRoles](const nn::IDevice& device) { return device.allocate(desc, preparedModels, inputRoles, outputRoles); }; - return protect(*this, fn, blocking); + return protect(*this, fn, /*blocking=*/false); } } // namespace android::hardware::neuralnetworks::utils diff --git a/neuralnetworks/utils/common/src/ResilientPreparedModel.cpp b/neuralnetworks/utils/common/src/ResilientPreparedModel.cpp index 012a1dedc3..b8acee16c9 100644 --- a/neuralnetworks/utils/common/src/ResilientPreparedModel.cpp +++ b/neuralnetworks/utils/common/src/ResilientPreparedModel.cpp @@ -36,7 +36,7 @@ nn::GeneralResult> ResilientPrepar return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "utils::ResilientPreparedModel::create must have non-empty makePreparedModel"; } - auto preparedModel = NN_TRY(makePreparedModel(/*blocking=*/true)); + auto preparedModel = NN_TRY(makePreparedModel()); CHECK(preparedModel != nullptr); return std::make_shared( PrivateConstructorTag{}, std::move(makePreparedModel), std::move(preparedModel)); -- GitLab From e351e3b3215cdfab62db6a5a4734b1d9ece6aa45 Mon Sep 17 00:00:00 2001 From: Anthony Stange Date: Tue, 15 Dec 2020 11:06:14 -0500 Subject: [PATCH 341/790] Update Contexthub HAL 1.2 Update Contexthub HAL 1.2 to support passing permissions information about host apps and nanoapps to the HAL and contexthub framework. Bug: 166846988 Test: hidl-gen && Run VTS against default HAL Change-Id: I483cb066b3228c4a80bab8f12f8bfee2610c9e6b --- contexthub/1.2/Android.bp | 1 + contexthub/1.2/IContexthub.hal | 30 +++++++++++++++++ contexthub/1.2/IContexthubCallback.hal | 45 ++++++++++++++++++++++++++ contexthub/1.2/types.hal | 35 ++++++++++++++++++++ current.txt | 4 +-- 5 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 contexthub/1.2/IContexthubCallback.hal diff --git a/contexthub/1.2/Android.bp b/contexthub/1.2/Android.bp index e81948234a..9722a97ee6 100644 --- a/contexthub/1.2/Android.bp +++ b/contexthub/1.2/Android.bp @@ -6,6 +6,7 @@ hidl_interface { srcs: [ "types.hal", "IContexthub.hal", + "IContexthubCallback.hal", ], interfaces: [ "android.hardware.contexthub@1.0", diff --git a/contexthub/1.2/IContexthub.hal b/contexthub/1.2/IContexthub.hal index 819fc1d6e1..3488b7446c 100644 --- a/contexthub/1.2/IContexthub.hal +++ b/contexthub/1.2/IContexthub.hal @@ -16,10 +16,40 @@ package android.hardware.contexthub@1.2; +import @1.0::Result; import @1.1::IContexthub; import @1.1::SettingValue; +import IContexthubCallback; interface IContexthub extends @1.1::IContexthub { + /** + * Register a callback for the HAL implementation to send asynchronous + * messages to the service from a context hub. There can be a maximum of + * one callback registered with the HAL. A call to this function when a + * callback has already been registered must override the previous + * registration. + * + * @param hubId identifier for the hub + * @param callback an implementation of the IContextHubCallbacks + * + * @return result OK on success + * BAD_VALUE if parameters are not valid + * + */ + registerCallback_1_2(uint32_t hubId, IContexthubCallback cb) generates (Result result); + + /** + * Send a message to a hub + * + * @param hubId identifier for hub to send message to + * @param msg message to be sent + * + * @return result OK if successful, error code otherwise + * BAD_VALUE if parameters are not valid + * TRANSACTION_FAILED if message send failed + */ + sendMessageToHub_1_2(uint32_t hubId, ContextHubMsg msg) generates (Result result); + /** * Notification sent by the framework to indicate that the user * has changed a setting. diff --git a/contexthub/1.2/IContexthubCallback.hal b/contexthub/1.2/IContexthubCallback.hal new file mode 100644 index 0000000000..0236160305 --- /dev/null +++ b/contexthub/1.2/IContexthubCallback.hal @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.contexthub@1.2; + +import @1.0::IContexthubCallback; + +interface IContexthubCallback extends @1.0::IContexthubCallback { + /** + * This callback is passed by the Contexthub service to the HAL + * implementation to allow the HAL to send asynchronous messages back + * to the service and registered clients of the ContextHub service. + * + * @param msg message that should be delivered to host app clients + * + */ + handleClientMsg_1_2(ContextHubMsg msg); + + /** + * This callback is passed by the Contexthub service to the HAL + * implementation to allow the HAL to send information about the + * currently loaded and active nanoapps on the hub. + * + * @param appInfo vector of HubAppinfo structure for each nanoApp + * on the hub that can be enabled, disabled and + * unloaded by the service. Any nanoApps that cannot + * be controlled by the service must not be reported. + * All nanoApps that can be controlled by the service + * must be reported. + */ + handleAppsInfo_1_2(vec appInfo); +}; diff --git a/contexthub/1.2/types.hal b/contexthub/1.2/types.hal index 38f9f7af55..e6c8acc57d 100644 --- a/contexthub/1.2/types.hal +++ b/contexthub/1.2/types.hal @@ -16,6 +16,8 @@ package android.hardware.contexthub@1.2; +import @1.0::ContextHubMsg; +import @1.0::HubAppInfo; import @1.1::Setting; /** @@ -32,3 +34,36 @@ enum Setting : @1.1::Setting { WIFI_AVAILABLE, AIRPLANE_MODE, }; + +struct ContextHubMsg { + @1.0::ContextHubMsg msg_1_0; + + /** + * The list of Android permissions that the sender of this message has at + * the time the message was sent. + * + * The HAL MUST drop messages to nanoapps if this list of permissions is not + * a superset of those of the receiving nanoapp(s). + * + * The framework MUST drop messages to host apps that don't have a superset + * of the permissions that the sending nanoapp is using. + */ + vec permissions; +}; + +struct HubAppInfo { + @1.0::HubAppInfo info_1_0; + + /** + * The list of Android permissions used by this nanoapp. This list MUST + * correspond to the permissions required for an equivalent Android app to + * sample similar signals through the Android framework. + * + * For example, if a nanoapp used location-based signals, the permissions + * list MUST contains android.permission.ACCESS_FINE_LOCATION and + * android.permission.ACCESS_BACKGROUND_LOCATION. If it were to also list to + * audio data, it would require adding android.permission.RECORD_AUDIO to + * this list. + */ + vec permissions; +}; diff --git a/current.txt b/current.txt index 8623fc001b..0b88a7a835 100644 --- a/current.txt +++ b/current.txt @@ -787,6 +787,4 @@ b9fbb6e2e061ed0960939d48b785e9700210add1f13ed32ecd688d0f1ca20ef7 android.hardwar # HALs released in Android S # NOTE: waiting to freeze HALs until later in the release -# NOTE: new HALs are recommended to be in AIDL -6e64b33f1b720b66b0deb5e08dee37a99deaa94e2e9ebf7806703cabab56e21d android.hardware.contexthub@1.2::IContexthub -3fb83f4539cab2c7bf9fdbecf7265d1c1dd6e8de9694046fe512b493c127ccea android.hardware.contexthub@1.2::types +# NOTE: new HALs are recommended to be in AIDL \ No newline at end of file -- GitLab From 6c77c35406c7de17a12a8b40f4f2e1d430a71320 Mon Sep 17 00:00:00 2001 From: Anthony Stange Date: Wed, 16 Dec 2020 12:50:08 -0500 Subject: [PATCH 342/790] Add stubs for new contexthub v1.2 methods Bug: 166846988 Test: compile Change-Id: Iccf32340f9fa024a26832090f1e0835198546946 --- contexthub/1.2/default/Contexthub.cpp | 13 +++++++++++++ contexthub/1.2/default/Contexthub.h | 7 +++++++ 2 files changed, 20 insertions(+) diff --git a/contexthub/1.2/default/Contexthub.cpp b/contexthub/1.2/default/Contexthub.cpp index d7ac7bf30e..8bc028eda2 100644 --- a/contexthub/1.2/default/Contexthub.cpp +++ b/contexthub/1.2/default/Contexthub.cpp @@ -17,12 +17,25 @@ #include +using ::android::hardware::contexthub::V1_0::Result; + namespace android { namespace hardware { namespace contexthub { namespace V1_2 { namespace implementation { +// TODO(b/166846988): Implement new methods. +Return Contexthub::registerCallback_1_2(uint32_t /* hubId */, + const sp& /* cb */) { + return Result::UNKNOWN_FAILURE; +} + +Return Contexthub::sendMessageToHub_1_2(uint32_t /* hubId */, + const ContextHubMsg& /* msg */) { + return Result::UNKNOWN_FAILURE; +} + Return Contexthub::onSettingChanged(SettingV1_1 /*setting*/, SettingValue /*newValue*/) { return Void(); } diff --git a/contexthub/1.2/default/Contexthub.h b/contexthub/1.2/default/Contexthub.h index d2f8d69afc..c85d3b3b63 100644 --- a/contexthub/1.2/default/Contexthub.h +++ b/contexthub/1.2/default/Contexthub.h @@ -27,10 +27,17 @@ namespace implementation { class Contexthub : public ::android::hardware::contexthub::V1_X::implementation::ContextHub { + using ContextHubMsg = ::android::hardware::contexthub::V1_2::ContextHubMsg; + using IContexthubCallback = ::android::hardware::contexthub::V1_2::IContexthubCallback; + using Result = ::android::hardware::contexthub::V1_0::Result; using SettingValue = ::android::hardware::contexthub::V1_1::SettingValue; using SettingV1_1 = ::android::hardware::contexthub::V1_1::Setting; public: + Return registerCallback_1_2(uint32_t hubId, const sp& cb) override; + + Return sendMessageToHub_1_2(uint32_t hubId, const ContextHubMsg& msg) override; + // Methods from V1_1::IContexthub Return onSettingChanged(SettingV1_1 setting, SettingValue newValue) override; -- GitLab From 100aa5eda108c406bf0244062d033d136a02badf Mon Sep 17 00:00:00 2001 From: Anthony Stange Date: Thu, 17 Dec 2020 14:20:02 -0500 Subject: [PATCH 343/790] Add new contexthub HAL 1.2 methods to default impl Bug: 166846988 Test: Run VTS against default HAL Change-Id: I158a49e54f340a2ba25f79894d6ec465070326f8 --- contexthub/1.1/default/Contexthub.cpp | 19 +++ contexthub/1.1/default/Contexthub.h | 10 ++ contexthub/1.2/default/Android.bp | 1 + contexthub/1.2/default/Contexthub.cpp | 38 +++++- contexthub/1.2/default/Contexthub.h | 17 ++- contexthub/common/default/1.X/ContextHub.h | 21 +-- contexthub/common/default/1.X/OWNERS | 3 + .../common/default/1.X/utils/Android.bp | 30 +++++ .../1.X/utils/IContextHubCallbackWrapper.h | 123 ++++++++++++++++++ 9 files changed, 233 insertions(+), 29 deletions(-) create mode 100644 contexthub/common/default/1.X/OWNERS create mode 100644 contexthub/common/default/1.X/utils/Android.bp create mode 100644 contexthub/common/default/1.X/utils/IContextHubCallbackWrapper.h diff --git a/contexthub/1.1/default/Contexthub.cpp b/contexthub/1.1/default/Contexthub.cpp index e7fde84058..2d4fbaee24 100644 --- a/contexthub/1.1/default/Contexthub.cpp +++ b/contexthub/1.1/default/Contexthub.cpp @@ -23,10 +23,29 @@ namespace contexthub { namespace V1_1 { namespace implementation { +using ::android::hardware::contexthub::V1_0::Result; + Return Contexthub::onSettingChanged(Setting /*setting*/, SettingValue /*newValue*/) { return Void(); } +Return Contexthub::registerCallback(uint32_t hubId, const sp& cb) { + if (hubId == kMockHubId) { + mCallback = cb; + return Result::OK; + } + return Result::BAD_PARAMS; +} + +Return Contexthub::queryApps(uint32_t hubId) { + if (hubId == kMockHubId && mCallback != nullptr) { + std::vector nanoapps; + mCallback->handleAppsInfo(nanoapps); + return Result::OK; + } + return Result::BAD_PARAMS; +} + } // namespace implementation } // namespace V1_1 } // namespace contexthub diff --git a/contexthub/1.1/default/Contexthub.h b/contexthub/1.1/default/Contexthub.h index 1468fcfc0e..648749e27a 100644 --- a/contexthub/1.1/default/Contexthub.h +++ b/contexthub/1.1/default/Contexthub.h @@ -27,9 +27,19 @@ namespace implementation { class Contexthub : public ::android::hardware::contexthub::V1_X::implementation::ContextHub { + using Result = ::android::hardware::contexthub::V1_0::Result; + public: + // Methods from V1_0::IContexthub + Return registerCallback(uint32_t hubId, const sp& cb) override; + + Return queryApps(uint32_t hubId) override; + // Methods from V1_1::IContexthub Return onSettingChanged(Setting setting, SettingValue newValue) override; + + private: + sp mCallback; }; } // namespace implementation diff --git a/contexthub/1.2/default/Android.bp b/contexthub/1.2/default/Android.bp index 49b54fc007..0a31325811 100644 --- a/contexthub/1.2/default/Android.bp +++ b/contexthub/1.2/default/Android.bp @@ -41,6 +41,7 @@ cc_binary { ], header_libs: [ "android.hardware.contexthub@1.X-common-impl", + "android.hardware.contexthub@1.X-common-utils", ], vintf_fragments: ["android.hardware.contexthub@1.2.xml"], } diff --git a/contexthub/1.2/default/Contexthub.cpp b/contexthub/1.2/default/Contexthub.cpp index 8bc028eda2..db0c5bc3df 100644 --- a/contexthub/1.2/default/Contexthub.cpp +++ b/contexthub/1.2/default/Contexthub.cpp @@ -17,23 +17,47 @@ #include -using ::android::hardware::contexthub::V1_0::Result; - namespace android { namespace hardware { namespace contexthub { namespace V1_2 { namespace implementation { -// TODO(b/166846988): Implement new methods. -Return Contexthub::registerCallback_1_2(uint32_t /* hubId */, - const sp& /* cb */) { - return Result::UNKNOWN_FAILURE; +using ::android::hardware::contexthub::V1_0::Result; +using ::android::hardware::contexthub::V1_X::implementation::IContextHubCallbackWrapperV1_0; +using ::android::hardware::contexthub::V1_X::implementation::IContextHubCallbackWrapperV1_2; + +Return Contexthub::registerCallback(uint32_t hubId, + const sp& cb) { + if (hubId == kMockHubId) { + mCallback = new IContextHubCallbackWrapperV1_0(cb); + return Result::OK; + } + return Result::BAD_PARAMS; +} + +Return Contexthub::queryApps(uint32_t hubId) { + if (hubId == kMockHubId && mCallback != nullptr) { + std::vector nanoapps; + mCallback->handleAppsInfo(nanoapps); + return Result::OK; + } + return Result::BAD_PARAMS; +} + +Return Contexthub::registerCallback_1_2(uint32_t hubId, + const sp& cb) { + if (hubId == kMockHubId) { + mCallback = new IContextHubCallbackWrapperV1_2(cb); + return Result::OK; + } + return Result::BAD_PARAMS; } +// We don't expose any nanoapps, therefore all nanoapp-related API calls return with BAD_PARAMS Return Contexthub::sendMessageToHub_1_2(uint32_t /* hubId */, const ContextHubMsg& /* msg */) { - return Result::UNKNOWN_FAILURE; + return Result::BAD_PARAMS; } Return Contexthub::onSettingChanged(SettingV1_1 /*setting*/, SettingValue /*newValue*/) { diff --git a/contexthub/1.2/default/Contexthub.h b/contexthub/1.2/default/Contexthub.h index c85d3b3b63..8b89824d6b 100644 --- a/contexthub/1.2/default/Contexthub.h +++ b/contexthub/1.2/default/Contexthub.h @@ -16,6 +16,7 @@ #pragma once #include "ContextHub.h" +#include "IContextHubCallbackWrapper.h" #include @@ -29,20 +30,32 @@ class Contexthub : public ::android::hardware::contexthub::V1_X::implementation::ContextHub { using ContextHubMsg = ::android::hardware::contexthub::V1_2::ContextHubMsg; using IContexthubCallback = ::android::hardware::contexthub::V1_2::IContexthubCallback; + using IContextHubCallbackWrapperBase = + ::android::hardware::contexthub::V1_X::implementation::IContextHubCallbackWrapperBase; using Result = ::android::hardware::contexthub::V1_0::Result; using SettingValue = ::android::hardware::contexthub::V1_1::SettingValue; using SettingV1_1 = ::android::hardware::contexthub::V1_1::Setting; public: - Return registerCallback_1_2(uint32_t hubId, const sp& cb) override; + // Methods from V1_0::IContexthub + Return registerCallback(uint32_t hubId, + const sp& cb) override; - Return sendMessageToHub_1_2(uint32_t hubId, const ContextHubMsg& msg) override; + Return queryApps(uint32_t hubId) override; // Methods from V1_1::IContexthub Return onSettingChanged(SettingV1_1 setting, SettingValue newValue) override; // Methods from V1_2::IContexthub Return onSettingChanged_1_2(Setting setting, SettingValue newValue) override; + + Return registerCallback_1_2(uint32_t hubId, + const sp& cb) override; + + Return sendMessageToHub_1_2(uint32_t hubId, const ContextHubMsg& msg) override; + + private: + sp mCallback; }; } // namespace implementation diff --git a/contexthub/common/default/1.X/ContextHub.h b/contexthub/common/default/1.X/ContextHub.h index 73d06319dd..00f74afa1b 100644 --- a/contexthub/common/default/1.X/ContextHub.h +++ b/contexthub/common/default/1.X/ContextHub.h @@ -60,14 +60,6 @@ struct ContextHub : public IContextHubInterface { return Void(); } - Return registerCallback(uint32_t hubId, const sp& cb) override { - if (hubId == kMockHubId) { - mCallback = cb; - return Result::OK; - } - return Result::BAD_PARAMS; - } - // We don't expose any nanoapps, therefore all nanoapp-related API calls return with BAD_PARAMS Return sendMessageToHub(uint32_t /*hubId*/, const ContextHubMsg& /*msg*/) override { return Result::BAD_PARAMS; @@ -93,19 +85,8 @@ struct ContextHub : public IContextHubInterface { return Result::BAD_PARAMS; } - Return queryApps(uint32_t hubId) override { - if (hubId == kMockHubId && mCallback != nullptr) { - std::vector nanoapps; - mCallback->handleAppsInfo(nanoapps); - return Result::OK; - } - return Result::BAD_PARAMS; - } - - private: + protected: static constexpr uint32_t kMockHubId = 0; - - sp mCallback; }; } // namespace implementation diff --git a/contexthub/common/default/1.X/OWNERS b/contexthub/common/default/1.X/OWNERS new file mode 100644 index 0000000000..90c233030e --- /dev/null +++ b/contexthub/common/default/1.X/OWNERS @@ -0,0 +1,3 @@ +arthuri@google.com +bduddie@google.com +stange@google.com diff --git a/contexthub/common/default/1.X/utils/Android.bp b/contexthub/common/default/1.X/utils/Android.bp new file mode 100644 index 0000000000..c74b647413 --- /dev/null +++ b/contexthub/common/default/1.X/utils/Android.bp @@ -0,0 +1,30 @@ +// +// 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. + +cc_library_headers { + name: "android.hardware.contexthub@1.X-common-utils", + vendor_available: true, + defaults: ["hidl_defaults"], + export_include_dirs: ["."], + shared_libs: [ + "android.hardware.contexthub@1.0", + "android.hardware.contexthub@1.1", + "android.hardware.contexthub@1.2", + "libbinder", + "libcutils", + "libhidlbase", + "libutils", + ], +} diff --git a/contexthub/common/default/1.X/utils/IContextHubCallbackWrapper.h b/contexthub/common/default/1.X/utils/IContextHubCallbackWrapper.h new file mode 100644 index 0000000000..df78438750 --- /dev/null +++ b/contexthub/common/default/1.X/utils/IContextHubCallbackWrapper.h @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_CONTEXTHUB_V1_X_ICONTEXTHUBCALLBACKWRAPPER_H +#define ANDROID_HARDWARE_CONTEXTHUB_V1_X_ICONTEXTHUBCALLBACKWRAPPER_H + +#include "android/hardware/contexthub/1.0/IContexthub.h" +#include "android/hardware/contexthub/1.0/IContexthubCallback.h" +#include "android/hardware/contexthub/1.0/types.h" +#include "android/hardware/contexthub/1.2/IContexthubCallback.h" +#include "android/hardware/contexthub/1.2/types.h" + +#include + +#include + +namespace android { +namespace hardware { +namespace contexthub { +namespace V1_X { +namespace implementation { + +inline V1_0::ContextHubMsg convertToOldMsg(V1_2::ContextHubMsg msg) { + return msg.msg_1_0; +} + +inline hidl_vec convertToOldAppInfo(hidl_vec appInfos) { + hidl_vec convertedInfo(appInfos.size()); + for (int i = 0; i < appInfos.size(); ++i) { + convertedInfo[i] = appInfos[i].info_1_0; + } + + return convertedInfo; +} + +/** + * The IContexthubCallback classes below abstract away the common logic between both the V1.0, and + * V1.2 versions of the Contexthub HAL callback interface. This allows users of these classes to + * only care about the HAL version at init time and then interact with either version of the + * callback without worrying about the class type by utilizing the base class. + */ +class IContextHubCallbackWrapperBase : public VirtualLightRefBase { + public: + virtual Return handleClientMsg(V1_2::ContextHubMsg msg) = 0; + + virtual Return handleTxnResult(uint32_t txnId, V1_0::TransactionResult result) = 0; + + virtual Return handleHubEvent(V1_0::AsyncEventType evt) = 0; + + virtual Return handleAppAbort(uint64_t appId, uint32_t abortCode) = 0; + + virtual Return handleAppsInfo(hidl_vec appInfo) = 0; +}; + +template +class ContextHubCallbackWrapper : public IContextHubCallbackWrapperBase { + public: + ContextHubCallbackWrapper(sp callback) : mCallback(callback){}; + + virtual Return handleClientMsg(V1_2::ContextHubMsg msg) override { + return mCallback->handleClientMsg(convertToOldMsg(msg)); + } + + virtual Return handleTxnResult(uint32_t txnId, V1_0::TransactionResult result) override { + return mCallback->handleTxnResult(txnId, result); + } + + virtual Return handleHubEvent(V1_0::AsyncEventType evt) override { + return mCallback->handleHubEvent(evt); + } + + virtual Return handleAppAbort(uint64_t appId, uint32_t abortCode) override { + return mCallback->handleAppAbort(appId, abortCode); + } + + virtual Return handleAppsInfo(hidl_vec appInfo) override { + return mCallback->handleAppsInfo(convertToOldAppInfo(appInfo)); + } + + protected: + sp mCallback; +}; + +class IContextHubCallbackWrapperV1_0 : public ContextHubCallbackWrapper { + public: + IContextHubCallbackWrapperV1_0(sp callback) + : ContextHubCallbackWrapper(callback){}; +}; + +class IContextHubCallbackWrapperV1_2 : public ContextHubCallbackWrapper { + public: + IContextHubCallbackWrapperV1_2(sp callback) + : ContextHubCallbackWrapper(callback){}; + + Return handleClientMsg(V1_2::ContextHubMsg msg) override { + return mCallback->handleClientMsg_1_2(msg); + } + + Return handleAppsInfo(hidl_vec appInfo) override { + return mCallback->handleAppsInfo_1_2(appInfo); + } +}; + +} // namespace implementation +} // namespace V1_X +} // namespace contexthub +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_CONTEXTHUB_V1_X_ICONTEXTHUBCALLBACKWRAPPER_H \ No newline at end of file -- GitLab From 2ca7a118100304dd9ae986f8b3af6e31a4a3dba9 Mon Sep 17 00:00:00 2001 From: Kai Shi Date: Tue, 15 Dec 2020 19:51:28 -0800 Subject: [PATCH 344/790] Add voip optimization HAL API Test: compilation and halutil test Bug: 166311728 Change-Id: I3173e733abe158e1b009ed8378d1963ca3b8b8e8 --- wifi/1.5/default/wifi_legacy_hal.cpp | 105 +++++++++++++++++++++ wifi/1.5/default/wifi_legacy_hal.h | 34 +++++++ wifi/1.5/default/wifi_legacy_hal_stubs.cpp | 9 +- 3 files changed, 147 insertions(+), 1 deletion(-) diff --git a/wifi/1.5/default/wifi_legacy_hal.cpp b/wifi/1.5/default/wifi_legacy_hal.cpp index 773dd9b4f3..e1a5a8c957 100644 --- a/wifi/1.5/default/wifi_legacy_hal.cpp +++ b/wifi/1.5/default/wifi_legacy_hal.cpp @@ -343,6 +343,43 @@ void onAsyncNanEventScheduleUpdate(NanDataPathScheduleUpdateInd* event) { on_nan_event_schedule_update_user_callback(*event); } } + +// Callbacks for the various TWT operations. +std::function + 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) { + on_twt_event_setup_response_callback(*event); + } +} + +std::function + 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) { + on_twt_event_teardown_completion_callback(*event); + } +} + +std::function + 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) { + on_twt_event_info_frame_received_callback(*event); + } +} + +std::function on_twt_event_device_notify_callback; +void onAsyncTwtEventDeviceNotify(TwtDeviceNotify* event) { + const auto lock = hidl_sync_util::acquireGlobalLock(); + if (on_twt_event_device_notify_callback && event) { + on_twt_event_device_notify_callback(*event); + } +} + // End of the free-standing "C" style callbacks. WifiLegacyHal::WifiLegacyHal( @@ -1529,6 +1566,70 @@ wifi_error WifiLegacyHal::setCoexUnsafeChannels( 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::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_device_notify_callback = user_callbacks.on_device_notify; + + return global_func_table_.wifi_twt_register_handler( + getIfaceHandle(iface_name), + {onAsyncTwtEventSetupResponse, onAsyncTwtEventTeardownCompletion, + onAsyncTwtEventInfoFrameReceived, onAsyncTwtEventDeviceNotify}); +} + +std::pair WifiLegacyHal::twtGetCapability( + const std::string& iface_name) { + TwtCapabilitySet 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); +} + +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); +} + +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); +} + +std::pair 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); + 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); +} + void WifiLegacyHal::invalidate() { global_handle_ = nullptr; iface_name_to_handle_.clear(); @@ -1560,6 +1661,10 @@ void WifiLegacyHal::invalidate() { on_nan_event_range_request_user_callback = nullptr; on_nan_event_range_report_user_callback = nullptr; on_nan_event_schedule_update_user_callback = nullptr; + on_twt_event_setup_response_callback = nullptr; + on_twt_event_teardown_completion_callback = nullptr; + on_twt_event_info_frame_received_callback = nullptr; + on_twt_event_device_notify_callback = nullptr; } } // namespace legacy_hal diff --git a/wifi/1.5/default/wifi_legacy_hal.h b/wifi/1.5/default/wifi_legacy_hal.h index 6266cf6fd5..11efe7efef 100644 --- a/wifi/1.5/default/wifi_legacy_hal.h +++ b/wifi/1.5/default/wifi_legacy_hal.h @@ -164,6 +164,18 @@ typedef struct { using on_radio_mode_change_callback = std::function&)>; +// TWT response and event callbacks struct. +struct TwtCallbackHandlers { + // Callback for TWT setup response + std::function on_setup_response; + // Callback for TWT teardown completion + std::function on_teardown_completion; + // Callback for TWT info frame received event + std::function on_info_frame_received; + // Callback for TWT notification from the device + std::function on_device_notify; +}; + /** * Class that encapsulates all legacy HAL interactions. * This class manages the lifetime of the event loop thread used by legacy HAL. @@ -391,6 +403,28 @@ class WifiLegacyHal { std::vector 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 twtGetCapability( + const std::string& iface_name); + + wifi_error twtSetupRequest(const std::string& iface_name, + const TwtSetupRequest& msg); + + wifi_error twtTearDownRequest(const std::string& iface_name, + const TwtTeardownRequest& msg); + + wifi_error twtInfoFrameRequest(const std::string& iface_name, + const TwtInfoFrameRequest& msg); + + std::pair twtGetStats(const std::string& iface_name, + uint8_t configId); + + wifi_error twtClearStats(const std::string& iface_name, uint8_t configId); + private: // Retrieve interface handles for all the available interfaces. wifi_error retrieveIfaceHandles(); diff --git a/wifi/1.5/default/wifi_legacy_hal_stubs.cpp b/wifi/1.5/default/wifi_legacy_hal_stubs.cpp index b6c908b0d2..4b005d6809 100644 --- a/wifi/1.5/default/wifi_legacy_hal_stubs.cpp +++ b/wifi/1.5/default/wifi_legacy_hal_stubs.cpp @@ -150,7 +150,14 @@ bool initHalFuncTableWithStubs(wifi_hal_fn* hal_fn) { populateStubFor(&hal_fn->wifi_multi_sta_set_primary_connection); populateStubFor(&hal_fn->wifi_multi_sta_set_use_case); populateStubFor(&hal_fn->wifi_set_coex_unsafe_channels); - + populateStubFor(&hal_fn->wifi_set_voip_mode); + populateStubFor(&hal_fn->wifi_twt_register_handler); + populateStubFor(&hal_fn->wifi_twt_get_capability); + populateStubFor(&hal_fn->wifi_twt_setup_request); + populateStubFor(&hal_fn->wifi_twt_teardown_request); + populateStubFor(&hal_fn->wifi_twt_info_frame_request); + populateStubFor(&hal_fn->wifi_twt_get_stats); + populateStubFor(&hal_fn->wifi_twt_clear_stats); return true; } } // namespace legacy_hal -- GitLab From 3b069c909c6d6ab4fb99b74e7d0152994068da4a Mon Sep 17 00:00:00 2001 From: Midas Chien Date: Thu, 17 Dec 2020 20:42:58 +0800 Subject: [PATCH 345/790] composer: vts: allocate buffer larger or equal to crop size Ensure buffer size larger than crop size. Bug: 175028291 Test: VtsHalGraphicsComposerV2_4TargetTest on Pixel 4, 5 Change-Id: I6528ac6989ca557d9f578b0119715a6688bb6d5d --- .../VtsHalGraphicsComposerV2_4TargetTest.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp b/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp index d8312a2b5c..d2d6d7d38c 100644 --- a/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp +++ b/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp @@ -152,9 +152,9 @@ class GraphicsComposerHidlTest : public ::testing::TestWithParam { void execute() { mComposerClient->execute(mReader.get(), mWriter.get()); } - const native_handle_t* allocate() { + const native_handle_t* allocate(int32_t width, int32_t height) { return mGralloc->allocate( - /*width*/ 64, /*height*/ 64, /*layerCount*/ 1, + width, height, /*layerCount*/ 1, static_cast(PixelFormat::RGBA_8888), static_cast(BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN)); } @@ -407,7 +407,10 @@ void GraphicsComposerHidlTest::sendRefreshFrame(const VtsDisplay& display, mComposerClient->setPowerMode(display.get(), V2_1::IComposerClient::PowerMode::ON); mComposerClient->setColorMode_2_3(display.get(), ColorMode::NATIVE, RenderIntent::COLORIMETRIC); - auto handle = allocate(); + IComposerClient::FRect displayCrop = display.getCrop(); + int32_t displayWidth = static_cast(std::ceilf(displayCrop.right - displayCrop.left)); + int32_t displayHeight = static_cast(std::ceilf(displayCrop.bottom - displayCrop.top)); + auto handle = allocate(displayWidth, displayHeight); ASSERT_NE(nullptr, handle); Layer layer; @@ -435,7 +438,7 @@ void GraphicsComposerHidlTest::sendRefreshFrame(const VtsDisplay& display, ASSERT_EQ(0, mReader->mErrors.size()); mWriter->selectLayer(layer); - auto handle2 = allocate(); + auto handle2 = allocate(displayWidth, displayHeight); ASSERT_NE(nullptr, handle2); mWriter->setLayerBuffer(0, handle2, -1); @@ -703,4 +706,4 @@ int main(int argc, char** argv) { } return RUN_ALL_TESTS(); -} \ No newline at end of file +} -- GitLab From 85169ab87a78d927705394bda0472e56384ff77c Mon Sep 17 00:00:00 2001 From: Daniel Bright Date: Mon, 14 Dec 2020 12:51:08 -0800 Subject: [PATCH 346/790] Add S-NSSAI * Added support for S-NSSAI within HAL * Created struct SliceInfo that represents a S-NSSAI as defined in 3GPP TS 24.501. * Added slice info to setupDataCall and SetupDataCallResult Bug: 169960538 Test: made ims phone call Change-Id: I8d2c55bece07c599cb7d1ac0d16ad85c0acdeae5 --- radio/1.6/IRadio.hal | 5 +- radio/1.6/types.hal | 83 +++++++++++++++++++ .../1.6/vts/functional/radio_hidl_hal_api.cpp | 8 +- 3 files changed, 93 insertions(+), 3 deletions(-) diff --git a/radio/1.6/IRadio.hal b/radio/1.6/IRadio.hal index 3dc80b9e22..a398e7d07f 100644 --- a/radio/1.6/IRadio.hal +++ b/radio/1.6/IRadio.hal @@ -117,6 +117,9 @@ interface IRadio extends @1.5::IRadio { * @param pduSessionId The pdu session id to be used for this data call. A value of 0 means * no pdu session id was attached to this call. * Reference: 3GPP TS 24.007 section 11.2.3.1b + * @param sliceInfo SliceInfo to be used for the data connection when a handover occurs from + * EPDG to 5G. It is valid only when accessNetwork is AccessNetwork:NGRAN. If the slice + * passed from EPDG is rejected, then the data failure cause must be DataCallFailCause:SLICE_REJECTED. * * Response function is IRadioResponse.setupDataCallResponse_1_6() * @@ -125,7 +128,7 @@ interface IRadio extends @1.5::IRadio { oneway setupDataCall_1_6(int32_t serial, AccessNetwork accessNetwork, DataProfileInfo dataProfileInfo, bool roamingAllowed, DataRequestReason reason, vec addresses, vec dnses, - int32_t pduSessionId); + int32_t pduSessionId, OptionalSliceInfo sliceInfo); /** * Send an SMS message diff --git a/radio/1.6/types.hal b/radio/1.6/types.hal index f4dc0bdd17..c2de76b5e7 100644 --- a/radio/1.6/types.hal +++ b/radio/1.6/types.hal @@ -352,6 +352,12 @@ struct SetupDataCallResult { * Reference: 3GPP TS 24.007 section 11.2.3.1b */ int32_t pduSessionId; + + /** + * Slice used for this data call. It is valid only when this data call is on + * AccessNetwork:NGRAN. + */ + OptionalSliceInfo sliceInfo; }; /** @@ -733,3 +739,80 @@ struct Call { */ string forwardedNumber; }; + +/** + * This safe_union represents an optional slice info + */ +safe_union OptionalSliceInfo { + Monostate noinit; + SliceInfo value; +}; + +/** + * This struct represents a S-NSSAI as defined in 3GPP TS 24.501. + */ +struct SliceInfo { + /** + * The type of service provided by the slice. + * + * see: 3GPP TS 24.501 Section 9.11.2.8. + */ + SliceServiceType sst; + + /** + * Slice differentiator is the identifier of a slice that has + * SliceServiceType as SST. A value of -1 indicates that there is + * no corresponding SliceInfo of the HPLMN. + * + * see: 3GPP TS 24.501 Section 9.11.2.8. + */ + int32_t sliceDifferentiator; + + /** + * This SST corresponds to a SliceInfo (S-NSSAI) of the HPLMN; the SST is + * mapped to this value. + * + * see: 3GPP TS 24.501 Section 9.11.2.8. + */ + SliceServiceType mappedHplmnSst; + + /** + * Present only if both sliceDifferentiator and mappedHplmnSst are also + * present. This SD corresponds to a SliceInfo (S-NSSAI) of the HPLMN; + * sliceDifferentiator is mapped to this value. A value of -1 indicates that + * there is no corresponding SliceInfo of the HPLMN. + * + * see: 3GPP TS 24.501 Section 9.11.2.8. + */ + int32_t mappedHplmnSD; +}; + +/** + * Slice/Service Type as defined in 3GPP TS 23.501. + */ +enum SliceServiceType : uint8_t { + /* Not specified */ + NONE = 0, + + /* Slice suitable for the handling of 5G enhanced Mobile Broadband */ + EMBB = 1, + + /** + * Slice suitable for the handling of ultra-reliable low latency + * communications + */ + URLLC = 2, + + /* Slice suitable for the handling of massive IoT */ + MIOT = 3, +}; + +/** + * Expose more setup data call failures. + */ +enum DataCallFailCause : @1.4::DataCallFailCause { + /** + * Data call fail due to the slice not being allowed for the data call. + */ + SLICE_REJECTED = 0x8CC, +}; diff --git a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp index 47babed32e..8b872921ec 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp +++ b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp @@ -56,8 +56,12 @@ TEST_P(RadioHidlTest_v1_6, setupDataCall_1_6) { ::android::hardware::radio::V1_2::DataRequestReason reason = ::android::hardware::radio::V1_2::DataRequestReason::NORMAL; - Return res = radio_v1_6->setupDataCall_1_6(serial, accessNetwork, dataProfileInfo, - roamingAllowed, reason, addresses, dnses, -1); + ::android::hardware::radio::V1_6::OptionalSliceInfo optionalSliceInfo; + memset(&optionalSliceInfo, 0, sizeof(optionalSliceInfo)); + + Return res = + radio_v1_6->setupDataCall_1_6(serial, accessNetwork, dataProfileInfo, roamingAllowed, + reason, addresses, dnses, -1, optionalSliceInfo); ASSERT_OK(res); EXPECT_EQ(std::cv_status::no_timeout, wait()); -- GitLab From 71412f40c6e66df6169fa334c439db09e85f2756 Mon Sep 17 00:00:00 2001 From: Tomasz Wasilczyk Date: Wed, 16 Dec 2020 16:23:44 -0800 Subject: [PATCH 347/790] Implement MessageMutator and FamilyTracker Bug: 173729274 Test: Reboot TCU *after* HU and verify Wi-Fi STA gets SSID list Change-Id: Ie7b0e264a73bd4597470fab8a9bcbfd03e82e9b3 --- automotive/can/1.0/default/libnl++/Android.bp | 2 + .../1.0/default/libnl++/MessageMutator.cpp | 50 +++++++++++++++ .../libnl++/include/libnl++/Attributes.h | 23 +++++-- .../default/libnl++/include/libnl++/Buffer.h | 12 ++++ .../libnl++/include/libnl++/MessageMutator.h | 61 ++++++++++++++++++ .../include/libnl++/generic/FamilyTracker.h | 62 +++++++++++++++++++ .../protocols/generic/FamilyTracker.cpp | 50 +++++++++++++++ 7 files changed, 256 insertions(+), 4 deletions(-) create mode 100644 automotive/can/1.0/default/libnl++/MessageMutator.cpp create mode 100644 automotive/can/1.0/default/libnl++/include/libnl++/MessageMutator.h create mode 100644 automotive/can/1.0/default/libnl++/include/libnl++/generic/FamilyTracker.h create mode 100644 automotive/can/1.0/default/libnl++/protocols/generic/FamilyTracker.cpp diff --git a/automotive/can/1.0/default/libnl++/Android.bp b/automotive/can/1.0/default/libnl++/Android.bp index 90e1002508..a69e302658 100644 --- a/automotive/can/1.0/default/libnl++/Android.bp +++ b/automotive/can/1.0/default/libnl++/Android.bp @@ -22,6 +22,7 @@ cc_library_static { "protocols/common/Empty.cpp", "protocols/common/Error.cpp", "protocols/generic/Ctrl.cpp", + "protocols/generic/FamilyTracker.cpp", "protocols/generic/Generic.cpp", "protocols/generic/GenericMessageBase.cpp", "protocols/generic/Unknown.cpp", @@ -34,6 +35,7 @@ cc_library_static { "protocols/all.cpp", "Attributes.cpp", "MessageFactory.cpp", + "MessageMutator.cpp", "Socket.cpp", "common.cpp", "printer.cpp", diff --git a/automotive/can/1.0/default/libnl++/MessageMutator.cpp b/automotive/can/1.0/default/libnl++/MessageMutator.cpp new file mode 100644 index 0000000000..00b48a66ae --- /dev/null +++ b/automotive/can/1.0/default/libnl++/MessageMutator.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +namespace android::nl { + +MessageMutator::MessageMutator(nlmsghdr* buffer, size_t totalLen) + : mConstBuffer(buffer, totalLen), mMutableBuffer(buffer) { + CHECK(totalLen >= sizeof(nlmsghdr)); +} + +nlmsghdr* MessageMutator::operator->() const { + return mMutableBuffer; +} + +MessageMutator::operator Buffer() const { + return mConstBuffer; +} + +uint64_t MessageMutator::read(Buffer attr) const { + return attr.data().copyFirst(); +} + +void MessageMutator::write(Buffer attr, uint64_t val) const { + const auto attrData = attr.data(); + const auto offset = mConstBuffer.getOffset(attrData); + CHECK(offset.has_value()) << "Trying to write attribute that's not a member of this message"; + + const auto writeableBuffer = reinterpret_cast(mMutableBuffer) + *offset; + const auto attrSize = attrData.getRaw().len(); + + if (attrSize > sizeof(val)) memset(writeableBuffer, 0, attrSize); + memcpy(writeableBuffer, &val, std::min(sizeof(val), attrSize)); +} + +} // namespace android::nl diff --git a/automotive/can/1.0/default/libnl++/include/libnl++/Attributes.h b/automotive/can/1.0/default/libnl++/include/libnl++/Attributes.h index f16d997899..a438a69932 100644 --- a/automotive/can/1.0/default/libnl++/include/libnl++/Attributes.h +++ b/automotive/can/1.0/default/libnl++/include/libnl++/Attributes.h @@ -93,14 +93,29 @@ class Attributes : private Buffer { */ template T get(nlattrtype_t attrtype) const { - const auto& ind = index(); - const auto it = ind.find(attrtype); - if (it == ind.end()) { + const auto buffer = getBuffer(attrtype); + if (!buffer.has_value()) { LOG(WARNING) << "Netlink attribute is missing: " << attrtype; return T{}; } - return parse(it->second); + return parse(*buffer); + } + + /** + * Fetches underlying buffer of a given attribute. + * + * This is a low-level access method unlikely to be useful in most cases. Please consider + * using #get instead. + * + * \param attrtype Attribute to fetch + * \return Attribute buffer. + */ + std::optional> getBuffer(nlattrtype_t attrtype) const { + const auto& ind = index(); + const auto it = ind.find(attrtype); + if (it == ind.end()) return std::nullopt; + return it->second; } /** diff --git a/automotive/can/1.0/default/libnl++/include/libnl++/Buffer.h b/automotive/can/1.0/default/libnl++/include/libnl++/Buffer.h index bf83fbcc20..d759a0a570 100644 --- a/automotive/can/1.0/default/libnl++/include/libnl++/Buffer.h +++ b/automotive/can/1.0/default/libnl++/include/libnl++/Buffer.h @@ -91,6 +91,18 @@ class Buffer { return {impl::data(mData, offset), dataEnd()}; } + template + std::optional getOffset(Buffer inner) const { + const auto selfStart = uintptr_t(mData); + const auto selfEnd = uintptr_t(mBufferEnd); + const auto innerStart = uintptr_t(inner.mData); + const auto innerEnd = uintptr_t(inner.mBufferEnd); + + if (innerStart < selfStart || innerEnd > selfEnd) return std::nullopt; + + return innerStart - selfStart; + } + class iterator { public: iterator() : mCurrent(nullptr, size_t(0)) { diff --git a/automotive/can/1.0/default/libnl++/include/libnl++/MessageMutator.h b/automotive/can/1.0/default/libnl++/include/libnl++/MessageMutator.h new file mode 100644 index 0000000000..7d495e9a5b --- /dev/null +++ b/automotive/can/1.0/default/libnl++/include/libnl++/MessageMutator.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +namespace android::nl { + +/** + * In-place message mutator. + * + * Useful for making small changes (such as adjusting const-sized attributes or struct fields) + * efficiently and in-place. However, if you need to rebuild the message (e.g. to modify variable + * sized attributes or add/remove them), you need to use MessageFactory instead. + */ +class MessageMutator { + public: + /** + * Construct message mutator object from editable buffer. + */ + MessageMutator(nlmsghdr* buffer, size_t totalLen); + + nlmsghdr* operator->() const; + operator Buffer() const; + + /** + * Read current attribute value. + * + * \param Read-only attribute buffer. + * \returns Attribute value. + */ + uint64_t read(Buffer attr) const; + + /** + * Write new attribute value. + * + * \param Read-only attribute buffer. + * \param val New value to set. + */ + void write(Buffer attr, uint64_t val) const; + + private: + const Buffer mConstBuffer; + nlmsghdr* mMutableBuffer; +}; + +} // namespace android::nl diff --git a/automotive/can/1.0/default/libnl++/include/libnl++/generic/FamilyTracker.h b/automotive/can/1.0/default/libnl++/include/libnl++/generic/FamilyTracker.h new file mode 100644 index 0000000000..253003527f --- /dev/null +++ b/automotive/can/1.0/default/libnl++/include/libnl++/generic/FamilyTracker.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include + +#include + +#include + +namespace android::nl::generic { + +/** + * Tracker of Netlink family ID registrations. + */ +class FamilyTracker { + public: + /** + * Try parsing NL80211 message. + * + * Proper parsing of NL80211 nessages requires prior parsing of control message for Generic + * Netlink protocol. + * + * \param msg Message to parse + * \returns Parsed NL80211 message or std::nullopt if it wasn't one + */ + std::optional> parseNl80211(Buffer msg); + + private: + /* For efficiency, we use a single hardcoded family ID. However, if we supported multiple family + * types, this should probably be a map. + */ + std::optional mNl80211FamilyId; + + /** + * Track Generic protocol messages. + * + * This method is looking for family registration messages. + * + * \param msg Message to track + * \returns True, if the message was a control message (regardless of carrying + * family info or not) + */ + bool track(const Buffer& msg); +}; + +} // namespace android::nl::generic diff --git a/automotive/can/1.0/default/libnl++/protocols/generic/FamilyTracker.cpp b/automotive/can/1.0/default/libnl++/protocols/generic/FamilyTracker.cpp new file mode 100644 index 0000000000..900560e5b9 --- /dev/null +++ b/automotive/can/1.0/default/libnl++/protocols/generic/FamilyTracker.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include + +namespace android::nl::generic { + +bool FamilyTracker::track(const Buffer& buffer) { + const auto msgMaybe = nl::Message::parse(buffer, {GENL_ID_CTRL}); + if (!msgMaybe.has_value()) return false; + + const auto msg = *msgMaybe; + if (msg->cmd != CTRL_CMD_NEWFAMILY) return true; + + const auto familyName = msg.attributes.get(CTRL_ATTR_FAMILY_NAME); + const auto familyId = msg.attributes.get(CTRL_ATTR_FAMILY_ID); + + if (familyId < GENL_START_ALLOC) { + LOG(WARNING) << "Invalid family ID: " << familyId; + return true; + } + + if (familyName == "nl80211") mNl80211FamilyId = familyId; + + return true; +} + +std::optional> FamilyTracker::parseNl80211(Buffer msg) { + if (track(msg)) return std::nullopt; + if (!mNl80211FamilyId.has_value()) return std::nullopt; + + return nl::Message::parse(msg, {*mNl80211FamilyId}); +} + +} // namespace android::nl::generic -- GitLab From 143575a10c471d467e78ed725501c44f2793ca9c Mon Sep 17 00:00:00 2001 From: lesl Date: Tue, 22 Dec 2020 15:19:09 +0800 Subject: [PATCH 348/790] wifi: Fix VTS error The current hostapd use channelParams1_3.bandMask (changed on ag/13001575), but VTS doesn't prepare test data:channelParams1_3.bandMask. Test: atest VtsHalWifiHostapdV1_3TargetTest Test: atest VtsHalWifiHostapdV1_2TargetTest Test: atest VtsHalWifiHostapdV1_1TargetTest Test: atest VtsHalWifiHostapdV1_0TargetTest Bug: 176139512 Change-Id: Ibdc08acb55b673b464b5c59ae714157941487a5b --- wifi/hostapd/1.3/vts/functional/hostapd_hidl_test.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/wifi/hostapd/1.3/vts/functional/hostapd_hidl_test.cpp b/wifi/hostapd/1.3/vts/functional/hostapd_hidl_test.cpp index bdbe65128c..a22252c2a5 100644 --- a/wifi/hostapd/1.3/vts/functional/hostapd_hidl_test.cpp +++ b/wifi/hostapd/1.3/vts/functional/hostapd_hidl_test.cpp @@ -124,6 +124,7 @@ class HostapdHidlTest // Newly added attributes in V1_3 channelParams_1_3.channel = iface_params.channelParams.channel; channelParams_1_3.enableAcs = iface_params.channelParams.enableAcs; + channelParams_1_3.bandMask = iface_params_1_2.channelParams.bandMask; channelParams_1_3.V1_2 = iface_params_1_2.channelParams; vec_channelParams.push_back(channelParams_1_3); @@ -147,7 +148,8 @@ class HostapdHidlTest iface_params_1_3.V1_2.V1_1.V1_0.channelParams.enableAcs; iface_params_1_3.channelParamsList[0].V1_2 = iface_params_1_3.V1_2.channelParams; - + iface_params_1_3.channelParamsList[0].bandMask = + iface_params_1_3.V1_2.channelParams.bandMask; return iface_params_1_3; } -- GitLab From deebf381f6d0a09975df4e239be30ecc3d4c5bfa Mon Sep 17 00:00:00 2001 From: Eric Laurent Date: Fri, 20 Nov 2020 18:42:21 +0100 Subject: [PATCH 349/790] audio HAL V7: Update track metadata Add channel mask and audio attributes tags to playback and record track metadata sent to audio HAL. The legacy HAL wrapper supports older legacy HAL versions by sending partial metadata when the legay HAL version is less than 3.2. Bug: 168751366 Test: make Change-Id: Iba3ee3b669e4300201374d4a0d5cf45a04872274 --- audio/common/7.0/types.hal | 14 ++++ audio/common/all-versions/default/HidlUtils.h | 3 + audio/core/all-versions/default/StreamIn.cpp | 82 ++++++++++++++++--- audio/core/all-versions/default/StreamOut.cpp | 74 +++++++++++++++-- .../default/include/core/default/Device.h | 4 +- .../default/include/core/default/StreamIn.h | 11 ++- .../default/include/core/default/StreamOut.h | 11 +++ .../4.0/AudioPrimaryHidlHalTest.cpp | 38 +++++++-- .../6.0/AudioPrimaryHidlHalTest.cpp | 13 ++- .../vts/functional/AudioPrimaryHidlHalTest.h | 7 +- 10 files changed, 220 insertions(+), 37 deletions(-) diff --git a/audio/common/7.0/types.hal b/audio/common/7.0/types.hal index ed56c7320f..b14ebd48d9 100644 --- a/audio/common/7.0/types.hal +++ b/audio/common/7.0/types.hal @@ -274,10 +274,21 @@ struct AudioConfig { uint64_t frameCount; }; +/** + * AudioTag is an additional use case qualifier complementing + * AudioUsage and AudioContentType. Tags are set by vendor specific applications + * and must be prefixed by "VX_". Vendor must namespace their tag + * names to avoid conflicts. + */ +typedef string AudioTag; + /** Metadata of a playback track for a StreamOut. */ struct PlaybackTrackMetadata { AudioUsage usage; AudioContentType contentType; + /** Tags from AudioTrack audio atttributes */ + vec tags; + AudioChannelMask channelMask; /** * Positive linear gain applied to the track samples. 0 being muted and 1 is no attenuation, * 2 means double amplification... @@ -294,6 +305,9 @@ struct SourceMetadata { /** Metadata of a record track for a StreamIn. */ struct RecordTrackMetadata { AudioSource source; + /** Tags from AudioTrack audio atttributes */ + vec tags; + AudioChannelMask channelMask; /** * Positive linear gain applied to the track samples. 0 being muted and 1 is no attenuation, * 2 means double amplification... diff --git a/audio/common/all-versions/default/HidlUtils.h b/audio/common/all-versions/default/HidlUtils.h index a0bd1bc27e..d8b7ba419e 100644 --- a/audio/common/all-versions/default/HidlUtils.h +++ b/audio/common/all-versions/default/HidlUtils.h @@ -77,6 +77,8 @@ struct HidlUtils { #endif #if MAJOR_VERSION >= 7 + static constexpr char sAudioTagSeparator = ';'; + static status_t audioChannelMaskFromHal(audio_channel_mask_t halChannelMask, bool isInput, AudioChannelMask* channelMask); static status_t audioChannelMasksFromHal(const std::vector& halChannelMasks, @@ -126,6 +128,7 @@ struct HidlUtils { struct audio_port_config_device_ext* device, struct audio_port_config_mix_ext* mix, struct audio_port_config_session_ext* session); + #endif // MAJOR_VERSION >= 7 // V4 and below have DeviceAddress defined in the 'core' interface. diff --git a/audio/core/all-versions/default/StreamIn.cpp b/audio/core/all-versions/default/StreamIn.cpp index ead7204712..a6735546f3 100644 --- a/audio/core/all-versions/default/StreamIn.cpp +++ b/audio/core/all-versions/default/StreamIn.cpp @@ -478,29 +478,85 @@ Return StreamIn::debug(const hidl_handle& fd, const hidl_vec& } #if MAJOR_VERSION >= 4 -Return StreamIn::updateSinkMetadata(const SinkMetadata& sinkMetadata) { - if (mStream->update_sink_metadata == nullptr) { - return Void(); // not supported by the HAL + +record_track_metadata StreamIn::convertRecordTrackMetadata( + const RecordTrackMetadata& trackMetadata) { + record_track_metadata halTrackMetadata = {.gain = trackMetadata.gain}; + (void)HidlUtils::audioSourceToHal(trackMetadata.source, &halTrackMetadata.source); +#if MAJOR_VERSION >= 5 + if (trackMetadata.destination.getDiscriminator() == + RecordTrackMetadata::Destination::hidl_discriminator::device) { + (void)deviceAddressToHal(trackMetadata.destination.device(), &halTrackMetadata.dest_device, + halTrackMetadata.dest_device_address); } +#endif + return halTrackMetadata; +} + +void StreamIn::doUpdateSinkMetadata(const SinkMetadata& sinkMetadata) { std::vector halTracks; halTracks.reserve(sinkMetadata.tracks.size()); for (auto& metadata : sinkMetadata.tracks) { - record_track_metadata halTrackMetadata = {.gain = metadata.gain}; - (void)HidlUtils::audioSourceToHal(metadata.source, &halTrackMetadata.source); -#if MAJOR_VERSION >= 5 - if (metadata.destination.getDiscriminator() == - RecordTrackMetadata::Destination::hidl_discriminator::device) { - (void)deviceAddressToHal(metadata.destination.device(), &halTrackMetadata.dest_device, - halTrackMetadata.dest_device_address); - } -#endif - halTracks.push_back(halTrackMetadata); + halTracks.push_back(convertRecordTrackMetadata(metadata)); } const sink_metadata_t halMetadata = { .track_count = halTracks.size(), .tracks = halTracks.data(), }; mStream->update_sink_metadata(mStream, &halMetadata); +} + +#if MAJOR_VERSION >= 7 +record_track_metadata_v7 StreamIn::convertRecordTrackMetadataV7( + const RecordTrackMetadata& trackMetadata) { + record_track_metadata_v7 halTrackMetadata; + halTrackMetadata.base = convertRecordTrackMetadata(trackMetadata); + (void)HidlUtils::audioChannelMaskToHal(trackMetadata.channelMask, + &halTrackMetadata.channel_mask); + std::string halTags; + for (const auto& tag : trackMetadata.tags) { + if (&tag != &trackMetadata.tags[0]) { + halTags += HidlUtils::sAudioTagSeparator; + } + halTags += tag.c_str(); + } + strncpy(halTrackMetadata.tags, halTags.c_str(), AUDIO_ATTRIBUTES_TAGS_MAX_SIZE); + return halTrackMetadata; +} + +void StreamIn::doUpdateSinkMetadataV7(const SinkMetadata& sinkMetadata) { + std::vector halTracks; + halTracks.reserve(sinkMetadata.tracks.size()); + for (auto& metadata : sinkMetadata.tracks) { + halTracks.push_back(convertRecordTrackMetadataV7(metadata)); + } + const sink_metadata_v7_t halMetadata = { + .track_count = halTracks.size(), + .tracks = halTracks.data(), + }; + mStream->update_sink_metadata_v7(mStream, &halMetadata); +} +#endif // MAJOR_VERSION >= 7 + +Return StreamIn::updateSinkMetadata(const SinkMetadata& sinkMetadata) { +#if MAJOR_VERSION < 7 + if (mStream->update_sink_metadata == nullptr) { + return Void(); // not supported by the HAL + } + doUpdateSinkMetadata(sinkMetadata); +#else + if (mDevice->version() < AUDIO_DEVICE_API_VERSION_3_2) { + if (mStream->update_sink_metadata == nullptr) { + return Void(); // not supported by the HAL + } + doUpdateSinkMetadata(sinkMetadata); + } else { + if (mStream->update_sink_metadata_v7 == nullptr) { + return Void(); // not supported by the HAL + } + doUpdateSinkMetadataV7(sinkMetadata); + } +#endif // MAJOR_VERSION < 7 return Void(); } diff --git a/audio/core/all-versions/default/StreamOut.cpp b/audio/core/all-versions/default/StreamOut.cpp index 5633cbb4b7..2451b9eb3a 100644 --- a/audio/core/all-versions/default/StreamOut.cpp +++ b/audio/core/all-versions/default/StreamOut.cpp @@ -585,26 +585,82 @@ Return StreamOut::debug(const hidl_handle& fd, const hidl_vec } #if MAJOR_VERSION >= 4 -Return StreamOut::updateSourceMetadata(const SourceMetadata& sourceMetadata) { - if (mStream->update_source_metadata == nullptr) { - return Void(); // not supported by the HAL - } +playback_track_metadata StreamOut::convertPlaybackTrackMetadata( + const PlaybackTrackMetadata& trackMetadata) { + playback_track_metadata_t halTrackMetadata = {.gain = trackMetadata.gain}; + (void)HidlUtils::audioUsageToHal(trackMetadata.usage, &halTrackMetadata.usage); + (void)HidlUtils::audioContentTypeToHal(trackMetadata.contentType, + &halTrackMetadata.content_type); + return halTrackMetadata; +} + +void StreamOut::doUpdateSourceMetadata(const SourceMetadata& sourceMetadata) { std::vector halTracks; halTracks.reserve(sourceMetadata.tracks.size()); for (auto& metadata : sourceMetadata.tracks) { - playback_track_metadata_t halTrackMetadata = {.gain = metadata.gain}; - (void)HidlUtils::audioUsageToHal(metadata.usage, &halTrackMetadata.usage); - (void)HidlUtils::audioContentTypeToHal(metadata.contentType, - &halTrackMetadata.content_type); - halTracks.push_back(std::move(halTrackMetadata)); + halTracks.push_back(convertPlaybackTrackMetadata(metadata)); } const source_metadata_t halMetadata = { .track_count = halTracks.size(), .tracks = halTracks.data(), }; mStream->update_source_metadata(mStream, &halMetadata); +} + +#if MAJOR_VERSION >= 7 +playback_track_metadata_v7 StreamOut::convertPlaybackTrackMetadataV7( + const PlaybackTrackMetadata& trackMetadata) { + playback_track_metadata_v7 halTrackMetadata; + halTrackMetadata.base = convertPlaybackTrackMetadata(trackMetadata); + (void)HidlUtils::audioChannelMaskToHal(trackMetadata.channelMask, + &halTrackMetadata.channel_mask); + std::string halTags; + for (const auto& tag : trackMetadata.tags) { + if (&tag != &trackMetadata.tags[0]) { + halTags += HidlUtils::sAudioTagSeparator; + } + halTags += tag.c_str(); + } + strncpy(halTrackMetadata.tags, halTags.c_str(), AUDIO_ATTRIBUTES_TAGS_MAX_SIZE); + return halTrackMetadata; +} + +void StreamOut::doUpdateSourceMetadataV7(const SourceMetadata& sourceMetadata) { + std::vector halTracks; + halTracks.reserve(sourceMetadata.tracks.size()); + for (auto& metadata : sourceMetadata.tracks) { + halTracks.push_back(convertPlaybackTrackMetadataV7(metadata)); + } + const source_metadata_v7_t halMetadata = { + .track_count = halTracks.size(), + .tracks = halTracks.data(), + }; + mStream->update_source_metadata_v7(mStream, &halMetadata); +} +#endif // MAJOR_VERSION >= 7 + +Return StreamOut::updateSourceMetadata(const SourceMetadata& sourceMetadata) { +#if MAJOR_VERSION < 7 + if (mStream->update_source_metadata == nullptr) { + return Void(); // not supported by the HAL + } + doUpdateSourceMetadata(sourceMetadata); +#else + if (mDevice->version() < AUDIO_DEVICE_API_VERSION_3_2) { + if (mStream->update_source_metadata == nullptr) { + return Void(); // not supported by the HAL + } + doUpdateSourceMetadata(sourceMetadata); + } else { + if (mStream->update_source_metadata_v7 == nullptr) { + return Void(); // not supported by the HAL + } + doUpdateSourceMetadataV7(sourceMetadata); + } +#endif // MAJOR_VERSION < 7 return Void(); } + Return StreamOut::selectPresentation(int32_t /*presentationId*/, int32_t /*programId*/) { return Result::NOT_SUPPORTED; // TODO: propagate to legacy } diff --git a/audio/core/all-versions/default/include/core/default/Device.h b/audio/core/all-versions/default/include/core/default/Device.h index 461c253768..2a4d22651a 100644 --- a/audio/core/all-versions/default/include/core/default/Device.h +++ b/audio/core/all-versions/default/include/core/default/Device.h @@ -146,6 +146,8 @@ struct Device : public IDevice, public ParametersUtil { void closeOutputStream(audio_stream_out_t* stream); audio_hw_device_t* device() const { return mDevice; } + uint32_t version() const { return mDevice->common.version; } + private: bool mIsClosed; audio_hw_device_t* mDevice; @@ -161,8 +163,6 @@ struct Device : public IDevice, public ParametersUtil { // Methods from ParametersUtil. char* halGetParameters(const char* keys) override; int halSetParameters(const char* keysAndValues) override; - - uint32_t version() const { return mDevice->common.version; } }; } // namespace implementation diff --git a/audio/core/all-versions/default/include/core/default/StreamIn.h b/audio/core/all-versions/default/include/core/default/StreamIn.h index b861c6cc2b..512da559bf 100644 --- a/audio/core/all-versions/default/include/core/default/StreamIn.h +++ b/audio/core/all-versions/default/include/core/default/StreamIn.h @@ -124,7 +124,16 @@ struct StreamIn : public IStreamIn { static Result getCapturePositionImpl(audio_stream_in_t* stream, uint64_t* frames, uint64_t* time); - private: + private: +#if MAJOR_VERSION >= 4 + record_track_metadata convertRecordTrackMetadata(const RecordTrackMetadata& trackMetadata); + void doUpdateSinkMetadata(const SinkMetadata& sinkMetadata); +#if MAJOR_VERSION >= 7 + record_track_metadata_v7 convertRecordTrackMetadataV7(const RecordTrackMetadata& trackMetadata); + void doUpdateSinkMetadataV7(const SinkMetadata& sinkMetadata); +#endif +#endif + const sp mDevice; audio_stream_in_t* mStream; const sp mStreamCommon; diff --git a/audio/core/all-versions/default/include/core/default/StreamOut.h b/audio/core/all-versions/default/include/core/default/StreamOut.h index 9f64e3e77d..8da940d846 100644 --- a/audio/core/all-versions/default/include/core/default/StreamOut.h +++ b/audio/core/all-versions/default/include/core/default/StreamOut.h @@ -143,6 +143,17 @@ struct StreamOut : public IStreamOut { #endif private: +#if MAJOR_VERSION >= 4 + playback_track_metadata convertPlaybackTrackMetadata( + const PlaybackTrackMetadata& trackMetadata); + void doUpdateSourceMetadata(const SourceMetadata& sourceMetadata); +#if MAJOR_VERSION >= 7 + playback_track_metadata_v7 convertPlaybackTrackMetadataV7( + const PlaybackTrackMetadata& trackMetadata); + void doUpdateSourceMetadataV7(const SourceMetadata& sourceMetadata); +#endif +#endif + const sp mDevice; audio_stream_out_t* mStream; const sp mStreamCommon; diff --git a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp index 1612d3c30c..a7d7ed104b 100644 --- a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp +++ b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp @@ -72,7 +72,10 @@ TEST_P(AudioHidlDeviceTest, GetMicrophonesTest) { config.base.format = toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT); hidl_vec flags; const SinkMetadata initMetadata = { - {{.source = toString(xsd::AudioSource::AUDIO_SOURCE_MIC), .gain = 1}}}; + {{.source = toString(xsd::AudioSource::AUDIO_SOURCE_MIC), + .gain = 1, + .tags = {}, + .channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_IN_MONO)}}}; #endif EventFlag* efGroup; for (auto microphone : microphones) { @@ -243,7 +246,11 @@ TEST_P(InputStreamTest, updateSinkMetadata) { #if MAJOR_VERSION <= 6 const SinkMetadata metadata = {{{.source = source, .gain = volume}}}; #elif MAJOR_VERSION >= 7 - const SinkMetadata metadata = {{{.source = toString(source), .gain = volume}}}; + const SinkMetadata metadata = { + {{.source = toString(source), + .gain = volume, + .tags = {}, + .channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_IN_MONO)}}}; #endif ASSERT_OK(stream->updateSinkMetadata(metadata)) << "source=" << toString(source) << ", volume=" << volume; @@ -281,7 +288,12 @@ TEST_P(OutputStreamTest, updateSourceMetadata) { #if MAJOR_VERSION <= 6 const SourceMetadata metadata = {{{usage, content, volume}}}; #elif MAJOR_VERSION >= 7 - const SourceMetadata metadata = {{{toString(usage), toString(content), volume}}}; + const SourceMetadata metadata = { + {{toString(usage), + toString(content), + {} /* tags */, + toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO), + volume}}}; #endif ASSERT_OK(stream->updateSourceMetadata(metadata)) << "usage=" << toString(usage) << ", content=" << toString(content) @@ -300,13 +312,25 @@ TEST_P(OutputStreamTest, updateSourceMetadata) { {AudioUsage::ASSISTANT, AudioContentType::UNKNOWN, 0.3}}} #elif MAJOR_VERSION >= 7 {{{toString(xsd::AudioUsage::AUDIO_USAGE_MEDIA), - toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_MUSIC), 0.1}, + toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_MUSIC), + {}, + toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO), + 0.1}, {toString(xsd::AudioUsage::AUDIO_USAGE_VOICE_COMMUNICATION), - toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_SPEECH), 1.0}, + toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_SPEECH), + {}, // tags + toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_MONO), + 1.0}, {toString(xsd::AudioUsage::AUDIO_USAGE_ALARM), - toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_SONIFICATION), 0.0}, + toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_SONIFICATION), + {}, // tags + toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO), + 0.0}, {toString(xsd::AudioUsage::AUDIO_USAGE_ASSISTANT), - toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_UNKNOWN), 0.3}}} + toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_UNKNOWN), + {}, + toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_MONO), + 0.3}}} #endif )); // clang-format on diff --git a/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp index bd8de2d0e6..5ad38de412 100644 --- a/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp +++ b/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp @@ -98,9 +98,11 @@ TEST_P(AudioHidlDeviceTest, CloseDeviceWithOpenedOutputStreams) { auto flags = hidl_bitfield(AudioOutputFlag::NONE); #elif MAJOR_VERSION >= 7 DeviceAddress address{.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_OUT_DEFAULT)}; - SourceMetadata initMetadata = { - {{toString(xsd::AudioUsage::AUDIO_USAGE_MEDIA), - toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_MUSIC), 1 /* gain */}}}; + SourceMetadata initMetadata = {{{toString(xsd::AudioUsage::AUDIO_USAGE_MEDIA), + toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_MUSIC), + {} /* tags */, + toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO), + 1 /* gain */}}}; hidl_vec flags; #endif AudioConfig config{}; @@ -131,7 +133,10 @@ TEST_P(AudioHidlDeviceTest, CloseDeviceWithOpenedInputStreams) { #elif MAJOR_VERSION >= 7 DeviceAddress address{.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_IN_DEFAULT)}; SinkMetadata initMetadata = { - {{.source = toString(xsd::AudioSource::AUDIO_SOURCE_MIC), .gain = 1}}}; + {{.source = toString(xsd::AudioSource::AUDIO_SOURCE_MIC), + .gain = 1, + .tags = {}, + .channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_IN_MONO)}}}; hidl_vec flags; #endif AudioConfig config{}; diff --git a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h index 05c9bf7e2e..63330233ee 100644 --- a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h +++ b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h @@ -926,6 +926,8 @@ class OutputStreamTest : public OpenStreamTest { const SourceMetadata initMetadata = { { { toString(xsd::AudioUsage::AUDIO_USAGE_MEDIA), toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_MUSIC), + {}, + toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO), 1 /* gain */ } }}; #endif }; @@ -991,7 +993,10 @@ class InputStreamTest : public OpenStreamTest { const SinkMetadata initMetadata = {{ {.source = AudioSource::DEFAULT, .gain = 1 } }}; #elif MAJOR_VERSION >= 7 const SinkMetadata initMetadata = { - {{.source = toString(xsd::AudioSource::AUDIO_SOURCE_DEFAULT), .gain = 1}}}; + {{.source = toString(xsd::AudioSource::AUDIO_SOURCE_DEFAULT), + .gain = 1, + .tags = {}, + .channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_IN_MONO)}}}; #endif }; -- GitLab From 9d480d32a3767fcbed3ccaa59fc802423c195d20 Mon Sep 17 00:00:00 2001 From: Jennifer Tsau Date: Tue, 22 Dec 2020 23:22:30 +0000 Subject: [PATCH 350/790] Fixed flags on example. Guest is 2 and Ephemeral is 4, so it should be 6. Bug: 157770534 Test: None Change-Id: I82b94427a4474ee0773f17f5cda8338d5b7c3989 --- automotive/vehicle/2.0/types.hal | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/automotive/vehicle/2.0/types.hal b/automotive/vehicle/2.0/types.hal index 931fee4a23..0488b57196 100644 --- a/automotive/vehicle/2.0/types.hal +++ b/automotive/vehicle/2.0/types.hal @@ -2773,7 +2773,7 @@ enum VehicleProperty : int32_t { * * int32[0]: 42 // request id * int32[1]: 11 // Android id of the created user - * int32[2]: 3 // Android flags (ephemeral guest) of the created user + * int32[2]: 6 // Android flags (ephemeral guest) of the created user * int32[3]: 10 // current user * int32[4]: 0 // current user flags (none) * int32[5]: 3 // number of users @@ -2782,7 +2782,7 @@ enum VehicleProperty : int32_t { * int32[8]: 10 // 2nd user (user 10) * int32[9]: 0 // 2nd user flags (none) * int32[19]: 11 // 3rd user (user 11) - * int32[11]: 3 // 3rd user flags (ephemeral guest) + * int32[11]: 6 // 3rd user flags (ephemeral guest) * string: "ElGuesto" // name of the new user * * Then if the request succeeded, the HAL would return: -- GitLab From 66dbcee2d3e4637b0d396b145ceee128b389e4ff Mon Sep 17 00:00:00 2001 From: Sooraj Sasindran Date: Wed, 23 Dec 2020 10:17:18 -0800 Subject: [PATCH 351/790] Update documentation for secondary bandwidth Update documentation for secondary bandwidth to indicate that some modems do not support this feature Test: build Bug: 162373679 Change-Id: I03d4079e03817fe7c7b52eb18058c49e54302d6b --- radio/1.6/types.hal | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/radio/1.6/types.hal b/radio/1.6/types.hal index f4dc0bdd17..a2e0c3f73d 100644 --- a/radio/1.6/types.hal +++ b/radio/1.6/types.hal @@ -405,7 +405,8 @@ struct LinkCapacityEstimate { * This bandwidth estimate shall be the estimated maximum sustainable link bandwidth * (as would be measured at the Upper PDCP or SNDCP SAP). This is valid only * in if device is connected to both primary and secodary in dual connected - * mode. This must be filled with -1 if secondary is not connected. + * mode. This must be filled with -1 if secondary is not connected or if + * modem does not support this feature. */ uint32_t secondaryDownlinkCapacityKbps; @@ -414,7 +415,8 @@ struct LinkCapacityEstimate { * This bandwidth estimate shall be the estimated * maximum sustainable link bandwidth (as would be measured at the Upper PDCP or SNDCP SAP). * This is valid only in if device is connected to both primary and secodary in dual connected - * mode.This must be filled with -1 if secondary is not connected. + * mode.This must be filled with -1 if secondary is not connected or if modem + * does not support this feature. */ uint32_t secondaryUplinkCapacityKbps; }; -- GitLab From 84b7069ab7975cf0293424ee6f6d148eb0a325e5 Mon Sep 17 00:00:00 2001 From: Shuo Qian Date: Thu, 3 Dec 2020 15:47:35 -0800 Subject: [PATCH 352/790] Add emergencyDial_1_6 in the HAL to modify the multisim logic for pin lock Test: vts Bug: 171235919 Change-Id: I94319ab345dabae040792b14b2f8bd8bc64839c0 --- radio/1.6/IRadio.hal | 61 +++++++ .../1.6/vts/functional/radio_hidl_hal_api.cpp | 161 ++++++++++++++++++ .../vts/functional/radio_hidl_hal_test.cpp | 23 +++ .../functional/radio_hidl_hal_utils_v1_6.h | 3 +- radio/1.6/vts/functional/radio_response.cpp | 10 +- 5 files changed, 254 insertions(+), 4 deletions(-) diff --git a/radio/1.6/IRadio.hal b/radio/1.6/IRadio.hal index 3dc80b9e22..36d288fbc5 100644 --- a/radio/1.6/IRadio.hal +++ b/radio/1.6/IRadio.hal @@ -18,9 +18,12 @@ package android.hardware.radio@1.6; import @1.0::CdmaSmsMessage; +import @1.0::Dial; import @1.0::GsmSmsMessage; import @1.1::CardPowerState; import @1.2::DataRequestReason; +import @1.4::EmergencyCallRouting; +import @1.4::EmergencyServiceCategory; import @1.4::RadioAccessFamily; import @1.5::IRadio; import @1.5::AccessNetwork; @@ -371,6 +374,64 @@ interface IRadio extends @1.5::IRadio { DataThrottlingAction dataThrottlingAction, int64_t completionDurationMillis); + /** + * Initiate emergency voice call, with zero or more emergency service category(s), zero or + * more emergency Uniform Resource Names (URN), and routing information for handling the call. + * Android uses this request to make its emergency call instead of using @1.0::IRadio.dial + * if the 'address' in the 'dialInfo' field is identified as an emergency number by Android. + * + * In multi-sim scenario, if the emergency number is from a specific subscription, this radio + * request can still be sent out on the other subscription as long as routing is set to + * @1.4::EmergencyNumberRouting#EMERGENCY. This radio request will not be sent on an inactive + * (PIN/PUK locked) subscription unless both subscriptions are PIN/PUK locked. In this case, + * the request will be sent on the primary subscription. + * + * Some countries or carriers require some emergency numbers that must be handled with normal + * call routing if possible or emergency routing. 1) if the 'routing' field is specified as + * @1.4::EmergencyNumberRouting#NORMAL, the implementation must try the full radio service to + * use normal call routing to handle the call; if service cannot support normal routing, the + * implementation must use emergency routing to handle the call. 2) if 'routing' is specified + * as @1.4::EmergencyNumberRouting#EMERGENCY, the implementation must use emergency routing to + * handle the call. 3) if 'routing' is specified as @1.4::EmergencyNumberRouting#UNKNOWN, + * Android does not know how to handle the call. + * + * If the dialed emergency number does not have a specified emergency service category, the + * 'categories' field is set to @1.4::EmergencyServiceCategory#UNSPECIFIED; if the dialed + * emergency number does not have specified emergency Uniform Resource Names, the 'urns' field + * is set to an empty list. If the underlying technology used to request emergency services + * does not support the emergency service category or emergency uniform resource names, the + * field 'categories' or 'urns' may be ignored. + * + * In the scenarios that the 'address' in the 'dialInfo' field has other functions besides the + * emergency number function, if the 'hasKnownUserIntentEmergency' field is true, the user's + * intent for this dial request is emergency call, and the modem must treat this as an actual + * emergency dial; if the 'hasKnownUserIntentEmergency' field is false, Android does not know + * user's intent for this call. + * + * If 'isTesting' is true, this request is for testing purpose, and must not be sent to a real + * emergency service; otherwise it's for a real emergency call request. + * + * Reference: 3gpp 22.101, Section 10 - Emergency Calls; + * 3gpp 23.167, Section 6 - Functional description; + * 3gpp 24.503, Section 5.1.6.8.1 - General; + * RFC 5031 + * + * @param serial Serial number of request. + * @param dialInfo the same @1.0::Dial information used by @1.0::IRadio.dial. + * @param categories bitfield<@1.4::EmergencyServiceCategory> the Emergency Service Category(s) + * of the call. + * @param urns the emergency Uniform Resource Names (URN) + * @param routing @1.4::EmergencyCallRouting the emergency call routing information. + * @param hasKnownUserIntentEmergency Flag indicating if user's intent for the emergency call + * is known. + * @param isTesting Flag indicating if this request is for testing purpose. + * + * Response function is IRadioResponse.emergencyDialResponse() + */ + oneway emergencyDial_1_6(int32_t serial, Dial dialInfo, + bitfield categories, vec urns, + EmergencyCallRouting routing, bool hasKnownUserIntentEmergency, bool isTesting); + /** * Get which bands the modem's background scan is acting on. * diff --git a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp index 47babed32e..c8846d2242 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp +++ b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp @@ -407,6 +407,167 @@ TEST_P(RadioHidlTest_v1_6, setSimCardPower_1_6) { } } +/* + * Test IRadio.emergencyDial() for the response returned. + */ +TEST_P(RadioHidlTest_v1_6, emergencyDial_1_6) { + if (!deviceSupportsFeature(FEATURE_VOICE_CALL)) { + ALOGI("Skipping emergencyDial because voice call is not supported in device"); + return; + } else { + ALOGI("Running emergencyDial because voice call is supported in device"); + } + + serial = GetRandomSerialNumber(); + + ::android::hardware::radio::V1_0::Dial dialInfo; + dialInfo.address = hidl_string("911"); + int categories = static_cast( + ::android::hardware::radio::V1_4::EmergencyServiceCategory::UNSPECIFIED); + std::vector urns = {""}; + ::android::hardware::radio::V1_4::EmergencyCallRouting routing = + ::android::hardware::radio::V1_4::EmergencyCallRouting::UNKNOWN; + + Return res = + radio_v1_6->emergencyDial_1_6(serial, dialInfo, categories, urns, routing, true, true); + ASSERT_OK(res); + EXPECT_EQ(std::cv_status::no_timeout, wait()); + EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo_v1_0.type); + EXPECT_EQ(serial, radioRsp_v1_6->rspInfo_v1_0.serial); + + ALOGI("emergencyDial, rspInfo_v1_0.error = %s\n", + toString(radioRsp_v1_6->rspInfo_v1_0.error).c_str()); + + ::android::hardware::radio::V1_0::RadioError rspEmergencyDial = + radioRsp_v1_6->rspInfo_v1_0.error; + // In DSDS or TSTS, we only check the result if the current slot is IN_SERVICE + // or Emergency_Only. + if (isDsDsEnabled() || isTsTsEnabled()) { + serial = GetRandomSerialNumber(); + radio_v1_6->getVoiceRegistrationState(serial); + EXPECT_EQ(std::cv_status::no_timeout, wait()); + if (isVoiceEmergencyOnly(radioRsp_v1_6->voiceRegResp.regState) || + isVoiceInService(radioRsp_v1_6->voiceRegResp.regState)) { + EXPECT_EQ(::android::hardware::radio::V1_0::RadioError::NONE, rspEmergencyDial); + } + } else { + EXPECT_EQ(::android::hardware::radio::V1_0::RadioError::NONE, rspEmergencyDial); + } + + // Give some time for modem to establish the emergency call channel. + sleep(MODEM_EMERGENCY_CALL_ESTABLISH_TIME); + + // Disconnect all the potential established calls to prevent them affecting other tests. + clearPotentialEstablishedCalls(); +} + +/* + * Test IRadio.emergencyDial() with specified service and its response returned. + */ +TEST_P(RadioHidlTest_v1_6, emergencyDial_1_6_withServices) { + if (!deviceSupportsFeature(FEATURE_VOICE_CALL)) { + ALOGI("Skipping emergencyDial because voice call is not supported in device"); + return; + } else { + ALOGI("Running emergencyDial because voice call is supported in device"); + } + + serial = GetRandomSerialNumber(); + + ::android::hardware::radio::V1_0::Dial dialInfo; + dialInfo.address = hidl_string("911"); + int categories = + static_cast(::android::hardware::radio::V1_4::EmergencyServiceCategory::AMBULANCE); + std::vector urns = {"urn:service:sos.ambulance"}; + ::android::hardware::radio::V1_4::EmergencyCallRouting routing = + ::android::hardware::radio::V1_4::EmergencyCallRouting::UNKNOWN; + + Return res = + radio_v1_6->emergencyDial_1_6(serial, dialInfo, categories, urns, routing, true, true); + ASSERT_OK(res); + EXPECT_EQ(std::cv_status::no_timeout, wait()); + EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo_v1_0.type); + EXPECT_EQ(serial, radioRsp_v1_6->rspInfo_v1_0.serial); + + ALOGI("emergencyDial_withServices, rspInfo_v1_0.error = %s\n", + toString(radioRsp_v1_6->rspInfo_v1_0.error).c_str()); + ::android::hardware::radio::V1_0::RadioError rspEmergencyDial = + radioRsp_v1_6->rspInfo_v1_0.error; + + // In DSDS or TSTS, we only check the result if the current slot is IN_SERVICE + // or Emergency_Only. + if (isDsDsEnabled() || isTsTsEnabled()) { + serial = GetRandomSerialNumber(); + radio_v1_6->getVoiceRegistrationState(serial); + EXPECT_EQ(std::cv_status::no_timeout, wait()); + if (isVoiceEmergencyOnly(radioRsp_v1_6->voiceRegResp.regState) || + isVoiceInService(radioRsp_v1_6->voiceRegResp.regState)) { + EXPECT_EQ(::android::hardware::radio::V1_0::RadioError::NONE, rspEmergencyDial); + } + } else { + EXPECT_EQ(::android::hardware::radio::V1_0::RadioError::NONE, rspEmergencyDial); + } + // Give some time for modem to establish the emergency call channel. + sleep(MODEM_EMERGENCY_CALL_ESTABLISH_TIME); + + // Disconnect all the potential established calls to prevent them affecting other tests. + clearPotentialEstablishedCalls(); +} + +/* + * Test IRadio.emergencyDial() with known emergency call routing and its response returned. + */ +TEST_P(RadioHidlTest_v1_6, emergencyDial_1_6_withEmergencyRouting) { + if (!deviceSupportsFeature(FEATURE_VOICE_CALL)) { + ALOGI("Skipping emergencyDial because voice call is not supported in device"); + return; + } else { + ALOGI("Running emergencyDial because voice call is supported in device"); + } + + serial = GetRandomSerialNumber(); + + ::android::hardware::radio::V1_0::Dial dialInfo; + dialInfo.address = hidl_string("911"); + int categories = static_cast( + ::android::hardware::radio::V1_4::EmergencyServiceCategory::UNSPECIFIED); + std::vector urns = {""}; + ::android::hardware::radio::V1_4::EmergencyCallRouting routing = + ::android::hardware::radio::V1_4::EmergencyCallRouting::EMERGENCY; + + Return res = + radio_v1_6->emergencyDial_1_6(serial, dialInfo, categories, urns, routing, true, true); + ASSERT_OK(res); + EXPECT_EQ(std::cv_status::no_timeout, wait()); + EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo_v1_0.type); + EXPECT_EQ(serial, radioRsp_v1_6->rspInfo_v1_0.serial); + + ALOGI("emergencyDial_withEmergencyRouting, rspInfo_v1_0.error = %s\n", + toString(radioRsp_v1_6->rspInfo_v1_0.error).c_str()); + ::android::hardware::radio::V1_0::RadioError rspEmergencyDial = + radioRsp_v1_6->rspInfo_v1_0.error; + + // In DSDS or TSTS, we only check the result if the current slot is IN_SERVICE + // or Emergency_Only. + if (isDsDsEnabled() || isTsTsEnabled()) { + serial = GetRandomSerialNumber(); + radio_v1_6->getVoiceRegistrationState(serial); + EXPECT_EQ(std::cv_status::no_timeout, wait()); + if (isVoiceEmergencyOnly(radioRsp_v1_6->voiceRegResp.regState) || + isVoiceInService(radioRsp_v1_6->voiceRegResp.regState)) { + EXPECT_EQ(::android::hardware::radio::V1_0::RadioError::NONE, rspEmergencyDial); + } + } else { + EXPECT_EQ(::android::hardware::radio::V1_0::RadioError::NONE, rspEmergencyDial); + } + + // Give some time for modem to establish the emergency call channel. + sleep(MODEM_EMERGENCY_CALL_ESTABLISH_TIME); + + // Disconnect all the potential established calls to prevent them affecting other tests. + clearPotentialEstablishedCalls(); +} + /* * Test IRadio.getCurrentCalls_1_6() for the response returned. */ diff --git a/radio/1.6/vts/functional/radio_hidl_hal_test.cpp b/radio/1.6/vts/functional/radio_hidl_hal_test.cpp index 79c3cde745..59f768201d 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_test.cpp +++ b/radio/1.6/vts/functional/radio_hidl_hal_test.cpp @@ -74,6 +74,29 @@ std::cv_status RadioHidlTest_v1_6::wait() { return status; } +void RadioHidlTest_v1_6::clearPotentialEstablishedCalls() { + // Get the current call Id to hangup the established emergency call. + serial = GetRandomSerialNumber(); + radio_v1_6->getCurrentCalls_1_6(serial); + EXPECT_EQ(std::cv_status::no_timeout, wait()); + + // Hang up to disconnect the established call channels. + for (const ::android::hardware::radio::V1_6::Call& call : radioRsp_v1_6->currentCalls) { + serial = GetRandomSerialNumber(); + radio_v1_6->hangup(serial, call.base.base.index); + ALOGI("Hang up to disconnect the established call channel: %d", call.base.base.index); + EXPECT_EQ(std::cv_status::no_timeout, wait()); + // Give some time for modem to disconnect the established call channel. + sleep(MODEM_EMERGENCY_CALL_DISCONNECT_TIME); + } + + // Verify there are no more current calls. + serial = GetRandomSerialNumber(); + radio_v1_6->getCurrentCalls_1_6(serial); + EXPECT_EQ(std::cv_status::no_timeout, wait()); + EXPECT_EQ(0, radioRsp_v1_6->currentCalls.size()); +} + void RadioHidlTest_v1_6::updateSimCardStatus() { serial = GetRandomSerialNumber(); radio_v1_6->getIccCardStatus(serial); diff --git a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h index fbcd7a9339..e41b807484 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h +++ b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h @@ -70,7 +70,8 @@ class RadioResponse_v1_6 : public ::android::hardware::radio::V1_6::IRadioRespon ::android::hardware::radio::V1_6::RadioResponseInfo rspInfo; // Call - hidl_vec<::android::hardware::radio::V1_2::Call> currentCalls; + hidl_vec<::android::hardware::radio::V1_6::Call> currentCalls; + ::android::hardware::radio::V1_2::VoiceRegStateResult voiceRegResp; // Sms SendSmsResult sendSmsResult; diff --git a/radio/1.6/vts/functional/radio_response.cpp b/radio/1.6/vts/functional/radio_response.cpp index 7c5cf6df86..ba84fd45b3 100644 --- a/radio/1.6/vts/functional/radio_response.cpp +++ b/radio/1.6/vts/functional/radio_response.cpp @@ -816,8 +816,11 @@ Return RadioResponse_v1_6::getCellInfoListResponse_1_2( } Return RadioResponse_v1_6::getVoiceRegistrationStateResponse_1_2( - const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, - const ::android::hardware::radio::V1_2::VoiceRegStateResult& /*voiceRegResponse*/) { + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, + const ::android::hardware::radio::V1_2::VoiceRegStateResult& voiceRegResponse) { + rspInfo_v1_0 = info; + voiceRegResp = voiceRegResponse; + parent_v1_6.notify(info.serial); return Void(); } @@ -1210,8 +1213,9 @@ Return RadioResponse_v1_6::getDataRegistrationStateResponse_1_6( Return RadioResponse_v1_6::getCurrentCallsResponse_1_6( const ::android::hardware::radio::V1_6::RadioResponseInfo& info, - const ::android::hardware::hidl_vec<::android::hardware::radio::V1_6::Call>& /*calls*/) { + const ::android::hardware::hidl_vec<::android::hardware::radio::V1_6::Call>& calls) { rspInfo = info; + currentCalls = calls; parent_v1_6.notify(info.serial); return Void(); } -- GitLab From bcf3b22fba281b81ba9db2d2d30461388d124fd8 Mon Sep 17 00:00:00 2001 From: Yu-Han Yang Date: Mon, 28 Dec 2020 13:32:39 -0800 Subject: [PATCH 353/790] Move utcTime in default implementation forward Bug: 175890761 Test: atest GnssLocationUpdateIntervalTest#testLocationUpdatesAtVariousIntervals Change-Id: Iab572243fc8cbf2f34df0b45614050ad794af384 --- gnss/common/utils/default/Utils.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gnss/common/utils/default/Utils.cpp b/gnss/common/utils/default/Utils.cpp index e383d516ea..21282f443d 100644 --- a/gnss/common/utils/default/Utils.cpp +++ b/gnss/common/utils/default/Utils.cpp @@ -228,7 +228,8 @@ V1_0::GnssLocation Utils::getMockLocationV1_0() { .verticalAccuracyMeters = kMockVerticalAccuracyMeters, .speedAccuracyMetersPerSecond = kMockSpeedAccuracyMetersPerSecond, .bearingAccuracyDegrees = kMockBearingAccuracyDegrees, - .timestamp = kMockTimestamp}; + .timestamp = + static_cast(kMockTimestamp + ::android::elapsedRealtimeNano() / 1e6)}; return location; } -- GitLab From 3ea060eb6dab7ef26a1ec087d7dbc17193b88821 Mon Sep 17 00:00:00 2001 From: Yi-yo Chiang Date: Wed, 30 Dec 2020 07:34:58 +0000 Subject: [PATCH 354/790] Revert "Add emergencyDial_1_6 in the HAL to modify the multisim ..." Revert "Add cuttilefish implementation for emergencyDial_1_6" Revert submission 13164522-emergencyDial_1_6 Reason for revert: Potential culprit of b/176519828 Reverted Changes: I3680b8d42:Add cuttilefish implementation for emergencyDial_1... I94319ab34:Add emergencyDial_1_6 in the HAL to modify the mul... Change-Id: I17e59676b6467b8b51dcb839497883a2c89ee50d --- radio/1.6/IRadio.hal | 61 ------- .../1.6/vts/functional/radio_hidl_hal_api.cpp | 161 ------------------ .../vts/functional/radio_hidl_hal_test.cpp | 23 --- .../functional/radio_hidl_hal_utils_v1_6.h | 3 +- radio/1.6/vts/functional/radio_response.cpp | 10 +- 5 files changed, 4 insertions(+), 254 deletions(-) diff --git a/radio/1.6/IRadio.hal b/radio/1.6/IRadio.hal index 36d288fbc5..3dc80b9e22 100644 --- a/radio/1.6/IRadio.hal +++ b/radio/1.6/IRadio.hal @@ -18,12 +18,9 @@ package android.hardware.radio@1.6; import @1.0::CdmaSmsMessage; -import @1.0::Dial; import @1.0::GsmSmsMessage; import @1.1::CardPowerState; import @1.2::DataRequestReason; -import @1.4::EmergencyCallRouting; -import @1.4::EmergencyServiceCategory; import @1.4::RadioAccessFamily; import @1.5::IRadio; import @1.5::AccessNetwork; @@ -374,64 +371,6 @@ interface IRadio extends @1.5::IRadio { DataThrottlingAction dataThrottlingAction, int64_t completionDurationMillis); - /** - * Initiate emergency voice call, with zero or more emergency service category(s), zero or - * more emergency Uniform Resource Names (URN), and routing information for handling the call. - * Android uses this request to make its emergency call instead of using @1.0::IRadio.dial - * if the 'address' in the 'dialInfo' field is identified as an emergency number by Android. - * - * In multi-sim scenario, if the emergency number is from a specific subscription, this radio - * request can still be sent out on the other subscription as long as routing is set to - * @1.4::EmergencyNumberRouting#EMERGENCY. This radio request will not be sent on an inactive - * (PIN/PUK locked) subscription unless both subscriptions are PIN/PUK locked. In this case, - * the request will be sent on the primary subscription. - * - * Some countries or carriers require some emergency numbers that must be handled with normal - * call routing if possible or emergency routing. 1) if the 'routing' field is specified as - * @1.4::EmergencyNumberRouting#NORMAL, the implementation must try the full radio service to - * use normal call routing to handle the call; if service cannot support normal routing, the - * implementation must use emergency routing to handle the call. 2) if 'routing' is specified - * as @1.4::EmergencyNumberRouting#EMERGENCY, the implementation must use emergency routing to - * handle the call. 3) if 'routing' is specified as @1.4::EmergencyNumberRouting#UNKNOWN, - * Android does not know how to handle the call. - * - * If the dialed emergency number does not have a specified emergency service category, the - * 'categories' field is set to @1.4::EmergencyServiceCategory#UNSPECIFIED; if the dialed - * emergency number does not have specified emergency Uniform Resource Names, the 'urns' field - * is set to an empty list. If the underlying technology used to request emergency services - * does not support the emergency service category or emergency uniform resource names, the - * field 'categories' or 'urns' may be ignored. - * - * In the scenarios that the 'address' in the 'dialInfo' field has other functions besides the - * emergency number function, if the 'hasKnownUserIntentEmergency' field is true, the user's - * intent for this dial request is emergency call, and the modem must treat this as an actual - * emergency dial; if the 'hasKnownUserIntentEmergency' field is false, Android does not know - * user's intent for this call. - * - * If 'isTesting' is true, this request is for testing purpose, and must not be sent to a real - * emergency service; otherwise it's for a real emergency call request. - * - * Reference: 3gpp 22.101, Section 10 - Emergency Calls; - * 3gpp 23.167, Section 6 - Functional description; - * 3gpp 24.503, Section 5.1.6.8.1 - General; - * RFC 5031 - * - * @param serial Serial number of request. - * @param dialInfo the same @1.0::Dial information used by @1.0::IRadio.dial. - * @param categories bitfield<@1.4::EmergencyServiceCategory> the Emergency Service Category(s) - * of the call. - * @param urns the emergency Uniform Resource Names (URN) - * @param routing @1.4::EmergencyCallRouting the emergency call routing information. - * @param hasKnownUserIntentEmergency Flag indicating if user's intent for the emergency call - * is known. - * @param isTesting Flag indicating if this request is for testing purpose. - * - * Response function is IRadioResponse.emergencyDialResponse() - */ - oneway emergencyDial_1_6(int32_t serial, Dial dialInfo, - bitfield categories, vec urns, - EmergencyCallRouting routing, bool hasKnownUserIntentEmergency, bool isTesting); - /** * Get which bands the modem's background scan is acting on. * diff --git a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp index c8846d2242..47babed32e 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp +++ b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp @@ -407,167 +407,6 @@ TEST_P(RadioHidlTest_v1_6, setSimCardPower_1_6) { } } -/* - * Test IRadio.emergencyDial() for the response returned. - */ -TEST_P(RadioHidlTest_v1_6, emergencyDial_1_6) { - if (!deviceSupportsFeature(FEATURE_VOICE_CALL)) { - ALOGI("Skipping emergencyDial because voice call is not supported in device"); - return; - } else { - ALOGI("Running emergencyDial because voice call is supported in device"); - } - - serial = GetRandomSerialNumber(); - - ::android::hardware::radio::V1_0::Dial dialInfo; - dialInfo.address = hidl_string("911"); - int categories = static_cast( - ::android::hardware::radio::V1_4::EmergencyServiceCategory::UNSPECIFIED); - std::vector urns = {""}; - ::android::hardware::radio::V1_4::EmergencyCallRouting routing = - ::android::hardware::radio::V1_4::EmergencyCallRouting::UNKNOWN; - - Return res = - radio_v1_6->emergencyDial_1_6(serial, dialInfo, categories, urns, routing, true, true); - ASSERT_OK(res); - EXPECT_EQ(std::cv_status::no_timeout, wait()); - EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo_v1_0.type); - EXPECT_EQ(serial, radioRsp_v1_6->rspInfo_v1_0.serial); - - ALOGI("emergencyDial, rspInfo_v1_0.error = %s\n", - toString(radioRsp_v1_6->rspInfo_v1_0.error).c_str()); - - ::android::hardware::radio::V1_0::RadioError rspEmergencyDial = - radioRsp_v1_6->rspInfo_v1_0.error; - // In DSDS or TSTS, we only check the result if the current slot is IN_SERVICE - // or Emergency_Only. - if (isDsDsEnabled() || isTsTsEnabled()) { - serial = GetRandomSerialNumber(); - radio_v1_6->getVoiceRegistrationState(serial); - EXPECT_EQ(std::cv_status::no_timeout, wait()); - if (isVoiceEmergencyOnly(radioRsp_v1_6->voiceRegResp.regState) || - isVoiceInService(radioRsp_v1_6->voiceRegResp.regState)) { - EXPECT_EQ(::android::hardware::radio::V1_0::RadioError::NONE, rspEmergencyDial); - } - } else { - EXPECT_EQ(::android::hardware::radio::V1_0::RadioError::NONE, rspEmergencyDial); - } - - // Give some time for modem to establish the emergency call channel. - sleep(MODEM_EMERGENCY_CALL_ESTABLISH_TIME); - - // Disconnect all the potential established calls to prevent them affecting other tests. - clearPotentialEstablishedCalls(); -} - -/* - * Test IRadio.emergencyDial() with specified service and its response returned. - */ -TEST_P(RadioHidlTest_v1_6, emergencyDial_1_6_withServices) { - if (!deviceSupportsFeature(FEATURE_VOICE_CALL)) { - ALOGI("Skipping emergencyDial because voice call is not supported in device"); - return; - } else { - ALOGI("Running emergencyDial because voice call is supported in device"); - } - - serial = GetRandomSerialNumber(); - - ::android::hardware::radio::V1_0::Dial dialInfo; - dialInfo.address = hidl_string("911"); - int categories = - static_cast(::android::hardware::radio::V1_4::EmergencyServiceCategory::AMBULANCE); - std::vector urns = {"urn:service:sos.ambulance"}; - ::android::hardware::radio::V1_4::EmergencyCallRouting routing = - ::android::hardware::radio::V1_4::EmergencyCallRouting::UNKNOWN; - - Return res = - radio_v1_6->emergencyDial_1_6(serial, dialInfo, categories, urns, routing, true, true); - ASSERT_OK(res); - EXPECT_EQ(std::cv_status::no_timeout, wait()); - EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo_v1_0.type); - EXPECT_EQ(serial, radioRsp_v1_6->rspInfo_v1_0.serial); - - ALOGI("emergencyDial_withServices, rspInfo_v1_0.error = %s\n", - toString(radioRsp_v1_6->rspInfo_v1_0.error).c_str()); - ::android::hardware::radio::V1_0::RadioError rspEmergencyDial = - radioRsp_v1_6->rspInfo_v1_0.error; - - // In DSDS or TSTS, we only check the result if the current slot is IN_SERVICE - // or Emergency_Only. - if (isDsDsEnabled() || isTsTsEnabled()) { - serial = GetRandomSerialNumber(); - radio_v1_6->getVoiceRegistrationState(serial); - EXPECT_EQ(std::cv_status::no_timeout, wait()); - if (isVoiceEmergencyOnly(radioRsp_v1_6->voiceRegResp.regState) || - isVoiceInService(radioRsp_v1_6->voiceRegResp.regState)) { - EXPECT_EQ(::android::hardware::radio::V1_0::RadioError::NONE, rspEmergencyDial); - } - } else { - EXPECT_EQ(::android::hardware::radio::V1_0::RadioError::NONE, rspEmergencyDial); - } - // Give some time for modem to establish the emergency call channel. - sleep(MODEM_EMERGENCY_CALL_ESTABLISH_TIME); - - // Disconnect all the potential established calls to prevent them affecting other tests. - clearPotentialEstablishedCalls(); -} - -/* - * Test IRadio.emergencyDial() with known emergency call routing and its response returned. - */ -TEST_P(RadioHidlTest_v1_6, emergencyDial_1_6_withEmergencyRouting) { - if (!deviceSupportsFeature(FEATURE_VOICE_CALL)) { - ALOGI("Skipping emergencyDial because voice call is not supported in device"); - return; - } else { - ALOGI("Running emergencyDial because voice call is supported in device"); - } - - serial = GetRandomSerialNumber(); - - ::android::hardware::radio::V1_0::Dial dialInfo; - dialInfo.address = hidl_string("911"); - int categories = static_cast( - ::android::hardware::radio::V1_4::EmergencyServiceCategory::UNSPECIFIED); - std::vector urns = {""}; - ::android::hardware::radio::V1_4::EmergencyCallRouting routing = - ::android::hardware::radio::V1_4::EmergencyCallRouting::EMERGENCY; - - Return res = - radio_v1_6->emergencyDial_1_6(serial, dialInfo, categories, urns, routing, true, true); - ASSERT_OK(res); - EXPECT_EQ(std::cv_status::no_timeout, wait()); - EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo_v1_0.type); - EXPECT_EQ(serial, radioRsp_v1_6->rspInfo_v1_0.serial); - - ALOGI("emergencyDial_withEmergencyRouting, rspInfo_v1_0.error = %s\n", - toString(radioRsp_v1_6->rspInfo_v1_0.error).c_str()); - ::android::hardware::radio::V1_0::RadioError rspEmergencyDial = - radioRsp_v1_6->rspInfo_v1_0.error; - - // In DSDS or TSTS, we only check the result if the current slot is IN_SERVICE - // or Emergency_Only. - if (isDsDsEnabled() || isTsTsEnabled()) { - serial = GetRandomSerialNumber(); - radio_v1_6->getVoiceRegistrationState(serial); - EXPECT_EQ(std::cv_status::no_timeout, wait()); - if (isVoiceEmergencyOnly(radioRsp_v1_6->voiceRegResp.regState) || - isVoiceInService(radioRsp_v1_6->voiceRegResp.regState)) { - EXPECT_EQ(::android::hardware::radio::V1_0::RadioError::NONE, rspEmergencyDial); - } - } else { - EXPECT_EQ(::android::hardware::radio::V1_0::RadioError::NONE, rspEmergencyDial); - } - - // Give some time for modem to establish the emergency call channel. - sleep(MODEM_EMERGENCY_CALL_ESTABLISH_TIME); - - // Disconnect all the potential established calls to prevent them affecting other tests. - clearPotentialEstablishedCalls(); -} - /* * Test IRadio.getCurrentCalls_1_6() for the response returned. */ diff --git a/radio/1.6/vts/functional/radio_hidl_hal_test.cpp b/radio/1.6/vts/functional/radio_hidl_hal_test.cpp index 59f768201d..79c3cde745 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_test.cpp +++ b/radio/1.6/vts/functional/radio_hidl_hal_test.cpp @@ -74,29 +74,6 @@ std::cv_status RadioHidlTest_v1_6::wait() { return status; } -void RadioHidlTest_v1_6::clearPotentialEstablishedCalls() { - // Get the current call Id to hangup the established emergency call. - serial = GetRandomSerialNumber(); - radio_v1_6->getCurrentCalls_1_6(serial); - EXPECT_EQ(std::cv_status::no_timeout, wait()); - - // Hang up to disconnect the established call channels. - for (const ::android::hardware::radio::V1_6::Call& call : radioRsp_v1_6->currentCalls) { - serial = GetRandomSerialNumber(); - radio_v1_6->hangup(serial, call.base.base.index); - ALOGI("Hang up to disconnect the established call channel: %d", call.base.base.index); - EXPECT_EQ(std::cv_status::no_timeout, wait()); - // Give some time for modem to disconnect the established call channel. - sleep(MODEM_EMERGENCY_CALL_DISCONNECT_TIME); - } - - // Verify there are no more current calls. - serial = GetRandomSerialNumber(); - radio_v1_6->getCurrentCalls_1_6(serial); - EXPECT_EQ(std::cv_status::no_timeout, wait()); - EXPECT_EQ(0, radioRsp_v1_6->currentCalls.size()); -} - void RadioHidlTest_v1_6::updateSimCardStatus() { serial = GetRandomSerialNumber(); radio_v1_6->getIccCardStatus(serial); diff --git a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h index e41b807484..fbcd7a9339 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h +++ b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h @@ -70,8 +70,7 @@ class RadioResponse_v1_6 : public ::android::hardware::radio::V1_6::IRadioRespon ::android::hardware::radio::V1_6::RadioResponseInfo rspInfo; // Call - hidl_vec<::android::hardware::radio::V1_6::Call> currentCalls; - ::android::hardware::radio::V1_2::VoiceRegStateResult voiceRegResp; + hidl_vec<::android::hardware::radio::V1_2::Call> currentCalls; // Sms SendSmsResult sendSmsResult; diff --git a/radio/1.6/vts/functional/radio_response.cpp b/radio/1.6/vts/functional/radio_response.cpp index ba84fd45b3..7c5cf6df86 100644 --- a/radio/1.6/vts/functional/radio_response.cpp +++ b/radio/1.6/vts/functional/radio_response.cpp @@ -816,11 +816,8 @@ Return RadioResponse_v1_6::getCellInfoListResponse_1_2( } Return RadioResponse_v1_6::getVoiceRegistrationStateResponse_1_2( - const ::android::hardware::radio::V1_0::RadioResponseInfo& info, - const ::android::hardware::radio::V1_2::VoiceRegStateResult& voiceRegResponse) { - rspInfo_v1_0 = info; - voiceRegResp = voiceRegResponse; - parent_v1_6.notify(info.serial); + const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, + const ::android::hardware::radio::V1_2::VoiceRegStateResult& /*voiceRegResponse*/) { return Void(); } @@ -1213,9 +1210,8 @@ Return RadioResponse_v1_6::getDataRegistrationStateResponse_1_6( Return RadioResponse_v1_6::getCurrentCallsResponse_1_6( const ::android::hardware::radio::V1_6::RadioResponseInfo& info, - const ::android::hardware::hidl_vec<::android::hardware::radio::V1_6::Call>& calls) { + const ::android::hardware::hidl_vec<::android::hardware::radio::V1_6::Call>& /*calls*/) { rspInfo = info; - currentCalls = calls; parent_v1_6.notify(info.serial); return Void(); } -- GitLab From 0eb468d82d27a35e941c59fe7eaa22df7b5a8669 Mon Sep 17 00:00:00 2001 From: samou Date: Wed, 9 Dec 2020 20:10:36 +0000 Subject: [PATCH 355/790] power/stats: Add EnergyConsumerAttribution interface Bug: 172576334 Test: build pass Change-Id: I4a02a3cb9a20bd371cf1c0bf0c891eecb0283fbe --- .../stats/EnergyConsumerAttribution.aidl | 23 +++++++++++++++ .../power/stats/EnergyConsumerResult.aidl | 1 + .../stats/EnergyConsumerAttribution.aidl | 29 +++++++++++++++++++ .../power/stats/EnergyConsumerResult.aidl | 5 ++++ 4 files changed, 58 insertions(+) create mode 100644 power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerAttribution.aidl create mode 100644 power/stats/aidl/android/hardware/power/stats/EnergyConsumerAttribution.aidl diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerAttribution.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerAttribution.aidl new file mode 100644 index 0000000000..0a7cff7d01 --- /dev/null +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerAttribution.aidl @@ -0,0 +1,23 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL interface (or parcelable). Do not try to +// edit this file. It looks like you are doing that because you have modified +// an AIDL interface in a backward-incompatible way, e.g., deleting a function +// from an interface or a field from a parcelable and it broke the build. That +// breakage is intended. +// +// You must not make a backward incompatible changes to the AIDL files 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.power.stats; +@VintfStability +parcelable EnergyConsumerAttribution { + int uid; + long energyUWs; +} diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerResult.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerResult.aidl index 6289a08439..815316ec92 100644 --- a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerResult.aidl +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerResult.aidl @@ -21,4 +21,5 @@ parcelable EnergyConsumerResult { android.hardware.power.stats.EnergyConsumerId energyConsumerId; long timestampMs; long energyUWs; + android.hardware.power.stats.EnergyConsumerAttribution[] attribution; } diff --git a/power/stats/aidl/android/hardware/power/stats/EnergyConsumerAttribution.aidl b/power/stats/aidl/android/hardware/power/stats/EnergyConsumerAttribution.aidl new file mode 100644 index 0000000000..e07204aa33 --- /dev/null +++ b/power/stats/aidl/android/hardware/power/stats/EnergyConsumerAttribution.aidl @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.power.stats; + +@VintfStability +parcelable EnergyConsumerAttribution { + /** + * Android ID / Linux UID, the accumulated energy should be attributed to + */ + int uid; + /** + * Accumulated energy since boot in microwatt-seconds (uWs) for this AID + */ + long energyUWs; +} diff --git a/power/stats/aidl/android/hardware/power/stats/EnergyConsumerResult.aidl b/power/stats/aidl/android/hardware/power/stats/EnergyConsumerResult.aidl index d2b902ae56..e8d3dd9f94 100644 --- a/power/stats/aidl/android/hardware/power/stats/EnergyConsumerResult.aidl +++ b/power/stats/aidl/android/hardware/power/stats/EnergyConsumerResult.aidl @@ -17,6 +17,7 @@ package android.hardware.power.stats; import android.hardware.power.stats.EnergyConsumerId; +import android.hardware.power.stats.EnergyConsumerAttribution; @VintfStability parcelable EnergyConsumerResult { @@ -32,5 +33,9 @@ parcelable EnergyConsumerResult { * Accumulated energy since boot in microwatt-seconds (uWs) */ long energyUWs; + /** + * Optional attribution per UID for this EnergyConsumer. + */ + EnergyConsumerAttribution[] attribution; } -- GitLab From 78471d9a2476bf6b04a6a858b127fb30a0d74d1a Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Wed, 30 Dec 2020 17:12:41 -0800 Subject: [PATCH 356/790] Instead of including wifi_hal.h in the legacy_hal namespace, import the types. Including the header inside a namespace leads to ODR violations, which are normally benign but can cause problems if we want to use something like CFI in the wifi HAL. Change-Id: I80cc854632da7e18e5c208ba9210de44b31abbdb --- wifi/1.5/default/wifi_legacy_hal.h | 283 ++++++++++++++++++++++- wifi/1.5/default/wifi_legacy_hal_stubs.h | 3 +- 2 files changed, 276 insertions(+), 10 deletions(-) diff --git a/wifi/1.5/default/wifi_legacy_hal.h b/wifi/1.5/default/wifi_legacy_hal.h index 11efe7efef..610a3326d1 100644 --- a/wifi/1.5/default/wifi_legacy_hal.h +++ b/wifi/1.5/default/wifi_legacy_hal.h @@ -23,15 +23,9 @@ #include #include +#include #include -// HACK: The include inside the namespace below also transitively includes a -// bunch of libc headers into the namespace, which leads to functions like -// socketpair being defined in -// android::hardware::wifi::V1_1::implementation::legacy_hal. Include this one -// particular header as a hacky workaround until that's fixed. -#include - namespace android { namespace hardware { namespace wifi { @@ -40,9 +34,280 @@ namespace implementation { // This is in a separate namespace to prevent typename conflicts between // the legacy HAL types and the HIDL interface types. namespace legacy_hal { -// Wrap all the types defined inside the legacy HAL header files inside this +// Import all the types defined inside the legacy HAL header files into this // namespace. -#include +using ::FRAME_TYPE_80211_MGMT; +using ::FRAME_TYPE_ETHERNET_II; +using ::FRAME_TYPE_UNKNOWN; +using ::NAN_CHANNEL_24G_BAND; +using ::NAN_CHANNEL_5G_BAND_HIGH; +using ::NAN_CHANNEL_5G_BAND_LOW; +using ::NAN_DISABLE_RANGE_REPORT; +using ::NAN_DO_NOT_USE_SRF; +using ::NAN_DP_CHANNEL_NOT_REQUESTED; +using ::NAN_DP_CONFIG_NO_SECURITY; +using ::NAN_DP_CONFIG_SECURITY; +using ::NAN_DP_END; +using ::NAN_DP_FORCE_CHANNEL_SETUP; +using ::NAN_DP_INITIATOR_RESPONSE; +using ::NAN_DP_INTERFACE_CREATE; +using ::NAN_DP_INTERFACE_DELETE; +using ::NAN_DP_REQUEST_ACCEPT; +using ::NAN_DP_REQUEST_CHANNEL_SETUP; +using ::NAN_DP_REQUEST_REJECT; +using ::NAN_DP_RESPONDER_RESPONSE; +using ::NAN_GET_CAPABILITIES; +using ::NAN_MATCH_ALG_MATCH_CONTINUOUS; +using ::NAN_MATCH_ALG_MATCH_NEVER; +using ::NAN_MATCH_ALG_MATCH_ONCE; +using ::NAN_PUBLISH_TYPE_SOLICITED; +using ::NAN_PUBLISH_TYPE_UNSOLICITED; +using ::NAN_PUBLISH_TYPE_UNSOLICITED_SOLICITED; +using ::NAN_RANGING_AUTO_RESPONSE_DISABLE; +using ::NAN_RANGING_AUTO_RESPONSE_ENABLE; +using ::NAN_RANGING_DISABLE; +using ::NAN_RANGING_ENABLE; +using ::NAN_RESPONSE_BEACON_SDF_PAYLOAD; +using ::NAN_RESPONSE_CONFIG; +using ::NAN_RESPONSE_DISABLED; +using ::NAN_RESPONSE_ENABLED; +using ::NAN_RESPONSE_ERROR; +using ::NAN_RESPONSE_PUBLISH; +using ::NAN_RESPONSE_PUBLISH_CANCEL; +using ::NAN_RESPONSE_STATS; +using ::NAN_RESPONSE_SUBSCRIBE; +using ::NAN_RESPONSE_SUBSCRIBE_CANCEL; +using ::NAN_RESPONSE_TCA; +using ::NAN_RESPONSE_TRANSMIT_FOLLOWUP; +using ::NAN_SECURITY_KEY_INPUT_PASSPHRASE; +using ::NAN_SECURITY_KEY_INPUT_PASSPHRASE; +using ::NAN_SECURITY_KEY_INPUT_PMK; +using ::NAN_SECURITY_KEY_INPUT_PMK; +using ::NAN_SERVICE_ACCEPT_POLICY_ALL; +using ::NAN_SERVICE_ACCEPT_POLICY_NONE; +using ::NAN_SRF_ATTR_BLOOM_FILTER; +using ::NAN_SRF_ATTR_PARTIAL_MAC_ADDR; +using ::NAN_SRF_INCLUDE_DO_NOT_RESPOND; +using ::NAN_SRF_INCLUDE_RESPOND; +using ::NAN_SSI_NOT_REQUIRED_IN_MATCH_IND; +using ::NAN_SSI_REQUIRED_IN_MATCH_IND; +using ::NAN_STATUS_ALREADY_ENABLED; +using ::NAN_STATUS_FOLLOWUP_QUEUE_FULL; +using ::NAN_STATUS_INTERNAL_FAILURE; +using ::NAN_STATUS_INVALID_NDP_ID; +using ::NAN_STATUS_INVALID_PARAM; +using ::NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID; +using ::NAN_STATUS_INVALID_REQUESTOR_INSTANCE_ID; +using ::NAN_STATUS_NAN_NOT_ALLOWED; +using ::NAN_STATUS_NO_OTA_ACK; +using ::NAN_STATUS_NO_RESOURCE_AVAILABLE; +using ::NAN_STATUS_PROTOCOL_FAILURE; +using ::NAN_STATUS_SUCCESS; +using ::NAN_STATUS_UNSUPPORTED_CONCURRENCY_NAN_DISABLED; +using ::NAN_SUBSCRIBE_TYPE_ACTIVE; +using ::NAN_SUBSCRIBE_TYPE_PASSIVE; +using ::NAN_TRANSMIT_IN_DW; +using ::NAN_TRANSMIT_IN_FAW; +using ::NAN_TX_PRIORITY_HIGH; +using ::NAN_TX_PRIORITY_NORMAL; +using ::NAN_TX_TYPE_BROADCAST; +using ::NAN_TX_TYPE_UNICAST; +using ::NAN_USE_SRF; +using ::NanBeaconSdfPayloadInd; +using ::NanCapabilities; +using ::NanChannelInfo; +using ::NanConfigRequest; +using ::NanDataPathChannelCfg; +using ::NanDataPathConfirmInd; +using ::NanDataPathEndInd; +using ::NanDataPathIndicationResponse; +using ::NanDataPathInitiatorRequest; +using ::NanDataPathRequestInd; +using ::NanDataPathScheduleUpdateInd; +using ::NanDisabledInd; +using ::NanDiscEngEventInd; +using ::NanEnableRequest; +using ::NanFollowupInd; +using ::NanMatchAlg; +using ::NanMatchExpiredInd; +using ::NanMatchInd; +using ::NanPublishCancelRequest; +using ::NanPublishRequest; +using ::NanPublishTerminatedInd; +using ::NanPublishType; +using ::NanRangeReportInd; +using ::NanRangeRequestInd; +using ::NanResponseMsg; +using ::NanSRFType; +using ::NanStatusType; +using ::NanSubscribeCancelRequest; +using ::NanSubscribeRequest; +using ::NanSubscribeTerminatedInd; +using ::NanSubscribeType; +using ::NanTransmitFollowupInd; +using ::NanTransmitFollowupRequest; +using ::NanTxType; +using ::ROAMING_DISABLE; +using ::ROAMING_ENABLE; +using ::RTT_PEER_AP; +using ::RTT_PEER_NAN; +using ::RTT_PEER_P2P_CLIENT; +using ::RTT_PEER_P2P_GO; +using ::RTT_PEER_STA; +using ::RTT_STATUS_ABORTED; +using ::RTT_STATUS_FAILURE; +using ::RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL; +using ::RTT_STATUS_FAIL_BUSY_TRY_LATER; +using ::RTT_STATUS_FAIL_FTM_PARAM_OVERRIDE; +using ::RTT_STATUS_FAIL_INVALID_TS; +using ::RTT_STATUS_FAIL_NOT_SCHEDULED_YET; +using ::RTT_STATUS_FAIL_NO_CAPABILITY; +using ::RTT_STATUS_FAIL_NO_RSP; +using ::RTT_STATUS_FAIL_PROTOCOL; +using ::RTT_STATUS_FAIL_REJECTED; +using ::RTT_STATUS_FAIL_SCHEDULE; +using ::RTT_STATUS_FAIL_TM_TIMEOUT; +using ::RTT_STATUS_INVALID_REQ; +using ::RTT_STATUS_NAN_RANGING_CONCURRENCY_NOT_SUPPORTED; +using ::RTT_STATUS_NAN_RANGING_PROTOCOL_FAILURE; +using ::RTT_STATUS_NO_WIFI; +using ::RTT_STATUS_SUCCESS; +using ::RTT_TYPE_1_SIDED; +using ::RTT_TYPE_2_SIDED; +using ::RX_PKT_FATE_DRV_DROP_FILTER; +using ::RX_PKT_FATE_DRV_DROP_INVALID; +using ::RX_PKT_FATE_DRV_DROP_NOBUFS; +using ::RX_PKT_FATE_DRV_DROP_OTHER; +using ::RX_PKT_FATE_DRV_QUEUED; +using ::RX_PKT_FATE_FW_DROP_FILTER; +using ::RX_PKT_FATE_FW_DROP_INVALID; +using ::RX_PKT_FATE_FW_DROP_NOBUFS; +using ::RX_PKT_FATE_FW_DROP_OTHER; +using ::RX_PKT_FATE_FW_QUEUED; +using ::RX_PKT_FATE_SUCCESS; +using ::TX_PKT_FATE_ACKED; +using ::TX_PKT_FATE_DRV_DROP_INVALID; +using ::TX_PKT_FATE_DRV_DROP_NOBUFS; +using ::TX_PKT_FATE_DRV_DROP_OTHER; +using ::TX_PKT_FATE_DRV_QUEUED; +using ::TX_PKT_FATE_FW_DROP_INVALID; +using ::TX_PKT_FATE_FW_DROP_NOBUFS; +using ::TX_PKT_FATE_FW_DROP_OTHER; +using ::TX_PKT_FATE_FW_QUEUED; +using ::TX_PKT_FATE_SENT; +using ::WIFI_AC_BE; +using ::WIFI_AC_BK; +using ::WIFI_AC_VI; +using ::WIFI_AC_VO; +using ::WIFI_BAND_A; +using ::WIFI_BAND_ABG; +using ::WIFI_BAND_ABG_WITH_DFS; +using ::WIFI_BAND_A_DFS; +using ::WIFI_BAND_A_WITH_DFS; +using ::WIFI_BAND_BG; +using ::WIFI_BAND_UNSPECIFIED; +using ::WIFI_CHAN_WIDTH_10; +using ::WIFI_CHAN_WIDTH_160; +using ::WIFI_CHAN_WIDTH_20; +using ::WIFI_CHAN_WIDTH_40; +using ::WIFI_CHAN_WIDTH_5; +using ::WIFI_CHAN_WIDTH_5; +using ::WIFI_CHAN_WIDTH_80; +using ::WIFI_CHAN_WIDTH_80P80; +using ::WIFI_CHAN_WIDTH_INVALID; +using ::WIFI_DUAL_STA_NON_TRANSIENT_UNBIASED; +using ::WIFI_DUAL_STA_TRANSIENT_PREFER_PRIMARY; +using ::WIFI_ERROR_BUSY; +using ::WIFI_ERROR_INVALID_ARGS; +using ::WIFI_ERROR_INVALID_REQUEST_ID; +using ::WIFI_ERROR_NONE; +using ::WIFI_ERROR_NOT_AVAILABLE; +using ::WIFI_ERROR_NOT_SUPPORTED; +using ::WIFI_ERROR_OUT_OF_MEMORY; +using ::WIFI_ERROR_TIMED_OUT; +using ::WIFI_ERROR_TOO_MANY_REQUESTS; +using ::WIFI_ERROR_UNINITIALIZED; +using ::WIFI_ERROR_UNKNOWN; +using ::WIFI_INTERFACE_TYPE_AP; +using ::WIFI_INTERFACE_TYPE_NAN; +using ::WIFI_INTERFACE_TYPE_P2P; +using ::WIFI_INTERFACE_TYPE_STA; +using ::WIFI_LATENCY_MODE_LOW; +using ::WIFI_LATENCY_MODE_NORMAL; +using ::WIFI_LOGGER_CONNECT_EVENT_SUPPORTED; +using ::WIFI_LOGGER_DRIVER_DUMP_SUPPORTED; +using ::WIFI_LOGGER_MEMORY_DUMP_SUPPORTED; +using ::WIFI_LOGGER_PACKET_FATE_SUPPORTED; +using ::WIFI_LOGGER_POWER_EVENT_SUPPORTED; +using ::WIFI_LOGGER_WAKE_LOCK_SUPPORTED; +using ::WIFI_MOTION_EXPECTED; +using ::WIFI_MOTION_NOT_EXPECTED; +using ::WIFI_MOTION_UNKNOWN; +using ::WIFI_POWER_SCENARIO_ON_BODY_CELL_OFF; +using ::WIFI_POWER_SCENARIO_ON_BODY_CELL_ON; +using ::WIFI_POWER_SCENARIO_ON_HEAD_CELL_OFF; +using ::WIFI_POWER_SCENARIO_ON_HEAD_CELL_ON; +using ::WIFI_POWER_SCENARIO_VOICE_CALL; +using ::WIFI_RTT_BW_10; +using ::WIFI_RTT_BW_160; +using ::WIFI_RTT_BW_20; +using ::WIFI_RTT_BW_40; +using ::WIFI_RTT_BW_5; +using ::WIFI_RTT_BW_80; +using ::WIFI_RTT_PREAMBLE_HE; +using ::WIFI_RTT_PREAMBLE_HT; +using ::WIFI_RTT_PREAMBLE_LEGACY; +using ::WIFI_RTT_PREAMBLE_VHT; +using ::WIFI_SCAN_FLAG_INTERRUPTED; +using ::WIFI_SUCCESS; +using ::WLAN_MAC_2_4_BAND; +using ::WLAN_MAC_5_0_BAND; +using ::WLAN_MAC_6_0_BAND; +using ::frame_info; +using ::frame_type; +using ::fw_roaming_state_t; +using ::mac_addr; +using ::rtt_peer_type; +using ::ssid_t; +using ::transaction_id; +using ::wifi_band; +using ::wifi_cached_scan_results; +using ::wifi_channel_info; +using ::wifi_channel_stat; +using ::wifi_channel_width; +using ::wifi_coex_restriction; +using ::wifi_coex_unsafe_channel; +using ::wifi_error; +using ::wifi_gscan_capabilities; +using ::wifi_hal_fn; +using ::wifi_information_element; +using ::wifi_interface_type; +using ::wifi_latency_mode; +using ::wifi_lci_information; +using ::wifi_lcr_information; +using ::wifi_motion_pattern; +using ::wifi_multi_sta_use_case; +using ::wifi_power_scenario; +using ::wifi_rate; +using ::wifi_request_id; +using ::wifi_ring_buffer_status; +using ::wifi_roaming_capabilities; +using ::wifi_roaming_config; +using ::wifi_rtt_bw; +using ::wifi_rtt_capabilities; +using ::wifi_rtt_config; +using ::wifi_rtt_preamble; +using ::wifi_rtt_responder; +using ::wifi_rtt_result; +using ::wifi_rtt_status; +using ::wifi_rtt_type; +using ::wifi_rx_packet_fate; +using ::wifi_rx_report; +using ::wifi_scan_bucket_spec; +using ::wifi_scan_cmd_params; +using ::wifi_scan_result; +using ::wifi_tx_packet_fate; +using ::wifi_tx_report; // APF capabilities supported by the iface. struct PacketFilterCapabilities { diff --git a/wifi/1.5/default/wifi_legacy_hal_stubs.h b/wifi/1.5/default/wifi_legacy_hal_stubs.h index 7e4eb0a0fd..480389b0ce 100644 --- a/wifi/1.5/default/wifi_legacy_hal_stubs.h +++ b/wifi/1.5/default/wifi_legacy_hal_stubs.h @@ -17,13 +17,14 @@ #ifndef WIFI_LEGACY_HAL_STUBS_H_ #define WIFI_LEGACY_HAL_STUBS_H_ +#include + namespace android { namespace hardware { namespace wifi { namespace V1_5 { namespace implementation { namespace legacy_hal { -#include bool initHalFuncTableWithStubs(wifi_hal_fn* hal_fn); } // namespace legacy_hal -- GitLab From cb09e87a520aa2fa7aa2a291c2962c4dc26558cb Mon Sep 17 00:00:00 2001 From: Zhomart Mukhamejanov Date: Tue, 5 Jan 2021 14:56:25 -0800 Subject: [PATCH 357/790] Add timestamp details in docs Bug: 176847000 Change-Id: Id8dc26c14a42f5622cf9fac935d94f2fe2918d67 Test: n/a --- automotive/vehicle/2.0/types.hal | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/automotive/vehicle/2.0/types.hal b/automotive/vehicle/2.0/types.hal index 931fee4a23..da48b3cdba 100644 --- a/automotive/vehicle/2.0/types.hal +++ b/automotive/vehicle/2.0/types.hal @@ -3691,7 +3691,10 @@ struct VehiclePropConfig { * events. */ struct VehiclePropValue { - /** Time is elapsed nanoseconds since boot */ + /** + * Time is elapsed nanoseconds since boot. It's equivalent to + * {@code SystemClock.elapsedRealtimeNano()}. + */ int64_t timestamp; /** -- GitLab From 667dc2dcacba5341a79ac520ce712d2ce4cae1cc Mon Sep 17 00:00:00 2001 From: Michael Butler Date: Tue, 29 Dec 2020 18:56:44 -0800 Subject: [PATCH 358/790] Add recovery code to NN ResilientPreparedModel and *Buffer Prior to this CL, ResilientPreparedModel and ResilientBuffer were passthrough interfaces that just forwarded calls to the underlying interface object. This CL implements the full recovery mechanism for these two classes. However, because we do not want to enable this functionality in the NN runtime yet, ResilientDevice hides the paths that create ResilientPreparedModel and ResilientBuffer behind an #if until we want to enable those paths. Bug: N/A Test: mma Change-Id: Idfe8093c63c7ba2f16c995eec872d150696e7a08 --- .../include/nnapi/hal/ResilientBuffer.h | 2 +- .../nnapi/hal/ResilientPreparedModel.h | 4 +- .../utils/common/src/ResilientBuffer.cpp | 48 ++++++++++++++-- .../utils/common/src/ResilientDevice.cpp | 19 ++++++- .../common/src/ResilientPreparedModel.cpp | 55 +++++++++++++++++-- 5 files changed, 113 insertions(+), 15 deletions(-) diff --git a/neuralnetworks/utils/common/include/nnapi/hal/ResilientBuffer.h b/neuralnetworks/utils/common/include/nnapi/hal/ResilientBuffer.h index 9d5e3e6a05..d2c2469403 100644 --- a/neuralnetworks/utils/common/include/nnapi/hal/ResilientBuffer.h +++ b/neuralnetworks/utils/common/include/nnapi/hal/ResilientBuffer.h @@ -42,7 +42,7 @@ class ResilientBuffer final : public nn::IBuffer { nn::SharedBuffer buffer); nn::SharedBuffer getBuffer() const; - nn::SharedBuffer recover(const nn::IBuffer* failingBuffer, bool blocking) const; + nn::GeneralResult recover(const nn::IBuffer* failingBuffer) const; nn::Request::MemoryDomainToken getToken() const override; diff --git a/neuralnetworks/utils/common/include/nnapi/hal/ResilientPreparedModel.h b/neuralnetworks/utils/common/include/nnapi/hal/ResilientPreparedModel.h index faae673ba7..9b8d92435c 100644 --- a/neuralnetworks/utils/common/include/nnapi/hal/ResilientPreparedModel.h +++ b/neuralnetworks/utils/common/include/nnapi/hal/ResilientPreparedModel.h @@ -43,8 +43,8 @@ class ResilientPreparedModel final : public nn::IPreparedModel { nn::SharedPreparedModel preparedModel); nn::SharedPreparedModel getPreparedModel() const; - nn::SharedPreparedModel recover(const nn::IPreparedModel* failingPreparedModel, - bool blocking) const; + nn::GeneralResult recover( + const nn::IPreparedModel* failingPreparedModel) const; nn::ExecutionResult, nn::Timing>> execute( const nn::Request& request, nn::MeasureTiming measure, diff --git a/neuralnetworks/utils/common/src/ResilientBuffer.cpp b/neuralnetworks/utils/common/src/ResilientBuffer.cpp index cf5496ac39..47abbe268f 100644 --- a/neuralnetworks/utils/common/src/ResilientBuffer.cpp +++ b/neuralnetworks/utils/common/src/ResilientBuffer.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -29,6 +30,34 @@ #include namespace android::hardware::neuralnetworks::utils { +namespace { + +template +auto protect(const ResilientBuffer& resilientBuffer, const FnType& fn) + -> decltype(fn(*resilientBuffer.getBuffer())) { + auto buffer = resilientBuffer.getBuffer(); + auto result = fn(*buffer); + + // Immediately return if device is not dead. + if (result.has_value() || result.error().code != nn::ErrorStatus::DEAD_OBJECT) { + return result; + } + + // Attempt recovery and return if it fails. + auto maybeBuffer = resilientBuffer.recover(buffer.get()); + if (!maybeBuffer.has_value()) { + const auto& [resultErrorMessage, resultErrorCode] = result.error(); + const auto& [recoveryErrorMessage, recoveryErrorCode] = maybeBuffer.error(); + return nn::error(resultErrorCode) + << resultErrorMessage << ", and failed to recover dead buffer with error " + << recoveryErrorCode << ": " << recoveryErrorMessage; + } + buffer = std::move(maybeBuffer).value(); + + return fn(*buffer); +} + +} // namespace nn::GeneralResult> ResilientBuffer::create( Factory makeBuffer) { @@ -53,9 +82,16 @@ nn::SharedBuffer ResilientBuffer::getBuffer() const { std::lock_guard guard(mMutex); return mBuffer; } -nn::SharedBuffer ResilientBuffer::recover(const nn::IBuffer* /*failingBuffer*/, - bool /*blocking*/) const { +nn::GeneralResult ResilientBuffer::recover( + const nn::IBuffer* failingBuffer) const { std::lock_guard guard(mMutex); + + // Another caller updated the failing prepared model. + if (mBuffer.get() != failingBuffer) { + return mBuffer; + } + + mBuffer = NN_TRY(kMakeBuffer()); return mBuffer; } @@ -64,12 +100,16 @@ nn::Request::MemoryDomainToken ResilientBuffer::getToken() const { } nn::GeneralResult ResilientBuffer::copyTo(const nn::Memory& dst) const { - return getBuffer()->copyTo(dst); + const auto fn = [&dst](const nn::IBuffer& buffer) { return buffer.copyTo(dst); }; + return protect(*this, fn); } nn::GeneralResult ResilientBuffer::copyFrom(const nn::Memory& src, const nn::Dimensions& dimensions) const { - return getBuffer()->copyFrom(src, dimensions); + const auto fn = [&src, &dimensions](const nn::IBuffer& buffer) { + return buffer.copyFrom(src, dimensions); + }; + return protect(*this, fn); } } // namespace android::hardware::neuralnetworks::utils diff --git a/neuralnetworks/utils/common/src/ResilientDevice.cpp b/neuralnetworks/utils/common/src/ResilientDevice.cpp index 6ad3fadee6..2023c9af30 100644 --- a/neuralnetworks/utils/common/src/ResilientDevice.cpp +++ b/neuralnetworks/utils/common/src/ResilientDevice.cpp @@ -180,6 +180,7 @@ nn::GeneralResult ResilientDevice::prepareModel( const nn::Model& model, nn::ExecutionPreference preference, nn::Priority priority, nn::OptionalTimePoint deadline, const std::vector& modelCache, const std::vector& dataCache, const nn::CacheToken& token) const { +#if 0 auto self = shared_from_this(); ResilientPreparedModel::Factory makePreparedModel = [device = std::move(self), model, preference, priority, deadline, modelCache, @@ -188,29 +189,41 @@ nn::GeneralResult ResilientDevice::prepareModel( dataCache, token); }; return ResilientPreparedModel::create(std::move(makePreparedModel)); +#else + return prepareModelInternal(model, preference, priority, deadline, modelCache, dataCache, + token); +#endif } nn::GeneralResult ResilientDevice::prepareModelFromCache( nn::OptionalTimePoint deadline, const std::vector& modelCache, const std::vector& dataCache, const nn::CacheToken& token) const { +#if 0 auto self = shared_from_this(); ResilientPreparedModel::Factory makePreparedModel = [device = std::move(self), deadline, modelCache, dataCache, token] { return device->prepareModelFromCacheInternal(deadline, modelCache, dataCache, token); }; return ResilientPreparedModel::create(std::move(makePreparedModel)); +#else + return prepareModelFromCacheInternal(deadline, modelCache, dataCache, token); +#endif } nn::GeneralResult ResilientDevice::allocate( const nn::BufferDesc& desc, const std::vector& preparedModels, const std::vector& inputRoles, const std::vector& outputRoles) const { +#if 0 auto self = shared_from_this(); ResilientBuffer::Factory makeBuffer = [device = std::move(self), desc, preparedModels, inputRoles, outputRoles] { return device->allocateInternal(desc, preparedModels, inputRoles, outputRoles); }; return ResilientBuffer::create(std::move(makeBuffer)); +#else + return allocateInternal(desc, preparedModels, inputRoles, outputRoles); +#endif } bool ResilientDevice::isValidInternal() const { @@ -225,8 +238,8 @@ nn::GeneralResult ResilientDevice::prepareModelInternal if (!isValidInternal()) { return std::make_shared(); } - const auto fn = [&model, preference, priority, deadline, &modelCache, &dataCache, - token](const nn::IDevice& device) { + const auto fn = [&model, preference, priority, &deadline, &modelCache, &dataCache, + &token](const nn::IDevice& device) { return device.prepareModel(model, preference, priority, deadline, modelCache, dataCache, token); }; @@ -239,7 +252,7 @@ nn::GeneralResult ResilientDevice::prepareModelFromCach if (!isValidInternal()) { return std::make_shared(); } - const auto fn = [deadline, &modelCache, &dataCache, token](const nn::IDevice& device) { + const auto fn = [&deadline, &modelCache, &dataCache, &token](const nn::IDevice& device) { return device.prepareModelFromCache(deadline, modelCache, dataCache, token); }; return protect(*this, fn, /*blocking=*/false); diff --git a/neuralnetworks/utils/common/src/ResilientPreparedModel.cpp b/neuralnetworks/utils/common/src/ResilientPreparedModel.cpp index b8acee16c9..667df2b590 100644 --- a/neuralnetworks/utils/common/src/ResilientPreparedModel.cpp +++ b/neuralnetworks/utils/common/src/ResilientPreparedModel.cpp @@ -20,15 +20,45 @@ #include #include #include +#include #include #include #include #include +#include #include #include namespace android::hardware::neuralnetworks::utils { +namespace { + +template +auto protect(const ResilientPreparedModel& resilientPreparedModel, const FnType& fn) + -> decltype(fn(*resilientPreparedModel.getPreparedModel())) { + auto preparedModel = resilientPreparedModel.getPreparedModel(); + auto result = fn(*preparedModel); + + // Immediately return if prepared model is not dead. + if (result.has_value() || result.error().code != nn::ErrorStatus::DEAD_OBJECT) { + return result; + } + + // Attempt recovery and return if it fails. + auto maybePreparedModel = resilientPreparedModel.recover(preparedModel.get()); + if (!maybePreparedModel.has_value()) { + const auto& [message, code] = maybePreparedModel.error(); + std::ostringstream oss; + oss << ", and failed to recover dead prepared model with error " << code << ": " << message; + result.error().message += oss.str(); + return result; + } + preparedModel = std::move(maybePreparedModel).value(); + + return fn(*preparedModel); +} + +} // namespace nn::GeneralResult> ResilientPreparedModel::create( Factory makePreparedModel) { @@ -55,9 +85,16 @@ nn::SharedPreparedModel ResilientPreparedModel::getPreparedModel() const { return mPreparedModel; } -nn::SharedPreparedModel ResilientPreparedModel::recover( - const nn::IPreparedModel* /*failingPreparedModel*/, bool /*blocking*/) const { +nn::GeneralResult ResilientPreparedModel::recover( + const nn::IPreparedModel* failingPreparedModel) const { std::lock_guard guard(mMutex); + + // Another caller updated the failing prepared model. + if (mPreparedModel.get() != failingPreparedModel) { + return mPreparedModel; + } + + mPreparedModel = NN_TRY(kMakePreparedModel()); return mPreparedModel; } @@ -65,7 +102,11 @@ nn::ExecutionResult, nn::Timing>> ResilientPreparedModel::execute(const nn::Request& request, nn::MeasureTiming measure, const nn::OptionalTimePoint& deadline, const nn::OptionalDuration& loopTimeoutDuration) const { - return getPreparedModel()->execute(request, measure, deadline, loopTimeoutDuration); + const auto fn = [&request, measure, &deadline, + &loopTimeoutDuration](const nn::IPreparedModel& preparedModel) { + return preparedModel.execute(request, measure, deadline, loopTimeoutDuration); + }; + return protect(*this, fn); } nn::GeneralResult> @@ -75,8 +116,12 @@ ResilientPreparedModel::executeFenced(const nn::Request& request, const nn::OptionalTimePoint& deadline, const nn::OptionalDuration& loopTimeoutDuration, const nn::OptionalDuration& timeoutDurationAfterFence) const { - return getPreparedModel()->executeFenced(request, waitFor, measure, deadline, - loopTimeoutDuration, timeoutDurationAfterFence); + const auto fn = [&request, &waitFor, measure, &deadline, &loopTimeoutDuration, + &timeoutDurationAfterFence](const nn::IPreparedModel& preparedModel) { + return preparedModel.executeFenced(request, waitFor, measure, deadline, loopTimeoutDuration, + timeoutDurationAfterFence); + }; + return protect(*this, fn); } std::any ResilientPreparedModel::getUnderlyingResource() const { -- GitLab From afc4d7cfe753669b08562eba8f58cbceefed334f Mon Sep 17 00:00:00 2001 From: Michael Butler Date: Thu, 10 Dec 2020 15:38:45 -0800 Subject: [PATCH 359/790] Create unit tests for NN interface utility code This CL introduces unit tests to validate the V1_X::utils::Device, *PreparedModel, and *Buffer adapter classes. It does so by mocking the underlying HIDL interface in order to simulate a driver returning bad data, HIDL transport failures, and service crashes. Note that the purpose of these new tests is to validate the adapter classes themselves, not the HIDL interfaces they use. For example, because nn::IPreparedModel does not currently define a method for configuring a burst execution, V1_[23]::utils::PreparedModel similarly does not use hardware::neuralnetworks::V1_[23]::IPreparedModel's configureExecutionBurst method. This CL also introduces unit tests to validate the utils::Resilient* adapter classes, and mocks DEAD_OBJECT failures to ensure that the underyling object can be recovered appropriately. Bug: 163801800 Test: mma Test: atest neuralnetworks_utils_hal_common_test Test: atest neuralnetworks_utils_hal_1_[0-3]_test Change-Id: I2c79865bf666d3f4bf53061ff5090746403583e9 --- neuralnetworks/1.0/utils/Android.bp | 26 + neuralnetworks/1.0/utils/test/DeviceTest.cpp | 524 ++++++++++ neuralnetworks/1.0/utils/test/MockDevice.h | 86 ++ .../1.0/utils/test/MockPreparedModel.h | 85 ++ .../1.0/utils/test/PreparedModelTest.cpp | 243 +++++ neuralnetworks/1.1/utils/Android.bp | 28 + neuralnetworks/1.1/utils/test/DeviceTest.cpp | 534 ++++++++++ neuralnetworks/1.1/utils/test/MockDevice.h | 95 ++ .../1.1/utils/test/MockPreparedModel.h | 44 + neuralnetworks/1.2/utils/Android.bp | 30 + neuralnetworks/1.2/utils/test/DeviceTest.cpp | 875 ++++++++++++++++ neuralnetworks/1.2/utils/test/MockDevice.h | 117 +++ .../1.2/utils/test/MockPreparedModel.h | 101 ++ .../1.2/utils/test/PreparedModelTest.cpp | 341 +++++++ neuralnetworks/1.3/utils/Android.bp | 32 + neuralnetworks/1.3/utils/test/BufferTest.cpp | 208 ++++ neuralnetworks/1.3/utils/test/DeviceTest.cpp | 951 ++++++++++++++++++ neuralnetworks/1.3/utils/test/MockBuffer.h | 43 + neuralnetworks/1.3/utils/test/MockDevice.h | 139 +++ .../utils/test/MockFencedExecutionCallback.h | 42 + .../1.3/utils/test/MockPreparedModel.h | 121 +++ .../1.3/utils/test/PreparedModelTest.cpp | 470 +++++++++ neuralnetworks/TEST_MAPPING | 15 + neuralnetworks/utils/common/Android.bp | 25 + neuralnetworks/utils/common/test/MockBuffer.h | 37 + neuralnetworks/utils/common/test/MockDevice.h | 57 ++ .../utils/common/test/MockPreparedModel.h | 43 + .../utils/common/test/ResilientBufferTest.cpp | 266 +++++ .../utils/common/test/ResilientDeviceTest.cpp | 725 +++++++++++++ .../test/ResilientPreparedModelTest.cpp | 297 ++++++ 30 files changed, 6600 insertions(+) create mode 100644 neuralnetworks/1.0/utils/test/DeviceTest.cpp create mode 100644 neuralnetworks/1.0/utils/test/MockDevice.h create mode 100644 neuralnetworks/1.0/utils/test/MockPreparedModel.h create mode 100644 neuralnetworks/1.0/utils/test/PreparedModelTest.cpp create mode 100644 neuralnetworks/1.1/utils/test/DeviceTest.cpp create mode 100644 neuralnetworks/1.1/utils/test/MockDevice.h create mode 100644 neuralnetworks/1.1/utils/test/MockPreparedModel.h create mode 100644 neuralnetworks/1.2/utils/test/DeviceTest.cpp create mode 100644 neuralnetworks/1.2/utils/test/MockDevice.h create mode 100644 neuralnetworks/1.2/utils/test/MockPreparedModel.h create mode 100644 neuralnetworks/1.2/utils/test/PreparedModelTest.cpp create mode 100644 neuralnetworks/1.3/utils/test/BufferTest.cpp create mode 100644 neuralnetworks/1.3/utils/test/DeviceTest.cpp create mode 100644 neuralnetworks/1.3/utils/test/MockBuffer.h create mode 100644 neuralnetworks/1.3/utils/test/MockDevice.h create mode 100644 neuralnetworks/1.3/utils/test/MockFencedExecutionCallback.h create mode 100644 neuralnetworks/1.3/utils/test/MockPreparedModel.h create mode 100644 neuralnetworks/1.3/utils/test/PreparedModelTest.cpp create mode 100644 neuralnetworks/utils/common/test/MockBuffer.h create mode 100644 neuralnetworks/utils/common/test/MockDevice.h create mode 100644 neuralnetworks/utils/common/test/MockPreparedModel.h create mode 100644 neuralnetworks/utils/common/test/ResilientBufferTest.cpp create mode 100644 neuralnetworks/utils/common/test/ResilientDeviceTest.cpp create mode 100644 neuralnetworks/utils/common/test/ResilientPreparedModelTest.cpp diff --git a/neuralnetworks/1.0/utils/Android.bp b/neuralnetworks/1.0/utils/Android.bp index 4d61fc0a94..d03361724c 100644 --- a/neuralnetworks/1.0/utils/Android.bp +++ b/neuralnetworks/1.0/utils/Android.bp @@ -32,3 +32,29 @@ cc_library_static { "neuralnetworks_utils_hal_common", ], } + +cc_test { + name: "neuralnetworks_utils_hal_1_0_test", + srcs: ["test/*.cpp"], + static_libs: [ + "android.hardware.neuralnetworks@1.0", + "libgmock", + "libneuralnetworks_common", + "neuralnetworks_types", + "neuralnetworks_utils_hal_common", + "neuralnetworks_utils_hal_1_0", + ], + shared_libs: [ + "android.hidl.allocator@1.0", + "android.hidl.memory@1.0", + "libbase", + "libcutils", + "libfmq", + "libhidlbase", + "libhidlmemory", + "liblog", + "libnativewindow", + "libutils", + ], + test_suites: ["general-tests"], +} diff --git a/neuralnetworks/1.0/utils/test/DeviceTest.cpp b/neuralnetworks/1.0/utils/test/DeviceTest.cpp new file mode 100644 index 0000000000..e881da2c85 --- /dev/null +++ b/neuralnetworks/1.0/utils/test/DeviceTest.cpp @@ -0,0 +1,524 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "MockDevice.h" +#include "MockPreparedModel.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace android::hardware::neuralnetworks::V1_0::utils { +namespace { + +using ::testing::_; +using ::testing::Invoke; +using ::testing::InvokeWithoutArgs; + +const nn::Model kSimpleModel = { + .main = {.operands = {{.type = nn::OperandType::TENSOR_FLOAT32, + .dimensions = {1}, + .lifetime = nn::Operand::LifeTime::SUBGRAPH_INPUT}, + {.type = nn::OperandType::TENSOR_FLOAT32, + .dimensions = {1}, + .lifetime = nn::Operand::LifeTime::SUBGRAPH_OUTPUT}}, + .operations = {{.type = nn::OperationType::RELU, .inputs = {0}, .outputs = {1}}}, + .inputIndexes = {0}, + .outputIndexes = {1}}}; + +const std::string kName = "Google-MockV1"; +const std::string kInvalidName = ""; +const sp kInvalidDevice; +constexpr V1_0::PerformanceInfo kNoPerformanceInfo = { + .execTime = std::numeric_limits::max(), + .powerUsage = std::numeric_limits::max()}; + +template +auto makeCallbackReturn(Args&&... args) { + return [argPack = std::make_tuple(std::forward(args)...)](const auto& cb) { + std::apply(cb, argPack); + return Void(); + }; +} + +sp createMockDevice() { + const auto mockDevice = MockDevice::create(); + + // Setup default actions for each relevant call. + const auto getCapabilities_ret = makeCallbackReturn( + V1_0::ErrorStatus::NONE, V1_0::Capabilities{ + .float32Performance = kNoPerformanceInfo, + .quantized8Performance = kNoPerformanceInfo, + }); + + // Setup default actions for each relevant call. + ON_CALL(*mockDevice, getCapabilities(_)).WillByDefault(Invoke(getCapabilities_ret)); + + // These EXPECT_CALL(...).Times(testing::AnyNumber()) calls are to suppress warnings on the + // uninteresting methods calls. + EXPECT_CALL(*mockDevice, getCapabilities(_)).Times(testing::AnyNumber()); + + return mockDevice; +} + +auto makePreparedModelReturn(V1_0::ErrorStatus launchStatus, V1_0::ErrorStatus returnStatus, + const sp& preparedModel) { + return [launchStatus, returnStatus, preparedModel](const V1_0::Model& /*model*/, + const sp& cb) + -> hardware::Return { + cb->notify(returnStatus, preparedModel).isOk(); + return launchStatus; + }; +} + +std::function makeTransportFailure(status_t status) { + return [status] { return hardware::Status::fromStatusT(status); }; +} + +const auto makeGeneralTransportFailure = makeTransportFailure(NO_MEMORY); +const auto makeDeadObjectFailure = makeTransportFailure(DEAD_OBJECT); + +} // namespace + +TEST(DeviceTest, invalidName) { + // run test + const auto device = MockDevice::create(); + const auto result = Device::create(kInvalidName, device); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::INVALID_ARGUMENT); +} + +TEST(DeviceTest, invalidDevice) { + // run test + const auto result = Device::create(kName, kInvalidDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::INVALID_ARGUMENT); +} + +TEST(DeviceTest, getCapabilitiesError) { + // setup call + const auto mockDevice = createMockDevice(); + const auto ret = makeCallbackReturn(V1_0::ErrorStatus::GENERAL_FAILURE, + V1_0::Capabilities{ + .float32Performance = kNoPerformanceInfo, + .quantized8Performance = kNoPerformanceInfo, + }); + EXPECT_CALL(*mockDevice, getCapabilities(_)).Times(1).WillOnce(Invoke(ret)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, getCapabilitiesTransportFailure) { + // setup call + const auto mockDevice = createMockDevice(); + EXPECT_CALL(*mockDevice, getCapabilities(_)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, getCapabilitiesDeadObject) { + // setup call + const auto mockDevice = createMockDevice(); + EXPECT_CALL(*mockDevice, getCapabilities(_)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(DeviceTest, linkToDeathError) { + // setup call + const auto mockDevice = createMockDevice(); + const auto ret = []() -> Return { return false; }; + EXPECT_CALL(*mockDevice, linkToDeathRet()).Times(1).WillOnce(InvokeWithoutArgs(ret)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, linkToDeathTransportFailure) { + // setup call + const auto mockDevice = createMockDevice(); + EXPECT_CALL(*mockDevice, linkToDeathRet()) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, linkToDeathDeadObject) { + // setup call + const auto mockDevice = createMockDevice(); + EXPECT_CALL(*mockDevice, linkToDeathRet()) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(DeviceTest, getName) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + + // run test + const auto& name = device->getName(); + + // verify result + EXPECT_EQ(name, kName); +} + +TEST(DeviceTest, getFeatureLevel) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + + // run test + const auto featureLevel = device->getFeatureLevel(); + + // verify result + EXPECT_EQ(featureLevel, nn::Version::ANDROID_OC_MR1); +} + +TEST(DeviceTest, getCachedData) { + // setup call + const auto mockDevice = createMockDevice(); + const auto result = Device::create(kName, mockDevice); + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; + const auto& device = result.value(); + + // run test and verify results + EXPECT_EQ(device->getVersionString(), device->getVersionString()); + EXPECT_EQ(device->getType(), device->getType()); + EXPECT_EQ(device->getSupportedExtensions(), device->getSupportedExtensions()); + EXPECT_EQ(device->getNumberOfCacheFilesNeeded(), device->getNumberOfCacheFilesNeeded()); + EXPECT_EQ(device->getCapabilities(), device->getCapabilities()); +} + +TEST(DeviceTest, wait) { + // setup call + const auto mockDevice = createMockDevice(); + const auto ret = []() -> Return { return {}; }; + EXPECT_CALL(*mockDevice, ping()).Times(1).WillOnce(InvokeWithoutArgs(ret)); + const auto device = Device::create(kName, mockDevice).value(); + + // run test + const auto result = device->wait(); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; +} + +TEST(DeviceTest, waitTransportFailure) { + // setup call + const auto mockDevice = createMockDevice(); + EXPECT_CALL(*mockDevice, ping()) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + const auto device = Device::create(kName, mockDevice).value(); + + // run test + const auto result = device->wait(); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, waitDeadObject) { + // setup call + const auto mockDevice = createMockDevice(); + EXPECT_CALL(*mockDevice, ping()).Times(1).WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + const auto device = Device::create(kName, mockDevice).value(); + + // run test + const auto result = device->wait(); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(DeviceTest, getSupportedOperations) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + const auto ret = [](const auto& model, const auto& cb) { + cb(V1_0::ErrorStatus::NONE, std::vector(model.operations.size(), true)); + return hardware::Void(); + }; + EXPECT_CALL(*mockDevice, getSupportedOperations(_, _)).Times(1).WillOnce(Invoke(ret)); + + // run test + const auto result = device->getSupportedOperations(kSimpleModel); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; + const auto& supportedOperations = result.value(); + EXPECT_EQ(supportedOperations.size(), kSimpleModel.main.operations.size()); + EXPECT_THAT(supportedOperations, Each(testing::IsTrue())); +} + +TEST(DeviceTest, getSupportedOperationsError) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + const auto ret = [](const auto& /*model*/, const auto& cb) { + cb(V1_0::ErrorStatus::GENERAL_FAILURE, {}); + return hardware::Void(); + }; + EXPECT_CALL(*mockDevice, getSupportedOperations(_, _)).Times(1).WillOnce(Invoke(ret)); + + // run test + const auto result = device->getSupportedOperations(kSimpleModel); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, getSupportedOperationsTransportFailure) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + EXPECT_CALL(*mockDevice, getSupportedOperations(_, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // run test + const auto result = device->getSupportedOperations(kSimpleModel); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, getSupportedOperationsDeadObject) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + EXPECT_CALL(*mockDevice, getSupportedOperations(_, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // run test + const auto result = device->getSupportedOperations(kSimpleModel); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(DeviceTest, prepareModel) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + const auto mockPreparedModel = V1_0::utils::MockPreparedModel::create(); + EXPECT_CALL(*mockDevice, prepareModel(_, _)) + .Times(1) + .WillOnce(Invoke(makePreparedModelReturn(V1_0::ErrorStatus::NONE, + V1_0::ErrorStatus::NONE, mockPreparedModel))); + + // run test + const auto result = device->prepareModel(kSimpleModel, nn::ExecutionPreference::DEFAULT, + nn::Priority::DEFAULT, {}, {}, {}, {}); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; + EXPECT_NE(result.value(), nullptr); +} + +TEST(DeviceTest, prepareModelLaunchError) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + EXPECT_CALL(*mockDevice, prepareModel(_, _)) + .Times(1) + .WillOnce(Invoke(makePreparedModelReturn(V1_0::ErrorStatus::GENERAL_FAILURE, + V1_0::ErrorStatus::GENERAL_FAILURE, nullptr))); + + // run test + const auto result = device->prepareModel(kSimpleModel, nn::ExecutionPreference::DEFAULT, + nn::Priority::DEFAULT, {}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, prepareModelReturnError) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + EXPECT_CALL(*mockDevice, prepareModel(_, _)) + .Times(1) + .WillOnce(Invoke(makePreparedModelReturn(V1_0::ErrorStatus::NONE, + V1_0::ErrorStatus::GENERAL_FAILURE, nullptr))); + + // run test + const auto result = device->prepareModel(kSimpleModel, nn::ExecutionPreference::DEFAULT, + nn::Priority::DEFAULT, {}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, prepareModelNullptrError) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + EXPECT_CALL(*mockDevice, prepareModel(_, _)) + .Times(1) + .WillOnce(Invoke(makePreparedModelReturn(V1_0::ErrorStatus::NONE, + V1_0::ErrorStatus::NONE, nullptr))); + + // run test + const auto result = device->prepareModel(kSimpleModel, nn::ExecutionPreference::DEFAULT, + nn::Priority::DEFAULT, {}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, prepareModelTransportFailure) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + EXPECT_CALL(*mockDevice, prepareModel(_, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // run test + const auto result = device->prepareModel(kSimpleModel, nn::ExecutionPreference::DEFAULT, + nn::Priority::DEFAULT, {}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, prepareModelDeadObject) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + EXPECT_CALL(*mockDevice, prepareModel(_, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // run test + const auto result = device->prepareModel(kSimpleModel, nn::ExecutionPreference::DEFAULT, + nn::Priority::DEFAULT, {}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(DeviceTest, prepareModelAsyncCrash) { + // setup test + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + const auto ret = [&mockDevice]() -> hardware::Return { + mockDevice->simulateCrash(); + return V1_0::ErrorStatus::NONE; + }; + EXPECT_CALL(*mockDevice, prepareModel(_, _)).Times(1).WillOnce(InvokeWithoutArgs(ret)); + + // run test + const auto result = device->prepareModel(kSimpleModel, nn::ExecutionPreference::DEFAULT, + nn::Priority::DEFAULT, {}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(DeviceTest, prepareModelFromCacheNotSupported) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + + // run test + const auto result = device->prepareModelFromCache({}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, allocateNotSupported) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + + // run test + const auto result = device->allocate({}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +} // namespace android::hardware::neuralnetworks::V1_0::utils diff --git a/neuralnetworks/1.0/utils/test/MockDevice.h b/neuralnetworks/1.0/utils/test/MockDevice.h new file mode 100644 index 0000000000..0fb59e3a63 --- /dev/null +++ b/neuralnetworks/1.0/utils/test/MockDevice.h @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_0_UTILS_TEST_MOCK_DEVICE +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_0_UTILS_TEST_MOCK_DEVICE + +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::V1_0::utils { + +class MockDevice final : public IDevice { + public: + static sp create(); + + // IBase methods below. + MOCK_METHOD(Return, ping, (), (override)); + MOCK_METHOD(Return, linkToDeathRet, ()); + Return linkToDeath(const sp& recipient, uint64_t /*cookie*/); + + // V1_0 methods below. + MOCK_METHOD(Return, getCapabilities, (getCapabilities_cb cb), (override)); + MOCK_METHOD(Return, getSupportedOperations, + (const V1_0::Model& model, getSupportedOperations_cb cb), (override)); + MOCK_METHOD(Return, prepareModel, + (const V1_0::Model& model, const sp& callback), + (override)); + MOCK_METHOD(Return, getStatus, (), (override)); + + // Helper methods. + void simulateCrash(); + + private: + sp mDeathRecipient; +}; + +inline sp MockDevice::create() { + auto mockDevice = sp::make(); + + // Setup default actions for each relevant call. + const auto ret = []() -> Return { return true; }; + + // Setup default actions for each relevant call. + ON_CALL(*mockDevice, linkToDeathRet()).WillByDefault(testing::Invoke(ret)); + + // These EXPECT_CALL(...).Times(testing::AnyNumber()) calls are to suppress warnings on the + // uninteresting methods calls. + EXPECT_CALL(*mockDevice, linkToDeathRet()).Times(testing::AnyNumber()); + + return mockDevice; +} + +inline Return MockDevice::linkToDeath(const sp& recipient, + uint64_t /*cookie*/) { + mDeathRecipient = recipient; + return linkToDeathRet(); +} + +inline void MockDevice::simulateCrash() { + ASSERT_NE(nullptr, mDeathRecipient.get()); + + // Currently, the utils::Device will not use the `cookie` or `who` arguments, so we pass in 0 + // and nullptr for these arguments instead. Normally, they are used by the hidl_death_recipient + // to determine which object is dead. However, the utils::Device code only pairs a single death + // recipient with a single HIDL interface object, so these arguments are redundant. + mDeathRecipient->serviceDied(0, nullptr); +} + +} // namespace android::hardware::neuralnetworks::V1_0::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_0_UTILS_TEST_MOCK_DEVICE diff --git a/neuralnetworks/1.0/utils/test/MockPreparedModel.h b/neuralnetworks/1.0/utils/test/MockPreparedModel.h new file mode 100644 index 0000000000..7a48a834ac --- /dev/null +++ b/neuralnetworks/1.0/utils/test/MockPreparedModel.h @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_0_UTILS_TEST_MOCK_PREPARED_MODEL +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_0_UTILS_TEST_MOCK_PREPARED_MODEL + +#include +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::V1_0::utils { + +class MockPreparedModel final : public IPreparedModel { + public: + static sp create(); + + // IBase methods below. + MOCK_METHOD(Return, ping, (), (override)); + MOCK_METHOD(Return, linkToDeathRet, ()); + Return linkToDeath(const sp& recipient, + uint64_t /*cookie*/) override; + + // V1_0 methods below. + MOCK_METHOD(Return, execute, + (const V1_0::Request& request, const sp& callback), + (override)); + + // Helper methods. + void simulateCrash(); + + private: + sp mDeathRecipient; +}; + +inline sp MockPreparedModel::create() { + auto mockPreparedModel = sp::make(); + + // Setup default actions for each relevant call. + const auto ret = []() -> Return { return true; }; + + // Setup default actions for each relevant call. + ON_CALL(*mockPreparedModel, linkToDeathRet()).WillByDefault(testing::Invoke(ret)); + + // These EXPECT_CALL(...).Times(testing::AnyNumber()) calls are to suppress warnings on the + // uninteresting methods calls. + EXPECT_CALL(*mockPreparedModel, linkToDeathRet()).Times(testing::AnyNumber()); + + return mockPreparedModel; +} + +inline Return MockPreparedModel::linkToDeath(const sp& recipient, + uint64_t /*cookie*/) { + mDeathRecipient = recipient; + return linkToDeathRet(); +} + +inline void MockPreparedModel::simulateCrash() { + ASSERT_NE(nullptr, mDeathRecipient.get()); + + // Currently, the utils::PreparedModel will not use the `cookie` or `who` arguments, so we pass + // in 0 and nullptr for these arguments instead. Normally, they are used by the + // hidl_death_recipient to determine which object is dead. However, the utils::PreparedModel + // code only pairs a single death recipient with a single HIDL interface object, so these + // arguments are redundant. + mDeathRecipient->serviceDied(0, nullptr); +} + +} // namespace android::hardware::neuralnetworks::V1_0::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_0_UTILS_TEST_MOCK_PREPARED_MODEL diff --git a/neuralnetworks/1.0/utils/test/PreparedModelTest.cpp b/neuralnetworks/1.0/utils/test/PreparedModelTest.cpp new file mode 100644 index 0000000000..a5cbc72a71 --- /dev/null +++ b/neuralnetworks/1.0/utils/test/PreparedModelTest.cpp @@ -0,0 +1,243 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "MockPreparedModel.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace android::hardware::neuralnetworks::V1_0::utils { +namespace { + +using ::testing::_; +using ::testing::Invoke; +using ::testing::InvokeWithoutArgs; + +const sp kInvalidPreparedModel; + +sp createMockPreparedModel() { + return MockPreparedModel::create(); +} + +auto makeExecute(V1_0::ErrorStatus launchStatus, V1_0::ErrorStatus returnStatus) { + return [launchStatus, returnStatus]( + const V1_0::Request& /*request*/, + const sp& cb) -> Return { + cb->notify(returnStatus); + return launchStatus; + }; +} + +std::function makeTransportFailure(status_t status) { + return [status] { return hardware::Status::fromStatusT(status); }; +} + +const auto makeGeneralTransportFailure = makeTransportFailure(NO_MEMORY); +const auto makeDeadObjectFailure = makeTransportFailure(DEAD_OBJECT); + +} // namespace + +TEST(PreparedModelTest, invalidPreparedModel) { + // run test + const auto result = PreparedModel::create(kInvalidPreparedModel); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(PreparedModelTest, linkToDeathError) { + // setup call + const auto mockPreparedModel = createMockPreparedModel(); + const auto ret = []() -> Return { return false; }; + EXPECT_CALL(*mockPreparedModel, linkToDeathRet()).Times(1).WillOnce(InvokeWithoutArgs(ret)); + + // run test + const auto result = PreparedModel::create(mockPreparedModel); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(PreparedModelTest, linkToDeathTransportFailure) { + // setup call + const auto mockPreparedModel = createMockPreparedModel(); + EXPECT_CALL(*mockPreparedModel, linkToDeathRet()) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // run test + const auto result = PreparedModel::create(mockPreparedModel); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(PreparedModelTest, linkToDeathDeadObject) { + // setup call + const auto mockPreparedModel = createMockPreparedModel(); + EXPECT_CALL(*mockPreparedModel, linkToDeathRet()) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // run test + const auto result = PreparedModel::create(mockPreparedModel); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(PreparedModelTest, execute) { + // setup call + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + EXPECT_CALL(*mockPreparedModel, execute(_, _)) + .Times(1) + .WillOnce(Invoke(makeExecute(V1_0::ErrorStatus::NONE, V1_0::ErrorStatus::NONE))); + + // run test + const auto result = preparedModel->execute({}, {}, {}, {}); + + // verify result + EXPECT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; +} + +TEST(PreparedModelTest, executeLaunchError) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + EXPECT_CALL(*mockPreparedModel, execute(_, _)) + .Times(1) + .WillOnce(Invoke(makeExecute(V1_0::ErrorStatus::GENERAL_FAILURE, + V1_0::ErrorStatus::GENERAL_FAILURE))); + + // run test + const auto result = preparedModel->execute({}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(PreparedModelTest, executeReturnError) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + EXPECT_CALL(*mockPreparedModel, execute(_, _)) + .Times(1) + .WillOnce(Invoke( + makeExecute(V1_0::ErrorStatus::NONE, V1_0::ErrorStatus::GENERAL_FAILURE))); + + // run test + const auto result = preparedModel->execute({}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(PreparedModelTest, executeTransportFailure) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + EXPECT_CALL(*mockPreparedModel, execute(_, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // run test + const auto result = preparedModel->execute({}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(PreparedModelTest, executeDeadObject) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + EXPECT_CALL(*mockPreparedModel, execute(_, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // run test + const auto result = preparedModel->execute({}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(PreparedModelTest, executeCrash) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto ret = [&mockPreparedModel]() -> hardware::Return { + mockPreparedModel->simulateCrash(); + return V1_0::ErrorStatus::NONE; + }; + EXPECT_CALL(*mockPreparedModel, execute(_, _)).Times(1).WillOnce(InvokeWithoutArgs(ret)); + + // run test + const auto result = preparedModel->execute({}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(PreparedModelTest, executeFencedNotSupported) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + + // run test + const auto result = preparedModel->executeFenced({}, {}, {}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +// TODO: test burst execution if/when it is added to nn::IPreparedModel. + +TEST(PreparedModelTest, getUnderlyingResource) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + + // run test + const auto resource = preparedModel->getUnderlyingResource(); + + // verify resource + const sp* maybeMock = std::any_cast>(&resource); + ASSERT_NE(maybeMock, nullptr); + EXPECT_EQ(maybeMock->get(), mockPreparedModel.get()); +} + +} // namespace android::hardware::neuralnetworks::V1_0::utils diff --git a/neuralnetworks/1.1/utils/Android.bp b/neuralnetworks/1.1/utils/Android.bp index 909575b634..fe0c80ab45 100644 --- a/neuralnetworks/1.1/utils/Android.bp +++ b/neuralnetworks/1.1/utils/Android.bp @@ -34,3 +34,31 @@ cc_library_static { "neuralnetworks_utils_hal_common", ], } + +cc_test { + name: "neuralnetworks_utils_hal_1_1_test", + srcs: ["test/*.cpp"], + static_libs: [ + "android.hardware.neuralnetworks@1.0", + "android.hardware.neuralnetworks@1.1", + "libgmock", + "libneuralnetworks_common", + "neuralnetworks_types", + "neuralnetworks_utils_hal_common", + "neuralnetworks_utils_hal_1_0", + "neuralnetworks_utils_hal_1_1", + ], + shared_libs: [ + "android.hidl.allocator@1.0", + "android.hidl.memory@1.0", + "libbase", + "libcutils", + "libfmq", + "libhidlbase", + "libhidlmemory", + "liblog", + "libnativewindow", + "libutils", + ], + test_suites: ["general-tests"], +} diff --git a/neuralnetworks/1.1/utils/test/DeviceTest.cpp b/neuralnetworks/1.1/utils/test/DeviceTest.cpp new file mode 100644 index 0000000000..41e0e3050d --- /dev/null +++ b/neuralnetworks/1.1/utils/test/DeviceTest.cpp @@ -0,0 +1,534 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "MockDevice.h" +#include "MockPreparedModel.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace android::hardware::neuralnetworks::V1_1::utils { +namespace { + +using ::testing::_; +using ::testing::Invoke; +using ::testing::InvokeWithoutArgs; + +const nn::Model kSimpleModel = { + .main = {.operands = {{.type = nn::OperandType::TENSOR_FLOAT32, + .dimensions = {1}, + .lifetime = nn::Operand::LifeTime::SUBGRAPH_INPUT}, + {.type = nn::OperandType::TENSOR_FLOAT32, + .dimensions = {1}, + .lifetime = nn::Operand::LifeTime::SUBGRAPH_OUTPUT}}, + .operations = {{.type = nn::OperationType::RELU, .inputs = {0}, .outputs = {1}}}, + .inputIndexes = {0}, + .outputIndexes = {1}}}; + +const std::string kName = "Google-MockV1"; +const std::string kInvalidName = ""; +const sp kInvalidDevice; +constexpr V1_0::PerformanceInfo kNoPerformanceInfo = { + .execTime = std::numeric_limits::max(), + .powerUsage = std::numeric_limits::max()}; + +template +auto makeCallbackReturn(Args&&... args) { + return [argPack = std::make_tuple(std::forward(args)...)](const auto& cb) { + std::apply(cb, argPack); + return Void(); + }; +} + +sp createMockDevice() { + const auto mockDevice = MockDevice::create(); + + // Setup default actions for each relevant call. + const auto getCapabilities_ret = + makeCallbackReturn(V1_0::ErrorStatus::NONE, + V1_1::Capabilities{ + .float32Performance = kNoPerformanceInfo, + .quantized8Performance = kNoPerformanceInfo, + .relaxedFloat32toFloat16Performance = kNoPerformanceInfo, + }); + + // Setup default actions for each relevant call. + ON_CALL(*mockDevice, getCapabilities_1_1(_)).WillByDefault(Invoke(getCapabilities_ret)); + + // Ensure that older calls are not used. + EXPECT_CALL(*mockDevice, getCapabilities(_)).Times(0); + EXPECT_CALL(*mockDevice, getSupportedOperations(_, _)).Times(0); + EXPECT_CALL(*mockDevice, prepareModel(_, _)).Times(0); + + // These EXPECT_CALL(...).Times(testing::AnyNumber()) calls are to suppress warnings on the + // uninteresting methods calls. + EXPECT_CALL(*mockDevice, getCapabilities_1_1(_)).Times(testing::AnyNumber()); + + return mockDevice; +} + +auto makePreparedModelReturn(V1_0::ErrorStatus launchStatus, V1_0::ErrorStatus returnStatus, + const sp& preparedModel) { + return [launchStatus, returnStatus, preparedModel](const V1_1::Model& /*model*/, + V1_1::ExecutionPreference /*preference*/, + const sp& cb) + -> hardware::Return { + cb->notify(returnStatus, preparedModel).isOk(); + return launchStatus; + }; +} + +std::function makeTransportFailure(status_t status) { + return [status] { return hardware::Status::fromStatusT(status); }; +} + +const auto makeGeneralTransportFailure = makeTransportFailure(NO_MEMORY); +const auto makeDeadObjectFailure = makeTransportFailure(DEAD_OBJECT); + +} // namespace + +TEST(DeviceTest, invalidName) { + // run test + const auto device = MockDevice::create(); + const auto result = Device::create(kInvalidName, device); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::INVALID_ARGUMENT); +} + +TEST(DeviceTest, invalidDevice) { + // run test + const auto result = Device::create(kName, kInvalidDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::INVALID_ARGUMENT); +} + +TEST(DeviceTest, getCapabilitiesError) { + // setup call + const auto mockDevice = createMockDevice(); + const auto ret = + makeCallbackReturn(V1_0::ErrorStatus::GENERAL_FAILURE, + V1_1::Capabilities{ + .float32Performance = kNoPerformanceInfo, + .quantized8Performance = kNoPerformanceInfo, + .relaxedFloat32toFloat16Performance = kNoPerformanceInfo, + }); + EXPECT_CALL(*mockDevice, getCapabilities_1_1(_)).Times(1).WillOnce(Invoke(ret)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, getCapabilitiesTransportFailure) { + // setup call + const auto mockDevice = createMockDevice(); + EXPECT_CALL(*mockDevice, getCapabilities_1_1(_)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, getCapabilitiesDeadObject) { + // setup call + const auto mockDevice = createMockDevice(); + EXPECT_CALL(*mockDevice, getCapabilities_1_1(_)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(DeviceTest, linkToDeathError) { + // setup call + const auto mockDevice = createMockDevice(); + const auto ret = []() -> Return { return false; }; + EXPECT_CALL(*mockDevice, linkToDeathRet()).Times(1).WillOnce(InvokeWithoutArgs(ret)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, linkToDeathTransportFailure) { + // setup call + const auto mockDevice = createMockDevice(); + EXPECT_CALL(*mockDevice, linkToDeathRet()) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, linkToDeathDeadObject) { + // setup call + const auto mockDevice = createMockDevice(); + EXPECT_CALL(*mockDevice, linkToDeathRet()) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(DeviceTest, getName) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + + // run test + const auto& name = device->getName(); + + // verify result + EXPECT_EQ(name, kName); +} + +TEST(DeviceTest, getFeatureLevel) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + + // run test + const auto featureLevel = device->getFeatureLevel(); + + // verify result + EXPECT_EQ(featureLevel, nn::Version::ANDROID_P); +} + +TEST(DeviceTest, getCachedData) { + // setup call + const auto mockDevice = createMockDevice(); + const auto result = Device::create(kName, mockDevice); + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; + const auto& device = result.value(); + + // run test and verify results + EXPECT_EQ(device->getVersionString(), device->getVersionString()); + EXPECT_EQ(device->getType(), device->getType()); + EXPECT_EQ(device->getSupportedExtensions(), device->getSupportedExtensions()); + EXPECT_EQ(device->getNumberOfCacheFilesNeeded(), device->getNumberOfCacheFilesNeeded()); + EXPECT_EQ(device->getCapabilities(), device->getCapabilities()); +} + +TEST(DeviceTest, wait) { + // setup call + const auto mockDevice = createMockDevice(); + const auto ret = []() -> Return { return {}; }; + EXPECT_CALL(*mockDevice, ping()).Times(1).WillOnce(InvokeWithoutArgs(ret)); + const auto device = Device::create(kName, mockDevice).value(); + + // run test + const auto result = device->wait(); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; +} + +TEST(DeviceTest, waitTransportFailure) { + // setup call + const auto mockDevice = createMockDevice(); + EXPECT_CALL(*mockDevice, ping()) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + const auto device = Device::create(kName, mockDevice).value(); + + // run test + const auto result = device->wait(); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, waitDeadObject) { + // setup call + const auto mockDevice = createMockDevice(); + EXPECT_CALL(*mockDevice, ping()).Times(1).WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + const auto device = Device::create(kName, mockDevice).value(); + + // run test + const auto result = device->wait(); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(DeviceTest, getSupportedOperations) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + const auto ret = [](const auto& model, const auto& cb) { + cb(V1_0::ErrorStatus::NONE, std::vector(model.operations.size(), true)); + return hardware::Void(); + }; + EXPECT_CALL(*mockDevice, getSupportedOperations_1_1(_, _)).Times(1).WillOnce(Invoke(ret)); + + // run test + const auto result = device->getSupportedOperations(kSimpleModel); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; + const auto& supportedOperations = result.value(); + EXPECT_EQ(supportedOperations.size(), kSimpleModel.main.operations.size()); + EXPECT_THAT(supportedOperations, Each(testing::IsTrue())); +} + +TEST(DeviceTest, getSupportedOperationsError) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + const auto ret = [](const auto& /*model*/, const auto& cb) { + cb(V1_0::ErrorStatus::GENERAL_FAILURE, {}); + return hardware::Void(); + }; + EXPECT_CALL(*mockDevice, getSupportedOperations_1_1(_, _)).Times(1).WillOnce(Invoke(ret)); + + // run test + const auto result = device->getSupportedOperations(kSimpleModel); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, getSupportedOperationsTransportFailure) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + EXPECT_CALL(*mockDevice, getSupportedOperations_1_1(_, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // run test + const auto result = device->getSupportedOperations(kSimpleModel); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, getSupportedOperationsDeadObject) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + EXPECT_CALL(*mockDevice, getSupportedOperations_1_1(_, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // run test + const auto result = device->getSupportedOperations(kSimpleModel); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(DeviceTest, prepareModel) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + const auto mockPreparedModel = V1_0::utils::MockPreparedModel::create(); + EXPECT_CALL(*mockDevice, prepareModel_1_1(_, _, _)) + .Times(1) + .WillOnce(Invoke(makePreparedModelReturn(V1_0::ErrorStatus::NONE, + V1_0::ErrorStatus::NONE, mockPreparedModel))); + + // run test + const auto result = device->prepareModel(kSimpleModel, nn::ExecutionPreference::DEFAULT, + nn::Priority::DEFAULT, {}, {}, {}, {}); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; + EXPECT_NE(result.value(), nullptr); +} + +TEST(DeviceTest, prepareModelLaunchError) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + EXPECT_CALL(*mockDevice, prepareModel_1_1(_, _, _)) + .Times(1) + .WillOnce(Invoke(makePreparedModelReturn(V1_0::ErrorStatus::GENERAL_FAILURE, + V1_0::ErrorStatus::GENERAL_FAILURE, nullptr))); + + // run test + const auto result = device->prepareModel(kSimpleModel, nn::ExecutionPreference::DEFAULT, + nn::Priority::DEFAULT, {}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, prepareModelReturnError) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + EXPECT_CALL(*mockDevice, prepareModel_1_1(_, _, _)) + .Times(1) + .WillOnce(Invoke(makePreparedModelReturn(V1_0::ErrorStatus::NONE, + V1_0::ErrorStatus::GENERAL_FAILURE, nullptr))); + + // run test + const auto result = device->prepareModel(kSimpleModel, nn::ExecutionPreference::DEFAULT, + nn::Priority::DEFAULT, {}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, prepareModelNullptrError) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + EXPECT_CALL(*mockDevice, prepareModel_1_1(_, _, _)) + .Times(1) + .WillOnce(Invoke(makePreparedModelReturn(V1_0::ErrorStatus::NONE, + V1_0::ErrorStatus::NONE, nullptr))); + + // run test + const auto result = device->prepareModel(kSimpleModel, nn::ExecutionPreference::DEFAULT, + nn::Priority::DEFAULT, {}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, prepareModelTransportFailure) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + EXPECT_CALL(*mockDevice, prepareModel_1_1(_, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // run test + const auto result = device->prepareModel(kSimpleModel, nn::ExecutionPreference::DEFAULT, + nn::Priority::DEFAULT, {}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, prepareModelDeadObject) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + EXPECT_CALL(*mockDevice, prepareModel_1_1(_, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // run test + const auto result = device->prepareModel(kSimpleModel, nn::ExecutionPreference::DEFAULT, + nn::Priority::DEFAULT, {}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(DeviceTest, prepareModelAsyncCrash) { + // setup test + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + const auto ret = [&mockDevice]() -> hardware::Return { + mockDevice->simulateCrash(); + return V1_0::ErrorStatus::NONE; + }; + EXPECT_CALL(*mockDevice, prepareModel_1_1(_, _, _)).Times(1).WillOnce(InvokeWithoutArgs(ret)); + + // run test + const auto result = device->prepareModel(kSimpleModel, nn::ExecutionPreference::DEFAULT, + nn::Priority::DEFAULT, {}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(DeviceTest, prepareModelFromCacheNotSupported) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + + // run test + const auto result = device->prepareModelFromCache({}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, allocateNotSupported) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + + // run test + const auto result = device->allocate({}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +} // namespace android::hardware::neuralnetworks::V1_1::utils diff --git a/neuralnetworks/1.1/utils/test/MockDevice.h b/neuralnetworks/1.1/utils/test/MockDevice.h new file mode 100644 index 0000000000..3b92e58102 --- /dev/null +++ b/neuralnetworks/1.1/utils/test/MockDevice.h @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_1_UTILS_TEST_MOCK_DEVICE +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_1_UTILS_TEST_MOCK_DEVICE + +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::V1_1::utils { + +class MockDevice final : public IDevice { + public: + static sp create(); + + // IBase methods below. + MOCK_METHOD(Return, ping, (), (override)); + MOCK_METHOD(Return, linkToDeathRet, ()); + Return linkToDeath(const sp& recipient, uint64_t /*cookie*/); + + // V1_0 methods below. + MOCK_METHOD(Return, getCapabilities, (getCapabilities_cb cb), (override)); + MOCK_METHOD(Return, getSupportedOperations, + (const V1_0::Model& model, getSupportedOperations_cb cb), (override)); + MOCK_METHOD(Return, prepareModel, + (const V1_0::Model& model, const sp& callback), + (override)); + MOCK_METHOD(Return, getStatus, (), (override)); + + // V1_1 methods below. + MOCK_METHOD(Return, getCapabilities_1_1, (getCapabilities_1_1_cb cb), (override)); + MOCK_METHOD(Return, getSupportedOperations_1_1, + (const V1_1::Model& model, getSupportedOperations_1_1_cb cb), (override)); + MOCK_METHOD(Return, prepareModel_1_1, + (const V1_1::Model& model, V1_1::ExecutionPreference preference, + const sp& callback), + (override)); + + // Helper methods. + void simulateCrash(); + + private: + sp mDeathRecipient; +}; + +inline sp MockDevice::create() { + auto mockDevice = sp::make(); + + // Setup default actions for each relevant call. + const auto ret = []() -> Return { return true; }; + + // Setup default actions for each relevant call. + ON_CALL(*mockDevice, linkToDeathRet()).WillByDefault(testing::Invoke(ret)); + + // These EXPECT_CALL(...).Times(testing::AnyNumber()) calls are to suppress warnings on the + // uninteresting methods calls. + EXPECT_CALL(*mockDevice, linkToDeathRet()).Times(testing::AnyNumber()); + + return mockDevice; +} + +inline Return MockDevice::linkToDeath(const sp& recipient, + uint64_t /*cookie*/) { + mDeathRecipient = recipient; + return linkToDeathRet(); +} + +inline void MockDevice::simulateCrash() { + ASSERT_NE(nullptr, mDeathRecipient.get()); + + // Currently, the utils::Device will not use the `cookie` or `who` arguments, so we pass in 0 + // and nullptr for these arguments instead. Normally, they are used by the hidl_death_recipient + // to determine which object is dead. However, the utils::Device code only pairs a single death + // recipient with a single HIDL interface object, so these arguments are redundant. + mDeathRecipient->serviceDied(0, nullptr); +} + +} // namespace android::hardware::neuralnetworks::V1_1::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_1_UTILS_TEST_MOCK_DEVICE diff --git a/neuralnetworks/1.1/utils/test/MockPreparedModel.h b/neuralnetworks/1.1/utils/test/MockPreparedModel.h new file mode 100644 index 0000000000..aba731efa1 --- /dev/null +++ b/neuralnetworks/1.1/utils/test/MockPreparedModel.h @@ -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. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_1_UTILS_TEST_MOCK_PREPARED_MODEL +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_1_UTILS_TEST_MOCK_PREPARED_MODEL + +#include +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::V1_0::utils { + +class MockPreparedModel final : public IPreparedModel { + public: + static sp create(); + + // V1_0 methods below. + MOCK_METHOD(Return, execute, + (const V1_0::Request& request, const sp& callback), + (override)); +}; + +inline sp MockPreparedModel::create() { + return sp::make(); +} + +} // namespace android::hardware::neuralnetworks::V1_0::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_1_UTILS_TEST_MOCK_PREPARED_MODEL diff --git a/neuralnetworks/1.2/utils/Android.bp b/neuralnetworks/1.2/utils/Android.bp index 22e8659557..0fec41c240 100644 --- a/neuralnetworks/1.2/utils/Android.bp +++ b/neuralnetworks/1.2/utils/Android.bp @@ -36,3 +36,33 @@ cc_library_static { "neuralnetworks_utils_hal_common", ], } + +cc_test { + name: "neuralnetworks_utils_hal_1_2_test", + srcs: ["test/*.cpp"], + static_libs: [ + "android.hardware.neuralnetworks@1.0", + "android.hardware.neuralnetworks@1.1", + "android.hardware.neuralnetworks@1.2", + "libgmock", + "libneuralnetworks_common", + "neuralnetworks_types", + "neuralnetworks_utils_hal_common", + "neuralnetworks_utils_hal_1_0", + "neuralnetworks_utils_hal_1_1", + "neuralnetworks_utils_hal_1_2", + ], + shared_libs: [ + "android.hidl.allocator@1.0", + "android.hidl.memory@1.0", + "libbase", + "libcutils", + "libfmq", + "libhidlbase", + "libhidlmemory", + "liblog", + "libnativewindow", + "libutils", + ], + test_suites: ["general-tests"], +} diff --git a/neuralnetworks/1.2/utils/test/DeviceTest.cpp b/neuralnetworks/1.2/utils/test/DeviceTest.cpp new file mode 100644 index 0000000000..9c8addef1f --- /dev/null +++ b/neuralnetworks/1.2/utils/test/DeviceTest.cpp @@ -0,0 +1,875 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "MockDevice.h" +#include "MockPreparedModel.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace android::hardware::neuralnetworks::V1_2::utils { +namespace { + +using ::testing::_; +using ::testing::Invoke; +using ::testing::InvokeWithoutArgs; + +const nn::Model kSimpleModel = { + .main = {.operands = {{.type = nn::OperandType::TENSOR_FLOAT32, + .dimensions = {1}, + .lifetime = nn::Operand::LifeTime::SUBGRAPH_INPUT}, + {.type = nn::OperandType::TENSOR_FLOAT32, + .dimensions = {1}, + .lifetime = nn::Operand::LifeTime::SUBGRAPH_OUTPUT}}, + .operations = {{.type = nn::OperationType::RELU, .inputs = {0}, .outputs = {1}}}, + .inputIndexes = {0}, + .outputIndexes = {1}}}; + +const std::string kName = "Google-MockV1"; +const std::string kInvalidName = ""; +const sp kInvalidDevice; +constexpr V1_0::PerformanceInfo kNoPerformanceInfo = { + .execTime = std::numeric_limits::max(), + .powerUsage = std::numeric_limits::max()}; + +template +auto makeCallbackReturn(Args&&... args) { + return [argPack = std::make_tuple(std::forward(args)...)](const auto& cb) { + std::apply(cb, argPack); + return Void(); + }; +} + +sp createMockDevice() { + const auto mockDevice = MockDevice::create(); + + // Setup default actions for each relevant call. + const auto getVersionString_ret = makeCallbackReturn(V1_0::ErrorStatus::NONE, kName); + const auto getType_ret = makeCallbackReturn(V1_0::ErrorStatus::NONE, V1_2::DeviceType::OTHER); + const auto getSupportedExtensions_ret = + makeCallbackReturn(V1_0::ErrorStatus::NONE, hidl_vec{}); + const auto getNumberOfCacheFilesNeeded_ret = makeCallbackReturn( + V1_0::ErrorStatus::NONE, nn::kMaxNumberOfCacheFiles, nn::kMaxNumberOfCacheFiles); + const auto getCapabilities_ret = makeCallbackReturn( + V1_0::ErrorStatus::NONE, + V1_2::Capabilities{ + .relaxedFloat32toFloat16PerformanceScalar = kNoPerformanceInfo, + .relaxedFloat32toFloat16PerformanceTensor = kNoPerformanceInfo, + }); + + // Setup default actions for each relevant call. + ON_CALL(*mockDevice, getVersionString(_)).WillByDefault(Invoke(getVersionString_ret)); + ON_CALL(*mockDevice, getType(_)).WillByDefault(Invoke(getType_ret)); + ON_CALL(*mockDevice, getSupportedExtensions(_)) + .WillByDefault(Invoke(getSupportedExtensions_ret)); + ON_CALL(*mockDevice, getNumberOfCacheFilesNeeded(_)) + .WillByDefault(Invoke(getNumberOfCacheFilesNeeded_ret)); + ON_CALL(*mockDevice, getCapabilities_1_2(_)).WillByDefault(Invoke(getCapabilities_ret)); + + // Ensure that older calls are not used. + EXPECT_CALL(*mockDevice, getCapabilities(_)).Times(0); + EXPECT_CALL(*mockDevice, getCapabilities_1_1(_)).Times(0); + EXPECT_CALL(*mockDevice, getSupportedOperations(_, _)).Times(0); + EXPECT_CALL(*mockDevice, getSupportedOperations_1_1(_, _)).Times(0); + EXPECT_CALL(*mockDevice, prepareModel(_, _)).Times(0); + EXPECT_CALL(*mockDevice, prepareModel_1_1(_, _, _)).Times(0); + + // These EXPECT_CALL(...).Times(testing::AnyNumber()) calls are to suppress warnings on the + // uninteresting methods calls. + EXPECT_CALL(*mockDevice, getVersionString(_)).Times(testing::AnyNumber()); + EXPECT_CALL(*mockDevice, getType(_)).Times(testing::AnyNumber()); + EXPECT_CALL(*mockDevice, getSupportedExtensions(_)).Times(testing::AnyNumber()); + EXPECT_CALL(*mockDevice, getNumberOfCacheFilesNeeded(_)).Times(testing::AnyNumber()); + EXPECT_CALL(*mockDevice, getCapabilities_1_2(_)).Times(testing::AnyNumber()); + + return mockDevice; +} + +auto makePreparedModelReturn(V1_0::ErrorStatus launchStatus, V1_0::ErrorStatus returnStatus, + const sp& preparedModel) { + return [launchStatus, returnStatus, preparedModel]( + const V1_2::Model& /*model*/, V1_1::ExecutionPreference /*preference*/, + const hardware::hidl_vec& /*modelCache*/, + const hardware::hidl_vec& /*dataCache*/, + const CacheToken& /*token*/, const sp& cb) + -> hardware::Return { + cb->notify_1_2(returnStatus, preparedModel).isOk(); + return launchStatus; + }; +} +auto makePreparedModelFromCacheReturn(V1_0::ErrorStatus launchStatus, + V1_0::ErrorStatus returnStatus, + const sp& preparedModel) { + return [launchStatus, returnStatus, preparedModel]( + const hardware::hidl_vec& /*modelCache*/, + const hardware::hidl_vec& /*dataCache*/, + const CacheToken& /*token*/, const sp& cb) + -> hardware::Return { + cb->notify_1_2(returnStatus, preparedModel).isOk(); + return launchStatus; + }; +} + +std::function makeTransportFailure(status_t status) { + return [status] { return hardware::Status::fromStatusT(status); }; +} + +const auto makeGeneralTransportFailure = makeTransportFailure(NO_MEMORY); +const auto makeDeadObjectFailure = makeTransportFailure(DEAD_OBJECT); + +} // namespace + +TEST(DeviceTest, invalidName) { + // run test + const auto device = MockDevice::create(); + const auto result = Device::create(kInvalidName, device); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::INVALID_ARGUMENT); +} + +TEST(DeviceTest, invalidDevice) { + // run test + const auto result = Device::create(kName, kInvalidDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::INVALID_ARGUMENT); +} + +TEST(DeviceTest, getVersionStringError) { + // setup call + const auto mockDevice = createMockDevice(); + const auto ret = makeCallbackReturn(V1_0::ErrorStatus::GENERAL_FAILURE, ""); + EXPECT_CALL(*mockDevice, getVersionString(_)).Times(1).WillOnce(Invoke(ret)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, getVersionStringTransportFailure) { + // setup call + const auto mockDevice = createMockDevice(); + EXPECT_CALL(*mockDevice, getVersionString(_)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, getVersionStringDeadObject) { + // setup call + const auto mockDevice = createMockDevice(); + EXPECT_CALL(*mockDevice, getVersionString(_)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(DeviceTest, getTypeError) { + // setup call + const auto mockDevice = createMockDevice(); + const auto ret = + makeCallbackReturn(V1_0::ErrorStatus::GENERAL_FAILURE, V1_2::DeviceType::OTHER); + EXPECT_CALL(*mockDevice, getType(_)).Times(1).WillOnce(Invoke(ret)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, getTypeTransportFailure) { + // setup call + const auto mockDevice = createMockDevice(); + EXPECT_CALL(*mockDevice, getType(_)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, getTypeDeadObject) { + // setup call + const auto mockDevice = createMockDevice(); + EXPECT_CALL(*mockDevice, getType(_)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(DeviceTest, getSupportedExtensionsError) { + // setup call + const auto mockDevice = createMockDevice(); + const auto ret = + makeCallbackReturn(V1_0::ErrorStatus::GENERAL_FAILURE, hidl_vec{}); + EXPECT_CALL(*mockDevice, getSupportedExtensions(_)).Times(1).WillOnce(Invoke(ret)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, getSupportedExtensionsTransportFailure) { + // setup call + const auto mockDevice = createMockDevice(); + EXPECT_CALL(*mockDevice, getSupportedExtensions(_)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, getSupportedExtensionsDeadObject) { + // setup call + const auto mockDevice = createMockDevice(); + EXPECT_CALL(*mockDevice, getSupportedExtensions(_)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(DeviceTest, getNumberOfCacheFilesNeededError) { + // setup call + const auto mockDevice = createMockDevice(); + const auto ret = makeCallbackReturn(V1_0::ErrorStatus::GENERAL_FAILURE, + nn::kMaxNumberOfCacheFiles, nn::kMaxNumberOfCacheFiles); + EXPECT_CALL(*mockDevice, getNumberOfCacheFilesNeeded(_)).Times(1).WillOnce(Invoke(ret)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, dataCacheFilesExceedsSpecifiedMax) { + // setup test + const auto mockDevice = createMockDevice(); + const auto ret = makeCallbackReturn(V1_0::ErrorStatus::NONE, nn::kMaxNumberOfCacheFiles + 1, + nn::kMaxNumberOfCacheFiles); + EXPECT_CALL(*mockDevice, getNumberOfCacheFilesNeeded(_)).Times(1).WillOnce(Invoke(ret)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, modelCacheFilesExceedsSpecifiedMax) { + // setup test + const auto mockDevice = createMockDevice(); + const auto ret = makeCallbackReturn(V1_0::ErrorStatus::NONE, nn::kMaxNumberOfCacheFiles, + nn::kMaxNumberOfCacheFiles + 1); + EXPECT_CALL(*mockDevice, getNumberOfCacheFilesNeeded(_)).Times(1).WillOnce(Invoke(ret)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, getNumberOfCacheFilesNeededTransportFailure) { + // setup call + const auto mockDevice = createMockDevice(); + EXPECT_CALL(*mockDevice, getNumberOfCacheFilesNeeded(_)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, getNumberOfCacheFilesNeededDeadObject) { + // setup call + const auto mockDevice = createMockDevice(); + EXPECT_CALL(*mockDevice, getNumberOfCacheFilesNeeded(_)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(DeviceTest, getCapabilitiesError) { + // setup call + const auto mockDevice = createMockDevice(); + const auto ret = makeCallbackReturn( + V1_0::ErrorStatus::GENERAL_FAILURE, + V1_2::Capabilities{ + .relaxedFloat32toFloat16PerformanceScalar = kNoPerformanceInfo, + .relaxedFloat32toFloat16PerformanceTensor = kNoPerformanceInfo, + }); + EXPECT_CALL(*mockDevice, getCapabilities_1_2(_)).Times(1).WillOnce(Invoke(ret)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, getCapabilitiesTransportFailure) { + // setup call + const auto mockDevice = createMockDevice(); + EXPECT_CALL(*mockDevice, getCapabilities_1_2(_)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, getCapabilitiesDeadObject) { + // setup call + const auto mockDevice = createMockDevice(); + EXPECT_CALL(*mockDevice, getCapabilities_1_2(_)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(DeviceTest, linkToDeathError) { + // setup call + const auto mockDevice = createMockDevice(); + const auto ret = []() -> Return { return false; }; + EXPECT_CALL(*mockDevice, linkToDeathRet()).Times(1).WillOnce(InvokeWithoutArgs(ret)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, linkToDeathTransportFailure) { + // setup call + const auto mockDevice = createMockDevice(); + EXPECT_CALL(*mockDevice, linkToDeathRet()) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, linkToDeathDeadObject) { + // setup call + const auto mockDevice = createMockDevice(); + EXPECT_CALL(*mockDevice, linkToDeathRet()) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(DeviceTest, getName) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + + // run test + const auto& name = device->getName(); + + // verify result + EXPECT_EQ(name, kName); +} + +TEST(DeviceTest, getFeatureLevel) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + + // run test + const auto featureLevel = device->getFeatureLevel(); + + // verify result + EXPECT_EQ(featureLevel, nn::Version::ANDROID_Q); +} + +TEST(DeviceTest, getCachedData) { + // setup call + const auto mockDevice = createMockDevice(); + EXPECT_CALL(*mockDevice, getVersionString(_)).Times(1); + EXPECT_CALL(*mockDevice, getType(_)).Times(1); + EXPECT_CALL(*mockDevice, getSupportedExtensions(_)).Times(1); + EXPECT_CALL(*mockDevice, getNumberOfCacheFilesNeeded(_)).Times(1); + EXPECT_CALL(*mockDevice, getCapabilities_1_2(_)).Times(1); + + const auto result = Device::create(kName, mockDevice); + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; + const auto& device = result.value(); + + // run test and verify results + EXPECT_EQ(device->getVersionString(), device->getVersionString()); + EXPECT_EQ(device->getType(), device->getType()); + EXPECT_EQ(device->getSupportedExtensions(), device->getSupportedExtensions()); + EXPECT_EQ(device->getNumberOfCacheFilesNeeded(), device->getNumberOfCacheFilesNeeded()); + EXPECT_EQ(device->getCapabilities(), device->getCapabilities()); +} + +TEST(DeviceTest, wait) { + // setup call + const auto mockDevice = createMockDevice(); + const auto ret = []() -> Return { return {}; }; + EXPECT_CALL(*mockDevice, ping()).Times(1).WillOnce(InvokeWithoutArgs(ret)); + const auto device = Device::create(kName, mockDevice).value(); + + // run test + const auto result = device->wait(); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; +} + +TEST(DeviceTest, waitTransportFailure) { + // setup call + const auto mockDevice = createMockDevice(); + EXPECT_CALL(*mockDevice, ping()) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + const auto device = Device::create(kName, mockDevice).value(); + + // run test + const auto result = device->wait(); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, waitDeadObject) { + // setup call + const auto mockDevice = createMockDevice(); + EXPECT_CALL(*mockDevice, ping()).Times(1).WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + const auto device = Device::create(kName, mockDevice).value(); + + // run test + const auto result = device->wait(); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(DeviceTest, getSupportedOperations) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + const auto ret = [](const auto& model, const auto& cb) { + cb(V1_0::ErrorStatus::NONE, std::vector(model.operations.size(), true)); + return hardware::Void(); + }; + EXPECT_CALL(*mockDevice, getSupportedOperations_1_2(_, _)).Times(1).WillOnce(Invoke(ret)); + + // run test + const auto result = device->getSupportedOperations(kSimpleModel); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; + const auto& supportedOperations = result.value(); + EXPECT_EQ(supportedOperations.size(), kSimpleModel.main.operations.size()); + EXPECT_THAT(supportedOperations, Each(testing::IsTrue())); +} + +TEST(DeviceTest, getSupportedOperationsError) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + const auto ret = [](const auto& /*model*/, const auto& cb) { + cb(V1_0::ErrorStatus::GENERAL_FAILURE, {}); + return hardware::Void(); + }; + EXPECT_CALL(*mockDevice, getSupportedOperations_1_2(_, _)).Times(1).WillOnce(Invoke(ret)); + + // run test + const auto result = device->getSupportedOperations(kSimpleModel); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, getSupportedOperationsTransportFailure) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + EXPECT_CALL(*mockDevice, getSupportedOperations_1_2(_, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // run test + const auto result = device->getSupportedOperations(kSimpleModel); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, getSupportedOperationsDeadObject) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + EXPECT_CALL(*mockDevice, getSupportedOperations_1_2(_, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // run test + const auto result = device->getSupportedOperations(kSimpleModel); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(DeviceTest, prepareModel) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + const auto mockPreparedModel = MockPreparedModel::create(); + EXPECT_CALL(*mockDevice, prepareModel_1_2(_, _, _, _, _, _)) + .Times(1) + .WillOnce(Invoke(makePreparedModelReturn(V1_0::ErrorStatus::NONE, + V1_0::ErrorStatus::NONE, mockPreparedModel))); + + // run test + const auto result = device->prepareModel(kSimpleModel, nn::ExecutionPreference::DEFAULT, + nn::Priority::DEFAULT, {}, {}, {}, {}); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; + EXPECT_NE(result.value(), nullptr); +} + +TEST(DeviceTest, prepareModelLaunchError) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + EXPECT_CALL(*mockDevice, prepareModel_1_2(_, _, _, _, _, _)) + .Times(1) + .WillOnce(Invoke(makePreparedModelReturn(V1_0::ErrorStatus::GENERAL_FAILURE, + V1_0::ErrorStatus::GENERAL_FAILURE, nullptr))); + + // run test + const auto result = device->prepareModel(kSimpleModel, nn::ExecutionPreference::DEFAULT, + nn::Priority::DEFAULT, {}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, prepareModelReturnError) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + EXPECT_CALL(*mockDevice, prepareModel_1_2(_, _, _, _, _, _)) + .Times(1) + .WillOnce(Invoke(makePreparedModelReturn(V1_0::ErrorStatus::NONE, + V1_0::ErrorStatus::GENERAL_FAILURE, nullptr))); + + // run test + const auto result = device->prepareModel(kSimpleModel, nn::ExecutionPreference::DEFAULT, + nn::Priority::DEFAULT, {}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, prepareModelNullptrError) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + EXPECT_CALL(*mockDevice, prepareModel_1_2(_, _, _, _, _, _)) + .Times(1) + .WillOnce(Invoke(makePreparedModelReturn(V1_0::ErrorStatus::NONE, + V1_0::ErrorStatus::NONE, nullptr))); + + // run test + const auto result = device->prepareModel(kSimpleModel, nn::ExecutionPreference::DEFAULT, + nn::Priority::DEFAULT, {}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, prepareModelTransportFailure) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + EXPECT_CALL(*mockDevice, prepareModel_1_2(_, _, _, _, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // run test + const auto result = device->prepareModel(kSimpleModel, nn::ExecutionPreference::DEFAULT, + nn::Priority::DEFAULT, {}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, prepareModelDeadObject) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + EXPECT_CALL(*mockDevice, prepareModel_1_2(_, _, _, _, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // run test + const auto result = device->prepareModel(kSimpleModel, nn::ExecutionPreference::DEFAULT, + nn::Priority::DEFAULT, {}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(DeviceTest, prepareModelAsyncCrash) { + // setup test + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + const auto ret = [&mockDevice]() -> hardware::Return { + mockDevice->simulateCrash(); + return V1_0::ErrorStatus::NONE; + }; + EXPECT_CALL(*mockDevice, prepareModel_1_2(_, _, _, _, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(ret)); + + // run test + const auto result = device->prepareModel(kSimpleModel, nn::ExecutionPreference::DEFAULT, + nn::Priority::DEFAULT, {}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(DeviceTest, prepareModelFromCache) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + const auto mockPreparedModel = MockPreparedModel::create(); + EXPECT_CALL(*mockDevice, prepareModelFromCache(_, _, _, _)) + .Times(1) + .WillOnce(Invoke(makePreparedModelFromCacheReturn( + V1_0::ErrorStatus::NONE, V1_0::ErrorStatus::NONE, mockPreparedModel))); + + // run test + const auto result = device->prepareModelFromCache({}, {}, {}, {}); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; + EXPECT_NE(result.value(), nullptr); +} + +TEST(DeviceTest, prepareModelFromCacheError) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + EXPECT_CALL(*mockDevice, prepareModelFromCache(_, _, _, _)) + .Times(1) + .WillOnce(Invoke(makePreparedModelFromCacheReturn(V1_0::ErrorStatus::GENERAL_FAILURE, + V1_0::ErrorStatus::GENERAL_FAILURE, + nullptr))); + + // run test + const auto result = device->prepareModelFromCache({}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, prepareModelFromCacheNullptrError) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + EXPECT_CALL(*mockDevice, prepareModelFromCache(_, _, _, _)) + .Times(1) + .WillOnce(Invoke(makePreparedModelFromCacheReturn(V1_0::ErrorStatus::NONE, + V1_0::ErrorStatus::NONE, nullptr))); + + // run test + const auto result = device->prepareModelFromCache({}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, prepareModelFromCacheTransportFailure) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + EXPECT_CALL(*mockDevice, prepareModelFromCache(_, _, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // run test + const auto result = device->prepareModelFromCache({}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, prepareModelFromCacheDeadObject) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + EXPECT_CALL(*mockDevice, prepareModelFromCache(_, _, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // run test + const auto result = device->prepareModelFromCache({}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(DeviceTest, prepareModelFromCacheAsyncCrash) { + // setup test + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + const auto ret = [&mockDevice]() -> hardware::Return { + mockDevice->simulateCrash(); + return V1_0::ErrorStatus::NONE; + }; + EXPECT_CALL(*mockDevice, prepareModelFromCache(_, _, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(ret)); + + // run test + const auto result = device->prepareModelFromCache({}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(DeviceTest, allocateNotSupported) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + + // run test + const auto result = device->allocate({}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +} // namespace android::hardware::neuralnetworks::V1_2::utils diff --git a/neuralnetworks/1.2/utils/test/MockDevice.h b/neuralnetworks/1.2/utils/test/MockDevice.h new file mode 100644 index 0000000000..b4599430a2 --- /dev/null +++ b/neuralnetworks/1.2/utils/test/MockDevice.h @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_2_UTILS_TEST_MOCK_DEVICE +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_2_UTILS_TEST_MOCK_DEVICE + +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::V1_2::utils { + +using CacheToken = + hidl_array(V1_2::Constant::BYTE_SIZE_OF_CACHE_TOKEN)>; + +class MockDevice final : public IDevice { + public: + static sp create(); + + // IBase methods below. + MOCK_METHOD(Return, ping, (), (override)); + MOCK_METHOD(Return, linkToDeathRet, ()); + Return linkToDeath(const sp& recipient, uint64_t /*cookie*/); + + // V1_0 methods below. + MOCK_METHOD(Return, getCapabilities, (getCapabilities_cb cb), (override)); + MOCK_METHOD(Return, getSupportedOperations, + (const V1_0::Model& model, getSupportedOperations_cb cb), (override)); + MOCK_METHOD(Return, prepareModel, + (const V1_0::Model& model, const sp& callback), + (override)); + MOCK_METHOD(Return, getStatus, (), (override)); + + // V1_1 methods below. + MOCK_METHOD(Return, getCapabilities_1_1, (getCapabilities_1_1_cb cb), (override)); + MOCK_METHOD(Return, getSupportedOperations_1_1, + (const V1_1::Model& model, getSupportedOperations_1_1_cb cb), (override)); + MOCK_METHOD(Return, prepareModel_1_1, + (const V1_1::Model& model, V1_1::ExecutionPreference preference, + const sp& callback), + (override)); + + // V1_2 methods below. + MOCK_METHOD(Return, getVersionString, (getVersionString_cb cb), (override)); + MOCK_METHOD(Return, getType, (getType_cb cb), (override)); + MOCK_METHOD(Return, getCapabilities_1_2, (getCapabilities_1_2_cb cb), (override)); + MOCK_METHOD(Return, getSupportedExtensions, (getSupportedExtensions_cb cb), (override)); + MOCK_METHOD(Return, getSupportedOperations_1_2, + (const V1_2::Model& model, getSupportedOperations_1_2_cb cb), (override)); + MOCK_METHOD(Return, getNumberOfCacheFilesNeeded, (getNumberOfCacheFilesNeeded_cb cb), + (override)); + MOCK_METHOD(Return, prepareModel_1_2, + (const V1_2::Model& model, V1_1::ExecutionPreference preference, + const hidl_vec& modelCache, const hidl_vec& dataCache, + const CacheToken& token, const sp& callback), + (override)); + MOCK_METHOD(Return, prepareModelFromCache, + (const hidl_vec& modelCache, const hidl_vec& dataCache, + const CacheToken& token, const sp& callback), + (override)); + + // Helper methods. + void simulateCrash(); + + private: + sp mDeathRecipient; +}; + +inline sp MockDevice::create() { + auto mockDevice = sp::make(); + + // Setup default actions for each relevant call. + const auto ret = []() -> Return { return true; }; + + // Setup default actions for each relevant call. + ON_CALL(*mockDevice, linkToDeathRet()).WillByDefault(testing::Invoke(ret)); + + // These EXPECT_CALL(...).Times(testing::AnyNumber()) calls are to suppress warnings on the + // uninteresting methods calls. + EXPECT_CALL(*mockDevice, linkToDeathRet()).Times(testing::AnyNumber()); + + return mockDevice; +} + +inline Return MockDevice::linkToDeath(const sp& recipient, + uint64_t /*cookie*/) { + mDeathRecipient = recipient; + return linkToDeathRet(); +} + +inline void MockDevice::simulateCrash() { + ASSERT_NE(nullptr, mDeathRecipient.get()); + + // Currently, the utils::Device will not use the `cookie` or `who` arguments, so we pass in 0 + // and nullptr for these arguments instead. Normally, they are used by the hidl_death_recipient + // to determine which object is dead. However, the utils::Device code only pairs a single death + // recipient with a single HIDL interface object, so these arguments are redundant. + mDeathRecipient->serviceDied(0, nullptr); +} + +} // namespace android::hardware::neuralnetworks::V1_2::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_2_UTILS_TEST_MOCK_DEVICE diff --git a/neuralnetworks/1.2/utils/test/MockPreparedModel.h b/neuralnetworks/1.2/utils/test/MockPreparedModel.h new file mode 100644 index 0000000000..f5fd1f3204 --- /dev/null +++ b/neuralnetworks/1.2/utils/test/MockPreparedModel.h @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_2_UTILS_TEST_MOCK_PREPARED_MODEL +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_2_UTILS_TEST_MOCK_PREPARED_MODEL + +#include +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::V1_2::utils { + +class MockPreparedModel final : public IPreparedModel { + public: + static sp create(); + + // IBase methods below. + MOCK_METHOD(Return, ping, (), (override)); + MOCK_METHOD(Return, linkToDeathRet, ()); + Return linkToDeath(const sp& recipient, + uint64_t /*cookie*/) override; + + // V1_0 methods below. + MOCK_METHOD(Return, execute, + (const V1_0::Request& request, const sp& callback), + (override)); + + // V1_2 methods below. + MOCK_METHOD(Return, execute_1_2, + (const V1_0::Request& request, V1_2::MeasureTiming measure, + const sp& callback), + (override)); + MOCK_METHOD(Return, executeSynchronously, + (const V1_0::Request& request, V1_2::MeasureTiming measure, + executeSynchronously_cb cb), + (override)); + MOCK_METHOD(Return, configureExecutionBurst, + (const sp& callback, + const MQDescriptorSync& requestChannel, + const MQDescriptorSync& resultChannel, + configureExecutionBurst_cb cb), + (override)); + + // Helper methods. + void simulateCrash(); + + private: + sp mDeathRecipient; +}; + +inline sp MockPreparedModel::create() { + auto mockPreparedModel = sp::make(); + + // Setup default actions for each relevant call. + const auto ret = []() -> Return { return true; }; + + // Setup default actions for each relevant call. + ON_CALL(*mockPreparedModel, linkToDeathRet()).WillByDefault(testing::Invoke(ret)); + + // These EXPECT_CALL(...).Times(testing::AnyNumber()) calls are to suppress warnings on the + // uninteresting methods calls. + EXPECT_CALL(*mockPreparedModel, linkToDeathRet()).Times(testing::AnyNumber()); + + return mockPreparedModel; +} + +inline Return MockPreparedModel::linkToDeath(const sp& recipient, + uint64_t /*cookie*/) { + mDeathRecipient = recipient; + return linkToDeathRet(); +} + +inline void MockPreparedModel::simulateCrash() { + ASSERT_NE(nullptr, mDeathRecipient.get()); + + // Currently, the utils::PreparedModel will not use the `cookie` or `who` arguments, so we pass + // in 0 and nullptr for these arguments instead. Normally, they are used by the + // hidl_death_recipient to determine which object is dead. However, the utils::PreparedModel + // code only pairs a single death recipient with a single HIDL interface object, so these + // arguments are redundant. + mDeathRecipient->serviceDied(0, nullptr); +} + +} // namespace android::hardware::neuralnetworks::V1_2::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_2_UTILS_TEST_MOCK_PREPARED_MODEL diff --git a/neuralnetworks/1.2/utils/test/PreparedModelTest.cpp b/neuralnetworks/1.2/utils/test/PreparedModelTest.cpp new file mode 100644 index 0000000000..5062ac9a97 --- /dev/null +++ b/neuralnetworks/1.2/utils/test/PreparedModelTest.cpp @@ -0,0 +1,341 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "MockPreparedModel.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace android::hardware::neuralnetworks::V1_2::utils { +namespace { + +using ::testing::_; +using ::testing::Invoke; +using ::testing::InvokeWithoutArgs; + +const sp kInvalidPreparedModel; +constexpr auto kNoTiming = V1_2::Timing{.timeOnDevice = std::numeric_limits::max(), + .timeInDriver = std::numeric_limits::max()}; + +sp createMockPreparedModel() { + const auto mockPreparedModel = MockPreparedModel::create(); + + // Ensure that older calls are not used. + EXPECT_CALL(*mockPreparedModel, execute(_, _)).Times(0); + + return mockPreparedModel; +} + +auto makeExecuteSynchronously(V1_0::ErrorStatus status, + const std::vector& outputShapes, + const V1_2::Timing& timing) { + return [status, outputShapes, timing](const V1_0::Request& /*request*/, + V1_2::MeasureTiming /*measureTiming*/, + const V1_2::IPreparedModel::executeSynchronously_cb& cb) { + cb(status, outputShapes, timing); + return hardware::Void(); + }; +} +auto makeExecuteAsynchronously(V1_0::ErrorStatus launchStatus, V1_0::ErrorStatus returnStatus, + const std::vector& outputShapes, + const V1_2::Timing& timing) { + return [launchStatus, returnStatus, outputShapes, timing]( + const V1_0::Request& /*request*/, V1_2::MeasureTiming /*measureTiming*/, + const sp& cb) -> Return { + cb->notify_1_2(returnStatus, outputShapes, timing); + return launchStatus; + }; +} + +std::function makeTransportFailure(status_t status) { + return [status] { return hardware::Status::fromStatusT(status); }; +} + +const auto makeGeneralTransportFailure = makeTransportFailure(NO_MEMORY); +const auto makeDeadObjectFailure = makeTransportFailure(DEAD_OBJECT); + +} // namespace + +TEST(PreparedModelTest, invalidPreparedModel) { + // run test + const auto result = PreparedModel::create(kInvalidPreparedModel, /*executeSynchronously=*/true); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(PreparedModelTest, linkToDeathError) { + // setup call + const auto mockPreparedModel = createMockPreparedModel(); + const auto ret = []() -> Return { return false; }; + EXPECT_CALL(*mockPreparedModel, linkToDeathRet()).Times(1).WillOnce(InvokeWithoutArgs(ret)); + + // run test + const auto result = PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/true); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(PreparedModelTest, linkToDeathTransportFailure) { + // setup call + const auto mockPreparedModel = createMockPreparedModel(); + EXPECT_CALL(*mockPreparedModel, linkToDeathRet()) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // run test + const auto result = PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/true); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(PreparedModelTest, linkToDeathDeadObject) { + // setup call + const auto mockPreparedModel = createMockPreparedModel(); + EXPECT_CALL(*mockPreparedModel, linkToDeathRet()) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // run test + const auto result = PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/true); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(PreparedModelTest, executeSync) { + // setup call + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/true).value(); + EXPECT_CALL(*mockPreparedModel, executeSynchronously(_, _, _)) + .Times(1) + .WillOnce(Invoke(makeExecuteSynchronously(V1_0::ErrorStatus::NONE, {}, kNoTiming))); + + // run test + const auto result = preparedModel->execute({}, {}, {}, {}); + + // verify result + EXPECT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; +} + +TEST(PreparedModelTest, executeSyncError) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/true).value(); + EXPECT_CALL(*mockPreparedModel, executeSynchronously(_, _, _)) + .Times(1) + .WillOnce(Invoke( + makeExecuteSynchronously(V1_0::ErrorStatus::GENERAL_FAILURE, {}, kNoTiming))); + + // run test + const auto result = preparedModel->execute({}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(PreparedModelTest, executeSyncTransportFailure) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/true).value(); + EXPECT_CALL(*mockPreparedModel, executeSynchronously(_, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // run test + const auto result = preparedModel->execute({}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(PreparedModelTest, executeSyncDeadObject) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/true).value(); + EXPECT_CALL(*mockPreparedModel, executeSynchronously(_, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // run test + const auto result = preparedModel->execute({}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(PreparedModelTest, executeAsync) { + // setup call + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/false).value(); + EXPECT_CALL(*mockPreparedModel, execute_1_2(_, _, _)) + .Times(1) + .WillOnce(Invoke(makeExecuteAsynchronously(V1_0::ErrorStatus::NONE, + V1_0::ErrorStatus::NONE, {}, kNoTiming))); + + // run test + const auto result = preparedModel->execute({}, {}, {}, {}); + + // verify result + EXPECT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; +} + +TEST(PreparedModelTest, executeAsyncLaunchError) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/false).value(); + EXPECT_CALL(*mockPreparedModel, execute_1_2(_, _, _)) + .Times(1) + .WillOnce(Invoke(makeExecuteAsynchronously(V1_0::ErrorStatus::GENERAL_FAILURE, + V1_0::ErrorStatus::GENERAL_FAILURE, {}, + kNoTiming))); + + // run test + const auto result = preparedModel->execute({}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(PreparedModelTest, executeAsyncReturnError) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/false).value(); + EXPECT_CALL(*mockPreparedModel, execute_1_2(_, _, _)) + .Times(1) + .WillOnce(Invoke(makeExecuteAsynchronously( + V1_0::ErrorStatus::NONE, V1_0::ErrorStatus::GENERAL_FAILURE, {}, kNoTiming))); + + // run test + const auto result = preparedModel->execute({}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(PreparedModelTest, executeAsyncTransportFailure) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/false).value(); + EXPECT_CALL(*mockPreparedModel, execute_1_2(_, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // run test + const auto result = preparedModel->execute({}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(PreparedModelTest, executeAsyncDeadObject) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/false).value(); + EXPECT_CALL(*mockPreparedModel, execute_1_2(_, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // run test + const auto result = preparedModel->execute({}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(PreparedModelTest, executeAsyncCrash) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/false).value(); + const auto ret = [&mockPreparedModel]() -> hardware::Return { + mockPreparedModel->simulateCrash(); + return V1_0::ErrorStatus::NONE; + }; + EXPECT_CALL(*mockPreparedModel, execute_1_2(_, _, _)).Times(1).WillOnce(InvokeWithoutArgs(ret)); + + // run test + const auto result = preparedModel->execute({}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(PreparedModelTest, executeFencedNotSupported) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/true).value(); + + // run test + const auto result = preparedModel->executeFenced({}, {}, {}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +// TODO: test burst execution if/when it is added to nn::IPreparedModel. + +TEST(PreparedModelTest, getUnderlyingResource) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/true).value(); + + // run test + const auto resource = preparedModel->getUnderlyingResource(); + + // verify resource + const sp* maybeMock = std::any_cast>(&resource); + ASSERT_NE(maybeMock, nullptr); + EXPECT_EQ(maybeMock->get(), mockPreparedModel.get()); +} + +} // namespace android::hardware::neuralnetworks::V1_2::utils diff --git a/neuralnetworks/1.3/utils/Android.bp b/neuralnetworks/1.3/utils/Android.bp index d5d897d470..41d9521173 100644 --- a/neuralnetworks/1.3/utils/Android.bp +++ b/neuralnetworks/1.3/utils/Android.bp @@ -38,3 +38,35 @@ cc_library_static { "neuralnetworks_utils_hal_common", ], } + +cc_test { + name: "neuralnetworks_utils_hal_1_3_test", + srcs: ["test/*.cpp"], + static_libs: [ + "android.hardware.neuralnetworks@1.0", + "android.hardware.neuralnetworks@1.1", + "android.hardware.neuralnetworks@1.2", + "android.hardware.neuralnetworks@1.3", + "libgmock", + "libneuralnetworks_common", + "neuralnetworks_types", + "neuralnetworks_utils_hal_common", + "neuralnetworks_utils_hal_1_0", + "neuralnetworks_utils_hal_1_1", + "neuralnetworks_utils_hal_1_2", + "neuralnetworks_utils_hal_1_3", + ], + shared_libs: [ + "android.hidl.allocator@1.0", + "android.hidl.memory@1.0", + "libbase", + "libcutils", + "libfmq", + "libhidlbase", + "libhidlmemory", + "liblog", + "libnativewindow", + "libutils", + ], + test_suites: ["general-tests"], +} diff --git a/neuralnetworks/1.3/utils/test/BufferTest.cpp b/neuralnetworks/1.3/utils/test/BufferTest.cpp new file mode 100644 index 0000000000..d892b8787e --- /dev/null +++ b/neuralnetworks/1.3/utils/test/BufferTest.cpp @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "MockBuffer.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace android::hardware::neuralnetworks::V1_3::utils { +namespace { + +using ::testing::_; +using ::testing::Invoke; +using ::testing::InvokeWithoutArgs; +using ::testing::Return; + +const auto kMemory = nn::createSharedMemory(4).value(); +const sp kInvalidBuffer; +constexpr auto kInvalidToken = nn::Request::MemoryDomainToken{0}; +constexpr auto kToken = nn::Request::MemoryDomainToken{1}; + +std::function()> makeFunctionReturn(V1_3::ErrorStatus status) { + return [status]() -> hardware::Return { return status; }; +} + +std::function makeTransportFailure(status_t status) { + return [status] { return hardware::Status::fromStatusT(status); }; +} + +const auto makeSuccessful = makeFunctionReturn(V1_3::ErrorStatus::NONE); +const auto makeGeneralError = makeFunctionReturn(V1_3::ErrorStatus::GENERAL_FAILURE); +const auto makeGeneralTransportFailure = makeTransportFailure(NO_MEMORY); +const auto makeDeadObjectFailure = makeTransportFailure(DEAD_OBJECT); + +} // namespace + +TEST(BufferTest, invalidBuffer) { + // run test + const auto result = Buffer::create(kInvalidBuffer, kToken); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(BufferTest, invalidToken) { + // setup call + const auto mockBuffer = MockBuffer::create(); + + // run test + const auto result = Buffer::create(mockBuffer, kInvalidToken); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(BufferTest, create) { + // setup call + const auto mockBuffer = MockBuffer::create(); + const auto buffer = Buffer::create(mockBuffer, kToken).value(); + + // run test + const auto token = buffer->getToken(); + + // verify result + EXPECT_EQ(token, kToken); +} + +TEST(BufferTest, copyTo) { + // setup call + const auto mockBuffer = MockBuffer::create(); + const auto buffer = Buffer::create(mockBuffer, kToken).value(); + EXPECT_CALL(*mockBuffer, copyTo(_)).Times(1).WillOnce(InvokeWithoutArgs(makeSuccessful)); + + // run test + const auto result = buffer->copyTo(kMemory); + + // verify result + EXPECT_TRUE(result.has_value()) << result.error().message; +} + +TEST(BufferTest, copyToError) { + // setup test + const auto mockBuffer = MockBuffer::create(); + const auto buffer = Buffer::create(mockBuffer, kToken).value(); + EXPECT_CALL(*mockBuffer, copyTo(_)).Times(1).WillOnce(InvokeWithoutArgs(makeGeneralError)); + + // run test + const auto result = buffer->copyTo(kMemory); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(BufferTest, copyToTransportFailure) { + // setup test + const auto mockBuffer = MockBuffer::create(); + const auto buffer = Buffer::create(mockBuffer, kToken).value(); + EXPECT_CALL(*mockBuffer, copyTo(_)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // run test + const auto result = buffer->copyTo(kMemory); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(BufferTest, copyToDeadObject) { + // setup test + const auto mockBuffer = MockBuffer::create(); + const auto buffer = Buffer::create(mockBuffer, kToken).value(); + EXPECT_CALL(*mockBuffer, copyTo(_)).Times(1).WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // run test + const auto result = buffer->copyTo(kMemory); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(BufferTest, copyFrom) { + // setup call + const auto mockBuffer = MockBuffer::create(); + const auto buffer = Buffer::create(mockBuffer, kToken).value(); + EXPECT_CALL(*mockBuffer, copyFrom(_, _)).Times(1).WillOnce(InvokeWithoutArgs(makeSuccessful)); + + // run test + const auto result = buffer->copyFrom(kMemory, {}); + + // verify result + EXPECT_TRUE(result.has_value()); +} + +TEST(BufferTest, copyFromError) { + // setup test + const auto mockBuffer = MockBuffer::create(); + const auto buffer = Buffer::create(mockBuffer, kToken).value(); + EXPECT_CALL(*mockBuffer, copyFrom(_, _)).Times(1).WillOnce(InvokeWithoutArgs(makeGeneralError)); + + // run test + const auto result = buffer->copyFrom(kMemory, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(BufferTest, copyFromTransportFailure) { + // setup test + const auto mockBuffer = MockBuffer::create(); + const auto buffer = Buffer::create(mockBuffer, kToken).value(); + EXPECT_CALL(*mockBuffer, copyFrom(_, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // run test + const auto result = buffer->copyFrom(kMemory, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(BufferTest, copyFromDeadObject) { + // setup test + const auto mockBuffer = MockBuffer::create(); + const auto buffer = Buffer::create(mockBuffer, kToken).value(); + EXPECT_CALL(*mockBuffer, copyFrom(_, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // run test + const auto result = buffer->copyFrom(kMemory, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +} // namespace android::hardware::neuralnetworks::V1_3::utils diff --git a/neuralnetworks/1.3/utils/test/DeviceTest.cpp b/neuralnetworks/1.3/utils/test/DeviceTest.cpp new file mode 100644 index 0000000000..f260990471 --- /dev/null +++ b/neuralnetworks/1.3/utils/test/DeviceTest.cpp @@ -0,0 +1,951 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "MockBuffer.h" +#include "MockDevice.h" +#include "MockPreparedModel.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace android::hardware::neuralnetworks::V1_3::utils { +namespace { + +using ::testing::_; +using ::testing::Invoke; +using ::testing::InvokeWithoutArgs; + +const nn::Model kSimpleModel = { + .main = {.operands = {{.type = nn::OperandType::TENSOR_FLOAT32, + .dimensions = {1}, + .lifetime = nn::Operand::LifeTime::SUBGRAPH_INPUT}, + {.type = nn::OperandType::TENSOR_FLOAT32, + .dimensions = {1}, + .lifetime = nn::Operand::LifeTime::SUBGRAPH_OUTPUT}}, + .operations = {{.type = nn::OperationType::RELU, .inputs = {0}, .outputs = {1}}}, + .inputIndexes = {0}, + .outputIndexes = {1}}}; + +const std::string kName = "Google-MockV1"; +const std::string kInvalidName = ""; +const sp kInvalidDevice; +constexpr V1_0::PerformanceInfo kNoPerformanceInfo = { + .execTime = std::numeric_limits::max(), + .powerUsage = std::numeric_limits::max()}; + +template +auto makeCallbackReturn(Args&&... args) { + return [argPack = std::make_tuple(std::forward(args)...)](const auto& cb) { + std::apply(cb, argPack); + return Void(); + }; +} + +sp createMockDevice() { + const auto mockDevice = MockDevice::create(); + + // Setup default actions for each relevant call. + const auto getVersionString_ret = makeCallbackReturn(V1_0::ErrorStatus::NONE, kName); + const auto getType_ret = makeCallbackReturn(V1_0::ErrorStatus::NONE, V1_2::DeviceType::OTHER); + const auto getSupportedExtensions_ret = + makeCallbackReturn(V1_0::ErrorStatus::NONE, hidl_vec{}); + const auto getNumberOfCacheFilesNeeded_ret = makeCallbackReturn( + V1_0::ErrorStatus::NONE, nn::kMaxNumberOfCacheFiles, nn::kMaxNumberOfCacheFiles); + const auto getCapabilities_ret = makeCallbackReturn( + V1_3::ErrorStatus::NONE, + V1_3::Capabilities{ + .relaxedFloat32toFloat16PerformanceScalar = kNoPerformanceInfo, + .relaxedFloat32toFloat16PerformanceTensor = kNoPerformanceInfo, + .ifPerformance = kNoPerformanceInfo, + .whilePerformance = kNoPerformanceInfo, + }); + + // Setup default actions for each relevant call. + ON_CALL(*mockDevice, getVersionString(_)).WillByDefault(Invoke(getVersionString_ret)); + ON_CALL(*mockDevice, getType(_)).WillByDefault(Invoke(getType_ret)); + ON_CALL(*mockDevice, getSupportedExtensions(_)) + .WillByDefault(Invoke(getSupportedExtensions_ret)); + ON_CALL(*mockDevice, getNumberOfCacheFilesNeeded(_)) + .WillByDefault(Invoke(getNumberOfCacheFilesNeeded_ret)); + ON_CALL(*mockDevice, getCapabilities_1_3(_)).WillByDefault(Invoke(getCapabilities_ret)); + + // Ensure that older calls are not used. + EXPECT_CALL(*mockDevice, getCapabilities(_)).Times(0); + EXPECT_CALL(*mockDevice, getCapabilities_1_1(_)).Times(0); + EXPECT_CALL(*mockDevice, getCapabilities_1_2(_)).Times(0); + EXPECT_CALL(*mockDevice, getSupportedOperations(_, _)).Times(0); + EXPECT_CALL(*mockDevice, getSupportedOperations_1_1(_, _)).Times(0); + EXPECT_CALL(*mockDevice, prepareModel(_, _)).Times(0); + EXPECT_CALL(*mockDevice, prepareModel_1_1(_, _, _)).Times(0); + EXPECT_CALL(*mockDevice, getSupportedOperations_1_2(_, _)).Times(0); + EXPECT_CALL(*mockDevice, prepareModel_1_2(_, _, _, _, _, _)).Times(0); + EXPECT_CALL(*mockDevice, prepareModelFromCache(_, _, _, _)).Times(0); + + // These EXPECT_CALL(...).Times(testing::AnyNumber()) calls are to suppress warnings on the + // uninteresting methods calls. + EXPECT_CALL(*mockDevice, getVersionString(_)).Times(testing::AnyNumber()); + EXPECT_CALL(*mockDevice, getType(_)).Times(testing::AnyNumber()); + EXPECT_CALL(*mockDevice, getSupportedExtensions(_)).Times(testing::AnyNumber()); + EXPECT_CALL(*mockDevice, getNumberOfCacheFilesNeeded(_)).Times(testing::AnyNumber()); + EXPECT_CALL(*mockDevice, getCapabilities_1_3(_)).Times(testing::AnyNumber()); + + return mockDevice; +} + +auto makePreparedModelReturn(V1_3::ErrorStatus launchStatus, V1_3::ErrorStatus returnStatus, + const sp& preparedModel) { + return [launchStatus, returnStatus, preparedModel]( + const V1_3::Model& /*model*/, V1_1::ExecutionPreference /*preference*/, + V1_3::Priority /*priority*/, const V1_3::OptionalTimePoint& /*deadline*/, + const hardware::hidl_vec& /*modelCache*/, + const hardware::hidl_vec& /*dataCache*/, + const CacheToken& /*token*/, const sp& cb) + -> hardware::Return { + cb->notify_1_3(returnStatus, preparedModel).isOk(); + return launchStatus; + }; +} +auto makePreparedModelFromCacheReturn(V1_3::ErrorStatus launchStatus, + V1_3::ErrorStatus returnStatus, + const sp& preparedModel) { + return [launchStatus, returnStatus, preparedModel]( + const V1_3::OptionalTimePoint& /*deadline*/, + const hardware::hidl_vec& /*modelCache*/, + const hardware::hidl_vec& /*dataCache*/, + const CacheToken& /*token*/, const sp& cb) + -> hardware::Return { + cb->notify_1_3(returnStatus, preparedModel).isOk(); + return launchStatus; + }; +} +auto makeAllocateReturn(ErrorStatus status, const sp& buffer, uint32_t token) { + return [status, buffer, token]( + const V1_3::BufferDesc& /*desc*/, + const hardware::hidl_vec>& /*preparedModels*/, + const hardware::hidl_vec& /*inputRoles*/, + const hardware::hidl_vec& /*outputRoles*/, + const V1_3::IDevice::allocate_cb& cb) -> hardware::Return { + cb(status, buffer, token); + return hardware::Void(); + }; +} + +std::function makeTransportFailure(status_t status) { + return [status] { return hardware::Status::fromStatusT(status); }; +} + +const auto makeGeneralTransportFailure = makeTransportFailure(NO_MEMORY); +const auto makeDeadObjectFailure = makeTransportFailure(DEAD_OBJECT); + +} // namespace + +TEST(DeviceTest, invalidName) { + // run test + const auto device = MockDevice::create(); + const auto result = Device::create(kInvalidName, device); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::INVALID_ARGUMENT); +} + +TEST(DeviceTest, invalidDevice) { + // run test + const auto result = Device::create(kName, kInvalidDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::INVALID_ARGUMENT); +} + +TEST(DeviceTest, getVersionStringError) { + // setup call + const auto mockDevice = createMockDevice(); + const auto ret = makeCallbackReturn(V1_0::ErrorStatus::GENERAL_FAILURE, ""); + EXPECT_CALL(*mockDevice, getVersionString(_)).Times(1).WillOnce(Invoke(ret)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, getVersionStringTransportFailure) { + // setup call + const auto mockDevice = createMockDevice(); + EXPECT_CALL(*mockDevice, getVersionString(_)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, getVersionStringDeadObject) { + // setup call + const auto mockDevice = createMockDevice(); + EXPECT_CALL(*mockDevice, getVersionString(_)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(DeviceTest, getTypeError) { + // setup call + const auto mockDevice = createMockDevice(); + const auto ret = + makeCallbackReturn(V1_0::ErrorStatus::GENERAL_FAILURE, V1_2::DeviceType::OTHER); + EXPECT_CALL(*mockDevice, getType(_)).Times(1).WillOnce(Invoke(ret)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, getTypeTransportFailure) { + // setup call + const auto mockDevice = createMockDevice(); + EXPECT_CALL(*mockDevice, getType(_)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, getTypeDeadObject) { + // setup call + const auto mockDevice = createMockDevice(); + EXPECT_CALL(*mockDevice, getType(_)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(DeviceTest, getSupportedExtensionsError) { + // setup call + const auto mockDevice = createMockDevice(); + const auto ret = + makeCallbackReturn(V1_0::ErrorStatus::GENERAL_FAILURE, hidl_vec{}); + EXPECT_CALL(*mockDevice, getSupportedExtensions(_)).Times(1).WillOnce(Invoke(ret)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, getSupportedExtensionsTransportFailure) { + // setup call + const auto mockDevice = createMockDevice(); + EXPECT_CALL(*mockDevice, getSupportedExtensions(_)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, getSupportedExtensionsDeadObject) { + // setup call + const auto mockDevice = createMockDevice(); + EXPECT_CALL(*mockDevice, getSupportedExtensions(_)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(DeviceTest, getNumberOfCacheFilesNeededError) { + // setup call + const auto mockDevice = createMockDevice(); + const auto ret = makeCallbackReturn(V1_0::ErrorStatus::GENERAL_FAILURE, + nn::kMaxNumberOfCacheFiles, nn::kMaxNumberOfCacheFiles); + EXPECT_CALL(*mockDevice, getNumberOfCacheFilesNeeded(_)).Times(1).WillOnce(Invoke(ret)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, dataCacheFilesExceedsSpecifiedMax) { + // setup test + const auto mockDevice = createMockDevice(); + const auto ret = makeCallbackReturn(V1_0::ErrorStatus::NONE, nn::kMaxNumberOfCacheFiles + 1, + nn::kMaxNumberOfCacheFiles); + EXPECT_CALL(*mockDevice, getNumberOfCacheFilesNeeded(_)).Times(1).WillOnce(Invoke(ret)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, modelCacheFilesExceedsSpecifiedMax) { + // setup test + const auto mockDevice = createMockDevice(); + const auto ret = makeCallbackReturn(V1_0::ErrorStatus::NONE, nn::kMaxNumberOfCacheFiles, + nn::kMaxNumberOfCacheFiles + 1); + EXPECT_CALL(*mockDevice, getNumberOfCacheFilesNeeded(_)).Times(1).WillOnce(Invoke(ret)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, getNumberOfCacheFilesNeededTransportFailure) { + // setup call + const auto mockDevice = createMockDevice(); + EXPECT_CALL(*mockDevice, getNumberOfCacheFilesNeeded(_)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, getNumberOfCacheFilesNeededDeadObject) { + // setup call + const auto mockDevice = createMockDevice(); + EXPECT_CALL(*mockDevice, getNumberOfCacheFilesNeeded(_)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(DeviceTest, getCapabilitiesError) { + // setup call + const auto mockDevice = createMockDevice(); + const auto ret = makeCallbackReturn( + V1_3::ErrorStatus::GENERAL_FAILURE, + V1_3::Capabilities{ + .relaxedFloat32toFloat16PerformanceScalar = kNoPerformanceInfo, + .relaxedFloat32toFloat16PerformanceTensor = kNoPerformanceInfo, + .ifPerformance = kNoPerformanceInfo, + .whilePerformance = kNoPerformanceInfo, + }); + EXPECT_CALL(*mockDevice, getCapabilities_1_3(_)).Times(1).WillOnce(Invoke(ret)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, getCapabilitiesTransportFailure) { + // setup call + const auto mockDevice = createMockDevice(); + EXPECT_CALL(*mockDevice, getCapabilities_1_3(_)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, getCapabilitiesDeadObject) { + // setup call + const auto mockDevice = createMockDevice(); + EXPECT_CALL(*mockDevice, getCapabilities_1_3(_)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(DeviceTest, linkToDeathError) { + // setup call + const auto mockDevice = createMockDevice(); + const auto ret = []() -> Return { return false; }; + EXPECT_CALL(*mockDevice, linkToDeathRet()).Times(1).WillOnce(InvokeWithoutArgs(ret)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, linkToDeathTransportFailure) { + // setup call + const auto mockDevice = createMockDevice(); + EXPECT_CALL(*mockDevice, linkToDeathRet()) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, linkToDeathDeadObject) { + // setup call + const auto mockDevice = createMockDevice(); + EXPECT_CALL(*mockDevice, linkToDeathRet()) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(DeviceTest, getName) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + + // run test + const auto& name = device->getName(); + + // verify result + EXPECT_EQ(name, kName); +} + +TEST(DeviceTest, getFeatureLevel) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + + // run test + const auto featureLevel = device->getFeatureLevel(); + + // verify result + EXPECT_EQ(featureLevel, nn::Version::ANDROID_R); +} + +TEST(DeviceTest, getCachedData) { + // setup call + const auto mockDevice = createMockDevice(); + EXPECT_CALL(*mockDevice, getVersionString(_)).Times(1); + EXPECT_CALL(*mockDevice, getType(_)).Times(1); + EXPECT_CALL(*mockDevice, getSupportedExtensions(_)).Times(1); + EXPECT_CALL(*mockDevice, getNumberOfCacheFilesNeeded(_)).Times(1); + EXPECT_CALL(*mockDevice, getCapabilities_1_3(_)).Times(1); + + const auto result = Device::create(kName, mockDevice); + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; + const auto& device = result.value(); + + // run test and verify results + EXPECT_EQ(device->getVersionString(), device->getVersionString()); + EXPECT_EQ(device->getType(), device->getType()); + EXPECT_EQ(device->getSupportedExtensions(), device->getSupportedExtensions()); + EXPECT_EQ(device->getNumberOfCacheFilesNeeded(), device->getNumberOfCacheFilesNeeded()); + EXPECT_EQ(device->getCapabilities(), device->getCapabilities()); +} + +TEST(DeviceTest, wait) { + // setup call + const auto mockDevice = createMockDevice(); + const auto ret = []() -> Return { return {}; }; + EXPECT_CALL(*mockDevice, ping()).Times(1).WillOnce(InvokeWithoutArgs(ret)); + const auto device = Device::create(kName, mockDevice).value(); + + // run test + const auto result = device->wait(); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; +} + +TEST(DeviceTest, waitTransportFailure) { + // setup call + const auto mockDevice = createMockDevice(); + EXPECT_CALL(*mockDevice, ping()) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + const auto device = Device::create(kName, mockDevice).value(); + + // run test + const auto result = device->wait(); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, waitDeadObject) { + // setup call + const auto mockDevice = createMockDevice(); + EXPECT_CALL(*mockDevice, ping()).Times(1).WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + const auto device = Device::create(kName, mockDevice).value(); + + // run test + const auto result = device->wait(); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(DeviceTest, getSupportedOperations) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + const auto ret = [](const auto& model, const auto& cb) { + cb(V1_3::ErrorStatus::NONE, std::vector(model.main.operations.size(), true)); + return hardware::Void(); + }; + EXPECT_CALL(*mockDevice, getSupportedOperations_1_3(_, _)).Times(1).WillOnce(Invoke(ret)); + + // run test + const auto result = device->getSupportedOperations(kSimpleModel); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; + const auto& supportedOperations = result.value(); + EXPECT_EQ(supportedOperations.size(), kSimpleModel.main.operations.size()); + EXPECT_THAT(supportedOperations, Each(testing::IsTrue())); +} + +TEST(DeviceTest, getSupportedOperationsError) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + const auto ret = [](const auto& /*model*/, const auto& cb) { + cb(V1_3::ErrorStatus::GENERAL_FAILURE, {}); + return hardware::Void(); + }; + EXPECT_CALL(*mockDevice, getSupportedOperations_1_3(_, _)).Times(1).WillOnce(Invoke(ret)); + + // run test + const auto result = device->getSupportedOperations(kSimpleModel); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, getSupportedOperationsTransportFailure) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + EXPECT_CALL(*mockDevice, getSupportedOperations_1_3(_, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // run test + const auto result = device->getSupportedOperations(kSimpleModel); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, getSupportedOperationsDeadObject) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + EXPECT_CALL(*mockDevice, getSupportedOperations_1_3(_, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // run test + const auto result = device->getSupportedOperations(kSimpleModel); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(DeviceTest, prepareModel) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + const auto mockPreparedModel = MockPreparedModel::create(); + EXPECT_CALL(*mockDevice, prepareModel_1_3(_, _, _, _, _, _, _, _)) + .Times(1) + .WillOnce(Invoke(makePreparedModelReturn(V1_3::ErrorStatus::NONE, + V1_3::ErrorStatus::NONE, mockPreparedModel))); + + // run test + const auto result = device->prepareModel(kSimpleModel, nn::ExecutionPreference::DEFAULT, + nn::Priority::DEFAULT, {}, {}, {}, {}); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; + EXPECT_NE(result.value(), nullptr); +} + +TEST(DeviceTest, prepareModelLaunchError) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + EXPECT_CALL(*mockDevice, prepareModel_1_3(_, _, _, _, _, _, _, _)) + .Times(1) + .WillOnce(Invoke(makePreparedModelReturn(V1_3::ErrorStatus::GENERAL_FAILURE, + V1_3::ErrorStatus::GENERAL_FAILURE, nullptr))); + + // run test + const auto result = device->prepareModel(kSimpleModel, nn::ExecutionPreference::DEFAULT, + nn::Priority::DEFAULT, {}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, prepareModelReturnError) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + EXPECT_CALL(*mockDevice, prepareModel_1_3(_, _, _, _, _, _, _, _)) + .Times(1) + .WillOnce(Invoke(makePreparedModelReturn(V1_3::ErrorStatus::NONE, + V1_3::ErrorStatus::GENERAL_FAILURE, nullptr))); + + // run test + const auto result = device->prepareModel(kSimpleModel, nn::ExecutionPreference::DEFAULT, + nn::Priority::DEFAULT, {}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, prepareModelNullptrError) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + EXPECT_CALL(*mockDevice, prepareModel_1_3(_, _, _, _, _, _, _, _)) + .Times(1) + .WillOnce(Invoke(makePreparedModelReturn(V1_3::ErrorStatus::NONE, + V1_3::ErrorStatus::NONE, nullptr))); + + // run test + const auto result = device->prepareModel(kSimpleModel, nn::ExecutionPreference::DEFAULT, + nn::Priority::DEFAULT, {}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, prepareModelTransportFailure) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + EXPECT_CALL(*mockDevice, prepareModel_1_3(_, _, _, _, _, _, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // run test + const auto result = device->prepareModel(kSimpleModel, nn::ExecutionPreference::DEFAULT, + nn::Priority::DEFAULT, {}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, prepareModelDeadObject) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + EXPECT_CALL(*mockDevice, prepareModel_1_3(_, _, _, _, _, _, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // run test + const auto result = device->prepareModel(kSimpleModel, nn::ExecutionPreference::DEFAULT, + nn::Priority::DEFAULT, {}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(DeviceTest, prepareModelAsyncCrash) { + // setup test + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + const auto ret = [&mockDevice]() -> hardware::Return { + mockDevice->simulateCrash(); + return V1_3::ErrorStatus::NONE; + }; + EXPECT_CALL(*mockDevice, prepareModel_1_3(_, _, _, _, _, _, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(ret)); + + // run test + const auto result = device->prepareModel(kSimpleModel, nn::ExecutionPreference::DEFAULT, + nn::Priority::DEFAULT, {}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(DeviceTest, prepareModelFromCache) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + const auto mockPreparedModel = MockPreparedModel::create(); + EXPECT_CALL(*mockDevice, prepareModelFromCache_1_3(_, _, _, _, _)) + .Times(1) + .WillOnce(Invoke(makePreparedModelFromCacheReturn( + V1_3::ErrorStatus::NONE, V1_3::ErrorStatus::NONE, mockPreparedModel))); + + // run test + const auto result = device->prepareModelFromCache({}, {}, {}, {}); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; + EXPECT_NE(result.value(), nullptr); +} + +TEST(DeviceTest, prepareModelFromCacheError) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + EXPECT_CALL(*mockDevice, prepareModelFromCache_1_3(_, _, _, _, _)) + .Times(1) + .WillOnce(Invoke(makePreparedModelFromCacheReturn(V1_3::ErrorStatus::GENERAL_FAILURE, + V1_3::ErrorStatus::GENERAL_FAILURE, + nullptr))); + + // run test + const auto result = device->prepareModelFromCache({}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, prepareModelFromCacheNullptrError) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + EXPECT_CALL(*mockDevice, prepareModelFromCache_1_3(_, _, _, _, _)) + .Times(1) + .WillOnce(Invoke(makePreparedModelFromCacheReturn(V1_3::ErrorStatus::NONE, + V1_3::ErrorStatus::NONE, nullptr))); + + // run test + const auto result = device->prepareModelFromCache({}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, prepareModelFromCacheTransportFailure) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + EXPECT_CALL(*mockDevice, prepareModelFromCache_1_3(_, _, _, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // run test + const auto result = device->prepareModelFromCache({}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, prepareModelFromCacheDeadObject) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + EXPECT_CALL(*mockDevice, prepareModelFromCache_1_3(_, _, _, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // run test + const auto result = device->prepareModelFromCache({}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(DeviceTest, prepareModelFromCacheAsyncCrash) { + // setup test + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + const auto ret = [&mockDevice]() -> hardware::Return { + mockDevice->simulateCrash(); + return V1_3::ErrorStatus::NONE; + }; + EXPECT_CALL(*mockDevice, prepareModelFromCache_1_3(_, _, _, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(ret)); + + // run test + const auto result = device->prepareModelFromCache({}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(DeviceTest, allocate) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + const auto mockBuffer = MockBuffer::create(); + constexpr uint32_t token = 1; + EXPECT_CALL(*mockDevice, allocate(_, _, _, _, _)) + .Times(1) + .WillOnce(Invoke(makeAllocateReturn(ErrorStatus::NONE, mockBuffer, token))); + + // run test + const auto result = device->allocate({}, {}, {}, {}); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; + EXPECT_NE(result.value(), nullptr); +} + +TEST(DeviceTest, allocateError) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + EXPECT_CALL(*mockDevice, allocate(_, _, _, _, _)) + .Times(1) + .WillOnce(Invoke(makeAllocateReturn(ErrorStatus::GENERAL_FAILURE, nullptr, 0))); + + // run test + const auto result = device->allocate({}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, allocateTransportFailure) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + EXPECT_CALL(*mockDevice, allocate(_, _, _, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // run test + const auto result = device->allocate({}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(DeviceTest, allocateDeadObject) { + // setup call + const auto mockDevice = createMockDevice(); + const auto device = Device::create(kName, mockDevice).value(); + EXPECT_CALL(*mockDevice, allocate(_, _, _, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // run test + const auto result = device->allocate({}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +} // namespace android::hardware::neuralnetworks::V1_3::utils diff --git a/neuralnetworks/1.3/utils/test/MockBuffer.h b/neuralnetworks/1.3/utils/test/MockBuffer.h new file mode 100644 index 0000000000..fb31b51261 --- /dev/null +++ b/neuralnetworks/1.3/utils/test/MockBuffer.h @@ -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. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_3_UTILS_TEST_MOCK_BUFFER +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_3_UTILS_TEST_MOCK_BUFFER + +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::V1_3::utils { + +class MockBuffer final : public IBuffer { + public: + static sp create(); + + // V1_3 methods below. + MOCK_METHOD(Return, copyTo, (const hidl_memory& dst), (override)); + MOCK_METHOD(Return, copyFrom, + (const hidl_memory& src, const hidl_vec& dimensions), (override)); +}; + +inline sp MockBuffer::create() { + return sp::make(); +} + +} // namespace android::hardware::neuralnetworks::V1_3::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_3_UTILS_TEST_MOCK_BUFFER diff --git a/neuralnetworks/1.3/utils/test/MockDevice.h b/neuralnetworks/1.3/utils/test/MockDevice.h new file mode 100644 index 0000000000..85d3750d22 --- /dev/null +++ b/neuralnetworks/1.3/utils/test/MockDevice.h @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_3_UTILS_TEST_MOCK_DEVICE +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_3_UTILS_TEST_MOCK_DEVICE + +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::V1_3::utils { + +using CacheToken = + hidl_array(V1_2::Constant::BYTE_SIZE_OF_CACHE_TOKEN)>; + +class MockDevice final : public IDevice { + public: + static sp create(); + + // IBase methods below. + MOCK_METHOD(Return, ping, (), (override)); + MOCK_METHOD(Return, linkToDeathRet, ()); + Return linkToDeath(const sp& recipient, uint64_t /*cookie*/); + + // V1_0 methods below. + MOCK_METHOD(Return, getCapabilities, (getCapabilities_cb cb), (override)); + MOCK_METHOD(Return, getSupportedOperations, + (const V1_0::Model& model, getSupportedOperations_cb cb), (override)); + MOCK_METHOD(Return, prepareModel, + (const V1_0::Model& model, const sp& callback), + (override)); + MOCK_METHOD(Return, getStatus, (), (override)); + + // V1_1 methods below. + MOCK_METHOD(Return, getCapabilities_1_1, (getCapabilities_1_1_cb cb), (override)); + MOCK_METHOD(Return, getSupportedOperations_1_1, + (const V1_1::Model& model, getSupportedOperations_1_1_cb cb), (override)); + MOCK_METHOD(Return, prepareModel_1_1, + (const V1_1::Model& model, V1_1::ExecutionPreference preference, + const sp& callback), + (override)); + + // V1_2 methods below. + MOCK_METHOD(Return, getVersionString, (getVersionString_cb cb), (override)); + MOCK_METHOD(Return, getType, (getType_cb cb), (override)); + MOCK_METHOD(Return, getCapabilities_1_2, (getCapabilities_1_2_cb cb), (override)); + MOCK_METHOD(Return, getSupportedExtensions, (getSupportedExtensions_cb cb), (override)); + MOCK_METHOD(Return, getSupportedOperations_1_2, + (const V1_2::Model& model, getSupportedOperations_1_2_cb cb), (override)); + MOCK_METHOD(Return, getNumberOfCacheFilesNeeded, (getNumberOfCacheFilesNeeded_cb cb), + (override)); + MOCK_METHOD(Return, prepareModel_1_2, + (const V1_2::Model& model, V1_1::ExecutionPreference preference, + const hidl_vec& modelCache, const hidl_vec& dataCache, + const CacheToken& token, const sp& callback), + (override)); + MOCK_METHOD(Return, prepareModelFromCache, + (const hidl_vec& modelCache, const hidl_vec& dataCache, + const CacheToken& token, const sp& callback), + (override)); + + // V1_3 methods below. + MOCK_METHOD(Return, getCapabilities_1_3, (getCapabilities_1_3_cb cb), (override)); + MOCK_METHOD(Return, getSupportedOperations_1_3, + (const V1_3::Model& model, getSupportedOperations_1_3_cb cb), (override)); + MOCK_METHOD(Return, prepareModel_1_3, + (const V1_3::Model& model, V1_1::ExecutionPreference preference, + V1_3::Priority priority, const V1_3::OptionalTimePoint& deadline, + const hidl_vec& modelCache, const hidl_vec& dataCache, + const CacheToken& token, const sp& callback), + (override)); + MOCK_METHOD(Return, prepareModelFromCache_1_3, + (const V1_3::OptionalTimePoint& deadline, const hidl_vec& modelCache, + const hidl_vec& dataCache, const CacheToken& token, + const sp& callback), + (override)); + MOCK_METHOD(Return, allocate, + (const V1_3::BufferDesc& desc, + const hidl_vec>& preparedModels, + const hidl_vec& inputRoles, + const hidl_vec& outputRoles, allocate_cb cb), + (override)); + + // Helper methods. + void simulateCrash(); + + private: + sp mDeathRecipient; +}; + +inline sp MockDevice::create() { + auto mockDevice = sp::make(); + + // Setup default actions for each relevant call. + const auto ret = []() -> Return { return true; }; + + // Setup default actions for each relevant call. + ON_CALL(*mockDevice, linkToDeathRet()).WillByDefault(testing::Invoke(ret)); + + // These EXPECT_CALL(...).Times(testing::AnyNumber()) calls are to suppress warnings on the + // uninteresting methods calls. + EXPECT_CALL(*mockDevice, linkToDeathRet()).Times(testing::AnyNumber()); + + return mockDevice; +} + +inline Return MockDevice::linkToDeath(const sp& recipient, + uint64_t /*cookie*/) { + mDeathRecipient = recipient; + return linkToDeathRet(); +} + +inline void MockDevice::simulateCrash() { + ASSERT_NE(nullptr, mDeathRecipient.get()); + + // Currently, the utils::Device will not use the `cookie` or `who` arguments, so we pass in 0 + // and nullptr for these arguments instead. Normally, they are used by the hidl_death_recipient + // to determine which object is dead. However, the utils::Device code only pairs a single death + // recipient with a single HIDL interface object, so these arguments are redundant. + mDeathRecipient->serviceDied(0, nullptr); +} + +} // namespace android::hardware::neuralnetworks::V1_3::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_3_UTILS_TEST_MOCK_DEVICE diff --git a/neuralnetworks/1.3/utils/test/MockFencedExecutionCallback.h b/neuralnetworks/1.3/utils/test/MockFencedExecutionCallback.h new file mode 100644 index 0000000000..fc08a7fc70 --- /dev/null +++ b/neuralnetworks/1.3/utils/test/MockFencedExecutionCallback.h @@ -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. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_3_UTILS_TEST_MOCK_FENCED_EXECUTION_CALLBACK +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_3_UTILS_TEST_MOCK_FENCED_EXECUTION_CALLBACK + +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::V1_3::utils { + +class MockFencedExecutionCallback final : public IFencedExecutionCallback { + public: + static sp create(); + + // V1_3 methods below. + MOCK_METHOD(Return, getExecutionInfo, (IFencedExecutionCallback::getExecutionInfo_cb cb), + (override)); +}; + +inline sp MockFencedExecutionCallback::create() { + return sp::make(); +} + +} // namespace android::hardware::neuralnetworks::V1_3::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_3_UTILS_TEST_MOCK_FENCED_EXECUTION_CALLBACK diff --git a/neuralnetworks/1.3/utils/test/MockPreparedModel.h b/neuralnetworks/1.3/utils/test/MockPreparedModel.h new file mode 100644 index 0000000000..e44152426b --- /dev/null +++ b/neuralnetworks/1.3/utils/test/MockPreparedModel.h @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_3_UTILS_TEST_MOCK_PREPARED_MODEL +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_3_UTILS_TEST_MOCK_PREPARED_MODEL + +#include +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::V1_3::utils { + +class MockPreparedModel final : public IPreparedModel { + public: + static sp create(); + + // IBase methods below. + MOCK_METHOD(Return, ping, (), (override)); + MOCK_METHOD(Return, linkToDeathRet, ()); + Return linkToDeath(const sp& recipient, + uint64_t /*cookie*/) override; + + // V1_0 methods below. + MOCK_METHOD(Return, execute, + (const V1_0::Request& request, const sp& callback), + (override)); + + // V1_2 methods below. + MOCK_METHOD(Return, execute_1_2, + (const V1_0::Request& request, V1_2::MeasureTiming measure, + const sp& callback), + (override)); + MOCK_METHOD(Return, executeSynchronously, + (const V1_0::Request& request, V1_2::MeasureTiming measure, + executeSynchronously_cb cb), + (override)); + MOCK_METHOD(Return, configureExecutionBurst, + (const sp& callback, + const MQDescriptorSync& requestChannel, + const MQDescriptorSync& resultChannel, + configureExecutionBurst_cb cb), + (override)); + + // V1_3 methods below. + MOCK_METHOD(Return, execute_1_3, + (const V1_3::Request& request, V1_2::MeasureTiming measure, + const V1_3::OptionalTimePoint& deadline, + const V1_3::OptionalTimeoutDuration& loopTimeoutDuration, + const sp& callback), + (override)); + MOCK_METHOD(Return, executeSynchronously_1_3, + (const V1_3::Request& request, V1_2::MeasureTiming measure, + const V1_3::OptionalTimePoint& deadline, + const V1_3::OptionalTimeoutDuration& loopTimeoutDuration, + executeSynchronously_1_3_cb cb), + (override)); + MOCK_METHOD(Return, executeFenced, + (const V1_3::Request& request, const hidl_vec& waitFor, + V1_2::MeasureTiming measure, const V1_3::OptionalTimePoint& deadline, + const V1_3::OptionalTimeoutDuration& loopTimeoutDuration, + const V1_3::OptionalTimeoutDuration& duration, executeFenced_cb cb), + (override)); + + // Helper methods. + void simulateCrash(); + + private: + sp mDeathRecipient; +}; + +inline sp MockPreparedModel::create() { + auto mockPreparedModel = sp::make(); + + // Setup default actions for each relevant call. + const auto ret = []() -> Return { return true; }; + + // Setup default actions for each relevant call. + ON_CALL(*mockPreparedModel, linkToDeathRet()).WillByDefault(testing::Invoke(ret)); + + // These EXPECT_CALL(...).Times(testing::AnyNumber()) calls are to suppress warnings on the + // uninteresting methods calls. + EXPECT_CALL(*mockPreparedModel, linkToDeathRet()).Times(testing::AnyNumber()); + + return mockPreparedModel; +} + +inline Return MockPreparedModel::linkToDeath(const sp& recipient, + uint64_t /*cookie*/) { + mDeathRecipient = recipient; + return linkToDeathRet(); +} + +inline void MockPreparedModel::simulateCrash() { + ASSERT_NE(nullptr, mDeathRecipient.get()); + + // Currently, the utils::PreparedModel will not use the `cookie` or `who` arguments, so we pass + // in 0 and nullptr for these arguments instead. Normally, they are used by the + // hidl_death_recipient to determine which object is dead. However, the utils::PreparedModel + // code only pairs a single death recipient with a single HIDL interface object, so these + // arguments are redundant. + mDeathRecipient->serviceDied(0, nullptr); +} + +} // namespace android::hardware::neuralnetworks::V1_3::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_3_UTILS_TEST_MOCK_PREPARED_MODEL diff --git a/neuralnetworks/1.3/utils/test/PreparedModelTest.cpp b/neuralnetworks/1.3/utils/test/PreparedModelTest.cpp new file mode 100644 index 0000000000..11796ddc2d --- /dev/null +++ b/neuralnetworks/1.3/utils/test/PreparedModelTest.cpp @@ -0,0 +1,470 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "MockFencedExecutionCallback.h" +#include "MockPreparedModel.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace android::hardware::neuralnetworks::V1_3::utils { +namespace { + +using ::testing::_; +using ::testing::Invoke; +using ::testing::InvokeWithoutArgs; + +const sp kInvalidPreparedModel; +constexpr auto kNoTiming = V1_2::Timing{.timeOnDevice = std::numeric_limits::max(), + .timeInDriver = std::numeric_limits::max()}; + +sp createMockPreparedModel() { + const auto mockPreparedModel = MockPreparedModel::create(); + + // Ensure that older calls are not used. + EXPECT_CALL(*mockPreparedModel, execute(_, _)).Times(0); + EXPECT_CALL(*mockPreparedModel, execute_1_2(_, _, _)).Times(0); + EXPECT_CALL(*mockPreparedModel, executeSynchronously(_, _, _)).Times(0); + + return mockPreparedModel; +} + +auto makeExecuteSynchronously(V1_3::ErrorStatus status, + const std::vector& outputShapes, + const V1_2::Timing& timing) { + return [status, outputShapes, timing]( + const V1_3::Request& /*request*/, V1_2::MeasureTiming /*measureTiming*/, + const V1_3::OptionalTimePoint& /*deadline*/, + const V1_3::OptionalTimeoutDuration& /*loopTimeoutDuration*/, + const V1_3::IPreparedModel::executeSynchronously_1_3_cb& cb) { + cb(status, outputShapes, timing); + return hardware::Void(); + }; +} +auto makeExecuteAsynchronously(V1_3::ErrorStatus launchStatus, V1_3::ErrorStatus returnStatus, + const std::vector& outputShapes, + const V1_2::Timing& timing) { + return [launchStatus, returnStatus, outputShapes, timing]( + const V1_3::Request& /*request*/, V1_2::MeasureTiming /*measureTiming*/, + const V1_3::OptionalTimePoint& /*deadline*/, + const V1_3::OptionalTimeoutDuration& /*loopTimeoutDuration*/, + const sp& cb) -> Return { + cb->notify_1_3(returnStatus, outputShapes, timing); + return launchStatus; + }; +} +auto makeExecuteFencedReturn(V1_3::ErrorStatus status, const hardware::hidl_handle& syncFence, + const sp& dispatchCallback) { + return [status, syncFence, dispatchCallback]( + const V1_3::Request& /*request*/, + const hardware::hidl_vec& /*waitFor*/, + V1_2::MeasureTiming /*measure*/, const V1_3::OptionalTimePoint& /*deadline*/, + const V1_3::OptionalTimeoutDuration& /*loopTimeoutDuration*/, + const V1_3::OptionalTimeoutDuration& /*duration*/, + const V1_3::IPreparedModel::executeFenced_cb& cb) { + cb(status, syncFence, dispatchCallback); + return hardware::Void(); + }; +} +auto makeExecuteFencedCallbackReturn(V1_3::ErrorStatus status, const V1_2::Timing& timingA, + const V1_2::Timing& timingB) { + return [status, timingA, + timingB](const V1_3::IFencedExecutionCallback::getExecutionInfo_cb& cb) { + cb(status, timingA, timingB); + return hardware::Void(); + }; +} + +std::function makeTransportFailure(status_t status) { + return [status] { return hardware::Status::fromStatusT(status); }; +} + +const auto makeGeneralTransportFailure = makeTransportFailure(NO_MEMORY); +const auto makeDeadObjectFailure = makeTransportFailure(DEAD_OBJECT); + +} // namespace + +TEST(PreparedModelTest, invalidPreparedModel) { + // run test + const auto result = PreparedModel::create(kInvalidPreparedModel, /*executeSynchronously=*/true); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(PreparedModelTest, linkToDeathError) { + // setup call + const auto mockPreparedModel = createMockPreparedModel(); + const auto ret = []() -> Return { return false; }; + EXPECT_CALL(*mockPreparedModel, linkToDeathRet()).Times(1).WillOnce(InvokeWithoutArgs(ret)); + + // run test + const auto result = PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/true); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(PreparedModelTest, linkToDeathTransportFailure) { + // setup call + const auto mockPreparedModel = createMockPreparedModel(); + EXPECT_CALL(*mockPreparedModel, linkToDeathRet()) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // run test + const auto result = PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/true); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(PreparedModelTest, linkToDeathDeadObject) { + // setup call + const auto mockPreparedModel = createMockPreparedModel(); + EXPECT_CALL(*mockPreparedModel, linkToDeathRet()) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // run test + const auto result = PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/true); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(PreparedModelTest, executeSync) { + // setup call + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/true).value(); + EXPECT_CALL(*mockPreparedModel, executeSynchronously_1_3(_, _, _, _, _)) + .Times(1) + .WillOnce(Invoke(makeExecuteSynchronously(V1_3::ErrorStatus::NONE, {}, kNoTiming))); + + // run test + const auto result = preparedModel->execute({}, {}, {}, {}); + + // verify result + EXPECT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; +} + +TEST(PreparedModelTest, executeSyncError) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/true).value(); + EXPECT_CALL(*mockPreparedModel, executeSynchronously_1_3(_, _, _, _, _)) + .Times(1) + .WillOnce(Invoke( + makeExecuteSynchronously(V1_3::ErrorStatus::GENERAL_FAILURE, {}, kNoTiming))); + + // run test + const auto result = preparedModel->execute({}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(PreparedModelTest, executeSyncTransportFailure) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/true).value(); + EXPECT_CALL(*mockPreparedModel, executeSynchronously_1_3(_, _, _, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // run test + const auto result = preparedModel->execute({}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(PreparedModelTest, executeSyncDeadObject) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/true).value(); + EXPECT_CALL(*mockPreparedModel, executeSynchronously_1_3(_, _, _, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // run test + const auto result = preparedModel->execute({}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(PreparedModelTest, executeAsync) { + // setup call + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/false).value(); + EXPECT_CALL(*mockPreparedModel, execute_1_3(_, _, _, _, _)) + .Times(1) + .WillOnce(Invoke(makeExecuteAsynchronously(V1_3::ErrorStatus::NONE, + V1_3::ErrorStatus::NONE, {}, kNoTiming))); + + // run test + const auto result = preparedModel->execute({}, {}, {}, {}); + + // verify result + EXPECT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; +} + +TEST(PreparedModelTest, executeAsyncLaunchError) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/false).value(); + EXPECT_CALL(*mockPreparedModel, execute_1_3(_, _, _, _, _)) + .Times(1) + .WillOnce(Invoke(makeExecuteAsynchronously(V1_3::ErrorStatus::GENERAL_FAILURE, + V1_3::ErrorStatus::GENERAL_FAILURE, {}, + kNoTiming))); + + // run test + const auto result = preparedModel->execute({}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(PreparedModelTest, executeAsyncReturnError) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/false).value(); + EXPECT_CALL(*mockPreparedModel, execute_1_3(_, _, _, _, _)) + .Times(1) + .WillOnce(Invoke(makeExecuteAsynchronously( + V1_3::ErrorStatus::NONE, V1_3::ErrorStatus::GENERAL_FAILURE, {}, kNoTiming))); + + // run test + const auto result = preparedModel->execute({}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(PreparedModelTest, executeAsyncTransportFailure) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/false).value(); + EXPECT_CALL(*mockPreparedModel, execute_1_3(_, _, _, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // run test + const auto result = preparedModel->execute({}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(PreparedModelTest, executeAsyncDeadObject) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/false).value(); + EXPECT_CALL(*mockPreparedModel, execute_1_3(_, _, _, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // run test + const auto result = preparedModel->execute({}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(PreparedModelTest, executeAsyncCrash) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/false).value(); + const auto ret = [&mockPreparedModel]() -> hardware::Return { + mockPreparedModel->simulateCrash(); + return V1_3::ErrorStatus::NONE; + }; + EXPECT_CALL(*mockPreparedModel, execute_1_3(_, _, _, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(ret)); + + // run test + const auto result = preparedModel->execute({}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(PreparedModelTest, executeFenced) { + // setup call + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/true).value(); + const auto mockCallback = MockFencedExecutionCallback::create(); + EXPECT_CALL(*mockCallback, getExecutionInfo(_)) + .Times(1) + .WillOnce(Invoke(makeExecuteFencedCallbackReturn(V1_3::ErrorStatus::NONE, kNoTiming, + kNoTiming))); + EXPECT_CALL(*mockPreparedModel, executeFenced(_, _, _, _, _, _, _)) + .Times(1) + .WillOnce(Invoke(makeExecuteFencedReturn(V1_3::ErrorStatus::NONE, {}, mockCallback))); + + // run test + const auto result = preparedModel->executeFenced({}, {}, {}, {}, {}, {}); + + // 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(PreparedModelTest, executeFencedCallbackError) { + // setup call + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/true).value(); + const auto mockCallback = MockFencedExecutionCallback::create(); + EXPECT_CALL(*mockCallback, getExecutionInfo(_)) + .Times(1) + .WillOnce(Invoke(makeExecuteFencedCallbackReturn(V1_3::ErrorStatus::GENERAL_FAILURE, + kNoTiming, kNoTiming))); + EXPECT_CALL(*mockPreparedModel, executeFenced(_, _, _, _, _, _, _)) + .Times(1) + .WillOnce(Invoke(makeExecuteFencedReturn(V1_3::ErrorStatus::NONE, {}, mockCallback))); + + // run test + const auto result = preparedModel->executeFenced({}, {}, {}, {}, {}, {}); + + // 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(PreparedModelTest, executeFencedError) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/true).value(); + EXPECT_CALL(*mockPreparedModel, executeFenced(_, _, _, _, _, _, _)) + .Times(1) + .WillOnce(Invoke( + makeExecuteFencedReturn(V1_3::ErrorStatus::GENERAL_FAILURE, {}, nullptr))); + + // run test + const auto result = preparedModel->executeFenced({}, {}, {}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(PreparedModelTest, executeFencedTransportFailure) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/true).value(); + EXPECT_CALL(*mockPreparedModel, executeFenced(_, _, _, _, _, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // run test + const auto result = preparedModel->executeFenced({}, {}, {}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(PreparedModelTest, executeFencedDeadObject) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/true).value(); + EXPECT_CALL(*mockPreparedModel, executeFenced(_, _, _, _, _, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // run test + const auto result = preparedModel->executeFenced({}, {}, {}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +// TODO: test burst execution if/when it is added to nn::IPreparedModel. + +TEST(PreparedModelTest, getUnderlyingResource) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/true).value(); + + // run test + const auto resource = preparedModel->getUnderlyingResource(); + + // verify resource + const sp* maybeMock = std::any_cast>(&resource); + ASSERT_NE(maybeMock, nullptr); + EXPECT_EQ(maybeMock->get(), mockPreparedModel.get()); +} + +} // namespace android::hardware::neuralnetworks::V1_3::utils diff --git a/neuralnetworks/TEST_MAPPING b/neuralnetworks/TEST_MAPPING index ca5041db4b..de846244a1 100644 --- a/neuralnetworks/TEST_MAPPING +++ b/neuralnetworks/TEST_MAPPING @@ -1,5 +1,20 @@ { "presubmit": [ + { + "name": "neuralnetworks_utils_hal_common_test" + }, + { + "name": "neuralnetworks_utils_hal_1_0_test" + }, + { + "name": "neuralnetworks_utils_hal_1_1_test" + }, + { + "name": "neuralnetworks_utils_hal_1_2_test" + }, + { + "name": "neuralnetworks_utils_hal_1_3_test" + }, { "name": "VtsHalNeuralnetworksV1_0TargetTest", "options": [ diff --git a/neuralnetworks/utils/common/Android.bp b/neuralnetworks/utils/common/Android.bp index 21562cffaf..6c491ae7ae 100644 --- a/neuralnetworks/utils/common/Android.bp +++ b/neuralnetworks/utils/common/Android.bp @@ -28,3 +28,28 @@ cc_library_static { "libhidlbase", ], } + +cc_test { + name: "neuralnetworks_utils_hal_common_test", + srcs: ["test/*.cpp"], + static_libs: [ + "android.hardware.neuralnetworks@1.0", + "libgmock", + "libneuralnetworks_common", + "neuralnetworks_types", + "neuralnetworks_utils_hal_common", + ], + shared_libs: [ + "android.hidl.allocator@1.0", + "android.hidl.memory@1.0", + "libbase", + "libcutils", + "libfmq", + "libhidlbase", + "libhidlmemory", + "liblog", + "libnativewindow", + "libutils", + ], + test_suites: ["general-tests"], +} diff --git a/neuralnetworks/utils/common/test/MockBuffer.h b/neuralnetworks/utils/common/test/MockBuffer.h new file mode 100644 index 0000000000..c5405fb837 --- /dev/null +++ b/neuralnetworks/utils/common/test/MockBuffer.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_TEST_MOCK_BUFFER +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_TEST_MOCK_BUFFER + +#include +#include +#include +#include + +namespace android::nn { + +class MockBuffer final : public IBuffer { + public: + MOCK_METHOD(Request::MemoryDomainToken, getToken, (), (const, override)); + MOCK_METHOD(GeneralResult, copyTo, (const Memory& dst), (const, override)); + MOCK_METHOD(GeneralResult, copyFrom, (const Memory& src, const Dimensions& dimensions), + (const, override)); +}; + +} // namespace android::nn + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_TEST_MOCK_BUFFER diff --git a/neuralnetworks/utils/common/test/MockDevice.h b/neuralnetworks/utils/common/test/MockDevice.h new file mode 100644 index 0000000000..08cd5c5501 --- /dev/null +++ b/neuralnetworks/utils/common/test/MockDevice.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_TEST_MOCK_DEVICE +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_TEST_MOCK_DEVICE + +#include +#include +#include + +namespace android::nn { + +class MockDevice final : public IDevice { + public: + MOCK_METHOD(const std::string&, getName, (), (const, override)); + MOCK_METHOD(const std::string&, getVersionString, (), (const, override)); + MOCK_METHOD(Version, getFeatureLevel, (), (const, override)); + MOCK_METHOD(DeviceType, getType, (), (const, override)); + MOCK_METHOD(const std::vector&, getSupportedExtensions, (), (const, override)); + MOCK_METHOD(const Capabilities&, getCapabilities, (), (const, override)); + MOCK_METHOD((std::pair), getNumberOfCacheFilesNeeded, (), + (const, override)); + MOCK_METHOD(GeneralResult, wait, (), (const, override)); + MOCK_METHOD(GeneralResult>, getSupportedOperations, (const Model& model), + (const, override)); + MOCK_METHOD(GeneralResult, prepareModel, + (const Model& model, ExecutionPreference preference, Priority priority, + OptionalTimePoint deadline, const std::vector& modelCache, + const std::vector& dataCache, const CacheToken& token), + (const, override)); + MOCK_METHOD(GeneralResult, prepareModelFromCache, + (OptionalTimePoint deadline, const std::vector& modelCache, + const std::vector& dataCache, const CacheToken& token), + (const, override)); + MOCK_METHOD(GeneralResult, allocate, + (const BufferDesc& desc, const std::vector& preparedModels, + const std::vector& inputRoles, + const std::vector& outputRoles), + (const, override)); +}; + +} // namespace android::nn + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_TEST_MOCK_DEVICE diff --git a/neuralnetworks/utils/common/test/MockPreparedModel.h b/neuralnetworks/utils/common/test/MockPreparedModel.h new file mode 100644 index 0000000000..928508edc3 --- /dev/null +++ b/neuralnetworks/utils/common/test/MockPreparedModel.h @@ -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. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_TEST_MOCK_PREPARED_MODEL +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_TEST_MOCK_PREPARED_MODEL + +#include +#include +#include + +namespace android::nn { + +class MockPreparedModel final : public IPreparedModel { + public: + MOCK_METHOD((ExecutionResult, Timing>>), execute, + (const Request& request, MeasureTiming measure, const OptionalTimePoint& deadline, + const OptionalDuration& loopTimeoutDuration), + (const, override)); + MOCK_METHOD((GeneralResult>), executeFenced, + (const Request& request, const std::vector& waitFor, + MeasureTiming measure, const OptionalTimePoint& deadline, + const OptionalDuration& loopTimeoutDuration, + const OptionalDuration& timeoutDurationAfterFence), + (const, override)); + MOCK_METHOD(std::any, getUnderlyingResource, (), (const, override)); +}; + +} // namespace android::nn + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_TEST_MOCK_PREPARED_MODEL diff --git a/neuralnetworks/utils/common/test/ResilientBufferTest.cpp b/neuralnetworks/utils/common/test/ResilientBufferTest.cpp new file mode 100644 index 0000000000..deb9b7cf21 --- /dev/null +++ b/neuralnetworks/utils/common/test/ResilientBufferTest.cpp @@ -0,0 +1,266 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include "MockBuffer.h" + +namespace android::hardware::neuralnetworks::utils { +namespace { + +using ::testing::_; +using ::testing::InvokeWithoutArgs; +using ::testing::Return; + +constexpr auto kToken = nn::Request::MemoryDomainToken{1}; + +using SharedMockBuffer = std::shared_ptr; +using MockBufferFactory = ::testing::MockFunction()>; + +SharedMockBuffer createConfiguredMockBuffer() { + return std::make_shared(); +} + +std::tuple, std::unique_ptr, + std::shared_ptr> +setup() { + auto mockBuffer = std::make_shared(); + + auto mockBufferFactory = std::make_unique(); + EXPECT_CALL(*mockBufferFactory, Call()).Times(1).WillOnce(Return(mockBuffer)); + + auto buffer = ResilientBuffer::create(mockBufferFactory->AsStdFunction()).value(); + return std::make_tuple(std::move(mockBuffer), std::move(mockBufferFactory), std::move(buffer)); +} + +constexpr auto makeError = [](nn::ErrorStatus status) { + return [status](const auto&... /*args*/) { return nn::error(status); }; +}; +const auto kReturnGeneralFailure = makeError(nn::ErrorStatus::GENERAL_FAILURE); +const auto kReturnDeadObject = makeError(nn::ErrorStatus::DEAD_OBJECT); + +const auto kNoError = nn::GeneralResult{}; + +} // namespace + +TEST(ResilientBufferTest, invalidBufferFactory) { + // setup call + const auto invalidBufferFactory = ResilientBuffer::Factory{}; + + // run test + const auto result = ResilientBuffer::create(invalidBufferFactory); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::INVALID_ARGUMENT); +} + +TEST(ResilientBufferTest, bufferFactoryFailure) { + // setup call + const auto invalidBufferFactory = kReturnGeneralFailure; + + // run test + const auto result = ResilientBuffer::create(invalidBufferFactory); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(ResilientBufferTest, getBuffer) { + // setup call + const auto [mockBuffer, mockBufferFactory, buffer] = setup(); + + // run test + const auto result = buffer->getBuffer(); + + // verify result + EXPECT_TRUE(result == mockBuffer); +} + +TEST(ResilientBufferTest, getToken) { + // setup call + const auto [mockBuffer, mockBufferFactory, buffer] = setup(); + EXPECT_CALL(*mockBuffer, getToken()).Times(1).WillOnce(Return(kToken)); + + // run test + const auto token = buffer->getToken(); + + // verify result + EXPECT_EQ(token, kToken); +} + +TEST(ResilientBufferTest, copyTo) { + // setup call + const auto [mockBuffer, mockBufferFactory, buffer] = setup(); + EXPECT_CALL(*mockBuffer, copyTo(_)).Times(1).WillOnce(Return(kNoError)); + + // run test + const auto result = buffer->copyTo({}); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; +} + +TEST(ResilientBufferTest, copyToError) { + // setup call + const auto [mockBuffer, mockBufferFactory, buffer] = setup(); + EXPECT_CALL(*mockBuffer, copyTo(_)).Times(1).WillOnce(kReturnGeneralFailure); + + // run test + const auto result = buffer->copyTo({}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(ResilientBufferTest, copyToDeadObjectFailedRecovery) { + // setup call + const auto [mockBuffer, mockBufferFactory, buffer] = setup(); + EXPECT_CALL(*mockBuffer, copyTo(_)).Times(1).WillOnce(kReturnDeadObject); + EXPECT_CALL(*mockBufferFactory, Call()).Times(1).WillOnce(kReturnGeneralFailure); + + // run test + const auto result = buffer->copyTo({}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(ResilientBufferTest, copyToDeadObjectSuccessfulRecovery) { + // setup call + const auto [mockBuffer, mockBufferFactory, buffer] = setup(); + EXPECT_CALL(*mockBuffer, copyTo(_)).Times(1).WillOnce(kReturnDeadObject); + const auto recoveredMockBuffer = createConfiguredMockBuffer(); + EXPECT_CALL(*recoveredMockBuffer, copyTo(_)).Times(1).WillOnce(Return(kNoError)); + EXPECT_CALL(*mockBufferFactory, Call()).Times(1).WillOnce(Return(recoveredMockBuffer)); + + // run test + const auto result = buffer->copyTo({}); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; +} + +TEST(ResilientBufferTest, copyFrom) { + // setup call + const auto [mockBuffer, mockBufferFactory, buffer] = setup(); + EXPECT_CALL(*mockBuffer, copyFrom(_, _)).Times(1).WillOnce(Return(kNoError)); + + // run test + const auto result = buffer->copyFrom({}, {}); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; +} + +TEST(ResilientBufferTest, copyFromError) { + // setup call + const auto [mockBuffer, mockBufferFactory, buffer] = setup(); + EXPECT_CALL(*mockBuffer, copyFrom(_, _)).Times(1).WillOnce(kReturnGeneralFailure); + + // run test + const auto result = buffer->copyFrom({}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(ResilientBufferTest, copyFromDeadObjectFailedRecovery) { + // setup call + const auto [mockBuffer, mockBufferFactory, buffer] = setup(); + EXPECT_CALL(*mockBuffer, copyFrom(_, _)).Times(1).WillOnce(kReturnDeadObject); + EXPECT_CALL(*mockBufferFactory, Call()).Times(1).WillOnce(kReturnGeneralFailure); + + // run test + const auto result = buffer->copyFrom({}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(ResilientBufferTest, copyFromDeadObjectSuccessfulRecovery) { + // setup call + const auto [mockBuffer, mockBufferFactory, buffer] = setup(); + EXPECT_CALL(*mockBuffer, copyFrom(_, _)).Times(1).WillOnce(kReturnDeadObject); + const auto recoveredMockBuffer = createConfiguredMockBuffer(); + EXPECT_CALL(*recoveredMockBuffer, copyFrom(_, _)).Times(1).WillOnce(Return(kNoError)); + EXPECT_CALL(*mockBufferFactory, Call()).Times(1).WillOnce(Return(recoveredMockBuffer)); + + // run test + const auto result = buffer->copyFrom({}, {}); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; +} + +TEST(ResilientBufferTest, recover) { + // setup call + const auto [mockBuffer, mockBufferFactory, buffer] = setup(); + const auto recoveredMockBuffer = createConfiguredMockBuffer(); + EXPECT_CALL(*mockBufferFactory, Call()).Times(1).WillOnce(Return(recoveredMockBuffer)); + + // run test + const auto result = buffer->recover(mockBuffer.get()); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; + EXPECT_TRUE(result.value() == recoveredMockBuffer); +} + +TEST(ResilientBufferTest, recoverFailure) { + // setup call + const auto [mockBuffer, mockBufferFactory, buffer] = setup(); + const auto recoveredMockBuffer = createConfiguredMockBuffer(); + EXPECT_CALL(*mockBufferFactory, Call()).Times(1).WillOnce(kReturnGeneralFailure); + + // run test + const auto result = buffer->recover(mockBuffer.get()); + + // verify result + EXPECT_FALSE(result.has_value()); +} + +TEST(ResilientBufferTest, someoneElseRecovered) { + // setup call + const auto [mockBuffer, mockBufferFactory, buffer] = setup(); + const auto recoveredMockBuffer = createConfiguredMockBuffer(); + EXPECT_CALL(*mockBufferFactory, Call()).Times(1).WillOnce(Return(recoveredMockBuffer)); + buffer->recover(mockBuffer.get()); + + // run test + const auto result = buffer->recover(mockBuffer.get()); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; + EXPECT_TRUE(result.value() == recoveredMockBuffer); +} + +} // namespace android::hardware::neuralnetworks::utils diff --git a/neuralnetworks/utils/common/test/ResilientDeviceTest.cpp b/neuralnetworks/utils/common/test/ResilientDeviceTest.cpp new file mode 100644 index 0000000000..3abd724c8c --- /dev/null +++ b/neuralnetworks/utils/common/test/ResilientDeviceTest.cpp @@ -0,0 +1,725 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include "MockBuffer.h" +#include "MockDevice.h" +#include "MockPreparedModel.h" + +namespace android::hardware::neuralnetworks::utils { +namespace { + +using ::testing::_; +using ::testing::InvokeWithoutArgs; +using ::testing::Return; + +using SharedMockDevice = std::shared_ptr; +using MockDeviceFactory = ::testing::MockFunction(bool)>; + +const std::string kName = "Google-MockV1"; +const std::string kVersionString = "version1"; +const auto kExtensions = std::vector{}; +constexpr auto kNoInfo = std::numeric_limits::max(); +constexpr auto kNoPerformanceInfo = + nn::Capabilities::PerformanceInfo{.execTime = kNoInfo, .powerUsage = kNoInfo}; +const auto kCapabilities = nn::Capabilities{ + .relaxedFloat32toFloat16PerformanceScalar = kNoPerformanceInfo, + .relaxedFloat32toFloat16PerformanceTensor = kNoPerformanceInfo, + .operandPerformance = nn::Capabilities::OperandPerformanceTable::create({}).value(), + .ifPerformance = kNoPerformanceInfo, + .whilePerformance = kNoPerformanceInfo}; +constexpr auto kNumberOfCacheFilesNeeded = std::pair(5, 3); + +SharedMockDevice createConfiguredMockDevice() { + auto mockDevice = std::make_shared(); + + // Setup default actions for each relevant call. + constexpr auto getName_ret = []() -> const std::string& { return kName; }; + constexpr auto getVersionString_ret = []() -> const std::string& { return kVersionString; }; + constexpr auto kFeatureLevel = nn::Version::ANDROID_OC_MR1; + constexpr auto kDeviceType = nn::DeviceType::ACCELERATOR; + constexpr auto getSupportedExtensions_ret = []() -> const std::vector& { + return kExtensions; + }; + constexpr auto getCapabilities_ret = []() -> const nn::Capabilities& { return kCapabilities; }; + + // Setup default actions for each relevant call. + ON_CALL(*mockDevice, getName()).WillByDefault(getName_ret); + ON_CALL(*mockDevice, getVersionString()).WillByDefault(getVersionString_ret); + ON_CALL(*mockDevice, getFeatureLevel()).WillByDefault(Return(kFeatureLevel)); + ON_CALL(*mockDevice, getType()).WillByDefault(Return(kDeviceType)); + ON_CALL(*mockDevice, getSupportedExtensions()).WillByDefault(getSupportedExtensions_ret); + ON_CALL(*mockDevice, getCapabilities()).WillByDefault(getCapabilities_ret); + ON_CALL(*mockDevice, getNumberOfCacheFilesNeeded()) + .WillByDefault(Return(kNumberOfCacheFilesNeeded)); + + // These EXPECT_CALL(...).Times(testing::AnyNumber()) calls are to suppress warnings on the + // uninteresting methods calls. + EXPECT_CALL(*mockDevice, getName()).Times(testing::AnyNumber()); + EXPECT_CALL(*mockDevice, getVersionString()).Times(testing::AnyNumber()); + EXPECT_CALL(*mockDevice, getFeatureLevel()).Times(testing::AnyNumber()); + EXPECT_CALL(*mockDevice, getType()).Times(testing::AnyNumber()); + EXPECT_CALL(*mockDevice, getSupportedExtensions()).Times(testing::AnyNumber()); + EXPECT_CALL(*mockDevice, getCapabilities()).Times(testing::AnyNumber()); + EXPECT_CALL(*mockDevice, getNumberOfCacheFilesNeeded()).Times(testing::AnyNumber()); + + return mockDevice; +} + +std::tuple, + std::shared_ptr> +setup() { + auto mockDevice = createConfiguredMockDevice(); + + auto mockDeviceFactory = std::make_unique(); + EXPECT_CALL(*mockDeviceFactory, Call(true)).Times(1).WillOnce(Return(mockDevice)); + + auto device = ResilientDevice::create(mockDeviceFactory->AsStdFunction()).value(); + return std::make_tuple(std::move(mockDevice), std::move(mockDeviceFactory), std::move(device)); +} + +constexpr auto makeError = [](nn::ErrorStatus status) { + return [status](const auto&... /*args*/) { return nn::error(status); }; +}; +const auto kReturnGeneralFailure = makeError(nn::ErrorStatus::GENERAL_FAILURE); +const auto kReturnDeadObject = makeError(nn::ErrorStatus::DEAD_OBJECT); + +} // namespace + +TEST(ResilientDeviceTest, invalidDeviceFactory) { + // setup call + const auto invalidDeviceFactory = ResilientDevice::Factory{}; + + // run test + const auto result = ResilientDevice::create(invalidDeviceFactory); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::INVALID_ARGUMENT); +} + +TEST(ResilientDeviceTest, preparedModelFactoryFailure) { + // setup call + const auto invalidDeviceFactory = kReturnGeneralFailure; + + // run test + const auto result = ResilientDevice::create(invalidDeviceFactory); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(ResilientDeviceTest, cachedData) { + // setup call + const auto [mockDevice, mockDeviceFactory, device] = setup(); + + // run test and verify results + EXPECT_EQ(device->getName(), kName); + EXPECT_EQ(device->getVersionString(), kVersionString); + EXPECT_EQ(device->getSupportedExtensions(), kExtensions); + EXPECT_EQ(device->getCapabilities(), kCapabilities); +} + +TEST(ResilientDeviceTest, getFeatureLevel) { + // setup call + const auto [mockDevice, mockDeviceFactory, device] = setup(); + constexpr auto kFeatureLevel = nn::Version::ANDROID_OC_MR1; + EXPECT_CALL(*mockDevice, getFeatureLevel()).Times(1).WillOnce(Return(kFeatureLevel)); + + // run test + const auto featureLevel = device->getFeatureLevel(); + + // verify results + EXPECT_EQ(featureLevel, kFeatureLevel); +} + +TEST(ResilientDeviceTest, getType) { + // setup call + const auto [mockDevice, mockDeviceFactory, device] = setup(); + constexpr auto kDeviceType = nn::DeviceType::ACCELERATOR; + EXPECT_CALL(*mockDevice, getType()).Times(1).WillOnce(Return(kDeviceType)); + + // run test + const auto type = device->getType(); + + // verify results + EXPECT_EQ(type, kDeviceType); +} + +TEST(ResilientDeviceTest, getNumberOfCacheFilesNeeded) { + // setup call + const auto [mockDevice, mockDeviceFactory, device] = setup(); + EXPECT_CALL(*mockDevice, getNumberOfCacheFilesNeeded()) + .Times(1) + .WillOnce(Return(kNumberOfCacheFilesNeeded)); + + // run test + const auto numberOfCacheFilesNeeded = device->getNumberOfCacheFilesNeeded(); + + // verify results + EXPECT_EQ(numberOfCacheFilesNeeded, kNumberOfCacheFilesNeeded); +} + +TEST(ResilientDeviceTest, getDevice) { + // setup call + const auto [mockDevice, mockDeviceFactory, device] = setup(); + + // run test + const auto result = device->getDevice(); + + // verify result + EXPECT_TRUE(result == mockDevice); +} + +TEST(ResilientDeviceTest, wait) { + // setup call + const auto [mockDevice, mockDeviceFactory, device] = setup(); + EXPECT_CALL(*mockDevice, wait()).Times(1).WillOnce(Return(nn::GeneralResult{})); + + // run test + const auto result = device->wait(); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; +} + +TEST(ResilientDeviceTest, waitError) { + // setup call + const auto [mockDevice, mockDeviceFactory, device] = setup(); + EXPECT_CALL(*mockDevice, wait()).Times(1).WillOnce(kReturnGeneralFailure); + + // run test + const auto result = device->wait(); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(ResilientDeviceTest, waitDeadObjectFailedRecovery) { + // setup call + const auto [mockDevice, mockDeviceFactory, device] = setup(); + EXPECT_CALL(*mockDevice, wait()).Times(1).WillOnce(kReturnDeadObject); + EXPECT_CALL(*mockDeviceFactory, Call(true)).Times(1).WillOnce(kReturnGeneralFailure); + + // run test + const auto result = device->wait(); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(ResilientDeviceTest, waitDeadObjectSuccessfulRecovery) { + // setup call + const auto [mockDevice, mockDeviceFactory, device] = setup(); + EXPECT_CALL(*mockDevice, wait()).Times(1).WillOnce(kReturnDeadObject); + const auto recoveredMockDevice = createConfiguredMockDevice(); + EXPECT_CALL(*recoveredMockDevice, wait()).Times(1).WillOnce(Return(nn::GeneralResult{})); + EXPECT_CALL(*mockDeviceFactory, Call(true)).Times(1).WillOnce(Return(recoveredMockDevice)); + + // run test + const auto result = device->wait(); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; +} + +TEST(ResilientDeviceTest, getSupportedOperations) { + // setup call + const auto [mockDevice, mockDeviceFactory, device] = setup(); + EXPECT_CALL(*mockDevice, getSupportedOperations(_)) + .Times(1) + .WillOnce(Return(nn::GeneralResult>{})); + + // run test + const auto result = device->getSupportedOperations({}); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; +} + +TEST(ResilientDeviceTest, getSupportedOperationsError) { + // setup call + const auto [mockDevice, mockDeviceFactory, device] = setup(); + EXPECT_CALL(*mockDevice, getSupportedOperations(_)).Times(1).WillOnce(kReturnGeneralFailure); + + // run test + const auto result = device->getSupportedOperations({}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(ResilientDeviceTest, getSupportedOperationsDeadObjectFailedRecovery) { + // setup call + const auto [mockDevice, mockDeviceFactory, device] = setup(); + EXPECT_CALL(*mockDevice, getSupportedOperations(_)).Times(1).WillOnce(kReturnDeadObject); + EXPECT_CALL(*mockDeviceFactory, Call(false)).Times(1).WillOnce(kReturnGeneralFailure); + + // run test + const auto result = device->getSupportedOperations({}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(ResilientDeviceTest, getSupportedOperationsDeadObjectSuccessfulRecovery) { + // setup call + const auto [mockDevice, mockDeviceFactory, device] = setup(); + EXPECT_CALL(*mockDevice, getSupportedOperations(_)).Times(1).WillOnce(kReturnDeadObject); + const auto recoveredMockDevice = createConfiguredMockDevice(); + EXPECT_CALL(*recoveredMockDevice, getSupportedOperations(_)) + .Times(1) + .WillOnce(Return(nn::GeneralResult>{})); + EXPECT_CALL(*mockDeviceFactory, Call(false)).Times(1).WillOnce(Return(recoveredMockDevice)); + + // run test + const auto result = device->getSupportedOperations({}); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; +} + +TEST(ResilientDeviceTest, prepareModel) { + // setup call + const auto [mockDevice, mockDeviceFactory, device] = setup(); + const auto mockPreparedModel = std::make_shared(); + EXPECT_CALL(*mockDevice, prepareModel(_, _, _, _, _, _, _)) + .Times(1) + .WillOnce(Return(mockPreparedModel)); + + // run test + const auto result = device->prepareModel({}, {}, {}, {}, {}, {}, {}); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; +} + +TEST(ResilientDeviceTest, prepareModelError) { + // setup call + const auto [mockDevice, mockDeviceFactory, device] = setup(); + EXPECT_CALL(*mockDevice, prepareModel(_, _, _, _, _, _, _)) + .Times(1) + .WillOnce(kReturnGeneralFailure); + + // run test + const auto result = device->prepareModel({}, {}, {}, {}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(ResilientDeviceTest, prepareModelDeadObjectFailedRecovery) { + // setup call + const auto [mockDevice, mockDeviceFactory, device] = setup(); + EXPECT_CALL(*mockDevice, prepareModel(_, _, _, _, _, _, _)) + .Times(1) + .WillOnce(kReturnDeadObject); + EXPECT_CALL(*mockDeviceFactory, Call(false)).Times(1).WillOnce(kReturnGeneralFailure); + + // run test + const auto result = device->prepareModel({}, {}, {}, {}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(ResilientDeviceTest, prepareModelDeadObjectSuccessfulRecovery) { + // setup call + const auto [mockDevice, mockDeviceFactory, device] = setup(); + EXPECT_CALL(*mockDevice, prepareModel(_, _, _, _, _, _, _)) + .Times(1) + .WillOnce(kReturnDeadObject); + const auto recoveredMockDevice = createConfiguredMockDevice(); + const auto mockPreparedModel = std::make_shared(); + EXPECT_CALL(*recoveredMockDevice, prepareModel(_, _, _, _, _, _, _)) + .Times(1) + .WillOnce(Return(mockPreparedModel)); + EXPECT_CALL(*mockDeviceFactory, Call(false)).Times(1).WillOnce(Return(recoveredMockDevice)); + + // run test + const auto result = device->prepareModel({}, {}, {}, {}, {}, {}, {}); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; +} + +TEST(ResilientDeviceTest, prepareModelFromCache) { + // setup call + const auto [mockDevice, mockDeviceFactory, device] = setup(); + const auto mockPreparedModel = std::make_shared(); + EXPECT_CALL(*mockDevice, prepareModelFromCache(_, _, _, _)) + .Times(1) + .WillOnce(Return(mockPreparedModel)); + + // run test + const auto result = device->prepareModelFromCache({}, {}, {}, {}); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; +} + +TEST(ResilientDeviceTest, prepareModelFromCacheError) { + // setup call + const auto [mockDevice, mockDeviceFactory, device] = setup(); + EXPECT_CALL(*mockDevice, prepareModelFromCache(_, _, _, _)) + .Times(1) + .WillOnce(kReturnGeneralFailure); + + // run test + const auto result = device->prepareModelFromCache({}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(ResilientDeviceTest, prepareModelFromCacheDeadObjectFailedRecovery) { + // setup call + const auto [mockDevice, mockDeviceFactory, device] = setup(); + EXPECT_CALL(*mockDevice, prepareModelFromCache(_, _, _, _)) + .Times(1) + .WillOnce(kReturnDeadObject); + EXPECT_CALL(*mockDeviceFactory, Call(false)).Times(1).WillOnce(kReturnGeneralFailure); + + // run test + const auto result = device->prepareModelFromCache({}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(ResilientDeviceTest, prepareModelFromCacheDeadObjectSuccessfulRecovery) { + // setup call + const auto [mockDevice, mockDeviceFactory, device] = setup(); + EXPECT_CALL(*mockDevice, prepareModelFromCache(_, _, _, _)) + .Times(1) + .WillOnce(kReturnDeadObject); + const auto recoveredMockDevice = createConfiguredMockDevice(); + const auto mockPreparedModel = std::make_shared(); + EXPECT_CALL(*recoveredMockDevice, prepareModelFromCache(_, _, _, _)) + .Times(1) + .WillOnce(Return(mockPreparedModel)); + EXPECT_CALL(*mockDeviceFactory, Call(false)).Times(1).WillOnce(Return(recoveredMockDevice)); + + // run test + const auto result = device->prepareModelFromCache({}, {}, {}, {}); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; +} + +TEST(ResilientDeviceTest, allocate) { + // setup call + const auto [mockDevice, mockDeviceFactory, device] = setup(); + const auto mockBuffer = std::make_shared(); + EXPECT_CALL(*mockDevice, allocate(_, _, _, _)).Times(1).WillOnce(Return(mockBuffer)); + + // run test + const auto result = device->allocate({}, {}, {}, {}); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; +} + +TEST(ResilientDeviceTest, allocateError) { + // setup call + const auto [mockDevice, mockDeviceFactory, device] = setup(); + EXPECT_CALL(*mockDevice, allocate(_, _, _, _)).Times(1).WillOnce(kReturnGeneralFailure); + + // run test + const auto result = device->allocate({}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(ResilientDeviceTest, allocateDeadObjectFailedRecovery) { + // setup call + const auto [mockDevice, mockDeviceFactory, device] = setup(); + EXPECT_CALL(*mockDevice, allocate(_, _, _, _)).Times(1).WillOnce(kReturnDeadObject); + EXPECT_CALL(*mockDeviceFactory, Call(false)).Times(1).WillOnce(kReturnGeneralFailure); + + // run test + const auto result = device->allocate({}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(ResilientDeviceTest, allocateDeadObjectSuccessfulRecovery) { + // setup call + const auto [mockDevice, mockDeviceFactory, device] = setup(); + EXPECT_CALL(*mockDevice, allocate(_, _, _, _)).Times(1).WillOnce(kReturnDeadObject); + const auto recoveredMockDevice = createConfiguredMockDevice(); + const auto mockBuffer = std::make_shared(); + EXPECT_CALL(*recoveredMockDevice, allocate(_, _, _, _)).Times(1).WillOnce(Return(mockBuffer)); + EXPECT_CALL(*mockDeviceFactory, Call(false)).Times(1).WillOnce(Return(recoveredMockDevice)); + + // run test + const auto result = device->allocate({}, {}, {}, {}); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; +} + +TEST(ResilientDeviceTest, recover) { + // setup call + const auto [mockDevice, mockDeviceFactory, device] = setup(); + const auto recoveredMockDevice = createConfiguredMockDevice(); + EXPECT_CALL(*mockDeviceFactory, Call(false)).Times(1).WillOnce(Return(recoveredMockDevice)); + + // run test + const auto result = device->recover(mockDevice.get(), /*blocking=*/false); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; + EXPECT_TRUE(result.value() == recoveredMockDevice); +} + +TEST(ResilientDeviceTest, recoverFailure) { + // setup call + const auto [mockDevice, mockDeviceFactory, device] = setup(); + const auto recoveredMockDevice = createConfiguredMockDevice(); + EXPECT_CALL(*mockDeviceFactory, Call(_)).Times(1).WillOnce(kReturnGeneralFailure); + + // run test + const auto result = device->recover(mockDevice.get(), /*blocking=*/false); + + // verify result + EXPECT_FALSE(result.has_value()); +} + +TEST(ResilientDeviceTest, someoneElseRecovered) { + // setup call + const auto [mockDevice, mockDeviceFactory, device] = setup(); + const auto recoveredMockDevice = createConfiguredMockDevice(); + EXPECT_CALL(*mockDeviceFactory, Call(false)).Times(1).WillOnce(Return(recoveredMockDevice)); + device->recover(mockDevice.get(), /*blocking=*/false); + + // run test + const auto result = device->recover(mockDevice.get(), /*blocking=*/false); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; + EXPECT_TRUE(result.value() == recoveredMockDevice); +} + +TEST(ResilientDeviceTest, recoverCacheMismatchGetName) { + // setup call + const auto [mockDevice, mockDeviceFactory, device] = setup(); + const auto recoveredMockDevice = createConfiguredMockDevice(); + const std::string kDifferentName = "Google-DifferentName"; + const auto ret = [&kDifferentName]() -> const std::string& { return kDifferentName; }; + EXPECT_CALL(*recoveredMockDevice, getName()).Times(1).WillOnce(ret); + EXPECT_CALL(*mockDeviceFactory, Call(false)).Times(1).WillOnce(Return(recoveredMockDevice)); + + // run test + const auto result = device->recover(mockDevice.get(), /*blocking=*/false); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; + EXPECT_TRUE(result.value() != nullptr); + EXPECT_TRUE(result.value() != mockDevice); + EXPECT_TRUE(result.value() != recoveredMockDevice); +} + +TEST(ResilientDeviceTest, recoverCacheMismatchGetVersionString) { + // setup call + const auto [mockDevice, mockDeviceFactory, device] = setup(); + const auto recoveredMockDevice = createConfiguredMockDevice(); + const std::string kDifferentVersionString = "differentversion"; + const auto ret = [&kDifferentVersionString]() -> const std::string& { + return kDifferentVersionString; + }; + EXPECT_CALL(*recoveredMockDevice, getVersionString()).Times(1).WillOnce(ret); + EXPECT_CALL(*mockDeviceFactory, Call(false)).Times(1).WillOnce(Return(recoveredMockDevice)); + + // run test + const auto result = device->recover(mockDevice.get(), /*blocking=*/false); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; + EXPECT_TRUE(result.value() != nullptr); + EXPECT_TRUE(result.value() != mockDevice); + EXPECT_TRUE(result.value() != recoveredMockDevice); +} + +TEST(ResilientDeviceTest, recoverCacheMismatchGetFeatureLevel) { + // setup call + const auto [mockDevice, mockDeviceFactory, device] = setup(); + const auto recoveredMockDevice = createConfiguredMockDevice(); + EXPECT_CALL(*recoveredMockDevice, getFeatureLevel()) + .Times(1) + .WillOnce(Return(nn::Version::ANDROID_P)); + EXPECT_CALL(*mockDeviceFactory, Call(false)).Times(1).WillOnce(Return(recoveredMockDevice)); + + // run test + const auto result = device->recover(mockDevice.get(), /*blocking=*/false); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; + EXPECT_TRUE(result.value() != nullptr); + EXPECT_TRUE(result.value() != mockDevice); + EXPECT_TRUE(result.value() != recoveredMockDevice); +} + +TEST(ResilientDeviceTest, recoverCacheMismatchGetType) { + // setup call + const auto [mockDevice, mockDeviceFactory, device] = setup(); + const auto recoveredMockDevice = createConfiguredMockDevice(); + EXPECT_CALL(*recoveredMockDevice, getType()).Times(1).WillOnce(Return(nn::DeviceType::GPU)); + EXPECT_CALL(*mockDeviceFactory, Call(false)).Times(1).WillOnce(Return(recoveredMockDevice)); + + // run test + const auto result = device->recover(mockDevice.get(), /*blocking=*/false); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; + EXPECT_TRUE(result.value() != nullptr); + EXPECT_TRUE(result.value() != mockDevice); + EXPECT_TRUE(result.value() != recoveredMockDevice); +} + +TEST(ResilientDeviceTest, recoverCacheMismatchGetSupportedExtensions) { + // setup call + const auto [mockDevice, mockDeviceFactory, device] = setup(); + const auto recoveredMockDevice = createConfiguredMockDevice(); + const auto kDifferentExtensions = + std::vector{nn::Extension{.name = "", .operandTypes = {}}}; + const auto ret = [&kDifferentExtensions]() -> const std::vector& { + return kDifferentExtensions; + }; + EXPECT_CALL(*recoveredMockDevice, getSupportedExtensions()).Times(1).WillOnce(ret); + EXPECT_CALL(*mockDeviceFactory, Call(false)).Times(1).WillOnce(Return(recoveredMockDevice)); + + // run test + const auto result = device->recover(mockDevice.get(), /*blocking=*/false); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; + EXPECT_TRUE(result.value() != nullptr); + EXPECT_TRUE(result.value() != mockDevice); + EXPECT_TRUE(result.value() != recoveredMockDevice); +} + +TEST(ResilientDeviceTest, recoverCacheMismatchGetCapabilities) { + // setup call + const auto [mockDevice, mockDeviceFactory, device] = setup(); + const auto recoveredMockDevice = createConfiguredMockDevice(); + const auto kDifferentCapabilities = nn::Capabilities{ + .relaxedFloat32toFloat16PerformanceTensor = {.execTime = 0.5f, .powerUsage = 0.5f}, + .operandPerformance = nn::Capabilities::OperandPerformanceTable::create({}).value()}; + const auto ret = [&kDifferentCapabilities]() -> const nn::Capabilities& { + return kDifferentCapabilities; + }; + EXPECT_CALL(*recoveredMockDevice, getCapabilities()).Times(1).WillOnce(ret); + EXPECT_CALL(*mockDeviceFactory, Call(false)).Times(1).WillOnce(Return(recoveredMockDevice)); + + // run test + const auto result = device->recover(mockDevice.get(), /*blocking=*/false); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; + EXPECT_TRUE(result.value() != nullptr); + EXPECT_TRUE(result.value() != mockDevice); + EXPECT_TRUE(result.value() != recoveredMockDevice); +} + +TEST(ResilientDeviceTest, recoverCacheMismatchInvalidPrepareModel) { + // setup call + const auto [mockDevice, mockDeviceFactory, device] = setup(); + const auto recoveredMockDevice = createConfiguredMockDevice(); + EXPECT_CALL(*recoveredMockDevice, getType()).Times(1).WillOnce(Return(nn::DeviceType::GPU)); + EXPECT_CALL(*mockDeviceFactory, Call(false)).Times(1).WillOnce(Return(recoveredMockDevice)); + device->recover(mockDevice.get(), /*blocking=*/false); + + // run test + auto result = device->prepareModel({}, {}, {}, {}, {}, {}, {}); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; + EXPECT_TRUE(result.value() != nullptr); +} + +TEST(ResilientDeviceTest, recoverCacheMismatchInvalidPrepareModelFromCache) { + // setup call + const auto [mockDevice, mockDeviceFactory, device] = setup(); + const auto recoveredMockDevice = createConfiguredMockDevice(); + EXPECT_CALL(*recoveredMockDevice, getType()).Times(1).WillOnce(Return(nn::DeviceType::GPU)); + EXPECT_CALL(*mockDeviceFactory, Call(false)).Times(1).WillOnce(Return(recoveredMockDevice)); + device->recover(mockDevice.get(), /*blocking=*/false); + + // run test + auto result = device->prepareModelFromCache({}, {}, {}, {}); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; + EXPECT_TRUE(result.value() != nullptr); +} + +TEST(ResilientDeviceTest, recoverCacheMismatchInvalidAllocate) { + // setup call + const auto [mockDevice, mockDeviceFactory, device] = setup(); + const auto recoveredMockDevice = createConfiguredMockDevice(); + EXPECT_CALL(*recoveredMockDevice, getType()).Times(1).WillOnce(Return(nn::DeviceType::GPU)); + EXPECT_CALL(*mockDeviceFactory, Call(false)).Times(1).WillOnce(Return(recoveredMockDevice)); + device->recover(mockDevice.get(), /*blocking=*/false); + + // run test + auto result = device->allocate({}, {}, {}, {}); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; + EXPECT_TRUE(result.value() != nullptr); +} + +} // namespace android::hardware::neuralnetworks::utils diff --git a/neuralnetworks/utils/common/test/ResilientPreparedModelTest.cpp b/neuralnetworks/utils/common/test/ResilientPreparedModelTest.cpp new file mode 100644 index 0000000000..6d86e10df2 --- /dev/null +++ b/neuralnetworks/utils/common/test/ResilientPreparedModelTest.cpp @@ -0,0 +1,297 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include "MockPreparedModel.h" + +namespace android::hardware::neuralnetworks::utils { +namespace { + +using ::testing::_; +using ::testing::InvokeWithoutArgs; +using ::testing::Return; + +using SharedMockPreparedModel = std::shared_ptr; +using MockPreparedModelFactory = + ::testing::MockFunction()>; + +SharedMockPreparedModel createConfiguredMockPreparedModel() { + return std::make_shared(); +} + +std::tuple, std::unique_ptr, + std::shared_ptr> +setup() { + auto mockPreparedModel = std::make_shared(); + + auto mockPreparedModelFactory = std::make_unique(); + EXPECT_CALL(*mockPreparedModelFactory, Call()).Times(1).WillOnce(Return(mockPreparedModel)); + + auto buffer = ResilientPreparedModel::create(mockPreparedModelFactory->AsStdFunction()).value(); + return std::make_tuple(std::move(mockPreparedModel), std::move(mockPreparedModelFactory), + std::move(buffer)); +} + +constexpr auto makeError = [](nn::ErrorStatus status) { + return [status](const auto&... /*args*/) { return nn::error(status); }; +}; +const auto kReturnGeneralFailure = makeError(nn::ErrorStatus::GENERAL_FAILURE); +const auto kReturnDeadObject = makeError(nn::ErrorStatus::DEAD_OBJECT); + +const auto kNoExecutionError = + nn::ExecutionResult, nn::Timing>>{}; +const auto kNoFencedExecutionError = + nn::GeneralResult>( + std::make_pair(nn::SyncFence::createAsSignaled(), nullptr)); + +struct FakeResource {}; + +} // namespace + +TEST(ResilientPreparedModelTest, invalidPreparedModelFactory) { + // setup call + const auto invalidPreparedModelFactory = ResilientPreparedModel::Factory{}; + + // run test + const auto result = ResilientPreparedModel::create(invalidPreparedModelFactory); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::INVALID_ARGUMENT); +} + +TEST(ResilientPreparedModelTest, preparedModelFactoryFailure) { + // setup call + const auto invalidPreparedModelFactory = kReturnGeneralFailure; + + // run test + const auto result = ResilientPreparedModel::create(invalidPreparedModelFactory); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(ResilientPreparedModelTest, getPreparedModel) { + // setup call + const auto [mockPreparedModel, mockPreparedModelFactory, preparedModel] = setup(); + + // run test + const auto result = preparedModel->getPreparedModel(); + + // verify result + EXPECT_TRUE(result == mockPreparedModel); +} + +TEST(ResilientPreparedModelTest, execute) { + // setup call + const auto [mockPreparedModel, mockPreparedModelFactory, preparedModel] = setup(); + EXPECT_CALL(*mockPreparedModel, execute(_, _, _, _)) + .Times(1) + .WillOnce(Return(kNoExecutionError)); + + // run test + const auto result = preparedModel->execute({}, {}, {}, {}); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; +} + +TEST(ResilientPreparedModelTest, executeError) { + // setup call + const auto [mockPreparedModel, mockPreparedModelFactory, preparedModel] = setup(); + EXPECT_CALL(*mockPreparedModel, execute(_, _, _, _)).Times(1).WillOnce(kReturnGeneralFailure); + + // run test + const auto result = preparedModel->execute({}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(ResilientPreparedModelTest, executeDeadObjectFailedRecovery) { + // setup call + const auto [mockPreparedModel, mockPreparedModelFactory, preparedModel] = setup(); + EXPECT_CALL(*mockPreparedModel, execute(_, _, _, _)).Times(1).WillOnce(kReturnDeadObject); + constexpr auto ret = [] { return nn::error(nn::ErrorStatus::GENERAL_FAILURE); }; + EXPECT_CALL(*mockPreparedModelFactory, Call()).Times(1).WillOnce(ret); + + // run test + const auto result = preparedModel->execute({}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(ResilientPreparedModelTest, executeDeadObjectSuccessfulRecovery) { + // setup call + const auto [mockPreparedModel, mockPreparedModelFactory, preparedModel] = setup(); + EXPECT_CALL(*mockPreparedModel, execute(_, _, _, _)).Times(1).WillOnce(kReturnDeadObject); + const auto recoveredMockPreparedModel = createConfiguredMockPreparedModel(); + EXPECT_CALL(*recoveredMockPreparedModel, execute(_, _, _, _)) + .Times(1) + .WillOnce(Return(kNoExecutionError)); + EXPECT_CALL(*mockPreparedModelFactory, Call()) + .Times(1) + .WillOnce(Return(recoveredMockPreparedModel)); + + // run test + const auto result = preparedModel->execute({}, {}, {}, {}); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; +} + +TEST(ResilientPreparedModelTest, executeFenced) { + // setup call + const auto [mockPreparedModel, mockPreparedModelFactory, preparedModel] = setup(); + EXPECT_CALL(*mockPreparedModel, executeFenced(_, _, _, _, _, _)) + .Times(1) + .WillOnce(Return(kNoFencedExecutionError)); + + // run test + const auto result = preparedModel->executeFenced({}, {}, {}, {}, {}, {}); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; +} + +TEST(ResilientPreparedModelTest, executeFencedError) { + // setup call + const auto [mockPreparedModel, mockPreparedModelFactory, preparedModel] = setup(); + EXPECT_CALL(*mockPreparedModel, executeFenced(_, _, _, _, _, _)) + .Times(1) + .WillOnce(kReturnGeneralFailure); + + // run test + const auto result = preparedModel->executeFenced({}, {}, {}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(ResilientPreparedModelTest, executeFencedDeadObjectFailedRecovery) { + // setup call + const auto [mockPreparedModel, mockPreparedModelFactory, preparedModel] = setup(); + EXPECT_CALL(*mockPreparedModel, executeFenced(_, _, _, _, _, _)) + .Times(1) + .WillOnce(kReturnDeadObject); + EXPECT_CALL(*mockPreparedModelFactory, Call()).Times(1).WillOnce(kReturnGeneralFailure); + + // run test + const auto result = preparedModel->executeFenced({}, {}, {}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(ResilientPreparedModelTest, executeFencedDeadObjectSuccessfulRecovery) { + // setup call + const auto [mockPreparedModel, mockPreparedModelFactory, preparedModel] = setup(); + EXPECT_CALL(*mockPreparedModel, executeFenced(_, _, _, _, _, _)) + .Times(1) + .WillOnce(kReturnDeadObject); + const auto recoveredMockPreparedModel = createConfiguredMockPreparedModel(); + EXPECT_CALL(*recoveredMockPreparedModel, executeFenced(_, _, _, _, _, _)) + .Times(1) + .WillOnce(Return(kNoFencedExecutionError)); + EXPECT_CALL(*mockPreparedModelFactory, Call()) + .Times(1) + .WillOnce(Return(recoveredMockPreparedModel)); + + // run test + const auto result = preparedModel->executeFenced({}, {}, {}, {}, {}, {}); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; +} + +TEST(ResilientPreparedModelTest, getUnderlyingResource) { + // setup call + const auto [mockPreparedModel, mockPreparedModelFactory, preparedModel] = setup(); + EXPECT_CALL(*mockPreparedModel, getUnderlyingResource()) + .Times(1) + .WillOnce(Return(FakeResource{})); + + // run test + const auto resource = preparedModel->getUnderlyingResource(); + + // verify resource + const FakeResource* maybeFakeResource = std::any_cast(&resource); + EXPECT_NE(maybeFakeResource, nullptr); +} + +TEST(ResilientPreparedModelTest, recover) { + // setup call + const auto [mockPreparedModel, mockPreparedModelFactory, preparedModel] = setup(); + const auto recoveredMockPreparedModel = createConfiguredMockPreparedModel(); + EXPECT_CALL(*mockPreparedModelFactory, Call()) + .Times(1) + .WillOnce(Return(recoveredMockPreparedModel)); + + // run test + const auto result = preparedModel->recover(mockPreparedModel.get()); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; + EXPECT_TRUE(result.value() == recoveredMockPreparedModel); +} + +TEST(ResilientPreparedModelTest, recoverFailure) { + // setup call + const auto [mockPreparedModel, mockPreparedModelFactory, preparedModel] = setup(); + const auto recoveredMockPreparedModel = createConfiguredMockPreparedModel(); + EXPECT_CALL(*mockPreparedModelFactory, Call()).Times(1).WillOnce(kReturnGeneralFailure); + + // run test + const auto result = preparedModel->recover(mockPreparedModel.get()); + + // verify result + EXPECT_FALSE(result.has_value()); +} + +TEST(ResilientPreparedModelTest, someoneElseRecovered) { + // setup call + const auto [mockPreparedModel, mockPreparedModelFactory, preparedModel] = setup(); + const auto recoveredMockPreparedModel = createConfiguredMockPreparedModel(); + EXPECT_CALL(*mockPreparedModelFactory, Call()) + .Times(1) + .WillOnce(Return(recoveredMockPreparedModel)); + preparedModel->recover(mockPreparedModel.get()); + + // run test + const auto result = preparedModel->recover(mockPreparedModel.get()); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; + EXPECT_TRUE(result.value() == recoveredMockPreparedModel); +} + +} // namespace android::hardware::neuralnetworks::utils -- GitLab From b46c41f2fb6ae7de2e89f54cd2f1f76b9e806905 Mon Sep 17 00:00:00 2001 From: Yifan Hong Date: Wed, 6 Jan 2021 16:22:30 -0800 Subject: [PATCH 360/790] matrix: IVibratorManager AIDL has version 2. Test: builds Bug: 150034914 Change-Id: I62d800cb30f05a77e272d4e67afddfda09accd6e --- compatibility_matrices/compatibility_matrix.current.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index 9ff08096ba..0d524f71cb 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -559,6 +559,7 @@ android.hardware.vibrator + 1-2 IVibratorManager default -- GitLab From f2f8d85cd8144dcb22ce091847422df64b0924ee Mon Sep 17 00:00:00 2001 From: Yifan Hong Date: Wed, 6 Jan 2021 16:20:47 -0800 Subject: [PATCH 361/790] Update AIDL IVibratorManager manifest version to 2. Test: vts_treble_vintf_test Bug: 150034914 Change-Id: Idb9156a279b2aa942a7772e0e9150bb55aaa23d8 --- vibrator/aidl/default/vibrator-default.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/vibrator/aidl/default/vibrator-default.xml b/vibrator/aidl/default/vibrator-default.xml index 9f9cd40c4e..137a811bf9 100644 --- a/vibrator/aidl/default/vibrator-default.xml +++ b/vibrator/aidl/default/vibrator-default.xml @@ -5,6 +5,7 @@ android.hardware.vibrator + 2 IVibratorManager/default -- GitLab From 819e37237ac2b6e2fd76f1dba8a4cb97866b1f34 Mon Sep 17 00:00:00 2001 From: lesl Date: Thu, 7 Jan 2021 09:49:04 +0800 Subject: [PATCH 362/790] wifi: Fix removeIfaceInstanceFromBridgedApIfaceInternal Fix the incorrect empty check. Bug: 162686273 Test: Manual Test, shutdown instance works normally Change-Id: I44c5c4adcc7a964e25b5fa5e291bb9b9f4932655 --- wifi/1.5/default/wifi_chip.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wifi/1.5/default/wifi_chip.cpp b/wifi/1.5/default/wifi_chip.cpp index 6dd400c899..a37fee22a4 100644 --- a/wifi/1.5/default/wifi_chip.cpp +++ b/wifi/1.5/default/wifi_chip.cpp @@ -1031,7 +1031,7 @@ WifiStatus WifiChip::removeIfaceInstanceFromBridgedApIfaceInternal( const std::string& ifname, const std::string& ifInstanceName) { legacy_hal::wifi_error legacy_status; const auto iface = findUsingName(ap_ifaces_, ifname); - if (!iface.get() || !ifInstanceName.empty()) { + if (!iface.get() || ifInstanceName.empty()) { return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); } // Requires to remove one of the instance in bridge mode -- GitLab From 6d42d0474555f62b5169f1e7e8d997a57ad79771 Mon Sep 17 00:00:00 2001 From: Daniel Bright Date: Mon, 28 Dec 2020 15:51:23 -0800 Subject: [PATCH 363/790] Partial hal support for secondary link bandwidth * Added modemReducedFeatureSet1 flag to HalDeviceCapabilities * Applied flag to secondary link bandwidth getters in carrier bandwidth Test: cts Bug: 173806995 Change-Id: Icfca599607e02a6c3e258c11dc9eb7701b7afd3f --- radio/config/1.3/types.hal | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/radio/config/1.3/types.hal b/radio/config/1.3/types.hal index bedb70922e..ba964bfda9 100644 --- a/radio/config/1.3/types.hal +++ b/radio/config/1.3/types.hal @@ -19,4 +19,10 @@ package android.hardware.radio.config@1.3; /** * Contains the device capabilities with respect to the Radio HAL. */ -struct HalDeviceCapabilities {}; +struct HalDeviceCapabilities { + /** + * True indicates that the modem is missing features within the current + * version of the Radio HAL. + */ + bool modemReducedFeatureSet1; +}; -- GitLab From 8dae6e7b72ee00e71ce26ea2d760bd8e75be3fad Mon Sep 17 00:00:00 2001 From: Eric Jeong Date: Thu, 3 Dec 2020 16:39:53 -0800 Subject: [PATCH 364/790] Implement power policy change listener in AudioControl HAL Bug: 173719953 Test: manual test Change-Id: Id773bd2bb1c8becc8f3e9e69e23ed8034dd36937 --- .../audiocontrol/aidl/default/Android.bp | 5 +- .../aidl/default/PowerPolicyClient.cpp | 69 +++++++++++++++++++ .../aidl/default/PowerPolicyClient.h | 45 ++++++++++++ automotive/audiocontrol/aidl/default/main.cpp | 8 ++- 4 files changed, 125 insertions(+), 2 deletions(-) create mode 100644 automotive/audiocontrol/aidl/default/PowerPolicyClient.cpp create mode 100644 automotive/audiocontrol/aidl/default/PowerPolicyClient.h diff --git a/automotive/audiocontrol/aidl/default/Android.bp b/automotive/audiocontrol/aidl/default/Android.bp index faf7ad2485..427709abb3 100644 --- a/automotive/audiocontrol/aidl/default/Android.bp +++ b/automotive/audiocontrol/aidl/default/Android.bp @@ -22,15 +22,18 @@ cc_binary { generated_sources: ["audio_policy_configuration_V7_0"], header_libs: ["libxsdc-utils"], shared_libs: [ + "android.frameworks.automotive.powerpolicy-ndk_platform", "android.hardware.automotive.audiocontrol-ndk_platform", "libbase", "libbinder_ndk", - "liblog", "libcutils", + "liblog", + "libpowerpolicyclient", "libxml2", ], srcs: [ "AudioControl.cpp", "main.cpp", + "PowerPolicyClient.cpp", ], } diff --git a/automotive/audiocontrol/aidl/default/PowerPolicyClient.cpp b/automotive/audiocontrol/aidl/default/PowerPolicyClient.cpp new file mode 100644 index 0000000000..765733716b --- /dev/null +++ b/automotive/audiocontrol/aidl/default/PowerPolicyClient.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "PowerPolicyClient.h" +#include "AudioControl.h" + +#include + +namespace aidl { +namespace android { +namespace hardware { +namespace automotive { +namespace audiocontrol { + +namespace aafap = aidl::android::frameworks::automotive::powerpolicy; + +using aafap::CarPowerPolicy; +using aafap::CarPowerPolicyFilter; +using aafap::PowerComponent; +using ::android::frameworks::automotive::powerpolicy::hasComponent; +using ::ndk::ScopedAStatus; + +namespace { + +constexpr PowerComponent kAudioComponent = PowerComponent::AUDIO; + +} // namespace + +PowerPolicyClient::PowerPolicyClient(std::shared_ptr audioControl) + : mAudioControl(audioControl) {} + +void PowerPolicyClient::onInitFailed() { + LOG(ERROR) << "Initializing power policy client failed"; +} + +std::vector PowerPolicyClient::getComponentsOfInterest() { + std::vector components{kAudioComponent}; + return components; +} + +ScopedAStatus PowerPolicyClient::onPolicyChanged(const CarPowerPolicy& powerPolicy) { + if (hasComponent(powerPolicy.enabledComponents, kAudioComponent)) { + LOG(DEBUG) << "Power policy: Audio component is enabled"; + // TODO(b/173719953): Do something when AUDIO is enabled. + } else if (hasComponent(powerPolicy.disabledComponents, kAudioComponent)) { + LOG(DEBUG) << "Power policy: Audio component is disabled"; + // TODO(b/173719953): Do something when AUDIO is disabled. + } + return ScopedAStatus::ok(); +} + +} // namespace audiocontrol +} // namespace automotive +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/automotive/audiocontrol/aidl/default/PowerPolicyClient.h b/automotive/audiocontrol/aidl/default/PowerPolicyClient.h new file mode 100644 index 0000000000..0b4d5b6c0a --- /dev/null +++ b/automotive/audiocontrol/aidl/default/PowerPolicyClient.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AUTOMOTIVE_AUDIOCONTROL_AIDL_DEFAULT_POWERPOLICYCLIENT_H_ +#define AUTOMOTIVE_AUDIOCONTROL_AIDL_DEFAULT_POWERPOLICYCLIENT_H_ + +#include "PowerPolicyClientBase.h" + +#include + +namespace aidl::android::hardware::automotive::audiocontrol { + +class AudioControl; + +class PowerPolicyClient + : public ::android::frameworks::automotive::powerpolicy::PowerPolicyClientBase { + public: + explicit PowerPolicyClient(std::shared_ptr audioControl); + + void onInitFailed(); + std::vector<::aidl::android::frameworks::automotive::powerpolicy::PowerComponent> + getComponentsOfInterest() override; + ::ndk::ScopedAStatus onPolicyChanged( + const ::aidl::android::frameworks::automotive::powerpolicy::CarPowerPolicy&) override; + + private: + std::shared_ptr mAudioControl; +}; + +} // namespace aidl::android::hardware::automotive::audiocontrol + +#endif // AUTOMOTIVE_AUDIOCONTROL_AIDL_DEFAULT_POWERPOLICYCLIENT_H_ diff --git a/automotive/audiocontrol/aidl/default/main.cpp b/automotive/audiocontrol/aidl/default/main.cpp index 996665fe5c..9b259fca0a 100644 --- a/automotive/audiocontrol/aidl/default/main.cpp +++ b/automotive/audiocontrol/aidl/default/main.cpp @@ -15,22 +15,28 @@ */ #include "AudioControl.h" +#include "PowerPolicyClient.h" #include #include #include using aidl::android::hardware::automotive::audiocontrol::AudioControl; +using aidl::android::hardware::automotive::audiocontrol::PowerPolicyClient; int main() { ABinderProcess_setThreadPoolMaxThreadCount(0); - std::shared_ptr audioControl = ndk::SharedRefBase::make(); + std::shared_ptr audioControl = ::ndk::SharedRefBase::make(); const std::string instance = std::string() + AudioControl::descriptor + "/default"; binder_status_t status = AServiceManager_addService(audioControl->asBinder().get(), instance.c_str()); CHECK(status == STATUS_OK); + std::shared_ptr powerPolicyClient = + ::ndk::SharedRefBase::make(audioControl); + powerPolicyClient->init(); + ABinderProcess_joinThreadPool(); return EXIT_FAILURE; // should not reach } -- GitLab From 0d203ba5692b7a120c767fc1bc295e71b7bc07ea Mon Sep 17 00:00:00 2001 From: Joe Huang Date: Mon, 7 Dec 2020 23:57:48 +0800 Subject: [PATCH 365/790] Add Satellite PVT AIDL HAL Bug: 171537015 Test: atest VtsHalGnssTargetTest Change-Id: Icc1f915801d8d3f15757c43abe19f8c264347e22 --- .../hardware/gnss/GnssMeasurement.aidl | 15 +++--- .../android/hardware/gnss/IGnssCallback.aidl | 14 +++--- .../hardware/gnss/SatelliteClockInfo.aidl | 25 ++++++++++ .../hardware/gnss/SatellitePositionEcef.aidl | 26 ++++++++++ .../android/hardware/gnss/SatellitePvt.aidl | 27 ++++++++++ .../hardware/gnss/SatelliteVelocityEcef.aidl | 26 ++++++++++ .../hardware/gnss/GnssMeasurement.aidl | 13 +++++ .../android/hardware/gnss/IGnssCallback.aidl | 3 ++ .../hardware/gnss/SatelliteClockInfo.aidl | 39 +++++++++++++++ .../hardware/gnss/SatellitePositionEcef.aidl | 39 +++++++++++++++ .../android/hardware/gnss/SatellitePvt.aidl | 49 +++++++++++++++++++ .../hardware/gnss/SatelliteVelocityEcef.aidl | 40 +++++++++++++++ gnss/aidl/default/Gnss.cpp | 3 +- gnss/aidl/vts/gnss_hal_test_cases.cpp | 25 +++++++++- gnss/common/utils/default/Utils.cpp | 18 +++++-- 15 files changed, 345 insertions(+), 17 deletions(-) create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatelliteClockInfo.aidl create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatellitePositionEcef.aidl create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatellitePvt.aidl create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatelliteVelocityEcef.aidl create mode 100644 gnss/aidl/android/hardware/gnss/SatelliteClockInfo.aidl create mode 100644 gnss/aidl/android/hardware/gnss/SatellitePositionEcef.aidl create mode 100644 gnss/aidl/android/hardware/gnss/SatellitePvt.aidl create mode 100644 gnss/aidl/android/hardware/gnss/SatelliteVelocityEcef.aidl diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMeasurement.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMeasurement.aidl index 73d8a86187..7328f7ed40 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMeasurement.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMeasurement.aidl @@ -2,13 +2,14 @@ // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped @@ -42,6 +43,7 @@ parcelable GnssMeasurement { double fullInterSignalBiasUncertaintyNs; double satelliteInterSignalBiasNs; double satelliteInterSignalBiasUncertaintyNs; + android.hardware.gnss.SatellitePvt satellitePvt; const int HAS_SNR = 1; const int HAS_CARRIER_FREQUENCY = 512; const int HAS_CARRIER_CYCLES = 1024; @@ -52,6 +54,7 @@ parcelable GnssMeasurement { const int HAS_FULL_ISB_UNCERTAINTY = 131072; const int HAS_SATELLITE_ISB = 262144; const int HAS_SATELLITE_ISB_UNCERTAINTY = 524288; + const int HAS_SATELLITE_PVT = 1048576; const int STATE_UNKNOWN = 0; const int STATE_CODE_LOCK = 1; const int STATE_BIT_SYNC = 2; diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl index 62870d6871..bf6d3c13a3 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl @@ -2,13 +2,14 @@ // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped @@ -20,4 +21,5 @@ package android.hardware.gnss; interface IGnssCallback { void gnssSetCapabilitiesCb(in int capabilities); const int CAPABILITY_SATELLITE_BLOCKLIST = 1; + const int CAPABILITY_SATELLITE_PVT = 8192; } diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatelliteClockInfo.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatelliteClockInfo.aidl new file mode 100644 index 0000000000..bdba6673ea --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatelliteClockInfo.aidl @@ -0,0 +1,25 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.gnss; +@VintfStability +parcelable SatelliteClockInfo { + double satHardwareCodeBiasMeters; + double satTimeCorrectionMeters; + double satClkDriftMps; +} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatellitePositionEcef.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatellitePositionEcef.aidl new file mode 100644 index 0000000000..550fa4dbe9 --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatellitePositionEcef.aidl @@ -0,0 +1,26 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.gnss; +@VintfStability +parcelable SatellitePositionEcef { + double posXMeters; + double posYMeters; + double posZMeters; + double ureMeters; +} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatellitePvt.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatellitePvt.aidl new file mode 100644 index 0000000000..4ff025eff8 --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatellitePvt.aidl @@ -0,0 +1,27 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.gnss; +@VintfStability +parcelable SatellitePvt { + android.hardware.gnss.SatellitePositionEcef satPosEcef; + android.hardware.gnss.SatelliteVelocityEcef satVelEcef; + android.hardware.gnss.SatelliteClockInfo satClockInfo; + double ionoDelayMeters; + double tropoDelayMeters; +} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatelliteVelocityEcef.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatelliteVelocityEcef.aidl new file mode 100644 index 0000000000..7db7ee6b5d --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatelliteVelocityEcef.aidl @@ -0,0 +1,26 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.gnss; +@VintfStability +parcelable SatelliteVelocityEcef { + double velXMps; + double velYMps; + double velZMps; + double ureRateMps; +} diff --git a/gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl b/gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl index ce88647162..09897fb18e 100644 --- a/gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl +++ b/gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl @@ -18,6 +18,7 @@ package android.hardware.gnss; import android.hardware.gnss.GnssSignalType; import android.hardware.gnss.GnssMultipathIndicator; +import android.hardware.gnss.SatellitePvt; /** * Represents a GNSS Measurement, it contains raw and computed information. @@ -57,6 +58,10 @@ parcelable GnssMeasurement { * GnssMeasurement. */ const int HAS_SATELLITE_ISB_UNCERTAINTY = 1 << 19; + /** + * Bit mask indicating a valid satellite PVT is stored in the GnssMeasurement. + */ + const int HAS_SATELLITE_PVT = 1 << 20; /** * A bitfield of flags indicating the validity of the fields in this GnssMeasurement. The bit @@ -612,4 +617,12 @@ parcelable GnssMeasurement { * 1-sigma uncertainty associated with the satellite inter-signal bias in nanoseconds. */ double satelliteInterSignalBiasUncertaintyNs; + + /** + * The GNSS satellite position, velocity and time information at the signal transmission time + * receivedSvTimeInNs. + * + * If the data is available, gnssMeasurementFlags must contain HAS_SATELLITE_PVT. + */ + SatellitePvt satellitePvt; } \ No newline at end of file diff --git a/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl b/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl index a46a018141..1ea6faad0b 100644 --- a/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl +++ b/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl @@ -30,6 +30,9 @@ interface IGnssCallback { /** Capability bit mask indicating GNSS supports blocklisting satellites */ const int CAPABILITY_SATELLITE_BLOCKLIST = 1 << 0; + /** Capability bit mask indicating that GNSS supports satellite PVT */ + const int CAPABILITY_SATELLITE_PVT = 1 << 13; + /** * Callback to inform framework of the GNSS HAL implementation's capabilities. * diff --git a/gnss/aidl/android/hardware/gnss/SatelliteClockInfo.aidl b/gnss/aidl/android/hardware/gnss/SatelliteClockInfo.aidl new file mode 100644 index 0000000000..844fd1c47d --- /dev/null +++ b/gnss/aidl/android/hardware/gnss/SatelliteClockInfo.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.gnss; + +/** + * Contains estimates of the satellite clock info. + */ +@VintfStability +parcelable SatelliteClockInfo { + /** + * Satellite hardware code bias of the reported code type w.r.t + * ionosphere-free measurement in meters. + */ + double satHardwareCodeBiasMeters; + + /** + * Satellite time correction for ionospheric-free signal measurement + * (meters). The satellite clock correction for the given signal type + * = satTimeCorrectionMeters - satHardwareCodeBiasMeters. + */ + double satTimeCorrectionMeters; + + /** Satellite clock drift (meters per second). */ + double satClkDriftMps; +} \ No newline at end of file diff --git a/gnss/aidl/android/hardware/gnss/SatellitePositionEcef.aidl b/gnss/aidl/android/hardware/gnss/SatellitePositionEcef.aidl new file mode 100644 index 0000000000..4b3615e29a --- /dev/null +++ b/gnss/aidl/android/hardware/gnss/SatellitePositionEcef.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.gnss; + +/** + * Contains estimates of the satellite position fields in ECEF coordinate frame. + */ +@VintfStability +parcelable SatellitePositionEcef { + /** Satellite position X in WGS84 ECEF (meters). */ + double posXMeters; + + /** Satellite position Y in WGS84 ECEF (meters). */ + double posYMeters; + + /** Satellite position Z in WGS84 ECEF (meters). */ + double posZMeters; + + /** + * The Signal in Space User Range Error (URE) (meters). + * + * It covers satellite position and clock errors projected to the pseudorange measurements. + */ + double ureMeters; +} \ No newline at end of file diff --git a/gnss/aidl/android/hardware/gnss/SatellitePvt.aidl b/gnss/aidl/android/hardware/gnss/SatellitePvt.aidl new file mode 100644 index 0000000000..ea55f0c257 --- /dev/null +++ b/gnss/aidl/android/hardware/gnss/SatellitePvt.aidl @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.gnss; + +import android.hardware.gnss.SatellitePositionEcef; +import android.hardware.gnss.SatelliteVelocityEcef; +import android.hardware.gnss.SatelliteClockInfo; + +/** + * Contains estimates of the satellite position, velocity and time in the + * ECEF coordinate frame. + */ +@VintfStability +parcelable SatellitePvt { + /** + * Satellite position in WGS84 ECEF. See comments of + * SatellitePositionEcef for units. + */ + SatellitePositionEcef satPosEcef; + + /** + * Satellite velocity in WGS84 ECEF. See comments of + * SatelliteVelocityEcef for units. + */ + SatelliteVelocityEcef satVelEcef; + + /** Satellite clock bias and drift info. */ + SatelliteClockInfo satClockInfo; + + /** Ionospheric delay in meters. */ + double ionoDelayMeters; + + /** Tropospheric delay in meters. */ + double tropoDelayMeters; +} \ No newline at end of file diff --git a/gnss/aidl/android/hardware/gnss/SatelliteVelocityEcef.aidl b/gnss/aidl/android/hardware/gnss/SatelliteVelocityEcef.aidl new file mode 100644 index 0000000000..25ece3a3a7 --- /dev/null +++ b/gnss/aidl/android/hardware/gnss/SatelliteVelocityEcef.aidl @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.gnss; + +/** + * Contains estimates of the satellite velocity fields in the ECEF coordinate frame. + */ +@VintfStability +parcelable SatelliteVelocityEcef { + /** Satellite velocity X in WGS84 ECEF (meters per second). */ + double velXMps; + + /** Satellite velocity Y in WGS84 ECEF (meters per second). */ + double velYMps; + + /** Satellite velocity Z in WGS84 ECEF (meters per second). */ + double velZMps; + + /** + * The Signal in Space User Range Error Rate (URE Rate) (meters per second). + * + * It covers satellite velocity error and Satellite clock drift + * projected to the pseudorange rate measurements. + */ + double ureRateMps; +} \ No newline at end of file diff --git a/gnss/aidl/default/Gnss.cpp b/gnss/aidl/default/Gnss.cpp index 02bad6031d..661f3511b1 100644 --- a/gnss/aidl/default/Gnss.cpp +++ b/gnss/aidl/default/Gnss.cpp @@ -36,7 +36,8 @@ ndk::ScopedAStatus Gnss::setCallback(const std::shared_ptr& callb sGnssCallback = callback; - int capabilities = (int)IGnssCallback::CAPABILITY_SATELLITE_BLOCKLIST; + int capabilities = (int)(IGnssCallback::CAPABILITY_SATELLITE_BLOCKLIST | + IGnssCallback::CAPABILITY_SATELLITE_PVT); auto status = sGnssCallback->gnssSetCapabilitiesCb(capabilities); if (!status.isOk()) { ALOGE("%s: Unable to invoke callback.gnssSetCapabilities", __func__); diff --git a/gnss/aidl/vts/gnss_hal_test_cases.cpp b/gnss/aidl/vts/gnss_hal_test_cases.cpp index 857c74208b..18fda45f60 100644 --- a/gnss/aidl/vts/gnss_hal_test_cases.cpp +++ b/gnss/aidl/vts/gnss_hal_test_cases.cpp @@ -70,6 +70,7 @@ TEST_P(GnssHalTest, TestPsdsExtension) { */ TEST_P(GnssHalTest, TestGnssMeasurementExtension) { const int kFirstGnssMeasurementTimeoutSeconds = 10; + bool has_capability_satpvt = false; sp iGnssMeasurement; auto status = aidl_gnss_hal_->getExtensionGnssMeasurement(&iGnssMeasurement); ASSERT_TRUE(status.isOk()); @@ -102,6 +103,10 @@ TEST_P(GnssHalTest, TestGnssMeasurementExtension) { GnssClock::HAS_FULL_BIAS | GnssClock::HAS_BIAS | GnssClock::HAS_BIAS_UNCERTAINTY | GnssClock::HAS_DRIFT | GnssClock::HAS_DRIFT_UNCERTAINTY)); + + if (aidl_gnss_cb_->last_capabilities_ & (int)GnssCallbackAidl::CAPABILITY_SATELLITE_PVT) { + has_capability_satpvt = true; + } for (const auto& measurement : lastMeasurement.measurements) { ASSERT_TRUE( measurement.flags >= 0 && @@ -112,7 +117,25 @@ TEST_P(GnssHalTest, TestGnssMeasurementExtension) { GnssMeasurement::HAS_AUTOMATIC_GAIN_CONTROL | GnssMeasurement::HAS_FULL_ISB | GnssMeasurement::HAS_FULL_ISB_UNCERTAINTY | GnssMeasurement::HAS_SATELLITE_ISB | - GnssMeasurement::HAS_SATELLITE_ISB_UNCERTAINTY)); + GnssMeasurement::HAS_SATELLITE_ISB_UNCERTAINTY | + GnssMeasurement::HAS_SATELLITE_PVT)); + if ((measurement.flags & GnssMeasurement::HAS_SATELLITE_PVT) && + (has_capability_satpvt == true)) { + ASSERT_TRUE(measurement.satellitePvt.satPosEcef.posXMeters >= -43000000 && + measurement.satellitePvt.satPosEcef.posXMeters <= 43000000); + ASSERT_TRUE(measurement.satellitePvt.satPosEcef.posYMeters >= -43000000 && + measurement.satellitePvt.satPosEcef.posYMeters <= 43000000); + ASSERT_TRUE(measurement.satellitePvt.satPosEcef.posZMeters >= -43000000 && + measurement.satellitePvt.satPosEcef.posZMeters <= 43000000); + ASSERT_TRUE(measurement.satellitePvt.satPosEcef.ureMeters > 0); + ASSERT_TRUE(measurement.satellitePvt.satVelEcef.velXMps >= -4000 && + measurement.satellitePvt.satVelEcef.velXMps <= 4000); + ASSERT_TRUE(measurement.satellitePvt.satVelEcef.velYMps >= -4000 && + measurement.satellitePvt.satVelEcef.velYMps <= 4000); + ASSERT_TRUE(measurement.satellitePvt.satVelEcef.velZMps >= -4000 && + measurement.satellitePvt.satVelEcef.velZMps <= 4000); + ASSERT_TRUE(measurement.satellitePvt.satVelEcef.ureRateMps > 0); + } } status = iGnssMeasurement->close(); diff --git a/gnss/common/utils/default/Utils.cpp b/gnss/common/utils/default/Utils.cpp index 21282f443d..1079fa5c24 100644 --- a/gnss/common/utils/default/Utils.cpp +++ b/gnss/common/utils/default/Utils.cpp @@ -152,10 +152,10 @@ GnssData Utils::getMockMeasurement() { GnssMeasurement::HAS_CARRIER_PHASE_UNCERTAINTY | GnssMeasurement::HAS_FULL_ISB | GnssMeasurement::HAS_FULL_ISB_UNCERTAINTY | GnssMeasurement::HAS_SATELLITE_ISB | - GnssMeasurement::HAS_SATELLITE_ISB_UNCERTAINTY, + GnssMeasurement::HAS_SATELLITE_ISB_UNCERTAINTY | + GnssMeasurement::HAS_SATELLITE_PVT, .svid = 13, .signalType = signalType, - .timeOffsetNs = 0.0, .receivedSvTimeInNs = 8195997131077, .receivedSvTimeUncertaintyInNs = 15, .antennaCN0DbHz = 30.0, @@ -175,7 +175,19 @@ GnssData Utils::getMockMeasurement() { .fullInterSignalBiasUncertaintyNs = 792.0, .satelliteInterSignalBiasNs = 233.9, .satelliteInterSignalBiasUncertaintyNs = 921.2, - }; + .satellitePvt = {.satPosEcef = {.posXMeters = 10442993.1153328, + .posYMeters = -19926932.8051666, + .posZMeters = -12034295.0216203, + .ureMeters = 1000.2345678}, + .satVelEcef = {.velXMps = -478.667183715732, + .velYMps = 1580.68371984114, + .velZMps = -3030.52994449997, + .ureRateMps = 10.2345678}, + .satClockInfo = {.satHardwareCodeBiasMeters = 1.396983861923e-09, + .satTimeCorrectionMeters = -7113.08964331, + .satClkDriftMps = 0}, + .ionoDelayMeters = 3.069949602639317e-08, + .tropoDelayMeters = 3.882265204404031}}; GnssClock clock = {.gnssClockFlags = GnssClock::HAS_FULL_BIAS | GnssClock::HAS_FULL_BIAS | GnssClock::HAS_BIAS_UNCERTAINTY | GnssClock::HAS_DRIFT | -- GitLab From f012b65dc081b409cbc33c55f2c50103d0dee75b Mon Sep 17 00:00:00 2001 From: lesl Date: Fri, 8 Jan 2021 15:22:49 +0800 Subject: [PATCH 366/790] wifi: fix incorrect active wlan iface in bridged mode The hal use first active wlan iface to get chip info. It should should return active wlan instance in bridged mode. Bug: 162686273 Test: Manual test. 1. Wifi Off (SAA off), make sure bridged AP is first wlan iface 2. Enable bridged mode Change-Id: Id5a3d5ab53c6ed34d5633be22ad56070f5f0d0e2 --- wifi/1.5/default/wifi_chip.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/wifi/1.5/default/wifi_chip.cpp b/wifi/1.5/default/wifi_chip.cpp index a37fee22a4..80a48f5e7b 100644 --- a/wifi/1.5/default/wifi_chip.cpp +++ b/wifi/1.5/default/wifi_chip.cpp @@ -1795,7 +1795,16 @@ bool WifiChip::isDualStaConcurrencyAllowedInCurrentMode() { std::string WifiChip::getFirstActiveWlanIfaceName() { if (sta_ifaces_.size() > 0) return sta_ifaces_[0]->getName(); - if (ap_ifaces_.size() > 0) return ap_ifaces_[0]->getName(); + if (ap_ifaces_.size() > 0) { + // If the first active wlan iface is bridged iface. + // Return first instance name. + for (auto const& it : br_ifaces_ap_instances_) { + if (it.first == ap_ifaces_[0]->getName()) { + return it.second[0]; + } + } + return ap_ifaces_[0]->getName(); + } // This could happen if the chip call is made before any STA/AP // iface is created. Default to wlan0 for such cases. LOG(WARNING) << "No active wlan interfaces in use! Using default"; -- GitLab From 9a484da68566a324eb10f68ed62587365f44e6aa Mon Sep 17 00:00:00 2001 From: Daniel Bright Date: Fri, 8 Jan 2021 14:47:17 -0800 Subject: [PATCH 367/790] Added javadoc to apn retry \ throttling related methods Bug: 175092152 Test: N/A Change-Id: I84c7845343a08d725764cf4a5777f720b8f6d0da --- radio/1.6/types.hal | 3 +++ 1 file changed, 3 insertions(+) diff --git a/radio/1.6/types.hal b/radio/1.6/types.hal index 550e079885..01fdc62bd7 100644 --- a/radio/1.6/types.hal +++ b/radio/1.6/types.hal @@ -280,6 +280,9 @@ struct SetupDataCallResult { * retry back-off time in milliseconds. Negative value indicates network does not give any * suggestion. 0 indicates retry should be performed immediately. 0x7fffffffffffffff indicates * the device should not retry data setup anymore. + * + * During this time, no calls to IRadio@1.6::SetupDataCall for this APN will be made unless + * IRadioIndication@1.6::unthrottleApn is sent with the same APN. */ uint64_t suggestedRetryTime; -- GitLab From 8eab4f33901d036feaef772eb750b525016637d3 Mon Sep 17 00:00:00 2001 From: Yifan Hong Date: Fri, 8 Jan 2021 17:03:35 -0800 Subject: [PATCH 368/790] Reland "matrix: IVibrator AIDL has version 2." This is reverted in AOSP because vibrator 2 has not been published in AOSP, but relanded in internal because vibrator 2 is in internal. This reverts commit 6135189a2925bf5e5d7222a410777672edb14432. Test: TH Bug: 150034914 Change-Id: I94a663be8a07a24587127d3ca489647a16c0be7a --- compatibility_matrices/compatibility_matrix.current.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index 609d78d933..2f672661d6 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -553,6 +553,7 @@ android.hardware.vibrator + 1-2 IVibrator default -- GitLab From 31a72d0328f7b654d4b533cbde84ef0c79843258 Mon Sep 17 00:00:00 2001 From: Yifan Hong Date: Fri, 8 Jan 2021 17:04:32 -0800 Subject: [PATCH 369/790] Reland "Update AIDL IVibrator manifest version to 2." This is reverted in AOSP because vibrator 2 has not been published in AOSP, but relanded in internal because vibrator 2 is in internal. This reverts commit 9e8fe956f65cc8824d22e415246ca22c768c0c31. Test: TH Bug: 150034914 Change-Id: I3c40be3f9ba7806455bf5b7e8142e11c581ddb73 --- vibrator/aidl/default/vibrator-default.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/vibrator/aidl/default/vibrator-default.xml b/vibrator/aidl/default/vibrator-default.xml index 137a811bf9..b5bd3ddd1e 100644 --- a/vibrator/aidl/default/vibrator-default.xml +++ b/vibrator/aidl/default/vibrator-default.xml @@ -1,6 +1,7 @@ android.hardware.vibrator + 2 IVibrator/default -- GitLab From 3000a60c2abd3d1e4f64e6c141d6759eaa7c7931 Mon Sep 17 00:00:00 2001 From: Quang Luong Date: Sun, 10 Jan 2021 18:14:35 -0800 Subject: [PATCH 370/790] Fix 1.5::WifiBand inheritance 1.5::WifiBand should inherit from 1.4::WifiBand. Bug: 15365100 Test: build Change-Id: Ic22cbed19fee274bbaadf282b0a492857bd3dcc5 --- wifi/1.5/types.hal | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wifi/1.5/types.hal b/wifi/1.5/types.hal index 3fbec82658..9fa5c800c0 100644 --- a/wifi/1.5/types.hal +++ b/wifi/1.5/types.hal @@ -19,7 +19,7 @@ package android.hardware.wifi@1.5; import @1.0::StaLinkLayerIfaceStats; import @1.0::StaLinkLayerIfacePacketStats; import @1.0::TimeStampInMs; -import @1.0::WifiBand; +import @1.4::WifiBand; import @1.0::NanCipherSuiteType; import @1.0::NanCapabilities; import @1.2::NanConfigRequestSupplemental; @@ -28,7 +28,7 @@ import @1.3::StaLinkLayerRadioStats; /** * Wifi bands defined in 80211 spec. */ -enum WifiBand : @1.0::WifiBand { +enum WifiBand : @1.4::WifiBand { /** * 60 GHz. */ -- GitLab From deb46ec7b2877e9d54aebb1dc3b578b02b00d3c3 Mon Sep 17 00:00:00 2001 From: Vince Leung Date: Tue, 22 Dec 2020 00:03:16 +0000 Subject: [PATCH 371/790] vibrator: aidl: add primitive LOW_TICK Bug: 174561580 Change-Id: I48d034c92f2405d09073344405f8038fdefaf294 --- .../android/hardware/vibrator/CompositePrimitive.aidl | 1 + .../aidl/android/hardware/vibrator/CompositePrimitive.aidl | 7 +++++++ vibrator/aidl/default/Vibrator.cpp | 1 + 3 files changed, 9 insertions(+) diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/CompositePrimitive.aidl b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/CompositePrimitive.aidl index 6ab7ac5b20..3071dce32b 100644 --- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/CompositePrimitive.aidl +++ b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/CompositePrimitive.aidl @@ -26,4 +26,5 @@ enum CompositePrimitive { SLOW_RISE = 5, QUICK_FALL = 6, LIGHT_TICK = 7, + LOW_TICK = 8, } diff --git a/vibrator/aidl/android/hardware/vibrator/CompositePrimitive.aidl b/vibrator/aidl/android/hardware/vibrator/CompositePrimitive.aidl index 8e82db076b..531489824b 100644 --- a/vibrator/aidl/android/hardware/vibrator/CompositePrimitive.aidl +++ b/vibrator/aidl/android/hardware/vibrator/CompositePrimitive.aidl @@ -70,4 +70,11 @@ enum CompositePrimitive { * Support is required. */ LIGHT_TICK, + /** + * This very short low frequency effect should produce a light crisp sensation intended + * to be used repetitively for dynamic feedback. + * + * Support is required. + */ + LOW_TICK, } diff --git a/vibrator/aidl/default/Vibrator.cpp b/vibrator/aidl/default/Vibrator.cpp index c446afdea8..1021e620ce 100644 --- a/vibrator/aidl/default/Vibrator.cpp +++ b/vibrator/aidl/default/Vibrator.cpp @@ -119,6 +119,7 @@ ndk::ScopedAStatus Vibrator::getSupportedPrimitives(std::vector Date: Mon, 30 Nov 2020 14:35:33 -0800 Subject: [PATCH 372/790] Adds vehicle properties for for Cluster2. - CLUSTER_SWITCH_UI - CLUSTER_DISPLAY_STATE - CLUSTER_REPORT_STATE - CLUSTER_REQUEST_DISPLAY - CLUSTER_NAVIGATION_STATE_LEGACY Bug: 173454429 Test: it builds Change-Id: I0298cf35d83a02fe69ebfef9de1583aa3c598af1 --- .../default/impl/vhal_v2_0/DefaultConfig.h | 41 +++++++ automotive/vehicle/2.0/types.hal | 109 ++++++++++++++++++ 2 files changed, 150 insertions(+) diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h index 8ef2b6018a..73513f4e4c 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h @@ -1153,6 +1153,47 @@ const ConfigDeclaration kVehicleProperties[]{ .changeMode = VehiclePropertyChangeMode::ON_CHANGE, }, }, + { + .config = + { + .prop = toInt(VehicleProperty::CLUSTER_SWITCH_UI), + .access = VehiclePropertyAccess::READ, + .changeMode = VehiclePropertyChangeMode::ON_CHANGE, + }, + }, + { + .config = + { + .prop = toInt(VehicleProperty::CLUSTER_DISPLAY_STATE), + .access = VehiclePropertyAccess::READ, + .changeMode = VehiclePropertyChangeMode::ON_CHANGE, + }, + }, + { + .config = + { + .prop = toInt(VehicleProperty::CLUSTER_REPORT_STATE), + .access = VehiclePropertyAccess::WRITE, + .changeMode = VehiclePropertyChangeMode::ON_CHANGE, + .configArray = {0, 0, 0, 9, 0, 0, 0, 0, 16}, + }, + }, + { + .config = + { + .prop = toInt(VehicleProperty::CLUSTER_REQUEST_DISPLAY), + .access = VehiclePropertyAccess::WRITE, + .changeMode = VehiclePropertyChangeMode::ON_CHANGE, + }, + }, + { + .config = + { + .prop = toInt(VehicleProperty::CLUSTER_NAVIGATION_STATE_LEGACY), + .access = VehiclePropertyAccess::WRITE, + .changeMode = VehiclePropertyChangeMode::ON_CHANGE, + }, + }, }; } // impl diff --git a/automotive/vehicle/2.0/types.hal b/automotive/vehicle/2.0/types.hal index 0488b57196..3c1ecc6c9d 100644 --- a/automotive/vehicle/2.0/types.hal +++ b/automotive/vehicle/2.0/types.hal @@ -3027,6 +3027,115 @@ enum VehicleProperty : int32_t { | VehiclePropertyGroup:SYSTEM | VehiclePropertyType:INT64 | VehicleArea:GLOBAL), + + /** + * Starts the ClusterUI in cluster display. + * + * int32[0]: the type of ClusterUI to show + * 0 indicates ClusterHome, that is a home screen of cluster display, and provides + * the default UI and a kind of launcher functionality for cluster display. + * the other values are followed by OEM's definition. + * + * @change_mode VehiclePropertyChangeMode:ON_CHANGE + * @access VehiclePropertyAccess:READ + */ + CLUSTER_SWITCH_UI = ( + 0x0F34 + | VehiclePropertyGroup:SYSTEM + | VehiclePropertyType:INT32 + | VehicleArea:GLOBAL), + + /** + * Changes the state of the cluster display. + * + * int32[0]: on/off: 0 - off, 1 - on, -1 - don't care + * int32[1]: width: positive number - actual width in pixels + -1 - don't care (should set "don't care" both width and height) + * int32[2]: height: ditto with width + * int32[3]: Inset - left: positive number - actual left inset value in pixels + -1 - don't care (should set "don't care" all Inset fields) + * int32[4]: Inset - top + * int32[5]: Inset - right + * int32[6]: Inset - bottom + * + * @change_mode VehiclePropertyChangeMode:ON_CHANGE + * @access VehiclePropertyAccess:READ + */ + CLUSTER_DISPLAY_STATE = ( + 0x0F35 + | VehiclePropertyGroup:SYSTEM + | VehiclePropertyType:INT32_VEC + | VehicleArea:GLOBAL), + + /** + * Reports the current display state and ClusterUI state. + * + * ClusterHome will send this message when it handles CLUSTER_SWITCH_UI, CLUSTER_DISPLAY_STATE. + * + * In addition, ClusterHome should send this message when it starts for the first time. + * When ClusterOS receives this message and if the internal expectation is different with the + * received message, then it should send CLUSTER_SWITCH_UI, CLUSTER_DISPLAY_STATE again to + * match the state. + * + * int32[0]: on/off: 0 - off, 1 - on + * int32[1]: width + * int32[2]: height + * int32[3]: Inset - left + * int32[4]: Inset - top + * int32[5]: Inset - right + * int32[6]: Inset - bottom + * int32[7]: the type of ClusterUI in the fullscreen or main screen. + * 0 indicates ClusterHome. + * the other values are followed by OEM's definition. + * int32[8]: the type of ClusterUI in sub screen if the currently two UIs are shown. + * -1 indicates the area isn't used any more. + * bytes: the array to represent the availability of ClusterUI. + * 0 indicates non-available and 1 indicates available. + * For example, let's assume a car supports 3 UI like HOME, MAPS, CALL and it only supports + * CALL UI only when the cellular network is available. Then, if the nework is avaibale, + * it'll send [1 1 1], and if it's out of network, it'll send [1 1 0]. + * + * @change_mode VehiclePropertyChangeMode:ON_CHANGE + * @access VehiclePropertyAccess:WRITE + */ + CLUSTER_REPORT_STATE = ( + 0x0F36 + | VehiclePropertyGroup:SYSTEM + | VehiclePropertyType:MIXED + | VehicleArea:GLOBAL), + + /** + * Requests to change the cluster display state to show some ClusterUI. + * + * When the current display state is off and ClusterHome sends this message to ClusterOS to + * request to turn the display on to show some specific ClusterUI. + * ClusterOS should response this with CLUSTER_DISPLAY_STATE. + * + * int32[0]: the type of ClusterUI to show + * + * @change_mode VehiclePropertyChangeMode:ON_CHANGE + * @access VehiclePropertyAccess:WRITE + */ + CLUSTER_REQUEST_DISPLAY = ( + 0x0F37 + | VehiclePropertyGroup:SYSTEM + | VehiclePropertyType:INT32 + | VehicleArea:GLOBAL), + + /** + * Informs the current navigation state. + * + * bytes: the serialized message of NavigationStateProto. + * + * @change_mode VehiclePropertyChangeMode:ON_CHANGE + * @access VehiclePropertyAccess:WRITE + */ + CLUSTER_NAVIGATION_STATE_LEGACY = ( + 0x0F38 + | VehiclePropertyGroup:SYSTEM + | VehiclePropertyType:BYTES + | VehicleArea:GLOBAL), + }; /** -- GitLab From 600160285345c0c207d6924d8a1c7d6ed1b5345e Mon Sep 17 00:00:00 2001 From: Anthony Stange Date: Mon, 11 Jan 2021 15:53:30 -0500 Subject: [PATCH 373/790] Update Contexthub HAL 1.0 doc format The HAL 1.0 docs are using the incorrect format for HALs. Update them to match what is now used in 1.1/1.2. Fixes: 177248013 Test: presubmits Change-Id: If5bdac0cec9e271ba6b79ecc10f4b3a93aff040c --- contexthub/1.0/IContexthub.hal | 20 ++++++++++---------- contexthub/1.0/IContexthubCallback.hal | 25 ++++++++++++------------- current.txt | 2 ++ 3 files changed, 24 insertions(+), 23 deletions(-) diff --git a/contexthub/1.0/IContexthub.hal b/contexthub/1.0/IContexthub.hal index 8dccd67276..950e081326 100644 --- a/contexthub/1.0/IContexthub.hal +++ b/contexthub/1.0/IContexthub.hal @@ -41,7 +41,7 @@ interface IContexthub { * registration. * * @param hubId identifier for the hub - * callback an implementation of the IContextHubCallbacks + * @param callback an implementation of the IContextHubCallbacks * * @return result OK on success * BAD_VALUE if parameters are not sane @@ -53,7 +53,7 @@ interface IContexthub { * Send a message to a hub * * @param hubId identifier for hub to send message to - * msg message to be sent + * @param msg message to be sent * * @return result OK if successful, error code otherwise * BAD_VALUE if parameters are not sane @@ -77,9 +77,9 @@ interface IContexthub { * device. * * @param hubId identifer of the contextHub - * appBinary contains the binary representation of the nanoApp, plus + * @param appBinary contains the binary representation of the nanoApp, plus * metadata - * transactionId transactionId for this call + * @param transactionId transactionId for this call * * @return result OK if transation started * BAD_VALUE if parameters are not sane @@ -101,8 +101,8 @@ interface IContexthub { * Unloading a nanoapp must not take more than 5 seconds. * * @param hubId identifer of the contextHub - * appId appIdentifier returned by the HAL - * msg message to be sent + * @param appId appIdentifier returned by the HAL + * @param msg message to be sent * * @return result OK if transation started * BAD_VALUE if parameters are not sane @@ -122,8 +122,8 @@ interface IContexthub { * Enabling a nanoapp must not take more than 5 seconds. * * @param hubId identifer of the contextHub - * appId appIdentifier returned by the HAL - * msg message to be sent + * @param appId appIdentifier returned by the HAL + * @param msg message to be sent * * @return result OK if transation started * BAD_VALUE if parameters are not sane @@ -143,8 +143,8 @@ interface IContexthub { * Disabling a nanoapp must not take more than 5 seconds. * * @param hubId identifer of the contextHub - * appId appIdentifier returned by the HAL - * msg message to be sent + * @param appId appIdentifier returned by the HAL + * @param msg message to be sent * * @return result OK if transation started * BAD_VALUE if parameters are not sane diff --git a/contexthub/1.0/IContexthubCallback.hal b/contexthub/1.0/IContexthubCallback.hal index 264f84ca17..70750f808b 100644 --- a/contexthub/1.0/IContexthubCallback.hal +++ b/contexthub/1.0/IContexthubCallback.hal @@ -22,7 +22,7 @@ interface IContexthubCallback { * implementation to allow the HAL to send asynchronous messages back * to the service and registered clients of the ContextHub service. * - * @params msg : message + * @param msg message being sent from the contexthub * */ handleClientMsg(ContextHubMsg msg); @@ -32,9 +32,9 @@ interface IContexthubCallback { * implementation to allow the HAL to send the response for a * transaction. * - * @params txnId : transaction id whose result is being sent - * passed in by the service at start of transacation. - * result: result of transaction. + * @param txnId transaction id whose result is being sent + * passed in by the service at start of transacation. + * @param result result of transaction. * */ handleTxnResult(uint32_t txnId, TransactionResult result); @@ -44,7 +44,7 @@ interface IContexthubCallback { * implementation to allow the HAL to send an asynchronous event * to the ContextHub service. * - * @params msg : message + * @param evt event being sent from the contexthub * */ handleHubEvent(AsyncEventType evt); @@ -55,8 +55,8 @@ interface IContexthubCallback { * that a nanp-app has aborted. * This method must be called when a nanoapp invokes chreAbort(...)). * - * @params appId : app identifier - * : abortCode code passed by the nanoApp. + * @param appId app identifier + * @param abortCode code passed by the nanoApp. * * Also see chreAbort(...) * @@ -68,12 +68,11 @@ interface IContexthubCallback { * implementation to allow the HAL to send information about the * currently loaded and active nanoapps on the hub. * - * @params appInfo : vector of HubAppinfo structure for each nanoApp - * on the hub that can be enabled, disabled and - * unloaded by the service. Any nanoApps that cannot - * be controlled by the service must not be reported. - * All nanoApps that can be controlled by the service - * must be reported. + * @param appInfo vector of HubAppinfo structure for each nanoApp on the + * hub that can be enabled, disabled and unloaded by the + * service. Any nanoApps that cannot be controlled by the + * service must not be reported. All nanoApps that can be + * controlled by the service must be reported. */ handleAppsInfo(vec appInfo); }; diff --git a/current.txt b/current.txt index 0b88a7a835..bf6829a353 100644 --- a/current.txt +++ b/current.txt @@ -767,6 +767,8 @@ a64467bae843569f0d465c5be7f0c7a5b987985b55a3ef4794dd5afc68538650 android.hardwar 98592d193a717066facf91428426e5abe211e3bd718bc372e29fb944ddbe6e7c android.hardware.wifi.supplicant@1.3::types # ABI preserving changes to HALs during Android S +e042522daa4b5f7fd4a0a19bcdadb93c79a1b04c09ef2c9813a3a8941032f3f5 android.hardware.contexthub@1.0::IContexthub +c2f64133b83ede65c9939ef97ab5bd867b73faf3dba0e7e69f77c3c43d9e487e android.hardware.contexthub@1.0::IContexthubCallback 1ca372cd67d197df099e87616a613ba6ede6552638a603e18f86c8834302c3d1 android.hardware.gnss@1.0::IGnssMeasurementCallback 6a271e493907e8ba20912e42771bd0d99ae45431a851d5675ef9496d02510a34 android.hardware.gnss@1.1::IGnssMeasurementCallback 2c331a9605f3a08d9c1e0a36169ca57758bc43c11a78ef3f3730509885e52c15 android.hardware.graphics.composer@2.4::IComposerClient -- GitLab From 8964b85a6a14bf5208251554b5f14940fb65df13 Mon Sep 17 00:00:00 2001 From: Henry Fang Date: Fri, 8 Jan 2021 16:09:08 -0800 Subject: [PATCH 374/790] make descrambler test optional since it may be provided through tuner module since cas@1.2 bug: 176799453 Test: Manual Change-Id: Iffbd76723c53ba0d94ccfcbd8c22beb1d8173fad --- cas/1.0/vts/functional/Android.bp | 2 + .../functional/VtsHalCasV1_0TargetTest.cpp | 360 +++++++++--------- cas/1.1/vts/functional/Android.bp | 1 + .../functional/VtsHalCasV1_1TargetTest.cpp | 65 ++-- .../functional/VtsHalCasV1_2TargetTest.cpp | 57 +-- 5 files changed, 256 insertions(+), 229 deletions(-) diff --git a/cas/1.0/vts/functional/Android.bp b/cas/1.0/vts/functional/Android.bp index 82dc568fa6..a065b85906 100644 --- a/cas/1.0/vts/functional/Android.bp +++ b/cas/1.0/vts/functional/Android.bp @@ -20,6 +20,8 @@ cc_test { srcs: ["VtsHalCasV1_0TargetTest.cpp"], static_libs: [ "android.hardware.cas@1.0", + "android.hardware.cas@1.1", + "android.hardware.cas@1.2", "android.hardware.cas.native@1.0", "android.hidl.allocator@1.0", "android.hidl.memory@1.0", diff --git a/cas/1.0/vts/functional/VtsHalCasV1_0TargetTest.cpp b/cas/1.0/vts/functional/VtsHalCasV1_0TargetTest.cpp index 7f5d98888a..df0c85934f 100644 --- a/cas/1.0/vts/functional/VtsHalCasV1_0TargetTest.cpp +++ b/cas/1.0/vts/functional/VtsHalCasV1_0TargetTest.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -212,6 +213,10 @@ void MediaCasListener::testEventEcho(sp& mediaCas, int32_t& event, int32_t class MediaCasHidlTest : public testing::TestWithParam { public: virtual void SetUp() override { + if (android::hardware::cas::V1_2::IMediaCasService::getService(GetParam()) == nullptr) { + ALOGI("Descrambler is need to be tested before cas@1.2."); + mIsTestDescrambler = true; + } mService = IMediaCasService::getService(GetParam()); ASSERT_NE(mService, nullptr); } @@ -226,6 +231,7 @@ class MediaCasHidlTest : public testing::TestWithParam { sp mMediaCas; sp mDescramblerBase; sp mCasListener; + bool mIsTestDescrambler = false; typedef struct _OobInputTestParams { const SubSample* subSamples; uint32_t numSubSamples; @@ -270,8 +276,14 @@ class MediaCasHidlTest : public testing::TestWithParam { auto descramblerStatus = mService->createDescrambler(caSystemId); if (!descramblerStatus.isOk()) { - return ::testing::AssertionFailure(); + if (mIsTestDescrambler) { + return ::testing::AssertionFailure(); + } else { + ALOGI("Skip Descrambler test since it's not required in cas@1.2."); + return ::testing::AssertionSuccess(); + } } + mIsTestDescrambler = true; mDescramblerBase = descramblerStatus; return ::testing::AssertionResult(mDescramblerBase != nullptr); } @@ -494,14 +506,15 @@ TEST_P(MediaCasHidlTest, TestClearKeyApis) { returnStatus = mMediaCas->setSessionPrivateData(streamSessionId, hidlPvtData); EXPECT_TRUE(returnStatus.isOk()); EXPECT_EQ(Status::OK, returnStatus); - - returnStatus = mDescramblerBase->setMediaCasSession(sessionId); - EXPECT_TRUE(returnStatus.isOk()); - EXPECT_EQ(Status::OK, returnStatus); - - returnStatus = mDescramblerBase->setMediaCasSession(streamSessionId); - EXPECT_TRUE(returnStatus.isOk()); - EXPECT_EQ(Status::OK, returnStatus); + if (mIsTestDescrambler) { + returnStatus = mDescramblerBase->setMediaCasSession(sessionId); + EXPECT_TRUE(returnStatus.isOk()); + EXPECT_EQ(Status::OK, returnStatus); + + returnStatus = mDescramblerBase->setMediaCasSession(streamSessionId); + EXPECT_TRUE(returnStatus.isOk()); + EXPECT_EQ(Status::OK, returnStatus); + } hidl_vec hidlNullPtr; hidlNullPtr.setToExternal(static_cast(nullptr), 0); @@ -543,29 +556,32 @@ TEST_P(MediaCasHidlTest, TestClearKeyApis) { EXPECT_TRUE(returnStatus.isOk()); EXPECT_EQ(Status::OK, returnStatus); - EXPECT_FALSE(mDescramblerBase->requiresSecureDecoderComponent("video/avc")); + if (mIsTestDescrambler) { + EXPECT_FALSE(mDescramblerBase->requiresSecureDecoderComponent("video/avc")); - sp descrambler; - descrambler = IDescrambler::castFrom(mDescramblerBase); - ASSERT_NE(descrambler, nullptr); + sp descrambler; + descrambler = IDescrambler::castFrom(mDescramblerBase); + ASSERT_NE(descrambler, nullptr); - Status descrambleStatus = Status::OK; - sp dataMemory; + Status descrambleStatus = Status::OK; + sp dataMemory; - ASSERT_TRUE(descrambleTestInputBuffer(descrambler, &descrambleStatus, &dataMemory)); - EXPECT_EQ(Status::OK, descrambleStatus); + ASSERT_TRUE(descrambleTestInputBuffer(descrambler, &descrambleStatus, &dataMemory)); + EXPECT_EQ(Status::OK, descrambleStatus); - ASSERT_NE(nullptr, dataMemory.get()); - uint8_t* opBuffer = static_cast(static_cast(dataMemory->unsecurePointer())); + ASSERT_NE(nullptr, dataMemory.get()); + uint8_t* opBuffer = + static_cast(static_cast(dataMemory->unsecurePointer())); - int compareResult = - memcmp(static_cast(opBuffer), static_cast(kOutRefBinaryBuffer), - sizeof(kOutRefBinaryBuffer)); - EXPECT_EQ(0, compareResult); + int compareResult = + memcmp(static_cast(opBuffer), + static_cast(kOutRefBinaryBuffer), sizeof(kOutRefBinaryBuffer)); + EXPECT_EQ(0, compareResult); - returnStatus = mDescramblerBase->release(); - EXPECT_TRUE(returnStatus.isOk()); - EXPECT_EQ(Status::OK, returnStatus); + returnStatus = mDescramblerBase->release(); + EXPECT_TRUE(returnStatus.isOk()); + EXPECT_EQ(Status::OK, returnStatus); + } returnStatus = mMediaCas->release(); EXPECT_TRUE(returnStatus.isOk()); @@ -590,13 +606,15 @@ TEST_P(MediaCasHidlTest, TestClearKeySessionClosedAfterRelease) { EXPECT_TRUE(returnStatus.isOk()); EXPECT_EQ(Status::OK, returnStatus); - returnStatus = mDescramblerBase->setMediaCasSession(sessionId); - EXPECT_TRUE(returnStatus.isOk()); - EXPECT_EQ(Status::ERROR_CAS_SESSION_NOT_OPENED, returnStatus); + if (mIsTestDescrambler) { + returnStatus = mDescramblerBase->setMediaCasSession(sessionId); + EXPECT_TRUE(returnStatus.isOk()); + EXPECT_EQ(Status::ERROR_CAS_SESSION_NOT_OPENED, returnStatus); - returnStatus = mDescramblerBase->setMediaCasSession(streamSessionId); - EXPECT_TRUE(returnStatus.isOk()); - EXPECT_EQ(Status::ERROR_CAS_SESSION_NOT_OPENED, returnStatus); + returnStatus = mDescramblerBase->setMediaCasSession(streamSessionId); + EXPECT_TRUE(returnStatus.isOk()); + EXPECT_EQ(Status::ERROR_CAS_SESSION_NOT_OPENED, returnStatus); + } } TEST_P(MediaCasHidlTest, TestClearKeyErrors) { @@ -654,38 +672,40 @@ TEST_P(MediaCasHidlTest, TestClearKeyErrors) { EXPECT_TRUE(returnStatus.isOk()); EXPECT_EQ(Status::ERROR_CAS_UNKNOWN, returnStatus); - /* - * Test MediaDescrambler error codes - */ - // setMediaCasSession should fail with an invalid session id - returnStatus = mDescramblerBase->setMediaCasSession(invalidSessionId); - EXPECT_TRUE(returnStatus.isOk()); - EXPECT_EQ(Status::ERROR_CAS_SESSION_NOT_OPENED, returnStatus); + if (mIsTestDescrambler) { + /* + * Test MediaDescrambler error codes + */ + // setMediaCasSession should fail with an invalid session id + returnStatus = mDescramblerBase->setMediaCasSession(invalidSessionId); + EXPECT_TRUE(returnStatus.isOk()); + EXPECT_EQ(Status::ERROR_CAS_SESSION_NOT_OPENED, returnStatus); - // descramble should fail without a valid session - sp descrambler; - descrambler = IDescrambler::castFrom(mDescramblerBase); - ASSERT_NE(descrambler, nullptr); + // descramble should fail without a valid session + sp descrambler; + descrambler = IDescrambler::castFrom(mDescramblerBase); + ASSERT_NE(descrambler, nullptr); - Status descrambleStatus = Status::OK; - sp dataMemory; + Status descrambleStatus = Status::OK; + sp dataMemory; - ASSERT_TRUE(descrambleTestInputBuffer(descrambler, &descrambleStatus, &dataMemory)); - EXPECT_EQ(Status::ERROR_CAS_DECRYPT_UNIT_NOT_INITIALIZED, descrambleStatus); + ASSERT_TRUE(descrambleTestInputBuffer(descrambler, &descrambleStatus, &dataMemory)); + EXPECT_EQ(Status::ERROR_CAS_DECRYPT_UNIT_NOT_INITIALIZED, descrambleStatus); - // Now set a valid session, should still fail because no valid ecm is processed - returnStatus = mDescramblerBase->setMediaCasSession(sessionId); - EXPECT_TRUE(returnStatus.isOk()); - EXPECT_EQ(Status::OK, returnStatus); + // Now set a valid session, should still fail because no valid ecm is processed + returnStatus = mDescramblerBase->setMediaCasSession(sessionId); + EXPECT_TRUE(returnStatus.isOk()); + EXPECT_EQ(Status::OK, returnStatus); - ASSERT_TRUE(descrambleTestInputBuffer(descrambler, &descrambleStatus, &dataMemory)); - EXPECT_EQ(Status::ERROR_CAS_DECRYPT, descrambleStatus); + ASSERT_TRUE(descrambleTestInputBuffer(descrambler, &descrambleStatus, &dataMemory)); + EXPECT_EQ(Status::ERROR_CAS_DECRYPT, descrambleStatus); - // Verify that requiresSecureDecoderComponent handles empty mime - EXPECT_FALSE(mDescramblerBase->requiresSecureDecoderComponent("")); + // Verify that requiresSecureDecoderComponent handles empty mime + EXPECT_FALSE(mDescramblerBase->requiresSecureDecoderComponent("")); - // Verify that requiresSecureDecoderComponent handles invalid mime - EXPECT_FALSE(mDescramblerBase->requiresSecureDecoderComponent("bad")); + // Verify that requiresSecureDecoderComponent handles invalid mime + EXPECT_FALSE(mDescramblerBase->requiresSecureDecoderComponent("bad")); + } } TEST_P(MediaCasHidlTest, TestClearKeyOobFails) { @@ -700,9 +720,11 @@ TEST_P(MediaCasHidlTest, TestClearKeyOobFails) { std::vector sessionId; ASSERT_TRUE(openCasSession(&sessionId)); - returnStatus = mDescramblerBase->setMediaCasSession(sessionId); - EXPECT_TRUE(returnStatus.isOk()); - EXPECT_EQ(Status::OK, returnStatus); + if (mIsTestDescrambler) { + returnStatus = mDescramblerBase->setMediaCasSession(sessionId); + EXPECT_TRUE(returnStatus.isOk()); + EXPECT_EQ(Status::OK, returnStatus); + } hidl_vec hidlEcm; hidlEcm.setToExternal(const_cast(kEcmBinaryBuffer), sizeof(kEcmBinaryBuffer)); @@ -710,126 +732,104 @@ TEST_P(MediaCasHidlTest, TestClearKeyOobFails) { EXPECT_TRUE(returnStatus.isOk()); EXPECT_EQ(Status::OK, returnStatus); - sp descrambler = IDescrambler::castFrom(mDescramblerBase); - ASSERT_NE(nullptr, descrambler.get()); - - Status descrambleStatus = Status::OK; - - // test invalid src buffer offset - ASSERT_TRUE(descrambleTestOobInput( - descrambler, - &descrambleStatus, - { - .subSamples = kSubSamples, - .numSubSamples = sizeof(kSubSamples)/sizeof(SubSample), - .imemSizeActual = sizeof(kInBinaryBuffer), - .imemOffset = 0xcccccc, - .imemSize = sizeof(kInBinaryBuffer), - .srcOffset = 0, - .dstOffset = 0 - })); - EXPECT_EQ(Status::BAD_VALUE, descrambleStatus); - - // test invalid src buffer size - ASSERT_TRUE(descrambleTestOobInput( - descrambler, - &descrambleStatus, - { - .subSamples = kSubSamples, - .numSubSamples = sizeof(kSubSamples)/sizeof(SubSample), - .imemSizeActual = sizeof(kInBinaryBuffer), - .imemOffset = 0, - .imemSize = 0xcccccc, - .srcOffset = 0, - .dstOffset = 0 - })); - EXPECT_EQ(Status::BAD_VALUE, descrambleStatus); - - // test invalid src buffer size - ASSERT_TRUE(descrambleTestOobInput( - descrambler, - &descrambleStatus, - { - .subSamples = kSubSamples, - .numSubSamples = sizeof(kSubSamples)/sizeof(SubSample), - .imemSizeActual = sizeof(kInBinaryBuffer), - .imemOffset = 1, - .imemSize = (uint64_t)-1, - .srcOffset = 0, - .dstOffset = 0 - })); - EXPECT_EQ(Status::BAD_VALUE, descrambleStatus); - - // test invalid srcOffset - ASSERT_TRUE(descrambleTestOobInput( - descrambler, - &descrambleStatus, - { - .subSamples = kSubSamples, - .numSubSamples = sizeof(kSubSamples)/sizeof(SubSample), - .imemSizeActual = sizeof(kInBinaryBuffer), - .imemOffset = 0, - .imemSize = sizeof(kInBinaryBuffer), - .srcOffset = 0xcccccc, - .dstOffset = 0 - })); - EXPECT_EQ(Status::BAD_VALUE, descrambleStatus); - - // test invalid dstOffset - ASSERT_TRUE(descrambleTestOobInput( - descrambler, - &descrambleStatus, - { - .subSamples = kSubSamples, - .numSubSamples = sizeof(kSubSamples)/sizeof(SubSample), - .imemSizeActual = sizeof(kInBinaryBuffer), - .imemOffset = 0, - .imemSize = sizeof(kInBinaryBuffer), - .srcOffset = 0, - .dstOffset = 0xcccccc - })); - EXPECT_EQ(Status::BAD_VALUE, descrambleStatus); - - // test detection of oob subsample sizes - const SubSample invalidSubSamples1[] = - {{162, 0}, {0, 184}, {0, 0xdddddd}}; - - ASSERT_TRUE(descrambleTestOobInput( - descrambler, - &descrambleStatus, - { - .subSamples = invalidSubSamples1, - .numSubSamples = sizeof(invalidSubSamples1)/sizeof(SubSample), - .imemSizeActual = sizeof(kInBinaryBuffer), - .imemOffset = 0, - .imemSize = sizeof(kInBinaryBuffer), - .srcOffset = 0, - .dstOffset = 0 - })); - EXPECT_EQ(Status::BAD_VALUE, descrambleStatus); - - // test detection of overflowing subsample sizes - const SubSample invalidSubSamples2[] = - {{162, 0}, {0, 184}, {2, (uint32_t)-1}}; - - ASSERT_TRUE(descrambleTestOobInput( - descrambler, - &descrambleStatus, - { - .subSamples = invalidSubSamples2, - .numSubSamples = sizeof(invalidSubSamples2)/sizeof(SubSample), - .imemSizeActual = sizeof(kInBinaryBuffer), - .imemOffset = 0, - .imemSize = sizeof(kInBinaryBuffer), - .srcOffset = 0, - .dstOffset = 0 - })); - EXPECT_EQ(Status::BAD_VALUE, descrambleStatus); - - returnStatus = mDescramblerBase->release(); - EXPECT_TRUE(returnStatus.isOk()); - EXPECT_EQ(Status::OK, returnStatus); - + if (mIsTestDescrambler) { + sp descrambler = IDescrambler::castFrom(mDescramblerBase); + ASSERT_NE(nullptr, descrambler.get()); + + Status descrambleStatus = Status::OK; + + // test invalid src buffer offset + ASSERT_TRUE( + descrambleTestOobInput(descrambler, &descrambleStatus, + {.subSamples = kSubSamples, + .numSubSamples = sizeof(kSubSamples) / sizeof(SubSample), + .imemSizeActual = sizeof(kInBinaryBuffer), + .imemOffset = 0xcccccc, + .imemSize = sizeof(kInBinaryBuffer), + .srcOffset = 0, + .dstOffset = 0})); + EXPECT_EQ(Status::BAD_VALUE, descrambleStatus); + + // test invalid src buffer size + ASSERT_TRUE( + descrambleTestOobInput(descrambler, &descrambleStatus, + {.subSamples = kSubSamples, + .numSubSamples = sizeof(kSubSamples) / sizeof(SubSample), + .imemSizeActual = sizeof(kInBinaryBuffer), + .imemOffset = 0, + .imemSize = 0xcccccc, + .srcOffset = 0, + .dstOffset = 0})); + EXPECT_EQ(Status::BAD_VALUE, descrambleStatus); + + // test invalid src buffer size + ASSERT_TRUE( + descrambleTestOobInput(descrambler, &descrambleStatus, + {.subSamples = kSubSamples, + .numSubSamples = sizeof(kSubSamples) / sizeof(SubSample), + .imemSizeActual = sizeof(kInBinaryBuffer), + .imemOffset = 1, + .imemSize = (uint64_t)-1, + .srcOffset = 0, + .dstOffset = 0})); + EXPECT_EQ(Status::BAD_VALUE, descrambleStatus); + + // test invalid srcOffset + ASSERT_TRUE( + descrambleTestOobInput(descrambler, &descrambleStatus, + {.subSamples = kSubSamples, + .numSubSamples = sizeof(kSubSamples) / sizeof(SubSample), + .imemSizeActual = sizeof(kInBinaryBuffer), + .imemOffset = 0, + .imemSize = sizeof(kInBinaryBuffer), + .srcOffset = 0xcccccc, + .dstOffset = 0})); + EXPECT_EQ(Status::BAD_VALUE, descrambleStatus); + + // test invalid dstOffset + ASSERT_TRUE( + descrambleTestOobInput(descrambler, &descrambleStatus, + {.subSamples = kSubSamples, + .numSubSamples = sizeof(kSubSamples) / sizeof(SubSample), + .imemSizeActual = sizeof(kInBinaryBuffer), + .imemOffset = 0, + .imemSize = sizeof(kInBinaryBuffer), + .srcOffset = 0, + .dstOffset = 0xcccccc})); + EXPECT_EQ(Status::BAD_VALUE, descrambleStatus); + + // test detection of oob subsample sizes + const SubSample invalidSubSamples1[] = {{162, 0}, {0, 184}, {0, 0xdddddd}}; + + ASSERT_TRUE(descrambleTestOobInput( + descrambler, &descrambleStatus, + {.subSamples = invalidSubSamples1, + .numSubSamples = sizeof(invalidSubSamples1) / sizeof(SubSample), + .imemSizeActual = sizeof(kInBinaryBuffer), + .imemOffset = 0, + .imemSize = sizeof(kInBinaryBuffer), + .srcOffset = 0, + .dstOffset = 0})); + EXPECT_EQ(Status::BAD_VALUE, descrambleStatus); + + // test detection of overflowing subsample sizes + const SubSample invalidSubSamples2[] = {{162, 0}, {0, 184}, {2, (uint32_t)-1}}; + + ASSERT_TRUE(descrambleTestOobInput( + descrambler, &descrambleStatus, + {.subSamples = invalidSubSamples2, + .numSubSamples = sizeof(invalidSubSamples2) / sizeof(SubSample), + .imemSizeActual = sizeof(kInBinaryBuffer), + .imemOffset = 0, + .imemSize = sizeof(kInBinaryBuffer), + .srcOffset = 0, + .dstOffset = 0})); + EXPECT_EQ(Status::BAD_VALUE, descrambleStatus); + + returnStatus = mDescramblerBase->release(); + EXPECT_TRUE(returnStatus.isOk()); + EXPECT_EQ(Status::OK, returnStatus); + } returnStatus = mMediaCas->release(); EXPECT_TRUE(returnStatus.isOk()); EXPECT_EQ(Status::OK, returnStatus); diff --git a/cas/1.1/vts/functional/Android.bp b/cas/1.1/vts/functional/Android.bp index de223c8ce2..0647d12a1c 100644 --- a/cas/1.1/vts/functional/Android.bp +++ b/cas/1.1/vts/functional/Android.bp @@ -21,6 +21,7 @@ cc_test { static_libs: [ "android.hardware.cas@1.0", "android.hardware.cas@1.1", + "android.hardware.cas@1.2", "android.hardware.cas.native@1.0", "android.hidl.allocator@1.0", "android.hidl.memory@1.0", diff --git a/cas/1.1/vts/functional/VtsHalCasV1_1TargetTest.cpp b/cas/1.1/vts/functional/VtsHalCasV1_1TargetTest.cpp index b657f07c1a..6797506642 100644 --- a/cas/1.1/vts/functional/VtsHalCasV1_1TargetTest.cpp +++ b/cas/1.1/vts/functional/VtsHalCasV1_1TargetTest.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -255,6 +256,10 @@ void MediaCasListener::testSessionEventEcho(sp& mediaCas, const hidl_vec { public: virtual void SetUp() override { + if (android::hardware::cas::V1_2::IMediaCasService::getService(GetParam()) == nullptr) { + ALOGI("Descrambler is need to be tested before cas@1.2."); + mIsTestDescrambler = true; + } mService = IMediaCasService::getService(GetParam()); ASSERT_NE(mService, nullptr); } @@ -269,6 +274,7 @@ class MediaCasHidlTest : public testing::TestWithParam { sp mMediaCas; sp mDescramblerBase; sp mCasListener; + bool mIsTestDescrambler = false; typedef struct _OobInputTestParams { const SubSample* subSamples; uint32_t numSubSamples; @@ -311,8 +317,15 @@ class MediaCasHidlTest : public testing::TestWithParam { auto descramblerStatus = mService->createDescrambler(caSystemId); if (!descramblerStatus.isOk()) { - return ::testing::AssertionFailure(); + if (mIsTestDescrambler) { + return ::testing::AssertionFailure(); + } else { + ALOGI("Skip Descrambler test since it's not required in cas@1.2."); + return ::testing::AssertionSuccess(); + } } + mIsTestDescrambler = true; + mDescramblerBase = descramblerStatus; return ::testing::AssertionResult(mDescramblerBase != nullptr); } @@ -468,13 +481,15 @@ TEST_P(MediaCasHidlTest, TestClearKeyApisWithSession) { EXPECT_TRUE(returnStatus.isOk()); EXPECT_EQ(Status::OK, returnStatus); - returnStatus = mDescramblerBase->setMediaCasSession(sessionId); - EXPECT_TRUE(returnStatus.isOk()); - EXPECT_EQ(Status::OK, returnStatus); + if (mIsTestDescrambler) { + returnStatus = mDescramblerBase->setMediaCasSession(sessionId); + EXPECT_TRUE(returnStatus.isOk()); + EXPECT_EQ(Status::OK, returnStatus); - returnStatus = mDescramblerBase->setMediaCasSession(streamSessionId); - EXPECT_TRUE(returnStatus.isOk()); - EXPECT_EQ(Status::OK, returnStatus); + returnStatus = mDescramblerBase->setMediaCasSession(streamSessionId); + EXPECT_TRUE(returnStatus.isOk()); + EXPECT_EQ(Status::OK, returnStatus); + } hidl_vec hidlNullPtr; hidlNullPtr.setToExternal(static_cast(nullptr), 0); @@ -518,29 +533,31 @@ TEST_P(MediaCasHidlTest, TestClearKeyApisWithSession) { EXPECT_TRUE(returnStatus.isOk()); EXPECT_EQ(Status::OK, returnStatus); - EXPECT_FALSE(mDescramblerBase->requiresSecureDecoderComponent("video/avc")); + if (mIsTestDescrambler) { + EXPECT_FALSE(mDescramblerBase->requiresSecureDecoderComponent("video/avc")); - sp descrambler; - descrambler = IDescrambler::castFrom(mDescramblerBase); - ASSERT_NE(descrambler, nullptr); + sp descrambler; + descrambler = IDescrambler::castFrom(mDescramblerBase); + ASSERT_NE(descrambler, nullptr); - Status descrambleStatus = Status::OK; - sp dataMemory; + Status descrambleStatus = Status::OK; + sp dataMemory; - ASSERT_TRUE(descrambleTestInputBuffer(descrambler, &descrambleStatus, &dataMemory)); - EXPECT_EQ(Status::OK, descrambleStatus); + ASSERT_TRUE(descrambleTestInputBuffer(descrambler, &descrambleStatus, &dataMemory)); + EXPECT_EQ(Status::OK, descrambleStatus); - ASSERT_NE(nullptr, dataMemory.get()); - uint8_t* opBuffer = static_cast(static_cast(dataMemory->unsecurePointer())); + ASSERT_NE(nullptr, dataMemory.get()); + uint8_t* opBuffer = static_cast(static_cast(dataMemory->unsecurePointer())); - int compareResult = - memcmp(static_cast(opBuffer), - static_cast(kOutRefBinaryBuffer), sizeof(kOutRefBinaryBuffer)); - EXPECT_EQ(0, compareResult); + int compareResult = + memcmp(static_cast(opBuffer), + static_cast(kOutRefBinaryBuffer), sizeof(kOutRefBinaryBuffer)); + EXPECT_EQ(0, compareResult); - returnStatus = mDescramblerBase->release(); - EXPECT_TRUE(returnStatus.isOk()); - EXPECT_EQ(Status::OK, returnStatus); + returnStatus = mDescramblerBase->release(); + EXPECT_TRUE(returnStatus.isOk()); + EXPECT_EQ(Status::OK, returnStatus); + } returnStatus = mMediaCas->release(); EXPECT_TRUE(returnStatus.isOk()); diff --git a/cas/1.2/vts/functional/VtsHalCasV1_2TargetTest.cpp b/cas/1.2/vts/functional/VtsHalCasV1_2TargetTest.cpp index f436b8b5ee..333dea61db 100644 --- a/cas/1.2/vts/functional/VtsHalCasV1_2TargetTest.cpp +++ b/cas/1.2/vts/functional/VtsHalCasV1_2TargetTest.cpp @@ -311,6 +311,7 @@ class MediaCasHidlTest : public testing::TestWithParam { sp mMediaCas; sp mDescramblerBase; sp mCasListener; + bool mIsTestDescrambler = false; typedef struct _OobInputTestParams { const SubSample* subSamples; uint32_t numSubSamples; @@ -355,8 +356,11 @@ class MediaCasHidlTest : public testing::TestWithParam { auto descramblerStatus = mService->createDescrambler(caSystemId); if (!descramblerStatus.isOk()) { - return ::testing::AssertionFailure(); + ALOGI("Skip Descrambler test since it's not required in cas@1.2."); + return ::testing::AssertionSuccess(); } + mIsTestDescrambler = true; + mDescramblerBase = descramblerStatus; return ::testing::AssertionResult(mDescramblerBase != nullptr); } @@ -512,14 +516,15 @@ TEST_P(MediaCasHidlTest, TestClearKeyApisWithSession) { EXPECT_TRUE(returnStatus.isOk()); EXPECT_EQ(Status::OK, returnStatus); - returnStatus = mDescramblerBase->setMediaCasSession(sessionId); - EXPECT_TRUE(returnStatus.isOk()); - EXPECT_EQ(Status::OK, returnStatus); - - returnStatus = mDescramblerBase->setMediaCasSession(streamSessionId); - EXPECT_TRUE(returnStatus.isOk()); - EXPECT_EQ(Status::OK, returnStatus); + if (mIsTestDescrambler) { + returnStatus = mDescramblerBase->setMediaCasSession(sessionId); + EXPECT_TRUE(returnStatus.isOk()); + EXPECT_EQ(Status::OK, returnStatus); + returnStatus = mDescramblerBase->setMediaCasSession(streamSessionId); + EXPECT_TRUE(returnStatus.isOk()); + EXPECT_EQ(Status::OK, returnStatus); + } hidl_vec hidlNullPtr; hidlNullPtr.setToExternal(static_cast(nullptr), 0); returnStatus = mMediaCas->refreshEntitlements(3, hidlNullPtr); @@ -566,29 +571,31 @@ TEST_P(MediaCasHidlTest, TestClearKeyApisWithSession) { EXPECT_TRUE(returnStatus.isOk()); EXPECT_EQ(Status::OK, returnStatus); - EXPECT_FALSE(mDescramblerBase->requiresSecureDecoderComponent("video/avc")); + if (mIsTestDescrambler) { + EXPECT_FALSE(mDescramblerBase->requiresSecureDecoderComponent("video/avc")); - sp descrambler; - descrambler = IDescrambler::castFrom(mDescramblerBase); - ASSERT_NE(descrambler, nullptr); + sp descrambler; + descrambler = IDescrambler::castFrom(mDescramblerBase); + ASSERT_NE(descrambler, nullptr); - Status descrambleStatus = Status::OK; - sp dataMemory; + Status descrambleStatus = Status::OK; + sp dataMemory; - ASSERT_TRUE(descrambleTestInputBuffer(descrambler, &descrambleStatus, &dataMemory)); - EXPECT_EQ(Status::OK, descrambleStatus); + ASSERT_TRUE(descrambleTestInputBuffer(descrambler, &descrambleStatus, &dataMemory)); + EXPECT_EQ(Status::OK, descrambleStatus); - ASSERT_NE(nullptr, dataMemory.get()); - uint8_t* opBuffer = static_cast(static_cast(dataMemory->unsecurePointer())); + ASSERT_NE(nullptr, dataMemory.get()); + uint8_t* opBuffer = static_cast(static_cast(dataMemory->unsecurePointer())); - int compareResult = - memcmp(static_cast(opBuffer), - static_cast(kOutRefBinaryBuffer), sizeof(kOutRefBinaryBuffer)); - EXPECT_EQ(0, compareResult); + int compareResult = + memcmp(static_cast(opBuffer), + static_cast(kOutRefBinaryBuffer), sizeof(kOutRefBinaryBuffer)); + EXPECT_EQ(0, compareResult); - returnStatus = mDescramblerBase->release(); - EXPECT_TRUE(returnStatus.isOk()); - EXPECT_EQ(Status::OK, returnStatus); + returnStatus = mDescramblerBase->release(); + EXPECT_TRUE(returnStatus.isOk()); + EXPECT_EQ(Status::OK, returnStatus); + } returnStatus = mMediaCas->release(); EXPECT_TRUE(returnStatus.isOk()); -- GitLab From b6a7ed5d5fd45828643429fbfe015fe3a8054ef1 Mon Sep 17 00:00:00 2001 From: Michael Butler Date: Fri, 18 Dec 2020 20:31:14 -0800 Subject: [PATCH 375/790] Introduce canonical IBurst object in NNAPI -- hal A sibling change to this change introduces a canonical IBurst object and a new method IPreparedModel::configureExecutionBurst. This CL performs minimal changes to the NN hal utility code to make the code still compile. Bug: 177267324 Test: mma Change-Id: I076067289dde7def5622a6cb25233619f80efa41 --- .../1.0/utils/include/nnapi/hal/1.0/PreparedModel.h | 2 ++ neuralnetworks/1.0/utils/src/PreparedModel.cpp | 4 ++++ .../1.2/utils/include/nnapi/hal/1.2/PreparedModel.h | 2 ++ neuralnetworks/1.2/utils/src/PreparedModel.cpp | 4 ++++ .../1.3/utils/include/nnapi/hal/1.3/PreparedModel.h | 2 ++ neuralnetworks/1.3/utils/src/PreparedModel.cpp | 4 ++++ .../utils/common/include/nnapi/hal/InvalidPreparedModel.h | 2 ++ .../common/include/nnapi/hal/ResilientPreparedModel.h | 2 ++ neuralnetworks/utils/common/src/InvalidPreparedModel.cpp | 4 ++++ neuralnetworks/utils/common/src/ResilientPreparedModel.cpp | 7 +++++++ neuralnetworks/utils/common/test/MockPreparedModel.h | 1 + 11 files changed, 34 insertions(+) diff --git a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/PreparedModel.h b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/PreparedModel.h index 2de182871d..bda40c549b 100644 --- a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/PreparedModel.h +++ b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/PreparedModel.h @@ -56,6 +56,8 @@ class PreparedModel final : public nn::IPreparedModel { const nn::OptionalDuration& loopTimeoutDuration, const nn::OptionalDuration& timeoutDurationAfterFence) const override; + nn::GeneralResult configureExecutionBurst() const override; + std::any getUnderlyingResource() const override; private: diff --git a/neuralnetworks/1.0/utils/src/PreparedModel.cpp b/neuralnetworks/1.0/utils/src/PreparedModel.cpp index c0c22fbd6a..b8de131383 100644 --- a/neuralnetworks/1.0/utils/src/PreparedModel.cpp +++ b/neuralnetworks/1.0/utils/src/PreparedModel.cpp @@ -90,6 +90,10 @@ PreparedModel::executeFenced(const nn::Request& /*request*/, << "IPreparedModel::executeFenced is not supported on 1.0 HAL service"; } +nn::GeneralResult PreparedModel::configureExecutionBurst() const { + return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "Not yet implemented"; +} + std::any PreparedModel::getUnderlyingResource() const { sp resource = kPreparedModel; return resource; diff --git a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/PreparedModel.h b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/PreparedModel.h index 6a56a82f99..f43933309c 100644 --- a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/PreparedModel.h +++ b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/PreparedModel.h @@ -57,6 +57,8 @@ class PreparedModel final : public nn::IPreparedModel { const nn::OptionalDuration& loopTimeoutDuration, const nn::OptionalDuration& timeoutDurationAfterFence) const override; + nn::GeneralResult configureExecutionBurst() const override; + std::any getUnderlyingResource() const override; private: diff --git a/neuralnetworks/1.2/utils/src/PreparedModel.cpp b/neuralnetworks/1.2/utils/src/PreparedModel.cpp index 6d00082a5f..ad54c39282 100644 --- a/neuralnetworks/1.2/utils/src/PreparedModel.cpp +++ b/neuralnetworks/1.2/utils/src/PreparedModel.cpp @@ -117,6 +117,10 @@ PreparedModel::executeFenced(const nn::Request& /*request*/, << "IPreparedModel::executeFenced is not supported on 1.2 HAL service"; } +nn::GeneralResult PreparedModel::configureExecutionBurst() const { + return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "Not yet implemented"; +} + std::any PreparedModel::getUnderlyingResource() const { sp resource = kPreparedModel; return resource; diff --git a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/PreparedModel.h b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/PreparedModel.h index 664d87a7c2..63aa6faf79 100644 --- a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/PreparedModel.h +++ b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/PreparedModel.h @@ -56,6 +56,8 @@ class PreparedModel final : public nn::IPreparedModel { const nn::OptionalDuration& loopTimeoutDuration, const nn::OptionalDuration& timeoutDurationAfterFence) const override; + nn::GeneralResult configureExecutionBurst() const override; + std::any getUnderlyingResource() const override; private: diff --git a/neuralnetworks/1.3/utils/src/PreparedModel.cpp b/neuralnetworks/1.3/utils/src/PreparedModel.cpp index 7b4b7bac3b..7afa777868 100644 --- a/neuralnetworks/1.3/utils/src/PreparedModel.cpp +++ b/neuralnetworks/1.3/utils/src/PreparedModel.cpp @@ -197,6 +197,10 @@ PreparedModel::executeFenced(const nn::Request& request, const std::vector PreparedModel::configureExecutionBurst() const { + return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "Not yet implemented"; +} + std::any PreparedModel::getUnderlyingResource() const { sp resource = kPreparedModel; return resource; diff --git a/neuralnetworks/utils/common/include/nnapi/hal/InvalidPreparedModel.h b/neuralnetworks/utils/common/include/nnapi/hal/InvalidPreparedModel.h index 985cddb2c2..3e1dca7139 100644 --- a/neuralnetworks/utils/common/include/nnapi/hal/InvalidPreparedModel.h +++ b/neuralnetworks/utils/common/include/nnapi/hal/InvalidPreparedModel.h @@ -40,6 +40,8 @@ class InvalidPreparedModel final : public nn::IPreparedModel { const nn::OptionalDuration& loopTimeoutDuration, const nn::OptionalDuration& timeoutDurationAfterFence) const override; + nn::GeneralResult configureExecutionBurst() const override; + std::any getUnderlyingResource() const override; }; diff --git a/neuralnetworks/utils/common/include/nnapi/hal/ResilientPreparedModel.h b/neuralnetworks/utils/common/include/nnapi/hal/ResilientPreparedModel.h index 9b8d92435c..4014404aee 100644 --- a/neuralnetworks/utils/common/include/nnapi/hal/ResilientPreparedModel.h +++ b/neuralnetworks/utils/common/include/nnapi/hal/ResilientPreparedModel.h @@ -57,6 +57,8 @@ class ResilientPreparedModel final : public nn::IPreparedModel { const nn::OptionalDuration& loopTimeoutDuration, const nn::OptionalDuration& timeoutDurationAfterFence) const override; + nn::GeneralResult configureExecutionBurst() const override; + std::any getUnderlyingResource() const override; private: diff --git a/neuralnetworks/utils/common/src/InvalidPreparedModel.cpp b/neuralnetworks/utils/common/src/InvalidPreparedModel.cpp index a46f4ac574..9081e1fdd1 100644 --- a/neuralnetworks/utils/common/src/InvalidPreparedModel.cpp +++ b/neuralnetworks/utils/common/src/InvalidPreparedModel.cpp @@ -42,6 +42,10 @@ InvalidPreparedModel::executeFenced( return NN_ERROR() << "InvalidPreparedModel"; } +nn::GeneralResult InvalidPreparedModel::configureExecutionBurst() const { + return NN_ERROR() << "InvalidPreparedModel"; +} + std::any InvalidPreparedModel::getUnderlyingResource() const { return {}; } diff --git a/neuralnetworks/utils/common/src/ResilientPreparedModel.cpp b/neuralnetworks/utils/common/src/ResilientPreparedModel.cpp index 667df2b590..faba9965f2 100644 --- a/neuralnetworks/utils/common/src/ResilientPreparedModel.cpp +++ b/neuralnetworks/utils/common/src/ResilientPreparedModel.cpp @@ -124,6 +124,13 @@ ResilientPreparedModel::executeFenced(const nn::Request& request, return protect(*this, fn); } +nn::GeneralResult ResilientPreparedModel::configureExecutionBurst() const { + const auto fn = [](const nn::IPreparedModel& preparedModel) { + return preparedModel.configureExecutionBurst(); + }; + return protect(*this, fn); +} + std::any ResilientPreparedModel::getUnderlyingResource() const { return getPreparedModel()->getUnderlyingResource(); } diff --git a/neuralnetworks/utils/common/test/MockPreparedModel.h b/neuralnetworks/utils/common/test/MockPreparedModel.h index 928508edc3..418af61666 100644 --- a/neuralnetworks/utils/common/test/MockPreparedModel.h +++ b/neuralnetworks/utils/common/test/MockPreparedModel.h @@ -35,6 +35,7 @@ class MockPreparedModel final : public IPreparedModel { const OptionalDuration& loopTimeoutDuration, const OptionalDuration& timeoutDurationAfterFence), (const, override)); + MOCK_METHOD(GeneralResult, configureExecutionBurst, (), (const, override)); MOCK_METHOD(std::any, getUnderlyingResource, (), (const, override)); }; -- GitLab From 44f324fb0d89ed896c9b0566ea632bddcfe69439 Mon Sep 17 00:00:00 2001 From: Michael Butler Date: Fri, 18 Dec 2020 20:53:55 -0800 Subject: [PATCH 376/790] Implement partial canonical Burst in NN util code This CL adds a simple implementation of IBurst that dispatches calls to an IPreparedModel object and changes IPreparedModel::configureExecutionBurst to return this new object (instead of returning an error). This CL additionally defines an InvalidBurst class that returns errors whenever it is used and a ResilientBurst class to recover an IBurst object when it has died. Bug: 177267324 Test: mma Change-Id: I4c7e7ff4e6559aeb5e62c4fa02f2e751fef9d87d --- .../1.0/utils/include/nnapi/hal/1.0/Burst.h | 55 +++++++++ .../include/nnapi/hal/1.0/PreparedModel.h | 3 +- neuralnetworks/1.0/utils/src/Burst.cpp | 55 +++++++++ .../1.0/utils/src/PreparedModel.cpp | 3 +- .../include/nnapi/hal/1.2/PreparedModel.h | 3 +- .../1.2/utils/src/PreparedModel.cpp | 3 +- .../include/nnapi/hal/1.3/PreparedModel.h | 3 +- .../1.3/utils/src/PreparedModel.cpp | 3 +- .../common/include/nnapi/hal/InvalidBurst.h | 40 +++++++ .../common/include/nnapi/hal/ResilientBurst.h | 60 ++++++++++ .../nnapi/hal/ResilientPreparedModel.h | 6 +- .../utils/common/src/InvalidBurst.cpp | 38 ++++++ .../utils/common/src/ResilientBurst.cpp | 109 ++++++++++++++++++ .../common/src/ResilientPreparedModel.cpp | 29 ++++- 14 files changed, 400 insertions(+), 10 deletions(-) create mode 100644 neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Burst.h create mode 100644 neuralnetworks/1.0/utils/src/Burst.cpp create mode 100644 neuralnetworks/utils/common/include/nnapi/hal/InvalidBurst.h create mode 100644 neuralnetworks/utils/common/include/nnapi/hal/ResilientBurst.h create mode 100644 neuralnetworks/utils/common/src/InvalidBurst.cpp create mode 100644 neuralnetworks/utils/common/src/ResilientBurst.cpp diff --git a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Burst.h b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Burst.h new file mode 100644 index 0000000000..f2cbe93c7c --- /dev/null +++ b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Burst.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_0_UTILS_BURST_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_0_UTILS_BURST_H + +#include +#include +#include +#include + +#include +#include +#include + +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface +// lifetimes across processes and for protecting asynchronous calls across HIDL. + +namespace android::hardware::neuralnetworks::V1_0::utils { + +// Class that adapts nn::IPreparedModel to nn::IBurst. +class Burst final : public nn::IBurst { + struct PrivateConstructorTag {}; + + public: + static nn::GeneralResult> create( + nn::SharedPreparedModel preparedModel); + + Burst(PrivateConstructorTag tag, nn::SharedPreparedModel preparedModel); + + OptionalCacheHold cacheMemory(const nn::Memory& memory) const override; + + nn::ExecutionResult, nn::Timing>> execute( + const nn::Request& request, nn::MeasureTiming measure) const override; + + private: + const nn::SharedPreparedModel kPreparedModel; +}; + +} // namespace android::hardware::neuralnetworks::V1_0::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_0_UTILS_BURST_H diff --git a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/PreparedModel.h b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/PreparedModel.h index bda40c549b..8853eea048 100644 --- a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/PreparedModel.h +++ b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/PreparedModel.h @@ -35,7 +35,8 @@ namespace android::hardware::neuralnetworks::V1_0::utils { // Class that adapts V1_0::IPreparedModel to nn::IPreparedModel. -class PreparedModel final : public nn::IPreparedModel { +class PreparedModel final : public nn::IPreparedModel, + public std::enable_shared_from_this { struct PrivateConstructorTag {}; public: diff --git a/neuralnetworks/1.0/utils/src/Burst.cpp b/neuralnetworks/1.0/utils/src/Burst.cpp new file mode 100644 index 0000000000..384bd9b699 --- /dev/null +++ b/neuralnetworks/1.0/utils/src/Burst.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Burst.h" + +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace android::hardware::neuralnetworks::V1_0::utils { + +nn::GeneralResult> Burst::create( + nn::SharedPreparedModel preparedModel) { + if (preparedModel == nullptr) { + return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) + << "V1_0::utils::Burst::create must have non-null preparedModel"; + } + + return std::make_shared(PrivateConstructorTag{}, std::move(preparedModel)); +} + +Burst::Burst(PrivateConstructorTag /*tag*/, nn::SharedPreparedModel preparedModel) + : kPreparedModel(std::move(preparedModel)) { + CHECK(kPreparedModel != nullptr); +} + +Burst::OptionalCacheHold Burst::cacheMemory(const nn::Memory& /*memory*/) const { + return nullptr; +} + +nn::ExecutionResult, nn::Timing>> Burst::execute( + const nn::Request& request, nn::MeasureTiming measure) const { + return kPreparedModel->execute(request, measure, {}, {}); +} + +} // namespace android::hardware::neuralnetworks::V1_0::utils diff --git a/neuralnetworks/1.0/utils/src/PreparedModel.cpp b/neuralnetworks/1.0/utils/src/PreparedModel.cpp index b8de131383..858571d401 100644 --- a/neuralnetworks/1.0/utils/src/PreparedModel.cpp +++ b/neuralnetworks/1.0/utils/src/PreparedModel.cpp @@ -16,6 +16,7 @@ #include "PreparedModel.h" +#include "Burst.h" #include "Callbacks.h" #include "Conversions.h" #include "Utils.h" @@ -91,7 +92,7 @@ PreparedModel::executeFenced(const nn::Request& /*request*/, } nn::GeneralResult PreparedModel::configureExecutionBurst() const { - return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "Not yet implemented"; + return Burst::create(shared_from_this()); } std::any PreparedModel::getUnderlyingResource() const { diff --git a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/PreparedModel.h b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/PreparedModel.h index f43933309c..fb1113051c 100644 --- a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/PreparedModel.h +++ b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/PreparedModel.h @@ -36,7 +36,8 @@ namespace android::hardware::neuralnetworks::V1_2::utils { // Class that adapts V1_2::IPreparedModel to nn::IPreparedModel. -class PreparedModel final : public nn::IPreparedModel { +class PreparedModel final : public nn::IPreparedModel, + public std::enable_shared_from_this { struct PrivateConstructorTag {}; public: diff --git a/neuralnetworks/1.2/utils/src/PreparedModel.cpp b/neuralnetworks/1.2/utils/src/PreparedModel.cpp index ad54c39282..6841c5e007 100644 --- a/neuralnetworks/1.2/utils/src/PreparedModel.cpp +++ b/neuralnetworks/1.2/utils/src/PreparedModel.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -118,7 +119,7 @@ PreparedModel::executeFenced(const nn::Request& /*request*/, } nn::GeneralResult PreparedModel::configureExecutionBurst() const { - return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "Not yet implemented"; + return V1_0::utils::Burst::create(shared_from_this()); } std::any PreparedModel::getUnderlyingResource() const { diff --git a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/PreparedModel.h b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/PreparedModel.h index 63aa6faf79..690fecccfb 100644 --- a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/PreparedModel.h +++ b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/PreparedModel.h @@ -35,7 +35,8 @@ namespace android::hardware::neuralnetworks::V1_3::utils { // Class that adapts V1_3::IPreparedModel to nn::IPreparedModel. -class PreparedModel final : public nn::IPreparedModel { +class PreparedModel final : public nn::IPreparedModel, + public std::enable_shared_from_this { struct PrivateConstructorTag {}; public: diff --git a/neuralnetworks/1.3/utils/src/PreparedModel.cpp b/neuralnetworks/1.3/utils/src/PreparedModel.cpp index 7afa777868..725e4f546a 100644 --- a/neuralnetworks/1.3/utils/src/PreparedModel.cpp +++ b/neuralnetworks/1.3/utils/src/PreparedModel.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -198,7 +199,7 @@ PreparedModel::executeFenced(const nn::Request& request, const std::vector PreparedModel::configureExecutionBurst() const { - return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "Not yet implemented"; + return V1_0::utils::Burst::create(shared_from_this()); } std::any PreparedModel::getUnderlyingResource() const { diff --git a/neuralnetworks/utils/common/include/nnapi/hal/InvalidBurst.h b/neuralnetworks/utils/common/include/nnapi/hal/InvalidBurst.h new file mode 100644 index 0000000000..83e60b6a25 --- /dev/null +++ b/neuralnetworks/utils/common/include/nnapi/hal/InvalidBurst.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_INVALID_BURST_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_INVALID_BURST_H + +#include +#include +#include + +#include +#include +#include + +namespace android::hardware::neuralnetworks::utils { + +class InvalidBurst final : public nn::IBurst { + public: + OptionalCacheHold cacheMemory(const nn::Memory& memory) const override; + + nn::ExecutionResult, nn::Timing>> execute( + const nn::Request& request, nn::MeasureTiming measure) const override; +}; + +} // namespace android::hardware::neuralnetworks::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_INVALID_BURST_H diff --git a/neuralnetworks/utils/common/include/nnapi/hal/ResilientBurst.h b/neuralnetworks/utils/common/include/nnapi/hal/ResilientBurst.h new file mode 100644 index 0000000000..0df287f2f8 --- /dev/null +++ b/neuralnetworks/utils/common/include/nnapi/hal/ResilientBurst.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_RESILIENT_BURST_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_RESILIENT_BURST_H + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::utils { + +class ResilientBurst final : public nn::IBurst, + public std::enable_shared_from_this { + struct PrivateConstructorTag {}; + + public: + using Factory = std::function()>; + + static nn::GeneralResult> create(Factory makeBurst); + + ResilientBurst(PrivateConstructorTag tag, Factory makeBurst, nn::SharedBurst burst); + + nn::SharedBurst getBurst() const; + nn::GeneralResult recover(const nn::IBurst* failingBurst) const; + + OptionalCacheHold cacheMemory(const nn::Memory& memory) const override; + + nn::ExecutionResult, nn::Timing>> execute( + const nn::Request& request, nn::MeasureTiming measure) const override; + + private: + const Factory kMakeBurst; + mutable std::mutex mMutex; + mutable nn::SharedBurst mBurst GUARDED_BY(mMutex); +}; + +} // namespace android::hardware::neuralnetworks::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_RESILIENT_BURST_H diff --git a/neuralnetworks/utils/common/include/nnapi/hal/ResilientPreparedModel.h b/neuralnetworks/utils/common/include/nnapi/hal/ResilientPreparedModel.h index 4014404aee..a6c1b1911a 100644 --- a/neuralnetworks/utils/common/include/nnapi/hal/ResilientPreparedModel.h +++ b/neuralnetworks/utils/common/include/nnapi/hal/ResilientPreparedModel.h @@ -30,7 +30,8 @@ namespace android::hardware::neuralnetworks::utils { -class ResilientPreparedModel final : public nn::IPreparedModel { +class ResilientPreparedModel final : public nn::IPreparedModel, + public std::enable_shared_from_this { struct PrivateConstructorTag {}; public: @@ -62,6 +63,9 @@ class ResilientPreparedModel final : public nn::IPreparedModel { std::any getUnderlyingResource() const override; private: + bool isValidInternal() const EXCLUDES(mMutex); + nn::GeneralResult configureExecutionBurstInternal() const; + const Factory kMakePreparedModel; mutable std::mutex mMutex; mutable nn::SharedPreparedModel mPreparedModel GUARDED_BY(mMutex); diff --git a/neuralnetworks/utils/common/src/InvalidBurst.cpp b/neuralnetworks/utils/common/src/InvalidBurst.cpp new file mode 100644 index 0000000000..4ca6603eb7 --- /dev/null +++ b/neuralnetworks/utils/common/src/InvalidBurst.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "InvalidBurst.h" + +#include +#include +#include + +#include +#include +#include + +namespace android::hardware::neuralnetworks::utils { + +InvalidBurst::OptionalCacheHold InvalidBurst::cacheMemory(const nn::Memory& /*memory*/) const { + return nullptr; +} + +nn::ExecutionResult, nn::Timing>> InvalidBurst::execute( + const nn::Request& /*request*/, nn::MeasureTiming /*measure*/) const { + return NN_ERROR() << "InvalidBurst"; +} + +} // namespace android::hardware::neuralnetworks::utils diff --git a/neuralnetworks/utils/common/src/ResilientBurst.cpp b/neuralnetworks/utils/common/src/ResilientBurst.cpp new file mode 100644 index 0000000000..0d3cb33a98 --- /dev/null +++ b/neuralnetworks/utils/common/src/ResilientBurst.cpp @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ResilientBurst.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::utils { +namespace { + +template +auto protect(const ResilientBurst& resilientBurst, const FnType& fn) + -> decltype(fn(*resilientBurst.getBurst())) { + auto burst = resilientBurst.getBurst(); + auto result = fn(*burst); + + // Immediately return if burst is not dead. + if (result.has_value() || result.error().code != nn::ErrorStatus::DEAD_OBJECT) { + return result; + } + + // Attempt recovery and return if it fails. + auto maybeBurst = resilientBurst.recover(burst.get()); + if (!maybeBurst.has_value()) { + auto [resultErrorMessage, resultErrorCode, resultOutputShapes] = std::move(result).error(); + const auto& [recoveryErrorMessage, recoveryErrorCode] = maybeBurst.error(); + return nn::error(resultErrorCode, std::move(resultOutputShapes)) + << resultErrorMessage << ", and failed to recover dead burst object with error " + << recoveryErrorCode << ": " << recoveryErrorMessage; + } + burst = std::move(maybeBurst).value(); + + return fn(*burst); +} + +} // namespace + +nn::GeneralResult> ResilientBurst::create(Factory makeBurst) { + if (makeBurst == nullptr) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) + << "utils::ResilientBurst::create must have non-empty makeBurst"; + } + auto burst = NN_TRY(makeBurst()); + CHECK(burst != nullptr); + return std::make_shared(PrivateConstructorTag{}, std::move(makeBurst), + std::move(burst)); +} + +ResilientBurst::ResilientBurst(PrivateConstructorTag /*tag*/, Factory makeBurst, + nn::SharedBurst burst) + : kMakeBurst(std::move(makeBurst)), mBurst(std::move(burst)) { + CHECK(kMakeBurst != nullptr); + CHECK(mBurst != nullptr); +} + +nn::SharedBurst ResilientBurst::getBurst() const { + std::lock_guard guard(mMutex); + return mBurst; +} + +nn::GeneralResult ResilientBurst::recover(const nn::IBurst* failingBurst) const { + std::lock_guard guard(mMutex); + + // Another caller updated the failing burst. + if (mBurst.get() != failingBurst) { + return mBurst; + } + + mBurst = NN_TRY(kMakeBurst()); + return mBurst; +} + +ResilientBurst::OptionalCacheHold ResilientBurst::cacheMemory(const nn::Memory& memory) const { + return getBurst()->cacheMemory(memory); +} + +nn::ExecutionResult, nn::Timing>> ResilientBurst::execute( + const nn::Request& request, nn::MeasureTiming measure) const { + const auto fn = [&request, measure](const nn::IBurst& burst) { + return burst.execute(request, measure); + }; + return protect(*this, fn); +} + +} // namespace android::hardware::neuralnetworks::utils diff --git a/neuralnetworks/utils/common/src/ResilientPreparedModel.cpp b/neuralnetworks/utils/common/src/ResilientPreparedModel.cpp index faba9965f2..5dd5f99f5f 100644 --- a/neuralnetworks/utils/common/src/ResilientPreparedModel.cpp +++ b/neuralnetworks/utils/common/src/ResilientPreparedModel.cpp @@ -16,6 +16,9 @@ #include "ResilientPreparedModel.h" +#include "InvalidBurst.h" +#include "ResilientBurst.h" + #include #include #include @@ -125,14 +128,34 @@ ResilientPreparedModel::executeFenced(const nn::Request& request, } nn::GeneralResult ResilientPreparedModel::configureExecutionBurst() const { - const auto fn = [](const nn::IPreparedModel& preparedModel) { - return preparedModel.configureExecutionBurst(); +#if 0 + auto self = shared_from_this(); + ResilientBurst::Factory makeBurst = + [preparedModel = std::move(self)]() -> nn::GeneralResult { + return preparedModel->configureExecutionBurst(); }; - return protect(*this, fn); + return ResilientBurst::create(std::move(makeBurst)); +#else + return configureExecutionBurstInternal(); +#endif } std::any ResilientPreparedModel::getUnderlyingResource() const { return getPreparedModel()->getUnderlyingResource(); } +bool ResilientPreparedModel::isValidInternal() const { + return true; +} + +nn::GeneralResult ResilientPreparedModel::configureExecutionBurstInternal() const { + if (!isValidInternal()) { + return std::make_shared(); + } + const auto fn = [](const nn::IPreparedModel& preparedModel) { + return preparedModel.configureExecutionBurst(); + }; + return protect(*this, fn); +} + } // namespace android::hardware::neuralnetworks::utils -- GitLab From 87e83068784b65ab851e4ff65a1099de4e777c9e Mon Sep 17 00:00:00 2001 From: Michael Butler Date: Sat, 19 Dec 2020 14:44:35 -0800 Subject: [PATCH 377/790] Relocate ExecutionBurst* classes to NN util code The only changes when copying these files were .clang-format differences and correcting a typo in a comment. Bug: 177267324 Test: mma Change-Id: I96cc2402642e1e3076ac7e78e06163c1d3d41701 --- neuralnetworks/1.2/utils/Android.bp | 1 + .../nnapi/hal/1.2/ExecutionBurstController.h | 345 ++++++++++ .../nnapi/hal/1.2/ExecutionBurstServer.h | 343 ++++++++++ .../utils/src/ExecutionBurstController.cpp | 631 +++++++++++++++++ .../1.2/utils/src/ExecutionBurstServer.cpp | 646 ++++++++++++++++++ 5 files changed, 1966 insertions(+) create mode 100644 neuralnetworks/1.2/utils/include/nnapi/hal/1.2/ExecutionBurstController.h create mode 100644 neuralnetworks/1.2/utils/include/nnapi/hal/1.2/ExecutionBurstServer.h create mode 100644 neuralnetworks/1.2/utils/src/ExecutionBurstController.cpp create mode 100644 neuralnetworks/1.2/utils/src/ExecutionBurstServer.cpp diff --git a/neuralnetworks/1.2/utils/Android.bp b/neuralnetworks/1.2/utils/Android.bp index 0fec41c240..695905690e 100644 --- a/neuralnetworks/1.2/utils/Android.bp +++ b/neuralnetworks/1.2/utils/Android.bp @@ -18,6 +18,7 @@ cc_library_static { name: "neuralnetworks_utils_hal_1_2", defaults: ["neuralnetworks_utils_defaults"], srcs: ["src/*"], + exclude_srcs: ["src/ExecutionBurst*"], local_include_dirs: ["include/nnapi/hal/1.2/"], export_include_dirs: ["include"], cflags: ["-Wthread-safety"], diff --git a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/ExecutionBurstController.h b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/ExecutionBurstController.h new file mode 100644 index 0000000000..e00ab82d69 --- /dev/null +++ b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/ExecutionBurstController.h @@ -0,0 +1,345 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_FRAMEWORKS_ML_NN_COMMON_EXECUTION_BURST_CONTROLLER_H +#define ANDROID_FRAMEWORKS_ML_NN_COMMON_EXECUTION_BURST_CONTROLLER_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace android::nn { + +/** + * Number of elements in the FMQ. + */ +constexpr const size_t kExecutionBurstChannelLength = 1024; + +/** + * Function to serialize a request. + * + * Prefer calling RequestChannelSender::send. + * + * @param request Request object without the pool information. + * @param measure Whether to collect timing information for the execution. + * @param memoryIds Slot identifiers corresponding to memory resources for the + * request. + * @return Serialized FMQ request data. + */ +std::vector serialize( + const hardware::neuralnetworks::V1_0::Request& request, + hardware::neuralnetworks::V1_2::MeasureTiming measure, const std::vector& slots); + +/** + * Deserialize the FMQ result data. + * + * The three resulting fields are the status of the execution, the dynamic + * shapes of the output tensors, and the timing information of the execution. + * + * @param data Serialized FMQ result data. + * @return Result object if successfully deserialized, std::nullopt otherwise. + */ +std::optional, + hardware::neuralnetworks::V1_2::Timing>> +deserialize(const std::vector& data); + +/** + * Convert result code to error status. + * + * @param resultCode Result code to be converted. + * @return ErrorStatus Resultant error status. + */ +hardware::neuralnetworks::V1_0::ErrorStatus legacyConvertResultCodeToErrorStatus(int resultCode); + +/** + * ResultChannelReceiver is responsible for waiting on the channel until the + * packet is available, extracting the packet from the channel, and + * deserializing the packet. + * + * Because the receiver can wait on a packet that may never come (e.g., because + * the sending side of the packet has been closed), this object can be + * invalidated, unblocking the receiver. + */ +class ResultChannelReceiver { + using FmqResultDescriptor = + hardware::MQDescriptorSync; + using FmqResultChannel = hardware::MessageQueue; + + public: + /** + * Create the receiving end of a result channel. + * + * Prefer this call over the constructor. + * + * @param channelLength Number of elements in the FMQ. + * @param pollingTimeWindow How much time (in microseconds) the + * ResultChannelReceiver is allowed to poll the FMQ before waiting on + * the blocking futex. Polling may result in lower latencies at the + * potential cost of more power usage. + * @return A pair of ResultChannelReceiver and the FMQ descriptor on + * successful creation, both nullptr otherwise. + */ + static std::pair, const FmqResultDescriptor*> create( + size_t channelLength, std::chrono::microseconds pollingTimeWindow); + + /** + * Get the result from the channel. + * + * This method will block until either: + * 1) The packet has been retrieved, or + * 2) The receiver has been invalidated + * + * @return Result object if successfully received, std::nullopt if error or + * if the receiver object was invalidated. + */ + std::optional, + hardware::neuralnetworks::V1_2::Timing>> + getBlocking(); + + /** + * Method to mark the channel as invalid, unblocking any current or future + * calls to ResultChannelReceiver::getBlocking. + */ + void invalidate(); + + // prefer calling ResultChannelReceiver::getBlocking + std::optional> getPacketBlocking(); + + ResultChannelReceiver(std::unique_ptr fmqResultChannel, + std::chrono::microseconds pollingTimeWindow); + + private: + const std::unique_ptr mFmqResultChannel; + std::atomic mValid{true}; + const std::chrono::microseconds kPollingTimeWindow; +}; + +/** + * RequestChannelSender is responsible for serializing the result packet of + * information, sending it on the result channel, and signaling that the data is + * available. + */ +class RequestChannelSender { + using FmqRequestDescriptor = + hardware::MQDescriptorSync; + using FmqRequestChannel = + hardware::MessageQueue; + + public: + /** + * Create the sending end of a request channel. + * + * Prefer this call over the constructor. + * + * @param channelLength Number of elements in the FMQ. + * @return A pair of ResultChannelReceiver and the FMQ descriptor on + * successful creation, both nullptr otherwise. + */ + static std::pair, const FmqRequestDescriptor*> create( + size_t channelLength); + + /** + * Send the request to the channel. + * + * @param request Request object without the pool information. + * @param measure Whether to collect timing information for the execution. + * @param memoryIds Slot identifiers corresponding to memory resources for + * the request. + * @return 'true' on successful send, 'false' otherwise. + */ + bool send(const hardware::neuralnetworks::V1_0::Request& request, + hardware::neuralnetworks::V1_2::MeasureTiming measure, + const std::vector& slots); + + /** + * Method to mark the channel as invalid, causing all future calls to + * RequestChannelSender::send to immediately return false without attempting + * to send a message across the FMQ. + */ + void invalidate(); + + // prefer calling RequestChannelSender::send + bool sendPacket(const std::vector& packet); + + RequestChannelSender(std::unique_ptr fmqRequestChannel); + + private: + const std::unique_ptr mFmqRequestChannel; + std::atomic mValid{true}; +}; + +/** + * The ExecutionBurstController class manages both the serialization and + * deserialization of data across FMQ, making it appear to the runtime as a + * regular synchronous inference. Additionally, this class manages the burst's + * memory cache. + */ +class ExecutionBurstController { + DISALLOW_IMPLICIT_CONSTRUCTORS(ExecutionBurstController); + + public: + /** + * NN runtime burst callback object and memory cache. + * + * ExecutionBurstCallback associates a hidl_memory object with a slot number + * to be passed across FMQ. The ExecutionBurstServer can use this callback + * to retrieve this hidl_memory corresponding to the slot via HIDL. + * + * Whenever a hidl_memory object is copied, it will duplicate the underlying + * file descriptor. Because the NN runtime currently copies the hidl_memory + * on each execution, it is difficult to associate hidl_memory objects with + * previously cached hidl_memory objects. For this reason, callers of this + * class must pair each hidl_memory object with an associated key. For + * efficiency, if two hidl_memory objects represent the same underlying + * buffer, they must use the same key. + */ + class ExecutionBurstCallback : public hardware::neuralnetworks::V1_2::IBurstCallback { + DISALLOW_COPY_AND_ASSIGN(ExecutionBurstCallback); + + public: + ExecutionBurstCallback() = default; + + hardware::Return getMemories(const hardware::hidl_vec& slots, + getMemories_cb cb) override; + + /** + * This function performs one of two different actions: + * 1) If a key corresponding to a memory resource is unrecognized by the + * ExecutionBurstCallback object, the ExecutionBurstCallback object + * will allocate a slot, bind the memory to the slot, and return the + * slot identifier. + * 2) If a key corresponding to a memory resource is recognized by the + * ExecutionBurstCallback object, the ExecutionBurstCallback object + * will return the existing slot identifier. + * + * @param memories Memory resources used in an inference. + * @param keys Unique identifiers where each element corresponds to a + * memory resource element in "memories". + * @return Unique slot identifiers where each returned slot element + * corresponds to a memory resource element in "memories". + */ + std::vector getSlots(const hardware::hidl_vec& memories, + const std::vector& keys); + + /* + * This function performs two different actions: + * 1) Removes an entry from the cache (if present), including the local + * storage of the hidl_memory object. Note that this call does not + * free any corresponding hidl_memory object in ExecutionBurstServer, + * which is separately freed via IBurstContext::freeMemory. + * 2) Return whether a cache entry was removed and which slot was removed if + * found. If the key did not to correspond to any entry in the cache, a + * slot number of 0 is returned. The slot number and whether the entry + * existed is useful so the same slot can be freed in the + * ExecutionBurstServer's cache via IBurstContext::freeMemory. + */ + std::pair freeMemory(intptr_t key); + + private: + int32_t getSlotLocked(const hardware::hidl_memory& memory, intptr_t key); + int32_t allocateSlotLocked(); + + std::mutex mMutex; + std::stack> mFreeSlots; + std::map mMemoryIdToSlot; + std::vector mMemoryCache; + }; + + /** + * Creates a burst controller on a prepared model. + * + * Prefer this over ExecutionBurstController's constructor. + * + * @param preparedModel Model prepared for execution to execute on. + * @param pollingTimeWindow How much time (in microseconds) the + * ExecutionBurstController is allowed to poll the FMQ before waiting on + * the blocking futex. Polling may result in lower latencies at the + * potential cost of more power usage. + * @return ExecutionBurstController Execution burst controller object. + */ + static std::unique_ptr create( + const sp& preparedModel, + std::chrono::microseconds pollingTimeWindow); + + // prefer calling ExecutionBurstController::create + ExecutionBurstController(const std::shared_ptr& requestChannelSender, + const std::shared_ptr& resultChannelReceiver, + const sp& burstContext, + const sp& callback, + const sp& deathHandler = nullptr); + + // explicit destructor to unregister the death recipient + ~ExecutionBurstController(); + + /** + * Execute a request on a model. + * + * @param request Arguments to be executed on a model. + * @param measure Whether to collect timing measurements, either YES or NO + * @param memoryIds Identifiers corresponding to each memory object in the + * request's pools. + * @return A tuple of: + * - result code of the execution + * - dynamic output shapes from the execution + * - any execution time measurements of the execution + * - whether or not a failed burst execution should be re-run using a + * different path (e.g., IPreparedModel::executeSynchronously) + */ + std::tuple, + hardware::neuralnetworks::V1_2::Timing, bool> + compute(const hardware::neuralnetworks::V1_0::Request& request, + hardware::neuralnetworks::V1_2::MeasureTiming measure, + const std::vector& memoryIds); + + /** + * Propagate a user's freeing of memory to the service. + * + * @param key Key corresponding to the memory object. + */ + void freeMemory(intptr_t key); + + private: + std::mutex mMutex; + const std::shared_ptr mRequestChannelSender; + const std::shared_ptr mResultChannelReceiver; + const sp mBurstContext; + const sp mMemoryCache; + const sp mDeathHandler; +}; + +} // namespace android::nn + +#endif // ANDROID_FRAMEWORKS_ML_NN_COMMON_EXECUTION_BURST_CONTROLLER_H diff --git a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/ExecutionBurstServer.h b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/ExecutionBurstServer.h new file mode 100644 index 0000000000..2c7d6540de --- /dev/null +++ b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/ExecutionBurstServer.h @@ -0,0 +1,343 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_FRAMEWORKS_ML_NN_COMMON_EXECUTION_BURST_SERVER_H +#define ANDROID_FRAMEWORKS_ML_NN_COMMON_EXECUTION_BURST_SERVER_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace android::nn { + +using FmqRequestDescriptor = + hardware::MQDescriptorSync; +using FmqResultDescriptor = + hardware::MQDescriptorSync; + +/** + * Function to serialize results. + * + * Prefer calling ResultChannelSender::send. + * + * @param errorStatus Status of the execution. + * @param outputShapes Dynamic shapes of the output tensors. + * @param timing Timing information of the execution. + * @return Serialized FMQ result data. + */ +std::vector serialize( + hardware::neuralnetworks::V1_0::ErrorStatus errorStatus, + const std::vector& outputShapes, + hardware::neuralnetworks::V1_2::Timing timing); + +/** + * Deserialize the FMQ request data. + * + * The three resulting fields are the Request object (where Request::pools is + * empty), slot identifiers (which are stand-ins for Request::pools), and + * whether timing information must be collected for the run. + * + * @param data Serialized FMQ request data. + * @return Request object if successfully deserialized, std::nullopt otherwise. + */ +std::optional, + hardware::neuralnetworks::V1_2::MeasureTiming>> +deserialize(const std::vector& data); + +/** + * RequestChannelReceiver is responsible for waiting on the channel until the + * packet is available, extracting the packet from the channel, and + * deserializing the packet. + * + * Because the receiver can wait on a packet that may never come (e.g., because + * the sending side of the packet has been closed), this object can be + * invalidated, unblocking the receiver. + */ +class RequestChannelReceiver { + using FmqRequestChannel = + hardware::MessageQueue; + + public: + /** + * Create the receiving end of a request channel. + * + * Prefer this call over the constructor. + * + * @param requestChannel Descriptor for the request channel. + * @param pollingTimeWindow How much time (in microseconds) the + * RequestChannelReceiver is allowed to poll the FMQ before waiting on + * the blocking futex. Polling may result in lower latencies at the + * potential cost of more power usage. + * @return RequestChannelReceiver on successful creation, nullptr otherwise. + */ + static std::unique_ptr create( + const FmqRequestDescriptor& requestChannel, + std::chrono::microseconds pollingTimeWindow); + + /** + * Get the request from the channel. + * + * This method will block until either: + * 1) The packet has been retrieved, or + * 2) The receiver has been invalidated + * + * @return Request object if successfully received, std::nullopt if error or + * if the receiver object was invalidated. + */ + std::optional, + hardware::neuralnetworks::V1_2::MeasureTiming>> + getBlocking(); + + /** + * Method to mark the channel as invalid, unblocking any current or future + * calls to RequestChannelReceiver::getBlocking. + */ + void invalidate(); + + RequestChannelReceiver(std::unique_ptr fmqRequestChannel, + std::chrono::microseconds pollingTimeWindow); + + private: + std::optional> getPacketBlocking(); + + const std::unique_ptr mFmqRequestChannel; + std::atomic mTeardown{false}; + const std::chrono::microseconds kPollingTimeWindow; +}; + +/** + * ResultChannelSender is responsible for serializing the result packet of + * information, sending it on the result channel, and signaling that the data is + * available. + */ +class ResultChannelSender { + using FmqResultChannel = hardware::MessageQueue; + + public: + /** + * Create the sending end of a result channel. + * + * Prefer this call over the constructor. + * + * @param resultChannel Descriptor for the result channel. + * @return ResultChannelSender on successful creation, nullptr otherwise. + */ + static std::unique_ptr create(const FmqResultDescriptor& resultChannel); + + /** + * Send the result to the channel. + * + * @param errorStatus Status of the execution. + * @param outputShapes Dynamic shapes of the output tensors. + * @param timing Timing information of the execution. + * @return 'true' on successful send, 'false' otherwise. + */ + bool send(hardware::neuralnetworks::V1_0::ErrorStatus errorStatus, + const std::vector& outputShapes, + hardware::neuralnetworks::V1_2::Timing timing); + + // prefer calling ResultChannelSender::send + bool sendPacket(const std::vector& packet); + + ResultChannelSender(std::unique_ptr fmqResultChannel); + + private: + const std::unique_ptr mFmqResultChannel; +}; + +/** + * The ExecutionBurstServer class is responsible for waiting for and + * deserializing a request object from a FMQ, performing the inference, and + * serializing the result back across another FMQ. + */ +class ExecutionBurstServer : public hardware::neuralnetworks::V1_2::IBurstContext { + DISALLOW_IMPLICIT_CONSTRUCTORS(ExecutionBurstServer); + + public: + /** + * IBurstExecutorWithCache is a callback object passed to + * ExecutionBurstServer's factory function that is used to perform an + * execution. Because some memory resources are needed across multiple + * executions, this object also contains a local cache that can directly be + * used in the execution. + * + * ExecutionBurstServer will never access its IBurstExecutorWithCache object + * with concurrent calls. + */ + class IBurstExecutorWithCache { + DISALLOW_COPY_AND_ASSIGN(IBurstExecutorWithCache); + + public: + IBurstExecutorWithCache() = default; + virtual ~IBurstExecutorWithCache() = default; + + /** + * Checks if a cache entry specified by a slot is present in the cache. + * + * @param slot Identifier of the cache entry. + * @return 'true' if the cache entry is present in the cache, 'false' + * otherwise. + */ + virtual bool isCacheEntryPresent(int32_t slot) const = 0; + + /** + * Adds an entry specified by a slot to the cache. + * + * The caller of this function must ensure that the cache entry that is + * being added is not already present in the cache. This can be checked + * via isCacheEntryPresent. + * + * @param memory Memory resource to be cached. + * @param slot Slot identifier corresponding to the memory resource. + */ + virtual void addCacheEntry(const hardware::hidl_memory& memory, int32_t slot) = 0; + + /** + * Removes an entry specified by a slot from the cache. + * + * If the cache entry corresponding to the slot number does not exist, + * the call does nothing. + * + * @param slot Slot identifier corresponding to the memory resource. + */ + virtual void removeCacheEntry(int32_t slot) = 0; + + /** + * Perform an execution. + * + * @param request Request object with inputs and outputs specified. + * Request::pools is empty, and DataLocation::poolIndex instead + * refers to the 'slots' argument as if it were Request::pools. + * @param slots Slots corresponding to the cached memory entries to be + * used. + * @param measure Whether timing information is requested for the + * execution. + * @return Result of the execution, including the status of the + * execution, dynamic output shapes, and any timing information. + */ + virtual std::tuple, + hardware::neuralnetworks::V1_2::Timing> + execute(const hardware::neuralnetworks::V1_0::Request& request, + const std::vector& slots, + hardware::neuralnetworks::V1_2::MeasureTiming measure) = 0; + }; + + /** + * Create automated context to manage FMQ-based executions. + * + * This function is intended to be used by a service to automatically: + * 1) Receive data from a provided FMQ + * 2) Execute a model with the given information + * 3) Send the result to the created FMQ + * + * @param callback Callback used to retrieve memories corresponding to + * unrecognized slots. + * @param requestChannel Input FMQ channel through which the client passes the + * request to the service. + * @param resultChannel Output FMQ channel from which the client can retrieve + * the result of the execution. + * @param executorWithCache Object which maintains a local cache of the + * memory pools and executes using the cached memory pools. + * @param pollingTimeWindow How much time (in microseconds) the + * ExecutionBurstServer is allowed to poll the FMQ before waiting on + * the blocking futex. Polling may result in lower latencies at the + * potential cost of more power usage. + * @result IBurstContext Handle to the burst context. + */ + static sp create( + const sp& callback, + const FmqRequestDescriptor& requestChannel, const FmqResultDescriptor& resultChannel, + std::shared_ptr executorWithCache, + std::chrono::microseconds pollingTimeWindow = std::chrono::microseconds{0}); + + /** + * Create automated context to manage FMQ-based executions. + * + * This function is intended to be used by a service to automatically: + * 1) Receive data from a provided FMQ + * 2) Execute a model with the given information + * 3) Send the result to the created FMQ + * + * @param callback Callback used to retrieve memories corresponding to + * unrecognized slots. + * @param requestChannel Input FMQ channel through which the client passes the + * request to the service. + * @param resultChannel Output FMQ channel from which the client can retrieve + * the result of the execution. + * @param preparedModel PreparedModel that the burst object was created from. + * IPreparedModel::executeSynchronously will be used to perform the + * execution. + * @param pollingTimeWindow How much time (in microseconds) the + * ExecutionBurstServer is allowed to poll the FMQ before waiting on + * the blocking futex. Polling may result in lower latencies at the + * potential cost of more power usage. + * @result IBurstContext Handle to the burst context. + */ + static sp create( + const sp& callback, + const FmqRequestDescriptor& requestChannel, const FmqResultDescriptor& resultChannel, + hardware::neuralnetworks::V1_2::IPreparedModel* preparedModel, + std::chrono::microseconds pollingTimeWindow = std::chrono::microseconds{0}); + + ExecutionBurstServer(const sp& callback, + std::unique_ptr requestChannel, + std::unique_ptr resultChannel, + std::shared_ptr cachedExecutor); + ~ExecutionBurstServer(); + + // Used by the NN runtime to preemptively remove any stored memory. + hardware::Return freeMemory(int32_t slot) override; + + private: + // Ensures all cache entries contained in mExecutorWithCache are present in + // the cache. If they are not present, they are retrieved (via + // IBurstCallback::getMemories) and added to mExecutorWithCache. + // + // This method is locked via mMutex when it is called. + void ensureCacheEntriesArePresentLocked(const std::vector& slots); + + // Work loop that will continue processing execution requests until the + // ExecutionBurstServer object is freed. + void task(); + + std::thread mWorker; + std::mutex mMutex; + std::atomic mTeardown{false}; + const sp mCallback; + const std::unique_ptr mRequestChannelReceiver; + const std::unique_ptr mResultChannelSender; + const std::shared_ptr mExecutorWithCache; +}; + +} // namespace android::nn + +#endif // ANDROID_FRAMEWORKS_ML_NN_COMMON_EXECUTION_BURST_SERVER_H diff --git a/neuralnetworks/1.2/utils/src/ExecutionBurstController.cpp b/neuralnetworks/1.2/utils/src/ExecutionBurstController.cpp new file mode 100644 index 0000000000..212863e183 --- /dev/null +++ b/neuralnetworks/1.2/utils/src/ExecutionBurstController.cpp @@ -0,0 +1,631 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "ExecutionBurstController" + +#include "ExecutionBurstController.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "HalInterfaces.h" +#include "Tracing.h" +#include "Utils.h" + +namespace android::nn { +namespace { + +using V1_2::FmqRequestDatum; +using V1_2::FmqResultDatum; +using V1_2::IBurstCallback; +using V1_2::IBurstContext; +using FmqRequestDescriptor = hardware::MQDescriptorSync; +using FmqResultDescriptor = hardware::MQDescriptorSync; + +constexpr V1_2::Timing kNoTiming12 = {std::numeric_limits::max(), + std::numeric_limits::max()}; + +class BurstContextDeathHandler : public hardware::hidl_death_recipient { + public: + using Callback = std::function; + + BurstContextDeathHandler(const Callback& onDeathCallback) : mOnDeathCallback(onDeathCallback) { + CHECK(onDeathCallback != nullptr); + } + + void serviceDied(uint64_t /*cookie*/, const wp& /*who*/) override { + LOG(ERROR) << "BurstContextDeathHandler::serviceDied -- service unexpectedly died!"; + mOnDeathCallback(); + } + + private: + const Callback mOnDeathCallback; +}; + +} // anonymous namespace + +// serialize a request into a packet +std::vector serialize(const V1_0::Request& request, V1_2::MeasureTiming measure, + const std::vector& slots) { + // count how many elements need to be sent for a request + size_t count = 2 + request.inputs.size() + request.outputs.size() + request.pools.size(); + for (const auto& input : request.inputs) { + count += input.dimensions.size(); + } + for (const auto& output : request.outputs) { + count += output.dimensions.size(); + } + + // create buffer to temporarily store elements + std::vector data; + data.reserve(count); + + // package packetInfo + { + FmqRequestDatum datum; + datum.packetInformation( + {/*.packetSize=*/static_cast(count), + /*.numberOfInputOperands=*/static_cast(request.inputs.size()), + /*.numberOfOutputOperands=*/static_cast(request.outputs.size()), + /*.numberOfPools=*/static_cast(request.pools.size())}); + data.push_back(datum); + } + + // package input data + for (const auto& input : request.inputs) { + // package operand information + FmqRequestDatum datum; + datum.inputOperandInformation( + {/*.hasNoValue=*/input.hasNoValue, + /*.location=*/input.location, + /*.numberOfDimensions=*/static_cast(input.dimensions.size())}); + data.push_back(datum); + + // package operand dimensions + for (uint32_t dimension : input.dimensions) { + FmqRequestDatum datum; + datum.inputOperandDimensionValue(dimension); + data.push_back(datum); + } + } + + // package output data + for (const auto& output : request.outputs) { + // package operand information + FmqRequestDatum datum; + datum.outputOperandInformation( + {/*.hasNoValue=*/output.hasNoValue, + /*.location=*/output.location, + /*.numberOfDimensions=*/static_cast(output.dimensions.size())}); + data.push_back(datum); + + // package operand dimensions + for (uint32_t dimension : output.dimensions) { + FmqRequestDatum datum; + datum.outputOperandDimensionValue(dimension); + data.push_back(datum); + } + } + + // package pool identifier + for (int32_t slot : slots) { + FmqRequestDatum datum; + datum.poolIdentifier(slot); + data.push_back(datum); + } + + // package measureTiming + { + FmqRequestDatum datum; + datum.measureTiming(measure); + data.push_back(datum); + } + + // return packet + return data; +} + +// deserialize a packet into the result +std::optional, V1_2::Timing>> +deserialize(const std::vector& data) { + using discriminator = FmqResultDatum::hidl_discriminator; + + std::vector outputShapes; + size_t index = 0; + + // validate packet information + if (data.size() == 0 || data[index].getDiscriminator() != discriminator::packetInformation) { + LOG(ERROR) << "FMQ Result packet ill-formed"; + return std::nullopt; + } + + // unpackage packet information + const FmqResultDatum::PacketInformation& packetInfo = data[index].packetInformation(); + index++; + const uint32_t packetSize = packetInfo.packetSize; + const V1_0::ErrorStatus errorStatus = packetInfo.errorStatus; + const uint32_t numberOfOperands = packetInfo.numberOfOperands; + + // verify packet size + if (data.size() != packetSize) { + LOG(ERROR) << "FMQ Result packet ill-formed"; + return std::nullopt; + } + + // unpackage operands + for (size_t operand = 0; operand < numberOfOperands; ++operand) { + // validate operand information + if (data[index].getDiscriminator() != discriminator::operandInformation) { + LOG(ERROR) << "FMQ Result packet ill-formed"; + return std::nullopt; + } + + // unpackage operand information + const FmqResultDatum::OperandInformation& operandInfo = data[index].operandInformation(); + index++; + const bool isSufficient = operandInfo.isSufficient; + const uint32_t numberOfDimensions = operandInfo.numberOfDimensions; + + // unpackage operand dimensions + std::vector dimensions; + dimensions.reserve(numberOfDimensions); + for (size_t i = 0; i < numberOfDimensions; ++i) { + // validate dimension + if (data[index].getDiscriminator() != discriminator::operandDimensionValue) { + LOG(ERROR) << "FMQ Result packet ill-formed"; + return std::nullopt; + } + + // unpackage dimension + const uint32_t dimension = data[index].operandDimensionValue(); + index++; + + // store result + dimensions.push_back(dimension); + } + + // store result + outputShapes.push_back({/*.dimensions=*/dimensions, /*.isSufficient=*/isSufficient}); + } + + // validate execution timing + if (data[index].getDiscriminator() != discriminator::executionTiming) { + LOG(ERROR) << "FMQ Result packet ill-formed"; + return std::nullopt; + } + + // unpackage execution timing + const V1_2::Timing timing = data[index].executionTiming(); + index++; + + // validate packet information + if (index != packetSize) { + LOG(ERROR) << "FMQ Result packet ill-formed"; + return std::nullopt; + } + + // return result + return std::make_tuple(errorStatus, std::move(outputShapes), timing); +} + +V1_0::ErrorStatus legacyConvertResultCodeToErrorStatus(int resultCode) { + return convertToV1_0(convertResultCodeToErrorStatus(resultCode)); +} + +std::pair, const FmqResultDescriptor*> +ResultChannelReceiver::create(size_t channelLength, std::chrono::microseconds pollingTimeWindow) { + std::unique_ptr fmqResultChannel = + std::make_unique(channelLength, /*confEventFlag=*/true); + if (!fmqResultChannel->isValid()) { + LOG(ERROR) << "Unable to create ResultChannelReceiver"; + return {nullptr, nullptr}; + } + + const FmqResultDescriptor* descriptor = fmqResultChannel->getDesc(); + return std::make_pair( + std::make_unique(std::move(fmqResultChannel), pollingTimeWindow), + descriptor); +} + +ResultChannelReceiver::ResultChannelReceiver(std::unique_ptr fmqResultChannel, + std::chrono::microseconds pollingTimeWindow) + : mFmqResultChannel(std::move(fmqResultChannel)), kPollingTimeWindow(pollingTimeWindow) {} + +std::optional, V1_2::Timing>> +ResultChannelReceiver::getBlocking() { + const auto packet = getPacketBlocking(); + if (!packet) { + return std::nullopt; + } + + return deserialize(*packet); +} + +void ResultChannelReceiver::invalidate() { + mValid = false; + + // force unblock + // ExecutionBurstController waits on a result packet after sending a + // request. If the driver containing ExecutionBurstServer crashes, the + // controller may be waiting on the futex. This force unblock wakes up any + // thread waiting on the futex. + // TODO: look for a different/better way to signal/notify the futex to + // wake up any thread waiting on it + FmqResultDatum datum; + datum.packetInformation({/*.packetSize=*/0, + /*.errorStatus=*/V1_0::ErrorStatus::GENERAL_FAILURE, + /*.numberOfOperands=*/0}); + mFmqResultChannel->writeBlocking(&datum, 1); +} + +std::optional> ResultChannelReceiver::getPacketBlocking() { + if (!mValid) { + return std::nullopt; + } + + // First spend time polling if results are available in FMQ instead of + // waiting on the futex. Polling is more responsive (yielding lower + // latencies), but can take up more power, so only poll for a limited period + // of time. + + auto& getCurrentTime = std::chrono::high_resolution_clock::now; + const auto timeToStopPolling = getCurrentTime() + kPollingTimeWindow; + + while (getCurrentTime() < timeToStopPolling) { + // if class is being torn down, immediately return + if (!mValid.load(std::memory_order_relaxed)) { + return std::nullopt; + } + + // Check if data is available. If it is, immediately retrieve it and + // return. + const size_t available = mFmqResultChannel->availableToRead(); + if (available > 0) { + std::vector packet(available); + const bool success = mFmqResultChannel->read(packet.data(), available); + if (!success) { + LOG(ERROR) << "Error receiving packet"; + return std::nullopt; + } + return std::make_optional(std::move(packet)); + } + } + + // If we get to this point, we either stopped polling because it was taking + // too long or polling was not allowed. Instead, perform a blocking call + // which uses a futex to save power. + + // wait for result packet and read first element of result packet + FmqResultDatum datum; + bool success = mFmqResultChannel->readBlocking(&datum, 1); + + // retrieve remaining elements + // NOTE: all of the data is already available at this point, so there's no + // need to do a blocking wait to wait for more data. This is known because + // in FMQ, all writes are published (made available) atomically. Currently, + // the producer always publishes the entire packet in one function call, so + // if the first element of the packet is available, the remaining elements + // are also available. + const size_t count = mFmqResultChannel->availableToRead(); + std::vector packet(count + 1); + std::memcpy(&packet.front(), &datum, sizeof(datum)); + success &= mFmqResultChannel->read(packet.data() + 1, count); + + if (!mValid) { + return std::nullopt; + } + + // ensure packet was successfully received + if (!success) { + LOG(ERROR) << "Error receiving packet"; + return std::nullopt; + } + + return std::make_optional(std::move(packet)); +} + +std::pair, const FmqRequestDescriptor*> +RequestChannelSender::create(size_t channelLength) { + std::unique_ptr fmqRequestChannel = + std::make_unique(channelLength, /*confEventFlag=*/true); + if (!fmqRequestChannel->isValid()) { + LOG(ERROR) << "Unable to create RequestChannelSender"; + return {nullptr, nullptr}; + } + + const FmqRequestDescriptor* descriptor = fmqRequestChannel->getDesc(); + return std::make_pair(std::make_unique(std::move(fmqRequestChannel)), + descriptor); +} + +RequestChannelSender::RequestChannelSender(std::unique_ptr fmqRequestChannel) + : mFmqRequestChannel(std::move(fmqRequestChannel)) {} + +bool RequestChannelSender::send(const V1_0::Request& request, V1_2::MeasureTiming measure, + const std::vector& slots) { + const std::vector serialized = serialize(request, measure, slots); + return sendPacket(serialized); +} + +bool RequestChannelSender::sendPacket(const std::vector& packet) { + if (!mValid) { + return false; + } + + if (packet.size() > mFmqRequestChannel->availableToWrite()) { + LOG(ERROR) + << "RequestChannelSender::sendPacket -- packet size exceeds size available in FMQ"; + return false; + } + + // Always send the packet with "blocking" because this signals the futex and + // unblocks the consumer if it is waiting on the futex. + return mFmqRequestChannel->writeBlocking(packet.data(), packet.size()); +} + +void RequestChannelSender::invalidate() { + mValid = false; +} + +hardware::Return ExecutionBurstController::ExecutionBurstCallback::getMemories( + const hardware::hidl_vec& slots, getMemories_cb cb) { + std::lock_guard guard(mMutex); + + // get all memories + hardware::hidl_vec memories(slots.size()); + std::transform(slots.begin(), slots.end(), memories.begin(), [this](int32_t slot) { + return slot < mMemoryCache.size() ? mMemoryCache[slot] : hardware::hidl_memory{}; + }); + + // ensure all memories are valid + if (!std::all_of(memories.begin(), memories.end(), + [](const hardware::hidl_memory& memory) { return memory.valid(); })) { + cb(V1_0::ErrorStatus::INVALID_ARGUMENT, {}); + return hardware::Void(); + } + + // return successful + cb(V1_0::ErrorStatus::NONE, std::move(memories)); + return hardware::Void(); +} + +std::vector ExecutionBurstController::ExecutionBurstCallback::getSlots( + const hardware::hidl_vec& memories, + const std::vector& keys) { + std::lock_guard guard(mMutex); + + // retrieve (or bind) all slots corresponding to memories + std::vector slots; + slots.reserve(memories.size()); + for (size_t i = 0; i < memories.size(); ++i) { + slots.push_back(getSlotLocked(memories[i], keys[i])); + } + return slots; +} + +std::pair ExecutionBurstController::ExecutionBurstCallback::freeMemory( + intptr_t key) { + std::lock_guard guard(mMutex); + + auto iter = mMemoryIdToSlot.find(key); + if (iter == mMemoryIdToSlot.end()) { + return {false, 0}; + } + const int32_t slot = iter->second; + mMemoryIdToSlot.erase(key); + mMemoryCache[slot] = {}; + mFreeSlots.push(slot); + return {true, slot}; +} + +int32_t ExecutionBurstController::ExecutionBurstCallback::getSlotLocked( + const hardware::hidl_memory& memory, intptr_t key) { + auto iter = mMemoryIdToSlot.find(key); + if (iter == mMemoryIdToSlot.end()) { + const int32_t slot = allocateSlotLocked(); + mMemoryIdToSlot[key] = slot; + mMemoryCache[slot] = memory; + return slot; + } else { + const int32_t slot = iter->second; + return slot; + } +} + +int32_t ExecutionBurstController::ExecutionBurstCallback::allocateSlotLocked() { + constexpr size_t kMaxNumberOfSlots = std::numeric_limits::max(); + + // if there is a free slot, use it + if (mFreeSlots.size() > 0) { + const int32_t slot = mFreeSlots.top(); + mFreeSlots.pop(); + return slot; + } + + // otherwise use a slot for the first time + CHECK(mMemoryCache.size() < kMaxNumberOfSlots) << "Exceeded maximum number of slots!"; + const int32_t slot = static_cast(mMemoryCache.size()); + mMemoryCache.emplace_back(); + + return slot; +} + +std::unique_ptr ExecutionBurstController::create( + const sp& preparedModel, + std::chrono::microseconds pollingTimeWindow) { + // check inputs + if (preparedModel == nullptr) { + LOG(ERROR) << "ExecutionBurstController::create passed a nullptr"; + return nullptr; + } + + // create callback object + sp callback = new ExecutionBurstCallback(); + + // create FMQ objects + auto [requestChannelSenderTemp, requestChannelDescriptor] = + RequestChannelSender::create(kExecutionBurstChannelLength); + auto [resultChannelReceiverTemp, resultChannelDescriptor] = + ResultChannelReceiver::create(kExecutionBurstChannelLength, pollingTimeWindow); + std::shared_ptr requestChannelSender = + std::move(requestChannelSenderTemp); + std::shared_ptr resultChannelReceiver = + std::move(resultChannelReceiverTemp); + + // check FMQ objects + if (!requestChannelSender || !resultChannelReceiver || !requestChannelDescriptor || + !resultChannelDescriptor) { + LOG(ERROR) << "ExecutionBurstController::create failed to create FastMessageQueue"; + return nullptr; + } + + // configure burst + V1_0::ErrorStatus errorStatus; + sp burstContext; + const hardware::Return ret = preparedModel->configureExecutionBurst( + callback, *requestChannelDescriptor, *resultChannelDescriptor, + [&errorStatus, &burstContext](V1_0::ErrorStatus status, + const sp& context) { + errorStatus = status; + burstContext = context; + }); + + // check burst + if (!ret.isOk()) { + LOG(ERROR) << "IPreparedModel::configureExecutionBurst failed with description " + << ret.description(); + return nullptr; + } + if (errorStatus != V1_0::ErrorStatus::NONE) { + LOG(ERROR) << "IPreparedModel::configureExecutionBurst failed with status " + << toString(errorStatus); + return nullptr; + } + if (burstContext == nullptr) { + LOG(ERROR) << "IPreparedModel::configureExecutionBurst returned nullptr for burst"; + return nullptr; + } + + // create death handler object + BurstContextDeathHandler::Callback onDeathCallback = [requestChannelSender, + resultChannelReceiver] { + requestChannelSender->invalidate(); + resultChannelReceiver->invalidate(); + }; + const sp deathHandler = new BurstContextDeathHandler(onDeathCallback); + + // linkToDeath registers a callback that will be invoked on service death to + // proactively handle service crashes. If the linkToDeath call fails, + // asynchronous calls are susceptible to hangs if the service crashes before + // providing the response. + const hardware::Return deathHandlerRet = burstContext->linkToDeath(deathHandler, 0); + if (!deathHandlerRet.isOk() || deathHandlerRet != true) { + LOG(ERROR) << "ExecutionBurstController::create -- Failed to register a death recipient " + "for the IBurstContext object."; + return nullptr; + } + + // make and return controller + return std::make_unique(requestChannelSender, resultChannelReceiver, + burstContext, callback, deathHandler); +} + +ExecutionBurstController::ExecutionBurstController( + const std::shared_ptr& requestChannelSender, + const std::shared_ptr& resultChannelReceiver, + const sp& burstContext, const sp& callback, + const sp& deathHandler) + : mRequestChannelSender(requestChannelSender), + mResultChannelReceiver(resultChannelReceiver), + mBurstContext(burstContext), + mMemoryCache(callback), + mDeathHandler(deathHandler) {} + +ExecutionBurstController::~ExecutionBurstController() { + // It is safe to ignore any errors resulting from this unlinkToDeath call + // because the ExecutionBurstController object is already being destroyed + // and its underlying IBurstContext object is no longer being used by the NN + // runtime. + if (mDeathHandler) { + mBurstContext->unlinkToDeath(mDeathHandler).isOk(); + } +} + +static std::tuple, V1_2::Timing, bool> getExecutionResult( + V1_0::ErrorStatus status, std::vector outputShapes, V1_2::Timing timing, + bool fallback) { + auto [n, checkedOutputShapes, checkedTiming] = + getExecutionResult(convertToV1_3(status), std::move(outputShapes), timing); + return {n, convertToV1_2(checkedOutputShapes), convertToV1_2(checkedTiming), fallback}; +} + +std::tuple, V1_2::Timing, bool> +ExecutionBurstController::compute(const V1_0::Request& request, V1_2::MeasureTiming measure, + const std::vector& memoryIds) { + // This is the first point when we know an execution is occurring, so begin + // to collect systraces. Note that the first point we can begin collecting + // systraces in ExecutionBurstServer is when the RequestChannelReceiver + // realizes there is data in the FMQ, so ExecutionBurstServer collects + // systraces at different points in the code. + NNTRACE_FULL(NNTRACE_LAYER_IPC, NNTRACE_PHASE_EXECUTION, "ExecutionBurstController::compute"); + + std::lock_guard guard(mMutex); + + // send request packet + const std::vector slots = mMemoryCache->getSlots(request.pools, memoryIds); + const bool success = mRequestChannelSender->send(request, measure, slots); + if (!success) { + LOG(ERROR) << "Error sending FMQ packet"; + // only use fallback execution path if the packet could not be sent + return getExecutionResult(V1_0::ErrorStatus::GENERAL_FAILURE, {}, kNoTiming12, + /*fallback=*/true); + } + + // get result packet + const auto result = mResultChannelReceiver->getBlocking(); + if (!result) { + LOG(ERROR) << "Error retrieving FMQ packet"; + // only use fallback execution path if the packet could not be sent + return getExecutionResult(V1_0::ErrorStatus::GENERAL_FAILURE, {}, kNoTiming12, + /*fallback=*/false); + } + + // unpack results and return (only use fallback execution path if the + // packet could not be sent) + auto [status, outputShapes, timing] = std::move(*result); + return getExecutionResult(status, std::move(outputShapes), timing, /*fallback=*/false); +} + +void ExecutionBurstController::freeMemory(intptr_t key) { + std::lock_guard guard(mMutex); + + bool valid; + int32_t slot; + std::tie(valid, slot) = mMemoryCache->freeMemory(key); + if (valid) { + mBurstContext->freeMemory(slot).isOk(); + } +} + +} // namespace android::nn diff --git a/neuralnetworks/1.2/utils/src/ExecutionBurstServer.cpp b/neuralnetworks/1.2/utils/src/ExecutionBurstServer.cpp new file mode 100644 index 0000000000..848c77b284 --- /dev/null +++ b/neuralnetworks/1.2/utils/src/ExecutionBurstServer.cpp @@ -0,0 +1,646 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "ExecutionBurstServer" + +#include "ExecutionBurstServer.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "HalInterfaces.h" +#include "Tracing.h" + +namespace android::nn { +namespace { + +using hardware::MQDescriptorSync; +using V1_2::FmqRequestDatum; +using V1_2::FmqResultDatum; +using V1_2::IBurstCallback; +using V1_2::IBurstContext; + +constexpr V1_2::Timing kNoTiming = {std::numeric_limits::max(), + std::numeric_limits::max()}; + +// DefaultBurstExecutorWithCache adapts an IPreparedModel so that it can be +// used as an IBurstExecutorWithCache. Specifically, the cache simply stores the +// hidl_memory object, and the execution forwards calls to the provided +// IPreparedModel's "executeSynchronously" method. With this class, hidl_memory +// must be mapped and unmapped for each execution. +class DefaultBurstExecutorWithCache : public ExecutionBurstServer::IBurstExecutorWithCache { + public: + DefaultBurstExecutorWithCache(V1_2::IPreparedModel* preparedModel) + : mpPreparedModel(preparedModel) {} + + bool isCacheEntryPresent(int32_t slot) const override { + const auto it = mMemoryCache.find(slot); + return (it != mMemoryCache.end()) && it->second.valid(); + } + + void addCacheEntry(const hardware::hidl_memory& memory, int32_t slot) override { + mMemoryCache[slot] = memory; + } + + void removeCacheEntry(int32_t slot) override { mMemoryCache.erase(slot); } + + std::tuple, V1_2::Timing> execute( + const V1_0::Request& request, const std::vector& slots, + V1_2::MeasureTiming measure) override { + // convert slots to pools + hardware::hidl_vec pools(slots.size()); + std::transform(slots.begin(), slots.end(), pools.begin(), + [this](int32_t slot) { return mMemoryCache[slot]; }); + + // create full request + V1_0::Request fullRequest = request; + fullRequest.pools = std::move(pools); + + // setup execution + V1_0::ErrorStatus returnedStatus = V1_0::ErrorStatus::GENERAL_FAILURE; + hardware::hidl_vec returnedOutputShapes; + V1_2::Timing returnedTiming; + auto cb = [&returnedStatus, &returnedOutputShapes, &returnedTiming]( + V1_0::ErrorStatus status, + const hardware::hidl_vec& outputShapes, + const V1_2::Timing& timing) { + returnedStatus = status; + returnedOutputShapes = outputShapes; + returnedTiming = timing; + }; + + // execute + const hardware::Return ret = + mpPreparedModel->executeSynchronously(fullRequest, measure, cb); + if (!ret.isOk() || returnedStatus != V1_0::ErrorStatus::NONE) { + LOG(ERROR) << "IPreparedModelAdapter::execute -- Error executing"; + return {returnedStatus, std::move(returnedOutputShapes), kNoTiming}; + } + + return std::make_tuple(returnedStatus, std::move(returnedOutputShapes), returnedTiming); + } + + private: + V1_2::IPreparedModel* const mpPreparedModel; + std::map mMemoryCache; +}; + +} // anonymous namespace + +// serialize result +std::vector serialize(V1_0::ErrorStatus errorStatus, + const std::vector& outputShapes, + V1_2::Timing timing) { + // count how many elements need to be sent for a request + size_t count = 2 + outputShapes.size(); + for (const auto& outputShape : outputShapes) { + count += outputShape.dimensions.size(); + } + + // create buffer to temporarily store elements + std::vector data; + data.reserve(count); + + // package packetInfo + { + FmqResultDatum datum; + datum.packetInformation({/*.packetSize=*/static_cast(count), + /*.errorStatus=*/errorStatus, + /*.numberOfOperands=*/static_cast(outputShapes.size())}); + data.push_back(datum); + } + + // package output shape data + for (const auto& operand : outputShapes) { + // package operand information + FmqResultDatum::OperandInformation info{}; + info.isSufficient = operand.isSufficient; + info.numberOfDimensions = static_cast(operand.dimensions.size()); + + FmqResultDatum datum; + datum.operandInformation(info); + data.push_back(datum); + + // package operand dimensions + for (uint32_t dimension : operand.dimensions) { + FmqResultDatum datum; + datum.operandDimensionValue(dimension); + data.push_back(datum); + } + } + + // package executionTiming + { + FmqResultDatum datum; + datum.executionTiming(timing); + data.push_back(datum); + } + + // return result + return data; +} + +// deserialize request +std::optional, V1_2::MeasureTiming>> deserialize( + const std::vector& data) { + using discriminator = FmqRequestDatum::hidl_discriminator; + + size_t index = 0; + + // validate packet information + if (data.size() == 0 || data[index].getDiscriminator() != discriminator::packetInformation) { + LOG(ERROR) << "FMQ Request packet ill-formed"; + return std::nullopt; + } + + // unpackage packet information + const FmqRequestDatum::PacketInformation& packetInfo = data[index].packetInformation(); + index++; + const uint32_t packetSize = packetInfo.packetSize; + const uint32_t numberOfInputOperands = packetInfo.numberOfInputOperands; + const uint32_t numberOfOutputOperands = packetInfo.numberOfOutputOperands; + const uint32_t numberOfPools = packetInfo.numberOfPools; + + // verify packet size + if (data.size() != packetSize) { + LOG(ERROR) << "FMQ Request packet ill-formed"; + return std::nullopt; + } + + // unpackage input operands + std::vector inputs; + inputs.reserve(numberOfInputOperands); + for (size_t operand = 0; operand < numberOfInputOperands; ++operand) { + // validate input operand information + if (data[index].getDiscriminator() != discriminator::inputOperandInformation) { + LOG(ERROR) << "FMQ Request packet ill-formed"; + return std::nullopt; + } + + // unpackage operand information + const FmqRequestDatum::OperandInformation& operandInfo = + data[index].inputOperandInformation(); + index++; + const bool hasNoValue = operandInfo.hasNoValue; + const V1_0::DataLocation location = operandInfo.location; + const uint32_t numberOfDimensions = operandInfo.numberOfDimensions; + + // unpackage operand dimensions + std::vector dimensions; + dimensions.reserve(numberOfDimensions); + for (size_t i = 0; i < numberOfDimensions; ++i) { + // validate dimension + if (data[index].getDiscriminator() != discriminator::inputOperandDimensionValue) { + LOG(ERROR) << "FMQ Request packet ill-formed"; + return std::nullopt; + } + + // unpackage dimension + const uint32_t dimension = data[index].inputOperandDimensionValue(); + index++; + + // store result + dimensions.push_back(dimension); + } + + // store result + inputs.push_back( + {/*.hasNoValue=*/hasNoValue, /*.location=*/location, /*.dimensions=*/dimensions}); + } + + // unpackage output operands + std::vector outputs; + outputs.reserve(numberOfOutputOperands); + for (size_t operand = 0; operand < numberOfOutputOperands; ++operand) { + // validate output operand information + if (data[index].getDiscriminator() != discriminator::outputOperandInformation) { + LOG(ERROR) << "FMQ Request packet ill-formed"; + return std::nullopt; + } + + // unpackage operand information + const FmqRequestDatum::OperandInformation& operandInfo = + data[index].outputOperandInformation(); + index++; + const bool hasNoValue = operandInfo.hasNoValue; + const V1_0::DataLocation location = operandInfo.location; + const uint32_t numberOfDimensions = operandInfo.numberOfDimensions; + + // unpackage operand dimensions + std::vector dimensions; + dimensions.reserve(numberOfDimensions); + for (size_t i = 0; i < numberOfDimensions; ++i) { + // validate dimension + if (data[index].getDiscriminator() != discriminator::outputOperandDimensionValue) { + LOG(ERROR) << "FMQ Request packet ill-formed"; + return std::nullopt; + } + + // unpackage dimension + const uint32_t dimension = data[index].outputOperandDimensionValue(); + index++; + + // store result + dimensions.push_back(dimension); + } + + // store result + outputs.push_back( + {/*.hasNoValue=*/hasNoValue, /*.location=*/location, /*.dimensions=*/dimensions}); + } + + // unpackage pools + std::vector slots; + slots.reserve(numberOfPools); + for (size_t pool = 0; pool < numberOfPools; ++pool) { + // validate input operand information + if (data[index].getDiscriminator() != discriminator::poolIdentifier) { + LOG(ERROR) << "FMQ Request packet ill-formed"; + return std::nullopt; + } + + // unpackage operand information + const int32_t poolId = data[index].poolIdentifier(); + index++; + + // store result + slots.push_back(poolId); + } + + // validate measureTiming + if (data[index].getDiscriminator() != discriminator::measureTiming) { + LOG(ERROR) << "FMQ Request packet ill-formed"; + return std::nullopt; + } + + // unpackage measureTiming + const V1_2::MeasureTiming measure = data[index].measureTiming(); + index++; + + // validate packet information + if (index != packetSize) { + LOG(ERROR) << "FMQ Result packet ill-formed"; + return std::nullopt; + } + + // return request + V1_0::Request request = {/*.inputs=*/inputs, /*.outputs=*/outputs, /*.pools=*/{}}; + return std::make_tuple(std::move(request), std::move(slots), measure); +} + +// RequestChannelReceiver methods + +std::unique_ptr RequestChannelReceiver::create( + const FmqRequestDescriptor& requestChannel, std::chrono::microseconds pollingTimeWindow) { + std::unique_ptr fmqRequestChannel = + std::make_unique(requestChannel); + + if (!fmqRequestChannel->isValid()) { + LOG(ERROR) << "Unable to create RequestChannelReceiver"; + return nullptr; + } + if (fmqRequestChannel->getEventFlagWord() == nullptr) { + LOG(ERROR) + << "RequestChannelReceiver::create was passed an MQDescriptor without an EventFlag"; + return nullptr; + } + + return std::make_unique(std::move(fmqRequestChannel), + pollingTimeWindow); +} + +RequestChannelReceiver::RequestChannelReceiver(std::unique_ptr fmqRequestChannel, + std::chrono::microseconds pollingTimeWindow) + : mFmqRequestChannel(std::move(fmqRequestChannel)), kPollingTimeWindow(pollingTimeWindow) {} + +std::optional, V1_2::MeasureTiming>> +RequestChannelReceiver::getBlocking() { + const auto packet = getPacketBlocking(); + if (!packet) { + return std::nullopt; + } + + return deserialize(*packet); +} + +void RequestChannelReceiver::invalidate() { + mTeardown = true; + + // force unblock + // ExecutionBurstServer is by default waiting on a request packet. If the + // client process destroys its burst object, the server may still be waiting + // on the futex. This force unblock wakes up any thread waiting on the + // futex. + // TODO: look for a different/better way to signal/notify the futex to wake + // up any thread waiting on it + FmqRequestDatum datum; + datum.packetInformation({/*.packetSize=*/0, /*.numberOfInputOperands=*/0, + /*.numberOfOutputOperands=*/0, /*.numberOfPools=*/0}); + mFmqRequestChannel->writeBlocking(&datum, 1); +} + +std::optional> RequestChannelReceiver::getPacketBlocking() { + if (mTeardown) { + return std::nullopt; + } + + // First spend time polling if results are available in FMQ instead of + // waiting on the futex. Polling is more responsive (yielding lower + // latencies), but can take up more power, so only poll for a limited period + // of time. + + auto& getCurrentTime = std::chrono::high_resolution_clock::now; + const auto timeToStopPolling = getCurrentTime() + kPollingTimeWindow; + + while (getCurrentTime() < timeToStopPolling) { + // if class is being torn down, immediately return + if (mTeardown.load(std::memory_order_relaxed)) { + return std::nullopt; + } + + // Check if data is available. If it is, immediately retrieve it and + // return. + const size_t available = mFmqRequestChannel->availableToRead(); + if (available > 0) { + // This is the first point when we know an execution is occurring, + // so begin to collect systraces. Note that a similar systrace does + // not exist at the corresponding point in + // ResultChannelReceiver::getPacketBlocking because the execution is + // already in flight. + NNTRACE_FULL(NNTRACE_LAYER_IPC, NNTRACE_PHASE_EXECUTION, + "ExecutionBurstServer getting packet"); + std::vector packet(available); + const bool success = mFmqRequestChannel->read(packet.data(), available); + if (!success) { + LOG(ERROR) << "Error receiving packet"; + return std::nullopt; + } + return std::make_optional(std::move(packet)); + } + } + + // If we get to this point, we either stopped polling because it was taking + // too long or polling was not allowed. Instead, perform a blocking call + // which uses a futex to save power. + + // wait for request packet and read first element of request packet + FmqRequestDatum datum; + bool success = mFmqRequestChannel->readBlocking(&datum, 1); + + // This is the first point when we know an execution is occurring, so begin + // to collect systraces. Note that a similar systrace does not exist at the + // corresponding point in ResultChannelReceiver::getPacketBlocking because + // the execution is already in flight. + NNTRACE_FULL(NNTRACE_LAYER_IPC, NNTRACE_PHASE_EXECUTION, "ExecutionBurstServer getting packet"); + + // retrieve remaining elements + // NOTE: all of the data is already available at this point, so there's no + // need to do a blocking wait to wait for more data. This is known because + // in FMQ, all writes are published (made available) atomically. Currently, + // the producer always publishes the entire packet in one function call, so + // if the first element of the packet is available, the remaining elements + // are also available. + const size_t count = mFmqRequestChannel->availableToRead(); + std::vector packet(count + 1); + std::memcpy(&packet.front(), &datum, sizeof(datum)); + success &= mFmqRequestChannel->read(packet.data() + 1, count); + + // terminate loop + if (mTeardown) { + return std::nullopt; + } + + // ensure packet was successfully received + if (!success) { + LOG(ERROR) << "Error receiving packet"; + return std::nullopt; + } + + return std::make_optional(std::move(packet)); +} + +// ResultChannelSender methods + +std::unique_ptr ResultChannelSender::create( + const FmqResultDescriptor& resultChannel) { + std::unique_ptr fmqResultChannel = + std::make_unique(resultChannel); + + if (!fmqResultChannel->isValid()) { + LOG(ERROR) << "Unable to create RequestChannelSender"; + return nullptr; + } + if (fmqResultChannel->getEventFlagWord() == nullptr) { + LOG(ERROR) << "ResultChannelSender::create was passed an MQDescriptor without an EventFlag"; + return nullptr; + } + + return std::make_unique(std::move(fmqResultChannel)); +} + +ResultChannelSender::ResultChannelSender(std::unique_ptr fmqResultChannel) + : mFmqResultChannel(std::move(fmqResultChannel)) {} + +bool ResultChannelSender::send(V1_0::ErrorStatus errorStatus, + const std::vector& outputShapes, + V1_2::Timing timing) { + const std::vector serialized = serialize(errorStatus, outputShapes, timing); + return sendPacket(serialized); +} + +bool ResultChannelSender::sendPacket(const std::vector& packet) { + if (packet.size() > mFmqResultChannel->availableToWrite()) { + LOG(ERROR) + << "ResultChannelSender::sendPacket -- packet size exceeds size available in FMQ"; + const std::vector errorPacket = + serialize(V1_0::ErrorStatus::GENERAL_FAILURE, {}, kNoTiming); + + // Always send the packet with "blocking" because this signals the futex + // and unblocks the consumer if it is waiting on the futex. + return mFmqResultChannel->writeBlocking(errorPacket.data(), errorPacket.size()); + } + + // Always send the packet with "blocking" because this signals the futex and + // unblocks the consumer if it is waiting on the futex. + return mFmqResultChannel->writeBlocking(packet.data(), packet.size()); +} + +// ExecutionBurstServer methods + +sp ExecutionBurstServer::create( + const sp& callback, const MQDescriptorSync& requestChannel, + const MQDescriptorSync& resultChannel, + std::shared_ptr executorWithCache, + std::chrono::microseconds pollingTimeWindow) { + // check inputs + if (callback == nullptr || executorWithCache == nullptr) { + LOG(ERROR) << "ExecutionBurstServer::create passed a nullptr"; + return nullptr; + } + + // create FMQ objects + std::unique_ptr requestChannelReceiver = + RequestChannelReceiver::create(requestChannel, pollingTimeWindow); + std::unique_ptr resultChannelSender = + ResultChannelSender::create(resultChannel); + + // check FMQ objects + if (!requestChannelReceiver || !resultChannelSender) { + LOG(ERROR) << "ExecutionBurstServer::create failed to create FastMessageQueue"; + return nullptr; + } + + // make and return context + return new ExecutionBurstServer(callback, std::move(requestChannelReceiver), + std::move(resultChannelSender), std::move(executorWithCache)); +} + +sp ExecutionBurstServer::create( + const sp& callback, const MQDescriptorSync& requestChannel, + const MQDescriptorSync& resultChannel, V1_2::IPreparedModel* preparedModel, + std::chrono::microseconds pollingTimeWindow) { + // check relevant input + if (preparedModel == nullptr) { + LOG(ERROR) << "ExecutionBurstServer::create passed a nullptr"; + return nullptr; + } + + // adapt IPreparedModel to have caching + const std::shared_ptr preparedModelAdapter = + std::make_shared(preparedModel); + + // make and return context + return ExecutionBurstServer::create(callback, requestChannel, resultChannel, + preparedModelAdapter, pollingTimeWindow); +} + +ExecutionBurstServer::ExecutionBurstServer( + const sp& callback, std::unique_ptr requestChannel, + std::unique_ptr resultChannel, + std::shared_ptr executorWithCache) + : mCallback(callback), + mRequestChannelReceiver(std::move(requestChannel)), + mResultChannelSender(std::move(resultChannel)), + mExecutorWithCache(std::move(executorWithCache)) { + // TODO: highly document the threading behavior of this class + mWorker = std::thread([this] { task(); }); +} + +ExecutionBurstServer::~ExecutionBurstServer() { + // set teardown flag + mTeardown = true; + mRequestChannelReceiver->invalidate(); + + // wait for task thread to end + mWorker.join(); +} + +hardware::Return ExecutionBurstServer::freeMemory(int32_t slot) { + std::lock_guard hold(mMutex); + mExecutorWithCache->removeCacheEntry(slot); + return hardware::Void(); +} + +void ExecutionBurstServer::ensureCacheEntriesArePresentLocked(const std::vector& slots) { + const auto slotIsKnown = [this](int32_t slot) { + return mExecutorWithCache->isCacheEntryPresent(slot); + }; + + // find unique unknown slots + std::vector unknownSlots = slots; + auto unknownSlotsEnd = unknownSlots.end(); + std::sort(unknownSlots.begin(), unknownSlotsEnd); + unknownSlotsEnd = std::unique(unknownSlots.begin(), unknownSlotsEnd); + unknownSlotsEnd = std::remove_if(unknownSlots.begin(), unknownSlotsEnd, slotIsKnown); + unknownSlots.erase(unknownSlotsEnd, unknownSlots.end()); + + // quick-exit if all slots are known + if (unknownSlots.empty()) { + return; + } + + V1_0::ErrorStatus errorStatus = V1_0::ErrorStatus::GENERAL_FAILURE; + std::vector returnedMemories; + auto cb = [&errorStatus, &returnedMemories]( + V1_0::ErrorStatus status, + const hardware::hidl_vec& memories) { + errorStatus = status; + returnedMemories = memories; + }; + + const hardware::Return ret = mCallback->getMemories(unknownSlots, cb); + + if (!ret.isOk() || errorStatus != V1_0::ErrorStatus::NONE || + returnedMemories.size() != unknownSlots.size()) { + LOG(ERROR) << "Error retrieving memories"; + return; + } + + // add memories to unknown slots + for (size_t i = 0; i < unknownSlots.size(); ++i) { + mExecutorWithCache->addCacheEntry(returnedMemories[i], unknownSlots[i]); + } +} + +void ExecutionBurstServer::task() { + // loop until the burst object is being destroyed + while (!mTeardown) { + // receive request + auto arguments = mRequestChannelReceiver->getBlocking(); + + // if the request packet was not properly received, return a generic + // error and skip the execution + // + // if the burst is being torn down, skip the execution so the "task" + // function can end + if (!arguments) { + if (!mTeardown) { + mResultChannelSender->send(V1_0::ErrorStatus::GENERAL_FAILURE, {}, kNoTiming); + } + continue; + } + + // otherwise begin tracing execution + NNTRACE_FULL(NNTRACE_LAYER_IPC, NNTRACE_PHASE_EXECUTION, + "ExecutionBurstServer getting memory, executing, and returning results"); + + // unpack the arguments; types are Request, std::vector, and + // MeasureTiming, respectively + const auto [requestWithoutPools, slotsOfPools, measure] = std::move(*arguments); + + // ensure executor with cache has required memory + std::lock_guard hold(mMutex); + ensureCacheEntriesArePresentLocked(slotsOfPools); + + // perform computation; types are ErrorStatus, hidl_vec, + // and Timing, respectively + const auto [errorStatus, outputShapes, returnedTiming] = + mExecutorWithCache->execute(requestWithoutPools, slotsOfPools, measure); + + // return result + mResultChannelSender->send(errorStatus, outputShapes, returnedTiming); + } +} + +} // namespace android::nn -- GitLab From 297108360f2f97ec09d261bb10c5af0fa41e827a Mon Sep 17 00:00:00 2001 From: Michael Butler Date: Fri, 8 Jan 2021 17:21:27 -0800 Subject: [PATCH 378/790] Relocate NN burst utility to ExecutionBurstUtils This CL relocates serialize, deserialize, RequestChannelSender, RequestChannelReceiver, ResultChannelSender, and ResultChannelReceiver to ExecutionBurstUtils. Bug: 177267324 Test: mma Change-Id: Ie1fffdc89dc5bd325d3cd7806d2de632b8513cf9 --- .../nnapi/hal/1.2/ExecutionBurstController.h | 164 +--- .../nnapi/hal/1.2/ExecutionBurstServer.h | 139 +--- .../nnapi/hal/1.2/ExecutionBurstUtils.h | 335 ++++++++ .../utils/src/ExecutionBurstController.cpp | 334 +------- .../1.2/utils/src/ExecutionBurstServer.cpp | 388 +-------- .../1.2/utils/src/ExecutionBurstUtils.cpp | 749 ++++++++++++++++++ 6 files changed, 1090 insertions(+), 1019 deletions(-) create mode 100644 neuralnetworks/1.2/utils/include/nnapi/hal/1.2/ExecutionBurstUtils.h create mode 100644 neuralnetworks/1.2/utils/src/ExecutionBurstUtils.cpp diff --git a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/ExecutionBurstController.h b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/ExecutionBurstController.h index e00ab82d69..5356a912bd 100644 --- a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/ExecutionBurstController.h +++ b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/ExecutionBurstController.h @@ -17,6 +17,8 @@ #ifndef ANDROID_FRAMEWORKS_ML_NN_COMMON_EXECUTION_BURST_CONTROLLER_H #define ANDROID_FRAMEWORKS_ML_NN_COMMON_EXECUTION_BURST_CONTROLLER_H +#include "ExecutionBurstUtils.h" + #include #include #include @@ -39,168 +41,6 @@ namespace android::nn { -/** - * Number of elements in the FMQ. - */ -constexpr const size_t kExecutionBurstChannelLength = 1024; - -/** - * Function to serialize a request. - * - * Prefer calling RequestChannelSender::send. - * - * @param request Request object without the pool information. - * @param measure Whether to collect timing information for the execution. - * @param memoryIds Slot identifiers corresponding to memory resources for the - * request. - * @return Serialized FMQ request data. - */ -std::vector serialize( - const hardware::neuralnetworks::V1_0::Request& request, - hardware::neuralnetworks::V1_2::MeasureTiming measure, const std::vector& slots); - -/** - * Deserialize the FMQ result data. - * - * The three resulting fields are the status of the execution, the dynamic - * shapes of the output tensors, and the timing information of the execution. - * - * @param data Serialized FMQ result data. - * @return Result object if successfully deserialized, std::nullopt otherwise. - */ -std::optional, - hardware::neuralnetworks::V1_2::Timing>> -deserialize(const std::vector& data); - -/** - * Convert result code to error status. - * - * @param resultCode Result code to be converted. - * @return ErrorStatus Resultant error status. - */ -hardware::neuralnetworks::V1_0::ErrorStatus legacyConvertResultCodeToErrorStatus(int resultCode); - -/** - * ResultChannelReceiver is responsible for waiting on the channel until the - * packet is available, extracting the packet from the channel, and - * deserializing the packet. - * - * Because the receiver can wait on a packet that may never come (e.g., because - * the sending side of the packet has been closed), this object can be - * invalidated, unblocking the receiver. - */ -class ResultChannelReceiver { - using FmqResultDescriptor = - hardware::MQDescriptorSync; - using FmqResultChannel = hardware::MessageQueue; - - public: - /** - * Create the receiving end of a result channel. - * - * Prefer this call over the constructor. - * - * @param channelLength Number of elements in the FMQ. - * @param pollingTimeWindow How much time (in microseconds) the - * ResultChannelReceiver is allowed to poll the FMQ before waiting on - * the blocking futex. Polling may result in lower latencies at the - * potential cost of more power usage. - * @return A pair of ResultChannelReceiver and the FMQ descriptor on - * successful creation, both nullptr otherwise. - */ - static std::pair, const FmqResultDescriptor*> create( - size_t channelLength, std::chrono::microseconds pollingTimeWindow); - - /** - * Get the result from the channel. - * - * This method will block until either: - * 1) The packet has been retrieved, or - * 2) The receiver has been invalidated - * - * @return Result object if successfully received, std::nullopt if error or - * if the receiver object was invalidated. - */ - std::optional, - hardware::neuralnetworks::V1_2::Timing>> - getBlocking(); - - /** - * Method to mark the channel as invalid, unblocking any current or future - * calls to ResultChannelReceiver::getBlocking. - */ - void invalidate(); - - // prefer calling ResultChannelReceiver::getBlocking - std::optional> getPacketBlocking(); - - ResultChannelReceiver(std::unique_ptr fmqResultChannel, - std::chrono::microseconds pollingTimeWindow); - - private: - const std::unique_ptr mFmqResultChannel; - std::atomic mValid{true}; - const std::chrono::microseconds kPollingTimeWindow; -}; - -/** - * RequestChannelSender is responsible for serializing the result packet of - * information, sending it on the result channel, and signaling that the data is - * available. - */ -class RequestChannelSender { - using FmqRequestDescriptor = - hardware::MQDescriptorSync; - using FmqRequestChannel = - hardware::MessageQueue; - - public: - /** - * Create the sending end of a request channel. - * - * Prefer this call over the constructor. - * - * @param channelLength Number of elements in the FMQ. - * @return A pair of ResultChannelReceiver and the FMQ descriptor on - * successful creation, both nullptr otherwise. - */ - static std::pair, const FmqRequestDescriptor*> create( - size_t channelLength); - - /** - * Send the request to the channel. - * - * @param request Request object without the pool information. - * @param measure Whether to collect timing information for the execution. - * @param memoryIds Slot identifiers corresponding to memory resources for - * the request. - * @return 'true' on successful send, 'false' otherwise. - */ - bool send(const hardware::neuralnetworks::V1_0::Request& request, - hardware::neuralnetworks::V1_2::MeasureTiming measure, - const std::vector& slots); - - /** - * Method to mark the channel as invalid, causing all future calls to - * RequestChannelSender::send to immediately return false without attempting - * to send a message across the FMQ. - */ - void invalidate(); - - // prefer calling RequestChannelSender::send - bool sendPacket(const std::vector& packet); - - RequestChannelSender(std::unique_ptr fmqRequestChannel); - - private: - const std::unique_ptr mFmqRequestChannel; - std::atomic mValid{true}; -}; - /** * The ExecutionBurstController class manages both the serialization and * deserialization of data across FMQ, making it appear to the runtime as a diff --git a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/ExecutionBurstServer.h b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/ExecutionBurstServer.h index 2c7d6540de..2e109b2de7 100644 --- a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/ExecutionBurstServer.h +++ b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/ExecutionBurstServer.h @@ -17,6 +17,8 @@ #ifndef ANDROID_FRAMEWORKS_ML_NN_COMMON_EXECUTION_BURST_SERVER_H #define ANDROID_FRAMEWORKS_ML_NN_COMMON_EXECUTION_BURST_SERVER_H +#include "ExecutionBurstUtils.h" + #include #include #include @@ -36,143 +38,6 @@ namespace android::nn { -using FmqRequestDescriptor = - hardware::MQDescriptorSync; -using FmqResultDescriptor = - hardware::MQDescriptorSync; - -/** - * Function to serialize results. - * - * Prefer calling ResultChannelSender::send. - * - * @param errorStatus Status of the execution. - * @param outputShapes Dynamic shapes of the output tensors. - * @param timing Timing information of the execution. - * @return Serialized FMQ result data. - */ -std::vector serialize( - hardware::neuralnetworks::V1_0::ErrorStatus errorStatus, - const std::vector& outputShapes, - hardware::neuralnetworks::V1_2::Timing timing); - -/** - * Deserialize the FMQ request data. - * - * The three resulting fields are the Request object (where Request::pools is - * empty), slot identifiers (which are stand-ins for Request::pools), and - * whether timing information must be collected for the run. - * - * @param data Serialized FMQ request data. - * @return Request object if successfully deserialized, std::nullopt otherwise. - */ -std::optional, - hardware::neuralnetworks::V1_2::MeasureTiming>> -deserialize(const std::vector& data); - -/** - * RequestChannelReceiver is responsible for waiting on the channel until the - * packet is available, extracting the packet from the channel, and - * deserializing the packet. - * - * Because the receiver can wait on a packet that may never come (e.g., because - * the sending side of the packet has been closed), this object can be - * invalidated, unblocking the receiver. - */ -class RequestChannelReceiver { - using FmqRequestChannel = - hardware::MessageQueue; - - public: - /** - * Create the receiving end of a request channel. - * - * Prefer this call over the constructor. - * - * @param requestChannel Descriptor for the request channel. - * @param pollingTimeWindow How much time (in microseconds) the - * RequestChannelReceiver is allowed to poll the FMQ before waiting on - * the blocking futex. Polling may result in lower latencies at the - * potential cost of more power usage. - * @return RequestChannelReceiver on successful creation, nullptr otherwise. - */ - static std::unique_ptr create( - const FmqRequestDescriptor& requestChannel, - std::chrono::microseconds pollingTimeWindow); - - /** - * Get the request from the channel. - * - * This method will block until either: - * 1) The packet has been retrieved, or - * 2) The receiver has been invalidated - * - * @return Request object if successfully received, std::nullopt if error or - * if the receiver object was invalidated. - */ - std::optional, - hardware::neuralnetworks::V1_2::MeasureTiming>> - getBlocking(); - - /** - * Method to mark the channel as invalid, unblocking any current or future - * calls to RequestChannelReceiver::getBlocking. - */ - void invalidate(); - - RequestChannelReceiver(std::unique_ptr fmqRequestChannel, - std::chrono::microseconds pollingTimeWindow); - - private: - std::optional> getPacketBlocking(); - - const std::unique_ptr mFmqRequestChannel; - std::atomic mTeardown{false}; - const std::chrono::microseconds kPollingTimeWindow; -}; - -/** - * ResultChannelSender is responsible for serializing the result packet of - * information, sending it on the result channel, and signaling that the data is - * available. - */ -class ResultChannelSender { - using FmqResultChannel = hardware::MessageQueue; - - public: - /** - * Create the sending end of a result channel. - * - * Prefer this call over the constructor. - * - * @param resultChannel Descriptor for the result channel. - * @return ResultChannelSender on successful creation, nullptr otherwise. - */ - static std::unique_ptr create(const FmqResultDescriptor& resultChannel); - - /** - * Send the result to the channel. - * - * @param errorStatus Status of the execution. - * @param outputShapes Dynamic shapes of the output tensors. - * @param timing Timing information of the execution. - * @return 'true' on successful send, 'false' otherwise. - */ - bool send(hardware::neuralnetworks::V1_0::ErrorStatus errorStatus, - const std::vector& outputShapes, - hardware::neuralnetworks::V1_2::Timing timing); - - // prefer calling ResultChannelSender::send - bool sendPacket(const std::vector& packet); - - ResultChannelSender(std::unique_ptr fmqResultChannel); - - private: - const std::unique_ptr mFmqResultChannel; -}; - /** * The ExecutionBurstServer class is responsible for waiting for and * deserializing a request object from a FMQ, performing the inference, and diff --git a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/ExecutionBurstUtils.h b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/ExecutionBurstUtils.h new file mode 100644 index 0000000000..8a4159122e --- /dev/null +++ b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/ExecutionBurstUtils.h @@ -0,0 +1,335 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_2_UTILS_EXECUTION_BURST_UTILS_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_2_UTILS_EXECUTION_BURST_UTILS_H + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::V1_2::utils { + +/** + * Number of elements in the FMQ. + */ +constexpr const size_t kExecutionBurstChannelLength = 1024; + +using FmqRequestDescriptor = MQDescriptorSync; +using FmqResultDescriptor = MQDescriptorSync; + +/** + * Function to serialize a request. + * + * Prefer calling RequestChannelSender::send. + * + * @param request Request object without the pool information. + * @param measure Whether to collect timing information for the execution. + * @param memoryIds Slot identifiers corresponding to memory resources for the + * request. + * @return Serialized FMQ request data. + */ +std::vector serialize( + const hardware::neuralnetworks::V1_0::Request& request, + hardware::neuralnetworks::V1_2::MeasureTiming measure, const std::vector& slots); + +/** + * Deserialize the FMQ request data. + * + * The three resulting fields are the Request object (where Request::pools is + * empty), slot identifiers (which are stand-ins for Request::pools), and + * whether timing information must be collected for the run. + * + * @param data Serialized FMQ request data. + * @return Request object if successfully deserialized, std::nullopt otherwise. + */ +std::optional, + hardware::neuralnetworks::V1_2::MeasureTiming>> +deserialize(const std::vector& data); + +/** + * Function to serialize results. + * + * Prefer calling ResultChannelSender::send. + * + * @param errorStatus Status of the execution. + * @param outputShapes Dynamic shapes of the output tensors. + * @param timing Timing information of the execution. + * @return Serialized FMQ result data. + */ +std::vector serialize( + hardware::neuralnetworks::V1_0::ErrorStatus errorStatus, + const std::vector& outputShapes, + hardware::neuralnetworks::V1_2::Timing timing); + +/** + * Deserialize the FMQ result data. + * + * The three resulting fields are the status of the execution, the dynamic + * shapes of the output tensors, and the timing information of the execution. + * + * @param data Serialized FMQ result data. + * @return Result object if successfully deserialized, std::nullopt otherwise. + */ +std::optional, + hardware::neuralnetworks::V1_2::Timing>> +deserialize(const std::vector& data); + +/** + * Convert result code to error status. + * + * @param resultCode Result code to be converted. + * @return ErrorStatus Resultant error status. + */ +hardware::neuralnetworks::V1_0::ErrorStatus legacyConvertResultCodeToErrorStatus(int resultCode); + +/** + * RequestChannelSender is responsible for serializing the result packet of + * information, sending it on the result channel, and signaling that the data is + * available. + */ +class RequestChannelSender { + using FmqRequestDescriptor = + hardware::MQDescriptorSync; + using FmqRequestChannel = + hardware::MessageQueue; + + public: + /** + * Create the sending end of a request channel. + * + * Prefer this call over the constructor. + * + * @param channelLength Number of elements in the FMQ. + * @return A pair of ResultChannelReceiver and the FMQ descriptor on + * successful creation, both nullptr otherwise. + */ + static std::pair, const FmqRequestDescriptor*> create( + size_t channelLength); + + /** + * Send the request to the channel. + * + * @param request Request object without the pool information. + * @param measure Whether to collect timing information for the execution. + * @param memoryIds Slot identifiers corresponding to memory resources for + * the request. + * @return 'true' on successful send, 'false' otherwise. + */ + bool send(const hardware::neuralnetworks::V1_0::Request& request, + hardware::neuralnetworks::V1_2::MeasureTiming measure, + const std::vector& slots); + + /** + * Method to mark the channel as invalid, causing all future calls to + * RequestChannelSender::send to immediately return false without attempting + * to send a message across the FMQ. + */ + void invalidate(); + + // prefer calling RequestChannelSender::send + bool sendPacket(const std::vector& packet); + + RequestChannelSender(std::unique_ptr fmqRequestChannel); + + private: + const std::unique_ptr mFmqRequestChannel; + std::atomic mValid{true}; +}; + +/** + * RequestChannelReceiver is responsible for waiting on the channel until the + * packet is available, extracting the packet from the channel, and + * deserializing the packet. + * + * Because the receiver can wait on a packet that may never come (e.g., because + * the sending side of the packet has been closed), this object can be + * invalidated, unblocking the receiver. + */ +class RequestChannelReceiver { + using FmqRequestChannel = + hardware::MessageQueue; + + public: + /** + * Create the receiving end of a request channel. + * + * Prefer this call over the constructor. + * + * @param requestChannel Descriptor for the request channel. + * @param pollingTimeWindow How much time (in microseconds) the + * RequestChannelReceiver is allowed to poll the FMQ before waiting on + * the blocking futex. Polling may result in lower latencies at the + * potential cost of more power usage. + * @return RequestChannelReceiver on successful creation, nullptr otherwise. + */ + static std::unique_ptr create( + const FmqRequestDescriptor& requestChannel, + std::chrono::microseconds pollingTimeWindow); + + /** + * Get the request from the channel. + * + * This method will block until either: + * 1) The packet has been retrieved, or + * 2) The receiver has been invalidated + * + * @return Request object if successfully received, std::nullopt if error or + * if the receiver object was invalidated. + */ + std::optional, + hardware::neuralnetworks::V1_2::MeasureTiming>> + getBlocking(); + + /** + * Method to mark the channel as invalid, unblocking any current or future + * calls to RequestChannelReceiver::getBlocking. + */ + void invalidate(); + + RequestChannelReceiver(std::unique_ptr fmqRequestChannel, + std::chrono::microseconds pollingTimeWindow); + + private: + std::optional> getPacketBlocking(); + + const std::unique_ptr mFmqRequestChannel; + std::atomic mTeardown{false}; + const std::chrono::microseconds kPollingTimeWindow; +}; + +/** + * ResultChannelSender is responsible for serializing the result packet of + * information, sending it on the result channel, and signaling that the data is + * available. + */ +class ResultChannelSender { + using FmqResultChannel = hardware::MessageQueue; + + public: + /** + * Create the sending end of a result channel. + * + * Prefer this call over the constructor. + * + * @param resultChannel Descriptor for the result channel. + * @return ResultChannelSender on successful creation, nullptr otherwise. + */ + static std::unique_ptr create(const FmqResultDescriptor& resultChannel); + + /** + * Send the result to the channel. + * + * @param errorStatus Status of the execution. + * @param outputShapes Dynamic shapes of the output tensors. + * @param timing Timing information of the execution. + * @return 'true' on successful send, 'false' otherwise. + */ + bool send(hardware::neuralnetworks::V1_0::ErrorStatus errorStatus, + const std::vector& outputShapes, + hardware::neuralnetworks::V1_2::Timing timing); + + // prefer calling ResultChannelSender::send + bool sendPacket(const std::vector& packet); + + ResultChannelSender(std::unique_ptr fmqResultChannel); + + private: + const std::unique_ptr mFmqResultChannel; +}; + +/** + * ResultChannelReceiver is responsible for waiting on the channel until the + * packet is available, extracting the packet from the channel, and + * deserializing the packet. + * + * Because the receiver can wait on a packet that may never come (e.g., because + * the sending side of the packet has been closed), this object can be + * invalidated, unblocking the receiver. + */ +class ResultChannelReceiver { + using FmqResultDescriptor = + hardware::MQDescriptorSync; + using FmqResultChannel = hardware::MessageQueue; + + public: + /** + * Create the receiving end of a result channel. + * + * Prefer this call over the constructor. + * + * @param channelLength Number of elements in the FMQ. + * @param pollingTimeWindow How much time (in microseconds) the + * ResultChannelReceiver is allowed to poll the FMQ before waiting on + * the blocking futex. Polling may result in lower latencies at the + * potential cost of more power usage. + * @return A pair of ResultChannelReceiver and the FMQ descriptor on + * successful creation, both nullptr otherwise. + */ + static std::pair, const FmqResultDescriptor*> create( + size_t channelLength, std::chrono::microseconds pollingTimeWindow); + + /** + * Get the result from the channel. + * + * This method will block until either: + * 1) The packet has been retrieved, or + * 2) The receiver has been invalidated + * + * @return Result object if successfully received, std::nullopt if error or + * if the receiver object was invalidated. + */ + std::optional, + hardware::neuralnetworks::V1_2::Timing>> + getBlocking(); + + /** + * Method to mark the channel as invalid, unblocking any current or future + * calls to ResultChannelReceiver::getBlocking. + */ + void invalidate(); + + // prefer calling ResultChannelReceiver::getBlocking + std::optional> getPacketBlocking(); + + ResultChannelReceiver(std::unique_ptr fmqResultChannel, + std::chrono::microseconds pollingTimeWindow); + + private: + const std::unique_ptr mFmqResultChannel; + std::atomic mValid{true}; + const std::chrono::microseconds kPollingTimeWindow; +}; + +} // namespace android::hardware::neuralnetworks::V1_2::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_2_UTILS_EXECUTION_BURST_UTILS_H diff --git a/neuralnetworks/1.2/utils/src/ExecutionBurstController.cpp b/neuralnetworks/1.2/utils/src/ExecutionBurstController.cpp index 212863e183..2265861b41 100644 --- a/neuralnetworks/1.2/utils/src/ExecutionBurstController.cpp +++ b/neuralnetworks/1.2/utils/src/ExecutionBurstController.cpp @@ -29,6 +29,7 @@ #include #include +#include "ExecutionBurstUtils.h" #include "HalInterfaces.h" #include "Tracing.h" #include "Utils.h" @@ -36,16 +37,6 @@ namespace android::nn { namespace { -using V1_2::FmqRequestDatum; -using V1_2::FmqResultDatum; -using V1_2::IBurstCallback; -using V1_2::IBurstContext; -using FmqRequestDescriptor = hardware::MQDescriptorSync; -using FmqResultDescriptor = hardware::MQDescriptorSync; - -constexpr V1_2::Timing kNoTiming12 = {std::numeric_limits::max(), - std::numeric_limits::max()}; - class BurstContextDeathHandler : public hardware::hidl_death_recipient { public: using Callback = std::function; @@ -65,329 +56,6 @@ class BurstContextDeathHandler : public hardware::hidl_death_recipient { } // anonymous namespace -// serialize a request into a packet -std::vector serialize(const V1_0::Request& request, V1_2::MeasureTiming measure, - const std::vector& slots) { - // count how many elements need to be sent for a request - size_t count = 2 + request.inputs.size() + request.outputs.size() + request.pools.size(); - for (const auto& input : request.inputs) { - count += input.dimensions.size(); - } - for (const auto& output : request.outputs) { - count += output.dimensions.size(); - } - - // create buffer to temporarily store elements - std::vector data; - data.reserve(count); - - // package packetInfo - { - FmqRequestDatum datum; - datum.packetInformation( - {/*.packetSize=*/static_cast(count), - /*.numberOfInputOperands=*/static_cast(request.inputs.size()), - /*.numberOfOutputOperands=*/static_cast(request.outputs.size()), - /*.numberOfPools=*/static_cast(request.pools.size())}); - data.push_back(datum); - } - - // package input data - for (const auto& input : request.inputs) { - // package operand information - FmqRequestDatum datum; - datum.inputOperandInformation( - {/*.hasNoValue=*/input.hasNoValue, - /*.location=*/input.location, - /*.numberOfDimensions=*/static_cast(input.dimensions.size())}); - data.push_back(datum); - - // package operand dimensions - for (uint32_t dimension : input.dimensions) { - FmqRequestDatum datum; - datum.inputOperandDimensionValue(dimension); - data.push_back(datum); - } - } - - // package output data - for (const auto& output : request.outputs) { - // package operand information - FmqRequestDatum datum; - datum.outputOperandInformation( - {/*.hasNoValue=*/output.hasNoValue, - /*.location=*/output.location, - /*.numberOfDimensions=*/static_cast(output.dimensions.size())}); - data.push_back(datum); - - // package operand dimensions - for (uint32_t dimension : output.dimensions) { - FmqRequestDatum datum; - datum.outputOperandDimensionValue(dimension); - data.push_back(datum); - } - } - - // package pool identifier - for (int32_t slot : slots) { - FmqRequestDatum datum; - datum.poolIdentifier(slot); - data.push_back(datum); - } - - // package measureTiming - { - FmqRequestDatum datum; - datum.measureTiming(measure); - data.push_back(datum); - } - - // return packet - return data; -} - -// deserialize a packet into the result -std::optional, V1_2::Timing>> -deserialize(const std::vector& data) { - using discriminator = FmqResultDatum::hidl_discriminator; - - std::vector outputShapes; - size_t index = 0; - - // validate packet information - if (data.size() == 0 || data[index].getDiscriminator() != discriminator::packetInformation) { - LOG(ERROR) << "FMQ Result packet ill-formed"; - return std::nullopt; - } - - // unpackage packet information - const FmqResultDatum::PacketInformation& packetInfo = data[index].packetInformation(); - index++; - const uint32_t packetSize = packetInfo.packetSize; - const V1_0::ErrorStatus errorStatus = packetInfo.errorStatus; - const uint32_t numberOfOperands = packetInfo.numberOfOperands; - - // verify packet size - if (data.size() != packetSize) { - LOG(ERROR) << "FMQ Result packet ill-formed"; - return std::nullopt; - } - - // unpackage operands - for (size_t operand = 0; operand < numberOfOperands; ++operand) { - // validate operand information - if (data[index].getDiscriminator() != discriminator::operandInformation) { - LOG(ERROR) << "FMQ Result packet ill-formed"; - return std::nullopt; - } - - // unpackage operand information - const FmqResultDatum::OperandInformation& operandInfo = data[index].operandInformation(); - index++; - const bool isSufficient = operandInfo.isSufficient; - const uint32_t numberOfDimensions = operandInfo.numberOfDimensions; - - // unpackage operand dimensions - std::vector dimensions; - dimensions.reserve(numberOfDimensions); - for (size_t i = 0; i < numberOfDimensions; ++i) { - // validate dimension - if (data[index].getDiscriminator() != discriminator::operandDimensionValue) { - LOG(ERROR) << "FMQ Result packet ill-formed"; - return std::nullopt; - } - - // unpackage dimension - const uint32_t dimension = data[index].operandDimensionValue(); - index++; - - // store result - dimensions.push_back(dimension); - } - - // store result - outputShapes.push_back({/*.dimensions=*/dimensions, /*.isSufficient=*/isSufficient}); - } - - // validate execution timing - if (data[index].getDiscriminator() != discriminator::executionTiming) { - LOG(ERROR) << "FMQ Result packet ill-formed"; - return std::nullopt; - } - - // unpackage execution timing - const V1_2::Timing timing = data[index].executionTiming(); - index++; - - // validate packet information - if (index != packetSize) { - LOG(ERROR) << "FMQ Result packet ill-formed"; - return std::nullopt; - } - - // return result - return std::make_tuple(errorStatus, std::move(outputShapes), timing); -} - -V1_0::ErrorStatus legacyConvertResultCodeToErrorStatus(int resultCode) { - return convertToV1_0(convertResultCodeToErrorStatus(resultCode)); -} - -std::pair, const FmqResultDescriptor*> -ResultChannelReceiver::create(size_t channelLength, std::chrono::microseconds pollingTimeWindow) { - std::unique_ptr fmqResultChannel = - std::make_unique(channelLength, /*confEventFlag=*/true); - if (!fmqResultChannel->isValid()) { - LOG(ERROR) << "Unable to create ResultChannelReceiver"; - return {nullptr, nullptr}; - } - - const FmqResultDescriptor* descriptor = fmqResultChannel->getDesc(); - return std::make_pair( - std::make_unique(std::move(fmqResultChannel), pollingTimeWindow), - descriptor); -} - -ResultChannelReceiver::ResultChannelReceiver(std::unique_ptr fmqResultChannel, - std::chrono::microseconds pollingTimeWindow) - : mFmqResultChannel(std::move(fmqResultChannel)), kPollingTimeWindow(pollingTimeWindow) {} - -std::optional, V1_2::Timing>> -ResultChannelReceiver::getBlocking() { - const auto packet = getPacketBlocking(); - if (!packet) { - return std::nullopt; - } - - return deserialize(*packet); -} - -void ResultChannelReceiver::invalidate() { - mValid = false; - - // force unblock - // ExecutionBurstController waits on a result packet after sending a - // request. If the driver containing ExecutionBurstServer crashes, the - // controller may be waiting on the futex. This force unblock wakes up any - // thread waiting on the futex. - // TODO: look for a different/better way to signal/notify the futex to - // wake up any thread waiting on it - FmqResultDatum datum; - datum.packetInformation({/*.packetSize=*/0, - /*.errorStatus=*/V1_0::ErrorStatus::GENERAL_FAILURE, - /*.numberOfOperands=*/0}); - mFmqResultChannel->writeBlocking(&datum, 1); -} - -std::optional> ResultChannelReceiver::getPacketBlocking() { - if (!mValid) { - return std::nullopt; - } - - // First spend time polling if results are available in FMQ instead of - // waiting on the futex. Polling is more responsive (yielding lower - // latencies), but can take up more power, so only poll for a limited period - // of time. - - auto& getCurrentTime = std::chrono::high_resolution_clock::now; - const auto timeToStopPolling = getCurrentTime() + kPollingTimeWindow; - - while (getCurrentTime() < timeToStopPolling) { - // if class is being torn down, immediately return - if (!mValid.load(std::memory_order_relaxed)) { - return std::nullopt; - } - - // Check if data is available. If it is, immediately retrieve it and - // return. - const size_t available = mFmqResultChannel->availableToRead(); - if (available > 0) { - std::vector packet(available); - const bool success = mFmqResultChannel->read(packet.data(), available); - if (!success) { - LOG(ERROR) << "Error receiving packet"; - return std::nullopt; - } - return std::make_optional(std::move(packet)); - } - } - - // If we get to this point, we either stopped polling because it was taking - // too long or polling was not allowed. Instead, perform a blocking call - // which uses a futex to save power. - - // wait for result packet and read first element of result packet - FmqResultDatum datum; - bool success = mFmqResultChannel->readBlocking(&datum, 1); - - // retrieve remaining elements - // NOTE: all of the data is already available at this point, so there's no - // need to do a blocking wait to wait for more data. This is known because - // in FMQ, all writes are published (made available) atomically. Currently, - // the producer always publishes the entire packet in one function call, so - // if the first element of the packet is available, the remaining elements - // are also available. - const size_t count = mFmqResultChannel->availableToRead(); - std::vector packet(count + 1); - std::memcpy(&packet.front(), &datum, sizeof(datum)); - success &= mFmqResultChannel->read(packet.data() + 1, count); - - if (!mValid) { - return std::nullopt; - } - - // ensure packet was successfully received - if (!success) { - LOG(ERROR) << "Error receiving packet"; - return std::nullopt; - } - - return std::make_optional(std::move(packet)); -} - -std::pair, const FmqRequestDescriptor*> -RequestChannelSender::create(size_t channelLength) { - std::unique_ptr fmqRequestChannel = - std::make_unique(channelLength, /*confEventFlag=*/true); - if (!fmqRequestChannel->isValid()) { - LOG(ERROR) << "Unable to create RequestChannelSender"; - return {nullptr, nullptr}; - } - - const FmqRequestDescriptor* descriptor = fmqRequestChannel->getDesc(); - return std::make_pair(std::make_unique(std::move(fmqRequestChannel)), - descriptor); -} - -RequestChannelSender::RequestChannelSender(std::unique_ptr fmqRequestChannel) - : mFmqRequestChannel(std::move(fmqRequestChannel)) {} - -bool RequestChannelSender::send(const V1_0::Request& request, V1_2::MeasureTiming measure, - const std::vector& slots) { - const std::vector serialized = serialize(request, measure, slots); - return sendPacket(serialized); -} - -bool RequestChannelSender::sendPacket(const std::vector& packet) { - if (!mValid) { - return false; - } - - if (packet.size() > mFmqRequestChannel->availableToWrite()) { - LOG(ERROR) - << "RequestChannelSender::sendPacket -- packet size exceeds size available in FMQ"; - return false; - } - - // Always send the packet with "blocking" because this signals the futex and - // unblocks the consumer if it is waiting on the futex. - return mFmqRequestChannel->writeBlocking(packet.data(), packet.size()); -} - -void RequestChannelSender::invalidate() { - mValid = false; -} - hardware::Return ExecutionBurstController::ExecutionBurstCallback::getMemories( const hardware::hidl_vec& slots, getMemories_cb cb) { std::lock_guard guard(mMutex); diff --git a/neuralnetworks/1.2/utils/src/ExecutionBurstServer.cpp b/neuralnetworks/1.2/utils/src/ExecutionBurstServer.cpp index 848c77b284..022548dcd4 100644 --- a/neuralnetworks/1.2/utils/src/ExecutionBurstServer.cpp +++ b/neuralnetworks/1.2/utils/src/ExecutionBurstServer.cpp @@ -29,21 +29,13 @@ #include #include +#include "ExecutionBurstUtils.h" #include "HalInterfaces.h" #include "Tracing.h" namespace android::nn { namespace { -using hardware::MQDescriptorSync; -using V1_2::FmqRequestDatum; -using V1_2::FmqResultDatum; -using V1_2::IBurstCallback; -using V1_2::IBurstContext; - -constexpr V1_2::Timing kNoTiming = {std::numeric_limits::max(), - std::numeric_limits::max()}; - // DefaultBurstExecutorWithCache adapts an IPreparedModel so that it can be // used as an IBurstExecutorWithCache. Specifically, the cache simply stores the // hidl_memory object, and the execution forwards calls to the provided @@ -108,384 +100,6 @@ class DefaultBurstExecutorWithCache : public ExecutionBurstServer::IBurstExecuto } // anonymous namespace -// serialize result -std::vector serialize(V1_0::ErrorStatus errorStatus, - const std::vector& outputShapes, - V1_2::Timing timing) { - // count how many elements need to be sent for a request - size_t count = 2 + outputShapes.size(); - for (const auto& outputShape : outputShapes) { - count += outputShape.dimensions.size(); - } - - // create buffer to temporarily store elements - std::vector data; - data.reserve(count); - - // package packetInfo - { - FmqResultDatum datum; - datum.packetInformation({/*.packetSize=*/static_cast(count), - /*.errorStatus=*/errorStatus, - /*.numberOfOperands=*/static_cast(outputShapes.size())}); - data.push_back(datum); - } - - // package output shape data - for (const auto& operand : outputShapes) { - // package operand information - FmqResultDatum::OperandInformation info{}; - info.isSufficient = operand.isSufficient; - info.numberOfDimensions = static_cast(operand.dimensions.size()); - - FmqResultDatum datum; - datum.operandInformation(info); - data.push_back(datum); - - // package operand dimensions - for (uint32_t dimension : operand.dimensions) { - FmqResultDatum datum; - datum.operandDimensionValue(dimension); - data.push_back(datum); - } - } - - // package executionTiming - { - FmqResultDatum datum; - datum.executionTiming(timing); - data.push_back(datum); - } - - // return result - return data; -} - -// deserialize request -std::optional, V1_2::MeasureTiming>> deserialize( - const std::vector& data) { - using discriminator = FmqRequestDatum::hidl_discriminator; - - size_t index = 0; - - // validate packet information - if (data.size() == 0 || data[index].getDiscriminator() != discriminator::packetInformation) { - LOG(ERROR) << "FMQ Request packet ill-formed"; - return std::nullopt; - } - - // unpackage packet information - const FmqRequestDatum::PacketInformation& packetInfo = data[index].packetInformation(); - index++; - const uint32_t packetSize = packetInfo.packetSize; - const uint32_t numberOfInputOperands = packetInfo.numberOfInputOperands; - const uint32_t numberOfOutputOperands = packetInfo.numberOfOutputOperands; - const uint32_t numberOfPools = packetInfo.numberOfPools; - - // verify packet size - if (data.size() != packetSize) { - LOG(ERROR) << "FMQ Request packet ill-formed"; - return std::nullopt; - } - - // unpackage input operands - std::vector inputs; - inputs.reserve(numberOfInputOperands); - for (size_t operand = 0; operand < numberOfInputOperands; ++operand) { - // validate input operand information - if (data[index].getDiscriminator() != discriminator::inputOperandInformation) { - LOG(ERROR) << "FMQ Request packet ill-formed"; - return std::nullopt; - } - - // unpackage operand information - const FmqRequestDatum::OperandInformation& operandInfo = - data[index].inputOperandInformation(); - index++; - const bool hasNoValue = operandInfo.hasNoValue; - const V1_0::DataLocation location = operandInfo.location; - const uint32_t numberOfDimensions = operandInfo.numberOfDimensions; - - // unpackage operand dimensions - std::vector dimensions; - dimensions.reserve(numberOfDimensions); - for (size_t i = 0; i < numberOfDimensions; ++i) { - // validate dimension - if (data[index].getDiscriminator() != discriminator::inputOperandDimensionValue) { - LOG(ERROR) << "FMQ Request packet ill-formed"; - return std::nullopt; - } - - // unpackage dimension - const uint32_t dimension = data[index].inputOperandDimensionValue(); - index++; - - // store result - dimensions.push_back(dimension); - } - - // store result - inputs.push_back( - {/*.hasNoValue=*/hasNoValue, /*.location=*/location, /*.dimensions=*/dimensions}); - } - - // unpackage output operands - std::vector outputs; - outputs.reserve(numberOfOutputOperands); - for (size_t operand = 0; operand < numberOfOutputOperands; ++operand) { - // validate output operand information - if (data[index].getDiscriminator() != discriminator::outputOperandInformation) { - LOG(ERROR) << "FMQ Request packet ill-formed"; - return std::nullopt; - } - - // unpackage operand information - const FmqRequestDatum::OperandInformation& operandInfo = - data[index].outputOperandInformation(); - index++; - const bool hasNoValue = operandInfo.hasNoValue; - const V1_0::DataLocation location = operandInfo.location; - const uint32_t numberOfDimensions = operandInfo.numberOfDimensions; - - // unpackage operand dimensions - std::vector dimensions; - dimensions.reserve(numberOfDimensions); - for (size_t i = 0; i < numberOfDimensions; ++i) { - // validate dimension - if (data[index].getDiscriminator() != discriminator::outputOperandDimensionValue) { - LOG(ERROR) << "FMQ Request packet ill-formed"; - return std::nullopt; - } - - // unpackage dimension - const uint32_t dimension = data[index].outputOperandDimensionValue(); - index++; - - // store result - dimensions.push_back(dimension); - } - - // store result - outputs.push_back( - {/*.hasNoValue=*/hasNoValue, /*.location=*/location, /*.dimensions=*/dimensions}); - } - - // unpackage pools - std::vector slots; - slots.reserve(numberOfPools); - for (size_t pool = 0; pool < numberOfPools; ++pool) { - // validate input operand information - if (data[index].getDiscriminator() != discriminator::poolIdentifier) { - LOG(ERROR) << "FMQ Request packet ill-formed"; - return std::nullopt; - } - - // unpackage operand information - const int32_t poolId = data[index].poolIdentifier(); - index++; - - // store result - slots.push_back(poolId); - } - - // validate measureTiming - if (data[index].getDiscriminator() != discriminator::measureTiming) { - LOG(ERROR) << "FMQ Request packet ill-formed"; - return std::nullopt; - } - - // unpackage measureTiming - const V1_2::MeasureTiming measure = data[index].measureTiming(); - index++; - - // validate packet information - if (index != packetSize) { - LOG(ERROR) << "FMQ Result packet ill-formed"; - return std::nullopt; - } - - // return request - V1_0::Request request = {/*.inputs=*/inputs, /*.outputs=*/outputs, /*.pools=*/{}}; - return std::make_tuple(std::move(request), std::move(slots), measure); -} - -// RequestChannelReceiver methods - -std::unique_ptr RequestChannelReceiver::create( - const FmqRequestDescriptor& requestChannel, std::chrono::microseconds pollingTimeWindow) { - std::unique_ptr fmqRequestChannel = - std::make_unique(requestChannel); - - if (!fmqRequestChannel->isValid()) { - LOG(ERROR) << "Unable to create RequestChannelReceiver"; - return nullptr; - } - if (fmqRequestChannel->getEventFlagWord() == nullptr) { - LOG(ERROR) - << "RequestChannelReceiver::create was passed an MQDescriptor without an EventFlag"; - return nullptr; - } - - return std::make_unique(std::move(fmqRequestChannel), - pollingTimeWindow); -} - -RequestChannelReceiver::RequestChannelReceiver(std::unique_ptr fmqRequestChannel, - std::chrono::microseconds pollingTimeWindow) - : mFmqRequestChannel(std::move(fmqRequestChannel)), kPollingTimeWindow(pollingTimeWindow) {} - -std::optional, V1_2::MeasureTiming>> -RequestChannelReceiver::getBlocking() { - const auto packet = getPacketBlocking(); - if (!packet) { - return std::nullopt; - } - - return deserialize(*packet); -} - -void RequestChannelReceiver::invalidate() { - mTeardown = true; - - // force unblock - // ExecutionBurstServer is by default waiting on a request packet. If the - // client process destroys its burst object, the server may still be waiting - // on the futex. This force unblock wakes up any thread waiting on the - // futex. - // TODO: look for a different/better way to signal/notify the futex to wake - // up any thread waiting on it - FmqRequestDatum datum; - datum.packetInformation({/*.packetSize=*/0, /*.numberOfInputOperands=*/0, - /*.numberOfOutputOperands=*/0, /*.numberOfPools=*/0}); - mFmqRequestChannel->writeBlocking(&datum, 1); -} - -std::optional> RequestChannelReceiver::getPacketBlocking() { - if (mTeardown) { - return std::nullopt; - } - - // First spend time polling if results are available in FMQ instead of - // waiting on the futex. Polling is more responsive (yielding lower - // latencies), but can take up more power, so only poll for a limited period - // of time. - - auto& getCurrentTime = std::chrono::high_resolution_clock::now; - const auto timeToStopPolling = getCurrentTime() + kPollingTimeWindow; - - while (getCurrentTime() < timeToStopPolling) { - // if class is being torn down, immediately return - if (mTeardown.load(std::memory_order_relaxed)) { - return std::nullopt; - } - - // Check if data is available. If it is, immediately retrieve it and - // return. - const size_t available = mFmqRequestChannel->availableToRead(); - if (available > 0) { - // This is the first point when we know an execution is occurring, - // so begin to collect systraces. Note that a similar systrace does - // not exist at the corresponding point in - // ResultChannelReceiver::getPacketBlocking because the execution is - // already in flight. - NNTRACE_FULL(NNTRACE_LAYER_IPC, NNTRACE_PHASE_EXECUTION, - "ExecutionBurstServer getting packet"); - std::vector packet(available); - const bool success = mFmqRequestChannel->read(packet.data(), available); - if (!success) { - LOG(ERROR) << "Error receiving packet"; - return std::nullopt; - } - return std::make_optional(std::move(packet)); - } - } - - // If we get to this point, we either stopped polling because it was taking - // too long or polling was not allowed. Instead, perform a blocking call - // which uses a futex to save power. - - // wait for request packet and read first element of request packet - FmqRequestDatum datum; - bool success = mFmqRequestChannel->readBlocking(&datum, 1); - - // This is the first point when we know an execution is occurring, so begin - // to collect systraces. Note that a similar systrace does not exist at the - // corresponding point in ResultChannelReceiver::getPacketBlocking because - // the execution is already in flight. - NNTRACE_FULL(NNTRACE_LAYER_IPC, NNTRACE_PHASE_EXECUTION, "ExecutionBurstServer getting packet"); - - // retrieve remaining elements - // NOTE: all of the data is already available at this point, so there's no - // need to do a blocking wait to wait for more data. This is known because - // in FMQ, all writes are published (made available) atomically. Currently, - // the producer always publishes the entire packet in one function call, so - // if the first element of the packet is available, the remaining elements - // are also available. - const size_t count = mFmqRequestChannel->availableToRead(); - std::vector packet(count + 1); - std::memcpy(&packet.front(), &datum, sizeof(datum)); - success &= mFmqRequestChannel->read(packet.data() + 1, count); - - // terminate loop - if (mTeardown) { - return std::nullopt; - } - - // ensure packet was successfully received - if (!success) { - LOG(ERROR) << "Error receiving packet"; - return std::nullopt; - } - - return std::make_optional(std::move(packet)); -} - -// ResultChannelSender methods - -std::unique_ptr ResultChannelSender::create( - const FmqResultDescriptor& resultChannel) { - std::unique_ptr fmqResultChannel = - std::make_unique(resultChannel); - - if (!fmqResultChannel->isValid()) { - LOG(ERROR) << "Unable to create RequestChannelSender"; - return nullptr; - } - if (fmqResultChannel->getEventFlagWord() == nullptr) { - LOG(ERROR) << "ResultChannelSender::create was passed an MQDescriptor without an EventFlag"; - return nullptr; - } - - return std::make_unique(std::move(fmqResultChannel)); -} - -ResultChannelSender::ResultChannelSender(std::unique_ptr fmqResultChannel) - : mFmqResultChannel(std::move(fmqResultChannel)) {} - -bool ResultChannelSender::send(V1_0::ErrorStatus errorStatus, - const std::vector& outputShapes, - V1_2::Timing timing) { - const std::vector serialized = serialize(errorStatus, outputShapes, timing); - return sendPacket(serialized); -} - -bool ResultChannelSender::sendPacket(const std::vector& packet) { - if (packet.size() > mFmqResultChannel->availableToWrite()) { - LOG(ERROR) - << "ResultChannelSender::sendPacket -- packet size exceeds size available in FMQ"; - const std::vector errorPacket = - serialize(V1_0::ErrorStatus::GENERAL_FAILURE, {}, kNoTiming); - - // Always send the packet with "blocking" because this signals the futex - // and unblocks the consumer if it is waiting on the futex. - return mFmqResultChannel->writeBlocking(errorPacket.data(), errorPacket.size()); - } - - // Always send the packet with "blocking" because this signals the futex and - // unblocks the consumer if it is waiting on the futex. - return mFmqResultChannel->writeBlocking(packet.data(), packet.size()); -} - // ExecutionBurstServer methods sp ExecutionBurstServer::create( diff --git a/neuralnetworks/1.2/utils/src/ExecutionBurstUtils.cpp b/neuralnetworks/1.2/utils/src/ExecutionBurstUtils.cpp new file mode 100644 index 0000000000..f0275f933a --- /dev/null +++ b/neuralnetworks/1.2/utils/src/ExecutionBurstUtils.cpp @@ -0,0 +1,749 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "ExecutionBurstUtils" + +#include "ExecutionBurstUtils.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::V1_2::utils { +namespace { + +constexpr V1_2::Timing kNoTiming = {std::numeric_limits::max(), + std::numeric_limits::max()}; + +} + +// serialize a request into a packet +std::vector serialize(const V1_0::Request& request, V1_2::MeasureTiming measure, + const std::vector& slots) { + // count how many elements need to be sent for a request + size_t count = 2 + request.inputs.size() + request.outputs.size() + request.pools.size(); + for (const auto& input : request.inputs) { + count += input.dimensions.size(); + } + for (const auto& output : request.outputs) { + count += output.dimensions.size(); + } + + // create buffer to temporarily store elements + std::vector data; + data.reserve(count); + + // package packetInfo + { + FmqRequestDatum datum; + datum.packetInformation( + {/*.packetSize=*/static_cast(count), + /*.numberOfInputOperands=*/static_cast(request.inputs.size()), + /*.numberOfOutputOperands=*/static_cast(request.outputs.size()), + /*.numberOfPools=*/static_cast(request.pools.size())}); + data.push_back(datum); + } + + // package input data + for (const auto& input : request.inputs) { + // package operand information + FmqRequestDatum datum; + datum.inputOperandInformation( + {/*.hasNoValue=*/input.hasNoValue, + /*.location=*/input.location, + /*.numberOfDimensions=*/static_cast(input.dimensions.size())}); + data.push_back(datum); + + // package operand dimensions + for (uint32_t dimension : input.dimensions) { + FmqRequestDatum datum; + datum.inputOperandDimensionValue(dimension); + data.push_back(datum); + } + } + + // package output data + for (const auto& output : request.outputs) { + // package operand information + FmqRequestDatum datum; + datum.outputOperandInformation( + {/*.hasNoValue=*/output.hasNoValue, + /*.location=*/output.location, + /*.numberOfDimensions=*/static_cast(output.dimensions.size())}); + data.push_back(datum); + + // package operand dimensions + for (uint32_t dimension : output.dimensions) { + FmqRequestDatum datum; + datum.outputOperandDimensionValue(dimension); + data.push_back(datum); + } + } + + // package pool identifier + for (int32_t slot : slots) { + FmqRequestDatum datum; + datum.poolIdentifier(slot); + data.push_back(datum); + } + + // package measureTiming + { + FmqRequestDatum datum; + datum.measureTiming(measure); + data.push_back(datum); + } + + // return packet + return data; +} + +// serialize result +std::vector serialize(V1_0::ErrorStatus errorStatus, + const std::vector& outputShapes, + V1_2::Timing timing) { + // count how many elements need to be sent for a request + size_t count = 2 + outputShapes.size(); + for (const auto& outputShape : outputShapes) { + count += outputShape.dimensions.size(); + } + + // create buffer to temporarily store elements + std::vector data; + data.reserve(count); + + // package packetInfo + { + FmqResultDatum datum; + datum.packetInformation({/*.packetSize=*/static_cast(count), + /*.errorStatus=*/errorStatus, + /*.numberOfOperands=*/static_cast(outputShapes.size())}); + data.push_back(datum); + } + + // package output shape data + for (const auto& operand : outputShapes) { + // package operand information + FmqResultDatum::OperandInformation info{}; + info.isSufficient = operand.isSufficient; + info.numberOfDimensions = static_cast(operand.dimensions.size()); + + FmqResultDatum datum; + datum.operandInformation(info); + data.push_back(datum); + + // package operand dimensions + for (uint32_t dimension : operand.dimensions) { + FmqResultDatum datum; + datum.operandDimensionValue(dimension); + data.push_back(datum); + } + } + + // package executionTiming + { + FmqResultDatum datum; + datum.executionTiming(timing); + data.push_back(datum); + } + + // return result + return data; +} + +// deserialize request +std::optional, V1_2::MeasureTiming>> deserialize( + const std::vector& data) { + using discriminator = FmqRequestDatum::hidl_discriminator; + + size_t index = 0; + + // validate packet information + if (data.size() == 0 || data[index].getDiscriminator() != discriminator::packetInformation) { + LOG(ERROR) << "FMQ Request packet ill-formed"; + return std::nullopt; + } + + // unpackage packet information + const FmqRequestDatum::PacketInformation& packetInfo = data[index].packetInformation(); + index++; + const uint32_t packetSize = packetInfo.packetSize; + const uint32_t numberOfInputOperands = packetInfo.numberOfInputOperands; + const uint32_t numberOfOutputOperands = packetInfo.numberOfOutputOperands; + const uint32_t numberOfPools = packetInfo.numberOfPools; + + // verify packet size + if (data.size() != packetSize) { + LOG(ERROR) << "FMQ Request packet ill-formed"; + return std::nullopt; + } + + // unpackage input operands + std::vector inputs; + inputs.reserve(numberOfInputOperands); + for (size_t operand = 0; operand < numberOfInputOperands; ++operand) { + // validate input operand information + if (data[index].getDiscriminator() != discriminator::inputOperandInformation) { + LOG(ERROR) << "FMQ Request packet ill-formed"; + return std::nullopt; + } + + // unpackage operand information + const FmqRequestDatum::OperandInformation& operandInfo = + data[index].inputOperandInformation(); + index++; + const bool hasNoValue = operandInfo.hasNoValue; + const V1_0::DataLocation location = operandInfo.location; + const uint32_t numberOfDimensions = operandInfo.numberOfDimensions; + + // unpackage operand dimensions + std::vector dimensions; + dimensions.reserve(numberOfDimensions); + for (size_t i = 0; i < numberOfDimensions; ++i) { + // validate dimension + if (data[index].getDiscriminator() != discriminator::inputOperandDimensionValue) { + LOG(ERROR) << "FMQ Request packet ill-formed"; + return std::nullopt; + } + + // unpackage dimension + const uint32_t dimension = data[index].inputOperandDimensionValue(); + index++; + + // store result + dimensions.push_back(dimension); + } + + // store result + inputs.push_back( + {/*.hasNoValue=*/hasNoValue, /*.location=*/location, /*.dimensions=*/dimensions}); + } + + // unpackage output operands + std::vector outputs; + outputs.reserve(numberOfOutputOperands); + for (size_t operand = 0; operand < numberOfOutputOperands; ++operand) { + // validate output operand information + if (data[index].getDiscriminator() != discriminator::outputOperandInformation) { + LOG(ERROR) << "FMQ Request packet ill-formed"; + return std::nullopt; + } + + // unpackage operand information + const FmqRequestDatum::OperandInformation& operandInfo = + data[index].outputOperandInformation(); + index++; + const bool hasNoValue = operandInfo.hasNoValue; + const V1_0::DataLocation location = operandInfo.location; + const uint32_t numberOfDimensions = operandInfo.numberOfDimensions; + + // unpackage operand dimensions + std::vector dimensions; + dimensions.reserve(numberOfDimensions); + for (size_t i = 0; i < numberOfDimensions; ++i) { + // validate dimension + if (data[index].getDiscriminator() != discriminator::outputOperandDimensionValue) { + LOG(ERROR) << "FMQ Request packet ill-formed"; + return std::nullopt; + } + + // unpackage dimension + const uint32_t dimension = data[index].outputOperandDimensionValue(); + index++; + + // store result + dimensions.push_back(dimension); + } + + // store result + outputs.push_back( + {/*.hasNoValue=*/hasNoValue, /*.location=*/location, /*.dimensions=*/dimensions}); + } + + // unpackage pools + std::vector slots; + slots.reserve(numberOfPools); + for (size_t pool = 0; pool < numberOfPools; ++pool) { + // validate input operand information + if (data[index].getDiscriminator() != discriminator::poolIdentifier) { + LOG(ERROR) << "FMQ Request packet ill-formed"; + return std::nullopt; + } + + // unpackage operand information + const int32_t poolId = data[index].poolIdentifier(); + index++; + + // store result + slots.push_back(poolId); + } + + // validate measureTiming + if (data[index].getDiscriminator() != discriminator::measureTiming) { + LOG(ERROR) << "FMQ Request packet ill-formed"; + return std::nullopt; + } + + // unpackage measureTiming + const V1_2::MeasureTiming measure = data[index].measureTiming(); + index++; + + // validate packet information + if (index != packetSize) { + LOG(ERROR) << "FMQ Result packet ill-formed"; + return std::nullopt; + } + + // return request + V1_0::Request request = {/*.inputs=*/inputs, /*.outputs=*/outputs, /*.pools=*/{}}; + return std::make_tuple(std::move(request), std::move(slots), measure); +} + +// deserialize a packet into the result +std::optional, V1_2::Timing>> +deserialize(const std::vector& data) { + using discriminator = FmqResultDatum::hidl_discriminator; + + std::vector outputShapes; + size_t index = 0; + + // validate packet information + if (data.size() == 0 || data[index].getDiscriminator() != discriminator::packetInformation) { + LOG(ERROR) << "FMQ Result packet ill-formed"; + return std::nullopt; + } + + // unpackage packet information + const FmqResultDatum::PacketInformation& packetInfo = data[index].packetInformation(); + index++; + const uint32_t packetSize = packetInfo.packetSize; + const V1_0::ErrorStatus errorStatus = packetInfo.errorStatus; + const uint32_t numberOfOperands = packetInfo.numberOfOperands; + + // verify packet size + if (data.size() != packetSize) { + LOG(ERROR) << "FMQ Result packet ill-formed"; + return std::nullopt; + } + + // unpackage operands + for (size_t operand = 0; operand < numberOfOperands; ++operand) { + // validate operand information + if (data[index].getDiscriminator() != discriminator::operandInformation) { + LOG(ERROR) << "FMQ Result packet ill-formed"; + return std::nullopt; + } + + // unpackage operand information + const FmqResultDatum::OperandInformation& operandInfo = data[index].operandInformation(); + index++; + const bool isSufficient = operandInfo.isSufficient; + const uint32_t numberOfDimensions = operandInfo.numberOfDimensions; + + // unpackage operand dimensions + std::vector dimensions; + dimensions.reserve(numberOfDimensions); + for (size_t i = 0; i < numberOfDimensions; ++i) { + // validate dimension + if (data[index].getDiscriminator() != discriminator::operandDimensionValue) { + LOG(ERROR) << "FMQ Result packet ill-formed"; + return std::nullopt; + } + + // unpackage dimension + const uint32_t dimension = data[index].operandDimensionValue(); + index++; + + // store result + dimensions.push_back(dimension); + } + + // store result + outputShapes.push_back({/*.dimensions=*/dimensions, /*.isSufficient=*/isSufficient}); + } + + // validate execution timing + if (data[index].getDiscriminator() != discriminator::executionTiming) { + LOG(ERROR) << "FMQ Result packet ill-formed"; + return std::nullopt; + } + + // unpackage execution timing + const V1_2::Timing timing = data[index].executionTiming(); + index++; + + // validate packet information + if (index != packetSize) { + LOG(ERROR) << "FMQ Result packet ill-formed"; + return std::nullopt; + } + + // return result + return std::make_tuple(errorStatus, std::move(outputShapes), timing); +} + +V1_0::ErrorStatus legacyConvertResultCodeToErrorStatus(int resultCode) { + return convertToV1_0(convertResultCodeToErrorStatus(resultCode)); +} + +// RequestChannelSender methods + +std::pair, const FmqRequestDescriptor*> +RequestChannelSender::create(size_t channelLength) { + std::unique_ptr fmqRequestChannel = + std::make_unique(channelLength, /*confEventFlag=*/true); + if (!fmqRequestChannel->isValid()) { + LOG(ERROR) << "Unable to create RequestChannelSender"; + return {nullptr, nullptr}; + } + + const FmqRequestDescriptor* descriptor = fmqRequestChannel->getDesc(); + return std::make_pair(std::make_unique(std::move(fmqRequestChannel)), + descriptor); +} + +RequestChannelSender::RequestChannelSender(std::unique_ptr fmqRequestChannel) + : mFmqRequestChannel(std::move(fmqRequestChannel)) {} + +bool RequestChannelSender::send(const V1_0::Request& request, V1_2::MeasureTiming measure, + const std::vector& slots) { + const std::vector serialized = serialize(request, measure, slots); + return sendPacket(serialized); +} + +bool RequestChannelSender::sendPacket(const std::vector& packet) { + if (!mValid) { + return false; + } + + if (packet.size() > mFmqRequestChannel->availableToWrite()) { + LOG(ERROR) + << "RequestChannelSender::sendPacket -- packet size exceeds size available in FMQ"; + return false; + } + + // Always send the packet with "blocking" because this signals the futex and + // unblocks the consumer if it is waiting on the futex. + return mFmqRequestChannel->writeBlocking(packet.data(), packet.size()); +} + +void RequestChannelSender::invalidate() { + mValid = false; +} + +// RequestChannelReceiver methods + +std::unique_ptr RequestChannelReceiver::create( + const FmqRequestDescriptor& requestChannel, std::chrono::microseconds pollingTimeWindow) { + std::unique_ptr fmqRequestChannel = + std::make_unique(requestChannel); + + if (!fmqRequestChannel->isValid()) { + LOG(ERROR) << "Unable to create RequestChannelReceiver"; + return nullptr; + } + if (fmqRequestChannel->getEventFlagWord() == nullptr) { + LOG(ERROR) + << "RequestChannelReceiver::create was passed an MQDescriptor without an EventFlag"; + return nullptr; + } + + return std::make_unique(std::move(fmqRequestChannel), + pollingTimeWindow); +} + +RequestChannelReceiver::RequestChannelReceiver(std::unique_ptr fmqRequestChannel, + std::chrono::microseconds pollingTimeWindow) + : mFmqRequestChannel(std::move(fmqRequestChannel)), kPollingTimeWindow(pollingTimeWindow) {} + +std::optional, V1_2::MeasureTiming>> +RequestChannelReceiver::getBlocking() { + const auto packet = getPacketBlocking(); + if (!packet) { + return std::nullopt; + } + + return deserialize(*packet); +} + +void RequestChannelReceiver::invalidate() { + mTeardown = true; + + // force unblock + // ExecutionBurstServer is by default waiting on a request packet. If the + // client process destroys its burst object, the server may still be waiting + // on the futex. This force unblock wakes up any thread waiting on the + // futex. + // TODO: look for a different/better way to signal/notify the futex to wake + // up any thread waiting on it + FmqRequestDatum datum; + datum.packetInformation({/*.packetSize=*/0, /*.numberOfInputOperands=*/0, + /*.numberOfOutputOperands=*/0, /*.numberOfPools=*/0}); + mFmqRequestChannel->writeBlocking(&datum, 1); +} + +std::optional> RequestChannelReceiver::getPacketBlocking() { + if (mTeardown) { + return std::nullopt; + } + + // First spend time polling if results are available in FMQ instead of + // waiting on the futex. Polling is more responsive (yielding lower + // latencies), but can take up more power, so only poll for a limited period + // of time. + + auto& getCurrentTime = std::chrono::high_resolution_clock::now; + const auto timeToStopPolling = getCurrentTime() + kPollingTimeWindow; + + while (getCurrentTime() < timeToStopPolling) { + // if class is being torn down, immediately return + if (mTeardown.load(std::memory_order_relaxed)) { + return std::nullopt; + } + + // Check if data is available. If it is, immediately retrieve it and + // return. + const size_t available = mFmqRequestChannel->availableToRead(); + if (available > 0) { + // This is the first point when we know an execution is occurring, + // so begin to collect systraces. Note that a similar systrace does + // not exist at the corresponding point in + // ResultChannelReceiver::getPacketBlocking because the execution is + // already in flight. + NNTRACE_FULL(NNTRACE_LAYER_IPC, NNTRACE_PHASE_EXECUTION, + "ExecutionBurstServer getting packet"); + std::vector packet(available); + const bool success = mFmqRequestChannel->read(packet.data(), available); + if (!success) { + LOG(ERROR) << "Error receiving packet"; + return std::nullopt; + } + return std::make_optional(std::move(packet)); + } + } + + // If we get to this point, we either stopped polling because it was taking + // too long or polling was not allowed. Instead, perform a blocking call + // which uses a futex to save power. + + // wait for request packet and read first element of request packet + FmqRequestDatum datum; + bool success = mFmqRequestChannel->readBlocking(&datum, 1); + + // This is the first point when we know an execution is occurring, so begin + // to collect systraces. Note that a similar systrace does not exist at the + // corresponding point in ResultChannelReceiver::getPacketBlocking because + // the execution is already in flight. + NNTRACE_FULL(NNTRACE_LAYER_IPC, NNTRACE_PHASE_EXECUTION, "ExecutionBurstServer getting packet"); + + // retrieve remaining elements + // NOTE: all of the data is already available at this point, so there's no + // need to do a blocking wait to wait for more data. This is known because + // in FMQ, all writes are published (made available) atomically. Currently, + // the producer always publishes the entire packet in one function call, so + // if the first element of the packet is available, the remaining elements + // are also available. + const size_t count = mFmqRequestChannel->availableToRead(); + std::vector packet(count + 1); + std::memcpy(&packet.front(), &datum, sizeof(datum)); + success &= mFmqRequestChannel->read(packet.data() + 1, count); + + // terminate loop + if (mTeardown) { + return std::nullopt; + } + + // ensure packet was successfully received + if (!success) { + LOG(ERROR) << "Error receiving packet"; + return std::nullopt; + } + + return std::make_optional(std::move(packet)); +} + +// ResultChannelSender methods + +std::unique_ptr ResultChannelSender::create( + const FmqResultDescriptor& resultChannel) { + std::unique_ptr fmqResultChannel = + std::make_unique(resultChannel); + + if (!fmqResultChannel->isValid()) { + LOG(ERROR) << "Unable to create RequestChannelSender"; + return nullptr; + } + if (fmqResultChannel->getEventFlagWord() == nullptr) { + LOG(ERROR) << "ResultChannelSender::create was passed an MQDescriptor without an EventFlag"; + return nullptr; + } + + return std::make_unique(std::move(fmqResultChannel)); +} + +ResultChannelSender::ResultChannelSender(std::unique_ptr fmqResultChannel) + : mFmqResultChannel(std::move(fmqResultChannel)) {} + +bool ResultChannelSender::send(V1_0::ErrorStatus errorStatus, + const std::vector& outputShapes, + V1_2::Timing timing) { + const std::vector serialized = serialize(errorStatus, outputShapes, timing); + return sendPacket(serialized); +} + +bool ResultChannelSender::sendPacket(const std::vector& packet) { + if (packet.size() > mFmqResultChannel->availableToWrite()) { + LOG(ERROR) + << "ResultChannelSender::sendPacket -- packet size exceeds size available in FMQ"; + const std::vector errorPacket = + serialize(V1_0::ErrorStatus::GENERAL_FAILURE, {}, kNoTiming); + + // Always send the packet with "blocking" because this signals the futex + // and unblocks the consumer if it is waiting on the futex. + return mFmqResultChannel->writeBlocking(errorPacket.data(), errorPacket.size()); + } + + // Always send the packet with "blocking" because this signals the futex and + // unblocks the consumer if it is waiting on the futex. + return mFmqResultChannel->writeBlocking(packet.data(), packet.size()); +} + +// ResultChannelReceiver methods + +std::pair, const FmqResultDescriptor*> +ResultChannelReceiver::create(size_t channelLength, std::chrono::microseconds pollingTimeWindow) { + std::unique_ptr fmqResultChannel = + std::make_unique(channelLength, /*confEventFlag=*/true); + if (!fmqResultChannel->isValid()) { + LOG(ERROR) << "Unable to create ResultChannelReceiver"; + return {nullptr, nullptr}; + } + + const FmqResultDescriptor* descriptor = fmqResultChannel->getDesc(); + return std::make_pair( + std::make_unique(std::move(fmqResultChannel), pollingTimeWindow), + descriptor); +} + +ResultChannelReceiver::ResultChannelReceiver(std::unique_ptr fmqResultChannel, + std::chrono::microseconds pollingTimeWindow) + : mFmqResultChannel(std::move(fmqResultChannel)), kPollingTimeWindow(pollingTimeWindow) {} + +std::optional, V1_2::Timing>> +ResultChannelReceiver::getBlocking() { + const auto packet = getPacketBlocking(); + if (!packet) { + return std::nullopt; + } + + return deserialize(*packet); +} + +void ResultChannelReceiver::invalidate() { + mValid = false; + + // force unblock + // ExecutionBurstController waits on a result packet after sending a + // request. If the driver containing ExecutionBurstServer crashes, the + // controller may be waiting on the futex. This force unblock wakes up any + // thread waiting on the futex. + // TODO: look for a different/better way to signal/notify the futex to + // wake up any thread waiting on it + FmqResultDatum datum; + datum.packetInformation({/*.packetSize=*/0, + /*.errorStatus=*/V1_0::ErrorStatus::GENERAL_FAILURE, + /*.numberOfOperands=*/0}); + mFmqResultChannel->writeBlocking(&datum, 1); +} + +std::optional> ResultChannelReceiver::getPacketBlocking() { + if (!mValid) { + return std::nullopt; + } + + // First spend time polling if results are available in FMQ instead of + // waiting on the futex. Polling is more responsive (yielding lower + // latencies), but can take up more power, so only poll for a limited period + // of time. + + auto& getCurrentTime = std::chrono::high_resolution_clock::now; + const auto timeToStopPolling = getCurrentTime() + kPollingTimeWindow; + + while (getCurrentTime() < timeToStopPolling) { + // if class is being torn down, immediately return + if (!mValid.load(std::memory_order_relaxed)) { + return std::nullopt; + } + + // Check if data is available. If it is, immediately retrieve it and + // return. + const size_t available = mFmqResultChannel->availableToRead(); + if (available > 0) { + std::vector packet(available); + const bool success = mFmqResultChannel->read(packet.data(), available); + if (!success) { + LOG(ERROR) << "Error receiving packet"; + return std::nullopt; + } + return std::make_optional(std::move(packet)); + } + } + + // If we get to this point, we either stopped polling because it was taking + // too long or polling was not allowed. Instead, perform a blocking call + // which uses a futex to save power. + + // wait for result packet and read first element of result packet + FmqResultDatum datum; + bool success = mFmqResultChannel->readBlocking(&datum, 1); + + // retrieve remaining elements + // NOTE: all of the data is already available at this point, so there's no + // need to do a blocking wait to wait for more data. This is known because + // in FMQ, all writes are published (made available) atomically. Currently, + // the producer always publishes the entire packet in one function call, so + // if the first element of the packet is available, the remaining elements + // are also available. + const size_t count = mFmqResultChannel->availableToRead(); + std::vector packet(count + 1); + std::memcpy(&packet.front(), &datum, sizeof(datum)); + success &= mFmqResultChannel->read(packet.data() + 1, count); + + if (!mValid) { + return std::nullopt; + } + + // ensure packet was successfully received + if (!success) { + LOG(ERROR) << "Error receiving packet"; + return std::nullopt; + } + + return std::make_optional(std::move(packet)); +} + +} // namespace android::hardware::neuralnetworks::V1_2::utils -- GitLab From 7e9d71fa64bf4b749b50d5633fac1baff71be9f9 Mon Sep 17 00:00:00 2001 From: Sunil Ravi Date: Sun, 3 Jan 2021 08:38:52 -0800 Subject: [PATCH 379/790] wifi: Send MBO-OCE association rejection info. Parse association response for MBO association disallowed indication and OCE RSSI based association rejection info and send it to framework in association rejection event. Bug: 162542063 Test: vts test - VtsHalWifiSupplicantV1_4TargetTest Change-Id: I63ae2c37b816dbe1790647e90541e2d0b6df8401 --- .../1.4/ISupplicantStaIfaceCallback.hal | 100 ++++++++++++++++++ .../supplicant_sta_iface_hidl_test.cpp | 5 + 2 files changed, 105 insertions(+) diff --git a/wifi/supplicant/1.4/ISupplicantStaIfaceCallback.hal b/wifi/supplicant/1.4/ISupplicantStaIfaceCallback.hal index efcebdac00..c6f05fb953 100644 --- a/wifi/supplicant/1.4/ISupplicantStaIfaceCallback.hal +++ b/wifi/supplicant/1.4/ISupplicantStaIfaceCallback.hal @@ -20,7 +20,9 @@ import @1.0::ISupplicantStaIfaceCallback.AnqpData; import @1.0::ISupplicantStaIfaceCallback.Hs20AnqpData; import @1.3::ISupplicantStaIfaceCallback; import @1.0::ISupplicantStaIfaceCallback.State; +import @1.0::ISupplicantStaIfaceCallback.StatusCode; import @1.0::Bssid; +import @1.0::Ssid; /** * Callback Interface exposed by the supplicant service @@ -31,6 +33,19 @@ import @1.0::Bssid; * corresponding |ISupplicantStaIface.registerCallback_1_4| method. */ interface ISupplicantStaIfaceCallback extends @1.3::ISupplicantStaIfaceCallback { + /** + * MBO spec v1.2, 4.2.4 Table 14: MBO Association disallowed reason code attribute + * values. + */ + enum MboAssocDisallowedReasonCode : uint8_t { + RESERVED = 0, + UNSPECIFIED = 1, + MAX_NUM_STA_ASSOCIATED = 2, + AIR_INTERFACE_OVERLOADED = 3, + AUTH_SERVER_OVERLOADED = 4, + INSUFFICIENT_RSSI = 5, + }; + /** * ANQP data for IEEE Std 802.11-2016. * The format of the data within these elements follows the IEEE @@ -48,6 +63,83 @@ interface ISupplicantStaIfaceCallback extends @1.3::ISupplicantStaIfaceCallback vec venueUrl; }; + /** + * OceRssiBasedAssocRejectAttr is extracted from (Re-)Association response + * frame from an OCE AP to indicate that the AP has rejected the + * (Re-)Association request on the basis of insufficient RSSI. + * Refer OCE spec v1.0 section 4.2.2 Table 7. + */ + struct OceRssiBasedAssocRejectAttr { + /* + * Delta RSSI - The difference in dB between the minimum RSSI at which + * the AP would accept a (Re-)Association request from the STA before + * Retry Delay expires and the AP's measurement of the RSSI at which the + * (Re-)Association request was received. + */ + uint32_t deltaRssi; + + /* + * Retry Delay - The time period in seconds for which the AP will not + * accept any subsequent (Re-)Association requests from the STA, unless + * the received RSSI has improved by Delta RSSI. + */ + uint32_t retryDelayS; + }; + + /** + * Association Rejection related information. + */ + struct AssociationRejectionData { + /** + * SSID of the AP that rejected the association. + */ + Ssid ssid; + + /** + * BSSID of the AP that rejected the association. + */ + Bssid bssid; + + /* + * 802.11 code to indicate the reject reason. + * Refer to section 8.4.1.9 of IEEE 802.11 spec. + */ + StatusCode statusCode; + + /* + * Flag to indicate that failure is due to timeout rather than + * explicit rejection response from the AP. + */ + bool timedOut; + + /** + * Flag to indicate that MboAssocDisallowedReasonCode is present + * in the (Re-)Association response frame. + */ + bool isMboAssocDisallowedReasonCodePresent; + + /** + * mboAssocDisallowedReason is extracted from MBO association disallowed attribute + * in (Re-)Association response frame to indicate that the AP is not accepting new + * associations. + * Refer MBO spec v1.2 section 4.2.4 Table 13 for the details of reason code. + * The value is undefined if isMboAssocDisallowedReasonCodePresent is false. + */ + MboAssocDisallowedReasonCode mboAssocDisallowedReason; + + /** + * Flag to indicate that OceRssiBasedAssocRejectAttr is present + * in the (Re-)Association response frame. + */ + bool isOceRssiBasedAssocRejectAttrPresent; + + /* + * OCE RSSI-based (Re-)Association rejection attribute. + * The contents are undefined if isOceRssiBasedAssocRejectAttrPresent is false. + */ + OceRssiBasedAssocRejectAttr oceRssiBasedAssocRejectData; + }; + /** * Used to indicate a Hotspot 2.0 terms and conditions acceptance is requested from the user * before allowing the device to get internet access. @@ -68,4 +160,12 @@ interface ISupplicantStaIfaceCallback extends @1.3::ISupplicantStaIfaceCallback * All the fields in this struct must be empty if the query failed. */ oneway onAnqpQueryDone_1_4(Bssid bssid, AnqpData data, Hs20AnqpData hs20Data); + + /** + * Used to indicate an association rejection received from the AP + * to which the connection is being attempted. + * + * @param assocRejectData Association Rejection related information. + */ + oneway onAssociationRejected_1_4(AssociationRejectionData assocRejectData); }; diff --git a/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp index ccd469d4b3..1794a39530 100644 --- a/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp +++ b/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp @@ -232,6 +232,11 @@ class IfaceCallback : public ISupplicantStaIfaceCallback { override { return Void(); } + Return onAssociationRejected_1_4( + const ISupplicantStaIfaceCallback::AssociationRejectionData& /* data */) + override { + return Void(); + } }; /* -- GitLab From f7890cc53d8f2d81fad22ee2ddb977a008857832 Mon Sep 17 00:00:00 2001 From: Kevin Chyn Date: Mon, 11 Jan 2021 17:08:36 -0800 Subject: [PATCH 380/790] Return new authenticatorId when invalidation finishes The new authenticatorId will always be needed by the client after invalidation finishes. This change allows the client to receive it without requesting getAuthenticatorId. Test: m android.hardware.biometrics.face-update-api Test: m android.hardware.biometrics.fingerprint-update-api Test: m VtsHalBiometricsFaceTargetTest Test: m VtsHalBiometricsFingerprintTargetTest Bug: 159667191 Change-Id: I63166315789945966ff8081e07dd714cc14bc2f0 --- .../hardware/biometrics/face/AcquiredInfo.aidl | 13 +++++++------ .../android/hardware/biometrics/face/Error.aidl | 13 +++++++------ .../hardware/biometrics/face/FaceSensorType.aidl | 13 +++++++------ .../android/hardware/biometrics/face/IFace.aidl | 13 +++++++------ .../hardware/biometrics/face/ISession.aidl | 13 +++++++------ .../biometrics/face/ISessionCallback.aidl | 15 ++++++++------- .../hardware/biometrics/face/SensorProps.aidl | 13 +++++++------ .../hardware/biometrics/face/SessionState.aidl | 13 +++++++------ .../biometrics/face/ISessionCallback.aidl | 5 ++++- .../aidl/vts/VtsHalBiometricsFaceTargetTest.cpp | 4 +++- .../biometrics/fingerprint/AcquiredInfo.aidl | 13 +++++++------ .../hardware/biometrics/fingerprint/Error.aidl | 13 +++++++------ .../fingerprint/FingerprintSensorType.aidl | 13 +++++++------ .../biometrics/fingerprint/IFingerprint.aidl | 13 +++++++------ .../hardware/biometrics/fingerprint/ISession.aidl | 13 +++++++------ .../biometrics/fingerprint/ISessionCallback.aidl | 15 ++++++++------- .../biometrics/fingerprint/SensorProps.aidl | 13 +++++++------ .../biometrics/fingerprint/SessionState.aidl | 13 +++++++------ .../biometrics/fingerprint/ISessionCallback.aidl | 5 ++++- .../vts/VtsHalBiometricsFingerprintTargetTest.cpp | 2 +- 20 files changed, 126 insertions(+), 102 deletions(-) diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl index a05fad9da9..56d097d5ff 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl @@ -2,13 +2,14 @@ // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Error.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Error.aidl index 15fcbf959a..cba6ec595f 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Error.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Error.aidl @@ -2,13 +2,14 @@ // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/FaceSensorType.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/FaceSensorType.aidl index 943129ed8a..b08c345b5d 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/FaceSensorType.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/FaceSensorType.aidl @@ -2,13 +2,14 @@ // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl index 518fb147f4..65afaa493f 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl @@ -2,13 +2,14 @@ // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped diff --git a/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 5d9a430779..7d70971479 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 @@ -2,13 +2,14 @@ // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl index caf65aea1c..4cea0f0d99 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl @@ -2,13 +2,14 @@ // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped @@ -33,5 +34,5 @@ interface ISessionCallback { void onEnrollmentsEnumerated(in int[] enrollmentIds); void onEnrollmentsRemoved(in int[] enrollmentIds); void onAuthenticatorIdRetrieved(in long authenticatorId); - void onAuthenticatorIdInvalidated(); + void onAuthenticatorIdInvalidated(in long newAuthenticatorId); } diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl index 365ae58a46..a52829cc5b 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl @@ -2,13 +2,14 @@ // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SessionState.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SessionState.aidl index 8e5139b38b..12a5eabbc4 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SessionState.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SessionState.aidl @@ -2,13 +2,14 @@ // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl index fd4a648843..d59ce2e349 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl @@ -195,6 +195,9 @@ interface ISessionCallback { * SessionState::INVALIDATING_AUTHENTICATOR_ID. * * See ISession#invalidateAuthenticatorId for more information. + * + * @param newAuthenticatorId The new entropy-encoded random identifier associated with the + * current set of enrollments. */ - void onAuthenticatorIdInvalidated(); + void onAuthenticatorIdInvalidated(in long newAuthenticatorId); } diff --git a/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp b/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp index 5f1030620d..f6d0aab44e 100644 --- a/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp +++ b/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp @@ -103,7 +103,9 @@ class SessionCallback : public BnSessionCallback { return ndk::ScopedAStatus::ok(); } - ndk::ScopedAStatus onAuthenticatorIdInvalidated() override { return ndk::ScopedAStatus::ok(); } + ndk::ScopedAStatus onAuthenticatorIdInvalidated(int64_t /*newAuthenticatorId*/) override { + return ndk::ScopedAStatus::ok(); + } private: std::promise invocation_promise_; diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl index df30dcae47..d5f2ed27c6 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl @@ -2,13 +2,14 @@ // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl index 6bd71b2d34..aec499f229 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl @@ -2,13 +2,14 @@ // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl index 14bfece745..784e1d0d2f 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl @@ -2,13 +2,14 @@ // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl index c5c6786542..51b4c63799 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl @@ -2,13 +2,14 @@ // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped diff --git a/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 4df79817bf..185d86ff24 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 @@ -2,13 +2,14 @@ // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl index b7a48a5186..cf663a5670 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl @@ -2,13 +2,14 @@ // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped @@ -33,5 +34,5 @@ interface ISessionCallback { void onEnrollmentsEnumerated(in int[] enrollmentIds); void onEnrollmentsRemoved(in int[] enrollmentIds); void onAuthenticatorIdRetrieved(in long authenticatorId); - void onAuthenticatorIdInvalidated(); + void onAuthenticatorIdInvalidated(in long newAuthenticatorId); } diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl index 8c779abc09..f8a40a964f 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl @@ -2,13 +2,14 @@ // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.aidl index e9daef1740..3453f93763 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.aidl @@ -2,13 +2,14 @@ // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl index 4387f988d0..fde1df753d 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl @@ -195,6 +195,9 @@ interface ISessionCallback { * SessionState::INVALIDATING_AUTHENTICATOR_ID. * * See ISession#invalidateAuthenticatorId for more information. + * + * @param newAuthenticatorId The new entropy-encoded random identifier associated with the + * current set of enrollments. */ - void onAuthenticatorIdInvalidated(); + void onAuthenticatorIdInvalidated(in long newAuthenticatorId); } diff --git a/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp b/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp index adb98ac46f..ddbc0fee5a 100644 --- a/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp +++ b/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp @@ -110,7 +110,7 @@ class SessionCallback : public BnSessionCallback { return ndk::ScopedAStatus::ok(); } - ndk::ScopedAStatus onAuthenticatorIdInvalidated() override { + ndk::ScopedAStatus onAuthenticatorIdInvalidated(int64_t /*newAuthenticatorId*/) override { return ndk::ScopedAStatus::ok(); } -- GitLab From 0b6341c67aac9d4bf8962c0296298ec0739e5603 Mon Sep 17 00:00:00 2001 From: Kai Shi Date: Mon, 11 Jan 2021 20:22:59 -0800 Subject: [PATCH 381/790] Add dtim config optimization HAL API Test: compilation and halutil test Bug: 170678227 Change-Id: I4f7535a70e53bd55f02b70867d071c440ad1529f --- wifi/1.5/default/wifi_legacy_hal.cpp | 6 ++++++ wifi/1.5/default/wifi_legacy_hal.h | 3 +++ wifi/1.5/default/wifi_legacy_hal_stubs.cpp | 1 + 3 files changed, 10 insertions(+) diff --git a/wifi/1.5/default/wifi_legacy_hal.cpp b/wifi/1.5/default/wifi_legacy_hal.cpp index e1a5a8c957..3e65ee0f25 100644 --- a/wifi/1.5/default/wifi_legacy_hal.cpp +++ b/wifi/1.5/default/wifi_legacy_hal.cpp @@ -1630,6 +1630,12 @@ wifi_error WifiLegacyHal::twtClearStats(const std::string& 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); +} + void WifiLegacyHal::invalidate() { global_handle_ = nullptr; iface_name_to_handle_.clear(); diff --git a/wifi/1.5/default/wifi_legacy_hal.h b/wifi/1.5/default/wifi_legacy_hal.h index 610a3326d1..0cc1cff8cf 100644 --- a/wifi/1.5/default/wifi_legacy_hal.h +++ b/wifi/1.5/default/wifi_legacy_hal.h @@ -690,6 +690,9 @@ class WifiLegacyHal { wifi_error twtClearStats(const std::string& iface_name, uint8_t configId); + wifi_error setDtimConfig(const std::string& iface_name, + uint32_t multiplier); + private: // Retrieve interface handles for all the available interfaces. wifi_error retrieveIfaceHandles(); diff --git a/wifi/1.5/default/wifi_legacy_hal_stubs.cpp b/wifi/1.5/default/wifi_legacy_hal_stubs.cpp index 4b005d6809..7ba5d9b804 100644 --- a/wifi/1.5/default/wifi_legacy_hal_stubs.cpp +++ b/wifi/1.5/default/wifi_legacy_hal_stubs.cpp @@ -158,6 +158,7 @@ bool initHalFuncTableWithStubs(wifi_hal_fn* hal_fn) { populateStubFor(&hal_fn->wifi_twt_info_frame_request); populateStubFor(&hal_fn->wifi_twt_get_stats); populateStubFor(&hal_fn->wifi_twt_clear_stats); + populateStubFor(&hal_fn->wifi_set_dtim_config); return true; } } // namespace legacy_hal -- GitLab From 080fbf755c48a944586ecd739f02570b7aa611ee Mon Sep 17 00:00:00 2001 From: Michael Butler Date: Mon, 11 Jan 2021 19:35:53 -0800 Subject: [PATCH 382/790] Add isUpdatable to NNAPI canonical IDevice -- hal Bug: 177284207 Test: mma Change-Id: I580d5325be91f566ee1c591736a87a94d0a74315 --- .../1.0/utils/include/nnapi/hal/1.0/Device.h | 1 + neuralnetworks/1.0/utils/src/Device.cpp | 4 ++++ .../1.1/utils/include/nnapi/hal/1.1/Device.h | 1 + neuralnetworks/1.1/utils/src/Device.cpp | 4 ++++ .../1.2/utils/include/nnapi/hal/1.2/Device.h | 1 + neuralnetworks/1.2/utils/src/Device.cpp | 4 ++++ .../1.3/utils/include/nnapi/hal/1.3/Device.h | 1 + neuralnetworks/1.3/utils/src/Device.cpp | 4 ++++ .../utils/common/include/nnapi/hal/InvalidDevice.h | 4 +++- .../utils/common/include/nnapi/hal/ResilientDevice.h | 1 + neuralnetworks/utils/common/src/InvalidDevice.cpp | 9 +++++++-- neuralnetworks/utils/common/src/ResilientDevice.cpp | 12 +++++++++--- neuralnetworks/utils/common/test/MockDevice.h | 1 + 13 files changed, 41 insertions(+), 6 deletions(-) diff --git a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Device.h b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Device.h index db3b2ad44f..4681b9e47f 100644 --- a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Device.h +++ b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Device.h @@ -52,6 +52,7 @@ class Device final : public nn::IDevice { const std::string& getVersionString() const override; nn::Version getFeatureLevel() const override; nn::DeviceType getType() const override; + bool isUpdatable() const override; const std::vector& getSupportedExtensions() const override; const nn::Capabilities& getCapabilities() const override; std::pair getNumberOfCacheFilesNeeded() const override; diff --git a/neuralnetworks/1.0/utils/src/Device.cpp b/neuralnetworks/1.0/utils/src/Device.cpp index 93bd81a19c..bb31a266e0 100644 --- a/neuralnetworks/1.0/utils/src/Device.cpp +++ b/neuralnetworks/1.0/utils/src/Device.cpp @@ -106,6 +106,10 @@ nn::DeviceType Device::getType() const { return nn::DeviceType::OTHER; } +bool Device::isUpdatable() const { + return false; +} + const std::vector& Device::getSupportedExtensions() const { return kExtensions; } diff --git a/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Device.h b/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Device.h index 5e224b5018..3aec8ee497 100644 --- a/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Device.h +++ b/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Device.h @@ -52,6 +52,7 @@ class Device final : public nn::IDevice { const std::string& getVersionString() const override; nn::Version getFeatureLevel() const override; nn::DeviceType getType() const override; + bool isUpdatable() const override; const std::vector& getSupportedExtensions() const override; const nn::Capabilities& getCapabilities() const override; std::pair getNumberOfCacheFilesNeeded() const override; diff --git a/neuralnetworks/1.1/utils/src/Device.cpp b/neuralnetworks/1.1/utils/src/Device.cpp index 3197ef4ac3..d2ef57f18e 100644 --- a/neuralnetworks/1.1/utils/src/Device.cpp +++ b/neuralnetworks/1.1/utils/src/Device.cpp @@ -106,6 +106,10 @@ nn::DeviceType Device::getType() const { return nn::DeviceType::UNKNOWN; } +bool Device::isUpdatable() const { + return false; +} + const std::vector& Device::getSupportedExtensions() const { return kExtensions; } diff --git a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Device.h b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Device.h index b4bef5ee0a..489f85749d 100644 --- a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Device.h +++ b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Device.h @@ -71,6 +71,7 @@ class Device final : public nn::IDevice { const std::string& getVersionString() const override; nn::Version getFeatureLevel() const override; nn::DeviceType getType() const override; + bool isUpdatable() const override; const std::vector& getSupportedExtensions() const override; const nn::Capabilities& getCapabilities() const override; std::pair getNumberOfCacheFilesNeeded() const override; diff --git a/neuralnetworks/1.2/utils/src/Device.cpp b/neuralnetworks/1.2/utils/src/Device.cpp index 9fe0de25b3..1954dfa5bf 100644 --- a/neuralnetworks/1.2/utils/src/Device.cpp +++ b/neuralnetworks/1.2/utils/src/Device.cpp @@ -199,6 +199,10 @@ nn::DeviceType Device::getType() const { return kDeviceType; } +bool Device::isUpdatable() const { + return false; +} + const std::vector& Device::getSupportedExtensions() const { return kExtensions; } diff --git a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Device.h b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Device.h index 84f606a357..f36b6c0642 100644 --- a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Device.h +++ b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Device.h @@ -54,6 +54,7 @@ class Device final : public nn::IDevice { const std::string& getVersionString() const override; nn::Version getFeatureLevel() const override; nn::DeviceType getType() const override; + bool isUpdatable() const override; const std::vector& getSupportedExtensions() const override; const nn::Capabilities& getCapabilities() const override; std::pair getNumberOfCacheFilesNeeded() const override; diff --git a/neuralnetworks/1.3/utils/src/Device.cpp b/neuralnetworks/1.3/utils/src/Device.cpp index d710b85070..87c9f32e4d 100644 --- a/neuralnetworks/1.3/utils/src/Device.cpp +++ b/neuralnetworks/1.3/utils/src/Device.cpp @@ -150,6 +150,10 @@ nn::DeviceType Device::getType() const { return kDeviceType; } +bool Device::isUpdatable() const { + return false; +} + const std::vector& Device::getSupportedExtensions() const { return kExtensions; } diff --git a/neuralnetworks/utils/common/include/nnapi/hal/InvalidDevice.h b/neuralnetworks/utils/common/include/nnapi/hal/InvalidDevice.h index 5e62b9ae0b..d8435262cc 100644 --- a/neuralnetworks/utils/common/include/nnapi/hal/InvalidDevice.h +++ b/neuralnetworks/utils/common/include/nnapi/hal/InvalidDevice.h @@ -32,7 +32,7 @@ namespace android::hardware::neuralnetworks::utils { class InvalidDevice final : public nn::IDevice { public: InvalidDevice(std::string name, std::string versionString, nn::Version featureLevel, - nn::DeviceType type, std::vector extensions, + nn::DeviceType type, bool isUpdatable, std::vector extensions, nn::Capabilities capabilities, std::pair numberOfCacheFilesNeeded); @@ -40,6 +40,7 @@ class InvalidDevice final : public nn::IDevice { const std::string& getVersionString() const override; nn::Version getFeatureLevel() const override; nn::DeviceType getType() const override; + bool isUpdatable() const override; const std::vector& getSupportedExtensions() const override; const nn::Capabilities& getCapabilities() const override; std::pair getNumberOfCacheFilesNeeded() const override; @@ -70,6 +71,7 @@ class InvalidDevice final : public nn::IDevice { const std::string kVersionString; const nn::Version kFeatureLevel; const nn::DeviceType kType; + const bool kIsUpdatable; const std::vector kExtensions; const nn::Capabilities kCapabilities; const std::pair kNumberOfCacheFilesNeeded; diff --git a/neuralnetworks/utils/common/include/nnapi/hal/ResilientDevice.h b/neuralnetworks/utils/common/include/nnapi/hal/ResilientDevice.h index 84ae799aad..8199c522e3 100644 --- a/neuralnetworks/utils/common/include/nnapi/hal/ResilientDevice.h +++ b/neuralnetworks/utils/common/include/nnapi/hal/ResilientDevice.h @@ -53,6 +53,7 @@ class ResilientDevice final : public nn::IDevice, const std::string& getVersionString() const override; nn::Version getFeatureLevel() const override; nn::DeviceType getType() const override; + bool isUpdatable() const override; const std::vector& getSupportedExtensions() const override; const nn::Capabilities& getCapabilities() const override; std::pair getNumberOfCacheFilesNeeded() const override; diff --git a/neuralnetworks/utils/common/src/InvalidDevice.cpp b/neuralnetworks/utils/common/src/InvalidDevice.cpp index 535ccb41c7..81bca7fad0 100644 --- a/neuralnetworks/utils/common/src/InvalidDevice.cpp +++ b/neuralnetworks/utils/common/src/InvalidDevice.cpp @@ -32,13 +32,14 @@ namespace android::hardware::neuralnetworks::utils { InvalidDevice::InvalidDevice(std::string name, std::string versionString, nn::Version featureLevel, - nn::DeviceType type, std::vector extensions, - nn::Capabilities capabilities, + nn::DeviceType type, bool isUpdatable, + std::vector extensions, nn::Capabilities capabilities, std::pair numberOfCacheFilesNeeded) : kName(std::move(name)), kVersionString(std::move(versionString)), kFeatureLevel(featureLevel), kType(type), + kIsUpdatable(isUpdatable), kExtensions(std::move(extensions)), kCapabilities(std::move(capabilities)), kNumberOfCacheFilesNeeded(numberOfCacheFilesNeeded) {} @@ -59,6 +60,10 @@ nn::DeviceType InvalidDevice::getType() const { return kType; } +bool InvalidDevice::isUpdatable() const { + return kIsUpdatable; +} + const std::vector& InvalidDevice::getSupportedExtensions() const { return kExtensions; } diff --git a/neuralnetworks/utils/common/src/ResilientDevice.cpp b/neuralnetworks/utils/common/src/ResilientDevice.cpp index 2023c9af30..13965afd37 100644 --- a/neuralnetworks/utils/common/src/ResilientDevice.cpp +++ b/neuralnetworks/utils/common/src/ResilientDevice.cpp @@ -122,12 +122,14 @@ nn::GeneralResult ResilientDevice::recover(const nn::IDevice* }; if (compare(&IDevice::getName) || compare(&IDevice::getVersionString) || compare(&IDevice::getFeatureLevel) || compare(&IDevice::getType) || - compare(&IDevice::getSupportedExtensions) || compare(&IDevice::getCapabilities)) { + compare(&IDevice::isUpdatable) || compare(&IDevice::getSupportedExtensions) || + compare(&IDevice::getCapabilities)) { LOG(ERROR) << "Recovered device has different metadata than what is cached. Marking " "IDevice object as invalid."; device = std::make_shared( - kName, kVersionString, mDevice->getFeatureLevel(), mDevice->getType(), kExtensions, - kCapabilities, mDevice->getNumberOfCacheFilesNeeded()); + kName, kVersionString, mDevice->getFeatureLevel(), mDevice->getType(), + mDevice->isUpdatable(), kExtensions, kCapabilities, + mDevice->getNumberOfCacheFilesNeeded()); mIsValid = false; } @@ -151,6 +153,10 @@ nn::DeviceType ResilientDevice::getType() const { return getDevice()->getType(); } +bool ResilientDevice::isUpdatable() const { + return getDevice()->isUpdatable(); +} + const std::vector& ResilientDevice::getSupportedExtensions() const { return kExtensions; } diff --git a/neuralnetworks/utils/common/test/MockDevice.h b/neuralnetworks/utils/common/test/MockDevice.h index 08cd5c5501..5566968c68 100644 --- a/neuralnetworks/utils/common/test/MockDevice.h +++ b/neuralnetworks/utils/common/test/MockDevice.h @@ -29,6 +29,7 @@ class MockDevice final : public IDevice { MOCK_METHOD(const std::string&, getVersionString, (), (const, override)); MOCK_METHOD(Version, getFeatureLevel, (), (const, override)); MOCK_METHOD(DeviceType, getType, (), (const, override)); + MOCK_METHOD(bool, isUpdatable, (), (const, override)); MOCK_METHOD(const std::vector&, getSupportedExtensions, (), (const, override)); MOCK_METHOD(const Capabilities&, getCapabilities, (), (const, override)); MOCK_METHOD((std::pair), getNumberOfCacheFilesNeeded, (), -- GitLab From da62c38e5866994c6cc99d1956ed6fe5570b036b Mon Sep 17 00:00:00 2001 From: Kumar Anand Date: Wed, 18 Nov 2020 17:17:47 -0800 Subject: [PATCH 383/790] Wifi: Chip level API to set the country code Country code is global setting across the Wifi chip and not really Wifi interface (STA or AP) specific. Framework should have the ability to set the country code on a chip level without requiring supplicant instance to be running. As long as there is at least one active interface to communicate to kernel driver, country code can be set and driver should apply the setting globally. Bug: 149936939 Test: VTS - VtsHalWifiV1_5TargetTest Change-Id: I1be5dae34b216a6152d09605d055872d5345507c --- wifi/1.5/IWifiChip.hal | 18 ++++++++++++++++++ wifi/1.5/default/wifi_chip.cpp | 13 +++++++++++++ wifi/1.5/default/wifi_chip.h | 4 +++- .../1.5/vts/functional/wifi_chip_hidl_test.cpp | 14 ++++++++++++++ 4 files changed, 48 insertions(+), 1 deletion(-) diff --git a/wifi/1.5/IWifiChip.hal b/wifi/1.5/IWifiChip.hal index 80f2ca448c..b2960cfa7a 100644 --- a/wifi/1.5/IWifiChip.hal +++ b/wifi/1.5/IWifiChip.hal @@ -216,4 +216,22 @@ interface IWifiChip extends @1.4::IWifiChip { setCoexUnsafeChannels( vec unsafeChannels, bitfield restrictions) generates (WifiStatus status); + + /** + * Set country code for this Wifi chip. + * + * Country code is global setting across the Wifi chip and not Wifi + * interface (STA or AP) specific. Legacy HAL API's for country code in + * @1.0::ISupplicantStaIface::setCountryCode & + * @1.0::IWifiApIface:setCountryCode are deprecated in favor of this + * chip level API. + * + * @param code 2 byte country code (as defined in ISO 3166) to set. + * @return status Status of the operation. + * Possible status codes: + * |WifiStatusCode.SUCCESS|, + * |WifiStatusCode.FAILURE_UNKNOWN|, + * |WifiStatusCode.FAILURE_IFACE_INVALID| + */ + setCountryCode(int8_t[2] code) generates (WifiStatus status); }; diff --git a/wifi/1.5/default/wifi_chip.cpp b/wifi/1.5/default/wifi_chip.cpp index 6dd400c899..d3a617a90a 100644 --- a/wifi/1.5/default/wifi_chip.cpp +++ b/wifi/1.5/default/wifi_chip.cpp @@ -731,6 +731,13 @@ Return WifiChip::setCoexUnsafeChannels( hidl_status_cb, unsafeChannels, restrictions); } +Return WifiChip::setCountryCode(const hidl_array& code, + setCountryCode_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiChip::setCountryCodeInternal, hidl_status_cb, + code); +} + void WifiChip::invalidateAndRemoveAllIfaces() { invalidateAndClearBridgedApAll(); invalidateAndClearAll(ap_ifaces_); @@ -1478,6 +1485,12 @@ WifiStatus WifiChip::setCoexUnsafeChannelsInternal( return createWifiStatusFromLegacyError(legacy_status); } +WifiStatus WifiChip::setCountryCodeInternal(const std::array& code) { + auto legacy_status = + legacy_hal_.lock()->setCountryCode(getFirstActiveWlanIfaceName(), code); + return createWifiStatusFromLegacyError(legacy_status); +} + WifiStatus WifiChip::handleChipConfiguration( /* NONNULL */ std::unique_lock* lock, ChipModeId mode_id) { diff --git a/wifi/1.5/default/wifi_chip.h b/wifi/1.5/default/wifi_chip.h index 95c122d2b1..7d7a9b546c 100644 --- a/wifi/1.5/default/wifi_chip.h +++ b/wifi/1.5/default/wifi_chip.h @@ -178,6 +178,8 @@ class WifiChip : public V1_5::IWifiChip { const hidl_vec& unsafe_channels, hidl_bitfield restrictions, setCoexUnsafeChannels_cb hidl_status_cb) override; + Return setCountryCode(const hidl_array& code, + setCountryCode_cb _hidl_cb) override; private: void invalidateAndRemoveAllIfaces(); @@ -258,7 +260,7 @@ class WifiChip : public V1_5::IWifiChip { WifiStatus setMultiStaUseCaseInternal(MultiStaUseCase use_case); WifiStatus setCoexUnsafeChannelsInternal( std::vector unsafe_channels, uint32_t restrictions); - + WifiStatus setCountryCodeInternal(const std::array& code); WifiStatus handleChipConfiguration( std::unique_lock* lock, ChipModeId mode_id); WifiStatus registerDebugRingBufferCallback(); diff --git a/wifi/1.5/vts/functional/wifi_chip_hidl_test.cpp b/wifi/1.5/vts/functional/wifi_chip_hidl_test.cpp index a0657218f4..36a8448d04 100644 --- a/wifi/1.5/vts/functional/wifi_chip_hidl_test.cpp +++ b/wifi/1.5/vts/functional/wifi_chip_hidl_test.cpp @@ -173,6 +173,20 @@ TEST_P(WifiChipHidlTest, setCoexUnsafeChannels) { } } +/* + * SetCountryCode: + * Ensures that a call to set the country code will return with a success + * status code. + */ +TEST_P(WifiChipHidlTest, setCountryCode) { + const android::hardware::hidl_array kCountryCode{ + std::array{{0x55, 0x53}}}; + + configureChipForIfaceType(IfaceType::STA, true); + EXPECT_EQ(WifiStatusCode::SUCCESS, + HIDL_INVOKE(wifi_chip_, setCountryCode, kCountryCode).code); +} + GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiChipHidlTest); INSTANTIATE_TEST_SUITE_P( PerInstance, WifiChipHidlTest, -- GitLab From 001c4bf209b8b99a3a7e6d000dd2486f011e40a4 Mon Sep 17 00:00:00 2001 From: More Kuo Date: Wed, 13 Jan 2021 16:22:44 +0800 Subject: [PATCH 384/790] BT: Make Bluetooth HCI VTS tests more stable Extend to 600 ms sleep after BluetoothHci->close() to give HAL an ample time to shutdown Test: make, VtsHalBluetoothV1_0TargetTest Bug: 176503623 Change-Id: If6d293167309b9dbcae94cf03199a6c95ecf9836 --- bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp b/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp index 0328af1d82..76777dcd73 100644 --- a/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp +++ b/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp @@ -50,7 +50,7 @@ using ::android::hardware::bluetooth::V1_0::Status; #define WAIT_FOR_HCI_EVENT_TIMEOUT std::chrono::milliseconds(2000) #define WAIT_FOR_SCO_DATA_TIMEOUT std::chrono::milliseconds(1000) #define WAIT_FOR_ACL_DATA_TIMEOUT std::chrono::milliseconds(1000) -#define INTERFACE_CLOSE_DELAY_MS std::chrono::milliseconds(200) +#define INTERFACE_CLOSE_DELAY_MS std::chrono::milliseconds(600) #define COMMAND_HCI_SHOULD_BE_UNKNOWN \ { 0xff, 0x3B, 0x08, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 } -- GitLab From 4abab5060393afa730b69ec4267b8d7c52f17103 Mon Sep 17 00:00:00 2001 From: Shinru Han Date: Wed, 9 Dec 2020 15:07:18 +0800 Subject: [PATCH 385/790] Add CorrelationVector AIDL HAL Adds CorrelationVector into GnssMeasurement report. Bug: 171516016 Test: on cuttlefish Change-Id: Ibe47f4839012d34272fd2d0b079e1edda6282fd2 --- .../hardware/gnss/BlocklistedSource.aidl | 13 ++--- .../hardware/gnss/CorrelationVector.aidl | 26 ++++++++++ .../hardware/gnss/ElapsedRealtime.aidl | 13 ++--- .../android/hardware/gnss/GnssClock.aidl | 13 ++--- .../hardware/gnss/GnssConstellationType.aidl | 13 ++--- .../android/hardware/gnss/GnssData.aidl | 13 ++--- .../hardware/gnss/GnssMeasurement.aidl | 2 + .../hardware/gnss/GnssMultipathIndicator.aidl | 13 ++--- .../android/hardware/gnss/GnssPowerStats.aidl | 13 ++--- .../android/hardware/gnss/GnssSignalType.aidl | 13 ++--- .../current/android/hardware/gnss/IGnss.aidl | 13 ++--- .../android/hardware/gnss/IGnssCallback.aidl | 1 + .../hardware/gnss/IGnssConfiguration.aidl | 13 ++--- .../gnss/IGnssMeasurementCallback.aidl | 13 ++--- .../gnss/IGnssMeasurementInterface.aidl | 15 +++--- .../hardware/gnss/IGnssPowerIndication.aidl | 13 ++--- .../gnss/IGnssPowerIndicationCallback.aidl | 13 ++--- .../android/hardware/gnss/IGnssPsds.aidl | 13 ++--- .../hardware/gnss/IGnssPsdsCallback.aidl | 13 ++--- .../android/hardware/gnss/PsdsType.aidl | 13 ++--- .../hardware/gnss/CorrelationVector.aidl | 51 +++++++++++++++++++ .../hardware/gnss/GnssMeasurement.aidl | 14 +++++ .../android/hardware/gnss/IGnssCallback.aidl | 5 +- .../gnss/IGnssMeasurementInterface.aidl | 6 ++- gnss/aidl/default/Gnss.cpp | 4 +- .../aidl/default/GnssMeasurementInterface.cpp | 14 ++--- gnss/aidl/default/GnssMeasurementInterface.h | 5 +- gnss/aidl/vts/gnss_hal_test_cases.cpp | 26 +++++++++- gnss/common/utils/default/Utils.cpp | 20 +++++++- gnss/common/utils/default/include/Utils.h | 3 +- 30 files changed, 281 insertions(+), 119 deletions(-) create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/CorrelationVector.aidl create mode 100644 gnss/aidl/android/hardware/gnss/CorrelationVector.aidl diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/BlocklistedSource.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/BlocklistedSource.aidl index 89f5d53106..03026761f8 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/BlocklistedSource.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/BlocklistedSource.aidl @@ -2,13 +2,14 @@ // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/CorrelationVector.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/CorrelationVector.aidl new file mode 100644 index 0000000000..1f713fa4e0 --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/CorrelationVector.aidl @@ -0,0 +1,26 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.gnss; +@VintfStability +parcelable CorrelationVector { + int frequencyOffsetMps; + double samplingWidthM; + double samplingStartM; + int[] magnitude; +} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/ElapsedRealtime.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/ElapsedRealtime.aidl index a0e8de41a3..933f659c57 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/ElapsedRealtime.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/ElapsedRealtime.aidl @@ -2,13 +2,14 @@ // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssClock.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssClock.aidl index 42b940e886..53ac0efa37 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssClock.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssClock.aidl @@ -2,13 +2,14 @@ // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssConstellationType.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssConstellationType.aidl index 30d0227577..18fdfa91c2 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssConstellationType.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssConstellationType.aidl @@ -2,13 +2,14 @@ // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssData.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssData.aidl index 7ffabd2a3c..73ead10ff7 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssData.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssData.aidl @@ -2,13 +2,14 @@ // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMeasurement.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMeasurement.aidl index 7328f7ed40..3d287e4a1a 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMeasurement.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMeasurement.aidl @@ -44,6 +44,7 @@ parcelable GnssMeasurement { double satelliteInterSignalBiasNs; double satelliteInterSignalBiasUncertaintyNs; android.hardware.gnss.SatellitePvt satellitePvt; + android.hardware.gnss.CorrelationVector[] correlationVectors; const int HAS_SNR = 1; const int HAS_CARRIER_FREQUENCY = 512; const int HAS_CARRIER_CYCLES = 1024; @@ -55,6 +56,7 @@ parcelable GnssMeasurement { const int HAS_SATELLITE_ISB = 262144; const int HAS_SATELLITE_ISB_UNCERTAINTY = 524288; const int HAS_SATELLITE_PVT = 1048576; + const int HAS_CORRELATION_VECTOR = 2097152; const int STATE_UNKNOWN = 0; const int STATE_CODE_LOCK = 1; const int STATE_BIT_SYNC = 2; diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMultipathIndicator.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMultipathIndicator.aidl index 75ca3afbc3..5da60f7a6e 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMultipathIndicator.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMultipathIndicator.aidl @@ -2,13 +2,14 @@ // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssPowerStats.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssPowerStats.aidl index d385fd488c..358b570157 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssPowerStats.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssPowerStats.aidl @@ -2,13 +2,14 @@ // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssSignalType.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssSignalType.aidl index f10b9430dd..b2a498d009 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssSignalType.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssSignalType.aidl @@ -2,13 +2,14 @@ // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl index 10ac150a53..bd6f1ff34d 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl @@ -2,13 +2,14 @@ // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl index bf6d3c13a3..a04ad660a3 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl @@ -21,5 +21,6 @@ package android.hardware.gnss; interface IGnssCallback { void gnssSetCapabilitiesCb(in int capabilities); const int CAPABILITY_SATELLITE_BLOCKLIST = 1; + const int CAPABILITY_CORRELATION_VECTOR = 4096; const int CAPABILITY_SATELLITE_PVT = 8192; } diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssConfiguration.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssConfiguration.aidl index 5af30cf237..eb4ad82653 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssConfiguration.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssConfiguration.aidl @@ -2,13 +2,14 @@ // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementCallback.aidl index e05e9b9954..764b896955 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementCallback.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementCallback.aidl @@ -2,13 +2,14 @@ // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementInterface.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementInterface.aidl index 9576205772..7cb7395c18 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementInterface.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementInterface.aidl @@ -2,13 +2,14 @@ // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped @@ -18,6 +19,6 @@ package android.hardware.gnss; @VintfStability interface IGnssMeasurementInterface { - void setCallback(in android.hardware.gnss.IGnssMeasurementCallback callback, in boolean enableFullTracking); + void setCallback(in android.hardware.gnss.IGnssMeasurementCallback callback, in boolean enableFullTracking, in boolean enableCorrVecOutputs); void close(); } diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndication.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndication.aidl index 843489e941..c44903eadb 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndication.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndication.aidl @@ -2,13 +2,14 @@ // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndicationCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndicationCallback.aidl index 5281d29bc6..12e6762d2b 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndicationCallback.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndicationCallback.aidl @@ -2,13 +2,14 @@ // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsds.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsds.aidl index ddef9280ed..cae2ea6432 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsds.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsds.aidl @@ -2,13 +2,14 @@ // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsdsCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsdsCallback.aidl index 8413d2cc77..6888632fa2 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsdsCallback.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsdsCallback.aidl @@ -2,13 +2,14 @@ // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/PsdsType.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/PsdsType.aidl index 9d1984e292..d348c633d0 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/PsdsType.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/PsdsType.aidl @@ -2,13 +2,14 @@ // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped diff --git a/gnss/aidl/android/hardware/gnss/CorrelationVector.aidl b/gnss/aidl/android/hardware/gnss/CorrelationVector.aidl new file mode 100644 index 0000000000..22a80cec57 --- /dev/null +++ b/gnss/aidl/android/hardware/gnss/CorrelationVector.aidl @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.gnss; + +/** + * Contains info about the correlation output of incoming GNSS signal and a local copy of + * its corresponding spreading code at a given frequency offset. + */ +@VintfStability +parcelable CorrelationVector { + + /** + * Frequency offset from reported pseudorange rate for this Correlation Vector. + */ + int frequencyOffsetMps; + + /** + * Space between correlation samples in meters. + */ + double samplingWidthM; + + /** + * Offset of the first sampling bin in meters. + * The following sampling bins are located at positive offsets from this value as follows: + * samplingStartM, samplingStartM + samplingWidthM, ... , samplingStartM + + * (magnitude.size-1) * samplingWidthM. + */ + double samplingStartM; + + /** + * Normalized correlation magnitude values from -1 to 1, the reported value must be encoded as + * signed 16 bit integer where 1 is represented by 32767 and -1 is represented by -32768. + * + * The length of the array is defined by the GNSS chipset. + */ + int[] magnitude; +} \ No newline at end of file diff --git a/gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl b/gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl index 09897fb18e..2c56a41643 100644 --- a/gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl +++ b/gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl @@ -16,6 +16,7 @@ package android.hardware.gnss; +import android.hardware.gnss.CorrelationVector; import android.hardware.gnss.GnssSignalType; import android.hardware.gnss.GnssMultipathIndicator; import android.hardware.gnss.SatellitePvt; @@ -62,6 +63,10 @@ parcelable GnssMeasurement { * Bit mask indicating a valid satellite PVT is stored in the GnssMeasurement. */ const int HAS_SATELLITE_PVT = 1 << 20; + /** + * Bit mask indicating valid correlation vectors are stored in the GnssMeasurement. + */ + const int HAS_CORRELATION_VECTOR = 1 << 21; /** * A bitfield of flags indicating the validity of the fields in this GnssMeasurement. The bit @@ -625,4 +630,13 @@ parcelable GnssMeasurement { * If the data is available, gnssMeasurementFlags must contain HAS_SATELLITE_PVT. */ SatellitePvt satellitePvt; + + /** + * A list of Correlation Vectors with each vector corresponding to a frequency offset. + * + * To represent correlation values over a 2D spaces (delay and frequency), a CorrelationVector + * is required per frequency offset, and each CorrelationVector contains correlation values + * at equally spaced spatial offsets. + */ + CorrelationVector[] correlationVectors; } \ No newline at end of file diff --git a/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl b/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl index 1ea6faad0b..81e06382b4 100644 --- a/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl +++ b/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl @@ -27,9 +27,12 @@ import android.hardware.gnss.IGnssConfiguration; @VintfStability interface IGnssCallback { - /** Capability bit mask indicating GNSS supports blocklisting satellites */ + /** Capability bit mask indicating that GNSS supports blocklisting satellites */ const int CAPABILITY_SATELLITE_BLOCKLIST = 1 << 0; + /** Capability bit mask indicating that GNSS supports correlation vector */ + const int CAPABILITY_CORRELATION_VECTOR = 1 << 12; + /** Capability bit mask indicating that GNSS supports satellite PVT */ const int CAPABILITY_SATELLITE_PVT = 1 << 13; diff --git a/gnss/aidl/android/hardware/gnss/IGnssMeasurementInterface.aidl b/gnss/aidl/android/hardware/gnss/IGnssMeasurementInterface.aidl index fdeebde8ae..04cdf6417b 100644 --- a/gnss/aidl/android/hardware/gnss/IGnssMeasurementInterface.aidl +++ b/gnss/aidl/android/hardware/gnss/IGnssMeasurementInterface.aidl @@ -37,12 +37,16 @@ interface IGnssMeasurementInterface { * The GNSS chipset is allowed to consume more power in this mode. If false, API must * optimize power via duty cycling, constellations and frequency limits, etc. * + * @param enableCorrVecOutputs If true, enable correlation vectors as part of the raw GNSS + * measurements outputs. If false, disable correlation vectors. + * * @return initRet Returns SUCCESS if successful. Returns ERROR_ALREADY_INIT if a callback has * already been registered without a corresponding call to 'close'. Returns ERROR_GENERIC * for any other error. The HAL must not generate any other updates upon returning this * error code. */ - void setCallback(in IGnssMeasurementCallback callback, in boolean enableFullTracking); + void setCallback(in IGnssMeasurementCallback callback, in boolean enableFullTracking, + in boolean enableCorrVecOutputs); /** * Stops updates from the HAL, and unregisters the callback routines. After a call to close(), diff --git a/gnss/aidl/default/Gnss.cpp b/gnss/aidl/default/Gnss.cpp index 661f3511b1..435afa3576 100644 --- a/gnss/aidl/default/Gnss.cpp +++ b/gnss/aidl/default/Gnss.cpp @@ -37,7 +37,9 @@ ndk::ScopedAStatus Gnss::setCallback(const std::shared_ptr& callb sGnssCallback = callback; int capabilities = (int)(IGnssCallback::CAPABILITY_SATELLITE_BLOCKLIST | - IGnssCallback::CAPABILITY_SATELLITE_PVT); + IGnssCallback::CAPABILITY_SATELLITE_PVT | + IGnssCallback::CAPABILITY_CORRELATION_VECTOR); + auto status = sGnssCallback->gnssSetCapabilitiesCb(capabilities); if (!status.isOk()) { ALOGE("%s: Unable to invoke callback.gnssSetCapabilities", __func__); diff --git a/gnss/aidl/default/GnssMeasurementInterface.cpp b/gnss/aidl/default/GnssMeasurementInterface.cpp index d726d9502f..cae9499077 100644 --- a/gnss/aidl/default/GnssMeasurementInterface.cpp +++ b/gnss/aidl/default/GnssMeasurementInterface.cpp @@ -34,8 +34,10 @@ GnssMeasurementInterface::~GnssMeasurementInterface() { } ndk::ScopedAStatus GnssMeasurementInterface::setCallback( - const std::shared_ptr& callback, const bool enableFullTracking) { - ALOGD("setCallback: enableFullTracking: %d", (int)enableFullTracking); + const std::shared_ptr& callback, const bool enableFullTracking, + const bool enableCorrVecOutputs) { + ALOGD("setCallback: enableFullTracking: %d enableCorrVecOutputs: %d", (int)enableFullTracking, + (int)enableCorrVecOutputs); std::unique_lock lock(mMutex); sCallback = callback; @@ -43,7 +45,7 @@ ndk::ScopedAStatus GnssMeasurementInterface::setCallback( ALOGW("GnssMeasurement callback already set. Resetting the callback..."); stop(); } - start(); + start(enableCorrVecOutputs); return ndk::ScopedAStatus::ok(); } @@ -56,12 +58,12 @@ ndk::ScopedAStatus GnssMeasurementInterface::close() { return ndk::ScopedAStatus::ok(); } -void GnssMeasurementInterface::start() { +void GnssMeasurementInterface::start(const bool enableCorrVecOutputs) { ALOGD("start"); mIsActive = true; - mThread = std::thread([this]() { + mThread = std::thread([this, enableCorrVecOutputs]() { while (mIsActive == true) { - auto measurement = Utils::getMockMeasurement(); + auto measurement = Utils::getMockMeasurement(enableCorrVecOutputs); this->reportMeasurement(measurement); std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMillis)); diff --git a/gnss/aidl/default/GnssMeasurementInterface.h b/gnss/aidl/default/GnssMeasurementInterface.h index 69cd871c96..db6351555d 100644 --- a/gnss/aidl/default/GnssMeasurementInterface.h +++ b/gnss/aidl/default/GnssMeasurementInterface.h @@ -29,11 +29,12 @@ struct GnssMeasurementInterface : public BnGnssMeasurementInterface { GnssMeasurementInterface(); ~GnssMeasurementInterface(); ndk::ScopedAStatus setCallback(const std::shared_ptr& callback, - const bool enableFullTracking) override; + const bool enableFullTracking, + const bool enableCorrVecOutputs) override; ndk::ScopedAStatus close() override; private: - void start(); + void start(const bool enableCorrVecOutputs); void stop(); void reportMeasurement(const GnssData&); diff --git a/gnss/aidl/vts/gnss_hal_test_cases.cpp b/gnss/aidl/vts/gnss_hal_test_cases.cpp index 18fda45f60..ae0551d63d 100644 --- a/gnss/aidl/vts/gnss_hal_test_cases.cpp +++ b/gnss/aidl/vts/gnss_hal_test_cases.cpp @@ -69,15 +69,21 @@ TEST_P(GnssHalTest, TestPsdsExtension) { * 2. Sets a GnssMeasurementCallback, waits for a measurement, and verifies fields are valid. */ TEST_P(GnssHalTest, TestGnssMeasurementExtension) { + const bool kIsCorrelationVectorSupported = aidl_gnss_cb_->last_capabilities_ & + (int)GnssCallbackAidl::CAPABILITY_CORRELATION_VECTOR; const int kFirstGnssMeasurementTimeoutSeconds = 10; + bool has_capability_satpvt = false; + sp iGnssMeasurement; auto status = aidl_gnss_hal_->getExtensionGnssMeasurement(&iGnssMeasurement); ASSERT_TRUE(status.isOk()); ASSERT_TRUE(iGnssMeasurement != nullptr); auto callback = sp::make(); - status = iGnssMeasurement->setCallback(callback, /* enableFullTracking= */ true); + status = + iGnssMeasurement->setCallback(callback, /* enableFullTracking= */ true, + /* enableCorrVecOutputs */ kIsCorrelationVectorSupported); ASSERT_TRUE(status.isOk()); android::hardware::gnss::GnssData lastMeasurement; @@ -118,7 +124,9 @@ TEST_P(GnssHalTest, TestGnssMeasurementExtension) { GnssMeasurement::HAS_FULL_ISB | GnssMeasurement::HAS_FULL_ISB_UNCERTAINTY | GnssMeasurement::HAS_SATELLITE_ISB | GnssMeasurement::HAS_SATELLITE_ISB_UNCERTAINTY | - GnssMeasurement::HAS_SATELLITE_PVT)); + GnssMeasurement::HAS_SATELLITE_PVT | + GnssMeasurement::HAS_CORRELATION_VECTOR)); + if ((measurement.flags & GnssMeasurement::HAS_SATELLITE_PVT) && (has_capability_satpvt == true)) { ASSERT_TRUE(measurement.satellitePvt.satPosEcef.posXMeters >= -43000000 && @@ -136,6 +144,20 @@ TEST_P(GnssHalTest, TestGnssMeasurementExtension) { measurement.satellitePvt.satVelEcef.velZMps <= 4000); ASSERT_TRUE(measurement.satellitePvt.satVelEcef.ureRateMps > 0); } + + if (kIsCorrelationVectorSupported && + measurement.flags & GnssMeasurement::HAS_CORRELATION_VECTOR) { + ASSERT_TRUE(measurement.correlationVectors.size() > 0); + for (const auto& correlationVector : measurement.correlationVectors) { + ASSERT_GE(correlationVector.frequencyOffsetMps, 0); + ASSERT_GT(correlationVector.samplingWidthM, 0); + ASSERT_GE(correlationVector.samplingStartM, 0); + ASSERT_TRUE(correlationVector.magnitude.size() > 0); + for (const auto& magnitude : correlationVector.magnitude) { + ASSERT_TRUE(magnitude >= -32768 && magnitude <= 32767); + } + } + } } status = iGnssMeasurement->close(); diff --git a/gnss/common/utils/default/Utils.cpp b/gnss/common/utils/default/Utils.cpp index 1079fa5c24..ccc7145d2c 100644 --- a/gnss/common/utils/default/Utils.cpp +++ b/gnss/common/utils/default/Utils.cpp @@ -140,7 +140,7 @@ GnssDataV2_0 Utils::getMockMeasurementV2_0() { return gnssData; } -GnssData Utils::getMockMeasurement() { +GnssData Utils::getMockMeasurement(const bool enableCorrVecOutputs) { aidl::android::hardware::gnss::GnssSignalType signalType = { .constellation = aidl::android::hardware::gnss::GnssConstellationType::GLONASS, .carrierFrequencyHz = 1.59975e+09, @@ -187,7 +187,8 @@ GnssData Utils::getMockMeasurement() { .satTimeCorrectionMeters = -7113.08964331, .satClkDriftMps = 0}, .ionoDelayMeters = 3.069949602639317e-08, - .tropoDelayMeters = 3.882265204404031}}; + .tropoDelayMeters = 3.882265204404031}, + .correlationVectors = {}}; GnssClock clock = {.gnssClockFlags = GnssClock::HAS_FULL_BIAS | GnssClock::HAS_FULL_BIAS | GnssClock::HAS_BIAS_UNCERTAINTY | GnssClock::HAS_DRIFT | @@ -208,6 +209,21 @@ GnssData Utils::getMockMeasurement() { // or don't set the field. .timeUncertaintyNs = 1020400}; + if (enableCorrVecOutputs) { + aidl::android::hardware::gnss::CorrelationVector correlationVector1 = { + .frequencyOffsetMps = 10, + .samplingWidthM = 30, + .samplingStartM = 0, + .magnitude = {0, 5000, 10000, 5000, 0, 0, 3000, 0}}; + aidl::android::hardware::gnss::CorrelationVector correlationVector2 = { + .frequencyOffsetMps = 20, + .samplingWidthM = 30, + .samplingStartM = 0, + .magnitude = {0, 3000, 5000, 3000, 0, 0, 1000, 0}}; + measurement.correlationVectors = {correlationVector1, correlationVector2}; + measurement.flags |= GnssMeasurement::HAS_CORRELATION_VECTOR; + } + GnssData gnssData = { .measurements = {measurement}, .clock = clock, .elapsedRealtime = timestamp}; return gnssData; diff --git a/gnss/common/utils/default/include/Utils.h b/gnss/common/utils/default/include/Utils.h index 0ca1b00e32..771d39dbd1 100644 --- a/gnss/common/utils/default/include/Utils.h +++ b/gnss/common/utils/default/include/Utils.h @@ -30,7 +30,8 @@ namespace gnss { namespace common { struct Utils { - static aidl::android::hardware::gnss::GnssData getMockMeasurement(); + static aidl::android::hardware::gnss::GnssData getMockMeasurement( + const bool enableCorrVecOutputs); static V2_0::IGnssMeasurementCallback::GnssData getMockMeasurementV2_0(); static V2_1::IGnssMeasurementCallback::GnssData getMockMeasurementV2_1(); static V2_0::GnssLocation getMockLocationV2_0(); -- GitLab From 6ee09f04577dc07e3242c1214fcb6d5501b29a77 Mon Sep 17 00:00:00 2001 From: Andy Hung Date: Tue, 12 Jan 2021 14:54:10 -0800 Subject: [PATCH 386/790] StreamOut: use atomic_sp<> for callback thread safety Test: see bug Test: basic audio works Bug: 177278988 Change-Id: Id1f5036e36b2a3b3e71e0b0ec548d4c65a972b50 --- audio/core/all-versions/default/Android.bp | 1 + audio/core/all-versions/default/StreamOut.cpp | 6 +++--- .../all-versions/default/include/core/default/StreamOut.h | 3 ++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/audio/core/all-versions/default/Android.bp b/audio/core/all-versions/default/Android.bp index e0f086094c..c75c779a91 100644 --- a/audio/core/all-versions/default/Android.bp +++ b/audio/core/all-versions/default/Android.bp @@ -51,6 +51,7 @@ cc_defaults { "libaudio_system_headers", "libhardware_headers", "libmedia_headers", + "libmediautils_headers", ], export_header_lib_headers: [ diff --git a/audio/core/all-versions/default/StreamOut.cpp b/audio/core/all-versions/default/StreamOut.cpp index ffd3b6b856..1fb72671bb 100644 --- a/audio/core/all-versions/default/StreamOut.cpp +++ b/audio/core/all-versions/default/StreamOut.cpp @@ -163,7 +163,7 @@ StreamOut::~StreamOut() { status_t status = EventFlag::deleteEventFlag(&mEfGroup); ALOGE_IF(status, "write MQ event flag deletion error: %s", strerror(-status)); } - mCallback.clear(); + mCallback = nullptr; #if MAJOR_VERSION <= 5 mDevice->closeOutputStream(mStream); // Closing the output stream in the HAL waits for the callback to finish, @@ -462,7 +462,7 @@ Return StreamOut::setCallback(const sp& callback) { Return StreamOut::clearCallback() { if (mStream->set_callback == NULL) return Result::NOT_SUPPORTED; - mCallback.clear(); + mCallback = nullptr; return Result::OK; } @@ -477,7 +477,7 @@ int StreamOut::asyncCallback(stream_callback_event_t event, void*, void* cookie) // It's correct to hold an sp<> to callback because the reference // in the StreamOut instance can be cleared in the meantime. There is // no difference on which thread to run IStreamOutCallback's destructor. - sp callback = self->mCallback; + sp callback = self->mCallback.load(); if (callback.get() == nullptr) return 0; ALOGV("asyncCallback() event %d", event); Return result; diff --git a/audio/core/all-versions/default/include/core/default/StreamOut.h b/audio/core/all-versions/default/include/core/default/StreamOut.h index b8e8515739..c246ef3e4c 100644 --- a/audio/core/all-versions/default/include/core/default/StreamOut.h +++ b/audio/core/all-versions/default/include/core/default/StreamOut.h @@ -29,6 +29,7 @@ #include #include #include +#include #include namespace android { @@ -158,7 +159,7 @@ struct StreamOut : public IStreamOut { audio_stream_out_t* mStream; const sp mStreamCommon; const sp> mStreamMmap; - sp mCallback; // Callback for non-blocking write and drain + mediautils::atomic_sp mCallback; // for non-blocking write and drain #if MAJOR_VERSION >= 6 sp mEventCallback; #endif -- GitLab From df24582044d2790b573a3bc473c784e88a9109c4 Mon Sep 17 00:00:00 2001 From: karthik bharadwaj Date: Wed, 13 Jan 2021 00:19:00 -0800 Subject: [PATCH 387/790] Update ContextHub HAL 1.2 Update ContextHub HAL 1.2 to include support for the Global Microphone Access Disable user setting. Bug: 174691697 Test: run vts -m VtsHalContexthubV1_2TargetTest -t ContexthubHidlTest Change-Id: I11bce59069fa97010b66f194a9ccc01a5b81f808 --- contexthub/1.2/types.hal | 6 ++++++ .../1.2/vts/functional/VtsHalContexthubV1_2TargetTest.cpp | 7 +++++++ 2 files changed, 13 insertions(+) diff --git a/contexthub/1.2/types.hal b/contexthub/1.2/types.hal index e6c8acc57d..5a11efea46 100644 --- a/contexthub/1.2/types.hal +++ b/contexthub/1.2/types.hal @@ -33,6 +33,12 @@ enum Setting : @1.1::Setting { */ WIFI_AVAILABLE, AIRPLANE_MODE, + + /** + * Indicates if the microphone access was turned off globally by the user, + * in which case audio data cannot be used and propagated by CHRE. + */ + GLOBAL_MIC_DISABLE, }; struct ContextHubMsg { diff --git a/contexthub/1.2/vts/functional/VtsHalContexthubV1_2TargetTest.cpp b/contexthub/1.2/vts/functional/VtsHalContexthubV1_2TargetTest.cpp index 77883c2423..782edae610 100644 --- a/contexthub/1.2/vts/functional/VtsHalContexthubV1_2TargetTest.cpp +++ b/contexthub/1.2/vts/functional/VtsHalContexthubV1_2TargetTest.cpp @@ -62,6 +62,13 @@ TEST_P(ContexthubHidlTest, TestOnAirplaneModeSettingChanged) { ASSERT_OK(registerCallback(nullptr)); } +TEST_P(ContexthubHidlTest, TestOnGlobalMicDisableSettingChanged) { + ASSERT_OK(registerCallback(new ContexthubCallbackBase())); + hubApi->onSettingChanged_1_2(Setting::GLOBAL_MIC_DISABLE, SettingValue::DISABLED); + hubApi->onSettingChanged_1_2(Setting::GLOBAL_MIC_DISABLE, SettingValue::ENABLED); + ASSERT_OK(registerCallback(nullptr)); +} + GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ContexthubHidlTest); INSTANTIATE_TEST_SUITE_P(HubIdSpecificTests, ContexthubHidlTest, testing::ValuesIn(kTestParameters), android::hardware::PrintInstanceTupleNameToString<>); -- GitLab From 30874b7a02183252f76da6360ed92f89df3787a1 Mon Sep 17 00:00:00 2001 From: Andy Hung Date: Thu, 14 Jan 2021 19:42:25 -0800 Subject: [PATCH 388/790] StreamOut: use atomic_sp<> for event callback thread safety Test: basic audio works Bug: 177278988 Change-Id: I987b31f470009c50412d8cee09163d093ecdd6f9 --- audio/core/all-versions/default/StreamOut.cpp | 2 +- .../core/all-versions/default/include/core/default/StreamOut.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/audio/core/all-versions/default/StreamOut.cpp b/audio/core/all-versions/default/StreamOut.cpp index 1fb72671bb..357fd941bd 100644 --- a/audio/core/all-versions/default/StreamOut.cpp +++ b/audio/core/all-versions/default/StreamOut.cpp @@ -698,7 +698,7 @@ Return StreamOut::setEventCallback(const sp& ca // static int StreamOut::asyncEventCallback(stream_event_callback_type_t event, void* param, void* cookie) { StreamOut* self = reinterpret_cast(cookie); - sp eventCallback = self->mEventCallback; + sp eventCallback = self->mEventCallback.load(); if (eventCallback.get() == nullptr) return 0; ALOGV("%s event %d", __func__, event); Return result; diff --git a/audio/core/all-versions/default/include/core/default/StreamOut.h b/audio/core/all-versions/default/include/core/default/StreamOut.h index c246ef3e4c..02d8e8962d 100644 --- a/audio/core/all-versions/default/include/core/default/StreamOut.h +++ b/audio/core/all-versions/default/include/core/default/StreamOut.h @@ -161,7 +161,7 @@ struct StreamOut : public IStreamOut { const sp> mStreamMmap; mediautils::atomic_sp mCallback; // for non-blocking write and drain #if MAJOR_VERSION >= 6 - sp mEventCallback; + mediautils::atomic_sp mEventCallback; #endif std::unique_ptr mCommandMQ; std::unique_ptr mDataMQ; -- GitLab From 90e6565e1e2b9b1e25a2d6058ab61b6fe7f764f4 Mon Sep 17 00:00:00 2001 From: lesl Date: Wed, 13 Jan 2021 17:38:53 +0800 Subject: [PATCH 389/790] wifi: Add VTS for wifi hal and hostapd hal. Tested on S5 and O6. Found VTS gets failure on wlan1 b/177389456 to track for O6 b/177483254 to track for S5 But both of O6 and S5 will get pass because it uses wlan0. Bug: 162686273 Bug: 173999527 Test: atest -c VtsHalWifiHostapdV1_3TargetTest Test: atest -c VtsHalWifiApV1_5TargetTest Change-Id: Idbaa7fb2f95abc954fda8daf8670e4a57b453030 --- wifi/1.5/vts/functional/Android.bp | 23 ++ .../functional/wifi_ap_iface_hidl_test.cpp | 97 ++++++++ .../vts/functional/wifi_chip_hidl_ap_test.cpp | 44 ++-- .../functional/wifi_hidl_test_utils_1_5.cpp | 61 +++++ .../vts/functional/wifi_hidl_test_utils_1_5.h | 35 +++ wifi/hostapd/1.3/vts/functional/Android.bp | 6 + .../1.3/vts/functional/hostapd_hidl_test.cpp | 220 ++++++++++++++---- 7 files changed, 416 insertions(+), 70 deletions(-) create mode 100644 wifi/1.5/vts/functional/wifi_ap_iface_hidl_test.cpp create mode 100644 wifi/1.5/vts/functional/wifi_hidl_test_utils_1_5.cpp create mode 100644 wifi/1.5/vts/functional/wifi_hidl_test_utils_1_5.h diff --git a/wifi/1.5/vts/functional/Android.bp b/wifi/1.5/vts/functional/Android.bp index 2d8b412abb..118822a35f 100644 --- a/wifi/1.5/vts/functional/Android.bp +++ b/wifi/1.5/vts/functional/Android.bp @@ -14,6 +14,27 @@ // limitations under the License. // +cc_library_static { + name: "VtsHalWifiV1_5TargetTestUtil", + defaults: ["VtsHalTargetTestDefaults"], + srcs: [ + "wifi_hidl_test_utils_1_5.cpp", + ], + export_include_dirs: [ + ".", + ], + shared_libs: [ + "libnativehelper", + ], + static_libs: [ + "VtsHalWifiV1_0TargetTestUtil", + "android.hardware.wifi@1.0", + "android.hardware.wifi@1.3", + "android.hardware.wifi@1.5", + "libwifi-system-iface", + ], +} + cc_test { name: "VtsHalWifiV1_5TargetTest", defaults: ["VtsHalTargetTestDefaults"], @@ -67,9 +88,11 @@ cc_test { defaults: ["VtsHalTargetTestDefaults"], srcs: [ "wifi_chip_hidl_ap_test.cpp", + "wifi_ap_iface_hidl_test.cpp", ], static_libs: [ "VtsHalWifiV1_0TargetTestUtil", + "VtsHalWifiV1_5TargetTestUtil", "android.hardware.wifi@1.0", "android.hardware.wifi@1.1", "android.hardware.wifi@1.2", diff --git a/wifi/1.5/vts/functional/wifi_ap_iface_hidl_test.cpp b/wifi/1.5/vts/functional/wifi_ap_iface_hidl_test.cpp new file mode 100644 index 0000000000..e47b14df1e --- /dev/null +++ b/wifi/1.5/vts/functional/wifi_ap_iface_hidl_test.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#undef NAN // NAN is defined in bionic/libc/include/math.h:38 + +#include +#include +#include +#include +#include +#include +#include + +#include "wifi_hidl_call_util.h" +#include "wifi_hidl_test_utils.h" +#include "wifi_hidl_test_utils_1_5.h" + +using ::android::sp; +using ::android::hardware::hidl_string; +using ::android::hardware::hidl_vec; +using ::android::hardware::Return; +using ::android::hardware::Void; +using ::android::hardware::wifi::V1_0::ChipModeId; +using ::android::hardware::wifi::V1_0::IfaceType; +using ::android::hardware::wifi::V1_0::IWifiIface; +using ::android::hardware::wifi::V1_0::WifiDebugRingBufferStatus; +using ::android::hardware::wifi::V1_0::WifiStatus; +using ::android::hardware::wifi::V1_0::WifiStatusCode; +using ::android::hardware::wifi::V1_4::IWifiChipEventCallback; +using ::android::hardware::wifi::V1_5::IWifiApIface; +using ::android::hardware::wifi::V1_5::IWifiChip; + +/** + * Fixture for IWifiChip tests that are conditioned on SoftAP support. + */ +class WifiApIfaceHidlTest : public ::testing::TestWithParam { + public: + virtual void SetUp() override { + isBridgedSupport_ = testing::checkSubstringInCommandOutput( + "/system/bin/cmd wifi get-softap-supported-features", + "wifi_softap_bridged_ap_supported"); + // Make sure to start with a clean state + stopWifi(GetInstanceName()); + } + + virtual void TearDown() override { stopWifi(GetInstanceName()); } + + protected: + bool isBridgedSupport_ = false; + std::string GetInstanceName() { return GetParam(); } +}; + +/* + * resetToFactoryMacAddress + */ +TEST_P(WifiApIfaceHidlTest, resetToFactoryMacAddressInBridgedModeTest) { + if (!isBridgedSupport_) GTEST_SKIP() << "Missing Bridged AP support"; + sp wifi_ap_iface = + getBridgedWifiApIface_1_5(GetInstanceName()); + ASSERT_NE(nullptr, wifi_ap_iface.get()); + const auto& status = HIDL_INVOKE(wifi_ap_iface, resetToFactoryMacAddress); + EXPECT_EQ(WifiStatusCode::SUCCESS, status.code); +} + +/* + * resetToFactoryMacAddress + */ +TEST_P(WifiApIfaceHidlTest, resetToFactoryMacAddressTest) { + sp wifi_ap_iface = getWifiApIface_1_5(GetInstanceName()); + ASSERT_NE(nullptr, wifi_ap_iface.get()); + const auto& status = HIDL_INVOKE(wifi_ap_iface, resetToFactoryMacAddress); + EXPECT_EQ(WifiStatusCode::SUCCESS, status.code); +} + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiApIfaceHidlTest); +INSTANTIATE_TEST_SUITE_P( + PerInstance, WifiApIfaceHidlTest, + testing::ValuesIn(android::hardware::getAllHalInstanceNames( + ::android::hardware::wifi::V1_5::IWifi::descriptor)), + android::hardware::PrintInstanceNameToString); diff --git a/wifi/1.5/vts/functional/wifi_chip_hidl_ap_test.cpp b/wifi/1.5/vts/functional/wifi_chip_hidl_ap_test.cpp index 395d317065..922c9a767a 100644 --- a/wifi/1.5/vts/functional/wifi_chip_hidl_ap_test.cpp +++ b/wifi/1.5/vts/functional/wifi_chip_hidl_ap_test.cpp @@ -14,6 +14,7 @@ * limitations under the License. */ +#include #include #include @@ -51,6 +52,9 @@ using ::android::hardware::wifi::V1_5::IWifiChip; class WifiChipHidlTest : public ::testing::TestWithParam { public: virtual void SetUp() override { + isBridgedSupport_ = testing::checkSubstringInCommandOutput( + "/system/bin/cmd wifi get-softap-supported-features", + "wifi_softap_bridged_ap_supported"); // Make sure to start with a clean state stopWifi(GetInstanceName()); @@ -61,6 +65,7 @@ class WifiChipHidlTest : public ::testing::TestWithParam { virtual void TearDown() override { stopWifi(GetInstanceName()); } protected: + bool isBridgedSupport_ = false; // Helper function to configure the Chip in one of the supported modes. // Most of the non-mode-configuration-related methods require chip // to be first configured. @@ -71,19 +76,12 @@ class WifiChipHidlTest : public ::testing::TestWithParam { return mode_id; } - WifiStatusCode createApIface(sp* ap_iface) { - configureChipForIfaceType(IfaceType::AP, true); - const auto& status_and_iface = HIDL_INVOKE(wifi_chip_, createApIface); - *ap_iface = IWifiApIface::castFrom(status_and_iface.second); - return status_and_iface.first.code; - } - - WifiStatusCode createBridgedApIface(sp* ap_iface) { + void createBridgedApIface(sp* ap_iface) { configureChipForIfaceType(IfaceType::AP, true); const auto& status_and_iface = HIDL_INVOKE(wifi_chip_, createBridgedApIface); *ap_iface = status_and_iface.second; - return status_and_iface.first.code; + EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_iface.first.code); } sp wifi_chip_; @@ -92,19 +90,25 @@ class WifiChipHidlTest : public ::testing::TestWithParam { std::string GetInstanceName() { return GetParam(); } }; -// TODO: b/173999527. Add test for bridged API. - -/* - * resetToFactoryMacAddress +/** + * createBridgedApIface & removeIfaceInstanceFromBridgedApIface */ -TEST_P(WifiChipHidlTest, resetToFactoryMacAddressTest) { +TEST_P(WifiChipHidlTest, + createBridgedApIfaceAndremoveIfaceInstanceFromBridgedApIfaceTest) { + if (!isBridgedSupport_) GTEST_SKIP() << "Missing Bridged AP support"; sp wifi_ap_iface; - const auto& status_code = createApIface(&wifi_ap_iface); - if (status_code != WifiStatusCode::SUCCESS) { - EXPECT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED, status_code); - } - const auto& status = HIDL_INVOKE(wifi_ap_iface, resetToFactoryMacAddress); - EXPECT_EQ(WifiStatusCode::SUCCESS, status.code); + createBridgedApIface(&wifi_ap_iface); + ASSERT_NE(nullptr, wifi_ap_iface.get()); + const auto& status_and_name = HIDL_INVOKE(wifi_ap_iface, getName); + EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_name.first.code); + // TODO: b/173999527, add API to get instance name to replace it. + std::string br_name = status_and_name.second; // ap_br_ is the pre-fix + std::string instance_name = + br_name.substr(6, br_name.length()); // remove the pre-fex + const auto& status_code = + HIDL_INVOKE(wifi_chip_, removeIfaceInstanceFromBridgedApIface, br_name, + instance_name); + EXPECT_EQ(WifiStatusCode::SUCCESS, status_code.code); } GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiChipHidlTest); diff --git a/wifi/1.5/vts/functional/wifi_hidl_test_utils_1_5.cpp b/wifi/1.5/vts/functional/wifi_hidl_test_utils_1_5.cpp new file mode 100644 index 0000000000..f1da2eae98 --- /dev/null +++ b/wifi/1.5/vts/functional/wifi_hidl_test_utils_1_5.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#undef NAN // NAN is defined in bionic/libc/include/math.h:38 + +#include +#include +#include +#include +#include +#include + +#include "wifi_hidl_call_util.h" +#include "wifi_hidl_test_utils.h" + +using ::android::sp; +using ::android::hardware::hidl_string; +using ::android::hardware::hidl_vec; +using ::android::hardware::Return; +using ::android::hardware::Void; +using ::android::hardware::wifi::V1_0::ChipModeId; +using ::android::hardware::wifi::V1_0::IfaceType; +using ::android::hardware::wifi::V1_5::IWifiApIface; +using ::android::hardware::wifi::V1_5::IWifiChip; + +sp getWifiChip_1_5(const std::string& instance_name) { + return IWifiChip::castFrom(getWifiChip(instance_name)); +} + +sp getWifiApIface_1_5(const std::string& instance_name) { + ChipModeId mode_id; + sp wifi_chip_ = getWifiChip_1_5(instance_name); + configureChipToSupportIfaceType(wifi_chip_, IfaceType::AP, &mode_id); + const auto& status_and_iface = HIDL_INVOKE(wifi_chip_, createApIface); + return IWifiApIface::castFrom(status_and_iface.second); +} + +sp getBridgedWifiApIface_1_5(const std::string& instance_name) { + ChipModeId mode_id; + sp wifi_chip_ = getWifiChip_1_5(instance_name); + configureChipToSupportIfaceType(wifi_chip_, IfaceType::AP, &mode_id); + const auto& status_and_iface = + HIDL_INVOKE(wifi_chip_, createBridgedApIface); + return IWifiApIface::castFrom(status_and_iface.second); +} diff --git a/wifi/1.5/vts/functional/wifi_hidl_test_utils_1_5.h b/wifi/1.5/vts/functional/wifi_hidl_test_utils_1_5.h new file mode 100644 index 0000000000..1b8b737632 --- /dev/null +++ b/wifi/1.5/vts/functional/wifi_hidl_test_utils_1_5.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include + +#include + +#include +// Helper functions to obtain references to the various HIDL interface objects. +// Note: We only have a single instance of each of these objects currently. +// These helper functions should be modified to return vectors if we support +// multiple instances. +android::sp getWifiChip_1_5( + const std::string& instance_name); +android::sp getWifiApIface_1_5( + const std::string& instance_name); +android::sp +getBridgedWifiApIface_1_5(const std::string& instance_name); diff --git a/wifi/hostapd/1.3/vts/functional/Android.bp b/wifi/hostapd/1.3/vts/functional/Android.bp index 07cebb018a..ed18bb69cd 100644 --- a/wifi/hostapd/1.3/vts/functional/Android.bp +++ b/wifi/hostapd/1.3/vts/functional/Android.bp @@ -22,12 +22,18 @@ cc_test { ], static_libs: [ "VtsHalWifiV1_0TargetTestUtil", + "VtsHalWifiV1_5TargetTestUtil", "VtsHalWifiHostapdV1_0TargetTestUtil", "android.hardware.wifi.hostapd@1.0", "android.hardware.wifi.hostapd@1.1", "android.hardware.wifi.hostapd@1.2", "android.hardware.wifi.hostapd@1.3", "android.hardware.wifi@1.0", + "android.hardware.wifi@1.1", + "android.hardware.wifi@1.2", + "android.hardware.wifi@1.3", + "android.hardware.wifi@1.4", + "android.hardware.wifi@1.5", "libgmock", "libwifi-system", "libwifi-system-iface", diff --git a/wifi/hostapd/1.3/vts/functional/hostapd_hidl_test.cpp b/wifi/hostapd/1.3/vts/functional/hostapd_hidl_test.cpp index a22252c2a5..4e63c56d2c 100644 --- a/wifi/hostapd/1.3/vts/functional/hostapd_hidl_test.cpp +++ b/wifi/hostapd/1.3/vts/functional/hostapd_hidl_test.cpp @@ -28,6 +28,7 @@ #include "hostapd_hidl_call_util.h" #include "hostapd_hidl_test_utils.h" +#include "wifi_hidl_test_utils_1_5.h" using ::android::sp; using ::android::hardware::hidl_string; @@ -38,6 +39,8 @@ using ::android::hardware::wifi::hostapd::V1_2::HostapdStatusCode; using ::android::hardware::wifi::hostapd::V1_2::Ieee80211ReasonCode; using ::android::hardware::wifi::hostapd::V1_3::IHostapd; using ::android::hardware::wifi::V1_0::IWifi; +using ::android::hardware::wifi::V1_0::WifiStatusCode; +using ::android::hardware::wifi::V1_5::IWifiApIface; namespace { constexpr unsigned char kNwSsid[] = {'t', 'e', 's', 't', '1', @@ -71,16 +74,39 @@ class HostapdHidlTest isWpa3SaeSupport_ = testing::checkSubstringInCommandOutput( "/system/bin/cmd wifi get-softap-supported-features", "wifi_softap_wpa3_sae_supported"); + isBridgedSupport_ = testing::checkSubstringInCommandOutput( + "/system/bin/cmd wifi get-softap-supported-features", + "wifi_softap_bridged_ap_supported"); } virtual void TearDown() override { HIDL_INVOKE_VOID_WITHOUT_ARGUMENTS(hostapd_, terminate); stopHostapd(wifi_instance_name_); + // Wait 3 seconds to allow driver processing load/unload between two + // test cases. + sleep(3); } protected: bool isWpa3SaeSupport_ = false; bool isAcsSupport_ = false; + bool isBridgedSupport_ = false; + + std::string setupApIfaceAndGetName(bool isBridged) { + sp wifi_ap_iface; + if (isBridged) { + wifi_ap_iface = getBridgedWifiApIface_1_5(wifi_instance_name_); + } else { + wifi_ap_iface = getWifiApIface_1_5(wifi_instance_name_); + } + EXPECT_NE(nullptr, wifi_ap_iface.get()); + + const auto& status_and_name = HIDL_INVOKE(wifi_ap_iface, getName); + EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_name.first.code); + return status_and_name.second; + } + + // TODO: b/177483254, remove it after fix wlan1 failure case. std::string getPrimaryWlanIfaceName() { std::array buffer; auto res = property_get("ro.vendor.wifi.sap.interface", buffer.data(), @@ -90,7 +116,7 @@ class HostapdHidlTest return buffer.data(); } - IHostapd::IfaceParams getIfaceParamsWithoutAcs() { + IHostapd::IfaceParams getIfaceParamsWithoutAcs(std::string iface_name) { ::android::hardware::wifi::hostapd::V1_0::IHostapd::IfaceParams iface_params; ::android::hardware::wifi::hostapd::V1_1::IHostapd::IfaceParams @@ -106,7 +132,7 @@ class HostapdHidlTest ::android::hardware::wifi::hostapd::V1_3::IHostapd::ChannelParams channelParams_1_3; - iface_params.ifaceName = getPrimaryWlanIfaceName(); + iface_params.ifaceName = iface_name; iface_params.hwModeParams.enable80211N = true; iface_params.hwModeParams.enable80211AC = false; iface_params.channelParams.enableAcs = false; @@ -133,9 +159,41 @@ class HostapdHidlTest return iface_params_1_3; } - IHostapd::IfaceParams getIfaceParamsWithAcs() { + IHostapd::IfaceParams getIfaceParamsWithBridgedModeACS( + std::string iface_name) { + // First get the settings for WithoutAcs and then make changes + IHostapd::IfaceParams iface_params_1_3 = + getIfaceParamsWithoutAcs(iface_name); + iface_params_1_3.V1_2.V1_1.V1_0.channelParams.enableAcs = true; + iface_params_1_3.V1_2.V1_1.V1_0.channelParams.acsShouldExcludeDfs = + true; + + std::vector< + ::android::hardware::wifi::hostapd::V1_3::IHostapd::ChannelParams> + vec_channelParams; + + vec_channelParams.push_back(iface_params_1_3.channelParamsList[0]); + + ::android::hardware::wifi::hostapd::V1_3::IHostapd::ChannelParams + second_channelParams_1_3; + second_channelParams_1_3.channel = 0; + second_channelParams_1_3.enableAcs = true; + second_channelParams_1_3.bandMask = 0; + second_channelParams_1_3.bandMask |= IHostapd::BandMask::BAND_5_GHZ; + second_channelParams_1_3.V1_2 = iface_params_1_3.V1_2.channelParams; + second_channelParams_1_3.V1_2.bandMask = 0; + second_channelParams_1_3.V1_2.bandMask |= + IHostapd::BandMask::BAND_5_GHZ; + vec_channelParams.push_back(second_channelParams_1_3); + + iface_params_1_3.channelParamsList = vec_channelParams; + return iface_params_1_3; + } + + IHostapd::IfaceParams getIfaceParamsWithAcs(std::string iface_name) { // First get the settings for WithoutAcs and then make changes - IHostapd::IfaceParams iface_params_1_3 = getIfaceParamsWithoutAcs(); + IHostapd::IfaceParams iface_params_1_3 = + getIfaceParamsWithoutAcs(iface_name); iface_params_1_3.V1_2.V1_1.V1_0.channelParams.enableAcs = true; iface_params_1_3.V1_2.V1_1.V1_0.channelParams.acsShouldExcludeDfs = true; @@ -153,8 +211,10 @@ class HostapdHidlTest return iface_params_1_3; } - IHostapd::IfaceParams getIfaceParamsWithAcsAndFreqRange() { - IHostapd::IfaceParams iface_params_1_3 = getIfaceParamsWithAcs(); + IHostapd::IfaceParams getIfaceParamsWithAcsAndFreqRange( + std::string iface_name) { + IHostapd::IfaceParams iface_params_1_3 = + getIfaceParamsWithAcs(iface_name); ::android::hardware::wifi::hostapd::V1_2::IHostapd::AcsFrequencyRange acsFrequencyRange; acsFrequencyRange.start = 2412; @@ -170,9 +230,10 @@ class HostapdHidlTest return iface_params_1_3; } - IHostapd::IfaceParams getIfaceParamsWithAcsAndInvalidFreqRange() { + IHostapd::IfaceParams getIfaceParamsWithAcsAndInvalidFreqRange( + std::string iface_name) { IHostapd::IfaceParams iface_params_1_3 = - getIfaceParamsWithAcsAndFreqRange(); + getIfaceParamsWithAcsAndFreqRange(iface_name); iface_params_1_3.V1_2.channelParams.acsChannelFreqRangesMhz[0].start = 222; iface_params_1_3.V1_2.channelParams.acsChannelFreqRangesMhz[0].end = @@ -250,8 +311,10 @@ class HostapdHidlTest return nw_params_1_3; } - IHostapd::IfaceParams getIfaceParamsWithInvalidChannel() { - IHostapd::IfaceParams iface_params_1_3 = getIfaceParamsWithoutAcs(); + IHostapd::IfaceParams getIfaceParamsWithInvalidChannel( + std::string iface_name) { + IHostapd::IfaceParams iface_params_1_3 = + getIfaceParamsWithoutAcs(iface_name); iface_params_1_3.V1_2.V1_1.V1_0.channelParams.channel = kIfaceInvalidChannel; iface_params_1_3.channelParamsList[0].channel = @@ -271,8 +334,11 @@ class HostapdHidlTest */ TEST_P(HostapdHidlTest, AddPskAccessPointWithAcs) { if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support"; + // TODO: Use setupApIfaceAndGetName after fixing b/177483254 + // std::string ifname = setupApIfaceAndGetName(false); + std::string ifname = getPrimaryWlanIfaceName(); auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, - getIfaceParamsWithAcs(), getPskNwParams()); + getIfaceParamsWithAcs(ifname), getPskNwParams()); EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); } @@ -282,9 +348,12 @@ TEST_P(HostapdHidlTest, AddPskAccessPointWithAcs) { */ TEST_P(HostapdHidlTest, AddPskAccessPointWithAcsAndFreqRange) { if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support"; - auto status = - HIDL_INVOKE(hostapd_, addAccessPoint_1_3, - getIfaceParamsWithAcsAndFreqRange(), getPskNwParams()); + // TODO: Use setupApIfaceAndGetName after fixing b/177483254 + // std::string ifname = setupApIfaceAndGetName(false); + std::string ifname = getPrimaryWlanIfaceName(); + auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, + getIfaceParamsWithAcsAndFreqRange(ifname), + getPskNwParams()); EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); } @@ -294,8 +363,11 @@ TEST_P(HostapdHidlTest, AddPskAccessPointWithAcsAndFreqRange) { */ TEST_P(HostapdHidlTest, AddPskAccessPointWithAcsAndInvalidFreqRange) { if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support"; + // TODO: Use setupApIfaceAndGetName after fixing b/177483254 + // std::string ifname = setupApIfaceAndGetName(false); + std::string ifname = getPrimaryWlanIfaceName(); auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, - getIfaceParamsWithAcsAndInvalidFreqRange(), + getIfaceParamsWithAcsAndInvalidFreqRange(ifname), getPskNwParams()); EXPECT_NE(HostapdStatusCode::SUCCESS, status.code); } @@ -306,8 +378,11 @@ TEST_P(HostapdHidlTest, AddPskAccessPointWithAcsAndInvalidFreqRange) { */ TEST_P(HostapdHidlTest, AddOpenAccessPointWithAcs) { if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support"; + // TODO: Use setupApIfaceAndGetName after fixing b/177483254 + // std::string ifname = setupApIfaceAndGetName(false); + std::string ifname = getPrimaryWlanIfaceName(); auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, - getIfaceParamsWithAcs(), getOpenNwParams()); + getIfaceParamsWithAcs(ifname), getOpenNwParams()); EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); } @@ -316,8 +391,12 @@ TEST_P(HostapdHidlTest, AddOpenAccessPointWithAcs) { * Access point creation should pass. */ TEST_P(HostapdHidlTest, AddPskAccessPointWithoutAcs) { - auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, - getIfaceParamsWithoutAcs(), getPskNwParams()); + // TODO: Use setupApIfaceAndGetName after fixing b/177483254 + // std::string ifname = setupApIfaceAndGetName(false); + std::string ifname = getPrimaryWlanIfaceName(); + auto status = + HIDL_INVOKE(hostapd_, addAccessPoint_1_3, + getIfaceParamsWithoutAcs(ifname), getPskNwParams()); EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); } @@ -326,9 +405,12 @@ TEST_P(HostapdHidlTest, AddPskAccessPointWithoutAcs) { * Access point creation should pass. */ TEST_P(HostapdHidlTest, AddPskAccessPointWithoutAcsAndNonMetered) { - auto status = - HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithoutAcs(), - getPskNwParamsWithNonMetered()); + // TODO: Use setupApIfaceAndGetName after fixing b/177483254 + // std::string ifname = setupApIfaceAndGetName(false); + std::string ifname = getPrimaryWlanIfaceName(); + auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, + getIfaceParamsWithoutAcs(ifname), + getPskNwParamsWithNonMetered()); EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); } @@ -337,8 +419,12 @@ TEST_P(HostapdHidlTest, AddPskAccessPointWithoutAcsAndNonMetered) { * Access point creation should pass. */ TEST_P(HostapdHidlTest, AddOpenAccessPointWithoutAcs) { - auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, - getIfaceParamsWithoutAcs(), getOpenNwParams()); + // TODO: Use setupApIfaceAndGetName after fixing b/177483254 + // std::string ifname = setupApIfaceAndGetName(false); + std::string ifname = getPrimaryWlanIfaceName(); + auto status = + HIDL_INVOKE(hostapd_, addAccessPoint_1_3, + getIfaceParamsWithoutAcs(ifname), getOpenNwParams()); EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); } @@ -348,9 +434,12 @@ TEST_P(HostapdHidlTest, AddOpenAccessPointWithoutAcs) { */ TEST_P(HostapdHidlTest, AddSaeTransitionAccessPointWithoutAcs) { if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support"; - auto status = - HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithoutAcs(), - getSaeTransitionNwParams()); + // TODO: Use setupApIfaceAndGetName after fixing b/177483254 + // std::string ifname = setupApIfaceAndGetName(false); + std::string ifname = getPrimaryWlanIfaceName(); + auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, + getIfaceParamsWithoutAcs(ifname), + getSaeTransitionNwParams()); EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); } @@ -360,8 +449,12 @@ TEST_P(HostapdHidlTest, AddSaeTransitionAccessPointWithoutAcs) { */ TEST_P(HostapdHidlTest, AddSAEAccessPointWithoutAcs) { if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support"; - auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, - getIfaceParamsWithoutAcs(), getSaeNwParams()); + // TODO: Use setupApIfaceAndGetName after fixing b/177483254 + // std::string ifname = setupApIfaceAndGetName(false); + std::string ifname = getPrimaryWlanIfaceName(); + auto status = + HIDL_INVOKE(hostapd_, addAccessPoint_1_3, + getIfaceParamsWithoutAcs(ifname), getSaeNwParams()); EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); } @@ -371,11 +464,14 @@ TEST_P(HostapdHidlTest, AddSAEAccessPointWithoutAcs) { */ TEST_P(HostapdHidlTest, RemoveAccessPointWithAcs) { if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support"; - auto status_1_2 = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, - getIfaceParamsWithAcs(), getPskNwParams()); + // TODO: Use setupApIfaceAndGetName after fixing b/177483254 + // std::string ifname = setupApIfaceAndGetName(false); + std::string ifname = getPrimaryWlanIfaceName(); + auto status_1_2 = + HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithAcs(ifname), + getPskNwParams()); EXPECT_EQ(HostapdStatusCode::SUCCESS, status_1_2.code); - auto status = - HIDL_INVOKE(hostapd_, removeAccessPoint, getPrimaryWlanIfaceName()); + auto status = HIDL_INVOKE(hostapd_, removeAccessPoint, ifname); EXPECT_EQ( android::hardware::wifi::hostapd::V1_0::HostapdStatusCode::SUCCESS, status.code); @@ -386,11 +482,14 @@ TEST_P(HostapdHidlTest, RemoveAccessPointWithAcs) { * Access point creation & removal should pass. */ TEST_P(HostapdHidlTest, RemoveAccessPointWithoutAcs) { - auto status_1_2 = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, - getIfaceParamsWithoutAcs(), getPskNwParams()); + // TODO: Use setupApIfaceAndGetName after fixing b/177483254 + // std::string ifname = setupApIfaceAndGetName(false); + std::string ifname = getPrimaryWlanIfaceName(); + auto status_1_2 = + HIDL_INVOKE(hostapd_, addAccessPoint_1_3, + getIfaceParamsWithoutAcs(ifname), getPskNwParams()); EXPECT_EQ(HostapdStatusCode::SUCCESS, status_1_2.code); - auto status = - HIDL_INVOKE(hostapd_, removeAccessPoint, getPrimaryWlanIfaceName()); + auto status = HIDL_INVOKE(hostapd_, removeAccessPoint, ifname); EXPECT_EQ( android::hardware::wifi::hostapd::V1_0::HostapdStatusCode::SUCCESS, status.code); @@ -401,9 +500,12 @@ TEST_P(HostapdHidlTest, RemoveAccessPointWithoutAcs) { * Access point creation should fail. */ TEST_P(HostapdHidlTest, AddPskAccessPointWithInvalidChannel) { + // TODO: Use setupApIfaceAndGetName after fixing b/177483254 + // std::string ifname = setupApIfaceAndGetName(false); + std::string ifname = getPrimaryWlanIfaceName(); auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, - getIfaceParamsWithInvalidChannel(), getPskNwParams()); + getIfaceParamsWithInvalidChannel(ifname), getPskNwParams()); EXPECT_NE(HostapdStatusCode::SUCCESS, status.code); } @@ -412,9 +514,12 @@ TEST_P(HostapdHidlTest, AddPskAccessPointWithInvalidChannel) { * Access point creation should fail. */ TEST_P(HostapdHidlTest, AddInvalidPskAccessPointWithoutAcs) { + // TODO: Use setupApIfaceAndGetName after fixing b/177483254 + // std::string ifname = setupApIfaceAndGetName(false); + std::string ifname = getPrimaryWlanIfaceName(); auto status = - HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithoutAcs(), - getInvalidPskNwParams()); + HIDL_INVOKE(hostapd_, addAccessPoint_1_3, + getIfaceParamsWithoutAcs(ifname), getInvalidPskNwParams()); EXPECT_NE(HostapdStatusCode::SUCCESS, status.code); } @@ -424,9 +529,12 @@ TEST_P(HostapdHidlTest, AddInvalidPskAccessPointWithoutAcs) { */ TEST_P(HostapdHidlTest, AddInvalidSaeTransitionAccessPointWithoutAcs) { if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support"; - auto status = - HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithoutAcs(), - getInvalidSaeTransitionNwParams()); + // TODO: Use setupApIfaceAndGetName after fixing b/177483254 + // std::string ifname = setupApIfaceAndGetName(false); + std::string ifname = getPrimaryWlanIfaceName(); + auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, + getIfaceParamsWithoutAcs(ifname), + getInvalidSaeTransitionNwParams()); EXPECT_NE(HostapdStatusCode::SUCCESS, status.code); } @@ -436,9 +544,12 @@ TEST_P(HostapdHidlTest, AddInvalidSaeTransitionAccessPointWithoutAcs) { */ TEST_P(HostapdHidlTest, AddInvalidSaeAccessPointWithoutAcs) { if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support"; + // TODO: Use setupApIfaceAndGetName after fixing b/177483254 + // std::string ifname = setupApIfaceAndGetName(false); + std::string ifname = getPrimaryWlanIfaceName(); auto status = - HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithoutAcs(), - getInvalidSaeNwParams()); + HIDL_INVOKE(hostapd_, addAccessPoint_1_3, + getIfaceParamsWithoutAcs(ifname), getInvalidSaeNwParams()); EXPECT_NE(HostapdStatusCode::SUCCESS, status.code); } @@ -447,21 +558,30 @@ TEST_P(HostapdHidlTest, AddInvalidSaeAccessPointWithoutAcs) { * when hotspot interface available. */ TEST_P(HostapdHidlTest, DisconnectClientWhenIfacAvailable) { + // TODO: Use setupApIfaceAndGetName after fixing b/177483254 + // std::string ifname = setupApIfaceAndGetName(false); + std::string ifname = getPrimaryWlanIfaceName(); auto status_1_2 = - HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithoutAcs(), - getOpenNwParams()); + HIDL_INVOKE(hostapd_, addAccessPoint_1_3, + getIfaceParamsWithoutAcs(ifname), getOpenNwParams()); EXPECT_EQ(HostapdStatusCode::SUCCESS, status_1_2.code); - status_1_2 = - HIDL_INVOKE(hostapd_, forceClientDisconnect, getPrimaryWlanIfaceName(), - kTestZeroMacAddr, kTestDisconnectReasonCode); + status_1_2 = HIDL_INVOKE(hostapd_, forceClientDisconnect, ifname, + kTestZeroMacAddr, kTestDisconnectReasonCode); EXPECT_EQ(HostapdStatusCode::FAILURE_CLIENT_UNKNOWN, status_1_2.code); } /** * AddAccessPointWithDualBandConfig should pass */ -// TODO: Add it after VendorHal ready & add feature support check. +TEST_P(HostapdHidlTest, AddAccessPointWithDualBandConfig) { + if (!isBridgedSupport_) GTEST_SKIP() << "Missing Bridged AP support"; + std::string ifname = setupApIfaceAndGetName(true); + auto status_1_2 = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, + getIfaceParamsWithBridgedModeACS(ifname), + getOpenNwParams()); + EXPECT_EQ(HostapdStatusCode::SUCCESS, status_1_2.code); +} GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(HostapdHidlTest); INSTANTIATE_TEST_CASE_P( -- GitLab From 1276bc9bee443a8f160e95c8748e6557cc6a7551 Mon Sep 17 00:00:00 2001 From: Zoey Chen Date: Tue, 1 Dec 2020 12:44:06 +0800 Subject: [PATCH 390/790] [Telephony] Implement PhysicalChannelConfig in HAL 1.6 Bug: 169206279 Test: make and VtsHalRadioV1_6Target Change-Id: I4352ea928a76197aae01b887960eaed05698e3eb --- radio/1.6/IRadioIndication.hal | 12 ++++ radio/1.6/types.hal | 71 +++++++++++++++++++ .../functional/radio_hidl_hal_utils_v1_6.h | 5 ++ radio/1.6/vts/functional/radio_indication.cpp | 7 ++ 4 files changed, 95 insertions(+) diff --git a/radio/1.6/IRadioIndication.hal b/radio/1.6/IRadioIndication.hal index 1b56d40bcf..a53d7c1212 100644 --- a/radio/1.6/IRadioIndication.hal +++ b/radio/1.6/IRadioIndication.hal @@ -23,6 +23,7 @@ import @1.6::LinkCapacityEstimate; import @1.6::NetworkScanResult; import @1.6::SignalStrength; import @1.6::SetupDataCallResult; +import @1.6::PhysicalChannelConfig; /** * Interface declaring unsolicited radio indications. @@ -101,4 +102,15 @@ interface IRadioIndication extends @1.5::IRadioIndication { * CellInfo. */ oneway networkScanResult_1_6(RadioIndicationType type, NetworkScanResult result); + + /** + * Indicates physical channel configurations. + * + * An empty configs list indicates that the radio is in idle mode. + * + * @param type Type of radio indication + * @param configs Vector of PhysicalChannelConfigs + */ + oneway currentPhysicalChannelConfigs_1_6(RadioIndicationType type, + vec configs); }; diff --git a/radio/1.6/types.hal b/radio/1.6/types.hal index c2de76b5e7..3563e14b27 100644 --- a/radio/1.6/types.hal +++ b/radio/1.6/types.hal @@ -23,7 +23,10 @@ import @1.0::LteSignalStrength; import @1.0::RadioError; import @1.0::RadioResponseType; import @1.0::RegState; +import @1.1::EutranBands; +import @1.1::GeranBands; import @1.1::ScanStatus; +import @1.1::UtranBands; import @1.2::Call; import @1.2::CellInfoCdma; import @1.2::CellConnectionStatus; @@ -41,6 +44,7 @@ import @1.5::CellInfoGsm; import @1.5::CellInfoWcdma; import @1.5::CellInfoTdscdma; import @1.5::LinkAddress; +import @1.5::NgranBands; import @1.5::RegStateResult.AccessTechnologySpecificInfo.Cdma2000RegistrationInfo; import @1.5::RegStateResult.AccessTechnologySpecificInfo.EutranRegistrationInfo; import @1.5::RegistrationFailCause; @@ -816,3 +820,70 @@ enum DataCallFailCause : @1.4::DataCallFailCause { */ SLICE_REJECTED = 0x8CC, }; + +struct PhysicalChannelConfig { + /** Connection status for cell. Valid values are PRIMARY_SERVING and SECONDARY_SERVING */ + CellConnectionStatus status; + + /** The radio technology for this physical channel */ + RadioTechnology rat; + + /** Downlink Absolute Radio Frequency Channel Number */ + int32_t downlinkChannelNumber; + + /** Uplink Absolute Radio Frequency Channel Number */ + int32_t uplinkChannelNumber; + + /** Downlink cell bandwidth, in kHz */ + int32_t cellBandwidthDownlink; + + /** Uplink cell bandwidth, in kHz */ + int32_t cellBandwidthUplink; + + /** + * A list of data calls mapped to this physical channel. The context id must match the cid of + * @1.5::SetupDataCallResult. An empty list means the physical channel has no data call mapped + * to it. + */ + vec contextIds; + + /** + * The physical cell identifier for this cell. + * + * In UTRAN, this value is primary scrambling code. The range is [0, 511]. + * Reference: 3GPP TS 25.213 section 5.2.2. + * + * In EUTRAN, this value is physical layer cell identity. The range is [0, 503]. + * Reference: 3GPP TS 36.211 section 6.11. + * + * In 5G RAN, this value is physical layer cell identity. The range is [0, 1007]. + * Reference: 3GPP TS 38.211 section 7.4.2.1. + */ + uint32_t physicalCellId; + + /** + * The frequency band to scan. + */ + safe_union Band { + /** Valid only if radioAccessNetwork = GERAN. */ + GeranBands geranBand; + /** Valid only if radioAccessNetwork = UTRAN. */ + UtranBands utranBand; + /** Valid only if radioAccessNetwork = EUTRAN. */ + EutranBands eutranBand; + /** Valid only if radioAccessNetwork = NGRAN. */ + NgranBands ngranBand; + } band; +}; + +/** + * Extended from @1.5 NgranBands + * IRadio 1.6 supports NGRAN bands up to V16.5.0 + */ +enum NgranBands : @1.5::NgranBands { + /** 3GPP TS 38.101-1, Table 5.2-1: FR1 bands */ + BAND_26 = 26, + BAND_46 = 46, + BAND_53 = 53, + BAND_96 = 96, +}; diff --git a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h index fbcd7a9339..5fcfa3b0bb 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h +++ b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h @@ -857,6 +857,11 @@ class RadioIndication_v1_6 : public ::android::hardware::radio::V1_6::IRadioIndi const ::android::hardware::hidl_vec<::android::hardware::radio::V1_6::CellInfo>& records); + Return currentPhysicalChannelConfigs_1_6( + RadioIndicationType type, + const ::android::hardware::hidl_vec< + ::android::hardware::radio::V1_6::PhysicalChannelConfig>& configs); + /* 1.5 Api */ Return uiccApplicationsEnablementChanged(RadioIndicationType type, bool enabled); diff --git a/radio/1.6/vts/functional/radio_indication.cpp b/radio/1.6/vts/functional/radio_indication.cpp index bfc54c0ac5..e7a96807a9 100644 --- a/radio/1.6/vts/functional/radio_indication.cpp +++ b/radio/1.6/vts/functional/radio_indication.cpp @@ -30,6 +30,13 @@ Return RadioIndication_v1_6::unthrottleApn(RadioIndicationType /*type*/, return Void(); } +Return RadioIndication_v1_6::currentPhysicalChannelConfigs_1_6( + RadioIndicationType /*type*/, + const ::android::hardware::hidl_vec< + ::android::hardware::radio::V1_6::PhysicalChannelConfig>& /*configs*/) { + return Void(); +} + /* 1.5 Apis */ Return RadioIndication_v1_6::uiccApplicationsEnablementChanged(RadioIndicationType /*type*/, bool /*enabled*/) { -- GitLab From ea6cdc00169b1b3c99b04000e4d78398c3dcc149 Mon Sep 17 00:00:00 2001 From: Yu-Han Yang Date: Wed, 6 Jan 2021 17:23:15 -0800 Subject: [PATCH 391/790] Update SATELLITE_BLOCKLIST capability value Make the capability value consistent with the framework so that it doesn't need conversion. Bug: 176854122 Test: on cuttlefish Change-Id: I4f6c24a55dea59374791a7d5ad3c6ce657712422 --- .../current/android/hardware/gnss/IGnssCallback.aidl | 2 +- gnss/aidl/android/hardware/gnss/IGnssCallback.aidl | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl index a04ad660a3..a0c4255df2 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl @@ -20,7 +20,7 @@ package android.hardware.gnss; @VintfStability interface IGnssCallback { void gnssSetCapabilitiesCb(in int capabilities); - const int CAPABILITY_SATELLITE_BLOCKLIST = 1; + const int CAPABILITY_SATELLITE_BLOCKLIST = 512; const int CAPABILITY_CORRELATION_VECTOR = 4096; const int CAPABILITY_SATELLITE_PVT = 8192; } diff --git a/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl b/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl index 81e06382b4..8881ea7486 100644 --- a/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl +++ b/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl @@ -28,7 +28,7 @@ import android.hardware.gnss.IGnssConfiguration; interface IGnssCallback { /** Capability bit mask indicating that GNSS supports blocklisting satellites */ - const int CAPABILITY_SATELLITE_BLOCKLIST = 1 << 0; + const int CAPABILITY_SATELLITE_BLOCKLIST = 1 << 9; /** Capability bit mask indicating that GNSS supports correlation vector */ const int CAPABILITY_CORRELATION_VECTOR = 1 << 12; @@ -42,4 +42,4 @@ interface IGnssCallback { * @param capabilities Capability parameter is a bit field of the Capability bit masks. */ void gnssSetCapabilitiesCb(in int capabilities); -} \ No newline at end of file +} -- GitLab From 2194bb44309be98efbd8b4e377aefa4fd0ae53df Mon Sep 17 00:00:00 2001 From: Robert Shih Date: Sat, 16 Jan 2021 20:29:56 -0800 Subject: [PATCH 392/790] Add android.hardware.drm@1.4 Bug: 136119370 Test: GtsMediaTestCases MediaDrmTest#testRequiresSecureDecoder Change-Id: If7bec99c7a1c98da9f85876722e6da88a425b1e7 --- .../compatibility_matrix.current.xml | 2 +- drm/1.4/Android.bp | 20 ++++++++ drm/1.4/ICryptoFactory.hal | 32 ++++++++++++ drm/1.4/ICryptoPlugin.hal | 26 ++++++++++ drm/1.4/IDrmFactory.hal | 34 +++++++++++++ drm/1.4/IDrmPlugin.hal | 50 +++++++++++++++++++ 6 files changed, 163 insertions(+), 1 deletion(-) create mode 100644 drm/1.4/Android.bp create mode 100644 drm/1.4/ICryptoFactory.hal create mode 100644 drm/1.4/ICryptoPlugin.hal create mode 100644 drm/1.4/IDrmFactory.hal create mode 100644 drm/1.4/IDrmPlugin.hal diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index 7c41d1fb09..c7266f9fbe 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -198,7 +198,7 @@ android.hardware.drm - 1.3 + 1.3-4 ICryptoFactory .* diff --git a/drm/1.4/Android.bp b/drm/1.4/Android.bp new file mode 100644 index 0000000000..8e1dc93c9f --- /dev/null +++ b/drm/1.4/Android.bp @@ -0,0 +1,20 @@ +// This file is autogenerated by hidl-gen -Landroidbp. + +hidl_interface { + name: "android.hardware.drm@1.4", + root: "android.hardware", + srcs: [ + "ICryptoFactory.hal", + "ICryptoPlugin.hal", + "IDrmFactory.hal", + "IDrmPlugin.hal", + ], + interfaces: [ + "android.hardware.drm@1.0", + "android.hardware.drm@1.1", + "android.hardware.drm@1.2", + "android.hardware.drm@1.3", + "android.hidl.base@1.0", + ], + gen_java: false, +} diff --git a/drm/1.4/ICryptoFactory.hal b/drm/1.4/ICryptoFactory.hal new file mode 100644 index 0000000000..6cbf9e3449 --- /dev/null +++ b/drm/1.4/ICryptoFactory.hal @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.hardware.drm@1.4; + +import @1.3::ICryptoFactory; + +/** + * ICryptoFactory is the main entry point for interacting with a vendor's + * crypto HAL to create crypto plugins. Crypto plugins create crypto sessions + * which are used by a codec to decrypt protected video content. + * + * The 1.4 factory must always create 1.4 ICryptoPlugin interfaces, which are + * returned via the 1.0 createPlugin method. + * + * To use 1.4 features the caller must cast the returned interface to a + * 1.4 HAL, using V1_4::ICryptoPlugin::castFrom(). + */ +interface ICryptoFactory extends @1.3::ICryptoFactory { +}; diff --git a/drm/1.4/ICryptoPlugin.hal b/drm/1.4/ICryptoPlugin.hal new file mode 100644 index 0000000000..874ef4cd3b --- /dev/null +++ b/drm/1.4/ICryptoPlugin.hal @@ -0,0 +1,26 @@ +/** + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.hardware.drm@1.4; + +import @1.2::ICryptoPlugin; + +/** + * ICryptoPlugin is the HAL for vendor-provided crypto plugins. + * It allows crypto sessions to be opened and operated on, to + * load crypto keys for a codec to decrypt protected video content. + */ +interface ICryptoPlugin extends @1.2::ICryptoPlugin { +}; diff --git a/drm/1.4/IDrmFactory.hal b/drm/1.4/IDrmFactory.hal new file mode 100644 index 0000000000..035a2983ae --- /dev/null +++ b/drm/1.4/IDrmFactory.hal @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.hardware.drm@1.4; + +import @1.3::IDrmFactory; + +/** + * IDrmFactory is the main entry point for interacting with a vendor's + * drm HAL to create drm plugin instances. A drm plugin instance + * creates drm sessions which are used to obtain keys for a crypto + * session so it can decrypt protected video content. + * + * The 1.4 factory must always create 1.4 IDrmPlugin interfaces, which are + * returned via the 1.0 createPlugin method. + * + * To use 1.4 features the caller must cast the returned interface to a + * 1.4 HAL, using V1_4::IDrmPlugin::castFrom(). + */ + +interface IDrmFactory extends @1.3::IDrmFactory { +}; diff --git a/drm/1.4/IDrmPlugin.hal b/drm/1.4/IDrmPlugin.hal new file mode 100644 index 0000000000..9cc0600412 --- /dev/null +++ b/drm/1.4/IDrmPlugin.hal @@ -0,0 +1,50 @@ +/** + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.hardware.drm@1.4; + +import @1.1::SecurityLevel; +import @1.2::IDrmPlugin; + +/** + * IDrmPlugin is used to interact with a specific drm plugin that was + * created by IDrmFactory::createPlugin. A drm plugin provides methods for + * obtaining drm keys to be used by a codec to decrypt protected video + * content. + */ +interface IDrmPlugin extends @1.2::IDrmPlugin { + + /** + * Check if the specified mime-type & security level require a secure decoder + * component. + * + * @param mime The content mime-type + * @param level the requested security level + * @return secureRequired must be true if and only if a secure decoder is required + * for the specified mime-type & security level + */ + requiresSecureDecoder(string mime, @1.1::SecurityLevel level) generates (bool secureRequired); + + /** + * Check if the specified mime-type requires a secure decoder component + * at the highest security level supported on the device. + * + * @param mime The content mime-type + * @return secureRequired must be true if and only if a secure decoder is required + * for the specified mime-type + */ + requiresSecureDecoderDefault(string mime) generates (bool secureRequired); + +}; -- GitLab From 37719f3879150d6041d56b3e37c6ea2ecc69f0b5 Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Tue, 19 Jan 2021 19:39:01 -0800 Subject: [PATCH 393/790] Enhance Tuner 1.0 VTS testing and configurations Broadcom shared a valuable patch to enhance Tuner 1.0 VTS per their testing experience on the real devices. We evaluated the suggestions and fix the following issues: 1. Allow testers to set a default frontend 2. Allow testers to enable/disable frontend 3. Skip FMQ creation on filters that do not need FMQ 4. Don't fail if the vendor impl rejects a foreign keytoken 5. Better logs 6. Clean up filter and its callback on close regardless of the closing result 7. More filter size constants options Suggestions from: Gareth Fenn Test: atest VtsHalTvTunerV1_0TargetTest Bug: 177960135 Change-Id: Ie4dcc6cb284b2b57879f286c436f5bd9adf43201 --- tv/tuner/1.0/vts/functional/DvrTests.cpp | 3 +- tv/tuner/1.0/vts/functional/FilterTests.cpp | 24 +++++--- tv/tuner/1.0/vts/functional/FilterTests.h | 2 +- .../VtsHalTvTunerV1_0TargetTest.cpp | 59 +++++++++++-------- .../VtsHalTvTunerV1_0TestConfigurations.h | 9 +++ 5 files changed, 62 insertions(+), 35 deletions(-) diff --git a/tv/tuner/1.0/vts/functional/DvrTests.cpp b/tv/tuner/1.0/vts/functional/DvrTests.cpp index 0dfc032d19..ba211894f7 100644 --- a/tv/tuner/1.0/vts/functional/DvrTests.cpp +++ b/tv/tuner/1.0/vts/functional/DvrTests.cpp @@ -55,6 +55,7 @@ void DvrCallback::playbackThreadLoop() { uint8_t* buffer; ALOGW("[vts] playback thread loop start %s", mInputDataFile.c_str()); if (fd < 0) { + EXPECT_TRUE(fd >= 0) << "Failed to open: " + mInputDataFile; mPlaybackThreadRunning = false; ALOGW("[vts] Error %s", strerror(errno)); } @@ -178,7 +179,7 @@ void DvrCallback::recordThreadLoop(RecordSettings* /*recordSettings*/, bool* kee // Our current implementation filter the data and write it into the filter FMQ // immediately after the DATA_READY from the VTS/framework if (!readRecordFMQ()) { - ALOGD("[vts] record data failed to be filtered. Ending thread"); + ALOGW("[vts] record data failed to be filtered. Ending thread"); mRecordThreadRunning = false; break; } diff --git a/tv/tuner/1.0/vts/functional/FilterTests.cpp b/tv/tuner/1.0/vts/functional/FilterTests.cpp index 5f5d108fd3..240aa9f149 100644 --- a/tv/tuner/1.0/vts/functional/FilterTests.cpp +++ b/tv/tuner/1.0/vts/functional/FilterTests.cpp @@ -70,6 +70,10 @@ void FilterCallback::filterThreadLoop(DemuxFilterEvent& /* event */) { } bool FilterCallback::readFilterEventData() { + if (mFilterMQ == NULL) { + ALOGW("[vts] FMQ is not configured and does not need to be tested."); + return true; + } bool result = false; DemuxFilterEvent filterEvent = mFilterEvent; ALOGW("[vts] reading from filter FMQ or buffer %d", mFilterId); @@ -223,7 +227,11 @@ AssertionResult FilterTests::configFilter(DemuxFilterSettings setting, uint32_t return AssertionResult(status == Result::SUCCESS); } -AssertionResult FilterTests::getFilterMQDescriptor(uint32_t filterId) { +AssertionResult FilterTests::getFilterMQDescriptor(uint32_t filterId, bool getMqDesc) { + if (!getMqDesc) { + ALOGE("[vts] Filter does not need FMQ."); + return success(); + } Result status; EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first."; EXPECT_TRUE(mFilterCallbacks[filterId]) << "Test with getNewlyOpenedFilterId first."; @@ -284,16 +292,14 @@ AssertionResult FilterTests::clearTimeStamp() { AssertionResult FilterTests::closeFilter(uint32_t filterId) { EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first."; Result status = mFilters[filterId]->close(); - if (status == Result::SUCCESS) { - for (int i = 0; i < mUsedFilterIds.size(); i++) { - if (mUsedFilterIds[i] == filterId) { - mUsedFilterIds.erase(mUsedFilterIds.begin() + i); - break; - } + for (int i = 0; i < mUsedFilterIds.size(); i++) { + if (mUsedFilterIds[i] == filterId) { + mUsedFilterIds.erase(mUsedFilterIds.begin() + i); + break; } - mFilterCallbacks.erase(filterId); - mFilters.erase(filterId); } + mFilterCallbacks.erase(filterId); + mFilters.erase(filterId); return AssertionResult(status == Result::SUCCESS); } diff --git a/tv/tuner/1.0/vts/functional/FilterTests.h b/tv/tuner/1.0/vts/functional/FilterTests.h index 8ac9c555c1..c61fa18c3c 100644 --- a/tv/tuner/1.0/vts/functional/FilterTests.h +++ b/tv/tuner/1.0/vts/functional/FilterTests.h @@ -159,7 +159,7 @@ class FilterTests { AssertionResult getTimeStamp(); AssertionResult getNewlyOpenedFilterId(uint32_t& filterId); AssertionResult configFilter(DemuxFilterSettings setting, uint32_t filterId); - AssertionResult getFilterMQDescriptor(uint32_t filterId); + AssertionResult getFilterMQDescriptor(uint32_t filterId, bool getMqDesc); AssertionResult setFilterDataSource(uint32_t sourceFilterId, uint32_t sinkFilterId); AssertionResult setFilterDataSourceToDemux(uint32_t filterId); AssertionResult startFilter(uint32_t filterId); diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp index 078f5df391..891619a810 100644 --- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp +++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp @@ -48,7 +48,7 @@ void TunerFilterHidlTest::configSingleFilterInDemuxTest(FilterConfig filterConf, ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize)); ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId)); ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId)); - ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId)); + ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterConf.getMqDesc)); ASSERT_TRUE(mFilterTests.startFilter(filterId)); ASSERT_TRUE(mFilterTests.stopFilter(filterId)); ASSERT_TRUE(mFilterTests.closeFilter(filterId)); @@ -75,6 +75,9 @@ void TunerFilterHidlTest::testTimeFilter(TimeFilterConfig filterConf) { void TunerBroadcastHidlTest::broadcastSingleFilterTest(FilterConfig filterConf, FrontendConfig frontendConf) { + if (!frontendConf.enable) { + return; + } uint32_t feId; uint32_t demuxId; sp demux; @@ -99,7 +102,7 @@ void TunerBroadcastHidlTest::broadcastSingleFilterTest(FilterConfig filterConf, ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize)); ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId)); ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId)); - ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId)); + ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterConf.getMqDesc)); ASSERT_TRUE(mFilterTests.startFilter(filterId)); // tune test ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/)); @@ -145,7 +148,7 @@ void TunerPlaybackHidlTest::playbackSingleFilterTest(FilterConfig filterConf, Dv ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize)); ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId)); ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId)); - ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId)); + ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterConf.getMqDesc)); mDvrTests.startPlaybackInputThread(dvrConf.playbackInputFile, dvrConf.settings.playback()); ASSERT_TRUE(mDvrTests.startDvrPlayback()); ASSERT_TRUE(mFilterTests.startFilter(filterId)); @@ -160,6 +163,9 @@ void TunerPlaybackHidlTest::playbackSingleFilterTest(FilterConfig filterConf, Dv void TunerRecordHidlTest::recordSingleFilterTest(FilterConfig filterConf, FrontendConfig frontendConf, DvrConfig dvrConf) { + if (!frontendConf.enable) { + return; + } uint32_t feId; uint32_t demuxId; sp demux; @@ -184,7 +190,7 @@ void TunerRecordHidlTest::recordSingleFilterTest(FilterConfig filterConf, ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize)); ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId)); ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId)); - ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId)); + ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterConf.getMqDesc)); filter = mFilterTests.getFilterById(filterId); ASSERT_TRUE(filter != nullptr); mDvrTests.startRecordOutputThread(dvrConf.settings.record()); @@ -247,7 +253,7 @@ void TunerRecordHidlTest::attachSingleFilterToRecordDvrTest(FilterConfig filterC ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize)); ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId)); ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId)); - ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId)); + ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterConf.getMqDesc)); filter = mFilterTests.getFilterById(filterId); ASSERT_TRUE(filter != nullptr); ASSERT_TRUE(mDvrTests.attachFilterToDvr(filter)); @@ -265,6 +271,9 @@ void TunerRecordHidlTest::attachSingleFilterToRecordDvrTest(FilterConfig filterC void TunerDescramblerHidlTest::scrambledBroadcastTest(set mediaFilterConfs, FrontendConfig frontendConf, DescramblerConfig descConfig) { + if (!frontendConf.enable) { + return; + } uint32_t feId; uint32_t demuxId; sp demux; @@ -328,17 +337,17 @@ void TunerDescramblerHidlTest::scrambledBroadcastTest(set m TEST_P(TunerFrontendHidlTest, TuneFrontend) { description("Tune one Frontend with specific setting and check Lock event"); - mFrontendTests.tuneTest(frontendArray[DVBT]); + mFrontendTests.tuneTest(frontendArray[defaultFrontend]); } TEST_P(TunerFrontendHidlTest, AutoScanFrontend) { description("Run an auto frontend scan with specific setting and check lock scanMessage"); - mFrontendTests.scanTest(frontendScanArray[SCAN_DVBT], FrontendScanType::SCAN_AUTO); + mFrontendTests.scanTest(frontendScanArray[defaultScanFrontend], FrontendScanType::SCAN_AUTO); } TEST_P(TunerFrontendHidlTest, BlindScanFrontend) { description("Run an blind frontend scan with specific setting and check lock scanMessage"); - mFrontendTests.scanTest(frontendScanArray[SCAN_DVBT], FrontendScanType::SCAN_BLIND); + mFrontendTests.scanTest(frontendScanArray[defaultScanFrontend], FrontendScanType::SCAN_BLIND); } TEST_P(TunerLnbHidlTest, OpenLnbByName) { @@ -374,7 +383,7 @@ TEST_P(TunerDemuxHidlTest, openDemux) { uint32_t feId; uint32_t demuxId; sp demux; - mFrontendTests.getFrontendIdByType(frontendArray[DVBT].type, feId); + mFrontendTests.getFrontendIdByType(frontendArray[defaultFrontend].type, feId); ASSERT_TRUE(feId != INVALID_ID); ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); ASSERT_TRUE(mFrontendTests.setFrontendCallback()); @@ -394,7 +403,7 @@ TEST_P(TunerDemuxHidlTest, getAvSyncTime) { uint32_t avSyncHwId; sp mediaFilter; - mFrontendTests.getFrontendIdByType(frontendArray[DVBT].type, feId); + mFrontendTests.getFrontendIdByType(frontendArray[defaultFrontend].type, feId); ASSERT_TRUE(feId != INVALID_ID); ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); ASSERT_TRUE(mFrontendTests.setFrontendCallback()); @@ -422,7 +431,7 @@ TEST_P(TunerDemuxHidlTest, getAvSyncTime) { TEST_P(TunerFilterHidlTest, StartFilterInDemux) { description("Open and start a filter in Demux."); // TODO use paramterized tests - configSingleFilterInDemuxTest(filterArray[TS_VIDEO0], frontendArray[DVBT]); + configSingleFilterInDemuxTest(filterArray[TS_VIDEO0], frontendArray[defaultFrontend]); } TEST_P(TunerFilterHidlTest, SetFilterLinkage) { @@ -463,22 +472,22 @@ TEST_P(TunerFilterHidlTest, testTimeFilter) { TEST_P(TunerBroadcastHidlTest, BroadcastDataFlowVideoFilterTest) { description("Test Video Filter functionality in Broadcast use case."); - broadcastSingleFilterTest(filterArray[TS_VIDEO1], frontendArray[DVBT]); + broadcastSingleFilterTest(filterArray[TS_VIDEO1], frontendArray[defaultFrontend]); } TEST_P(TunerBroadcastHidlTest, BroadcastDataFlowAudioFilterTest) { description("Test Audio Filter functionality in Broadcast use case."); - broadcastSingleFilterTest(filterArray[TS_AUDIO0], frontendArray[DVBT]); + broadcastSingleFilterTest(filterArray[TS_AUDIO0], frontendArray[defaultFrontend]); } TEST_P(TunerBroadcastHidlTest, BroadcastDataFlowSectionFilterTest) { description("Test Section Filter functionality in Broadcast use case."); - broadcastSingleFilterTest(filterArray[TS_SECTION0], frontendArray[DVBT]); + broadcastSingleFilterTest(filterArray[TS_SECTION0], frontendArray[defaultFrontend]); } TEST_P(TunerBroadcastHidlTest, IonBufferTest) { description("Test the av filter data bufferring."); - broadcastSingleFilterTest(filterArray[TS_VIDEO0], frontendArray[DVBT]); + broadcastSingleFilterTest(filterArray[TS_VIDEO0], frontendArray[defaultFrontend]); } TEST_P(TunerBroadcastHidlTest, LnbBroadcastDataFlowVideoFilterTest) { @@ -493,11 +502,11 @@ TEST_P(TunerBroadcastHidlTest, BroadcastEsDataFlowMediaFiltersTest) { sp demux; uint32_t filterId; - mFrontendTests.getFrontendIdByType(frontendArray[DVBT].type, feId); + mFrontendTests.getFrontendIdByType(frontendArray[defaultFrontend].type, feId); if (feId == INVALID_ID) { // TODO broadcast test on Cuttlefish needs licensed ts input, // these tests are runnable on vendor device with real frontend module - // or with manual ts installing and use DVBT frontend. + // or with manual ts installing and use defaultFrontend frontend. return; } ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); @@ -510,13 +519,13 @@ TEST_P(TunerBroadcastHidlTest, BroadcastEsDataFlowMediaFiltersTest) { filterArray[TS_AUDIO1].bufferSize)); ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId)); ASSERT_TRUE(mFilterTests.configFilter(filterArray[TS_AUDIO1].settings, filterId)); - ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId)); + ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterArray[TS_AUDIO1].getMqDesc)); ASSERT_TRUE(mFilterTests.startFilter(filterId)); ASSERT_TRUE(mFilterTests.openFilterInDemux(filterArray[TS_VIDEO1].type, filterArray[TS_VIDEO1].bufferSize)); ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId)); ASSERT_TRUE(mFilterTests.configFilter(filterArray[TS_VIDEO1].settings, filterId)); - ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId)); + ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterArray[TS_VIDEO1].getMqDesc)); ASSERT_TRUE(mFilterTests.startFilter(filterId)); // tune test PlaybackSettings playbackSettings{ @@ -533,7 +542,8 @@ TEST_P(TunerBroadcastHidlTest, BroadcastEsDataFlowMediaFiltersTest) { }; dvrConfig.settings.playback(playbackSettings); mFrontendTests.setSoftwareFrontendDvrConfig(dvrConfig); - ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendArray[DVBT], true /*testWithDemux*/)); + ASSERT_TRUE( + mFrontendTests.tuneFrontend(frontendArray[defaultFrontend], true /*testWithDemux*/)); ASSERT_TRUE(filterDataOutputTest(goldenOutputFiles)); ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/)); ASSERT_TRUE(mFilterTests.stopFilter(filterId)); @@ -550,13 +560,14 @@ TEST_P(TunerPlaybackHidlTest, PlaybackDataFlowWithTsSectionFilterTest) { TEST_P(TunerRecordHidlTest, AttachFiltersToRecordTest) { description("Attach a single filter to the record dvr test."); // TODO use paramterized tests - attachSingleFilterToRecordDvrTest(filterArray[TS_RECORD0], frontendArray[DVBT], + attachSingleFilterToRecordDvrTest(filterArray[TS_RECORD0], frontendArray[defaultFrontend], dvrArray[DVR_RECORD0]); } TEST_P(TunerRecordHidlTest, RecordDataFlowWithTsRecordFilterTest) { description("Feed ts data from frontend to recording and test with ts record filter"); - recordSingleFilterTest(filterArray[TS_RECORD0], frontendArray[DVBT], dvrArray[DVR_RECORD0]); + recordSingleFilterTest(filterArray[TS_RECORD0], frontendArray[defaultFrontend], + dvrArray[DVR_RECORD0]); } TEST_P(TunerRecordHidlTest, LnbRecordDataFlowWithTsRecordFilterTest) { @@ -569,7 +580,7 @@ TEST_P(TunerDescramblerHidlTest, CreateDescrambler) { uint32_t feId; uint32_t demuxId; sp demux; - mFrontendTests.getFrontendIdByType(frontendArray[DVBT].type, feId); + mFrontendTests.getFrontendIdByType(frontendArray[defaultFrontend].type, feId); ASSERT_TRUE(feId != INVALID_ID); ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); ASSERT_TRUE(mFrontendTests.setFrontendCallback()); @@ -586,7 +597,7 @@ TEST_P(TunerDescramblerHidlTest, ScrambledBroadcastDataFlowMediaFiltersTest) { set filterConfs; filterConfs.insert(filterArray[TS_AUDIO0]); filterConfs.insert(filterArray[TS_VIDEO1]); - scrambledBroadcastTest(filterConfs, frontendArray[DVBT], descramblerArray[DESC_0]); + scrambledBroadcastTest(filterConfs, frontendArray[defaultFrontend], descramblerArray[DESC_0]); } INSTANTIATE_TEST_SUITE_P( diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h index 27c65931b8..b0a9c038e3 100644 --- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h +++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h @@ -55,6 +55,7 @@ using android::hardware::tv::tuner::V1_0::RecordSettings; using namespace std; +const uint32_t FMQ_SIZE_512K = 0x80000; const uint32_t FMQ_SIZE_1M = 0x100000; const uint32_t FMQ_SIZE_4M = 0x400000; const uint32_t FMQ_SIZE_16M = 0x1000000; @@ -134,6 +135,7 @@ struct FilterConfig { uint32_t bufferSize; DemuxFilterType type; DemuxFilterSettings settings; + bool getMqDesc; bool operator<(const FilterConfig& /*c*/) const { return false; } }; @@ -144,6 +146,7 @@ struct TimeFilterConfig { }; struct FrontendConfig { + bool enable; bool isSoftwareFe; FrontendType type; FrontendSettings settings; @@ -191,6 +194,8 @@ static DemuxFilterType filterLinkageTypes[LINKAGE_DIR][FILTER_MAIN_TYPE_BIT_COUN static DvrConfig dvrArray[DVR_MAX]; static DescramblerConfig descramblerArray[DESC_MAX]; static vector goldenOutputFiles; +static int defaultFrontend = DVBT; +static int defaultScanFrontend = SCAN_DVBT; /** Configuration array for the frontend tune test */ inline void initFrontendConfig() { @@ -216,7 +221,9 @@ inline void initFrontendConfig() { frontendArray[DVBT].tuneStatusTypes = types; frontendArray[DVBT].expectTuneStatuses = statuses; frontendArray[DVBT].isSoftwareFe = true; + frontendArray[DVBS].enable = true; frontendArray[DVBS].type = FrontendType::DVBS; + frontendArray[DVBS].enable = true; frontendArray[DVBS].isSoftwareFe = true; }; @@ -288,6 +295,7 @@ inline void initFilterConfig() { .isRaw = false, .streamId = 0xbd, }); + filterArray[TS_PES0].getMqDesc = true; // TS PCR filter setting filterArray[TS_PCR0].type.mainType = DemuxFilterMainType::TS; filterArray[TS_PCR0].type.subType.tsFilterType(DemuxTsFilterType::PCR); @@ -308,6 +316,7 @@ inline void initFilterConfig() { filterArray[TS_SECTION0].settings.ts().filterSettings.section({ .isRaw = false, }); + filterArray[TS_SECTION0].getMqDesc = true; // TS RECORD filter setting filterArray[TS_RECORD0].type.mainType = DemuxFilterMainType::TS; filterArray[TS_RECORD0].type.subType.tsFilterType(DemuxTsFilterType::RECORD); -- GitLab From ff911f463dc12b920e258451e49ee5ddec876b29 Mon Sep 17 00:00:00 2001 From: Robert Shih Date: Mon, 18 Jan 2021 00:01:40 -0800 Subject: [PATCH 394/790] android.hardware.drm@1.4: add setPlaybackId Bug: 159337195 Bug: 168341163 Test: GtsMediaTestCases MediaDrmTest#testSetPlaybackId Change-Id: Ib0b19c0e60d2d6797a3e4b0cfd3d76a2afb808d9 --- drm/1.4/IDrmPlugin.hal | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drm/1.4/IDrmPlugin.hal b/drm/1.4/IDrmPlugin.hal index 9cc0600412..e8af230033 100644 --- a/drm/1.4/IDrmPlugin.hal +++ b/drm/1.4/IDrmPlugin.hal @@ -15,6 +15,8 @@ */ package android.hardware.drm@1.4; +import @1.0::Status; +import @1.0::SessionId; import @1.1::SecurityLevel; import @1.2::IDrmPlugin; @@ -47,4 +49,16 @@ interface IDrmPlugin extends @1.2::IDrmPlugin { */ requiresSecureDecoderDefault(string mime) generates (bool secureRequired); + /** + * 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 status the status of the call. The status must be OK on success, or + * ERROR_DRM_SESSION_NOT_OPENED if the drm session cannot be found + */ + setPlaybackId(SessionId sessionId, string playbackId) generates (@1.0::Status status); + }; -- GitLab From 8ddf29869bdf116b5a2d97aa52f00d778b48af04 Mon Sep 17 00:00:00 2001 From: Benjamin Schwartz Date: Mon, 21 Dec 2020 14:57:45 -0800 Subject: [PATCH 395/790] power/stats: Add EnergyConsumer types Also cleaning up Power Stats HAL type names to be less verbose Bug: 176117316 Test: atest VtsHalPowerStatsTargetTest Change-Id: I252a13b0490326ab9557f4a81ee313e57eb36754 --- .../stats/{StateInfo.aidl => Channel.aidl} | 19 +++++---- .../hardware/power/stats/EnergyConsumer.aidl | 26 ++++++++++++ .../stats/EnergyConsumerAttribution.aidl | 13 +++--- .../power/stats/EnergyConsumerResult.aidl | 15 +++---- ...ntityInfo.aidl => EnergyConsumerType.aidl} | 21 +++++----- .../power/stats/EnergyMeasurement.aidl | 15 +++---- .../hardware/power/stats/IPowerStats.aidl | 21 +++++----- ...EnergyConsumerId.aidl => PowerEntity.aidl} | 22 +++++----- .../stats/{ChannelInfo.aidl => State.aidl} | 19 +++++---- .../hardware/power/stats/StateResidency.aidl | 15 +++---- .../power/stats/StateResidencyResult.aidl | 15 +++---- .../stats/{ChannelInfo.aidl => Channel.aidl} | 10 ++--- .../hardware/power/stats/EnergyConsumer.aidl | 41 +++++++++++++++++++ .../stats/EnergyConsumerAttribution.aidl | 2 +- .../power/stats/EnergyConsumerResult.aidl | 8 ++-- ...onsumerId.aidl => EnergyConsumerType.aidl} | 9 ++-- .../power/stats/EnergyMeasurement.aidl | 2 +- .../hardware/power/stats/IPowerStats.aidl | 21 +++++----- ...{PowerEntityInfo.aidl => PowerEntity.aidl} | 16 ++++---- .../stats/{StateInfo.aidl => State.aidl} | 10 ++--- .../hardware/power/stats/StateResidency.aidl | 2 +- .../power/stats/StateResidencyResult.aidl | 2 +- power/stats/aidl/default/PowerStats.cpp | 11 +++-- power/stats/aidl/default/PowerStats.h | 8 ++-- .../aidl/vts/VtsHalPowerStatsTargetTest.cpp | 30 +++++++------- 25 files changed, 225 insertions(+), 148 deletions(-) rename power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/{StateInfo.aidl => Channel.aidl} (57%) create mode 100644 power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumer.aidl rename power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/{PowerEntityInfo.aidl => EnergyConsumerType.aidl} (55%) rename power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/{EnergyConsumerId.aidl => PowerEntity.aidl} (53%) rename power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/{ChannelInfo.aidl => State.aidl} (57%) rename power/stats/aidl/android/hardware/power/stats/{ChannelInfo.aidl => Channel.aidl} (78%) create mode 100644 power/stats/aidl/android/hardware/power/stats/EnergyConsumer.aidl rename power/stats/aidl/android/hardware/power/stats/{EnergyConsumerId.aidl => EnergyConsumerType.aidl} (82%) rename power/stats/aidl/android/hardware/power/stats/{PowerEntityInfo.aidl => PowerEntity.aidl} (67%) rename power/stats/aidl/android/hardware/power/stats/{StateInfo.aidl => State.aidl} (76%) diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateInfo.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/Channel.aidl similarity index 57% rename from power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateInfo.aidl rename to power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/Channel.aidl index 0db9ab190d..ac326b5906 100644 --- a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateInfo.aidl +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/Channel.aidl @@ -2,13 +2,14 @@ // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped @@ -17,7 +18,7 @@ package android.hardware.power.stats; @VintfStability -parcelable StateInfo { - int stateId; - @utf8InCpp String stateName; +parcelable Channel { + int id; + @utf8InCpp String name; } diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumer.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumer.aidl new file mode 100644 index 0000000000..9f9a10bee4 --- /dev/null +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumer.aidl @@ -0,0 +1,26 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -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.power.stats; +@VintfStability +parcelable EnergyConsumer { + int id; + int ordinal; + android.hardware.power.stats.EnergyConsumerType type; + @utf8InCpp String name; +} diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerAttribution.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerAttribution.aidl index 0a7cff7d01..53f31b6410 100644 --- a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerAttribution.aidl +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerAttribution.aidl @@ -2,13 +2,14 @@ // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerResult.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerResult.aidl index 815316ec92..773fa282bd 100644 --- a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerResult.aidl +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerResult.aidl @@ -2,13 +2,14 @@ // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped @@ -18,7 +19,7 @@ package android.hardware.power.stats; @VintfStability parcelable EnergyConsumerResult { - android.hardware.power.stats.EnergyConsumerId energyConsumerId; + int id; long timestampMs; long energyUWs; android.hardware.power.stats.EnergyConsumerAttribution[] attribution; diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/PowerEntityInfo.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerType.aidl similarity index 55% rename from power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/PowerEntityInfo.aidl rename to power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerType.aidl index 3b16362046..d08d24eedc 100644 --- a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/PowerEntityInfo.aidl +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerType.aidl @@ -2,13 +2,14 @@ // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped @@ -17,8 +18,8 @@ package android.hardware.power.stats; @VintfStability -parcelable PowerEntityInfo { - int powerEntityId; - @utf8InCpp String powerEntityName; - android.hardware.power.stats.StateInfo[] states; +enum EnergyConsumerType { + OTHER = 0, + CPU_CLUSTER = 1, + DISPLAY = 2, } diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyMeasurement.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyMeasurement.aidl index 4d56ccf379..fc61c27355 100644 --- a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyMeasurement.aidl +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyMeasurement.aidl @@ -2,13 +2,14 @@ // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped @@ -18,7 +19,7 @@ package android.hardware.power.stats; @VintfStability parcelable EnergyMeasurement { - int channelId; + int id; long timestampMs; long durationMs; long energyUWs; diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/IPowerStats.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/IPowerStats.aidl index 07013b0b45..11a2936b82 100644 --- a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/IPowerStats.aidl +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/IPowerStats.aidl @@ -2,13 +2,14 @@ // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped @@ -18,10 +19,10 @@ package android.hardware.power.stats; @VintfStability interface IPowerStats { - android.hardware.power.stats.PowerEntityInfo[] getPowerEntityInfo(); + android.hardware.power.stats.PowerEntity[] getPowerEntityInfo(); android.hardware.power.stats.StateResidencyResult[] getStateResidency(in int[] powerEntityIds); - android.hardware.power.stats.EnergyConsumerId[] getEnergyConsumerInfo(); - android.hardware.power.stats.EnergyConsumerResult[] getEnergyConsumed(in android.hardware.power.stats.EnergyConsumerId[] energyConsumerIds); - android.hardware.power.stats.ChannelInfo[] getEnergyMeterInfo(); + android.hardware.power.stats.EnergyConsumer[] getEnergyConsumerInfo(); + android.hardware.power.stats.EnergyConsumerResult[] getEnergyConsumed(in int[] energyConsumerIds); + android.hardware.power.stats.Channel[] getEnergyMeterInfo(); android.hardware.power.stats.EnergyMeasurement[] readEnergyMeters(in int[] channelIds); } diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerId.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/PowerEntity.aidl similarity index 53% rename from power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerId.aidl rename to power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/PowerEntity.aidl index 7ca3b15ff1..8fff6c3053 100644 --- a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerId.aidl +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/PowerEntity.aidl @@ -2,13 +2,14 @@ // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped @@ -16,8 +17,9 @@ // later when a module using the interface is updated, e.g., Mainline modules. package android.hardware.power.stats; -@Backing(type="int") @VintfStability -enum EnergyConsumerId { - DISPLAY = 0, - GPS = 1, +@VintfStability +parcelable PowerEntity { + int id; + @utf8InCpp String name; + android.hardware.power.stats.State[] states; } diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/ChannelInfo.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/State.aidl similarity index 57% rename from power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/ChannelInfo.aidl rename to power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/State.aidl index 209bec4aa7..2a8e6f8dc8 100644 --- a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/ChannelInfo.aidl +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/State.aidl @@ -2,13 +2,14 @@ // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped @@ -17,7 +18,7 @@ package android.hardware.power.stats; @VintfStability -parcelable ChannelInfo { - int channelId; - @utf8InCpp String channelName; +parcelable State { + int id; + @utf8InCpp String name; } diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateResidency.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateResidency.aidl index 206c974bc5..cb38df580e 100644 --- a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateResidency.aidl +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateResidency.aidl @@ -2,13 +2,14 @@ // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped @@ -18,7 +19,7 @@ package android.hardware.power.stats; @VintfStability parcelable StateResidency { - int stateId; + int id; long totalTimeInStateMs; long totalStateEntryCount; long lastEntryTimestampMs; diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateResidencyResult.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateResidencyResult.aidl index dc41fef557..9f92253e33 100644 --- a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateResidencyResult.aidl +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateResidencyResult.aidl @@ -2,13 +2,14 @@ // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped @@ -18,6 +19,6 @@ package android.hardware.power.stats; @VintfStability parcelable StateResidencyResult { - int powerEntityId; + int id; android.hardware.power.stats.StateResidency[] stateResidencyData; } diff --git a/power/stats/aidl/android/hardware/power/stats/ChannelInfo.aidl b/power/stats/aidl/android/hardware/power/stats/Channel.aidl similarity index 78% rename from power/stats/aidl/android/hardware/power/stats/ChannelInfo.aidl rename to power/stats/aidl/android/hardware/power/stats/Channel.aidl index a2ca6a63f1..09c7d75942 100644 --- a/power/stats/aidl/android/hardware/power/stats/ChannelInfo.aidl +++ b/power/stats/aidl/android/hardware/power/stats/Channel.aidl @@ -17,14 +17,14 @@ package android.hardware.power.stats; @VintfStability -parcelable ChannelInfo { +parcelable Channel { /** - * Unique ID of this ChannelInfo + * Unique ID of this Channel */ - int channelId; + int id; /** - * Unique name of the ChannelInfo. Vendor/device specific. Opaque to framework + * Unique name of this Channel. Vendor/device specific. Opaque to framework */ - @utf8InCpp String channelName; + @utf8InCpp String name; } diff --git a/power/stats/aidl/android/hardware/power/stats/EnergyConsumer.aidl b/power/stats/aidl/android/hardware/power/stats/EnergyConsumer.aidl new file mode 100644 index 0000000000..065d9993d9 --- /dev/null +++ b/power/stats/aidl/android/hardware/power/stats/EnergyConsumer.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. + */ + +package android.hardware.power.stats; + +import android.hardware.power.stats.EnergyConsumerType; + +@VintfStability +parcelable EnergyConsumer { + /** + * Unique ID of this EnergyConsumer + */ + int id; + + /** + * For a group of EnergyConsumers of the same logical type, sorting by ordinal should + * be give their physical order. No other meaning is carried by it. + */ + int ordinal; + + /* Type of this EnergyConsumer */ + EnergyConsumerType type; + + /** + * Unique name of this EnergyConsumer. Vendor/device specific. Opaque to framework + */ + @utf8InCpp String name; +} \ No newline at end of file diff --git a/power/stats/aidl/android/hardware/power/stats/EnergyConsumerAttribution.aidl b/power/stats/aidl/android/hardware/power/stats/EnergyConsumerAttribution.aidl index e07204aa33..5767de1656 100644 --- a/power/stats/aidl/android/hardware/power/stats/EnergyConsumerAttribution.aidl +++ b/power/stats/aidl/android/hardware/power/stats/EnergyConsumerAttribution.aidl @@ -19,7 +19,7 @@ package android.hardware.power.stats; @VintfStability parcelable EnergyConsumerAttribution { /** - * Android ID / Linux UID, the accumulated energy should be attributed to + * Android ID / Linux UID, the accumulated energy is attributed to */ int uid; /** diff --git a/power/stats/aidl/android/hardware/power/stats/EnergyConsumerResult.aidl b/power/stats/aidl/android/hardware/power/stats/EnergyConsumerResult.aidl index e8d3dd9f94..12d2042eb2 100644 --- a/power/stats/aidl/android/hardware/power/stats/EnergyConsumerResult.aidl +++ b/power/stats/aidl/android/hardware/power/stats/EnergyConsumerResult.aidl @@ -16,7 +16,6 @@ package android.hardware.power.stats; -import android.hardware.power.stats.EnergyConsumerId; import android.hardware.power.stats.EnergyConsumerAttribution; @VintfStability @@ -24,17 +23,18 @@ parcelable EnergyConsumerResult { /** * ID of the EnergyConsumer associated with this result */ - EnergyConsumerId energyConsumerId; + int id; /** * Time since boot in milliseconds */ long timestampMs; /** - * Accumulated energy since boot in microwatt-seconds (uWs) + * Total accumulated energy since boot in microwatt-seconds (uWs) */ long energyUWs; /** - * Optional attribution per UID for this EnergyConsumer. + * Optional attributed energy per Android ID / Linux UID for this EnergyConsumer. + * Sum total of attributed energy must be less than or equal to total accumulated energy. */ EnergyConsumerAttribution[] attribution; } diff --git a/power/stats/aidl/android/hardware/power/stats/EnergyConsumerId.aidl b/power/stats/aidl/android/hardware/power/stats/EnergyConsumerType.aidl similarity index 82% rename from power/stats/aidl/android/hardware/power/stats/EnergyConsumerId.aidl rename to power/stats/aidl/android/hardware/power/stats/EnergyConsumerType.aidl index 4a6a67724d..7fd2348d70 100644 --- a/power/stats/aidl/android/hardware/power/stats/EnergyConsumerId.aidl +++ b/power/stats/aidl/android/hardware/power/stats/EnergyConsumerType.aidl @@ -16,9 +16,10 @@ package android.hardware.power.stats; +/* Indicates the type of an energy consumer reported by the Power Stats HAL */ @VintfStability -@Backing(type="int") -enum EnergyConsumerId { - DISPLAY = 0, - GPS = 1, +enum EnergyConsumerType { + OTHER, + CPU_CLUSTER, + DISPLAY, } \ No newline at end of file diff --git a/power/stats/aidl/android/hardware/power/stats/EnergyMeasurement.aidl b/power/stats/aidl/android/hardware/power/stats/EnergyMeasurement.aidl index d81914d1f0..d3e8f46699 100644 --- a/power/stats/aidl/android/hardware/power/stats/EnergyMeasurement.aidl +++ b/power/stats/aidl/android/hardware/power/stats/EnergyMeasurement.aidl @@ -21,7 +21,7 @@ parcelable EnergyMeasurement { /** * ID of the Channel associated with this measurement */ - int channelId; + int id; /** * Approximate time of data capture in millseconds since boot */ diff --git a/power/stats/aidl/android/hardware/power/stats/IPowerStats.aidl b/power/stats/aidl/android/hardware/power/stats/IPowerStats.aidl index 05e2004b67..24a8f67ca8 100644 --- a/power/stats/aidl/android/hardware/power/stats/IPowerStats.aidl +++ b/power/stats/aidl/android/hardware/power/stats/IPowerStats.aidl @@ -16,11 +16,11 @@ package android.hardware.power.stats; -import android.hardware.power.stats.ChannelInfo; -import android.hardware.power.stats.EnergyConsumerId; +import android.hardware.power.stats.Channel; +import android.hardware.power.stats.EnergyConsumer; import android.hardware.power.stats.EnergyConsumerResult; import android.hardware.power.stats.EnergyMeasurement; -import android.hardware.power.stats.PowerEntityInfo; +import android.hardware.power.stats.PowerEntity; import android.hardware.power.stats.StateResidencyResult; @VintfStability @@ -34,7 +34,7 @@ interface IPowerStats { * * @return List of information on each PowerEntity */ - PowerEntityInfo[] getPowerEntityInfo(); + PowerEntity[] getPowerEntityInfo(); /** * Reports the accumulated state residency for each requested PowerEntity. @@ -61,15 +61,14 @@ interface IPowerStats { StateResidencyResult[] getStateResidency(in int[] powerEntityIds); /** - * Return the list IDs for all supported EnergyConsumers for which energy consumption data is - * available. + * Return the list EnergyConsumers for which energy consumption data is available. * * An EnergyConsumer is a device subsystem or peripheral that consumes energy. Energy * consumption data may be used by framework for the purpose of power attribution. * - * @return List of EnergyConsumersIds that are available. + * @return List of EnergyConsumers that are available. */ - EnergyConsumerId[] getEnergyConsumerInfo(); + EnergyConsumer[] getEnergyConsumerInfo(); /** * Reports the energy consumed since boot by each requested EnergyConsumer. @@ -83,7 +82,7 @@ interface IPowerStats { * - STATUS_BAD_VALUE if an invalid energyConsumerId is provided * - STATUS_FAILED_TRANSACTION if any EnergyConsumerResult fails to be returned */ - EnergyConsumerResult[] getEnergyConsumed(in EnergyConsumerId[] energyConsumerIds); + EnergyConsumerResult[] getEnergyConsumed(in int[] energyConsumerIds); /** * Return information related to all channels monitored by Energy Meters. @@ -91,9 +90,9 @@ interface IPowerStats { * An Energy Meter is a device that monitors energy and may support monitoring multiple * channels simultaneously. A channel may correspond a bus, sense resistor, or power rail. * - * @return Information about channels monitored by Energy Meters. + * @return Channels monitored by Energy Meters. */ - ChannelInfo[] getEnergyMeterInfo(); + Channel[] getEnergyMeterInfo(); /** * Reports accumulated energy for each specified channel. diff --git a/power/stats/aidl/android/hardware/power/stats/PowerEntityInfo.aidl b/power/stats/aidl/android/hardware/power/stats/PowerEntity.aidl similarity index 67% rename from power/stats/aidl/android/hardware/power/stats/PowerEntityInfo.aidl rename to power/stats/aidl/android/hardware/power/stats/PowerEntity.aidl index 002b34376e..6844a4cdb6 100644 --- a/power/stats/aidl/android/hardware/power/stats/PowerEntityInfo.aidl +++ b/power/stats/aidl/android/hardware/power/stats/PowerEntity.aidl @@ -16,20 +16,20 @@ package android.hardware.power.stats; -import android.hardware.power.stats.StateInfo; +import android.hardware.power.stats.State; @VintfStability -parcelable PowerEntityInfo { +parcelable PowerEntity { /** - * Unique ID of this PowerEntityInfo + * Unique ID of this PowerEntity */ - int powerEntityId; + int id; /** - * Unique name of the PowerEntity. Vendor/device specific. Opaque to framework + * Unique name of this PowerEntity. Vendor/device specific. Opaque to framework */ - @utf8InCpp String powerEntityName; + @utf8InCpp String name; /** - * List of states that the PowerEntity may reside in + * List of states that this PowerEntity may reside in */ - StateInfo[] states; + State[] states; } \ No newline at end of file diff --git a/power/stats/aidl/android/hardware/power/stats/StateInfo.aidl b/power/stats/aidl/android/hardware/power/stats/State.aidl similarity index 76% rename from power/stats/aidl/android/hardware/power/stats/StateInfo.aidl rename to power/stats/aidl/android/hardware/power/stats/State.aidl index 5703f1e9bd..33a9f705a5 100644 --- a/power/stats/aidl/android/hardware/power/stats/StateInfo.aidl +++ b/power/stats/aidl/android/hardware/power/stats/State.aidl @@ -17,15 +17,15 @@ package android.hardware.power.stats; @VintfStability -parcelable StateInfo { +parcelable State { /** - * Unique (for a given PowerEntityInfo) ID of this StateInfo + * Unique (for a given PowerEntity) ID of this State */ - int stateId; + int id; /** - * Unique (for a given PowerEntityInfo) name of the state. Vendor/device specific. + * Unique (for a given PowerEntity) name of the state. Vendor/device specific. * Opaque to framework */ - @utf8InCpp String stateName; + @utf8InCpp String name; } diff --git a/power/stats/aidl/android/hardware/power/stats/StateResidency.aidl b/power/stats/aidl/android/hardware/power/stats/StateResidency.aidl index a85ca33b51..41625171ad 100644 --- a/power/stats/aidl/android/hardware/power/stats/StateResidency.aidl +++ b/power/stats/aidl/android/hardware/power/stats/StateResidency.aidl @@ -24,7 +24,7 @@ parcelable StateResidency { /** * ID of the state associated with this residency */ - int stateId; + int id; /** * Total time in milliseconds that the corresponding PowerEntity resided * in this state since boot diff --git a/power/stats/aidl/android/hardware/power/stats/StateResidencyResult.aidl b/power/stats/aidl/android/hardware/power/stats/StateResidencyResult.aidl index 3356405a0a..949879c22c 100644 --- a/power/stats/aidl/android/hardware/power/stats/StateResidencyResult.aidl +++ b/power/stats/aidl/android/hardware/power/stats/StateResidencyResult.aidl @@ -23,7 +23,7 @@ parcelable StateResidencyResult { /** * ID of the PowerEntity associated with this result */ - int powerEntityId; + int id; /** * Residency for each state in the PowerEntity's state space */ diff --git a/power/stats/aidl/default/PowerStats.cpp b/power/stats/aidl/default/PowerStats.cpp index 367ee95201..6cb0a738b0 100644 --- a/power/stats/aidl/default/PowerStats.cpp +++ b/power/stats/aidl/default/PowerStats.cpp @@ -24,7 +24,7 @@ namespace hardware { namespace power { namespace stats { -ndk::ScopedAStatus PowerStats::getPowerEntityInfo(std::vector* _aidl_return) { +ndk::ScopedAStatus PowerStats::getPowerEntityInfo(std::vector* _aidl_return) { (void)_aidl_return; return ndk::ScopedAStatus::ok(); } @@ -36,20 +36,19 @@ ndk::ScopedAStatus PowerStats::getStateResidency(const std::vector& in_ return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus PowerStats::getEnergyConsumerInfo(std::vector* _aidl_return) { +ndk::ScopedAStatus PowerStats::getEnergyConsumerInfo(std::vector* _aidl_return) { (void)_aidl_return; return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus PowerStats::getEnergyConsumed( - const std::vector& in_energyConsumerIds, - std::vector* _aidl_return) { +ndk::ScopedAStatus PowerStats::getEnergyConsumed(const std::vector& in_energyConsumerIds, + std::vector* _aidl_return) { (void)in_energyConsumerIds; (void)_aidl_return; return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus PowerStats::getEnergyMeterInfo(std::vector* _aidl_return) { +ndk::ScopedAStatus PowerStats::getEnergyMeterInfo(std::vector* _aidl_return) { (void)_aidl_return; return ndk::ScopedAStatus::ok(); } diff --git a/power/stats/aidl/default/PowerStats.h b/power/stats/aidl/default/PowerStats.h index 76ab2cbd95..04c2d547cc 100644 --- a/power/stats/aidl/default/PowerStats.h +++ b/power/stats/aidl/default/PowerStats.h @@ -28,13 +28,13 @@ class PowerStats : public BnPowerStats { public: PowerStats() = default; // Methods from aidl::android::hardware::power::stats::IPowerStats - ndk::ScopedAStatus getPowerEntityInfo(std::vector* _aidl_return) override; + ndk::ScopedAStatus getPowerEntityInfo(std::vector* _aidl_return) override; ndk::ScopedAStatus getStateResidency(const std::vector& in_powerEntityIds, std::vector* _aidl_return) override; - ndk::ScopedAStatus getEnergyConsumerInfo(std::vector* _aidl_return) override; - ndk::ScopedAStatus getEnergyConsumed(const std::vector& in_energyConsumerIds, + ndk::ScopedAStatus getEnergyConsumerInfo(std::vector* _aidl_return) override; + ndk::ScopedAStatus getEnergyConsumed(const std::vector& in_energyConsumerIds, std::vector* _aidl_return) override; - ndk::ScopedAStatus getEnergyMeterInfo(std::vector* _aidl_return) override; + ndk::ScopedAStatus getEnergyMeterInfo(std::vector* _aidl_return) override; ndk::ScopedAStatus readEnergyMeters(const std::vector& in_channelIds, std::vector* _aidl_return) override; }; diff --git a/power/stats/aidl/vts/VtsHalPowerStatsTargetTest.cpp b/power/stats/aidl/vts/VtsHalPowerStatsTargetTest.cpp index 1d3082191a..f293773383 100644 --- a/power/stats/aidl/vts/VtsHalPowerStatsTargetTest.cpp +++ b/power/stats/aidl/vts/VtsHalPowerStatsTargetTest.cpp @@ -21,10 +21,10 @@ #include #include -using aidl::android::hardware::power::stats::ChannelInfo; +using aidl::android::hardware::power::stats::Channel; using aidl::android::hardware::power::stats::EnergyMeasurement; using aidl::android::hardware::power::stats::IPowerStats; -using aidl::android::hardware::power::stats::PowerEntityInfo; +using aidl::android::hardware::power::stats::PowerEntity; using aidl::android::hardware::power::stats::StateResidencyResult; using ndk::SpAIBinder; @@ -47,70 +47,70 @@ TEST_P(PowerStatsAidl, TestReadEnergyMeter) { // Each PowerEntity must have a valid name TEST_P(PowerStatsAidl, ValidatePowerEntityNames) { - std::vector infos; + std::vector infos; ASSERT_TRUE(powerstats->getPowerEntityInfo(&infos).isOk()); for (auto info : infos) { - EXPECT_NE(info.powerEntityName, ""); + EXPECT_NE(info.name, ""); } } // Each power entity must have a unique name TEST_P(PowerStatsAidl, ValidatePowerEntityUniqueNames) { - std::vector infos; + std::vector infos; ASSERT_TRUE(powerstats->getPowerEntityInfo(&infos).isOk()); std::set names; for (auto info : infos) { - EXPECT_TRUE(names.insert(info.powerEntityName).second); + EXPECT_TRUE(names.insert(info.name).second); } } // Each PowerEntity must have a unique ID TEST_P(PowerStatsAidl, ValidatePowerEntityIds) { - std::vector infos; + std::vector infos; ASSERT_TRUE(powerstats->getPowerEntityInfo(&infos).isOk()); std::set ids; for (auto info : infos) { - EXPECT_TRUE(ids.insert(info.powerEntityId).second); + EXPECT_TRUE(ids.insert(info.id).second); } } // Each state must have a valid name TEST_P(PowerStatsAidl, ValidateStateNames) { - std::vector infos; + std::vector infos; ASSERT_TRUE(powerstats->getPowerEntityInfo(&infos).isOk()); for (auto info : infos) { for (auto state : info.states) { - EXPECT_NE(state.stateName, ""); + EXPECT_NE(state.name, ""); } } } // Each state must have a name that is unique to the given PowerEntity TEST_P(PowerStatsAidl, ValidateStateUniqueNames) { - std::vector infos; + std::vector infos; ASSERT_TRUE(powerstats->getPowerEntityInfo(&infos).isOk()); for (auto info : infos) { std::set stateNames; for (auto state : info.states) { - EXPECT_TRUE(stateNames.insert(state.stateName).second); + EXPECT_TRUE(stateNames.insert(state.name).second); } } } // Each state must have an ID that is unique to the given PowerEntity TEST_P(PowerStatsAidl, ValidateStateUniqueIds) { - std::vector infos; + std::vector infos; ASSERT_TRUE(powerstats->getPowerEntityInfo(&infos).isOk()); for (auto info : infos) { std::set stateIds; for (auto state : info.states) { - EXPECT_TRUE(stateIds.insert(state.stateId).second); + EXPECT_TRUE(stateIds.insert(state.id).second); } } } @@ -121,7 +121,7 @@ TEST_P(PowerStatsAidl, TestGetStateResidency) { } TEST_P(PowerStatsAidl, TestGetEnergyMeterInfo) { - std::vector info; + std::vector info; ASSERT_TRUE(powerstats->getEnergyMeterInfo(&info).isOk()); } -- GitLab From 0dd4124699a2b3f26f7d1e0a57edc7d1af8d1b4f Mon Sep 17 00:00:00 2001 From: Yu-Han Yang Date: Fri, 15 Jan 2021 09:23:49 -0800 Subject: [PATCH 396/790] Remove GNSS HAL v3.0 (hardware/interfaces) Bug: 170506696 Test: on cuttlefish Change-Id: I4be1755e850ac53315a50f0659f57fe35279d7bf --- .../compatibility_matrix.current.xml | 1 - gnss/3.0/Android.bp | 22 -------- gnss/3.0/IGnss.hal | 32 ------------ gnss/3.0/IGnssPsds.hal | 48 ------------------ gnss/3.0/IGnssPsdsCallback.hal | 41 --------------- gnss/3.0/default/Android.bp | 44 ---------------- gnss/3.0/default/Gnss.cpp | 32 ------------ gnss/3.0/default/Gnss.h | 42 ---------------- gnss/3.0/default/GnssPsds.cpp | 50 ------------------- gnss/3.0/default/GnssPsds.h | 50 ------------------- gnss/3.0/default/OWNERS | 4 -- .../android.hardware.gnss@3.0-service.rc | 4 -- .../android.hardware.gnss@3.0-service.xml | 13 ----- gnss/3.0/default/service.cpp | 41 --------------- gnss/3.0/vts/OWNERS | 4 -- gnss/3.0/vts/functional/Android.bp | 39 --------------- .../functional/VtsHalGnssV3_0TargetTest.cpp | 30 ----------- gnss/3.0/vts/functional/gnss_hal_test.h | 24 --------- .../vts/functional/gnss_hal_test_cases.cpp | 49 ------------------ 19 files changed, 570 deletions(-) delete mode 100644 gnss/3.0/Android.bp delete mode 100644 gnss/3.0/IGnss.hal delete mode 100644 gnss/3.0/IGnssPsds.hal delete mode 100644 gnss/3.0/IGnssPsdsCallback.hal delete mode 100644 gnss/3.0/default/Android.bp delete mode 100644 gnss/3.0/default/Gnss.cpp delete mode 100644 gnss/3.0/default/Gnss.h delete mode 100644 gnss/3.0/default/GnssPsds.cpp delete mode 100644 gnss/3.0/default/GnssPsds.h delete mode 100644 gnss/3.0/default/OWNERS delete mode 100644 gnss/3.0/default/android.hardware.gnss@3.0-service.rc delete mode 100644 gnss/3.0/default/android.hardware.gnss@3.0-service.xml delete mode 100644 gnss/3.0/default/service.cpp delete mode 100644 gnss/3.0/vts/OWNERS delete mode 100644 gnss/3.0/vts/functional/Android.bp delete mode 100644 gnss/3.0/vts/functional/VtsHalGnssV3_0TargetTest.cpp delete mode 100644 gnss/3.0/vts/functional/gnss_hal_test.h delete mode 100644 gnss/3.0/vts/functional/gnss_hal_test_cases.cpp diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index cdf72aed15..d83609512b 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -227,7 +227,6 @@ android.hardware.gnss 2.0-1 - 3.0 IGnss default diff --git a/gnss/3.0/Android.bp b/gnss/3.0/Android.bp deleted file mode 100644 index dada17ced7..0000000000 --- a/gnss/3.0/Android.bp +++ /dev/null @@ -1,22 +0,0 @@ -// This file is autogenerated by hidl-gen -Landroidbp. - -hidl_interface { - name: "android.hardware.gnss@3.0", - root: "android.hardware", - srcs: [ - "IGnss.hal", - "IGnssPsds.hal", - "IGnssPsdsCallback.hal", - ], - interfaces: [ - "android.hardware.gnss.measurement_corrections@1.0", - "android.hardware.gnss.measurement_corrections@1.1", - "android.hardware.gnss.visibility_control@1.0", - "android.hardware.gnss@1.0", - "android.hardware.gnss@1.1", - "android.hardware.gnss@2.0", - "android.hardware.gnss@2.1", - "android.hidl.base@1.0", - ], - gen_java: true, -} diff --git a/gnss/3.0/IGnss.hal b/gnss/3.0/IGnss.hal deleted file mode 100644 index 18e5a9dee3..0000000000 --- a/gnss/3.0/IGnss.hal +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.hardware.gnss@3.0; - -import @2.1::IGnss; -import IGnssPsds; - -/** - * Represents the standard GNSS (Global Navigation Satellite System) interface. - */ -interface IGnss extends @2.1::IGnss { - /** - * This method returns the IGnssPsds interface. - * - * @return psdsIface Handle to the IGnssPsds interface. - */ - getExtensionPsds() generates (IGnssPsds psdsIface); -}; diff --git a/gnss/3.0/IGnssPsds.hal b/gnss/3.0/IGnssPsds.hal deleted file mode 100644 index 5004570574..0000000000 --- a/gnss/3.0/IGnssPsds.hal +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.hardware.gnss@3.0; - -import @1.0::IGnssXtra; -import IGnssPsdsCallback; - -/** - * This interface is used by the GNSS HAL to request the framework to download Predicted Satellite - * Data Service data. - */ -interface IGnssPsds extends @1.0::IGnssXtra { - /** - * Opens the PSDS interface and provides the callback routines to the implementation of this - * interface. - * - * @param callback Handle to the IGnssPsdsCallback interface. - * - * @return success True if the operation is successful. - */ - setCallback_3_0(IGnssPsdsCallback callback) generates (bool success); - - /** - * Inject the downloaded PSDS data into the GNSS receiver. - * - * @param psdsType Type of PSDS as defined in IGnssPsdsCallback.hal - * @param psdsData GNSS PSDS data. Framework must not parse the data since the data format is - * opaque to framework. - * - * @return success True if the operation is successful. - */ - injectPsdsData_3_0(int32_t psdsType, string psdsData) generates (bool success); -}; - diff --git a/gnss/3.0/IGnssPsdsCallback.hal b/gnss/3.0/IGnssPsdsCallback.hal deleted file mode 100644 index d91385f814..0000000000 --- a/gnss/3.0/IGnssPsdsCallback.hal +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.hardware.gnss@3.0; - -import @1.0::IGnssXtraCallback; - -/** - * This interface is used by the GNSS HAL to request download data from Predicted Satellite Data - * Service (PSDS). - */ -interface IGnssPsdsCallback extends @1.0::IGnssXtraCallback { - /** - * Callback to request the client to download PSDS data. The client should - * download PSDS data and inject it by calling injectPsdsData(). - * - * psdsType represents the type of PSDS data requested. - * - Value 1 represents the Long-Term type PSDS data, which lasts for many hours to several days - * and often provides satellite orbit and clock accuracy of 2 - 20 meters. - * - Value 2 represents the Normal type PSDS data, which is similar to broadcast ephemeris in - * longevity - lasting for hours and providings satellite orbit and clock accuracy of 1 - 2 - * meters. - * - Value 3 represents the Real-Time type PSDS data, which lasts for minutes and provides brief - * satellite status information such as temporary malfunction, but does not include satellite - * orbit or clock information. - */ - downloadRequestCb_3_0(int32_t psdsType); -}; diff --git a/gnss/3.0/default/Android.bp b/gnss/3.0/default/Android.bp deleted file mode 100644 index bb3c467923..0000000000 --- a/gnss/3.0/default/Android.bp +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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. - */ - -cc_binary { - name: "android.hardware.gnss@3.0-service", - init_rc: ["android.hardware.gnss@3.0-service.rc"], - relative_install_path: "hw", - vendor: true, - vintf_fragments: ["android.hardware.gnss@3.0-service.xml"], - srcs: [ - "Gnss.cpp", - "GnssPsds.cpp", - "service.cpp", - ], - shared_libs: [ - "libhidlbase", - "libutils", - "liblog", - "android.hardware.gnss@1.0", - "android.hardware.gnss@1.1", - "android.hardware.gnss@2.0", - "android.hardware.gnss@2.1", - "android.hardware.gnss@3.0", - "android.hardware.gnss.measurement_corrections@1.1", - "android.hardware.gnss.measurement_corrections@1.0", - "android.hardware.gnss-ndk_platform", - ], - static_libs: [ - "android.hardware.gnss@common-default-lib", - ], -} diff --git a/gnss/3.0/default/Gnss.cpp b/gnss/3.0/default/Gnss.cpp deleted file mode 100644 index 5f2ca4f522..0000000000 --- a/gnss/3.0/default/Gnss.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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 "Gnss" - -#include "Gnss.h" -#include -#include "GnssPsds.h" -#include "Utils.h" - -namespace android::hardware::gnss::V3_0::implementation { - -// Methods from V3_0::IGnss follow. -Return> Gnss::getExtensionPsds() { - ALOGD("Gnss::getExtensionPsds"); - return new GnssPsds(); -} - -} // namespace android::hardware::gnss::V3_0::implementation diff --git a/gnss/3.0/default/Gnss.h b/gnss/3.0/default/Gnss.h deleted file mode 100644 index 7ae562ade3..0000000000 --- a/gnss/3.0/default/Gnss.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include -#include -#include -#include -#include -#include -#include "v2_1/GnssTemplate.h" - -namespace android::hardware::gnss::V3_0::implementation { - -using ::android::sp; -using ::android::hardware::Return; -using ::android::hardware::Void; -using ::android::hardware::gnss::common::implementation::GnssTemplate; - -struct Gnss : public GnssTemplate { - Gnss(){}; - ~Gnss(){}; - - // Methods from V3_0::IGnss follow. - Return> getExtensionPsds() override; -}; - -} // namespace android::hardware::gnss::V3_0::implementation diff --git a/gnss/3.0/default/GnssPsds.cpp b/gnss/3.0/default/GnssPsds.cpp deleted file mode 100644 index 44e096ebd3..0000000000 --- a/gnss/3.0/default/GnssPsds.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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 "GnssPsds" - -#include "GnssPsds.h" - -#include - -namespace android::hardware::gnss::V3_0::implementation { - -sp GnssPsds::sCallback_3_0 = nullptr; - -// Methods from V1_0::IGnssXtra follow. -Return GnssPsds::setCallback(const sp&) { - // TODO implement - return bool{}; -} - -Return GnssPsds::injectXtraData(const hidl_string&) { - // TODO implement - return bool{}; -} - -// Methods from V3_0::IGnssPsds follow. -Return GnssPsds::setCallback_3_0(const sp& callback) { - ALOGD("setCallback_3_0"); - std::unique_lock lock(mMutex); - sCallback_3_0 = callback; - return true; -} - -Return GnssPsds::injectPsdsData_3_0(int32_t psdsType, const hidl_string& psdsData) { - ALOGD("injectPsdsData_3_0. psdsType: %d, psdsData: %s", psdsType, psdsData.c_str()); - return true; -} -} // namespace android::hardware::gnss::V3_0::implementation diff --git a/gnss/3.0/default/GnssPsds.h b/gnss/3.0/default/GnssPsds.h deleted file mode 100644 index 4053bf17c8..0000000000 --- a/gnss/3.0/default/GnssPsds.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include -#include -#include - -namespace android::hardware::gnss::V3_0::implementation { - -using ::android::sp; -using ::android::hardware::hidl_array; -using ::android::hardware::hidl_memory; -using ::android::hardware::hidl_string; -using ::android::hardware::hidl_vec; -using ::android::hardware::Return; -using ::android::hardware::Void; - -struct GnssPsds : public V3_0::IGnssPsds { - // Methods from V1_0::IGnssXtra follow. - Return setCallback(const sp& callback) override; - Return injectXtraData(const hidl_string& xtraData) override; - - // Methods from V3_0::IGnssPsds follow. - Return setCallback_3_0(const sp& callback) override; - Return injectPsdsData_3_0(int32_t psdsType, const hidl_string& psdsData) override; - - private: - // Guarded by mMutex - static sp sCallback_3_0; - - // Synchronization lock for sCallback_3_0 - mutable std::mutex mMutex; -}; - -} // namespace android::hardware::gnss::V3_0::implementation diff --git a/gnss/3.0/default/OWNERS b/gnss/3.0/default/OWNERS deleted file mode 100644 index b7b4a2e902..0000000000 --- a/gnss/3.0/default/OWNERS +++ /dev/null @@ -1,4 +0,0 @@ -gomo@google.com -smalkos@google.com -wyattriley@google.com -yuhany@google.com diff --git a/gnss/3.0/default/android.hardware.gnss@3.0-service.rc b/gnss/3.0/default/android.hardware.gnss@3.0-service.rc deleted file mode 100644 index c2bfb91e22..0000000000 --- a/gnss/3.0/default/android.hardware.gnss@3.0-service.rc +++ /dev/null @@ -1,4 +0,0 @@ -service vendor.gnss-3-0 /vendor/bin/hw/android.hardware.gnss@3.0-service - class hal - user system - group system diff --git a/gnss/3.0/default/android.hardware.gnss@3.0-service.xml b/gnss/3.0/default/android.hardware.gnss@3.0-service.xml deleted file mode 100644 index 6709e0c3b5..0000000000 --- a/gnss/3.0/default/android.hardware.gnss@3.0-service.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - android.hardware.gnss - hwbinder - 3.0 - 2.1 - 1.1 - - IGnss - default - - - diff --git a/gnss/3.0/default/service.cpp b/gnss/3.0/default/service.cpp deleted file mode 100644 index 87b458070b..0000000000 --- a/gnss/3.0/default/service.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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 "android.hardware.gnss@3.0-service" - -#include -#include -#include "Gnss.h" - -using ::android::OK; -using ::android::sp; -using ::android::hardware::configureRpcThreadpool; -using ::android::hardware::joinRpcThreadpool; -using ::android::hardware::gnss::V3_0::IGnss; -using ::android::hardware::gnss::V3_0::implementation::Gnss; - -int main(int /* argc */, char* /* argv */[]) { - sp gnss = new Gnss(); - configureRpcThreadpool(1, true /* will join */); - if (gnss->registerAsService() != OK) { - ALOGE("Could not register gnss 3.0 service."); - return 1; - } - joinRpcThreadpool(); - - ALOGE("Service exited!"); - return 1; -} \ No newline at end of file diff --git a/gnss/3.0/vts/OWNERS b/gnss/3.0/vts/OWNERS deleted file mode 100644 index b7b4a2e902..0000000000 --- a/gnss/3.0/vts/OWNERS +++ /dev/null @@ -1,4 +0,0 @@ -gomo@google.com -smalkos@google.com -wyattriley@google.com -yuhany@google.com diff --git a/gnss/3.0/vts/functional/Android.bp b/gnss/3.0/vts/functional/Android.bp deleted file mode 100644 index 584424ccc4..0000000000 --- a/gnss/3.0/vts/functional/Android.bp +++ /dev/null @@ -1,39 +0,0 @@ -// -// 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. -// - -cc_test { - name: "VtsHalGnssV3_0TargetTest", - defaults: ["VtsHalTargetTestDefaults"], - srcs: [ - "gnss_hal_test_cases.cpp", - "VtsHalGnssV3_0TargetTest.cpp", - ], - static_libs: [ - "android.hardware.gnss.measurement_corrections@1.0", - "android.hardware.gnss.measurement_corrections@1.1", - "android.hardware.gnss.visibility_control@1.0", - "android.hardware.gnss@1.0", - "android.hardware.gnss@1.1", - "android.hardware.gnss@2.0", - "android.hardware.gnss@2.1", - "android.hardware.gnss@3.0", - "android.hardware.gnss@common-vts-lib", - ], - test_suites: [ - "general-tests", - "vts", - ], -} diff --git a/gnss/3.0/vts/functional/VtsHalGnssV3_0TargetTest.cpp b/gnss/3.0/vts/functional/VtsHalGnssV3_0TargetTest.cpp deleted file mode 100644 index 31e6164f9e..0000000000 --- a/gnss/3.0/vts/functional/VtsHalGnssV3_0TargetTest.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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 "VtsHalGnssV3_0TargetTest" - -#include -#include -#include - -#include "gnss_hal_test.h" - -using android::hardware::gnss::V3_0::IGnss; - -GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GnssHalTest); -INSTANTIATE_TEST_SUITE_P( - PerInstance, GnssHalTest, - testing::ValuesIn(android::hardware::getAllHalInstanceNames(IGnss::descriptor)), - android::hardware::PrintInstanceNameToString); \ No newline at end of file diff --git a/gnss/3.0/vts/functional/gnss_hal_test.h b/gnss/3.0/vts/functional/gnss_hal_test.h deleted file mode 100644 index be6d38cfac..0000000000 --- a/gnss/3.0/vts/functional/gnss_hal_test.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include -#include "v2_1/gnss_hal_test_template.h" - -// The main test class for GNSS HAL. -class GnssHalTest : public android::hardware::gnss::common::GnssHalTestTemplate< - android::hardware::gnss::V3_0::IGnss> {}; \ No newline at end of file diff --git a/gnss/3.0/vts/functional/gnss_hal_test_cases.cpp b/gnss/3.0/vts/functional/gnss_hal_test_cases.cpp deleted file mode 100644 index cc5341c181..0000000000 --- a/gnss/3.0/vts/functional/gnss_hal_test_cases.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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 "GnssHalTestCases" - -#include -#include -#include "Utils.h" - -#include - -using android::hardware::hidl_string; -using android::hardware::hidl_vec; - -using android::hardware::gnss::common::Utils; - -using android::hardware::gnss::V3_0::IGnssPsds; - -/* - * SetupTeardownCreateCleanup: - * Requests the gnss HAL then calls cleanup - * - * Empty test fixture to verify basic Setup & Teardown - */ -TEST_P(GnssHalTest, SetupTeardownCreateCleanup) {} - -/* - * TestPsdsExtension: - * Gets the PsdsExtension and verifies that it returns a non-null extension. - */ -TEST_P(GnssHalTest, TestPsdsExtension) { - auto psds = gnss_hal_->getExtensionPsds(); - ASSERT_TRUE(psds.isOk()); - sp iPsds = psds; - ASSERT_TRUE(iPsds != nullptr); -} -- GitLab From 330dae0264682eacaf7a1991255b18a8de44da3c Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Tue, 29 Dec 2020 14:41:23 -0800 Subject: [PATCH 397/790] Update the enrollment API Bug: 174619156 Test: m android.hardware.biometrics.face-update-api Change-Id: I4683ef3217a3053363cae460a961a75d90cf2e51 --- .../biometrics/face/AuthenticationFrame.aidl | 23 +++++++ .../hardware/biometrics/face/BaseFrame.aidl | 28 ++++++++ .../hardware/biometrics/face/Cell.aidl | 25 +++++++ .../biometrics/face/EnrollmentFrame.aidl | 25 +++++++ .../biometrics/face/EnrollmentStage.aidl | 28 ++++++++ .../face/EnrollmentStageConfig.aidl | 24 +++++++ .../biometrics/face/EnrollmentType.aidl | 24 +++++++ .../hardware/biometrics/face/ISession.aidl | 2 +- .../biometrics/face/ISessionCallback.aidl | 3 +- .../biometrics/face/AcquiredInfo.aidl | 2 +- .../biometrics/face/AuthenticationFrame.aidl | 31 +++++++++ .../hardware/biometrics/face/BaseFrame.aidl | 68 +++++++++++++++++++ .../hardware/biometrics/face/Cell.aidl | 27 ++++++++ .../biometrics/face/EnrollmentFrame.aidl | 42 ++++++++++++ .../biometrics/face/EnrollmentStage.aidl | 55 +++++++++++++++ .../face/EnrollmentStageConfig.aidl | 33 +++++++++ .../biometrics/face/EnrollmentType.aidl | 24 +++++++ .../hardware/biometrics/face/Error.aidl | 2 +- .../biometrics/face/FaceSensorType.aidl | 2 +- .../hardware/biometrics/face/IFace.aidl | 2 +- .../hardware/biometrics/face/ISession.aidl | 19 +++++- .../biometrics/face/ISessionCallback.aidl | 28 +++++--- .../hardware/biometrics/face/SensorProps.aidl | 2 +- .../biometrics/face/SessionState.aidl | 2 +- 24 files changed, 501 insertions(+), 20 deletions(-) create mode 100644 biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AuthenticationFrame.aidl create mode 100644 biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/BaseFrame.aidl create mode 100644 biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Cell.aidl create mode 100644 biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentFrame.aidl create mode 100644 biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStage.aidl create mode 100644 biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStageConfig.aidl create mode 100644 biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentType.aidl create mode 100644 biometrics/face/aidl/android/hardware/biometrics/face/AuthenticationFrame.aidl create mode 100644 biometrics/face/aidl/android/hardware/biometrics/face/BaseFrame.aidl create mode 100644 biometrics/face/aidl/android/hardware/biometrics/face/Cell.aidl create mode 100644 biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentFrame.aidl create mode 100644 biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentStage.aidl create mode 100644 biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentStageConfig.aidl create mode 100644 biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentType.aidl diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AuthenticationFrame.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AuthenticationFrame.aidl new file mode 100644 index 0000000000..3043000f39 --- /dev/null +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AuthenticationFrame.aidl @@ -0,0 +1,23 @@ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.face; +@VintfStability +parcelable AuthenticationFrame { + android.hardware.biometrics.face.BaseFrame data; +} diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/BaseFrame.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/BaseFrame.aidl new file mode 100644 index 0000000000..27821e3ece --- /dev/null +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/BaseFrame.aidl @@ -0,0 +1,28 @@ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.face; +@VintfStability +parcelable BaseFrame { + android.hardware.biometrics.face.AcquiredInfo acquiredInfo; + int vendorCode; + float pan; + float tilt; + float distance; + boolean isCancellable; +} diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Cell.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Cell.aidl new file mode 100644 index 0000000000..17c1ba3695 --- /dev/null +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Cell.aidl @@ -0,0 +1,25 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -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.face; +@VintfStability +parcelable Cell { + int x; + int y; + int z; +} diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentFrame.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentFrame.aidl new file mode 100644 index 0000000000..c736e7e743 --- /dev/null +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentFrame.aidl @@ -0,0 +1,25 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -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.face; +@VintfStability +parcelable EnrollmentFrame { + @nullable android.hardware.biometrics.face.Cell cell; + android.hardware.biometrics.face.EnrollmentStage stage; + android.hardware.biometrics.face.BaseFrame data; +} diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStage.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStage.aidl new file mode 100644 index 0000000000..af6be9061a --- /dev/null +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStage.aidl @@ -0,0 +1,28 @@ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.face; +@Backing(type="byte") @VintfStability +enum EnrollmentStage { + FIRST_FRAME_RECEIVED = 0, + WAITING_FOR_CENTERING = 1, + HOLD_STILL_IN_CENTER = 2, + ENROLLING_MOVEMENT_1 = 3, + ENROLLING_MOVEMENT_2 = 4, + ENROLLMENT_FINISHED = 5, +} diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStageConfig.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStageConfig.aidl new file mode 100644 index 0000000000..268ce52e46 --- /dev/null +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStageConfig.aidl @@ -0,0 +1,24 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -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.face; +@VintfStability +parcelable EnrollmentStageConfig { + android.hardware.biometrics.face.EnrollmentStage stage; + List cells; +} diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentType.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentType.aidl new file mode 100644 index 0000000000..7295b3b4ee --- /dev/null +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentType.aidl @@ -0,0 +1,24 @@ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -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.face; +@Backing(type="byte") @VintfStability +enum EnrollmentType { + DEFAULT = 0, + ACCESSIBILITY = 1, +} 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 7d70971479..203e2752b8 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 @@ -21,7 +21,7 @@ package android.hardware.biometrics.face; interface ISession { void generateChallenge(in int cookie, in int timeoutSec); void revokeChallenge(in int cookie, in long challenge); - android.hardware.biometrics.common.ICancellationSignal enroll(in int cookie, in android.hardware.keymaster.HardwareAuthToken hat, in android.hardware.common.NativeHandle previewSurface); + android.hardware.biometrics.common.ICancellationSignal enroll(in int cookie, in android.hardware.biometrics.face.EnrollmentType enrollmentType, in android.hardware.keymaster.HardwareAuthToken hat, in android.hardware.common.NativeHandle previewSurface); android.hardware.biometrics.common.ICancellationSignal authenticate(in int cookie, in long operationId); android.hardware.biometrics.common.ICancellationSignal detectInteraction(in int cookie); void enumerateEnrollments(in int cookie); diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl index 4cea0f0d99..a81c79a42b 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl @@ -22,7 +22,8 @@ interface ISessionCallback { void onStateChanged(in int cookie, in android.hardware.biometrics.face.SessionState state); void onChallengeGenerated(in long challenge); void onChallengeRevoked(in long challenge); - void onAcquired(in android.hardware.biometrics.face.AcquiredInfo info, in int vendorCode); + void onAuthenticationFrame(in android.hardware.biometrics.face.AuthenticationFrame frame); + void onEnrollmentFrame(in android.hardware.biometrics.face.EnrollmentFrame frame); void onError(in android.hardware.biometrics.face.Error error, in int vendorCode); void onEnrollmentProgress(in int enrollmentId, int remaining); void onAuthenticationSucceeded(in int enrollmentId, in android.hardware.keymaster.HardwareAuthToken hat); diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl index 56a600f824..217a9bbfb1 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.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. diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/AuthenticationFrame.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/AuthenticationFrame.aidl new file mode 100644 index 0000000000..47cad3c61d --- /dev/null +++ b/biometrics/face/aidl/android/hardware/biometrics/face/AuthenticationFrame.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.biometrics.face; + +import android.hardware.biometrics.face.BaseFrame; + +/** + * Describes an individual frame captured during authentication. + */ +@VintfStability +parcelable AuthenticationFrame { + + /** + * The frame metadata. Can be used by the framework to provide user feedback. + */ + BaseFrame data; +} diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/BaseFrame.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/BaseFrame.aidl new file mode 100644 index 0000000000..9e6b98adfa --- /dev/null +++ b/biometrics/face/aidl/android/hardware/biometrics/face/BaseFrame.aidl @@ -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. + */ + +package android.hardware.biometrics.face; + +import android.hardware.biometrics.face.AcquiredInfo; + +/** + * Metadata of an individual frame. Can be used by the framework to provide user feedback. + * This parcelable is part of AuthenticationFrame and EnrollmentFrame, and shouldn't be used + * independently of those parcelables. + */ +@VintfStability +parcelable BaseFrame { + /** + * Information about the frame that can be used by the framework to provide feedback to the + * user, for example ask the user to move their face in a certain way. + */ + AcquiredInfo acquiredInfo; + + /** + * If acquiredInfo is set to AcquiredInfo::VENDOR. This is the index into the configuration + * "com.android.internal.R.array.face_acquired_vendor" that's installed on the vendor partition. + * Otherwise, this value must be ignored. + */ + int vendorCode; + + /** + * Pan value. It is recommended to use the range of [-1, 1] to represent valid values, and + * anything outside of that range to represent errors. However, vendors are free to define + * their own way of representing valid values and errors. + */ + float pan; + + /** + * Tilt value. It is recommended to use the range of [-1, 1] to represent valid values, and + * anything outside of that range to represent errors. However, vendors are free to define + * their own way of representing valid values and errors. + */ + float tilt; + + /** + * Distance value. It is recommended to use the range of [-1, 1] to represent valid values, and + * anything outside of that range to represent errors. However, vendors are free to define + * their own way of representing valid values and errors. + */ + float distance; + + /** + * Indicates that the HAL can no longer continue with authentication or enrollment. This allows + * the framework to correlate a failure condition with a particular AcquiredInfo, rather than + * having a sequence of AcquiredInfo + Error. + */ + boolean isCancellable; +} diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/Cell.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/Cell.aidl new file mode 100644 index 0000000000..77f33b96f3 --- /dev/null +++ b/biometrics/face/aidl/android/hardware/biometrics/face/Cell.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.biometrics.face; + +/** + * Coordinates of an enrollment UI cell in a vendor-defined coordinate system. + */ +@VintfStability +parcelable Cell { + int x; + int y; + int z; +} diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentFrame.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentFrame.aidl new file mode 100644 index 0000000000..d4f9771d03 --- /dev/null +++ b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentFrame.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. + */ + +package android.hardware.biometrics.face; + +import android.hardware.biometrics.face.Cell; +import android.hardware.biometrics.face.EnrollmentStage; +import android.hardware.biometrics.face.BaseFrame; + +/** + * Describes an individual frame captured during enrollment. + */ +@VintfStability +parcelable EnrollmentFrame { + /** + * The enrollment UI cell that was captured in this frame, or null if no cell was captured. + */ + @nullable Cell cell; + + /** + * The enrollment stage for which this frame was captured. + */ + EnrollmentStage stage; + + /** + * The frame metadata. Can be used by the framework to provide user feedback. + */ + BaseFrame data; +} diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentStage.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentStage.aidl new file mode 100644 index 0000000000..bbc874fb0c --- /dev/null +++ b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentStage.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.biometrics.face; + +/** + * Enrollment stages that can be mapped to the enrollment UI actions in the framework. + */ +@VintfStability +@Backing(type="byte") +enum EnrollmentStage { + + /** + * HAL has obtained the first camera frame. + */ + FIRST_FRAME_RECEIVED, + + /** + * HAL is waiting for the user's face to be centered. + */ + WAITING_FOR_CENTERING, + + /** + * HAL is expecting the user's face to stay centered. + */ + HOLD_STILL_IN_CENTER, + + /** + * Vendor defined movement 1. + */ + ENROLLING_MOVEMENT_1, + + /** + * Vendor defined movement 2. + */ + ENROLLING_MOVEMENT_2, + + /** + * HAL has finished the enrollment. + */ + ENROLLMENT_FINISHED, +} diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentStageConfig.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentStageConfig.aidl new file mode 100644 index 0000000000..0b64e2bfbd --- /dev/null +++ b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentStageConfig.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.biometrics.face; + +import android.hardware.biometrics.face.Cell; +import android.hardware.biometrics.face.EnrollmentStage; + +@VintfStability +parcelable EnrollmentStageConfig { + /** + * The stage that's being configured. + */ + EnrollmentStage stage; + + /** + * Optional list of cells that must be completed to finish this stage. + */ + List cells; +} diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentType.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentType.aidl new file mode 100644 index 0000000000..d7f31756bc --- /dev/null +++ b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentType.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.biometrics.face; + +@VintfStability +@Backing(type="byte") +enum EnrollmentType { + DEFAULT, + ACCESSIBILITY, +} diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/Error.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/Error.aidl index 1d02456f6d..d88370f129 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/Error.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/Error.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. diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/FaceSensorType.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/FaceSensorType.aidl index 766f732a56..2a5dd20be1 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/FaceSensorType.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/FaceSensorType.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. diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/IFace.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/IFace.aidl index e9a66e2ea3..f9ed4b1701 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/IFace.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/IFace.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. diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl index 425b3525eb..34a1f8b5a9 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.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. @@ -17,6 +17,7 @@ package android.hardware.biometrics.face; import android.hardware.biometrics.common.ICancellationSignal; +import android.hardware.biometrics.face.EnrollmentType; import android.hardware.keymaster.HardwareAuthToken; import android.hardware.common.NativeHandle; @@ -84,6 +85,18 @@ interface ISession { */ void revokeChallenge(in int cookie, in long challenge); + /** + * getEnrollmentConfig: + * + * Returns the enrollment configuration depending on the provided enrollment type. Enrollment + * configuration determines how many stages the enrollment will have and the requirements for + * each of the stages. + * + * @param enrollmentType See the EnrollmentType enum. + * @return A list of EnrollmentStageConfig that describes each enrollment stage. + * + List getEnrollmentConfig(in EnrollmentType enrollmentType); + /** * enroll: * @@ -118,6 +131,7 @@ interface ISession { * * @param cookie An identifier used to track subsystem operations related to this call path. The * client must guarantee that it is unique per ISession. + * @param enrollmentType See the EnrollmentType enum. * @param previewSurface A surface provided by the framework if SensorProps#halControlsPreview is * set to true. The HAL must send the preview frames to previewSurface if * it's not null. @@ -125,7 +139,8 @@ interface ISession { * @return ICancellationSignal An object that can be used by the framework to cancel this * operation. */ - ICancellationSignal enroll(in int cookie, in HardwareAuthToken hat, in NativeHandle previewSurface); + ICancellationSignal enroll(in int cookie, in EnrollmentType enrollmentType, + in HardwareAuthToken hat, in NativeHandle previewSurface); /** * authenticate: diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl index d59ce2e349..9178e3aa7b 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.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. @@ -17,6 +17,8 @@ package android.hardware.biometrics.face; import android.hardware.biometrics.face.AcquiredInfo; +import android.hardware.biometrics.face.AuthenticationFrame; +import android.hardware.biometrics.face.EnrollmentFrame; import android.hardware.biometrics.face.Error; import android.hardware.biometrics.face.SessionState; import android.hardware.keymaster.HardwareAuthToken; @@ -40,20 +42,26 @@ interface ISessionCallback { /** * This method must only be used to notify the framework during the following states: - * 1) SessionState::ENROLLING - * 2) SessionState::AUTHENTICATING - * 3) SessionState::DETECTING_INTERACTION + * 1) SessionState::AUTHENTICATING + * 2) SessionState::DETECTING_INTERACTION + * + * These messages may be used to provide user guidance multiple times if necessary per + * operation. + * + * @param frame See the AuthenticationFrame enum. + */ + void onAuthenticationFrame(in AuthenticationFrame frame); + + /** + * This method must only be used to notify the framework during the SessionState::ENROLLING + * state. * * These messages may be used to provide user guidance multiple times if necessary per * operation. * - * @param info See the AcquiredInfo enum. - * @param vendorCode Only valid if info == AcquiredInfo::VENDOR. The vendorCode must be used to - * index into the configuration - * com.android.internal.R.array.face_acquired_vendor that's installed - * on the vendor partition. + * @param frame See the EnrollmentFrame enum. */ - void onAcquired(in AcquiredInfo info, in int vendorCode); + void onEnrollmentFrame(in EnrollmentFrame frame); /** * This method must only be used to notify the framework during the following states: diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl index 9c2f9a1734..335f2f9e52 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.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. diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/SessionState.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/SessionState.aidl index 1878f7c823..e56f5d84fc 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/SessionState.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/SessionState.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. -- GitLab From af30cdeca5e60833d807e021f87c4664f01198c1 Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Fri, 8 Jan 2021 09:42:50 -0800 Subject: [PATCH 398/790] Update the default implementation Bug: 174619156 Test: atest VtsHalBiometricsFaceTargetTest Change-Id: Ibfa8ace1205ba500a865e09218f4fdc69eb6d8fb --- biometrics/face/aidl/default/Session.cpp | 16 +++++++++------- biometrics/face/aidl/default/Session.h | 6 +++--- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/biometrics/face/aidl/default/Session.cpp b/biometrics/face/aidl/default/Session.cpp index c5d7d23ecb..df5187955f 100644 --- a/biometrics/face/aidl/default/Session.cpp +++ b/biometrics/face/aidl/default/Session.cpp @@ -23,6 +23,7 @@ namespace aidl::android::hardware::biometrics::face { class CancellationSignal : public common::BnCancellationSignal { private: std::shared_ptr cb_; + public: explicit CancellationSignal(std::shared_ptr cb) : cb_(std::move(cb)) {} @@ -53,10 +54,10 @@ ndk::ScopedAStatus Session::revokeChallenge(int32_t /*cookie*/, int64_t challeng return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::enroll(int32_t /*cookie*/, const keymaster::HardwareAuthToken& /*hat*/, - const NativeHandle& /*previewSurface*/, - std::shared_ptr* - /*returnVal*/) { +ndk::ScopedAStatus Session::enroll( + int32_t /*cookie*/, biometrics::face::EnrollmentType /*enrollmentType*/, + const keymaster::HardwareAuthToken& /*hat*/, const NativeHandle& /*previewSurface*/, + std::shared_ptr* /*return_val*/) { return ndk::ScopedAStatus::ok(); } @@ -86,9 +87,9 @@ ndk::ScopedAStatus Session::enumerateEnrollments(int32_t /*cookie*/) { ndk::ScopedAStatus Session::removeEnrollments(int32_t /*cookie*/, const std::vector& /*enrollmentIds*/) { if (cb_) { - cb_->onStateChanged(0, SessionState::REMOVING_ENROLLMENTS); - cb_->onEnrollmentsRemoved(std::vector()); - cb_->onStateChanged(0, SessionState::IDLING); + cb_->onStateChanged(0, SessionState::REMOVING_ENROLLMENTS); + cb_->onEnrollmentsRemoved(std::vector()); + cb_->onStateChanged(0, SessionState::IDLING); } return ndk::ScopedAStatus::ok(); } @@ -115,4 +116,5 @@ ndk::ScopedAStatus Session::resetLockout(int32_t /*cookie*/, } return ndk::ScopedAStatus::ok(); } + } // namespace aidl::android::hardware::biometrics::face diff --git a/biometrics/face/aidl/default/Session.h b/biometrics/face/aidl/default/Session.h index 2bb5c42a99..347d2020fc 100644 --- a/biometrics/face/aidl/default/Session.h +++ b/biometrics/face/aidl/default/Session.h @@ -35,9 +35,9 @@ class Session : public BnSession { ndk::ScopedAStatus revokeChallenge(int32_t cookie, int64_t challenge) override; ndk::ScopedAStatus enroll( - int32_t cookie, const keymaster::HardwareAuthToken& hat, - const NativeHandle& previewSurface, - std::shared_ptr* returnVal) override; + int32_t cookie, biometrics::face::EnrollmentType enrollmentType, + const keymaster::HardwareAuthToken& hat, const NativeHandle& previewSurface, + std::shared_ptr* return_val) override; ndk::ScopedAStatus authenticate( int32_t cookie, int64_t keystoreOperationId, -- GitLab From e13bc8109f1554d095933a2a202939c1031ee83e Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Tue, 19 Jan 2021 16:04:04 -0800 Subject: [PATCH 399/790] Update the VTS test Bug: 174619156 Test: atest VtsHalBiometricsFaceTargetTest Change-Id: I908789c3a6c9b0682d13ffff53cf70163a929abf --- biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp b/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp index f6d0aab44e..5b02a57ce8 100644 --- a/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp +++ b/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp @@ -59,7 +59,11 @@ class SessionCallback : public BnSessionCallback { return ndk::ScopedAStatus::ok(); } - ndk::ScopedAStatus onAcquired(AcquiredInfo /*info*/, int32_t /*vendorCode*/) override { + ndk::ScopedAStatus onAuthenticationFrame(const AuthenticationFrame& /*frame*/) override { + return ndk::ScopedAStatus::ok(); + } + + ndk::ScopedAStatus onEnrollmentFrame(const EnrollmentFrame& /*frame*/) override { return ndk::ScopedAStatus::ok(); } -- GitLab From a0177a056608c116a21525b97b05af5c9d06c8a7 Mon Sep 17 00:00:00 2001 From: Kuowei Li Date: Wed, 19 Aug 2020 15:56:29 +0800 Subject: [PATCH 400/790] audio: add implementation for TV related API 1. AudioDescriptionMixLevel getter/setter. 2. DualMonoMode getter/setter. 3. PlaybackRate getter/setter. Test: TIS player with instrumented HAL Test: atest AudioTrackTest#testTunerConfiguration Test: atest AudioTrackTest#testDualMonoMode Test: atest AudioTrackTest#testAudioDescriptionMixLevel Test: atest AudioManagerTest#testGetAdditionalOutputDeviceDelay Bug: 173482792 Change-Id: I7e4f14387b45a5387ba2c4e8797edf18f373b936 --- audio/core/all-versions/default/StreamOut.cpp | 55 +++++++++++++++---- 1 file changed, 44 insertions(+), 11 deletions(-) diff --git a/audio/core/all-versions/default/StreamOut.cpp b/audio/core/all-versions/default/StreamOut.cpp index 357fd941bd..b5ddba036e 100644 --- a/audio/core/all-versions/default/StreamOut.cpp +++ b/audio/core/all-versions/default/StreamOut.cpp @@ -658,32 +658,65 @@ Return StreamOut::selectPresentation(int32_t /*presentationId*/, int32_t #if MAJOR_VERSION >= 6 Return StreamOut::getDualMonoMode(getDualMonoMode_cb _hidl_cb) { - _hidl_cb(Result::NOT_SUPPORTED, DualMonoMode::OFF); + audio_dual_mono_mode_t mode = AUDIO_DUAL_MONO_MODE_OFF; + Result retval = mStream->get_dual_mono_mode != nullptr + ? Stream::analyzeStatus("get_dual_mono_mode", + mStream->get_dual_mono_mode(mStream, &mode)) + : Result::NOT_SUPPORTED; + _hidl_cb(retval, DualMonoMode(mode)); return Void(); } -Return StreamOut::setDualMonoMode(DualMonoMode /*mode*/) { - return Result::NOT_SUPPORTED; +Return StreamOut::setDualMonoMode(DualMonoMode mode) { + return mStream->set_dual_mono_mode != nullptr + ? Stream::analyzeStatus( + "set_dual_mono_mode", + mStream->set_dual_mono_mode(mStream, + static_cast(mode))) + : Result::NOT_SUPPORTED; } Return StreamOut::getAudioDescriptionMixLevel(getAudioDescriptionMixLevel_cb _hidl_cb) { - _hidl_cb(Result::NOT_SUPPORTED, -std::numeric_limits::infinity()); + float leveldB = -std::numeric_limits::infinity(); + Result retval = mStream->get_audio_description_mix_level != nullptr + ? Stream::analyzeStatus( + "get_audio_description_mix_level", + mStream->get_audio_description_mix_level(mStream, &leveldB)) + : Result::NOT_SUPPORTED; + _hidl_cb(retval, leveldB); return Void(); } -Return StreamOut::setAudioDescriptionMixLevel(float /*leveldB*/) { - return Result::NOT_SUPPORTED; +Return StreamOut::setAudioDescriptionMixLevel(float leveldB) { + return mStream->set_audio_description_mix_level != nullptr + ? Stream::analyzeStatus( + "set_audio_description_mix_level", + mStream->set_audio_description_mix_level(mStream, leveldB)) + : Result::NOT_SUPPORTED; } Return StreamOut::getPlaybackRateParameters(getPlaybackRateParameters_cb _hidl_cb) { - _hidl_cb(Result::NOT_SUPPORTED, - // Same as AUDIO_PLAYBACK_RATE_INITIALIZER - PlaybackRate{1.0f, 1.0f, TimestretchMode::DEFAULT, TimestretchFallbackMode::FAIL}); + audio_playback_rate_t rate = AUDIO_PLAYBACK_RATE_INITIALIZER; + Result retval = + mStream->get_playback_rate_parameters != nullptr + ? Stream::analyzeStatus("get_playback_rate_parameters", + mStream->get_playback_rate_parameters(mStream, &rate)) + : Result::NOT_SUPPORTED; + _hidl_cb(retval, + PlaybackRate{rate.mSpeed, rate.mPitch, static_cast(rate.mStretchMode), + static_cast(rate.mFallbackMode)}); return Void(); } -Return StreamOut::setPlaybackRateParameters(const PlaybackRate& /*playbackRate*/) { - return Result::NOT_SUPPORTED; +Return StreamOut::setPlaybackRateParameters(const PlaybackRate& playbackRate) { + audio_playback_rate_t rate = { + playbackRate.speed, playbackRate.pitch, + static_cast(playbackRate.timestretchMode), + static_cast(playbackRate.fallbackMode)}; + return mStream->set_playback_rate_parameters != nullptr + ? Stream::analyzeStatus("set_playback_rate_parameters", + mStream->set_playback_rate_parameters(mStream, &rate)) + : Result::NOT_SUPPORTED; } Return StreamOut::setEventCallback(const sp& callback) { -- GitLab From 0d4ace0138ecaa769e3c6c08e700f5d4a6015454 Mon Sep 17 00:00:00 2001 From: Kevin Chyn Date: Thu, 21 Jan 2021 16:42:46 -0800 Subject: [PATCH 401/790] Add TOO_DARK and TOO_BRIGHT to AcquiredInfo Fixes: 169186958 Test: make -j android.hardware.biometrics.fingerprint-update-api Change-Id: If12088b65b4defe5c83fed2f118d437075789632 --- .../biometrics/fingerprint/AcquiredInfo.aidl | 2 ++ .../biometrics/fingerprint/AcquiredInfo.aidl | 12 ++++++++++++ 2 files changed, 14 insertions(+) diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl index d5f2ed27c6..7d8c034984 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl @@ -27,4 +27,6 @@ enum AcquiredInfo { TOO_FAST = 5, VENDOR = 6, START = 7, + TOO_DARK = 8, + TOO_BRIGHT = 9, } diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl index adb1c78cb2..3709a64b78 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl @@ -63,5 +63,17 @@ enum AcquiredInfo { * latency based on the time between the last START message and the onAuthenticated callback. */ START, + + /** + * For sensors that require illumination, such as optical under-display fingerprint sensors, + * the image was too dark to be used for matching. + */ + TOO_DARK, + + /** + * For sensors that require illumination, such as optical under-display fingerprint sensors, + * the image was too bright to be used for matching. + */ + TOO_BRIGHT, } -- GitLab From 78a04d6bc74106af9bde8654d529e0949aeafcf4 Mon Sep 17 00:00:00 2001 From: lesl Date: Fri, 22 Jan 2021 10:32:11 +0800 Subject: [PATCH 402/790] wifi: Support use "non-primy interface when testing hostapd Hal In current android design, the general use case is the interface is removed after terminate() call. But the VTS kill the hostapd immediately it causes terminate doesn't work normally. Add sleep 3 seconds to allow terminate processing. Another test case is considered to check hostapd died because any reason. (for instance: NPE crash) But the interface handling in android design is control in framework and WiFiHal. Case 1. Native crash will be handled in framework and clean the interface for the recovery. Case 2. VTS use "stopHAL" to clean "primy interface". It will cause clean up fail if OEM use "non-primy interface" for the SoftAp. But it is not requirement in hostapd HAL. Verify terminate is good in VtsHalWifiHostapd. Bug: 177483254 Bug: 177389456 Test: atest -c VtsHalWifiHostapdV1_3TargetTest Change-Id: I39f6ee92b1354ab2cebbe2fe6e9873e62d850c42 --- .../1.3/vts/functional/hostapd_hidl_test.cpp | 79 +++++-------------- 1 file changed, 18 insertions(+), 61 deletions(-) diff --git a/wifi/hostapd/1.3/vts/functional/hostapd_hidl_test.cpp b/wifi/hostapd/1.3/vts/functional/hostapd_hidl_test.cpp index 4e63c56d2c..fe9a183d56 100644 --- a/wifi/hostapd/1.3/vts/functional/hostapd_hidl_test.cpp +++ b/wifi/hostapd/1.3/vts/functional/hostapd_hidl_test.cpp @@ -81,10 +81,9 @@ class HostapdHidlTest virtual void TearDown() override { HIDL_INVOKE_VOID_WITHOUT_ARGUMENTS(hostapd_, terminate); - stopHostapd(wifi_instance_name_); - // Wait 3 seconds to allow driver processing load/unload between two - // test cases. + // Wait 3 seconds to allow terminate processing before kill hostapd. sleep(3); + stopHostapd(wifi_instance_name_); } protected: @@ -106,16 +105,6 @@ class HostapdHidlTest return status_and_name.second; } - // TODO: b/177483254, remove it after fix wlan1 failure case. - std::string getPrimaryWlanIfaceName() { - std::array buffer; - auto res = property_get("ro.vendor.wifi.sap.interface", buffer.data(), - nullptr); - if (res > 0) return buffer.data(); - property_get("wifi.interface", buffer.data(), "wlan0"); - return buffer.data(); - } - IHostapd::IfaceParams getIfaceParamsWithoutAcs(std::string iface_name) { ::android::hardware::wifi::hostapd::V1_0::IHostapd::IfaceParams iface_params; @@ -334,9 +323,7 @@ class HostapdHidlTest */ TEST_P(HostapdHidlTest, AddPskAccessPointWithAcs) { if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support"; - // TODO: Use setupApIfaceAndGetName after fixing b/177483254 - // std::string ifname = setupApIfaceAndGetName(false); - std::string ifname = getPrimaryWlanIfaceName(); + std::string ifname = setupApIfaceAndGetName(false); auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithAcs(ifname), getPskNwParams()); EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); @@ -348,9 +335,7 @@ TEST_P(HostapdHidlTest, AddPskAccessPointWithAcs) { */ TEST_P(HostapdHidlTest, AddPskAccessPointWithAcsAndFreqRange) { if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support"; - // TODO: Use setupApIfaceAndGetName after fixing b/177483254 - // std::string ifname = setupApIfaceAndGetName(false); - std::string ifname = getPrimaryWlanIfaceName(); + std::string ifname = setupApIfaceAndGetName(false); auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithAcsAndFreqRange(ifname), getPskNwParams()); @@ -363,9 +348,7 @@ TEST_P(HostapdHidlTest, AddPskAccessPointWithAcsAndFreqRange) { */ TEST_P(HostapdHidlTest, AddPskAccessPointWithAcsAndInvalidFreqRange) { if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support"; - // TODO: Use setupApIfaceAndGetName after fixing b/177483254 - // std::string ifname = setupApIfaceAndGetName(false); - std::string ifname = getPrimaryWlanIfaceName(); + std::string ifname = setupApIfaceAndGetName(false); auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithAcsAndInvalidFreqRange(ifname), getPskNwParams()); @@ -378,9 +361,7 @@ TEST_P(HostapdHidlTest, AddPskAccessPointWithAcsAndInvalidFreqRange) { */ TEST_P(HostapdHidlTest, AddOpenAccessPointWithAcs) { if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support"; - // TODO: Use setupApIfaceAndGetName after fixing b/177483254 - // std::string ifname = setupApIfaceAndGetName(false); - std::string ifname = getPrimaryWlanIfaceName(); + std::string ifname = setupApIfaceAndGetName(false); auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithAcs(ifname), getOpenNwParams()); EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code); @@ -391,9 +372,7 @@ TEST_P(HostapdHidlTest, AddOpenAccessPointWithAcs) { * Access point creation should pass. */ TEST_P(HostapdHidlTest, AddPskAccessPointWithoutAcs) { - // TODO: Use setupApIfaceAndGetName after fixing b/177483254 - // std::string ifname = setupApIfaceAndGetName(false); - std::string ifname = getPrimaryWlanIfaceName(); + std::string ifname = setupApIfaceAndGetName(false); auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithoutAcs(ifname), getPskNwParams()); @@ -405,9 +384,7 @@ TEST_P(HostapdHidlTest, AddPskAccessPointWithoutAcs) { * Access point creation should pass. */ TEST_P(HostapdHidlTest, AddPskAccessPointWithoutAcsAndNonMetered) { - // TODO: Use setupApIfaceAndGetName after fixing b/177483254 - // std::string ifname = setupApIfaceAndGetName(false); - std::string ifname = getPrimaryWlanIfaceName(); + std::string ifname = setupApIfaceAndGetName(false); auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithoutAcs(ifname), getPskNwParamsWithNonMetered()); @@ -419,9 +396,7 @@ TEST_P(HostapdHidlTest, AddPskAccessPointWithoutAcsAndNonMetered) { * Access point creation should pass. */ TEST_P(HostapdHidlTest, AddOpenAccessPointWithoutAcs) { - // TODO: Use setupApIfaceAndGetName after fixing b/177483254 - // std::string ifname = setupApIfaceAndGetName(false); - std::string ifname = getPrimaryWlanIfaceName(); + std::string ifname = setupApIfaceAndGetName(false); auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithoutAcs(ifname), getOpenNwParams()); @@ -434,9 +409,7 @@ TEST_P(HostapdHidlTest, AddOpenAccessPointWithoutAcs) { */ TEST_P(HostapdHidlTest, AddSaeTransitionAccessPointWithoutAcs) { if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support"; - // TODO: Use setupApIfaceAndGetName after fixing b/177483254 - // std::string ifname = setupApIfaceAndGetName(false); - std::string ifname = getPrimaryWlanIfaceName(); + std::string ifname = setupApIfaceAndGetName(false); auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithoutAcs(ifname), getSaeTransitionNwParams()); @@ -449,9 +422,7 @@ TEST_P(HostapdHidlTest, AddSaeTransitionAccessPointWithoutAcs) { */ TEST_P(HostapdHidlTest, AddSAEAccessPointWithoutAcs) { if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support"; - // TODO: Use setupApIfaceAndGetName after fixing b/177483254 - // std::string ifname = setupApIfaceAndGetName(false); - std::string ifname = getPrimaryWlanIfaceName(); + std::string ifname = setupApIfaceAndGetName(false); auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithoutAcs(ifname), getSaeNwParams()); @@ -464,9 +435,7 @@ TEST_P(HostapdHidlTest, AddSAEAccessPointWithoutAcs) { */ TEST_P(HostapdHidlTest, RemoveAccessPointWithAcs) { if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support"; - // TODO: Use setupApIfaceAndGetName after fixing b/177483254 - // std::string ifname = setupApIfaceAndGetName(false); - std::string ifname = getPrimaryWlanIfaceName(); + std::string ifname = setupApIfaceAndGetName(false); auto status_1_2 = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithAcs(ifname), getPskNwParams()); @@ -482,9 +451,7 @@ TEST_P(HostapdHidlTest, RemoveAccessPointWithAcs) { * Access point creation & removal should pass. */ TEST_P(HostapdHidlTest, RemoveAccessPointWithoutAcs) { - // TODO: Use setupApIfaceAndGetName after fixing b/177483254 - // std::string ifname = setupApIfaceAndGetName(false); - std::string ifname = getPrimaryWlanIfaceName(); + std::string ifname = setupApIfaceAndGetName(false); auto status_1_2 = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithoutAcs(ifname), getPskNwParams()); @@ -500,9 +467,7 @@ TEST_P(HostapdHidlTest, RemoveAccessPointWithoutAcs) { * Access point creation should fail. */ TEST_P(HostapdHidlTest, AddPskAccessPointWithInvalidChannel) { - // TODO: Use setupApIfaceAndGetName after fixing b/177483254 - // std::string ifname = setupApIfaceAndGetName(false); - std::string ifname = getPrimaryWlanIfaceName(); + std::string ifname = setupApIfaceAndGetName(false); auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithInvalidChannel(ifname), getPskNwParams()); @@ -514,9 +479,7 @@ TEST_P(HostapdHidlTest, AddPskAccessPointWithInvalidChannel) { * Access point creation should fail. */ TEST_P(HostapdHidlTest, AddInvalidPskAccessPointWithoutAcs) { - // TODO: Use setupApIfaceAndGetName after fixing b/177483254 - // std::string ifname = setupApIfaceAndGetName(false); - std::string ifname = getPrimaryWlanIfaceName(); + std::string ifname = setupApIfaceAndGetName(false); auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithoutAcs(ifname), getInvalidPskNwParams()); @@ -529,9 +492,7 @@ TEST_P(HostapdHidlTest, AddInvalidPskAccessPointWithoutAcs) { */ TEST_P(HostapdHidlTest, AddInvalidSaeTransitionAccessPointWithoutAcs) { if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support"; - // TODO: Use setupApIfaceAndGetName after fixing b/177483254 - // std::string ifname = setupApIfaceAndGetName(false); - std::string ifname = getPrimaryWlanIfaceName(); + std::string ifname = setupApIfaceAndGetName(false); auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithoutAcs(ifname), getInvalidSaeTransitionNwParams()); @@ -544,9 +505,7 @@ TEST_P(HostapdHidlTest, AddInvalidSaeTransitionAccessPointWithoutAcs) { */ TEST_P(HostapdHidlTest, AddInvalidSaeAccessPointWithoutAcs) { if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support"; - // TODO: Use setupApIfaceAndGetName after fixing b/177483254 - // std::string ifname = setupApIfaceAndGetName(false); - std::string ifname = getPrimaryWlanIfaceName(); + std::string ifname = setupApIfaceAndGetName(false); auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithoutAcs(ifname), getInvalidSaeNwParams()); @@ -558,9 +517,7 @@ TEST_P(HostapdHidlTest, AddInvalidSaeAccessPointWithoutAcs) { * when hotspot interface available. */ TEST_P(HostapdHidlTest, DisconnectClientWhenIfacAvailable) { - // TODO: Use setupApIfaceAndGetName after fixing b/177483254 - // std::string ifname = setupApIfaceAndGetName(false); - std::string ifname = getPrimaryWlanIfaceName(); + std::string ifname = setupApIfaceAndGetName(false); auto status_1_2 = HIDL_INVOKE(hostapd_, addAccessPoint_1_3, getIfaceParamsWithoutAcs(ifname), getOpenNwParams()); -- GitLab From c6b5f89b083f7f6e1d4cbebaaca5823195b75517 Mon Sep 17 00:00:00 2001 From: Ye Jiao Date: Fri, 15 Jan 2021 15:42:09 +0800 Subject: [PATCH 403/790] Notify scan-only mode to driver for power saving If Wi-Fi driver knows it's in scan-only mode, it can save more power than connect mode. This change adds setScanMode in IWifiStaIface to allow Wi-Fi framework to notify scan-only mode change to Wi-Fi driver. Bug: 177811719 Test: atest VtsHalWifiV1_5TargetTest Change-Id: I1dfbc24a0a3272c1341223aff36656be4a6fd21b --- wifi/1.5/IWifiStaIface.hal | 13 +++++++++++++ wifi/1.5/default/wifi_sta_iface.cpp | 13 +++++++++++++ wifi/1.5/default/wifi_sta_iface.h | 3 +++ .../1.5/vts/functional/wifi_sta_iface_hidl_test.cpp | 13 +++++++++++++ 4 files changed, 42 insertions(+) diff --git a/wifi/1.5/IWifiStaIface.hal b/wifi/1.5/IWifiStaIface.hal index e9d411e00b..daf545eb9c 100644 --- a/wifi/1.5/IWifiStaIface.hal +++ b/wifi/1.5/IWifiStaIface.hal @@ -41,4 +41,17 @@ interface IWifiStaIface extends @1.3::IWifiStaIface { * @return stats Instance of |LinkLayerStats|. */ getLinkLayerStats_1_5() generates (WifiStatus status, StaLinkLayerStats stats); + + /** + * Turn on/off scan only mode for the interface. + * + * @param enable Indicate if scan only mode is to be turned on/off. + * @return status Status of the operation. + * Possible status codes: + * |WifiStatusCode.SUCCESS|, + * |WifiStatusCode.ERROR_NOT_SUPPORTED|, + * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|, + * |WifiStatusCode.FAILURE_UNKNOWN| + */ + setScanMode(bool enable) generates (WifiStatus status); }; diff --git a/wifi/1.5/default/wifi_sta_iface.cpp b/wifi/1.5/default/wifi_sta_iface.cpp index 82bfcf15bb..92c9fe4392 100644 --- a/wifi/1.5/default/wifi_sta_iface.cpp +++ b/wifi/1.5/default/wifi_sta_iface.cpp @@ -273,6 +273,13 @@ Return WifiStaIface::getFactoryMacAddress( hidl_status_cb); } +Return WifiStaIface::setScanMode(bool enable, + setScanMode_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiStaIface::setScanModeInternal, hidl_status_cb, + enable); +} + std::pair WifiStaIface::getNameInternal() { return {createWifiStatus(WifiStatusCode::SUCCESS), ifname_}; } @@ -655,6 +662,12 @@ WifiStaIface::getFactoryMacAddressInternal() { return {createWifiStatus(WifiStatusCode::SUCCESS), mac}; } +WifiStatus WifiStaIface::setScanModeInternal(bool enable) { + // OEM's need to implement this on their devices if needed. + LOG(WARNING) << "setScanModeInternal(" << enable << ") not supported"; + return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); +} + } // namespace implementation } // namespace V1_5 } // namespace wifi diff --git a/wifi/1.5/default/wifi_sta_iface.h b/wifi/1.5/default/wifi_sta_iface.h index 94873c9494..f9058b8af1 100644 --- a/wifi/1.5/default/wifi_sta_iface.h +++ b/wifi/1.5/default/wifi_sta_iface.h @@ -114,6 +114,8 @@ class WifiStaIface : public V1_5::IWifiStaIface { setMacAddress_cb hidl_status_cb) override; Return getFactoryMacAddress( getFactoryMacAddress_cb hidl_status_cb) override; + Return setScanMode(bool enable, + setScanMode_cb hidl_status_cb) override; private: // Corresponding worker functions for the HIDL methods. @@ -164,6 +166,7 @@ class WifiStaIface : public V1_5::IWifiStaIface { WifiStatus setMacAddressInternal(const std::array& mac); std::pair> getFactoryMacAddressInternal(); + WifiStatus setScanModeInternal(bool enable); std::string ifname_; std::weak_ptr legacy_hal_; diff --git a/wifi/1.5/vts/functional/wifi_sta_iface_hidl_test.cpp b/wifi/1.5/vts/functional/wifi_sta_iface_hidl_test.cpp index 8cc3300324..399307ecdc 100644 --- a/wifi/1.5/vts/functional/wifi_sta_iface_hidl_test.cpp +++ b/wifi/1.5/vts/functional/wifi_sta_iface_hidl_test.cpp @@ -108,6 +108,19 @@ TEST_P(WifiStaIfaceHidlTest, GetLinkLayerStats_1_5) { WifiStatusCode::SUCCESS, HIDL_INVOKE(wifi_sta_iface_, disableLinkLayerStatsCollection).code); } +/** + * SetScanMode + */ +TEST_P(WifiStaIfaceHidlTest, SetScanMode) { + auto statusCode = + HIDL_INVOKE(wifi_sta_iface_, setScanMode, true).code; + EXPECT_TRUE(statusCode == WifiStatusCode::SUCCESS || + statusCode == WifiStatusCode::ERROR_NOT_SUPPORTED); + + statusCode = HIDL_INVOKE(wifi_sta_iface_, setScanMode, false).code; + EXPECT_TRUE(statusCode == WifiStatusCode::SUCCESS || + statusCode == WifiStatusCode::ERROR_NOT_SUPPORTED); +} GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiStaIfaceHidlTest); INSTANTIATE_TEST_SUITE_P( -- GitLab From 4e9b3b799d296ed389c78f2a82f12c63923200e9 Mon Sep 17 00:00:00 2001 From: Yipeng Cao Date: Sat, 23 Jan 2021 00:29:52 +0000 Subject: [PATCH 404/790] Fixed small typo in the gnss hal Change-Id: I074261e23a59e388b863249a6d528dcd3e5f6875 --- gnss/common/utils/default/Utils.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gnss/common/utils/default/Utils.cpp b/gnss/common/utils/default/Utils.cpp index ccc7145d2c..9bc6786b80 100644 --- a/gnss/common/utils/default/Utils.cpp +++ b/gnss/common/utils/default/Utils.cpp @@ -190,7 +190,7 @@ GnssData Utils::getMockMeasurement(const bool enableCorrVecOutputs) { .tropoDelayMeters = 3.882265204404031}, .correlationVectors = {}}; - GnssClock clock = {.gnssClockFlags = GnssClock::HAS_FULL_BIAS | GnssClock::HAS_FULL_BIAS | + GnssClock clock = {.gnssClockFlags = GnssClock::HAS_FULL_BIAS | GnssClock::HAS_BIAS | GnssClock::HAS_BIAS_UNCERTAINTY | GnssClock::HAS_DRIFT | GnssClock::HAS_DRIFT_UNCERTAINTY, .timeNs = 35854545000000, -- GitLab From 666dc38de4c58c996d872727f90bf213c86919d4 Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Thu, 21 Jan 2021 14:40:13 -0800 Subject: [PATCH 405/790] Add methonds to set and get authentication features Bug: 172593978 Test: m android.hardware.biometrics.face-update-api Change-Id: I497b9bd50fa082f711b3806da9cb8f307b921a22 --- .../biometrics/face/AcquiredInfo.aidl | 16 ++++- .../biometrics/face/AuthenticationFrame.aidl | 16 ++++- .../hardware/biometrics/face/BaseFrame.aidl | 16 ++++- .../hardware/biometrics/face/Cell.aidl | 16 ++++- .../biometrics/face/EnrollmentFrame.aidl | 16 ++++- .../biometrics/face/EnrollmentStage.aidl | 16 ++++- .../face/EnrollmentStageConfig.aidl | 16 ++++- .../biometrics/face/EnrollmentType.aidl | 16 ++++- .../hardware/biometrics/face/Error.aidl | 16 ++++- .../biometrics/face/FaceSensorType.aidl | 16 ++++- .../hardware/biometrics/face/Feature.aidl | 39 ++++++++++++ .../hardware/biometrics/face/IFace.aidl | 16 ++++- .../hardware/biometrics/face/ISession.aidl | 20 ++++++- .../biometrics/face/ISessionCallback.aidl | 18 +++++- .../hardware/biometrics/face/SensorProps.aidl | 16 ++++- .../biometrics/face/SessionState.aidl | 24 ++++++-- .../hardware/biometrics/face/Error.aidl | 5 +- .../hardware/biometrics/face/Feature.aidl | 39 ++++++++++++ .../hardware/biometrics/face/ISession.aidl | 59 +++++++++++++++++-- .../biometrics/face/ISessionCallback.aidl | 21 +++++++ .../biometrics/face/SessionState.aidl | 10 ++++ 21 files changed, 400 insertions(+), 27 deletions(-) create mode 100644 biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Feature.aidl create mode 100644 biometrics/face/aidl/android/hardware/biometrics/face/Feature.aidl diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl index 56d097d5ff..8fd6c5f9a8 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AuthenticationFrame.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AuthenticationFrame.aidl index 3043000f39..a9e4de3bc3 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AuthenticationFrame.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AuthenticationFrame.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/BaseFrame.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/BaseFrame.aidl index 27821e3ece..a93510160b 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/BaseFrame.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/BaseFrame.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Cell.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Cell.aidl index 17c1ba3695..cc2bf53c1d 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Cell.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Cell.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentFrame.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentFrame.aidl index c736e7e743..cc78e6b077 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentFrame.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentFrame.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStage.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStage.aidl index af6be9061a..fefac68ad6 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStage.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStage.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStageConfig.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStageConfig.aidl index 268ce52e46..d13eccd0fe 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStageConfig.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStageConfig.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentType.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentType.aidl index 7295b3b4ee..3603c4e08c 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentType.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentType.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Error.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Error.aidl index cba6ec595f..6bbe7871ac 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Error.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Error.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/FaceSensorType.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/FaceSensorType.aidl index b08c345b5d..481b678157 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/FaceSensorType.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/FaceSensorType.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Feature.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Feature.aidl new file mode 100644 index 0000000000..d9e561d518 --- /dev/null +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Feature.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 -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.face; +@Backing(type="byte") @VintfStability +enum Feature { + WAVE_ATTENTION_REQUIREMENT = 0, + WAVE_DIVERSE_POSES_REQUIREMENT = 1, + DEBUG = 2, +} diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl index 65afaa493f..37345ec01b 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// 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 203e2752b8..b855a9ede1 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 @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// @@ -21,11 +35,13 @@ package android.hardware.biometrics.face; interface ISession { void generateChallenge(in int cookie, in int timeoutSec); void revokeChallenge(in int cookie, in long challenge); - android.hardware.biometrics.common.ICancellationSignal enroll(in int cookie, in android.hardware.biometrics.face.EnrollmentType enrollmentType, in android.hardware.keymaster.HardwareAuthToken hat, in android.hardware.common.NativeHandle previewSurface); + android.hardware.biometrics.common.ICancellationSignal enroll(in int cookie, in android.hardware.keymaster.HardwareAuthToken hat, in android.hardware.biometrics.face.EnrollmentType type, in android.hardware.biometrics.face.Feature[] features, in android.hardware.common.NativeHandle previewSurface); android.hardware.biometrics.common.ICancellationSignal authenticate(in int cookie, in long operationId); android.hardware.biometrics.common.ICancellationSignal detectInteraction(in int cookie); void enumerateEnrollments(in int cookie); void removeEnrollments(in int cookie, in int[] enrollmentIds); + void getFeatures(in int cookie, in int enrollmentId); + void setFeature(in int cookie, in android.hardware.keymaster.HardwareAuthToken hat, in int enrollmentId, in android.hardware.biometrics.face.Feature feature, boolean enabled); void getAuthenticatorId(in int cookie); void invalidateAuthenticatorId(in int cookie); void resetLockout(in int cookie, in android.hardware.keymaster.HardwareAuthToken hat); diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl index a81c79a42b..6127c7b956 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// @@ -33,6 +47,8 @@ interface ISessionCallback { void onLockoutCleared(); void onInteractionDetected(); void onEnrollmentsEnumerated(in int[] enrollmentIds); + void onFeaturesRetrieved(in android.hardware.biometrics.face.Feature[] features, in int enrollmentId); + void onFeatureSet(in int enrollmentId, android.hardware.biometrics.face.Feature feature); void onEnrollmentsRemoved(in int[] enrollmentIds); void onAuthenticatorIdRetrieved(in long authenticatorId); void onAuthenticatorIdInvalidated(in long newAuthenticatorId); diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl index a52829cc5b..9147bc1853 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SessionState.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SessionState.aidl index 12a5eabbc4..46751d03d0 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SessionState.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SessionState.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// @@ -28,7 +42,9 @@ enum SessionState { DETECTING_INTERACTION = 6, ENUMERATING_ENROLLMENTS = 7, REMOVING_ENROLLMENTS = 8, - GETTING_AUTHENTICATOR_ID = 9, - INVALIDATING_AUTHENTICATOR_ID = 10, - RESETTING_LOCKOUT = 11, + GETTING_FEATURES = 9, + SETTING_FEATURE = 10, + GETTING_AUTHENTICATOR_ID = 11, + INVALIDATING_AUTHENTICATOR_ID = 12, + RESETTING_LOCKOUT = 13, } diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/Error.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/Error.aidl index d88370f129..7230128989 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/Error.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/Error.aidl @@ -32,9 +32,8 @@ enum Error { HW_UNAVAILABLE = 1, /** - * The current enroll or authenticate operation could not be completed, - * e.g. the sensor was unable to process the current image or the HAT was - * invalid. + * The current operation could not be completed, e.g. the sensor was unable + * to process the current image or the HAT was invalid. */ UNABLE_TO_PROCESS = 2, diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/Feature.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/Feature.aidl new file mode 100644 index 0000000000..b88050ab60 --- /dev/null +++ b/biometrics/face/aidl/android/hardware/biometrics/face/Feature.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.biometrics.face; + +@VintfStability +@Backing(type="byte") +enum Feature { + /** + * Do not require the user to look at the device during enrollment and authentication. Note + * this is to accommodate people who have limited vision. + */ + WAVE_ATTENTION_REQUIREMENT, + + /** + * Do not require a diverse set of poses during enrollment. This is to accommodate people with + * limited mobility. + */ + WAVE_DIVERSE_POSES_REQUIREMENT, + + /** + * Enable debugging functionality. + */ + DEBUG, +} + diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl index 34a1f8b5a9..25ddd82851 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl @@ -17,12 +17,12 @@ package android.hardware.biometrics.face; import android.hardware.biometrics.common.ICancellationSignal; +import android.hardware.biometrics.face.Feature; import android.hardware.biometrics.face.EnrollmentType; import android.hardware.keymaster.HardwareAuthToken; import android.hardware.common.NativeHandle; -/** - * A session is a collection of immutable state (sensorId, userId), mutable state (SessionState), +/** * A session is a collection of immutable state (sensorId, userId), mutable state (SessionState), * methods available for the framework to call, and a callback (ISessionCallback) to notify the * framework about the events and results. A session is used to establish communication between * the framework and the HAL. @@ -131,16 +131,17 @@ interface ISession { * * @param cookie An identifier used to track subsystem operations related to this call path. The * client must guarantee that it is unique per ISession. + * @param hat See above documentation. * @param enrollmentType See the EnrollmentType enum. + * @param features See the Feature enum. * @param previewSurface A surface provided by the framework if SensorProps#halControlsPreview is * set to true. The HAL must send the preview frames to previewSurface if * it's not null. - * @param hat See above documentation. * @return ICancellationSignal An object that can be used by the framework to cancel this * operation. */ - ICancellationSignal enroll(in int cookie, in EnrollmentType enrollmentType, - in HardwareAuthToken hat, in NativeHandle previewSurface); + ICancellationSignal enroll(in int cookie, in HardwareAuthToken hat, in EnrollmentType type, + in Feature[] features, in NativeHandle previewSurface); /** * authenticate: @@ -265,6 +266,54 @@ interface ISession { */ void removeEnrollments(in int cookie, in int[] enrollmentIds); + /** + * getFeatures: + * + * Returns a list of currently enabled features for the provided enrollmentId. + * + * If the enrollmentId is invalid, the HAL must invoke ISessionCallback#onError with + * Error::UNABLE_TO_PROCESS and return to SessionState::IDLING if no subsequent work is in the + * queue. + * + * Once the HAL is able to start processing this request, it must notify the framework by using + * ISessionCallback#onStateChanged with SessionState::GETTING_FEATURES. + * + * The HAL must notify the framework about the result by calling + * ISessionCallback#onFeaturesRetrieved. + * + * @param cookie An identifier used to track subsystem operations related to this call path. The + * client must guarantee that it is unique per ISession. + * @param enrollmentId the ID of the enrollment for which the features are requested. + */ + void getFeatures(in int cookie, in int enrollmentId); + + /** + * setFeature: + * + * Enables or disables a feature for the given enrollmentId. Because certain features may + * decrease security, the user must enter their password before this method is invoked + * (see @param hat). The HAL must verify the hat before changing any feature state. + * + * If either the hat or enrollmentId is invalid, the HAL must invoke ISessionCallback#onError + * with Error::UNABLE_TO_PROCESS and return to SessionState::IDLING if no subsequent work is in + * the queue. + * + * Once the HAL is able to start processing this request, it must notify the framework by using + * ISessionCallback#onStateChanged with SessionState::SETTING_FEATURE. + * + * After the feature is successfully set, the HAL must notify the framework by calling + * ISessionCallback#onFeatureSet. + * + * @param cookie An identifier used to track subsystem operations related to this call path. The + * client must guarantee that it is unique per ISession. + * @param hat HardwareAuthToken See above documentation. + * @param enrollmentId the ID of the enrollment for which the feature update is requested. + * @param feature The feature to be enabled or disabled. + * @param enabled Whether the provided features should be enabled or disabled. + */ + void setFeature(in int cookie, in HardwareAuthToken hat, in int enrollmentId, + in Feature feature, boolean enabled); + /** * getAuthenticatorId: * diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl index 9178e3aa7b..354f4a7e19 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl @@ -17,6 +17,7 @@ package android.hardware.biometrics.face; import android.hardware.biometrics.face.AcquiredInfo; +import android.hardware.biometrics.face.Feature; import android.hardware.biometrics.face.AuthenticationFrame; import android.hardware.biometrics.face.EnrollmentFrame; import android.hardware.biometrics.face.Error; @@ -177,6 +178,26 @@ interface ISessionCallback { */ void onEnrollmentsEnumerated(in int[] enrollmentIds); + /** + * This method must only be used to notify the framework during SessionState::GETTING_FEATURES. + * + * Provides a list of features that are currently enabled for the given enrollmentId. + * + * @param features A list of currently enabled features. See the Feature enum. + * @param enrollmentId The enrollment for which the features were requested. + */ + void onFeaturesRetrieved(in Feature[] features, in int enrollmentId); + + /** + * This method must only be used to notify the framework during SessionState::SETTING_FEATURE. + * + * Notifies the framework that ISession#setFeature has completed. + * + * @param enrollmentId The enrollment for which a feature was set. + * @param feature The feature that was set. + */ + void onFeatureSet(in int enrollmentId, Feature feature); + /** * This method must only be used to notify the framework during * SessionState::REMOVING_ENROLLMENTS. diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/SessionState.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/SessionState.aidl index e56f5d84fc..76755649e4 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/SessionState.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/SessionState.aidl @@ -64,6 +64,16 @@ enum SessionState { */ REMOVING_ENROLLMENTS, + /** + * The HAL is processing the ISession#getFeatures request. + */ + GETTING_FEATURES, + + /** + * The HAL is processing the ISession#setFeature request. + */ + SETTING_FEATURE, + /** * The HAL is processing the ISession#getAuthenticatorId request. */ -- GitLab From 26b20b9f64c3a75c365a7124611b1bdab453e8af Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Fri, 22 Jan 2021 11:39:49 -0800 Subject: [PATCH 406/790] Update the default implementation Bug: 172593978 Test: atest VtsHalBiometricsFaceTargetTest Change-Id: Ic86c936df8513a6181134053c20fe145cf509f13 --- biometrics/face/aidl/default/Session.cpp | 16 ++++++++++++++-- biometrics/face/aidl/default/Session.h | 13 +++++++++---- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/biometrics/face/aidl/default/Session.cpp b/biometrics/face/aidl/default/Session.cpp index df5187955f..63d1721314 100644 --- a/biometrics/face/aidl/default/Session.cpp +++ b/biometrics/face/aidl/default/Session.cpp @@ -55,8 +55,9 @@ ndk::ScopedAStatus Session::revokeChallenge(int32_t /*cookie*/, int64_t challeng } ndk::ScopedAStatus Session::enroll( - int32_t /*cookie*/, biometrics::face::EnrollmentType /*enrollmentType*/, - const keymaster::HardwareAuthToken& /*hat*/, const NativeHandle& /*previewSurface*/, + int32_t /*cookie*/, const keymaster::HardwareAuthToken& /*hat*/, + EnrollmentType /*enrollmentType*/, const std::vector& /*features*/, + const NativeHandle& /*previewSurface*/, std::shared_ptr* /*return_val*/) { return ndk::ScopedAStatus::ok(); } @@ -94,6 +95,17 @@ ndk::ScopedAStatus Session::removeEnrollments(int32_t /*cookie*/, return ndk::ScopedAStatus::ok(); } +ndk::ScopedAStatus Session::getFeatures(int32_t /*cookie*/, int32_t /*enrollmentId*/) { + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Session::setFeature(int32_t /*cookie*/, + const keymaster::HardwareAuthToken& /*hat*/, + int32_t /*enrollmentId*/, Feature /*feature*/, + bool /*enabled*/) { + return ndk::ScopedAStatus::ok(); +} + ndk::ScopedAStatus Session::getAuthenticatorId(int32_t /*cookie*/) { if (cb_) { cb_->onStateChanged(0, SessionState::GETTING_AUTHENTICATOR_ID); diff --git a/biometrics/face/aidl/default/Session.h b/biometrics/face/aidl/default/Session.h index 347d2020fc..83cb0641d6 100644 --- a/biometrics/face/aidl/default/Session.h +++ b/biometrics/face/aidl/default/Session.h @@ -34,10 +34,10 @@ class Session : public BnSession { ndk::ScopedAStatus revokeChallenge(int32_t cookie, int64_t challenge) override; - ndk::ScopedAStatus enroll( - int32_t cookie, biometrics::face::EnrollmentType enrollmentType, - const keymaster::HardwareAuthToken& hat, const NativeHandle& previewSurface, - std::shared_ptr* return_val) override; + ndk::ScopedAStatus enroll(int32_t cookie, const keymaster::HardwareAuthToken& hat, + EnrollmentType enrollmentType, const std::vector& features, + const NativeHandle& previewSurface, + std::shared_ptr* return_val) override; ndk::ScopedAStatus authenticate( int32_t cookie, int64_t keystoreOperationId, @@ -51,6 +51,11 @@ class Session : public BnSession { ndk::ScopedAStatus removeEnrollments(int32_t cookie, const std::vector& enrollmentIds) override; + ndk::ScopedAStatus getFeatures(int32_t cookie, int32_t enrollmentId) override; + + ndk::ScopedAStatus setFeature(int32_t cookie, const keymaster::HardwareAuthToken& hat, + int32_t enrollmentId, Feature feature, bool enabled) override; + ndk::ScopedAStatus getAuthenticatorId(int32_t cookie) override; ndk::ScopedAStatus invalidateAuthenticatorId(int32_t cookie) override; -- GitLab From f2d3886a2cc38e82da244c5b939d765e5f89a415 Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Fri, 22 Jan 2021 11:48:59 -0800 Subject: [PATCH 407/790] Update the VTS test Bug: 172593978 Test: atest VtsHalBiometricsFaceTargetTest Change-Id: I3d7c49a173fa7296a1eb2334cce9cf0c3d745fce --- .../face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp b/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp index 5b02a57ce8..4cc8b4afa0 100644 --- a/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp +++ b/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp @@ -103,6 +103,15 @@ class SessionCallback : public BnSessionCallback { return ndk::ScopedAStatus::ok(); } + ndk::ScopedAStatus onFeaturesRetrieved(const std::vector& /*features*/, + int32_t /*enrollmentId*/) override { + return ndk::ScopedAStatus::ok(); + } + + ndk::ScopedAStatus onFeatureSet(int32_t /*enrollmentId*/, Feature /*feature*/) override { + return ndk::ScopedAStatus::ok(); + } + ndk::ScopedAStatus onAuthenticatorIdRetrieved(int64_t /*authenticatorId*/) override { return ndk::ScopedAStatus::ok(); } -- GitLab From ee197f3c70bbb8c9ba4dbd7fa4d6faff90d4c884 Mon Sep 17 00:00:00 2001 From: Sunil Ravi Date: Tue, 12 Jan 2021 18:45:11 -0800 Subject: [PATCH 408/790] Wifi: Inform framework on failure to find a network Added a callback function to indicate that the supplicant failed to find a network in scan result which matches with the network capabilities requested by upper layer for connection. Bug: 161196120 Test: vts test - VtsHalWifiSupplicantV1_4TargetTest Change-Id: I9549a80ca636b4ee91aca421cf7cfae9f95a9161 --- wifi/supplicant/1.4/ISupplicantStaIfaceCallback.hal | 9 +++++++++ .../vts/functional/supplicant_sta_iface_hidl_test.cpp | 4 ++++ 2 files changed, 13 insertions(+) diff --git a/wifi/supplicant/1.4/ISupplicantStaIfaceCallback.hal b/wifi/supplicant/1.4/ISupplicantStaIfaceCallback.hal index c6f05fb953..3b0a4d4ca0 100644 --- a/wifi/supplicant/1.4/ISupplicantStaIfaceCallback.hal +++ b/wifi/supplicant/1.4/ISupplicantStaIfaceCallback.hal @@ -168,4 +168,13 @@ interface ISupplicantStaIfaceCallback extends @1.3::ISupplicantStaIfaceCallback * @param assocRejectData Association Rejection related information. */ oneway onAssociationRejected_1_4(AssociationRejectionData assocRejectData); + + /** + * Used to indicate that the supplicant failed to find a network in scan result + * which matches with the network capabilities requested by upper layer + * for connection. + * + * @param ssid network name supplicant tried to connect. + */ + oneway onNetworkNotFound(Ssid ssid); }; diff --git a/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp index 1794a39530..86d6737fa9 100644 --- a/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp +++ b/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp @@ -237,6 +237,10 @@ class IfaceCallback : public ISupplicantStaIfaceCallback { override { return Void(); } + Return onNetworkNotFound( + const hidl_vec& /* ssid */) override { + return Void(); + } }; /* -- GitLab From 3512b3cdb5054b41d50f0109a12634f0d0886cb6 Mon Sep 17 00:00:00 2001 From: SongFerngWang Date: Tue, 26 Jan 2021 03:08:48 +0800 Subject: [PATCH 409/790] Rename AllowedNetworkType to AllowedNetworkTypes Reference the ag/q/topic:%22b_171791177%22+(status:open%20OR%20status:merged) and ag/q/topic:"getAllowedNetworkTypeBitmap"+(status:open%20OR%20status:merged) Bug: 161434786 Test: build pass Change-Id: Iee919a40153f680d6a8b81dc88d8fa2bd1e8d343 --- radio/1.6/IRadio.hal | 19 +++++++++---------- radio/1.6/IRadioResponse.hal | 10 ++++++---- .../functional/radio_hidl_hal_utils_v1_6.h | 4 ++-- radio/1.6/vts/functional/radio_response.cpp | 4 ++-- 4 files changed, 19 insertions(+), 18 deletions(-) diff --git a/radio/1.6/IRadio.hal b/radio/1.6/IRadio.hal index a398e7d07f..1862800f5e 100644 --- a/radio/1.6/IRadio.hal +++ b/radio/1.6/IRadio.hal @@ -324,30 +324,29 @@ interface IRadio extends @1.5::IRadio { /** * Requests to set the network type for searching and registering. * - * Instruct the radio to *only* accept the types of network provided. This - * is stronger than setPreferredNetworkType which is a suggestion. + * Instruct the radio to *only* accept the types of network provided. + * setPreferredNetworkType, setPreferredNetworkTypesBitmap will not be called anymore + * except for IRadio v1.5 or older devices. * * @param serial Serial number of request. * @param networkTypeBitmap a 32-bit bearer bitmap of RadioAccessFamily * - * Response callback is IRadioResponse.setNetworkTypeBitmapResponse() + * Response callback is IRadioResponse.setAllowedNetworkTypesBitmapResponse() */ - oneway setAllowedNetworkTypeBitmap( + oneway setAllowedNetworkTypesBitmap( uint32_t serial, bitfield networkTypeBitmap); /** * Requests bitmap representing the currently allowed network types. * - * Requests the bitmap set by the corresponding method - * setAllowedNetworkTypeBitmap, which sets a strict set of RATs for the - * radio to use. Differs from getPreferredNetworkType and getPreferredNetworkTypeBitmap - * in that those request *preferences*. + * getPreferredNetworkType, getPreferredNetworkTypesBitmap will not be called anymore + * except for IRadio v1.5 or older devices. * * @param serial Serial number of request. * - * Response callback is IRadioResponse.getNetworkTypeBitmapResponse() + * Response callback is IRadioResponse.getAllowedNetworkTypesBitmapResponse() */ - oneway getAllowedNetworkTypeBitmap(uint32_t serial); + oneway getAllowedNetworkTypesBitmap(uint32_t serial); /** * Control data throttling at modem. diff --git a/radio/1.6/IRadioResponse.hal b/radio/1.6/IRadioResponse.hal index 6ac86c335e..3c6137ec3b 100644 --- a/radio/1.6/IRadioResponse.hal +++ b/radio/1.6/IRadioResponse.hal @@ -296,7 +296,7 @@ interface IRadioResponse extends @1.5::IRadioResponse { oneway cancelHandoverResponse(RadioResponseInfo info); /** - * Callback of IRadio.setAllowedNetworkTypeBitmap(int, bitfield) + * Callback of IRadio.setAllowedNetworkTypesBitmap(int, bitfield) * * Valid errors returned: * RadioError:NONE @@ -309,10 +309,12 @@ interface IRadioResponse extends @1.5::IRadioResponse { * RadioError:REQUEST_NOT_SUPPORTED * RadioError:NO_RESOURCES */ - oneway setAllowedNetworkTypeBitmapResponse(RadioResponseInfo info); + oneway setAllowedNetworkTypesBitmapResponse(RadioResponseInfo info); /** - * Callback of IRadio.getAllowedNetworkTypeBitmap(int, bitfield) + * Callback of IRadio.getAllowedNetworkTypesBitmap(int, bitfield) + * @param info Response info struct containing response type, serial no. and error + * @param networkTypeBitmap a 32-bit bitmap of RadioAccessFamily. * * Valid errors returned: * RadioError:NONE @@ -325,7 +327,7 @@ interface IRadioResponse extends @1.5::IRadioResponse { * RadioError:REQUEST_NOT_SUPPORTED * RadioError:NO_RESOURCES */ - oneway getAllowedNetworkTypeBitmapResponse( + oneway getAllowedNetworkTypesBitmapResponse( RadioResponseInfo info, bitfield networkTypeBitmap); /** diff --git a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h index 5fcfa3b0bb..334fec3622 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h +++ b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h @@ -790,10 +790,10 @@ class RadioResponse_v1_6 : public ::android::hardware::radio::V1_6::IRadioRespon Return cancelHandoverResponse( const ::android::hardware::radio::V1_6::RadioResponseInfo& info); - Return setAllowedNetworkTypeBitmapResponse( + Return setAllowedNetworkTypesBitmapResponse( const ::android::hardware::radio::V1_6::RadioResponseInfo& info); - Return getAllowedNetworkTypeBitmapResponse( + Return getAllowedNetworkTypesBitmapResponse( const ::android::hardware::radio::V1_6::RadioResponseInfo& info, const ::android::hardware::hidl_bitfield< ::android::hardware::radio::V1_4::RadioAccessFamily> diff --git a/radio/1.6/vts/functional/radio_response.cpp b/radio/1.6/vts/functional/radio_response.cpp index 7c5cf6df86..100fabd828 100644 --- a/radio/1.6/vts/functional/radio_response.cpp +++ b/radio/1.6/vts/functional/radio_response.cpp @@ -1150,14 +1150,14 @@ Return RadioResponse_v1_6::cancelHandoverResponse( return Void(); } -Return RadioResponse_v1_6::setAllowedNetworkTypeBitmapResponse( +Return RadioResponse_v1_6::setAllowedNetworkTypesBitmapResponse( const ::android::hardware::radio::V1_6::RadioResponseInfo& info) { rspInfo = info; parent_v1_6.notify(info.serial); return Void(); } -Return RadioResponse_v1_6::getAllowedNetworkTypeBitmapResponse( +Return RadioResponse_v1_6::getAllowedNetworkTypesBitmapResponse( const ::android::hardware::radio::V1_6::RadioResponseInfo& /*info*/, const ::android::hardware::hidl_bitfield< ::android::hardware::radio::V1_4::RadioAccessFamily> -- GitLab From d9a671e64a7153e8c3f85da3c84595c637a265ad Mon Sep 17 00:00:00 2001 From: Benjamin Schwartz Date: Mon, 25 Jan 2021 21:22:55 -0800 Subject: [PATCH 410/790] power/stats: Adding subsystem field to Channel Also fixing some comments Bug: 178115561 Test: dumpsys android.hardware.power.stats.IPowerStats/default Change-Id: I630d26ffe02e7d8a26f42f10516900370db3a3bb --- .../android/hardware/power/stats/Channel.aidl | 17 ++++++++++++++++- .../hardware/power/stats/EnergyConsumer.aidl | 16 +++++++++++++++- .../power/stats/EnergyConsumerAttribution.aidl | 16 +++++++++++++++- .../power/stats/EnergyConsumerResult.aidl | 16 +++++++++++++++- .../power/stats/EnergyConsumerType.aidl | 16 +++++++++++++++- .../hardware/power/stats/EnergyMeasurement.aidl | 16 +++++++++++++++- .../hardware/power/stats/IPowerStats.aidl | 16 +++++++++++++++- .../hardware/power/stats/PowerEntity.aidl | 16 +++++++++++++++- .../android/hardware/power/stats/State.aidl | 16 +++++++++++++++- .../hardware/power/stats/StateResidency.aidl | 16 +++++++++++++++- .../power/stats/StateResidencyResult.aidl | 16 +++++++++++++++- .../android/hardware/power/stats/Channel.aidl | 5 +++++ .../hardware/power/stats/EnergyConsumer.aidl | 4 ++-- 13 files changed, 173 insertions(+), 13 deletions(-) diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/Channel.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/Channel.aidl index ac326b5906..e0c372b308 100644 --- a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/Channel.aidl +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/Channel.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// @@ -21,4 +35,5 @@ package android.hardware.power.stats; parcelable Channel { int id; @utf8InCpp String name; + @utf8InCpp String subsystem; } diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumer.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumer.aidl index 9f9a10bee4..c8d7645ba2 100644 --- a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumer.aidl +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumer.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerAttribution.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerAttribution.aidl index 53f31b6410..2fdc1a5d6a 100644 --- a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerAttribution.aidl +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerAttribution.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerResult.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerResult.aidl index 773fa282bd..4937aef992 100644 --- a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerResult.aidl +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerResult.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerType.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerType.aidl index d08d24eedc..7b05d2f426 100644 --- a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerType.aidl +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyConsumerType.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyMeasurement.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyMeasurement.aidl index fc61c27355..2d6ae165fd 100644 --- a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyMeasurement.aidl +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/EnergyMeasurement.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/IPowerStats.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/IPowerStats.aidl index 11a2936b82..0b6387e4aa 100644 --- a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/IPowerStats.aidl +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/IPowerStats.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/PowerEntity.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/PowerEntity.aidl index 8fff6c3053..38a62acf1e 100644 --- a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/PowerEntity.aidl +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/PowerEntity.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/State.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/State.aidl index 2a8e6f8dc8..1c5d7c13e3 100644 --- a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/State.aidl +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/State.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateResidency.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateResidency.aidl index cb38df580e..7982f02063 100644 --- a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateResidency.aidl +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateResidency.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateResidencyResult.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateResidencyResult.aidl index 9f92253e33..5bc548e437 100644 --- a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateResidencyResult.aidl +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/StateResidencyResult.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/power/stats/aidl/android/hardware/power/stats/Channel.aidl b/power/stats/aidl/android/hardware/power/stats/Channel.aidl index 09c7d75942..5e8962e256 100644 --- a/power/stats/aidl/android/hardware/power/stats/Channel.aidl +++ b/power/stats/aidl/android/hardware/power/stats/Channel.aidl @@ -26,5 +26,10 @@ parcelable Channel { * Unique name of this Channel. Vendor/device specific. Opaque to framework */ @utf8InCpp String name; + + /** + * Name of the subsystem associated with this Channel. Opaque to framework + */ + @utf8InCpp String subsystem; } diff --git a/power/stats/aidl/android/hardware/power/stats/EnergyConsumer.aidl b/power/stats/aidl/android/hardware/power/stats/EnergyConsumer.aidl index 065d9993d9..2ff1279584 100644 --- a/power/stats/aidl/android/hardware/power/stats/EnergyConsumer.aidl +++ b/power/stats/aidl/android/hardware/power/stats/EnergyConsumer.aidl @@ -26,8 +26,8 @@ parcelable EnergyConsumer { int id; /** - * For a group of EnergyConsumers of the same logical type, sorting by ordinal should - * be give their physical order. No other meaning is carried by it. + * For a group of EnergyConsumers of the same logical type, sorting by ordinal + * gives their physical order. Ordinals must be consecutive integers starting from 0. */ int ordinal; -- GitLab From 2c0a47db87985c5610df088b19d1362d54aeb2c2 Mon Sep 17 00:00:00 2001 From: George Burgess IV Date: Wed, 20 Jan 2021 21:14:13 -0800 Subject: [PATCH 411/790] wifi: fix a use of an uninitialized value This `if` is executed once, so using `legacy_status` from a prior execution is nonsensical. Caught by the static analyzer: > hardware/interfaces/wifi/1.5/default/wifi_chip.cpp:1053:39: warning: 1st function call argument is an uninitialized value [clang-analyzer-core.CallAndMessage] Bug: 173999527 Test: atest -c VtsHalWifiApV1_5TargetTest Merged-In: Ib81f1496be53e453d9c99ede129a77bdaf860de7 Change-Id: Ib81f1496be53e453d9c99ede129a77bdaf860de7 --- wifi/1.5/default/wifi_chip.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/wifi/1.5/default/wifi_chip.cpp b/wifi/1.5/default/wifi_chip.cpp index fbb4a52bd9..414d74c088 100644 --- a/wifi/1.5/default/wifi_chip.cpp +++ b/wifi/1.5/default/wifi_chip.cpp @@ -1036,7 +1036,6 @@ WifiStatus WifiChip::removeApIfaceInternal(const std::string& ifname) { WifiStatus WifiChip::removeIfaceInstanceFromBridgedApIfaceInternal( const std::string& ifname, const std::string& ifInstanceName) { - legacy_hal::wifi_error legacy_status; const auto iface = findUsingName(ap_ifaces_, ifname); if (!iface.get() || ifInstanceName.empty()) { return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); @@ -1048,13 +1047,13 @@ WifiStatus WifiChip::removeIfaceInstanceFromBridgedApIfaceInternal( if (iface == ifInstanceName) { if (!iface_util_.lock()->removeIfaceFromBridge(it.first, iface)) { - LOG(ERROR) << "Failed to remove interface: " << iface - << " from " << ifname << ", error: " - << legacyErrorToString(legacy_status); + LOG(ERROR) + << "Failed to remove interface: " << ifInstanceName + << " from " << ifname; return createWifiStatus( WifiStatusCode::ERROR_NOT_AVAILABLE); } - legacy_status = + legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->deleteVirtualInterface(iface); if (legacy_status != legacy_hal::WIFI_SUCCESS) { LOG(ERROR) << "Failed to del interface: " << iface -- GitLab From 669c90632976f87949cc557c472386f64ae21db4 Mon Sep 17 00:00:00 2001 From: lesl Date: Fri, 22 Jan 2021 19:37:47 +0800 Subject: [PATCH 412/790] wifi: Add new HAL API: getBridgedInstances Also fix the instances doesn't update after removing the instance Cherry-pick from ag/13382534 which finished the review in master branch Bug: 173999527 Test: atest -c VtsHalWifiApV1_5TargetTest Change-Id: I439922d38c35b5367823f95f5f7d0e4c6ed05f57 --- wifi/1.5/IWifiApIface.hal | 14 ++++++++ wifi/1.5/default/wifi_ap_iface.cpp | 22 ++++++++++++ wifi/1.5/default/wifi_ap_iface.h | 6 ++++ wifi/1.5/default/wifi_chip.cpp | 1 + .../functional/wifi_ap_iface_hidl_test.cpp | 36 ++++++++++++++++--- .../vts/functional/wifi_chip_hidl_ap_test.cpp | 19 +++++++--- 6 files changed, 89 insertions(+), 9 deletions(-) diff --git a/wifi/1.5/IWifiApIface.hal b/wifi/1.5/IWifiApIface.hal index 9625a6b712..c638f1d570 100644 --- a/wifi/1.5/IWifiApIface.hal +++ b/wifi/1.5/IWifiApIface.hal @@ -37,4 +37,18 @@ interface IWifiApIface extends @1.4::IWifiApIface { * |WifiStatusCode.ERROR_UNKNOWN| */ resetToFactoryMacAddress() generates (WifiStatus status); + + /** + * Get the names of the bridged AP instances. + * + * @return status WifiStatus of the operation + * Possible status codes: + * |WifiStatusCode.SUCCESS|, + * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|, + * |WifiStatusCode.ERROR_UNKNOWN| + * + * @return instances A vector which contains the names of the bridged AP + * instances. Note: Returns an empty vector for a non-bridged AP. + */ + getBridgedInstances() generates (WifiStatus status, vec instances); }; diff --git a/wifi/1.5/default/wifi_ap_iface.cpp b/wifi/1.5/default/wifi_ap_iface.cpp index d98aa4579a..b438a4a832 100644 --- a/wifi/1.5/default/wifi_ap_iface.cpp +++ b/wifi/1.5/default/wifi_ap_iface.cpp @@ -47,6 +47,12 @@ bool WifiApIface::isValid() { return is_valid_; } std::string WifiApIface::getName() { return ifname_; } +void WifiApIface::removeInstance(std::string instance) { + instances_.erase( + std::remove(instances_.begin(), instances_.end(), instance), + instances_.end()); +} + Return WifiApIface::getName(getName_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, &WifiApIface::getNameInternal, hidl_status_cb); @@ -93,6 +99,13 @@ Return WifiApIface::resetToFactoryMacAddress( hidl_status_cb); } +Return WifiApIface::getBridgedInstances( + getBridgedInstances_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiApIface::getBridgedInstancesInternal, + hidl_status_cb); +} + std::pair WifiApIface::getNameInternal() { return {createWifiStatus(WifiStatusCode::SUCCESS), ifname_}; } @@ -178,6 +191,15 @@ WifiStatus WifiApIface::resetToFactoryMacAddressInternal() { } return createWifiStatus(WifiStatusCode::SUCCESS); } + +std::pair> +WifiApIface::getBridgedInstancesInternal() { + std::vector instances; + for (const auto& instance_name : instances_) { + instances.push_back(instance_name); + } + return {createWifiStatus(WifiStatusCode::SUCCESS), instances}; +} } // namespace implementation } // namespace V1_5 } // namespace wifi diff --git a/wifi/1.5/default/wifi_ap_iface.h b/wifi/1.5/default/wifi_ap_iface.h index 02fb2d8edc..8f8387deae 100644 --- a/wifi/1.5/default/wifi_ap_iface.h +++ b/wifi/1.5/default/wifi_ap_iface.h @@ -43,6 +43,7 @@ class WifiApIface : public V1_5::IWifiApIface { void invalidate(); bool isValid(); std::string getName(); + void removeInstance(std::string instance); // HIDL methods exposed. Return getName(getName_cb hidl_status_cb) override; @@ -59,6 +60,9 @@ class WifiApIface : public V1_5::IWifiApIface { Return resetToFactoryMacAddress( resetToFactoryMacAddress_cb hidl_status_cb) override; + Return getBridgedInstances( + getBridgedInstances_cb hidl_status_cb) override; + private: // Corresponding worker functions for the HIDL methods. std::pair getNameInternal(); @@ -70,6 +74,8 @@ class WifiApIface : public V1_5::IWifiApIface { std::pair> getFactoryMacAddressInternal( const std::string& ifaceName); WifiStatus resetToFactoryMacAddressInternal(); + std::pair> + getBridgedInstancesInternal(); std::string ifname_; std::vector instances_; diff --git a/wifi/1.5/default/wifi_chip.cpp b/wifi/1.5/default/wifi_chip.cpp index fbb4a52bd9..50836ccb1a 100644 --- a/wifi/1.5/default/wifi_chip.cpp +++ b/wifi/1.5/default/wifi_chip.cpp @@ -1067,6 +1067,7 @@ WifiStatus WifiChip::removeIfaceInstanceFromBridgedApIfaceInternal( } } br_ifaces_ap_instances_.erase(ifInstanceName); + iface->removeInstance(ifInstanceName); return createWifiStatus(WifiStatusCode::SUCCESS); } diff --git a/wifi/1.5/vts/functional/wifi_ap_iface_hidl_test.cpp b/wifi/1.5/vts/functional/wifi_ap_iface_hidl_test.cpp index e47b14df1e..424f9345f8 100644 --- a/wifi/1.5/vts/functional/wifi_ap_iface_hidl_test.cpp +++ b/wifi/1.5/vts/functional/wifi_ap_iface_hidl_test.cpp @@ -67,8 +67,8 @@ class WifiApIfaceHidlTest : public ::testing::TestWithParam { std::string GetInstanceName() { return GetParam(); } }; -/* - * resetToFactoryMacAddress +/** + * resetToFactoryMacAddress in bridged AP mode. */ TEST_P(WifiApIfaceHidlTest, resetToFactoryMacAddressInBridgedModeTest) { if (!isBridgedSupport_) GTEST_SKIP() << "Missing Bridged AP support"; @@ -79,8 +79,8 @@ TEST_P(WifiApIfaceHidlTest, resetToFactoryMacAddressInBridgedModeTest) { EXPECT_EQ(WifiStatusCode::SUCCESS, status.code); } -/* - * resetToFactoryMacAddress +/** + * resetToFactoryMacAddress in non-bridged mode */ TEST_P(WifiApIfaceHidlTest, resetToFactoryMacAddressTest) { sp wifi_ap_iface = getWifiApIface_1_5(GetInstanceName()); @@ -89,6 +89,34 @@ TEST_P(WifiApIfaceHidlTest, resetToFactoryMacAddressTest) { EXPECT_EQ(WifiStatusCode::SUCCESS, status.code); } +/** + * getBridgedInstances in non-bridged mode + */ +TEST_P(WifiApIfaceHidlTest, getBridgedInstancesTest) { + sp wifi_ap_iface = getWifiApIface_1_5(GetInstanceName()); + ASSERT_NE(nullptr, wifi_ap_iface.get()); + const auto& status_and_instances = + HIDL_INVOKE(wifi_ap_iface, getBridgedInstances); + EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_instances.first.code); + const auto& instances = status_and_instances.second; + EXPECT_EQ(0, instances.size()); +} + +/** + * getBridgedInstances in bridged AP mode. + */ +TEST_P(WifiApIfaceHidlTest, getBridgedInstancesInBridgedModeTest) { + if (!isBridgedSupport_) GTEST_SKIP() << "Missing Bridged AP support"; + sp wifi_ap_iface = + getBridgedWifiApIface_1_5(GetInstanceName()); + ASSERT_NE(nullptr, wifi_ap_iface.get()); + const auto& status_and_instances = + HIDL_INVOKE(wifi_ap_iface, getBridgedInstances); + EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_instances.first.code); + const auto& instances = status_and_instances.second; + EXPECT_EQ(2, instances.size()); +} + GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiApIfaceHidlTest); INSTANTIATE_TEST_SUITE_P( PerInstance, WifiApIfaceHidlTest, diff --git a/wifi/1.5/vts/functional/wifi_chip_hidl_ap_test.cpp b/wifi/1.5/vts/functional/wifi_chip_hidl_ap_test.cpp index 922c9a767a..d6a040852e 100644 --- a/wifi/1.5/vts/functional/wifi_chip_hidl_ap_test.cpp +++ b/wifi/1.5/vts/functional/wifi_chip_hidl_ap_test.cpp @@ -101,14 +101,23 @@ TEST_P(WifiChipHidlTest, ASSERT_NE(nullptr, wifi_ap_iface.get()); const auto& status_and_name = HIDL_INVOKE(wifi_ap_iface, getName); EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_name.first.code); - // TODO: b/173999527, add API to get instance name to replace it. - std::string br_name = status_and_name.second; // ap_br_ is the pre-fix - std::string instance_name = - br_name.substr(6, br_name.length()); // remove the pre-fex + std::string br_name = status_and_name.second; + const auto& status_and_instances = + HIDL_INVOKE(wifi_ap_iface, getBridgedInstances); + EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_instances.first.code); + const auto& instances = status_and_instances.second; + EXPECT_EQ(2, instances.size()); const auto& status_code = HIDL_INVOKE(wifi_chip_, removeIfaceInstanceFromBridgedApIface, br_name, - instance_name); + instances[0]); EXPECT_EQ(WifiStatusCode::SUCCESS, status_code.code); + const auto& status_and_instances_after_remove = + HIDL_INVOKE(wifi_ap_iface, getBridgedInstances); + EXPECT_EQ(WifiStatusCode::SUCCESS, + status_and_instances_after_remove.first.code); + const auto& instances_after_remove = + status_and_instances_after_remove.second; + EXPECT_EQ(1, instances_after_remove.size()); } GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiChipHidlTest); -- GitLab From 38533915d11f3a9d7fed45dab2bef376c1026d47 Mon Sep 17 00:00:00 2001 From: Jeongik Cha Date: Thu, 28 Jan 2021 00:49:49 +0900 Subject: [PATCH 413/790] Specify version for aidl_interface explicitly Bug: 150578172 Test: m Change-Id: I141de8ed6958fe42f727a0fa41473de4c1fb38de --- audio/core/all-versions/vts/functional/Android.bp | 2 +- authsecret/aidl/default/Android.bp | 2 +- authsecret/aidl/vts/Android.bp | 2 +- automotive/audiocontrol/aidl/default/Android.bp | 4 ++-- automotive/audiocontrol/aidl/vts/Android.bp | 2 +- automotive/occupant_awareness/aidl/default/Android.bp | 2 +- automotive/occupant_awareness/aidl/mock/Android.bp | 2 +- .../occupant_awareness/aidl/vts/functional/Android.bp | 2 +- automotive/vehicle/2.0/default/Android.bp | 2 +- biometrics/face/aidl/default/Android.bp | 4 ++-- biometrics/face/aidl/vts/Android.bp | 2 +- biometrics/fingerprint/aidl/default/Android.bp | 4 ++-- biometrics/fingerprint/aidl/vts/Android.bp | 2 +- gnss/1.1/default/Android.bp | 2 +- gnss/2.0/default/Android.bp | 2 +- gnss/2.1/default/Android.bp | 2 +- gnss/aidl/default/Android.bp | 2 +- gnss/aidl/vts/Android.bp | 2 +- gnss/common/utils/default/Android.bp | 2 +- graphics/mapper/4.0/vts/functional/Android.bp | 2 +- health/storage/aidl/default/Android.bp | 2 +- health/storage/aidl/vts/functional/Android.bp | 2 +- identity/aidl/default/Android.bp | 8 ++++---- identity/aidl/vts/Android.bp | 6 +++--- light/aidl/default/Android.bp | 2 +- light/aidl/vts/functional/Android.bp | 2 +- light/utils/Android.bp | 2 +- memtrack/aidl/default/Android.bp | 2 +- memtrack/aidl/vts/Android.bp | 2 +- oemlock/aidl/default/Android.bp | 2 +- oemlock/aidl/vts/Android.bp | 2 +- power/aidl/default/Android.bp | 2 +- power/aidl/vts/Android.bp | 2 +- power/stats/aidl/default/Android.bp | 2 +- power/stats/aidl/vts/Android.bp | 2 +- rebootescrow/aidl/default/Android.bp | 4 ++-- rebootescrow/aidl/vts/functional/Android.bp | 2 +- security/keymint/aidl/default/Android.bp | 2 +- security/keymint/aidl/vts/functional/Android.bp | 8 ++++---- security/keymint/support/Android.bp | 2 +- tests/extension/vibrator/aidl/client/Android.bp | 8 ++++---- tests/extension/vibrator/aidl/default/Android.bp | 4 ++-- tests/msgq/1.0/default/Android.bp | 4 ++-- vibrator/aidl/default/Android.bp | 4 ++-- vibrator/aidl/vts/Android.bp | 4 ++-- vibrator/bench/Android.bp | 2 +- weaver/aidl/default/Android.bp | 2 +- weaver/aidl/vts/Android.bp | 2 +- 48 files changed, 67 insertions(+), 67 deletions(-) diff --git a/audio/core/all-versions/vts/functional/Android.bp b/audio/core/all-versions/vts/functional/Android.bp index a809a92558..8021bd9dd9 100644 --- a/audio/core/all-versions/vts/functional/Android.bp +++ b/audio/core/all-versions/vts/functional/Android.bp @@ -22,7 +22,7 @@ cc_defaults { "libxml2", ], shared_libs: [ - "audioclient-types-aidl-unstable-cpp", + "audioclient-types-aidl-cpp", "libaudioclient_aidl_conversion", "libbinder", "libfmq", diff --git a/authsecret/aidl/default/Android.bp b/authsecret/aidl/default/Android.bp index d5983442f5..44e0711096 100644 --- a/authsecret/aidl/default/Android.bp +++ b/authsecret/aidl/default/Android.bp @@ -25,7 +25,7 @@ cc_binary { "AuthSecret.cpp", ], shared_libs: [ - "android.hardware.authsecret-ndk_platform", + "android.hardware.authsecret-V1-ndk_platform", "libbase", "libbinder_ndk", ], diff --git a/authsecret/aidl/vts/Android.bp b/authsecret/aidl/vts/Android.bp index 83a85b26ce..29b3bcc21d 100644 --- a/authsecret/aidl/vts/Android.bp +++ b/authsecret/aidl/vts/Android.bp @@ -21,7 +21,7 @@ cc_test { "use_libaidlvintf_gtest_helper_static", ], srcs: ["VtsHalAuthSecretTargetTest.cpp"], - static_libs: ["android.hardware.authsecret-ndk_platform"], + static_libs: ["android.hardware.authsecret-V1-ndk_platform"], shared_libs: ["libbinder_ndk"], test_suites: [ "general-tests", diff --git a/automotive/audiocontrol/aidl/default/Android.bp b/automotive/audiocontrol/aidl/default/Android.bp index 427709abb3..05fec79666 100644 --- a/automotive/audiocontrol/aidl/default/Android.bp +++ b/automotive/audiocontrol/aidl/default/Android.bp @@ -22,8 +22,8 @@ cc_binary { generated_sources: ["audio_policy_configuration_V7_0"], header_libs: ["libxsdc-utils"], shared_libs: [ - "android.frameworks.automotive.powerpolicy-ndk_platform", - "android.hardware.automotive.audiocontrol-ndk_platform", + "android.frameworks.automotive.powerpolicy-V1-ndk_platform", + "android.hardware.automotive.audiocontrol-V1-ndk_platform", "libbase", "libbinder_ndk", "libcutils", diff --git a/automotive/audiocontrol/aidl/vts/Android.bp b/automotive/audiocontrol/aidl/vts/Android.bp index 3d81e001c1..89f5f9266c 100644 --- a/automotive/audiocontrol/aidl/vts/Android.bp +++ b/automotive/audiocontrol/aidl/vts/Android.bp @@ -28,7 +28,7 @@ cc_test { "libxml2", ], static_libs: [ - "android.hardware.automotive.audiocontrol-cpp", + "android.hardware.automotive.audiocontrol-V1-cpp", "libgmock", ], test_suites: [ diff --git a/automotive/occupant_awareness/aidl/default/Android.bp b/automotive/occupant_awareness/aidl/default/Android.bp index 1b2fba2ea4..1e50930716 100644 --- a/automotive/occupant_awareness/aidl/default/Android.bp +++ b/automotive/occupant_awareness/aidl/default/Android.bp @@ -27,6 +27,6 @@ cc_binary { "libbase", "libbinder_ndk", "libutils", - "android.hardware.automotive.occupant_awareness-ndk_platform", + "android.hardware.automotive.occupant_awareness-V1-ndk_platform", ], } diff --git a/automotive/occupant_awareness/aidl/mock/Android.bp b/automotive/occupant_awareness/aidl/mock/Android.bp index 4b3086660c..64ca73377b 100644 --- a/automotive/occupant_awareness/aidl/mock/Android.bp +++ b/automotive/occupant_awareness/aidl/mock/Android.bp @@ -27,6 +27,6 @@ cc_binary { "libbase", "libbinder_ndk", "libutils", - "android.hardware.automotive.occupant_awareness-ndk_platform", + "android.hardware.automotive.occupant_awareness-V1-ndk_platform", ], } diff --git a/automotive/occupant_awareness/aidl/vts/functional/Android.bp b/automotive/occupant_awareness/aidl/vts/functional/Android.bp index 514b0afc2b..dbd0538de1 100644 --- a/automotive/occupant_awareness/aidl/vts/functional/Android.bp +++ b/automotive/occupant_awareness/aidl/vts/functional/Android.bp @@ -9,7 +9,7 @@ cc_test { "libbinder", ], static_libs: [ - "android.hardware.automotive.occupant_awareness-cpp", + "android.hardware.automotive.occupant_awareness-V1-cpp", ], test_suites: [ "vts", diff --git a/automotive/vehicle/2.0/default/Android.bp b/automotive/vehicle/2.0/default/Android.bp index bbb48e1489..c66c9cca11 100644 --- a/automotive/vehicle/2.0/default/Android.bp +++ b/automotive/vehicle/2.0/default/Android.bp @@ -32,7 +32,7 @@ cc_defaults { defaults: ["vhal_v2_0_defaults"], shared_libs: [ "libbinder_ndk", - "android.automotive.watchdog-ndk_platform", + "android.automotive.watchdog-V2-ndk_platform", ], } diff --git a/biometrics/face/aidl/default/Android.bp b/biometrics/face/aidl/default/Android.bp index 51a8ef4488..a13b8cb09d 100644 --- a/biometrics/face/aidl/default/Android.bp +++ b/biometrics/face/aidl/default/Android.bp @@ -7,8 +7,8 @@ cc_binary { shared_libs: [ "libbase", "libbinder_ndk", - "android.hardware.biometrics.face-ndk_platform", - "android.hardware.biometrics.common-unstable-ndk_platform", + "android.hardware.biometrics.face-V1-ndk_platform", + "android.hardware.biometrics.common-V1-ndk_platform", ], srcs: [ "main.cpp", diff --git a/biometrics/face/aidl/vts/Android.bp b/biometrics/face/aidl/vts/Android.bp index 427b8785fb..a4c76f573a 100644 --- a/biometrics/face/aidl/vts/Android.bp +++ b/biometrics/face/aidl/vts/Android.bp @@ -7,7 +7,7 @@ cc_test { srcs: ["VtsHalBiometricsFaceTargetTest.cpp"], shared_libs: [ "libbinder_ndk", - "android.hardware.biometrics.face-ndk_platform", + "android.hardware.biometrics.face-V1-ndk_platform", ], test_suites: [ "general-tests", diff --git a/biometrics/fingerprint/aidl/default/Android.bp b/biometrics/fingerprint/aidl/default/Android.bp index ce1ff5964b..c8cb663686 100644 --- a/biometrics/fingerprint/aidl/default/Android.bp +++ b/biometrics/fingerprint/aidl/default/Android.bp @@ -7,8 +7,8 @@ cc_binary { shared_libs: [ "libbase", "libbinder_ndk", - "android.hardware.biometrics.fingerprint-ndk_platform", - "android.hardware.biometrics.common-unstable-ndk_platform", + "android.hardware.biometrics.fingerprint-V1-ndk_platform", + "android.hardware.biometrics.common-V1-ndk_platform", ], srcs: [ "main.cpp", diff --git a/biometrics/fingerprint/aidl/vts/Android.bp b/biometrics/fingerprint/aidl/vts/Android.bp index b441eb3bcb..07bccb5965 100644 --- a/biometrics/fingerprint/aidl/vts/Android.bp +++ b/biometrics/fingerprint/aidl/vts/Android.bp @@ -7,7 +7,7 @@ cc_test { srcs: ["VtsHalBiometricsFingerprintTargetTest.cpp"], shared_libs: [ "libbinder_ndk", - "android.hardware.biometrics.fingerprint-ndk_platform", + "android.hardware.biometrics.fingerprint-V1-ndk_platform", ], test_suites: [ "general-tests", diff --git a/gnss/1.1/default/Android.bp b/gnss/1.1/default/Android.bp index ef43a34947..6853ad948d 100644 --- a/gnss/1.1/default/Android.bp +++ b/gnss/1.1/default/Android.bp @@ -18,7 +18,7 @@ cc_binary { "android.hardware.gnss@2.0", "android.hardware.gnss@1.1", "android.hardware.gnss@1.0", - "android.hardware.gnss-ndk_platform", + "android.hardware.gnss-V1-ndk_platform", ], static_libs: [ "android.hardware.gnss@common-default-lib", diff --git a/gnss/2.0/default/Android.bp b/gnss/2.0/default/Android.bp index 7da462f977..be0455365d 100644 --- a/gnss/2.0/default/Android.bp +++ b/gnss/2.0/default/Android.bp @@ -41,7 +41,7 @@ cc_binary { "android.hardware.gnss@2.0", "android.hardware.gnss@1.1", "android.hardware.gnss@1.0", - "android.hardware.gnss-ndk_platform", + "android.hardware.gnss-V1-ndk_platform", ], static_libs: [ "android.hardware.gnss@common-default-lib", diff --git a/gnss/2.1/default/Android.bp b/gnss/2.1/default/Android.bp index 63e5013276..7c4b9c6fc5 100644 --- a/gnss/2.1/default/Android.bp +++ b/gnss/2.1/default/Android.bp @@ -34,7 +34,7 @@ cc_binary { "android.hardware.gnss@1.0", "android.hardware.gnss@1.1", "android.hardware.gnss@2.0", - "android.hardware.gnss-ndk_platform", + "android.hardware.gnss-V1-ndk_platform", ], static_libs: [ "android.hardware.gnss@common-default-lib", diff --git a/gnss/aidl/default/Android.bp b/gnss/aidl/default/Android.bp index 6694ce619c..b56a701935 100644 --- a/gnss/aidl/default/Android.bp +++ b/gnss/aidl/default/Android.bp @@ -42,7 +42,7 @@ 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-ndk_platform", + "android.hardware.gnss-V1-ndk_platform", ], srcs: [ "Gnss.cpp", diff --git a/gnss/aidl/vts/Android.bp b/gnss/aidl/vts/Android.bp index c10e809725..7cdc339633 100644 --- a/gnss/aidl/vts/Android.bp +++ b/gnss/aidl/vts/Android.bp @@ -34,7 +34,7 @@ cc_test { "libbinder", ], static_libs: [ - "android.hardware.gnss-cpp", + "android.hardware.gnss-V1-cpp", "android.hardware.gnss@common-vts-lib", ], test_suites: [ diff --git a/gnss/common/utils/default/Android.bp b/gnss/common/utils/default/Android.bp index be1d532288..c44968d674 100644 --- a/gnss/common/utils/default/Android.bp +++ b/gnss/common/utils/default/Android.bp @@ -42,6 +42,6 @@ cc_library_static { "android.hardware.gnss@2.1", "android.hardware.gnss.measurement_corrections@1.1", "android.hardware.gnss.measurement_corrections@1.0", - "android.hardware.gnss-ndk_platform", + "android.hardware.gnss-V1-ndk_platform", ], } diff --git a/graphics/mapper/4.0/vts/functional/Android.bp b/graphics/mapper/4.0/vts/functional/Android.bp index 8bda42556b..2d39daaa0b 100644 --- a/graphics/mapper/4.0/vts/functional/Android.bp +++ b/graphics/mapper/4.0/vts/functional/Android.bp @@ -19,7 +19,7 @@ cc_test { defaults: ["VtsHalTargetTestDefaults"], srcs: ["VtsHalGraphicsMapperV4_0TargetTest.cpp"], static_libs: [ - "android.hardware.graphics.common-unstable-ndk_platform", + "android.hardware.graphics.common-V2-ndk_platform", "android.hardware.graphics.mapper@4.0-vts", "libgralloctypes", "libsync", diff --git a/health/storage/aidl/default/Android.bp b/health/storage/aidl/default/Android.bp index 68a8ee267f..b53bc35f28 100644 --- a/health/storage/aidl/default/Android.bp +++ b/health/storage/aidl/default/Android.bp @@ -20,7 +20,7 @@ cc_defaults { shared_libs: [ "libbase", "libbinder_ndk", - "android.hardware.health.storage-unstable-ndk_platform", + "android.hardware.health.storage-V1-ndk_platform", ], static_libs: [ "libfstab", diff --git a/health/storage/aidl/vts/functional/Android.bp b/health/storage/aidl/vts/functional/Android.bp index 86b72a712d..0e7671df03 100644 --- a/health/storage/aidl/vts/functional/Android.bp +++ b/health/storage/aidl/vts/functional/Android.bp @@ -25,7 +25,7 @@ cc_test { "libbinder_ndk", ], static_libs: [ - "android.hardware.health.storage-ndk_platform", + "android.hardware.health.storage-V1-ndk_platform", ], header_libs: [ "libhealth_storage_test_common_headers", diff --git a/identity/aidl/default/Android.bp b/identity/aidl/default/Android.bp index 874464849d..9659f576cf 100644 --- a/identity/aidl/default/Android.bp +++ b/identity/aidl/default/Android.bp @@ -29,8 +29,8 @@ cc_library_static { "libsoft_attestation_cert", "libpuresoftkeymasterdevice", "android.hardware.identity-support-lib", - "android.hardware.identity-unstable-ndk_platform", - "android.hardware.keymaster-unstable-ndk_platform", + "android.hardware.identity-V3-ndk_platform", + "android.hardware.keymaster-V3-ndk_platform", ], } @@ -89,8 +89,8 @@ cc_binary { "libsoft_attestation_cert", "libpuresoftkeymasterdevice", "android.hardware.identity-support-lib", - "android.hardware.identity-unstable-ndk_platform", - "android.hardware.keymaster-unstable-ndk_platform", + "android.hardware.identity-V3-ndk_platform", + "android.hardware.keymaster-V3-ndk_platform", "android.hardware.identity-libeic-hal-common", "android.hardware.identity-libeic-library", ], diff --git a/identity/aidl/vts/Android.bp b/identity/aidl/vts/Android.bp index f1b1bcf552..f487a64799 100644 --- a/identity/aidl/vts/Android.bp +++ b/identity/aidl/vts/Android.bp @@ -30,9 +30,9 @@ cc_test { "libpuresoftkeymasterdevice", "android.hardware.keymaster@4.0", "android.hardware.identity-support-lib", - "android.hardware.identity-unstable-cpp", - "android.hardware.keymaster-unstable-cpp", - "android.hardware.keymaster-unstable-ndk_platform", + "android.hardware.identity-V3-cpp", + "android.hardware.keymaster-V3-cpp", + "android.hardware.keymaster-V3-ndk_platform", "libkeymaster4support", "libkeymaster4_1support", ], diff --git a/light/aidl/default/Android.bp b/light/aidl/default/Android.bp index ae3f4630de..4e43ba9c63 100644 --- a/light/aidl/default/Android.bp +++ b/light/aidl/default/Android.bp @@ -7,7 +7,7 @@ cc_binary { shared_libs: [ "libbase", "libbinder_ndk", - "android.hardware.light-ndk_platform", + "android.hardware.light-V1-ndk_platform", ], srcs: [ "Lights.cpp", diff --git a/light/aidl/vts/functional/Android.bp b/light/aidl/vts/functional/Android.bp index aa4719b739..4c9356c9ca 100644 --- a/light/aidl/vts/functional/Android.bp +++ b/light/aidl/vts/functional/Android.bp @@ -27,7 +27,7 @@ cc_test { "libbinder", ], static_libs: [ - "android.hardware.light-cpp", + "android.hardware.light-V1-cpp", ], test_suites: [ "vts", diff --git a/light/utils/Android.bp b/light/utils/Android.bp index e901129d1f..871f983532 100644 --- a/light/utils/Android.bp +++ b/light/utils/Android.bp @@ -28,6 +28,6 @@ cc_binary { "libutils", ], static_libs: [ - "android.hardware.light-cpp", + "android.hardware.light-V1-cpp", ], } diff --git a/memtrack/aidl/default/Android.bp b/memtrack/aidl/default/Android.bp index 52f88c8097..8d97bfc703 100644 --- a/memtrack/aidl/default/Android.bp +++ b/memtrack/aidl/default/Android.bp @@ -21,7 +21,7 @@ cc_binary { shared_libs: [ "libbase", "libbinder_ndk", - "android.hardware.memtrack-ndk_platform", + "android.hardware.memtrack-V1-ndk_platform", ], srcs: [ "main.cpp", diff --git a/memtrack/aidl/vts/Android.bp b/memtrack/aidl/vts/Android.bp index c9743f43f6..df87db843f 100644 --- a/memtrack/aidl/vts/Android.bp +++ b/memtrack/aidl/vts/Android.bp @@ -10,7 +10,7 @@ cc_test { "libvintf", ], static_libs: [ - "android.hardware.memtrack-unstable-ndk_platform", + "android.hardware.memtrack-V1-ndk_platform", ], test_suites: [ "vts-core", diff --git a/oemlock/aidl/default/Android.bp b/oemlock/aidl/default/Android.bp index b9872d7eda..464b0a3d60 100644 --- a/oemlock/aidl/default/Android.bp +++ b/oemlock/aidl/default/Android.bp @@ -25,7 +25,7 @@ cc_binary { "OemLock.cpp", ], shared_libs: [ - "android.hardware.oemlock-ndk_platform", + "android.hardware.oemlock-V1-ndk_platform", "libbase", "libbinder_ndk", ], diff --git a/oemlock/aidl/vts/Android.bp b/oemlock/aidl/vts/Android.bp index a13dbe2cc7..18b53c2e7d 100644 --- a/oemlock/aidl/vts/Android.bp +++ b/oemlock/aidl/vts/Android.bp @@ -25,7 +25,7 @@ cc_test { "libbinder_ndk", "libbase", ], - static_libs: ["android.hardware.oemlock-ndk_platform"], + static_libs: ["android.hardware.oemlock-V1-ndk_platform"], test_suites: [ "general-tests", "vts", diff --git a/power/aidl/default/Android.bp b/power/aidl/default/Android.bp index 07cd368a54..de04bcdcfc 100644 --- a/power/aidl/default/Android.bp +++ b/power/aidl/default/Android.bp @@ -21,7 +21,7 @@ cc_binary { shared_libs: [ "libbase", "libbinder_ndk", - "android.hardware.power-ndk_platform", + "android.hardware.power-V1-ndk_platform", ], srcs: [ "main.cpp", diff --git a/power/aidl/vts/Android.bp b/power/aidl/vts/Android.bp index 28b08c7c4e..008073bdf8 100644 --- a/power/aidl/vts/Android.bp +++ b/power/aidl/vts/Android.bp @@ -23,7 +23,7 @@ cc_test { "libbinder", ], static_libs: [ - "android.hardware.power-cpp", + "android.hardware.power-V1-cpp", ], test_suites: [ "vts", diff --git a/power/stats/aidl/default/Android.bp b/power/stats/aidl/default/Android.bp index 40b9447b70..595ecd62d5 100644 --- a/power/stats/aidl/default/Android.bp +++ b/power/stats/aidl/default/Android.bp @@ -21,7 +21,7 @@ cc_binary { shared_libs: [ "libbase", "libbinder_ndk", - "android.hardware.power.stats-ndk_platform", + "android.hardware.power.stats-V1-ndk_platform", ], srcs: [ "main.cpp", diff --git a/power/stats/aidl/vts/Android.bp b/power/stats/aidl/vts/Android.bp index 930709f160..31fb990905 100644 --- a/power/stats/aidl/vts/Android.bp +++ b/power/stats/aidl/vts/Android.bp @@ -23,7 +23,7 @@ cc_test { "libbinder_ndk", ], static_libs: [ - "android.hardware.power.stats-ndk_platform", + "android.hardware.power.stats-V1-ndk_platform", ], test_suites: [ "general-tests", diff --git a/rebootescrow/aidl/default/Android.bp b/rebootescrow/aidl/default/Android.bp index b77272f6d8..e6a4e7ab4f 100644 --- a/rebootescrow/aidl/default/Android.bp +++ b/rebootescrow/aidl/default/Android.bp @@ -20,7 +20,7 @@ cc_library_static { shared_libs: [ "libbase", "libbinder_ndk", - "android.hardware.rebootescrow-ndk_platform", + "android.hardware.rebootescrow-V1-ndk_platform", ], export_include_dirs: ["include"], srcs: [ @@ -47,7 +47,7 @@ cc_binary { shared_libs: [ "libbase", "libbinder_ndk", - "android.hardware.rebootescrow-ndk_platform", + "android.hardware.rebootescrow-V1-ndk_platform", ], static_libs: [ "libhadamardutils", diff --git a/rebootescrow/aidl/vts/functional/Android.bp b/rebootescrow/aidl/vts/functional/Android.bp index 2cc00685d6..abd4937f62 100644 --- a/rebootescrow/aidl/vts/functional/Android.bp +++ b/rebootescrow/aidl/vts/functional/Android.bp @@ -25,7 +25,7 @@ cc_test { "libbinder", ], static_libs: [ - "android.hardware.rebootescrow-cpp", + "android.hardware.rebootescrow-V1-cpp", ], test_suites: [ "vts", diff --git a/security/keymint/aidl/default/Android.bp b/security/keymint/aidl/default/Android.bp index 79697c4e9e..b2758adcb1 100644 --- a/security/keymint/aidl/default/Android.bp +++ b/security/keymint/aidl/default/Android.bp @@ -9,7 +9,7 @@ cc_binary { "-Wextra", ], shared_libs: [ - "android.hardware.security.keymint-unstable-ndk_platform", + "android.hardware.security.keymint-V1-ndk_platform", "libbase", "libbinder_ndk", "libcppbor", diff --git a/security/keymint/aidl/vts/functional/Android.bp b/security/keymint/aidl/vts/functional/Android.bp index 17a461366c..f4ba9e7362 100644 --- a/security/keymint/aidl/vts/functional/Android.bp +++ b/security/keymint/aidl/vts/functional/Android.bp @@ -30,8 +30,8 @@ cc_test { "libkeymint_support", ], static_libs: [ - "android.hardware.security.keymint-unstable-ndk_platform", - "android.hardware.security.secureclock-unstable-ndk_platform", + "android.hardware.security.keymint-V1-ndk_platform", + "android.hardware.security.secureclock-V1-ndk_platform", "libcppbor_external", "libkeymint_vts_test_utils", ], @@ -60,8 +60,8 @@ cc_test_library { "libkeymint_support", ], static_libs: [ - "android.hardware.security.keymint-unstable-ndk_platform", - "android.hardware.security.secureclock-unstable-ndk_platform", + "android.hardware.security.keymint-V1-ndk_platform", + "android.hardware.security.secureclock-V1-ndk_platform", "libcppbor", ], } diff --git a/security/keymint/support/Android.bp b/security/keymint/support/Android.bp index 0cfa798344..fde6b57683 100644 --- a/security/keymint/support/Android.bp +++ b/security/keymint/support/Android.bp @@ -31,7 +31,7 @@ cc_library { "include", ], shared_libs: [ - "android.hardware.security.keymint-unstable-ndk_platform", + "android.hardware.security.keymint-V1-ndk_platform", "libbase", "libcrypto", "libutils", diff --git a/tests/extension/vibrator/aidl/client/Android.bp b/tests/extension/vibrator/aidl/client/Android.bp index b0d82382fa..108d000970 100644 --- a/tests/extension/vibrator/aidl/client/Android.bp +++ b/tests/extension/vibrator/aidl/client/Android.bp @@ -14,11 +14,11 @@ cc_test { shared_libs: [ "libbinder", "libutils", - "android.hardware.vibrator-cpp", - "android.hardware.tests.extension.vibrator-cpp", + "android.hardware.vibrator-V1-cpp", + "android.hardware.tests.extension.vibrator-V1-cpp", "libbinder_ndk", - "android.hardware.vibrator-ndk_platform", - "android.hardware.tests.extension.vibrator-ndk_platform", + "android.hardware.vibrator-V1-ndk_platform", + "android.hardware.tests.extension.vibrator-V1-ndk_platform", ], } diff --git a/tests/extension/vibrator/aidl/default/Android.bp b/tests/extension/vibrator/aidl/default/Android.bp index 80f7727646..2486588225 100644 --- a/tests/extension/vibrator/aidl/default/Android.bp +++ b/tests/extension/vibrator/aidl/default/Android.bp @@ -19,7 +19,7 @@ cc_binary { shared_libs: [ "libbase", "libbinder_ndk", - "android.hardware.vibrator-unstable-ndk_platform", - "android.hardware.tests.extension.vibrator-unstable-ndk_platform", + "android.hardware.vibrator-V2-ndk_platform", + "android.hardware.tests.extension.vibrator-V2-ndk_platform", ], } diff --git a/tests/msgq/1.0/default/Android.bp b/tests/msgq/1.0/default/Android.bp index a50206bb75..a0d6f31fd9 100644 --- a/tests/msgq/1.0/default/Android.bp +++ b/tests/msgq/1.0/default/Android.bp @@ -91,8 +91,8 @@ cc_test { // These are static libs only for testing purposes and portability. Shared // libs should be used on device. static_libs: [ - "android.hardware.common-unstable-ndk_platform", - "android.hardware.common.fmq-unstable-ndk_platform", + "android.hardware.common-V2-ndk_platform", + "android.hardware.common.fmq-V1-ndk_platform", "android.hardware.tests.msgq@1.0", "android.fmq.test-ndk_platform", ], diff --git a/vibrator/aidl/default/Android.bp b/vibrator/aidl/default/Android.bp index f9d45bb001..b44f11dc94 100644 --- a/vibrator/aidl/default/Android.bp +++ b/vibrator/aidl/default/Android.bp @@ -4,7 +4,7 @@ cc_library_static { shared_libs: [ "libbase", "libbinder_ndk", - "android.hardware.vibrator-unstable-ndk_platform", + "android.hardware.vibrator-V2-ndk_platform", ], export_include_dirs: ["include"], srcs: [ @@ -26,7 +26,7 @@ cc_binary { shared_libs: [ "libbase", "libbinder_ndk", - "android.hardware.vibrator-unstable-ndk_platform", + "android.hardware.vibrator-V2-ndk_platform", ], static_libs: [ "libvibratorexampleimpl", diff --git a/vibrator/aidl/vts/Android.bp b/vibrator/aidl/vts/Android.bp index d06b50efe3..b50b3f70be 100644 --- a/vibrator/aidl/vts/Android.bp +++ b/vibrator/aidl/vts/Android.bp @@ -9,7 +9,7 @@ cc_test { "libbinder", ], static_libs: [ - "android.hardware.vibrator-unstable-cpp", + "android.hardware.vibrator-V2-cpp", ], test_suites: [ "general-tests", @@ -28,7 +28,7 @@ cc_test { "libbinder", ], static_libs: [ - "android.hardware.vibrator-unstable-cpp", + "android.hardware.vibrator-V2-cpp", ], test_suites: [ "general-tests", diff --git a/vibrator/bench/Android.bp b/vibrator/bench/Android.bp index c7f824d75f..3d7bdc5084 100644 --- a/vibrator/bench/Android.bp +++ b/vibrator/bench/Android.bp @@ -20,7 +20,7 @@ cc_benchmark { "benchmark.cpp", ], shared_libs: [ - "android.hardware.vibrator-cpp", + "android.hardware.vibrator-V1-cpp", "android.hardware.vibrator@1.0", "android.hardware.vibrator@1.1", "android.hardware.vibrator@1.2", diff --git a/weaver/aidl/default/Android.bp b/weaver/aidl/default/Android.bp index d93682828f..8440670c27 100644 --- a/weaver/aidl/default/Android.bp +++ b/weaver/aidl/default/Android.bp @@ -25,7 +25,7 @@ cc_binary { "Weaver.cpp", ], shared_libs: [ - "android.hardware.weaver-ndk_platform", + "android.hardware.weaver-V1-ndk_platform", "libbase", "libbinder_ndk", ], diff --git a/weaver/aidl/vts/Android.bp b/weaver/aidl/vts/Android.bp index d7e3ab7a6e..7daad8d833 100644 --- a/weaver/aidl/vts/Android.bp +++ b/weaver/aidl/vts/Android.bp @@ -25,7 +25,7 @@ cc_test { "libbinder_ndk", "libbase", ], - static_libs: ["android.hardware.weaver-ndk_platform"], + static_libs: ["android.hardware.weaver-V1-ndk_platform"], test_suites: [ "general-tests", "vts", -- GitLab From b33c577722e30845227aed6a4104949e15e42f45 Mon Sep 17 00:00:00 2001 From: Yu-Han Yang Date: Wed, 27 Jan 2021 11:01:28 -0800 Subject: [PATCH 414/790] Add GNSS AIDL error codes Bug: 178060679 Test: on cuttlefish Change-Id: Iccb01bbb375ae204e0caabf674b285f27a82fbc3 --- .../hardware/gnss/BlocklistedSource.aidl | 16 +++++++++++++++- .../hardware/gnss/CorrelationVector.aidl | 16 +++++++++++++++- .../android/hardware/gnss/ElapsedRealtime.aidl | 16 +++++++++++++++- .../android/hardware/gnss/GnssClock.aidl | 16 +++++++++++++++- .../hardware/gnss/GnssConstellationType.aidl | 16 +++++++++++++++- .../android/hardware/gnss/GnssData.aidl | 16 +++++++++++++++- .../android/hardware/gnss/GnssMeasurement.aidl | 16 +++++++++++++++- .../hardware/gnss/GnssMultipathIndicator.aidl | 16 +++++++++++++++- .../android/hardware/gnss/GnssPowerStats.aidl | 16 +++++++++++++++- .../android/hardware/gnss/GnssSignalType.aidl | 16 +++++++++++++++- .../current/android/hardware/gnss/IGnss.aidl | 18 +++++++++++++++++- .../android/hardware/gnss/IGnssCallback.aidl | 16 +++++++++++++++- .../hardware/gnss/IGnssConfiguration.aidl | 16 +++++++++++++++- .../gnss/IGnssMeasurementCallback.aidl | 16 +++++++++++++++- .../gnss/IGnssMeasurementInterface.aidl | 16 +++++++++++++++- .../hardware/gnss/IGnssPowerIndication.aidl | 16 +++++++++++++++- .../gnss/IGnssPowerIndicationCallback.aidl | 16 +++++++++++++++- .../android/hardware/gnss/IGnssPsds.aidl | 16 +++++++++++++++- .../hardware/gnss/IGnssPsdsCallback.aidl | 16 +++++++++++++++- .../android/hardware/gnss/PsdsType.aidl | 16 +++++++++++++++- .../hardware/gnss/SatelliteClockInfo.aidl | 16 +++++++++++++++- .../hardware/gnss/SatellitePositionEcef.aidl | 16 +++++++++++++++- .../android/hardware/gnss/SatellitePvt.aidl | 16 +++++++++++++++- .../hardware/gnss/SatelliteVelocityEcef.aidl | 16 +++++++++++++++- gnss/aidl/android/hardware/gnss/IGnss.aidl | 6 ++++++ .../gnss/IGnssMeasurementInterface.aidl | 7 +++---- 26 files changed, 371 insertions(+), 28 deletions(-) diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/BlocklistedSource.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/BlocklistedSource.aidl index 03026761f8..11cdcfcc9a 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/BlocklistedSource.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/BlocklistedSource.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/CorrelationVector.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/CorrelationVector.aidl index 1f713fa4e0..2d21748564 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/CorrelationVector.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/CorrelationVector.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/ElapsedRealtime.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/ElapsedRealtime.aidl index 933f659c57..fbcc8a3ac7 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/ElapsedRealtime.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/ElapsedRealtime.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssClock.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssClock.aidl index 53ac0efa37..15fe2e9b57 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssClock.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssClock.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssConstellationType.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssConstellationType.aidl index 18fdfa91c2..f873b87d7f 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssConstellationType.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssConstellationType.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// 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 73ead10ff7..9e05db7bd1 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 @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMeasurement.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMeasurement.aidl index 3d287e4a1a..728ff68a28 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMeasurement.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMeasurement.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMultipathIndicator.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMultipathIndicator.aidl index 5da60f7a6e..b9db34382e 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMultipathIndicator.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMultipathIndicator.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssPowerStats.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssPowerStats.aidl index 358b570157..6676e2eb7c 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssPowerStats.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssPowerStats.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssSignalType.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssSignalType.aidl index b2a498d009..f729d4c2ec 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssSignalType.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssSignalType.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// 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 bd6f1ff34d..10b05a7ff1 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 @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// @@ -26,4 +40,6 @@ interface IGnss { android.hardware.gnss.IGnssMeasurementInterface getExtensionGnssMeasurement(); android.hardware.gnss.IGnssPowerIndication getExtensionGnssPowerIndication(); 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/IGnssCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl index a0c4255df2..9ad9159d67 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssConfiguration.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssConfiguration.aidl index eb4ad82653..20dd781466 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssConfiguration.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssConfiguration.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementCallback.aidl index 764b896955..93894bfd6a 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementCallback.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementCallback.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementInterface.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementInterface.aidl index 7cb7395c18..07a51aeb5d 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementInterface.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementInterface.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndication.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndication.aidl index c44903eadb..1cc7f7114a 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndication.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndication.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndicationCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndicationCallback.aidl index 12e6762d2b..01f91dc3de 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndicationCallback.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndicationCallback.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsds.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsds.aidl index cae2ea6432..175879245a 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsds.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsds.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsdsCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsdsCallback.aidl index 6888632fa2..a1af1057ef 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsdsCallback.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsdsCallback.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/PsdsType.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/PsdsType.aidl index d348c633d0..b387121d5b 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/PsdsType.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/PsdsType.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatelliteClockInfo.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatelliteClockInfo.aidl index bdba6673ea..4dd45b2af7 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatelliteClockInfo.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatelliteClockInfo.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatellitePositionEcef.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatellitePositionEcef.aidl index 550fa4dbe9..c96b2e5344 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatellitePositionEcef.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatellitePositionEcef.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatellitePvt.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatellitePvt.aidl index 4ff025eff8..95af1524b3 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatellitePvt.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatellitePvt.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatelliteVelocityEcef.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatelliteVelocityEcef.aidl index 7db7ee6b5d..558aec992d 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatelliteVelocityEcef.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatelliteVelocityEcef.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/gnss/aidl/android/hardware/gnss/IGnss.aidl b/gnss/aidl/android/hardware/gnss/IGnss.aidl index c815e2dc93..f99b512c5f 100644 --- a/gnss/aidl/android/hardware/gnss/IGnss.aidl +++ b/gnss/aidl/android/hardware/gnss/IGnss.aidl @@ -34,6 +34,12 @@ interface IGnss { */ const int ERROR_INVALID_ARGUMENT = 1; + /** A callback has already been registered. */ + const int ERROR_ALREADY_INIT = 2; + + /** Any other error. */ + const int ERROR_GENERIC = 3; + /** * Opens the interface and provides the callback routines to the implementation of this * interface. diff --git a/gnss/aidl/android/hardware/gnss/IGnssMeasurementInterface.aidl b/gnss/aidl/android/hardware/gnss/IGnssMeasurementInterface.aidl index 04cdf6417b..08c83a42e7 100644 --- a/gnss/aidl/android/hardware/gnss/IGnssMeasurementInterface.aidl +++ b/gnss/aidl/android/hardware/gnss/IGnssMeasurementInterface.aidl @@ -40,10 +40,9 @@ interface IGnssMeasurementInterface { * @param enableCorrVecOutputs If true, enable correlation vectors as part of the raw GNSS * measurements outputs. If false, disable correlation vectors. * - * @return initRet Returns SUCCESS if successful. Returns ERROR_ALREADY_INIT if a callback has - * already been registered without a corresponding call to 'close'. Returns ERROR_GENERIC - * for any other error. The HAL must not generate any other updates upon returning this - * error code. + * Returns ok() if successful. Returns ERROR_ALREADY_INIT if a callback has already been + * registered without a corresponding call to 'close'. Returns ERROR_GENERIC for any other + * error. The HAL must not generate any other updates upon returning this error code. */ void setCallback(in IGnssMeasurementCallback callback, in boolean enableFullTracking, in boolean enableCorrVecOutputs); -- GitLab From 226b119451674f9188c5c25b36e931bc7dd15eb7 Mon Sep 17 00:00:00 2001 From: jiabin Date: Wed, 27 Jan 2021 19:16:26 +0000 Subject: [PATCH 415/790] Add MPEG-H enum. MPEG-H is a new surround audio codec. Add new enum format for MPEG-H in the HIDL interface. Though MPEG-H has different profiles and audio levels, only low complexity and baseline with audio level as 3 and 4 is defined in this CL as they are relevant for the current and upcoming commercial services. Bug: 178619392 Test: make Change-Id: I5672f3874f6cffe31a83b6d7e351d0bf56bfd038 --- audio/7.0/config/api/current.txt | 4 ++++ audio/7.0/config/audio_policy_configuration.xsd | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/audio/7.0/config/api/current.txt b/audio/7.0/config/api/current.txt index 0b2e4a4d85..2e2e4780a9 100644 --- a/audio/7.0/config/api/current.txt +++ b/audio/7.0/config/api/current.txt @@ -222,6 +222,10 @@ package android.audio.policy.configuration.V7_0 { enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_MAT_2_1; enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_MP2; enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_MP3; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_MPEGH_BL_L3; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_MPEGH_BL_L4; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_MPEGH_LC_L3; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_MPEGH_LC_L4; enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_OPUS; enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_PCM_16_BIT; enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_PCM_24_BIT_PACKED; diff --git a/audio/7.0/config/audio_policy_configuration.xsd b/audio/7.0/config/audio_policy_configuration.xsd index a735c6de39..b90693c0bf 100644 --- a/audio/7.0/config/audio_policy_configuration.xsd +++ b/audio/7.0/config/audio_policy_configuration.xsd @@ -407,6 +407,10 @@ + + + + -- GitLab From c9b5693c7f024a6b0c7fc59123dbc313ecbf6e9b Mon Sep 17 00:00:00 2001 From: Edwin Wong Date: Tue, 26 Jan 2021 20:29:25 -0800 Subject: [PATCH 416/790] Fix potential decrypt src pointer overflow. There is a potential integer overflow to bypass the source base size check in decrypt. The source pointer can then point to the outside of the source buffer, which could potentially leak arbitrary memory content to destination pointer. Test: sts-tradefed sts-tradefed run sts-engbuild-no-spl-lock -m StsHostTestCases --test android.security.sts.Bug_176496160#testPocBug_176496160 Test: push to device with target_hwasan-userdebug build adb shell /data/local/tmp/Bug-17649616064 Bug: 176496160 Bug: 176444786 Change-Id: I811a6f60948bde2a72906c2c6172fd7bc5feb6d9 --- drm/1.0/default/CryptoPlugin.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drm/1.0/default/CryptoPlugin.cpp b/drm/1.0/default/CryptoPlugin.cpp index 19666f53a8..e60ba8f54d 100644 --- a/drm/1.0/default/CryptoPlugin.cpp +++ b/drm/1.0/default/CryptoPlugin.cpp @@ -125,7 +125,11 @@ namespace implementation { return Void(); } - if (source.offset + offset + source.size > sourceBase->getSize()) { + size_t totalSize = 0; + if (__builtin_add_overflow(source.offset, offset, &totalSize) || + __builtin_add_overflow(totalSize, source.size, &totalSize) || + totalSize > sourceBase->getSize()) { + android_errorWriteLog(0x534e4554, "176496160"); _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size"); return Void(); } -- GitLab From 072cdf233c02d1dc3eb8b2e20498675aea70c21d Mon Sep 17 00:00:00 2001 From: Edwin Wong Date: Wed, 27 Jan 2021 20:19:32 -0800 Subject: [PATCH 417/790] [RESTRICT AUTOMERGE] Fix potential decrypt srcPtr overflow. There is a potential integer overflow to bypass the source base size check in decrypt. The source pointer can then point to the outside of the source buffer, which could potentially leak arbitrary memory content to destination pointer. Test: sts-tradefed sts-tradefed run sts-engbuild-no-spl-lock -m StsHostTestCases --test android.security.sts.Bug_176496160#testPocBug_176496160 Test: push to device with target_hwasan-userdebug build adb shell /data/local/tmp/Bug-17649616064 Bug: 176496160 Bug: 176444786 Change-Id: I5ed8921cbd7120e2f3841de1ea7b73d33539838f --- drm/1.0/default/CryptoPlugin.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drm/1.0/default/CryptoPlugin.cpp b/drm/1.0/default/CryptoPlugin.cpp index b86260342f..2a85f0e3d3 100644 --- a/drm/1.0/default/CryptoPlugin.cpp +++ b/drm/1.0/default/CryptoPlugin.cpp @@ -127,7 +127,11 @@ namespace implementation { return Void(); } - if (source.offset + offset + source.size > sourceBase->getSize()) { + size_t totalSize = 0; + if (__builtin_add_overflow(source.offset, offset, &totalSize) || + __builtin_add_overflow(totalSize, source.size, &totalSize) || + totalSize > sourceBase->getSize()) { + android_errorWriteLog(0x534e4554, "176496160"); _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size"); return Void(); } -- GitLab From b305c80409dd967622fd45ee7762f12ce654b4e1 Mon Sep 17 00:00:00 2001 From: bohu Date: Sat, 30 Jan 2021 19:14:05 -0800 Subject: [PATCH 418/790] mediacas: make it also work on 64bit only guest BUG: 178885191 Change-Id: I15d711dee366f7c39d6a89aecf34c9503bf32da8 --- cas/1.0/default/Android.bp | 2 +- cas/1.0/default/FactoryLoader.h | 10 ++++++++++ cas/1.1/default/Android.bp | 2 +- cas/1.1/default/FactoryLoader.h | 8 ++++++++ cas/1.2/default/Android.bp | 2 +- cas/1.2/default/FactoryLoader.h | 8 ++++++++ 6 files changed, 29 insertions(+), 3 deletions(-) diff --git a/cas/1.0/default/Android.bp b/cas/1.0/default/Android.bp index f9977ff7be..70f4371e0b 100644 --- a/cas/1.0/default/Android.bp +++ b/cas/1.0/default/Android.bp @@ -12,7 +12,7 @@ cc_defaults { "TypeConvert.cpp", ], - compile_multilib: "32", + compile_multilib: "prefer32", shared_libs: [ "android.hardware.cas@1.0", diff --git a/cas/1.0/default/FactoryLoader.h b/cas/1.0/default/FactoryLoader.h index 18c2186dcb..45e515afbf 100644 --- a/cas/1.0/default/FactoryLoader.h +++ b/cas/1.0/default/FactoryLoader.h @@ -92,7 +92,12 @@ bool FactoryLoader::findFactoryForScheme( } // no luck, have to search +#ifdef __LP64__ + String8 dirPath("/vendor/lib64/mediacas"); +#else String8 dirPath("/vendor/lib/mediacas"); +#endif + DIR* pDir = opendir(dirPath.string()); if (pDir == NULL) { @@ -127,7 +132,12 @@ bool FactoryLoader::enumeratePlugins( results->clear(); +#ifdef __LP64__ + String8 dirPath("/vendor/lib64/mediacas"); +#else String8 dirPath("/vendor/lib/mediacas"); +#endif + DIR* pDir = opendir(dirPath.string()); if (pDir == NULL) { diff --git a/cas/1.1/default/Android.bp b/cas/1.1/default/Android.bp index 66a1eb8804..8e1f20772d 100644 --- a/cas/1.1/default/Android.bp +++ b/cas/1.1/default/Android.bp @@ -12,7 +12,7 @@ cc_defaults { "TypeConvert.cpp", ], - compile_multilib: "32", + compile_multilib: "prefer32", shared_libs: [ "android.hardware.cas@1.0", diff --git a/cas/1.1/default/FactoryLoader.h b/cas/1.1/default/FactoryLoader.h index c4a48e2852..121f90c333 100644 --- a/cas/1.1/default/FactoryLoader.h +++ b/cas/1.1/default/FactoryLoader.h @@ -85,7 +85,11 @@ bool FactoryLoader::findFactoryForScheme(int32_t CA_system_id, sp::enumeratePlugins(vector* results results->clear(); +#ifdef __LP64__ + String8 dirPath("/vendor/lib64/mediacas"); +#else String8 dirPath("/vendor/lib/mediacas"); +#endif DIR* pDir = opendir(dirPath.string()); if (pDir == NULL) { diff --git a/cas/1.2/default/Android.bp b/cas/1.2/default/Android.bp index 9e5314874f..d855e85a67 100644 --- a/cas/1.2/default/Android.bp +++ b/cas/1.2/default/Android.bp @@ -12,7 +12,7 @@ cc_defaults { "TypeConvert.cpp", ], - compile_multilib: "32", + compile_multilib: "prefer32", shared_libs: [ "android.hardware.cas@1.0", diff --git a/cas/1.2/default/FactoryLoader.h b/cas/1.2/default/FactoryLoader.h index 7403f86ac9..a374b31891 100644 --- a/cas/1.2/default/FactoryLoader.h +++ b/cas/1.2/default/FactoryLoader.h @@ -85,7 +85,11 @@ bool FactoryLoader::findFactoryForScheme(int32_t CA_system_id, sp::enumeratePlugins(vector* results results->clear(); +#ifdef __LP64__ + String8 dirPath("/vendor/lib64/mediacas"); +#else String8 dirPath("/vendor/lib/mediacas"); +#endif DIR* pDir = opendir(dirPath.string()); if (pDir == NULL) { -- GitLab From 5bd43606ee90ee1600692aa5fbd779f68860229c Mon Sep 17 00:00:00 2001 From: Hongbo Zeng Date: Thu, 21 Jan 2021 17:23:45 +0800 Subject: [PATCH 419/790] Update HAL 1.6 for 5G Slicing - add trafficDescriptor and matchAllRuleAllowed to setupDataCall - add trafficDescriptors to SetupDataCallResult - create structs TrafficDescriptor and OSAppId base on the definition in TS 24.526 Section 5.2 - add MATCH_ALL_RULE_NOT_ALLOWED and ALL_MATCHING_RULES_FAILED as DataCallFailCause Bug: 178075054 Test: make VtsHalRadioV1_6TargetTest Change-Id: Ibf6d92d50c8c2c3fce51522677d75bf33127320f --- radio/1.6/IRadio.hal | 15 +++- radio/1.6/types.hal | 71 ++++++++++++++++ .../1.6/vts/functional/radio_hidl_hal_api.cpp | 83 ++++++++++++++++++- .../functional/radio_hidl_hal_utils_v1_6.h | 1 + radio/1.6/vts/functional/radio_response.cpp | 3 +- 5 files changed, 170 insertions(+), 3 deletions(-) diff --git a/radio/1.6/IRadio.hal b/radio/1.6/IRadio.hal index 1862800f5e..e770a5d26c 100644 --- a/radio/1.6/IRadio.hal +++ b/radio/1.6/IRadio.hal @@ -120,6 +120,18 @@ interface IRadio extends @1.5::IRadio { * @param sliceInfo SliceInfo to be used for the data connection when a handover occurs from * EPDG to 5G. It is valid only when accessNetwork is AccessNetwork:NGRAN. If the slice * passed from EPDG is rejected, then the data failure cause must be DataCallFailCause:SLICE_REJECTED. + * @param trafficDescriptor TrafficDescriptor for which data connection needs to be + * established. It is used for URSP traffic matching as described in TS 24.526 + * Section 4.2.2. It includes an optional DNN which, if present, must be used for traffic + * matching -- it does not specify the end point to be used for the data call. The end + * point is specified by DataProfileInfo.apn; DataProfileInfo.apn must be used as the end + * point if one is not specified through URSP rules. + * @param matchAllRuleAllowed bool to indicate if using default match-all URSP rule for this + * request is allowed. If false, this request must not use the match-all URSP rule and if + * a non-match-all rule is not found (or if URSP rules are not available) it should return + * failure with cause DataCallFailCause:MATCH_ALL_RULE_NOT_ALLOWED. This is needed as some + * requests need to have a hard failure if the intention cannot be met, for example, a + * zero-rating slice. * * Response function is IRadioResponse.setupDataCallResponse_1_6() * @@ -128,7 +140,8 @@ interface IRadio extends @1.5::IRadio { oneway setupDataCall_1_6(int32_t serial, AccessNetwork accessNetwork, DataProfileInfo dataProfileInfo, bool roamingAllowed, DataRequestReason reason, vec addresses, vec dnses, - int32_t pduSessionId, OptionalSliceInfo sliceInfo); + int32_t pduSessionId, OptionalSliceInfo sliceInfo, + OptionalTrafficDescriptor trafficDescriptor, bool matchAllRuleAllowed); /** * Send an SMS message diff --git a/radio/1.6/types.hal b/radio/1.6/types.hal index 4eaf7be821..a6de033d20 100644 --- a/radio/1.6/types.hal +++ b/radio/1.6/types.hal @@ -365,6 +365,13 @@ struct SetupDataCallResult { * AccessNetwork:NGRAN. */ OptionalSliceInfo sliceInfo; + + /** + * TrafficDescriptors for which this data call must be used. It only includes + * the TDs for which a data call has been requested so far; it is not an + * exhaustive list. + */ + vec trafficDescriptors; }; /** @@ -824,6 +831,16 @@ enum DataCallFailCause : @1.4::DataCallFailCause { * Data call fail due to the slice not being allowed for the data call. */ SLICE_REJECTED = 0x8CC, + + /** + * No matching rule available for the request, and match-all rule is not allowed for it. + */ + MATCH_ALL_RULE_NOT_ALLOWED = 0x8CD, + + /** + * If connection failed for all matching URSP rules + */ + ALL_MATCHING_RULES_FAILED = 0x8CE, }; struct PhysicalChannelConfig { @@ -892,3 +909,57 @@ enum NgranBands : @1.5::NgranBands { BAND_53 = 53, BAND_96 = 96, }; + +/** + * This safe_union represents an optional DNN. DNN stands for Data Network Name + * and represents an APN as defined in 3GPP TS 23.003. + */ +safe_union OptionalDNN { + Monostate noinit; + string value; +}; + +/** + * This safe_union represents an optional OSAppId. + */ +safe_union OptionalOSAppId { + Monostate noinit; + OSAppId value; +}; + +/** + * This safe_union represents an optional TrafficDescriptor. + */ +safe_union OptionalTrafficDescriptor { + Monostate noinit; + TrafficDescriptor value; +}; + +/** + * This struct represents a traffic descriptor. A valid struct must have at least + * one of the optional values present. This is based on the definition of traffic + * descriptor in TS 24.526 Section 5.2. + */ +struct TrafficDescriptor { + /** + * DNN stands for Data Network Name and represents an APN as defined in + * 3GPP TS 23.003. + */ + OptionalDNN dnn; + /** + * Indicates the OSId + OSAppId (used as category in Android). + */ + OptionalOSAppId osAppId; +}; + +/** + * This struct represents the OSId + OSAppId as defined in TS 24.526 Section 5.2 + */ +struct OSAppId { + /** + * Byte array representing OSId + OSAppId. The minimum length of the array is + * 18 and maximum length is 272 (16 bytes for OSId + 1 byte for OSAppId length + * + up to 255 bytes for OSAppId). + */ + vec osAppId; +}; diff --git a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp index 8b872921ec..2acec4606d 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp +++ b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp @@ -59,9 +59,88 @@ TEST_P(RadioHidlTest_v1_6, setupDataCall_1_6) { ::android::hardware::radio::V1_6::OptionalSliceInfo optionalSliceInfo; memset(&optionalSliceInfo, 0, sizeof(optionalSliceInfo)); + ::android::hardware::radio::V1_6::OptionalTrafficDescriptor optionalTrafficDescriptor; + memset(&optionalTrafficDescriptor, 0, sizeof(optionalTrafficDescriptor)); + + bool matchAllRuleAllowed = true; + + Return res = + radio_v1_6->setupDataCall_1_6(serial, accessNetwork, dataProfileInfo, roamingAllowed, + reason, addresses, dnses, -1, optionalSliceInfo, + optionalTrafficDescriptor, matchAllRuleAllowed); + ASSERT_OK(res); + + EXPECT_EQ(std::cv_status::no_timeout, wait()); + EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type); + EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial); + if (cardStatus.base.base.base.cardState == CardState::ABSENT) { + ASSERT_TRUE(CheckAnyOfErrors( + radioRsp_v1_6->rspInfo.error, + {::android::hardware::radio::V1_6::RadioError::SIM_ABSENT, + ::android::hardware::radio::V1_6::RadioError::RADIO_NOT_AVAILABLE, + ::android::hardware::radio::V1_6::RadioError::OP_NOT_ALLOWED_BEFORE_REG_TO_NW})); + } else if (cardStatus.base.base.base.cardState == CardState::PRESENT) { + ASSERT_TRUE(CheckAnyOfErrors( + radioRsp_v1_6->rspInfo.error, + {::android::hardware::radio::V1_6::RadioError::NONE, + ::android::hardware::radio::V1_6::RadioError::RADIO_NOT_AVAILABLE, + ::android::hardware::radio::V1_6::RadioError::OP_NOT_ALLOWED_BEFORE_REG_TO_NW})); + } +} + +TEST_P(RadioHidlTest_v1_6, setupDataCall_1_6_osAppId) { + serial = GetRandomSerialNumber(); + + ::android::hardware::radio::V1_5::AccessNetwork accessNetwork = + ::android::hardware::radio::V1_5::AccessNetwork::EUTRAN; + + android::hardware::radio::V1_5::DataProfileInfo dataProfileInfo; + memset(&dataProfileInfo, 0, sizeof(dataProfileInfo)); + dataProfileInfo.profileId = DataProfileId::DEFAULT; + dataProfileInfo.apn = hidl_string("internet"); + dataProfileInfo.protocol = PdpProtocolType::IP; + dataProfileInfo.roamingProtocol = PdpProtocolType::IP; + dataProfileInfo.authType = ApnAuthType::NO_PAP_NO_CHAP; + dataProfileInfo.user = hidl_string("username"); + dataProfileInfo.password = hidl_string("password"); + dataProfileInfo.type = DataProfileInfoType::THREE_GPP; + dataProfileInfo.maxConnsTime = 300; + dataProfileInfo.maxConns = 20; + dataProfileInfo.waitTime = 0; + dataProfileInfo.enabled = true; + dataProfileInfo.supportedApnTypesBitmap = 320; + dataProfileInfo.bearerBitmap = 161543; + dataProfileInfo.mtuV4 = 0; + dataProfileInfo.mtuV6 = 0; + dataProfileInfo.preferred = true; + dataProfileInfo.persistent = false; + + bool roamingAllowed = false; + + std::vector<::android::hardware::radio::V1_5::LinkAddress> addresses = {}; + std::vector dnses = {}; + + ::android::hardware::radio::V1_2::DataRequestReason reason = + ::android::hardware::radio::V1_2::DataRequestReason::NORMAL; + + ::android::hardware::radio::V1_6::OptionalSliceInfo optionalSliceInfo; + memset(&optionalSliceInfo, 0, sizeof(optionalSliceInfo)); + + ::android::hardware::radio::V1_6::OptionalTrafficDescriptor optionalTrafficDescriptor; + memset(&optionalTrafficDescriptor, 0, sizeof(optionalTrafficDescriptor)); + + ::android::hardware::radio::V1_6::TrafficDescriptor trafficDescriptor; + ::android::hardware::radio::V1_6::OSAppId osAppId; + osAppId.osAppId = 1; + trafficDescriptor.osAppId.value(osAppId); + optionalTrafficDescriptor.value(trafficDescriptor); + + bool matchAllRuleAllowed = true; + Return res = radio_v1_6->setupDataCall_1_6(serial, accessNetwork, dataProfileInfo, roamingAllowed, - reason, addresses, dnses, -1, optionalSliceInfo); + reason, addresses, dnses, -1, optionalSliceInfo, + optionalTrafficDescriptor, matchAllRuleAllowed); ASSERT_OK(res); EXPECT_EQ(std::cv_status::no_timeout, wait()); @@ -79,6 +158,8 @@ TEST_P(RadioHidlTest_v1_6, setupDataCall_1_6) { {::android::hardware::radio::V1_6::RadioError::NONE, ::android::hardware::radio::V1_6::RadioError::RADIO_NOT_AVAILABLE, ::android::hardware::radio::V1_6::RadioError::OP_NOT_ALLOWED_BEFORE_REG_TO_NW})); + EXPECT_EQ(optionalTrafficDescriptor.value().osAppId.value().osAppId, + radioRsp_v1_6->setupDataCallResult.trafficDescriptors[0].osAppId.value().osAppId); } } diff --git a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h index 334fec3622..ba2a359c2d 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h +++ b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h @@ -88,6 +88,7 @@ class RadioResponse_v1_6 : public ::android::hardware::radio::V1_6::IRadioRespon // Data ::android::hardware::radio::V1_4::DataRegStateResult dataRegResp; + ::android::hardware::radio::V1_6::SetupDataCallResult setupDataCallResult; // SimLock status ::android::hardware::radio::V1_4::CarrierRestrictionsWithPriority carrierRestrictionsResp; diff --git a/radio/1.6/vts/functional/radio_response.cpp b/radio/1.6/vts/functional/radio_response.cpp index 100fabd828..1104328c52 100644 --- a/radio/1.6/vts/functional/radio_response.cpp +++ b/radio/1.6/vts/functional/radio_response.cpp @@ -1050,8 +1050,9 @@ Return RadioResponse_v1_6::setRadioPowerResponse_1_6( Return RadioResponse_v1_6::setupDataCallResponse_1_6( const ::android::hardware::radio::V1_6::RadioResponseInfo& info, - const android::hardware::radio::V1_6::SetupDataCallResult& /* dcResponse */) { + const android::hardware::radio::V1_6::SetupDataCallResult& dcResponse) { rspInfo = info; + setupDataCallResult = dcResponse; parent_v1_6.notify(info.serial); return Void(); } -- GitLab From 2a630a3817beca855bf5bc2e45c32ea29b00b6a3 Mon Sep 17 00:00:00 2001 From: Kumar Anand Date: Thu, 21 Jan 2021 14:09:14 -0800 Subject: [PATCH 420/790] Wifi: HAL API to query the list of usable channels API can be used to query what modes (SAP, STA, WFD Client, WFD Group Owner, TDLS, NAN) can be supported on each channel for specified band. Needs support from Wifi chip vendors. Bug: 160212907 Test: VTS - VtsHalWifiV1_5TargetTest Change-Id: Icf270b8c2ee14c794778421c9d988712c5c38380 --- wifi/1.5/IWifiChip.hal | 29 +++++ wifi/1.5/default/hidl_struct_util.cpp | 123 ++++++++++++++++++ wifi/1.5/default/hidl_struct_util.h | 5 + wifi/1.5/default/wifi_chip.cpp | 27 ++++ wifi/1.5/default/wifi_chip.h | 5 + wifi/1.5/default/wifi_legacy_hal.cpp | 14 ++ wifi/1.5/default/wifi_legacy_hal.h | 106 ++++++++------- wifi/1.5/default/wifi_legacy_hal_stubs.cpp | 1 + wifi/1.5/types.hal | 60 +++++++++ .../vts/functional/wifi_chip_hidl_test.cpp | 18 +++ 10 files changed, 342 insertions(+), 46 deletions(-) diff --git a/wifi/1.5/IWifiChip.hal b/wifi/1.5/IWifiChip.hal index b2960cfa7a..209190a759 100644 --- a/wifi/1.5/IWifiChip.hal +++ b/wifi/1.5/IWifiChip.hal @@ -234,4 +234,33 @@ interface IWifiChip extends @1.4::IWifiChip { * |WifiStatusCode.FAILURE_IFACE_INVALID| */ setCountryCode(int8_t[2] code) generates (WifiStatus status); + + /** + * Retrieve list of usable Wifi channels for the specified band & + * operational modes. + * + * The list of usable Wifi channels in a given band depends on factors + * like current country code, operational mode (e.g. STA, SAP, CLI, GO, + * TDLS, NAN) and any hard restrictons due to DFS, LTE Coex and + * MCC(multi channel-concurrency). + * + * @param band |WifiBand| for which list of usable channels is requested. + * @param ifaceModeMask Bitmask of the modes represented by |WifiIfaceMode| + * Bitmask respresents all the modes that the caller is interested + * in (e.g. STA, SAP, CLI, GO, TDLS, NAN). + * Note: Bitmask does not represent concurrency matrix. + * @return status WifiStatus of the operation. + * Possible status codes: + * |WifiStatusCode.SUCCESS|, + * |WifiStatusCode.ERROR_NOT_SUPPORTED|, + * |WifiStatusCode.ERROR_INVALID_ARGS|, + * |WifiStatusCode.FAILURE_UNKNOWN| + * @return channels List of channels represented by |WifiUsableChannel| + * Each entry represents a channel frequency, bandwidth and + * bitmask of operational modes (e.g. STA, SAP, CLI, GO, TDLS, NAN) + * allowed on that channel. + * Note: Bitmask does not represent concurrency matrix. + */ + getUsableChannels(WifiBand band, bitfield ifaceModeMask) + generates (WifiStatus status, vec channels); }; diff --git a/wifi/1.5/default/hidl_struct_util.cpp b/wifi/1.5/default/hidl_struct_util.cpp index 8e2e647cc5..7cee4cd868 100644 --- a/wifi/1.5/default/hidl_struct_util.cpp +++ b/wifi/1.5/default/hidl_struct_util.cpp @@ -356,6 +356,129 @@ bool convertLegacyWifiMacInfoToHidl( return true; } +uint32_t convertHidlWifiBandToLegacyMacBand(V1_5::WifiBand hidl_band) { + switch (hidl_band) { + case V1_5::WifiBand::BAND_24GHZ: + return legacy_hal::WLAN_MAC_2_4_BAND; + case V1_5::WifiBand::BAND_5GHZ: + case V1_5::WifiBand::BAND_5GHZ_DFS: + case V1_5::WifiBand::BAND_5GHZ_WITH_DFS: + 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); + 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); + 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 | + 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); + } +} + +uint32_t convertHidlWifiIfaceModeToLegacy(uint32_t hidl_iface_mask) { + uint32_t legacy_iface_mask = 0; + if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_STA) { + legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_STA); + } + if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_SOFTAP) { + legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_SOFTAP); + } + if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_P2P_CLIENT) { + legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_P2P_CLIENT); + } + if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_P2P_GO) { + legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_P2P_GO); + } + if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_NAN) { + legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_NAN); + } + if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_TDLS) { + legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_TDLS); + } + if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_MESH) { + legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_MESH); + } + if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_IBSS) { + legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_IBSS); + } + return legacy_iface_mask; +} + +uint32_t convertLegacyWifiInterfaceModeToHidl(uint32_t legacy_iface_mask) { + uint32_t hidl_iface_mask = 0; + if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_STA)) { + hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_STA; + } + if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_SOFTAP)) { + hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_SOFTAP; + } + if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_P2P_CLIENT)) { + hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_P2P_CLIENT; + } + if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_P2P_GO)) { + hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_P2P_GO; + } + if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_NAN)) { + hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_NAN; + } + if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_TDLS)) { + hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_TDLS; + } + if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_MESH)) { + hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_MESH; + } + if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_IBSS)) { + hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_IBSS; + } + return hidl_iface_mask; +} + +bool convertLegacyWifiUsableChannelToHidl( + 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); + + return true; +} + +bool convertLegacyWifiUsableChannelsToHidl( + const std::vector& legacy_usable_channels, + std::vector* 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)) { + return false; + } + hidl_usable_channels->push_back(hidl_usable_channel); + } + return true; +} + bool convertLegacyWifiMacInfosToHidl( const std::vector& legacy_mac_infos, std::vector* diff --git a/wifi/1.5/default/hidl_struct_util.h b/wifi/1.5/default/hidl_struct_util.h index feb47ef7ab..c0d7bf8f0c 100644 --- a/wifi/1.5/default/hidl_struct_util.h +++ b/wifi/1.5/default/hidl_struct_util.h @@ -206,6 +206,11 @@ bool convertLegacyRttCapabilitiesToHidl( bool convertLegacyVectorOfRttResultToHidl( const std::vector& legacy_results, std::vector* hidl_results); +uint32_t convertHidlWifiBandToLegacyMacBand(V1_5::WifiBand band); +uint32_t convertHidlWifiIfaceModeToLegacy(uint32_t hidl_iface_mask); +bool convertLegacyWifiUsableChannelsToHidl( + const std::vector& legacy_usable_channels, + std::vector* hidl_usable_channels); } // namespace hidl_struct_util } // namespace implementation } // namespace V1_5 diff --git a/wifi/1.5/default/wifi_chip.cpp b/wifi/1.5/default/wifi_chip.cpp index 414d74c088..92acfd22f8 100644 --- a/wifi/1.5/default/wifi_chip.cpp +++ b/wifi/1.5/default/wifi_chip.cpp @@ -738,6 +738,14 @@ Return WifiChip::setCountryCode(const hidl_array& code, code); } +Return WifiChip::getUsableChannels( + WifiBand band, hidl_bitfield ifaceModeMask, + getUsableChannels_cb _hidl_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::getUsableChannelsInternal, _hidl_cb, band, + ifaceModeMask); +} + void WifiChip::invalidateAndRemoveAllIfaces() { invalidateAndClearBridgedApAll(); invalidateAndClearAll(ap_ifaces_); @@ -1490,6 +1498,25 @@ WifiStatus WifiChip::setCountryCodeInternal(const std::array& code) { return createWifiStatusFromLegacyError(legacy_status); } +std::pair> +WifiChip::getUsableChannelsInternal(WifiBand band, uint32_t ifaceModeMask) { + legacy_hal::wifi_error legacy_status; + std::vector legacy_usable_channels; + std::tie(legacy_status, legacy_usable_channels) = + legacy_hal_.lock()->getUsableChannels( + hidl_struct_util::convertHidlWifiBandToLegacyMacBand(band), + hidl_struct_util::convertHidlWifiIfaceModeToLegacy(ifaceModeMask)); + if (legacy_status != legacy_hal::WIFI_SUCCESS) { + return {createWifiStatusFromLegacyError(legacy_status), {}}; + } + std::vector 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}; +} + WifiStatus WifiChip::handleChipConfiguration( /* NONNULL */ std::unique_lock* lock, ChipModeId mode_id) { diff --git a/wifi/1.5/default/wifi_chip.h b/wifi/1.5/default/wifi_chip.h index 7d7a9b546c..d542792cda 100644 --- a/wifi/1.5/default/wifi_chip.h +++ b/wifi/1.5/default/wifi_chip.h @@ -180,6 +180,9 @@ class WifiChip : public V1_5::IWifiChip { setCoexUnsafeChannels_cb hidl_status_cb) override; Return setCountryCode(const hidl_array& code, setCountryCode_cb _hidl_cb) override; + Return getUsableChannels(WifiBand band, + hidl_bitfield ifaceModeMask, + getUsableChannels_cb _hidl_cb) override; private: void invalidateAndRemoveAllIfaces(); @@ -261,6 +264,8 @@ class WifiChip : public V1_5::IWifiChip { WifiStatus setCoexUnsafeChannelsInternal( std::vector unsafe_channels, uint32_t restrictions); WifiStatus setCountryCodeInternal(const std::array& code); + std::pair> + getUsableChannelsInternal(WifiBand band, uint32_t ifaceModeMask); WifiStatus handleChipConfiguration( std::unique_lock* lock, ChipModeId mode_id); WifiStatus registerDebugRingBufferCallback(); diff --git a/wifi/1.5/default/wifi_legacy_hal.cpp b/wifi/1.5/default/wifi_legacy_hal.cpp index 3e65ee0f25..94603b3053 100644 --- a/wifi/1.5/default/wifi_legacy_hal.cpp +++ b/wifi/1.5/default/wifi_legacy_hal.cpp @@ -36,6 +36,7 @@ static constexpr uint32_t kMaxGscanFrequenciesForBand = 64; static constexpr uint32_t kLinkLayerStatsDataMpduSizeThreshold = 128; static constexpr uint32_t kMaxWakeReasonStatsArraySize = 32; static constexpr uint32_t kMaxRingBuffers = 10; +static constexpr uint32_t kMaxWifiUsableChannels = 256; // need a long timeout (1000ms) for chips that unload their driver. static constexpr uint32_t kMaxStopCompleteWaitMs = 1000; static constexpr char kDriverPropName[] = "wlan.driver.status"; @@ -1636,6 +1637,19 @@ wifi_error WifiLegacyHal::setDtimConfig(const std::string& iface_name, multiplier); } +std::pair> +WifiLegacyHal::getUsableChannels(uint32_t band_mask, uint32_t iface_mode_mask) { + std::vector 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, channels.size(), &size, + reinterpret_cast(channels.data())); + CHECK(size >= 0 && size <= kMaxWifiUsableChannels); + channels.resize(size); + return {status, std::move(channels)}; +} + void WifiLegacyHal::invalidate() { global_handle_ = nullptr; iface_name_to_handle_.clear(); diff --git a/wifi/1.5/default/wifi_legacy_hal.h b/wifi/1.5/default/wifi_legacy_hal.h index 0cc1cff8cf..dc641aef28 100644 --- a/wifi/1.5/default/wifi_legacy_hal.h +++ b/wifi/1.5/default/wifi_legacy_hal.h @@ -36,9 +36,13 @@ namespace implementation { namespace legacy_hal { // Import all the types defined inside the legacy HAL header files into this // namespace. +using ::frame_info; +using ::frame_type; using ::FRAME_TYPE_80211_MGMT; using ::FRAME_TYPE_ETHERNET_II; using ::FRAME_TYPE_UNKNOWN; +using ::fw_roaming_state_t; +using ::mac_addr; using ::NAN_CHANNEL_24G_BAND; using ::NAN_CHANNEL_5G_BAND_HIGH; using ::NAN_CHANNEL_5G_BAND_LOW; @@ -80,8 +84,6 @@ using ::NAN_RESPONSE_SUBSCRIBE_CANCEL; using ::NAN_RESPONSE_TCA; using ::NAN_RESPONSE_TRANSMIT_FOLLOWUP; using ::NAN_SECURITY_KEY_INPUT_PASSPHRASE; -using ::NAN_SECURITY_KEY_INPUT_PASSPHRASE; -using ::NAN_SECURITY_KEY_INPUT_PMK; using ::NAN_SECURITY_KEY_INPUT_PMK; using ::NAN_SERVICE_ACCEPT_POLICY_ALL; using ::NAN_SERVICE_ACCEPT_POLICY_NONE; @@ -154,19 +156,20 @@ using ::RTT_PEER_NAN; using ::RTT_PEER_P2P_CLIENT; using ::RTT_PEER_P2P_GO; using ::RTT_PEER_STA; +using ::rtt_peer_type; using ::RTT_STATUS_ABORTED; -using ::RTT_STATUS_FAILURE; using ::RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL; using ::RTT_STATUS_FAIL_BUSY_TRY_LATER; using ::RTT_STATUS_FAIL_FTM_PARAM_OVERRIDE; using ::RTT_STATUS_FAIL_INVALID_TS; -using ::RTT_STATUS_FAIL_NOT_SCHEDULED_YET; using ::RTT_STATUS_FAIL_NO_CAPABILITY; using ::RTT_STATUS_FAIL_NO_RSP; +using ::RTT_STATUS_FAIL_NOT_SCHEDULED_YET; using ::RTT_STATUS_FAIL_PROTOCOL; using ::RTT_STATUS_FAIL_REJECTED; using ::RTT_STATUS_FAIL_SCHEDULE; using ::RTT_STATUS_FAIL_TM_TIMEOUT; +using ::RTT_STATUS_FAILURE; using ::RTT_STATUS_INVALID_REQ; using ::RTT_STATUS_NAN_RANGING_CONCURRENCY_NOT_SUPPORTED; using ::RTT_STATUS_NAN_RANGING_PROTOCOL_FAILURE; @@ -185,6 +188,8 @@ using ::RX_PKT_FATE_FW_DROP_NOBUFS; using ::RX_PKT_FATE_FW_DROP_OTHER; using ::RX_PKT_FATE_FW_QUEUED; using ::RX_PKT_FATE_SUCCESS; +using ::ssid_t; +using ::transaction_id; using ::TX_PKT_FATE_ACKED; using ::TX_PKT_FATE_DRV_DROP_INVALID; using ::TX_PKT_FATE_DRV_DROP_NOBUFS; @@ -199,24 +204,31 @@ using ::WIFI_AC_BE; using ::WIFI_AC_BK; using ::WIFI_AC_VI; using ::WIFI_AC_VO; +using ::wifi_band; using ::WIFI_BAND_A; -using ::WIFI_BAND_ABG; -using ::WIFI_BAND_ABG_WITH_DFS; using ::WIFI_BAND_A_DFS; using ::WIFI_BAND_A_WITH_DFS; +using ::WIFI_BAND_ABG; +using ::WIFI_BAND_ABG_WITH_DFS; using ::WIFI_BAND_BG; using ::WIFI_BAND_UNSPECIFIED; +using ::wifi_cached_scan_results; using ::WIFI_CHAN_WIDTH_10; using ::WIFI_CHAN_WIDTH_160; using ::WIFI_CHAN_WIDTH_20; using ::WIFI_CHAN_WIDTH_40; using ::WIFI_CHAN_WIDTH_5; -using ::WIFI_CHAN_WIDTH_5; using ::WIFI_CHAN_WIDTH_80; using ::WIFI_CHAN_WIDTH_80P80; using ::WIFI_CHAN_WIDTH_INVALID; +using ::wifi_channel_info; +using ::wifi_channel_stat; +using ::wifi_channel_width; +using ::wifi_coex_restriction; +using ::wifi_coex_unsafe_channel; using ::WIFI_DUAL_STA_NON_TRANSIENT_UNBIASED; using ::WIFI_DUAL_STA_TRANSIENT_PREFER_PRIMARY; +using ::wifi_error; using ::WIFI_ERROR_BUSY; using ::WIFI_ERROR_INVALID_ARGS; using ::WIFI_ERROR_INVALID_REQUEST_ID; @@ -228,12 +240,29 @@ using ::WIFI_ERROR_TIMED_OUT; using ::WIFI_ERROR_TOO_MANY_REQUESTS; using ::WIFI_ERROR_UNINITIALIZED; using ::WIFI_ERROR_UNKNOWN; +using ::wifi_gscan_capabilities; +using ::wifi_hal_fn; +using ::wifi_information_element; +using ::WIFI_INTERFACE_IBSS; +using ::WIFI_INTERFACE_MESH; +using ::wifi_interface_mode; +using ::WIFI_INTERFACE_NAN; +using ::WIFI_INTERFACE_P2P_CLIENT; +using ::WIFI_INTERFACE_P2P_GO; +using ::WIFI_INTERFACE_SOFTAP; +using ::WIFI_INTERFACE_STA; +using ::WIFI_INTERFACE_TDLS; +using ::wifi_interface_type; using ::WIFI_INTERFACE_TYPE_AP; using ::WIFI_INTERFACE_TYPE_NAN; using ::WIFI_INTERFACE_TYPE_P2P; using ::WIFI_INTERFACE_TYPE_STA; +using ::WIFI_INTERFACE_UNKNOWN; +using ::wifi_latency_mode; using ::WIFI_LATENCY_MODE_LOW; using ::WIFI_LATENCY_MODE_NORMAL; +using ::wifi_lci_information; +using ::wifi_lcr_information; using ::WIFI_LOGGER_CONNECT_EVENT_SUPPORTED; using ::WIFI_LOGGER_DRIVER_DUMP_SUPPORTED; using ::WIFI_LOGGER_MEMORY_DUMP_SUPPORTED; @@ -242,61 +271,34 @@ using ::WIFI_LOGGER_POWER_EVENT_SUPPORTED; using ::WIFI_LOGGER_WAKE_LOCK_SUPPORTED; using ::WIFI_MOTION_EXPECTED; using ::WIFI_MOTION_NOT_EXPECTED; +using ::wifi_motion_pattern; using ::WIFI_MOTION_UNKNOWN; +using ::wifi_multi_sta_use_case; +using ::wifi_power_scenario; using ::WIFI_POWER_SCENARIO_ON_BODY_CELL_OFF; using ::WIFI_POWER_SCENARIO_ON_BODY_CELL_ON; using ::WIFI_POWER_SCENARIO_ON_HEAD_CELL_OFF; using ::WIFI_POWER_SCENARIO_ON_HEAD_CELL_ON; using ::WIFI_POWER_SCENARIO_VOICE_CALL; +using ::wifi_rate; +using ::wifi_request_id; +using ::wifi_ring_buffer_status; +using ::wifi_roaming_capabilities; +using ::wifi_roaming_config; +using ::wifi_rtt_bw; using ::WIFI_RTT_BW_10; using ::WIFI_RTT_BW_160; using ::WIFI_RTT_BW_20; using ::WIFI_RTT_BW_40; using ::WIFI_RTT_BW_5; using ::WIFI_RTT_BW_80; +using ::wifi_rtt_capabilities; +using ::wifi_rtt_config; +using ::wifi_rtt_preamble; using ::WIFI_RTT_PREAMBLE_HE; using ::WIFI_RTT_PREAMBLE_HT; using ::WIFI_RTT_PREAMBLE_LEGACY; using ::WIFI_RTT_PREAMBLE_VHT; -using ::WIFI_SCAN_FLAG_INTERRUPTED; -using ::WIFI_SUCCESS; -using ::WLAN_MAC_2_4_BAND; -using ::WLAN_MAC_5_0_BAND; -using ::WLAN_MAC_6_0_BAND; -using ::frame_info; -using ::frame_type; -using ::fw_roaming_state_t; -using ::mac_addr; -using ::rtt_peer_type; -using ::ssid_t; -using ::transaction_id; -using ::wifi_band; -using ::wifi_cached_scan_results; -using ::wifi_channel_info; -using ::wifi_channel_stat; -using ::wifi_channel_width; -using ::wifi_coex_restriction; -using ::wifi_coex_unsafe_channel; -using ::wifi_error; -using ::wifi_gscan_capabilities; -using ::wifi_hal_fn; -using ::wifi_information_element; -using ::wifi_interface_type; -using ::wifi_latency_mode; -using ::wifi_lci_information; -using ::wifi_lcr_information; -using ::wifi_motion_pattern; -using ::wifi_multi_sta_use_case; -using ::wifi_power_scenario; -using ::wifi_rate; -using ::wifi_request_id; -using ::wifi_ring_buffer_status; -using ::wifi_roaming_capabilities; -using ::wifi_roaming_config; -using ::wifi_rtt_bw; -using ::wifi_rtt_capabilities; -using ::wifi_rtt_config; -using ::wifi_rtt_preamble; using ::wifi_rtt_responder; using ::wifi_rtt_result; using ::wifi_rtt_status; @@ -305,9 +307,16 @@ using ::wifi_rx_packet_fate; using ::wifi_rx_report; using ::wifi_scan_bucket_spec; using ::wifi_scan_cmd_params; +using ::WIFI_SCAN_FLAG_INTERRUPTED; using ::wifi_scan_result; +using ::WIFI_SUCCESS; using ::wifi_tx_packet_fate; using ::wifi_tx_report; +using ::wifi_usable_channel; +using ::WLAN_MAC_2_4_BAND; +using ::WLAN_MAC_5_0_BAND; +using ::WLAN_MAC_60_0_BAND; +using ::WLAN_MAC_6_0_BAND; // APF capabilities supported by the iface. struct PacketFilterCapabilities { @@ -693,6 +702,11 @@ class WifiLegacyHal { 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> getUsableChannels( + uint32_t band_mask, uint32_t iface_mode_mask); + private: // Retrieve interface handles for all the available interfaces. wifi_error retrieveIfaceHandles(); diff --git a/wifi/1.5/default/wifi_legacy_hal_stubs.cpp b/wifi/1.5/default/wifi_legacy_hal_stubs.cpp index 7ba5d9b804..6212960d7a 100644 --- a/wifi/1.5/default/wifi_legacy_hal_stubs.cpp +++ b/wifi/1.5/default/wifi_legacy_hal_stubs.cpp @@ -159,6 +159,7 @@ bool initHalFuncTableWithStubs(wifi_hal_fn* hal_fn) { populateStubFor(&hal_fn->wifi_twt_get_stats); populateStubFor(&hal_fn->wifi_twt_clear_stats); populateStubFor(&hal_fn->wifi_set_dtim_config); + populateStubFor(&hal_fn->wifi_get_usable_channels); return true; } } // namespace legacy_hal diff --git a/wifi/1.5/types.hal b/wifi/1.5/types.hal index 9fa5c800c0..4dff77443e 100644 --- a/wifi/1.5/types.hal +++ b/wifi/1.5/types.hal @@ -24,6 +24,8 @@ import @1.0::NanCipherSuiteType; import @1.0::NanCapabilities; import @1.2::NanConfigRequestSupplemental; import @1.3::StaLinkLayerRadioStats; +import @1.0::WifiChannelInMhz; +import @1.0::WifiChannelWidthInMhz; /** * Wifi bands defined in 80211 spec. @@ -43,6 +45,64 @@ enum WifiBand : @1.4::WifiBand { BAND_24GHZ_5GHZ_WITH_DFS_6GHZ_60GHZ = 31, }; +/** + * Interface operating modes. + */ +enum WifiIfaceMode : uint32_t { + /** + * Interface operation mode is client. + */ + IFACE_MODE_STA = 1 << 0, + /** + * Interface operation mode is Hotspot. + */ + IFACE_MODE_SOFTAP = 1 << 1, + /** + * Interface operation mode is Ad-Hoc network. + */ + IFACE_MODE_IBSS = 1 << 2, + /** + * Interface operation mode is Wifi Direct Client. + */ + IFACE_MODE_P2P_CLIENT = 1 << 3, + /** + * Interface operation mode is Wifi Direct Group Owner. + */ + IFACE_MODE_P2P_GO = 1 << 4, + /** + * Interface operation mode is Aware. + */ + IFACE_MODE_NAN = 1 << 5, + /** + * Interface operation mode is Mesh network. + */ + IFACE_MODE_MESH = 1 << 6, + /** + * Interface operation mode is Tunneled Direct Link Setup. + */ + IFACE_MODE_TDLS = 1 << 7, +}; + +/** + * Wifi usable channel information. + */ +struct WifiUsableChannel { + /** + * Wifi channel freqeuncy in MHz. + */ + WifiChannelInMhz channel; + + /** + * Wifi channel bandwidth in MHz. + */ + WifiChannelWidthInMhz channelBandwidth; + + /** + * Iface modes feasible on this channel. + */ + bitfield ifaceModeMask; +}; + /** * NAN configuration request parameters added in the 1.2 HAL. These are supplemental to previous * versions. diff --git a/wifi/1.5/vts/functional/wifi_chip_hidl_test.cpp b/wifi/1.5/vts/functional/wifi_chip_hidl_test.cpp index 36a8448d04..509f1bddc7 100644 --- a/wifi/1.5/vts/functional/wifi_chip_hidl_test.cpp +++ b/wifi/1.5/vts/functional/wifi_chip_hidl_test.cpp @@ -45,6 +45,7 @@ using ::android::hardware::wifi::V1_0::WifiStatusCode; using ::android::hardware::wifi::V1_4::IWifiChipEventCallback; using ::android::hardware::wifi::V1_5::IWifiChip; using ::android::hardware::wifi::V1_5::WifiBand; +using ::android::hardware::wifi::V1_5::WifiIfaceMode; /** * Fixture to use for all Wifi chip HIDL interface tests. @@ -187,6 +188,23 @@ TEST_P(WifiChipHidlTest, setCountryCode) { HIDL_INVOKE(wifi_chip_, setCountryCode, kCountryCode).code); } +/* getUsableChannels: + * Ensure that a call to getUsableChannels will return with a success + * status for valid inputs. + */ +TEST_P(WifiChipHidlTest, getUsableChannels) { + uint32_t ifaceModeMask = + WifiIfaceMode::IFACE_MODE_P2P_CLIENT | WifiIfaceMode::IFACE_MODE_P2P_GO; + configureChipForIfaceType(IfaceType::STA, true); + WifiBand band = WifiBand::BAND_24GHZ_5GHZ_6GHZ; + const auto& statusNonEmpty = + HIDL_INVOKE(wifi_chip_, getUsableChannels, band, ifaceModeMask); + if (statusNonEmpty.first.code != WifiStatusCode::SUCCESS) { + EXPECT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED, + statusNonEmpty.first.code); + } +} + GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiChipHidlTest); INSTANTIATE_TEST_SUITE_P( PerInstance, WifiChipHidlTest, -- GitLab From 5e3298c3b498f981e70d6d9c546b8add4fdfe338 Mon Sep 17 00:00:00 2001 From: Benjamin Schwartz Date: Tue, 26 Jan 2021 10:15:23 -0800 Subject: [PATCH 421/790] power/stats: Add VTS tests for power stats hal Bug: 165345767 Test: atest VtsHalPowerStatsTargetTest Change-Id: Iba90d106a5be13d817a4a2fb36098781ea2f9ee0 --- .../aidl/vts/VtsHalPowerStatsTargetTest.cpp | 352 ++++++++++++++++-- 1 file changed, 318 insertions(+), 34 deletions(-) diff --git a/power/stats/aidl/vts/VtsHalPowerStatsTargetTest.cpp b/power/stats/aidl/vts/VtsHalPowerStatsTargetTest.cpp index f293773383..033bf1a3a4 100644 --- a/power/stats/aidl/vts/VtsHalPowerStatsTargetTest.cpp +++ b/power/stats/aidl/vts/VtsHalPowerStatsTargetTest.cpp @@ -21,10 +21,21 @@ #include #include +#include +#include +#include +#include + using aidl::android::hardware::power::stats::Channel; +using aidl::android::hardware::power::stats::EnergyConsumer; +using aidl::android::hardware::power::stats::EnergyConsumerAttribution; +using aidl::android::hardware::power::stats::EnergyConsumerResult; +using aidl::android::hardware::power::stats::EnergyConsumerType; using aidl::android::hardware::power::stats::EnergyMeasurement; using aidl::android::hardware::power::stats::IPowerStats; using aidl::android::hardware::power::stats::PowerEntity; +using aidl::android::hardware::power::stats::State; +using aidl::android::hardware::power::stats::StateResidency; using aidl::android::hardware::power::stats::StateResidencyResult; using ndk::SpAIBinder; @@ -37,12 +48,61 @@ class PowerStatsAidl : public testing::TestWithParam { ASSERT_NE(nullptr, powerstats.get()); } + template + std::vector getRandomSubset(std::vector const& collection); + + void testNameValid(const std::string& name); + + template + void testUnique(std::vector const& collection, S T::*field); + + template + void testMatching(std::vector const& c1, R T::*f1, std::vector const& c2, R S::*f2); + std::shared_ptr powerstats; }; -TEST_P(PowerStatsAidl, TestReadEnergyMeter) { - std::vector data; - ASSERT_TRUE(powerstats->readEnergyMeters({}, &data).isOk()); +// Returns a random subset from a collection +template +std::vector PowerStatsAidl::getRandomSubset(std::vector const& collection) { + if (collection.empty()) { + return {}; + } + + std::vector selected; + std::sample(collection.begin(), collection.end(), std::back_inserter(selected), + rand() % collection.size() + 1, std::mt19937{std::random_device{}()}); + + return selected; +} + +// Tests whether a name is valid +void PowerStatsAidl::testNameValid(const std::string& name) { + EXPECT_NE(name, ""); +} + +// Tests whether the fields in a given collection are unique +template +void PowerStatsAidl::testUnique(std::vector const& collection, S T::*field) { + std::set cSet; + for (auto const& elem : collection) { + EXPECT_TRUE(cSet.insert(elem.*field).second); + } +} + +template +void PowerStatsAidl::testMatching(std::vector const& c1, R T::*f1, std::vector const& c2, + R S::*f2) { + std::set c1fields, c2fields; + for (auto elem : c1) { + c1fields.insert(elem.*f1); + } + + for (auto elem : c2) { + c2fields.insert(elem.*f2); + } + + EXPECT_EQ(c1fields, c2fields); } // Each PowerEntity must have a valid name @@ -51,80 +111,304 @@ TEST_P(PowerStatsAidl, ValidatePowerEntityNames) { ASSERT_TRUE(powerstats->getPowerEntityInfo(&infos).isOk()); for (auto info : infos) { - EXPECT_NE(info.name, ""); + testNameValid(info.name); } } // Each power entity must have a unique name TEST_P(PowerStatsAidl, ValidatePowerEntityUniqueNames) { - std::vector infos; - ASSERT_TRUE(powerstats->getPowerEntityInfo(&infos).isOk()); + std::vector entities; + ASSERT_TRUE(powerstats->getPowerEntityInfo(&entities).isOk()); - std::set names; - for (auto info : infos) { - EXPECT_TRUE(names.insert(info.name).second); - } + testUnique(entities, &PowerEntity::name); } // Each PowerEntity must have a unique ID TEST_P(PowerStatsAidl, ValidatePowerEntityIds) { - std::vector infos; - ASSERT_TRUE(powerstats->getPowerEntityInfo(&infos).isOk()); + std::vector entities; + ASSERT_TRUE(powerstats->getPowerEntityInfo(&entities).isOk()); - std::set ids; - for (auto info : infos) { - EXPECT_TRUE(ids.insert(info.id).second); + testUnique(entities, &PowerEntity::id); +} + +// Each power entity must have at least one state +TEST_P(PowerStatsAidl, ValidateStateSize) { + std::vector entities; + ASSERT_TRUE(powerstats->getPowerEntityInfo(&entities).isOk()); + + for (auto entity : entities) { + EXPECT_GT(entity.states.size(), 0); } } // Each state must have a valid name TEST_P(PowerStatsAidl, ValidateStateNames) { - std::vector infos; - ASSERT_TRUE(powerstats->getPowerEntityInfo(&infos).isOk()); + std::vector entities; + ASSERT_TRUE(powerstats->getPowerEntityInfo(&entities).isOk()); - for (auto info : infos) { - for (auto state : info.states) { - EXPECT_NE(state.name, ""); + for (auto entity : entities) { + for (auto state : entity.states) { + testNameValid(state.name); } } } // Each state must have a name that is unique to the given PowerEntity TEST_P(PowerStatsAidl, ValidateStateUniqueNames) { - std::vector infos; - ASSERT_TRUE(powerstats->getPowerEntityInfo(&infos).isOk()); + std::vector entities; + ASSERT_TRUE(powerstats->getPowerEntityInfo(&entities).isOk()); - for (auto info : infos) { - std::set stateNames; - for (auto state : info.states) { - EXPECT_TRUE(stateNames.insert(state.name).second); - } + for (auto entity : entities) { + testUnique(entity.states, &State::name); } } // Each state must have an ID that is unique to the given PowerEntity TEST_P(PowerStatsAidl, ValidateStateUniqueIds) { - std::vector infos; - ASSERT_TRUE(powerstats->getPowerEntityInfo(&infos).isOk()); + std::vector entities; + ASSERT_TRUE(powerstats->getPowerEntityInfo(&entities).isOk()); - for (auto info : infos) { - std::set stateIds; - for (auto state : info.states) { - EXPECT_TRUE(stateIds.insert(state.id).second); - } + for (auto entity : entities) { + testUnique(entity.states, &State::id); } } +// State residency must return a valid status TEST_P(PowerStatsAidl, TestGetStateResidency) { std::vector results; ASSERT_TRUE(powerstats->getStateResidency({}, &results).isOk()); } +// State residency must return all results +TEST_P(PowerStatsAidl, TestGetStateResidencyAllResults) { + std::vector entities; + ASSERT_TRUE(powerstats->getPowerEntityInfo(&entities).isOk()); + + std::vector results; + ASSERT_TRUE(powerstats->getStateResidency({}, &results).isOk()); + + testMatching(entities, &PowerEntity::id, results, &StateResidencyResult::id); +} + +// Each result must contain all state residencies +TEST_P(PowerStatsAidl, TestGetStateResidencyAllStateResidencies) { + std::vector entities; + ASSERT_TRUE(powerstats->getPowerEntityInfo(&entities).isOk()); + + std::vector results; + ASSERT_TRUE(powerstats->getStateResidency({}, &results).isOk()); + + for (auto entity : entities) { + auto it = std::find_if(results.begin(), results.end(), + [&entity](const auto& x) { return x.id == entity.id; }); + ASSERT_NE(it, results.end()); + + testMatching(entity.states, &State::id, it->stateResidencyData, &StateResidency::id); + } +} + +// State residency must return results for each requested power entity +TEST_P(PowerStatsAidl, TestGetStateResidencySelectedResults) { + std::vector entities; + ASSERT_TRUE(powerstats->getPowerEntityInfo(&entities).isOk()); + if (entities.empty()) { + return; + } + + std::vector selectedEntities = getRandomSubset(entities); + std::vector selectedIds; + for (auto const& entity : selectedEntities) { + selectedIds.push_back(entity.id); + } + + std::vector selectedResults; + ASSERT_TRUE(powerstats->getStateResidency(selectedIds, &selectedResults).isOk()); + + testMatching(selectedEntities, &PowerEntity::id, selectedResults, &StateResidencyResult::id); +} + +// Energy meter info must return a valid status TEST_P(PowerStatsAidl, TestGetEnergyMeterInfo) { std::vector info; ASSERT_TRUE(powerstats->getEnergyMeterInfo(&info).isOk()); } +// Each channel must have a valid name and subsystem +TEST_P(PowerStatsAidl, ValidateChannelNames) { + std::vector channels; + ASSERT_TRUE(powerstats->getEnergyMeterInfo(&channels).isOk()); + for (auto channel : channels) { + testNameValid(channel.name); + testNameValid(channel.subsystem); + } +} + +// Each channel must have a unique name +TEST_P(PowerStatsAidl, ValidateChannelUniqueNames) { + std::vector channels; + ASSERT_TRUE(powerstats->getEnergyMeterInfo(&channels).isOk()); + + testUnique(channels, &Channel::name); +} + +// Each channel must have a unique ID +TEST_P(PowerStatsAidl, ValidateChannelUniqueIds) { + std::vector channels; + ASSERT_TRUE(powerstats->getEnergyMeterInfo(&channels).isOk()); + + testUnique(channels, &Channel::id); +} + +// Reading energy meter must return a valid status +TEST_P(PowerStatsAidl, TestReadEnergyMeter) { + std::vector data; + ASSERT_TRUE(powerstats->readEnergyMeters({}, &data).isOk()); +} + +// Reading energy meter must return results for all available channels +TEST_P(PowerStatsAidl, TestGetAllEnergyMeasurements) { + std::vector channels; + ASSERT_TRUE(powerstats->getEnergyMeterInfo(&channels).isOk()); + + std::vector measurements; + ASSERT_TRUE(powerstats->readEnergyMeters({}, &measurements).isOk()); + + testMatching(channels, &Channel::id, measurements, &EnergyMeasurement::id); +} + +// Reading energy must must return results for each selected channel +TEST_P(PowerStatsAidl, TestGetSelectedEnergyMeasurements) { + std::vector channels; + ASSERT_TRUE(powerstats->getEnergyMeterInfo(&channels).isOk()); + if (channels.empty()) { + return; + } + + std::vector selectedChannels = getRandomSubset(channels); + std::vector selectedIds; + for (auto const& channel : selectedChannels) { + selectedIds.push_back(channel.id); + } + + std::vector selectedMeasurements; + ASSERT_TRUE(powerstats->readEnergyMeters(selectedIds, &selectedMeasurements).isOk()); + + testMatching(selectedChannels, &Channel::id, selectedMeasurements, &EnergyMeasurement::id); +} + +// Energy consumer info must return a valid status +TEST_P(PowerStatsAidl, TestGetEnergyConsumerInfo) { + std::vector consumers; + ASSERT_TRUE(powerstats->getEnergyConsumerInfo(&consumers).isOk()); +} + +// Each energy consumer must have a unique id +TEST_P(PowerStatsAidl, TestGetEnergyConsumerUniqueId) { + std::vector consumers; + ASSERT_TRUE(powerstats->getEnergyConsumerInfo(&consumers).isOk()); + + testUnique(consumers, &EnergyConsumer::id); +} + +// Each energy consumer must have a valid name +TEST_P(PowerStatsAidl, ValidateEnergyConsumerNames) { + std::vector consumers; + ASSERT_TRUE(powerstats->getEnergyConsumerInfo(&consumers).isOk()); + + for (auto consumer : consumers) { + testNameValid(consumer.name); + } +} + +// Each energy consumer must have a unique name +TEST_P(PowerStatsAidl, ValidateEnergyConsumerUniqueNames) { + std::vector consumers; + ASSERT_TRUE(powerstats->getEnergyConsumerInfo(&consumers).isOk()); + + testUnique(consumers, &EnergyConsumer::name); +} + +// Energy consumers of the same type must have ordinals that are 0,1,2,..., N - 1 +TEST_P(PowerStatsAidl, ValidateEnergyConsumerOrdinals) { + std::vector consumers; + ASSERT_TRUE(powerstats->getEnergyConsumerInfo(&consumers).isOk()); + + std::unordered_map> ordinalMap; + + // Ordinals must be unique for each type + for (auto consumer : consumers) { + EXPECT_TRUE(ordinalMap[consumer.type].insert(consumer.ordinal).second); + } + + // Min ordinal must be 0, max ordinal must be N - 1 + for (const auto& [unused, ordinals] : ordinalMap) { + EXPECT_EQ(0, *std::min_element(ordinals.begin(), ordinals.end())); + EXPECT_EQ(ordinals.size() - 1, *std::max_element(ordinals.begin(), ordinals.end())); + } +} + +// Energy consumed must return a valid status +TEST_P(PowerStatsAidl, TestGetEnergyConsumed) { + std::vector results; + ASSERT_TRUE(powerstats->getEnergyConsumed({}, &results).isOk()); +} + +// Energy consumed must return data for all energy consumers +TEST_P(PowerStatsAidl, TestGetAllEnergyConsumed) { + std::vector consumers; + ASSERT_TRUE(powerstats->getEnergyConsumerInfo(&consumers).isOk()); + + std::vector results; + ASSERT_TRUE(powerstats->getEnergyConsumed({}, &results).isOk()); + + testMatching(consumers, &EnergyConsumer::id, results, &EnergyConsumerResult::id); +} + +// Energy consumed must return data for each selected energy consumer +TEST_P(PowerStatsAidl, TestGetSelectedEnergyConsumed) { + std::vector consumers; + ASSERT_TRUE(powerstats->getEnergyConsumerInfo(&consumers).isOk()); + if (consumers.empty()) { + return; + } + + std::vector selectedConsumers = getRandomSubset(consumers); + std::vector selectedIds; + for (auto const& consumer : selectedConsumers) { + selectedIds.push_back(consumer.id); + } + + std::vector selectedResults; + ASSERT_TRUE(powerstats->getEnergyConsumed(selectedIds, &selectedResults).isOk()); + + testMatching(selectedConsumers, &EnergyConsumer::id, selectedResults, + &EnergyConsumerResult::id); +} + +// Energy consumed attribution uids must be unique for a given energy consumer +TEST_P(PowerStatsAidl, ValidateEnergyConsumerAttributionUniqueUids) { + std::vector results; + ASSERT_TRUE(powerstats->getEnergyConsumed({}, &results).isOk()); + + for (auto result : results) { + testUnique(result.attribution, &EnergyConsumerAttribution::uid); + } +} + +// Energy consumed total energy >= sum total of uid-attributed energy +TEST_P(PowerStatsAidl, TestGetEnergyConsumedAttributedEnergy) { + std::vector results; + ASSERT_TRUE(powerstats->getEnergyConsumed({}, &results).isOk()); + + for (auto result : results) { + int64_t totalAttributedEnergyUWs = 0; + for (auto attribution : result.attribution) { + totalAttributedEnergyUWs += attribution.energyUWs; + } + EXPECT_TRUE(result.energyUWs >= totalAttributedEnergyUWs); + } +} + GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(PowerStatsAidl); INSTANTIATE_TEST_SUITE_P( PowerStats, PowerStatsAidl, -- GitLab From 5ec48c2d4d7a8ccdea489ad4b34a7cf75480ffcc Mon Sep 17 00:00:00 2001 From: Mikhail Naganov Date: Fri, 15 Jan 2021 19:05:04 +0000 Subject: [PATCH 422/790] audio: Create libraries for data types in core and effect Add 'CoreUtils' library similar to 'HidlUtils' for the types specific to the core HAL. Add 'EffectUtils' library similar to 'HidlUtils' for the types specific to the effects HAL. Move into them and de-duplicate code previously scattered across the default HAL implementation and libaudiohal. Add unit tests. Removed 'AUDIO_{INPUT|OUTPUT}_FLAG_NONE' from the list of values in the XSD file to avoid additional complexity due to equivalence of this value to an empty list of flags. Bug: 142480271 Test: m android.hardware.audio@X.0-impl Test: m android.hardware.audio.effect@X.0-impl Test: atest android.hardware.audio@7.0-util_tests Test: atest android.hardware.audio.common@7.0-util_tests Test: atest android.hardware.audio.effect@7.0-util_tests Change-Id: I71a95cbe07fcc162dc6d74ff9665747a17ce5a80 --- audio/7.0/config/api/current.txt | 2 - .../7.0/config/audio_policy_configuration.xsd | 5 - audio/README.md | 54 +- ...id_audio_policy_configuration_V7_0-enums.h | 8 +- audio/common/7.0/types.hal | 12 +- .../all-versions/default/7.0/HidlUtils.cpp | 40 +- audio/common/all-versions/default/HidlUtils.h | 8 +- .../common/all-versions/default/UuidUtils.cpp | 8 + audio/common/all-versions/default/UuidUtils.h | 5 +- .../default/tests/hidlutils_tests.cpp | 124 ++++- audio/core/all-versions/default/Android.bp | 6 +- .../core/all-versions/default/Conversions.cpp | 230 -------- audio/core/all-versions/default/Device.cpp | 27 +- .../all-versions/default/ParametersUtil.cpp | 5 +- audio/core/all-versions/default/Stream.cpp | 9 +- audio/core/all-versions/default/StreamIn.cpp | 14 +- audio/core/all-versions/default/StreamOut.cpp | 12 +- audio/core/all-versions/default/TEST_MAPPING | 7 + .../include/core/default/Conversions.h | 83 --- .../default/include/core/default/Device.h | 12 +- .../core/all-versions/default/util/Android.bp | 139 +++++ .../all-versions/default/util/CoreUtils.cpp | 476 ++++++++++++++++ .../default/util/include/util/CoreUtils.h | 110 ++++ .../default/util/tests/coreutils_tests.cpp | 525 ++++++++++++++++++ .../4.0/AudioPrimaryHidlHalTest.cpp | 16 +- audio/effect/all-versions/default/Android.bp | 6 +- .../all-versions/default/Conversions.cpp | 61 -- .../effect/all-versions/default/Conversions.h | 46 -- audio/effect/all-versions/default/Effect.cpp | 96 +--- audio/effect/all-versions/default/Effect.h | 5 - .../all-versions/default/EffectsFactory.cpp | 19 +- .../effect/all-versions/default/TEST_MAPPING | 7 + .../all-versions/default/util/Android.bp | 136 +++++ .../all-versions/default/util/EffectUtils.cpp | 183 ++++++ .../default/util/include/util/EffectUtils.h | 53 ++ .../default/util/tests/effectutils_tests.cpp | 144 +++++ 36 files changed, 2048 insertions(+), 645 deletions(-) delete mode 100644 audio/core/all-versions/default/Conversions.cpp create mode 100644 audio/core/all-versions/default/TEST_MAPPING delete mode 100644 audio/core/all-versions/default/include/core/default/Conversions.h create mode 100644 audio/core/all-versions/default/util/Android.bp create mode 100644 audio/core/all-versions/default/util/CoreUtils.cpp create mode 100644 audio/core/all-versions/default/util/include/util/CoreUtils.h create mode 100644 audio/core/all-versions/default/util/tests/coreutils_tests.cpp delete mode 100644 audio/effect/all-versions/default/Conversions.cpp delete mode 100644 audio/effect/all-versions/default/Conversions.h create mode 100644 audio/effect/all-versions/default/TEST_MAPPING create mode 100644 audio/effect/all-versions/default/util/Android.bp create mode 100644 audio/effect/all-versions/default/util/EffectUtils.cpp create mode 100644 audio/effect/all-versions/default/util/include/util/EffectUtils.h create mode 100644 audio/effect/all-versions/default/util/tests/effectutils_tests.cpp diff --git a/audio/7.0/config/api/current.txt b/audio/7.0/config/api/current.txt index f585d8e405..78f2f29c17 100644 --- a/audio/7.0/config/api/current.txt +++ b/audio/7.0/config/api/current.txt @@ -251,7 +251,6 @@ package android.audio.policy.configuration.V7_0 { enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_HW_AV_SYNC; enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_HW_HOTWORD; enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_MMAP_NOIRQ; - enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_NONE; enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_RAW; enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_SYNC; enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_INPUT_FLAG_VOIP_TX; @@ -265,7 +264,6 @@ package android.audio.policy.configuration.V7_0 { enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO; enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_INCALL_MUSIC; enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_MMAP_NOIRQ; - enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_NONE; enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_NON_BLOCKING; enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_PRIMARY; enum_constant public static final android.audio.policy.configuration.V7_0.AudioInOutFlag AUDIO_OUTPUT_FLAG_RAW; diff --git a/audio/7.0/config/audio_policy_configuration.xsd b/audio/7.0/config/audio_policy_configuration.xsd index 87e5774337..50c179352f 100644 --- a/audio/7.0/config/audio_policy_configuration.xsd +++ b/audio/7.0/config/audio_policy_configuration.xsd @@ -159,13 +159,9 @@ The flags indicate suggested stream attributes supported by the profile. - Use of AUDIO_{INPUT|OUTPUT}_FLAG_NONE in the XML file isn't required - as empty flag lists are allowed. However these constants are useful for - representing an empty enum value. - @@ -182,7 +178,6 @@ - diff --git a/audio/README.md b/audio/README.md index b77b9ba42d..1938ad4d11 100644 --- a/audio/README.md +++ b/audio/README.md @@ -7,47 +7,49 @@ based on an existing one. ## Directory Structure -* `2.0` -- version 2.0 of the core HIDL API. Note that `.hal` files +* `2.0` — version 2.0 of the core HIDL API. Note that `.hal` files can not be moved into the `core` directory because that would change its namespace and include path. - - `config` -- the XSD schema for the Audio Policy Manager + - `config` — the XSD schema for the Audio Policy Manager configuration file. -* `4.0` -- version 4.0 of the core HIDL API. +* `4.0` — version 4.0 of the core HIDL API. * ... -* `common` -- common types for audio core and effect HIDL API. - - `2.0` -- version 2.0 of the common types HIDL API. - - `4.0` -- version 4.0. +* `common` — common types for audio core and effect HIDL API. + - `2.0` — version 2.0 of the common types HIDL API. + - `4.0` — version 4.0. - ... - - `7.0` -- version 7.0. - - `example` -- example implementation of the core and effect + - `7.0` — version 7.0. + - `example` — example implementation of the core and effect V7.0 API. It represents a "fake" audio HAL that doesn't actually communicate with hardware. - - `all-versions` -- code common to all version of both core and effect API. - - `default` -- shared code of the default implementation. - - `service` -- vendor HAL service for hosting the default + - `all-versions` — code common to all version of both core and effect API. + - `default` — shared code of the default implementation. + - `service` — vendor HAL service for hosting the default implementation. - - `test` -- utilities used by tests. - - `util` -- utilities used by both implementation and tests. -* `core` -- VTS tests and the default implementation of the core API + - `test` — utilities used by tests. + - `util` — utilities used by both implementation and tests. +* `core` — VTS tests and the default implementation of the core API (not HIDL API, it's in `audio/N.M`). - - `7.0` -- code specific to version V7.0 of the core HIDL API - - `all-versions` -- the code is common between all versions, + - `7.0` — code specific to version V7.0 of the core HIDL API + - `all-versions` — the code is common between all versions, version-specific parts are enclosed into conditional directives of preprocessor or reside in dedicated files. - - `default` -- code that wraps the legacy API (from + - `default` — code that wraps the legacy API (from `hardware/libhardware`). + - `util` — utilities for the default implementation. - `vts` VTS tests for the core HIDL API. -* `effect` -- same for the effect HIDL API. +* `effect` — same for the effect HIDL API. - `2.0` - - `config` -- the XSD schema for the Audio Effects configuration - file. + - `config` — the XSD schema for the Audio Effects configuration file. - `4.0` - ... - `all-versions` - - `default` - - `vts` -* `policy` -- Configurable Audio Policy schemes. - - `1.0` -- note that versions of CAP are not linked to the versions + - `default` — code that wraps the legacy API (from + `hardware/libhardware`). + - `util` — utilities for the default implementation. + - `vts` VTS tests for the effect HIDL API. +* `policy` — Configurable Audio Policy schemes. + - `1.0` — note that versions of CAP are not linked to the versions of audio HAL. - - `vts` -- VTS tests for validating actual configuration files. - - `xml` -- XSD schemas for CAP configuration files. + - `vts` — VTS tests for validating actual configuration files. + - `xml` — XSD schemas for CAP configuration files. diff --git a/audio/common/7.0/enums/include/android_audio_policy_configuration_V7_0-enums.h b/audio/common/7.0/enums/include/android_audio_policy_configuration_V7_0-enums.h index c0042db0ba..b427f3a0d4 100644 --- a/audio/common/7.0/enums/include/android_audio_policy_configuration_V7_0-enums.h +++ b/audio/common/7.0/enums/include/android_audio_policy_configuration_V7_0-enums.h @@ -212,10 +212,16 @@ static inline bool isOutputDevice(const std::string& device) { return isOutputDevice(stringToAudioDevice(device)); } +static inline bool maybeVendorExtension(const std::string& s) { + // Only checks whether the string starts with the "vendor prefix". + static const std::string vendorPrefix = "VX_"; + return s.size() > vendorPrefix.size() && s.substr(0, vendorPrefix.size()) == vendorPrefix; +} + static inline bool isVendorExtension(const std::string& s) { // Must match the "vendorExtension" rule from the XSD file. static const std::string vendorPrefix = "VX_"; - return s.size() > vendorPrefix.size() && s.substr(0, vendorPrefix.size()) == vendorPrefix && + return maybeVendorExtension(s) && std::all_of(s.begin() + vendorPrefix.size(), s.end(), [](unsigned char c) { return c == '_' || std::isalnum(c); }); } diff --git a/audio/common/7.0/types.hal b/audio/common/7.0/types.hal index 3903a0b2ce..99c2e5a0eb 100644 --- a/audio/common/7.0/types.hal +++ b/audio/common/7.0/types.hal @@ -309,15 +309,15 @@ typedef string AudioTag; struct PlaybackTrackMetadata { AudioUsage usage; AudioContentType contentType; - /** Tags from AudioTrack audio atttributes */ - vec tags; - AudioChannelMask channelMask; /** * Positive linear gain applied to the track samples. 0 being muted and 1 is no attenuation, * 2 means double amplification... * Must not be negative. */ float gain; + AudioChannelMask channelMask; + /** Tags from AudioTrack audio atttributes */ + vec tags; }; /** Metadatas of the source of a StreamOut. */ @@ -328,9 +328,6 @@ struct SourceMetadata { /** Metadata of a record track for a StreamIn. */ struct RecordTrackMetadata { AudioSource source; - /** Tags from AudioTrack audio atttributes */ - vec tags; - AudioChannelMask channelMask; /** * Positive linear gain applied to the track samples. 0 being muted and 1 is no attenuation, * 2 means double amplification... @@ -344,6 +341,9 @@ struct RecordTrackMetadata { Monostate unspecified; DeviceAddress device; } destination; + AudioChannelMask channelMask; + /** Tags from AudioTrack audio atttributes */ + vec tags; }; /** Metadatas of the sink of a StreamIn. */ diff --git a/audio/common/all-versions/default/7.0/HidlUtils.cpp b/audio/common/all-versions/default/7.0/HidlUtils.cpp index f09db5ed98..bb3a5968b5 100644 --- a/audio/common/all-versions/default/7.0/HidlUtils.cpp +++ b/audio/common/all-versions/default/7.0/HidlUtils.cpp @@ -16,6 +16,7 @@ #include #include +#include #define LOG_TAG "HidlUtils" #include @@ -281,7 +282,7 @@ status_t HidlUtils::audioGainModeMaskFromHal(audio_gain_mode_t halGainModeMask, hidl_vec* gainModeMask) { status_t status = NO_ERROR; std::vector result; - for (uint32_t bit = 0; bit < sizeof(audio_gain_mode_t) * 8; ++bit) { + for (uint32_t bit = 0; halGainModeMask != 0 && bit < sizeof(audio_gain_mode_t) * 8; ++bit) { audio_gain_mode_t flag = static_cast(1u << bit); if ((flag & halGainModeMask) == flag) { AudioGainMode flagStr = audio_gain_mode_to_string(flag); @@ -291,6 +292,7 @@ status_t HidlUtils::audioGainModeMaskFromHal(audio_gain_mode_t halGainModeMask, ALOGE("Unknown audio gain mode value 0x%X", flag); status = BAD_VALUE; } + halGainModeMask = static_cast(halGainModeMask & ~flag); } } *gainModeMask = result; @@ -858,15 +860,17 @@ status_t HidlUtils::audioProfileToHal(const AudioProfile& profile, return result; } -status_t HidlUtils::audioTagsFromHal(const char* halTags, hidl_vec* tags) { - std::vector strTags = utils::splitString(halTags, sAudioTagSeparator); +status_t HidlUtils::audioTagsFromHal(const std::vector& strTags, + hidl_vec* tags) { status_t result = NO_ERROR; tags->resize(strTags.size()); size_t to = 0; for (size_t from = 0; from < strTags.size(); ++from) { - if (xsd::isVendorExtension(strTags[from])) { - (*tags)[to++] = strTags[from]; + const auto& tag = strTags[from]; + if (xsd::isVendorExtension(tag)) { + (*tags)[to++] = tag; } else { + ALOGE("Vendor extension tag is ill-formed: \"%s\"", tag.c_str()); result = BAD_VALUE; } } @@ -889,6 +893,7 @@ status_t HidlUtils::audioTagsToHal(const hidl_vec& tags, char* halTags halTagsBuffer << tag; hasValue = true; } else { + ALOGE("Vendor extension tag is ill-formed: \"%s\"", tag.c_str()); result = BAD_VALUE; } } @@ -899,6 +904,31 @@ status_t HidlUtils::audioTagsToHal(const hidl_vec& tags, char* halTags return result; } +hidl_vec HidlUtils::filterOutNonVendorTags(const hidl_vec& tags) { + hidl_vec result; + result.resize(tags.size()); + size_t resultIdx = 0; + for (const auto& tag : tags) { + if (xsd::maybeVendorExtension(tag)) { + result[resultIdx++] = tag; + } + } + if (resultIdx != result.size()) { + result.resize(resultIdx); + } + return result; +} + +std::vector HidlUtils::filterOutNonVendorTags(const std::vector& tags) { + std::vector result; + std::copy_if(tags.begin(), tags.end(), std::back_inserter(result), xsd::maybeVendorExtension); + return result; +} + +std::vector HidlUtils::splitAudioTags(const char* halTags) { + return utils::splitString(halTags, sAudioTagSeparator); +} + status_t HidlUtils::deviceAddressFromHal(audio_devices_t halDeviceType, const char* halDeviceAddress, DeviceAddress* device) { status_t result = NO_ERROR; diff --git a/audio/common/all-versions/default/HidlUtils.h b/audio/common/all-versions/default/HidlUtils.h index cc4fbf2f15..22b7152f99 100644 --- a/audio/common/all-versions/default/HidlUtils.h +++ b/audio/common/all-versions/default/HidlUtils.h @@ -20,6 +20,8 @@ #include PATH(android/hardware/audio/common/FILE_VERSION/types.h) #include +#include +#include #include @@ -118,8 +120,12 @@ struct HidlUtils { AudioStreamType* streamType); static status_t audioStreamTypeToHal(const AudioStreamType& streamType, audio_stream_type_t* halStreamType); - static status_t audioTagsFromHal(const char* halTags, hidl_vec* tags); + static status_t audioTagsFromHal(const std::vector& strTags, + hidl_vec* tags); static status_t audioTagsToHal(const hidl_vec& tags, char* halTags); + static hidl_vec filterOutNonVendorTags(const hidl_vec& tags); + static std::vector filterOutNonVendorTags(const std::vector& tags); + static std::vector splitAudioTags(const char* halTags); private: static status_t audioIndexChannelMaskFromHal(audio_channel_mask_t halChannelMask, diff --git a/audio/common/all-versions/default/UuidUtils.cpp b/audio/common/all-versions/default/UuidUtils.cpp index 85edc7b2f4..6c4c94d415 100644 --- a/audio/common/all-versions/default/UuidUtils.cpp +++ b/audio/common/all-versions/default/UuidUtils.cpp @@ -42,6 +42,14 @@ void UuidUtils::uuidToHal(const Uuid& uuid, audio_uuid_t* halUuid) { memcpy(halUuid->node, uuid.node.data(), uuid.node.size()); } +std::string UuidUtils::uuidToString(const audio_uuid_t& halUuid) { + char str[64]; + snprintf(str, sizeof(str), "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x", halUuid.timeLow, + halUuid.timeMid, halUuid.timeHiAndVersion, halUuid.clockSeq, halUuid.node[0], + halUuid.node[1], halUuid.node[2], halUuid.node[3], halUuid.node[4], halUuid.node[5]); + return str; +} + } // namespace implementation } // namespace CPP_VERSION } // namespace common diff --git a/audio/common/all-versions/default/UuidUtils.h b/audio/common/all-versions/default/UuidUtils.h index 38db48a730..cd04fb039a 100644 --- a/audio/common/all-versions/default/UuidUtils.h +++ b/audio/common/all-versions/default/UuidUtils.h @@ -17,14 +17,14 @@ #ifndef android_hardware_audio_Uuid_Utils_H_ #define android_hardware_audio_Uuid_Utils_H_ +#include + // clang-format off #include PATH(android/hardware/audio/common/FILE_VERSION/types.h) // clang-format on #include -using ::android::hardware::hidl_vec; - namespace android { namespace hardware { namespace audio { @@ -38,6 +38,7 @@ class UuidUtils { public: static void uuidFromHal(const audio_uuid_t& halUuid, Uuid* uuid); static void uuidToHal(const Uuid& uuid, audio_uuid_t* halUuid); + static std::string uuidToString(const audio_uuid_t& halUuid); }; } // namespace implementation diff --git a/audio/common/all-versions/default/tests/hidlutils_tests.cpp b/audio/common/all-versions/default/tests/hidlutils_tests.cpp index 642ece3255..40fc5c81c6 100644 --- a/audio/common/all-versions/default/tests/hidlutils_tests.cpp +++ b/audio/common/all-versions/default/tests/hidlutils_tests.cpp @@ -762,9 +762,7 @@ TEST(HidlUtils, ConvertInvalidOffloadInfo) { TEST(HidlUtils, ConvertOffloadInfo) { AudioOffloadInfo offloadInfo = {}; - offloadInfo.base.sampleRateHz = 44100; - offloadInfo.base.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO); - offloadInfo.base.format = toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT); + offloadInfo.base = generateValidConfigBase(false /*isInput*/); offloadInfo.streamType = toString(xsd::AudioStreamType::AUDIO_STREAM_MUSIC); offloadInfo.bitRatePerSecond = 320; offloadInfo.durationMicroseconds = -1; @@ -783,33 +781,76 @@ TEST(HidlUtils, ConvertOffloadInfo) { TEST(HidlUtils, ConvertInvalidConfig) { AudioConfig invalid; - audio_config_t halInvalid = AUDIO_CONFIG_INITIALIZER; - halInvalid.channel_mask = kInvalidHalChannelMask; - halInvalid.format = kInvalidHalFormat; - EXPECT_EQ(BAD_VALUE, HidlUtils::audioConfigFromHal(halInvalid, false /*isInput*/, &invalid)); - EXPECT_EQ(BAD_VALUE, HidlUtils::audioConfigFromHal(halInvalid, true /*isInput*/, &invalid)); - invalid.base.channelMask = "random string"; - invalid.base.format = "random string"; - EXPECT_EQ(BAD_VALUE, HidlUtils::audioConfigToHal(invalid, &halInvalid)); + audio_config_t halInvalidChannelMask = AUDIO_CONFIG_INITIALIZER; + halInvalidChannelMask.channel_mask = kInvalidHalChannelMask; + EXPECT_EQ(BAD_VALUE, + HidlUtils::audioConfigFromHal(halInvalidChannelMask, false /*isInput*/, &invalid)); + EXPECT_EQ(BAD_VALUE, + HidlUtils::audioConfigFromHal(halInvalidChannelMask, true /*isInput*/, &invalid)); + audio_config_t halInvalidFormat = AUDIO_CONFIG_INITIALIZER; + halInvalidFormat.format = kInvalidHalFormat; + EXPECT_EQ(BAD_VALUE, + HidlUtils::audioConfigFromHal(halInvalidFormat, false /*isInput*/, &invalid)); + EXPECT_EQ(BAD_VALUE, + HidlUtils::audioConfigFromHal(halInvalidFormat, true /*isInput*/, &invalid)); + + AudioConfig invalidChannelMask; + audio_config_t halInvalid; + invalidChannelMask.base.channelMask = "random string"; + invalidChannelMask.base.format = toString(xsd::AudioFormat::AUDIO_FORMAT_DEFAULT); + EXPECT_EQ(BAD_VALUE, HidlUtils::audioConfigToHal(invalidChannelMask, &halInvalid)); + AudioConfig invalidFormat; + invalidFormat.base.format = "random string"; + invalidFormat.base.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_NONE); + EXPECT_EQ(BAD_VALUE, HidlUtils::audioConfigToHal(invalidFormat, &halInvalid)); +} + +TEST(HidlUtils, ConvertConfigDefault) { + audio_config_t halDefault = AUDIO_CONFIG_INITIALIZER; + AudioConfig defaultOut, defaultIn; + EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigFromHal(halDefault, false /*isInput*/, &defaultOut)); + EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigFromHal(halDefault, true /*isInput*/, &defaultIn)); + EXPECT_EQ(defaultOut, defaultIn); + EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigToHal(defaultOut, &halDefault)); + + // Note: empty channel mask and config are not valid values. + AudioConfig defaultCfg{}; + defaultCfg.base.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_NONE); + defaultCfg.base.format = toString(xsd::AudioFormat::AUDIO_FORMAT_DEFAULT); + audio_config_t halDefaultCfg; + EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigToHal(defaultCfg, &halDefaultCfg)); + AudioConfig defaultCfgBackOut, defaultCfgBackIn; + EXPECT_EQ(NO_ERROR, + HidlUtils::audioConfigFromHal(halDefaultCfg, false /*isInput*/, &defaultCfgBackOut)); + EXPECT_EQ(NO_ERROR, + HidlUtils::audioConfigFromHal(halDefaultCfg, true /*isInput*/, &defaultCfgBackIn)); + EXPECT_EQ(defaultCfgBackOut, defaultCfgBackIn); + EXPECT_EQ(defaultCfg, defaultCfgBackOut); } TEST(HidlUtils, ConvertConfig) { - AudioConfig config = {}; - config.base.sampleRateHz = 44100; - config.base.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO); - config.base.format = toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT); - audio_config_t halConfig; - EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigToHal(config, &halConfig)); - AudioConfig configBack; - EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigFromHal(halConfig, false /*isInput*/, &configBack)); - EXPECT_EQ(config, configBack); + AudioConfig configOut{}; + configOut.base = generateValidConfigBase(false /*isInput*/); + audio_config_t halConfigOut; + EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigToHal(configOut, &halConfigOut)); + AudioConfig configOutBack; + EXPECT_EQ(NO_ERROR, + HidlUtils::audioConfigFromHal(halConfigOut, false /*isInput*/, &configOutBack)); + EXPECT_EQ(configOut, configOutBack); + + AudioConfig configIn{}; + configIn.base = generateValidConfigBase(true /*isInput*/); + audio_config_t halConfigIn; + EXPECT_EQ(NO_ERROR, HidlUtils::audioConfigToHal(configIn, &halConfigIn)); + AudioConfig configInBack; + EXPECT_EQ(NO_ERROR, + HidlUtils::audioConfigFromHal(halConfigIn, true /*isInput*/, &configInBack)); + EXPECT_EQ(configIn, configInBack); } TEST(HidlUtils, ConvertConfigWithOffloadInfo) { AudioConfig config = {}; - config.base.sampleRateHz = 44100; - config.base.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO); - config.base.format = toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT); + config.base = generateValidConfigBase(false /*isInput*/); config.offloadInfo.info( AudioOffloadInfo{.base = config.base, .streamType = toString(xsd::AudioStreamType::AUDIO_STREAM_MUSIC), @@ -952,20 +993,51 @@ TEST(HidlUtils, ConvertAudioTags) { char halEmptyTags[AUDIO_ATTRIBUTES_TAGS_MAX_SIZE] = {}; EXPECT_EQ(NO_ERROR, HidlUtils::audioTagsToHal(emptyTags, halEmptyTags)); hidl_vec emptyTagsBack; - EXPECT_EQ(NO_ERROR, HidlUtils::audioTagsFromHal(halEmptyTags, &emptyTagsBack)); + EXPECT_EQ(NO_ERROR, + HidlUtils::audioTagsFromHal(HidlUtils::splitAudioTags(halEmptyTags), &emptyTagsBack)); EXPECT_EQ(emptyTags, emptyTagsBack); hidl_vec oneTag = {{"VX_GOOGLE_VR"}}; char halOneTag[AUDIO_ATTRIBUTES_TAGS_MAX_SIZE] = {}; EXPECT_EQ(NO_ERROR, HidlUtils::audioTagsToHal(oneTag, halOneTag)); hidl_vec oneTagBack; - EXPECT_EQ(NO_ERROR, HidlUtils::audioTagsFromHal(halOneTag, &oneTagBack)); + EXPECT_EQ(NO_ERROR, + HidlUtils::audioTagsFromHal(HidlUtils::splitAudioTags(halOneTag), &oneTagBack)); EXPECT_EQ(oneTag, oneTagBack); hidl_vec twoTags = {{"VX_GOOGLE_VR_42", "VX_GOOGLE_1E100"}}; char halTwoTags[AUDIO_ATTRIBUTES_TAGS_MAX_SIZE] = {}; EXPECT_EQ(NO_ERROR, HidlUtils::audioTagsToHal(twoTags, halTwoTags)); hidl_vec twoTagsBack; - EXPECT_EQ(NO_ERROR, HidlUtils::audioTagsFromHal(halTwoTags, &twoTagsBack)); + EXPECT_EQ(NO_ERROR, + HidlUtils::audioTagsFromHal(HidlUtils::splitAudioTags(halTwoTags), &twoTagsBack)); EXPECT_EQ(twoTags, twoTagsBack); } + +template +class FilterTest : public ::testing::Test {}; +using FilterTestTypeParams = ::testing::Types, std::vector>; +TYPED_TEST_SUITE(FilterTest, FilterTestTypeParams); + +TYPED_TEST(FilterTest, FilterOutNonVendorTags) { + TypeParam emptyTags; + EXPECT_EQ(emptyTags, HidlUtils::filterOutNonVendorTags(emptyTags)); + + TypeParam allVendorTags = {{"VX_GOOGLE_VR_42", "VX_GOOGLE_1E100"}}; + EXPECT_EQ(allVendorTags, HidlUtils::filterOutNonVendorTags(allVendorTags)); + + TypeParam oneVendorTag = {{"", "VX_GOOGLE_VR", "random_string"}}; + TypeParam oneVendorTagOnly = HidlUtils::filterOutNonVendorTags(oneVendorTag); + EXPECT_EQ(1, oneVendorTagOnly.size()); + EXPECT_EQ(oneVendorTag[1], oneVendorTagOnly[0]); + + // The vendor extension isn't valid, however it must not be filtered out + // so the converter can detect the issue. + TypeParam oneMaybeVendorTag = {{"", "random string", "VX_GOOGLE_$$"}}; + TypeParam oneMaybeVendorTagOnly = HidlUtils::filterOutNonVendorTags(oneMaybeVendorTag); + EXPECT_EQ(1, oneMaybeVendorTagOnly.size()); + EXPECT_EQ(oneMaybeVendorTag[2], oneMaybeVendorTagOnly[0]); + + TypeParam noVendorTags = {{"", "random string", "V_"}}; + EXPECT_EQ(emptyTags, HidlUtils::filterOutNonVendorTags(noVendorTags)); +} diff --git a/audio/core/all-versions/default/Android.bp b/audio/core/all-versions/default/Android.bp index c75c779a91..e0f089425f 100644 --- a/audio/core/all-versions/default/Android.bp +++ b/audio/core/all-versions/default/Android.bp @@ -1,7 +1,6 @@ filegroup { name: "android.hardware.audio-impl_srcs", srcs: [ - "Conversions.cpp", "Device.cpp", "DevicesFactory.cpp", "ParametersUtil.cpp", @@ -64,6 +63,7 @@ cc_library_shared { defaults: ["android.hardware.audio-impl_default"], shared_libs: [ "android.hardware.audio@2.0", + "android.hardware.audio@2.0-util", "android.hardware.audio.common@2.0", "android.hardware.audio.common@2.0-util", ], @@ -80,6 +80,7 @@ cc_library_shared { shared_libs: [ "android.hardware.audio@4.0", + "android.hardware.audio@4.0-util", "android.hardware.audio.common@4.0", "android.hardware.audio.common@4.0-util", ], @@ -95,6 +96,7 @@ cc_library_shared { defaults: ["android.hardware.audio-impl_default"], shared_libs: [ "android.hardware.audio@5.0", + "android.hardware.audio@5.0-util", "android.hardware.audio.common@5.0", "android.hardware.audio.common@5.0-util", ], @@ -110,6 +112,7 @@ cc_defaults { defaults: ["android.hardware.audio-impl_default"], shared_libs: [ "android.hardware.audio@6.0", + "android.hardware.audio@6.0-util", "android.hardware.audio.common@6.0", "android.hardware.audio.common@6.0-util", ], @@ -130,6 +133,7 @@ cc_library_shared { defaults: ["android.hardware.audio-impl_default"], shared_libs: [ "android.hardware.audio@7.0", + "android.hardware.audio@7.0-util", "android.hardware.audio.common@7.0", "android.hardware.audio.common@7.0-enums", "android.hardware.audio.common@7.0-util", diff --git a/audio/core/all-versions/default/Conversions.cpp b/audio/core/all-versions/default/Conversions.cpp deleted file mode 100644 index f1752ccba3..0000000000 --- a/audio/core/all-versions/default/Conversions.cpp +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "core/default/Conversions.h" - -#include - -#if MAJOR_VERSION >= 7 -#include -#endif -#include -#include - -namespace android { -namespace hardware { -namespace audio { -namespace CPP_VERSION { -namespace implementation { - -using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils; - -#define CONVERT_CHECKED(expr, result) \ - if (status_t status = (expr); status != NO_ERROR) { \ - result = status; \ - } - -status_t deviceAddressToHal(const DeviceAddress& device, audio_devices_t* halDeviceType, - char* halDeviceAddress) { -#if MAJOR_VERSION >= 5 - return HidlUtils::deviceAddressToHal(device, halDeviceType, halDeviceAddress); -#else - return HidlUtils::deviceAddressToHalImpl(device, halDeviceType, halDeviceAddress); -#endif -} - -status_t deviceAddressFromHal(audio_devices_t halDeviceType, const char* halDeviceAddress, - DeviceAddress* device) { -#if MAJOR_VERSION >= 5 - return HidlUtils::deviceAddressFromHal(halDeviceType, halDeviceAddress, device); -#else - return HidlUtils::deviceAddressFromHalImpl(halDeviceType, halDeviceAddress, device); -#endif -} - -#if MAJOR_VERSION >= 4 -bool halToMicrophoneCharacteristics(MicrophoneInfo* pDst, - const struct audio_microphone_characteristic_t& src) { - bool status = false; - if (pDst != NULL) { - pDst->deviceId = src.device_id; - - if (deviceAddressFromHal(src.device, src.address, &pDst->deviceAddress) != OK) { - return false; - } - pDst->channelMapping.resize(AUDIO_CHANNEL_COUNT_MAX); - for (size_t ch = 0; ch < pDst->channelMapping.size(); ch++) { - pDst->channelMapping[ch] = AudioMicrophoneChannelMapping(src.channel_mapping[ch]); - } - pDst->location = AudioMicrophoneLocation(src.location); - pDst->group = (AudioMicrophoneGroup)src.group; - pDst->indexInTheGroup = (uint32_t)src.index_in_the_group; - pDst->sensitivity = src.sensitivity; - pDst->maxSpl = src.max_spl; - pDst->minSpl = src.min_spl; - pDst->directionality = AudioMicrophoneDirectionality(src.directionality); - pDst->frequencyResponse.resize(src.num_frequency_responses); - for (size_t k = 0; k < src.num_frequency_responses; k++) { - pDst->frequencyResponse[k].frequency = src.frequency_responses[0][k]; - pDst->frequencyResponse[k].level = src.frequency_responses[1][k]; - } - pDst->position.x = src.geometric_location.x; - pDst->position.y = src.geometric_location.y; - pDst->position.z = src.geometric_location.z; - - pDst->orientation.x = src.orientation.x; - pDst->orientation.y = src.orientation.y; - pDst->orientation.z = src.orientation.z; - - status = true; - } - return status; -} - -status_t sinkMetadataToHal(const SinkMetadata& sinkMetadata, - std::vector* halTracks) { - status_t result = NO_ERROR; - if (halTracks != nullptr) { - halTracks->reserve(sinkMetadata.tracks.size()); - } - for (auto& metadata : sinkMetadata.tracks) { - record_track_metadata halTrackMetadata{.gain = metadata.gain}; - CONVERT_CHECKED(HidlUtils::audioSourceToHal(metadata.source, &halTrackMetadata.source), - result); -#if MAJOR_VERSION >= 5 - if (metadata.destination.getDiscriminator() == - RecordTrackMetadata::Destination::hidl_discriminator::device) { - CONVERT_CHECKED( - deviceAddressToHal(metadata.destination.device(), &halTrackMetadata.dest_device, - halTrackMetadata.dest_device_address), - result); - } -#endif - if (halTracks != nullptr) { - halTracks->push_back(std::move(halTrackMetadata)); - } - } - return result; -} - -status_t sourceMetadataToHal(const SourceMetadata& sourceMetadata, - std::vector* halTracks) { - status_t result = NO_ERROR; - if (halTracks != nullptr) { - halTracks->reserve(sourceMetadata.tracks.size()); - } - for (auto& metadata : sourceMetadata.tracks) { - playback_track_metadata_t halTrackMetadata{.gain = metadata.gain}; - CONVERT_CHECKED(HidlUtils::audioUsageToHal(metadata.usage, &halTrackMetadata.usage), - result); - CONVERT_CHECKED(HidlUtils::audioContentTypeToHal(metadata.contentType, - &halTrackMetadata.content_type), - result); - if (halTracks != nullptr) { - halTracks->push_back(std::move(halTrackMetadata)); - } - } - return result; -} -#endif // MAJOR_VERSION >= 4 - -#if MAJOR_VERSION >= 7 -namespace xsd { -using namespace ::android::audio::policy::configuration::V7_0; -} - -bool audioInputFlagsToHal(const hidl_vec& flags, audio_input_flags_t* halFlags) { - bool success = true; - *halFlags = {}; - for (const auto& flag : flags) { - audio_input_flags_t halFlag; - if (!xsd::isUnknownAudioInOutFlag(flag) && - audio_input_flag_from_string(flag.c_str(), &halFlag)) { - *halFlags = static_cast(*halFlags | halFlag); - } else { - ALOGE("Unknown audio input flag \"%s\"", flag.c_str()); - success = false; - } - } - return success; -} - -bool audioOutputFlagsToHal(const hidl_vec& flags, audio_output_flags_t* halFlags) { - bool success = true; - *halFlags = {}; - for (const auto& flag : flags) { - audio_output_flags_t halFlag; - if (!xsd::isUnknownAudioInOutFlag(flag) && - audio_output_flag_from_string(flag.c_str(), &halFlag)) { - *halFlags = static_cast(*halFlags | halFlag); - } else { - ALOGE("Unknown audio output flag \"%s\"", flag.c_str()); - success = false; - } - } - return success; -} - -status_t sinkMetadataToHalV7(const SinkMetadata& sinkMetadata, - std::vector* halTracks) { - std::vector bases; - status_t result = sinkMetadataToHal(sinkMetadata, halTracks != nullptr ? &bases : nullptr); - if (halTracks != nullptr) { - halTracks->reserve(bases.size()); - } - auto baseIter = std::make_move_iterator(bases.begin()); - for (auto& metadata : sinkMetadata.tracks) { - record_track_metadata_v7_t halTrackMetadata; - CONVERT_CHECKED(HidlUtils::audioChannelMaskToHal(metadata.channelMask, - &halTrackMetadata.channel_mask), - result); - CONVERT_CHECKED(HidlUtils::audioTagsToHal(metadata.tags, halTrackMetadata.tags), result); - if (halTracks != nullptr) { - halTrackMetadata.base = std::move(*baseIter++); - halTracks->push_back(std::move(halTrackMetadata)); - } - } - return result; -} - -status_t sourceMetadataToHalV7(const SourceMetadata& sourceMetadata, - std::vector* halTracks) { - std::vector bases; - status_t result = sourceMetadataToHal(sourceMetadata, halTracks != nullptr ? &bases : nullptr); - if (halTracks != nullptr) { - halTracks->reserve(bases.size()); - } - auto baseIter = std::make_move_iterator(bases.begin()); - for (auto& metadata : sourceMetadata.tracks) { - playback_track_metadata_v7_t halTrackMetadata; - CONVERT_CHECKED(HidlUtils::audioChannelMaskToHal(metadata.channelMask, - &halTrackMetadata.channel_mask), - result); - CONVERT_CHECKED(HidlUtils::audioTagsToHal(metadata.tags, halTrackMetadata.tags), result); - if (halTracks != nullptr) { - halTrackMetadata.base = std::move(*baseIter++); - halTracks->push_back(std::move(halTrackMetadata)); - } - } - return result; -} -#endif - -} // namespace implementation -} // namespace CPP_VERSION -} // namespace audio -} // namespace hardware -} // namespace android diff --git a/audio/core/all-versions/default/Device.cpp b/audio/core/all-versions/default/Device.cpp index 7caed44bc9..70a1a4d1c1 100644 --- a/audio/core/all-versions/default/Device.cpp +++ b/audio/core/all-versions/default/Device.cpp @@ -17,9 +17,7 @@ #define LOG_TAG "DeviceHAL" #include "core/default/Device.h" -#include #include "common/all-versions/default/EffectMap.h" -#include "core/default/Conversions.h" #include "core/default/StreamIn.h" #include "core/default/StreamOut.h" #include "core/default/Util.h" @@ -33,6 +31,8 @@ #include +#include + namespace android { namespace hardware { namespace audio { @@ -160,11 +160,11 @@ std::tuple> Device::openOutputStreamImpl(int32_t ioHandle audio_stream_out_t* halStream; audio_devices_t halDevice; char halDeviceAddress[AUDIO_DEVICE_MAX_ADDRESS_LEN]; - if (deviceAddressToHal(device, &halDevice, halDeviceAddress) != NO_ERROR) { + if (CoreUtils::deviceAddressToHal(device, &halDevice, halDeviceAddress) != NO_ERROR) { return {Result::INVALID_ARGUMENTS, nullptr}; } audio_output_flags_t halFlags; - if (!audioOutputFlagsToHal(flags, &halFlags)) { + if (CoreUtils::audioOutputFlagsToHal(flags, &halFlags) != NO_ERROR) { return {Result::INVALID_ARGUMENTS, nullptr}; } ALOGV("open_output_stream handle: %d devices: %x flags: %#x " @@ -195,12 +195,12 @@ std::tuple> Device::openInputStreamImpl( audio_stream_in_t* halStream; audio_devices_t halDevice; char halDeviceAddress[AUDIO_DEVICE_MAX_ADDRESS_LEN]; - if (deviceAddressToHal(device, &halDevice, halDeviceAddress) != NO_ERROR) { + if (CoreUtils::deviceAddressToHal(device, &halDevice, halDeviceAddress) != NO_ERROR) { return {Result::INVALID_ARGUMENTS, nullptr}; } audio_input_flags_t halFlags; audio_source_t halSource; - if (!audioInputFlagsToHal(flags, &halFlags) || + if (CoreUtils::audioInputFlagsToHal(flags, &halFlags) != NO_ERROR || HidlUtils::audioSourceToHal(source, &halSource) != NO_ERROR) { return {Result::INVALID_ARGUMENTS, nullptr}; } @@ -254,9 +254,12 @@ Return Device::openOutputStream(int32_t ioHandle, const DeviceAddress& dev const SourceMetadata& sourceMetadata, openOutputStream_cb _hidl_cb) { #if MAJOR_VERSION <= 6 - if (status_t status = sourceMetadataToHal(sourceMetadata, nullptr); status != NO_ERROR) { + if (status_t status = CoreUtils::sourceMetadataToHal(sourceMetadata, nullptr); + status != NO_ERROR) { #else - if (status_t status = sourceMetadataToHalV7(sourceMetadata, nullptr); status != NO_ERROR) { + if (status_t status = CoreUtils::sourceMetadataToHalV7(sourceMetadata, + false /*ignoreNonVendorTags*/, nullptr); + status != NO_ERROR) { #endif _hidl_cb(analyzeStatus("sourceMetadataToHal", status), nullptr, AudioConfig{}); return Void(); @@ -288,9 +291,11 @@ Return Device::openInputStream(int32_t ioHandle, const DeviceAddress& devi return Void(); } #if MAJOR_VERSION <= 6 - if (status_t status = sinkMetadataToHal(sinkMetadata, nullptr); status != NO_ERROR) { + if (status_t status = CoreUtils::sinkMetadataToHal(sinkMetadata, nullptr); status != NO_ERROR) { #else - if (status_t status = sinkMetadataToHalV7(sinkMetadata, nullptr); status != NO_ERROR) { + if (status_t status = CoreUtils::sinkMetadataToHalV7(sinkMetadata, + false /*ignoreNonVendorTags*/, nullptr); + status != NO_ERROR) { #endif _hidl_cb(analyzeStatus("sinkMetadataToHal", status), nullptr, AudioConfig{}); return Void(); @@ -444,7 +449,7 @@ Return Device::getMicrophones(getMicrophones_cb _hidl_cb) { mDevice->get_microphones(mDevice, &mic_array[0], &actual_mics) == 0) { microphones.resize(actual_mics); for (size_t i = 0; i < actual_mics; ++i) { - halToMicrophoneCharacteristics(µphones[i], mic_array[i]); + (void)CoreUtils::microphoneInfoFromHal(mic_array[i], µphones[i]); } retval = Result::OK; } diff --git a/audio/core/all-versions/default/ParametersUtil.cpp b/audio/core/all-versions/default/ParametersUtil.cpp index 694eb73aee..4d536455d4 100644 --- a/audio/core/all-versions/default/ParametersUtil.cpp +++ b/audio/core/all-versions/default/ParametersUtil.cpp @@ -15,11 +15,12 @@ */ #include "core/default/ParametersUtil.h" -#include "core/default/Conversions.h" #include "core/default/Util.h" #include +#include + namespace android { namespace hardware { namespace audio { @@ -153,7 +154,7 @@ Result ParametersUtil::setParametersImpl(const hidl_vec& context Result ParametersUtil::setParam(const char* name, const DeviceAddress& address) { audio_devices_t halDeviceType; char halDeviceAddress[AUDIO_DEVICE_MAX_ADDRESS_LEN]; - if (deviceAddressToHal(address, &halDeviceType, halDeviceAddress) != NO_ERROR) { + if (CoreUtils::deviceAddressToHal(address, &halDeviceType, halDeviceAddress) != NO_ERROR) { return Result::INVALID_ARGUMENTS; } AudioParameter params{String8(halDeviceAddress)}; diff --git a/audio/core/all-versions/default/Stream.cpp b/audio/core/all-versions/default/Stream.cpp index 3f8efd231f..7e3257399c 100644 --- a/audio/core/all-versions/default/Stream.cpp +++ b/audio/core/all-versions/default/Stream.cpp @@ -19,7 +19,6 @@ #include "core/default/Stream.h" #include "common/all-versions/HidlSupport.h" #include "common/all-versions/default/EffectMap.h" -#include "core/default/Conversions.h" #include "core/default/Util.h" #include @@ -30,6 +29,7 @@ #include #include #include +#include namespace android { namespace hardware { @@ -373,9 +373,10 @@ Return Stream::getDevices(getDevices_cb _hidl_cb) { hidl_vec devices; if (retval == Result::OK) { devices.resize(1); - retval = Stream::analyzeStatus("get_devices", - deviceAddressFromHal(static_cast(halDevice), - nullptr, &devices[0])); + retval = Stream::analyzeStatus( + "get_devices", + CoreUtils::deviceAddressFromHal(static_cast(halDevice), nullptr, + &devices[0])); } _hidl_cb(retval, devices); return Void(); diff --git a/audio/core/all-versions/default/StreamIn.cpp b/audio/core/all-versions/default/StreamIn.cpp index c670a4da73..599f3c396e 100644 --- a/audio/core/all-versions/default/StreamIn.cpp +++ b/audio/core/all-versions/default/StreamIn.cpp @@ -17,7 +17,6 @@ #define LOG_TAG "StreamInHAL" #include "core/default/StreamIn.h" -#include "core/default/Conversions.h" #include "core/default/Util.h" #include "common/all-versions/HidlSupport.h" @@ -27,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -481,13 +481,15 @@ Return StreamIn::debug(const hidl_handle& fd, const hidl_vec& Result StreamIn::doUpdateSinkMetadata(const SinkMetadata& sinkMetadata) { std::vector halTracks; #if MAJOR_VERSION <= 6 - (void)sinkMetadataToHal(sinkMetadata, &halTracks); + (void)CoreUtils::sinkMetadataToHal(sinkMetadata, &halTracks); #else // Validate whether a conversion to V7 is possible. This is needed // to have a consistent behavior of the HAL regardless of the API // version of the legacy HAL (and also to be consistent with openInputStream). std::vector halTracksV7; - if (status_t status = sinkMetadataToHalV7(sinkMetadata, &halTracksV7); status == NO_ERROR) { + if (status_t status = CoreUtils::sinkMetadataToHalV7( + sinkMetadata, false /*ignoreNonVendorTags*/, &halTracksV7); + status == NO_ERROR) { halTracks.reserve(halTracksV7.size()); for (auto metadata_v7 : halTracksV7) { halTracks.push_back(std::move(metadata_v7.base)); @@ -507,7 +509,9 @@ Result StreamIn::doUpdateSinkMetadata(const SinkMetadata& sinkMetadata) { #if MAJOR_VERSION >= 7 Result StreamIn::doUpdateSinkMetadataV7(const SinkMetadata& sinkMetadata) { std::vector halTracks; - if (status_t status = sinkMetadataToHalV7(sinkMetadata, &halTracks); status != NO_ERROR) { + if (status_t status = CoreUtils::sinkMetadataToHalV7(sinkMetadata, + false /*ignoreNonVendorTags*/, &halTracks); + status != NO_ERROR) { return Stream::analyzeStatus("sinkMetadataToHal", status); } const sink_metadata_v7_t halMetadata = { @@ -553,7 +557,7 @@ Return StreamIn::getActiveMicrophones(getActiveMicrophones_cb _hidl_cb) { mStream->get_active_microphones(mStream, &mic_array[0], &actual_mics) == 0) { microphones.resize(actual_mics); for (size_t i = 0; i < actual_mics; ++i) { - halToMicrophoneCharacteristics(µphones[i], mic_array[i]); + (void)CoreUtils::microphoneInfoFromHal(mic_array[i], µphones[i]); } retval = Result::OK; } diff --git a/audio/core/all-versions/default/StreamOut.cpp b/audio/core/all-versions/default/StreamOut.cpp index c2ad7206ab..5e4dd2ad40 100644 --- a/audio/core/all-versions/default/StreamOut.cpp +++ b/audio/core/all-versions/default/StreamOut.cpp @@ -17,7 +17,6 @@ #define LOG_TAG "StreamOutHAL" #include "core/default/StreamOut.h" -#include "core/default/Conversions.h" #include "core/default/Util.h" //#define LOG_NDEBUG 0 @@ -30,6 +29,7 @@ #include #include #include +#include #include namespace android { @@ -589,13 +589,15 @@ Return StreamOut::debug(const hidl_handle& fd, const hidl_vec Result StreamOut::doUpdateSourceMetadata(const SourceMetadata& sourceMetadata) { std::vector halTracks; #if MAJOR_VERSION <= 6 - (void)sourceMetadataToHal(sourceMetadata, &halTracks); + (void)CoreUtils::sourceMetadataToHal(sourceMetadata, &halTracks); #else // Validate whether a conversion to V7 is possible. This is needed // to have a consistent behavior of the HAL regardless of the API // version of the legacy HAL (and also to be consistent with openOutputStream). std::vector halTracksV7; - if (status_t status = sourceMetadataToHalV7(sourceMetadata, &halTracksV7); status == NO_ERROR) { + if (status_t status = CoreUtils::sourceMetadataToHalV7( + sourceMetadata, false /*ignoreNonVendorTags*/, &halTracksV7); + status == NO_ERROR) { halTracks.reserve(halTracksV7.size()); for (auto metadata_v7 : halTracksV7) { halTracks.push_back(std::move(metadata_v7.base)); @@ -615,7 +617,9 @@ Result StreamOut::doUpdateSourceMetadata(const SourceMetadata& sourceMetadata) { #if MAJOR_VERSION >= 7 Result StreamOut::doUpdateSourceMetadataV7(const SourceMetadata& sourceMetadata) { std::vector halTracks; - if (status_t status = sourceMetadataToHalV7(sourceMetadata, &halTracks); status != NO_ERROR) { + if (status_t status = CoreUtils::sourceMetadataToHalV7( + sourceMetadata, false /*ignoreNonVendorTags*/, &halTracks); + status != NO_ERROR) { return Stream::analyzeStatus("sourceMetadataToHal", status); } const source_metadata_v7_t halMetadata = { diff --git a/audio/core/all-versions/default/TEST_MAPPING b/audio/core/all-versions/default/TEST_MAPPING new file mode 100644 index 0000000000..d53c97afaa --- /dev/null +++ b/audio/core/all-versions/default/TEST_MAPPING @@ -0,0 +1,7 @@ +{ + "presubmit": [ + { + "name": "android.hardware.audio@7.0-util_tests" + } + ] +} diff --git a/audio/core/all-versions/default/include/core/default/Conversions.h b/audio/core/all-versions/default/include/core/default/Conversions.h deleted file mode 100644 index 61720d5303..0000000000 --- a/audio/core/all-versions/default/include/core/default/Conversions.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_HARDWARE_AUDIO_CONVERSIONS_H_ -#define ANDROID_HARDWARE_AUDIO_CONVERSIONS_H_ - -#include PATH(android/hardware/audio/FILE_VERSION/types.h) - -#include - -#include - -#include - -namespace android { -namespace hardware { -namespace audio { -namespace CPP_VERSION { -namespace implementation { - -using ::android::hardware::hidl_vec; -using namespace ::android::hardware::audio::common::CPP_VERSION; -using namespace ::android::hardware::audio::CPP_VERSION; - -status_t deviceAddressToHal(const DeviceAddress& device, audio_devices_t* halDeviceType, - char* halDeviceAddress); -status_t deviceAddressFromHal(audio_devices_t halDeviceType, const char* halDeviceAddress, - DeviceAddress* device); - -#if MAJOR_VERSION >= 4 -bool halToMicrophoneCharacteristics(MicrophoneInfo* pDst, - const struct audio_microphone_characteristic_t& src); -status_t sinkMetadataToHal(const SinkMetadata& sinkMetadata, - std::vector* halTracks); -status_t sourceMetadataToHal(const SourceMetadata& sourceMetadata, - std::vector* halTracks); -#endif - -#if MAJOR_VERSION <= 6 -using AudioInputFlags = - ::android::hardware::audio::common::CPP_VERSION::implementation::AudioInputFlagBitfield; -using AudioOutputFlags = - ::android::hardware::audio::common::CPP_VERSION::implementation::AudioOutputFlagBitfield; - -inline bool audioInputFlagsToHal(AudioInputFlags flags, audio_input_flags_t* halFlags) { - *halFlags = static_cast(flags); - return true; -} - -inline bool audioOutputFlagsToHal(AudioOutputFlags flags, audio_output_flags_t* halFlags) { - *halFlags = static_cast(flags); - return true; -} -#else -bool audioInputFlagsToHal(const hidl_vec& flags, audio_input_flags_t* halFlags); -bool audioOutputFlagsToHal(const hidl_vec& flags, audio_output_flags_t* halFlags); -// Overloading isn't convenient when passing a nullptr. -status_t sinkMetadataToHalV7(const SinkMetadata& sinkMetadata, - std::vector* halTracks); -status_t sourceMetadataToHalV7(const SourceMetadata& sourceMetadata, - std::vector* halTracks); -#endif - -} // namespace implementation -} // namespace CPP_VERSION -} // namespace audio -} // namespace hardware -} // namespace android - -#endif // ANDROID_HARDWARE_AUDIO_CONVERSIONS_H_ diff --git a/audio/core/all-versions/default/include/core/default/Device.h b/audio/core/all-versions/default/include/core/default/Device.h index 2a4d22651a..5851fc949c 100644 --- a/audio/core/all-versions/default/include/core/default/Device.h +++ b/audio/core/all-versions/default/include/core/default/Device.h @@ -31,6 +31,7 @@ #include #include +#include namespace android { namespace hardware { @@ -43,17 +44,10 @@ using ::android::hardware::hidl_string; using ::android::hardware::hidl_vec; using ::android::hardware::Return; using ::android::hardware::Void; -#if MAJOR_VERSION <= 6 -using AudioInputFlags = - ::android::hardware::audio::common::CPP_VERSION::implementation::AudioInputFlagBitfield; -using AudioOutputFlags = - ::android::hardware::audio::common::CPP_VERSION::implementation::AudioOutputFlagBitfield; -#else -using AudioInputFlags = hidl_vec<::android::hardware::audio::CPP_VERSION::AudioInOutFlag>; -using AudioOutputFlags = hidl_vec<::android::hardware::audio::CPP_VERSION::AudioInOutFlag>; -#endif using namespace ::android::hardware::audio::common::CPP_VERSION; using namespace ::android::hardware::audio::CPP_VERSION; +using AudioInputFlags = CoreUtils::AudioInputFlags; +using AudioOutputFlags = CoreUtils::AudioOutputFlags; struct Device : public IDevice, public ParametersUtil { explicit Device(audio_hw_device_t* device); diff --git a/audio/core/all-versions/default/util/Android.bp b/audio/core/all-versions/default/util/Android.bp new file mode 100644 index 0000000000..447184bbe7 --- /dev/null +++ b/audio/core/all-versions/default/util/Android.bp @@ -0,0 +1,139 @@ +cc_defaults { + name: "android.hardware.audio-util_default", + defaults: ["hidl_defaults"], + + vendor_available: true, + + export_include_dirs: ["include"], + + srcs: [ + "CoreUtils.cpp", + ], + + shared_libs: [ + "liblog", + "libutils", + "libhidlbase", + "android.hardware.audio.common-util", + ], + export_shared_lib_headers: [ + "android.hardware.audio.common-util", + ], + + header_libs: [ + "libaudio_system_headers", + "libhardware_headers", + ], +} + +cc_library_shared { + name: "android.hardware.audio@2.0-util", + defaults: ["android.hardware.audio-util_default"], + shared_libs: [ + "android.hardware.audio.common@2.0", + "android.hardware.audio.common@2.0-util", + "android.hardware.audio@2.0", + ], + cflags: [ + "-DMAJOR_VERSION=2", + "-DMINOR_VERSION=0", + "-include common/all-versions/VersionMacro.h", + ], +} + +cc_library_shared { + name: "android.hardware.audio@4.0-util", + defaults: ["android.hardware.audio-util_default"], + shared_libs: [ + "android.hardware.audio.common@4.0", + "android.hardware.audio.common@4.0-util", + "android.hardware.audio@4.0", + ], + cflags: [ + "-DMAJOR_VERSION=4", + "-DMINOR_VERSION=0", + "-include common/all-versions/VersionMacro.h", + ], +} + +cc_library_shared { + name: "android.hardware.audio@5.0-util", + defaults: ["android.hardware.audio-util_default"], + shared_libs: [ + "android.hardware.audio.common@5.0", + "android.hardware.audio.common@5.0-util", + "android.hardware.audio@5.0", + ], + cflags: [ + "-DMAJOR_VERSION=5", + "-DMINOR_VERSION=0", + "-include common/all-versions/VersionMacro.h", + ], +} + +cc_library_shared { + name: "android.hardware.audio@6.0-util", + defaults: ["android.hardware.audio-util_default"], + shared_libs: [ + "android.hardware.audio.common@6.0", + "android.hardware.audio.common@6.0-util", + "android.hardware.audio@6.0", + ], + cflags: [ + "-DMAJOR_VERSION=6", + "-DMINOR_VERSION=0", + "-include common/all-versions/VersionMacro.h", + ], +} + +cc_library { + name: "android.hardware.audio@7.0-util", + defaults: ["android.hardware.audio-util_default"], + shared_libs: [ + "android.hardware.audio.common@7.0", + "android.hardware.audio.common@7.0-enums", + "android.hardware.audio.common@7.0-util", + "android.hardware.audio@7.0", + "libbase", + "libxml2", + ], + cflags: [ + "-DMAJOR_VERSION=7", + "-DMINOR_VERSION=0", + "-include common/all-versions/VersionMacro.h", + ], +} + +// Note: this isn't a VTS test, but rather a unit test +// to verify correctness of conversion utilities. +cc_test { + name: "android.hardware.audio@7.0-util_tests", + defaults: ["android.hardware.audio-util_default"], + + srcs: ["tests/coreutils_tests.cpp"], + + // Use static linking to allow running in presubmit on + // targets that don't have HAL V7. + static_libs: [ + "android.hardware.audio.common@7.0", + "android.hardware.audio.common@7.0-enums", + "android.hardware.audio.common@7.0-util", + "android.hardware.audio@7.0", + "android.hardware.audio@7.0-util", + ], + + shared_libs: [ + "libbase", + "libxml2", + ], + + cflags: [ + "-Werror", + "-Wall", + "-DMAJOR_VERSION=7", + "-DMINOR_VERSION=0", + "-include common/all-versions/VersionMacro.h", + ], + + test_suites: ["device-tests"], +} diff --git a/audio/core/all-versions/default/util/CoreUtils.cpp b/audio/core/all-versions/default/util/CoreUtils.cpp new file mode 100644 index 0000000000..14f76f3c65 --- /dev/null +++ b/audio/core/all-versions/default/util/CoreUtils.cpp @@ -0,0 +1,476 @@ +/* + * 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. + */ + +#if MAJOR_VERSION >= 7 +#include +#endif +#include +#include + +#include "util/CoreUtils.h" + +using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils; +#if MAJOR_VERSION >= 7 +namespace xsd { +using namespace ::android::audio::policy::configuration::V7_0; +} +#endif + +namespace android { +namespace hardware { +namespace audio { +namespace CPP_VERSION { +namespace implementation { + +#define CONVERT_CHECKED(expr, result) \ + if (status_t status = (expr); status != NO_ERROR) { \ + result = status; \ + } + +status_t CoreUtils::deviceAddressToHal(const DeviceAddress& device, audio_devices_t* halDeviceType, + char* halDeviceAddress) { +#if MAJOR_VERSION >= 5 + return HidlUtils::deviceAddressToHal(device, halDeviceType, halDeviceAddress); +#else + return HidlUtils::deviceAddressToHalImpl(device, halDeviceType, halDeviceAddress); +#endif +} + +status_t CoreUtils::deviceAddressFromHal(audio_devices_t halDeviceType, + const char* halDeviceAddress, DeviceAddress* device) { +#if MAJOR_VERSION >= 5 + return HidlUtils::deviceAddressFromHal(halDeviceType, halDeviceAddress, device); +#else + return HidlUtils::deviceAddressFromHalImpl(halDeviceType, halDeviceAddress, device); +#endif +} + +#if MAJOR_VERSION >= 4 +status_t CoreUtils::microphoneInfoFromHal( + const struct audio_microphone_characteristic_t& halMicInfo, MicrophoneInfo* micInfo) { + status_t result = NO_ERROR; + micInfo->deviceId = halMicInfo.device_id; + CONVERT_CHECKED( + deviceAddressFromHal(halMicInfo.device, halMicInfo.address, &micInfo->deviceAddress), + result); + size_t chCount; + for (chCount = 0; chCount < AUDIO_CHANNEL_COUNT_MAX; ++chCount) { + if (halMicInfo.channel_mapping[chCount] == AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED) { + break; + } + } + micInfo->channelMapping.resize(chCount); + for (size_t ch = 0; ch < micInfo->channelMapping.size(); ch++) { + micInfo->channelMapping[ch] = AudioMicrophoneChannelMapping(halMicInfo.channel_mapping[ch]); + } + micInfo->location = AudioMicrophoneLocation(halMicInfo.location); + micInfo->group = AudioMicrophoneGroup(halMicInfo.group); + micInfo->indexInTheGroup = static_cast(halMicInfo.index_in_the_group); + micInfo->sensitivity = halMicInfo.sensitivity; + micInfo->maxSpl = halMicInfo.max_spl; + micInfo->minSpl = halMicInfo.min_spl; + micInfo->directionality = AudioMicrophoneDirectionality(halMicInfo.directionality); + micInfo->frequencyResponse.resize(halMicInfo.num_frequency_responses); + for (size_t k = 0; k < halMicInfo.num_frequency_responses; k++) { + micInfo->frequencyResponse[k].frequency = halMicInfo.frequency_responses[0][k]; + micInfo->frequencyResponse[k].level = halMicInfo.frequency_responses[1][k]; + } + micInfo->position.x = halMicInfo.geometric_location.x; + micInfo->position.y = halMicInfo.geometric_location.y; + micInfo->position.z = halMicInfo.geometric_location.z; + micInfo->orientation.x = halMicInfo.orientation.x; + micInfo->orientation.y = halMicInfo.orientation.y; + micInfo->orientation.z = halMicInfo.orientation.z; + return result; +} + +status_t CoreUtils::microphoneInfoToHal(const MicrophoneInfo& micInfo, + audio_microphone_characteristic_t* halMicInfo) { + status_t result = NO_ERROR; + strncpy(halMicInfo->device_id, micInfo.deviceId.c_str(), AUDIO_MICROPHONE_ID_MAX_LEN); + halMicInfo->device_id[AUDIO_MICROPHONE_ID_MAX_LEN - 1] = '\0'; + if (micInfo.deviceId.size() >= AUDIO_MICROPHONE_ID_MAX_LEN) { + ALOGE("HIDL MicrophoneInfo device ID is too long: %zu", micInfo.deviceId.size()); + result = BAD_VALUE; + } + CONVERT_CHECKED( + deviceAddressToHal(micInfo.deviceAddress, &halMicInfo->device, halMicInfo->address), + result); + if (micInfo.channelMapping.size() > AUDIO_CHANNEL_COUNT_MAX) { + ALOGE("HIDL MicrophoneInfo has too many channelMapping elements: %zu", + micInfo.channelMapping.size()); + result = BAD_VALUE; + } + size_t ch; + for (ch = 0; ch < micInfo.channelMapping.size() && ch < AUDIO_CHANNEL_COUNT_MAX; ch++) { + halMicInfo->channel_mapping[ch] = + static_cast(micInfo.channelMapping[ch]); + } + for (; ch < AUDIO_CHANNEL_COUNT_MAX; ch++) { + halMicInfo->channel_mapping[ch] = AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED; + } + halMicInfo->location = static_cast(micInfo.location); + halMicInfo->group = static_cast(micInfo.group); + halMicInfo->index_in_the_group = static_cast(micInfo.indexInTheGroup); + halMicInfo->sensitivity = micInfo.sensitivity; + halMicInfo->max_spl = micInfo.maxSpl; + halMicInfo->min_spl = micInfo.minSpl; + halMicInfo->directionality = + static_cast(micInfo.directionality); + halMicInfo->num_frequency_responses = + static_cast(micInfo.frequencyResponse.size()); + if (halMicInfo->num_frequency_responses > AUDIO_MICROPHONE_MAX_FREQUENCY_RESPONSES) { + ALOGE("HIDL MicrophoneInfo has too many frequency responses: %u", + halMicInfo->num_frequency_responses); + halMicInfo->num_frequency_responses = AUDIO_MICROPHONE_MAX_FREQUENCY_RESPONSES; + result = BAD_VALUE; + } + for (size_t k = 0; k < halMicInfo->num_frequency_responses; k++) { + halMicInfo->frequency_responses[0][k] = micInfo.frequencyResponse[k].frequency; + halMicInfo->frequency_responses[1][k] = micInfo.frequencyResponse[k].level; + } + halMicInfo->geometric_location.x = micInfo.position.x; + halMicInfo->geometric_location.y = micInfo.position.y; + halMicInfo->geometric_location.z = micInfo.position.z; + halMicInfo->orientation.x = micInfo.orientation.x; + halMicInfo->orientation.y = micInfo.orientation.y; + halMicInfo->orientation.z = micInfo.orientation.z; + return result; +} + +status_t CoreUtils::sinkMetadataFromHal(const std::vector& halTracks, + SinkMetadata* sinkMetadata) { + status_t result = NO_ERROR; + sinkMetadata->tracks.resize(halTracks.size()); + for (size_t i = 0; i < sinkMetadata->tracks.size(); ++i) { + const auto& halTrackMetadata = halTracks[i]; + RecordTrackMetadata trackMetadata{}; + CONVERT_CHECKED( + HidlUtils::audioSourceFromHal(halTrackMetadata.source, &trackMetadata.source), + result); + trackMetadata.gain = halTrackMetadata.gain; +#if MAJOR_VERSION >= 5 + if (halTrackMetadata.dest_device != AUDIO_DEVICE_NONE) { + DeviceAddress address; + if (status_t status = + deviceAddressFromHal(halTrackMetadata.dest_device, + halTrackMetadata.dest_device_address, &address); + status == NO_ERROR) { + trackMetadata.destination.device(std::move(address)); + } else { + result = status; + } + } +#if MAJOR_VERSION >= 7 + trackMetadata.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_NONE); +#endif +#endif // MAJOR_VERSION >= 5 + sinkMetadata->tracks[i] = std::move(trackMetadata); + } + return result; +} + +status_t CoreUtils::sinkMetadataFromHalV7(const std::vector& halTracks, + bool ignoreNonVendorTags, SinkMetadata* sinkMetadata) { + std::vector bases; + bases.reserve(halTracks.size()); + std::transform(halTracks.begin(), halTracks.end(), std::back_inserter(bases), + [](const record_track_metadata_v7_t& src) -> record_track_metadata_t { + record_track_metadata_t result; + record_track_metadata_from_v7(&result, &src); + return result; + }); + status_t result = sinkMetadataFromHal(bases, sinkMetadata); +#if MAJOR_VERSION >= 7 + for (size_t i = 0; i < halTracks.size(); ++i) { + auto& trackMetadata = sinkMetadata->tracks[i]; + const auto& halTrackMetadata = halTracks[i]; + CONVERT_CHECKED( + HidlUtils::audioChannelMaskFromHal(halTrackMetadata.channel_mask, true /*isInput*/, + &trackMetadata.channelMask), + result); + std::vector strTags = HidlUtils::splitAudioTags(halTrackMetadata.tags); + if (ignoreNonVendorTags) { + strTags = HidlUtils::filterOutNonVendorTags(strTags); + } + CONVERT_CHECKED(HidlUtils::audioTagsFromHal(strTags, &trackMetadata.tags), result); + } +#else + (void)ignoreNonVendorTags; +#endif + return result; +} + +status_t CoreUtils::sinkMetadataToHal(const SinkMetadata& sinkMetadata, + std::vector* halTracks) { + status_t result = NO_ERROR; + if (halTracks != nullptr) { + halTracks->reserve(sinkMetadata.tracks.size()); + } + for (auto& trackMetadata : sinkMetadata.tracks) { + record_track_metadata halTrackMetadata{.gain = trackMetadata.gain}; + CONVERT_CHECKED(HidlUtils::audioSourceToHal(trackMetadata.source, &halTrackMetadata.source), + result); +#if MAJOR_VERSION >= 5 + if (trackMetadata.destination.getDiscriminator() == + RecordTrackMetadata::Destination::hidl_discriminator::device) { + CONVERT_CHECKED(deviceAddressToHal(trackMetadata.destination.device(), + &halTrackMetadata.dest_device, + halTrackMetadata.dest_device_address), + result); + } +#endif + if (halTracks != nullptr) { + halTracks->push_back(std::move(halTrackMetadata)); + } + } + return result; +} + +status_t CoreUtils::sinkMetadataToHalV7(const SinkMetadata& sinkMetadata, bool ignoreNonVendorTags, + std::vector* halTracks) { + std::vector bases; + status_t result = sinkMetadataToHal(sinkMetadata, halTracks != nullptr ? &bases : nullptr); + if (halTracks != nullptr) { + halTracks->reserve(sinkMetadata.tracks.size()); + } + for (size_t i = 0; i < sinkMetadata.tracks.size(); ++i) { + record_track_metadata_v7_t halTrackMetadata; + if (halTracks != nullptr) { + record_track_metadata_to_v7(&halTrackMetadata, &bases[i]); + } +#if MAJOR_VERSION >= 7 + const auto& trackMetadata = sinkMetadata.tracks[i]; + CONVERT_CHECKED(HidlUtils::audioChannelMaskToHal(trackMetadata.channelMask, + &halTrackMetadata.channel_mask), + result); + if (ignoreNonVendorTags) { + CONVERT_CHECKED( + HidlUtils::audioTagsToHal(HidlUtils::filterOutNonVendorTags(trackMetadata.tags), + halTrackMetadata.tags), + result); + } else { + CONVERT_CHECKED(HidlUtils::audioTagsToHal(trackMetadata.tags, halTrackMetadata.tags), + result); + } +#else + (void)ignoreNonVendorTags; +#endif + if (halTracks != nullptr) { + halTracks->push_back(std::move(halTrackMetadata)); + } + } + return result; +} + +status_t CoreUtils::sourceMetadataFromHal(const std::vector& halTracks, + SourceMetadata* sourceMetadata) { + status_t result = NO_ERROR; + sourceMetadata->tracks.resize(halTracks.size()); + for (size_t i = 0; i < sourceMetadata->tracks.size(); ++i) { + const auto& halTrackMetadata = halTracks[i]; + PlaybackTrackMetadata trackMetadata{}; + CONVERT_CHECKED(HidlUtils::audioUsageFromHal(halTrackMetadata.usage, &trackMetadata.usage), + result); + CONVERT_CHECKED(HidlUtils::audioContentTypeFromHal(halTrackMetadata.content_type, + &trackMetadata.contentType), + result); + trackMetadata.gain = halTrackMetadata.gain; +#if MAJOR_VERSION >= 7 + trackMetadata.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_NONE); +#endif + sourceMetadata->tracks[i] = std::move(trackMetadata); + } + return result; +} + +status_t CoreUtils::sourceMetadataFromHalV7( + const std::vector& halTracks, bool ignoreNonVendorTags, + SourceMetadata* sourceMetadata) { + std::vector bases; + bases.reserve(halTracks.size()); + std::transform(halTracks.begin(), halTracks.end(), std::back_inserter(bases), + [](const playback_track_metadata_v7_t& src) -> playback_track_metadata_t { + playback_track_metadata_t result; + playback_track_metadata_from_v7(&result, &src); + return result; + }); + status_t result = sourceMetadataFromHal(bases, sourceMetadata); +#if MAJOR_VERSION >= 7 + for (size_t i = 0; i < halTracks.size(); ++i) { + auto& trackMetadata = sourceMetadata->tracks[i]; + const auto& halTrackMetadata = halTracks[i]; + CONVERT_CHECKED( + HidlUtils::audioChannelMaskFromHal(halTrackMetadata.channel_mask, false /*isInput*/, + &trackMetadata.channelMask), + result); + std::vector strTags = HidlUtils::splitAudioTags(halTrackMetadata.tags); + if (ignoreNonVendorTags) { + strTags = HidlUtils::filterOutNonVendorTags(strTags); + } + CONVERT_CHECKED(HidlUtils::audioTagsFromHal(strTags, &trackMetadata.tags), result); + } +#else + (void)ignoreNonVendorTags; +#endif + return result; +} + +status_t CoreUtils::sourceMetadataToHal(const SourceMetadata& sourceMetadata, + std::vector* halTracks) { + status_t result = NO_ERROR; + if (halTracks != nullptr) { + halTracks->reserve(sourceMetadata.tracks.size()); + } + for (auto& trackMetadata : sourceMetadata.tracks) { + playback_track_metadata_t halTrackMetadata{.gain = trackMetadata.gain}; + CONVERT_CHECKED(HidlUtils::audioUsageToHal(trackMetadata.usage, &halTrackMetadata.usage), + result); + CONVERT_CHECKED(HidlUtils::audioContentTypeToHal(trackMetadata.contentType, + &halTrackMetadata.content_type), + result); + if (halTracks != nullptr) { + halTracks->push_back(std::move(halTrackMetadata)); + } + } + return result; +} + +status_t CoreUtils::sourceMetadataToHalV7(const SourceMetadata& sourceMetadata, + bool ignoreNonVendorTags, + std::vector* halTracks) { + std::vector bases; + status_t result = sourceMetadataToHal(sourceMetadata, halTracks != nullptr ? &bases : nullptr); + if (halTracks != nullptr) { + halTracks->reserve(sourceMetadata.tracks.size()); + } + for (size_t i = 0; i < sourceMetadata.tracks.size(); ++i) { + playback_track_metadata_v7_t halTrackMetadata; + if (halTracks != nullptr) { + playback_track_metadata_to_v7(&halTrackMetadata, &bases[i]); + } +#if MAJOR_VERSION >= 7 + const auto& trackMetadata = sourceMetadata.tracks[i]; + CONVERT_CHECKED(HidlUtils::audioChannelMaskToHal(trackMetadata.channelMask, + &halTrackMetadata.channel_mask), + result); + if (ignoreNonVendorTags) { + CONVERT_CHECKED( + HidlUtils::audioTagsToHal(HidlUtils::filterOutNonVendorTags(trackMetadata.tags), + halTrackMetadata.tags), + result); + } else { + CONVERT_CHECKED(HidlUtils::audioTagsToHal(trackMetadata.tags, halTrackMetadata.tags), + result); + } +#else + (void)ignoreNonVendorTags; +#endif + if (halTracks != nullptr) { + halTracks->push_back(std::move(halTrackMetadata)); + } + } + return result; +} +#endif // MAJOR_VERSION >= 4 + +#if MAJOR_VERSION >= 7 +namespace xsd { +using namespace ::android::audio::policy::configuration::V7_0; +} + +status_t CoreUtils::audioInputFlagsFromHal(audio_input_flags_t halFlagMask, + AudioInputFlags* flags) { + status_t status = NO_ERROR; + std::vector result; + for (uint32_t bit = 0; halFlagMask != 0 && bit < sizeof(audio_input_flags_t) * 8; ++bit) { + audio_input_flags_t flag = static_cast(1u << bit); + if ((flag & halFlagMask) == flag) { + AudioInOutFlag flagStr = audio_input_flag_to_string(flag); + if (!flagStr.empty() && !xsd::isUnknownAudioInOutFlag(flagStr)) { + result.push_back(flagStr); + } else { + ALOGE("Unknown audio input flag value 0x%X", flag); + status = BAD_VALUE; + } + halFlagMask = static_cast(halFlagMask & ~flag); + } + } + *flags = result; + return status; +} + +status_t CoreUtils::audioInputFlagsToHal(const AudioInputFlags& flags, + audio_input_flags_t* halFlagMask) { + status_t status = NO_ERROR; + *halFlagMask = {}; + for (const auto& flag : flags) { + audio_input_flags_t halFlag; + if (!xsd::isUnknownAudioInOutFlag(flag) && + audio_input_flag_from_string(flag.c_str(), &halFlag)) { + *halFlagMask = static_cast(*halFlagMask | halFlag); + } else { + ALOGE("Unknown audio input flag \"%s\"", flag.c_str()); + status = BAD_VALUE; + } + } + return status; +} + +status_t CoreUtils::audioOutputFlagsFromHal(audio_output_flags_t halFlagMask, + AudioOutputFlags* flags) { + status_t status = NO_ERROR; + std::vector result; + for (uint32_t bit = 0; halFlagMask != 0 && bit < sizeof(audio_output_flags_t) * 8; ++bit) { + audio_output_flags_t flag = static_cast(1u << bit); + if ((flag & halFlagMask) == flag) { + AudioInOutFlag flagStr = audio_output_flag_to_string(flag); + if (!flagStr.empty() && !xsd::isUnknownAudioInOutFlag(flagStr)) { + result.push_back(flagStr); + } else { + ALOGE("Unknown audio output flag value 0x%X", flag); + status = BAD_VALUE; + } + halFlagMask = static_cast(halFlagMask & ~flag); + } + } + *flags = result; + return status; +} + +status_t CoreUtils::audioOutputFlagsToHal(const AudioOutputFlags& flags, + audio_output_flags_t* halFlagMask) { + status_t status = NO_ERROR; + *halFlagMask = {}; + for (const auto& flag : flags) { + audio_output_flags_t halFlag; + if (!xsd::isUnknownAudioInOutFlag(flag) && + audio_output_flag_from_string(flag.c_str(), &halFlag)) { + *halFlagMask = static_cast(*halFlagMask | halFlag); + } else { + ALOGE("Unknown audio output flag \"%s\"", flag.c_str()); + status = BAD_VALUE; + } + } + return status; +} +#endif + +} // namespace implementation +} // namespace CPP_VERSION +} // namespace audio +} // namespace hardware +} // namespace android diff --git a/audio/core/all-versions/default/util/include/util/CoreUtils.h b/audio/core/all-versions/default/util/include/util/CoreUtils.h new file mode 100644 index 0000000000..1e5272a479 --- /dev/null +++ b/audio/core/all-versions/default/util/include/util/CoreUtils.h @@ -0,0 +1,110 @@ +/* + * 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 + +// clang-format off +#include PATH(android/hardware/audio/FILE_VERSION/types.h) +// clang-format off + +#include + +#include + +#include +#include + +namespace android { +namespace hardware { +namespace audio { +namespace CPP_VERSION { +namespace implementation { + +using ::android::hardware::audio::common::utils::EnumBitfield; +using ::android::hardware::hidl_vec; +using namespace ::android::hardware::audio::common::CPP_VERSION; +using namespace ::android::hardware::audio::CPP_VERSION; + +struct CoreUtils { + // Note: the converters for DeviceAddress have to be in CoreUtils for HAL V4 + // because DeviceAddress used to be defined in the core HAL. For V5 and above + // these functions simply delegate to HidlUtils. + static status_t deviceAddressToHal(const DeviceAddress& device, audio_devices_t* halDeviceType, + char* halDeviceAddress); + static status_t deviceAddressFromHal(audio_devices_t halDeviceType, const char* halDeviceAddress, + DeviceAddress* device); +#if MAJOR_VERSION >= 4 + static status_t microphoneInfoFromHal(const struct audio_microphone_characteristic_t& halMicInfo, + MicrophoneInfo* micInfo); + static status_t microphoneInfoToHal(const MicrophoneInfo& micInfo, audio_microphone_characteristic_t* halMicInfo); + // Note: {Sink|Source}Metadata types are defined in 'common' (since V5), so they can be used + // by the BT HAL. However, the converters are defined here, not in HidlUtils to avoid adding + // conditionals to handle V4. The converters are only used by 'core' HAL anyways. + static status_t sinkMetadataFromHal(const std::vector& halTracks, + SinkMetadata* sinkMetadata); + static status_t sinkMetadataFromHalV7(const std::vector& halTracks, + bool ignoreNonVendorTags, SinkMetadata* sinkMetadata); + static status_t sinkMetadataToHal(const SinkMetadata& sinkMetadata, + std::vector* halTracks); + static status_t sinkMetadataToHalV7(const SinkMetadata& sinkMetadata, bool ignoreNonVendorTags, + std::vector* halTracks); + static status_t sourceMetadataFromHal(const std::vector& halTracks, + SourceMetadata* sourceMetadata); + static status_t sourceMetadataFromHalV7(const std::vector& halTracks, + bool ignoreNonVendorTags, SourceMetadata* sourceMetadata); + static status_t sourceMetadataToHal(const SourceMetadata& sourceMetadata, + std::vector* halTracks); + static status_t sourceMetadataToHalV7(const SourceMetadata& sourceMetadata, bool ignoreNonVendorTags, + std::vector* halTracks); +#endif + +#if MAJOR_VERSION <= 6 + using AudioInputFlags = + ::android::hardware::audio::common::CPP_VERSION::implementation::AudioInputFlagBitfield; + using AudioOutputFlags = + ::android::hardware::audio::common::CPP_VERSION::implementation::AudioOutputFlagBitfield; + static inline status_t audioInputFlagsFromHal(audio_input_flags_t halFlagMask, AudioInputFlags* flags) { + *flags = EnumBitfield(halFlagMask); + return NO_ERROR; + } + static inline status_t audioInputFlagsToHal(AudioInputFlags flags, audio_input_flags_t* halFlagMask) { + *halFlagMask = static_cast(flags); + return NO_ERROR; + } + static inline status_t audioOutputFlagsFromHal(audio_output_flags_t halFlagMask, AudioOutputFlags* flags) { + *flags = EnumBitfield(halFlagMask); + return NO_ERROR; + } + static inline status_t audioOutputFlagsToHal(AudioOutputFlags flags, audio_output_flags_t* halFlagMask) { + *halFlagMask = static_cast(flags); + return NO_ERROR; + } +#else + using AudioInputFlags = hidl_vec<::android::hardware::audio::CPP_VERSION::AudioInOutFlag>; + using AudioOutputFlags = hidl_vec<::android::hardware::audio::CPP_VERSION::AudioInOutFlag>; + static status_t audioInputFlagsFromHal(audio_input_flags_t halFlagMask, AudioInputFlags* flags); + static status_t audioInputFlagsToHal(const AudioInputFlags& flags, audio_input_flags_t* halFlagMask); + static status_t audioOutputFlagsFromHal(audio_output_flags_t halFlagMask, AudioOutputFlags* flags); + static status_t audioOutputFlagsToHal(const AudioOutputFlags& flags, audio_output_flags_t* halFlagMask); +#endif + +}; + +} // namespace implementation +} // namespace CPP_VERSION +} // namespace audio +} // namespace hardware +} // namespace android diff --git a/audio/core/all-versions/default/util/tests/coreutils_tests.cpp b/audio/core/all-versions/default/util/tests/coreutils_tests.cpp new file mode 100644 index 0000000000..0c18482632 --- /dev/null +++ b/audio/core/all-versions/default/util/tests/coreutils_tests.cpp @@ -0,0 +1,525 @@ +/* + * 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 +#include + +#include + +#define LOG_TAG "CoreUtils_Test" +#include + +#include +#include +#include +#include + +using namespace android; +using namespace ::android::hardware::audio::common::CPP_VERSION; +using namespace ::android::hardware::audio::CPP_VERSION; +using ::android::hardware::hidl_vec; +using ::android::hardware::audio::CPP_VERSION::implementation::CoreUtils; +namespace xsd { +using namespace ::android::audio::policy::configuration::V7_0; +} + +static constexpr audio_channel_mask_t kInvalidHalChannelMask = AUDIO_CHANNEL_INVALID; +static constexpr audio_content_type_t kInvalidHalContentType = + static_cast(0xFFFFFFFFU); +static constexpr audio_devices_t kInvalidHalDevice = static_cast(0xFFFFFFFFU); +static constexpr audio_input_flags_t kInvalidInputFlags = + static_cast(0xFFFFFFFFU); +static constexpr audio_output_flags_t kInvalidOutputFlags = + static_cast(0xFFFFFFFFU); +// AUDIO_SOURCE_INVALID is framework-only. +static constexpr audio_source_t kInvalidHalSource = static_cast(-1); +static constexpr audio_usage_t kInvalidHalUsage = static_cast(0xFFFFFFFFU); + +static bool isInputFlag(xsd::AudioInOutFlag flag) { + return toString(flag).find("_INPUT_FLAG_") != std::string::npos; +} + +static bool isOutputFlag(xsd::AudioInOutFlag flag) { + return toString(flag).find("_OUTPUT_FLAG_") != std::string::npos; +} + +TEST(CoreUtils, ConvertInvalidInputFlagMask) { + CoreUtils::AudioInputFlags invalid; + EXPECT_EQ(BAD_VALUE, CoreUtils::audioInputFlagsFromHal(kInvalidInputFlags, &invalid)); + audio_input_flags_t halInvalid; + invalid.resize(1); + invalid[0] = "random string"; + EXPECT_EQ(BAD_VALUE, CoreUtils::audioInputFlagsToHal(invalid, &halInvalid)); +} + +TEST(CoreUtils, ConvertInputFlagMask) { + CoreUtils::AudioInputFlags emptyInputFlags; + audio_input_flags_t halEmptyInputFlags; + EXPECT_EQ(NO_ERROR, CoreUtils::audioInputFlagsToHal(emptyInputFlags, &halEmptyInputFlags)); + EXPECT_EQ(AUDIO_INPUT_FLAG_NONE, halEmptyInputFlags); + CoreUtils::AudioInputFlags emptyInputFlagsBack; + EXPECT_EQ(NO_ERROR, + CoreUtils::audioInputFlagsFromHal(halEmptyInputFlags, &emptyInputFlagsBack)); + EXPECT_EQ(emptyInputFlags, emptyInputFlagsBack); + CoreUtils::AudioInputFlags emptyInputFlagsFromNone; + EXPECT_EQ(NO_ERROR, + CoreUtils::audioInputFlagsFromHal(AUDIO_INPUT_FLAG_NONE, &emptyInputFlagsFromNone)); + EXPECT_EQ(emptyInputFlags, emptyInputFlagsFromNone); + + std::vector allEnumValues; + for (const auto enumVal : xsdc_enum_range{}) { + if (isInputFlag(enumVal)) { + allEnumValues.push_back(toString(enumVal)); + } + } + CoreUtils::AudioInputFlags allInputFlags; + allInputFlags.resize(allEnumValues.size()); + for (size_t i = 0; i < allEnumValues.size(); ++i) { + allInputFlags[i] = allEnumValues[i]; + } + audio_input_flags_t halAllInputFlags; + EXPECT_EQ(NO_ERROR, CoreUtils::audioInputFlagsToHal(allInputFlags, &halAllInputFlags)); + CoreUtils::AudioInputFlags allInputFlagsBack; + EXPECT_EQ(NO_ERROR, CoreUtils::audioInputFlagsFromHal(halAllInputFlags, &allInputFlagsBack)); + EXPECT_EQ(allInputFlags, allInputFlagsBack); +} + +TEST(CoreUtils, ConvertInvalidOutputFlagMask) { + CoreUtils::AudioOutputFlags invalid; + EXPECT_EQ(BAD_VALUE, CoreUtils::audioOutputFlagsFromHal(kInvalidOutputFlags, &invalid)); + audio_output_flags_t halInvalid; + invalid.resize(1); + invalid[0] = "random string"; + EXPECT_EQ(BAD_VALUE, CoreUtils::audioOutputFlagsToHal(invalid, &halInvalid)); +} + +TEST(CoreUtils, ConvertOutputFlagMask) { + CoreUtils::AudioOutputFlags emptyOutputFlags; + audio_output_flags_t halEmptyOutputFlags; + EXPECT_EQ(NO_ERROR, CoreUtils::audioOutputFlagsToHal(emptyOutputFlags, &halEmptyOutputFlags)); + EXPECT_EQ(AUDIO_OUTPUT_FLAG_NONE, halEmptyOutputFlags); + CoreUtils::AudioOutputFlags emptyOutputFlagsBack; + EXPECT_EQ(NO_ERROR, + CoreUtils::audioOutputFlagsFromHal(halEmptyOutputFlags, &emptyOutputFlagsBack)); + EXPECT_EQ(emptyOutputFlags, emptyOutputFlagsBack); + CoreUtils::AudioOutputFlags emptyOutputFlagsFromNone; + EXPECT_EQ(NO_ERROR, CoreUtils::audioOutputFlagsFromHal(AUDIO_OUTPUT_FLAG_NONE, + &emptyOutputFlagsFromNone)); + EXPECT_EQ(emptyOutputFlags, emptyOutputFlagsFromNone); + + std::vector allEnumValues; + for (const auto enumVal : xsdc_enum_range{}) { + if (isOutputFlag(enumVal)) { + allEnumValues.push_back(toString(enumVal)); + } + } + CoreUtils::AudioOutputFlags allOutputFlags; + allOutputFlags.resize(allEnumValues.size()); + for (size_t i = 0; i < allEnumValues.size(); ++i) { + allOutputFlags[i] = allEnumValues[i]; + } + audio_output_flags_t halAllOutputFlags; + EXPECT_EQ(NO_ERROR, CoreUtils::audioOutputFlagsToHal(allOutputFlags, &halAllOutputFlags)); + CoreUtils::AudioOutputFlags allOutputFlagsBack; + EXPECT_EQ(NO_ERROR, CoreUtils::audioOutputFlagsFromHal(halAllOutputFlags, &allOutputFlagsBack)); + EXPECT_EQ(allOutputFlags, allOutputFlagsBack); +} + +static MicrophoneInfo generateValidMicrophoneInfo() { + MicrophoneInfo micInfo{}; + micInfo.deviceAddress.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_IN_BUILTIN_MIC); + micInfo.channelMapping.resize(1); + micInfo.channelMapping[0] = AudioMicrophoneChannelMapping::DIRECT; + micInfo.location = AudioMicrophoneLocation::MAINBODY_MOVABLE; + micInfo.group = 42; + micInfo.indexInTheGroup = 13; + micInfo.sensitivity = 65.5; + micInfo.maxSpl = 100.5; + micInfo.minSpl = 36.6; + micInfo.directionality = AudioMicrophoneDirectionality::HYPER_CARDIOID; + micInfo.frequencyResponse.resize(1); + micInfo.frequencyResponse[0].frequency = 1000; + micInfo.frequencyResponse[0].level = 85; + micInfo.position.x = 0; + micInfo.position.y = 1; + micInfo.position.z = 0; + micInfo.orientation.x = 0; + micInfo.orientation.y = 0; + micInfo.orientation.z = 1; + return micInfo; +} + +TEST(CoreUtils, ConvertInvalidMicrophoneInfo) { + MicrophoneInfo invalid; + audio_microphone_characteristic_t halInvalid{}; + halInvalid.device = kInvalidHalDevice; + EXPECT_EQ(BAD_VALUE, CoreUtils::microphoneInfoFromHal(halInvalid, &invalid)); + + MicrophoneInfo oversizeDeviceId = generateValidMicrophoneInfo(); + oversizeDeviceId.deviceId = std::string(AUDIO_MICROPHONE_ID_MAX_LEN + 1, 'A'); + EXPECT_EQ(BAD_VALUE, CoreUtils::microphoneInfoToHal(oversizeDeviceId, &halInvalid)); + MicrophoneInfo invalidDeviceType = generateValidMicrophoneInfo(); + invalidDeviceType.deviceAddress.deviceType = "random string"; + EXPECT_EQ(BAD_VALUE, CoreUtils::microphoneInfoToHal(invalidDeviceType, &halInvalid)); + MicrophoneInfo oversizeChannelMapping = generateValidMicrophoneInfo(); + oversizeChannelMapping.channelMapping.resize(AUDIO_CHANNEL_COUNT_MAX + 1); + EXPECT_EQ(BAD_VALUE, CoreUtils::microphoneInfoToHal(oversizeChannelMapping, &halInvalid)); + MicrophoneInfo oversizeFrequencyResponses = generateValidMicrophoneInfo(); + oversizeFrequencyResponses.frequencyResponse.resize(AUDIO_MICROPHONE_MAX_FREQUENCY_RESPONSES + + 1); + EXPECT_EQ(BAD_VALUE, CoreUtils::microphoneInfoToHal(oversizeFrequencyResponses, &halInvalid)); +} + +TEST(CoreUtils, ConvertMicrophoneInfo) { + MicrophoneInfo micInfo = generateValidMicrophoneInfo(); + audio_microphone_characteristic_t halMicInfo; + EXPECT_EQ(NO_ERROR, CoreUtils::microphoneInfoToHal(micInfo, &halMicInfo)); + MicrophoneInfo micInfoBack; + EXPECT_EQ(NO_ERROR, CoreUtils::microphoneInfoFromHal(halMicInfo, &micInfoBack)); + EXPECT_EQ(micInfo, micInfoBack); +} + +static RecordTrackMetadata generateMinimalRecordTrackMetadata() { + RecordTrackMetadata metadata{}; + metadata.source = toString(xsd::AudioSource::AUDIO_SOURCE_DEFAULT); + metadata.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_NONE); + return metadata; +} + +static RecordTrackMetadata generateValidRecordTrackMetadata() { + RecordTrackMetadata metadata = generateMinimalRecordTrackMetadata(); + metadata.tags.resize(1); + metadata.tags[0] = "VX_GOOGLE_42"; + metadata.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_IN_MONO); + metadata.gain = 1.0; + return metadata; +} + +static RecordTrackMetadata generateValidRecordTrackMetadataWithDevice() { + RecordTrackMetadata metadata = generateValidRecordTrackMetadata(); + metadata.destination.device({}); + metadata.destination.device().deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_OUT_SPEAKER); + return metadata; +} + +using SinkTracks = hidl_vec; + +TEST(CoreUtils, ConvertInvalidSinkMetadata) { + SinkMetadata invalidSource; + invalidSource.tracks = SinkTracks{generateMinimalRecordTrackMetadata()}; + invalidSource.tracks[0].source = "random string"; + EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataToHal(invalidSource, nullptr)); + EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataToHalV7(invalidSource, + false /*ignoreNonVendorTags*/, nullptr)); + EXPECT_EQ(BAD_VALUE, + CoreUtils::sinkMetadataToHalV7(invalidSource, true /*ignoreNonVendorTags*/, nullptr)); + SinkMetadata invalidDeviceType; + invalidDeviceType.tracks = SinkTracks{generateValidRecordTrackMetadataWithDevice()}; + invalidDeviceType.tracks[0].destination.device().deviceType = "random string"; + EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataToHal(invalidDeviceType, nullptr)); + EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataToHalV7(invalidDeviceType, + false /*ignoreNonVendorTags*/, nullptr)); + EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataToHalV7(invalidDeviceType, + true /*ignoreNonVendorTags*/, nullptr)); + SinkMetadata invalidChannelMask; + invalidChannelMask.tracks = SinkTracks{generateValidRecordTrackMetadata()}; + invalidChannelMask.tracks[0].channelMask = "random string"; + // Channel mask is sliced away by 'sinkMetadataToHal' + EXPECT_EQ(NO_ERROR, CoreUtils::sinkMetadataToHal(invalidChannelMask, nullptr)); + EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataToHalV7(invalidChannelMask, + false /*ignoreNonVendorTags*/, nullptr)); + EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataToHalV7(invalidChannelMask, + true /*ignoreNonVendorTags*/, nullptr)); + SinkMetadata invalidTags; + invalidTags.tracks = SinkTracks{generateValidRecordTrackMetadata()}; + invalidTags.tracks[0].tags[0] = "random string"; + // Tags are sliced away by 'sinkMetadataToHal' + EXPECT_EQ(NO_ERROR, CoreUtils::sinkMetadataToHal(invalidTags, nullptr)); + EXPECT_EQ(BAD_VALUE, + CoreUtils::sinkMetadataToHalV7(invalidTags, false /*ignoreNonVendorTags*/, nullptr)); + // Non-vendor tags should be filtered out. + EXPECT_EQ(NO_ERROR, + CoreUtils::sinkMetadataToHalV7(invalidTags, true /*ignoreNonVendorTags*/, nullptr)); + + // Verify that a default-initialized metadata is valid. + std::vector halValid(1, record_track_metadata_t{}); + std::vector halValidV7(1, record_track_metadata_v7_t{}); + SinkMetadata valid; + EXPECT_EQ(NO_ERROR, CoreUtils::sinkMetadataFromHal(halValid, &valid)); + EXPECT_EQ(NO_ERROR, + CoreUtils::sinkMetadataFromHalV7(halValidV7, false /*ignoreNonVendorTags*/, &valid)); + EXPECT_EQ(NO_ERROR, + CoreUtils::sinkMetadataFromHalV7(halValidV7, true /*ignoreNonVendorTags*/, &valid)); + + std::vector halInvalidSource = {{.source = kInvalidHalSource}}; + std::vector halInvalidSourceV7 = { + {.base = {.source = kInvalidHalSource}}}; + EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataFromHal(halInvalidSource, &invalidSource)); + EXPECT_EQ(BAD_VALUE, + CoreUtils::sinkMetadataFromHalV7(halInvalidSourceV7, false /*ignoreNonVendorTags*/, + &invalidSource)); + EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataFromHalV7( + halInvalidSourceV7, true /*ignoreNonVendorTags*/, &invalidSource)); + std::vector halInvalidDeviceType = { + {.dest_device = kInvalidHalDevice}}; + std::vector halInvalidDeviceTypeV7 = { + {.base = {.dest_device = kInvalidHalDevice}}}; + EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataFromHal(halInvalidDeviceType, &invalidDeviceType)); + EXPECT_EQ(BAD_VALUE, + CoreUtils::sinkMetadataFromHalV7(halInvalidDeviceTypeV7, + false /*ignoreNonVendorTags*/, &invalidDeviceType)); + EXPECT_EQ(BAD_VALUE, + CoreUtils::sinkMetadataFromHalV7(halInvalidDeviceTypeV7, true /*ignoreNonVendorTags*/, + &invalidDeviceType)); + std::vector halInvalidChannelMaskV7 = { + {.channel_mask = kInvalidHalChannelMask}}; + EXPECT_EQ(BAD_VALUE, + CoreUtils::sinkMetadataFromHalV7(halInvalidChannelMaskV7, + false /*ignoreNonVendorTags*/, &invalidChannelMask)); + EXPECT_EQ(BAD_VALUE, + CoreUtils::sinkMetadataFromHalV7(halInvalidChannelMaskV7, + true /*ignoreNonVendorTags*/, &invalidChannelMask)); + std::vector halInvalidTagsV7 = {{.tags = "random string"}}; + EXPECT_EQ(BAD_VALUE, CoreUtils::sinkMetadataFromHalV7( + halInvalidTagsV7, false /*ignoreNonVendorTags*/, &invalidTags)); + // Non-vendor tags should be filtered out. + EXPECT_EQ(NO_ERROR, CoreUtils::sinkMetadataFromHalV7( + halInvalidTagsV7, true /*ignoreNonVendorTags*/, &invalidTags)); +} + +TEST(CoreUtils, ConvertEmptySinkMetadata) { + SinkMetadata emptySinkMetadata; + std::vector halEmptySinkMetadata; + EXPECT_EQ(NO_ERROR, CoreUtils::sinkMetadataToHal(emptySinkMetadata, &halEmptySinkMetadata)); + EXPECT_TRUE(halEmptySinkMetadata.empty()); + SinkMetadata emptySinkMetadataBack; + EXPECT_EQ(NO_ERROR, + CoreUtils::sinkMetadataFromHal(halEmptySinkMetadata, &emptySinkMetadataBack)); + EXPECT_EQ(emptySinkMetadata, emptySinkMetadataBack); + std::vector halEmptySinkMetadataV7; + EXPECT_EQ(NO_ERROR, + CoreUtils::sinkMetadataToHalV7(emptySinkMetadata, false /*ignoreNonVendorTags*/, + &halEmptySinkMetadataV7)); + EXPECT_TRUE(halEmptySinkMetadataV7.empty()); + SinkMetadata emptySinkMetadataBackFromV7; + EXPECT_EQ(NO_ERROR, CoreUtils::sinkMetadataFromHalV7(halEmptySinkMetadataV7, + false /*ignoreNonVendorTags*/, + &emptySinkMetadataBackFromV7)); + EXPECT_EQ(emptySinkMetadata, emptySinkMetadataBackFromV7); +} + +class SinkMetadataConvertTest : public ::testing::TestWithParam {}; + +TEST_P(SinkMetadataConvertTest, ToFromHal) { + SinkMetadata sinkMetadata; + sinkMetadata.tracks = GetParam(); + std::vector halSinkMetadata; + EXPECT_EQ(NO_ERROR, CoreUtils::sinkMetadataToHal(sinkMetadata, &halSinkMetadata)); + EXPECT_EQ(sinkMetadata.tracks.size(), halSinkMetadata.size()); + SinkMetadata sinkMetadataBackTrimmed; + EXPECT_EQ(NO_ERROR, CoreUtils::sinkMetadataFromHal(halSinkMetadata, &sinkMetadataBackTrimmed)); + // Can't compare 'sinkMetadata' to 'sinkMetadataBackTrimmed' + std::vector halSinkMetadataV7; + EXPECT_EQ(NO_ERROR, CoreUtils::sinkMetadataToHalV7(sinkMetadata, false /*ignoreNonVendorTags*/, + &halSinkMetadataV7)); + EXPECT_EQ(sinkMetadata.tracks.size(), halSinkMetadataV7.size()); + SinkMetadata sinkMetadataBackFromV7; + EXPECT_EQ(NO_ERROR, + CoreUtils::sinkMetadataFromHalV7(halSinkMetadataV7, false /*ignoreNonVendorTags*/, + &sinkMetadataBackFromV7)); + EXPECT_EQ(sinkMetadata, sinkMetadataBackFromV7); + std::vector halSinkMetadataV7FromTrimmed; + EXPECT_EQ(NO_ERROR, + CoreUtils::sinkMetadataToHalV7(sinkMetadataBackTrimmed, false /*ignoreNonVendorTags*/, + &halSinkMetadataV7FromTrimmed)); + EXPECT_EQ(sinkMetadata.tracks.size(), halSinkMetadataV7FromTrimmed.size()); + SinkMetadata sinkMetadataBackFromV7Trimmed; + EXPECT_EQ(NO_ERROR, CoreUtils::sinkMetadataFromHalV7(halSinkMetadataV7FromTrimmed, + false /*ignoreNonVendorTags*/, + &sinkMetadataBackFromV7Trimmed)); + EXPECT_EQ(sinkMetadataBackTrimmed, sinkMetadataBackFromV7Trimmed); +} + +INSTANTIATE_TEST_SUITE_P(ValidRecordTrackMetadatas, SinkMetadataConvertTest, + ::testing::Values(SinkTracks{generateMinimalRecordTrackMetadata()}, + SinkTracks{generateValidRecordTrackMetadata()}, + SinkTracks{generateValidRecordTrackMetadataWithDevice()}, + SinkTracks{ + generateMinimalRecordTrackMetadata(), + generateValidRecordTrackMetadata(), + generateValidRecordTrackMetadataWithDevice()})); + +static PlaybackTrackMetadata generateMinimalPlaybackTrackMetadata() { + PlaybackTrackMetadata metadata{}; + metadata.usage = toString(xsd::AudioUsage::AUDIO_USAGE_UNKNOWN); + metadata.contentType = toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_UNKNOWN); + metadata.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_NONE); + return metadata; +} + +static PlaybackTrackMetadata generateValidPlaybackTrackMetadata() { + PlaybackTrackMetadata metadata = generateMinimalPlaybackTrackMetadata(); + metadata.tags.resize(1); + metadata.tags[0] = "VX_GOOGLE_42"; + metadata.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_MONO); + metadata.gain = 1.0; + return metadata; +} + +using SourceTracks = hidl_vec; + +TEST(CoreUtils, ConvertInvalidSourceMetadata) { + SourceMetadata invalidUsage; + invalidUsage.tracks = SourceTracks{generateMinimalPlaybackTrackMetadata()}; + invalidUsage.tracks[0].usage = "random string"; + EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataToHal(invalidUsage, nullptr)); + EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataToHalV7(invalidUsage, + false /*ignoreNonVendorTags*/, nullptr)); + SourceMetadata invalidContentType; + invalidContentType.tracks = SourceTracks{generateMinimalPlaybackTrackMetadata()}; + invalidContentType.tracks[0].contentType = "random string"; + EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataToHal(invalidContentType, nullptr)); + EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataToHalV7(invalidContentType, + false /*ignoreNonVendorTags*/, nullptr)); + EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataToHalV7(invalidContentType, + true /*ignoreNonVendorTags*/, nullptr)); + SourceMetadata invalidChannelMask; + invalidChannelMask.tracks = SourceTracks{generateValidPlaybackTrackMetadata()}; + invalidChannelMask.tracks[0].channelMask = "random string"; + // Channel mask is sliced away by 'sourceMetadataToHal' + EXPECT_EQ(NO_ERROR, CoreUtils::sourceMetadataToHal(invalidChannelMask, nullptr)); + EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataToHalV7(invalidChannelMask, + false /*ignoreNonVendorTags*/, nullptr)); + EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataToHalV7(invalidChannelMask, + true /*ignoreNonVendorTags*/, nullptr)); + SourceMetadata invalidTags; + invalidTags.tracks = SourceTracks{generateValidPlaybackTrackMetadata()}; + invalidTags.tracks[0].tags[0] = "random string"; + // Tags are sliced away by 'sourceMetadataToHal' + EXPECT_EQ(NO_ERROR, CoreUtils::sourceMetadataToHal(invalidTags, nullptr)); + EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataToHalV7(invalidTags, + false /*ignoreNonVendorTags*/, nullptr)); + // Non-vendor tags should be filtered out. + EXPECT_EQ(NO_ERROR, + CoreUtils::sourceMetadataToHalV7(invalidTags, true /*ignoreNonVendorTags*/, nullptr)); + + // Verify that a default-initialized metadata is valid. + std::vector halValid(1, playback_track_metadata_t{}); + std::vector halValidV7(1, playback_track_metadata_v7_t{}); + SourceMetadata valid; + EXPECT_EQ(NO_ERROR, CoreUtils::sourceMetadataFromHal(halValid, &valid)); + EXPECT_EQ(NO_ERROR, CoreUtils::sourceMetadataFromHalV7(halValidV7, + false /*ignoreNonVendorTags*/, &valid)); + EXPECT_EQ(NO_ERROR, + CoreUtils::sourceMetadataFromHalV7(halValidV7, true /*ignoreNonVendorTags*/, &valid)); + + std::vector halInvalidUsage = {{.usage = kInvalidHalUsage}}; + std::vector halInvalidUsageV7 = { + {.base = {.usage = kInvalidHalUsage}}}; + EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataFromHal(halInvalidUsage, &invalidUsage)); + EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataFromHalV7( + halInvalidUsageV7, false /*ignoreNonVendorTags*/, &invalidUsage)); + EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataFromHalV7( + halInvalidUsageV7, true /*ignoreNonVendorTags*/, &invalidUsage)); + std::vector halInvalidContentType = { + {.content_type = kInvalidHalContentType}}; + std::vector halInvalidContentTypeV7 = { + {.base = {.content_type = kInvalidHalContentType}}}; + EXPECT_EQ(BAD_VALUE, + CoreUtils::sourceMetadataFromHal(halInvalidContentType, &invalidContentType)); + EXPECT_EQ(BAD_VALUE, + CoreUtils::sourceMetadataFromHalV7( + halInvalidContentTypeV7, false /*ignoreNonVendorTags*/, &invalidContentType)); + EXPECT_EQ(BAD_VALUE, + CoreUtils::sourceMetadataFromHalV7( + halInvalidContentTypeV7, true /*ignoreNonVendorTags*/, &invalidContentType)); + std::vector halInvalidChannelMaskV7 = { + {.channel_mask = kInvalidHalChannelMask}}; + EXPECT_EQ(BAD_VALUE, + CoreUtils::sourceMetadataFromHalV7( + halInvalidChannelMaskV7, false /*ignoreNonVendorTags*/, &invalidChannelMask)); + EXPECT_EQ(BAD_VALUE, + CoreUtils::sourceMetadataFromHalV7( + halInvalidChannelMaskV7, true /*ignoreNonVendorTags*/, &invalidChannelMask)); + std::vector halInvalidTagsV7 = {{.tags = "random string"}}; + EXPECT_EQ(BAD_VALUE, CoreUtils::sourceMetadataFromHalV7( + halInvalidTagsV7, false /*ignoreNonVendorTags*/, &invalidTags)); + // Non-vendor tags should be filtered out. + EXPECT_EQ(NO_ERROR, CoreUtils::sourceMetadataFromHalV7( + halInvalidTagsV7, true /*ignoreNonVendorTags*/, &invalidTags)); +} + +TEST(CoreUtils, ConvertEmptySourceMetadata) { + SourceMetadata emptySourceMetadata; + std::vector halEmptySourceMetadata; + EXPECT_EQ(NO_ERROR, + CoreUtils::sourceMetadataToHal(emptySourceMetadata, &halEmptySourceMetadata)); + EXPECT_TRUE(halEmptySourceMetadata.empty()); + SourceMetadata emptySourceMetadataBack; + EXPECT_EQ(NO_ERROR, + CoreUtils::sourceMetadataFromHal(halEmptySourceMetadata, &emptySourceMetadataBack)); + EXPECT_EQ(emptySourceMetadata, emptySourceMetadataBack); + std::vector halEmptySourceMetadataV7; + EXPECT_EQ(NO_ERROR, + CoreUtils::sourceMetadataToHalV7(emptySourceMetadata, false /*ignoreNonVendorTags*/, + &halEmptySourceMetadataV7)); + EXPECT_TRUE(halEmptySourceMetadataV7.empty()); + SourceMetadata emptySourceMetadataBackFromV7; + EXPECT_EQ(NO_ERROR, CoreUtils::sourceMetadataFromHalV7(halEmptySourceMetadataV7, + false /*ignoreNonVendorTags*/, + &emptySourceMetadataBackFromV7)); + EXPECT_EQ(emptySourceMetadata, emptySourceMetadataBackFromV7); +} + +class SourceMetadataConvertTest : public ::testing::TestWithParam {}; + +TEST_P(SourceMetadataConvertTest, ToFromHal) { + SourceMetadata sourceMetadata; + sourceMetadata.tracks = GetParam(); + std::vector halSourceMetadata; + EXPECT_EQ(NO_ERROR, CoreUtils::sourceMetadataToHal(sourceMetadata, &halSourceMetadata)); + EXPECT_EQ(sourceMetadata.tracks.size(), halSourceMetadata.size()); + SourceMetadata sourceMetadataBackTrimmed; + EXPECT_EQ(NO_ERROR, + CoreUtils::sourceMetadataFromHal(halSourceMetadata, &sourceMetadataBackTrimmed)); + // Can't compare 'sourceMetadata' to 'sourceMetadataBackTrimmed' + std::vector halSourceMetadataV7; + EXPECT_EQ(NO_ERROR, + CoreUtils::sourceMetadataToHalV7(sourceMetadata, false /*ignoreNonVendorTags*/, + &halSourceMetadataV7)); + EXPECT_EQ(sourceMetadata.tracks.size(), halSourceMetadataV7.size()); + SourceMetadata sourceMetadataBackFromV7; + EXPECT_EQ(NO_ERROR, + CoreUtils::sourceMetadataFromHalV7(halSourceMetadataV7, false /*ignoreNonVendorTags*/, + &sourceMetadataBackFromV7)); + EXPECT_EQ(sourceMetadata, sourceMetadataBackFromV7); + std::vector halSourceMetadataV7FromTrimmed; + EXPECT_EQ(NO_ERROR, CoreUtils::sourceMetadataToHalV7(sourceMetadataBackTrimmed, + false /*ignoreNonVendorTags*/, + &halSourceMetadataV7FromTrimmed)); + EXPECT_EQ(sourceMetadata.tracks.size(), halSourceMetadataV7FromTrimmed.size()); + SourceMetadata sourceMetadataBackFromV7Trimmed; + EXPECT_EQ(NO_ERROR, CoreUtils::sourceMetadataFromHalV7(halSourceMetadataV7FromTrimmed, + false /*ignoreNonVendorTags*/, + &sourceMetadataBackFromV7Trimmed)); + EXPECT_EQ(sourceMetadataBackTrimmed, sourceMetadataBackFromV7Trimmed); +} + +INSTANTIATE_TEST_SUITE_P(ValidPlaybackTrackMetadatas, SourceMetadataConvertTest, + ::testing::Values(SourceTracks{generateMinimalPlaybackTrackMetadata()}, + SourceTracks{generateValidPlaybackTrackMetadata()}, + SourceTracks{generateMinimalPlaybackTrackMetadata(), + generateValidPlaybackTrackMetadata()})); diff --git a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp index 5076dcfdb0..bb7c6d3d3e 100644 --- a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp +++ b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp @@ -336,24 +336,24 @@ TEST_P(OutputStreamTest, updateSourceMetadata) { ASSERT_RESULT(okOrNotSupported, stream->updateSourceMetadata( {{{toString(xsd::AudioUsage::AUDIO_USAGE_MEDIA), toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_MUSIC), - {}, + 0.1, // gain toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO), - 0.1}, + {}}, // tags {toString(xsd::AudioUsage::AUDIO_USAGE_VOICE_COMMUNICATION), toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_SPEECH), - {}, // tags + 1.0, toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_MONO), - 1.0}, + {}}, {toString(xsd::AudioUsage::AUDIO_USAGE_ALARM), toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_SONIFICATION), - {}, // tags + 0.0, toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO), - 0.0}, + {}}, {toString(xsd::AudioUsage::AUDIO_USAGE_ASSISTANT), toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_UNKNOWN), - {}, + 0.3, toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_MONO), - 0.3}}} + {}}}} )); // clang-format on // Set no metadata as if all stream track had stopped diff --git a/audio/effect/all-versions/default/Android.bp b/audio/effect/all-versions/default/Android.bp index a0cd6120e2..99b1120218 100644 --- a/audio/effect/all-versions/default/Android.bp +++ b/audio/effect/all-versions/default/Android.bp @@ -8,7 +8,6 @@ cc_defaults { "AudioBufferManager.cpp", "AutomaticGainControlEffect.cpp", "BassBoostEffect.cpp", - "Conversions.cpp", "DownmixEffect.cpp", "Effect.cpp", "EffectsFactory.cpp", @@ -51,6 +50,7 @@ cc_library_shared { "android.hardware.audio.common@2.0", "android.hardware.audio.common@2.0-util", "android.hardware.audio.effect@2.0", + "android.hardware.audio.effect@2.0-util", ], cflags: [ "-DMAJOR_VERSION=2", @@ -66,6 +66,7 @@ cc_library_shared { "android.hardware.audio.common@4.0", "android.hardware.audio.common@4.0-util", "android.hardware.audio.effect@4.0", + "android.hardware.audio.effect@4.0-util", ], cflags: [ "-DMAJOR_VERSION=4", @@ -81,6 +82,7 @@ cc_library_shared { "android.hardware.audio.common@5.0", "android.hardware.audio.common@5.0-util", "android.hardware.audio.effect@5.0", + "android.hardware.audio.effect@5.0-util", ], cflags: [ "-DMAJOR_VERSION=5", @@ -96,6 +98,7 @@ cc_library_shared { "android.hardware.audio.common@6.0", "android.hardware.audio.common@6.0-util", "android.hardware.audio.effect@6.0", + "android.hardware.audio.effect@6.0-util", ], cflags: [ "-DMAJOR_VERSION=6", @@ -111,6 +114,7 @@ cc_library_shared { "android.hardware.audio.common@7.0", "android.hardware.audio.common@7.0-util", "android.hardware.audio.effect@7.0", + "android.hardware.audio.effect@7.0-util", ], cflags: [ "-DMAJOR_VERSION=7", diff --git a/audio/effect/all-versions/default/Conversions.cpp b/audio/effect/all-versions/default/Conversions.cpp deleted file mode 100644 index 0cc8767e8d..0000000000 --- a/audio/effect/all-versions/default/Conversions.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "Conversions.h" -#include "UuidUtils.h" - -#include -#include - -#include - -using ::android::hardware::audio::common::utils::EnumBitfield; - -namespace android { -namespace hardware { -namespace audio { -namespace effect { -namespace CPP_VERSION { -namespace implementation { - -using ::android::hardware::audio::common::CPP_VERSION::implementation::UuidUtils; - -void effectDescriptorFromHal(const effect_descriptor_t& halDescriptor, - EffectDescriptor* descriptor) { - UuidUtils::uuidFromHal(halDescriptor.type, &descriptor->type); - UuidUtils::uuidFromHal(halDescriptor.uuid, &descriptor->uuid); - descriptor->flags = EnumBitfield(halDescriptor.flags); - descriptor->cpuLoad = halDescriptor.cpuLoad; - descriptor->memoryUsage = halDescriptor.memoryUsage; - memcpy(descriptor->name.data(), halDescriptor.name, descriptor->name.size()); - memcpy(descriptor->implementor.data(), halDescriptor.implementor, - descriptor->implementor.size()); -} - -std::string uuidToString(const effect_uuid_t& halUuid) { - char str[64]; - snprintf(str, sizeof(str), "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x", halUuid.timeLow, - halUuid.timeMid, halUuid.timeHiAndVersion, halUuid.clockSeq, halUuid.node[0], - halUuid.node[1], halUuid.node[2], halUuid.node[3], halUuid.node[4], halUuid.node[5]); - return str; -} - -} // namespace implementation -} // namespace CPP_VERSION -} // namespace effect -} // namespace audio -} // namespace hardware -} // namespace android diff --git a/audio/effect/all-versions/default/Conversions.h b/audio/effect/all-versions/default/Conversions.h deleted file mode 100644 index 75aab24efe..0000000000 --- a/audio/effect/all-versions/default/Conversions.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_HARDWARE_AUDIO_EFFECT_CONVERSIONS_H_ -#define ANDROID_HARDWARE_AUDIO_EFFECT_CONVERSIONS_H_ - -#include PATH(android/hardware/audio/effect/FILE_VERSION/types.h) - -#include - -#include - -namespace android { -namespace hardware { -namespace audio { -namespace effect { -namespace CPP_VERSION { -namespace implementation { - -using ::android::hardware::audio::effect::CPP_VERSION::EffectDescriptor; - -void effectDescriptorFromHal(const effect_descriptor_t& halDescriptor, - EffectDescriptor* descriptor); -std::string uuidToString(const effect_uuid_t& halUuid); - -} // namespace implementation -} // namespace CPP_VERSION -} // namespace effect -} // namespace audio -} // namespace hardware -} // namespace android - -#endif // ANDROID_HARDWARE_AUDIO_EFFECT_CONVERSIONS_H_ diff --git a/audio/effect/all-versions/default/Effect.cpp b/audio/effect/all-versions/default/Effect.cpp index 58f1779ffd..ccfc6b22c9 100644 --- a/audio/effect/all-versions/default/Effect.cpp +++ b/audio/effect/all-versions/default/Effect.cpp @@ -19,7 +19,6 @@ #define LOG_TAG "EffectHAL" #define ATRACE_TAG ATRACE_TAG_AUDIO -#include "Conversions.h" #include "Effect.h" #include "common/all-versions/default/EffectMap.h" @@ -30,6 +29,7 @@ #include #include #include +#include #include #include "VersionUtils.h" @@ -202,34 +202,6 @@ void Effect::effectAuxChannelsConfigToHal(const EffectAuxChannelsConfig& config, halConfig->aux_channels = static_cast(config.auxChannels); } -void Effect::effectBufferConfigFromHal(const buffer_config_t& halConfig, - EffectBufferConfig* config) { - config->buffer.id = 0; - config->buffer.frameCount = 0; - config->samplingRateHz = halConfig.samplingRate; - config->channels = AudioChannelBitfield(halConfig.channels); - config->format = AudioFormat(halConfig.format); - config->accessMode = EffectBufferAccess(halConfig.accessMode); - config->mask = static_castmask)>(halConfig.mask); -} - -// static -void Effect::effectBufferConfigToHal(const EffectBufferConfig& config, buffer_config_t* halConfig) { - // Note: setting the buffers directly is considered obsolete. They need to be set - // using 'setProcessBuffers'. - halConfig->buffer.frameCount = 0; - halConfig->buffer.raw = NULL; - halConfig->samplingRate = config.samplingRateHz; - halConfig->channels = static_cast(config.channels); - // Note: The framework code does not use BP. - halConfig->bufferProvider.cookie = NULL; - halConfig->bufferProvider.getBuffer = NULL; - halConfig->bufferProvider.releaseBuffer = NULL; - halConfig->format = static_cast(config.format); - halConfig->accessMode = static_cast(config.accessMode); - halConfig->mask = static_cast(config.mask); -} - #else // MAJOR_VERSION <= 6 void Effect::effectAuxChannelsConfigFromHal(const channel_config_t& halConfig, @@ -247,68 +219,8 @@ void Effect::effectAuxChannelsConfigToHal(const EffectAuxChannelsConfig& config, (void)HidlUtils::audioChannelMaskToHal(config.auxChannels, &halConfig->aux_channels); } -void Effect::effectBufferConfigFromHal(const buffer_config_t& halConfig, - EffectBufferConfig* config) { - config->buffer.unspecified(); - audio_config_base_t halConfigBase = {halConfig.samplingRate, - static_cast(halConfig.channels), - static_cast(halConfig.format)}; - (void)HidlUtils::audioConfigBaseOptionalFromHal( - halConfigBase, mIsInput, halConfig.mask & EFFECT_CONFIG_FORMAT, - halConfig.mask & EFFECT_CONFIG_SMP_RATE, halConfig.mask & EFFECT_CONFIG_CHANNELS, - &config->base); - if (halConfig.mask & EFFECT_CONFIG_ACC_MODE) { - config->accessMode.value(EffectBufferAccess(halConfig.accessMode)); - } -} - -// static -void Effect::effectBufferConfigToHal(const EffectBufferConfig& config, buffer_config_t* halConfig) { - // Note: setting the buffers directly is considered obsolete. They need to be set - // using 'setProcessBuffers'. - halConfig->buffer.frameCount = 0; - halConfig->buffer.raw = nullptr; - audio_config_base_t halConfigBase = AUDIO_CONFIG_BASE_INITIALIZER; - bool formatSpecified = false, sRateSpecified = false, channelMaskSpecified = false; - (void)HidlUtils::audioConfigBaseOptionalToHal(config.base, &halConfigBase, &formatSpecified, - &sRateSpecified, &channelMaskSpecified); - halConfig->mask = 0; - if (sRateSpecified) { - halConfig->mask |= EFFECT_CONFIG_SMP_RATE; - halConfig->samplingRate = halConfigBase.sample_rate; - } - if (channelMaskSpecified) { - halConfig->mask |= EFFECT_CONFIG_CHANNELS; - halConfig->channels = halConfigBase.channel_mask; - } - if (formatSpecified) { - halConfig->mask |= EFFECT_CONFIG_FORMAT; - halConfig->format = halConfigBase.format; - } - // Note: The framework code does not use BP. - halConfig->bufferProvider.cookie = nullptr; - halConfig->bufferProvider.getBuffer = nullptr; - halConfig->bufferProvider.releaseBuffer = nullptr; - if (config.accessMode.getDiscriminator() == - EffectBufferConfig::OptionalAccessMode::hidl_discriminator::value) { - halConfig->mask |= EFFECT_CONFIG_ACC_MODE; - halConfig->accessMode = static_cast(config.accessMode.value()); - } -} - #endif // MAJOR_VERSION <= 6 -void Effect::effectConfigFromHal(const effect_config_t& halConfig, EffectConfig* config) { - effectBufferConfigFromHal(halConfig.inputCfg, &config->inputCfg); - effectBufferConfigFromHal(halConfig.outputCfg, &config->outputCfg); -} - -// static -void Effect::effectConfigToHal(const EffectConfig& config, effect_config_t* halConfig) { - effectBufferConfigToHal(config.inputCfg, &halConfig->inputCfg); - effectBufferConfigToHal(config.outputCfg, &halConfig->outputCfg); -} - // static void Effect::effectOffloadParamToHal(const EffectOffloadParameter& offload, effect_offload_param_t* halOffload) { @@ -373,7 +285,7 @@ void Effect::getConfigImpl(int commandCode, const char* commandName, GetConfigCa (*mHandle)->command(mHandle, commandCode, 0, NULL, &halResultSize, &halConfig); EffectConfig config; if (status == OK) { - effectConfigFromHal(halConfig, &config); + status = EffectUtils::effectConfigFromHal(halConfig, mIsInput, &config); } cb(analyzeCommandStatus(commandName, sContextCallToCommand, status), config); } @@ -538,7 +450,7 @@ Result Effect::setConfigImpl(int commandCode, const char* commandName, const Eff const sp& inputBufferProvider, const sp& outputBufferProvider) { effect_config_t halConfig; - effectConfigToHal(config, &halConfig); + EffectUtils::effectConfigToHal(config, &halConfig); if (inputBufferProvider != 0) { LOG_FATAL("Using input buffer provider is not supported"); } @@ -733,7 +645,7 @@ Return Effect::getDescriptor(getDescriptor_cb _hidl_cb) { status_t status = (*mHandle)->get_descriptor(mHandle, &halDescriptor); EffectDescriptor descriptor; if (status == OK) { - effectDescriptorFromHal(halDescriptor, &descriptor); + status = EffectUtils::effectDescriptorFromHal(halDescriptor, &descriptor); } _hidl_cb(analyzeStatus("get_descriptor", "", sContextCallFunction, status), descriptor); return Void(); diff --git a/audio/effect/all-versions/default/Effect.h b/audio/effect/all-versions/default/Effect.h index 9aa47ea7d9..d5218f7240 100644 --- a/audio/effect/all-versions/default/Effect.h +++ b/audio/effect/all-versions/default/Effect.h @@ -203,11 +203,6 @@ struct Effect : public IEffect { EffectAuxChannelsConfig* config); static void effectAuxChannelsConfigToHal(const EffectAuxChannelsConfig& config, channel_config_t* halConfig); - void effectBufferConfigFromHal(const buffer_config_t& halConfig, EffectBufferConfig* config); - static void effectBufferConfigToHal(const EffectBufferConfig& config, - buffer_config_t* halConfig); - void effectConfigFromHal(const effect_config_t& halConfig, EffectConfig* config); - static void effectConfigToHal(const EffectConfig& config, effect_config_t* halConfig); static void effectOffloadParamToHal(const EffectOffloadParameter& offload, effect_offload_param_t* halOffload); static std::vector parameterToHal(uint32_t paramSize, const void* paramData, diff --git a/audio/effect/all-versions/default/EffectsFactory.cpp b/audio/effect/all-versions/default/EffectsFactory.cpp index 1ea990b3b6..eb1cb4971c 100644 --- a/audio/effect/all-versions/default/EffectsFactory.cpp +++ b/audio/effect/all-versions/default/EffectsFactory.cpp @@ -19,7 +19,6 @@ #include "AcousticEchoCancelerEffect.h" #include "AutomaticGainControlEffect.h" #include "BassBoostEffect.h" -#include "Conversions.h" #include "DownmixEffect.h" #include "Effect.h" #include "EnvironmentalReverbEffect.h" @@ -27,11 +26,11 @@ #include "LoudnessEnhancerEffect.h" #include "NoiseSuppressionEffect.h" #include "PresetReverbEffect.h" -#include "UuidUtils.h" #include "VirtualizerEffect.h" #include "VisualizerEffect.h" #include "common/all-versions/default/EffectMap.h" +#include #include #include #include @@ -45,6 +44,7 @@ #include #include #include +#include namespace android { namespace hardware { @@ -107,7 +107,7 @@ restart: effect_descriptor_t halDescriptor; status = EffectQueryEffect(i, &halDescriptor); if (status == OK) { - effectDescriptorFromHal(halDescriptor, &result[i]); + EffectUtils::effectDescriptorFromHal(halDescriptor, &result[i]); } else { ALOGE("Error querying effect at position %d / %d: %s", i, numEffects, strerror(-status)); @@ -141,11 +141,11 @@ Return EffectsFactory::getDescriptor(const Uuid& uuid, getDescriptor_cb _h effect_descriptor_t halDescriptor; status_t status = EffectGetDescriptor(&halUuid, &halDescriptor); EffectDescriptor descriptor; - effectDescriptorFromHal(halDescriptor, &descriptor); + EffectUtils::effectDescriptorFromHal(halDescriptor, &descriptor); Result retval(Result::OK); if (status != OK) { - ALOGE("Error querying effect descriptor for %s: %s", uuidToString(halUuid).c_str(), - strerror(-status)); + ALOGE("Error querying effect descriptor for %s: %s", + UuidUtils::uuidToString(halUuid).c_str(), strerror(-status)); if (status == -ENOENT) { retval = Result::INVALID_ARGUMENTS; } else { @@ -191,13 +191,14 @@ Return EffectsFactory::createEffectImpl(const Uuid& uuid, int32_t session, effect = dispatchEffectInstanceCreation(halDescriptor, handle); effectId = EffectMap::getInstance().add(handle); } else { - ALOGE("Error querying effect descriptor for %s: %s", uuidToString(halUuid).c_str(), - strerror(-status)); + ALOGE("Error querying effect descriptor for %s: %s", + UuidUtils::uuidToString(halUuid).c_str(), strerror(-status)); EffectRelease(handle); } } if (status != OK) { - ALOGE("Error creating effect %s: %s", uuidToString(halUuid).c_str(), strerror(-status)); + ALOGE("Error creating effect %s: %s", UuidUtils::uuidToString(halUuid).c_str(), + strerror(-status)); if (status == -ENOENT) { retval = Result::INVALID_ARGUMENTS; } else { diff --git a/audio/effect/all-versions/default/TEST_MAPPING b/audio/effect/all-versions/default/TEST_MAPPING new file mode 100644 index 0000000000..b66e4e4758 --- /dev/null +++ b/audio/effect/all-versions/default/TEST_MAPPING @@ -0,0 +1,7 @@ +{ + "presubmit": [ + { + "name": "android.hardware.audio.effect@7.0-util_tests" + } + ] +} diff --git a/audio/effect/all-versions/default/util/Android.bp b/audio/effect/all-versions/default/util/Android.bp new file mode 100644 index 0000000000..5ba19d3a2d --- /dev/null +++ b/audio/effect/all-versions/default/util/Android.bp @@ -0,0 +1,136 @@ +cc_defaults { + name: "android.hardware.audio.effect-util_default", + defaults: ["hidl_defaults"], + + vendor_available: true, + + export_include_dirs: ["include"], + + srcs: [ + "EffectUtils.cpp", + ], + + shared_libs: [ + "liblog", + "libutils", + "libhidlbase", + "android.hardware.audio.common-util", + ], + export_shared_lib_headers: [ + "android.hardware.audio.common-util", + ], + + header_libs: [ + "libaudio_system_headers", + "libhardware_headers", + ], +} + +cc_library_shared { + name: "android.hardware.audio.effect@2.0-util", + defaults: ["android.hardware.audio.effect-util_default"], + shared_libs: [ + "android.hardware.audio.common@2.0", + "android.hardware.audio.common@2.0-util", + "android.hardware.audio.effect@2.0", + ], + cflags: [ + "-DMAJOR_VERSION=2", + "-DMINOR_VERSION=0", + "-include common/all-versions/VersionMacro.h", + ], +} + +cc_library_shared { + name: "android.hardware.audio.effect@4.0-util", + defaults: ["android.hardware.audio.effect-util_default"], + shared_libs: [ + "android.hardware.audio.common@4.0", + "android.hardware.audio.common@4.0-util", + "android.hardware.audio.effect@4.0", + ], + cflags: [ + "-DMAJOR_VERSION=4", + "-DMINOR_VERSION=0", + "-include common/all-versions/VersionMacro.h", + ], +} + +cc_library_shared { + name: "android.hardware.audio.effect@5.0-util", + defaults: ["android.hardware.audio.effect-util_default"], + shared_libs: [ + "android.hardware.audio.common@5.0", + "android.hardware.audio.common@5.0-util", + "android.hardware.audio.effect@5.0", + ], + cflags: [ + "-DMAJOR_VERSION=5", + "-DMINOR_VERSION=0", + "-include common/all-versions/VersionMacro.h", + ], +} + +cc_library_shared { + name: "android.hardware.audio.effect@6.0-util", + defaults: ["android.hardware.audio.effect-util_default"], + shared_libs: [ + "android.hardware.audio.common@6.0", + "android.hardware.audio.common@6.0-util", + "android.hardware.audio.effect@6.0", + ], + cflags: [ + "-DMAJOR_VERSION=6", + "-DMINOR_VERSION=0", + "-include common/all-versions/VersionMacro.h", + ], +} + +cc_library { + name: "android.hardware.audio.effect@7.0-util", + defaults: ["android.hardware.audio.effect-util_default"], + shared_libs: [ + "android.hardware.audio.common@7.0", + "android.hardware.audio.common@7.0-util", + "android.hardware.audio.effect@7.0", + ], + cflags: [ + "-DMAJOR_VERSION=7", + "-DMINOR_VERSION=0", + "-include common/all-versions/VersionMacro.h", + ], +} + +// Note: this isn't a VTS test, but rather a unit test +// to verify correctness of conversion utilities. +cc_test { + name: "android.hardware.audio.effect@7.0-util_tests", + defaults: ["android.hardware.audio.effect-util_default"], + + srcs: ["tests/effectutils_tests.cpp"], + + // Use static linking to allow running in presubmit on + // targets that don't have HAL V7. + static_libs: [ + "android.hardware.audio.common@7.0", + "android.hardware.audio.common@7.0-enums", + "android.hardware.audio.common@7.0-util", + "android.hardware.audio.effect@7.0", + "android.hardware.audio.effect@7.0-util", + ], + + shared_libs: [ + "libbase", + "libxml2", + ], + + cflags: [ + "-Werror", + "-Wall", + "-DMAJOR_VERSION=7", + "-DMINOR_VERSION=0", + "-include common/all-versions/VersionMacro.h", + ], + + test_suites: ["device-tests"], +} diff --git a/audio/effect/all-versions/default/util/EffectUtils.cpp b/audio/effect/all-versions/default/util/EffectUtils.cpp new file mode 100644 index 0000000000..1c0419aba3 --- /dev/null +++ b/audio/effect/all-versions/default/util/EffectUtils.cpp @@ -0,0 +1,183 @@ +/* + * 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 + +#include +#include +#include + +#include "util/EffectUtils.h" + +using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils; +using ::android::hardware::audio::common::CPP_VERSION::implementation::UuidUtils; +using ::android::hardware::audio::common::utils::EnumBitfield; + +namespace android { +namespace hardware { +namespace audio { +namespace effect { +namespace CPP_VERSION { +namespace implementation { + +using namespace ::android::hardware::audio::common::CPP_VERSION; + +#define CONVERT_CHECKED(expr, result) \ + if (status_t status = (expr); status != NO_ERROR) { \ + result = status; \ + } + +#if MAJOR_VERSION <= 6 + +status_t EffectUtils::effectBufferConfigFromHal(const buffer_config_t& halConfig, bool /*isInput*/, + EffectBufferConfig* config) { + config->buffer.id = 0; + config->buffer.frameCount = 0; + config->samplingRateHz = halConfig.samplingRate; + config->channels = EnumBitfield(halConfig.channels); + config->format = AudioFormat(halConfig.format); + config->accessMode = EffectBufferAccess(halConfig.accessMode); + config->mask = EnumBitfield(halConfig.mask); + return NO_ERROR; +} + +status_t EffectUtils::effectBufferConfigToHal(const EffectBufferConfig& config, + buffer_config_t* halConfig) { + // Note: setting the buffers directly is considered obsolete. They need to be set + // using 'setProcessBuffers'. + halConfig->buffer.frameCount = 0; + halConfig->buffer.raw = nullptr; + halConfig->samplingRate = config.samplingRateHz; + halConfig->channels = static_cast(config.channels); + // Note: The framework code does not use BP. + halConfig->bufferProvider.cookie = nullptr; + halConfig->bufferProvider.getBuffer = nullptr; + halConfig->bufferProvider.releaseBuffer = nullptr; + halConfig->format = static_cast(config.format); + halConfig->accessMode = static_cast(config.accessMode); + halConfig->mask = static_cast(config.mask); + return NO_ERROR; +} + +#else + +status_t EffectUtils::effectBufferConfigFromHal(const buffer_config_t& halConfig, bool isInput, + EffectBufferConfig* config) { + status_t result = NO_ERROR; + config->buffer.unspecified(); + audio_config_base_t halConfigBase = {halConfig.samplingRate, + static_cast(halConfig.channels), + static_cast(halConfig.format)}; + CONVERT_CHECKED(HidlUtils::audioConfigBaseOptionalFromHal( + halConfigBase, isInput, halConfig.mask & EFFECT_CONFIG_FORMAT, + halConfig.mask & EFFECT_CONFIG_SMP_RATE, + halConfig.mask & EFFECT_CONFIG_CHANNELS, &config->base), + result); + if (halConfig.mask & EFFECT_CONFIG_ACC_MODE) { + config->accessMode.value(EffectBufferAccess(halConfig.accessMode)); + } + return result; +} + +status_t EffectUtils::effectBufferConfigToHal(const EffectBufferConfig& config, + buffer_config_t* halConfig) { + status_t result = NO_ERROR; + // Note: setting the buffers directly is considered obsolete. They need to be set + // using 'setProcessBuffers'. + halConfig->buffer.frameCount = 0; + halConfig->buffer.raw = nullptr; + audio_config_base_t halConfigBase = AUDIO_CONFIG_BASE_INITIALIZER; + bool formatSpecified = false, sRateSpecified = false, channelMaskSpecified = false; + CONVERT_CHECKED( + HidlUtils::audioConfigBaseOptionalToHal(config.base, &halConfigBase, &formatSpecified, + &sRateSpecified, &channelMaskSpecified), + result); + halConfig->mask = 0; + if (sRateSpecified) { + halConfig->mask |= EFFECT_CONFIG_SMP_RATE; + halConfig->samplingRate = halConfigBase.sample_rate; + } + if (channelMaskSpecified) { + halConfig->mask |= EFFECT_CONFIG_CHANNELS; + halConfig->channels = halConfigBase.channel_mask; + } + if (formatSpecified) { + halConfig->mask |= EFFECT_CONFIG_FORMAT; + halConfig->format = halConfigBase.format; + } + // Note: The framework code does not use BP. + halConfig->bufferProvider.cookie = nullptr; + halConfig->bufferProvider.getBuffer = nullptr; + halConfig->bufferProvider.releaseBuffer = nullptr; + if (config.accessMode.getDiscriminator() == + EffectBufferConfig::OptionalAccessMode::hidl_discriminator::value) { + halConfig->mask |= EFFECT_CONFIG_ACC_MODE; + halConfig->accessMode = static_cast(config.accessMode.value()); + } + return result; +} + +#endif // MAJOR_VERSION >= 6 + +status_t EffectUtils::effectConfigFromHal(const effect_config_t& halConfig, bool isInput, + EffectConfig* config) { + status_t result = NO_ERROR; + CONVERT_CHECKED(effectBufferConfigFromHal(halConfig.inputCfg, isInput, &config->inputCfg), + result); + CONVERT_CHECKED(effectBufferConfigFromHal(halConfig.outputCfg, isInput, &config->outputCfg), + result); + return result; +} + +status_t EffectUtils::effectConfigToHal(const EffectConfig& config, effect_config_t* halConfig) { + status_t result = NO_ERROR; + CONVERT_CHECKED(effectBufferConfigToHal(config.inputCfg, &halConfig->inputCfg), result); + CONVERT_CHECKED(effectBufferConfigToHal(config.outputCfg, &halConfig->outputCfg), result); + return result; +} + +status_t EffectUtils::effectDescriptorFromHal(const effect_descriptor_t& halDescriptor, + EffectDescriptor* descriptor) { + UuidUtils::uuidFromHal(halDescriptor.type, &descriptor->type); + UuidUtils::uuidFromHal(halDescriptor.uuid, &descriptor->uuid); + descriptor->flags = EnumBitfield(halDescriptor.flags); + descriptor->cpuLoad = halDescriptor.cpuLoad; + descriptor->memoryUsage = halDescriptor.memoryUsage; + memcpy(descriptor->name.data(), halDescriptor.name, descriptor->name.size()); + memcpy(descriptor->implementor.data(), halDescriptor.implementor, + descriptor->implementor.size()); + return NO_ERROR; +} + +status_t EffectUtils::effectDescriptorToHal(const EffectDescriptor& descriptor, + effect_descriptor_t* halDescriptor) { + UuidUtils::uuidToHal(descriptor.type, &halDescriptor->type); + UuidUtils::uuidToHal(descriptor.uuid, &halDescriptor->uuid); + halDescriptor->flags = static_cast(descriptor.flags); + halDescriptor->cpuLoad = descriptor.cpuLoad; + halDescriptor->memoryUsage = descriptor.memoryUsage; + memcpy(halDescriptor->name, descriptor.name.data(), descriptor.name.size()); + memcpy(halDescriptor->implementor, descriptor.implementor.data(), + descriptor.implementor.size()); + return NO_ERROR; +} + +} // namespace implementation +} // namespace CPP_VERSION +} // namespace effect +} // namespace audio +} // namespace hardware +} // namespace android diff --git a/audio/effect/all-versions/default/util/include/util/EffectUtils.h b/audio/effect/all-versions/default/util/include/util/EffectUtils.h new file mode 100644 index 0000000000..23963b4d41 --- /dev/null +++ b/audio/effect/all-versions/default/util/include/util/EffectUtils.h @@ -0,0 +1,53 @@ +/* + * 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 + +// clang-format off +#include PATH(android/hardware/audio/effect/FILE_VERSION/types.h) +// clang-format on + +#include + +namespace android { +namespace hardware { +namespace audio { +namespace effect { +namespace CPP_VERSION { +namespace implementation { + +using namespace ::android::hardware::audio::effect::CPP_VERSION; + +struct EffectUtils { + static status_t effectBufferConfigFromHal(const buffer_config_t& halConfig, bool isInput, + EffectBufferConfig* config); + static status_t effectBufferConfigToHal(const EffectBufferConfig& config, + buffer_config_t* halConfig); + static status_t effectConfigFromHal(const effect_config_t& halConfig, bool isInput, + EffectConfig* config); + static status_t effectConfigToHal(const EffectConfig& config, effect_config_t* halConfig); + static status_t effectDescriptorFromHal(const effect_descriptor_t& halDescriptor, + EffectDescriptor* descriptor); + static status_t effectDescriptorToHal(const EffectDescriptor& descriptor, + effect_descriptor_t* halDescriptor); +}; + +} // namespace implementation +} // namespace CPP_VERSION +} // namespace effect +} // namespace audio +} // namespace hardware +} // namespace android diff --git a/audio/effect/all-versions/default/util/tests/effectutils_tests.cpp b/audio/effect/all-versions/default/util/tests/effectutils_tests.cpp new file mode 100644 index 0000000000..7eb8cd2958 --- /dev/null +++ b/audio/effect/all-versions/default/util/tests/effectutils_tests.cpp @@ -0,0 +1,144 @@ +/* + * 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 + +#include + +#define LOG_TAG "EffectUtils_Test" +#include + +#include +#include +#include +#include + +using namespace android; +using namespace ::android::hardware::audio::common::CPP_VERSION; +using namespace ::android::hardware::audio::effect::CPP_VERSION; +using ::android::hardware::audio::effect::CPP_VERSION::implementation::EffectUtils; +namespace xsd { +using namespace ::android::audio::policy::configuration::V7_0; +} + +static constexpr audio_channel_mask_t kInvalidHalChannelMask = AUDIO_CHANNEL_INVALID; +static constexpr audio_format_t kInvalidHalFormat = AUDIO_FORMAT_INVALID; + +// Not generated automatically because AudioBuffer contains +// instances of hidl_memory which can't be compared properly +// in general case due to presence of handles. +// +// However, in this particular case, handles must not present +// thus comparison is possible. +// +// operator== must be defined in the same namespace as the structures. +namespace android { +namespace hardware { +namespace audio { +namespace effect { +namespace CPP_VERSION { +inline bool operator==(const AudioBuffer& lhs, const AudioBuffer& rhs) { + return lhs.id == rhs.id && lhs.frameCount == rhs.frameCount && lhs.data.handle() == nullptr && + rhs.data.handle() == nullptr; +} + +inline bool operator==(const EffectBufferConfig& lhs, const EffectBufferConfig& rhs) { + return lhs.buffer.getDiscriminator() == rhs.buffer.getDiscriminator() && + (lhs.buffer.getDiscriminator() == + EffectBufferConfig::OptionalBuffer::hidl_discriminator::unspecified || + lhs.buffer.buf() == rhs.buffer.buf()) && + lhs.base == rhs.base && lhs.accessMode == rhs.accessMode; +} + +inline bool operator==(const EffectConfig& lhs, const EffectConfig& rhs) { + return lhs.inputCfg == rhs.inputCfg && lhs.outputCfg == rhs.outputCfg; +} +} // namespace CPP_VERSION +} // namespace effect +} // namespace audio +} // namespace hardware +} // namespace android + +TEST(EffectUtils, ConvertInvalidBufferConfig) { + buffer_config_t halInvalid; + EffectBufferConfig invalidChannelMask; + invalidChannelMask.base.channelMask.value("random string"); + EXPECT_EQ(BAD_VALUE, EffectUtils::effectBufferConfigToHal(invalidChannelMask, &halInvalid)); + EffectBufferConfig invalidFormat; + invalidFormat.base.format.value("random string"); + EXPECT_EQ(BAD_VALUE, EffectUtils::effectBufferConfigToHal(invalidFormat, &halInvalid)); + + buffer_config_t halInvalidChannelMask; + EffectBufferConfig invalid; + halInvalidChannelMask.channels = kInvalidHalChannelMask; + halInvalidChannelMask.mask = EFFECT_CONFIG_CHANNELS; + EXPECT_EQ(BAD_VALUE, EffectUtils::effectBufferConfigFromHal(halInvalidChannelMask, + false /*isInput*/, &invalid)); + EXPECT_EQ(BAD_VALUE, EffectUtils::effectBufferConfigFromHal(halInvalidChannelMask, + true /*isInput*/, &invalid)); + buffer_config_t halInvalidFormat; + halInvalidFormat.format = (uint8_t)kInvalidHalFormat; + halInvalidFormat.mask = EFFECT_CONFIG_FORMAT; + EXPECT_EQ(BAD_VALUE, EffectUtils::effectBufferConfigFromHal(halInvalidFormat, false /*isInput*/, + &invalid)); + EXPECT_EQ(BAD_VALUE, + EffectUtils::effectBufferConfigFromHal(halInvalidFormat, true /*isInput*/, &invalid)); +} + +TEST(EffectUtils, ConvertBufferConfig) { + EffectBufferConfig empty; + buffer_config_t halEmpty; + EXPECT_EQ(NO_ERROR, EffectUtils::effectBufferConfigToHal(empty, &halEmpty)); + EffectBufferConfig emptyBackOut; + EXPECT_EQ(NO_ERROR, + EffectUtils::effectBufferConfigFromHal(halEmpty, false /*isInput*/, &emptyBackOut)); + EXPECT_EQ(empty, emptyBackOut); + EffectBufferConfig emptyBackIn; + EXPECT_EQ(NO_ERROR, + EffectUtils::effectBufferConfigFromHal(halEmpty, true /*isInput*/, &emptyBackIn)); + EXPECT_EQ(empty, emptyBackIn); + + EffectBufferConfig chanMask; + chanMask.base.channelMask.value(toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO)); + buffer_config_t halChanMask; + EXPECT_EQ(NO_ERROR, EffectUtils::effectBufferConfigToHal(chanMask, &halChanMask)); + EffectBufferConfig chanMaskBack; + EXPECT_EQ(NO_ERROR, EffectUtils::effectBufferConfigFromHal(halChanMask, false /*isInput*/, + &chanMaskBack)); + EXPECT_EQ(chanMask, chanMaskBack); + + EffectBufferConfig format; + format.base.format.value(toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT)); + buffer_config_t halFormat; + EXPECT_EQ(NO_ERROR, EffectUtils::effectBufferConfigToHal(format, &halFormat)); + EffectBufferConfig formatBackOut; + EXPECT_EQ(NO_ERROR, + EffectUtils::effectBufferConfigFromHal(halFormat, false /*isInput*/, &formatBackOut)); + EXPECT_EQ(format, formatBackOut); + EffectBufferConfig formatBackIn; + EXPECT_EQ(NO_ERROR, + EffectUtils::effectBufferConfigFromHal(halFormat, true /*isInput*/, &formatBackIn)); + EXPECT_EQ(format, formatBackIn); +} + +TEST(EffectUtils, ConvertDescriptor) { + EffectDescriptor desc{}; + effect_descriptor_t halDesc; + EXPECT_EQ(NO_ERROR, EffectUtils::effectDescriptorToHal(desc, &halDesc)); + EffectDescriptor descBack; + EXPECT_EQ(NO_ERROR, EffectUtils::effectDescriptorFromHal(halDesc, &descBack)); + EXPECT_EQ(desc, descBack); +} -- GitLab From 3bf3e3323f15d22ce1c3f10bf08f9a0129f4e433 Mon Sep 17 00:00:00 2001 From: Shuo Qian Date: Tue, 2 Feb 2021 00:20:08 +0000 Subject: [PATCH 423/790] Add emergencyDial_1_6 in the HAL to modify the multisim logic for pin lock Test: vts Bug: 171235919 Change-Id: I6d495199af4d2abbf22cf6dded4ee4ecf1407f3a --- radio/1.6/IRadio.hal | 61 +++++++ .../1.6/vts/functional/radio_hidl_hal_api.cpp | 161 ++++++++++++++++++ .../vts/functional/radio_hidl_hal_test.cpp | 23 +++ .../functional/radio_hidl_hal_utils_v1_6.h | 3 +- radio/1.6/vts/functional/radio_response.cpp | 10 +- 5 files changed, 254 insertions(+), 4 deletions(-) diff --git a/radio/1.6/IRadio.hal b/radio/1.6/IRadio.hal index 1862800f5e..0a5dc83b79 100644 --- a/radio/1.6/IRadio.hal +++ b/radio/1.6/IRadio.hal @@ -18,9 +18,12 @@ package android.hardware.radio@1.6; import @1.0::CdmaSmsMessage; +import @1.0::Dial; import @1.0::GsmSmsMessage; import @1.1::CardPowerState; import @1.2::DataRequestReason; +import @1.4::EmergencyCallRouting; +import @1.4::EmergencyServiceCategory; import @1.4::RadioAccessFamily; import @1.5::IRadio; import @1.5::AccessNetwork; @@ -373,6 +376,64 @@ interface IRadio extends @1.5::IRadio { DataThrottlingAction dataThrottlingAction, int64_t completionDurationMillis); + /** + * Initiate emergency voice call, with zero or more emergency service category(s), zero or + * more emergency Uniform Resource Names (URN), and routing information for handling the call. + * Android uses this request to make its emergency call instead of using @1.0::IRadio.dial + * if the 'address' in the 'dialInfo' field is identified as an emergency number by Android. + * + * In multi-sim scenario, if the emergency number is from a specific subscription, this radio + * request can still be sent out on the other subscription as long as routing is set to + * @1.4::EmergencyNumberRouting#EMERGENCY. This radio request will not be sent on an inactive + * (PIN/PUK locked) subscription unless both subscriptions are PIN/PUK locked. In this case, + * the request will be sent on the primary subscription. + * + * Some countries or carriers require some emergency numbers that must be handled with normal + * call routing if possible or emergency routing. 1) if the 'routing' field is specified as + * @1.4::EmergencyNumberRouting#NORMAL, the implementation must try the full radio service to + * use normal call routing to handle the call; if service cannot support normal routing, the + * implementation must use emergency routing to handle the call. 2) if 'routing' is specified + * as @1.4::EmergencyNumberRouting#EMERGENCY, the implementation must use emergency routing to + * handle the call. 3) if 'routing' is specified as @1.4::EmergencyNumberRouting#UNKNOWN, + * Android does not know how to handle the call. + * + * If the dialed emergency number does not have a specified emergency service category, the + * 'categories' field is set to @1.4::EmergencyServiceCategory#UNSPECIFIED; if the dialed + * emergency number does not have specified emergency Uniform Resource Names, the 'urns' field + * is set to an empty list. If the underlying technology used to request emergency services + * does not support the emergency service category or emergency uniform resource names, the + * field 'categories' or 'urns' may be ignored. + * + * In the scenarios that the 'address' in the 'dialInfo' field has other functions besides the + * emergency number function, if the 'hasKnownUserIntentEmergency' field is true, the user's + * intent for this dial request is emergency call, and the modem must treat this as an actual + * emergency dial; if the 'hasKnownUserIntentEmergency' field is false, Android does not know + * user's intent for this call. + * + * If 'isTesting' is true, this request is for testing purpose, and must not be sent to a real + * emergency service; otherwise it's for a real emergency call request. + * + * Reference: 3gpp 22.101, Section 10 - Emergency Calls; + * 3gpp 23.167, Section 6 - Functional description; + * 3gpp 24.503, Section 5.1.6.8.1 - General; + * RFC 5031 + * + * @param serial Serial number of request. + * @param dialInfo the same @1.0::Dial information used by @1.0::IRadio.dial. + * @param categories bitfield<@1.4::EmergencyServiceCategory> the Emergency Service Category(s) + * of the call. + * @param urns the emergency Uniform Resource Names (URN) + * @param routing @1.4::EmergencyCallRouting the emergency call routing information. + * @param hasKnownUserIntentEmergency Flag indicating if user's intent for the emergency call + * is known. + * @param isTesting Flag indicating if this request is for testing purpose. + * + * Response function is IRadioResponse.emergencyDialResponse() + */ + oneway emergencyDial_1_6(int32_t serial, Dial dialInfo, + bitfield categories, vec urns, + EmergencyCallRouting routing, bool hasKnownUserIntentEmergency, bool isTesting); + /** * Get which bands the modem's background scan is acting on. * diff --git a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp index 8b872921ec..44900b8d49 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp +++ b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp @@ -411,6 +411,167 @@ TEST_P(RadioHidlTest_v1_6, setSimCardPower_1_6) { } } +/* + * Test IRadio.emergencyDial() for the response returned. + */ +TEST_P(RadioHidlTest_v1_6, emergencyDial_1_6) { + if (!deviceSupportsFeature(FEATURE_VOICE_CALL)) { + ALOGI("Skipping emergencyDial because voice call is not supported in device"); + return; + } else { + ALOGI("Running emergencyDial because voice call is supported in device"); + } + + serial = GetRandomSerialNumber(); + + ::android::hardware::radio::V1_0::Dial dialInfo; + dialInfo.address = hidl_string("911"); + int categories = static_cast( + ::android::hardware::radio::V1_4::EmergencyServiceCategory::UNSPECIFIED); + std::vector urns = {""}; + ::android::hardware::radio::V1_4::EmergencyCallRouting routing = + ::android::hardware::radio::V1_4::EmergencyCallRouting::UNKNOWN; + + Return res = + radio_v1_6->emergencyDial_1_6(serial, dialInfo, categories, urns, routing, true, true); + ASSERT_OK(res); + EXPECT_EQ(std::cv_status::no_timeout, wait()); + EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo_v1_0.type); + EXPECT_EQ(serial, radioRsp_v1_6->rspInfo_v1_0.serial); + + ALOGI("emergencyDial, rspInfo_v1_0.error = %s\n", + toString(radioRsp_v1_6->rspInfo_v1_0.error).c_str()); + + ::android::hardware::radio::V1_0::RadioError rspEmergencyDial = + radioRsp_v1_6->rspInfo_v1_0.error; + // In DSDS or TSTS, we only check the result if the current slot is IN_SERVICE + // or Emergency_Only. + if (isDsDsEnabled() || isTsTsEnabled()) { + serial = GetRandomSerialNumber(); + radio_v1_6->getVoiceRegistrationState(serial); + EXPECT_EQ(std::cv_status::no_timeout, wait()); + if (isVoiceEmergencyOnly(radioRsp_v1_6->voiceRegResp.regState) || + isVoiceInService(radioRsp_v1_6->voiceRegResp.regState)) { + EXPECT_EQ(::android::hardware::radio::V1_0::RadioError::NONE, rspEmergencyDial); + } + } else { + EXPECT_EQ(::android::hardware::radio::V1_0::RadioError::NONE, rspEmergencyDial); + } + + // Give some time for modem to establish the emergency call channel. + sleep(MODEM_EMERGENCY_CALL_ESTABLISH_TIME); + + // Disconnect all the potential established calls to prevent them affecting other tests. + clearPotentialEstablishedCalls(); +} + +/* + * Test IRadio.emergencyDial() with specified service and its response returned. + */ +TEST_P(RadioHidlTest_v1_6, emergencyDial_1_6_withServices) { + if (!deviceSupportsFeature(FEATURE_VOICE_CALL)) { + ALOGI("Skipping emergencyDial because voice call is not supported in device"); + return; + } else { + ALOGI("Running emergencyDial because voice call is supported in device"); + } + + serial = GetRandomSerialNumber(); + + ::android::hardware::radio::V1_0::Dial dialInfo; + dialInfo.address = hidl_string("911"); + int categories = + static_cast(::android::hardware::radio::V1_4::EmergencyServiceCategory::AMBULANCE); + std::vector urns = {"urn:service:sos.ambulance"}; + ::android::hardware::radio::V1_4::EmergencyCallRouting routing = + ::android::hardware::radio::V1_4::EmergencyCallRouting::UNKNOWN; + + Return res = + radio_v1_6->emergencyDial_1_6(serial, dialInfo, categories, urns, routing, true, true); + ASSERT_OK(res); + EXPECT_EQ(std::cv_status::no_timeout, wait()); + EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo_v1_0.type); + EXPECT_EQ(serial, radioRsp_v1_6->rspInfo_v1_0.serial); + + ALOGI("emergencyDial_withServices, rspInfo_v1_0.error = %s\n", + toString(radioRsp_v1_6->rspInfo_v1_0.error).c_str()); + ::android::hardware::radio::V1_0::RadioError rspEmergencyDial = + radioRsp_v1_6->rspInfo_v1_0.error; + + // In DSDS or TSTS, we only check the result if the current slot is IN_SERVICE + // or Emergency_Only. + if (isDsDsEnabled() || isTsTsEnabled()) { + serial = GetRandomSerialNumber(); + radio_v1_6->getVoiceRegistrationState(serial); + EXPECT_EQ(std::cv_status::no_timeout, wait()); + if (isVoiceEmergencyOnly(radioRsp_v1_6->voiceRegResp.regState) || + isVoiceInService(radioRsp_v1_6->voiceRegResp.regState)) { + EXPECT_EQ(::android::hardware::radio::V1_0::RadioError::NONE, rspEmergencyDial); + } + } else { + EXPECT_EQ(::android::hardware::radio::V1_0::RadioError::NONE, rspEmergencyDial); + } + // Give some time for modem to establish the emergency call channel. + sleep(MODEM_EMERGENCY_CALL_ESTABLISH_TIME); + + // Disconnect all the potential established calls to prevent them affecting other tests. + clearPotentialEstablishedCalls(); +} + +/* + * Test IRadio.emergencyDial() with known emergency call routing and its response returned. + */ +TEST_P(RadioHidlTest_v1_6, emergencyDial_1_6_withEmergencyRouting) { + if (!deviceSupportsFeature(FEATURE_VOICE_CALL)) { + ALOGI("Skipping emergencyDial because voice call is not supported in device"); + return; + } else { + ALOGI("Running emergencyDial because voice call is supported in device"); + } + + serial = GetRandomSerialNumber(); + + ::android::hardware::radio::V1_0::Dial dialInfo; + dialInfo.address = hidl_string("911"); + int categories = static_cast( + ::android::hardware::radio::V1_4::EmergencyServiceCategory::UNSPECIFIED); + std::vector urns = {""}; + ::android::hardware::radio::V1_4::EmergencyCallRouting routing = + ::android::hardware::radio::V1_4::EmergencyCallRouting::EMERGENCY; + + Return res = + radio_v1_6->emergencyDial_1_6(serial, dialInfo, categories, urns, routing, true, true); + ASSERT_OK(res); + EXPECT_EQ(std::cv_status::no_timeout, wait()); + EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo_v1_0.type); + EXPECT_EQ(serial, radioRsp_v1_6->rspInfo_v1_0.serial); + + ALOGI("emergencyDial_withEmergencyRouting, rspInfo_v1_0.error = %s\n", + toString(radioRsp_v1_6->rspInfo_v1_0.error).c_str()); + ::android::hardware::radio::V1_0::RadioError rspEmergencyDial = + radioRsp_v1_6->rspInfo_v1_0.error; + + // In DSDS or TSTS, we only check the result if the current slot is IN_SERVICE + // or Emergency_Only. + if (isDsDsEnabled() || isTsTsEnabled()) { + serial = GetRandomSerialNumber(); + radio_v1_6->getVoiceRegistrationState(serial); + EXPECT_EQ(std::cv_status::no_timeout, wait()); + if (isVoiceEmergencyOnly(radioRsp_v1_6->voiceRegResp.regState) || + isVoiceInService(radioRsp_v1_6->voiceRegResp.regState)) { + EXPECT_EQ(::android::hardware::radio::V1_0::RadioError::NONE, rspEmergencyDial); + } + } else { + EXPECT_EQ(::android::hardware::radio::V1_0::RadioError::NONE, rspEmergencyDial); + } + + // Give some time for modem to establish the emergency call channel. + sleep(MODEM_EMERGENCY_CALL_ESTABLISH_TIME); + + // Disconnect all the potential established calls to prevent them affecting other tests. + clearPotentialEstablishedCalls(); +} + /* * Test IRadio.getCurrentCalls_1_6() for the response returned. */ diff --git a/radio/1.6/vts/functional/radio_hidl_hal_test.cpp b/radio/1.6/vts/functional/radio_hidl_hal_test.cpp index 79c3cde745..59f768201d 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_test.cpp +++ b/radio/1.6/vts/functional/radio_hidl_hal_test.cpp @@ -74,6 +74,29 @@ std::cv_status RadioHidlTest_v1_6::wait() { return status; } +void RadioHidlTest_v1_6::clearPotentialEstablishedCalls() { + // Get the current call Id to hangup the established emergency call. + serial = GetRandomSerialNumber(); + radio_v1_6->getCurrentCalls_1_6(serial); + EXPECT_EQ(std::cv_status::no_timeout, wait()); + + // Hang up to disconnect the established call channels. + for (const ::android::hardware::radio::V1_6::Call& call : radioRsp_v1_6->currentCalls) { + serial = GetRandomSerialNumber(); + radio_v1_6->hangup(serial, call.base.base.index); + ALOGI("Hang up to disconnect the established call channel: %d", call.base.base.index); + EXPECT_EQ(std::cv_status::no_timeout, wait()); + // Give some time for modem to disconnect the established call channel. + sleep(MODEM_EMERGENCY_CALL_DISCONNECT_TIME); + } + + // Verify there are no more current calls. + serial = GetRandomSerialNumber(); + radio_v1_6->getCurrentCalls_1_6(serial); + EXPECT_EQ(std::cv_status::no_timeout, wait()); + EXPECT_EQ(0, radioRsp_v1_6->currentCalls.size()); +} + void RadioHidlTest_v1_6::updateSimCardStatus() { serial = GetRandomSerialNumber(); radio_v1_6->getIccCardStatus(serial); diff --git a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h index 334fec3622..ea85e3ac7d 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h +++ b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h @@ -70,7 +70,8 @@ class RadioResponse_v1_6 : public ::android::hardware::radio::V1_6::IRadioRespon ::android::hardware::radio::V1_6::RadioResponseInfo rspInfo; // Call - hidl_vec<::android::hardware::radio::V1_2::Call> currentCalls; + hidl_vec<::android::hardware::radio::V1_6::Call> currentCalls; + ::android::hardware::radio::V1_2::VoiceRegStateResult voiceRegResp; // Sms SendSmsResult sendSmsResult; diff --git a/radio/1.6/vts/functional/radio_response.cpp b/radio/1.6/vts/functional/radio_response.cpp index 100fabd828..6edf2fdc37 100644 --- a/radio/1.6/vts/functional/radio_response.cpp +++ b/radio/1.6/vts/functional/radio_response.cpp @@ -816,8 +816,11 @@ Return RadioResponse_v1_6::getCellInfoListResponse_1_2( } Return RadioResponse_v1_6::getVoiceRegistrationStateResponse_1_2( - const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/, - const ::android::hardware::radio::V1_2::VoiceRegStateResult& /*voiceRegResponse*/) { + const ::android::hardware::radio::V1_0::RadioResponseInfo& info, + const ::android::hardware::radio::V1_2::VoiceRegStateResult& voiceRegResponse) { + rspInfo_v1_0 = info; + voiceRegResp = voiceRegResponse; + parent_v1_6.notify(info.serial); return Void(); } @@ -1210,8 +1213,9 @@ Return RadioResponse_v1_6::getDataRegistrationStateResponse_1_6( Return RadioResponse_v1_6::getCurrentCallsResponse_1_6( const ::android::hardware::radio::V1_6::RadioResponseInfo& info, - const ::android::hardware::hidl_vec<::android::hardware::radio::V1_6::Call>& /*calls*/) { + const ::android::hardware::hidl_vec<::android::hardware::radio::V1_6::Call>& calls) { rspInfo = info; + currentCalls = calls; parent_v1_6.notify(info.serial); return Void(); } -- GitLab From d468101f149e30bc4ec5105555973d4ed8b4e009 Mon Sep 17 00:00:00 2001 From: Edwin Wong Date: Tue, 2 Feb 2021 10:04:02 -0800 Subject: [PATCH 424/790] [RESTRICT AUTOMERGE] Fix potential decrypt destPtr overflow. There is a potential integer overflow to bypass the destination base size check in decrypt. The destPtr can then point to the outside of the destination buffer. Test: sts-tradefed sts-tradefed run sts-engbuild-no-spl-lock -m StsHostTestCases --test android.security.sts.Bug_176444622#testPocBug_176444622 Test: push to device with target_hwasan-userdebug build adb shell /data/local/tmp/Bug-17644462264 Bug: 176444622 Bug: 176496353 Change-Id: I75ae057793a4ff4e4f52a8577bef189ad842fb0e --- drm/1.0/default/CryptoPlugin.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drm/1.0/default/CryptoPlugin.cpp b/drm/1.0/default/CryptoPlugin.cpp index 2a85f0e3d3..4ab9029434 100644 --- a/drm/1.0/default/CryptoPlugin.cpp +++ b/drm/1.0/default/CryptoPlugin.cpp @@ -80,7 +80,7 @@ namespace implementation { } } - android::CryptoPlugin::Mode legacyMode; + android::CryptoPlugin::Mode legacyMode = android::CryptoPlugin::kMode_Unencrypted; switch(mode) { case Mode::UNENCRYPTED: legacyMode = android::CryptoPlugin::kMode_Unencrypted; @@ -149,7 +149,10 @@ namespace implementation { return Void(); } - if (destBuffer.offset + destBuffer.size > destBase->getSize()) { + size_t totalDstSize = 0; + if (__builtin_add_overflow(destBuffer.offset, destBuffer.size, &totalDstSize) || + totalDstSize > destBase->getSize()) { + android_errorWriteLog(0x534e4554, "176496353"); _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size"); return Void(); } -- GitLab From da826d6ebe6f19fb0651c85c11ef23a67a6702ec Mon Sep 17 00:00:00 2001 From: Marin Shalamanov Date: Wed, 3 Feb 2021 21:20:15 +0100 Subject: [PATCH 425/790] Tracking changes to renaming DisplayConfig to DisplayMode Bug: 159590486 Test: presubmit Change-Id: I23509d81e47bbe5245f33aa86a94d8126ace5f8e --- .../evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp b/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp index e56c2d1834..a3dc45bb5b 100644 --- a/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp +++ b/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp @@ -41,14 +41,14 @@ static const float kNanoToSeconds = 0.000000001f; #include #include +#include #include #include -#include #include +#include #include -#include #include -#include +#include #include #include #include @@ -622,7 +622,7 @@ TEST_P(EvsHidlTest, CameraToDisplayRoundTrip) { ASSERT_GT(config.size(), 0); ASSERT_GT(state.size(), 0); - android::DisplayConfig* pConfig = (android::DisplayConfig*)config.data(); + android::ui::DisplayMode* pConfig = (android::ui::DisplayMode*)config.data(); const auto width = pConfig->resolution.getWidth(); const auto height = pConfig->resolution.getHeight(); LOG(INFO) << " Resolution: " << width << "x" << height; -- GitLab From 6300039f3e0515cf17bed2419ed764e5498d3e61 Mon Sep 17 00:00:00 2001 From: Ytai Ben-Tsvi Date: Wed, 3 Feb 2021 16:34:21 -0800 Subject: [PATCH 426/790] Deprecate old soundtrigger HAL versions This will give us an eventual path for dropping support for those old versions, with minimal consequences, since upgrading those HAL implementations is trivial. Fixes: 179307730 Test: Compile Change-Id: I9d8981126ef7be2acb9aca182de595a78630053b --- compatibility_matrices/compatibility_matrix.current.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index f125df266f..8e44be0e0c 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -517,7 +517,7 @@ android.hardware.soundtrigger - 2.0-3 + 2.3 ISoundTriggerHw default -- GitLab From eb3939467a27aad2232286e11ce3d127b9d45973 Mon Sep 17 00:00:00 2001 From: Zoey Chen Date: Mon, 1 Feb 2021 21:16:31 +0800 Subject: [PATCH 427/790] Add dtmSupported into 1.6 HAL for 2G network Bug: 178328574 Test: make, VTS Change-Id: Iba230acda8302df90e77d93701d9b0ba74196fc0 --- radio/1.6/types.hal | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/radio/1.6/types.hal b/radio/1.6/types.hal index 4eaf7be821..6ceff7762d 100644 --- a/radio/1.6/types.hal +++ b/radio/1.6/types.hal @@ -737,6 +737,14 @@ struct RegStateResult { */ NrVopsInfo nrVopsInfo; } ngranInfo; + + struct GeranRegistrationInfo { + /** + * True if the dual transfer mode is supported. + * Refer to 3GPP TS 44.108 section 3.4.25.3 + */ + bool dtmSupported; + } geranInfo; } accessTechnologySpecificInfo; }; -- GitLab From 02f2da87d8145a0922d6897ffe6b90c75eb009f8 Mon Sep 17 00:00:00 2001 From: Robert Shih Date: Fri, 15 Jan 2021 08:25:24 -0800 Subject: [PATCH 428/790] drm@1.4: API to retrieve plugin log messages Log messages can be exported by apps during error diagnosis. Bug: 162255728 Test: GtsMediaTestCases MediaDrmTest#testGetLogMessages Change-Id: Id7576b237501f4af6a7399207fbad5ac3b92c20b --- drm/1.4/Android.bp | 1 + drm/1.4/ICryptoPlugin.hal | 13 ++++++++++ drm/1.4/IDrmPlugin.hal | 12 +++++++++ drm/1.4/types.hal | 51 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 77 insertions(+) create mode 100644 drm/1.4/types.hal diff --git a/drm/1.4/Android.bp b/drm/1.4/Android.bp index 8e1dc93c9f..f40ff87b13 100644 --- a/drm/1.4/Android.bp +++ b/drm/1.4/Android.bp @@ -8,6 +8,7 @@ hidl_interface { "ICryptoPlugin.hal", "IDrmFactory.hal", "IDrmPlugin.hal", + "types.hal", ], interfaces: [ "android.hardware.drm@1.0", diff --git a/drm/1.4/ICryptoPlugin.hal b/drm/1.4/ICryptoPlugin.hal index 874ef4cd3b..addfdd08d9 100644 --- a/drm/1.4/ICryptoPlugin.hal +++ b/drm/1.4/ICryptoPlugin.hal @@ -16,6 +16,8 @@ package android.hardware.drm@1.4; import @1.2::ICryptoPlugin; +import @1.4::LogMessage; +import @1.4::Status; /** * ICryptoPlugin is the HAL for vendor-provided crypto plugins. @@ -23,4 +25,15 @@ import @1.2::ICryptoPlugin; * load crypto keys for a codec to decrypt protected video content. */ interface ICryptoPlugin extends @1.2::ICryptoPlugin { + + /** + * @return logMessages latest plugin level log messages. Can be used + * by apps in diagnosis of errors. + * @return status the status of the call. The status must be: + * OK on success; + * GENERAL_OEM_ERROR on OEM-provided, low-level component failures; + * GENERAL_PLUGIN_ERROR on unexpected plugin-level errors. + */ + getLogMessages() generates (@1.4::Status status, vec logMessages); + }; diff --git a/drm/1.4/IDrmPlugin.hal b/drm/1.4/IDrmPlugin.hal index e8af230033..df04b9f226 100644 --- a/drm/1.4/IDrmPlugin.hal +++ b/drm/1.4/IDrmPlugin.hal @@ -19,6 +19,8 @@ import @1.0::Status; import @1.0::SessionId; import @1.1::SecurityLevel; import @1.2::IDrmPlugin; +import @1.4::LogMessage; +import @1.4::Status; /** * IDrmPlugin is used to interact with a specific drm plugin that was @@ -61,4 +63,14 @@ interface IDrmPlugin extends @1.2::IDrmPlugin { */ setPlaybackId(SessionId sessionId, string playbackId) generates (@1.0::Status status); + /** + * @return logMessages latest plugin level log messages. Can be used + * by apps in diagnosis of errors. + * @return status the status of the call. The status must be: + * OK on success; + * GENERAL_OEM_ERROR on OEM-provided, low-level component failures; + * GENERAL_PLUGIN_ERROR on unexpected plugin-level errors. + */ + getLogMessages() generates (@1.4::Status status, vec logMessages); + }; diff --git a/drm/1.4/types.hal b/drm/1.4/types.hal new file mode 100644 index 0000000000..706c3aa92a --- /dev/null +++ b/drm/1.4/types.hal @@ -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@1.4; + +import @1.2::Status; + +enum LogPriority : uint32_t { + ERROR, + WARN, + INFO, + DEBUG, + VERBOSE +}; + +/** + * Returned by getLogMessages to report error diagnostics to the + * app. + */ +struct LogMessage { + int64_t timeMs; + LogPriority priority; + string message; +}; + +enum Status : @1.2::Status { + + /** + * Non-specific error reported by the device OEM subsystem. + */ + GENERAL_OEM_ERROR, + + /** + * Unexpected internal failure in the drm/crypto plugin. + */ + GENERAL_PLUGIN_ERROR, + +}; -- GitLab From 77e678ce596346df8622a0b783c802866466e5b7 Mon Sep 17 00:00:00 2001 From: Benjamin Schwartz Date: Wed, 3 Feb 2021 12:55:39 -0800 Subject: [PATCH 429/790] power/stats: Rename readEnergyMeters to readEnergyMeter Bug: 135067502 Test: build Change-Id: I76e73668faf248ca33a37eb221973d2164d9c9b8 --- .../current/android/hardware/power/stats/IPowerStats.aidl | 2 +- .../aidl/android/hardware/power/stats/IPowerStats.aidl | 4 ++-- power/stats/aidl/default/PowerStats.cpp | 4 ++-- power/stats/aidl/default/PowerStats.h | 4 ++-- power/stats/aidl/vts/VtsHalPowerStatsTargetTest.cpp | 6 +++--- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/IPowerStats.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/IPowerStats.aidl index 0b6387e4aa..5b11695e85 100644 --- a/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/IPowerStats.aidl +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/current/android/hardware/power/stats/IPowerStats.aidl @@ -38,5 +38,5 @@ interface IPowerStats { android.hardware.power.stats.EnergyConsumer[] getEnergyConsumerInfo(); android.hardware.power.stats.EnergyConsumerResult[] getEnergyConsumed(in int[] energyConsumerIds); android.hardware.power.stats.Channel[] getEnergyMeterInfo(); - android.hardware.power.stats.EnergyMeasurement[] readEnergyMeters(in int[] channelIds); + android.hardware.power.stats.EnergyMeasurement[] readEnergyMeter(in int[] channelIds); } diff --git a/power/stats/aidl/android/hardware/power/stats/IPowerStats.aidl b/power/stats/aidl/android/hardware/power/stats/IPowerStats.aidl index 24a8f67ca8..7a95f744d0 100644 --- a/power/stats/aidl/android/hardware/power/stats/IPowerStats.aidl +++ b/power/stats/aidl/android/hardware/power/stats/IPowerStats.aidl @@ -107,5 +107,5 @@ interface IPowerStats { * - STATUS_BAD_VALUE if an invalid channelId is provided * - STATUS_FAILED_TRANSACTION if any EnergyMeasurement fails to be returned */ - EnergyMeasurement[] readEnergyMeters(in int[] channelIds); -} \ No newline at end of file + EnergyMeasurement[] readEnergyMeter(in int[] channelIds); +} diff --git a/power/stats/aidl/default/PowerStats.cpp b/power/stats/aidl/default/PowerStats.cpp index 6cb0a738b0..0ffbd083c6 100644 --- a/power/stats/aidl/default/PowerStats.cpp +++ b/power/stats/aidl/default/PowerStats.cpp @@ -53,8 +53,8 @@ ndk::ScopedAStatus PowerStats::getEnergyMeterInfo(std::vector* _aidl_re return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus PowerStats::readEnergyMeters(const std::vector& in_channelIds, - std::vector* _aidl_return) { +ndk::ScopedAStatus PowerStats::readEnergyMeter(const std::vector& in_channelIds, + std::vector* _aidl_return) { (void)in_channelIds; (void)_aidl_return; return ndk::ScopedAStatus::ok(); diff --git a/power/stats/aidl/default/PowerStats.h b/power/stats/aidl/default/PowerStats.h index 04c2d547cc..cb98e553f3 100644 --- a/power/stats/aidl/default/PowerStats.h +++ b/power/stats/aidl/default/PowerStats.h @@ -35,8 +35,8 @@ class PowerStats : public BnPowerStats { ndk::ScopedAStatus getEnergyConsumed(const std::vector& in_energyConsumerIds, std::vector* _aidl_return) override; ndk::ScopedAStatus getEnergyMeterInfo(std::vector* _aidl_return) override; - ndk::ScopedAStatus readEnergyMeters(const std::vector& in_channelIds, - std::vector* _aidl_return) override; + ndk::ScopedAStatus readEnergyMeter(const std::vector& in_channelIds, + std::vector* _aidl_return) override; }; } // namespace stats diff --git a/power/stats/aidl/vts/VtsHalPowerStatsTargetTest.cpp b/power/stats/aidl/vts/VtsHalPowerStatsTargetTest.cpp index 033bf1a3a4..bed3fdf352 100644 --- a/power/stats/aidl/vts/VtsHalPowerStatsTargetTest.cpp +++ b/power/stats/aidl/vts/VtsHalPowerStatsTargetTest.cpp @@ -262,7 +262,7 @@ TEST_P(PowerStatsAidl, ValidateChannelUniqueIds) { // Reading energy meter must return a valid status TEST_P(PowerStatsAidl, TestReadEnergyMeter) { std::vector data; - ASSERT_TRUE(powerstats->readEnergyMeters({}, &data).isOk()); + ASSERT_TRUE(powerstats->readEnergyMeter({}, &data).isOk()); } // Reading energy meter must return results for all available channels @@ -271,7 +271,7 @@ TEST_P(PowerStatsAidl, TestGetAllEnergyMeasurements) { ASSERT_TRUE(powerstats->getEnergyMeterInfo(&channels).isOk()); std::vector measurements; - ASSERT_TRUE(powerstats->readEnergyMeters({}, &measurements).isOk()); + ASSERT_TRUE(powerstats->readEnergyMeter({}, &measurements).isOk()); testMatching(channels, &Channel::id, measurements, &EnergyMeasurement::id); } @@ -291,7 +291,7 @@ TEST_P(PowerStatsAidl, TestGetSelectedEnergyMeasurements) { } std::vector selectedMeasurements; - ASSERT_TRUE(powerstats->readEnergyMeters(selectedIds, &selectedMeasurements).isOk()); + ASSERT_TRUE(powerstats->readEnergyMeter(selectedIds, &selectedMeasurements).isOk()); testMatching(selectedChannels, &Channel::id, selectedMeasurements, &EnergyMeasurement::id); } -- GitLab From 687ffe58de012d4797af12d5d3a457a0f821bbea Mon Sep 17 00:00:00 2001 From: Hongbo Zeng Date: Tue, 2 Feb 2021 23:01:12 +0800 Subject: [PATCH 430/790] Support SlicingConfig for 5G Slicing Configuration - add new HAL APIs getSlicingConfig() and getSlicingConfigResponse() - create structs SlicingConfig, UrspRule, RouteSelectionDescriptor, RouteSelectionDescriptorParams, Nssais, and RejectedSliceInfo - add SliceRejectionCause Bug: 178075054 Test: run "atest VtsHalRadioV1_6TargetTest" and check the result for getSlicingConfig is PASSED [3/13] PerInstance/RadioHidlTest_v1_6#getSlicingConfig/0_slot1: PASSED (15ms) Change-Id: I5dc97d3c49d0bf4726975a5558360ebf9c09224b --- radio/1.6/IRadio.hal | 13 ++ radio/1.6/IRadioResponse.hal | 14 ++ radio/1.6/types.hal | 144 ++++++++++++++++++ .../1.6/vts/functional/radio_hidl_hal_api.cpp | 12 ++ .../functional/radio_hidl_hal_utils_v1_6.h | 4 + radio/1.6/vts/functional/radio_response.cpp | 8 + 6 files changed, 195 insertions(+) diff --git a/radio/1.6/IRadio.hal b/radio/1.6/IRadio.hal index 7bb35362da..b756ce1261 100644 --- a/radio/1.6/IRadio.hal +++ b/radio/1.6/IRadio.hal @@ -505,4 +505,17 @@ interface IRadio extends @1.5::IRadio { * Response function is IRadioResponse.getCurrentCallsResponse_1_6() */ oneway getCurrentCalls_1_6(int32_t serial); + + /** + * Request to get 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. + * + * Response function is IRadioResponse.getSlicingConfigResponse() + */ + oneway getSlicingConfig(int32_t serial); }; diff --git a/radio/1.6/IRadioResponse.hal b/radio/1.6/IRadioResponse.hal index 3c6137ec3b..6ad5cf262a 100644 --- a/radio/1.6/IRadioResponse.hal +++ b/radio/1.6/IRadioResponse.hal @@ -25,6 +25,7 @@ import @1.6::RegStateResult; import @1.6::RadioResponseInfo; import @1.6::SetupDataCallResult; import @1.6::SignalStrength; +import @1.6::SlicingConfig; /** * Interface declaring response functions to solicited radio requests. @@ -416,4 +417,17 @@ interface IRadioResponse extends @1.5::IRadioResponse { * RadioError:CANCELLED */ oneway getCurrentCallsResponse_1_6(RadioResponseInfo info, vec calls); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param slicingConfig Current slicing configuration + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:MODEM_ERR + */ + oneway getSlicingConfigResponse(RadioResponseInfo info, + SlicingConfig slicingConfig); }; diff --git a/radio/1.6/types.hal b/radio/1.6/types.hal index c02a43ff0c..6c23650dde 100644 --- a/radio/1.6/types.hal +++ b/radio/1.6/types.hal @@ -971,3 +971,147 @@ struct OSAppId { */ vec osAppId; }; + +/** + * This struct represents the current slicing configuration. + */ +struct SlicingConfig { + /** + * This vector contains the current URSP rules. Empty vector represents that no + * rules are configured. + */ + vec urspRules; + /** + * Struct containing all NSSAIs (list of slice info). + */ + Nssais nsaids; +}; + +/** + * This struct represents a single URSP rule as defined in 3GPP TS 24.526. + */ +struct UrspRule { + /** + * Precedence value in the range of 0 to 255. Higher value has lower + * precedence. + */ + uint8_t precedence; + /** + * Used as a matcher for network requests. + */ + vec trafficDescriptors; + /** + * List of routes (connection parameters) that must be used for requests + * matching a trafficDescriptor. + */ + vec routeSelectionDescriptor; +}; + + +/** + * This struct represents a single route selection descriptor as defined in + * 3GPP TS 24.526. + */ +struct RouteSelectionDescriptor { + /** + * Precedence value in the range of 0 to 255. Higher value has lower + * precedence. + */ + uint8_t precedence; + /** + * Parameters defining this RouteSelectionDescriptor. The length of the vector + * must be >= 1. + */ + vec routeSelectionDescriptorParams; +}; + +/** + * This struct represents a route selection descriptor. A valid struct must have + * at least one of the vectors non-empty. + */ +struct RouteSelectionDescriptorParams { + /** + * Valid values are IP, IPV6 and IPV4V6. + */ + OptionalPdpProtocolType sessionType; + OptionalSscMode sscMode; + /** + * There can be 0 or more SliceInfo specified in a route descriptor. + */ + vec sliceInfo; + /** + * DNN stands for Data Network Name and represents an APN as defined in + * 3GPP TS 23.003. There can be 0 or more DNNs specified in a route + * descriptor. + */ + vec dnn; +}; + +/** + * This safe_union represents an optional PdpProtocolType. + */ +safe_union OptionalPdpProtocolType { + Monostate noinit; + PdpProtocolType value; +}; + +/** + * This safe_union represents an optional SscMode. + */ +safe_union OptionalSscMode { + Monostate noinit; + SscMode value; +}; + +/** + * This struct contains all NSSAIs (lists of slices). + */ +struct Nssais { + /** + * These are all the slices configured by the network. This includes allowed + * and rejected slices, as well as slices that are neither allowed nor rejected + * yet. Empty vector indicates that no slices are configured, and in that case + * allowed and rejected vectors must be empty as well. + */ + vec configured; + /** + * These are all the slices that the UE is allowed to use. All these slices + * must be configured as well. Empty vector indicates that no slices are + * allowed yet. + */ + vec allowed; + /** + * These are all the slices that the UE is not allowed to use. All these slices + * must be configured as well. Empty vector indicates that no slices are + * rejected yet. + */ + vec rejected; + /** + * Default configured NSSAI + */ + vec defaultConfigured; +}; + +/** + * This struct represents a network slice rejected by the network. It contains a + * rejectionCause corresponding to a rejected network slice. + */ +struct RejectedSliceInfo { + SliceInfo sliceInfo; + SliceRejectionCause rejectionCause; +}; + +enum SliceRejectionCause : int32_t { + NOT_AVAILABLE_IN_PLMN, + NOT_AVAILABLE_IN_REG_AREA, +}; + +/** + * Enum representing session and service continuity mode as defined in + * 3GPP TS 23.501. + */ +enum SscMode : int32_t { + MODE_1 = 1, + MODE_2 = 2, + MODE_3 = 3, +}; diff --git a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp index be24535404..07b8ccb035 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp +++ b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp @@ -163,6 +163,18 @@ TEST_P(RadioHidlTest_v1_6, setupDataCall_1_6_osAppId) { } } +/* + * Test IRadio.getSlicingConfig() for the response returned. + */ +TEST_P(RadioHidlTest_v1_6, getSlicingConfig) { + serial = GetRandomSerialNumber(); + radio_v1_6->getSlicingConfig(serial); + EXPECT_EQ(std::cv_status::no_timeout, wait()); + EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type); + EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial); + EXPECT_EQ(::android::hardware::radio::V1_6::RadioError::NONE, radioRsp_v1_6->rspInfo.error); +} + /* * Test IRadio_1_6.sendSms() for the response returned. */ diff --git a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h index 010d36b142..f32e31296d 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h +++ b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h @@ -827,6 +827,10 @@ class RadioResponse_v1_6 : public ::android::hardware::radio::V1_6::IRadioRespon Return getCurrentCallsResponse_1_6( const ::android::hardware::radio::V1_6::RadioResponseInfo& info, const ::android::hardware::hidl_vec<::android::hardware::radio::V1_6::Call>& calls); + + Return getSlicingConfigResponse( + const ::android::hardware::radio::V1_6::RadioResponseInfo& info, + const ::android::hardware::radio::V1_6::SlicingConfig& slicingConfig); }; /* Callback class for radio indication */ diff --git a/radio/1.6/vts/functional/radio_response.cpp b/radio/1.6/vts/functional/radio_response.cpp index 81f4f104a3..fad3f12e2b 100644 --- a/radio/1.6/vts/functional/radio_response.cpp +++ b/radio/1.6/vts/functional/radio_response.cpp @@ -1220,3 +1220,11 @@ Return RadioResponse_v1_6::getCurrentCallsResponse_1_6( parent_v1_6.notify(info.serial); return Void(); } + +Return RadioResponse_v1_6::getSlicingConfigResponse( + const ::android::hardware::radio::V1_6::RadioResponseInfo& info, + const ::android::hardware::radio::V1_6::SlicingConfig& /*slicingConfig*/) { + rspInfo = info; + parent_v1_6.notify(info.serial); + return Void(); +} -- GitLab From c66a455f275f24ca5fbc3e09d116debcbb2b22a0 Mon Sep 17 00:00:00 2001 From: Mikhail Naganov Date: Thu, 4 Feb 2021 22:12:36 +0000 Subject: [PATCH 431/790] Fix library dependencies for VtsHalAudio tests Move system-only libraries to 'static_libs', move 'libxml2' to 'shared_libs'. Bug: 169605640 Test: atest VtsHalAudioV6_0TargetTest Change-Id: I1bb8c800704aa25c395164ee7d95d4508dcfbfae --- audio/core/all-versions/vts/functional/Android.bp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/audio/core/all-versions/vts/functional/Android.bp b/audio/core/all-versions/vts/functional/Android.bp index 8021bd9dd9..e8b704ca22 100644 --- a/audio/core/all-versions/vts/functional/Android.bp +++ b/audio/core/all-versions/vts/functional/Android.bp @@ -19,13 +19,13 @@ cc_defaults { defaults: ["VtsHalTargetTestDefaults"], static_libs: [ "android.hardware.audio.common.test.utility", - "libxml2", - ], - shared_libs: [ "audioclient-types-aidl-cpp", "libaudioclient_aidl_conversion", + ], + shared_libs: [ "libbinder", "libfmq", + "libxml2", ], header_libs: [ "android.hardware.audio.common.util@all-versions", -- GitLab From 4f7e565dfaec3fafa1fb076a239447fb5d87f363 Mon Sep 17 00:00:00 2001 From: Robert Shih Date: Thu, 21 Jan 2021 02:49:22 -0800 Subject: [PATCH 432/790] android.hardware.drm@1.4 vts Bug: 177872328 Test: VtsHalDrmV1_4TargetTest Change-Id: I5586ab2bbf4eb0487c50f81758b6edb4e8eadd42 --- drm/1.4/vts/OWNERS | 9 + drm/1.4/vts/functional/Android.bp | 95 +++++++++++ drm/1.4/vts/functional/AndroidTest.xml | 38 +++++ drm/1.4/vts/functional/drm_hal_test.cpp | 161 ++++++++++++++++++ drm/1.4/vts/functional/drm_hal_test_main.cpp | 94 ++++++++++ .../hardware/drm/1.4/vts/drm_hal_test.h | 83 +++++++++ 6 files changed, 480 insertions(+) create mode 100644 drm/1.4/vts/OWNERS create mode 100644 drm/1.4/vts/functional/Android.bp create mode 100644 drm/1.4/vts/functional/AndroidTest.xml create mode 100644 drm/1.4/vts/functional/drm_hal_test.cpp create mode 100644 drm/1.4/vts/functional/drm_hal_test_main.cpp create mode 100644 drm/1.4/vts/functional/include/android/hardware/drm/1.4/vts/drm_hal_test.h diff --git a/drm/1.4/vts/OWNERS b/drm/1.4/vts/OWNERS new file mode 100644 index 0000000000..3a0672e5c6 --- /dev/null +++ b/drm/1.4/vts/OWNERS @@ -0,0 +1,9 @@ +conglin@google.com +edwinwong@google.com +fredgc@google.com +jtinker@google.com +juce@google.com +kylealexander@google.com +rfrias@google.com +robertshih@google.com +sigquit@google.com diff --git a/drm/1.4/vts/functional/Android.bp b/drm/1.4/vts/functional/Android.bp new file mode 100644 index 0000000000..80b1dd1825 --- /dev/null +++ b/drm/1.4/vts/functional/Android.bp @@ -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. +// + +cc_library_static { + name: "android.hardware.drm@1.4-vts", + defaults: ["VtsHalTargetTestDefaults"], + local_include_dirs: [ + "include", + ], + srcs: [ + "drm_hal_test.cpp", + ], + shared_libs: [ + "android.hardware.drm@1.0", + "android.hardware.drm@1.1", + "android.hardware.drm@1.2", + "android.hardware.drm@1.3", + "android.hardware.drm@1.4", + "android.hidl.allocator@1.0", + "android.hidl.memory@1.0", + "libhidlmemory", + "libnativehelper", + ], + static_libs: [ + "android.hardware.drm@1.0-helper", + "android.hardware.drm@1.2-vts", + "libdrmvtshelper", + ], + export_static_lib_headers: [ + "android.hardware.drm@1.2-vts", + ], + export_include_dirs: [ + "include", + ], +} + +cc_test { + name: "VtsHalDrmV1_4TargetTest", + defaults: ["VtsHalTargetTestDefaults"], + include_dirs: ["hardware/interfaces/drm/1.0/vts/functional"], + srcs: [ + "drm_hal_test_main.cpp", + ], + whole_static_libs: [ + "android.hardware.drm@1.4-vts", + ], + shared_libs: [ + "android.hardware.drm@1.0", + "android.hardware.drm@1.1", + "android.hardware.drm@1.2", + "android.hardware.drm@1.3", + "android.hardware.drm@1.4", + "android.hidl.allocator@1.0", + "android.hidl.memory@1.0", + "libcrypto", + "libhidlmemory", + "libnativehelper", + ], + static_libs: [ + "android.hardware.drm@1.0-helper", + "android.hardware.drm@1.2-vts", + "libdrmvtshelper", + ], + arch: { + arm: { + data: [":libvtswidevine-arm-prebuilts"], + }, + arm64: { + data: [":libvtswidevine-arm64-prebuilts"], + }, + x86: { + data: [":libvtswidevine-x86-prebuilts"], + }, + x86_64: { + data: [":libvtswidevine-x86_64-prebuilts"], + }, + }, + test_suites: [ + "general-tests", + "vts", + ], +} diff --git a/drm/1.4/vts/functional/AndroidTest.xml b/drm/1.4/vts/functional/AndroidTest.xml new file mode 100644 index 0000000000..b18da49a8c --- /dev/null +++ b/drm/1.4/vts/functional/AndroidTest.xml @@ -0,0 +1,38 @@ + + + + diff --git a/drm/1.4/vts/functional/drm_hal_test.cpp b/drm/1.4/vts/functional/drm_hal_test.cpp new file mode 100644 index 0000000000..ee6635b2ad --- /dev/null +++ b/drm/1.4/vts/functional/drm_hal_test.cpp @@ -0,0 +1,161 @@ +/* + * 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 "drm_hal_test@1.4" + +#include "android/hardware/drm/1.4/vts/drm_hal_test.h" + +namespace android { +namespace hardware { +namespace drm { +namespace V1_4 { +namespace vts { + +const char* const DrmHalTest::kVideoMp4 = "video/mp4"; +const char* const DrmHalTest::kAudioMp4 = "audio/mp4"; +const uint32_t DrmHalTest::kSecLevelDefault = DrmHalTest::kSecLevelMax + 1; + +sp DrmHalTest::DrmPluginV1_4() const { + sp plugin(drm::V1_4::IDrmPlugin::castFrom(drmPlugin)); + EXPECT_NE(nullptr, plugin.get()); + return plugin; +} + +sp DrmHalTest::CryptoPlugin(const SessionId& sid) { + sp crypto; + auto res = cryptoFactory->createPlugin( + getUUID(), sid, + [&](V1_0::Status status, const sp& plugin) { + EXPECT_EQ(V1_0::Status::OK, status); + EXPECT_NE(nullptr, plugin.get()); + crypto = plugin; + }); + EXPECT_OK(res); + return crypto; +} + +SessionId DrmHalTest::OpenSession(uint32_t level = kSecLevelDefault) { + V1_0::Status err; + SessionId sessionId; + bool attemptedProvision = false; + + V1_0::IDrmPlugin::openSession_cb cb = [&]( + V1_0::Status status, + const hidl_vec &id) { + err = status; + sessionId = id; + }; + + while (true) { + Return res; + if (level > kSecLevelMax) { + res = drmPlugin->openSession(cb); + } else if (level >= kSecLevelMin) { + auto securityLevel = static_cast(level); + res = drmPlugin->openSession_1_1(securityLevel, cb); + } + EXPECT_OK(res); + if (V1_0::Status::ERROR_DRM_NOT_PROVISIONED == err + && !attemptedProvision) { + // provision once if necessary + provision(); + attemptedProvision = true; + continue; + } else if (V1_0::Status::ERROR_DRM_CANNOT_HANDLE == err) { + // must be able to handle default level + EXPECT_NE(kSecLevelDefault, level); + sessionId = {}; + } else { + EXPECT_EQ(V1_0::Status::OK, err); + EXPECT_NE(sessionId.size(), 0u); + } + break; + } + + return sessionId; +} + +TEST_P(DrmHalTest, RequiresSecureDecoder) { + for (uint32_t level : {kSecLevelMin, kSecLevelMax, kSecLevelDefault}) { + for (auto mime : {kVideoMp4, kAudioMp4}) { + auto sid = OpenSession(level); + if (sid.size() == 0u) { + continue; + } + auto drm = DrmPluginV1_4(); + sp crypto(CryptoPlugin(sid)); + if (drm == nullptr || crypto == nullptr) { + continue; + } + bool r1 = crypto->requiresSecureDecoderComponent(mime); + bool r2; + if (level == kSecLevelDefault) { + r2 = drm->requiresSecureDecoderDefault(mime); + } else { + auto sL = static_cast(level); + r2 = drm->requiresSecureDecoder(mime, sL); + } + EXPECT_EQ(r1, r2); + closeSession(sid); + } + } +} + +TEST_P(DrmHalTest, SetPlaybackId) { + auto testInfo = ::testing::UnitTest::GetInstance()->current_test_info(); + auto testName = testInfo->name(); + const hidl_string& pbId{testName}; + auto sid = OpenSession(); + auto drm = DrmPluginV1_4(); + if (drm == nullptr) { + return; + } + V1_0::Status err = drm->setPlaybackId(sid, pbId); + EXPECT_EQ(V1_0::Status::OK, err); + closeSession(sid); + + // search for playback id among metric attributes/values + bool foundPbId = false; + auto res = drmPlugin->getMetrics([&]( + V1_0::Status status, + hidl_vec metricGroups) { + EXPECT_EQ(V1_0::Status::OK, status); + for (const auto& group : metricGroups) { + for (const auto& metric : group.metrics) { + for (const auto& value : metric.values) { + if (value.stringValue == pbId) { + foundPbId = true; + break; + } + } + for (const auto& attr : metric.attributes) { + if (attr.stringValue == pbId) { + foundPbId = true; + break; + } + } + } + } + }); + EXPECT_OK(res); + EXPECT_TRUE(foundPbId); +} + +} // namespace vts +} // namespace V1_4 +} // namespace drm +} // namespace hardware +} // namespace android diff --git a/drm/1.4/vts/functional/drm_hal_test_main.cpp b/drm/1.4/vts/functional/drm_hal_test_main.cpp new file mode 100644 index 0000000000..65d1b76038 --- /dev/null +++ b/drm/1.4/vts/functional/drm_hal_test_main.cpp @@ -0,0 +1,94 @@ +/* + * 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. + */ + +/** + * Instantiate the set of test cases for each vendor module + */ + +#define LOG_TAG "drm_hal_test@1.4" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "android/hardware/drm/1.4/vts/drm_hal_test.h" + +using drm_vts::DrmHalTestParam; +using drm_vts::PrintParamInstanceToString; + +using android::hardware::drm::V1_4::vts::DrmHalTest; + +static const std::vector kAllInstances = [] { + using ::android::hardware::hidl_array; + using ::android::hardware::hidl_vec; + using ::android::hardware::drm::V1_4::ICryptoFactory; + using ::android::hardware::drm::V1_4::IDrmFactory; + + std::vector drmInstances = + android::hardware::getAllHalInstanceNames(IDrmFactory::descriptor); + std::vector cryptoInstances = + android::hardware::getAllHalInstanceNames(ICryptoFactory::descriptor); + std::set allInstances; + allInstances.insert(drmInstances.begin(), drmInstances.end()); + allInstances.insert(cryptoInstances.begin(), cryptoInstances.end()); + + std::vector firstInstanceUuidCombos; + for (const auto &instance : allInstances) { + auto drmFactory = IDrmFactory::getService(instance); + if (drmFactory == nullptr) { + continue; + } + drmFactory->getSupportedCryptoSchemes( + [&](const hidl_vec>& schemes) { + if (schemes.size() > 0) { + firstInstanceUuidCombos.push_back(DrmHalTestParam(instance, schemes[0])); + } + }); + } + return firstInstanceUuidCombos; +}(); + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DrmHalTest); +INSTANTIATE_TEST_SUITE_P(PerInstance, DrmHalTest, + testing::ValuesIn(kAllInstances), + PrintParamInstanceToString); + +int main(int argc, char** argv) { +#if defined(__LP64__) + const char* kModulePath = "/data/local/tmp/64/lib"; +#else + const char* kModulePath = "/data/local/tmp/32/lib"; +#endif + DrmHalTest::gVendorModules + = new drm_vts::VendorModules(kModulePath); + if (DrmHalTest::gVendorModules->getPathList().size() == 0) { + std::cerr << "WARNING: No vendor modules found in " << kModulePath << + ", all vendor tests will be skipped" << std::endl; + } + ::testing::InitGoogleTest(&argc, argv); + int status = RUN_ALL_TESTS(); + ALOGI("Test result = %d", status); + return status; +} diff --git a/drm/1.4/vts/functional/include/android/hardware/drm/1.4/vts/drm_hal_test.h b/drm/1.4/vts/functional/include/android/hardware/drm/1.4/vts/drm_hal_test.h new file mode 100644 index 0000000000..ed49a6141b --- /dev/null +++ b/drm/1.4/vts/functional/include/android/hardware/drm/1.4/vts/drm_hal_test.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 DRM_HAL_TEST_V1_4_H +#define DRM_HAL_TEST_V1_4_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "drm_hal_vendor_module_api.h" +#include "drm_vts_helper.h" +#include "vendor_modules.h" +#include "VtsHalHidlTargetCallbackBase.h" + +#include "android/hardware/drm/1.2/vts/drm_hal_common.h" + +namespace android { +namespace hardware { +namespace drm { +namespace V1_4 { +namespace vts { + +namespace drm = ::android::hardware::drm; +using android::hardware::hidl_array; +using android::hardware::hidl_string; +using V1_0::SessionId; +using V1_1::SecurityLevel; + +using drm_vts::DrmHalTestParam; + +class DrmHalTest : public drm::V1_2::vts::DrmHalTest { +public: + using drm::V1_2::vts::DrmHalTest::DrmHalTest; + static const char* const kVideoMp4; + static const char* const kAudioMp4; + static const uint32_t kSecLevelMin = static_cast(SecurityLevel::SW_SECURE_CRYPTO); + static const uint32_t kSecLevelMax = static_cast(SecurityLevel::HW_SECURE_ALL); + static const uint32_t kSecLevelDefault; + +protected: + sp DrmPluginV1_4() const; + sp CryptoPlugin(const SessionId& sid); + SessionId OpenSession(uint32_t level); + +private: + void DoProvisioning(); +}; + +} // namespace vts +} // namespace V1_4 +} // namespace drm +} // namespace hardware +} // namespace android + +#endif // DRM_HAL_TEST_V1_4_H -- GitLab From 45f5b0f9f2f4da2ba8d3f92b6ed77f733586336e Mon Sep 17 00:00:00 2001 From: Kevin Chyn Date: Fri, 5 Feb 2021 14:30:23 -0800 Subject: [PATCH 433/790] ISession#detectInteraction should be an optional feature Bug: 178165973 Test: m android.hardware.biometrics.fingerprint-update-api Test: m android.hardware.biometrics.face-update-api Change-Id: I4b07b523735e25f233dfec79b787ec536a57660a --- .../hardware/biometrics/face/SensorProps.aidl | 1 + .../hardware/biometrics/face/ISession.aidl | 4 +++- .../hardware/biometrics/face/SensorProps.aidl | 5 +++++ .../biometrics/fingerprint/AcquiredInfo.aidl | 16 +++++++++++++++- .../hardware/biometrics/fingerprint/Error.aidl | 16 +++++++++++++++- .../fingerprint/FingerprintSensorType.aidl | 16 +++++++++++++++- .../biometrics/fingerprint/IFingerprint.aidl | 16 +++++++++++++++- .../biometrics/fingerprint/ISession.aidl | 16 +++++++++++++++- .../fingerprint/ISessionCallback.aidl | 16 +++++++++++++++- .../biometrics/fingerprint/SensorProps.aidl | 17 ++++++++++++++++- .../biometrics/fingerprint/SessionState.aidl | 16 +++++++++++++++- .../biometrics/fingerprint/ISession.aidl | 4 +++- .../biometrics/fingerprint/SensorProps.aidl | 5 +++++ 13 files changed, 138 insertions(+), 10 deletions(-) diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl index 9147bc1853..23a8d4dddc 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl @@ -41,4 +41,5 @@ parcelable SensorProps { float enrollTranslationX; float enrollTranslationY; float enrollPreviewScale; + boolean supportsDetectInteraction; } diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl index 25ddd82851..f540502669 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl @@ -196,7 +196,9 @@ interface ISession { /** * detectInteraction: * - * A request to start looking for faces without performing matching. + * A request to start looking for faces without performing matching. Must only be called if + * SensorProps#supportsDetectInteraction is true. If invoked on implementations that do not + * support this functionality, the HAL must respond with ISession#onError(UNABLE_TO_PROCESS, 0). * * Once the HAL is able to start processing this request, it must notify the framework via * ISessionCallback#onStateChanged with SessionState::DETECTING_INTERACTION. diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl index 335f2f9e52..091e3225a3 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl @@ -70,5 +70,10 @@ parcelable SensorProps { * be applied when configuring the preview texture. */ float enrollPreviewScale; + + /** + * Specifies whether or not the implementation supports ISession#detectInteraction. + */ + boolean supportsDetectInteraction; } diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl index 7d8c034984..189095a7d7 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl index aec499f229..cdbc2d2f67 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl index 784e1d0d2f..c81cad2971 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl index 51b4c63799..c5a5422d24 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// 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 185d86ff24..be0029c53b 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 @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl index cf663a5670..f20f15324e 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl index f8a40a964f..c3daacd5de 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// @@ -26,4 +40,5 @@ parcelable SensorProps { int sensorLocationY; int sensorRadius; int displayId; + boolean supportsDetectInteraction; } diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.aidl index 3453f93763..44323ffb1d 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.aidl @@ -1,4 +1,18 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl index 09bd04d4ef..f9c3732ac4 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl @@ -191,7 +191,9 @@ interface ISession { /** * detectInteraction: * - * A request to start looking for fingerprints without performing matching. + * A request to start looking for fingerprints without performing matching. Must only be called + * if SensorProps#supportsDetectInteraction is true. If invoked on implementations that do not + * support this functionality, the HAL must respond with ISession#onError(UNABLE_TO_PROCESS, 0). * * Once the HAL is able to start processing this request, it must notify the framework via * ISessionCallback#onStateChanged with SessionState::DETECTING_INTERACTION. diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl index ab70a5801c..afed175bbb 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl @@ -63,5 +63,10 @@ parcelable SensorProps { * android.hardware.DisplayManager#getDisplay Android API. */ int displayId; + + /** + * Specifies whether or not the implementation supports ISession#detectInteraction. + */ + boolean supportsDetectInteraction; } -- GitLab From c5a3798288fdb67917e0cfed951ad2209672a866 Mon Sep 17 00:00:00 2001 From: Sarah Chin Date: Wed, 3 Feb 2021 12:02:14 -0800 Subject: [PATCH 434/790] API updates for TrafficDescriptr fields Bug: 179312227 Test: atest VtsHalRadioV1_6TargetTest Change-Id: I33018ad413875f4fae1497ed5acc8ee50df7c942 --- radio/1.6/IRadio.hal | 9 +++++- radio/1.6/types.hal | 29 ++++++++++--------- .../1.6/vts/functional/radio_hidl_hal_api.cpp | 2 +- radio/1.6/vts/functional/radio_response.cpp | 1 + 4 files changed, 25 insertions(+), 16 deletions(-) diff --git a/radio/1.6/IRadio.hal b/radio/1.6/IRadio.hal index b756ce1261..996a1fcc41 100644 --- a/radio/1.6/IRadio.hal +++ b/radio/1.6/IRadio.hal @@ -103,6 +103,12 @@ interface IRadio extends @1.5::IRadio { * - Support simultaneous data call contexts up to DataRegStateResult.maxDataCalls specified * in the response of getDataRegistrationState. * + * The differences relative to the 1.5 version of the API are: + * - The addition of new parameters pduSessionId, sliceInfo, trafficDescriptor, and + * matchAllRuleAllowed. + * - If an existing data call should be used for the request, that must be indicated in the + * response by setting SetupDataCallResult::cid to the context id of that call. + * * @param serial Serial number of request. * @param accessNetwork The access network to setup the data call. If the data connection cannot * be established on the specified access network then it should be responded with an error. @@ -122,7 +128,8 @@ interface IRadio extends @1.5::IRadio { * Reference: 3GPP TS 24.007 section 11.2.3.1b * @param sliceInfo SliceInfo to be used for the data connection when a handover occurs from * EPDG to 5G. It is valid only when accessNetwork is AccessNetwork:NGRAN. If the slice - * passed from EPDG is rejected, then the data failure cause must be DataCallFailCause:SLICE_REJECTED. + * passed from EPDG is rejected, then the data failure cause must be + * DataCallFailCause:SLICE_REJECTED. * @param trafficDescriptor TrafficDescriptor for which data connection needs to be * established. It is used for URSP traffic matching as described in TS 24.526 * Section 4.2.2. It includes an optional DNN which, if present, must be used for traffic diff --git a/radio/1.6/types.hal b/radio/1.6/types.hal index 6c23650dde..9bb3b55298 100644 --- a/radio/1.6/types.hal +++ b/radio/1.6/types.hal @@ -273,7 +273,8 @@ enum HandoverFailureMode : int32_t { /** * Overwritten from @1.5::SetupDataCallResult in order to change the suggestedRetryTime * to 64-bit value. In the future, this must be extended instead of overwritten. - * Also added defaultQos, qosSessions, and handoverFailureMode in this version. + * Also added defaultQos, qosSessions, handoverFailureMode, pduSessionId, sliceInfo, + * and traffic descriptors in this version. */ struct SetupDataCallResult { /** Data call fail cause. DataCallFailCause.NONE if no error. */ @@ -846,7 +847,7 @@ enum DataCallFailCause : @1.4::DataCallFailCause { MATCH_ALL_RULE_NOT_ALLOWED = 0x8CD, /** - * If connection failed for all matching URSP rules + * If connection failed for all matching URSP rules. */ ALL_MATCHING_RULES_FAILED = 0x8CE, }; @@ -922,17 +923,17 @@ enum NgranBands : @1.5::NgranBands { * This safe_union represents an optional DNN. DNN stands for Data Network Name * and represents an APN as defined in 3GPP TS 23.003. */ -safe_union OptionalDNN { +safe_union OptionalDnn { Monostate noinit; string value; }; /** - * This safe_union represents an optional OSAppId. + * This safe_union represents an optional OsAppId. */ -safe_union OptionalOSAppId { +safe_union OptionalOsAppId { Monostate noinit; - OSAppId value; + OsAppId value; }; /** @@ -953,21 +954,21 @@ struct TrafficDescriptor { * DNN stands for Data Network Name and represents an APN as defined in * 3GPP TS 23.003. */ - OptionalDNN dnn; + OptionalDnn dnn; /** - * Indicates the OSId + OSAppId (used as category in Android). + * Indicates the OsId + OsAppId (used as category in Android). */ - OptionalOSAppId osAppId; + OptionalOsAppId osAppId; }; /** - * This struct represents the OSId + OSAppId as defined in TS 24.526 Section 5.2 + * This struct represents the OsId + OsAppId as defined in TS 24.526 Section 5.2 */ -struct OSAppId { +struct OsAppId { /** - * Byte array representing OSId + OSAppId. The minimum length of the array is - * 18 and maximum length is 272 (16 bytes for OSId + 1 byte for OSAppId length - * + up to 255 bytes for OSAppId). + * Byte array representing OsId + OsAppId. The minimum length of the array is + * 18 and maximum length is 272 (16 bytes for OsId + 1 byte for OsAppId length + * + up to 255 bytes for OsAppId). */ vec osAppId; }; diff --git a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp index 07b8ccb035..716a10b17d 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp +++ b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp @@ -130,7 +130,7 @@ TEST_P(RadioHidlTest_v1_6, setupDataCall_1_6_osAppId) { memset(&optionalTrafficDescriptor, 0, sizeof(optionalTrafficDescriptor)); ::android::hardware::radio::V1_6::TrafficDescriptor trafficDescriptor; - ::android::hardware::radio::V1_6::OSAppId osAppId; + ::android::hardware::radio::V1_6::OsAppId osAppId; osAppId.osAppId = 1; trafficDescriptor.osAppId.value(osAppId); optionalTrafficDescriptor.value(trafficDescriptor); diff --git a/radio/1.6/vts/functional/radio_response.cpp b/radio/1.6/vts/functional/radio_response.cpp index fad3f12e2b..87b83c8b86 100644 --- a/radio/1.6/vts/functional/radio_response.cpp +++ b/radio/1.6/vts/functional/radio_response.cpp @@ -1059,6 +1059,7 @@ Return RadioResponse_v1_6::setupDataCallResponse_1_6( parent_v1_6.notify(info.serial); return Void(); } + Return RadioResponse_v1_6::setNrDualConnectivityStateResponse( const ::android::hardware::radio::V1_6::RadioResponseInfo& info) { rspInfo = info; -- GitLab From a23aa3ba711b2d33b6ad49e2a98ae47855d0070a Mon Sep 17 00:00:00 2001 From: Yu-Han Yang Date: Tue, 2 Feb 2021 10:13:52 -0800 Subject: [PATCH 435/790] Update HAL comment of AGC Bug: 179157665 Test: doc update only Change-Id: I9395a68d3154e8b4e47fd2fb6b0d8f5f33e48805 --- current.txt | 2 +- gnss/1.0/IGnssMeasurementCallback.hal | 29 +++++++++---------- .../hardware/gnss/GnssMeasurement.aidl | 24 +++++++-------- 3 files changed, 24 insertions(+), 31 deletions(-) diff --git a/current.txt b/current.txt index bf6829a353..fb9b056a43 100644 --- a/current.txt +++ b/current.txt @@ -769,7 +769,7 @@ a64467bae843569f0d465c5be7f0c7a5b987985b55a3ef4794dd5afc68538650 android.hardwar # ABI preserving changes to HALs during Android S e042522daa4b5f7fd4a0a19bcdadb93c79a1b04c09ef2c9813a3a8941032f3f5 android.hardware.contexthub@1.0::IContexthub c2f64133b83ede65c9939ef97ab5bd867b73faf3dba0e7e69f77c3c43d9e487e android.hardware.contexthub@1.0::IContexthubCallback -1ca372cd67d197df099e87616a613ba6ede6552638a603e18f86c8834302c3d1 android.hardware.gnss@1.0::IGnssMeasurementCallback +bda492ec4021d13869de72bd6f8c15c5837b78d6136b8d538efec5320573a5ec android.hardware.gnss@1.0::IGnssMeasurementCallback 6a271e493907e8ba20912e42771bd0d99ae45431a851d5675ef9496d02510a34 android.hardware.gnss@1.1::IGnssMeasurementCallback 2c331a9605f3a08d9c1e0a36169ca57758bc43c11a78ef3f3730509885e52c15 android.hardware.graphics.composer@2.4::IComposerClient 3da3ce039247872d95c6bd48621dbfdfa1c2d2a91a90f257862f87ee2bc46300 android.hardware.health@2.1::types diff --git a/gnss/1.0/IGnssMeasurementCallback.hal b/gnss/1.0/IGnssMeasurementCallback.hal index d219af0bd1..603680d0b4 100644 --- a/gnss/1.0/IGnssMeasurementCallback.hal +++ b/gnss/1.0/IGnssMeasurementCallback.hal @@ -644,22 +644,19 @@ interface IGnssMeasurementCallback { */ double snrDb; - /** - * 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. When AGC is at a - * nominal level, this value must be set as 0. 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. - * - * Note: Different hardware designs (e.g. antenna, pre-amplification, or - * other RF HW components) may also affect the typical output of 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. - */ + + /** + * 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; }; diff --git a/gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl b/gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl index 2c56a41643..4468b63e26 100644 --- a/gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl +++ b/gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl @@ -547,20 +547,16 @@ parcelable GnssMeasurement { double snrDb; /** - * 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. When AGC is at a - * nominal level, this value must be set as 0. 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. - * - * 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. + * 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; -- GitLab From f2354c67aa2402f853e7d8644b57eb35933bc984 Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Mon, 8 Feb 2021 19:58:04 -0800 Subject: [PATCH 436/790] Add more status capabilities in Tuner default implementation This CL added more extended frontend status caps into the default implementation to test more code paths. Note that this CL changes the 0 fe from dvbt to isdbs to cover more status caps. fe 0 is used as the default testing fe in CTS Test: atest android.media.tv.tuner.cts Bug: 159067322 Change-Id: I7c15f5fe3cd133af4a191b80ce832a9affef9ee3 --- tv/tuner/1.1/default/Frontend.cpp | 8 +++++--- tv/tuner/1.1/default/Tuner.cpp | 6 ++++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/tv/tuner/1.1/default/Frontend.cpp b/tv/tuner/1.1/default/Frontend.cpp index 6956f30634..243891c996 100644 --- a/tv/tuner/1.1/default/Frontend.cpp +++ b/tv/tuner/1.1/default/Frontend.cpp @@ -196,7 +196,7 @@ Return Frontend::getStatus(const hidl_vec& statusTypes } case FrontendStatusType::MODULATION: { FrontendModulationStatus modulationStatus; - modulationStatus.isdbt(FrontendIsdbtModulation::MOD_16QAM); // value = 1 << 3 + modulationStatus.isdbs(FrontendIsdbsModulation::MOD_BPSK); // value = 1 << 1 status.modulation(modulationStatus); break; } @@ -281,12 +281,14 @@ Return Frontend::getStatusExt1_1(const hidl_vec modulations; V1_1::FrontendModulation modulation; - modulation.isdbt(FrontendIsdbtModulation::MOD_16QAM); // value = 1 << 3 + modulation.isdbs(FrontendIsdbsModulation::MOD_BPSK); // value = 1 << 1 modulations.push_back(modulation); status.modulations(modulations); break; @@ -347,7 +349,7 @@ Return Frontend::getStatusExt1_1(const hidl_vec Tuner::getFrontendInfo(FrontendId frontendId, getFrontendInfo_cb _h FrontendStatusType::PLP_ID, FrontendStatusType::LAYER_ERROR, FrontendStatusType::ATSC3_PLP_INFO, + static_cast(V1_1::FrontendStatusTypeExt1_1::MODULATIONS), + static_cast(V1_1::FrontendStatusTypeExt1_1::ROLL_OFF), }; // assign randomly selected values for testing. info = { -- GitLab From 656b4f29e169d348955785984eb21bf585e30283 Mon Sep 17 00:00:00 2001 From: Kevin Chyn Date: Fri, 5 Feb 2021 16:58:44 -0800 Subject: [PATCH 437/790] Update fingerprint SensorLocation interface for multi-display Allows the implementation to specify location relative to multiple displays (instead of just one), from which the sensor is accessible from. Fixes: 174868353 Test: make -j android.hardware.biometrics.fingerprint-update-api Test: make -j android.hardware.biometrics.fingerprint-service.example Change-Id: I0d1c1d2bdc0ea817656c14b3b79381db994fdd75 --- .../fingerprint/SensorLocation.aidl | 40 ++++++++++++++ .../biometrics/fingerprint/SensorProps.aidl | 5 +- .../fingerprint/SensorLocation.aidl | 54 +++++++++++++++++++ .../biometrics/fingerprint/SensorProps.aidl | 34 +++--------- .../fingerprint/aidl/default/Fingerprint.cpp | 12 +++-- 5 files changed, 110 insertions(+), 35 deletions(-) create mode 100644 biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorLocation.aidl create mode 100644 biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorLocation.aidl diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorLocation.aidl new file mode 100644 index 0000000000..a6e8b4d245 --- /dev/null +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorLocation.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 -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.fingerprint; +@VintfStability +parcelable SensorLocation { + int displayId; + int sensorLocationX; + int sensorLocationY; + int sensorRadius; +} diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl index c3daacd5de..53ac6dd917 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl @@ -35,10 +35,7 @@ package android.hardware.biometrics.fingerprint; parcelable SensorProps { android.hardware.biometrics.common.CommonProps commonProps; android.hardware.biometrics.fingerprint.FingerprintSensorType sensorType; + android.hardware.biometrics.fingerprint.SensorLocation[] sensorLocations; boolean supportsNavigationGestures; - int sensorLocationX; - int sensorLocationY; - int sensorRadius; - int displayId; boolean supportsDetectInteraction; } diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorLocation.aidl new file mode 100644 index 0000000000..62a2e8cdbb --- /dev/null +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorLocation.aidl @@ -0,0 +1,54 @@ +/* + * 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; + +@VintfStability +parcelable SensorLocation { + /** + * The display to which the following measurements are relative to. This must correspond to the + * android.hardware.DisplayManager#getDisplay Android API. + * + * A few examples: + * 1) A capacitive rear fingerprint sensor would specify the display to which it is behind. + * 2) An under-display fingerprint sensor would specify the display on which the sensor is + * located. + * 3) A foldable device would specify multiple locations and have a SensorLocation entry + * for each display from which the sensor is accessible from. + */ + int displayId; + + /** + * The location of the center of the sensor if applicable. For example, sensors of + * FingerprintSensorType::UNDER_DISPLAY_* would report this value as the distance in pixels, + * measured from the left edge of the screen. + */ + int sensorLocationX; + + /** + * The location of the center of the sensor if applicable. For example, sensors of + * FingerprintSensorType::UNDER_DISPLAY_* would report this value as the distance in pixels, + * measured from the top edge of the screen. + */ + int sensorLocationY; + + /** + * The radius of the sensor if applicable. For example, sensors of + * FingerprintSensorType::UNDER_DISPLAY_* would report this value as the radius of the sensor, + * in pixels. + */ + int sensorRadius; +} \ No newline at end of file diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl index afed175bbb..5222f3ea3a 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl @@ -18,6 +18,7 @@ package android.hardware.biometrics.fingerprint; import android.hardware.biometrics.common.CommonProps; import android.hardware.biometrics.fingerprint.FingerprintSensorType; +import android.hardware.biometrics.fingerprint.SensorLocation; @VintfStability parcelable SensorProps { @@ -32,37 +33,16 @@ parcelable SensorProps { FingerprintSensorType sensorType; /** - * Must be set to true for sensors that support "swipe" gestures via - * android.view.KeyEvent#KEYCODE_SYSTEM_NAVIGATION_*. - */ - boolean supportsNavigationGestures; - - /** - * The location of the center of the sensor if applicable. For example, sensors of - * FingerprintSensorType::UNDER_DISPLAY_* would report this value as the distance in pixels, - * measured from the left edge of the screen. + * A list of display-specific locations from where the sensor is usable from. See SensorLocation + * for more details. */ - int sensorLocationX; + SensorLocation[] sensorLocations; /** - * The location of the center of the sensor if applicable. For example, sensors of - * FingerprintSensorType::UNDER_DISPLAY_* would report this value as the distance in pixels, - * measured from the top edge of the screen. - */ - int sensorLocationY; - - /** - * The radius of the sensor if applicable. For example, sensors of - * FingerprintSensorType::UNDER_DISPLAY_* would report this value as the radius of the sensor, - * in pixels. - */ - int sensorRadius; - - /** - * For sensors of FingerprintSensorType::UNDER_DISPLAY_*, this must correspond to the - * android.hardware.DisplayManager#getDisplay Android API. + * Must be set to true for sensors that support "swipe" gestures via + * android.view.KeyEvent#KEYCODE_SYSTEM_NAVIGATION_*. */ - int displayId; + boolean supportsNavigationGestures; /** * Specifies whether or not the implementation supports ISession#detectInteraction. diff --git a/biometrics/fingerprint/aidl/default/Fingerprint.cpp b/biometrics/fingerprint/aidl/default/Fingerprint.cpp index 6eb35d970f..f27e278574 100644 --- a/biometrics/fingerprint/aidl/default/Fingerprint.cpp +++ b/biometrics/fingerprint/aidl/default/Fingerprint.cpp @@ -43,13 +43,17 @@ ndk::ScopedAStatus Fingerprint::getSensorProps(std::vector* return_ kSensorStrength, kMaxEnrollmentsPerUser, hardwareInfos}; + SensorLocation sensorLocation = { + 0 /* displayId */, + 0 /* sensorLocationX */, + 0 /* sensorLocationY */, + 0 /* sensorRadius */ + }; SensorProps props = {commonProps, kSensorType, + {sensorLocation}, kSupportsNavigationGestures, - 0 /* sensorLocationX */, - 0 /* sensorLocationY */, - 0 /* sensorRadius */, - 0 /* displayId */}; + false /* supportsDetectInteraction */}; return_val->push_back(props); return ndk::ScopedAStatus::ok(); } -- GitLab From d4dada833a14cc262f4150f1f83359f7217f8684 Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Tue, 9 Feb 2021 15:35:13 -0800 Subject: [PATCH 438/790] Update the comments for onAuthentication<...> Bug: 179627783 Test: none Change-Id: Ic2d97729b2f124d8791da027c5acb43875ea90a9 --- .../hardware/biometrics/face/ISessionCallback.aidl | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl index 354f4a7e19..2e3cd950f6 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl @@ -17,10 +17,10 @@ package android.hardware.biometrics.face; import android.hardware.biometrics.face.AcquiredInfo; -import android.hardware.biometrics.face.Feature; import android.hardware.biometrics.face.AuthenticationFrame; import android.hardware.biometrics.face.EnrollmentFrame; import android.hardware.biometrics.face.Error; +import android.hardware.biometrics.face.Feature; import android.hardware.biometrics.face.SessionState; import android.hardware.keymaster.HardwareAuthToken; @@ -100,9 +100,8 @@ interface ISessionCallback { /** * This method must only be used to notify the framework during SessionState::AUTHENTICATING. * - * Used to notify the framework upon successful authentication. Note that the authentication - * lifecycle ends when either 1) a face is accepted, or 2) an error occurred. The - * authentication lifecycle does NOT end when a face is rejected. + * Used to notify the framework about a successful authentication. This ends the authentication + * lifecycle. * * @param enrollmentId Face that was accepted. * @param hat If the sensor is configured as SensorStrength::STRONG, a non-null attestation that @@ -115,9 +114,8 @@ interface ISessionCallback { /** * This method must only be used to notify the framework during SessionState::AUTHENTICATING. * - * Used to notify the framework upon rejected attempts. Note that the authentication - * lifecycle ends when either 1) a face is accepted, or 2) an occurred. The - * authentication lifecycle does NOT end when a face is rejected. + * Used to notify the framework about a failed authentication. This ends the authentication + * lifecycle. */ void onAuthenticationFailed(); -- GitLab From 6501ff3b17889c752e02b0a820f1c31a779276af Mon Sep 17 00:00:00 2001 From: Marvin Ramin Date: Tue, 2 Feb 2021 15:41:11 +0100 Subject: [PATCH 439/790] Add TV CEC HAL v1.1 Add new message types and logical address definitions to enums in types. As these enum types are not directly used by framework but rather their integer values the interface does not require changes. Bug: 169121290 Test: make Change-Id: I2cc395733def0b0e42a8717fb94f1759a6fee15c --- tv/cec/1.1/Android.bp | 16 ++++++++ tv/cec/1.1/IHdmiCec.hal | 70 +++++++++++++++++++++++++++++++++ tv/cec/1.1/IHdmiCecCallback.hal | 30 ++++++++++++++ tv/cec/1.1/types.hal | 45 +++++++++++++++++++++ 4 files changed, 161 insertions(+) create mode 100644 tv/cec/1.1/Android.bp create mode 100644 tv/cec/1.1/IHdmiCec.hal create mode 100644 tv/cec/1.1/IHdmiCecCallback.hal create mode 100644 tv/cec/1.1/types.hal diff --git a/tv/cec/1.1/Android.bp b/tv/cec/1.1/Android.bp new file mode 100644 index 0000000000..c2d4e54407 --- /dev/null +++ b/tv/cec/1.1/Android.bp @@ -0,0 +1,16 @@ +// This file is autogenerated by hidl-gen -Landroidbp. + +hidl_interface { + name: "android.hardware.tv.cec@1.1", + root: "android.hardware", + srcs: [ + "types.hal", + "IHdmiCec.hal", + "IHdmiCecCallback.hal", + ], + interfaces: [ + "android.hardware.tv.cec@1.0", + "android.hidl.base@1.0", + ], + gen_java: true, +} diff --git a/tv/cec/1.1/IHdmiCec.hal b/tv/cec/1.1/IHdmiCec.hal new file mode 100644 index 0000000000..fe7bedf195 --- /dev/null +++ b/tv/cec/1.1/IHdmiCec.hal @@ -0,0 +1,70 @@ +/* + * 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.tv.cec@1.1; + +import @1.0::IHdmiCec; +import @1.0::Result; +import @1.0::SendMessageResult; + +import IHdmiCecCallback; + +/** + * HDMI-CEC HAL interface definition. + */ +interface IHdmiCec extends @1.0::IHdmiCec { + /** + * Passes the logical address that must be used in this system. + * + * HAL must use it to configure the hardware so that the CEC commands + * addressed the given logical address can be filtered in. This method must + * be able to be called as many times as necessary in order to support + * multiple logical devices. + * + * @param addr Logical address that must be used in this system. It must be + * in the range of valid logical addresses for the call to succeed. + * @return result Result status of the operation. SUCCESS if successful, + * FAILURE_INVALID_ARGS if the given logical address is invalid, + * FAILURE_BUSY if device or resource is busy + */ + addLogicalAddress_1_1(CecLogicalAddress addr) generates (Result result); + + /** + * Transmits HDMI-CEC message to other HDMI device. + * + * The method must be designed to return in a certain amount of time and not + * hanging forever which may happen if CEC signal line is pulled low for + * some reason. + * + * It must try retransmission at least once as specified in the section '7.1 + * Frame Re-transmissions' of the CEC Spec 1.4b. + * + * @param message CEC message to be sent to other HDMI device. + * @return result Result status of the operation. SUCCESS if successful, + * NACK if the sent message is not acknowledged, + * BUSY if the CEC bus is busy. + */ + sendMessage_1_1(CecMessage message) generates (SendMessageResult result); + + /** + * Sets a callback that HDMI-CEC HAL must later use for incoming CEC + * messages or internal HDMI events. + * + * @param callback Callback object to pass hdmi events to the system. The + * previously registered callback must be replaced with this one. + */ + setCallback_1_1(IHdmiCecCallback callback); +}; diff --git a/tv/cec/1.1/IHdmiCecCallback.hal b/tv/cec/1.1/IHdmiCecCallback.hal new file mode 100644 index 0000000000..3928f186cc --- /dev/null +++ b/tv/cec/1.1/IHdmiCecCallback.hal @@ -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.tv.cec@1.1; + +import @1.0::IHdmiCecCallback; + +/** + * Callbacks from the HAL implementation to notify the system of new events. + */ +interface IHdmiCecCallback extends @1.0::IHdmiCecCallback { + /** + * The callback function that must be called by HAL implementation to notify + * the system of new CEC message arrival. + */ + oneway onCecMessage_1_1(CecMessage message); +}; diff --git a/tv/cec/1.1/types.hal b/tv/cec/1.1/types.hal new file mode 100644 index 0000000000..a117519ed0 --- /dev/null +++ b/tv/cec/1.1/types.hal @@ -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.tv.cec@1.1; + +import @1.0::CecLogicalAddress; +import @1.0::CecMessageType; + +enum CecLogicalAddress : @1.0::CecLogicalAddress { + BACKUP_1 = 12, + BACKUP_2 = 13, +}; + +enum CecMessageType : @1.0::CecMessageType { + GIVE_FEATURES = 0xA5, + REPORT_FEATURES = 0xA6, + REQUEST_CURRENT_LATENCY = 0xA7, + REPORT_CURRENT_LATENCY = 0xA8, +}; + +struct CecMessage { + /** logical address of the initiator */ + CecLogicalAddress initiator; + + /** logical address of destination */ + CecLogicalAddress destination; + + /** + * The maximum size of body is 15 (MaxLength::MESSAGE_BODY) as specified in + * the section 6 of the CEC Spec 1.4b. Overflowed data must be ignored. */ + vec body; +}; -- GitLab From 001be94c10b97a34e6cdedcc1aa5cbe3233691d9 Mon Sep 17 00:00:00 2001 From: Marvin Ramin Date: Wed, 3 Feb 2021 15:49:50 +0100 Subject: [PATCH 440/790] Add CEC HAL v1.1 to compatibility matrix HAL v1.1 introduces new constants in types enums to support the new version of the HDMI CEC specification. The interfaces remain unchanged. Bug: 169121290 Test: make -j Change-Id: I535099c80f56d4c8ab4f5c725b83db33a9666359 --- compatibility_matrices/compatibility_matrix.current.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index 8e44be0e0c..7bf366eecc 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -549,7 +549,7 @@ android.hardware.tv.cec - 1.0 + 1.0-1 IHdmiCec default -- GitLab From a959f364dc8031991fbf47446a961ec1b7bf6caa Mon Sep 17 00:00:00 2001 From: Guillaume Chelfi Date: Wed, 10 Feb 2021 15:00:14 +0100 Subject: [PATCH 441/790] Fix overlooked reference during refactoring The refactoring happened in change Icda34e3eb4d4ccb9f4564e23a61bd71323ca9bb3. Bug: 173570056 Test: atest VtsHalTetheroffloadControlV1_0TargetTest Change-Id: I596fbf9678564f0f38e0c1de32df8903a59334a4 --- .../functional/VtsHalTetheroffloadControlV1_0TargetTest.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tetheroffload/control/1.0/vts/functional/VtsHalTetheroffloadControlV1_0TargetTest.cpp b/tetheroffload/control/1.0/vts/functional/VtsHalTetheroffloadControlV1_0TargetTest.cpp index ad4ef125ce..ea9bcb5d09 100644 --- a/tetheroffload/control/1.0/vts/functional/VtsHalTetheroffloadControlV1_0TargetTest.cpp +++ b/tetheroffload/control/1.0/vts/functional/VtsHalTetheroffloadControlV1_0TargetTest.cpp @@ -469,7 +469,7 @@ TEST_P(OffloadControlTestV1_0_HalStarted, RemoveDownstreamBogusPrefixFails) { } } -GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(OffloadControlHidlTestBase); +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(OffloadControlTestV1_0_HalNotStarted); INSTANTIATE_TEST_CASE_P( PerInstance, OffloadControlTestV1_0_HalNotStarted, testing::Combine(testing::ValuesIn(android::hardware::getAllHalInstanceNames( @@ -478,7 +478,7 @@ INSTANTIATE_TEST_CASE_P( IOffloadControl::descriptor))), android::hardware::PrintInstanceTupleNameToString<>); -GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(OffloadControlHidlTest); +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(OffloadControlTestV1_0_HalStarted); INSTANTIATE_TEST_CASE_P( PerInstance, OffloadControlTestV1_0_HalStarted, testing::Combine(testing::ValuesIn(android::hardware::getAllHalInstanceNames( -- GitLab From 2bdef6aef9050cc3d9938cc8cd63e902e3881a3d Mon Sep 17 00:00:00 2001 From: Anthony Stange Date: Wed, 10 Feb 2021 15:11:38 +0000 Subject: [PATCH 442/790] Tweak ContextHub HAL 1.2 based on feedback To assist in making permissions attribution more robust at the ContextHub service level, tweak the V1.2 interface with the following changes: - Return the full list of supported permissions that all hubs support for attribution. This assists in limiting the number of permissions strings sent between the HAL and service to only those the HAL actually attempts to use. - Add new parameter to handleClientMsg_1_2 that allows nanoapps to denote the list of attributable permissions relating to the contents of the message being sent. This is strictly a subset of the permissions the nanoapp holds and allows a message to be sent without attributing the full nanoapp permission set to the host client when the message may not have been generated from data covered by the permissions. Bug: 166846988 Test: compile Change-Id: I2dc8e1ab4fce2a9ebcc393d07fdffe23dfceb4c2 --- contexthub/1.2/IContexthub.hal | 12 ++++++++++++ contexthub/1.2/IContexthubCallback.hal | 14 +++++++++++--- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/contexthub/1.2/IContexthub.hal b/contexthub/1.2/IContexthub.hal index 3488b7446c..4bb9361bc1 100644 --- a/contexthub/1.2/IContexthub.hal +++ b/contexthub/1.2/IContexthub.hal @@ -16,12 +16,24 @@ package android.hardware.contexthub@1.2; +import @1.0::ContextHub; import @1.0::Result; import @1.1::IContexthub; import @1.1::SettingValue; import IContexthubCallback; interface IContexthub extends @1.1::IContexthub { + /** + * Enumerate all available context hubs on the system. + * + * @return hubs list of hubs on this system. + * @return supportedPermissions list of Android permissions all hubs + * support for nanoapps to enforce host + * endpoints are granted in order to + * communicate with them. + */ + getHubs_1_2() generates (vec hubs, vec supportedPermissions); + /** * Register a callback for the HAL implementation to send asynchronous * messages to the service from a context hub. There can be a maximum of diff --git a/contexthub/1.2/IContexthubCallback.hal b/contexthub/1.2/IContexthubCallback.hal index 0236160305..1a405128b7 100644 --- a/contexthub/1.2/IContexthubCallback.hal +++ b/contexthub/1.2/IContexthubCallback.hal @@ -24,10 +24,18 @@ interface IContexthubCallback extends @1.0::IContexthubCallback { * implementation to allow the HAL to send asynchronous messages back * to the service and registered clients of the ContextHub service. * - * @param msg message that should be delivered to host app clients - * + * @param msg message that should be delivered to host app + * clients + * @param msgContentPerms list of Android permissions that cover the + * contents of the message being sent from the app. + * This is different from the permissions stored + * inside of ContextHubMsg in that these must be a + * subset of those permissions and are meant to + * assist in properly attributing the message + * contents when delivering to a ContextHub service + * client. */ - handleClientMsg_1_2(ContextHubMsg msg); + handleClientMsg_1_2(ContextHubMsg msg, vec msgContentPerms); /** * This callback is passed by the Contexthub service to the HAL -- GitLab From c3c59b343723653ef708fed493ccfb2f375fa27c Mon Sep 17 00:00:00 2001 From: Anthony Stange Date: Wed, 10 Feb 2021 15:42:10 +0000 Subject: [PATCH 443/790] Update ContextHub v1.2 default HAL Updates ContextHub v1.2 default HAL based on latest tweaks to the API. Bug: 166846988 Test: compile Change-Id: I4a723afab834153d5e59694e70fc9282a96e7954 --- contexthub/1.2/default/Contexthub.cpp | 26 +++++++++++++++++++ contexthub/1.2/default/Contexthub.h | 3 +++ .../1.X/utils/IContextHubCallbackWrapper.h | 11 +++++--- 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/contexthub/1.2/default/Contexthub.cpp b/contexthub/1.2/default/Contexthub.cpp index db0c5bc3df..601eccd399 100644 --- a/contexthub/1.2/default/Contexthub.cpp +++ b/contexthub/1.2/default/Contexthub.cpp @@ -23,10 +23,36 @@ namespace contexthub { namespace V1_2 { namespace implementation { +using ::android::hardware::hidl_string; using ::android::hardware::contexthub::V1_0::Result; using ::android::hardware::contexthub::V1_X::implementation::IContextHubCallbackWrapperV1_0; using ::android::hardware::contexthub::V1_X::implementation::IContextHubCallbackWrapperV1_2; +Return Contexthub::getHubs_1_2(getHubs_1_2_cb _hidl_cb) { + ::android::hardware::contexthub::V1_0::ContextHub hub = {}; + hub.name = "Mock Context Hub"; + hub.vendor = "AOSP"; + hub.toolchain = "n/a"; + hub.platformVersion = 1; + hub.toolchainVersion = 1; + hub.hubId = kMockHubId; + hub.peakMips = 1; + hub.peakPowerDrawMw = 1; + hub.maxSupportedMsgLen = 4096; + hub.chrePlatformId = UINT64_C(0x476f6f6754000000); + hub.chreApiMajorVersion = 1; + hub.chreApiMinorVersion = 4; + + // Report a single mock hub + std::vector<::android::hardware::contexthub::V1_0::ContextHub> hubs; + hubs.push_back(hub); + + std::vector hubPermissionList; + + _hidl_cb(hubs, hubPermissionList); + return Void(); +} + Return Contexthub::registerCallback(uint32_t hubId, const sp& cb) { if (hubId == kMockHubId) { diff --git a/contexthub/1.2/default/Contexthub.h b/contexthub/1.2/default/Contexthub.h index 8b89824d6b..32b862dc3f 100644 --- a/contexthub/1.2/default/Contexthub.h +++ b/contexthub/1.2/default/Contexthub.h @@ -35,6 +35,7 @@ class Contexthub using Result = ::android::hardware::contexthub::V1_0::Result; using SettingValue = ::android::hardware::contexthub::V1_1::SettingValue; using SettingV1_1 = ::android::hardware::contexthub::V1_1::Setting; + using getHubs_1_2_cb = ::android::hardware::contexthub::V1_2::IContexthub::getHubs_1_2_cb; public: // Methods from V1_0::IContexthub @@ -47,6 +48,8 @@ class Contexthub Return onSettingChanged(SettingV1_1 setting, SettingValue newValue) override; // Methods from V1_2::IContexthub + Return getHubs_1_2(getHubs_1_2_cb _hidl_cb) override; + Return onSettingChanged_1_2(Setting setting, SettingValue newValue) override; Return registerCallback_1_2(uint32_t hubId, diff --git a/contexthub/common/default/1.X/utils/IContextHubCallbackWrapper.h b/contexthub/common/default/1.X/utils/IContextHubCallbackWrapper.h index df78438750..d8cc37b5f2 100644 --- a/contexthub/common/default/1.X/utils/IContextHubCallbackWrapper.h +++ b/contexthub/common/default/1.X/utils/IContextHubCallbackWrapper.h @@ -54,7 +54,8 @@ inline hidl_vec convertToOldAppInfo(hidl_vec */ class IContextHubCallbackWrapperBase : public VirtualLightRefBase { public: - virtual Return handleClientMsg(V1_2::ContextHubMsg msg) = 0; + virtual Return handleClientMsg(V1_2::ContextHubMsg msg, + hidl_vec msgContentPerms) = 0; virtual Return handleTxnResult(uint32_t txnId, V1_0::TransactionResult result) = 0; @@ -70,7 +71,8 @@ class ContextHubCallbackWrapper : public IContextHubCallbackWrapperBase { public: ContextHubCallbackWrapper(sp callback) : mCallback(callback){}; - virtual Return handleClientMsg(V1_2::ContextHubMsg msg) override { + virtual Return handleClientMsg(V1_2::ContextHubMsg msg, + hidl_vec /* msgContentPerms */) override { return mCallback->handleClientMsg(convertToOldMsg(msg)); } @@ -105,8 +107,9 @@ class IContextHubCallbackWrapperV1_2 : public ContextHubCallbackWrapper callback) : ContextHubCallbackWrapper(callback){}; - Return handleClientMsg(V1_2::ContextHubMsg msg) override { - return mCallback->handleClientMsg_1_2(msg); + Return handleClientMsg(V1_2::ContextHubMsg msg, + hidl_vec msgContentPerms) override { + return mCallback->handleClientMsg_1_2(msg, msgContentPerms); } Return handleAppsInfo(hidl_vec appInfo) override { -- GitLab From 146f6c8f1dd935d36fedabc19fe6b90080d71b24 Mon Sep 17 00:00:00 2001 From: Kevin Chyn Date: Wed, 10 Feb 2021 11:32:35 -0800 Subject: [PATCH 444/790] Add logs to default biometric HALs Bug: 179856730 Test: Presubmit Change-Id: I6ebf88b36e075586d2596af7a82b4ab8cf24ad22 --- biometrics/face/aidl/default/Session.cpp | 13 +++++++++++++ biometrics/fingerprint/aidl/default/Session.cpp | 14 ++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/biometrics/face/aidl/default/Session.cpp b/biometrics/face/aidl/default/Session.cpp index 63d1721314..bd5a0625f9 100644 --- a/biometrics/face/aidl/default/Session.cpp +++ b/biometrics/face/aidl/default/Session.cpp @@ -15,6 +15,7 @@ */ #include +#include #include "Session.h" @@ -37,6 +38,7 @@ class CancellationSignal : public common::BnCancellationSignal { Session::Session(std::shared_ptr cb) : cb_(std::move(cb)) {} ndk::ScopedAStatus Session::generateChallenge(int32_t /*cookie*/, int32_t /*timeoutSec*/) { + LOG(INFO) << "generateChallenge"; if (cb_) { cb_->onStateChanged(0, SessionState::GENERATING_CHALLENGE); cb_->onChallengeGenerated(0); @@ -46,6 +48,7 @@ ndk::ScopedAStatus Session::generateChallenge(int32_t /*cookie*/, int32_t /*time } ndk::ScopedAStatus Session::revokeChallenge(int32_t /*cookie*/, int64_t challenge) { + LOG(INFO) << "revokeChallenge"; if (cb_) { cb_->onStateChanged(0, SessionState::REVOKING_CHALLENGE); cb_->onChallengeRevoked(challenge); @@ -59,11 +62,13 @@ ndk::ScopedAStatus Session::enroll( EnrollmentType /*enrollmentType*/, const std::vector& /*features*/, const NativeHandle& /*previewSurface*/, std::shared_ptr* /*return_val*/) { + LOG(INFO) << "enroll"; return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus Session::authenticate(int32_t /*cookie*/, int64_t /*keystoreOperationId*/, std::shared_ptr* return_val) { + LOG(INFO) << "authenticate"; if (cb_) { cb_->onStateChanged(0, SessionState::AUTHENTICATING); } @@ -73,10 +78,12 @@ ndk::ScopedAStatus Session::authenticate(int32_t /*cookie*/, int64_t /*keystoreO ndk::ScopedAStatus Session::detectInteraction( int32_t /*cookie*/, std::shared_ptr* /*return_val*/) { + LOG(INFO) << "detectInteraction"; return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus Session::enumerateEnrollments(int32_t /*cookie*/) { + LOG(INFO) << "enumerateEnrollments"; if (cb_) { cb_->onStateChanged(0, SessionState::ENUMERATING_ENROLLMENTS); cb_->onEnrollmentsEnumerated(std::vector()); @@ -87,6 +94,7 @@ ndk::ScopedAStatus Session::enumerateEnrollments(int32_t /*cookie*/) { ndk::ScopedAStatus Session::removeEnrollments(int32_t /*cookie*/, const std::vector& /*enrollmentIds*/) { + LOG(INFO) << "removeEnrollments"; if (cb_) { cb_->onStateChanged(0, SessionState::REMOVING_ENROLLMENTS); cb_->onEnrollmentsRemoved(std::vector()); @@ -96,6 +104,7 @@ ndk::ScopedAStatus Session::removeEnrollments(int32_t /*cookie*/, } ndk::ScopedAStatus Session::getFeatures(int32_t /*cookie*/, int32_t /*enrollmentId*/) { + LOG(INFO) << "getFeatures"; return ndk::ScopedAStatus::ok(); } @@ -103,10 +112,12 @@ ndk::ScopedAStatus Session::setFeature(int32_t /*cookie*/, const keymaster::HardwareAuthToken& /*hat*/, int32_t /*enrollmentId*/, Feature /*feature*/, bool /*enabled*/) { + LOG(INFO) << "setFeature"; return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus Session::getAuthenticatorId(int32_t /*cookie*/) { + LOG(INFO) << "getAuthenticatorId"; if (cb_) { cb_->onStateChanged(0, SessionState::GETTING_AUTHENTICATOR_ID); cb_->onAuthenticatorIdRetrieved(0 /* authenticatorId */); @@ -116,11 +127,13 @@ ndk::ScopedAStatus Session::getAuthenticatorId(int32_t /*cookie*/) { } ndk::ScopedAStatus Session::invalidateAuthenticatorId(int32_t /*cookie*/) { + LOG(INFO) << "invalidateAuthenticatorId"; return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus Session::resetLockout(int32_t /*cookie*/, const keymaster::HardwareAuthToken& /*hat*/) { + LOG(INFO) << "resetLockout"; if (cb_) { cb_->onStateChanged(0, SessionState::RESETTING_LOCKOUT); cb_->onLockoutCleared(); diff --git a/biometrics/fingerprint/aidl/default/Session.cpp b/biometrics/fingerprint/aidl/default/Session.cpp index bf08203707..844622101e 100644 --- a/biometrics/fingerprint/aidl/default/Session.cpp +++ b/biometrics/fingerprint/aidl/default/Session.cpp @@ -15,6 +15,7 @@ */ #include +#include #include "Session.h" @@ -28,20 +29,24 @@ class CancellationSignal : public common::BnCancellationSignal { Session::Session(std::shared_ptr cb) : cb_(std::move(cb)) {} ndk::ScopedAStatus Session::generateChallenge(int32_t /*cookie*/, int32_t /*timeoutSec*/) { + LOG(INFO) << "generateChallenge"; return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus Session::revokeChallenge(int32_t /*cookie*/, int64_t /*challenge*/) { + LOG(INFO) << "revokeChallenge"; return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus Session::enroll(int32_t /*cookie*/, const keymaster::HardwareAuthToken& /*hat*/, std::shared_ptr* /*return_val*/) { + LOG(INFO) << "enroll"; return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus Session::authenticate(int32_t /*cookie*/, int64_t /*keystoreOperationId*/, std::shared_ptr* return_val) { + LOG(INFO) << "authenticate"; if (cb_) { cb_->onStateChanged(0, SessionState::AUTHENTICATING); } @@ -51,10 +56,12 @@ ndk::ScopedAStatus Session::authenticate(int32_t /*cookie*/, int64_t /*keystoreO ndk::ScopedAStatus Session::detectInteraction( int32_t /*cookie*/, std::shared_ptr* /*return_val*/) { + LOG(INFO) << "detectInteraction"; return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus Session::enumerateEnrollments(int32_t /*cookie*/) { + LOG(INFO) << "enumerateEnrollments"; if (cb_) { cb_->onStateChanged(0, SessionState::ENUMERATING_ENROLLMENTS); cb_->onEnrollmentsEnumerated(std::vector()); @@ -64,6 +71,7 @@ ndk::ScopedAStatus Session::enumerateEnrollments(int32_t /*cookie*/) { ndk::ScopedAStatus Session::removeEnrollments(int32_t /*cookie*/, const std::vector& /*enrollmentIds*/) { + LOG(INFO) << "removeEnrollments"; if (cb_) { cb_->onStateChanged(0, SessionState::REMOVING_ENROLLMENTS); cb_->onEnrollmentsRemoved(std::vector()); @@ -72,6 +80,7 @@ ndk::ScopedAStatus Session::removeEnrollments(int32_t /*cookie*/, } ndk::ScopedAStatus Session::getAuthenticatorId(int32_t /*cookie*/) { + LOG(INFO) << "getAuthenticatorId"; if (cb_) { cb_->onStateChanged(0, SessionState::GETTING_AUTHENTICATOR_ID); cb_->onAuthenticatorIdRetrieved(0 /* authenticatorId */); @@ -80,24 +89,29 @@ ndk::ScopedAStatus Session::getAuthenticatorId(int32_t /*cookie*/) { } ndk::ScopedAStatus Session::invalidateAuthenticatorId(int32_t /*cookie*/) { + LOG(INFO) << "invalidateAuthenticatorId"; return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus Session::resetLockout(int32_t /*cookie*/, const keymaster::HardwareAuthToken& /*hat*/) { + LOG(INFO) << "resetLockout"; return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus Session::onPointerDown(int32_t /*pointerId*/, int32_t /*x*/, int32_t /*y*/, float /*minor*/, float /*major*/) { + LOG(INFO) << "onPointerDown"; return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus Session::onPointerUp(int32_t /*pointerId*/) { + LOG(INFO) << "onPointerUp"; return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus Session::onUiReady() { + LOG(INFO) << "onUiReady"; return ndk::ScopedAStatus::ok(); } } // namespace aidl::android::hardware::biometrics::fingerprint -- GitLab From b8fe666c7f47aad6bd9769f7d47b109f55bf6f83 Mon Sep 17 00:00:00 2001 From: Marvin Ramin Date: Mon, 8 Feb 2021 11:33:33 +0100 Subject: [PATCH 445/790] Add default implementation for tv.cec@1.1 Default implementation based on tv.cec@1.0. Implements the new 1.1 interfaces returning default values and communicating via mocked inputs. Bug: 169121290 Test: manual; VTS in following changes Change-Id: I1642e340e9064ab37670f1998421e3190085d98b --- tv/cec/1.1/default/Android.bp | 23 ++ tv/cec/1.1/default/HdmiCecMock.cpp | 371 ++++++++++++++++++ tv/cec/1.1/default/HdmiCecMock.h | 125 ++++++ .../android.hardware.tv.cec@1.1-service.rc | 6 + .../android.hardware.tv.cec@1.1-service.xml | 11 + tv/cec/1.1/default/serviceMock.cpp | 40 ++ 6 files changed, 576 insertions(+) create mode 100644 tv/cec/1.1/default/Android.bp create mode 100644 tv/cec/1.1/default/HdmiCecMock.cpp create mode 100644 tv/cec/1.1/default/HdmiCecMock.h create mode 100644 tv/cec/1.1/default/android.hardware.tv.cec@1.1-service.rc create mode 100644 tv/cec/1.1/default/android.hardware.tv.cec@1.1-service.xml create mode 100644 tv/cec/1.1/default/serviceMock.cpp diff --git a/tv/cec/1.1/default/Android.bp b/tv/cec/1.1/default/Android.bp new file mode 100644 index 0000000000..e0dff0d033 --- /dev/null +++ b/tv/cec/1.1/default/Android.bp @@ -0,0 +1,23 @@ +cc_binary { + name: "android.hardware.tv.cec@1.1-service", + defaults: ["hidl_defaults"], + vintf_fragments: ["android.hardware.tv.cec@1.1-service.xml"], + relative_install_path: "hw", + vendor: true, + init_rc: ["android.hardware.tv.cec@1.1-service.rc"], + srcs: [ + "serviceMock.cpp", + "HdmiCecMock.cpp", + ], + + shared_libs: [ + "liblog", + "libcutils", + "libbase", + "libutils", + "libhardware", + "libhidlbase", + "android.hardware.tv.cec@1.0", + "android.hardware.tv.cec@1.1", + ], +} diff --git a/tv/cec/1.1/default/HdmiCecMock.cpp b/tv/cec/1.1/default/HdmiCecMock.cpp new file mode 100644 index 0000000000..f65bab9865 --- /dev/null +++ b/tv/cec/1.1/default/HdmiCecMock.cpp @@ -0,0 +1,371 @@ +/* + * 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 "android.hardware.tv.cec@1.1" +#include +#include + +#include +#include +#include "HdmiCecMock.h" + +namespace android { +namespace hardware { +namespace tv { +namespace cec { +namespace V1_1 { +namespace implementation { + +class WrappedCallback : public ::android::hardware::tv::cec::V1_1::IHdmiCecCallback { + public: + WrappedCallback(sp<::android::hardware::tv::cec::V1_0::IHdmiCecCallback> callback) { + mCallback = callback; + } + + Return onCecMessage(const ::android::hardware::tv::cec::V1_0::CecMessage& message) { + mCallback->onCecMessage(message); + return Void(); + } + Return onCecMessage_1_1(const ::android::hardware::tv::cec::V1_1::CecMessage& message) { + ::android::hardware::tv::cec::V1_0::CecMessage cecMessage; + cecMessage.initiator = + ::android::hardware::tv::cec::V1_0::CecLogicalAddress(message.initiator); + cecMessage.destination = + ::android::hardware::tv::cec::V1_0::CecLogicalAddress(message.destination); + cecMessage.body = message.body; + mCallback->onCecMessage(cecMessage); + return Void(); + } + Return onHotplugEvent(const ::android::hardware::tv::cec::V1_0::HotplugEvent& event) { + mCallback->onHotplugEvent(event); + return Void(); + } + + private: + sp<::android::hardware::tv::cec::V1_0::IHdmiCecCallback> mCallback; +}; + +/* + * (*set_option)() passes flags controlling the way HDMI-CEC service works down + * to HAL implementation. Those flags will be used in case the feature needs + * update in HAL itself, firmware or microcontroller. + */ +void HdmiCecMock::cec_set_option(int flag, int value) { + // maintain options and set them accordingly + switch (flag) { + case HDMI_OPTION_WAKEUP: + mOptionWakeUp = value; + break; + case HDMI_OPTION_ENABLE_CEC: + mOptionEnableCec = value; + break; + case HDMI_OPTION_SYSTEM_CEC_CONTROL: + mOptionSystemCecControl = value; + break; + case HDMI_OPTION_SET_LANG: + mOptionLanguage = value; + break; + } +} + +// Methods from ::android::hardware::tv::cec::V1_0::IHdmiCec follow. +Return HdmiCecMock::addLogicalAddress(CecLogicalAddress addr) { + return addLogicalAddress_1_1(::android::hardware::tv::cec::V1_1::CecLogicalAddress(addr)); +} + +Return HdmiCecMock::clearLogicalAddress() { + // remove logical address from the list + mLogicalAddresses = {}; + return Void(); +} + +Return HdmiCecMock::getPhysicalAddress(getPhysicalAddress_cb _hidl_cb) { + // maintain a physical address and return it + // default 0xFFFF, update on hotplug event + _hidl_cb(Result::SUCCESS, mPhysicalAddress); + return Void(); +} + +Return HdmiCecMock::sendMessage(const CecMessage& message) { + ::android::hardware::tv::cec::V1_1::CecMessage cecMessage; + cecMessage.initiator = ::android::hardware::tv::cec::V1_1::CecLogicalAddress(message.initiator); + cecMessage.destination = + ::android::hardware::tv::cec::V1_1::CecLogicalAddress(message.destination); + cecMessage.body = message.body; + return sendMessage_1_1(cecMessage); +} + +Return HdmiCecMock::setCallback(const sp& callback) { + return setCallback_1_1(new WrappedCallback(callback)); +} + +Return HdmiCecMock::getCecVersion() { + // maintain a cec version and return it + return mCecVersion; +} + +Return HdmiCecMock::getVendorId() { + return mCecVendorId; +} + +Return HdmiCecMock::getPortInfo(getPortInfo_cb _hidl_cb) { + // TODO ready port info from device specific config + _hidl_cb(mPortInfo); + return Void(); +} + +Return HdmiCecMock::setOption(OptionKey key, bool value) { + cec_set_option(static_cast(key), value ? 1 : 0); + return Void(); +} + +Return HdmiCecMock::setLanguage(const hidl_string& language) { + if (language.size() != 3) { + LOG(ERROR) << "Wrong language code: expected 3 letters, but it was " << language.size() + << "."; + return Void(); + } + // TODO validate if language is a valid language code + const char* languageStr = language.c_str(); + int convertedLanguage = ((languageStr[0] & 0xFF) << 16) | ((languageStr[1] & 0xFF) << 8) | + (languageStr[2] & 0xFF); + cec_set_option(HDMI_OPTION_SET_LANG, convertedLanguage); + return Void(); +} + +Return HdmiCecMock::enableAudioReturnChannel(int32_t portId __unused, bool enable __unused) { + // Maintain ARC status + return Void(); +} + +Return HdmiCecMock::isConnected(int32_t portId) { + // maintain port connection status and update on hotplug event + if (portId < mTotalPorts && portId >= 0) { + return mPortConnectionStatus[portId]; + } + return false; +} + +// Methods from ::android::hardware::tv::cec::V1_1::IHdmiCec follow. +Return HdmiCecMock::addLogicalAddress_1_1( + ::android::hardware::tv::cec::V1_1::CecLogicalAddress addr) { + // have a list to maintain logical addresses + int size = mLogicalAddresses.size(); + mLogicalAddresses.resize(size + 1); + mLogicalAddresses[size + 1] = addr; + return Result::SUCCESS; +} + +Return HdmiCecMock::sendMessage_1_1( + const ::android::hardware::tv::cec::V1_1::CecMessage& message) { + if (message.body.size() == 0) { + return SendMessageResult::NACK; + } + sendMessageToFifo(message); + return SendMessageResult::SUCCESS; +} + +Return HdmiCecMock::setCallback_1_1( + const sp<::android::hardware::tv::cec::V1_1::IHdmiCecCallback>& callback) { + if (mCallback != nullptr) { + mCallback = nullptr; + } + + if (callback != nullptr) { + mCallback = callback; + mCallback->linkToDeath(this, 0 /*cookie*/); + + mInputFile = open(CEC_MSG_IN_FIFO, O_RDWR); + mOutputFile = open(CEC_MSG_OUT_FIFO, O_RDWR); + pthread_create(&mThreadId, NULL, __threadLoop, this); + pthread_setname_np(mThreadId, "hdmi_cec_loop"); + } + return Void(); +} + +void* HdmiCecMock::__threadLoop(void* user) { + HdmiCecMock* const self = static_cast(user); + self->threadLoop(); + return 0; +} + +int HdmiCecMock::readMessageFromFifo(unsigned char* buf, int msgCount) { + if (msgCount <= 0 || !buf) { + return 0; + } + + int ret = -1; + /* maybe blocked at driver */ + ret = read(mInputFile, buf, msgCount); + if (ret < 0) { + ALOGE("[halimp] read :%s failed, ret:%d\n", CEC_MSG_IN_FIFO, ret); + return -1; + } + + return ret; +} + +int HdmiCecMock::sendMessageToFifo(const ::android::hardware::tv::cec::V1_1::CecMessage& message) { + unsigned char msgBuf[CEC_MESSAGE_BODY_MAX_LENGTH]; + int ret = -1; + + memset(msgBuf, 0, sizeof(msgBuf)); + msgBuf[0] = ((static_cast(message.initiator) & 0xf) << 4) | + (static_cast(message.destination) & 0xf); + + size_t length = std::min(static_cast(message.body.size()), + static_cast(MaxLength::MESSAGE_BODY)); + for (size_t i = 0; i < length; ++i) { + msgBuf[i + 1] = static_cast(message.body[i]); + } + + // open the output pipe for writing outgoing cec message + mOutputFile = open(CEC_MSG_OUT_FIFO, O_WRONLY); + if (mOutputFile < 0) { + ALOGD("[halimp] file open failed for writing"); + return -1; + } + + // write message into the output pipe + ret = write(mOutputFile, msgBuf, length + 1); + close(mOutputFile); + if (ret < 0) { + ALOGE("[halimp] write :%s failed, ret:%d\n", CEC_MSG_OUT_FIFO, ret); + return -1; + } + return ret; +} + +void HdmiCecMock::printCecMsgBuf(const char* msg_buf, int len) { + char buf[64] = {}; + int i, size = 0; + memset(buf, 0, sizeof(buf)); + for (i = 0; i < len; i++) { + size += sprintf(buf + size, " %02x", msg_buf[i]); + } + ALOGD("[halimp] %s, msg:%s", __FUNCTION__, buf); +} + +void HdmiCecMock::handleHotplugMessage(unsigned char* msgBuf) { + HotplugEvent hotplugEvent{.connected = ((msgBuf[3]) & 0xf) > 0, + .portId = static_cast(msgBuf[0] & 0xf)}; + + if (hotplugEvent.portId >= mPortInfo.size()) { + ALOGD("[halimp] ignore hot plug message, id %x does not exist", hotplugEvent.portId); + return; + } + + ALOGD("[halimp] hot plug port id %x, is connected %x", (msgBuf[0] & 0xf), (msgBuf[3] & 0xf)); + if (mPortInfo[hotplugEvent.portId].type == HdmiPortType::OUTPUT) { + mPhysicalAddress = + ((hotplugEvent.connected == 0) ? 0xffff : ((msgBuf[1] << 8) | (msgBuf[2]))); + mPortInfo[hotplugEvent.portId].physicalAddress = mPhysicalAddress; + ALOGD("[halimp] hot plug physical address %x", mPhysicalAddress); + } + + // todo update connection status + + if (mCallback != nullptr) { + mCallback->onHotplugEvent(hotplugEvent); + } +} + +void HdmiCecMock::handleCecMessage(unsigned char* msgBuf, int megSize) { + ::android::hardware::tv::cec::V1_1::CecMessage message; + size_t length = std::min(static_cast(megSize - 1), + static_cast(MaxLength::MESSAGE_BODY)); + message.body.resize(length); + + for (size_t i = 0; i < length; ++i) { + message.body[i] = static_cast(msgBuf[i + 1]); + ALOGD("[halimp] msg body %x", message.body[i]); + } + + message.initiator = static_cast<::android::hardware::tv::cec::V1_1::CecLogicalAddress>( + (msgBuf[0] >> 4) & 0xf); + ALOGD("[halimp] msg init %x", message.initiator); + message.destination = static_cast<::android::hardware::tv::cec::V1_1::CecLogicalAddress>( + (msgBuf[0] >> 0) & 0xf); + ALOGD("[halimp] msg dest %x", message.destination); + + // messageValidateAndHandle(&event); + + if (mCallback != nullptr) { + mCallback->onCecMessage_1_1(message); + } +} + +void HdmiCecMock::threadLoop() { + ALOGD("[halimp] threadLoop start."); + unsigned char msgBuf[CEC_MESSAGE_BODY_MAX_LENGTH]; + int r = -1; + + // open the input pipe + while (mInputFile < 0) { + usleep(1000 * 1000); + mInputFile = open(CEC_MSG_IN_FIFO, O_RDONLY); + } + ALOGD("[halimp] file open ok, fd = %d.", mInputFile); + + while (mCecThreadRun) { + if (!mOptionSystemCecControl) { + usleep(1000 * 1000); + continue; + } + + memset(msgBuf, 0, sizeof(msgBuf)); + // try to get a message from dev. + // echo -n -e '\x04\x83' >> /dev/cec + r = readMessageFromFifo(msgBuf, CEC_MESSAGE_BODY_MAX_LENGTH); + if (r <= 1) { + // ignore received ping messages + continue; + } + + printCecMsgBuf((const char*)msgBuf, r); + + if (((msgBuf[0] >> 4) & 0xf) == 0xf) { + // the message is a hotplug event + handleHotplugMessage(msgBuf); + continue; + } + + handleCecMessage(msgBuf, r); + } + + ALOGD("[halimp] thread end."); + // mCecDevice.mExited = true; +} + +HdmiCecMock::HdmiCecMock() { + ALOGE("[halimp] Opening a virtual HAL for testing and virtual machine."); + mCallback = nullptr; + mPortInfo.resize(mTotalPorts); + mPortConnectionStatus.resize(mTotalPorts); + mPortInfo[0] = {.type = HdmiPortType::OUTPUT, + .portId = static_cast(1), + .cecSupported = true, + .arcSupported = false, + .physicalAddress = mPhysicalAddress}; + mPortConnectionStatus[0] = false; +} + +} // namespace implementation +} // namespace V1_1 +} // namespace cec +} // namespace tv +} // namespace hardware +} // namespace android \ No newline at end of file diff --git a/tv/cec/1.1/default/HdmiCecMock.h b/tv/cec/1.1/default/HdmiCecMock.h new file mode 100644 index 0000000000..0205f8d95f --- /dev/null +++ b/tv/cec/1.1/default/HdmiCecMock.h @@ -0,0 +1,125 @@ +/* + * 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 +#include +#include +#include + +using namespace std; + +namespace android { +namespace hardware { +namespace tv { +namespace cec { +namespace V1_1 { +namespace implementation { + +using ::android::sp; +using ::android::hardware::hidl_string; +using ::android::hardware::hidl_vec; +using ::android::hardware::Return; +using ::android::hardware::Void; +using ::android::hardware::tv::cec::V1_0::CecLogicalAddress; +using ::android::hardware::tv::cec::V1_0::CecMessage; +using ::android::hardware::tv::cec::V1_0::HdmiPortInfo; +using ::android::hardware::tv::cec::V1_0::HdmiPortType; +using ::android::hardware::tv::cec::V1_0::HotplugEvent; +using ::android::hardware::tv::cec::V1_0::IHdmiCecCallback; +using ::android::hardware::tv::cec::V1_0::MaxLength; +using ::android::hardware::tv::cec::V1_0::OptionKey; +using ::android::hardware::tv::cec::V1_0::Result; +using ::android::hardware::tv::cec::V1_0::SendMessageResult; +using ::android::hardware::tv::cec::V1_1::IHdmiCec; + +#define CEC_MSG_IN_FIFO "/dev/cec_in_pipe" +#define CEC_MSG_OUT_FIFO "/dev/cec_out_pipe" + +struct HdmiCecMock : public IHdmiCec, public hidl_death_recipient { + HdmiCecMock(); + // Methods from ::android::hardware::tv::cec::V1_0::IHdmiCec follow. + Return addLogicalAddress(CecLogicalAddress addr) override; + Return clearLogicalAddress() override; + Return getPhysicalAddress(getPhysicalAddress_cb _hidl_cb) override; + Return sendMessage(const CecMessage& message) override; + Return setCallback( + const sp<::android::hardware::tv::cec::V1_0::IHdmiCecCallback>& callback) override; + Return getCecVersion() override; + Return getVendorId() override; + Return getPortInfo(getPortInfo_cb _hidl_cb) override; + Return setOption(OptionKey key, bool value) override; + Return setLanguage(const hidl_string& language) override; + Return enableAudioReturnChannel(int32_t portId, bool enable) override; + Return isConnected(int32_t portId) override; + + // Methods from ::android::hardware::tv::cec::V1_1::IHdmiCec follow. + Return addLogicalAddress_1_1( + ::android::hardware::tv::cec::V1_1::CecLogicalAddress addr) override; + Return sendMessage_1_1( + const ::android::hardware::tv::cec::V1_1::CecMessage& message) override; + Return setCallback_1_1( + const sp<::android::hardware::tv::cec::V1_1::IHdmiCecCallback>& callback) override; + + virtual void serviceDied(uint64_t /*cookie*/, + const wp<::android::hidl::base::V1_0::IBase>& /*who*/) { + setCallback(nullptr); + } + + void cec_set_option(int flag, int value); + void printCecMsgBuf(const char* msg_buf, int len); + + private: + static void* __threadLoop(void* data); + void threadLoop(); + int readMessageFromFifo(unsigned char* buf, int msgCount); + int sendMessageToFifo(const ::android::hardware::tv::cec::V1_1::CecMessage& message); + void handleHotplugMessage(unsigned char* msgBuf); + void handleCecMessage(unsigned char* msgBuf, int length); + + private: + sp<::android::hardware::tv::cec::V1_1::IHdmiCecCallback> mCallback; + + // Variables for the virtual cec hal impl + uint16_t mPhysicalAddress = 0xFFFF; + vector<::android::hardware::tv::cec::V1_1::CecLogicalAddress> mLogicalAddresses; + int32_t mCecVersion = 0x06; + uint32_t mCecVendorId = 0x01; + + // Port configuration + int mTotalPorts = 1; + hidl_vec mPortInfo; + hidl_vec mPortConnectionStatus; + + // CEC Option value + int mOptionWakeUp = 0; + int mOptionEnableCec = 0; + int mOptionSystemCecControl = 0; + int mOptionLanguage = 0; + + // Testing variables + // Input file descriptor + int mInputFile; + // Output file descriptor + int mOutputFile; + bool mCecThreadRun = true; + pthread_t mThreadId = 0; +}; +} // namespace implementation +} // namespace V1_1 +} // namespace cec +} // namespace tv +} // namespace hardware +} // namespace android \ No newline at end of file diff --git a/tv/cec/1.1/default/android.hardware.tv.cec@1.1-service.rc b/tv/cec/1.1/default/android.hardware.tv.cec@1.1-service.rc new file mode 100644 index 0000000000..e150c91cc7 --- /dev/null +++ b/tv/cec/1.1/default/android.hardware.tv.cec@1.1-service.rc @@ -0,0 +1,6 @@ +service vendor.cec-hal-1-1 /vendor/bin/hw/android.hardware.tv.cec@1.1-service + interface android.hardware.tv.cec@1.0::IHdmiCec default + interface android.hardware.tv.cec@1.1::IHdmiCec default + class hal + user system + group system \ No newline at end of file diff --git a/tv/cec/1.1/default/android.hardware.tv.cec@1.1-service.xml b/tv/cec/1.1/default/android.hardware.tv.cec@1.1-service.xml new file mode 100644 index 0000000000..492369e67f --- /dev/null +++ b/tv/cec/1.1/default/android.hardware.tv.cec@1.1-service.xml @@ -0,0 +1,11 @@ + + + android.hardware.tv.cec + hwbinder + 1.1 + + IHdmiCec + default + + + diff --git a/tv/cec/1.1/default/serviceMock.cpp b/tv/cec/1.1/default/serviceMock.cpp new file mode 100644 index 0000000000..72fc311ddc --- /dev/null +++ b/tv/cec/1.1/default/serviceMock.cpp @@ -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. + */ + +#define LOG_TAG "android.hardware.tv.cec@1.1-service-shim" + +#include +#include +#include "HdmiCecMock.h" + +using android::hardware::configureRpcThreadpool; +using android::hardware::joinRpcThreadpool; +using android::hardware::tv::cec::V1_1::IHdmiCec; +using android::hardware::tv::cec::V1_1::implementation::HdmiCecMock; + +int main() { + configureRpcThreadpool(8, true /* callerWillJoin */); + + // Setup hwbinder service + android::sp service = new HdmiCecMock(); + android::status_t status; + status = service->registerAsService(); + LOG_ALWAYS_FATAL_IF(status != android::OK, "Error while registering mock cec service: %d", + status); + + joinRpcThreadpool(); + return 0; +} -- GitLab From ad7fb5ce9dafa0ff40fcaffea7c43ac1508e6123 Mon Sep 17 00:00:00 2001 From: Marvin Ramin Date: Mon, 8 Feb 2021 13:08:58 +0100 Subject: [PATCH 446/790] Add VTS for tv.cec@1.1 Add VTS tests for tv.cec. Verify return values of relevant methods and updated 1.1 methods. Bug: 169121290 Test: vts-tradefed Change-Id: I6b7129f233171daf9cac0757e500c341d1564363 --- tv/cec/1.1/vts/functional/Android.bp | 14 ++ .../functional/VtsHalTvCecV1_1TargetTest.cpp | 199 ++++++++++++++++++ 2 files changed, 213 insertions(+) create mode 100644 tv/cec/1.1/vts/functional/Android.bp create mode 100644 tv/cec/1.1/vts/functional/VtsHalTvCecV1_1TargetTest.cpp diff --git a/tv/cec/1.1/vts/functional/Android.bp b/tv/cec/1.1/vts/functional/Android.bp new file mode 100644 index 0000000000..5fc7093fa8 --- /dev/null +++ b/tv/cec/1.1/vts/functional/Android.bp @@ -0,0 +1,14 @@ +cc_test { + name: "VtsHalTvCecV1_1TargetTest", + defaults: ["VtsHalTargetTestDefaults"], + srcs: ["VtsHalTvCecV1_1TargetTest.cpp"], + static_libs: [ + "android.hardware.tv.cec@1.1", + "android.hardware.tv.cec@1.0", + ], + test_suites: [ + "general-tests", + "vts", + ], + disable_framework: true, +} diff --git a/tv/cec/1.1/vts/functional/VtsHalTvCecV1_1TargetTest.cpp b/tv/cec/1.1/vts/functional/VtsHalTvCecV1_1TargetTest.cpp new file mode 100644 index 0000000000..1eb4643565 --- /dev/null +++ b/tv/cec/1.1/vts/functional/VtsHalTvCecV1_1TargetTest.cpp @@ -0,0 +1,199 @@ +/* + * 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 "HdmiCec_hal_test" +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +using ::android::sp; +using ::android::hardware::hidl_death_recipient; +using ::android::hardware::hidl_vec; +using ::android::hardware::Return; +using ::android::hardware::Void; +using ::android::hardware::tv::cec::V1_0::CecDeviceType; +using ::android::hardware::tv::cec::V1_0::HdmiPortInfo; +using ::android::hardware::tv::cec::V1_0::HdmiPortType; +using ::android::hardware::tv::cec::V1_0::HotplugEvent; +using ::android::hardware::tv::cec::V1_0::OptionKey; +using ::android::hardware::tv::cec::V1_0::Result; +using ::android::hardware::tv::cec::V1_0::SendMessageResult; +using ::android::hardware::tv::cec::V1_1::CecLogicalAddress; +using ::android::hardware::tv::cec::V1_1::CecMessage; +using ::android::hardware::tv::cec::V1_1::IHdmiCec; +using ::android::hardware::tv::cec::V1_1::IHdmiCecCallback; + +#define CEC_VERSION 0x05 +#define INCORRECT_VENDOR_ID 0x00 + +// The main test class for TV CEC HAL. +class HdmiCecTest : public ::testing::TestWithParam { + public: + void SetUp() override { + hdmiCec = IHdmiCec::getService(GetParam()); + ASSERT_NE(hdmiCec, nullptr); + ALOGI("%s: getService() for hdmiCec is %s", __func__, + hdmiCec->isRemote() ? "remote" : "local"); + + hdmiCec_death_recipient = new HdmiCecDeathRecipient(); + hdmiCecCallback = new CecCallback(); + ASSERT_NE(hdmiCec_death_recipient, nullptr); + ASSERT_TRUE(hdmiCec->linkToDeath(hdmiCec_death_recipient, 0).isOk()); + } + + std::vector getDeviceTypes() { + std::vector deviceTypes; + FILE* p = popen("getprop ro.hdmi.device_type", "re"); + if (p) { + char* line = NULL; + size_t len = 0; + if (getline(&line, &len, p) > 0) { + std::istringstream stream(line); + std::string number{}; + while (std::getline(stream, number, ',')) { + deviceTypes.push_back(stoi(number)); + } + } + pclose(p); + } + return deviceTypes; + } + + bool hasDeviceType(CecDeviceType type) { + std::vector deviceTypes = getDeviceTypes(); + return std::find(deviceTypes.begin(), deviceTypes.end(), (int)type) != deviceTypes.end(); + } + + class CecCallback : public IHdmiCecCallback { + public: + Return onCecMessage( + const ::android::hardware::tv::cec::V1_0::CecMessage& /* message */) { + return Void(); + } + Return onCecMessage_1_1( + const ::android::hardware::tv::cec::V1_1::CecMessage& /* message */) { + return Void(); + } + Return onHotplugEvent( + const ::android::hardware::tv::cec::V1_0::HotplugEvent& /* event */) { + return Void(); + } + }; + + class HdmiCecDeathRecipient : public hidl_death_recipient { + public: + void serviceDied(uint64_t /*cookie*/, + const android::wp<::android::hidl::base::V1_0::IBase>& /*who*/) override { + FAIL(); + } + }; + + sp hdmiCec; + sp hdmiCecCallback; + sp hdmiCec_death_recipient; +}; + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(HdmiCecTest); +INSTANTIATE_TEST_SUITE_P( + PerInstance, HdmiCecTest, + testing::ValuesIn(android::hardware::getAllHalInstanceNames(IHdmiCec::descriptor)), + android::hardware::PrintInstanceNameToString); + +TEST_P(HdmiCecTest, ClearAddLogicalAddress) { + hdmiCec->clearLogicalAddress(); + Return ret = hdmiCec->addLogicalAddress_1_1(CecLogicalAddress::PLAYBACK_3); + EXPECT_EQ(ret, Result::SUCCESS); +} + +TEST_P(HdmiCecTest, SendMessage) { + CecMessage message; + message.initiator = CecLogicalAddress::PLAYBACK_1; + message.destination = CecLogicalAddress::BROADCAST; + message.body.resize(1); + message.body[0] = 131; + SendMessageResult ret = hdmiCec->sendMessage_1_1(message); + EXPECT_EQ(ret, SendMessageResult::SUCCESS); +} + +TEST_P(HdmiCecTest, CecVersion) { + Return ret = hdmiCec->getCecVersion(); + EXPECT_GE(ret, CEC_VERSION); +} + +TEST_P(HdmiCecTest, SetCallback) { + Return ret = hdmiCec->setCallback_1_1(new CecCallback()); + ASSERT_TRUE(ret.isOk()); +} + +TEST_P(HdmiCecTest, VendorId) { + Return ret = hdmiCec->getVendorId(); + EXPECT_NE(ret, INCORRECT_VENDOR_ID); +} + +TEST_P(HdmiCecTest, GetPortInfo) { + hidl_vec ports; + Return ret = + hdmiCec->getPortInfo([&ports](hidl_vec list) { ports = list; }); + ASSERT_TRUE(ret.isOk()); + bool cecSupportedOnDevice = false; + for (size_t i = 0; i < ports.size(); ++i) { + EXPECT_TRUE((ports[i].type == HdmiPortType::OUTPUT) || + (ports[i].type == HdmiPortType::INPUT)); + if (ports[i].portId == 0) { + ALOGW("%s: Port id should start from 1", __func__); + } + cecSupportedOnDevice = cecSupportedOnDevice | ports[i].cecSupported; + } + EXPECT_NE(cecSupportedOnDevice, false) << "At least one port should support CEC"; +} + +TEST_P(HdmiCecTest, SetOption) { + Return wakeup = hdmiCec->setOption(OptionKey::WAKEUP, false); + ASSERT_TRUE(wakeup.isOk()); + Return enableCec = hdmiCec->setOption(OptionKey::ENABLE_CEC, false); + ASSERT_TRUE(enableCec.isOk()); + Return systemCecControl = hdmiCec->setOption(OptionKey::SYSTEM_CEC_CONTROL, true); + ASSERT_TRUE(systemCecControl.isOk()); + // Restore option keys to their default values + hdmiCec->setOption(OptionKey::WAKEUP, true); + hdmiCec->setOption(OptionKey::ENABLE_CEC, true); + hdmiCec->setOption(OptionKey::SYSTEM_CEC_CONTROL, false); +} + +TEST_P(HdmiCecTest, SetLanguage) { + Return ret = hdmiCec->setLanguage("eng"); + ASSERT_TRUE(ret.isOk()); +} + +TEST_P(HdmiCecTest, EnableAudioReturnChannel) { + hidl_vec ports; + Return ret = + hdmiCec->getPortInfo([&ports](hidl_vec list) { ports = list; }); + for (size_t i = 0; i < ports.size(); ++i) { + if (ports[i].arcSupported) { + Return ret = hdmiCec->enableAudioReturnChannel(ports[i].portId, true); + ASSERT_TRUE(ret.isOk()); + } + } +} \ No newline at end of file -- GitLab From 3b1e800b9ea737f3e8e7700502ac0d96cd565037 Mon Sep 17 00:00:00 2001 From: Robert Shih Date: Thu, 11 Feb 2021 22:18:54 -0800 Subject: [PATCH 447/790] drm@1.4: add detailed error codes Bug: 162255728 Test: VtsHalDrmV1_4TargetTest Change-Id: Id1a3376d926ad1e5e4e53c619588af2ab9f7fabf --- drm/1.4/types.hal | 91 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 88 insertions(+), 3 deletions(-) diff --git a/drm/1.4/types.hal b/drm/1.4/types.hal index 706c3aa92a..09531a40fd 100644 --- a/drm/1.4/types.hal +++ b/drm/1.4/types.hal @@ -37,15 +37,100 @@ struct LogMessage { }; enum Status : @1.2::Status { - + /** + * 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, + /** + * 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, }; -- GitLab From 10ca7b1d5bc1820b402c49003b9fe6f8d88505dd Mon Sep 17 00:00:00 2001 From: Tyler Wear Date: Thu, 30 Jul 2020 13:21:03 -0700 Subject: [PATCH 448/790] IRadio 1.6: Public Key Type For IMSI Encryption - Add public key type for IMSI encryption. - Add VTS test case for setCarrierInfoForImsiEncryption_1_6 Test: Manual Bug: 142333634 Change-Id: Id11055354b32e492e24f43b348bdf2745d63529c --- radio/1.6/IRadio.hal | 16 ++++++++++++ radio/1.6/types.hal | 18 +++++++++++++ .../1.6/vts/functional/radio_hidl_hal_api.cpp | 26 +++++++++++++++++++ 3 files changed, 60 insertions(+) diff --git a/radio/1.6/IRadio.hal b/radio/1.6/IRadio.hal index 32f8b0be2c..7a13f0d71a 100644 --- a/radio/1.6/IRadio.hal +++ b/radio/1.6/IRadio.hal @@ -521,4 +521,20 @@ interface IRadio extends @1.5::IRadio { * Response function is IRadioResponse.getSlicingConfigResponse() */ oneway getSlicingConfig(int32_t serial); + + /** + * Provide Carrier specific information to the modem that must be used to + * encrypt the IMSI and IMPI. Sent by the framework during boot, carrier + * switch and everytime the framework receives a new certificate. + * + * @param serial Serial number of request. + * @param imsiEncryptionInfo ImsiEncryptionInfo as defined in types.hal. + * + * Response callback is + * IRadioResponse.setCarrierInfoForImsiEncryptionResponse() + * + * Note this API is the same as the 1.1 version except using the 1.6 ImsiEncryptionInfo + * as the input param. + */ + oneway setCarrierInfoForImsiEncryption_1_6(int32_t serial, @1.6::ImsiEncryptionInfo imsiEncryptionInfo); }; diff --git a/radio/1.6/types.hal b/radio/1.6/types.hal index 6c23650dde..5d363c95a0 100644 --- a/radio/1.6/types.hal +++ b/radio/1.6/types.hal @@ -27,6 +27,7 @@ import @1.1::EutranBands; import @1.1::GeranBands; import @1.1::ScanStatus; import @1.1::UtranBands; +import @1.1::ImsiEncryptionInfo; import @1.2::Call; import @1.2::CellInfoCdma; import @1.2::CellConnectionStatus; @@ -1115,3 +1116,20 @@ enum SscMode : int32_t { MODE_2 = 2, MODE_3 = 3, }; + +/** + * Public key type from carrier certificate. + */ +enum PublicKeyType : int32_t { + EPDG = 1, // Key type to be used for ePDG + WLAN = 2, // Key type to be used for WLAN +}; + +/** + * Carrier specific Information sent by the carrier, + * which will be used to encrypt the IMSI and IMPI. + */ +struct ImsiEncryptionInfo { + @1.1::ImsiEncryptionInfo base; + PublicKeyType keyType; // Public key type +}; diff --git a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp index 07b8ccb035..fb50990a28 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp +++ b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp @@ -676,3 +676,29 @@ TEST_P(RadioHidlTest_v1_6, getCurrentCalls_1_6) { EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial); EXPECT_EQ(::android::hardware::radio::V1_6::RadioError::NONE, radioRsp_v1_6->rspInfo.error); } + +/* + * Test IRadio.setCarrierInfoForImsiEncryption_1_6() for the response returned. + */ +TEST_P(RadioHidlTest_v1_6, setCarrierInfoForImsiEncryption_1_6) { + serial = GetRandomSerialNumber(); + ::android::hardware::radio::V1_6::ImsiEncryptionInfo imsiInfo; + imsiInfo.base.mcc = "310"; + imsiInfo.base.mnc = "004"; + imsiInfo.base.carrierKey = (std::vector){1, 2, 3, 4, 5, 6}; + imsiInfo.base.keyIdentifier = "Test"; + imsiInfo.base.expirationTime = 20180101; + imsiInfo.keyType = PublicKeyType::EPDG; + + radio_v1_6->setCarrierInfoForImsiEncryption_1_6(serial, imsiInfo); + EXPECT_EQ(std::cv_status::no_timeout, wait()); + EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type); + EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial); + + if (cardStatus.base.base.base.cardState == CardState::ABSENT) { + ASSERT_TRUE(CheckAnyOfErrors( + radioRsp_v1_6->rspInfo.error, + {::android::hardware::radio::V1_6::RadioError::NONE, + ::android::hardware::radio::V1_6::RadioError::REQUEST_NOT_SUPPORTED})); + } +} -- GitLab From e5b120f096749f2bd22c55e6e918e61c72e9ce84 Mon Sep 17 00:00:00 2001 From: Anthony Stange Date: Fri, 12 Feb 2021 14:38:15 +0000 Subject: [PATCH 449/790] Deprecate old Contexthub HAL versions The latest HAL allows the Contexthub service to enforce and attribute permissions usage when using nanoapps which must be supported on devices launching with S+ Fixes: 180100226 Test: compile Change-Id: Ifff454b0757abe190b22089cb7de37204ee05ce7 --- compatibility_matrices/compatibility_matrix.current.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index 8e44be0e0c..8d41d5a06e 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -191,7 +191,7 @@ android.hardware.contexthub - 1.0-2 + 1.2 IContexthub default -- GitLab From b4695c83bc7afefa4af74990f6c4670a8b49aede Mon Sep 17 00:00:00 2001 From: Henry Fang Date: Thu, 11 Feb 2021 10:20:51 -0800 Subject: [PATCH 450/790] handle multiple cas plugins. some of them support descrambler, some of them don't bug: 176799453 Test: atest VtsHalCasV1_[#]TargetTest Change-Id: Ifec298486b413129601787755bbe8e7bbea6cbf3 --- .../functional/VtsHalCasV1_0TargetTest.cpp | 34 +++++++++++-------- .../functional/VtsHalCasV1_1TargetTest.cpp | 25 ++++++++------ .../functional/VtsHalCasV1_2TargetTest.cpp | 18 ++++++---- 3 files changed, 46 insertions(+), 31 deletions(-) diff --git a/cas/1.0/vts/functional/VtsHalCasV1_0TargetTest.cpp b/cas/1.0/vts/functional/VtsHalCasV1_0TargetTest.cpp index df0c85934f..a1d5930386 100644 --- a/cas/1.0/vts/functional/VtsHalCasV1_0TargetTest.cpp +++ b/cas/1.0/vts/functional/VtsHalCasV1_0TargetTest.cpp @@ -256,12 +256,19 @@ class MediaCasHidlTest : public testing::TestWithParam { ::testing::AssertionResult MediaCasHidlTest::createCasPlugin(int32_t caSystemId) { auto status = mService->isSystemIdSupported(caSystemId); + bool skipDescrambler = false; if (!status.isOk() || !status) { return ::testing::AssertionFailure(); } status = mService->isDescramblerSupported(caSystemId); if (!status.isOk() || !status) { - return ::testing::AssertionFailure(); + if (mIsTestDescrambler) { + return ::testing::AssertionFailure(); + } else { + ALOGI("Skip Descrambler test since it's not required in cas@1.2."); + mDescramblerBase = nullptr; + skipDescrambler = true; + } } mCasListener = new MediaCasListener(); @@ -274,16 +281,15 @@ class MediaCasHidlTest : public testing::TestWithParam { return ::testing::AssertionFailure(); } + if (skipDescrambler) { + return ::testing::AssertionSuccess(); + } + auto descramblerStatus = mService->createDescrambler(caSystemId); if (!descramblerStatus.isOk()) { - if (mIsTestDescrambler) { - return ::testing::AssertionFailure(); - } else { - ALOGI("Skip Descrambler test since it's not required in cas@1.2."); - return ::testing::AssertionSuccess(); - } + return ::testing::AssertionFailure(); } - mIsTestDescrambler = true; + mDescramblerBase = descramblerStatus; return ::testing::AssertionResult(mDescramblerBase != nullptr); } @@ -506,7 +512,7 @@ TEST_P(MediaCasHidlTest, TestClearKeyApis) { returnStatus = mMediaCas->setSessionPrivateData(streamSessionId, hidlPvtData); EXPECT_TRUE(returnStatus.isOk()); EXPECT_EQ(Status::OK, returnStatus); - if (mIsTestDescrambler) { + if (mDescramblerBase != nullptr) { returnStatus = mDescramblerBase->setMediaCasSession(sessionId); EXPECT_TRUE(returnStatus.isOk()); EXPECT_EQ(Status::OK, returnStatus); @@ -556,7 +562,7 @@ TEST_P(MediaCasHidlTest, TestClearKeyApis) { EXPECT_TRUE(returnStatus.isOk()); EXPECT_EQ(Status::OK, returnStatus); - if (mIsTestDescrambler) { + if (mDescramblerBase != nullptr) { EXPECT_FALSE(mDescramblerBase->requiresSecureDecoderComponent("video/avc")); sp descrambler; @@ -606,7 +612,7 @@ TEST_P(MediaCasHidlTest, TestClearKeySessionClosedAfterRelease) { EXPECT_TRUE(returnStatus.isOk()); EXPECT_EQ(Status::OK, returnStatus); - if (mIsTestDescrambler) { + if (mDescramblerBase != nullptr) { returnStatus = mDescramblerBase->setMediaCasSession(sessionId); EXPECT_TRUE(returnStatus.isOk()); EXPECT_EQ(Status::ERROR_CAS_SESSION_NOT_OPENED, returnStatus); @@ -672,7 +678,7 @@ TEST_P(MediaCasHidlTest, TestClearKeyErrors) { EXPECT_TRUE(returnStatus.isOk()); EXPECT_EQ(Status::ERROR_CAS_UNKNOWN, returnStatus); - if (mIsTestDescrambler) { + if (mDescramblerBase != nullptr) { /* * Test MediaDescrambler error codes */ @@ -720,7 +726,7 @@ TEST_P(MediaCasHidlTest, TestClearKeyOobFails) { std::vector sessionId; ASSERT_TRUE(openCasSession(&sessionId)); - if (mIsTestDescrambler) { + if (mDescramblerBase != nullptr) { returnStatus = mDescramblerBase->setMediaCasSession(sessionId); EXPECT_TRUE(returnStatus.isOk()); EXPECT_EQ(Status::OK, returnStatus); @@ -732,7 +738,7 @@ TEST_P(MediaCasHidlTest, TestClearKeyOobFails) { EXPECT_TRUE(returnStatus.isOk()); EXPECT_EQ(Status::OK, returnStatus); - if (mIsTestDescrambler) { + if (mDescramblerBase != nullptr) { sp descrambler = IDescrambler::castFrom(mDescramblerBase); ASSERT_NE(nullptr, descrambler.get()); diff --git a/cas/1.1/vts/functional/VtsHalCasV1_1TargetTest.cpp b/cas/1.1/vts/functional/VtsHalCasV1_1TargetTest.cpp index 6797506642..42d70cfeb9 100644 --- a/cas/1.1/vts/functional/VtsHalCasV1_1TargetTest.cpp +++ b/cas/1.1/vts/functional/VtsHalCasV1_1TargetTest.cpp @@ -297,12 +297,19 @@ class MediaCasHidlTest : public testing::TestWithParam { ::testing::AssertionResult MediaCasHidlTest::createCasPlugin(int32_t caSystemId) { auto status = mService->isSystemIdSupported(caSystemId); + bool skipDescrambler = false; if (!status.isOk() || !status) { return ::testing::AssertionFailure(); } status = mService->isDescramblerSupported(caSystemId); if (!status.isOk() || !status) { - return ::testing::AssertionFailure(); + if (mIsTestDescrambler) { + return ::testing::AssertionFailure(); + } else { + ALOGI("Skip Descrambler test since it's not required in cas@1.2."); + mDescramblerBase = nullptr; + skipDescrambler = true; + } } mCasListener = new MediaCasListener(); @@ -315,16 +322,14 @@ class MediaCasHidlTest : public testing::TestWithParam { return ::testing::AssertionFailure(); } + if (skipDescrambler) { + return ::testing::AssertionSuccess(); + } + auto descramblerStatus = mService->createDescrambler(caSystemId); if (!descramblerStatus.isOk()) { - if (mIsTestDescrambler) { - return ::testing::AssertionFailure(); - } else { - ALOGI("Skip Descrambler test since it's not required in cas@1.2."); - return ::testing::AssertionSuccess(); - } + return ::testing::AssertionFailure(); } - mIsTestDescrambler = true; mDescramblerBase = descramblerStatus; return ::testing::AssertionResult(mDescramblerBase != nullptr); @@ -481,7 +486,7 @@ TEST_P(MediaCasHidlTest, TestClearKeyApisWithSession) { EXPECT_TRUE(returnStatus.isOk()); EXPECT_EQ(Status::OK, returnStatus); - if (mIsTestDescrambler) { + if (mDescramblerBase != nullptr) { returnStatus = mDescramblerBase->setMediaCasSession(sessionId); EXPECT_TRUE(returnStatus.isOk()); EXPECT_EQ(Status::OK, returnStatus); @@ -533,7 +538,7 @@ TEST_P(MediaCasHidlTest, TestClearKeyApisWithSession) { EXPECT_TRUE(returnStatus.isOk()); EXPECT_EQ(Status::OK, returnStatus); - if (mIsTestDescrambler) { + if (mDescramblerBase != nullptr) { EXPECT_FALSE(mDescramblerBase->requiresSecureDecoderComponent("video/avc")); sp descrambler; diff --git a/cas/1.2/vts/functional/VtsHalCasV1_2TargetTest.cpp b/cas/1.2/vts/functional/VtsHalCasV1_2TargetTest.cpp index 333dea61db..0d75f5b812 100644 --- a/cas/1.2/vts/functional/VtsHalCasV1_2TargetTest.cpp +++ b/cas/1.2/vts/functional/VtsHalCasV1_2TargetTest.cpp @@ -311,7 +311,6 @@ class MediaCasHidlTest : public testing::TestWithParam { sp mMediaCas; sp mDescramblerBase; sp mCasListener; - bool mIsTestDescrambler = false; typedef struct _OobInputTestParams { const SubSample* subSamples; uint32_t numSubSamples; @@ -336,12 +335,15 @@ class MediaCasHidlTest : public testing::TestWithParam { ::testing::AssertionResult MediaCasHidlTest::createCasPlugin(int32_t caSystemId) { auto status = mService->isSystemIdSupported(caSystemId); + bool skipDescrambler = false; if (!status.isOk() || !status) { return ::testing::AssertionFailure(); } status = mService->isDescramblerSupported(caSystemId); if (!status.isOk() || !status) { - return ::testing::AssertionFailure(); + ALOGI("Skip Descrambler test since it's not required in cas@1.2."); + mDescramblerBase = nullptr; + skipDescrambler = true; } mCasListener = new MediaCasListener(); @@ -354,12 +356,14 @@ class MediaCasHidlTest : public testing::TestWithParam { return ::testing::AssertionFailure(); } + if (skipDescrambler) { + return ::testing::AssertionSuccess(); + } + auto descramblerStatus = mService->createDescrambler(caSystemId); if (!descramblerStatus.isOk()) { - ALOGI("Skip Descrambler test since it's not required in cas@1.2."); - return ::testing::AssertionSuccess(); + return ::testing::AssertionFailure(); } - mIsTestDescrambler = true; mDescramblerBase = descramblerStatus; return ::testing::AssertionResult(mDescramblerBase != nullptr); @@ -516,7 +520,7 @@ TEST_P(MediaCasHidlTest, TestClearKeyApisWithSession) { EXPECT_TRUE(returnStatus.isOk()); EXPECT_EQ(Status::OK, returnStatus); - if (mIsTestDescrambler) { + if (mDescramblerBase != nullptr) { returnStatus = mDescramblerBase->setMediaCasSession(sessionId); EXPECT_TRUE(returnStatus.isOk()); EXPECT_EQ(Status::OK, returnStatus); @@ -571,7 +575,7 @@ TEST_P(MediaCasHidlTest, TestClearKeyApisWithSession) { EXPECT_TRUE(returnStatus.isOk()); EXPECT_EQ(Status::OK, returnStatus); - if (mIsTestDescrambler) { + if (mDescramblerBase != nullptr) { EXPECT_FALSE(mDescramblerBase->requiresSecureDecoderComponent("video/avc")); sp descrambler; -- GitLab From 92b14470971633219d88e7c59d388b500787fcad Mon Sep 17 00:00:00 2001 From: Anthony Stange Date: Mon, 15 Feb 2021 22:13:26 +0000 Subject: [PATCH 451/790] Add methods needed for CHRE HAL to use IContextHubWrapper Bug: 166846988 Test: Load onto device and verify HAL 1.2 works as it did previously Change-Id: I5281362178901a841ad2cf6bb839fe9f9a863a56 --- .../default/1.X/utils/IContextHubCallbackWrapper.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/contexthub/common/default/1.X/utils/IContextHubCallbackWrapper.h b/contexthub/common/default/1.X/utils/IContextHubCallbackWrapper.h index d8cc37b5f2..d9459b7381 100644 --- a/contexthub/common/default/1.X/utils/IContextHubCallbackWrapper.h +++ b/contexthub/common/default/1.X/utils/IContextHubCallbackWrapper.h @@ -64,6 +64,11 @@ class IContextHubCallbackWrapperBase : public VirtualLightRefBase { virtual Return handleAppAbort(uint64_t appId, uint32_t abortCode) = 0; virtual Return handleAppsInfo(hidl_vec appInfo) = 0; + + virtual Return linkToDeath(const sp& recipient, + uint64_t cookie) = 0; + + virtual Return unlinkToDeath(const sp& recipient) = 0; }; template @@ -92,6 +97,14 @@ class ContextHubCallbackWrapper : public IContextHubCallbackWrapperBase { return mCallback->handleAppsInfo(convertToOldAppInfo(appInfo)); } + Return linkToDeath(const sp& recipient, uint64_t cookie) override { + return mCallback->linkToDeath(recipient, cookie); + } + + Return unlinkToDeath(const sp& recipient) override { + return mCallback->unlinkToDeath(recipient); + } + protected: sp mCallback; }; -- GitLab From 124e70a8ed7d6d15f99806e86c8713c40c47b608 Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Fri, 12 Feb 2021 13:00:15 -0800 Subject: [PATCH 452/790] Move headers to include/ and clean up style Bug: 166800618 Test: mma Change-Id: I7c1c60445f2e66f4f655863404769a834abc0026 --- .../fingerprint/aidl/default/Android.bp | 13 ++-- .../fingerprint/aidl/default/Fingerprint.cpp | 66 +++++++++---------- .../fingerprint/aidl/default/Session.cpp | 32 ++++----- .../aidl/default/{ => include}/Fingerprint.h | 8 ++- .../aidl/default/{ => include}/Session.h | 11 ++-- 5 files changed, 63 insertions(+), 67 deletions(-) rename biometrics/fingerprint/aidl/default/{ => include}/Fingerprint.h (91%) rename biometrics/fingerprint/aidl/default/{ => include}/Session.h (89%) diff --git a/biometrics/fingerprint/aidl/default/Android.bp b/biometrics/fingerprint/aidl/default/Android.bp index c8cb663686..69fb2e3309 100644 --- a/biometrics/fingerprint/aidl/default/Android.bp +++ b/biometrics/fingerprint/aidl/default/Android.bp @@ -1,18 +1,19 @@ cc_binary { name: "android.hardware.biometrics.fingerprint-service.example", + vendor: true, relative_install_path: "hw", init_rc: ["fingerprint-default.rc"], vintf_fragments: ["fingerprint-default.xml"], - vendor: true, + local_include_dirs: ["include"], + srcs: [ + "main.cpp", + "Fingerprint.cpp", + "Session.cpp", + ], shared_libs: [ "libbase", "libbinder_ndk", "android.hardware.biometrics.fingerprint-V1-ndk_platform", "android.hardware.biometrics.common-V1-ndk_platform", ], - srcs: [ - "main.cpp", - "Fingerprint.cpp", - "Session.cpp", - ], } diff --git a/biometrics/fingerprint/aidl/default/Fingerprint.cpp b/biometrics/fingerprint/aidl/default/Fingerprint.cpp index f27e278574..fa3171f850 100644 --- a/biometrics/fingerprint/aidl/default/Fingerprint.cpp +++ b/biometrics/fingerprint/aidl/default/Fingerprint.cpp @@ -18,50 +18,44 @@ #include "Session.h" namespace aidl::android::hardware::biometrics::fingerprint { +namespace { -const int kSensorId = 1; -const common::SensorStrength kSensorStrength = common::SensorStrength::STRONG; -const int kMaxEnrollmentsPerUser = 5; -const FingerprintSensorType kSensorType = FingerprintSensorType::REAR; -const bool kSupportsNavigationGestures = true; -const std::string kHwDeviceName = "fingerprintSensor"; -const std::string kHardwareVersion = "vendor/model/revision"; -const std::string kFirmwareVersion = "1.01"; -const std::string kSerialNumber = "00000001"; +constexpr int SENSOR_ID = 1; +constexpr common::SensorStrength SENSOR_STRENGTH = common::SensorStrength::STRONG; +constexpr int MAX_ENROLLMENTS_PER_USER = 5; +constexpr FingerprintSensorType SENSOR_TYPE = FingerprintSensorType::REAR; +constexpr bool SUPPORTS_NAVIGATION_GESTURES = true; +constexpr char HW_DEVICE_NAME[] = "fingerprintSensor"; +constexpr char HW_VERSION[] = "vendor/model/revision"; +constexpr char FW_VERSION[] = "1.01"; +constexpr char SERIAL_NUMBER[] = "00000001"; -ndk::ScopedAStatus Fingerprint::getSensorProps(std::vector* return_val) { - *return_val = std::vector(); +} // namespace - std::vector hardwareInfos = std::vector(); - common::HardwareInfo sensorInfo = {kHwDeviceName, - kHardwareVersion, - kFirmwareVersion, - kSerialNumber - }; - hardwareInfos.push_back(sensorInfo); - common::CommonProps commonProps = {kSensorId, - kSensorStrength, - kMaxEnrollmentsPerUser, - hardwareInfos}; - SensorLocation sensorLocation = { - 0 /* displayId */, - 0 /* sensorLocationX */, - 0 /* sensorLocationY */, - 0 /* sensorRadius */ - }; - SensorProps props = {commonProps, - kSensorType, - {sensorLocation}, - kSupportsNavigationGestures, - false /* supportsDetectInteraction */}; - return_val->push_back(props); +Fingerprint::Fingerprint() {} + +ndk::ScopedAStatus Fingerprint::getSensorProps(std::vector* out) { + std::vector hardwareInfos = { + {HW_DEVICE_NAME, HW_VERSION, FW_VERSION, SERIAL_NUMBER}}; + + common::CommonProps commonProps = {SENSOR_ID, SENSOR_STRENGTH, MAX_ENROLLMENTS_PER_USER, + hardwareInfos}; + + SensorLocation sensorLocation = {0 /* displayId */, 0 /* sensorLocationX */, + 0 /* sensorLocationY */, 0 /* sensorRadius */}; + + *out = {{commonProps, + SENSOR_TYPE, + {sensorLocation}, + SUPPORTS_NAVIGATION_GESTURES, + false /* supportsDetectInteraction */}}; return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus Fingerprint::createSession(int32_t /*sensorId*/, int32_t /*userId*/, const std::shared_ptr& cb, - std::shared_ptr* return_val) { - *return_val = SharedRefBase::make(cb); + std::shared_ptr* out) { + *out = SharedRefBase::make(cb); return ndk::ScopedAStatus::ok(); } } // namespace aidl::android::hardware::biometrics::fingerprint diff --git a/biometrics/fingerprint/aidl/default/Session.cpp b/biometrics/fingerprint/aidl/default/Session.cpp index 844622101e..52dddb665e 100644 --- a/biometrics/fingerprint/aidl/default/Session.cpp +++ b/biometrics/fingerprint/aidl/default/Session.cpp @@ -26,7 +26,7 @@ class CancellationSignal : public common::BnCancellationSignal { ndk::ScopedAStatus cancel() override { return ndk::ScopedAStatus::ok(); } }; -Session::Session(std::shared_ptr cb) : cb_(std::move(cb)) {} +Session::Session(std::shared_ptr cb) : mCb(std::move(cb)) {} ndk::ScopedAStatus Session::generateChallenge(int32_t /*cookie*/, int32_t /*timeoutSec*/) { LOG(INFO) << "generateChallenge"; @@ -39,32 +39,32 @@ ndk::ScopedAStatus Session::revokeChallenge(int32_t /*cookie*/, int64_t /*challe } ndk::ScopedAStatus Session::enroll(int32_t /*cookie*/, const keymaster::HardwareAuthToken& /*hat*/, - std::shared_ptr* /*return_val*/) { + std::shared_ptr* /*out*/) { LOG(INFO) << "enroll"; return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus Session::authenticate(int32_t /*cookie*/, int64_t /*keystoreOperationId*/, - std::shared_ptr* return_val) { + std::shared_ptr* out) { LOG(INFO) << "authenticate"; - if (cb_) { - cb_->onStateChanged(0, SessionState::AUTHENTICATING); + if (mCb) { + mCb->onStateChanged(0, SessionState::AUTHENTICATING); } - *return_val = SharedRefBase::make(); + *out = SharedRefBase::make(); return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus Session::detectInteraction( - int32_t /*cookie*/, std::shared_ptr* /*return_val*/) { + int32_t /*cookie*/, std::shared_ptr* /*out*/) { LOG(INFO) << "detectInteraction"; return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus Session::enumerateEnrollments(int32_t /*cookie*/) { LOG(INFO) << "enumerateEnrollments"; - if (cb_) { - cb_->onStateChanged(0, SessionState::ENUMERATING_ENROLLMENTS); - cb_->onEnrollmentsEnumerated(std::vector()); + if (mCb) { + mCb->onStateChanged(0, SessionState::ENUMERATING_ENROLLMENTS); + mCb->onEnrollmentsEnumerated(std::vector()); } return ndk::ScopedAStatus::ok(); } @@ -72,18 +72,18 @@ ndk::ScopedAStatus Session::enumerateEnrollments(int32_t /*cookie*/) { ndk::ScopedAStatus Session::removeEnrollments(int32_t /*cookie*/, const std::vector& /*enrollmentIds*/) { LOG(INFO) << "removeEnrollments"; - if (cb_) { - cb_->onStateChanged(0, SessionState::REMOVING_ENROLLMENTS); - cb_->onEnrollmentsRemoved(std::vector()); + if (mCb) { + mCb->onStateChanged(0, SessionState::REMOVING_ENROLLMENTS); + mCb->onEnrollmentsRemoved(std::vector()); } return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus Session::getAuthenticatorId(int32_t /*cookie*/) { LOG(INFO) << "getAuthenticatorId"; - if (cb_) { - cb_->onStateChanged(0, SessionState::GETTING_AUTHENTICATOR_ID); - cb_->onAuthenticatorIdRetrieved(0 /* authenticatorId */); + if (mCb) { + mCb->onStateChanged(0, SessionState::GETTING_AUTHENTICATOR_ID); + mCb->onAuthenticatorIdRetrieved(0 /* authenticatorId */); } return ndk::ScopedAStatus::ok(); } diff --git a/biometrics/fingerprint/aidl/default/Fingerprint.h b/biometrics/fingerprint/aidl/default/include/Fingerprint.h similarity index 91% rename from biometrics/fingerprint/aidl/default/Fingerprint.h rename to biometrics/fingerprint/aidl/default/include/Fingerprint.h index 4e952ba74e..867e5fafb3 100644 --- a/biometrics/fingerprint/aidl/default/Fingerprint.h +++ b/biometrics/fingerprint/aidl/default/include/Fingerprint.h @@ -20,13 +20,15 @@ namespace aidl::android::hardware::biometrics::fingerprint { -class Fingerprint : public BnFingerprint { +class Fingerprint final : public BnFingerprint { public: - ndk::ScopedAStatus getSensorProps(std::vector* _aidl_return) override; + Fingerprint(); + + ndk::ScopedAStatus getSensorProps(std::vector* out) override; ndk::ScopedAStatus createSession(int32_t sensorId, int32_t userId, const std::shared_ptr& cb, - std::shared_ptr* _aidl_return) override; + std::shared_ptr* out) override; }; } // namespace aidl::android::hardware::biometrics::fingerprint diff --git a/biometrics/fingerprint/aidl/default/Session.h b/biometrics/fingerprint/aidl/default/include/Session.h similarity index 89% rename from biometrics/fingerprint/aidl/default/Session.h rename to biometrics/fingerprint/aidl/default/include/Session.h index ed3ae3fd7e..b9befef119 100644 --- a/biometrics/fingerprint/aidl/default/Session.h +++ b/biometrics/fingerprint/aidl/default/include/Session.h @@ -33,14 +33,13 @@ class Session : public BnSession { ndk::ScopedAStatus revokeChallenge(int32_t cookie, int64_t challenge) override; ndk::ScopedAStatus enroll(int32_t cookie, const keymaster::HardwareAuthToken& hat, - std::shared_ptr* return_val) override; + std::shared_ptr* out) override; - ndk::ScopedAStatus authenticate( - int32_t cookie, int64_t keystoreOperationId, - std::shared_ptr* return_val) override; + ndk::ScopedAStatus authenticate(int32_t cookie, int64_t keystoreOperationId, + std::shared_ptr* out) override; ndk::ScopedAStatus detectInteraction( - int32_t cookie, std::shared_ptr* return_val) override; + int32_t cookie, std::shared_ptr* out) override; ndk::ScopedAStatus enumerateEnrollments(int32_t cookie) override; @@ -62,7 +61,7 @@ class Session : public BnSession { ndk::ScopedAStatus onUiReady() override; private: - std::shared_ptr cb_; + std::shared_ptr mCb; }; } // namespace aidl::android::hardware::biometrics::fingerprint -- GitLab From 08d9c53712d3090f316784f214a6e76d47f5c434 Mon Sep 17 00:00:00 2001 From: Robert Shih Date: Tue, 16 Feb 2021 01:08:49 -0800 Subject: [PATCH 453/790] drm@1.4: reorder LogPriority to match android_LogPriority Bug: 162255728 Test: VtsHalDrmV1_4TargetTest Change-Id: Ia987890a4c58ce5f7fac7b33ae8568fbcee427dc --- drm/1.4/types.hal | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drm/1.4/types.hal b/drm/1.4/types.hal index 706c3aa92a..fd07c69477 100644 --- a/drm/1.4/types.hal +++ b/drm/1.4/types.hal @@ -19,11 +19,14 @@ package android.hardware.drm@1.4; import @1.2::Status; enum LogPriority : uint32_t { - ERROR, - WARN, - INFO, - DEBUG, - VERBOSE + UNKNOWN, + DEFAULT, + VERBOSE, + DEBUG, + INFO, + WARN, + ERROR, + FATAL, }; /** -- GitLab From 292336884e54876dbbc299aa0b37e0cc92b64ad5 Mon Sep 17 00:00:00 2001 From: Albert Wang Date: Tue, 17 Nov 2020 13:23:40 +0800 Subject: [PATCH 454/790] USB HAL 1.3 interface Supports to enable/disable USB data signaling Bug: 142105910 Bug: 161414036 Test: USB HAL V1.3 HIDL tests Signed-off-by: Albert Wang Change-Id: I55ac262dbcdd89ab039193ed467b94f80664c9ba Merged-In: I55ac262dbcdd89ab039193ed467b94f80664c9ba (cherry picked from commit 64bd20e416d13d3f10d670c0dc42a9892f248763) --- .../compatibility_matrix.current.xml | 2 +- usb/1.3/Android.bp | 16 +++++ usb/1.3/IUsb.hal | 32 +++++++++ usb/1.3/vts/OWNERS | 2 + usb/1.3/vts/functional/Android.bp | 31 +++++++++ .../functional/VtsHalUsbV1_3TargetTest.cpp | 69 +++++++++++++++++++ 6 files changed, 151 insertions(+), 1 deletion(-) create mode 100644 usb/1.3/Android.bp create mode 100644 usb/1.3/IUsb.hal create mode 100644 usb/1.3/vts/OWNERS create mode 100644 usb/1.3/vts/functional/Android.bp create mode 100644 usb/1.3/vts/functional/VtsHalUsbV1_3TargetTest.cpp diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index 2281858779..48f0b60c5d 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -578,7 +578,7 @@ android.hardware.usb - 1.0-2 + 1.0-3 IUsb default diff --git a/usb/1.3/Android.bp b/usb/1.3/Android.bp new file mode 100644 index 0000000000..17367d3d8d --- /dev/null +++ b/usb/1.3/Android.bp @@ -0,0 +1,16 @@ +// This file is autogenerated by hidl-gen -Landroidbp. + +hidl_interface { + name: "android.hardware.usb@1.3", + root: "android.hardware", + srcs: [ + "IUsb.hal", + ], + interfaces: [ + "android.hardware.usb@1.0", + "android.hardware.usb@1.1", + "android.hardware.usb@1.2", + "android.hidl.base@1.0", + ], + gen_java: true, +} diff --git a/usb/1.3/IUsb.hal b/usb/1.3/IUsb.hal new file mode 100644 index 0000000000..3d1d380578 --- /dev/null +++ b/usb/1.3/IUsb.hal @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.usb@1.3; + +import android.hardware.usb@1.2::IUsb; + +interface IUsb extends @1.2::IUsb { + /** + * This function is used to enable/disable USB controller when some + * scenarios need. This function can stop and restore USB data signaling. + * + * @param enable true Enable USB data signaling. + * false Disable USB data signaling. + * @return true enable or disable USB data successfully + * false if something wrong + */ + enableUsbDataSignal(bool enable) generates(bool result); +}; diff --git a/usb/1.3/vts/OWNERS b/usb/1.3/vts/OWNERS new file mode 100644 index 0000000000..a6a1e5416a --- /dev/null +++ b/usb/1.3/vts/OWNERS @@ -0,0 +1,2 @@ +albertccwang@google.com +badhri@google.com diff --git a/usb/1.3/vts/functional/Android.bp b/usb/1.3/vts/functional/Android.bp new file mode 100644 index 0000000000..b62bb9d03f --- /dev/null +++ b/usb/1.3/vts/functional/Android.bp @@ -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. +// + +cc_test { + name: "VtsHalUsbV1_3TargetTest", + defaults: ["VtsHalTargetTestDefaults"], + srcs: ["VtsHalUsbV1_3TargetTest.cpp"], + static_libs: [ + "android.hardware.usb@1.0", + "android.hardware.usb@1.1", + "android.hardware.usb@1.2", + "android.hardware.usb@1.3", + ], + test_suites: [ + "general-tests", + "vts", + ], +} diff --git a/usb/1.3/vts/functional/VtsHalUsbV1_3TargetTest.cpp b/usb/1.3/vts/functional/VtsHalUsbV1_3TargetTest.cpp new file mode 100644 index 0000000000..ed35d4223e --- /dev/null +++ b/usb/1.3/vts/functional/VtsHalUsbV1_3TargetTest.cpp @@ -0,0 +1,69 @@ +/* + * 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 "VtsHalUsbV1_3TargetTest" +#include + +#include + +#include +#include +#include + +#include +#include +#include + +using ::android::sp; +using ::android::hardware::hidl_array; +using ::android::hardware::hidl_memory; +using ::android::hardware::hidl_string; +using ::android::hardware::hidl_vec; +using ::android::hardware::Return; +using ::android::hardware::Void; +using ::android::hardware::usb::V1_0::Status; +using ::android::hardware::usb::V1_3::IUsb; +using ::android::hidl::base::V1_0::IBase; + +// The main test class for the USB hidl HAL +class UsbHidlTest : public ::testing::TestWithParam { + public: + virtual void SetUp() override { + ALOGI(__FUNCTION__); + usb = IUsb::getService(GetParam()); + ASSERT_NE(usb, nullptr); + } + + virtual void TearDown() override { ALOGI("Teardown"); } + + // USB hidl hal Proxy + sp usb; +}; + +/* + * Check to see if enable usb data signal succeeds. + * HAL service should call enableUsbDataSignal. + */ +TEST_P(UsbHidlTest, enableUsbDataSignal) { + Return ret = usb->enableUsbDataSignal(true); + ASSERT_TRUE(ret.isOk()); +} + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(UsbHidlTest); +INSTANTIATE_TEST_SUITE_P( + PerInstance, UsbHidlTest, + testing::ValuesIn(android::hardware::getAllHalInstanceNames(IUsb::descriptor)), + android::hardware::PrintInstanceNameToString); -- GitLab From 87ff8d20ae5b42f7eca1ecf65bda7c10ee4d1164 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Szczepaniak?= Date: Wed, 3 Feb 2021 13:50:02 +0000 Subject: [PATCH 455/790] Non ABI changes to neuralnetworks HAL NNAPI HAL comment strings were reformated due to template changes for new versioning scheme. Test: Image built Bug: 177298018 Change-Id: I67b3a38c087edf6ba3c295f5ac43ca02b8359f6a --- current.txt | 5 +++-- neuralnetworks/1.0/types.hal | 5 +++-- neuralnetworks/1.2/types.hal | 8 +++++--- neuralnetworks/1.3/types.hal | 20 +++++++++++++------- 4 files changed, 24 insertions(+), 14 deletions(-) diff --git a/current.txt b/current.txt index fb9b056a43..5e9a34c5f6 100644 --- a/current.txt +++ b/current.txt @@ -779,8 +779,9 @@ bda492ec4021d13869de72bd6f8c15c5837b78d6136b8d538efec5320573a5ec android.hardwar 6017b4f2481feb0fffceae81c62bc372c898998b2d8fe69fbd39859d3a315e5e android.hardware.keymaster@4.0::IKeymasterDevice dabe23dde7c9e3ad65c61def7392f186d7efe7f4216f9b6f9cf0863745b1a9f4 android.hardware.keymaster@4.1::IKeymasterDevice cd84ab19c590e0e73dd2307b591a3093ee18147ef95e6d5418644463a6620076 android.hardware.neuralnetworks@1.2::IDevice -9625e85f56515ad2cf87b6a1847906db669f746ea4ab02cd3d4ca25abc9b0109 android.hardware.neuralnetworks@1.2::types -9e758e208d14f7256e0885d6d8ad0b61121b21d8c313864f981727ae55bffd16 android.hardware.neuralnetworks@1.3::types +f729ee6a5f136b25d79ea6895d24700fce413df555baaecf2c39e4440d15d043 android.hardware.neuralnetworks@1.0::types +c6ae443608502339aec4256feef48e7b2d36f7477ca5361cc95cd27a8ed9c612 android.hardware.neuralnetworks@1.2::types +9fe5a4093043c2b5da4e9491aed1646c388a5d3059b8fd77d5b6a9807e6d3a3e android.hardware.neuralnetworks@1.3::types e8c86c69c438da8d1549856c1bb3e2d1b8da52722f8235ff49a30f2cce91742c android.hardware.soundtrigger@2.1::ISoundTriggerHwCallback b9fbb6e2e061ed0960939d48b785e9700210add1f13ed32ecd688d0f1ca20ef7 android.hardware.renderscript@1.0::types 0f53d70e1eadf8d987766db4bf6ae2048004682168f4cab118da576787def3fa android.hardware.radio@1.0::types diff --git a/neuralnetworks/1.0/types.hal b/neuralnetworks/1.0/types.hal index 620eefb48b..5bfadd33bb 100644 --- a/neuralnetworks/1.0/types.hal +++ b/neuralnetworks/1.0/types.hal @@ -308,8 +308,9 @@ enum OperationType : int32_t { * Outputs: * * 0: The output 4-D tensor, of shape * [batches, out_height, out_width, depth_out]. - * For output tensor of {@link OperandType::TENSOR_QUANT8_ASYMM}, - * the following condition must be satisfied: output_scale > input_scale * filter_scale + * For output tensor of + * {@link OperandType::TENSOR_QUANT8_ASYMM}, the following condition must + * be satisfied: output_scale > input_scale * filter_scale */ CONV_2D = 3, diff --git a/neuralnetworks/1.2/types.hal b/neuralnetworks/1.2/types.hal index 7441a54dba..7cec49e0e2 100644 --- a/neuralnetworks/1.2/types.hal +++ b/neuralnetworks/1.2/types.hal @@ -314,7 +314,8 @@ enum OperationType : int32_t { * tensors. The output shape is [D0, D1, ..., sum(Daxis(i)), ..., Dm]. * Since HAL version 1.2, for a {@link OperandType::TENSOR_QUANT8_ASYMM} tensor, * the scale and zeroPoint values can be different from - * input tensors. Before HAL version 1.2 they have to be the same as for the input tensors. + * input tensors. Before HAL version 1.2 they have to be the same as for the + * input tensors. */ CONCATENATION = @1.1::OperationType:CONCATENATION, @@ -460,8 +461,9 @@ enum OperationType : int32_t { * Outputs: * * 0: The output 4-D tensor, of shape * [batches, out_height, out_width, depth_out]. - * Before HAL version 1.2, for output tensor of {@link OperandType::TENSOR_QUANT8_ASYMM}, - * the following condition must be satisfied: output_scale > input_scale * filter_scale + * Before HAL version 1.2, for output tensor of + * {@link OperandType::TENSOR_QUANT8_ASYMM}, the following condition must + * be satisfied: output_scale > input_scale * filter_scale */ CONV_2D = @1.1::OperationType:CONV_2D, diff --git a/neuralnetworks/1.3/types.hal b/neuralnetworks/1.3/types.hal index 5f5ee0360c..51837fe858 100644 --- a/neuralnetworks/1.3/types.hal +++ b/neuralnetworks/1.3/types.hal @@ -263,7 +263,8 @@ enum OperationType : int32_t { * tensors. The output shape is [D0, D1, ..., sum(Daxis(i)), ..., Dm]. * Since HAL version 1.2, for a {@link OperandType::TENSOR_QUANT8_ASYMM} tensor, * the scale and zeroPoint values can be different from - * input tensors. Before HAL version 1.2 they have to be the same as for the input tensors. + * input tensors. Before HAL version 1.2 they have to be the same as for the + * input tensors. * For a {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} tensor, * the scale and zeroPoint values can be different from input tensors. */ @@ -312,7 +313,8 @@ enum OperationType : int32_t { * * * {@link OperandType::TENSOR_INT32} for bias (with scale set to * * * input.scale * filter.scale). * - * * Quantized signed with filter symmetric per channel quantization (since HAL version 1.3): + * * Quantized signed with filter symmetric per channel quantization + * (since HAL version 1.3): * * * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} for input, and output. * * * {@link OperandType::TENSOR_QUANT8_SYMM_PER_CHANNEL} for filter. * * * {@link OperandType::TENSOR_INT32} for bias (scale set to 0.0, @@ -425,8 +427,9 @@ enum OperationType : int32_t { * Outputs: * * 0: The output 4-D tensor, of shape * [batches, out_height, out_width, depth_out]. - * Before HAL version 1.2, for output tensor of {@link OperandType::TENSOR_QUANT8_ASYMM}, - * the following condition must be satisfied: output_scale > input_scale * filter_scale + * Before HAL version 1.2, for output tensor of + * {@link OperandType::TENSOR_QUANT8_ASYMM}, the following condition must + * be satisfied: output_scale > input_scale * filter_scale */ CONV_2D = @1.2::OperationType:CONV_2D, @@ -477,7 +480,8 @@ enum OperationType : int32_t { * * * {@link OperandType::TENSOR_INT32} for bias (with scale set to * * * input.scale * filter.scale). * - * * Quantized signed with filter symmetric per channel quantization (since HAL version 1.3): + * * Quantized signed with filter symmetric per channel quantization + * (since HAL version 1.3): * * * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} for input, and output. * * * {@link OperandType::TENSOR_QUANT8_SYMM_PER_CHANNEL} for filter. * * * {@link OperandType::TENSOR_INT32} for bias (scale set to 0.0, @@ -3354,7 +3358,8 @@ enum OperationType : int32_t { * * * {@link OperandType::TENSOR_INT32} for bias (scale set to 0.0, * * * each value scaling is separate and equal to input.scale * filter.scales[channel]). * - * * Quantized signed with filter symmetric per channel quantization (since HAL version 1.3): + * * Quantized signed with filter symmetric per channel quantization + * (since HAL version 1.3): * * * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} for input, and output. * * * {@link OperandType::TENSOR_QUANT8_SYMM_PER_CHANNEL} for filter. * * * {@link OperandType::TENSOR_INT32} for bias (scale set to 0.0, @@ -4615,7 +4620,8 @@ enum OperationType : int32_t { * * * {@link OperandType::TENSOR_INT32} for bias (with scale set to * * * input.scale * filter.scale). * - * * Quantized signed with filter symmetric per channel quantization (since HAL version 1.3): + * * Quantized signed with filter symmetric per channel quantization + * (since HAL version 1.3): * * * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} for input, and output. * * * {@link OperandType::TENSOR_QUANT8_SYMM_PER_CHANNEL} for filter. * * * {@link OperandType::TENSOR_INT32} for bias (scale set to 0.0, -- GitLab From 8c37651ea9a17181d2b56d3812602c665e9488c5 Mon Sep 17 00:00:00 2001 From: Yin-Chia Yeh Date: Thu, 11 Feb 2021 17:05:49 -0800 Subject: [PATCH 456/790] Camera: add default secure image size key Test: new CTS tests pass Bug: 153663201 Change-Id: Ic185306e0b895b0d5e52a368f2712e97bb0aebcf --- camera/metadata/3.6/Android.bp | 16 +++++++++++ camera/metadata/3.6/types.hal | 51 ++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 camera/metadata/3.6/Android.bp create mode 100644 camera/metadata/3.6/types.hal diff --git a/camera/metadata/3.6/Android.bp b/camera/metadata/3.6/Android.bp new file mode 100644 index 0000000000..d9f3fb82e8 --- /dev/null +++ b/camera/metadata/3.6/Android.bp @@ -0,0 +1,16 @@ +// This file is autogenerated by hidl-gen -Landroidbp. + +hidl_interface { + name: "android.hardware.camera.metadata@3.6", + root: "android.hardware", + srcs: [ + "types.hal", + ], + interfaces: [ + "android.hardware.camera.metadata@3.2", + "android.hardware.camera.metadata@3.3", + "android.hardware.camera.metadata@3.4", + "android.hardware.camera.metadata@3.5", + ], + gen_java: true, +} diff --git a/camera/metadata/3.6/types.hal b/camera/metadata/3.6/types.hal new file mode 100644 index 0000000000..fb957367f8 --- /dev/null +++ b/camera/metadata/3.6/types.hal @@ -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. + */ + +/* + * Autogenerated from camera metadata definitions in + * /system/media/camera/docs/metadata_definitions.xml + * *** DO NOT EDIT BY HAND *** + */ + +package android.hardware.camera.metadata@3.6; + +import android.hardware.camera.metadata@3.2; +import android.hardware.camera.metadata@3.3; +import android.hardware.camera.metadata@3.4; +import android.hardware.camera.metadata@3.5; + +// No new metadata sections added in this revision + +/** + * Main enumeration for defining camera metadata tags added in this revision + * + *

    Partial documentation is included for each tag; for complete documentation, reference + * '/system/media/camera/docs/docs.html' in the corresponding Android source tree.

    + */ +enum CameraMetadataTag : @3.5::CameraMetadataTag { + /** android.scaler.defaultSecureImageSize [static, int32[], public] + * + *

    Default YUV/PRIVATE size to use for requesting secure image buffers.

    + */ + ANDROID_SCALER_DEFAULT_SECURE_IMAGE_SIZE = android.hardware.camera.metadata@3.5::CameraMetadataTag:ANDROID_SCALER_END_3_5, + + ANDROID_SCALER_END_3_6, + +}; + +/* + * Enumeration definitions for the various entries that need them + */ -- GitLab From aea86e089a4f77bc75c1629f070a257bcd6813a8 Mon Sep 17 00:00:00 2001 From: Kumar Anand Date: Wed, 10 Feb 2021 16:22:31 -0800 Subject: [PATCH 457/790] Wifi: Filter usable channels by Coex, Concurrency Add ability to filter usable channel due to coex & concurrency limitations. List of usable channels could be limited due to coex restrictions and also due to concurrency limitations & connection state. Bug: 160212907 Test: VTS - VtsHalWifiV1_5TargetTest Change-Id: Ic36b792b93fc4a6e328b9bc606a5286b8c1fd690 --- wifi/1.5/IWifiChip.hal | 58 ++++++++++++++++--- wifi/1.5/default/hidl_struct_util.cpp | 14 +++++ wifi/1.5/default/hidl_struct_util.h | 1 + wifi/1.5/default/wifi_chip.cpp | 11 +++- wifi/1.5/default/wifi_chip.h | 10 ++-- wifi/1.5/default/wifi_legacy_hal.cpp | 6 +- wifi/1.5/default/wifi_legacy_hal.h | 4 +- .../vts/functional/wifi_chip_hidl_test.cpp | 6 +- 8 files changed, 89 insertions(+), 21 deletions(-) diff --git a/wifi/1.5/IWifiChip.hal b/wifi/1.5/IWifiChip.hal index 209190a759..5a3e2883d5 100644 --- a/wifi/1.5/IWifiChip.hal +++ b/wifi/1.5/IWifiChip.hal @@ -235,20 +235,55 @@ interface IWifiChip extends @1.4::IWifiChip { */ setCountryCode(int8_t[2] code) generates (WifiStatus status); + /** + * Usable Wifi channels filter masks. + */ + enum UsableChannelFilter : uint32_t { + /** + * Filter Wifi channels that should be avoided due to extreme + * cellular coexistence restrictions. Some Wifi channels can have + * extreme interference from/to cellular due to short frequency + * seperation with neighboring cellular channels or when there + * is harmonic and intermodulation interference. Channels which + * only have some performance degradation (e.g. power back off is + * sufficient to deal with coexistence issue) can be included and + * should not be filtered out. + */ + CELLULAR_COEXISTENCE = 1 << 0, + /** + * Filter based on concurrency state. + * Examples: + * - 5GHz SAP operation may be supported in standalone mode, but if + * there is STA connection on 5GHz DFS channel, none of the 5GHz + * channels are usable for SAP if device does not support DFS SAP mode. + * - P2P GO may not be supported on indoor channels in EU during + * standalone mode but if there is a STA connection on indoor channel, + * P2P GO may be supported by some vendors on the same STA channel. + */ + CONCURRENCY = 1 << 1, + }; + /** * Retrieve list of usable Wifi channels for the specified band & * operational modes. * * The list of usable Wifi channels in a given band depends on factors - * like current country code, operational mode (e.g. STA, SAP, CLI, GO, - * TDLS, NAN) and any hard restrictons due to DFS, LTE Coex and - * MCC(multi channel-concurrency). + * like current country code, operational mode (e.g. STA, SAP, WFD-CLI, + * WFD-GO, TDLS, NAN) and other restrictons due to DFS, cellular coexistence + * and conncurency state of the device. * * @param band |WifiBand| for which list of usable channels is requested. * @param ifaceModeMask Bitmask of the modes represented by |WifiIfaceMode| * Bitmask respresents all the modes that the caller is interested - * in (e.g. STA, SAP, CLI, GO, TDLS, NAN). - * Note: Bitmask does not represent concurrency matrix. + * in (e.g. STA, SAP, CLI, GO, TDLS, NAN). E.g. If the caller is + * interested in knowing usable channels for P2P CLI, P2P GO & NAN, + * ifaceModeMask would be set to + * IFACE_MODE_P2P_CLIENT|IFACE_MODE_P2P_GO|IFACE_MODE_NAN. + * @param filterMask Bitmask of filters represented by + * |UsableChannelFilter|. Specifies whether driver should filter + * channels based on additional criteria. If no filter is specified + * driver should return usable channels purely based on regulatory + * constraints. * @return status WifiStatus of the operation. * Possible status codes: * |WifiStatusCode.SUCCESS|, @@ -257,10 +292,15 @@ interface IWifiChip extends @1.4::IWifiChip { * |WifiStatusCode.FAILURE_UNKNOWN| * @return channels List of channels represented by |WifiUsableChannel| * Each entry represents a channel frequency, bandwidth and - * bitmask of operational modes (e.g. STA, SAP, CLI, GO, TDLS, NAN) - * allowed on that channel. - * Note: Bitmask does not represent concurrency matrix. + * bitmask of modes (e.g. STA, SAP, CLI, GO, TDLS, NAN) that are + * allowed on that channel. E.g. If only STA mode can be supported + * on an indoor channel, only the IFACE_MODE_STA bit would be set + * for that channel. If 5GHz SAP cannot be supported, then none of + * the 5GHz channels will have IFACE_MODE_SOFTAP bit set. + * Note: Bits do not represent concurrency state. Each bit only + * represents whether particular mode is allowed on that channel. */ - getUsableChannels(WifiBand band, bitfield ifaceModeMask) + getUsableChannels(WifiBand band, bitfield ifaceModeMask, + bitfield filterMask) generates (WifiStatus status, vec channels); }; diff --git a/wifi/1.5/default/hidl_struct_util.cpp b/wifi/1.5/default/hidl_struct_util.cpp index 7cee4cd868..3c69da5c18 100644 --- a/wifi/1.5/default/hidl_struct_util.cpp +++ b/wifi/1.5/default/hidl_struct_util.cpp @@ -445,6 +445,20 @@ uint32_t convertLegacyWifiInterfaceModeToHidl(uint32_t legacy_iface_mask) { return hidl_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 & 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) { diff --git a/wifi/1.5/default/hidl_struct_util.h b/wifi/1.5/default/hidl_struct_util.h index c0d7bf8f0c..8b81033fac 100644 --- a/wifi/1.5/default/hidl_struct_util.h +++ b/wifi/1.5/default/hidl_struct_util.h @@ -208,6 +208,7 @@ bool convertLegacyVectorOfRttResultToHidl( std::vector* 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_usable_channels, std::vector* hidl_usable_channels); diff --git a/wifi/1.5/default/wifi_chip.cpp b/wifi/1.5/default/wifi_chip.cpp index 2dc73148a6..0450a7bfe1 100644 --- a/wifi/1.5/default/wifi_chip.cpp +++ b/wifi/1.5/default/wifi_chip.cpp @@ -740,10 +740,11 @@ Return WifiChip::setCountryCode(const hidl_array& code, Return WifiChip::getUsableChannels( WifiBand band, hidl_bitfield ifaceModeMask, + hidl_bitfield filterMask, getUsableChannels_cb _hidl_cb) { return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, &WifiChip::getUsableChannelsInternal, _hidl_cb, band, - ifaceModeMask); + ifaceModeMask, filterMask); } void WifiChip::invalidateAndRemoveAllIfaces() { @@ -1500,13 +1501,17 @@ WifiStatus WifiChip::setCountryCodeInternal(const std::array& code) { } std::pair> -WifiChip::getUsableChannelsInternal(WifiBand band, uint32_t ifaceModeMask) { +WifiChip::getUsableChannelsInternal(WifiBand band, uint32_t ifaceModeMask, + uint32_t filterMask) { legacy_hal::wifi_error legacy_status; std::vector legacy_usable_channels; std::tie(legacy_status, legacy_usable_channels) = legacy_hal_.lock()->getUsableChannels( hidl_struct_util::convertHidlWifiBandToLegacyMacBand(band), - hidl_struct_util::convertHidlWifiIfaceModeToLegacy(ifaceModeMask)); + hidl_struct_util::convertHidlWifiIfaceModeToLegacy(ifaceModeMask), + hidl_struct_util::convertHidlUsableChannelFilterToLegacy( + filterMask)); + if (legacy_status != legacy_hal::WIFI_SUCCESS) { return {createWifiStatusFromLegacyError(legacy_status), {}}; } diff --git a/wifi/1.5/default/wifi_chip.h b/wifi/1.5/default/wifi_chip.h index d542792cda..b4ed30ed69 100644 --- a/wifi/1.5/default/wifi_chip.h +++ b/wifi/1.5/default/wifi_chip.h @@ -180,9 +180,10 @@ class WifiChip : public V1_5::IWifiChip { setCoexUnsafeChannels_cb hidl_status_cb) override; Return setCountryCode(const hidl_array& code, setCountryCode_cb _hidl_cb) override; - Return getUsableChannels(WifiBand band, - hidl_bitfield ifaceModeMask, - getUsableChannels_cb _hidl_cb) override; + Return getUsableChannels( + WifiBand band, hidl_bitfield ifaceModeMask, + hidl_bitfield filterMask, + getUsableChannels_cb _hidl_cb) override; private: void invalidateAndRemoveAllIfaces(); @@ -265,7 +266,8 @@ class WifiChip : public V1_5::IWifiChip { std::vector unsafe_channels, uint32_t restrictions); WifiStatus setCountryCodeInternal(const std::array& code); std::pair> - getUsableChannelsInternal(WifiBand band, uint32_t ifaceModeMask); + getUsableChannelsInternal(WifiBand band, uint32_t ifaceModeMask, + uint32_t filterMask); WifiStatus handleChipConfiguration( std::unique_lock* lock, ChipModeId mode_id); WifiStatus registerDebugRingBufferCallback(); diff --git a/wifi/1.5/default/wifi_legacy_hal.cpp b/wifi/1.5/default/wifi_legacy_hal.cpp index 94603b3053..f5ca753824 100644 --- a/wifi/1.5/default/wifi_legacy_hal.cpp +++ b/wifi/1.5/default/wifi_legacy_hal.cpp @@ -1638,12 +1638,14 @@ wifi_error WifiLegacyHal::setDtimConfig(const std::string& iface_name, } std::pair> -WifiLegacyHal::getUsableChannels(uint32_t band_mask, uint32_t iface_mode_mask) { +WifiLegacyHal::getUsableChannels(uint32_t band_mask, uint32_t iface_mode_mask, + uint32_t filter_mask) { std::vector 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, channels.size(), &size, + global_handle_, band_mask, iface_mode_mask, filter_mask, + channels.size(), &size, reinterpret_cast(channels.data())); CHECK(size >= 0 && size <= kMaxWifiUsableChannels); channels.resize(size); diff --git a/wifi/1.5/default/wifi_legacy_hal.h b/wifi/1.5/default/wifi_legacy_hal.h index dc641aef28..03ca8412ce 100644 --- a/wifi/1.5/default/wifi_legacy_hal.h +++ b/wifi/1.5/default/wifi_legacy_hal.h @@ -313,6 +313,8 @@ using ::WIFI_SUCCESS; using ::wifi_tx_packet_fate; using ::wifi_tx_report; using ::wifi_usable_channel; +using ::WIFI_USABLE_CHANNEL_FILTER_CELLULAR_COEXISTENCE; +using ::WIFI_USABLE_CHANNEL_FILTER_CONCURRENCY; using ::WLAN_MAC_2_4_BAND; using ::WLAN_MAC_5_0_BAND; using ::WLAN_MAC_60_0_BAND; @@ -705,7 +707,7 @@ class WifiLegacyHal { // Retrieve the list of usable channels in the requested bands // for the requested modes std::pair> getUsableChannels( - uint32_t band_mask, uint32_t iface_mode_mask); + uint32_t band_mask, uint32_t iface_mode_mask, uint32_t filter_mask); private: // Retrieve interface handles for all the available interfaces. diff --git a/wifi/1.5/vts/functional/wifi_chip_hidl_test.cpp b/wifi/1.5/vts/functional/wifi_chip_hidl_test.cpp index 509f1bddc7..5ac747de22 100644 --- a/wifi/1.5/vts/functional/wifi_chip_hidl_test.cpp +++ b/wifi/1.5/vts/functional/wifi_chip_hidl_test.cpp @@ -195,10 +195,12 @@ TEST_P(WifiChipHidlTest, setCountryCode) { TEST_P(WifiChipHidlTest, getUsableChannels) { uint32_t ifaceModeMask = WifiIfaceMode::IFACE_MODE_P2P_CLIENT | WifiIfaceMode::IFACE_MODE_P2P_GO; + uint32_t filterMask = IWifiChip::UsableChannelFilter::CELLULAR_COEXISTENCE | + IWifiChip::UsableChannelFilter::CONCURRENCY; configureChipForIfaceType(IfaceType::STA, true); WifiBand band = WifiBand::BAND_24GHZ_5GHZ_6GHZ; - const auto& statusNonEmpty = - HIDL_INVOKE(wifi_chip_, getUsableChannels, band, ifaceModeMask); + const auto& statusNonEmpty = HIDL_INVOKE(wifi_chip_, getUsableChannels, + band, ifaceModeMask, filterMask); if (statusNonEmpty.first.code != WifiStatusCode::SUCCESS) { EXPECT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED, statusNonEmpty.first.code); -- GitLab From a2c3db1e70bfb661148bdc32776f2efd219afae6 Mon Sep 17 00:00:00 2001 From: Anthony Stange Date: Wed, 16 Dec 2020 15:04:02 -0500 Subject: [PATCH 458/790] Add VTS tests for new methods in contexthub HAL 1.2 Bug: 166846988 Test: Run against production HAL Change-Id: I9e22f41736d54501cd74c7d56f61db8e771529df --- .../VtsHalContexthubV1_0TargetTest.cpp | 35 +--- .../VtsHalContexthubV1_1TargetTest.cpp | 5 +- .../VtsHalContexthubV1_2TargetTest.cpp | 171 +++++++++++++++++- .../common/vts/ContexthubCallbackBase.h | 3 +- contexthub/common/vts/VtsHalContexthubUtils.h | 27 +++ 5 files changed, 203 insertions(+), 38 deletions(-) diff --git a/contexthub/1.0/vts/functional/VtsHalContexthubV1_0TargetTest.cpp b/contexthub/1.0/vts/functional/VtsHalContexthubV1_0TargetTest.cpp index 8a90173bf1..356ad97327 100644 --- a/contexthub/1.0/vts/functional/VtsHalContexthubV1_0TargetTest.cpp +++ b/contexthub/1.0/vts/functional/VtsHalContexthubV1_0TargetTest.cpp @@ -52,40 +52,17 @@ using ::android::hardware::contexthub::vts_utils::ContexthubCallbackBase; using ::android::hardware::contexthub::vts_utils::ContexthubHidlTestBase; using ::android::hardware::contexthub::vts_utils::getHalAndHubIdList; using ::android::hardware::contexthub::vts_utils::getHubsSync; +using ::android::hardware::contexthub::vts_utils::kNonExistentAppId; +using ::android::hardware::contexthub::vts_utils::waitForCallback; namespace { -// App ID with vendor "GoogT" (Google Testing), app identifier 0x555555. This -// app ID is reserved and must never appear in the list of loaded apps. -constexpr uint64_t kNonExistentAppId = 0x476f6f6754555555; - const std::vector> kTestParameters = getHalAndHubIdList(); class ContexthubHidlTest : public ContexthubHidlTestBase {}; -// Wait for a callback to occur (signaled by the given future) up to the -// provided timeout. If the future is invalid or the callback does not come -// within the given time, returns false. -template -bool waitForCallback(std::future future, ReturnType* result, - std::chrono::milliseconds timeout = std::chrono::seconds(5)) { - auto expiration = std::chrono::system_clock::now() + timeout; - - EXPECT_NE(result, nullptr); - EXPECT_TRUE(future.valid()); - if (result != nullptr && future.valid()) { - std::future_status status = future.wait_until(expiration); - EXPECT_NE(status, std::future_status::timeout) << "Timed out waiting for callback"; - - if (status == std::future_status::ready) { - *result = future.get(); - return true; - } - } - - return false; -} +class ContexthubCallbackV1_0 : public ContexthubCallbackBase {}; // Ensures that the metadata reported in getHubs() is sane TEST_P(ContexthubHidlTest, TestGetHubs) { @@ -110,7 +87,7 @@ TEST_P(ContexthubHidlTest, TestGetHubs) { TEST_P(ContexthubHidlTest, TestRegisterCallback) { ALOGD("TestRegisterCallback called, hubId %" PRIu32, getHubId()); - ASSERT_OK(registerCallback(new ContexthubCallbackBase())); + ASSERT_OK(registerCallback(new ContexthubCallbackV1_0())); } TEST_P(ContexthubHidlTest, TestRegisterNullCallback) { @@ -119,7 +96,7 @@ TEST_P(ContexthubHidlTest, TestRegisterNullCallback) { } // Helper callback that puts the async appInfo callback data into a promise -class QueryAppsCallback : public ContexthubCallbackBase { +class QueryAppsCallback : public ContexthubCallbackV1_0 { public: virtual Return handleAppsInfo(const hidl_vec& appInfo) override { ALOGD("Got app info callback with %zu apps", appInfo.size()); @@ -150,7 +127,7 @@ TEST_P(ContexthubHidlTest, TestQueryApps) { // Helper callback that puts the TransactionResult for the expectedTxnId into a // promise -class TxnResultCallback : public ContexthubCallbackBase { +class TxnResultCallback : public ContexthubCallbackV1_0 { public: virtual Return handleTxnResult(uint32_t txnId, TransactionResult result) override { ALOGD("Got transaction result callback for txnId %" PRIu32 " (expecting %" PRIu32 diff --git a/contexthub/1.1/vts/functional/VtsHalContexthubV1_1TargetTest.cpp b/contexthub/1.1/vts/functional/VtsHalContexthubV1_1TargetTest.cpp index 5f1dad97cb..acf4be0c45 100644 --- a/contexthub/1.1/vts/functional/VtsHalContexthubV1_1TargetTest.cpp +++ b/contexthub/1.1/vts/functional/VtsHalContexthubV1_1TargetTest.cpp @@ -31,6 +31,7 @@ #include +using ::android::hardware::contexthub::V1_0::IContexthubCallback; using ::android::hardware::contexthub::V1_1::IContexthub; using ::android::hardware::contexthub::V1_1::Setting; using ::android::hardware::contexthub::V1_1::SettingValue; @@ -45,10 +46,12 @@ const std::vector> kTestParameters = class ContexthubHidlTest : public ContexthubHidlTestBase {}; +class ContexthubCallbackV1_0 : public ContexthubCallbackBase {}; + TEST_P(ContexthubHidlTest, TestOnSettingChanged) { // In VTS, we only test that sending the values doesn't cause things to blow up - other test // suites verify the expected E2E behavior in CHRE - ASSERT_OK(registerCallback(new ContexthubCallbackBase())); + ASSERT_OK(registerCallback(new ContexthubCallbackV1_0())); hubApi->onSettingChanged(Setting::LOCATION, SettingValue::DISABLED); hubApi->onSettingChanged(Setting::LOCATION, SettingValue::ENABLED); ASSERT_OK(registerCallback(nullptr)); diff --git a/contexthub/1.2/vts/functional/VtsHalContexthubV1_2TargetTest.cpp b/contexthub/1.2/vts/functional/VtsHalContexthubV1_2TargetTest.cpp index 782edae610..c50d43c137 100644 --- a/contexthub/1.2/vts/functional/VtsHalContexthubV1_2TargetTest.cpp +++ b/contexthub/1.2/vts/functional/VtsHalContexthubV1_2TargetTest.cpp @@ -32,45 +32,202 @@ #include +using ::android::sp; +using ::android::hardware::hidl_string; +using ::android::hardware::hidl_vec; +using ::android::hardware::Return; +using ::android::hardware::Void; +using ::android::hardware::contexthub::V1_0::ContextHub; +using ::android::hardware::contexthub::V1_0::Result; +using ::android::hardware::contexthub::V1_0::TransactionResult; using ::android::hardware::contexthub::V1_1::SettingValue; +using ::android::hardware::contexthub::V1_2::ContextHubMsg; +using ::android::hardware::contexthub::V1_2::HubAppInfo; using ::android::hardware::contexthub::V1_2::IContexthub; +using ::android::hardware::contexthub::V1_2::IContexthubCallback; using ::android::hardware::contexthub::V1_2::Setting; +using ::android::hardware::contexthub::vts_utils::asBaseType; using ::android::hardware::contexthub::vts_utils::ContexthubCallbackBase; using ::android::hardware::contexthub::vts_utils::ContexthubHidlTestBase; using ::android::hardware::contexthub::vts_utils::getHalAndHubIdList; +using ::android::hardware::contexthub::vts_utils::kNonExistentAppId; +using ::android::hardware::contexthub::vts_utils::waitForCallback; namespace { const std::vector> kTestParameters = getHalAndHubIdList(); -class ContexthubHidlTest : public ContexthubHidlTestBase {}; +class ContexthubCallbackV1_2 : public ContexthubCallbackBase { + public: + virtual Return handleClientMsg_1_2( + const ContextHubMsg& /*msg*/, + const hidl_vec& /*msgContentPerms*/) override { + ALOGD("Got client message callback"); + return Void(); + } + + virtual Return handleAppsInfo_1_2(const hidl_vec& /*appInfo*/) override { + ALOGD("Got app info callback"); + return Void(); + } +}; + +class ContexthubHidlTest : public ContexthubHidlTestBase { + public: + Result registerCallback_1_2(sp cb) { + return hubApi->registerCallback_1_2(getHubId(), cb); + } +}; + +// Ensures that the metadata reported in getHubs_1_2() is valid +TEST_P(ContexthubHidlTest, TestGetHubs_1_2) { + hidl_vec hubList; + hubApi->getHubs_1_2( + [&hubList](const hidl_vec& hubs, + const hidl_vec& /*hubPermissions*/) { hubList = hubs; }); + + ALOGD("System reports %zu hubs", hubList.size()); + + for (const ContextHub& hub : hubList) { + ALOGD("Checking hub ID %" PRIu32, hub.hubId); + + EXPECT_FALSE(hub.name.empty()); + EXPECT_FALSE(hub.vendor.empty()); + EXPECT_FALSE(hub.toolchain.empty()); + EXPECT_GT(hub.peakMips, 0); + EXPECT_GE(hub.stoppedPowerDrawMw, 0); + EXPECT_GE(hub.sleepPowerDrawMw, 0); + EXPECT_GT(hub.peakPowerDrawMw, 0); + + // Minimum 128 byte MTU as required by CHRE API v1.0 + EXPECT_GE(hub.maxSupportedMsgLen, UINT32_C(128)); + } +} + +TEST_P(ContexthubHidlTest, TestRegisterCallback) { + ALOGD("TestRegisterCallback called, hubId %" PRIu32, getHubId()); + ASSERT_OK(registerCallback_1_2(new ContexthubCallbackV1_2())); +} + +TEST_P(ContexthubHidlTest, TestRegisterNullCallback) { + ALOGD("TestRegisterNullCallback called, hubId %" PRIu32, getHubId()); + ASSERT_OK(registerCallback_1_2(nullptr)); +} // In VTS, we only test that sending the values doesn't cause things to blow up - other test // suites verify the expected E2E behavior in CHRE TEST_P(ContexthubHidlTest, TestOnWifiSettingChanged) { - ASSERT_OK(registerCallback(new ContexthubCallbackBase())); + ASSERT_OK(registerCallback_1_2(new ContexthubCallbackV1_2())); hubApi->onSettingChanged_1_2(Setting::WIFI_AVAILABLE, SettingValue::DISABLED); hubApi->onSettingChanged_1_2(Setting::WIFI_AVAILABLE, SettingValue::ENABLED); - ASSERT_OK(registerCallback(nullptr)); + ASSERT_OK(registerCallback_1_2(nullptr)); } TEST_P(ContexthubHidlTest, TestOnAirplaneModeSettingChanged) { - ASSERT_OK(registerCallback(new ContexthubCallbackBase())); + ASSERT_OK(registerCallback_1_2(new ContexthubCallbackV1_2())); hubApi->onSettingChanged_1_2(Setting::AIRPLANE_MODE, SettingValue::DISABLED); hubApi->onSettingChanged_1_2(Setting::AIRPLANE_MODE, SettingValue::ENABLED); - ASSERT_OK(registerCallback(nullptr)); + ASSERT_OK(registerCallback_1_2(nullptr)); } TEST_P(ContexthubHidlTest, TestOnGlobalMicDisableSettingChanged) { - ASSERT_OK(registerCallback(new ContexthubCallbackBase())); + ASSERT_OK(registerCallback_1_2(new ContexthubCallbackV1_2())); hubApi->onSettingChanged_1_2(Setting::GLOBAL_MIC_DISABLE, SettingValue::DISABLED); hubApi->onSettingChanged_1_2(Setting::GLOBAL_MIC_DISABLE, SettingValue::ENABLED); - ASSERT_OK(registerCallback(nullptr)); + ASSERT_OK(registerCallback_1_2(nullptr)); +} + +// Helper callback that puts the async appInfo callback data into a promise +class QueryAppsCallback : public ContexthubCallbackV1_2 { + public: + virtual Return handleAppsInfo_1_2(const hidl_vec& appInfo) override { + ALOGD("Got app info callback with %zu apps", appInfo.size()); + promise.set_value(appInfo); + return Void(); + } + + std::promise> promise; +}; + +// Calls queryApps() and checks the returned metadata +TEST_P(ContexthubHidlTest, TestQueryApps) { + hidl_vec hubPerms; + hubApi->getHubs_1_2([&hubPerms](const hidl_vec& /*hubs*/, + const hidl_vec& hubPermissions) { + hubPerms = hubPermissions; + }); + + ALOGD("TestQueryApps called, hubId %u", getHubId()); + sp cb = new QueryAppsCallback(); + ASSERT_OK(registerCallback_1_2(cb)); + + Result result = hubApi->queryApps(getHubId()); + ASSERT_OK(result); + + ALOGD("Waiting for app info callback"); + hidl_vec appList; + ASSERT_TRUE(waitForCallback(cb->promise.get_future(), &appList)); + for (const HubAppInfo& appInfo : appList) { + EXPECT_NE(appInfo.info_1_0.appId, UINT64_C(0)); + EXPECT_NE(appInfo.info_1_0.appId, kNonExistentAppId); + for (std::string permission : appInfo.permissions) { + ASSERT_TRUE(hubPerms.contains(permission)); + } + } +} + +// Helper callback that puts the TransactionResult for the expectedTxnId into a +// promise +class TxnResultCallback : public ContexthubCallbackV1_2 { + public: + virtual Return handleTxnResult(uint32_t txnId, TransactionResult result) override { + ALOGD("Got transaction result callback for txnId %" PRIu32 " (expecting %" PRIu32 + ") with result %" PRId32, + txnId, expectedTxnId, result); + if (txnId == expectedTxnId) { + promise.set_value(result); + } + return Void(); + } + + uint32_t expectedTxnId = 0; + std::promise promise; +}; + +// Parameterized fixture that sets the callback to TxnResultCallback +class ContexthubTxnTest : public ContexthubHidlTest { + public: + virtual void SetUp() override { + ContexthubHidlTest::SetUp(); + ASSERT_OK(registerCallback_1_2(cb)); + } + + sp cb = new TxnResultCallback(); +}; + +TEST_P(ContexthubTxnTest, TestSendMessageToNonExistentNanoApp) { + ContextHubMsg msg; + msg.msg_1_0.appName = kNonExistentAppId; + msg.msg_1_0.msgType = 1; + msg.msg_1_0.msg.resize(4); + std::fill(msg.msg_1_0.msg.begin(), msg.msg_1_0.msg.end(), 0); + + ALOGD("Sending message to non-existent nanoapp"); + Result result = hubApi->sendMessageToHub_1_2(getHubId(), msg); + if (result != Result::OK && result != Result::BAD_PARAMS && + result != Result::TRANSACTION_FAILED) { + FAIL() << "Got result " << asBaseType(result) << ", expected OK, BAD_PARAMS" + << ", or TRANSACTION_FAILED"; + } } GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ContexthubHidlTest); INSTANTIATE_TEST_SUITE_P(HubIdSpecificTests, ContexthubHidlTest, testing::ValuesIn(kTestParameters), android::hardware::PrintInstanceTupleNameToString<>); +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ContexthubTxnTest); +INSTANTIATE_TEST_SUITE_P(HubIdSpecificTests, ContexthubTxnTest, testing::ValuesIn(kTestParameters), + android::hardware::PrintInstanceTupleNameToString<>); + } // anonymous namespace diff --git a/contexthub/common/vts/ContexthubCallbackBase.h b/contexthub/common/vts/ContexthubCallbackBase.h index 124a11601a..24d6c52705 100644 --- a/contexthub/common/vts/ContexthubCallbackBase.h +++ b/contexthub/common/vts/ContexthubCallbackBase.h @@ -27,7 +27,8 @@ namespace vts_utils { // Base callback implementation that just logs all callbacks by default, but // records a failure if -class ContexthubCallbackBase : public V1_0::IContexthubCallback { +template +class ContexthubCallbackBase : public CallbackType { public: virtual Return handleClientMsg(const V1_0::ContextHubMsg& /*msg*/) override { ALOGD("Got client message callback"); diff --git a/contexthub/common/vts/VtsHalContexthubUtils.h b/contexthub/common/vts/VtsHalContexthubUtils.h index 8f9b6946d9..dff1865f4c 100644 --- a/contexthub/common/vts/VtsHalContexthubUtils.h +++ b/contexthub/common/vts/VtsHalContexthubUtils.h @@ -30,6 +30,10 @@ namespace hardware { namespace contexthub { namespace vts_utils { +// App ID with vendor "GoogT" (Google Testing), app identifier 0x555555. This +// app ID is reserved and must never appear in the list of loaded apps. +constexpr uint64_t kNonExistentAppId = 0x476f6f6754555555; + #define ASSERT_OK(result) ASSERT_EQ(result, ::android::hardware::contexthub::V1_0::Result::OK) #define EXPECT_OK(result) EXPECT_EQ(result, ::android::hardware::contexthub::V1_0::Result::OK) @@ -64,6 +68,29 @@ static std::vector> getHalAndHubIdList() { return parameters; } +// Wait for a callback to occur (signaled by the given future) up to the +// provided timeout. If the future is invalid or the callback does not come +// within the given time, returns false. +template +bool waitForCallback(std::future future, ReturnType* result, + std::chrono::milliseconds timeout = std::chrono::seconds(5)) { + auto expiration = std::chrono::system_clock::now() + timeout; + + EXPECT_NE(result, nullptr); + EXPECT_TRUE(future.valid()); + if (result != nullptr && future.valid()) { + std::future_status status = future.wait_until(expiration); + EXPECT_NE(status, std::future_status::timeout) << "Timed out waiting for callback"; + + if (status == std::future_status::ready) { + *result = future.get(); + return true; + } + } + + return false; +} + } // namespace vts_utils } // namespace contexthub } // namespace hardware -- GitLab From d1f16b824b59eb33033c541d805c0f5b1d93bb4c Mon Sep 17 00:00:00 2001 From: Joshua Mccloskey Date: Tue, 9 Feb 2021 03:46:16 +0000 Subject: [PATCH 459/790] Revert^2 "Revert "Add enroll_1_1 with preview window id"" 35e8d370fe7b4ecde43bdc919aa6361e81be67f8 Change-Id: I8907905ae929af3ad7b1e66477cec589e4f3f09f --- biometrics/face/1.1/IBiometricsFace.hal | 39 +---------------- .../face/1.1/default/BiometricsFace.cpp | 8 ---- biometrics/face/1.1/default/BiometricsFace.h | 4 -- .../VtsHalBiometricsFaceV1_1TargetTest.cpp | 42 ------------------- 4 files changed, 2 insertions(+), 91 deletions(-) diff --git a/biometrics/face/1.1/IBiometricsFace.hal b/biometrics/face/1.1/IBiometricsFace.hal index 84e7443c9c..975001f30b 100644 --- a/biometrics/face/1.1/IBiometricsFace.hal +++ b/biometrics/face/1.1/IBiometricsFace.hal @@ -15,7 +15,6 @@ */ package android.hardware.biometrics.face@1.1; - import @1.0::IBiometricsFace; import @1.0::Status; import @1.0::Feature; @@ -78,40 +77,6 @@ interface IBiometricsFace extends @1.0::IBiometricsFace { * enrollment. Note that all features are enabled by default. * @return status The status of this method call. */ - enrollRemotely(vec hat, uint32_t timeoutSec, vec disabledFeatures) - generates (Status status); - - /** - * Enrolls a user's face. - * - * Note that the Hardware Authentication Token must be valid for the - * duration of enrollment and thus should be explicitly invalidated by a - * call to revokeChallenge() when enrollment is complete, to reduce the - * window of opportunity to re-use the challenge and HAT. For example, - * Settings calls generateChallenge() once to allow the user to enroll one - * or more faces or toggle secure settings without having to re-enter the - * PIN/pattern/password. Once the user completes the operation, Settings - * invokes revokeChallenge() to close the transaction. If the HAT is expired, - * the implementation must invoke onError with UNABLE_TO_PROCESS. - * - * This method triggers the IBiometricsFaceClientCallback#onEnrollResult() - * method. - * - * @param hat A valid Hardware Authentication Token, generated as a result - * of a generateChallenge() challenge being wrapped by the gatekeeper - * after a successful strong authentication request. - * @param timeoutSec A timeout in seconds, after which this enroll - * attempt is cancelled. Note that the framework can continue - * enrollment by calling this again with a valid HAT. This timeout is - * expected to be used to limit power usage if the device becomes idle - * during enrollment. The implementation is expected to send - * ERROR_TIMEOUT if this happens. - * @param disabledFeatures A list of features to be disabled during - * enrollment. Note that all features are enabled by default. - * @param windowId optional ID of a camera preview window for a - * single-camera device. Must be null if not used. - * @return status The status of this method call. - */ - enroll_1_1(vec hat, uint32_t timeoutSec, vec disabledFeatures, - handle windowId) generates (Status status); + enrollRemotely(vec hat, uint32_t timeoutSec, + vec disabledFeatures) generates (Status status); }; diff --git a/biometrics/face/1.1/default/BiometricsFace.cpp b/biometrics/face/1.1/default/BiometricsFace.cpp index 57b3a92690..f2c9bf0af2 100644 --- a/biometrics/face/1.1/default/BiometricsFace.cpp +++ b/biometrics/face/1.1/default/BiometricsFace.cpp @@ -111,14 +111,6 @@ Return BiometricsFace::resetLockout(const hidl_vec& /* hat */) } // Methods from ::android::hardware::biometrics::face::V1_1::IBiometricsFace follow. -Return BiometricsFace::enroll_1_1(const hidl_vec& /* hat */, - uint32_t /* timeoutSec */, - const hidl_vec& /* disabledFeatures */, - const hidl_handle& /* windowId */) { - mClientCallback->onError(kDeviceId, mUserId, FaceError::UNABLE_TO_PROCESS, 0 /* vendorCode */); - return Status::OK; -} - Return BiometricsFace::enrollRemotely(const hidl_vec& /* hat */, uint32_t /* timeoutSec */, const hidl_vec& /* disabledFeatures */) { diff --git a/biometrics/face/1.1/default/BiometricsFace.h b/biometrics/face/1.1/default/BiometricsFace.h index 5ce5771eae..5620b45a43 100644 --- a/biometrics/face/1.1/default/BiometricsFace.h +++ b/biometrics/face/1.1/default/BiometricsFace.h @@ -72,10 +72,6 @@ class BiometricsFace : public V1_1::IBiometricsFace { Return resetLockout(const hidl_vec& hat) override; // Methods from ::android::hardware::biometrics::face::V1_1::IBiometricsFace follow. - Return enroll_1_1(const hidl_vec& hat, uint32_t timeoutSec, - const hidl_vec& disabledFeatures, - const hidl_handle& windowId) override; - Return enrollRemotely(const hidl_vec& hat, uint32_t timeoutSec, const hidl_vec& disabledFeatures) override; diff --git a/biometrics/face/1.1/vts/functional/VtsHalBiometricsFaceV1_1TargetTest.cpp b/biometrics/face/1.1/vts/functional/VtsHalBiometricsFaceV1_1TargetTest.cpp index 0077c8c728..9ecaab8920 100644 --- a/biometrics/face/1.1/vts/functional/VtsHalBiometricsFaceV1_1TargetTest.cpp +++ b/biometrics/face/1.1/vts/functional/VtsHalBiometricsFaceV1_1TargetTest.cpp @@ -30,7 +30,6 @@ #include using android::sp; -using android::hardware::hidl_handle; using android::hardware::hidl_vec; using android::hardware::Return; using android::hardware::Void; @@ -117,47 +116,6 @@ class FaceHidlTest : public ::testing::TestWithParam { sp mCallback; }; -// enroll with an invalid (all zeroes) HAT should fail. -TEST_P(FaceHidlTest, Enroll1_1ZeroHatTest) { - // Filling HAT with zeros - hidl_vec token(69); - for (size_t i = 0; i < 69; i++) { - token[i] = 0; - } - - hidl_handle windowId = nullptr; - Return ret = mService->enroll_1_1(token, kTimeoutSec, {}, windowId); - ASSERT_EQ(Status::OK, static_cast(ret)); - - // onError should be called with a meaningful (nonzero) error. - auto res = mCallback->WaitForCallback(kCallbackNameOnError); - EXPECT_TRUE(res.no_timeout); - EXPECT_EQ(kUserId, res.args->userId); - EXPECT_EQ(FaceError::UNABLE_TO_PROCESS, res.args->error); -} - -// enroll with an invalid HAT should fail. -TEST_P(FaceHidlTest, Enroll1_1GarbageHatTest) { - // Filling HAT with pseudorandom invalid data. - // Using default seed to make the test reproducible. - std::mt19937 gen(std::mt19937::default_seed); - std::uniform_int_distribution dist; - hidl_vec token(69); - for (size_t i = 0; i < 69; ++i) { - token[i] = dist(gen); - } - - hidl_handle windowId = nullptr; - Return ret = mService->enroll_1_1(token, kTimeoutSec, {}, windowId); - ASSERT_EQ(Status::OK, static_cast(ret)); - - // onError should be called with a meaningful (nonzero) error. - auto res = mCallback->WaitForCallback(kCallbackNameOnError); - EXPECT_TRUE(res.no_timeout); - EXPECT_EQ(kUserId, res.args->userId); - EXPECT_EQ(FaceError::UNABLE_TO_PROCESS, res.args->error); -} - // enroll with an invalid (all zeroes) HAT should fail. TEST_P(FaceHidlTest, EnrollRemotelyZeroHatTest) { // Filling HAT with zeros -- GitLab From 65eddd20ece3a26c6f557c15f6247e37faffce9c Mon Sep 17 00:00:00 2001 From: Joshua Mccloskey Date: Tue, 9 Feb 2021 03:46:16 +0000 Subject: [PATCH 460/790] Revert^2 "Move default implementation from 1.1 to 1.0" 94992158c9242a74dd8bdea17468db2d451711ca Change-Id: I6f52d0e49c3a6c362a7333adfe07a0103943e456 --- biometrics/face/{1.1 => 1.0}/default/Android.bp | 5 ++--- biometrics/face/{1.1 => 1.0}/default/BiometricsFace.cpp | 8 -------- biometrics/face/{1.1 => 1.0}/default/BiometricsFace.h | 8 ++------ .../android.hardware.biometrics.face@1.0-service.rc} | 2 +- .../face/{1.1 => 1.0}/default/manifest_face_default.xml | 2 +- biometrics/face/{1.1 => 1.0}/default/service.cpp | 6 +++--- 6 files changed, 9 insertions(+), 22 deletions(-) rename biometrics/face/{1.1 => 1.0}/default/Android.bp (85%) rename biometrics/face/{1.1 => 1.0}/default/BiometricsFace.cpp (89%) rename biometrics/face/{1.1 => 1.0}/default/BiometricsFace.h (87%) rename biometrics/face/{1.1/default/android.hardware.biometrics.face@1.1-service.rc => 1.0/default/android.hardware.biometrics.face@1.0-service.rc} (75%) rename biometrics/face/{1.1 => 1.0}/default/manifest_face_default.xml (90%) rename biometrics/face/{1.1 => 1.0}/default/service.cpp (88%) diff --git a/biometrics/face/1.1/default/Android.bp b/biometrics/face/1.0/default/Android.bp similarity index 85% rename from biometrics/face/1.1/default/Android.bp rename to biometrics/face/1.0/default/Android.bp index 360071f3dd..d6ff087ee6 100644 --- a/biometrics/face/1.1/default/Android.bp +++ b/biometrics/face/1.0/default/Android.bp @@ -15,10 +15,10 @@ */ cc_binary { - name: "android.hardware.biometrics.face@1.1-service.example", + name: "android.hardware.biometrics.face@1.0-service.example", defaults: ["hidl_defaults"], vendor: true, - init_rc: ["android.hardware.biometrics.face@1.1-service.rc"], + init_rc: ["android.hardware.biometrics.face@1.0-service.rc"], vintf_fragments: ["manifest_face_default.xml"], relative_install_path: "hw", proprietary: true, @@ -31,6 +31,5 @@ cc_binary { "libutils", "liblog", "android.hardware.biometrics.face@1.0", - "android.hardware.biometrics.face@1.1", ], } diff --git a/biometrics/face/1.1/default/BiometricsFace.cpp b/biometrics/face/1.0/default/BiometricsFace.cpp similarity index 89% rename from biometrics/face/1.1/default/BiometricsFace.cpp rename to biometrics/face/1.0/default/BiometricsFace.cpp index f2c9bf0af2..97dc4690be 100644 --- a/biometrics/face/1.1/default/BiometricsFace.cpp +++ b/biometrics/face/1.0/default/BiometricsFace.cpp @@ -110,12 +110,4 @@ Return BiometricsFace::resetLockout(const hidl_vec& /* hat */) return Status::OK; } -// Methods from ::android::hardware::biometrics::face::V1_1::IBiometricsFace follow. -Return BiometricsFace::enrollRemotely(const hidl_vec& /* hat */, - uint32_t /* timeoutSec */, - const hidl_vec& /* disabledFeatures */) { - mClientCallback->onError(kDeviceId, mUserId, FaceError::UNABLE_TO_PROCESS, 0 /* vendorCode */); - return Status::OK; -} - } // namespace android::hardware::biometrics::face::implementation diff --git a/biometrics/face/1.1/default/BiometricsFace.h b/biometrics/face/1.0/default/BiometricsFace.h similarity index 87% rename from biometrics/face/1.1/default/BiometricsFace.h rename to biometrics/face/1.0/default/BiometricsFace.h index 5620b45a43..1d99ed26bc 100644 --- a/biometrics/face/1.1/default/BiometricsFace.h +++ b/biometrics/face/1.0/default/BiometricsFace.h @@ -16,7 +16,7 @@ #pragma once -#include +#include #include #include #include @@ -34,7 +34,7 @@ using ::android::hardware::biometrics::face::V1_0::Feature; using ::android::hardware::biometrics::face::V1_0::IBiometricsFaceClientCallback; using ::android::hardware::biometrics::face::V1_0::Status; -class BiometricsFace : public V1_1::IBiometricsFace { +class BiometricsFace : public V1_0::IBiometricsFace { public: BiometricsFace(); @@ -71,10 +71,6 @@ class BiometricsFace : public V1_1::IBiometricsFace { Return resetLockout(const hidl_vec& hat) override; - // Methods from ::android::hardware::biometrics::face::V1_1::IBiometricsFace follow. - Return enrollRemotely(const hidl_vec& hat, uint32_t timeoutSec, - const hidl_vec& disabledFeatures) override; - private: std::mt19937 mRandom; int32_t mUserId; diff --git a/biometrics/face/1.1/default/android.hardware.biometrics.face@1.1-service.rc b/biometrics/face/1.0/default/android.hardware.biometrics.face@1.0-service.rc similarity index 75% rename from biometrics/face/1.1/default/android.hardware.biometrics.face@1.1-service.rc rename to biometrics/face/1.0/default/android.hardware.biometrics.face@1.0-service.rc index 687e2d8c86..6c7362f2bb 100644 --- a/biometrics/face/1.1/default/android.hardware.biometrics.face@1.1-service.rc +++ b/biometrics/face/1.0/default/android.hardware.biometrics.face@1.0-service.rc @@ -1,4 +1,4 @@ -service vendor.face-hal-1-1-default /vendor/bin/hw/android.hardware.biometrics.face@1.1-service.example +service vendor.face-hal-1-0-default /vendor/bin/hw/android.hardware.biometrics.face@1.0-service.example # "class hal" causes a race condition on some devices due to files created # in /data. As a workaround, postpone startup until later in boot once # /data is mounted. diff --git a/biometrics/face/1.1/default/manifest_face_default.xml b/biometrics/face/1.0/default/manifest_face_default.xml similarity index 90% rename from biometrics/face/1.1/default/manifest_face_default.xml rename to biometrics/face/1.0/default/manifest_face_default.xml index ec71d9c92b..380ae49e93 100644 --- a/biometrics/face/1.1/default/manifest_face_default.xml +++ b/biometrics/face/1.0/default/manifest_face_default.xml @@ -2,7 +2,7 @@ android.hardware.biometrics.face hwbinder - 1.1 + 1.0 IBiometricsFace default diff --git a/biometrics/face/1.1/default/service.cpp b/biometrics/face/1.0/default/service.cpp similarity index 88% rename from biometrics/face/1.1/default/service.cpp rename to biometrics/face/1.0/default/service.cpp index 344bdb99b4..9818c959d6 100644 --- a/biometrics/face/1.1/default/service.cpp +++ b/biometrics/face/1.0/default/service.cpp @@ -14,10 +14,10 @@ * limitations under the License. */ -#define LOG_TAG "android.hardware.biometrics.face@1.1-service" +#define LOG_TAG "android.hardware.biometrics.face@1.0-service" #include -#include +#include #include #include #include @@ -27,7 +27,7 @@ using android::sp; using android::hardware::configureRpcThreadpool; using android::hardware::joinRpcThreadpool; using android::hardware::biometrics::face::implementation::BiometricsFace; -using android::hardware::biometrics::face::V1_1::IBiometricsFace; +using android::hardware::biometrics::face::V1_0::IBiometricsFace; int main() { ALOGI("BiometricsFace HAL is being started."); -- GitLab From a2e77cf352f8354f4bf0d9995c56ca96f6325ef9 Mon Sep 17 00:00:00 2001 From: Joshua Mccloskey Date: Tue, 9 Feb 2021 03:46:16 +0000 Subject: [PATCH 461/790] Revert^2 "Revert "Add VTS tests for biometrics.face@1.1"" 605521ca5713d028f0746cb4e90127e744322115 Change-Id: I1064436e210d551a077b775c069bae1f86579aea --- biometrics/face/1.1/vts/functional/Android.bp | 29 ---- .../VtsHalBiometricsFaceV1_1TargetTest.cpp | 164 ------------------ 2 files changed, 193 deletions(-) delete mode 100644 biometrics/face/1.1/vts/functional/Android.bp delete mode 100644 biometrics/face/1.1/vts/functional/VtsHalBiometricsFaceV1_1TargetTest.cpp diff --git a/biometrics/face/1.1/vts/functional/Android.bp b/biometrics/face/1.1/vts/functional/Android.bp deleted file mode 100644 index aa0b1fa082..0000000000 --- a/biometrics/face/1.1/vts/functional/Android.bp +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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. - */ - -cc_test { - name: "VtsHalBiometricsFaceV1_1TargetTest", - defaults: ["VtsHalTargetTestDefaults"], - srcs: ["VtsHalBiometricsFaceV1_1TargetTest.cpp"], - static_libs: [ - "android.hardware.biometrics.face@1.0", - "android.hardware.biometrics.face@1.1", - ], - test_suites: [ - "general-tests", - "vts", - ], -} diff --git a/biometrics/face/1.1/vts/functional/VtsHalBiometricsFaceV1_1TargetTest.cpp b/biometrics/face/1.1/vts/functional/VtsHalBiometricsFaceV1_1TargetTest.cpp deleted file mode 100644 index 9ecaab8920..0000000000 --- a/biometrics/face/1.1/vts/functional/VtsHalBiometricsFaceV1_1TargetTest.cpp +++ /dev/null @@ -1,164 +0,0 @@ -/* - * 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. - */ - -#define LOG_TAG "biometrics_face_hidl_hal_test" - -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include - -using android::sp; -using android::hardware::hidl_vec; -using android::hardware::Return; -using android::hardware::Void; -using android::hardware::biometrics::face::V1_0::FaceAcquiredInfo; -using android::hardware::biometrics::face::V1_0::FaceError; -using android::hardware::biometrics::face::V1_0::IBiometricsFaceClientCallback; -using android::hardware::biometrics::face::V1_0::OptionalUint64; -using android::hardware::biometrics::face::V1_0::Status; -using android::hardware::biometrics::face::V1_1::IBiometricsFace; - -namespace { - -// Arbitrary, nonexistent userId -constexpr uint32_t kUserId = 9; -constexpr uint32_t kTimeoutSec = 3; -constexpr auto kTimeout = std::chrono::seconds(kTimeoutSec); -constexpr char kFacedataDir[] = "/data/vendor_de/0/facedata"; -constexpr char kCallbackNameOnError[] = "onError"; - -// Callback arguments that need to be captured for the tests. -struct FaceCallbackArgs { - // The error passed to the last onError() callback. - FaceError error; - - // The userId passed to the last callback. - int32_t userId; -}; - -// Test callback class for the BiometricsFace HAL. -// The HAL will call these callback methods to notify about completed operations -// or encountered errors. -class FaceCallback : public ::testing::VtsHalHidlTargetCallbackBase, - public IBiometricsFaceClientCallback { - public: - Return onEnrollResult(uint64_t, uint32_t, int32_t, uint32_t) override { return Void(); } - - Return onAuthenticated(uint64_t, uint32_t, int32_t, const hidl_vec&) override { - return Void(); - } - - Return onAcquired(uint64_t, int32_t, FaceAcquiredInfo, int32_t) override { - return Void(); - } - - Return onError(uint64_t, int32_t userId, FaceError error, int32_t) override { - FaceCallbackArgs args = {}; - args.error = error; - args.userId = userId; - NotifyFromCallback(kCallbackNameOnError, args); - return Void(); - } - - Return onRemoved(uint64_t, const hidl_vec&, int32_t) override { return Void(); } - - Return onEnumerate(uint64_t, const hidl_vec&, int32_t) override { - return Void(); - } - - Return onLockoutChanged(uint64_t) override { return Void(); } -}; - -// Test class for the BiometricsFace HAL. -class FaceHidlTest : public ::testing::TestWithParam { - public: - void SetUp() override { - mService = IBiometricsFace::getService(GetParam()); - ASSERT_NE(mService, nullptr); - mCallback = new FaceCallback(); - mCallback->SetWaitTimeoutDefault(kTimeout); - Return ret1 = mService->setCallback(mCallback, [](const OptionalUint64& res) { - ASSERT_EQ(Status::OK, res.status); - // Makes sure the "deviceId" represented by "res.value" is not 0. - // 0 would mean the HIDL is not available. - ASSERT_NE(0UL, res.value); - }); - ASSERT_TRUE(ret1.isOk()); - Return ret2 = mService->setActiveUser(kUserId, kFacedataDir); - ASSERT_EQ(Status::OK, static_cast(ret2)); - } - - void TearDown() override {} - - sp mService; - sp mCallback; -}; - -// enroll with an invalid (all zeroes) HAT should fail. -TEST_P(FaceHidlTest, EnrollRemotelyZeroHatTest) { - // Filling HAT with zeros - hidl_vec token(69); - for (size_t i = 0; i < 69; i++) { - token[i] = 0; - } - - Return ret = mService->enrollRemotely(token, kTimeoutSec, {}); - ASSERT_EQ(Status::OK, static_cast(ret)); - - // onError should be called with a meaningful (nonzero) error. - auto res = mCallback->WaitForCallback(kCallbackNameOnError); - EXPECT_TRUE(res.no_timeout); - EXPECT_EQ(kUserId, res.args->userId); - EXPECT_EQ(FaceError::UNABLE_TO_PROCESS, res.args->error); -} - -// enroll with an invalid HAT should fail. -TEST_P(FaceHidlTest, EnrollRemotelyGarbageHatTest) { - // Filling HAT with pseudorandom invalid data. - // Using default seed to make the test reproducible. - std::mt19937 gen(std::mt19937::default_seed); - std::uniform_int_distribution dist; - hidl_vec token(69); - for (size_t i = 0; i < 69; ++i) { - token[i] = dist(gen); - } - - Return ret = mService->enrollRemotely(token, kTimeoutSec, {}); - ASSERT_EQ(Status::OK, static_cast(ret)); - - // onError should be called with a meaningful (nonzero) error. - auto res = mCallback->WaitForCallback(kCallbackNameOnError); - EXPECT_TRUE(res.no_timeout); - EXPECT_EQ(kUserId, res.args->userId); - EXPECT_EQ(FaceError::UNABLE_TO_PROCESS, res.args->error); -} - -} // anonymous namespace - -GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(FaceHidlTest); -INSTANTIATE_TEST_SUITE_P( - PerInstance, FaceHidlTest, - testing::ValuesIn(android::hardware::getAllHalInstanceNames(IBiometricsFace::descriptor)), - android::hardware::PrintInstanceNameToString); -- GitLab From f6d062fd836188aeafb7cadcf49be720df6f0ee0 Mon Sep 17 00:00:00 2001 From: Joshua Mccloskey Date: Tue, 9 Feb 2021 03:46:16 +0000 Subject: [PATCH 462/790] Revert "Revert "Revert "Define biometrics.face@1.1 with remote e..." Revert^2 "Temporarily remove support for biometrics.face@1.1" cccbd64ff74ee45a48eaf6a68e97349fb9542c92 Change-Id: I981f607b48a44459363f5edbd075f1fcfcf0a10f --- biometrics/face/1.1/Android.bp | 14 ----- biometrics/face/1.1/IBiometricsFace.hal | 82 ------------------------- 2 files changed, 96 deletions(-) delete mode 100644 biometrics/face/1.1/Android.bp delete mode 100644 biometrics/face/1.1/IBiometricsFace.hal diff --git a/biometrics/face/1.1/Android.bp b/biometrics/face/1.1/Android.bp deleted file mode 100644 index 14a86f14b8..0000000000 --- a/biometrics/face/1.1/Android.bp +++ /dev/null @@ -1,14 +0,0 @@ -// This file is autogenerated by hidl-gen -Landroidbp. - -hidl_interface { - name: "android.hardware.biometrics.face@1.1", - root: "android.hardware", - srcs: [ - "IBiometricsFace.hal", - ], - interfaces: [ - "android.hardware.biometrics.face@1.0", - "android.hidl.base@1.0", - ], - gen_java: true, -} diff --git a/biometrics/face/1.1/IBiometricsFace.hal b/biometrics/face/1.1/IBiometricsFace.hal deleted file mode 100644 index 975001f30b..0000000000 --- a/biometrics/face/1.1/IBiometricsFace.hal +++ /dev/null @@ -1,82 +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. - */ - -package android.hardware.biometrics.face@1.1; -import @1.0::IBiometricsFace; -import @1.0::Status; -import @1.0::Feature; - -/** - * The HAL interface for biometric face authentication. - */ -interface IBiometricsFace extends @1.0::IBiometricsFace { - /** - * Enrolls a user's face for a remote client, for example Android Auto. - * - * The HAL implementation is responsible for creating a secure communication - * channel and receiving the enrollment images from a mobile device with - * face authentication hardware. - * - * Note that the Hardware Authentication Token must be valid for the - * duration of enrollment and thus should be explicitly invalidated by a - * call to revokeChallenge() when enrollment is complete, to reduce the - * window of opportunity to re-use the challenge and HAT. For example, - * Settings calls generateChallenge() once to allow the user to enroll one - * or more faces or toggle secure settings without having to re-enter the - * PIN/pattern/password. Once the user completes the operation, Settings - * invokes revokeChallenge() to close the transaction. If the HAT is expired, - * the implementation must invoke onError with UNABLE_TO_PROCESS. - * - * Requirements for using this API: - * - Mobile devices MUST NOT delegate enrollment to another device by calling - * this API. This feature is intended only to allow enrollment on devices - * where it is impossible to enroll locally on the device. - * - The path MUST be protected by a secret key with rollback protection. - * - Synchronizing between devices MUST be accomplished by having both - * devices agree on a secret PIN entered by the user (similar to BT - * pairing procedure) and use a salted version of that PIN plus other secret - * to encrypt traffic. - * - All communication to/from the remote device MUST be encrypted and signed - * to prevent image injection and other man-in-the-middle type attacks. - * - generateChallenge() and revokeChallenge() MUST be implemented on both - * remote and local host (e.g. hash the result of the remote host with a - * local secret before responding to the API call) and any transmission of - * the challenge between hosts MUST be signed to prevent man-in-the-middle - * attacks. - * - In the event of a lost connection, the result of the last - * generateChallenge() MUST be invalidated and the process started over. - * - Both the remote and local host MUST honor the timeout and invalidate the - * challenge. - * - * This method triggers the IBiometricsFaceClientCallback#onEnrollResult() - * method. - * - * @param hat A valid Hardware Authentication Token, generated as a result - * of a generateChallenge() challenge being wrapped by the gatekeeper - * after a successful strong authentication request. - * @param timeoutSec A timeout in seconds, after which this enroll - * attempt is cancelled. Note that the framework can continue - * enrollment by calling this again with a valid HAT. This timeout is - * expected to be used to limit power usage if the device becomes idle - * during enrollment. The implementation is expected to send - * ERROR_TIMEOUT if this happens. - * @param disabledFeatures A list of features to be disabled during - * enrollment. Note that all features are enabled by default. - * @return status The status of this method call. - */ - enrollRemotely(vec hat, uint32_t timeoutSec, - vec disabledFeatures) generates (Status status); -}; -- GitLab From 55c20af08aa78ff2c8be021497f892d7bdfcce05 Mon Sep 17 00:00:00 2001 From: Kai Date: Mon, 8 Feb 2021 20:28:10 -0800 Subject: [PATCH 463/790] Add Kiran as VHAL owner Add Kiran as VHAL owner Bug: 179717304 Test: build Change-Id: I311024d66be562ad792a33108e61b0f367c69cf9 (cherry picked from commit 98b06b9fdd913ef4c5a86e02b884631d17ac1c3f) --- automotive/OWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/automotive/OWNERS b/automotive/OWNERS index fb3e3d63bf..43c5f3e30e 100644 --- a/automotive/OWNERS +++ b/automotive/OWNERS @@ -1,6 +1,6 @@ pirozzoj@google.com twasilczyk@google.com -pfg@google.com +krachuri@google.com gurunagarajan@google.com keunyoung@google.com felipeal@google.com -- GitLab From 1f3c852be8a9762860b75783543a95c9371d8dbb Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Fri, 12 Feb 2021 12:56:02 -0800 Subject: [PATCH 464/790] Implement a simple worker thread Bug: 166800618 Bug: 175070939 Test: atest --host android.hardware.biometrics.fingerprint.WorkerThreadTest Change-Id: Ic84efbde21d0997450585078b311610fe752fa88 --- .../fingerprint/aidl/default/Android.bp | 13 +++ .../fingerprint/aidl/default/WorkerThread.cpp | 68 ++++++++++++ .../aidl/default/include/WorkerThread.h | 74 ++++++++++++ .../aidl/default/tests/WorkerThreadTest.cpp | 105 ++++++++++++++++++ 4 files changed, 260 insertions(+) create mode 100644 biometrics/fingerprint/aidl/default/WorkerThread.cpp create mode 100644 biometrics/fingerprint/aidl/default/include/WorkerThread.h create mode 100644 biometrics/fingerprint/aidl/default/tests/WorkerThreadTest.cpp diff --git a/biometrics/fingerprint/aidl/default/Android.bp b/biometrics/fingerprint/aidl/default/Android.bp index 69fb2e3309..24087cf036 100644 --- a/biometrics/fingerprint/aidl/default/Android.bp +++ b/biometrics/fingerprint/aidl/default/Android.bp @@ -17,3 +17,16 @@ cc_binary { "android.hardware.biometrics.common-V1-ndk_platform", ], } + +cc_test_host { + name: "android.hardware.biometrics.fingerprint.WorkerThreadTest", + local_include_dirs: ["include"], + srcs: [ + "tests/WorkerThreadTest.cpp", + "WorkerThread.cpp", + ], + shared_libs: [ + "libcutils", + ], + test_suites: ["general-tests"], +} diff --git a/biometrics/fingerprint/aidl/default/WorkerThread.cpp b/biometrics/fingerprint/aidl/default/WorkerThread.cpp new file mode 100644 index 0000000000..512efb8d5d --- /dev/null +++ b/biometrics/fingerprint/aidl/default/WorkerThread.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. + */ + +#include "WorkerThread.h" + +namespace aidl::android::hardware::biometrics::fingerprint { + +// It's important that mThread is initialized after everything else because it runs a member +// function that may use any member of this class. +WorkerThread::WorkerThread(size_t maxQueueSize) + : mMaxSize(maxQueueSize), + mIsDestructing(false), + mQueue(), + mQueueMutex(), + mQueueCond(), + mThread(&WorkerThread::threadFunc, this) {} + +WorkerThread::~WorkerThread() { + // This is a signal for threadFunc to terminate as soon as possible, and a hint for schedule + // that it doesn't need to do any work. + mIsDestructing = true; + mQueueCond.notify_all(); + mThread.join(); +} + +bool WorkerThread::schedule(Task&& task) { + if (mIsDestructing) { + return false; + } + + std::unique_lock lock(mQueueMutex); + if (mQueue.size() >= mMaxSize) { + return false; + } + mQueue.push_back(std::move(task)); + lock.unlock(); + mQueueCond.notify_one(); + return true; +} + +void WorkerThread::threadFunc() { + while (!mIsDestructing) { + std::unique_lock lock(mQueueMutex); + mQueueCond.wait(lock, [this] { return !mQueue.empty() || mIsDestructing; }); + if (mIsDestructing) { + return; + } + Task task = std::move(mQueue.front()); + mQueue.pop_front(); + lock.unlock(); + task(); + } +} + +} // namespace aidl::android::hardware::biometrics::fingerprint diff --git a/biometrics/fingerprint/aidl/default/include/WorkerThread.h b/biometrics/fingerprint/aidl/default/include/WorkerThread.h new file mode 100644 index 0000000000..49104c85e2 --- /dev/null +++ b/biometrics/fingerprint/aidl/default/include/WorkerThread.h @@ -0,0 +1,74 @@ +/* + * 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 +#include +#include +#include + +namespace aidl::android::hardware::biometrics::fingerprint { + +using Task = std::function; + +// A class that encapsulates a worker thread and a task queue, and provides a convenient interface +// for a Session to schedule its tasks for asynchronous execution. +class WorkerThread final { + public: + // Internally creates a queue that cannot exceed maxQueueSize elements and a new thread that + // polls the queue for tasks until this instance is destructed. + explicit WorkerThread(size_t maxQueueSize); + + // Unblocks the internal queue and calls join on the internal thread allowing it to gracefully + // exit. + ~WorkerThread(); + + // Disallow copying this class. + WorkerThread(const WorkerThread&) = delete; + WorkerThread& operator=(const WorkerThread&) = delete; + + // Also disable moving this class to simplify implementation. + WorkerThread(WorkerThread&&) = delete; + WorkerThread& operator=(WorkerThread&&) = delete; + + // If the internal queue is not full, pushes a task at the end of the queue and returns true. + // Otherwise, returns false. If the queue is busy, blocks until it becomes available. + bool schedule(Task&& task); + + private: + // The function that runs on the internal thread. Sequentially runs the available tasks from + // the queue. If the queue is empty, waits until a new task is added. If the worker is being + // destructed, finishes its current task and gracefully exits. + void threadFunc(); + + // The maximum size that the queue is allowed to expand to. + size_t mMaxSize; + + // Whether the destructor was called. If true, tells threadFunc to exit as soon as possible, and + // tells schedule to avoid doing any work. + std::atomic mIsDestructing; + + // Queue that's guarded by mQueueMutex and mQueueCond. + std::deque mQueue; + std::mutex mQueueMutex; + std::condition_variable mQueueCond; + + // The internal thread that works on the tasks from the queue. + std::thread mThread; +}; + +} // namespace aidl::android::hardware::biometrics::fingerprint diff --git a/biometrics/fingerprint/aidl/default/tests/WorkerThreadTest.cpp b/biometrics/fingerprint/aidl/default/tests/WorkerThreadTest.cpp new file mode 100644 index 0000000000..ba901ad5ca --- /dev/null +++ b/biometrics/fingerprint/aidl/default/tests/WorkerThreadTest.cpp @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +#include + +#include "WorkerThread.h" + +namespace { + +using aidl::android::hardware::biometrics::fingerprint::WorkerThread; +using namespace std::chrono_literals; + +TEST(WorkerThreadTest, ScheduleReturnsTrueWhenQueueHasSpace) { + WorkerThread worker(1 /*maxQueueSize*/); + for (int i = 0; i < 100; ++i) { + EXPECT_TRUE(worker.schedule([] {})); + // Allow enough time for the previous task to be processed. + std::this_thread::sleep_for(2ms); + } +} + +TEST(WorkerThreadTest, ScheduleReturnsFalseWhenQueueIsFull) { + WorkerThread worker(2 /*maxQueueSize*/); + // Add a long-running task. + worker.schedule([] { std::this_thread::sleep_for(1s); }); + + // Allow enough time for the worker to start working on the previous task. + std::this_thread::sleep_for(2ms); + + // Fill the worker's queue to the maximum. + worker.schedule([] {}); + worker.schedule([] {}); + + EXPECT_FALSE(worker.schedule([] {})); +} + +TEST(WorkerThreadTest, TasksExecuteInOrder) { + constexpr int NUM_TASKS = 10000; + WorkerThread worker(NUM_TASKS); + + std::vector results; + for (int i = 0; i < NUM_TASKS; ++i) { + worker.schedule([&results, i] { + // Delay tasks differently to provoke races. + std::this_thread::sleep_for(std::chrono::nanoseconds(100 - i % 100)); + // Unguarded write to results to provoke races. + results.push_back(i); + }); + } + + std::promise promise; + auto future = promise.get_future(); + + // Schedule a special task to signal when all of the tasks are finished. + worker.schedule([&promise] { promise.set_value(); }); + auto status = future.wait_for(1s); + ASSERT_EQ(status, std::future_status::ready); + + ASSERT_EQ(results.size(), NUM_TASKS); + EXPECT_TRUE(std::is_sorted(results.begin(), results.end())); +} + +TEST(WorkerThreadTest, ExecutionStopsAfterWorkerIsDestroyed) { + std::promise promise1; + std::promise promise2; + auto future1 = promise1.get_future(); + auto future2 = promise2.get_future(); + + { + WorkerThread worker(2 /*maxQueueSize*/); + worker.schedule([&promise1] { + promise1.set_value(); + std::this_thread::sleep_for(200ms); + }); + worker.schedule([&promise2] { promise2.set_value(); }); + + // Make sure the first task is executing. + auto status1 = future1.wait_for(1s); + ASSERT_EQ(status1, std::future_status::ready); + } + + // The second task should never execute. + auto status2 = future2.wait_for(1s); + EXPECT_EQ(status2, std::future_status::timeout); +} + +} // namespace -- GitLab From 4bae4f943d61bca6461cdeaa3da8823ffbd1886a Mon Sep 17 00:00:00 2001 From: Vince Leung Date: Wed, 3 Feb 2021 06:21:58 +0000 Subject: [PATCH 465/790] vibrator: aidl: Add get f0 and get Q APIs Add APIs to get f0, resonant frequency, and Q factor. Bug: 178826612 Test: m and verify using idlcli Change-Id: I834693693a91871f988504d2d9448497ef10e7fc --- .../hardware/vibrator/CompositeEffect.aidl | 29 ++++++++++++---- .../hardware/vibrator/CompositePrimitive.aidl | 29 ++++++++++++---- .../android/hardware/vibrator/Effect.aidl | 29 ++++++++++++---- .../hardware/vibrator/EffectStrength.aidl | 29 ++++++++++++---- .../android/hardware/vibrator/IVibrator.aidl | 33 +++++++++++++++---- .../hardware/vibrator/IVibratorCallback.aidl | 29 ++++++++++++---- .../hardware/vibrator/IVibratorManager.aidl | 29 ++++++++++++---- .../android/hardware/vibrator/IVibrator.aidl | 24 ++++++++++++++ vibrator/aidl/default/Vibrator.cpp | 16 ++++++++- .../default/include/vibrator-impl/Vibrator.h | 2 ++ .../aidl/vts/VtsHalVibratorTargetTest.cpp | 22 +++++++++++++ 11 files changed, 221 insertions(+), 50 deletions(-) diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/CompositeEffect.aidl b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/CompositeEffect.aidl index 8cb259ffaa..0995d2d7af 100644 --- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/CompositeEffect.aidl +++ b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/CompositeEffect.aidl @@ -1,14 +1,29 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/CompositePrimitive.aidl b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/CompositePrimitive.aidl index 3071dce32b..0b4b527359 100644 --- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/CompositePrimitive.aidl +++ b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/CompositePrimitive.aidl @@ -1,14 +1,29 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/Effect.aidl b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/Effect.aidl index 5ed4dc5ad6..0d2b340a6c 100644 --- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/Effect.aidl +++ b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/Effect.aidl @@ -1,14 +1,29 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/EffectStrength.aidl b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/EffectStrength.aidl index 802d236309..808644a4b5 100644 --- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/EffectStrength.aidl +++ b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/EffectStrength.aidl @@ -1,14 +1,29 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibrator.aidl b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibrator.aidl index 2de1d7bde7..1f2d946836 100644 --- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibrator.aidl +++ b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibrator.aidl @@ -1,14 +1,29 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped @@ -33,6 +48,8 @@ interface IVibrator { android.hardware.vibrator.Effect[] getSupportedAlwaysOnEffects(); void alwaysOnEnable(in int id, in android.hardware.vibrator.Effect effect, in android.hardware.vibrator.EffectStrength strength); void alwaysOnDisable(in int id); + float getResonantFrequency(); + float getQFactor(); const int CAP_ON_CALLBACK = 1; const int CAP_PERFORM_CALLBACK = 2; const int CAP_AMPLITUDE_CONTROL = 4; @@ -40,4 +57,6 @@ interface IVibrator { const int CAP_EXTERNAL_AMPLITUDE_CONTROL = 16; const int CAP_COMPOSE_EFFECTS = 32; const int CAP_ALWAYS_ON_CONTROL = 64; + const int CAP_GET_RESONANT_FREQUENCY = 128; + const int CAP_GET_Q_FACTOR = 256; } diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibratorCallback.aidl b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibratorCallback.aidl index 3a1e7d865b..f99ecc1143 100644 --- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibratorCallback.aidl +++ b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibratorCallback.aidl @@ -1,14 +1,29 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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. + *//////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibratorManager.aidl b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibratorManager.aidl index 99cd448f41..8e3ac88e8c 100644 --- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibratorManager.aidl +++ b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibratorManager.aidl @@ -1,14 +1,29 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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 interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped diff --git a/vibrator/aidl/android/hardware/vibrator/IVibrator.aidl b/vibrator/aidl/android/hardware/vibrator/IVibrator.aidl index cd7b60340c..cba76dc745 100644 --- a/vibrator/aidl/android/hardware/vibrator/IVibrator.aidl +++ b/vibrator/aidl/android/hardware/vibrator/IVibrator.aidl @@ -52,6 +52,14 @@ interface IVibrator { * Whether alwaysOnEnable/alwaysOnDisable is supported. */ const int CAP_ALWAYS_ON_CONTROL = 1 << 6; + /** + * Whether getResonantFrequency is supported. + */ + const int CAP_GET_RESONANT_FREQUENCY = 1 << 7; + /** + * Whether getQFactor is supported. + */ + const int CAP_GET_Q_FACTOR = 1 << 8; /** * Determine capabilities of the vibrator HAL (CAP_* mask) @@ -230,4 +238,20 @@ interface IVibrator { * @param id The device-specific always-on source ID to disable. */ void alwaysOnDisable(in int id); + + /** + * Retrieve the measured resonant frequency of the actuator. This may not be supported + * and this support is reflected in getCapabilities (CAP_GET_RESONANT_FREQUENCY) + * + * @return Measured resonant frequency in Hz. + */ + float getResonantFrequency(); + + /** + * Retrieve the measured Q factor. This may not be supported + * and this support is reflected in getCapabilities (CAP_GET_Q_FACTOR) + * + * @return Measured Q factor. + */ + float getQFactor(); } diff --git a/vibrator/aidl/default/Vibrator.cpp b/vibrator/aidl/default/Vibrator.cpp index 1021e620ce..bf61bfec91 100644 --- a/vibrator/aidl/default/Vibrator.cpp +++ b/vibrator/aidl/default/Vibrator.cpp @@ -27,12 +27,16 @@ namespace vibrator { static constexpr int32_t kComposeDelayMaxMs = 1000; static constexpr int32_t kComposeSizeMax = 256; +static constexpr float kResonantFrequency = 150.0; +static constexpr float kQFactor = 11.0; + ndk::ScopedAStatus Vibrator::getCapabilities(int32_t* _aidl_return) { LOG(INFO) << "Vibrator reporting capabilities"; *_aidl_return = IVibrator::CAP_ON_CALLBACK | IVibrator::CAP_PERFORM_CALLBACK | IVibrator::CAP_AMPLITUDE_CONTROL | IVibrator::CAP_EXTERNAL_CONTROL | IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL | IVibrator::CAP_COMPOSE_EFFECTS | - IVibrator::CAP_ALWAYS_ON_CONTROL; + IVibrator::CAP_ALWAYS_ON_CONTROL | IVibrator::CAP_GET_RESONANT_FREQUENCY | + IVibrator::CAP_GET_Q_FACTOR; return ndk::ScopedAStatus::ok(); } @@ -201,6 +205,16 @@ ndk::ScopedAStatus Vibrator::alwaysOnDisable(int32_t id) { return ndk::ScopedAStatus::ok(); } +ndk::ScopedAStatus Vibrator::getResonantFrequency(float *resonantFreqHz) { + *resonantFreqHz = kResonantFrequency; + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Vibrator::getQFactor(float *qFactor) { + *qFactor = kQFactor; + return ndk::ScopedAStatus::ok(); +} + } // namespace vibrator } // namespace hardware } // namespace android diff --git a/vibrator/aidl/default/include/vibrator-impl/Vibrator.h b/vibrator/aidl/default/include/vibrator-impl/Vibrator.h index c3f3616876..a2af9637ed 100644 --- a/vibrator/aidl/default/include/vibrator-impl/Vibrator.h +++ b/vibrator/aidl/default/include/vibrator-impl/Vibrator.h @@ -44,6 +44,8 @@ class Vibrator : public BnVibrator { ndk::ScopedAStatus getSupportedAlwaysOnEffects(std::vector* _aidl_return) override; ndk::ScopedAStatus alwaysOnEnable(int32_t id, Effect effect, EffectStrength strength) override; ndk::ScopedAStatus alwaysOnDisable(int32_t id) override; + ndk::ScopedAStatus getResonantFrequency(float *resonantFreqHz) override; + ndk::ScopedAStatus getQFactor(float *qFactor) override; }; } // namespace vibrator diff --git a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp index adbb0cfeb3..2540d0b1d5 100644 --- a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp +++ b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp @@ -538,6 +538,28 @@ TEST_P(VibratorAidl, AlwaysOn) { } } +TEST_P(VibratorAidl, GetResonantFrequency) { + float resonantFrequency; + Status status = vibrator->getResonantFrequency(&resonantFrequency); + if (capabilities & IVibrator::CAP_GET_RESONANT_FREQUENCY) { + ASSERT_NE(resonantFrequency, 0); + EXPECT_EQ(status.exceptionCode(), Status::EX_NONE); + } else { + EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION); + } +} + +TEST_P(VibratorAidl, GetQFactor) { + float qFactor; + Status status = vibrator->getQFactor(&qFactor); + if (capabilities & IVibrator::CAP_GET_Q_FACTOR) { + ASSERT_NE(qFactor, 0); + EXPECT_EQ(status.exceptionCode(), Status::EX_NONE); + } else { + EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION); + } +} + std::vector> GenerateVibratorMapping() { std::vector> tuples; auto managerAidlNames = android::getAidlHalInstanceNames(IVibratorManager::descriptor); -- GitLab From bb4c2fdc0221ae49aaf77e9fd659381cc4073702 Mon Sep 17 00:00:00 2001 From: Sarah Chin Date: Fri, 12 Feb 2021 11:55:15 -0800 Subject: [PATCH 466/790] Allow getSystemSelectionChannels to return specifiers Bug: 179929817 Test: VTS Change-Id: I574e897c0fdb57cad1a3655c34d43f0d080de9ae --- radio/1.6/IRadio.hal | 2 +- radio/1.6/IRadioResponse.hal | 5 ++++- radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h | 3 ++- radio/1.6/vts/functional/radio_response.cpp | 3 ++- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/radio/1.6/IRadio.hal b/radio/1.6/IRadio.hal index b756ce1261..7c00e04c5c 100644 --- a/radio/1.6/IRadio.hal +++ b/radio/1.6/IRadio.hal @@ -462,7 +462,7 @@ interface IRadio extends @1.5::IRadio { * cell information isn't known then the appropriate unknown value will be returned. * This does not cause or change the rate of unsolicited cellInfoList(). * - * This is identitcal to getCellInfoList in V1.0, but it requests updated version of CellInfo. + * This is identical to getCellInfoList in V1.0, but it requests updated version of CellInfo. * * @param serial Serial number of request. * diff --git a/radio/1.6/IRadioResponse.hal b/radio/1.6/IRadioResponse.hal index 6ad5cf262a..56ce809dfe 100644 --- a/radio/1.6/IRadioResponse.hal +++ b/radio/1.6/IRadioResponse.hal @@ -19,6 +19,7 @@ package android.hardware.radio@1.6; import @1.0::SendSmsResult; import @1.4::RadioAccessFamily; import @1.5::IRadioResponse; +import @1.5::RadioAccessSpecifier; import @1.6::Call; import @1.6::CellInfo; import @1.6::RegStateResult; @@ -344,6 +345,7 @@ interface IRadioResponse extends @1.5::IRadioResponse { /** * @param info Response info struct containing response type, serial no. and error + * @param specifiers List of RadioAccessSpecifiers that are scanned. * * Valid errors returned: * RadioError:NONE @@ -351,7 +353,8 @@ interface IRadioResponse extends @1.5::IRadioResponse { * RadioError:INTERNAL_ERR * RadioError:INVALID_ARGUMENTS */ - oneway getSystemSelectionChannelsResponse(RadioResponseInfo info); + oneway getSystemSelectionChannelsResponse( + RadioResponseInfo info, vec specifiers); /** * This is identical to getCellInfoListResponse_1_5 but uses an updated version of CellInfo. diff --git a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h index f32e31296d..f610f2af76 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h +++ b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h @@ -805,7 +805,8 @@ class RadioResponse_v1_6 : public ::android::hardware::radio::V1_6::IRadioRespon const ::android::hardware::radio::V1_6::RadioResponseInfo& info); Return getSystemSelectionChannelsResponse( - const ::android::hardware::radio::V1_6::RadioResponseInfo& info); + const ::android::hardware::radio::V1_6::RadioResponseInfo& info, + const hidl_vec<::android::hardware::radio::V1_5::RadioAccessSpecifier>& specifier); Return getSignalStrengthResponse_1_6( const ::android::hardware::radio::V1_6::RadioResponseInfo& info, diff --git a/radio/1.6/vts/functional/radio_response.cpp b/radio/1.6/vts/functional/radio_response.cpp index fad3f12e2b..027e9acd74 100644 --- a/radio/1.6/vts/functional/radio_response.cpp +++ b/radio/1.6/vts/functional/radio_response.cpp @@ -1190,7 +1190,8 @@ Return RadioResponse_v1_6::getCellInfoListResponse_1_6( } Return RadioResponse_v1_6::getSystemSelectionChannelsResponse( - const ::android::hardware::radio::V1_6::RadioResponseInfo& info) { + const ::android::hardware::radio::V1_6::RadioResponseInfo& info, + const hidl_vec<::android::hardware::radio::V1_5::RadioAccessSpecifier>& /*specifier*/) { rspInfo = info; parent_v1_6.notify(info.serial); return Void(); -- GitLab From 513ef09a21cd7fa22ed2cc5ac4be2e4613f986fb Mon Sep 17 00:00:00 2001 From: Yifan Hong Date: Wed, 17 Feb 2021 23:56:06 +0000 Subject: [PATCH 467/790] Revert "Add default implementation for biometrics.face@1.1" This reverts commit 366cc5371401070753150e685e07e100f837dbe4. Reason for revert: b/179207135. I1aa682644b9 is not a full revert of the original CL, so properly revert the rest. Bug: 179207135 Test: pass Change-Id: Id81783c9e67e63c8717fcb216e52d0d6da203c60 --- compatibility_matrices/compatibility_matrix.current.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index e500a296f2..6562f2282f 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -95,7 +95,7 @@ android.hardware.biometrics.face - 1.0-1 + 1.0 IBiometricsFace default -- GitLab From b0b83b3ee12a5a1b1f124c7c61d4ae53a20dd72c Mon Sep 17 00:00:00 2001 From: Robert Shih Date: Fri, 22 Jan 2021 10:14:53 -0800 Subject: [PATCH 468/790] drm: vts for V1_4::ICrypto/DrmPlugin::getLogMessages Bug: 162255728 Test: VtsHalDrmV1_4TargetTest Change-Id: I5e05c4d36f983053ab80495258112a4d57076436 --- drm/1.4/vts/functional/drm_hal_test.cpp | 36 +++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/drm/1.4/vts/functional/drm_hal_test.cpp b/drm/1.4/vts/functional/drm_hal_test.cpp index ee6635b2ad..f9fa0bde3b 100644 --- a/drm/1.4/vts/functional/drm_hal_test.cpp +++ b/drm/1.4/vts/functional/drm_hal_test.cpp @@ -154,6 +154,42 @@ TEST_P(DrmHalTest, SetPlaybackId) { EXPECT_TRUE(foundPbId); } +TEST_P(DrmHalTest, GetLogMessages) { + auto drm = DrmPluginV1_4(); + auto sid = OpenSession(); + auto crypto_1_0 = CryptoPlugin(sid); + sp crypto(V1_4::ICryptoPlugin::castFrom(crypto_1_0)); + + hidl_vec initData; + hidl_string mime{"text/plain"}; + V1_0::KeyedVector optionalParameters; + auto res = drmPlugin->getKeyRequest_1_2( + sid, initData, mime, V1_0::KeyType::STREAMING, + optionalParameters, [&](V1_2::Status status, const hidl_vec&, + V1_1::KeyRequestType, const hidl_string&) { + EXPECT_NE(V1_2::Status::OK, status); + }); + EXPECT_OK(res); + + V1_4::IDrmPlugin::getLogMessages_cb cb = [&]( + V1_4::Status status, + hidl_vec logs) { + EXPECT_EQ(V1_4::Status::OK, status); + EXPECT_NE(0, logs.size()); + for (auto log: logs) { + ALOGI("priority=[%u] message='%s'", log.priority, log.message.c_str()); + } + }; + + auto res2 = drm->getLogMessages(cb); + EXPECT_OK(res2); + + auto res3 = crypto->getLogMessages(cb); + EXPECT_OK(res3); + + closeSession(sid); +} + } // namespace vts } // namespace V1_4 } // namespace drm -- GitLab From 4ae95d73ebbb6e1d569aa4e6232f29c829c68ad7 Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Tue, 16 Feb 2021 16:03:48 -0800 Subject: [PATCH 469/790] Add IFingerprint#reset and ISession#close methods Bug: 180521746 Test: m android.hardware.biometrics.fingerprint-update-api Test: build Change-Id: Ie69ea596dbbaefd4ee360facb2b57a21c8c0a46f --- .../biometrics/fingerprint/IFingerprint.aidl | 1 + .../biometrics/fingerprint/ISession.aidl | 1 + .../biometrics/fingerprint/SessionState.aidl | 21 ++++++++++--------- .../biometrics/fingerprint/IFingerprint.aidl | 14 +++++++++++++ .../biometrics/fingerprint/ISession.aidl | 19 ++++++++++++++++- .../biometrics/fingerprint/SessionState.aidl | 6 +++++- 6 files changed, 50 insertions(+), 12 deletions(-) diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl index c5a5422d24..2d44528f2e 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl @@ -35,4 +35,5 @@ package android.hardware.biometrics.fingerprint; 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); + void reset(); } 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 be0029c53b..b583006d46 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 @@ -43,6 +43,7 @@ interface ISession { void getAuthenticatorId(in int cookie); void invalidateAuthenticatorId(in int cookie); void resetLockout(in int cookie, in android.hardware.keymaster.HardwareAuthToken hat); + void close(in int cookie); void onPointerDown(in int pointerId, in int x, in int y, in float minor, in float major); void onPointerUp(in int pointerId); void onUiReady(); diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.aidl index 44323ffb1d..05dd85bbfd 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.aidl @@ -34,14 +34,15 @@ package android.hardware.biometrics.fingerprint; @Backing(type="byte") @VintfStability enum SessionState { IDLING = 0, - GENERATING_CHALLENGE = 1, - REVOKING_CHALLENGE = 2, - ENROLLING = 3, - AUTHENTICATING = 4, - DETECTING_INTERACTION = 5, - ENUMERATING_ENROLLMENTS = 6, - REMOVING_ENROLLMENTS = 7, - GETTING_AUTHENTICATOR_ID = 8, - INVALIDATING_AUTHENTICATOR_ID = 9, - RESETTING_LOCKOUT = 10, + CLOSED = 1, + GENERATING_CHALLENGE = 2, + REVOKING_CHALLENGE = 3, + ENROLLING = 4, + AUTHENTICATING = 5, + DETECTING_INTERACTION = 6, + ENUMERATING_ENROLLMENTS = 7, + REMOVING_ENROLLMENTS = 8, + GETTING_AUTHENTICATOR_ID = 9, + INVALIDATING_AUTHENTICATOR_ID = 10, + RESETTING_LOCKOUT = 11, } diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl index 3675aa4019..37062badae 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl @@ -35,6 +35,10 @@ interface IFingerprint { * Creates a session which can then be used by the framework to perform operations such as * enroll, authenticate, etc for the given sensorId and userId. * + * Calling this method while there is an active session is considered an error. If the + * framework is in a bad state and for some reason cannot close its session, it should use + * the reset method below. + * * A physical sensor identified by sensorId typically supports only a single in-flight session * at a time. As such, if a session is currently in a state other than SessionState::IDLING, the * HAL MUST finish or cancel the current operation and return to SessionState::IDLING before the @@ -61,4 +65,14 @@ interface IFingerprint { * @return A new session */ ISession createSession(in int sensorId, in int userId, in ISessionCallback cb); + + /** + * Resets the HAL into a clean state, forcing it to cancel all of the pending operations, close + * its current session, and release all of the acquired resources. + * + * This should be used as a last resort to recover the HAL if the current session becomes + * unresponsive. The implementation might choose to restart the HAL process to get back into a + * good state. + */ + void reset(); } diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl index f9c3732ac4..ab7930d81b 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl @@ -366,6 +366,24 @@ interface ISession { */ void resetLockout(in int cookie, in HardwareAuthToken hat); + /* + * Close this session and allow the HAL to release the resources associated with this session. + * + * A session can only be closed when it's in SessionState::IDLING. Closing a session will + * result in a ISessionCallback#onStateChanged call with SessionState::CLOSED. + * + * If a session is unresponsive or stuck in a state other than SessionState::CLOSED, + * IFingerprint#reset could be used as a last resort to terminate the session and recover the + * HAL from a bad state. + * + * All sessions must be explicitly closed. Calling IFingerprint#createSession while there is an + * active session is considered an error. + * + * @param cookie An identifier used to track subsystem operations related to this call path. The + * client must guarantee that it is unique per ISession. + */ + void close(in int cookie); + /** * Methods for notifying the under-display fingerprint sensor about external events. */ @@ -420,4 +438,3 @@ interface ISession { */ void onUiReady(); } - diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SessionState.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SessionState.aidl index 1de01ad73c..19a6ce3682 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SessionState.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SessionState.aidl @@ -24,6 +24,11 @@ enum SessionState { */ IDLING, + /** + * The session has been closed by the client. + */ + CLOSED, + /** * The HAL is processing the ISession#generateChallenge request. */ @@ -74,4 +79,3 @@ enum SessionState { */ RESETTING_LOCKOUT } - -- GitLab From 71005c54994a646affe645f1c61078e15df0e01b Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Wed, 17 Feb 2021 12:44:14 -0800 Subject: [PATCH 470/790] Update default HAL with close and reset methods Bug: 180521746 Test: atest VtsHalBiometricsFingerprintTargetTest Change-Id: I3331f8185ff90106a2500fe5ca17836e8127add5 --- biometrics/fingerprint/aidl/default/Fingerprint.cpp | 5 +++++ biometrics/fingerprint/aidl/default/Session.cpp | 5 +++++ biometrics/fingerprint/aidl/default/include/Fingerprint.h | 2 ++ biometrics/fingerprint/aidl/default/include/Session.h | 2 ++ 4 files changed, 14 insertions(+) diff --git a/biometrics/fingerprint/aidl/default/Fingerprint.cpp b/biometrics/fingerprint/aidl/default/Fingerprint.cpp index fa3171f850..6f893468a8 100644 --- a/biometrics/fingerprint/aidl/default/Fingerprint.cpp +++ b/biometrics/fingerprint/aidl/default/Fingerprint.cpp @@ -58,4 +58,9 @@ ndk::ScopedAStatus Fingerprint::createSession(int32_t /*sensorId*/, int32_t /*us *out = SharedRefBase::make(cb); return ndk::ScopedAStatus::ok(); } + +ndk::ScopedAStatus Fingerprint::reset() { + return ndk::ScopedAStatus::ok(); +} + } // namespace aidl::android::hardware::biometrics::fingerprint diff --git a/biometrics/fingerprint/aidl/default/Session.cpp b/biometrics/fingerprint/aidl/default/Session.cpp index 52dddb665e..c928df4dd5 100644 --- a/biometrics/fingerprint/aidl/default/Session.cpp +++ b/biometrics/fingerprint/aidl/default/Session.cpp @@ -99,6 +99,11 @@ ndk::ScopedAStatus Session::resetLockout(int32_t /*cookie*/, return ndk::ScopedAStatus::ok(); } +ndk::ScopedAStatus Session::close(int32_t /*cookie*/) { + LOG(INFO) << "close"; + return ndk::ScopedAStatus::ok(); +} + ndk::ScopedAStatus Session::onPointerDown(int32_t /*pointerId*/, int32_t /*x*/, int32_t /*y*/, float /*minor*/, float /*major*/) { LOG(INFO) << "onPointerDown"; diff --git a/biometrics/fingerprint/aidl/default/include/Fingerprint.h b/biometrics/fingerprint/aidl/default/include/Fingerprint.h index 867e5fafb3..ce1366cf4c 100644 --- a/biometrics/fingerprint/aidl/default/include/Fingerprint.h +++ b/biometrics/fingerprint/aidl/default/include/Fingerprint.h @@ -29,6 +29,8 @@ class Fingerprint final : public BnFingerprint { ndk::ScopedAStatus createSession(int32_t sensorId, int32_t userId, const std::shared_ptr& cb, std::shared_ptr* out) override; + + ndk::ScopedAStatus reset() override; }; } // 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 b9befef119..99d806b5e5 100644 --- a/biometrics/fingerprint/aidl/default/include/Session.h +++ b/biometrics/fingerprint/aidl/default/include/Session.h @@ -53,6 +53,8 @@ class Session : public BnSession { ndk::ScopedAStatus resetLockout(int32_t cookie, const keymaster::HardwareAuthToken& hat) override; + ndk::ScopedAStatus close(int32_t cookie) override; + ndk::ScopedAStatus onPointerDown(int32_t pointerId, int32_t x, int32_t y, float minor, float major) override; -- GitLab From 42a106315b584e7426253aa10024abce28a6422e Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Tue, 15 Dec 2020 13:35:53 -0800 Subject: [PATCH 471/790] Add IFace#reset and ISession#close methods Bug: 180625923 Test: m android.hardware.biometrics.face-update-api Test: build Change-Id: I6ec2436ff4ae4c11a177ab911aebe4e80a591089 --- .../hardware/biometrics/face/IFace.aidl | 1 + .../hardware/biometrics/face/ISession.aidl | 1 + .../biometrics/face/SessionState.aidl | 2 +- .../hardware/biometrics/face/IFace.aidl | 13 +++++++ .../hardware/biometrics/face/ISession.aidl | 34 ++++++++++++++----- .../biometrics/face/SessionState.aidl | 5 ++- 6 files changed, 44 insertions(+), 12 deletions(-) diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl index 37345ec01b..bfaf90d0e1 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl @@ -35,4 +35,5 @@ package android.hardware.biometrics.face; interface IFace { android.hardware.biometrics.face.SensorProps[] getSensorProps(); android.hardware.biometrics.face.ISession createSession(in int sensorId, in int userId, in android.hardware.biometrics.face.ISessionCallback cb); + void reset(); } 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 b855a9ede1..c9165e1ab6 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 @@ -45,4 +45,5 @@ interface ISession { void getAuthenticatorId(in int cookie); void invalidateAuthenticatorId(in int cookie); void resetLockout(in int cookie, in android.hardware.keymaster.HardwareAuthToken hat); + void close(in int cookie); } diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SessionState.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SessionState.aidl index 46751d03d0..3792eae17f 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SessionState.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SessionState.aidl @@ -34,7 +34,7 @@ package android.hardware.biometrics.face; @Backing(type="byte") @VintfStability enum SessionState { IDLING = 0, - TERMINATED = 1, + CLOSED = 1, GENERATING_CHALLENGE = 2, REVOKING_CHALLENGE = 3, ENROLLING = 4, diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/IFace.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/IFace.aidl index f9ed4b1701..afb7c8de65 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/IFace.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/IFace.aidl @@ -35,6 +35,10 @@ interface IFace { * Creates a session that can be used by the framework to perform operations such as * enroll, authenticate, etc. for the given sensorId and userId. * + * Calling this method while there is an active session is considered an error. If the + * framework is in a bad state and for some reason cannot close its session, it should use + * the reset method below. + * * Implementations must store user-specific state or metadata in /data/vendor_de//facedata * as specified by the SELinux policy. The directory /data/vendor_de is managed by vold (see * vold_prepare_subdirs.cpp). Implementations may store additional user-specific data, such as @@ -47,4 +51,13 @@ interface IFace { */ ISession createSession(in int sensorId, in int userId, in ISessionCallback cb); + /** + * Resets the HAL into a clean state, forcing it to cancel all of the pending operations, close + * its current session, and release all of the acquired resources. + * + * This should be used as a last resort to recover the HAL if the current session becomes + * unresponsive. The implementation might choose to restart the HAL process to get back into a + * good state. + */ + void reset(); } diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl index f540502669..6f2014a61f 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl @@ -17,19 +17,20 @@ package android.hardware.biometrics.face; import android.hardware.biometrics.common.ICancellationSignal; -import android.hardware.biometrics.face.Feature; import android.hardware.biometrics.face.EnrollmentType; -import android.hardware.keymaster.HardwareAuthToken; +import android.hardware.biometrics.face.Feature; import android.hardware.common.NativeHandle; +import android.hardware.keymaster.HardwareAuthToken; -/** * A session is a collection of immutable state (sensorId, userId), mutable state (SessionState), +/** + * A session is a collection of immutable state (sensorId, userId), mutable state (SessionState), * methods available for the framework to call, and a callback (ISessionCallback) to notify the * framework about the events and results. A session is used to establish communication between * the framework and the HAL. */ @VintfStability interface ISession { - /** + /** * generateChallenge: * * Begins a secure transaction request. Note that the challenge by itself is not useful. It only @@ -134,9 +135,9 @@ interface ISession { * @param hat See above documentation. * @param enrollmentType See the EnrollmentType enum. * @param features See the Feature enum. - * @param previewSurface A surface provided by the framework if SensorProps#halControlsPreview is - * set to true. The HAL must send the preview frames to previewSurface if - * it's not null. + * @param previewSurface A surface provided by the framework if SensorProps#halControlsPreview + * is set to true. The HAL must send the preview frames to previewSurface + * if it's not null. * @return ICancellationSignal An object that can be used by the framework to cancel this * operation. */ @@ -420,5 +421,22 @@ interface ISession { * @param hat HardwareAuthToken See above documentation. */ void resetLockout(in int cookie, in HardwareAuthToken hat); -} + /* + * Close this session and allow the HAL to release the resources associated with this session. + * + * A session can only be closed when it's in SessionState::IDLING. Closing a session will + * result in a ISessionCallback#onStateChanged call with SessionState::CLOSED. + * + * If a session is unresponsive or stuck in a state other than SessionState::CLOSED, + * IFace#reset could be used as a last resort to terminate the session and recover the HAL + * from a bad state. + * + * All sessions must be explicitly closed. Calling IFace#createSession while there is an active + * session is considered an error. + * + * @param cookie An identifier used to track subsystem operations related to this call path. The + * client must guarantee that it is unique per ISession. + */ + void close(in int cookie); +} diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/SessionState.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/SessionState.aidl index 76755649e4..afde4eb2d5 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/SessionState.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/SessionState.aidl @@ -25,9 +25,9 @@ enum SessionState { IDLING, /** - * The session has been terminated by the HAL. + * The session has been closed by the client. */ - TERMINATED, + CLOSED, /** * The HAL is processing the ISession#generateChallenge request. @@ -89,4 +89,3 @@ enum SessionState { */ RESETTING_LOCKOUT } - -- GitLab From e52cae0fc88b8b8c96b136adc4e5fc29305d0f34 Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Wed, 17 Feb 2021 16:38:56 -0800 Subject: [PATCH 472/790] Update default HAL with close and reset methods Bug: 180625923 Test: atest VtsHalBiometricsFaceTargetTest Change-Id: Ie0881ec827a7ab0c277373da36ecdf3502ef0f15 --- biometrics/face/aidl/default/Face.cpp | 4 ++++ biometrics/face/aidl/default/Face.h | 2 ++ biometrics/face/aidl/default/Session.cpp | 4 ++++ biometrics/face/aidl/default/Session.h | 2 ++ 4 files changed, 12 insertions(+) diff --git a/biometrics/face/aidl/default/Face.cpp b/biometrics/face/aidl/default/Face.cpp index 773359e89c..2b4085054b 100644 --- a/biometrics/face/aidl/default/Face.cpp +++ b/biometrics/face/aidl/default/Face.cpp @@ -63,4 +63,8 @@ ndk::ScopedAStatus Face::createSession(int32_t /*sensorId*/, int32_t /*userId*/, return ndk::ScopedAStatus::ok(); } +ndk::ScopedAStatus Face::reset() { + return ndk::ScopedAStatus::ok(); +} + } // namespace aidl::android::hardware::biometrics::face diff --git a/biometrics/face/aidl/default/Face.h b/biometrics/face/aidl/default/Face.h index 786b4f89fe..809b8568c2 100644 --- a/biometrics/face/aidl/default/Face.h +++ b/biometrics/face/aidl/default/Face.h @@ -27,6 +27,8 @@ class Face : public BnFace { ndk::ScopedAStatus createSession(int32_t sensorId, int32_t userId, const std::shared_ptr& cb, std::shared_ptr* _aidl_return) override; + + ndk::ScopedAStatus reset() override; }; } // namespace aidl::android::hardware::biometrics::face diff --git a/biometrics/face/aidl/default/Session.cpp b/biometrics/face/aidl/default/Session.cpp index bd5a0625f9..a7130e62d0 100644 --- a/biometrics/face/aidl/default/Session.cpp +++ b/biometrics/face/aidl/default/Session.cpp @@ -142,4 +142,8 @@ ndk::ScopedAStatus Session::resetLockout(int32_t /*cookie*/, return ndk::ScopedAStatus::ok(); } +ndk::ScopedAStatus Session::close(int32_t /*cookie*/) { + return ndk::ScopedAStatus::ok(); +} + } // namespace aidl::android::hardware::biometrics::face diff --git a/biometrics/face/aidl/default/Session.h b/biometrics/face/aidl/default/Session.h index 83cb0641d6..0651726d0a 100644 --- a/biometrics/face/aidl/default/Session.h +++ b/biometrics/face/aidl/default/Session.h @@ -63,6 +63,8 @@ class Session : public BnSession { ndk::ScopedAStatus resetLockout(int32_t cookie, const keymaster::HardwareAuthToken& hat) override; + ndk::ScopedAStatus close(int32_t cookie) override; + private: std::shared_ptr cb_; }; -- GitLab From 9d5289fa065c3ffa20314276ab91f569c4dd9b1c Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Thu, 18 Feb 2021 13:56:45 -0800 Subject: [PATCH 473/790] Wait for all the thread loop to exit to finish the filter/dvr/frontend close/stop API Call Test: atest android.media.tv.tuner.cts Bug: 180641600 Change-Id: I0925e8ffe5604d2c6a48871897871f5ac51c572e --- tv/tuner/1.1/default/Demux.cpp | 11 ++++++++--- tv/tuner/1.1/default/Dvr.cpp | 13 ++++++++++--- tv/tuner/1.1/default/Filter.cpp | 24 ++++++++++++++++-------- 3 files changed, 34 insertions(+), 14 deletions(-) diff --git a/tv/tuner/1.1/default/Demux.cpp b/tv/tuner/1.1/default/Demux.cpp index 66c95dc3c2..f4e4a919de 100644 --- a/tv/tuner/1.1/default/Demux.cpp +++ b/tv/tuner/1.1/default/Demux.cpp @@ -27,12 +27,16 @@ namespace V1_0 { namespace implementation { #define WAIT_TIMEOUT 3000000000 + Demux::Demux(uint32_t demuxId, sp tuner) { mDemuxId = demuxId; mTunerService = tuner; } -Demux::~Demux() {} +Demux::~Demux() { + mFrontendInputThreadRunning = false; + std::lock_guard lock(mFrontendInputThreadLock); +} Return Demux::setFrontendDataSource(uint32_t frontendId) { ALOGV("%s", __FUNCTION__); @@ -171,6 +175,8 @@ Return Demux::close() { mFilters.clear(); mLastUsedFilterId = -1; mTunerService->removeDemux(mDemuxId); + mFrontendInputThreadRunning = false; + std::lock_guard lock(mFrontendInputThreadLock); return Result::SUCCESS; } @@ -322,6 +328,7 @@ uint16_t Demux::getFilterTpid(uint64_t filterId) { } void Demux::startFrontendInputLoop() { + mFrontendInputThreadRunning = true; pthread_create(&mFrontendInputThread, NULL, __threadLoopFrontend, this); pthread_setname_np(mFrontendInputThread, "frontend_input_thread"); } @@ -334,8 +341,6 @@ void* Demux::__threadLoopFrontend(void* user) { void Demux::frontendInputThreadLoop() { std::lock_guard lock(mFrontendInputThreadLock); - mFrontendInputThreadRunning = true; - if (!mDvrPlayback) { ALOGW("[Demux] No software Frontend input configured. Ending Frontend thread loop."); mFrontendInputThreadRunning = false; diff --git a/tv/tuner/1.1/default/Dvr.cpp b/tv/tuner/1.1/default/Dvr.cpp index 3a4ef1bee7..93bb6a875b 100644 --- a/tv/tuner/1.1/default/Dvr.cpp +++ b/tv/tuner/1.1/default/Dvr.cpp @@ -37,7 +37,10 @@ Dvr::Dvr(DvrType type, uint32_t bufferSize, const sp& cb, sp lock(mDvrThreadLock); +} Return Dvr::getQueueDesc(getQueueDesc_cb _hidl_cb) { ALOGV("%s", __FUNCTION__); @@ -118,6 +121,9 @@ Return Dvr::detachFilter(const sp& filter) { Return Dvr::start() { ALOGV("%s", __FUNCTION__); + if (mDvrThreadRunning) { + return Result::SUCCESS; + } if (!mCallback) { return Result::NOT_INITIALIZED; @@ -128,6 +134,7 @@ Return Dvr::start() { } if (mType == DvrType::PLAYBACK) { + mDvrThreadRunning = true; pthread_create(&mDvrThread, NULL, __threadLoopPlayback, this); pthread_setname_np(mDvrThread, "playback_waiting_loop"); } else if (mType == DvrType::RECORD) { @@ -144,7 +151,6 @@ Return Dvr::stop() { ALOGV("%s", __FUNCTION__); mDvrThreadRunning = false; - lock_guard lock(mDvrThreadLock); mIsRecordStarted = false; @@ -164,6 +170,8 @@ Return Dvr::flush() { Return Dvr::close() { ALOGV("%s", __FUNCTION__); + mDvrThreadRunning = false; + lock_guard lock(mDvrThreadLock); return Result::SUCCESS; } @@ -199,7 +207,6 @@ void* Dvr::__threadLoopPlayback(void* user) { void Dvr::playbackThreadLoop() { ALOGD("[Dvr] playback threadLoop start."); lock_guard lock(mDvrThreadLock); - mDvrThreadRunning = true; while (mDvrThreadRunning) { uint32_t efState = 0; diff --git a/tv/tuner/1.1/default/Filter.cpp b/tv/tuner/1.1/default/Filter.cpp index 6b2413c97e..2e29aa9696 100644 --- a/tv/tuner/1.1/default/Filter.cpp +++ b/tv/tuner/1.1/default/Filter.cpp @@ -77,7 +77,10 @@ Filter::Filter(DemuxFilterType type, uint64_t filterId, uint32_t bufferSize, } } -Filter::~Filter() {} +Filter::~Filter() { + mFilterThreadRunning = false; + std::lock_guard lock(mFilterThreadLock); +} Return Filter::getId64Bit(getId64Bit_cb _hidl_cb) { ALOGV("%s", __FUNCTION__); @@ -137,15 +140,14 @@ Return Filter::configure(const DemuxFilterSettings& settings) { Return Filter::start() { ALOGV("%s", __FUNCTION__); - + mFilterThreadRunning = true; return startFilterLoop(); } Return Filter::stop() { ALOGV("%s", __FUNCTION__); - mFilterThreadRunning = false; - + std::lock_guard lock(mFilterThreadLock); return Result::SUCCESS; } @@ -185,6 +187,8 @@ Return Filter::releaseAvHandle(const hidl_handle& avMemory, uint64_t avD Return Filter::close() { ALOGV("%s", __FUNCTION__); + mFilterThreadRunning = false; + std::lock_guard lock(mFilterThreadLock); return mDemux->removeFilter(mFilterId); } @@ -331,9 +335,11 @@ void* Filter::__threadLoopFilter(void* user) { } void Filter::filterThreadLoop() { - ALOGD("[Filter] filter %" PRIu64 " threadLoop start.", mFilterId); + if (!mFilterThreadRunning) { + return; + } std::lock_guard lock(mFilterThreadLock); - mFilterThreadRunning = true; + ALOGD("[Filter] filter %" PRIu64 " threadLoop start.", mFilterId); // For the first time of filter output, implementation needs to send the filter // Event Callback without waiting for the DATA_CONSUMED to init the process. @@ -382,6 +388,9 @@ void Filter::filterThreadLoop() { // We do not wait for the last round of written data to be read to finish the thread // because the VTS can verify the reading itself. for (int i = 0; i < SECTION_WRITE_COUNT; i++) { + if (!mFilterThreadRunning) { + break; + } while (mFilterThreadRunning && mIsUsingFMQ) { status_t status = mFilterEventFlag->wait( static_cast(DemuxQueueNotifyBits::DATA_CONSUMED), &efState, @@ -417,9 +426,8 @@ void Filter::filterThreadLoop() { break; } } - mFilterThreadRunning = false; + break; } - ALOGD("[Filter] filter thread ended."); } -- GitLab From 81c2d68ff22a4ccd6c49ed245d961dc0f6931a36 Mon Sep 17 00:00:00 2001 From: Kai Date: Tue, 16 Feb 2021 21:19:22 -0800 Subject: [PATCH 474/790] Update doc for PERF_VEHICLE_SPEED Vehicle_speed should be negative if the vehicle is moving in reverse. Bug: 127573221 Test: build image Change-Id: I0cb2baef16a778278a3011ed49e3e36a7da09122 --- automotive/vehicle/2.0/types.hal | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/automotive/vehicle/2.0/types.hal b/automotive/vehicle/2.0/types.hal index ed75e1dfb7..e3fd16de57 100644 --- a/automotive/vehicle/2.0/types.hal +++ b/automotive/vehicle/2.0/types.hal @@ -354,6 +354,12 @@ enum VehicleProperty : int32_t { /** * Speed of the vehicle * + * The value must be positive when the vehicle is moving forward and negative when + * the vehicle is moving backward. This value is independent of gear value + * (CURRENT_GEAR or GEAR_SELECTION), for example, if GEAR_SELECTION is GEAR_NEUTRAL, + * PERF_VEHICLE_SPEED is positive when the vehicle is moving forward, negative when moving + * backward, and zero when not moving. + * * @change_mode VehiclePropertyChangeMode:CONTINUOUS * @access VehiclePropertyAccess:READ * @unit VehicleUnit:METER_PER_SEC -- GitLab From da3a54da937027534cb1a59488bb7f6545eee8d7 Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Thu, 18 Feb 2021 21:47:00 -0800 Subject: [PATCH 475/790] Add VTS to test link/unlinkCicam in IFrontend Test: atest VtsHalTvTunerV1_1TargetTest Bug: 158818696 Change-Id: If741e7c5482ab1a65fc74b02b0be6c7fdb784e02 --- tv/tuner/1.1/vts/functional/FilterTests.cpp | 1 + tv/tuner/1.1/vts/functional/FrontendTests.cpp | 34 +++++++++++++++++++ tv/tuner/1.1/vts/functional/FrontendTests.h | 3 ++ .../VtsHalTvTunerV1_1TargetTest.cpp | 5 +++ .../VtsHalTvTunerV1_1TestConfigurations.h | 5 +++ 5 files changed, 48 insertions(+) diff --git a/tv/tuner/1.1/vts/functional/FilterTests.cpp b/tv/tuner/1.1/vts/functional/FilterTests.cpp index d8fad3d5d2..1617642693 100644 --- a/tv/tuner/1.1/vts/functional/FilterTests.cpp +++ b/tv/tuner/1.1/vts/functional/FilterTests.cpp @@ -274,6 +274,7 @@ AssertionResult FilterTests::startFilter(uint64_t filterId) { AssertionResult FilterTests::stopFilter(uint64_t filterId) { EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first."; Result status = mFilters[filterId]->stop(); + return AssertionResult(status == Result::SUCCESS); } diff --git a/tv/tuner/1.1/vts/functional/FrontendTests.cpp b/tv/tuner/1.1/vts/functional/FrontendTests.cpp index 0948f743ad..887f8b8131 100644 --- a/tv/tuner/1.1/vts/functional/FrontendTests.cpp +++ b/tv/tuner/1.1/vts/functional/FrontendTests.cpp @@ -305,6 +305,36 @@ AssertionResult FrontendTests::getFrontendDtmbCaps(uint32_t id) { return AssertionResult(status == Result::SUCCESS); } +AssertionResult FrontendTests::linkCiCam(uint32_t ciCamId) { + sp frontend_1_1; + frontend_1_1 = android::hardware::tv::tuner::V1_1::IFrontend::castFrom(mFrontend); + if (frontend_1_1 == nullptr) { + EXPECT_TRUE(false) << "Couldn't get 1.1 IFrontend from the Hal implementation."; + return failure(); + } + + Result status; + uint32_t ltsId; + frontend_1_1->linkCiCam(ciCamId, [&](Result r, uint32_t id) { + status = r; + ltsId = id; + }); + + return AssertionResult(status == Result::SUCCESS); +} + +AssertionResult FrontendTests::unlinkCiCam(uint32_t ciCamId) { + sp frontend_1_1; + frontend_1_1 = android::hardware::tv::tuner::V1_1::IFrontend::castFrom(mFrontend); + if (frontend_1_1 == nullptr) { + EXPECT_TRUE(false) << "Couldn't get 1.1 IFrontend from the Hal implementation."; + return failure(); + } + + Result status = frontend_1_1->unlinkCiCam(ciCamId); + return AssertionResult(status == Result::SUCCESS); +} + void FrontendTests::verifyFrontendStatusExt1_1(vector statusTypes, vector expectStatuses) { ASSERT_TRUE(mFrontend) << "Frontend is not opened yet."; @@ -465,6 +495,10 @@ void FrontendTests::tuneTest(FrontendConfig frontendConf) { ASSERT_TRUE(feId != INVALID_ID); ASSERT_TRUE(openFrontendById(feId)); ASSERT_TRUE(setFrontendCallback()); + if (frontendConf.canConnectToCiCam) { + ASSERT_TRUE(linkCiCam(frontendConf.ciCamId)); + ASSERT_TRUE(unlinkCiCam(frontendConf.ciCamId)); + } ASSERT_TRUE(tuneFrontend(frontendConf, false /*testWithDemux*/)); verifyFrontendStatusExt1_1(frontendConf.tuneStatusTypes, frontendConf.expectTuneStatuses); ASSERT_TRUE(stopTuneFrontend(false /*testWithDemux*/)); diff --git a/tv/tuner/1.1/vts/functional/FrontendTests.h b/tv/tuner/1.1/vts/functional/FrontendTests.h index 243d9decd7..43c1579cb7 100644 --- a/tv/tuner/1.1/vts/functional/FrontendTests.h +++ b/tv/tuner/1.1/vts/functional/FrontendTests.h @@ -123,6 +123,9 @@ class FrontendTests { AssertionResult closeFrontend(); AssertionResult getFrontendDtmbCaps(uint32_t); + AssertionResult linkCiCam(uint32_t ciCamId); + AssertionResult unlinkCiCam(uint32_t ciCamId); + void getFrontendIdByType(FrontendType feType, uint32_t& feId); void tuneTest(FrontendConfig frontendConf); void scanTest(FrontendConfig frontend, FrontendScanType type); diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp index 2dcb9a14e5..2e6c87fb5a 100644 --- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp @@ -211,6 +211,11 @@ TEST_P(TunerFrontendHidlTest, GetFrontendDtmbCaps) { mFrontendTests.getFrontendDtmbCapsTest(); } +TEST_P(TunerFrontendHidlTest, LinkToCiCam) { + description("Test Frontend link to CiCam"); + mFrontendTests.tuneTest(frontendArray[defaultFrontend]); +} + INSTANTIATE_TEST_SUITE_P( PerInstance, TunerBroadcastHidlTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames(ITuner::descriptor)), diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h index beae223e4b..ecdf683b24 100644 --- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h @@ -103,6 +103,8 @@ struct FilterConfig { struct FrontendConfig { bool isSoftwareFe; + bool canConnectToCiCam; + uint32_t ciCamId; FrontendType type; FrontendSettings settings; FrontendSettingsExt1_1 settingsExt1_1; @@ -121,6 +123,7 @@ static FrontendConfig frontendArray[FILTER_MAX]; static FrontendConfig frontendScanArray[SCAN_MAX]; static FilterConfig filterArray[FILTER_MAX]; static DvrConfig dvrArray[DVR_MAX]; +static int defaultFrontend = DVBT; /** Configuration array for the frontend tune test */ inline void initFrontendConfig() { @@ -150,6 +153,8 @@ inline void initFrontendConfig() { frontendArray[DVBT].tuneStatusTypes = types; frontendArray[DVBT].expectTuneStatuses = statuses; frontendArray[DVBT].isSoftwareFe = true; + frontendArray[DVBT].canConnectToCiCam = true; + frontendArray[DVBT].ciCamId = 0; frontendArray[DVBT].settingsExt1_1.settingExt.dvbt({ .transmissionMode = android::hardware::tv::tuner::V1_1::FrontendDvbtTransmissionMode::MODE_8K_E, -- GitLab From 4f05f7c2de698c0c78fd8c03407d85e941084f62 Mon Sep 17 00:00:00 2001 From: Quang Luong Date: Mon, 22 Feb 2021 11:13:54 -0800 Subject: [PATCH 476/790] [WifiCoex] Fix VTS test for implemented hal Fix coex VTS test by configuring chip for sta iface before invoking the coex hal api. Bug: 177929636 Test: atest VtsHalWifiV1_5TargetTest Change-Id: I5ead53e603a2136e3c8b2d931c512e6d337f4ba7 --- wifi/1.5/vts/functional/wifi_chip_hidl_test.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/wifi/1.5/vts/functional/wifi_chip_hidl_test.cpp b/wifi/1.5/vts/functional/wifi_chip_hidl_test.cpp index 5ac747de22..07f7f470fe 100644 --- a/wifi/1.5/vts/functional/wifi_chip_hidl_test.cpp +++ b/wifi/1.5/vts/functional/wifi_chip_hidl_test.cpp @@ -147,6 +147,7 @@ TEST_P(WifiChipHidlTest, setMultiStaUseCase) { * setCoexUnsafeChannels */ TEST_P(WifiChipHidlTest, setCoexUnsafeChannels) { + configureChipForIfaceType(IfaceType::STA, true); // Test with empty vector of CoexUnsafeChannels std::vector vec; const auto& statusEmpty = -- GitLab From 4f5d6801e9da3e728d87235a496a520bea224c68 Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Mon, 22 Feb 2021 13:10:55 -0800 Subject: [PATCH 477/790] Add move-only lambdas support Bug: 166800618 Test: atest --host android.hardware.biometrics.fingerprint.WorkerThreadTest Change-Id: I582d44d5098b7426663b75200c822bc6e8bb70a6 --- .../fingerprint/aidl/default/WorkerThread.cpp | 6 +-- .../aidl/default/include/Callable.h | 54 +++++++++++++++++++ .../aidl/default/include/WorkerThread.h | 13 +++-- .../aidl/default/tests/WorkerThreadTest.cpp | 23 ++++---- 4 files changed, 78 insertions(+), 18 deletions(-) create mode 100644 biometrics/fingerprint/aidl/default/include/Callable.h diff --git a/biometrics/fingerprint/aidl/default/WorkerThread.cpp b/biometrics/fingerprint/aidl/default/WorkerThread.cpp index 512efb8d5d..d1a63d07ee 100644 --- a/biometrics/fingerprint/aidl/default/WorkerThread.cpp +++ b/biometrics/fingerprint/aidl/default/WorkerThread.cpp @@ -36,7 +36,7 @@ WorkerThread::~WorkerThread() { mThread.join(); } -bool WorkerThread::schedule(Task&& task) { +bool WorkerThread::schedule(std::unique_ptr task) { if (mIsDestructing) { return false; } @@ -58,10 +58,10 @@ void WorkerThread::threadFunc() { if (mIsDestructing) { return; } - Task task = std::move(mQueue.front()); + std::unique_ptr task = std::move(mQueue.front()); mQueue.pop_front(); lock.unlock(); - task(); + (*task)(); } } diff --git a/biometrics/fingerprint/aidl/default/include/Callable.h b/biometrics/fingerprint/aidl/default/include/Callable.h new file mode 100644 index 0000000000..c6295117e5 --- /dev/null +++ b/biometrics/fingerprint/aidl/default/include/Callable.h @@ -0,0 +1,54 @@ +/* + * 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 + +namespace aidl::android::hardware::biometrics::fingerprint { + +// Interface for representing parameterless functions. Unlike std::function, this can also +// represent move-only lambdas. +class Callable { + public: + virtual void operator()() = 0; + virtual ~Callable() = default; + + // Creates a heap-allocated Callable instance from any function object. + template + static std::unique_ptr from(T func); + + private: + template + class AnyFuncWrapper; +}; + +// Private helper class for wrapping any function object into a Callable. +template +class Callable::AnyFuncWrapper : public Callable { + public: + explicit AnyFuncWrapper(T func) : mFunc(std::move(func)) {} + + void operator()() override { mFunc(); } + + private: + T mFunc; +}; + +template +std::unique_ptr Callable::from(T func) { + return std::make_unique>(std::move(func)); +} + +} // namespace aidl::android::hardware::biometrics::fingerprint \ No newline at end of file diff --git a/biometrics/fingerprint/aidl/default/include/WorkerThread.h b/biometrics/fingerprint/aidl/default/include/WorkerThread.h index 49104c85e2..6fff4f2cb7 100644 --- a/biometrics/fingerprint/aidl/default/include/WorkerThread.h +++ b/biometrics/fingerprint/aidl/default/include/WorkerThread.h @@ -21,9 +21,9 @@ #include #include -namespace aidl::android::hardware::biometrics::fingerprint { +#include "Callable.h" -using Task = std::function; +namespace aidl::android::hardware::biometrics::fingerprint { // A class that encapsulates a worker thread and a task queue, and provides a convenient interface // for a Session to schedule its tasks for asynchronous execution. @@ -47,7 +47,12 @@ class WorkerThread final { // If the internal queue is not full, pushes a task at the end of the queue and returns true. // Otherwise, returns false. If the queue is busy, blocks until it becomes available. - bool schedule(Task&& task); + // This method expects heap-allocated tasks because it's the simplest way to represent function + // objects of any type. Stack-allocated std::function could be used instead, but it cannot + // represent functions with move-only captures because std::function is inherently copyable. + // Not being able to pass move-only lambdas is a major limitation for the HAL implementation, + // so heap-allocated tasks that share a common interface (Callable) were chosen instead. + bool schedule(std::unique_ptr task); private: // The function that runs on the internal thread. Sequentially runs the available tasks from @@ -63,7 +68,7 @@ class WorkerThread final { std::atomic mIsDestructing; // Queue that's guarded by mQueueMutex and mQueueCond. - std::deque mQueue; + std::deque> mQueue; std::mutex mQueueMutex; std::condition_variable mQueueCond; diff --git a/biometrics/fingerprint/aidl/default/tests/WorkerThreadTest.cpp b/biometrics/fingerprint/aidl/default/tests/WorkerThreadTest.cpp index ba901ad5ca..0d5014bb84 100644 --- a/biometrics/fingerprint/aidl/default/tests/WorkerThreadTest.cpp +++ b/biometrics/fingerprint/aidl/default/tests/WorkerThreadTest.cpp @@ -25,13 +25,14 @@ namespace { +using aidl::android::hardware::biometrics::fingerprint::Callable; using aidl::android::hardware::biometrics::fingerprint::WorkerThread; using namespace std::chrono_literals; TEST(WorkerThreadTest, ScheduleReturnsTrueWhenQueueHasSpace) { WorkerThread worker(1 /*maxQueueSize*/); for (int i = 0; i < 100; ++i) { - EXPECT_TRUE(worker.schedule([] {})); + EXPECT_TRUE(worker.schedule(Callable::from([] {}))); // Allow enough time for the previous task to be processed. std::this_thread::sleep_for(2ms); } @@ -40,16 +41,16 @@ TEST(WorkerThreadTest, ScheduleReturnsTrueWhenQueueHasSpace) { TEST(WorkerThreadTest, ScheduleReturnsFalseWhenQueueIsFull) { WorkerThread worker(2 /*maxQueueSize*/); // Add a long-running task. - worker.schedule([] { std::this_thread::sleep_for(1s); }); + worker.schedule(Callable::from([] { std::this_thread::sleep_for(1s); })); // Allow enough time for the worker to start working on the previous task. std::this_thread::sleep_for(2ms); // Fill the worker's queue to the maximum. - worker.schedule([] {}); - worker.schedule([] {}); + worker.schedule(Callable::from([] {})); + worker.schedule(Callable::from([] {})); - EXPECT_FALSE(worker.schedule([] {})); + EXPECT_FALSE(worker.schedule(Callable::from([] {}))); } TEST(WorkerThreadTest, TasksExecuteInOrder) { @@ -58,19 +59,19 @@ TEST(WorkerThreadTest, TasksExecuteInOrder) { std::vector results; for (int i = 0; i < NUM_TASKS; ++i) { - worker.schedule([&results, i] { + worker.schedule(Callable::from([&results, i] { // Delay tasks differently to provoke races. std::this_thread::sleep_for(std::chrono::nanoseconds(100 - i % 100)); // Unguarded write to results to provoke races. results.push_back(i); - }); + })); } std::promise promise; auto future = promise.get_future(); // Schedule a special task to signal when all of the tasks are finished. - worker.schedule([&promise] { promise.set_value(); }); + worker.schedule(Callable::from([&promise] { promise.set_value(); })); auto status = future.wait_for(1s); ASSERT_EQ(status, std::future_status::ready); @@ -86,11 +87,11 @@ TEST(WorkerThreadTest, ExecutionStopsAfterWorkerIsDestroyed) { { WorkerThread worker(2 /*maxQueueSize*/); - worker.schedule([&promise1] { + worker.schedule(Callable::from([&promise1] { promise1.set_value(); std::this_thread::sleep_for(200ms); - }); - worker.schedule([&promise2] { promise2.set_value(); }); + })); + worker.schedule(Callable::from([&promise2] { promise2.set_value(); })); // Make sure the first task is executing. auto status1 = future1.wait_for(1s); -- GitLab From 48ff8969f8b974d2121dbbcf2adbf334874138c1 Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Mon, 22 Feb 2021 13:13:13 -0800 Subject: [PATCH 478/790] Implement the state machine Bug: 166800618 Bug: 175070939 Test: atest VtsHalBiometricsFingerprintTargetTest Change-Id: I3a908b0f910323d643b220e560e9c2d8e4c5675a --- .../fingerprint/aidl/default/Android.bp | 4 +- .../aidl/default/CancellationSignal.cpp | 37 ++++ .../fingerprint/aidl/default/Fingerprint.cpp | 17 +- .../fingerprint/aidl/default/Session.cpp | 200 ++++++++++++++---- .../aidl/default/include/CancellationSignal.h | 42 ++++ .../default/include/FakeFingerprintEngine.h | 76 +++++++ .../aidl/default/include/Fingerprint.h | 11 +- .../aidl/default/include/Session.h | 29 ++- 8 files changed, 370 insertions(+), 46 deletions(-) create mode 100644 biometrics/fingerprint/aidl/default/CancellationSignal.cpp create mode 100644 biometrics/fingerprint/aidl/default/include/CancellationSignal.h create mode 100644 biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h diff --git a/biometrics/fingerprint/aidl/default/Android.bp b/biometrics/fingerprint/aidl/default/Android.bp index 24087cf036..6b43bffbdd 100644 --- a/biometrics/fingerprint/aidl/default/Android.bp +++ b/biometrics/fingerprint/aidl/default/Android.bp @@ -6,9 +6,11 @@ cc_binary { vintf_fragments: ["fingerprint-default.xml"], local_include_dirs: ["include"], srcs: [ - "main.cpp", + "CancellationSignal.cpp", "Fingerprint.cpp", "Session.cpp", + "WorkerThread.cpp", + "main.cpp", ], shared_libs: [ "libbase", diff --git a/biometrics/fingerprint/aidl/default/CancellationSignal.cpp b/biometrics/fingerprint/aidl/default/CancellationSignal.cpp new file mode 100644 index 0000000000..659831616d --- /dev/null +++ b/biometrics/fingerprint/aidl/default/CancellationSignal.cpp @@ -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. + */ + +#include "CancellationSignal.h" + +#include +#include + +namespace aidl::android::hardware::biometrics::fingerprint { + +CancellationSignal::CancellationSignal(std::promise&& cancellationPromise) + : mCancellationPromise(std::move(cancellationPromise)) {} + +ndk::ScopedAStatus CancellationSignal::cancel() { + mCancellationPromise.set_value(); + return ndk::ScopedAStatus::ok(); +} + +bool shouldCancel(const std::future& f) { + CHECK(f.valid()); + return f.wait_for(std::chrono::seconds(0)) == std::future_status::ready; +} + +} // namespace aidl::android::hardware::biometrics::fingerprint diff --git a/biometrics/fingerprint/aidl/default/Fingerprint.cpp b/biometrics/fingerprint/aidl/default/Fingerprint.cpp index 6f893468a8..67dc34fdd5 100644 --- a/biometrics/fingerprint/aidl/default/Fingerprint.cpp +++ b/biometrics/fingerprint/aidl/default/Fingerprint.cpp @@ -15,11 +15,12 @@ */ #include "Fingerprint.h" + #include "Session.h" namespace aidl::android::hardware::biometrics::fingerprint { namespace { - +constexpr size_t MAX_WORKER_QUEUE_SIZE = 5; constexpr int SENSOR_ID = 1; constexpr common::SensorStrength SENSOR_STRENGTH = common::SensorStrength::STRONG; constexpr int MAX_ENROLLMENTS_PER_USER = 5; @@ -32,7 +33,8 @@ constexpr char SERIAL_NUMBER[] = "00000001"; } // namespace -Fingerprint::Fingerprint() {} +Fingerprint::Fingerprint() + : mEngine(std::make_unique()), mWorker(MAX_WORKER_QUEUE_SIZE) {} ndk::ScopedAStatus Fingerprint::getSensorProps(std::vector* out) { std::vector hardwareInfos = { @@ -52,14 +54,21 @@ ndk::ScopedAStatus Fingerprint::getSensorProps(std::vector* out) { return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Fingerprint::createSession(int32_t /*sensorId*/, int32_t /*userId*/, +ndk::ScopedAStatus Fingerprint::createSession(int32_t sensorId, int32_t userId, const std::shared_ptr& cb, std::shared_ptr* out) { - *out = SharedRefBase::make(cb); + auto sessionSp = mSession.lock(); + CHECK(sessionSp == nullptr || sessionSp->isClosed()) << "Open session already exists!"; + + auto session = SharedRefBase::make(sensorId, userId, cb, mEngine.get(), &mWorker); + mSession = session; + *out = session; return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus Fingerprint::reset() { + // Crash. The system will start a fresh instance of the HAL. + CHECK(false) << "Unable to reset. Crashing."; return ndk::ScopedAStatus::ok(); } diff --git a/biometrics/fingerprint/aidl/default/Session.cpp b/biometrics/fingerprint/aidl/default/Session.cpp index c928df4dd5..f6a03143a0 100644 --- a/biometrics/fingerprint/aidl/default/Session.cpp +++ b/biometrics/fingerprint/aidl/default/Session.cpp @@ -14,93 +14,216 @@ * limitations under the License. */ -#include +#include "Session.h" + #include -#include "Session.h" +#include "CancellationSignal.h" namespace aidl::android::hardware::biometrics::fingerprint { -class CancellationSignal : public common::BnCancellationSignal { - public: - ndk::ScopedAStatus cancel() override { return ndk::ScopedAStatus::ok(); } -}; +Session::Session(int sensorId, int userId, std::shared_ptr cb, + FakeFingerprintEngine* engine, WorkerThread* worker) + : mSensorId(sensorId), + mUserId(userId), + mCb(std::move(cb)), + mEngine(engine), + mWorker(worker), + mScheduledState(SessionState::IDLING), + mCurrentState(SessionState::IDLING) { + CHECK_GE(mSensorId, 0); + CHECK_GE(mUserId, 0); + CHECK(mEngine); + CHECK(mWorker); + CHECK(mCb); +} -Session::Session(std::shared_ptr cb) : mCb(std::move(cb)) {} +void Session::scheduleStateOrCrash(SessionState state) { + CHECK(mScheduledState == SessionState::IDLING); + CHECK(mCurrentState == SessionState::IDLING); + mScheduledState = state; +} + +void Session::enterStateOrCrash(int cookie, SessionState state) { + CHECK(mScheduledState == state); + mCurrentState = mScheduledState; + mScheduledState = SessionState::IDLING; + mCb->onStateChanged(cookie, mCurrentState); +} -ndk::ScopedAStatus Session::generateChallenge(int32_t /*cookie*/, int32_t /*timeoutSec*/) { +void Session::enterIdling(int cookie) { + mCurrentState = SessionState::IDLING; + mCb->onStateChanged(cookie, mCurrentState); +} + +bool Session::isClosed() { + return mCurrentState == SessionState::CLOSED; +} + +ndk::ScopedAStatus Session::generateChallenge(int32_t cookie, int32_t timeoutSec) { LOG(INFO) << "generateChallenge"; + scheduleStateOrCrash(SessionState::GENERATING_CHALLENGE); + + mWorker->schedule(Callable::from([this, cookie, timeoutSec] { + enterStateOrCrash(cookie, SessionState::GENERATING_CHALLENGE); + mEngine->generateChallengeImpl(mCb.get(), timeoutSec); + enterIdling(cookie); + })); + return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::revokeChallenge(int32_t /*cookie*/, int64_t /*challenge*/) { +ndk::ScopedAStatus Session::revokeChallenge(int32_t cookie, int64_t challenge) { LOG(INFO) << "revokeChallenge"; + scheduleStateOrCrash(SessionState::REVOKING_CHALLENGE); + + mWorker->schedule(Callable::from([this, cookie, challenge] { + enterStateOrCrash(cookie, SessionState::REVOKING_CHALLENGE); + mEngine->revokeChallengeImpl(mCb.get(), challenge); + enterIdling(cookie); + })); + return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::enroll(int32_t /*cookie*/, const keymaster::HardwareAuthToken& /*hat*/, - std::shared_ptr* /*out*/) { +ndk::ScopedAStatus Session::enroll(int32_t cookie, const keymaster::HardwareAuthToken& hat, + std::shared_ptr* out) { LOG(INFO) << "enroll"; + scheduleStateOrCrash(SessionState::ENROLLING); + + std::promise cancellationPromise; + auto cancFuture = cancellationPromise.get_future(); + + mWorker->schedule(Callable::from([this, cookie, hat, cancFuture = std::move(cancFuture)] { + enterStateOrCrash(cookie, SessionState::ENROLLING); + if (shouldCancel(cancFuture)) { + mCb->onError(Error::CANCELED, 0 /* vendorCode */); + } else { + mEngine->enrollImpl(mCb.get(), hat); + } + enterIdling(cookie); + })); + + *out = SharedRefBase::make(std::move(cancellationPromise)); return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::authenticate(int32_t /*cookie*/, int64_t /*keystoreOperationId*/, +ndk::ScopedAStatus Session::authenticate(int32_t cookie, int64_t operationId, std::shared_ptr* out) { LOG(INFO) << "authenticate"; - if (mCb) { - mCb->onStateChanged(0, SessionState::AUTHENTICATING); - } - *out = SharedRefBase::make(); + scheduleStateOrCrash(SessionState::AUTHENTICATING); + + std::promise cancPromise; + auto cancFuture = cancPromise.get_future(); + + mWorker->schedule( + Callable::from([this, cookie, operationId, cancFuture = std::move(cancFuture)] { + enterStateOrCrash(cookie, SessionState::AUTHENTICATING); + if (shouldCancel(cancFuture)) { + mCb->onError(Error::CANCELED, 0 /* vendorCode */); + } else { + mEngine->authenticateImpl(mCb.get(), operationId); + } + enterIdling(cookie); + })); + + *out = SharedRefBase::make(std::move(cancPromise)); return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::detectInteraction( - int32_t /*cookie*/, std::shared_ptr* /*out*/) { +ndk::ScopedAStatus Session::detectInteraction(int32_t cookie, + std::shared_ptr* out) { LOG(INFO) << "detectInteraction"; + scheduleStateOrCrash(SessionState::DETECTING_INTERACTION); + + std::promise cancellationPromise; + auto cancFuture = cancellationPromise.get_future(); + + mWorker->schedule(Callable::from([this, cookie, cancFuture = std::move(cancFuture)] { + enterStateOrCrash(cookie, SessionState::DETECTING_INTERACTION); + if (shouldCancel(cancFuture)) { + mCb->onError(Error::CANCELED, 0 /* vendorCode */); + } else { + mEngine->detectInteractionImpl(mCb.get()); + } + enterIdling(cookie); + })); + + *out = SharedRefBase::make(std::move(cancellationPromise)); return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::enumerateEnrollments(int32_t /*cookie*/) { +ndk::ScopedAStatus Session::enumerateEnrollments(int32_t cookie) { LOG(INFO) << "enumerateEnrollments"; - if (mCb) { - mCb->onStateChanged(0, SessionState::ENUMERATING_ENROLLMENTS); - mCb->onEnrollmentsEnumerated(std::vector()); - } + scheduleStateOrCrash(SessionState::ENUMERATING_ENROLLMENTS); + + mWorker->schedule(Callable::from([this, cookie] { + enterStateOrCrash(cookie, SessionState::ENUMERATING_ENROLLMENTS); + mEngine->enumerateEnrollmentsImpl(mCb.get()); + enterIdling(cookie); + })); + return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::removeEnrollments(int32_t /*cookie*/, - const std::vector& /*enrollmentIds*/) { +ndk::ScopedAStatus Session::removeEnrollments(int32_t cookie, + const std::vector& enrollmentIds) { LOG(INFO) << "removeEnrollments"; - if (mCb) { - mCb->onStateChanged(0, SessionState::REMOVING_ENROLLMENTS); - mCb->onEnrollmentsRemoved(std::vector()); - } + scheduleStateOrCrash(SessionState::REMOVING_ENROLLMENTS); + + mWorker->schedule(Callable::from([this, cookie, enrollmentIds] { + enterStateOrCrash(cookie, SessionState::REMOVING_ENROLLMENTS); + mEngine->removeEnrollmentsImpl(mCb.get(), enrollmentIds); + enterIdling(cookie); + })); + return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::getAuthenticatorId(int32_t /*cookie*/) { +ndk::ScopedAStatus Session::getAuthenticatorId(int32_t cookie) { LOG(INFO) << "getAuthenticatorId"; - if (mCb) { - mCb->onStateChanged(0, SessionState::GETTING_AUTHENTICATOR_ID); - mCb->onAuthenticatorIdRetrieved(0 /* authenticatorId */); - } + scheduleStateOrCrash(SessionState::GETTING_AUTHENTICATOR_ID); + + mWorker->schedule(Callable::from([this, cookie] { + enterStateOrCrash(cookie, SessionState::GETTING_AUTHENTICATOR_ID); + mEngine->getAuthenticatorIdImpl(mCb.get()); + enterIdling(cookie); + })); + return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::invalidateAuthenticatorId(int32_t /*cookie*/) { +ndk::ScopedAStatus Session::invalidateAuthenticatorId(int32_t cookie) { LOG(INFO) << "invalidateAuthenticatorId"; + scheduleStateOrCrash(SessionState::INVALIDATING_AUTHENTICATOR_ID); + + mWorker->schedule(Callable::from([this, cookie] { + enterStateOrCrash(cookie, SessionState::INVALIDATING_AUTHENTICATOR_ID); + mEngine->invalidateAuthenticatorIdImpl(mCb.get()); + enterIdling(cookie); + })); + return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::resetLockout(int32_t /*cookie*/, - const keymaster::HardwareAuthToken& /*hat*/) { +ndk::ScopedAStatus Session::resetLockout(int32_t cookie, const keymaster::HardwareAuthToken& hat) { LOG(INFO) << "resetLockout"; + scheduleStateOrCrash(SessionState::RESETTING_LOCKOUT); + + mWorker->schedule(Callable::from([this, cookie, hat] { + enterStateOrCrash(cookie, SessionState::RESETTING_LOCKOUT); + mEngine->resetLockoutImpl(mCb.get(), hat); + enterIdling(cookie); + })); + return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::close(int32_t /*cookie*/) { +ndk::ScopedAStatus Session::close(int32_t cookie) { LOG(INFO) << "close"; + CHECK(mCurrentState == SessionState::IDLING) << "Can't close a non-idling session. Crashing."; + mCurrentState = SessionState::CLOSED; + mCb->onStateChanged(cookie, mCurrentState); return ndk::ScopedAStatus::ok(); } @@ -119,4 +242,5 @@ ndk::ScopedAStatus Session::onUiReady() { LOG(INFO) << "onUiReady"; return ndk::ScopedAStatus::ok(); } + } // namespace aidl::android::hardware::biometrics::fingerprint diff --git a/biometrics/fingerprint/aidl/default/include/CancellationSignal.h b/biometrics/fingerprint/aidl/default/include/CancellationSignal.h new file mode 100644 index 0000000000..99f2fbae97 --- /dev/null +++ b/biometrics/fingerprint/aidl/default/include/CancellationSignal.h @@ -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. + */ + +#pragma once + +#include +#include +#include +#include + +#include "WorkerThread.h" + +namespace aidl::android::hardware::biometrics::fingerprint { + +class CancellationSignal : public common::BnCancellationSignal { + public: + explicit CancellationSignal(std::promise&& cancellationPromise); + + ndk::ScopedAStatus cancel() override; + + private: + std::promise mCancellationPromise; +}; + +// Returns whether the given cancellation future is ready, i.e. whether the operation corresponding +// to this future should be cancelled. +bool shouldCancel(const std::future& cancellationFuture); + +} // namespace aidl::android::hardware::biometrics::fingerprint diff --git a/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h new file mode 100644 index 0000000000..934331638e --- /dev/null +++ b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h @@ -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. + */ + +#pragma once + +#include + +namespace aidl::android::hardware::biometrics::fingerprint { + +class FakeFingerprintEngine { + public: + void generateChallengeImpl(ISessionCallback* cb, int32_t /*timeoutSec*/) { + LOG(INFO) << "generateChallengeImpl"; + cb->onChallengeGenerated(0 /* challenge */); + } + + void revokeChallengeImpl(ISessionCallback* cb, int64_t challenge) { + LOG(INFO) << "revokeChallengeImpl"; + cb->onChallengeRevoked(challenge); + } + + void enrollImpl(ISessionCallback* cb, const keymaster::HardwareAuthToken& /*hat*/) { + LOG(INFO) << "enrollImpl"; + cb->onEnrollmentProgress(0 /* enrollmentId */, 0 /* remaining */); + } + + void authenticateImpl(ISessionCallback* cb, int64_t /*operationId*/) { + LOG(INFO) << "authenticateImpl"; + cb->onAuthenticationSucceeded(0 /* enrollmentId */, {} /* hat */); + } + + void detectInteractionImpl(ISessionCallback* cb) { + LOG(INFO) << "detectInteractionImpl"; + cb->onInteractionDetected(); + } + + void enumerateEnrollmentsImpl(ISessionCallback* cb) { + LOG(INFO) << "enumerateEnrollmentsImpl"; + cb->onEnrollmentsEnumerated({} /* enrollmentIds */); + } + + void removeEnrollmentsImpl(ISessionCallback* cb, const std::vector& enrollmentIds) { + LOG(INFO) << "removeEnrollmentsImpl"; + cb->onEnrollmentsRemoved(enrollmentIds); + } + + void getAuthenticatorIdImpl(ISessionCallback* cb) { + LOG(INFO) << "getAuthenticatorIdImpl"; + cb->onAuthenticatorIdRetrieved(0 /* authenticatorId */); + } + + void invalidateAuthenticatorIdImpl(ISessionCallback* cb) { + LOG(INFO) << "invalidateAuthenticatorIdImpl"; + cb->onAuthenticatorIdInvalidated(0 /* newAuthenticatorId */); + } + + void resetLockoutImpl(ISessionCallback* cb, const keymaster::HardwareAuthToken& /*hat*/) { + LOG(INFO) << "resetLockoutImpl"; + cb->onLockoutCleared(); + } +}; + +} // namespace aidl::android::hardware::biometrics::fingerprint \ No newline at end of file diff --git a/biometrics/fingerprint/aidl/default/include/Fingerprint.h b/biometrics/fingerprint/aidl/default/include/Fingerprint.h index ce1366cf4c..9b8eef85ea 100644 --- a/biometrics/fingerprint/aidl/default/include/Fingerprint.h +++ b/biometrics/fingerprint/aidl/default/include/Fingerprint.h @@ -18,9 +18,13 @@ #include +#include "FakeFingerprintEngine.h" +#include "Session.h" +#include "WorkerThread.h" + namespace aidl::android::hardware::biometrics::fingerprint { -class Fingerprint final : public BnFingerprint { +class Fingerprint : public BnFingerprint { public: Fingerprint(); @@ -31,6 +35,11 @@ class Fingerprint final : public BnFingerprint { std::shared_ptr* out) override; ndk::ScopedAStatus reset() override; + + private: + std::unique_ptr mEngine; + WorkerThread mWorker; + std::weak_ptr mSession; }; } // 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 99d806b5e5..adda8310f4 100644 --- a/biometrics/fingerprint/aidl/default/include/Session.h +++ b/biometrics/fingerprint/aidl/default/include/Session.h @@ -19,6 +19,9 @@ #include #include +#include "FakeFingerprintEngine.h" +#include "WorkerThread.h" + namespace aidl::android::hardware::biometrics::fingerprint { namespace common = aidl::android::hardware::biometrics::common; @@ -26,7 +29,8 @@ namespace keymaster = aidl::android::hardware::keymaster; class Session : public BnSession { public: - explicit Session(std::shared_ptr cb); + Session(int sensorId, int userId, std::shared_ptr cb, + FakeFingerprintEngine* engine, WorkerThread* worker); ndk::ScopedAStatus generateChallenge(int32_t cookie, int32_t timeoutSec) override; @@ -35,7 +39,7 @@ class Session : public BnSession { ndk::ScopedAStatus enroll(int32_t cookie, const keymaster::HardwareAuthToken& hat, std::shared_ptr* out) override; - ndk::ScopedAStatus authenticate(int32_t cookie, int64_t keystoreOperationId, + ndk::ScopedAStatus authenticate(int32_t cookie, int64_t operationId, std::shared_ptr* out) override; ndk::ScopedAStatus detectInteraction( @@ -62,8 +66,29 @@ class Session : public BnSession { ndk::ScopedAStatus onUiReady() override; + bool isClosed(); + private: + // Crashes the HAL if it's not currently idling because that would be an invalid state machine + // transition. Otherwise, sets the scheduled state to the given state. + void scheduleStateOrCrash(SessionState state); + + // Crashes the HAL if the provided state doesn't match the previously scheduled state. + // Otherwise, transitions into the provided state, clears the scheduled state, and notifies + // the client about the transition by calling ISessionCallback#onStateChanged. + void enterStateOrCrash(int cookie, SessionState state); + + // Sets the current state to SessionState::IDLING and notifies the client about the transition + // by calling ISessionCallback#onStateChanged. + void enterIdling(int cookie); + + int32_t mSensorId; + int32_t mUserId; std::shared_ptr mCb; + FakeFingerprintEngine* mEngine; + WorkerThread* mWorker; + SessionState mScheduledState; + SessionState mCurrentState; }; } // namespace aidl::android::hardware::biometrics::fingerprint -- GitLab From a6d0b847db60ffc855316c4b553751b595d12f2d Mon Sep 17 00:00:00 2001 From: Mingguang Xu Date: Fri, 12 Feb 2021 14:53:37 -0800 Subject: [PATCH 479/790] WiFi: Get contention time stats from wifi_wmm_ac_stat in link_layer_stats Bug: 172412545 Test: atest VtsHalWifiV1_5TargetTest Signed-off-by: Mingguang Xu Change-Id: Iab7ae64f55d2b3a2a654492f7566c8df2671c230 --- wifi/1.5/default/hidl_struct_util.cpp | 32 +++++++++++ .../tests/hidl_struct_util_unit_tests.cpp | 56 +++++++++++++++++++ wifi/1.5/types.hal | 47 ++++++++++++++++ 3 files changed, 135 insertions(+) diff --git a/wifi/1.5/default/hidl_struct_util.cpp b/wifi/1.5/default/hidl_struct_util.cpp index 7cee4cd868..5613357a71 100644 --- a/wifi/1.5/default/hidl_struct_util.cpp +++ b/wifi/1.5/default/hidl_struct_util.cpp @@ -1005,6 +1005,14 @@ bool convertLegacyLinkLayerStatsToHidl( 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; + hidl_stats->iface.wmeBeContentionTimeStats.contentionTimeMinInUsec = + 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; + hidl_stats->iface.wmeBeContentionTimeStats.contentionTimeAvgInUsec = + 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; hidl_stats->iface.V1_0.wmeBkPktStats.rxMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].rx_mpdu; hidl_stats->iface.V1_0.wmeBkPktStats.txMpdu = @@ -1013,6 +1021,14 @@ bool convertLegacyLinkLayerStatsToHidl( 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; + hidl_stats->iface.wmeBkContentionTimeStats.contentionTimeMinInUsec = + 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; + hidl_stats->iface.wmeBkContentionTimeStats.contentionTimeAvgInUsec = + 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; hidl_stats->iface.V1_0.wmeViPktStats.rxMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].rx_mpdu; hidl_stats->iface.V1_0.wmeViPktStats.txMpdu = @@ -1021,6 +1037,14 @@ bool convertLegacyLinkLayerStatsToHidl( 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; + hidl_stats->iface.wmeViContentionTimeStats.contentionTimeMinInUsec = + 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; + hidl_stats->iface.wmeViContentionTimeStats.contentionTimeAvgInUsec = + 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; hidl_stats->iface.V1_0.wmeVoPktStats.rxMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].rx_mpdu; hidl_stats->iface.V1_0.wmeVoPktStats.txMpdu = @@ -1029,6 +1053,14 @@ bool convertLegacyLinkLayerStatsToHidl( 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; + hidl_stats->iface.wmeVoContentionTimeStats.contentionTimeMinInUsec = + 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; + hidl_stats->iface.wmeVoContentionTimeStats.contentionTimeAvgInUsec = + 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; hidl_stats->iface.timeSliceDutyCycleInPercent = legacy_stats.iface.info.time_slicing_duty_cycle_percent; // radio legacy_stats conversion. diff --git a/wifi/1.5/default/tests/hidl_struct_util_unit_tests.cpp b/wifi/1.5/default/tests/hidl_struct_util_unit_tests.cpp index ea84c61f66..6391a6aec1 100644 --- a/wifi/1.5/default/tests/hidl_struct_util_unit_tests.cpp +++ b/wifi/1.5/default/tests/hidl_struct_util_unit_tests.cpp @@ -138,21 +138,41 @@ TEST_F(HidlStructUtilTest, canConvertLegacyLinkLayerStatsToHidl) { legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].tx_mpdu = rand(); legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].mpdu_lost = rand(); legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].retries = rand(); + 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_BK].rx_mpdu = rand(); legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].tx_mpdu = rand(); legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].mpdu_lost = rand(); legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].retries = rand(); + 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_VI].rx_mpdu = rand(); legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].tx_mpdu = rand(); legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].mpdu_lost = rand(); legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].retries = rand(); + 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_VO].rx_mpdu = rand(); legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].tx_mpdu = rand(); legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].mpdu_lost = rand(); legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].retries = rand(); + 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.info.time_slicing_duty_cycle_percent = rand(); @@ -197,6 +217,15 @@ TEST_F(HidlStructUtilTest, canConvertLegacyLinkLayerStatsToHidl) { converted.iface.V1_0.wmeBePktStats.lostMpdu); EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].retries, converted.iface.V1_0.wmeBePktStats.retries); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_min, + converted.iface.wmeBeContentionTimeStats.contentionTimeMinInUsec); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_max, + 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_BK].rx_mpdu, converted.iface.V1_0.wmeBkPktStats.rxMpdu); @@ -206,6 +235,15 @@ TEST_F(HidlStructUtilTest, canConvertLegacyLinkLayerStatsToHidl) { converted.iface.V1_0.wmeBkPktStats.lostMpdu); EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].retries, converted.iface.V1_0.wmeBkPktStats.retries); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_min, + converted.iface.wmeBkContentionTimeStats.contentionTimeMinInUsec); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_max, + 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_VI].rx_mpdu, converted.iface.V1_0.wmeViPktStats.rxMpdu); @@ -215,6 +253,15 @@ TEST_F(HidlStructUtilTest, canConvertLegacyLinkLayerStatsToHidl) { converted.iface.V1_0.wmeViPktStats.lostMpdu); EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].retries, converted.iface.V1_0.wmeViPktStats.retries); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_min, + converted.iface.wmeViContentionTimeStats.contentionTimeMinInUsec); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_max, + 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_VO].rx_mpdu, converted.iface.V1_0.wmeVoPktStats.rxMpdu); @@ -224,6 +271,15 @@ TEST_F(HidlStructUtilTest, canConvertLegacyLinkLayerStatsToHidl) { converted.iface.V1_0.wmeVoPktStats.lostMpdu); EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].retries, converted.iface.V1_0.wmeVoPktStats.retries); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_min, + converted.iface.wmeVoContentionTimeStats.contentionTimeMinInUsec); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_max, + 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.info.time_slicing_duty_cycle_percent, converted.iface.timeSliceDutyCycleInPercent); diff --git a/wifi/1.5/types.hal b/wifi/1.5/types.hal index 4dff77443e..3a5560b70b 100644 --- a/wifi/1.5/types.hal +++ b/wifi/1.5/types.hal @@ -134,6 +134,33 @@ struct NanCapabilities { bool instantCommunicationModeSupportFlag; }; +/** + * Contention time statistics for different traffic categories. + */ +struct StaLinkLayerIfaceContentionTimeStats { + /** + * Data packet min contention time (usec). It includes both the internal contention time + * among different access categories within the chipset and the contention time for the medium. + */ + uint64_t contentionTimeMinInUsec; + + /** + * Data packet max contention time (usec). It includes both the internal contention time + * among different access categories within the chipset and the contention time for the medium. + */ + uint64_t contentionTimeMaxInUsec; + /** + * Data packet average contention time (usec). It includes both the internal contention time + * among different access categories within the chipset and the contention time for the medium. + */ + uint64_t contentionTimeAvgInUsec; + + /** + * Number of data packets used for contention statistics. + */ + uint64_t contentionNumSamples; +}; + /** * Iface statistics for the current connection. */ @@ -150,6 +177,26 @@ struct StaLinkLayerIfaceStats { * If not using time slicing (i.e SCC or DBS), set to 100. */ uint8_t timeSliceDutyCycleInPercent; + + /** + * WME Best Effort (BE) Access Category (AC) contention time statistics. + */ + StaLinkLayerIfaceContentionTimeStats wmeBeContentionTimeStats; + + /** + * WME Background (BK) Access Category (AC) contention time statistics. + */ + StaLinkLayerIfaceContentionTimeStats wmeBkContentionTimeStats; + + /** + * WME Video (VI) Access Category (AC) contention time statistics. + */ + StaLinkLayerIfaceContentionTimeStats wmeViContentionTimeStats; + + /** + * WME Voice (VO) Access Category (AC) contention time statistics. + */ + StaLinkLayerIfaceContentionTimeStats wmeVoContentionTimeStats; }; /** -- GitLab From bf69b25911c6cf6b7e17b5c54668af92aba64391 Mon Sep 17 00:00:00 2001 From: Lais Andrade Date: Tue, 23 Feb 2021 10:34:13 +0000 Subject: [PATCH 480/790] Use current sdk in hardware.vibrator java backend This change a allows usaging this target in frameworks code without creating a cyclic dependency. Bug: 180924179 Test: manual Change-Id: I5f3c1598c548489dbf23edb7eb1becb985288768 --- vibrator/aidl/Android.bp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vibrator/aidl/Android.bp b/vibrator/aidl/Android.bp index 97663538fa..f6bd4cfd5b 100644 --- a/vibrator/aidl/Android.bp +++ b/vibrator/aidl/Android.bp @@ -7,7 +7,7 @@ aidl_interface { stability: "vintf", backend: { java: { - platform_apis: true, + sdk_version: "module_current", }, ndk: { vndk: { -- GitLab From 11f63389136da39c644a06d054dacaa26d9c13fb Mon Sep 17 00:00:00 2001 From: Vince Leung Date: Mon, 22 Feb 2021 22:00:43 +0000 Subject: [PATCH 481/790] vibrator: aidl: Add OWNERS Add owners for vibrator related files Bug: 177325091 Test: m Change-Id: I213f87b5a99ab0d529742ac01f230a932fc7f09b --- vibrator/aidl/OWNERS | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 vibrator/aidl/OWNERS diff --git a/vibrator/aidl/OWNERS b/vibrator/aidl/OWNERS new file mode 100644 index 0000000000..4bd56146ca --- /dev/null +++ b/vibrator/aidl/OWNERS @@ -0,0 +1,4 @@ +chasewu@google.com +leungv@google.com +lsandrade@google.com +michaelwr@google.com -- GitLab From bf5b361fa8356a244b4ed2900fdca1104ddaedc2 Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Fri, 19 Feb 2021 15:12:28 -0800 Subject: [PATCH 482/790] Add REENROLL_REQUIRED to IFace Bug: 180723766 Test: m android.hardware.biometrics.face-update-api Change-Id: I4687828a9e1bcd42633b28f16656d99632b63520 --- .../current/android/hardware/biometrics/face/Error.aidl | 1 + .../face/aidl/android/hardware/biometrics/face/Error.aidl | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Error.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Error.aidl index 6bbe7871ac..7992f9973a 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Error.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Error.aidl @@ -40,4 +40,5 @@ enum Error { CANCELED = 5, UNABLE_TO_REMOVE = 6, VENDOR = 8, + REENROLL_REQUIRED = 16, } diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/Error.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/Error.aidl index 7230128989..6f3264b4b6 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/Error.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/Error.aidl @@ -87,5 +87,9 @@ enum Error { * * LOCKOUT_PERMANENT = 9 */ -} + /** + * Authentication cannot be performed because re-enrollment is required. + */ + REENROLL_REQUIRED = 16, +} -- GitLab From c22b35bf04a3c852c60567eff90bd06fe1a40960 Mon Sep 17 00:00:00 2001 From: Bob Badour Date: Tue, 23 Feb 2021 14:26:20 -0800 Subject: [PATCH 483/790] [LSC] Add LOCAL_LICENSE_KINDS to hardware/interfaces Added SPDX-license-identifier-Apache-2.0 to: atrace/1.0/Android.bp atrace/1.0/default/Android.bp atrace/1.0/vts/functional/Android.bp audio/2.0/Android.bp audio/2.0/config/Android.bp audio/4.0/Android.bp audio/4.0/config/Android.bp audio/5.0/Android.bp audio/5.0/config/Android.bp audio/6.0/Android.bp audio/6.0/config/Android.bp audio/7.0/Android.bp audio/7.0/config/Android.bp audio/common/2.0/Android.bp audio/common/4.0/Android.bp audio/common/5.0/Android.bp audio/common/6.0/Android.bp audio/common/7.0/Android.bp audio/common/7.0/example/Android.bp audio/common/all-versions/default/Android.bp audio/common/all-versions/default/service/Android.bp audio/common/all-versions/test/utility/Android.bp audio/common/all-versions/util/Android.bp audio/core/all-versions/default/Android.bp audio/core/all-versions/default/util/Android.bp audio/core/all-versions/vts/functional/Android.bp audio/effect/2.0/Android.bp audio/effect/2.0/xml/Android.bp audio/effect/4.0/Android.bp audio/effect/4.0/xml/Android.bp audio/effect/5.0/Android.bp audio/effect/5.0/xml/Android.bp audio/effect/6.0/Android.bp audio/effect/6.0/xml/Android.bp audio/effect/7.0/Android.bp audio/effect/7.0/xml/Android.bp audio/effect/all-versions/default/Android.bp audio/effect/all-versions/default/util/Android.bp audio/effect/all-versions/vts/functional/Android.bp audio/policy/1.0/vts/functional/Android.bp audio/policy/1.0/xml/Android.bp audio/policy/1.0/xml/pfw_schemas/Android.bp authsecret/1.0/Android.bp authsecret/1.0/default/Android.bp authsecret/1.0/vts/functional/Android.bp authsecret/aidl/Android.bp authsecret/aidl/default/Android.bp authsecret/aidl/vts/Android.bp automotive/audiocontrol/1.0/Android.bp automotive/audiocontrol/1.0/default/Android.bp automotive/audiocontrol/1.0/vts/functional/Android.bp automotive/audiocontrol/2.0/Android.bp automotive/audiocontrol/2.0/default/Android.bp automotive/audiocontrol/2.0/vts/functional/Android.bp automotive/audiocontrol/aidl/Android.bp automotive/audiocontrol/aidl/default/Android.bp automotive/audiocontrol/aidl/vts/Android.bp automotive/can/1.0/default/libnetdevice/Android.bp automotive/can/1.0/default/libnl++/Android.bp automotive/can/1.0/hidl-utils/Android.bp automotive/can/1.0/tools/Android.bp automotive/can/1.0/tools/configurator/Android.bp automotive/can/1.0/tools/configurator/proto/Android.bp automotive/can/1.0/tools/libcanhaltools/Android.bp automotive/can/1.0/vts/functional/Android.bp automotive/can/1.0/vts/utils/Android.bp automotive/evs/1.0/Android.bp automotive/evs/1.0/default/Android.bp automotive/evs/1.0/vts/functional/Android.bp automotive/evs/1.1/Android.bp automotive/evs/1.1/default/Android.bp automotive/evs/1.1/vts/functional/Android.bp automotive/evs/1.1/vts/fuzzing/Android.bp automotive/evs/common/utils/default/Android.bp automotive/evs/common/utils/default/test/fuzz/Android.bp automotive/occupant_awareness/aidl/Android.bp automotive/occupant_awareness/aidl/default/Android.bp automotive/occupant_awareness/aidl/mock/Android.bp automotive/occupant_awareness/aidl/vts/functional/Android.bp automotive/sv/1.0/Android.bp automotive/sv/1.0/default/Android.bp automotive/sv/1.0/vts/functional/Android.bp automotive/vehicle/2.0/Android.bp automotive/vehicle/2.0/default/Android.bp automotive/vehicle/2.0/default/impl/vhal_v2_0/proto/Android.bp automotive/vehicle/2.0/utils/Android.bp biometrics/common/aidl/Android.bp biometrics/face/1.0/Android.bp biometrics/face/1.0/default/Android.bp biometrics/face/1.0/vts/functional/Android.bp biometrics/face/aidl/Android.bp biometrics/face/aidl/default/Android.bp biometrics/face/aidl/vts/Android.bp biometrics/fingerprint/2.1/Android.bp biometrics/fingerprint/2.1/default/Android.bp biometrics/fingerprint/2.1/vts/functional/Android.bp biometrics/fingerprint/2.2/Android.bp biometrics/fingerprint/2.2/default/Android.bp biometrics/fingerprint/2.2/vts/functional/Android.bp biometrics/fingerprint/2.3/Android.bp biometrics/fingerprint/2.3/vts/functional/Android.bp biometrics/fingerprint/aidl/Android.bp biometrics/fingerprint/aidl/default/Android.bp biometrics/fingerprint/aidl/vts/Android.bp bluetooth/1.0/Android.bp bluetooth/1.0/default/Android.bp bluetooth/1.0/vts/functional/Android.bp bluetooth/1.1/Android.bp bluetooth/1.1/default/Android.bp bluetooth/1.1/vts/functional/Android.bp bluetooth/a2dp/1.0/Android.bp bluetooth/a2dp/1.0/default/Android.bp bluetooth/a2dp/1.0/vts/functional/Android.bp bluetooth/audio/2.0/Android.bp bluetooth/audio/2.0/default/Android.bp bluetooth/audio/2.0/vts/functional/Android.bp bluetooth/audio/2.1/Android.bp bluetooth/audio/2.1/default/Android.bp bluetooth/audio/2.1/vts/functional/Android.bp bluetooth/audio/utils/Android.bp boot/1.0/Android.bp boot/1.0/default/Android.bp boot/1.0/vts/functional/Android.bp boot/1.1/Android.bp boot/1.1/default/Android.bp boot/1.1/default/boot_control/Android.bp boot/1.1/vts/functional/Android.bp boot/1.2/Android.bp boot/1.2/default/Android.bp boot/1.2/vts/functional/Android.bp broadcastradio/1.0/Android.bp broadcastradio/1.0/default/Android.bp broadcastradio/1.0/vts/functional/Android.bp broadcastradio/1.1/Android.bp broadcastradio/1.1/default/Android.bp broadcastradio/1.1/vts/functional/Android.bp broadcastradio/2.0/Android.bp broadcastradio/2.0/default/Android.bp broadcastradio/2.0/vts/functional/Android.bp broadcastradio/common/tests/Android.bp broadcastradio/common/utils/Android.bp broadcastradio/common/utils1x/Android.bp broadcastradio/common/utils2x/Android.bp broadcastradio/common/vts/utils/Android.bp camera/common/1.0/Android.bp camera/common/1.0/default/Android.bp camera/device/1.0/Android.bp camera/device/1.0/default/Android.bp camera/device/3.2/Android.bp camera/device/3.2/default/Android.bp camera/device/3.3/Android.bp camera/device/3.3/default/Android.bp camera/device/3.4/Android.bp camera/device/3.4/default/Android.bp camera/device/3.5/Android.bp camera/device/3.5/default/Android.bp camera/device/3.6/Android.bp camera/device/3.6/default/Android.bp camera/metadata/3.2/Android.bp camera/metadata/3.3/Android.bp camera/metadata/3.4/Android.bp camera/metadata/3.5/Android.bp camera/metadata/3.6/Android.bp camera/provider/2.4/Android.bp camera/provider/2.4/default/Android.bp camera/provider/2.4/vts/functional/Android.bp camera/provider/2.5/Android.bp camera/provider/2.5/default/Android.bp camera/provider/2.6/Android.bp cas/1.0/Android.bp cas/1.0/default/Android.bp cas/1.0/vts/functional/Android.bp cas/1.1/Android.bp cas/1.1/default/Android.bp cas/1.1/vts/functional/Android.bp cas/1.2/Android.bp cas/1.2/default/Android.bp cas/1.2/vts/functional/Android.bp cas/native/1.0/Android.bp common/aidl/Android.bp common/fmq/aidl/Android.bp common/support/Android.bp compatibility_matrices/Android.bp compatibility_matrices/Android.mk compatibility_matrices/build/Android.bp compatibility_matrices/exclude/Android.bp configstore/1.0/Android.bp configstore/1.0/vts/functional/Android.bp configstore/1.1/Android.bp configstore/1.1/default/Android.mk configstore/utils/Android.bp confirmationui/1.0/Android.bp confirmationui/1.0/default/Android.bp confirmationui/1.0/vts/functional/Android.bp confirmationui/support/Android.bp contexthub/1.0/Android.bp contexthub/1.0/default/Android.bp contexthub/1.0/vts/functional/Android.bp contexthub/1.1/Android.bp contexthub/1.1/default/Android.bp contexthub/1.1/vts/functional/Android.bp contexthub/1.2/Android.bp contexthub/1.2/default/Android.bp contexthub/1.2/vts/functional/Android.bp contexthub/common/default/1.X/Android.bp contexthub/common/default/1.X/utils/Android.bp contexthub/common/vts/Android.bp drm/1.0/Android.bp drm/1.0/default/Android.bp drm/1.0/vts/functional/Android.bp drm/1.1/Android.bp drm/1.1/vts/functional/Android.bp drm/1.2/Android.bp drm/1.2/vts/functional/Android.bp drm/1.3/Android.bp drm/1.3/vts/functional/Android.bp drm/1.4/Android.bp drm/1.4/vts/functional/Android.bp dumpstate/1.0/Android.bp dumpstate/1.0/default/Android.bp dumpstate/1.0/vts/functional/Android.bp dumpstate/1.1/Android.bp dumpstate/1.1/default/Android.bp dumpstate/1.1/vts/functional/Android.bp fastboot/1.0/Android.bp fastboot/1.0/default/Android.bp fastboot/1.1/Android.bp fastboot/1.1/default/Android.bp gatekeeper/1.0/Android.bp gatekeeper/1.0/default/Android.bp gatekeeper/1.0/software/Android.bp gatekeeper/1.0/software/tests/Android.bp gatekeeper/1.0/vts/functional/Android.bp gnss/1.0/Android.bp gnss/1.0/default/Android.bp gnss/1.0/vts/functional/Android.bp gnss/1.1/Android.bp gnss/1.1/default/Android.bp gnss/1.1/vts/functional/Android.bp gnss/2.0/Android.bp gnss/2.0/default/Android.bp gnss/2.0/vts/functional/Android.bp gnss/2.1/Android.bp gnss/2.1/default/Android.bp gnss/2.1/vts/functional/Android.bp gnss/aidl/Android.bp gnss/aidl/default/Android.bp gnss/aidl/vts/Android.bp gnss/common/utils/default/Android.bp gnss/common/utils/vts/Android.bp gnss/measurement_corrections/1.0/Android.bp gnss/measurement_corrections/1.1/Android.bp gnss/visibility_control/1.0/Android.bp graphics/allocator/2.0/Android.bp graphics/allocator/2.0/default/Android.bp graphics/allocator/2.0/utils/gralloc1-adapter/Android.bp graphics/allocator/2.0/utils/hal/Android.bp graphics/allocator/2.0/utils/passthrough/Android.bp graphics/allocator/3.0/Android.bp graphics/allocator/4.0/Android.bp graphics/bufferqueue/1.0/Android.bp graphics/bufferqueue/2.0/Android.bp graphics/common/1.0/Android.bp graphics/common/1.1/Android.bp graphics/common/1.2/Android.bp graphics/common/aidl/Android.bp graphics/composer/2.1/Android.bp graphics/composer/2.1/default/Android.bp graphics/composer/2.1/utils/command-buffer/Android.bp graphics/composer/2.1/utils/hal/Android.bp graphics/composer/2.1/utils/hwc2on1adapter/Android.bp graphics/composer/2.1/utils/hwc2onfbadapter/Android.bp graphics/composer/2.1/utils/passthrough/Android.bp graphics/composer/2.1/utils/resources/Android.bp graphics/composer/2.1/utils/vts/Android.bp graphics/composer/2.1/vts/functional/Android.bp graphics/composer/2.2/Android.bp graphics/composer/2.2/default/Android.mk graphics/composer/2.2/utils/command-buffer/Android.bp graphics/composer/2.2/utils/hal/Android.bp graphics/composer/2.2/utils/passthrough/Android.bp graphics/composer/2.2/utils/resources/Android.bp graphics/composer/2.2/utils/vts/Android.bp graphics/composer/2.2/vts/functional/Android.bp graphics/composer/2.3/Android.bp graphics/composer/2.3/default/Android.bp graphics/composer/2.3/utils/command-buffer/Android.bp graphics/composer/2.3/utils/hal/Android.bp graphics/composer/2.3/utils/passthrough/Android.bp graphics/composer/2.3/utils/vts/Android.bp graphics/composer/2.3/vts/functional/Android.bp graphics/composer/2.4/Android.bp graphics/composer/2.4/default/Android.bp graphics/composer/2.4/utils/command-buffer/Android.bp graphics/composer/2.4/utils/hal/Android.bp graphics/composer/2.4/utils/passthrough/Android.bp graphics/composer/2.4/utils/vts/Android.bp graphics/composer/2.4/vts/functional/Android.bp graphics/mapper/2.0/Android.bp graphics/mapper/2.0/default/Android.bp graphics/mapper/2.0/utils/hal/Android.bp graphics/mapper/2.0/utils/passthrough/Android.bp graphics/mapper/2.0/utils/vts/Android.bp graphics/mapper/2.0/vts/functional/Android.bp graphics/mapper/2.1/Android.bp graphics/mapper/2.1/default/Android.bp graphics/mapper/2.1/utils/hal/Android.bp graphics/mapper/2.1/utils/passthrough/Android.bp graphics/mapper/2.1/utils/vts/Android.bp graphics/mapper/2.1/vts/functional/Android.bp graphics/mapper/3.0/Android.bp graphics/mapper/3.0/utils/vts/Android.bp graphics/mapper/3.0/vts/functional/Android.bp graphics/mapper/4.0/Android.bp graphics/mapper/4.0/utils/vts/Android.bp graphics/mapper/4.0/vts/functional/Android.bp health/1.0/Android.bp health/1.0/default/Android.bp health/2.0/Android.bp health/2.0/default/Android.bp health/2.0/utils/libhealthhalutils/Android.bp health/2.0/utils/libhealthservice/Android.bp health/2.0/utils/libhealthstoragedefault/Android.bp health/2.0/vts/functional/Android.bp health/2.1/Android.bp health/2.1/default/Android.bp health/2.1/vts/functional/Android.bp health/storage/1.0/Android.bp health/storage/1.0/default/Android.bp health/storage/1.0/vts/functional/Android.bp health/storage/aidl/Android.bp health/storage/aidl/default/Android.bp health/storage/aidl/vts/functional/Android.bp health/storage/impl_common/Android.bp health/storage/test_common/Android.bp health/utils/libhealth2impl/Android.bp health/utils/libhealthloop/Android.bp identity/aidl/Android.bp identity/aidl/default/Android.bp identity/aidl/vts/Android.bp identity/support/Android.bp input/classifier/1.0/Android.bp input/classifier/1.0/default/Android.bp input/classifier/1.0/vts/functional/Android.bp input/common/1.0/Android.bp ir/1.0/Android.bp ir/1.0/default/Android.bp ir/1.0/vts/functional/Android.bp keymaster/3.0/Android.bp keymaster/3.0/default/Android.mk keymaster/3.0/vts/functional/Android.bp keymaster/4.0/Android.bp keymaster/4.0/default/Android.bp keymaster/4.0/support/Android.bp keymaster/4.0/vts/functional/Android.bp keymaster/4.0/vts/performance/Android.bp keymaster/4.1/Android.bp keymaster/4.1/default/Android.bp keymaster/4.1/support/Android.bp keymaster/4.1/vts/functional/Android.bp keymaster/aidl/Android.bp light/2.0/Android.bp light/2.0/default/Android.bp light/2.0/vts/functional/Android.bp light/aidl/Android.bp light/aidl/default/Android.bp light/aidl/vts/functional/Android.bp light/utils/Android.bp media/1.0/Android.bp media/1.0/xml/Android.mk media/Android.bp media/bufferpool/1.0/Android.bp media/bufferpool/2.0/Android.bp media/c2/1.0/Android.bp media/c2/1.1/Android.bp media/omx/1.0/Android.bp media/omx/1.0/vts/functional/audio/Android.bp media/omx/1.0/vts/functional/common/Android.bp media/omx/1.0/vts/functional/component/Android.bp media/omx/1.0/vts/functional/store/Android.bp media/omx/1.0/vts/functional/video/Android.bp memtrack/1.0/Android.bp memtrack/1.0/default/Android.bp memtrack/1.0/vts/functional/Android.bp memtrack/aidl/Android.bp memtrack/aidl/default/Android.bp memtrack/aidl/vts/Android.bp neuralnetworks/1.0/Android.bp neuralnetworks/1.0/utils/Android.bp neuralnetworks/1.0/vts/functional/Android.bp neuralnetworks/1.1/Android.bp neuralnetworks/1.1/utils/Android.bp neuralnetworks/1.1/vts/functional/Android.bp neuralnetworks/1.2/Android.bp neuralnetworks/1.2/utils/Android.bp neuralnetworks/1.2/vts/functional/Android.bp neuralnetworks/1.3/Android.bp neuralnetworks/1.3/utils/Android.bp neuralnetworks/1.3/vts/functional/Android.bp neuralnetworks/aidl/Android.bp neuralnetworks/aidl/utils/Android.bp neuralnetworks/aidl/vts/functional/Android.bp neuralnetworks/utils/common/Android.bp neuralnetworks/utils/service/Android.bp nfc/1.0/Android.bp nfc/1.0/default/Android.bp nfc/1.0/vts/functional/Android.bp nfc/1.1/Android.bp nfc/1.1/vts/functional/Android.bp nfc/1.2/Android.bp nfc/1.2/vts/functional/Android.bp oemlock/1.0/Android.bp oemlock/1.0/vts/functional/Android.bp oemlock/aidl/Android.bp oemlock/aidl/default/Android.bp oemlock/aidl/vts/Android.bp power/1.0/Android.bp power/1.0/default/Android.bp power/1.0/vts/functional/Android.bp power/1.1/Android.bp power/1.1/vts/functional/Android.bp power/1.2/Android.bp power/1.2/vts/functional/Android.bp power/1.3/Android.bp power/1.3/vts/functional/Android.bp power/aidl/Android.bp power/aidl/default/Android.bp power/aidl/vts/Android.bp power/stats/1.0/Android.bp power/stats/1.0/default/Android.bp power/stats/1.0/vts/functional/Android.bp power/stats/aidl/Android.bp power/stats/aidl/default/Android.bp power/stats/aidl/vts/Android.bp radio/1.0/Android.bp radio/1.0/vts/functional/Android.bp radio/1.1/Android.bp radio/1.1/vts/functional/Android.bp radio/1.2/Android.bp radio/1.2/default/Android.bp radio/1.2/vts/functional/Android.bp radio/1.3/Android.bp radio/1.3/vts/functional/Android.bp radio/1.4/Android.bp radio/1.4/vts/functional/Android.bp radio/1.5/Android.bp radio/1.5/vts/functional/Android.bp radio/1.6/Android.bp radio/1.6/vts/functional/Android.bp radio/config/1.0/Android.bp radio/config/1.0/default/Android.bp radio/config/1.0/vts/functional/Android.bp radio/config/1.1/Android.bp radio/config/1.1/vts/functional/Android.bp radio/config/1.2/Android.bp radio/config/1.2/vts/functional/Android.bp radio/config/1.3/Android.bp radio/config/1.3/vts/functional/Android.bp radio/deprecated/1.0/Android.bp rebootescrow/aidl/Android.bp rebootescrow/aidl/default/Android.bp rebootescrow/aidl/vts/functional/Android.bp renderscript/1.0/Android.bp renderscript/1.0/default/Android.bp renderscript/1.0/vts/functional/Android.bp secure_element/1.0/Android.bp secure_element/1.0/vts/functional/Android.bp secure_element/1.1/Android.bp secure_element/1.1/vts/functional/Android.bp secure_element/1.2/Android.bp secure_element/1.2/vts/functional/Android.bp security/keymint/aidl/Android.bp security/keymint/aidl/default/Android.bp security/keymint/aidl/vts/functional/Android.bp security/keymint/aidl/vts/performance/Android.bp security/keymint/support/Android.bp security/secureclock/aidl/Android.bp security/secureclock/aidl/vts/functional/Android.bp security/sharedsecret/aidl/Android.bp security/sharedsecret/aidl/vts/functional/Android.bp sensors/1.0/Android.bp sensors/1.0/default/Android.bp sensors/1.0/vts/functional/Android.bp sensors/2.0/Android.bp sensors/2.0/default/Android.bp sensors/2.0/multihal/Android.bp sensors/2.0/vts/functional/Android.bp sensors/2.1/Android.bp sensors/2.1/default/Android.bp sensors/2.1/multihal/Android.bp sensors/2.1/vts/functional/Android.bp sensors/common/default/2.X/Android.bp sensors/common/default/2.X/multihal/Android.bp sensors/common/default/2.X/multihal/tests/Android.bp sensors/common/utils/Android.bp sensors/common/vts/2_X/Android.bp sensors/common/vts/utils/Android.bp soundtrigger/2.0/Android.bp soundtrigger/2.0/default/Android.bp soundtrigger/2.0/default/Android.mk soundtrigger/2.0/vts/functional/Android.bp soundtrigger/2.1/Android.bp soundtrigger/2.1/default/Android.mk soundtrigger/2.1/vts/functional/Android.bp soundtrigger/2.2/Android.bp soundtrigger/2.2/default/Android.bp soundtrigger/2.2/vts/functional/Android.bp soundtrigger/2.3/Android.bp soundtrigger/2.3/default/Android.bp soundtrigger/2.3/vts/functional/Android.bp tests/bar/1.0/Android.bp tests/bar/1.0/default/Android.bp tests/baz/1.0/Android.bp tests/baz/1.0/default/Android.bp tests/expression/1.0/Android.bp tests/extension/light/2.0/Android.bp tests/extension/light/2.0/default/Android.bp tests/extension/vibrator/aidl/Android.bp tests/extension/vibrator/aidl/client/Android.bp tests/extension/vibrator/aidl/default/Android.bp tests/foo/1.0/Android.bp tests/foo/1.0/default/Android.bp tests/foo/1.0/default/lib/Android.bp tests/hash/1.0/Android.bp tests/hash/1.0/default/Android.bp tests/inheritance/1.0/Android.bp tests/inheritance/1.0/default/Android.bp tests/lazy/1.0/Android.bp tests/lazy/1.1/Android.bp tests/libhwbinder/1.0/Android.bp tests/libhwbinder/1.0/default/Android.bp tests/libhwbinder/aidl/Android.bp tests/memory/1.0/Android.bp tests/memory/1.0/default/Android.bp tests/memory/2.0/Android.bp tests/msgq/1.0/Android.bp tests/msgq/1.0/default/Android.bp tests/multithread/1.0/Android.bp tests/multithread/1.0/default/Android.bp tests/safeunion/1.0/Android.bp tests/safeunion/1.0/default/Android.bp tests/safeunion/cpp/1.0/Android.bp tests/safeunion/cpp/1.0/default/Android.bp tests/trie/1.0/Android.bp tests/trie/1.0/default/Android.bp tetheroffload/config/1.0/Android.bp tetheroffload/config/1.0/vts/functional/Android.bp tetheroffload/control/1.0/Android.bp tetheroffload/control/1.0/vts/functional/Android.bp tetheroffload/control/1.1/Android.bp tetheroffload/control/1.1/vts/functional/Android.bp thermal/1.0/Android.bp thermal/1.0/default/Android.bp thermal/1.0/vts/functional/Android.bp thermal/1.1/Android.bp thermal/1.1/vts/functional/Android.bp thermal/2.0/Android.bp thermal/2.0/default/Android.bp thermal/2.0/vts/functional/Android.bp tv/cec/1.0/Android.bp tv/cec/1.0/default/Android.bp tv/cec/1.1/Android.bp tv/cec/1.1/default/Android.bp tv/cec/1.1/vts/functional/Android.bp tv/input/1.0/Android.bp tv/input/1.0/default/Android.bp tv/input/1.0/vts/functional/Android.bp tv/tuner/1.0/Android.bp tv/tuner/1.0/default/Android.bp tv/tuner/1.0/vts/functional/Android.bp tv/tuner/1.1/Android.bp tv/tuner/1.1/default/Android.bp tv/tuner/1.1/vts/functional/Android.bp tv/tuner/assets/Android.bp usb/1.0/Android.bp usb/1.0/default/Android.bp usb/1.0/vts/functional/Android.bp usb/1.1/Android.bp usb/1.1/vts/functional/Android.bp usb/1.2/Android.bp usb/1.2/vts/functional/Android.bp usb/1.3/Android.bp usb/1.3/vts/functional/Android.bp usb/gadget/1.0/Android.bp usb/gadget/1.1/Android.bp usb/gadget/1.1/default/Android.bp usb/gadget/1.1/default/lib/Android.bp usb/gadget/1.2/Android.bp usb/gadget/1.2/default/Android.bp usb/gadget/1.2/default/lib/Android.bp vibrator/1.0/Android.bp vibrator/1.0/default/Android.bp vibrator/1.0/vts/functional/Android.bp vibrator/1.1/Android.bp vibrator/1.1/vts/functional/Android.bp vibrator/1.2/Android.bp vibrator/1.2/vts/functional/Android.bp vibrator/1.3/Android.bp vibrator/1.3/example/Android.bp vibrator/1.3/vts/functional/Android.bp vibrator/aidl/Android.bp vibrator/aidl/default/Android.bp vibrator/aidl/vts/Android.bp vibrator/bench/Android.bp vr/1.0/Android.bp vr/1.0/default/Android.bp vr/1.0/vts/functional/Android.bp weaver/1.0/Android.bp weaver/1.0/vts/functional/Android.bp weaver/aidl/Android.bp weaver/aidl/default/Android.bp weaver/aidl/vts/Android.bp wifi/1.0/Android.bp wifi/1.0/vts/functional/Android.bp wifi/1.1/Android.bp wifi/1.1/vts/functional/Android.bp wifi/1.2/Android.bp wifi/1.2/vts/functional/Android.bp wifi/1.3/Android.bp wifi/1.3/vts/functional/Android.bp wifi/1.4/Android.bp wifi/1.4/vts/functional/Android.bp wifi/1.5/Android.bp wifi/1.5/default/Android.mk wifi/1.5/vts/functional/Android.bp wifi/hostapd/1.0/Android.bp wifi/hostapd/1.0/vts/functional/Android.bp wifi/hostapd/1.1/Android.bp wifi/hostapd/1.1/vts/functional/Android.bp wifi/hostapd/1.2/Android.bp wifi/hostapd/1.2/vts/functional/Android.bp wifi/hostapd/1.3/Android.bp wifi/hostapd/1.3/vts/functional/Android.bp wifi/offload/1.0/Android.bp wifi/offload/1.0/vts/functional/Android.bp wifi/supplicant/1.0/Android.bp wifi/supplicant/1.0/vts/functional/Android.bp wifi/supplicant/1.1/Android.bp wifi/supplicant/1.1/vts/functional/Android.bp wifi/supplicant/1.2/Android.bp wifi/supplicant/1.2/vts/functional/Android.bp wifi/supplicant/1.3/Android.bp wifi/supplicant/1.3/vts/functional/Android.bp wifi/supplicant/1.4/Android.bp wifi/supplicant/1.4/vts/functional/Android.bp Added SPDX-license-identifier-Apache-2.0 SPDX-license-identifier-NCSA to: Android.bp automotive/can/1.0/Android.bp automotive/can/1.0/default/Android.bp Added SPDX-license-identifier-NCSA to: automotive/can/1.0/default/libc++fs/Android.bp Bug: 68860345 Bug: 151177513 Bug: 151953481 Test: m all Exempt-From-Owner-Approval: janitorial work Change-Id: If5e9ac8023cdc10d2370d16e7dd75a4bbb7085aa --- Android.bp | 30 +++++++++++++++++++ atrace/1.0/Android.bp | 9 ++++++ atrace/1.0/default/Android.bp | 9 ++++++ atrace/1.0/vts/functional/Android.bp | 9 ++++++ audio/2.0/Android.bp | 9 ++++++ audio/2.0/config/Android.bp | 9 ++++++ audio/4.0/Android.bp | 9 ++++++ audio/4.0/config/Android.bp | 10 ++++++- audio/5.0/Android.bp | 9 ++++++ audio/5.0/config/Android.bp | 10 ++++++- audio/6.0/Android.bp | 9 ++++++ audio/6.0/config/Android.bp | 10 ++++++- audio/7.0/Android.bp | 9 ++++++ audio/7.0/config/Android.bp | 9 ++++++ audio/common/2.0/Android.bp | 9 ++++++ audio/common/4.0/Android.bp | 9 ++++++ audio/common/5.0/Android.bp | 9 ++++++ audio/common/6.0/Android.bp | 9 ++++++ audio/common/7.0/Android.bp | 9 ++++++ audio/common/7.0/example/Android.bp | 9 ++++++ audio/common/all-versions/default/Android.bp | 9 ++++++ .../all-versions/default/service/Android.bp | 9 ++++++ .../all-versions/test/utility/Android.bp | 10 ++++++- audio/common/all-versions/util/Android.bp | 9 ++++++ audio/core/all-versions/default/Android.bp | 9 ++++++ .../core/all-versions/default/util/Android.bp | 9 ++++++ .../all-versions/vts/functional/Android.bp | 9 ++++++ audio/effect/2.0/Android.bp | 9 ++++++ audio/effect/2.0/xml/Android.bp | 9 ++++++ audio/effect/4.0/Android.bp | 9 ++++++ audio/effect/4.0/xml/Android.bp | 9 ++++++ audio/effect/5.0/Android.bp | 9 ++++++ audio/effect/5.0/xml/Android.bp | 9 ++++++ audio/effect/6.0/Android.bp | 9 ++++++ audio/effect/6.0/xml/Android.bp | 9 ++++++ audio/effect/7.0/Android.bp | 9 ++++++ audio/effect/7.0/xml/Android.bp | 9 ++++++ audio/effect/all-versions/default/Android.bp | 9 ++++++ .../all-versions/default/util/Android.bp | 9 ++++++ .../all-versions/vts/functional/Android.bp | 9 ++++++ audio/policy/1.0/vts/functional/Android.bp | 9 ++++++ audio/policy/1.0/xml/Android.bp | 9 ++++++ audio/policy/1.0/xml/pfw_schemas/Android.bp | 9 ++++++ authsecret/1.0/Android.bp | 9 ++++++ authsecret/1.0/default/Android.bp | 9 ++++++ authsecret/1.0/vts/functional/Android.bp | 9 ++++++ authsecret/aidl/Android.bp | 9 ++++++ authsecret/aidl/default/Android.bp | 9 ++++++ authsecret/aidl/vts/Android.bp | 9 ++++++ automotive/audiocontrol/1.0/Android.bp | 9 ++++++ .../audiocontrol/1.0/default/Android.bp | 9 ++++++ .../1.0/vts/functional/Android.bp | 9 ++++++ automotive/audiocontrol/2.0/Android.bp | 9 ++++++ .../audiocontrol/2.0/default/Android.bp | 9 ++++++ .../2.0/vts/functional/Android.bp | 9 ++++++ automotive/audiocontrol/aidl/Android.bp | 9 ++++++ .../audiocontrol/aidl/default/Android.bp | 9 ++++++ automotive/audiocontrol/aidl/vts/Android.bp | 9 ++++++ automotive/can/1.0/Android.bp | 10 +++++++ automotive/can/1.0/default/Android.bp | 10 +++++++ .../can/1.0/default/libc++fs/Android.bp | 9 ++++++ .../can/1.0/default/libnetdevice/Android.bp | 9 ++++++ automotive/can/1.0/default/libnl++/Android.bp | 9 ++++++ automotive/can/1.0/hidl-utils/Android.bp | 9 ++++++ automotive/can/1.0/tools/Android.bp | 9 ++++++ .../can/1.0/tools/configurator/Android.bp | 9 ++++++ .../1.0/tools/configurator/proto/Android.bp | 9 ++++++ .../can/1.0/tools/libcanhaltools/Android.bp | 9 ++++++ automotive/can/1.0/vts/functional/Android.bp | 9 ++++++ automotive/can/1.0/vts/utils/Android.bp | 9 ++++++ automotive/evs/1.0/Android.bp | 9 ++++++ automotive/evs/1.0/default/Android.bp | 9 ++++++ automotive/evs/1.0/vts/functional/Android.bp | 9 ++++++ automotive/evs/1.1/Android.bp | 9 ++++++ automotive/evs/1.1/default/Android.bp | 9 ++++++ automotive/evs/1.1/vts/functional/Android.bp | 9 ++++++ automotive/evs/1.1/vts/fuzzing/Android.bp | 9 ++++++ .../evs/common/utils/default/Android.bp | 9 ++++++ .../common/utils/default/test/fuzz/Android.bp | 9 ++++++ automotive/occupant_awareness/aidl/Android.bp | 9 ++++++ .../aidl/default/Android.bp | 9 ++++++ .../occupant_awareness/aidl/mock/Android.bp | 9 ++++++ .../aidl/vts/functional/Android.bp | 9 ++++++ automotive/sv/1.0/Android.bp | 9 ++++++ automotive/sv/1.0/default/Android.bp | 9 ++++++ automotive/sv/1.0/vts/functional/Android.bp | 9 ++++++ automotive/vehicle/2.0/Android.bp | 9 ++++++ automotive/vehicle/2.0/default/Android.bp | 9 ++++++ .../default/impl/vhal_v2_0/proto/Android.bp | 9 ++++++ automotive/vehicle/2.0/utils/Android.bp | 9 ++++++ biometrics/common/aidl/Android.bp | 11 ++++++- biometrics/face/1.0/Android.bp | 9 ++++++ biometrics/face/1.0/default/Android.bp | 9 ++++++ biometrics/face/1.0/vts/functional/Android.bp | 10 ++++++- biometrics/face/aidl/Android.bp | 9 ++++++ biometrics/face/aidl/default/Android.bp | 9 ++++++ biometrics/face/aidl/vts/Android.bp | 9 ++++++ biometrics/fingerprint/2.1/Android.bp | 9 ++++++ biometrics/fingerprint/2.1/default/Android.bp | 9 ++++++ .../fingerprint/2.1/vts/functional/Android.bp | 10 ++++++- biometrics/fingerprint/2.2/Android.bp | 9 ++++++ biometrics/fingerprint/2.2/default/Android.bp | 9 ++++++ .../fingerprint/2.2/vts/functional/Android.bp | 9 ++++++ biometrics/fingerprint/2.3/Android.bp | 9 ++++++ .../fingerprint/2.3/vts/functional/Android.bp | 9 ++++++ biometrics/fingerprint/aidl/Android.bp | 9 ++++++ .../fingerprint/aidl/default/Android.bp | 9 ++++++ biometrics/fingerprint/aidl/vts/Android.bp | 9 ++++++ bluetooth/1.0/Android.bp | 9 ++++++ bluetooth/1.0/default/Android.bp | 9 ++++++ bluetooth/1.0/vts/functional/Android.bp | 9 ++++++ bluetooth/1.1/Android.bp | 9 ++++++ bluetooth/1.1/default/Android.bp | 9 ++++++ bluetooth/1.1/vts/functional/Android.bp | 9 ++++++ bluetooth/a2dp/1.0/Android.bp | 9 ++++++ bluetooth/a2dp/1.0/default/Android.bp | 9 ++++++ bluetooth/a2dp/1.0/vts/functional/Android.bp | 9 ++++++ bluetooth/audio/2.0/Android.bp | 9 ++++++ bluetooth/audio/2.0/default/Android.bp | 9 ++++++ bluetooth/audio/2.0/vts/functional/Android.bp | 9 ++++++ bluetooth/audio/2.1/Android.bp | 9 ++++++ bluetooth/audio/2.1/default/Android.bp | 9 ++++++ bluetooth/audio/2.1/vts/functional/Android.bp | 9 ++++++ bluetooth/audio/utils/Android.bp | 9 ++++++ boot/1.0/Android.bp | 9 ++++++ boot/1.0/default/Android.bp | 9 ++++++ boot/1.0/vts/functional/Android.bp | 9 ++++++ boot/1.1/Android.bp | 9 ++++++ boot/1.1/default/Android.bp | 9 ++++++ boot/1.1/default/boot_control/Android.bp | 9 ++++++ boot/1.1/vts/functional/Android.bp | 9 ++++++ boot/1.2/Android.bp | 9 ++++++ boot/1.2/default/Android.bp | 9 ++++++ boot/1.2/vts/functional/Android.bp | 9 ++++++ broadcastradio/1.0/Android.bp | 9 ++++++ broadcastradio/1.0/default/Android.bp | 9 ++++++ broadcastradio/1.0/vts/functional/Android.bp | 9 ++++++ broadcastradio/1.1/Android.bp | 9 ++++++ broadcastradio/1.1/default/Android.bp | 9 ++++++ broadcastradio/1.1/vts/functional/Android.bp | 9 ++++++ broadcastradio/2.0/Android.bp | 9 ++++++ broadcastradio/2.0/default/Android.bp | 9 ++++++ broadcastradio/2.0/vts/functional/Android.bp | 9 ++++++ broadcastradio/common/tests/Android.bp | 9 ++++++ broadcastradio/common/utils/Android.bp | 9 ++++++ broadcastradio/common/utils1x/Android.bp | 9 ++++++ broadcastradio/common/utils2x/Android.bp | 9 ++++++ broadcastradio/common/vts/utils/Android.bp | 9 ++++++ camera/common/1.0/Android.bp | 9 ++++++ camera/common/1.0/default/Android.bp | 9 ++++++ camera/device/1.0/Android.bp | 9 ++++++ camera/device/1.0/default/Android.bp | 9 ++++++ camera/device/3.2/Android.bp | 9 ++++++ camera/device/3.2/default/Android.bp | 9 ++++++ camera/device/3.3/Android.bp | 9 ++++++ camera/device/3.3/default/Android.bp | 9 ++++++ camera/device/3.4/Android.bp | 9 ++++++ camera/device/3.4/default/Android.bp | 9 ++++++ camera/device/3.5/Android.bp | 9 ++++++ camera/device/3.5/default/Android.bp | 9 ++++++ camera/device/3.6/Android.bp | 9 ++++++ camera/device/3.6/default/Android.bp | 9 ++++++ camera/metadata/3.2/Android.bp | 9 ++++++ camera/metadata/3.3/Android.bp | 9 ++++++ camera/metadata/3.4/Android.bp | 9 ++++++ camera/metadata/3.5/Android.bp | 9 ++++++ camera/metadata/3.6/Android.bp | 9 ++++++ camera/provider/2.4/Android.bp | 9 ++++++ camera/provider/2.4/default/Android.bp | 9 ++++++ camera/provider/2.4/vts/functional/Android.bp | 9 ++++++ camera/provider/2.5/Android.bp | 9 ++++++ camera/provider/2.5/default/Android.bp | 9 ++++++ camera/provider/2.6/Android.bp | 9 ++++++ cas/1.0/Android.bp | 9 ++++++ cas/1.0/default/Android.bp | 9 ++++++ cas/1.0/vts/functional/Android.bp | 10 ++++++- cas/1.1/Android.bp | 9 ++++++ cas/1.1/default/Android.bp | 9 ++++++ cas/1.1/vts/functional/Android.bp | 10 ++++++- cas/1.2/Android.bp | 9 ++++++ cas/1.2/default/Android.bp | 9 ++++++ cas/1.2/vts/functional/Android.bp | 9 ++++++ cas/native/1.0/Android.bp | 9 ++++++ common/aidl/Android.bp | 9 ++++++ common/fmq/aidl/Android.bp | 9 ++++++ common/support/Android.bp | 9 ++++++ compatibility_matrices/Android.bp | 9 ++++++ compatibility_matrices/Android.mk | 12 ++++++++ compatibility_matrices/build/Android.bp | 9 ++++++ compatibility_matrices/exclude/Android.bp | 9 ++++++ configstore/1.0/Android.bp | 9 ++++++ configstore/1.0/vts/functional/Android.bp | 10 ++++++- configstore/1.1/Android.bp | 9 ++++++ configstore/1.1/default/Android.mk | 9 ++++++ configstore/utils/Android.bp | 9 ++++++ confirmationui/1.0/Android.bp | 9 ++++++ confirmationui/1.0/default/Android.bp | 9 ++++++ confirmationui/1.0/vts/functional/Android.bp | 9 ++++++ confirmationui/support/Android.bp | 9 ++++++ contexthub/1.0/Android.bp | 9 ++++++ contexthub/1.0/default/Android.bp | 9 ++++++ contexthub/1.0/vts/functional/Android.bp | 9 ++++++ contexthub/1.1/Android.bp | 9 ++++++ contexthub/1.1/default/Android.bp | 9 ++++++ contexthub/1.1/vts/functional/Android.bp | 9 ++++++ contexthub/1.2/Android.bp | 9 ++++++ contexthub/1.2/default/Android.bp | 9 ++++++ contexthub/1.2/vts/functional/Android.bp | 9 ++++++ contexthub/common/default/1.X/Android.bp | 9 ++++++ .../common/default/1.X/utils/Android.bp | 9 ++++++ contexthub/common/vts/Android.bp | 9 ++++++ drm/1.0/Android.bp | 9 ++++++ drm/1.0/default/Android.bp | 9 ++++++ drm/1.0/vts/functional/Android.bp | 9 ++++++ drm/1.1/Android.bp | 9 ++++++ drm/1.1/vts/functional/Android.bp | 9 ++++++ drm/1.2/Android.bp | 9 ++++++ drm/1.2/vts/functional/Android.bp | 9 ++++++ drm/1.3/Android.bp | 9 ++++++ drm/1.3/vts/functional/Android.bp | 9 ++++++ drm/1.4/Android.bp | 9 ++++++ drm/1.4/vts/functional/Android.bp | 9 ++++++ dumpstate/1.0/Android.bp | 9 ++++++ dumpstate/1.0/default/Android.bp | 9 ++++++ dumpstate/1.0/vts/functional/Android.bp | 9 ++++++ dumpstate/1.1/Android.bp | 9 ++++++ dumpstate/1.1/default/Android.bp | 9 ++++++ dumpstate/1.1/vts/functional/Android.bp | 9 ++++++ fastboot/1.0/Android.bp | 9 ++++++ fastboot/1.0/default/Android.bp | 9 ++++++ fastboot/1.1/Android.bp | 9 ++++++ fastboot/1.1/default/Android.bp | 9 ++++++ gatekeeper/1.0/Android.bp | 9 ++++++ gatekeeper/1.0/default/Android.bp | 9 ++++++ gatekeeper/1.0/software/Android.bp | 9 ++++++ gatekeeper/1.0/software/tests/Android.bp | 9 ++++++ gatekeeper/1.0/vts/functional/Android.bp | 9 ++++++ gnss/1.0/Android.bp | 9 ++++++ gnss/1.0/default/Android.bp | 9 ++++++ gnss/1.0/vts/functional/Android.bp | 9 ++++++ gnss/1.1/Android.bp | 9 ++++++ gnss/1.1/default/Android.bp | 9 ++++++ gnss/1.1/vts/functional/Android.bp | 9 ++++++ gnss/2.0/Android.bp | 9 ++++++ gnss/2.0/default/Android.bp | 9 ++++++ gnss/2.0/vts/functional/Android.bp | 9 ++++++ gnss/2.1/Android.bp | 9 ++++++ gnss/2.1/default/Android.bp | 9 ++++++ gnss/2.1/vts/functional/Android.bp | 9 ++++++ gnss/aidl/Android.bp | 9 ++++++ gnss/aidl/default/Android.bp | 9 ++++++ gnss/aidl/vts/Android.bp | 9 ++++++ gnss/common/utils/default/Android.bp | 9 ++++++ gnss/common/utils/vts/Android.bp | 9 ++++++ gnss/measurement_corrections/1.0/Android.bp | 9 ++++++ gnss/measurement_corrections/1.1/Android.bp | 9 ++++++ gnss/visibility_control/1.0/Android.bp | 9 ++++++ graphics/allocator/2.0/Android.bp | 9 ++++++ graphics/allocator/2.0/default/Android.bp | 9 ++++++ .../2.0/utils/gralloc1-adapter/Android.bp | 9 ++++++ graphics/allocator/2.0/utils/hal/Android.bp | 9 ++++++ .../2.0/utils/passthrough/Android.bp | 9 ++++++ graphics/allocator/3.0/Android.bp | 9 ++++++ graphics/allocator/4.0/Android.bp | 9 ++++++ graphics/bufferqueue/1.0/Android.bp | 9 ++++++ graphics/bufferqueue/2.0/Android.bp | 9 ++++++ graphics/common/1.0/Android.bp | 9 ++++++ graphics/common/1.1/Android.bp | 9 ++++++ graphics/common/1.2/Android.bp | 9 ++++++ graphics/common/aidl/Android.bp | 9 ++++++ graphics/composer/2.1/Android.bp | 9 ++++++ graphics/composer/2.1/default/Android.bp | 9 ++++++ .../2.1/utils/command-buffer/Android.bp | 9 ++++++ graphics/composer/2.1/utils/hal/Android.bp | 9 ++++++ .../2.1/utils/hwc2on1adapter/Android.bp | 9 ++++++ .../2.1/utils/hwc2onfbadapter/Android.bp | 9 ++++++ .../composer/2.1/utils/passthrough/Android.bp | 9 ++++++ .../composer/2.1/utils/resources/Android.bp | 9 ++++++ graphics/composer/2.1/utils/vts/Android.bp | 9 ++++++ .../composer/2.1/vts/functional/Android.bp | 9 ++++++ graphics/composer/2.2/Android.bp | 9 ++++++ graphics/composer/2.2/default/Android.mk | 3 ++ .../2.2/utils/command-buffer/Android.bp | 9 ++++++ graphics/composer/2.2/utils/hal/Android.bp | 9 ++++++ .../composer/2.2/utils/passthrough/Android.bp | 9 ++++++ .../composer/2.2/utils/resources/Android.bp | 9 ++++++ graphics/composer/2.2/utils/vts/Android.bp | 9 ++++++ .../composer/2.2/vts/functional/Android.bp | 9 ++++++ graphics/composer/2.3/Android.bp | 9 ++++++ graphics/composer/2.3/default/Android.bp | 9 ++++++ .../2.3/utils/command-buffer/Android.bp | 9 ++++++ graphics/composer/2.3/utils/hal/Android.bp | 9 ++++++ .../composer/2.3/utils/passthrough/Android.bp | 9 ++++++ graphics/composer/2.3/utils/vts/Android.bp | 9 ++++++ .../composer/2.3/vts/functional/Android.bp | 9 ++++++ graphics/composer/2.4/Android.bp | 9 ++++++ graphics/composer/2.4/default/Android.bp | 9 ++++++ .../2.4/utils/command-buffer/Android.bp | 9 ++++++ graphics/composer/2.4/utils/hal/Android.bp | 9 ++++++ .../composer/2.4/utils/passthrough/Android.bp | 9 ++++++ graphics/composer/2.4/utils/vts/Android.bp | 9 ++++++ .../composer/2.4/vts/functional/Android.bp | 9 ++++++ graphics/mapper/2.0/Android.bp | 9 ++++++ graphics/mapper/2.0/default/Android.bp | 9 ++++++ graphics/mapper/2.0/utils/hal/Android.bp | 9 ++++++ .../mapper/2.0/utils/passthrough/Android.bp | 9 ++++++ graphics/mapper/2.0/utils/vts/Android.bp | 9 ++++++ graphics/mapper/2.0/vts/functional/Android.bp | 9 ++++++ graphics/mapper/2.1/Android.bp | 9 ++++++ graphics/mapper/2.1/default/Android.bp | 9 ++++++ graphics/mapper/2.1/utils/hal/Android.bp | 9 ++++++ .../mapper/2.1/utils/passthrough/Android.bp | 9 ++++++ graphics/mapper/2.1/utils/vts/Android.bp | 9 ++++++ graphics/mapper/2.1/vts/functional/Android.bp | 9 ++++++ graphics/mapper/3.0/Android.bp | 9 ++++++ graphics/mapper/3.0/utils/vts/Android.bp | 9 ++++++ graphics/mapper/3.0/vts/functional/Android.bp | 9 ++++++ graphics/mapper/4.0/Android.bp | 9 ++++++ graphics/mapper/4.0/utils/vts/Android.bp | 9 ++++++ graphics/mapper/4.0/vts/functional/Android.bp | 9 ++++++ health/1.0/Android.bp | 9 ++++++ health/1.0/default/Android.bp | 9 ++++++ health/2.0/Android.bp | 9 ++++++ health/2.0/default/Android.bp | 9 ++++++ health/2.0/utils/libhealthhalutils/Android.bp | 9 ++++++ health/2.0/utils/libhealthservice/Android.bp | 9 ++++++ .../utils/libhealthstoragedefault/Android.bp | 9 ++++++ health/2.0/vts/functional/Android.bp | 9 ++++++ health/2.1/Android.bp | 9 ++++++ health/2.1/default/Android.bp | 9 ++++++ health/2.1/vts/functional/Android.bp | 9 ++++++ health/storage/1.0/Android.bp | 9 ++++++ health/storage/1.0/default/Android.bp | 9 ++++++ health/storage/1.0/vts/functional/Android.bp | 9 ++++++ health/storage/aidl/Android.bp | 9 ++++++ health/storage/aidl/default/Android.bp | 9 ++++++ health/storage/aidl/vts/functional/Android.bp | 9 ++++++ health/storage/impl_common/Android.bp | 9 ++++++ health/storage/test_common/Android.bp | 9 ++++++ health/utils/libhealth2impl/Android.bp | 9 ++++++ health/utils/libhealthloop/Android.bp | 9 ++++++ identity/aidl/Android.bp | 9 ++++++ identity/aidl/default/Android.bp | 9 ++++++ identity/aidl/vts/Android.bp | 9 ++++++ identity/support/Android.bp | 9 ++++++ input/classifier/1.0/Android.bp | 9 ++++++ input/classifier/1.0/default/Android.bp | 9 ++++++ .../classifier/1.0/vts/functional/Android.bp | 9 ++++++ input/common/1.0/Android.bp | 9 ++++++ ir/1.0/Android.bp | 9 ++++++ ir/1.0/default/Android.bp | 9 ++++++ ir/1.0/vts/functional/Android.bp | 9 ++++++ keymaster/3.0/Android.bp | 9 ++++++ keymaster/3.0/default/Android.mk | 6 ++++ keymaster/3.0/vts/functional/Android.bp | 9 ++++++ keymaster/4.0/Android.bp | 9 ++++++ keymaster/4.0/default/Android.bp | 9 ++++++ keymaster/4.0/support/Android.bp | 9 ++++++ keymaster/4.0/vts/functional/Android.bp | 9 ++++++ keymaster/4.0/vts/performance/Android.bp | 9 ++++++ keymaster/4.1/Android.bp | 9 ++++++ keymaster/4.1/default/Android.bp | 9 ++++++ keymaster/4.1/support/Android.bp | 9 ++++++ keymaster/4.1/vts/functional/Android.bp | 9 ++++++ keymaster/aidl/Android.bp | 9 ++++++ light/2.0/Android.bp | 9 ++++++ light/2.0/default/Android.bp | 9 ++++++ light/2.0/vts/functional/Android.bp | 10 ++++++- light/aidl/Android.bp | 9 ++++++ light/aidl/default/Android.bp | 9 ++++++ light/aidl/vts/functional/Android.bp | 9 ++++++ light/utils/Android.bp | 9 ++++++ media/1.0/Android.bp | 9 ++++++ media/1.0/xml/Android.mk | 4 ++- media/Android.bp | 9 ++++++ media/bufferpool/1.0/Android.bp | 9 ++++++ media/bufferpool/2.0/Android.bp | 9 ++++++ media/c2/1.0/Android.bp | 9 ++++++ media/c2/1.1/Android.bp | 9 ++++++ media/omx/1.0/Android.bp | 9 ++++++ media/omx/1.0/vts/functional/audio/Android.bp | 9 ++++++ .../omx/1.0/vts/functional/common/Android.bp | 9 ++++++ .../1.0/vts/functional/component/Android.bp | 9 ++++++ media/omx/1.0/vts/functional/store/Android.bp | 9 ++++++ media/omx/1.0/vts/functional/video/Android.bp | 9 ++++++ memtrack/1.0/Android.bp | 9 ++++++ memtrack/1.0/default/Android.bp | 9 ++++++ memtrack/1.0/vts/functional/Android.bp | 9 ++++++ memtrack/aidl/Android.bp | 9 ++++++ memtrack/aidl/default/Android.bp | 9 ++++++ memtrack/aidl/vts/Android.bp | 9 ++++++ neuralnetworks/1.0/Android.bp | 9 ++++++ neuralnetworks/1.0/utils/Android.bp | 9 ++++++ neuralnetworks/1.0/vts/functional/Android.bp | 9 ++++++ neuralnetworks/1.1/Android.bp | 9 ++++++ neuralnetworks/1.1/utils/Android.bp | 9 ++++++ neuralnetworks/1.1/vts/functional/Android.bp | 9 ++++++ neuralnetworks/1.2/Android.bp | 9 ++++++ neuralnetworks/1.2/utils/Android.bp | 9 ++++++ neuralnetworks/1.2/vts/functional/Android.bp | 9 ++++++ neuralnetworks/1.3/Android.bp | 9 ++++++ neuralnetworks/1.3/utils/Android.bp | 9 ++++++ neuralnetworks/1.3/vts/functional/Android.bp | 9 ++++++ neuralnetworks/aidl/Android.bp | 9 ++++++ neuralnetworks/aidl/utils/Android.bp | 9 ++++++ neuralnetworks/aidl/vts/functional/Android.bp | 9 ++++++ neuralnetworks/utils/common/Android.bp | 9 ++++++ neuralnetworks/utils/service/Android.bp | 9 ++++++ nfc/1.0/Android.bp | 9 ++++++ nfc/1.0/default/Android.bp | 9 ++++++ nfc/1.0/vts/functional/Android.bp | 9 ++++++ nfc/1.1/Android.bp | 9 ++++++ nfc/1.1/vts/functional/Android.bp | 9 ++++++ nfc/1.2/Android.bp | 9 ++++++ nfc/1.2/vts/functional/Android.bp | 9 ++++++ oemlock/1.0/Android.bp | 9 ++++++ oemlock/1.0/vts/functional/Android.bp | 9 ++++++ oemlock/aidl/Android.bp | 9 ++++++ oemlock/aidl/default/Android.bp | 9 ++++++ oemlock/aidl/vts/Android.bp | 9 ++++++ power/1.0/Android.bp | 9 ++++++ power/1.0/default/Android.bp | 9 ++++++ power/1.0/vts/functional/Android.bp | 9 ++++++ power/1.1/Android.bp | 9 ++++++ power/1.1/vts/functional/Android.bp | 9 ++++++ power/1.2/Android.bp | 9 ++++++ power/1.2/vts/functional/Android.bp | 9 ++++++ power/1.3/Android.bp | 9 ++++++ power/1.3/vts/functional/Android.bp | 9 ++++++ power/aidl/Android.bp | 9 ++++++ power/aidl/default/Android.bp | 9 ++++++ power/aidl/vts/Android.bp | 9 ++++++ power/stats/1.0/Android.bp | 9 ++++++ power/stats/1.0/default/Android.bp | 9 ++++++ power/stats/1.0/vts/functional/Android.bp | 9 ++++++ power/stats/aidl/Android.bp | 9 ++++++ power/stats/aidl/default/Android.bp | 9 ++++++ power/stats/aidl/vts/Android.bp | 9 ++++++ radio/1.0/Android.bp | 9 ++++++ radio/1.0/vts/functional/Android.bp | 9 ++++++ radio/1.1/Android.bp | 9 ++++++ radio/1.1/vts/functional/Android.bp | 9 ++++++ radio/1.2/Android.bp | 9 ++++++ radio/1.2/default/Android.bp | 9 ++++++ radio/1.2/vts/functional/Android.bp | 9 ++++++ radio/1.3/Android.bp | 9 ++++++ radio/1.3/vts/functional/Android.bp | 9 ++++++ radio/1.4/Android.bp | 9 ++++++ radio/1.4/vts/functional/Android.bp | 9 ++++++ radio/1.5/Android.bp | 9 ++++++ radio/1.5/vts/functional/Android.bp | 9 ++++++ radio/1.6/Android.bp | 9 ++++++ radio/1.6/vts/functional/Android.bp | 9 ++++++ radio/config/1.0/Android.bp | 9 ++++++ radio/config/1.0/default/Android.bp | 9 ++++++ radio/config/1.0/vts/functional/Android.bp | 9 ++++++ radio/config/1.1/Android.bp | 9 ++++++ radio/config/1.1/vts/functional/Android.bp | 9 ++++++ radio/config/1.2/Android.bp | 9 ++++++ radio/config/1.2/vts/functional/Android.bp | 9 ++++++ radio/config/1.3/Android.bp | 9 ++++++ radio/config/1.3/vts/functional/Android.bp | 9 ++++++ radio/deprecated/1.0/Android.bp | 9 ++++++ rebootescrow/aidl/Android.bp | 9 ++++++ rebootescrow/aidl/default/Android.bp | 9 ++++++ rebootescrow/aidl/vts/functional/Android.bp | 9 ++++++ renderscript/1.0/Android.bp | 9 ++++++ renderscript/1.0/default/Android.bp | 9 ++++++ renderscript/1.0/vts/functional/Android.bp | 9 ++++++ secure_element/1.0/Android.bp | 9 ++++++ secure_element/1.0/vts/functional/Android.bp | 9 ++++++ secure_element/1.1/Android.bp | 9 ++++++ secure_element/1.1/vts/functional/Android.bp | 9 ++++++ secure_element/1.2/Android.bp | 9 ++++++ secure_element/1.2/vts/functional/Android.bp | 9 ++++++ security/keymint/aidl/Android.bp | 9 ++++++ security/keymint/aidl/default/Android.bp | 9 ++++++ .../keymint/aidl/vts/functional/Android.bp | 9 ++++++ .../keymint/aidl/vts/performance/Android.bp | 9 ++++++ security/keymint/support/Android.bp | 9 ++++++ security/secureclock/aidl/Android.bp | 9 ++++++ .../aidl/vts/functional/Android.bp | 9 ++++++ security/sharedsecret/aidl/Android.bp | 9 ++++++ .../aidl/vts/functional/Android.bp | 9 ++++++ sensors/1.0/Android.bp | 9 ++++++ sensors/1.0/default/Android.bp | 9 ++++++ sensors/1.0/vts/functional/Android.bp | 9 ++++++ sensors/2.0/Android.bp | 9 ++++++ sensors/2.0/default/Android.bp | 9 ++++++ sensors/2.0/multihal/Android.bp | 9 ++++++ sensors/2.0/vts/functional/Android.bp | 9 ++++++ sensors/2.1/Android.bp | 9 ++++++ sensors/2.1/default/Android.bp | 9 ++++++ sensors/2.1/multihal/Android.bp | 9 ++++++ sensors/2.1/vts/functional/Android.bp | 9 ++++++ sensors/common/default/2.X/Android.bp | 9 ++++++ .../common/default/2.X/multihal/Android.bp | 9 ++++++ .../default/2.X/multihal/tests/Android.bp | 9 ++++++ sensors/common/utils/Android.bp | 9 ++++++ sensors/common/vts/2_X/Android.bp | 9 ++++++ sensors/common/vts/utils/Android.bp | 9 ++++++ soundtrigger/2.0/Android.bp | 9 ++++++ soundtrigger/2.0/default/Android.bp | 9 ++++++ soundtrigger/2.0/default/Android.mk | 3 ++ soundtrigger/2.0/vts/functional/Android.bp | 9 ++++++ soundtrigger/2.1/Android.bp | 9 ++++++ soundtrigger/2.1/default/Android.mk | 3 ++ soundtrigger/2.1/vts/functional/Android.bp | 9 ++++++ soundtrigger/2.2/Android.bp | 9 ++++++ soundtrigger/2.2/default/Android.bp | 9 ++++++ soundtrigger/2.2/vts/functional/Android.bp | 9 ++++++ soundtrigger/2.3/Android.bp | 9 ++++++ soundtrigger/2.3/default/Android.bp | 9 ++++++ soundtrigger/2.3/vts/functional/Android.bp | 9 ++++++ tests/bar/1.0/Android.bp | 9 ++++++ tests/bar/1.0/default/Android.bp | 9 ++++++ tests/baz/1.0/Android.bp | 9 ++++++ tests/baz/1.0/default/Android.bp | 9 ++++++ tests/expression/1.0/Android.bp | 9 ++++++ tests/extension/light/2.0/Android.bp | 9 ++++++ tests/extension/light/2.0/default/Android.bp | 9 ++++++ tests/extension/vibrator/aidl/Android.bp | 9 ++++++ .../extension/vibrator/aidl/client/Android.bp | 9 ++++++ .../vibrator/aidl/default/Android.bp | 9 ++++++ tests/foo/1.0/Android.bp | 9 ++++++ tests/foo/1.0/default/Android.bp | 9 ++++++ tests/foo/1.0/default/lib/Android.bp | 9 ++++++ tests/hash/1.0/Android.bp | 9 ++++++ tests/hash/1.0/default/Android.bp | 9 ++++++ tests/inheritance/1.0/Android.bp | 9 ++++++ tests/inheritance/1.0/default/Android.bp | 9 ++++++ tests/lazy/1.0/Android.bp | 9 ++++++ tests/lazy/1.1/Android.bp | 9 ++++++ tests/libhwbinder/1.0/Android.bp | 9 ++++++ tests/libhwbinder/1.0/default/Android.bp | 9 ++++++ tests/libhwbinder/aidl/Android.bp | 9 ++++++ tests/memory/1.0/Android.bp | 9 ++++++ tests/memory/1.0/default/Android.bp | 11 ++++++- tests/memory/2.0/Android.bp | 9 ++++++ tests/msgq/1.0/Android.bp | 9 ++++++ tests/msgq/1.0/default/Android.bp | 9 ++++++ tests/multithread/1.0/Android.bp | 9 ++++++ tests/multithread/1.0/default/Android.bp | 9 ++++++ tests/safeunion/1.0/Android.bp | 9 ++++++ tests/safeunion/1.0/default/Android.bp | 9 ++++++ tests/safeunion/cpp/1.0/Android.bp | 9 ++++++ tests/safeunion/cpp/1.0/default/Android.bp | 9 ++++++ tests/trie/1.0/Android.bp | 9 ++++++ tests/trie/1.0/default/Android.bp | 9 ++++++ tetheroffload/config/1.0/Android.bp | 9 ++++++ .../config/1.0/vts/functional/Android.bp | 9 ++++++ tetheroffload/control/1.0/Android.bp | 9 ++++++ .../control/1.0/vts/functional/Android.bp | 9 ++++++ tetheroffload/control/1.1/Android.bp | 9 ++++++ .../control/1.1/vts/functional/Android.bp | 9 ++++++ thermal/1.0/Android.bp | 9 ++++++ thermal/1.0/default/Android.bp | 9 ++++++ thermal/1.0/vts/functional/Android.bp | 10 ++++++- thermal/1.1/Android.bp | 9 ++++++ thermal/1.1/vts/functional/Android.bp | 9 ++++++ thermal/2.0/Android.bp | 9 ++++++ thermal/2.0/default/Android.bp | 9 ++++++ thermal/2.0/vts/functional/Android.bp | 10 ++++++- tv/cec/1.0/Android.bp | 9 ++++++ tv/cec/1.0/default/Android.bp | 9 ++++++ tv/cec/1.1/Android.bp | 9 ++++++ tv/cec/1.1/default/Android.bp | 9 ++++++ tv/cec/1.1/vts/functional/Android.bp | 9 ++++++ tv/input/1.0/Android.bp | 9 ++++++ tv/input/1.0/default/Android.bp | 9 ++++++ tv/input/1.0/vts/functional/Android.bp | 9 ++++++ tv/tuner/1.0/Android.bp | 9 ++++++ tv/tuner/1.0/default/Android.bp | 9 ++++++ tv/tuner/1.0/vts/functional/Android.bp | 9 ++++++ tv/tuner/1.1/Android.bp | 9 ++++++ tv/tuner/1.1/default/Android.bp | 9 ++++++ tv/tuner/1.1/vts/functional/Android.bp | 9 ++++++ tv/tuner/assets/Android.bp | 9 ++++++ usb/1.0/Android.bp | 9 ++++++ usb/1.0/default/Android.bp | 9 ++++++ usb/1.0/vts/functional/Android.bp | 9 ++++++ usb/1.1/Android.bp | 9 ++++++ usb/1.1/vts/functional/Android.bp | 10 ++++++- usb/1.2/Android.bp | 9 ++++++ usb/1.2/vts/functional/Android.bp | 9 ++++++ usb/1.3/Android.bp | 9 ++++++ usb/1.3/vts/functional/Android.bp | 9 ++++++ usb/gadget/1.0/Android.bp | 9 ++++++ usb/gadget/1.1/Android.bp | 9 ++++++ usb/gadget/1.1/default/Android.bp | 9 ++++++ usb/gadget/1.1/default/lib/Android.bp | 9 ++++++ usb/gadget/1.2/Android.bp | 9 ++++++ usb/gadget/1.2/default/Android.bp | 9 ++++++ usb/gadget/1.2/default/lib/Android.bp | 9 ++++++ vibrator/1.0/Android.bp | 9 ++++++ vibrator/1.0/default/Android.bp | 9 ++++++ vibrator/1.0/vts/functional/Android.bp | 10 ++++++- vibrator/1.1/Android.bp | 9 ++++++ vibrator/1.1/vts/functional/Android.bp | 10 ++++++- vibrator/1.2/Android.bp | 9 ++++++ vibrator/1.2/vts/functional/Android.bp | 10 ++++++- vibrator/1.3/Android.bp | 9 ++++++ vibrator/1.3/example/Android.bp | 9 ++++++ vibrator/1.3/vts/functional/Android.bp | 10 ++++++- vibrator/aidl/Android.bp | 9 ++++++ vibrator/aidl/default/Android.bp | 9 ++++++ vibrator/aidl/vts/Android.bp | 9 ++++++ vibrator/bench/Android.bp | 9 ++++++ vr/1.0/Android.bp | 9 ++++++ vr/1.0/default/Android.bp | 9 ++++++ vr/1.0/vts/functional/Android.bp | 9 ++++++ weaver/1.0/Android.bp | 9 ++++++ weaver/1.0/vts/functional/Android.bp | 9 ++++++ weaver/aidl/Android.bp | 9 ++++++ weaver/aidl/default/Android.bp | 9 ++++++ weaver/aidl/vts/Android.bp | 9 ++++++ wifi/1.0/Android.bp | 9 ++++++ wifi/1.0/vts/functional/Android.bp | 9 ++++++ wifi/1.1/Android.bp | 9 ++++++ wifi/1.1/vts/functional/Android.bp | 9 ++++++ wifi/1.2/Android.bp | 9 ++++++ wifi/1.2/vts/functional/Android.bp | 9 ++++++ wifi/1.3/Android.bp | 9 ++++++ wifi/1.3/vts/functional/Android.bp | 9 ++++++ wifi/1.4/Android.bp | 9 ++++++ wifi/1.4/vts/functional/Android.bp | 9 ++++++ wifi/1.5/Android.bp | 9 ++++++ wifi/1.5/default/Android.mk | 12 ++++++++ wifi/1.5/vts/functional/Android.bp | 9 ++++++ wifi/hostapd/1.0/Android.bp | 9 ++++++ wifi/hostapd/1.0/vts/functional/Android.bp | 9 ++++++ wifi/hostapd/1.1/Android.bp | 9 ++++++ wifi/hostapd/1.1/vts/functional/Android.bp | 9 ++++++ wifi/hostapd/1.2/Android.bp | 9 ++++++ wifi/hostapd/1.2/vts/functional/Android.bp | 9 ++++++ wifi/hostapd/1.3/Android.bp | 9 ++++++ wifi/hostapd/1.3/vts/functional/Android.bp | 9 ++++++ wifi/offload/1.0/Android.bp | 9 ++++++ wifi/offload/1.0/vts/functional/Android.bp | 9 ++++++ wifi/supplicant/1.0/Android.bp | 9 ++++++ wifi/supplicant/1.0/vts/functional/Android.bp | 9 ++++++ wifi/supplicant/1.1/Android.bp | 9 ++++++ wifi/supplicant/1.1/vts/functional/Android.bp | 9 ++++++ wifi/supplicant/1.2/Android.bp | 9 ++++++ wifi/supplicant/1.2/vts/functional/Android.bp | 9 ++++++ wifi/supplicant/1.3/Android.bp | 9 ++++++ wifi/supplicant/1.3/vts/functional/Android.bp | 9 ++++++ wifi/supplicant/1.4/Android.bp | 9 ++++++ wifi/supplicant/1.4/vts/functional/Android.bp | 9 ++++++ 649 files changed, 5845 insertions(+), 20 deletions(-) diff --git a/Android.bp b/Android.bp index 00ba1e24c5..815e7662e6 100644 --- a/Android.bp +++ b/Android.bp @@ -1,3 +1,33 @@ +package { + default_applicable_licenses: ["hardware_interfaces_license"], +} + +// Added automatically by a large-scale-change that took the approach of +// 'apply every license found to every target'. While this makes sure we respect +// every license restriction, it may not be entirely correct. +// +// e.g. GPL in an MIT project might only apply to the contrib/ directory. +// +// Please consider splitting the single license below into multiple licenses, +// taking care not to lose any license_kind information, and overriding the +// default license using the 'licenses: [...]' property on targets as needed. +// +// For unused files, consider creating a 'fileGroup' with "//visibility:private" +// to attach the license to, and including a comment whether the files may be +// used in the current project. +// See: http://go/android-license-faq +license { + name: "hardware_interfaces_license", + visibility: [":__subpackages__"], + license_kinds: [ + "SPDX-license-identifier-Apache-2.0", + "SPDX-license-identifier-NCSA", + ], + license_text: [ + "NOTICE", + ], +} + hidl_package_root { name: "android.hardware", use_current: true, diff --git a/atrace/1.0/Android.bp b/atrace/1.0/Android.bp index 5290a9a486..69d25f4e21 100644 --- a/atrace/1.0/Android.bp +++ b/atrace/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.atrace@1.0", root: "android.hardware", diff --git a/atrace/1.0/default/Android.bp b/atrace/1.0/default/Android.bp index 4bbbdb3471..766ef361b7 100644 --- a/atrace/1.0/default/Android.bp +++ b/atrace/1.0/default/Android.bp @@ -13,6 +13,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"], +} + cc_binary { name: "android.hardware.atrace@1.0-service", defaults: ["hidl_defaults"], diff --git a/atrace/1.0/vts/functional/Android.bp b/atrace/1.0/vts/functional/Android.bp index 07d3f7fedf..9681aa27ae 100644 --- a/atrace/1.0/vts/functional/Android.bp +++ b/atrace/1.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalAtraceV1_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/audio/2.0/Android.bp b/audio/2.0/Android.bp index 35f6803e30..268935516a 100644 --- a/audio/2.0/Android.bp +++ b/audio/2.0/Android.bp @@ -1,5 +1,14 @@ // 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.audio@2.0", root: "android.hardware", diff --git a/audio/2.0/config/Android.bp b/audio/2.0/config/Android.bp index 65a32eb11d..3844b2b046 100644 --- a/audio/2.0/config/Android.bp +++ b/audio/2.0/config/Android.bp @@ -14,6 +14,15 @@ // 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"], +} + filegroup { name: "audio_policy_configuration_V2_0", srcs: ["audio_policy_configuration.xsd"], diff --git a/audio/4.0/Android.bp b/audio/4.0/Android.bp index 4957a1470f..1a05d416b8 100644 --- a/audio/4.0/Android.bp +++ b/audio/4.0/Android.bp @@ -1,5 +1,14 @@ // 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.audio@4.0", root: "android.hardware", diff --git a/audio/4.0/config/Android.bp b/audio/4.0/config/Android.bp index 6aac8999f4..5b559b1605 100644 --- a/audio/4.0/config/Android.bp +++ b/audio/4.0/config/Android.bp @@ -1,7 +1,15 @@ +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"], +} + xsd_config { name: "audio_policy_configuration_V4_0", srcs: ["audio_policy_configuration.xsd"], package_name: "audio.policy.configuration.V4_0", } - diff --git a/audio/5.0/Android.bp b/audio/5.0/Android.bp index 365a654610..525b0b9544 100644 --- a/audio/5.0/Android.bp +++ b/audio/5.0/Android.bp @@ -1,5 +1,14 @@ // 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.audio@5.0", root: "android.hardware", diff --git a/audio/5.0/config/Android.bp b/audio/5.0/config/Android.bp index a3f1c33f4e..95354bd1b2 100644 --- a/audio/5.0/config/Android.bp +++ b/audio/5.0/config/Android.bp @@ -1,7 +1,15 @@ +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"], +} + xsd_config { name: "audio_policy_configuration_V5_0", srcs: ["audio_policy_configuration.xsd"], package_name: "audio.policy.configuration.V5_0", } - diff --git a/audio/6.0/Android.bp b/audio/6.0/Android.bp index d7880b631d..09705e69c6 100644 --- a/audio/6.0/Android.bp +++ b/audio/6.0/Android.bp @@ -1,5 +1,14 @@ // 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.audio@6.0", root: "android.hardware", diff --git a/audio/6.0/config/Android.bp b/audio/6.0/config/Android.bp index 182dfcc9b5..c8ca19e5dd 100644 --- a/audio/6.0/config/Android.bp +++ b/audio/6.0/config/Android.bp @@ -1,7 +1,15 @@ +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"], +} + xsd_config { name: "audio_policy_configuration_V6_0", srcs: ["audio_policy_configuration.xsd"], package_name: "audio.policy.configuration.V6_0", } - diff --git a/audio/7.0/Android.bp b/audio/7.0/Android.bp index d07ce1284a..5533df3d7b 100644 --- a/audio/7.0/Android.bp +++ b/audio/7.0/Android.bp @@ -1,5 +1,14 @@ // 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.audio@7.0", root: "android.hardware", diff --git a/audio/7.0/config/Android.bp b/audio/7.0/config/Android.bp index 4a46795228..096ab6aec7 100644 --- a/audio/7.0/config/Android.bp +++ b/audio/7.0/config/Android.bp @@ -1,3 +1,12 @@ +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"], +} + xsd_config { name: "audio_policy_configuration_V7_0", srcs: ["audio_policy_configuration.xsd"], diff --git a/audio/common/2.0/Android.bp b/audio/common/2.0/Android.bp index 56b43ffce0..f27eb9381d 100644 --- a/audio/common/2.0/Android.bp +++ b/audio/common/2.0/Android.bp @@ -1,5 +1,14 @@ // 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.audio.common@2.0", root: "android.hardware", diff --git a/audio/common/4.0/Android.bp b/audio/common/4.0/Android.bp index dc4bca4a92..ea88b06f3d 100644 --- a/audio/common/4.0/Android.bp +++ b/audio/common/4.0/Android.bp @@ -1,5 +1,14 @@ // 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.audio.common@4.0", root: "android.hardware", diff --git a/audio/common/5.0/Android.bp b/audio/common/5.0/Android.bp index bf265a5511..c4f3d4c8c6 100644 --- a/audio/common/5.0/Android.bp +++ b/audio/common/5.0/Android.bp @@ -1,5 +1,14 @@ // 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.audio.common@5.0", root: "android.hardware", diff --git a/audio/common/6.0/Android.bp b/audio/common/6.0/Android.bp index caeee6f75b..fc54caff83 100644 --- a/audio/common/6.0/Android.bp +++ b/audio/common/6.0/Android.bp @@ -1,5 +1,14 @@ // 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.audio.common@6.0", root: "android.hardware", diff --git a/audio/common/7.0/Android.bp b/audio/common/7.0/Android.bp index 47f031fd2e..2f7665e502 100644 --- a/audio/common/7.0/Android.bp +++ b/audio/common/7.0/Android.bp @@ -1,5 +1,14 @@ // 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.audio.common@7.0", root: "android.hardware", diff --git a/audio/common/7.0/example/Android.bp b/audio/common/7.0/example/Android.bp index a6ae560ec5..a85e4faae8 100644 --- a/audio/common/7.0/example/Android.bp +++ b/audio/common/7.0/example/Android.bp @@ -13,6 +13,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"], +} + cc_binary { name: "android.hardware.audio@7.0-service.example", vendor: true, diff --git a/audio/common/all-versions/default/Android.bp b/audio/common/all-versions/default/Android.bp index 9afc95a8c9..8f557449f1 100644 --- a/audio/common/all-versions/default/Android.bp +++ b/audio/common/all-versions/default/Android.bp @@ -13,6 +13,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"], +} + cc_library_shared { name: "android.hardware.audio.common-util", defaults: ["hidl_defaults"], diff --git a/audio/common/all-versions/default/service/Android.bp b/audio/common/all-versions/default/service/Android.bp index f163a2facc..0d4775c6a8 100644 --- a/audio/common/all-versions/default/service/Android.bp +++ b/audio/common/all-versions/default/service/Android.bp @@ -1,3 +1,12 @@ +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.audio.service", diff --git a/audio/common/all-versions/test/utility/Android.bp b/audio/common/all-versions/test/utility/Android.bp index b796acc73e..1602d25b2f 100644 --- a/audio/common/all-versions/test/utility/Android.bp +++ b/audio/common/all-versions/test/utility/Android.bp @@ -14,6 +14,15 @@ // 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.audio.common.test.utility", defaults : ["hidl_defaults"], @@ -29,4 +38,3 @@ cc_library_static { static_libs: ["libgtest"], export_static_lib_headers: ["libgtest"], } - diff --git a/audio/common/all-versions/util/Android.bp b/audio/common/all-versions/util/Android.bp index 3c7e62e4e4..91de6ecbff 100644 --- a/audio/common/all-versions/util/Android.bp +++ b/audio/common/all-versions/util/Android.bp @@ -1,3 +1,12 @@ +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_headers { name: "android.hardware.audio.common.util@all-versions", defaults: ["hidl_defaults"], diff --git a/audio/core/all-versions/default/Android.bp b/audio/core/all-versions/default/Android.bp index 0222bee0c0..27857396d2 100644 --- a/audio/core/all-versions/default/Android.bp +++ b/audio/core/all-versions/default/Android.bp @@ -1,3 +1,12 @@ +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"], +} + filegroup { name: "android.hardware.audio-impl_srcs", srcs: [ diff --git a/audio/core/all-versions/default/util/Android.bp b/audio/core/all-versions/default/util/Android.bp index ee80bbbd1a..7caf18ddfd 100644 --- a/audio/core/all-versions/default/util/Android.bp +++ b/audio/core/all-versions/default/util/Android.bp @@ -1,3 +1,12 @@ +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_defaults { name: "android.hardware.audio-util_default", defaults: ["hidl_defaults"], diff --git a/audio/core/all-versions/vts/functional/Android.bp b/audio/core/all-versions/vts/functional/Android.bp index 8cea3cbf71..af2ae9cc0c 100644 --- a/audio/core/all-versions/vts/functional/Android.bp +++ b/audio/core/all-versions/vts/functional/Android.bp @@ -14,6 +14,15 @@ // 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_defaults { name: "VtsHalAudioTargetTest_defaults", defaults: ["VtsHalTargetTestDefaults"], diff --git a/audio/effect/2.0/Android.bp b/audio/effect/2.0/Android.bp index a5a8b3405f..f2f512433b 100644 --- a/audio/effect/2.0/Android.bp +++ b/audio/effect/2.0/Android.bp @@ -1,5 +1,14 @@ // 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.audio.effect@2.0", root: "android.hardware", diff --git a/audio/effect/2.0/xml/Android.bp b/audio/effect/2.0/xml/Android.bp index 050425a1c4..d015639e5d 100644 --- a/audio/effect/2.0/xml/Android.bp +++ b/audio/effect/2.0/xml/Android.bp @@ -1,3 +1,12 @@ +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"], +} + genrule { name: "audio_effects_conf_V2_0", srcs: ["audio_effects_conf.xsd"], diff --git a/audio/effect/4.0/Android.bp b/audio/effect/4.0/Android.bp index 31f94ae8b8..1eb754a922 100644 --- a/audio/effect/4.0/Android.bp +++ b/audio/effect/4.0/Android.bp @@ -1,5 +1,14 @@ // 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.audio.effect@4.0", root: "android.hardware", diff --git a/audio/effect/4.0/xml/Android.bp b/audio/effect/4.0/xml/Android.bp index 27ffd0200c..8c03a35fbb 100644 --- a/audio/effect/4.0/xml/Android.bp +++ b/audio/effect/4.0/xml/Android.bp @@ -1,3 +1,12 @@ +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"], +} + genrule { name: "audio_effects_conf_V4_0", srcs: ["audio_effects_conf.xsd"], diff --git a/audio/effect/5.0/Android.bp b/audio/effect/5.0/Android.bp index a3081c688c..126964c9b5 100644 --- a/audio/effect/5.0/Android.bp +++ b/audio/effect/5.0/Android.bp @@ -1,5 +1,14 @@ // 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.audio.effect@5.0", root: "android.hardware", diff --git a/audio/effect/5.0/xml/Android.bp b/audio/effect/5.0/xml/Android.bp index 67b2f97947..7982e2a1a9 100644 --- a/audio/effect/5.0/xml/Android.bp +++ b/audio/effect/5.0/xml/Android.bp @@ -1,3 +1,12 @@ +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"], +} + xsd_config { name: "audio_effects_conf_V5_0", srcs: ["audio_effects_conf.xsd"], diff --git a/audio/effect/6.0/Android.bp b/audio/effect/6.0/Android.bp index de4bde74b1..8d15d0942f 100644 --- a/audio/effect/6.0/Android.bp +++ b/audio/effect/6.0/Android.bp @@ -1,5 +1,14 @@ // 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.audio.effect@6.0", root: "android.hardware", diff --git a/audio/effect/6.0/xml/Android.bp b/audio/effect/6.0/xml/Android.bp index 8d68672df1..f139341e94 100644 --- a/audio/effect/6.0/xml/Android.bp +++ b/audio/effect/6.0/xml/Android.bp @@ -1,3 +1,12 @@ +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"], +} + xsd_config { name: "audio_effects_conf_V6_0", srcs: ["audio_effects_conf.xsd"], diff --git a/audio/effect/7.0/Android.bp b/audio/effect/7.0/Android.bp index c1137827cf..7399cdbddd 100644 --- a/audio/effect/7.0/Android.bp +++ b/audio/effect/7.0/Android.bp @@ -1,5 +1,14 @@ // 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.audio.effect@7.0", root: "android.hardware", diff --git a/audio/effect/7.0/xml/Android.bp b/audio/effect/7.0/xml/Android.bp index dc12e6368d..978e4341e2 100644 --- a/audio/effect/7.0/xml/Android.bp +++ b/audio/effect/7.0/xml/Android.bp @@ -1,3 +1,12 @@ +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"], +} + xsd_config { name: "audio_effects_conf_V7_0", srcs: ["audio_effects_conf.xsd"], diff --git a/audio/effect/all-versions/default/Android.bp b/audio/effect/all-versions/default/Android.bp index 99b1120218..6df9dbf9c4 100644 --- a/audio/effect/all-versions/default/Android.bp +++ b/audio/effect/all-versions/default/Android.bp @@ -1,3 +1,12 @@ +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_defaults { name: "android.hardware.audio.effect-impl_default", defaults: ["hidl_defaults"], diff --git a/audio/effect/all-versions/default/util/Android.bp b/audio/effect/all-versions/default/util/Android.bp index 5ba19d3a2d..143094d604 100644 --- a/audio/effect/all-versions/default/util/Android.bp +++ b/audio/effect/all-versions/default/util/Android.bp @@ -1,3 +1,12 @@ +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_defaults { name: "android.hardware.audio.effect-util_default", defaults: ["hidl_defaults"], diff --git a/audio/effect/all-versions/vts/functional/Android.bp b/audio/effect/all-versions/vts/functional/Android.bp index f4a72834d5..48d6474b41 100644 --- a/audio/effect/all-versions/vts/functional/Android.bp +++ b/audio/effect/all-versions/vts/functional/Android.bp @@ -14,6 +14,15 @@ // 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_defaults { name: "VtsHalAudioEffectTargetTest_default", defaults: ["VtsHalTargetTestDefaults"], diff --git a/audio/policy/1.0/vts/functional/Android.bp b/audio/policy/1.0/vts/functional/Android.bp index 7b7cf0d44a..cccb2fc6f0 100644 --- a/audio/policy/1.0/vts/functional/Android.bp +++ b/audio/policy/1.0/vts/functional/Android.bp @@ -1,3 +1,12 @@ +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalAudioPolicyV1_0TargetTest", srcs: [ diff --git a/audio/policy/1.0/xml/Android.bp b/audio/policy/1.0/xml/Android.bp index 6da7b5a3e5..403278cbba 100644 --- a/audio/policy/1.0/xml/Android.bp +++ b/audio/policy/1.0/xml/Android.bp @@ -1,3 +1,12 @@ +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"], +} + xsd_config { name: "audio_policy_engine_conf_V1_0", srcs: ["audio_policy_engine_configuration.xsd"], diff --git a/audio/policy/1.0/xml/pfw_schemas/Android.bp b/audio/policy/1.0/xml/pfw_schemas/Android.bp index 8054dc57ef..5d669c2a83 100644 --- a/audio/policy/1.0/xml/pfw_schemas/Android.bp +++ b/audio/policy/1.0/xml/pfw_schemas/Android.bp @@ -1,3 +1,12 @@ +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"], +} + xsd_config { name: "audio_policy_engine_configurable_configuration_V1_0", srcs: ["AllSchemas.xsd"], diff --git a/authsecret/1.0/Android.bp b/authsecret/1.0/Android.bp index 5c556d2926..b14284b4d2 100644 --- a/authsecret/1.0/Android.bp +++ b/authsecret/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.authsecret@1.0", root: "android.hardware", diff --git a/authsecret/1.0/default/Android.bp b/authsecret/1.0/default/Android.bp index b6ea3c4ca7..5bf389b60b 100644 --- a/authsecret/1.0/default/Android.bp +++ b/authsecret/1.0/default/Android.bp @@ -1,3 +1,12 @@ +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.authsecret@1.0-service", init_rc: ["android.hardware.authsecret@1.0-service.rc"], diff --git a/authsecret/1.0/vts/functional/Android.bp b/authsecret/1.0/vts/functional/Android.bp index c49d37492d..853b4ddeb1 100644 --- a/authsecret/1.0/vts/functional/Android.bp +++ b/authsecret/1.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalAuthSecretV1_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/authsecret/aidl/Android.bp b/authsecret/aidl/Android.bp index 0a05034762..8fe9f27d7e 100644 --- a/authsecret/aidl/Android.bp +++ b/authsecret/aidl/Android.bp @@ -1,3 +1,12 @@ +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.authsecret", vendor_available: true, diff --git a/authsecret/aidl/default/Android.bp b/authsecret/aidl/default/Android.bp index 44e0711096..a6c0bc4001 100644 --- a/authsecret/aidl/default/Android.bp +++ b/authsecret/aidl/default/Android.bp @@ -14,6 +14,15 @@ // 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.authsecret-service.example", relative_install_path: "hw", diff --git a/authsecret/aidl/vts/Android.bp b/authsecret/aidl/vts/Android.bp index 29b3bcc21d..dca70465ab 100644 --- a/authsecret/aidl/vts/Android.bp +++ b/authsecret/aidl/vts/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalAuthSecretTargetTest", defaults: [ diff --git a/automotive/audiocontrol/1.0/Android.bp b/automotive/audiocontrol/1.0/Android.bp index 8835f51a29..628793bfbd 100644 --- a/automotive/audiocontrol/1.0/Android.bp +++ b/automotive/audiocontrol/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.automotive.audiocontrol@1.0", root: "android.hardware", diff --git a/automotive/audiocontrol/1.0/default/Android.bp b/automotive/audiocontrol/1.0/default/Android.bp index ae4b8057ae..3cae4f11a5 100644 --- a/automotive/audiocontrol/1.0/default/Android.bp +++ b/automotive/audiocontrol/1.0/default/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"], +} + cc_binary { name: "android.hardware.automotive.audiocontrol@1.0-service", defaults: ["hidl_defaults"], diff --git a/automotive/audiocontrol/1.0/vts/functional/Android.bp b/automotive/audiocontrol/1.0/vts/functional/Android.bp index 1bb8e88fbc..15c480aec5 100644 --- a/automotive/audiocontrol/1.0/vts/functional/Android.bp +++ b/automotive/audiocontrol/1.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalAudioControlV1_0TargetTest", srcs: [ diff --git a/automotive/audiocontrol/2.0/Android.bp b/automotive/audiocontrol/2.0/Android.bp index e9ce638bae..4d1fdbca26 100644 --- a/automotive/audiocontrol/2.0/Android.bp +++ b/automotive/audiocontrol/2.0/Android.bp @@ -1,5 +1,14 @@ // 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.automotive.audiocontrol@2.0", root: "android.hardware", diff --git a/automotive/audiocontrol/2.0/default/Android.bp b/automotive/audiocontrol/2.0/default/Android.bp index 44ad0281fe..1b8cef723d 100644 --- a/automotive/audiocontrol/2.0/default/Android.bp +++ b/automotive/audiocontrol/2.0/default/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"], +} + cc_binary { name: "android.hardware.automotive.audiocontrol@2.0-service", defaults: ["hidl_defaults"], diff --git a/automotive/audiocontrol/2.0/vts/functional/Android.bp b/automotive/audiocontrol/2.0/vts/functional/Android.bp index ac20509dd5..cb7a54d79b 100644 --- a/automotive/audiocontrol/2.0/vts/functional/Android.bp +++ b/automotive/audiocontrol/2.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalAudioControlV2_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/automotive/audiocontrol/aidl/Android.bp b/automotive/audiocontrol/aidl/Android.bp index f8240b1cc7..7a947d3ab5 100644 --- a/automotive/audiocontrol/aidl/Android.bp +++ b/automotive/audiocontrol/aidl/Android.bp @@ -1,5 +1,14 @@ // 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.automotive.audiocontrol", vendor_available: true, diff --git a/automotive/audiocontrol/aidl/default/Android.bp b/automotive/audiocontrol/aidl/default/Android.bp index 05fec79666..878bee19cb 100644 --- a/automotive/audiocontrol/aidl/default/Android.bp +++ b/automotive/audiocontrol/aidl/default/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"], +} + cc_binary { name: "android.hardware.automotive.audiocontrol-service.example", relative_install_path: "hw", diff --git a/automotive/audiocontrol/aidl/vts/Android.bp b/automotive/audiocontrol/aidl/vts/Android.bp index 89f5f9266c..6856b91d2b 100644 --- a/automotive/audiocontrol/aidl/vts/Android.bp +++ b/automotive/audiocontrol/aidl/vts/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"], +} + cc_test { name: "VtsAidlHalAudioControlTest", defaults: [ diff --git a/automotive/can/1.0/Android.bp b/automotive/can/1.0/Android.bp index 2ddfaf93b8..47db9f8d34 100644 --- a/automotive/can/1.0/Android.bp +++ b/automotive/can/1.0/Android.bp @@ -1,5 +1,15 @@ // 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 + // SPDX-license-identifier-NCSA + default_applicable_licenses: ["hardware_interfaces_license"], +} + hidl_interface { name: "android.hardware.automotive.can@1.0", root: "android.hardware", diff --git a/automotive/can/1.0/default/Android.bp b/automotive/can/1.0/default/Android.bp index 0ba066e35a..c0c17e27f5 100644 --- a/automotive/can/1.0/default/Android.bp +++ b/automotive/can/1.0/default/Android.bp @@ -14,6 +14,16 @@ // 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 + // SPDX-license-identifier-NCSA + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_defaults { name: "android.hardware.automotive.can@defaults", cpp_std: "experimental", diff --git a/automotive/can/1.0/default/libc++fs/Android.bp b/automotive/can/1.0/default/libc++fs/Android.bp index 7ab1c28b3b..06419919ac 100644 --- a/automotive/can/1.0/default/libc++fs/Android.bp +++ b/automotive/can/1.0/default/libc++fs/Android.bp @@ -17,6 +17,15 @@ // TODO(152067309): Stop building this yourself once it's ABI stable and has // been made vendor available. Just use libc++fs instead of this. +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-NCSA + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_defaults { name: "android.hardware.automotive@libc++fsdefaults", local_include_dirs: ["include"], diff --git a/automotive/can/1.0/default/libnetdevice/Android.bp b/automotive/can/1.0/default/libnetdevice/Android.bp index 2605f88104..653e773240 100644 --- a/automotive/can/1.0/default/libnetdevice/Android.bp +++ b/automotive/can/1.0/default/libnetdevice/Android.bp @@ -14,6 +14,15 @@ // 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.automotive.can@libnetdevice", defaults: ["android.hardware.automotive.can@defaults"], diff --git a/automotive/can/1.0/default/libnl++/Android.bp b/automotive/can/1.0/default/libnl++/Android.bp index a69e302658..790adcd073 100644 --- a/automotive/can/1.0/default/libnl++/Android.bp +++ b/automotive/can/1.0/default/libnl++/Android.bp @@ -14,6 +14,15 @@ // 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: "libnl++", defaults: ["android.hardware.automotive.can@defaults"], diff --git a/automotive/can/1.0/hidl-utils/Android.bp b/automotive/can/1.0/hidl-utils/Android.bp index 63b07c9391..7453e10308 100644 --- a/automotive/can/1.0/hidl-utils/Android.bp +++ b/automotive/can/1.0/hidl-utils/Android.bp @@ -14,6 +14,15 @@ // 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_headers { name: "android.hardware.automotive.can@hidl-utils-lib", export_include_dirs: ["include"], diff --git a/automotive/can/1.0/tools/Android.bp b/automotive/can/1.0/tools/Android.bp index a6c40d933a..a0807aa190 100644 --- a/automotive/can/1.0/tools/Android.bp +++ b/automotive/can/1.0/tools/Android.bp @@ -14,6 +14,15 @@ // 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: "canhalctrl", defaults: ["android.hardware.automotive.can@defaults"], diff --git a/automotive/can/1.0/tools/configurator/Android.bp b/automotive/can/1.0/tools/configurator/Android.bp index 2c4bc1d6fc..cc826bc85f 100644 --- a/automotive/can/1.0/tools/configurator/Android.bp +++ b/automotive/can/1.0/tools/configurator/Android.bp @@ -14,6 +14,15 @@ // 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: "canhalconfigurator", init_rc: ["canhalconfigurator.rc"], diff --git a/automotive/can/1.0/tools/configurator/proto/Android.bp b/automotive/can/1.0/tools/configurator/proto/Android.bp index 05e120524a..7b10791c83 100644 --- a/automotive/can/1.0/tools/configurator/proto/Android.bp +++ b/automotive/can/1.0/tools/configurator/proto/Android.bp @@ -14,6 +14,15 @@ // 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.automotive.can@1.x-config-format", defaults: ["android.hardware.automotive.can@defaults"], diff --git a/automotive/can/1.0/tools/libcanhaltools/Android.bp b/automotive/can/1.0/tools/libcanhaltools/Android.bp index cee9eef20d..a25748bea9 100644 --- a/automotive/can/1.0/tools/libcanhaltools/Android.bp +++ b/automotive/can/1.0/tools/libcanhaltools/Android.bp @@ -14,6 +14,15 @@ // 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.automotive.can@libcanhaltools", defaults: ["android.hardware.automotive.can@defaults"], diff --git a/automotive/can/1.0/vts/functional/Android.bp b/automotive/can/1.0/vts/functional/Android.bp index d020750f3a..1d51492fd8 100644 --- a/automotive/can/1.0/vts/functional/Android.bp +++ b/automotive/can/1.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // 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_defaults { name: "android.hardware.automotive.can@vts-defaults", defaults: [ diff --git a/automotive/can/1.0/vts/utils/Android.bp b/automotive/can/1.0/vts/utils/Android.bp index d03ead30eb..81d7ed180c 100644 --- a/automotive/can/1.0/vts/utils/Android.bp +++ b/automotive/can/1.0/vts/utils/Android.bp @@ -14,6 +14,15 @@ // 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.automotive.can@vts-utils-lib", defaults: ["android.hardware.automotive.can@defaults"], diff --git a/automotive/evs/1.0/Android.bp b/automotive/evs/1.0/Android.bp index 279c09aca0..04b9c7865d 100644 --- a/automotive/evs/1.0/Android.bp +++ b/automotive/evs/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.automotive.evs@1.0", root: "android.hardware", diff --git a/automotive/evs/1.0/default/Android.bp b/automotive/evs/1.0/default/Android.bp index 6e28ab1a54..c4c624f8aa 100644 --- a/automotive/evs/1.0/default/Android.bp +++ b/automotive/evs/1.0/default/Android.bp @@ -1,3 +1,12 @@ +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.automotive.evs@1.0-service", defaults: ["hidl_defaults"], diff --git a/automotive/evs/1.0/vts/functional/Android.bp b/automotive/evs/1.0/vts/functional/Android.bp index 74d512293b..f1b57d715d 100644 --- a/automotive/evs/1.0/vts/functional/Android.bp +++ b/automotive/evs/1.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalEvsV1_0TargetTest", srcs: [ diff --git a/automotive/evs/1.1/Android.bp b/automotive/evs/1.1/Android.bp index 443422e5aa..a72f971e04 100644 --- a/automotive/evs/1.1/Android.bp +++ b/automotive/evs/1.1/Android.bp @@ -1,5 +1,14 @@ // 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.automotive.evs@1.1", root: "android.hardware", diff --git a/automotive/evs/1.1/default/Android.bp b/automotive/evs/1.1/default/Android.bp index 6e5695d7c4..ea1851f607 100644 --- a/automotive/evs/1.1/default/Android.bp +++ b/automotive/evs/1.1/default/Android.bp @@ -1,3 +1,12 @@ +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.automotive.evs@1.1-service", defaults: ["hidl_defaults"], diff --git a/automotive/evs/1.1/vts/functional/Android.bp b/automotive/evs/1.1/vts/functional/Android.bp index d61f0a8f9c..cbc2150811 100644 --- a/automotive/evs/1.1/vts/functional/Android.bp +++ b/automotive/evs/1.1/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalEvsV1_1TargetTest", srcs: [ diff --git a/automotive/evs/1.1/vts/fuzzing/Android.bp b/automotive/evs/1.1/vts/fuzzing/Android.bp index 48427ee532..1764821ad6 100644 --- a/automotive/evs/1.1/vts/fuzzing/Android.bp +++ b/automotive/evs/1.1/vts/fuzzing/Android.bp @@ -14,6 +14,15 @@ // 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_defaults { name: "android.hardware.automotive.evs@fuzz-defaults", defaults: ["VtsHalTargetTestDefaults"], diff --git a/automotive/evs/common/utils/default/Android.bp b/automotive/evs/common/utils/default/Android.bp index 776ef81875..18b6ee68f6 100644 --- a/automotive/evs/common/utils/default/Android.bp +++ b/automotive/evs/common/utils/default/Android.bp @@ -14,6 +14,15 @@ // 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 { host_supported: true, name: "android.hardware.automotive.evs@common-default-lib", diff --git a/automotive/evs/common/utils/default/test/fuzz/Android.bp b/automotive/evs/common/utils/default/test/fuzz/Android.bp index 105ec68b04..a2cf27383f 100644 --- a/automotive/evs/common/utils/default/test/fuzz/Android.bp +++ b/automotive/evs/common/utils/default/test/fuzz/Android.bp @@ -14,6 +14,15 @@ // 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_fuzz { host_supported: true, name : "FormatConvertFuzzer_copyNV21toRGB32", diff --git a/automotive/occupant_awareness/aidl/Android.bp b/automotive/occupant_awareness/aidl/Android.bp index 4127f333b3..26c53fa4bb 100644 --- a/automotive/occupant_awareness/aidl/Android.bp +++ b/automotive/occupant_awareness/aidl/Android.bp @@ -1,3 +1,12 @@ +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.automotive.occupant_awareness", vendor_available: true, diff --git a/automotive/occupant_awareness/aidl/default/Android.bp b/automotive/occupant_awareness/aidl/default/Android.bp index 1e50930716..4db43bbd85 100644 --- a/automotive/occupant_awareness/aidl/default/Android.bp +++ b/automotive/occupant_awareness/aidl/default/Android.bp @@ -14,6 +14,15 @@ * 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.automotive.occupant_awareness@1.0-service", init_rc: ["android.hardware.automotive.occupant_awareness@1.0-service.rc"], diff --git a/automotive/occupant_awareness/aidl/mock/Android.bp b/automotive/occupant_awareness/aidl/mock/Android.bp index 64ca73377b..275eb22f31 100644 --- a/automotive/occupant_awareness/aidl/mock/Android.bp +++ b/automotive/occupant_awareness/aidl/mock/Android.bp @@ -14,6 +14,15 @@ * 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.automotive.occupant_awareness@1.0-service_mock", relative_install_path: "hw", diff --git a/automotive/occupant_awareness/aidl/vts/functional/Android.bp b/automotive/occupant_awareness/aidl/vts/functional/Android.bp index dbd0538de1..f248aa9f4e 100644 --- a/automotive/occupant_awareness/aidl/vts/functional/Android.bp +++ b/automotive/occupant_awareness/aidl/vts/functional/Android.bp @@ -1,3 +1,12 @@ +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalOccupantAwarenessV1_0TargetTest", defaults: [ diff --git a/automotive/sv/1.0/Android.bp b/automotive/sv/1.0/Android.bp index 3a39148aa0..a6b1ba77b3 100644 --- a/automotive/sv/1.0/Android.bp +++ b/automotive/sv/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.automotive.sv@1.0", root: "android.hardware", diff --git a/automotive/sv/1.0/default/Android.bp b/automotive/sv/1.0/default/Android.bp index 8417949eba..da974a0509 100644 --- a/automotive/sv/1.0/default/Android.bp +++ b/automotive/sv/1.0/default/Android.bp @@ -14,6 +14,15 @@ // 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.automotive.sv@1.0-service", vendor: true, diff --git a/automotive/sv/1.0/vts/functional/Android.bp b/automotive/sv/1.0/vts/functional/Android.bp index d5d72a6c5b..1ff34506ee 100644 --- a/automotive/sv/1.0/vts/functional/Android.bp +++ b/automotive/sv/1.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalSurroundViewV1_0TargetTest", srcs: [ diff --git a/automotive/vehicle/2.0/Android.bp b/automotive/vehicle/2.0/Android.bp index 4fa8773270..e2164b1d9d 100644 --- a/automotive/vehicle/2.0/Android.bp +++ b/automotive/vehicle/2.0/Android.bp @@ -1,5 +1,14 @@ // 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.automotive.vehicle@2.0", root: "android.hardware", diff --git a/automotive/vehicle/2.0/default/Android.bp b/automotive/vehicle/2.0/default/Android.bp index c66c9cca11..17b61e1d5e 100644 --- a/automotive/vehicle/2.0/default/Android.bp +++ b/automotive/vehicle/2.0/default/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"], +} + cc_defaults { name: "vhal_v2_0_defaults", shared_libs: [ diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/proto/Android.bp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/proto/Android.bp index c5b9ed6b0a..6e85ae96ee 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/proto/Android.bp +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/proto/Android.bp @@ -13,6 +13,15 @@ // limitations under the License. // Vehicle HAL Protobuf library +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.automotive.vehicle@2.0-libproto-native", vendor: true, diff --git a/automotive/vehicle/2.0/utils/Android.bp b/automotive/vehicle/2.0/utils/Android.bp index e354634165..a75ce49803 100644 --- a/automotive/vehicle/2.0/utils/Android.bp +++ b/automotive/vehicle/2.0/utils/Android.bp @@ -13,6 +13,15 @@ // limitations under the License. // User HAL helper library. +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.automotive.vehicle@2.0-user-hal-helper-lib", defaults: ["vhal_v2_0_defaults"], diff --git a/biometrics/common/aidl/Android.bp b/biometrics/common/aidl/Android.bp index f7462e6f51..829f8c2625 100644 --- a/biometrics/common/aidl/Android.bp +++ b/biometrics/common/aidl/Android.bp @@ -1,3 +1,12 @@ +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.biometrics.common", vendor_available: true, @@ -13,4 +22,4 @@ aidl_interface { enabled: false, }, } -} \ No newline at end of file +} diff --git a/biometrics/face/1.0/Android.bp b/biometrics/face/1.0/Android.bp index dd406f99c3..d3c262a0e7 100644 --- a/biometrics/face/1.0/Android.bp +++ b/biometrics/face/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.biometrics.face@1.0", root: "android.hardware", diff --git a/biometrics/face/1.0/default/Android.bp b/biometrics/face/1.0/default/Android.bp index d6ff087ee6..30cefed88c 100644 --- a/biometrics/face/1.0/default/Android.bp +++ b/biometrics/face/1.0/default/Android.bp @@ -14,6 +14,15 @@ * 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.biometrics.face@1.0-service.example", defaults: ["hidl_defaults"], diff --git a/biometrics/face/1.0/vts/functional/Android.bp b/biometrics/face/1.0/vts/functional/Android.bp index ff4a6de889..259c4eca49 100644 --- a/biometrics/face/1.0/vts/functional/Android.bp +++ b/biometrics/face/1.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalBiometricsFaceV1_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], @@ -21,4 +30,3 @@ cc_test { static_libs: ["android.hardware.biometrics.face@1.0"], test_suites: ["general-tests", "vts"], } - diff --git a/biometrics/face/aidl/Android.bp b/biometrics/face/aidl/Android.bp index a4fcbfe54b..63f5ae41af 100644 --- a/biometrics/face/aidl/Android.bp +++ b/biometrics/face/aidl/Android.bp @@ -1,3 +1,12 @@ +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.biometrics.face", vendor_available: true, diff --git a/biometrics/face/aidl/default/Android.bp b/biometrics/face/aidl/default/Android.bp index a13b8cb09d..d72411e6e2 100644 --- a/biometrics/face/aidl/default/Android.bp +++ b/biometrics/face/aidl/default/Android.bp @@ -1,3 +1,12 @@ +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.biometrics.face-service.example", relative_install_path: "hw", diff --git a/biometrics/face/aidl/vts/Android.bp b/biometrics/face/aidl/vts/Android.bp index a4c76f573a..c5660b1e01 100644 --- a/biometrics/face/aidl/vts/Android.bp +++ b/biometrics/face/aidl/vts/Android.bp @@ -1,3 +1,12 @@ +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalBiometricsFaceTargetTest", defaults: [ diff --git a/biometrics/fingerprint/2.1/Android.bp b/biometrics/fingerprint/2.1/Android.bp index 25bd48db70..3378930fe2 100644 --- a/biometrics/fingerprint/2.1/Android.bp +++ b/biometrics/fingerprint/2.1/Android.bp @@ -1,5 +1,14 @@ // 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.biometrics.fingerprint@2.1", root: "android.hardware", diff --git a/biometrics/fingerprint/2.1/default/Android.bp b/biometrics/fingerprint/2.1/default/Android.bp index ec4838bd9d..4d5cc8d3ee 100644 --- a/biometrics/fingerprint/2.1/default/Android.bp +++ b/biometrics/fingerprint/2.1/default/Android.bp @@ -1,3 +1,12 @@ +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.biometrics.fingerprint@2.1-service", defaults: ["hidl_defaults"], diff --git a/biometrics/fingerprint/2.1/vts/functional/Android.bp b/biometrics/fingerprint/2.1/vts/functional/Android.bp index 7e3f3406bb..0935bf61c2 100644 --- a/biometrics/fingerprint/2.1/vts/functional/Android.bp +++ b/biometrics/fingerprint/2.1/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalBiometricsFingerprintV2_1TargetTest", defaults: ["VtsHalTargetTestDefaults"], @@ -21,4 +30,3 @@ cc_test { static_libs: ["android.hardware.biometrics.fingerprint@2.1"], test_suites: ["general-tests", "vts"], } - diff --git a/biometrics/fingerprint/2.2/Android.bp b/biometrics/fingerprint/2.2/Android.bp index a8f202c2c0..bea8d44351 100644 --- a/biometrics/fingerprint/2.2/Android.bp +++ b/biometrics/fingerprint/2.2/Android.bp @@ -1,5 +1,14 @@ // 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.biometrics.fingerprint@2.2", root: "android.hardware", diff --git a/biometrics/fingerprint/2.2/default/Android.bp b/biometrics/fingerprint/2.2/default/Android.bp index 8931308936..f4fb57f20c 100644 --- a/biometrics/fingerprint/2.2/default/Android.bp +++ b/biometrics/fingerprint/2.2/default/Android.bp @@ -1,3 +1,12 @@ +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.biometrics.fingerprint@2.2-service.example", defaults: ["hidl_defaults"], diff --git a/biometrics/fingerprint/2.2/vts/functional/Android.bp b/biometrics/fingerprint/2.2/vts/functional/Android.bp index 5e8e7c80be..02f833ac0c 100644 --- a/biometrics/fingerprint/2.2/vts/functional/Android.bp +++ b/biometrics/fingerprint/2.2/vts/functional/Android.bp @@ -14,6 +14,15 @@ * limitations under the License. */ +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalBiometricsFingerprintV2_2TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/biometrics/fingerprint/2.3/Android.bp b/biometrics/fingerprint/2.3/Android.bp index cf635029f1..4608df7ebf 100644 --- a/biometrics/fingerprint/2.3/Android.bp +++ b/biometrics/fingerprint/2.3/Android.bp @@ -1,5 +1,14 @@ // 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.biometrics.fingerprint@2.3", root: "android.hardware", diff --git a/biometrics/fingerprint/2.3/vts/functional/Android.bp b/biometrics/fingerprint/2.3/vts/functional/Android.bp index 521c0f41fd..100aa29cd0 100644 --- a/biometrics/fingerprint/2.3/vts/functional/Android.bp +++ b/biometrics/fingerprint/2.3/vts/functional/Android.bp @@ -14,6 +14,15 @@ * limitations under the License. */ +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalBiometricsFingerprintV2_3TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/biometrics/fingerprint/aidl/Android.bp b/biometrics/fingerprint/aidl/Android.bp index 6bf20386e1..7ee957dd88 100644 --- a/biometrics/fingerprint/aidl/Android.bp +++ b/biometrics/fingerprint/aidl/Android.bp @@ -1,3 +1,12 @@ +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.biometrics.fingerprint", vendor_available: true, diff --git a/biometrics/fingerprint/aidl/default/Android.bp b/biometrics/fingerprint/aidl/default/Android.bp index 6b43bffbdd..80e6e02cf1 100644 --- a/biometrics/fingerprint/aidl/default/Android.bp +++ b/biometrics/fingerprint/aidl/default/Android.bp @@ -1,3 +1,12 @@ +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.biometrics.fingerprint-service.example", vendor: true, diff --git a/biometrics/fingerprint/aidl/vts/Android.bp b/biometrics/fingerprint/aidl/vts/Android.bp index 07bccb5965..0d83e744f2 100644 --- a/biometrics/fingerprint/aidl/vts/Android.bp +++ b/biometrics/fingerprint/aidl/vts/Android.bp @@ -1,3 +1,12 @@ +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalBiometricsFingerprintTargetTest", defaults: [ diff --git a/bluetooth/1.0/Android.bp b/bluetooth/1.0/Android.bp index 1cac820427..8d023c01d7 100644 --- a/bluetooth/1.0/Android.bp +++ b/bluetooth/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.bluetooth@1.0", root: "android.hardware", diff --git a/bluetooth/1.0/default/Android.bp b/bluetooth/1.0/default/Android.bp index 6e39d541fb..70a42b7f9b 100644 --- a/bluetooth/1.0/default/Android.bp +++ b/bluetooth/1.0/default/Android.bp @@ -13,6 +13,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"], +} + cc_library_shared { name: "android.hardware.bluetooth@1.0-impl", defaults: ["hidl_defaults"], diff --git a/bluetooth/1.0/vts/functional/Android.bp b/bluetooth/1.0/vts/functional/Android.bp index e9f867f5f0..4806fef5ee 100644 --- a/bluetooth/1.0/vts/functional/Android.bp +++ b/bluetooth/1.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalBluetoothV1_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/bluetooth/1.1/Android.bp b/bluetooth/1.1/Android.bp index c3967f028f..4feb28bd96 100644 --- a/bluetooth/1.1/Android.bp +++ b/bluetooth/1.1/Android.bp @@ -1,5 +1,14 @@ // 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.bluetooth@1.1", root: "android.hardware", diff --git a/bluetooth/1.1/default/Android.bp b/bluetooth/1.1/default/Android.bp index 4f7fecbeb6..ce85db0515 100644 --- a/bluetooth/1.1/default/Android.bp +++ b/bluetooth/1.1/default/Android.bp @@ -13,6 +13,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"], +} + cc_binary { name: "android.hardware.bluetooth@1.1-service", defaults: ["hidl_defaults"], diff --git a/bluetooth/1.1/vts/functional/Android.bp b/bluetooth/1.1/vts/functional/Android.bp index eb4a720f95..e64d5a9105 100644 --- a/bluetooth/1.1/vts/functional/Android.bp +++ b/bluetooth/1.1/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalBluetoothV1_1TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/bluetooth/a2dp/1.0/Android.bp b/bluetooth/a2dp/1.0/Android.bp index d9ec982da8..7f39d4f55c 100644 --- a/bluetooth/a2dp/1.0/Android.bp +++ b/bluetooth/a2dp/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.bluetooth.a2dp@1.0", root: "android.hardware", diff --git a/bluetooth/a2dp/1.0/default/Android.bp b/bluetooth/a2dp/1.0/default/Android.bp index 5264899bb9..f368dd4ab2 100644 --- a/bluetooth/a2dp/1.0/default/Android.bp +++ b/bluetooth/a2dp/1.0/default/Android.bp @@ -1,3 +1,12 @@ +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.a2dp@1.0-impl.mock", relative_install_path: "hw", diff --git a/bluetooth/a2dp/1.0/vts/functional/Android.bp b/bluetooth/a2dp/1.0/vts/functional/Android.bp index df18fcc7c5..0d393bc29c 100644 --- a/bluetooth/a2dp/1.0/vts/functional/Android.bp +++ b/bluetooth/a2dp/1.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalBluetoothA2dpV1_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/bluetooth/audio/2.0/Android.bp b/bluetooth/audio/2.0/Android.bp index 3fbd51f631..dd39f9f9d3 100644 --- a/bluetooth/audio/2.0/Android.bp +++ b/bluetooth/audio/2.0/Android.bp @@ -1,5 +1,14 @@ // 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.bluetooth.audio@2.0", root: "android.hardware", diff --git a/bluetooth/audio/2.0/default/Android.bp b/bluetooth/audio/2.0/default/Android.bp index 8ed631e08f..9bca0ca9f2 100644 --- a/bluetooth/audio/2.0/default/Android.bp +++ b/bluetooth/audio/2.0/default/Android.bp @@ -1,3 +1,12 @@ +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@2.0-impl", defaults: ["hidl_defaults"], diff --git a/bluetooth/audio/2.0/vts/functional/Android.bp b/bluetooth/audio/2.0/vts/functional/Android.bp index 0ed5da43f2..f5cb956e37 100644 --- a/bluetooth/audio/2.0/vts/functional/Android.bp +++ b/bluetooth/audio/2.0/vts/functional/Android.bp @@ -1,3 +1,12 @@ +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalBluetoothAudioV2_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/bluetooth/audio/2.1/Android.bp b/bluetooth/audio/2.1/Android.bp index 9af8add19b..822f5b3ebf 100644 --- a/bluetooth/audio/2.1/Android.bp +++ b/bluetooth/audio/2.1/Android.bp @@ -1,5 +1,14 @@ // 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.bluetooth.audio@2.1", root: "android.hardware", diff --git a/bluetooth/audio/2.1/default/Android.bp b/bluetooth/audio/2.1/default/Android.bp index c05aa3f04a..5c30f79001 100644 --- a/bluetooth/audio/2.1/default/Android.bp +++ b/bluetooth/audio/2.1/default/Android.bp @@ -1,3 +1,12 @@ +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@2.1-impl", defaults: ["hidl_defaults"], diff --git a/bluetooth/audio/2.1/vts/functional/Android.bp b/bluetooth/audio/2.1/vts/functional/Android.bp index 6ec5537775..3314a8ada8 100644 --- a/bluetooth/audio/2.1/vts/functional/Android.bp +++ b/bluetooth/audio/2.1/vts/functional/Android.bp @@ -1,3 +1,12 @@ +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalBluetoothAudioV2_1TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/bluetooth/audio/utils/Android.bp b/bluetooth/audio/utils/Android.bp index 35476d285f..551bc50618 100644 --- a/bluetooth/audio/utils/Android.bp +++ b/bluetooth/audio/utils/Android.bp @@ -1,3 +1,12 @@ +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: "libbluetooth_audio_session", defaults: ["hidl_defaults"], diff --git a/boot/1.0/Android.bp b/boot/1.0/Android.bp index 844cf9b26b..81170666c3 100644 --- a/boot/1.0/Android.bp +++ b/boot/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.boot@1.0", root: "android.hardware", diff --git a/boot/1.0/default/Android.bp b/boot/1.0/default/Android.bp index fdf7a1e40f..b7d2ec8971 100644 --- a/boot/1.0/default/Android.bp +++ b/boot/1.0/default/Android.bp @@ -1,3 +1,12 @@ +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.boot@1.0-impl", defaults: ["hidl_defaults"], diff --git a/boot/1.0/vts/functional/Android.bp b/boot/1.0/vts/functional/Android.bp index 92c818c56c..90ee9cb417 100644 --- a/boot/1.0/vts/functional/Android.bp +++ b/boot/1.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalBootV1_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/boot/1.1/Android.bp b/boot/1.1/Android.bp index 3f505e659e..a2a8447ec7 100644 --- a/boot/1.1/Android.bp +++ b/boot/1.1/Android.bp @@ -1,5 +1,14 @@ // 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.boot@1.1", root: "android.hardware", diff --git a/boot/1.1/default/Android.bp b/boot/1.1/default/Android.bp index abf1bf9530..0b0a5b711e 100644 --- a/boot/1.1/default/Android.bp +++ b/boot/1.1/default/Android.bp @@ -1,3 +1,12 @@ +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.boot@1.1-impl", stem: "android.hardware.boot@1.0-impl-1.1", diff --git a/boot/1.1/default/boot_control/Android.bp b/boot/1.1/default/boot_control/Android.bp index b2e68dfd41..ad71700fa1 100644 --- a/boot/1.1/default/boot_control/Android.bp +++ b/boot/1.1/default/boot_control/Android.bp @@ -14,6 +14,15 @@ // 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_defaults { name: "libboot_control_defaults", vendor: true, diff --git a/boot/1.1/vts/functional/Android.bp b/boot/1.1/vts/functional/Android.bp index 9f0c74a482..3a36046bdc 100644 --- a/boot/1.1/vts/functional/Android.bp +++ b/boot/1.1/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalBootV1_1TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/boot/1.2/Android.bp b/boot/1.2/Android.bp index e51c5cdc4d..17ba3e9ee2 100644 --- a/boot/1.2/Android.bp +++ b/boot/1.2/Android.bp @@ -1,5 +1,14 @@ // 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.boot@1.2", root: "android.hardware", diff --git a/boot/1.2/default/Android.bp b/boot/1.2/default/Android.bp index c097667d1d..4e1c35e599 100644 --- a/boot/1.2/default/Android.bp +++ b/boot/1.2/default/Android.bp @@ -1,3 +1,12 @@ +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.boot@1.2-impl", stem: "android.hardware.boot@1.0-impl-1.2", diff --git a/boot/1.2/vts/functional/Android.bp b/boot/1.2/vts/functional/Android.bp index a7f5ccb440..7d546ed48f 100644 --- a/boot/1.2/vts/functional/Android.bp +++ b/boot/1.2/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalBootV1_2TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/broadcastradio/1.0/Android.bp b/broadcastradio/1.0/Android.bp index 5fc120d3b9..fca4ac8e91 100644 --- a/broadcastradio/1.0/Android.bp +++ b/broadcastradio/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.broadcastradio@1.0", root: "android.hardware", diff --git a/broadcastradio/1.0/default/Android.bp b/broadcastradio/1.0/default/Android.bp index 2c96e2a45a..efb7f6c123 100644 --- a/broadcastradio/1.0/default/Android.bp +++ b/broadcastradio/1.0/default/Android.bp @@ -14,6 +14,15 @@ // 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_shared { name: "android.hardware.broadcastradio@1.0-impl", vendor: true, diff --git a/broadcastradio/1.0/vts/functional/Android.bp b/broadcastradio/1.0/vts/functional/Android.bp index 2a4f9420ec..623ff78f5d 100644 --- a/broadcastradio/1.0/vts/functional/Android.bp +++ b/broadcastradio/1.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalBroadcastradioV1_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/broadcastradio/1.1/Android.bp b/broadcastradio/1.1/Android.bp index 5efa3d4599..2874a7d0f0 100644 --- a/broadcastradio/1.1/Android.bp +++ b/broadcastradio/1.1/Android.bp @@ -1,5 +1,14 @@ // 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.broadcastradio@1.1", root: "android.hardware", diff --git a/broadcastradio/1.1/default/Android.bp b/broadcastradio/1.1/default/Android.bp index 3659cb9fe1..5a17f5aace 100644 --- a/broadcastradio/1.1/default/Android.bp +++ b/broadcastradio/1.1/default/Android.bp @@ -14,6 +14,15 @@ // 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.broadcastradio@1.1-service", init_rc: ["android.hardware.broadcastradio@1.1-service.rc"], diff --git a/broadcastradio/1.1/vts/functional/Android.bp b/broadcastradio/1.1/vts/functional/Android.bp index 661439aa67..f0dfe961b9 100644 --- a/broadcastradio/1.1/vts/functional/Android.bp +++ b/broadcastradio/1.1/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalBroadcastradioV1_1TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/broadcastradio/2.0/Android.bp b/broadcastradio/2.0/Android.bp index 0ef635eb5e..447b2c7976 100644 --- a/broadcastradio/2.0/Android.bp +++ b/broadcastradio/2.0/Android.bp @@ -1,5 +1,14 @@ // 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.broadcastradio@2.0", root: "android.hardware", diff --git a/broadcastradio/2.0/default/Android.bp b/broadcastradio/2.0/default/Android.bp index 83eedb189a..870c944d75 100644 --- a/broadcastradio/2.0/default/Android.bp +++ b/broadcastradio/2.0/default/Android.bp @@ -14,6 +14,15 @@ // 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.broadcastradio@2.0-service", init_rc: ["android.hardware.broadcastradio@2.0-service.rc"], diff --git a/broadcastradio/2.0/vts/functional/Android.bp b/broadcastradio/2.0/vts/functional/Android.bp index be17da32df..e26486dcc7 100644 --- a/broadcastradio/2.0/vts/functional/Android.bp +++ b/broadcastradio/2.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalBroadcastradioV2_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/broadcastradio/common/tests/Android.bp b/broadcastradio/common/tests/Android.bp index 0ace941ac1..0a6a3a27d0 100644 --- a/broadcastradio/common/tests/Android.bp +++ b/broadcastradio/common/tests/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "android.hardware.broadcastradio@common-utils-xx-tests", vendor: true, diff --git a/broadcastradio/common/utils/Android.bp b/broadcastradio/common/utils/Android.bp index 32e06d7bdf..3131ab3ac6 100644 --- a/broadcastradio/common/utils/Android.bp +++ b/broadcastradio/common/utils/Android.bp @@ -14,6 +14,15 @@ // 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.broadcastradio@common-utils-lib", vendor_available: true, diff --git a/broadcastradio/common/utils1x/Android.bp b/broadcastradio/common/utils1x/Android.bp index 443dca158d..681f7de8a6 100644 --- a/broadcastradio/common/utils1x/Android.bp +++ b/broadcastradio/common/utils1x/Android.bp @@ -14,6 +14,15 @@ // 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.broadcastradio@common-utils-1x-lib", vendor_available: true, diff --git a/broadcastradio/common/utils2x/Android.bp b/broadcastradio/common/utils2x/Android.bp index df2cefe36c..124a7e517f 100644 --- a/broadcastradio/common/utils2x/Android.bp +++ b/broadcastradio/common/utils2x/Android.bp @@ -14,6 +14,15 @@ // 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.broadcastradio@common-utils-2x-lib", vendor_available: true, diff --git a/broadcastradio/common/vts/utils/Android.bp b/broadcastradio/common/vts/utils/Android.bp index 24fea0bb2d..e08813ba9d 100644 --- a/broadcastradio/common/vts/utils/Android.bp +++ b/broadcastradio/common/vts/utils/Android.bp @@ -14,6 +14,15 @@ // 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.broadcastradio@vts-utils-lib", srcs: [ diff --git a/camera/common/1.0/Android.bp b/camera/common/1.0/Android.bp index bd00dbbd37..3eb12b92ff 100644 --- a/camera/common/1.0/Android.bp +++ b/camera/common/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.camera.common@1.0", root: "android.hardware", diff --git a/camera/common/1.0/default/Android.bp b/camera/common/1.0/default/Android.bp index 3b8b23946e..4a5ca83803 100644 --- a/camera/common/1.0/default/Android.bp +++ b/camera/common/1.0/default/Android.bp @@ -1,3 +1,12 @@ +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.camera.common@1.0-helper", vendor_available: true, diff --git a/camera/device/1.0/Android.bp b/camera/device/1.0/Android.bp index f2125af005..6947779e6b 100644 --- a/camera/device/1.0/Android.bp +++ b/camera/device/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.camera.device@1.0", root: "android.hardware", diff --git a/camera/device/1.0/default/Android.bp b/camera/device/1.0/default/Android.bp index da70577f93..9ff6480d4b 100644 --- a/camera/device/1.0/default/Android.bp +++ b/camera/device/1.0/default/Android.bp @@ -1,3 +1,12 @@ +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: "camera.device@1.0-impl", defaults: ["hidl_defaults"], diff --git a/camera/device/3.2/Android.bp b/camera/device/3.2/Android.bp index 93d1e75a36..c80538c531 100644 --- a/camera/device/3.2/Android.bp +++ b/camera/device/3.2/Android.bp @@ -1,5 +1,14 @@ // 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.camera.device@3.2", root: "android.hardware", diff --git a/camera/device/3.2/default/Android.bp b/camera/device/3.2/default/Android.bp index be2de07c6b..a1962915ff 100644 --- a/camera/device/3.2/default/Android.bp +++ b/camera/device/3.2/default/Android.bp @@ -1,3 +1,12 @@ +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: "camera.device@3.2-impl", defaults: ["hidl_defaults"], diff --git a/camera/device/3.3/Android.bp b/camera/device/3.3/Android.bp index 0f8502b80c..f5e51d6b21 100644 --- a/camera/device/3.3/Android.bp +++ b/camera/device/3.3/Android.bp @@ -1,5 +1,14 @@ // 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.camera.device@3.3", root: "android.hardware", diff --git a/camera/device/3.3/default/Android.bp b/camera/device/3.3/default/Android.bp index 0aa0dd7ca4..cc0dd39db5 100644 --- a/camera/device/3.3/default/Android.bp +++ b/camera/device/3.3/default/Android.bp @@ -1,3 +1,12 @@ +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: "camera.device@3.3-impl", defaults: ["hidl_defaults"], diff --git a/camera/device/3.4/Android.bp b/camera/device/3.4/Android.bp index 5575366155..2a6faabc3f 100644 --- a/camera/device/3.4/Android.bp +++ b/camera/device/3.4/Android.bp @@ -1,5 +1,14 @@ // 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.camera.device@3.4", root: "android.hardware", diff --git a/camera/device/3.4/default/Android.bp b/camera/device/3.4/default/Android.bp index 982dce1aae..9f0c77739a 100644 --- a/camera/device/3.4/default/Android.bp +++ b/camera/device/3.4/default/Android.bp @@ -14,6 +14,15 @@ // 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_headers { name: "camera.device@3.4-impl_headers", vendor: true, diff --git a/camera/device/3.5/Android.bp b/camera/device/3.5/Android.bp index 94962169d9..f29f9364fb 100644 --- a/camera/device/3.5/Android.bp +++ b/camera/device/3.5/Android.bp @@ -1,5 +1,14 @@ // 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.camera.device@3.5", root: "android.hardware", diff --git a/camera/device/3.5/default/Android.bp b/camera/device/3.5/default/Android.bp index d106b4b992..9d27b321e0 100644 --- a/camera/device/3.5/default/Android.bp +++ b/camera/device/3.5/default/Android.bp @@ -14,6 +14,15 @@ // 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_headers { name: "camera.device@3.5-impl_headers", vendor: true, diff --git a/camera/device/3.6/Android.bp b/camera/device/3.6/Android.bp index e6f458ca5f..ff37ca3695 100644 --- a/camera/device/3.6/Android.bp +++ b/camera/device/3.6/Android.bp @@ -1,5 +1,14 @@ // 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.camera.device@3.6", root: "android.hardware", diff --git a/camera/device/3.6/default/Android.bp b/camera/device/3.6/default/Android.bp index 2871e2a1ad..89ee145820 100644 --- a/camera/device/3.6/default/Android.bp +++ b/camera/device/3.6/default/Android.bp @@ -14,6 +14,15 @@ // 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_headers { name: "camera.device@3.6-external-impl_headers", vendor: true, diff --git a/camera/metadata/3.2/Android.bp b/camera/metadata/3.2/Android.bp index 6e55139241..ec8107e9f7 100644 --- a/camera/metadata/3.2/Android.bp +++ b/camera/metadata/3.2/Android.bp @@ -1,5 +1,14 @@ // 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.camera.metadata@3.2", root: "android.hardware", diff --git a/camera/metadata/3.3/Android.bp b/camera/metadata/3.3/Android.bp index f11fe2bd2f..4bed25b2f4 100644 --- a/camera/metadata/3.3/Android.bp +++ b/camera/metadata/3.3/Android.bp @@ -1,5 +1,14 @@ // 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.camera.metadata@3.3", root: "android.hardware", diff --git a/camera/metadata/3.4/Android.bp b/camera/metadata/3.4/Android.bp index 31218be61e..fdddfdf07a 100644 --- a/camera/metadata/3.4/Android.bp +++ b/camera/metadata/3.4/Android.bp @@ -1,5 +1,14 @@ // 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.camera.metadata@3.4", root: "android.hardware", diff --git a/camera/metadata/3.5/Android.bp b/camera/metadata/3.5/Android.bp index a28ba430a5..9349d546c5 100644 --- a/camera/metadata/3.5/Android.bp +++ b/camera/metadata/3.5/Android.bp @@ -1,5 +1,14 @@ // 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.camera.metadata@3.5", root: "android.hardware", diff --git a/camera/metadata/3.6/Android.bp b/camera/metadata/3.6/Android.bp index d9f3fb82e8..9e2b8a35e6 100644 --- a/camera/metadata/3.6/Android.bp +++ b/camera/metadata/3.6/Android.bp @@ -1,5 +1,14 @@ // 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.camera.metadata@3.6", root: "android.hardware", diff --git a/camera/provider/2.4/Android.bp b/camera/provider/2.4/Android.bp index 8b67f3fc13..a4c0dd2297 100644 --- a/camera/provider/2.4/Android.bp +++ b/camera/provider/2.4/Android.bp @@ -1,5 +1,14 @@ // 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.camera.provider@2.4", root: "android.hardware", diff --git a/camera/provider/2.4/default/Android.bp b/camera/provider/2.4/default/Android.bp index bbb21c7256..bccd6cb536 100644 --- a/camera/provider/2.4/default/Android.bp +++ b/camera/provider/2.4/default/Android.bp @@ -1,3 +1,12 @@ +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.camera.provider@2.4-legacy", defaults: ["hidl_defaults"], diff --git a/camera/provider/2.4/vts/functional/Android.bp b/camera/provider/2.4/vts/functional/Android.bp index cd66f74571..691d77252e 100644 --- a/camera/provider/2.4/vts/functional/Android.bp +++ b/camera/provider/2.4/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalCameraProviderV2_4TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/camera/provider/2.5/Android.bp b/camera/provider/2.5/Android.bp index be71806206..e14c0a846d 100644 --- a/camera/provider/2.5/Android.bp +++ b/camera/provider/2.5/Android.bp @@ -1,5 +1,14 @@ // 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.camera.provider@2.5", root: "android.hardware", diff --git a/camera/provider/2.5/default/Android.bp b/camera/provider/2.5/default/Android.bp index 9ddf651440..2fcb35ab00 100644 --- a/camera/provider/2.5/default/Android.bp +++ b/camera/provider/2.5/default/Android.bp @@ -1,3 +1,12 @@ +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.camera.provider@2.5-legacy", proprietary: true, diff --git a/camera/provider/2.6/Android.bp b/camera/provider/2.6/Android.bp index 6934c175e0..f402a560c9 100644 --- a/camera/provider/2.6/Android.bp +++ b/camera/provider/2.6/Android.bp @@ -1,5 +1,14 @@ // 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.camera.provider@2.6", root: "android.hardware", diff --git a/cas/1.0/Android.bp b/cas/1.0/Android.bp index 9f289a1dcc..368156ad76 100644 --- a/cas/1.0/Android.bp +++ b/cas/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.cas@1.0", root: "android.hardware", diff --git a/cas/1.0/default/Android.bp b/cas/1.0/default/Android.bp index 70f4371e0b..fc5b3b4361 100644 --- a/cas/1.0/default/Android.bp +++ b/cas/1.0/default/Android.bp @@ -1,3 +1,12 @@ +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_defaults { name: "cas_service_defaults", defaults: ["hidl_defaults"], diff --git a/cas/1.0/vts/functional/Android.bp b/cas/1.0/vts/functional/Android.bp index a065b85906..6d06cabfc3 100644 --- a/cas/1.0/vts/functional/Android.bp +++ b/cas/1.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalCasV1_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], @@ -33,4 +42,3 @@ cc_test { ], test_suites: ["general-tests", "vts"], } - diff --git a/cas/1.1/Android.bp b/cas/1.1/Android.bp index e20298b374..f5b1cc9564 100644 --- a/cas/1.1/Android.bp +++ b/cas/1.1/Android.bp @@ -1,5 +1,14 @@ // 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.cas@1.1", root: "android.hardware", diff --git a/cas/1.1/default/Android.bp b/cas/1.1/default/Android.bp index 8e1f20772d..2cfc0b90fb 100644 --- a/cas/1.1/default/Android.bp +++ b/cas/1.1/default/Android.bp @@ -1,3 +1,12 @@ +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_defaults { name: "cas_service_defaults@1.1", defaults: ["hidl_defaults"], diff --git a/cas/1.1/vts/functional/Android.bp b/cas/1.1/vts/functional/Android.bp index 0647d12a1c..a598554123 100644 --- a/cas/1.1/vts/functional/Android.bp +++ b/cas/1.1/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalCasV1_1TargetTest", defaults: ["VtsHalTargetTestDefaults"], @@ -33,4 +42,3 @@ cc_test { ], test_suites: ["general-tests", "vts"], } - diff --git a/cas/1.2/Android.bp b/cas/1.2/Android.bp index f03b6b7db1..6c94020464 100644 --- a/cas/1.2/Android.bp +++ b/cas/1.2/Android.bp @@ -1,5 +1,14 @@ // 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.cas@1.2", root: "android.hardware", diff --git a/cas/1.2/default/Android.bp b/cas/1.2/default/Android.bp index d855e85a67..38561fd3e7 100644 --- a/cas/1.2/default/Android.bp +++ b/cas/1.2/default/Android.bp @@ -1,3 +1,12 @@ +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_defaults { name: "cas_service_defaults@1.2", defaults: ["hidl_defaults"], diff --git a/cas/1.2/vts/functional/Android.bp b/cas/1.2/vts/functional/Android.bp index 74ea85fbf2..21f791be1c 100644 --- a/cas/1.2/vts/functional/Android.bp +++ b/cas/1.2/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalCasV1_2TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/cas/native/1.0/Android.bp b/cas/native/1.0/Android.bp index 6aa420414b..3bb74c107e 100644 --- a/cas/native/1.0/Android.bp +++ b/cas/native/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.cas.native@1.0", root: "android.hardware", diff --git a/common/aidl/Android.bp b/common/aidl/Android.bp index 8029efa023..127b6c004b 100644 --- a/common/aidl/Android.bp +++ b/common/aidl/Android.bp @@ -1,3 +1,12 @@ +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.common", host_supported: true, diff --git a/common/fmq/aidl/Android.bp b/common/fmq/aidl/Android.bp index 9389712733..1ab724f097 100644 --- a/common/fmq/aidl/Android.bp +++ b/common/fmq/aidl/Android.bp @@ -1,3 +1,12 @@ +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.common.fmq", host_supported: true, diff --git a/common/support/Android.bp b/common/support/Android.bp index ce3aa3fbd6..8aea306dae 100644 --- a/common/support/Android.bp +++ b/common/support/Android.bp @@ -1,3 +1,12 @@ +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: "libaidlcommonsupport", vendor_available: true, diff --git a/compatibility_matrices/Android.bp b/compatibility_matrices/Android.bp index de73201f8b..314a809228 100644 --- a/compatibility_matrices/Android.bp +++ b/compatibility_matrices/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"], +} + vintf_compatibility_matrix { name: "framework_compatibility_matrix.3.xml", stem: "compatibility_matrix.3.xml", diff --git a/compatibility_matrices/Android.mk b/compatibility_matrices/Android.mk index 3951666fbf..85c8ca01a7 100644 --- a/compatibility_matrices/Android.mk +++ b/compatibility_matrices/Android.mk @@ -24,6 +24,9 @@ my_empty_manifest := $(LOCAL_PATH)/manifest.empty.xml include $(CLEAR_VARS) include $(LOCAL_PATH)/clear_vars.mk LOCAL_MODULE := framework_compatibility_matrix.device.xml +LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 +LOCAL_LICENSE_CONDITIONS := notice +LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../NOTICE LOCAL_MODULE_STEM := compatibility_matrix.device.xml # define LOCAL_MODULE_CLASS for local-generated-sources-dir. LOCAL_MODULE_CLASS := ETC @@ -66,6 +69,9 @@ include $(BUILD_FRAMEWORK_COMPATIBILITY_MATRIX) include $(CLEAR_VARS) include $(LOCAL_PATH)/clear_vars.mk LOCAL_MODULE := product_compatibility_matrix.xml +LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 +LOCAL_LICENSE_CONDITIONS := notice +LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../NOTICE ifndef DEVICE_PRODUCT_COMPATIBILITY_MATRIX_FILE my_framework_matrix_deps := @@ -104,12 +110,18 @@ my_framework_matrix_deps += \ # Phony target that installs all system compatibility matrix files include $(CLEAR_VARS) LOCAL_MODULE := system_compatibility_matrix.xml +LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 +LOCAL_LICENSE_CONDITIONS := notice +LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../NOTICE LOCAL_REQUIRED_MODULES := $(my_system_matrix_deps) include $(BUILD_PHONY_PACKAGE) # Phony target that installs all framework compatibility matrix files (system + product) include $(CLEAR_VARS) LOCAL_MODULE := framework_compatibility_matrix.xml +LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 +LOCAL_LICENSE_CONDITIONS := notice +LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../NOTICE LOCAL_REQUIRED_MODULES := $(my_framework_matrix_deps) include $(BUILD_PHONY_PACKAGE) diff --git a/compatibility_matrices/build/Android.bp b/compatibility_matrices/build/Android.bp index 42dc886b12..79ef36dffc 100644 --- a/compatibility_matrices/build/Android.bp +++ b/compatibility_matrices/build/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"], +} + bootstrap_go_package { name: "vintf-compatibility-matrix-soong-rules", pkgPath: "android/soong/vintf-compatibility-matrix", diff --git a/compatibility_matrices/exclude/Android.bp b/compatibility_matrices/exclude/Android.bp index d7bf63559d..9b686ae8a0 100644 --- a/compatibility_matrices/exclude/Android.bp +++ b/compatibility_matrices/exclude/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"], +} + cc_library_host_static { name: "libvintf_fcm_exclude", cflags: [ diff --git a/configstore/1.0/Android.bp b/configstore/1.0/Android.bp index d92f2524ad..51fc44c2ca 100644 --- a/configstore/1.0/Android.bp +++ b/configstore/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.configstore@1.0", root: "android.hardware", diff --git a/configstore/1.0/vts/functional/Android.bp b/configstore/1.0/vts/functional/Android.bp index 4e1e045dd1..27c66fd42c 100644 --- a/configstore/1.0/vts/functional/Android.bp +++ b/configstore/1.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalConfigstoreV1_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], @@ -21,4 +30,3 @@ cc_test { static_libs: ["android.hardware.configstore@1.0"], test_suites: ["general-tests", "vts"], } - diff --git a/configstore/1.1/Android.bp b/configstore/1.1/Android.bp index 7c5f3f7059..ec745dd2ba 100644 --- a/configstore/1.1/Android.bp +++ b/configstore/1.1/Android.bp @@ -1,5 +1,14 @@ // 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.configstore@1.1", root: "android.hardware", diff --git a/configstore/1.1/default/Android.mk b/configstore/1.1/default/Android.mk index 6b7bb004e3..9a6f0fc24f 100644 --- a/configstore/1.1/default/Android.mk +++ b/configstore/1.1/default/Android.mk @@ -3,6 +3,9 @@ LOCAL_PATH := $(call my-dir) ################################################################################ include $(CLEAR_VARS) LOCAL_MODULE := android.hardware.configstore@1.1-service +LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 +LOCAL_LICENSE_CONDITIONS := notice +LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../../NOTICE # seccomp is not required for coverage build. ifneq ($(NATIVE_COVERAGE),true) LOCAL_REQUIRED_MODULES_arm64 := configstore@1.1.policy @@ -30,6 +33,9 @@ include $(BUILD_EXECUTABLE) ifeq ($(TARGET_ARCH), $(filter $(TARGET_ARCH), arm64)) include $(CLEAR_VARS) LOCAL_MODULE := configstore@1.1.policy +LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 +LOCAL_LICENSE_CONDITIONS := notice +LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../../NOTICE LOCAL_MODULE_CLASS := ETC LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/etc/seccomp_policy LOCAL_SRC_FILES := seccomp_policy/configstore@1.1-$(TARGET_ARCH).policy @@ -39,6 +45,9 @@ endif # disable configstore include $(CLEAR_VARS) LOCAL_MODULE := disable_configstore +LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 +LOCAL_LICENSE_CONDITIONS := notice +LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../../NOTICE LOCAL_MODULE_CLASS := EXECUTABLES LOCAL_SRC_FILES:= disable_configstore.cpp LOCAL_OVERRIDES_MODULES := android.hardware.configstore@1.1-service diff --git a/configstore/utils/Android.bp b/configstore/utils/Android.bp index 178f245fd6..7ed3f68db2 100644 --- a/configstore/utils/Android.bp +++ b/configstore/utils/Android.bp @@ -14,6 +14,15 @@ // 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_shared { name: "android.hardware.configstore-utils", vendor_available: true, diff --git a/confirmationui/1.0/Android.bp b/confirmationui/1.0/Android.bp index 15c4f18c99..950a55aa86 100644 --- a/confirmationui/1.0/Android.bp +++ b/confirmationui/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.confirmationui@1.0", root: "android.hardware", diff --git a/confirmationui/1.0/default/Android.bp b/confirmationui/1.0/default/Android.bp index 33a1e078a9..99f6f76422 100644 --- a/confirmationui/1.0/default/Android.bp +++ b/confirmationui/1.0/default/Android.bp @@ -14,6 +14,15 @@ // 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.confirmationui@1.0-service", init_rc: ["android.hardware.confirmationui@1.0-service.rc"], diff --git a/confirmationui/1.0/vts/functional/Android.bp b/confirmationui/1.0/vts/functional/Android.bp index c73ee2826c..6c6488bebe 100644 --- a/confirmationui/1.0/vts/functional/Android.bp +++ b/confirmationui/1.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalConfirmationUIV1_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/confirmationui/support/Android.bp b/confirmationui/support/Android.bp index e215baa142..6ab83f2bbe 100644 --- a/confirmationui/support/Android.bp +++ b/confirmationui/support/Android.bp @@ -14,6 +14,15 @@ // 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 { name: "android.hardware.confirmationui-support-lib", vendor_available: true, diff --git a/contexthub/1.0/Android.bp b/contexthub/1.0/Android.bp index be30d61a11..00dc666f76 100644 --- a/contexthub/1.0/Android.bp +++ b/contexthub/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.contexthub@1.0", root: "android.hardware", diff --git a/contexthub/1.0/default/Android.bp b/contexthub/1.0/default/Android.bp index 83840375f1..5bd31b62b0 100644 --- a/contexthub/1.0/default/Android.bp +++ b/contexthub/1.0/default/Android.bp @@ -14,6 +14,15 @@ * 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_shared { name: "android.hardware.contexthub@1.0-impl", defaults: ["hidl_defaults"], diff --git a/contexthub/1.0/vts/functional/Android.bp b/contexthub/1.0/vts/functional/Android.bp index 091f2dc201..5949f8d482 100644 --- a/contexthub/1.0/vts/functional/Android.bp +++ b/contexthub/1.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalContexthubV1_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/contexthub/1.1/Android.bp b/contexthub/1.1/Android.bp index 9ee8e765e5..6aba5f7de0 100644 --- a/contexthub/1.1/Android.bp +++ b/contexthub/1.1/Android.bp @@ -1,5 +1,14 @@ // 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.contexthub@1.1", root: "android.hardware", diff --git a/contexthub/1.1/default/Android.bp b/contexthub/1.1/default/Android.bp index 5c9ec4e2c7..55f5026a9a 100644 --- a/contexthub/1.1/default/Android.bp +++ b/contexthub/1.1/default/Android.bp @@ -14,6 +14,15 @@ * 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.contexthub@1.1-service.mock", defaults: ["hidl_defaults"], diff --git a/contexthub/1.1/vts/functional/Android.bp b/contexthub/1.1/vts/functional/Android.bp index 034c11fb0c..b2961c4756 100644 --- a/contexthub/1.1/vts/functional/Android.bp +++ b/contexthub/1.1/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalContexthubV1_1TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/contexthub/1.2/Android.bp b/contexthub/1.2/Android.bp index 9722a97ee6..d7d4c49cfb 100644 --- a/contexthub/1.2/Android.bp +++ b/contexthub/1.2/Android.bp @@ -1,5 +1,14 @@ // 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.contexthub@1.2", root: "android.hardware", diff --git a/contexthub/1.2/default/Android.bp b/contexthub/1.2/default/Android.bp index 0a31325811..a52577a620 100644 --- a/contexthub/1.2/default/Android.bp +++ b/contexthub/1.2/default/Android.bp @@ -14,6 +14,15 @@ * 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.contexthub@1.2-service.mock", defaults: ["hidl_defaults"], diff --git a/contexthub/1.2/vts/functional/Android.bp b/contexthub/1.2/vts/functional/Android.bp index 6e425be258..c923f42a20 100644 --- a/contexthub/1.2/vts/functional/Android.bp +++ b/contexthub/1.2/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalContexthubV1_2TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/contexthub/common/default/1.X/Android.bp b/contexthub/common/default/1.X/Android.bp index 691a1b7c9d..eef137ec83 100644 --- a/contexthub/common/default/1.X/Android.bp +++ b/contexthub/common/default/1.X/Android.bp @@ -13,6 +13,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"], +} + cc_library_headers { name: "android.hardware.contexthub@1.X-common-impl", vendor_available: true, diff --git a/contexthub/common/default/1.X/utils/Android.bp b/contexthub/common/default/1.X/utils/Android.bp index c74b647413..dabe754cca 100644 --- a/contexthub/common/default/1.X/utils/Android.bp +++ b/contexthub/common/default/1.X/utils/Android.bp @@ -13,6 +13,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"], +} + cc_library_headers { name: "android.hardware.contexthub@1.X-common-utils", vendor_available: true, diff --git a/contexthub/common/vts/Android.bp b/contexthub/common/vts/Android.bp index 3d5196a70e..ae56a6c52d 100644 --- a/contexthub/common/vts/Android.bp +++ b/contexthub/common/vts/Android.bp @@ -14,6 +14,15 @@ * limitations under the License. */ +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test_library { name: "VtsHalContexthubUtils", srcs: [ diff --git a/drm/1.0/Android.bp b/drm/1.0/Android.bp index 44fb83777f..3aa2a4d4d8 100644 --- a/drm/1.0/Android.bp +++ b/drm/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.drm@1.0", root: "android.hardware", diff --git a/drm/1.0/default/Android.bp b/drm/1.0/default/Android.bp index d5063fb2f9..af1c076e0d 100644 --- a/drm/1.0/default/Android.bp +++ b/drm/1.0/default/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"], +} + cc_library_static { name: "android.hardware.drm@1.0-helper", vendor_available: true, diff --git a/drm/1.0/vts/functional/Android.bp b/drm/1.0/vts/functional/Android.bp index 0545c70606..5ea6ad3c66 100644 --- a/drm/1.0/vts/functional/Android.bp +++ b/drm/1.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // 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: "libdrmvtshelper", defaults: ["VtsHalTargetTestDefaults"], diff --git a/drm/1.1/Android.bp b/drm/1.1/Android.bp index 0af4cf4cdf..3290203e64 100644 --- a/drm/1.1/Android.bp +++ b/drm/1.1/Android.bp @@ -1,5 +1,14 @@ // 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.drm@1.1", root: "android.hardware", diff --git a/drm/1.1/vts/functional/Android.bp b/drm/1.1/vts/functional/Android.bp index 053a564023..656ec50894 100644 --- a/drm/1.1/vts/functional/Android.bp +++ b/drm/1.1/vts/functional/Android.bp @@ -14,6 +14,15 @@ // 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.drm@1.1-vts", defaults: ["VtsHalTargetTestDefaults"], diff --git a/drm/1.2/Android.bp b/drm/1.2/Android.bp index f1c60de482..453ae0da49 100644 --- a/drm/1.2/Android.bp +++ b/drm/1.2/Android.bp @@ -1,5 +1,14 @@ // 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.drm@1.2", root: "android.hardware", diff --git a/drm/1.2/vts/functional/Android.bp b/drm/1.2/vts/functional/Android.bp index 271cc043d0..ca90ee9e30 100644 --- a/drm/1.2/vts/functional/Android.bp +++ b/drm/1.2/vts/functional/Android.bp @@ -14,6 +14,15 @@ // 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.drm@1.2-vts", defaults: ["VtsHalTargetTestDefaults"], diff --git a/drm/1.3/Android.bp b/drm/1.3/Android.bp index 9a2b9e12aa..08f7aa8367 100644 --- a/drm/1.3/Android.bp +++ b/drm/1.3/Android.bp @@ -1,5 +1,14 @@ // 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.drm@1.3", root: "android.hardware", diff --git a/drm/1.3/vts/functional/Android.bp b/drm/1.3/vts/functional/Android.bp index 3e40adfd4a..cd1cc0f85c 100644 --- a/drm/1.3/vts/functional/Android.bp +++ b/drm/1.3/vts/functional/Android.bp @@ -14,6 +14,15 @@ // 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.drm@1.3-vts", defaults: ["VtsHalTargetTestDefaults"], diff --git a/drm/1.4/Android.bp b/drm/1.4/Android.bp index f40ff87b13..d1bb4bc858 100644 --- a/drm/1.4/Android.bp +++ b/drm/1.4/Android.bp @@ -1,5 +1,14 @@ // 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.drm@1.4", root: "android.hardware", diff --git a/drm/1.4/vts/functional/Android.bp b/drm/1.4/vts/functional/Android.bp index 80b1dd1825..e18d0883a2 100644 --- a/drm/1.4/vts/functional/Android.bp +++ b/drm/1.4/vts/functional/Android.bp @@ -14,6 +14,15 @@ // 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.drm@1.4-vts", defaults: ["VtsHalTargetTestDefaults"], diff --git a/dumpstate/1.0/Android.bp b/dumpstate/1.0/Android.bp index 5d9eefcdf3..4e37ce9a0d 100644 --- a/dumpstate/1.0/Android.bp +++ b/dumpstate/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.dumpstate@1.0", root: "android.hardware", diff --git a/dumpstate/1.0/default/Android.bp b/dumpstate/1.0/default/Android.bp index 6b02715feb..18777a7eb8 100644 --- a/dumpstate/1.0/default/Android.bp +++ b/dumpstate/1.0/default/Android.bp @@ -1,3 +1,12 @@ +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.dumpstate@1.0-service.example", init_rc: ["android.hardware.dumpstate@1.0-service.rc"], diff --git a/dumpstate/1.0/vts/functional/Android.bp b/dumpstate/1.0/vts/functional/Android.bp index 451b0536fd..cc0a9cd6ca 100644 --- a/dumpstate/1.0/vts/functional/Android.bp +++ b/dumpstate/1.0/vts/functional/Android.bp @@ -13,6 +13,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"], +} + cc_test { name: "VtsHalDumpstateV1_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/dumpstate/1.1/Android.bp b/dumpstate/1.1/Android.bp index 75805dfb51..b87ca91d83 100644 --- a/dumpstate/1.1/Android.bp +++ b/dumpstate/1.1/Android.bp @@ -1,5 +1,14 @@ // 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.dumpstate@1.1", root: "android.hardware", diff --git a/dumpstate/1.1/default/Android.bp b/dumpstate/1.1/default/Android.bp index bd920752ba..29c245e8ae 100644 --- a/dumpstate/1.1/default/Android.bp +++ b/dumpstate/1.1/default/Android.bp @@ -1,3 +1,12 @@ +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.dumpstate@1.1-service.example", vendor: true, diff --git a/dumpstate/1.1/vts/functional/Android.bp b/dumpstate/1.1/vts/functional/Android.bp index 43a3c21b7c..17b412e3c0 100644 --- a/dumpstate/1.1/vts/functional/Android.bp +++ b/dumpstate/1.1/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalDumpstateV1_1TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/fastboot/1.0/Android.bp b/fastboot/1.0/Android.bp index 60dfb2d9f5..e097d4b869 100644 --- a/fastboot/1.0/Android.bp +++ b/fastboot/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.fastboot@1.0", root: "android.hardware", diff --git a/fastboot/1.0/default/Android.bp b/fastboot/1.0/default/Android.bp index f7b3635da4..bb32c0d66d 100644 --- a/fastboot/1.0/default/Android.bp +++ b/fastboot/1.0/default/Android.bp @@ -13,6 +13,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"], +} + cc_library { name: "android.hardware.fastboot@1.0-impl-mock", recovery: true, diff --git a/fastboot/1.1/Android.bp b/fastboot/1.1/Android.bp index 46306cfe81..f08e10ba71 100644 --- a/fastboot/1.1/Android.bp +++ b/fastboot/1.1/Android.bp @@ -1,5 +1,14 @@ // 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.fastboot@1.1", root: "android.hardware", diff --git a/fastboot/1.1/default/Android.bp b/fastboot/1.1/default/Android.bp index 980586ba4b..f779753241 100644 --- a/fastboot/1.1/default/Android.bp +++ b/fastboot/1.1/default/Android.bp @@ -13,6 +13,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"], +} + cc_library { name: "android.hardware.fastboot@1.1-impl-mock", recovery: true, diff --git a/gatekeeper/1.0/Android.bp b/gatekeeper/1.0/Android.bp index f5cb8e457d..631881658a 100644 --- a/gatekeeper/1.0/Android.bp +++ b/gatekeeper/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.gatekeeper@1.0", root: "android.hardware", diff --git a/gatekeeper/1.0/default/Android.bp b/gatekeeper/1.0/default/Android.bp index 2be4f4df13..a7723f697e 100644 --- a/gatekeeper/1.0/default/Android.bp +++ b/gatekeeper/1.0/default/Android.bp @@ -1,3 +1,12 @@ +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.gatekeeper@1.0-impl", defaults: ["hidl_defaults"], diff --git a/gatekeeper/1.0/software/Android.bp b/gatekeeper/1.0/software/Android.bp index 24c81f6055..098c067a67 100644 --- a/gatekeeper/1.0/software/Android.bp +++ b/gatekeeper/1.0/software/Android.bp @@ -1,3 +1,12 @@ +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.gatekeeper@1.0-service.software", defaults: ["hidl_defaults"], diff --git a/gatekeeper/1.0/software/tests/Android.bp b/gatekeeper/1.0/software/tests/Android.bp index 3f0300dc18..1162719526 100644 --- a/gatekeeper/1.0/software/tests/Android.bp +++ b/gatekeeper/1.0/software/tests/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "gatekeeper-software-device-unit-tests", diff --git a/gatekeeper/1.0/vts/functional/Android.bp b/gatekeeper/1.0/vts/functional/Android.bp index 1ca966d20f..64b3505c4d 100644 --- a/gatekeeper/1.0/vts/functional/Android.bp +++ b/gatekeeper/1.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalGatekeeperV1_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/gnss/1.0/Android.bp b/gnss/1.0/Android.bp index 22f47e8aba..873ac05e13 100644 --- a/gnss/1.0/Android.bp +++ b/gnss/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.gnss@1.0", root: "android.hardware", diff --git a/gnss/1.0/default/Android.bp b/gnss/1.0/default/Android.bp index 57d8903c47..b0cf2c6888 100644 --- a/gnss/1.0/default/Android.bp +++ b/gnss/1.0/default/Android.bp @@ -1,3 +1,12 @@ +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.gnss@1.0-impl", defaults: ["hidl_defaults"], diff --git a/gnss/1.0/vts/functional/Android.bp b/gnss/1.0/vts/functional/Android.bp index 45755e6671..f27732afdd 100644 --- a/gnss/1.0/vts/functional/Android.bp +++ b/gnss/1.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalGnssV1_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/gnss/1.1/Android.bp b/gnss/1.1/Android.bp index 1c38e97c44..0664f483c3 100644 --- a/gnss/1.1/Android.bp +++ b/gnss/1.1/Android.bp @@ -1,5 +1,14 @@ // 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.gnss@1.1", root: "android.hardware", diff --git a/gnss/1.1/default/Android.bp b/gnss/1.1/default/Android.bp index 6853ad948d..ab87990ed1 100644 --- a/gnss/1.1/default/Android.bp +++ b/gnss/1.1/default/Android.bp @@ -1,3 +1,12 @@ +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.gnss@1.1-service", init_rc: ["android.hardware.gnss@1.1-service.rc"], diff --git a/gnss/1.1/vts/functional/Android.bp b/gnss/1.1/vts/functional/Android.bp index 94bfb894d4..c59d5e7a64 100644 --- a/gnss/1.1/vts/functional/Android.bp +++ b/gnss/1.1/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalGnssV1_1TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/gnss/2.0/Android.bp b/gnss/2.0/Android.bp index b7a98b7af2..e88696341e 100644 --- a/gnss/2.0/Android.bp +++ b/gnss/2.0/Android.bp @@ -1,5 +1,14 @@ // 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.gnss@2.0", root: "android.hardware", diff --git a/gnss/2.0/default/Android.bp b/gnss/2.0/default/Android.bp index be0455365d..8ae9f956c4 100644 --- a/gnss/2.0/default/Android.bp +++ b/gnss/2.0/default/Android.bp @@ -14,6 +14,15 @@ * 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.gnss@2.0-service", init_rc: ["android.hardware.gnss@2.0-service.rc"], diff --git a/gnss/2.0/vts/functional/Android.bp b/gnss/2.0/vts/functional/Android.bp index d67677afe4..3bbd572841 100644 --- a/gnss/2.0/vts/functional/Android.bp +++ b/gnss/2.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalGnssV2_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/gnss/2.1/Android.bp b/gnss/2.1/Android.bp index affbeae66d..6273ecbaa0 100644 --- a/gnss/2.1/Android.bp +++ b/gnss/2.1/Android.bp @@ -1,5 +1,14 @@ // 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.gnss@2.1", root: "android.hardware", diff --git a/gnss/2.1/default/Android.bp b/gnss/2.1/default/Android.bp index 7c4b9c6fc5..9a44eb5607 100644 --- a/gnss/2.1/default/Android.bp +++ b/gnss/2.1/default/Android.bp @@ -14,6 +14,15 @@ * 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.gnss@2.1-service", init_rc: ["android.hardware.gnss@2.1-service.rc"], diff --git a/gnss/2.1/vts/functional/Android.bp b/gnss/2.1/vts/functional/Android.bp index aae35710cd..aaddd96f8c 100644 --- a/gnss/2.1/vts/functional/Android.bp +++ b/gnss/2.1/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalGnssV2_1TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/gnss/aidl/Android.bp b/gnss/aidl/Android.bp index c503190802..7725b9549b 100644 --- a/gnss/aidl/Android.bp +++ b/gnss/aidl/Android.bp @@ -14,6 +14,15 @@ * 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.gnss", vendor_available: true, diff --git a/gnss/aidl/default/Android.bp b/gnss/aidl/default/Android.bp index b56a701935..d363a9f832 100644 --- a/gnss/aidl/default/Android.bp +++ b/gnss/aidl/default/Android.bp @@ -14,6 +14,15 @@ * 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.gnss-service.example", relative_install_path: "hw", diff --git a/gnss/aidl/vts/Android.bp b/gnss/aidl/vts/Android.bp index 7cdc339633..838849d535 100644 --- a/gnss/aidl/vts/Android.bp +++ b/gnss/aidl/vts/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"], +} + cc_test { name: "VtsHalGnssTargetTest", defaults: [ diff --git a/gnss/common/utils/default/Android.bp b/gnss/common/utils/default/Android.bp index c44968d674..a330c5a3b0 100644 --- a/gnss/common/utils/default/Android.bp +++ b/gnss/common/utils/default/Android.bp @@ -14,6 +14,15 @@ // 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.gnss@common-default-lib", vendor_available: true, diff --git a/gnss/common/utils/vts/Android.bp b/gnss/common/utils/vts/Android.bp index e36b656171..47eff2ec9c 100644 --- a/gnss/common/utils/vts/Android.bp +++ b/gnss/common/utils/vts/Android.bp @@ -14,6 +14,15 @@ // 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.gnss@common-vts-lib", vendor_available: true, diff --git a/gnss/measurement_corrections/1.0/Android.bp b/gnss/measurement_corrections/1.0/Android.bp index a140674338..d75a9a7e54 100644 --- a/gnss/measurement_corrections/1.0/Android.bp +++ b/gnss/measurement_corrections/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.gnss.measurement_corrections@1.0", root: "android.hardware", diff --git a/gnss/measurement_corrections/1.1/Android.bp b/gnss/measurement_corrections/1.1/Android.bp index 93638489b0..1ae4ef3600 100644 --- a/gnss/measurement_corrections/1.1/Android.bp +++ b/gnss/measurement_corrections/1.1/Android.bp @@ -1,5 +1,14 @@ // 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.gnss.measurement_corrections@1.1", root: "android.hardware", diff --git a/gnss/visibility_control/1.0/Android.bp b/gnss/visibility_control/1.0/Android.bp index 975da785e9..163595a588 100644 --- a/gnss/visibility_control/1.0/Android.bp +++ b/gnss/visibility_control/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.gnss.visibility_control@1.0", root: "android.hardware", diff --git a/graphics/allocator/2.0/Android.bp b/graphics/allocator/2.0/Android.bp index 37d9dfcf89..6ec4e645c1 100644 --- a/graphics/allocator/2.0/Android.bp +++ b/graphics/allocator/2.0/Android.bp @@ -1,5 +1,14 @@ // 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.graphics.allocator@2.0", root: "android.hardware", diff --git a/graphics/allocator/2.0/default/Android.bp b/graphics/allocator/2.0/default/Android.bp index 59229b06e3..4d17dc3a1b 100644 --- a/graphics/allocator/2.0/default/Android.bp +++ b/graphics/allocator/2.0/default/Android.bp @@ -1,3 +1,12 @@ +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.graphics.allocator@2.0-impl", defaults: ["hidl_defaults"], diff --git a/graphics/allocator/2.0/utils/gralloc1-adapter/Android.bp b/graphics/allocator/2.0/utils/gralloc1-adapter/Android.bp index 9cb53e363b..bc42099c92 100644 --- a/graphics/allocator/2.0/utils/gralloc1-adapter/Android.bp +++ b/graphics/allocator/2.0/utils/gralloc1-adapter/Android.bp @@ -1,3 +1,12 @@ +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: "libgralloc1-adapter", defaults: ["hidl_defaults"], diff --git a/graphics/allocator/2.0/utils/hal/Android.bp b/graphics/allocator/2.0/utils/hal/Android.bp index ac642ce99f..6bb9a0f657 100644 --- a/graphics/allocator/2.0/utils/hal/Android.bp +++ b/graphics/allocator/2.0/utils/hal/Android.bp @@ -1,3 +1,12 @@ +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_headers { name: "android.hardware.graphics.allocator@2.0-hal", defaults: ["hidl_defaults"], diff --git a/graphics/allocator/2.0/utils/passthrough/Android.bp b/graphics/allocator/2.0/utils/passthrough/Android.bp index 95b92cfb55..f5ac5a61e6 100644 --- a/graphics/allocator/2.0/utils/passthrough/Android.bp +++ b/graphics/allocator/2.0/utils/passthrough/Android.bp @@ -1,3 +1,12 @@ +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_headers { name: "android.hardware.graphics.allocator@2.0-passthrough", defaults: ["hidl_defaults"], diff --git a/graphics/allocator/3.0/Android.bp b/graphics/allocator/3.0/Android.bp index 2cfa1d0ab7..768baba987 100644 --- a/graphics/allocator/3.0/Android.bp +++ b/graphics/allocator/3.0/Android.bp @@ -1,5 +1,14 @@ // 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.graphics.allocator@3.0", root: "android.hardware", diff --git a/graphics/allocator/4.0/Android.bp b/graphics/allocator/4.0/Android.bp index f5f94585a7..0df9b390f5 100644 --- a/graphics/allocator/4.0/Android.bp +++ b/graphics/allocator/4.0/Android.bp @@ -1,5 +1,14 @@ // 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.graphics.allocator@4.0", root: "android.hardware", diff --git a/graphics/bufferqueue/1.0/Android.bp b/graphics/bufferqueue/1.0/Android.bp index 7fca3548e3..eda80d7a0d 100644 --- a/graphics/bufferqueue/1.0/Android.bp +++ b/graphics/bufferqueue/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.graphics.bufferqueue@1.0", root: "android.hardware", diff --git a/graphics/bufferqueue/2.0/Android.bp b/graphics/bufferqueue/2.0/Android.bp index fd080794b8..13feeb1548 100644 --- a/graphics/bufferqueue/2.0/Android.bp +++ b/graphics/bufferqueue/2.0/Android.bp @@ -1,5 +1,14 @@ // 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.graphics.bufferqueue@2.0", root: "android.hardware", diff --git a/graphics/common/1.0/Android.bp b/graphics/common/1.0/Android.bp index 089fe145a2..74a0d9b9ea 100644 --- a/graphics/common/1.0/Android.bp +++ b/graphics/common/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.graphics.common@1.0", root: "android.hardware", diff --git a/graphics/common/1.1/Android.bp b/graphics/common/1.1/Android.bp index 899fe039ce..a120278a86 100644 --- a/graphics/common/1.1/Android.bp +++ b/graphics/common/1.1/Android.bp @@ -1,5 +1,14 @@ // 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.graphics.common@1.1", root: "android.hardware", diff --git a/graphics/common/1.2/Android.bp b/graphics/common/1.2/Android.bp index 2c4d93b734..fe149e4225 100644 --- a/graphics/common/1.2/Android.bp +++ b/graphics/common/1.2/Android.bp @@ -1,5 +1,14 @@ // 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.graphics.common@1.2", root: "android.hardware", diff --git a/graphics/common/aidl/Android.bp b/graphics/common/aidl/Android.bp index 22e609d758..2a46f9dc7f 100644 --- a/graphics/common/aidl/Android.bp +++ b/graphics/common/aidl/Android.bp @@ -1,3 +1,12 @@ +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.graphics.common", host_supported: true, diff --git a/graphics/composer/2.1/Android.bp b/graphics/composer/2.1/Android.bp index 2358a8fbf3..2e41208663 100644 --- a/graphics/composer/2.1/Android.bp +++ b/graphics/composer/2.1/Android.bp @@ -1,5 +1,14 @@ // 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.graphics.composer@2.1", root: "android.hardware", diff --git a/graphics/composer/2.1/default/Android.bp b/graphics/composer/2.1/default/Android.bp index a367457ae9..96fea4e6cd 100644 --- a/graphics/composer/2.1/default/Android.bp +++ b/graphics/composer/2.1/default/Android.bp @@ -1,3 +1,12 @@ +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.graphics.composer@2.1-service", defaults: ["hidl_defaults"], diff --git a/graphics/composer/2.1/utils/command-buffer/Android.bp b/graphics/composer/2.1/utils/command-buffer/Android.bp index 140d9bb698..07dea31736 100644 --- a/graphics/composer/2.1/utils/command-buffer/Android.bp +++ b/graphics/composer/2.1/utils/command-buffer/Android.bp @@ -1,3 +1,12 @@ +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_headers { name: "android.hardware.graphics.composer@2.1-command-buffer", defaults: ["hidl_defaults"], diff --git a/graphics/composer/2.1/utils/hal/Android.bp b/graphics/composer/2.1/utils/hal/Android.bp index ea3666dd28..874be84f4d 100644 --- a/graphics/composer/2.1/utils/hal/Android.bp +++ b/graphics/composer/2.1/utils/hal/Android.bp @@ -13,6 +13,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"], +} + cc_library_headers { name: "android.hardware.graphics.composer@2.1-hal", defaults: ["hidl_defaults"], diff --git a/graphics/composer/2.1/utils/hwc2on1adapter/Android.bp b/graphics/composer/2.1/utils/hwc2on1adapter/Android.bp index ec7a0b927a..0171dd68c9 100644 --- a/graphics/composer/2.1/utils/hwc2on1adapter/Android.bp +++ b/graphics/composer/2.1/utils/hwc2on1adapter/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"], +} + cc_library_shared { name: "libhwc2on1adapter", vendor: true, diff --git a/graphics/composer/2.1/utils/hwc2onfbadapter/Android.bp b/graphics/composer/2.1/utils/hwc2onfbadapter/Android.bp index 73a41f7ff4..3965d1217e 100644 --- a/graphics/composer/2.1/utils/hwc2onfbadapter/Android.bp +++ b/graphics/composer/2.1/utils/hwc2onfbadapter/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"], +} + cc_library_shared { name: "libhwc2onfbadapter", vendor: true, diff --git a/graphics/composer/2.1/utils/passthrough/Android.bp b/graphics/composer/2.1/utils/passthrough/Android.bp index 4d3c976acd..67f516399c 100644 --- a/graphics/composer/2.1/utils/passthrough/Android.bp +++ b/graphics/composer/2.1/utils/passthrough/Android.bp @@ -1,3 +1,12 @@ +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_headers { name: "android.hardware.graphics.composer@2.1-passthrough", defaults: ["hidl_defaults"], diff --git a/graphics/composer/2.1/utils/resources/Android.bp b/graphics/composer/2.1/utils/resources/Android.bp index d77bff07bc..9eb23fa82e 100644 --- a/graphics/composer/2.1/utils/resources/Android.bp +++ b/graphics/composer/2.1/utils/resources/Android.bp @@ -13,6 +13,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"], +} + cc_library { name: "android.hardware.graphics.composer@2.1-resources", system_ext_specific: true, diff --git a/graphics/composer/2.1/utils/vts/Android.bp b/graphics/composer/2.1/utils/vts/Android.bp index 3b0911f923..8732d53a44 100644 --- a/graphics/composer/2.1/utils/vts/Android.bp +++ b/graphics/composer/2.1/utils/vts/Android.bp @@ -14,6 +14,15 @@ // 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.graphics.composer@2.1-vts", defaults: ["hidl_defaults"], diff --git a/graphics/composer/2.1/vts/functional/Android.bp b/graphics/composer/2.1/vts/functional/Android.bp index 9e703d8f0b..eb67d34b50 100644 --- a/graphics/composer/2.1/vts/functional/Android.bp +++ b/graphics/composer/2.1/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalGraphicsComposerV2_1TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/graphics/composer/2.2/Android.bp b/graphics/composer/2.2/Android.bp index 234b9ac6bf..e44a236ba9 100644 --- a/graphics/composer/2.2/Android.bp +++ b/graphics/composer/2.2/Android.bp @@ -1,5 +1,14 @@ // 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.graphics.composer@2.2", root: "android.hardware", diff --git a/graphics/composer/2.2/default/Android.mk b/graphics/composer/2.2/default/Android.mk index 156ecb6bad..6f7ef85904 100644 --- a/graphics/composer/2.2/default/Android.mk +++ b/graphics/composer/2.2/default/Android.mk @@ -2,6 +2,9 @@ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := android.hardware.graphics.composer@2.2-service +LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 +LOCAL_LICENSE_CONDITIONS := notice +LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../../../NOTICE LOCAL_VENDOR_MODULE := true LOCAL_MODULE_RELATIVE_PATH := hw LOCAL_CFLAGS := -Wall -Werror -DLOG_TAG=\"ComposerHal\" diff --git a/graphics/composer/2.2/utils/command-buffer/Android.bp b/graphics/composer/2.2/utils/command-buffer/Android.bp index c4ceaabe9f..d55145e48c 100644 --- a/graphics/composer/2.2/utils/command-buffer/Android.bp +++ b/graphics/composer/2.2/utils/command-buffer/Android.bp @@ -1,3 +1,12 @@ +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_headers { name: "android.hardware.graphics.composer@2.2-command-buffer", defaults: ["hidl_defaults"], diff --git a/graphics/composer/2.2/utils/hal/Android.bp b/graphics/composer/2.2/utils/hal/Android.bp index f334a11c7c..4e028e034e 100644 --- a/graphics/composer/2.2/utils/hal/Android.bp +++ b/graphics/composer/2.2/utils/hal/Android.bp @@ -13,6 +13,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"], +} + cc_library_headers { name: "android.hardware.graphics.composer@2.2-hal", defaults: ["hidl_defaults"], diff --git a/graphics/composer/2.2/utils/passthrough/Android.bp b/graphics/composer/2.2/utils/passthrough/Android.bp index 318ce914ed..b7003446e7 100644 --- a/graphics/composer/2.2/utils/passthrough/Android.bp +++ b/graphics/composer/2.2/utils/passthrough/Android.bp @@ -1,3 +1,12 @@ +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_headers { name: "android.hardware.graphics.composer@2.2-passthrough", defaults: ["hidl_defaults"], diff --git a/graphics/composer/2.2/utils/resources/Android.bp b/graphics/composer/2.2/utils/resources/Android.bp index 752eb8170d..9e45ef2bc4 100644 --- a/graphics/composer/2.2/utils/resources/Android.bp +++ b/graphics/composer/2.2/utils/resources/Android.bp @@ -13,6 +13,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"], +} + cc_library_shared { name: "android.hardware.graphics.composer@2.2-resources", defaults: ["hidl_defaults"], diff --git a/graphics/composer/2.2/utils/vts/Android.bp b/graphics/composer/2.2/utils/vts/Android.bp index a8bb1a22cb..5c085cb768 100644 --- a/graphics/composer/2.2/utils/vts/Android.bp +++ b/graphics/composer/2.2/utils/vts/Android.bp @@ -14,6 +14,15 @@ // 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.graphics.composer@2.2-vts", defaults: ["hidl_defaults"], diff --git a/graphics/composer/2.2/vts/functional/Android.bp b/graphics/composer/2.2/vts/functional/Android.bp index 6aa836c7b9..36f3c00fae 100644 --- a/graphics/composer/2.2/vts/functional/Android.bp +++ b/graphics/composer/2.2/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalGraphicsComposerV2_2TargetTest", defaults: [ diff --git a/graphics/composer/2.3/Android.bp b/graphics/composer/2.3/Android.bp index 96f301c807..3c52b6f0d5 100644 --- a/graphics/composer/2.3/Android.bp +++ b/graphics/composer/2.3/Android.bp @@ -1,5 +1,14 @@ // 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.graphics.composer@2.3", root: "android.hardware", diff --git a/graphics/composer/2.3/default/Android.bp b/graphics/composer/2.3/default/Android.bp index a5696ddb95..f801fbadfa 100644 --- a/graphics/composer/2.3/default/Android.bp +++ b/graphics/composer/2.3/default/Android.bp @@ -14,6 +14,15 @@ // 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.graphics.composer@2.3-service", defaults: ["hidl_defaults"], diff --git a/graphics/composer/2.3/utils/command-buffer/Android.bp b/graphics/composer/2.3/utils/command-buffer/Android.bp index 36ac297588..ca7d136edc 100644 --- a/graphics/composer/2.3/utils/command-buffer/Android.bp +++ b/graphics/composer/2.3/utils/command-buffer/Android.bp @@ -1,3 +1,12 @@ +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_headers { name: "android.hardware.graphics.composer@2.3-command-buffer", defaults: ["hidl_defaults"], diff --git a/graphics/composer/2.3/utils/hal/Android.bp b/graphics/composer/2.3/utils/hal/Android.bp index 3ee930050c..b475757658 100644 --- a/graphics/composer/2.3/utils/hal/Android.bp +++ b/graphics/composer/2.3/utils/hal/Android.bp @@ -14,6 +14,15 @@ // 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_headers { name: "android.hardware.graphics.composer@2.3-hal", defaults: ["hidl_defaults"], diff --git a/graphics/composer/2.3/utils/passthrough/Android.bp b/graphics/composer/2.3/utils/passthrough/Android.bp index 3ae6b1648d..68b706cdc1 100644 --- a/graphics/composer/2.3/utils/passthrough/Android.bp +++ b/graphics/composer/2.3/utils/passthrough/Android.bp @@ -14,6 +14,15 @@ // 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_headers { name: "android.hardware.graphics.composer@2.3-passthrough", defaults: ["hidl_defaults"], diff --git a/graphics/composer/2.3/utils/vts/Android.bp b/graphics/composer/2.3/utils/vts/Android.bp index 3d81e8f647..7bc07a4428 100644 --- a/graphics/composer/2.3/utils/vts/Android.bp +++ b/graphics/composer/2.3/utils/vts/Android.bp @@ -14,6 +14,15 @@ // 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.graphics.composer@2.3-vts", defaults: ["hidl_defaults"], diff --git a/graphics/composer/2.3/vts/functional/Android.bp b/graphics/composer/2.3/vts/functional/Android.bp index 1cbb60e555..d27a1513f4 100644 --- a/graphics/composer/2.3/vts/functional/Android.bp +++ b/graphics/composer/2.3/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalGraphicsComposerV2_3TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/graphics/composer/2.4/Android.bp b/graphics/composer/2.4/Android.bp index 2bbe751402..e6b238ba9f 100644 --- a/graphics/composer/2.4/Android.bp +++ b/graphics/composer/2.4/Android.bp @@ -1,5 +1,14 @@ // 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.graphics.composer@2.4", root: "android.hardware", diff --git a/graphics/composer/2.4/default/Android.bp b/graphics/composer/2.4/default/Android.bp index a30609b1a2..7a91ec1f11 100644 --- a/graphics/composer/2.4/default/Android.bp +++ b/graphics/composer/2.4/default/Android.bp @@ -14,6 +14,15 @@ // 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.graphics.composer@2.4-service", defaults: ["hidl_defaults"], diff --git a/graphics/composer/2.4/utils/command-buffer/Android.bp b/graphics/composer/2.4/utils/command-buffer/Android.bp index 8acf0e13ca..c966fc4171 100644 --- a/graphics/composer/2.4/utils/command-buffer/Android.bp +++ b/graphics/composer/2.4/utils/command-buffer/Android.bp @@ -1,3 +1,12 @@ +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_headers { name: "android.hardware.graphics.composer@2.4-command-buffer", defaults: ["hidl_defaults"], diff --git a/graphics/composer/2.4/utils/hal/Android.bp b/graphics/composer/2.4/utils/hal/Android.bp index f4cdea49a8..abf8e0450b 100644 --- a/graphics/composer/2.4/utils/hal/Android.bp +++ b/graphics/composer/2.4/utils/hal/Android.bp @@ -14,6 +14,15 @@ // 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_headers { name: "android.hardware.graphics.composer@2.4-hal", defaults: ["hidl_defaults"], diff --git a/graphics/composer/2.4/utils/passthrough/Android.bp b/graphics/composer/2.4/utils/passthrough/Android.bp index 43d9aaaa78..a851c0a081 100644 --- a/graphics/composer/2.4/utils/passthrough/Android.bp +++ b/graphics/composer/2.4/utils/passthrough/Android.bp @@ -14,6 +14,15 @@ // 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_headers { name: "android.hardware.graphics.composer@2.4-passthrough", defaults: ["hidl_defaults"], diff --git a/graphics/composer/2.4/utils/vts/Android.bp b/graphics/composer/2.4/utils/vts/Android.bp index fc13c2a79c..5ef861c4f7 100644 --- a/graphics/composer/2.4/utils/vts/Android.bp +++ b/graphics/composer/2.4/utils/vts/Android.bp @@ -14,6 +14,15 @@ // 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.graphics.composer@2.4-vts", defaults: ["hidl_defaults"], diff --git a/graphics/composer/2.4/vts/functional/Android.bp b/graphics/composer/2.4/vts/functional/Android.bp index cab549c50b..6089e2da75 100644 --- a/graphics/composer/2.4/vts/functional/Android.bp +++ b/graphics/composer/2.4/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalGraphicsComposerV2_4TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/graphics/mapper/2.0/Android.bp b/graphics/mapper/2.0/Android.bp index 4459bdc7f6..63fdfa6cc5 100644 --- a/graphics/mapper/2.0/Android.bp +++ b/graphics/mapper/2.0/Android.bp @@ -1,5 +1,14 @@ // 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.graphics.mapper@2.0", root: "android.hardware", diff --git a/graphics/mapper/2.0/default/Android.bp b/graphics/mapper/2.0/default/Android.bp index 4f641842db..fffea3b5f2 100644 --- a/graphics/mapper/2.0/default/Android.bp +++ b/graphics/mapper/2.0/default/Android.bp @@ -13,6 +13,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"], +} + cc_library_shared { name: "android.hardware.graphics.mapper@2.0-impl", defaults: ["hidl_defaults"], diff --git a/graphics/mapper/2.0/utils/hal/Android.bp b/graphics/mapper/2.0/utils/hal/Android.bp index 5610a69aac..f5d4506100 100644 --- a/graphics/mapper/2.0/utils/hal/Android.bp +++ b/graphics/mapper/2.0/utils/hal/Android.bp @@ -13,6 +13,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"], +} + cc_library_headers { name: "android.hardware.graphics.mapper@2.0-hal", defaults: ["hidl_defaults"], diff --git a/graphics/mapper/2.0/utils/passthrough/Android.bp b/graphics/mapper/2.0/utils/passthrough/Android.bp index 4f700c867a..23450fb0a7 100644 --- a/graphics/mapper/2.0/utils/passthrough/Android.bp +++ b/graphics/mapper/2.0/utils/passthrough/Android.bp @@ -13,6 +13,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"], +} + cc_library_headers { name: "android.hardware.graphics.mapper@2.0-passthrough", defaults: ["hidl_defaults"], diff --git a/graphics/mapper/2.0/utils/vts/Android.bp b/graphics/mapper/2.0/utils/vts/Android.bp index e43011f0a8..03f925d7bf 100644 --- a/graphics/mapper/2.0/utils/vts/Android.bp +++ b/graphics/mapper/2.0/utils/vts/Android.bp @@ -14,6 +14,15 @@ // 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.graphics.mapper@2.0-vts", defaults: ["VtsHalTargetTestDefaults"], diff --git a/graphics/mapper/2.0/vts/functional/Android.bp b/graphics/mapper/2.0/vts/functional/Android.bp index 1f7ae04c15..43e61565fb 100644 --- a/graphics/mapper/2.0/vts/functional/Android.bp +++ b/graphics/mapper/2.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalGraphicsMapperV2_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/graphics/mapper/2.1/Android.bp b/graphics/mapper/2.1/Android.bp index e5a5ae4d66..4011650d85 100644 --- a/graphics/mapper/2.1/Android.bp +++ b/graphics/mapper/2.1/Android.bp @@ -1,5 +1,14 @@ // 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.graphics.mapper@2.1", root: "android.hardware", diff --git a/graphics/mapper/2.1/default/Android.bp b/graphics/mapper/2.1/default/Android.bp index 2ea7f94b82..4f080c417f 100644 --- a/graphics/mapper/2.1/default/Android.bp +++ b/graphics/mapper/2.1/default/Android.bp @@ -13,6 +13,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"], +} + cc_library_shared { name: "android.hardware.graphics.mapper@2.0-impl-2.1", defaults: ["hidl_defaults"], diff --git a/graphics/mapper/2.1/utils/hal/Android.bp b/graphics/mapper/2.1/utils/hal/Android.bp index 2a4cc6e4fb..aff497cea0 100644 --- a/graphics/mapper/2.1/utils/hal/Android.bp +++ b/graphics/mapper/2.1/utils/hal/Android.bp @@ -13,6 +13,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"], +} + cc_library_headers { name: "android.hardware.graphics.mapper@2.1-hal", defaults: ["hidl_defaults"], diff --git a/graphics/mapper/2.1/utils/passthrough/Android.bp b/graphics/mapper/2.1/utils/passthrough/Android.bp index 6946a53c71..d46041b37a 100644 --- a/graphics/mapper/2.1/utils/passthrough/Android.bp +++ b/graphics/mapper/2.1/utils/passthrough/Android.bp @@ -13,6 +13,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"], +} + cc_library_headers { name: "android.hardware.graphics.mapper@2.1-passthrough", defaults: ["hidl_defaults"], diff --git a/graphics/mapper/2.1/utils/vts/Android.bp b/graphics/mapper/2.1/utils/vts/Android.bp index abbe50a64c..5c67df9443 100644 --- a/graphics/mapper/2.1/utils/vts/Android.bp +++ b/graphics/mapper/2.1/utils/vts/Android.bp @@ -14,6 +14,15 @@ // 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.graphics.mapper@2.1-vts", defaults: ["hidl_defaults", "VtsHalTargetTestDefaults"], diff --git a/graphics/mapper/2.1/vts/functional/Android.bp b/graphics/mapper/2.1/vts/functional/Android.bp index ccbe40fd96..7bbc9a44f7 100644 --- a/graphics/mapper/2.1/vts/functional/Android.bp +++ b/graphics/mapper/2.1/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalGraphicsMapperV2_1TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/graphics/mapper/3.0/Android.bp b/graphics/mapper/3.0/Android.bp index a14324310c..401a3a22b5 100644 --- a/graphics/mapper/3.0/Android.bp +++ b/graphics/mapper/3.0/Android.bp @@ -1,5 +1,14 @@ // 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.graphics.mapper@3.0", root: "android.hardware", diff --git a/graphics/mapper/3.0/utils/vts/Android.bp b/graphics/mapper/3.0/utils/vts/Android.bp index c3d480a565..c0d56de1ab 100644 --- a/graphics/mapper/3.0/utils/vts/Android.bp +++ b/graphics/mapper/3.0/utils/vts/Android.bp @@ -14,6 +14,15 @@ // 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.graphics.mapper@3.0-vts", defaults: ["VtsHalTargetTestDefaults"], diff --git a/graphics/mapper/3.0/vts/functional/Android.bp b/graphics/mapper/3.0/vts/functional/Android.bp index 3f4abecdd4..e83702703c 100644 --- a/graphics/mapper/3.0/vts/functional/Android.bp +++ b/graphics/mapper/3.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalGraphicsMapperV3_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/graphics/mapper/4.0/Android.bp b/graphics/mapper/4.0/Android.bp index 42c4942e85..4084dcda91 100644 --- a/graphics/mapper/4.0/Android.bp +++ b/graphics/mapper/4.0/Android.bp @@ -1,5 +1,14 @@ // 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.graphics.mapper@4.0", root: "android.hardware", diff --git a/graphics/mapper/4.0/utils/vts/Android.bp b/graphics/mapper/4.0/utils/vts/Android.bp index 56ff116a43..633149805c 100644 --- a/graphics/mapper/4.0/utils/vts/Android.bp +++ b/graphics/mapper/4.0/utils/vts/Android.bp @@ -14,6 +14,15 @@ // 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.graphics.mapper@4.0-vts", defaults: ["VtsHalTargetTestDefaults"], diff --git a/graphics/mapper/4.0/vts/functional/Android.bp b/graphics/mapper/4.0/vts/functional/Android.bp index 2d39daaa0b..11ebdc59a1 100644 --- a/graphics/mapper/4.0/vts/functional/Android.bp +++ b/graphics/mapper/4.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalGraphicsMapperV4_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/health/1.0/Android.bp b/health/1.0/Android.bp index 7786c08bdc..003b106cc2 100644 --- a/health/1.0/Android.bp +++ b/health/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.health@1.0", root: "android.hardware", diff --git a/health/1.0/default/Android.bp b/health/1.0/default/Android.bp index ff4b8759b8..6a21595378 100644 --- a/health/1.0/default/Android.bp +++ b/health/1.0/default/Android.bp @@ -1,3 +1,12 @@ +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.health@1.0-convert", vendor_available: true, diff --git a/health/2.0/Android.bp b/health/2.0/Android.bp index 420586e2e2..ddd983dc50 100644 --- a/health/2.0/Android.bp +++ b/health/2.0/Android.bp @@ -1,5 +1,14 @@ // 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.health@2.0", root: "android.hardware", diff --git a/health/2.0/default/Android.bp b/health/2.0/default/Android.bp index 3c5877e1da..73cd553058 100644 --- a/health/2.0/default/Android.bp +++ b/health/2.0/default/Android.bp @@ -1,3 +1,12 @@ +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_defaults { name: "android.hardware.health@2.0-impl_defaults", diff --git a/health/2.0/utils/libhealthhalutils/Android.bp b/health/2.0/utils/libhealthhalutils/Android.bp index 449ef16b30..fa6e67e397 100644 --- a/health/2.0/utils/libhealthhalutils/Android.bp +++ b/health/2.0/utils/libhealthhalutils/Android.bp @@ -16,6 +16,15 @@ // Convenience library for (hwbinder) clients to choose the correct health // service instance. +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: "libhealthhalutils", srcs: ["HealthHalUtils.cpp"], diff --git a/health/2.0/utils/libhealthservice/Android.bp b/health/2.0/utils/libhealthservice/Android.bp index 88c38f2125..8023692247 100644 --- a/health/2.0/utils/libhealthservice/Android.bp +++ b/health/2.0/utils/libhealthservice/Android.bp @@ -3,6 +3,15 @@ // libhealthd and libhealthstoragedefault. +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: "libhealthservice", vendor_available: true, diff --git a/health/2.0/utils/libhealthstoragedefault/Android.bp b/health/2.0/utils/libhealthstoragedefault/Android.bp index 5bc8b9fdef..3de8789713 100644 --- a/health/2.0/utils/libhealthstoragedefault/Android.bp +++ b/health/2.0/utils/libhealthstoragedefault/Android.bp @@ -17,6 +17,15 @@ // Default implementation for (passthrough) clients that statically links to // android.hardware.health@2.0-impl but do no query for storage related // information. +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 { srcs: ["StorageHealthDefault.cpp"], name: "libhealthstoragedefault", diff --git a/health/2.0/vts/functional/Android.bp b/health/2.0/vts/functional/Android.bp index ab14ca75c3..eb696123f4 100644 --- a/health/2.0/vts/functional/Android.bp +++ b/health/2.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalHealthV2_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/health/2.1/Android.bp b/health/2.1/Android.bp index 80a6501664..8a116173fb 100644 --- a/health/2.1/Android.bp +++ b/health/2.1/Android.bp @@ -1,5 +1,14 @@ // 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.health@2.1", root: "android.hardware", diff --git a/health/2.1/default/Android.bp b/health/2.1/default/Android.bp index 3649853a3d..b7bcea5d18 100644 --- a/health/2.1/default/Android.bp +++ b/health/2.1/default/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"], +} + cc_defaults { name: "android.hardware.health@2.1-impl-defaults", relative_install_path: "hw", diff --git a/health/2.1/vts/functional/Android.bp b/health/2.1/vts/functional/Android.bp index 7894ca24a8..238a150d10 100644 --- a/health/2.1/vts/functional/Android.bp +++ b/health/2.1/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalHealthV2_1TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/health/storage/1.0/Android.bp b/health/storage/1.0/Android.bp index b9d892db43..70b2bdce13 100644 --- a/health/storage/1.0/Android.bp +++ b/health/storage/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.health.storage@1.0", root: "android.hardware", diff --git a/health/storage/1.0/default/Android.bp b/health/storage/1.0/default/Android.bp index 3834244cea..7edf9d1a5e 100644 --- a/health/storage/1.0/default/Android.bp +++ b/health/storage/1.0/default/Android.bp @@ -14,6 +14,15 @@ * 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.health.storage@1.0-service", vendor: true, diff --git a/health/storage/1.0/vts/functional/Android.bp b/health/storage/1.0/vts/functional/Android.bp index 731ad62434..ccf22ce2e0 100644 --- a/health/storage/1.0/vts/functional/Android.bp +++ b/health/storage/1.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalHealthStorageV1_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/health/storage/aidl/Android.bp b/health/storage/aidl/Android.bp index c39a46d48e..bf49466a91 100644 --- a/health/storage/aidl/Android.bp +++ b/health/storage/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.health.storage", vendor_available: true, diff --git a/health/storage/aidl/default/Android.bp b/health/storage/aidl/default/Android.bp index b53bc35f28..819b885318 100644 --- a/health/storage/aidl/default/Android.bp +++ b/health/storage/aidl/default/Android.bp @@ -14,6 +14,15 @@ * 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_defaults { name: "libhealth_storage_impl_defaults", vendor: true, diff --git a/health/storage/aidl/vts/functional/Android.bp b/health/storage/aidl/vts/functional/Android.bp index 0e7671df03..be3eac7d98 100644 --- a/health/storage/aidl/vts/functional/Android.bp +++ b/health/storage/aidl/vts/functional/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"], +} + cc_test { name: "VtsHalHealthStorageTargetTest", defaults: [ diff --git a/health/storage/impl_common/Android.bp b/health/storage/impl_common/Android.bp index e1149c0cb7..925cd5506a 100644 --- a/health/storage/impl_common/Android.bp +++ b/health/storage/impl_common/Android.bp @@ -15,6 +15,15 @@ */ // Common implementation between HIDL and AIDL 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_library_static { name: "libhealth_storage_impl_common", vendor: true, diff --git a/health/storage/test_common/Android.bp b/health/storage/test_common/Android.bp index 7c6bef414c..a43aae5454 100644 --- a/health/storage/test_common/Android.bp +++ b/health/storage/test_common/Android.bp @@ -14,6 +14,15 @@ * 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_headers { name: "libhealth_storage_test_common_headers", export_include_dirs: ["include"], diff --git a/health/utils/libhealth2impl/Android.bp b/health/utils/libhealth2impl/Android.bp index 14374a29ee..58417af32b 100644 --- a/health/utils/libhealth2impl/Android.bp +++ b/health/utils/libhealth2impl/Android.bp @@ -14,6 +14,15 @@ // A helper library for health@2.x HAL implementation. // HAL implementations can link to this library and extend the Health class. +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: "libhealth2impl", vendor_available: true, diff --git a/health/utils/libhealthloop/Android.bp b/health/utils/libhealthloop/Android.bp index de0f24fcbb..7aaf90516e 100644 --- a/health/utils/libhealthloop/Android.bp +++ b/health/utils/libhealthloop/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"], +} + cc_library_static { name: "libhealthloop", vendor_available: true, diff --git a/identity/aidl/Android.bp b/identity/aidl/Android.bp index 14aef8ee40..8da664245d 100644 --- a/identity/aidl/Android.bp +++ b/identity/aidl/Android.bp @@ -1,3 +1,12 @@ +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.identity", vendor_available: true, diff --git a/identity/aidl/default/Android.bp b/identity/aidl/default/Android.bp index 9659f576cf..05b3662035 100644 --- a/identity/aidl/default/Android.bp +++ b/identity/aidl/default/Android.bp @@ -1,3 +1,12 @@ +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.identity-libeic-hal-common", vendor_available: true, diff --git a/identity/aidl/vts/Android.bp b/identity/aidl/vts/Android.bp index f487a64799..82c40110eb 100644 --- a/identity/aidl/vts/Android.bp +++ b/identity/aidl/vts/Android.bp @@ -1,3 +1,12 @@ +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalIdentityTargetTest", defaults: [ diff --git a/identity/support/Android.bp b/identity/support/Android.bp index 2b6c695442..d00f59a9fa 100644 --- a/identity/support/Android.bp +++ b/identity/support/Android.bp @@ -13,6 +13,15 @@ // 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 { name: "android.hardware.identity-support-lib", vendor_available: true, diff --git a/input/classifier/1.0/Android.bp b/input/classifier/1.0/Android.bp index b6e54ca56a..37e522d4f5 100644 --- a/input/classifier/1.0/Android.bp +++ b/input/classifier/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.input.classifier@1.0", root: "android.hardware", diff --git a/input/classifier/1.0/default/Android.bp b/input/classifier/1.0/default/Android.bp index 3379a76a81..8ab2ba8b9a 100644 --- a/input/classifier/1.0/default/Android.bp +++ b/input/classifier/1.0/default/Android.bp @@ -1,3 +1,12 @@ +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.input.classifier@1.0-service.default", init_rc: ["android.hardware.input.classifier@1.0-service.default.rc"], diff --git a/input/classifier/1.0/vts/functional/Android.bp b/input/classifier/1.0/vts/functional/Android.bp index fc1f5857b2..e170f4a613 100644 --- a/input/classifier/1.0/vts/functional/Android.bp +++ b/input/classifier/1.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalInputClassifierV1_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/input/common/1.0/Android.bp b/input/common/1.0/Android.bp index 07ced7ab05..ed0ab9875b 100644 --- a/input/common/1.0/Android.bp +++ b/input/common/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.input.common@1.0", root: "android.hardware", diff --git a/ir/1.0/Android.bp b/ir/1.0/Android.bp index 6a521f7d51..7ed742903c 100644 --- a/ir/1.0/Android.bp +++ b/ir/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.ir@1.0", root: "android.hardware", diff --git a/ir/1.0/default/Android.bp b/ir/1.0/default/Android.bp index 80e0f3c88c..9b99f13da6 100644 --- a/ir/1.0/default/Android.bp +++ b/ir/1.0/default/Android.bp @@ -12,6 +12,15 @@ // WITHOUT 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_shared { name: "android.hardware.ir@1.0-impl", defaults: ["hidl_defaults"], diff --git a/ir/1.0/vts/functional/Android.bp b/ir/1.0/vts/functional/Android.bp index 160129f8c5..983f2a44e1 100644 --- a/ir/1.0/vts/functional/Android.bp +++ b/ir/1.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalIrV1_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/keymaster/3.0/Android.bp b/keymaster/3.0/Android.bp index d0c7a7cd3e..12f6e3c00e 100644 --- a/keymaster/3.0/Android.bp +++ b/keymaster/3.0/Android.bp @@ -1,5 +1,14 @@ // 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.keymaster@3.0", root: "android.hardware", diff --git a/keymaster/3.0/default/Android.mk b/keymaster/3.0/default/Android.mk index 208cb66b2d..053ad671fb 100644 --- a/keymaster/3.0/default/Android.mk +++ b/keymaster/3.0/default/Android.mk @@ -2,6 +2,9 @@ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := android.hardware.keymaster@3.0-impl +LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 +LOCAL_LICENSE_CONDITIONS := notice +LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../../NOTICE LOCAL_PROPRIETARY_MODULE := true LOCAL_MODULE_RELATIVE_PATH := hw LOCAL_SRC_FILES := \ @@ -25,6 +28,9 @@ include $(CLEAR_VARS) LOCAL_MODULE_RELATIVE_PATH := hw LOCAL_PROPRIETARY_MODULE := true LOCAL_MODULE := android.hardware.keymaster@3.0-service +LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 +LOCAL_LICENSE_CONDITIONS := notice +LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../../NOTICE LOCAL_INIT_RC := android.hardware.keymaster@3.0-service.rc LOCAL_SRC_FILES := \ service.cpp diff --git a/keymaster/3.0/vts/functional/Android.bp b/keymaster/3.0/vts/functional/Android.bp index 35b9387132..e2ae80373f 100644 --- a/keymaster/3.0/vts/functional/Android.bp +++ b/keymaster/3.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalKeymasterV3_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/keymaster/4.0/Android.bp b/keymaster/4.0/Android.bp index 5774718601..8b4bc5b0da 100644 --- a/keymaster/4.0/Android.bp +++ b/keymaster/4.0/Android.bp @@ -1,5 +1,14 @@ // 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.keymaster@4.0", root: "android.hardware", diff --git a/keymaster/4.0/default/Android.bp b/keymaster/4.0/default/Android.bp index f9e39864c7..702a7160bd 100644 --- a/keymaster/4.0/default/Android.bp +++ b/keymaster/4.0/default/Android.bp @@ -14,6 +14,15 @@ // 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.keymaster@4.0-service", defaults: ["hidl_defaults"], diff --git a/keymaster/4.0/support/Android.bp b/keymaster/4.0/support/Android.bp index 9c5fbab735..efb64c3821 100644 --- a/keymaster/4.0/support/Android.bp +++ b/keymaster/4.0/support/Android.bp @@ -14,6 +14,15 @@ // 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 { name: "libkeymaster4support", vendor_available: true, diff --git a/keymaster/4.0/vts/functional/Android.bp b/keymaster/4.0/vts/functional/Android.bp index e706c689e6..a7be660c43 100644 --- a/keymaster/4.0/vts/functional/Android.bp +++ b/keymaster/4.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalKeymasterV4_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/keymaster/4.0/vts/performance/Android.bp b/keymaster/4.0/vts/performance/Android.bp index 9434bc9de7..d7342ad253 100644 --- a/keymaster/4.0/vts/performance/Android.bp +++ b/keymaster/4.0/vts/performance/Android.bp @@ -14,6 +14,15 @@ // 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_benchmark { name: "keymaster_benchmark", defaults: ["VtsHalTargetTestDefaults"], diff --git a/keymaster/4.1/Android.bp b/keymaster/4.1/Android.bp index 4e7e944564..e76afbdfa3 100644 --- a/keymaster/4.1/Android.bp +++ b/keymaster/4.1/Android.bp @@ -1,5 +1,14 @@ // 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.keymaster@4.1", root: "android.hardware", diff --git a/keymaster/4.1/default/Android.bp b/keymaster/4.1/default/Android.bp index 3442b181bb..3e2289a701 100644 --- a/keymaster/4.1/default/Android.bp +++ b/keymaster/4.1/default/Android.bp @@ -14,6 +14,15 @@ // 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.keymaster@4.1-service", defaults: ["hidl_defaults"], diff --git a/keymaster/4.1/support/Android.bp b/keymaster/4.1/support/Android.bp index bdd0ca89ae..fe0d07dd6c 100644 --- a/keymaster/4.1/support/Android.bp +++ b/keymaster/4.1/support/Android.bp @@ -14,6 +14,15 @@ // 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 { name: "libkeymaster4_1support", vendor_available: true, diff --git a/keymaster/4.1/vts/functional/Android.bp b/keymaster/4.1/vts/functional/Android.bp index 5ba05ea4ef..c650bec258 100644 --- a/keymaster/4.1/vts/functional/Android.bp +++ b/keymaster/4.1/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalKeymasterV4_1TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/keymaster/aidl/Android.bp b/keymaster/aidl/Android.bp index 56a3ca99e7..b7a261c596 100644 --- a/keymaster/aidl/Android.bp +++ b/keymaster/aidl/Android.bp @@ -1,3 +1,12 @@ +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.keymaster", vendor_available: true, diff --git a/light/2.0/Android.bp b/light/2.0/Android.bp index ae6d37c387..95eb5ae896 100644 --- a/light/2.0/Android.bp +++ b/light/2.0/Android.bp @@ -1,5 +1,14 @@ // 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.light@2.0", root: "android.hardware", diff --git a/light/2.0/default/Android.bp b/light/2.0/default/Android.bp index ed4882591a..2745f3d8be 100644 --- a/light/2.0/default/Android.bp +++ b/light/2.0/default/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"], +} + cc_library_shared { name: "android.hardware.light@2.0-impl", defaults: ["hidl_defaults"], diff --git a/light/2.0/vts/functional/Android.bp b/light/2.0/vts/functional/Android.bp index 06590c3a15..91fb8470dc 100644 --- a/light/2.0/vts/functional/Android.bp +++ b/light/2.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalLightV2_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], @@ -21,4 +30,3 @@ cc_test { static_libs: ["android.hardware.light@2.0"], test_suites: ["general-tests", "vts"], } - diff --git a/light/aidl/Android.bp b/light/aidl/Android.bp index fbcdb321aa..c8973f3c25 100644 --- a/light/aidl/Android.bp +++ b/light/aidl/Android.bp @@ -1,3 +1,12 @@ +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.light", vendor_available: true, diff --git a/light/aidl/default/Android.bp b/light/aidl/default/Android.bp index 4e43ba9c63..459b8e2248 100644 --- a/light/aidl/default/Android.bp +++ b/light/aidl/default/Android.bp @@ -1,3 +1,12 @@ +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.lights-service.example", relative_install_path: "hw", diff --git a/light/aidl/vts/functional/Android.bp b/light/aidl/vts/functional/Android.bp index 4c9356c9ca..c5a85620d2 100644 --- a/light/aidl/vts/functional/Android.bp +++ b/light/aidl/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalLightTargetTest", defaults: [ diff --git a/light/utils/Android.bp b/light/utils/Android.bp index 871f983532..927394e763 100644 --- a/light/utils/Android.bp +++ b/light/utils/Android.bp @@ -16,6 +16,15 @@ // Turns off the screen. // Canonical usage is for init (which can't talk to hals directly). +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: "blank_screen", init_rc: ["blank_screen.rc"], diff --git a/media/1.0/Android.bp b/media/1.0/Android.bp index 2dbe466692..6e823f6e4d 100644 --- a/media/1.0/Android.bp +++ b/media/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.media@1.0", root: "android.hardware", diff --git a/media/1.0/xml/Android.mk b/media/1.0/xml/Android.mk index bc44b9eeab..a7952880ab 100644 --- a/media/1.0/xml/Android.mk +++ b/media/1.0/xml/Android.mk @@ -6,9 +6,11 @@ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := media_profiles_V1_0.dtd +LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 +LOCAL_LICENSE_CONDITIONS := notice +LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../../NOTICE LOCAL_SRC_FILES := media_profiles.dtd LOCAL_MODULE_CLASS := ETC LOCAL_MODULE_PATH := $(TARGET_OUT_ETC) include $(BUILD_PREBUILT) - diff --git a/media/Android.bp b/media/Android.bp index 267c02bdf4..b70da2a3d0 100644 --- a/media/Android.bp +++ b/media/Android.bp @@ -14,6 +14,15 @@ // 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"], +} + filegroup { name: "media_omx_audio_res", path: "res", diff --git a/media/bufferpool/1.0/Android.bp b/media/bufferpool/1.0/Android.bp index 5dbbadd436..175b8a5ae7 100644 --- a/media/bufferpool/1.0/Android.bp +++ b/media/bufferpool/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.media.bufferpool@1.0", root: "android.hardware", diff --git a/media/bufferpool/2.0/Android.bp b/media/bufferpool/2.0/Android.bp index 6a82616b6f..01273c11d6 100644 --- a/media/bufferpool/2.0/Android.bp +++ b/media/bufferpool/2.0/Android.bp @@ -1,5 +1,14 @@ // 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.media.bufferpool@2.0", root: "android.hardware", diff --git a/media/c2/1.0/Android.bp b/media/c2/1.0/Android.bp index 089ce981eb..dc56fef7d8 100644 --- a/media/c2/1.0/Android.bp +++ b/media/c2/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.media.c2@1.0", root: "android.hardware", diff --git a/media/c2/1.1/Android.bp b/media/c2/1.1/Android.bp index a3d31dfaff..885a4c8845 100644 --- a/media/c2/1.1/Android.bp +++ b/media/c2/1.1/Android.bp @@ -1,5 +1,14 @@ // 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.media.c2@1.1", root: "android.hardware", diff --git a/media/omx/1.0/Android.bp b/media/omx/1.0/Android.bp index 5fe73abcf1..e33bab39dd 100644 --- a/media/omx/1.0/Android.bp +++ b/media/omx/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.media.omx@1.0", root: "android.hardware", diff --git a/media/omx/1.0/vts/functional/audio/Android.bp b/media/omx/1.0/vts/functional/audio/Android.bp index ec7357cb3d..a2733c92f1 100644 --- a/media/omx/1.0/vts/functional/audio/Android.bp +++ b/media/omx/1.0/vts/functional/audio/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalMediaOmxV1_0TargetAudioEncTest", stem: "vts_hal_media_omx_v1_0_audio_enc_test", diff --git a/media/omx/1.0/vts/functional/common/Android.bp b/media/omx/1.0/vts/functional/common/Android.bp index 89df4ff3fb..12b6fb292f 100644 --- a/media/omx/1.0/vts/functional/common/Android.bp +++ b/media/omx/1.0/vts/functional/common/Android.bp @@ -14,6 +14,15 @@ // 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: "VtsHalMediaOmxV1_0CommonUtil", srcs: ["media_hidl_test_common.cpp"], diff --git a/media/omx/1.0/vts/functional/component/Android.bp b/media/omx/1.0/vts/functional/component/Android.bp index 8fb627ad42..9d4d092a52 100644 --- a/media/omx/1.0/vts/functional/component/Android.bp +++ b/media/omx/1.0/vts/functional/component/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalMediaOmxV1_0TargetComponentTest", defaults: ["VtsHalMediaOmxV1_0Defaults"], diff --git a/media/omx/1.0/vts/functional/store/Android.bp b/media/omx/1.0/vts/functional/store/Android.bp index 28d12ffa5d..b34fff1b7b 100644 --- a/media/omx/1.0/vts/functional/store/Android.bp +++ b/media/omx/1.0/vts/functional/store/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalMediaOmxV1_0TargetStoreTest", defaults: ["VtsHalMediaOmxV1_0Defaults"], diff --git a/media/omx/1.0/vts/functional/video/Android.bp b/media/omx/1.0/vts/functional/video/Android.bp index b35c26c0f3..5454f16c67 100644 --- a/media/omx/1.0/vts/functional/video/Android.bp +++ b/media/omx/1.0/vts/functional/video/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalMediaOmxV1_0TargetVideoDecTest", stem: "vts_hal_media_omx_v1_0_video_dec_test", diff --git a/memtrack/1.0/Android.bp b/memtrack/1.0/Android.bp index a50195ee43..bf8db3f6f4 100644 --- a/memtrack/1.0/Android.bp +++ b/memtrack/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.memtrack@1.0", root: "android.hardware", diff --git a/memtrack/1.0/default/Android.bp b/memtrack/1.0/default/Android.bp index 8aa33eefcb..addffe3344 100644 --- a/memtrack/1.0/default/Android.bp +++ b/memtrack/1.0/default/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"], +} + cc_library_shared { name: "android.hardware.memtrack@1.0-impl", defaults: ["hidl_defaults"], diff --git a/memtrack/1.0/vts/functional/Android.bp b/memtrack/1.0/vts/functional/Android.bp index 445770ad9b..852cd156bc 100644 --- a/memtrack/1.0/vts/functional/Android.bp +++ b/memtrack/1.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalMemtrackV1_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/memtrack/aidl/Android.bp b/memtrack/aidl/Android.bp index fe4d01bad1..29fec2451f 100644 --- a/memtrack/aidl/Android.bp +++ b/memtrack/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.memtrack", vendor_available: true, diff --git a/memtrack/aidl/default/Android.bp b/memtrack/aidl/default/Android.bp index 8d97bfc703..7a7feea5bf 100644 --- a/memtrack/aidl/default/Android.bp +++ b/memtrack/aidl/default/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"], +} + cc_binary { name: "android.hardware.memtrack-service.example", relative_install_path: "hw", diff --git a/memtrack/aidl/vts/Android.bp b/memtrack/aidl/vts/Android.bp index eff2a563af..8614b478a6 100644 --- a/memtrack/aidl/vts/Android.bp +++ b/memtrack/aidl/vts/Android.bp @@ -1,3 +1,12 @@ +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalMemtrackTargetTest", defaults: [ diff --git a/neuralnetworks/1.0/Android.bp b/neuralnetworks/1.0/Android.bp index 20de9d56ec..7bc65ffbf1 100644 --- a/neuralnetworks/1.0/Android.bp +++ b/neuralnetworks/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.neuralnetworks@1.0", root: "android.hardware", diff --git a/neuralnetworks/1.0/utils/Android.bp b/neuralnetworks/1.0/utils/Android.bp index d03361724c..0ad9926df5 100644 --- a/neuralnetworks/1.0/utils/Android.bp +++ b/neuralnetworks/1.0/utils/Android.bp @@ -14,6 +14,15 @@ // 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_1_0", defaults: ["neuralnetworks_utils_defaults"], diff --git a/neuralnetworks/1.0/vts/functional/Android.bp b/neuralnetworks/1.0/vts/functional/Android.bp index d802911234..9a91560fea 100644 --- a/neuralnetworks/1.0/vts/functional/Android.bp +++ b/neuralnetworks/1.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // 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_defaults { name: "neuralnetworks_vts_functional_defaults", defaults: ["VtsHalTargetTestDefaults"], diff --git a/neuralnetworks/1.1/Android.bp b/neuralnetworks/1.1/Android.bp index 52d866f853..772e5e69a9 100644 --- a/neuralnetworks/1.1/Android.bp +++ b/neuralnetworks/1.1/Android.bp @@ -1,5 +1,14 @@ // 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.neuralnetworks@1.1", root: "android.hardware", diff --git a/neuralnetworks/1.1/utils/Android.bp b/neuralnetworks/1.1/utils/Android.bp index fe0c80ab45..d9e82d47b4 100644 --- a/neuralnetworks/1.1/utils/Android.bp +++ b/neuralnetworks/1.1/utils/Android.bp @@ -14,6 +14,15 @@ // 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_1_1", defaults: ["neuralnetworks_utils_defaults"], diff --git a/neuralnetworks/1.1/vts/functional/Android.bp b/neuralnetworks/1.1/vts/functional/Android.bp index 405548fe55..826ba9629c 100644 --- a/neuralnetworks/1.1/vts/functional/Android.bp +++ b/neuralnetworks/1.1/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalNeuralnetworksV1_1TargetTest", defaults: ["neuralnetworks_vts_functional_defaults"], diff --git a/neuralnetworks/1.2/Android.bp b/neuralnetworks/1.2/Android.bp index 9e1db1e8f8..2b83d3997c 100644 --- a/neuralnetworks/1.2/Android.bp +++ b/neuralnetworks/1.2/Android.bp @@ -1,5 +1,14 @@ // 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.neuralnetworks@1.2", root: "android.hardware", diff --git a/neuralnetworks/1.2/utils/Android.bp b/neuralnetworks/1.2/utils/Android.bp index 695905690e..2921141484 100644 --- a/neuralnetworks/1.2/utils/Android.bp +++ b/neuralnetworks/1.2/utils/Android.bp @@ -14,6 +14,15 @@ // 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_1_2", defaults: ["neuralnetworks_utils_defaults"], diff --git a/neuralnetworks/1.2/vts/functional/Android.bp b/neuralnetworks/1.2/vts/functional/Android.bp index 93edca6126..e313b47e1e 100644 --- a/neuralnetworks/1.2/vts/functional/Android.bp +++ b/neuralnetworks/1.2/vts/functional/Android.bp @@ -14,6 +14,15 @@ // 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: "VtsHalNeuralNetworksV1_2_utils", defaults: ["neuralnetworks_vts_functional_defaults"], diff --git a/neuralnetworks/1.3/Android.bp b/neuralnetworks/1.3/Android.bp index 3e02c909c7..aa8fc39e64 100644 --- a/neuralnetworks/1.3/Android.bp +++ b/neuralnetworks/1.3/Android.bp @@ -1,5 +1,14 @@ // 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.neuralnetworks@1.3", root: "android.hardware", diff --git a/neuralnetworks/1.3/utils/Android.bp b/neuralnetworks/1.3/utils/Android.bp index 41d9521173..2b1dcc40bb 100644 --- a/neuralnetworks/1.3/utils/Android.bp +++ b/neuralnetworks/1.3/utils/Android.bp @@ -14,6 +14,15 @@ // 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_1_3", defaults: ["neuralnetworks_utils_defaults"], diff --git a/neuralnetworks/1.3/vts/functional/Android.bp b/neuralnetworks/1.3/vts/functional/Android.bp index ee753bb951..f9752505a3 100644 --- a/neuralnetworks/1.3/vts/functional/Android.bp +++ b/neuralnetworks/1.3/vts/functional/Android.bp @@ -14,6 +14,15 @@ // 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: "VtsHalNeuralNetworksV1_3_utils", defaults: ["neuralnetworks_vts_functional_defaults"], diff --git a/neuralnetworks/aidl/Android.bp b/neuralnetworks/aidl/Android.bp index 0557e43a5a..b1860e2bd0 100644 --- a/neuralnetworks/aidl/Android.bp +++ b/neuralnetworks/aidl/Android.bp @@ -1,3 +1,12 @@ +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.neuralnetworks", vendor_available: true, diff --git a/neuralnetworks/aidl/utils/Android.bp b/neuralnetworks/aidl/utils/Android.bp index 147d401201..2673caef0e 100644 --- a/neuralnetworks/aidl/utils/Android.bp +++ b/neuralnetworks/aidl/utils/Android.bp @@ -14,6 +14,15 @@ // 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_aidl", defaults: ["neuralnetworks_utils_defaults"], diff --git a/neuralnetworks/aidl/vts/functional/Android.bp b/neuralnetworks/aidl/vts/functional/Android.bp index aa7afbf6a7..7804c2a765 100644 --- a/neuralnetworks/aidl/vts/functional/Android.bp +++ b/neuralnetworks/aidl/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalNeuralnetworksTargetTest", defaults: [ diff --git a/neuralnetworks/utils/common/Android.bp b/neuralnetworks/utils/common/Android.bp index 50295f1aad..6162fe8cbc 100644 --- a/neuralnetworks/utils/common/Android.bp +++ b/neuralnetworks/utils/common/Android.bp @@ -14,6 +14,15 @@ // 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_common", defaults: ["neuralnetworks_utils_defaults"], diff --git a/neuralnetworks/utils/service/Android.bp b/neuralnetworks/utils/service/Android.bp index 402598c7aa..9f8b9bbbfd 100644 --- a/neuralnetworks/utils/service/Android.bp +++ b/neuralnetworks/utils/service/Android.bp @@ -14,6 +14,15 @@ // 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_service", defaults: ["neuralnetworks_utils_defaults"], diff --git a/nfc/1.0/Android.bp b/nfc/1.0/Android.bp index 667922a4ac..55c8639dfd 100644 --- a/nfc/1.0/Android.bp +++ b/nfc/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.nfc@1.0", root: "android.hardware", diff --git a/nfc/1.0/default/Android.bp b/nfc/1.0/default/Android.bp index 9827edd454..a0cefeead2 100644 --- a/nfc/1.0/default/Android.bp +++ b/nfc/1.0/default/Android.bp @@ -1,3 +1,12 @@ +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.nfc@1.0-impl", defaults: ["hidl_defaults"], diff --git a/nfc/1.0/vts/functional/Android.bp b/nfc/1.0/vts/functional/Android.bp index 40ba22ee2f..0d3f0c95d6 100644 --- a/nfc/1.0/vts/functional/Android.bp +++ b/nfc/1.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalNfcV1_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/nfc/1.1/Android.bp b/nfc/1.1/Android.bp index a8976b06c4..a8463cf0fe 100644 --- a/nfc/1.1/Android.bp +++ b/nfc/1.1/Android.bp @@ -1,5 +1,14 @@ // 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.nfc@1.1", root: "android.hardware", diff --git a/nfc/1.1/vts/functional/Android.bp b/nfc/1.1/vts/functional/Android.bp index 1c18418514..4439531d9f 100644 --- a/nfc/1.1/vts/functional/Android.bp +++ b/nfc/1.1/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalNfcV1_1TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/nfc/1.2/Android.bp b/nfc/1.2/Android.bp index 514d5313aa..4831ab9133 100644 --- a/nfc/1.2/Android.bp +++ b/nfc/1.2/Android.bp @@ -1,5 +1,14 @@ // 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.nfc@1.2", root: "android.hardware", diff --git a/nfc/1.2/vts/functional/Android.bp b/nfc/1.2/vts/functional/Android.bp index 83e7a8e58e..ff7bd3a8d8 100644 --- a/nfc/1.2/vts/functional/Android.bp +++ b/nfc/1.2/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalNfcV1_2TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/oemlock/1.0/Android.bp b/oemlock/1.0/Android.bp index 8ab2911b8e..da536c4b49 100644 --- a/oemlock/1.0/Android.bp +++ b/oemlock/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.oemlock@1.0", root: "android.hardware", diff --git a/oemlock/1.0/vts/functional/Android.bp b/oemlock/1.0/vts/functional/Android.bp index 4dd92b53d6..f1b8d2f8ee 100644 --- a/oemlock/1.0/vts/functional/Android.bp +++ b/oemlock/1.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalOemLockV1_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/oemlock/aidl/Android.bp b/oemlock/aidl/Android.bp index bfc99e7b5f..439d43d760 100644 --- a/oemlock/aidl/Android.bp +++ b/oemlock/aidl/Android.bp @@ -1,3 +1,12 @@ +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.oemlock", vendor_available: true, diff --git a/oemlock/aidl/default/Android.bp b/oemlock/aidl/default/Android.bp index 464b0a3d60..84136fe701 100644 --- a/oemlock/aidl/default/Android.bp +++ b/oemlock/aidl/default/Android.bp @@ -14,6 +14,15 @@ // 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.oemlock-service.example", relative_install_path: "hw", diff --git a/oemlock/aidl/vts/Android.bp b/oemlock/aidl/vts/Android.bp index 18b53c2e7d..840d20aa50 100644 --- a/oemlock/aidl/vts/Android.bp +++ b/oemlock/aidl/vts/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalOemLockTargetTest", defaults: [ diff --git a/power/1.0/Android.bp b/power/1.0/Android.bp index 7381c709c9..68596ef64f 100644 --- a/power/1.0/Android.bp +++ b/power/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.power@1.0", root: "android.hardware", diff --git a/power/1.0/default/Android.bp b/power/1.0/default/Android.bp index 1d152ee59e..a64b15ca97 100644 --- a/power/1.0/default/Android.bp +++ b/power/1.0/default/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"], +} + cc_library_shared { name: "android.hardware.power@1.0-impl", defaults: ["hidl_defaults"], diff --git a/power/1.0/vts/functional/Android.bp b/power/1.0/vts/functional/Android.bp index 27b945651c..7d90a839e8 100644 --- a/power/1.0/vts/functional/Android.bp +++ b/power/1.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalPowerV1_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/power/1.1/Android.bp b/power/1.1/Android.bp index e026e7021f..259be4268e 100644 --- a/power/1.1/Android.bp +++ b/power/1.1/Android.bp @@ -1,5 +1,14 @@ // 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.power@1.1", root: "android.hardware", diff --git a/power/1.1/vts/functional/Android.bp b/power/1.1/vts/functional/Android.bp index 2860fdb10a..4270ab7bc8 100644 --- a/power/1.1/vts/functional/Android.bp +++ b/power/1.1/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalPowerV1_1TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/power/1.2/Android.bp b/power/1.2/Android.bp index ccf66dc1a6..aad89e047b 100644 --- a/power/1.2/Android.bp +++ b/power/1.2/Android.bp @@ -1,5 +1,14 @@ // 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.power@1.2", root: "android.hardware", diff --git a/power/1.2/vts/functional/Android.bp b/power/1.2/vts/functional/Android.bp index 5d1b2a4973..ab4b60166f 100644 --- a/power/1.2/vts/functional/Android.bp +++ b/power/1.2/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalPowerV1_2TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/power/1.3/Android.bp b/power/1.3/Android.bp index 15955e5db5..93467975ba 100644 --- a/power/1.3/Android.bp +++ b/power/1.3/Android.bp @@ -1,5 +1,14 @@ // 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.power@1.3", root: "android.hardware", diff --git a/power/1.3/vts/functional/Android.bp b/power/1.3/vts/functional/Android.bp index d8e1c050ad..c1186e3a67 100644 --- a/power/1.3/vts/functional/Android.bp +++ b/power/1.3/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalPowerV1_3TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/power/aidl/Android.bp b/power/aidl/Android.bp index 40086520fa..054fea5467 100644 --- a/power/aidl/Android.bp +++ b/power/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.power", vendor_available: true, diff --git a/power/aidl/default/Android.bp b/power/aidl/default/Android.bp index de04bcdcfc..5aa6893e67 100644 --- a/power/aidl/default/Android.bp +++ b/power/aidl/default/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"], +} + cc_binary { name: "android.hardware.power-service.example", relative_install_path: "hw", diff --git a/power/aidl/vts/Android.bp b/power/aidl/vts/Android.bp index 008073bdf8..1051b03823 100644 --- a/power/aidl/vts/Android.bp +++ b/power/aidl/vts/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"], +} + cc_test { name: "VtsHalPowerTargetTest", defaults: [ diff --git a/power/stats/1.0/Android.bp b/power/stats/1.0/Android.bp index 2a71490522..72da04e1d5 100644 --- a/power/stats/1.0/Android.bp +++ b/power/stats/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.power.stats@1.0", root: "android.hardware", diff --git a/power/stats/1.0/default/Android.bp b/power/stats/1.0/default/Android.bp index 0321da1354..f0bbef1dc9 100644 --- a/power/stats/1.0/default/Android.bp +++ b/power/stats/1.0/default/Android.bp @@ -11,6 +11,15 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and +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.power.stats@1.0-service.mock", relative_install_path: "hw", diff --git a/power/stats/1.0/vts/functional/Android.bp b/power/stats/1.0/vts/functional/Android.bp index d5f1da2d9d..5a448d845f 100644 --- a/power/stats/1.0/vts/functional/Android.bp +++ b/power/stats/1.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalPowerStatsV1_0TargetTest", defaults: [ diff --git a/power/stats/aidl/Android.bp b/power/stats/aidl/Android.bp index 1688b12d9a..f4955e2835 100644 --- a/power/stats/aidl/Android.bp +++ b/power/stats/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.power.stats", vendor_available: true, diff --git a/power/stats/aidl/default/Android.bp b/power/stats/aidl/default/Android.bp index 595ecd62d5..417dc97f0b 100644 --- a/power/stats/aidl/default/Android.bp +++ b/power/stats/aidl/default/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"], +} + cc_binary { name: "android.hardware.power.stats-service.example", relative_install_path: "hw", diff --git a/power/stats/aidl/vts/Android.bp b/power/stats/aidl/vts/Android.bp index 31fb990905..b556548ece 100644 --- a/power/stats/aidl/vts/Android.bp +++ b/power/stats/aidl/vts/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"], +} + cc_test { name: "VtsHalPowerStatsTargetTest", defaults: [ diff --git a/radio/1.0/Android.bp b/radio/1.0/Android.bp index f3cc2e0ad4..cd64bca66a 100644 --- a/radio/1.0/Android.bp +++ b/radio/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.radio@1.0", root: "android.hardware", diff --git a/radio/1.0/vts/functional/Android.bp b/radio/1.0/vts/functional/Android.bp index 13fc5425ac..386784299c 100644 --- a/radio/1.0/vts/functional/Android.bp +++ b/radio/1.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalRadioV1_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/radio/1.1/Android.bp b/radio/1.1/Android.bp index b325015824..abff05c382 100644 --- a/radio/1.1/Android.bp +++ b/radio/1.1/Android.bp @@ -1,5 +1,14 @@ // 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.radio@1.1", root: "android.hardware", diff --git a/radio/1.1/vts/functional/Android.bp b/radio/1.1/vts/functional/Android.bp index e1278b926a..c576fe89d4 100644 --- a/radio/1.1/vts/functional/Android.bp +++ b/radio/1.1/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalRadioV1_1TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/radio/1.2/Android.bp b/radio/1.2/Android.bp index 0a4caf11f5..924c77a9a6 100644 --- a/radio/1.2/Android.bp +++ b/radio/1.2/Android.bp @@ -1,5 +1,14 @@ // 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.radio@1.2", root: "android.hardware", diff --git a/radio/1.2/default/Android.bp b/radio/1.2/default/Android.bp index 74fcf11170..7b3dd1f8b3 100644 --- a/radio/1.2/default/Android.bp +++ b/radio/1.2/default/Android.bp @@ -1,3 +1,12 @@ +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.radio@1.2-radio-service", init_rc: ["android.hardware.radio@1.2-radio-service.rc"], diff --git a/radio/1.2/vts/functional/Android.bp b/radio/1.2/vts/functional/Android.bp index 56f2d5fb49..cb42cc7b51 100644 --- a/radio/1.2/vts/functional/Android.bp +++ b/radio/1.2/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalRadioV1_2TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/radio/1.3/Android.bp b/radio/1.3/Android.bp index 1c8e6c2242..8d24b2b683 100644 --- a/radio/1.3/Android.bp +++ b/radio/1.3/Android.bp @@ -1,5 +1,14 @@ // 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.radio@1.3", root: "android.hardware", diff --git a/radio/1.3/vts/functional/Android.bp b/radio/1.3/vts/functional/Android.bp index e32258f5d3..516e904e5c 100644 --- a/radio/1.3/vts/functional/Android.bp +++ b/radio/1.3/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalRadioV1_3TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/radio/1.4/Android.bp b/radio/1.4/Android.bp index 6c3a7d2563..385f2d324d 100644 --- a/radio/1.4/Android.bp +++ b/radio/1.4/Android.bp @@ -1,5 +1,14 @@ // 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.radio@1.4", root: "android.hardware", diff --git a/radio/1.4/vts/functional/Android.bp b/radio/1.4/vts/functional/Android.bp index 369b55b7a2..681e7165e9 100644 --- a/radio/1.4/vts/functional/Android.bp +++ b/radio/1.4/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalRadioV1_4TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/radio/1.5/Android.bp b/radio/1.5/Android.bp index 74de0fddd2..a36f296c2b 100644 --- a/radio/1.5/Android.bp +++ b/radio/1.5/Android.bp @@ -1,5 +1,14 @@ // 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.radio@1.5", root: "android.hardware", diff --git a/radio/1.5/vts/functional/Android.bp b/radio/1.5/vts/functional/Android.bp index cd54d274fd..c04edcf6e7 100644 --- a/radio/1.5/vts/functional/Android.bp +++ b/radio/1.5/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalRadioV1_5TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/radio/1.6/Android.bp b/radio/1.6/Android.bp index fc3191f630..4b79c0a43e 100644 --- a/radio/1.6/Android.bp +++ b/radio/1.6/Android.bp @@ -1,5 +1,14 @@ // 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.radio@1.6", root: "android.hardware", diff --git a/radio/1.6/vts/functional/Android.bp b/radio/1.6/vts/functional/Android.bp index db90f88618..dde718b32c 100644 --- a/radio/1.6/vts/functional/Android.bp +++ b/radio/1.6/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalRadioV1_6TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/radio/config/1.0/Android.bp b/radio/config/1.0/Android.bp index eea4c34b90..9e317b378e 100644 --- a/radio/config/1.0/Android.bp +++ b/radio/config/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.radio.config@1.0", root: "android.hardware", diff --git a/radio/config/1.0/default/Android.bp b/radio/config/1.0/default/Android.bp index a0f4214fa8..e221ceb9fc 100644 --- a/radio/config/1.0/default/Android.bp +++ b/radio/config/1.0/default/Android.bp @@ -1,3 +1,12 @@ +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.radio.config@1.0-service", init_rc: ["android.hardware.radio.config@1.0-service.rc"], diff --git a/radio/config/1.0/vts/functional/Android.bp b/radio/config/1.0/vts/functional/Android.bp index 330209eed0..ef11d7e73f 100644 --- a/radio/config/1.0/vts/functional/Android.bp +++ b/radio/config/1.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalRadioConfigV1_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/radio/config/1.1/Android.bp b/radio/config/1.1/Android.bp index 69d9a836fc..b1705f98ec 100644 --- a/radio/config/1.1/Android.bp +++ b/radio/config/1.1/Android.bp @@ -1,5 +1,14 @@ // 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.radio.config@1.1", root: "android.hardware", diff --git a/radio/config/1.1/vts/functional/Android.bp b/radio/config/1.1/vts/functional/Android.bp index f60331d1c3..3635f8315a 100644 --- a/radio/config/1.1/vts/functional/Android.bp +++ b/radio/config/1.1/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalRadioConfigV1_1TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/radio/config/1.2/Android.bp b/radio/config/1.2/Android.bp index f751868af3..3327af4d86 100644 --- a/radio/config/1.2/Android.bp +++ b/radio/config/1.2/Android.bp @@ -1,5 +1,14 @@ // 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.radio.config@1.2", root: "android.hardware", diff --git a/radio/config/1.2/vts/functional/Android.bp b/radio/config/1.2/vts/functional/Android.bp index fdc83b73fc..e7cc155378 100644 --- a/radio/config/1.2/vts/functional/Android.bp +++ b/radio/config/1.2/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalRadioConfigV1_2TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/radio/config/1.3/Android.bp b/radio/config/1.3/Android.bp index ace0de96f9..cc5944df44 100644 --- a/radio/config/1.3/Android.bp +++ b/radio/config/1.3/Android.bp @@ -1,5 +1,14 @@ // 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.radio.config@1.3", root: "android.hardware", diff --git a/radio/config/1.3/vts/functional/Android.bp b/radio/config/1.3/vts/functional/Android.bp index abd081f9df..aa3522dead 100644 --- a/radio/config/1.3/vts/functional/Android.bp +++ b/radio/config/1.3/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalRadioConfigV1_3TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/radio/deprecated/1.0/Android.bp b/radio/deprecated/1.0/Android.bp index 1a7cb940ae..53f6da51b9 100644 --- a/radio/deprecated/1.0/Android.bp +++ b/radio/deprecated/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.radio.deprecated@1.0", root: "android.hardware", diff --git a/rebootescrow/aidl/Android.bp b/rebootescrow/aidl/Android.bp index 75faa1a65b..c764f86e9f 100644 --- a/rebootescrow/aidl/Android.bp +++ b/rebootescrow/aidl/Android.bp @@ -1,3 +1,12 @@ +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.rebootescrow", vendor_available: true, diff --git a/rebootescrow/aidl/default/Android.bp b/rebootescrow/aidl/default/Android.bp index e6a4e7ab4f..b9fb2a9665 100644 --- a/rebootescrow/aidl/default/Android.bp +++ b/rebootescrow/aidl/default/Android.bp @@ -14,6 +14,15 @@ // 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: "librebootescrowdefaultimpl", vendor: true, diff --git a/rebootescrow/aidl/vts/functional/Android.bp b/rebootescrow/aidl/vts/functional/Android.bp index abd4937f62..76b678467e 100644 --- a/rebootescrow/aidl/vts/functional/Android.bp +++ b/rebootescrow/aidl/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalRebootEscrowTargetTest", defaults: [ diff --git a/renderscript/1.0/Android.bp b/renderscript/1.0/Android.bp index d3b5abed9a..1f2ac15f8f 100644 --- a/renderscript/1.0/Android.bp +++ b/renderscript/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.renderscript@1.0", root: "android.hardware", diff --git a/renderscript/1.0/default/Android.bp b/renderscript/1.0/default/Android.bp index 4fa85c63bf..c68e370a1e 100644 --- a/renderscript/1.0/default/Android.bp +++ b/renderscript/1.0/default/Android.bp @@ -1,3 +1,12 @@ +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.renderscript@1.0-impl", defaults: ["hidl_defaults"], diff --git a/renderscript/1.0/vts/functional/Android.bp b/renderscript/1.0/vts/functional/Android.bp index 327c09edb5..4b665b11f2 100644 --- a/renderscript/1.0/vts/functional/Android.bp +++ b/renderscript/1.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalRenderscriptV1_0TargetTest", srcs: [ diff --git a/secure_element/1.0/Android.bp b/secure_element/1.0/Android.bp index a32b9d1401..520d3a37df 100644 --- a/secure_element/1.0/Android.bp +++ b/secure_element/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.secure_element@1.0", root: "android.hardware", diff --git a/secure_element/1.0/vts/functional/Android.bp b/secure_element/1.0/vts/functional/Android.bp index d428c6f771..735d7c9ac5 100644 --- a/secure_element/1.0/vts/functional/Android.bp +++ b/secure_element/1.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalSecureElementV1_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/secure_element/1.1/Android.bp b/secure_element/1.1/Android.bp index 08e6c8855e..3874fda5ac 100644 --- a/secure_element/1.1/Android.bp +++ b/secure_element/1.1/Android.bp @@ -1,5 +1,14 @@ // 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.secure_element@1.1", root: "android.hardware", diff --git a/secure_element/1.1/vts/functional/Android.bp b/secure_element/1.1/vts/functional/Android.bp index 200aed829d..d63e7c469d 100644 --- a/secure_element/1.1/vts/functional/Android.bp +++ b/secure_element/1.1/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalSecureElementV1_1TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/secure_element/1.2/Android.bp b/secure_element/1.2/Android.bp index 03df5f9d68..6de92dfa47 100644 --- a/secure_element/1.2/Android.bp +++ b/secure_element/1.2/Android.bp @@ -1,5 +1,14 @@ // 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.secure_element@1.2", root: "android.hardware", diff --git a/secure_element/1.2/vts/functional/Android.bp b/secure_element/1.2/vts/functional/Android.bp index 9a7ca45b54..63a0a198fe 100644 --- a/secure_element/1.2/vts/functional/Android.bp +++ b/secure_element/1.2/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalSecureElementV1_2TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/security/keymint/aidl/Android.bp b/security/keymint/aidl/Android.bp index 5652827a92..54cb4b8ebb 100644 --- a/security/keymint/aidl/Android.bp +++ b/security/keymint/aidl/Android.bp @@ -1,3 +1,12 @@ +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.security.keymint", vendor_available: true, diff --git a/security/keymint/aidl/default/Android.bp b/security/keymint/aidl/default/Android.bp index e160548931..63b91fefdf 100644 --- a/security/keymint/aidl/default/Android.bp +++ b/security/keymint/aidl/default/Android.bp @@ -1,3 +1,12 @@ +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.security.keymint-service", relative_install_path: "hw", diff --git a/security/keymint/aidl/vts/functional/Android.bp b/security/keymint/aidl/vts/functional/Android.bp index 24fe61641c..991d77a43b 100644 --- a/security/keymint/aidl/vts/functional/Android.bp +++ b/security/keymint/aidl/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsAidlKeyMintTargetTest", defaults: [ diff --git a/security/keymint/aidl/vts/performance/Android.bp b/security/keymint/aidl/vts/performance/Android.bp index 03240c3459..79ed0d5442 100644 --- a/security/keymint/aidl/vts/performance/Android.bp +++ b/security/keymint/aidl/vts/performance/Android.bp @@ -14,6 +14,15 @@ // 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_benchmark { name: "VtsAidlKeyMintBenchmarkTest", defaults: [ diff --git a/security/keymint/support/Android.bp b/security/keymint/support/Android.bp index 02558745d5..fe04ede49f 100644 --- a/security/keymint/support/Android.bp +++ b/security/keymint/support/Android.bp @@ -14,6 +14,15 @@ // 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 { name: "libkeymint_support", cflags: [ diff --git a/security/secureclock/aidl/Android.bp b/security/secureclock/aidl/Android.bp index 5a6d7ae538..c8e5c025ff 100644 --- a/security/secureclock/aidl/Android.bp +++ b/security/secureclock/aidl/Android.bp @@ -1,3 +1,12 @@ +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.security.secureclock", vendor_available: true, diff --git a/security/secureclock/aidl/vts/functional/Android.bp b/security/secureclock/aidl/vts/functional/Android.bp index 1619eab235..6dfa4175c7 100644 --- a/security/secureclock/aidl/vts/functional/Android.bp +++ b/security/secureclock/aidl/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsAidlSecureClockTargetTest", defaults: [ diff --git a/security/sharedsecret/aidl/Android.bp b/security/sharedsecret/aidl/Android.bp index ab441106f7..16830598f5 100644 --- a/security/sharedsecret/aidl/Android.bp +++ b/security/sharedsecret/aidl/Android.bp @@ -1,3 +1,12 @@ +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.security.sharedsecret", vendor_available: true, diff --git a/security/sharedsecret/aidl/vts/functional/Android.bp b/security/sharedsecret/aidl/vts/functional/Android.bp index 76bf7ff762..1bc5bebc91 100644 --- a/security/sharedsecret/aidl/vts/functional/Android.bp +++ b/security/sharedsecret/aidl/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsAidlSharedSecretTargetTest", defaults: [ diff --git a/sensors/1.0/Android.bp b/sensors/1.0/Android.bp index 109367106a..c81ee6dbc9 100644 --- a/sensors/1.0/Android.bp +++ b/sensors/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.sensors@1.0", root: "android.hardware", diff --git a/sensors/1.0/default/Android.bp b/sensors/1.0/default/Android.bp index d5c1b23d2e..2e4e1b015c 100644 --- a/sensors/1.0/default/Android.bp +++ b/sensors/1.0/default/Android.bp @@ -1,3 +1,12 @@ +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.sensors@1.0-impl", defaults: ["hidl_defaults"], diff --git a/sensors/1.0/vts/functional/Android.bp b/sensors/1.0/vts/functional/Android.bp index c77733bba2..9a92fb3150 100644 --- a/sensors/1.0/vts/functional/Android.bp +++ b/sensors/1.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalSensorsV1_0TargetTest", cflags: ["-DLOG_TAG=\"sensors_hidl_hal_test\""], diff --git a/sensors/2.0/Android.bp b/sensors/2.0/Android.bp index d71f07b355..5a22b1f308 100644 --- a/sensors/2.0/Android.bp +++ b/sensors/2.0/Android.bp @@ -1,5 +1,14 @@ // 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.sensors@2.0", root: "android.hardware", diff --git a/sensors/2.0/default/Android.bp b/sensors/2.0/default/Android.bp index bb383273a6..04a490e44e 100644 --- a/sensors/2.0/default/Android.bp +++ b/sensors/2.0/default/Android.bp @@ -13,6 +13,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"], +} + cc_binary { name: "android.hardware.sensors@2.0-service.mock", defaults: ["hidl_defaults"], diff --git a/sensors/2.0/multihal/Android.bp b/sensors/2.0/multihal/Android.bp index bf51fcdbbc..ae5c3422a9 100644 --- a/sensors/2.0/multihal/Android.bp +++ b/sensors/2.0/multihal/Android.bp @@ -13,6 +13,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"], +} + cc_binary { name: "android.hardware.sensors@2.0-service.multihal", defaults: [ diff --git a/sensors/2.0/vts/functional/Android.bp b/sensors/2.0/vts/functional/Android.bp index 83ebc6b807..cf7c9fae75 100644 --- a/sensors/2.0/vts/functional/Android.bp +++ b/sensors/2.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalSensorsV2_0TargetTest", cflags: ["-DLOG_TAG=\"sensors_hidl_hal_test\""], diff --git a/sensors/2.1/Android.bp b/sensors/2.1/Android.bp index 9ba3248085..5dd511af73 100644 --- a/sensors/2.1/Android.bp +++ b/sensors/2.1/Android.bp @@ -1,5 +1,14 @@ // 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.sensors@2.1", root: "android.hardware", diff --git a/sensors/2.1/default/Android.bp b/sensors/2.1/default/Android.bp index 27b439d422..0be81e11d7 100644 --- a/sensors/2.1/default/Android.bp +++ b/sensors/2.1/default/Android.bp @@ -13,6 +13,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"], +} + cc_binary { name: "android.hardware.sensors@2.1-service.mock", defaults: ["hidl_defaults"], diff --git a/sensors/2.1/multihal/Android.bp b/sensors/2.1/multihal/Android.bp index 6a7cac9f25..3846e19e05 100644 --- a/sensors/2.1/multihal/Android.bp +++ b/sensors/2.1/multihal/Android.bp @@ -13,6 +13,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"], +} + cc_binary { name: "android.hardware.sensors@2.1-service.multihal", defaults: [ diff --git a/sensors/2.1/vts/functional/Android.bp b/sensors/2.1/vts/functional/Android.bp index d257993329..3659e11ffc 100644 --- a/sensors/2.1/vts/functional/Android.bp +++ b/sensors/2.1/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalSensorsV2_1TargetTest", cflags: [ diff --git a/sensors/common/default/2.X/Android.bp b/sensors/common/default/2.X/Android.bp index 8b0d52f06a..82c942f701 100644 --- a/sensors/common/default/2.X/Android.bp +++ b/sensors/common/default/2.X/Android.bp @@ -13,6 +13,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"], +} + cc_library_static { name: "android.hardware.sensors@2.X-shared-impl", vendor: true, diff --git a/sensors/common/default/2.X/multihal/Android.bp b/sensors/common/default/2.X/multihal/Android.bp index c80c47a4bf..b0ad934826 100644 --- a/sensors/common/default/2.X/multihal/Android.bp +++ b/sensors/common/default/2.X/multihal/Android.bp @@ -13,6 +13,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"], +} + cc_defaults { name: "android.hardware.sensors@2.X-multihal-defaults", header_libs: [ diff --git a/sensors/common/default/2.X/multihal/tests/Android.bp b/sensors/common/default/2.X/multihal/tests/Android.bp index 1b60f4b505..d8e7ce6a5c 100644 --- a/sensors/common/default/2.X/multihal/tests/Android.bp +++ b/sensors/common/default/2.X/multihal/tests/Android.bp @@ -13,6 +13,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"], +} + cc_defaults { name: "android.hardware.sensors@2.X-fakesubhal-defaults", srcs: [ diff --git a/sensors/common/utils/Android.bp b/sensors/common/utils/Android.bp index aec6c4b58b..97e857c680 100644 --- a/sensors/common/utils/Android.bp +++ b/sensors/common/utils/Android.bp @@ -13,6 +13,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"], +} + cc_library_headers { name: "android.hardware.sensors@2.X-shared-utils", vendor_available: true, diff --git a/sensors/common/vts/2_X/Android.bp b/sensors/common/vts/2_X/Android.bp index e5eceb5ed5..4cf6a08382 100644 --- a/sensors/common/vts/2_X/Android.bp +++ b/sensors/common/vts/2_X/Android.bp @@ -14,6 +14,15 @@ // 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_defaults { name: "VtsHalSensorsV2_XTargetTest-defaults", cflags: ["-DLOG_TAG=\"sensors_hidl_hal_test\""], diff --git a/sensors/common/vts/utils/Android.bp b/sensors/common/vts/utils/Android.bp index baaed6cc20..44bed6e002 100644 --- a/sensors/common/vts/utils/Android.bp +++ b/sensors/common/vts/utils/Android.bp @@ -14,6 +14,15 @@ // 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: "VtsHalSensorsTargetTestUtils", defaults: ["VtsHalTargetTestDefaults"], diff --git a/soundtrigger/2.0/Android.bp b/soundtrigger/2.0/Android.bp index 07c05bc656..996105cc8f 100644 --- a/soundtrigger/2.0/Android.bp +++ b/soundtrigger/2.0/Android.bp @@ -1,5 +1,14 @@ // 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.soundtrigger@2.0", root: "android.hardware", diff --git a/soundtrigger/2.0/default/Android.bp b/soundtrigger/2.0/default/Android.bp index 1f9ae45ed1..8236e3012e 100644 --- a/soundtrigger/2.0/default/Android.bp +++ b/soundtrigger/2.0/default/Android.bp @@ -13,6 +13,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"], +} + cc_library_shared { name: "android.hardware.soundtrigger@2.0-core", defaults: ["hidl_defaults"], diff --git a/soundtrigger/2.0/default/Android.mk b/soundtrigger/2.0/default/Android.mk index 835a020800..17e44403c0 100644 --- a/soundtrigger/2.0/default/Android.mk +++ b/soundtrigger/2.0/default/Android.mk @@ -18,6 +18,9 @@ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := android.hardware.soundtrigger@2.0-impl +LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 +LOCAL_LICENSE_CONDITIONS := notice +LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../../NOTICE LOCAL_VENDOR_MODULE := true LOCAL_MODULE_RELATIVE_PATH := hw LOCAL_SRC_FILES := \ diff --git a/soundtrigger/2.0/vts/functional/Android.bp b/soundtrigger/2.0/vts/functional/Android.bp index 86697bda3d..403fa9b1e0 100644 --- a/soundtrigger/2.0/vts/functional/Android.bp +++ b/soundtrigger/2.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalSoundtriggerV2_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/soundtrigger/2.1/Android.bp b/soundtrigger/2.1/Android.bp index 024e0f6b5a..7f6503c81f 100644 --- a/soundtrigger/2.1/Android.bp +++ b/soundtrigger/2.1/Android.bp @@ -1,5 +1,14 @@ // 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.soundtrigger@2.1", root: "android.hardware", diff --git a/soundtrigger/2.1/default/Android.mk b/soundtrigger/2.1/default/Android.mk index b8d0407e4e..602f5a7130 100644 --- a/soundtrigger/2.1/default/Android.mk +++ b/soundtrigger/2.1/default/Android.mk @@ -18,6 +18,9 @@ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := android.hardware.soundtrigger@2.1-impl +LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 +LOCAL_LICENSE_CONDITIONS := notice +LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../../NOTICE LOCAL_VENDOR_MODULE := true LOCAL_MODULE_RELATIVE_PATH := hw LOCAL_SRC_FILES := \ diff --git a/soundtrigger/2.1/vts/functional/Android.bp b/soundtrigger/2.1/vts/functional/Android.bp index 9de913b641..b0133509a0 100644 --- a/soundtrigger/2.1/vts/functional/Android.bp +++ b/soundtrigger/2.1/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalSoundtriggerV2_1TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/soundtrigger/2.2/Android.bp b/soundtrigger/2.2/Android.bp index dbf4f8bacd..f126eed116 100644 --- a/soundtrigger/2.2/Android.bp +++ b/soundtrigger/2.2/Android.bp @@ -1,5 +1,14 @@ // 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.soundtrigger@2.2", root: "android.hardware", diff --git a/soundtrigger/2.2/default/Android.bp b/soundtrigger/2.2/default/Android.bp index db37c5b36a..768b9d6111 100644 --- a/soundtrigger/2.2/default/Android.bp +++ b/soundtrigger/2.2/default/Android.bp @@ -13,6 +13,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"], +} + cc_library_shared { name: "android.hardware.soundtrigger@2.2-impl", relative_install_path: "hw", diff --git a/soundtrigger/2.2/vts/functional/Android.bp b/soundtrigger/2.2/vts/functional/Android.bp index b7967d966f..faf6d58155 100644 --- a/soundtrigger/2.2/vts/functional/Android.bp +++ b/soundtrigger/2.2/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalSoundtriggerV2_2TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/soundtrigger/2.3/Android.bp b/soundtrigger/2.3/Android.bp index 480df4daa4..e65c0ad953 100644 --- a/soundtrigger/2.3/Android.bp +++ b/soundtrigger/2.3/Android.bp @@ -1,5 +1,14 @@ // 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.soundtrigger@2.3", root: "android.hardware", diff --git a/soundtrigger/2.3/default/Android.bp b/soundtrigger/2.3/default/Android.bp index be2c8b0961..acb7ffebb4 100644 --- a/soundtrigger/2.3/default/Android.bp +++ b/soundtrigger/2.3/default/Android.bp @@ -13,6 +13,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"], +} + cc_library_shared { name: "android.hardware.soundtrigger@2.3-impl", relative_install_path: "hw", diff --git a/soundtrigger/2.3/vts/functional/Android.bp b/soundtrigger/2.3/vts/functional/Android.bp index 2c1b9e594e..e613db5093 100644 --- a/soundtrigger/2.3/vts/functional/Android.bp +++ b/soundtrigger/2.3/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalSoundtriggerV2_3TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/tests/bar/1.0/Android.bp b/tests/bar/1.0/Android.bp index 0aeccd6a39..ed0507859f 100644 --- a/tests/bar/1.0/Android.bp +++ b/tests/bar/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.tests.bar@1.0", root: "android.hardware", diff --git a/tests/bar/1.0/default/Android.bp b/tests/bar/1.0/default/Android.bp index 8e3d072318..fd0cf0b145 100644 --- a/tests/bar/1.0/default/Android.bp +++ b/tests/bar/1.0/default/Android.bp @@ -1,5 +1,14 @@ +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 { name: "android.hardware.tests.bar@1.0-impl", defaults: ["hidl_defaults"], diff --git a/tests/baz/1.0/Android.bp b/tests/baz/1.0/Android.bp index ed18876561..0594f295cf 100644 --- a/tests/baz/1.0/Android.bp +++ b/tests/baz/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.tests.baz@1.0", root: "android.hardware", diff --git a/tests/baz/1.0/default/Android.bp b/tests/baz/1.0/default/Android.bp index 4096d47576..64ccb14b36 100644 --- a/tests/baz/1.0/default/Android.bp +++ b/tests/baz/1.0/default/Android.bp @@ -1,3 +1,12 @@ +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 { name: "android.hardware.tests.baz@1.0-impl", defaults: ["hidl_defaults"], diff --git a/tests/expression/1.0/Android.bp b/tests/expression/1.0/Android.bp index 4bc3848c9a..8942e76756 100644 --- a/tests/expression/1.0/Android.bp +++ b/tests/expression/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.tests.expression@1.0", root: "android.hardware", diff --git a/tests/extension/light/2.0/Android.bp b/tests/extension/light/2.0/Android.bp index e19a9137c1..9e38ec9425 100644 --- a/tests/extension/light/2.0/Android.bp +++ b/tests/extension/light/2.0/Android.bp @@ -1,5 +1,14 @@ // 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.tests.extension.light@2.0", root: "android.hardware", diff --git a/tests/extension/light/2.0/default/Android.bp b/tests/extension/light/2.0/default/Android.bp index d8d8dd5e40..7a85da6b62 100644 --- a/tests/extension/light/2.0/default/Android.bp +++ b/tests/extension/light/2.0/default/Android.bp @@ -14,6 +14,15 @@ // 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.tests.extension.light@2.0-service", defaults: ["hidl_defaults"], diff --git a/tests/extension/vibrator/aidl/Android.bp b/tests/extension/vibrator/aidl/Android.bp index c64779cb4c..4d544e11fb 100644 --- a/tests/extension/vibrator/aidl/Android.bp +++ b/tests/extension/vibrator/aidl/Android.bp @@ -1,3 +1,12 @@ +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 { // This is an example test interface showing how to add functionality // with setExtension/getExtension diff --git a/tests/extension/vibrator/aidl/client/Android.bp b/tests/extension/vibrator/aidl/client/Android.bp index 108d000970..fb34d7e771 100644 --- a/tests/extension/vibrator/aidl/client/Android.bp +++ b/tests/extension/vibrator/aidl/client/Android.bp @@ -2,6 +2,15 @@ // context. All this code would look the same if it was running in system // server for example. +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "android.hardware.tests.extension.vibrator-client", srcs: [ diff --git a/tests/extension/vibrator/aidl/default/Android.bp b/tests/extension/vibrator/aidl/default/Android.bp index 2486588225..a200292330 100644 --- a/tests/extension/vibrator/aidl/default/Android.bp +++ b/tests/extension/vibrator/aidl/default/Android.bp @@ -1,3 +1,12 @@ +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.tests.extension.vibrator-service.example", relative_install_path: "hw", diff --git a/tests/foo/1.0/Android.bp b/tests/foo/1.0/Android.bp index 2f97fcaf78..1c6ec5887f 100644 --- a/tests/foo/1.0/Android.bp +++ b/tests/foo/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.tests.foo@1.0", root: "android.hardware", diff --git a/tests/foo/1.0/default/Android.bp b/tests/foo/1.0/default/Android.bp index 48d6894dd0..48f5b75006 100644 --- a/tests/foo/1.0/default/Android.bp +++ b/tests/foo/1.0/default/Android.bp @@ -1,5 +1,14 @@ +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 { name: "android.hardware.tests.foo@1.0-impl", defaults: ["hidl_defaults"], diff --git a/tests/foo/1.0/default/lib/Android.bp b/tests/foo/1.0/default/lib/Android.bp index ba2081e779..818e1c3127 100644 --- a/tests/foo/1.0/default/lib/Android.bp +++ b/tests/foo/1.0/default/lib/Android.bp @@ -1,3 +1,12 @@ +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 { name: "libfootest", defaults: ["hidl_defaults"], diff --git a/tests/hash/1.0/Android.bp b/tests/hash/1.0/Android.bp index 109557629e..4d250bf2cd 100644 --- a/tests/hash/1.0/Android.bp +++ b/tests/hash/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.tests.hash@1.0", root: "android.hardware", diff --git a/tests/hash/1.0/default/Android.bp b/tests/hash/1.0/default/Android.bp index 410b759e38..c1e0d9b5c9 100644 --- a/tests/hash/1.0/default/Android.bp +++ b/tests/hash/1.0/default/Android.bp @@ -1,3 +1,12 @@ +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 { name: "android.hardware.tests.hash@1.0-impl", defaults: ["hidl_defaults"], diff --git a/tests/inheritance/1.0/Android.bp b/tests/inheritance/1.0/Android.bp index 0042b57b70..574f8dd599 100644 --- a/tests/inheritance/1.0/Android.bp +++ b/tests/inheritance/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.tests.inheritance@1.0", root: "android.hardware", diff --git a/tests/inheritance/1.0/default/Android.bp b/tests/inheritance/1.0/default/Android.bp index 4a0c876a3a..ff1cf538ac 100644 --- a/tests/inheritance/1.0/default/Android.bp +++ b/tests/inheritance/1.0/default/Android.bp @@ -1,5 +1,14 @@ +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 { name: "android.hardware.tests.inheritance@1.0-impl", defaults: ["hidl_defaults"], diff --git a/tests/lazy/1.0/Android.bp b/tests/lazy/1.0/Android.bp index d2f81756e3..3ee307a0fd 100644 --- a/tests/lazy/1.0/Android.bp +++ b/tests/lazy/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.tests.lazy@1.0", root: "android.hardware", diff --git a/tests/lazy/1.1/Android.bp b/tests/lazy/1.1/Android.bp index ccedd8d576..9429a23e87 100644 --- a/tests/lazy/1.1/Android.bp +++ b/tests/lazy/1.1/Android.bp @@ -1,5 +1,14 @@ // 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.tests.lazy@1.1", root: "android.hardware", diff --git a/tests/libhwbinder/1.0/Android.bp b/tests/libhwbinder/1.0/Android.bp index 13af77cc90..8f45656706 100644 --- a/tests/libhwbinder/1.0/Android.bp +++ b/tests/libhwbinder/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.tests.libhwbinder@1.0", root: "android.hardware", diff --git a/tests/libhwbinder/1.0/default/Android.bp b/tests/libhwbinder/1.0/default/Android.bp index 3bf08ed87c..1f8035006a 100644 --- a/tests/libhwbinder/1.0/default/Android.bp +++ b/tests/libhwbinder/1.0/default/Android.bp @@ -1,3 +1,12 @@ +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 { name: "android.hardware.tests.libhwbinder@1.0-impl.test", defaults: ["hidl_defaults"], diff --git a/tests/libhwbinder/aidl/Android.bp b/tests/libhwbinder/aidl/Android.bp index c9e09f7516..2b83f2b725 100644 --- a/tests/libhwbinder/aidl/Android.bp +++ b/tests/libhwbinder/aidl/Android.bp @@ -1,3 +1,12 @@ +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 { name: "android.hardware.tests.libbinder", defaults: ["hidl_defaults"], diff --git a/tests/memory/1.0/Android.bp b/tests/memory/1.0/Android.bp index 6612e31164..4bb724bcaf 100644 --- a/tests/memory/1.0/Android.bp +++ b/tests/memory/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.tests.memory@1.0", root: "android.hardware", diff --git a/tests/memory/1.0/default/Android.bp b/tests/memory/1.0/default/Android.bp index 0293953b9b..71d1b3d2ba 100644 --- a/tests/memory/1.0/default/Android.bp +++ b/tests/memory/1.0/default/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"], +} + cc_library { name: "android.hardware.tests.memory@1.0-impl", defaults: ["hidl_defaults"], @@ -32,4 +41,4 @@ cc_library { // These are static libs only for testing purposes and portability. Shared // libs should be used on device. static_libs: ["android.hardware.tests.memory@1.0"], -} \ No newline at end of file +} diff --git a/tests/memory/2.0/Android.bp b/tests/memory/2.0/Android.bp index d24bd21312..6eace8d69e 100644 --- a/tests/memory/2.0/Android.bp +++ b/tests/memory/2.0/Android.bp @@ -1,5 +1,14 @@ // 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.tests.memory@2.0", root: "android.hardware", diff --git a/tests/msgq/1.0/Android.bp b/tests/msgq/1.0/Android.bp index eea1ce6029..8dd38702b1 100644 --- a/tests/msgq/1.0/Android.bp +++ b/tests/msgq/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.tests.msgq@1.0", root: "android.hardware", diff --git a/tests/msgq/1.0/default/Android.bp b/tests/msgq/1.0/default/Android.bp index a0d6f31fd9..5f116e7371 100644 --- a/tests/msgq/1.0/default/Android.bp +++ b/tests/msgq/1.0/default/Android.bp @@ -13,6 +13,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"], +} + cc_library { name: "android.hardware.tests.msgq@1.0-impl", defaults: ["hidl_defaults"], diff --git a/tests/multithread/1.0/Android.bp b/tests/multithread/1.0/Android.bp index ed3a687777..62bffb3d57 100644 --- a/tests/multithread/1.0/Android.bp +++ b/tests/multithread/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.tests.multithread@1.0", root: "android.hardware", diff --git a/tests/multithread/1.0/default/Android.bp b/tests/multithread/1.0/default/Android.bp index ff899386e3..80ab55ec3b 100644 --- a/tests/multithread/1.0/default/Android.bp +++ b/tests/multithread/1.0/default/Android.bp @@ -1,3 +1,12 @@ +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 { name: "android.hardware.tests.multithread@1.0-impl", defaults: ["hidl_defaults"], diff --git a/tests/safeunion/1.0/Android.bp b/tests/safeunion/1.0/Android.bp index f1ec267768..ca1edfc6ea 100644 --- a/tests/safeunion/1.0/Android.bp +++ b/tests/safeunion/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.tests.safeunion@1.0", root: "android.hardware", diff --git a/tests/safeunion/1.0/default/Android.bp b/tests/safeunion/1.0/default/Android.bp index 759a49c63a..94fee852cb 100644 --- a/tests/safeunion/1.0/default/Android.bp +++ b/tests/safeunion/1.0/default/Android.bp @@ -1,3 +1,12 @@ +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 { name: "android.hardware.tests.safeunion@1.0-impl", defaults: ["hidl_defaults"], diff --git a/tests/safeunion/cpp/1.0/Android.bp b/tests/safeunion/cpp/1.0/Android.bp index 221643a392..6c670f633f 100644 --- a/tests/safeunion/cpp/1.0/Android.bp +++ b/tests/safeunion/cpp/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.tests.safeunion.cpp@1.0", root: "android.hardware", diff --git a/tests/safeunion/cpp/1.0/default/Android.bp b/tests/safeunion/cpp/1.0/default/Android.bp index 618f295f25..25f37508af 100644 --- a/tests/safeunion/cpp/1.0/default/Android.bp +++ b/tests/safeunion/cpp/1.0/default/Android.bp @@ -1,3 +1,12 @@ +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 { name: "android.hardware.tests.safeunion.cpp@1.0-impl", relative_install_path: "hw", diff --git a/tests/trie/1.0/Android.bp b/tests/trie/1.0/Android.bp index 3cb67c7577..e7025406dc 100644 --- a/tests/trie/1.0/Android.bp +++ b/tests/trie/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.tests.trie@1.0", root: "android.hardware", diff --git a/tests/trie/1.0/default/Android.bp b/tests/trie/1.0/default/Android.bp index 4ca705c16d..3690802b66 100644 --- a/tests/trie/1.0/default/Android.bp +++ b/tests/trie/1.0/default/Android.bp @@ -1,3 +1,12 @@ +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 { name: "android.hardware.tests.trie@1.0-impl", defaults: ["hidl_defaults"], diff --git a/tetheroffload/config/1.0/Android.bp b/tetheroffload/config/1.0/Android.bp index e774048751..116c9b6264 100644 --- a/tetheroffload/config/1.0/Android.bp +++ b/tetheroffload/config/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.tetheroffload.config@1.0", root: "android.hardware", diff --git a/tetheroffload/config/1.0/vts/functional/Android.bp b/tetheroffload/config/1.0/vts/functional/Android.bp index ad5a1b1af4..fe03d8f710 100644 --- a/tetheroffload/config/1.0/vts/functional/Android.bp +++ b/tetheroffload/config/1.0/vts/functional/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"], +} + cc_test { name: "VtsHalTetheroffloadConfigV1_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/tetheroffload/control/1.0/Android.bp b/tetheroffload/control/1.0/Android.bp index 4bcaed2dbf..acb5ee8a1b 100644 --- a/tetheroffload/control/1.0/Android.bp +++ b/tetheroffload/control/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.tetheroffload.control@1.0", root: "android.hardware", diff --git a/tetheroffload/control/1.0/vts/functional/Android.bp b/tetheroffload/control/1.0/vts/functional/Android.bp index ddf382626f..dc3b00c1ad 100644 --- a/tetheroffload/control/1.0/vts/functional/Android.bp +++ b/tetheroffload/control/1.0/vts/functional/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"], +} + cc_test { name: "VtsHalTetheroffloadControlV1_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/tetheroffload/control/1.1/Android.bp b/tetheroffload/control/1.1/Android.bp index 18c8ea97d1..e87ff5c71b 100644 --- a/tetheroffload/control/1.1/Android.bp +++ b/tetheroffload/control/1.1/Android.bp @@ -1,5 +1,14 @@ // 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.tetheroffload.control@1.1", root: "android.hardware", diff --git a/tetheroffload/control/1.1/vts/functional/Android.bp b/tetheroffload/control/1.1/vts/functional/Android.bp index ab29350805..3eea59ba05 100644 --- a/tetheroffload/control/1.1/vts/functional/Android.bp +++ b/tetheroffload/control/1.1/vts/functional/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"], +} + cc_test { name: "VtsHalTetheroffloadControlV1_1TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/thermal/1.0/Android.bp b/thermal/1.0/Android.bp index 10eeddc07d..f6cf294017 100644 --- a/thermal/1.0/Android.bp +++ b/thermal/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.thermal@1.0", root: "android.hardware", diff --git a/thermal/1.0/default/Android.bp b/thermal/1.0/default/Android.bp index 194a9f8aa0..18bc046f4e 100644 --- a/thermal/1.0/default/Android.bp +++ b/thermal/1.0/default/Android.bp @@ -13,6 +13,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"], +} + cc_library_shared { name: "android.hardware.thermal@1.0-impl", defaults: ["hidl_defaults"], diff --git a/thermal/1.0/vts/functional/Android.bp b/thermal/1.0/vts/functional/Android.bp index 5ccf07af17..c73008ac7c 100644 --- a/thermal/1.0/vts/functional/Android.bp +++ b/thermal/1.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalThermalV1_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], @@ -21,4 +30,3 @@ cc_test { static_libs: ["android.hardware.thermal@1.0"], test_suites: ["general-tests", "vts"], } - diff --git a/thermal/1.1/Android.bp b/thermal/1.1/Android.bp index 7dc30a324d..ef2fa208e6 100644 --- a/thermal/1.1/Android.bp +++ b/thermal/1.1/Android.bp @@ -1,5 +1,14 @@ // 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.thermal@1.1", root: "android.hardware", diff --git a/thermal/1.1/vts/functional/Android.bp b/thermal/1.1/vts/functional/Android.bp index b869ece290..89fef1b890 100644 --- a/thermal/1.1/vts/functional/Android.bp +++ b/thermal/1.1/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalThermalV1_1TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/thermal/2.0/Android.bp b/thermal/2.0/Android.bp index 3d9cea1230..eb47b38431 100644 --- a/thermal/2.0/Android.bp +++ b/thermal/2.0/Android.bp @@ -1,5 +1,14 @@ // 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.thermal@2.0", root: "android.hardware", diff --git a/thermal/2.0/default/Android.bp b/thermal/2.0/default/Android.bp index 7b72694018..a63ffbc34c 100644 --- a/thermal/2.0/default/Android.bp +++ b/thermal/2.0/default/Android.bp @@ -13,6 +13,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"], +} + cc_binary { name: "android.hardware.thermal@2.0-service.mock", defaults: ["hidl_defaults"], diff --git a/thermal/2.0/vts/functional/Android.bp b/thermal/2.0/vts/functional/Android.bp index 026cb62577..f26c1af3b1 100644 --- a/thermal/2.0/vts/functional/Android.bp +++ b/thermal/2.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalThermalV2_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], @@ -24,4 +33,3 @@ cc_test { ], test_suites: ["general-tests", "vts"], } - diff --git a/tv/cec/1.0/Android.bp b/tv/cec/1.0/Android.bp index 0e0f284d51..889399ab43 100644 --- a/tv/cec/1.0/Android.bp +++ b/tv/cec/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.tv.cec@1.0", root: "android.hardware", diff --git a/tv/cec/1.0/default/Android.bp b/tv/cec/1.0/default/Android.bp index 239a527faa..fc4298d86c 100644 --- a/tv/cec/1.0/default/Android.bp +++ b/tv/cec/1.0/default/Android.bp @@ -1,3 +1,12 @@ +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.tv.cec@1.0-impl", defaults: ["hidl_defaults"], diff --git a/tv/cec/1.1/Android.bp b/tv/cec/1.1/Android.bp index c2d4e54407..27b4f03767 100644 --- a/tv/cec/1.1/Android.bp +++ b/tv/cec/1.1/Android.bp @@ -1,5 +1,14 @@ // 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.tv.cec@1.1", root: "android.hardware", diff --git a/tv/cec/1.1/default/Android.bp b/tv/cec/1.1/default/Android.bp index e0dff0d033..b536d23b29 100644 --- a/tv/cec/1.1/default/Android.bp +++ b/tv/cec/1.1/default/Android.bp @@ -1,3 +1,12 @@ +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.tv.cec@1.1-service", defaults: ["hidl_defaults"], diff --git a/tv/cec/1.1/vts/functional/Android.bp b/tv/cec/1.1/vts/functional/Android.bp index 5fc7093fa8..5a6548d4dc 100644 --- a/tv/cec/1.1/vts/functional/Android.bp +++ b/tv/cec/1.1/vts/functional/Android.bp @@ -1,3 +1,12 @@ +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalTvCecV1_1TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/tv/input/1.0/Android.bp b/tv/input/1.0/Android.bp index 1121f4ed46..292ec6331a 100644 --- a/tv/input/1.0/Android.bp +++ b/tv/input/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.tv.input@1.0", root: "android.hardware", diff --git a/tv/input/1.0/default/Android.bp b/tv/input/1.0/default/Android.bp index 5f6b7e75be..f572003f1c 100644 --- a/tv/input/1.0/default/Android.bp +++ b/tv/input/1.0/default/Android.bp @@ -1,3 +1,12 @@ +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.tv.input@1.0-impl", defaults: ["hidl_defaults"], diff --git a/tv/input/1.0/vts/functional/Android.bp b/tv/input/1.0/vts/functional/Android.bp index 29d4e21de2..fad1c90f61 100644 --- a/tv/input/1.0/vts/functional/Android.bp +++ b/tv/input/1.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalTvInputV1_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/tv/tuner/1.0/Android.bp b/tv/tuner/1.0/Android.bp index e5786418f5..237f4957e2 100644 --- a/tv/tuner/1.0/Android.bp +++ b/tv/tuner/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.tv.tuner@1.0", root: "android.hardware", diff --git a/tv/tuner/1.0/default/Android.bp b/tv/tuner/1.0/default/Android.bp index 5711889aa4..c85fbdf389 100644 --- a/tv/tuner/1.0/default/Android.bp +++ b/tv/tuner/1.0/default/Android.bp @@ -1,3 +1,12 @@ +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_defaults { name: "tuner_service_defaults", defaults: ["hidl_defaults"], diff --git a/tv/tuner/1.0/vts/functional/Android.bp b/tv/tuner/1.0/vts/functional/Android.bp index 7b130ea00b..c27a935c2e 100644 --- a/tv/tuner/1.0/vts/functional/Android.bp +++ b/tv/tuner/1.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalTvTunerV1_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/tv/tuner/1.1/Android.bp b/tv/tuner/1.1/Android.bp index daa3683fd7..40bea6f7c8 100644 --- a/tv/tuner/1.1/Android.bp +++ b/tv/tuner/1.1/Android.bp @@ -1,5 +1,14 @@ // 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.tv.tuner@1.1", root: "android.hardware", diff --git a/tv/tuner/1.1/default/Android.bp b/tv/tuner/1.1/default/Android.bp index 4401f7cd2c..86025cf4dd 100644 --- a/tv/tuner/1.1/default/Android.bp +++ b/tv/tuner/1.1/default/Android.bp @@ -1,3 +1,12 @@ +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_defaults { name: "tuner_service_defaults@1.1", defaults: ["hidl_defaults"], diff --git a/tv/tuner/1.1/vts/functional/Android.bp b/tv/tuner/1.1/vts/functional/Android.bp index 73cd0578c1..92e587b699 100644 --- a/tv/tuner/1.1/vts/functional/Android.bp +++ b/tv/tuner/1.1/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalTvTunerV1_1TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/tv/tuner/assets/Android.bp b/tv/tuner/assets/Android.bp index b58b645515..79244edbb0 100644 --- a/tv/tuner/assets/Android.bp +++ b/tv/tuner/assets/Android.bp @@ -1,3 +1,12 @@ +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"], +} + genrule { name: "tuner_frontend_input_es", srcs: ["tuner_frontend_input.es"], diff --git a/usb/1.0/Android.bp b/usb/1.0/Android.bp index 607d1aca79..d5d3500496 100644 --- a/usb/1.0/Android.bp +++ b/usb/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.usb@1.0", root: "android.hardware", diff --git a/usb/1.0/default/Android.bp b/usb/1.0/default/Android.bp index 98d9064474..5f56fe0262 100644 --- a/usb/1.0/default/Android.bp +++ b/usb/1.0/default/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"], +} + cc_binary { name: "android.hardware.usb@1.0-service", defaults: ["hidl_defaults"], diff --git a/usb/1.0/vts/functional/Android.bp b/usb/1.0/vts/functional/Android.bp index ae31bd2d30..d976a06116 100644 --- a/usb/1.0/vts/functional/Android.bp +++ b/usb/1.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalUsbV1_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/usb/1.1/Android.bp b/usb/1.1/Android.bp index 8742e77c57..9c3e0dc434 100644 --- a/usb/1.1/Android.bp +++ b/usb/1.1/Android.bp @@ -1,5 +1,14 @@ // 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.usb@1.1", root: "android.hardware", diff --git a/usb/1.1/vts/functional/Android.bp b/usb/1.1/vts/functional/Android.bp index 5bec94af66..f514009cda 100644 --- a/usb/1.1/vts/functional/Android.bp +++ b/usb/1.1/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalUsbV1_1TargetTest", defaults: ["VtsHalTargetTestDefaults"], @@ -24,4 +33,3 @@ cc_test { ], test_suites: ["general-tests", "vts"], } - diff --git a/usb/1.2/Android.bp b/usb/1.2/Android.bp index 8b9f0fb609..0d4430df06 100644 --- a/usb/1.2/Android.bp +++ b/usb/1.2/Android.bp @@ -1,5 +1,14 @@ // 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.usb@1.2", root: "android.hardware", diff --git a/usb/1.2/vts/functional/Android.bp b/usb/1.2/vts/functional/Android.bp index d6aaf2d9aa..688e725708 100644 --- a/usb/1.2/vts/functional/Android.bp +++ b/usb/1.2/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalUsbV1_2TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/usb/1.3/Android.bp b/usb/1.3/Android.bp index 17367d3d8d..c48da37934 100644 --- a/usb/1.3/Android.bp +++ b/usb/1.3/Android.bp @@ -1,5 +1,14 @@ // 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.usb@1.3", root: "android.hardware", diff --git a/usb/1.3/vts/functional/Android.bp b/usb/1.3/vts/functional/Android.bp index b62bb9d03f..6a1ce1e1ce 100644 --- a/usb/1.3/vts/functional/Android.bp +++ b/usb/1.3/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalUsbV1_3TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/usb/gadget/1.0/Android.bp b/usb/gadget/1.0/Android.bp index 21f152c36c..bb602fa595 100644 --- a/usb/gadget/1.0/Android.bp +++ b/usb/gadget/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.usb.gadget@1.0", root: "android.hardware", diff --git a/usb/gadget/1.1/Android.bp b/usb/gadget/1.1/Android.bp index e5100697cc..388f11cc3c 100644 --- a/usb/gadget/1.1/Android.bp +++ b/usb/gadget/1.1/Android.bp @@ -1,5 +1,14 @@ // 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.usb.gadget@1.1", root: "android.hardware", diff --git a/usb/gadget/1.1/default/Android.bp b/usb/gadget/1.1/default/Android.bp index 68e2a29857..789a4f0c2b 100644 --- a/usb/gadget/1.1/default/Android.bp +++ b/usb/gadget/1.1/default/Android.bp @@ -14,6 +14,15 @@ * 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.usb.gadget@1.1-service", defaults: ["hidl_defaults"], diff --git a/usb/gadget/1.1/default/lib/Android.bp b/usb/gadget/1.1/default/lib/Android.bp index bba83409cc..bf7bb37b83 100644 --- a/usb/gadget/1.1/default/lib/Android.bp +++ b/usb/gadget/1.1/default/lib/Android.bp @@ -14,6 +14,15 @@ * 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: "libusbconfigfs", vendor_available: true, diff --git a/usb/gadget/1.2/Android.bp b/usb/gadget/1.2/Android.bp index 386f00fcfc..dc3589708d 100644 --- a/usb/gadget/1.2/Android.bp +++ b/usb/gadget/1.2/Android.bp @@ -1,5 +1,14 @@ // 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.usb.gadget@1.2", root: "android.hardware", diff --git a/usb/gadget/1.2/default/Android.bp b/usb/gadget/1.2/default/Android.bp index 9c73a59dc2..713ce83046 100644 --- a/usb/gadget/1.2/default/Android.bp +++ b/usb/gadget/1.2/default/Android.bp @@ -14,6 +14,15 @@ * 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.usb.gadget@1.2-service", defaults: ["hidl_defaults"], diff --git a/usb/gadget/1.2/default/lib/Android.bp b/usb/gadget/1.2/default/lib/Android.bp index 727de136cb..3bf46e36a8 100644 --- a/usb/gadget/1.2/default/lib/Android.bp +++ b/usb/gadget/1.2/default/lib/Android.bp @@ -14,6 +14,15 @@ * 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: "libusbconfigfs-2", vendor_available: true, diff --git a/vibrator/1.0/Android.bp b/vibrator/1.0/Android.bp index d6321fb163..1ae1cef04d 100644 --- a/vibrator/1.0/Android.bp +++ b/vibrator/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.vibrator@1.0", root: "android.hardware", diff --git a/vibrator/1.0/default/Android.bp b/vibrator/1.0/default/Android.bp index b0d09860cb..ed750b453b 100644 --- a/vibrator/1.0/default/Android.bp +++ b/vibrator/1.0/default/Android.bp @@ -13,6 +13,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"], +} + cc_library_shared { name: "android.hardware.vibrator@1.0-impl", defaults: ["hidl_defaults"], diff --git a/vibrator/1.0/vts/functional/Android.bp b/vibrator/1.0/vts/functional/Android.bp index 4ec1aa8064..83377e79bd 100644 --- a/vibrator/1.0/vts/functional/Android.bp +++ b/vibrator/1.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalVibratorV1_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], @@ -21,4 +30,3 @@ cc_test { static_libs: ["android.hardware.vibrator@1.0"], test_suites: ["general-tests", "vts"], } - diff --git a/vibrator/1.1/Android.bp b/vibrator/1.1/Android.bp index 0302220b56..357c1f0c66 100644 --- a/vibrator/1.1/Android.bp +++ b/vibrator/1.1/Android.bp @@ -1,5 +1,14 @@ // 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.vibrator@1.1", root: "android.hardware", diff --git a/vibrator/1.1/vts/functional/Android.bp b/vibrator/1.1/vts/functional/Android.bp index b291e7ce50..f97a343226 100644 --- a/vibrator/1.1/vts/functional/Android.bp +++ b/vibrator/1.1/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalVibratorV1_1TargetTest", defaults: ["VtsHalTargetTestDefaults"], @@ -24,4 +33,3 @@ cc_test { ], test_suites: ["general-tests", "vts"], } - diff --git a/vibrator/1.2/Android.bp b/vibrator/1.2/Android.bp index 1fa01144fa..42f97d4351 100644 --- a/vibrator/1.2/Android.bp +++ b/vibrator/1.2/Android.bp @@ -1,5 +1,14 @@ // 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.vibrator@1.2", root: "android.hardware", diff --git a/vibrator/1.2/vts/functional/Android.bp b/vibrator/1.2/vts/functional/Android.bp index 7bf69d06d3..40171ae863 100644 --- a/vibrator/1.2/vts/functional/Android.bp +++ b/vibrator/1.2/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalVibratorV1_2TargetTest", defaults: ["VtsHalTargetTestDefaults"], @@ -25,4 +34,3 @@ cc_test { ], test_suites: ["general-tests", "vts"], } - diff --git a/vibrator/1.3/Android.bp b/vibrator/1.3/Android.bp index d742388879..124f5d1834 100644 --- a/vibrator/1.3/Android.bp +++ b/vibrator/1.3/Android.bp @@ -1,5 +1,14 @@ // 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.vibrator@1.3", root: "android.hardware", diff --git a/vibrator/1.3/example/Android.bp b/vibrator/1.3/example/Android.bp index 07f1c26db3..7e9bf8f1f5 100644 --- a/vibrator/1.3/example/Android.bp +++ b/vibrator/1.3/example/Android.bp @@ -13,6 +13,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"], +} + cc_binary { name: "android.hardware.vibrator@1.3-service.example", vendor: true, diff --git a/vibrator/1.3/vts/functional/Android.bp b/vibrator/1.3/vts/functional/Android.bp index 5215ed04cf..0fcbf0771b 100644 --- a/vibrator/1.3/vts/functional/Android.bp +++ b/vibrator/1.3/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalVibratorV1_3TargetTest", defaults: ["VtsHalTargetTestDefaults"], @@ -26,4 +35,3 @@ cc_test { ], test_suites: ["general-tests", "vts"], } - diff --git a/vibrator/aidl/Android.bp b/vibrator/aidl/Android.bp index 97663538fa..9bad971724 100644 --- a/vibrator/aidl/Android.bp +++ b/vibrator/aidl/Android.bp @@ -1,3 +1,12 @@ +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.vibrator", vendor_available: true, diff --git a/vibrator/aidl/default/Android.bp b/vibrator/aidl/default/Android.bp index b44f11dc94..d463f51511 100644 --- a/vibrator/aidl/default/Android.bp +++ b/vibrator/aidl/default/Android.bp @@ -1,3 +1,12 @@ +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: "libvibratorexampleimpl", vendor: true, diff --git a/vibrator/aidl/vts/Android.bp b/vibrator/aidl/vts/Android.bp index b50b3f70be..3f328fa736 100644 --- a/vibrator/aidl/vts/Android.bp +++ b/vibrator/aidl/vts/Android.bp @@ -1,3 +1,12 @@ +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalVibratorTargetTest", defaults: [ diff --git a/vibrator/bench/Android.bp b/vibrator/bench/Android.bp index 3d7bdc5084..e4c9cfb33d 100644 --- a/vibrator/bench/Android.bp +++ b/vibrator/bench/Android.bp @@ -13,6 +13,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"], +} + cc_benchmark { name: "VibratorHalIntegrationBenchmark", defaults: ["hidl_defaults"], diff --git a/vr/1.0/Android.bp b/vr/1.0/Android.bp index 769ee3b4a3..27d2ea8287 100644 --- a/vr/1.0/Android.bp +++ b/vr/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.vr@1.0", root: "android.hardware", diff --git a/vr/1.0/default/Android.bp b/vr/1.0/default/Android.bp index cfb28086b9..6e59bcf99a 100644 --- a/vr/1.0/default/Android.bp +++ b/vr/1.0/default/Android.bp @@ -1,3 +1,12 @@ +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.vr@1.0-impl", defaults: ["hidl_defaults"], diff --git a/vr/1.0/vts/functional/Android.bp b/vr/1.0/vts/functional/Android.bp index 6bfa05cad7..8e23f4f687 100644 --- a/vr/1.0/vts/functional/Android.bp +++ b/vr/1.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalVrV1_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/weaver/1.0/Android.bp b/weaver/1.0/Android.bp index 11fc68560a..f7d452af66 100644 --- a/weaver/1.0/Android.bp +++ b/weaver/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.weaver@1.0", root: "android.hardware", diff --git a/weaver/1.0/vts/functional/Android.bp b/weaver/1.0/vts/functional/Android.bp index b20f127647..cc1d28465d 100644 --- a/weaver/1.0/vts/functional/Android.bp +++ b/weaver/1.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalWeaverV1_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/weaver/aidl/Android.bp b/weaver/aidl/Android.bp index 5637e0a248..60925ecb89 100644 --- a/weaver/aidl/Android.bp +++ b/weaver/aidl/Android.bp @@ -1,3 +1,12 @@ +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.weaver", vendor_available: true, diff --git a/weaver/aidl/default/Android.bp b/weaver/aidl/default/Android.bp index 8440670c27..37a9c947d5 100644 --- a/weaver/aidl/default/Android.bp +++ b/weaver/aidl/default/Android.bp @@ -14,6 +14,15 @@ // 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.weaver-service.example", relative_install_path: "hw", diff --git a/weaver/aidl/vts/Android.bp b/weaver/aidl/vts/Android.bp index 7daad8d833..8dec4c17f0 100644 --- a/weaver/aidl/vts/Android.bp +++ b/weaver/aidl/vts/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalWeaverTargetTest", defaults: [ diff --git a/wifi/1.0/Android.bp b/wifi/1.0/Android.bp index c41864f853..94f8462836 100644 --- a/wifi/1.0/Android.bp +++ b/wifi/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.0", root: "android.hardware", diff --git a/wifi/1.0/vts/functional/Android.bp b/wifi/1.0/vts/functional/Android.bp index 30512a9f1a..e4948b4cc2 100644 --- a/wifi/1.0/vts/functional/Android.bp +++ b/wifi/1.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // 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: "VtsHalWifiV1_0TargetTestUtil", defaults: ["VtsHalTargetTestDefaults"], diff --git a/wifi/1.1/Android.bp b/wifi/1.1/Android.bp index 4068b31fbb..7b4116a258 100644 --- a/wifi/1.1/Android.bp +++ b/wifi/1.1/Android.bp @@ -1,5 +1,14 @@ // 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.1", root: "android.hardware", diff --git a/wifi/1.1/vts/functional/Android.bp b/wifi/1.1/vts/functional/Android.bp index 98931372e2..80486425c1 100644 --- a/wifi/1.1/vts/functional/Android.bp +++ b/wifi/1.1/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalWifiV1_1TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/wifi/1.2/Android.bp b/wifi/1.2/Android.bp index 5812b8268a..f0edb81976 100644 --- a/wifi/1.2/Android.bp +++ b/wifi/1.2/Android.bp @@ -1,5 +1,14 @@ // 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.2", root: "android.hardware", diff --git a/wifi/1.2/vts/functional/Android.bp b/wifi/1.2/vts/functional/Android.bp index 21d8388369..f43892bb32 100644 --- a/wifi/1.2/vts/functional/Android.bp +++ b/wifi/1.2/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalWifiV1_2TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/wifi/1.3/Android.bp b/wifi/1.3/Android.bp index f4e130a7a8..030d7f6eb6 100644 --- a/wifi/1.3/Android.bp +++ b/wifi/1.3/Android.bp @@ -1,5 +1,14 @@ // 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.3", root: "android.hardware", diff --git a/wifi/1.3/vts/functional/Android.bp b/wifi/1.3/vts/functional/Android.bp index 7ee69c9964..16f84ef495 100644 --- a/wifi/1.3/vts/functional/Android.bp +++ b/wifi/1.3/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalWifiV1_3TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/wifi/1.4/Android.bp b/wifi/1.4/Android.bp index 5620d03553..1523f79927 100644 --- a/wifi/1.4/Android.bp +++ b/wifi/1.4/Android.bp @@ -1,5 +1,14 @@ // 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.4", root: "android.hardware", diff --git a/wifi/1.4/vts/functional/Android.bp b/wifi/1.4/vts/functional/Android.bp index 0051d27d6b..14ebbe3bb8 100644 --- a/wifi/1.4/vts/functional/Android.bp +++ b/wifi/1.4/vts/functional/Android.bp @@ -15,6 +15,15 @@ // // SoftAP-specific tests, similar to VtsHalWifiApV1_0TargetTest. +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalWifiApV1_4TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/wifi/1.5/Android.bp b/wifi/1.5/Android.bp index e2c38cecc0..7c04c6967a 100644 --- a/wifi/1.5/Android.bp +++ b/wifi/1.5/Android.bp @@ -1,5 +1,14 @@ // 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.5", root: "android.hardware", diff --git a/wifi/1.5/default/Android.mk b/wifi/1.5/default/Android.mk index dc9e89b2b6..1997b2209f 100644 --- a/wifi/1.5/default/Android.mk +++ b/wifi/1.5/default/Android.mk @@ -18,6 +18,9 @@ LOCAL_PATH := $(call my-dir) ### include $(CLEAR_VARS) LOCAL_MODULE := android.hardware.wifi@1.0-service-lib +LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 +LOCAL_LICENSE_CONDITIONS := notice +LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../../NOTICE LOCAL_MODULE_RELATIVE_PATH := hw LOCAL_PROPRIETARY_MODULE := true LOCAL_CPPFLAGS := -Wall -Werror -Wextra @@ -84,6 +87,9 @@ include $(BUILD_STATIC_LIBRARY) ### include $(CLEAR_VARS) LOCAL_MODULE := android.hardware.wifi@1.0-service +LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 +LOCAL_LICENSE_CONDITIONS := notice +LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../../NOTICE LOCAL_VINTF_FRAGMENTS := android.hardware.wifi@1.0-service.xml LOCAL_MODULE_RELATIVE_PATH := hw LOCAL_PROPRIETARY_MODULE := true @@ -116,6 +122,9 @@ include $(BUILD_EXECUTABLE) ### include $(CLEAR_VARS) LOCAL_MODULE := android.hardware.wifi@1.0-service-lazy +LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 +LOCAL_LICENSE_CONDITIONS := notice +LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../../NOTICE LOCAL_VINTF_FRAGMENTS := android.hardware.wifi@1.0-service.xml LOCAL_OVERRIDES_MODULES := android.hardware.wifi@1.0-service LOCAL_CFLAGS := -DLAZY_SERVICE @@ -150,6 +159,9 @@ include $(BUILD_EXECUTABLE) ### include $(CLEAR_VARS) LOCAL_MODULE := android.hardware.wifi@1.0-service-tests +LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 +LOCAL_LICENSE_CONDITIONS := notice +LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../../NOTICE LOCAL_PROPRIETARY_MODULE := true LOCAL_CPPFLAGS := -Wall -Werror -Wextra LOCAL_SRC_FILES := \ diff --git a/wifi/1.5/vts/functional/Android.bp b/wifi/1.5/vts/functional/Android.bp index 118822a35f..764d14da0a 100644 --- a/wifi/1.5/vts/functional/Android.bp +++ b/wifi/1.5/vts/functional/Android.bp @@ -14,6 +14,15 @@ // 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: "VtsHalWifiV1_5TargetTestUtil", defaults: ["VtsHalTargetTestDefaults"], diff --git a/wifi/hostapd/1.0/Android.bp b/wifi/hostapd/1.0/Android.bp index b736167f24..afcd45cc0c 100644 --- a/wifi/hostapd/1.0/Android.bp +++ b/wifi/hostapd/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.hostapd@1.0", root: "android.hardware", diff --git a/wifi/hostapd/1.0/vts/functional/Android.bp b/wifi/hostapd/1.0/vts/functional/Android.bp index 2a35f15190..daf5b60bfc 100644 --- a/wifi/hostapd/1.0/vts/functional/Android.bp +++ b/wifi/hostapd/1.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // 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: "VtsHalWifiHostapdV1_0TargetTestUtil", defaults: ["VtsHalTargetTestDefaults"], diff --git a/wifi/hostapd/1.1/Android.bp b/wifi/hostapd/1.1/Android.bp index bba065df08..f5f2fbe93a 100644 --- a/wifi/hostapd/1.1/Android.bp +++ b/wifi/hostapd/1.1/Android.bp @@ -1,5 +1,14 @@ // 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.hostapd@1.1", root: "android.hardware", diff --git a/wifi/hostapd/1.1/vts/functional/Android.bp b/wifi/hostapd/1.1/vts/functional/Android.bp index 61a8dfd813..999a6a7d32 100644 --- a/wifi/hostapd/1.1/vts/functional/Android.bp +++ b/wifi/hostapd/1.1/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalWifiHostapdV1_1TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/wifi/hostapd/1.2/Android.bp b/wifi/hostapd/1.2/Android.bp index 9b26ece6b2..4ca41aa2a7 100644 --- a/wifi/hostapd/1.2/Android.bp +++ b/wifi/hostapd/1.2/Android.bp @@ -1,5 +1,14 @@ // 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.hostapd@1.2", root: "android.hardware", diff --git a/wifi/hostapd/1.2/vts/functional/Android.bp b/wifi/hostapd/1.2/vts/functional/Android.bp index 577174b018..9609da5d41 100644 --- a/wifi/hostapd/1.2/vts/functional/Android.bp +++ b/wifi/hostapd/1.2/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalWifiHostapdV1_2TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/wifi/hostapd/1.3/Android.bp b/wifi/hostapd/1.3/Android.bp index 31faa6a9a6..f75b5e25da 100644 --- a/wifi/hostapd/1.3/Android.bp +++ b/wifi/hostapd/1.3/Android.bp @@ -1,5 +1,14 @@ // 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.hostapd@1.3", root: "android.hardware", diff --git a/wifi/hostapd/1.3/vts/functional/Android.bp b/wifi/hostapd/1.3/vts/functional/Android.bp index ed18bb69cd..6eceadf774 100644 --- a/wifi/hostapd/1.3/vts/functional/Android.bp +++ b/wifi/hostapd/1.3/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalWifiHostapdV1_3TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/wifi/offload/1.0/Android.bp b/wifi/offload/1.0/Android.bp index 91ed476c62..8fd602de1f 100644 --- a/wifi/offload/1.0/Android.bp +++ b/wifi/offload/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.offload@1.0", root: "android.hardware", diff --git a/wifi/offload/1.0/vts/functional/Android.bp b/wifi/offload/1.0/vts/functional/Android.bp index abfefa8214..a0eb048c66 100644 --- a/wifi/offload/1.0/vts/functional/Android.bp +++ b/wifi/offload/1.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // limitations under the License. // +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalWifiOffloadV1_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], diff --git a/wifi/supplicant/1.0/Android.bp b/wifi/supplicant/1.0/Android.bp index d46e463ac9..66e9353833 100644 --- a/wifi/supplicant/1.0/Android.bp +++ b/wifi/supplicant/1.0/Android.bp @@ -1,5 +1,14 @@ // 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.supplicant@1.0", root: "android.hardware", diff --git a/wifi/supplicant/1.0/vts/functional/Android.bp b/wifi/supplicant/1.0/vts/functional/Android.bp index 42efde451e..121117c244 100644 --- a/wifi/supplicant/1.0/vts/functional/Android.bp +++ b/wifi/supplicant/1.0/vts/functional/Android.bp @@ -14,6 +14,15 @@ // 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: "VtsHalWifiSupplicantV1_0TargetTestUtil", defaults: ["VtsHalTargetTestDefaults"], diff --git a/wifi/supplicant/1.1/Android.bp b/wifi/supplicant/1.1/Android.bp index bc20dca6db..c62437455e 100644 --- a/wifi/supplicant/1.1/Android.bp +++ b/wifi/supplicant/1.1/Android.bp @@ -1,5 +1,14 @@ // 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.supplicant@1.1", root: "android.hardware", diff --git a/wifi/supplicant/1.1/vts/functional/Android.bp b/wifi/supplicant/1.1/vts/functional/Android.bp index d9ae3e029c..68cda33d3e 100644 --- a/wifi/supplicant/1.1/vts/functional/Android.bp +++ b/wifi/supplicant/1.1/vts/functional/Android.bp @@ -14,6 +14,15 @@ // 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: "VtsHalWifiSupplicantV1_1TargetTestUtil", defaults: ["VtsHalTargetTestDefaults"], diff --git a/wifi/supplicant/1.2/Android.bp b/wifi/supplicant/1.2/Android.bp index aa2fa7be60..d5d937fac0 100644 --- a/wifi/supplicant/1.2/Android.bp +++ b/wifi/supplicant/1.2/Android.bp @@ -1,5 +1,14 @@ // 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.supplicant@1.2", root: "android.hardware", diff --git a/wifi/supplicant/1.2/vts/functional/Android.bp b/wifi/supplicant/1.2/vts/functional/Android.bp index 2592a2b08c..ec3ca2210a 100644 --- a/wifi/supplicant/1.2/vts/functional/Android.bp +++ b/wifi/supplicant/1.2/vts/functional/Android.bp @@ -14,6 +14,15 @@ // 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: "VtsHalWifiSupplicantV1_2TargetTestUtil", defaults: ["VtsHalTargetTestDefaults"], diff --git a/wifi/supplicant/1.3/Android.bp b/wifi/supplicant/1.3/Android.bp index 4268490f6a..fbe7f75bf4 100644 --- a/wifi/supplicant/1.3/Android.bp +++ b/wifi/supplicant/1.3/Android.bp @@ -1,5 +1,14 @@ // 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.supplicant@1.3", root: "android.hardware", diff --git a/wifi/supplicant/1.3/vts/functional/Android.bp b/wifi/supplicant/1.3/vts/functional/Android.bp index 1784fad60c..ec25de2a43 100644 --- a/wifi/supplicant/1.3/vts/functional/Android.bp +++ b/wifi/supplicant/1.3/vts/functional/Android.bp @@ -14,6 +14,15 @@ // 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: "VtsHalWifiSupplicantV1_3TargetTestUtil", defaults: ["VtsHalTargetTestDefaults"], diff --git a/wifi/supplicant/1.4/Android.bp b/wifi/supplicant/1.4/Android.bp index 2867629d4c..b486687d74 100644 --- a/wifi/supplicant/1.4/Android.bp +++ b/wifi/supplicant/1.4/Android.bp @@ -1,5 +1,14 @@ // 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.supplicant@1.4", root: "android.hardware", diff --git a/wifi/supplicant/1.4/vts/functional/Android.bp b/wifi/supplicant/1.4/vts/functional/Android.bp index d6af0a03d2..8cbe04f686 100644 --- a/wifi/supplicant/1.4/vts/functional/Android.bp +++ b/wifi/supplicant/1.4/vts/functional/Android.bp @@ -14,6 +14,15 @@ // 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: "VtsHalWifiSupplicantV1_4TargetTestUtil", defaults: ["VtsHalTargetTestDefaults"], -- GitLab From 7394e62c7aae72d3b9cc71a6e07d8c4f6b936de4 Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Tue, 23 Feb 2021 22:29:48 -0800 Subject: [PATCH 484/790] Add more Frontend Status Caps and frontend types in Tuner default impl This helps the CTS to cover more Frontend JNI/java/client codes Test: atest android.media.tv.tuner.cts Bug: 181088182 Change-Id: I6fe079f7691cddaca6262345b10abc2145a5a6f3 --- tv/tuner/1.1/default/Frontend.cpp | 230 +++++++++++++++++++++++++++--- tv/tuner/1.1/default/Tuner.cpp | 122 +++++++++++++--- tv/tuner/1.1/default/Tuner.h | 1 + 3 files changed, 318 insertions(+), 35 deletions(-) diff --git a/tv/tuner/1.1/default/Frontend.cpp b/tv/tuner/1.1/default/Frontend.cpp index 243891c996..0f6784bd31 100644 --- a/tv/tuner/1.1/default/Frontend.cpp +++ b/tv/tuner/1.1/default/Frontend.cpp @@ -196,8 +196,38 @@ Return Frontend::getStatus(const hidl_vec& statusTypes } case FrontendStatusType::MODULATION: { FrontendModulationStatus modulationStatus; - modulationStatus.isdbs(FrontendIsdbsModulation::MOD_BPSK); // value = 1 << 1 - status.modulation(modulationStatus); + switch (mType) { + case FrontendType::ISDBS: { + modulationStatus.isdbs( + FrontendIsdbsModulation::MOD_BPSK); // value = 1 << 1 + status.modulation(modulationStatus); + break; + } + case FrontendType::DVBC: { + modulationStatus.dvbc(FrontendDvbcModulation::MOD_16QAM); // value = 1 << 1 + status.modulation(modulationStatus); + break; + } + case FrontendType::DVBS: { + modulationStatus.dvbs(FrontendDvbsModulation::MOD_QPSK); // value = 1 << 1 + status.modulation(modulationStatus); + break; + } + case FrontendType::ISDBS3: { + modulationStatus.isdbs3( + FrontendIsdbs3Modulation::MOD_BPSK); // value = 1 << 1 + status.modulation(modulationStatus); + break; + } + case FrontendType::ISDBT: { + modulationStatus.isdbt( + FrontendIsdbtModulation::MOD_DQPSK); // value = 1 << 1 + status.modulation(modulationStatus); + break; + } + default: + break; + } break; } case FrontendStatusType::SPECTRAL: { @@ -282,15 +312,70 @@ Return Frontend::getStatusExt1_1(const hidl_vec modulations; V1_1::FrontendModulation modulation; - modulation.isdbs(FrontendIsdbsModulation::MOD_BPSK); // value = 1 << 1 - modulations.push_back(modulation); - status.modulations(modulations); + switch ((int)mType) { + case (int)FrontendType::ISDBS: { + modulation.isdbs(FrontendIsdbsModulation::MOD_BPSK); // value = 1 << 1 + modulations.push_back(modulation); + status.modulations(modulations); + break; + } + case (int)FrontendType::DVBC: { + modulation.dvbc(FrontendDvbcModulation::MOD_16QAM); // value = 1 << 1 + modulations.push_back(modulation); + status.modulations(modulations); + break; + } + case (int)FrontendType::DVBS: { + modulation.dvbs(FrontendDvbsModulation::MOD_QPSK); // value = 1 << 1 + modulations.push_back(modulation); + status.modulations(modulations); + break; + } + case (int)FrontendType::DVBT: { + // value = 1 << 16 + modulation.dvbt(V1_1::FrontendDvbtConstellation::CONSTELLATION_16QAM_R); + modulations.push_back(modulation); + status.modulations(modulations); + break; + } + case (int)FrontendType::ISDBS3: { + modulation.isdbs3(FrontendIsdbs3Modulation::MOD_BPSK); // value = 1 << 1 + modulations.push_back(modulation); + status.modulations(modulations); + break; + } + case (int)FrontendType::ISDBT: { + modulation.isdbt(FrontendIsdbtModulation::MOD_DQPSK); // value = 1 << 1 + modulations.push_back(modulation); + status.modulations(modulations); + break; + } + case (int)FrontendType::ATSC: { + modulation.atsc(FrontendAtscModulation::MOD_8VSB); // value = 1 << 2 + modulations.push_back(modulation); + status.modulations(modulations); + break; + } + case (int)FrontendType::ATSC3: { + modulation.atsc3(FrontendAtsc3Modulation::MOD_QPSK); // value = 1 << 1 + modulations.push_back(modulation); + status.modulations(modulations); + break; + } + case (int)V1_1::FrontendType::DTMB: { + // value = 1 << 1 + modulation.dtmb(V1_1::FrontendDtmbModulation::CONSTELLATION_4QAM); + modulations.push_back(modulation); + status.modulations(modulations); + break; + } + default: + break; + } break; } case V1_1::FrontendStatusTypeExt1_1::BERS: { @@ -306,20 +391,86 @@ Return Frontend::getStatusExt1_1(const hidl_vec Frontend::getStatusExt1_1(const hidl_vec interleaving = {interleave}; - status.interleaving(interleaving); + switch ((int)mType) { + case (int)FrontendType::DVBC: { + // value = 1 << 1 + interleave.dvbc( + V1_1::FrontendCableTimeInterleaveMode::INTERLEAVING_128_1_0); + vector interleaving = {interleave}; + status.interleaving(interleaving); + break; + } + case (int)FrontendType::ATSC3: { + // value = 1 << 1 + interleave.atsc3(FrontendAtsc3TimeInterleaveMode::CTI); + vector interleaving = {interleave}; + status.interleaving(interleaving); + break; + } + case (int)V1_1::FrontendType::DTMB: { + // value = 1 << 1 + interleave.dtmb(V1_1::FrontendDtmbTimeInterleaveMode::TIMER_INT_240); + vector interleaving = {interleave}; + status.interleaving(interleaving); + break; + } + default: + break; + } break; } case V1_1::FrontendStatusTypeExt1_1::ISDBT_SEGMENTS: { @@ -349,8 +523,28 @@ Return Frontend::getStatusExt1_1(const hidl_vec(V1_1::FrontendType::DTMB), 8, this); + mFrontends[8] = new Frontend(FrontendType::ISDBS3, 8, this); + mFrontends[9] = + new Frontend(static_cast(V1_1::FrontendType::DTMB), 9, this); FrontendInfo::FrontendCapabilities caps; + vector statusCaps; + caps = FrontendInfo::FrontendCapabilities(); caps.isdbsCaps(FrontendIsdbsCapabilities()); mFrontendCaps[0] = caps; + statusCaps = { + FrontendStatusType::DEMOD_LOCK, + FrontendStatusType::SNR, + FrontendStatusType::FEC, + FrontendStatusType::MODULATION, + static_cast(V1_1::FrontendStatusTypeExt1_1::MODULATIONS), + static_cast(V1_1::FrontendStatusTypeExt1_1::ROLL_OFF), + }; + mFrontendStatusCaps[0] = statusCaps; caps = FrontendInfo::FrontendCapabilities(); - caps.atscCaps(FrontendAtscCapabilities()); + caps.atsc3Caps(FrontendAtsc3Capabilities()); mFrontendCaps[1] = caps; + statusCaps = { + FrontendStatusType::BER, + FrontendStatusType::PER, + FrontendStatusType::ATSC3_PLP_INFO, + static_cast(V1_1::FrontendStatusTypeExt1_1::MODULATIONS), + static_cast(V1_1::FrontendStatusTypeExt1_1::BERS), + static_cast(V1_1::FrontendStatusTypeExt1_1::INTERLEAVINGS), + static_cast(V1_1::FrontendStatusTypeExt1_1::BANDWIDTH), + }; + mFrontendStatusCaps[1] = statusCaps; caps = FrontendInfo::FrontendCapabilities(); caps.dvbcCaps(FrontendDvbcCapabilities()); mFrontendCaps[2] = caps; + statusCaps = { + FrontendStatusType::PRE_BER, + FrontendStatusType::SIGNAL_QUALITY, + FrontendStatusType::MODULATION, + FrontendStatusType::SPECTRAL, + static_cast(V1_1::FrontendStatusTypeExt1_1::MODULATIONS), + static_cast(V1_1::FrontendStatusTypeExt1_1::CODERATES), + static_cast(V1_1::FrontendStatusTypeExt1_1::INTERLEAVINGS), + static_cast(V1_1::FrontendStatusTypeExt1_1::BANDWIDTH), + }; + mFrontendStatusCaps[2] = statusCaps; caps = FrontendInfo::FrontendCapabilities(); caps.dvbsCaps(FrontendDvbsCapabilities()); mFrontendCaps[3] = caps; + statusCaps = { + FrontendStatusType::SIGNAL_STRENGTH, + FrontendStatusType::SYMBOL_RATE, + FrontendStatusType::MODULATION, + static_cast(V1_1::FrontendStatusTypeExt1_1::MODULATIONS), + static_cast(V1_1::FrontendStatusTypeExt1_1::ROLL_OFF), + static_cast(V1_1::FrontendStatusTypeExt1_1::IS_MISO), + }; + mFrontendStatusCaps[3] = statusCaps; caps = FrontendInfo::FrontendCapabilities(); caps.dvbtCaps(FrontendDvbtCapabilities()); mFrontendCaps[4] = caps; + statusCaps = { + FrontendStatusType::EWBS, + FrontendStatusType::PLP_ID, + FrontendStatusType::HIERARCHY, + static_cast(V1_1::FrontendStatusTypeExt1_1::MODULATIONS), + static_cast(V1_1::FrontendStatusTypeExt1_1::BANDWIDTH), + static_cast(V1_1::FrontendStatusTypeExt1_1::GUARD_INTERVAL), + static_cast(V1_1::FrontendStatusTypeExt1_1::TRANSMISSION_MODE), + static_cast(V1_1::FrontendStatusTypeExt1_1::T2_SYSTEM_ID), + }; + mFrontendStatusCaps[4] = statusCaps; caps = FrontendInfo::FrontendCapabilities(); FrontendIsdbtCapabilities isdbtCaps{ @@ -77,14 +130,60 @@ Tuner::Tuner() { }; caps.isdbtCaps(isdbtCaps); mFrontendCaps[5] = caps; + statusCaps = { + FrontendStatusType::AGC, + FrontendStatusType::LNA, + FrontendStatusType::MODULATION, + static_cast(V1_1::FrontendStatusTypeExt1_1::MODULATIONS), + static_cast(V1_1::FrontendStatusTypeExt1_1::BANDWIDTH), + static_cast(V1_1::FrontendStatusTypeExt1_1::GUARD_INTERVAL), + static_cast(V1_1::FrontendStatusTypeExt1_1::TRANSMISSION_MODE), + static_cast(V1_1::FrontendStatusTypeExt1_1::ISDBT_SEGMENTS), + }; + mFrontendStatusCaps[5] = statusCaps; caps = FrontendInfo::FrontendCapabilities(); caps.analogCaps(FrontendAnalogCapabilities()); mFrontendCaps[6] = caps; + statusCaps = { + FrontendStatusType::LAYER_ERROR, + FrontendStatusType::MER, + static_cast(V1_1::FrontendStatusTypeExt1_1::UEC), + static_cast(V1_1::FrontendStatusTypeExt1_1::TS_DATA_RATES), + }; + mFrontendStatusCaps[6] = statusCaps; caps = FrontendInfo::FrontendCapabilities(); caps.atscCaps(FrontendAtscCapabilities()); mFrontendCaps[7] = caps; + statusCaps = { + FrontendStatusType::FREQ_OFFSET, + FrontendStatusType::RF_LOCK, + static_cast(V1_1::FrontendStatusTypeExt1_1::MODULATIONS), + static_cast(V1_1::FrontendStatusTypeExt1_1::IS_LINEAR), + }; + mFrontendStatusCaps[7] = statusCaps; + + caps = FrontendInfo::FrontendCapabilities(); + caps.isdbs3Caps(FrontendIsdbs3Capabilities()); + mFrontendCaps[8] = caps; + statusCaps = { + FrontendStatusType::DEMOD_LOCK, + FrontendStatusType::MODULATION, + static_cast(V1_1::FrontendStatusTypeExt1_1::MODULATIONS), + static_cast(V1_1::FrontendStatusTypeExt1_1::ROLL_OFF), + static_cast(V1_1::FrontendStatusTypeExt1_1::IS_SHORT_FRAMES), + }; + mFrontendStatusCaps[8] = statusCaps; + + statusCaps = { + static_cast(V1_1::FrontendStatusTypeExt1_1::MODULATIONS), + static_cast(V1_1::FrontendStatusTypeExt1_1::INTERLEAVINGS), + static_cast(V1_1::FrontendStatusTypeExt1_1::BANDWIDTH), + static_cast(V1_1::FrontendStatusTypeExt1_1::GUARD_INTERVAL), + static_cast(V1_1::FrontendStatusTypeExt1_1::TRANSMISSION_MODE), + }; + mFrontendStatusCaps[9] = statusCaps; mLnbs.resize(2); mLnbs[0] = new Lnb(0); @@ -160,17 +259,6 @@ Return Tuner::getFrontendInfo(FrontendId frontendId, getFrontendInfo_cb _h return Void(); } - vector statusCaps = { - FrontendStatusType::DEMOD_LOCK, - FrontendStatusType::SNR, - FrontendStatusType::FEC, - FrontendStatusType::MODULATION, - FrontendStatusType::PLP_ID, - FrontendStatusType::LAYER_ERROR, - FrontendStatusType::ATSC3_PLP_INFO, - static_cast(V1_1::FrontendStatusTypeExt1_1::MODULATIONS), - static_cast(V1_1::FrontendStatusTypeExt1_1::ROLL_OFF), - }; // assign randomly selected values for testing. info = { .type = mFrontends[frontendId]->getFrontendType(), @@ -180,7 +268,7 @@ Return Tuner::getFrontendInfo(FrontendId frontendId, getFrontendInfo_cb _h .maxSymbolRate = 1145, .acquireRange = 30, .exclusiveGroupId = 57, - .statusCaps = statusCaps, + .statusCaps = mFrontendStatusCaps[frontendId], .frontendCaps = mFrontendCaps[frontendId], }; diff --git a/tv/tuner/1.1/default/Tuner.h b/tv/tuner/1.1/default/Tuner.h index fda3636939..97bc99544a 100644 --- a/tv/tuner/1.1/default/Tuner.h +++ b/tv/tuner/1.1/default/Tuner.h @@ -79,6 +79,7 @@ class Tuner : public ITuner { // Static mFrontends array to maintain local frontends information map> mFrontends; map mFrontendCaps; + map> mFrontendStatusCaps; V1_1::FrontendDtmbCapabilities mDtmbCaps; map mFrontendToDemux; map> mDemuxes; -- GitLab From 8638d754ee8a13dc8c5e016db3c252acfbfedbdf Mon Sep 17 00:00:00 2001 From: Yu-Han Yang Date: Thu, 11 Feb 2021 13:45:06 -0800 Subject: [PATCH 485/790] Clean up AIDL warnings in GNSS Bug: 179853357 Test: on cuttlefish Change-Id: I4f41b1ce7ddce6cfa1b240dc455643d93ce697d1 --- .../current/android/hardware/gnss/BlocklistedSource.aidl | 2 +- .../current/android/hardware/gnss/GnssMeasurement.aidl | 2 +- .../current/android/hardware/gnss/GnssSignalType.aidl | 2 +- gnss/aidl/android/hardware/gnss/BlocklistedSource.aidl | 2 +- gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl | 2 +- gnss/aidl/android/hardware/gnss/GnssSignalType.aidl | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/BlocklistedSource.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/BlocklistedSource.aidl index 11cdcfcc9a..1a2feb776a 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/BlocklistedSource.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/BlocklistedSource.aidl @@ -33,6 +33,6 @@ package android.hardware.gnss; @VintfStability parcelable BlocklistedSource { - android.hardware.gnss.GnssConstellationType constellation; + android.hardware.gnss.GnssConstellationType constellation = android.hardware.gnss.GnssConstellationType.UNKNOWN; int svid; } diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMeasurement.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMeasurement.aidl index 728ff68a28..bc73bb19eb 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMeasurement.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMeasurement.aidl @@ -50,7 +50,7 @@ parcelable GnssMeasurement { long carrierCycles; double carrierPhase; double carrierPhaseUncertainty; - android.hardware.gnss.GnssMultipathIndicator multipathIndicator; + android.hardware.gnss.GnssMultipathIndicator multipathIndicator = android.hardware.gnss.GnssMultipathIndicator.UNKNOWN; double snrDb; double agcLevelDb; double fullInterSignalBiasNs; diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssSignalType.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssSignalType.aidl index f729d4c2ec..ba02f72961 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssSignalType.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssSignalType.aidl @@ -33,7 +33,7 @@ package android.hardware.gnss; @VintfStability parcelable GnssSignalType { - android.hardware.gnss.GnssConstellationType constellation; + android.hardware.gnss.GnssConstellationType constellation = android.hardware.gnss.GnssConstellationType.UNKNOWN; double carrierFrequencyHz; @utf8InCpp String codeType; const @utf8InCpp String CODE_TYPE_A = "A"; diff --git a/gnss/aidl/android/hardware/gnss/BlocklistedSource.aidl b/gnss/aidl/android/hardware/gnss/BlocklistedSource.aidl index 2fde5b20fd..8b730921ff 100644 --- a/gnss/aidl/android/hardware/gnss/BlocklistedSource.aidl +++ b/gnss/aidl/android/hardware/gnss/BlocklistedSource.aidl @@ -26,7 +26,7 @@ parcelable BlocklistedSource { /** * Defines the constellation of the given satellite(s). */ - GnssConstellationType constellation; + GnssConstellationType constellation = GnssConstellationType.UNKNOWN; /** * Satellite (space vehicle) ID number, as defined in GnssSvInfo::svid, or 0 to blocklist all diff --git a/gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl b/gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl index 4468b63e26..f20cd25cd7 100644 --- a/gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl +++ b/gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl @@ -536,7 +536,7 @@ parcelable GnssMeasurement { * contain multipath, and MULTIPATH_INDICATOR_NOT_PRESENT for those * signals that are tracked and do not contain multipath. */ - GnssMultipathIndicator multipathIndicator; + GnssMultipathIndicator multipathIndicator = GnssMultipathIndicator.UNKNOWN; /** * Signal-to-noise ratio at correlator output in dB. diff --git a/gnss/aidl/android/hardware/gnss/GnssSignalType.aidl b/gnss/aidl/android/hardware/gnss/GnssSignalType.aidl index 9c68db1f54..a16b170da4 100644 --- a/gnss/aidl/android/hardware/gnss/GnssSignalType.aidl +++ b/gnss/aidl/android/hardware/gnss/GnssSignalType.aidl @@ -26,7 +26,7 @@ parcelable GnssSignalType { /** * Constellation type of the SV that transmits the signal. */ - GnssConstellationType constellation; + GnssConstellationType constellation = GnssConstellationType.UNKNOWN; /** * Carrier frequency of the signal tracked, for example it can be the -- GitLab From 43db707407ec6c620fb3bec496caf48c35f72ff2 Mon Sep 17 00:00:00 2001 From: Alec Mouri Date: Wed, 24 Feb 2021 11:24:22 -0800 Subject: [PATCH 486/790] Add render target bit to output buffer for readback vts RenderEngine requires the gpu target bit on its output buffers, since it is a GPU implementation which...uses the GPU. Bug: 180650640 Test: atest VtsHalGraphicsComposerV2_2TargetTest Change-Id: Ie99af44dc1b8804026b889f8342362839a43c945 --- .../vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp index f522731ec9..1463c3be6c 100644 --- a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp +++ b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp @@ -103,7 +103,8 @@ class GraphicsCompositionTestBase : public ::testing::Test { mTestRenderEngine->initGraphicBuffer( static_cast(mDisplayWidth), static_cast(mDisplayHeight), 1, - static_cast(BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN)); + static_cast(BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN | + BufferUsage::GPU_RENDER_TARGET)); mTestRenderEngine->setDisplaySettings(clientCompositionDisplay); } -- GitLab From bfb5adeff04e2444251a052b39e5d9e02584de94 Mon Sep 17 00:00:00 2001 From: Mingguang Xu Date: Wed, 24 Feb 2021 23:04:00 -0800 Subject: [PATCH 487/790] Wifi: Change the type from long to int for contention time statistics Bug: 172412545 Test: atest com.android.server.wifi Signed-off-by: Mingguang Xu Change-Id: I7d64013c63a38b85d4b0ea37cdc260a19049bfce --- wifi/1.5/types.hal | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/wifi/1.5/types.hal b/wifi/1.5/types.hal index 3a5560b70b..e1c0d327e0 100644 --- a/wifi/1.5/types.hal +++ b/wifi/1.5/types.hal @@ -142,23 +142,23 @@ struct StaLinkLayerIfaceContentionTimeStats { * Data packet min contention time (usec). It includes both the internal contention time * among different access categories within the chipset and the contention time for the medium. */ - uint64_t contentionTimeMinInUsec; + uint32_t contentionTimeMinInUsec; /** * Data packet max contention time (usec). It includes both the internal contention time * among different access categories within the chipset and the contention time for the medium. */ - uint64_t contentionTimeMaxInUsec; + uint32_t contentionTimeMaxInUsec; /** * Data packet average contention time (usec). It includes both the internal contention time * among different access categories within the chipset and the contention time for the medium. */ - uint64_t contentionTimeAvgInUsec; + uint32_t contentionTimeAvgInUsec; /** * Number of data packets used for contention statistics. */ - uint64_t contentionNumSamples; + uint32_t contentionNumSamples; }; /** -- GitLab From 82a6c61d1dd5e77fe9d25db8c005402bd5eddd84 Mon Sep 17 00:00:00 2001 From: Hongbo Zeng Date: Tue, 23 Feb 2021 17:19:58 +0800 Subject: [PATCH 488/790] rename nsaids to nssais Bug: 178075054 Test: full build pass Change-Id: I04e7794e8b9f13962dff782fd51ac6df6117f862 --- radio/1.6/types.hal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/radio/1.6/types.hal b/radio/1.6/types.hal index 21cb0101f4..20f14dc771 100644 --- a/radio/1.6/types.hal +++ b/radio/1.6/types.hal @@ -986,7 +986,7 @@ struct SlicingConfig { /** * Struct containing all NSSAIs (list of slice info). */ - Nssais nsaids; + Nssais nssais; }; /** -- GitLab From ef0fb1da94ba5f8fcd101ef59ae7b96ee1b6131a Mon Sep 17 00:00:00 2001 From: Shinru Han Date: Thu, 25 Feb 2021 13:46:56 +0800 Subject: [PATCH 489/790] Fix type of frequencyOffsetMps to use double Bug: 179389247 Test: on cuttlefish Change-Id: I3389a2986692e439469b618470ba6a325436a30f --- .../current/android/hardware/gnss/CorrelationVector.aidl | 2 +- gnss/aidl/android/hardware/gnss/CorrelationVector.aidl | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/CorrelationVector.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/CorrelationVector.aidl index 2d21748564..9c9a2414a6 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/CorrelationVector.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/CorrelationVector.aidl @@ -33,7 +33,7 @@ package android.hardware.gnss; @VintfStability parcelable CorrelationVector { - int frequencyOffsetMps; + double frequencyOffsetMps; double samplingWidthM; double samplingStartM; int[] magnitude; diff --git a/gnss/aidl/android/hardware/gnss/CorrelationVector.aidl b/gnss/aidl/android/hardware/gnss/CorrelationVector.aidl index 22a80cec57..6fbabbc140 100644 --- a/gnss/aidl/android/hardware/gnss/CorrelationVector.aidl +++ b/gnss/aidl/android/hardware/gnss/CorrelationVector.aidl @@ -22,11 +22,10 @@ package android.hardware.gnss; */ @VintfStability parcelable CorrelationVector { - /** * Frequency offset from reported pseudorange rate for this Correlation Vector. */ - int frequencyOffsetMps; + double frequencyOffsetMps; /** * Space between correlation samples in meters. @@ -48,4 +47,4 @@ parcelable CorrelationVector { * The length of the array is defined by the GNSS chipset. */ int[] magnitude; -} \ No newline at end of file +} -- GitLab From 013fc384645256d6cccb686a63cd29d56ae89f84 Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Thu, 25 Feb 2021 10:41:34 -0800 Subject: [PATCH 490/790] Add various filter events callbacks after filter starting in the Filter default impl Note: these events are only for testing purpose. This would make sure that CTS could cover more of the Filter events codes. Test: atest android.media.tv.tuner.cts Bug: 181152149 Change-Id: I8b4318a384af75646b61060f849353602ecefc03 --- tv/tuner/1.1/default/Demux.cpp | 4 + tv/tuner/1.1/default/Filter.cpp | 203 +++++++++++++++++++++++++++++++- tv/tuner/1.1/default/Filter.h | 12 ++ 3 files changed, 217 insertions(+), 2 deletions(-) diff --git a/tv/tuner/1.1/default/Demux.cpp b/tv/tuner/1.1/default/Demux.cpp index f4e4a919de..db25c2e43d 100644 --- a/tv/tuner/1.1/default/Demux.cpp +++ b/tv/tuner/1.1/default/Demux.cpp @@ -340,6 +340,10 @@ void* Demux::__threadLoopFrontend(void* user) { } void Demux::frontendInputThreadLoop() { + if (!mFrontendInputThreadRunning) { + return; + } + std::lock_guard lock(mFrontendInputThreadLock); if (!mDvrPlayback) { ALOGW("[Demux] No software Frontend input configured. Ending Frontend thread loop."); diff --git a/tv/tuner/1.1/default/Filter.cpp b/tv/tuner/1.1/default/Filter.cpp index 2e29aa9696..884b5077a0 100644 --- a/tv/tuner/1.1/default/Filter.cpp +++ b/tv/tuner/1.1/default/Filter.cpp @@ -72,9 +72,8 @@ Filter::Filter(DemuxFilterType type, uint64_t filterId, uint32_t bufferSize, sp filterCallback_v1_1 = V1_1::IFilterCallback::castFrom(cb); if (filterCallback_v1_1 != NULL) { mCallback_1_1 = filterCallback_v1_1; - } else { - mCallback = cb; } + mCallback = cb; } Filter::~Filter() { @@ -141,6 +140,36 @@ Return Filter::configure(const DemuxFilterSettings& settings) { Return Filter::start() { ALOGV("%s", __FUNCTION__); mFilterThreadRunning = true; + // All the filter event callbacks in start are for testing purpose. + switch (mType.mainType) { + case DemuxFilterMainType::TS: + mCallback->onFilterEvent(createMediaEvent()); + mCallback->onFilterEvent(createTsRecordEvent()); + mCallback_1_1->onFilterEvent_1_1(createTsRecordEvent(), createTsRecordEventExt()); + mCallback->onFilterEvent(createTemiEvent()); + break; + case DemuxFilterMainType::MMTP: + mCallback->onFilterEvent(createDownloadEvent()); + mCallback->onFilterEvent(createMmtpRecordEvent()); + mCallback_1_1->onFilterEvent_1_1(createMmtpRecordEvent(), createMmtpRecordEventExt()); + break; + case DemuxFilterMainType::IP: + mCallback->onFilterEvent(createSectionEvent()); + mCallback->onFilterEvent(createIpPayloadEvent()); + break; + case DemuxFilterMainType::TLV: { + DemuxFilterEvent emptyFilterEvent; + mCallback_1_1->onFilterEvent_1_1(emptyFilterEvent, createMonitorEvent()); + break; + } + case DemuxFilterMainType::ALP: { + DemuxFilterEvent emptyFilterEvent; + mCallback_1_1->onFilterEvent_1_1(emptyFilterEvent, createRestartEvent()); + break; + } + default: + break; + } return startFilterLoop(); } @@ -926,6 +955,176 @@ bool Filter::sameFile(int fd1, int fd2) { } return (stat1.st_dev == stat2.st_dev) && (stat1.st_ino == stat2.st_ino); } + +DemuxFilterEvent Filter::createMediaEvent() { + DemuxFilterEvent event; + event.events.resize(1); + + event.events[0].media({ + .streamId = 1, + .isPtsPresent = true, + .pts = 2, + .dataLength = 3, + .offset = 4, + .isSecureMemory = true, + .avDataId = 5, + .mpuSequenceNumber = 6, + .isPesPrivateData = true, + }); + + event.events[0].media().extraMetaData.audio({ + .adFade = 1, + .adPan = 2, + .versionTextTag = 3, + .adGainCenter = 4, + .adGainFront = 5, + .adGainSurround = 6, + }); + + int av_fd = createAvIonFd(BUFFER_SIZE_16M); + if (av_fd == -1) { + return event; + } + + native_handle_t* nativeHandle = createNativeHandle(av_fd); + if (nativeHandle == NULL) { + return event; + } + + hidl_handle handle; + handle.setTo(nativeHandle, /*shouldOwn=*/true); + event.events[0].media().avMemory = std::move(handle); + ::close(av_fd); + + return event; +} + +DemuxFilterEvent Filter::createTsRecordEvent() { + DemuxFilterEvent event; + event.events.resize(1); + + DemuxPid pid; + pid.tPid(1); + DemuxFilterTsRecordEvent::ScIndexMask mask; + mask.sc(1); + event.events[0].tsRecord({ + .pid = pid, + .tsIndexMask = 1, + .scIndexMask = mask, + .byteNumber = 2, + }); + return event; +} + +V1_1::DemuxFilterEventExt Filter::createTsRecordEventExt() { + V1_1::DemuxFilterEventExt event; + event.events.resize(1); + + event.events[0].tsRecord({ + .pts = 1, + .firstMbInSlice = 2, // random address + }); + return event; +} + +DemuxFilterEvent Filter::createMmtpRecordEvent() { + DemuxFilterEvent event; + event.events.resize(1); + + event.events[0].mmtpRecord({ + .scHevcIndexMask = 1, + .byteNumber = 2, + }); + return event; +} + +V1_1::DemuxFilterEventExt Filter::createMmtpRecordEventExt() { + V1_1::DemuxFilterEventExt event; + event.events.resize(1); + + event.events[0].mmtpRecord({ + .pts = 1, + .mpuSequenceNumber = 2, + .firstMbInSlice = 3, + .tsIndexMask = 4, + }); + return event; +} + +DemuxFilterEvent Filter::createSectionEvent() { + DemuxFilterEvent event; + event.events.resize(1); + + event.events[0].section({ + .tableId = 1, + .version = 2, + .sectionNum = 3, + .dataLength = 0, + }); + return event; +} + +DemuxFilterEvent Filter::createPesEvent() { + DemuxFilterEvent event; + event.events.resize(1); + + event.events[0].pes({ + .streamId = static_cast(1), + .dataLength = 1, + .mpuSequenceNumber = 2, + }); + return event; +} + +DemuxFilterEvent Filter::createDownloadEvent() { + DemuxFilterEvent event; + event.events.resize(1); + + event.events[0].download({ + .itemId = 1, + .mpuSequenceNumber = 2, + .itemFragmentIndex = 3, + .lastItemFragmentIndex = 4, + .dataLength = 0, + }); + return event; +} + +DemuxFilterEvent Filter::createIpPayloadEvent() { + DemuxFilterEvent event; + event.events.resize(1); + + event.events[0].ipPayload({ + .dataLength = 0, + }); + return event; +} + +DemuxFilterEvent Filter::createTemiEvent() { + DemuxFilterEvent event; + event.events.resize(1); + + event.events[0].temi({.pts = 1, .descrTag = 2, .descrData = {3}}); + return event; +} + +V1_1::DemuxFilterEventExt Filter::createMonitorEvent() { + V1_1::DemuxFilterEventExt event; + event.events.resize(1); + + V1_1::DemuxFilterMonitorEvent monitor; + monitor.scramblingStatus(V1_1::ScramblingStatus::SCRAMBLED); + event.events[0].monitorEvent(monitor); + return event; +} + +V1_1::DemuxFilterEventExt Filter::createRestartEvent() { + V1_1::DemuxFilterEventExt event; + event.events.resize(1); + + event.events[0].startId(1); + return event; +} } // namespace implementation } // namespace V1_0 } // namespace tuner diff --git a/tv/tuner/1.1/default/Filter.h b/tv/tuner/1.1/default/Filter.h index 3a4246e095..659bebf178 100644 --- a/tv/tuner/1.1/default/Filter.h +++ b/tv/tuner/1.1/default/Filter.h @@ -198,6 +198,18 @@ class Filter : public V1_1::IFilter { Result createShareMemMediaEvents(vector output); bool sameFile(int fd1, int fd2); + DemuxFilterEvent createMediaEvent(); + DemuxFilterEvent createTsRecordEvent(); + V1_1::DemuxFilterEventExt createTsRecordEventExt(); + DemuxFilterEvent createMmtpRecordEvent(); + V1_1::DemuxFilterEventExt createMmtpRecordEventExt(); + DemuxFilterEvent createSectionEvent(); + DemuxFilterEvent createPesEvent(); + DemuxFilterEvent createDownloadEvent(); + DemuxFilterEvent createIpPayloadEvent(); + DemuxFilterEvent createTemiEvent(); + V1_1::DemuxFilterEventExt createMonitorEvent(); + V1_1::DemuxFilterEventExt createRestartEvent(); /** * Lock to protect writes to the FMQs */ -- GitLab From c605e0b9b3251fe4e21bf6394c8fe55fad8638ce Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Thu, 25 Feb 2021 16:04:34 -0800 Subject: [PATCH 491/790] Keep a strong pointer to Session in the HAL If the client who's holding the other end of the Session goes away prematurely, the Session will have 0 strong references and will be destructed. That can cause a crash because the worker thread might still be working on a task that's referencing the Session's resources. By keeping a strong pointer to the Session in the HAL, we make sure that even if the client disappears, the tasks can gracefully finish. One small issue with this is that the Session's resources will not be freed until a new session is requested. This may need to be revised if we subscribe to client's binder death. The VTS test no longer crashes, but fails due to another unrelated issue. Bug: 181184674 Test: atest VtsHalBiometricsFingerprintTargetTest Change-Id: Ic0eafa525a7f714d26946db7c9b4ee5793f531e6 --- biometrics/fingerprint/aidl/default/Fingerprint.cpp | 8 +++----- biometrics/fingerprint/aidl/default/include/Fingerprint.h | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/biometrics/fingerprint/aidl/default/Fingerprint.cpp b/biometrics/fingerprint/aidl/default/Fingerprint.cpp index 67dc34fdd5..802808911c 100644 --- a/biometrics/fingerprint/aidl/default/Fingerprint.cpp +++ b/biometrics/fingerprint/aidl/default/Fingerprint.cpp @@ -57,12 +57,10 @@ ndk::ScopedAStatus Fingerprint::getSensorProps(std::vector* out) { ndk::ScopedAStatus Fingerprint::createSession(int32_t sensorId, int32_t userId, const std::shared_ptr& cb, std::shared_ptr* out) { - auto sessionSp = mSession.lock(); - CHECK(sessionSp == nullptr || sessionSp->isClosed()) << "Open session already exists!"; + CHECK(mSession == nullptr || mSession->isClosed()) << "Open session already exists!"; - auto session = SharedRefBase::make(sensorId, userId, cb, mEngine.get(), &mWorker); - mSession = session; - *out = session; + mSession = SharedRefBase::make(sensorId, userId, cb, mEngine.get(), &mWorker); + *out = mSession; return ndk::ScopedAStatus::ok(); } diff --git a/biometrics/fingerprint/aidl/default/include/Fingerprint.h b/biometrics/fingerprint/aidl/default/include/Fingerprint.h index 9b8eef85ea..9b43419718 100644 --- a/biometrics/fingerprint/aidl/default/include/Fingerprint.h +++ b/biometrics/fingerprint/aidl/default/include/Fingerprint.h @@ -39,7 +39,7 @@ class Fingerprint : public BnFingerprint { private: std::unique_ptr mEngine; WorkerThread mWorker; - std::weak_ptr mSession; + std::shared_ptr mSession; }; } // namespace aidl::android::hardware::biometrics::fingerprint -- GitLab From ff537c8516e1f8be96264d3c5db3ac084e307566 Mon Sep 17 00:00:00 2001 From: Edwin Wong Date: Tue, 2 Feb 2021 10:42:38 -0800 Subject: [PATCH 492/790] [RESTRICT AUTOMERGE] Fix potential decrypt destPtr overflow. There is a potential integer overflow to bypass the destination base size check in decrypt. The destPtr can then point to the outside of the destination buffer. Test: sts-tradefed sts-tradefed run sts-engbuild-no-spl-lock -m StsHostTestCases --test android.security.sts.Bug_176444622#testPocBug_176444622 Test: push to device with target_hwasan-userdebug build adb shell /data/local/tmp/Bug-17644462264 Bug: 176444622 Bug: 176496353 Change-Id: I71b390846a17aecbb9180865e1f9538b4b464abf --- drm/1.0/default/CryptoPlugin.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drm/1.0/default/CryptoPlugin.cpp b/drm/1.0/default/CryptoPlugin.cpp index e60ba8f54d..e71385da5d 100644 --- a/drm/1.0/default/CryptoPlugin.cpp +++ b/drm/1.0/default/CryptoPlugin.cpp @@ -80,7 +80,7 @@ namespace implementation { } } - android::CryptoPlugin::Mode legacyMode; + android::CryptoPlugin::Mode legacyMode = android::CryptoPlugin::kMode_Unencrypted; switch(mode) { case Mode::UNENCRYPTED: legacyMode = android::CryptoPlugin::kMode_Unencrypted; @@ -147,7 +147,10 @@ namespace implementation { return Void(); } - if (destBuffer.offset + destBuffer.size > destBase->getSize()) { + size_t totalDstSize = 0; + if (__builtin_add_overflow(destBuffer.offset, destBuffer.size, &totalDstSize) || + totalDstSize > destBase->getSize()) { + android_errorWriteLog(0x534e4554, "176496353"); _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size"); return Void(); } @@ -158,7 +161,7 @@ namespace implementation { } base = static_cast(static_cast(destBase->getPointer())); - destPtr = static_cast(base + destination.nonsecureMemory.offset); + destPtr = static_cast(base + destination.nonsecureMemory.offset); } else if (destination.type == BufferType::NATIVE_HANDLE) { if (!secure) { _hidl_cb(Status::BAD_VALUE, 0, "native handle destination must be secure"); -- GitLab From 682abf403969efcbc8072a26f687560ad9def69a Mon Sep 17 00:00:00 2001 From: Jasmine Chen Date: Thu, 25 Feb 2021 21:57:31 +0800 Subject: [PATCH 493/790] Camera: Fix double-free in removeCamera When a camera is removed, |hidlMetadata| takes over ownership of |metadata|. Therefore, we should not free |metadata| again. Bug: 180014486 Test: Remove an external camera, and no crashes were observed. Change-Id: I85246067f8753911cbcb58af24a46f12962226f3 (cherry picked from commit f36a439e3a97315a9f0a8661ea77aff61fb79c82) --- camera/common/1.0/default/CameraModule.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/camera/common/1.0/default/CameraModule.cpp b/camera/common/1.0/default/CameraModule.cpp index 27e74f1480..16fb85cc64 100644 --- a/camera/common/1.0/default/CameraModule.cpp +++ b/camera/common/1.0/default/CameraModule.cpp @@ -549,7 +549,6 @@ void CameraModule::removeCamera(int cameraId) { } } } - free_camera_metadata(metadata); } mCameraInfoMap.removeItem(cameraId); -- GitLab From 5e09b8282951b63c80efe7813462c9b97dde374b Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Fri, 26 Feb 2021 12:24:18 -0800 Subject: [PATCH 494/790] Fix IFingerprint VTS The main function was not defined/visible because it was inside of a namespace. The default GTest main was used instead, and the Binder threadpool was never initialized, causing the test to hang. In addition to that, the test expected a single onStateChanged with SessionState::AUTHENTICATING. Added support and expectations for multiple callback invocations. Bug: 181184674 Test: atest VtsHalBiometricsFingerprintTargetTest Change-Id: I1da72a81b091c7382494a2c4828c113671de845c --- .../VtsHalBiometricsFingerprintTargetTest.cpp | 90 +++++++++++-------- 1 file changed, 54 insertions(+), 36 deletions(-) diff --git a/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp b/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp index ddbc0fee5a..894fdfe362 100644 --- a/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp +++ b/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + #include #include #include @@ -30,25 +31,35 @@ constexpr int kSensorId = 0; constexpr int kUserId = 0; constexpr auto kCallbackTimeout = std::chrono::seconds(1); -enum class SessionCallbackMethodName { +enum class MethodName { kOnStateChanged, }; -struct SessionCallbackInvocation { - SessionCallbackMethodName method_name; +struct Invocation { + MethodName methodName; + int32_t cookie; SessionState state; }; class SessionCallback : public BnSessionCallback { public: - explicit SessionCallback(std::promise invocation_promise) - : invocation_promise_(std::move(invocation_promise)) {} + explicit SessionCallback() : mIsPromiseValid(false) {} + + void setPromise(std::promise>&& promise) { + mPromise = std::move(promise); + mIsPromiseValid = true; + } - ndk::ScopedAStatus onStateChanged(int32_t /*cookie*/, SessionState state) override { - SessionCallbackInvocation invocation = {}; - invocation.method_name = SessionCallbackMethodName::kOnStateChanged; + ndk::ScopedAStatus onStateChanged(int32_t cookie, SessionState state) override { + Invocation invocation = {}; + invocation.methodName = MethodName::kOnStateChanged; + invocation.cookie = cookie; invocation.state = state; - invocation_promise_.set_value(invocation); + mInvocations.push_back(invocation); + if (state == SessionState::IDLING) { + assert(mIsPromiseValid); + mPromise.set_value(mInvocations); + } return ndk::ScopedAStatus::ok(); } @@ -73,26 +84,20 @@ class SessionCallback : public BnSessionCallback { return ndk::ScopedAStatus::ok(); } - ndk::ScopedAStatus onAuthenticationSucceeded(int32_t /*enrollmentId*/, - const keymaster::HardwareAuthToken& /*hat*/) override { + ndk::ScopedAStatus onAuthenticationSucceeded( + int32_t /*enrollmentId*/, const keymaster::HardwareAuthToken& /*hat*/) override { return ndk::ScopedAStatus::ok(); } - ndk::ScopedAStatus onAuthenticationFailed() override { - return ndk::ScopedAStatus::ok(); - } + ndk::ScopedAStatus onAuthenticationFailed() override { return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus onLockoutTimed(int64_t /*durationMillis*/) override { return ndk::ScopedAStatus::ok(); } - ndk::ScopedAStatus onLockoutPermanent() override { - return ndk::ScopedAStatus::ok(); - } + ndk::ScopedAStatus onLockoutPermanent() override { return ndk::ScopedAStatus::ok(); } - ndk::ScopedAStatus onLockoutCleared() override { - return ndk::ScopedAStatus::ok(); - } + ndk::ScopedAStatus onLockoutCleared() override { return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus onInteractionDetected() override { return ndk::ScopedAStatus::ok(); } @@ -115,7 +120,9 @@ class SessionCallback : public BnSessionCallback { } private: - std::promise invocation_promise_; + bool mIsPromiseValid; + std::vector mInvocations; + std::promise> mPromise; }; class Fingerprint : public testing::TestWithParam { @@ -123,28 +130,40 @@ class Fingerprint : public testing::TestWithParam { void SetUp() override { AIBinder* binder = AServiceManager_waitForService(GetParam().c_str()); ASSERT_NE(binder, nullptr); - hal_ = IFingerprint::fromBinder(ndk::SpAIBinder(binder)); + mHal = IFingerprint::fromBinder(ndk::SpAIBinder(binder)); } - std::shared_ptr hal_; + std::shared_ptr mHal; }; TEST_P(Fingerprint, AuthenticateTest) { - std::promise invocation_promise; - std::future invocation_future = invocation_promise.get_future(); - std::shared_ptr session_cb = - ndk::SharedRefBase::make(std::move(invocation_promise)); + // Prepare the callback + std::promise> promise; + auto future = promise.get_future(); + std::shared_ptr cb = ndk::SharedRefBase::make(); + cb->setPromise(std::move(promise)); + // Create a session std::shared_ptr session; - ASSERT_TRUE(hal_->createSession(kSensorId, kUserId, session_cb, &session).isOk()); + ASSERT_TRUE(mHal->createSession(kSensorId, kUserId, cb, &session).isOk()); + + // Call authenticate + int32_t cookie = 123; + std::shared_ptr cancellationSignal; + ASSERT_TRUE(session->authenticate(cookie, 0, &cancellationSignal).isOk()); + + // Get the results + ASSERT_TRUE(future.wait_for(kCallbackTimeout) == std::future_status::ready); + std::vector invocations = future.get(); - std::shared_ptr cancel_cb; - ASSERT_TRUE(session->authenticate(0, 0, &cancel_cb).isOk()); - ASSERT_EQ(invocation_future.wait_for(kCallbackTimeout), std::future_status::ready); + // Close the session + ASSERT_TRUE(session->close(0).isOk()); - SessionCallbackInvocation invocation = invocation_future.get(); - EXPECT_EQ(invocation.method_name, SessionCallbackMethodName::kOnStateChanged); - EXPECT_EQ(invocation.state, SessionState::AUTHENTICATING); + ASSERT_FALSE(invocations.empty()); + EXPECT_EQ(invocations.front().methodName, MethodName::kOnStateChanged); + EXPECT_EQ(invocations.front().state, SessionState::AUTHENTICATING); + EXPECT_EQ(invocations.back().methodName, MethodName::kOnStateChanged); + EXPECT_EQ(invocations.back().state, SessionState::IDLING); } GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Fingerprint); @@ -154,6 +173,7 @@ INSTANTIATE_TEST_SUITE_P( ::android::PrintInstanceNameToString); } // namespace +} // namespace aidl::android::hardware::biometrics::fingerprint int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); @@ -161,5 +181,3 @@ int main(int argc, char** argv) { ABinderProcess_startThreadPool(); return RUN_ALL_TESTS(); } - -} // namespace aidl::android::hardware::biometrics::fingerprint -- GitLab From cd690782caf99aa3b517f2d4d2659e666ef660ad Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Fri, 26 Feb 2021 13:53:17 -0800 Subject: [PATCH 495/790] Set enum defaults for biometrics Bug: 179853316 Test: m android.hardware.biometrics.common-update-api Test: m android.hardware.biometrics.fingerprint-update-api Test: m android.hardware.biometrics.face-update-api Test: build Change-Id: Ia13a0e59a5009e17496e84c593a64e3da27fac05 --- .../biometrics/common/CommonProps.aidl | 31 ++++++++++++++----- .../biometrics/common/HardwareInfo.aidl | 29 ++++++++++++----- .../common/ICancellationSignal.aidl | 29 ++++++++++++----- .../biometrics/common/SensorStrength.aidl | 29 ++++++++++++----- .../biometrics/common/CommonProps.aidl | 4 +-- .../hardware/biometrics/face/BaseFrame.aidl | 2 +- .../biometrics/face/EnrollmentFrame.aidl | 2 +- .../face/EnrollmentStageConfig.aidl | 2 +- .../hardware/biometrics/face/SensorProps.aidl | 2 +- .../hardware/biometrics/face/BaseFrame.aidl | 2 +- .../biometrics/face/EnrollmentFrame.aidl | 4 +-- .../face/EnrollmentStageConfig.aidl | 2 +- .../hardware/biometrics/face/SensorProps.aidl | 3 +- .../biometrics/fingerprint/SensorProps.aidl | 2 +- .../biometrics/fingerprint/SensorProps.aidl | 3 +- 15 files changed, 102 insertions(+), 44 deletions(-) diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/CommonProps.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/CommonProps.aidl index 8dbc149fa8..30959b10e7 100644 --- a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/CommonProps.aidl +++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/CommonProps.aidl @@ -1,14 +1,29 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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 interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped @@ -19,7 +34,7 @@ package android.hardware.biometrics.common; @VintfStability parcelable CommonProps { int sensorId; - android.hardware.biometrics.common.SensorStrength sensorStrength; + android.hardware.biometrics.common.SensorStrength sensorStrength = android.hardware.biometrics.common.SensorStrength.CONVENIENCE; int maxEnrollmentsPerUser; android.hardware.biometrics.common.HardwareInfo[] hardwareInfo; } diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/HardwareInfo.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/HardwareInfo.aidl index b94b6b0174..8fea864986 100644 --- a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/HardwareInfo.aidl +++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/HardwareInfo.aidl @@ -1,14 +1,29 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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 interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/ICancellationSignal.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/ICancellationSignal.aidl index 1a875bfbd8..b85a590612 100644 --- a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/ICancellationSignal.aidl +++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/ICancellationSignal.aidl @@ -1,14 +1,29 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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 interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/SensorStrength.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/SensorStrength.aidl index eaff85d2f9..3b20c9aa98 100644 --- a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/SensorStrength.aidl +++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/SensorStrength.aidl @@ -1,14 +1,29 @@ -/////////////////////////////////////////////////////////////////////////////// +/* + * 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 interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped diff --git a/biometrics/common/aidl/android/hardware/biometrics/common/CommonProps.aidl b/biometrics/common/aidl/android/hardware/biometrics/common/CommonProps.aidl index 9c3fd58090..59f398ef4e 100644 --- a/biometrics/common/aidl/android/hardware/biometrics/common/CommonProps.aidl +++ b/biometrics/common/aidl/android/hardware/biometrics/common/CommonProps.aidl @@ -33,7 +33,7 @@ parcelable CommonProps { * A statically configured strength for this sensor. See the SensorStrength interface for more * information. */ - SensorStrength sensorStrength; + SensorStrength sensorStrength = SensorStrength.CONVENIENCE; /** * The maximum number of enrollments that a single user can have. Statically configured. @@ -44,4 +44,4 @@ parcelable CommonProps { * A list of hardware information for subsystems that pertain to this biometric sensor. */ HardwareInfo[] hardwareInfo; -} \ No newline at end of file +} diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/BaseFrame.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/BaseFrame.aidl index a93510160b..99397051f2 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/BaseFrame.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/BaseFrame.aidl @@ -33,7 +33,7 @@ package android.hardware.biometrics.face; @VintfStability parcelable BaseFrame { - android.hardware.biometrics.face.AcquiredInfo acquiredInfo; + android.hardware.biometrics.face.AcquiredInfo acquiredInfo = android.hardware.biometrics.face.AcquiredInfo.INSUFFICIENT; int vendorCode; float pan; float tilt; diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentFrame.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentFrame.aidl index cc78e6b077..cb9a6c682b 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentFrame.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentFrame.aidl @@ -34,6 +34,6 @@ package android.hardware.biometrics.face; @VintfStability parcelable EnrollmentFrame { @nullable android.hardware.biometrics.face.Cell cell; - android.hardware.biometrics.face.EnrollmentStage stage; + android.hardware.biometrics.face.EnrollmentStage stage = android.hardware.biometrics.face.EnrollmentStage.FIRST_FRAME_RECEIVED; android.hardware.biometrics.face.BaseFrame data; } diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStageConfig.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStageConfig.aidl index d13eccd0fe..f55aafdb7c 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStageConfig.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStageConfig.aidl @@ -33,6 +33,6 @@ package android.hardware.biometrics.face; @VintfStability parcelable EnrollmentStageConfig { - android.hardware.biometrics.face.EnrollmentStage stage; + android.hardware.biometrics.face.EnrollmentStage stage = android.hardware.biometrics.face.EnrollmentStage.FIRST_FRAME_RECEIVED; List cells; } diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl index 23a8d4dddc..69355fbe69 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl @@ -34,7 +34,7 @@ package android.hardware.biometrics.face; @VintfStability parcelable SensorProps { android.hardware.biometrics.common.CommonProps commonProps; - android.hardware.biometrics.face.FaceSensorType sensorType; + android.hardware.biometrics.face.FaceSensorType sensorType = android.hardware.biometrics.face.FaceSensorType.RGB; boolean halControlsPreview; int enrollPreviewWidth; int enrollPreviewHeight; diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/BaseFrame.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/BaseFrame.aidl index 9e6b98adfa..85535f920d 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/BaseFrame.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/BaseFrame.aidl @@ -29,7 +29,7 @@ parcelable BaseFrame { * Information about the frame that can be used by the framework to provide feedback to the * user, for example ask the user to move their face in a certain way. */ - AcquiredInfo acquiredInfo; + AcquiredInfo acquiredInfo = AcquiredInfo.INSUFFICIENT; /** * If acquiredInfo is set to AcquiredInfo::VENDOR. This is the index into the configuration diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentFrame.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentFrame.aidl index d4f9771d03..ea0a502166 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentFrame.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentFrame.aidl @@ -16,9 +16,9 @@ package android.hardware.biometrics.face; +import android.hardware.biometrics.face.BaseFrame; import android.hardware.biometrics.face.Cell; import android.hardware.biometrics.face.EnrollmentStage; -import android.hardware.biometrics.face.BaseFrame; /** * Describes an individual frame captured during enrollment. @@ -33,7 +33,7 @@ parcelable EnrollmentFrame { /** * The enrollment stage for which this frame was captured. */ - EnrollmentStage stage; + EnrollmentStage stage = EnrollmentStage.FIRST_FRAME_RECEIVED; /** * The frame metadata. Can be used by the framework to provide user feedback. diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentStageConfig.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentStageConfig.aidl index 0b64e2bfbd..3c31fcc977 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentStageConfig.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentStageConfig.aidl @@ -24,7 +24,7 @@ parcelable EnrollmentStageConfig { /** * The stage that's being configured. */ - EnrollmentStage stage; + EnrollmentStage stage = EnrollmentStage.FIRST_FRAME_RECEIVED; /** * Optional list of cells that must be completed to finish this stage. diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl index 091e3225a3..b11b436098 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl @@ -29,7 +29,7 @@ parcelable SensorProps { /** * A statically configured sensor type representing this face sensor. */ - FaceSensorType sensorType; + FaceSensorType sensorType = FaceSensorType.RGB; /** * Whether or not the HAL is responsible for showing the face enrollment preview to the user. @@ -76,4 +76,3 @@ parcelable SensorProps { */ boolean supportsDetectInteraction; } - diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl index 53ac6dd917..00cbb6da86 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl @@ -34,7 +34,7 @@ package android.hardware.biometrics.fingerprint; @VintfStability parcelable SensorProps { android.hardware.biometrics.common.CommonProps commonProps; - android.hardware.biometrics.fingerprint.FingerprintSensorType sensorType; + android.hardware.biometrics.fingerprint.FingerprintSensorType sensorType = android.hardware.biometrics.fingerprint.FingerprintSensorType.UNKNOWN; android.hardware.biometrics.fingerprint.SensorLocation[] sensorLocations; boolean supportsNavigationGestures; boolean supportsDetectInteraction; diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl index 5222f3ea3a..fd2cf47d9e 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl @@ -30,7 +30,7 @@ parcelable SensorProps { /** * A statically configured sensor type representing this fingerprint sensor. */ - FingerprintSensorType sensorType; + FingerprintSensorType sensorType = FingerprintSensorType.UNKNOWN; /** * A list of display-specific locations from where the sensor is usable from. See SensorLocation @@ -49,4 +49,3 @@ parcelable SensorProps { */ boolean supportsDetectInteraction; } - -- GitLab From b207c4bd74036d75d97695d61f97255d3c16e42c Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Thu, 25 Feb 2021 16:41:51 -0800 Subject: [PATCH 496/790] Add test scan message during Frontend.scan in the Frontend default impl Note that this CL also fixes the broken Tuner 1.0 VTS due to the filter testing events, which trigger the Tuner 1.0 VTS to read data from the events meta data Test: atest android.media.tv.tuner.cts Test: atest VtsHalTvTunerV1_0TargetTest Test: atest VtsHalTvTunerV1_1TargetTest Bug: 181152149 Bug: 181242574 Change-Id: Ic6416e085dc2b81c3410db9e08fcea03cb8813d2 --- tv/tuner/1.0/vts/functional/FilterTests.cpp | 31 ++---- tv/tuner/1.0/vts/functional/FilterTests.h | 60 ----------- tv/tuner/1.1/default/Filter.cpp | 30 ++++-- tv/tuner/1.1/default/Frontend.cpp | 110 ++++++++++++++++---- 4 files changed, 126 insertions(+), 105 deletions(-) diff --git a/tv/tuner/1.0/vts/functional/FilterTests.cpp b/tv/tuner/1.0/vts/functional/FilterTests.cpp index 240aa9f149..1a09290725 100644 --- a/tv/tuner/1.0/vts/functional/FilterTests.cpp +++ b/tv/tuner/1.0/vts/functional/FilterTests.cpp @@ -78,24 +78,20 @@ bool FilterCallback::readFilterEventData() { DemuxFilterEvent filterEvent = mFilterEvent; ALOGW("[vts] reading from filter FMQ or buffer %d", mFilterId); // todo separate filter handlers - for (int i = 0; i < filterEvent.events.size(); i++) { - switch (mFilterEventType) { - case FilterEventType::SECTION: - mDataLength = filterEvent.events[i].section().dataLength; + for (auto event : filterEvent.events) { + switch (event.getDiscriminator()) { + case DemuxFilterEvent::Event::hidl_discriminator::section: + mDataLength = event.section().dataLength; break; - case FilterEventType::PES: - mDataLength = filterEvent.events[i].pes().dataLength; - break; - case FilterEventType::MEDIA: - return dumpAvData(filterEvent.events[i].media()); - case FilterEventType::RECORD: - return readRecordData(filterEvent.events[i].tsRecord()); - case FilterEventType::MMTPRECORD: - break; - case FilterEventType::DOWNLOAD: + case DemuxFilterEvent::Event::hidl_discriminator::pes: + mDataLength = event.pes().dataLength; break; + case DemuxFilterEvent::Event::hidl_discriminator::media: + return dumpAvData(event.media()); + case DemuxFilterEvent::Event::hidl_discriminator::tsRecord: + return readRecordData(event.tsRecord()); default: - break; + continue; } // EXPECT_TRUE(mDataLength == goldenDataOutputBuffer.size()) << "buffer size does not // match"; @@ -150,11 +146,6 @@ AssertionResult FilterTests::openFilterInDemux(DemuxFilterType type, uint32_t bu mFilter = filter; status = result; }); - - if (status == Result::SUCCESS) { - mFilterCallback->setFilterEventType(getFilterEventType(type)); - } - return AssertionResult(status == Result::SUCCESS); } diff --git a/tv/tuner/1.0/vts/functional/FilterTests.h b/tv/tuner/1.0/vts/functional/FilterTests.h index c61fa18c3c..7bc4832171 100644 --- a/tv/tuner/1.0/vts/functional/FilterTests.h +++ b/tv/tuner/1.0/vts/functional/FilterTests.h @@ -66,17 +66,6 @@ using ::testing::AssertionResult; using namespace std; -enum FilterEventType : uint8_t { - UNDEFINED, - SECTION, - MEDIA, - PES, - RECORD, - MMTPRECORD, - DOWNLOAD, - TEMI, -}; - using FilterMQ = MessageQueue; using MQDesc = MQDescriptorSync; @@ -104,7 +93,6 @@ class FilterCallback : public IFilterCallback { void setFilterId(uint32_t filterId) { mFilterId = filterId; } void setFilterInterface(sp filter) { mFilter = filter; } - void setFilterEventType(FilterEventType type) { mFilterEventType = type; } void testFilterDataOutput(); @@ -130,7 +118,6 @@ class FilterCallback : public IFilterCallback { uint32_t mFilterId; sp mFilter; - FilterEventType mFilterEventType; std::unique_ptr mFilterMQ; EventFlag* mFilterMQEventFlag; DemuxFilterEvent mFilterEvent; @@ -168,53 +155,6 @@ class FilterTests { AssertionResult closeFilter(uint32_t filterId); AssertionResult closeTimeFilter(); - FilterEventType getFilterEventType(DemuxFilterType type) { - FilterEventType eventType = FilterEventType::UNDEFINED; - switch (type.mainType) { - case DemuxFilterMainType::TS: - switch (type.subType.tsFilterType()) { - case DemuxTsFilterType::UNDEFINED: - break; - case DemuxTsFilterType::SECTION: - eventType = FilterEventType::SECTION; - break; - case DemuxTsFilterType::PES: - eventType = FilterEventType::PES; - break; - case DemuxTsFilterType::TS: - break; - case DemuxTsFilterType::AUDIO: - case DemuxTsFilterType::VIDEO: - eventType = FilterEventType::MEDIA; - break; - case DemuxTsFilterType::PCR: - break; - case DemuxTsFilterType::RECORD: - eventType = FilterEventType::RECORD; - break; - case DemuxTsFilterType::TEMI: - eventType = FilterEventType::TEMI; - break; - } - break; - case DemuxFilterMainType::MMTP: - /*mmtpSettings*/ - break; - case DemuxFilterMainType::IP: - /*ipSettings*/ - break; - case DemuxFilterMainType::TLV: - /*tlvSettings*/ - break; - case DemuxFilterMainType::ALP: - /*alpSettings*/ - break; - default: - break; - } - return eventType; - } - protected: static AssertionResult failure() { return ::testing::AssertionFailure(); } diff --git a/tv/tuner/1.1/default/Filter.cpp b/tv/tuner/1.1/default/Filter.cpp index 884b5077a0..aec1fd0576 100644 --- a/tv/tuner/1.1/default/Filter.cpp +++ b/tv/tuner/1.1/default/Filter.cpp @@ -145,26 +145,36 @@ Return Filter::start() { case DemuxFilterMainType::TS: mCallback->onFilterEvent(createMediaEvent()); mCallback->onFilterEvent(createTsRecordEvent()); - mCallback_1_1->onFilterEvent_1_1(createTsRecordEvent(), createTsRecordEventExt()); mCallback->onFilterEvent(createTemiEvent()); + // clients could still pass 1.0 callback + if (mCallback_1_1 != NULL) { + mCallback_1_1->onFilterEvent_1_1(createTsRecordEvent(), createTsRecordEventExt()); + } break; case DemuxFilterMainType::MMTP: mCallback->onFilterEvent(createDownloadEvent()); mCallback->onFilterEvent(createMmtpRecordEvent()); - mCallback_1_1->onFilterEvent_1_1(createMmtpRecordEvent(), createMmtpRecordEventExt()); + if (mCallback_1_1 != NULL) { + mCallback_1_1->onFilterEvent_1_1(createMmtpRecordEvent(), + createMmtpRecordEventExt()); + } break; case DemuxFilterMainType::IP: mCallback->onFilterEvent(createSectionEvent()); mCallback->onFilterEvent(createIpPayloadEvent()); break; case DemuxFilterMainType::TLV: { - DemuxFilterEvent emptyFilterEvent; - mCallback_1_1->onFilterEvent_1_1(emptyFilterEvent, createMonitorEvent()); + if (mCallback_1_1 != NULL) { + DemuxFilterEvent emptyFilterEvent; + mCallback_1_1->onFilterEvent_1_1(emptyFilterEvent, createMonitorEvent()); + } break; } case DemuxFilterMainType::ALP: { - DemuxFilterEvent emptyFilterEvent; - mCallback_1_1->onFilterEvent_1_1(emptyFilterEvent, createRestartEvent()); + if (mCallback_1_1 != NULL) { + DemuxFilterEvent emptyFilterEvent; + mCallback_1_1->onFilterEvent_1_1(emptyFilterEvent, createRestartEvent()); + } break; } default: @@ -967,7 +977,6 @@ DemuxFilterEvent Filter::createMediaEvent() { .dataLength = 3, .offset = 4, .isSecureMemory = true, - .avDataId = 5, .mpuSequenceNumber = 6, .isPesPrivateData = true, }); @@ -988,9 +997,16 @@ DemuxFilterEvent Filter::createMediaEvent() { native_handle_t* nativeHandle = createNativeHandle(av_fd); if (nativeHandle == NULL) { + ::close(av_fd); + ALOGE("[Filter] Failed to create native_handle %d", errno); return event; } + // Create a dataId and add a pair into the dataId2Avfd map + uint64_t dataId = mLastUsedDataId++ /*createdUID*/; + mDataId2Avfd[dataId] = dup(av_fd); + event.events[0].media().avDataId = dataId; + hidl_handle handle; handle.setTo(nativeHandle, /*shouldOwn=*/true); event.events[0].media().avMemory = std::move(handle); diff --git a/tv/tuner/1.1/default/Frontend.cpp b/tv/tuner/1.1/default/Frontend.cpp index 0f6784bd31..e3fbdadc3f 100644 --- a/tv/tuner/1.1/default/Frontend.cpp +++ b/tv/tuner/1.1/default/Frontend.cpp @@ -88,18 +88,6 @@ Return Frontend::stopTune() { Return Frontend::scan(const FrontendSettings& settings, FrontendScanType type) { ALOGV("%s", __FUNCTION__); - - if (mType == FrontendType::ATSC) { - FrontendScanMessage msg; - msg.isLocked(true); - mCallback->onScanMessage(FrontendScanMessageType::LOCKED, msg); - mIsLocked = true; - return Result::SUCCESS; - } - if (mType != FrontendType::DVBT) { - return Result::UNAVAILABLE; - } - FrontendScanMessage msg; if (mIsLocked) { @@ -108,15 +96,96 @@ Return Frontend::scan(const FrontendSettings& settings, FrontendScanType return Result::SUCCESS; } - uint32_t frequency = settings.dvbt().frequency; + uint32_t frequency; + switch (settings.getDiscriminator()) { + case FrontendSettings::hidl_discriminator::analog: + frequency = settings.analog().frequency; + break; + case FrontendSettings::hidl_discriminator::atsc: + frequency = settings.atsc().frequency; + break; + case FrontendSettings::hidl_discriminator::atsc3: + frequency = settings.atsc3().frequency; + break; + case FrontendSettings::hidl_discriminator::dvbs: + frequency = settings.dvbs().frequency; + break; + case FrontendSettings::hidl_discriminator::dvbc: + frequency = settings.dvbc().frequency; + break; + case FrontendSettings::hidl_discriminator::dvbt: + frequency = settings.dvbt().frequency; + break; + case FrontendSettings::hidl_discriminator::isdbs: + frequency = settings.isdbs().frequency; + break; + case FrontendSettings::hidl_discriminator::isdbs3: + frequency = settings.isdbs3().frequency; + break; + case FrontendSettings::hidl_discriminator::isdbt: + frequency = settings.isdbt().frequency; + break; + } + if (type == FrontendScanType::SCAN_BLIND) { frequency += 100; } + msg.frequencies({frequency}); mCallback->onScanMessage(FrontendScanMessageType::FREQUENCY, msg); - msg.isLocked(true); - mCallback->onScanMessage(FrontendScanMessageType::LOCKED, msg); - mIsLocked = true; + + msg.progressPercent(20); + mCallback->onScanMessage(FrontendScanMessageType::PROGRESS_PERCENT, msg); + + msg.symbolRates({30}); + mCallback->onScanMessage(FrontendScanMessageType::SYMBOL_RATE, msg); + + if (mType == FrontendType::DVBT) { + msg.hierarchy(FrontendDvbtHierarchy::HIERARCHY_NON_NATIVE); + mCallback->onScanMessage(FrontendScanMessageType::HIERARCHY, msg); + } + + if (mType == FrontendType::ANALOG) { + msg.analogType(FrontendAnalogType::PAL); + mCallback->onScanMessage(FrontendScanMessageType::ANALOG_TYPE, msg); + } + + msg.plpIds({3}); + mCallback->onScanMessage(FrontendScanMessageType::PLP_IDS, msg); + + msg.groupIds({2}); + mCallback->onScanMessage(FrontendScanMessageType::GROUP_IDS, msg); + + msg.inputStreamIds({1}); + mCallback->onScanMessage(FrontendScanMessageType::INPUT_STREAM_IDS, msg); + + FrontendScanMessage::Standard s; + switch (mType) { + case FrontendType::DVBT: + s.tStd(FrontendDvbtStandard::AUTO); + msg.std(s); + mCallback->onScanMessage(FrontendScanMessageType::STANDARD, msg); + break; + case FrontendType::DVBS: + s.sStd(FrontendDvbsStandard::AUTO); + msg.std(s); + mCallback->onScanMessage(FrontendScanMessageType::STANDARD, msg); + break; + case FrontendType::ANALOG: + s.sifStd(FrontendAnalogSifStandard::AUTO); + msg.std(s); + mCallback->onScanMessage(FrontendScanMessageType::STANDARD, msg); + break; + default: + break; + } + + FrontendScanAtsc3PlpInfo info{ + .plpId = 1, + .bLlsFlag = false, + }; + msg.atsc3PlpInfos({info}); + mCallback->onScanMessage(FrontendScanMessageType::ATSC3_PLP_INFO, msg); sp frontendCallback_v1_1 = V1_1::IFrontendCallback::castFrom(mCallback); @@ -129,15 +198,20 @@ Return Frontend::scan(const FrontendSettings& settings, FrontendScanType frontendCallback_v1_1->onScanMessageExt1_1( V1_1::FrontendScanMessageTypeExt1_1::HIGH_PRIORITY, msg); } else { - ALOGD("[Filter] Couldn't cast to V1_1 IFrontendCallback"); + ALOGD("[Frontend] Couldn't cast to V1_1 IFrontendCallback"); } + msg.isLocked(true); + mCallback->onScanMessage(FrontendScanMessageType::LOCKED, msg); + mIsLocked = true; + return Result::SUCCESS; } Return Frontend::scan_1_1(const FrontendSettings& settings, FrontendScanType type, - const V1_1::FrontendSettingsExt1_1& /*settingsExt1_1*/) { + const V1_1::FrontendSettingsExt1_1& settingsExt1_1) { ALOGV("%s", __FUNCTION__); + ALOGD("[Frontend] scan_1_1 end frequency %d", settingsExt1_1.endFrequency); return scan(settings, type); } -- GitLab From 5feda3d112892e86293eec08f8d350c19c12093f Mon Sep 17 00:00:00 2001 From: Haining Chen Date: Tue, 23 Feb 2021 13:58:58 -0800 Subject: [PATCH 497/790] Update sensor properties: (1) Add software information (eg, matching and PAD algorithm versions) (2) Remove firmware version from hardware information Bug: 156024031 Test: m -j android.hardware.biometrics.common-update-api Test: m -j android.hardware.biometrics.face-update-api Test: m -j android.hardware.biometrics.face-service.example Test: m -j android.hardware.biometrics.fingerprint-update-api Test: m -j android.hardware.biometrics.fingerprint-service.example Change-Id: I7fb5a31562152d621feed4d775beb14dab3a5fed --- .../android/hardware/biometrics/common/CommonProps.aidl | 4 +++- .../android/hardware/biometrics/common/HardwareInfo.aidl | 4 ++-- .../hardware/biometrics/common/ICancellationSignal.aidl | 3 ++- .../hardware/biometrics/common/SensorStrength.aidl | 3 ++- .../android/hardware/biometrics/common/CommonProps.aidl | 9 +++++++++ .../android/hardware/biometrics/common/HardwareInfo.aidl | 7 +------ .../android/hardware/biometrics/face/AcquiredInfo.aidl | 3 ++- .../hardware/biometrics/face/AuthenticationFrame.aidl | 3 ++- .../android/hardware/biometrics/face/BaseFrame.aidl | 3 ++- .../current/android/hardware/biometrics/face/Cell.aidl | 3 ++- .../hardware/biometrics/face/EnrollmentFrame.aidl | 3 ++- .../hardware/biometrics/face/EnrollmentStage.aidl | 3 ++- .../hardware/biometrics/face/EnrollmentStageConfig.aidl | 3 ++- .../android/hardware/biometrics/face/EnrollmentType.aidl | 3 ++- .../current/android/hardware/biometrics/face/Error.aidl | 3 ++- .../android/hardware/biometrics/face/FaceSensorType.aidl | 8 +++++--- .../android/hardware/biometrics/face/Feature.aidl | 3 ++- .../current/android/hardware/biometrics/face/IFace.aidl | 3 ++- .../android/hardware/biometrics/face/ISession.aidl | 3 ++- .../hardware/biometrics/face/ISessionCallback.aidl | 3 ++- .../android/hardware/biometrics/face/SensorProps.aidl | 3 ++- .../android/hardware/biometrics/face/SessionState.aidl | 3 ++- .../android/hardware/biometrics/face/FaceSensorType.aidl | 7 +------ biometrics/face/aidl/default/Face.cpp | 4 ++-- .../hardware/biometrics/fingerprint/AcquiredInfo.aidl | 3 ++- .../android/hardware/biometrics/fingerprint/Error.aidl | 3 ++- .../biometrics/fingerprint/FingerprintSensorType.aidl | 3 ++- .../hardware/biometrics/fingerprint/IFingerprint.aidl | 3 ++- .../hardware/biometrics/fingerprint/ISession.aidl | 3 ++- .../biometrics/fingerprint/ISessionCallback.aidl | 3 ++- .../hardware/biometrics/fingerprint/SensorLocation.aidl | 3 ++- .../hardware/biometrics/fingerprint/SensorProps.aidl | 3 ++- .../hardware/biometrics/fingerprint/SessionState.aidl | 3 ++- biometrics/fingerprint/aidl/default/Fingerprint.cpp | 7 +++---- 34 files changed, 78 insertions(+), 50 deletions(-) diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/CommonProps.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/CommonProps.aidl index 30959b10e7..4b4e7df146 100644 --- a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/CommonProps.aidl +++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/CommonProps.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. // /////////////////////////////////////////////////////////////////////////////// @@ -37,4 +38,5 @@ parcelable CommonProps { android.hardware.biometrics.common.SensorStrength sensorStrength = android.hardware.biometrics.common.SensorStrength.CONVENIENCE; int maxEnrollmentsPerUser; android.hardware.biometrics.common.HardwareInfo[] hardwareInfo; + String softwareInfo; } diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/HardwareInfo.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/HardwareInfo.aidl index 8fea864986..c5288fdae5 100644 --- a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/HardwareInfo.aidl +++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/HardwareInfo.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. // /////////////////////////////////////////////////////////////////////////////// @@ -35,6 +36,5 @@ package android.hardware.biometrics.common; parcelable HardwareInfo { String deviceName; String hardwareVersion; - String firmwareVersion; String serialNumber; } diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/ICancellationSignal.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/ICancellationSignal.aidl index b85a590612..2bc6a6df05 100644 --- a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/ICancellationSignal.aidl +++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/ICancellationSignal.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/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/SensorStrength.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/SensorStrength.aidl index 3b20c9aa98..6675d091e5 100644 --- a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/SensorStrength.aidl +++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/SensorStrength.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/biometrics/common/aidl/android/hardware/biometrics/common/CommonProps.aidl b/biometrics/common/aidl/android/hardware/biometrics/common/CommonProps.aidl index 59f398ef4e..7c3d511360 100644 --- a/biometrics/common/aidl/android/hardware/biometrics/common/CommonProps.aidl +++ b/biometrics/common/aidl/android/hardware/biometrics/common/CommonProps.aidl @@ -44,4 +44,13 @@ parcelable CommonProps { * A list of hardware information for subsystems that pertain to this biometric sensor. */ HardwareInfo[] hardwareInfo; + + /** + * Software information for subsystems that pertain to this biometric sensor. + * This may include information for the matching algorithm, the PAD (Presentation Attack + * Detection) algorithm, and any other algorithm(s) used by this biometric sensor. + * For example, ;;. + * The format of each algorithm's info can be //. + */ + String softwareInfo; } diff --git a/biometrics/common/aidl/android/hardware/biometrics/common/HardwareInfo.aidl b/biometrics/common/aidl/android/hardware/biometrics/common/HardwareInfo.aidl index 23f0202542..ce9e354dd3 100644 --- a/biometrics/common/aidl/android/hardware/biometrics/common/HardwareInfo.aidl +++ b/biometrics/common/aidl/android/hardware/biometrics/common/HardwareInfo.aidl @@ -28,13 +28,8 @@ parcelable HardwareInfo { */ String hardwareVersion; - /** - * The firmware version. - */ - String firmwareVersion; - /** * The sensor's serial number. */ String serialNumber; -} \ No newline at end of file +} diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl index 8fd6c5f9a8..2600e61bee 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.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/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AuthenticationFrame.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AuthenticationFrame.aidl index a9e4de3bc3..20bc76779b 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AuthenticationFrame.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AuthenticationFrame.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/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/BaseFrame.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/BaseFrame.aidl index 99397051f2..aa51343281 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/BaseFrame.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/BaseFrame.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/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Cell.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Cell.aidl index cc2bf53c1d..6be8c8e975 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Cell.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Cell.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/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentFrame.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentFrame.aidl index cb9a6c682b..982e759180 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentFrame.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentFrame.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/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStage.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStage.aidl index fefac68ad6..6be6e0bbdd 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStage.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStage.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/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStageConfig.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStageConfig.aidl index f55aafdb7c..232bd52813 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStageConfig.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStageConfig.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/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentType.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentType.aidl index 3603c4e08c..8e99ad6529 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentType.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentType.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/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Error.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Error.aidl index 7992f9973a..0437f0708c 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Error.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Error.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/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/FaceSensorType.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/FaceSensorType.aidl index 481b678157..a215b99f72 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/FaceSensorType.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/FaceSensorType.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. // /////////////////////////////////////////////////////////////////////////////// @@ -33,6 +34,7 @@ package android.hardware.biometrics.face; @Backing(type="byte") @VintfStability enum FaceSensorType { - RGB = 0, - IR = 1, + UNKNOWN = 0, + RGB = 1, + IR = 2, } diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Feature.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Feature.aidl index d9e561d518..a8faf06a26 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Feature.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Feature.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/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl index bfaf90d0e1..0d1ef45d8e 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.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/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 c9165e1ab6..4aef61a0a5 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 @@ -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/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl index 6127c7b956..d6ebbb6208 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.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/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl index 69355fbe69..c55a600eed 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.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/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SessionState.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SessionState.aidl index 3792eae17f..4db47c9c67 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SessionState.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SessionState.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/biometrics/face/aidl/android/hardware/biometrics/face/FaceSensorType.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/FaceSensorType.aidl index 2a5dd20be1..57f39d4f51 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/FaceSensorType.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/FaceSensorType.aidl @@ -16,9 +16,4 @@ package android.hardware.biometrics.face; -@VintfStability -@Backing(type="byte") -enum FaceSensorType { - RGB, - IR -} +@VintfStability @Backing(type="byte") enum FaceSensorType { UNKNOWN, RGB, IR } diff --git a/biometrics/face/aidl/default/Face.cpp b/biometrics/face/aidl/default/Face.cpp index 2b4085054b..73e50f3151 100644 --- a/biometrics/face/aidl/default/Face.cpp +++ b/biometrics/face/aidl/default/Face.cpp @@ -26,14 +26,13 @@ const FaceSensorType kSensorType = FaceSensorType::RGB; const bool kHalControlsPreview = true; const std::string kHwDeviceName = "faceSensor"; const std::string kHardwareVersion = "vendor/model/revision"; -const std::string kFirmwareVersion = "1.01"; const std::string kSerialNumber = "00000001"; +const std::string kSoftwareVersion = "vendor1/algorithm1/version;vendor2/algorithm2/version"; ndk::ScopedAStatus Face::getSensorProps(std::vector* return_val) { common::HardwareInfo hardware_info; hardware_info.deviceName = kHwDeviceName; hardware_info.hardwareVersion = kHardwareVersion; - hardware_info.firmwareVersion = kFirmwareVersion; hardware_info.serialNumber = kSerialNumber; common::CommonProps commonProps; @@ -41,6 +40,7 @@ ndk::ScopedAStatus Face::getSensorProps(std::vector* return_val) { commonProps.sensorStrength = kSensorStrength; commonProps.maxEnrollmentsPerUser = kMaxEnrollmentsPerUser; commonProps.hardwareInfo = {std::move(hardware_info)}; + commonProps.softwareInfo = kSoftwareVersion; SensorProps props; props.commonProps = std::move(commonProps); diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl index 189095a7d7..31d9a9022d 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.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/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl index cdbc2d2f67..f79c576fb1 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.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/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl index c81cad2971..9c208c4e7c 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/FingerprintSensorType.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/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl index 2d44528f2e..07777c991b 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.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/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 b583006d46..cade76dcb7 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 @@ -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/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl index f20f15324e..13c2b05081 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.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/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorLocation.aidl index a6e8b4d245..515ddaa358 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorLocation.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorLocation.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/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl index 00cbb6da86..c7a4002c11 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.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/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.aidl index 05dd85bbfd..9b0b6f6a77 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.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/biometrics/fingerprint/aidl/default/Fingerprint.cpp b/biometrics/fingerprint/aidl/default/Fingerprint.cpp index 802808911c..206f5187e9 100644 --- a/biometrics/fingerprint/aidl/default/Fingerprint.cpp +++ b/biometrics/fingerprint/aidl/default/Fingerprint.cpp @@ -28,8 +28,8 @@ constexpr FingerprintSensorType SENSOR_TYPE = FingerprintSensorType::REAR; constexpr bool SUPPORTS_NAVIGATION_GESTURES = true; constexpr char HW_DEVICE_NAME[] = "fingerprintSensor"; constexpr char HW_VERSION[] = "vendor/model/revision"; -constexpr char FW_VERSION[] = "1.01"; constexpr char SERIAL_NUMBER[] = "00000001"; +constexpr char SW_VERSION[] = "vendor1/algorithm1/version;vendor2/algorithm2/version"; } // namespace @@ -37,11 +37,10 @@ Fingerprint::Fingerprint() : mEngine(std::make_unique()), mWorker(MAX_WORKER_QUEUE_SIZE) {} ndk::ScopedAStatus Fingerprint::getSensorProps(std::vector* out) { - std::vector hardwareInfos = { - {HW_DEVICE_NAME, HW_VERSION, FW_VERSION, SERIAL_NUMBER}}; + std::vector hardwareInfos = {{HW_DEVICE_NAME, HW_VERSION, SERIAL_NUMBER}}; common::CommonProps commonProps = {SENSOR_ID, SENSOR_STRENGTH, MAX_ENROLLMENTS_PER_USER, - hardwareInfos}; + hardwareInfos, SW_VERSION}; SensorLocation sensorLocation = {0 /* displayId */, 0 /* sensorLocationX */, 0 /* sensorLocationY */, 0 /* sensorRadius */}; -- GitLab From 3965b93b928766047cbbcc5411e2aefd10f04b8a Mon Sep 17 00:00:00 2001 From: Kevin Chyn Date: Mon, 1 Mar 2021 17:01:14 -0800 Subject: [PATCH 498/790] Add biometrics/common/aidl OWNERS Test: Presubmit Fixes: 181615425 Change-Id: Id31d953796b8e3926cd98b79ba189e9748217aec --- biometrics/common/aidl/OWNERS | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 biometrics/common/aidl/OWNERS diff --git a/biometrics/common/aidl/OWNERS b/biometrics/common/aidl/OWNERS new file mode 100644 index 0000000000..36d726136f --- /dev/null +++ b/biometrics/common/aidl/OWNERS @@ -0,0 +1,2 @@ +ilyamaty@google.com +kchyn@google.com -- GitLab From b471a062f9fc90eefec70d3179f3fc964977ef72 Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Tue, 2 Mar 2021 16:02:34 +0800 Subject: [PATCH 499/790] wifi: add comment for SAE_PK capability Bug: 181603483 Test: atest VtsHalWifiSupplicantV1_4TargetTest Change-Id: If66f1ad0b3c44190beacb48c988c47fe8767bfee --- wifi/supplicant/1.4/types.hal | 1 + 1 file changed, 1 insertion(+) diff --git a/wifi/supplicant/1.4/types.hal b/wifi/supplicant/1.4/types.hal index aec61c4121..c39de6ead6 100644 --- a/wifi/supplicant/1.4/types.hal +++ b/wifi/supplicant/1.4/types.hal @@ -104,6 +104,7 @@ struct SupplicantStatus { */ enum WpaDriverCapabilitiesMask : @1.3::WpaDriverCapabilitiesMask { /** + * WPA3 SAE Public-Key. */ SAE_PK = 1 << 2, }; -- GitLab From 1ca75eca0253e0b343c74c1b450c87bec23a48e4 Mon Sep 17 00:00:00 2001 From: Kevin Chyn Date: Tue, 2 Mar 2021 16:19:11 -0800 Subject: [PATCH 500/790] Add IFingerprint AcquiredInfo.IMMOBILE Fixes: 181278306 Test: make -j android.hardware.biometrics.fingerprint-update-api Change-Id: I1ad9156ecfd2bf0b9efcb7a78871ca27aa97f7b7 --- .../hardware/biometrics/fingerprint/AcquiredInfo.aidl | 4 +++- .../android/hardware/biometrics/fingerprint/Error.aidl | 3 ++- .../biometrics/fingerprint/FingerprintSensorType.aidl | 3 ++- .../hardware/biometrics/fingerprint/IFingerprint.aidl | 3 ++- .../android/hardware/biometrics/fingerprint/ISession.aidl | 3 ++- .../hardware/biometrics/fingerprint/ISessionCallback.aidl | 3 ++- .../hardware/biometrics/fingerprint/SensorLocation.aidl | 3 ++- .../hardware/biometrics/fingerprint/SensorProps.aidl | 3 ++- .../hardware/biometrics/fingerprint/SessionState.aidl | 3 ++- .../hardware/biometrics/fingerprint/AcquiredInfo.aidl | 7 +++++++ 10 files changed, 26 insertions(+), 9 deletions(-) diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl index 189095a7d7..a8e73fc82c 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.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. // /////////////////////////////////////////////////////////////////////////////// @@ -43,4 +44,5 @@ enum AcquiredInfo { START = 7, TOO_DARK = 8, TOO_BRIGHT = 9, + IMMOBILE = 10, } diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl index cdbc2d2f67..f79c576fb1 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.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/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl index c81cad2971..9c208c4e7c 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/FingerprintSensorType.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/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl index 2d44528f2e..07777c991b 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.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/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 b583006d46..cade76dcb7 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 @@ -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/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl index f20f15324e..13c2b05081 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.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/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorLocation.aidl index a6e8b4d245..515ddaa358 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorLocation.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorLocation.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/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl index 53ac6dd917..93d49a4579 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.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/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.aidl index 05dd85bbfd..9b0b6f6a77 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.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/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl index 3709a64b78..bf11daa817 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl @@ -75,5 +75,12 @@ enum AcquiredInfo { * the image was too bright to be used for matching. */ TOO_BRIGHT, + + /** + * This message may be sent during enrollment if the same area of the finger has already + * been captured during this enrollment session. In general, enrolling multiple areas of the + * same finger can help against false rejections. + */ + IMMOBILE, } -- GitLab From 1fd7bc32838936f4ecc9bd822cdfa350331925e2 Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Tue, 2 Mar 2021 23:43:25 +0800 Subject: [PATCH 501/790] wifi: change H2E mode API arguemnt to tri-state enumeration Bug: 180532458 Test: atest VtsHalWifiSupplicantV1_4TargetTest Change-Id: Ibba7bf26e7bbe45cadc45c0e68d9fd56f4034923 --- wifi/supplicant/1.4/ISupplicantStaNetwork.hal | 30 +++++++++++++------ .../supplicant_sta_network_hidl_test.cpp | 27 ++++++++++++----- 2 files changed, 40 insertions(+), 17 deletions(-) diff --git a/wifi/supplicant/1.4/ISupplicantStaNetwork.hal b/wifi/supplicant/1.4/ISupplicantStaNetwork.hal index 6bed5ab887..4f95213223 100644 --- a/wifi/supplicant/1.4/ISupplicantStaNetwork.hal +++ b/wifi/supplicant/1.4/ISupplicantStaNetwork.hal @@ -54,6 +54,24 @@ interface ISupplicantStaNetwork extends @1.3::ISupplicantStaNetwork { GCMP_128 = 1 << 9, }; + /** + * SAE Hash-to-Element mode. + */ + enum SaeH2eMode : uint8_t { + /** + * Hash-to-Element is disabled, only Hunting & Pecking is allowed. + */ + DISABLED, + /** + * Both Hash-to-Element and Hunting & Pecking are allowed. + */ + H2E_OPTIONAL, + /** + * Only Hash-to-Element is allowed. + */ + H2E_MANDATORY, + }; + /** * Set group cipher mask for the network. * @@ -154,22 +172,16 @@ interface ISupplicantStaNetwork extends @1.3::ISupplicantStaNetwork { generates (SupplicantStatus status); /** - * Set whether to enable SAE H2E (Hash-to-Element) only mode. - * - * When enabled, only SAE H2E network is allowed; othewise - * H&P (Hunting and Pecking) and H2E are both allowed. - * H&P only mode is not supported. - * If this API is not called before connecting to a SAE - * network, the behavior is undefined. + * Set SAE H2E (Hash-to-Element) mode. * - * @param enable true to set, false otherwise. + * @param mode SAE H2E supporting mode. * @return status Status of the operation. * Possible status codes: * |SupplicantStatusCode.SUCCESS|, * |SupplicantStatusCode.FAILURE_UNKNOWN|, * |SupplicantStatusCode.FAILURE_NETWORK_INVALID| */ - enableSaeH2eOnlyMode(bool enable) generates (SupplicantStatus status); + setSaeH2eMode(SaeH2eMode mode) generates (SupplicantStatus status); /** * Set whether to enable SAE PK (Public Key) only mode to enable public AP validation. diff --git a/wifi/supplicant/1.4/vts/functional/supplicant_sta_network_hidl_test.cpp b/wifi/supplicant/1.4/vts/functional/supplicant_sta_network_hidl_test.cpp index 0e38c4b26b..e3fbaf36f1 100644 --- a/wifi/supplicant/1.4/vts/functional/supplicant_sta_network_hidl_test.cpp +++ b/wifi/supplicant/1.4/vts/functional/supplicant_sta_network_hidl_test.cpp @@ -42,6 +42,8 @@ using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatusCode; using ::android::hardware::wifi::supplicant::V1_4:: ISupplicantStaNetworkCallback; using ::android::hardware::wifi::V1_0::IWifi; +using ISupplicantStaNetworkV1_4 = + ::android::hardware::wifi::supplicant::V1_4::ISupplicantStaNetwork; using SupplicantStatusV1_4 = ::android::hardware::wifi::supplicant::V1_4::SupplicantStatus; using SupplicantStatusCodeV1_4 = @@ -110,15 +112,24 @@ TEST_P(SupplicantStaNetworkHidlTest, RegisterCallback_1_4) { } /* - * enable SAE H2E (Hash-to-Element) only mode + * set SAE H2E (Hash-to-Element) mode */ -TEST_P(SupplicantStaNetworkHidlTest, EnableSaeH2eOnlyMode) { - v1_4->enableSaeH2eOnlyMode(true, [&](const SupplicantStatusV1_4& status) { - EXPECT_EQ(SupplicantStatusCodeV1_4::SUCCESS, status.code); - }); - v1_4->enableSaeH2eOnlyMode(false, [&](const SupplicantStatusV1_4& status) { - EXPECT_EQ(SupplicantStatusCodeV1_4::SUCCESS, status.code); - }); +TEST_P(SupplicantStaNetworkHidlTest, SetSaeH2eMode) { + v1_4->setSaeH2eMode(ISupplicantStaNetworkV1_4::SaeH2eMode::DISABLED, + [&](const SupplicantStatusV1_4& status) { + EXPECT_EQ(SupplicantStatusCodeV1_4::SUCCESS, + status.code); + }); + v1_4->setSaeH2eMode(ISupplicantStaNetworkV1_4::SaeH2eMode::H2E_MANDATORY, + [&](const SupplicantStatusV1_4& status) { + EXPECT_EQ(SupplicantStatusCodeV1_4::SUCCESS, + status.code); + }); + v1_4->setSaeH2eMode(ISupplicantStaNetworkV1_4::SaeH2eMode::H2E_OPTIONAL, + [&](const SupplicantStatusV1_4& status) { + EXPECT_EQ(SupplicantStatusCodeV1_4::SUCCESS, + status.code); + }); } /* -- GitLab From b816f26bbcf137a08c6149467f349b8ac8e61cba Mon Sep 17 00:00:00 2001 From: Kai Date: Wed, 9 Dec 2020 22:01:20 -0800 Subject: [PATCH 502/790] Add EVS_SERVICE_REQUEST property Add EVS_SERVICE_REQUEST property to let android trigger the EVS service Bug: 173759534 Test: check the property in KitchenSink Change-Id: I219eecadfea1ca5fca281d51bd9bc45589e5b9ef Merged-In: I219eecadfea1ca5fca281d51bd9bc45589e5b9ef (cherry picked from commit b479e5704ac2a5b2b7293ab44ac5f1bd1d4d6b8e) --- .../default/impl/vhal_v2_0/DefaultConfig.h | 9 ++++ automotive/vehicle/2.0/types.hal | 50 +++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h index 73513f4e4c..5915a53c03 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h @@ -996,6 +996,15 @@ const ConfigDeclaration kVehicleProperties[]{ }, .initialValue = {.int32Values = {LIGHT_SWITCH_AUTO}}}, + {.config = + { + .prop = toInt(VehicleProperty::EVS_SERVICE_REQUEST), + .access = VehiclePropertyAccess::READ, + .changeMode = VehiclePropertyChangeMode::ON_CHANGE, + }, + .initialValue = {.int32Values = {toInt(EvsServiceType::REARVIEW), + toInt(EvsServiceState::OFF)}}}, + {.config = {.prop = VEHICLE_MAP_SERVICE, .access = VehiclePropertyAccess::READ_WRITE, .changeMode = VehiclePropertyChangeMode::ON_CHANGE}}, diff --git a/automotive/vehicle/2.0/types.hal b/automotive/vehicle/2.0/types.hal index e3fd16de57..0eb73a7a9e 100644 --- a/automotive/vehicle/2.0/types.hal +++ b/automotive/vehicle/2.0/types.hal @@ -2926,6 +2926,29 @@ enum VehicleProperty : int32_t { | VehiclePropertyType:MIXED | VehicleArea:GLOBAL), + /** + * Enable/request an EVS service. + * + * The property provides a generalized way to trigger EVS services. VHAL + * should use this property to request Android to start or stop EVS service. + * + * int32Values[0] = a type of the EVS service. The value must be one of enums in + * EvsServiceType. + * int32Values[1] = the state of the EVS service. The value must be one of enums in + * EvsServiceState. + * + * For example, to enable rear view EVS service, android side can set the property value as + * [EvsServiceType::REAR_VIEW, EvsServiceState::ON]. + * + * @change_mode VehiclePropertyChangeMode:ON_CHANGE + * @access VehiclePropertyAccess:READ + */ + EVS_SERVICE_REQUEST = ( + 0x0F10 + | VehiclePropertyGroup:SYSTEM + | VehiclePropertyType:INT32_VEC + | VehicleArea:GLOBAL), + /** * Defines a request to apply power policy. * @@ -3212,6 +3235,33 @@ enum VehicleSeatOccupancyState : int32_t { OCCUPIED = 2 }; +/** + * Used by EVS_SERVICE_REQUEST to enumerate the service's type. + */ +enum EvsServiceType : int32_t { + + REARVIEW = 0, + SURROUNDVIEW = 1, +}; + +/** + * Used by EVS_SERVICE_REQUEST to enumerate the service's state. + */ +enum EvsServiceState : int32_t { + + OFF = 0, + ON = 1, +}; + +/** + * Index in int32VAlues for VehicleProperty#EVS_SERVICE_REQUEST property. + */ +enum EvsServiceRequestIndex : int32_t { + + TYPE = 0, + STATE = 1, +}; + /** * Used by lights state properties to enumerate the current state of the lights. * -- GitLab From 7bce01c3b3e71d10555478293bdf3ece90e10ccf Mon Sep 17 00:00:00 2001 From: Robert Shih Date: Wed, 3 Mar 2021 02:26:47 -0800 Subject: [PATCH 503/790] drm@1.4 status: add PROVISIONING_REQUEST_REJECTED Bug: 180579631 Test: VtsHalDrmV1_4TargetTest Change-Id: Ia427924c94eb3dfe4f91f15ef94136d599c67414 --- drm/1.4/types.hal | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drm/1.4/types.hal b/drm/1.4/types.hal index 17eba8a08f..a4490a543e 100644 --- a/drm/1.4/types.hal +++ b/drm/1.4/types.hal @@ -118,6 +118,10 @@ enum Status : @1.2::Status { * 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. -- GitLab From 8c1a67b7af5851a01fedf087bfd998afdbcfeaaa Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Tue, 2 Mar 2021 10:00:23 -0800 Subject: [PATCH 504/790] wifi: Wait for driver ready and bring up the interface when setMacAddress fails setMacAddress may fail in some scenarios like SSR inprogress. In such case framework is not bringing up the iface again if it was brought down to set random MAC address. Due to this subsequent operations like scans are failing with "Network Down" error and Wi-Fi can't recover until Wi-Fi restarts. To avoid this bring up the iface irrespective of setMacAddress status. Modified the original CL to move the WifiIfaceUtil creation to inside Wifi object since that is where the legacy HAL instance is created for the corresponding chip. This helps keeping the setMacAddress logic still inside WifiIfaceUtil. Modified the iface_util lifetime - no longer a singleton, one instance created per wifi chip instance. Bug: 174183763 Test: Wifi can be enabled when back-to-back SSR and wifi on Change-Id: I926b59f5da126aba222e05d1e570c0c19de739ed --- wifi/1.5/default/service.cpp | 2 -- .../default/tests/mock_wifi_iface_util.cpp | 5 ++-- wifi/1.5/default/tests/mock_wifi_iface_util.h | 3 +- wifi/1.5/default/tests/mock_wifi_legacy_hal.h | 1 + .../default/tests/wifi_chip_unit_tests.cpp | 2 +- .../tests/wifi_iface_util_unit_tests.cpp | 7 ++++- .../tests/wifi_nan_iface_unit_tests.cpp | 2 +- wifi/1.5/default/wifi.cpp | 5 ++-- wifi/1.5/default/wifi.h | 2 -- wifi/1.5/default/wifi_chip.cpp | 19 ++++++------ wifi/1.5/default/wifi_chip.h | 4 +-- wifi/1.5/default/wifi_iface_util.cpp | 30 +++++++++++++------ wifi/1.5/default/wifi_iface_util.h | 6 +++- wifi/1.5/default/wifi_legacy_hal.cpp | 4 +++ wifi/1.5/default/wifi_legacy_hal.h | 1 + 15 files changed, 58 insertions(+), 35 deletions(-) diff --git a/wifi/1.5/default/service.cpp b/wifi/1.5/default/service.cpp index 23e2b47ee4..3de49b29bb 100644 --- a/wifi/1.5/default/service.cpp +++ b/wifi/1.5/default/service.cpp @@ -32,7 +32,6 @@ 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::iface_util::WifiIfaceUtil; using android::hardware::wifi::V1_5::implementation::legacy_hal::WifiLegacyHal; using android::hardware::wifi::V1_5::implementation::legacy_hal:: WifiLegacyHalFactory; @@ -63,7 +62,6 @@ int main(int /*argc*/, char** argv) { new android::hardware::wifi::V1_5::implementation::Wifi( iface_tool, legacy_hal_factory, std::make_shared(), - std::make_shared(iface_tool), std::make_shared()); if (kLazyService) { auto registrar = LazyServiceRegistrar::getInstance(); diff --git a/wifi/1.5/default/tests/mock_wifi_iface_util.cpp b/wifi/1.5/default/tests/mock_wifi_iface_util.cpp index fe6e9e2e57..b101c4ac34 100644 --- a/wifi/1.5/default/tests/mock_wifi_iface_util.cpp +++ b/wifi/1.5/default/tests/mock_wifi_iface_util.cpp @@ -29,8 +29,9 @@ namespace implementation { namespace iface_util { MockWifiIfaceUtil::MockWifiIfaceUtil( - const std::weak_ptr iface_tool) - : WifiIfaceUtil(iface_tool) {} + const std::weak_ptr iface_tool, + const std::weak_ptr legacy_hal) + : WifiIfaceUtil(iface_tool, legacy_hal) {} } // namespace iface_util } // namespace implementation } // namespace V1_5 diff --git a/wifi/1.5/default/tests/mock_wifi_iface_util.h b/wifi/1.5/default/tests/mock_wifi_iface_util.h index a719fec878..6d5f59ce53 100644 --- a/wifi/1.5/default/tests/mock_wifi_iface_util.h +++ b/wifi/1.5/default/tests/mock_wifi_iface_util.h @@ -31,7 +31,8 @@ namespace iface_util { class MockWifiIfaceUtil : public WifiIfaceUtil { public: MockWifiIfaceUtil( - const std::weak_ptr iface_tool); + const std::weak_ptr iface_tool, + const std::weak_ptr legacy_hal); MOCK_METHOD1(getFactoryMacAddress, std::array(const std::string&)); MOCK_METHOD2(setMacAddress, diff --git a/wifi/1.5/default/tests/mock_wifi_legacy_hal.h b/wifi/1.5/default/tests/mock_wifi_legacy_hal.h index 9ab2fd5421..826b35f8dd 100644 --- a/wifi/1.5/default/tests/mock_wifi_legacy_hal.h +++ b/wifi/1.5/default/tests/mock_wifi_legacy_hal.h @@ -62,6 +62,7 @@ class MockWifiLegacyHal : public WifiLegacyHal { 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 diff --git a/wifi/1.5/default/tests/wifi_chip_unit_tests.cpp b/wifi/1.5/default/tests/wifi_chip_unit_tests.cpp index d99bfbd0d5..0ad6f3e821 100644 --- a/wifi/1.5/default/tests/wifi_chip_unit_tests.cpp +++ b/wifi/1.5/default/tests/wifi_chip_unit_tests.cpp @@ -276,7 +276,7 @@ class WifiChipTest : public Test { std::shared_ptr> mode_controller_{new NiceMock}; std::shared_ptr> iface_util_{ - new NiceMock(iface_tool_)}; + new NiceMock(iface_tool_, legacy_hal_)}; std::shared_ptr> feature_flags_{new NiceMock}; diff --git a/wifi/1.5/default/tests/wifi_iface_util_unit_tests.cpp b/wifi/1.5/default/tests/wifi_iface_util_unit_tests.cpp index d70e42f80e..8b67bb80c8 100644 --- a/wifi/1.5/default/tests/wifi_iface_util_unit_tests.cpp +++ b/wifi/1.5/default/tests/wifi_iface_util_unit_tests.cpp @@ -22,6 +22,7 @@ #include "wifi_iface_util.h" #include "mock_interface_tool.h" +#include "mock_wifi_legacy_hal.h" using testing::NiceMock; using testing::Test; @@ -48,7 +49,11 @@ class WifiIfaceUtilTest : public Test { protected: std::shared_ptr> iface_tool_{ new NiceMock}; - WifiIfaceUtil* iface_util_ = new WifiIfaceUtil(iface_tool_); + legacy_hal::wifi_hal_fn fake_func_table_; + std::shared_ptr> legacy_hal_{ + new NiceMock(iface_tool_, + fake_func_table_, true)}; + WifiIfaceUtil* iface_util_ = new WifiIfaceUtil(iface_tool_, legacy_hal_); }; TEST_F(WifiIfaceUtilTest, GetOrCreateRandomMacAddress) { 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 index 52f0c2bcde..32da55ec2b 100644 --- a/wifi/1.5/default/tests/wifi_nan_iface_unit_tests.cpp +++ b/wifi/1.5/default/tests/wifi_nan_iface_unit_tests.cpp @@ -122,7 +122,7 @@ class WifiNanIfaceTest : public Test { new NiceMock(iface_tool_, fake_func_table_, true)}; std::shared_ptr> iface_util_{ - new NiceMock(iface_tool_)}; + new NiceMock(iface_tool_, legacy_hal_)}; }; TEST_F(WifiNanIfaceTest, IfacEventHandlers_OnStateToggleOffOn) { diff --git a/wifi/1.5/default/wifi.cpp b/wifi/1.5/default/wifi.cpp index 17db51d35b..da98db8296 100644 --- a/wifi/1.5/default/wifi.cpp +++ b/wifi/1.5/default/wifi.cpp @@ -37,12 +37,10 @@ Wifi::Wifi( const std::shared_ptr iface_tool, const std::shared_ptr legacy_hal_factory, const std::shared_ptr mode_controller, - const std::shared_ptr iface_util, const std::shared_ptr feature_flags) : iface_tool_(iface_tool), legacy_hal_factory_(legacy_hal_factory), mode_controller_(mode_controller), - iface_util_(iface_util), feature_flags_(feature_flags), run_state_(RunState::STOPPED) {} @@ -130,7 +128,8 @@ WifiStatus Wifi::startInternal() { for (auto& hal : legacy_hals_) { chips_.push_back(new WifiChip( chipId, chipId == kPrimaryChipId, hal, mode_controller_, - iface_util_, feature_flags_, on_subsystem_restart_callback)); + std::make_shared(iface_tool_, hal), + feature_flags_, on_subsystem_restart_callback)); chipId++; } run_state_ = RunState::STARTED; diff --git a/wifi/1.5/default/wifi.h b/wifi/1.5/default/wifi.h index 9f5a1b0a3c..825c0bc182 100644 --- a/wifi/1.5/default/wifi.h +++ b/wifi/1.5/default/wifi.h @@ -46,7 +46,6 @@ class Wifi : public V1_5::IWifi { legacy_hal_factory, const std::shared_ptr mode_controller, - const std::shared_ptr iface_util, const std::shared_ptr feature_flags); bool isValid(); @@ -85,7 +84,6 @@ class Wifi : public V1_5::IWifi { std::shared_ptr legacy_hal_factory_; std::shared_ptr mode_controller_; std::vector> legacy_hals_; - std::shared_ptr iface_util_; std::shared_ptr feature_flags_; RunState run_state_; std::vector> chips_; diff --git a/wifi/1.5/default/wifi_chip.cpp b/wifi/1.5/default/wifi_chip.cpp index 0450a7bfe1..0499f456c1 100644 --- a/wifi/1.5/default/wifi_chip.cpp +++ b/wifi/1.5/default/wifi_chip.cpp @@ -353,7 +353,7 @@ WifiChip::WifiChip( ChipId chip_id, bool is_primary, const std::weak_ptr legacy_hal, const std::weak_ptr mode_controller, - const std::weak_ptr iface_util, + const std::shared_ptr iface_util, const std::weak_ptr feature_flags, const std::function& handler) : chip_id_(chip_id), @@ -986,14 +986,14 @@ WifiChip::createBridgedApIfaceInternal() { } } br_ifaces_ap_instances_[br_ifname] = ap_instances; - if (!iface_util_.lock()->createBridge(br_ifname)) { + if (!iface_util_->createBridge(br_ifname)) { LOG(ERROR) << "Failed createBridge - br_name=" << br_ifname.c_str(); invalidateAndClearBridgedAp(br_ifname); return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; } for (auto const& instance : ap_instances) { // Bind ap instance interface to AP bridge - if (!iface_util_.lock()->addIfaceToBridge(br_ifname, instance)) { + if (!iface_util_->addIfaceToBridge(br_ifname, instance)) { LOG(ERROR) << "Failed add if to Bridge - if_name=" << instance.c_str(); invalidateAndClearBridgedAp(br_ifname); @@ -1054,8 +1054,7 @@ WifiStatus WifiChip::removeIfaceInstanceFromBridgedApIfaceInternal( if (it.first == ifname) { for (auto const& iface : it.second) { if (iface == ifInstanceName) { - if (!iface_util_.lock()->removeIfaceFromBridge(it.first, - iface)) { + if (!iface_util_->removeIfaceFromBridge(it.first, iface)) { LOG(ERROR) << "Failed to remove interface: " << ifInstanceName << " from " << ifname; @@ -1086,7 +1085,7 @@ WifiChip::createNanIfaceInternal() { } bool is_dedicated_iface = true; std::string ifname = getPredefinedNanIfaceName(); - if (ifname.empty() || !iface_util_.lock()->ifNameToIndex(ifname)) { + if (ifname.empty() || !iface_util_->ifNameToIndex(ifname)) { // Use the first shared STA iface (wlan0) if a dedicated aware iface is // not defined. ifname = getFirstActiveWlanIfaceName(); @@ -1968,10 +1967,10 @@ std::string WifiChip::getWlanIfaceNameWithType(IfaceType type, unsigned idx) { void WifiChip::invalidateAndClearBridgedApAll() { for (auto const& it : br_ifaces_ap_instances_) { for (auto const& iface : it.second) { - iface_util_.lock()->removeIfaceFromBridge(it.first, iface); + iface_util_->removeIfaceFromBridge(it.first, iface); legacy_hal_.lock()->deleteVirtualInterface(iface); } - iface_util_.lock()->deleteBridge(it.first); + iface_util_->deleteBridge(it.first); } br_ifaces_ap_instances_.clear(); } @@ -1982,10 +1981,10 @@ void WifiChip::invalidateAndClearBridgedAp(const std::string& br_name) { for (auto const& it : br_ifaces_ap_instances_) { if (it.first == br_name) { for (auto const& iface : it.second) { - iface_util_.lock()->removeIfaceFromBridge(br_name, iface); + iface_util_->removeIfaceFromBridge(br_name, iface); legacy_hal_.lock()->deleteVirtualInterface(iface); } - iface_util_.lock()->deleteBridge(br_name); + iface_util_->deleteBridge(br_name); br_ifaces_ap_instances_.erase(br_name); break; } diff --git a/wifi/1.5/default/wifi_chip.h b/wifi/1.5/default/wifi_chip.h index b4ed30ed69..92d639f8b5 100644 --- a/wifi/1.5/default/wifi_chip.h +++ b/wifi/1.5/default/wifi_chip.h @@ -54,7 +54,7 @@ class WifiChip : public V1_5::IWifiChip { const std::weak_ptr legacy_hal, const std::weak_ptr mode_controller, - const std::weak_ptr iface_util, + const std::shared_ptr iface_util, const std::weak_ptr feature_flags, const std::function& subsystemCallbackHandler); @@ -307,7 +307,7 @@ class WifiChip : public V1_5::IWifiChip { ChipId chip_id_; std::weak_ptr legacy_hal_; std::weak_ptr mode_controller_; - std::weak_ptr iface_util_; + std::shared_ptr iface_util_; std::vector> ap_ifaces_; std::vector> nan_ifaces_; std::vector> p2p_ifaces_; diff --git a/wifi/1.5/default/wifi_iface_util.cpp b/wifi/1.5/default/wifi_iface_util.cpp index 2a0aef8906..d1434e3a41 100644 --- a/wifi/1.5/default/wifi_iface_util.cpp +++ b/wifi/1.5/default/wifi_iface_util.cpp @@ -41,8 +41,10 @@ namespace implementation { namespace iface_util { WifiIfaceUtil::WifiIfaceUtil( - const std::weak_ptr iface_tool) + const std::weak_ptr iface_tool, + const std::weak_ptr legacy_hal) : iface_tool_(iface_tool), + legacy_hal_(legacy_hal), random_mac_address_(nullptr), event_handlers_map_() {} @@ -59,14 +61,20 @@ bool WifiIfaceUtil::setMacAddress(const std::string& iface_name, return false; } #endif - if (!iface_tool_.lock()->SetMacAddress(iface_name.c_str(), mac)) { - LOG(ERROR) << "SetMacAddress failed."; - return false; - } + bool success = iface_tool_.lock()->SetMacAddress(iface_name.c_str(), mac); #ifndef WIFI_AVOID_IFACE_RESET_MAC_CHANGE if (!iface_tool_.lock()->SetUpState(iface_name.c_str(), true)) { - LOG(ERROR) << "SetUpState(true) failed."; - return false; + 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) { + LOG(ERROR) << "SetUpState(true) wait for driver ready failed."; + return false; + } + if (!iface_tool_.lock()->SetUpState(iface_name.c_str(), true)) { + LOG(ERROR) << "SetUpState(true) failed after retry."; + return false; + } } #endif IfaceEventHandlers event_handlers = {}; @@ -77,8 +85,12 @@ bool WifiIfaceUtil::setMacAddress(const std::string& iface_name, if (event_handlers.on_state_toggle_off_on != nullptr) { event_handlers.on_state_toggle_off_on(iface_name); } - LOG(DEBUG) << "Successfully SetMacAddress."; - return true; + if (!success) { + LOG(ERROR) << "SetMacAddress failed."; + } else { + LOG(DEBUG) << "SetMacAddress succeeded."; + } + return success; } std::array WifiIfaceUtil::getOrCreateRandomMacAddress() { diff --git a/wifi/1.5/default/wifi_iface_util.h b/wifi/1.5/default/wifi_iface_util.h index 296d1821d0..b449077e9e 100644 --- a/wifi/1.5/default/wifi_iface_util.h +++ b/wifi/1.5/default/wifi_iface_util.h @@ -21,6 +21,8 @@ #include +#include "wifi_legacy_hal.h" + namespace android { namespace hardware { namespace wifi { @@ -40,7 +42,8 @@ struct IfaceEventHandlers { */ class WifiIfaceUtil { public: - WifiIfaceUtil(const std::weak_ptr iface_tool); + WifiIfaceUtil(const std::weak_ptr iface_tool, + const std::weak_ptr legacy_hal); virtual ~WifiIfaceUtil() = default; virtual std::array getFactoryMacAddress( @@ -73,6 +76,7 @@ class WifiIfaceUtil { std::array createRandomMacAddress(); std::weak_ptr iface_tool_; + std::weak_ptr legacy_hal_; std::unique_ptr> random_mac_address_; std::map event_handlers_map_; }; diff --git a/wifi/1.5/default/wifi_legacy_hal.cpp b/wifi/1.5/default/wifi_legacy_hal.cpp index f5ca753824..260f186457 100644 --- a/wifi/1.5/default/wifi_legacy_hal.cpp +++ b/wifi/1.5/default/wifi_legacy_hal.cpp @@ -476,6 +476,10 @@ wifi_error WifiLegacyHal::stop( bool WifiLegacyHal::isStarted() { return is_started_; } +wifi_error WifiLegacyHal::waitForDriverReady() { + return global_func_table_.wifi_wait_for_driver_ready(); +} + std::pair WifiLegacyHal::getDriverVersion( const std::string& iface_name) { std::array buffer; diff --git a/wifi/1.5/default/wifi_legacy_hal.h b/wifi/1.5/default/wifi_legacy_hal.h index 03ca8412ce..237253590e 100644 --- a/wifi/1.5/default/wifi_legacy_hal.h +++ b/wifi/1.5/default/wifi_legacy_hal.h @@ -473,6 +473,7 @@ class WifiLegacyHal { // using a predefined timeout. virtual wifi_error stop(std::unique_lock* lock, const std::function& on_complete_callback); + virtual wifi_error waitForDriverReady(); // Checks if legacy HAL has successfully started bool isStarted(); // Wrappers for all the functions in the legacy HAL function table. -- GitLab From 1fd7cb029b3c57baa2fb7f3c543900ab45b3237a Mon Sep 17 00:00:00 2001 From: Rambo Wang Date: Thu, 18 Feb 2021 20:55:26 -0800 Subject: [PATCH 505/790] Deprecates obsoleted radio hal interfaces Makes a ABI preserving change to radio hal by adding deprecation comments for following interfaces: - startLceService - stopLceService - pullLceData - lceData - setSimCardPower - setIndicationFilter - setupDataCall - deactivateDataCall - startNetworkScan - startNetworkScan_1_2 Bug: 170288130 Test: make Change-Id: I4563b7081dec6fa64b7faff7c8e3c2c3b1239880 --- current.txt | 8 +++++++- radio/1.0/IRadio.hal | 35 +++++++++++++++++++++++++++------- radio/1.0/IRadioIndication.hal | 3 +++ radio/1.0/IRadioResponse.hal | 14 +++++++------- radio/1.1/IRadio.hal | 5 ++++- radio/1.1/IRadioResponse.hal | 2 +- radio/1.2/IRadio.hal | 5 ++++- 7 files changed, 54 insertions(+), 18 deletions(-) diff --git a/current.txt b/current.txt index dfe5d9d5e7..af50841aa8 100644 --- a/current.txt +++ b/current.txt @@ -787,7 +787,13 @@ b9fbb6e2e061ed0960939d48b785e9700210add1f13ed32ecd688d0f1ca20ef7 android.hardwar 0f53d70e1eadf8d987766db4bf6ae2048004682168f4cab118da576787def3fa android.hardware.radio@1.0::types 38d65fb20c60a5b823298560fc0825457ecdc49603a4b4e94bf81511790737da android.hardware.radio@1.4::types 954c334efd80e8869b66d1ce5fe2755712d96ba4b3c38d415739c330af5fb4cb android.hardware.radio@1.5::types +cfaab0e45c5d7b3595032d649da29ed712e920f956c13671efd35602fa81c923 android.hardware.radio@1.0::IRadio +89d78fa49b09e2f31812bb63e1bfac2bf318a9561473c6b0ed6904ce18377d54 android.hardware.radio@1.0::IRadioIndication +bc3c8c233085fca3879dc74b490b9e5bc1063258470d3b4c12f7a74bf215cbbd android.hardware.radio@1.0::IRadioResponse +86fb079a600b2301a752249dfbfc53983a795d752f11aabcb68315a189f6c9a2 android.hardware.radio@1.1::IRadio +00366b2f88f9ec2458014972938270c8413d4ab303218e37bf3add2b8e6b829a android.hardware.radio@1.1::IRadioResponse +2b5afef68e3e2ff1dab63e4f2ee57337ef2635ec812f49080cadfce966d33b52 android.hardware.radio@1.2::IRadio # HALs released in Android S # NOTE: waiting to freeze HALs until later in the release -# NOTE: new HALs are recommended to be in AIDL \ No newline at end of file +# NOTE: new HALs are recommended to be in AIDL diff --git a/radio/1.0/IRadio.hal b/radio/1.0/IRadio.hal index 236dbf5bd6..66cd4f0008 100644 --- a/radio/1.0/IRadio.hal +++ b/radio/1.0/IRadio.hal @@ -385,7 +385,10 @@ interface IRadio { * Note this is for backward compatibility with the old radio modem. The modem * must not use this param for any other reason. * - * Response function is IRadioResponse.setupDataCallResponse() + * Response function is IRadioResponse.setupDataCallResponse() which may return + * RadioError:REQUEST_NOT_SUPPORTED if @1.2::IRadio or higher is supported. + * + * DEPRECATED in @1.2 or higher, use @1.2::IRadio.setupDataCall_1_2() instead. */ oneway setupDataCall(int32_t serial, RadioTechnology radioTechnology, DataProfileInfo dataProfileInfo, bool modemCognitive, bool roamingAllowed, @@ -546,7 +549,10 @@ interface IRadio { * false => No specific reason specified * true => Radio shutdown requested * - * Response function is IRadioResponse.deactivateDataCallResponse() + * Response function is IRadioResponse.deactivateDataCallResponse() which may return + * RadioError:REQUEST_NOT_SUPPORTED if @1.2::IRadio or higher is supported. + * + * DEPRECATED in @1.2 or higher, use @1.2::IRadio.deactivateDataCall_1_2() instead. */ oneway deactivateDataCall(int32_t serial, int32_t cid, bool reasonRadioShutDown); @@ -1456,7 +1462,10 @@ interface IRadio { * @param reportInterval desired reporting interval (ms). * @param pullMode LCE service mode. true: PULL; false: PUSH. * - * Response callback is IRadioResponse.startLceServiceResponse() + * Response callback is IRadioResponse.startLceServiceResponse() which may return + * RadioError:REQUEST_NOT_SUPPORTED if @1.2::IRadio or higher is supported. + * + * DEPRECATED in @1.2 or higher which use the always-on LCE that relies on indications. */ oneway startLceService(int32_t serial, int32_t reportInterval, bool pullMode); @@ -1466,7 +1475,10 @@ interface IRadio { * * @param serial Serial number of request. * - * Response callback is IRadioResponse.stopLceServiceResponse() + * Response callback is IRadioResponse.stopLceServiceResponse() which may return + * RadioError:REQUEST_NOT_SUPPORTED if @1.2::IRadio or higher is supported. + * + * DEPRECATED in @1.2 or higher which use the always-on LCE that relies on indications. */ oneway stopLceService(int32_t serial); @@ -1475,7 +1487,10 @@ interface IRadio { * * @param serial Serial number of request. * - * Response callback is IRadioResponse.pullLceDataResponse() + * Response callback is IRadioResponse.pullLceDataResponse() which may return + * RadioError:REQUEST_NOT_SUPPORTED if @1.2::IRadio or higher is supported. + * + * DEPRECATED in @1.2 or higher which use the always-on LCE that relies on indications. */ oneway pullLceData(int32_t serial); @@ -1546,7 +1561,10 @@ interface IRadio { * @param indicationFilter 32-bit bitmap of IndicationFilter. Bits set to 1 indicate the * indications are enabled. See IndicationFilter for the definition of each bit. * - * Response callback is IRadioResponse.setIndicationFilterResponse() + * Response callback is IRadioResponse.setIndicationFilterResponse() which may return + * RadioError:REQUEST_NOT_SUPPORTED if @1.2::IRadio or higher is supported. + * + * DEPRECATED in @1.2 or higher, use @1.2::IRadio.setIndicationFilter_1_2() instead. */ oneway setIndicationFilter(int32_t serial, bitfield indicationFilter); @@ -1560,7 +1578,10 @@ interface IRadio { * @param serial Serial number of request * @param powerUp True if powering up the sim card * - * Response callback is IRadioResponse.setSimCardPowerResponse() + * Response callback is IRadioResponse.setSimCardPowerResponse() which may return + * RadioError:REQUEST_NOT_SUPPORTED if @1.1::IRadio or higher is supported. + * + * DEPRECATED in @1.1 or higher, use @1.1::IRadio.setSimCardPower_1_1() instead. */ oneway setSimCardPower(int32_t serial, bool powerUp); diff --git a/radio/1.0/IRadioIndication.hal b/radio/1.0/IRadioIndication.hal index eb07226ffc..eb6c8ef8ce 100644 --- a/radio/1.0/IRadioIndication.hal +++ b/radio/1.0/IRadioIndication.hal @@ -427,6 +427,9 @@ interface IRadioIndication { * * @param type Type of radio indication * @param lce LceData information + * + * DEPRECATED in @1.2 and above, use + * @1.2::IRadioIndication.currentLinkCapacityEstimate() instead. */ oneway lceData(RadioIndicationType type, LceDataInfo lce); diff --git a/radio/1.0/IRadioResponse.hal b/radio/1.0/IRadioResponse.hal index c1b16b7b83..00cec9f0d1 100644 --- a/radio/1.0/IRadioResponse.hal +++ b/radio/1.0/IRadioResponse.hal @@ -590,10 +590,10 @@ interface IRadioResponse { * RadioError:NONE must be returned on both success and failure of setup with the * DataCallResponse.status containing the actual status * For all other errors the DataCallResponse is ignored. + * RadioError:REQUEST_NOT_SUPPORTED may be returned when HAL 1.2 or higher is supported. * RadioError:RADIO_NOT_AVAILABLE * RadioError:OP_NOT_ALLOWED_BEFORE_REG_TO_NW * RadioError:OP_NOT_ALLOWED_DURING_VOICE_CALL - * RadioError:REQUEST_NOT_SUPPORTED * RadioError:INVALID_ARGUMENTS * RadioError:INTERNAL_ERR * RadioError:NO_MEMORY @@ -856,12 +856,12 @@ interface IRadioResponse { * @param info Response info struct containing response type, serial no. and error * * Valid errors returned: + * RadioError:REQUEST_NOT_SUPPORTED may be returned when HAL 1.2 or higher is supported. * RadioError:NONE * RadioError:RADIO_NOT_AVAILABLE * RadioError:INVALID_CALL_ID * RadioError:INVALID_STATE * RadioError:INVALID_ARGUMENTS - * RadioError:REQUEST_NOT_SUPPORTED * RadioError:INTERNAL_ERR * RadioError:NO_MEMORY * RadioError:NO_RESOURCES @@ -2420,11 +2420,11 @@ interface IRadioResponse { * @param statusInfo LceStatusInfo indicating LCE status * * Valid errors returned: + * RadioError:REQUEST_NOT_SUPPORTED may be returned when HAL 1.2 or higher is supported. * RadioError:NONE * RadioError:RADIO_NOT_AVAILABLE * RadioError:LCE_NOT_SUPPORTED * RadioError:INTERNAL_ERR - * RadioError:REQUEST_NOT_SUPPORTED * RadioError:NO_MEMORY * RadioError:NO_RESOURCES * RadioError:CANCELLED @@ -2436,6 +2436,7 @@ interface IRadioResponse { * @param statusInfo LceStatusInfo indicating LCE status * * Valid errors returned: + * RadioError:REQUEST_NOT_SUPPORTED may be returned when HAL 1.2 or higher is supported. * RadioError:NONE * RadioError:RADIO_NOT_AVAILABLE * RadioError:LCE_NOT_SUPPORTED @@ -2443,7 +2444,6 @@ interface IRadioResponse { * RadioError:NO_MEMORY * RadioError:NO_RESOURCES * RadioError:CANCELLED - * RadioError:REQUEST_NOT_SUPPORTED * RadioError:SIM_ABSENT */ oneway stopLceServiceResponse(RadioResponseInfo info, LceStatusInfo statusInfo); @@ -2453,6 +2453,7 @@ interface IRadioResponse { * @param lceInfo LceDataInfo indicating LCE data as defined in types.hal * * Valid errors returned: + * RadioError:REQUEST_NOT_SUPPORTED may be returned when HAL 1.2 or higher is supported. * RadioError:NONE * RadioError:RADIO_NOT_AVAILABLE * RadioError:LCE_NOT_SUPPORTED @@ -2460,7 +2461,6 @@ interface IRadioResponse { * RadioError:NO_MEMORY * RadioError:NO_RESOURCES * RadioError:CANCELLED - * RadioError:REQUEST_NOT_SUPPORTED * RadioError:SIM_ABSENT */ oneway pullLceDataResponse(RadioResponseInfo info, LceDataInfo lceInfo); @@ -2534,13 +2534,13 @@ interface IRadioResponse { * @param info Response info struct containing response type, serial no. and error * * Valid errors returned: + * RadioError:REQUEST_NOT_SUPPORTED may be returned when HAL 1.2 or higher is supported. * RadioError:NONE * RadioError:INVALID_ARGUMENTS * RadioError:RADIO_NOT_AVAILABLE * RadioError:NO_MEMORY * RadioError:INTERNAL_ERR * RadioError:SYSTEM_ERR - * RadioError:REQUEST_NOT_SUPPORTED * RadioError:NO_RESOURCES * RadioError:CANCELLED */ @@ -2550,9 +2550,9 @@ interface IRadioResponse { * @param info Response info struct containing response type, serial no. and error * * Valid errors returned: + * RadioError:REQUEST_NOT_SUPPORTED may be returned when HAL 1.1 or higher is supported. * RadioError:NONE * RadioError:RADIO_NOT_AVAILABLE - * RadioError:REQUEST_NOT_SUPPORTED * RadioError:INVALID_ARGUMENTS * RadioError:INTERNAL_ERR * RadioError:NO_MEMORY diff --git a/radio/1.1/IRadio.hal b/radio/1.1/IRadio.hal index 22d27d4563..de2135ad74 100644 --- a/radio/1.1/IRadio.hal +++ b/radio/1.1/IRadio.hal @@ -77,7 +77,10 @@ interface IRadio extends @1.0::IRadio { * @param serial Serial number of request. * @param request Defines the radio networks/bands/channels which need to be scanned. * - * Response function is IRadioResponse.startNetworkScanResponse() + * Response function is IRadioResponse.startNetworkScanResponse() which may return + * RadioError:REQUEST_NOT_SUPPORTED if @1.2::IRadio or higher is supported. + * + * DEPRECATED in @1.2 or higher, use @1.2::IRadio.startNetworkScan_1_2() instead. */ oneway startNetworkScan(int32_t serial, NetworkScanRequest request); diff --git a/radio/1.1/IRadioResponse.hal b/radio/1.1/IRadioResponse.hal index 759602b004..7dc1bc6a7b 100644 --- a/radio/1.1/IRadioResponse.hal +++ b/radio/1.1/IRadioResponse.hal @@ -51,6 +51,7 @@ interface IRadioResponse extends @1.0::IRadioResponse { * @param info Response info struct containing response type, serial no. and error * * Valid errors returned: + * RadioError:REQUEST_NOT_SUPPORTED may be returned when HAL 1.2 or higher is supported. * RadioError:NONE * RadioError:RADIO_NOT_AVAILABLE * RadioError:OPERATION_NOT_ALLOWED @@ -59,7 +60,6 @@ interface IRadioResponse extends @1.0::IRadioResponse { * RadioError:NO_MEMORY * RadioError:MODEM_ERR * RadioError:INVALID_ARGUMENTS - * RadioError:REQUEST_NOT_SUPPORTED */ oneway startNetworkScanResponse(RadioResponseInfo info); diff --git a/radio/1.2/IRadio.hal b/radio/1.2/IRadio.hal index 87b0add5da..6d48ca0a45 100644 --- a/radio/1.2/IRadio.hal +++ b/radio/1.2/IRadio.hal @@ -37,7 +37,10 @@ interface IRadio extends @1.1::IRadio { * @param serial Serial number of request. * @param request Defines the radio networks/bands/channels which need to be scanned. * - * Response function is IRadioResponse.startNetworkScanResponse() + * Response function is IRadioResponse.startNetworkScanResponse() which may return + * RadioError:REQUEST_NOT_SUPPORTED if @1.4::IRadio or higher is supported. + * + * DEPRECATED in @1.4 or higher, use @1.4::IRadio.startNetworkScan_1_4() instead. */ oneway startNetworkScan_1_2(int32_t serial, NetworkScanRequest request); -- GitLab From 8709aa134b212bc68e1798ce6b11cac2d07224b5 Mon Sep 17 00:00:00 2001 From: Yuncheol Heo Date: Wed, 3 Mar 2021 21:11:00 -0800 Subject: [PATCH 506/790] Polish the comments of Cluster VHAL. Bug: 173454429 Test: it builds Change-Id: Ia3ddc7329494298d49d841f5e913423aeef7d648 --- automotive/vehicle/2.0/types.hal | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/automotive/vehicle/2.0/types.hal b/automotive/vehicle/2.0/types.hal index e3fd16de57..7ff79fec20 100644 --- a/automotive/vehicle/2.0/types.hal +++ b/automotive/vehicle/2.0/types.hal @@ -3037,7 +3037,7 @@ enum VehicleProperty : int32_t { /** * Starts the ClusterUI in cluster display. * - * int32[0]: the type of ClusterUI to show + * int32: the type of ClusterUI to show * 0 indicates ClusterHome, that is a home screen of cluster display, and provides * the default UI and a kind of launcher functionality for cluster display. * the other values are followed by OEM's definition. @@ -3057,12 +3057,12 @@ enum VehicleProperty : int32_t { * int32[0]: on/off: 0 - off, 1 - on, -1 - don't care * int32[1]: width: positive number - actual width in pixels -1 - don't care (should set "don't care" both width and height) - * int32[2]: height: ditto with width + * int32[2]: height: same format with 'width' * int32[3]: Inset - left: positive number - actual left inset value in pixels -1 - don't care (should set "don't care" all Inset fields) - * int32[4]: Inset - top - * int32[5]: Inset - right - * int32[6]: Inset - bottom + * int32[4]: Inset - top: same format with 'left' + * int32[5]: Inset - right: same format with 'left' + * int32[6]: Inset - bottom: same format with 'left' * * @change_mode VehiclePropertyChangeMode:ON_CHANGE * @access VehiclePropertyAccess:READ @@ -3097,9 +3097,9 @@ enum VehicleProperty : int32_t { * -1 indicates the area isn't used any more. * bytes: the array to represent the availability of ClusterUI. * 0 indicates non-available and 1 indicates available. - * For example, let's assume a car supports 3 UI like HOME, MAPS, CALL and it only supports - * CALL UI only when the cellular network is available. Then, if the nework is avaibale, - * it'll send [1 1 1], and if it's out of network, it'll send [1 1 0]. + * For example, let's assume a car supports 3 OEM defined ClusterUI like HOME, MAPS, CALL, + * and it only supports CALL UI only when the cellular network is available. Then, if the + * nework is avaibale, it'll send [1 1 1], and if it's out of network, it'll send [1 1 0]. * * @change_mode VehiclePropertyChangeMode:ON_CHANGE * @access VehiclePropertyAccess:WRITE @@ -3117,7 +3117,7 @@ enum VehicleProperty : int32_t { * request to turn the display on to show some specific ClusterUI. * ClusterOS should response this with CLUSTER_DISPLAY_STATE. * - * int32[0]: the type of ClusterUI to show + * int32: the type of ClusterUI to show * * @change_mode VehiclePropertyChangeMode:ON_CHANGE * @access VehiclePropertyAccess:WRITE -- GitLab From 25d67108b7e731912e53b3454c9cf9c90daf5caa Mon Sep 17 00:00:00 2001 From: Shuzhen Wang Date: Fri, 4 Dec 2020 12:57:09 -0800 Subject: [PATCH 507/790] Camera: Add support for multi-resolution input and output streams - Multi-resolution output streams allow for variable output sizes for logical multi-camera. - Multi-resolution reprocessing allows for reprocessing of variable size images. Test: Camera CTS, VTS Bug: 156254356 Change-Id: I4e8b14a4d6aabdb4b194483d93af53e033c08e28 --- camera/device/3.7/Android.bp | 22 +++ camera/device/3.7/ICameraDevice.hal | 43 ++++++ camera/device/3.7/ICameraDeviceSession.hal | 124 ++++++++++++++++ camera/device/3.7/types.hal | 136 ++++++++++++++++++ camera/metadata/3.6/types.hal | 16 +++ camera/provider/2.4/vts/functional/Android.bp | 2 + .../VtsHalCameraProviderV2_4TargetTest.cpp | 83 ++++++++--- camera/provider/2.7/Android.bp | 26 ++++ camera/provider/2.7/ICameraProvider.hal | 51 +++++++ camera/provider/2.7/types.hal | 30 ++++ .../compatibility_matrix.current.xml | 2 +- 11 files changed, 517 insertions(+), 18 deletions(-) create mode 100644 camera/device/3.7/Android.bp create mode 100644 camera/device/3.7/ICameraDevice.hal create mode 100644 camera/device/3.7/ICameraDeviceSession.hal create mode 100644 camera/device/3.7/types.hal create mode 100644 camera/provider/2.7/Android.bp create mode 100644 camera/provider/2.7/ICameraProvider.hal create mode 100644 camera/provider/2.7/types.hal diff --git a/camera/device/3.7/Android.bp b/camera/device/3.7/Android.bp new file mode 100644 index 0000000000..42782f29a9 --- /dev/null +++ b/camera/device/3.7/Android.bp @@ -0,0 +1,22 @@ +// This file is autogenerated by hidl-gen -Landroidbp. + +hidl_interface { + name: "android.hardware.camera.device@3.7", + root: "android.hardware", + srcs: [ + "types.hal", + "ICameraDevice.hal", + "ICameraDeviceSession.hal", + ], + interfaces: [ + "android.hardware.camera.common@1.0", + "android.hardware.camera.device@3.2", + "android.hardware.camera.device@3.3", + "android.hardware.camera.device@3.4", + "android.hardware.camera.device@3.5", + "android.hardware.camera.device@3.6", + "android.hardware.graphics.common@1.0", + "android.hidl.base@1.0", + ], + gen_java: false, +} diff --git a/camera/device/3.7/ICameraDevice.hal b/camera/device/3.7/ICameraDevice.hal new file mode 100644 index 0000000000..9bc208373b --- /dev/null +++ b/camera/device/3.7/ICameraDevice.hal @@ -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.camera.device@3.7; + +import android.hardware.camera.common@1.0::Status; +import @3.6::ICameraDevice; + +/** + * Camera device interface + * + * Supports the android.hardware.Camera API, and the android.hardware.camera2 + * API at LIMITED or better hardware level. + * + * ICameraDevice.open() must return @3.2::ICameraDeviceSession, + * @3.5::ICameraDeviceSession, @3.6::ICameraDeviceSession, or + * @3.7::ICameraDeviceSession. + */ +interface ICameraDevice extends @3.6::ICameraDevice { + /** + * isStreamCombinationSupported_3_7: + * + * Identical to @3.5::ICameraDevice.isStreamCombinationSupported, except + * that it takes a @3.7::StreamConfiguration parameter, which could contain + * information about multi-resolution input and output streams. + * + */ + isStreamCombinationSupported_3_7(StreamConfiguration streams) + generates (Status status, bool queryStatus); +}; diff --git a/camera/device/3.7/ICameraDeviceSession.hal b/camera/device/3.7/ICameraDeviceSession.hal new file mode 100644 index 0000000000..fb5c7fa89e --- /dev/null +++ b/camera/device/3.7/ICameraDeviceSession.hal @@ -0,0 +1,124 @@ +/* + * 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.7; + +import android.hardware.camera.common@1.0::Status; +import @3.2::BufferCache; +import @3.5::StreamConfiguration; +import @3.6::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.6::ICameraDeviceSession { + /** + * configureStreams_3_7: + * + * Identical to @3.6::ICameraDeviceSession.configureStreams_3_6, except that: + * + * - The requestedConfiguration allows the camera framework to configure + * stream groups. + * - For requested configurations of streams within the same group, the + * corresponding halConfiguration must have the same usage flags and + * maxBuffers. + * - Within a CaptureRequest, the application is guaranteed not to request + * more than one streams within the same stream group. When one of the + * stream within a stream group is requested, the camera HAL can either + * produce output on that stream, or any other stream within the same + * stream group. + * - The requestedConfiguration allows the camera framework to indicate that + * input images of different sizes may be submitted within capture + * requests. + * + * @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. + * 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. + */ + configureStreams_3_7(StreamConfiguration requestedConfiguration) + generates (Status status, @3.6::HalStreamConfiguration halConfiguration); + + /** + * processCaptureRequest_3_7: + * + * Identical to @3.4::ICameraDeviceSession.processCaptureRequest, except that: + * + * - The capture request can include width and height of the input buffer for + * a reprocessing request. + * + * @return status Status code for the operation, one of: + * OK: + * On a successful start to processing the capture request + * ILLEGAL_ARGUMENT: + * If the input is malformed (the settings are empty when not + * allowed, the physical camera settings are invalid, there are 0 + * output buffers, etc) and capture processing + * cannot start. Failures during request processing must be + * handled by calling ICameraDeviceCallback::notify(). In case of + * this error, the framework retains responsibility for the + * stream buffers' fences and the buffer handles; the HAL must not + * close the fences or return these buffers with + * ICameraDeviceCallback::processCaptureResult(). + * In case of multi-resolution input image, this error must be returned + * if the caller passes in a CaptureRequest with an invalid + * [inputWith, inputHeight]. + * INTERNAL_ERROR: + * If the camera device has encountered a serious error. After this + * error is returned, only the close() method can be successfully + * called by the framework. + * @return numRequestProcessed Number of requests successfully processed by + * camera HAL. When status is OK, this must be equal to the size of + * requests. When the call fails, this number is the number of requests + * that HAL processed successfully before HAL runs into an error. + * + */ + processCaptureRequest_3_7(vec requests, vec cachesToRemove) + generates (Status status, uint32_t numRequestProcessed); +}; diff --git a/camera/device/3.7/types.hal b/camera/device/3.7/types.hal new file mode 100644 index 0000000000..9450c2f5a7 --- /dev/null +++ b/camera/device/3.7/types.hal @@ -0,0 +1,136 @@ +/* + * 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.7; + +import @3.2::CameraMetadata; +import @3.2::StreamConfigurationMode; +import @3.4::CaptureRequest; +import @3.4::Stream; + +/** + * 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.4 Stream with the multi-resolution output surface + * group Id field. + */ +struct Stream { + /** + * The definition of Stream from the prior version. + */ + @3.4::Stream v3_4; + + /** + * The surface group id used for multi-resolution output streams. + * + * This works simliar to the surfaceGroupId of OutputConfiguration in the + * public API, with the exception that this is for multi-resolution image + * reader and is used by the camera HAL to choose a target stream within + * the same group to which images are written. All streams in the same group + * will have the same image format, data space, and usage flag. + * + * The framework must only call processCaptureRequest on at most one of the + * streams within a surface group. Depending on current active physical + * camera backing the logical multi-camera, or the pixel mode the camera is + * running in, the HAL can choose to request and return a buffer from any + * stream within the same group. -1 means that this stream is an input + * stream, or is an output stream which doesn't belong to any group. + * + * Streams with the same non-negative group id must have the same format and + * usage flag. + */ + int32_t groupId; +}; + +/** + * StreamConfiguration: + * + * Identical to @3.5::StreamConfiguration, except that the streams + * vector contains @3.7::Stream. + */ +struct StreamConfiguration { + /** + * An array of camera stream pointers, defining the input/output + * configuration for the camera HAL device. + */ + vec 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; +}; + +/** + * CaptureRequest: + * + * This version extends 3.4::CaptureRequest with the input buffer's width and + * height. + */ +struct CaptureRequest { + /** + * The definition of CaptureRequest from the prior version. + */ + @3.4::CaptureRequest v3_4; + + /** + * The width and height of the input buffer for this capture request. + * + * These fields will be [0, 0] if no input buffer exists in the capture + * request. + * + * If the stream configuration contains an input stream and has the + * multiResolutionInputImage flag set to true, the camera client may submit a + * reprocessing request with input buffer size different than the + * configured input stream size. In that case, the inputWith and inputHeight + * fields will be the actual size of the input image. + * + * If the stream configuration contains an input stream and the + * multiResolutionInputImage flag is false, the inputWidth and inputHeight must + * match the input stream size. + */ + uint32_t inputWidth; + uint32_t inputHeight; +}; diff --git a/camera/metadata/3.6/types.hal b/camera/metadata/3.6/types.hal index fb957367f8..3472ae9668 100644 --- a/camera/metadata/3.6/types.hal +++ b/camera/metadata/3.6/types.hal @@ -42,6 +42,14 @@ enum CameraMetadataTag : @3.5::CameraMetadataTag { */ ANDROID_SCALER_DEFAULT_SECURE_IMAGE_SIZE = android.hardware.camera.metadata@3.5::CameraMetadataTag:ANDROID_SCALER_END_3_5, + /** android.scaler.physicalCameraMultiResolutionStreamConfigurations [static, enum[], ndk_public] + * + *

    The available multi-resolution stream configurations that this + * physical camera device supports + * (i.e. format, width, height, output/input stream).

    + */ + ANDROID_SCALER_PHYSICAL_CAMERA_MULTI_RESOLUTION_STREAM_CONFIGURATIONS, + ANDROID_SCALER_END_3_6, }; @@ -49,3 +57,11 @@ enum CameraMetadataTag : @3.5::CameraMetadataTag { /* * Enumeration definitions for the various entries that need them */ + +/** android.scaler.physicalCameraMultiResolutionStreamConfigurations enumeration values + * @see ANDROID_SCALER_PHYSICAL_CAMERA_MULTI_RESOLUTION_STREAM_CONFIGURATIONS + */ +enum CameraMetadataEnumAndroidScalerPhysicalCameraMultiResolutionStreamConfigurations : uint32_t { + ANDROID_SCALER_PHYSICAL_CAMERA_MULTI_RESOLUTION_STREAM_CONFIGURATIONS_OUTPUT, + ANDROID_SCALER_PHYSICAL_CAMERA_MULTI_RESOLUTION_STREAM_CONFIGURATIONS_INPUT, +}; diff --git a/camera/provider/2.4/vts/functional/Android.bp b/camera/provider/2.4/vts/functional/Android.bp index 691d77252e..8886ee1e8c 100644 --- a/camera/provider/2.4/vts/functional/Android.bp +++ b/camera/provider/2.4/vts/functional/Android.bp @@ -48,10 +48,12 @@ cc_test { "android.hardware.camera.device@3.4", "android.hardware.camera.device@3.5", "android.hardware.camera.device@3.6", + "android.hardware.camera.device@3.7", "android.hardware.camera.metadata@3.4", "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.hidl.allocator@1.0", "libgrallocusage", diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp index d6213448ea..b2fd402ed8 100644 --- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp +++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp @@ -40,11 +40,14 @@ #include #include #include +#include +#include #include #include #include #include #include +#include #include #include #include @@ -189,12 +192,14 @@ enum SystemCameraKind { namespace { // "device@/legacy/" const char *kDeviceNameRE = "device@([0-9]+\\.[0-9]+)/%s/(.+)"; + const int CAMERA_DEVICE_API_VERSION_3_7 = 0x307; const int CAMERA_DEVICE_API_VERSION_3_6 = 0x306; const int CAMERA_DEVICE_API_VERSION_3_5 = 0x305; const int CAMERA_DEVICE_API_VERSION_3_4 = 0x304; const int CAMERA_DEVICE_API_VERSION_3_3 = 0x303; const int CAMERA_DEVICE_API_VERSION_3_2 = 0x302; const int CAMERA_DEVICE_API_VERSION_1_0 = 0x100; + const char *kHAL3_7 = "3.7"; const char *kHAL3_6 = "3.6"; const char *kHAL3_5 = "3.5"; const char *kHAL3_4 = "3.4"; @@ -231,7 +236,9 @@ namespace { return -1; } - if (version.compare(kHAL3_6) == 0) { + if (version.compare(kHAL3_7) == 0) { + return CAMERA_DEVICE_API_VERSION_3_7; + } else if (version.compare(kHAL3_6) == 0) { return CAMERA_DEVICE_API_VERSION_3_6; } else if (version.compare(kHAL3_5) == 0) { return CAMERA_DEVICE_API_VERSION_3_5; @@ -756,7 +763,8 @@ public: sp *session3_3 /*out*/, sp *session3_4 /*out*/, sp *session3_5 /*out*/, - sp *session3_6 /*out*/); + sp *session3_6 /*out*/, + sp *session3_7 /*out*/); void castDevice(const sp &device, int32_t deviceVersion, sp *device3_5/*out*/); void createStreamConfiguration(const ::android::hardware::hidl_vec& streams3_2, @@ -1883,6 +1891,7 @@ TEST_P(CameraHidlTest, getCameraDeviceInterface) { for (const auto& name : cameraDeviceNames) { int deviceVersion = getCameraDeviceVersion(name, mProviderType); switch (deviceVersion) { + case CAMERA_DEVICE_API_VERSION_3_7: case CAMERA_DEVICE_API_VERSION_3_6: case CAMERA_DEVICE_API_VERSION_3_5: case CAMERA_DEVICE_API_VERSION_3_4: @@ -1926,6 +1935,7 @@ TEST_P(CameraHidlTest, getResourceCost) { for (const auto& name : cameraDeviceNames) { int deviceVersion = getCameraDeviceVersion(name, mProviderType); switch (deviceVersion) { + case CAMERA_DEVICE_API_VERSION_3_7: case CAMERA_DEVICE_API_VERSION_3_6: case CAMERA_DEVICE_API_VERSION_3_5: case CAMERA_DEVICE_API_VERSION_3_4: @@ -2666,6 +2676,7 @@ TEST_P(CameraHidlTest, systemCameraTest) { for (const auto& name : cameraDeviceNames) { int deviceVersion = getCameraDeviceVersion(name, mProviderType); switch (deviceVersion) { + case CAMERA_DEVICE_API_VERSION_3_7: case CAMERA_DEVICE_API_VERSION_3_6: case CAMERA_DEVICE_API_VERSION_3_5: case CAMERA_DEVICE_API_VERSION_3_4: @@ -2752,6 +2763,7 @@ TEST_P(CameraHidlTest, getCameraCharacteristics) { for (const auto& name : cameraDeviceNames) { int deviceVersion = getCameraDeviceVersion(name, mProviderType); switch (deviceVersion) { + case CAMERA_DEVICE_API_VERSION_3_7: case CAMERA_DEVICE_API_VERSION_3_6: case CAMERA_DEVICE_API_VERSION_3_5: case CAMERA_DEVICE_API_VERSION_3_4: @@ -2832,6 +2844,7 @@ TEST_P(CameraHidlTest, setTorchMode) { for (const auto& name : cameraDeviceNames) { int deviceVersion = getCameraDeviceVersion(name, mProviderType); switch (deviceVersion) { + case CAMERA_DEVICE_API_VERSION_3_7: case CAMERA_DEVICE_API_VERSION_3_6: case CAMERA_DEVICE_API_VERSION_3_5: case CAMERA_DEVICE_API_VERSION_3_4: @@ -2959,6 +2972,7 @@ TEST_P(CameraHidlTest, dumpState) { for (const auto& name : cameraDeviceNames) { int deviceVersion = getCameraDeviceVersion(name, mProviderType); switch (deviceVersion) { + case CAMERA_DEVICE_API_VERSION_3_7: case CAMERA_DEVICE_API_VERSION_3_6: case CAMERA_DEVICE_API_VERSION_3_5: case CAMERA_DEVICE_API_VERSION_3_4: @@ -3025,6 +3039,7 @@ TEST_P(CameraHidlTest, openClose) { for (const auto& name : cameraDeviceNames) { int deviceVersion = getCameraDeviceVersion(name, mProviderType); switch (deviceVersion) { + case CAMERA_DEVICE_API_VERSION_3_7: case CAMERA_DEVICE_API_VERSION_3_6: case CAMERA_DEVICE_API_VERSION_3_5: case CAMERA_DEVICE_API_VERSION_3_4: @@ -3056,9 +3071,13 @@ TEST_P(CameraHidlTest, openClose) { sp sessionV3_4; sp sessionV3_5; sp sessionV3_6; + sp sessionV3_7; castSession(session, deviceVersion, &sessionV3_3, - &sessionV3_4, &sessionV3_5, &sessionV3_6); - if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_6) { + &sessionV3_4, &sessionV3_5, &sessionV3_6, + &sessionV3_7); + 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); } else if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_5) { ASSERT_TRUE(sessionV3_5.get() != nullptr); @@ -3122,6 +3141,7 @@ TEST_P(CameraHidlTest, constructDefaultRequestSettings) { for (const auto& name : cameraDeviceNames) { int deviceVersion = getCameraDeviceVersion(name, mProviderType); switch (deviceVersion) { + case CAMERA_DEVICE_API_VERSION_3_7: case CAMERA_DEVICE_API_VERSION_3_6: case CAMERA_DEVICE_API_VERSION_3_5: case CAMERA_DEVICE_API_VERSION_3_4: @@ -3221,11 +3241,13 @@ TEST_P(CameraHidlTest, configureStreamsAvailableOutputs) { sp session3_4; sp session3_5; sp session3_6; + sp session3_7; sp cameraDevice; sp cameraDevice3_5; openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/, &cameraDevice /*out*/); - castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, &session3_6); + castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, + &session3_6, &session3_7); castDevice(cameraDevice, deviceVersion, &cameraDevice3_5); outputStreams.clear(); @@ -3307,6 +3329,7 @@ TEST_P(CameraHidlTest, configureConcurrentStreamsAvailableOutputs) { sp session3_4; sp session3_5; sp session3_6; + sp session3_7; sp cameraDevice; sp cameraDevice3_5; ::android::hardware::camera::device::V3_5::StreamConfiguration config3_5; @@ -3344,7 +3367,7 @@ 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_5, &cti.session3_6, &cti.session3_7); castDevice(cti.cameraDevice, deviceVersion, &cti.cameraDevice3_5); outputStreams.clear(); @@ -3462,11 +3485,13 @@ TEST_P(CameraHidlTest, configureStreamsInvalidOutputs) { sp session3_4; sp session3_5; sp session3_6; + sp session3_7; sp cameraDevice; sp cameraDevice3_5; openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/, &cameraDevice /*out*/); - castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, &session3_6); + castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, + &session3_6, &session3_7); castDevice(cameraDevice, deviceVersion, &cameraDevice3_5); outputStreams.clear(); @@ -3660,11 +3685,13 @@ TEST_P(CameraHidlTest, configureStreamsZSLInputOutputs) { sp session3_4; sp session3_5; sp session3_6; + sp session3_7; sp cameraDevice; sp cameraDevice3_5; openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/, &cameraDevice /*out*/); - castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, &session3_6); + castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, + &session3_6, &session3_7); castDevice(cameraDevice, deviceVersion, &cameraDevice3_5); Status rc = isZSLModeAvailable(staticMeta); @@ -3828,8 +3855,10 @@ TEST_P(CameraHidlTest, configureStreamsWithSessionParameters) { sp session3_4; sp session3_5; sp session3_6; + sp session3_7; openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMetaBuffer /*out*/); - castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, &session3_6); + castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, + &session3_6, &session3_7); if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_4) { ASSERT_NE(session3_4, nullptr); } else { @@ -3951,11 +3980,13 @@ TEST_P(CameraHidlTest, configureStreamsPreviewStillOutputs) { sp session3_4; sp session3_5; sp session3_6; + sp session3_7; sp cameraDevice; sp cameraDevice3_5; openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/, &cameraDevice /*out*/); - castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, &session3_6); + castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, + &session3_6, &session3_7); castDevice(cameraDevice, deviceVersion, &cameraDevice3_5); // Check if camera support depth only @@ -4069,11 +4100,13 @@ TEST_P(CameraHidlTest, configureStreamsConstrainedOutputs) { sp session3_4; sp session3_5; sp session3_6; + sp session3_7; sp cameraDevice; sp cameraDevice3_5; openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/, &cameraDevice /*out*/); - castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, &session3_6); + castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, + &session3_6, &session3_7); castDevice(cameraDevice, deviceVersion, &cameraDevice3_5); Status rc = isConstrainedModeAvailable(staticMeta); @@ -4281,11 +4314,13 @@ TEST_P(CameraHidlTest, configureStreamsVideoStillOutputs) { sp session3_4; sp session3_5; sp session3_6; + sp session3_7; sp cameraDevice; sp cameraDevice3_5; openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/, &cameraDevice /*out*/); - castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, &session3_6); + castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, + &session3_6, &session3_7); castDevice(cameraDevice, deviceVersion, &cameraDevice3_5); // Check if camera support depth only @@ -6103,7 +6138,9 @@ void CameraHidlTest::configurePreviewStreams3_4(const std::string &name, int32_t sp session3_3; sp session3_6; - castSession(session, deviceVersion, &session3_3, session3_4, session3_5, &session3_6); + sp session3_7; + castSession(session, deviceVersion, &session3_3, session3_4, session3_5, + &session3_6, &session3_7); ASSERT_NE(nullptr, (*session3_4).get()); *useHalBufManager = false; @@ -6144,7 +6181,7 @@ void CameraHidlTest::configurePreviewStreams3_4(const std::string &name, int32_t }); ASSERT_TRUE(ret.isOk()); - ASSERT_TRUE(!allowUnsupport || deviceVersion == CAMERA_DEVICE_API_VERSION_3_5); + ASSERT_TRUE(!allowUnsupport || deviceVersion >= CAMERA_DEVICE_API_VERSION_3_5); if (allowUnsupport) { sp cameraDevice3_5; castDevice(device3_x, deviceVersion, &cameraDevice3_5); @@ -6446,7 +6483,9 @@ void CameraHidlTest::configureSingleStream( sp session3_4; sp session3_5; sp session3_6; - castSession(*session, deviceVersion, &session3_3, &session3_4, &session3_5, &session3_6); + sp session3_7; + castSession(*session, deviceVersion, &session3_3, &session3_4, &session3_5, + &session3_6, &session3_7); *useHalBufManager = false; status = find_camera_metadata_ro_entry(staticMeta, @@ -6583,13 +6622,21 @@ void CameraHidlTest::castSession(const sp &session, int32_ sp *session3_3 /*out*/, sp *session3_4 /*out*/, sp *session3_5 /*out*/, - sp *session3_6 /*out*/) { + sp *session3_6 /*out*/, + sp *session3_7 /*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); switch (deviceVersion) { + case CAMERA_DEVICE_API_VERSION_3_7: { + auto castResult = device::V3_7::ICameraDeviceSession::castFrom(session); + ASSERT_TRUE(castResult.isOk()); + *session3_7 = castResult; + } + [[fallthrough]]; case CAMERA_DEVICE_API_VERSION_3_6: { auto castResult = device::V3_6::ICameraDeviceSession::castFrom(session); ASSERT_TRUE(castResult.isOk()); @@ -7233,7 +7280,9 @@ void CameraHidlTest::verifyBuffersReturned( sp session3_4; sp session3_5; sp session3_6; - castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, &session3_6); + sp session3_7; + castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, + &session3_6, &session3_7); ASSERT_NE(nullptr, session3_5.get()); hidl_vec streamIds(1); diff --git a/camera/provider/2.7/Android.bp b/camera/provider/2.7/Android.bp new file mode 100644 index 0000000000..094dd9d4cd --- /dev/null +++ b/camera/provider/2.7/Android.bp @@ -0,0 +1,26 @@ +// This file is autogenerated by hidl-gen -Landroidbp. + +hidl_interface { + name: "android.hardware.camera.provider@2.7", + root: "android.hardware", + srcs: [ + "types.hal", + "ICameraProvider.hal", + ], + interfaces: [ + "android.hardware.camera.common@1.0", + "android.hardware.camera.device@1.0", + "android.hardware.camera.device@3.2", + "android.hardware.camera.device@3.3", + "android.hardware.camera.device@3.4", + "android.hardware.camera.device@3.5", + "android.hardware.camera.device@3.6", + "android.hardware.camera.device@3.7", + "android.hardware.camera.provider@2.4", + "android.hardware.camera.provider@2.5", + "android.hardware.camera.provider@2.6", + "android.hardware.graphics.common@1.0", + "android.hidl.base@1.0", + ], + gen_java: false, +} diff --git a/camera/provider/2.7/ICameraProvider.hal b/camera/provider/2.7/ICameraProvider.hal new file mode 100644 index 0000000000..c9d52ee21c --- /dev/null +++ b/camera/provider/2.7/ICameraProvider.hal @@ -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.camera.provider@2.7; + +import @2.6::ICameraProvider; +import android.hardware.camera.common@1.0::Status; + +/** + * Camera provider HAL + * + * Adds support for the isConcurrentStreamCombinationSupported() with + * ICameraDevice@3.7::StreamConfiguration. + */ +interface ICameraProvider extends @2.6::ICameraProvider { + /** + * isConcurrentStreamCombinationSupported_2_7: + * + * Identical to @2.6::isConcurrentStreamCombinationSupported except that + * this function takes a vector of @3.7::StreamConfiguration. + * + * @param configs a vector of camera ids and their corresponding stream + * configurations that need to be queried for support. + * + * @return status Status code for the operation, one of: + * OK: + * On successful stream combination query. + * METHOD_NOT_SUPPORTED: + * The camera provider does not support stream combination query. + * INTERNAL_ERROR: + * The stream combination query cannot complete due to internal + * error. + * @return true in case the stream combination is supported, false otherwise. + * + */ + isConcurrentStreamCombinationSupported_2_7(vec configs) + generates (Status status, bool queryStatus); +}; diff --git a/camera/provider/2.7/types.hal b/camera/provider/2.7/types.hal new file mode 100644 index 0000000000..363e894ed3 --- /dev/null +++ b/camera/provider/2.7/types.hal @@ -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.camera.provider@2.7; + +import android.hardware.camera.device@3.7::StreamConfiguration; + +/** + * CameraIdAndStreamCombination: + * + * This is identical to @2.6::CameraIdAndStreamCombination except that + * streamConfiguration is of version @3.7. + */ +struct CameraIdAndStreamCombination { + string cameraId; + @3.7::StreamConfiguration streamConfiguration; +}; diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index 6562f2282f..1f9cdb9c7f 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -165,7 +165,7 @@
    android.hardware.camera.provider - 2.4-6 + 2.4-7 ICameraProvider [^/]+/[0-9]+ -- GitLab From 8c8e4c69e9f36bec9e2b746d12ea43dff8a1cbbc Mon Sep 17 00:00:00 2001 From: f Date: Fri, 5 Mar 2021 05:12:58 +0000 Subject: [PATCH 508/790] Remove timeout from IFingerprint generateChallenge Bug: 181699471 Test: atest VtsHalBiometricsFingerprintTargetTest Change-Id: I30e3ff213e34354310b77c9cffad3c46c3256dc7 --- .../hardware/biometrics/fingerprint/ISession.aidl | 2 +- .../hardware/biometrics/fingerprint/ISession.aidl | 14 ++++++-------- biometrics/fingerprint/aidl/default/Session.cpp | 6 +++--- .../aidl/default/include/FakeFingerprintEngine.h | 4 ++-- .../fingerprint/aidl/default/include/Session.h | 2 +- 5 files changed, 13 insertions(+), 15 deletions(-) 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 cade76dcb7..87eaf96a41 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 @@ -34,7 +34,7 @@ package android.hardware.biometrics.fingerprint; @VintfStability interface ISession { - void generateChallenge(in int cookie, in int timeoutSec); + void generateChallenge(in int cookie); void revokeChallenge(in int cookie, in long challenge); android.hardware.biometrics.common.ICancellationSignal enroll(in int cookie, in android.hardware.keymaster.HardwareAuthToken hat); android.hardware.biometrics.common.ICancellationSignal authenticate(in int cookie, in long operationId); diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl index ab7930d81b..ef2e6fc499 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl @@ -61,7 +61,7 @@ interface ISession { * to allow addition of biometric enrollments. * To secure this path, the following path is taken: * 1) Upon user requesting fingerprint enroll, the framework requests - * IFingerprint#generateChallenge + * ISession#generateChallenge * 2) Framework sends the challenge to the credential subsystem, and upon credential * confirmation, a HAT is created, containing the challenge in the "challenge" field. * 3) Framework sends the HAT to the HAL, e.g. ISession#enroll. @@ -69,10 +69,9 @@ interface ISession { * 5) Implementation now has confidence that the user entered their credential to allow * biometric enrollment. * - * Note that the interface allows multiple in-flight challenges. For example, invoking - * generateChallenge(0, 0, timeoutSec, cb) twice does not invalidate the first challenge. The - * challenge is invalidated only when: - * 1) The provided timeout expires, or + * Note that this interface allows multiple in-flight challenges. Invoking generateChallenge + * twice does not invalidate the first challenge. The challenge is invalidated only when: + * 1) Its lifespan exceeds the HAL's internal challenge timeout * 2) IFingerprint#revokeChallenge is invoked * * For example, the following is a possible table of valid challenges: @@ -86,9 +85,8 @@ interface ISession { * ---------------------------------------------- * * @param cookie A unique number identifying this operation - * @param timeoutSec Duration for which the challenge is valid for */ - void generateChallenge(in int cookie, in int timeoutSec); + void generateChallenge(in int cookie); /** * revokeChallenge: @@ -117,7 +115,7 @@ interface ISession { * * Before capturing fingerprint data, the implementation must first verify the authenticity and * integrity of the provided HardwareAuthToken. In addition, it must check that the challenge - * within the provided HardwareAuthToken is valid. See IFingerprint#generateChallenge. If any of + * within the provided HardwareAuthToken is valid. See ISession#generateChallenge. If any of * the above checks fail, the framework must be notified via ISessionCallback#onError and the * HAL must notify the framework when it returns to the idle state. See * Error::UNABLE_TO_PROCESS. diff --git a/biometrics/fingerprint/aidl/default/Session.cpp b/biometrics/fingerprint/aidl/default/Session.cpp index f6a03143a0..9e6ac77a2f 100644 --- a/biometrics/fingerprint/aidl/default/Session.cpp +++ b/biometrics/fingerprint/aidl/default/Session.cpp @@ -60,13 +60,13 @@ bool Session::isClosed() { return mCurrentState == SessionState::CLOSED; } -ndk::ScopedAStatus Session::generateChallenge(int32_t cookie, int32_t timeoutSec) { +ndk::ScopedAStatus Session::generateChallenge(int32_t cookie) { LOG(INFO) << "generateChallenge"; scheduleStateOrCrash(SessionState::GENERATING_CHALLENGE); - mWorker->schedule(Callable::from([this, cookie, timeoutSec] { + mWorker->schedule(Callable::from([this, cookie] { enterStateOrCrash(cookie, SessionState::GENERATING_CHALLENGE); - mEngine->generateChallengeImpl(mCb.get(), timeoutSec); + mEngine->generateChallengeImpl(mCb.get()); enterIdling(cookie); })); diff --git a/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h index 934331638e..42e1aa5357 100644 --- a/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h +++ b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h @@ -22,7 +22,7 @@ namespace aidl::android::hardware::biometrics::fingerprint { class FakeFingerprintEngine { public: - void generateChallengeImpl(ISessionCallback* cb, int32_t /*timeoutSec*/) { + void generateChallengeImpl(ISessionCallback* cb) { LOG(INFO) << "generateChallengeImpl"; cb->onChallengeGenerated(0 /* challenge */); } @@ -73,4 +73,4 @@ class FakeFingerprintEngine { } }; -} // namespace aidl::android::hardware::biometrics::fingerprint \ No newline at end of file +} // 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 adda8310f4..d2f0c19777 100644 --- a/biometrics/fingerprint/aidl/default/include/Session.h +++ b/biometrics/fingerprint/aidl/default/include/Session.h @@ -32,7 +32,7 @@ class Session : public BnSession { Session(int sensorId, int userId, std::shared_ptr cb, FakeFingerprintEngine* engine, WorkerThread* worker); - ndk::ScopedAStatus generateChallenge(int32_t cookie, int32_t timeoutSec) override; + ndk::ScopedAStatus generateChallenge(int32_t cookie) override; ndk::ScopedAStatus revokeChallenge(int32_t cookie, int64_t challenge) override; -- GitLab From ef7c2a915c41b5dfbe25053694cf35a1523a32ed Mon Sep 17 00:00:00 2001 From: f Date: Fri, 5 Mar 2021 05:40:54 +0000 Subject: [PATCH 509/790] Remove timeout from IFace generateChallenge Bug: 181699471 Test: atest VtsHalBiometricsFaceTargetTest Change-Id: Ief068efc3a2c12fbc6b7d89229355ffbcc1b279c --- .../hardware/biometrics/face/ISession.aidl | 2 +- .../hardware/biometrics/face/ISession.aidl | 16 +++++++--------- biometrics/face/aidl/default/Session.cpp | 2 +- biometrics/face/aidl/default/Session.h | 2 +- 4 files changed, 10 insertions(+), 12 deletions(-) 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 4aef61a0a5..205429bd7a 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 @@ -34,7 +34,7 @@ package android.hardware.biometrics.face; @VintfStability interface ISession { - void generateChallenge(in int cookie, in int timeoutSec); + void generateChallenge(in int cookie); void revokeChallenge(in int cookie, in long challenge); android.hardware.biometrics.common.ICancellationSignal enroll(in int cookie, in android.hardware.keymaster.HardwareAuthToken hat, in android.hardware.biometrics.face.EnrollmentType type, in android.hardware.biometrics.face.Feature[] features, in android.hardware.common.NativeHandle previewSurface); android.hardware.biometrics.common.ICancellationSignal authenticate(in int cookie, in long operationId); diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl index 6f2014a61f..66c7c38710 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl @@ -45,7 +45,7 @@ interface ISession { * to allow addition of biometric enrollments. * To secure this path, the following path is taken: * 1) Upon user requesting face enroll, the framework requests - * IFace#generateChallenge + * ISession#generateChallenge * 2) Framework sends the challenge to the credential subsystem, and upon credential * confirmation, a HAT is created, containing the challenge in the "challenge" field. * 3) Framework sends the HAT to the HAL, e.g. ISession#enroll. @@ -53,11 +53,10 @@ interface ISession { * 5) Implementation now has confidence that the user entered their credential to allow * biometric enrollment. * - * Note that the interface allows multiple in-flight challenges. For example, invoking - * generateChallenge(0, 0, timeoutSec) twice does not invalidate the first challenge. The - * challenge is invalidated only when: - * 1) The provided timeout expires, or - * 2) IFace#revokeChallenge is invoked + * Note that this interface allows multiple in-flight challenges. Invoking generateChallenge + * twice does not invalidate the first challenge. The challenge is invalidated only when: + * 1) Its lifespan exceeds the HAL's internal challenge timeout + * 2) IFingerprint#revokeChallenge is invoked * * For example, the following is a possible table of valid challenges: * ---------------------------------------------- @@ -70,9 +69,8 @@ interface ISession { * ---------------------------------------------- * * @param cookie A unique number identifying this operation - * @param timeoutSec Duration for which the challenge is valid for */ - void generateChallenge(in int cookie, in int timeoutSec); + void generateChallenge(in int cookie); /** * revokeChallenge: @@ -113,7 +111,7 @@ interface ISession { * * Before capturing face data, the implementation must first verify the authenticity and * integrity of the provided HardwareAuthToken. In addition, it must check that the challenge - * within the provided HardwareAuthToken is valid. See IFace#generateChallenge. If any of + * within the provided HardwareAuthToken is valid. See ISession#generateChallenge. If any of * the above checks fail, the framework must be notified via ISessionCallback#onError and the * HAL must notify the framework when it returns to the idle state. See * Error::UNABLE_TO_PROCESS. diff --git a/biometrics/face/aidl/default/Session.cpp b/biometrics/face/aidl/default/Session.cpp index a7130e62d0..ce6c5572e6 100644 --- a/biometrics/face/aidl/default/Session.cpp +++ b/biometrics/face/aidl/default/Session.cpp @@ -37,7 +37,7 @@ class CancellationSignal : public common::BnCancellationSignal { Session::Session(std::shared_ptr cb) : cb_(std::move(cb)) {} -ndk::ScopedAStatus Session::generateChallenge(int32_t /*cookie*/, int32_t /*timeoutSec*/) { +ndk::ScopedAStatus Session::generateChallenge(int32_t /*cookie*/) { LOG(INFO) << "generateChallenge"; if (cb_) { cb_->onStateChanged(0, SessionState::GENERATING_CHALLENGE); diff --git a/biometrics/face/aidl/default/Session.h b/biometrics/face/aidl/default/Session.h index 0651726d0a..eb9ae83342 100644 --- a/biometrics/face/aidl/default/Session.h +++ b/biometrics/face/aidl/default/Session.h @@ -30,7 +30,7 @@ class Session : public BnSession { public: explicit Session(std::shared_ptr cb); - ndk::ScopedAStatus generateChallenge(int32_t cookie, int32_t timeoutSec) override; + ndk::ScopedAStatus generateChallenge(int32_t cookie) override; ndk::ScopedAStatus revokeChallenge(int32_t cookie, int64_t challenge) override; -- GitLab From d7ce9e5b1795eaa7d689b83994cdd3d05ad6991a Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Fri, 5 Mar 2021 16:19:26 -0800 Subject: [PATCH 510/790] Add missing return in Tuner default impl getAvSharedHandle after hidl_cb Per CTS automation test failure logs: Abort message: 'getAvSharedHandle: _hidl_cb called a second time, but must be called once.' this should be the root cause of the failure. Couldn't reproduce locally. Test: make Bug: 181997400 Change-Id: Ib3fb5ad535ab51cc7281c3f81a61d1913a1f4e65 --- tv/tuner/1.1/default/Filter.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tv/tuner/1.1/default/Filter.cpp b/tv/tuner/1.1/default/Filter.cpp index aec1fd0576..5ddac9909f 100644 --- a/tv/tuner/1.1/default/Filter.cpp +++ b/tv/tuner/1.1/default/Filter.cpp @@ -259,11 +259,14 @@ Return Filter::getAvSharedHandle(getAvSharedHandle_cb _hidl_cb) { int av_fd = createAvIonFd(BUFFER_SIZE_16M); if (av_fd == -1) { _hidl_cb(Result::UNKNOWN_ERROR, NULL, 0); + return Void(); } native_handle_t* nativeHandle = createNativeHandle(av_fd); if (nativeHandle == NULL) { + ::close(av_fd); _hidl_cb(Result::UNKNOWN_ERROR, NULL, 0); + return Void(); } mSharedAvMemHandle.setTo(nativeHandle, /*shouldOwn=*/true); ::close(av_fd); -- GitLab From 6a25dc5f40eb14e3eb83213ff88e888c20c58eb3 Mon Sep 17 00:00:00 2001 From: f Date: Sat, 6 Mar 2021 03:35:51 +0000 Subject: [PATCH 511/790] Update AcquiredInfo constants Bug: 173711478 Test: m android.hardware.biometrics.face-update-api Change-Id: Ib929c70af16b73a902666e4af96ed95be4629f3c --- .../hardware/biometrics/face/AcquiredInfo.aidl | 4 +--- .../hardware/biometrics/face/AcquiredInfo.aidl | 17 ++--------------- 2 files changed, 3 insertions(+), 18 deletions(-) diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl index 2600e61bee..c19534c016 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl @@ -59,7 +59,5 @@ enum AcquiredInfo { VENDOR = 22, FIRST_FRAME_RECEIVED = 23, DARK_GLASSES_DETECTED = 24, - FACE_COVERING_DETECTED = 25, - EYES_NOT_VISIBLE = 26, - MOUTH_NOT_VISIBLE = 27, + MOUTH_COVERING_DETECTED = 25, } diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl index 217a9bbfb1..a3b229e83a 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl @@ -187,7 +187,7 @@ enum AcquiredInfo { */ ROLL_TOO_EXTREME = 18, - /** + /** * The user’s face has been obscured by some object. * * The user should be informed to remove any objects from the line of sight from @@ -230,18 +230,5 @@ enum AcquiredInfo { * A face mask or face covering detected. This can be useful for providing relevant feedback to * the user and enabling an alternative authentication logic if the implementation supports it. */ - FACE_COVERING_DETECTED = 25, - - /** - * Either one or both eyes are not visible in the frame. Prefer to use DARK_GLASSES_DETECTED if - * the eyes are not visible due to dark glasses. - */ - EYES_NOT_VISIBLE = 26, - - /** - * The mouth is not visible in the frame. Prefer to use MASK_DETECTED if the mouth is not - * visible due to a mask. - */ - MOUTH_NOT_VISIBLE = 27, + MOUTH_COVERING_DETECTED = 25, } - -- GitLab From 0f7ed1d9eb37daba886a065205e0866cfd504a0a Mon Sep 17 00:00:00 2001 From: Daniel Bright Date: Thu, 4 Mar 2021 13:31:28 -0800 Subject: [PATCH 512/790] Get Radio Hal Capabilities in VTS * Created utility method in v1_6 HAL to access radio hal capabilities * Created static library to support getting the capaiblities response * Created RadioResponseWaiter to encapsulate the notify \ wait logic used when waiting for an asynchronous response from the HAL * Usage: if (getRadioHalCapabilities().modemReducedFeatureSet1) { ... } Bug: 181895757 Test: Accessed default hal capabilities Change-Id: Ie0a727d4e9d268ad03cf3fa793aa456a95c89f5b --- radio/1.0/vts/functional/vts_test_util.cpp | 33 ++++++++++- radio/1.0/vts/functional/vts_test_util.h | 24 +++++++- radio/1.6/vts/functional/Android.bp | 8 ++- .../vts/functional/radio_hidl_hal_test.cpp | 57 +++++++++---------- .../functional/radio_hidl_hal_utils_v1_6.h | 31 +++------- radio/1.6/vts/functional/radio_response.cpp | 2 +- radio/config/1.3/vts/functional/Android.bp | 23 ++++++++ .../functional/radio_config_hidl_hal_test.cpp | 29 ---------- .../functional/radio_config_hidl_hal_utils.h | 25 +++----- .../vts/functional/radio_config_response.cpp | 7 ++- 10 files changed, 134 insertions(+), 105 deletions(-) diff --git a/radio/1.0/vts/functional/vts_test_util.cpp b/radio/1.0/vts/functional/vts_test_util.cpp index 9a2d089899..fc372011ed 100644 --- a/radio/1.0/vts/functional/vts_test_util.cpp +++ b/radio/1.0/vts/functional/vts_test_util.cpp @@ -19,6 +19,8 @@ #include #include "VtsCoreUtil.h" +#define WAIT_TIMEOUT_PERIOD 75 + int GetRandomSerialNumber() { return rand(); } @@ -99,4 +101,33 @@ bool isVoiceEmergencyOnly(RegState state) { ::android::hardware::radio::V1_0::RegState::NOT_REG_MT_SEARCHING_OP_EM == state || ::android::hardware::radio::V1_0::RegState::REG_DENIED_EM == state || ::android::hardware::radio::V1_0::RegState::UNKNOWN_EM == state; -} \ No newline at end of file +} + +/* + * Notify that the response message is received. + */ +void RadioResponseWaiter::notify(int receivedSerial) { + std::unique_lock lock(mtx_); + if (serial == receivedSerial) { + count_++; + cv_.notify_one(); + } +} + +/* + * Wait till the response message is notified or till WAIT_TIMEOUT_PERIOD. + */ +std::cv_status RadioResponseWaiter::wait() { + std::unique_lock lock(mtx_); + + std::cv_status status = std::cv_status::no_timeout; + auto now = std::chrono::system_clock::now(); + while (count_ == 0) { + status = cv_.wait_until(lock, now + std::chrono::seconds(WAIT_TIMEOUT_PERIOD)); + if (status == std::cv_status::timeout) { + return status; + } + } + count_--; + return status; +} diff --git a/radio/1.0/vts/functional/vts_test_util.h b/radio/1.0/vts/functional/vts_test_util.h index 218e8236b0..08f7ba38bd 100644 --- a/radio/1.0/vts/functional/vts_test_util.h +++ b/radio/1.0/vts/functional/vts_test_util.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#pragma once + #include #include @@ -81,4 +83,24 @@ bool isVoiceEmergencyOnly(RegState state); /* * Check if voice status is in service. */ -bool isVoiceInService(RegState state); \ No newline at end of file +bool isVoiceInService(RegState state); + +/** + * Used when waiting for an asynchronous response from the HAL. + */ +class RadioResponseWaiter { + protected: + std::mutex mtx_; + std::condition_variable cv_; + int count_; + + public: + /* Serial number for radio request */ + int serial; + + /* Used as a mechanism to inform the test about data/event callback */ + void notify(int receivedSerial); + + /* Test code calls this function to wait for response */ + std::cv_status wait(); +}; diff --git a/radio/1.6/vts/functional/Android.bp b/radio/1.6/vts/functional/Android.bp index dde718b32c..65b0dd03ba 100644 --- a/radio/1.6/vts/functional/Android.bp +++ b/radio/1.6/vts/functional/Android.bp @@ -36,6 +36,7 @@ cc_test { ], static_libs: [ "RadioVtsTestUtilBase", + "RadioConfigVtsTestResponse", "android.hardware.radio@1.6", "android.hardware.radio@1.5", "android.hardware.radio@1.4", @@ -45,8 +46,13 @@ cc_test { "android.hardware.radio@1.0", "android.hardware.radio.config@1.0", "android.hardware.radio.config@1.1", + "android.hardware.radio.config@1.2", + "android.hardware.radio.config@1.3", + ], + header_libs: [ + "radio.util.header@1.0", + "radio.config.util.header@1.3", ], - header_libs: ["radio.util.header@1.0"], test_suites: [ "general-tests", "vts", diff --git a/radio/1.6/vts/functional/radio_hidl_hal_test.cpp b/radio/1.6/vts/functional/radio_hidl_hal_test.cpp index 59f768201d..6255f66f69 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_test.cpp +++ b/radio/1.6/vts/functional/radio_hidl_hal_test.cpp @@ -45,35 +45,6 @@ void RadioHidlTest_v1_6::SetUp() { EXPECT_EQ(CardState::PRESENT, cardStatus.base.base.base.cardState); } -/* - * Notify that the response message is received. - */ -void RadioHidlTest_v1_6::notify(int receivedSerial) { - std::unique_lock lock(mtx_); - if (serial == receivedSerial) { - count_++; - cv_.notify_one(); - } -} - -/* - * Wait till the response message is notified or till TIMEOUT_PERIOD. - */ -std::cv_status RadioHidlTest_v1_6::wait() { - std::unique_lock lock(mtx_); - - std::cv_status status = std::cv_status::no_timeout; - auto now = std::chrono::system_clock::now(); - while (count_ == 0) { - status = cv_.wait_until(lock, now + std::chrono::seconds(TIMEOUT_PERIOD)); - if (status == std::cv_status::timeout) { - return status; - } - } - count_--; - return status; -} - void RadioHidlTest_v1_6::clearPotentialEstablishedCalls() { // Get the current call Id to hangup the established emergency call. serial = GetRandomSerialNumber(); @@ -108,3 +79,31 @@ void RadioHidlTest_v1_6::getDataCallList() { radio_v1_6->getDataCallList_1_6(serial); EXPECT_EQ(std::cv_status::no_timeout, wait()); } + +/** + * Specific features on the Radio Hal rely on Radio Hal Capabilities. The VTS + * tests related to that features must not run if the related capability is + * disabled. + *

    + * Typical usage within VTS: + * if (getRadioHalCapabilities().modemReducedFeatureSet) return; + */ +HalDeviceCapabilities RadioHidlTest_v1_6::getRadioHalCapabilities() { + sp<::android::hardware::radio::config::V1_3::IRadioConfig> radioConfig_v1_3 = + ::android::hardware::radio::config::V1_3::IRadioConfig::getService(); + if (radioConfig_v1_3.get() == nullptr) { + // If v1_3 isn't present, the values are initialized to false + HalDeviceCapabilities radioHalCapabilities; + memset(&radioHalCapabilities, 0, sizeof(radioHalCapabilities)); + return radioHalCapabilities; + } else { + // Get radioHalDeviceCapabilities from the radio config + sp radioConfigRsp = new (std::nothrow) RadioConfigResponse(*this); + radioConfig_v1_3->setResponseFunctions(radioConfigRsp, nullptr); + serial = GetRandomSerialNumber(); + + radioConfig_v1_3->getHalDeviceCapabilities(serial); + EXPECT_EQ(std::cv_status::no_timeout, wait()); + return radioConfigRsp->halDeviceCapabilities; + } +} diff --git a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h index f610f2af76..23378b53d0 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h +++ b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h @@ -18,16 +18,12 @@ #include -#include -#include -#include -#include +#include "radio_config_hidl_hal_utils.h" + #include #include #include -#include - #include #include #include @@ -42,14 +38,15 @@ using namespace ::android::hardware::radio::V1_3; using namespace ::android::hardware::radio::V1_2; using namespace ::android::hardware::radio::V1_1; using namespace ::android::hardware::radio::V1_0; +using namespace ::android::hardware::radio::config::V1_3; using ::android::sp; using ::android::hardware::hidl_string; using ::android::hardware::hidl_vec; using ::android::hardware::Return; using ::android::hardware::Void; +using ::android::hardware::radio::config::V1_3::HalDeviceCapabilities; -#define TIMEOUT_PERIOD 75 #define MODEM_EMERGENCY_CALL_ESTABLISH_TIME 3 #define MODEM_EMERGENCY_CALL_DISCONNECT_TIME 3 @@ -61,7 +58,7 @@ extern ::android::hardware::radio::V1_5::CardStatus cardStatus; /* Callback class for radio response v1_6 */ class RadioResponse_v1_6 : public ::android::hardware::radio::V1_6::IRadioResponse { protected: - RadioHidlTest_v1_6& parent_v1_6; + RadioResponseWaiter& parent_v1_6; public: hidl_vec radioBandModes; @@ -105,7 +102,7 @@ class RadioResponse_v1_6 : public ::android::hardware::radio::V1_6::IRadioRespon ::android::hardware::radio::V1_5::CellIdentity barringCellIdentity; ::android::hardware::hidl_vec<::android::hardware::radio::V1_5::BarringInfo> barringInfos; - RadioResponse_v1_6(RadioHidlTest_v1_6& parent_v1_6); + RadioResponse_v1_6(RadioResponseWaiter& parent_v1_6); virtual ~RadioResponse_v1_6() = default; Return getIccCardStatusResponse( @@ -1079,15 +1076,9 @@ class RadioIndication_v1_6 : public ::android::hardware::radio::V1_6::IRadioIndi }; // The main test class for Radio HIDL. -class RadioHidlTest_v1_6 : public ::testing::TestWithParam { +class RadioHidlTest_v1_6 : public ::testing::TestWithParam, + public RadioResponseWaiter { protected: - std::mutex mtx_; - std::condition_variable cv_; - int count_; - - /* Serial number for radio request */ - int serial; - /* Clear Potential Established Calls */ void clearPotentialEstablishedCalls(); @@ -1100,11 +1091,7 @@ class RadioHidlTest_v1_6 : public ::testing::TestWithParam { public: virtual void SetUp() override; - /* Used as a mechanism to inform the test about data/event callback */ - void notify(int receivedSerial); - - /* Test code calls this function to wait for response */ - std::cv_status wait(); + HalDeviceCapabilities getRadioHalCapabilities(); /* radio service handle */ sp<::android::hardware::radio::V1_6::IRadio> radio_v1_6; diff --git a/radio/1.6/vts/functional/radio_response.cpp b/radio/1.6/vts/functional/radio_response.cpp index d9da40aaa6..8034fd2437 100644 --- a/radio/1.6/vts/functional/radio_response.cpp +++ b/radio/1.6/vts/functional/radio_response.cpp @@ -18,7 +18,7 @@ ::android::hardware::radio::V1_5::CardStatus cardStatus; -RadioResponse_v1_6::RadioResponse_v1_6(RadioHidlTest_v1_6& parent) : parent_v1_6(parent) {} +RadioResponse_v1_6::RadioResponse_v1_6(RadioResponseWaiter& parent) : parent_v1_6(parent) {} /* 1.0 Apis */ Return RadioResponse_v1_6::getIccCardStatusResponse( diff --git a/radio/config/1.3/vts/functional/Android.bp b/radio/config/1.3/vts/functional/Android.bp index aa3522dead..20c480ff3d 100644 --- a/radio/config/1.3/vts/functional/Android.bp +++ b/radio/config/1.3/vts/functional/Android.bp @@ -46,3 +46,26 @@ cc_test { "vts", ], } + +cc_library_static { + name: "RadioConfigVtsTestResponse", + defaults: ["VtsHalTargetTestDefaults"], + srcs : [ + "radio_config_response.cpp", + "radio_config_hidl_hal_test.cpp", + ], + header_libs: ["radio.util.header@1.0"], + static_libs: ["RadioVtsTestUtilBase"], + shared_libs: [ + "android.hardware.radio@1.0", + "android.hardware.radio.config@1.0", + "android.hardware.radio.config@1.1", + "android.hardware.radio.config@1.2", + "android.hardware.radio.config@1.3", + ], +} + +cc_library_headers { + name: "radio.config.util.header@1.3", + export_include_dirs: ["."], +} diff --git a/radio/config/1.3/vts/functional/radio_config_hidl_hal_test.cpp b/radio/config/1.3/vts/functional/radio_config_hidl_hal_test.cpp index de8365aee8..da614645f5 100644 --- a/radio/config/1.3/vts/functional/radio_config_hidl_hal_test.cpp +++ b/radio/config/1.3/vts/functional/radio_config_hidl_hal_test.cpp @@ -31,32 +31,3 @@ void RadioConfigHidlTest::SetUp() { radioConfig->setResponseFunctions(radioConfigRsp, nullptr); } - -/* - * Notify that the response message is received. - */ -void RadioConfigHidlTest::notify(int receivedSerial) { - std::unique_lock lock(mtx_); - if (serial == receivedSerial) { - count_++; - cv_.notify_one(); - } -} - -/* - * Wait till the response message is notified or till TIMEOUT_PERIOD. - */ -std::cv_status RadioConfigHidlTest::wait() { - std::unique_lock lock(mtx_); - - std::cv_status status = std::cv_status::no_timeout; - auto now = std::chrono::system_clock::now(); - while (count_ == 0) { - status = cv_.wait_until(lock, now + std::chrono::seconds(TIMEOUT_PERIOD)); - if (status == std::cv_status::timeout) { - return status; - } - } - count_--; - return status; -} diff --git a/radio/config/1.3/vts/functional/radio_config_hidl_hal_utils.h b/radio/config/1.3/vts/functional/radio_config_hidl_hal_utils.h index 439eb705b6..895ae08c23 100644 --- a/radio/config/1.3/vts/functional/radio_config_hidl_hal_utils.h +++ b/radio/config/1.3/vts/functional/radio_config_hidl_hal_utils.h @@ -14,6 +14,8 @@ * limitations under the License. */ +#pragma once + #include #include @@ -49,7 +51,6 @@ using ::android::hardware::radio::config::V1_3::HalDeviceCapabilities; using ::android::hardware::radio::config::V1_3::IRadioConfig; using ::android::hardware::radio::V1_0::RadioResponseInfo; -#define TIMEOUT_PERIOD 75 #define RADIO_SERVICE_NAME "slot1" class RadioConfigHidlTest; @@ -57,13 +58,14 @@ class RadioConfigHidlTest; /* Callback class for radio config response */ class RadioConfigResponse : public IRadioConfigResponse { protected: - RadioConfigHidlTest& parent; + RadioResponseWaiter& parent; public: RadioResponseInfo rspInfo; PhoneCapability phoneCap; + HalDeviceCapabilities halDeviceCapabilities; - RadioConfigResponse(RadioConfigHidlTest& parent); + RadioConfigResponse(RadioResponseWaiter& parent); virtual ~RadioConfigResponse() = default; Return getSimSlotsStatusResponse( @@ -107,26 +109,13 @@ class RadioConfigIndication : public IRadioConfigIndication { }; // The main test class for Radio config HIDL. -class RadioConfigHidlTest : public ::testing::TestWithParam { - protected: - std::mutex mtx_; - std::condition_variable cv_; - int count_; - +class RadioConfigHidlTest : public ::testing::TestWithParam, + public RadioResponseWaiter { public: virtual void SetUp() override; - /* Used as a mechanism to inform the test about data/event callback */ - void notify(int receivedSerial); - - /* Test code calls this function to wait for response */ - std::cv_status wait(); - void updateSimCardStatus(); - /* Serial number for radio request */ - int serial; - /* radio config service handle */ sp radioConfig; diff --git a/radio/config/1.3/vts/functional/radio_config_response.cpp b/radio/config/1.3/vts/functional/radio_config_response.cpp index 2a8b28ba7c..11e3cce147 100644 --- a/radio/config/1.3/vts/functional/radio_config_response.cpp +++ b/radio/config/1.3/vts/functional/radio_config_response.cpp @@ -18,7 +18,7 @@ // SimSlotStatus slotStatus; -RadioConfigResponse::RadioConfigResponse(RadioConfigHidlTest& parent) : parent(parent) {} +RadioConfigResponse::RadioConfigResponse(RadioResponseWaiter& parent) : parent(parent) {} Return RadioConfigResponse::getSimSlotsStatusResponse( const ::android::hardware::radio::V1_0::RadioResponseInfo& /* info */, @@ -65,6 +65,7 @@ Return RadioConfigResponse::setModemsConfigResponse( Return RadioConfigResponse::getHalDeviceCapabilitiesResponse( const ::android::hardware::radio::V1_6::RadioResponseInfo& /* info */, - const ::android::hardware::radio::config::V1_3::HalDeviceCapabilities& /* capabilities */) { + const ::android::hardware::radio::config::V1_3::HalDeviceCapabilities& capabilities) { + halDeviceCapabilities = capabilities; return Void(); -} \ No newline at end of file +} -- GitLab From 7e4c587ae32aca644254fa206de5131553975f4b Mon Sep 17 00:00:00 2001 From: Edwin Wong Date: Fri, 5 Feb 2021 12:47:20 -0800 Subject: [PATCH 513/790] [RESTRICT AUTOMERGE] Fix CryptoPlugin use after free vulnerability. The shared memory buffer used by srcPtr can be freed by another thread because it is not protected by a mutex. Subsequently, a use after free AIGABRT can occur in a race condition. SafetyNet logging is not added to avoid log spamming. The mutex lock is called to setup for decryption, which is called frequently. Test is run on rvc-dev branch, using target_hwasan-userdebug build. Test: sts sts-tradefed run sts-engbuild-no-spl-lock -m StsHostTestCases --test android.security.sts.Bug_176495665#testPocBug_176495665 Test: push to device with target_hwasan-userdebug build adb shell /data/local/tmp/Bug-176495665_sts64 Bug: 176495665 Bug: 176444161 Change-Id: If40e792cf78445a4b2dcce6a7d7905b5342c1724 --- drm/1.0/default/Android.bp | 3 ++- drm/1.0/default/CryptoPlugin.cpp | 9 +++++++-- drm/1.0/default/CryptoPlugin.h | 21 +++++++++++++-------- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/drm/1.0/default/Android.bp b/drm/1.0/default/Android.bp index ed6bcdeee6..1122e46a05 100644 --- a/drm/1.0/default/Android.bp +++ b/drm/1.0/default/Android.bp @@ -9,6 +9,7 @@ cc_library_static { "-Werror", "-Wextra", "-Wall", + "-Wthread-safety", ], shared_libs: [ "liblog", @@ -19,5 +20,5 @@ cc_library_static { export_header_lib_headers: [ "libutils_headers", ], - export_include_dirs : ["include"] + export_include_dirs: ["include"], } diff --git a/drm/1.0/default/CryptoPlugin.cpp b/drm/1.0/default/CryptoPlugin.cpp index 2a85f0e3d3..74047ff9e9 100644 --- a/drm/1.0/default/CryptoPlugin.cpp +++ b/drm/1.0/default/CryptoPlugin.cpp @@ -54,6 +54,8 @@ namespace implementation { sp hidlMemory = mapMemory(base); ALOGE_IF(hidlMemory == nullptr, "mapMemory returns nullptr"); + std::unique_lock lock(mSharedBufferLock); + // allow mapMemory to return nullptr mSharedBufferMap[bufferId] = hidlMemory; return Void(); @@ -66,7 +68,7 @@ namespace implementation { const SharedBuffer& source, uint64_t offset, const DestinationBuffer& destination, decrypt_cb _hidl_cb) { - + std::unique_lock lock(mSharedBufferLock); if (mSharedBufferMap.find(source.bufferId) == mSharedBufferMap.end()) { _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "source decrypt buffer base not set"); return Void(); @@ -80,7 +82,7 @@ namespace implementation { } } - android::CryptoPlugin::Mode legacyMode; + android::CryptoPlugin::Mode legacyMode = android::CryptoPlugin::kMode_Unencrypted; switch(mode) { case Mode::UNENCRYPTED: legacyMode = android::CryptoPlugin::kMode_Unencrypted; @@ -176,6 +178,9 @@ namespace implementation { _hidl_cb(Status::BAD_VALUE, 0, "invalid destination type"); return Void(); } + + // release mSharedBufferLock + lock.unlock(); ssize_t result = mLegacyPlugin->decrypt(secure, keyId.data(), iv.data(), legacyMode, legacyPattern, srcPtr, legacySubSamples, subSamples.size(), destPtr, &detailMessage); diff --git a/drm/1.0/default/CryptoPlugin.h b/drm/1.0/default/CryptoPlugin.h index 11cc2aae47..13fe898cb6 100644 --- a/drm/1.0/default/CryptoPlugin.h +++ b/drm/1.0/default/CryptoPlugin.h @@ -17,11 +17,14 @@ #ifndef ANDROID_HARDWARE_DRM_V1_0__CRYPTOPLUGIN_H #define ANDROID_HARDWARE_DRM_V1_0__CRYPTOPLUGIN_H -#include +#include #include +#include #include #include +#include + namespace android { namespace hardware { namespace drm { @@ -60,19 +63,21 @@ struct CryptoPlugin : public ICryptoPlugin { Return setSharedBufferBase(const ::android::hardware::hidl_memory& base, uint32_t bufferId) override; - Return decrypt(bool secure, const hidl_array& keyId, - const hidl_array& iv, Mode mode, const Pattern& pattern, - const hidl_vec& subSamples, const SharedBuffer& source, - uint64_t offset, const DestinationBuffer& destination, - decrypt_cb _hidl_cb) override; + Return decrypt( + bool secure, const hidl_array& keyId, const hidl_array& iv, + Mode mode, const Pattern& pattern, const hidl_vec& subSamples, + const SharedBuffer& source, uint64_t offset, const DestinationBuffer& destination, + decrypt_cb _hidl_cb) override NO_THREAD_SAFETY_ANALYSIS; // use unique_lock -private: + private: android::CryptoPlugin *mLegacyPlugin; - std::map > mSharedBufferMap; + std::map> mSharedBufferMap GUARDED_BY(mSharedBufferLock); CryptoPlugin() = delete; CryptoPlugin(const CryptoPlugin &) = delete; void operator=(const CryptoPlugin &) = delete; + + std::mutex mSharedBufferLock; }; } // namespace implementation -- GitLab From 41242be732a4c2e944b1f2accfea49e1df3ad5f3 Mon Sep 17 00:00:00 2001 From: Mingguang Xu Date: Fri, 19 Feb 2021 18:16:01 -0800 Subject: [PATCH 514/790] WiFi: Get peer information (BSS load and rate statistics) from link layer stats Bug: 177069641 Test: atest VtsHalWifiV1_5TargetTest Signed-off-by: Mingguang Xu Change-Id: I3373d065a3b04d86f52d5bffe28d5581746cef4a --- wifi/1.5/default/hidl_struct_util.cpp | 40 +++++++++++++ wifi/1.5/default/hidl_struct_util.h | 5 ++ .../tests/hidl_struct_util_unit_tests.cpp | 59 +++++++++++++++++++ wifi/1.5/default/wifi_legacy_hal.cpp | 20 +++++++ wifi/1.5/default/wifi_legacy_hal.h | 6 ++ wifi/1.5/types.hal | 54 +++++++++++++++++ 6 files changed, 184 insertions(+) diff --git a/wifi/1.5/default/hidl_struct_util.cpp b/wifi/1.5/default/hidl_struct_util.cpp index cd0edbefb5..baa898e43c 100644 --- a/wifi/1.5/default/hidl_struct_util.cpp +++ b/wifi/1.5/default/hidl_struct_util.cpp @@ -1077,6 +1077,17 @@ bool convertLegacyLinkLayerStatsToHidl( 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; + // peer info legacy_stats conversion. + std::vector 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)) { + return false; + } + hidl_peers_info_stats.push_back(hidl_peer_info_stats); + } + hidl_stats->iface.peers = hidl_peers_info_stats; // radio legacy_stats conversion. std::vector hidl_radios_stats; for (const auto& legacy_radio_stats : legacy_stats.radios) { @@ -1094,6 +1105,35 @@ bool convertLegacyLinkLayerStatsToHidl( return true; } +bool convertLegacyPeerInfoStatsToHidl( + const legacy_hal::WifiPeerInfo& legacy_peer_info_stats, + 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; + + std::vector hidlRateStats; + for (const auto& legacy_rate_stats : legacy_peer_info_stats.rate_stats) { + StaRateStat rateStat; + if (!convertLegacyWifiRateInfoToHidl(legacy_rate_stats.rate, + &rateStat.rateInfo)) { + return false; + } + rateStat.txMpdu = legacy_rate_stats.tx_mpdu; + rateStat.rxMpdu = legacy_rate_stats.rx_mpdu; + rateStat.mpduLost = legacy_rate_stats.mpdu_lost; + rateStat.retries = legacy_rate_stats.retries; + hidlRateStats.push_back(rateStat); + } + hidl_peer_info_stats->rateStats = hidlRateStats; + return true; +} + bool convertLegacyRoamingCapabilitiesToHidl( const legacy_hal::wifi_roaming_capabilities& legacy_caps, StaRoamingCapabilities* hidl_caps) { diff --git a/wifi/1.5/default/hidl_struct_util.h b/wifi/1.5/default/hidl_struct_util.h index 8b81033fac..352f213664 100644 --- a/wifi/1.5/default/hidl_struct_util.h +++ b/wifi/1.5/default/hidl_struct_util.h @@ -212,6 +212,11 @@ uint32_t convertHidlUsableChannelFilterToLegacy(uint32_t hidl_filter_mask); bool convertLegacyWifiUsableChannelsToHidl( const std::vector& legacy_usable_channels, std::vector* 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 diff --git a/wifi/1.5/default/tests/hidl_struct_util_unit_tests.cpp b/wifi/1.5/default/tests/hidl_struct_util_unit_tests.cpp index 6391a6aec1..e70d7baa8a 100644 --- a/wifi/1.5/default/tests/hidl_struct_util_unit_tests.cpp +++ b/wifi/1.5/default/tests/hidl_struct_util_unit_tests.cpp @@ -132,6 +132,8 @@ TEST_F(HidlStructUtilTest, canConvertLegacyLinkLayerStatsToHidl) { legacy_hal::LinkLayerStats legacy_stats{}; legacy_stats.radios.push_back(legacy_hal::LinkLayerRadioStats{}); legacy_stats.radios.push_back(legacy_hal::LinkLayerRadioStats{}); + legacy_stats.peers.push_back(legacy_hal::WifiPeerInfo{}); + legacy_stats.peers.push_back(legacy_hal::WifiPeerInfo{}); legacy_stats.iface.beacon_rx = rand(); legacy_stats.iface.rssi_mgmt = rand(); legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].rx_mpdu = rand(); @@ -175,6 +177,7 @@ TEST_F(HidlStructUtilTest, canConvertLegacyLinkLayerStatsToHidl) { rand(); legacy_stats.iface.info.time_slicing_duty_cycle_percent = rand(); + legacy_stats.iface.num_peers = 1; for (auto& radio : legacy_stats.radios) { radio.stats.on_time = rand(); @@ -204,6 +207,31 @@ TEST_F(HidlStructUtilTest, canConvertLegacyLinkLayerStatsToHidl) { radio.channel_stats.push_back(channel_stat2); } + for (auto& peer : legacy_stats.peers) { + 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, + }; + 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, + }; + 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); @@ -330,6 +358,37 @@ TEST_F(HidlStructUtilTest, canConvertLegacyLinkLayerStatsToHidl) { converted.radios[i].channelStats[k].onTimeInMs); } } + + EXPECT_EQ(legacy_stats.peers.size(), converted.iface.peers.size()); + for (size_t i = 0; i < legacy_stats.peers.size(); i++) { + EXPECT_EQ(legacy_stats.peers[i].peer_info.bssload.sta_count, + converted.iface.peers[i].staCount); + EXPECT_EQ(legacy_stats.peers[i].peer_info.bssload.chan_util, + 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); + 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, + converted.iface.peers[i].rateStats[j].rxMpdu); + EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].mpdu_lost, + converted.iface.peers[i].rateStats[j].mpduLost); + EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].retries, + converted.iface.peers[i].rateStats[j].retries); + } + } } TEST_F(HidlStructUtilTest, CanConvertLegacyFeaturesToHidl) { diff --git a/wifi/1.5/default/wifi_legacy_hal.cpp b/wifi/1.5/default/wifi_legacy_hal.cpp index f5ca753824..8c64ebc566 100644 --- a/wifi/1.5/default/wifi_legacy_hal.cpp +++ b/wifi/1.5/default/wifi_legacy_hal.cpp @@ -715,9 +715,29 @@ std::pair WifiLegacyHal::getLinkLayerStats( 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) + + (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"; diff --git a/wifi/1.5/default/wifi_legacy_hal.h b/wifi/1.5/default/wifi_legacy_hal.h index 03ca8412ce..cf2450de8b 100644 --- a/wifi/1.5/default/wifi_legacy_hal.h +++ b/wifi/1.5/default/wifi_legacy_hal.h @@ -340,9 +340,15 @@ struct LinkLayerRadioStats { std::vector channel_stats; }; +struct WifiPeerInfo { + wifi_peer_info peer_info; + std::vector rate_stats; +}; + struct LinkLayerStats { wifi_iface_stat iface; std::vector radios; + std::vector peers; }; #pragma GCC diagnostic pop diff --git a/wifi/1.5/types.hal b/wifi/1.5/types.hal index e1c0d327e0..0543004f52 100644 --- a/wifi/1.5/types.hal +++ b/wifi/1.5/types.hal @@ -26,6 +26,7 @@ import @1.2::NanConfigRequestSupplemental; import @1.3::StaLinkLayerRadioStats; import @1.0::WifiChannelInMhz; import @1.0::WifiChannelWidthInMhz; +import @1.4::WifiRateInfo; /** * Wifi bands defined in 80211 spec. @@ -161,6 +162,54 @@ struct StaLinkLayerIfaceContentionTimeStats { uint32_t contentionNumSamples; }; +/** + * Per rate statistics. The rate is characterized by the combination of preamble, number of spatial + * streams, transmission bandwidth, and modulation and coding scheme (MCS). + */ +struct StaRateStat{ + /** + * Wifi rate information: preamble, number of spatial streams, bandwidth, MCS, etc. + */ + WifiRateInfo rateInfo; + /** + * Number of successfully transmitted data packets (ACK received) + */ + uint32_t txMpdu; + /** + * Number of received data packets + */ + uint32_t rxMpdu; + /** + * Number of data packet losses (no ACK) + */ + uint32_t mpduLost; + /** + * Number of data packet retries + */ + uint32_t retries; +}; + +/** + * Per peer statistics. The types of peer include the Access Point (AP), the Tunneled Direct Link + * Setup (TDLS), the Group Owner (GO), the Neighbor Awareness Networking (NAN), etc. + */ +struct StaPeerInfo { + /** + * Station count: The total number of stations currently associated with the peer. + */ + uint16_t staCount; + /** + * Channel utilization: The percentage of time (normalized to 255, i.e., x% corresponds to + * (int) x * 255 / 100) that the medium is sensed as busy measured by either physical or + * virtual carrier sense (CS) mechanism. + */ + uint16_t chanUtil; + /** + * Per rate statistics + */ + vec rateStats; +}; + /** * Iface statistics for the current connection. */ @@ -197,6 +246,11 @@ struct StaLinkLayerIfaceStats { * WME Voice (VO) Access Category (AC) contention time statistics. */ StaLinkLayerIfaceContentionTimeStats wmeVoContentionTimeStats; + + /** + * Per peer statistics. + */ + vec peers; }; /** -- GitLab From 9de6ef99e5abd0a3ccad23ff336b06fc87d318d8 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 8 Mar 2021 21:52:11 +0000 Subject: [PATCH 515/790] Remove IFingerprint#reset Bug: 181247174 Test: m android.hardware.biometrics.fingerprint-update-api Test: atest VtsHalBiometricsFingerprintTargetTest Change-Id: I2f25bde2955f90f6f0b66cd04faa735420fa1d6a --- .../hardware/biometrics/fingerprint/IFingerprint.aidl | 1 - .../hardware/biometrics/fingerprint/IFingerprint.aidl | 10 ---------- biometrics/fingerprint/aidl/default/Fingerprint.cpp | 6 ------ .../fingerprint/aidl/default/include/Fingerprint.h | 2 -- 4 files changed, 19 deletions(-) diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl index 07777c991b..5d3df6fbaa 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl @@ -36,5 +36,4 @@ package android.hardware.biometrics.fingerprint; 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); - void reset(); } diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl index 37062badae..98a45307b9 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl @@ -65,14 +65,4 @@ interface IFingerprint { * @return A new session */ ISession createSession(in int sensorId, in int userId, in ISessionCallback cb); - - /** - * Resets the HAL into a clean state, forcing it to cancel all of the pending operations, close - * its current session, and release all of the acquired resources. - * - * This should be used as a last resort to recover the HAL if the current session becomes - * unresponsive. The implementation might choose to restart the HAL process to get back into a - * good state. - */ - void reset(); } diff --git a/biometrics/fingerprint/aidl/default/Fingerprint.cpp b/biometrics/fingerprint/aidl/default/Fingerprint.cpp index 206f5187e9..79f48fe195 100644 --- a/biometrics/fingerprint/aidl/default/Fingerprint.cpp +++ b/biometrics/fingerprint/aidl/default/Fingerprint.cpp @@ -63,10 +63,4 @@ ndk::ScopedAStatus Fingerprint::createSession(int32_t sensorId, int32_t userId, return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Fingerprint::reset() { - // Crash. The system will start a fresh instance of the HAL. - CHECK(false) << "Unable to reset. Crashing."; - return ndk::ScopedAStatus::ok(); -} - } // namespace aidl::android::hardware::biometrics::fingerprint diff --git a/biometrics/fingerprint/aidl/default/include/Fingerprint.h b/biometrics/fingerprint/aidl/default/include/Fingerprint.h index 9b43419718..7bd3d6ddfd 100644 --- a/biometrics/fingerprint/aidl/default/include/Fingerprint.h +++ b/biometrics/fingerprint/aidl/default/include/Fingerprint.h @@ -34,8 +34,6 @@ class Fingerprint : public BnFingerprint { const std::shared_ptr& cb, std::shared_ptr* out) override; - ndk::ScopedAStatus reset() override; - private: std::unique_ptr mEngine; WorkerThread mWorker; -- GitLab From a44f5e998e6ae4779e51831e5aba4b03039d25f2 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 8 Mar 2021 22:31:13 +0000 Subject: [PATCH 516/790] Remove IFace#reset Bug: 181247174 Test: m android.hardware.biometrics.face-update-api Test: atest VtsHalBiometricsFaceTargetTest Change-Id: I0569bc52d4c8bc247425cb6784dd1400106077cf --- .../android/hardware/biometrics/face/IFace.aidl | 1 - .../aidl/android/hardware/biometrics/face/IFace.aidl | 10 ---------- biometrics/face/aidl/default/Face.cpp | 4 ---- biometrics/face/aidl/default/Face.h | 2 -- 4 files changed, 17 deletions(-) diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl index 0d1ef45d8e..fc4a4d04bb 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl @@ -36,5 +36,4 @@ package android.hardware.biometrics.face; interface IFace { android.hardware.biometrics.face.SensorProps[] getSensorProps(); android.hardware.biometrics.face.ISession createSession(in int sensorId, in int userId, in android.hardware.biometrics.face.ISessionCallback cb); - void reset(); } diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/IFace.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/IFace.aidl index afb7c8de65..11cdf7753e 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/IFace.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/IFace.aidl @@ -50,14 +50,4 @@ interface IFace { * @return A new session. */ ISession createSession(in int sensorId, in int userId, in ISessionCallback cb); - - /** - * Resets the HAL into a clean state, forcing it to cancel all of the pending operations, close - * its current session, and release all of the acquired resources. - * - * This should be used as a last resort to recover the HAL if the current session becomes - * unresponsive. The implementation might choose to restart the HAL process to get back into a - * good state. - */ - void reset(); } diff --git a/biometrics/face/aidl/default/Face.cpp b/biometrics/face/aidl/default/Face.cpp index 73e50f3151..a4520deb47 100644 --- a/biometrics/face/aidl/default/Face.cpp +++ b/biometrics/face/aidl/default/Face.cpp @@ -63,8 +63,4 @@ ndk::ScopedAStatus Face::createSession(int32_t /*sensorId*/, int32_t /*userId*/, return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Face::reset() { - return ndk::ScopedAStatus::ok(); -} - } // namespace aidl::android::hardware::biometrics::face diff --git a/biometrics/face/aidl/default/Face.h b/biometrics/face/aidl/default/Face.h index 809b8568c2..786b4f89fe 100644 --- a/biometrics/face/aidl/default/Face.h +++ b/biometrics/face/aidl/default/Face.h @@ -27,8 +27,6 @@ class Face : public BnFace { ndk::ScopedAStatus createSession(int32_t sensorId, int32_t userId, const std::shared_ptr& cb, std::shared_ptr* _aidl_return) override; - - ndk::ScopedAStatus reset() override; }; } // namespace aidl::android::hardware::biometrics::face -- GitLab From ed3d8cb87fb69497e2d291d19484c9d8d62c3887 Mon Sep 17 00:00:00 2001 From: lesl Date: Thu, 4 Mar 2021 13:50:32 +0800 Subject: [PATCH 517/790] wifi: Add unit for API doc. Bug: 181603380 Bug: 181246414 Test: Manual Test. SAP works normally. Change-Id: If06849ea5ae8a8ffa95abdb8f2d3f2ea337338ab --- wifi/hostapd/1.3/IHostapdCallback.hal | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wifi/hostapd/1.3/IHostapdCallback.hal b/wifi/hostapd/1.3/IHostapdCallback.hal index a098d87093..32083669d2 100644 --- a/wifi/hostapd/1.3/IHostapdCallback.hal +++ b/wifi/hostapd/1.3/IHostapdCallback.hal @@ -35,12 +35,12 @@ interface IHostapdCallback extends @1.1::IHostapdCallback { * The apIfaceInstance can be used to identify which instance the callback * is from. * Note: The apIfaceInstance must be same as ifaceName in single AP mode. - * @param freq The operational frequency of the AP. + * @param freqMhz The operational frequency of the AP in Mhz. * @param bandwidth The operational bandwidth of the AP. * @param generation The operational mode of the AP (e.g. 11ac, 11ax). * @param apIfaceInstanceMacAddress MAC Address of the apIfaceInstance. */ - oneway onApInstanceInfoChanged(string ifaceName, string apIfaceInstance, uint32_t freq, + oneway onApInstanceInfoChanged(string ifaceName, string apIfaceInstance, uint32_t freqMhz, Bandwidth bandwidth, Generation generation, MacAddress apIfaceInstanceMacAddress); /** -- GitLab From 48dc9fcea5bfd2b89682e05f45cd94b98919df0b Mon Sep 17 00:00:00 2001 From: f Date: Wed, 10 Mar 2021 04:40:58 +0000 Subject: [PATCH 518/790] Make states atomic and update comments Bug: 166800618 Test: atest VtsHalBiometricsFingerprintTargetTest Change-Id: I52ee6e8b6ddefdc972e803bcd81819f04061a570 --- .../fingerprint/aidl/default/Session.cpp | 2 +- .../aidl/default/include/Session.h | 19 +++++++++++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/biometrics/fingerprint/aidl/default/Session.cpp b/biometrics/fingerprint/aidl/default/Session.cpp index f6a03143a0..8db320569a 100644 --- a/biometrics/fingerprint/aidl/default/Session.cpp +++ b/biometrics/fingerprint/aidl/default/Session.cpp @@ -46,7 +46,7 @@ void Session::scheduleStateOrCrash(SessionState state) { void Session::enterStateOrCrash(int cookie, SessionState state) { CHECK(mScheduledState == state); - mCurrentState = mScheduledState; + mCurrentState = state; mScheduledState = SessionState::IDLING; mCb->onStateChanged(cookie, mCurrentState); } diff --git a/biometrics/fingerprint/aidl/default/include/Session.h b/biometrics/fingerprint/aidl/default/include/Session.h index adda8310f4..b5e55b3785 100644 --- a/biometrics/fingerprint/aidl/default/include/Session.h +++ b/biometrics/fingerprint/aidl/default/include/Session.h @@ -82,13 +82,28 @@ class Session : public BnSession { // by calling ISessionCallback#onStateChanged. void enterIdling(int cookie); + // The sensor and user IDs for which this session was created. int32_t mSensorId; int32_t mUserId; + + // Callback for talking to the framework. This callback must only be called from non-binder + // threads to prevent nested binder calls and consequently a binder thread exhaustion. + // Practically, it means that this callback should always be called from the worker thread. std::shared_ptr mCb; + + // Module that communicates to the actual fingerprint hardware, keystore, TEE, etc. In real + // life such modules typically consume a lot of memory and are slow to initialize. This is here + // to showcase how such a module can be used within a Session without incurring the high + // initialization costs every time a Session is constructed. FakeFingerprintEngine* mEngine; + + // Worker thread that allows to schedule tasks for asynchronous execution. WorkerThread* mWorker; - SessionState mScheduledState; - SessionState mCurrentState; + + // Simple representation of the session's state machine. These are atomic because they can be + // modified from both the main and the worker threads. + std::atomic mScheduledState; + std::atomic mCurrentState; }; } // namespace aidl::android::hardware::biometrics::fingerprint -- GitLab From f5c7dcee2d14734e013e0f32ee8f93cf0ae4ae5e Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Mon, 1 Mar 2021 20:18:26 -0800 Subject: [PATCH 519/790] Make the tv tuner hal use libdmabufheap instead of libion Cherry-pick the same change from aosp/1610134 on Tuner 1.0 to Tuner 1.1 in sc-dev branch Let the TV tuner HAL allocate DMA-BUFs fds with libdmabufheap. Devices supporting ION will continue to allocate from ION with the change. Devices that are deprecating ION will be able to allocate from the DMA-BUF heap framework instead. Both frameworks allocate DMA-BUFs, hence no other changes are required in the handling of the fd. Test: make android.hardware.tv.tuner@1.1-service and sampletis on Cuttlefish Refer to AOSP Change-Id: Ic147ed83c9097be76162a86cd4f94d3b1c27a10f Change-Id: Ibb4f29624008b5af24429c48fc72f6bf8a8bc5ac Bug: 181341260 Bug: 181997400 Change-Id: Ic392428f1cef183ef4c9c8720bc984673095f2a9 --- tv/tuner/1.1/default/Android.bp | 1 + tv/tuner/1.1/default/Filter.cpp | 16 +++++++++------- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/tv/tuner/1.1/default/Android.bp b/tv/tuner/1.1/default/Android.bp index 86025cf4dd..a612802527 100644 --- a/tv/tuner/1.1/default/Android.bp +++ b/tv/tuner/1.1/default/Android.bp @@ -31,6 +31,7 @@ cc_defaults { "android.hardware.tv.tuner@1.1", "android.hidl.memory@1.0", "libcutils", + "libdmabufheap", "libfmq", "libhidlbase", "libhidlmemory", diff --git a/tv/tuner/1.1/default/Filter.cpp b/tv/tuner/1.1/default/Filter.cpp index 5ddac9909f..7d609ea3dc 100644 --- a/tv/tuner/1.1/default/Filter.cpp +++ b/tv/tuner/1.1/default/Filter.cpp @@ -16,9 +16,11 @@ #define LOG_TAG "android.hardware.tv.tuner@1.1-Filter" -#include "Filter.h" +#include #include +#include "Filter.h" + namespace android { namespace hardware { namespace tv { @@ -829,15 +831,15 @@ void Filter::detachFilterFromRecord() { } int Filter::createAvIonFd(int size) { - // Create an ion fd and allocate an av fd mapped to a buffer to it. - int ion_fd = ion_open(); - if (ion_fd == -1) { - ALOGE("[Filter] Failed to open ion fd %d", errno); + // Create an DMA-BUF fd and allocate an av fd mapped to a buffer to it. + auto buffer_allocator = std::make_unique(); + if (!buffer_allocator) { + ALOGE("[Filter] Unable to create BufferAllocator object"); return -1; } int av_fd = -1; - ion_alloc_fd(dup(ion_fd), size, 0 /*align*/, ION_HEAP_SYSTEM_MASK, 0 /*flags*/, &av_fd); - if (av_fd == -1) { + av_fd = buffer_allocator->Alloc("system-uncached", size); + if (av_fd < 0) { ALOGE("[Filter] Failed to create av fd %d", errno); return -1; } -- GitLab From 1d8fb33f9fd94690ec7d4c56eb6f65019d1ca0c3 Mon Sep 17 00:00:00 2001 From: Amit Mahajan Date: Wed, 10 Mar 2021 14:43:29 -0800 Subject: [PATCH 520/790] Simplify slicing related structs. Test: atest VtsHalRadioV1_6TargetTest Bug: 178075054 Change-Id: I6f711321ff8825e86b3d1da20ea985e81088eae0 --- radio/1.6/types.hal | 58 +++++++++++---------------------------------- 1 file changed, 14 insertions(+), 44 deletions(-) diff --git a/radio/1.6/types.hal b/radio/1.6/types.hal index 6400c63b11..95eba69948 100644 --- a/radio/1.6/types.hal +++ b/radio/1.6/types.hal @@ -813,6 +813,11 @@ struct SliceInfo { * see: 3GPP TS 24.501 Section 9.11.2.8. */ int32_t mappedHplmnSD; + + /** + * Field to indicate the current status of the slice. + */ + SliceStatus status; }; /** @@ -986,9 +991,9 @@ struct SlicingConfig { */ vec urspRules; /** - * Struct containing all NSSAIs (list of slice info). + * List of all slices. */ - Nssais nssais; + vec sliceInfo; }; /** @@ -1011,7 +1016,6 @@ struct UrspRule { vec routeSelectionDescriptor; }; - /** * This struct represents a single route selection descriptor as defined in * 3GPP TS 24.526. @@ -1067,47 +1071,13 @@ safe_union OptionalSscMode { SscMode value; }; -/** - * This struct contains all NSSAIs (lists of slices). - */ -struct Nssais { - /** - * These are all the slices configured by the network. This includes allowed - * and rejected slices, as well as slices that are neither allowed nor rejected - * yet. Empty vector indicates that no slices are configured, and in that case - * allowed and rejected vectors must be empty as well. - */ - vec configured; - /** - * These are all the slices that the UE is allowed to use. All these slices - * must be configured as well. Empty vector indicates that no slices are - * allowed yet. - */ - vec allowed; - /** - * These are all the slices that the UE is not allowed to use. All these slices - * must be configured as well. Empty vector indicates that no slices are - * rejected yet. - */ - vec rejected; - /** - * Default configured NSSAI - */ - vec defaultConfigured; -}; - -/** - * This struct represents a network slice rejected by the network. It contains a - * rejectionCause corresponding to a rejected network slice. - */ -struct RejectedSliceInfo { - SliceInfo sliceInfo; - SliceRejectionCause rejectionCause; -}; - -enum SliceRejectionCause : int32_t { - NOT_AVAILABLE_IN_PLMN, - NOT_AVAILABLE_IN_REG_AREA, +enum SliceStatus : int32_t { + UNKNOWN, + CONFIGURED, // Configured but not allowed or rejected yet + ALLOWED, // Allowed to be used + REJECTED_NOT_AVAILABLE_IN_PLMN, // Rejected because not available in PLMN + REJECTED_NOT_AVAILABLE_IN_REG_AREA, // Rejected because not available in reg area + DEFAULT_CONFIGURED, // Considered valid when configured/allowed slices are not available }; /** -- GitLab From cfbfa1361d13219dc142df170abf08ca53fd0146 Mon Sep 17 00:00:00 2001 From: Kai Date: Wed, 10 Mar 2021 16:34:04 -0800 Subject: [PATCH 521/790] Correct Vehicle properties permissions Some properties has different documentation in types.hal and propertyHalIds. fix the inconsistency Add e2e test for system properties' permission Bug: 156660899 Test: atest VehicleHalTest Change-Id: I5cf77cf039508a383b0b2ea5836b3a29bca9e514 --- .../vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h | 10 +++++++++- automotive/vehicle/2.0/types.hal | 4 ++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h index 73513f4e4c..961f750bea 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h @@ -488,6 +488,14 @@ const ConfigDeclaration kVehicleProperties[]{ }, .initialValue = {.int32Values = {1}}}, + {.config = + { + .prop = toInt(VehicleProperty::PARKING_BRAKE_AUTO_APPLY), + .access = VehiclePropertyAccess::READ, + .changeMode = VehiclePropertyChangeMode::ON_CHANGE, + }, + .initialValue = {.int32Values = {1}}}, + {.config = { .prop = toInt(VehicleProperty::FUEL_LEVEL_LOW), @@ -1050,7 +1058,7 @@ const ConfigDeclaration kVehicleProperties[]{ {.config = { .prop = toInt(VehicleProperty::SUPPORT_CUSTOMIZE_VENDOR_PERMISSION), - .access = VehiclePropertyAccess::READ_WRITE, + .access = VehiclePropertyAccess::READ, .changeMode = VehiclePropertyChangeMode::ON_CHANGE, .configArray = {kMixedTypePropertyForTest, diff --git a/automotive/vehicle/2.0/types.hal b/automotive/vehicle/2.0/types.hal index e3fd16de57..20c2848547 100644 --- a/automotive/vehicle/2.0/types.hal +++ b/automotive/vehicle/2.0/types.hal @@ -688,7 +688,7 @@ enum VehicleProperty : int32_t { * Parking brake state. * * @change_mode VehiclePropertyChangeMode:ON_CHANGE - * @access VehiclePropertyAccess:READ_WRITE + * @access VehiclePropertyAccess:READ */ PARKING_BRAKE_ON = ( 0x0402 @@ -700,7 +700,7 @@ enum VehicleProperty : int32_t { * Auto-apply parking brake. * * @change_mode VehiclePropertyChangeMode:ON_CHANGE - * @access VehiclePropertyAccess:READ_WRITE + * @access VehiclePropertyAccess:READ */ PARKING_BRAKE_AUTO_APPLY = ( 0x0403 -- GitLab From e162c6cd3f998d2924486d6ec97de96ff571d9ef Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Thu, 4 Mar 2021 13:56:33 +0800 Subject: [PATCH 522/790] wifi: Add WFD R2 HAL API Bug: 179342930 Test: atest VtsHalWifiSupplicantP2pV1_4TargetTest Change-Id: I1c991fc6c3698eab1a32f728e9d71323a0103b21 --- wifi/supplicant/1.4/Android.bp | 1 + wifi/supplicant/1.4/ISupplicantP2pIface.hal | 33 +++++ .../1.4/ISupplicantP2pIfaceCallback.hal | 61 +++++++++ wifi/supplicant/1.4/types.hal | 4 + .../supplicant_p2p_iface_hidl_test.cpp | 121 ++++++++++++++++++ 5 files changed, 220 insertions(+) create mode 100644 wifi/supplicant/1.4/ISupplicantP2pIfaceCallback.hal diff --git a/wifi/supplicant/1.4/Android.bp b/wifi/supplicant/1.4/Android.bp index b486687d74..c988fdbb9e 100644 --- a/wifi/supplicant/1.4/Android.bp +++ b/wifi/supplicant/1.4/Android.bp @@ -16,6 +16,7 @@ hidl_interface { "types.hal", "ISupplicant.hal", "ISupplicantP2pIface.hal", + "ISupplicantP2pIfaceCallback.hal", "ISupplicantStaIface.hal", "ISupplicantStaNetwork.hal", "ISupplicantStaNetworkCallback.hal", diff --git a/wifi/supplicant/1.4/ISupplicantP2pIface.hal b/wifi/supplicant/1.4/ISupplicantP2pIface.hal index 65c761da80..28846dec64 100644 --- a/wifi/supplicant/1.4/ISupplicantP2pIface.hal +++ b/wifi/supplicant/1.4/ISupplicantP2pIface.hal @@ -17,6 +17,7 @@ package android.hardware.wifi.supplicant@1.4; import @1.2::ISupplicantP2pIface; +import ISupplicantP2pIfaceCallback; /** * Interface exposed by the supplicant for each P2P mode network @@ -48,4 +49,36 @@ interface ISupplicantP2pIface extends @1.2::ISupplicantP2pIface { * @return enabled true if set, false otherwise. */ getEdmg() generates (SupplicantStatus status, bool enabled); + + /** + * Register for callbacks from this interface. + * + * These callbacks are invoked for events that are specific to this interface. + * Registration of multiple callback objects is supported. These objects must + * be automatically deleted when the corresponding client process is dead or + * if this interface is removed. + * + * @param callback An instance of the |ISupplicantP2pIfaceCallback| HIDL + * interface object. + * @return status Status of the operation. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_UNKNOWN|, + * |SupplicantStatusCode.FAILURE_IFACE_INVALID| + */ + registerCallback_1_4(ISupplicantP2pIfaceCallback callback) + generates (SupplicantStatus status); + + /* + * Set Wifi Display R2 device info. + * + * @param info WFD R2 device info as described in section 5.1.12 of WFD technical + * specification v2.1. + * @return status Status of the operation. + * Possible status codes: + * |SupplicantStatusCode.SUCCESS|, + * |SupplicantStatusCode.FAILURE_UNKNOWN|, + * |SupplicantStatusCode.FAILURE_IFACE_INVALID| + */ + setWfdR2DeviceInfo(uint8_t[4] info) generates (SupplicantStatus status); }; diff --git a/wifi/supplicant/1.4/ISupplicantP2pIfaceCallback.hal b/wifi/supplicant/1.4/ISupplicantP2pIfaceCallback.hal new file mode 100644 index 0000000000..a0912746fb --- /dev/null +++ b/wifi/supplicant/1.4/ISupplicantP2pIfaceCallback.hal @@ -0,0 +1,61 @@ +/* + * 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.wifi.supplicant@1.4; + +import @1.0::ISupplicantP2pIfaceCallback; +import @1.0::MacAddress; +import @1.0::WpsConfigMethods; +import @1.0::P2pGroupCapabilityMask; + +/** + * Callback Interface exposed by the supplicant service + * for each P2P mode interface (ISupplicantP2pIface). + * + * Clients need to host an instance of this HIDL interface object and + * pass a reference of the object to the supplicant via the + * corresponding |ISupplicantP2pIface.registerCallback| method. + */ +interface ISupplicantP2pIfaceCallback extends @1.0::ISupplicantP2pIfaceCallback { + /** + * Used to indicate that a P2P Wi-Fi Display R2 device has been found. Refer to + * Wi-Fi Display Technical Specification Version 2.0. + * + * @param srcAddress MAC address of the device found. This must either + * be the P2P device address for a peer which is not in a group, + * or the P2P interface address for a peer which is a Group Owner. + * @param p2pDeviceAddress P2P device address. + * @param primaryDeviceType Type of device. Refer to section B.1 of Wifi P2P + * Technical specification v1.2. + * @param deviceName Name of the device. + * @param configMethods Mask of WPS configuration methods supported by the + * device. + * @param deviceCapabilities Refer to section 4.1.4 of Wifi P2P Technical + * specification v1.2. + * @param groupCapabilites Refer to section 4.1.4 of Wifi P2P Technical + * specification v1.2. + * @param wfdDeviceInfo WFD device info as described in section 5.1.2 of WFD + * technical specification v1.0.0. + * @param wfdR2DeviceInfo WFD R2 device info as described in section 5.1.12 of WFD + * technical specification v2.1. + */ + oneway onR2DeviceFound( + MacAddress srcAddress, MacAddress p2pDeviceAddress, + uint8_t[8] primaryDeviceType, string deviceName, + bitfield configMethods, uint8_t deviceCapabilities, + bitfield groupCapabilities, uint8_t[6] wfdDeviceInfo, + uint8_t[2] wfdR2DeviceInfo); +}; diff --git a/wifi/supplicant/1.4/types.hal b/wifi/supplicant/1.4/types.hal index c39de6ead6..b72eb425b0 100644 --- a/wifi/supplicant/1.4/types.hal +++ b/wifi/supplicant/1.4/types.hal @@ -107,6 +107,10 @@ enum WpaDriverCapabilitiesMask : @1.3::WpaDriverCapabilitiesMask { * WPA3 SAE Public-Key. */ SAE_PK = 1 << 2, + /** + * Wi-Fi Display R2 + */ + WFD_R2 = 1 << 3, }; /** diff --git a/wifi/supplicant/1.4/vts/functional/supplicant_p2p_iface_hidl_test.cpp b/wifi/supplicant/1.4/vts/functional/supplicant_p2p_iface_hidl_test.cpp index 9185279f38..4427c390c4 100644 --- a/wifi/supplicant/1.4/vts/functional/supplicant_p2p_iface_hidl_test.cpp +++ b/wifi/supplicant/1.4/vts/functional/supplicant_p2p_iface_hidl_test.cpp @@ -28,16 +28,23 @@ #include "supplicant_hidl_test_utils_1_4.h" using ::android::sp; +using ::android::hardware::hidl_array; +using ::android::hardware::hidl_string; +using ::android::hardware::hidl_vec; +using ::android::hardware::Return; using ::android::hardware::Void; using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatus; using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatusCode; using ::android::hardware::wifi::supplicant::V1_4::ISupplicantP2pIface; +using ::android::hardware::wifi::supplicant::V1_4::ISupplicantP2pIfaceCallback; using SupplicantStatusV1_4 = ::android::hardware::wifi::supplicant::V1_4::SupplicantStatus; using SupplicantStatusCodeV1_4 = ::android::hardware::wifi::supplicant::V1_4::SupplicantStatusCode; +constexpr uint8_t kTestWfdR2DeviceInfo[] = {[0 ... 3] = 0x01}; + class SupplicantP2pIfaceHidlTest : public SupplicantHidlTestBaseV1_4 { public: virtual void SetUp() override { @@ -51,6 +58,100 @@ class SupplicantP2pIfaceHidlTest : public SupplicantHidlTestBaseV1_4 { sp p2p_iface_; }; +class IfaceCallback : public ISupplicantP2pIfaceCallback { + Return onNetworkAdded(uint32_t /* id */) override { return Void(); } + Return onNetworkRemoved(uint32_t /* id */) override { return Void(); } + Return onDeviceFound( + const hidl_array& /* srcAddress */, + const hidl_array& /* p2pDeviceAddress */, + const hidl_array& /* primaryDeviceType */, + const hidl_string& /* deviceName */, uint16_t /* configMethods */, + uint8_t /* deviceCapabilities */, uint32_t /* groupCapabilities */, + const hidl_array& /* wfdDeviceInfo */) override { + return Void(); + } + Return onDeviceLost( + const hidl_array& /* p2pDeviceAddress */) override { + return Void(); + } + Return onFindStopped() override { return Void(); } + Return onGoNegotiationRequest( + const hidl_array& /* srcAddress */, + ISupplicantP2pIfaceCallback::WpsDevPasswordId /* passwordId */) + override { + return Void(); + } + Return onGoNegotiationCompleted( + ISupplicantP2pIfaceCallback::P2pStatusCode /* status */) override { + return Void(); + } + Return onGroupFormationSuccess() override { return Void(); } + Return onGroupFormationFailure( + const hidl_string& /* failureReason */) override { + return Void(); + } + Return onGroupStarted( + const hidl_string& /* groupIfname */, bool /* isGo */, + const hidl_vec& /* ssid */, uint32_t /* frequency */, + const hidl_array& /* psk */, + const hidl_string& /* passphrase */, + const hidl_array& /* goDeviceAddress */, + bool /* isPersistent */) override { + return Void(); + } + Return onGroupRemoved(const hidl_string& /* groupIfname */, + bool /* isGo */) override { + return Void(); + } + Return onInvitationReceived( + const hidl_array& /* srcAddress */, + const hidl_array& /* goDeviceAddress */, + const hidl_array& /* bssid */, + uint32_t /* persistentNetworkId */, + uint32_t /* operatingFrequency */) override { + return Void(); + } + Return onInvitationResult( + const hidl_array& /* bssid */, + ISupplicantP2pIfaceCallback::P2pStatusCode /* status */) override { + return Void(); + } + Return onProvisionDiscoveryCompleted( + const hidl_array& /* p2pDeviceAddress */, + bool /* isRequest */, + ISupplicantP2pIfaceCallback::P2pProvDiscStatusCode /* status */, + uint16_t /* configMethods */, + const hidl_string& /* generatedPin */) override { + return Void(); + } + Return onServiceDiscoveryResponse( + const hidl_array& /* srcAddress */, + uint16_t /* updateIndicator */, + const hidl_vec& /* tlvs */) override { + return Void(); + } + Return onStaAuthorized( + const hidl_array& /* srcAddress */, + const hidl_array& /* p2pDeviceAddress */) override { + return Void(); + } + Return onStaDeauthorized( + const hidl_array& /* srcAddress */, + const hidl_array& /* p2pDeviceAddress */) override { + return Void(); + } + Return onR2DeviceFound( + const hidl_array& /* srcAddress */, + const hidl_array& /* p2pDeviceAddress */, + const hidl_array& /* primaryDeviceType */, + const hidl_string& /* deviceName */, uint16_t /* configMethods */, + uint8_t /* deviceCapabilities */, uint32_t /* groupCapabilities */, + const hidl_array& /* wfdDeviceInfo */, + const hidl_array& /* wfdR2DeviceInfo */) override { + return Void(); + } +}; + /* * SetGetEdmg */ @@ -71,6 +172,26 @@ TEST_P(SupplicantP2pIfaceHidlTest, SetGetEdmg) { }); } +/* + * RegisterCallback_1_4 + */ +TEST_P(SupplicantP2pIfaceHidlTest, RegisterCallback_1_4) { + p2p_iface_->registerCallback_1_4( + new IfaceCallback(), [](const SupplicantStatusV1_4& status) { + EXPECT_EQ(SupplicantStatusCodeV1_4::SUCCESS, status.code); + }); +} + +/* + * SetWfdR2DeviceInfo + */ +TEST_P(SupplicantP2pIfaceHidlTest, SetWfdR2DeviceInfo) { + p2p_iface_->setWfdR2DeviceInfo( + kTestWfdR2DeviceInfo, [&](const SupplicantStatusV1_4& status) { + EXPECT_EQ(SupplicantStatusCodeV1_4::SUCCESS, status.code); + }); +} + GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantP2pIfaceHidlTest); INSTANTIATE_TEST_CASE_P( PerInstance, SupplicantP2pIfaceHidlTest, -- GitLab From 6365ea1dbba94da8a0f2fb63d00283109ee47f9b Mon Sep 17 00:00:00 2001 From: Xusong Wang Date: Tue, 16 Feb 2021 10:40:32 -0800 Subject: [PATCH 523/790] Passing padding information to the driver -- hal. This CL changes the sAIDL interface to enable passing padding information of the shared memory pool to the driver. The sAIDL interface defines the padding field explicitly in DataLocation to make it easy to convert to/from the canonical request. Bug: 179691454 Test: NNT_static Test: VtsHalNeuralnetworksTargetTest Change-Id: Ie13b421531ee4df48822086b027d94a622a3518c --- .../hardware/neuralnetworks/DataLocation.aidl | 1 + .../hardware/neuralnetworks/DataLocation.aidl | 21 +++++++++++++++++++ neuralnetworks/aidl/utils/src/Conversions.cpp | 6 ++++++ .../aidl/vts/functional/MemoryDomainTests.cpp | 9 +++++--- 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/DataLocation.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/DataLocation.aidl index 074cc0922d..e836daec96 100644 --- a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/DataLocation.aidl +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/DataLocation.aidl @@ -36,4 +36,5 @@ parcelable DataLocation { int poolIndex; long offset; long length; + long padding; } diff --git a/neuralnetworks/aidl/android/hardware/neuralnetworks/DataLocation.aidl b/neuralnetworks/aidl/android/hardware/neuralnetworks/DataLocation.aidl index f6b5e0d2ac..1b2378f016 100644 --- a/neuralnetworks/aidl/android/hardware/neuralnetworks/DataLocation.aidl +++ b/neuralnetworks/aidl/android/hardware/neuralnetworks/DataLocation.aidl @@ -18,6 +18,23 @@ package android.hardware.neuralnetworks; /** * Describes the location of a data object. + * + * If the data object is an omitted operand, all of the fields must be 0. If the poolIndex refers to + * a driver-managed buffer allocated from IDevice::allocate, or an AHardwareBuffer of a format other + * than AHARDWAREBUFFER_FORMAT_BLOB, the offset, length, and padding must be set to 0 indicating + * the entire pool is used. + * + * Otherwise, the offset, length, and padding specify a sub-region of a memory pool. The sum of + * offset, length, and padding must not exceed the total size of the specified memory pool. If the + * data object is a scalar operand or a tensor operand with fully specified dimensions, the value of + * length must be equal to the raw size of the operand (i.e. the size of an element multiplied + * by the number of elements). When used in Operand, the value of padding must be 0. When used in + * RequestArgument, the value of padding specifies the extra bytes at the end of the memory region + * that may be used by the device to access memory in chunks, for efficiency. If the data object is + * a Request output whose dimensions are not fully specified, the value of length specifies the + * total size of the writable region of the output data, and padding specifies the extra bytes at + * the end of the memory region that may be used by the device to access memory in chunks, for + * efficiency, but must not be used to hold any output data. */ @VintfStability parcelable DataLocation { @@ -33,4 +50,8 @@ parcelable DataLocation { * The length of the data in bytes. */ long length; + /** + * The end padding of the specified memory region in bytes. + */ + long padding; } diff --git a/neuralnetworks/aidl/utils/src/Conversions.cpp b/neuralnetworks/aidl/utils/src/Conversions.cpp index db3504bb74..9a06d475f8 100644 --- a/neuralnetworks/aidl/utils/src/Conversions.cpp +++ b/neuralnetworks/aidl/utils/src/Conversions.cpp @@ -254,16 +254,22 @@ GeneralResult unvalidatedConvert(const aidl_hal::DataLocation& loc VERIFY_NON_NEGATIVE(location.poolIndex) << "DataLocation: pool index must not be negative"; VERIFY_NON_NEGATIVE(location.offset) << "DataLocation: offset must not be negative"; VERIFY_NON_NEGATIVE(location.length) << "DataLocation: length must not be negative"; + VERIFY_NON_NEGATIVE(location.padding) << "DataLocation: padding must not be negative"; if (location.offset > std::numeric_limits::max()) { return NN_ERROR() << "DataLocation: offset must be <= std::numeric_limits::max()"; } if (location.length > std::numeric_limits::max()) { return NN_ERROR() << "DataLocation: length must be <= std::numeric_limits::max()"; } + if (location.padding > std::numeric_limits::max()) { + return NN_ERROR() + << "DataLocation: padding must be <= std::numeric_limits::max()"; + } return DataLocation{ .poolIndex = static_cast(location.poolIndex), .offset = static_cast(location.offset), .length = static_cast(location.length), + .padding = static_cast(location.padding), }; } diff --git a/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp b/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp index 1929750d28..57bc1aed54 100644 --- a/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp +++ b/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp @@ -1125,12 +1125,15 @@ TEST_P(MemoryDomainExecutionTest, InvalidDimensions) { utils::toSigned(kTestOperand.dimensions).value()); if (deviceBuffer.buffer == nullptr) return; - RequestMemoryPool sharedMemory = createSharedMemoryPool(kTestOperandDataSize); - RequestMemoryPool deviceMemory = createDeviceMemoryPool(deviceBuffer.token); + // Use an incompatible dimension and make sure the length matches with the bad dimension. auto badDimensions = utils::toSigned(kTestOperand.dimensions).value(); badDimensions[0] = 2; + const uint32_t badTestOperandDataSize = kTestOperandDataSize * 2; + + RequestMemoryPool sharedMemory = createSharedMemoryPool(badTestOperandDataSize); + RequestMemoryPool deviceMemory = createDeviceMemoryPool(deviceBuffer.token); RequestArgument sharedMemoryArg = { - .location = {.poolIndex = 0, .offset = 0, .length = kTestOperandDataSize}, + .location = {.poolIndex = 0, .offset = 0, .length = badTestOperandDataSize}, .dimensions = badDimensions}; RequestArgument deviceMemoryArg = {.location = {.poolIndex = 1}}; RequestArgument deviceMemoryArgWithBadDimensions = {.location = {.poolIndex = 1}, -- GitLab From df57fbfb6c507c5be627ef232ea62fe9a5ac0677 Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Thu, 11 Mar 2021 17:39:10 -0800 Subject: [PATCH 524/790] Improve Tuner 1.1 VTS configuration and 1.0 VTS compatibility This CL cherry-picks most of the backported changes of Tuner 1.0 from android 12 to android 11 vts branch to Tuner 1.1 VTS in Android 12 per BCM's suggestions Test: atest VtsHalTvTunerV1_0TargetTest Test: atest VtsHalTvTunerV1_1TargetTest Bug: 182519645 Change-Id: I3651396511fa067ce053ac2531cd2324832eb5f0 --- tv/tuner/1.0/vts/functional/FilterTests.cpp | 17 +++--- .../VtsHalTvTunerV1_0TestConfigurations.h | 2 +- tv/tuner/1.1/vts/functional/FilterTests.cpp | 6 +- tv/tuner/1.1/vts/functional/FilterTests.h | 2 +- tv/tuner/1.1/vts/functional/FrontendTests.cpp | 55 ++++++++++--------- tv/tuner/1.1/vts/functional/FrontendTests.h | 2 +- .../VtsHalTvTunerV1_1TargetTest.cpp | 39 +++++++++---- .../VtsHalTvTunerV1_1TestConfigurations.h | 8 +++ 8 files changed, 80 insertions(+), 51 deletions(-) diff --git a/tv/tuner/1.0/vts/functional/FilterTests.cpp b/tv/tuner/1.0/vts/functional/FilterTests.cpp index 1a09290725..f47024526d 100644 --- a/tv/tuner/1.0/vts/functional/FilterTests.cpp +++ b/tv/tuner/1.0/vts/functional/FilterTests.cpp @@ -70,10 +70,6 @@ void FilterCallback::filterThreadLoop(DemuxFilterEvent& /* event */) { } bool FilterCallback::readFilterEventData() { - if (mFilterMQ == NULL) { - ALOGW("[vts] FMQ is not configured and does not need to be tested."); - return true; - } bool result = false; DemuxFilterEvent filterEvent = mFilterEvent; ALOGW("[vts] reading from filter FMQ or buffer %d", mFilterId); @@ -95,16 +91,19 @@ bool FilterCallback::readFilterEventData() { } // EXPECT_TRUE(mDataLength == goldenDataOutputBuffer.size()) << "buffer size does not // match"; - - mDataOutputBuffer.resize(mDataLength); - result = mFilterMQ->read(mDataOutputBuffer.data(), mDataLength); - EXPECT_TRUE(result) << "can't read from Filter MQ"; + if (mFilterMQ != NULL) { + mDataOutputBuffer.resize(mDataLength); + result = mFilterMQ->read(mDataOutputBuffer.data(), mDataLength); + EXPECT_TRUE(result) << "can't read from Filter MQ"; + } /*for (int i = 0; i < mDataLength; i++) { EXPECT_TRUE(goldenDataOutputBuffer[i] == mDataOutputBuffer[i]) << "data does not match"; }*/ } - mFilterMQEventFlag->wake(static_cast(DemuxQueueNotifyBits::DATA_CONSUMED)); + if (mFilterMQ != NULL) { + mFilterMQEventFlag->wake(static_cast(DemuxQueueNotifyBits::DATA_CONSUMED)); + } return result; } diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h index b0a9c038e3..834e296872 100644 --- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h +++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h @@ -221,7 +221,7 @@ inline void initFrontendConfig() { frontendArray[DVBT].tuneStatusTypes = types; frontendArray[DVBT].expectTuneStatuses = statuses; frontendArray[DVBT].isSoftwareFe = true; - frontendArray[DVBS].enable = true; + frontendArray[DVBT].enable = true; frontendArray[DVBS].type = FrontendType::DVBS; frontendArray[DVBS].enable = true; frontendArray[DVBS].isSoftwareFe = true; diff --git a/tv/tuner/1.1/vts/functional/FilterTests.cpp b/tv/tuner/1.1/vts/functional/FilterTests.cpp index 1617642693..3bcf32ac1d 100644 --- a/tv/tuner/1.1/vts/functional/FilterTests.cpp +++ b/tv/tuner/1.1/vts/functional/FilterTests.cpp @@ -252,7 +252,11 @@ AssertionResult FilterTests::configIpFilterCid(uint32_t ipCid, uint64_t filterId return AssertionResult(status == Result::SUCCESS); } -AssertionResult FilterTests::getFilterMQDescriptor(uint64_t filterId) { +AssertionResult FilterTests::getFilterMQDescriptor(uint64_t filterId, bool getMqDesc) { + if (!getMqDesc) { + ALOGE("[vts] Filter does not need FMQ."); + return success(); + } Result status; EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first."; EXPECT_TRUE(mFilterCallbacks[filterId]) << "Test with getNewlyOpenedFilterId first."; diff --git a/tv/tuner/1.1/vts/functional/FilterTests.h b/tv/tuner/1.1/vts/functional/FilterTests.h index 6749265661..59611fa7ae 100644 --- a/tv/tuner/1.1/vts/functional/FilterTests.h +++ b/tv/tuner/1.1/vts/functional/FilterTests.h @@ -161,7 +161,7 @@ class FilterTests { AssertionResult configAvFilterStreamType(AvStreamType type, uint64_t filterId); AssertionResult configIpFilterCid(uint32_t ipCid, uint64_t filterId); AssertionResult configureMonitorEvent(uint64_t filterId, uint32_t monitorEventTypes); - AssertionResult getFilterMQDescriptor(uint64_t filterId); + AssertionResult getFilterMQDescriptor(uint64_t filterId, bool getMqDesc); AssertionResult startFilter(uint64_t filterId); AssertionResult stopFilter(uint64_t filterId); AssertionResult closeFilter(uint64_t filterId); diff --git a/tv/tuner/1.1/vts/functional/FrontendTests.cpp b/tv/tuner/1.1/vts/functional/FrontendTests.cpp index 887f8b8131..0fd5be0664 100644 --- a/tv/tuner/1.1/vts/functional/FrontendTests.cpp +++ b/tv/tuner/1.1/vts/functional/FrontendTests.cpp @@ -130,7 +130,7 @@ void FrontendCallback::scanTest(sp& frontend, FrontendConfig config, return; } - uint32_t targetFrequency = getTargetFrequency(config.settings, config.type); + uint32_t targetFrequency = getTargetFrequency(config.settings); if (type == FrontendScanType::SCAN_BLIND) { // reset the frequency in the scan configuration to test blind scan. The settings param of // passed in means the real input config on the transponder connected to the DUT. @@ -184,64 +184,59 @@ wait: mScanMsgProcessed = true; } -uint32_t FrontendCallback::getTargetFrequency(FrontendSettings settings, FrontendType type) { - switch (type) { - case FrontendType::ANALOG: +uint32_t FrontendCallback::getTargetFrequency(FrontendSettings settings) { + switch (settings.getDiscriminator()) { + case FrontendSettings::hidl_discriminator::analog: return settings.analog().frequency; - case FrontendType::ATSC: + case FrontendSettings::hidl_discriminator::atsc: return settings.atsc().frequency; - case FrontendType::ATSC3: + case FrontendSettings::hidl_discriminator::atsc3: return settings.atsc3().frequency; - case FrontendType::DVBC: + case FrontendSettings::hidl_discriminator::dvbc: return settings.dvbc().frequency; - case FrontendType::DVBS: + case FrontendSettings::hidl_discriminator::dvbs: return settings.dvbs().frequency; - case FrontendType::DVBT: + case FrontendSettings::hidl_discriminator::dvbt: return settings.dvbt().frequency; - case FrontendType::ISDBS: + case FrontendSettings::hidl_discriminator::isdbs: return settings.isdbs().frequency; - case FrontendType::ISDBS3: + case FrontendSettings::hidl_discriminator::isdbs3: return settings.isdbs3().frequency; - case FrontendType::ISDBT: + case FrontendSettings::hidl_discriminator::isdbt: return settings.isdbt().frequency; - default: - return 0; } } void FrontendCallback::resetBlindScanStartingFrequency(FrontendConfig& config, uint32_t resetingFreq) { - switch (config.type) { - case FrontendType::ANALOG: + switch (config.settings.getDiscriminator()) { + case FrontendSettings::hidl_discriminator::analog: config.settings.analog().frequency = resetingFreq; break; - case FrontendType::ATSC: + case FrontendSettings::hidl_discriminator::atsc: config.settings.atsc().frequency = resetingFreq; break; - case FrontendType::ATSC3: + case FrontendSettings::hidl_discriminator::atsc3: config.settings.atsc3().frequency = resetingFreq; break; - case FrontendType::DVBC: + case FrontendSettings::hidl_discriminator::dvbc: config.settings.dvbc().frequency = resetingFreq; break; - case FrontendType::DVBS: + case FrontendSettings::hidl_discriminator::dvbs: config.settings.dvbs().frequency = resetingFreq; break; - case FrontendType::DVBT: + case FrontendSettings::hidl_discriminator::dvbt: config.settings.dvbt().frequency = resetingFreq; break; - case FrontendType::ISDBS: + case FrontendSettings::hidl_discriminator::isdbs: config.settings.isdbs().frequency = resetingFreq; break; - case FrontendType::ISDBS3: + case FrontendSettings::hidl_discriminator::isdbs3: config.settings.isdbs3().frequency = resetingFreq; break; - case FrontendType::ISDBT: + case FrontendSettings::hidl_discriminator::isdbt: config.settings.isdbt().frequency = resetingFreq; break; - default: - // do nothing - return; } } @@ -490,6 +485,9 @@ void FrontendTests::getFrontendIdByType(FrontendType feType, uint32_t& feId) { } void FrontendTests::tuneTest(FrontendConfig frontendConf) { + if (!frontendConf.enable) { + return; + } uint32_t feId; getFrontendIdByType(frontendConf.type, feId); ASSERT_TRUE(feId != INVALID_ID); @@ -506,6 +504,9 @@ void FrontendTests::tuneTest(FrontendConfig frontendConf) { } void FrontendTests::scanTest(FrontendConfig frontendConf, FrontendScanType scanType) { + if (!frontendConf.enable) { + return; + } uint32_t feId; getFrontendIdByType(frontendConf.type, feId); ASSERT_TRUE(feId != INVALID_ID); diff --git a/tv/tuner/1.1/vts/functional/FrontendTests.h b/tv/tuner/1.1/vts/functional/FrontendTests.h index 43c1579cb7..01d2007f3d 100644 --- a/tv/tuner/1.1/vts/functional/FrontendTests.h +++ b/tv/tuner/1.1/vts/functional/FrontendTests.h @@ -82,7 +82,7 @@ class FrontendCallback : public IFrontendCallback { void scanTest(sp& frontend, FrontendConfig config, FrontendScanType type); // Helper methods - uint32_t getTargetFrequency(FrontendSettings settings, FrontendType type); + uint32_t getTargetFrequency(FrontendSettings settings); void resetBlindScanStartingFrequency(FrontendConfig& config, uint32_t resetingFreq); private: diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp index 2e6c87fb5a..97fb90db69 100644 --- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp @@ -28,6 +28,10 @@ AssertionResult TunerRecordHidlTest::filterDataOutputTest() { void TunerFilterHidlTest::configSingleFilterInDemuxTest(FilterConfig filterConf, FrontendConfig frontendConf) { + if (!frontendConf.enable) { + return; + } + uint32_t feId; uint32_t demuxId; sp demux; @@ -49,7 +53,7 @@ void TunerFilterHidlTest::configSingleFilterInDemuxTest(FilterConfig filterConf, if (filterConf.monitorEventTypes > 0) { ASSERT_TRUE(mFilterTests.configureMonitorEvent(filterId, filterConf.monitorEventTypes)); } - ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId)); + ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterConf.getMqDesc)); ASSERT_TRUE(mFilterTests.startFilter(filterId)); ASSERT_TRUE(mFilterTests.stopFilter(filterId)); ASSERT_TRUE(mFilterTests.closeFilter(filterId)); @@ -60,6 +64,10 @@ void TunerFilterHidlTest::configSingleFilterInDemuxTest(FilterConfig filterConf, void TunerFilterHidlTest::reconfigSingleFilterInDemuxTest(FilterConfig filterConf, FilterConfig filterReconf, FrontendConfig frontendConf) { + if (!frontendConf.enable) { + return; + } + uint32_t feId; uint32_t demuxId; sp demux; @@ -76,7 +84,7 @@ void TunerFilterHidlTest::reconfigSingleFilterInDemuxTest(FilterConfig filterCon ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize)); ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(filterId)); ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId)); - ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId)); + ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterConf.getMqDesc)); ASSERT_TRUE(mFilterTests.startFilter(filterId)); ASSERT_TRUE(mFilterTests.stopFilter(filterId)); ASSERT_TRUE(mFilterTests.configFilter(filterReconf.settings, filterId)); @@ -92,6 +100,10 @@ void TunerFilterHidlTest::reconfigSingleFilterInDemuxTest(FilterConfig filterCon void TunerBroadcastHidlTest::mediaFilterUsingSharedMemoryTest(FilterConfig filterConf, FrontendConfig frontendConf) { + if (!frontendConf.enable) { + return; + } + uint32_t feId; uint32_t demuxId; sp demux; @@ -110,7 +122,7 @@ void TunerBroadcastHidlTest::mediaFilterUsingSharedMemoryTest(FilterConfig filte ASSERT_TRUE(mFilterTests.getSharedAvMemoryHandle(filterId)); ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId)); ASSERT_TRUE(mFilterTests.configAvFilterStreamType(filterConf.streamType, filterId)); - ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId)); + ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterConf.getMqDesc)); ASSERT_TRUE(mFilterTests.startFilter(filterId)); // tune test ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/)); @@ -125,6 +137,10 @@ void TunerBroadcastHidlTest::mediaFilterUsingSharedMemoryTest(FilterConfig filte void TunerRecordHidlTest::recordSingleFilterTest(FilterConfig filterConf, FrontendConfig frontendConf, DvrConfig dvrConf) { + if (!frontendConf.enable) { + return; + } + uint32_t feId; uint32_t demuxId; sp demux; @@ -146,7 +162,7 @@ void TunerRecordHidlTest::recordSingleFilterTest(FilterConfig filterConf, ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize)); ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(filterId)); ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId)); - ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId)); + ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterConf.getMqDesc)); filter = mFilterTests.getFilterById(filterId); ASSERT_TRUE(filter != nullptr); mDvrTests.startRecordOutputThread(dvrConf.settings.record()); @@ -170,40 +186,41 @@ void TunerRecordHidlTest::recordSingleFilterTest(FilterConfig filterConf, TEST_P(TunerFilterHidlTest, StartFilterInDemux) { description("Open and start a filter in Demux."); // TODO use parameterized tests - configSingleFilterInDemuxTest(filterArray[TS_VIDEO0], frontendArray[DVBT]); + configSingleFilterInDemuxTest(filterArray[TS_VIDEO0], frontendArray[defaultFrontend]); } TEST_P(TunerFilterHidlTest, ConfigIpFilterInDemuxWithCid) { description("Open and configure an ip filter in Demux."); // TODO use parameterized tests - configSingleFilterInDemuxTest(filterArray[IP_IP0], frontendArray[DVBT]); + configSingleFilterInDemuxTest(filterArray[IP_IP0], frontendArray[defaultFrontend]); } TEST_P(TunerFilterHidlTest, ReconfigFilterToReceiveStartId) { description("Recofigure and restart a filter to test start id."); // TODO use parameterized tests reconfigSingleFilterInDemuxTest(filterArray[TS_VIDEO0], filterArray[TS_VIDEO1], - frontendArray[DVBT]); + frontendArray[defaultFrontend]); } TEST_P(TunerRecordHidlTest, RecordDataFlowWithTsRecordFilterTest) { description("Feed ts data from frontend to recording and test with ts record filter"); - recordSingleFilterTest(filterArray[TS_RECORD0], frontendArray[DVBT], dvrArray[DVR_RECORD0]); + recordSingleFilterTest(filterArray[TS_RECORD0], frontendArray[defaultFrontend], + dvrArray[DVR_RECORD0]); } TEST_P(TunerFrontendHidlTest, TuneFrontendWithFrontendSettingsExt1_1) { description("Tune one Frontend with v1_1 extended setting and check Lock event"); - mFrontendTests.tuneTest(frontendArray[DVBT]); + mFrontendTests.tuneTest(frontendArray[defaultFrontend]); } TEST_P(TunerFrontendHidlTest, BlindScanFrontendWithEndFrequency) { description("Run an blind frontend scan with v1_1 extended setting and check lock scanMessage"); - mFrontendTests.scanTest(frontendScanArray[SCAN_DVBT], FrontendScanType::SCAN_BLIND); + mFrontendTests.scanTest(frontendScanArray[defaultScanFrontend], FrontendScanType::SCAN_BLIND); } TEST_P(TunerBroadcastHidlTest, MediaFilterWithSharedMemoryHandle) { description("Test the Media Filter with shared memory handle"); - mediaFilterUsingSharedMemoryTest(filterArray[TS_VIDEO0], frontendArray[DVBT]); + mediaFilterUsingSharedMemoryTest(filterArray[TS_VIDEO0], frontendArray[defaultFrontend]); } TEST_P(TunerFrontendHidlTest, GetFrontendDtmbCaps) { diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h index ecdf683b24..ad5784972e 100644 --- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h @@ -55,6 +55,7 @@ using android::hardware::tv::tuner::V1_1::VideoStreamType; using namespace std; +const uint32_t FMQ_SIZE_512K = 0x80000; const uint32_t FMQ_SIZE_1M = 0x100000; const uint32_t FMQ_SIZE_4M = 0x400000; const uint32_t FMQ_SIZE_16M = 0x1000000; @@ -94,6 +95,7 @@ struct FilterConfig { uint32_t bufferSize; DemuxFilterType type; DemuxFilterSettings settings; + bool getMqDesc; AvStreamType streamType; uint32_t ipCid; uint32_t monitorEventTypes; @@ -102,6 +104,7 @@ struct FilterConfig { }; struct FrontendConfig { + bool enable; bool isSoftwareFe; bool canConnectToCiCam; uint32_t ciCamId; @@ -124,6 +127,7 @@ static FrontendConfig frontendScanArray[SCAN_MAX]; static FilterConfig filterArray[FILTER_MAX]; static DvrConfig dvrArray[DVR_MAX]; static int defaultFrontend = DVBT; +static int defaultScanFrontend = SCAN_DVBT; /** Configuration array for the frontend tune test */ inline void initFrontendConfig() { @@ -159,8 +163,10 @@ inline void initFrontendConfig() { .transmissionMode = android::hardware::tv::tuner::V1_1::FrontendDvbtTransmissionMode::MODE_8K_E, }); + frontendArray[DVBT].enable = true; frontendArray[DVBS].type = FrontendType::DVBS; frontendArray[DVBS].isSoftwareFe = true; + frontendArray[DVBS].enable = true; }; /** Configuration array for the frontend scan test */ @@ -223,6 +229,7 @@ inline void initFilterConfig() { .isRaw = false, .streamId = 0xbd, }); + filterArray[TS_PES0].getMqDesc = true; // TS PCR filter setting filterArray[TS_PCR0].type.mainType = DemuxFilterMainType::TS; filterArray[TS_PCR0].type.subType.tsFilterType(DemuxTsFilterType::PCR); @@ -243,6 +250,7 @@ inline void initFilterConfig() { filterArray[TS_SECTION0].settings.ts().filterSettings.section({ .isRaw = false, }); + filterArray[TS_SECTION0].getMqDesc = true; // TS RECORD filter setting filterArray[TS_RECORD0].type.mainType = DemuxFilterMainType::TS; filterArray[TS_RECORD0].type.subType.tsFilterType(DemuxTsFilterType::RECORD); -- GitLab From 40b9fe8213b1eefa8560d4972289ff0313833ad7 Mon Sep 17 00:00:00 2001 From: Kai Date: Tue, 23 Feb 2021 15:56:53 -0800 Subject: [PATCH 525/790] Convert VTS for VHAL from python to gtest VTS10 won't be supported after S. Rewrite the VTS for VHAL in gtest test suit. Also, the test is moved from host-side to target side. Bug: 153872561 Test: atest -c VtsHalAutomotiveVehicleV2_0TargetTest Change-Id: I89d3983daba2ea5784ba9d95833c3f2dda3b1fac --- .../vehicle/2.0/vts/functional/Android.bp | 21 ++ .../VtsHalAutomotiveVehicleV2_0TargetTest.cpp | 247 ++++++++++++++++++ 2 files changed, 268 insertions(+) create mode 100644 automotive/vehicle/2.0/vts/functional/Android.bp create mode 100644 automotive/vehicle/2.0/vts/functional/VtsHalAutomotiveVehicleV2_0TargetTest.cpp diff --git a/automotive/vehicle/2.0/vts/functional/Android.bp b/automotive/vehicle/2.0/vts/functional/Android.bp new file mode 100644 index 0000000000..9f1dd6fb86 --- /dev/null +++ b/automotive/vehicle/2.0/vts/functional/Android.bp @@ -0,0 +1,21 @@ +cc_test { + name: "VtsHalAutomotiveVehicleV2_0TargetTest", + defaults: [ + "VtsHalTargetTestDefaults", + ], + srcs: [ + "VtsHalAutomotiveVehicleV2_0TargetTest.cpp", + ], + shared_libs: [ + "libbase", + "libhidlbase", + "liblog", + ], + static_libs: [ + "android.hardware.automotive.vehicle@2.0", + ], + test_suites: [ + "vts", + "general-tests", + ], +} diff --git a/automotive/vehicle/2.0/vts/functional/VtsHalAutomotiveVehicleV2_0TargetTest.cpp b/automotive/vehicle/2.0/vts/functional/VtsHalAutomotiveVehicleV2_0TargetTest.cpp new file mode 100644 index 0000000000..7f1d4d10b6 --- /dev/null +++ b/automotive/vehicle/2.0/vts/functional/VtsHalAutomotiveVehicleV2_0TargetTest.cpp @@ -0,0 +1,247 @@ +/* + * 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 "VtsHalAutomotiveVehicle" + +#include +#include + +#include +#include +#include + +using namespace android::hardware::automotive::vehicle::V2_0; +using ::android::sp; +using ::android::hardware::hidl_vec; +using ::android::hardware::Return; + +constexpr auto kTimeout = std::chrono::milliseconds(500); +constexpr auto kInvalidProp = 0x31600207; + +class VtsVehicleCallback : public IVehicleCallback { + private: + using MutexGuard = std::lock_guard; + using HidlVecOfValues = hidl_vec; + std::mutex mLock; + std::condition_variable mEventCond; + std::vector mReceivedEvents; + + public: + Return onPropertyEvent(const hidl_vec& values) override { + { + MutexGuard guard(mLock); + mReceivedEvents.push_back(values); + } + mEventCond.notify_one(); + return Return(); + } + + Return onPropertySet(const VehiclePropValue& /* value */) override { + return Return(); + } + Return onPropertySetError(StatusCode /* errorCode */, int32_t /* propId */, + int32_t /* areaId */) override { + return Return(); + } + + bool waitForExpectedEvents(size_t expectedEvents) { + std::unique_lock g(mLock); + + if (expectedEvents == 0 && mReceivedEvents.size() == 0) { + return mEventCond.wait_for(g, kTimeout) == std::cv_status::timeout; + } + + while (expectedEvents != mReceivedEvents.size()) { + if (mEventCond.wait_for(g, kTimeout) == std::cv_status::timeout) { + return false; + } + } + return true; + } + + void reset() { mReceivedEvents.clear(); } +}; + +class VehicleHalHidlTest : public testing::TestWithParam { + public: + virtual void SetUp() override { + mVehicle = IVehicle::getService(GetParam()); + ASSERT_NE(mVehicle.get(), nullptr); + } + virtual void TearDown() override {} + + sp mVehicle; + + bool isBooleanGlobalProp(int32_t property) { + return (property & (int)VehiclePropertyType::MASK) == (int)VehiclePropertyType::BOOLEAN && + (property & (int)VehicleArea::MASK) == (int)VehicleArea::GLOBAL; + } + + void invokeGet(int32_t property, int32_t areaId) { + VehiclePropValue requestedValue{}; + requestedValue.prop = property; + requestedValue.areaId = areaId; + + invokeGet(requestedValue); + } + + void invokeGet(const VehiclePropValue& requestedPropValue) { + mActualValue = VehiclePropValue{}; // reset previous values + + StatusCode refStatus; + VehiclePropValue refValue; + bool isCalled = false; + mVehicle->get(requestedPropValue, + [&refStatus, &refValue, &isCalled](StatusCode status, + const VehiclePropValue& value) { + refStatus = status; + refValue = value; + isCalled = true; + }); + ASSERT_TRUE(isCalled) << "callback wasn't called for property: " << requestedPropValue.prop; + + mActualValue = refValue; + mActualStatusCode = refStatus; + } + + VehiclePropValue mActualValue; + StatusCode mActualStatusCode; +}; + +// Test getAllPropConfig() returns at least 4 property configs. +TEST_P(VehicleHalHidlTest, getAllPropConfigs) { + ALOGD("VehicleHalHidlTest::getAllPropConfigs"); + bool isCalled = false; + hidl_vec propConfigs; + mVehicle->getAllPropConfigs([&isCalled, &propConfigs](const hidl_vec& cfgs) { + propConfigs = cfgs; + isCalled = true; + }); + ASSERT_TRUE(isCalled); + ASSERT_GE(propConfigs.size(), 4); +} + +// Test getPropConfig() can query all properties listed in CDD. +TEST_P(VehicleHalHidlTest, getPropConfigs) { + ALOGD("VehicleHalHidlTest::getPropConfigs"); + // Check the properties listed in CDD + hidl_vec properties = { + (int)VehicleProperty::GEAR_SELECTION, (int)VehicleProperty::NIGHT_MODE, + (int)VehicleProperty::PARKING_BRAKE_ON, (int)VehicleProperty::PERF_VEHICLE_SPEED}; + bool isCalled = false; + mVehicle->getPropConfigs( + properties, [&isCalled](StatusCode status, const hidl_vec& cfgs) { + ASSERT_EQ(StatusCode::OK, status); + ASSERT_EQ(4u, cfgs.size()); + isCalled = true; + }); + ASSERT_TRUE(isCalled); +} + +// Test getPropConfig() with an invalid propertyId returns an error code. +TEST_P(VehicleHalHidlTest, getPropConfigsWithInvalidProp) { + ALOGD("VehicleHalHidlTest::getPropConfigsWithInvalidProp"); + hidl_vec properties = {kInvalidProp}; + bool isCalled = false; + mVehicle->getPropConfigs( + properties, [&isCalled](StatusCode status, const hidl_vec& cfgs) { + ASSERT_NE(StatusCode::OK, status); + ASSERT_EQ(0, cfgs.size()); + isCalled = true; + }); + ASSERT_TRUE(isCalled); +} + +// Test get() return current value for properties. +TEST_P(VehicleHalHidlTest, get) { + ALOGD("VehicleHalHidlTest::get"); + invokeGet((int)VehicleProperty::PERF_VEHICLE_SPEED, 0); + ASSERT_EQ(StatusCode::OK, mActualStatusCode); +} + +// Test get() with an invalid propertyId return an error codes. +TEST_P(VehicleHalHidlTest, getInvalidProp) { + ALOGD("VehicleHalHidlTest::getInvalidProp"); + + invokeGet(kInvalidProp, 0); + ASSERT_NE(StatusCode::OK, mActualStatusCode); +} + +// Test set() on read_write properties. +TEST_P(VehicleHalHidlTest, setProp) { + ALOGD("VehicleHalHidlTest::setProp"); + hidl_vec propConfigs; + mVehicle->getAllPropConfigs( + [&propConfigs](const hidl_vec& cfgs) { propConfigs = cfgs; }); + for (const VehiclePropConfig& cfg : propConfigs) { + // test on boolean and writable property + if (cfg.access == VehiclePropertyAccess::READ_WRITE && isBooleanGlobalProp(cfg.prop)) { + invokeGet(cfg.prop, 0); + int setValue = mActualValue.value.int32Values[0] == 1 ? 0 : 1; + VehiclePropValue propToSet = mActualValue; + propToSet.value.int32Values[0] = setValue; + ASSERT_EQ(StatusCode::OK, mVehicle->set(propToSet)); + // check set success + invokeGet(cfg.prop, 0); + ASSERT_EQ(StatusCode::OK, mActualStatusCode); + ASSERT_EQ(setValue, mActualValue.value.int32Values[0]); + } + } +} + +// Test set() on an read_only property. +TEST_P(VehicleHalHidlTest, setNotWritableProp) { + ALOGD("VehicleHalHidlTest::setNotWritableProp"); + invokeGet(static_cast(VehicleProperty::PERF_VEHICLE_SPEED), 0); + ASSERT_EQ(StatusCode::OK, mActualStatusCode); + VehiclePropValue vehicleSpeed = mActualValue; + + ASSERT_EQ(StatusCode::ACCESS_DENIED, mVehicle->set(vehicleSpeed)); +} + +// Test subscribe() and unsubscribe(). +TEST_P(VehicleHalHidlTest, subscribeAndUnsubscribe) { + ALOGD("VehicleHalHidlTest::subscribeAndUnsubscribe"); + const auto prop = static_cast(VehicleProperty::PERF_VEHICLE_SPEED); + sp cb = new VtsVehicleCallback(); + + hidl_vec options = { + SubscribeOptions{.propId = prop, 100.0, .flags = SubscribeFlags::EVENTS_FROM_CAR}}; + + ASSERT_EQ(StatusCode::OK, mVehicle->subscribe(cb, options)); + ASSERT_TRUE(cb->waitForExpectedEvents(10)); + + ASSERT_EQ(StatusCode::OK, mVehicle->unsubscribe(cb, prop)); + cb->reset(); + ASSERT_FALSE(cb->waitForExpectedEvents(10)); +} + +// Test subscribe() with an invalid property. +TEST_P(VehicleHalHidlTest, subscribeInvalidProp) { + ALOGD("VehicleHalHidlTest::subscribeInvalidProp"); + + sp cb = new VtsVehicleCallback(); + + hidl_vec options = {SubscribeOptions{ + .propId = kInvalidProp, 10.0, .flags = SubscribeFlags::EVENTS_FROM_CAR}}; + + ASSERT_NE(StatusCode::OK, mVehicle->subscribe(cb, options)); +} + +INSTANTIATE_TEST_SUITE_P( + PerInstance, VehicleHalHidlTest, + testing::ValuesIn(android::hardware::getAllHalInstanceNames(IVehicle::descriptor)), + android::hardware::PrintInstanceNameToString); -- GitLab From 944b68180b008456ed2eb4d4d329e33b19bd5166 Mon Sep 17 00:00:00 2001 From: Marin Shalamanov Date: Fri, 12 Mar 2021 19:19:55 +0100 Subject: [PATCH 526/790] ComposerClient 2.4: Clean cache on hotplug On subsequent hotplug connected event for a display SurfaceFlinger destroys the previous framebuffers and recreates them. When the new buffers are created ComposerClient still holds a handle to the old buffers and they are not destroyed. This way the new framebuffers may get allocated on non continuous memory causing garbled screens for the user. This is already implemented for ComposerClient 2.1-2.3. In this CL only the behavior for ComposerClient 2.4 is changed. Test: manually flash a device Bug: 178785393 Change-Id: I6aa1243d61676c0a3d42cb7aecf19e6f8802cb1a --- .../include/composer-hal/2.1/ComposerClient.h | 103 +++++++++--------- .../include/composer-hal/2.4/ComposerClient.h | 17 ++- 2 files changed, 66 insertions(+), 54 deletions(-) diff --git a/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerClient.h b/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerClient.h index 3d74af4a41..46f5d6e1e0 100644 --- a/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerClient.h +++ b/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerClient.h @@ -98,7 +98,7 @@ class ComposerClientImpl : public Interface { // display change and thus the framework may want to reallocate buffers. We // need to free all cached handles, since they are holding a strong reference // to the underlying buffers. - cleanDisplayResources(display); + cleanDisplayResources(display, mResources, mHal); mResources->removeDisplay(display); } mResources->addPhysicalDisplay(display); @@ -125,56 +125,6 @@ class ComposerClientImpl : public Interface { Hal* const mHal; const sp mCallback; ComposerResources* const mResources; - - void cleanDisplayResources(Display display) { - size_t cacheSize; - Error err = mResources->getDisplayClientTargetCacheSize(display, &cacheSize); - if (err == Error::NONE) { - for (int slot = 0; slot < cacheSize; slot++) { - ComposerResources::ReplacedHandle replacedBuffer(/*isBuffer*/ true); - // Replace the buffer slots with NULLs. Keep the old handle until it is - // replaced in ComposerHal, otherwise we risk leaving a dangling pointer. - const native_handle_t* clientTarget = nullptr; - err = mResources->getDisplayClientTarget(display, slot, /*useCache*/ true, - /*rawHandle*/ nullptr, &clientTarget, - &replacedBuffer); - if (err != Error::NONE) { - continue; - } - const std::vector damage; - err = mHal->setClientTarget(display, clientTarget, /*fence*/ -1, 0, damage); - ALOGE_IF(err != Error::NONE, - "Can't clean slot %d of the client target buffer" - "cache for display %" PRIu64, - slot, display); - } - } else { - ALOGE("Can't clean client target cache for display %" PRIu64, display); - } - - err = mResources->getDisplayOutputBufferCacheSize(display, &cacheSize); - if (err == Error::NONE) { - for (int slot = 0; slot < cacheSize; slot++) { - // Replace the buffer slots with NULLs. Keep the old handle until it is - // replaced in ComposerHal, otherwise we risk leaving a dangling pointer. - ComposerResources::ReplacedHandle replacedBuffer(/*isBuffer*/ true); - const native_handle_t* outputBuffer = nullptr; - err = mResources->getDisplayOutputBuffer(display, slot, /*useCache*/ true, - /*rawHandle*/ nullptr, &outputBuffer, - &replacedBuffer); - if (err != Error::NONE) { - continue; - } - err = mHal->setOutputBuffer(display, outputBuffer, /*fence*/ -1); - ALOGE_IF(err != Error::NONE, - "Can't clean slot %d of the output buffer cache" - "for display %" PRIu64, - slot, display); - } - } else { - ALOGE("Can't clean output buffer cache for display %" PRIu64, display); - } - } }; Return registerCallback(const sp& callback) override { @@ -380,6 +330,57 @@ class ComposerClientImpl : public Interface { return std::make_unique(mHal, mResources.get()); } + static void cleanDisplayResources(Display display, ComposerResources* const resources, + Hal* const hal) { + size_t cacheSize; + Error err = resources->getDisplayClientTargetCacheSize(display, &cacheSize); + if (err == Error::NONE) { + for (int slot = 0; slot < cacheSize; slot++) { + ComposerResources::ReplacedHandle replacedBuffer(/*isBuffer*/ true); + // Replace the buffer slots with NULLs. Keep the old handle until it is + // replaced in ComposerHal, otherwise we risk leaving a dangling pointer. + const native_handle_t* clientTarget = nullptr; + err = resources->getDisplayClientTarget(display, slot, /*useCache*/ true, + /*rawHandle*/ nullptr, &clientTarget, + &replacedBuffer); + if (err != Error::NONE) { + continue; + } + const std::vector damage; + err = hal->setClientTarget(display, clientTarget, /*fence*/ -1, 0, damage); + ALOGE_IF(err != Error::NONE, + "Can't clean slot %d of the client target buffer" + "cache for display %" PRIu64, + slot, display); + } + } else { + ALOGE("Can't clean client target cache for display %" PRIu64, display); + } + + err = resources->getDisplayOutputBufferCacheSize(display, &cacheSize); + if (err == Error::NONE) { + for (int slot = 0; slot < cacheSize; slot++) { + // Replace the buffer slots with NULLs. Keep the old handle until it is + // replaced in ComposerHal, otherwise we risk leaving a dangling pointer. + ComposerResources::ReplacedHandle replacedBuffer(/*isBuffer*/ true); + const native_handle_t* outputBuffer = nullptr; + err = resources->getDisplayOutputBuffer(display, slot, /*useCache*/ true, + /*rawHandle*/ nullptr, &outputBuffer, + &replacedBuffer); + if (err != Error::NONE) { + continue; + } + err = hal->setOutputBuffer(display, outputBuffer, /*fence*/ -1); + ALOGE_IF(err != Error::NONE, + "Can't clean slot %d of the output buffer cache" + "for display %" PRIu64, + slot, display); + } + } else { + ALOGE("Can't clean output buffer cache for display %" PRIu64, display); + } + } + void destroyResources() { // We want to call hwc2_close here (and move hwc2_open to the // constructor), with the assumption that hwc2_close would diff --git a/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerClient.h b/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerClient.h index c889069143..3464342719 100644 --- a/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerClient.h +++ b/graphics/composer/2.4/utils/hal/include/composer-hal/2.4/ComposerClient.h @@ -45,12 +45,21 @@ class ComposerClientImpl : public V2_3::hal::detail::ComposerClientImpl callback, + HalEventCallback(Hal* hal, const sp callback, V2_1::hal::ComposerResources* resources) - : mCallback(callback), mResources(resources) {} + : mHal(hal), mCallback(callback), mResources(resources) {} void onHotplug(Display display, IComposerCallback::Connection connected) override { if (connected == IComposerCallback::Connection::CONNECTED) { + if (mResources->hasDisplay(display)) { + // This is a subsequent hotplug "connected" for a display. This signals a + // display change and thus the framework may want to reallocate buffers. We + // need to free all cached handles, since they are holding a strong reference + // to the underlying buffers. + V2_1::hal::detail::ComposerClientImpl::cleanDisplayResources( + display, mResources, mHal); + mResources->removeDisplay(display); + } mResources->addPhysicalDisplay(display); } else if (connected == IComposerCallback::Connection::DISCONNECTED) { mResources->removeDisplay(display); @@ -91,13 +100,15 @@ class ComposerClientImpl : public V2_3::hal::detail::ComposerClientImpl mCallback; V2_1::hal::ComposerResources* const mResources; }; Return registerCallback_2_4(const sp& callback) override { // no locking as we require this function to be called only once - mHalEventCallback_2_4 = std::make_unique(callback, mResources.get()); + mHalEventCallback_2_4 = + std::make_unique(mHal, callback, mResources.get()); mHal->registerEventCallback_2_4(mHalEventCallback_2_4.get()); return Void(); } -- GitLab From c1fd6fc3163a5f6866970f722f30082fe0228529 Mon Sep 17 00:00:00 2001 From: Robert Shih Date: Tue, 16 Mar 2021 02:37:04 -0700 Subject: [PATCH 527/790] drm@1.4: ANAPIC doc review follow-up Bug: 182507500 Test: build Change-Id: I8eb586f14f23607dac684ca9636d4aeae450c6a3 --- drm/1.4/types.hal | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drm/1.4/types.hal b/drm/1.4/types.hal index a4490a543e..8cb27cdbe9 100644 --- a/drm/1.4/types.hal +++ b/drm/1.4/types.hal @@ -32,8 +32,16 @@ enum LogPriority : uint32_t { /** * 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. */ struct LogMessage { + /** + * Epoch time in milliseconds. + */ int64_t timeMs; LogPriority priority; string message; -- GitLab From e6dcc9a38d3fbc2cbd957577657493e36783d3ed Mon Sep 17 00:00:00 2001 From: Xusong Wang Date: Mon, 15 Mar 2021 17:09:37 -0700 Subject: [PATCH 528/790] Document the default alignment and padding value. This CL documents the default value of the preferred alignment and padding for request memories. Bug: 179799921 Test: m Change-Id: I89c16c3e20939a0ad68d9e3b0061c4a16dc00d8b --- .../aidl/android/hardware/neuralnetworks/DataLocation.aidl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/neuralnetworks/aidl/android/hardware/neuralnetworks/DataLocation.aidl b/neuralnetworks/aidl/android/hardware/neuralnetworks/DataLocation.aidl index 1b2378f016..f656360ff9 100644 --- a/neuralnetworks/aidl/android/hardware/neuralnetworks/DataLocation.aidl +++ b/neuralnetworks/aidl/android/hardware/neuralnetworks/DataLocation.aidl @@ -35,6 +35,11 @@ package android.hardware.neuralnetworks; * total size of the writable region of the output data, and padding specifies the extra bytes at * the end of the memory region that may be used by the device to access memory in chunks, for * efficiency, but must not be used to hold any output data. + * + * When used in RequestArgument, clients should prefer to align and pad the sub-region to + * 64 bytes when possible; this may allow the device to access the sub-region more efficiently. + * The sub-region is aligned to 64 bytes if the value of offset is a multiple of 64. + * The sub-region is padded to 64 bytes if the sum of length and padding is a multiple of 64. */ @VintfStability parcelable DataLocation { -- GitLab From ea0d50167be453dd36bc74bb45fc66f202958a21 Mon Sep 17 00:00:00 2001 From: Kumar Anand Date: Tue, 16 Mar 2021 12:07:12 -0700 Subject: [PATCH 529/790] Wifi: Invalid bandwidth crash handling Treat WIFI_CHAN_WIDTH_INVALID(-1) and any other unknown bandwidth value as invalid. Bug: 182850702 Test: VTS - VtsHalWifiV1_5TargetTest Change-Id: Id25d50af9283b89f135a4f36e1f696f6db4e302e --- wifi/1.5/default/hidl_struct_util.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/wifi/1.5/default/hidl_struct_util.cpp b/wifi/1.5/default/hidl_struct_util.cpp index baa898e43c..125a50fcca 100644 --- a/wifi/1.5/default/hidl_struct_util.cpp +++ b/wifi/1.5/default/hidl_struct_util.cpp @@ -2557,10 +2557,9 @@ WifiChannelWidthInMhz convertLegacyWifiChannelWidthToHidl( return WifiChannelWidthInMhz::WIDTH_5; case legacy_hal::WIFI_CHAN_WIDTH_10: return WifiChannelWidthInMhz::WIDTH_10; - case legacy_hal::WIFI_CHAN_WIDTH_INVALID: + default: return WifiChannelWidthInMhz::WIDTH_INVALID; }; - CHECK(false) << "Unknown legacy type: " << type; } legacy_hal::wifi_rtt_preamble convertHidlRttPreambleToLegacy( -- GitLab From 203bdee4565e3562064dd1375bd1e859e95da832 Mon Sep 17 00:00:00 2001 From: Ady Abraham Date: Tue, 16 Mar 2021 23:59:45 +0000 Subject: [PATCH 530/790] Vts: Add missing usage to buffer The test's buffer is read by the GPU and therefore needs to be allocatted with BufferUsage::GPU_TEXTURE Fixes: 182935868 Change-Id: I7795e6a32acdf3ecf76003bd12715fcaf73a4e71 Test: VtsHalGraphicsComposerV2_2TargetTest --- graphics/composer/2.2/utils/vts/ReadbackVts.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/graphics/composer/2.2/utils/vts/ReadbackVts.cpp b/graphics/composer/2.2/utils/vts/ReadbackVts.cpp index 7bb9121cba..b179f35109 100644 --- a/graphics/composer/2.2/utils/vts/ReadbackVts.cpp +++ b/graphics/composer/2.2/utils/vts/ReadbackVts.cpp @@ -268,7 +268,7 @@ TestBufferLayer::TestBufferLayer(const std::shared_ptr& client, mLayerCount = 1; mFormat = format; mUsage = static_cast(BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN | - BufferUsage::COMPOSER_OVERLAY); + BufferUsage::COMPOSER_OVERLAY | BufferUsage::GPU_TEXTURE); mAccessRegion.top = 0; mAccessRegion.left = 0; -- GitLab From 8474d0fb291bfa9889466f2722b35e60bd41c906 Mon Sep 17 00:00:00 2001 From: Shinru Han Date: Thu, 18 Mar 2021 00:22:37 +0800 Subject: [PATCH 531/790] Add capability bit for Bluesky driving Bug: 182304682 Test: on cuttlefish Change-Id: I80e4eb9bbd052ec2e2a16a8af12b5c6a29012f36 --- .../android/hardware/gnss/BlocklistedSource.aidl | 3 ++- .../android/hardware/gnss/CorrelationVector.aidl | 3 ++- .../current/android/hardware/gnss/ElapsedRealtime.aidl | 3 ++- .../current/android/hardware/gnss/GnssClock.aidl | 3 ++- .../android/hardware/gnss/GnssConstellationType.aidl | 3 ++- .../current/android/hardware/gnss/GnssData.aidl | 3 ++- .../current/android/hardware/gnss/GnssMeasurement.aidl | 3 ++- .../android/hardware/gnss/GnssMultipathIndicator.aidl | 3 ++- .../current/android/hardware/gnss/GnssPowerStats.aidl | 3 ++- .../current/android/hardware/gnss/GnssSignalType.aidl | 3 ++- .../current/android/hardware/gnss/IGnss.aidl | 3 ++- .../current/android/hardware/gnss/IGnssCallback.aidl | 4 +++- .../android/hardware/gnss/IGnssConfiguration.aidl | 3 ++- .../hardware/gnss/IGnssMeasurementCallback.aidl | 3 ++- .../hardware/gnss/IGnssMeasurementInterface.aidl | 3 ++- .../android/hardware/gnss/IGnssPowerIndication.aidl | 3 ++- .../hardware/gnss/IGnssPowerIndicationCallback.aidl | 3 ++- .../current/android/hardware/gnss/IGnssPsds.aidl | 3 ++- .../android/hardware/gnss/IGnssPsdsCallback.aidl | 3 ++- .../current/android/hardware/gnss/PsdsType.aidl | 3 ++- .../android/hardware/gnss/SatelliteClockInfo.aidl | 3 ++- .../android/hardware/gnss/SatellitePositionEcef.aidl | 3 ++- .../current/android/hardware/gnss/SatellitePvt.aidl | 3 ++- .../android/hardware/gnss/SatelliteVelocityEcef.aidl | 3 ++- gnss/aidl/android/hardware/gnss/IGnssCallback.aidl | 10 ++++++---- 25 files changed, 55 insertions(+), 28 deletions(-) diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/BlocklistedSource.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/BlocklistedSource.aidl index 1a2feb776a..a4f00971c5 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/BlocklistedSource.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/BlocklistedSource.aidl @@ -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/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/CorrelationVector.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/CorrelationVector.aidl index 9c9a2414a6..b0848bb9c4 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/CorrelationVector.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/CorrelationVector.aidl @@ -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/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/ElapsedRealtime.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/ElapsedRealtime.aidl index fbcc8a3ac7..7d3baa41f2 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/ElapsedRealtime.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/ElapsedRealtime.aidl @@ -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/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssClock.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssClock.aidl index 15fe2e9b57..c54cc2c500 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssClock.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssClock.aidl @@ -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/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssConstellationType.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssConstellationType.aidl index f873b87d7f..c1fcfcc741 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssConstellationType.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssConstellationType.aidl @@ -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/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 9e05db7bd1..ebb5d0bdff 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 @@ -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/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMeasurement.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMeasurement.aidl index bc73bb19eb..948c540fc3 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMeasurement.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMeasurement.aidl @@ -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/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMultipathIndicator.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMultipathIndicator.aidl index b9db34382e..24f45c42fa 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMultipathIndicator.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssMultipathIndicator.aidl @@ -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/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssPowerStats.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssPowerStats.aidl index 6676e2eb7c..670244fd1f 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssPowerStats.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssPowerStats.aidl @@ -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/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssSignalType.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssSignalType.aidl index ba02f72961..c2a5b51e15 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssSignalType.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssSignalType.aidl @@ -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/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 10b05a7ff1..f93b496cdd 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 @@ -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/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl index 9ad9159d67..fb0931c59a 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl @@ -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. // /////////////////////////////////////////////////////////////////////////////// @@ -37,4 +38,5 @@ interface IGnssCallback { const int CAPABILITY_SATELLITE_BLOCKLIST = 512; const int CAPABILITY_CORRELATION_VECTOR = 4096; const int CAPABILITY_SATELLITE_PVT = 8192; + const int CAPABILITY_MEASUREMENT_CORRECTIONS_FOR_DRIVING = 16384; } diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssConfiguration.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssConfiguration.aidl index 20dd781466..54cd022f66 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssConfiguration.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssConfiguration.aidl @@ -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/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementCallback.aidl index 93894bfd6a..6e626172b9 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementCallback.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementCallback.aidl @@ -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/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementInterface.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementInterface.aidl index 07a51aeb5d..24d6f9c4cf 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementInterface.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementInterface.aidl @@ -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/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndication.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndication.aidl index 1cc7f7114a..fbf1f6ffb6 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndication.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndication.aidl @@ -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/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndicationCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndicationCallback.aidl index 01f91dc3de..bfa787e3e2 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndicationCallback.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPowerIndicationCallback.aidl @@ -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/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsds.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsds.aidl index 175879245a..526ecc8fcd 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsds.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsds.aidl @@ -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/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsdsCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsdsCallback.aidl index a1af1057ef..2205bc46dd 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsdsCallback.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssPsdsCallback.aidl @@ -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/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/PsdsType.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/PsdsType.aidl index b387121d5b..727bb6912b 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/PsdsType.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/PsdsType.aidl @@ -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/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatelliteClockInfo.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatelliteClockInfo.aidl index 4dd45b2af7..ed23e639a8 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatelliteClockInfo.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatelliteClockInfo.aidl @@ -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/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatellitePositionEcef.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatellitePositionEcef.aidl index c96b2e5344..e1a20c378e 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatellitePositionEcef.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatellitePositionEcef.aidl @@ -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/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatellitePvt.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatellitePvt.aidl index 95af1524b3..747ee90933 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatellitePvt.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatellitePvt.aidl @@ -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/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatelliteVelocityEcef.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatelliteVelocityEcef.aidl index 558aec992d..a571048c20 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatelliteVelocityEcef.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatelliteVelocityEcef.aidl @@ -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/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl b/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl index 8881ea7486..aad09ef98b 100644 --- a/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl +++ b/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl @@ -16,8 +16,8 @@ package android.hardware.gnss; -import android.hardware.gnss.IGnssPsds; import android.hardware.gnss.IGnssConfiguration; +import android.hardware.gnss.IGnssPsds; /** * This interface is required for the HAL to communicate certain information @@ -26,15 +26,17 @@ import android.hardware.gnss.IGnssConfiguration; */ @VintfStability interface IGnssCallback { - /** Capability bit mask indicating that GNSS supports blocklisting satellites */ const int CAPABILITY_SATELLITE_BLOCKLIST = 1 << 9; /** Capability bit mask indicating that GNSS supports correlation vector */ - const int CAPABILITY_CORRELATION_VECTOR = 1 << 12; + const int CAPABILITY_CORRELATION_VECTOR = 1 << 12; /** Capability bit mask indicating that GNSS supports satellite PVT */ - const int CAPABILITY_SATELLITE_PVT = 1 << 13; + const int CAPABILITY_SATELLITE_PVT = 1 << 13; + + /** Capability bit mask indicating that GNSS supports measurement corrections for driving */ + const int CAPABILITY_MEASUREMENT_CORRECTIONS_FOR_DRIVING = 1 << 14; /** * Callback to inform framework of the GNSS HAL implementation's capabilities. -- GitLab From aa2c425e66a8a81e7489699dbc8aa5c0f7ca3f4e Mon Sep 17 00:00:00 2001 From: Anthony Stange Date: Fri, 12 Mar 2021 22:08:31 +0000 Subject: [PATCH 532/790] Rework V1.2 ContextHub HAL spec In the final implementation that makes use of this HAL version, ContextHubMsg's don't have permissions information when they are sent from the framework to the HAL since the framework is the end decider for whether its clients have the right permissions. Bug: 180606685 Test: presubmits Change-Id: I385edce48ff71abc1c684919532b6c578df2a414 --- contexthub/1.2/IContexthub.hal | 12 ------------ contexthub/1.2/types.hal | 7 ++----- 2 files changed, 2 insertions(+), 17 deletions(-) diff --git a/contexthub/1.2/IContexthub.hal b/contexthub/1.2/IContexthub.hal index 4bb9361bc1..04a8cb29cc 100644 --- a/contexthub/1.2/IContexthub.hal +++ b/contexthub/1.2/IContexthub.hal @@ -50,18 +50,6 @@ interface IContexthub extends @1.1::IContexthub { */ registerCallback_1_2(uint32_t hubId, IContexthubCallback cb) generates (Result result); - /** - * Send a message to a hub - * - * @param hubId identifier for hub to send message to - * @param msg message to be sent - * - * @return result OK if successful, error code otherwise - * BAD_VALUE if parameters are not valid - * TRANSACTION_FAILED if message send failed - */ - sendMessageToHub_1_2(uint32_t hubId, ContextHubMsg msg) generates (Result result); - /** * Notification sent by the framework to indicate that the user * has changed a setting. diff --git a/contexthub/1.2/types.hal b/contexthub/1.2/types.hal index 5a11efea46..5033ce84c6 100644 --- a/contexthub/1.2/types.hal +++ b/contexthub/1.2/types.hal @@ -45,11 +45,8 @@ struct ContextHubMsg { @1.0::ContextHubMsg msg_1_0; /** - * The list of Android permissions that the sender of this message has at - * the time the message was sent. - * - * The HAL MUST drop messages to nanoapps if this list of permissions is not - * a superset of those of the receiving nanoapp(s). + * The list of Android permissions held by the sending nanoapp at the time + * the message was sent. * * The framework MUST drop messages to host apps that don't have a superset * of the permissions that the sending nanoapp is using. -- GitLab From 778fb3e71720269da5131065cc8d193ef48e9bf1 Mon Sep 17 00:00:00 2001 From: Anthony Stange Date: Wed, 17 Mar 2021 17:30:45 +0000 Subject: [PATCH 533/790] Modify default contexthub impl based on latest spec Bug: 180606685 Test: compile Change-Id: Ic9ed850cc7b96b5e2732bbcee81157e9fc81a906 --- contexthub/1.2/default/Contexthub.cpp | 6 ------ contexthub/1.2/default/Contexthub.h | 2 -- 2 files changed, 8 deletions(-) diff --git a/contexthub/1.2/default/Contexthub.cpp b/contexthub/1.2/default/Contexthub.cpp index 601eccd399..57145fc64f 100644 --- a/contexthub/1.2/default/Contexthub.cpp +++ b/contexthub/1.2/default/Contexthub.cpp @@ -80,12 +80,6 @@ Return Contexthub::registerCallback_1_2(uint32_t hubId, return Result::BAD_PARAMS; } -// We don't expose any nanoapps, therefore all nanoapp-related API calls return with BAD_PARAMS -Return Contexthub::sendMessageToHub_1_2(uint32_t /* hubId */, - const ContextHubMsg& /* msg */) { - return Result::BAD_PARAMS; -} - Return Contexthub::onSettingChanged(SettingV1_1 /*setting*/, SettingValue /*newValue*/) { return Void(); } diff --git a/contexthub/1.2/default/Contexthub.h b/contexthub/1.2/default/Contexthub.h index 32b862dc3f..305544d5f4 100644 --- a/contexthub/1.2/default/Contexthub.h +++ b/contexthub/1.2/default/Contexthub.h @@ -55,8 +55,6 @@ class Contexthub Return registerCallback_1_2(uint32_t hubId, const sp& cb) override; - Return sendMessageToHub_1_2(uint32_t hubId, const ContextHubMsg& msg) override; - private: sp mCallback; }; -- GitLab From a03042d7a4eb786baa42d782441aa397496b38a9 Mon Sep 17 00:00:00 2001 From: Anthony Stange Date: Wed, 17 Mar 2021 17:31:15 +0000 Subject: [PATCH 534/790] Update contexthub VTS based on latest spec Bug: 180606685 Test: compile Change-Id: I2e9e02aed4dae2a35b0b780e1f3379c08e80a6c4 --- .../VtsHalContexthubV1_2TargetTest.cpp | 31 ------------------- 1 file changed, 31 deletions(-) diff --git a/contexthub/1.2/vts/functional/VtsHalContexthubV1_2TargetTest.cpp b/contexthub/1.2/vts/functional/VtsHalContexthubV1_2TargetTest.cpp index c50d43c137..3510c2379f 100644 --- a/contexthub/1.2/vts/functional/VtsHalContexthubV1_2TargetTest.cpp +++ b/contexthub/1.2/vts/functional/VtsHalContexthubV1_2TargetTest.cpp @@ -195,39 +195,8 @@ class TxnResultCallback : public ContexthubCallbackV1_2 { std::promise promise; }; -// Parameterized fixture that sets the callback to TxnResultCallback -class ContexthubTxnTest : public ContexthubHidlTest { - public: - virtual void SetUp() override { - ContexthubHidlTest::SetUp(); - ASSERT_OK(registerCallback_1_2(cb)); - } - - sp cb = new TxnResultCallback(); -}; - -TEST_P(ContexthubTxnTest, TestSendMessageToNonExistentNanoApp) { - ContextHubMsg msg; - msg.msg_1_0.appName = kNonExistentAppId; - msg.msg_1_0.msgType = 1; - msg.msg_1_0.msg.resize(4); - std::fill(msg.msg_1_0.msg.begin(), msg.msg_1_0.msg.end(), 0); - - ALOGD("Sending message to non-existent nanoapp"); - Result result = hubApi->sendMessageToHub_1_2(getHubId(), msg); - if (result != Result::OK && result != Result::BAD_PARAMS && - result != Result::TRANSACTION_FAILED) { - FAIL() << "Got result " << asBaseType(result) << ", expected OK, BAD_PARAMS" - << ", or TRANSACTION_FAILED"; - } -} - GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ContexthubHidlTest); INSTANTIATE_TEST_SUITE_P(HubIdSpecificTests, ContexthubHidlTest, testing::ValuesIn(kTestParameters), android::hardware::PrintInstanceTupleNameToString<>); -GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ContexthubTxnTest); -INSTANTIATE_TEST_SUITE_P(HubIdSpecificTests, ContexthubTxnTest, testing::ValuesIn(kTestParameters), - android::hardware::PrintInstanceTupleNameToString<>); - } // anonymous namespace -- GitLab From de053d008c0c7a67cc952e680c8088e324ceff2a Mon Sep 17 00:00:00 2001 From: Michal Olech Date: Thu, 18 Mar 2021 13:32:17 +0100 Subject: [PATCH 535/790] CEC: Add VTS test to get physical address (HAL 1.1) Test: atest VtsHalTvCecV1_1TargetTest Bug: 172316717 Change-Id: If8e64e48cc968c0b88e9d9615b80718db56adc29 --- .../vts/functional/VtsHalTvCecV1_1TargetTest.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tv/cec/1.1/vts/functional/VtsHalTvCecV1_1TargetTest.cpp b/tv/cec/1.1/vts/functional/VtsHalTvCecV1_1TargetTest.cpp index 1eb4643565..67a79b8cf4 100644 --- a/tv/cec/1.1/vts/functional/VtsHalTvCecV1_1TargetTest.cpp +++ b/tv/cec/1.1/vts/functional/VtsHalTvCecV1_1TargetTest.cpp @@ -46,6 +46,7 @@ using ::android::hardware::tv::cec::V1_1::IHdmiCecCallback; #define CEC_VERSION 0x05 #define INCORRECT_VENDOR_ID 0x00 +#define TV_PHYSICAL_ADDRESS 0x0000 // The main test class for TV CEC HAL. class HdmiCecTest : public ::testing::TestWithParam { @@ -126,6 +127,19 @@ TEST_P(HdmiCecTest, ClearAddLogicalAddress) { EXPECT_EQ(ret, Result::SUCCESS); } +TEST_P(HdmiCecTest, PhysicalAddress) { + Result result; + uint16_t addr; + Return ret = hdmiCec->getPhysicalAddress([&result, &addr](Result res, uint16_t paddr) { + result = res; + addr = paddr; + }); + EXPECT_EQ(result, Result::SUCCESS); + if (!hasDeviceType(CecDeviceType::TV)) { + EXPECT_NE(addr, TV_PHYSICAL_ADDRESS); + } +} + TEST_P(HdmiCecTest, SendMessage) { CecMessage message; message.initiator = CecLogicalAddress::PLAYBACK_1; -- GitLab From 9bccd5f634267b27471465387fb90df58fd1b81e Mon Sep 17 00:00:00 2001 From: Michal Olech Date: Thu, 18 Mar 2021 13:29:42 +0100 Subject: [PATCH 536/790] CEC: Add VTS test to check is connected (HAL 1.1) Test: atest VtsHalTvCecV1_1TargetTest Bug: 172316717 Change-Id: Ia4f78f53bef7ce151b0f711b7e7d8595c068c9ef --- .../1.1/vts/functional/VtsHalTvCecV1_1TargetTest.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/tv/cec/1.1/vts/functional/VtsHalTvCecV1_1TargetTest.cpp b/tv/cec/1.1/vts/functional/VtsHalTvCecV1_1TargetTest.cpp index 1eb4643565..103f2dca6c 100644 --- a/tv/cec/1.1/vts/functional/VtsHalTvCecV1_1TargetTest.cpp +++ b/tv/cec/1.1/vts/functional/VtsHalTvCecV1_1TargetTest.cpp @@ -196,4 +196,14 @@ TEST_P(HdmiCecTest, EnableAudioReturnChannel) { ASSERT_TRUE(ret.isOk()); } } -} \ No newline at end of file +} + +TEST_P(HdmiCecTest, IsConnected) { + hidl_vec ports; + Return ret = + hdmiCec->getPortInfo([&ports](hidl_vec list) { ports = list; }); + for (size_t i = 0; i < ports.size(); ++i) { + Return ret = hdmiCec->isConnected(ports[i].portId); + EXPECT_TRUE(ret.isOk()); + } +} -- GitLab From 486185569ba0739a479f8e0a3f8a772370e652be Mon Sep 17 00:00:00 2001 From: Haining Chen Date: Sun, 14 Mar 2021 17:30:09 -0700 Subject: [PATCH 537/790] Rename HardwareInfo to ComponentInfo for the flexibility and extensibility to support new biometric sensor properties Bug: 156024031 Test: m -j android.hardware.biometrics.common-update-api Test: m -j android.hardware.biometrics.face-service.example Test: m -j android.hardware.biometrics.fingerprint-service.example Change-Id: Iede6fe7eefbdde2320b495e467430b3e6269b5b6 --- .../biometrics/common/CommonProps.aidl | 3 +-- .../{HardwareInfo.aidl => ComponentInfo.aidl} | 6 +++-- .../biometrics/common/CommonProps.aidl | 15 +++-------- .../{HardwareInfo.aidl => ComponentInfo.aidl} | 19 ++++++++++++-- biometrics/face/aidl/default/Face.cpp | 26 +++++++++++++------ .../fingerprint/aidl/default/Fingerprint.cpp | 13 +++++++--- 6 files changed, 52 insertions(+), 30 deletions(-) rename biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/{HardwareInfo.aidl => ComponentInfo.aidl} (94%) rename biometrics/common/aidl/android/hardware/biometrics/common/{HardwareInfo.aidl => ComponentInfo.aidl} (61%) diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/CommonProps.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/CommonProps.aidl index 4b4e7df146..d4433c5bde 100644 --- a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/CommonProps.aidl +++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/CommonProps.aidl @@ -37,6 +37,5 @@ parcelable CommonProps { int sensorId; android.hardware.biometrics.common.SensorStrength sensorStrength = android.hardware.biometrics.common.SensorStrength.CONVENIENCE; int maxEnrollmentsPerUser; - android.hardware.biometrics.common.HardwareInfo[] hardwareInfo; - String softwareInfo; + android.hardware.biometrics.common.ComponentInfo[] componentInfo; } diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/HardwareInfo.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/ComponentInfo.aidl similarity index 94% rename from biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/HardwareInfo.aidl rename to biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/ComponentInfo.aidl index c5288fdae5..ad11ddaa6d 100644 --- a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/HardwareInfo.aidl +++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/ComponentInfo.aidl @@ -33,8 +33,10 @@ package android.hardware.biometrics.common; @VintfStability -parcelable HardwareInfo { - String deviceName; +parcelable ComponentInfo { + String componentId; String hardwareVersion; + String firmwareVersion; String serialNumber; + String softwareVersion; } diff --git a/biometrics/common/aidl/android/hardware/biometrics/common/CommonProps.aidl b/biometrics/common/aidl/android/hardware/biometrics/common/CommonProps.aidl index 7c3d511360..2f5af5dbc9 100644 --- a/biometrics/common/aidl/android/hardware/biometrics/common/CommonProps.aidl +++ b/biometrics/common/aidl/android/hardware/biometrics/common/CommonProps.aidl @@ -16,7 +16,7 @@ package android.hardware.biometrics.common; -import android.hardware.biometrics.common.HardwareInfo; +import android.hardware.biometrics.common.ComponentInfo; import android.hardware.biometrics.common.SensorStrength; @VintfStability @@ -41,16 +41,7 @@ parcelable CommonProps { int maxEnrollmentsPerUser; /** - * A list of hardware information for subsystems that pertain to this biometric sensor. + * A list of component information for subsystems that pertain to this biometric sensor. */ - HardwareInfo[] hardwareInfo; - - /** - * Software information for subsystems that pertain to this biometric sensor. - * This may include information for the matching algorithm, the PAD (Presentation Attack - * Detection) algorithm, and any other algorithm(s) used by this biometric sensor. - * For example, ;;. - * The format of each algorithm's info can be //. - */ - String softwareInfo; + ComponentInfo[] componentInfo; } diff --git a/biometrics/common/aidl/android/hardware/biometrics/common/HardwareInfo.aidl b/biometrics/common/aidl/android/hardware/biometrics/common/ComponentInfo.aidl similarity index 61% rename from biometrics/common/aidl/android/hardware/biometrics/common/HardwareInfo.aidl rename to biometrics/common/aidl/android/hardware/biometrics/common/ComponentInfo.aidl index ce9e354dd3..b268eef976 100644 --- a/biometrics/common/aidl/android/hardware/biometrics/common/HardwareInfo.aidl +++ b/biometrics/common/aidl/android/hardware/biometrics/common/ComponentInfo.aidl @@ -17,19 +17,34 @@ package android.hardware.biometrics.common; @VintfStability -parcelable HardwareInfo { +parcelable ComponentInfo { /** * An identifier uniquely identifying a subsystem. + * It must not be an empty string. */ - String deviceName; + String componentId; /** * The hardware version. For example, //. + * If there's no hardware version for this component, it must be empty. */ String hardwareVersion; + /** + * The firmware version. + * If there's no firmware version for this component, it must be empty. + */ + String firmwareVersion; + /** * The sensor's serial number. + * If there's no serial number for this component, it must be empty. */ String serialNumber; + + /** + * The software version. For example, //. + * If there's no software version for this component, it must be empty. + */ + String softwareVersion; } diff --git a/biometrics/face/aidl/default/Face.cpp b/biometrics/face/aidl/default/Face.cpp index a4520deb47..aca3e135f6 100644 --- a/biometrics/face/aidl/default/Face.cpp +++ b/biometrics/face/aidl/default/Face.cpp @@ -24,23 +24,33 @@ const common::SensorStrength kSensorStrength = common::SensorStrength::STRONG; const int kMaxEnrollmentsPerUser = 5; const FaceSensorType kSensorType = FaceSensorType::RGB; const bool kHalControlsPreview = true; -const std::string kHwDeviceName = "faceSensor"; +const std::string kHwComponentId = "faceSensor"; const std::string kHardwareVersion = "vendor/model/revision"; +const std::string kFirmwareVersion = "1.01"; const std::string kSerialNumber = "00000001"; -const std::string kSoftwareVersion = "vendor1/algorithm1/version;vendor2/algorithm2/version"; +const std::string kSwComponentId = "matchingAlgorithm"; +const std::string kSoftwareVersion = "vendor/version/revision"; ndk::ScopedAStatus Face::getSensorProps(std::vector* return_val) { - common::HardwareInfo hardware_info; - hardware_info.deviceName = kHwDeviceName; - hardware_info.hardwareVersion = kHardwareVersion; - hardware_info.serialNumber = kSerialNumber; + common::ComponentInfo hw_component_info; + hw_component_info.componentId = kHwComponentId; + hw_component_info.hardwareVersion = kHardwareVersion; + hw_component_info.firmwareVersion = kFirmwareVersion; + hw_component_info.serialNumber = kSerialNumber; + hw_component_info.softwareVersion = ""; + + common::ComponentInfo sw_component_info; + sw_component_info.componentId = kSwComponentId; + sw_component_info.hardwareVersion = ""; + sw_component_info.firmwareVersion = ""; + sw_component_info.serialNumber = ""; + sw_component_info.softwareVersion = kSoftwareVersion; common::CommonProps commonProps; commonProps.sensorId = kSensorId; commonProps.sensorStrength = kSensorStrength; commonProps.maxEnrollmentsPerUser = kMaxEnrollmentsPerUser; - commonProps.hardwareInfo = {std::move(hardware_info)}; - commonProps.softwareInfo = kSoftwareVersion; + commonProps.componentInfo = {std::move(hw_component_info), std::move(sw_component_info)}; SensorProps props; props.commonProps = std::move(commonProps); diff --git a/biometrics/fingerprint/aidl/default/Fingerprint.cpp b/biometrics/fingerprint/aidl/default/Fingerprint.cpp index 79f48fe195..fbfa52f0e7 100644 --- a/biometrics/fingerprint/aidl/default/Fingerprint.cpp +++ b/biometrics/fingerprint/aidl/default/Fingerprint.cpp @@ -26,10 +26,12 @@ constexpr common::SensorStrength SENSOR_STRENGTH = common::SensorStrength::STRON constexpr int MAX_ENROLLMENTS_PER_USER = 5; constexpr FingerprintSensorType SENSOR_TYPE = FingerprintSensorType::REAR; constexpr bool SUPPORTS_NAVIGATION_GESTURES = true; -constexpr char HW_DEVICE_NAME[] = "fingerprintSensor"; +constexpr char HW_COMPONENT_ID[] = "fingerprintSensor"; constexpr char HW_VERSION[] = "vendor/model/revision"; +constexpr char FW_VERSION[] = "1.01"; constexpr char SERIAL_NUMBER[] = "00000001"; -constexpr char SW_VERSION[] = "vendor1/algorithm1/version;vendor2/algorithm2/version"; +constexpr char SW_COMPONENT_ID[] = "matchingAlgorithm"; +constexpr char SW_VERSION[] = "vendor/version/revision"; } // namespace @@ -37,10 +39,13 @@ Fingerprint::Fingerprint() : mEngine(std::make_unique()), mWorker(MAX_WORKER_QUEUE_SIZE) {} ndk::ScopedAStatus Fingerprint::getSensorProps(std::vector* out) { - std::vector hardwareInfos = {{HW_DEVICE_NAME, HW_VERSION, SERIAL_NUMBER}}; + std::vector componentInfo = { + {HW_COMPONENT_ID, HW_VERSION, FW_VERSION, SERIAL_NUMBER, "" /* softwareVersion */}, + {SW_COMPONENT_ID, "" /* hardwareVersion */, "" /* firmwareVersion */, + "" /* serialNumber */, SW_VERSION}}; common::CommonProps commonProps = {SENSOR_ID, SENSOR_STRENGTH, MAX_ENROLLMENTS_PER_USER, - hardwareInfos, SW_VERSION}; + componentInfo}; SensorLocation sensorLocation = {0 /* displayId */, 0 /* sensorLocationX */, 0 /* sensorLocationY */, 0 /* sensorRadius */}; -- GitLab From b690fb822e12e249ca98b9c4f73130c20c764c8f Mon Sep 17 00:00:00 2001 From: chenpaul Date: Tue, 16 Mar 2021 22:49:18 +0800 Subject: [PATCH 538/790] Uprev IWifiEventCallback.hal to 1.5 Bug: 178126071 Test: atest VtsHalWifiV1_5TargetTest wifi basic function is workable Change-Id: I5f1897b6d4190d80eaf25eccea04ccfdbe4884c7 --- wifi/1.5/Android.bp | 1 + wifi/1.5/IWifi.hal | 21 ++++++++++++++++++++- wifi/1.5/IWifiEventCallback.hal | 21 +++++++++++++++++++++ wifi/1.5/default/wifi.cpp | 18 ++++++++++++++++-- wifi/1.5/default/wifi.h | 11 ++++++++--- 5 files changed, 66 insertions(+), 6 deletions(-) create mode 100644 wifi/1.5/IWifiEventCallback.hal diff --git a/wifi/1.5/Android.bp b/wifi/1.5/Android.bp index 7c04c6967a..0887c6b5c1 100644 --- a/wifi/1.5/Android.bp +++ b/wifi/1.5/Android.bp @@ -20,6 +20,7 @@ hidl_interface { "IWifiNanIface.hal", "IWifiNanIfaceEventCallback.hal", "IWifiStaIface.hal", + "IWifiEventCallback.hal", ], interfaces: [ "android.hardware.wifi@1.0", diff --git a/wifi/1.5/IWifi.hal b/wifi/1.5/IWifi.hal index 66d0a9c2f9..28b808ed32 100644 --- a/wifi/1.5/IWifi.hal +++ b/wifi/1.5/IWifi.hal @@ -17,6 +17,8 @@ package android.hardware.wifi@1.5; import @1.4::IWifi; +import IWifiEventCallback; +import @1.0::WifiStatus; /** * This is the root of the HAL module and is the interface returned when @@ -24,4 +26,21 @@ import @1.4::IWifi; * module loaded in the system. * IWifi.getChip() must return @1.5::IWifiChip */ -interface IWifi extends @1.4::IWifi {}; +interface IWifi extends @1.4::IWifi { + /** + * Requests notifications of significant events for the HAL. Multiple calls to + * this must register multiple callbacks each of which must receive all + * events. |IWifiEventCallback| object registration must be independent of the + * state of the rest of the HAL and must persist though stops/starts. These + * objects must be deleted when the corresponding client process is dead. + * + * @param callback An instance of the |IWifiEventCallback| HIDL interface + * object. + * @return status WifiStatus of the operation. + * Possible status codes: + * |WifiStatusCode.SUCCESS|, + * |WifiStatusCode.UNKNOWN| + */ + registerEventCallback_1_5(IWifiEventCallback callback) + generates (WifiStatus status); +}; diff --git a/wifi/1.5/IWifiEventCallback.hal b/wifi/1.5/IWifiEventCallback.hal new file mode 100644 index 0000000000..17dce39950 --- /dev/null +++ b/wifi/1.5/IWifiEventCallback.hal @@ -0,0 +1,21 @@ +/* + * 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.wifi@1.5; + +import @1.0::IWifiEventCallback; + +interface IWifiEventCallback extends @1.0::IWifiEventCallback {}; diff --git a/wifi/1.5/default/wifi.cpp b/wifi/1.5/default/wifi.cpp index da98db8296..b4037e9907 100644 --- a/wifi/1.5/default/wifi.cpp +++ b/wifi/1.5/default/wifi.cpp @@ -50,13 +50,21 @@ bool Wifi::isValid() { } Return Wifi::registerEventCallback( - const sp& event_callback, + const sp& event_callback, registerEventCallback_cb hidl_status_cb) { return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN, &Wifi::registerEventCallbackInternal, hidl_status_cb, event_callback); } +Return Wifi::registerEventCallback_1_5( + const sp& event_callback, + registerEventCallback_1_5_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN, + &Wifi::registerEventCallbackInternal_1_5, + hidl_status_cb, event_callback); +} + Return Wifi::isStarted() { return run_state_ != RunState::STOPPED; } Return Wifi::start(start_cb hidl_status_cb) { @@ -95,7 +103,13 @@ Return Wifi::debug(const hidl_handle& handle, } WifiStatus Wifi::registerEventCallbackInternal( - const sp& event_callback) { + const sp& event_callback __unused) { + // Deprecated support for this callback. + return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); +} + +WifiStatus Wifi::registerEventCallbackInternal_1_5( + const sp& event_callback) { if (!event_cb_handler_.addCallback(event_callback)) { return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); } diff --git a/wifi/1.5/default/wifi.h b/wifi/1.5/default/wifi.h index 825c0bc182..840bdfd927 100644 --- a/wifi/1.5/default/wifi.h +++ b/wifi/1.5/default/wifi.h @@ -52,8 +52,11 @@ class Wifi : public V1_5::IWifi { // HIDL methods exposed. Return registerEventCallback( - const sp& event_callback, + const sp& event_callback, registerEventCallback_cb hidl_status_cb) override; + Return registerEventCallback_1_5( + const sp& event_callback, + registerEventCallback_1_5_cb hidl_status_cb) override; Return isStarted() override; Return start(start_cb hidl_status_cb) override; Return stop(stop_cb hidl_status_cb) override; @@ -67,7 +70,9 @@ class Wifi : public V1_5::IWifi { // Corresponding worker functions for the HIDL methods. WifiStatus registerEventCallbackInternal( - const sp& event_callback); + const sp& event_callback __unused); + WifiStatus registerEventCallbackInternal_1_5( + const sp& event_callback); WifiStatus startInternal(); WifiStatus stopInternal(std::unique_lock* lock); std::pair> getChipIdsInternal(); @@ -87,7 +92,7 @@ class Wifi : public V1_5::IWifi { std::shared_ptr feature_flags_; RunState run_state_; std::vector> chips_; - hidl_callback_util::HidlCallbackHandler + hidl_callback_util::HidlCallbackHandler event_cb_handler_; DISALLOW_COPY_AND_ASSIGN(Wifi); -- GitLab From f78f2676da9d011968330c57bf70d9804124ecf7 Mon Sep 17 00:00:00 2001 From: Hongbo Zeng Date: Fri, 26 Feb 2021 21:48:12 +0800 Subject: [PATCH 539/790] move the fields in RouteSelectionDescriptorParams to RouteSelectionDescriptor Bug: 178075054 Test: full build pass Change-Id: I283514bd63cb3ae7c37d8e3d4740e38f7e79a09e --- radio/1.6/types.hal | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/radio/1.6/types.hal b/radio/1.6/types.hal index 95eba69948..f2c0e76c7a 100644 --- a/radio/1.6/types.hal +++ b/radio/1.6/types.hal @@ -1026,18 +1026,6 @@ struct RouteSelectionDescriptor { * precedence. */ uint8_t precedence; - /** - * Parameters defining this RouteSelectionDescriptor. The length of the vector - * must be >= 1. - */ - vec routeSelectionDescriptorParams; -}; - -/** - * This struct represents a route selection descriptor. A valid struct must have - * at least one of the vectors non-empty. - */ -struct RouteSelectionDescriptorParams { /** * Valid values are IP, IPV6 and IPV4V6. */ -- GitLab From 288409881e16b7857dc8880cd299a3f5ca159284 Mon Sep 17 00:00:00 2001 From: Bob Badour Date: Fri, 19 Mar 2021 05:13:08 -0700 Subject: [PATCH 540/790] [LSC] Add LOCAL_LICENSE_KINDS to hardware/interfaces Added SPDX-license-identifier-Apache-2.0 to: camera/device/3.7/Android.bp camera/provider/2.7/Android.bp Bug: 68860345 Bug: 151177513 Bug: 151953481 Test: m all Exempt-From-Owner-Approval: janitorial work Change-Id: I59ccb5f111e47611a92c5e1d6488593a1ce02ec7 --- camera/device/3.7/Android.bp | 9 +++++++++ camera/provider/2.7/Android.bp | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/camera/device/3.7/Android.bp b/camera/device/3.7/Android.bp index 42782f29a9..163f781e42 100644 --- a/camera/device/3.7/Android.bp +++ b/camera/device/3.7/Android.bp @@ -1,5 +1,14 @@ // 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.camera.device@3.7", root: "android.hardware", diff --git a/camera/provider/2.7/Android.bp b/camera/provider/2.7/Android.bp index 094dd9d4cd..ba59b380f5 100644 --- a/camera/provider/2.7/Android.bp +++ b/camera/provider/2.7/Android.bp @@ -1,5 +1,14 @@ // 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.camera.provider@2.7", root: "android.hardware", -- GitLab From 46bf892f46aac0f3269970267e6ab7ed0d7d61a3 Mon Sep 17 00:00:00 2001 From: Xusong Wang Date: Fri, 19 Mar 2021 13:58:24 -0700 Subject: [PATCH 541/790] Rename BufferRole.frequency -> probability -- HAL. "Frenquency" often refers to the number of occurrences over a period of time, while "probability" refers to the number of occurrences of one event over the number of occurrences of all events. "Probability" is a better name for this field. Fixes: 183117895 Test: VtsHalNeuralnetworksTargetTest Test: NNT_static Change-Id: Ic86f73b8be2aed567ae4ca17bdb3a57c658fb349 --- neuralnetworks/1.3/utils/src/Conversions.cpp | 4 +- .../hardware/neuralnetworks/BufferRole.aidl | 2 +- .../hardware/neuralnetworks/BufferRole.aidl | 2 +- neuralnetworks/aidl/utils/src/Conversions.cpp | 4 +- .../vts/functional/GeneratedTestHarness.cpp | 2 +- .../aidl/vts/functional/MemoryDomainTests.cpp | 66 +++++++++---------- 6 files changed, 40 insertions(+), 40 deletions(-) diff --git a/neuralnetworks/1.3/utils/src/Conversions.cpp b/neuralnetworks/1.3/utils/src/Conversions.cpp index 9788fe1b9d..8b45f715ab 100644 --- a/neuralnetworks/1.3/utils/src/Conversions.cpp +++ b/neuralnetworks/1.3/utils/src/Conversions.cpp @@ -244,7 +244,7 @@ GeneralResult unvalidatedConvert(const hal::V1_3::BufferRole& buffer return BufferRole{ .modelIndex = bufferRole.modelIndex, .ioIndex = bufferRole.ioIndex, - .frequency = bufferRole.frequency, + .probability = bufferRole.frequency, }; } @@ -577,7 +577,7 @@ nn::GeneralResult unvalidatedConvert(const nn::BufferRole& bufferRol return BufferRole{ .modelIndex = bufferRole.modelIndex, .ioIndex = bufferRole.ioIndex, - .frequency = bufferRole.frequency, + .frequency = bufferRole.probability, }; } diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/BufferRole.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/BufferRole.aidl index c2d636c53d..907fa0bb15 100644 --- a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/BufferRole.aidl +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/BufferRole.aidl @@ -35,5 +35,5 @@ package android.hardware.neuralnetworks; parcelable BufferRole { int modelIndex; int ioIndex; - float frequency; + float probability; } diff --git a/neuralnetworks/aidl/android/hardware/neuralnetworks/BufferRole.aidl b/neuralnetworks/aidl/android/hardware/neuralnetworks/BufferRole.aidl index 0d7f678006..c444851b1e 100644 --- a/neuralnetworks/aidl/android/hardware/neuralnetworks/BufferRole.aidl +++ b/neuralnetworks/aidl/android/hardware/neuralnetworks/BufferRole.aidl @@ -35,5 +35,5 @@ parcelable BufferRole { * used in the specified role. This is provided as a hint to optimize the case when multiple * roles prefer different buffer locations or data layouts. */ - float frequency; + float probability; } diff --git a/neuralnetworks/aidl/utils/src/Conversions.cpp b/neuralnetworks/aidl/utils/src/Conversions.cpp index c47ba0ec1c..45bc005e9f 100644 --- a/neuralnetworks/aidl/utils/src/Conversions.cpp +++ b/neuralnetworks/aidl/utils/src/Conversions.cpp @@ -472,7 +472,7 @@ GeneralResult unvalidatedConvert(const aidl_hal::BufferRole& bufferR return BufferRole{ .modelIndex = static_cast(bufferRole.modelIndex), .ioIndex = static_cast(bufferRole.ioIndex), - .frequency = bufferRole.frequency, + .probability = bufferRole.probability, }; } @@ -718,7 +718,7 @@ nn::GeneralResult unvalidatedConvert(const nn::BufferRole& bufferRol return BufferRole{ .modelIndex = static_cast(bufferRole.modelIndex), .ioIndex = static_cast(bufferRole.ioIndex), - .frequency = bufferRole.frequency, + .probability = bufferRole.probability, }; } diff --git a/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp index 7a042ed37e..098ed94791 100644 --- a/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp +++ b/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp @@ -101,7 +101,7 @@ class DeviceMemoryAllocator { ASSERT_NE(result, nullptr); // Prepare arguments. - BufferRole role = {.modelIndex = 0, .ioIndex = index, .frequency = 1.0f}; + BufferRole role = {.modelIndex = 0, .ioIndex = index, .probability = 1.0f}; std::vector inputRoles, outputRoles; if constexpr (ioType == IOType::INPUT) { inputRoles = {role}; diff --git a/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp b/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp index 57bc1aed54..9c6d385496 100644 --- a/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp +++ b/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp @@ -333,18 +333,18 @@ class MemoryDomainAllocateTest : public MemoryDomainTestBase, const std::shared_ptr& model2) { validateAllocate({ .preparedModels = {model1, model2}, - .inputRoles = {{.modelIndex = 0, .ioIndex = 0, .frequency = 1.0f}, - {.modelIndex = 1, .ioIndex = 0, .frequency = 1.0f}}, + .inputRoles = {{.modelIndex = 0, .ioIndex = 0, .probability = 1.0f}, + {.modelIndex = 1, .ioIndex = 0, .probability = 1.0f}}, }); validateAllocate({ .preparedModels = {model1, model2}, - .inputRoles = {{.modelIndex = 0, .ioIndex = 0, .frequency = 1.0f}}, - .outputRoles = {{.modelIndex = 1, .ioIndex = 0, .frequency = 1.0f}}, + .inputRoles = {{.modelIndex = 0, .ioIndex = 0, .probability = 1.0f}}, + .outputRoles = {{.modelIndex = 1, .ioIndex = 0, .probability = 1.0f}}, }); validateAllocate({ .preparedModels = {model1, model2}, - .outputRoles = {{.modelIndex = 0, .ioIndex = 0, .frequency = 1.0f}, - {.modelIndex = 1, .ioIndex = 0, .frequency = 1.0f}}, + .outputRoles = {{.modelIndex = 0, .ioIndex = 0, .probability = 1.0f}, + {.modelIndex = 1, .ioIndex = 0, .probability = 1.0f}}, }); } }; @@ -366,13 +366,13 @@ TEST_P(MemoryDomainAllocateTest, NullptrPreparedModel) { // Test with nullptr prepared model as input role. validateAllocate({ .preparedModels = {nullptr}, - .inputRoles = {{.modelIndex = 0, .ioIndex = 0, .frequency = 1.0f}}, + .inputRoles = {{.modelIndex = 0, .ioIndex = 0, .probability = 1.0f}}, }); // Test with nullptr prepared model as output role. validateAllocate({ .preparedModels = {nullptr}, - .outputRoles = {{.modelIndex = 0, .ioIndex = 0, .frequency = 1.0f}}, + .outputRoles = {{.modelIndex = 0, .ioIndex = 0, .probability = 1.0f}}, }); } @@ -383,13 +383,13 @@ TEST_P(MemoryDomainAllocateTest, InvalidPreparedModel) { // Test with invalid prepared model as input role. validateAllocate({ .preparedModels = {invalidPreparedModel}, - .inputRoles = {{.modelIndex = 0, .ioIndex = 0, .frequency = 1.0f}}, + .inputRoles = {{.modelIndex = 0, .ioIndex = 0, .probability = 1.0f}}, }); // Test with invalid prepared model as output role. validateAllocate({ .preparedModels = {invalidPreparedModel}, - .outputRoles = {{.modelIndex = 0, .ioIndex = 0, .frequency = 1.0f}}, + .outputRoles = {{.modelIndex = 0, .ioIndex = 0, .probability = 1.0f}}, }); } @@ -400,13 +400,13 @@ TEST_P(MemoryDomainAllocateTest, InvalidModelIndex) { // This should fail, because the model index is out of bound. validateAllocate({ .preparedModels = {preparedModel}, - .inputRoles = {{.modelIndex = 1, .ioIndex = 0, .frequency = 1.0f}}, + .inputRoles = {{.modelIndex = 1, .ioIndex = 0, .probability = 1.0f}}, }); // This should fail, because the model index is out of bound. validateAllocate({ .preparedModels = {preparedModel}, - .outputRoles = {{.modelIndex = 1, .ioIndex = 0, .frequency = 1.0f}}, + .outputRoles = {{.modelIndex = 1, .ioIndex = 0, .probability = 1.0f}}, }); } @@ -417,30 +417,30 @@ TEST_P(MemoryDomainAllocateTest, InvalidIOIndex) { // This should fail, because the model only has one input. validateAllocate({ .preparedModels = {preparedModel}, - .inputRoles = {{.modelIndex = 0, .ioIndex = 1, .frequency = 1.0f}}, + .inputRoles = {{.modelIndex = 0, .ioIndex = 1, .probability = 1.0f}}, }); // This should fail, because the model only has one output. validateAllocate({ .preparedModels = {preparedModel}, - .outputRoles = {{.modelIndex = 0, .ioIndex = 1, .frequency = 1.0f}}, + .outputRoles = {{.modelIndex = 0, .ioIndex = 1, .probability = 1.0f}}, }); } -TEST_P(MemoryDomainAllocateTest, InvalidFrequency) { +TEST_P(MemoryDomainAllocateTest, InvalidProbability) { auto preparedModel = createConvPreparedModel(kTestOperand); if (preparedModel == nullptr) return; for (float invalidFreq : {10.0f, 0.0f, -0.5f}) { - // Test with invalid frequency for input roles. + // Test with invalid probability for input roles. validateAllocate({ .preparedModels = {preparedModel}, - .inputRoles = {{.modelIndex = 0, .ioIndex = 0, .frequency = invalidFreq}}, + .inputRoles = {{.modelIndex = 0, .ioIndex = 0, .probability = invalidFreq}}, }); - // Test with invalid frequency for output roles. + // Test with invalid probability for output roles. validateAllocate({ .preparedModels = {preparedModel}, - .outputRoles = {{.modelIndex = 0, .ioIndex = 0, .frequency = invalidFreq}}, + .outputRoles = {{.modelIndex = 0, .ioIndex = 0, .probability = invalidFreq}}, }); } } @@ -452,25 +452,25 @@ TEST_P(MemoryDomainAllocateTest, SameRoleSpecifiedTwice) { // Same role with same model index. validateAllocate({ .preparedModels = {preparedModel}, - .inputRoles = {{.modelIndex = 0, .ioIndex = 0, .frequency = 1.0f}, - {.modelIndex = 0, .ioIndex = 0, .frequency = 1.0f}}, + .inputRoles = {{.modelIndex = 0, .ioIndex = 0, .probability = 1.0f}, + {.modelIndex = 0, .ioIndex = 0, .probability = 1.0f}}, }); validateAllocate({ .preparedModels = {preparedModel}, - .outputRoles = {{.modelIndex = 0, .ioIndex = 0, .frequency = 1.0f}, - {.modelIndex = 0, .ioIndex = 0, .frequency = 1.0f}}, + .outputRoles = {{.modelIndex = 0, .ioIndex = 0, .probability = 1.0f}, + {.modelIndex = 0, .ioIndex = 0, .probability = 1.0f}}, }); // Different model indexes, but logically referring to the same role. validateAllocate({ .preparedModels = {preparedModel, preparedModel}, - .inputRoles = {{.modelIndex = 0, .ioIndex = 0, .frequency = 1.0f}, - {.modelIndex = 1, .ioIndex = 0, .frequency = 1.0f}}, + .inputRoles = {{.modelIndex = 0, .ioIndex = 0, .probability = 1.0f}, + {.modelIndex = 1, .ioIndex = 0, .probability = 1.0f}}, }); validateAllocate({ .preparedModels = {preparedModel, preparedModel}, - .outputRoles = {{.modelIndex = 0, .ioIndex = 0, .frequency = 1.0f}, - {.modelIndex = 1, .ioIndex = 0, .frequency = 1.0f}}, + .outputRoles = {{.modelIndex = 0, .ioIndex = 0, .probability = 1.0f}, + {.modelIndex = 1, .ioIndex = 0, .probability = 1.0f}}, }); } @@ -549,12 +549,12 @@ TEST_P(MemoryDomainAllocateTest, ConflictRankBetweenRoleAndDesc) { validateAllocate({ .dimensions = badDimensions, .preparedModels = {preparedModel}, - .inputRoles = {{.modelIndex = 0, .ioIndex = 0, .frequency = 1.0f}}, + .inputRoles = {{.modelIndex = 0, .ioIndex = 0, .probability = 1.0f}}, }); validateAllocate({ .dimensions = badDimensions, .preparedModels = {preparedModel}, - .outputRoles = {{.modelIndex = 0, .ioIndex = 0, .frequency = 1.0f}}, + .outputRoles = {{.modelIndex = 0, .ioIndex = 0, .probability = 1.0f}}, }); } @@ -568,12 +568,12 @@ TEST_P(MemoryDomainAllocateTest, ConflictDimensionsBetweenRoleAndDesc) { validateAllocate({ .dimensions = badDimensions, .preparedModels = {preparedModel}, - .inputRoles = {{.modelIndex = 0, .ioIndex = 0, .frequency = 1.0f}}, + .inputRoles = {{.modelIndex = 0, .ioIndex = 0, .probability = 1.0f}}, }); validateAllocate({ .dimensions = badDimensions, .preparedModels = {preparedModel}, - .outputRoles = {{.modelIndex = 0, .ioIndex = 0, .frequency = 1.0f}}, + .outputRoles = {{.modelIndex = 0, .ioIndex = 0, .probability = 1.0f}}, }); } @@ -586,7 +586,7 @@ TEST_P(MemoryDomainAllocateTest, ConflictRankWithScalarRole) { validateAllocate({ .dimensions = {1}, .preparedModels = {preparedModel}, - .inputRoles = {{.modelIndex = 0, .ioIndex = 2, .frequency = 1.0f}}, + .inputRoles = {{.modelIndex = 0, .ioIndex = 2, .probability = 1.0f}}, }); } @@ -620,7 +620,7 @@ class MemoryDomainCopyTestBase : public MemoryDomainTestBase { std::vector inputRoles(inputIndexes.size()), outputRoles(outputIndexes.size()); auto trans = [](int32_t ind) -> BufferRole { - return {.modelIndex = 0, .ioIndex = ind, .frequency = 1.0f}; + return {.modelIndex = 0, .ioIndex = ind, .probability = 1.0f}; }; std::transform(inputIndexes.begin(), inputIndexes.end(), inputRoles.begin(), trans); std::transform(outputIndexes.begin(), outputIndexes.end(), outputRoles.begin(), trans); -- GitLab From c6f570378bd657db956366f406ce7291b06164e2 Mon Sep 17 00:00:00 2001 From: chenpaul Date: Fri, 5 Mar 2021 17:06:50 +0800 Subject: [PATCH 542/790] Add API "startSubsystemRestart" and callback function In order to trigger subsystem restart to reload wlan firmware, this change adds an API for framework and vendor HAL. Meanwhile, create new callback function for subsystem restart instead of general callback "onFailure()". Bug: 178126071 Test: vendor HAL can received API call subsystem restart will callback "onSubsystemRestart()" Change-Id: If3dc84049a9171677ad281c9bcc67a44dc722bdb --- wifi/1.5/IWifiChip.hal | 21 +++++++++++++++++++++ wifi/1.5/IWifiEventCallback.hal | 9 ++++++++- wifi/1.5/default/wifi.cpp | 2 +- wifi/1.5/default/wifi_chip.cpp | 12 ++++++++++++ wifi/1.5/default/wifi_chip.h | 3 +++ wifi/1.5/default/wifi_legacy_hal.cpp | 4 ++++ wifi/1.5/default/wifi_legacy_hal.h | 2 ++ wifi/1.5/default/wifi_legacy_hal_stubs.cpp | 1 + 8 files changed, 52 insertions(+), 2 deletions(-) diff --git a/wifi/1.5/IWifiChip.hal b/wifi/1.5/IWifiChip.hal index 5a3e2883d5..e199850c1a 100644 --- a/wifi/1.5/IWifiChip.hal +++ b/wifi/1.5/IWifiChip.hal @@ -303,4 +303,25 @@ interface IWifiChip extends @1.4::IWifiChip { getUsableChannels(WifiBand band, bitfield ifaceModeMask, bitfield filterMask) generates (WifiStatus status, vec channels); + + /** + * Trigger subsystem restart + * + * If the framework detects a problem (e.g. connection failure), + * it must call this function to attempt recovery. + * + * When the wifi HAL receiveds triggerSubsystemRestart(), it must restart + * the wlan subsystem, especially the wlan firmware. + * + * Regarding the callback function for subsystem restart, refer to documentation of + * |IWifiEventCallback.onSubsystemRestart| for details. + * + * @return status WifiStatus of the operation. + * Possible status codes: + * |WifiStatusCode.SUCCESS|, + * |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|, + * |WifiStatusCode.ERROR_NOT_AVAILABLE|, + * |WifiStatusCode.ERROR_UNKNOWN| + */ + triggerSubsystemRestart() generates (WifiStatus status); }; diff --git a/wifi/1.5/IWifiEventCallback.hal b/wifi/1.5/IWifiEventCallback.hal index 17dce39950..ff276306fd 100644 --- a/wifi/1.5/IWifiEventCallback.hal +++ b/wifi/1.5/IWifiEventCallback.hal @@ -17,5 +17,12 @@ package android.hardware.wifi@1.5; import @1.0::IWifiEventCallback; +import @1.0::WifiStatus; -interface IWifiEventCallback extends @1.0::IWifiEventCallback {}; +interface IWifiEventCallback extends @1.0::IWifiEventCallback { + /** + * Must be called when the Wi-Fi subsystem restart completes. + * Once this event is received, framework must fully reset the Wi-Fi stack state. + */ + oneway onSubsystemRestart(WifiStatus status); +}; diff --git a/wifi/1.5/default/wifi.cpp b/wifi/1.5/default/wifi.cpp index b4037e9907..b9f20a4615 100644 --- a/wifi/1.5/default/wifi.cpp +++ b/wifi/1.5/default/wifi.cpp @@ -131,7 +131,7 @@ WifiStatus Wifi::startInternal() { WifiStatus wifi_status = createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, error); for (const auto& callback : event_cb_handler_.getCallbacks()) { - if (!callback->onFailure(wifi_status).isOk()) { + if (!callback->onSubsystemRestart(wifi_status).isOk()) { LOG(ERROR) << "Failed to invoke onFailure callback"; } } diff --git a/wifi/1.5/default/wifi_chip.cpp b/wifi/1.5/default/wifi_chip.cpp index 0499f456c1..961f9da4c2 100644 --- a/wifi/1.5/default/wifi_chip.cpp +++ b/wifi/1.5/default/wifi_chip.cpp @@ -747,6 +747,13 @@ Return WifiChip::getUsableChannels( ifaceModeMask, filterMask); } +Return WifiChip::triggerSubsystemRestart( + triggerSubsystemRestart_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, + &WifiChip::triggerSubsystemRestartInternal, + hidl_status_cb); +} + void WifiChip::invalidateAndRemoveAllIfaces() { invalidateAndClearBridgedApAll(); invalidateAndClearAll(ap_ifaces_); @@ -1522,6 +1529,11 @@ WifiChip::getUsableChannelsInternal(WifiBand band, uint32_t ifaceModeMask, return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_usable_channels}; } +WifiStatus WifiChip::triggerSubsystemRestartInternal() { + auto legacy_status = legacy_hal_.lock()->triggerSubsystemRestart(); + return createWifiStatusFromLegacyError(legacy_status); +} + WifiStatus WifiChip::handleChipConfiguration( /* NONNULL */ std::unique_lock* lock, ChipModeId mode_id) { diff --git a/wifi/1.5/default/wifi_chip.h b/wifi/1.5/default/wifi_chip.h index 92d639f8b5..bd40ead35a 100644 --- a/wifi/1.5/default/wifi_chip.h +++ b/wifi/1.5/default/wifi_chip.h @@ -184,6 +184,8 @@ class WifiChip : public V1_5::IWifiChip { WifiBand band, hidl_bitfield ifaceModeMask, hidl_bitfield filterMask, getUsableChannels_cb _hidl_cb) override; + Return triggerSubsystemRestart( + triggerSubsystemRestart_cb hidl_status_cb) override; private: void invalidateAndRemoveAllIfaces(); @@ -303,6 +305,7 @@ class WifiChip : public V1_5::IWifiChip { void invalidateAndClearBridgedApAll(); void invalidateAndClearBridgedAp(const std::string& br_name); bool findUsingNameFromBridgedApInstances(const std::string& name); + WifiStatus triggerSubsystemRestartInternal(); ChipId chip_id_; std::weak_ptr legacy_hal_; diff --git a/wifi/1.5/default/wifi_legacy_hal.cpp b/wifi/1.5/default/wifi_legacy_hal.cpp index 45ad84b8c1..848fbd6114 100644 --- a/wifi/1.5/default/wifi_legacy_hal.cpp +++ b/wifi/1.5/default/wifi_legacy_hal.cpp @@ -1676,6 +1676,10 @@ WifiLegacyHal::getUsableChannels(uint32_t band_mask, uint32_t iface_mode_mask, return {status, std::move(channels)}; } +wifi_error WifiLegacyHal::triggerSubsystemRestart() { + return global_func_table_.wifi_trigger_subsystem_restart(); +} + void WifiLegacyHal::invalidate() { global_handle_ = nullptr; iface_name_to_handle_.clear(); diff --git a/wifi/1.5/default/wifi_legacy_hal.h b/wifi/1.5/default/wifi_legacy_hal.h index 8ebc66aaa6..2bb7631efa 100644 --- a/wifi/1.5/default/wifi_legacy_hal.h +++ b/wifi/1.5/default/wifi_legacy_hal.h @@ -716,6 +716,8 @@ class WifiLegacyHal { std::pair> getUsableChannels( uint32_t band_mask, uint32_t iface_mode_mask, uint32_t filter_mask); + wifi_error triggerSubsystemRestart(); + private: // Retrieve interface handles for all the available interfaces. wifi_error retrieveIfaceHandles(); diff --git a/wifi/1.5/default/wifi_legacy_hal_stubs.cpp b/wifi/1.5/default/wifi_legacy_hal_stubs.cpp index 6212960d7a..dd860d6920 100644 --- a/wifi/1.5/default/wifi_legacy_hal_stubs.cpp +++ b/wifi/1.5/default/wifi_legacy_hal_stubs.cpp @@ -160,6 +160,7 @@ bool initHalFuncTableWithStubs(wifi_hal_fn* hal_fn) { populateStubFor(&hal_fn->wifi_twt_clear_stats); populateStubFor(&hal_fn->wifi_set_dtim_config); populateStubFor(&hal_fn->wifi_get_usable_channels); + populateStubFor(&hal_fn->wifi_trigger_subsystem_restart); return true; } } // namespace legacy_hal -- GitLab From 65aa12e1f2879c15535af7447439b92066e697ef Mon Sep 17 00:00:00 2001 From: Janis Danisevskis Date: Wed, 17 Mar 2021 10:55:10 -0700 Subject: [PATCH 543/790] Security: Provide generated java sources. Enable generation of java sources for AIDL interfaces. This allows enabling the @SensitiveData annotation without causing circular build dependencies. Also mark doc comments as @hide to prevent the interface from being included in the SDK. Bug: 174857732 Test: N/A Change-Id: If00e4dfc24bf776f87c7e2b2e3f42350aa4d4379 --- security/keymint/aidl/Android.bp | 3 ++- .../hardware/security/keymint/Algorithm.aidl | 1 + .../security/keymint/AttestationKey.aidl | 1 + .../hardware/security/keymint/BeginResult.aidl | 1 + .../hardware/security/keymint/BlockMode.aidl | 1 + .../hardware/security/keymint/Certificate.aidl | 1 + .../hardware/security/keymint/Digest.aidl | 1 + .../hardware/security/keymint/EcCurve.aidl | 1 + .../hardware/security/keymint/ErrorCode.aidl | 1 + .../security/keymint/HardwareAuthToken.aidl | 1 + .../keymint/HardwareAuthenticatorType.aidl | 1 + .../security/keymint/IKeyMintDevice.aidl | 1 + .../security/keymint/IKeyMintOperation.aidl | 1 + .../keymint/IRemotelyProvisionedComponent.aidl | 1 + .../security/keymint/KeyCharacteristics.aidl | 1 + .../security/keymint/KeyCreationResult.aidl | 1 + .../hardware/security/keymint/KeyFormat.aidl | 1 + .../security/keymint/KeyMintHardwareInfo.aidl | 1 + .../hardware/security/keymint/KeyOrigin.aidl | 1 + .../hardware/security/keymint/KeyParameter.aidl | 1 + .../security/keymint/KeyParameterValue.aidl | 1 + .../hardware/security/keymint/KeyPurpose.aidl | 1 + .../security/keymint/MacedPublicKey.aidl | 1 + .../hardware/security/keymint/PaddingMode.aidl | 1 + .../hardware/security/keymint/ProtectedData.aidl | 1 + .../hardware/security/keymint/SecurityLevel.aidl | 1 + .../android/hardware/security/keymint/Tag.aidl | 1 + .../hardware/security/keymint/TagType.aidl | 1 + .../hardware/security/keymint/Algorithm.aidl | 1 + .../security/keymint/AttestationKey.aidl | 1 + .../hardware/security/keymint/BeginResult.aidl | 1 + .../hardware/security/keymint/BlockMode.aidl | 1 + .../hardware/security/keymint/Certificate.aidl | 1 + .../hardware/security/keymint/Digest.aidl | 1 + .../hardware/security/keymint/EcCurve.aidl | 1 + .../hardware/security/keymint/ErrorCode.aidl | 1 + .../security/keymint/HardwareAuthToken.aidl | 1 + .../keymint/HardwareAuthenticatorType.aidl | 1 + .../security/keymint/IKeyMintDevice.aidl | 1 + .../security/keymint/IKeyMintOperation.aidl | 1 + .../keymint/IRemotelyProvisionedComponent.aidl | 1 + .../security/keymint/KeyCharacteristics.aidl | 1 + .../security/keymint/KeyCreationResult.aidl | 1 + .../hardware/security/keymint/KeyFormat.aidl | 1 + .../security/keymint/KeyMintHardwareInfo.aidl | 1 + .../hardware/security/keymint/KeyOrigin.aidl | 1 + .../hardware/security/keymint/KeyParameter.aidl | 1 + .../security/keymint/KeyParameterValue.aidl | 4 ++-- .../hardware/security/keymint/KeyPurpose.aidl | 1 + .../security/keymint/MacedPublicKey.aidl | 1 + .../hardware/security/keymint/PaddingMode.aidl | 1 + .../hardware/security/keymint/ProtectedData.aidl | 1 + .../hardware/security/keymint/SecurityLevel.aidl | 1 + .../android/hardware/security/keymint/Tag.aidl | 1 + .../hardware/security/keymint/TagType.aidl | 1 + security/secureclock/aidl/Android.bp | 3 ++- .../security/secureclock/ISecureClock.aidl | 4 +++- .../security/secureclock/TimeStampToken.aidl | 4 +++- .../hardware/security/secureclock/Timestamp.aidl | 4 +++- .../security/secureclock/ISecureClock.aidl | 2 +- .../security/secureclock/TimeStampToken.aidl | 2 +- .../hardware/security/secureclock/Timestamp.aidl | 1 + .../security/sharedsecret/ISharedSecret.aidl | 15 +++++++++++++++ .../sharedsecret/SharedSecretParameters.aidl | 16 ++++++++++++++++ .../security/sharedsecret/ISharedSecret.aidl | 2 +- .../sharedsecret/SharedSecretParameters.aidl | 2 +- 66 files changed, 104 insertions(+), 11 deletions(-) diff --git a/security/keymint/aidl/Android.bp b/security/keymint/aidl/Android.bp index 54cb4b8ebb..6766d99311 100644 --- a/security/keymint/aidl/Android.bp +++ b/security/keymint/aidl/Android.bp @@ -19,7 +19,8 @@ aidl_interface { stability: "vintf", backend: { java: { - sdk_version: "module_current", + platform_apis: true, + srcs_available: true, }, ndk: { vndk: { diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Algorithm.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Algorithm.aidl index 5adbdc10ca..6da124f601 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Algorithm.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Algorithm.aidl @@ -32,6 +32,7 @@ // later when a module using the interface is updated, e.g., Mainline modules. package android.hardware.security.keymint; +/* @hide */ @Backing(type="int") @VintfStability enum Algorithm { RSA = 1, diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/AttestationKey.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/AttestationKey.aidl index 21721bfa39..90f2e6ee54 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/AttestationKey.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/AttestationKey.aidl @@ -32,6 +32,7 @@ // later when a module using the interface is updated, e.g., Mainline modules. package android.hardware.security.keymint; +/* @hide */ @RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability parcelable AttestationKey { byte[] keyBlob; diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/BeginResult.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/BeginResult.aidl index d9d9c13e3b..c952a3152a 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/BeginResult.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/BeginResult.aidl @@ -32,6 +32,7 @@ // later when a module using the interface is updated, e.g., Mainline modules. package android.hardware.security.keymint; +/* @hide */ @VintfStability parcelable BeginResult { long challenge; diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/BlockMode.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/BlockMode.aidl index feba9d0ca3..004988326b 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/BlockMode.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/BlockMode.aidl @@ -32,6 +32,7 @@ // later when a module using the interface is updated, e.g., Mainline modules. package android.hardware.security.keymint; +/* @hide */ @Backing(type="int") @VintfStability enum BlockMode { ECB = 1, diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Certificate.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Certificate.aidl index 470d53405c..645f0a72ee 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Certificate.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Certificate.aidl @@ -32,6 +32,7 @@ // later when a module using the interface is updated, e.g., Mainline modules. package android.hardware.security.keymint; +/* @hide */ @VintfStability parcelable Certificate { byte[] encodedCertificate; diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Digest.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Digest.aidl index 5a15aad765..0df709609f 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Digest.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Digest.aidl @@ -32,6 +32,7 @@ // later when a module using the interface is updated, e.g., Mainline modules. package android.hardware.security.keymint; +/* @hide */ @Backing(type="int") @VintfStability enum Digest { NONE = 0, diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/EcCurve.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/EcCurve.aidl index d7ec0068f6..6b4a9aefb2 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/EcCurve.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/EcCurve.aidl @@ -32,6 +32,7 @@ // later when a module using the interface is updated, e.g., Mainline modules. package android.hardware.security.keymint; +/* @hide */ @Backing(type="int") @VintfStability enum EcCurve { P_224 = 0, diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ErrorCode.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ErrorCode.aidl index 91e289950b..69ec4cefbb 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ErrorCode.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ErrorCode.aidl @@ -32,6 +32,7 @@ // later when a module using the interface is updated, e.g., Mainline modules. package android.hardware.security.keymint; +/* @hide */ @Backing(type="int") @VintfStability enum ErrorCode { OK = 0, diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/HardwareAuthToken.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/HardwareAuthToken.aidl index 3205a461af..2e07924382 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/HardwareAuthToken.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/HardwareAuthToken.aidl @@ -32,6 +32,7 @@ // later when a module using the interface is updated, e.g., Mainline modules. package android.hardware.security.keymint; +/* @hide */ @RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability parcelable HardwareAuthToken { long challenge; diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/HardwareAuthenticatorType.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/HardwareAuthenticatorType.aidl index 926f2ecd52..dfc98f0066 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/HardwareAuthenticatorType.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/HardwareAuthenticatorType.aidl @@ -32,6 +32,7 @@ // later when a module using the interface is updated, e.g., Mainline modules. package android.hardware.security.keymint; +/* @hide */ @Backing(type="int") @VintfStability enum HardwareAuthenticatorType { NONE = 0, diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintDevice.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintDevice.aidl index bb186694ce..195590c2f3 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintDevice.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintDevice.aidl @@ -32,6 +32,7 @@ // later when a module using the interface is updated, e.g., Mainline modules. package android.hardware.security.keymint; +/* @hide */ @VintfStability interface IKeyMintDevice { android.hardware.security.keymint.KeyMintHardwareInfo getHardwareInfo(); diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintOperation.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintOperation.aidl index 28a83da0fa..5ac2b4a139 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintOperation.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintOperation.aidl @@ -32,6 +32,7 @@ // later when a module using the interface is updated, e.g., Mainline modules. package android.hardware.security.keymint; +/* @hide */ @VintfStability interface IKeyMintOperation { void updateAad(in byte[] input, in @nullable android.hardware.security.keymint.HardwareAuthToken authToken, in @nullable android.hardware.security.secureclock.TimeStampToken timeStampToken); diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl index 8387ecc9dd..63bad2c0b7 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl @@ -32,6 +32,7 @@ // later when a module using the interface is updated, e.g., Mainline modules. package android.hardware.security.keymint; +/* @hide */ @VintfStability interface IRemotelyProvisionedComponent { byte[] generateEcdsaP256KeyPair(in boolean testMode, out android.hardware.security.keymint.MacedPublicKey macedPublicKey); diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyCharacteristics.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyCharacteristics.aidl index 91ac7be061..008381f282 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyCharacteristics.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyCharacteristics.aidl @@ -32,6 +32,7 @@ // later when a module using the interface is updated, e.g., Mainline modules. package android.hardware.security.keymint; +/* @hide */ @VintfStability parcelable KeyCharacteristics { android.hardware.security.keymint.SecurityLevel securityLevel = android.hardware.security.keymint.SecurityLevel.SOFTWARE; diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyCreationResult.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyCreationResult.aidl index b85203fd2f..9f77d3e3d5 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyCreationResult.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyCreationResult.aidl @@ -32,6 +32,7 @@ // later when a module using the interface is updated, e.g., Mainline modules. package android.hardware.security.keymint; +/* @hide */ @VintfStability parcelable KeyCreationResult { byte[] keyBlob; diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyFormat.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyFormat.aidl index 4500288542..9560d8d2b5 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyFormat.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyFormat.aidl @@ -32,6 +32,7 @@ // later when a module using the interface is updated, e.g., Mainline modules. package android.hardware.security.keymint; +/* @hide */ @Backing(type="int") @VintfStability enum KeyFormat { X509 = 0, diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyMintHardwareInfo.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyMintHardwareInfo.aidl index d959ac4536..2113e42a8e 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyMintHardwareInfo.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyMintHardwareInfo.aidl @@ -32,6 +32,7 @@ // later when a module using the interface is updated, e.g., Mainline modules. package android.hardware.security.keymint; +/* @hide */ @RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability parcelable KeyMintHardwareInfo { int versionNumber; diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyOrigin.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyOrigin.aidl index 2b65567d8f..4b3c659ffe 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyOrigin.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyOrigin.aidl @@ -32,6 +32,7 @@ // later when a module using the interface is updated, e.g., Mainline modules. package android.hardware.security.keymint; +/* @hide */ @Backing(type="int") @VintfStability enum KeyOrigin { GENERATED = 0, diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameter.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameter.aidl index ee8abda648..c5a1e011d2 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameter.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameter.aidl @@ -32,6 +32,7 @@ // later when a module using the interface is updated, e.g., Mainline modules. package android.hardware.security.keymint; +/* @hide */ @RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability parcelable KeyParameter { android.hardware.security.keymint.Tag tag = android.hardware.security.keymint.Tag.INVALID; diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameterValue.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameterValue.aidl index fc57cd22e3..7a0b074fe5 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameterValue.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameterValue.aidl @@ -32,6 +32,7 @@ // later when a module using the interface is updated, e.g., Mainline modules. package android.hardware.security.keymint; +/* @hide */ @RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability union KeyParameterValue { int invalid; diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyPurpose.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyPurpose.aidl index f891de6c8e..b84bec1fc0 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyPurpose.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyPurpose.aidl @@ -32,6 +32,7 @@ // later when a module using the interface is updated, e.g., Mainline modules. package android.hardware.security.keymint; +/* @hide */ @Backing(type="int") @VintfStability enum KeyPurpose { ENCRYPT = 0, diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/MacedPublicKey.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/MacedPublicKey.aidl index 30b38e1f01..8095e8ce04 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/MacedPublicKey.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/MacedPublicKey.aidl @@ -32,6 +32,7 @@ // later when a module using the interface is updated, e.g., Mainline modules. package android.hardware.security.keymint; +/* @hide */ @VintfStability parcelable MacedPublicKey { byte[] macedKey; diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/PaddingMode.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/PaddingMode.aidl index bfb6ea1e98..dba4a8a06e 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/PaddingMode.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/PaddingMode.aidl @@ -32,6 +32,7 @@ // later when a module using the interface is updated, e.g., Mainline modules. package android.hardware.security.keymint; +/* @hide */ @Backing(type="int") @VintfStability enum PaddingMode { NONE = 1, diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ProtectedData.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ProtectedData.aidl index 64cce78bd5..d1610b4d6f 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ProtectedData.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ProtectedData.aidl @@ -32,6 +32,7 @@ // later when a module using the interface is updated, e.g., Mainline modules. package android.hardware.security.keymint; +/* @hide */ @VintfStability parcelable ProtectedData { byte[] protectedData; diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/SecurityLevel.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/SecurityLevel.aidl index 628476d7e8..0d278e0af9 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/SecurityLevel.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/SecurityLevel.aidl @@ -32,6 +32,7 @@ // later when a module using the interface is updated, e.g., Mainline modules. package android.hardware.security.keymint; +/* @hide */ @Backing(type="int") @VintfStability enum SecurityLevel { SOFTWARE = 0, diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Tag.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Tag.aidl index ccb040437f..7591318289 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Tag.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Tag.aidl @@ -32,6 +32,7 @@ // later when a module using the interface is updated, e.g., Mainline modules. package android.hardware.security.keymint; +/* @hide */ @Backing(type="int") @VintfStability enum Tag { INVALID = 0, diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/TagType.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/TagType.aidl index 58f8bd3278..a7d1de5fd4 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/TagType.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/TagType.aidl @@ -32,6 +32,7 @@ // later when a module using the interface is updated, e.g., Mainline modules. package android.hardware.security.keymint; +/* @hide */ @Backing(type="int") @VintfStability enum TagType { INVALID = 0, diff --git a/security/keymint/aidl/android/hardware/security/keymint/Algorithm.aidl b/security/keymint/aidl/android/hardware/security/keymint/Algorithm.aidl index 8300b0d75c..18208939eb 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/Algorithm.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/Algorithm.aidl @@ -18,6 +18,7 @@ package android.hardware.security.keymint; /** * Algorithms provided by IKeyMintDevice implementations. + * @hide */ @VintfStability @Backing(type="int") diff --git a/security/keymint/aidl/android/hardware/security/keymint/AttestationKey.aidl b/security/keymint/aidl/android/hardware/security/keymint/AttestationKey.aidl index 8167cebacd..b4bc60c05b 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/AttestationKey.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/AttestationKey.aidl @@ -22,6 +22,7 @@ import android.hardware.security.keymint.KeyParameter; * Contains a key blob with Tag::ATTEST_KEY that can be used to sign an attestation certificate, * and the DER-encoded X.501 Subject Name that will be placed in the Issuer field of the attestation * certificate. + * @hide */ @VintfStability @RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true) diff --git a/security/keymint/aidl/android/hardware/security/keymint/BeginResult.aidl b/security/keymint/aidl/android/hardware/security/keymint/BeginResult.aidl index aaf9f3caa4..2304a580a5 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/BeginResult.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/BeginResult.aidl @@ -21,6 +21,7 @@ import android.hardware.security.keymint.KeyParameter; /** * This is all the results returned by the IKeyMintDevice begin() function. + * @hide */ @VintfStability parcelable BeginResult { diff --git a/security/keymint/aidl/android/hardware/security/keymint/BlockMode.aidl b/security/keymint/aidl/android/hardware/security/keymint/BlockMode.aidl index 629c89f02e..749da81aa8 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/BlockMode.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/BlockMode.aidl @@ -18,6 +18,7 @@ package android.hardware.security.keymint; /** * Symmetric block cipher modes provided by IKeyMintDevice implementations. + * @hide */ @VintfStability @Backing(type="int") diff --git a/security/keymint/aidl/android/hardware/security/keymint/Certificate.aidl b/security/keymint/aidl/android/hardware/security/keymint/Certificate.aidl index 0e5d898804..21dfdd554c 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/Certificate.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/Certificate.aidl @@ -18,6 +18,7 @@ package android.hardware.security.keymint; /** * This encodes an IKeyMintDevice certificate, generated for a KeyMint asymmetric public key. + * @hide */ @VintfStability parcelable Certificate { diff --git a/security/keymint/aidl/android/hardware/security/keymint/Digest.aidl b/security/keymint/aidl/android/hardware/security/keymint/Digest.aidl index b44da5a51c..a8768c3ec9 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/Digest.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/Digest.aidl @@ -18,6 +18,7 @@ package android.hardware.security.keymint; /** * Digests provided by keyMint implementations. + * @hide */ @VintfStability @Backing(type="int") diff --git a/security/keymint/aidl/android/hardware/security/keymint/EcCurve.aidl b/security/keymint/aidl/android/hardware/security/keymint/EcCurve.aidl index b9d16467b0..5b1c10c2c5 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/EcCurve.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/EcCurve.aidl @@ -18,6 +18,7 @@ package android.hardware.security.keymint; /** * Supported EC curves, used in ECDSA + * @hide */ @VintfStability @Backing(type="int") diff --git a/security/keymint/aidl/android/hardware/security/keymint/ErrorCode.aidl b/security/keymint/aidl/android/hardware/security/keymint/ErrorCode.aidl index 95b38f2958..0e2c5f29c8 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/ErrorCode.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/ErrorCode.aidl @@ -19,6 +19,7 @@ package android.hardware.security.keymint; /** * KeyMint error codes. Aidl will return these error codes as service specific * errors in EX_SERVICE_SPECIFIC. + * @hide */ @VintfStability @Backing(type="int") diff --git a/security/keymint/aidl/android/hardware/security/keymint/HardwareAuthToken.aidl b/security/keymint/aidl/android/hardware/security/keymint/HardwareAuthToken.aidl index 57150d5da6..0933bd560b 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/HardwareAuthToken.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/HardwareAuthToken.aidl @@ -27,6 +27,7 @@ import android.hardware.security.secureclock.Timestamp; * passed to begin(), update(), and finish() to prove that authentication occurred. See those * methods for more details. It is up to the caller to determine which of the generated auth tokens * is appropriate for a given key operation. + * @hide */ @VintfStability @RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true) diff --git a/security/keymint/aidl/android/hardware/security/keymint/HardwareAuthenticatorType.aidl b/security/keymint/aidl/android/hardware/security/keymint/HardwareAuthenticatorType.aidl index 33f71b8d3c..2d9d0ff86a 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/HardwareAuthenticatorType.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/HardwareAuthenticatorType.aidl @@ -20,6 +20,7 @@ package android.hardware.security.keymint; * Hardware authentication type, used by HardwareAuthTokens to specify the mechanism used to * authentiate the user, and in KeyCharacteristics to specify the allowable mechanisms for * authenticating to activate a key. + * @hide */ @VintfStability @Backing(type="int") diff --git a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl index 384416e692..3100b23f89 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl @@ -211,6 +211,7 @@ import android.hardware.security.secureclock.TimeStampToken; * hardwareEnforced authorization list. Tag::OS_VERSION, Tag::OS_PATCHLEVEL, * Tag::VENDOR_PATCHLEVEL, and Tag::BOOT_PATCHLEVEL must be cryptographically bound to every * IKeyMintDevice key, as described in the Key Access Control section above. + * @hide */ @VintfStability interface IKeyMintDevice { diff --git a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl index 1c2511b34e..5ad54cda19 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl @@ -20,6 +20,7 @@ import android.hardware.security.keymint.HardwareAuthToken; import android.hardware.security.keymint.KeyParameter; import android.hardware.security.secureclock.TimeStampToken; +/** @hide */ @VintfStability interface IKeyMintOperation { /** diff --git a/security/keymint/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl b/security/keymint/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl index 327e4a1e5d..5c8ca6d875 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl @@ -109,6 +109,7 @@ import android.hardware.security.keymint.ProtectedData; * The IRemotelyProvisionedComponent supports a test mode, allowing the generation of test key pairs * and test CertificateRequests. Test keys/requests are annotated as such, and the BCC used for test * CertificateRequests must contain freshly-generated keys, not the real BCC key pairs. + * @hide */ @VintfStability interface IRemotelyProvisionedComponent { diff --git a/security/keymint/aidl/android/hardware/security/keymint/KeyCharacteristics.aidl b/security/keymint/aidl/android/hardware/security/keymint/KeyCharacteristics.aidl index 3a32e4d224..25fdee3d75 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/KeyCharacteristics.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/KeyCharacteristics.aidl @@ -28,6 +28,7 @@ import android.hardware.security.keymint.SecurityLevel; * enforced. Note that enforcement at a given security level means that the semantics of the tag * and value are fully enforced. See the definition of individual tags for specifications of what * must be enforced. + * @hide */ @VintfStability parcelable KeyCharacteristics { diff --git a/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl b/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl index 69bec2d79f..c589ca14d4 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl @@ -22,6 +22,7 @@ import android.hardware.security.keymint.KeyCharacteristics; /** * This structure is returned when a new key is created with generateKey(), importKey() or * importWrappedKey(). + * @hide */ @VintfStability parcelable KeyCreationResult { diff --git a/security/keymint/aidl/android/hardware/security/keymint/KeyFormat.aidl b/security/keymint/aidl/android/hardware/security/keymint/KeyFormat.aidl index 6ad8e3d922..da3d52122c 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/KeyFormat.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/KeyFormat.aidl @@ -18,6 +18,7 @@ package android.hardware.security.keymint; /** * Formats for key import and export. + * @hide */ @VintfStability @Backing(type="int") diff --git a/security/keymint/aidl/android/hardware/security/keymint/KeyMintHardwareInfo.aidl b/security/keymint/aidl/android/hardware/security/keymint/KeyMintHardwareInfo.aidl index ae0d152f16..8da75784de 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/KeyMintHardwareInfo.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/KeyMintHardwareInfo.aidl @@ -20,6 +20,7 @@ import android.hardware.security.keymint.SecurityLevel; /** * KeyMintHardwareInfo is the hardware information returned by calling KeyMint getHardwareInfo() + * @hide */ @VintfStability @RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true) diff --git a/security/keymint/aidl/android/hardware/security/keymint/KeyOrigin.aidl b/security/keymint/aidl/android/hardware/security/keymint/KeyOrigin.aidl index 0cd53c2fbb..f89612593b 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/KeyOrigin.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/KeyOrigin.aidl @@ -21,6 +21,7 @@ package android.hardware.security.keymint; * either the hardware-enforced or software-enforced list for a key, indicating whether the key is * hardware or software-based. Specifically, a key with GENERATED in the hardware-enforced list * must be guaranteed never to have existed outide the secure hardware. + * @hide */ @VintfStability @Backing(type="int") diff --git a/security/keymint/aidl/android/hardware/security/keymint/KeyParameter.aidl b/security/keymint/aidl/android/hardware/security/keymint/KeyParameter.aidl index bf6c9b204d..b69e6787e7 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/KeyParameter.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/KeyParameter.aidl @@ -22,6 +22,7 @@ import android.hardware.security.keymint.Tag; /** * Identifies the key authorization parameters to be used with keyMint. This is usually * provided as an array of KeyParameters to IKeyMintDevice or Operation. + * @hide */ @VintfStability @RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true) diff --git a/security/keymint/aidl/android/hardware/security/keymint/KeyParameterValue.aidl b/security/keymint/aidl/android/hardware/security/keymint/KeyParameterValue.aidl index a4f5154e62..59016f2c3b 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/KeyParameterValue.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/KeyParameterValue.aidl @@ -26,10 +26,10 @@ import android.hardware.security.keymint.KeyPurpose; import android.hardware.security.keymint.PaddingMode; import android.hardware.security.keymint.SecurityLevel; +/** @hide */ @VintfStability @RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true) union KeyParameterValue { - /* Represents an invalid value type. */ int invalid; @@ -45,7 +45,7 @@ union KeyParameterValue { SecurityLevel securityLevel; /* Other types */ - boolean boolValue; // Always true, if present. + boolean boolValue; // Always true, if present. int integer; long longInteger; long dateTime; diff --git a/security/keymint/aidl/android/hardware/security/keymint/KeyPurpose.aidl b/security/keymint/aidl/android/hardware/security/keymint/KeyPurpose.aidl index 978a02723c..c874fc3a07 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/KeyPurpose.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/KeyPurpose.aidl @@ -18,6 +18,7 @@ package android.hardware.security.keymint; /** * Possible purposes of a key (or pair). + * @hide */ @VintfStability @Backing(type="int") diff --git a/security/keymint/aidl/android/hardware/security/keymint/MacedPublicKey.aidl b/security/keymint/aidl/android/hardware/security/keymint/MacedPublicKey.aidl index cb5492dc48..a26094c4b9 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/MacedPublicKey.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/MacedPublicKey.aidl @@ -19,6 +19,7 @@ package android.hardware.security.keymint; /** * MacedPublicKey contains a CBOR-encoded public key, MACed by an IRemotelyProvisionedComponent, to * prove that the key pair was generated by that component. + * @hide */ @VintfStability parcelable MacedPublicKey { diff --git a/security/keymint/aidl/android/hardware/security/keymint/PaddingMode.aidl b/security/keymint/aidl/android/hardware/security/keymint/PaddingMode.aidl index 80b73bd0dc..fbb373b873 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/PaddingMode.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/PaddingMode.aidl @@ -23,6 +23,7 @@ package android.hardware.security.keymint; * padding modes for both symmetric and asymmetric algorithms. Note that implementations should not * provide all possible combinations of algorithm and padding, only the * cryptographically-appropriate pairs. + * @hide */ @VintfStability @Backing(type="int") diff --git a/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl b/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl index 438505ebec..44f316fde7 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl @@ -19,6 +19,7 @@ package android.hardware.security.keymint; /** * ProtectedData contains the encrypted BCC and the ephemeral MAC key used to * authenticate the keysToSign (see keysToSignMac output argument). + * @hide */ @VintfStability parcelable ProtectedData { diff --git a/security/keymint/aidl/android/hardware/security/keymint/SecurityLevel.aidl b/security/keymint/aidl/android/hardware/security/keymint/SecurityLevel.aidl index ecbde8c97c..80c63b2de3 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/SecurityLevel.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/SecurityLevel.aidl @@ -27,6 +27,7 @@ package android.hardware.security.keymint; * certificates. This specifies the security level of the weakest environment involved in * enforcing that particular tag, i.e. the sort of security environment an attacker would have * to subvert in order to break the enforcement of that tag. + * @hide */ @VintfStability @Backing(type="int") diff --git a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl index aa9aa6f1c9..6243bb9b78 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl @@ -25,6 +25,7 @@ import android.hardware.security.keymint.TagType; /** * Tag specifies various kinds of tags that can be set in KeyParameter to identify what kind of * data are stored in KeyParameter. + * @hide */ @VintfStability @Backing(type="int") diff --git a/security/keymint/aidl/android/hardware/security/keymint/TagType.aidl b/security/keymint/aidl/android/hardware/security/keymint/TagType.aidl index a273af3f8c..1ba6ededf2 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/TagType.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/TagType.aidl @@ -18,6 +18,7 @@ package android.hardware.security.keymint; /** * TagType classifies Tags in Tag.aidl into various groups of data. + * @hide */ @VintfStability @Backing(type="int") diff --git a/security/secureclock/aidl/Android.bp b/security/secureclock/aidl/Android.bp index c8e5c025ff..c78be3b20c 100644 --- a/security/secureclock/aidl/Android.bp +++ b/security/secureclock/aidl/Android.bp @@ -16,7 +16,8 @@ aidl_interface { stability: "vintf", backend: { java: { - sdk_version: "module_current", + platform_apis: true, + srcs_available: true, }, ndk: { vndk: { diff --git a/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/current/android/hardware/security/secureclock/ISecureClock.aidl b/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/current/android/hardware/security/secureclock/ISecureClock.aidl index 377889716a..4ecc1e4430 100644 --- a/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/current/android/hardware/security/secureclock/ISecureClock.aidl +++ b/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/current/android/hardware/security/secureclock/ISecureClock.aidl @@ -11,7 +11,8 @@ * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * limitations under the License. - *//////////////////////////////////////////////////////////////////////////////// + */ +/////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// @@ -30,6 +31,7 @@ // later when a module using the interface is updated, e.g., Mainline modules. package android.hardware.security.secureclock; +/* @hide */ @VintfStability interface ISecureClock { android.hardware.security.secureclock.TimeStampToken generateTimeStamp(in long challenge); diff --git a/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/current/android/hardware/security/secureclock/TimeStampToken.aidl b/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/current/android/hardware/security/secureclock/TimeStampToken.aidl index 00a8bb256d..d105ac8f6c 100644 --- a/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/current/android/hardware/security/secureclock/TimeStampToken.aidl +++ b/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/current/android/hardware/security/secureclock/TimeStampToken.aidl @@ -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. // /////////////////////////////////////////////////////////////////////////////// @@ -31,6 +32,7 @@ // later when a module using the interface is updated, e.g., Mainline modules. package android.hardware.security.secureclock; +/* @hide */ @RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability parcelable TimeStampToken { long challenge; diff --git a/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/current/android/hardware/security/secureclock/Timestamp.aidl b/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/current/android/hardware/security/secureclock/Timestamp.aidl index bebeb5cb9c..2e0e389d9e 100644 --- a/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/current/android/hardware/security/secureclock/Timestamp.aidl +++ b/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/current/android/hardware/security/secureclock/Timestamp.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. // /////////////////////////////////////////////////////////////////////////////// @@ -31,6 +32,7 @@ // later when a module using the interface is updated, e.g., Mainline modules. package android.hardware.security.secureclock; +/* @hide */ @RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability parcelable Timestamp { long milliSeconds; diff --git a/security/secureclock/aidl/android/hardware/security/secureclock/ISecureClock.aidl b/security/secureclock/aidl/android/hardware/security/secureclock/ISecureClock.aidl index 577dd8f231..a742ff0dad 100644 --- a/security/secureclock/aidl/android/hardware/security/secureclock/ISecureClock.aidl +++ b/security/secureclock/aidl/android/hardware/security/secureclock/ISecureClock.aidl @@ -25,8 +25,8 @@ import android.hardware.security.secureclock.TimeStampToken; * secret. The shared secret must be available to secure clock service by implementing * ISharedSecret aidl. Note: ISecureClock depends on the shared secret, without which the secure * time stamp token cannot be generated. + * @hide */ - @VintfStability interface ISecureClock { /** diff --git a/security/secureclock/aidl/android/hardware/security/secureclock/TimeStampToken.aidl b/security/secureclock/aidl/android/hardware/security/secureclock/TimeStampToken.aidl index dd957325e9..71b4278d55 100644 --- a/security/secureclock/aidl/android/hardware/security/secureclock/TimeStampToken.aidl +++ b/security/secureclock/aidl/android/hardware/security/secureclock/TimeStampToken.aidl @@ -20,8 +20,8 @@ import android.hardware.security.secureclock.Timestamp; /** * TimeStampToken instances are used for secure environments that requires secure time information. + * @hide */ - @VintfStability @RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true) parcelable TimeStampToken { diff --git a/security/secureclock/aidl/android/hardware/security/secureclock/Timestamp.aidl b/security/secureclock/aidl/android/hardware/security/secureclock/Timestamp.aidl index 27758e1d25..5061aa4a7c 100644 --- a/security/secureclock/aidl/android/hardware/security/secureclock/Timestamp.aidl +++ b/security/secureclock/aidl/android/hardware/security/secureclock/Timestamp.aidl @@ -21,6 +21,7 @@ package android.hardware.security.secureclock; * and a secure environment's notion of "current time" must not repeat until the Android device * reboots, or until at least 50 million years have elapsed (note that this requirement is satisfied * by setting the clock to zero during each boot, and then counting time accurately). + * @hide */ @VintfStability @RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true) diff --git a/security/sharedsecret/aidl/aidl_api/android.hardware.security.sharedsecret/current/android/hardware/security/sharedsecret/ISharedSecret.aidl b/security/sharedsecret/aidl/aidl_api/android.hardware.security.sharedsecret/current/android/hardware/security/sharedsecret/ISharedSecret.aidl index 2509936d99..e76efe7f5d 100644 --- a/security/sharedsecret/aidl/aidl_api/android.hardware.security.sharedsecret/current/android/hardware/security/sharedsecret/ISharedSecret.aidl +++ b/security/sharedsecret/aidl/aidl_api/android.hardware.security.sharedsecret/current/android/hardware/security/sharedsecret/ISharedSecret.aidl @@ -1,3 +1,17 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * limitations under the License. + */ /////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// @@ -17,6 +31,7 @@ // later when a module using the interface is updated, e.g., Mainline modules. package android.hardware.security.sharedsecret; +/* @hide */ @VintfStability interface ISharedSecret { android.hardware.security.sharedsecret.SharedSecretParameters getSharedSecretParameters(); diff --git a/security/sharedsecret/aidl/aidl_api/android.hardware.security.sharedsecret/current/android/hardware/security/sharedsecret/SharedSecretParameters.aidl b/security/sharedsecret/aidl/aidl_api/android.hardware.security.sharedsecret/current/android/hardware/security/sharedsecret/SharedSecretParameters.aidl index 9b65046060..b50ddcdad2 100644 --- a/security/sharedsecret/aidl/aidl_api/android.hardware.security.sharedsecret/current/android/hardware/security/sharedsecret/SharedSecretParameters.aidl +++ b/security/sharedsecret/aidl/aidl_api/android.hardware.security.sharedsecret/current/android/hardware/security/sharedsecret/SharedSecretParameters.aidl @@ -1,3 +1,18 @@ +/* + * 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. // /////////////////////////////////////////////////////////////////////////////// @@ -17,6 +32,7 @@ // later when a module using the interface is updated, e.g., Mainline modules. package android.hardware.security.sharedsecret; +/* @hide */ @VintfStability parcelable SharedSecretParameters { byte[] seed; diff --git a/security/sharedsecret/aidl/android/hardware/security/sharedsecret/ISharedSecret.aidl b/security/sharedsecret/aidl/android/hardware/security/sharedsecret/ISharedSecret.aidl index 906303f15b..4303dc5c6f 100644 --- a/security/sharedsecret/aidl/android/hardware/security/sharedsecret/ISharedSecret.aidl +++ b/security/sharedsecret/aidl/android/hardware/security/sharedsecret/ISharedSecret.aidl @@ -35,8 +35,8 @@ import android.hardware.security.sharedsecret.SharedSecretParameters; * Step 3: The system collects sharing check hash values from each service and evaluates them. If * they are all equal, then the shared secret generation is considered to be successful else it is * considered to have failed. + * @hide */ - @VintfStability interface ISharedSecret { /** diff --git a/security/sharedsecret/aidl/android/hardware/security/sharedsecret/SharedSecretParameters.aidl b/security/sharedsecret/aidl/android/hardware/security/sharedsecret/SharedSecretParameters.aidl index 691b3f1386..a5eec400f2 100644 --- a/security/sharedsecret/aidl/android/hardware/security/sharedsecret/SharedSecretParameters.aidl +++ b/security/sharedsecret/aidl/android/hardware/security/sharedsecret/SharedSecretParameters.aidl @@ -21,8 +21,8 @@ package android.hardware.security.sharedsecret; * HMAC key between multiple keymint services. These parameters are returned in by * getSharedSecretParameters() and send to computeShareSecret(). See the named methods in * ISharedSecret for details of usage. + * @hide */ - @VintfStability parcelable SharedSecretParameters { /** -- GitLab From 723021f42eff0df0f0156094db482743a36c2050 Mon Sep 17 00:00:00 2001 From: Hongbo Zeng Date: Fri, 5 Mar 2021 11:49:58 +0800 Subject: [PATCH 544/790] add capability for TelephonyManager.getNetworkSlicingConfiguration() - add comment to specify HAL interface getSlicingConfig() which is used by TelephonyManager.getNetworkSlicingConfiguration() is in the reduced feature set. - allow REQUEST_NOT_SUPPORTED for HAL interface getSlicingConfig() and update related VTS test case. Bug: 181713905 Test: run "atest VtsHalRadioV1_6TargetTest" and check the result for getSlicingConfig is PASSED [3/17] PerInstance/RadioHidlTest_v1_6#getSlicingConfig/0_slot1: PASSED (9ms) Change-Id: Ia318b8225e8b0e772a85bb9909f2e0114e0ae6e3 --- radio/1.6/IRadioResponse.hal | 1 + radio/1.6/vts/functional/radio_hidl_hal_api.cpp | 8 +++++++- radio/config/1.3/types.hal | 3 +++ .../1.3/vts/functional/radio_config_hidl_hal_utils.h | 4 +++- radio/config/1.3/vts/functional/radio_config_response.cpp | 3 ++- 5 files changed, 16 insertions(+), 3 deletions(-) diff --git a/radio/1.6/IRadioResponse.hal b/radio/1.6/IRadioResponse.hal index 883711c9f1..805586bd37 100644 --- a/radio/1.6/IRadioResponse.hal +++ b/radio/1.6/IRadioResponse.hal @@ -433,6 +433,7 @@ interface IRadioResponse extends @1.5::IRadioResponse { * RadioError:RADIO_NOT_AVAILABLE * RadioError:INTERNAL_ERR * RadioError:MODEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED */ oneway getSlicingConfigResponse(RadioResponseInfo info, SlicingConfig slicingConfig); diff --git a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp index 7fde18ea46..70abc4b432 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp +++ b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp @@ -172,7 +172,13 @@ TEST_P(RadioHidlTest_v1_6, getSlicingConfig) { EXPECT_EQ(std::cv_status::no_timeout, wait()); EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type); EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial); - EXPECT_EQ(::android::hardware::radio::V1_6::RadioError::NONE, radioRsp_v1_6->rspInfo.error); + if (getRadioHalCapabilities().modemReducedFeatureSet1) { + ASSERT_TRUE(CheckAnyOfErrors( + radioRsp_v1_6->rspInfo.error, + {::android::hardware::radio::V1_6::RadioError::REQUEST_NOT_SUPPORTED})); + } else { + EXPECT_EQ(::android::hardware::radio::V1_6::RadioError::NONE, radioRsp_v1_6->rspInfo.error); + } } /* diff --git a/radio/config/1.3/types.hal b/radio/config/1.3/types.hal index 2b6c9f06c7..8667f0ab4f 100644 --- a/radio/config/1.3/types.hal +++ b/radio/config/1.3/types.hal @@ -33,6 +33,9 @@ struct HalDeviceCapabilities { * *

  1. Requesting android.hardware.radio@1.6::IRadio.setDataThrottling() *
  2. + *
  3. Providing android.hardware.radio@1.6::SlicingConfig through + * android.hardware.radio@1.6::getSlicingConfig() + *
  4. * */ bool modemReducedFeatureSet1; diff --git a/radio/config/1.3/vts/functional/radio_config_hidl_hal_utils.h b/radio/config/1.3/vts/functional/radio_config_hidl_hal_utils.h index 895ae08c23..50038eb478 100644 --- a/radio/config/1.3/vts/functional/radio_config_hidl_hal_utils.h +++ b/radio/config/1.3/vts/functional/radio_config_hidl_hal_utils.h @@ -37,7 +37,7 @@ #include "vts_test_util.h" -using namespace ::android::hardware::radio::config::V1_2; +using namespace ::android::hardware::radio::config::V1_3; using ::android::sp; using ::android::hardware::hidl_string; @@ -46,9 +46,11 @@ using ::android::hardware::Return; using ::android::hardware::Void; using ::android::hardware::radio::config::V1_1::ModemsConfig; using ::android::hardware::radio::config::V1_1::PhoneCapability; +using ::android::hardware::radio::config::V1_2::IRadioConfigIndication; using ::android::hardware::radio::config::V1_2::SimSlotStatus; using ::android::hardware::radio::config::V1_3::HalDeviceCapabilities; using ::android::hardware::radio::config::V1_3::IRadioConfig; +using ::android::hardware::radio::config::V1_3::IRadioConfigResponse; using ::android::hardware::radio::V1_0::RadioResponseInfo; #define RADIO_SERVICE_NAME "slot1" diff --git a/radio/config/1.3/vts/functional/radio_config_response.cpp b/radio/config/1.3/vts/functional/radio_config_response.cpp index 11e3cce147..5501ae25e8 100644 --- a/radio/config/1.3/vts/functional/radio_config_response.cpp +++ b/radio/config/1.3/vts/functional/radio_config_response.cpp @@ -64,8 +64,9 @@ Return RadioConfigResponse::setModemsConfigResponse( } Return RadioConfigResponse::getHalDeviceCapabilitiesResponse( - const ::android::hardware::radio::V1_6::RadioResponseInfo& /* info */, + const ::android::hardware::radio::V1_6::RadioResponseInfo& info, const ::android::hardware::radio::config::V1_3::HalDeviceCapabilities& capabilities) { halDeviceCapabilities = capabilities; + parent.notify(info.serial); return Void(); } -- GitLab From 62af06812fe6fac42f59a75eb567b070a57dd8a7 Mon Sep 17 00:00:00 2001 From: Jayant Chowdhary Date: Wed, 18 Nov 2020 18:15:15 -0800 Subject: [PATCH 545/790] camera: Add support for quad bayer sensors. Bug: 152813564 Test: Camera CTS Change-Id: I4aaf7c9f25518e29c4b408bc0b498c618214862e Signed-off-by: Jayant Chowdhary --- camera/device/3.7/Android.bp | 5 + camera/device/3.7/types.hal | 10 ++ camera/metadata/3.6/types.hal | 308 ++++++++++++++++++++++++++++++++++ 3 files changed, 323 insertions(+) diff --git a/camera/device/3.7/Android.bp b/camera/device/3.7/Android.bp index 42782f29a9..2f05af557d 100644 --- a/camera/device/3.7/Android.bp +++ b/camera/device/3.7/Android.bp @@ -15,6 +15,11 @@ hidl_interface { "android.hardware.camera.device@3.4", "android.hardware.camera.device@3.5", "android.hardware.camera.device@3.6", + "android.hardware.camera.metadata@3.2", + "android.hardware.camera.metadata@3.3", + "android.hardware.camera.metadata@3.4", + "android.hardware.camera.metadata@3.5", + "android.hardware.camera.metadata@3.6", "android.hardware.graphics.common@1.0", "android.hidl.base@1.0", ], diff --git a/camera/device/3.7/types.hal b/camera/device/3.7/types.hal index 9450c2f5a7..6910e6574c 100644 --- a/camera/device/3.7/types.hal +++ b/camera/device/3.7/types.hal @@ -21,6 +21,8 @@ import @3.2::StreamConfigurationMode; import @3.4::CaptureRequest; import @3.4::Stream; +import android.hardware.camera.metadata@3.6::CameraMetadataEnumAndroidSensorPixelMode; + /** * Stream: * @@ -57,6 +59,14 @@ struct Stream { * usage flag. */ int32_t groupId; + + /** + * The sensor pixel modes used by this stream. This can assist the camera + * HAL in decision making about stream combination support. + * If this is empty, the HAL must assume that this stream will only be used + * with ANDROID_SENSOR_PIXEL_MODE set to ANDROID_SENSOR_PIXEL_MODE_DEFAULT. + */ + vec sensorPixelModesUsed; }; /** diff --git a/camera/metadata/3.6/types.hal b/camera/metadata/3.6/types.hal index 3472ae9668..709cfb3ec5 100644 --- a/camera/metadata/3.6/types.hal +++ b/camera/metadata/3.6/types.hal @@ -36,6 +36,43 @@ import android.hardware.camera.metadata@3.5; * '/system/media/camera/docs/docs.html' in the corresponding Android source tree.

    */ enum CameraMetadataTag : @3.5::CameraMetadataTag { + /** android.control.availableHighSpeedVideoConfigurationsMaximumResolution [static, int32[], hidden] + * + *
    + * + * @see ANDROID_SENSOR_PIXEL_MODE + */ + ANDROID_CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS_MAXIMUM_RESOLUTION = android.hardware.camera.metadata@3.5::CameraMetadataTag:ANDROID_CONTROL_END_3_5, + + ANDROID_CONTROL_END_3_6, + + /** android.lens.distortionMaximumResolution [static, float[], public] + * + *

    The correction coefficients to correct for this camera device's + * radial and tangential lens distortion for a + * CaptureRequest with ANDROID_SENSOR_PIXEL_MODE set to + * CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION.

    + * + * @see ANDROID_SENSOR_PIXEL_MODE + */ + ANDROID_LENS_DISTORTION_MAXIMUM_RESOLUTION = android.hardware.camera.metadata@3.3::CameraMetadataTag:ANDROID_LENS_END_3_3, + + /** android.lens.intrinsicCalibrationMaximumResolution [static, float[], public] + * + *

    The parameters for this camera device's intrinsic + * calibration when ANDROID_SENSOR_PIXEL_MODE is set to + * CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION.

    + * + * @see ANDROID_SENSOR_PIXEL_MODE + */ + ANDROID_LENS_INTRINSIC_CALIBRATION_MAXIMUM_RESOLUTION, + + ANDROID_LENS_END_3_6, + /** android.scaler.defaultSecureImageSize [static, int32[], public] * *

    Default YUV/PRIVATE size to use for requesting secure image buffers.

    @@ -50,14 +87,237 @@ enum CameraMetadataTag : @3.5::CameraMetadataTag { */ ANDROID_SCALER_PHYSICAL_CAMERA_MULTI_RESOLUTION_STREAM_CONFIGURATIONS, + /** android.scaler.availableStreamConfigurationsMaximumResolution [static, enum[], ndk_public] + * + *

    The available stream configurations that this + * camera device supports (i.e. format, width, height, output/input stream) for a + * CaptureRequest with ANDROID_SENSOR_PIXEL_MODE set to + * CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION.

    + * + * @see ANDROID_SENSOR_PIXEL_MODE + */ + ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION, + + /** android.scaler.availableMinFrameDurationsMaximumResolution [static, int64[], ndk_public] + * + *

    This lists the minimum frame duration for each + * format/size combination when the camera device is sent a CaptureRequest with + * ANDROID_SENSOR_PIXEL_MODE set to + * CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION.

    + * + * @see ANDROID_SENSOR_PIXEL_MODE + */ + ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION, + + /** android.scaler.availableStallDurationsMaximumResolution [static, int64[], ndk_public] + * + *

    This lists the maximum stall duration for each + * output format/size combination when CaptureRequests are submitted with + * ANDROID_SENSOR_PIXEL_MODE set to + * CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION

    + * + * @see ANDROID_SENSOR_PIXEL_MODE + */ + ANDROID_SCALER_AVAILABLE_STALL_DURATIONS_MAXIMUM_RESOLUTION, + + /** android.scaler.availableInputOutputFormatsMapMaximumResolution [static, int32, hidden] + * + *

    The mapping of image formats that are supported by this + * camera device for input streams, to their corresponding output formats, when + * ANDROID_SENSOR_PIXEL_MODE is set to + * CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION.

    + * + * @see ANDROID_SENSOR_PIXEL_MODE + */ + ANDROID_SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP_MAXIMUM_RESOLUTION, + ANDROID_SCALER_END_3_6, + /** android.sensor.opaqueRawSizeMaximumResolution [static, int32[], system] + * + *

    Size in bytes for all the listed opaque RAW buffer sizes when + * ANDROID_SENSOR_PIXEL_MODE is set to + * CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION.

    + * + * @see ANDROID_SENSOR_PIXEL_MODE + */ + ANDROID_SENSOR_OPAQUE_RAW_SIZE_MAXIMUM_RESOLUTION = android.hardware.camera.metadata@3.2::CameraMetadataTag:ANDROID_SENSOR_END, + + /** android.sensor.pixelMode [dynamic, enum, public] + * + *

    Switches sensor pixel mode between maximum resolution mode and default mode.

    + */ + ANDROID_SENSOR_PIXEL_MODE, + + /** android.sensor.rawBinningFactorUsed [dynamic, enum, public] + * + *

    Whether RAW images requested have their bayer pattern as described by + * ANDROID_SENSOR_INFO_BINNING_FACTOR.

    + * + * @see ANDROID_SENSOR_INFO_BINNING_FACTOR + */ + ANDROID_SENSOR_RAW_BINNING_FACTOR_USED, + + ANDROID_SENSOR_END_3_6, + + /** android.sensor.info.activeArraySizeMaximumResolution [static, int32[], public] + * + *

    The area of the image sensor which corresponds to active pixels after any geometric + * distortion correction has been applied, when the sensor runs in maximum resolution mode.

    + */ + ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION = android.hardware.camera.metadata@3.2::CameraMetadataTag:ANDROID_SENSOR_INFO_END, + + /** android.sensor.info.pixelArraySizeMaximumResolution [static, int32[], public] + * + *

    Dimensions of the full pixel array, possibly + * including black calibration pixels, when the sensor runs in maximum resolution mode. + * Analogous to ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE, when ANDROID_SENSOR_PIXEL_MODE is + * set to + * CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION.

    + * + * @see ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE + * @see ANDROID_SENSOR_PIXEL_MODE + */ + ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE_MAXIMUM_RESOLUTION, + + /** android.sensor.info.preCorrectionActiveArraySizeMaximumResolution [static, int32[], public] + * + *

    The area of the image sensor which corresponds to active pixels prior to the + * application of any geometric distortion correction, when the sensor runs in maximum + * resolution mode. This key must be used for crop / metering regions, only when + * ANDROID_SENSOR_PIXEL_MODE is set to + * CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION.

    + * + * @see ANDROID_SENSOR_PIXEL_MODE + */ + ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION, + + /** android.sensor.info.binningFactor [static, int32[], public] + * + *

    Dimensions of the group of pixels which are under the same color filter. + * This specifies the width and height (pair of integers) of the group of pixels which fall + * under the same color filter for ULTRA_HIGH_RESOLUTION sensors.

    + */ + ANDROID_SENSOR_INFO_BINNING_FACTOR, + + ANDROID_SENSOR_INFO_END_3_6, + + /** android.depth.availableDepthStreamConfigurationsMaximumResolution [static, enum[], ndk_public] + * + *

    The available depth dataspace stream + * configurations that this camera device supports + * (i.e. format, width, height, output/input stream) when a CaptureRequest is submitted with + * ANDROID_SENSOR_PIXEL_MODE set to + * CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION.

    + * + * @see ANDROID_SENSOR_PIXEL_MODE + */ + ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION = android.hardware.camera.metadata@3.4::CameraMetadataTag:ANDROID_DEPTH_END_3_4, + + /** android.depth.availableDepthMinFrameDurationsMaximumResolution [static, int64[], ndk_public] + * + *

    This lists the minimum frame duration for each + * format/size combination for depth output formats when a CaptureRequest is submitted with + * ANDROID_SENSOR_PIXEL_MODE set to + * CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION.

    + * + * @see ANDROID_SENSOR_PIXEL_MODE + */ + ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION, + + /** android.depth.availableDepthStallDurationsMaximumResolution [static, int64[], ndk_public] + * + *

    This lists the maximum stall duration for each + * output format/size combination for depth streams for CaptureRequests where + * ANDROID_SENSOR_PIXEL_MODE is set to + * CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION.

    + * + * @see ANDROID_SENSOR_PIXEL_MODE + */ + ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS_MAXIMUM_RESOLUTION, + + /** android.depth.availableDynamicDepthStreamConfigurationsMaximumResolution [static, enum[], ndk_public] + * + *

    The available dynamic depth dataspace stream + * configurations that this camera device supports (i.e. format, width, height, + * output/input stream) for CaptureRequests where ANDROID_SENSOR_PIXEL_MODE is set to + * CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION.

    + * + * @see ANDROID_SENSOR_PIXEL_MODE + */ + ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION, + + /** android.depth.availableDynamicDepthMinFrameDurationsMaximumResolution [static, int64[], ndk_public] + * + *

    This lists the minimum frame duration for each + * format/size combination for dynamic depth output streams for CaptureRequests where + * ANDROID_SENSOR_PIXEL_MODE is set to + * CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION.

    + * + * @see ANDROID_SENSOR_PIXEL_MODE + */ + ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION, + + /** android.depth.availableDynamicDepthStallDurationsMaximumResolution [static, int64[], ndk_public] + * + *

    This lists the maximum stall duration for each + * output format/size combination for dynamic depth streams for CaptureRequests where + * ANDROID_SENSOR_PIXEL_MODE is set to + * CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION.

    + * + * @see ANDROID_SENSOR_PIXEL_MODE + */ + ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS_MAXIMUM_RESOLUTION, + + ANDROID_DEPTH_END_3_6, + + /** android.heic.availableHeicStreamConfigurationsMaximumResolution [static, enum[], ndk_public] + * + *

    The available HEIC (ISO/IEC 23008-12) stream + * configurations that this camera device supports + * (i.e. format, width, height, output/input stream).

    + */ + ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION = android.hardware.camera.metadata@3.4::CameraMetadataTag:ANDROID_HEIC_END_3_4, + + /** android.heic.availableHeicMinFrameDurationsMaximumResolution [static, int64[], ndk_public] + * + *

    This lists the minimum frame duration for each + * format/size combination for HEIC output formats for CaptureRequests where + * ANDROID_SENSOR_PIXEL_MODE is set to + * CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION.

    + * + * @see ANDROID_SENSOR_PIXEL_MODE + */ + ANDROID_HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION, + + /** android.heic.availableHeicStallDurationsMaximumResolution [static, int64[], ndk_public] + * + *

    This lists the maximum stall duration for each + * output format/size combination for HEIC streams for CaptureRequests where + * ANDROID_SENSOR_PIXEL_MODE is set to + * CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION.

    + * + * @see ANDROID_SENSOR_PIXEL_MODE + */ + ANDROID_HEIC_AVAILABLE_HEIC_STALL_DURATIONS_MAXIMUM_RESOLUTION, + + ANDROID_HEIC_END_3_6, + }; /* * Enumeration definitions for the various entries that need them */ +/** android.request.availableCapabilities enumeration values added since v3.5 + * @see ANDROID_REQUEST_AVAILABLE_CAPABILITIES + */ +enum CameraMetadataEnumAndroidRequestAvailableCapabilities : + @3.5::CameraMetadataEnumAndroidRequestAvailableCapabilities { + ANDROID_REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR, + ANDROID_REQUEST_AVAILABLE_CAPABILITIES_REMOSAIC_REPROCESSING, +}; + /** android.scaler.physicalCameraMultiResolutionStreamConfigurations enumeration values * @see ANDROID_SCALER_PHYSICAL_CAMERA_MULTI_RESOLUTION_STREAM_CONFIGURATIONS */ @@ -65,3 +325,51 @@ enum CameraMetadataEnumAndroidScalerPhysicalCameraMultiResolutionStreamConfigura ANDROID_SCALER_PHYSICAL_CAMERA_MULTI_RESOLUTION_STREAM_CONFIGURATIONS_OUTPUT, ANDROID_SCALER_PHYSICAL_CAMERA_MULTI_RESOLUTION_STREAM_CONFIGURATIONS_INPUT, }; + +/** android.scaler.availableStreamConfigurationsMaximumResolution enumeration values + * @see ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION + */ +enum CameraMetadataEnumAndroidScalerAvailableStreamConfigurationsMaximumResolution : uint32_t { + ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_OUTPUT, + ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT, +}; + +/** android.sensor.pixelMode enumeration values + * @see ANDROID_SENSOR_PIXEL_MODE + */ +enum CameraMetadataEnumAndroidSensorPixelMode : uint32_t { + ANDROID_SENSOR_PIXEL_MODE_DEFAULT, + ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION, +}; + +/** android.sensor.rawBinningFactorUsed enumeration values + * @see ANDROID_SENSOR_RAW_BINNING_FACTOR_USED + */ +enum CameraMetadataEnumAndroidSensorRawBinningFactorUsed : uint32_t { + ANDROID_SENSOR_RAW_BINNING_FACTOR_USED_TRUE, + ANDROID_SENSOR_RAW_BINNING_FACTOR_USED_FALSE, +}; + +/** android.depth.availableDepthStreamConfigurationsMaximumResolution enumeration values + * @see ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION + */ +enum CameraMetadataEnumAndroidDepthAvailableDepthStreamConfigurationsMaximumResolution : uint32_t { + ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_OUTPUT, + ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT, +}; + +/** android.depth.availableDynamicDepthStreamConfigurationsMaximumResolution enumeration values + * @see ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION + */ +enum CameraMetadataEnumAndroidDepthAvailableDynamicDepthStreamConfigurationsMaximumResolution : uint32_t { + ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_OUTPUT, + ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT, +}; + +/** android.heic.availableHeicStreamConfigurationsMaximumResolution enumeration values + * @see ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION + */ +enum CameraMetadataEnumAndroidHeicAvailableHeicStreamConfigurationsMaximumResolution : uint32_t { + ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_OUTPUT, + ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT, +}; -- GitLab From cbbfa93a17647f59a5a8c84243f86d4cab4623b7 Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Mon, 22 Mar 2021 13:25:15 -0700 Subject: [PATCH 546/790] Add ISessionCallback#onSessionClosed Bug: 181984005 Test: m android.hardware.biometrics.fingerprint-update-api Test: m android.hardware.biometrics.face-update-api Test: atest VtsHalBiometricsFingerprintTargetTest Change-Id: I766c3ae0dc9916c376da6432a5545af581dda819 --- .../android/hardware/biometrics/face/ISessionCallback.aidl | 1 + .../android/hardware/biometrics/face/ISessionCallback.aidl | 6 ++++++ biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp | 2 ++ .../hardware/biometrics/fingerprint/ISessionCallback.aidl | 1 + .../hardware/biometrics/fingerprint/ISessionCallback.aidl | 6 ++++++ biometrics/fingerprint/aidl/default/Session.cpp | 4 ++-- .../aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp | 2 ++ 7 files changed, 20 insertions(+), 2 deletions(-) diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl index d6ebbb6208..b0bfa3084e 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl @@ -53,4 +53,5 @@ interface ISessionCallback { void onEnrollmentsRemoved(in int[] enrollmentIds); void onAuthenticatorIdRetrieved(in long authenticatorId); void onAuthenticatorIdInvalidated(in long newAuthenticatorId); + void onSessionClosed(); } diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl index 2e3cd950f6..c1aa3fcf80 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl @@ -227,4 +227,10 @@ interface ISessionCallback { * current set of enrollments. */ void onAuthenticatorIdInvalidated(in long newAuthenticatorId); + + /** + * This method notifes the client that this session has closed. + * The client must not make any more calls to this session. + */ + void onSessionClosed(); } diff --git a/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp b/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp index 4cc8b4afa0..936fcc69e5 100644 --- a/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp +++ b/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp @@ -120,6 +120,8 @@ class SessionCallback : public BnSessionCallback { return ndk::ScopedAStatus::ok(); } + ndk::ScopedAStatus onSessionClosed() override { return ndk::ScopedAStatus::ok(); } + private: std::promise invocation_promise_; }; diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl index 13c2b05081..3a977178ff 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl @@ -50,4 +50,5 @@ interface ISessionCallback { void onEnrollmentsRemoved(in int[] enrollmentIds); void onAuthenticatorIdRetrieved(in long authenticatorId); void onAuthenticatorIdInvalidated(in long newAuthenticatorId); + void onSessionClosed(); } diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl index fde1df753d..cf3a271ef6 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl @@ -200,4 +200,10 @@ interface ISessionCallback { * current set of enrollments. */ void onAuthenticatorIdInvalidated(in long newAuthenticatorId); + + /** + * This method notifes the client that this session has closed. + * The client must not make any more calls to this session. + */ + void onSessionClosed(); } diff --git a/biometrics/fingerprint/aidl/default/Session.cpp b/biometrics/fingerprint/aidl/default/Session.cpp index c035407c7e..f030f138f5 100644 --- a/biometrics/fingerprint/aidl/default/Session.cpp +++ b/biometrics/fingerprint/aidl/default/Session.cpp @@ -219,11 +219,11 @@ ndk::ScopedAStatus Session::resetLockout(int32_t cookie, const keymaster::Hardwa return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::close(int32_t cookie) { +ndk::ScopedAStatus Session::close(int32_t /*cookie*/) { LOG(INFO) << "close"; CHECK(mCurrentState == SessionState::IDLING) << "Can't close a non-idling session. Crashing."; mCurrentState = SessionState::CLOSED; - mCb->onStateChanged(cookie, mCurrentState); + mCb->onSessionClosed(); return ndk::ScopedAStatus::ok(); } diff --git a/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp b/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp index 894fdfe362..885f703d5b 100644 --- a/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp +++ b/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp @@ -119,6 +119,8 @@ class SessionCallback : public BnSessionCallback { return ndk::ScopedAStatus::ok(); } + ndk::ScopedAStatus onSessionClosed() override { return ndk::ScopedAStatus::ok(); } + private: bool mIsPromiseValid; std::vector mInvocations; -- GitLab From 1d998ec20e7d0d6e0f5e772c7ad6b9c6cee7f393 Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Mon, 22 Mar 2021 22:05:27 +0000 Subject: [PATCH 547/790] Fix flaky WorkerThreadTest Bug: 183250492 Test: atest --host android.hardware.biometrics.fingerprint.WorkerThreadTest Change-Id: Ic51681103989d13d5c968d9b7ce1ebf9a306edee --- .../aidl/default/tests/WorkerThreadTest.cpp | 73 ++++++++++++++----- 1 file changed, 53 insertions(+), 20 deletions(-) diff --git a/biometrics/fingerprint/aidl/default/tests/WorkerThreadTest.cpp b/biometrics/fingerprint/aidl/default/tests/WorkerThreadTest.cpp index 0d5014bb84..c548fe5bfb 100644 --- a/biometrics/fingerprint/aidl/default/tests/WorkerThreadTest.cpp +++ b/biometrics/fingerprint/aidl/default/tests/WorkerThreadTest.cpp @@ -32,23 +32,41 @@ using namespace std::chrono_literals; TEST(WorkerThreadTest, ScheduleReturnsTrueWhenQueueHasSpace) { WorkerThread worker(1 /*maxQueueSize*/); for (int i = 0; i < 100; ++i) { - EXPECT_TRUE(worker.schedule(Callable::from([] {}))); - // Allow enough time for the previous task to be processed. - std::this_thread::sleep_for(2ms); + std::promise promise; + auto future = promise.get_future(); + + ASSERT_TRUE(worker.schedule(Callable::from([promise = std::move(promise)]() mutable { + // Notify that the task has started. + promise.set_value(); + }))); + + auto status = future.wait_for(1s); + EXPECT_EQ(status, std::future_status::ready); } } TEST(WorkerThreadTest, ScheduleReturnsFalseWhenQueueIsFull) { WorkerThread worker(2 /*maxQueueSize*/); - // Add a long-running task. - worker.schedule(Callable::from([] { std::this_thread::sleep_for(1s); })); - // Allow enough time for the worker to start working on the previous task. - std::this_thread::sleep_for(2ms); + std::promise promise; + auto future = promise.get_future(); + + // Schedule a long-running task. + ASSERT_TRUE(worker.schedule(Callable::from([promise = std::move(promise)]() mutable { + // Notify that the task has started. + promise.set_value(); + // Block for a "very long" time. + std::this_thread::sleep_for(2s); + }))); + + // Make sure the long-running task began executing. + auto status = future.wait_for(1s); + ASSERT_EQ(status, std::future_status::ready); + // The first task is already being worked on, which means the queue must be empty. // Fill the worker's queue to the maximum. - worker.schedule(Callable::from([] {})); - worker.schedule(Callable::from([] {})); + ASSERT_TRUE(worker.schedule(Callable::from([] {}))); + ASSERT_TRUE(worker.schedule(Callable::from([] {}))); EXPECT_FALSE(worker.schedule(Callable::from([] {}))); } @@ -71,7 +89,8 @@ TEST(WorkerThreadTest, TasksExecuteInOrder) { auto future = promise.get_future(); // Schedule a special task to signal when all of the tasks are finished. - worker.schedule(Callable::from([&promise] { promise.set_value(); })); + worker.schedule( + Callable::from([promise = std::move(promise)]() mutable { promise.set_value(); })); auto status = future.wait_for(1s); ASSERT_EQ(status, std::future_status::ready); @@ -84,23 +103,37 @@ TEST(WorkerThreadTest, ExecutionStopsAfterWorkerIsDestroyed) { std::promise promise2; auto future1 = promise1.get_future(); auto future2 = promise2.get_future(); + std::atomic value; + // Local scope for the worker to test its destructor when it goes out of scope. { WorkerThread worker(2 /*maxQueueSize*/); - worker.schedule(Callable::from([&promise1] { - promise1.set_value(); - std::this_thread::sleep_for(200ms); - })); - worker.schedule(Callable::from([&promise2] { promise2.set_value(); })); - // Make sure the first task is executing. - auto status1 = future1.wait_for(1s); - ASSERT_EQ(status1, std::future_status::ready); + ASSERT_TRUE(worker.schedule(Callable::from([promise = std::move(promise1)]() mutable { + promise.set_value(); + std::this_thread::sleep_for(200ms); + }))); + + // The first task should start executing. + auto status = future1.wait_for(1s); + ASSERT_EQ(status, std::future_status::ready); + + // The second task should schedule successfully. + ASSERT_TRUE( + worker.schedule(Callable::from([promise = std::move(promise2), &value]() mutable { + // The worker should destruct before it gets a chance to execute this. + value = true; + promise.set_value(); + }))); } // The second task should never execute. - auto status2 = future2.wait_for(1s); - EXPECT_EQ(status2, std::future_status::timeout); + auto status = future2.wait_for(1s); + ASSERT_EQ(status, std::future_status::ready); + // The future is expected to be ready but contain an exception. + // Cannot use ASSERT_THROW because exceptions are disabled in this codebase. + // ASSERT_THROW(future2.get(), std::future_error); + EXPECT_FALSE(value); } } // namespace -- GitLab From aede9615c72bde0e019549d2c5960f04f97f6e6b Mon Sep 17 00:00:00 2001 From: Sungtak Lee Date: Thu, 25 Feb 2021 02:18:19 -0800 Subject: [PATCH 548/790] Add media.c2@1.2 Add setOutputSurfaceWithSyncObj() to IComponent. Test: make vts -j123 && vts-tradefed run commandAndExit vts \ -m VtsHAlMediaC2V1_0Host Bug: 157111613 Change-Id: I5a52b3d9448ea88681eb9b1b409f89723f732e9b --- .../compatibility_matrix.current.xml | 2 +- media/c2/1.2/Android.bp | 31 +++++++++ media/c2/1.2/IComponent.hal | 61 ++++++++++++++++++ media/c2/1.2/IComponentStore.hal | 64 +++++++++++++++++++ media/c2/1.2/types.hal | 52 +++++++++++++++ 5 files changed, 209 insertions(+), 1 deletion(-) create mode 100644 media/c2/1.2/Android.bp create mode 100644 media/c2/1.2/IComponent.hal create mode 100644 media/c2/1.2/IComponentStore.hal create mode 100644 media/c2/1.2/types.hal diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index 9e99c48f7c..c656af2b21 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -359,7 +359,7 @@ android.hardware.media.c2 - 1.0-1 + 1.0-2 IComponentStore default[0-9]* diff --git a/media/c2/1.2/Android.bp b/media/c2/1.2/Android.bp new file mode 100644 index 0000000000..10947219fb --- /dev/null +++ b/media/c2/1.2/Android.bp @@ -0,0 +1,31 @@ +// This file is autogenerated by hidl-gen -Landroidbp. + +hidl_interface { + name: "android.hardware.media.c2@1.2", + root: "android.hardware", + srcs: [ + "types.hal", + "IComponent.hal", + "IComponentStore.hal", + ], + interfaces: [ + "android.hardware.graphics.bufferqueue@1.0", + "android.hardware.graphics.bufferqueue@2.0", + "android.hardware.graphics.common@1.0", + "android.hardware.graphics.common@1.1", + "android.hardware.graphics.common@1.2", + "android.hardware.media.bufferpool@2.0", + "android.hardware.media.c2@1.0", + "android.hardware.media.c2@1.1", + "android.hardware.media.omx@1.0", + "android.hardware.media@1.0", + "android.hidl.base@1.0", + "android.hidl.safe_union@1.0", + ], + gen_java: false, + apex_available: [ + "//apex_available:platform", + "com.android.media.swcodec", + "test_com.android.media.swcodec", + ], +} diff --git a/media/c2/1.2/IComponent.hal b/media/c2/1.2/IComponent.hal new file mode 100644 index 0000000000..088d810492 --- /dev/null +++ b/media/c2/1.2/IComponent.hal @@ -0,0 +1,61 @@ +/* + * 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.media.c2@1.2; + +import android.hardware.graphics.bufferqueue@2.0::IGraphicBufferProducer; +import android.hardware.media.c2@1.1::IComponent; +import android.hardware.media.c2@1.0::Status; + + +/** + * Interface for a Codec2 component corresponding to API level 1.2 or below. + * Components have two states: stopped and running. The running state has three + * sub-states: executing, tripped and error. + * + * All methods in `IComponent` must not block. If a method call cannot be + * completed in a timely manner, it must return `TIMED_OUT` in the return + * status. + * + * @note This is an extension of version 1.1 of `IComponent`. The purpose of the + * extension is to add blocking allocation of output buffer from surface. + */ +interface IComponent extends @1.1::IComponent { + /** + * Starts using a surface for output with a synchronization object + * + * This method must not block. + * + * @param blockPoolId Id of the `C2BlockPool` to be associated with the + * output surface. + * @param surface Output surface. + * @param syncObject synchronization object for buffer allocation between + * Framework and Component. + * @return status Status of the call, which may be + * - `OK` - The operation completed successfully. + * - `CANNOT_DO` - The component does not support an output surface. + * - `REFUSED` - The output surface cannot be accessed. + * - `TIMED_OUT` - The operation cannot be finished in a timely manner. + * - `CORRUPTED` - Some unknown error occurred. + */ + setOutputSurfaceWithSyncObj( + uint64_t blockPoolId, + @2.0::IGraphicBufferProducer surface, + SurfaceSyncObj syncObject + ) generates ( + Status status + ); +}; diff --git a/media/c2/1.2/IComponentStore.hal b/media/c2/1.2/IComponentStore.hal new file mode 100644 index 0000000000..c38fc7a499 --- /dev/null +++ b/media/c2/1.2/IComponentStore.hal @@ -0,0 +1,64 @@ +/* + * 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.media.c2@1.2; + +import android.hardware.media.bufferpool@2.0::IClientManager; +import android.hardware.media.c2@1.0::IComponentListener; +import android.hardware.media.c2@1.1::IComponentStore; +import android.hardware.media.c2@1.0::Status; + +import IComponent; + +/** + * Entry point for Codec2 HAL. + * + * All methods in `IComponentStore` must not block. If a method call cannot be + * completed in a timely manner, it must return `TIMED_OUT` in the return + * status. The only exceptions are getPoolClientManager() and getConfigurable(), + * which must always return immediately. + * + * @note This is an extension of version 1.1 of `IComponentStore`. The purpose + * of the extension is to add support for blocking output buffer allocator. + */ +interface IComponentStore extends @1.1::IComponentStore { + /** + * Creates a component by name. + * + * @param name Name of the component to create. This must match one of the + * names returned by listComponents(). + * @param listener Callback receiver. + * @param pool `IClientManager` object of the BufferPool in the client + * process. This may be null if the client does not own a BufferPool. + * @return status Status of the call, which may be + * - `OK` - The component was created successfully. + * - `NOT_FOUND` - There is no component with the given name. + * - `NO_MEMORY` - Not enough memory to create the component. + * - `TIMED_OUT` - The operation cannot be finished in a timely manner. + * - `CORRUPTED` - Some unknown error occurred. + * @return comp The created component if @p status is `OK`. + * + * @sa IComponentListener. + */ + createComponent_1_2( + string name, + IComponentListener listener, + IClientManager pool + ) generates ( + Status status, + IComponent comp + ); +}; diff --git a/media/c2/1.2/types.hal b/media/c2/1.2/types.hal new file mode 100644 index 0000000000..096edbdf8c --- /dev/null +++ b/media/c2/1.2/types.hal @@ -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.media.c2@1.2; + +/** + * Surface(BufferQueue/IGBP) synchronization object regarding # of dequeued + * output buffers. This keeps # of dequeued buffers from Surface less than + * configured max # of dequeued buffers all the time. + */ +struct SurfaceSyncObj { + /** + * ASharedMemory for synchronization data. Layout is below + * + * |lock(futex) 4bytes| + * |conditional_variable(futex) 4bytes| + * |# of max dequeable buffer 4bytes| + * |# of dequeued buffer 4bytes| + * |Status of the surface 4bytes| + * INIT = 0, Configuring surface is not finished. + * ACTIVE = 1, Surface is ready to allocate(dequeue). + * SWITCHING = 2, Switching to the new surface. It is blocked + * to allocate(dequeue) a buffer until switching + * completes. + */ + handle syncMemory; + + // Read-only. + // The values which are tied and not changed with respect to Surface + // which is currently set up. + /** BufferQueue id. */ + uint64_t bqId; + /** Generation id. */ + uint32_t generationId; + /** Consumer usage flags. See +ndk + * libnativewindow#AHardwareBuffer_UsageFlags for possible values. + */ + uint64_t consumerUsage; +}; -- GitLab From 83f7907233ed1334c15bee7aa9d795c4d8403188 Mon Sep 17 00:00:00 2001 From: Sunil Ravi Date: Thu, 18 Mar 2021 20:04:46 -0700 Subject: [PATCH 549/790] Wifi: Add Radio ID in radiostats Get the radio id from link layer radio stats to framework. Bug: 163103321 Test: VTS test - VtsHalWifiV1_5TargetTest Change-Id: I6958a5b78798edf8529032cd255c61ba6a442633 --- wifi/1.5/default/hidl_struct_util.cpp | 30 ++++++------ .../tests/hidl_struct_util_unit_tests.cpp | 48 +++++++++++-------- wifi/1.5/types.hal | 15 ++++++ 3 files changed, 58 insertions(+), 35 deletions(-) diff --git a/wifi/1.5/default/hidl_struct_util.cpp b/wifi/1.5/default/hidl_struct_util.cpp index 125a50fcca..338a8f13c1 100644 --- a/wifi/1.5/default/hidl_struct_util.cpp +++ b/wifi/1.5/default/hidl_struct_util.cpp @@ -954,27 +954,29 @@ bool convertLegacyVectorOfDebugRxPacketFateToHidl( bool convertLegacyLinkLayerRadioStatsToHidl( const legacy_hal::LinkLayerRadioStats& legacy_radio_stat, - V1_3::StaLinkLayerRadioStats* hidl_radio_stat) { + V1_5::StaLinkLayerRadioStats* hidl_radio_stat) { if (!hidl_radio_stat) { return false; } *hidl_radio_stat = {}; - hidl_radio_stat->V1_0.onTimeInMs = legacy_radio_stat.stats.on_time; - hidl_radio_stat->V1_0.txTimeInMs = legacy_radio_stat.stats.tx_time; - hidl_radio_stat->V1_0.rxTimeInMs = legacy_radio_stat.stats.rx_time; - hidl_radio_stat->V1_0.onTimeInMsForScan = + hidl_radio_stat->radioId = legacy_radio_stat.stats.radio; + 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_0.txTimeInMsPerLevel = + hidl_radio_stat->V1_3.V1_0.txTimeInMsPerLevel = legacy_radio_stat.tx_time_per_levels; - hidl_radio_stat->onTimeInMsForNanScan = legacy_radio_stat.stats.on_time_nbd; - hidl_radio_stat->onTimeInMsForBgScan = + 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->onTimeInMsForRoamScan = + hidl_radio_stat->V1_3.onTimeInMsForRoamScan = legacy_radio_stat.stats.on_time_roam_scan; - hidl_radio_stat->onTimeInMsForPnoScan = + hidl_radio_stat->V1_3.onTimeInMsForPnoScan = legacy_radio_stat.stats.on_time_pno_scan; - hidl_radio_stat->onTimeInMsForHs20Scan = + hidl_radio_stat->V1_3.onTimeInMsForHs20Scan = legacy_radio_stat.stats.on_time_hs20; std::vector hidl_channel_stats; @@ -996,7 +998,7 @@ bool convertLegacyLinkLayerRadioStatsToHidl( hidl_channel_stats.push_back(hidl_channel_stat); } - hidl_radio_stat->channelStats = hidl_channel_stats; + hidl_radio_stat->V1_3.channelStats = hidl_channel_stats; return true; } @@ -1089,9 +1091,9 @@ bool convertLegacyLinkLayerStatsToHidl( } hidl_stats->iface.peers = hidl_peers_info_stats; // radio legacy_stats conversion. - std::vector hidl_radios_stats; + std::vector hidl_radios_stats; for (const auto& legacy_radio_stats : legacy_stats.radios) { - V1_3::StaLinkLayerRadioStats hidl_radio_stats; + V1_5::StaLinkLayerRadioStats hidl_radio_stats; if (!convertLegacyLinkLayerRadioStatsToHidl(legacy_radio_stats, &hidl_radio_stats)) { return false; diff --git a/wifi/1.5/default/tests/hidl_struct_util_unit_tests.cpp b/wifi/1.5/default/tests/hidl_struct_util_unit_tests.cpp index e70d7baa8a..4b4ebd6138 100644 --- a/wifi/1.5/default/tests/hidl_struct_util_unit_tests.cpp +++ b/wifi/1.5/default/tests/hidl_struct_util_unit_tests.cpp @@ -180,6 +180,7 @@ TEST_F(HidlStructUtilTest, canConvertLegacyLinkLayerStatsToHidl) { legacy_stats.iface.num_peers = 1; for (auto& radio : legacy_stats.radios) { + radio.stats.radio = rand(); radio.stats.on_time = rand(); radio.stats.tx_time = rand(); radio.stats.rx_time = rand(); @@ -314,48 +315,53 @@ TEST_F(HidlStructUtilTest, canConvertLegacyLinkLayerStatsToHidl) { 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_0.onTimeInMs); + converted.radios[i].V1_3.V1_0.onTimeInMs); EXPECT_EQ(legacy_stats.radios[i].stats.tx_time, - converted.radios[i].V1_0.txTimeInMs); + converted.radios[i].V1_3.V1_0.txTimeInMs); EXPECT_EQ(legacy_stats.radios[i].stats.rx_time, - converted.radios[i].V1_0.rxTimeInMs); + converted.radios[i].V1_3.V1_0.rxTimeInMs); EXPECT_EQ(legacy_stats.radios[i].stats.on_time_scan, - converted.radios[i].V1_0.onTimeInMsForScan); + converted.radios[i].V1_3.V1_0.onTimeInMsForScan); EXPECT_EQ(legacy_stats.radios[i].tx_time_per_levels.size(), - converted.radios[i].V1_0.txTimeInMsPerLevel.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++) { EXPECT_EQ(legacy_stats.radios[i].tx_time_per_levels[j], - converted.radios[i].V1_0.txTimeInMsPerLevel[j]); + converted.radios[i].V1_3.V1_0.txTimeInMsPerLevel[j]); } EXPECT_EQ(legacy_stats.radios[i].stats.on_time_nbd, - converted.radios[i].onTimeInMsForNanScan); + converted.radios[i].V1_3.onTimeInMsForNanScan); EXPECT_EQ(legacy_stats.radios[i].stats.on_time_gscan, - converted.radios[i].onTimeInMsForBgScan); + converted.radios[i].V1_3.onTimeInMsForBgScan); EXPECT_EQ(legacy_stats.radios[i].stats.on_time_roam_scan, - converted.radios[i].onTimeInMsForRoamScan); + converted.radios[i].V1_3.onTimeInMsForRoamScan); EXPECT_EQ(legacy_stats.radios[i].stats.on_time_pno_scan, - converted.radios[i].onTimeInMsForPnoScan); + converted.radios[i].V1_3.onTimeInMsForPnoScan); EXPECT_EQ(legacy_stats.radios[i].stats.on_time_hs20, - converted.radios[i].onTimeInMsForHs20Scan); + converted.radios[i].V1_3.onTimeInMsForHs20Scan); EXPECT_EQ(legacy_stats.radios[i].channel_stats.size(), - converted.radios[i].channelStats.size()); + converted.radios[i].V1_3.channelStats.size()); 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].channelStats[k].channel.width); - EXPECT_EQ(WifiChannelInMhz(legacy_channel_st.channel.center_freq), - converted.radios[i].channelStats[k].channel.centerFreq); - EXPECT_EQ(WifiChannelInMhz(legacy_channel_st.channel.center_freq0), - converted.radios[i].channelStats[k].channel.centerFreq0); - EXPECT_EQ(WifiChannelInMhz(legacy_channel_st.channel.center_freq1), - converted.radios[i].channelStats[k].channel.centerFreq1); + 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(legacy_channel_st.cca_busy_time, - converted.radios[i].channelStats[k].ccaBusyTimeInMs); + converted.radios[i].V1_3.channelStats[k].ccaBusyTimeInMs); EXPECT_EQ(legacy_channel_st.on_time, - converted.radios[i].channelStats[k].onTimeInMs); + converted.radios[i].V1_3.channelStats[k].onTimeInMs); } } diff --git a/wifi/1.5/types.hal b/wifi/1.5/types.hal index 0543004f52..3c197916eb 100644 --- a/wifi/1.5/types.hal +++ b/wifi/1.5/types.hal @@ -253,6 +253,21 @@ struct StaLinkLayerIfaceStats { vec peers; }; +struct StaLinkLayerRadioStats { + /** + * Baseline information as defined in HAL 1.3. + */ + @1.3::StaLinkLayerRadioStats V1_3; + + /** + * Radio ID: An implementation specific value identifying the radio interface for which the + * stats are produced. Framework must not interpret this value. It must use this value for + * persistently identifying the statistics between calls, + * e.g. if the HAL provides them in different order. + */ + int32_t radioId; +}; + /** * Link layer stats retrieved via |getLinkLayerStats|. */ -- GitLab From f001b128549629582efac9c3a078020616997160 Mon Sep 17 00:00:00 2001 From: bohu Date: Tue, 23 Mar 2021 14:12:45 -0700 Subject: [PATCH 550/790] gnss: allows custom gnss device name This is a temporary workaround the missing kernel support of reclaiming virtio-console as gnss0 device. When kernel can support converting virtio-console to gnss0 device, this cl can be reverted Bug: 180435101 Change-Id: I6e48b6c446dd945f066fbd8f5471b77226eba68b --- gnss/2.1/default/Android.bp | 1 + gnss/aidl/default/Android.bp | 1 + gnss/common/utils/default/Android.bp | 1 + .../utils/default/include/v2_1/GnssTemplate.h | 14 ++++++++++++-- 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/gnss/2.1/default/Android.bp b/gnss/2.1/default/Android.bp index 9a44eb5607..609f59e60f 100644 --- a/gnss/2.1/default/Android.bp +++ b/gnss/2.1/default/Android.bp @@ -33,6 +33,7 @@ cc_binary { "service.cpp", ], shared_libs: [ + "libcutils", "libhidlbase", "libutils", "liblog", diff --git a/gnss/aidl/default/Android.bp b/gnss/aidl/default/Android.bp index d363a9f832..4cc2b6e251 100644 --- a/gnss/aidl/default/Android.bp +++ b/gnss/aidl/default/Android.bp @@ -40,6 +40,7 @@ cc_binary { ], shared_libs: [ "libbase", + "libcutils", "libbinder_ndk", "libhidlbase", "libutils", diff --git a/gnss/common/utils/default/Android.bp b/gnss/common/utils/default/Android.bp index a330c5a3b0..43db8739d1 100644 --- a/gnss/common/utils/default/Android.bp +++ b/gnss/common/utils/default/Android.bp @@ -44,6 +44,7 @@ cc_library_static { ], export_include_dirs: ["include"], shared_libs: [ + "libcutils", "libhidlbase", "libutils", "android.hardware.gnss@1.0", diff --git a/gnss/common/utils/default/include/v2_1/GnssTemplate.h b/gnss/common/utils/default/include/v2_1/GnssTemplate.h index 4d4ec93593..79c78c3f07 100644 --- a/gnss/common/utils/default/include/v2_1/GnssTemplate.h +++ b/gnss/common/utils/default/include/v2_1/GnssTemplate.h @@ -28,6 +28,8 @@ #include #include +#include + #include "GnssAntennaInfo.h" #include "GnssConfiguration.h" #include "GnssDebug.h" @@ -157,9 +159,17 @@ template std::unique_ptr GnssTemplate::getLocationFromHW() { char inputBuffer[INPUT_BUFFER_SIZE]; if (!mHardwareModeChecked) { - mGnssFd = open(GNSS_PATH, O_RDWR | O_NONBLOCK); + // default using gnss0 + const char * gnss_dev_path = GNSS_PATH; + char devname_value[PROPERTY_VALUE_MAX] = ""; + if (property_get("debug.location.gnss.devname", devname_value, NULL) > 0) { + gnss_dev_path = devname_value; + ALOGD("using %s instead of the default %s", gnss_dev_path, GNSS_PATH); + } + + mGnssFd = open(gnss_dev_path, O_RDWR | O_NONBLOCK); if (mGnssFd == -1) { - ALOGW("Failed to open /dev/gnss0 errno: %d", errno); + ALOGW("Failed to open %s errno: %d", gnss_dev_path, errno); } mHardwareModeChecked = true; } -- GitLab From a2f3e4bab9c7643ab68de0143d4c008e595b7547 Mon Sep 17 00:00:00 2001 From: lesl Date: Mon, 22 Mar 2021 21:48:46 +0800 Subject: [PATCH 551/790] wifi: Correct document for SAP 11AX mode Current hostapd doesn't support mode: HOSTAPD_MODE_IEEE80211AX. Using he_capabilies->he_supported to identify if the current mode is AX. BYPASS_INCLUSIVE_LANGUAGE_REASON : The HE is a abbreviation which is High-Efficiency. Bug: 162484222 Test: Enable SAP on P21 (supported AX) and check the wifistandard is AX mode. BYPASS_INCLUSIVE_LANGUAGE_REASON=The HE is a abbreviation which is High-Efficiency. Change-Id: I1f40f2e2e5a0d1a862810d19899a6d968d8c29b2 --- wifi/hostapd/1.3/types.hal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wifi/hostapd/1.3/types.hal b/wifi/hostapd/1.3/types.hal index f453df7585..2230da8609 100644 --- a/wifi/hostapd/1.3/types.hal +++ b/wifi/hostapd/1.3/types.hal @@ -25,7 +25,7 @@ package android.hardware.wifi.hostapd@1.3; * WIFI_STANDARD_11N = [hw_mode is HOSTAPD_MODE_IEEE80211G and (HT is 1 or HT40 is 1)] or * [hw_mode is HOSTAPD_MODE_IEEE80211A and VHT is 0]. * WIFI_STANDARD_11AC = hw_mode is HOSTAPD_MODE_IEEE80211A and VHT is 1. - * WIFI_STANDARD_11AX = hw_mode is HOSTAPD_MODE_IEEE80211AX. + * WIFI_STANDARD_11AX = hw_mode is HOSTAPD_MODE_IEEE80211A and HE supported. * WIFI_STANDARD_11AD = hw_mode is HOSTAPD_MODE_IEEE80211AD. */ enum Generation : uint32_t { -- GitLab From 823cf5f4551721aa41403d0c873940294984ece4 Mon Sep 17 00:00:00 2001 From: Vince Leung Date: Thu, 11 Feb 2021 02:21:57 +0000 Subject: [PATCH 552/790] Add Chirp APIs for PWLE sequence creation Add the necessary Chirp APIs required to allow for piecewise-linear equation sequencing of haptic waveforms. These APIs will allow developers to create a fully customizable sequence of haptics waveforms for playback. Bug: 162859057 Test: verify pwle sequences can be created and played using idlcli command. Also verify using atest. Change-Id: I7fec224b7090e482bbcd1c94a3799ec232cc547f --- .../android/hardware/vibrator/ActivePwle.aidl | 42 ++ .../android/hardware/vibrator/Braking.aidl | 39 ++ .../hardware/vibrator/BrakingPwle.aidl | 39 ++ .../hardware/vibrator/CompositeEffect.aidl | 3 +- .../hardware/vibrator/CompositePrimitive.aidl | 3 +- .../android/hardware/vibrator/Effect.aidl | 3 +- .../hardware/vibrator/EffectStrength.aidl | 3 +- .../android/hardware/vibrator/IVibrator.aidl | 12 +- .../hardware/vibrator/IVibratorCallback.aidl | 3 +- .../hardware/vibrator/IVibratorManager.aidl | 3 +- .../hardware/vibrator/PrimitivePwle.aidl | 39 ++ .../android/hardware/vibrator/ActivePwle.aidl | 49 ++ .../android/hardware/vibrator/Braking.aidl | 34 ++ .../hardware/vibrator/BrakingPwle.aidl | 37 ++ .../android/hardware/vibrator/IVibrator.aidl | 113 ++++- .../hardware/vibrator/PrimitivePwle.aidl | 26 ++ vibrator/aidl/default/Vibrator.cpp | 173 ++++++- .../default/include/vibrator-impl/Vibrator.h | 9 + .../aidl/vts/VtsHalVibratorTargetTest.cpp | 421 +++++++++++++++--- 19 files changed, 984 insertions(+), 67 deletions(-) create mode 100644 vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/ActivePwle.aidl create mode 100644 vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/Braking.aidl create mode 100644 vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/BrakingPwle.aidl create mode 100644 vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PrimitivePwle.aidl create mode 100644 vibrator/aidl/android/hardware/vibrator/ActivePwle.aidl create mode 100644 vibrator/aidl/android/hardware/vibrator/Braking.aidl create mode 100644 vibrator/aidl/android/hardware/vibrator/BrakingPwle.aidl create mode 100644 vibrator/aidl/android/hardware/vibrator/PrimitivePwle.aidl diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/ActivePwle.aidl b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/ActivePwle.aidl new file mode 100644 index 0000000000..de3ad3c032 --- /dev/null +++ b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/ActivePwle.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 -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.vibrator; +@VintfStability +parcelable ActivePwle { + float startAmplitude; + float startFrequency; + float endAmplitude; + float endFrequency; + int duration; +} diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/Braking.aidl b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/Braking.aidl new file mode 100644 index 0000000000..d38c584d76 --- /dev/null +++ b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/Braking.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 -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.vibrator; +@Backing(type="int") @VintfStability +enum Braking { + NONE = 0, + CLAB = 1, +} diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/BrakingPwle.aidl b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/BrakingPwle.aidl new file mode 100644 index 0000000000..fa7b43abd0 --- /dev/null +++ b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/BrakingPwle.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 -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.vibrator; +@VintfStability +parcelable BrakingPwle { + android.hardware.vibrator.Braking braking; + int duration; +} diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/CompositeEffect.aidl b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/CompositeEffect.aidl index 0995d2d7af..3be58a1490 100644 --- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/CompositeEffect.aidl +++ b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/CompositeEffect.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/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/CompositePrimitive.aidl b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/CompositePrimitive.aidl index 0b4b527359..50de13fc27 100644 --- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/CompositePrimitive.aidl +++ b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/CompositePrimitive.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/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/Effect.aidl b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/Effect.aidl index 0d2b340a6c..adf0f2009f 100644 --- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/Effect.aidl +++ b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/Effect.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/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/EffectStrength.aidl b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/EffectStrength.aidl index 808644a4b5..af5e15871b 100644 --- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/EffectStrength.aidl +++ b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/EffectStrength.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/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibrator.aidl b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibrator.aidl index 1f2d946836..b7afb663cf 100644 --- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibrator.aidl +++ b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibrator.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. // /////////////////////////////////////////////////////////////////////////////// @@ -50,6 +51,13 @@ interface IVibrator { void alwaysOnDisable(in int id); float getResonantFrequency(); float getQFactor(); + float getFrequencyResolution(); + float getFrequencyMinimum(); + float[] getBandwidthAmplitudeMap(); + int getPwlePrimitiveDurationMax(); + int getPwleCompositionSizeMax(); + android.hardware.vibrator.Braking[] getSupportedBraking(); + void composePwle(in android.hardware.vibrator.PrimitivePwle[] composite, in android.hardware.vibrator.IVibratorCallback callback); const int CAP_ON_CALLBACK = 1; const int CAP_PERFORM_CALLBACK = 2; const int CAP_AMPLITUDE_CONTROL = 4; @@ -59,4 +67,6 @@ interface IVibrator { const int CAP_ALWAYS_ON_CONTROL = 64; const int CAP_GET_RESONANT_FREQUENCY = 128; const int CAP_GET_Q_FACTOR = 256; + const int CAP_FREQUENCY_CONTROL = 512; + const int CAP_COMPOSE_PWLE_EFFECTS = 1024; } diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibratorCallback.aidl b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibratorCallback.aidl index f99ecc1143..99d6d2290d 100644 --- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibratorCallback.aidl +++ b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibratorCallback.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/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibratorManager.aidl b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibratorManager.aidl index 8e3ac88e8c..290c68d877 100644 --- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibratorManager.aidl +++ b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibratorManager.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/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PrimitivePwle.aidl b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PrimitivePwle.aidl new file mode 100644 index 0000000000..584bcf4a47 --- /dev/null +++ b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PrimitivePwle.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 -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.vibrator; +@VintfStability +union PrimitivePwle { + android.hardware.vibrator.ActivePwle active; + android.hardware.vibrator.BrakingPwle braking; +} diff --git a/vibrator/aidl/android/hardware/vibrator/ActivePwle.aidl b/vibrator/aidl/android/hardware/vibrator/ActivePwle.aidl new file mode 100644 index 0000000000..fd5f8d1973 --- /dev/null +++ b/vibrator/aidl/android/hardware/vibrator/ActivePwle.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.vibrator; + +@VintfStability +parcelable ActivePwle { + /** + * Amplitude ranging from 0.0 (inclusive) to 1.0 (inclusive) + * in units of output acceleration amplitude, not voltage amplitude. + * + * 0.0 represents no output acceleration amplitude + * 1.0 represents maximum output acceleration amplitude at resonant frequency + */ + float startAmplitude; + /** + * Absolute frequency point in the units of hertz + */ + float startFrequency; + /** + * Amplitude ranging from 0.0 (inclusive) to 1.0 (inclusive) + * in units of output acceleration amplitude, not voltage amplitude. + * + * 0.0 represents no output acceleration amplitude + * 1.0 represents maximum output acceleration amplitude at resonant frequency + */ + float endAmplitude; + /** + * Absolute frequency point in the units of hertz + */ + float endFrequency; + /** + * Total duration from start point to end point in the units of milliseconds + */ + int duration; +} diff --git a/vibrator/aidl/android/hardware/vibrator/Braking.aidl b/vibrator/aidl/android/hardware/vibrator/Braking.aidl new file mode 100644 index 0000000000..2bc51db3f6 --- /dev/null +++ b/vibrator/aidl/android/hardware/vibrator/Braking.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.vibrator; + +@VintfStability +@Backing(type="int") +enum Braking { + /** + * No braking mechanism used. + * This is the default if the hardware does not support any braking mechanism. + */ + NONE, + /** + * Closed-loop active braking. + * + * This effect should produce a sharp, crisp end to the waveform + * Support is optional. + */ + CLAB, +} diff --git a/vibrator/aidl/android/hardware/vibrator/BrakingPwle.aidl b/vibrator/aidl/android/hardware/vibrator/BrakingPwle.aidl new file mode 100644 index 0000000000..00675ed0fc --- /dev/null +++ b/vibrator/aidl/android/hardware/vibrator/BrakingPwle.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.vibrator; + +import android.hardware.vibrator.Braking; + +/** + * BrakingPwle is defined as a segment of zero output acceleration amplitude of duration length. + * + * There should be no output acceleration and the vibrator should be off for the entire duration. + * If the hardware supports braking mechanism(s), they can be set here. + */ +@VintfStability +parcelable BrakingPwle { + /** + * Braking mechanism applied to adjacent segments + */ + Braking braking; + /** + * Total duration of zero output acceleration in the units of milliseconds. + */ + int duration; +} diff --git a/vibrator/aidl/android/hardware/vibrator/IVibrator.aidl b/vibrator/aidl/android/hardware/vibrator/IVibrator.aidl index cba76dc745..592d151d32 100644 --- a/vibrator/aidl/android/hardware/vibrator/IVibrator.aidl +++ b/vibrator/aidl/android/hardware/vibrator/IVibrator.aidl @@ -17,10 +17,12 @@ package android.hardware.vibrator; import android.hardware.vibrator.IVibratorCallback; +import android.hardware.vibrator.Braking; import android.hardware.vibrator.Effect; import android.hardware.vibrator.EffectStrength; import android.hardware.vibrator.CompositeEffect; import android.hardware.vibrator.CompositePrimitive; +import android.hardware.vibrator.PrimitivePwle; @VintfStability interface IVibrator { @@ -60,6 +62,14 @@ interface IVibrator { * Whether getQFactor is supported. */ const int CAP_GET_Q_FACTOR = 1 << 8; + /** + * Whether frequency control is supported. + */ + const int CAP_FREQUENCY_CONTROL = 1 << 9; + /** + * Whether composePwle is supported. + */ + const int CAP_COMPOSE_PWLE_EFFECTS = 1 << 10; /** * Determine capabilities of the vibrator HAL (CAP_* mask) @@ -240,18 +250,109 @@ interface IVibrator { void alwaysOnDisable(in int id); /** - * Retrieve the measured resonant frequency of the actuator. This may not be supported - * and this support is reflected in getCapabilities (CAP_GET_RESONANT_FREQUENCY) + * Retrieve the measured resonant frequency of the actuator. + * + * This may not be supported and this support is reflected in + * getCapabilities (CAP_GET_RESONANT_FREQUENCY) * - * @return Measured resonant frequency in Hz. + * @return Measured resonant frequency in Hz. Non-zero value if supported, + * or value should be ignored if not supported. */ float getResonantFrequency(); /** - * Retrieve the measured Q factor. This may not be supported - * and this support is reflected in getCapabilities (CAP_GET_Q_FACTOR) + * Retrieve the measured Q factor. + * + * This may not be supported and this support is reflected in + * getCapabilities (CAP_GET_Q_FACTOR) * - * @return Measured Q factor. + * @return Measured Q factor. Non-zero value if supported, or value should be + * ignored if not supported. */ float getQFactor(); + + /** + * Retrieve the frequency resolution used in getBandwidthAmplitudeMap() in units of hertz + * + * This may not be supported and this support is reflected in + * getCapabilities (CAP_FREQUENCY_CONTROL). + * + * @return The frequency resolution of the bandwidth amplitude map. + * Non-zero value if supported, or value should be ignored if not supported. + */ + float getFrequencyResolution(); + + /** + * Retrieve the minimum allowed frequency in units of hertz + * + * This may not be supported and this support is reflected in + * getCapabilities (CAP_FREQUENCY_CONTROL). + * + * @return The minimum frequency allowed. Non-zero value if supported, + * or value should be ignored if not supported. + */ + float getFrequencyMinimum(); + + /** + * Retrieve the output acceleration amplitude values per frequency supported + * + * This may not be supported and this support is reflected in + * getCapabilities (CAP_FREQUENCY_CONTROL). + * + * The mapping is represented as a list of amplitude values in the inclusive range [0.0, 1.0]. + * The first value represents the amplitude at the frequency returned by getFrequencyMinimum(). + * Each subsequent element is the amplitude at the next supported frequency, in increments + * of getFrequencyResolution(). The value returned by getResonantFrequency() must be + * represented in the returned list. + * + * @return The maximum output acceleration amplitude for each supported frequency, + * starting at getMinimumFrequency() + */ + float[] getBandwidthAmplitudeMap(); + + /** + * Retrieve the maximum duration allowed for any primitive PWLE in units of milliseconds. + * + * This may not be supported and this support is reflected in + * getCapabilities (CAP_COMPOSE_PWLE_EFFECTS). + * + * @return The maximum duration allowed for a single PrimitivePwle. + * Non-zero value if supported, or value should be ignored if not supported. + */ + int getPwlePrimitiveDurationMax(); + + /** + * Retrieve the maximum count for allowed PWLEs in one composition. + * + * This may not be supported and this support is reflected in + * getCapabilities (CAP_COMPOSE_PWLE_EFFECTS). + * + * @return The maximum count allowed. Non-zero value if supported, + * or value should be ignored if not supported. + */ + int getPwleCompositionSizeMax(); + + /** + * List of supported braking mechanism. + * + * This may not be supported and this support is reflected in + * getCapabilities (CAP_COMPOSE_PWLE_EFFECTS). + * Implementations are optional but encouraged if available. + * + * @return The braking mechanisms which are supported by the composePwle API. + */ + Braking[] getSupportedBraking(); + + /** + * Fire off a string of PWLEs. + * + * This may not be supported and this support is reflected in + * getCapabilities (CAP_COMPOSE_PWLE_EFFECTS). + * + * Doing this operation while the vibrator is already on is undefined behavior. Clients should + * explicitly call off. IVibratorCallback.onComplete() support is required for this API. + * + * @param composite Array of PWLEs. + */ + void composePwle(in PrimitivePwle[] composite, in IVibratorCallback callback); } diff --git a/vibrator/aidl/android/hardware/vibrator/PrimitivePwle.aidl b/vibrator/aidl/android/hardware/vibrator/PrimitivePwle.aidl new file mode 100644 index 0000000000..813c7dcb33 --- /dev/null +++ b/vibrator/aidl/android/hardware/vibrator/PrimitivePwle.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.vibrator; + +import android.hardware.vibrator.ActivePwle; +import android.hardware.vibrator.BrakingPwle; + +@VintfStability +union PrimitivePwle { + ActivePwle active; + BrakingPwle braking; +} diff --git a/vibrator/aidl/default/Vibrator.cpp b/vibrator/aidl/default/Vibrator.cpp index bf61bfec91..c6682b318f 100644 --- a/vibrator/aidl/default/Vibrator.cpp +++ b/vibrator/aidl/default/Vibrator.cpp @@ -26,9 +26,16 @@ namespace vibrator { static constexpr int32_t kComposeDelayMaxMs = 1000; static constexpr int32_t kComposeSizeMax = 256; +static constexpr int32_t kComposePwleSizeMax = 127; static constexpr float kResonantFrequency = 150.0; static constexpr float kQFactor = 11.0; +static constexpr int32_t COMPOSE_PWLE_PRIMITIVE_DURATION_MAX_MS = 16383; +static constexpr float PWLE_LEVEL_MIN = 0.0; +static constexpr float PWLE_LEVEL_MAX = 0.98256; +static constexpr float PWLE_FREQUENCY_RESOLUTION_HZ = 1.0; +static constexpr float PWLE_FREQUENCY_MIN_HZ = 140.0; +static constexpr float PWLE_FREQUENCY_MAX_HZ = 160.0; ndk::ScopedAStatus Vibrator::getCapabilities(int32_t* _aidl_return) { LOG(INFO) << "Vibrator reporting capabilities"; @@ -36,7 +43,8 @@ ndk::ScopedAStatus Vibrator::getCapabilities(int32_t* _aidl_return) { IVibrator::CAP_AMPLITUDE_CONTROL | IVibrator::CAP_EXTERNAL_CONTROL | IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL | IVibrator::CAP_COMPOSE_EFFECTS | IVibrator::CAP_ALWAYS_ON_CONTROL | IVibrator::CAP_GET_RESONANT_FREQUENCY | - IVibrator::CAP_GET_Q_FACTOR; + IVibrator::CAP_GET_Q_FACTOR | IVibrator::CAP_FREQUENCY_CONTROL | + IVibrator::CAP_COMPOSE_PWLE_EFFECTS; return ndk::ScopedAStatus::ok(); } @@ -215,6 +223,169 @@ ndk::ScopedAStatus Vibrator::getQFactor(float *qFactor) { return ndk::ScopedAStatus::ok(); } +ndk::ScopedAStatus Vibrator::getFrequencyResolution(float *freqResolutionHz) { + *freqResolutionHz = PWLE_FREQUENCY_RESOLUTION_HZ; + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Vibrator::getFrequencyMinimum(float *freqMinimumHz) { + *freqMinimumHz = PWLE_FREQUENCY_MIN_HZ; + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Vibrator::getBandwidthAmplitudeMap(std::vector *_aidl_return) { + // A valid array should be of size: + // (PWLE_FREQUENCY_MAX_HZ - PWLE_FREQUENCY_MIN_HZ) / PWLE_FREQUENCY_RESOLUTION_HZ + *_aidl_return = {0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.10, + 0.11, 0.12, 0.13, 0.14, 0.15, 0.16, 0.17, 0.18, 0.19, 0.20}; + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Vibrator::getPwlePrimitiveDurationMax(int32_t *durationMs) { + *durationMs = COMPOSE_PWLE_PRIMITIVE_DURATION_MAX_MS; + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Vibrator::getPwleCompositionSizeMax(int32_t *maxSize) { + *maxSize = kComposePwleSizeMax; + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus Vibrator::getSupportedBraking(std::vector *supported) { + *supported = { + Braking::NONE, + Braking::CLAB, + }; + return ndk::ScopedAStatus::ok(); +} + +void resetPreviousEndAmplitudeEndFrequency(float &prevEndAmplitude, float &prevEndFrequency) { + const float reset = -1.0; + prevEndAmplitude = reset; + prevEndFrequency = reset; +} + +void incrementIndex(int &index) { + index += 1; +} + +void constructActiveDefaults(std::ostringstream &pwleBuilder, const int &segmentIdx) { + pwleBuilder << ",C" << segmentIdx << ":1"; + pwleBuilder << ",B" << segmentIdx << ":0"; + pwleBuilder << ",AR" << segmentIdx << ":0"; + pwleBuilder << ",V" << segmentIdx << ":0"; +} + +void constructActiveSegment(std::ostringstream &pwleBuilder, const int &segmentIdx, int duration, + float amplitude, float frequency) { + pwleBuilder << ",T" << segmentIdx << ":" << duration; + pwleBuilder << ",L" << segmentIdx << ":" << amplitude; + pwleBuilder << ",F" << segmentIdx << ":" << frequency; + constructActiveDefaults(pwleBuilder, segmentIdx); +} + +void constructBrakingSegment(std::ostringstream &pwleBuilder, const int &segmentIdx, int duration, + Braking brakingType) { + pwleBuilder << ",T" << segmentIdx << ":" << duration; + pwleBuilder << ",L" << segmentIdx << ":" << 0; + pwleBuilder << ",F" << segmentIdx << ":" << 0; + pwleBuilder << ",C" << segmentIdx << ":0"; + pwleBuilder << ",B" << segmentIdx << ":" + << static_cast::type>(brakingType); + pwleBuilder << ",AR" << segmentIdx << ":0"; + pwleBuilder << ",V" << segmentIdx << ":0"; +} + +ndk::ScopedAStatus Vibrator::composePwle(const std::vector &composite, + const std::shared_ptr &callback) { + std::ostringstream pwleBuilder; + std::string pwleQueue; + + int compositionSizeMax; + getPwleCompositionSizeMax(&compositionSizeMax); + if (composite.size() <= 0 || composite.size() > compositionSizeMax) { + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + } + + float prevEndAmplitude; + float prevEndFrequency; + resetPreviousEndAmplitudeEndFrequency(prevEndAmplitude, prevEndFrequency); + + int segmentIdx = 0; + uint32_t totalDuration = 0; + + pwleBuilder << "S:0,WF:4,RP:0,WT:0"; + + for (auto &e : composite) { + switch (e.getTag()) { + case PrimitivePwle::active: { + auto active = e.get(); + if (active.duration < 0 || + active.duration > COMPOSE_PWLE_PRIMITIVE_DURATION_MAX_MS) { + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + } + if (active.startAmplitude < PWLE_LEVEL_MIN || + active.startAmplitude > PWLE_LEVEL_MAX || + active.endAmplitude < PWLE_LEVEL_MIN || active.endAmplitude > PWLE_LEVEL_MAX) { + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + } + if (active.startFrequency < PWLE_FREQUENCY_MIN_HZ || + active.startFrequency > PWLE_FREQUENCY_MAX_HZ || + active.endFrequency < PWLE_FREQUENCY_MIN_HZ || + active.endFrequency > PWLE_FREQUENCY_MAX_HZ) { + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + } + + if (!((active.startAmplitude == prevEndAmplitude) && + (active.startFrequency == prevEndFrequency))) { + constructActiveSegment(pwleBuilder, segmentIdx, 0, active.startAmplitude, + active.startFrequency); + incrementIndex(segmentIdx); + } + + constructActiveSegment(pwleBuilder, segmentIdx, active.duration, + active.endAmplitude, active.endFrequency); + incrementIndex(segmentIdx); + + prevEndAmplitude = active.endAmplitude; + prevEndFrequency = active.endFrequency; + totalDuration += active.duration; + break; + } + case PrimitivePwle::braking: { + auto braking = e.get(); + if (braking.braking > Braking::CLAB) { + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + } + if (braking.duration > COMPOSE_PWLE_PRIMITIVE_DURATION_MAX_MS) { + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + } + + constructBrakingSegment(pwleBuilder, segmentIdx, 0, braking.braking); + incrementIndex(segmentIdx); + + constructBrakingSegment(pwleBuilder, segmentIdx, braking.duration, braking.braking); + incrementIndex(segmentIdx); + + resetPreviousEndAmplitudeEndFrequency(prevEndAmplitude, prevEndFrequency); + totalDuration += braking.duration; + break; + } + } + } + + std::thread([=] { + LOG(INFO) << "Starting composePwle on another thread"; + usleep(totalDuration * 1000); + if (callback != nullptr) { + LOG(INFO) << "Notifying compose PWLE complete"; + callback->onComplete(); + } + }).detach(); + + return ndk::ScopedAStatus::ok(); +} + } // namespace vibrator } // namespace hardware } // namespace android diff --git a/vibrator/aidl/default/include/vibrator-impl/Vibrator.h b/vibrator/aidl/default/include/vibrator-impl/Vibrator.h index a2af9637ed..4203bf212c 100644 --- a/vibrator/aidl/default/include/vibrator-impl/Vibrator.h +++ b/vibrator/aidl/default/include/vibrator-impl/Vibrator.h @@ -46,6 +46,15 @@ class Vibrator : public BnVibrator { ndk::ScopedAStatus alwaysOnDisable(int32_t id) override; ndk::ScopedAStatus getResonantFrequency(float *resonantFreqHz) override; ndk::ScopedAStatus getQFactor(float *qFactor) override; + ndk::ScopedAStatus getFrequencyResolution(float *freqResolutionHz) override; + ndk::ScopedAStatus getFrequencyMinimum(float *freqMinimumHz) override; + ndk::ScopedAStatus getBandwidthAmplitudeMap(std::vector *_aidl_return) override; + ndk::ScopedAStatus getPwlePrimitiveDurationMax(int32_t *durationMs) override; + ndk::ScopedAStatus getPwleCompositionSizeMax(int32_t *maxSize) override; + ndk::ScopedAStatus getSupportedBraking(std::vector* supported) override; + ndk::ScopedAStatus composePwle(const std::vector &composite, + const std::shared_ptr &callback) override; + }; } // namespace vibrator diff --git a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp index 2540d0b1d5..a9d1ed5a51 100644 --- a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp +++ b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp @@ -15,7 +15,6 @@ */ #include #include - #include #include #include @@ -29,13 +28,17 @@ using android::ProcessState; using android::sp; using android::String16; using android::binder::Status; +using android::hardware::vibrator::ActivePwle; using android::hardware::vibrator::BnVibratorCallback; +using android::hardware::vibrator::Braking; +using android::hardware::vibrator::BrakingPwle; using android::hardware::vibrator::CompositeEffect; using android::hardware::vibrator::CompositePrimitive; using android::hardware::vibrator::Effect; using android::hardware::vibrator::EffectStrength; using android::hardware::vibrator::IVibrator; using android::hardware::vibrator::IVibratorManager; +using android::hardware::vibrator::PrimitivePwle; using std::chrono::high_resolution_clock; const std::vector kEffects{android::enum_range().begin(), @@ -44,32 +47,32 @@ const std::vector kEffectStrengths{android::enum_range().end()}; const std::vector kInvalidEffects = { - static_cast(static_cast(kEffects.front()) - 1), - static_cast(static_cast(kEffects.back()) + 1), + static_cast(static_cast(kEffects.front()) - 1), + static_cast(static_cast(kEffects.back()) + 1), }; const std::vector kInvalidEffectStrengths = { - static_cast(static_cast(kEffectStrengths.front()) - 1), - static_cast(static_cast(kEffectStrengths.back()) + 1), + static_cast(static_cast(kEffectStrengths.front()) - 1), + static_cast(static_cast(kEffectStrengths.back()) + 1), }; const std::vector kCompositePrimitives{ - android::enum_range().begin(), - android::enum_range().end()}; + android::enum_range().begin(), + android::enum_range().end()}; const std::vector kOptionalPrimitives = { - CompositePrimitive::THUD, - CompositePrimitive::SPIN, + CompositePrimitive::THUD, + CompositePrimitive::SPIN, }; const std::vector kInvalidPrimitives = { - static_cast(static_cast(kCompositePrimitives.front()) - 1), - static_cast(static_cast(kCompositePrimitives.back()) + 1), + static_cast(static_cast(kCompositePrimitives.front()) - 1), + static_cast(static_cast(kCompositePrimitives.back()) + 1), }; class CompletionCallback : public BnVibratorCallback { public: - CompletionCallback(const std::function& callback) : mCallback(callback) {} + CompletionCallback(const std::function &callback) : mCallback(callback) {} Status onComplete() override { mCallback(); return Status::ok(); @@ -109,6 +112,89 @@ class VibratorAidl : public testing::TestWithParam> int32_t capabilities; }; +static float getResonantFrequencyHz(sp vibrator, int32_t capabilities) { + float resonantFrequencyHz; + Status status = vibrator->getResonantFrequency(&resonantFrequencyHz); + if (capabilities & IVibrator::CAP_GET_RESONANT_FREQUENCY) { + EXPECT_GT(resonantFrequencyHz, 0); + EXPECT_EQ(status.exceptionCode(), Status::EX_NONE); + } else { + EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION); + } + return resonantFrequencyHz; +} + +static float getFrequencyResolutionHz(sp vibrator, int32_t capabilities) { + float freqResolutionHz; + Status status = vibrator->getFrequencyResolution(&freqResolutionHz); + if (capabilities & IVibrator::CAP_FREQUENCY_CONTROL) { + EXPECT_GT(freqResolutionHz, 0); + EXPECT_EQ(status.exceptionCode(), Status::EX_NONE); + } else { + EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION); + } + return freqResolutionHz; +} + +static float getFrequencyMinimumHz(sp vibrator, int32_t capabilities) { + float freqMinimumHz; + Status status = vibrator->getFrequencyMinimum(&freqMinimumHz); + if (capabilities & IVibrator::CAP_FREQUENCY_CONTROL) { + EXPECT_EQ(status.exceptionCode(), Status::EX_NONE); + + float resonantFrequencyHz = getResonantFrequencyHz(vibrator, capabilities); + + EXPECT_GT(freqMinimumHz, 0); + EXPECT_LE(freqMinimumHz, resonantFrequencyHz); + } else { + EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION); + } + return freqMinimumHz; +} + +static float getFrequencyMaximumHz(sp vibrator, int32_t capabilities) { + std::vector bandwidthAmplitudeMap; + Status status = vibrator->getBandwidthAmplitudeMap(&bandwidthAmplitudeMap); + if (capabilities & IVibrator::CAP_FREQUENCY_CONTROL) { + EXPECT_EQ(status.exceptionCode(), Status::EX_NONE); + } else { + EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION); + } + + float freqMaximumHz = + (bandwidthAmplitudeMap.size() * getFrequencyResolutionHz(vibrator, capabilities)) + + getFrequencyMinimumHz(vibrator, capabilities); + return freqMaximumHz; +} + +static float getAmplitudeMin() { + return 0.0; +} + +static float getAmplitudeMax() { + return 1.0; +} + +static ActivePwle composeValidActivePwle(sp vibrator, int32_t capabilities) { + float frequencyHz; + if (capabilities & IVibrator::CAP_GET_RESONANT_FREQUENCY) { + frequencyHz = getResonantFrequencyHz(vibrator, capabilities); + } else if (capabilities & IVibrator::CAP_FREQUENCY_CONTROL) { + frequencyHz = getFrequencyMinimumHz(vibrator, capabilities); + } else { + frequencyHz = 150.0; // default value commonly used + } + + ActivePwle active; + active.startAmplitude = (getAmplitudeMin() + getAmplitudeMax()) / 2; + active.startFrequency = frequencyHz; + active.endAmplitude = (getAmplitudeMin() + getAmplitudeMax()) / 2; + active.endFrequency = frequencyHz; + active.duration = 1000; + + return active; +} + TEST_P(VibratorAidl, OnThenOffBeforeTimeout) { EXPECT_TRUE(vibrator->on(2000, nullptr /*callback*/).isOk()); sleep(1); @@ -116,12 +202,13 @@ TEST_P(VibratorAidl, OnThenOffBeforeTimeout) { } TEST_P(VibratorAidl, OnWithCallback) { - if (!(capabilities & IVibrator::CAP_ON_CALLBACK)) return; + if (!(capabilities & IVibrator::CAP_ON_CALLBACK)) + return; std::promise completionPromise; std::future completionFuture{completionPromise.get_future()}; sp callback = - new CompletionCallback([&completionPromise] { completionPromise.set_value(); }); + new CompletionCallback([&completionPromise] { completionPromise.set_value(); }); uint32_t durationMs = 250; std::chrono::milliseconds timeout{durationMs * 2}; EXPECT_TRUE(vibrator->on(durationMs, callback).isOk()); @@ -142,7 +229,7 @@ TEST_P(VibratorAidl, ValidateEffect) { for (Effect effect : kEffects) { bool isEffectSupported = - std::find(supported.begin(), supported.end(), effect) != supported.end(); + std::find(supported.begin(), supported.end(), effect) != supported.end(); for (EffectStrength strength : kEffectStrengths) { int32_t lengthMs = 0; @@ -154,27 +241,28 @@ TEST_P(VibratorAidl, ValidateEffect) { usleep(lengthMs * 1000); } else { EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION) - << toString(effect) << " " << toString(strength); + << toString(effect) << " " << toString(strength); } } } } TEST_P(VibratorAidl, ValidateEffectWithCallback) { - if (!(capabilities & IVibrator::CAP_PERFORM_CALLBACK)) return; + if (!(capabilities & IVibrator::CAP_PERFORM_CALLBACK)) + return; std::vector supported; ASSERT_TRUE(vibrator->getSupportedEffects(&supported).isOk()); for (Effect effect : kEffects) { bool isEffectSupported = - std::find(supported.begin(), supported.end(), effect) != supported.end(); + std::find(supported.begin(), supported.end(), effect) != supported.end(); for (EffectStrength strength : kEffectStrengths) { std::promise completionPromise; std::future completionFuture{completionPromise.get_future()}; sp callback = - new CompletionCallback([&completionPromise] { completionPromise.set_value(); }); + new CompletionCallback([&completionPromise] { completionPromise.set_value(); }); int lengthMs = 0; Status status = vibrator->perform(effect, strength, callback, &lengthMs); @@ -185,7 +273,8 @@ TEST_P(VibratorAidl, ValidateEffectWithCallback) { EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION); } - if (!status.isOk()) continue; + if (!status.isOk()) + continue; std::chrono::milliseconds timeout{lengthMs * 2}; EXPECT_EQ(completionFuture.wait_for(timeout), std::future_status::ready); @@ -194,7 +283,8 @@ TEST_P(VibratorAidl, ValidateEffectWithCallback) { } TEST_P(VibratorAidl, ValidateEffectWithCallbackNotSupported) { - if (capabilities & IVibrator::CAP_PERFORM_CALLBACK) return; + if (capabilities & IVibrator::CAP_PERFORM_CALLBACK) + return; for (Effect effect : kEffects) { for (EffectStrength strength : kEffectStrengths) { @@ -212,7 +302,7 @@ TEST_P(VibratorAidl, InvalidEffectsUnsupported) { int32_t lengthMs; Status status = vibrator->perform(effect, strength, nullptr /*callback*/, &lengthMs); EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION) - << toString(effect) << " " << toString(strength); + << toString(effect) << " " << toString(strength); } } for (Effect effect : kEffects) { @@ -220,7 +310,7 @@ TEST_P(VibratorAidl, InvalidEffectsUnsupported) { int32_t lengthMs; Status status = vibrator->perform(effect, strength, nullptr /*callback*/, &lengthMs); EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION) - << toString(effect) << " " << toString(strength); + << toString(effect) << " " << toString(strength); } } } @@ -261,7 +351,7 @@ TEST_P(VibratorAidl, ChangeVibrationExternalControl) { TEST_P(VibratorAidl, ExternalAmplitudeControl) { const bool supportsExternalAmplitudeControl = - (capabilities & IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL) > 0; + (capabilities & IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL) > 0; if (capabilities & IVibrator::CAP_EXTERNAL_CONTROL) { EXPECT_TRUE(vibrator->setExternalControl(true).isOk()); @@ -293,10 +383,10 @@ TEST_P(VibratorAidl, GetSupportedPrimitives) { for (auto primitive : kCompositePrimitives) { bool isPrimitiveSupported = - std::find(supported.begin(), supported.end(), primitive) != supported.end(); + std::find(supported.begin(), supported.end(), primitive) != supported.end(); bool isPrimitiveOptional = - std::find(kOptionalPrimitives.begin(), kOptionalPrimitives.end(), primitive) != - kOptionalPrimitives.end(); + std::find(kOptionalPrimitives.begin(), kOptionalPrimitives.end(), primitive) != + kOptionalPrimitives.end(); EXPECT_TRUE(isPrimitiveSupported || isPrimitiveOptional) << toString(primitive); } @@ -310,7 +400,7 @@ TEST_P(VibratorAidl, GetPrimitiveDuration) { for (auto primitive : kCompositePrimitives) { bool isPrimitiveSupported = - std::find(supported.begin(), supported.end(), primitive) != supported.end(); + std::find(supported.begin(), supported.end(), primitive) != supported.end(); int32_t duration; Status status = vibrator->getPrimitiveDuration(primitive, &duration); @@ -366,7 +456,7 @@ TEST_P(VibratorAidl, ComposeUnsupportedPrimitives) { for (auto primitive : kCompositePrimitives) { bool isPrimitiveSupported = - std::find(supported.begin(), supported.end(), primitive) != supported.end(); + std::find(supported.begin(), supported.end(), primitive) != supported.end(); if (!isPrimitiveSupported) { unsupported.push_back(primitive); @@ -376,7 +466,7 @@ TEST_P(VibratorAidl, ComposeUnsupportedPrimitives) { for (auto primitive : unsupported) { std::vector composite(1); - for (auto& effect : composite) { + for (auto &effect : composite) { effect.delayMs = 0; effect.primitive = primitive; effect.scale = 1.0f; @@ -391,7 +481,7 @@ TEST_P(VibratorAidl, ComposeUnsupportedPrimitives) { TEST_P(VibratorAidl, ComposeScaleBoundary) { if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) { std::vector composite(1); - CompositeEffect& effect = composite[0]; + CompositeEffect &effect = composite[0]; effect.delayMs = 0; effect.primitive = CompositePrimitive::CLICK; @@ -478,7 +568,7 @@ TEST_P(VibratorAidl, ComposeCallback) { std::promise completionPromise; std::future completionFuture{completionPromise.get_future()}; sp callback = - new CompletionCallback([&completionPromise] { completionPromise.set_value(); }); + new CompletionCallback([&completionPromise] { completionPromise.set_value(); }); CompositeEffect effect; std::vector composite; int32_t durationMs; @@ -493,16 +583,15 @@ TEST_P(VibratorAidl, ComposeCallback) { EXPECT_EQ(Status::EX_NONE, vibrator->getPrimitiveDuration(primitive, &durationMs).exceptionCode()) - << toString(primitive); + << toString(primitive); duration = std::chrono::milliseconds(durationMs); EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, callback).exceptionCode()) - << toString(primitive); + << toString(primitive); start = high_resolution_clock::now(); - EXPECT_EQ(completionFuture.wait_for(duration + allowedLatency), - std::future_status::ready) - << toString(primitive); + EXPECT_EQ(completionFuture.wait_for(duration + allowedLatency), std::future_status::ready) + << toString(primitive); end = high_resolution_clock::now(); elapsed = std::chrono::duration_cast(end - start); @@ -519,17 +608,17 @@ TEST_P(VibratorAidl, AlwaysOn) { for (Effect effect : kEffects) { bool isEffectSupported = - std::find(supported.begin(), supported.end(), effect) != supported.end(); + std::find(supported.begin(), supported.end(), effect) != supported.end(); for (EffectStrength strength : kEffectStrengths) { Status status = vibrator->alwaysOnEnable(0, effect, strength); if (isEffectSupported) { EXPECT_EQ(Status::EX_NONE, status.exceptionCode()) - << toString(effect) << " " << toString(strength); + << toString(effect) << " " << toString(strength); } else { EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION, status.exceptionCode()) - << toString(effect) << " " << toString(strength); + << toString(effect) << " " << toString(strength); } } } @@ -539,27 +628,253 @@ TEST_P(VibratorAidl, AlwaysOn) { } TEST_P(VibratorAidl, GetResonantFrequency) { - float resonantFrequency; - Status status = vibrator->getResonantFrequency(&resonantFrequency); - if (capabilities & IVibrator::CAP_GET_RESONANT_FREQUENCY) { - ASSERT_NE(resonantFrequency, 0); - EXPECT_EQ(status.exceptionCode(), Status::EX_NONE); - } else { - EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION); - } + getResonantFrequencyHz(vibrator, capabilities); } TEST_P(VibratorAidl, GetQFactor) { float qFactor; Status status = vibrator->getQFactor(&qFactor); if (capabilities & IVibrator::CAP_GET_Q_FACTOR) { - ASSERT_NE(qFactor, 0); + ASSERT_GT(qFactor, 0); EXPECT_EQ(status.exceptionCode(), Status::EX_NONE); } else { EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION); } } +TEST_P(VibratorAidl, GetFrequencyResolution) { + getFrequencyResolutionHz(vibrator, capabilities); +} + +TEST_P(VibratorAidl, GetFrequencyMinimum) { + getFrequencyMinimumHz(vibrator, capabilities); +} + +TEST_P(VibratorAidl, GetBandwidthAmplitudeMap) { + std::vector bandwidthAmplitudeMap; + Status status = vibrator->getBandwidthAmplitudeMap(&bandwidthAmplitudeMap); + if (capabilities & IVibrator::CAP_FREQUENCY_CONTROL) { + EXPECT_EQ(status.exceptionCode(), Status::EX_NONE); + ASSERT_FALSE(bandwidthAmplitudeMap.empty()); + + int minMapSize = (getResonantFrequencyHz(vibrator, capabilities) - + getFrequencyMinimumHz(vibrator, capabilities)) / + getFrequencyResolutionHz(vibrator, capabilities); + ASSERT_GT(bandwidthAmplitudeMap.size(), minMapSize); + + for (float e : bandwidthAmplitudeMap) { + ASSERT_GE(e, 0.0); + ASSERT_LE(e, 1.0); + } + } else { + EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION); + } +} + +TEST_P(VibratorAidl, GetPwlePrimitiveDurationMax) { + int32_t durationMs; + Status status = vibrator->getPwlePrimitiveDurationMax(&durationMs); + if (capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS) { + ASSERT_NE(durationMs, 0); + EXPECT_EQ(status.exceptionCode(), Status::EX_NONE); + } else { + EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION); + } +} + +TEST_P(VibratorAidl, GetPwleCompositionSizeMax) { + int32_t maxSize; + Status status = vibrator->getPwleCompositionSizeMax(&maxSize); + if (capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS) { + ASSERT_NE(maxSize, 0); + EXPECT_EQ(status.exceptionCode(), Status::EX_NONE); + } else { + EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION); + } +} + +TEST_P(VibratorAidl, GetSupportedBraking) { + std::vector supported; + Status status = vibrator->getSupportedBraking(&supported); + if (capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS) { + bool isDefaultNoneSupported = + std::find(supported.begin(), supported.end(), Braking::NONE) != supported.end(); + ASSERT_TRUE(isDefaultNoneSupported); + EXPECT_EQ(status.exceptionCode(), Status::EX_NONE); + } else { + EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION); + } +} + +TEST_P(VibratorAidl, ComposeValidPwle) { + if (capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS) { + ActivePwle active = composeValidActivePwle(vibrator, capabilities); + + std::vector supported; + ASSERT_TRUE(vibrator->getSupportedBraking(&supported).isOk()); + bool isClabSupported = + std::find(supported.begin(), supported.end(), Braking::CLAB) != supported.end(); + BrakingPwle braking; + braking.braking = isClabSupported ? Braking::CLAB : Braking::NONE; + braking.duration = 100; + + std::vector pwleQueue; + PrimitivePwle pwle; + pwle = active; + pwleQueue.emplace_back(std::move(pwle)); + pwle = braking; + pwleQueue.emplace_back(std::move(pwle)); + pwle = active; + pwleQueue.emplace_back(std::move(pwle)); + + EXPECT_EQ(Status::EX_NONE, vibrator->composePwle(pwleQueue, nullptr).exceptionCode()); + vibrator->off(); + } +} + +TEST_P(VibratorAidl, ComposeValidPwleWithCallback) { + if (!((capabilities & IVibrator::CAP_ON_CALLBACK) && + (capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS))) + return; + + std::promise completionPromise; + std::future completionFuture{completionPromise.get_future()}; + sp callback = + new CompletionCallback([&completionPromise] { completionPromise.set_value(); }); + uint32_t durationMs = 2100; // Sum of 2 active and 1 braking below + std::chrono::milliseconds timeout{durationMs * 2}; + + ActivePwle active = composeValidActivePwle(vibrator, capabilities); + + std::vector supported; + ASSERT_TRUE(vibrator->getSupportedBraking(&supported).isOk()); + bool isClabSupported = + std::find(supported.begin(), supported.end(), Braking::CLAB) != supported.end(); + BrakingPwle braking; + braking.braking = isClabSupported ? Braking::CLAB : Braking::NONE; + braking.duration = 100; + + std::vector pwleQueue; + PrimitivePwle pwle; + pwle = active; + pwleQueue.emplace_back(std::move(pwle)); + pwle = braking; + pwleQueue.emplace_back(std::move(pwle)); + pwle = active; + pwleQueue.emplace_back(std::move(pwle)); + + EXPECT_TRUE(vibrator->composePwle(pwleQueue, callback).isOk()); + EXPECT_EQ(completionFuture.wait_for(timeout), std::future_status::ready); + EXPECT_TRUE(vibrator->off().isOk()); +} + +TEST_P(VibratorAidl, ComposePwleSegmentBoundary) { + if (capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS) { + std::vector pwleQueue; + // test empty queue + EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, + vibrator->composePwle(pwleQueue, nullptr).exceptionCode()); + vibrator->off(); + + ActivePwle active = composeValidActivePwle(vibrator, capabilities); + + PrimitivePwle pwle; + pwle = active; + int segmentCountMax; + vibrator->getPwleCompositionSizeMax(&segmentCountMax); + + // Create PWLE queue with more segments than allowed + for (int i = 0; i < segmentCountMax + 10; i++) { + pwleQueue.emplace_back(std::move(pwle)); + } + + EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, + vibrator->composePwle(pwleQueue, nullptr).exceptionCode()); + vibrator->off(); + } +} + +TEST_P(VibratorAidl, ComposePwleAmplitudeParameterBoundary) { + if (capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS) { + ActivePwle active = composeValidActivePwle(vibrator, capabilities); + active.startAmplitude = getAmplitudeMax() + 1.0; // Amplitude greater than allowed + active.endAmplitude = getAmplitudeMax() + 1.0; // Amplitude greater than allowed + + std::vector pwleQueueGreater; + PrimitivePwle pwle; + pwle = active; + pwleQueueGreater.emplace_back(std::move(pwle)); + + EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, + vibrator->composePwle(pwleQueueGreater, nullptr).exceptionCode()); + vibrator->off(); + + active.startAmplitude = getAmplitudeMin() - 1.0; // Amplitude less than allowed + active.endAmplitude = getAmplitudeMin() - 1.0; // Amplitude less than allowed + + std::vector pwleQueueLess; + pwle = active; + pwleQueueLess.emplace_back(std::move(pwle)); + + EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, + vibrator->composePwle(pwleQueueLess, nullptr).exceptionCode()); + vibrator->off(); + } +} + +TEST_P(VibratorAidl, ComposePwleFrequencyParameterBoundary) { + if ((capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS) && + (capabilities & IVibrator::CAP_FREQUENCY_CONTROL)) { + float freqMinimumHz = getFrequencyMinimumHz(vibrator, capabilities); + float freqMaximumHz = getFrequencyMaximumHz(vibrator, capabilities); + float freqResolutionHz = getFrequencyResolutionHz(vibrator, capabilities); + + ActivePwle active = composeValidActivePwle(vibrator, capabilities); + active.startFrequency = + freqMaximumHz + freqResolutionHz; // Frequency greater than allowed + active.endFrequency = freqMaximumHz + freqResolutionHz; // Frequency greater than allowed + + std::vector pwleQueueGreater; + PrimitivePwle pwle; + pwle = active; + pwleQueueGreater.emplace_back(std::move(pwle)); + + EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, + vibrator->composePwle(pwleQueueGreater, nullptr).exceptionCode()); + vibrator->off(); + + active.startFrequency = freqMinimumHz - freqResolutionHz; // Frequency less than allowed + active.endFrequency = freqMinimumHz - freqResolutionHz; // Frequency less than allowed + + std::vector pwleQueueLess; + pwle = active; + pwleQueueLess.emplace_back(std::move(pwle)); + + EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, + vibrator->composePwle(pwleQueueLess, nullptr).exceptionCode()); + vibrator->off(); + } +} + +TEST_P(VibratorAidl, ComposePwleSegmentDurationBoundary) { + if (capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS) { + ActivePwle active = composeValidActivePwle(vibrator, capabilities); + + int segmentDurationMaxMs; + vibrator->getPwlePrimitiveDurationMax(&segmentDurationMaxMs); + active.duration = segmentDurationMaxMs + 10; // Segment duration greater than allowed + + std::vector pwleQueue; + PrimitivePwle pwle; + pwle = active; + pwleQueue.emplace_back(std::move(pwle)); + + EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, + vibrator->composePwle(pwleQueue, nullptr).exceptionCode()); + vibrator->off(); + } +} + std::vector> GenerateVibratorMapping() { std::vector> tuples; auto managerAidlNames = android::getAidlHalInstanceNames(IVibratorManager::descriptor); @@ -569,7 +884,7 @@ std::vector> GenerateVibratorMapping() { auto managerName = String16(managerAidlNames[i].c_str()); auto vibratorManager = android::waitForDeclaredService(managerName); if (vibratorManager->getVibratorIds(&vibratorIds).isOk()) { - for (auto& vibratorId : vibratorIds) { + for (auto &vibratorId : vibratorIds) { tuples.push_back(std::make_tuple(i, vibratorId)); } } @@ -583,8 +898,8 @@ std::vector> GenerateVibratorMapping() { return tuples; } -std::string PrintGeneratedTest(const testing::TestParamInfo& info) { - const auto& [managerIdx, vibratorId] = info.param; +std::string PrintGeneratedTest(const testing::TestParamInfo &info) { + const auto &[managerIdx, vibratorId] = info.param; if (managerIdx < 0) { return std::string("TOP_LEVEL_VIBRATOR_") + std::to_string(vibratorId); } @@ -596,7 +911,7 @@ GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VibratorAidl); INSTANTIATE_TEST_SUITE_P(Vibrator, VibratorAidl, testing::ValuesIn(GenerateVibratorMapping()), PrintGeneratedTest); -int main(int argc, char** argv) { +int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); ProcessState::self()->setThreadPoolMaxThreadCount(1); ProcessState::self()->startThreadPool(); -- GitLab From 98e579c7badb3aa9f0abcbdc1baedd224dc225e5 Mon Sep 17 00:00:00 2001 From: karthik bharadwaj Date: Wed, 24 Mar 2021 01:39:55 -0700 Subject: [PATCH 553/790] Rename the global mic disable setting The current implementation of the user microphone disable privacy setting has led to some confusion and readability issues. Originally meant to denote meaning along the lines of 'the user's microphone disable switch is enabled', the logic (and reviews) have turned out slightly cumbersome. Refactoring it to simply mean 'microphone access', would be easier to implement, review and maintain. This CL renames the enum, the reworked logic will be in an accompanying CL. Bug: 183416485 Test: atest VtsHalContexthubV1_2TargetTest Change-Id: I85c95f4a6ee5cb0db7547c318d30b72f740e6d9b --- contexthub/1.2/types.hal | 8 +++++--- .../1.2/vts/functional/VtsHalContexthubV1_2TargetTest.cpp | 6 +++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/contexthub/1.2/types.hal b/contexthub/1.2/types.hal index 5033ce84c6..75122bc898 100644 --- a/contexthub/1.2/types.hal +++ b/contexthub/1.2/types.hal @@ -35,10 +35,12 @@ enum Setting : @1.1::Setting { AIRPLANE_MODE, /** - * Indicates if the microphone access was turned off globally by the user, - * in which case audio data cannot be used and propagated by CHRE. + * Indicates if the microphone access is available for CHRE. Microphone + * access is disabled if the user has turned off the microphone as a + * privacy setting, in which case audio data cannot be used and propagated + * by CHRE. */ - GLOBAL_MIC_DISABLE, + MICROPHONE, }; struct ContextHubMsg { diff --git a/contexthub/1.2/vts/functional/VtsHalContexthubV1_2TargetTest.cpp b/contexthub/1.2/vts/functional/VtsHalContexthubV1_2TargetTest.cpp index 3510c2379f..9ee40ede01 100644 --- a/contexthub/1.2/vts/functional/VtsHalContexthubV1_2TargetTest.cpp +++ b/contexthub/1.2/vts/functional/VtsHalContexthubV1_2TargetTest.cpp @@ -131,10 +131,10 @@ TEST_P(ContexthubHidlTest, TestOnAirplaneModeSettingChanged) { ASSERT_OK(registerCallback_1_2(nullptr)); } -TEST_P(ContexthubHidlTest, TestOnGlobalMicDisableSettingChanged) { +TEST_P(ContexthubHidlTest, TestOnMicrophoneSettingChanged) { ASSERT_OK(registerCallback_1_2(new ContexthubCallbackV1_2())); - hubApi->onSettingChanged_1_2(Setting::GLOBAL_MIC_DISABLE, SettingValue::DISABLED); - hubApi->onSettingChanged_1_2(Setting::GLOBAL_MIC_DISABLE, SettingValue::ENABLED); + hubApi->onSettingChanged_1_2(Setting::MICROPHONE, SettingValue::DISABLED); + hubApi->onSettingChanged_1_2(Setting::MICROPHONE, SettingValue::ENABLED); ASSERT_OK(registerCallback_1_2(nullptr)); } -- GitLab From 184e35a4275c94705e8f0197c728689a42271c6c Mon Sep 17 00:00:00 2001 From: junyulai Date: Wed, 24 Mar 2021 23:23:28 +0800 Subject: [PATCH 554/790] [SP32.1] Put OffloadControl 1.1 HAL into apex Test: atest TetheringTests Bug: 149467454 Ignore-AOSP-First: avoid long automerger delay Change-Id: I0e4dc6758d87c320fc622da06144b4ceceb91964 --- tetheroffload/control/1.1/Android.bp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tetheroffload/control/1.1/Android.bp b/tetheroffload/control/1.1/Android.bp index e87ff5c71b..7871c2c1d9 100644 --- a/tetheroffload/control/1.1/Android.bp +++ b/tetheroffload/control/1.1/Android.bp @@ -21,5 +21,9 @@ hidl_interface { "android.hardware.tetheroffload.control@1.0", "android.hidl.base@1.0", ], + apex_available: [ + "//apex_available:platform", // Used by InProcessTethering + "com.android.tethering", + ], gen_java: true, } -- GitLab From 2ad929d98676282028e72daa4841742e35a8ee41 Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Tue, 23 Mar 2021 17:15:08 -0700 Subject: [PATCH 555/790] Remove SessionState from IFingerprint Bug: 183570051 Test: atest VtsHalBiometricsFingerprintTargetTest Change-Id: I82edc57b7bb36d9688428bc7a65470145aadcb89 --- .../biometrics/fingerprint/ISession.aidl | 22 +-- .../fingerprint/ISessionCallback.aidl | 1 - .../biometrics/fingerprint/SessionState.aidl | 49 ------- .../biometrics/fingerprint/IFingerprint.aidl | 27 +--- .../biometrics/fingerprint/ISession.aidl | 125 ++++++------------ .../fingerprint/ISessionCallback.aidl | 53 ++++---- .../biometrics/fingerprint/SessionState.aidl | 81 ------------ 7 files changed, 85 insertions(+), 273 deletions(-) delete mode 100644 biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.aidl delete mode 100644 biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SessionState.aidl 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 87eaf96a41..9934a763e7 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 @@ -34,17 +34,17 @@ package android.hardware.biometrics.fingerprint; @VintfStability interface ISession { - void generateChallenge(in int cookie); - void revokeChallenge(in int cookie, in long challenge); - android.hardware.biometrics.common.ICancellationSignal enroll(in int cookie, in android.hardware.keymaster.HardwareAuthToken hat); - android.hardware.biometrics.common.ICancellationSignal authenticate(in int cookie, in long operationId); - android.hardware.biometrics.common.ICancellationSignal detectInteraction(in int cookie); - void enumerateEnrollments(in int cookie); - void removeEnrollments(in int cookie, in int[] enrollmentIds); - void getAuthenticatorId(in int cookie); - void invalidateAuthenticatorId(in int cookie); - void resetLockout(in int cookie, in android.hardware.keymaster.HardwareAuthToken hat); - void close(in int cookie); + 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(); diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl index 3a977178ff..3c40ad63bf 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl @@ -34,7 +34,6 @@ package android.hardware.biometrics.fingerprint; @VintfStability interface ISessionCallback { - void onStateChanged(in int cookie, in android.hardware.biometrics.fingerprint.SessionState state); void onChallengeGenerated(in long challenge); void onChallengeRevoked(in long challenge); void onAcquired(in android.hardware.biometrics.fingerprint.AcquiredInfo info, in int vendorCode); diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.aidl deleted file mode 100644 index 9b0b6f6a77..0000000000 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.aidl +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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 -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.fingerprint; -@Backing(type="byte") @VintfStability -enum SessionState { - IDLING = 0, - CLOSED = 1, - GENERATING_CHALLENGE = 2, - REVOKING_CHALLENGE = 3, - ENROLLING = 4, - AUTHENTICATING = 5, - DETECTING_INTERACTION = 6, - ENUMERATING_ENROLLMENTS = 7, - REMOVING_ENROLLMENTS = 8, - GETTING_AUTHENTICATOR_ID = 9, - INVALIDATING_AUTHENTICATOR_ID = 10, - RESETTING_LOCKOUT = 11, -} diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl index 98a45307b9..271a9bf1cf 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl @@ -32,27 +32,14 @@ interface IFingerprint { /** * createSession: * - * Creates a session which can then be used by the framework to perform operations such as - * enroll, authenticate, etc for the given sensorId and userId. + * Creates a instance of ISession which can be used by the framework to perform operations + * such as ISession#enroll, ISession#authenticate, etc. for the given sensorId and userId. * - * Calling this method while there is an active session is considered an error. If the - * framework is in a bad state and for some reason cannot close its session, it should use - * the reset method below. - * - * A physical sensor identified by sensorId typically supports only a single in-flight session - * at a time. As such, if a session is currently in a state other than SessionState::IDLING, the - * HAL MUST finish or cancel the current operation and return to SessionState::IDLING before the - * new session is created. For example: - * 1) If a session for sensorId=0, userId=0 is currently in a cancellable state (see - * ICancellationSignal) such as SessionState::AUTHENTICATING and the framework requests a - * new session for sensorId=0, userId=10, the HAL must end the current session with - * Error::CANCELED, invoke ISessionCallback#onStateChanged with SessionState::IDLING, and - * then return a new session for sensorId=0, userId=10. - * 2) If a session for sensorId=0, userId=0 is currently in a non-cancellable state such as - * SessionState::REMOVING_ENROLLMENTS, and the framework requests a new session for - * sensorId=0, userId=10, the HAL must finish the current operation before invoking - * ISessionCallback#onStateChanged with SessionState::IDLING, and return a new session for - * sensorId=0, userId=10. + * Calling this method while there is an active session is considered an error. If the framework + * wants to create a new session when it already has an active session, it must first cancel the + * current operation if it's cancellable, or wait until it completes. Then, the framework must + * explicitly close the session with ISession#close. Once the framework receives + * ISessionCallback#onSessionClosed, a new session can be created. * * Implementations must store user-specific state or metadata in /data/vendor_de//fpdata * as specified by the SeLinux policy. This directory is created/removed by vold (see diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl index ef2e6fc499..940548ba88 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl @@ -22,23 +22,28 @@ import android.hardware.keymaster.HardwareAuthToken; /** * Operations that can be performed for unique sessions retrieved via IFingerprint#createSession. * Methods defined within this interface can be split into the following categories: - * 1) Methods associated with a state (see the SessionState enum). State-based operations are - * handled by the HAL in FIFO order. - * 1a) Cancellable state-based operations. If a cancellable operation is in-progress and the - * framework requests a subsequent state-based operation, the implementation should finish - * the operation via ISessionCallback#onError with Error::CANCELED. - * 1b) Non-cancellable state-based operations. These operations should fully complete before the - * next state-based operation can be started. - * 2) Methods without a state. These methods may be invoked by the framework depending on its - * use case. For example on devices with sensors of FingerprintSensorType::UNDER_DISPLAY_*, - * ISession#onFingerDown may be invoked while the HAL is in SessionState::ENROLLING, - * SessionState::AUTHENTICATING, or SessionState::DETECTING_INTERACTION. + * 1) Non-interrupting operations. These operations are handled by the HAL in FIFO order. + * 1a) Cancellable operations. These are usually the operations that can execute for several + * minutes. To allow for cancellation, they return an instance of ICancellationSignal that + * lets the framework cancel them by calling ICancellationSignal#cancel. If such an operation + * is cancelled, it must notify the framework by calling ISessionCallback#onError with + * Error::CANCELED. + * 1b) Non-cancellable operations. Such operations cannot be cancelled once started. + * 2) Interrupting operations. These operations may be invoked by the framework immediately, + * regardless of whether another operation is executing. For example, on devices with sensors + * of FingerprintSensorType::UNDER_DISPLAY_*, ISession#onFingerDown may be invoked while the + * HAL is executing ISession#enroll, ISession#authenticate or ISession#detectInteraction. * - * If the HAL has multiple operations in its queue, it is not required to notify the framework - * of SessionState::IDLING between each operation. However, it must notify the framework when all - * work is completed. See ISessionCallback#onStateChanged. For example, the following is a valid - * sequence of ISessionCallback#onStateChanged invocations: SessionState::IDLING --> - * SessionState::ENROLLING --> SessionState::ENUMERATING_ENROLLMENTS --> SessionState::IDLING. + * The lifecycle of a non-interrupting operation ends when one of its terminal callbacks is called. + * For example, ISession#authenticate is considered completed when either of the following callbacks + * is called: ISessionCallback#onError or ISessionCallback#onAuthenticationSucceeded. + * + * The lifecycle of an interrupting operation ends when it returns. Interrupting operations do not + * have callbacks. + * + * ISession only supports execution of one non-interrupting operation at a time, regardless of + * whether it's cancellable. The framework must wait for a corresponding callback indicating the end of + * the current non-interrupting operation before a new non-interrupting operation can be started. */ @VintfStability interface ISession { @@ -84,9 +89,8 @@ interface ISession { * | 0 | 10 | | | * ---------------------------------------------- * - * @param cookie A unique number identifying this operation */ - void generateChallenge(in int cookie); + void generateChallenge(); /** * revokeChallenge: @@ -95,23 +99,17 @@ interface ISession { * parameters is requested, the implementation must still notify the framework using the * provided callback. * - * @param cookie A unique number identifying this operation * @param challenge Challenge that should be revoked. */ - void revokeChallenge(in int cookie, in long challenge); + void revokeChallenge(in long challenge); /** * enroll: * * A request to add a fingerprint enrollment. * - * Once the HAL is able to start processing the enrollment request, it must notify the framework - * via ISessionCallback#onStateChanged with SessionState::ENROLLING. - * * At any point during enrollment, if a non-recoverable error occurs, the HAL must notify the - * framework via ISessionCallback#onError with the applicable enrollment-specific error, and - * then send ISessionCallback#onStateChanged(cookie, SessionState::IDLING) if no subsequent - * operation is in the queue. + * framework via ISessionCallback#onError with the applicable enrollment-specific error. * * Before capturing fingerprint data, the implementation must first verify the authenticity and * integrity of the provided HardwareAuthToken. In addition, it must check that the challenge @@ -132,24 +130,17 @@ interface ISession { * implementation MUST update and associate this (sensorId, userId) pair with a new new * entropy-encoded random identifier. See ISession#getAuthenticatorId for more information. * - * @param cookie An identifier used to track subsystem operations related to this call path. The - * client must guarantee that it is unique per ISession. * @param hat See above documentation. */ - ICancellationSignal enroll(in int cookie, in HardwareAuthToken hat); + ICancellationSignal enroll(in HardwareAuthToken hat); /** * authenticate: * * A request to start looking for fingerprints to authenticate. * - * Once the HAL is able to start processing the authentication request, it must notify framework - * via ISessionCallback#onStateChanged with SessionState::AUTHENTICATING. - * * At any point during authentication, if a non-recoverable error occurs, the HAL must notify - * the framework via ISessionCallback#onError with the applicable authentication-specific error, - * and then send ISessionCallback#onStateChanged(cookie, SessionState::IDLING) if no - * subsequent operation is in the queue. + * the framework via ISessionCallback#onError with the applicable authentication-specific error. * * During authentication, the implementation may notify the framework via * ISessionCallback#onAcquired with messages that may be used to guide the user. This callback @@ -171,8 +162,6 @@ interface ISession { * must be set with the operationId passed in during #authenticate. If the sensor is NOT * SensorStrength::STRONG, the HardwareAuthToken MUST be null. * - * @param cookie An identifier used to track subsystem operations related to this call path. The - * client must guarantee that it is unique per ISession. * @param operationId For sensors configured as SensorStrength::STRONG, this must be used ONLY * upon successful authentication and wrapped in the HardwareAuthToken's * "challenge" field and sent to the framework via @@ -184,7 +173,7 @@ interface ISession { * setUserAuthenticationParameters in KeyGenParameterSpec.Builder and * KeyProtection.Builder. */ - ICancellationSignal authenticate(in int cookie, in long operationId); + ICancellationSignal authenticate(in long operationId); /** * detectInteraction: @@ -193,17 +182,12 @@ interface ISession { * if SensorProps#supportsDetectInteraction is true. If invoked on implementations that do not * support this functionality, the HAL must respond with ISession#onError(UNABLE_TO_PROCESS, 0). * - * Once the HAL is able to start processing this request, it must notify the framework via - * ISessionCallback#onStateChanged with SessionState::DETECTING_INTERACTION. - * * The framework will use this method in cases where determing user presence is required, but * identifying/authentication is not. For example, when the device is encrypted (first boot) or * in lockdown mode. * * At any point during detectInteraction, if a non-recoverable error occurs, the HAL must notify - * the framework via ISessionCallback#onError with the applicable error, and then send - * ISessionCallback#onStateChanged(cookie, SessionState::IDLING) if no subsequent operation is - * in the queue. + * the framework via ISessionCallback#onError with the applicable error. * * The implementation must only check for a fingerprint-like image was detected (e.g. to * minimize interactions due to non-fingerprint objects), and the lockout counter must not @@ -221,10 +205,8 @@ interface ISession { * Note that if the operation is canceled, the implementation must notify the framework via * ISessionCallback#onError with Error::CANCELED. * - * @param cookie An identifier used to track subsystem operations related to this call path. - * The framework will guarantee that it is unique per ISession. */ - ICancellationSignal detectInteraction(in int cookie); + ICancellationSignal detectInteraction(); /* * enumerateEnrollments: @@ -232,32 +214,22 @@ interface ISession { * A request to enumerate (list) the enrollments for this (sensorId, userId) pair. The * framework typically uses this to ensure that its cache is in sync with the HAL. * - * Once the HAL is able to start processing this request, it must notify the framework via - * ISessionCallback#onStateChanged with SessionState::ENUMERATING_ENROLLMENTS. - * * The implementation must then notify the framework with a list of enrollments applicable * for the current session via ISessionCallback#onEnrollmentsEnumerated. * - * @param cookie An identifier used to track subsystem operations related to this call path. - * The framework will guarantee that it is unique per ISession. */ - void enumerateEnrollments(in int cookie); + void enumerateEnrollments(); /** * removeEnrollments: * * A request to remove the enrollments for this (sensorId, userId) pair. * - * Once the HAL is able to start processing this request, it must notify the framework via - * ISessionCallback#onStateChanged with SessionState::REMOVING_ENROLLMENTS. - * * After removing the enrollmentIds from everywhere necessary (filesystem, secure subsystems, * etc), the implementation must notify the framework via ISessionCallback#onEnrollmentsRemoved. * - * @param cookie An identifier used to track subsystem operations related to this call path. - * The framework will guarantee that it is unique per ISession. */ - void removeEnrollments(in int cookie, in int[] enrollmentIds); + void removeEnrollments(in int[] enrollmentIds); /** * getAuthenticatorId: @@ -285,10 +257,8 @@ interface ISession { * 3) MUST not change if a fingerprint is deleted. * 4) MUST be an entropy-encoded random number * - * @param cookie An identifier used to track subsystem operations related to this call path. The - * client must guarantee that it is unique per ISession. */ - void getAuthenticatorId(in int cookie); + void getAuthenticatorId(); /** * invalidateAuthenticatorId: @@ -312,10 +282,8 @@ interface ISession { * for more details). As such, the framework would coordinate invalidation across multiple * biometric HALs as necessary. * - * @param cookie An identifier used to track subsystem operations related to this call path. The - * client must guarantee that it is unique per ISession. */ - void invalidateAuthenticatorId(in int cookie); + void invalidateAuthenticatorId(); /** * resetLockout: @@ -326,8 +294,7 @@ interface ISession { * 2) Verify that the timestamp provided within the HAT is relatively recent (e.g. on the * order of minutes, not hours). * If either of the checks fail, the HAL must invoke ISessionCallback#onError with - * Error::UNABLE_TO_PROCESS and return to SessionState::IDLING if no subsequent work is in the - * queue. + * Error::UNABLE_TO_PROCESS and return to the idling state. * * Upon successful verification, the HAL must clear the lockout counter and notify the framework * via ISessionCallback#onLockoutCleared. @@ -358,29 +325,26 @@ interface ISession { * See the Android CDD section 7.3.10 for the full set of lockout and rate-limiting * requirements. * - * @param cookie An identifier used to track subsystem operations related to this call path. The - * client must guarantee that it is unique per ISession. * @param hat HardwareAuthToken See above documentation. */ - void resetLockout(in int cookie, in HardwareAuthToken hat); + void resetLockout(in HardwareAuthToken hat); /* * Close this session and allow the HAL to release the resources associated with this session. * - * A session can only be closed when it's in SessionState::IDLING. Closing a session will - * result in a ISessionCallback#onStateChanged call with SessionState::CLOSED. + * A session can only be closed when the HAL is idling, i.e. not performing any of the + * non-interruptable operations. If the HAL is busy performing a cancellable operation, the + * operation must be explicitly cancelled with a call to ICancellationSignal#cancel before + * the session can be closed. * - * If a session is unresponsive or stuck in a state other than SessionState::CLOSED, - * IFingerprint#reset could be used as a last resort to terminate the session and recover the - * HAL from a bad state. + * After a session is closed, the HAL must notify the framework by calling + * ISessionCallback#onSessionClosed. * * All sessions must be explicitly closed. Calling IFingerprint#createSession while there is an * active session is considered an error. * - * @param cookie An identifier used to track subsystem operations related to this call path. The - * client must guarantee that it is unique per ISession. */ - void close(in int cookie); + void close(); /** * Methods for notifying the under-display fingerprint sensor about external events. @@ -394,9 +358,8 @@ interface ISession { * of other types, the HAL must treat this as a no-op and return immediately. * * For sensors of type FingerprintSensorType::UNDER_DISPLAY_*, this method is used to notify the - * HAL of display touches. This method can be invoked when the session is in one of the - * following states: SessionState::ENROLLING, SessionState::AUTHENTICATING, or - * SessionState::DETECTING_INTERACTION. + * HAL of display touches. This method can be invoked when the HAL is performing any one of: + * ISession#authenticate, ISession#enroll, ISession#detectInteraction. * * Note that the framework will only invoke this method if the event occurred on the display on * which this sensor is located. diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl index cf3a271ef6..95657b3d7b 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl @@ -18,16 +18,10 @@ package android.hardware.biometrics.fingerprint; import android.hardware.biometrics.fingerprint.AcquiredInfo; import android.hardware.biometrics.fingerprint.Error; -import android.hardware.biometrics.fingerprint.SessionState; import android.hardware.keymaster.HardwareAuthToken; @VintfStability interface ISessionCallback { - /** - * Used to notify the framework of session state changes. See ISession for more information. - */ - void onStateChanged(in int cookie, in SessionState state); - /** * Notifies the framework when a challenge is successfully generated. */ @@ -39,10 +33,10 @@ interface ISessionCallback { void onChallengeRevoked(in long challenge); /** - * This method must only be used to notify the framework during the following states: - * 1) SessionState::ENROLLING - * 2) SessionState::AUTHENTICATING - * 3) SessionState::DETECTING_INTERACTION + * This method must only be used to notify the framework during the following operations: + * 1) ISession#enroll + * 2) ISession#authenticate + * 3) ISession#detectInteraction * * These messages may be used to provide user guidance multiple times if necessary per * operation. @@ -56,18 +50,18 @@ interface ISessionCallback { void onAcquired(in AcquiredInfo info, in int vendorCode); /** - * This method must only be used to notify the framework during the following states: - * 1) SessionState::ENROLLING - * 2) SessionState::AUTHENTICATING - * 3) SessionState::DETECTING_INTERACTION - * 4) SessionState::INVALIDATING_AUTHENTICATOR_ID - * 5) SessionState::RESETTING_LOCKOUT + * This method must only be used to notify the framework during the following operations: + * 1) ISession#enroll + * 2) ISession#authenticate + * 3) ISession#detectInteraction + * 4) ISession#invalidateAuthenticatorId + * 5) ISession#resetLockout * * These messages may be used to notify the framework or user that a non-recoverable error - * has occurred. The operation is finished, and the HAL must proceed with the next operation - * or return to SessionState::IDLING if the queue is empty. + * has occurred. The operation is finished, and the HAL can proceed with the next operation + * or return to the idling state. * - * Note that cancellation (see common::ICancellationSignal) and preemption most be followed with + * Note that cancellation (see common::ICancellationSignal) and preemption must be followed with * an Error::CANCELED message. * * @param error See the Error enum. @@ -79,8 +73,7 @@ interface ISessionCallback { void onError(in Error error, in int vendorCode); /** - * This method must only be used to notify the framework during the following state: - * 1) SessionState::ENROLLING + * This method must only be used to notify the framework during the ISession#enroll operation. * * @param enrollmentId Unique stable identifier for the enrollment that's being added by this * ISession#enroll invocation. @@ -89,7 +82,7 @@ interface ISessionCallback { void onEnrollmentProgress(in int enrollmentId, int remaining); /** - * This method must only be used to notify the framework during SessionState::AUTHENTICATING. + * This method must only be used to notify the framework during ISession#authenticate. * * Used to notify the framework upon successful authentication. Note that the authentication * lifecycle ends when either 1) a fingerprint is accepted, or 2) an error occurred. The @@ -104,7 +97,7 @@ interface ISessionCallback { void onAuthenticationSucceeded(in int enrollmentId, in HardwareAuthToken hat); /** - * This method must only be used to notify the framework during SessionState::AUTHENTICATING. + * This method must only be used to notify the framework during ISession#authenticate. * * Used to notify the framework upon rejected attempts. Note that the authentication * lifecycle ends when either 1) a fingerprint is accepted, or 2) an occurred. The @@ -113,7 +106,7 @@ interface ISessionCallback { void onAuthenticationFailed(); /** - * This method must only be used to notify the framework during SessionState::AUTHENTICATING. + * This method must only be used to notify the framework during ISession#authenticate. * * Authentication is locked out due to too many unsuccessful attempts. This is a rate-limiting * lockout, and authentication can be restarted after a period of time. See @@ -126,7 +119,7 @@ interface ISessionCallback { void onLockoutTimed(in long durationMillis); /** - * This method must only be used to notify the framework during SessionState::AUTHENTICATING. + * This method must only be used to notify the framework during ISession#authenticate. * * Authentication is disabled until the user unlocks with their device credential * (PIN/Pattern/Password). See ISession#resetLockout. @@ -153,7 +146,7 @@ interface ISessionCallback { /** * This method must only be used to notify the framework during - * SessionState::DETECTING_INTERACTION + * ISession#detectInteraction * * Notifies the framework that user interaction occurred. See ISession#detectInteraction. */ @@ -161,7 +154,7 @@ interface ISessionCallback { /** * This method must only be used to notify the framework during - * SessionState::ENUMERATING_ENROLLMENTS. + * ISession#enumerateEnrollments. * * Notifies the framework of the current enrollments. See ISession#enumerateEnrollments. * @@ -171,7 +164,7 @@ interface ISessionCallback { /** * This method must only be used to notify the framework during - * SessionState::REMOVING_ENROLLMENTS. + * ISession#removeEnrollments. * * Notifies the framework that the specified enrollments are removed. * @@ -181,7 +174,7 @@ interface ISessionCallback { /** * This method must only be used to notify the framework during - * SessionState::GETTING_AUTHENTICATOR_ID. + * ISession#getAuthenticatorId. * * Notifies the framework with the authenticatorId corresponding to this session's * (userId, sensorId) pair. @@ -192,7 +185,7 @@ interface ISessionCallback { /** * This method must only be used to notify the framework during - * SessionState::INVALIDATING_AUTHENTICATOR_ID. + * ISession#invalidateAuthenticatorId. * * See ISession#invalidateAuthenticatorId for more information. * diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SessionState.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SessionState.aidl deleted file mode 100644 index 19a6ce3682..0000000000 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SessionState.aidl +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.hardware.biometrics.fingerprint; - -@VintfStability -@Backing(type="byte") -enum SessionState { - /** - * The HAL is not processing any session requests. - */ - IDLING, - - /** - * The session has been closed by the client. - */ - CLOSED, - - /** - * The HAL is processing the ISession#generateChallenge request. - */ - GENERATING_CHALLENGE, - - /** - * The HAL is processing the ISession#revokeChallenge request. - */ - REVOKING_CHALLENGE, - - /** - * The HAL is processing the ISession#enroll request. - */ - ENROLLING, - - /** - * The HAL is processing the ISession#authenticate request. - */ - AUTHENTICATING, - - /** - * The HAL is processing the ISession#detectInteraction request. - */ - DETECTING_INTERACTION, - - /** - * The HAL is processing the ISession#enumerateEnrollments request. - */ - ENUMERATING_ENROLLMENTS, - - /** - * The HAL is processing the ISession#removeEnrollments request. - */ - REMOVING_ENROLLMENTS, - - /** - * The HAL is processing the ISession#getAuthenticatorId request. - */ - GETTING_AUTHENTICATOR_ID, - - /** - * The HAL is processing the ISession#invalidateAuthenticatorId request. - */ - INVALIDATING_AUTHENTICATOR_ID, - - /** - * The HAL is processing the ISession#resetLockout request. - */ - RESETTING_LOCKOUT -} -- GitLab From caa67677bd4af41ca9b90fe61a13b6f9ab1d8932 Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Tue, 23 Mar 2021 19:00:36 -0700 Subject: [PATCH 556/790] Remove SessionState from IFingerprint VTS Bug: 183570051 Test: atest VtsHalBiometricsFingerprintTargetTes Change-Id: I75d7d2e9f52db681538f6627ab4cc541ac260dd6 --- .../VtsHalBiometricsFingerprintTargetTest.cpp | 66 +++++-------------- 1 file changed, 17 insertions(+), 49 deletions(-) diff --git a/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp b/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp index 885f703d5b..f1cfb17837 100644 --- a/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp +++ b/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp @@ -22,46 +22,20 @@ #include #include +#include #include namespace aidl::android::hardware::biometrics::fingerprint { namespace { +using namespace std::literals::chrono_literals; + constexpr int kSensorId = 0; constexpr int kUserId = 0; -constexpr auto kCallbackTimeout = std::chrono::seconds(1); - -enum class MethodName { - kOnStateChanged, -}; - -struct Invocation { - MethodName methodName; - int32_t cookie; - SessionState state; -}; class SessionCallback : public BnSessionCallback { public: - explicit SessionCallback() : mIsPromiseValid(false) {} - - void setPromise(std::promise>&& promise) { - mPromise = std::move(promise); - mIsPromiseValid = true; - } - - ndk::ScopedAStatus onStateChanged(int32_t cookie, SessionState state) override { - Invocation invocation = {}; - invocation.methodName = MethodName::kOnStateChanged; - invocation.cookie = cookie; - invocation.state = state; - mInvocations.push_back(invocation); - if (state == SessionState::IDLING) { - assert(mIsPromiseValid); - mPromise.set_value(mInvocations); - } - return ndk::ScopedAStatus::ok(); - } + explicit SessionCallback(std::promise&& promise) : mPromise(std::move(promise)) {} ndk::ScopedAStatus onChallengeGenerated(int64_t /*challenge*/) override { return ndk::ScopedAStatus::ok(); @@ -119,12 +93,13 @@ class SessionCallback : public BnSessionCallback { return ndk::ScopedAStatus::ok(); } - ndk::ScopedAStatus onSessionClosed() override { return ndk::ScopedAStatus::ok(); } + ndk::ScopedAStatus onSessionClosed() override { + mPromise.set_value(); + return ndk::ScopedAStatus::ok(); + } private: - bool mIsPromiseValid; - std::vector mInvocations; - std::promise> mPromise; + std::promise mPromise; }; class Fingerprint : public testing::TestWithParam { @@ -139,33 +114,26 @@ class Fingerprint : public testing::TestWithParam { }; TEST_P(Fingerprint, AuthenticateTest) { - // Prepare the callback - std::promise> promise; + auto promise = std::promise{}; auto future = promise.get_future(); - std::shared_ptr cb = ndk::SharedRefBase::make(); - cb->setPromise(std::move(promise)); + // Prepare the callback. + auto cb = ndk::SharedRefBase::make(std::move(promise)); // Create a session std::shared_ptr session; ASSERT_TRUE(mHal->createSession(kSensorId, kUserId, cb, &session).isOk()); // Call authenticate - int32_t cookie = 123; std::shared_ptr cancellationSignal; - ASSERT_TRUE(session->authenticate(cookie, 0, &cancellationSignal).isOk()); + ASSERT_TRUE(session->authenticate(-1 /* operationId */, &cancellationSignal).isOk()); // Get the results - ASSERT_TRUE(future.wait_for(kCallbackTimeout) == std::future_status::ready); - std::vector invocations = future.get(); + // TODO(b/166799066): test authenticate. // Close the session - ASSERT_TRUE(session->close(0).isOk()); - - ASSERT_FALSE(invocations.empty()); - EXPECT_EQ(invocations.front().methodName, MethodName::kOnStateChanged); - EXPECT_EQ(invocations.front().state, SessionState::AUTHENTICATING); - EXPECT_EQ(invocations.back().methodName, MethodName::kOnStateChanged); - EXPECT_EQ(invocations.back().state, SessionState::IDLING); + ASSERT_TRUE(session->close().isOk()); + auto status = future.wait_for(1s); + ASSERT_EQ(status, std::future_status::ready); } GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Fingerprint); -- GitLab From aea213b4012eb55757ba87e9437a538a9d185d5d Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Tue, 23 Mar 2021 19:01:42 -0700 Subject: [PATCH 557/790] Remove SessionState from IFingerprint example Bug: 183570051 Test: atest VtsHalBiometricsFingerprintTargetTest Change-Id: I1dd4aa0dc8bd622824ad4c0c0dde78914c49838c --- .../fingerprint/aidl/default/Fingerprint.cpp | 2 +- .../fingerprint/aidl/default/Session.cpp | 117 +++++++++--------- .../default/include/FakeFingerprintEngine.h | 2 +- .../aidl/default/include/Session.h | 43 ++++--- 4 files changed, 89 insertions(+), 75 deletions(-) diff --git a/biometrics/fingerprint/aidl/default/Fingerprint.cpp b/biometrics/fingerprint/aidl/default/Fingerprint.cpp index fbfa52f0e7..734ff600b7 100644 --- a/biometrics/fingerprint/aidl/default/Fingerprint.cpp +++ b/biometrics/fingerprint/aidl/default/Fingerprint.cpp @@ -22,7 +22,7 @@ namespace aidl::android::hardware::biometrics::fingerprint { namespace { constexpr size_t MAX_WORKER_QUEUE_SIZE = 5; constexpr int SENSOR_ID = 1; -constexpr common::SensorStrength SENSOR_STRENGTH = common::SensorStrength::STRONG; +constexpr common::SensorStrength SENSOR_STRENGTH = common::SensorStrength::WEAK; constexpr int MAX_ENROLLMENTS_PER_USER = 5; constexpr FingerprintSensorType SENSOR_TYPE = FingerprintSensorType::REAR; constexpr bool SUPPORTS_NAVIGATION_GESTURES = true; diff --git a/biometrics/fingerprint/aidl/default/Session.cpp b/biometrics/fingerprint/aidl/default/Session.cpp index f030f138f5..ca481e7cf0 100644 --- a/biometrics/fingerprint/aidl/default/Session.cpp +++ b/biometrics/fingerprint/aidl/default/Session.cpp @@ -39,54 +39,56 @@ Session::Session(int sensorId, int userId, std::shared_ptr cb, } void Session::scheduleStateOrCrash(SessionState state) { - CHECK(mScheduledState == SessionState::IDLING); - CHECK(mCurrentState == SessionState::IDLING); + // TODO(b/166800618): call enterIdling from the terminal callbacks and restore these checks. + // CHECK(mScheduledState == SessionState::IDLING); + // CHECK(mCurrentState == SessionState::IDLING); mScheduledState = state; } -void Session::enterStateOrCrash(int cookie, SessionState state) { +void Session::enterStateOrCrash(SessionState state) { CHECK(mScheduledState == state); mCurrentState = state; mScheduledState = SessionState::IDLING; - mCb->onStateChanged(cookie, mCurrentState); } -void Session::enterIdling(int cookie) { - mCurrentState = SessionState::IDLING; - mCb->onStateChanged(cookie, mCurrentState); +void Session::enterIdling() { + // TODO(b/166800618): call enterIdling from the terminal callbacks and rethink this conditional. + if (mCurrentState != SessionState::CLOSED) { + mCurrentState = SessionState::IDLING; + } } bool Session::isClosed() { return mCurrentState == SessionState::CLOSED; } -ndk::ScopedAStatus Session::generateChallenge(int32_t cookie) { +ndk::ScopedAStatus Session::generateChallenge() { LOG(INFO) << "generateChallenge"; scheduleStateOrCrash(SessionState::GENERATING_CHALLENGE); - mWorker->schedule(Callable::from([this, cookie] { - enterStateOrCrash(cookie, SessionState::GENERATING_CHALLENGE); + mWorker->schedule(Callable::from([this] { + enterStateOrCrash(SessionState::GENERATING_CHALLENGE); mEngine->generateChallengeImpl(mCb.get()); - enterIdling(cookie); + enterIdling(); })); return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::revokeChallenge(int32_t cookie, int64_t challenge) { +ndk::ScopedAStatus Session::revokeChallenge(int64_t challenge) { LOG(INFO) << "revokeChallenge"; scheduleStateOrCrash(SessionState::REVOKING_CHALLENGE); - mWorker->schedule(Callable::from([this, cookie, challenge] { - enterStateOrCrash(cookie, SessionState::REVOKING_CHALLENGE); + mWorker->schedule(Callable::from([this, challenge] { + enterStateOrCrash(SessionState::REVOKING_CHALLENGE); mEngine->revokeChallengeImpl(mCb.get(), challenge); - enterIdling(cookie); + enterIdling(); })); return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::enroll(int32_t cookie, const keymaster::HardwareAuthToken& hat, +ndk::ScopedAStatus Session::enroll(const keymaster::HardwareAuthToken& hat, std::shared_ptr* out) { LOG(INFO) << "enroll"; scheduleStateOrCrash(SessionState::ENROLLING); @@ -94,21 +96,21 @@ ndk::ScopedAStatus Session::enroll(int32_t cookie, const keymaster::HardwareAuth std::promise cancellationPromise; auto cancFuture = cancellationPromise.get_future(); - mWorker->schedule(Callable::from([this, cookie, hat, cancFuture = std::move(cancFuture)] { - enterStateOrCrash(cookie, SessionState::ENROLLING); + mWorker->schedule(Callable::from([this, hat, cancFuture = std::move(cancFuture)] { + enterStateOrCrash(SessionState::ENROLLING); if (shouldCancel(cancFuture)) { mCb->onError(Error::CANCELED, 0 /* vendorCode */); } else { mEngine->enrollImpl(mCb.get(), hat); } - enterIdling(cookie); + enterIdling(); })); *out = SharedRefBase::make(std::move(cancellationPromise)); return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::authenticate(int32_t cookie, int64_t operationId, +ndk::ScopedAStatus Session::authenticate(int64_t operationId, std::shared_ptr* out) { LOG(INFO) << "authenticate"; scheduleStateOrCrash(SessionState::AUTHENTICATING); @@ -116,112 +118,111 @@ ndk::ScopedAStatus Session::authenticate(int32_t cookie, int64_t operationId, std::promise cancPromise; auto cancFuture = cancPromise.get_future(); - mWorker->schedule( - Callable::from([this, cookie, operationId, cancFuture = std::move(cancFuture)] { - enterStateOrCrash(cookie, SessionState::AUTHENTICATING); - if (shouldCancel(cancFuture)) { - mCb->onError(Error::CANCELED, 0 /* vendorCode */); - } else { - mEngine->authenticateImpl(mCb.get(), operationId); - } - enterIdling(cookie); - })); + mWorker->schedule(Callable::from([this, operationId, cancFuture = std::move(cancFuture)] { + enterStateOrCrash(SessionState::AUTHENTICATING); + if (shouldCancel(cancFuture)) { + mCb->onError(Error::CANCELED, 0 /* vendorCode */); + } else { + mEngine->authenticateImpl(mCb.get(), operationId); + } + enterIdling(); + })); *out = SharedRefBase::make(std::move(cancPromise)); return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::detectInteraction(int32_t cookie, - std::shared_ptr* out) { +ndk::ScopedAStatus Session::detectInteraction(std::shared_ptr* out) { LOG(INFO) << "detectInteraction"; scheduleStateOrCrash(SessionState::DETECTING_INTERACTION); std::promise cancellationPromise; auto cancFuture = cancellationPromise.get_future(); - mWorker->schedule(Callable::from([this, cookie, cancFuture = std::move(cancFuture)] { - enterStateOrCrash(cookie, SessionState::DETECTING_INTERACTION); + mWorker->schedule(Callable::from([this, cancFuture = std::move(cancFuture)] { + enterStateOrCrash(SessionState::DETECTING_INTERACTION); if (shouldCancel(cancFuture)) { mCb->onError(Error::CANCELED, 0 /* vendorCode */); } else { mEngine->detectInteractionImpl(mCb.get()); } - enterIdling(cookie); + enterIdling(); })); *out = SharedRefBase::make(std::move(cancellationPromise)); return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::enumerateEnrollments(int32_t cookie) { +ndk::ScopedAStatus Session::enumerateEnrollments() { LOG(INFO) << "enumerateEnrollments"; scheduleStateOrCrash(SessionState::ENUMERATING_ENROLLMENTS); - mWorker->schedule(Callable::from([this, cookie] { - enterStateOrCrash(cookie, SessionState::ENUMERATING_ENROLLMENTS); + mWorker->schedule(Callable::from([this] { + enterStateOrCrash(SessionState::ENUMERATING_ENROLLMENTS); mEngine->enumerateEnrollmentsImpl(mCb.get()); - enterIdling(cookie); + enterIdling(); })); return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::removeEnrollments(int32_t cookie, - const std::vector& enrollmentIds) { +ndk::ScopedAStatus Session::removeEnrollments(const std::vector& enrollmentIds) { LOG(INFO) << "removeEnrollments"; scheduleStateOrCrash(SessionState::REMOVING_ENROLLMENTS); - mWorker->schedule(Callable::from([this, cookie, enrollmentIds] { - enterStateOrCrash(cookie, SessionState::REMOVING_ENROLLMENTS); + mWorker->schedule(Callable::from([this, enrollmentIds] { + enterStateOrCrash(SessionState::REMOVING_ENROLLMENTS); mEngine->removeEnrollmentsImpl(mCb.get(), enrollmentIds); - enterIdling(cookie); + enterIdling(); })); return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::getAuthenticatorId(int32_t cookie) { +ndk::ScopedAStatus Session::getAuthenticatorId() { LOG(INFO) << "getAuthenticatorId"; scheduleStateOrCrash(SessionState::GETTING_AUTHENTICATOR_ID); - mWorker->schedule(Callable::from([this, cookie] { - enterStateOrCrash(cookie, SessionState::GETTING_AUTHENTICATOR_ID); + mWorker->schedule(Callable::from([this] { + enterStateOrCrash(SessionState::GETTING_AUTHENTICATOR_ID); mEngine->getAuthenticatorIdImpl(mCb.get()); - enterIdling(cookie); + enterIdling(); })); return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::invalidateAuthenticatorId(int32_t cookie) { +ndk::ScopedAStatus Session::invalidateAuthenticatorId() { LOG(INFO) << "invalidateAuthenticatorId"; scheduleStateOrCrash(SessionState::INVALIDATING_AUTHENTICATOR_ID); - mWorker->schedule(Callable::from([this, cookie] { - enterStateOrCrash(cookie, SessionState::INVALIDATING_AUTHENTICATOR_ID); + mWorker->schedule(Callable::from([this] { + enterStateOrCrash(SessionState::INVALIDATING_AUTHENTICATOR_ID); mEngine->invalidateAuthenticatorIdImpl(mCb.get()); - enterIdling(cookie); + enterIdling(); })); return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::resetLockout(int32_t cookie, const keymaster::HardwareAuthToken& hat) { +ndk::ScopedAStatus Session::resetLockout(const keymaster::HardwareAuthToken& hat) { LOG(INFO) << "resetLockout"; scheduleStateOrCrash(SessionState::RESETTING_LOCKOUT); - mWorker->schedule(Callable::from([this, cookie, hat] { - enterStateOrCrash(cookie, SessionState::RESETTING_LOCKOUT); + mWorker->schedule(Callable::from([this, hat] { + enterStateOrCrash(SessionState::RESETTING_LOCKOUT); mEngine->resetLockoutImpl(mCb.get(), hat); - enterIdling(cookie); + enterIdling(); })); return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::close(int32_t /*cookie*/) { +ndk::ScopedAStatus Session::close() { LOG(INFO) << "close"; - CHECK(mCurrentState == SessionState::IDLING) << "Can't close a non-idling session. Crashing."; + // TODO(b/166800618): call enterIdling from the terminal callbacks and restore this check. + // CHECK(mCurrentState == SessionState::IDLING) << "Can't close a non-idling session. + // Crashing."; mCurrentState = SessionState::CLOSED; mCb->onSessionClosed(); return ndk::ScopedAStatus::ok(); diff --git a/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h index 42e1aa5357..6667f7a7f0 100644 --- a/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h +++ b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h @@ -37,7 +37,7 @@ class FakeFingerprintEngine { cb->onEnrollmentProgress(0 /* enrollmentId */, 0 /* remaining */); } - void authenticateImpl(ISessionCallback* cb, int64_t /*operationId*/) { + void authenticateImpl(ISessionCallback* cb, int64_t /* operationId */) { LOG(INFO) << "authenticateImpl"; cb->onAuthenticationSucceeded(0 /* enrollmentId */, {} /* hat */); } diff --git a/biometrics/fingerprint/aidl/default/include/Session.h b/biometrics/fingerprint/aidl/default/include/Session.h index 97d5645c92..9e464229e1 100644 --- a/biometrics/fingerprint/aidl/default/include/Session.h +++ b/biometrics/fingerprint/aidl/default/include/Session.h @@ -27,37 +27,50 @@ namespace aidl::android::hardware::biometrics::fingerprint { namespace common = aidl::android::hardware::biometrics::common; namespace keymaster = aidl::android::hardware::keymaster; +enum class SessionState { + IDLING, + CLOSED, + GENERATING_CHALLENGE, + REVOKING_CHALLENGE, + ENROLLING, + AUTHENTICATING, + DETECTING_INTERACTION, + ENUMERATING_ENROLLMENTS, + REMOVING_ENROLLMENTS, + GETTING_AUTHENTICATOR_ID, + INVALIDATING_AUTHENTICATOR_ID, + RESETTING_LOCKOUT, +}; + class Session : public BnSession { public: Session(int sensorId, int userId, std::shared_ptr cb, FakeFingerprintEngine* engine, WorkerThread* worker); - ndk::ScopedAStatus generateChallenge(int32_t cookie) override; + ndk::ScopedAStatus generateChallenge() override; - ndk::ScopedAStatus revokeChallenge(int32_t cookie, int64_t challenge) override; + ndk::ScopedAStatus revokeChallenge(int64_t challenge) override; - ndk::ScopedAStatus enroll(int32_t cookie, const keymaster::HardwareAuthToken& hat, + ndk::ScopedAStatus enroll(const keymaster::HardwareAuthToken& hat, std::shared_ptr* out) override; - ndk::ScopedAStatus authenticate(int32_t cookie, int64_t operationId, + ndk::ScopedAStatus authenticate(int64_t operationId, std::shared_ptr* out) override; ndk::ScopedAStatus detectInteraction( - int32_t cookie, std::shared_ptr* out) override; + std::shared_ptr* out) override; - ndk::ScopedAStatus enumerateEnrollments(int32_t cookie) override; + ndk::ScopedAStatus enumerateEnrollments() override; - ndk::ScopedAStatus removeEnrollments(int32_t cookie, - const std::vector& enrollmentIds) override; + ndk::ScopedAStatus removeEnrollments(const std::vector& enrollmentIds) override; - ndk::ScopedAStatus getAuthenticatorId(int32_t cookie) override; + ndk::ScopedAStatus getAuthenticatorId() override; - ndk::ScopedAStatus invalidateAuthenticatorId(int32_t cookie) override; + ndk::ScopedAStatus invalidateAuthenticatorId() override; - ndk::ScopedAStatus resetLockout(int32_t cookie, - const keymaster::HardwareAuthToken& hat) override; + ndk::ScopedAStatus resetLockout(const keymaster::HardwareAuthToken& hat) override; - ndk::ScopedAStatus close(int32_t cookie) override; + ndk::ScopedAStatus close() override; ndk::ScopedAStatus onPointerDown(int32_t pointerId, int32_t x, int32_t y, float minor, float major) override; @@ -76,11 +89,11 @@ class Session : public BnSession { // Crashes the HAL if the provided state doesn't match the previously scheduled state. // Otherwise, transitions into the provided state, clears the scheduled state, and notifies // the client about the transition by calling ISessionCallback#onStateChanged. - void enterStateOrCrash(int cookie, SessionState state); + void enterStateOrCrash(SessionState state); // Sets the current state to SessionState::IDLING and notifies the client about the transition // by calling ISessionCallback#onStateChanged. - void enterIdling(int cookie); + void enterIdling(); // The sensor and user IDs for which this session was created. int32_t mSensorId; -- GitLab From c125d3a17d5451818c81bc239a92f0e02ca1a388 Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Tue, 23 Mar 2021 22:29:50 -0700 Subject: [PATCH 558/790] Remove SessionState from IFace Bug: 183570051 Test: atest VtsHalBiometricsFaceTargetTest Change-Id: I87a1610b280072e3ccc3d280ae492ae5f6f2b6cc --- .../hardware/biometrics/face/ISession.aidl | 26 ++-- .../biometrics/face/ISessionCallback.aidl | 1 - .../biometrics/face/SessionState.aidl | 51 ------- .../hardware/biometrics/face/ISession.aidl | 136 ++++++------------ .../biometrics/face/ISessionCallback.aidl | 57 ++++---- .../biometrics/face/SessionState.aidl | 91 ------------ 6 files changed, 83 insertions(+), 279 deletions(-) delete mode 100644 biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SessionState.aidl delete mode 100644 biometrics/face/aidl/android/hardware/biometrics/face/SessionState.aidl 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 205429bd7a..9033989563 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 @@ -34,17 +34,17 @@ package android.hardware.biometrics.face; @VintfStability interface ISession { - void generateChallenge(in int cookie); - void revokeChallenge(in int cookie, in long challenge); - android.hardware.biometrics.common.ICancellationSignal enroll(in int cookie, in android.hardware.keymaster.HardwareAuthToken hat, in android.hardware.biometrics.face.EnrollmentType type, in android.hardware.biometrics.face.Feature[] features, in android.hardware.common.NativeHandle previewSurface); - android.hardware.biometrics.common.ICancellationSignal authenticate(in int cookie, in long operationId); - android.hardware.biometrics.common.ICancellationSignal detectInteraction(in int cookie); - void enumerateEnrollments(in int cookie); - void removeEnrollments(in int cookie, in int[] enrollmentIds); - void getFeatures(in int cookie, in int enrollmentId); - void setFeature(in int cookie, in android.hardware.keymaster.HardwareAuthToken hat, in int enrollmentId, in android.hardware.biometrics.face.Feature feature, boolean enabled); - void getAuthenticatorId(in int cookie); - void invalidateAuthenticatorId(in int cookie); - void resetLockout(in int cookie, in android.hardware.keymaster.HardwareAuthToken hat); - void close(in int cookie); + void generateChallenge(); + void revokeChallenge(in long challenge); + android.hardware.biometrics.common.ICancellationSignal enroll(in android.hardware.keymaster.HardwareAuthToken hat, in android.hardware.biometrics.face.EnrollmentType type, in android.hardware.biometrics.face.Feature[] features, in android.hardware.common.NativeHandle previewSurface); + android.hardware.biometrics.common.ICancellationSignal authenticate(in long operationId); + android.hardware.biometrics.common.ICancellationSignal detectInteraction(); + void enumerateEnrollments(); + void removeEnrollments(in int[] enrollmentIds); + void getFeatures(in int enrollmentId); + void setFeature(in android.hardware.keymaster.HardwareAuthToken hat, in int enrollmentId, in android.hardware.biometrics.face.Feature feature, boolean enabled); + void getAuthenticatorId(); + void invalidateAuthenticatorId(); + void resetLockout(in android.hardware.keymaster.HardwareAuthToken hat); + void close(); } diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl index b0bfa3084e..2bb053a31c 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl @@ -34,7 +34,6 @@ package android.hardware.biometrics.face; @VintfStability interface ISessionCallback { - void onStateChanged(in int cookie, in android.hardware.biometrics.face.SessionState state); void onChallengeGenerated(in long challenge); void onChallengeRevoked(in long challenge); void onAuthenticationFrame(in android.hardware.biometrics.face.AuthenticationFrame frame); diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SessionState.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SessionState.aidl deleted file mode 100644 index 4db47c9c67..0000000000 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SessionState.aidl +++ /dev/null @@ -1,51 +0,0 @@ -/* - * 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 -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.face; -@Backing(type="byte") @VintfStability -enum SessionState { - IDLING = 0, - CLOSED = 1, - GENERATING_CHALLENGE = 2, - REVOKING_CHALLENGE = 3, - ENROLLING = 4, - AUTHENTICATING = 5, - DETECTING_INTERACTION = 6, - ENUMERATING_ENROLLMENTS = 7, - REMOVING_ENROLLMENTS = 8, - GETTING_FEATURES = 9, - SETTING_FEATURE = 10, - GETTING_AUTHENTICATOR_ID = 11, - INVALIDATING_AUTHENTICATOR_ID = 12, - RESETTING_LOCKOUT = 13, -} diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl index 66c7c38710..75025157a7 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl @@ -23,11 +23,25 @@ import android.hardware.common.NativeHandle; import android.hardware.keymaster.HardwareAuthToken; /** - * A session is a collection of immutable state (sensorId, userId), mutable state (SessionState), - * methods available for the framework to call, and a callback (ISessionCallback) to notify the - * framework about the events and results. A session is used to establish communication between - * the framework and the HAL. + * Operations that can be performed for unique sessions retrieved via IFace#createSession. + * Operations defined within this interface can be divided into the following categories: + * 1) Cancellable operations. These are usually the operations that can execute for several + * minutes. To allow for cancellation, they return an instance of ICancellationSignal that + * lets the framework cancel them by calling ICancellationSignal#cancel. If such an operation + * is cancelled, it must notify the framework by calling ISessionCallback#onError with + * Error::CANCELED. + * 2) Non-cancellable operations. Such operations cannot be cancelled once started. + * + * The lifecycle of an operation ends when one of its terminal callbacks is called. For example, + * ISession#authenticate is considered completed when any of the following callbacks is called: + * ISessionCallback#onError, ISessionCallback#onAuthenticationSucceeded, + * ISessionCallback#onAuthenticationFailed. + * + * ISession only supports execution of one operation at a time, regardless of whether it's + * cancellable or not. The framework must wait for a corresponding callback indicating the end of + * the current operation before a new operation can be started. */ + @VintfStability interface ISession { /** @@ -68,9 +82,8 @@ interface ISession { * | 0 | 10 | | | * ---------------------------------------------- * - * @param cookie A unique number identifying this operation */ - void generateChallenge(in int cookie); + void generateChallenge(); /** * revokeChallenge: @@ -79,10 +92,9 @@ interface ISession { * parameters is requested, the implementation must still notify the framework using the * provided callback. * - * @param cookie A unique number identifying this operation * @param challenge Challenge that should be revoked. */ - void revokeChallenge(in int cookie, in long challenge); + void revokeChallenge(in long challenge); /** * getEnrollmentConfig: @@ -101,19 +113,13 @@ interface ISession { * * A request to add a face enrollment. * - * Once the HAL is able to start processing the enrollment request, it must notify the framework - * via ISessionCallback#onStateChanged with SessionState::ENROLLING. - * * At any point during enrollment, if a non-recoverable error occurs, the HAL must notify the - * framework via ISessionCallback#onError with the applicable enrollment-specific error, and - * then send ISessionCallback#onStateChanged(cookie, SessionState::IDLING) if no subsequent - * operation is in the queue. + * framework via ISessionCallback#onError with the applicable enrollment-specific error. * * Before capturing face data, the implementation must first verify the authenticity and * integrity of the provided HardwareAuthToken. In addition, it must check that the challenge * within the provided HardwareAuthToken is valid. See ISession#generateChallenge. If any of - * the above checks fail, the framework must be notified via ISessionCallback#onError and the - * HAL must notify the framework when it returns to the idle state. See + * the above checks fail, the framework must be notified using ISessionCallback#onError with * Error::UNABLE_TO_PROCESS. * * During enrollment, the implementation may notify the framework via @@ -121,15 +127,12 @@ interface ISession { * can be invoked multiple times if necessary. Similarly, the framework may be notified of * enrollment progress changes via ISessionCallback#onEnrollmentProgress. Once the framework is * notified that there are 0 "remaining" steps, the framework may cache the "enrollmentId". See - * ISessionCallback#onEnrollmentProgress for more info. The HAL must notify the framework once - * it returns to the idle state. + * ISessionCallback#onEnrollmentProgress for more info. * - * When a finger is successfully added and before the framework is notified of remaining=0, the - * implementation MUST update and associate this (sensorId, userId) pair with a new new + * When a face is successfully added and before the framework is notified of remaining=0, the + * implementation MUST update and associate this (sensorId, userId) pair with a new * entropy-encoded random identifier. See ISession#getAuthenticatorId for more information. * - * @param cookie An identifier used to track subsystem operations related to this call path. The - * client must guarantee that it is unique per ISession. * @param hat See above documentation. * @param enrollmentType See the EnrollmentType enum. * @param features See the Feature enum. @@ -139,7 +142,7 @@ interface ISession { * @return ICancellationSignal An object that can be used by the framework to cancel this * operation. */ - ICancellationSignal enroll(in int cookie, in HardwareAuthToken hat, in EnrollmentType type, + ICancellationSignal enroll(in HardwareAuthToken hat, in EnrollmentType type, in Feature[] features, in NativeHandle previewSurface); /** @@ -147,13 +150,8 @@ interface ISession { * * A request to start looking for faces to authenticate. * - * Once the HAL is able to start processing the authentication request, it must notify framework - * via ISessionCallback#onStateChanged with SessionState::AUTHENTICATING. - * * At any point during authentication, if a non-recoverable error occurs, the HAL must notify - * the framework via ISessionCallback#onError with the applicable authentication-specific error, - * and then send ISessionCallback#onStateChanged(cookie, SessionState::IDLING) if no - * subsequent operation is in the queue. + * the framework via ISessionCallback#onError with the applicable authentication-specific error. * * During authentication, the implementation may notify the framework via * ISessionCallback#onAcquired with messages that may be used to guide the user. This callback @@ -175,8 +173,6 @@ interface ISession { * must be set with the operationId passed in during #authenticate. If the sensor is NOT * SensorStrength::STRONG, the HardwareAuthToken MUST be null. * - * @param cookie An identifier used to track subsystem operations related to this call path. The - * client must guarantee that it is unique per ISession. * @param operationId For sensors configured as SensorStrength::STRONG, this must be used ONLY * upon successful authentication and wrapped in the HardwareAuthToken's * "challenge" field and sent to the framework via @@ -190,7 +186,7 @@ interface ISession { * @return ICancellationSignal An object that can be used by the framework to cancel this * operation. */ - ICancellationSignal authenticate(in int cookie, in long operationId); + ICancellationSignal authenticate(in long operationId); /** * detectInteraction: @@ -199,17 +195,12 @@ interface ISession { * SensorProps#supportsDetectInteraction is true. If invoked on implementations that do not * support this functionality, the HAL must respond with ISession#onError(UNABLE_TO_PROCESS, 0). * - * Once the HAL is able to start processing this request, it must notify the framework via - * ISessionCallback#onStateChanged with SessionState::DETECTING_INTERACTION. - * * The framework will use this method in cases where determing user presence is required, but * identifying/authentication is not. For example, when the device is encrypted (first boot) or * in lockdown mode. * * At any point during detectInteraction, if a non-recoverable error occurs, the HAL must notify - * the framework via ISessionCallback#onError with the applicable error, and then send - * ISessionCallback#onStateChanged(cookie, SessionState::IDLING) if no subsequent operation is - * in the queue. + * the framework via ISessionCallback#onError with the applicable error. * * The implementation must only check for a face-like image was detected (e.g. to * minimize interactions due to non-face objects), and the lockout counter must not @@ -222,17 +213,14 @@ interface ISession { * 1) Any face is detected and the framework is notified via * ISessionCallback#onInteractiondetected * 2) The operation was cancelled by the framework (see ICancellationSignal) - * 3) The HAL ends the operation, for example when a subsequent operation pre-empts this one. * * Note that if the operation is canceled, the implementation must notify the framework via * ISessionCallback#onError with Error::CANCELED. * - * @param cookie An identifier used to track subsystem operations related to this call path. - * The framework will guarantee that it is unique per ISession. * @return ICancellationSignal An object that can be used by the framework to cancel this * operation. */ - ICancellationSignal detectInteraction(in int cookie); + ICancellationSignal detectInteraction(); /* * enumerateEnrollments: @@ -240,32 +228,22 @@ interface ISession { * A request to enumerate (list) the enrollments for this (sensorId, userId) pair. The * framework typically uses this to ensure that its cache is in sync with the HAL. * - * Once the HAL is able to start processing this request, it must notify the framework via - * ISessionCallback#onStateChanged with SessionState::ENUMERATING_ENROLLMENTS. - * * The implementation must then notify the framework with a list of enrollments applicable * for the current session via ISessionCallback#onEnrollmentsEnumerated. * - * @param cookie An identifier used to track subsystem operations related to this call path. - * The framework will guarantee that it is unique per ISession. */ - void enumerateEnrollments(in int cookie); + void enumerateEnrollments(); /** * removeEnrollments: * * A request to remove the enrollments for this (sensorId, userId) pair. * - * Once the HAL is able to start processing this request, it must notify the framework via - * ISessionCallback#onStateChanged with SessionState::REMOVING_ENROLLMENTS. - * * After removing the enrollmentIds from everywhere necessary (filesystem, secure subsystems, * etc), the implementation must notify the framework via ISessionCallback#onEnrollmentsRemoved. * - * @param cookie An identifier used to track subsystem operations related to this call path. - * The framework will guarantee that it is unique per ISession. */ - void removeEnrollments(in int cookie, in int[] enrollmentIds); + void removeEnrollments(in int[] enrollmentIds); /** * getFeatures: @@ -273,20 +251,14 @@ interface ISession { * Returns a list of currently enabled features for the provided enrollmentId. * * If the enrollmentId is invalid, the HAL must invoke ISessionCallback#onError with - * Error::UNABLE_TO_PROCESS and return to SessionState::IDLING if no subsequent work is in the - * queue. - * - * Once the HAL is able to start processing this request, it must notify the framework by using - * ISessionCallback#onStateChanged with SessionState::GETTING_FEATURES. + * Error::UNABLE_TO_PROCESS. * * The HAL must notify the framework about the result by calling * ISessionCallback#onFeaturesRetrieved. * - * @param cookie An identifier used to track subsystem operations related to this call path. The - * client must guarantee that it is unique per ISession. * @param enrollmentId the ID of the enrollment for which the features are requested. */ - void getFeatures(in int cookie, in int enrollmentId); + void getFeatures(in int enrollmentId); /** * setFeature: @@ -296,24 +268,18 @@ interface ISession { * (see @param hat). The HAL must verify the hat before changing any feature state. * * If either the hat or enrollmentId is invalid, the HAL must invoke ISessionCallback#onError - * with Error::UNABLE_TO_PROCESS and return to SessionState::IDLING if no subsequent work is in - * the queue. - * - * Once the HAL is able to start processing this request, it must notify the framework by using - * ISessionCallback#onStateChanged with SessionState::SETTING_FEATURE. + * with Error::UNABLE_TO_PROCESS. * * After the feature is successfully set, the HAL must notify the framework by calling * ISessionCallback#onFeatureSet. * - * @param cookie An identifier used to track subsystem operations related to this call path. The - * client must guarantee that it is unique per ISession. * @param hat HardwareAuthToken See above documentation. * @param enrollmentId the ID of the enrollment for which the feature update is requested. * @param feature The feature to be enabled or disabled. * @param enabled Whether the provided features should be enabled or disabled. */ - void setFeature(in int cookie, in HardwareAuthToken hat, in int enrollmentId, - in Feature feature, boolean enabled); + void setFeature( + in HardwareAuthToken hat, in int enrollmentId, in Feature feature, boolean enabled); /** * getAuthenticatorId: @@ -341,10 +307,8 @@ interface ISession { * 3) MUST not change if a face is deleted. * 4) MUST be an entropy-encoded random number * - * @param cookie An identifier used to track subsystem operations related to this call path. The - * client must guarantee that it is unique per ISession. */ - void getAuthenticatorId(in int cookie); + void getAuthenticatorId(); /** * invalidateAuthenticatorId: @@ -368,10 +332,8 @@ interface ISession { * for more details). As such, the framework would coordinate invalidation across multiple * biometric HALs as necessary. * - * @param cookie An identifier used to track subsystem operations related to this call path. The - * client must guarantee that it is unique per ISession. */ - void invalidateAuthenticatorId(in int cookie); + void invalidateAuthenticatorId(); /** * resetLockout: @@ -382,8 +344,7 @@ interface ISession { * 2) Verify that the timestamp provided within the HAT is relatively recent (e.g. on the * order of minutes, not hours). * If either of the checks fail, the HAL must invoke ISessionCallback#onError with - * Error::UNABLE_TO_PROCESS and return to SessionState::IDLING if no subsequent work is in the - * queue. + * Error::UNABLE_TO_PROCESS. * * Upon successful verification, the HAL must clear the lockout counter and notify the framework * via ISessionCallback#onLockoutCleared. @@ -414,27 +375,20 @@ interface ISession { * See the Android CDD section 7.3.10 for the full set of lockout and rate-limiting * requirements. * - * @param cookie An identifier used to track subsystem operations related to this call path. The - * client must guarantee that it is unique per ISession. * @param hat HardwareAuthToken See above documentation. */ - void resetLockout(in int cookie, in HardwareAuthToken hat); + void resetLockout(in HardwareAuthToken hat); /* * Close this session and allow the HAL to release the resources associated with this session. * - * A session can only be closed when it's in SessionState::IDLING. Closing a session will - * result in a ISessionCallback#onStateChanged call with SessionState::CLOSED. - * - * If a session is unresponsive or stuck in a state other than SessionState::CLOSED, - * IFace#reset could be used as a last resort to terminate the session and recover the HAL - * from a bad state. + * A session can only be closed when the HAL is idling, i.e. not performing any operations. + * If the HAL is busy performing a cancellable operation, the operation must be explicitly + * cancelled with a call to ICancellationSignal#cancel before the session can be closed. * * All sessions must be explicitly closed. Calling IFace#createSession while there is an active * session is considered an error. * - * @param cookie An identifier used to track subsystem operations related to this call path. The - * client must guarantee that it is unique per ISession. */ - void close(in int cookie); + void close(); } diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl index c1aa3fcf80..a2601e7360 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl @@ -21,16 +21,10 @@ import android.hardware.biometrics.face.AuthenticationFrame; import android.hardware.biometrics.face.EnrollmentFrame; import android.hardware.biometrics.face.Error; import android.hardware.biometrics.face.Feature; -import android.hardware.biometrics.face.SessionState; import android.hardware.keymaster.HardwareAuthToken; @VintfStability interface ISessionCallback { - /** - * Used to notify the framework of session state changes. See ISession for more information. - */ - void onStateChanged(in int cookie, in SessionState state); - /** * Notifies the framework when a challenge is successfully generated. */ @@ -42,9 +36,9 @@ interface ISessionCallback { void onChallengeRevoked(in long challenge); /** - * This method must only be used to notify the framework during the following states: - * 1) SessionState::AUTHENTICATING - * 2) SessionState::DETECTING_INTERACTION + * This method must only be used to notify the framework during the following operations: + * 1) ISession#authenticate + * 2) ISession#detectInteraction * * These messages may be used to provide user guidance multiple times if necessary per * operation. @@ -54,8 +48,8 @@ interface ISessionCallback { void onAuthenticationFrame(in AuthenticationFrame frame); /** - * This method must only be used to notify the framework during the SessionState::ENROLLING - * state. + * This method must only be used to notify the framework during the ISession#enroll + * operation. * * These messages may be used to provide user guidance multiple times if necessary per * operation. @@ -65,18 +59,18 @@ interface ISessionCallback { void onEnrollmentFrame(in EnrollmentFrame frame); /** - * This method must only be used to notify the framework during the following states: - * 1) SessionState::ENROLLING - * 2) SessionState::AUTHENTICATING - * 3) SessionState::DETECTING_INTERACTION - * 4) SessionState::INVALIDATING_AUTHENTICATOR_ID - * 5) SessionState::RESETTING_LOCKOUT + * This method must only be used to notify the framework during the following operations: + * 1) ISession#enroll + * 2) ISession#authenticate + * 3) ISession#detectInteraction + * 4) ISession#invalidateAuthenticatorId + * 5) ISession#resetLockout * * These messages may be used to notify the framework or user that a non-recoverable error * has occurred. The operation is finished, and the HAL must proceed with the next operation - * or return to SessionState::IDLING if the queue is empty. + * or return to the idling state. * - * Note that cancellation (see common::ICancellationSignal) and preemption most be followed with + * Note that cancellation (see common::ICancellationSignal) and preemption must be followed with * an Error::CANCELED message. * * @param error See the Error enum. @@ -88,8 +82,7 @@ interface ISessionCallback { void onError(in Error error, in int vendorCode); /** - * This method must only be used to notify the framework during the following state: - * 1) SessionState::ENROLLING + * This method must only be used to notify the framework during the ISession#enroll operation. * * @param enrollmentId Unique stable identifier for the enrollment that's being added by this * ISession#enroll invocation. @@ -98,7 +91,7 @@ interface ISessionCallback { void onEnrollmentProgress(in int enrollmentId, int remaining); /** - * This method must only be used to notify the framework during SessionState::AUTHENTICATING. + * This method must only be used to notify the framework during ISession#authenticate. * * Used to notify the framework about a successful authentication. This ends the authentication * lifecycle. @@ -112,7 +105,7 @@ interface ISessionCallback { void onAuthenticationSucceeded(in int enrollmentId, in HardwareAuthToken hat); /** - * This method must only be used to notify the framework during SessionState::AUTHENTICATING. + * This method must only be used to notify the framework during ISession#authenticate. * * Used to notify the framework about a failed authentication. This ends the authentication * lifecycle. @@ -120,7 +113,7 @@ interface ISessionCallback { void onAuthenticationFailed(); /** - * This method must only be used to notify the framework during SessionState::AUTHENTICATING. + * This method must only be used to notify the framework during ISession#authenticate. * * Authentication is locked out due to too many unsuccessful attempts. This is a rate-limiting * lockout, and authentication can be restarted after a period of time. See @@ -133,7 +126,7 @@ interface ISessionCallback { void onLockoutTimed(in long durationMillis); /** - * This method must only be used to notify the framework during SessionState::AUTHENTICATING. + * This method must only be used to notify the framework during ISession#authenticate. * * Authentication is disabled until the user unlocks with their device credential * (PIN/Pattern/Password). See ISession#resetLockout. @@ -160,7 +153,7 @@ interface ISessionCallback { /** * This method must only be used to notify the framework during - * SessionState::DETECTING_INTERACTION + * ISession#detectInteraction * * Notifies the framework that user interaction occurred. See ISession#detectInteraction. */ @@ -168,7 +161,7 @@ interface ISessionCallback { /** * This method must only be used to notify the framework during - * SessionState::ENUMERATING_ENROLLMENTS. + * ISession#enumerateEnrollments. * * Notifies the framework of the current enrollments. See ISession#enumerateEnrollments. * @@ -177,7 +170,7 @@ interface ISessionCallback { void onEnrollmentsEnumerated(in int[] enrollmentIds); /** - * This method must only be used to notify the framework during SessionState::GETTING_FEATURES. + * This method must only be used to notify the framework during ISession#getFeatures. * * Provides a list of features that are currently enabled for the given enrollmentId. * @@ -187,7 +180,7 @@ interface ISessionCallback { void onFeaturesRetrieved(in Feature[] features, in int enrollmentId); /** - * This method must only be used to notify the framework during SessionState::SETTING_FEATURE. + * This method must only be used to notify the framework during ISession#setFeature. * * Notifies the framework that ISession#setFeature has completed. * @@ -198,7 +191,7 @@ interface ISessionCallback { /** * This method must only be used to notify the framework during - * SessionState::REMOVING_ENROLLMENTS. + * ISession#removeEnrollments. * * Notifies the framework that the specified enrollments are removed. * @@ -208,7 +201,7 @@ interface ISessionCallback { /** * This method must only be used to notify the framework during - * SessionState::GETTING_AUTHENTICATOR_ID. + * ISession#getAuthenticatorId. * * Notifies the framework with the authenticatorId corresponding to this session's * (userId, sensorId) pair. @@ -219,7 +212,7 @@ interface ISessionCallback { /** * This method must only be used to notify the framework during - * SessionState::INVALIDATING_AUTHENTICATOR_ID. + * ISession#invalidateAuthenticatorId. * * See ISession#invalidateAuthenticatorId for more information. * diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/SessionState.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/SessionState.aidl deleted file mode 100644 index afde4eb2d5..0000000000 --- a/biometrics/face/aidl/android/hardware/biometrics/face/SessionState.aidl +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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.face; - -@VintfStability -@Backing(type="byte") -enum SessionState { - /** - * The HAL is not processing any session requests. - */ - IDLING, - - /** - * The session has been closed by the client. - */ - CLOSED, - - /** - * The HAL is processing the ISession#generateChallenge request. - */ - GENERATING_CHALLENGE, - - /** - * The HAL is processing the ISession#revokeChallenge request. - */ - REVOKING_CHALLENGE, - - /** - * The HAL is processing the ISession#enroll request. - */ - ENROLLING, - - /** - * The HAL is processing the ISession#authenticate request. - */ - AUTHENTICATING, - - /** - * The HAL is processing the ISession#detectInteraction request. - */ - DETECTING_INTERACTION, - - /** - * The HAL is processing the ISession#enumerateEnrollments request. - */ - ENUMERATING_ENROLLMENTS, - - /** - * The HAL is processing the ISession#removeEnrollments request. - */ - REMOVING_ENROLLMENTS, - - /** - * The HAL is processing the ISession#getFeatures request. - */ - GETTING_FEATURES, - - /** - * The HAL is processing the ISession#setFeature request. - */ - SETTING_FEATURE, - - /** - * The HAL is processing the ISession#getAuthenticatorId request. - */ - GETTING_AUTHENTICATOR_ID, - - /** - * The HAL is processing the ISession#invalidateAuthenticatorId request. - */ - INVALIDATING_AUTHENTICATOR_ID, - - /** - * The HAL is processing the ISession#resetLockout request. - */ - RESETTING_LOCKOUT -} -- GitLab From 66c6464a134eaae61e4179f15a77b99c06acaff2 Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Tue, 23 Mar 2021 22:33:31 -0700 Subject: [PATCH 559/790] Remove SessionState from IFace example Bug: 183570051 Test: atest VtsHalBiometricsFaceTargetTest Change-Id: Ia4c33f03e8482d5a89d2543a5bdcd851fbcd8a2c --- biometrics/face/aidl/default/Session.cpp | 50 +++++++++--------------- biometrics/face/aidl/default/Session.h | 30 +++++++------- 2 files changed, 32 insertions(+), 48 deletions(-) diff --git a/biometrics/face/aidl/default/Session.cpp b/biometrics/face/aidl/default/Session.cpp index ce6c5572e6..b5eb717351 100644 --- a/biometrics/face/aidl/default/Session.cpp +++ b/biometrics/face/aidl/default/Session.cpp @@ -30,119 +30,105 @@ class CancellationSignal : public common::BnCancellationSignal { ndk::ScopedAStatus cancel() override { cb_->onError(Error::CANCELED, 0 /* vendorCode */); - cb_->onStateChanged(0, SessionState::IDLING); return ndk::ScopedAStatus::ok(); } }; Session::Session(std::shared_ptr cb) : cb_(std::move(cb)) {} -ndk::ScopedAStatus Session::generateChallenge(int32_t /*cookie*/) { +ndk::ScopedAStatus Session::generateChallenge() { LOG(INFO) << "generateChallenge"; if (cb_) { - cb_->onStateChanged(0, SessionState::GENERATING_CHALLENGE); cb_->onChallengeGenerated(0); - cb_->onStateChanged(0, SessionState::IDLING); } return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::revokeChallenge(int32_t /*cookie*/, int64_t challenge) { +ndk::ScopedAStatus Session::revokeChallenge(int64_t challenge) { LOG(INFO) << "revokeChallenge"; if (cb_) { - cb_->onStateChanged(0, SessionState::REVOKING_CHALLENGE); cb_->onChallengeRevoked(challenge); - cb_->onStateChanged(0, SessionState::IDLING); } return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus Session::enroll( - int32_t /*cookie*/, const keymaster::HardwareAuthToken& /*hat*/, - EnrollmentType /*enrollmentType*/, const std::vector& /*features*/, - const NativeHandle& /*previewSurface*/, + const keymaster::HardwareAuthToken& /*hat*/, EnrollmentType /*enrollmentType*/, + const std::vector& /*features*/, const NativeHandle& /*previewSurface*/, std::shared_ptr* /*return_val*/) { LOG(INFO) << "enroll"; return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::authenticate(int32_t /*cookie*/, int64_t /*keystoreOperationId*/, +ndk::ScopedAStatus Session::authenticate(int64_t /*keystoreOperationId*/, std::shared_ptr* return_val) { LOG(INFO) << "authenticate"; if (cb_) { - cb_->onStateChanged(0, SessionState::AUTHENTICATING); + cb_->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorCode */); } *return_val = SharedRefBase::make(cb_); return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus Session::detectInteraction( - int32_t /*cookie*/, std::shared_ptr* /*return_val*/) { + std::shared_ptr* /*return_val*/) { LOG(INFO) << "detectInteraction"; return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::enumerateEnrollments(int32_t /*cookie*/) { +ndk::ScopedAStatus Session::enumerateEnrollments() { LOG(INFO) << "enumerateEnrollments"; if (cb_) { - cb_->onStateChanged(0, SessionState::ENUMERATING_ENROLLMENTS); cb_->onEnrollmentsEnumerated(std::vector()); - cb_->onStateChanged(0, SessionState::IDLING); } return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::removeEnrollments(int32_t /*cookie*/, - const std::vector& /*enrollmentIds*/) { +ndk::ScopedAStatus Session::removeEnrollments(const std::vector& /*enrollmentIds*/) { LOG(INFO) << "removeEnrollments"; if (cb_) { - cb_->onStateChanged(0, SessionState::REMOVING_ENROLLMENTS); cb_->onEnrollmentsRemoved(std::vector()); - cb_->onStateChanged(0, SessionState::IDLING); } return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::getFeatures(int32_t /*cookie*/, int32_t /*enrollmentId*/) { +ndk::ScopedAStatus Session::getFeatures(int32_t /*enrollmentId*/) { LOG(INFO) << "getFeatures"; return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::setFeature(int32_t /*cookie*/, - const keymaster::HardwareAuthToken& /*hat*/, +ndk::ScopedAStatus Session::setFeature(const keymaster::HardwareAuthToken& /*hat*/, int32_t /*enrollmentId*/, Feature /*feature*/, bool /*enabled*/) { LOG(INFO) << "setFeature"; return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::getAuthenticatorId(int32_t /*cookie*/) { +ndk::ScopedAStatus Session::getAuthenticatorId() { LOG(INFO) << "getAuthenticatorId"; if (cb_) { - cb_->onStateChanged(0, SessionState::GETTING_AUTHENTICATOR_ID); cb_->onAuthenticatorIdRetrieved(0 /* authenticatorId */); - cb_->onStateChanged(0, SessionState::IDLING); } return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::invalidateAuthenticatorId(int32_t /*cookie*/) { +ndk::ScopedAStatus Session::invalidateAuthenticatorId() { LOG(INFO) << "invalidateAuthenticatorId"; return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::resetLockout(int32_t /*cookie*/, - const keymaster::HardwareAuthToken& /*hat*/) { +ndk::ScopedAStatus Session::resetLockout(const keymaster::HardwareAuthToken& /*hat*/) { LOG(INFO) << "resetLockout"; if (cb_) { - cb_->onStateChanged(0, SessionState::RESETTING_LOCKOUT); cb_->onLockoutCleared(); - cb_->onStateChanged(0, SessionState::IDLING); } return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::close(int32_t /*cookie*/) { +ndk::ScopedAStatus Session::close() { + if (cb_) { + cb_->onSessionClosed(); + } return ndk::ScopedAStatus::ok(); } diff --git a/biometrics/face/aidl/default/Session.h b/biometrics/face/aidl/default/Session.h index eb9ae83342..73cdf08625 100644 --- a/biometrics/face/aidl/default/Session.h +++ b/biometrics/face/aidl/default/Session.h @@ -30,40 +30,38 @@ class Session : public BnSession { public: explicit Session(std::shared_ptr cb); - ndk::ScopedAStatus generateChallenge(int32_t cookie) override; + ndk::ScopedAStatus generateChallenge() override; - ndk::ScopedAStatus revokeChallenge(int32_t cookie, int64_t challenge) override; + ndk::ScopedAStatus revokeChallenge(int64_t challenge) override; - ndk::ScopedAStatus enroll(int32_t cookie, const keymaster::HardwareAuthToken& hat, + ndk::ScopedAStatus enroll(const keymaster::HardwareAuthToken& hat, EnrollmentType enrollmentType, const std::vector& features, const NativeHandle& previewSurface, std::shared_ptr* return_val) override; ndk::ScopedAStatus authenticate( - int32_t cookie, int64_t keystoreOperationId, + int64_t keystoreOperationId, std::shared_ptr* returnVal) override; ndk::ScopedAStatus detectInteraction( - int32_t cookie, std::shared_ptr* returnVal) override; + std::shared_ptr* returnVal) override; - ndk::ScopedAStatus enumerateEnrollments(int32_t cookie) override; + ndk::ScopedAStatus enumerateEnrollments() override; - ndk::ScopedAStatus removeEnrollments(int32_t cookie, - const std::vector& enrollmentIds) override; + ndk::ScopedAStatus removeEnrollments(const std::vector& enrollmentIds) override; - ndk::ScopedAStatus getFeatures(int32_t cookie, int32_t enrollmentId) override; + ndk::ScopedAStatus getFeatures(int32_t enrollmentId) override; - ndk::ScopedAStatus setFeature(int32_t cookie, const keymaster::HardwareAuthToken& hat, - int32_t enrollmentId, Feature feature, bool enabled) override; + ndk::ScopedAStatus setFeature(const keymaster::HardwareAuthToken& hat, int32_t enrollmentId, + Feature feature, bool enabled) override; - ndk::ScopedAStatus getAuthenticatorId(int32_t cookie) override; + ndk::ScopedAStatus getAuthenticatorId() override; - ndk::ScopedAStatus invalidateAuthenticatorId(int32_t cookie) override; + ndk::ScopedAStatus invalidateAuthenticatorId() override; - ndk::ScopedAStatus resetLockout(int32_t cookie, - const keymaster::HardwareAuthToken& hat) override; + ndk::ScopedAStatus resetLockout(const keymaster::HardwareAuthToken& hat) override; - ndk::ScopedAStatus close(int32_t cookie) override; + ndk::ScopedAStatus close() override; private: std::shared_ptr cb_; -- GitLab From cc2b6943c660bbf55a7ab9c0944db771da7ae5dc Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Tue, 23 Mar 2021 23:08:41 -0700 Subject: [PATCH 560/790] Remove SessionState from IFace VTS Bug: 183570051 Test: atest VtsHalBiometricsFaceTargetTest Change-Id: I2b106449cbafeaff1d683eb4ef87e022e12b4ee0 --- .../vts/VtsHalBiometricsFaceTargetTest.cpp | 76 +++++++++++-------- 1 file changed, 44 insertions(+), 32 deletions(-) diff --git a/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp b/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp index 936fcc69e5..60e0a2a41f 100644 --- a/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp +++ b/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp @@ -21,35 +21,31 @@ #include #include +#include #include namespace aidl::android::hardware::biometrics::face { namespace { +using namespace std::literals::chrono_literals; + constexpr int kSensorId = 0; constexpr int kUserId = 0; -constexpr auto kCallbackTimeout = std::chrono::seconds(1); -enum class SessionCallbackMethodName { - kOnStateChanged, +enum class MethodName { + kOnError, + kOnSessionClosed, }; -struct SessionCallbackInvocation { - SessionCallbackMethodName method_name; - SessionState state; +struct Invocation { + MethodName methodName; + Error error; + int32_t vendorCode; }; class SessionCallback : public BnSessionCallback { public: - explicit SessionCallback(std::promise invocation_promise) - : invocation_promise_(std::move(invocation_promise)) {} - ndk::ScopedAStatus onStateChanged(int32_t /*cookie*/, SessionState state) override { - SessionCallbackInvocation invocation = {}; - invocation.method_name = SessionCallbackMethodName::kOnStateChanged; - invocation.state = state; - invocation_promise_.set_value(invocation); - return ndk::ScopedAStatus::ok(); - } + explicit SessionCallback(Invocation* inv) : mInv(inv) {} ndk::ScopedAStatus onChallengeGenerated(int64_t /*challenge*/) override { return ndk::ScopedAStatus::ok(); @@ -67,7 +63,12 @@ class SessionCallback : public BnSessionCallback { return ndk::ScopedAStatus::ok(); } - ndk::ScopedAStatus onError(Error /*error*/, int32_t /*vendorCode*/) override { + ndk::ScopedAStatus onError(Error error, int32_t vendorCode) override { + *mInv = {}; + mInv->methodName = MethodName::kOnError; + mInv->error = error; + mInv->vendorCode = vendorCode; + return ndk::ScopedAStatus::ok(); } @@ -120,10 +121,15 @@ class SessionCallback : public BnSessionCallback { return ndk::ScopedAStatus::ok(); } - ndk::ScopedAStatus onSessionClosed() override { return ndk::ScopedAStatus::ok(); } + ndk::ScopedAStatus onSessionClosed() override { + *mInv = {}; + mInv->methodName = MethodName::kOnSessionClosed; + + return ndk::ScopedAStatus::ok(); + } private: - std::promise invocation_promise_; + Invocation* mInv; }; class Face : public testing::TestWithParam { @@ -131,28 +137,34 @@ class Face : public testing::TestWithParam { void SetUp() override { AIBinder* binder = AServiceManager_waitForService(GetParam().c_str()); ASSERT_NE(binder, nullptr); - hal_ = IFace::fromBinder(ndk::SpAIBinder(binder)); + mHal = IFace::fromBinder(ndk::SpAIBinder(binder)); } - std::shared_ptr hal_; + std::shared_ptr mHal; + Invocation mInv; }; TEST_P(Face, AuthenticateTest) { - std::promise invocation_promise; - std::future invocation_future = invocation_promise.get_future(); - std::shared_ptr session_cb = - ndk::SharedRefBase::make(std::move(invocation_promise)); + // Prepare the callback. + auto cb = ndk::SharedRefBase::make(&mInv); + // Create a session std::shared_ptr session; - ASSERT_TRUE(hal_->createSession(kSensorId, kUserId, session_cb, &session).isOk()); + ASSERT_TRUE(mHal->createSession(kSensorId, kUserId, cb, &session).isOk()); + + // Call authenticate + std::shared_ptr cancellationSignal; + ASSERT_TRUE(session->authenticate(0 /* operationId */, &cancellationSignal).isOk()); + + // Get the results + EXPECT_EQ(mInv.methodName, MethodName::kOnError); + EXPECT_EQ(mInv.error, Error::UNABLE_TO_PROCESS); + EXPECT_EQ(mInv.vendorCode, 0); - std::shared_ptr cancel_cb; - ASSERT_TRUE(session->authenticate(0, 0, &cancel_cb).isOk()); - ASSERT_EQ(invocation_future.wait_for(kCallbackTimeout), std::future_status::ready); + // Close the session + ASSERT_TRUE(session->close().isOk()); - SessionCallbackInvocation invocation = invocation_future.get(); - EXPECT_EQ(invocation.method_name, SessionCallbackMethodName::kOnStateChanged); - EXPECT_EQ(invocation.state, SessionState::AUTHENTICATING); + EXPECT_EQ(mInv.methodName, MethodName::kOnSessionClosed); } GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Face); @@ -161,6 +173,7 @@ INSTANTIATE_TEST_SUITE_P(IFace, Face, ::android::PrintInstanceNameToString); } // namespace +} // namespace aidl::android::hardware::biometrics::face int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); @@ -169,4 +182,3 @@ int main(int argc, char** argv) { return RUN_ALL_TESTS(); } -} // namespace aidl::android::hardware::biometrics::face -- GitLab From 3a11427073ab70760c1b8113b6033ac469426089 Mon Sep 17 00:00:00 2001 From: Mikhail Naganov Date: Wed, 24 Mar 2021 20:04:08 -0700 Subject: [PATCH 561/790] audio: Use get_audio_port_v7 in the default wrapper get_audio_port_v7 interface method was added in aosp/1518624 but wasn't used in the default wrapper due to the refactoring ongoing at that time. Fixing this omission. Bug: 160352965 Test: atest VtsHalAudioV7_0TargetTest Change-Id: I1e3594f30fe8fa319d0b5b4244531c9142870503 --- audio/core/all-versions/default/Device.cpp | 35 ++++++++++++++++--- .../default/include/core/default/Device.h | 4 +++ 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/audio/core/all-versions/default/Device.cpp b/audio/core/all-versions/default/Device.cpp index 70a1a4d1c1..130dfba95b 100644 --- a/audio/core/all-versions/default/Device.cpp +++ b/audio/core/all-versions/default/Device.cpp @@ -360,18 +360,43 @@ Return Device::releaseAudioPatch(int32_t patch) { return Result::NOT_SUPPORTED; } -Return Device::getAudioPort(const AudioPort& port, getAudioPort_cb _hidl_cb) { - audio_port halPort; - HidlUtils::audioPortToHal(port, &halPort); - Result retval = analyzeStatus("get_audio_port", mDevice->get_audio_port(mDevice, &halPort)); +template +Return Device::getAudioPortImpl(const AudioPort& port, getAudioPort_cb _hidl_cb, + int (*halGetter)(audio_hw_device_t*, HalPort*), + const char* halGetterName) { + HalPort halPort; + if (status_t status = HidlUtils::audioPortToHal(port, &halPort); status != NO_ERROR) { + _hidl_cb(analyzeStatus("audioPortToHal", status), port); + return Void(); + } + Result retval = analyzeStatus(halGetterName, halGetter(mDevice, &halPort)); AudioPort resultPort = port; if (retval == Result::OK) { - HidlUtils::audioPortFromHal(halPort, &resultPort); + if (status_t status = HidlUtils::audioPortFromHal(halPort, &resultPort); + status != NO_ERROR) { + _hidl_cb(analyzeStatus("audioPortFromHal", status), port); + return Void(); + } } _hidl_cb(retval, resultPort); return Void(); } +#if MAJOR_VERSION <= 6 +Return Device::getAudioPort(const AudioPort& port, getAudioPort_cb _hidl_cb) { + return getAudioPortImpl(port, _hidl_cb, mDevice->get_audio_port, "get_audio_port"); +} +#else +Return Device::getAudioPort(const AudioPort& port, getAudioPort_cb _hidl_cb) { + if (version() >= AUDIO_DEVICE_API_VERSION_3_2) { + // get_audio_port_v7 is mandatory if legacy HAL support this API version. + return getAudioPortImpl(port, _hidl_cb, mDevice->get_audio_port_v7, "get_audio_port_v7"); + } else { + return getAudioPortImpl(port, _hidl_cb, mDevice->get_audio_port, "get_audio_port"); + } +} +#endif + Return Device::setAudioPortConfig(const AudioPortConfig& config) { if (version() >= AUDIO_DEVICE_API_VERSION_3_0) { struct audio_port_config halPortConfig; diff --git a/audio/core/all-versions/default/include/core/default/Device.h b/audio/core/all-versions/default/include/core/default/Device.h index 5851fc949c..94cad53581 100644 --- a/audio/core/all-versions/default/include/core/default/Device.h +++ b/audio/core/all-versions/default/include/core/default/Device.h @@ -153,6 +153,10 @@ struct Device : public IDevice, public ParametersUtil { std::tuple createOrUpdateAudioPatch( AudioPatchHandle patch, const hidl_vec& sources, const hidl_vec& sinks); + template + Return getAudioPortImpl(const AudioPort& port, getAudioPort_cb _hidl_cb, + int (*halGetter)(audio_hw_device_t*, HalPort*), + const char* halGetterName); // Methods from ParametersUtil. char* halGetParameters(const char* keys) override; -- GitLab From 6e96be8019c4b5b61dca402258dc2a20447acc80 Mon Sep 17 00:00:00 2001 From: Shinru Han Date: Thu, 25 Mar 2021 12:28:09 +0800 Subject: [PATCH 562/790] Update HAL comment of SatellitePvt and GnssMeasurement Bug: 183670215 Test: comment only Change-Id: I6e6504eb8741b7991287d87efeb561c67fbc1dc2 --- .../hardware/gnss/GnssMeasurement.aidl | 79 ++++++++++--------- .../hardware/gnss/SatellitePositionEcef.aidl | 5 +- .../hardware/gnss/SatelliteVelocityEcef.aidl | 5 +- 3 files changed, 48 insertions(+), 41 deletions(-) diff --git a/gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl b/gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl index f20cd25cd7..336e9272a6 100644 --- a/gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl +++ b/gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl @@ -17,8 +17,8 @@ package android.hardware.gnss; import android.hardware.gnss.CorrelationVector; -import android.hardware.gnss.GnssSignalType; import android.hardware.gnss.GnssMultipathIndicator; +import android.hardware.gnss.GnssSignalType; import android.hardware.gnss.SatellitePvt; /** @@ -32,41 +32,41 @@ import android.hardware.gnss.SatellitePvt; @VintfStability parcelable GnssMeasurement { /** Bit mask indicating a valid 'snr' is stored in the GnssMeasurement. */ - const int HAS_SNR = 1 << 0; + const int HAS_SNR = 1 << 0; /** Bit mask indicating a valid 'carrier frequency' is stored in the GnssMeasurement. */ - const int HAS_CARRIER_FREQUENCY = 1 << 9; + const int HAS_CARRIER_FREQUENCY = 1 << 9; /** Bit mask indicating a valid 'carrier cycles' is stored in the GnssMeasurement. */ - const int HAS_CARRIER_CYCLES = 1 << 10; + const int HAS_CARRIER_CYCLES = 1 << 10; /** Bit mask indicating a valid 'carrier phase' is stored in the GnssMeasurement. */ - const int HAS_CARRIER_PHASE = 1 << 11; + const int HAS_CARRIER_PHASE = 1 << 11; /** Bit mask indicating a valid 'carrier phase uncertainty' is stored in the GnssMeasurement. */ - const int HAS_CARRIER_PHASE_UNCERTAINTY = 1 << 12; + const int HAS_CARRIER_PHASE_UNCERTAINTY = 1 << 12; /** Bit mask indicating a valid automatic gain control is stored in the GnssMeasurement. */ - const int HAS_AUTOMATIC_GAIN_CONTROL = 1 << 13; + const int HAS_AUTOMATIC_GAIN_CONTROL = 1 << 13; /** Bit mask indicating a valid full inter-signal bias is stored in the GnssMeasurement. */ - const int HAS_FULL_ISB = 1 << 16; + const int HAS_FULL_ISB = 1 << 16; /** * Bit mask indicating a valid full inter-signal bias uncertainty is stored in the * GnssMeasurement. */ - const int HAS_FULL_ISB_UNCERTAINTY = 1 << 17; + const int HAS_FULL_ISB_UNCERTAINTY = 1 << 17; /** * Bit mask indicating a valid satellite inter-signal bias is stored in the GnssMeasurement. */ - const int HAS_SATELLITE_ISB = 1 << 18; + const int HAS_SATELLITE_ISB = 1 << 18; /** * Bit mask indicating a valid satellite inter-signal bias uncertainty is stored in the * GnssMeasurement. */ - const int HAS_SATELLITE_ISB_UNCERTAINTY = 1 << 19; + const int HAS_SATELLITE_ISB_UNCERTAINTY = 1 << 19; /** * Bit mask indicating a valid satellite PVT is stored in the GnssMeasurement. */ - const int HAS_SATELLITE_PVT = 1 << 20; + const int HAS_SATELLITE_PVT = 1 << 20; /** * Bit mask indicating valid correlation vectors are stored in the GnssMeasurement. */ - const int HAS_CORRELATION_VECTOR = 1 << 21; + const int HAS_CORRELATION_VECTOR = 1 << 21; /** * A bitfield of flags indicating the validity of the fields in this GnssMeasurement. The bit @@ -132,17 +132,17 @@ parcelable GnssMeasurement { * the received GNSS satellite time value. * * +---------------------------+--------------------+-----+-----------+--------------------+------+ - * | |GPS/QZSS |GLNS |BDS |GAL |SBAS | + * | |GPS/QZSS |GLNS |BDS |GAL |SBAS | * +---------------------------+------+------+------+-----+------+----+------+------+------+------+ * |State Flag |L1 |L5I |L5Q |L1OF |B1I |B1I |E1B |E1C |E5AQ |L1 | - * | |C/A | | | |(D1) |(D2)| | | |C/A | + * | |C/A | | | |(D1) |(D2)| | | |C/A | * |---------------------------+------+------+------+-----+------+----+------+------+------+------+ - * |STATE_UNKNOWN |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 | + * |STATE_UNKNOWN |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 | * |---------------------------+------+------+------+-----+------+----+------+------+------+------+ * |STATE_CODE_LOCK |1ms |1 ms |1 ms |1 ms |1 ms |1 ms|- |- |1 ms |1 ms | * |---------------------------+------+------+------+-----+------+----+------+------+------+------+ * |STATE_SYMBOL_SYNC |20ms |10 ms |1 ms |10 ms|20 ms |2 ms|4 ms |4 ms |1 ms |2 ms | - * | |(opt.)| |(opt.)| |(opt.)| |(opt.)|(opt.)|(opt.)| | + * | |(opt.)| |(opt.)| |(opt.)| |(opt.)|(opt.)|(opt.)| | * |---------------------------+------+------+------+-----+------+----+------+------+------+------+ * |STATE_BIT_SYNC |20 ms |20 ms |1 ms |20 ms|20 ms |- |8 ms |- |1 ms |4 ms | * | | | |(opt.)| | | | | |(opt.)| | @@ -194,24 +194,24 @@ parcelable GnssMeasurement { * - For E1B and E1C, STATE_SYMBOL_SYNC is optional, because it is implied by * STATE_GAL_E1BC_CODE_LOCK. */ - const int STATE_UNKNOWN = 0; - const int STATE_CODE_LOCK = 1 << 0; - const int STATE_BIT_SYNC = 1 << 1; - const int STATE_SUBFRAME_SYNC = 1 << 2; - const int STATE_TOW_DECODED = 1 << 3; - const int STATE_MSEC_AMBIGUOUS = 1 << 4; - const int STATE_SYMBOL_SYNC = 1 << 5; - const int STATE_GLO_STRING_SYNC = 1 << 6; - const int STATE_GLO_TOD_DECODED = 1 << 7; - const int STATE_BDS_D2_BIT_SYNC = 1 << 8; - const int STATE_BDS_D2_SUBFRAME_SYNC = 1 << 9; - const int STATE_GAL_E1BC_CODE_LOCK = 1 << 10; - const int STATE_GAL_E1C_2ND_CODE_LOCK = 1 << 11; - const int STATE_GAL_E1B_PAGE_SYNC = 1 << 12; - const int STATE_SBAS_SYNC = 1 << 13; - const int STATE_TOW_KNOWN = 1 << 14; - const int STATE_GLO_TOD_KNOWN = 1 << 15; - const int STATE_2ND_CODE_LOCK = 1 << 16; + const int STATE_UNKNOWN = 0; + const int STATE_CODE_LOCK = 1 << 0; + const int STATE_BIT_SYNC = 1 << 1; + const int STATE_SUBFRAME_SYNC = 1 << 2; + const int STATE_TOW_DECODED = 1 << 3; + const int STATE_MSEC_AMBIGUOUS = 1 << 4; + const int STATE_SYMBOL_SYNC = 1 << 5; + const int STATE_GLO_STRING_SYNC = 1 << 6; + const int STATE_GLO_TOD_DECODED = 1 << 7; + const int STATE_BDS_D2_BIT_SYNC = 1 << 8; + const int STATE_BDS_D2_SUBFRAME_SYNC = 1 << 9; + const int STATE_GAL_E1BC_CODE_LOCK = 1 << 10; + const int STATE_GAL_E1C_2ND_CODE_LOCK = 1 << 11; + const int STATE_GAL_E1B_PAGE_SYNC = 1 << 12; + const int STATE_SBAS_SYNC = 1 << 13; + const int STATE_TOW_KNOWN = 1 << 14; + const int STATE_GLO_TOD_KNOWN = 1 << 15; + const int STATE_2ND_CODE_LOCK = 1 << 16; /** * A bitfield of flags indicating the GnssMeasurementState per satellite sync state. It @@ -380,7 +380,6 @@ parcelable GnssMeasurement { */ double pseudorangeRateUncertaintyMps; - /** * Flags indicating the Accumulated Delta Range's states. * @@ -620,8 +619,10 @@ parcelable GnssMeasurement { double satelliteInterSignalBiasUncertaintyNs; /** - * The GNSS satellite position, velocity and time information at the signal transmission time - * receivedSvTimeInNs. + * The GNSS satellite position, velocity and time information at the same signal transmission + * time receivedSvTimeInNs. + * + * The position and velocity must be in ECEF coordinates. * * If the data is available, gnssMeasurementFlags must contain HAS_SATELLITE_PVT. */ @@ -635,4 +636,4 @@ parcelable GnssMeasurement { * at equally spaced spatial offsets. */ CorrelationVector[] correlationVectors; -} \ No newline at end of file +} diff --git a/gnss/aidl/android/hardware/gnss/SatellitePositionEcef.aidl b/gnss/aidl/android/hardware/gnss/SatellitePositionEcef.aidl index 4b3615e29a..febe62333f 100644 --- a/gnss/aidl/android/hardware/gnss/SatellitePositionEcef.aidl +++ b/gnss/aidl/android/hardware/gnss/SatellitePositionEcef.aidl @@ -18,6 +18,9 @@ package android.hardware.gnss; /** * Contains estimates of the satellite position fields in ECEF coordinate frame. + * + * The satellite position must be defined at the time of transmission of the + * signal receivedSvTimeNs. */ @VintfStability parcelable SatellitePositionEcef { @@ -36,4 +39,4 @@ parcelable SatellitePositionEcef { * It covers satellite position and clock errors projected to the pseudorange measurements. */ double ureMeters; -} \ No newline at end of file +} diff --git a/gnss/aidl/android/hardware/gnss/SatelliteVelocityEcef.aidl b/gnss/aidl/android/hardware/gnss/SatelliteVelocityEcef.aidl index 25ece3a3a7..f2d7ab6030 100644 --- a/gnss/aidl/android/hardware/gnss/SatelliteVelocityEcef.aidl +++ b/gnss/aidl/android/hardware/gnss/SatelliteVelocityEcef.aidl @@ -18,6 +18,9 @@ package android.hardware.gnss; /** * Contains estimates of the satellite velocity fields in the ECEF coordinate frame. + * + * The satellite velocity must be defined at the time of transmission of the + * signal receivedSvTimeNs. */ @VintfStability parcelable SatelliteVelocityEcef { @@ -37,4 +40,4 @@ parcelable SatelliteVelocityEcef { * projected to the pseudorange rate measurements. */ double ureRateMps; -} \ No newline at end of file +} -- GitLab From 11c723db078d118abe5262bf45165bb09a899507 Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Mon, 22 Mar 2021 22:19:53 +0000 Subject: [PATCH 563/790] Update the comment for generateChallenge Bug: 182005958 Test: none Change-Id: Id8c08929a550a93f13d1579b6d2d9745db3001d1 --- .../face/aidl/android/hardware/biometrics/face/ISession.aidl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl index 75025157a7..f9c13e6801 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl @@ -69,7 +69,7 @@ interface ISession { * * Note that this interface allows multiple in-flight challenges. Invoking generateChallenge * twice does not invalidate the first challenge. The challenge is invalidated only when: - * 1) Its lifespan exceeds the HAL's internal challenge timeout + * 1) Its lifespan exceeds the challenge timeout defined in the TEE. * 2) IFingerprint#revokeChallenge is invoked * * For example, the following is a possible table of valid challenges: -- GitLab From 6333eedc9ed4b61273c23e273a2e904c47ef92ec Mon Sep 17 00:00:00 2001 From: Hayden Gomes Date: Thu, 25 Mar 2021 11:27:59 -0700 Subject: [PATCH 564/790] Applying cleanup to default AIDL AudioControl Updating default AudioControl HAL with cleanup steps applied based on feedback to emulator specific version of HAL. Bug: 183601304 Test: adb shell dumpsys android.hardware.automotive.audiocontrol.IAudioControl/default --request AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE 0 3 Change-Id: Ic8068b66d7f99a4bfaed025f13303f33d3f3a5bc --- .../audiocontrol/aidl/default/Android.bp | 5 +---- .../aidl/default/AudioControl.cpp | 22 ++++++++++++------- .../audiocontrol/aidl/default/AudioControl.h | 6 ++--- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/automotive/audiocontrol/aidl/default/Android.bp b/automotive/audiocontrol/aidl/default/Android.bp index 878bee19cb..7694bdf160 100644 --- a/automotive/audiocontrol/aidl/default/Android.bp +++ b/automotive/audiocontrol/aidl/default/Android.bp @@ -27,10 +27,8 @@ cc_binary { init_rc: ["audiocontrol-default.rc"], vintf_fragments: ["audiocontrol-default.xml"], vendor: true, - generated_headers: ["audio_policy_configuration_V7_0"], - generated_sources: ["audio_policy_configuration_V7_0"], - header_libs: ["libxsdc-utils"], shared_libs: [ + "android.hardware.audio.common@7.0-enums", "android.frameworks.automotive.powerpolicy-V1-ndk_platform", "android.hardware.automotive.audiocontrol-V1-ndk_platform", "libbase", @@ -38,7 +36,6 @@ cc_binary { "libcutils", "liblog", "libpowerpolicyclient", - "libxml2", ], srcs: [ "AudioControl.cpp", diff --git a/automotive/audiocontrol/aidl/default/AudioControl.cpp b/automotive/audiocontrol/aidl/default/AudioControl.cpp index b076d01282..c0bc796cdf 100644 --- a/automotive/audiocontrol/aidl/default/AudioControl.cpp +++ b/automotive/audiocontrol/aidl/default/AudioControl.cpp @@ -14,6 +14,9 @@ * limitations under the License. */ +#define LOG_TAG "AudioControl" +// #define LOG_NDEBUG 0 + #include "AudioControl.h" #include @@ -24,7 +27,7 @@ #include #include -#include +#include #include #include @@ -33,6 +36,7 @@ namespace aidl::android::hardware::automotive::audiocontrol { using ::android::base::EqualsIgnoreCase; using ::android::base::ParseInt; +using ::std::shared_ptr; using ::std::string; namespace xsd { @@ -68,7 +72,7 @@ ndk::ScopedAStatus AudioControl::registerFocusListener( const shared_ptr& in_listener) { LOG(DEBUG) << "registering focus listener"; - if (in_listener.get()) { + if (in_listener) { std::atomic_store(&mFocusListener, in_listener); } else { LOG(ERROR) << "Unexpected nullptr for listener resulting in no-op."; @@ -80,9 +84,10 @@ ndk::ScopedAStatus AudioControl::setBalanceTowardRight(float value) { if (isValidValue(value)) { // Just log in this default mock implementation LOG(INFO) << "Balance set to " << value; - } else { - LOG(ERROR) << "Balance value out of range -1 to 1 at " << value; + return ndk::ScopedAStatus::ok(); } + + LOG(ERROR) << "Balance value out of range -1 to 1 at " << value; return ndk::ScopedAStatus::ok(); } @@ -90,9 +95,10 @@ ndk::ScopedAStatus AudioControl::setFadeTowardFront(float value) { if (isValidValue(value)) { // Just log in this default mock implementation LOG(INFO) << "Fader set to " << value; - } else { - LOG(ERROR) << "Fader value out of range -1 to 1 at " << value; + return ndk::ScopedAStatus::ok(); } + + LOG(ERROR) << "Fader value out of range -1 to 1 at " << value; return ndk::ScopedAStatus::ok(); } @@ -194,7 +200,7 @@ binder_status_t AudioControl::cmdRequestFocus(int fd, const char** args, uint32_ } string usage = string(args[1]); - if (xsd::stringToAudioUsage(usage) == xsd::AudioUsage::UNKNOWN) { + if (xsd::isUnknownAudioUsage(usage)) { dprintf(fd, "Unknown usage provided: %s. Please see audio_policy_configuration.xsd V7_0 " "for supported values\n", @@ -236,7 +242,7 @@ binder_status_t AudioControl::cmdAbandonFocus(int fd, const char** args, uint32_ } string usage = string(args[1]); - if (xsd::stringToAudioUsage(usage) == xsd::AudioUsage::UNKNOWN) { + if (xsd::isUnknownAudioUsage(usage)) { dprintf(fd, "Unknown usage provided: %s. Please see audio_policy_configuration.xsd V7_0 " "for supported values\n", diff --git a/automotive/audiocontrol/aidl/default/AudioControl.h b/automotive/audiocontrol/aidl/default/AudioControl.h index ab0b1b3051..cca9c44004 100644 --- a/automotive/audiocontrol/aidl/default/AudioControl.h +++ b/automotive/audiocontrol/aidl/default/AudioControl.h @@ -23,8 +23,6 @@ namespace aidl::android::hardware::automotive::audiocontrol { -using ::std::shared_ptr; - class AudioControl : public BnAudioControl { public: ndk::ScopedAStatus onAudioFocusChange(const std::string& in_usage, int32_t in_zoneId, @@ -34,7 +32,7 @@ class AudioControl : public BnAudioControl { ndk::ScopedAStatus onDevicesToMuteChange( const std::vector& in_mutingInfos) override; ndk::ScopedAStatus registerFocusListener( - const shared_ptr& in_listener) override; + const std::shared_ptr& in_listener) override; ndk::ScopedAStatus setBalanceTowardRight(float in_value) override; ndk::ScopedAStatus setFadeTowardFront(float in_value) override; binder_status_t dump(int fd, const char** args, uint32_t numArgs) override; @@ -44,7 +42,7 @@ class AudioControl : public BnAudioControl { // a single instance of CarAudioService. As such, it doesn't have explicit serialization. // If a different AudioControl implementation were to have multiple threads leveraging this // listener, then it should also include mutexes or make the listener atomic. - shared_ptr mFocusListener; + std::shared_ptr mFocusListener; binder_status_t cmdHelp(int fd) const; binder_status_t cmdRequestFocus(int fd, const char** args, uint32_t numArgs); -- GitLab From 304e9ea675989631bc83a39d4eb007cc1ac540fe Mon Sep 17 00:00:00 2001 From: Bob Badour Date: Thu, 25 Mar 2021 12:22:15 -0700 Subject: [PATCH 565/790] [LSC] Add LOCAL_LICENSE_KINDS to hardware/interfaces Added SPDX-license-identifier-Apache-2.0 to: automotive/vehicle/2.0/vts/functional/Android.bp media/c2/1.2/Android.bp Bug: 68860345 Bug: 151177513 Bug: 151953481 Test: m all Exempt-From-Owner-Approval: janitorial work Change-Id: Iffcdec8246a5acaf28ccb4475a309554f46b56ce --- automotive/vehicle/2.0/vts/functional/Android.bp | 9 +++++++++ media/c2/1.2/Android.bp | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/automotive/vehicle/2.0/vts/functional/Android.bp b/automotive/vehicle/2.0/vts/functional/Android.bp index 9f1dd6fb86..e64e942a0e 100644 --- a/automotive/vehicle/2.0/vts/functional/Android.bp +++ b/automotive/vehicle/2.0/vts/functional/Android.bp @@ -1,3 +1,12 @@ +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + cc_test { name: "VtsHalAutomotiveVehicleV2_0TargetTest", defaults: [ diff --git a/media/c2/1.2/Android.bp b/media/c2/1.2/Android.bp index 10947219fb..6d3e74d2b1 100644 --- a/media/c2/1.2/Android.bp +++ b/media/c2/1.2/Android.bp @@ -1,5 +1,14 @@ // 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.media.c2@1.2", root: "android.hardware", -- GitLab From 4e9f2f79cb883a02331cfff77bce16585307e1d0 Mon Sep 17 00:00:00 2001 From: Kevin Chyn Date: Thu, 25 Mar 2021 12:04:11 -0700 Subject: [PATCH 566/790] Add AcqiredInfo.RETRYING_CAPTURE to IFingerprint Bug: 183154058 Test: make -j android.hardware.biometrics.fingerprint-update-api Change-Id: I76c9f157975af5c354136e0ec9d1b04dd1098b2a --- .../hardware/biometrics/fingerprint/AcquiredInfo.aidl | 1 + .../hardware/biometrics/fingerprint/AcquiredInfo.aidl | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl index a8e73fc82c..2c2011a034 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl @@ -45,4 +45,5 @@ enum AcquiredInfo { TOO_DARK = 8, TOO_BRIGHT = 9, IMMOBILE = 10, + RETRYING_CAPTURE = 11, } diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl index bf11daa817..b406947be5 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl @@ -82,5 +82,11 @@ enum AcquiredInfo { * same finger can help against false rejections. */ IMMOBILE, -} + /** + * This message may be sent to notify the framework that an additional image capture is taking + * place. Multiple RETRYING_CAPTURE may be sent before an ACQUIRED_GOOD message is sent. + * However, RETRYING_CAPTURE must not be sent after ACQUIRED_GOOD is sent. + */ + RETRYING_CAPTURE, +} -- GitLab From fd2cbf9981a4b467c22d0cb4bc4a45b67e59712a Mon Sep 17 00:00:00 2001 From: Kai Date: Sun, 21 Feb 2021 19:48:28 -0800 Subject: [PATCH 567/790] Add Unix_time and STORAGE_ENCRYPTION_BINDING_SEED Add two new properties. Unix_time and STORAGE_ENCRYPTION_BINDING_SEED. Bug: 176936731 Bug: 176985441 Test: adb shell cmd car_service get-carpropertyconfig Change-Id: Ib94d8747a1b9ad0f187a8f78a87cd7f10b4506c5 --- .../default/impl/vhal_v2_0/DefaultConfig.h | 16 +++++++ automotive/vehicle/2.0/types.hal | 43 +++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h index 9d0b9ec989..5dca1dc0ff 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h @@ -1146,6 +1146,22 @@ const ConfigDeclaration kVehicleProperties[]{ .changeMode = VehiclePropertyChangeMode::ON_CHANGE, }, }, + { + .config = + { + .prop = toInt(VehicleProperty::UNIX_TIME), + .access = VehiclePropertyAccess::READ_WRITE, + .changeMode = VehiclePropertyChangeMode::ON_CHANGE, + }, + }, + { + .config = + { + .prop = toInt(VehicleProperty::STORAGE_ENCRYPTION_BINDING_SEED), + .access = VehiclePropertyAccess::READ_WRITE, + .changeMode = VehiclePropertyChangeMode::ON_CHANGE, + }, + }, { .config = { diff --git a/automotive/vehicle/2.0/types.hal b/automotive/vehicle/2.0/types.hal index 9ecb2d56d2..eabd7e11fe 100644 --- a/automotive/vehicle/2.0/types.hal +++ b/automotive/vehicle/2.0/types.hal @@ -1347,6 +1347,48 @@ enum VehicleProperty : int32_t { | VehiclePropertyType:INT32 | VehicleArea:GLOBAL), + /** + * Current date and time, encoded as Unix time (in milliseconds). + * This value denotes the number of milliseconds seconds that have + * elapsed since 1/1/1970 UTC. + * + * Reading this value will give you the system’s time. This can be + * useful to synchronize other vehicle systems (dash clock etc). + * + * Writing this value will update the ‘ExternalTimeSuggestion’ + * value (if enabled). This value may be consumed by the “Time + * Detector Service”, if other sources do not have a higher + * priority. For information on how to adjust time source + * priorities see Time Detector Service documentation. + * + * @change_mode VehiclePropertyChangeMode:ON_CHANGE + * @access VehiclePropertyAccess:READ_WRITE + * @unit VehicleUnit:MILLI_SECS + */ + UNIX_TIME = ( + 0x0606 + | VehiclePropertyGroup:SYSTEM + | VehiclePropertyType:INT64 + | VehicleArea:GLOBAL), + + /** + * External encryption binding seed. + * + * This value is mixed with the local key storage encryption key. + * This property holds 16 bytes, and is expected to be persisted on an ECU separate from + * the IVI. The property is initially set by AAOS, who generates it using a CSRNG. + * AAOS will then read the property on subsequent boots. The binding seed is expected to be + * reliably persisted. Any loss of the seed results in a factory reset of the IVI. + * + * @change_mode VehiclePropertyChangeMode:ON_CHANGE + * @access VehiclePropertyAccess:READ_WRITE + */ + STORAGE_ENCRYPTION_BINDING_SEED = ( + 0x0607 + | VehiclePropertyGroup:SYSTEM + | VehiclePropertyType:BYTES + | VehicleArea:GLOBAL), + /** * Outside temperature * @@ -3623,6 +3665,7 @@ enum VehicleUnit : int32_t { US_GALLON = 0x42, IMPERIAL_GALLON = 0x43, NANO_SECS = 0x50, + MILLI_SECS = 0x51, SECS = 0x53, YEAR = 0x59, -- GitLab From 0ec2e0c3ec589a01c98ca5d68ebc4fee0d972f6c Mon Sep 17 00:00:00 2001 From: Kevin Chyn Date: Fri, 26 Mar 2021 18:07:24 -0700 Subject: [PATCH 568/790] Change default IFingerprint HAL back to STRONG This way, cuttlefish presubmit can run tests that require multiple strong sensors Bug: 163058911 Test: atest CtsBiometricsTestCases Change-Id: I8ce66d3bc9fe8ea91465a6fcd5e7e75369b1a90f --- biometrics/fingerprint/aidl/default/Fingerprint.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biometrics/fingerprint/aidl/default/Fingerprint.cpp b/biometrics/fingerprint/aidl/default/Fingerprint.cpp index 734ff600b7..fbfa52f0e7 100644 --- a/biometrics/fingerprint/aidl/default/Fingerprint.cpp +++ b/biometrics/fingerprint/aidl/default/Fingerprint.cpp @@ -22,7 +22,7 @@ namespace aidl::android::hardware::biometrics::fingerprint { namespace { constexpr size_t MAX_WORKER_QUEUE_SIZE = 5; constexpr int SENSOR_ID = 1; -constexpr common::SensorStrength SENSOR_STRENGTH = common::SensorStrength::WEAK; +constexpr common::SensorStrength SENSOR_STRENGTH = common::SensorStrength::STRONG; constexpr int MAX_ENROLLMENTS_PER_USER = 5; constexpr FingerprintSensorType SENSOR_TYPE = FingerprintSensorType::REAR; constexpr bool SUPPORTS_NAVIGATION_GESTURES = true; -- GitLab From 9c45243aef9c9c35381d800459efac3f129c798f Mon Sep 17 00:00:00 2001 From: Ady Abraham Date: Fri, 19 Feb 2021 16:44:31 -0800 Subject: [PATCH 569/790] composer: increase timeout for VTS Some devices expose more then a few display configurations which requires a longer timeout for the VTS to complete. Bug: 180690432 Test: run vts VtsHalGraphicsComposerV2_4TargetTest Change-Id: I4bef6354109d9244997c4b70e8c66b176ac90b10 -- GitLab From 9d432bd3fc707f02aad895c195a3283a65b1056b Mon Sep 17 00:00:00 2001 From: chenpaul Date: Tue, 30 Mar 2021 14:08:38 +0800 Subject: [PATCH 570/790] Wifi: Add argument "WifiHandle" in "wifi_set_subsystem_restart_handler" Bug: 178126071 Bug: 183483123 Test: vendor HAL can received API call Change-Id: If9f4f25dcb5e63b43cf098e410aad308fb4edae6 --- wifi/1.5/default/wifi_legacy_hal.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wifi/1.5/default/wifi_legacy_hal.cpp b/wifi/1.5/default/wifi_legacy_hal.cpp index 848fbd6114..5074252d3d 100644 --- a/wifi/1.5/default/wifi_legacy_hal.cpp +++ b/wifi/1.5/default/wifi_legacy_hal.cpp @@ -1677,7 +1677,7 @@ WifiLegacyHal::getUsableChannels(uint32_t band_mask, uint32_t iface_mode_mask, } wifi_error WifiLegacyHal::triggerSubsystemRestart() { - return global_func_table_.wifi_trigger_subsystem_restart(); + return global_func_table_.wifi_trigger_subsystem_restart(global_handle_); } void WifiLegacyHal::invalidate() { -- GitLab From 7700c1dc2dc69a841d376eba10eaa0fc4afd567e Mon Sep 17 00:00:00 2001 From: Hongbo Zeng Date: Tue, 30 Mar 2021 17:01:53 +0800 Subject: [PATCH 571/790] Fix crash issue for VTS setupDataCall_1_6_osAppId - donot check the osAppId for response if trafficDescriptors is empty due to no matching rule found Bug: 181187711 Test: * run command => atest VtsHalRadioV1_6TargetTest -- --test-arg com.android.tradefed.testtype.GTest:native-test-flag:"--gtest_filter=*slot1") and check the test result is PASSED [2/18] PerInstance/RadioHidlTest_v1_6#setupDataCall_1_6_osAppId/0_slot1: PASSED (24ms) Change-Id: Ic65b7a0eecc14a142ea69c2774344d9b601298fb --- radio/1.6/vts/functional/radio_hidl_hal_api.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp index e060dae6b8..b330585b2f 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp +++ b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp @@ -158,6 +158,9 @@ TEST_P(RadioHidlTest_v1_6, setupDataCall_1_6_osAppId) { {::android::hardware::radio::V1_6::RadioError::NONE, ::android::hardware::radio::V1_6::RadioError::RADIO_NOT_AVAILABLE, ::android::hardware::radio::V1_6::RadioError::OP_NOT_ALLOWED_BEFORE_REG_TO_NW})); + if (radioRsp_v1_6->setupDataCallResult.trafficDescriptors.size() <= 0) { + return; + } EXPECT_EQ(optionalTrafficDescriptor.value().osAppId.value().osAppId, radioRsp_v1_6->setupDataCallResult.trafficDescriptors[0].osAppId.value().osAppId); } -- GitLab From c16f1583cc61a332aede2c9a7c8c756a3a92900d Mon Sep 17 00:00:00 2001 From: Sarah Chin Date: Tue, 30 Mar 2021 11:34:36 -0700 Subject: [PATCH 572/790] Update test to TEST_P VTS tests were moved to parameterized gtests (TEST_F -> TEST_P), so update the test for getSimPhonebookRecords to prevent compile errors Test: mm Fix: 183964306 Change-Id: Ib35c3c06fbe3fa2205bdcd44f70bda805fcb8301 --- radio/1.6/vts/functional/radio_hidl_hal_api.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp index fa65aaacc0..2feb1cdee8 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp +++ b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp @@ -818,7 +818,7 @@ TEST_P(RadioHidlTest_v1_6, getSimPhonebookCapacity) { /* * Test IRadio.updateSimPhonebookRecords() for the response returned. */ -TEST_F(RadioHidlTest_v1_6, updateSimPhonebookRecords) { +TEST_P(RadioHidlTest_v1_6, updateSimPhonebookRecords) { serial = GetRandomSerialNumber(); radio_v1_6->getSimPhonebookCapacity(serial); EXPECT_EQ(std::cv_status::no_timeout, wait()); -- GitLab From ae1c624ba44ccc43dc8371328a4b3caa017c0ff8 Mon Sep 17 00:00:00 2001 From: Edwin Wong Date: Sat, 23 Jan 2021 17:25:14 -0800 Subject: [PATCH 573/790] [RESTRICT AUTOMERGE] Fix CryptoPlugin use after free vulnerability. The shared memory buffer used by srcPtr can be freed by another thread because it is not protected by a mutex. Subsequently, a use after free AIGABRT can occur in a race condition. SafetyNet logging is not added to avoid log spamming. The mutex lock is called to setup for decryption, which is called frequently. Test is run on rvc-dev branch, using target_hwasan-userdebug build. Test: sts sts-tradefed run sts-engbuild-no-spl-lock -m StsHostTestCases --test android.security.sts.Bug_176495665#testPocBug_176495665 Test: push to device with target_hwasan-userdebug build adb shell /data/local/tmp/Bug-176495665_sts64 Bug: 176495665 Bug: 176444161 Change-Id: I3ec33cd444183f40ee76bec4c88dec0dac859cd3 --- drm/1.0/default/Android.bp | 3 ++- drm/1.0/default/CryptoPlugin.cpp | 7 ++++++- drm/1.0/default/CryptoPlugin.h | 21 +++++++++++++-------- 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/drm/1.0/default/Android.bp b/drm/1.0/default/Android.bp index ed6bcdeee6..1122e46a05 100644 --- a/drm/1.0/default/Android.bp +++ b/drm/1.0/default/Android.bp @@ -9,6 +9,7 @@ cc_library_static { "-Werror", "-Wextra", "-Wall", + "-Wthread-safety", ], shared_libs: [ "liblog", @@ -19,5 +20,5 @@ cc_library_static { export_header_lib_headers: [ "libutils_headers", ], - export_include_dirs : ["include"] + export_include_dirs: ["include"], } diff --git a/drm/1.0/default/CryptoPlugin.cpp b/drm/1.0/default/CryptoPlugin.cpp index e71385da5d..9ba7ae7504 100644 --- a/drm/1.0/default/CryptoPlugin.cpp +++ b/drm/1.0/default/CryptoPlugin.cpp @@ -54,6 +54,8 @@ namespace implementation { sp hidlMemory = mapMemory(base); ALOGE_IF(hidlMemory == nullptr, "mapMemory returns nullptr"); + std::lock_guard shared_buffer_lock(mSharedBufferLock); + // allow mapMemory to return nullptr mSharedBufferMap[bufferId] = hidlMemory; return Void(); @@ -66,7 +68,7 @@ namespace implementation { const SharedBuffer& source, uint64_t offset, const DestinationBuffer& destination, decrypt_cb _hidl_cb) { - + std::unique_lock lock(mSharedBufferLock); if (mSharedBufferMap.find(source.bufferId) == mSharedBufferMap.end()) { _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "source decrypt buffer base not set"); return Void(); @@ -174,6 +176,9 @@ namespace implementation { _hidl_cb(Status::BAD_VALUE, 0, "invalid destination type"); return Void(); } + + // release mSharedBufferLock + lock.unlock(); ssize_t result = mLegacyPlugin->decrypt(secure, keyId.data(), iv.data(), legacyMode, legacyPattern, srcPtr, legacySubSamples.get(), subSamples.size(), destPtr, &detailMessage); diff --git a/drm/1.0/default/CryptoPlugin.h b/drm/1.0/default/CryptoPlugin.h index 11cc2aae47..13fe898cb6 100644 --- a/drm/1.0/default/CryptoPlugin.h +++ b/drm/1.0/default/CryptoPlugin.h @@ -17,11 +17,14 @@ #ifndef ANDROID_HARDWARE_DRM_V1_0__CRYPTOPLUGIN_H #define ANDROID_HARDWARE_DRM_V1_0__CRYPTOPLUGIN_H -#include +#include #include +#include #include #include +#include + namespace android { namespace hardware { namespace drm { @@ -60,19 +63,21 @@ struct CryptoPlugin : public ICryptoPlugin { Return setSharedBufferBase(const ::android::hardware::hidl_memory& base, uint32_t bufferId) override; - Return decrypt(bool secure, const hidl_array& keyId, - const hidl_array& iv, Mode mode, const Pattern& pattern, - const hidl_vec& subSamples, const SharedBuffer& source, - uint64_t offset, const DestinationBuffer& destination, - decrypt_cb _hidl_cb) override; + Return decrypt( + bool secure, const hidl_array& keyId, const hidl_array& iv, + Mode mode, const Pattern& pattern, const hidl_vec& subSamples, + const SharedBuffer& source, uint64_t offset, const DestinationBuffer& destination, + decrypt_cb _hidl_cb) override NO_THREAD_SAFETY_ANALYSIS; // use unique_lock -private: + private: android::CryptoPlugin *mLegacyPlugin; - std::map > mSharedBufferMap; + std::map> mSharedBufferMap GUARDED_BY(mSharedBufferLock); CryptoPlugin() = delete; CryptoPlugin(const CryptoPlugin &) = delete; void operator=(const CryptoPlugin &) = delete; + + std::mutex mSharedBufferLock; }; } // namespace implementation -- GitLab From c1982fe71b2161ac0f820388336dfb92cd7c43ed Mon Sep 17 00:00:00 2001 From: Jayant Chowdhary Date: Wed, 24 Mar 2021 10:24:32 -0700 Subject: [PATCH 574/790] camera VTS: Add VTS test for ultra high resolution sensors. Bug: 152813564 Test: VtsHalCameraProviderV2_4TargetTest --gtest_filter=PerInstance/CameraHidlTest.processUltra* on cuttlefish Change-Id: If314fedc5f57a01cb2a103b834356b0c3d51e976 Signed-off-by: Jayant Chowdhary --- .../VtsHalCameraProviderV2_4TargetTest.cpp | 407 +++++++++++++++++- 1 file changed, 394 insertions(+), 13 deletions(-) diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp index b2fd402ed8..ed3b1faa53 100644 --- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp +++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp @@ -125,6 +125,7 @@ using ::android::hardware::camera::device::V3_4::PhysicalCameraMetadata; 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::provider::V2_4::ICameraProvider; using ::android::hardware::camera::provider::V2_4::ICameraProviderCallback; using ::android::hardware::camera::provider::V2_6::CameraIdAndStreamCombination; @@ -767,6 +768,8 @@ public: sp *session3_7 /*out*/); void castDevice(const sp &device, int32_t deviceVersion, sp *device3_5/*out*/); + void castDevice3_7(const sp& device, int32_t deviceVersion, + sp* device3_7 /*out*/); void createStreamConfiguration(const ::android::hardware::hidl_vec& streams3_2, StreamConfigurationMode configMode, ::android::hardware::camera::device::V3_2::StreamConfiguration *config3_2, @@ -785,6 +788,16 @@ public: sp *outCb /*out*/, uint32_t *jpegBufferSize /*out*/, bool *useHalBufManager /*out*/); + void configureStreams3_7(const std::string& name, int32_t deviceVersion, + sp provider, PixelFormat format, + sp* session3_7 /*out*/, + V3_2::Stream* previewStream /*out*/, + device::V3_6::HalStreamConfiguration* halStreamConfig /*out*/, + bool* supportsPartialResults /*out*/, + uint32_t* partialResultCount /*out*/, bool* useHalBufManager /*out*/, + sp* outCb /*out*/, uint32_t streamConfigCounter, + bool maxResolution); + void configurePreviewStreams3_4(const std::string &name, int32_t deviceVersion, sp provider, const AvailableStream *previewThreshold, @@ -846,6 +859,10 @@ public: hidl_vec streamIds, sp cb, uint32_t streamConfigCounter = 0); + void verifyBuffersReturned(sp session, + hidl_vec streamIds, sp cb, + uint32_t streamConfigCounter = 0); + void verifySessionReconfigurationQuery(sp session3_5, camera_metadata* oldSessionParams, camera_metadata* newSessionParams); @@ -853,12 +870,15 @@ public: static bool isDepthOnly(const camera_metadata_t* staticMeta); - static Status getAvailableOutputStreams(const camera_metadata_t *staticMeta, - std::vector &outputStreams, - const AvailableStream *threshold = nullptr); + static bool isUltraHighResolution(const camera_metadata_t* staticMeta); + + static Status getAvailableOutputStreams(const camera_metadata_t* staticMeta, + std::vector& outputStreams, + const AvailableStream* threshold = nullptr, + bool maxResolution = false); static Status getMaxOutputSizeForFormat(const camera_metadata_t* staticMeta, PixelFormat format, - Size* size); + Size* size, bool maxResolution = false); static Status getMandatoryConcurrentStreams(const camera_metadata_t* staticMeta, std::vector* outputStreams); @@ -4841,6 +4861,184 @@ TEST_P(CameraHidlTest, processMultiCaptureRequestPreview) { } } +// Generate and verify an ultra high resolution capture request +TEST_P(CameraHidlTest, processUltraHighResolutionRequest) { + hidl_vec cameraDeviceNames = getCameraDeviceNames(mProvider); + uint64_t bufferId = 1; + uint32_t frameNumber = 1; + ::android::hardware::hidl_vec settings; + + for (const auto& name : cameraDeviceNames) { + int deviceVersion = getCameraDeviceVersion(name, mProviderType); + if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_7) { + continue; + } + std::string version, deviceId; + ASSERT_TRUE(::matchDeviceName(name, mProviderType, &version, &deviceId)); + camera_metadata_t* staticMeta; + Return ret; + sp session; + openEmptyDeviceSession(name, mProvider, &session, &staticMeta); + if (!isUltraHighResolution(staticMeta)) { + free_camera_metadata(staticMeta); + ret = session->close(); + ASSERT_TRUE(ret.isOk()); + continue; + } + 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(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()); + uint8_t sensorPixelMode = + static_cast(ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION); + ASSERT_EQ(::android::OK, + defaultSettings.update(ANDROID_SENSOR_PIXEL_MODE, &sensorPixelMode, 1)); + + const camera_metadata_t* settingsBuffer = defaultSettings.getAndLock(); + settings.setToExternal( + reinterpret_cast(const_cast(settingsBuffer)), + get_camera_metadata_size(settingsBuffer)); + + 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 session3_7; + sp cb; + std::list pixelFormats = {PixelFormat::YCBCR_420_888, PixelFormat::RAW16}; + for (PixelFormat format : pixelFormats) { + configureStreams3_7(name, deviceVersion, mProvider, format, &session3_7, &previewStream, + &halStreamConfig, &supportsPartialResults, &partialResultCount, + &useHalBufManager, &cb, 0, /*maxResolution*/ true); + ASSERT_NE(session3_7, nullptr); + + std::shared_ptr resultQueue; + auto resultQueueRet = session3_7->getCaptureResultMetadataQueue( + [&resultQueue](const auto& descriptor) { + resultQueue = std::make_shared(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 graphicBuffers; + graphicBuffers.reserve(halStreamConfig.streams.size()); + ::android::hardware::hidl_vec outputBuffers; + outputBuffers.resize(halStreamConfig.streams.size()); + InFlightRequest inflightReq = {static_cast(halStreamConfig.streams.size()), + false, + supportsPartialResults, + partialResultCount, + std::unordered_set(), + 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 l(mLock); + mInflightMap.clear(); + mInflightMap.add(frameNumber, &inflightReq); + } + + Status stat = Status::INTERNAL_ERROR; + uint32_t numRequestProcessed = 0; + hidl_vec cachesToRemove; + Return returnStatus = session3_7->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 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); + } + if (useHalBufManager) { + hidl_vec 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; + } + verifyBuffersReturned(session3_7, streamIds, cb); + } + + ret = session3_7->close(); + ASSERT_TRUE(ret.isOk()); + } + } +} + // Generate and verify a burst containing alternating sensor sensitivity values TEST_P(CameraHidlTest, processCaptureRequestBurstISO) { hidl_vec cameraDeviceNames = getCameraDeviceNames(mProvider); @@ -5537,21 +5735,26 @@ TEST_P(CameraHidlTest, providerDeviceStateNotification) { // Retrieve all valid output stream resolutions from the camera // static characteristics. -Status CameraHidlTest::getAvailableOutputStreams(const camera_metadata_t *staticMeta, - std::vector &outputStreams, - const AvailableStream *threshold) { +Status CameraHidlTest::getAvailableOutputStreams(const camera_metadata_t* staticMeta, + std::vector& outputStreams, + const AvailableStream* threshold, + bool maxResolution) { AvailableStream depthPreviewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight, static_cast(PixelFormat::Y16)}; if (nullptr == staticMeta) { return Status::ILLEGAL_ARGUMENT; } + int scalerTag = maxResolution + ? ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION + : ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS; + int depthTag = maxResolution + ? ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION + : ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS; camera_metadata_ro_entry scalarEntry; camera_metadata_ro_entry depthEntry; - int foundScalar = find_camera_metadata_ro_entry(staticMeta, - ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, &scalarEntry); - int foundDepth = find_camera_metadata_ro_entry(staticMeta, - ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS, &depthEntry); + int foundScalar = find_camera_metadata_ro_entry(staticMeta, scalerTag, &scalarEntry); + int foundDepth = find_camera_metadata_ro_entry(staticMeta, depthTag, &depthEntry); if ((0 != foundScalar || (0 != (scalarEntry.count % 4))) && (0 != foundDepth || (0 != (depthEntry.count % 4)))) { return Status::ILLEGAL_ARGUMENT; @@ -5619,9 +5822,12 @@ Status CameraHidlTest::getMandatoryConcurrentStreams(const camera_metadata_t* st } Status CameraHidlTest::getMaxOutputSizeForFormat(const camera_metadata_t* staticMeta, - PixelFormat format, Size* size) { + PixelFormat format, Size* size, + bool maxResolution) { std::vector outputStreams; - if (size == nullptr || getAvailableOutputStreams(staticMeta, outputStreams) != Status::OK) { + if (size == nullptr || + getAvailableOutputStreams(staticMeta, outputStreams, + /*threshold*/ nullptr, maxResolution) != Status::OK) { return Status::ILLEGAL_ARGUMENT; } Size maxSize; @@ -6065,6 +6271,148 @@ void CameraHidlTest::createStreamConfiguration( *config3_2 = {streams3_2, configMode}; } +// Configure streams +void CameraHidlTest::configureStreams3_7( + const std::string& name, int32_t deviceVersion, sp provider, + PixelFormat format, sp* session3_7 /*out*/, + V3_2::Stream* previewStream /*out*/, + device::V3_6::HalStreamConfiguration* halStreamConfig /*out*/, + bool* supportsPartialResults /*out*/, uint32_t* partialResultCount /*out*/, + bool* useHalBufManager /*out*/, sp* outCb /*out*/, uint32_t streamConfigCounter, + bool maxResolution) { + ASSERT_NE(nullptr, session3_7); + ASSERT_NE(nullptr, halStreamConfig); + ASSERT_NE(nullptr, previewStream); + ASSERT_NE(nullptr, supportsPartialResults); + ASSERT_NE(nullptr, partialResultCount); + ASSERT_NE(nullptr, useHalBufManager); + ASSERT_NE(nullptr, outCb); + + std::vector outputStreams; + ::android::sp device3_x; + ALOGI("configureStreams: Testing camera device %s", name.c_str()); + Return 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(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 cb = new DeviceCb(this, deviceVersion, staticMeta); + sp 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 session3_3; + sp session3_4; + sp session3_5; + sp session3_6; + castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, &session3_6, + session3_7); + ASSERT_NE(nullptr, (*session3_7).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 streams3_7(1); + streams3_7[0].groupId = -1; + streams3_7[0].sensorPixelModesUsed = { + CameraMetadataEnumAndroidSensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION}; + streams3_7[0].v3_4.bufferSize = 0; + streams3_7[0].v3_4.v3_2.id = 0; + streams3_7[0].v3_4.v3_2.streamType = StreamType::OUTPUT; + streams3_7[0].v3_4.v3_2.width = static_cast(maxSize.width); + streams3_7[0].v3_4.v3_2.height = static_cast(maxSize.height); + streams3_7[0].v3_4.v3_2.format = static_cast(format); + streams3_7[0].v3_4.v3_2.usage = GRALLOC1_CONSUMER_USAGE_CPU_READ; + streams3_7[0].v3_4.v3_2.dataSpace = 0; + streams3_7[0].v3_4.v3_2.rotation = StreamRotation::ROTATION_0; + + ::android::hardware::camera::device::V3_7::StreamConfiguration config3_7; + config3_7.streams = streams3_7; + config3_7.operationMode = StreamConfigurationMode::NORMAL_MODE; + config3_7.streamConfigCounter = streamConfigCounter; + config3_7.multiResolutionInputImage = false; + RequestTemplate reqTemplate = RequestTemplate::STILL_CAPTURE; + ret = (*session3_7) + ->constructDefaultRequestSettings(reqTemplate, + [&config3_7](auto status, const auto& req) { + ASSERT_EQ(Status::OK, status); + config3_7.sessionParams = req; + }); + ASSERT_TRUE(ret.isOk()); + + ASSERT_TRUE(deviceVersion >= CAMERA_DEVICE_API_VERSION_3_7); + sp cameraDevice3_7 = nullptr; + castDevice3_7(device3_x, deviceVersion, &cameraDevice3_7); + ASSERT_NE(cameraDevice3_7, nullptr); + bool supported = false; + ret = cameraDevice3_7->isStreamCombinationSupported_3_7( + config3_7, [&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_7 != nullptr) { + ret = (*session3_7) + ->configureStreams_3_7( + config3_7, + [&](Status s, device::V3_6::HalStreamConfiguration halConfig) { + ASSERT_EQ(Status::OK, s); + *halStreamConfig = halConfig; + if (*useHalBufManager) { + hidl_vec streams(1); + hidl_vec halStreams(1); + streams[0] = streams3_7[0].v3_4; + halStreams[0] = halConfig.streams[0].v3_4.v3_3.v3_2; + cb->setCurrentStreamConfig(streams, halStreams); + } + }); + } + *previewStream = streams3_7[0].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 provider, @@ -6362,6 +6710,21 @@ void CameraHidlTest::configureOfflineStillStream(const std::string &name, ASSERT_TRUE(ret.isOk()); } +bool CameraHidlTest::isUltraHighResolution(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_ULTRA_HIGH_RESOLUTION_SENSOR) { + return true; + } + } + } + return false; +} + bool CameraHidlTest::isDepthOnly(const camera_metadata_t* staticMeta) { camera_metadata_ro_entry scalarEntry; camera_metadata_ro_entry depthEntry; @@ -6590,6 +6953,17 @@ void CameraHidlTest::configureSingleStream( ASSERT_TRUE(ret.isOk()); } +void CameraHidlTest::castDevice3_7(const sp& device, + int32_t deviceVersion, + sp* device3_7 /*out*/) { + ASSERT_NE(nullptr, device3_7); + if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_7) { + auto castResult = device::V3_7::ICameraDevice::castFrom(device); + ASSERT_TRUE(castResult.isOk()); + *device3_7 = castResult; + } +} + void CameraHidlTest::castDevice(const sp &device, int32_t deviceVersion, sp *device3_5/*out*/) { ASSERT_NE(nullptr, device3_5); @@ -7303,6 +7677,13 @@ void CameraHidlTest::verifyBuffersReturned( cb->waitForBuffersReturned(); } +void CameraHidlTest::verifyBuffersReturned(sp session3_7, + hidl_vec streamIds, sp cb, + uint32_t streamConfigCounter) { + session3_7->signalStreamFlush(streamIds, /*streamConfigCounter*/ streamConfigCounter); + cb->waitForBuffersReturned(); +} + void CameraHidlTest::verifyLogicalCameraResult(const camera_metadata_t* staticMetadata, const ::android::hardware::camera::common::V1_0::helper::CameraMetadata& resultMetadata) { std::unordered_set physicalIds; -- GitLab From e6915053455ec7a2b616a5ecb82cb6c82e32c307 Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Tue, 30 Mar 2021 13:44:43 -0700 Subject: [PATCH 575/790] Refactor Tuner 1.0 vts to use dynamic configuration This CL starts the refatoring of Tuner 1.0 vts configuration file to replace the previous manual config with the current dynamic config using xml/xsd. Note that this CL only connects the frontend setting section with the dynamic config. The CLs to connect other hardware configs will come as child CLs. This CL also has some default implementation/vts test impl changes to sync the sc-dev vts 1.0 with the aosp. Child CL will also replace the 1.1 manual config with the dynamic config. Test: atest VtsHalTvTunerV1_0TargetTest Bug: 182519645 CTS-Coverage-Bug: 184077478 Change-Id: I13e6ea3d91e474c10e4f822a6ce59d99cc7c7d1d --- tv/tuner/1.0/default/Tuner.cpp | 2 + tv/tuner/1.0/vts/functional/Android.bp | 12 + tv/tuner/1.0/vts/functional/FrontendTests.h | 1 + .../VtsHalTvTunerV1_0TargetTest.cpp | 101 +++--- .../functional/VtsHalTvTunerV1_0TargetTest.h | 36 ++- .../VtsHalTvTunerV1_0TestConfigurations.h | 114 +++---- tv/tuner/1.1/default/Tuner.cpp | 2 + tv/tuner/config/Android.bp | 31 ++ tv/tuner/config/TunerTestingConfigReader.h | 293 ++++++++++++++++++ tv/tuner/config/api/current.txt | 143 +++++++++ tv/tuner/config/api/last_current.txt | 0 tv/tuner/config/api/last_removed.txt | 0 tv/tuner/config/api/removed.txt | 1 + tv/tuner/config/sample_tuner_vts_config.xml | 75 +++++ .../tuner_testing_dynamic_configuration.xsd | 188 +++++++++++ 15 files changed, 882 insertions(+), 117 deletions(-) create mode 100644 tv/tuner/config/Android.bp create mode 100644 tv/tuner/config/TunerTestingConfigReader.h create mode 100644 tv/tuner/config/api/current.txt create mode 100644 tv/tuner/config/api/last_current.txt create mode 100644 tv/tuner/config/api/last_removed.txt create mode 100644 tv/tuner/config/api/removed.txt create mode 100644 tv/tuner/config/sample_tuner_vts_config.xml create mode 100644 tv/tuner/config/tuner_testing_dynamic_configuration.xsd diff --git a/tv/tuner/1.0/default/Tuner.cpp b/tv/tuner/1.0/default/Tuner.cpp index 9a6ecf704f..c4f610ee23 100644 --- a/tv/tuner/1.0/default/Tuner.cpp +++ b/tv/tuner/1.0/default/Tuner.cpp @@ -139,6 +139,8 @@ Return Tuner::getDemuxCaps(getDemuxCaps_cb _hidl_cb) { // IP filter can be an MMTP filter's data source. caps.linkCaps = {0x00, 0x00, 0x02, 0x00, 0x00}; + // Support time filter testing + caps.bTimeFilter = true; _hidl_cb(Result::SUCCESS, caps); return Void(); } diff --git a/tv/tuner/1.0/vts/functional/Android.bp b/tv/tuner/1.0/vts/functional/Android.bp index c27a935c2e..6187c738ee 100644 --- a/tv/tuner/1.0/vts/functional/Android.bp +++ b/tv/tuner/1.0/vts/functional/Android.bp @@ -35,6 +35,15 @@ cc_test { "DescramblerTests.cpp", "LnbTests.cpp", ], + generated_headers: [ + "tuner_testing_dynamic_configuration_V1_0_enums", + "tuner_testing_dynamic_configuration_V1_0_parser", + ], + generated_sources: [ + "tuner_testing_dynamic_configuration_V1_0_enums", + "tuner_testing_dynamic_configuration_V1_0_parser", + ], + header_libs: ["libxsdc-utils"], static_libs: [ "android.hardware.cas@1.0", "android.hardware.cas@1.1", @@ -49,9 +58,12 @@ cc_test { ], shared_libs: [ "libbinder", + "libxml2", ], data: [ ":tuner_frontend_input_ts", + ":tuner_frontend_input_es", + ":tuner_testing_dynamic_configuration_V1_0", ], test_suites: [ "general-tests", diff --git a/tv/tuner/1.0/vts/functional/FrontendTests.h b/tv/tuner/1.0/vts/functional/FrontendTests.h index 4974ff351e..33ff603b85 100644 --- a/tv/tuner/1.0/vts/functional/FrontendTests.h +++ b/tv/tuner/1.0/vts/functional/FrontendTests.h @@ -132,6 +132,7 @@ class FrontendTests { static AssertionResult failure() { return ::testing::AssertionFailure(); } static AssertionResult success() { return ::testing::AssertionSuccess(); } + // TODO: replace with customized dvr input void getDefaultSoftwareFrontendPlaybackConfig(DvrConfig& dvrConfig) { PlaybackSettings playbackSettings{ .statusMask = 0xf, diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp index 891619a810..92996f9dc7 100644 --- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp +++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp @@ -18,16 +18,15 @@ namespace { -AssertionResult TunerBroadcastHidlTest::filterDataOutputTest(vector /*goldenOutputFiles*/) { +AssertionResult TunerBroadcastHidlTest::filterDataOutputTest() { return filterDataOutputTestBase(mFilterTests); } -AssertionResult TunerPlaybackHidlTest::filterDataOutputTest(vector /*goldenOutputFiles*/) { +AssertionResult TunerPlaybackHidlTest::filterDataOutputTest() { return filterDataOutputTestBase(mFilterTests); } -AssertionResult TunerDescramblerHidlTest::filterDataOutputTest( - vector /*goldenOutputFiles*/) { +AssertionResult TunerDescramblerHidlTest::filterDataOutputTest() { return filterDataOutputTestBase(mFilterTests); } @@ -62,8 +61,14 @@ void TunerFilterHidlTest::testTimeFilter(TimeFilterConfig filterConf) { } uint32_t demuxId; sp demux; + DemuxCapabilities caps; ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); + // TODO: add time filter hardware support checker + ASSERT_TRUE(mDemuxTests.getDemuxCaps(caps)); + if (!caps.bTimeFilter) { + return; + } mFilterTests.setDemux(demux); ASSERT_TRUE(mFilterTests.openTimeFilterInDemux()); ASSERT_TRUE(mFilterTests.setTimeStamp(filterConf.timeStamp)); @@ -75,9 +80,6 @@ void TunerFilterHidlTest::testTimeFilter(TimeFilterConfig filterConf) { void TunerBroadcastHidlTest::broadcastSingleFilterTest(FilterConfig filterConf, FrontendConfig frontendConf) { - if (!frontendConf.enable) { - return; - } uint32_t feId; uint32_t demuxId; sp demux; @@ -106,7 +108,7 @@ void TunerBroadcastHidlTest::broadcastSingleFilterTest(FilterConfig filterConf, ASSERT_TRUE(mFilterTests.startFilter(filterId)); // tune test ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/)); - ASSERT_TRUE(filterDataOutputTest(goldenOutputFiles)); + ASSERT_TRUE(filterDataOutputTest()); ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/)); ASSERT_TRUE(mFilterTests.stopFilter(filterId)); ASSERT_TRUE(mFilterTests.closeFilter(filterId)); @@ -119,12 +121,12 @@ void TunerBroadcastHidlTest::broadcastSingleFilterTestWithLnb(FilterConfig filte LnbConfig lnbConf) { vector ids; ASSERT_TRUE(mLnbTests.getLnbIds(ids)); - if (!lnbConf.usingLnb) { + if (ids.size() == 0) { return; } ASSERT_TRUE(ids.size() > 0); ASSERT_TRUE(mLnbTests.openLnbById(ids[0])); - *mLnbId = ids[0]; + mLnbId = &ids[0]; ASSERT_TRUE(mLnbTests.setLnbCallback()); ASSERT_TRUE(mLnbTests.setVoltage(lnbConf.voltage)); ASSERT_TRUE(mLnbTests.setTone(lnbConf.tone)); @@ -152,7 +154,7 @@ void TunerPlaybackHidlTest::playbackSingleFilterTest(FilterConfig filterConf, Dv mDvrTests.startPlaybackInputThread(dvrConf.playbackInputFile, dvrConf.settings.playback()); ASSERT_TRUE(mDvrTests.startDvrPlayback()); ASSERT_TRUE(mFilterTests.startFilter(filterId)); - ASSERT_TRUE(filterDataOutputTest(goldenOutputFiles)); + ASSERT_TRUE(filterDataOutputTest()); mDvrTests.stopPlaybackThread(); ASSERT_TRUE(mFilterTests.stopFilter(filterId)); ASSERT_TRUE(mDvrTests.stopDvrPlayback()); @@ -163,9 +165,6 @@ void TunerPlaybackHidlTest::playbackSingleFilterTest(FilterConfig filterConf, Dv void TunerRecordHidlTest::recordSingleFilterTest(FilterConfig filterConf, FrontendConfig frontendConf, DvrConfig dvrConf) { - if (!frontendConf.enable) { - return; - } uint32_t feId; uint32_t demuxId; sp demux; @@ -215,12 +214,12 @@ void TunerRecordHidlTest::recordSingleFilterTestWithLnb(FilterConfig filterConf, DvrConfig dvrConf, LnbConfig lnbConf) { vector ids; ASSERT_TRUE(mLnbTests.getLnbIds(ids)); - if (!lnbConf.usingLnb) { + if (ids.size() == 0) { return; } ASSERT_TRUE(ids.size() > 0); ASSERT_TRUE(mLnbTests.openLnbById(ids[0])); - *mLnbId = ids[0]; + mLnbId = &ids[0]; ASSERT_TRUE(mLnbTests.setLnbCallback()); ASSERT_TRUE(mLnbTests.setVoltage(lnbConf.voltage)); ASSERT_TRUE(mLnbTests.setTone(lnbConf.tone)); @@ -271,9 +270,6 @@ void TunerRecordHidlTest::attachSingleFilterToRecordDvrTest(FilterConfig filterC void TunerDescramblerHidlTest::scrambledBroadcastTest(set mediaFilterConfs, FrontendConfig frontendConf, DescramblerConfig descConfig) { - if (!frontendConf.enable) { - return; - } uint32_t feId; uint32_t demuxId; sp demux; @@ -319,7 +315,7 @@ void TunerDescramblerHidlTest::scrambledBroadcastTest(set m } // tune test ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/)); - ASSERT_TRUE(filterDataOutputTest(goldenOutputFiles)); + ASSERT_TRUE(filterDataOutputTest()); ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/)); for (id = filterIds.begin(); id != filterIds.end(); id++) { ASSERT_TRUE(mFilterTests.stopFilter(*id)); @@ -337,21 +333,27 @@ void TunerDescramblerHidlTest::scrambledBroadcastTest(set m TEST_P(TunerFrontendHidlTest, TuneFrontend) { description("Tune one Frontend with specific setting and check Lock event"); - mFrontendTests.tuneTest(frontendArray[defaultFrontend]); + mFrontendTests.tuneTest(frontendMap[live.frontendId]); } TEST_P(TunerFrontendHidlTest, AutoScanFrontend) { description("Run an auto frontend scan with specific setting and check lock scanMessage"); - mFrontendTests.scanTest(frontendScanArray[defaultScanFrontend], FrontendScanType::SCAN_AUTO); + mFrontendTests.scanTest(frontendMap[scan.frontendId], FrontendScanType::SCAN_AUTO); } TEST_P(TunerFrontendHidlTest, BlindScanFrontend) { description("Run an blind frontend scan with specific setting and check lock scanMessage"); - mFrontendTests.scanTest(frontendScanArray[defaultScanFrontend], FrontendScanType::SCAN_BLIND); + mFrontendTests.scanTest(frontendMap[scan.frontendId], FrontendScanType::SCAN_BLIND); } TEST_P(TunerLnbHidlTest, OpenLnbByName) { description("Open and configure an Lnb with name then send a diseqc msg to it."); + // TODO: add lnb hardware support checker + vector ids; + ASSERT_TRUE(mLnbTests.getLnbIds(ids)); + if (ids.size() == 0) { + return; + } ASSERT_TRUE(mLnbTests.openLnbByName(lnbArray[LNB_EXTERNAL].name)); ASSERT_TRUE(mLnbTests.setLnbCallback()); ASSERT_TRUE(mLnbTests.setVoltage(lnbArray[LNB_EXTERNAL].voltage)); @@ -365,7 +367,7 @@ TEST_P(TunerLnbHidlTest, SendDiseqcMessageToLnb) { description("Open and configure an Lnb with specific settings then send a diseqc msg to it."); vector ids; ASSERT_TRUE(mLnbTests.getLnbIds(ids)); - if (!lnbArray[LNB0].usingLnb) { + if (ids.size() == 0) { return; } ASSERT_TRUE(ids.size() > 0); @@ -383,7 +385,7 @@ TEST_P(TunerDemuxHidlTest, openDemux) { uint32_t feId; uint32_t demuxId; sp demux; - mFrontendTests.getFrontendIdByType(frontendArray[defaultFrontend].type, feId); + mFrontendTests.getFrontendIdByType(frontendMap[live.frontendId].type, feId); ASSERT_TRUE(feId != INVALID_ID); ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); ASSERT_TRUE(mFrontendTests.setFrontendCallback()); @@ -403,7 +405,7 @@ TEST_P(TunerDemuxHidlTest, getAvSyncTime) { uint32_t avSyncHwId; sp mediaFilter; - mFrontendTests.getFrontendIdByType(frontendArray[defaultFrontend].type, feId); + mFrontendTests.getFrontendIdByType(frontendMap[live.frontendId].type, feId); ASSERT_TRUE(feId != INVALID_ID); ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); ASSERT_TRUE(mFrontendTests.setFrontendCallback()); @@ -431,7 +433,7 @@ TEST_P(TunerDemuxHidlTest, getAvSyncTime) { TEST_P(TunerFilterHidlTest, StartFilterInDemux) { description("Open and start a filter in Demux."); // TODO use paramterized tests - configSingleFilterInDemuxTest(filterArray[TS_VIDEO0], frontendArray[defaultFrontend]); + configSingleFilterInDemuxTest(filterArray[TS_VIDEO0], frontendMap[live.frontendId]); } TEST_P(TunerFilterHidlTest, SetFilterLinkage) { @@ -472,27 +474,27 @@ TEST_P(TunerFilterHidlTest, testTimeFilter) { TEST_P(TunerBroadcastHidlTest, BroadcastDataFlowVideoFilterTest) { description("Test Video Filter functionality in Broadcast use case."); - broadcastSingleFilterTest(filterArray[TS_VIDEO1], frontendArray[defaultFrontend]); + broadcastSingleFilterTest(filterArray[TS_VIDEO1], frontendMap[live.frontendId]); } TEST_P(TunerBroadcastHidlTest, BroadcastDataFlowAudioFilterTest) { description("Test Audio Filter functionality in Broadcast use case."); - broadcastSingleFilterTest(filterArray[TS_AUDIO0], frontendArray[defaultFrontend]); + broadcastSingleFilterTest(filterArray[TS_AUDIO0], frontendMap[live.frontendId]); } TEST_P(TunerBroadcastHidlTest, BroadcastDataFlowSectionFilterTest) { description("Test Section Filter functionality in Broadcast use case."); - broadcastSingleFilterTest(filterArray[TS_SECTION0], frontendArray[defaultFrontend]); + broadcastSingleFilterTest(filterArray[TS_SECTION0], frontendMap[live.frontendId]); } TEST_P(TunerBroadcastHidlTest, IonBufferTest) { description("Test the av filter data bufferring."); - broadcastSingleFilterTest(filterArray[TS_VIDEO0], frontendArray[defaultFrontend]); + broadcastSingleFilterTest(filterArray[TS_VIDEO0], frontendMap[live.frontendId]); } TEST_P(TunerBroadcastHidlTest, LnbBroadcastDataFlowVideoFilterTest) { description("Test Video Filter functionality in Broadcast with Lnb use case."); - broadcastSingleFilterTest(filterArray[TS_VIDEO0], frontendArray[DVBS]); + broadcastSingleFilterTest(filterArray[TS_VIDEO0], frontendMap[live.frontendId]); } TEST_P(TunerBroadcastHidlTest, BroadcastEsDataFlowMediaFiltersTest) { @@ -502,7 +504,7 @@ TEST_P(TunerBroadcastHidlTest, BroadcastEsDataFlowMediaFiltersTest) { sp demux; uint32_t filterId; - mFrontendTests.getFrontendIdByType(frontendArray[defaultFrontend].type, feId); + mFrontendTests.getFrontendIdByType(frontendMap[live.frontendId].type, feId); if (feId == INVALID_ID) { // TODO broadcast test on Cuttlefish needs licensed ts input, // these tests are runnable on vendor device with real frontend module @@ -528,6 +530,7 @@ TEST_P(TunerBroadcastHidlTest, BroadcastEsDataFlowMediaFiltersTest) { ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterArray[TS_VIDEO1].getMqDesc)); ASSERT_TRUE(mFilterTests.startFilter(filterId)); // tune test + // TODO: replace with customized dvr input PlaybackSettings playbackSettings{ .statusMask = 0xf, .lowThreshold = 0x1000, @@ -542,9 +545,8 @@ TEST_P(TunerBroadcastHidlTest, BroadcastEsDataFlowMediaFiltersTest) { }; dvrConfig.settings.playback(playbackSettings); mFrontendTests.setSoftwareFrontendDvrConfig(dvrConfig); - ASSERT_TRUE( - mFrontendTests.tuneFrontend(frontendArray[defaultFrontend], true /*testWithDemux*/)); - ASSERT_TRUE(filterDataOutputTest(goldenOutputFiles)); + ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendMap[live.frontendId], true /*testWithDemux*/)); + ASSERT_TRUE(filterDataOutputTest()); ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/)); ASSERT_TRUE(mFilterTests.stopFilter(filterId)); ASSERT_TRUE(mFilterTests.closeFilter(filterId)); @@ -560,27 +562,40 @@ TEST_P(TunerPlaybackHidlTest, PlaybackDataFlowWithTsSectionFilterTest) { TEST_P(TunerRecordHidlTest, AttachFiltersToRecordTest) { description("Attach a single filter to the record dvr test."); // TODO use paramterized tests - attachSingleFilterToRecordDvrTest(filterArray[TS_RECORD0], frontendArray[defaultFrontend], + if (!record.support) { + return; + } + attachSingleFilterToRecordDvrTest(filterArray[TS_RECORD0], frontendMap[record.frontendId], dvrArray[DVR_RECORD0]); } TEST_P(TunerRecordHidlTest, RecordDataFlowWithTsRecordFilterTest) { description("Feed ts data from frontend to recording and test with ts record filter"); - recordSingleFilterTest(filterArray[TS_RECORD0], frontendArray[defaultFrontend], + if (!record.support) { + return; + } + recordSingleFilterTest(filterArray[TS_RECORD0], frontendMap[record.frontendId], dvrArray[DVR_RECORD0]); } TEST_P(TunerRecordHidlTest, LnbRecordDataFlowWithTsRecordFilterTest) { description("Feed ts data from Fe with Lnb to recording and test with ts record filter"); - recordSingleFilterTest(filterArray[TS_RECORD0], frontendArray[DVBS], dvrArray[DVR_RECORD0]); + if (record.support) { + return; + } + recordSingleFilterTestWithLnb(filterArray[TS_RECORD0], frontendMap[lnbRecord.frontendId], + dvrArray[DVR_RECORD0], lnbArray[LNB0]); } TEST_P(TunerDescramblerHidlTest, CreateDescrambler) { description("Create Descrambler"); + if (descrambling.support) { + return; + } uint32_t feId; uint32_t demuxId; sp demux; - mFrontendTests.getFrontendIdByType(frontendArray[defaultFrontend].type, feId); + mFrontendTests.getFrontendIdByType(frontendMap[descrambling.frontendId].type, feId); ASSERT_TRUE(feId != INVALID_ID); ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); ASSERT_TRUE(mFrontendTests.setFrontendCallback()); @@ -594,10 +609,14 @@ TEST_P(TunerDescramblerHidlTest, CreateDescrambler) { TEST_P(TunerDescramblerHidlTest, ScrambledBroadcastDataFlowMediaFiltersTest) { description("Test ts audio filter in scrambled broadcast use case"); + if (descrambling.support) { + return; + } set filterConfs; filterConfs.insert(filterArray[TS_AUDIO0]); filterConfs.insert(filterArray[TS_VIDEO1]); - scrambledBroadcastTest(filterConfs, frontendArray[defaultFrontend], descramblerArray[DESC_0]); + scrambledBroadcastTest(filterConfs, frontendMap[descrambling.frontendId], + descramblerArray[DESC_0]); } INSTANTIATE_TEST_SUITE_P( diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h index 5a23ca5f4a..d1f6a45366 100644 --- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h +++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h @@ -28,14 +28,24 @@ static AssertionResult success() { namespace { -void initConfiguration() { +bool initConfiguration() { + if (!TunerTestingConfigReader::checkConfigFileExists()) { + return false; + } initFrontendConfig(); - initFrontendScanConfig(); + connectHardwaresToTestCases(); + if (!validateConnections()) { + ALOGW("[vts] failed to validate connections."); + return false; + } + initLnbConfig(); initFilterConfig(); initTimeFilterConfig(); initDvrConfig(); initDescramblerConfig(); + + return true; } AssertionResult filterDataOutputTestBase(FilterTests tests) { @@ -53,7 +63,7 @@ class TunerFrontendHidlTest : public testing::TestWithParam { virtual void SetUp() override { mService = ITuner::getService(GetParam()); ASSERT_NE(mService, nullptr); - initConfiguration(); + ASSERT_TRUE(initConfiguration()); mFrontendTests.setService(mService); } @@ -75,7 +85,7 @@ class TunerLnbHidlTest : public testing::TestWithParam { virtual void SetUp() override { mService = ITuner::getService(GetParam()); ASSERT_NE(mService, nullptr); - initConfiguration(); + ASSERT_TRUE(initConfiguration()); mLnbTests.setService(mService); } @@ -97,7 +107,7 @@ class TunerDemuxHidlTest : public testing::TestWithParam { virtual void SetUp() override { mService = ITuner::getService(GetParam()); ASSERT_NE(mService, nullptr); - initConfiguration(); + ASSERT_TRUE(initConfiguration()); mFrontendTests.setService(mService); mDemuxTests.setService(mService); @@ -123,7 +133,7 @@ class TunerFilterHidlTest : public testing::TestWithParam { virtual void SetUp() override { mService = ITuner::getService(GetParam()); ASSERT_NE(mService, nullptr); - initConfiguration(); + ASSERT_TRUE(initConfiguration()); mFrontendTests.setService(mService); mDemuxTests.setService(mService); @@ -152,7 +162,7 @@ class TunerBroadcastHidlTest : public testing::TestWithParam { virtual void SetUp() override { mService = ITuner::getService(GetParam()); ASSERT_NE(mService, nullptr); - initConfiguration(); + ASSERT_TRUE(initConfiguration()); mFrontendTests.setService(mService); mDemuxTests.setService(mService); @@ -173,7 +183,7 @@ class TunerBroadcastHidlTest : public testing::TestWithParam { LnbTests mLnbTests; DvrTests mDvrTests; - AssertionResult filterDataOutputTest(vector goldenOutputFiles); + AssertionResult filterDataOutputTest(); void broadcastSingleFilterTest(FilterConfig filterConf, FrontendConfig frontendConf); void broadcastSingleFilterTestWithLnb(FilterConfig filterConf, FrontendConfig frontendConf, @@ -191,7 +201,7 @@ class TunerPlaybackHidlTest : public testing::TestWithParam { virtual void SetUp() override { mService = ITuner::getService(GetParam()); ASSERT_NE(mService, nullptr); - initConfiguration(); + ASSERT_TRUE(initConfiguration()); mFrontendTests.setService(mService); mDemuxTests.setService(mService); @@ -210,7 +220,7 @@ class TunerPlaybackHidlTest : public testing::TestWithParam { FilterTests mFilterTests; DvrTests mDvrTests; - AssertionResult filterDataOutputTest(vector goldenOutputFiles); + AssertionResult filterDataOutputTest(); void playbackSingleFilterTest(FilterConfig filterConf, DvrConfig dvrConf); }; @@ -223,7 +233,7 @@ class TunerRecordHidlTest : public testing::TestWithParam { virtual void SetUp() override { mService = ITuner::getService(GetParam()); ASSERT_NE(mService, nullptr); - initConfiguration(); + ASSERT_TRUE(initConfiguration()); mFrontendTests.setService(mService); mDemuxTests.setService(mService); @@ -265,7 +275,7 @@ class TunerDescramblerHidlTest : public testing::TestWithParam { mCasService = IMediaCasService::getService(); ASSERT_NE(mService, nullptr); ASSERT_NE(mCasService, nullptr); - initConfiguration(); + ASSERT_TRUE(initConfiguration()); mFrontendTests.setService(mService); mDemuxTests.setService(mService); @@ -281,7 +291,7 @@ class TunerDescramblerHidlTest : public testing::TestWithParam { void scrambledBroadcastTest(set mediaFilterConfs, FrontendConfig frontendConf, DescramblerConfig descConfig); - AssertionResult filterDataOutputTest(vector /*goldenOutputFiles*/); + AssertionResult filterDataOutputTest(); sp mService; sp mCasService; diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h index 834e296872..384455bc74 100644 --- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h +++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h @@ -21,6 +21,9 @@ #include #include +#include "../../../config/TunerTestingConfigReader.h" + +// TODO: remove unnecessary imports after config reader refactoring is done. using android::hardware::tv::tuner::V1_0::DataFormat; using android::hardware::tv::tuner::V1_0::DemuxAlpFilterType; using android::hardware::tv::tuner::V1_0::DemuxFilterEvent; @@ -54,7 +57,9 @@ using android::hardware::tv::tuner::V1_0::PlaybackSettings; using android::hardware::tv::tuner::V1_0::RecordSettings; using namespace std; +using namespace android::media::tuner::testing::configuration::V1_0; +// TODO: remove all the constants and structs after config reader refactoring is done. const uint32_t FMQ_SIZE_512K = 0x80000; const uint32_t FMQ_SIZE_1M = 0x100000; const uint32_t FMQ_SIZE_4M = 0x400000; @@ -98,12 +103,6 @@ typedef enum { LINKAGE_DIR, } Linkage; -typedef enum { - DVBT, - DVBS, - FRONTEND_MAX, -} Frontend; - typedef enum { LNB0, LNB_EXTERNAL, @@ -115,11 +114,6 @@ typedef enum { DISEQC_MAX, } Diseqc; -typedef enum { - SCAN_DVBT, - SCAN_MAX, -} FrontendScan; - typedef enum { DVR_RECORD0, DVR_PLAYBACK0, @@ -145,15 +139,6 @@ struct TimeFilterConfig { uint64_t timeStamp; }; -struct FrontendConfig { - bool enable; - bool isSoftwareFe; - FrontendType type; - FrontendSettings settings; - vector tuneStatusTypes; - vector expectTuneStatuses; -}; - struct LnbConfig { bool usingLnb; string name; @@ -162,14 +147,6 @@ struct LnbConfig { LnbPosition position; }; -struct ChannelConfig { - int32_t frontendId; - int32_t channelId; - std::string channelName; - DemuxTpid videoPid; - DemuxTpid audioPid; -}; - struct DvrConfig { DvrType type; uint32_t bufferSize; @@ -183,67 +160,78 @@ struct DescramblerConfig { vector hidlPvtData; }; -static FrontendConfig frontendArray[FILTER_MAX]; -static FrontendConfig frontendScanArray[SCAN_MAX]; +// TODO: remove all the manual config array after the dynamic config refactoring is done. static LnbConfig lnbArray[LNB_MAX]; static vector diseqcMsgArray[DISEQC_MAX]; -static ChannelConfig channelArray[FRONTEND_MAX]; static FilterConfig filterArray[FILTER_MAX]; static TimeFilterConfig timeFilterArray[TIMER_MAX]; static DemuxFilterType filterLinkageTypes[LINKAGE_DIR][FILTER_MAIN_TYPE_BIT_COUNT]; static DvrConfig dvrArray[DVR_MAX]; static DescramblerConfig descramblerArray[DESC_MAX]; -static vector goldenOutputFiles; -static int defaultFrontend = DVBT; -static int defaultScanFrontend = SCAN_DVBT; + +// Hardware configs +static map frontendMap; + +// Hardware and test cases connections +static LiveBroadcastHardwareConnections live; +static ScanHardwareConnections scan; +static DvrRecordHardwareConnections record; +static DescramblingHardwareConnections descrambling; +static LnbLiveHardwareConnections lnbLive; +static LnbRecordHardwareConnections lnbRecord; /** Configuration array for the frontend tune test */ inline void initFrontendConfig() { + // The test will use the internal default fe is default fe is connected to any data flow without + // overriding in the xml config. + string defaultFeId = "FE_DEFAULT"; FrontendDvbtSettings dvbtSettings{ .frequency = 578000, .transmissionMode = FrontendDvbtTransmissionMode::AUTO, .bandwidth = FrontendDvbtBandwidth::BANDWIDTH_8MHZ, - .constellation = FrontendDvbtConstellation::AUTO, - .hierarchy = FrontendDvbtHierarchy::AUTO, - .hpCoderate = FrontendDvbtCoderate::AUTO, - .lpCoderate = FrontendDvbtCoderate::AUTO, - .guardInterval = FrontendDvbtGuardInterval::AUTO, .isHighPriority = true, - .standard = FrontendDvbtStandard::T, }; - frontendArray[DVBT].type = FrontendType::DVBT, frontendArray[DVBT].settings.dvbt(dvbtSettings); + frontendMap[defaultFeId].type = FrontendType::DVBT; + frontendMap[defaultFeId].settings.dvbt(dvbtSettings); + vector types; types.push_back(FrontendStatusType::DEMOD_LOCK); FrontendStatus status; status.isDemodLocked(true); vector statuses; statuses.push_back(status); - frontendArray[DVBT].tuneStatusTypes = types; - frontendArray[DVBT].expectTuneStatuses = statuses; - frontendArray[DVBT].isSoftwareFe = true; - frontendArray[DVBT].enable = true; - frontendArray[DVBS].type = FrontendType::DVBS; - frontendArray[DVBS].enable = true; - frontendArray[DVBS].isSoftwareFe = true; + frontendMap[defaultFeId].tuneStatusTypes = types; + frontendMap[defaultFeId].expectTuneStatuses = statuses; + frontendMap[defaultFeId].isSoftwareFe = true; + + // Read customized config + TunerTestingConfigReader::readFrontendConfig1_0(frontendMap); }; -/** Configuration array for the frontend scan test */ -inline void initFrontendScanConfig() { - frontendScanArray[SCAN_DVBT].type = FrontendType::DVBT; - frontendScanArray[SCAN_DVBT].settings.dvbt({ - .frequency = 578000, - .transmissionMode = FrontendDvbtTransmissionMode::MODE_8K, - .bandwidth = FrontendDvbtBandwidth::BANDWIDTH_8MHZ, - .constellation = FrontendDvbtConstellation::AUTO, - .hierarchy = FrontendDvbtHierarchy::AUTO, - .hpCoderate = FrontendDvbtCoderate::AUTO, - .lpCoderate = FrontendDvbtCoderate::AUTO, - .guardInterval = FrontendDvbtGuardInterval::AUTO, - .isHighPriority = true, - .standard = FrontendDvbtStandard::T, - }); +/** Read the vendor configurations of which hardware to use for each test cases/data flows */ +inline void connectHardwaresToTestCases() { + TunerTestingConfigReader::connectLiveBroadcast(live); + TunerTestingConfigReader::connectScan(scan); + TunerTestingConfigReader::connectDvrRecord(record); + TunerTestingConfigReader::connectDescrambling(descrambling); + TunerTestingConfigReader::connectLnbLive(lnbLive); + TunerTestingConfigReader::connectLnbRecord(lnbRecord); }; +inline bool validateConnections() { + bool feIsValid = frontendMap.find(live.frontendId) != frontendMap.end() && + frontendMap.find(scan.frontendId) != frontendMap.end(); + feIsValid &= record.support ? frontendMap.find(record.frontendId) != frontendMap.end() : true; + feIsValid &= descrambling.support + ? frontendMap.find(descrambling.frontendId) != frontendMap.end() + : true; + feIsValid &= lnbLive.support ? frontendMap.find(lnbLive.frontendId) != frontendMap.end() : true; + feIsValid &= + lnbRecord.support ? frontendMap.find(lnbRecord.frontendId) != frontendMap.end() : true; + return feIsValid; +} + +// TODO: remove all the manual configs after the dynamic config refactoring is done. /** Configuration array for the Lnb test */ inline void initLnbConfig() { lnbArray[LNB0].usingLnb = true; diff --git a/tv/tuner/1.1/default/Tuner.cpp b/tv/tuner/1.1/default/Tuner.cpp index 38b2a26da0..1e940ba098 100644 --- a/tv/tuner/1.1/default/Tuner.cpp +++ b/tv/tuner/1.1/default/Tuner.cpp @@ -237,6 +237,8 @@ Return Tuner::getDemuxCaps(getDemuxCaps_cb _hidl_cb) { // IP filter can be an MMTP filter's data source. caps.linkCaps = {0x00, 0x00, 0x02, 0x00, 0x00}; + // Support time filter testing + caps.bTimeFilter = true; _hidl_cb(Result::SUCCESS, caps); return Void(); } diff --git a/tv/tuner/config/Android.bp b/tv/tuner/config/Android.bp new file mode 100644 index 0000000000..ddbf3a74a8 --- /dev/null +++ b/tv/tuner/config/Android.bp @@ -0,0 +1,31 @@ +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"], +} + +xsd_config { + name: "tuner_testing_dynamic_configuration_V1_0", + srcs: ["tuner_testing_dynamic_configuration.xsd"], + package_name: "android.media.tuner.testing.configuration.V1_0", + nullability: true, +} + +xsd_config { + name: "tuner_testing_dynamic_configuration_V1_0_enums", + srcs: ["tuner_testing_dynamic_configuration.xsd"], + package_name: "android.media.tuner.testing.configuration.V1_0", + nullability: true, + enums_only: true, +} + +xsd_config { + name: "tuner_testing_dynamic_configuration_V1_0_parser", + srcs: ["tuner_testing_dynamic_configuration.xsd"], + package_name: "android.media.tuner.testing.configuration.V1_0", + nullability: true, + parser_only: true, +} diff --git a/tv/tuner/config/TunerTestingConfigReader.h b/tv/tuner/config/TunerTestingConfigReader.h new file mode 100644 index 0000000000..5c7f5648d3 --- /dev/null +++ b/tv/tuner/config/TunerTestingConfigReader.h @@ -0,0 +1,293 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace android::media::tuner::testing::configuration::V1_0; + +using android::hardware::tv::tuner::V1_0::DataFormat; +using android::hardware::tv::tuner::V1_0::DemuxAlpFilterType; +using android::hardware::tv::tuner::V1_0::DemuxFilterEvent; +using android::hardware::tv::tuner::V1_0::DemuxFilterMainType; +using android::hardware::tv::tuner::V1_0::DemuxFilterSettings; +using android::hardware::tv::tuner::V1_0::DemuxFilterType; +using android::hardware::tv::tuner::V1_0::DemuxIpFilterType; +using android::hardware::tv::tuner::V1_0::DemuxMmtpFilterType; +using android::hardware::tv::tuner::V1_0::DemuxRecordScIndexType; +using android::hardware::tv::tuner::V1_0::DemuxTlvFilterType; +using android::hardware::tv::tuner::V1_0::DemuxTpid; +using android::hardware::tv::tuner::V1_0::DemuxTsFilterType; +using android::hardware::tv::tuner::V1_0::DvrSettings; +using android::hardware::tv::tuner::V1_0::DvrType; +using android::hardware::tv::tuner::V1_0::FrontendDvbsSettings; +using android::hardware::tv::tuner::V1_0::FrontendDvbtBandwidth; +using android::hardware::tv::tuner::V1_0::FrontendDvbtCoderate; +using android::hardware::tv::tuner::V1_0::FrontendDvbtConstellation; +using android::hardware::tv::tuner::V1_0::FrontendDvbtGuardInterval; +using android::hardware::tv::tuner::V1_0::FrontendDvbtHierarchy; +using android::hardware::tv::tuner::V1_0::FrontendDvbtSettings; +using android::hardware::tv::tuner::V1_0::FrontendDvbtStandard; +using android::hardware::tv::tuner::V1_0::FrontendDvbtTransmissionMode; +using android::hardware::tv::tuner::V1_0::FrontendSettings; +using android::hardware::tv::tuner::V1_0::FrontendStatus; +using android::hardware::tv::tuner::V1_0::FrontendStatusType; +using android::hardware::tv::tuner::V1_0::FrontendType; +using android::hardware::tv::tuner::V1_0::LnbPosition; +using android::hardware::tv::tuner::V1_0::LnbTone; +using android::hardware::tv::tuner::V1_0::LnbVoltage; +using android::hardware::tv::tuner::V1_0::PlaybackSettings; +using android::hardware::tv::tuner::V1_0::RecordSettings; + +const string configFilePath = "/vendor/etc/tuner_vts_config.xml"; + +struct FrontendConfig { + bool isSoftwareFe; + FrontendType type; + FrontendSettings settings; + vector tuneStatusTypes; + vector expectTuneStatuses; +}; + +struct LiveBroadcastHardwareConnections { + string frontendId; + /* string audioFilterId; + string videoFilterId; + list string of extra filters; */ +}; + +struct ScanHardwareConnections { + string frontendId; +}; + +struct DvrRecordHardwareConnections { + bool support; + string frontendId; + /* string recordFilterId; + string dvrId; */ +}; + +struct DescramblingHardwareConnections { + bool support; + string frontendId; + /* string descramblerId; + string audioFilterId; + string videoFilterId; + list string of extra filters; */ +}; + +struct LnbLiveHardwareConnections { + bool support; + string frontendId; + /* string audioFilterId; + string videoFilterId; + list string of extra filters; + string lnbId; */ +}; + +struct LnbRecordHardwareConnections { + bool support; + string frontendId; + /* string recordFilterId; + list string of extra filters; + string lnbId; */ +}; + +struct TunerTestingConfigReader { + public: + static bool checkConfigFileExists() { + auto res = read(configFilePath.c_str()); + if (res == nullopt) { + ALOGW("[ConfigReader] Couldn't read /vendor/etc/tuner_vts_config.xml." + "Please check tuner_testing_dynamic_configuration.xsd" + "and sample_tuner_vts_config.xml for more details on how to config Tune VTS."); + } + return (res != nullopt); + } + + static void readFrontendConfig1_0(map& frontendMap) { + auto hardwareConfig = getHardwareConfig(); + if (hardwareConfig.hasFrontends()) { + // TODO: complete the tune status config + vector types; + types.push_back(FrontendStatusType::DEMOD_LOCK); + FrontendStatus status; + status.isDemodLocked(true); + vector statuses; + statuses.push_back(status); + + auto frontends = *hardwareConfig.getFirstFrontends(); + for (auto feConfig : frontends.getFrontend()) { + string id = feConfig.getId(); + if (id.compare(string("FE_DEFAULT")) == 0) { + // overrid default + frontendMap.erase(string("FE_DEFAULT")); + } + FrontendType type; + switch (feConfig.getType()) { + case FrontendTypeEnum::UNDEFINED: + type = FrontendType::UNDEFINED; + break; + // TODO: finish all other frontend settings + case FrontendTypeEnum::ANALOG: + type = FrontendType::ANALOG; + break; + case FrontendTypeEnum::ATSC: + type = FrontendType::ATSC; + break; + case FrontendTypeEnum::ATSC3: + type = FrontendType::ATSC3; + break; + case FrontendTypeEnum::DVBC: + type = FrontendType::DVBC; + break; + case FrontendTypeEnum::DVBS: + type = FrontendType::DVBS; + frontendMap[id].settings.dvbs(readDvbsFrontendSettings(feConfig)); + break; + case FrontendTypeEnum::DVBT: { + type = FrontendType::DVBT; + frontendMap[id].settings.dvbt(readDvbtFrontendSettings(feConfig)); + break; + } + case FrontendTypeEnum::ISDBS: + type = FrontendType::ISDBS; + break; + case FrontendTypeEnum::ISDBS3: + type = FrontendType::ISDBS3; + break; + case FrontendTypeEnum::ISDBT: + type = FrontendType::ISDBT; + break; + case FrontendTypeEnum::DTMB: + // dtmb will be handled in readFrontendConfig1_1; + continue; + case FrontendTypeEnum::UNKNOWN: + ALOGW("[ConfigReader] invalid frontend type"); + return; + } + frontendMap[id].type = type; + frontendMap[id].isSoftwareFe = feConfig.getIsSoftwareFrontend(); + // TODO: complete the tune status config + frontendMap[id].tuneStatusTypes = types; + frontendMap[id].expectTuneStatuses = statuses; + } + } + } + + static void connectLiveBroadcast(LiveBroadcastHardwareConnections& live) { + auto liveConfig = getDataFlowConfiguration().getFirstClearLiveBroadcast(); + live.frontendId = liveConfig->getFrontendConnection(); + } + + static void connectScan(ScanHardwareConnections& scan) { + auto scanConfig = getDataFlowConfiguration().getFirstScan(); + scan.frontendId = scanConfig->getFrontendConnection(); + } + + static void connectDvrRecord(DvrRecordHardwareConnections& record) { + auto dataFlow = getDataFlowConfiguration(); + if (!dataFlow.hasDvrRecord()) { + record.support = false; + return; + } + auto recordConfig = dataFlow.getFirstDvrRecord(); + record.frontendId = recordConfig->getFrontendConnection(); + } + + static void connectDescrambling(DescramblingHardwareConnections& descrambling) { + auto dataFlow = getDataFlowConfiguration(); + if (!dataFlow.hasDescrambling()) { + descrambling.support = false; + return; + } + auto descConfig = dataFlow.getFirstDescrambling(); + descrambling.frontendId = descConfig->getFrontendConnection(); + } + + static void connectLnbLive(LnbLiveHardwareConnections& lnbLive) { + auto dataFlow = getDataFlowConfiguration(); + if (!dataFlow.hasLnbLive()) { + lnbLive.support = false; + return; + } + auto lnbLiveConfig = dataFlow.getFirstLnbLive(); + lnbLive.frontendId = lnbLiveConfig->getFrontendConnection(); + } + + static void connectLnbRecord(LnbRecordHardwareConnections& lnbRecord) { + auto dataFlow = getDataFlowConfiguration(); + if (!dataFlow.hasLnbRecord()) { + lnbRecord.support = false; + return; + } + auto lnbRecordConfig = dataFlow.getFirstLnbRecord(); + lnbRecord.frontendId = lnbRecordConfig->getFrontendConnection(); + } + + private: + static FrontendDvbtSettings readDvbtFrontendSettings(Frontend feConfig) { + ALOGW("[ConfigReader] type is dvbt"); + FrontendDvbtSettings dvbtSettings{ + .frequency = (uint32_t)feConfig.getFrequency(), + }; + if (!feConfig.hasDvbtFrontendSettings_optional()) { + ALOGW("[ConfigReader] no more dvbt settings"); + return dvbtSettings; + } + dvbtSettings.transmissionMode = static_cast( + feConfig.getFirstDvbtFrontendSettings_optional()->getTransmissionMode()); + dvbtSettings.bandwidth = static_cast( + feConfig.getFirstDvbtFrontendSettings_optional()->getBandwidth()); + dvbtSettings.isHighPriority = + feConfig.getFirstDvbtFrontendSettings_optional()->getIsHighPriority(); + return dvbtSettings; + } + + static FrontendDvbsSettings readDvbsFrontendSettings(Frontend feConfig) { + ALOGW("[ConfigReader] type is dvbs"); + FrontendDvbsSettings dvbsSettings{ + .frequency = (uint32_t)feConfig.getFrequency(), + }; + if (!feConfig.hasDvbsFrontendSettings_optional()) { + ALOGW("[ConfigReader] no more dvbs settings"); + return dvbsSettings; + } + dvbsSettings.symbolRate = static_cast( + feConfig.getFirstDvbsFrontendSettings_optional()->getSymbolRate()); + dvbsSettings.inputStreamId = static_cast( + feConfig.getFirstDvbsFrontendSettings_optional()->getInputStreamId()); + return dvbsSettings; + } + + static TunerConfiguration getTunerConfig() { return *read(configFilePath.c_str()); } + + static HardwareConfiguration getHardwareConfig() { + return *getTunerConfig().getFirstHardwareConfiguration(); + } + + static DataFlowConfiguration getDataFlowConfiguration() { + return *getTunerConfig().getFirstDataFlowConfiguration(); + } +}; diff --git a/tv/tuner/config/api/current.txt b/tv/tuner/config/api/current.txt new file mode 100644 index 0000000000..b0f410d25e --- /dev/null +++ b/tv/tuner/config/api/current.txt @@ -0,0 +1,143 @@ +// Signature format: 2.0 +package android.media.tuner.testing.configuration.V1_0 { + + public class DataFlowConfiguration { + ctor public DataFlowConfiguration(); + method @Nullable public android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.ClearLiveBroadcast getClearLiveBroadcast(); + method @Nullable public android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.Descrambling getDescrambling(); + method @Nullable public android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.DvrRecord getDvrRecord(); + method @Nullable public android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.LnbLive getLnbLive(); + method @Nullable public android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.LnbRecord getLnbRecord(); + method @Nullable public android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.Scan getScan(); + method public void setClearLiveBroadcast(@Nullable android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.ClearLiveBroadcast); + method public void setDescrambling(@Nullable android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.Descrambling); + method public void setDvrRecord(@Nullable android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.DvrRecord); + method public void setLnbLive(@Nullable android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.LnbLive); + method public void setLnbRecord(@Nullable android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.LnbRecord); + method public void setScan(@Nullable android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.Scan); + } + + public static class DataFlowConfiguration.ClearLiveBroadcast { + ctor public DataFlowConfiguration.ClearLiveBroadcast(); + method @Nullable public String getFrontendConnection(); + method public void setFrontendConnection(@Nullable String); + } + + public static class DataFlowConfiguration.Descrambling { + ctor public DataFlowConfiguration.Descrambling(); + method @Nullable public String getFrontendConnection(); + method public void setFrontendConnection(@Nullable String); + } + + public static class DataFlowConfiguration.DvrRecord { + ctor public DataFlowConfiguration.DvrRecord(); + method @Nullable public String getFrontendConnection(); + method public void setFrontendConnection(@Nullable String); + } + + public static class DataFlowConfiguration.LnbLive { + ctor public DataFlowConfiguration.LnbLive(); + method @Nullable public String getFrontendConnection(); + method public void setFrontendConnection(@Nullable String); + } + + public static class DataFlowConfiguration.LnbRecord { + ctor public DataFlowConfiguration.LnbRecord(); + method @Nullable public String getFrontendConnection(); + method public void setFrontendConnection(@Nullable String); + } + + public static class DataFlowConfiguration.Scan { + ctor public DataFlowConfiguration.Scan(); + method @Nullable public String getFrontendConnection(); + method public void setFrontendConnection(@Nullable String); + } + + public class DvbsFrontendSettings { + ctor public DvbsFrontendSettings(); + method @Nullable public java.math.BigInteger getInputStreamId(); + method @Nullable public java.math.BigInteger getSymbolRate(); + method public void setInputStreamId(@Nullable java.math.BigInteger); + method public void setSymbolRate(@Nullable java.math.BigInteger); + } + + public class DvbtFrontendSettings { + ctor public DvbtFrontendSettings(); + method @Nullable public java.math.BigInteger getBandwidth(); + method @Nullable public java.math.BigInteger getIsHighPriority(); + method @Nullable public java.math.BigInteger getTransmissionMode(); + method public void setBandwidth(@Nullable java.math.BigInteger); + method public void setIsHighPriority(@Nullable java.math.BigInteger); + method public void setTransmissionMode(@Nullable java.math.BigInteger); + } + + public class Frontend { + ctor public Frontend(); + method @Nullable public java.math.BigInteger getConnectToCicamId(); + method @Nullable public android.media.tuner.testing.configuration.V1_0.DvbsFrontendSettings getDvbsFrontendSettings_optional(); + method @Nullable public android.media.tuner.testing.configuration.V1_0.DvbtFrontendSettings getDvbtFrontendSettings_optional(); + method @Nullable public java.math.BigInteger getEndFrequency(); + method @Nullable public java.math.BigInteger getFrequency(); + method @Nullable public String getId(); + method @Nullable public boolean getIsSoftwareFrontend(); + method @Nullable public android.media.tuner.testing.configuration.V1_0.FrontendTypeEnum getType(); + method public void setConnectToCicamId(@Nullable java.math.BigInteger); + method public void setDvbsFrontendSettings_optional(@Nullable android.media.tuner.testing.configuration.V1_0.DvbsFrontendSettings); + method public void setDvbtFrontendSettings_optional(@Nullable android.media.tuner.testing.configuration.V1_0.DvbtFrontendSettings); + method public void setEndFrequency(@Nullable java.math.BigInteger); + method public void setFrequency(@Nullable java.math.BigInteger); + method public void setId(@Nullable String); + method public void setIsSoftwareFrontend(@Nullable boolean); + method public void setType(@Nullable android.media.tuner.testing.configuration.V1_0.FrontendTypeEnum); + } + + public enum FrontendTypeEnum { + method @NonNull public String getRawName(); + enum_constant public static final android.media.tuner.testing.configuration.V1_0.FrontendTypeEnum ANALOG; + enum_constant public static final android.media.tuner.testing.configuration.V1_0.FrontendTypeEnum ATSC; + enum_constant public static final android.media.tuner.testing.configuration.V1_0.FrontendTypeEnum ATSC3; + enum_constant public static final android.media.tuner.testing.configuration.V1_0.FrontendTypeEnum DTMB; + enum_constant public static final android.media.tuner.testing.configuration.V1_0.FrontendTypeEnum DVBC; + enum_constant public static final android.media.tuner.testing.configuration.V1_0.FrontendTypeEnum DVBS; + enum_constant public static final android.media.tuner.testing.configuration.V1_0.FrontendTypeEnum DVBT; + enum_constant public static final android.media.tuner.testing.configuration.V1_0.FrontendTypeEnum ISDBS; + enum_constant public static final android.media.tuner.testing.configuration.V1_0.FrontendTypeEnum ISDBS3; + enum_constant public static final android.media.tuner.testing.configuration.V1_0.FrontendTypeEnum ISDBT; + enum_constant public static final android.media.tuner.testing.configuration.V1_0.FrontendTypeEnum UNDEFINED; + } + + public class HardwareConfiguration { + ctor public HardwareConfiguration(); + method @Nullable public android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.Frontends getFrontends(); + method public void setFrontends(@Nullable android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.Frontends); + } + + public static class HardwareConfiguration.Frontends { + ctor public HardwareConfiguration.Frontends(); + method @Nullable public java.util.List getFrontend(); + } + + public class TunerConfiguration { + ctor public TunerConfiguration(); + method @Nullable public android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration getDataFlowConfiguration(); + method @Nullable public android.media.tuner.testing.configuration.V1_0.HardwareConfiguration getHardwareConfiguration(); + method @Nullable public android.media.tuner.testing.configuration.V1_0.Version getVersion(); + method public void setDataFlowConfiguration(@Nullable android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration); + method public void setHardwareConfiguration(@Nullable android.media.tuner.testing.configuration.V1_0.HardwareConfiguration); + method public void setVersion(@Nullable android.media.tuner.testing.configuration.V1_0.Version); + } + + public enum Version { + method @NonNull public String getRawName(); + enum_constant public static final android.media.tuner.testing.configuration.V1_0.Version _1_0; + } + + public class XmlParser { + ctor public XmlParser(); + method @Nullable public static android.media.tuner.testing.configuration.V1_0.TunerConfiguration read(@NonNull java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException; + method @Nullable public static String readText(@NonNull org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; + method public static void skip(@NonNull org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; + } + +} + diff --git a/tv/tuner/config/api/last_current.txt b/tv/tuner/config/api/last_current.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tv/tuner/config/api/last_removed.txt b/tv/tuner/config/api/last_removed.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tv/tuner/config/api/removed.txt b/tv/tuner/config/api/removed.txt new file mode 100644 index 0000000000..d802177e24 --- /dev/null +++ b/tv/tuner/config/api/removed.txt @@ -0,0 +1 @@ +// Signature format: 2.0 diff --git a/tv/tuner/config/sample_tuner_vts_config.xml b/tv/tuner/config/sample_tuner_vts_config.xml new file mode 100644 index 0000000000..c4080d9ac7 --- /dev/null +++ b/tv/tuner/config/sample_tuner_vts_config.xml @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tv/tuner/config/tuner_testing_dynamic_configuration.xsd b/tv/tuner/config/tuner_testing_dynamic_configuration.xsd new file mode 100644 index 0000000000..cd8b061309 --- /dev/null +++ b/tv/tuner/config/tuner_testing_dynamic_configuration.xsd @@ -0,0 +1,188 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Each frontend element contain the following attributes: + "id": unique id of the frontend that could be used to connect to the test the + "dataFlowConfiguration" + "type": the frontend type. The enums are defined in the xsd. + "isSoftwareFrontend": if the test environment is using hardware or software + frontend. If using software, a ts input file path needs to be configured. + "softwareFeInputPath": used as the source of the software frontend. + "connectToCicamId": if the device supports frontend connecting to cicam, the + target cicam id needs to be configured here. Supported in Tuner 1.1 or + higher. + "frequency": the frequency used to configure tune and scan. + "endFrequency": the end frequency of scan. Supported in Tuner 1.1 or higher. + + Each frontend element also contains at most one type-related "frontendSettings". + - The settings type should match the frontend "type" attribute. + - For example, when frontend type="DVBT", dvbtFrontendSettings can be + configured. + - This is optional and skipping the settings would pass a setting with frequency + config only to the hal. + + + + + + + + + + + + + + + + + + + + + + + + + + This section contains configurations of all the frontends that would be + used in the tests. + - This section is optional and can be skipped to use the default + fe settings. + - The default settings can be found in the + sample_tuner_vts_configurations.xml. + - The users can also override the default frontend settings using + id="FE_DEFAULT". + - The users can configure 1 or more frontend elements in the + frontends sections. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- GitLab From e60e17f781fc5527c2a80a0151bfdd7744fbc91c Mon Sep 17 00:00:00 2001 From: Yuncheol Heo Date: Wed, 31 Mar 2021 12:40:08 -0700 Subject: [PATCH 576/790] Remove the suffix LEGACY from CLUSTER_NAVIGATION_STATE_LEGACY. - It sounds awkward to have the suffix LEGACY for the new VHAL. Bug: 173454429 Test: atest ClusterHomeManagerTest ClusterHalServiceTest Change-Id: I4b79bed21859af3dee1efe2da420cb19c2aa19db --- automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h | 2 +- automotive/vehicle/2.0/types.hal | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h index 5dca1dc0ff..19b0a35e8d 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h @@ -1222,7 +1222,7 @@ const ConfigDeclaration kVehicleProperties[]{ { .config = { - .prop = toInt(VehicleProperty::CLUSTER_NAVIGATION_STATE_LEGACY), + .prop = toInt(VehicleProperty::CLUSTER_NAVIGATION_STATE), .access = VehiclePropertyAccess::WRITE, .changeMode = VehiclePropertyChangeMode::ON_CHANGE, }, diff --git a/automotive/vehicle/2.0/types.hal b/automotive/vehicle/2.0/types.hal index eabd7e11fe..1fe4bac6e3 100644 --- a/automotive/vehicle/2.0/types.hal +++ b/automotive/vehicle/2.0/types.hal @@ -3201,7 +3201,7 @@ enum VehicleProperty : int32_t { * @change_mode VehiclePropertyChangeMode:ON_CHANGE * @access VehiclePropertyAccess:WRITE */ - CLUSTER_NAVIGATION_STATE_LEGACY = ( + CLUSTER_NAVIGATION_STATE = ( 0x0F38 | VehiclePropertyGroup:SYSTEM | VehiclePropertyType:BYTES -- GitLab From 989975ec5a2a9284d13b6b5e76d34bc7c214673e Mon Sep 17 00:00:00 2001 From: Edwin Wong Date: Mon, 8 Mar 2021 18:46:42 -0800 Subject: [PATCH 577/790] Fix CryptoPlugin use after free vulnerability. The shared memory buffer used by srcPtr can be freed by another thread because it is not protected by a mutex. Subsequently, a use after free AIGABRT can occur in a race condition. SafetyNet logging is not added to avoid log spamming. The mutex lock is called to setup for decryption, which is called frequently. The crash was reproduced on the device before the fix. Verified the test passes after the fix. Test: sts sts-tradefed run sts-engbuild-no-spl-lock -m StsHostTestCases --test android.security.sts.Bug_176495665#testPocBug_176495665 Test: push to device with target_hwasan-userdebug build adb shell /data/local/tmp/Bug-176495665_sts64 Bug: 176495665 Bug: 176444161 Change-Id: I4c83c44873eef960b654f387a3574fcad49c41a9 --- drm/1.0/default/Android.bp | 15 ++++++++------- drm/1.0/default/CryptoPlugin.cpp | 10 ++++++++-- drm/1.0/default/CryptoPlugin.h | 21 +++++++++++++-------- 3 files changed, 29 insertions(+), 17 deletions(-) diff --git a/drm/1.0/default/Android.bp b/drm/1.0/default/Android.bp index af1c076e0d..cbdab4ffe0 100644 --- a/drm/1.0/default/Android.bp +++ b/drm/1.0/default/Android.bp @@ -32,6 +32,7 @@ cc_library_static { "-Werror", "-Wextra", "-Wall", + "-Wthread-safety", ], shared_libs: [ "liblog", @@ -42,7 +43,7 @@ cc_library_static { export_header_lib_headers: [ "libutils_headers", ], - export_include_dirs : ["include"] + export_include_dirs: ["include"], } soong_config_module_type { @@ -59,8 +60,8 @@ android_hardware_drm_1_0_multilib { soong_config_variables: { TARGET_ENABLE_MEDIADRM_64: { compile_multilib: "both", - } - } + }, + }, } android_hardware_drm_1_0_multilib { @@ -69,8 +70,8 @@ android_hardware_drm_1_0_multilib { soong_config_variables: { TARGET_ENABLE_MEDIADRM_64: { compile_multilib: "first", - } - } + }, + }, } cc_defaults { @@ -98,7 +99,7 @@ cc_binary { name: "android.hardware.drm@1.0-service", defaults: [ "android.hardware.drm@1.0-multilib-exe", - "android.hardware.drm@1.0-service-defaults" + "android.hardware.drm@1.0-service-defaults", ], init_rc: ["android.hardware.drm@1.0-service.rc"], srcs: ["service.cpp"], @@ -110,7 +111,7 @@ cc_binary { name: "android.hardware.drm@1.0-service-lazy", defaults: [ "android.hardware.drm@1.0-multilib-exe", - "android.hardware.drm@1.0-service-defaults" + "android.hardware.drm@1.0-service-defaults", ], overrides: ["android.hardware.drm@1.0-service"], init_rc: ["android.hardware.drm@1.0-service-lazy.rc"], diff --git a/drm/1.0/default/CryptoPlugin.cpp b/drm/1.0/default/CryptoPlugin.cpp index e6d4e8447b..de8bbd599c 100644 --- a/drm/1.0/default/CryptoPlugin.cpp +++ b/drm/1.0/default/CryptoPlugin.cpp @@ -53,6 +53,8 @@ namespace implementation { uint32_t bufferId) { sp hidlMemory = mapMemory(base); + std::lock_guard shared_buffer_lock(mSharedBufferLock); + // allow mapMemory to return nullptr mSharedBufferMap[bufferId] = hidlMemory; return Void(); @@ -65,7 +67,7 @@ namespace implementation { const SharedBuffer& source, uint64_t offset, const DestinationBuffer& destination, decrypt_cb _hidl_cb) { - + std::unique_lock shared_buffer_lock(mSharedBufferLock); if (mSharedBufferMap.find(source.bufferId) == mSharedBufferMap.end()) { _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "source decrypt buffer base not set"); return Void(); @@ -79,7 +81,7 @@ namespace implementation { } } - android::CryptoPlugin::Mode legacyMode; + android::CryptoPlugin::Mode legacyMode = android::CryptoPlugin::kMode_Unencrypted; switch(mode) { case Mode::UNENCRYPTED: legacyMode = android::CryptoPlugin::kMode_Unencrypted; @@ -170,6 +172,10 @@ namespace implementation { _hidl_cb(Status::BAD_VALUE, 0, "invalid destination type"); return Void(); } + + // release mSharedBufferLock + shared_buffer_lock.unlock(); + ssize_t result = mLegacyPlugin->decrypt(secure, keyId.data(), iv.data(), legacyMode, legacyPattern, srcPtr, legacySubSamples.get(), subSamples.size(), destPtr, &detailMessage); diff --git a/drm/1.0/default/CryptoPlugin.h b/drm/1.0/default/CryptoPlugin.h index 11cc2aae47..0d091fae65 100644 --- a/drm/1.0/default/CryptoPlugin.h +++ b/drm/1.0/default/CryptoPlugin.h @@ -17,11 +17,14 @@ #ifndef ANDROID_HARDWARE_DRM_V1_0__CRYPTOPLUGIN_H #define ANDROID_HARDWARE_DRM_V1_0__CRYPTOPLUGIN_H -#include +#include #include +#include #include #include +#include + namespace android { namespace hardware { namespace drm { @@ -60,19 +63,21 @@ struct CryptoPlugin : public ICryptoPlugin { Return setSharedBufferBase(const ::android::hardware::hidl_memory& base, uint32_t bufferId) override; - Return decrypt(bool secure, const hidl_array& keyId, - const hidl_array& iv, Mode mode, const Pattern& pattern, - const hidl_vec& subSamples, const SharedBuffer& source, - uint64_t offset, const DestinationBuffer& destination, - decrypt_cb _hidl_cb) override; + Return decrypt( + bool secure, const hidl_array& keyId, const hidl_array& iv, + Mode mode, const Pattern& pattern, const hidl_vec& subSamples, + const SharedBuffer& source, uint64_t offset, const DestinationBuffer& destination, + decrypt_cb _hidl_cb) override NO_THREAD_SAFETY_ANALYSIS; // use unique_lock -private: + private: android::CryptoPlugin *mLegacyPlugin; - std::map > mSharedBufferMap; + std::map> mSharedBufferMap GUARDED_BY(mSharedBufferLock); CryptoPlugin() = delete; CryptoPlugin(const CryptoPlugin &) = delete; void operator=(const CryptoPlugin &) = delete; + + std::mutex mSharedBufferLock; }; } // namespace implementation -- GitLab From 51c85195c1ba8f27955b3cfbcbe9dbf5a721f8e5 Mon Sep 17 00:00:00 2001 From: Yipeng Cao Date: Wed, 23 Dec 2020 17:04:29 -0800 Subject: [PATCH 578/790] Fix gnss replay Change the /dev/gnss0 read logic, will send the CMD_GET_LOCATION to /dev/gnss0 first. launch_cvd --start_gnss_proxy --gnss_file_path=xxx Test: Manually Bug: 183956668 Change-Id: Ic493790e80ceb6fd4d890b31e596b5c08addee40 (cherry picked from commit 80451ef0c39078e535b51668d709914c599be657) --- gnss/common/utils/default/NmeaFixInfo.cpp | 7 +++++++ gnss/common/utils/default/include/NmeaFixInfo.h | 1 + gnss/common/utils/default/include/v2_1/GnssTemplate.h | 11 +++++++++-- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/gnss/common/utils/default/NmeaFixInfo.cpp b/gnss/common/utils/default/NmeaFixInfo.cpp index 43e008bb72..c7ee13488b 100644 --- a/gnss/common/utils/default/NmeaFixInfo.cpp +++ b/gnss/common/utils/default/NmeaFixInfo.cpp @@ -202,8 +202,15 @@ std::unique_ptr NmeaFixInfo::getLocationFromInputStr( uint32_t fixId = 0; double lastTimeStamp = 0; for (const auto& line : nmeaRecords) { + if (line.compare(0, strlen(GPGA_RECORD_TAG), GPGA_RECORD_TAG) != 0 && + line.compare(0, strlen(GPRMC_RECORD_TAG), GPRMC_RECORD_TAG) != 0) { + continue; + } std::vector sentenceValues; splitStr(line, COMMA_SEPARATOR, sentenceValues); + if (sentenceValues.size() < MIN_COL_NUM) { + continue; + } double currentTimeStamp = std::stof(sentenceValues[1]); // If see a new timestamp, report correct location. if ((currentTimeStamp - lastTimeStamp) > TIMESTAMP_EPSILON && diff --git a/gnss/common/utils/default/include/NmeaFixInfo.h b/gnss/common/utils/default/include/NmeaFixInfo.h index 06eae7eda9..c96eecea00 100644 --- a/gnss/common/utils/default/include/NmeaFixInfo.h +++ b/gnss/common/utils/default/include/NmeaFixInfo.h @@ -32,6 +32,7 @@ constexpr char GPRMC_RECORD_TAG[] = "$GPRMC"; constexpr char LINE_SEPARATOR = '\n'; constexpr char COMMA_SEPARATOR = ','; constexpr double TIMESTAMP_EPSILON = 0.001; +constexpr int MIN_COL_NUM = 13; /** Helper class to parse and store the GNSS fix details information. */ class NmeaFixInfo { diff --git a/gnss/common/utils/default/include/v2_1/GnssTemplate.h b/gnss/common/utils/default/include/v2_1/GnssTemplate.h index 79c78c3f07..a6e8f58206 100644 --- a/gnss/common/utils/default/include/v2_1/GnssTemplate.h +++ b/gnss/common/utils/default/include/v2_1/GnssTemplate.h @@ -196,6 +196,7 @@ std::unique_ptr GnssTemplate::getLocationFromHW() { return nullptr; } while (true) { + memset(inputBuffer, 0, INPUT_BUFFER_SIZE); bytes_read = read(mGnssFd, &inputBuffer, INPUT_BUFFER_SIZE); if (bytes_read <= 0) { break; @@ -218,9 +219,14 @@ Return GnssTemplate::start() { auto svStatus = filterBlocklistedSatellitesV2_1(Utils::getMockSvInfoListV2_1()); this->reportSvStatus(svStatus); auto currentLocation = getLocationFromHW(); - if (mGnssFd != -1 && currentLocation != nullptr) { + if (mGnssFd != -1) { // Only report location if the return from hardware is valid - this->reportLocation(*currentLocation); + // note that we can not merge these two "if" together, if didn't + // get location from hardware, we shouldn't report location, not + // report the "default" one. + if (currentLocation != nullptr) { + this->reportLocation(*currentLocation); + } } else { if (sGnssCallback_2_1 != nullptr || sGnssCallback_2_0 != nullptr) { const auto location = Utils::getMockLocationV2_0(); @@ -259,6 +265,7 @@ Return GnssTemplate::stop() { if (mGnssFd != -1) { close(mGnssFd); mGnssFd = -1; + mHardwareModeChecked = false; } return true; } -- GitLab From 425a83b6fc026b5fb2f748afcda040fb1d044378 Mon Sep 17 00:00:00 2001 From: Kai Date: Tue, 23 Mar 2021 21:08:59 -0700 Subject: [PATCH 579/790] Add ETC_CARD_TYPE and ETC_CARD_STATUS Allow applications to know whether a Japanese ETC Card Reader is present, and whether a valid ETC card is inserted to the reader. Bug: 171751885 Test: check properites in kitchensink atest CarServicesTest atest VehiclePropertyIdsTest Change-Id: I9e9135b2eb0d2e701413dcc1b964e193a47d7b19 --- .../default/impl/vhal_v2_0/DefaultConfig.h | 10 ++++ automotive/vehicle/2.0/types.hal | 60 +++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h index 19b0a35e8d..f5b53d3f1b 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h @@ -1064,6 +1064,16 @@ const ConfigDeclaration kVehicleProperties[]{ .changeMode = VehiclePropertyChangeMode::ON_CHANGE}, .initialValue = {.stringValue = "Vendor String Property"}}, + {.config = {.prop = toInt(VehicleProperty::ELECTRONIC_TOLL_COLLECTION_CARD_TYPE), + .access = VehiclePropertyAccess::READ, + .changeMode = VehiclePropertyChangeMode::ON_CHANGE}, + .initialValue = {.int32Values = {0}}}, + + {.config = {.prop = toInt(VehicleProperty::ELECTRONIC_TOLL_COLLECTION_CARD_STATUS), + .access = VehiclePropertyAccess::READ, + .changeMode = VehiclePropertyChangeMode::ON_CHANGE}, + .initialValue = {.int32Values = {0}}}, + {.config = { .prop = toInt(VehicleProperty::SUPPORT_CUSTOMIZE_VENDOR_PERMISSION), diff --git a/automotive/vehicle/2.0/types.hal b/automotive/vehicle/2.0/types.hal index 1fe4bac6e3..1fb7dc737f 100644 --- a/automotive/vehicle/2.0/types.hal +++ b/automotive/vehicle/2.0/types.hal @@ -3207,6 +3207,66 @@ enum VehicleProperty : int32_t { | VehiclePropertyType:BYTES | VehicleArea:GLOBAL), + /** + * Electronic Toll Collection card type. + * + * This property indicates the type of ETC card in this vehicle. + * If the head unit is aware of an ETC card attached to the vehicle, this property should + * return the type of card attached; otherwise, this property should be UNAVAILABLE. + * + * @change_mode VehiclePropertyChangeMode:ON_CHANGE + * @access VehiclePropertyAccess:READ + * @data_enum ElectronicTollCollectionCardType + */ + ELECTRONIC_TOLL_COLLECTION_CARD_TYPE = ( + 0x0F39 + | VehiclePropertyGroup:SYSTEM + | VehiclePropertyType:INT32 + | VehicleArea:GLOBAL), + + /** + * Electronic Toll Collection card status. + * + * This property indicates the status of ETC card in this vehicle. + * If the head unit is aware of an ETC card attached to the vehicle, + * ELECTRONIC_TOLL_COLLECTION_CARD_TYPE gives that status of the card; otherwise, + * this property should be UNAVAILABLE. + * + * @change_mode VehiclePropertyChangeMode:ON_CHANGE + * @access VehiclePropertyAccess:READ + * @data_enum ElectronicTollCollectionCardStatus + */ + ELECTRONIC_TOLL_COLLECTION_CARD_STATUS = ( + 0x0F3A + | VehiclePropertyGroup:SYSTEM + | VehiclePropertyType:INT32 + | VehicleArea:GLOBAL), +}; + +/** + * Used by ELECTRONIC_TOLL_COLLECTION_CARD_TYPE. + */ +enum ElectronicTollCollectionCardType : int32_t { + // Type is unknown or not in the list below. + UNKNOWN = 0, + // A Japanese ETC card reader that does not support ETC 2.0. + JP_ELECTRONIC_TOLL_COLLECTION_CARD = 1, + // A Japanese ETC 2.0 card reader. + JP_ELECTRONIC_TOLL_COLLECTION_CARD_V2 = 2, +}; + +/** + * Used by ELECTRONIC_TOLL_COLLECTION_CARD_STATUS. + */ +enum ElectronicTollCollectionCardStatus : int32_t { + // Status could not be determined + UNKNOWN = 0, + // A valid ETC card is present + ELECTRONIC_TOLL_COLLECTION_CARD_VALID = 1, + // An ETC card is present, but it is expired or otherwise invalid + ELECTRONIC_TOLL_COLLECTION_CARD_INVALID = 2, + // No ETC card is inserted in the reader. + ELECTRONIC_TOLL_COLLECTION_CARD_NOT_INSERTED = 3, }; /** -- GitLab From 050034128f7cbadc8e1aa5180b7ba103acc3bc77 Mon Sep 17 00:00:00 2001 From: Wei Wang Date: Thu, 1 Apr 2021 10:44:29 -0700 Subject: [PATCH 580/790] ADPF: IPower: add aidl interfaces Test: Manual test, run bouncy ball Test: atest VtsHalPowerTargetTest Bug: 163794808 Change-Id: I295cf03b33ae8cb68826641c08a877a2a3e3a461 Signed-off-by: Wei Wang --- power/aidl/Android.bp | 7 +- .../current/android/hardware/power/Boost.aidl | 28 +++- .../android/hardware/power/IPower.aidl | 30 +++- .../hardware/power/IPowerHintSession.aidl | 42 ++++++ .../current/android/hardware/power/Mode.aidl | 28 +++- .../android/hardware/power/WorkDuration.aidl | 39 +++++ power/aidl/android/hardware/power/IPower.aidl | 34 +++++ .../hardware/power/IPowerHintSession.aidl | 59 ++++++++ .../android/hardware/power/WorkDuration.aidl | 30 ++++ power/aidl/default/Android.bp | 2 +- power/aidl/default/Power.cpp | 19 ++- power/aidl/default/Power.h | 5 + power/aidl/vts/Android.bp | 4 +- power/aidl/vts/VtsHalPowerTargetTest.cpp | 135 ++++++++++++++---- 14 files changed, 414 insertions(+), 48 deletions(-) create mode 100644 power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPowerHintSession.aidl create mode 100644 power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/WorkDuration.aidl create mode 100644 power/aidl/android/hardware/power/IPowerHintSession.aidl create mode 100644 power/aidl/android/hardware/power/WorkDuration.aidl diff --git a/power/aidl/Android.bp b/power/aidl/Android.bp index 054fea5467..dbd18fd5ec 100644 --- a/power/aidl/Android.bp +++ b/power/aidl/Android.bp @@ -29,6 +29,9 @@ aidl_interface { ], stability: "vintf", backend: { + cpp: { + enabled: true, + }, java: { platform_apis: true, }, @@ -38,5 +41,7 @@ aidl_interface { }, }, }, - versions: ["1"], + versions: [ + "1", + ], } diff --git a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/Boost.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/Boost.aidl index aced215bb9..c792d4e0c2 100644 --- a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/Boost.aidl +++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/Boost.aidl @@ -1,14 +1,30 @@ +/* + * 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 interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped diff --git a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPower.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPower.aidl index 8a06623fca..ae03313f11 100644 --- a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPower.aidl +++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPower.aidl @@ -1,14 +1,30 @@ +/* + * 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 interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped @@ -22,4 +38,6 @@ interface IPower { boolean isModeSupported(in android.hardware.power.Mode type); oneway void setBoost(in android.hardware.power.Boost type, in int durationMs); boolean isBoostSupported(in android.hardware.power.Boost type); + android.hardware.power.IPowerHintSession createHintSession(in int tgid, in int uid, in int[] threadIds, in long durationNanos); + long getHintSessionPreferredRate(); } diff --git a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPowerHintSession.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPowerHintSession.aidl new file mode 100644 index 0000000000..1d3ecb7eee --- /dev/null +++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPowerHintSession.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 -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.power; +@VintfStability +interface IPowerHintSession { + oneway void updateTargetWorkDuration(long targetDurationNanos); + oneway void reportActualWorkDuration(in android.hardware.power.WorkDuration[] durations); + oneway void pause(); + oneway void resume(); + oneway void close(); +} diff --git a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/Mode.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/Mode.aidl index f7c2552c8d..8920c014e3 100644 --- a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/Mode.aidl +++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/Mode.aidl @@ -1,14 +1,30 @@ +/* + * 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 interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped diff --git a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/WorkDuration.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/WorkDuration.aidl new file mode 100644 index 0000000000..e86cd40ec2 --- /dev/null +++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/WorkDuration.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 -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.power; +@VintfStability +parcelable WorkDuration { + long timeStampNanos; + long durationNanos; +} diff --git a/power/aidl/android/hardware/power/IPower.aidl b/power/aidl/android/hardware/power/IPower.aidl index 2c4bd86014..ee8e5a3a61 100644 --- a/power/aidl/android/hardware/power/IPower.aidl +++ b/power/aidl/android/hardware/power/IPower.aidl @@ -17,6 +17,7 @@ package android.hardware.power; import android.hardware.power.Boost; +import android.hardware.power.IPowerHintSession; import android.hardware.power.Mode; @VintfStability @@ -69,4 +70,37 @@ interface IPower { * @param type Boost to be queried */ boolean isBoostSupported(in Boost type); + + /** + * A Session represents a group of threads with an inter-related workload such that hints for + * their performance should be considered as a unit. The threads in a given session should be + * long-life and not created or destroyed dynamically. + * + * Each session is expected to have a periodic workload with a target duration for each + * cycle. The cycle duration is likely greater than the target work duration to allow other + * parts of the pipeline to run within the available budget. For example, a renderer thread may + * work at 60hz in order to produce frames at the display's frame but have a target work + * duration of only 6ms. + * + * Creates a session for the given set of threads and sets their initial target work + * duration. + * + * @return the new session if it is supported on this device, otherwise return with + * EX_UNSUPPORTED_OPERATION error if hint session is not supported on this device. + * @param tgid The TGID to be associated with this session. + * @param uid The UID to be associated with this session. + * @param threadIds The list of threads to be associated with this session. + * @param durationNanos The desired duration in nanoseconds for this session. + */ + IPowerHintSession createHintSession( + in int tgid, in int uid, in int[] threadIds, in long durationNanos); + + /** + * Get preferred update rate (interval) information for this device. Framework must communicate + * this rate to Apps, and also ensure the session hint sent no faster than the update rate. + * + * @return the preferred update rate in nanoseconds supported by device software. Return with + * EX_UNSUPPORTED_OPERATION if hint session is not supported. + */ + long getHintSessionPreferredRate(); } diff --git a/power/aidl/android/hardware/power/IPowerHintSession.aidl b/power/aidl/android/hardware/power/IPowerHintSession.aidl new file mode 100644 index 0000000000..9a85bee997 --- /dev/null +++ b/power/aidl/android/hardware/power/IPowerHintSession.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.power; + +import android.hardware.power.WorkDuration; + +@VintfStability +oneway interface IPowerHintSession { + /** + * Updates the desired duration of a previously-created thread group. + * + * See {@link IPowerHintSession#createHintSession} for more information on how + * the desired duration will be used. + * + * @param targetDurationNanos the new desired duration in nanoseconds + */ + void updateTargetWorkDuration(long targetDurationNanos); + + /** + * Reports the actual duration of a thread group. + * + * The system will attempt to adjust the core placement of the threads within + * the thread group and/or the frequency of the core on which they are run to bring + * the actual duration close to the target duration. + * + * @param actualDurationMicros how long the thread group took to complete its + * last task in nanoseconds + */ + void reportActualWorkDuration(in WorkDuration[] durations); + + /** + * Pause the session when the application is not in foreground and above + */ + void pause(); + + /** + * Resume the session when the application is not in foreground and above + */ + void resume(); + + /** + * Close the session to release resources + */ + void close(); +} diff --git a/power/aidl/android/hardware/power/WorkDuration.aidl b/power/aidl/android/hardware/power/WorkDuration.aidl new file mode 100644 index 0000000000..a06a058fb5 --- /dev/null +++ b/power/aidl/android/hardware/power/WorkDuration.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.power; + +@VintfStability +parcelable WorkDuration { + /** + * Time stamp in nanoseconds based on CLOCK_MONOTONIC when the duration + * sample was measured. + */ + long timeStampNanos; + /** + * Work duration in nanoseconds. + */ + long durationNanos; +} diff --git a/power/aidl/default/Android.bp b/power/aidl/default/Android.bp index 5aa6893e67..c0ba9a079c 100644 --- a/power/aidl/default/Android.bp +++ b/power/aidl/default/Android.bp @@ -30,7 +30,7 @@ cc_binary { shared_libs: [ "libbase", "libbinder_ndk", - "android.hardware.power-V1-ndk_platform", + "android.hardware.power-V2-ndk_platform", ], srcs: [ "main.cpp", diff --git a/power/aidl/default/Power.cpp b/power/aidl/default/Power.cpp index 8610de35b8..7f08f44926 100644 --- a/power/aidl/default/Power.cpp +++ b/power/aidl/default/Power.cpp @@ -25,6 +25,10 @@ namespace power { namespace impl { namespace example { +const std::vector BOOST_RANGE{ndk::enum_range().begin(), + ndk::enum_range().end()}; +const std::vector MODE_RANGE{ndk::enum_range().begin(), ndk::enum_range().end()}; + ndk::ScopedAStatus Power::setMode(Mode type, bool enabled) { LOG(VERBOSE) << "Power setMode: " << static_cast(type) << " to: " << enabled; return ndk::ScopedAStatus::ok(); @@ -32,7 +36,7 @@ ndk::ScopedAStatus Power::setMode(Mode type, bool enabled) { ndk::ScopedAStatus Power::isModeSupported(Mode type, bool* _aidl_return) { LOG(INFO) << "Power isModeSupported: " << static_cast(type); - *_aidl_return = false; + *_aidl_return = type >= MODE_RANGE.front() && type <= MODE_RANGE.back(); return ndk::ScopedAStatus::ok(); } @@ -44,10 +48,21 @@ ndk::ScopedAStatus Power::setBoost(Boost type, int32_t durationMs) { ndk::ScopedAStatus Power::isBoostSupported(Boost type, bool* _aidl_return) { LOG(INFO) << "Power isBoostSupported: " << static_cast(type); - *_aidl_return = false; + *_aidl_return = type >= BOOST_RANGE.front() && type <= BOOST_RANGE.back(); return ndk::ScopedAStatus::ok(); } +ndk::ScopedAStatus Power::createHintSession(int32_t, int32_t, const std::vector&, int64_t, + std::shared_ptr* _aidl_return) { + *_aidl_return = nullptr; + return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +} + +ndk::ScopedAStatus Power::getHintSessionPreferredRate(int64_t* outNanoseconds) { + *outNanoseconds = -1; + return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +} + } // namespace example } // namespace impl } // namespace power diff --git a/power/aidl/default/Power.h b/power/aidl/default/Power.h index f7645aa527..ef6439dde6 100644 --- a/power/aidl/default/Power.h +++ b/power/aidl/default/Power.h @@ -30,6 +30,11 @@ class Power : public BnPower { ndk::ScopedAStatus isModeSupported(Mode type, bool* _aidl_return) override; ndk::ScopedAStatus setBoost(Boost type, int32_t durationMs) override; ndk::ScopedAStatus isBoostSupported(Boost type, bool* _aidl_return) override; + ndk::ScopedAStatus createHintSession(int32_t tgid, int32_t uid, + const std::vector& threadIds, + int64_t durationNanos, + std::shared_ptr* _aidl_return) override; + ndk::ScopedAStatus getHintSessionPreferredRate(int64_t* outNanoseconds) override; }; } // namespace example diff --git a/power/aidl/vts/Android.bp b/power/aidl/vts/Android.bp index 1051b03823..3036b8202d 100644 --- a/power/aidl/vts/Android.bp +++ b/power/aidl/vts/Android.bp @@ -29,10 +29,10 @@ cc_test { ], srcs: ["VtsHalPowerTargetTest.cpp"], shared_libs: [ - "libbinder", + "libbinder_ndk", ], static_libs: [ - "android.hardware.power-V1-cpp", + "android.hardware.power-V2-ndk_platform", ], test_suites: [ "vts", diff --git a/power/aidl/vts/VtsHalPowerTargetTest.cpp b/power/aidl/vts/VtsHalPowerTargetTest.cpp index d036c9099f..5bb088a121 100644 --- a/power/aidl/vts/VtsHalPowerTargetTest.cpp +++ b/power/aidl/vts/VtsHalPowerTargetTest.cpp @@ -16,29 +16,28 @@ #include #include +#include +#include #include -#include -#include -#include -#include -#include - -#include - -using android::ProcessState; -using android::sp; -using android::String16; -using android::base::GetUintProperty; -using android::binder::Status; +#include +#include +#include + +#include + +namespace aidl::android::hardware::power { +namespace { + +using ::android::base::GetUintProperty; using android::hardware::power::Boost; using android::hardware::power::IPower; +using android::hardware::power::IPowerHintSession; using android::hardware::power::Mode; +using android::hardware::power::WorkDuration; -const std::vector kBoosts{android::enum_range().begin(), - android::enum_range().end()}; +const std::vector kBoosts{ndk::enum_range().begin(), ndk::enum_range().end()}; -const std::vector kModes{android::enum_range().begin(), - android::enum_range().end()}; +const std::vector kModes{ndk::enum_range().begin(), ndk::enum_range().end()}; const std::vector kInvalidBoosts = { static_cast(static_cast(kBoosts.front()) - 1), @@ -50,14 +49,48 @@ const std::vector kInvalidModes = { static_cast(static_cast(kModes.back()) + 1), }; +class DurationWrapper : public WorkDuration { + public: + DurationWrapper(int64_t dur, int64_t time) { + durationNanos = dur; + timeStampNanos = time; + } +}; + +const std::vector kSelfTids = { + gettid(), +}; + +const std::vector kEmptyTids = {}; + +const std::vector kNoDurations = {}; + +const std::vector kDurationsWithZero = { + DurationWrapper(1000L, 1L), + DurationWrapper(0L, 2L), +}; + +const std::vector kDurationsWithNegative = { + DurationWrapper(1000L, 1L), + DurationWrapper(-1000L, 2L), +}; + +const std::vector kDurations = { + DurationWrapper(1L, 1L), + DurationWrapper(1000L, 2L), + DurationWrapper(1000000L, 3L), + DurationWrapper(1000000000L, 4L), +}; + class PowerAidl : public testing::TestWithParam { public: virtual void SetUp() override { - power = android::waitForDeclaredService(String16(GetParam().c_str())); - ASSERT_NE(power, nullptr); + AIBinder* binder = AServiceManager_waitForService(GetParam().c_str()); + ASSERT_NE(binder, nullptr); + power = IPower::fromBinder(ndk::SpAIBinder(binder)); } - sp power; + std::shared_ptr power; }; TEST_P(PowerAidl, setMode) { @@ -110,6 +143,56 @@ TEST_P(PowerAidl, isBoostSupported) { } } +TEST_P(PowerAidl, getHintSessionPreferredRate) { + int64_t rate = -1; + auto status = power->getHintSessionPreferredRate(&rate); + if (!status.isOk()) { + ASSERT_EQ(EX_UNSUPPORTED_OPERATION, status.getExceptionCode()); + return; + } + + // At least 1ms rate limit from HAL + ASSERT_GE(rate, 1000000); +} + +TEST_P(PowerAidl, createAndCloseHintSession) { + std::shared_ptr session; + auto status = power->createHintSession(getpid(), getuid(), kSelfTids, 16666666L, &session); + if (!status.isOk()) { + ASSERT_EQ(EX_UNSUPPORTED_OPERATION, status.getExceptionCode()); + return; + } + ASSERT_NE(nullptr, session); + ASSERT_TRUE(session->pause().isOk()); + ASSERT_TRUE(session->resume().isOk()); + // Test normal destroy operation + ASSERT_TRUE(session->close().isOk()); + session.reset(); +} +TEST_P(PowerAidl, createHintSessionFailed) { + std::shared_ptr session; + auto status = power->createHintSession(getpid(), getuid(), kEmptyTids, 16666666L, &session); + ASSERT_FALSE(status.isOk()); + if (EX_UNSUPPORTED_OPERATION == status.getExceptionCode()) { + return; + } + // Test with empty tid list + ASSERT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode()); +} + +TEST_P(PowerAidl, updateAndReportDurations) { + std::shared_ptr session; + auto status = power->createHintSession(getpid(), getuid(), kSelfTids, 16666666L, &session); + if (!status.isOk()) { + ASSERT_EQ(EX_UNSUPPORTED_OPERATION, status.getExceptionCode()); + return; + } + ASSERT_NE(nullptr, session); + + ASSERT_TRUE(session->updateTargetWorkDuration(16666667LL).isOk()); + ASSERT_TRUE(session->reportActualWorkDuration(kDurations).isOk()); +} + // FIXED_PERFORMANCE mode is required for all devices which ship on Android 11 // or later TEST_P(PowerAidl, hasFixedPerformance) { @@ -128,12 +211,16 @@ TEST_P(PowerAidl, hasFixedPerformance) { GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(PowerAidl); INSTANTIATE_TEST_SUITE_P(Power, PowerAidl, - testing::ValuesIn(android::getAidlHalInstanceNames(IPower::descriptor)), - android::PrintInstanceNameToString); + testing::ValuesIn(::android::getAidlHalInstanceNames(IPower::descriptor)), + ::android::PrintInstanceNameToString); + +} // namespace int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); - ProcessState::self()->setThreadPoolMaxThreadCount(1); - ProcessState::self()->startThreadPool(); + ABinderProcess_setThreadPoolMaxThreadCount(1); + ABinderProcess_startThreadPool(); return RUN_ALL_TESTS(); } + +} // namespace aidl::android::hardware::power -- GitLab From 46816afaf6d2766e73a2b0a12346b319539e6796 Mon Sep 17 00:00:00 2001 From: Kevin Chyn Date: Mon, 5 Apr 2021 11:20:37 -0700 Subject: [PATCH 581/790] Update detectInteraction documentation Bug: 182004420 Test: Builds Change-Id: I1f785d4dda9bbde44aeab091b1f6cb1eaddf5afa --- .../face/aidl/android/hardware/biometrics/face/ISession.aidl | 1 + 1 file changed, 1 insertion(+) diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl index f9c13e6801..97348737ee 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl @@ -213,6 +213,7 @@ interface ISession { * 1) Any face is detected and the framework is notified via * ISessionCallback#onInteractiondetected * 2) The operation was cancelled by the framework (see ICancellationSignal) + * 3) An error occurred, for example ERROR::TIMEOUT * * Note that if the operation is canceled, the implementation must notify the framework via * ISessionCallback#onError with Error::CANCELED. -- GitLab From 4895b4df794060b04ce590cb58fd493ec9ea4b03 Mon Sep 17 00:00:00 2001 From: Michael Butler Date: Thu, 18 Mar 2021 21:15:09 -0700 Subject: [PATCH 582/790] Change NNAPI time from steady_clock to boot_clock -- hal Previously, the NNAPI used std::chrono::steady_clock to represent and measure timings. However, steady_clock does not count while the system is suspended. Instead, boot_clock is monotonic like steady_clock but does include the time when the system is suspended. This change also indicates that services may convert from std::chrono::steady_clock::time_point to android::base::boot_clock::time_point in the HIDL 1.3 NN HAL. Bug: 183118340 Test: mma Test: VtsHalNeuralnetworksV1_3TargetTest Test: VtsHalNeuralnetworksTargetTest Test: presubmit Change-Id: I5a7d039a31d9ce98602a301387ec99635f279f42 Merged-In: I5a7d039a31d9ce98602a301387ec99635f279f42 --- current.txt | 2 + neuralnetworks/1.3/IDevice.hal | 18 ++++- neuralnetworks/1.3/IPreparedModel.hal | 24 +++++++ neuralnetworks/1.3/utils/src/Conversions.cpp | 71 ++++++++++++++++++- .../hardware/neuralnetworks/IDevice.aidl | 16 ++--- .../neuralnetworks/IPreparedModel.aidl | 8 +-- neuralnetworks/aidl/utils/src/Conversions.cpp | 9 +-- .../vts/functional/QualityOfServiceTests.cpp | 10 +-- 8 files changed, 133 insertions(+), 25 deletions(-) diff --git a/current.txt b/current.txt index 6c576cab7a..270880fbf1 100644 --- a/current.txt +++ b/current.txt @@ -782,6 +782,8 @@ cd84ab19c590e0e73dd2307b591a3093ee18147ef95e6d5418644463a6620076 android.hardwar f729ee6a5f136b25d79ea6895d24700fce413df555baaecf2c39e4440d15d043 android.hardware.neuralnetworks@1.0::types a84f8dac7a9b75de1cc2936a9b429b9b62b32a31ea88ca52c29f98f5ddc0fa95 android.hardware.neuralnetworks@1.2::types cd331b92312d16ab89f475c39296abbf539efc4114a8c5c2b136ad99b904ef33 android.hardware.neuralnetworks@1.3::types +c3fec5bd470984402997f78a74b6511efc4063b270f2bd9ee7b78f48b683a1bb android.hardware.neuralnetworks@1.3::IDevice +0fdfad62c2ec33b52e6687004e5a1971c02d10b93ee4d26df5ccff7ce032494a android.hardware.neuralnetworks@1.3::IPreparedModel e8c86c69c438da8d1549856c1bb3e2d1b8da52722f8235ff49a30f2cce91742c android.hardware.soundtrigger@2.1::ISoundTriggerHwCallback b9fbb6e2e061ed0960939d48b785e9700210add1f13ed32ecd688d0f1ca20ef7 android.hardware.renderscript@1.0::types 0f53d70e1eadf8d987766db4bf6ae2048004682168f4cab118da576787def3fa android.hardware.radio@1.0::types diff --git a/neuralnetworks/1.3/IDevice.hal b/neuralnetworks/1.3/IDevice.hal index e0b04a8b62..de889e4b25 100644 --- a/neuralnetworks/1.3/IDevice.hal +++ b/neuralnetworks/1.3/IDevice.hal @@ -131,6 +131,14 @@ interface IDevice extends @1.2::IDevice { * 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. + * The deadline is represented as nanoseconds since the epoch of the steady + * clock (as if from std::chrono::steady_clock::time_point), but the service + * may convert it to the nanoseconds since boot time (as if from + * clock_gettime(CLOCK_BOOTTIME, &ts) or + * android::base::boot_clock::time_point) to account for time when the + * system is suspended. This conversion can by done by finding the timeout + * duration remaining compared to the steady_clock and adding it to the + * current boot_clock time. * * Optionally, the driver may save the prepared model to cache during the * asynchronous preparation. Any error that occurs when saving to cache must @@ -249,7 +257,15 @@ interface IDevice extends @1.2::IDevice { * 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. + * described above. The deadline is represented as nanoseconds since the + * epoch of the steady clock (as if from + * std::chrono::steady_clock::time_point), but the service may convert it to + * the nanoseconds since boot time (as if from + * clock_gettime(CLOCK_BOOTTIME, &ts) or + * android::base::boot_clock::time_point) to account for time when the + * system is suspended. This conversion can by done by finding the timeout + * duration remaining compared to the steady_clock and adding it to the + * current boot_clock time. * * The only information that may be unknown to the model at this stage is * the shape of the tensors, which may only be known at execution time. As diff --git a/neuralnetworks/1.3/IPreparedModel.hal b/neuralnetworks/1.3/IPreparedModel.hal index e7d63f4851..8b86a1a20e 100644 --- a/neuralnetworks/1.3/IPreparedModel.hal +++ b/neuralnetworks/1.3/IPreparedModel.hal @@ -74,6 +74,14 @@ interface IPreparedModel extends @1.2::IPreparedModel { * 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. + * The deadline is represented as nanoseconds since the epoch of the steady + * clock (as if from std::chrono::steady_clock::time_point), but the service + * may convert it to the nanoseconds since boot time (as if from + * clock_gettime(CLOCK_BOOTTIME, &ts) or + * android::base::boot_clock::time_point) to account for time when the + * system is suspended. This conversion can by done by finding the timeout + * duration remaining compared to the steady_clock and adding it to the + * current boot_clock time. * * Any number of calls to the execute* and executeSynchronously* functions, * in any combination, may be made concurrently, even on the same @@ -150,6 +158,14 @@ interface IPreparedModel extends @1.2::IPreparedModel { * 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. + * The deadline is represented as nanoseconds since the epoch of the steady + * clock (as if from std::chrono::steady_clock::time_point), but the service + * may convert it to the nanoseconds since boot time (as if from + * clock_gettime(CLOCK_BOOTTIME, &ts) or + * android::base::boot_clock::time_point) to account for time when the + * system is suspended. This conversion can by done by finding the timeout + * duration remaining compared to the steady_clock and adding it to the + * current boot_clock time. * * Any number of calls to the execute* and executeSynchronously* functions, * in any combination, may be made concurrently, even on the same @@ -231,6 +247,14 @@ interface IPreparedModel extends @1.2::IPreparedModel { * {@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. + * The deadline is represented as nanoseconds since the epoch of the steady + * clock (as if from std::chrono::steady_clock::time_point), but the service + * may convert it to the nanoseconds since boot time (as if from + * clock_gettime(CLOCK_BOOTTIME, &ts) or + * android::base::boot_clock::time_point) to account for time when the + * system is suspended. This conversion can by done by finding the timeout + * duration remaining compared to the steady_clock and adding it to the + * current boot_clock time. * * 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 diff --git a/neuralnetworks/1.3/utils/src/Conversions.cpp b/neuralnetworks/1.3/utils/src/Conversions.cpp index 8083ae4368..e8a4f55afd 100644 --- a/neuralnetworks/1.3/utils/src/Conversions.cpp +++ b/neuralnetworks/1.3/utils/src/Conversions.cpp @@ -42,6 +42,23 @@ namespace { +std::chrono::nanoseconds makeNanosFromUint64(uint64_t nanoseconds) { + constexpr auto kMaxCount = std::chrono::nanoseconds::max().count(); + using CommonType = std::common_type_t; + const auto count = std::min(kMaxCount, nanoseconds); + return std::chrono::nanoseconds{static_cast(count)}; +} + +uint64_t makeUint64FromNanos(std::chrono::nanoseconds nanoseconds) { + if (nanoseconds < std::chrono::nanoseconds::zero()) { + return 0; + } + constexpr auto kMaxCount = std::numeric_limits::max(); + using CommonType = std::common_type_t; + const auto count = std::min(kMaxCount, nanoseconds.count()); + return static_cast(count); +} + template constexpr std::underlying_type_t underlyingType(Type value) { return static_cast>(value); @@ -237,8 +254,32 @@ GeneralResult unvalidatedConvert( switch (optionalTimePoint.getDiscriminator()) { case Discriminator::none: return {}; - case Discriminator::nanosecondsSinceEpoch: - return TimePoint{Duration{optionalTimePoint.nanosecondsSinceEpoch()}}; + case Discriminator::nanosecondsSinceEpoch: { + const auto currentSteadyTime = std::chrono::steady_clock::now(); + const auto currentBootTime = Clock::now(); + + const auto timeSinceEpoch = + makeNanosFromUint64(optionalTimePoint.nanosecondsSinceEpoch()); + const auto steadyTimePoint = std::chrono::steady_clock::time_point{timeSinceEpoch}; + + // Both steadyTimePoint and currentSteadyTime are guaranteed to be non-negative, so this + // subtraction will never overflow or underflow. + const auto timeRemaining = steadyTimePoint - currentSteadyTime; + + // currentBootTime is guaranteed to be non-negative, so this code only protects against + // an overflow. + nn::TimePoint bootTimePoint; + constexpr auto kZeroNano = std::chrono::nanoseconds::zero(); + constexpr auto kMaxTime = nn::TimePoint::max(); + if (timeRemaining > kZeroNano && currentBootTime > kMaxTime - timeRemaining) { + bootTimePoint = kMaxTime; + } else { + bootTimePoint = currentBootTime + timeRemaining; + } + + constexpr auto kZeroTime = nn::TimePoint{}; + return std::max(bootTimePoint, kZeroTime); + } } return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "Invalid OptionalTimePoint discriminator " @@ -549,9 +590,33 @@ nn::GeneralResult unvalidatedConvert( nn::GeneralResult unvalidatedConvert( const nn::OptionalTimePoint& optionalTimePoint) { + const auto currentSteadyTime = std::chrono::steady_clock::now(); + const auto currentBootTime = nn::Clock::now(); + OptionalTimePoint ret; if (optionalTimePoint.has_value()) { - const auto count = optionalTimePoint.value().time_since_epoch().count(); + const auto bootTimePoint = optionalTimePoint.value(); + + if (bootTimePoint < nn::TimePoint{}) { + return NN_ERROR() << "Trying to cast invalid time point"; + } + + // Both bootTimePoint and currentBootTime are guaranteed to be non-negative, so this + // subtraction will never overflow or underflow. + const auto timeRemaining = bootTimePoint - currentBootTime; + + // currentSteadyTime is guaranteed to be non-negative, so this code only protects against an + // overflow. + std::chrono::steady_clock::time_point steadyTimePoint; + constexpr auto kZeroNano = std::chrono::nanoseconds::zero(); + constexpr auto kMaxTime = std::chrono::steady_clock::time_point::max(); + if (timeRemaining > kZeroNano && currentSteadyTime > kMaxTime - timeRemaining) { + steadyTimePoint = kMaxTime; + } else { + steadyTimePoint = currentSteadyTime + timeRemaining; + } + + const uint64_t count = makeUint64FromNanos(steadyTimePoint.time_since_epoch()); ret.nanosecondsSinceEpoch(count); } return ret; diff --git a/neuralnetworks/aidl/android/hardware/neuralnetworks/IDevice.aidl b/neuralnetworks/aidl/android/hardware/neuralnetworks/IDevice.aidl index e17e0cd765..c5b4ab1b8f 100644 --- a/neuralnetworks/aidl/android/hardware/neuralnetworks/IDevice.aidl +++ b/neuralnetworks/aidl/android/hardware/neuralnetworks/IDevice.aidl @@ -307,10 +307,10 @@ interface IDevice { * @param priority The priority of the prepared model relative to other prepared models owned by * the client. * @param deadline The time by which the model is expected to be prepared. The time is measured - * in nanoseconds since epoch of the steady clock (as from - * std::chrono::steady_clock). If the model cannot be prepared by the deadline, - * the preparation may be aborted. Passing -1 means the deadline is omitted. - * Other negative values are invalid. + * in nanoseconds since boot (as from clock_gettime(CLOCK_BOOTTIME, &ts) + * or ::android::base::boot_clock). If the model cannot be prepared by the + * deadline, the preparation may be aborted. Passing -1 means the deadline is + * omitted. Other negative values are invalid. * @param modelCache A vector of file descriptors for the security-sensitive cache. The length * of the vector must either be 0 indicating that caching information is not * provided, or match the numModelCache returned from @@ -396,10 +396,10 @@ interface IDevice { * different shapes of inputs on different (possibly concurrent) executions. * * @param deadline The time by which the model is expected to be prepared. The time is measured - * in nanoseconds since epoch of the steady clock (as from - * std::chrono::steady_clock). If the model cannot be prepared by the deadline, - * the preparation may be aborted. Passing -1 means the deadline is omitted. - * Other negative values are invalid. + * in nanoseconds since boot (as from clock_gettime(CLOCK_BOOTTIME, &ts) or + * ::android::base::boot_clock). If the model cannot be prepared by the + * deadline, the preparation may be aborted. Passing -1 means the deadline is + * omitted. Other negative values are invalid. * @param modelCache A vector of file descriptors for the security-sensitive cache. The length * of the vector must match the numModelCache returned from * getNumberOfCacheFilesNeeded. The cache file descriptors will be provided in diff --git a/neuralnetworks/aidl/android/hardware/neuralnetworks/IPreparedModel.aidl b/neuralnetworks/aidl/android/hardware/neuralnetworks/IPreparedModel.aidl index 2a9757b323..bfab9067d1 100644 --- a/neuralnetworks/aidl/android/hardware/neuralnetworks/IPreparedModel.aidl +++ b/neuralnetworks/aidl/android/hardware/neuralnetworks/IPreparedModel.aidl @@ -73,8 +73,8 @@ interface IPreparedModel { * runs from the time the driver sees the call to the executeSynchronously * function to the time the driver returns from the function. * @param deadline 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 + * 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 loopTimeoutDuration The maximum amount of time in nanoseconds that should be spent @@ -138,8 +138,8 @@ interface IPreparedModel { * sync fences have been signaled. * @param measure Specifies whether or not to measure duration of the execution. * @param deadline 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 + * 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 loopTimeoutDuration The maximum amount of time in nanoseconds that should be spent diff --git a/neuralnetworks/aidl/utils/src/Conversions.cpp b/neuralnetworks/aidl/utils/src/Conversions.cpp index c74c509a8d..d5f7f81663 100644 --- a/neuralnetworks/aidl/utils/src/Conversions.cpp +++ b/neuralnetworks/aidl/utils/src/Conversions.cpp @@ -931,11 +931,12 @@ nn::GeneralResult unvalidatedConvert(const nn::Timing& timing) { } nn::GeneralResult unvalidatedConvert(const nn::Duration& duration) { - const uint64_t nanoseconds = duration.count(); - if (nanoseconds > std::numeric_limits::max()) { - return std::numeric_limits::max(); + if (duration < nn::Duration::zero()) { + return NN_ERROR() << "Unable to convert invalid (negative) duration"; } - return static_cast(nanoseconds); + constexpr std::chrono::nanoseconds::rep kIntMax = std::numeric_limits::max(); + const auto count = duration.count(); + return static_cast(std::min(count, kIntMax)); } nn::GeneralResult unvalidatedConvert(const nn::OptionalDuration& optionalDuration) { diff --git a/neuralnetworks/aidl/vts/functional/QualityOfServiceTests.cpp b/neuralnetworks/aidl/vts/functional/QualityOfServiceTests.cpp index 9ace1a9591..e803e38092 100644 --- a/neuralnetworks/aidl/vts/functional/QualityOfServiceTests.cpp +++ b/neuralnetworks/aidl/vts/functional/QualityOfServiceTests.cpp @@ -14,10 +14,10 @@ * limitations under the License. */ +#include #include #include #include - #include #include "Callbacks.h" @@ -61,16 +61,16 @@ static int64_t makeDeadline(DeadlineBoundType deadlineBoundType) { return std::chrono::duration_cast(timeSinceEpoch).count(); }; - std::chrono::steady_clock::time_point timePoint; + ::android::base::boot_clock::time_point timePoint; switch (deadlineBoundType) { case DeadlineBoundType::NOW: - timePoint = std::chrono::steady_clock::now(); + timePoint = ::android::base::boot_clock::now(); break; case DeadlineBoundType::UNLIMITED: - timePoint = std::chrono::steady_clock::time_point::max(); + timePoint = ::android::base::boot_clock::time_point::max(); break; case DeadlineBoundType::SHORT: - timePoint = std::chrono::steady_clock::now() + kShortDuration; + timePoint = ::android::base::boot_clock::now() + kShortDuration; break; } -- GitLab From 7a7462397a323ba3ffa1631b8b8b424a220b544f Mon Sep 17 00:00:00 2001 From: Wei Wang Date: Mon, 5 Apr 2021 19:27:17 -0700 Subject: [PATCH 583/790] power: bump default example implementation to version 2 Bug: 177492680 Test: Build Signed-off-by: Wei Wang Change-Id: If423a7d0fb800a9528336245c7dbf42689080f0b --- compatibility_matrices/compatibility_matrix.current.xml | 2 +- power/aidl/default/power-default.xml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index c656af2b21..bb22974b98 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -419,7 +419,7 @@ android.hardware.power - 1 + 1-2 IPower default diff --git a/power/aidl/default/power-default.xml b/power/aidl/default/power-default.xml index caf6ea2d5d..9f56debdae 100644 --- a/power/aidl/default/power-default.xml +++ b/power/aidl/default/power-default.xml @@ -1,6 +1,7 @@ android.hardware.power + 2 IPower/default -- GitLab From a468cac258e722c648bb030fe70d29bae4d3246a Mon Sep 17 00:00:00 2001 From: Andy Hung Date: Tue, 6 Apr 2021 10:16:48 -0700 Subject: [PATCH 584/790] Audio: Add AUDIO_FORMAT_DTS_UHD See ETSI TS 103 491 V1.2.1 (2019-05) DTS-UHD Audio Format; Delivery of Channels, Objects and Ambisonic Sound Fields Test: atest AudioFormatTest Bug: 184538197 Change-Id: I4123efb29a95a599982af85068f8e4468ff15159 --- audio/7.0/config/api/current.txt | 1 + audio/7.0/config/audio_policy_configuration.xsd | 1 + 2 files changed, 2 insertions(+) diff --git a/audio/7.0/config/api/current.txt b/audio/7.0/config/api/current.txt index 7d2706cbe9..0bddd759e1 100644 --- a/audio/7.0/config/api/current.txt +++ b/audio/7.0/config/api/current.txt @@ -209,6 +209,7 @@ package android.audio.policy.configuration.V7_0 { enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DSD; enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DTS; enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DTS_HD; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DTS_UHD; enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_EVRC; enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_EVRCB; enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_EVRCNW; diff --git a/audio/7.0/config/audio_policy_configuration.xsd b/audio/7.0/config/audio_policy_configuration.xsd index 2030921453..a06e0278c7 100644 --- a/audio/7.0/config/audio_policy_configuration.xsd +++ b/audio/7.0/config/audio_policy_configuration.xsd @@ -412,6 +412,7 @@ + -- GitLab From e50f08d05f4795006d4e5dc3a4eeb0ad7dc9446e Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Tue, 30 Mar 2021 15:56:02 -0700 Subject: [PATCH 585/790] Add dvr dynamic configuration into Tuner 1.0 VTS Test: atest VtsHalTvTunerV1_0TargetTest Bug: 182519645 CTS-Coverage-Bug: 184077478 Change-Id: I04ef708064179e62c0c7b8c790fe844543b3eac8 --- .../VtsHalTvTunerV1_0TargetTest.cpp | 91 ++++------------- .../functional/VtsHalTvTunerV1_0TargetTest.h | 2 +- .../VtsHalTvTunerV1_0TestConfigurations.h | 83 ++++++++-------- tv/tuner/config/OWNERS | 4 + tv/tuner/config/TunerTestingConfigReader.h | 97 +++++++++++++++++- tv/tuner/config/api/current.txt | 69 +++++++++++++ tv/tuner/config/sample_tuner_vts_config.xml | 41 +++++++- .../tuner_testing_dynamic_configuration.xsd | 99 ++++++++++++++++++- 8 files changed, 360 insertions(+), 126 deletions(-) create mode 100644 tv/tuner/config/OWNERS diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp index 92996f9dc7..5fbdd2df0c 100644 --- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp +++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp @@ -86,17 +86,14 @@ void TunerBroadcastHidlTest::broadcastSingleFilterTest(FilterConfig filterConf, uint32_t filterId; mFrontendTests.getFrontendIdByType(frontendConf.type, feId); - if (feId == INVALID_ID) { - // TODO broadcast test on Cuttlefish needs licensed ts input, - // these tests are runnable on vendor device with real frontend module - // or with manual ts installing and use DVBT frontend. - return; - } ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); ASSERT_TRUE(mFrontendTests.setFrontendCallback()); if (mLnbId) { ASSERT_TRUE(mFrontendTests.setLnb(*mLnbId)); } + if (frontendConf.isSoftwareFe) { + mFrontendTests.setSoftwareFrontendDvrConfig(dvrMap[live.dvrSoftwareFeId]); + } ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); mFrontendTests.setDemux(demux); @@ -178,6 +175,9 @@ void TunerRecordHidlTest::recordSingleFilterTest(FilterConfig filterConf, if (mLnbId) { ASSERT_TRUE(mFrontendTests.setLnb(*mLnbId)); } + if (frontendConf.isSoftwareFe) { + mFrontendTests.setSoftwareFrontendDvrConfig(dvrMap[record.dvrSoftwareFeId]); + } ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); mFilterTests.setDemux(demux); @@ -279,14 +279,11 @@ void TunerDescramblerHidlTest::scrambledBroadcastTest(set m set::iterator id; mFrontendTests.getFrontendIdByType(frontendConf.type, feId); - if (feId == INVALID_ID) { - // TODO broadcast test on Cuttlefish needs licensed ts input, - // these tests are runnable on vendor device with real frontend module - // or with manual ts installing and use DVBT frontend. - return; - } ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); ASSERT_TRUE(mFrontendTests.setFrontendCallback()); + if (frontendConf.isSoftwareFe) { + mFrontendTests.setSoftwareFrontendDvrConfig(dvrMap[descrambling.dvrSoftwareFeId]); + } ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); mFilterTests.setDemux(demux); @@ -301,7 +298,7 @@ void TunerDescramblerHidlTest::scrambledBroadcastTest(set m TunerKeyToken token; ASSERT_TRUE(mDescramblerTests.getKeyToken(descConfig.casSystemId, descConfig.provisionStr, descConfig.hidlPvtData, token)); - ASSERT_TRUE(mDescramblerTests.setKeyToken(token)); + mDescramblerTests.setKeyToken(token); vector pids; DemuxPid pid; for (config = mediaFilterConfs.begin(); config != mediaFilterConfs.end(); config++) { @@ -497,66 +494,12 @@ TEST_P(TunerBroadcastHidlTest, LnbBroadcastDataFlowVideoFilterTest) { broadcastSingleFilterTest(filterArray[TS_VIDEO0], frontendMap[live.frontendId]); } -TEST_P(TunerBroadcastHidlTest, BroadcastEsDataFlowMediaFiltersTest) { - description("Test Meida Filters functionality in Broadcast use case with ES input."); - uint32_t feId; - uint32_t demuxId; - sp demux; - uint32_t filterId; - - mFrontendTests.getFrontendIdByType(frontendMap[live.frontendId].type, feId); - if (feId == INVALID_ID) { - // TODO broadcast test on Cuttlefish needs licensed ts input, - // these tests are runnable on vendor device with real frontend module - // or with manual ts installing and use defaultFrontend frontend. - return; - } - ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); - ASSERT_TRUE(mFrontendTests.setFrontendCallback()); - ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); - ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); - mFrontendTests.setDemux(demux); - mFilterTests.setDemux(demux); - ASSERT_TRUE(mFilterTests.openFilterInDemux(filterArray[TS_AUDIO1].type, - filterArray[TS_AUDIO1].bufferSize)); - ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId)); - ASSERT_TRUE(mFilterTests.configFilter(filterArray[TS_AUDIO1].settings, filterId)); - ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterArray[TS_AUDIO1].getMqDesc)); - ASSERT_TRUE(mFilterTests.startFilter(filterId)); - ASSERT_TRUE(mFilterTests.openFilterInDemux(filterArray[TS_VIDEO1].type, - filterArray[TS_VIDEO1].bufferSize)); - ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId)); - ASSERT_TRUE(mFilterTests.configFilter(filterArray[TS_VIDEO1].settings, filterId)); - ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterArray[TS_VIDEO1].getMqDesc)); - ASSERT_TRUE(mFilterTests.startFilter(filterId)); - // tune test - // TODO: replace with customized dvr input - PlaybackSettings playbackSettings{ - .statusMask = 0xf, - .lowThreshold = 0x1000, - .highThreshold = 0x07fff, - .dataFormat = DataFormat::ES, - .packetSize = 188, - }; - DvrConfig dvrConfig{ - .type = DvrType::PLAYBACK, - .playbackInputFile = "/data/local/tmp/test.es", - .bufferSize = FMQ_SIZE_4M, - }; - dvrConfig.settings.playback(playbackSettings); - mFrontendTests.setSoftwareFrontendDvrConfig(dvrConfig); - ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendMap[live.frontendId], true /*testWithDemux*/)); - ASSERT_TRUE(filterDataOutputTest()); - ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/)); - ASSERT_TRUE(mFilterTests.stopFilter(filterId)); - ASSERT_TRUE(mFilterTests.closeFilter(filterId)); - ASSERT_TRUE(mDemuxTests.closeDemux()); - ASSERT_TRUE(mFrontendTests.closeFrontend()); -} - TEST_P(TunerPlaybackHidlTest, PlaybackDataFlowWithTsSectionFilterTest) { description("Feed ts data from playback and configure Ts section filter to get output"); - playbackSingleFilterTest(filterArray[TS_SECTION0], dvrArray[DVR_PLAYBACK0]); + if (!playback.support) { + return; + } + playbackSingleFilterTest(filterArray[TS_SECTION0], dvrMap[playback.dvrId]); } TEST_P(TunerRecordHidlTest, AttachFiltersToRecordTest) { @@ -566,7 +509,7 @@ TEST_P(TunerRecordHidlTest, AttachFiltersToRecordTest) { return; } attachSingleFilterToRecordDvrTest(filterArray[TS_RECORD0], frontendMap[record.frontendId], - dvrArray[DVR_RECORD0]); + dvrMap[record.dvrRecordId]); } TEST_P(TunerRecordHidlTest, RecordDataFlowWithTsRecordFilterTest) { @@ -575,7 +518,7 @@ TEST_P(TunerRecordHidlTest, RecordDataFlowWithTsRecordFilterTest) { return; } recordSingleFilterTest(filterArray[TS_RECORD0], frontendMap[record.frontendId], - dvrArray[DVR_RECORD0]); + dvrMap[record.dvrRecordId]); } TEST_P(TunerRecordHidlTest, LnbRecordDataFlowWithTsRecordFilterTest) { @@ -584,7 +527,7 @@ TEST_P(TunerRecordHidlTest, LnbRecordDataFlowWithTsRecordFilterTest) { return; } recordSingleFilterTestWithLnb(filterArray[TS_RECORD0], frontendMap[lnbRecord.frontendId], - dvrArray[DVR_RECORD0], lnbArray[LNB0]); + dvrMap[record.dvrRecordId], lnbArray[LNB0]); } TEST_P(TunerDescramblerHidlTest, CreateDescrambler) { diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h index d1f6a45366..9723c2d645 100644 --- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h +++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h @@ -33,6 +33,7 @@ bool initConfiguration() { return false; } initFrontendConfig(); + initDvrConfig(); connectHardwaresToTestCases(); if (!validateConnections()) { ALOGW("[vts] failed to validate connections."); @@ -42,7 +43,6 @@ bool initConfiguration() { initLnbConfig(); initFilterConfig(); initTimeFilterConfig(); - initDvrConfig(); initDescramblerConfig(); return true; diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h index 384455bc74..a1c5cd9aa2 100644 --- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h +++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h @@ -114,12 +114,6 @@ typedef enum { DISEQC_MAX, } Diseqc; -typedef enum { - DVR_RECORD0, - DVR_PLAYBACK0, - DVR_MAX, -} Dvr; - typedef enum { DESC_0, DESC_MAX, @@ -147,13 +141,6 @@ struct LnbConfig { LnbPosition position; }; -struct DvrConfig { - DvrType type; - uint32_t bufferSize; - DvrSettings settings; - string playbackInputFile; -}; - struct DescramblerConfig { uint32_t casSystemId; string provisionStr; @@ -166,24 +153,25 @@ static vector diseqcMsgArray[DISEQC_MAX]; static FilterConfig filterArray[FILTER_MAX]; static TimeFilterConfig timeFilterArray[TIMER_MAX]; static DemuxFilterType filterLinkageTypes[LINKAGE_DIR][FILTER_MAIN_TYPE_BIT_COUNT]; -static DvrConfig dvrArray[DVR_MAX]; static DescramblerConfig descramblerArray[DESC_MAX]; // Hardware configs static map frontendMap; +static map dvrMap; // Hardware and test cases connections static LiveBroadcastHardwareConnections live; static ScanHardwareConnections scan; +static DvrPlaybackHardwareConnections playback; static DvrRecordHardwareConnections record; static DescramblingHardwareConnections descrambling; static LnbLiveHardwareConnections lnbLive; static LnbRecordHardwareConnections lnbRecord; -/** Configuration array for the frontend tune test */ +/** Config all the frontends that would be used in the tests */ inline void initFrontendConfig() { - // The test will use the internal default fe is default fe is connected to any data flow without - // overriding in the xml config. + // The test will use the internal default fe when default fe is connected to any data flow + // without overriding in the xml config. string defaultFeId = "FE_DEFAULT"; FrontendDvbtSettings dvbtSettings{ .frequency = 578000, @@ -208,10 +196,17 @@ inline void initFrontendConfig() { TunerTestingConfigReader::readFrontendConfig1_0(frontendMap); }; +/** Config all the dvrs that would be used in the tests */ +inline void initDvrConfig() { + // Read customized config + TunerTestingConfigReader::readDvrConfig1_0(dvrMap); +}; + /** Read the vendor configurations of which hardware to use for each test cases/data flows */ inline void connectHardwaresToTestCases() { TunerTestingConfigReader::connectLiveBroadcast(live); TunerTestingConfigReader::connectScan(scan); + TunerTestingConfigReader::connectDvrPlayback(playback); TunerTestingConfigReader::connectDvrRecord(record); TunerTestingConfigReader::connectDescrambling(descrambling); TunerTestingConfigReader::connectLnbLive(lnbLive); @@ -228,7 +223,34 @@ inline bool validateConnections() { feIsValid &= lnbLive.support ? frontendMap.find(lnbLive.frontendId) != frontendMap.end() : true; feIsValid &= lnbRecord.support ? frontendMap.find(lnbRecord.frontendId) != frontendMap.end() : true; - return feIsValid; + + if (!feIsValid) { + ALOGW("[vts config] dynamic config fe connection is invalid."); + return false; + } + + bool dvrIsValid = frontendMap[live.frontendId].isSoftwareFe + ? dvrMap.find(live.dvrSoftwareFeId) != dvrMap.end() + : true; + dvrIsValid &= playback.support ? dvrMap.find(playback.dvrId) != dvrMap.end() : true; + + if (record.support) { + if (frontendMap[record.frontendId].isSoftwareFe) { + dvrIsValid &= dvrMap.find(record.dvrSoftwareFeId) != dvrMap.end(); + } + dvrIsValid &= dvrMap.find(record.dvrRecordId) != dvrMap.end(); + } + + if (descrambling.support && frontendMap[descrambling.frontendId].isSoftwareFe) { + dvrIsValid &= dvrMap.find(descrambling.dvrSoftwareFeId) != dvrMap.end(); + } + + if (!dvrIsValid) { + ALOGW("[vts config] dynamic config dvr connection is invalid."); + return false; + } + + return true; } // TODO: remove all the manual configs after the dynamic config refactoring is done. @@ -341,31 +363,6 @@ inline void initTimeFilterConfig() { timeFilterArray[TIMER0].timeStamp = 1; } -/** Configuration array for the dvr test */ -inline void initDvrConfig() { - RecordSettings recordSettings{ - .statusMask = 0xf, - .lowThreshold = 0x1000, - .highThreshold = 0x07fff, - .dataFormat = DataFormat::TS, - .packetSize = 188, - }; - dvrArray[DVR_RECORD0].type = DvrType::RECORD; - dvrArray[DVR_RECORD0].bufferSize = FMQ_SIZE_4M; - dvrArray[DVR_RECORD0].settings.record(recordSettings); - PlaybackSettings playbackSettings{ - .statusMask = 0xf, - .lowThreshold = 0x1000, - .highThreshold = 0x07fff, - .dataFormat = DataFormat::TS, - .packetSize = 188, - }; - dvrArray[DVR_PLAYBACK0].type = DvrType::PLAYBACK; - dvrArray[DVR_PLAYBACK0].playbackInputFile = "/data/local/tmp/segment000000.ts"; - dvrArray[DVR_PLAYBACK0].bufferSize = FMQ_SIZE_4M; - dvrArray[DVR_PLAYBACK0].settings.playback(playbackSettings); -}; - /** Configuration array for the descrambler test */ inline void initDescramblerConfig() { descramblerArray[DESC_0].casSystemId = CLEAR_KEY_SYSTEM_ID; diff --git a/tv/tuner/config/OWNERS b/tv/tuner/config/OWNERS new file mode 100644 index 0000000000..1b3d095f9c --- /dev/null +++ b/tv/tuner/config/OWNERS @@ -0,0 +1,4 @@ +nchalko@google.com +amyjojo@google.com +shubang@google.com +quxiangfang@google.com diff --git a/tv/tuner/config/TunerTestingConfigReader.h b/tv/tuner/config/TunerTestingConfigReader.h index 5c7f5648d3..aa2b75c1de 100644 --- a/tv/tuner/config/TunerTestingConfigReader.h +++ b/tv/tuner/config/TunerTestingConfigReader.h @@ -70,8 +70,16 @@ struct FrontendConfig { vector expectTuneStatuses; }; +struct DvrConfig { + DvrType type; + uint32_t bufferSize; + DvrSettings settings; + string playbackInputFile; +}; + struct LiveBroadcastHardwareConnections { string frontendId; + string dvrSoftwareFeId; /* string audioFilterId; string videoFilterId; list string of extra filters; */ @@ -81,9 +89,20 @@ struct ScanHardwareConnections { string frontendId; }; +struct DvrPlaybackHardwareConnections { + bool support; + string frontendId; + string dvrId; + /* string audioFilterId; + string videoFilterId; + list string of extra filters; */ +}; + struct DvrRecordHardwareConnections { bool support; string frontendId; + string dvrRecordId; + string dvrSoftwareFeId; /* string recordFilterId; string dvrId; */ }; @@ -91,6 +110,7 @@ struct DvrRecordHardwareConnections { struct DescramblingHardwareConnections { bool support; string frontendId; + string dvrSoftwareFeId; /* string descramblerId; string audioFilterId; string videoFilterId; @@ -196,9 +216,41 @@ struct TunerTestingConfigReader { } } + static void readDvrConfig1_0(map& dvrMap) { + auto hardwareConfig = getHardwareConfig(); + if (hardwareConfig.hasDvrs()) { + auto dvrs = *hardwareConfig.getFirstDvrs(); + for (auto dvrConfig : dvrs.getDvr()) { + string id = dvrConfig.getId(); + DvrType type; + switch (dvrConfig.getType()) { + case DvrTypeEnum::PLAYBACK: + type = DvrType::PLAYBACK; + dvrMap[id].settings.playback(readPlaybackSettings(dvrConfig)); + break; + case DvrTypeEnum::RECORD: + type = DvrType::RECORD; + dvrMap[id].settings.record(readRecordSettings(dvrConfig)); + break; + case DvrTypeEnum::UNKNOWN: + ALOGW("[ConfigReader] invalid DVR type"); + return; + } + dvrMap[id].type = type; + dvrMap[id].bufferSize = static_cast(dvrConfig.getBufferSize()); + if (dvrConfig.hasInputFilePath()) { + dvrMap[id].playbackInputFile = dvrConfig.getInputFilePath(); + } + } + } + } + static void connectLiveBroadcast(LiveBroadcastHardwareConnections& live) { auto liveConfig = getDataFlowConfiguration().getFirstClearLiveBroadcast(); live.frontendId = liveConfig->getFrontendConnection(); + if (liveConfig->hasDvrSoftwareFeConnection()) { + live.dvrSoftwareFeId = liveConfig->getDvrSoftwareFeConnection(); + } } static void connectScan(ScanHardwareConnections& scan) { @@ -206,6 +258,16 @@ struct TunerTestingConfigReader { scan.frontendId = scanConfig->getFrontendConnection(); } + static void connectDvrPlayback(DvrPlaybackHardwareConnections& playback) { + auto dataFlow = getDataFlowConfiguration(); + if (!dataFlow.hasDvrPlayback()) { + playback.support = false; + return; + } + auto playbackConfig = dataFlow.getFirstDvrPlayback(); + playback.dvrId = playbackConfig->getDvrConnection(); + } + static void connectDvrRecord(DvrRecordHardwareConnections& record) { auto dataFlow = getDataFlowConfiguration(); if (!dataFlow.hasDvrRecord()) { @@ -214,6 +276,10 @@ struct TunerTestingConfigReader { } auto recordConfig = dataFlow.getFirstDvrRecord(); record.frontendId = recordConfig->getFrontendConnection(); + record.dvrRecordId = recordConfig->getDvrRecordConnection(); + if (recordConfig->hasDvrSoftwareFeConnection()) { + record.dvrSoftwareFeId = recordConfig->getDvrSoftwareFeConnection(); + } } static void connectDescrambling(DescramblingHardwareConnections& descrambling) { @@ -224,6 +290,9 @@ struct TunerTestingConfigReader { } auto descConfig = dataFlow.getFirstDescrambling(); descrambling.frontendId = descConfig->getFrontendConnection(); + if (descConfig->hasDvrSoftwareFeConnection()) { + descrambling.dvrSoftwareFeId = descConfig->getDvrSoftwareFeConnection(); + } } static void connectLnbLive(LnbLiveHardwareConnections& lnbLive) { @@ -248,7 +317,7 @@ struct TunerTestingConfigReader { private: static FrontendDvbtSettings readDvbtFrontendSettings(Frontend feConfig) { - ALOGW("[ConfigReader] type is dvbt"); + ALOGW("[ConfigReader] fe type is dvbt"); FrontendDvbtSettings dvbtSettings{ .frequency = (uint32_t)feConfig.getFrequency(), }; @@ -266,7 +335,7 @@ struct TunerTestingConfigReader { } static FrontendDvbsSettings readDvbsFrontendSettings(Frontend feConfig) { - ALOGW("[ConfigReader] type is dvbs"); + ALOGW("[ConfigReader] fe type is dvbs"); FrontendDvbsSettings dvbsSettings{ .frequency = (uint32_t)feConfig.getFrequency(), }; @@ -281,6 +350,30 @@ struct TunerTestingConfigReader { return dvbsSettings; } + static PlaybackSettings readPlaybackSettings(Dvr dvrConfig) { + ALOGW("[ConfigReader] dvr type is playback"); + PlaybackSettings playbackSettings{ + .statusMask = static_cast(dvrConfig.getStatusMask()), + .lowThreshold = static_cast(dvrConfig.getLowThreshold()), + .highThreshold = static_cast(dvrConfig.getHighThreshold()), + .dataFormat = static_cast(dvrConfig.getDataFormat()), + .packetSize = static_cast(dvrConfig.getPacketSize()), + }; + return playbackSettings; + } + + static RecordSettings readRecordSettings(Dvr dvrConfig) { + ALOGW("[ConfigReader] dvr type is record"); + RecordSettings recordSettings{ + .statusMask = static_cast(dvrConfig.getStatusMask()), + .lowThreshold = static_cast(dvrConfig.getLowThreshold()), + .highThreshold = static_cast(dvrConfig.getHighThreshold()), + .dataFormat = static_cast(dvrConfig.getDataFormat()), + .packetSize = static_cast(dvrConfig.getPacketSize()), + }; + return recordSettings; + } + static TunerConfiguration getTunerConfig() { return *read(configFilePath.c_str()); } static HardwareConfiguration getHardwareConfig() { diff --git a/tv/tuner/config/api/current.txt b/tv/tuner/config/api/current.txt index b0f410d25e..1ebd8e1494 100644 --- a/tv/tuner/config/api/current.txt +++ b/tv/tuner/config/api/current.txt @@ -5,12 +5,14 @@ package android.media.tuner.testing.configuration.V1_0 { ctor public DataFlowConfiguration(); method @Nullable public android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.ClearLiveBroadcast getClearLiveBroadcast(); method @Nullable public android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.Descrambling getDescrambling(); + method @Nullable public android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.DvrPlayback getDvrPlayback(); method @Nullable public android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.DvrRecord getDvrRecord(); method @Nullable public android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.LnbLive getLnbLive(); method @Nullable public android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.LnbRecord getLnbRecord(); method @Nullable public android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.Scan getScan(); method public void setClearLiveBroadcast(@Nullable android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.ClearLiveBroadcast); method public void setDescrambling(@Nullable android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.Descrambling); + method public void setDvrPlayback(@Nullable android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.DvrPlayback); method public void setDvrRecord(@Nullable android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.DvrRecord); method public void setLnbLive(@Nullable android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.LnbLive); method public void setLnbRecord(@Nullable android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.LnbRecord); @@ -19,19 +21,33 @@ package android.media.tuner.testing.configuration.V1_0 { public static class DataFlowConfiguration.ClearLiveBroadcast { ctor public DataFlowConfiguration.ClearLiveBroadcast(); + method @Nullable public String getDvrSoftwareFeConnection(); method @Nullable public String getFrontendConnection(); + method public void setDvrSoftwareFeConnection(@Nullable String); method public void setFrontendConnection(@Nullable String); } public static class DataFlowConfiguration.Descrambling { ctor public DataFlowConfiguration.Descrambling(); + method @Nullable public String getDvrSoftwareFeConnection(); method @Nullable public String getFrontendConnection(); + method public void setDvrSoftwareFeConnection(@Nullable String); method public void setFrontendConnection(@Nullable String); } + public static class DataFlowConfiguration.DvrPlayback { + ctor public DataFlowConfiguration.DvrPlayback(); + method @Nullable public String getDvrConnection(); + method public void setDvrConnection(@Nullable String); + } + public static class DataFlowConfiguration.DvrRecord { ctor public DataFlowConfiguration.DvrRecord(); + method @Nullable public String getDvrRecordConnection(); + method @Nullable public String getDvrSoftwareFeConnection(); method @Nullable public String getFrontendConnection(); + method public void setDvrRecordConnection(@Nullable String); + method public void setDvrSoftwareFeConnection(@Nullable String); method public void setFrontendConnection(@Nullable String); } @@ -43,7 +59,9 @@ package android.media.tuner.testing.configuration.V1_0 { public static class DataFlowConfiguration.LnbRecord { ctor public DataFlowConfiguration.LnbRecord(); + method @Nullable public String getDvrRecordConnection(); method @Nullable public String getFrontendConnection(); + method public void setDvrRecordConnection(@Nullable String); method public void setFrontendConnection(@Nullable String); } @@ -71,6 +89,50 @@ package android.media.tuner.testing.configuration.V1_0 { method public void setTransmissionMode(@Nullable java.math.BigInteger); } + public class Dvr { + ctor public Dvr(); + method @Nullable public java.math.BigInteger getBufferSize(); + method @Nullable public android.media.tuner.testing.configuration.V1_0.DvrDataFormatEnum getDataFormat(); + method @Nullable public java.math.BigInteger getHighThreshold(); + method @Nullable public String getId(); + method @Nullable public String getInputFilePath(); + method @Nullable public java.math.BigInteger getLowThreshold(); + method @Nullable public java.math.BigInteger getPacketSize(); + method @Nullable public java.math.BigInteger getStatusMask(); + method @Nullable public android.media.tuner.testing.configuration.V1_0.DvrTypeEnum getType(); + method public void setBufferSize(@Nullable java.math.BigInteger); + method public void setDataFormat(@Nullable android.media.tuner.testing.configuration.V1_0.DvrDataFormatEnum); + method public void setHighThreshold(@Nullable java.math.BigInteger); + method public void setId(@Nullable String); + method public void setInputFilePath(@Nullable String); + method public void setLowThreshold(@Nullable java.math.BigInteger); + method public void setPacketSize(@Nullable java.math.BigInteger); + method public void setStatusMask(@Nullable java.math.BigInteger); + method public void setType(@Nullable android.media.tuner.testing.configuration.V1_0.DvrTypeEnum); + } + + public enum DvrDataFormatEnum { + method @NonNull public String getRawName(); + enum_constant public static final android.media.tuner.testing.configuration.V1_0.DvrDataFormatEnum ES; + enum_constant public static final android.media.tuner.testing.configuration.V1_0.DvrDataFormatEnum PES; + enum_constant public static final android.media.tuner.testing.configuration.V1_0.DvrDataFormatEnum SHV_TLV; + enum_constant public static final android.media.tuner.testing.configuration.V1_0.DvrDataFormatEnum TS; + } + + public enum DvrStatusEnum { + method @NonNull public String getRawName(); + enum_constant public static final android.media.tuner.testing.configuration.V1_0.DvrStatusEnum DATA_READY; + enum_constant public static final android.media.tuner.testing.configuration.V1_0.DvrStatusEnum HIGH_WATER; + enum_constant public static final android.media.tuner.testing.configuration.V1_0.DvrStatusEnum LOW_WATER; + enum_constant public static final android.media.tuner.testing.configuration.V1_0.DvrStatusEnum OVERFLOW; + } + + public enum DvrTypeEnum { + method @NonNull public String getRawName(); + enum_constant public static final android.media.tuner.testing.configuration.V1_0.DvrTypeEnum PLAYBACK; + enum_constant public static final android.media.tuner.testing.configuration.V1_0.DvrTypeEnum RECORD; + } + public class Frontend { ctor public Frontend(); method @Nullable public java.math.BigInteger getConnectToCicamId(); @@ -108,10 +170,17 @@ package android.media.tuner.testing.configuration.V1_0 { public class HardwareConfiguration { ctor public HardwareConfiguration(); + method @Nullable public android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.Dvrs getDvrs(); method @Nullable public android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.Frontends getFrontends(); + method public void setDvrs(@Nullable android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.Dvrs); method public void setFrontends(@Nullable android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.Frontends); } + public static class HardwareConfiguration.Dvrs { + ctor public HardwareConfiguration.Dvrs(); + method @Nullable public java.util.List getDvr(); + } + public static class HardwareConfiguration.Frontends { ctor public HardwareConfiguration.Frontends(); method @Nullable public java.util.List getFrontend(); diff --git a/tv/tuner/config/sample_tuner_vts_config.xml b/tv/tuner/config/sample_tuner_vts_config.xml index c4080d9ac7..001e04574e 100644 --- a/tv/tuner/config/sample_tuner_vts_config.xml +++ b/tv/tuner/config/sample_tuner_vts_config.xml @@ -60,16 +60,49 @@ connectToCicamId="0" frequency="578000" endFrequency="800000"> + + + + + + - + - - + + - + diff --git a/tv/tuner/config/tuner_testing_dynamic_configuration.xsd b/tv/tuner/config/tuner_testing_dynamic_configuration.xsd index cd8b061309..45d25e5999 100644 --- a/tv/tuner/config/tuner_testing_dynamic_configuration.xsd +++ b/tv/tuner/config/tuner_testing_dynamic_configuration.xsd @@ -99,14 +99,80 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Each dvr element contain the following attributes: + "id": unique id of the dvr that could be used to connect to the test the + "dataFlowConfiguration" + "type": the dvr type. + "bufferSize": the dvr buffer size. + "statusMask": register callbacks of specific status. + "lowThreshold": the dvr status low threshold. + "highThreshold": the dvr status high threshold. + "dataFormat": the dvr data format. + "packetSize": the dvr packet size. + "inputFilePath": the dvr playback input file path. Only required in playback + dvr. + + + + + + + + + + + + + @@ -131,6 +197,23 @@ + + + + + This section contains configurations of all the dvrs that would be used + in the tests. + - This section is optional and can be skipped if the device does + not support dvr. + - The users can configure 1 or more dvr elements in the dvrs + sections. + + + + + + + @@ -139,8 +222,9 @@ - + + @@ -151,11 +235,21 @@ + + + + + + + + + + @@ -166,6 +260,7 @@ + -- GitLab From 12495d2ddd2ca8c56bfe672d22dd1310e8ab200f Mon Sep 17 00:00:00 2001 From: Wei Wang Date: Tue, 6 Apr 2021 19:43:00 -0700 Subject: [PATCH 586/790] power: refine comment for pause/resume session Bug: 163794808 Test: Build Change-Id: I37d15e0b0ae6646b89b63efde3731368181a01d4 --- power/aidl/android/hardware/power/IPowerHintSession.aidl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/power/aidl/android/hardware/power/IPowerHintSession.aidl b/power/aidl/android/hardware/power/IPowerHintSession.aidl index 9a85bee997..c289448855 100644 --- a/power/aidl/android/hardware/power/IPowerHintSession.aidl +++ b/power/aidl/android/hardware/power/IPowerHintSession.aidl @@ -43,17 +43,17 @@ oneway interface IPowerHintSession { void reportActualWorkDuration(in WorkDuration[] durations); /** - * Pause the session when the application is not in foreground and above + * Pause the session when the application is not allowed to send hint in framework. */ void pause(); /** - * Resume the session when the application is not in foreground and above + * Resume the session when the application is allowed to send hint in framework. */ void resume(); /** - * Close the session to release resources + * Close the session to release resources. */ void close(); } -- GitLab From e3eea4f93280d5cfd4042f04f0412d0691c29314 Mon Sep 17 00:00:00 2001 From: Yuncheol Heo Date: Thu, 1 Apr 2021 22:44:13 -0700 Subject: [PATCH 587/790] Redirect the Cluster VHAL messages to vendor ones, or vice versa. - We'll reroute the Cluster VHAL messages to vendor ones, so that our ClusetrOSDobule can receive them through the vendor properties. Bug: 181802283 Test: check if ClusterOSDouble gets the vendor messages. Change-Id: Iee71e7453bec6a633b94aa7f56e8ceec5fc7b9bd --- automotive/vehicle/2.0/default/Android.bp | 1 + .../default/impl/vhal_v2_0/DefaultConfig.h | 66 +++++++++++++++++++ .../impl/vhal_v2_0/VehicleHalServer.cpp | 22 +++++++ 3 files changed, 89 insertions(+) diff --git a/automotive/vehicle/2.0/default/Android.bp b/automotive/vehicle/2.0/default/Android.bp index b2f8bf630a..d6f3120221 100644 --- a/automotive/vehicle/2.0/default/Android.bp +++ b/automotive/vehicle/2.0/default/Android.bp @@ -210,6 +210,7 @@ cc_binary { vendor: true, relative_install_path: "hw", srcs: ["VehicleService.cpp"], + cflags: ["-DENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING"], shared_libs: [ "libbase", "libjsoncpp", diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h index 19b0a35e8d..85d14481e3 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h @@ -115,6 +115,28 @@ const int32_t kSetBooleanPropertyFromVehicleForTest = */ const int32_t kMixedTypePropertyForTest = 0x1111 | VehiclePropertyGroup::VENDOR | VehicleArea::GLOBAL | VehiclePropertyType::MIXED; + +#ifdef ENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING +/** + * Converts the system property to the vendor property. + * WARNING: This is only for the end-to-end testing, Should NOT include in the + * user build */ +inline constexpr int32_t toVendor(VehicleProperty prop) { + return (toInt(prop) & ~toInt(VehiclePropertyGroup::MASK)) | VehiclePropertyGroup::VENDOR; +} + +/** + * These properties are used for the end-to-end testing of ClusterHomeService. + */ +constexpr int32_t VENDOR_CLUSTER_SWITCH_UI = toVendor(VehicleProperty::CLUSTER_SWITCH_UI); +constexpr int32_t VENDOR_CLUSTER_DISPLAY_STATE = toVendor(VehicleProperty::CLUSTER_DISPLAY_STATE); +constexpr int32_t VENDOR_CLUSTER_REPORT_STATE = toVendor(VehicleProperty::CLUSTER_REPORT_STATE); +constexpr int32_t VENDOR_CLUSTER_REQUEST_DISPLAY = + toVendor(VehicleProperty::CLUSTER_REQUEST_DISPLAY); +constexpr int32_t VENDOR_CLUSTER_NAVIGATION_STATE = + toVendor(VehicleProperty::CLUSTER_NAVIGATION_STATE); +#endif // ENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING + /** * FakeDataCommand enum defines the supported command type for kGenerateFakeDataControllingProperty. * All those commands can be send independently with each other. And each will override the one sent @@ -1227,6 +1249,50 @@ const ConfigDeclaration kVehicleProperties[]{ .changeMode = VehiclePropertyChangeMode::ON_CHANGE, }, }, +#ifdef ENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING + // Vendor propetry for E2E ClusterHomeService testing. + { + .config = + { + .prop = VENDOR_CLUSTER_SWITCH_UI, + .access = VehiclePropertyAccess::WRITE, + .changeMode = VehiclePropertyChangeMode::ON_CHANGE, + }, + }, + { + .config = + { + .prop = VENDOR_CLUSTER_DISPLAY_STATE, + .access = VehiclePropertyAccess::WRITE, + .changeMode = VehiclePropertyChangeMode::ON_CHANGE, + }, + }, + { + .config = + { + .prop = VENDOR_CLUSTER_REPORT_STATE, + .access = VehiclePropertyAccess::READ, + .changeMode = VehiclePropertyChangeMode::ON_CHANGE, + .configArray = {0, 0, 0, 9, 0, 0, 0, 0, 16}, + }, + }, + { + .config = + { + .prop = VENDOR_CLUSTER_REQUEST_DISPLAY, + .access = VehiclePropertyAccess::READ, + .changeMode = VehiclePropertyChangeMode::ON_CHANGE, + }, + }, + { + .config = + { + .prop = VENDOR_CLUSTER_NAVIGATION_STATE, + .access = VehiclePropertyAccess::READ, + .changeMode = VehiclePropertyChangeMode::ON_CHANGE, + }, + }, +#endif // ENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING }; } // impl diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.cpp index 0ee183596a..6b870527c3 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.cpp +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.cpp @@ -247,6 +247,28 @@ StatusCode VehicleHalServer::onSetProperty(const VehiclePropValue& value, bool u break; } break; + +#ifdef ENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING + case toInt(VehicleProperty::CLUSTER_REPORT_STATE): + case toInt(VehicleProperty::CLUSTER_REQUEST_DISPLAY): + case toInt(VehicleProperty::CLUSTER_NAVIGATION_STATE): + case VENDOR_CLUSTER_SWITCH_UI: + case VENDOR_CLUSTER_DISPLAY_STATE: { + auto updatedPropValue = createVehiclePropValue(getPropType(value.prop), 0); + updatedPropValue->prop = value.prop & ~toInt(VehiclePropertyGroup::MASK); + if (isSystemProperty(value.prop)) { + updatedPropValue->prop |= toInt(VehiclePropertyGroup::VENDOR); + } else { + updatedPropValue->prop |= toInt(VehiclePropertyGroup::SYSTEM); + } + updatedPropValue->value = value.value; + updatedPropValue->timestamp = elapsedRealtimeNano(); + updatedPropValue->areaId = value.areaId; + onPropertyValueFromCar(*updatedPropValue, updateStatus); + return StatusCode::OK; + } +#endif // ENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING + default: break; } -- GitLab From 2ea2fe2e5b1c7eb601d69ec411d77a8ef3e0adfc Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Thu, 1 Apr 2021 11:55:41 -0700 Subject: [PATCH 588/790] Add filter dynamic configuration into Tuner 1.0 VTS Test: atest VtsHalTvTunerV1_0TargetTest Bug: 182519645 CTS-Coverage-Bug: 184077478 Change-Id: I26da0561b79ae741d1516bedda8c273fa0ed933b --- .../VtsHalTvTunerV1_0TargetTest.cpp | 55 ++-- .../functional/VtsHalTvTunerV1_0TargetTest.h | 2 +- .../VtsHalTvTunerV1_0TestConfigurations.h | 159 +++------ tv/tuner/config/TunerTestingConfigReader.h | 304 +++++++++++++++--- tv/tuner/config/api/current.txt | 107 ++++++ tv/tuner/config/sample_tuner_vts_config.xml | 65 +++- .../tuner_testing_dynamic_configuration.xsd | 154 ++++++++- 7 files changed, 668 insertions(+), 178 deletions(-) diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp index 5fbdd2df0c..491318e5c1 100644 --- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp +++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp @@ -394,6 +394,9 @@ TEST_P(TunerDemuxHidlTest, openDemux) { TEST_P(TunerDemuxHidlTest, getAvSyncTime) { description("Get the A/V sync time from a PCR filter."); + if (live.pcrFilterId.compare(emptyHardwareId) == 0) { + return; + } uint32_t feId; uint32_t demuxId; sp demux; @@ -409,15 +412,15 @@ TEST_P(TunerDemuxHidlTest, getAvSyncTime) { ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); mFilterTests.setDemux(demux); - ASSERT_TRUE(mFilterTests.openFilterInDemux(filterArray[TS_VIDEO1].type, - filterArray[TS_VIDEO1].bufferSize)); + ASSERT_TRUE(mFilterTests.openFilterInDemux(filterMap[live.videoFilterId].type, + filterMap[live.videoFilterId].bufferSize)); ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(mediaFilterId)); - ASSERT_TRUE(mFilterTests.configFilter(filterArray[TS_VIDEO1].settings, mediaFilterId)); + ASSERT_TRUE(mFilterTests.configFilter(filterMap[live.videoFilterId].settings, mediaFilterId)); mediaFilter = mFilterTests.getFilterById(mediaFilterId); - ASSERT_TRUE(mFilterTests.openFilterInDemux(filterArray[TS_PCR0].type, - filterArray[TS_PCR0].bufferSize)); + ASSERT_TRUE(mFilterTests.openFilterInDemux(filterMap[live.pcrFilterId].type, + filterMap[live.pcrFilterId].bufferSize)); ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(pcrFilterId)); - ASSERT_TRUE(mFilterTests.configFilter(filterArray[TS_PCR0].settings, pcrFilterId)); + ASSERT_TRUE(mFilterTests.configFilter(filterMap[live.pcrFilterId].settings, pcrFilterId)); ASSERT_TRUE(mDemuxTests.getAvSyncId(mediaFilter, avSyncHwId)); ASSERT_TRUE(pcrFilterId == avSyncHwId); ASSERT_TRUE(mDemuxTests.getAvSyncTime(pcrFilterId)); @@ -430,7 +433,7 @@ TEST_P(TunerDemuxHidlTest, getAvSyncTime) { TEST_P(TunerFilterHidlTest, StartFilterInDemux) { description("Open and start a filter in Demux."); // TODO use paramterized tests - configSingleFilterInDemuxTest(filterArray[TS_VIDEO0], frontendMap[live.frontendId]); + configSingleFilterInDemuxTest(filterMap[live.videoFilterId], frontendMap[live.frontendId]); } TEST_P(TunerFilterHidlTest, SetFilterLinkage) { @@ -471,35 +474,42 @@ TEST_P(TunerFilterHidlTest, testTimeFilter) { TEST_P(TunerBroadcastHidlTest, BroadcastDataFlowVideoFilterTest) { description("Test Video Filter functionality in Broadcast use case."); - broadcastSingleFilterTest(filterArray[TS_VIDEO1], frontendMap[live.frontendId]); + broadcastSingleFilterTest(filterMap[live.videoFilterId], frontendMap[live.frontendId]); } TEST_P(TunerBroadcastHidlTest, BroadcastDataFlowAudioFilterTest) { description("Test Audio Filter functionality in Broadcast use case."); - broadcastSingleFilterTest(filterArray[TS_AUDIO0], frontendMap[live.frontendId]); + broadcastSingleFilterTest(filterMap[live.audioFilterId], frontendMap[live.frontendId]); } TEST_P(TunerBroadcastHidlTest, BroadcastDataFlowSectionFilterTest) { description("Test Section Filter functionality in Broadcast use case."); - broadcastSingleFilterTest(filterArray[TS_SECTION0], frontendMap[live.frontendId]); + if (live.sectionFilterId.compare(emptyHardwareId) == 0) { + return; + } + broadcastSingleFilterTest(filterMap[live.sectionFilterId], frontendMap[live.frontendId]); } TEST_P(TunerBroadcastHidlTest, IonBufferTest) { description("Test the av filter data bufferring."); - broadcastSingleFilterTest(filterArray[TS_VIDEO0], frontendMap[live.frontendId]); + broadcastSingleFilterTest(filterMap[live.videoFilterId], frontendMap[live.frontendId]); } TEST_P(TunerBroadcastHidlTest, LnbBroadcastDataFlowVideoFilterTest) { description("Test Video Filter functionality in Broadcast with Lnb use case."); - broadcastSingleFilterTest(filterArray[TS_VIDEO0], frontendMap[live.frontendId]); + if (!lnbLive.support) { + return; + } + broadcastSingleFilterTestWithLnb(filterMap[lnbLive.videoFilterId], + frontendMap[lnbLive.frontendId], lnbArray[LNB0]); } TEST_P(TunerPlaybackHidlTest, PlaybackDataFlowWithTsSectionFilterTest) { description("Feed ts data from playback and configure Ts section filter to get output"); - if (!playback.support) { + if (!playback.support || playback.sectionFilterId.compare(emptyHardwareId) == 0) { return; } - playbackSingleFilterTest(filterArray[TS_SECTION0], dvrMap[playback.dvrId]); + playbackSingleFilterTest(filterMap[playback.sectionFilterId], dvrMap[playback.dvrId]); } TEST_P(TunerRecordHidlTest, AttachFiltersToRecordTest) { @@ -508,8 +518,8 @@ TEST_P(TunerRecordHidlTest, AttachFiltersToRecordTest) { if (!record.support) { return; } - attachSingleFilterToRecordDvrTest(filterArray[TS_RECORD0], frontendMap[record.frontendId], - dvrMap[record.dvrRecordId]); + attachSingleFilterToRecordDvrTest(filterMap[record.recordFilterId], + frontendMap[record.frontendId], dvrMap[record.dvrRecordId]); } TEST_P(TunerRecordHidlTest, RecordDataFlowWithTsRecordFilterTest) { @@ -517,17 +527,18 @@ TEST_P(TunerRecordHidlTest, RecordDataFlowWithTsRecordFilterTest) { if (!record.support) { return; } - recordSingleFilterTest(filterArray[TS_RECORD0], frontendMap[record.frontendId], + recordSingleFilterTest(filterMap[record.recordFilterId], frontendMap[record.frontendId], dvrMap[record.dvrRecordId]); } TEST_P(TunerRecordHidlTest, LnbRecordDataFlowWithTsRecordFilterTest) { description("Feed ts data from Fe with Lnb to recording and test with ts record filter"); - if (record.support) { + if (lnbRecord.support) { return; } - recordSingleFilterTestWithLnb(filterArray[TS_RECORD0], frontendMap[lnbRecord.frontendId], - dvrMap[record.dvrRecordId], lnbArray[LNB0]); + recordSingleFilterTestWithLnb(filterMap[lnbRecord.recordFilterId], + frontendMap[lnbRecord.frontendId], dvrMap[lnbRecord.dvrRecordId], + lnbArray[LNB0]); } TEST_P(TunerDescramblerHidlTest, CreateDescrambler) { @@ -556,8 +567,8 @@ TEST_P(TunerDescramblerHidlTest, ScrambledBroadcastDataFlowMediaFiltersTest) { return; } set filterConfs; - filterConfs.insert(filterArray[TS_AUDIO0]); - filterConfs.insert(filterArray[TS_VIDEO1]); + filterConfs.insert(static_cast(filterMap[descrambling.audioFilterId])); + filterConfs.insert(static_cast(filterMap[descrambling.videoFilterId])); scrambledBroadcastTest(filterConfs, frontendMap[descrambling.frontendId], descramblerArray[DESC_0]); } diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h index 9723c2d645..07ce201746 100644 --- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h +++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h @@ -33,6 +33,7 @@ bool initConfiguration() { return false; } initFrontendConfig(); + initFilterConfig(); initDvrConfig(); connectHardwaresToTestCases(); if (!validateConnections()) { @@ -41,7 +42,6 @@ bool initConfiguration() { } initLnbConfig(); - initFilterConfig(); initTimeFilterConfig(); initDescramblerConfig(); diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h index a1c5cd9aa2..8537fe8410 100644 --- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h +++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h @@ -79,19 +79,6 @@ const uint32_t FMQ_SIZE_16M = 0x1000000; " \"track_types\": [ ] " \ "} " -typedef enum { - TS_VIDEO0, - TS_VIDEO1, - TS_AUDIO0, - TS_AUDIO1, - TS_PES0, - TS_PCR0, - TS_SECTION0, - TS_TS0, - TS_RECORD0, - FILTER_MAX, -} Filter; - typedef enum { TIMER0, TIMER_MAX, @@ -119,15 +106,6 @@ typedef enum { DESC_MAX, } Descrambler; -struct FilterConfig { - uint32_t bufferSize; - DemuxFilterType type; - DemuxFilterSettings settings; - bool getMqDesc; - - bool operator<(const FilterConfig& /*c*/) const { return false; } -}; - struct TimeFilterConfig { bool supportTimeFilter; uint64_t timeStamp; @@ -150,13 +128,13 @@ struct DescramblerConfig { // TODO: remove all the manual config array after the dynamic config refactoring is done. static LnbConfig lnbArray[LNB_MAX]; static vector diseqcMsgArray[DISEQC_MAX]; -static FilterConfig filterArray[FILTER_MAX]; static TimeFilterConfig timeFilterArray[TIMER_MAX]; static DemuxFilterType filterLinkageTypes[LINKAGE_DIR][FILTER_MAIN_TYPE_BIT_COUNT]; static DescramblerConfig descramblerArray[DESC_MAX]; // Hardware configs static map frontendMap; +static map filterMap; static map dvrMap; // Hardware and test cases connections @@ -196,6 +174,28 @@ inline void initFrontendConfig() { TunerTestingConfigReader::readFrontendConfig1_0(frontendMap); }; +inline void initFilterConfig() { + // The test will use the internal default filter when default filter is connected to any + // data flow without overriding in the xml config. + string defaultAudioFilterId = "FILTER_AUDIO_DEFAULT"; + string defaultVideoFilterId = "FILTER_VIDEO_DEFAULT"; + + filterMap[defaultVideoFilterId].type.mainType = DemuxFilterMainType::TS; + filterMap[defaultVideoFilterId].type.subType.tsFilterType(DemuxTsFilterType::VIDEO); + filterMap[defaultVideoFilterId].bufferSize = FMQ_SIZE_16M; + filterMap[defaultVideoFilterId].settings.ts().tpid = 256; + filterMap[defaultVideoFilterId].settings.ts().filterSettings.av({.isPassthrough = false}); + + filterMap[defaultAudioFilterId].type.mainType = DemuxFilterMainType::TS; + filterMap[defaultAudioFilterId].type.subType.tsFilterType(DemuxTsFilterType::AUDIO); + filterMap[defaultAudioFilterId].bufferSize = FMQ_SIZE_16M; + filterMap[defaultAudioFilterId].settings.ts().tpid = 256; + filterMap[defaultAudioFilterId].settings.ts().filterSettings.av({.isPassthrough = false}); + + // Read customized config + TunerTestingConfigReader::readFilterConfig1_0(filterMap); +}; + /** Config all the dvrs that would be used in the tests */ inline void initDvrConfig() { // Read customized config @@ -250,6 +250,34 @@ inline bool validateConnections() { return false; } + bool filterIsValid = filterMap.find(live.audioFilterId) != filterMap.end() && + filterMap.find(live.videoFilterId) != filterMap.end(); + + filterIsValid &= playback.support + ? (filterMap.find(playback.audioFilterId) != filterMap.end() && + filterMap.find(playback.videoFilterId) != filterMap.end()) + : true; + + filterIsValid &= + record.support ? filterMap.find(record.recordFilterId) != filterMap.end() : true; + + filterIsValid &= descrambling.support + ? (filterMap.find(descrambling.audioFilterId) != filterMap.end() && + filterMap.find(descrambling.videoFilterId) != filterMap.end()) + : true; + + filterIsValid &= lnbLive.support ? (filterMap.find(lnbLive.audioFilterId) != filterMap.end() && + filterMap.find(lnbLive.videoFilterId) != filterMap.end()) + : true; + + filterIsValid &= + lnbRecord.support ? filterMap.find(lnbRecord.recordFilterId) != filterMap.end() : true; + + if (!filterIsValid) { + ALOGW("[vts config] dynamic config filter connection is invalid."); + return false; + } + return true; } @@ -272,91 +300,6 @@ inline void initDiseqcMsg() { diseqcMsgArray[DISEQC_POWER_ON] = {0xE, 0x0, 0x0, 0x0, 0x0, 0x3}; }; -/** Configuration array for the filter test */ -inline void initFilterConfig() { - // TS VIDEO filter setting for default implementation testing - filterArray[TS_VIDEO0].type.mainType = DemuxFilterMainType::TS; - filterArray[TS_VIDEO0].type.subType.tsFilterType(DemuxTsFilterType::VIDEO); - filterArray[TS_VIDEO0].bufferSize = FMQ_SIZE_16M; - filterArray[TS_VIDEO0].settings.ts().tpid = 256; - filterArray[TS_VIDEO0].settings.ts().filterSettings.av({.isPassthrough = false}); - filterArray[TS_VIDEO1].type.mainType = DemuxFilterMainType::TS; - filterArray[TS_VIDEO1].type.subType.tsFilterType(DemuxTsFilterType::VIDEO); - filterArray[TS_VIDEO1].bufferSize = FMQ_SIZE_16M; - filterArray[TS_VIDEO1].settings.ts().tpid = 256; - filterArray[TS_VIDEO1].settings.ts().filterSettings.av({.isPassthrough = false}); - // TS AUDIO filter setting - filterArray[TS_AUDIO0].type.mainType = DemuxFilterMainType::TS; - filterArray[TS_AUDIO0].type.subType.tsFilterType(DemuxTsFilterType::AUDIO); - filterArray[TS_AUDIO0].bufferSize = FMQ_SIZE_16M; - filterArray[TS_AUDIO0].settings.ts().tpid = 256; - filterArray[TS_AUDIO0].settings.ts().filterSettings.av({.isPassthrough = false}); - filterArray[TS_AUDIO1].type.mainType = DemuxFilterMainType::TS; - filterArray[TS_AUDIO1].type.subType.tsFilterType(DemuxTsFilterType::AUDIO); - filterArray[TS_AUDIO1].bufferSize = FMQ_SIZE_16M; - filterArray[TS_AUDIO1].settings.ts().tpid = 257; - filterArray[TS_AUDIO1].settings.ts().filterSettings.av({.isPassthrough = false}); - // TS PES filter setting - filterArray[TS_PES0].type.mainType = DemuxFilterMainType::TS; - filterArray[TS_PES0].type.subType.tsFilterType(DemuxTsFilterType::PES); - filterArray[TS_PES0].bufferSize = FMQ_SIZE_16M; - filterArray[TS_PES0].settings.ts().tpid = 256; - filterArray[TS_PES0].settings.ts().filterSettings.pesData({ - .isRaw = false, - .streamId = 0xbd, - }); - filterArray[TS_PES0].getMqDesc = true; - // TS PCR filter setting - filterArray[TS_PCR0].type.mainType = DemuxFilterMainType::TS; - filterArray[TS_PCR0].type.subType.tsFilterType(DemuxTsFilterType::PCR); - filterArray[TS_PCR0].bufferSize = FMQ_SIZE_16M; - filterArray[TS_PCR0].settings.ts().tpid = 256; - filterArray[TS_PCR0].settings.ts().filterSettings.noinit(); - // TS filter setting - filterArray[TS_TS0].type.mainType = DemuxFilterMainType::TS; - filterArray[TS_TS0].type.subType.tsFilterType(DemuxTsFilterType::TS); - filterArray[TS_TS0].bufferSize = FMQ_SIZE_16M; - filterArray[TS_TS0].settings.ts().tpid = 256; - filterArray[TS_TS0].settings.ts().filterSettings.noinit(); - // TS SECTION filter setting - filterArray[TS_SECTION0].type.mainType = DemuxFilterMainType::TS; - filterArray[TS_SECTION0].type.subType.tsFilterType(DemuxTsFilterType::SECTION); - filterArray[TS_SECTION0].bufferSize = FMQ_SIZE_16M; - filterArray[TS_SECTION0].settings.ts().tpid = 256; - filterArray[TS_SECTION0].settings.ts().filterSettings.section({ - .isRaw = false, - }); - filterArray[TS_SECTION0].getMqDesc = true; - // TS RECORD filter setting - filterArray[TS_RECORD0].type.mainType = DemuxFilterMainType::TS; - filterArray[TS_RECORD0].type.subType.tsFilterType(DemuxTsFilterType::RECORD); - filterArray[TS_RECORD0].settings.ts().tpid = 81; - filterArray[TS_RECORD0].settings.ts().filterSettings.record({ - .scIndexType = DemuxRecordScIndexType::NONE, - }); - - // TS Linkage filter setting - filterLinkageTypes[SOURCE][0].mainType = DemuxFilterMainType::TS; - filterLinkageTypes[SOURCE][0].subType.tsFilterType(DemuxTsFilterType::TS); - filterLinkageTypes[SINK][0] = filterLinkageTypes[SOURCE][0]; - // MMTP Linkage filter setting - filterLinkageTypes[SOURCE][1].mainType = DemuxFilterMainType::MMTP; - filterLinkageTypes[SOURCE][1].subType.mmtpFilterType(DemuxMmtpFilterType::AUDIO); - filterLinkageTypes[SINK][1] = filterLinkageTypes[SOURCE][1]; - // IP Linkage filter setting - filterLinkageTypes[SOURCE][2].mainType = DemuxFilterMainType::IP; - filterLinkageTypes[SOURCE][2].subType.ipFilterType(DemuxIpFilterType::IP); - filterLinkageTypes[SINK][2] = filterLinkageTypes[SOURCE][2]; - // TLV Linkage filter setting - filterLinkageTypes[SOURCE][3].mainType = DemuxFilterMainType::TLV; - filterLinkageTypes[SOURCE][3].subType.tlvFilterType(DemuxTlvFilterType::TLV); - filterLinkageTypes[SINK][3] = filterLinkageTypes[SOURCE][3]; - // ALP Linkage PTP filter setting - filterLinkageTypes[SOURCE][4].mainType = DemuxFilterMainType::ALP; - filterLinkageTypes[SOURCE][4].subType.alpFilterType(DemuxAlpFilterType::PTP); - filterLinkageTypes[SINK][4] = filterLinkageTypes[SOURCE][4]; -}; - /** Configuration array for the timer filter test */ inline void initTimeFilterConfig() { timeFilterArray[TIMER0].supportTimeFilter = true; diff --git a/tv/tuner/config/TunerTestingConfigReader.h b/tv/tuner/config/TunerTestingConfigReader.h index aa2b75c1de..9ee509c6c1 100644 --- a/tv/tuner/config/TunerTestingConfigReader.h +++ b/tv/tuner/config/TunerTestingConfigReader.h @@ -29,8 +29,11 @@ using namespace android::media::tuner::testing::configuration::V1_0; using android::hardware::tv::tuner::V1_0::DataFormat; using android::hardware::tv::tuner::V1_0::DemuxAlpFilterType; +using android::hardware::tv::tuner::V1_0::DemuxFilterAvSettings; using android::hardware::tv::tuner::V1_0::DemuxFilterEvent; using android::hardware::tv::tuner::V1_0::DemuxFilterMainType; +using android::hardware::tv::tuner::V1_0::DemuxFilterRecordSettings; +using android::hardware::tv::tuner::V1_0::DemuxFilterSectionSettings; using android::hardware::tv::tuner::V1_0::DemuxFilterSettings; using android::hardware::tv::tuner::V1_0::DemuxFilterType; using android::hardware::tv::tuner::V1_0::DemuxIpFilterType; @@ -61,6 +64,7 @@ using android::hardware::tv::tuner::V1_0::PlaybackSettings; using android::hardware::tv::tuner::V1_0::RecordSettings; const string configFilePath = "/vendor/etc/tuner_vts_config.xml"; +const string emptyHardwareId = ""; struct FrontendConfig { bool isSoftwareFe; @@ -70,6 +74,15 @@ struct FrontendConfig { vector expectTuneStatuses; }; +struct FilterConfig { + uint32_t bufferSize; + DemuxFilterType type; + DemuxFilterSettings settings; + bool getMqDesc; + + bool operator<(const FilterConfig& /*c*/) const { return false; } +}; + struct DvrConfig { DvrType type; uint32_t bufferSize; @@ -80,9 +93,11 @@ struct DvrConfig { struct LiveBroadcastHardwareConnections { string frontendId; string dvrSoftwareFeId; - /* string audioFilterId; + string audioFilterId; string videoFilterId; - list string of extra filters; */ + string sectionFilterId; + string pcrFilterId; + /* list string of extra filters; */ }; struct ScanHardwareConnections { @@ -93,9 +108,10 @@ struct DvrPlaybackHardwareConnections { bool support; string frontendId; string dvrId; - /* string audioFilterId; + string audioFilterId; string videoFilterId; - list string of extra filters; */ + string sectionFilterId; + /* list string of extra filters; */ }; struct DvrRecordHardwareConnections { @@ -103,34 +119,34 @@ struct DvrRecordHardwareConnections { string frontendId; string dvrRecordId; string dvrSoftwareFeId; - /* string recordFilterId; - string dvrId; */ + string recordFilterId; }; struct DescramblingHardwareConnections { bool support; string frontendId; string dvrSoftwareFeId; - /* string descramblerId; string audioFilterId; string videoFilterId; + /* string descramblerId; list string of extra filters; */ }; struct LnbLiveHardwareConnections { bool support; string frontendId; - /* string audioFilterId; + string audioFilterId; string videoFilterId; - list string of extra filters; + /* list string of extra filters; string lnbId; */ }; struct LnbRecordHardwareConnections { bool support; string frontendId; - /* string recordFilterId; - list string of extra filters; + string dvrRecordId; + string recordFilterId; + /* list string of extra filters; string lnbId; */ }; @@ -149,7 +165,7 @@ struct TunerTestingConfigReader { static void readFrontendConfig1_0(map& frontendMap) { auto hardwareConfig = getHardwareConfig(); if (hardwareConfig.hasFrontends()) { - // TODO: complete the tune status config + // TODO: b/182519645 complete the tune status config vector types; types.push_back(FrontendStatusType::DEMOD_LOCK); FrontendStatus status; @@ -169,7 +185,7 @@ struct TunerTestingConfigReader { case FrontendTypeEnum::UNDEFINED: type = FrontendType::UNDEFINED; break; - // TODO: finish all other frontend settings + // TODO: b/182519645 finish all other frontend settings case FrontendTypeEnum::ANALOG: type = FrontendType::ANALOG; break; @@ -209,13 +225,42 @@ struct TunerTestingConfigReader { } frontendMap[id].type = type; frontendMap[id].isSoftwareFe = feConfig.getIsSoftwareFrontend(); - // TODO: complete the tune status config + // TODO: b/182519645 complete the tune status config frontendMap[id].tuneStatusTypes = types; frontendMap[id].expectTuneStatuses = statuses; } } } + static void readFilterConfig1_0(map& filterMap) { + auto hardwareConfig = getHardwareConfig(); + if (hardwareConfig.hasFilters()) { + auto filters = *hardwareConfig.getFirstFilters(); + for (auto filterConfig : filters.getFilter()) { + string id = filterConfig.getId(); + if (id.compare(string("FILTER_AUDIO_DEFAULT")) == 0) { + // overrid default + filterMap.erase(string("FILTER_AUDIO_DEFAULT")); + } + if (id.compare(string("FILTER_VIDEO_DEFAULT")) == 0) { + // overrid default + filterMap.erase(string("FILTER_VIDEO_DEFAULT")); + } + + DemuxFilterType type; + DemuxFilterSettings settings; + if (!readFilterTypeAndSettings(filterConfig, type, settings)) { + ALOGW("[ConfigReader] invalid filter type"); + return; + } + filterMap[id].type = type; + filterMap[id].bufferSize = filterConfig.getBufferSize(); + filterMap[id].getMqDesc = filterConfig.getUseFMQ(); + filterMap[id].settings = settings; + } + } + } + static void readDvrConfig1_0(map& dvrMap) { auto hardwareConfig = getHardwareConfig(); if (hardwareConfig.hasDvrs()) { @@ -246,10 +291,23 @@ struct TunerTestingConfigReader { } static void connectLiveBroadcast(LiveBroadcastHardwareConnections& live) { - auto liveConfig = getDataFlowConfiguration().getFirstClearLiveBroadcast(); - live.frontendId = liveConfig->getFrontendConnection(); - if (liveConfig->hasDvrSoftwareFeConnection()) { - live.dvrSoftwareFeId = liveConfig->getDvrSoftwareFeConnection(); + auto liveConfig = *getDataFlowConfiguration().getFirstClearLiveBroadcast(); + live.frontendId = liveConfig.getFrontendConnection(); + + live.audioFilterId = liveConfig.getAudioFilterConnection(); + live.videoFilterId = liveConfig.getVideoFilterConnection(); + if (liveConfig.hasPcrFilterConnection()) { + live.pcrFilterId = liveConfig.getPcrFilterConnection(); + } else { + live.pcrFilterId = emptyHardwareId; + } + if (liveConfig.hasSectionFilterConnection()) { + live.sectionFilterId = liveConfig.getSectionFilterConnection(); + } else { + live.sectionFilterId = emptyHardwareId; + } + if (liveConfig.hasDvrSoftwareFeConnection()) { + live.dvrSoftwareFeId = liveConfig.getDvrSoftwareFeConnection(); } } @@ -260,59 +318,78 @@ struct TunerTestingConfigReader { static void connectDvrPlayback(DvrPlaybackHardwareConnections& playback) { auto dataFlow = getDataFlowConfiguration(); - if (!dataFlow.hasDvrPlayback()) { - playback.support = false; + if (dataFlow.hasDvrPlayback()) { + playback.support = true; + } else { return; } - auto playbackConfig = dataFlow.getFirstDvrPlayback(); - playback.dvrId = playbackConfig->getDvrConnection(); + auto playbackConfig = *dataFlow.getFirstDvrPlayback(); + playback.dvrId = playbackConfig.getDvrConnection(); + playback.audioFilterId = playbackConfig.getAudioFilterConnection(); + playback.videoFilterId = playbackConfig.getVideoFilterConnection(); + if (playbackConfig.hasSectionFilterConnection()) { + playback.sectionFilterId = playbackConfig.getSectionFilterConnection(); + } else { + playback.sectionFilterId = emptyHardwareId; + } } static void connectDvrRecord(DvrRecordHardwareConnections& record) { auto dataFlow = getDataFlowConfiguration(); - if (!dataFlow.hasDvrRecord()) { - record.support = false; + if (dataFlow.hasDvrRecord()) { + record.support = true; + } else { return; } - auto recordConfig = dataFlow.getFirstDvrRecord(); - record.frontendId = recordConfig->getFrontendConnection(); - record.dvrRecordId = recordConfig->getDvrRecordConnection(); - if (recordConfig->hasDvrSoftwareFeConnection()) { - record.dvrSoftwareFeId = recordConfig->getDvrSoftwareFeConnection(); + auto recordConfig = *dataFlow.getFirstDvrRecord(); + record.frontendId = recordConfig.getFrontendConnection(); + record.recordFilterId = recordConfig.getRecordFilterConnection(); + record.dvrRecordId = recordConfig.getDvrRecordConnection(); + if (recordConfig.hasDvrSoftwareFeConnection()) { + record.dvrSoftwareFeId = recordConfig.getDvrSoftwareFeConnection(); } } static void connectDescrambling(DescramblingHardwareConnections& descrambling) { auto dataFlow = getDataFlowConfiguration(); - if (!dataFlow.hasDescrambling()) { - descrambling.support = false; + if (dataFlow.hasDescrambling()) { + descrambling.support = true; + } else { return; } - auto descConfig = dataFlow.getFirstDescrambling(); - descrambling.frontendId = descConfig->getFrontendConnection(); - if (descConfig->hasDvrSoftwareFeConnection()) { - descrambling.dvrSoftwareFeId = descConfig->getDvrSoftwareFeConnection(); + auto descConfig = *dataFlow.getFirstDescrambling(); + descrambling.frontendId = descConfig.getFrontendConnection(); + descrambling.audioFilterId = descConfig.getAudioFilterConnection(); + descrambling.videoFilterId = descConfig.getVideoFilterConnection(); + if (descConfig.hasDvrSoftwareFeConnection()) { + descrambling.dvrSoftwareFeId = descConfig.getDvrSoftwareFeConnection(); } } static void connectLnbLive(LnbLiveHardwareConnections& lnbLive) { auto dataFlow = getDataFlowConfiguration(); - if (!dataFlow.hasLnbLive()) { - lnbLive.support = false; + if (dataFlow.hasLnbLive()) { + lnbLive.support = true; + } else { return; } - auto lnbLiveConfig = dataFlow.getFirstLnbLive(); - lnbLive.frontendId = lnbLiveConfig->getFrontendConnection(); + auto lnbLiveConfig = *dataFlow.getFirstLnbLive(); + lnbLive.frontendId = lnbLiveConfig.getFrontendConnection(); + lnbLive.audioFilterId = lnbLiveConfig.getAudioFilterConnection(); + lnbLive.videoFilterId = lnbLiveConfig.getVideoFilterConnection(); } static void connectLnbRecord(LnbRecordHardwareConnections& lnbRecord) { auto dataFlow = getDataFlowConfiguration(); - if (!dataFlow.hasLnbRecord()) { - lnbRecord.support = false; + if (dataFlow.hasLnbRecord()) { + lnbRecord.support = true; + } else { return; } - auto lnbRecordConfig = dataFlow.getFirstLnbRecord(); - lnbRecord.frontendId = lnbRecordConfig->getFrontendConnection(); + auto lnbRecordConfig = *dataFlow.getFirstLnbRecord(); + lnbRecord.frontendId = lnbRecordConfig.getFrontendConnection(); + lnbRecord.recordFilterId = lnbRecordConfig.getRecordFilterConnection(); + lnbRecord.dvrRecordId = lnbRecordConfig.getDvrRecordConnection(); } private: @@ -350,6 +427,147 @@ struct TunerTestingConfigReader { return dvbsSettings; } + static bool readFilterTypeAndSettings(Filter filterConfig, DemuxFilterType& type, + DemuxFilterSettings& settings) { + auto mainType = filterConfig.getMainType(); + auto subType = filterConfig.getSubType(); + uint32_t pid = static_cast(filterConfig.getPid()); + switch (mainType) { + case FilterMainTypeEnum::TS: { + ALOGW("[ConfigReader] filter main type is ts"); + type.mainType = DemuxFilterMainType::TS; + switch (subType) { + case FilterSubTypeEnum::UNDEFINED: + break; + case FilterSubTypeEnum::SECTION: + type.subType.tsFilterType(DemuxTsFilterType::SECTION); + settings.ts().filterSettings.section( + readSectionFilterSettings(filterConfig)); + break; + case FilterSubTypeEnum::PES: + // TODO: b/182519645 support all the filter settings + /*settings.ts().filterSettings.pesData( + getPesFilterSettings(filterConfig));*/ + type.subType.tsFilterType(DemuxTsFilterType::PES); + break; + case FilterSubTypeEnum::TS: + type.subType.tsFilterType(DemuxTsFilterType::TS); + settings.ts().filterSettings.noinit(); + break; + case FilterSubTypeEnum::PCR: + type.subType.tsFilterType(DemuxTsFilterType::PCR); + settings.ts().filterSettings.noinit(); + break; + case FilterSubTypeEnum::TEMI: + type.subType.tsFilterType(DemuxTsFilterType::TEMI); + settings.ts().filterSettings.noinit(); + break; + case FilterSubTypeEnum::AUDIO: + type.subType.tsFilterType(DemuxTsFilterType::AUDIO); + settings.ts().filterSettings.av(readAvFilterSettings(filterConfig)); + break; + case FilterSubTypeEnum::VIDEO: + type.subType.tsFilterType(DemuxTsFilterType::VIDEO); + settings.ts().filterSettings.av(readAvFilterSettings(filterConfig)); + break; + case FilterSubTypeEnum::RECORD: + type.subType.tsFilterType(DemuxTsFilterType::RECORD); + settings.ts().filterSettings.record(readRecordFilterSettings(filterConfig)); + break; + default: + ALOGW("[ConfigReader] ts subtype is not supported"); + return false; + } + settings.ts().tpid = pid; + break; + } + case FilterMainTypeEnum::MMTP: { + ALOGW("[ConfigReader] filter main type is mmtp"); + type.mainType = DemuxFilterMainType::MMTP; + switch (subType) { + case FilterSubTypeEnum::UNDEFINED: + break; + case FilterSubTypeEnum::SECTION: + type.subType.mmtpFilterType(DemuxMmtpFilterType::SECTION); + settings.mmtp().filterSettings.section( + readSectionFilterSettings(filterConfig)); + break; + case FilterSubTypeEnum::PES: + type.subType.mmtpFilterType(DemuxMmtpFilterType::PES); + // TODO: b/182519645 support all the filter settings + /*settings.mmtp().filterSettings.pesData( + getPesFilterSettings(filterConfig));*/ + break; + case FilterSubTypeEnum::MMTP: + type.subType.mmtpFilterType(DemuxMmtpFilterType::MMTP); + settings.mmtp().filterSettings.noinit(); + break; + case FilterSubTypeEnum::AUDIO: + type.subType.mmtpFilterType(DemuxMmtpFilterType::AUDIO); + settings.mmtp().filterSettings.av(readAvFilterSettings(filterConfig)); + break; + case FilterSubTypeEnum::VIDEO: + settings.mmtp().filterSettings.av(readAvFilterSettings(filterConfig)); + break; + case FilterSubTypeEnum::RECORD: + type.subType.mmtpFilterType(DemuxMmtpFilterType::RECORD); + settings.mmtp().filterSettings.record( + readRecordFilterSettings(filterConfig)); + break; + case FilterSubTypeEnum::DOWNLOAD: + type.subType.mmtpFilterType(DemuxMmtpFilterType::DOWNLOAD); + // TODO: b/182519645 support all the filter settings + /*settings.mmtp().filterSettings.download( + getDownloadFilterSettings(filterConfig));*/ + break; + default: + ALOGW("[ConfigReader] mmtp subtype is not supported"); + return false; + } + settings.mmtp().mmtpPid = pid; + break; + } + default: + // TODO: b/182519645 support all the filter configs + ALOGW("[ConfigReader] filter main type is not supported in dynamic config"); + return false; + } + return true; + } + + static DemuxFilterSectionSettings readSectionFilterSettings(Filter filterConfig) { + DemuxFilterSectionSettings settings; + if (!filterConfig.hasSectionFilterSettings_optional()) { + return settings; + } + auto section = filterConfig.getFirstSectionFilterSettings_optional(); + settings.isCheckCrc = section->getIsCheckCrc(); + settings.isRepeat = section->getIsRepeat(); + settings.isRaw = section->getIsRaw(); + return settings; + } + + static DemuxFilterAvSettings readAvFilterSettings(Filter filterConfig) { + DemuxFilterAvSettings settings; + if (!filterConfig.hasAvFilterSettings_optional()) { + return settings; + } + auto av = filterConfig.getFirstAvFilterSettings_optional(); + settings.isPassthrough = av->getIsPassthrough(); + return settings; + } + + static DemuxFilterRecordSettings readRecordFilterSettings(Filter filterConfig) { + DemuxFilterRecordSettings settings; + if (!filterConfig.hasRecordFilterSettings_optional()) { + return settings; + } + auto record = filterConfig.getFirstRecordFilterSettings_optional(); + settings.tsIndexMask = static_cast(record->getTsIndexMask()); + settings.scIndexType = static_cast(record->getScIndexType()); + return settings; + } + static PlaybackSettings readPlaybackSettings(Dvr dvrConfig) { ALOGW("[ConfigReader] dvr type is playback"); PlaybackSettings playbackSettings{ diff --git a/tv/tuner/config/api/current.txt b/tv/tuner/config/api/current.txt index 1ebd8e1494..a768acbb0d 100644 --- a/tv/tuner/config/api/current.txt +++ b/tv/tuner/config/api/current.txt @@ -1,6 +1,12 @@ // Signature format: 2.0 package android.media.tuner.testing.configuration.V1_0 { + public class AvFilterSettings { + ctor public AvFilterSettings(); + method @Nullable public boolean getIsPassthrough(); + method public void setIsPassthrough(@Nullable boolean); + } + public class DataFlowConfiguration { ctor public DataFlowConfiguration(); method @Nullable public android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.ClearLiveBroadcast getClearLiveBroadcast(); @@ -21,24 +27,42 @@ package android.media.tuner.testing.configuration.V1_0 { public static class DataFlowConfiguration.ClearLiveBroadcast { ctor public DataFlowConfiguration.ClearLiveBroadcast(); + method @Nullable public String getAudioFilterConnection(); method @Nullable public String getDvrSoftwareFeConnection(); method @Nullable public String getFrontendConnection(); + method @Nullable public String getPcrFilterConnection(); + method @Nullable public String getSectionFilterConnection(); + method @Nullable public String getVideoFilterConnection(); + method public void setAudioFilterConnection(@Nullable String); method public void setDvrSoftwareFeConnection(@Nullable String); method public void setFrontendConnection(@Nullable String); + method public void setPcrFilterConnection(@Nullable String); + method public void setSectionFilterConnection(@Nullable String); + method public void setVideoFilterConnection(@Nullable String); } public static class DataFlowConfiguration.Descrambling { ctor public DataFlowConfiguration.Descrambling(); + method @Nullable public String getAudioFilterConnection(); method @Nullable public String getDvrSoftwareFeConnection(); method @Nullable public String getFrontendConnection(); + method @Nullable public String getVideoFilterConnection(); + method public void setAudioFilterConnection(@Nullable String); method public void setDvrSoftwareFeConnection(@Nullable String); method public void setFrontendConnection(@Nullable String); + method public void setVideoFilterConnection(@Nullable String); } public static class DataFlowConfiguration.DvrPlayback { ctor public DataFlowConfiguration.DvrPlayback(); + method @Nullable public String getAudioFilterConnection(); method @Nullable public String getDvrConnection(); + method @Nullable public String getSectionFilterConnection(); + method @Nullable public String getVideoFilterConnection(); + method public void setAudioFilterConnection(@Nullable String); method public void setDvrConnection(@Nullable String); + method public void setSectionFilterConnection(@Nullable String); + method public void setVideoFilterConnection(@Nullable String); } public static class DataFlowConfiguration.DvrRecord { @@ -46,23 +70,31 @@ package android.media.tuner.testing.configuration.V1_0 { method @Nullable public String getDvrRecordConnection(); method @Nullable public String getDvrSoftwareFeConnection(); method @Nullable public String getFrontendConnection(); + method @Nullable public String getRecordFilterConnection(); method public void setDvrRecordConnection(@Nullable String); method public void setDvrSoftwareFeConnection(@Nullable String); method public void setFrontendConnection(@Nullable String); + method public void setRecordFilterConnection(@Nullable String); } public static class DataFlowConfiguration.LnbLive { ctor public DataFlowConfiguration.LnbLive(); + method @Nullable public String getAudioFilterConnection(); method @Nullable public String getFrontendConnection(); + method @Nullable public String getVideoFilterConnection(); + method public void setAudioFilterConnection(@Nullable String); method public void setFrontendConnection(@Nullable String); + method public void setVideoFilterConnection(@Nullable String); } public static class DataFlowConfiguration.LnbRecord { ctor public DataFlowConfiguration.LnbRecord(); method @Nullable public String getDvrRecordConnection(); method @Nullable public String getFrontendConnection(); + method @Nullable public String getRecordFilterConnection(); method public void setDvrRecordConnection(@Nullable String); method public void setFrontendConnection(@Nullable String); + method public void setRecordFilterConnection(@Nullable String); } public static class DataFlowConfiguration.Scan { @@ -133,6 +165,49 @@ package android.media.tuner.testing.configuration.V1_0 { enum_constant public static final android.media.tuner.testing.configuration.V1_0.DvrTypeEnum RECORD; } + public class Filter { + ctor public Filter(); + method @Nullable public android.media.tuner.testing.configuration.V1_0.AvFilterSettings getAvFilterSettings_optional(); + method @Nullable public java.math.BigInteger getBufferSize(); + method @Nullable public String getId(); + method @Nullable public android.media.tuner.testing.configuration.V1_0.FilterMainTypeEnum getMainType(); + method @Nullable public java.math.BigInteger getPid(); + method @Nullable public android.media.tuner.testing.configuration.V1_0.RecordFilterSettings getRecordFilterSettings_optional(); + method @Nullable public android.media.tuner.testing.configuration.V1_0.SectionFilterSettings getSectionFilterSettings_optional(); + method @Nullable public android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum getSubType(); + method @Nullable public boolean getUseFMQ(); + method public void setAvFilterSettings_optional(@Nullable android.media.tuner.testing.configuration.V1_0.AvFilterSettings); + method public void setBufferSize(@Nullable java.math.BigInteger); + method public void setId(@Nullable String); + method public void setMainType(@Nullable android.media.tuner.testing.configuration.V1_0.FilterMainTypeEnum); + method public void setPid(@Nullable java.math.BigInteger); + method public void setRecordFilterSettings_optional(@Nullable android.media.tuner.testing.configuration.V1_0.RecordFilterSettings); + method public void setSectionFilterSettings_optional(@Nullable android.media.tuner.testing.configuration.V1_0.SectionFilterSettings); + method public void setSubType(@Nullable android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum); + method public void setUseFMQ(@Nullable boolean); + } + + public enum FilterMainTypeEnum { + method @NonNull public String getRawName(); + enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterMainTypeEnum MMTP; + enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterMainTypeEnum TS; + } + + public enum FilterSubTypeEnum { + method @NonNull public String getRawName(); + enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum AUDIO; + enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum DOWNLOAD; + enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum MMTP; + enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum PCR; + enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum PES; + enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum RECORD; + enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum SECTION; + enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum TEMI; + enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum TS; + enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum UNDEFINED; + enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum VIDEO; + } + public class Frontend { ctor public Frontend(); method @Nullable public java.math.BigInteger getConnectToCicamId(); @@ -171,8 +246,10 @@ package android.media.tuner.testing.configuration.V1_0 { public class HardwareConfiguration { ctor public HardwareConfiguration(); method @Nullable public android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.Dvrs getDvrs(); + method @Nullable public android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.Filters getFilters(); method @Nullable public android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.Frontends getFrontends(); method public void setDvrs(@Nullable android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.Dvrs); + method public void setFilters(@Nullable android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.Filters); method public void setFrontends(@Nullable android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.Frontends); } @@ -181,11 +258,41 @@ package android.media.tuner.testing.configuration.V1_0 { method @Nullable public java.util.List getDvr(); } + public static class HardwareConfiguration.Filters { + ctor public HardwareConfiguration.Filters(); + method @Nullable public java.util.List getFilter(); + } + public static class HardwareConfiguration.Frontends { ctor public HardwareConfiguration.Frontends(); method @Nullable public java.util.List getFrontend(); } + public class RecordFilterSettings { + ctor public RecordFilterSettings(); + method @Nullable public android.media.tuner.testing.configuration.V1_0.ScIndexTypeEnum getScIndexType(); + method @Nullable public java.math.BigInteger getTsIndexMask(); + method public void setScIndexType(@Nullable android.media.tuner.testing.configuration.V1_0.ScIndexTypeEnum); + method public void setTsIndexMask(@Nullable java.math.BigInteger); + } + + public enum ScIndexTypeEnum { + method @NonNull public String getRawName(); + enum_constant public static final android.media.tuner.testing.configuration.V1_0.ScIndexTypeEnum NONE; + enum_constant public static final android.media.tuner.testing.configuration.V1_0.ScIndexTypeEnum SC; + enum_constant public static final android.media.tuner.testing.configuration.V1_0.ScIndexTypeEnum SC_HEVC; + } + + public class SectionFilterSettings { + ctor public SectionFilterSettings(); + method @Nullable public boolean getIsCheckCrc(); + method @Nullable public boolean getIsRaw(); + method @Nullable public boolean getIsRepeat(); + method public void setIsCheckCrc(@Nullable boolean); + method public void setIsRaw(@Nullable boolean); + method public void setIsRepeat(@Nullable boolean); + } + public class TunerConfiguration { ctor public TunerConfiguration(); method @Nullable public android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration getDataFlowConfiguration(); diff --git a/tv/tuner/config/sample_tuner_vts_config.xml b/tv/tuner/config/sample_tuner_vts_config.xml index 001e04574e..44120f7e66 100644 --- a/tv/tuner/config/sample_tuner_vts_config.xml +++ b/tv/tuner/config/sample_tuner_vts_config.xml @@ -60,6 +60,51 @@ connectToCicamId="0" frequency="578000" endFrequency="800000"> + + + + + + + + + + + + + + + + + + - - + + diff --git a/tv/tuner/config/tuner_testing_dynamic_configuration.xsd b/tv/tuner/config/tuner_testing_dynamic_configuration.xsd index 45d25e5999..03482b3a29 100644 --- a/tv/tuner/config/tuner_testing_dynamic_configuration.xsd +++ b/tv/tuner/config/tuner_testing_dynamic_configuration.xsd @@ -85,7 +85,7 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Each filter element contain the following attributes: + "id": unique id of the filter that could be used to connect to the test the + "dataFlowConfiguration" + "mainType": the main filter type. The enums are defined in the xsd. + "subType": the sub filter type. The enums are defined in the xsd. + "bufferSize": the buffer size of the filter in hex. + "pid": the pid that would be used to configure the filter. + "useFMQ": if the filter uses FMQ. + + Each filter element also contains at most one type-related "filterSettings". + - The settings type should match the filter "subType" attribute. + - For example, when filter subType is audio or video, the avFilterSettings + can be configured. + - This is optional and skipping the settings would pass a setting with tpid + config only to the hal. + + + + + + + + + + + + + + + + + @@ -197,6 +303,27 @@ + + + + + This section contains configurations of all the filters that would be + used in the tests. + - This section is optional and can be skipped to use the default + filter settings. + - The default settings can be found in the + sample_tuner_vts_configurations.xml. + - The users can also override the default filter settings using + - id="FILTER_AUDIO_DEFAULT" or "FILTER_VIDEO_DEFAULT". + - The users can configure 1 or more filter elements in the filters + sections. + + + + + + + @@ -223,6 +350,11 @@ + + + + + @@ -235,6 +367,9 @@ + + + @@ -242,6 +377,10 @@ + + + + @@ -250,16 +389,21 @@ + + + + + @@ -279,5 +423,13 @@ + + + + + + + + -- GitLab From c0e9a11256594f7bbebb9deae860dc90df3c4cf5 Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Thu, 1 Apr 2021 19:25:21 -0700 Subject: [PATCH 589/790] Add lnb/timeFilter dynamic configuration into Tuner 1.0 VTS Test: atest VtsHalTvTunerV1_0TargetTest Bug: 182519645 CTS-Coverage-Bug: 184077478 Change-Id: I75d7fb53054120c6ef5ce36a0bea1e4e334183c7 --- tv/tuner/1.0/vts/functional/LnbTests.cpp | 5 +- tv/tuner/1.0/vts/functional/LnbTests.h | 2 +- .../VtsHalTvTunerV1_0TargetTest.cpp | 89 +++++----- .../functional/VtsHalTvTunerV1_0TargetTest.h | 4 +- .../VtsHalTvTunerV1_0TestConfigurations.h | 104 +++++------- tv/tuner/config/TunerTestingConfigReader.h | 92 +++++++++- tv/tuner/config/api/current.txt | 93 ++++++++++ tv/tuner/config/sample_tuner_vts_config.xml | 44 ++++- .../tuner_testing_dynamic_configuration.xsd | 159 ++++++++++++++++++ 9 files changed, 470 insertions(+), 122 deletions(-) diff --git a/tv/tuner/1.0/vts/functional/LnbTests.cpp b/tv/tuner/1.0/vts/functional/LnbTests.cpp index 9080f59762..9338c7341c 100644 --- a/tv/tuner/1.0/vts/functional/LnbTests.cpp +++ b/tv/tuner/1.0/vts/functional/LnbTests.cpp @@ -48,10 +48,11 @@ AssertionResult LnbTests::openLnbById(uint32_t lnbId) { return AssertionResult(status == Result::SUCCESS); } -AssertionResult LnbTests::openLnbByName(string lnbName) { +AssertionResult LnbTests::openLnbByName(string lnbName, uint32_t& id) { Result status; - mService->openLnbByName(lnbName, [&](Result result, uint32_t /*lnbId*/, const sp& lnb) { + mService->openLnbByName(lnbName, [&](Result result, uint32_t lnbId, const sp& lnb) { mLnb = lnb; + id = lnbId; status = result; }); diff --git a/tv/tuner/1.0/vts/functional/LnbTests.h b/tv/tuner/1.0/vts/functional/LnbTests.h index 2fdbe2ce26..62b42ff937 100644 --- a/tv/tuner/1.0/vts/functional/LnbTests.h +++ b/tv/tuner/1.0/vts/functional/LnbTests.h @@ -64,7 +64,7 @@ class LnbTests { AssertionResult getLnbIds(vector& ids); AssertionResult openLnbById(uint32_t lnbId); - AssertionResult openLnbByName(string lnbName); + AssertionResult openLnbByName(string lnbName, uint32_t& lnbId); AssertionResult setLnbCallback(); AssertionResult setVoltage(LnbVoltage voltage); AssertionResult setTone(LnbTone tone); diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp index 491318e5c1..9c1d45791e 100644 --- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp +++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp @@ -56,7 +56,7 @@ void TunerFilterHidlTest::configSingleFilterInDemuxTest(FilterConfig filterConf, } void TunerFilterHidlTest::testTimeFilter(TimeFilterConfig filterConf) { - if (!filterConf.supportTimeFilter) { + if (!timeFilter.support) { return; } uint32_t demuxId; @@ -64,11 +64,8 @@ void TunerFilterHidlTest::testTimeFilter(TimeFilterConfig filterConf) { DemuxCapabilities caps; ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); - // TODO: add time filter hardware support checker ASSERT_TRUE(mDemuxTests.getDemuxCaps(caps)); - if (!caps.bTimeFilter) { - return; - } + ASSERT_TRUE(caps.bTimeFilter); mFilterTests.setDemux(demux); ASSERT_TRUE(mFilterTests.openTimeFilterInDemux()); ASSERT_TRUE(mFilterTests.setTimeStamp(filterConf.timeStamp)); @@ -116,14 +113,16 @@ void TunerBroadcastHidlTest::broadcastSingleFilterTest(FilterConfig filterConf, void TunerBroadcastHidlTest::broadcastSingleFilterTestWithLnb(FilterConfig filterConf, FrontendConfig frontendConf, LnbConfig lnbConf) { - vector ids; - ASSERT_TRUE(mLnbTests.getLnbIds(ids)); - if (ids.size() == 0) { - return; + if (lnbConf.name.compare(emptyHardwareId) == 0) { + vector ids; + ASSERT_TRUE(mLnbTests.getLnbIds(ids)); + ASSERT_TRUE(ids.size() > 0); + ASSERT_TRUE(mLnbTests.openLnbById(ids[0])); + mLnbId = &ids[0]; + } else { + mLnbId = (uint32_t*)malloc(sizeof(uint32_t)); + ASSERT_TRUE(mLnbTests.openLnbByName(lnbConf.name, *mLnbId)); } - ASSERT_TRUE(ids.size() > 0); - ASSERT_TRUE(mLnbTests.openLnbById(ids[0])); - mLnbId = &ids[0]; ASSERT_TRUE(mLnbTests.setLnbCallback()); ASSERT_TRUE(mLnbTests.setVoltage(lnbConf.voltage)); ASSERT_TRUE(mLnbTests.setTone(lnbConf.tone)); @@ -212,18 +211,23 @@ void TunerRecordHidlTest::recordSingleFilterTest(FilterConfig filterConf, void TunerRecordHidlTest::recordSingleFilterTestWithLnb(FilterConfig filterConf, FrontendConfig frontendConf, DvrConfig dvrConf, LnbConfig lnbConf) { - vector ids; - ASSERT_TRUE(mLnbTests.getLnbIds(ids)); - if (ids.size() == 0) { - return; + if (lnbConf.name.compare(emptyHardwareId) == 0) { + vector ids; + ASSERT_TRUE(mLnbTests.getLnbIds(ids)); + ASSERT_TRUE(ids.size() > 0); + ASSERT_TRUE(mLnbTests.openLnbById(ids[0])); + mLnbId = &ids[0]; + } else { + mLnbId = (uint32_t*)malloc(sizeof(uint32_t)); + ASSERT_TRUE(mLnbTests.openLnbByName(lnbConf.name, *mLnbId)); } - ASSERT_TRUE(ids.size() > 0); - ASSERT_TRUE(mLnbTests.openLnbById(ids[0])); - mLnbId = &ids[0]; ASSERT_TRUE(mLnbTests.setLnbCallback()); ASSERT_TRUE(mLnbTests.setVoltage(lnbConf.voltage)); ASSERT_TRUE(mLnbTests.setTone(lnbConf.tone)); ASSERT_TRUE(mLnbTests.setSatellitePosition(lnbConf.position)); + for (auto msgName : lnbRecord.diseqcMsgs) { + ASSERT_TRUE(mLnbTests.sendDiseqcMessage(diseqcMsgMap[msgName])); + } recordSingleFilterTest(filterConf, frontendConf, dvrConf); ASSERT_TRUE(mLnbTests.closeLnb()); mLnbId = nullptr; @@ -343,37 +347,24 @@ TEST_P(TunerFrontendHidlTest, BlindScanFrontend) { mFrontendTests.scanTest(frontendMap[scan.frontendId], FrontendScanType::SCAN_BLIND); } -TEST_P(TunerLnbHidlTest, OpenLnbByName) { - description("Open and configure an Lnb with name then send a diseqc msg to it."); - // TODO: add lnb hardware support checker - vector ids; - ASSERT_TRUE(mLnbTests.getLnbIds(ids)); - if (ids.size() == 0) { - return; - } - ASSERT_TRUE(mLnbTests.openLnbByName(lnbArray[LNB_EXTERNAL].name)); - ASSERT_TRUE(mLnbTests.setLnbCallback()); - ASSERT_TRUE(mLnbTests.setVoltage(lnbArray[LNB_EXTERNAL].voltage)); - ASSERT_TRUE(mLnbTests.setTone(lnbArray[LNB_EXTERNAL].tone)); - ASSERT_TRUE(mLnbTests.setSatellitePosition(lnbArray[LNB_EXTERNAL].position)); - ASSERT_TRUE(mLnbTests.sendDiseqcMessage(diseqcMsgArray[DISEQC_POWER_ON])); - ASSERT_TRUE(mLnbTests.closeLnb()); -} - TEST_P(TunerLnbHidlTest, SendDiseqcMessageToLnb) { description("Open and configure an Lnb with specific settings then send a diseqc msg to it."); - vector ids; - ASSERT_TRUE(mLnbTests.getLnbIds(ids)); - if (ids.size() == 0) { - return; + if (lnbMap[lnbLive.lnbId].name.compare(emptyHardwareId) == 0) { + vector ids; + ASSERT_TRUE(mLnbTests.getLnbIds(ids)); + ASSERT_TRUE(ids.size() > 0); + ASSERT_TRUE(mLnbTests.openLnbById(ids[0])); + } else { + uint32_t id; + ASSERT_TRUE(mLnbTests.openLnbByName(lnbMap[lnbLive.lnbId].name, id)); } - ASSERT_TRUE(ids.size() > 0); - ASSERT_TRUE(mLnbTests.openLnbById(ids[0])); ASSERT_TRUE(mLnbTests.setLnbCallback()); - ASSERT_TRUE(mLnbTests.setVoltage(lnbArray[LNB0].voltage)); - ASSERT_TRUE(mLnbTests.setTone(lnbArray[LNB0].tone)); - ASSERT_TRUE(mLnbTests.setSatellitePosition(lnbArray[LNB0].position)); - ASSERT_TRUE(mLnbTests.sendDiseqcMessage(diseqcMsgArray[DISEQC_POWER_ON])); + ASSERT_TRUE(mLnbTests.setVoltage(lnbMap[lnbLive.lnbId].voltage)); + ASSERT_TRUE(mLnbTests.setTone(lnbMap[lnbLive.lnbId].tone)); + ASSERT_TRUE(mLnbTests.setSatellitePosition(lnbMap[lnbLive.lnbId].position)); + for (auto msgName : lnbLive.diseqcMsgs) { + ASSERT_TRUE(mLnbTests.sendDiseqcMessage(diseqcMsgMap[msgName])); + } ASSERT_TRUE(mLnbTests.closeLnb()); } @@ -469,7 +460,7 @@ TEST_P(TunerFilterHidlTest, SetFilterLinkage) { TEST_P(TunerFilterHidlTest, testTimeFilter) { description("Open a timer filter in Demux and set time stamp."); // TODO use paramterized tests - testTimeFilter(timeFilterArray[TIMER0]); + testTimeFilter(timeFilterMap[timeFilter.timeFilterId]); } TEST_P(TunerBroadcastHidlTest, BroadcastDataFlowVideoFilterTest) { @@ -501,7 +492,7 @@ TEST_P(TunerBroadcastHidlTest, LnbBroadcastDataFlowVideoFilterTest) { return; } broadcastSingleFilterTestWithLnb(filterMap[lnbLive.videoFilterId], - frontendMap[lnbLive.frontendId], lnbArray[LNB0]); + frontendMap[lnbLive.frontendId], lnbMap[lnbLive.lnbId]); } TEST_P(TunerPlaybackHidlTest, PlaybackDataFlowWithTsSectionFilterTest) { @@ -538,7 +529,7 @@ TEST_P(TunerRecordHidlTest, LnbRecordDataFlowWithTsRecordFilterTest) { } recordSingleFilterTestWithLnb(filterMap[lnbRecord.recordFilterId], frontendMap[lnbRecord.frontendId], dvrMap[lnbRecord.dvrRecordId], - lnbArray[LNB0]); + lnbMap[lnbRecord.lnbId]); } TEST_P(TunerDescramblerHidlTest, CreateDescrambler) { diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h index 07ce201746..bf8e383294 100644 --- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h +++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h @@ -35,14 +35,14 @@ bool initConfiguration() { initFrontendConfig(); initFilterConfig(); initDvrConfig(); + initLnbConfig(); + initTimeFilterConfig(); connectHardwaresToTestCases(); if (!validateConnections()) { ALOGW("[vts] failed to validate connections."); return false; } - initLnbConfig(); - initTimeFilterConfig(); initDescramblerConfig(); return true; diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h index 8537fe8410..bdf94dc4e6 100644 --- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h +++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h @@ -79,46 +79,17 @@ const uint32_t FMQ_SIZE_16M = 0x1000000; " \"track_types\": [ ] " \ "} " -typedef enum { - TIMER0, - TIMER_MAX, -} TimeFilter; - typedef enum { SOURCE, SINK, LINKAGE_DIR, } Linkage; -typedef enum { - LNB0, - LNB_EXTERNAL, - LNB_MAX, -} Lnb; - -typedef enum { - DISEQC_POWER_ON, - DISEQC_MAX, -} Diseqc; - typedef enum { DESC_0, DESC_MAX, } Descrambler; -struct TimeFilterConfig { - bool supportTimeFilter; - uint64_t timeStamp; -}; - -struct LnbConfig { - bool usingLnb; - string name; - LnbVoltage voltage; - LnbTone tone; - LnbPosition position; -}; - struct DescramblerConfig { uint32_t casSystemId; string provisionStr; @@ -126,9 +97,6 @@ struct DescramblerConfig { }; // TODO: remove all the manual config array after the dynamic config refactoring is done. -static LnbConfig lnbArray[LNB_MAX]; -static vector diseqcMsgArray[DISEQC_MAX]; -static TimeFilterConfig timeFilterArray[TIMER_MAX]; static DemuxFilterType filterLinkageTypes[LINKAGE_DIR][FILTER_MAIN_TYPE_BIT_COUNT]; static DescramblerConfig descramblerArray[DESC_MAX]; @@ -136,6 +104,9 @@ static DescramblerConfig descramblerArray[DESC_MAX]; static map frontendMap; static map filterMap; static map dvrMap; +static map lnbMap; +static map timeFilterMap; +static map> diseqcMsgMap; // Hardware and test cases connections static LiveBroadcastHardwareConnections live; @@ -145,6 +116,7 @@ static DvrRecordHardwareConnections record; static DescramblingHardwareConnections descrambling; static LnbLiveHardwareConnections lnbLive; static LnbRecordHardwareConnections lnbRecord; +static TimeFilterHardwareConnections timeFilter; /** Config all the frontends that would be used in the tests */ inline void initFrontendConfig() { @@ -202,6 +174,19 @@ inline void initDvrConfig() { TunerTestingConfigReader::readDvrConfig1_0(dvrMap); }; +/** Config all the lnbs that would be used in the tests */ +inline void initLnbConfig() { + // Read customized config + TunerTestingConfigReader::readLnbConfig1_0(lnbMap); + TunerTestingConfigReader::readDiseqcMessages(diseqcMsgMap); +}; + +/** Config all the time filters that would be used in the tests */ +inline void initTimeFilterConfig() { + // Read customized config + TunerTestingConfigReader::readTimeFilterConfig1_0(timeFilterMap); +}; + /** Read the vendor configurations of which hardware to use for each test cases/data flows */ inline void connectHardwaresToTestCases() { TunerTestingConfigReader::connectLiveBroadcast(live); @@ -211,6 +196,7 @@ inline void connectHardwaresToTestCases() { TunerTestingConfigReader::connectDescrambling(descrambling); TunerTestingConfigReader::connectLnbLive(lnbLive); TunerTestingConfigReader::connectLnbRecord(lnbRecord); + TunerTestingConfigReader::connectTimeFilter(timeFilter); }; inline bool validateConnections() { @@ -233,14 +219,12 @@ inline bool validateConnections() { ? dvrMap.find(live.dvrSoftwareFeId) != dvrMap.end() : true; dvrIsValid &= playback.support ? dvrMap.find(playback.dvrId) != dvrMap.end() : true; - if (record.support) { if (frontendMap[record.frontendId].isSoftwareFe) { dvrIsValid &= dvrMap.find(record.dvrSoftwareFeId) != dvrMap.end(); } dvrIsValid &= dvrMap.find(record.dvrRecordId) != dvrMap.end(); } - if (descrambling.support && frontendMap[descrambling.frontendId].isSoftwareFe) { dvrIsValid &= dvrMap.find(descrambling.dvrSoftwareFeId) != dvrMap.end(); } @@ -252,24 +236,19 @@ inline bool validateConnections() { bool filterIsValid = filterMap.find(live.audioFilterId) != filterMap.end() && filterMap.find(live.videoFilterId) != filterMap.end(); - filterIsValid &= playback.support ? (filterMap.find(playback.audioFilterId) != filterMap.end() && filterMap.find(playback.videoFilterId) != filterMap.end()) : true; - filterIsValid &= record.support ? filterMap.find(record.recordFilterId) != filterMap.end() : true; - filterIsValid &= descrambling.support ? (filterMap.find(descrambling.audioFilterId) != filterMap.end() && filterMap.find(descrambling.videoFilterId) != filterMap.end()) : true; - filterIsValid &= lnbLive.support ? (filterMap.find(lnbLive.audioFilterId) != filterMap.end() && filterMap.find(lnbLive.videoFilterId) != filterMap.end()) : true; - filterIsValid &= lnbRecord.support ? filterMap.find(lnbRecord.recordFilterId) != filterMap.end() : true; @@ -278,34 +257,35 @@ inline bool validateConnections() { return false; } - return true; -} + bool lnbIsValid = lnbLive.support ? lnbMap.find(lnbLive.lnbId) != lnbMap.end() : true; + lnbIsValid &= lnbRecord.support ? lnbMap.find(lnbRecord.lnbId) != lnbMap.end() : true; -// TODO: remove all the manual configs after the dynamic config refactoring is done. -/** Configuration array for the Lnb test */ -inline void initLnbConfig() { - lnbArray[LNB0].usingLnb = true; - lnbArray[LNB0].voltage = LnbVoltage::VOLTAGE_12V; - lnbArray[LNB0].tone = LnbTone::NONE; - lnbArray[LNB0].position = LnbPosition::UNDEFINED; - lnbArray[LNB_EXTERNAL].usingLnb = true; - lnbArray[LNB_EXTERNAL].name = "default_lnb_external"; - lnbArray[LNB_EXTERNAL].voltage = LnbVoltage::VOLTAGE_5V; - lnbArray[LNB_EXTERNAL].tone = LnbTone::NONE; - lnbArray[LNB_EXTERNAL].position = LnbPosition::UNDEFINED; -}; + if (!lnbIsValid) { + ALOGW("[vts config] dynamic config lnb connection is invalid."); + return false; + } -/** Diseqc messages array for the Lnb test */ -inline void initDiseqcMsg() { - diseqcMsgArray[DISEQC_POWER_ON] = {0xE, 0x0, 0x0, 0x0, 0x0, 0x3}; -}; + bool diseqcMsgIsValid = true; + if (lnbLive.support) { + for (auto msgName : lnbLive.diseqcMsgs) { + diseqcMsgIsValid &= diseqcMsgMap.find(msgName) != diseqcMsgMap.end(); + } + } + if (lnbRecord.support) { + for (auto msgName : lnbRecord.diseqcMsgs) { + diseqcMsgIsValid &= diseqcMsgMap.find(msgName) != diseqcMsgMap.end(); + } + } -/** Configuration array for the timer filter test */ -inline void initTimeFilterConfig() { - timeFilterArray[TIMER0].supportTimeFilter = true; - timeFilterArray[TIMER0].timeStamp = 1; + if (!diseqcMsgIsValid) { + ALOGW("[vts config] dynamic config diseqcMsg sender is invalid."); + return false; + } + + return true; } +// TODO: remove all the manual configs after the dynamic config refactoring is done. /** Configuration array for the descrambler test */ inline void initDescramblerConfig() { descramblerArray[DESC_0].casSystemId = CLEAR_KEY_SYSTEM_ID; diff --git a/tv/tuner/config/TunerTestingConfigReader.h b/tv/tuner/config/TunerTestingConfigReader.h index 9ee509c6c1..bc35ac4128 100644 --- a/tv/tuner/config/TunerTestingConfigReader.h +++ b/tv/tuner/config/TunerTestingConfigReader.h @@ -90,6 +90,17 @@ struct DvrConfig { string playbackInputFile; }; +struct LnbConfig { + string name; + LnbVoltage voltage; + LnbTone tone; + LnbPosition position; +}; + +struct TimeFilterConfig { + uint64_t timeStamp; +}; + struct LiveBroadcastHardwareConnections { string frontendId; string dvrSoftwareFeId; @@ -137,8 +148,9 @@ struct LnbLiveHardwareConnections { string frontendId; string audioFilterId; string videoFilterId; - /* list string of extra filters; - string lnbId; */ + string lnbId; + vector diseqcMsgs; + /* list string of extra filters; */ }; struct LnbRecordHardwareConnections { @@ -146,8 +158,14 @@ struct LnbRecordHardwareConnections { string frontendId; string dvrRecordId; string recordFilterId; - /* list string of extra filters; - string lnbId; */ + string lnbId; + vector diseqcMsgs; + /* list string of extra filters; */ +}; + +struct TimeFilterHardwareConnections { + bool support; + string timeFilterId; }; struct TunerTestingConfigReader { @@ -290,6 +308,49 @@ struct TunerTestingConfigReader { } } + static void readLnbConfig1_0(map& lnbMap) { + auto hardwareConfig = getHardwareConfig(); + if (hardwareConfig.hasLnbs()) { + auto lnbs = *hardwareConfig.getFirstLnbs(); + for (auto lnbConfig : lnbs.getLnb()) { + string id = lnbConfig.getId(); + if (lnbConfig.hasName()) { + lnbMap[id].name = lnbConfig.getName(); + } else { + lnbMap[id].name = emptyHardwareId; + } + lnbMap[id].voltage = static_cast(lnbConfig.getVoltage()); + lnbMap[id].tone = static_cast(lnbConfig.getTone()); + lnbMap[id].position = static_cast(lnbConfig.getPosition()); + } + } + } + + static void readDiseqcMessages(map>& diseqcMsgMap) { + auto hardwareConfig = getHardwareConfig(); + if (hardwareConfig.hasDiseqcMessages()) { + auto msgs = *hardwareConfig.getFirstDiseqcMessages(); + for (auto msgConfig : msgs.getDiseqcMessage()) { + string name = msgConfig.getMsgName(); + for (uint8_t atom : msgConfig.getMsgBody()) { + diseqcMsgMap[name].push_back(atom); + } + } + } + } + + static void readTimeFilterConfig1_0(map& timeFilterMap) { + auto hardwareConfig = getHardwareConfig(); + if (hardwareConfig.hasTimeFilters()) { + auto timeFilters = *hardwareConfig.getFirstTimeFilters(); + for (auto timeFilterConfig : timeFilters.getTimeFilter()) { + string id = timeFilterConfig.getId(); + timeFilterMap[id].timeStamp = + static_cast(timeFilterConfig.getTimeStamp()); + } + } + } + static void connectLiveBroadcast(LiveBroadcastHardwareConnections& live) { auto liveConfig = *getDataFlowConfiguration().getFirstClearLiveBroadcast(); live.frontendId = liveConfig.getFrontendConnection(); @@ -377,6 +438,12 @@ struct TunerTestingConfigReader { lnbLive.frontendId = lnbLiveConfig.getFrontendConnection(); lnbLive.audioFilterId = lnbLiveConfig.getAudioFilterConnection(); lnbLive.videoFilterId = lnbLiveConfig.getVideoFilterConnection(); + lnbLive.lnbId = lnbLiveConfig.getLnbConnection(); + if (lnbLiveConfig.hasDiseqcMsgSender()) { + for (auto msgName : lnbLiveConfig.getDiseqcMsgSender()) { + lnbLive.diseqcMsgs.push_back(msgName); + } + } } static void connectLnbRecord(LnbRecordHardwareConnections& lnbRecord) { @@ -390,6 +457,23 @@ struct TunerTestingConfigReader { lnbRecord.frontendId = lnbRecordConfig.getFrontendConnection(); lnbRecord.recordFilterId = lnbRecordConfig.getRecordFilterConnection(); lnbRecord.dvrRecordId = lnbRecordConfig.getDvrRecordConnection(); + lnbRecord.lnbId = lnbRecordConfig.getLnbConnection(); + if (lnbRecordConfig.hasDiseqcMsgSender()) { + for (auto msgName : lnbRecordConfig.getDiseqcMsgSender()) { + lnbRecord.diseqcMsgs.push_back(msgName); + } + } + } + + static void connectTimeFilter(TimeFilterHardwareConnections& timeFilter) { + auto dataFlow = getDataFlowConfiguration(); + if (dataFlow.hasTimeFilter()) { + timeFilter.support = true; + } else { + return; + } + auto timeFilterConfig = *dataFlow.getFirstTimeFilter(); + timeFilter.timeFilterId = timeFilterConfig.getTimeFilterConnection(); } private: diff --git a/tv/tuner/config/api/current.txt b/tv/tuner/config/api/current.txt index a768acbb0d..78e958be44 100644 --- a/tv/tuner/config/api/current.txt +++ b/tv/tuner/config/api/current.txt @@ -16,6 +16,7 @@ package android.media.tuner.testing.configuration.V1_0 { method @Nullable public android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.LnbLive getLnbLive(); method @Nullable public android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.LnbRecord getLnbRecord(); method @Nullable public android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.Scan getScan(); + method @Nullable public android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.TimeFilter getTimeFilter(); method public void setClearLiveBroadcast(@Nullable android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.ClearLiveBroadcast); method public void setDescrambling(@Nullable android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.Descrambling); method public void setDvrPlayback(@Nullable android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.DvrPlayback); @@ -23,6 +24,7 @@ package android.media.tuner.testing.configuration.V1_0 { method public void setLnbLive(@Nullable android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.LnbLive); method public void setLnbRecord(@Nullable android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.LnbRecord); method public void setScan(@Nullable android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.Scan); + method public void setTimeFilter(@Nullable android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.TimeFilter); } public static class DataFlowConfiguration.ClearLiveBroadcast { @@ -80,20 +82,28 @@ package android.media.tuner.testing.configuration.V1_0 { public static class DataFlowConfiguration.LnbLive { ctor public DataFlowConfiguration.LnbLive(); method @Nullable public String getAudioFilterConnection(); + method @Nullable public java.util.List getDiseqcMsgSender(); method @Nullable public String getFrontendConnection(); + method @Nullable public String getLnbConnection(); method @Nullable public String getVideoFilterConnection(); method public void setAudioFilterConnection(@Nullable String); + method public void setDiseqcMsgSender(@Nullable java.util.List); method public void setFrontendConnection(@Nullable String); + method public void setLnbConnection(@Nullable String); method public void setVideoFilterConnection(@Nullable String); } public static class DataFlowConfiguration.LnbRecord { ctor public DataFlowConfiguration.LnbRecord(); + method @Nullable public java.util.List getDiseqcMsgSender(); method @Nullable public String getDvrRecordConnection(); method @Nullable public String getFrontendConnection(); + method @Nullable public String getLnbConnection(); method @Nullable public String getRecordFilterConnection(); + method public void setDiseqcMsgSender(@Nullable java.util.List); method public void setDvrRecordConnection(@Nullable String); method public void setFrontendConnection(@Nullable String); + method public void setLnbConnection(@Nullable String); method public void setRecordFilterConnection(@Nullable String); } @@ -103,6 +113,20 @@ package android.media.tuner.testing.configuration.V1_0 { method public void setFrontendConnection(@Nullable String); } + public static class DataFlowConfiguration.TimeFilter { + ctor public DataFlowConfiguration.TimeFilter(); + method @Nullable public String getTimeFilterConnection(); + method public void setTimeFilterConnection(@Nullable String); + } + + public class DiseqcMessage { + ctor public DiseqcMessage(); + method @Nullable public java.util.List getMsgBody(); + method @Nullable public String getMsgName(); + method public void setMsgBody(@Nullable java.util.List); + method public void setMsgName(@Nullable String); + } + public class DvbsFrontendSettings { ctor public DvbsFrontendSettings(); method @Nullable public java.math.BigInteger getInputStreamId(); @@ -245,12 +269,23 @@ package android.media.tuner.testing.configuration.V1_0 { public class HardwareConfiguration { ctor public HardwareConfiguration(); + method @Nullable public android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.DiseqcMessages getDiseqcMessages(); method @Nullable public android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.Dvrs getDvrs(); method @Nullable public android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.Filters getFilters(); method @Nullable public android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.Frontends getFrontends(); + method @Nullable public android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.Lnbs getLnbs(); + method @Nullable public android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.TimeFilters getTimeFilters(); + method public void setDiseqcMessages(@Nullable android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.DiseqcMessages); method public void setDvrs(@Nullable android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.Dvrs); method public void setFilters(@Nullable android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.Filters); method public void setFrontends(@Nullable android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.Frontends); + method public void setLnbs(@Nullable android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.Lnbs); + method public void setTimeFilters(@Nullable android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.TimeFilters); + } + + public static class HardwareConfiguration.DiseqcMessages { + ctor public HardwareConfiguration.DiseqcMessages(); + method @Nullable public java.util.List getDiseqcMessage(); } public static class HardwareConfiguration.Dvrs { @@ -268,6 +303,56 @@ package android.media.tuner.testing.configuration.V1_0 { method @Nullable public java.util.List getFrontend(); } + public static class HardwareConfiguration.Lnbs { + ctor public HardwareConfiguration.Lnbs(); + method @Nullable public java.util.List getLnb(); + } + + public static class HardwareConfiguration.TimeFilters { + ctor public HardwareConfiguration.TimeFilters(); + method @Nullable public java.util.List getTimeFilter(); + } + + public class Lnb { + ctor public Lnb(); + method @Nullable public String getId(); + method @Nullable public String getName(); + method @Nullable public android.media.tuner.testing.configuration.V1_0.LnbPositionEnum getPosition(); + method @Nullable public android.media.tuner.testing.configuration.V1_0.LnbToneEnum getTone(); + method @Nullable public android.media.tuner.testing.configuration.V1_0.LnbVoltageEnum getVoltage(); + method public void setId(@Nullable String); + method public void setName(@Nullable String); + method public void setPosition(@Nullable android.media.tuner.testing.configuration.V1_0.LnbPositionEnum); + method public void setTone(@Nullable android.media.tuner.testing.configuration.V1_0.LnbToneEnum); + method public void setVoltage(@Nullable android.media.tuner.testing.configuration.V1_0.LnbVoltageEnum); + } + + public enum LnbPositionEnum { + method @NonNull public String getRawName(); + enum_constant public static final android.media.tuner.testing.configuration.V1_0.LnbPositionEnum POSITION_A; + enum_constant public static final android.media.tuner.testing.configuration.V1_0.LnbPositionEnum POSITION_B; + enum_constant public static final android.media.tuner.testing.configuration.V1_0.LnbPositionEnum UNDEFINED; + } + + public enum LnbToneEnum { + method @NonNull public String getRawName(); + enum_constant public static final android.media.tuner.testing.configuration.V1_0.LnbToneEnum CONTINUOUS; + enum_constant public static final android.media.tuner.testing.configuration.V1_0.LnbToneEnum NONE; + } + + public enum LnbVoltageEnum { + method @NonNull public String getRawName(); + enum_constant public static final android.media.tuner.testing.configuration.V1_0.LnbVoltageEnum NONE; + enum_constant public static final android.media.tuner.testing.configuration.V1_0.LnbVoltageEnum VOLTAGE_11V; + enum_constant public static final android.media.tuner.testing.configuration.V1_0.LnbVoltageEnum VOLTAGE_12V; + enum_constant public static final android.media.tuner.testing.configuration.V1_0.LnbVoltageEnum VOLTAGE_13V; + enum_constant public static final android.media.tuner.testing.configuration.V1_0.LnbVoltageEnum VOLTAGE_14V; + enum_constant public static final android.media.tuner.testing.configuration.V1_0.LnbVoltageEnum VOLTAGE_15V; + enum_constant public static final android.media.tuner.testing.configuration.V1_0.LnbVoltageEnum VOLTAGE_18V; + enum_constant public static final android.media.tuner.testing.configuration.V1_0.LnbVoltageEnum VOLTAGE_19V; + enum_constant public static final android.media.tuner.testing.configuration.V1_0.LnbVoltageEnum VOLTAGE_5V; + } + public class RecordFilterSettings { ctor public RecordFilterSettings(); method @Nullable public android.media.tuner.testing.configuration.V1_0.ScIndexTypeEnum getScIndexType(); @@ -293,6 +378,14 @@ package android.media.tuner.testing.configuration.V1_0 { method public void setIsRepeat(@Nullable boolean); } + public class TimeFilter { + ctor public TimeFilter(); + method @Nullable public String getId(); + method @Nullable public java.math.BigInteger getTimeStamp(); + method public void setId(@Nullable String); + method public void setTimeStamp(@Nullable java.math.BigInteger); + } + public class TunerConfiguration { ctor public TunerConfiguration(); method @Nullable public android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration getDataFlowConfiguration(); diff --git a/tv/tuner/config/sample_tuner_vts_config.xml b/tv/tuner/config/sample_tuner_vts_config.xml index 44120f7e66..6a3e814e83 100644 --- a/tv/tuner/config/sample_tuner_vts_config.xml +++ b/tv/tuner/config/sample_tuner_vts_config.xml @@ -133,6 +133,41 @@ statusMask="15" lowThreshold="4096" highThreshold="32767" dataFormat="ES" packetSize="188" inputFilePath="/data/local/tmp/test.es"/> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Each lnb element contain the following attributes: + "id": unique id of the lnb that could be used to connect to the test the + "dataFlowConfiguration" + "name": the external lnb device name. + "voltage": the voltage used to config the lnb. + "tone": the voltage used to config the lnb. + "position": the voltage used to config the lnb. + + + + + + + + + + + + + + + + + + + + + + Each timeFilter element contain the following attributes: + "id": unique id of the time filter that could be used to connect to the test the + "dataFlowConfiguration" + "timeStamp": the time stamp used to config the time filter. + + + + + + @@ -341,6 +434,55 @@ + + + + + This section contains configurations of all the diseqc messages that + would be used in the lnb tests. + - This section is optional and can be skipped if lnb is not suppoted + - The users can configure 1 or more message elements in the + diseqcMessages sections. + + + + + + + + + + + + This section contains configurations of all the lnbs that would be used + in the tests. + - This section is optional and can be skipped if lnb is not suppoted + - The users can configure 1 or more lnb elements in the lnbs + sections. + + + + + + + + + + + + This section contains configurations of all the time filters that would + be used in the tests. + - This section is optional and can be skipped if time filter is + not supported. + - The users can configure 1 or more time filter elements in the + time filters sections. + + + + + + + @@ -397,6 +539,8 @@ + + @@ -405,6 +549,13 @@ + + + + + + + @@ -431,5 +582,13 @@ + + + + + + + + -- GitLab From 32b6f9eaf026f9d2037c34db16d634212c2c74c1 Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Fri, 2 Apr 2021 15:01:17 -0700 Subject: [PATCH 590/790] Add descrambler dynamic configuration into Tuner 1.0 VTS Test: atest VtsHalTvTunerV1_0TargetTest Bug: 182519645 CTS-Coverage-Bug: 184077478 Change-Id: I2ab16fa9645dba07f8969e3cd7a26cf3b9bcb527 --- .../VtsHalTvTunerV1_0TargetTest.cpp | 8 +- .../functional/VtsHalTvTunerV1_0TargetTest.h | 30 ++++++- .../VtsHalTvTunerV1_0TestConfigurations.h | 86 ++++--------------- tv/tuner/config/TunerTestingConfigReader.h | 48 ++++++++++- tv/tuner/config/api/current.txt | 21 +++++ tv/tuner/config/sample_tuner_vts_config.xml | 17 ++++ .../tuner_testing_dynamic_configuration.xsd | 50 +++++++++++ 7 files changed, 182 insertions(+), 78 deletions(-) diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp index 9c1d45791e..4c92665b63 100644 --- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp +++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp @@ -441,11 +441,9 @@ TEST_P(TunerFilterHidlTest, SetFilterLinkage) { if (caps.linkCaps[i] & (bitMask << j)) { uint32_t sourceFilterId; uint32_t sinkFilterId; - ASSERT_TRUE(mFilterTests.openFilterInDemux(filterLinkageTypes[SOURCE][i], - FMQ_SIZE_16M)); + ASSERT_TRUE(mFilterTests.openFilterInDemux(getLinkageFilterType(i), FMQ_SIZE_16M)); ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(sourceFilterId)); - ASSERT_TRUE( - mFilterTests.openFilterInDemux(filterLinkageTypes[SINK][j], FMQ_SIZE_16M)); + ASSERT_TRUE(mFilterTests.openFilterInDemux(getLinkageFilterType(j), FMQ_SIZE_16M)); ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(sinkFilterId)); ASSERT_TRUE(mFilterTests.setFilterDataSource(sourceFilterId, sinkFilterId)); ASSERT_TRUE(mFilterTests.setFilterDataSourceToDemux(sinkFilterId)); @@ -561,7 +559,7 @@ TEST_P(TunerDescramblerHidlTest, ScrambledBroadcastDataFlowMediaFiltersTest) { filterConfs.insert(static_cast(filterMap[descrambling.audioFilterId])); filterConfs.insert(static_cast(filterMap[descrambling.videoFilterId])); scrambledBroadcastTest(filterConfs, frontendMap[descrambling.frontendId], - descramblerArray[DESC_0]); + descramblerMap[descrambling.descramblerId]); } INSTANTIATE_TEST_SUITE_P( diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h index bf8e383294..e2406042df 100644 --- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h +++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h @@ -20,6 +20,9 @@ #include "LnbTests.h" using android::hardware::tv::tuner::V1_0::DataFormat; +using android::hardware::tv::tuner::V1_0::DemuxAlpFilterType; +using android::hardware::tv::tuner::V1_0::DemuxMmtpFilterType; +using android::hardware::tv::tuner::V1_0::DemuxTlvFilterType; using android::hardware::tv::tuner::V1_0::IDescrambler; static AssertionResult success() { @@ -37,14 +40,12 @@ bool initConfiguration() { initDvrConfig(); initLnbConfig(); initTimeFilterConfig(); + initDescramblerConfig(); connectHardwaresToTestCases(); if (!validateConnections()) { ALOGW("[vts] failed to validate connections."); return false; } - - initDescramblerConfig(); - return true; } @@ -148,6 +149,29 @@ class TunerFilterHidlTest : public testing::TestWithParam { void configSingleFilterInDemuxTest(FilterConfig filterConf, FrontendConfig frontendConf); void testTimeFilter(TimeFilterConfig filterConf); + DemuxFilterType getLinkageFilterType(int bit) { + DemuxFilterType type; + type.mainType = static_cast(1 << bit); + switch (type.mainType) { + case DemuxFilterMainType::TS: + type.subType.tsFilterType(DemuxTsFilterType::UNDEFINED); + break; + case DemuxFilterMainType::MMTP: + type.subType.mmtpFilterType(DemuxMmtpFilterType::UNDEFINED); + break; + case DemuxFilterMainType::IP: + type.subType.ipFilterType(DemuxIpFilterType::UNDEFINED); + break; + case DemuxFilterMainType::TLV: + type.subType.tlvFilterType(DemuxTlvFilterType::UNDEFINED); + break; + case DemuxFilterMainType::ALP: + type.subType.alpFilterType(DemuxAlpFilterType::UNDEFINED); + break; + } + return type; + } + sp mService; FrontendTests mFrontendTests; DemuxTests mDemuxTests; diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h index bdf94dc4e6..65f8615ad8 100644 --- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h +++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h @@ -23,82 +23,23 @@ #include "../../../config/TunerTestingConfigReader.h" -// TODO: remove unnecessary imports after config reader refactoring is done. -using android::hardware::tv::tuner::V1_0::DataFormat; -using android::hardware::tv::tuner::V1_0::DemuxAlpFilterType; -using android::hardware::tv::tuner::V1_0::DemuxFilterEvent; using android::hardware::tv::tuner::V1_0::DemuxFilterMainType; -using android::hardware::tv::tuner::V1_0::DemuxFilterSettings; -using android::hardware::tv::tuner::V1_0::DemuxFilterType; -using android::hardware::tv::tuner::V1_0::DemuxIpFilterType; -using android::hardware::tv::tuner::V1_0::DemuxMmtpFilterType; -using android::hardware::tv::tuner::V1_0::DemuxRecordScIndexType; -using android::hardware::tv::tuner::V1_0::DemuxTlvFilterType; -using android::hardware::tv::tuner::V1_0::DemuxTpid; using android::hardware::tv::tuner::V1_0::DemuxTsFilterType; -using android::hardware::tv::tuner::V1_0::DvrSettings; -using android::hardware::tv::tuner::V1_0::DvrType; using android::hardware::tv::tuner::V1_0::FrontendDvbtBandwidth; -using android::hardware::tv::tuner::V1_0::FrontendDvbtCoderate; -using android::hardware::tv::tuner::V1_0::FrontendDvbtConstellation; -using android::hardware::tv::tuner::V1_0::FrontendDvbtGuardInterval; -using android::hardware::tv::tuner::V1_0::FrontendDvbtHierarchy; using android::hardware::tv::tuner::V1_0::FrontendDvbtSettings; -using android::hardware::tv::tuner::V1_0::FrontendDvbtStandard; using android::hardware::tv::tuner::V1_0::FrontendDvbtTransmissionMode; using android::hardware::tv::tuner::V1_0::FrontendSettings; using android::hardware::tv::tuner::V1_0::FrontendStatus; using android::hardware::tv::tuner::V1_0::FrontendStatusType; using android::hardware::tv::tuner::V1_0::FrontendType; -using android::hardware::tv::tuner::V1_0::LnbPosition; -using android::hardware::tv::tuner::V1_0::LnbTone; -using android::hardware::tv::tuner::V1_0::LnbVoltage; -using android::hardware::tv::tuner::V1_0::PlaybackSettings; -using android::hardware::tv::tuner::V1_0::RecordSettings; using namespace std; using namespace android::media::tuner::testing::configuration::V1_0; -// TODO: remove all the constants and structs after config reader refactoring is done. -const uint32_t FMQ_SIZE_512K = 0x80000; -const uint32_t FMQ_SIZE_1M = 0x100000; const uint32_t FMQ_SIZE_4M = 0x400000; const uint32_t FMQ_SIZE_16M = 0x1000000; -#define CLEAR_KEY_SYSTEM_ID 0xF6D8 -#define FILTER_MAIN_TYPE_BIT_COUNT 32 -#define PROVISION_STR \ - "{ " \ - " \"id\": 21140844, " \ - " \"name\": \"Test Title\", " \ - " \"lowercase_organization_name\": \"Android\", " \ - " \"asset_key\": { " \ - " \"encryption_key\": \"nezAr3CHFrmBR9R8Tedotw==\" " \ - " }, " \ - " \"cas_type\": 1, " \ - " \"track_types\": [ ] " \ - "} " - -typedef enum { - SOURCE, - SINK, - LINKAGE_DIR, -} Linkage; - -typedef enum { - DESC_0, - DESC_MAX, -} Descrambler; - -struct DescramblerConfig { - uint32_t casSystemId; - string provisionStr; - vector hidlPvtData; -}; - -// TODO: remove all the manual config array after the dynamic config refactoring is done. -static DemuxFilterType filterLinkageTypes[LINKAGE_DIR][FILTER_MAIN_TYPE_BIT_COUNT]; -static DescramblerConfig descramblerArray[DESC_MAX]; +#define FILTER_MAIN_TYPE_BIT_COUNT 5 // Hardware configs static map frontendMap; @@ -107,6 +48,7 @@ static map dvrMap; static map lnbMap; static map timeFilterMap; static map> diseqcMsgMap; +static map descramblerMap; // Hardware and test cases connections static LiveBroadcastHardwareConnections live; @@ -187,6 +129,12 @@ inline void initTimeFilterConfig() { TunerTestingConfigReader::readTimeFilterConfig1_0(timeFilterMap); }; +/** Config all the descramblers that would be used in the tests */ +inline void initDescramblerConfig() { + // Read customized config + TunerTestingConfigReader::readDescramblerConfig1_0(descramblerMap); +}; + /** Read the vendor configurations of which hardware to use for each test cases/data flows */ inline void connectHardwaresToTestCases() { TunerTestingConfigReader::connectLiveBroadcast(live); @@ -265,6 +213,16 @@ inline bool validateConnections() { return false; } + bool descramblerIsValid = + descrambling.support + ? descramblerMap.find(descrambling.descramblerId) != descramblerMap.end() + : true; + + if (!descramblerIsValid) { + ALOGW("[vts config] dynamic config descrambler connection is invalid."); + return false; + } + bool diseqcMsgIsValid = true; if (lnbLive.support) { for (auto msgName : lnbLive.diseqcMsgs) { @@ -284,11 +242,3 @@ inline bool validateConnections() { return true; } - -// TODO: remove all the manual configs after the dynamic config refactoring is done. -/** Configuration array for the descrambler test */ -inline void initDescramblerConfig() { - descramblerArray[DESC_0].casSystemId = CLEAR_KEY_SYSTEM_ID; - descramblerArray[DESC_0].provisionStr = PROVISION_STR; - descramblerArray[DESC_0].hidlPvtData.resize(256); -}; diff --git a/tv/tuner/config/TunerTestingConfigReader.h b/tv/tuner/config/TunerTestingConfigReader.h index bc35ac4128..90499c414c 100644 --- a/tv/tuner/config/TunerTestingConfigReader.h +++ b/tv/tuner/config/TunerTestingConfigReader.h @@ -66,6 +66,18 @@ using android::hardware::tv::tuner::V1_0::RecordSettings; const string configFilePath = "/vendor/etc/tuner_vts_config.xml"; const string emptyHardwareId = ""; +#define PROVISION_STR \ + "{ " \ + " \"id\": 21140844, " \ + " \"name\": \"Test Title\", " \ + " \"lowercase_organization_name\": \"Android\", " \ + " \"asset_key\": { " \ + " \"encryption_key\": \"nezAr3CHFrmBR9R8Tedotw==\" " \ + " }, " \ + " \"cas_type\": 1, " \ + " \"track_types\": [ ] " \ + "} " + struct FrontendConfig { bool isSoftwareFe; FrontendType type; @@ -101,6 +113,12 @@ struct TimeFilterConfig { uint64_t timeStamp; }; +struct DescramblerConfig { + uint32_t casSystemId; + string provisionStr; + vector hidlPvtData; +}; + struct LiveBroadcastHardwareConnections { string frontendId; string dvrSoftwareFeId; @@ -139,8 +157,8 @@ struct DescramblingHardwareConnections { string dvrSoftwareFeId; string audioFilterId; string videoFilterId; - /* string descramblerId; - list string of extra filters; */ + string descramblerId; + /* list string of extra filters; */ }; struct LnbLiveHardwareConnections { @@ -326,6 +344,31 @@ struct TunerTestingConfigReader { } } + static void readDescramblerConfig1_0(map& descramblerMap) { + auto hardwareConfig = getHardwareConfig(); + if (hardwareConfig.hasDescramblers()) { + auto descramblers = *hardwareConfig.getFirstDescramblers(); + for (auto descramblerConfig : descramblers.getDescrambler()) { + string id = descramblerConfig.getId(); + descramblerMap[id].casSystemId = + static_cast(descramblerConfig.getCasSystemId()); + if (descramblerConfig.hasProvisionStr()) { + descramblerMap[id].provisionStr = descramblerConfig.getProvisionStr(); + } else { + descramblerMap[id].provisionStr = PROVISION_STR; + } + if (descramblerConfig.hasSesstionPrivatData()) { + auto privateData = descramblerConfig.getSesstionPrivatData(); + int size = privateData.size(); + descramblerMap[id].hidlPvtData.resize(size); + memcpy(descramblerMap[id].hidlPvtData.data(), privateData.data(), size); + } else { + descramblerMap[id].hidlPvtData.resize(256); + } + } + } + } + static void readDiseqcMessages(map>& diseqcMsgMap) { auto hardwareConfig = getHardwareConfig(); if (hardwareConfig.hasDiseqcMessages()) { @@ -420,6 +463,7 @@ struct TunerTestingConfigReader { } auto descConfig = *dataFlow.getFirstDescrambling(); descrambling.frontendId = descConfig.getFrontendConnection(); + descrambling.descramblerId = descConfig.getDescramblerConnection(); descrambling.audioFilterId = descConfig.getAudioFilterConnection(); descrambling.videoFilterId = descConfig.getVideoFilterConnection(); if (descConfig.hasDvrSoftwareFeConnection()) { diff --git a/tv/tuner/config/api/current.txt b/tv/tuner/config/api/current.txt index 78e958be44..4255a60d16 100644 --- a/tv/tuner/config/api/current.txt +++ b/tv/tuner/config/api/current.txt @@ -46,10 +46,12 @@ package android.media.tuner.testing.configuration.V1_0 { public static class DataFlowConfiguration.Descrambling { ctor public DataFlowConfiguration.Descrambling(); method @Nullable public String getAudioFilterConnection(); + method @Nullable public String getDescramblerConnection(); method @Nullable public String getDvrSoftwareFeConnection(); method @Nullable public String getFrontendConnection(); method @Nullable public String getVideoFilterConnection(); method public void setAudioFilterConnection(@Nullable String); + method public void setDescramblerConnection(@Nullable String); method public void setDvrSoftwareFeConnection(@Nullable String); method public void setFrontendConnection(@Nullable String); method public void setVideoFilterConnection(@Nullable String); @@ -119,6 +121,18 @@ package android.media.tuner.testing.configuration.V1_0 { method public void setTimeFilterConnection(@Nullable String); } + public class Descrambler { + ctor public Descrambler(); + method @Nullable public java.math.BigInteger getCasSystemId(); + method @Nullable public String getId(); + method @Nullable public String getProvisionStr(); + method @Nullable public java.util.List getSesstionPrivatData(); + method public void setCasSystemId(@Nullable java.math.BigInteger); + method public void setId(@Nullable String); + method public void setProvisionStr(@Nullable String); + method public void setSesstionPrivatData(@Nullable java.util.List); + } + public class DiseqcMessage { ctor public DiseqcMessage(); method @Nullable public java.util.List getMsgBody(); @@ -269,12 +283,14 @@ package android.media.tuner.testing.configuration.V1_0 { public class HardwareConfiguration { ctor public HardwareConfiguration(); + method @Nullable public android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.Descramblers getDescramblers(); method @Nullable public android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.DiseqcMessages getDiseqcMessages(); method @Nullable public android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.Dvrs getDvrs(); method @Nullable public android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.Filters getFilters(); method @Nullable public android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.Frontends getFrontends(); method @Nullable public android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.Lnbs getLnbs(); method @Nullable public android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.TimeFilters getTimeFilters(); + method public void setDescramblers(@Nullable android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.Descramblers); method public void setDiseqcMessages(@Nullable android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.DiseqcMessages); method public void setDvrs(@Nullable android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.Dvrs); method public void setFilters(@Nullable android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.Filters); @@ -283,6 +299,11 @@ package android.media.tuner.testing.configuration.V1_0 { method public void setTimeFilters(@Nullable android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.TimeFilters); } + public static class HardwareConfiguration.Descramblers { + ctor public HardwareConfiguration.Descramblers(); + method @Nullable public java.util.List getDescrambler(); + } + public static class HardwareConfiguration.DiseqcMessages { ctor public HardwareConfiguration.DiseqcMessages(); method @Nullable public java.util.List getDiseqcMessage(); diff --git a/tv/tuner/config/sample_tuner_vts_config.xml b/tv/tuner/config/sample_tuner_vts_config.xml index 6a3e814e83..570171edb7 100644 --- a/tv/tuner/config/sample_tuner_vts_config.xml +++ b/tv/tuner/config/sample_tuner_vts_config.xml @@ -168,6 +168,22 @@ + + + + + + + + + + + + + + + + + + Each descrambler element contain the following attributes: + "id": unique id of the descrambler that could be used to connect to the test the + "dataFlowConfiguration" + "casSystemId": the cas system id to connect to the descrambler. + "provisionStr": the provision string to use with the cas plugin. + "sesstionPrivatData": the session private data used to open the cas session. + + + + + + + + @@ -483,6 +511,23 @@ + + + + + This section contains configurations of all the descramblers that would + be used in the tests. + - This section is optional and can be skipped if descrambling is not + supported. + - The users can configure 1 or more descrambler elements in the + descramblers sections. + + + + + + + @@ -509,6 +554,7 @@ + @@ -590,5 +636,9 @@ + + + + -- GitLab From 8c4f0fcfc0387b73ee78b88a82fbec405d011a0a Mon Sep 17 00:00:00 2001 From: Michael Butler Date: Wed, 24 Mar 2021 21:26:02 -0700 Subject: [PATCH 591/790] Improve the structure of NNAPI AIDL Memory Prior to this change, the NN AIDL HAL created a Memory struct analogous to hidl_memory, consisting of a name, size, and native handle. However, this Memory struct is not very structured, and requires both the client and server to agree on how the data should be interpreted. This CL tightens the structure of the Memory representation by introducing Ashmem and MappableFile structs to android.hardware.common in order to hold specific file descriptors representing memory regions. Further, this CL redefines android.hardwre.neuralnetworks's Memory object as a union of the Ashmem, MappableFile, and (existing) HardwareBuffer memory types. This change also adds "com.android.neuralnetworks" to the graphics AIDL HAL's apex_available build rule. Bug: 183118727 Test: mma Change-Id: I32322df676b83597c9e95f13662c322a6a80accc Merged-In: I32322df676b83597c9e95f13662c322a6a80accc (cherry picked from commit 1158c80ff6f24223b8add271945b66f34db78d60) --- .../android/hardware/common/Ashmem.aidl | 39 ++++++++++++++ .../android/hardware/common/MappableFile.aidl | 41 ++++++++++++++ .../android/hardware/common/NativeHandle.aidl | 28 +++++++--- .../aidl/android/hardware/common/Ashmem.aidl | 34 ++++++++++++ .../android/hardware/common/MappableFile.aidl | 53 +++++++++++++++++++ graphics/common/aidl/Android.bp | 1 + neuralnetworks/aidl/Android.bp | 1 + .../hardware/neuralnetworks/Memory.aidl | 8 +-- .../hardware/neuralnetworks/Memory.aidl | 26 ++++++--- 9 files changed, 213 insertions(+), 18 deletions(-) create mode 100644 common/aidl/aidl_api/android.hardware.common/current/android/hardware/common/Ashmem.aidl create mode 100644 common/aidl/aidl_api/android.hardware.common/current/android/hardware/common/MappableFile.aidl create mode 100644 common/aidl/android/hardware/common/Ashmem.aidl create mode 100644 common/aidl/android/hardware/common/MappableFile.aidl diff --git a/common/aidl/aidl_api/android.hardware.common/current/android/hardware/common/Ashmem.aidl b/common/aidl/aidl_api/android.hardware.common/current/android/hardware/common/Ashmem.aidl new file mode 100644 index 0000000000..a4380315c9 --- /dev/null +++ b/common/aidl/aidl_api/android.hardware.common/current/android/hardware/common/Ashmem.aidl @@ -0,0 +1,39 @@ +/* + * 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 -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.common; +@VintfStability +parcelable Ashmem { + ParcelFileDescriptor fd; + long size; +} diff --git a/common/aidl/aidl_api/android.hardware.common/current/android/hardware/common/MappableFile.aidl b/common/aidl/aidl_api/android.hardware.common/current/android/hardware/common/MappableFile.aidl new file mode 100644 index 0000000000..394ea8ff07 --- /dev/null +++ b/common/aidl/aidl_api/android.hardware.common/current/android/hardware/common/MappableFile.aidl @@ -0,0 +1,41 @@ +/* + * 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 -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.common; +@VintfStability +parcelable MappableFile { + long length; + int prot; + ParcelFileDescriptor fd; + long offset; +} diff --git a/common/aidl/aidl_api/android.hardware.common/current/android/hardware/common/NativeHandle.aidl b/common/aidl/aidl_api/android.hardware.common/current/android/hardware/common/NativeHandle.aidl index f37b7d506f..2ed5c0b22d 100644 --- a/common/aidl/aidl_api/android.hardware.common/current/android/hardware/common/NativeHandle.aidl +++ b/common/aidl/aidl_api/android.hardware.common/current/android/hardware/common/NativeHandle.aidl @@ -1,14 +1,30 @@ +/* + * Copyright 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. + */ /////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// -// This file is a snapshot of an AIDL interface (or parcelable). Do not try to -// edit this file. It looks like you are doing that because you have modified -// an AIDL interface in a backward-incompatible way, e.g., deleting a function -// from an interface or a field from a parcelable and it broke the build. That -// breakage is intended. +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. // -// You must not make a backward incompatible changes to the AIDL files built +// You must not make a backward incompatible change to any AIDL file built // with the aidl_interface module type with versions property set. The module // type is used to build AIDL files in a way that they can be used across // independently updatable components of the system. If a device is shipped diff --git a/common/aidl/android/hardware/common/Ashmem.aidl b/common/aidl/android/hardware/common/Ashmem.aidl new file mode 100644 index 0000000000..8e402668bf --- /dev/null +++ b/common/aidl/android/hardware/common/Ashmem.aidl @@ -0,0 +1,34 @@ +/* + * 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.common; + +import android.os.ParcelFileDescriptor; + +/** + * Type that holds same memory as the "ashmem" hidl_memory type from HIDL. + */ +@VintfStability +parcelable Ashmem { + /** + * A handle to a memory region. + */ + ParcelFileDescriptor fd; + /** + * Size of the memory region in bytes. + */ + long size; +} diff --git a/common/aidl/android/hardware/common/MappableFile.aidl b/common/aidl/android/hardware/common/MappableFile.aidl new file mode 100644 index 0000000000..a7763eab37 --- /dev/null +++ b/common/aidl/android/hardware/common/MappableFile.aidl @@ -0,0 +1,53 @@ +/* + * 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.common; + +import android.os.ParcelFileDescriptor; + +/** + * A region of a file that can be mapped into memory. + * + * In Linux, MappableFile may be used with mmap as `MAP_SHARED`. + * + * MappableFile is compatible with ::android::base::MappedFile. + */ +@VintfStability +parcelable MappableFile { + /** + * Length of the mapping region in bytes. + */ + long length; + /** + * The desired memory protection for the mapping. + * + * In Linux, prot is either `PROT_NONE` (indicating that mapped pages may not be accessed) or + * the bitwise OR of one or more of the following flags: + * - `PROT_READ` (indicating that the mapped pages may be read) + * - `PROT_WRITE` (indicating that the mapped pages may be written) + */ + int prot; + /** + * A handle to a mappable file. + */ + ParcelFileDescriptor fd; + /** + * The offset in the file to the beginning of the mapping region in number of bytes. + * + * Note: Some mapping functions require that the offset is aligned to the page size. + */ + long offset; +} diff --git a/graphics/common/aidl/Android.bp b/graphics/common/aidl/Android.bp index 2a46f9dc7f..cadd13cdde 100644 --- a/graphics/common/aidl/Android.bp +++ b/graphics/common/aidl/Android.bp @@ -34,6 +34,7 @@ aidl_interface { apex_available: [ "//apex_available:platform", "com.android.media.swcodec", + "com.android.neuralnetworks", ], min_sdk_version: "29", }, diff --git a/neuralnetworks/aidl/Android.bp b/neuralnetworks/aidl/Android.bp index b1860e2bd0..ebf4654885 100644 --- a/neuralnetworks/aidl/Android.bp +++ b/neuralnetworks/aidl/Android.bp @@ -16,6 +16,7 @@ aidl_interface { stability: "vintf", imports: [ "android.hardware.common", + "android.hardware.graphics.common", ], backend: { java: { diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/Memory.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/Memory.aidl index 8207b25570..37fa102cf4 100644 --- a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/Memory.aidl +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/Memory.aidl @@ -33,8 +33,8 @@ package android.hardware.neuralnetworks; @VintfStability -parcelable Memory { - android.hardware.common.NativeHandle handle; - long size; - String name; +union Memory { + android.hardware.common.Ashmem ashmem; + android.hardware.common.MappableFile mappableFile; + android.hardware.graphics.common.HardwareBuffer hardwareBuffer; } diff --git a/neuralnetworks/aidl/android/hardware/neuralnetworks/Memory.aidl b/neuralnetworks/aidl/android/hardware/neuralnetworks/Memory.aidl index 870f0aeb08..244ac8752d 100644 --- a/neuralnetworks/aidl/android/hardware/neuralnetworks/Memory.aidl +++ b/neuralnetworks/aidl/android/hardware/neuralnetworks/Memory.aidl @@ -15,16 +15,26 @@ */ package android.hardware.neuralnetworks; -import android.hardware.common.NativeHandle; -import android.os.ParcelFileDescriptor; + +import android.hardware.common.Ashmem; +import android.hardware.common.MappableFile; +import android.hardware.graphics.common.HardwareBuffer; /** - * A type that is used to pass pieces of shared memory between processes. - * The type structure mimics hidl_memory type from HIDL. + * The different types of memory that can be shared across processes. */ @VintfStability -parcelable Memory { - NativeHandle handle; - long size; - String name; +union Memory { + /** + * Ashmem hidl_memory type from HIDL. + */ + Ashmem ashmem; + /** + * File that can be mapped. + */ + MappableFile mappableFile; + /** + * AIDL representation of AHardwareBuffer. + */ + HardwareBuffer hardwareBuffer; } -- GitLab From bed23d9c3310c1e9a00fa0f49a9b6209b83e23b0 Mon Sep 17 00:00:00 2001 From: Michael Butler Date: Thu, 25 Mar 2021 15:27:38 -0700 Subject: [PATCH 592/790] Update NN utility code and VTS tests with new Memory type This CL fixes the compiler errors that arose of changing the Memory representation of the NN AIDL HAL, and updates the conversion and utility code to work with the new Memory type. This change also makes libaidlcommonsupport available to apex modules at min sdk level 29. Bug: 183118727 Test: mma Test: VtsHalNeuralnetworksTargetTest Change-Id: Ief565473b4d82e0bb43785fc3b8275b16bd26cf6 Merged-In: Ief565473b4d82e0bb43785fc3b8275b16bd26cf6 (cherry picked from commit b0fcb3927d848e9721f05a458b5d6d4d2cb8079d) --- common/support/Android.bp | 5 + neuralnetworks/aidl/utils/Android.bp | 4 + neuralnetworks/aidl/utils/src/Conversions.cpp | 283 ++++++++++-------- neuralnetworks/aidl/utils/src/Utils.cpp | 62 +++- neuralnetworks/aidl/vts/functional/Android.bp | 2 + .../aidl/vts/functional/MemoryDomainTests.cpp | 21 +- .../aidl/vts/functional/ValidateModel.cpp | 16 +- .../utils/common/src/CommonUtils.cpp | 128 ++++++-- 8 files changed, 348 insertions(+), 173 deletions(-) diff --git a/common/support/Android.bp b/common/support/Android.bp index 8aea306dae..730798d840 100644 --- a/common/support/Android.bp +++ b/common/support/Android.bp @@ -18,6 +18,11 @@ cc_library_static { "android.hardware.common-V2-ndk_platform", "libcutils", ], + apex_available: [ + "//apex_available:platform", + "com.android.neuralnetworks", + ], + min_sdk_version: "29", } cc_test { diff --git a/neuralnetworks/aidl/utils/Android.bp b/neuralnetworks/aidl/utils/Android.bp index ad961cfe99..0ccc711ecf 100644 --- a/neuralnetworks/aidl/utils/Android.bp +++ b/neuralnetworks/aidl/utils/Android.bp @@ -31,6 +31,8 @@ cc_library_static { export_include_dirs: ["include"], cflags: ["-Wthread-safety"], static_libs: [ + "android.hardware.graphics.common-V2-ndk_platform", + "libaidlcommonsupport", "libarect", "neuralnetworks_types", "neuralnetworks_utils_hal_common", @@ -51,7 +53,9 @@ cc_test { ], static_libs: [ "android.hardware.common-V2-ndk_platform", + "android.hardware.graphics.common-V2-ndk_platform", "android.hardware.neuralnetworks-V1-ndk_platform", + "libaidlcommonsupport", "libgmock", "libneuralnetworks_common", "neuralnetworks_types", diff --git a/neuralnetworks/aidl/utils/src/Conversions.cpp b/neuralnetworks/aidl/utils/src/Conversions.cpp index d5f7f81663..93ac51c233 100644 --- a/neuralnetworks/aidl/utils/src/Conversions.cpp +++ b/neuralnetworks/aidl/utils/src/Conversions.cpp @@ -16,8 +16,13 @@ #include "Conversions.h" +#include +#include #include +#include +#include #include +#include #include #include #include @@ -125,28 +130,17 @@ struct NativeHandleDeleter { using UniqueNativeHandle = std::unique_ptr; -static GeneralResult nativeHandleFromAidlHandle(const NativeHandle& handle) { - std::vector fds; - fds.reserve(handle.fds.size()); - for (const auto& fd : handle.fds) { - auto duplicatedFd = NN_TRY(dupFd(fd.get())); - fds.emplace_back(duplicatedFd.release()); - } - - constexpr size_t kIntMax = std::numeric_limits::max(); - CHECK_LE(handle.fds.size(), kIntMax); - CHECK_LE(handle.ints.size(), kIntMax); - native_handle_t* nativeHandle = native_handle_create(static_cast(handle.fds.size()), - static_cast(handle.ints.size())); - if (nativeHandle == nullptr) { - return NN_ERROR() << "Failed to create native_handle"; +GeneralResult nativeHandleFromAidlHandle(const NativeHandle& handle) { + auto nativeHandle = UniqueNativeHandle(dupFromAidl(handle)); + if (nativeHandle.get() == nullptr) { + return NN_ERROR() << "android::dupFromAidl failed to convert the common::NativeHandle to a " + "native_handle_t"; } - for (size_t i = 0; i < fds.size(); ++i) { - nativeHandle->data[i] = fds[i].release(); + if (!std::all_of(nativeHandle->data + 0, nativeHandle->data + nativeHandle->numFds, + [](int fd) { return fd >= 0; })) { + return NN_ERROR() << "android::dupFromAidl returned an invalid native_handle_t"; } - std::copy(handle.ints.begin(), handle.ints.end(), &nativeHandle->data[nativeHandle->numFds]); - - return UniqueNativeHandle(nativeHandle); + return nativeHandle; } } // anonymous namespace @@ -353,67 +347,66 @@ GeneralResult unvalidatedConvert(bool measureTiming) { return measureTiming ? MeasureTiming::YES : MeasureTiming::NO; } -static uint32_t roundUpToMultiple(uint32_t value, uint32_t multiple) { - return (value + multiple - 1) / multiple * multiple; -} - GeneralResult unvalidatedConvert(const aidl_hal::Memory& memory) { - VERIFY_NON_NEGATIVE(memory.size) << "Memory size must not be negative"; - if (memory.size > std::numeric_limits::max()) { - return NN_ERROR() << "Memory: size must be <= std::numeric_limits::max()"; - } - - if (memory.name != "hardware_buffer_blob") { - return std::make_shared(Memory{ - .handle = NN_TRY(unvalidatedConvertHelper(memory.handle)), - .size = static_cast(memory.size), - .name = memory.name, - }); - } - - const auto size = static_cast(memory.size); - const auto format = AHARDWAREBUFFER_FORMAT_BLOB; - const auto usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN | AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN; - const uint32_t width = size; - const uint32_t height = 1; // height is always 1 for BLOB mode AHardwareBuffer. - const uint32_t layers = 1; // layers is always 1 for BLOB mode AHardwareBuffer. - - const UniqueNativeHandle handle = NN_TRY(nativeHandleFromAidlHandle(memory.handle)); - const native_handle_t* nativeHandle = handle.get(); - - // AHardwareBuffer_createFromHandle() might fail because an allocator - // expects a specific stride value. In that case, we try to guess it by - // aligning the width to small powers of 2. - // TODO(b/174120849): Avoid stride assumptions. - AHardwareBuffer* hardwareBuffer = nullptr; - status_t status = UNKNOWN_ERROR; - for (uint32_t alignment : {1, 4, 32, 64, 128, 2, 8, 16}) { - const uint32_t stride = roundUpToMultiple(width, alignment); - AHardwareBuffer_Desc desc{ - .width = width, - .height = height, - .layers = layers, - .format = format, - .usage = usage, - .stride = stride, - }; - status = AHardwareBuffer_createFromHandle(&desc, nativeHandle, - AHARDWAREBUFFER_CREATE_FROM_HANDLE_METHOD_CLONE, - &hardwareBuffer); - if (status == NO_ERROR) { - break; + using Tag = aidl_hal::Memory::Tag; + switch (memory.getTag()) { + case Tag::ashmem: { + const auto& ashmem = memory.get(); + VERIFY_NON_NEGATIVE(ashmem.size) << "Memory size must not be negative"; + if (ashmem.size > std::numeric_limits::max()) { + return NN_ERROR() << "Memory: size must be <= std::numeric_limits::max()"; + } + + auto handle = Memory::Ashmem{ + .fd = NN_TRY(dupFd(ashmem.fd.get())), + .size = static_cast(ashmem.size), + }; + return std::make_shared(Memory{.handle = std::move(handle)}); + } + case Tag::mappableFile: { + const auto& mappableFile = memory.get(); + VERIFY_NON_NEGATIVE(mappableFile.length) << "Memory size must not be negative"; + VERIFY_NON_NEGATIVE(mappableFile.offset) << "Memory offset must not be negative"; + if (mappableFile.length > std::numeric_limits::max()) { + return NN_ERROR() << "Memory: size must be <= std::numeric_limits::max()"; + } + if (mappableFile.offset > std::numeric_limits::max()) { + return NN_ERROR() << "Memory: offset must be <= std::numeric_limits::max()"; + } + + const size_t size = static_cast(mappableFile.length); + const int prot = mappableFile.prot; + const int fd = mappableFile.fd.get(); + const size_t offset = static_cast(mappableFile.offset); + + return createSharedMemoryFromFd(size, prot, fd, offset); + } + case Tag::hardwareBuffer: { + const auto& hardwareBuffer = memory.get(); + + const UniqueNativeHandle handle = + NN_TRY(nativeHandleFromAidlHandle(hardwareBuffer.handle)); + const native_handle_t* nativeHandle = handle.get(); + + const AHardwareBuffer_Desc desc{ + .width = static_cast(hardwareBuffer.description.width), + .height = static_cast(hardwareBuffer.description.height), + .layers = static_cast(hardwareBuffer.description.layers), + .format = static_cast(hardwareBuffer.description.format), + .usage = static_cast(hardwareBuffer.description.usage), + .stride = static_cast(hardwareBuffer.description.stride), + }; + AHardwareBuffer* ahwb = nullptr; + const status_t status = AHardwareBuffer_createFromHandle( + &desc, nativeHandle, AHARDWAREBUFFER_CREATE_FROM_HANDLE_METHOD_CLONE, &ahwb); + if (status != NO_ERROR) { + return NN_ERROR() << "createFromHandle failed"; + } + + return createSharedMemoryFromAHWB(ahwb, /*takeOwnership=*/true); } } - if (status != NO_ERROR) { - return NN_ERROR(ErrorStatus::GENERAL_FAILURE) - << "Can't create AHardwareBuffer from handle. Error: " << status; - } - - return std::make_shared(Memory{ - .handle = HardwareBufferHandle(hardwareBuffer, /*takeOwnership=*/true), - .size = static_cast(memory.size), - .name = memory.name, - }); + return NN_ERROR() << "Unrecognized Memory::Tag: " << memory.getTag(); } GeneralResult unvalidatedConvert(const aidl_hal::Timing& timing) { @@ -645,20 +638,95 @@ struct overloaded : Ts... { template overloaded(Ts...)->overloaded; -static nn::GeneralResult aidlHandleFromNativeHandle( - const native_handle_t& handle) { - common::NativeHandle aidlNativeHandle; +nn::GeneralResult aidlHandleFromNativeHandle( + const native_handle_t& nativeHandle) { + auto handle = ::android::dupToAidl(&nativeHandle); + if (!std::all_of(handle.fds.begin(), handle.fds.end(), + [](const ndk::ScopedFileDescriptor& fd) { return fd.get() >= 0; })) { + return NN_ERROR() << "android::dupToAidl returned an invalid common::NativeHandle"; + } + return handle; +} - aidlNativeHandle.fds.reserve(handle.numFds); - for (int i = 0; i < handle.numFds; ++i) { - auto duplicatedFd = NN_TRY(nn::dupFd(handle.data[i])); - aidlNativeHandle.fds.emplace_back(duplicatedFd.release()); +nn::GeneralResult unvalidatedConvert(const nn::Memory::Ashmem& memory) { + if constexpr (std::numeric_limits::max() > std::numeric_limits::max()) { + if (memory.size > std::numeric_limits::max()) { + return ( + NN_ERROR() + << "Memory::Ashmem: size must be <= std::numeric_limits::max()") + . + operator nn::GeneralResult(); + } } - aidlNativeHandle.ints = std::vector(&handle.data[handle.numFds], - &handle.data[handle.numFds + handle.numInts]); + auto fd = NN_TRY(nn::dupFd(memory.fd)); + auto handle = common::Ashmem{ + .fd = ndk::ScopedFileDescriptor(fd.release()), + .size = static_cast(memory.size), + }; + return Memory::make(std::move(handle)); +} - return aidlNativeHandle; +nn::GeneralResult unvalidatedConvert(const nn::Memory::Fd& memory) { + if constexpr (std::numeric_limits::max() > std::numeric_limits::max()) { + if (memory.size > std::numeric_limits::max()) { + return (NN_ERROR() << "Memory::Fd: size must be <= std::numeric_limits::max()") + . + operator nn::GeneralResult(); + } + if (memory.offset > std::numeric_limits::max()) { + return ( + NN_ERROR() + << "Memory::Fd: offset must be <= std::numeric_limits::max()") + . + operator nn::GeneralResult(); + } + } + + auto fd = NN_TRY(nn::dupFd(memory.fd)); + auto handle = common::MappableFile{ + .length = static_cast(memory.size), + .prot = memory.prot, + .fd = ndk::ScopedFileDescriptor(fd.release()), + .offset = static_cast(memory.offset), + }; + return Memory::make(std::move(handle)); +} + +nn::GeneralResult unvalidatedConvert(const nn::Memory::HardwareBuffer& memory) { + const native_handle_t* nativeHandle = AHardwareBuffer_getNativeHandle(memory.handle.get()); + if (nativeHandle == nullptr) { + return (NN_ERROR() << "unvalidatedConvert failed because AHardwareBuffer_getNativeHandle " + "returned nullptr") + . + operator nn::GeneralResult(); + } + + auto handle = NN_TRY(aidlHandleFromNativeHandle(*nativeHandle)); + + AHardwareBuffer_Desc desc; + AHardwareBuffer_describe(memory.handle.get(), &desc); + + const auto description = graphics::common::HardwareBufferDescription{ + .width = static_cast(desc.width), + .height = static_cast(desc.height), + .layers = static_cast(desc.layers), + .format = static_cast(desc.format), + .usage = static_cast(desc.usage), + .stride = static_cast(desc.stride), + }; + + auto hardwareBuffer = graphics::common::HardwareBuffer{ + .description = std::move(description), + .handle = std::move(handle), + }; + return Memory::make(std::move(hardwareBuffer)); +} + +nn::GeneralResult unvalidatedConvert(const nn::Memory::Unknown& /*memory*/) { + return (NN_ERROR() << "Unable to convert Unknown memory type") + . + operator nn::GeneralResult(); } } // namespace @@ -693,41 +761,12 @@ nn::GeneralResult unvalidatedConvert(const nn::SharedHandl } nn::GeneralResult unvalidatedConvert(const nn::SharedMemory& memory) { - CHECK(memory != nullptr); - if (memory->size > std::numeric_limits::max()) { - return NN_ERROR() << "Memory size doesn't fit into int64_t."; + if (memory == nullptr) { + return (NN_ERROR() << "Unable to convert nullptr memory") + . + operator nn::GeneralResult(); } - if (const auto* handle = std::get_if(&memory->handle)) { - return Memory{ - .handle = NN_TRY(unvalidatedConvert(*handle)), - .size = static_cast(memory->size), - .name = memory->name, - }; - } - - const auto* ahwb = std::get(memory->handle).get(); - AHardwareBuffer_Desc bufferDesc; - AHardwareBuffer_describe(ahwb, &bufferDesc); - - if (bufferDesc.format == AHARDWAREBUFFER_FORMAT_BLOB) { - CHECK_EQ(memory->size, bufferDesc.width); - CHECK_EQ(memory->name, "hardware_buffer_blob"); - } else { - CHECK_EQ(memory->size, 0u); - CHECK_EQ(memory->name, "hardware_buffer"); - } - - const native_handle_t* nativeHandle = AHardwareBuffer_getNativeHandle(ahwb); - if (nativeHandle == nullptr) { - return NN_ERROR() << "unvalidatedConvert failed because AHardwareBuffer_getNativeHandle " - "returned nullptr"; - } - - return Memory{ - .handle = NN_TRY(aidlHandleFromNativeHandle(*nativeHandle)), - .size = static_cast(memory->size), - .name = memory->name, - }; + return std::visit([](const auto& x) { return unvalidatedConvert(x); }, memory->handle); } nn::GeneralResult unvalidatedConvert(const nn::ErrorStatus& errorStatus) { diff --git a/neuralnetworks/aidl/utils/src/Utils.cpp b/neuralnetworks/aidl/utils/src/Utils.cpp index 95516c854b..03407be4ce 100644 --- a/neuralnetworks/aidl/utils/src/Utils.cpp +++ b/neuralnetworks/aidl/utils/src/Utils.cpp @@ -16,12 +16,20 @@ #include "Utils.h" +#include +#include +#include +#include #include #include +#include namespace aidl::android::hardware::neuralnetworks::utils { namespace { +nn::GeneralResult clone(const ndk::ScopedFileDescriptor& fd); +using utils::clone; + template nn::GeneralResult> cloneVec(const std::vector& arguments) { std::vector clonedObjects; @@ -37,24 +45,52 @@ nn::GeneralResult> clone(const std::vector& arguments) { return cloneVec(arguments); } +nn::GeneralResult clone(const ndk::ScopedFileDescriptor& fd) { + auto duplicatedFd = NN_TRY(nn::dupFd(fd.get())); + return ndk::ScopedFileDescriptor(duplicatedFd.release()); +} + +nn::GeneralResult clone(const common::NativeHandle& handle) { + return common::NativeHandle{ + .fds = NN_TRY(cloneVec(handle.fds)), + .ints = handle.ints, + }; +} + } // namespace nn::GeneralResult clone(const Memory& memory) { - common::NativeHandle nativeHandle; - nativeHandle.ints = memory.handle.ints; - nativeHandle.fds.reserve(memory.handle.fds.size()); - for (const auto& fd : memory.handle.fds) { - const int newFd = dup(fd.get()); - if (newFd < 0) { - return NN_ERROR() << "Couldn't dup a file descriptor"; + switch (memory.getTag()) { + case Memory::Tag::ashmem: { + const auto& ashmem = memory.get(); + auto handle = common::Ashmem{ + .fd = NN_TRY(clone(ashmem.fd)), + .size = ashmem.size, + }; + return Memory::make(std::move(handle)); + } + case Memory::Tag::mappableFile: { + const auto& memFd = memory.get(); + auto handle = common::MappableFile{ + .length = memFd.length, + .prot = memFd.prot, + .fd = NN_TRY(clone(memFd.fd)), + .offset = memFd.offset, + }; + return Memory::make(std::move(handle)); + } + case Memory::Tag::hardwareBuffer: { + const auto& hardwareBuffer = memory.get(); + auto handle = graphics::common::HardwareBuffer{ + .description = hardwareBuffer.description, + .handle = NN_TRY(clone(hardwareBuffer.handle)), + }; + return Memory::make(std::move(handle)); } - nativeHandle.fds.emplace_back(newFd); } - return Memory{ - .handle = std::move(nativeHandle), - .size = memory.size, - .name = memory.name, - }; + return (NN_ERROR() << "Unrecognized Memory::Tag: " << memory.getTag()) + . + operator nn::GeneralResult(); } nn::GeneralResult clone(const RequestMemoryPool& requestPool) { diff --git a/neuralnetworks/aidl/vts/functional/Android.bp b/neuralnetworks/aidl/vts/functional/Android.bp index 7804c2a765..d5b150a934 100644 --- a/neuralnetworks/aidl/vts/functional/Android.bp +++ b/neuralnetworks/aidl/vts/functional/Android.bp @@ -50,9 +50,11 @@ cc_test { ], static_libs: [ "android.hardware.common-V2-ndk_platform", + "android.hardware.graphics.common-V2-ndk_platform", "android.hardware.neuralnetworks-V1-ndk_platform", "android.hidl.allocator@1.0", "android.hidl.memory@1.0", + "libaidlcommonsupport", "libgmock", "libhidlmemory", "libneuralnetworks_generated_test_harness", diff --git a/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp b/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp index 596f8ae58e..e8313f19eb 100644 --- a/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp +++ b/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp @@ -16,6 +16,7 @@ #define LOG_TAG "neuralnetworks_aidl_hal_test" +#include #include #include #include @@ -659,10 +660,26 @@ class MemoryDomainCopyTestBase : public MemoryDomainTestBase { return allocateBuffer(preparedModel, inputIndexes, outputIndexes, {}); } + size_t getSize(const Memory& memory) { + switch (memory.getTag()) { + case Memory::Tag::ashmem: + return memory.get().size; + case Memory::Tag::mappableFile: + return memory.get().length; + case Memory::Tag::hardwareBuffer: { + const auto& hardwareBuffer = memory.get(); + const bool isBlob = + hardwareBuffer.description.format == graphics::common::PixelFormat::BLOB; + return isBlob ? hardwareBuffer.description.width : 0; + } + } + return 0; + } + Memory allocateSharedMemory(uint32_t size) { const auto sharedMemory = nn::createSharedMemory(size).value(); auto memory = utils::convert(sharedMemory).value(); - EXPECT_EQ(memory.size, size); + EXPECT_EQ(getSize(memory), size); return memory; } @@ -690,7 +707,7 @@ class MemoryDomainCopyTestBase : public MemoryDomainTestBase { void initializeDeviceMemory(const std::shared_ptr& buffer) { Memory memory = allocateSharedMemory(kTestOperandDataSize); - ASSERT_EQ(memory.size, kTestOperandDataSize); + ASSERT_EQ(getSize(memory), kTestOperandDataSize); testCopyFrom(buffer, memory, utils::toSigned(kTestOperand.dimensions).value(), ErrorStatus::NONE); } diff --git a/neuralnetworks/aidl/vts/functional/ValidateModel.cpp b/neuralnetworks/aidl/vts/functional/ValidateModel.cpp index 94d3daf6bb..698c054941 100644 --- a/neuralnetworks/aidl/vts/functional/ValidateModel.cpp +++ b/neuralnetworks/aidl/vts/functional/ValidateModel.cpp @@ -259,12 +259,16 @@ template <> size_t sizeForBinder(const Memory& memory) { // This is just a guess. - size_t size = 0; - const NativeHandle& handle = memory.handle; - size += sizeof(decltype(handle.fds)::value_type) * handle.fds.size(); - size += sizeof(decltype(handle.ints)::value_type) * handle.ints.size(); - size += sizeForBinder(memory.name); - size += sizeof(memory); + size_t size = sizeof(Memory); + + // Only hardwareBuffer type memory has dynamic memory that needs to be accounted for (in the + // form of a NativeHandle type). The other other types of memory (MappableFile, Ashmem) use a + // single file descriptor (with metadata) instead. + if (memory.getTag() == Memory::Tag::hardwareBuffer) { + const NativeHandle& handle = memory.get().handle; + size += sizeof(decltype(handle.fds)::value_type) * handle.fds.size(); + size += sizeof(decltype(handle.ints)::value_type) * handle.ints.size(); + } return size; } diff --git a/neuralnetworks/utils/common/src/CommonUtils.cpp b/neuralnetworks/utils/common/src/CommonUtils.cpp index 924ecb2d1b..4d26795d89 100644 --- a/neuralnetworks/utils/common/src/CommonUtils.cpp +++ b/neuralnetworks/utils/common/src/CommonUtils.cpp @@ -89,6 +89,59 @@ void copyPointersToSharedMemory(nn::Model::Subgraph* subgraph, }); } +nn::GeneralResult createNativeHandleFrom(base::unique_fd fd, + const std::vector& ints) { + constexpr size_t kIntMax = std::numeric_limits::max(); + CHECK_LE(ints.size(), kIntMax); + native_handle_t* nativeHandle = native_handle_create(1, static_cast(ints.size())); + if (nativeHandle == nullptr) { + return NN_ERROR() << "Failed to create native_handle"; + } + + nativeHandle->data[0] = fd.release(); + std::copy(ints.begin(), ints.end(), nativeHandle->data + 1); + + hidl_handle handle; + handle.setTo(nativeHandle, /*shouldOwn=*/true); + return handle; +} + +nn::GeneralResult createHidlMemoryFrom(const nn::Memory::Ashmem& memory) { + auto fd = NN_TRY(nn::dupFd(memory.fd)); + auto handle = NN_TRY(createNativeHandleFrom(std::move(fd), {})); + return hidl_memory("ashmem", std::move(handle), memory.size); +} + +nn::GeneralResult createHidlMemoryFrom(const nn::Memory::Fd& memory) { + auto fd = NN_TRY(nn::dupFd(memory.fd)); + + const auto [lowOffsetBits, highOffsetBits] = nn::getIntsFromOffset(memory.offset); + const std::vector ints = {memory.prot, lowOffsetBits, highOffsetBits}; + + auto handle = NN_TRY(createNativeHandleFrom(std::move(fd), ints)); + return hidl_memory("mmap_fd", std::move(handle), memory.size); +} + +nn::GeneralResult createHidlMemoryFrom(const nn::Memory::HardwareBuffer& memory) { + const auto* ahwb = memory.handle.get(); + AHardwareBuffer_Desc bufferDesc; + AHardwareBuffer_describe(ahwb, &bufferDesc); + + const bool isBlob = bufferDesc.format == AHARDWAREBUFFER_FORMAT_BLOB; + const size_t size = isBlob ? bufferDesc.width : 0; + const char* const name = isBlob ? "hardware_buffer_blob" : "hardware_buffer"; + + const native_handle_t* nativeHandle = AHardwareBuffer_getNativeHandle(ahwb); + const hidl_handle hidlHandle(nativeHandle); + hidl_handle copiedHandle(hidlHandle); + + return hidl_memory(name, std::move(copiedHandle), size); +} + +nn::GeneralResult createHidlMemoryFrom(const nn::Memory::Unknown& memory) { + return hidl_memory(memory.name, NN_TRY(hidlHandleFromSharedHandle(memory.handle)), memory.size); +} + } // anonymous namespace nn::Capabilities::OperandPerformanceTable makeQuantized8PerformanceConsistentWithP( @@ -255,27 +308,7 @@ nn::GeneralResult createHidlMemoryFromSharedMemory(const nn::Shared if (memory == nullptr) { return NN_ERROR() << "Memory must be non-empty"; } - if (const auto* handle = std::get_if(&memory->handle)) { - return hidl_memory(memory->name, NN_TRY(hidlHandleFromSharedHandle(*handle)), memory->size); - } - - const auto* ahwb = std::get(memory->handle).get(); - AHardwareBuffer_Desc bufferDesc; - AHardwareBuffer_describe(ahwb, &bufferDesc); - - if (bufferDesc.format == AHARDWAREBUFFER_FORMAT_BLOB) { - CHECK_EQ(memory->size, bufferDesc.width); - CHECK_EQ(memory->name, "hardware_buffer_blob"); - } else { - CHECK_EQ(memory->size, 0u); - CHECK_EQ(memory->name, "hardware_buffer"); - } - - const native_handle_t* nativeHandle = AHardwareBuffer_getNativeHandle(ahwb); - const hidl_handle hidlHandle(nativeHandle); - hidl_handle handle(hidlHandle); - - return hidl_memory(memory->name, std::move(handle), memory->size); + return std::visit([](const auto& x) { return createHidlMemoryFrom(x); }, memory->handle); } static uint32_t roundUpToMultiple(uint32_t value, uint32_t multiple) { @@ -283,14 +316,53 @@ static uint32_t roundUpToMultiple(uint32_t value, uint32_t multiple) { } nn::GeneralResult createSharedMemoryFromHidlMemory(const hidl_memory& memory) { - CHECK_LE(memory.size(), std::numeric_limits::max()); + CHECK_LE(memory.size(), std::numeric_limits::max()); + if (!memory.valid()) { + return NN_ERROR() << "Unable to convert invalid hidl_memory"; + } + + if (memory.name() == "ashmem") { + if (memory.handle()->numFds != 1) { + return NN_ERROR() << "Unable to convert invalid ashmem memory object with " + << memory.handle()->numFds << " numFds, but expected 1"; + } + if (memory.handle()->numInts != 0) { + return NN_ERROR() << "Unable to convert invalid ashmem memory object with " + << memory.handle()->numInts << " numInts, but expected 0"; + } + auto handle = nn::Memory::Ashmem{ + .fd = NN_TRY(nn::dupFd(memory.handle()->data[0])), + .size = static_cast(memory.size()), + }; + return std::make_shared(nn::Memory{.handle = std::move(handle)}); + } + + if (memory.name() == "mmap_fd") { + if (memory.handle()->numFds != 1) { + return NN_ERROR() << "Unable to convert invalid mmap_fd memory object with " + << memory.handle()->numFds << " numFds, but expected 1"; + } + if (memory.handle()->numInts != 3) { + return NN_ERROR() << "Unable to convert invalid mmap_fd memory object with " + << memory.handle()->numInts << " numInts, but expected 3"; + } + + const int fd = memory.handle()->data[0]; + const int prot = memory.handle()->data[1]; + const int lower = memory.handle()->data[2]; + const int higher = memory.handle()->data[3]; + const size_t offset = nn::getOffsetFromInts(lower, higher); + + return nn::createSharedMemoryFromFd(static_cast(memory.size()), prot, fd, offset); + } if (memory.name() != "hardware_buffer_blob") { - return std::make_shared(nn::Memory{ + auto handle = nn::Memory::Unknown{ .handle = NN_TRY(sharedHandleFromNativeHandle(memory.handle())), - .size = static_cast(memory.size()), + .size = static_cast(memory.size()), .name = memory.name(), - }); + }; + return std::make_shared(nn::Memory{.handle = std::move(handle)}); } const auto size = memory.size(); @@ -328,11 +400,7 @@ nn::GeneralResult createSharedMemoryFromHidlMemory(const hidl_ << "Can't create AHardwareBuffer from handle. Error: " << status; } - return std::make_shared(nn::Memory{ - .handle = nn::HardwareBufferHandle(hardwareBuffer, /*takeOwnership=*/true), - .size = static_cast(memory.size()), - .name = memory.name(), - }); + return nn::createSharedMemoryFromAHWB(hardwareBuffer, /*takeOwnership=*/true); } nn::GeneralResult hidlHandleFromSharedHandle(const nn::Handle& handle) { -- GitLab From b64997029c301d859cacfd1de9a11e0ef938ac87 Mon Sep 17 00:00:00 2001 From: Cliff Wu Date: Tue, 9 Mar 2021 19:10:50 +0800 Subject: [PATCH 593/790] DynamicCamera: Add new hidl interface ICameraInjectionSession for injection camera - The interface is inherited from ICameraDeviceSession 3.7. - Adding configureInjectionStreams() function can send the stream configuration of the previous camera and other required information (such as the source of the time stamp of the previous camera and the last time stamp, etc) to the dynamic camera HAL. Test: Camera VTS Bug: 171021757 Change-Id: I5744f32e187db51c05d40b85c0ebd453d1a53518 --- camera/device/3.7/Android.bp | 1 + camera/device/3.7/ICameraInjectionSession.hal | 85 +++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 camera/device/3.7/ICameraInjectionSession.hal diff --git a/camera/device/3.7/Android.bp b/camera/device/3.7/Android.bp index 15c1b5ced5..be08e91aed 100644 --- a/camera/device/3.7/Android.bp +++ b/camera/device/3.7/Android.bp @@ -16,6 +16,7 @@ hidl_interface { "types.hal", "ICameraDevice.hal", "ICameraDeviceSession.hal", + "ICameraInjectionSession.hal", ], interfaces: [ "android.hardware.camera.common@1.0", diff --git a/camera/device/3.7/ICameraInjectionSession.hal b/camera/device/3.7/ICameraInjectionSession.hal new file mode 100644 index 0000000000..f5797c3b17 --- /dev/null +++ b/camera/device/3.7/ICameraInjectionSession.hal @@ -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.camera.device@3.7; + +import android.hardware.camera.common@1.0::Status; +import @3.2::BufferCache; +import @3.2::CameraMetadata; +import @3.5::StreamConfiguration; +import @3.6::HalStreamConfiguration; +import @3.7::ICameraDeviceSession; + +/** + * Injection Camera device active session interface. + * + * When an external camera is injected to replace the internal camera session, the + * injection session will be established in camera framework, and then + * configureInjectionStreams() will be called to ask the external camera to + * configure itself to match the stream configuration of the internal camera. + * + * Camera framework is responsible to close the injection session once the client + * switch back to internal camera streaming. + * + * If the external camera cannot support the configuration ILLEGAL_ARGUMENT will + * be returned. + */ +interface ICameraInjectionSession extends @3.7::ICameraDeviceSession { + /** + * configureInjectionStreams: + * + * Identical to @3.7::ICameraDeviceSession.configureStreams_3_7, except that: + * + * @param requestedConfiguration + * The current stream configuration of the internal camera session and + * the injection camera must follow the configuration without overriding + * any part of it. + * @param characteristics + * The characteristics of internal camera contains a list of keys so that + * the stream continuity can be maintained after the external camera is + * injected. + * + * @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: + * - 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 + * 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 + * configureInjectionStreams call. + */ + configureInjectionStreams(StreamConfiguration requestedConfiguration, + CameraMetadata characteristics) generates (Status status); +}; -- GitLab From 4da494503975e85f1c89d669e9c796ef78223360 Mon Sep 17 00:00:00 2001 From: Andy Hung Date: Thu, 8 Apr 2021 18:36:17 -0700 Subject: [PATCH 594/790] audio: Add device constants for HDMI EARC Implementation check by grep -E -r "HDMI_ARC|HDMI_EARC" . Test: atest AudioDeviceInfoTest Bug: 131385398 Bug: 151781316 Change-Id: Idfe27b468a9f09770a31b6b58d83de77bebc6c80 --- audio/7.0/config/api/current.txt | 2 ++ audio/7.0/config/audio_policy_configuration.xsd | 2 ++ .../include/android_audio_policy_configuration_V7_0-enums.h | 2 ++ 3 files changed, 6 insertions(+) diff --git a/audio/7.0/config/api/current.txt b/audio/7.0/config/api/current.txt index 0bddd759e1..e61ddcbd1c 100644 --- a/audio/7.0/config/api/current.txt +++ b/audio/7.0/config/api/current.txt @@ -104,6 +104,7 @@ package android.audio.policy.configuration.V7_0 { enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_FM_TUNER; enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_HDMI; enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_HDMI_ARC; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_HDMI_EARC; enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_IP; enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_LINE; enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_IN_LOOPBACK; @@ -138,6 +139,7 @@ package android.audio.policy.configuration.V7_0 { enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_FM; enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_HDMI; enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_HDMI_ARC; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_HDMI_EARC; enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_HEARING_AID; enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_IP; enum_constant public static final android.audio.policy.configuration.V7_0.AudioDevice AUDIO_DEVICE_OUT_LINE; diff --git a/audio/7.0/config/audio_policy_configuration.xsd b/audio/7.0/config/audio_policy_configuration.xsd index a06e0278c7..77cff913a9 100644 --- a/audio/7.0/config/audio_policy_configuration.xsd +++ b/audio/7.0/config/audio_policy_configuration.xsd @@ -253,6 +253,7 @@ + @@ -304,6 +305,7 @@ + diff --git a/audio/common/7.0/enums/include/android_audio_policy_configuration_V7_0-enums.h b/audio/common/7.0/enums/include/android_audio_policy_configuration_V7_0-enums.h index 7d83556895..723d7f8d8b 100644 --- a/audio/common/7.0/enums/include/android_audio_policy_configuration_V7_0-enums.h +++ b/audio/common/7.0/enums/include/android_audio_policy_configuration_V7_0-enums.h @@ -155,6 +155,7 @@ static inline bool isOutputDevice(AudioDevice device) { case AudioDevice::AUDIO_DEVICE_OUT_TELEPHONY_TX: case AudioDevice::AUDIO_DEVICE_OUT_LINE: case AudioDevice::AUDIO_DEVICE_OUT_HDMI_ARC: + case AudioDevice::AUDIO_DEVICE_OUT_HDMI_EARC: case AudioDevice::AUDIO_DEVICE_OUT_SPDIF: case AudioDevice::AUDIO_DEVICE_OUT_FM: case AudioDevice::AUDIO_DEVICE_OUT_AUX_LINE: @@ -197,6 +198,7 @@ static inline bool isOutputDevice(AudioDevice device) { case AudioDevice::AUDIO_DEVICE_IN_USB_HEADSET: case AudioDevice::AUDIO_DEVICE_IN_BLUETOOTH_BLE: case AudioDevice::AUDIO_DEVICE_IN_HDMI_ARC: + case AudioDevice::AUDIO_DEVICE_IN_HDMI_EARC: case AudioDevice::AUDIO_DEVICE_IN_ECHO_REFERENCE: case AudioDevice::AUDIO_DEVICE_IN_BLE_HEADSET: case AudioDevice::AUDIO_DEVICE_IN_DEFAULT: -- GitLab From f10451b8fcc371f01fd7191ec320010b785ef22a Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Fri, 9 Apr 2021 12:51:00 -0700 Subject: [PATCH 595/790] hal(wifi): Replace rpius@ with kumaranand@ in OWNERS Bug: 184966495 Test: N/A Change-Id: Ib4cc2cc8479317b987edcdbcce0de4f699720cc3 --- wifi/1.0/vts/OWNERS | 2 +- wifi/1.1/vts/OWNERS | 2 +- wifi/1.2/vts/OWNERS | 2 +- wifi/1.3/vts/OWNERS | 2 +- wifi/1.4/vts/OWNERS | 2 +- wifi/1.5/default/OWNERS | 2 +- wifi/1.5/vts/OWNERS | 2 +- wifi/hostapd/1.0/vts/OWNERS | 2 +- wifi/hostapd/1.1/vts/OWNERS | 2 +- wifi/hostapd/1.2/vts/OWNERS | 2 +- wifi/hostapd/1.3/vts/OWNERS | 2 +- wifi/supplicant/1.2/vts/OWNERS | 2 +- wifi/supplicant/1.3/vts/OWNERS | 2 +- wifi/supplicant/1.4/vts/OWNERS | 2 +- 14 files changed, 14 insertions(+), 14 deletions(-) diff --git a/wifi/1.0/vts/OWNERS b/wifi/1.0/vts/OWNERS index 8bfb14882c..e7b2fc5284 100644 --- a/wifi/1.0/vts/OWNERS +++ b/wifi/1.0/vts/OWNERS @@ -1,2 +1,2 @@ -rpius@google.com +kumaranand@google.com etancohen@google.com diff --git a/wifi/1.1/vts/OWNERS b/wifi/1.1/vts/OWNERS index 8bfb14882c..e7b2fc5284 100644 --- a/wifi/1.1/vts/OWNERS +++ b/wifi/1.1/vts/OWNERS @@ -1,2 +1,2 @@ -rpius@google.com +kumaranand@google.com etancohen@google.com diff --git a/wifi/1.2/vts/OWNERS b/wifi/1.2/vts/OWNERS index 8bfb14882c..e7b2fc5284 100644 --- a/wifi/1.2/vts/OWNERS +++ b/wifi/1.2/vts/OWNERS @@ -1,2 +1,2 @@ -rpius@google.com +kumaranand@google.com etancohen@google.com diff --git a/wifi/1.3/vts/OWNERS b/wifi/1.3/vts/OWNERS index 8bfb14882c..e7b2fc5284 100644 --- a/wifi/1.3/vts/OWNERS +++ b/wifi/1.3/vts/OWNERS @@ -1,2 +1,2 @@ -rpius@google.com +kumaranand@google.com etancohen@google.com diff --git a/wifi/1.4/vts/OWNERS b/wifi/1.4/vts/OWNERS index 8bfb14882c..e7b2fc5284 100644 --- a/wifi/1.4/vts/OWNERS +++ b/wifi/1.4/vts/OWNERS @@ -1,2 +1,2 @@ -rpius@google.com +kumaranand@google.com etancohen@google.com diff --git a/wifi/1.5/default/OWNERS b/wifi/1.5/default/OWNERS index 8bfb14882c..e7b2fc5284 100644 --- a/wifi/1.5/default/OWNERS +++ b/wifi/1.5/default/OWNERS @@ -1,2 +1,2 @@ -rpius@google.com +kumaranand@google.com etancohen@google.com diff --git a/wifi/1.5/vts/OWNERS b/wifi/1.5/vts/OWNERS index 8bfb14882c..e7b2fc5284 100644 --- a/wifi/1.5/vts/OWNERS +++ b/wifi/1.5/vts/OWNERS @@ -1,2 +1,2 @@ -rpius@google.com +kumaranand@google.com etancohen@google.com diff --git a/wifi/hostapd/1.0/vts/OWNERS b/wifi/hostapd/1.0/vts/OWNERS index 8bfb14882c..e7b2fc5284 100644 --- a/wifi/hostapd/1.0/vts/OWNERS +++ b/wifi/hostapd/1.0/vts/OWNERS @@ -1,2 +1,2 @@ -rpius@google.com +kumaranand@google.com etancohen@google.com diff --git a/wifi/hostapd/1.1/vts/OWNERS b/wifi/hostapd/1.1/vts/OWNERS index 8bfb14882c..e7b2fc5284 100644 --- a/wifi/hostapd/1.1/vts/OWNERS +++ b/wifi/hostapd/1.1/vts/OWNERS @@ -1,2 +1,2 @@ -rpius@google.com +kumaranand@google.com etancohen@google.com diff --git a/wifi/hostapd/1.2/vts/OWNERS b/wifi/hostapd/1.2/vts/OWNERS index 8bfb14882c..e7b2fc5284 100644 --- a/wifi/hostapd/1.2/vts/OWNERS +++ b/wifi/hostapd/1.2/vts/OWNERS @@ -1,2 +1,2 @@ -rpius@google.com +kumaranand@google.com etancohen@google.com diff --git a/wifi/hostapd/1.3/vts/OWNERS b/wifi/hostapd/1.3/vts/OWNERS index 8bfb14882c..e7b2fc5284 100644 --- a/wifi/hostapd/1.3/vts/OWNERS +++ b/wifi/hostapd/1.3/vts/OWNERS @@ -1,2 +1,2 @@ -rpius@google.com +kumaranand@google.com etancohen@google.com diff --git a/wifi/supplicant/1.2/vts/OWNERS b/wifi/supplicant/1.2/vts/OWNERS index 8bfb14882c..e7b2fc5284 100644 --- a/wifi/supplicant/1.2/vts/OWNERS +++ b/wifi/supplicant/1.2/vts/OWNERS @@ -1,2 +1,2 @@ -rpius@google.com +kumaranand@google.com etancohen@google.com diff --git a/wifi/supplicant/1.3/vts/OWNERS b/wifi/supplicant/1.3/vts/OWNERS index 8bfb14882c..e7b2fc5284 100644 --- a/wifi/supplicant/1.3/vts/OWNERS +++ b/wifi/supplicant/1.3/vts/OWNERS @@ -1,2 +1,2 @@ -rpius@google.com +kumaranand@google.com etancohen@google.com diff --git a/wifi/supplicant/1.4/vts/OWNERS b/wifi/supplicant/1.4/vts/OWNERS index 8bfb14882c..e7b2fc5284 100644 --- a/wifi/supplicant/1.4/vts/OWNERS +++ b/wifi/supplicant/1.4/vts/OWNERS @@ -1,2 +1,2 @@ -rpius@google.com +kumaranand@google.com etancohen@google.com -- GitLab From 06fa69e2469df41977eeab2961b4e3bc82f55e75 Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Fri, 9 Apr 2021 09:56:25 -0700 Subject: [PATCH 596/790] Extend 1.0 dynamic config reader to read 1.1 Tuner HAL types Test: atest VtsHalTvTunerV1_1TargetTest Test: atest VtsHalTvTunerV1_0TargetTest Bug: 182519645 CTS-Coverage-Bug: 184077478 Change-Id: I0438fff48a6a763b88ed20e34d8ace66a6211302 --- .../functional/VtsHalTvTunerV1_0TargetTest.h | 3 +- .../VtsHalTvTunerV1_0TestConfigurations.h | 34 +- tv/tuner/1.1/vts/functional/Android.bp | 12 + tv/tuner/1.1/vts/functional/FrontendTests.cpp | 57 ++-- tv/tuner/1.1/vts/functional/FrontendTests.h | 12 +- .../VtsHalTvTunerV1_1TargetTest.cpp | 104 +++--- .../functional/VtsHalTvTunerV1_1TargetTest.h | 24 +- .../VtsHalTvTunerV1_1TestConfigurations.h | 315 ++++++------------ ...eader.h => TunerTestingConfigReaderV1_0.h} | 138 ++++++-- .../config/TunerTestingConfigReaderV1_1.h | 185 ++++++++++ tv/tuner/config/api/current.txt | 54 +++ ...ig.xml => sample_tuner_vts_config_1_0.xml} | 0 .../config/sample_tuner_vts_config_1_1.xml | 158 +++++++++ .../tuner_testing_dynamic_configuration.xsd | 74 +++- 14 files changed, 813 insertions(+), 357 deletions(-) rename tv/tuner/config/{TunerTestingConfigReader.h => TunerTestingConfigReaderV1_0.h} (84%) create mode 100644 tv/tuner/config/TunerTestingConfigReaderV1_1.h rename tv/tuner/config/{sample_tuner_vts_config.xml => sample_tuner_vts_config_1_0.xml} (100%) create mode 100644 tv/tuner/config/sample_tuner_vts_config_1_1.xml diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h index e2406042df..8358291cf3 100644 --- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h +++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h @@ -32,7 +32,8 @@ static AssertionResult success() { namespace { bool initConfiguration() { - if (!TunerTestingConfigReader::checkConfigFileExists()) { + TunerTestingConfigReader1_0::setConfigFilePath(configFilePath); + if (!TunerTestingConfigReader1_0::checkConfigFileExists()) { return false; } initFrontendConfig(); diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h index 65f8615ad8..a1597c7e95 100644 --- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h +++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h @@ -21,7 +21,7 @@ #include #include -#include "../../../config/TunerTestingConfigReader.h" +#include "../../../config/TunerTestingConfigReaderV1_0.h" using android::hardware::tv::tuner::V1_0::DemuxFilterMainType; using android::hardware::tv::tuner::V1_0::DemuxTsFilterType; @@ -39,6 +39,8 @@ using namespace android::media::tuner::testing::configuration::V1_0; const uint32_t FMQ_SIZE_4M = 0x400000; const uint32_t FMQ_SIZE_16M = 0x1000000; +const string configFilePath = "/vendor/etc/tuner_vts_config_1_0.xml"; + #define FILTER_MAIN_TYPE_BIT_COUNT 5 // Hardware configs @@ -85,7 +87,7 @@ inline void initFrontendConfig() { frontendMap[defaultFeId].isSoftwareFe = true; // Read customized config - TunerTestingConfigReader::readFrontendConfig1_0(frontendMap); + TunerTestingConfigReader1_0::readFrontendConfig1_0(frontendMap); }; inline void initFilterConfig() { @@ -107,44 +109,44 @@ inline void initFilterConfig() { filterMap[defaultAudioFilterId].settings.ts().filterSettings.av({.isPassthrough = false}); // Read customized config - TunerTestingConfigReader::readFilterConfig1_0(filterMap); + TunerTestingConfigReader1_0::readFilterConfig1_0(filterMap); }; /** Config all the dvrs that would be used in the tests */ inline void initDvrConfig() { // Read customized config - TunerTestingConfigReader::readDvrConfig1_0(dvrMap); + TunerTestingConfigReader1_0::readDvrConfig1_0(dvrMap); }; /** Config all the lnbs that would be used in the tests */ inline void initLnbConfig() { // Read customized config - TunerTestingConfigReader::readLnbConfig1_0(lnbMap); - TunerTestingConfigReader::readDiseqcMessages(diseqcMsgMap); + TunerTestingConfigReader1_0::readLnbConfig1_0(lnbMap); + TunerTestingConfigReader1_0::readDiseqcMessages(diseqcMsgMap); }; /** Config all the time filters that would be used in the tests */ inline void initTimeFilterConfig() { // Read customized config - TunerTestingConfigReader::readTimeFilterConfig1_0(timeFilterMap); + TunerTestingConfigReader1_0::readTimeFilterConfig1_0(timeFilterMap); }; /** Config all the descramblers that would be used in the tests */ inline void initDescramblerConfig() { // Read customized config - TunerTestingConfigReader::readDescramblerConfig1_0(descramblerMap); + TunerTestingConfigReader1_0::readDescramblerConfig1_0(descramblerMap); }; /** Read the vendor configurations of which hardware to use for each test cases/data flows */ inline void connectHardwaresToTestCases() { - TunerTestingConfigReader::connectLiveBroadcast(live); - TunerTestingConfigReader::connectScan(scan); - TunerTestingConfigReader::connectDvrPlayback(playback); - TunerTestingConfigReader::connectDvrRecord(record); - TunerTestingConfigReader::connectDescrambling(descrambling); - TunerTestingConfigReader::connectLnbLive(lnbLive); - TunerTestingConfigReader::connectLnbRecord(lnbRecord); - TunerTestingConfigReader::connectTimeFilter(timeFilter); + TunerTestingConfigReader1_0::connectLiveBroadcast(live); + TunerTestingConfigReader1_0::connectScan(scan); + TunerTestingConfigReader1_0::connectDvrPlayback(playback); + TunerTestingConfigReader1_0::connectDvrRecord(record); + TunerTestingConfigReader1_0::connectDescrambling(descrambling); + TunerTestingConfigReader1_0::connectLnbLive(lnbLive); + TunerTestingConfigReader1_0::connectLnbRecord(lnbRecord); + TunerTestingConfigReader1_0::connectTimeFilter(timeFilter); }; inline bool validateConnections() { diff --git a/tv/tuner/1.1/vts/functional/Android.bp b/tv/tuner/1.1/vts/functional/Android.bp index 92e587b699..ac835a4382 100644 --- a/tv/tuner/1.1/vts/functional/Android.bp +++ b/tv/tuner/1.1/vts/functional/Android.bp @@ -33,6 +33,15 @@ cc_test { "FrontendTests.cpp", "VtsHalTvTunerV1_1TargetTest.cpp", ], + generated_headers: [ + "tuner_testing_dynamic_configuration_V1_0_enums", + "tuner_testing_dynamic_configuration_V1_0_parser", + ], + generated_sources: [ + "tuner_testing_dynamic_configuration_V1_0_enums", + "tuner_testing_dynamic_configuration_V1_0_parser", + ], + header_libs: ["libxsdc-utils"], static_libs: [ "android.hardware.cas@1.0", "android.hardware.cas@1.1", @@ -48,9 +57,12 @@ cc_test { ], shared_libs: [ "libbinder", + "libxml2", ], data: [ + ":tuner_frontend_input_ts", ":tuner_frontend_input_es", + ":tuner_testing_dynamic_configuration_V1_0", ], test_suites: [ "general-tests", diff --git a/tv/tuner/1.1/vts/functional/FrontendTests.cpp b/tv/tuner/1.1/vts/functional/FrontendTests.cpp index 0fd5be0664..9c575ff782 100644 --- a/tv/tuner/1.1/vts/functional/FrontendTests.cpp +++ b/tv/tuner/1.1/vts/functional/FrontendTests.cpp @@ -121,7 +121,7 @@ void FrontendCallback::tuneTestOnLock(sp& frontend, FrontendSettings mLockMsgReceived = false; } -void FrontendCallback::scanTest(sp& frontend, FrontendConfig config, +void FrontendCallback::scanTest(sp& frontend, FrontendConfig1_1 config, FrontendScanType type) { sp frontend_1_1; frontend_1_1 = android::hardware::tv::tuner::V1_1::IFrontend::castFrom(frontend); @@ -130,7 +130,7 @@ void FrontendCallback::scanTest(sp& frontend, FrontendConfig config, return; } - uint32_t targetFrequency = getTargetFrequency(config.settings); + uint32_t targetFrequency = getTargetFrequency(config.config1_0.settings); if (type == FrontendScanType::SCAN_BLIND) { // reset the frequency in the scan configuration to test blind scan. The settings param of // passed in means the real input config on the transponder connected to the DUT. @@ -139,7 +139,7 @@ void FrontendCallback::scanTest(sp& frontend, FrontendConfig config, resetBlindScanStartingFrequency(config, targetFrequency - 100); } - Result result = frontend_1_1->scan_1_1(config.settings, type, config.settingsExt1_1); + Result result = frontend_1_1->scan_1_1(config.config1_0.settings, type, config.settingsExt1_1); EXPECT_TRUE(result == Result::SUCCESS); bool scanMsgLockedReceived = false; @@ -159,7 +159,8 @@ wait: if (mScanMessageType != FrontendScanMessageType::END) { if (mScanMessageType == FrontendScanMessageType::LOCKED) { scanMsgLockedReceived = true; - Result result = frontend_1_1->scan_1_1(config.settings, type, config.settingsExt1_1); + Result result = + frontend_1_1->scan_1_1(config.config1_0.settings, type, config.settingsExt1_1); EXPECT_TRUE(result == Result::SUCCESS); } @@ -207,35 +208,35 @@ uint32_t FrontendCallback::getTargetFrequency(FrontendSettings settings) { } } -void FrontendCallback::resetBlindScanStartingFrequency(FrontendConfig& config, +void FrontendCallback::resetBlindScanStartingFrequency(FrontendConfig1_1& config, uint32_t resetingFreq) { - switch (config.settings.getDiscriminator()) { + switch (config.config1_0.settings.getDiscriminator()) { case FrontendSettings::hidl_discriminator::analog: - config.settings.analog().frequency = resetingFreq; + config.config1_0.settings.analog().frequency = resetingFreq; break; case FrontendSettings::hidl_discriminator::atsc: - config.settings.atsc().frequency = resetingFreq; + config.config1_0.settings.atsc().frequency = resetingFreq; break; case FrontendSettings::hidl_discriminator::atsc3: - config.settings.atsc3().frequency = resetingFreq; + config.config1_0.settings.atsc3().frequency = resetingFreq; break; case FrontendSettings::hidl_discriminator::dvbc: - config.settings.dvbc().frequency = resetingFreq; + config.config1_0.settings.dvbc().frequency = resetingFreq; break; case FrontendSettings::hidl_discriminator::dvbs: - config.settings.dvbs().frequency = resetingFreq; + config.config1_0.settings.dvbs().frequency = resetingFreq; break; case FrontendSettings::hidl_discriminator::dvbt: - config.settings.dvbt().frequency = resetingFreq; + config.config1_0.settings.dvbt().frequency = resetingFreq; break; case FrontendSettings::hidl_discriminator::isdbs: - config.settings.isdbs().frequency = resetingFreq; + config.config1_0.settings.isdbs().frequency = resetingFreq; break; case FrontendSettings::hidl_discriminator::isdbs3: - config.settings.isdbs3().frequency = resetingFreq; + config.config1_0.settings.isdbs3().frequency = resetingFreq; break; case FrontendSettings::hidl_discriminator::isdbt: - config.settings.isdbt().frequency = resetingFreq; + config.config1_0.settings.isdbt().frequency = resetingFreq; break; } } @@ -274,11 +275,11 @@ AssertionResult FrontendTests::setFrontendCallback() { return AssertionResult(callbackStatus.isOk()); } -AssertionResult FrontendTests::scanFrontend(FrontendConfig config, FrontendScanType type) { +AssertionResult FrontendTests::scanFrontend(FrontendConfig1_1 config, FrontendScanType type) { EXPECT_TRUE(mFrontendCallback) << "test with openFrontendById/setFrontendCallback/getFrontendInfo first."; - EXPECT_TRUE(mFrontendInfo.type == config.type) + EXPECT_TRUE(mFrontendInfo.type == config.config1_0.type) << "FrontendConfig does not match the frontend info of the given id."; mFrontendCallback->scanTest(mFrontend, config, type); @@ -426,14 +427,14 @@ void FrontendTests::verifyFrontendStatusExt1_1(vector ASSERT_TRUE(status == Result::SUCCESS); } -AssertionResult FrontendTests::tuneFrontend(FrontendConfig config, bool testWithDemux) { +AssertionResult FrontendTests::tuneFrontend(FrontendConfig1_1 config, bool testWithDemux) { EXPECT_TRUE(mFrontendCallback) << "test with openFrontendById/setFrontendCallback/getFrontendInfo first."; - EXPECT_TRUE(mFrontendInfo.type == config.type) + EXPECT_TRUE(mFrontendInfo.type == config.config1_0.type) << "FrontendConfig does not match the frontend info of the given id."; - mIsSoftwareFe = config.isSoftwareFe; + mIsSoftwareFe = config.config1_0.isSoftwareFe; bool result = true; if (mIsSoftwareFe && testWithDemux) { result &= mDvrTests.openDvrInDemux(mDvrConfig.type, mDvrConfig.bufferSize) == success(); @@ -446,7 +447,7 @@ AssertionResult FrontendTests::tuneFrontend(FrontendConfig config, bool testWith return failure(); } } - mFrontendCallback->tuneTestOnLock(mFrontend, config.settings, config.settingsExt1_1); + mFrontendCallback->tuneTestOnLock(mFrontend, config.config1_0.settings, config.settingsExt1_1); return AssertionResult(true); } @@ -484,12 +485,9 @@ void FrontendTests::getFrontendIdByType(FrontendType feType, uint32_t& feId) { feId = INVALID_ID; } -void FrontendTests::tuneTest(FrontendConfig frontendConf) { - if (!frontendConf.enable) { - return; - } +void FrontendTests::tuneTest(FrontendConfig1_1 frontendConf) { uint32_t feId; - getFrontendIdByType(frontendConf.type, feId); + getFrontendIdByType(frontendConf.config1_0.type, feId); ASSERT_TRUE(feId != INVALID_ID); ASSERT_TRUE(openFrontendById(feId)); ASSERT_TRUE(setFrontendCallback()); @@ -503,12 +501,9 @@ void FrontendTests::tuneTest(FrontendConfig frontendConf) { ASSERT_TRUE(closeFrontend()); } -void FrontendTests::scanTest(FrontendConfig frontendConf, FrontendScanType scanType) { - if (!frontendConf.enable) { - return; - } +void FrontendTests::scanTest(FrontendConfig1_1 frontendConf, FrontendScanType scanType) { uint32_t feId; - getFrontendIdByType(frontendConf.type, feId); + getFrontendIdByType(frontendConf.config1_0.type, feId); ASSERT_TRUE(feId != INVALID_ID); ASSERT_TRUE(openFrontendById(feId)); ASSERT_TRUE(setFrontendCallback()); diff --git a/tv/tuner/1.1/vts/functional/FrontendTests.h b/tv/tuner/1.1/vts/functional/FrontendTests.h index 01d2007f3d..3687389571 100644 --- a/tv/tuner/1.1/vts/functional/FrontendTests.h +++ b/tv/tuner/1.1/vts/functional/FrontendTests.h @@ -79,11 +79,11 @@ class FrontendCallback : public IFrontendCallback { void tuneTestOnLock(sp& frontend, FrontendSettings settings, FrontendSettingsExt1_1 settingsExt1_1); - void scanTest(sp& frontend, FrontendConfig config, FrontendScanType type); + void scanTest(sp& frontend, FrontendConfig1_1 config, FrontendScanType type); // Helper methods uint32_t getTargetFrequency(FrontendSettings settings); - void resetBlindScanStartingFrequency(FrontendConfig& config, uint32_t resetingFreq); + void resetBlindScanStartingFrequency(FrontendConfig1_1& config, uint32_t resetingFreq); private: void readFrontendScanMessageExt1_1Modulation(FrontendModulation modulation); @@ -114,9 +114,9 @@ class FrontendTests { AssertionResult getFrontendInfo(uint32_t frontendId); AssertionResult openFrontendById(uint32_t frontendId); AssertionResult setFrontendCallback(); - AssertionResult scanFrontend(FrontendConfig config, FrontendScanType type); + AssertionResult scanFrontend(FrontendConfig1_1 config, FrontendScanType type); AssertionResult stopScanFrontend(); - AssertionResult tuneFrontend(FrontendConfig config, bool testWithDemux); + AssertionResult tuneFrontend(FrontendConfig1_1 config, bool testWithDemux); void verifyFrontendStatusExt1_1(vector statusTypes, vector expectStatuses); AssertionResult stopTuneFrontend(bool testWithDemux); @@ -127,8 +127,8 @@ class FrontendTests { AssertionResult unlinkCiCam(uint32_t ciCamId); void getFrontendIdByType(FrontendType feType, uint32_t& feId); - void tuneTest(FrontendConfig frontendConf); - void scanTest(FrontendConfig frontend, FrontendScanType type); + void tuneTest(FrontendConfig1_1 frontendConf); + void scanTest(FrontendConfig1_1 frontend, FrontendScanType type); void getFrontendDtmbCapsTest(); void setDvrTests(DvrTests dvrTests) { mDvrTests = dvrTests; } diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp index 97fb90db69..10808614f5 100644 --- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp @@ -26,34 +26,31 @@ AssertionResult TunerRecordHidlTest::filterDataOutputTest() { return filterDataOutputTestBase(mFilterTests); } -void TunerFilterHidlTest::configSingleFilterInDemuxTest(FilterConfig filterConf, - FrontendConfig frontendConf) { - if (!frontendConf.enable) { - return; - } - +void TunerFilterHidlTest::configSingleFilterInDemuxTest(FilterConfig1_1 filterConf, + FrontendConfig1_1 frontendConf) { uint32_t feId; uint32_t demuxId; sp demux; uint64_t filterId; - mFrontendTests.getFrontendIdByType(frontendConf.type, feId); + mFrontendTests.getFrontendIdByType(frontendConf.config1_0.type, feId); ASSERT_TRUE(feId != INVALID_ID); ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); ASSERT_TRUE(mFrontendTests.setFrontendCallback()); ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); mFilterTests.setDemux(demux); - ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize)); + ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.config1_0.type, + filterConf.config1_0.bufferSize)); ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(filterId)); - ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId)); - if (filterConf.type.mainType == DemuxFilterMainType::IP) { + ASSERT_TRUE(mFilterTests.configFilter(filterConf.config1_0.settings, filterId)); + if (filterConf.config1_0.type.mainType == DemuxFilterMainType::IP) { ASSERT_TRUE(mFilterTests.configIpFilterCid(filterConf.ipCid, filterId)); } if (filterConf.monitorEventTypes > 0) { ASSERT_TRUE(mFilterTests.configureMonitorEvent(filterId, filterConf.monitorEventTypes)); } - ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterConf.getMqDesc)); + ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterConf.config1_0.getMqDesc)); ASSERT_TRUE(mFilterTests.startFilter(filterId)); ASSERT_TRUE(mFilterTests.stopFilter(filterId)); ASSERT_TRUE(mFilterTests.closeFilter(filterId)); @@ -61,19 +58,15 @@ void TunerFilterHidlTest::configSingleFilterInDemuxTest(FilterConfig filterConf, ASSERT_TRUE(mFrontendTests.closeFrontend()); } -void TunerFilterHidlTest::reconfigSingleFilterInDemuxTest(FilterConfig filterConf, - FilterConfig filterReconf, - FrontendConfig frontendConf) { - if (!frontendConf.enable) { - return; - } - +void TunerFilterHidlTest::reconfigSingleFilterInDemuxTest(FilterConfig1_1 filterConf, + FilterConfig1_1 filterReconf, + FrontendConfig1_1 frontendConf) { uint32_t feId; uint32_t demuxId; sp demux; uint64_t filterId; - mFrontendTests.getFrontendIdByType(frontendConf.type, feId); + mFrontendTests.getFrontendIdByType(frontendConf.config1_0.type, feId); ASSERT_TRUE(feId != INVALID_ID); ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); ASSERT_TRUE(mFrontendTests.setFrontendCallback()); @@ -81,13 +74,14 @@ void TunerFilterHidlTest::reconfigSingleFilterInDemuxTest(FilterConfig filterCon ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); mFrontendTests.setDemux(demux); mFilterTests.setDemux(demux); - ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize)); + ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.config1_0.type, + filterConf.config1_0.bufferSize)); ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(filterId)); - ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId)); - ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterConf.getMqDesc)); + ASSERT_TRUE(mFilterTests.configFilter(filterConf.config1_0.settings, filterId)); + ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterConf.config1_0.getMqDesc)); ASSERT_TRUE(mFilterTests.startFilter(filterId)); ASSERT_TRUE(mFilterTests.stopFilter(filterId)); - ASSERT_TRUE(mFilterTests.configFilter(filterReconf.settings, filterId)); + ASSERT_TRUE(mFilterTests.configFilter(filterReconf.config1_0.settings, filterId)); ASSERT_TRUE(mFilterTests.startFilter(filterId)); ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/)); ASSERT_TRUE(mFilterTests.startIdTest(filterId)); @@ -98,18 +92,14 @@ void TunerFilterHidlTest::reconfigSingleFilterInDemuxTest(FilterConfig filterCon ASSERT_TRUE(mFrontendTests.closeFrontend()); } -void TunerBroadcastHidlTest::mediaFilterUsingSharedMemoryTest(FilterConfig filterConf, - FrontendConfig frontendConf) { - if (!frontendConf.enable) { - return; - } - +void TunerBroadcastHidlTest::mediaFilterUsingSharedMemoryTest(FilterConfig1_1 filterConf, + FrontendConfig1_1 frontendConf) { uint32_t feId; uint32_t demuxId; sp demux; uint64_t filterId; - mFrontendTests.getFrontendIdByType(frontendConf.type, feId); + mFrontendTests.getFrontendIdByType(frontendConf.config1_0.type, feId); ASSERT_TRUE(feId != INVALID_ID); ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); ASSERT_TRUE(mFrontendTests.setFrontendCallback()); @@ -117,12 +107,13 @@ void TunerBroadcastHidlTest::mediaFilterUsingSharedMemoryTest(FilterConfig filte ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); mFrontendTests.setDemux(demux); mFilterTests.setDemux(demux); - ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize)); + ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.config1_0.type, + filterConf.config1_0.bufferSize)); ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(filterId)); ASSERT_TRUE(mFilterTests.getSharedAvMemoryHandle(filterId)); - ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId)); + ASSERT_TRUE(mFilterTests.configFilter(filterConf.config1_0.settings, filterId)); ASSERT_TRUE(mFilterTests.configAvFilterStreamType(filterConf.streamType, filterId)); - ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterConf.getMqDesc)); + ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterConf.config1_0.getMqDesc)); ASSERT_TRUE(mFilterTests.startFilter(filterId)); // tune test ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/)); @@ -135,19 +126,16 @@ void TunerBroadcastHidlTest::mediaFilterUsingSharedMemoryTest(FilterConfig filte ASSERT_TRUE(mFrontendTests.closeFrontend()); } -void TunerRecordHidlTest::recordSingleFilterTest(FilterConfig filterConf, - FrontendConfig frontendConf, DvrConfig dvrConf) { - if (!frontendConf.enable) { - return; - } - +void TunerRecordHidlTest::recordSingleFilterTest(FilterConfig1_1 filterConf, + FrontendConfig1_1 frontendConf, + DvrConfig dvrConf) { uint32_t feId; uint32_t demuxId; sp demux; uint64_t filterId; sp filter; - mFrontendTests.getFrontendIdByType(frontendConf.type, feId); + mFrontendTests.getFrontendIdByType(frontendConf.config1_0.type, feId); ASSERT_TRUE(feId != INVALID_ID); ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); ASSERT_TRUE(mFrontendTests.setFrontendCallback()); @@ -159,10 +147,11 @@ void TunerRecordHidlTest::recordSingleFilterTest(FilterConfig filterConf, ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrConf.type, dvrConf.bufferSize)); ASSERT_TRUE(mDvrTests.configDvrRecord(dvrConf.settings)); ASSERT_TRUE(mDvrTests.getDvrRecordMQDescriptor()); - ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize)); + ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.config1_0.type, + filterConf.config1_0.bufferSize)); ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(filterId)); - ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId)); - ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterConf.getMqDesc)); + ASSERT_TRUE(mFilterTests.configFilter(filterConf.config1_0.settings, filterId)); + ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterConf.config1_0.getMqDesc)); filter = mFilterTests.getFilterById(filterId); ASSERT_TRUE(filter != nullptr); mDvrTests.startRecordOutputThread(dvrConf.settings.record()); @@ -186,41 +175,47 @@ void TunerRecordHidlTest::recordSingleFilterTest(FilterConfig filterConf, TEST_P(TunerFilterHidlTest, StartFilterInDemux) { description("Open and start a filter in Demux."); // TODO use parameterized tests - configSingleFilterInDemuxTest(filterArray[TS_VIDEO0], frontendArray[defaultFrontend]); + configSingleFilterInDemuxTest(filterMap[live.videoFilterId], frontendMap[live.frontendId]); } TEST_P(TunerFilterHidlTest, ConfigIpFilterInDemuxWithCid) { description("Open and configure an ip filter in Demux."); // TODO use parameterized tests - configSingleFilterInDemuxTest(filterArray[IP_IP0], frontendArray[defaultFrontend]); + if (live.ipFilterId.compare(emptyHardwareId) == 0) { + return; + } + configSingleFilterInDemuxTest(filterMap[live.ipFilterId], frontendMap[live.frontendId]); } TEST_P(TunerFilterHidlTest, ReconfigFilterToReceiveStartId) { description("Recofigure and restart a filter to test start id."); // TODO use parameterized tests - reconfigSingleFilterInDemuxTest(filterArray[TS_VIDEO0], filterArray[TS_VIDEO1], - frontendArray[defaultFrontend]); + reconfigSingleFilterInDemuxTest(filterMap[live.videoFilterId], filterMap[live.videoFilterId], + frontendMap[live.frontendId]); } TEST_P(TunerRecordHidlTest, RecordDataFlowWithTsRecordFilterTest) { description("Feed ts data from frontend to recording and test with ts record filter"); - recordSingleFilterTest(filterArray[TS_RECORD0], frontendArray[defaultFrontend], - dvrArray[DVR_RECORD0]); + if (!record.support) { + return; + } + recordSingleFilterTest(filterMap[record.recordFilterId], frontendMap[record.frontendId], + dvrMap[record.dvrRecordId]); } TEST_P(TunerFrontendHidlTest, TuneFrontendWithFrontendSettingsExt1_1) { description("Tune one Frontend with v1_1 extended setting and check Lock event"); - mFrontendTests.tuneTest(frontendArray[defaultFrontend]); + mFrontendTests.tuneTest(frontendMap[live.frontendId]); } TEST_P(TunerFrontendHidlTest, BlindScanFrontendWithEndFrequency) { description("Run an blind frontend scan with v1_1 extended setting and check lock scanMessage"); - mFrontendTests.scanTest(frontendScanArray[defaultScanFrontend], FrontendScanType::SCAN_BLIND); + mFrontendTests.scanTest(frontendMap[scan.frontendId], FrontendScanType::SCAN_BLIND); } TEST_P(TunerBroadcastHidlTest, MediaFilterWithSharedMemoryHandle) { description("Test the Media Filter with shared memory handle"); - mediaFilterUsingSharedMemoryTest(filterArray[TS_VIDEO0], frontendArray[defaultFrontend]); + mediaFilterUsingSharedMemoryTest(filterMap[live.videoFilterId], frontendMap[live.frontendId]); } TEST_P(TunerFrontendHidlTest, GetFrontendDtmbCaps) { @@ -230,7 +225,10 @@ TEST_P(TunerFrontendHidlTest, GetFrontendDtmbCaps) { TEST_P(TunerFrontendHidlTest, LinkToCiCam) { description("Test Frontend link to CiCam"); - mFrontendTests.tuneTest(frontendArray[defaultFrontend]); + if (!frontendMap[live.frontendId].canConnectToCiCam) { + return; + } + mFrontendTests.tuneTest(frontendMap[live.frontendId]); } INSTANTIATE_TEST_SUITE_P( diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h index d14a2e8779..863f649dd8 100644 --- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h @@ -19,11 +19,20 @@ namespace { -void initConfiguration() { +bool initConfiguration() { + TunerTestingConfigReader1_0::setConfigFilePath(configFilePath); + if (!TunerTestingConfigReader1_0::checkConfigFileExists()) { + return false; + } initFrontendConfig(); - initFrontendScanConfig(); initFilterConfig(); initDvrConfig(); + connectHardwaresToTestCases(); + if (!validateConnections()) { + ALOGW("[vts] failed to validate connections."); + return false; + } + return true; } static AssertionResult success() { @@ -57,9 +66,9 @@ class TunerFilterHidlTest : public testing::TestWithParam { RecordProperty("description", description); } - void configSingleFilterInDemuxTest(FilterConfig filterConf, FrontendConfig frontendConf); - void reconfigSingleFilterInDemuxTest(FilterConfig filterConf, FilterConfig filterReconf, - FrontendConfig frontendConf); + void configSingleFilterInDemuxTest(FilterConfig1_1 filterConf, FrontendConfig1_1 frontendConf); + void reconfigSingleFilterInDemuxTest(FilterConfig1_1 filterConf, FilterConfig1_1 filterReconf, + FrontendConfig1_1 frontendConf); sp mService; FrontendTests mFrontendTests; DemuxTests mDemuxTests; @@ -86,7 +95,7 @@ class TunerRecordHidlTest : public testing::TestWithParam { RecordProperty("description", description); } - void recordSingleFilterTest(FilterConfig filterConf, FrontendConfig frontendConf, + void recordSingleFilterTest(FilterConfig1_1 filterConf, FrontendConfig1_1 frontendConf, DvrConfig dvrConf); AssertionResult filterDataOutputTest(); @@ -144,7 +153,8 @@ class TunerBroadcastHidlTest : public testing::TestWithParam { AssertionResult filterDataOutputTest(); - void mediaFilterUsingSharedMemoryTest(FilterConfig filterConf, FrontendConfig frontendConf); + void mediaFilterUsingSharedMemoryTest(FilterConfig1_1 filterConf, + FrontendConfig1_1 frontendConf); }; // TODO remove from the allow list once the cf tv target is enabled for testing diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h index ad5784972e..390bd4c2d3 100644 --- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h @@ -21,6 +21,8 @@ #include #include +#include "../../../config/TunerTestingConfigReaderV1_1.h" + using android::hardware::tv::tuner::V1_0::DataFormat; using android::hardware::tv::tuner::V1_0::DemuxAlpFilterType; using android::hardware::tv::tuner::V1_0::DemuxFilterMainType; @@ -46,104 +48,39 @@ using android::hardware::tv::tuner::V1_0::FrontendSettings; using android::hardware::tv::tuner::V1_0::FrontendType; using android::hardware::tv::tuner::V1_0::PlaybackSettings; using android::hardware::tv::tuner::V1_0::RecordSettings; -using android::hardware::tv::tuner::V1_1::AudioStreamType; -using android::hardware::tv::tuner::V1_1::AvStreamType; -using android::hardware::tv::tuner::V1_1::FrontendSettingsExt1_1; -using android::hardware::tv::tuner::V1_1::FrontendStatusExt1_1; -using android::hardware::tv::tuner::V1_1::FrontendStatusTypeExt1_1; -using android::hardware::tv::tuner::V1_1::VideoStreamType; using namespace std; +using namespace android::media::tuner::testing::configuration::V1_0; -const uint32_t FMQ_SIZE_512K = 0x80000; -const uint32_t FMQ_SIZE_1M = 0x100000; const uint32_t FMQ_SIZE_4M = 0x400000; const uint32_t FMQ_SIZE_16M = 0x1000000; -typedef enum { - TS_VIDEO0, - TS_VIDEO1, - TS_AUDIO0, - TS_AUDIO1, - TS_PES0, - TS_PCR0, - TS_SECTION0, - TS_TS0, - TS_RECORD0, - IP_IP0, - FILTER_MAX, -} Filter; - -typedef enum { - DVBT, - DVBS, - FRONTEND_MAX, -} Frontend; - -typedef enum { - SCAN_DVBT, - SCAN_MAX, -} FrontendScan; - -typedef enum { - DVR_RECORD0, - DVR_PLAYBACK0, - DVR_MAX, -} Dvr; - -struct FilterConfig { - uint32_t bufferSize; - DemuxFilterType type; - DemuxFilterSettings settings; - bool getMqDesc; - AvStreamType streamType; - uint32_t ipCid; - uint32_t monitorEventTypes; - - bool operator<(const FilterConfig& /*c*/) const { return false; } -}; - -struct FrontendConfig { - bool enable; - bool isSoftwareFe; - bool canConnectToCiCam; - uint32_t ciCamId; - FrontendType type; - FrontendSettings settings; - FrontendSettingsExt1_1 settingsExt1_1; - vector tuneStatusTypes; - vector expectTuneStatuses; -}; +const string configFilePath = "/vendor/etc/tuner_vts_config_1_1.xml"; -struct DvrConfig { - DvrType type; - uint32_t bufferSize; - DvrSettings settings; - string playbackInputFile; -}; +// Hardware configs +static map frontendMap; +static map filterMap; +static map dvrMap; -static FrontendConfig frontendArray[FILTER_MAX]; -static FrontendConfig frontendScanArray[SCAN_MAX]; -static FilterConfig filterArray[FILTER_MAX]; -static DvrConfig dvrArray[DVR_MAX]; -static int defaultFrontend = DVBT; -static int defaultScanFrontend = SCAN_DVBT; +// Hardware and test cases connections +static LiveBroadcastHardwareConnections live; +static ScanHardwareConnections scan; +static DvrRecordHardwareConnections record; -/** Configuration array for the frontend tune test */ +/** Config all the frontends that would be used in the tests */ inline void initFrontendConfig() { + // The test will use the internal default fe when default fe is connected to any data flow + // without overriding in the xml config. + string defaultFeId = "FE_DEFAULT"; FrontendDvbtSettings dvbtSettings{ .frequency = 578000, .transmissionMode = FrontendDvbtTransmissionMode::AUTO, .bandwidth = FrontendDvbtBandwidth::BANDWIDTH_8MHZ, - .constellation = FrontendDvbtConstellation::AUTO, - .hierarchy = FrontendDvbtHierarchy::AUTO, - .hpCoderate = FrontendDvbtCoderate::AUTO, - .lpCoderate = FrontendDvbtCoderate::AUTO, - .guardInterval = FrontendDvbtGuardInterval::AUTO, .isHighPriority = true, - .standard = FrontendDvbtStandard::T, }; - frontendArray[DVBT].type = FrontendType::DVBT, frontendArray[DVBT].settings.dvbt(dvbtSettings); + frontendMap[defaultFeId].config1_0.type = FrontendType::DVBT; + frontendMap[defaultFeId].config1_0.settings.dvbt(dvbtSettings); + vector types; types.push_back(FrontendStatusTypeExt1_1::UEC); types.push_back(FrontendStatusTypeExt1_1::IS_MISO); @@ -153,147 +90,97 @@ inline void initFrontendConfig() { statuses.push_back(status); status.isMiso(true); statuses.push_back(status); - - frontendArray[DVBT].tuneStatusTypes = types; - frontendArray[DVBT].expectTuneStatuses = statuses; - frontendArray[DVBT].isSoftwareFe = true; - frontendArray[DVBT].canConnectToCiCam = true; - frontendArray[DVBT].ciCamId = 0; - frontendArray[DVBT].settingsExt1_1.settingExt.dvbt({ - .transmissionMode = - android::hardware::tv::tuner::V1_1::FrontendDvbtTransmissionMode::MODE_8K_E, - }); - frontendArray[DVBT].enable = true; - frontendArray[DVBS].type = FrontendType::DVBS; - frontendArray[DVBS].isSoftwareFe = true; - frontendArray[DVBS].enable = true; -}; - -/** Configuration array for the frontend scan test */ -inline void initFrontendScanConfig() { - frontendScanArray[SCAN_DVBT].type = FrontendType::DVBT; - frontendScanArray[SCAN_DVBT].settings.dvbt({ - .frequency = 578000, - .transmissionMode = FrontendDvbtTransmissionMode::MODE_8K, - .bandwidth = FrontendDvbtBandwidth::BANDWIDTH_8MHZ, - .constellation = FrontendDvbtConstellation::AUTO, - .hierarchy = FrontendDvbtHierarchy::AUTO, - .hpCoderate = FrontendDvbtCoderate::AUTO, - .lpCoderate = FrontendDvbtCoderate::AUTO, - .guardInterval = FrontendDvbtGuardInterval::AUTO, - .isHighPriority = true, - .standard = FrontendDvbtStandard::T, - }); - frontendScanArray[SCAN_DVBT].settingsExt1_1.endFrequency = 800000; - frontendScanArray[SCAN_DVBT].settingsExt1_1.settingExt.dvbt({ + frontendMap[defaultFeId].tuneStatusTypes = types; + frontendMap[defaultFeId].expectTuneStatuses = statuses; + frontendMap[defaultFeId].config1_0.isSoftwareFe = true; + frontendMap[defaultFeId].canConnectToCiCam = true; + frontendMap[defaultFeId].ciCamId = 0; + frontendMap[defaultFeId].settingsExt1_1.settingExt.dvbt({ .transmissionMode = android::hardware::tv::tuner::V1_1::FrontendDvbtTransmissionMode::MODE_8K_E, }); + // Read customized config + TunerTestingConfigReader1_1::readFrontendConfig1_1(frontendMap); }; -/** Configuration array for the filter test */ inline void initFilterConfig() { - // TS VIDEO filter setting for default implementation testing - filterArray[TS_VIDEO0].type.mainType = DemuxFilterMainType::TS; - filterArray[TS_VIDEO0].type.subType.tsFilterType(DemuxTsFilterType::VIDEO); - filterArray[TS_VIDEO0].bufferSize = FMQ_SIZE_16M; - filterArray[TS_VIDEO0].settings.ts().tpid = 256; - filterArray[TS_VIDEO0].settings.ts().filterSettings.av({.isPassthrough = false}); - filterArray[TS_VIDEO0].monitorEventTypes = + // The test will use the internal default filter when default filter is connected to any + // data flow without overriding in the xml config. + string defaultAudioFilterId = "FILTER_AUDIO_DEFAULT"; + string defaultVideoFilterId = "FILTER_VIDEO_DEFAULT"; + + filterMap[defaultVideoFilterId].config1_0.type.mainType = DemuxFilterMainType::TS; + filterMap[defaultVideoFilterId].config1_0.type.subType.tsFilterType(DemuxTsFilterType::VIDEO); + filterMap[defaultVideoFilterId].config1_0.bufferSize = FMQ_SIZE_16M; + filterMap[defaultVideoFilterId].config1_0.settings.ts().tpid = 256; + filterMap[defaultVideoFilterId].config1_0.settings.ts().filterSettings.av( + {.isPassthrough = false}); + filterMap[defaultVideoFilterId].monitorEventTypes = android::hardware::tv::tuner::V1_1::DemuxFilterMonitorEventType::SCRAMBLING_STATUS | android::hardware::tv::tuner::V1_1::DemuxFilterMonitorEventType::IP_CID_CHANGE; - filterArray[TS_VIDEO1].type.mainType = DemuxFilterMainType::TS; - filterArray[TS_VIDEO1].type.subType.tsFilterType(DemuxTsFilterType::VIDEO); - filterArray[TS_VIDEO1].bufferSize = FMQ_SIZE_16M; - filterArray[TS_VIDEO1].settings.ts().tpid = 256; - filterArray[TS_VIDEO1].settings.ts().filterSettings.av({.isPassthrough = false}); - filterArray[TS_VIDEO1].streamType.video(VideoStreamType::MPEG1); - // TS AUDIO filter setting - filterArray[TS_AUDIO0].type.mainType = DemuxFilterMainType::TS; - filterArray[TS_AUDIO0].type.subType.tsFilterType(DemuxTsFilterType::AUDIO); - filterArray[TS_AUDIO0].bufferSize = FMQ_SIZE_16M; - filterArray[TS_AUDIO0].settings.ts().tpid = 256; - filterArray[TS_AUDIO0].settings.ts().filterSettings.av({.isPassthrough = false}); - filterArray[TS_AUDIO1].type.mainType = DemuxFilterMainType::TS; - filterArray[TS_AUDIO1].type.subType.tsFilterType(DemuxTsFilterType::AUDIO); - filterArray[TS_AUDIO1].bufferSize = FMQ_SIZE_16M; - filterArray[TS_AUDIO1].settings.ts().tpid = 257; - filterArray[TS_AUDIO1].settings.ts().filterSettings.av({.isPassthrough = false}); - filterArray[TS_VIDEO1].streamType.audio(AudioStreamType::MP3); - // TS PES filter setting - filterArray[TS_PES0].type.mainType = DemuxFilterMainType::TS; - filterArray[TS_PES0].type.subType.tsFilterType(DemuxTsFilterType::PES); - filterArray[TS_PES0].bufferSize = FMQ_SIZE_16M; - filterArray[TS_PES0].settings.ts().tpid = 256; - filterArray[TS_PES0].settings.ts().filterSettings.pesData({ - .isRaw = false, - .streamId = 0xbd, - }); - filterArray[TS_PES0].getMqDesc = true; - // TS PCR filter setting - filterArray[TS_PCR0].type.mainType = DemuxFilterMainType::TS; - filterArray[TS_PCR0].type.subType.tsFilterType(DemuxTsFilterType::PCR); - filterArray[TS_PCR0].bufferSize = FMQ_SIZE_16M; - filterArray[TS_PCR0].settings.ts().tpid = 256; - filterArray[TS_PCR0].settings.ts().filterSettings.noinit(); - // TS filter setting - filterArray[TS_TS0].type.mainType = DemuxFilterMainType::TS; - filterArray[TS_TS0].type.subType.tsFilterType(DemuxTsFilterType::TS); - filterArray[TS_TS0].bufferSize = FMQ_SIZE_16M; - filterArray[TS_TS0].settings.ts().tpid = 256; - filterArray[TS_TS0].settings.ts().filterSettings.noinit(); - // TS SECTION filter setting - filterArray[TS_SECTION0].type.mainType = DemuxFilterMainType::TS; - filterArray[TS_SECTION0].type.subType.tsFilterType(DemuxTsFilterType::SECTION); - filterArray[TS_SECTION0].bufferSize = FMQ_SIZE_16M; - filterArray[TS_SECTION0].settings.ts().tpid = 256; - filterArray[TS_SECTION0].settings.ts().filterSettings.section({ - .isRaw = false, - }); - filterArray[TS_SECTION0].getMqDesc = true; - // TS RECORD filter setting - filterArray[TS_RECORD0].type.mainType = DemuxFilterMainType::TS; - filterArray[TS_RECORD0].type.subType.tsFilterType(DemuxTsFilterType::RECORD); - filterArray[TS_RECORD0].settings.ts().tpid = 256; - filterArray[TS_RECORD0].settings.ts().filterSettings.record({ - .scIndexType = DemuxRecordScIndexType::NONE, - }); - // IP filter setting - filterArray[IP_IP0].type.mainType = DemuxFilterMainType::IP; - filterArray[IP_IP0].type.subType.ipFilterType(DemuxIpFilterType::IP); - uint8_t src[4] = {192, 168, 1, 1}; - uint8_t dest[4] = {192, 168, 1, 2}; - DemuxIpAddress ipAddress; - ipAddress.srcIpAddress.v4(src); - ipAddress.dstIpAddress.v4(dest); - DemuxIpFilterSettings ipSettings{ - .ipAddr = ipAddress, - }; - filterArray[IP_IP0].settings.ip(ipSettings); - filterArray[IP_IP0].ipCid = 1; + filterMap[defaultVideoFilterId].streamType.video(VideoStreamType::MPEG1); + + filterMap[defaultAudioFilterId].config1_0.type.mainType = DemuxFilterMainType::TS; + filterMap[defaultAudioFilterId].config1_0.type.subType.tsFilterType(DemuxTsFilterType::AUDIO); + filterMap[defaultAudioFilterId].config1_0.bufferSize = FMQ_SIZE_16M; + filterMap[defaultAudioFilterId].config1_0.settings.ts().tpid = 256; + filterMap[defaultAudioFilterId].config1_0.settings.ts().filterSettings.av( + {.isPassthrough = false}); + filterMap[defaultAudioFilterId].monitorEventTypes = + android::hardware::tv::tuner::V1_1::DemuxFilterMonitorEventType::SCRAMBLING_STATUS | + android::hardware::tv::tuner::V1_1::DemuxFilterMonitorEventType::IP_CID_CHANGE; + filterMap[defaultAudioFilterId].streamType.audio(AudioStreamType::MP3); + // Read customized config + TunerTestingConfigReader1_1::readFilterConfig1_1(filterMap); }; -/** Configuration array for the dvr test */ +/** Config all the dvrs that would be used in the tests */ inline void initDvrConfig() { - RecordSettings recordSettings{ - .statusMask = 0xf, - .lowThreshold = 0x1000, - .highThreshold = 0x07fff, - .dataFormat = DataFormat::TS, - .packetSize = 188, - }; - dvrArray[DVR_RECORD0].type = DvrType::RECORD; - dvrArray[DVR_RECORD0].bufferSize = FMQ_SIZE_4M; - dvrArray[DVR_RECORD0].settings.record(recordSettings); - PlaybackSettings playbackSettings{ - .statusMask = 0xf, - .lowThreshold = 0x1000, - .highThreshold = 0x07fff, - .dataFormat = DataFormat::TS, - .packetSize = 188, - }; - dvrArray[DVR_PLAYBACK0].type = DvrType::PLAYBACK; - dvrArray[DVR_PLAYBACK0].playbackInputFile = "/data/local/tmp/segment000000.ts"; - dvrArray[DVR_PLAYBACK0].bufferSize = FMQ_SIZE_4M; - dvrArray[DVR_PLAYBACK0].settings.playback(playbackSettings); + // Read customized config + TunerTestingConfigReader1_0::readDvrConfig1_0(dvrMap); +}; + +/** Read the vendor configurations of which hardware to use for each test cases/data flows */ +inline void connectHardwaresToTestCases() { + TunerTestingConfigReader1_0::connectLiveBroadcast(live); + TunerTestingConfigReader1_0::connectScan(scan); + TunerTestingConfigReader1_0::connectDvrRecord(record); }; + +inline bool validateConnections() { + bool feIsValid = frontendMap.find(live.frontendId) != frontendMap.end() && + frontendMap.find(scan.frontendId) != frontendMap.end(); + feIsValid &= record.support ? frontendMap.find(record.frontendId) != frontendMap.end() : true; + + if (!feIsValid) { + ALOGW("[vts config] dynamic config fe connection is invalid."); + return false; + } + + bool dvrIsValid = frontendMap[live.frontendId].config1_0.isSoftwareFe + ? dvrMap.find(live.dvrSoftwareFeId) != dvrMap.end() + : true; + if (record.support) { + if (frontendMap[record.frontendId].config1_0.isSoftwareFe) { + dvrIsValid &= dvrMap.find(record.dvrSoftwareFeId) != dvrMap.end(); + } + dvrIsValid &= dvrMap.find(record.dvrRecordId) != dvrMap.end(); + } + + if (!dvrIsValid) { + ALOGW("[vts config] dynamic config dvr connection is invalid."); + return false; + } + + bool filterIsValid = filterMap.find(live.audioFilterId) != filterMap.end() && + filterMap.find(live.videoFilterId) != filterMap.end(); + filterIsValid &= + record.support ? filterMap.find(record.recordFilterId) != filterMap.end() : true; + + if (!filterIsValid) { + ALOGW("[vts config] dynamic config filter connection is invalid."); + return false; + } + + return true; +} diff --git a/tv/tuner/config/TunerTestingConfigReader.h b/tv/tuner/config/TunerTestingConfigReaderV1_0.h similarity index 84% rename from tv/tuner/config/TunerTestingConfigReader.h rename to tv/tuner/config/TunerTestingConfigReaderV1_0.h index 90499c414c..cff4af11d8 100644 --- a/tv/tuner/config/TunerTestingConfigReader.h +++ b/tv/tuner/config/TunerTestingConfigReaderV1_0.h @@ -36,6 +36,8 @@ using android::hardware::tv::tuner::V1_0::DemuxFilterRecordSettings; using android::hardware::tv::tuner::V1_0::DemuxFilterSectionSettings; using android::hardware::tv::tuner::V1_0::DemuxFilterSettings; using android::hardware::tv::tuner::V1_0::DemuxFilterType; +using android::hardware::tv::tuner::V1_0::DemuxIpAddress; +using android::hardware::tv::tuner::V1_0::DemuxIpFilterSettings; using android::hardware::tv::tuner::V1_0::DemuxIpFilterType; using android::hardware::tv::tuner::V1_0::DemuxMmtpFilterType; using android::hardware::tv::tuner::V1_0::DemuxRecordScIndexType; @@ -63,9 +65,10 @@ using android::hardware::tv::tuner::V1_0::LnbVoltage; using android::hardware::tv::tuner::V1_0::PlaybackSettings; using android::hardware::tv::tuner::V1_0::RecordSettings; -const string configFilePath = "/vendor/etc/tuner_vts_config.xml"; const string emptyHardwareId = ""; +static string mConfigFilePath; + #define PROVISION_STR \ "{ " \ " \"id\": 21140844, " \ @@ -125,6 +128,7 @@ struct LiveBroadcastHardwareConnections { string audioFilterId; string videoFilterId; string sectionFilterId; + string ipFilterId; string pcrFilterId; /* list string of extra filters; */ }; @@ -186,14 +190,17 @@ struct TimeFilterHardwareConnections { string timeFilterId; }; -struct TunerTestingConfigReader { +struct TunerTestingConfigReader1_0 { public: + static void setConfigFilePath(string path) { mConfigFilePath = path; } + static bool checkConfigFileExists() { - auto res = read(configFilePath.c_str()); + auto res = read(mConfigFilePath.c_str()); if (res == nullopt) { - ALOGW("[ConfigReader] Couldn't read /vendor/etc/tuner_vts_config.xml." + ALOGW("[ConfigReader] Couldn't read %s." "Please check tuner_testing_dynamic_configuration.xsd" - "and sample_tuner_vts_config.xml for more details on how to config Tune VTS."); + "and sample_tuner_vts_config.xml for more details on how to config Tune VTS.", + mConfigFilePath.c_str()); } return (res != nullopt); } @@ -413,6 +420,11 @@ struct TunerTestingConfigReader { if (liveConfig.hasDvrSoftwareFeConnection()) { live.dvrSoftwareFeId = liveConfig.getDvrSoftwareFeConnection(); } + if (liveConfig.hasIpFilterConnection()) { + live.ipFilterId = liveConfig.getIpFilterConnection(); + } else { + live.ipFilterId = emptyHardwareId; + } } static void connectScan(ScanHardwareConnections& scan) { @@ -520,6 +532,10 @@ struct TunerTestingConfigReader { timeFilter.timeFilterId = timeFilterConfig.getTimeFilterConnection(); } + static HardwareConfiguration getHardwareConfig() { + return *getTunerConfig().getFirstHardwareConfiguration(); + } + private: static FrontendDvbtSettings readDvbtFrontendSettings(Frontend feConfig) { ALOGW("[ConfigReader] fe type is dvbt"); @@ -530,12 +546,17 @@ struct TunerTestingConfigReader { ALOGW("[ConfigReader] no more dvbt settings"); return dvbtSettings; } - dvbtSettings.transmissionMode = static_cast( - feConfig.getFirstDvbtFrontendSettings_optional()->getTransmissionMode()); - dvbtSettings.bandwidth = static_cast( - feConfig.getFirstDvbtFrontendSettings_optional()->getBandwidth()); - dvbtSettings.isHighPriority = - feConfig.getFirstDvbtFrontendSettings_optional()->getIsHighPriority(); + auto dvbt = feConfig.getFirstDvbtFrontendSettings_optional(); + uint32_t trans = static_cast(dvbt->getTransmissionMode()); + if (trans <= (uint32_t)FrontendDvbtTransmissionMode::MODE_32K) { + dvbtSettings.transmissionMode = static_cast(trans); + } + dvbtSettings.bandwidth = static_cast(dvbt->getBandwidth()); + dvbtSettings.isHighPriority = dvbt->getIsHighPriority(); + if (dvbt->hasConstellation()) { + dvbtSettings.constellation = + static_cast(dvbt->getConstellation()); + } return dvbtSettings; } @@ -559,13 +580,13 @@ struct TunerTestingConfigReader { DemuxFilterSettings& settings) { auto mainType = filterConfig.getMainType(); auto subType = filterConfig.getSubType(); - uint32_t pid = static_cast(filterConfig.getPid()); switch (mainType) { case FilterMainTypeEnum::TS: { ALOGW("[ConfigReader] filter main type is ts"); type.mainType = DemuxFilterMainType::TS; switch (subType) { case FilterSubTypeEnum::UNDEFINED: + type.subType.tsFilterType(DemuxTsFilterType::UNDEFINED); break; case FilterSubTypeEnum::SECTION: type.subType.tsFilterType(DemuxTsFilterType::SECTION); @@ -606,7 +627,9 @@ struct TunerTestingConfigReader { ALOGW("[ConfigReader] ts subtype is not supported"); return false; } - settings.ts().tpid = pid; + if (filterConfig.hasPid()) { + settings.ts().tpid = static_cast(filterConfig.getPid()); + } break; } case FilterMainTypeEnum::MMTP: { @@ -614,6 +637,7 @@ struct TunerTestingConfigReader { type.mainType = DemuxFilterMainType::MMTP; switch (subType) { case FilterSubTypeEnum::UNDEFINED: + type.subType.mmtpFilterType(DemuxMmtpFilterType::UNDEFINED); break; case FilterSubTypeEnum::SECTION: type.subType.mmtpFilterType(DemuxMmtpFilterType::SECTION); @@ -652,7 +676,47 @@ struct TunerTestingConfigReader { ALOGW("[ConfigReader] mmtp subtype is not supported"); return false; } - settings.mmtp().mmtpPid = pid; + if (filterConfig.hasPid()) { + settings.mmtp().mmtpPid = static_cast(filterConfig.getPid()); + } + break; + } + case FilterMainTypeEnum::IP: { + ALOGW("[ConfigReader] filter main type is ip"); + type.mainType = DemuxFilterMainType::IP; + switch (subType) { + case FilterSubTypeEnum::UNDEFINED: + type.subType.ipFilterType(DemuxIpFilterType::UNDEFINED); + break; + case FilterSubTypeEnum::SECTION: + type.subType.ipFilterType(DemuxIpFilterType::SECTION); + settings.ip().filterSettings.section( + readSectionFilterSettings(filterConfig)); + break; + case FilterSubTypeEnum::NTP: + type.subType.ipFilterType(DemuxIpFilterType::NTP); + settings.ip().filterSettings.noinit(); + break; + case FilterSubTypeEnum::IP: { + DemuxIpFilterSettings ip{ + .ipAddr = readIpAddress(filterConfig), + }; + ip.filterSettings.bPassthrough(readPassthroughSettings(filterConfig)); + settings.ip(ip); + break; + } + case FilterSubTypeEnum::IP_PAYLOAD: + type.subType.ipFilterType(DemuxIpFilterType::IP_PAYLOAD); + settings.ip().filterSettings.noinit(); + break; + case FilterSubTypeEnum::PAYLOAD_THROUGH: + type.subType.ipFilterType(DemuxIpFilterType::PAYLOAD_THROUGH); + settings.ip().filterSettings.noinit(); + break; + default: + ALOGW("[ConfigReader] mmtp subtype is not supported"); + return false; + } break; } default: @@ -663,6 +727,46 @@ struct TunerTestingConfigReader { return true; } + static DemuxIpAddress readIpAddress(Filter filterConfig) { + DemuxIpAddress ipAddress; + if (!filterConfig.hasIpFilterConfig_optional()) { + return ipAddress; + } + auto ipFilterConfig = filterConfig.getFirstIpFilterConfig_optional(); + if (ipFilterConfig->hasSrcPort()) { + ipAddress.srcPort = ipFilterConfig->getSrcPort(); + } + if (ipFilterConfig->hasDestPort()) { + ipAddress.dstPort = ipFilterConfig->getDestPort(); + } + if (ipFilterConfig->getFirstSrcIpAddress()->getIsIpV4()) { + memcpy(ipAddress.srcIpAddress.v4().data(), + ipFilterConfig->getFirstSrcIpAddress()->getIp().data(), 4); + } else { + memcpy(ipAddress.srcIpAddress.v6().data(), + ipFilterConfig->getFirstSrcIpAddress()->getIp().data(), 6); + } + if (ipFilterConfig->getFirstDestIpAddress()->getIsIpV4()) { + memcpy(ipAddress.dstIpAddress.v4().data(), + ipFilterConfig->getFirstDestIpAddress()->getIp().data(), 4); + } else { + memcpy(ipAddress.dstIpAddress.v6().data(), + ipFilterConfig->getFirstDestIpAddress()->getIp().data(), 6); + } + return ipAddress; + } + + static bool readPassthroughSettings(Filter filterConfig) { + if (!filterConfig.hasIpFilterConfig_optional()) { + return false; + } + auto ipFilterConfig = filterConfig.getFirstIpFilterConfig_optional(); + if (ipFilterConfig->hasDataPassthrough()) { + return ipFilterConfig->getDataPassthrough(); + } + return false; + } + static DemuxFilterSectionSettings readSectionFilterSettings(Filter filterConfig) { DemuxFilterSectionSettings settings; if (!filterConfig.hasSectionFilterSettings_optional()) { @@ -720,11 +824,7 @@ struct TunerTestingConfigReader { return recordSettings; } - static TunerConfiguration getTunerConfig() { return *read(configFilePath.c_str()); } - - static HardwareConfiguration getHardwareConfig() { - return *getTunerConfig().getFirstHardwareConfiguration(); - } + static TunerConfiguration getTunerConfig() { return *read(mConfigFilePath.c_str()); } static DataFlowConfiguration getDataFlowConfiguration() { return *getTunerConfig().getFirstDataFlowConfiguration(); diff --git a/tv/tuner/config/TunerTestingConfigReaderV1_1.h b/tv/tuner/config/TunerTestingConfigReaderV1_1.h new file mode 100644 index 0000000000..13d5303230 --- /dev/null +++ b/tv/tuner/config/TunerTestingConfigReaderV1_1.h @@ -0,0 +1,185 @@ +/* + * 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. + */ + +#include +#include "TunerTestingConfigReaderV1_0.h" + +using android::hardware::tv::tuner::V1_1::AudioStreamType; +using android::hardware::tv::tuner::V1_1::AvStreamType; +using android::hardware::tv::tuner::V1_1::FrontendDvbsScanType; +using android::hardware::tv::tuner::V1_1::FrontendDvbsSettingsExt1_1; +using android::hardware::tv::tuner::V1_1::FrontendDvbtSettingsExt1_1; +using android::hardware::tv::tuner::V1_1::FrontendSettingsExt1_1; +using android::hardware::tv::tuner::V1_1::FrontendStatusExt1_1; +using android::hardware::tv::tuner::V1_1::FrontendStatusTypeExt1_1; +using android::hardware::tv::tuner::V1_1::VideoStreamType; + +struct FrontendConfig1_1 { + FrontendConfig config1_0; + bool canConnectToCiCam; + uint32_t ciCamId; + FrontendSettingsExt1_1 settingsExt1_1; + vector tuneStatusTypes; + vector expectTuneStatuses; +}; + +struct FilterConfig1_1 { + FilterConfig config1_0; + AvStreamType streamType; + uint32_t ipCid; + uint32_t monitorEventTypes; + + bool operator<(const FilterConfig& /*c*/) const { return false; } +}; + +struct TunerTestingConfigReader1_1 { + public: + static void readFrontendConfig1_1(map& frontendMap) { + map frontendMap1_0; + TunerTestingConfigReader1_0::readFrontendConfig1_0(frontendMap1_0); + for (auto it = frontendMap1_0.begin(); it != frontendMap1_0.end(); it++) { + frontendMap[it->first].config1_0 = it->second; + } + + auto hardwareConfig = TunerTestingConfigReader1_0::getHardwareConfig(); + if (hardwareConfig.hasFrontends()) { + // TODO: b/182519645 complete the tune status config + vector types; + types.push_back(FrontendStatusTypeExt1_1::UEC); + types.push_back(FrontendStatusTypeExt1_1::IS_MISO); + vector statuses; + FrontendStatusExt1_1 status; + status.uec(4); + statuses.push_back(status); + status.isMiso(true); + statuses.push_back(status); + + auto frontends = *hardwareConfig.getFirstFrontends(); + + for (auto feConfig : frontends.getFrontend()) { + string id = feConfig.getId(); + switch (feConfig.getType()) { + case FrontendTypeEnum::DVBS: + frontendMap[id].settingsExt1_1.settingExt.dvbs( + readDvbsFrontendSettings1_1(feConfig)); + break; + case FrontendTypeEnum::DVBT: { + frontendMap[id].settingsExt1_1.settingExt.dvbt( + readDvbtFrontendSettings1_1(feConfig)); + break; + } + case FrontendTypeEnum::DTMB: + frontendMap[id].config1_0.type = static_cast( + android::hardware::tv::tuner::V1_1::FrontendType::DTMB); + break; + case FrontendTypeEnum::UNKNOWN: + ALOGW("[ConfigReader] invalid frontend type"); + return; + default: + ALOGW("[ConfigReader] fe already handled in 1_0 reader."); + break; + } + if (feConfig.hasEndFrequency()) { + frontendMap[id].settingsExt1_1.endFrequency = + (uint32_t)feConfig.getEndFrequency(); + } + // TODO: b/182519645 complete the tune status config + frontendMap[id].tuneStatusTypes = types; + frontendMap[id].expectTuneStatuses = statuses; + getCiCamInfo(feConfig, frontendMap[id].canConnectToCiCam, frontendMap[id].ciCamId); + } + } + } + + static void readFilterConfig1_1(map& filterMap) { + map filterMap1_0; + TunerTestingConfigReader1_0::readFilterConfig1_0(filterMap1_0); + for (auto it = filterMap1_0.begin(); it != filterMap1_0.end(); it++) { + filterMap[it->first].config1_0 = it->second; + } + auto hardwareConfig = TunerTestingConfigReader1_0::getHardwareConfig(); + if (hardwareConfig.hasFilters()) { + auto filters = *hardwareConfig.getFirstFilters(); + for (auto filterConfig : filters.getFilter()) { + string id = filterConfig.getId(); + if (filterConfig.hasMonitorEventTypes()) { + filterMap[id].monitorEventTypes = (uint32_t)filterConfig.getMonitorEventTypes(); + } + if (filterConfig.hasAvFilterSettings_optional()) { + AvStreamType type; + auto av = filterConfig.getFirstAvFilterSettings_optional(); + if (av->hasAudioStreamType_optional()) { + type.audio(static_cast(av->getAudioStreamType_optional())); + filterMap[id].streamType = type; + } + if (av->hasVideoStreamType_optional()) { + type.video(static_cast(av->getVideoStreamType_optional())); + filterMap[id].streamType = type; + } + } + if (filterConfig.hasIpFilterConfig_optional()) { + auto ip = filterConfig.getFirstIpFilterConfig_optional(); + if (ip->hasIpCid()) { + filterMap[id].ipCid = ip->getIpCid(); + } + } + } + } + } + + private: + static void getCiCamInfo(Frontend feConfig, bool& canConnectToCiCam, uint32_t& ciCamId) { + if (!feConfig.hasConnectToCicamId()) { + canConnectToCiCam = false; + ciCamId = -1; + } + canConnectToCiCam = true; + ciCamId = static_cast(feConfig.getConnectToCicamId()); + } + + static FrontendDvbsSettingsExt1_1 readDvbsFrontendSettings1_1(Frontend feConfig) { + FrontendDvbsSettingsExt1_1 dvbsSettings; + if (!feConfig.hasDvbsFrontendSettings_optional()) { + return dvbsSettings; + } + auto dvbs = feConfig.getFirstDvbsFrontendSettings_optional(); + if (dvbs->hasScanType()) { + dvbsSettings.scanType = static_cast(dvbs->getScanType()); + } + if (dvbs->hasIsDiseqcRxMessage()) { + dvbsSettings.isDiseqcRxMessage = dvbs->getIsDiseqcRxMessage(); + } + return dvbsSettings; + } + + static FrontendDvbtSettingsExt1_1 readDvbtFrontendSettings1_1(Frontend feConfig) { + FrontendDvbtSettingsExt1_1 dvbtSettings; + if (!feConfig.hasDvbtFrontendSettings_optional()) { + return dvbtSettings; + } + auto dvbt = feConfig.getFirstDvbtFrontendSettings_optional(); + auto trans = dvbt->getTransmissionMode(); + dvbtSettings.transmissionMode = + static_cast( + trans); + if (dvbt->hasConstellation()) { + dvbtSettings.constellation = + static_cast( + dvbt->getConstellation()); + } + return dvbtSettings; + } +}; \ No newline at end of file diff --git a/tv/tuner/config/api/current.txt b/tv/tuner/config/api/current.txt index 4255a60d16..a9602e705d 100644 --- a/tv/tuner/config/api/current.txt +++ b/tv/tuner/config/api/current.txt @@ -3,8 +3,12 @@ package android.media.tuner.testing.configuration.V1_0 { public class AvFilterSettings { ctor public AvFilterSettings(); + method @Nullable public short getAudioStreamType_optional(); method @Nullable public boolean getIsPassthrough(); + method @Nullable public short getVideoStreamType_optional(); + method public void setAudioStreamType_optional(@Nullable short); method public void setIsPassthrough(@Nullable boolean); + method public void setVideoStreamType_optional(@Nullable short); } public class DataFlowConfiguration { @@ -32,12 +36,14 @@ package android.media.tuner.testing.configuration.V1_0 { method @Nullable public String getAudioFilterConnection(); method @Nullable public String getDvrSoftwareFeConnection(); method @Nullable public String getFrontendConnection(); + method @Nullable public String getIpFilterConnection(); method @Nullable public String getPcrFilterConnection(); method @Nullable public String getSectionFilterConnection(); method @Nullable public String getVideoFilterConnection(); method public void setAudioFilterConnection(@Nullable String); method public void setDvrSoftwareFeConnection(@Nullable String); method public void setFrontendConnection(@Nullable String); + method public void setIpFilterConnection(@Nullable String); method public void setPcrFilterConnection(@Nullable String); method public void setSectionFilterConnection(@Nullable String); method public void setVideoFilterConnection(@Nullable String); @@ -144,17 +150,32 @@ package android.media.tuner.testing.configuration.V1_0 { public class DvbsFrontendSettings { ctor public DvbsFrontendSettings(); method @Nullable public java.math.BigInteger getInputStreamId(); + method @Nullable public boolean getIsDiseqcRxMessage(); + method @Nullable public android.media.tuner.testing.configuration.V1_0.DvbsScanType getScanType(); method @Nullable public java.math.BigInteger getSymbolRate(); method public void setInputStreamId(@Nullable java.math.BigInteger); + method public void setIsDiseqcRxMessage(@Nullable boolean); + method public void setScanType(@Nullable android.media.tuner.testing.configuration.V1_0.DvbsScanType); method public void setSymbolRate(@Nullable java.math.BigInteger); } + public enum DvbsScanType { + method @NonNull public String getRawName(); + enum_constant public static final android.media.tuner.testing.configuration.V1_0.DvbsScanType DIRECT; + enum_constant public static final android.media.tuner.testing.configuration.V1_0.DvbsScanType DISEQC; + enum_constant public static final android.media.tuner.testing.configuration.V1_0.DvbsScanType JESS; + enum_constant public static final android.media.tuner.testing.configuration.V1_0.DvbsScanType UNDEFINED; + enum_constant public static final android.media.tuner.testing.configuration.V1_0.DvbsScanType UNICABLE; + } + public class DvbtFrontendSettings { ctor public DvbtFrontendSettings(); method @Nullable public java.math.BigInteger getBandwidth(); + method @Nullable public java.math.BigInteger getConstellation(); method @Nullable public java.math.BigInteger getIsHighPriority(); method @Nullable public java.math.BigInteger getTransmissionMode(); method public void setBandwidth(@Nullable java.math.BigInteger); + method public void setConstellation(@Nullable java.math.BigInteger); method public void setIsHighPriority(@Nullable java.math.BigInteger); method public void setTransmissionMode(@Nullable java.math.BigInteger); } @@ -208,7 +229,9 @@ package android.media.tuner.testing.configuration.V1_0 { method @Nullable public android.media.tuner.testing.configuration.V1_0.AvFilterSettings getAvFilterSettings_optional(); method @Nullable public java.math.BigInteger getBufferSize(); method @Nullable public String getId(); + method @Nullable public android.media.tuner.testing.configuration.V1_0.IpFilterConfig getIpFilterConfig_optional(); method @Nullable public android.media.tuner.testing.configuration.V1_0.FilterMainTypeEnum getMainType(); + method @Nullable public java.math.BigInteger getMonitorEventTypes(); method @Nullable public java.math.BigInteger getPid(); method @Nullable public android.media.tuner.testing.configuration.V1_0.RecordFilterSettings getRecordFilterSettings_optional(); method @Nullable public android.media.tuner.testing.configuration.V1_0.SectionFilterSettings getSectionFilterSettings_optional(); @@ -217,7 +240,9 @@ package android.media.tuner.testing.configuration.V1_0 { method public void setAvFilterSettings_optional(@Nullable android.media.tuner.testing.configuration.V1_0.AvFilterSettings); method public void setBufferSize(@Nullable java.math.BigInteger); method public void setId(@Nullable String); + method public void setIpFilterConfig_optional(@Nullable android.media.tuner.testing.configuration.V1_0.IpFilterConfig); method public void setMainType(@Nullable android.media.tuner.testing.configuration.V1_0.FilterMainTypeEnum); + method public void setMonitorEventTypes(@Nullable java.math.BigInteger); method public void setPid(@Nullable java.math.BigInteger); method public void setRecordFilterSettings_optional(@Nullable android.media.tuner.testing.configuration.V1_0.RecordFilterSettings); method public void setSectionFilterSettings_optional(@Nullable android.media.tuner.testing.configuration.V1_0.SectionFilterSettings); @@ -227,6 +252,7 @@ package android.media.tuner.testing.configuration.V1_0 { public enum FilterMainTypeEnum { method @NonNull public String getRawName(); + enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterMainTypeEnum IP; enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterMainTypeEnum MMTP; enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterMainTypeEnum TS; } @@ -235,7 +261,11 @@ package android.media.tuner.testing.configuration.V1_0 { method @NonNull public String getRawName(); enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum AUDIO; enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum DOWNLOAD; + enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum IP; + enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum IP_PAYLOAD; enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum MMTP; + enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum NTP; + enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum PAYLOAD_THROUGH; enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum PCR; enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum PES; enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum RECORD; @@ -334,6 +364,30 @@ package android.media.tuner.testing.configuration.V1_0 { method @Nullable public java.util.List getTimeFilter(); } + public class IpAddress { + ctor public IpAddress(); + method @Nullable public java.util.List getIp(); + method @Nullable public boolean getIsIpV4(); + method public void setIp(@Nullable java.util.List); + method public void setIsIpV4(@Nullable boolean); + } + + public class IpFilterConfig { + ctor public IpFilterConfig(); + method @Nullable public boolean getDataPassthrough(); + method @Nullable public android.media.tuner.testing.configuration.V1_0.IpAddress getDestIpAddress(); + method @Nullable public long getDestPort(); + method @Nullable public java.math.BigInteger getIpCid(); + method @Nullable public android.media.tuner.testing.configuration.V1_0.IpAddress getSrcIpAddress(); + method @Nullable public long getSrcPort(); + method public void setDataPassthrough(@Nullable boolean); + method public void setDestIpAddress(@Nullable android.media.tuner.testing.configuration.V1_0.IpAddress); + method public void setDestPort(@Nullable long); + method public void setIpCid(@Nullable java.math.BigInteger); + method public void setSrcIpAddress(@Nullable android.media.tuner.testing.configuration.V1_0.IpAddress); + method public void setSrcPort(@Nullable long); + } + public class Lnb { ctor public Lnb(); method @Nullable public String getId(); diff --git a/tv/tuner/config/sample_tuner_vts_config.xml b/tv/tuner/config/sample_tuner_vts_config_1_0.xml similarity index 100% rename from tv/tuner/config/sample_tuner_vts_config.xml rename to tv/tuner/config/sample_tuner_vts_config_1_0.xml diff --git a/tv/tuner/config/sample_tuner_vts_config_1_1.xml b/tv/tuner/config/sample_tuner_vts_config_1_1.xml new file mode 100644 index 0000000000..191e51cb81 --- /dev/null +++ b/tv/tuner/config/sample_tuner_vts_config_1_1.xml @@ -0,0 +1,158 @@ + + + + + + + + + + + + + + + + + + + + 2 + + + + + 2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tv/tuner/config/tuner_testing_dynamic_configuration.xsd b/tv/tuner/config/tuner_testing_dynamic_configuration.xsd index 3fe93ff120..3303657876 100644 --- a/tv/tuner/config/tuner_testing_dynamic_configuration.xsd +++ b/tv/tuner/config/tuner_testing_dynamic_configuration.xsd @@ -49,15 +49,27 @@ + + + + + + + + + + + + @@ -137,13 +149,19 @@ + + + + + + - @@ -161,10 +179,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -197,20 +242,28 @@ config only to the hal. - - - - - - - + + + + + + + + + + + + + + + @@ -396,7 +449,7 @@ - + @@ -541,6 +594,7 @@ + -- GitLab From c7582670a5a4593795566848ff833f46b2bffc10 Mon Sep 17 00:00:00 2001 From: Hongbo Zeng Date: Sat, 10 Apr 2021 21:14:53 +0800 Subject: [PATCH 597/790] Check more errors for VTS getSlicingConfig - add RADIO_NOT_AVAILABLE/INTERNAL_ERR/MODEM_ERR errors for normal case as defined in IRadioResponse.hal Bug: 181634613 Test: * run command => atest VtsHalRadioV1_6TargetTest -- --test-arg com.android.tradefed.testtype.GTest:native-test-flag:"--gtest_filter=*slot1" and check the test result is PASSED [3/19] PerInstance/RadioHidlTest_v1_6#getSlicingConfig/0_slot1: PASSED (28ms) Change-Id: If813cc51d0d06138aeebe4b528569c214677a1d2 --- radio/1.6/vts/functional/radio_hidl_hal_api.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp index 6cf4567782..2f08e834df 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp +++ b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp @@ -180,7 +180,12 @@ TEST_P(RadioHidlTest_v1_6, getSlicingConfig) { radioRsp_v1_6->rspInfo.error, {::android::hardware::radio::V1_6::RadioError::REQUEST_NOT_SUPPORTED})); } else { - EXPECT_EQ(::android::hardware::radio::V1_6::RadioError::NONE, radioRsp_v1_6->rspInfo.error); + ASSERT_TRUE( + CheckAnyOfErrors(radioRsp_v1_6->rspInfo.error, + {::android::hardware::radio::V1_6::RadioError::NONE, + ::android::hardware::radio::V1_6::RadioError::RADIO_NOT_AVAILABLE, + ::android::hardware::radio::V1_6::RadioError::INTERNAL_ERR, + ::android::hardware::radio::V1_6::RadioError::MODEM_ERR})); } } -- GitLab From 1731084b4eb5532590717112e80ddbefc69a67f0 Mon Sep 17 00:00:00 2001 From: Robert Shih Date: Mon, 29 Mar 2021 12:55:21 -0700 Subject: [PATCH 598/790] drm@1.2 vts: close session before modifying offline licenses Bug: 178904788 Test: VtsHalDrmV1_2TargetTest Change-Id: Ia2c7830dc24abf293fa5b9ffa13e2394232cdd4b --- drm/1.2/vts/functional/drm_hal_test.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drm/1.2/vts/functional/drm_hal_test.cpp b/drm/1.2/vts/functional/drm_hal_test.cpp index 0dfff26528..2d1068dcd2 100644 --- a/drm/1.2/vts/functional/drm_hal_test.cpp +++ b/drm/1.2/vts/functional/drm_hal_test.cpp @@ -172,6 +172,7 @@ void checkKeySetIdState(Status status, OfflineLicenseState state) { TEST_P(DrmHalTest, OfflineLicenseTest) { auto sessionId = openSession(); hidl_vec keySetId = loadKeys(sessionId, KeyType::OFFLINE); + closeSession(sessionId); auto res = drmPlugin->getOfflineLicenseKeySetIds( [&](Status status, const hidl_vec& keySetIds) { @@ -201,8 +202,6 @@ TEST_P(DrmHalTest, OfflineLicenseTest) { err = drmPlugin->removeOfflineLicense(keySetId); EXPECT_EQ(Status::BAD_VALUE, err); - - closeSession(sessionId); } /** @@ -212,6 +211,8 @@ TEST_P(DrmHalTest, OfflineLicenseStateTest) { auto sessionId = openSession(); DrmHalVTSVendorModule_V1::ContentConfiguration content = getContent(KeyType::OFFLINE); hidl_vec keySetId = loadKeys(sessionId, content, KeyType::OFFLINE); + closeSession(sessionId); + drmPlugin->getOfflineLicenseState(keySetId, checkKeySetIdState); hidl_vec keyRequest = getKeyRequest(keySetId, content, KeyType::RELEASE); @@ -226,7 +227,6 @@ TEST_P(DrmHalTest, OfflineLicenseStateTest) { provideKeyResponse(keySetId, keyResponse); drmPlugin->getOfflineLicenseState(keySetId, checkKeySetIdState); - closeSession(sessionId); } /** -- GitLab From 5f82f49d4f31f0622b422e6254aa60d36f4a61fa Mon Sep 17 00:00:00 2001 From: jiabin Date: Fri, 9 Apr 2021 19:03:58 +0000 Subject: [PATCH 599/790] Count channel mapping number from the back. The channel mapping array may have leading UNUSED value. In that case, count the channel mapping number from the back to avoid lost channel mapping information. Bug: 183558363 Test: repo steps in the bug Test: atest android.hardware.audio@7.0-util_tests Change-Id: Ic4238e520c16eb1daad7c9e92555e92637f8e7c9 --- audio/core/all-versions/default/util/CoreUtils.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/audio/core/all-versions/default/util/CoreUtils.cpp b/audio/core/all-versions/default/util/CoreUtils.cpp index 14f76f3c65..773be21962 100644 --- a/audio/core/all-versions/default/util/CoreUtils.cpp +++ b/audio/core/all-versions/default/util/CoreUtils.cpp @@ -66,13 +66,13 @@ status_t CoreUtils::microphoneInfoFromHal( CONVERT_CHECKED( deviceAddressFromHal(halMicInfo.device, halMicInfo.address, &micInfo->deviceAddress), result); - size_t chCount; - for (chCount = 0; chCount < AUDIO_CHANNEL_COUNT_MAX; ++chCount) { - if (halMicInfo.channel_mapping[chCount] == AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED) { + int chCount; + for (chCount = AUDIO_CHANNEL_COUNT_MAX - 1; chCount >= 0; --chCount) { + if (halMicInfo.channel_mapping[chCount] != AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED) { break; } } - micInfo->channelMapping.resize(chCount); + micInfo->channelMapping.resize(chCount + 1); for (size_t ch = 0; ch < micInfo->channelMapping.size(); ch++) { micInfo->channelMapping[ch] = AudioMicrophoneChannelMapping(halMicInfo.channel_mapping[ch]); } -- GitLab From 8baf60005853af814834cf23be0afc0d4ebb2f3b Mon Sep 17 00:00:00 2001 From: David Su Date: Wed, 31 Mar 2021 12:27:21 -0700 Subject: [PATCH 600/790] Wifi HAL Multi STA: Clarify behavior during single STA Firmware should maintain the last set multi STA use case & primary connection across periods of single STA. Bug: 183861582 Test: compiles Change-Id: Iab7b9298216a90ddcd792aec794266c9edb397fa --- wifi/1.5/IWifiChip.hal | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/wifi/1.5/IWifiChip.hal b/wifi/1.5/IWifiChip.hal index e199850c1a..8d7a36e285 100644 --- a/wifi/1.5/IWifiChip.hal +++ b/wifi/1.5/IWifiChip.hal @@ -47,6 +47,15 @@ interface IWifiChip extends @1.4::IWifiChip { * - This will be invoked before an active wifi connection is established on the second * interface. * - This use-case hint is implicitly void when the second STA interface is brought down. + * - When there is only 1 STA interface, the must should still retain the last use case + * set, which must become active the next time multi STA is enabled. + * 1. Initialize with single STA. + * 2. Framework creates second STA. + * 3. Framework sets use case to DUAL_STA_NON_TRANSIENT_UNBIASED. + * 4. Framework destroys second STA. Only 1 STA remains. + * 5. Framework recreates second STA. + * 6. The active use case remains DUAL_STA_NON_TRANSIENT_UNBIASED (i.e. firmware should not + * automatically change it during period of single STA unless requested by framework). */ enum MultiStaUseCase : uint8_t { /** @@ -100,11 +109,14 @@ interface IWifiChip extends @1.4::IWifiChip { /** * Invoked to indicate that the provided iface is the primary STA iface when there are more * than 1 STA iface concurrently active. - * Note: If the wifi firmware/chip cannot support multiple instances of any offload - * (like roaming, APF, rssi threshold, etc), the firmware should ensure that these - * offloads are at least enabled for the primary interface. If the new primary interface is - * already connected to a network, the firmware must switch all the offloads on - * this new interface without disconnecting. + * Notes: + * - If the wifi firmware/chip cannot support multiple instances of any offload + * (like roaming, APF, rssi threshold, etc), the firmware should ensure that these + * offloads are at least enabled for the primary interface. If the new primary interface is + * already connected to a network, the firmware must switch all the offloads on + * this new interface without disconnecting. + * - When there is only 1 STA interface, the firmware must still retain the last primary + * connection, which must become active the next time multi STA is enabled. * * @param ifname Name of the STA iface. * @return status WifiStatus of the operation. -- GitLab From f03a62f25c94c4848272a584bdbdb259f6d07b35 Mon Sep 17 00:00:00 2001 From: Zoey Chen Date: Mon, 12 Apr 2021 13:53:05 +0800 Subject: [PATCH 601/790] [ANAPIC Review] Remove config 1.3 hal Bug: 183738012 Test: build Change-Id: Ie0eec5576d08ddcd9a8f5ee1a1d9e2b32772653e --- .../1.6/vts/functional/radio_hidl_hal_api.cpp | 14 +++---- .../vts/functional/radio_hidl_hal_test.cpp | 10 ++--- .../functional/radio_hidl_hal_utils_v1_6.h | 4 +- radio/config/1.3/Android.bp | 1 - radio/config/1.3/IRadioConfigResponse.hal | 17 ++++++-- radio/config/1.3/types.hal | 42 ------------------- .../functional/radio_config_hidl_hal_utils.h | 6 +-- .../vts/functional/radio_config_response.cpp | 4 +- 8 files changed, 29 insertions(+), 69 deletions(-) delete mode 100644 radio/config/1.3/types.hal diff --git a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp index 6cf4567782..e794d2eb3e 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp +++ b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp @@ -175,7 +175,7 @@ TEST_P(RadioHidlTest_v1_6, getSlicingConfig) { EXPECT_EQ(std::cv_status::no_timeout, wait()); EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type); EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial); - if (getRadioHalCapabilities().modemReducedFeatureSet1) { + if (getRadioHalCapabilities()) { ASSERT_TRUE(CheckAnyOfErrors( radioRsp_v1_6->rspInfo.error, {::android::hardware::radio::V1_6::RadioError::REQUEST_NOT_SUPPORTED})); @@ -378,7 +378,7 @@ TEST_P(RadioHidlTest_v1_6, setNrDualConnectivityState) { EXPECT_EQ(std::cv_status::no_timeout, wait()); EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type); EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial); - if (getRadioHalCapabilities().modemReducedFeatureSet1) { + if (getRadioHalCapabilities()) { ASSERT_TRUE(CheckAnyOfErrors( radioRsp_v1_6->rspInfo.error, {::android::hardware::radio::V1_6::RadioError::REQUEST_NOT_SUPPORTED})); @@ -403,7 +403,7 @@ TEST_P(RadioHidlTest_v1_6, isNrDualConnectivityEnabled) { EXPECT_EQ(std::cv_status::no_timeout, wait()); EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type); EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial); - if (getRadioHalCapabilities().modemReducedFeatureSet1) { + if (getRadioHalCapabilities()) { ASSERT_TRUE(CheckAnyOfErrors( radioRsp_v1_6->rspInfo.error, {::android::hardware::radio::V1_6::RadioError::REQUEST_NOT_SUPPORTED})); @@ -429,7 +429,7 @@ TEST_P(RadioHidlTest_v1_6, setDataThrottling) { EXPECT_EQ(std::cv_status::no_timeout, wait()); EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type); EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial); - if (getRadioHalCapabilities().modemReducedFeatureSet1) { + if (getRadioHalCapabilities()) { ASSERT_TRUE(CheckAnyOfErrors( radioRsp_v1_6->rspInfo.error, {::android::hardware::radio::V1_6::RadioError::REQUEST_NOT_SUPPORTED})); @@ -449,7 +449,7 @@ TEST_P(RadioHidlTest_v1_6, setDataThrottling) { EXPECT_EQ(std::cv_status::no_timeout, wait()); EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type); EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial); - if (getRadioHalCapabilities().modemReducedFeatureSet1) { + if (getRadioHalCapabilities()) { ASSERT_TRUE(CheckAnyOfErrors( radioRsp_v1_6->rspInfo.error, {::android::hardware::radio::V1_6::RadioError::REQUEST_NOT_SUPPORTED})); @@ -469,7 +469,7 @@ TEST_P(RadioHidlTest_v1_6, setDataThrottling) { EXPECT_EQ(std::cv_status::no_timeout, wait()); EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type); EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial); - if (getRadioHalCapabilities().modemReducedFeatureSet1) { + if (getRadioHalCapabilities()) { ASSERT_TRUE(CheckAnyOfErrors( radioRsp_v1_6->rspInfo.error, {::android::hardware::radio::V1_6::RadioError::REQUEST_NOT_SUPPORTED})); @@ -488,7 +488,7 @@ TEST_P(RadioHidlTest_v1_6, setDataThrottling) { EXPECT_EQ(std::cv_status::no_timeout, wait()); EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type); EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial); - if (getRadioHalCapabilities().modemReducedFeatureSet1) { + if (getRadioHalCapabilities()) { ASSERT_TRUE(CheckAnyOfErrors( radioRsp_v1_6->rspInfo.error, {::android::hardware::radio::V1_6::RadioError::REQUEST_NOT_SUPPORTED})); diff --git a/radio/1.6/vts/functional/radio_hidl_hal_test.cpp b/radio/1.6/vts/functional/radio_hidl_hal_test.cpp index 6255f66f69..5d514a0e6e 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_test.cpp +++ b/radio/1.6/vts/functional/radio_hidl_hal_test.cpp @@ -86,16 +86,14 @@ void RadioHidlTest_v1_6::getDataCallList() { * disabled. *

    * Typical usage within VTS: - * if (getRadioHalCapabilities().modemReducedFeatureSet) return; + * if (getRadioHalCapabilities()) return; */ -HalDeviceCapabilities RadioHidlTest_v1_6::getRadioHalCapabilities() { +bool RadioHidlTest_v1_6::getRadioHalCapabilities() { sp<::android::hardware::radio::config::V1_3::IRadioConfig> radioConfig_v1_3 = ::android::hardware::radio::config::V1_3::IRadioConfig::getService(); if (radioConfig_v1_3.get() == nullptr) { // If v1_3 isn't present, the values are initialized to false - HalDeviceCapabilities radioHalCapabilities; - memset(&radioHalCapabilities, 0, sizeof(radioHalCapabilities)); - return radioHalCapabilities; + return false; } else { // Get radioHalDeviceCapabilities from the radio config sp radioConfigRsp = new (std::nothrow) RadioConfigResponse(*this); @@ -104,6 +102,6 @@ HalDeviceCapabilities RadioHidlTest_v1_6::getRadioHalCapabilities() { radioConfig_v1_3->getHalDeviceCapabilities(serial); EXPECT_EQ(std::cv_status::no_timeout, wait()); - return radioConfigRsp->halDeviceCapabilities; + return radioConfigRsp->modemReducedFeatureSet1; } } diff --git a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h index 4fc17e54d0..114091a9d8 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h +++ b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h @@ -38,14 +38,12 @@ using namespace ::android::hardware::radio::V1_3; using namespace ::android::hardware::radio::V1_2; using namespace ::android::hardware::radio::V1_1; using namespace ::android::hardware::radio::V1_0; -using namespace ::android::hardware::radio::config::V1_3; using ::android::sp; using ::android::hardware::hidl_string; using ::android::hardware::hidl_vec; using ::android::hardware::Return; using ::android::hardware::Void; -using ::android::hardware::radio::config::V1_3::HalDeviceCapabilities; #define MODEM_EMERGENCY_CALL_ESTABLISH_TIME 3 #define MODEM_EMERGENCY_CALL_DISCONNECT_TIME 3 @@ -1115,7 +1113,7 @@ class RadioHidlTest_v1_6 : public ::testing::TestWithParam, public: virtual void SetUp() override; - HalDeviceCapabilities getRadioHalCapabilities(); + bool getRadioHalCapabilities(); /* radio service handle */ sp<::android::hardware::radio::V1_6::IRadio> radio_v1_6; diff --git a/radio/config/1.3/Android.bp b/radio/config/1.3/Android.bp index cc5944df44..dc0d82cabd 100644 --- a/radio/config/1.3/Android.bp +++ b/radio/config/1.3/Android.bp @@ -13,7 +13,6 @@ hidl_interface { name: "android.hardware.radio.config@1.3", root: "android.hardware", srcs: [ - "types.hal", "IRadioConfig.hal", "IRadioConfigResponse.hal", ], diff --git a/radio/config/1.3/IRadioConfigResponse.hal b/radio/config/1.3/IRadioConfigResponse.hal index 863754f374..15eefed82c 100644 --- a/radio/config/1.3/IRadioConfigResponse.hal +++ b/radio/config/1.3/IRadioConfigResponse.hal @@ -18,7 +18,6 @@ package android.hardware.radio.config@1.3; import android.hardware.radio@1.6::RadioResponseInfo; import @1.2::IRadioConfigResponse; -import HalDeviceCapabilities; /** * Interface declaring response functions to solicited radio config requests. @@ -26,8 +25,18 @@ import HalDeviceCapabilities; interface IRadioConfigResponse extends @1.2::IRadioConfigResponse { /** * @param info Response info struct containing response type, serial no. and error - * @param capabilities Capabilities struct containing the capabilities of the - * device related to the Radio HAL + * @param modemReducedFeatureSet1 True indicates that the modem does NOT support the following + * features. + * - Providing either + * android.hardware.radio@1.6::LinkCapacityEstimate:secondaryDownlinkCapacityKbps + * or android.hardware.radio@1.6::LinkCapacityEstimate:secondaryUplinkCapacityKbps + * when given from + * android.hardware.radio@1.6::RadioIndication:currentLinkCapacityEstimate + * - Calling android.hardware.radio@1.6::IRadio.setNrDualConnectivityState + * or querying android.hardware.radio@1.6::IRadio.isNrDualConnectivityEnabled + * - Requesting android.hardware.radio@1.6::IRadio.setDataThrottling() + * - Providing android.hardware.radio@1.6::SlicingConfig through + * android.hardware.radio@1.6::getSlicingConfig() * * Valid errors returned: * RadioError:NONE @@ -35,5 +44,5 @@ interface IRadioConfigResponse extends @1.2::IRadioConfigResponse { * RadioError:INTERNAL_ERR */ oneway getHalDeviceCapabilitiesResponse(RadioResponseInfo info, - HalDeviceCapabilities capabilities); + bool modemReducedFeatureSet1); }; diff --git a/radio/config/1.3/types.hal b/radio/config/1.3/types.hal deleted file mode 100644 index 8667f0ab4f..0000000000 --- a/radio/config/1.3/types.hal +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.hardware.radio.config@1.3; - -/** - * Contains the device capabilities with respect to the Radio HAL. - */ -struct HalDeviceCapabilities { - /** - * True indicates that the modem does NOT support the following features: - *

      - *
    • Providing either - * android.hardware.radio@1.6::LinkCapacityEstimate:secondaryDownlinkCapacityKbps - * or android.hardware.radio@1.6::LinkCapacityEstimate:secondaryUplinkCapacityKbps - * when given from android.hardware.radio@1.6::RadioIndication:currentLinkCapacityEstimate - *
    • - *
    • calling android.hardware.radio@1.6::IRadio.setNrDualConnectivityState - * or querying android.hardware.radio@1.6::IRadio.isNrDualConnectivityEnabled - *
    • - *
    • Requesting android.hardware.radio@1.6::IRadio.setDataThrottling() - *
    • - *
    • Providing android.hardware.radio@1.6::SlicingConfig through - * android.hardware.radio@1.6::getSlicingConfig() - *
    • - *
    - */ - bool modemReducedFeatureSet1; -}; diff --git a/radio/config/1.3/vts/functional/radio_config_hidl_hal_utils.h b/radio/config/1.3/vts/functional/radio_config_hidl_hal_utils.h index 50038eb478..7235798f43 100644 --- a/radio/config/1.3/vts/functional/radio_config_hidl_hal_utils.h +++ b/radio/config/1.3/vts/functional/radio_config_hidl_hal_utils.h @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include @@ -48,7 +47,6 @@ using ::android::hardware::radio::config::V1_1::ModemsConfig; using ::android::hardware::radio::config::V1_1::PhoneCapability; using ::android::hardware::radio::config::V1_2::IRadioConfigIndication; using ::android::hardware::radio::config::V1_2::SimSlotStatus; -using ::android::hardware::radio::config::V1_3::HalDeviceCapabilities; using ::android::hardware::radio::config::V1_3::IRadioConfig; using ::android::hardware::radio::config::V1_3::IRadioConfigResponse; using ::android::hardware::radio::V1_0::RadioResponseInfo; @@ -65,7 +63,7 @@ class RadioConfigResponse : public IRadioConfigResponse { public: RadioResponseInfo rspInfo; PhoneCapability phoneCap; - HalDeviceCapabilities halDeviceCapabilities; + bool modemReducedFeatureSet1; RadioConfigResponse(RadioResponseWaiter& parent); virtual ~RadioConfigResponse() = default; @@ -93,7 +91,7 @@ class RadioConfigResponse : public IRadioConfigResponse { Return getHalDeviceCapabilitiesResponse( const ::android::hardware::radio::V1_6::RadioResponseInfo& info, - const HalDeviceCapabilities& halDeviceCapabilities); + bool modemReducedFeatureSet1); }; /* Callback class for radio config indication */ diff --git a/radio/config/1.3/vts/functional/radio_config_response.cpp b/radio/config/1.3/vts/functional/radio_config_response.cpp index 5501ae25e8..6188733f66 100644 --- a/radio/config/1.3/vts/functional/radio_config_response.cpp +++ b/radio/config/1.3/vts/functional/radio_config_response.cpp @@ -65,8 +65,8 @@ Return RadioConfigResponse::setModemsConfigResponse( Return RadioConfigResponse::getHalDeviceCapabilitiesResponse( const ::android::hardware::radio::V1_6::RadioResponseInfo& info, - const ::android::hardware::radio::config::V1_3::HalDeviceCapabilities& capabilities) { - halDeviceCapabilities = capabilities; + bool modemReducedFeatures) { + modemReducedFeatureSet1 = modemReducedFeatures; parent.notify(info.serial); return Void(); } -- GitLab From bdd7e7e5112e89167346e36f02bcf9d83b3b63a7 Mon Sep 17 00:00:00 2001 From: Alec Mouri Date: Mon, 12 Apr 2021 17:56:00 -0700 Subject: [PATCH 602/790] Update Readback VTS to align with RenderEngine interface change RenderEngine no longer directly takes in GraphicBuffer objects. Instead, it takes in ExternalTexture types that manage resources associated with a GraphicBuffer. Bug: 180767535 Test: builds Change-Id: I13904eec491fce223b6178fa5571589b67402865 --- .../composer/2.2/utils/vts/ReadbackVts.cpp | 15 ++++--- .../2.2/utils/vts/RenderEngineVts.cpp | 4 +- .../include/composer-vts/2.2/ReadbackVts.h | 6 ++- .../composer-vts/2.2/RenderEngineVts.h | 6 +++ ...VtsHalGraphicsComposerV2_2ReadbackTest.cpp | 44 +++++++++---------- 5 files changed, 46 insertions(+), 29 deletions(-) diff --git a/graphics/composer/2.2/utils/vts/ReadbackVts.cpp b/graphics/composer/2.2/utils/vts/ReadbackVts.cpp index b179f35109..19f5e8c614 100644 --- a/graphics/composer/2.2/utils/vts/ReadbackVts.cpp +++ b/graphics/composer/2.2/utils/vts/ReadbackVts.cpp @@ -15,6 +15,8 @@ */ #include +#include +#include "renderengine/ExternalTexture.h" namespace android { namespace hardware { @@ -257,10 +259,11 @@ LayerSettings TestColorLayer::toRenderEngineLayerSettings() { } TestBufferLayer::TestBufferLayer(const std::shared_ptr& client, - const std::shared_ptr& gralloc, Display display, - int32_t width, int32_t height, PixelFormat format, + const std::shared_ptr& gralloc, + TestRenderEngine& renderEngine, Display display, int32_t width, + int32_t height, PixelFormat format, IComposerClient::Composition composition) - : TestLayer{client, display} { + : TestLayer{client, display}, mRenderEngine(renderEngine) { mGralloc = gralloc; mComposition = composition; mWidth = width; @@ -293,9 +296,11 @@ void TestBufferLayer::write(const std::shared_ptr& writer) { LayerSettings TestBufferLayer::toRenderEngineLayerSettings() { LayerSettings layerSettings = TestLayer::toRenderEngineLayerSettings(); - layerSettings.source.buffer.buffer = + layerSettings.source.buffer.buffer = std::make_shared( new GraphicBuffer(mBufferHandle, GraphicBuffer::CLONE_HANDLE, mWidth, mHeight, - static_cast(mFormat), 1, mUsage, mStride); + static_cast(mFormat), 1, mUsage, mStride), + mRenderEngine.getInternalRenderEngine(), + renderengine::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 3becacea91..f78dda2689 100644 --- a/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp +++ b/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp @@ -69,7 +69,9 @@ void TestRenderEngine::drawLayers() { [](renderengine::LayerSettings& settings) -> renderengine::LayerSettings* { return &settings; }); - mRenderEngine->drawLayers(mDisplaySettings, compositionLayerPointers, mGraphicBuffer, true, + auto texture = std::make_shared( + mGraphicBuffer, *mRenderEngine, renderengine::ExternalTexture::Usage::WRITEABLE); + mRenderEngine->drawLayers(mDisplaySettings, compositionLayerPointers, texture, true, std::move(bufferFence), &readyFence); int fd = readyFence.release(); if (fd != -1) { diff --git a/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ReadbackVts.h b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ReadbackVts.h index d5eedf122c..b24e3b63bd 100644 --- a/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ReadbackVts.h +++ b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ReadbackVts.h @@ -50,6 +50,8 @@ static const IComposerClient::Color TRANSLUCENT_RED = {0xff, 0, 0, 0x33}; static const IComposerClient::Color GREEN = {0, 0xff, 0, 0xff}; static const IComposerClient::Color BLUE = {0, 0, 0xff, 0xff}; +class TestRenderEngine; + class TestLayer { public: TestLayer(const std::shared_ptr& client, Display display) @@ -110,7 +112,8 @@ class TestBufferLayer : public TestLayer { public: TestBufferLayer( const std::shared_ptr& client, const std::shared_ptr& gralloc, - Display display, int32_t width, int32_t height, PixelFormat format, + TestRenderEngine& renderEngine, Display display, int32_t width, int32_t height, + PixelFormat format, IComposerClient::Composition composition = IComposerClient::Composition::DEVICE); ~TestBufferLayer(); @@ -138,6 +141,7 @@ class TestBufferLayer : public TestLayer { protected: IComposerClient::Composition mComposition; std::shared_ptr mGralloc; + TestRenderEngine& mRenderEngine; int32_t mFillFence; const native_handle_t* mBufferHandle = nullptr; }; diff --git a/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/RenderEngineVts.h b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/RenderEngineVts.h index f2d5f1933f..26027d33a2 100644 --- a/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/RenderEngineVts.h +++ b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/RenderEngineVts.h @@ -14,9 +14,12 @@ * limitations under the License. */ +#pragma once + #include #include #include +#include #include #include #include @@ -51,12 +54,15 @@ class TestRenderEngine { void drawLayers(); void checkColorBuffer(std::vector& expectedColors); + renderengine::RenderEngine& getInternalRenderEngine() { return *mRenderEngine; } + private: common::V1_1::PixelFormat mFormat; std::vector mCompositionLayers; std::unique_ptr mRenderEngine; std::vector mRenderLayers; sp mGraphicBuffer; + DisplaySettings mDisplaySettings; }; diff --git a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp index 1463c3be6c..8d52173e59 100644 --- a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp +++ b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp @@ -288,9 +288,9 @@ TEST_P(GraphicsCompositionTest, SetLayerBuffer) { {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight}, BLUE); - auto layer = std::make_shared(mComposerClient, mGralloc, mPrimaryDisplay, - mDisplayWidth, mDisplayHeight, - PixelFormat::RGBA_8888); + auto layer = std::make_shared( + mComposerClient, mGralloc, *mTestRenderEngine, mPrimaryDisplay, mDisplayWidth, + mDisplayHeight, PixelFormat::RGBA_8888); layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight}); layer->setZOrder(10); layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter); @@ -422,9 +422,9 @@ TEST_P(GraphicsCompositionTest, ClientComposition) { {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight}, BLUE); - auto layer = std::make_shared(mComposerClient, mGralloc, mPrimaryDisplay, - mDisplayWidth, mDisplayHeight, - PixelFormat::RGBA_FP16); + auto layer = std::make_shared( + mComposerClient, mGralloc, *mTestRenderEngine, mPrimaryDisplay, mDisplayWidth, + mDisplayHeight, PixelFormat::RGBA_FP16); layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight}); layer->setZOrder(10); layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter); @@ -538,8 +538,8 @@ TEST_P(GraphicsCompositionTest, DeviceAndClientComposition) { ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer()); auto deviceLayer = std::make_shared( - mComposerClient, mGralloc, mPrimaryDisplay, mDisplayWidth, mDisplayHeight / 2, - PixelFormat::RGBA_8888); + mComposerClient, mGralloc, *mTestRenderEngine, mPrimaryDisplay, mDisplayWidth, + mDisplayHeight / 2, PixelFormat::RGBA_8888); std::vector deviceColors(deviceLayer->mWidth * deviceLayer->mHeight); ReadbackHelper::fillColorsArea(deviceColors, deviceLayer->mWidth, @@ -575,8 +575,8 @@ TEST_P(GraphicsCompositionTest, DeviceAndClientComposition) { } auto clientLayer = std::make_shared( - mComposerClient, mGralloc, mPrimaryDisplay, clientWidth, clientHeight, - PixelFormat::RGBA_FP16, IComposerClient::Composition::DEVICE); + mComposerClient, mGralloc, *mTestRenderEngine, mPrimaryDisplay, clientWidth, + clientHeight, PixelFormat::RGBA_FP16, IComposerClient::Composition::DEVICE); IComposerClient::Rect clientFrame = {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight}; clientLayer->setDisplayFrame(clientFrame); clientLayer->setZOrder(0); @@ -657,9 +657,9 @@ TEST_P(GraphicsCompositionTest, SetLayerDamage) { std::vector expectedColors(mDisplayWidth * mDisplayHeight); ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, redRect, RED); - auto layer = std::make_shared(mComposerClient, mGralloc, mPrimaryDisplay, - mDisplayWidth, mDisplayHeight, - PixelFormat::RGBA_8888); + auto layer = std::make_shared( + mComposerClient, mGralloc, *mTestRenderEngine, mPrimaryDisplay, mDisplayWidth, + mDisplayHeight, PixelFormat::RGBA_8888); layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight}); layer->setZOrder(10); layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter); @@ -805,9 +805,9 @@ TEST_P(GraphicsCompositionTest, SetLayerSourceCrop) { {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight}, BLUE); - auto layer = std::make_shared(mComposerClient, mGralloc, mPrimaryDisplay, - mDisplayWidth, mDisplayHeight, - PixelFormat::RGBA_8888); + auto layer = std::make_shared( + mComposerClient, mGralloc, *mTestRenderEngine, mPrimaryDisplay, mDisplayWidth, + mDisplayHeight, PixelFormat::RGBA_8888); layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight}); layer->setZOrder(10); layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter); @@ -957,9 +957,9 @@ class GraphicsBlendModeCompositionTest backgroundLayer->setZOrder(0); backgroundLayer->setColor(mBackgroundColor); - auto layer = std::make_shared(mComposerClient, mGralloc, mPrimaryDisplay, - mDisplayWidth, mDisplayHeight, - PixelFormat::RGBA_8888); + auto layer = std::make_shared( + mComposerClient, mGralloc, *mTestRenderEngine, mPrimaryDisplay, mDisplayWidth, + mDisplayHeight, PixelFormat::RGBA_8888); layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight}); layer->setZOrder(10); layer->setDataspace(Dataspace::UNKNOWN, mWriter); @@ -1195,9 +1195,9 @@ class GraphicsTransformCompositionTest : public GraphicsCompositionTest { IComposerClient::Rect blueRect = {mSideLength / 2, mSideLength / 2, mSideLength, mSideLength}; - mLayer = - std::make_shared(mComposerClient, mGralloc, mPrimaryDisplay, - mSideLength, mSideLength, PixelFormat::RGBA_8888); + mLayer = std::make_shared(mComposerClient, mGralloc, *mTestRenderEngine, + mPrimaryDisplay, mSideLength, mSideLength, + PixelFormat::RGBA_8888); mLayer->setDisplayFrame({0, 0, mSideLength, mSideLength}); mLayer->setZOrder(10); -- GitLab From a8ac7cf706be7a77589070ea7c62f8e1b94ce316 Mon Sep 17 00:00:00 2001 From: Steven Moreland Date: Tue, 13 Apr 2021 20:14:16 +0000 Subject: [PATCH 603/790] audio HAL - fix UAFs Bug: 185259758 Test: N/A Change-Id: I5ec70b098a00746108e10ab39e966607d78c84ae --- audio/core/all-versions/default/StreamIn.cpp | 6 +++--- audio/core/all-versions/default/StreamOut.cpp | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/audio/core/all-versions/default/StreamIn.cpp b/audio/core/all-versions/default/StreamIn.cpp index 599f3c396e..2aeee43c59 100644 --- a/audio/core/all-versions/default/StreamIn.cpp +++ b/audio/core/all-versions/default/StreamIn.cpp @@ -413,8 +413,8 @@ Return StreamIn::prepareForReading(uint32_t frameSize, uint32_t framesCoun // Create and launch the thread. auto tempReadThread = - std::make_unique(&mStopReadThread, mStream, tempCommandMQ.get(), - tempDataMQ.get(), tempStatusMQ.get(), tempElfGroup.get()); + sp::make(&mStopReadThread, mStream, tempCommandMQ.get(), tempDataMQ.get(), + tempStatusMQ.get(), tempElfGroup.get()); if (!tempReadThread->init()) { ALOGW("failed to start reader thread: %s", strerror(-status)); sendError(Result::INVALID_ARGUMENTS); @@ -430,7 +430,7 @@ Return StreamIn::prepareForReading(uint32_t frameSize, uint32_t framesCoun mCommandMQ = std::move(tempCommandMQ); mDataMQ = std::move(tempDataMQ); mStatusMQ = std::move(tempStatusMQ); - mReadThread = tempReadThread.release(); + mReadThread = tempReadThread; mEfGroup = tempElfGroup.release(); #if MAJOR_VERSION <= 6 threadInfo.pid = getpid(); diff --git a/audio/core/all-versions/default/StreamOut.cpp b/audio/core/all-versions/default/StreamOut.cpp index 5e4dd2ad40..6eed3daf12 100644 --- a/audio/core/all-versions/default/StreamOut.cpp +++ b/audio/core/all-versions/default/StreamOut.cpp @@ -398,8 +398,8 @@ Return StreamOut::prepareForWriting(uint32_t frameSize, uint32_t framesCou // Create and launch the thread. auto tempWriteThread = - std::make_unique(&mStopWriteThread, mStream, tempCommandMQ.get(), - tempDataMQ.get(), tempStatusMQ.get(), tempElfGroup.get()); + sp::make(&mStopWriteThread, mStream, tempCommandMQ.get(), tempDataMQ.get(), + tempStatusMQ.get(), tempElfGroup.get()); if (!tempWriteThread->init()) { ALOGW("failed to start writer thread: %s", strerror(-status)); sendError(Result::INVALID_ARGUMENTS); @@ -415,7 +415,7 @@ Return StreamOut::prepareForWriting(uint32_t frameSize, uint32_t framesCou mCommandMQ = std::move(tempCommandMQ); mDataMQ = std::move(tempDataMQ); mStatusMQ = std::move(tempStatusMQ); - mWriteThread = tempWriteThread.release(); + mWriteThread = tempWriteThread; mEfGroup = tempElfGroup.release(); #if MAJOR_VERSION <= 6 threadInfo.pid = getpid(); -- GitLab From b2da76d64be2f62e28272efbd86cb9d1080cb4f9 Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Wed, 14 Apr 2021 10:18:17 +0800 Subject: [PATCH 604/790] wifi: correct WPA cipher GCMP-128 bit Bug: 185202617 Test: atest VtsHalWifiSupplicantV1_4TargetTest Change-Id: I78fb68d0a4c046759592ceed7089a58c5ea69064 --- wifi/supplicant/1.4/ISupplicantStaNetwork.hal | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wifi/supplicant/1.4/ISupplicantStaNetwork.hal b/wifi/supplicant/1.4/ISupplicantStaNetwork.hal index 4f95213223..4dfe8e69ae 100644 --- a/wifi/supplicant/1.4/ISupplicantStaNetwork.hal +++ b/wifi/supplicant/1.4/ISupplicantStaNetwork.hal @@ -41,7 +41,7 @@ interface ISupplicantStaNetwork extends @1.3::ISupplicantStaNetwork { /** * GCMP-128 Pairwise Cipher */ - GCMP_128 = 1 << 9, + GCMP_128 = 1 << 6, }; /** @@ -51,7 +51,7 @@ interface ISupplicantStaNetwork extends @1.3::ISupplicantStaNetwork { /** * GCMP-128 Group Cipher */ - GCMP_128 = 1 << 9, + GCMP_128 = 1 << 6, }; /** -- GitLab From 36f70d6ffcd4d4cfb23658d6ab126dab98a73b13 Mon Sep 17 00:00:00 2001 From: Vince Leung Date: Fri, 9 Apr 2021 21:37:22 +0000 Subject: [PATCH 605/790] Relax timing parameters for vibrator VTS First we set the start timestamp before we call the compose method. We'll increase the allowed latency to if the system is under heavy load then there can be more latencies. Bug: 184578694 Test: atest Change-Id: I5c06017ab0242d32b281ff3a0d0dddcb2106de5d --- vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp index a9d1ed5a51..4d03ebf9f9 100644 --- a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp +++ b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp @@ -553,8 +553,6 @@ TEST_P(VibratorAidl, ComposeSizeBoundary) { } TEST_P(VibratorAidl, ComposeCallback) { - constexpr std::chrono::milliseconds allowedLatency{10}; - if (capabilities & IVibrator::CAP_COMPOSE_EFFECTS) { std::vector supported; @@ -586,17 +584,16 @@ TEST_P(VibratorAidl, ComposeCallback) { << toString(primitive); duration = std::chrono::milliseconds(durationMs); + start = high_resolution_clock::now(); EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, callback).exceptionCode()) << toString(primitive); - start = high_resolution_clock::now(); - EXPECT_EQ(completionFuture.wait_for(duration + allowedLatency), std::future_status::ready) + EXPECT_EQ(completionFuture.wait_for(duration * 2), std::future_status::ready) << toString(primitive); end = high_resolution_clock::now(); elapsed = std::chrono::duration_cast(end - start); - EXPECT_LE(elapsed.count(), (duration + allowedLatency).count()) << toString(primitive); - EXPECT_GE(elapsed.count(), (duration - allowedLatency).count()) << toString(primitive); + EXPECT_GE(elapsed.count(), duration.count()) << toString(primitive); } } } -- GitLab From 786db4a6daea03cd240387617fbb79909789b0f5 Mon Sep 17 00:00:00 2001 From: Kai Date: Mon, 22 Mar 2021 23:25:59 -0700 Subject: [PATCH 606/790] HVAC properties and CRITICALLY_LOW_TIRE_PRESSURE Address the requests from google Assistant team: Add CRITICALLY_LOW_TIRE_PRESSURE to indicate critically low tire pressure Add HVAC_TEMPERATURE_VALUE_SUGGESTION to let OEMs suggest temperature value for android. Bug: 116673704 Bug: 174207039 Bug: 157608587 Bug: 161831228 Bug: 174202040 Test: Use "adb shell cmd car_service get-carpropertyconfig" to check if the properties are added in google HAL. atest VehiclePropertyIdsTest Change-Id: I46b71bc44cfef64755109dd460777f36dd1d2767 --- .../default/impl/vhal_v2_0/DefaultConfig.h | 28 ++++++- automotive/vehicle/2.0/types.hal | 81 +++++++++++++++++++ 2 files changed, 105 insertions(+), 4 deletions(-) diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h index 5915a53c03..6021af11a6 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h @@ -439,22 +439,22 @@ const ConfigDeclaration kVehicleProperties[]{ .changeMode = VehiclePropertyChangeMode::CONTINUOUS, .areaConfigs = {VehicleAreaConfig{ .areaId = WHEEL_FRONT_LEFT, - .minFloatValue = 100.0f, + .minFloatValue = 193.0f, .maxFloatValue = 300.0f, }, VehicleAreaConfig{ .areaId = WHEEL_FRONT_RIGHT, - .minFloatValue = 100.0f, + .minFloatValue = 193.0f, .maxFloatValue = 300.0f, }, VehicleAreaConfig{ .areaId = WHEEL_REAR_LEFT, - .minFloatValue = 100.0f, + .minFloatValue = 193.0f, .maxFloatValue = 300.0f, }, VehicleAreaConfig{ .areaId = WHEEL_REAR_RIGHT, - .minFloatValue = 100.0f, + .minFloatValue = 193.0f, .maxFloatValue = 300.0f, }}, .minSampleRate = 1.0f, @@ -462,6 +462,17 @@ const ConfigDeclaration kVehicleProperties[]{ }, .initialValue = {.floatValues = {200.0f}}}, // units in kPa + {.config = + { + .prop = toInt(VehicleProperty::CRITICALLY_LOW_TIRE_PRESSURE), + .access = VehiclePropertyAccess::READ, + .changeMode = VehiclePropertyChangeMode::STATIC, + }, + .initialAreaValues = {{WHEEL_FRONT_LEFT, {.floatValues = {137.0f}}}, + {WHEEL_FRONT_RIGHT, {.floatValues = {137.0f}}}, + {WHEEL_REAR_RIGHT, {.floatValues = {137.0f}}}, + {WHEEL_REAR_LEFT, {.floatValues = {137.0f}}}}}, + {.config = { .prop = toInt(VehicleProperty::TIRE_PRESSURE_DISPLAY_UNITS), @@ -660,6 +671,7 @@ const ConfigDeclaration kVehicleProperties[]{ {.config = {.prop = toInt(VehicleProperty::HVAC_TEMPERATURE_SET), .access = VehiclePropertyAccess::READ_WRITE, .changeMode = VehiclePropertyChangeMode::ON_CHANGE, + .configArray = {160, 280, 5, 605, 825, 10}, .areaConfigs = {VehicleAreaConfig{ .areaId = HVAC_LEFT, .minFloatValue = 16, @@ -673,6 +685,14 @@ const ConfigDeclaration kVehicleProperties[]{ .initialAreaValues = {{HVAC_LEFT, {.floatValues = {16}}}, {HVAC_RIGHT, {.floatValues = {20}}}}}, + {.config = + { + .prop = toInt(VehicleProperty::HVAC_TEMPERATURE_VALUE_SUGGESTION), + .access = VehiclePropertyAccess::READ_WRITE, + .changeMode = VehiclePropertyChangeMode::ON_CHANGE, + }, + .initialValue = {.floatValues = {66.2f, (float)VehicleUnit::FAHRENHEIT, 19.0f, 66.5f}}}, + {.config = { .prop = toInt(VehicleProperty::ENV_OUTSIDE_TEMPERATURE), diff --git a/automotive/vehicle/2.0/types.hal b/automotive/vehicle/2.0/types.hal index 94645a4b4b..32f7cd60e5 100644 --- a/automotive/vehicle/2.0/types.hal +++ b/automotive/vehicle/2.0/types.hal @@ -640,6 +640,25 @@ enum VehicleProperty : int32_t { | VehiclePropertyType:FLOAT | VehicleArea:WHEEL), + /** + * Critically low tire pressure + * + * This property indicates the critically low pressure threshold for each tire. + * It indicates when it is time for tires to be replaced or fixed. The value + * must be less than or equal to minFloatValue in TIRE_PRESSURE. + * Minimum and maximum property values (that is, minFloatValue, maxFloatValue) + * are not applicable to this property. + * + * @change_mode VehiclePropertyChangeMode:STATIC + * @access VehiclePropertyAccess:READ + * @unit VehicleUnit:KILOPASCAL + */ + CRITICALLY_LOW_TIRE_PRESSURE = ( + 0x030A + | VehiclePropertyGroup:SYSTEM + | VehiclePropertyType:FLOAT + | VehicleArea:WHEEL), + /** * Currently selected gear * @@ -881,6 +900,24 @@ enum VehicleProperty : int32_t { /** * HVAC, target temperature set. * + * The configArray is used to indicate the valid values for HVAC in Fahrenheit and Celsius. + * Android might use it in the HVAC app UI. + * The configArray is set as follows: + * configArray[0] = [the lower bound of the supported temperature in Celsius] * 10. + * configArray[1] = [the upper bound of the supported temperature in Celsius] * 10. + * configArray[2] = [the increment in Celsius] * 10. + * configArray[3] = [the lower bound of the supported temperature in Fahrenheit] * 10. + * configArray[4] = [the upper bound of the supported temperature in Fahrenheit] * 10. + * configArray[5] = [the increment in Fahrenheit] * 10. + * For example, if the vehicle supports temperature values as: + * [16.0, 16.5, 17.0 ,..., 28.0] in Celsius + * [60.5, 61.5, 62.5 ,..., 85.5] in Fahrenheit. + * The configArray should be configArray = {160, 280, 5, 605, 825, 10}. + * + * If the vehicle supports HVAC_TEMPERATURE_VALUE_SUGGESTION, the application can use + * that property to get the suggested value before setting HVAC_TEMPERATURE_SET. Otherwise, + * the application may choose the value in HVAC_TEMPERATURE_SET configArray by itself. + * * @change_mode VehiclePropertyChangeMode:ON_CHANGE * @access VehiclePropertyAccess:READ_WRITE * @unit VehicleUnit:CELSIUS @@ -1229,6 +1266,50 @@ enum VehicleProperty : int32_t { | VehiclePropertyType:BOOLEAN | VehicleArea:WINDOW), + /** + * Suggested values for setting HVAC temperature. + * + * Implement the property to help applications understand the closest supported temperature + * value in Celsius or Fahrenheit. + * + * floatValues[0] = the requested value that an application wants to set a temperature to. + * floatValues[1] = the unit for floatValues[0]. It should be one of + * {VehicleUnit:CELSIUS, VehicleUnit:FAHRENHEIT}. + * floatValues[2] = the value OEMs suggested in CELSIUS. This value is not included + * in the request. + * floatValues[3] = the value OEMs suggested in FAHRENHEIT. This value is not included + * in the request. + * + * An application calls set(VehiclePropValue propValue) with the requested value and unit for + * the value. OEMs need to return the suggested values in floatValues[2] and floatValues[3] by + * onPropertyEvent() callbacks. + * + * For example, when a user uses the voice assistant to set HVAC temperature to 66.2 in + * Fahrenheit. + * First, an application will set this property with the value + * [66.2, (float)VehicleUnit:FAHRENHEIT,0,0]. + * If OEMs suggest to set 19.0 in Celsius or 66.5 in Fahrenheit for user's request, then VHAL + * must generate a callback with property value + * [66.2, (float)VehicleUnit:FAHRENHEIT, 19.0, 66.5]. After the voice assistant gets the + * callback, it will inform the user and set HVAC temperature to the suggested value. + * + * Another example, an application receives 21 Celsius as the current temperature value by + * querying HVC_TEMPERATURE_SET. But the application wants to know what value is displayed on + * the car's UI in Fahrenheit. + * For this, the application sets the property to [21, (float)VehicleUnit:CELSIUS, 0, 0]. If + * the suggested value by the OEM for 21 Celsius is 70 Fahrenheit, then VHAL must generate a + * callback with property value [21, (float)VehicleUnit:CELSIUS, 21.0, 70.0]. + * In this case, the application can know that the value is 70.0 Fahrenheit in the car’s UI. + * + * @change_mode VehiclePropertyChangeMode:ON_CHANGE + * @access VehiclePropertyAccess:READ_WRITE + */ + HVAC_TEMPERATURE_VALUE_SUGGESTION = ( + 0x0515 + | VehiclePropertyGroup:SYSTEM + | VehiclePropertyType:FLOAT_VEC + | VehicleArea:GLOBAL), + /** * Distance units for display * -- GitLab From 9fcf6b1f4924974d1dd65e4a125632c71cfddf51 Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Wed, 14 Apr 2021 13:43:06 -0700 Subject: [PATCH 607/790] Update IFace getFeatures/setFeature and feature names Bug: 185398301 Bug: 185384721 Test: build for aosp_cf_x86_phone-userdebug Test: atest VtsHalBiometricsFaceTargetTest Change-Id: I75d328485550ccbc4d136d6c6fbea92c21d7e421 --- .../hardware/biometrics/face/Feature.aidl | 4 ++-- .../hardware/biometrics/face/ISession.aidl | 4 ++-- .../biometrics/face/ISessionCallback.aidl | 4 ++-- .../hardware/biometrics/face/Feature.aidl | 13 ++++++------- .../hardware/biometrics/face/ISession.aidl | 18 +++++++----------- .../biometrics/face/ISessionCallback.aidl | 9 ++++----- biometrics/face/aidl/default/Session.cpp | 5 ++--- biometrics/face/aidl/default/Session.h | 6 +++--- .../vts/VtsHalBiometricsFaceTargetTest.cpp | 5 ++--- 9 files changed, 30 insertions(+), 38 deletions(-) diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Feature.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Feature.aidl index a8faf06a26..1875b97431 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Feature.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Feature.aidl @@ -34,7 +34,7 @@ package android.hardware.biometrics.face; @Backing(type="byte") @VintfStability enum Feature { - WAVE_ATTENTION_REQUIREMENT = 0, - WAVE_DIVERSE_POSES_REQUIREMENT = 1, + REQUIRE_ATTENTION = 0, + REQUIRE_DIVERSE_POSES = 1, DEBUG = 2, } 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 9033989563..1ee3cafc81 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 @@ -41,8 +41,8 @@ interface ISession { android.hardware.biometrics.common.ICancellationSignal detectInteraction(); void enumerateEnrollments(); void removeEnrollments(in int[] enrollmentIds); - void getFeatures(in int enrollmentId); - void setFeature(in android.hardware.keymaster.HardwareAuthToken hat, in int enrollmentId, in android.hardware.biometrics.face.Feature feature, boolean enabled); + void getFeatures(); + void setFeature(in android.hardware.keymaster.HardwareAuthToken hat, in android.hardware.biometrics.face.Feature feature, boolean enabled); void getAuthenticatorId(); void invalidateAuthenticatorId(); void resetLockout(in android.hardware.keymaster.HardwareAuthToken hat); diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl index 2bb053a31c..bbace29aa0 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl @@ -47,8 +47,8 @@ interface ISessionCallback { void onLockoutCleared(); void onInteractionDetected(); void onEnrollmentsEnumerated(in int[] enrollmentIds); - void onFeaturesRetrieved(in android.hardware.biometrics.face.Feature[] features, in int enrollmentId); - void onFeatureSet(in int enrollmentId, android.hardware.biometrics.face.Feature feature); + void onFeaturesRetrieved(in android.hardware.biometrics.face.Feature[] features); + void onFeatureSet(android.hardware.biometrics.face.Feature feature); void onEnrollmentsRemoved(in int[] enrollmentIds); void onAuthenticatorIdRetrieved(in long authenticatorId); void onAuthenticatorIdInvalidated(in long newAuthenticatorId); diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/Feature.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/Feature.aidl index b88050ab60..bff1a022b7 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/Feature.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/Feature.aidl @@ -20,20 +20,19 @@ package android.hardware.biometrics.face; @Backing(type="byte") enum Feature { /** - * Do not require the user to look at the device during enrollment and authentication. Note - * this is to accommodate people who have limited vision. + * Require the user to look at the device during enrollment and authentication. This feature + * can be disabled to accommodate people who have limited vision. */ - WAVE_ATTENTION_REQUIREMENT, + REQUIRE_ATTENTION, /** - * Do not require a diverse set of poses during enrollment. This is to accommodate people with - * limited mobility. + * Require a diverse set of poses during enrollment. This feature can be disabled to accommodate + * people with limited mobility. */ - WAVE_DIVERSE_POSES_REQUIREMENT, + REQUIRE_DIVERSE_POSES, /** * Enable debugging functionality. */ DEBUG, } - diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl index 97348737ee..12911e3ba7 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl @@ -249,38 +249,34 @@ interface ISession { /** * getFeatures: * - * Returns a list of currently enabled features for the provided enrollmentId. + * Returns a list of currently enabled features for this (sensorId, userId) pair. * - * If the enrollmentId is invalid, the HAL must invoke ISessionCallback#onError with + * If the user is not enrolled, the HAL must invoke ISessionCallback#onError with * Error::UNABLE_TO_PROCESS. * * The HAL must notify the framework about the result by calling * ISessionCallback#onFeaturesRetrieved. - * - * @param enrollmentId the ID of the enrollment for which the features are requested. */ - void getFeatures(in int enrollmentId); + void getFeatures(); /** * setFeature: * - * Enables or disables a feature for the given enrollmentId. Because certain features may + * Enables or disables a feature for this (sensorId, userId) pair. Because certain features may * decrease security, the user must enter their password before this method is invoked * (see @param hat). The HAL must verify the hat before changing any feature state. * - * If either the hat or enrollmentId is invalid, the HAL must invoke ISessionCallback#onError - * with Error::UNABLE_TO_PROCESS. + * If the hat is invalid or if the user is not enrolled, the HAL must invoke + * ISessionCallback#onError with Error::UNABLE_TO_PROCESS. * * After the feature is successfully set, the HAL must notify the framework by calling * ISessionCallback#onFeatureSet. * * @param hat HardwareAuthToken See above documentation. - * @param enrollmentId the ID of the enrollment for which the feature update is requested. * @param feature The feature to be enabled or disabled. * @param enabled Whether the provided features should be enabled or disabled. */ - void setFeature( - in HardwareAuthToken hat, in int enrollmentId, in Feature feature, boolean enabled); + void setFeature(in HardwareAuthToken hat, in Feature feature, boolean enabled); /** * getAuthenticatorId: diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl index a2601e7360..23570bd753 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl @@ -172,22 +172,21 @@ interface ISessionCallback { /** * This method must only be used to notify the framework during ISession#getFeatures. * - * Provides a list of features that are currently enabled for the given enrollmentId. + * Provides a list of features that are currently enabled for the session's (userId, sensorId) + * pair. * * @param features A list of currently enabled features. See the Feature enum. - * @param enrollmentId The enrollment for which the features were requested. */ - void onFeaturesRetrieved(in Feature[] features, in int enrollmentId); + void onFeaturesRetrieved(in Feature[] features); /** * This method must only be used to notify the framework during ISession#setFeature. * * Notifies the framework that ISession#setFeature has completed. * - * @param enrollmentId The enrollment for which a feature was set. * @param feature The feature that was set. */ - void onFeatureSet(in int enrollmentId, Feature feature); + void onFeatureSet(Feature feature); /** * This method must only be used to notify the framework during diff --git a/biometrics/face/aidl/default/Session.cpp b/biometrics/face/aidl/default/Session.cpp index b5eb717351..4438d35ba4 100644 --- a/biometrics/face/aidl/default/Session.cpp +++ b/biometrics/face/aidl/default/Session.cpp @@ -92,14 +92,13 @@ ndk::ScopedAStatus Session::removeEnrollments(const std::vector& /*enro return ndk::ScopedAStatus::ok(); } -ndk::ScopedAStatus Session::getFeatures(int32_t /*enrollmentId*/) { +ndk::ScopedAStatus Session::getFeatures() { LOG(INFO) << "getFeatures"; return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus Session::setFeature(const keymaster::HardwareAuthToken& /*hat*/, - int32_t /*enrollmentId*/, Feature /*feature*/, - bool /*enabled*/) { + Feature /*feature*/, bool /*enabled*/) { LOG(INFO) << "setFeature"; return ndk::ScopedAStatus::ok(); } diff --git a/biometrics/face/aidl/default/Session.h b/biometrics/face/aidl/default/Session.h index 73cdf08625..c89985e31e 100644 --- a/biometrics/face/aidl/default/Session.h +++ b/biometrics/face/aidl/default/Session.h @@ -50,10 +50,10 @@ class Session : public BnSession { ndk::ScopedAStatus removeEnrollments(const std::vector& enrollmentIds) override; - ndk::ScopedAStatus getFeatures(int32_t enrollmentId) override; + ndk::ScopedAStatus getFeatures() override; - ndk::ScopedAStatus setFeature(const keymaster::HardwareAuthToken& hat, int32_t enrollmentId, - Feature feature, bool enabled) override; + ndk::ScopedAStatus setFeature(const keymaster::HardwareAuthToken& hat, Feature feature, + bool enabled) override; ndk::ScopedAStatus getAuthenticatorId() override; diff --git a/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp b/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp index 60e0a2a41f..ada6f734ca 100644 --- a/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp +++ b/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp @@ -104,12 +104,11 @@ class SessionCallback : public BnSessionCallback { return ndk::ScopedAStatus::ok(); } - ndk::ScopedAStatus onFeaturesRetrieved(const std::vector& /*features*/, - int32_t /*enrollmentId*/) override { + ndk::ScopedAStatus onFeaturesRetrieved(const std::vector& /*features*/) override { return ndk::ScopedAStatus::ok(); } - ndk::ScopedAStatus onFeatureSet(int32_t /*enrollmentId*/, Feature /*feature*/) override { + ndk::ScopedAStatus onFeatureSet(Feature /*feature*/) override { return ndk::ScopedAStatus::ok(); } -- GitLab From fa6900abbdd20e4c89bab7435c73c3842c9f5e95 Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Thu, 15 Apr 2021 00:20:42 +0000 Subject: [PATCH 608/790] Fix IFingerprint VTS unable to link default HAL Bug: 184614916 Test: on device without AIDL HAL Test: atest VtsHalBiometricsFingerprintTargetTest Change-Id: Iff6bebbd2f7a6ce6172d4b9b23f63073165730bc --- biometrics/fingerprint/aidl/vts/Android.bp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/biometrics/fingerprint/aidl/vts/Android.bp b/biometrics/fingerprint/aidl/vts/Android.bp index 0d83e744f2..5539548856 100644 --- a/biometrics/fingerprint/aidl/vts/Android.bp +++ b/biometrics/fingerprint/aidl/vts/Android.bp @@ -14,9 +14,13 @@ cc_test { "use_libaidlvintf_gtest_helper_static", ], srcs: ["VtsHalBiometricsFingerprintTargetTest.cpp"], + static_libs: [ + "android.hardware.biometrics.common-V1-ndk_platform", + "android.hardware.biometrics.fingerprint-V1-ndk_platform", + "android.hardware.keymaster-V3-ndk_platform", + ], shared_libs: [ "libbinder_ndk", - "android.hardware.biometrics.fingerprint-V1-ndk_platform", ], test_suites: [ "general-tests", -- GitLab From c837d1291e87d8f5ebab6945c298dffc2f8e06fd Mon Sep 17 00:00:00 2001 From: Zoey Chen Date: Tue, 6 Apr 2021 23:23:55 +0800 Subject: [PATCH 609/790] [ANAPIC Review] Modify radio 1.6 based on ANAPIC comment - setupDataCall_1_6, remove "same as 1.5" comment - sendSMSExpectMore to sendSmsExpectMore - getAllowedNetworkTypesBitmap should use int32_t - csiCqiReport uses uint8_t - cellBandwidthDownlinkKhz and cellBandwidthUplinkKhz - AccessTechnologySpecificInfo, remove these struct NgranRegistrationInfo and GeranRegistrationInfo Bug: 183738486 Test: make Change-Id: I24106cba4db5c6e564459675426f5eea9670a6c2 --- radio/1.6/IRadio.hal | 9 ++- radio/1.6/IRadioResponse.hal | 2 +- radio/1.6/types.hal | 61 +++++++++---------- .../1.6/vts/functional/radio_hidl_hal_api.cpp | 8 +-- .../functional/radio_hidl_hal_utils_v1_6.h | 2 +- radio/1.6/vts/functional/radio_response.cpp | 2 +- 6 files changed, 40 insertions(+), 44 deletions(-) diff --git a/radio/1.6/IRadio.hal b/radio/1.6/IRadio.hal index a4e8811993..e2d35d059d 100644 --- a/radio/1.6/IRadio.hal +++ b/radio/1.6/IRadio.hal @@ -145,7 +145,6 @@ interface IRadio extends @1.5::IRadio { * * Response function is IRadioResponse.setupDataCallResponse_1_6() * - * Note this API is the same as the 1.5 */ oneway setupDataCall_1_6(int32_t serial, AccessNetwork accessNetwork, DataProfileInfo dataProfileInfo, bool roamingAllowed, @@ -177,7 +176,7 @@ interface IRadio extends @1.5::IRadio { * @param serial Serial number of request. * @param message GsmSmsMessage as defined in types.hal * - * Response function is IRadioResponse.sendSMSExpectMoreResponse_1_6() + * Response function is IRadioResponse.sendSmsExpectMoreResponse_1_6() * * Note this API is the same as the 1.0 * @@ -185,7 +184,7 @@ interface IRadio extends @1.5::IRadio { * fails. RadioError:SMS_SEND_FAIL_RETRY means retry (i.e. error cause is 332) * and RadioError:GENERIC_FAILURE means no retry (i.e. error cause is 500) */ - oneway sendSMSExpectMore_1_6(int32_t serial, GsmSmsMessage message); + oneway sendSmsExpectMore_1_6(int32_t serial, GsmSmsMessage message); /** * Send a CDMA SMS message @@ -267,7 +266,7 @@ interface IRadio extends @1.5::IRadio { * 2. Disable NR dual connectivity {NrDualConnectivityState:DISABLE} * 3. Disable NR dual connectivity and force secondary cell to be released * {NrDualConnectivityState:DISABLE_IMMEDIATE} - + * * Response callback is IRadioResponse.setNRDualConnectivityStateResponse() */ oneway setNrDualConnectivityState(int32_t serial, @@ -372,7 +371,7 @@ interface IRadio extends @1.5::IRadio { * * Response callback is IRadioResponse.getAllowedNetworkTypesBitmapResponse() */ - oneway getAllowedNetworkTypesBitmap(uint32_t serial); + oneway getAllowedNetworkTypesBitmap(int32_t serial); /** * Control data throttling at modem. diff --git a/radio/1.6/IRadioResponse.hal b/radio/1.6/IRadioResponse.hal index 33fe94fa4a..d8614f7d65 100644 --- a/radio/1.6/IRadioResponse.hal +++ b/radio/1.6/IRadioResponse.hal @@ -139,7 +139,7 @@ interface IRadioResponse extends @1.5::IRadioResponse { * RadioError:ACCESS_BARRED * RadioError:BLOCKED_DUE_TO_CALL */ - oneway sendSMSExpectMoreResponse_1_6(RadioResponseInfo info, SendSmsResult sms); + oneway sendSmsExpectMoreResponse_1_6(RadioResponseInfo info, SendSmsResult sms); /** * @param info Response info struct containing response type, serial no. and error diff --git a/radio/1.6/types.hal b/radio/1.6/types.hal index 3fd31cc7da..d843fd8676 100644 --- a/radio/1.6/types.hal +++ b/radio/1.6/types.hal @@ -55,9 +55,9 @@ import android.hidl.safe_union@1.0::Monostate; struct QosBandwidth { /** Maximum bit rate possible on the bearer */ - int32_t maxBitrateKbps; + uint32_t maxBitrateKbps; /** Minimum bit rate that is guaranteed to be provided by the network */ - int32_t guaranteedBitrateKbps; + uint32_t guaranteedBitrateKbps; }; /** LTE/EPS Quality of Service parameters as per 3gpp spec 24.301 sec 9.9.4.3. */ @@ -106,7 +106,7 @@ safe_union Qos { /** * Next header protocol numbers defined by IANA, RFC 5237 */ -enum QosProtocol : int32_t { +enum QosProtocol : int8_t { /** No protocol specified */ UNSPECIFIED = -1, /** Transmission Control Protocol */ @@ -119,14 +119,14 @@ enum QosProtocol : int32_t { AH = 51, }; -enum QosFilterDirection : int32_t { +enum QosFilterDirection : int8_t { DOWNLINK = 0, UPLINK = 1, BIDIRECTIONAL = 2, }; /** Allowed port numbers */ -enum QosPortRange : int32_t { +enum QosPortRange : uint16_t { MIN = 20, MAX = 65535 }; @@ -248,7 +248,7 @@ struct QosSession { }; /** The allowed failure modes on an IWLAN handover failure. */ -enum HandoverFailureMode : int32_t { +enum HandoverFailureMode : int8_t { /** * On data handover failure, fallback to the source data transport when the * fail cause is due to a hand off preference change. @@ -379,7 +379,7 @@ struct SetupDataCallResult { /** * NR Dual connectivity state */ -enum NrDualConnectivityState: int32_t { +enum NrDualConnectivityState: int8_t { /** * Enable NR dual connectivity. Enabled state does not mean dual connectivity * is active. It means device is allowed to connect to both primary and secondary. @@ -443,7 +443,7 @@ struct LinkCapacityEstimate { uint32_t secondaryUplinkCapacityKbps; }; -enum DataThrottlingAction : int32_t { +enum DataThrottlingAction : int8_t { /* Clear all existing data throttling. */ NO_DATA_THROTTLING = 0, @@ -581,9 +581,9 @@ struct NrSignalStrength { * * Reference: 3GPP TS 138.214 section 5.2.2.1. * - * Range [0, 15], INT_MAX means invalid/unreported. + * Range [0, 15], 0xFF means invalid/unreported. */ - vec csiCqiReport; + vec csiCqiReport; }; /** @@ -740,22 +740,19 @@ struct RegStateResult { EutranRegistrationInfo eutranInfo; - struct NgranRegistrationInfo { - /** - * Network capabilities for voice over PS services. This info is valid only on NR - * network and must be present when the device is camped on NR. VopsInfo must be - * empty when the device is not camped on NR. - */ - NrVopsInfo nrVopsInfo; - } ngranInfo; - - struct GeranRegistrationInfo { - /** - * True if the dual transfer mode is supported. - * Refer to 3GPP TS 44.108 section 3.4.25.3 - */ - bool dtmSupported; - } geranInfo; + /** + * Network capabilities for voice over PS services. This info is valid only on NR + * network and must be present when the device is camped on NR. VopsInfo must be + * empty when the device is not camped on NR. + */ + NrVopsInfo ngranNrVopsInfo; + + /** + * True if the dual transfer mode is supported. + * Refer to 3GPP TS 44.108 section 3.4.25.3 + */ + bool geranDtmSupported; + } accessTechnologySpecificInfo; }; @@ -874,10 +871,10 @@ struct PhysicalChannelConfig { int32_t uplinkChannelNumber; /** Downlink cell bandwidth, in kHz */ - int32_t cellBandwidthDownlink; + int32_t cellBandwidthDownlinkKhz; /** Uplink cell bandwidth, in kHz */ - int32_t cellBandwidthUplink; + int32_t cellBandwidthUplinkKhz; /** * A list of data calls mapped to this physical channel. The context id must match the cid of @@ -1059,7 +1056,7 @@ safe_union OptionalSscMode { SscMode value; }; -enum SliceStatus : int32_t { +enum SliceStatus : int8_t { UNKNOWN, CONFIGURED, // Configured but not allowed or rejected yet ALLOWED, // Allowed to be used @@ -1072,7 +1069,7 @@ enum SliceStatus : int32_t { * Enum representing session and service continuity mode as defined in * 3GPP TS 23.501. */ -enum SscMode : int32_t { +enum SscMode : int8_t { MODE_1 = 1, MODE_2 = 2, MODE_3 = 3, @@ -1081,7 +1078,7 @@ enum SscMode : int32_t { /** * Public key type from carrier certificate. */ -enum PublicKeyType : int32_t { +enum PublicKeyType : int8_t { EPDG = 1, // Key type to be used for ePDG WLAN = 2, // Key type to be used for WLAN }; @@ -1190,7 +1187,7 @@ struct PhonebookCapacity { * chunk of phonebook data, means this is a last indication with the left * data. */ -enum PbReceivedStatus : int32_t { +enum PbReceivedStatus : int8_t { PB_RECEIVED_OK = 1, PB_RECEIVED_ERROR = 2, PB_RECEIVED_ABORT = 3, diff --git a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp index 6cf4567782..be2be76913 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp +++ b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp @@ -213,10 +213,10 @@ TEST_P(RadioHidlTest_v1_6, sendSms_1_6) { } /* - * Test IRadio_1_6.sendSMSExpectMore() for the response returned. + * Test IRadio_1_6.sendSmsExpectMore() for the response returned. */ -TEST_P(RadioHidlTest_v1_6, sendSMSExpectMore_1_6) { - LOG(DEBUG) << "sendSMSExpectMore"; +TEST_P(RadioHidlTest_v1_6, sendSmsExpectMore_1_6) { + LOG(DEBUG) << "sendSmsExpectMore"; serial = GetRandomSerialNumber(); GsmSmsMessage msg; msg.smscPdu = ""; @@ -236,7 +236,7 @@ TEST_P(RadioHidlTest_v1_6, sendSMSExpectMore_1_6) { ::android::hardware::radio::V1_6::RadioError::SIM_ABSENT}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "sendSMSExpectMore finished"; + LOG(DEBUG) << "sendSmsExpectMore finished"; } /* diff --git a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h index 4fc17e54d0..0689e9b52b 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h +++ b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h @@ -762,7 +762,7 @@ class RadioResponse_v1_6 : public ::android::hardware::radio::V1_6::IRadioRespon const ::android::hardware::radio::V1_6::RadioResponseInfo& info, const SendSmsResult& sms); - Return sendSMSExpectMoreResponse_1_6( + Return sendSmsExpectMoreResponse_1_6( const ::android::hardware::radio::V1_6::RadioResponseInfo& info, const SendSmsResult& sms); diff --git a/radio/1.6/vts/functional/radio_response.cpp b/radio/1.6/vts/functional/radio_response.cpp index 2b6d1bb57e..942964bd8c 100644 --- a/radio/1.6/vts/functional/radio_response.cpp +++ b/radio/1.6/vts/functional/radio_response.cpp @@ -1090,7 +1090,7 @@ Return RadioResponse_v1_6::sendSmsResponse_1_6( return Void(); } -Return RadioResponse_v1_6::sendSMSExpectMoreResponse_1_6( +Return RadioResponse_v1_6::sendSmsExpectMoreResponse_1_6( const ::android::hardware::radio::V1_6::RadioResponseInfo& info, const SendSmsResult& sms) { rspInfo = info; -- GitLab From 51daee615fd434d768986b8dc8e5207165c2a603 Mon Sep 17 00:00:00 2001 From: Alec Mouri Date: Thu, 15 Apr 2021 16:27:01 +0000 Subject: [PATCH 610/790] Revert "Update Readback VTS to align with RenderEngine interface..." Revert "Update WaylandRenderSurface to accomodate interface change" Revert "Add ExternalTexture class into RenderEngine interface" Revert submission 14086921-renderengine-external-tex Reason for revert: Potential culprit for b/185361988 Reverted Changes: I7796764e2:Update WaylandRenderSurface to accomodate interfac... I13904eec4:Update Readback VTS to align with RenderEngine int... I222c71e6e:Add ExternalTexture class into RenderEngine interf... Change-Id: I7d58118c1c2284a04eb52e992e901d82faaf5bb0 --- .../composer/2.2/utils/vts/ReadbackVts.cpp | 15 +++---- .../2.2/utils/vts/RenderEngineVts.cpp | 4 +- .../include/composer-vts/2.2/ReadbackVts.h | 6 +-- .../composer-vts/2.2/RenderEngineVts.h | 6 --- ...VtsHalGraphicsComposerV2_2ReadbackTest.cpp | 44 +++++++++---------- 5 files changed, 29 insertions(+), 46 deletions(-) diff --git a/graphics/composer/2.2/utils/vts/ReadbackVts.cpp b/graphics/composer/2.2/utils/vts/ReadbackVts.cpp index 19f5e8c614..b179f35109 100644 --- a/graphics/composer/2.2/utils/vts/ReadbackVts.cpp +++ b/graphics/composer/2.2/utils/vts/ReadbackVts.cpp @@ -15,8 +15,6 @@ */ #include -#include -#include "renderengine/ExternalTexture.h" namespace android { namespace hardware { @@ -259,11 +257,10 @@ LayerSettings TestColorLayer::toRenderEngineLayerSettings() { } TestBufferLayer::TestBufferLayer(const std::shared_ptr& client, - const std::shared_ptr& gralloc, - TestRenderEngine& renderEngine, Display display, int32_t width, - int32_t height, PixelFormat format, + const std::shared_ptr& gralloc, Display display, + int32_t width, int32_t height, PixelFormat format, IComposerClient::Composition composition) - : TestLayer{client, display}, mRenderEngine(renderEngine) { + : TestLayer{client, display} { mGralloc = gralloc; mComposition = composition; mWidth = width; @@ -296,11 +293,9 @@ void TestBufferLayer::write(const std::shared_ptr& writer) { LayerSettings TestBufferLayer::toRenderEngineLayerSettings() { LayerSettings layerSettings = TestLayer::toRenderEngineLayerSettings(); - layerSettings.source.buffer.buffer = std::make_shared( + layerSettings.source.buffer.buffer = new GraphicBuffer(mBufferHandle, GraphicBuffer::CLONE_HANDLE, mWidth, mHeight, - static_cast(mFormat), 1, mUsage, mStride), - mRenderEngine.getInternalRenderEngine(), - renderengine::ExternalTexture::Usage::READABLE); + static_cast(mFormat), 1, mUsage, mStride); 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 f78dda2689..3becacea91 100644 --- a/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp +++ b/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp @@ -69,9 +69,7 @@ void TestRenderEngine::drawLayers() { [](renderengine::LayerSettings& settings) -> renderengine::LayerSettings* { return &settings; }); - auto texture = std::make_shared( - mGraphicBuffer, *mRenderEngine, renderengine::ExternalTexture::Usage::WRITEABLE); - mRenderEngine->drawLayers(mDisplaySettings, compositionLayerPointers, texture, true, + mRenderEngine->drawLayers(mDisplaySettings, compositionLayerPointers, mGraphicBuffer, true, std::move(bufferFence), &readyFence); int fd = readyFence.release(); if (fd != -1) { diff --git a/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ReadbackVts.h b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ReadbackVts.h index b24e3b63bd..d5eedf122c 100644 --- a/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ReadbackVts.h +++ b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ReadbackVts.h @@ -50,8 +50,6 @@ static const IComposerClient::Color TRANSLUCENT_RED = {0xff, 0, 0, 0x33}; static const IComposerClient::Color GREEN = {0, 0xff, 0, 0xff}; static const IComposerClient::Color BLUE = {0, 0, 0xff, 0xff}; -class TestRenderEngine; - class TestLayer { public: TestLayer(const std::shared_ptr& client, Display display) @@ -112,8 +110,7 @@ class TestBufferLayer : public TestLayer { public: TestBufferLayer( const std::shared_ptr& client, const std::shared_ptr& gralloc, - TestRenderEngine& renderEngine, Display display, int32_t width, int32_t height, - PixelFormat format, + Display display, int32_t width, int32_t height, PixelFormat format, IComposerClient::Composition composition = IComposerClient::Composition::DEVICE); ~TestBufferLayer(); @@ -141,7 +138,6 @@ class TestBufferLayer : public TestLayer { protected: IComposerClient::Composition mComposition; std::shared_ptr mGralloc; - TestRenderEngine& mRenderEngine; int32_t mFillFence; const native_handle_t* mBufferHandle = nullptr; }; diff --git a/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/RenderEngineVts.h b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/RenderEngineVts.h index 26027d33a2..f2d5f1933f 100644 --- a/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/RenderEngineVts.h +++ b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/RenderEngineVts.h @@ -14,12 +14,9 @@ * limitations under the License. */ -#pragma once - #include #include #include -#include #include #include #include @@ -54,15 +51,12 @@ class TestRenderEngine { void drawLayers(); void checkColorBuffer(std::vector& expectedColors); - renderengine::RenderEngine& getInternalRenderEngine() { return *mRenderEngine; } - private: common::V1_1::PixelFormat mFormat; std::vector mCompositionLayers; std::unique_ptr mRenderEngine; std::vector mRenderLayers; sp mGraphicBuffer; - DisplaySettings mDisplaySettings; }; diff --git a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp index 8d52173e59..1463c3be6c 100644 --- a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp +++ b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp @@ -288,9 +288,9 @@ TEST_P(GraphicsCompositionTest, SetLayerBuffer) { {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight}, BLUE); - auto layer = std::make_shared( - mComposerClient, mGralloc, *mTestRenderEngine, mPrimaryDisplay, mDisplayWidth, - mDisplayHeight, PixelFormat::RGBA_8888); + auto layer = std::make_shared(mComposerClient, mGralloc, mPrimaryDisplay, + mDisplayWidth, mDisplayHeight, + PixelFormat::RGBA_8888); layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight}); layer->setZOrder(10); layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter); @@ -422,9 +422,9 @@ TEST_P(GraphicsCompositionTest, ClientComposition) { {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight}, BLUE); - auto layer = std::make_shared( - mComposerClient, mGralloc, *mTestRenderEngine, mPrimaryDisplay, mDisplayWidth, - mDisplayHeight, PixelFormat::RGBA_FP16); + auto layer = std::make_shared(mComposerClient, mGralloc, mPrimaryDisplay, + mDisplayWidth, mDisplayHeight, + PixelFormat::RGBA_FP16); layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight}); layer->setZOrder(10); layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter); @@ -538,8 +538,8 @@ TEST_P(GraphicsCompositionTest, DeviceAndClientComposition) { ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer()); auto deviceLayer = std::make_shared( - mComposerClient, mGralloc, *mTestRenderEngine, mPrimaryDisplay, mDisplayWidth, - mDisplayHeight / 2, PixelFormat::RGBA_8888); + mComposerClient, mGralloc, mPrimaryDisplay, mDisplayWidth, mDisplayHeight / 2, + PixelFormat::RGBA_8888); std::vector deviceColors(deviceLayer->mWidth * deviceLayer->mHeight); ReadbackHelper::fillColorsArea(deviceColors, deviceLayer->mWidth, @@ -575,8 +575,8 @@ TEST_P(GraphicsCompositionTest, DeviceAndClientComposition) { } auto clientLayer = std::make_shared( - mComposerClient, mGralloc, *mTestRenderEngine, mPrimaryDisplay, clientWidth, - clientHeight, PixelFormat::RGBA_FP16, IComposerClient::Composition::DEVICE); + mComposerClient, mGralloc, mPrimaryDisplay, clientWidth, clientHeight, + PixelFormat::RGBA_FP16, IComposerClient::Composition::DEVICE); IComposerClient::Rect clientFrame = {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight}; clientLayer->setDisplayFrame(clientFrame); clientLayer->setZOrder(0); @@ -657,9 +657,9 @@ TEST_P(GraphicsCompositionTest, SetLayerDamage) { std::vector expectedColors(mDisplayWidth * mDisplayHeight); ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, redRect, RED); - auto layer = std::make_shared( - mComposerClient, mGralloc, *mTestRenderEngine, mPrimaryDisplay, mDisplayWidth, - mDisplayHeight, PixelFormat::RGBA_8888); + auto layer = std::make_shared(mComposerClient, mGralloc, mPrimaryDisplay, + mDisplayWidth, mDisplayHeight, + PixelFormat::RGBA_8888); layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight}); layer->setZOrder(10); layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter); @@ -805,9 +805,9 @@ TEST_P(GraphicsCompositionTest, SetLayerSourceCrop) { {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight}, BLUE); - auto layer = std::make_shared( - mComposerClient, mGralloc, *mTestRenderEngine, mPrimaryDisplay, mDisplayWidth, - mDisplayHeight, PixelFormat::RGBA_8888); + auto layer = std::make_shared(mComposerClient, mGralloc, mPrimaryDisplay, + mDisplayWidth, mDisplayHeight, + PixelFormat::RGBA_8888); layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight}); layer->setZOrder(10); layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter); @@ -957,9 +957,9 @@ class GraphicsBlendModeCompositionTest backgroundLayer->setZOrder(0); backgroundLayer->setColor(mBackgroundColor); - auto layer = std::make_shared( - mComposerClient, mGralloc, *mTestRenderEngine, mPrimaryDisplay, mDisplayWidth, - mDisplayHeight, PixelFormat::RGBA_8888); + auto layer = std::make_shared(mComposerClient, mGralloc, mPrimaryDisplay, + mDisplayWidth, mDisplayHeight, + PixelFormat::RGBA_8888); layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight}); layer->setZOrder(10); layer->setDataspace(Dataspace::UNKNOWN, mWriter); @@ -1195,9 +1195,9 @@ class GraphicsTransformCompositionTest : public GraphicsCompositionTest { IComposerClient::Rect blueRect = {mSideLength / 2, mSideLength / 2, mSideLength, mSideLength}; - mLayer = std::make_shared(mComposerClient, mGralloc, *mTestRenderEngine, - mPrimaryDisplay, mSideLength, mSideLength, - PixelFormat::RGBA_8888); + mLayer = + std::make_shared(mComposerClient, mGralloc, mPrimaryDisplay, + mSideLength, mSideLength, PixelFormat::RGBA_8888); mLayer->setDisplayFrame({0, 0, mSideLength, mSideLength}); mLayer->setZOrder(10); -- GitLab From 9f89b053799b5d99223253d27fd590252fbe8c6c Mon Sep 17 00:00:00 2001 From: Shuzhen Wang Date: Thu, 4 Mar 2021 11:59:23 -0800 Subject: [PATCH 611/790] Camera: Add a new tag for multi-resolution stream support - The new tag is used to remove the ambiguity when a physical camera is backing more than one logical cameras. - Add missing VTS tests for multi-resolution stream. Test: Camera CTS, VTS Bug: 156254356 Bug: 184663916 Change-Id: I8adc152bbf57e8ec5e058834c1c6f461aca1bcbd --- camera/metadata/3.6/types.hal | 14 + .../VtsHalCameraProviderV2_4TargetTest.cpp | 634 ++++++++++++++---- 2 files changed, 521 insertions(+), 127 deletions(-) diff --git a/camera/metadata/3.6/types.hal b/camera/metadata/3.6/types.hal index 709cfb3ec5..97cac7c3e8 100644 --- a/camera/metadata/3.6/types.hal +++ b/camera/metadata/3.6/types.hal @@ -131,6 +131,12 @@ enum CameraMetadataTag : @3.5::CameraMetadataTag { */ ANDROID_SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP_MAXIMUM_RESOLUTION, + /** android.scaler.multiResolutionStreamSupported [static, enum, ndk_public] + * + *

    Whether the camera device supports multi-resolution input or output streams

    + */ + ANDROID_SCALER_MULTI_RESOLUTION_STREAM_SUPPORTED, + ANDROID_SCALER_END_3_6, /** android.sensor.opaqueRawSizeMaximumResolution [static, int32[], system] @@ -334,6 +340,14 @@ enum CameraMetadataEnumAndroidScalerAvailableStreamConfigurationsMaximumResoluti ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT, }; +/** android.scaler.multiResolutionStreamSupported enumeration values + * @see ANDROID_SCALER_MULTI_RESOLUTION_STREAM_SUPPORTED + */ +enum CameraMetadataEnumAndroidScalerMultiResolutionStreamSupported : uint32_t { + ANDROID_SCALER_MULTI_RESOLUTION_STREAM_SUPPORTED_FALSE, + ANDROID_SCALER_MULTI_RESOLUTION_STREAM_SUPPORTED_TRUE, +}; + /** android.sensor.pixelMode enumeration values * @see ANDROID_SENSOR_PIXEL_MODE */ diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp index ed3b1faa53..7bb300ed2e 100644 --- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp +++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp @@ -578,7 +578,7 @@ public: uint32_t id; ASSERT_TRUE(parseProviderName(service_name, &mProviderType, &id)); - castProvider(mProvider, &mProvider2_5, &mProvider2_6); + castProvider(mProvider, &mProvider2_5, &mProvider2_6, &mProvider2_7); notifyDeviceState(provider::V2_5::DeviceState::NORMAL); } virtual void TearDown() override {} @@ -759,22 +759,24 @@ public: ::android::sp *device = nullptr/*out*/); void castProvider(const sp& provider, sp* provider2_5 /*out*/, - sp* provider2_6 /*out*/); + sp* provider2_6 /*out*/, + sp* provider2_7 /*out*/); void castSession(const sp &session, int32_t deviceVersion, sp *session3_3 /*out*/, sp *session3_4 /*out*/, sp *session3_5 /*out*/, sp *session3_6 /*out*/, sp *session3_7 /*out*/); - void castDevice(const sp &device, int32_t deviceVersion, - sp *device3_5/*out*/); - void castDevice3_7(const sp& device, int32_t deviceVersion, - sp* device3_7 /*out*/); - void createStreamConfiguration(const ::android::hardware::hidl_vec& streams3_2, + void castDevice(const sp& device, int32_t deviceVersion, + sp* device3_5 /*out*/, + sp* device3_7 /*out*/); + void createStreamConfiguration( + const ::android::hardware::hidl_vec& streams3_2, StreamConfigurationMode configMode, - ::android::hardware::camera::device::V3_2::StreamConfiguration *config3_2, - ::android::hardware::camera::device::V3_4::StreamConfiguration *config3_4, - ::android::hardware::camera::device::V3_5::StreamConfiguration *config3_5, + ::android::hardware::camera::device::V3_2::StreamConfiguration* config3_2, + ::android::hardware::camera::device::V3_4::StreamConfiguration* config3_4, + ::android::hardware::camera::device::V3_5::StreamConfiguration* config3_5, + ::android::hardware::camera::device::V3_7::StreamConfiguration* config3_7, uint32_t jpegBufferSize = 0); void configureOfflineStillStream(const std::string &name, int32_t deviceVersion, @@ -834,7 +836,8 @@ public: uint32_t* partialResultCount /*out*/, bool* useHalBufManager /*out*/, sp* cb /*out*/, uint32_t streamConfigCounter = 0); - void verifyLogicalCameraMetadata(const std::string& cameraName, + void verifyLogicalOrUltraHighResCameraMetadata( + const std::string& cameraName, const ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice>& device, const CameraMetadata& chars, int deviceVersion, const hidl_vec& deviceNames); @@ -845,8 +848,11 @@ public: void verifyMonochromeCharacteristics(const CameraMetadata& chars, int deviceVersion); void verifyMonochromeCameraResult( const ::android::hardware::camera::common::V1_0::helper::CameraMetadata& metadata); - void verifyStreamCombination(sp cameraDevice3_5, - const ::android::hardware::camera::device::V3_4::StreamConfiguration &config3_4, + void verifyStreamCombination( + sp cameraDevice3_7, + const ::android::hardware::camera::device::V3_7::StreamConfiguration& config3_7, + sp cameraDevice3_5, + const ::android::hardware::camera::device::V3_4::StreamConfiguration& config3_4, bool expectedStatus, bool expectStreamCombQuery); void verifyLogicalCameraResult(const camera_metadata_t* staticMetadata, const ::android::hardware::camera::common::V1_0::helper::CameraMetadata& resultMetadata); @@ -915,6 +921,11 @@ public: static Status isMonochromeCamera(const camera_metadata_t *staticMeta); static Status getSystemCameraKind(const camera_metadata_t* staticMeta, SystemCameraKind* systemCameraKind); + static void getMultiResolutionStreamConfigurations( + camera_metadata_ro_entry* multiResStreamConfigs, + camera_metadata_ro_entry* streamConfigs, + camera_metadata_ro_entry* maxResolutionStreamConfigs, + const camera_metadata_t* staticMetadata); static V3_2::DataspaceFlags getDataspace(PixelFormat format); @@ -1047,6 +1058,7 @@ protected: sp mProvider; sp<::android::hardware::camera::provider::V2_5::ICameraProvider> mProvider2_5; sp<::android::hardware::camera::provider::V2_6::ICameraProvider> mProvider2_6; + sp<::android::hardware::camera::provider::V2_7::ICameraProvider> mProvider2_7; // Camera provider type. std::string mProviderType; @@ -2805,8 +2817,8 @@ TEST_P(CameraHidlTest, getCameraCharacteristics) { verifyCameraCharacteristics(status, chars); verifyMonochromeCharacteristics(chars, deviceVersion); verifyRecommendedConfigs(chars); - verifyLogicalCameraMetadata(name, device3_x, chars, deviceVersion, - cameraDeviceNames); + verifyLogicalOrUltraHighResCameraMetadata(name, device3_x, chars, deviceVersion, + cameraDeviceNames); }); ASSERT_TRUE(ret.isOk()); @@ -3264,11 +3276,12 @@ TEST_P(CameraHidlTest, configureStreamsAvailableOutputs) { sp session3_7; sp cameraDevice; sp cameraDevice3_5; + sp cameraDevice3_7; 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); + castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7); outputStreams.clear(); ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputStreams)); @@ -3292,15 +3305,29 @@ TEST_P(CameraHidlTest, configureStreamsAvailableOutputs) { dataspaceFlag, StreamRotation::ROTATION_0}; ::android::hardware::hidl_vec streams3_2 = {stream3_2}; + ::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; ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2; - createStreamConfiguration(streams3_2, StreamConfigurationMode::NORMAL_MODE, - &config3_2, &config3_4, &config3_5, jpegBufferSize); + createStreamConfiguration(streams3_2, StreamConfigurationMode::NORMAL_MODE, &config3_2, + &config3_4, &config3_5, &config3_7, jpegBufferSize); + if (session3_5 != nullptr) { bool expectStreamCombQuery = (isLogicalMultiCamera(staticMeta) == Status::OK); - verifyStreamCombination(cameraDevice3_5, config3_4, - /*expectedStatus*/ true, expectStreamCombQuery); + verifyStreamCombination(cameraDevice3_7, config3_7, cameraDevice3_5, config3_4, + /*expectedStatus*/ true, expectStreamCombQuery); + } + + if (session3_7 != nullptr) { + config3_7.streamConfigCounter = streamConfigCounter++; + ret = session3_7->configureStreams_3_7( + config3_7, + [streamId](Status s, device::V3_6::HalStreamConfiguration halConfig) { + ASSERT_EQ(Status::OK, s); + ASSERT_EQ(1u, halConfig.streams.size()); + ASSERT_EQ(halConfig.streams[0].v3_4.v3_3.v3_2.id, streamId); + }); + } else if (session3_5 != nullptr) { config3_5.streamConfigCounter = streamConfigCounter++; ret = session3_5->configureStreams_3_5(config3_5, [streamId](Status s, device::V3_4::HalStreamConfiguration halConfig) { @@ -3352,6 +3379,8 @@ TEST_P(CameraHidlTest, configureConcurrentStreamsAvailableOutputs) { sp session3_7; sp cameraDevice; sp cameraDevice3_5; + sp cameraDevice3_7; + ::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; ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2; @@ -3388,7 +3417,7 @@ TEST_P(CameraHidlTest, configureConcurrentStreamsAvailableOutputs) { &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); + castDevice(cti.cameraDevice, deviceVersion, &cti.cameraDevice3_5, &cti.cameraDevice3_7); outputStreams.clear(); ASSERT_EQ(Status::OK, getMandatoryConcurrentStreams(cti.staticMeta, &outputStreams)); @@ -3420,7 +3449,7 @@ TEST_P(CameraHidlTest, configureConcurrentStreamsAvailableOutputs) { // Add the created stream configs to cameraIdsAndStreamCombinations createStreamConfiguration(streams3_2, StreamConfigurationMode::NORMAL_MODE, &cti.config3_2, &cti.config3_4, &cti.config3_5, - jpegBufferSize); + &cti.config3_7, jpegBufferSize); cti.config3_5.streamConfigCounter = outputStreams.size(); CameraIdAndStreamCombination cameraIdAndStreamCombination; @@ -3443,8 +3472,19 @@ TEST_P(CameraHidlTest, configureConcurrentStreamsAvailableOutputs) { for (const auto& cti : cameraTestInfos) { if (cti.session3_5 != nullptr) { bool expectStreamCombQuery = (isLogicalMultiCamera(cti.staticMeta) == Status::OK); - verifyStreamCombination(cti.cameraDevice3_5, cti.config3_4, + verifyStreamCombination(cti.cameraDevice3_7, cti.config3_7, cti.cameraDevice3_5, + cti.config3_4, /*expectedStatus*/ true, expectStreamCombQuery); + } + + if (cti.session3_7 != nullptr) { + ret = cti.session3_7->configureStreams_3_7( + cti.config3_7, + [&cti](Status s, device::V3_6::HalStreamConfiguration halConfig) { + ASSERT_EQ(Status::OK, s); + ASSERT_EQ(cti.config3_7.streams.size(), halConfig.streams.size()); + }); + } else if (cti.session3_5 != nullptr) { ret = cti.session3_5->configureStreams_3_5( cti.config3_5, [&cti](Status s, device::V3_4::HalStreamConfiguration halConfig) { @@ -3508,11 +3548,12 @@ TEST_P(CameraHidlTest, configureStreamsInvalidOutputs) { sp session3_7; sp cameraDevice; sp cameraDevice3_5; + sp cameraDevice3_7; 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); + castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7); outputStreams.clear(); ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputStreams)); @@ -3533,14 +3574,26 @@ TEST_P(CameraHidlTest, configureStreamsInvalidOutputs) { StreamRotation::ROTATION_0}; uint32_t streamConfigCounter = 0; ::android::hardware::hidl_vec streams = {stream3_2}; + ::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; ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2; - createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, - &config3_2, &config3_4, &config3_5, jpegBufferSize); + createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, &config3_2, + &config3_4, &config3_5, &config3_7, jpegBufferSize); + if (session3_5 != nullptr) { - verifyStreamCombination(cameraDevice3_5, config3_4, /*expectedStatus*/ false, - /*expectStreamCombQuery*/false); + verifyStreamCombination(cameraDevice3_7, config3_7, cameraDevice3_5, config3_4, + /*expectedStatus*/ false, /*expectStreamCombQuery*/ false); + } + + if (session3_7 != nullptr) { + config3_7.streamConfigCounter = streamConfigCounter++; + ret = session3_7->configureStreams_3_7( + config3_7, [](Status s, device::V3_6::HalStreamConfiguration) { + ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) || + (Status::INTERNAL_ERROR == s)); + }); + } else if (session3_5 != nullptr) { config3_5.streamConfigCounter = streamConfigCounter++; ret = session3_5->configureStreams_3_5(config3_5, [](Status s, device::V3_4::HalStreamConfiguration) { @@ -3553,7 +3606,7 @@ TEST_P(CameraHidlTest, configureStreamsInvalidOutputs) { ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) || (Status::INTERNAL_ERROR == s)); }); - } else if(session3_3 != nullptr) { + } else if (session3_3 != nullptr) { ret = session3_3->configureStreams_3_3(config3_2, [](Status s, device::V3_3::HalStreamConfiguration) { ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) || @@ -3577,8 +3630,8 @@ TEST_P(CameraHidlTest, configureStreamsInvalidOutputs) { 0, StreamRotation::ROTATION_0}; streams[0] = stream3_2; - createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, - &config3_2, &config3_4, &config3_5, jpegBufferSize); + createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, &config3_2, + &config3_4, &config3_5, &config3_7, jpegBufferSize); if (session3_5 != nullptr) { config3_5.streamConfigCounter = streamConfigCounter++; ret = session3_5->configureStreams_3_5(config3_5, [](Status s, @@ -3613,8 +3666,8 @@ TEST_P(CameraHidlTest, configureStreamsInvalidOutputs) { 0, StreamRotation::ROTATION_0}; streams[0] = stream3_2; - createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, - &config3_2, &config3_4, &config3_5, jpegBufferSize); + createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, &config3_2, + &config3_4, &config3_5, &config3_7, jpegBufferSize); if (session3_5 != nullptr) { config3_5.streamConfigCounter = streamConfigCounter++; ret = session3_5->configureStreams_3_5(config3_5, @@ -3648,8 +3701,8 @@ TEST_P(CameraHidlTest, configureStreamsInvalidOutputs) { 0, static_cast(UINT32_MAX)}; streams[0] = stream3_2; - createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, - &config3_2, &config3_4, &config3_5, jpegBufferSize); + createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, &config3_2, + &config3_4, &config3_5, &config3_7, jpegBufferSize); if (session3_5 != nullptr) { config3_5.streamConfigCounter = streamConfigCounter++; ret = session3_5->configureStreams_3_5(config3_5, @@ -3708,11 +3761,12 @@ TEST_P(CameraHidlTest, configureStreamsZSLInputOutputs) { sp session3_7; sp cameraDevice; sp cameraDevice3_5; + sp cameraDevice3_7; 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); + castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7); Status rc = isZSLModeAvailable(staticMeta); if (Status::METHOD_NOT_SUPPORTED == rc) { @@ -3797,14 +3851,27 @@ TEST_P(CameraHidlTest, configureStreamsZSLInputOutputs) { ::android::hardware::hidl_vec streams = {inputStream, zslStream, outputStream}; + ::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; ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2; - createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, - &config3_2, &config3_4, &config3_5, jpegBufferSize); + createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, &config3_2, + &config3_4, &config3_5, &config3_7, jpegBufferSize); if (session3_5 != nullptr) { - verifyStreamCombination(cameraDevice3_5, config3_4, - /*expectedStatus*/ true, /*expectStreamCombQuery*/ false); + verifyStreamCombination(cameraDevice3_7, config3_7, cameraDevice3_5, config3_4, + /*expectedStatus*/ true, + /*expectStreamCombQuery*/ false); + } + + if (session3_7 != nullptr) { + config3_7.streamConfigCounter = streamConfigCounter++; + ret = session3_7->configureStreams_3_7( + config3_7, + [](Status s, device::V3_6::HalStreamConfiguration halConfig) { + ASSERT_EQ(Status::OK, s); + ASSERT_EQ(3u, halConfig.streams.size()); + }); + } else if (session3_5 != nullptr) { config3_5.streamConfigCounter = streamConfigCounter++; ret = session3_5->configureStreams_3_5(config3_5, [](Status s, device::V3_4::HalStreamConfiguration halConfig) { @@ -3927,6 +3994,7 @@ TEST_P(CameraHidlTest, configureStreamsWithSessionParameters) { ::android::hardware::hidl_vec streams = {previewStream}; ::android::hardware::camera::device::V3_4::StreamConfiguration config; ::android::hardware::camera::device::V3_5::StreamConfiguration config3_5; + ::android::hardware::camera::device::V3_7::StreamConfiguration config3_7; config.streams = streams; config.operationMode = StreamConfigurationMode::NORMAL_MODE; modifiedSessionParams = sessionParams; @@ -3935,6 +4003,13 @@ TEST_P(CameraHidlTest, configureStreamsWithSessionParameters) { get_camera_metadata_size(sessionParamsBuffer)); config3_5.v3_4 = config; config3_5.streamConfigCounter = 0; + config3_7.streams = {{previewStream, -1, {ANDROID_SENSOR_PIXEL_MODE_DEFAULT}}}; + config3_7.operationMode = config.operationMode; + config3_7.sessionParams.setToExternal(reinterpret_cast(sessionParamsBuffer), + get_camera_metadata_size(sessionParamsBuffer)); + config3_7.streamConfigCounter = 0; + config3_7.multiResolutionInputImage = false; + if (session3_5 != nullptr) { bool newSessionParamsAvailable = false; for (const auto& it : availableSessionKeys) { @@ -3950,7 +4025,15 @@ TEST_P(CameraHidlTest, configureStreamsWithSessionParameters) { modifiedSessionParamsBuffer); modifiedSessionParams.acquire(modifiedSessionParamsBuffer); } + } + if (session3_7 != nullptr) { + ret = session3_7->configureStreams_3_7( + config3_7, [](Status s, device::V3_6::HalStreamConfiguration halConfig) { + ASSERT_EQ(Status::OK, s); + ASSERT_EQ(1u, halConfig.streams.size()); + }); + } else if (session3_5 != nullptr) { ret = session3_5->configureStreams_3_5(config3_5, [](Status s, device::V3_4::HalStreamConfiguration halConfig) { ASSERT_EQ(Status::OK, s); @@ -4003,11 +4086,12 @@ TEST_P(CameraHidlTest, configureStreamsPreviewStillOutputs) { sp session3_7; sp cameraDevice; sp cameraDevice3_5; + sp cameraDevice3_7; 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); + castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7); // Check if camera support depth only if (isDepthOnly(staticMeta)) { @@ -4054,14 +4138,27 @@ TEST_P(CameraHidlTest, configureStreamsPreviewStillOutputs) { StreamRotation::ROTATION_0}; ::android::hardware::hidl_vec streams = {previewStream, blobStream}; + ::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; ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2; - createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, - &config3_2, &config3_4, &config3_5, jpegBufferSize); + createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, &config3_2, + &config3_4, &config3_5, &config3_7, jpegBufferSize); if (session3_5 != nullptr) { - verifyStreamCombination(cameraDevice3_5, config3_4, - /*expectedStatus*/ true, /*expectStreamCombQuery*/ false); + verifyStreamCombination(cameraDevice3_7, config3_7, cameraDevice3_5, config3_4, + /*expectedStatus*/ true, + /*expectStreamCombQuery*/ false); + } + + if (session3_7 != nullptr) { + config3_7.streamConfigCounter = streamConfigCounter++; + ret = session3_7->configureStreams_3_7( + config3_7, + [](Status s, device::V3_6::HalStreamConfiguration halConfig) { + ASSERT_EQ(Status::OK, s); + ASSERT_EQ(2u, halConfig.streams.size()); + }); + } else if (session3_5 != nullptr) { config3_5.streamConfigCounter = streamConfigCounter++; ret = session3_5->configureStreams_3_5(config3_5, [](Status s, device::V3_4::HalStreamConfiguration halConfig) { @@ -4123,11 +4220,12 @@ TEST_P(CameraHidlTest, configureStreamsConstrainedOutputs) { sp session3_7; sp cameraDevice; sp cameraDevice3_5; + sp cameraDevice3_7; 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); + castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7); Status rc = isConstrainedModeAvailable(staticMeta); if (Status::METHOD_NOT_SUPPORTED == rc) { @@ -4152,14 +4250,27 @@ TEST_P(CameraHidlTest, configureStreamsConstrainedOutputs) { 0, StreamRotation::ROTATION_0}; ::android::hardware::hidl_vec streams = {stream}; + ::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; ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2; createStreamConfiguration(streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE, - &config3_2, &config3_4, &config3_5); + &config3_2, &config3_4, &config3_5, &config3_7); if (session3_5 != nullptr) { - verifyStreamCombination(cameraDevice3_5, config3_4, - /*expectedStatus*/ true, /*expectStreamCombQuery*/ false); + verifyStreamCombination(cameraDevice3_7, config3_7, cameraDevice3_5, config3_4, + /*expectedStatus*/ true, /*expectStreamCombQuery*/ false); + } + + if (session3_7 != nullptr) { + config3_7.streamConfigCounter = streamConfigCounter++; + ret = session3_7->configureStreams_3_7( + config3_7, + [streamId](Status s, device::V3_6::HalStreamConfiguration halConfig) { + ASSERT_EQ(Status::OK, s); + ASSERT_EQ(1u, halConfig.streams.size()); + ASSERT_EQ(halConfig.streams[0].v3_4.v3_3.v3_2.id, streamId); + }); + } else if (session3_5 != nullptr) { config3_5.streamConfigCounter = streamConfigCounter++; ret = session3_5->configureStreams_3_5(config3_5, [streamId](Status s, device::V3_4::HalStreamConfiguration halConfig) { @@ -4201,8 +4312,15 @@ TEST_P(CameraHidlTest, configureStreamsConstrainedOutputs) { StreamRotation::ROTATION_0}; streams[0] = stream; createStreamConfiguration(streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE, - &config3_2, &config3_4, &config3_5); - if (session3_5 != nullptr) { + &config3_2, &config3_4, &config3_5, &config3_7); + if (session3_7 != nullptr) { + config3_7.streamConfigCounter = streamConfigCounter++; + ret = session3_7->configureStreams_3_7( + config3_7, [](Status s, device::V3_6::HalStreamConfiguration) { + ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) || + (Status::INTERNAL_ERROR == s)); + }); + } else if (session3_5 != nullptr) { config3_5.streamConfigCounter = streamConfigCounter++; ret = session3_5->configureStreams_3_5(config3_5, [](Status s, device::V3_4::HalStreamConfiguration) { @@ -4240,8 +4358,14 @@ TEST_P(CameraHidlTest, configureStreamsConstrainedOutputs) { StreamRotation::ROTATION_0}; streams[0] = stream; createStreamConfiguration(streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE, - &config3_2, &config3_4, &config3_5); - if (session3_5 != nullptr) { + &config3_2, &config3_4, &config3_5, &config3_7); + if (session3_7 != nullptr) { + config3_7.streamConfigCounter = streamConfigCounter++; + ret = session3_7->configureStreams_3_7( + config3_7, [](Status s, device::V3_6::HalStreamConfiguration) { + ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); + }); + } else if (session3_5 != nullptr) { config3_5.streamConfigCounter = streamConfigCounter++; ret = session3_5->configureStreams_3_5(config3_5, [](Status s, device::V3_4::HalStreamConfiguration) { @@ -4275,8 +4399,14 @@ TEST_P(CameraHidlTest, configureStreamsConstrainedOutputs) { StreamRotation::ROTATION_0}; streams[0] = stream; createStreamConfiguration(streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE, - &config3_2, &config3_4, &config3_5); - if (session3_5 != nullptr) { + &config3_2, &config3_4, &config3_5, &config3_7); + if (session3_7 != nullptr) { + config3_7.streamConfigCounter = streamConfigCounter++; + ret = session3_7->configureStreams_3_7( + config3_7, [](Status s, device::V3_6::HalStreamConfiguration) { + ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); + }); + } else if (session3_5 != nullptr) { config3_5.streamConfigCounter = streamConfigCounter++; ret = session3_5->configureStreams_3_5(config3_5, [](Status s, device::V3_4::HalStreamConfiguration) { @@ -4337,11 +4467,12 @@ TEST_P(CameraHidlTest, configureStreamsVideoStillOutputs) { sp session3_7; sp cameraDevice; sp cameraDevice3_5; + sp cameraDevice3_7; 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); + castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7); // Check if camera support depth only if (isDepthOnly(staticMeta)) { @@ -4388,14 +4519,27 @@ TEST_P(CameraHidlTest, configureStreamsVideoStillOutputs) { static_cast(Dataspace::V0_JFIF), StreamRotation::ROTATION_0}; ::android::hardware::hidl_vec streams = {videoStream, blobStream}; + ::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; ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2; - createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, - &config3_2, &config3_4, &config3_5, jpegBufferSize); + createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, &config3_2, + &config3_4, &config3_5, &config3_7, jpegBufferSize); if (session3_5 != nullptr) { - verifyStreamCombination(cameraDevice3_5, config3_4, - /*expectedStatus*/ true, /*expectStreamCombQuery*/ false); + verifyStreamCombination(cameraDevice3_7, config3_7, cameraDevice3_5, config3_4, + /*expectedStatus*/ true, + /*expectStreamCombQuery*/ false); + } + + if (session3_7 != nullptr) { + config3_7.streamConfigCounter = streamConfigCounter++; + ret = session3_7->configureStreams_3_7( + config3_7, + [](Status s, device::V3_6::HalStreamConfiguration halConfig) { + ASSERT_EQ(Status::OK, s); + ASSERT_EQ(2u, halConfig.streams.size()); + }); + } else if (session3_5 != nullptr) { config3_5.streamConfigCounter = streamConfigCounter++; ret = session3_5->configureStreams_3_5(config3_5, [](Status s, device::V3_4::HalStreamConfiguration halConfig) { @@ -6142,6 +6286,28 @@ Status CameraHidlTest::getSystemCameraKind(const camera_metadata_t* staticMeta, return ret; } +void CameraHidlTest::getMultiResolutionStreamConfigurations( + camera_metadata_ro_entry* multiResStreamConfigs, camera_metadata_ro_entry* streamConfigs, + camera_metadata_ro_entry* maxResolutionStreamConfigs, + const camera_metadata_t* staticMetadata) { + ASSERT_NE(multiResStreamConfigs, nullptr); + ASSERT_NE(streamConfigs, nullptr); + ASSERT_NE(maxResolutionStreamConfigs, nullptr); + ASSERT_NE(staticMetadata, nullptr); + + int retcode = find_camera_metadata_ro_entry( + staticMetadata, ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, streamConfigs); + ASSERT_TRUE(0 == retcode); + retcode = find_camera_metadata_ro_entry( + staticMetadata, ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION, + maxResolutionStreamConfigs); + ASSERT_TRUE(-ENOENT == retcode || 0 == retcode); + retcode = find_camera_metadata_ro_entry( + staticMetadata, ANDROID_SCALER_PHYSICAL_CAMERA_MULTI_RESOLUTION_STREAM_CONFIGURATIONS, + multiResStreamConfigs); + ASSERT_TRUE(-ENOENT == retcode || 0 == retcode); +} + // Select an appropriate dataspace given a specific pixel format. V3_2::DataspaceFlags CameraHidlTest::getDataspace(PixelFormat format) { switch (format) { @@ -6245,15 +6411,18 @@ Status CameraHidlTest::isAutoFocusModeAvailable( void CameraHidlTest::createStreamConfiguration( const ::android::hardware::hidl_vec& streams3_2, StreamConfigurationMode configMode, - ::android::hardware::camera::device::V3_2::StreamConfiguration *config3_2 /*out*/, - ::android::hardware::camera::device::V3_4::StreamConfiguration *config3_4 /*out*/, - ::android::hardware::camera::device::V3_5::StreamConfiguration *config3_5 /*out*/, + ::android::hardware::camera::device::V3_2::StreamConfiguration* config3_2 /*out*/, + ::android::hardware::camera::device::V3_4::StreamConfiguration* config3_4 /*out*/, + ::android::hardware::camera::device::V3_5::StreamConfiguration* config3_5 /*out*/, + ::android::hardware::camera::device::V3_7::StreamConfiguration* config3_7 /*out*/, uint32_t jpegBufferSize) { ASSERT_NE(nullptr, config3_2); ASSERT_NE(nullptr, config3_4); ASSERT_NE(nullptr, config3_5); + ASSERT_NE(nullptr, config3_7); ::android::hardware::hidl_vec streams3_4(streams3_2.size()); + ::android::hardware::hidl_vec streams3_7(streams3_2.size()); size_t idx = 0; for (auto& stream3_2 : streams3_2) { V3_4::Stream stream; @@ -6263,9 +6432,12 @@ void CameraHidlTest::createStreamConfiguration( stream3_2.dataSpace == static_cast(Dataspace::V0_JFIF)) { stream.bufferSize = jpegBufferSize; } - streams3_4[idx++] = stream; + streams3_4[idx] = stream; + streams3_7[idx] = {stream, /*groupId*/ -1, {ANDROID_SENSOR_PIXEL_MODE_DEFAULT}}; + idx++; } // Caller is responsible to fill in non-zero config3_5->streamConfigCounter after this returns + *config3_7 = {streams3_7, configMode, {}, 0, false}; *config3_5 = {{streams3_4, configMode, {}}, 0}; *config3_4 = config3_5->v3_4; *config3_2 = {streams3_2, configMode}; @@ -6379,8 +6551,9 @@ void CameraHidlTest::configureStreams3_7( ASSERT_TRUE(ret.isOk()); ASSERT_TRUE(deviceVersion >= CAMERA_DEVICE_API_VERSION_3_7); + sp cameraDevice3_5 = nullptr; sp cameraDevice3_7 = nullptr; - castDevice3_7(device3_x, deviceVersion, &cameraDevice3_7); + castDevice(device3_x, deviceVersion, &cameraDevice3_5, &cameraDevice3_7); ASSERT_NE(cameraDevice3_7, nullptr); bool supported = false; ret = cameraDevice3_7->isStreamCombinationSupported_3_7( @@ -6532,7 +6705,8 @@ void CameraHidlTest::configurePreviewStreams3_4(const std::string &name, int32_t ASSERT_TRUE(!allowUnsupport || deviceVersion >= CAMERA_DEVICE_API_VERSION_3_5); if (allowUnsupport) { sp cameraDevice3_5; - castDevice(device3_x, deviceVersion, &cameraDevice3_5); + sp cameraDevice3_7; + castDevice(device3_x, deviceVersion, &cameraDevice3_5, &cameraDevice3_7); bool supported = false; ret = cameraDevice3_5->isStreamCombinationSupported(config3_4, @@ -6891,9 +7065,32 @@ void CameraHidlTest::configureSingleStream( ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2; ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4; ::android::hardware::camera::device::V3_5::StreamConfiguration config3_5; - createStreamConfiguration(streams3_2, StreamConfigurationMode::NORMAL_MODE, - &config3_2, &config3_4, &config3_5, jpegBufferSize); - if (session3_5 != nullptr) { + ::android::hardware::camera::device::V3_7::StreamConfiguration config3_7; + createStreamConfiguration(streams3_2, StreamConfigurationMode::NORMAL_MODE, &config3_2, + &config3_4, &config3_5, &config3_7, jpegBufferSize); + if (session3_7 != nullptr) { + ret = session3_7->constructDefaultRequestSettings( + reqTemplate, [&config3_7](auto status, const auto& req) { + ASSERT_EQ(Status::OK, status); + config3_7.sessionParams = req; + }); + ASSERT_TRUE(ret.isOk()); + config3_7.streamConfigCounter = streamConfigCounter; + ret = session3_7->configureStreams_3_7( + config3_7, [&](Status s, device::V3_6::HalStreamConfiguration halConfig) { + ASSERT_EQ(Status::OK, s); + ASSERT_EQ(1u, halConfig.streams.size()); + halStreamConfig->streams.resize(1); + halStreamConfig->streams[0] = halConfig.streams[0].v3_4.v3_3.v3_2; + if (*useHalBufManager) { + hidl_vec streams(1); + hidl_vec halStreams(1); + streams[0] = config3_4.streams[0]; + halStreams[0] = halConfig.streams[0].v3_4.v3_3.v3_2; + cb->setCurrentStreamConfig(streams, halStreams); + } + }); + } else if (session3_5 != nullptr) { ret = session3_5->constructDefaultRequestSettings(reqTemplate, [&config3_5](auto status, const auto& req) { ASSERT_EQ(Status::OK, status); @@ -6953,31 +7150,30 @@ void CameraHidlTest::configureSingleStream( ASSERT_TRUE(ret.isOk()); } -void CameraHidlTest::castDevice3_7(const sp& device, - int32_t deviceVersion, - sp* device3_7 /*out*/) { - ASSERT_NE(nullptr, device3_7); - if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_7) { - auto castResult = device::V3_7::ICameraDevice::castFrom(device); - ASSERT_TRUE(castResult.isOk()); - *device3_7 = castResult; - } -} - -void CameraHidlTest::castDevice(const sp &device, - int32_t deviceVersion, sp *device3_5/*out*/) { +void CameraHidlTest::castDevice(const sp& device, + int32_t deviceVersion, + sp* device3_5 /*out*/, + sp* device3_7 /*out*/) { ASSERT_NE(nullptr, device3_5); if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_5) { auto castResult = device::V3_5::ICameraDevice::castFrom(device); ASSERT_TRUE(castResult.isOk()); *device3_5 = castResult; } + + ASSERT_NE(nullptr, device3_7); + if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_7) { + auto castResult = device::V3_7::ICameraDevice::castFrom(device); + ASSERT_TRUE(castResult.isOk()); + *device3_7 = castResult; + } } //Cast camera provider to corresponding version if available void CameraHidlTest::castProvider(const sp& provider, sp* provider2_5 /*out*/, - sp* provider2_6 /*out*/) { + sp* provider2_6 /*out*/, + sp* provider2_7 /*out*/) { ASSERT_NE(nullptr, provider2_5); auto castResult2_5 = provider::V2_5::ICameraProvider::castFrom(provider); if (castResult2_5.isOk()) { @@ -6989,6 +7185,12 @@ void CameraHidlTest::castProvider(const sp& provider, if (castResult2_6.isOk()) { *provider2_6 = castResult2_6; } + + ASSERT_NE(nullptr, provider2_7); + auto castResult2_7 = provider::V2_7::ICameraProvider::castFrom(provider); + if (castResult2_7.isOk()) { + *provider2_7 = castResult2_7; + } } //Cast camera device session to corresponding version @@ -7041,9 +7243,24 @@ void CameraHidlTest::castSession(const sp &session, int32_ } } -void CameraHidlTest::verifyStreamCombination(sp cameraDevice3_5, - const ::android::hardware::camera::device::V3_4::StreamConfiguration &config3_4, +void CameraHidlTest::verifyStreamCombination( + sp cameraDevice3_7, + const ::android::hardware::camera::device::V3_7::StreamConfiguration& config3_7, + sp cameraDevice3_5, + const ::android::hardware::camera::device::V3_4::StreamConfiguration& config3_4, bool expectedStatus, bool expectMethodSupported) { + if (cameraDevice3_7.get() != nullptr) { + auto ret = cameraDevice3_7->isStreamCombinationSupported_3_7( + config3_7, [expectedStatus, expectMethodSupported](Status s, bool combStatus) { + ASSERT_TRUE((Status::OK == s) || + (!expectMethodSupported && Status::METHOD_NOT_SUPPORTED == s)); + if (Status::OK == s) { + ASSERT_TRUE(combStatus == expectedStatus); + } + }); + ASSERT_TRUE(ret.isOk()); + } + if (cameraDevice3_5.get() != nullptr) { auto ret = cameraDevice3_5->isStreamCombinationSupported(config3_4, [expectedStatus, expectMethodSupported] (Status s, bool combStatus) { @@ -7057,11 +7274,11 @@ void CameraHidlTest::verifyStreamCombination(sp cam } } -// Verify logical camera static metadata -void CameraHidlTest::verifyLogicalCameraMetadata(const std::string& cameraName, +// Verify logical or ultra high resolution camera static metadata +void CameraHidlTest::verifyLogicalOrUltraHighResCameraMetadata( + const std::string& cameraName, const ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice>& device, - const CameraMetadata &chars, int deviceVersion, - const hidl_vec& deviceNames) { + const CameraMetadata& chars, int deviceVersion, const hidl_vec& deviceNames) { const camera_metadata_t* metadata = (camera_metadata_t*)chars.data(); ASSERT_NE(nullptr, metadata); SystemCameraKind systemCameraKind = SystemCameraKind::PUBLIC; @@ -7069,7 +7286,9 @@ void CameraHidlTest::verifyLogicalCameraMetadata(const std::string& cameraName, ASSERT_EQ(rc, Status::OK); rc = isLogicalMultiCamera(metadata); ASSERT_TRUE(Status::OK == rc || Status::METHOD_NOT_SUPPORTED == rc); - if (Status::METHOD_NOT_SUPPORTED == rc) { + bool isMultiCamera = (Status::OK == rc); + bool isUltraHighResCamera = isUltraHighResolution(metadata); + if (!isMultiCamera && !isUltraHighResCamera) { return; } @@ -7077,13 +7296,36 @@ void CameraHidlTest::verifyLogicalCameraMetadata(const std::string& cameraName, int retcode = find_camera_metadata_ro_entry(metadata, ANDROID_CONTROL_ZOOM_RATIO_RANGE, &entry); bool hasZoomRatioRange = (0 == retcode && entry.count == 2); + retcode = find_camera_metadata_ro_entry( + metadata, ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION, &entry); + bool hasHalBufferManager = + (0 == retcode && 1 == entry.count && + entry.data.i32[0] == ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5); + retcode = find_camera_metadata_ro_entry( + metadata, ANDROID_SCALER_MULTI_RESOLUTION_STREAM_SUPPORTED, &entry); + bool multiResolutionStreamSupported = + (0 == retcode && 1 == entry.count && + entry.data.u8[0] == ANDROID_SCALER_MULTI_RESOLUTION_STREAM_SUPPORTED_TRUE); + if (multiResolutionStreamSupported) { + ASSERT_TRUE(hasHalBufferManager); + } std::string version, cameraId; ASSERT_TRUE(::matchDeviceName(cameraName, mProviderType, &version, &cameraId)); std::unordered_set physicalIds; - ASSERT_TRUE(Status::OK == getPhysicalCameraIds(metadata, &physicalIds)); + rc = getPhysicalCameraIds(metadata, &physicalIds); + ASSERT_TRUE(isUltraHighResCamera || Status::OK == rc); for (auto physicalId : physicalIds) { ASSERT_NE(physicalId, cameraId); + } + if (physicalIds.size() == 0) { + ASSERT_TRUE(isUltraHighResCamera && !isMultiCamera); + physicalIds.insert(cameraId); + } + // Map from image format to number of multi-resolution sizes for that format + std::unordered_map multiResOutputFormatCounterMap; + std::unordered_map multiResInputFormatCounterMap; + for (auto physicalId : physicalIds) { bool isPublicId = false; std::string fullPublicId; SystemCameraKind physSystemCameraKind = SystemCameraKind::PUBLIC; @@ -7096,6 +7338,11 @@ void CameraHidlTest::verifyLogicalCameraMetadata(const std::string& cameraName, break; } } + + camera_metadata_ro_entry physicalMultiResStreamConfigs; + camera_metadata_ro_entry physicalStreamConfigs; + camera_metadata_ro_entry physicalMaxResolutionStreamConfigs; + bool isUltraHighRes = false; if (isPublicId) { ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> subDevice; Return ret; @@ -7107,62 +7354,195 @@ void CameraHidlTest::verifyLogicalCameraMetadata(const std::string& cameraName, }); ASSERT_TRUE(ret.isOk()); - ret = subDevice->getCameraCharacteristics( - [&](auto status, const auto& chars) { + ret = subDevice->getCameraCharacteristics([&](auto status, const auto& chars) { ASSERT_EQ(Status::OK, status); - const camera_metadata_t* staticMeta = + const camera_metadata_t* staticMetadata = reinterpret_cast(chars.data()); - rc = getSystemCameraKind(staticMeta, &physSystemCameraKind); + rc = getSystemCameraKind(staticMetadata, &physSystemCameraKind); ASSERT_EQ(rc, Status::OK); // Make sure that the system camera kind of a non-hidden // physical cameras is the same as the logical camera associated // with it. ASSERT_EQ(physSystemCameraKind, systemCameraKind); - retcode = find_camera_metadata_ro_entry(staticMeta, + retcode = find_camera_metadata_ro_entry(staticMetadata, ANDROID_CONTROL_ZOOM_RATIO_RANGE, &entry); bool subCameraHasZoomRatioRange = (0 == retcode && entry.count == 2); ASSERT_EQ(hasZoomRatioRange, subCameraHasZoomRatioRange); + + getMultiResolutionStreamConfigurations( + &physicalMultiResStreamConfigs, &physicalStreamConfigs, + &physicalMaxResolutionStreamConfigs, staticMetadata); + isUltraHighRes = isUltraHighResolution(staticMetadata); }); ASSERT_TRUE(ret.isOk()); - continue; + } else { + ASSERT_TRUE(deviceVersion >= CAMERA_DEVICE_API_VERSION_3_5); + auto castResult = device::V3_5::ICameraDevice::castFrom(device); + ASSERT_TRUE(castResult.isOk()); + ::android::sp<::android::hardware::camera::device::V3_5::ICameraDevice> device3_5 = + castResult; + ASSERT_NE(device3_5, nullptr); + + // Check camera characteristics for hidden camera id + Return ret = device3_5->getPhysicalCameraCharacteristics( + physicalId, [&](auto status, const auto& chars) { + verifyCameraCharacteristics(status, chars); + verifyMonochromeCharacteristics(chars, deviceVersion); + + auto staticMetadata = (const camera_metadata_t*)chars.data(); + retcode = find_camera_metadata_ro_entry( + staticMetadata, ANDROID_CONTROL_ZOOM_RATIO_RANGE, &entry); + bool subCameraHasZoomRatioRange = (0 == retcode && entry.count == 2); + ASSERT_EQ(hasZoomRatioRange, subCameraHasZoomRatioRange); + + getMultiResolutionStreamConfigurations( + &physicalMultiResStreamConfigs, &physicalStreamConfigs, + &physicalMaxResolutionStreamConfigs, staticMetadata); + isUltraHighRes = isUltraHighResolution(staticMetadata); + }); + ASSERT_TRUE(ret.isOk()); + + // Check calling getCameraDeviceInterface_V3_x() on hidden camera id returns + // ILLEGAL_ARGUMENT. + std::stringstream s; + s << "device@" << version << "/" << mProviderType << "/" << physicalId; + hidl_string fullPhysicalId(s.str()); + ret = mProvider->getCameraDeviceInterface_V3_x( + fullPhysicalId, [&](auto status, const auto& device3_x) { + ASSERT_EQ(Status::ILLEGAL_ARGUMENT, status); + ASSERT_EQ(device3_x, nullptr); + }); + ASSERT_TRUE(ret.isOk()); } - ASSERT_TRUE(deviceVersion >= CAMERA_DEVICE_API_VERSION_3_5); - auto castResult = device::V3_5::ICameraDevice::castFrom(device); - ASSERT_TRUE(castResult.isOk()); - ::android::sp<::android::hardware::camera::device::V3_5::ICameraDevice> device3_5 = - castResult; - ASSERT_NE(device3_5, nullptr); + if (physicalMultiResStreamConfigs.count > 0) { + ASSERT_GE(deviceVersion, CAMERA_DEVICE_API_VERSION_3_7); + ASSERT_EQ(physicalMultiResStreamConfigs.count % 4, 0); + + // Each supported size must be max size for that format, + for (size_t i = 0; i < physicalMultiResStreamConfigs.count / 4; i++) { + int32_t multiResFormat = physicalMultiResStreamConfigs.data.i32[i * 4]; + int32_t multiResWidth = physicalMultiResStreamConfigs.data.i32[i * 4 + 1]; + int32_t multiResHeight = physicalMultiResStreamConfigs.data.i32[i * 4 + 2]; + int32_t multiResInput = physicalMultiResStreamConfigs.data.i32[i * 4 + 3]; + + // Check if the resolution is the max resolution in stream + // configuration map + bool supported = false; + bool isMaxSize = true; + for (size_t j = 0; j < physicalStreamConfigs.count / 4; j++) { + int32_t format = physicalStreamConfigs.data.i32[j * 4]; + int32_t width = physicalStreamConfigs.data.i32[j * 4 + 1]; + int32_t height = physicalStreamConfigs.data.i32[j * 4 + 2]; + int32_t input = physicalStreamConfigs.data.i32[j * 4 + 3]; + if (format == multiResFormat && input == multiResInput) { + if (width == multiResWidth && height == multiResHeight) { + supported = true; + } else if (width * height > multiResWidth * multiResHeight) { + isMaxSize = false; + } + } + } + // Check if the resolution is the max resolution in max + // resolution stream configuration map + bool supportedUltraHighRes = false; + bool isUltraHighResMaxSize = true; + for (size_t j = 0; j < physicalMaxResolutionStreamConfigs.count / 4; j++) { + int32_t format = physicalMaxResolutionStreamConfigs.data.i32[j * 4]; + int32_t width = physicalMaxResolutionStreamConfigs.data.i32[j * 4 + 1]; + int32_t height = physicalMaxResolutionStreamConfigs.data.i32[j * 4 + 2]; + int32_t input = physicalMaxResolutionStreamConfigs.data.i32[j * 4 + 3]; + if (format == multiResFormat && input == multiResInput) { + if (width == multiResWidth && height == multiResHeight) { + supportedUltraHighRes = true; + } else if (width * height > multiResWidth * multiResHeight) { + isUltraHighResMaxSize = false; + } + } + } - // Check camera characteristics for hidden camera id - Return ret = device3_5->getPhysicalCameraCharacteristics( - physicalId, [&](auto status, const auto& chars) { - verifyCameraCharacteristics(status, chars); - verifyMonochromeCharacteristics(chars, deviceVersion); - retcode = - find_camera_metadata_ro_entry((const camera_metadata_t*)chars.data(), - ANDROID_CONTROL_ZOOM_RATIO_RANGE, &entry); - bool subCameraHasZoomRatioRange = (0 == retcode && entry.count == 2); - ASSERT_EQ(hasZoomRatioRange, subCameraHasZoomRatioRange); - }); - ASSERT_TRUE(ret.isOk()); + if (isUltraHighRes) { + // For ultra high resolution camera, the configuration must + // be the maximum size in stream configuration map, or max + // resolution stream configuration map + ASSERT_TRUE((supported && isMaxSize) || + (supportedUltraHighRes && isUltraHighResMaxSize)); + } else { + // The configuration must be the maximum size in stream + // configuration map + ASSERT_TRUE(supported && isMaxSize); + ASSERT_FALSE(supportedUltraHighRes); + } - // Check calling getCameraDeviceInterface_V3_x() on hidden camera id returns - // ILLEGAL_ARGUMENT. - std::stringstream s; - s << "device@" << version << "/" << mProviderType << "/" << physicalId; - hidl_string fullPhysicalId(s.str()); - ret = mProvider->getCameraDeviceInterface_V3_x(fullPhysicalId, - [&](auto status, const auto& device3_x) { - ASSERT_EQ(Status::ILLEGAL_ARGUMENT, status); - ASSERT_EQ(device3_x, nullptr); - }); - ASSERT_TRUE(ret.isOk()); + // Increment the counter for the configuration's format. + auto& formatCounterMap = multiResInput ? multiResInputFormatCounterMap + : multiResOutputFormatCounterMap; + if (formatCounterMap.count(multiResFormat) == 0) { + formatCounterMap[multiResFormat] = 1; + } else { + formatCounterMap[multiResFormat]++; + } + } + + // There must be no duplicates + for (size_t i = 0; i < physicalMultiResStreamConfigs.count / 4 - 1; i++) { + for (size_t j = i + 1; j < physicalMultiResStreamConfigs.count / 4; j++) { + // Input/output doesn't match + if (physicalMultiResStreamConfigs.data.i32[i * 4 + 3] != + physicalMultiResStreamConfigs.data.i32[j * 4 + 3]) { + continue; + } + // Format doesn't match + if (physicalMultiResStreamConfigs.data.i32[i * 4] != + physicalMultiResStreamConfigs.data.i32[j * 4]) { + continue; + } + // Width doesn't match + if (physicalMultiResStreamConfigs.data.i32[i * 4 + 1] != + physicalMultiResStreamConfigs.data.i32[j * 4 + 1]) { + continue; + } + // Height doesn't match + if (physicalMultiResStreamConfigs.data.i32[i * 4 + 2] != + physicalMultiResStreamConfigs.data.i32[j * 4 + 2]) { + continue; + } + // input/output, format, width, and height all match + ADD_FAILURE(); + } + } + } + } + + // If a multi-resolution stream is supported, there must be at least one + // format with more than one resolutions + if (multiResolutionStreamSupported) { + size_t numMultiResFormats = 0; + for (const auto& [format, sizeCount] : multiResOutputFormatCounterMap) { + if (sizeCount >= 2) { + numMultiResFormats++; + } + } + for (const auto& [format, sizeCount] : multiResInputFormatCounterMap) { + if (sizeCount >= 2) { + numMultiResFormats++; + + // If multi-resolution reprocessing is supported, the logical + // camera or ultra-high resolution sensor camera must support + // the corresponding reprocessing capability. + if (format == static_cast(PixelFormat::IMPLEMENTATION_DEFINED)) { + ASSERT_EQ(isZSLModeAvailable(metadata, PRIV_REPROCESS), Status::OK); + } else if (format == static_cast(PixelFormat::YCBCR_420_888)) { + ASSERT_EQ(isZSLModeAvailable(metadata, YUV_REPROCESS), Status::OK); + } + } + } + ASSERT_GT(numMultiResFormats, 0); } // Make sure ANDROID_LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID is available in // result keys. - if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_5) { + if (isMultiCamera && deviceVersion >= CAMERA_DEVICE_API_VERSION_3_5) { retcode = find_camera_metadata_ro_entry(metadata, ANDROID_REQUEST_AVAILABLE_RESULT_KEYS, &entry); if ((0 == retcode) && (entry.count > 0)) { -- GitLab From 35f34f4d016cc693507e8036ceaf37c99db76837 Mon Sep 17 00:00:00 2001 From: Alisher Alikhodjaev Date: Thu, 15 Apr 2021 19:06:47 -0700 Subject: [PATCH 612/790] Out of bounds read in hal_core_initialized Bug: 176446340 Test: build and run Change-Id: I02f93750e590b2384f79580dd7c06fc06f46a4ca --- nfc/1.0/default/Nfc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nfc/1.0/default/Nfc.cpp b/nfc/1.0/default/Nfc.cpp index fcdcbbc301..a1e50f059c 100644 --- a/nfc/1.0/default/Nfc.cpp +++ b/nfc/1.0/default/Nfc.cpp @@ -38,7 +38,7 @@ Nfc::Nfc(nfc_nci_device_t* device) : mDevice(device) {} ::android::hardware::Return Nfc::coreInitialized(const hidl_vec& data) { hidl_vec copy = data; - if (mDevice == nullptr) { + if (mDevice == nullptr || copy.size() == 0) { return NfcStatus::FAILED; } int ret = mDevice->core_initialized(mDevice, ©[0]); -- GitLab From 95adbba86eee3d76a3f8ca60db41b8eeb95afd31 Mon Sep 17 00:00:00 2001 From: Alec Mouri Date: Thu, 15 Apr 2021 16:27:01 +0000 Subject: [PATCH 613/790] Revert "Update Readback VTS to align with RenderEngine interface..." Revert "Update WaylandRenderSurface to accomodate interface change" Revert "Add ExternalTexture class into RenderEngine interface" Revert submission 14086921-renderengine-external-tex Reason for revert: Potential culprit for b/185361988 Reverted Changes: I7796764e2:Update WaylandRenderSurface to accomodate interfac... I13904eec4:Update Readback VTS to align with RenderEngine int... I222c71e6e:Add ExternalTexture class into RenderEngine interf... Change-Id: I7d58118c1c2284a04eb52e992e901d82faaf5bb0 (cherry picked from commit 51daee615fd434d768986b8dc8e5207165c2a603) --- .../composer/2.2/utils/vts/ReadbackVts.cpp | 15 +++---- .../2.2/utils/vts/RenderEngineVts.cpp | 4 +- .../include/composer-vts/2.2/ReadbackVts.h | 6 +-- .../composer-vts/2.2/RenderEngineVts.h | 6 --- ...VtsHalGraphicsComposerV2_2ReadbackTest.cpp | 44 +++++++++---------- 5 files changed, 29 insertions(+), 46 deletions(-) diff --git a/graphics/composer/2.2/utils/vts/ReadbackVts.cpp b/graphics/composer/2.2/utils/vts/ReadbackVts.cpp index 19f5e8c614..b179f35109 100644 --- a/graphics/composer/2.2/utils/vts/ReadbackVts.cpp +++ b/graphics/composer/2.2/utils/vts/ReadbackVts.cpp @@ -15,8 +15,6 @@ */ #include -#include -#include "renderengine/ExternalTexture.h" namespace android { namespace hardware { @@ -259,11 +257,10 @@ LayerSettings TestColorLayer::toRenderEngineLayerSettings() { } TestBufferLayer::TestBufferLayer(const std::shared_ptr& client, - const std::shared_ptr& gralloc, - TestRenderEngine& renderEngine, Display display, int32_t width, - int32_t height, PixelFormat format, + const std::shared_ptr& gralloc, Display display, + int32_t width, int32_t height, PixelFormat format, IComposerClient::Composition composition) - : TestLayer{client, display}, mRenderEngine(renderEngine) { + : TestLayer{client, display} { mGralloc = gralloc; mComposition = composition; mWidth = width; @@ -296,11 +293,9 @@ void TestBufferLayer::write(const std::shared_ptr& writer) { LayerSettings TestBufferLayer::toRenderEngineLayerSettings() { LayerSettings layerSettings = TestLayer::toRenderEngineLayerSettings(); - layerSettings.source.buffer.buffer = std::make_shared( + layerSettings.source.buffer.buffer = new GraphicBuffer(mBufferHandle, GraphicBuffer::CLONE_HANDLE, mWidth, mHeight, - static_cast(mFormat), 1, mUsage, mStride), - mRenderEngine.getInternalRenderEngine(), - renderengine::ExternalTexture::Usage::READABLE); + static_cast(mFormat), 1, mUsage, mStride); 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 f78dda2689..3becacea91 100644 --- a/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp +++ b/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp @@ -69,9 +69,7 @@ void TestRenderEngine::drawLayers() { [](renderengine::LayerSettings& settings) -> renderengine::LayerSettings* { return &settings; }); - auto texture = std::make_shared( - mGraphicBuffer, *mRenderEngine, renderengine::ExternalTexture::Usage::WRITEABLE); - mRenderEngine->drawLayers(mDisplaySettings, compositionLayerPointers, texture, true, + mRenderEngine->drawLayers(mDisplaySettings, compositionLayerPointers, mGraphicBuffer, true, std::move(bufferFence), &readyFence); int fd = readyFence.release(); if (fd != -1) { diff --git a/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ReadbackVts.h b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ReadbackVts.h index b24e3b63bd..d5eedf122c 100644 --- a/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ReadbackVts.h +++ b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ReadbackVts.h @@ -50,8 +50,6 @@ static const IComposerClient::Color TRANSLUCENT_RED = {0xff, 0, 0, 0x33}; static const IComposerClient::Color GREEN = {0, 0xff, 0, 0xff}; static const IComposerClient::Color BLUE = {0, 0, 0xff, 0xff}; -class TestRenderEngine; - class TestLayer { public: TestLayer(const std::shared_ptr& client, Display display) @@ -112,8 +110,7 @@ class TestBufferLayer : public TestLayer { public: TestBufferLayer( const std::shared_ptr& client, const std::shared_ptr& gralloc, - TestRenderEngine& renderEngine, Display display, int32_t width, int32_t height, - PixelFormat format, + Display display, int32_t width, int32_t height, PixelFormat format, IComposerClient::Composition composition = IComposerClient::Composition::DEVICE); ~TestBufferLayer(); @@ -141,7 +138,6 @@ class TestBufferLayer : public TestLayer { protected: IComposerClient::Composition mComposition; std::shared_ptr mGralloc; - TestRenderEngine& mRenderEngine; int32_t mFillFence; const native_handle_t* mBufferHandle = nullptr; }; diff --git a/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/RenderEngineVts.h b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/RenderEngineVts.h index 26027d33a2..f2d5f1933f 100644 --- a/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/RenderEngineVts.h +++ b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/RenderEngineVts.h @@ -14,12 +14,9 @@ * limitations under the License. */ -#pragma once - #include #include #include -#include #include #include #include @@ -54,15 +51,12 @@ class TestRenderEngine { void drawLayers(); void checkColorBuffer(std::vector& expectedColors); - renderengine::RenderEngine& getInternalRenderEngine() { return *mRenderEngine; } - private: common::V1_1::PixelFormat mFormat; std::vector mCompositionLayers; std::unique_ptr mRenderEngine; std::vector mRenderLayers; sp mGraphicBuffer; - DisplaySettings mDisplaySettings; }; diff --git a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp index 8d52173e59..1463c3be6c 100644 --- a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp +++ b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp @@ -288,9 +288,9 @@ TEST_P(GraphicsCompositionTest, SetLayerBuffer) { {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight}, BLUE); - auto layer = std::make_shared( - mComposerClient, mGralloc, *mTestRenderEngine, mPrimaryDisplay, mDisplayWidth, - mDisplayHeight, PixelFormat::RGBA_8888); + auto layer = std::make_shared(mComposerClient, mGralloc, mPrimaryDisplay, + mDisplayWidth, mDisplayHeight, + PixelFormat::RGBA_8888); layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight}); layer->setZOrder(10); layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter); @@ -422,9 +422,9 @@ TEST_P(GraphicsCompositionTest, ClientComposition) { {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight}, BLUE); - auto layer = std::make_shared( - mComposerClient, mGralloc, *mTestRenderEngine, mPrimaryDisplay, mDisplayWidth, - mDisplayHeight, PixelFormat::RGBA_FP16); + auto layer = std::make_shared(mComposerClient, mGralloc, mPrimaryDisplay, + mDisplayWidth, mDisplayHeight, + PixelFormat::RGBA_FP16); layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight}); layer->setZOrder(10); layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter); @@ -538,8 +538,8 @@ TEST_P(GraphicsCompositionTest, DeviceAndClientComposition) { ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer()); auto deviceLayer = std::make_shared( - mComposerClient, mGralloc, *mTestRenderEngine, mPrimaryDisplay, mDisplayWidth, - mDisplayHeight / 2, PixelFormat::RGBA_8888); + mComposerClient, mGralloc, mPrimaryDisplay, mDisplayWidth, mDisplayHeight / 2, + PixelFormat::RGBA_8888); std::vector deviceColors(deviceLayer->mWidth * deviceLayer->mHeight); ReadbackHelper::fillColorsArea(deviceColors, deviceLayer->mWidth, @@ -575,8 +575,8 @@ TEST_P(GraphicsCompositionTest, DeviceAndClientComposition) { } auto clientLayer = std::make_shared( - mComposerClient, mGralloc, *mTestRenderEngine, mPrimaryDisplay, clientWidth, - clientHeight, PixelFormat::RGBA_FP16, IComposerClient::Composition::DEVICE); + mComposerClient, mGralloc, mPrimaryDisplay, clientWidth, clientHeight, + PixelFormat::RGBA_FP16, IComposerClient::Composition::DEVICE); IComposerClient::Rect clientFrame = {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight}; clientLayer->setDisplayFrame(clientFrame); clientLayer->setZOrder(0); @@ -657,9 +657,9 @@ TEST_P(GraphicsCompositionTest, SetLayerDamage) { std::vector expectedColors(mDisplayWidth * mDisplayHeight); ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, redRect, RED); - auto layer = std::make_shared( - mComposerClient, mGralloc, *mTestRenderEngine, mPrimaryDisplay, mDisplayWidth, - mDisplayHeight, PixelFormat::RGBA_8888); + auto layer = std::make_shared(mComposerClient, mGralloc, mPrimaryDisplay, + mDisplayWidth, mDisplayHeight, + PixelFormat::RGBA_8888); layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight}); layer->setZOrder(10); layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter); @@ -805,9 +805,9 @@ TEST_P(GraphicsCompositionTest, SetLayerSourceCrop) { {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight}, BLUE); - auto layer = std::make_shared( - mComposerClient, mGralloc, *mTestRenderEngine, mPrimaryDisplay, mDisplayWidth, - mDisplayHeight, PixelFormat::RGBA_8888); + auto layer = std::make_shared(mComposerClient, mGralloc, mPrimaryDisplay, + mDisplayWidth, mDisplayHeight, + PixelFormat::RGBA_8888); layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight}); layer->setZOrder(10); layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter); @@ -957,9 +957,9 @@ class GraphicsBlendModeCompositionTest backgroundLayer->setZOrder(0); backgroundLayer->setColor(mBackgroundColor); - auto layer = std::make_shared( - mComposerClient, mGralloc, *mTestRenderEngine, mPrimaryDisplay, mDisplayWidth, - mDisplayHeight, PixelFormat::RGBA_8888); + auto layer = std::make_shared(mComposerClient, mGralloc, mPrimaryDisplay, + mDisplayWidth, mDisplayHeight, + PixelFormat::RGBA_8888); layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight}); layer->setZOrder(10); layer->setDataspace(Dataspace::UNKNOWN, mWriter); @@ -1195,9 +1195,9 @@ class GraphicsTransformCompositionTest : public GraphicsCompositionTest { IComposerClient::Rect blueRect = {mSideLength / 2, mSideLength / 2, mSideLength, mSideLength}; - mLayer = std::make_shared(mComposerClient, mGralloc, *mTestRenderEngine, - mPrimaryDisplay, mSideLength, mSideLength, - PixelFormat::RGBA_8888); + mLayer = + std::make_shared(mComposerClient, mGralloc, mPrimaryDisplay, + mSideLength, mSideLength, PixelFormat::RGBA_8888); mLayer->setDisplayFrame({0, 0, mSideLength, mSideLength}); mLayer->setZOrder(10); -- GitLab From 2a6ef4e566a9aaaeaff1aee18a2a1127479816ce Mon Sep 17 00:00:00 2001 From: Alec Mouri Date: Fri, 16 Apr 2021 16:36:21 +0000 Subject: [PATCH 614/790] Revert "Revert "Update Readback VTS to align with RenderEngine i..." Revert "Revert "Update WaylandRenderSurface to accomodate interf..." Revert "Revert "Add ExternalTexture class into RenderEngine inte..." Revert submission 14199598-revert-14086921-renderengine-external-tex-QJNBWQMQEU Reason for revert: Prepare for relanding Reverted Changes: I01e65a7f4:Revert "Update WaylandRenderSurface to accomodate ... I7d58118c1:Revert "Update Readback VTS to align with RenderEn... I1501890f4:Revert "Add ExternalTexture class into RenderEngin... Change-Id: Ic2ee9311d22658ac77c8a94f6070324cf07b601b --- .../composer/2.2/utils/vts/ReadbackVts.cpp | 15 ++++--- .../2.2/utils/vts/RenderEngineVts.cpp | 4 +- .../include/composer-vts/2.2/ReadbackVts.h | 6 ++- .../composer-vts/2.2/RenderEngineVts.h | 6 +++ ...VtsHalGraphicsComposerV2_2ReadbackTest.cpp | 44 +++++++++---------- 5 files changed, 46 insertions(+), 29 deletions(-) diff --git a/graphics/composer/2.2/utils/vts/ReadbackVts.cpp b/graphics/composer/2.2/utils/vts/ReadbackVts.cpp index b179f35109..19f5e8c614 100644 --- a/graphics/composer/2.2/utils/vts/ReadbackVts.cpp +++ b/graphics/composer/2.2/utils/vts/ReadbackVts.cpp @@ -15,6 +15,8 @@ */ #include +#include +#include "renderengine/ExternalTexture.h" namespace android { namespace hardware { @@ -257,10 +259,11 @@ LayerSettings TestColorLayer::toRenderEngineLayerSettings() { } TestBufferLayer::TestBufferLayer(const std::shared_ptr& client, - const std::shared_ptr& gralloc, Display display, - int32_t width, int32_t height, PixelFormat format, + const std::shared_ptr& gralloc, + TestRenderEngine& renderEngine, Display display, int32_t width, + int32_t height, PixelFormat format, IComposerClient::Composition composition) - : TestLayer{client, display} { + : TestLayer{client, display}, mRenderEngine(renderEngine) { mGralloc = gralloc; mComposition = composition; mWidth = width; @@ -293,9 +296,11 @@ void TestBufferLayer::write(const std::shared_ptr& writer) { LayerSettings TestBufferLayer::toRenderEngineLayerSettings() { LayerSettings layerSettings = TestLayer::toRenderEngineLayerSettings(); - layerSettings.source.buffer.buffer = + layerSettings.source.buffer.buffer = std::make_shared( new GraphicBuffer(mBufferHandle, GraphicBuffer::CLONE_HANDLE, mWidth, mHeight, - static_cast(mFormat), 1, mUsage, mStride); + static_cast(mFormat), 1, mUsage, mStride), + mRenderEngine.getInternalRenderEngine(), + renderengine::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 3becacea91..f78dda2689 100644 --- a/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp +++ b/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp @@ -69,7 +69,9 @@ void TestRenderEngine::drawLayers() { [](renderengine::LayerSettings& settings) -> renderengine::LayerSettings* { return &settings; }); - mRenderEngine->drawLayers(mDisplaySettings, compositionLayerPointers, mGraphicBuffer, true, + auto texture = std::make_shared( + mGraphicBuffer, *mRenderEngine, renderengine::ExternalTexture::Usage::WRITEABLE); + mRenderEngine->drawLayers(mDisplaySettings, compositionLayerPointers, texture, true, std::move(bufferFence), &readyFence); int fd = readyFence.release(); if (fd != -1) { diff --git a/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ReadbackVts.h b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ReadbackVts.h index d5eedf122c..b24e3b63bd 100644 --- a/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ReadbackVts.h +++ b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ReadbackVts.h @@ -50,6 +50,8 @@ static const IComposerClient::Color TRANSLUCENT_RED = {0xff, 0, 0, 0x33}; static const IComposerClient::Color GREEN = {0, 0xff, 0, 0xff}; static const IComposerClient::Color BLUE = {0, 0, 0xff, 0xff}; +class TestRenderEngine; + class TestLayer { public: TestLayer(const std::shared_ptr& client, Display display) @@ -110,7 +112,8 @@ class TestBufferLayer : public TestLayer { public: TestBufferLayer( const std::shared_ptr& client, const std::shared_ptr& gralloc, - Display display, int32_t width, int32_t height, PixelFormat format, + TestRenderEngine& renderEngine, Display display, int32_t width, int32_t height, + PixelFormat format, IComposerClient::Composition composition = IComposerClient::Composition::DEVICE); ~TestBufferLayer(); @@ -138,6 +141,7 @@ class TestBufferLayer : public TestLayer { protected: IComposerClient::Composition mComposition; std::shared_ptr mGralloc; + TestRenderEngine& mRenderEngine; int32_t mFillFence; const native_handle_t* mBufferHandle = nullptr; }; diff --git a/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/RenderEngineVts.h b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/RenderEngineVts.h index f2d5f1933f..26027d33a2 100644 --- a/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/RenderEngineVts.h +++ b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/RenderEngineVts.h @@ -14,9 +14,12 @@ * limitations under the License. */ +#pragma once + #include #include #include +#include #include #include #include @@ -51,12 +54,15 @@ class TestRenderEngine { void drawLayers(); void checkColorBuffer(std::vector& expectedColors); + renderengine::RenderEngine& getInternalRenderEngine() { return *mRenderEngine; } + private: common::V1_1::PixelFormat mFormat; std::vector mCompositionLayers; std::unique_ptr mRenderEngine; std::vector mRenderLayers; sp mGraphicBuffer; + DisplaySettings mDisplaySettings; }; diff --git a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp index 1463c3be6c..8d52173e59 100644 --- a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp +++ b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp @@ -288,9 +288,9 @@ TEST_P(GraphicsCompositionTest, SetLayerBuffer) { {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight}, BLUE); - auto layer = std::make_shared(mComposerClient, mGralloc, mPrimaryDisplay, - mDisplayWidth, mDisplayHeight, - PixelFormat::RGBA_8888); + auto layer = std::make_shared( + mComposerClient, mGralloc, *mTestRenderEngine, mPrimaryDisplay, mDisplayWidth, + mDisplayHeight, PixelFormat::RGBA_8888); layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight}); layer->setZOrder(10); layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter); @@ -422,9 +422,9 @@ TEST_P(GraphicsCompositionTest, ClientComposition) { {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight}, BLUE); - auto layer = std::make_shared(mComposerClient, mGralloc, mPrimaryDisplay, - mDisplayWidth, mDisplayHeight, - PixelFormat::RGBA_FP16); + auto layer = std::make_shared( + mComposerClient, mGralloc, *mTestRenderEngine, mPrimaryDisplay, mDisplayWidth, + mDisplayHeight, PixelFormat::RGBA_FP16); layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight}); layer->setZOrder(10); layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter); @@ -538,8 +538,8 @@ TEST_P(GraphicsCompositionTest, DeviceAndClientComposition) { ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer()); auto deviceLayer = std::make_shared( - mComposerClient, mGralloc, mPrimaryDisplay, mDisplayWidth, mDisplayHeight / 2, - PixelFormat::RGBA_8888); + mComposerClient, mGralloc, *mTestRenderEngine, mPrimaryDisplay, mDisplayWidth, + mDisplayHeight / 2, PixelFormat::RGBA_8888); std::vector deviceColors(deviceLayer->mWidth * deviceLayer->mHeight); ReadbackHelper::fillColorsArea(deviceColors, deviceLayer->mWidth, @@ -575,8 +575,8 @@ TEST_P(GraphicsCompositionTest, DeviceAndClientComposition) { } auto clientLayer = std::make_shared( - mComposerClient, mGralloc, mPrimaryDisplay, clientWidth, clientHeight, - PixelFormat::RGBA_FP16, IComposerClient::Composition::DEVICE); + mComposerClient, mGralloc, *mTestRenderEngine, mPrimaryDisplay, clientWidth, + clientHeight, PixelFormat::RGBA_FP16, IComposerClient::Composition::DEVICE); IComposerClient::Rect clientFrame = {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight}; clientLayer->setDisplayFrame(clientFrame); clientLayer->setZOrder(0); @@ -657,9 +657,9 @@ TEST_P(GraphicsCompositionTest, SetLayerDamage) { std::vector expectedColors(mDisplayWidth * mDisplayHeight); ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth, redRect, RED); - auto layer = std::make_shared(mComposerClient, mGralloc, mPrimaryDisplay, - mDisplayWidth, mDisplayHeight, - PixelFormat::RGBA_8888); + auto layer = std::make_shared( + mComposerClient, mGralloc, *mTestRenderEngine, mPrimaryDisplay, mDisplayWidth, + mDisplayHeight, PixelFormat::RGBA_8888); layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight}); layer->setZOrder(10); layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter); @@ -805,9 +805,9 @@ TEST_P(GraphicsCompositionTest, SetLayerSourceCrop) { {0, mDisplayHeight / 2, mDisplayWidth, mDisplayHeight}, BLUE); - auto layer = std::make_shared(mComposerClient, mGralloc, mPrimaryDisplay, - mDisplayWidth, mDisplayHeight, - PixelFormat::RGBA_8888); + auto layer = std::make_shared( + mComposerClient, mGralloc, *mTestRenderEngine, mPrimaryDisplay, mDisplayWidth, + mDisplayHeight, PixelFormat::RGBA_8888); layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight}); layer->setZOrder(10); layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), mWriter); @@ -957,9 +957,9 @@ class GraphicsBlendModeCompositionTest backgroundLayer->setZOrder(0); backgroundLayer->setColor(mBackgroundColor); - auto layer = std::make_shared(mComposerClient, mGralloc, mPrimaryDisplay, - mDisplayWidth, mDisplayHeight, - PixelFormat::RGBA_8888); + auto layer = std::make_shared( + mComposerClient, mGralloc, *mTestRenderEngine, mPrimaryDisplay, mDisplayWidth, + mDisplayHeight, PixelFormat::RGBA_8888); layer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight}); layer->setZOrder(10); layer->setDataspace(Dataspace::UNKNOWN, mWriter); @@ -1195,9 +1195,9 @@ class GraphicsTransformCompositionTest : public GraphicsCompositionTest { IComposerClient::Rect blueRect = {mSideLength / 2, mSideLength / 2, mSideLength, mSideLength}; - mLayer = - std::make_shared(mComposerClient, mGralloc, mPrimaryDisplay, - mSideLength, mSideLength, PixelFormat::RGBA_8888); + mLayer = std::make_shared(mComposerClient, mGralloc, *mTestRenderEngine, + mPrimaryDisplay, mSideLength, mSideLength, + PixelFormat::RGBA_8888); mLayer->setDisplayFrame({0, 0, mSideLength, mSideLength}); mLayer->setZOrder(10); -- GitLab From 7283cbe8cbb250fc42f0358d4ca4c94f3c32b344 Mon Sep 17 00:00:00 2001 From: Steven Moreland Date: Tue, 13 Apr 2021 20:14:16 +0000 Subject: [PATCH 615/790] audio HAL - fix UAFs Bug: 185259758 Test: N/A Change-Id: I5ec70b098a00746108e10ab39e966607d78c84ae Merged-In: I5ec70b098a00746108e10ab39e966607d78c84ae (cherry picked from commit a8ac7cf706be7a77589070ea7c62f8e1b94ce316) --- audio/core/all-versions/default/StreamIn.cpp | 8 ++++---- audio/core/all-versions/default/StreamOut.cpp | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/audio/core/all-versions/default/StreamIn.cpp b/audio/core/all-versions/default/StreamIn.cpp index d316f83617..caf8bae8c6 100644 --- a/audio/core/all-versions/default/StreamIn.cpp +++ b/audio/core/all-versions/default/StreamIn.cpp @@ -387,9 +387,9 @@ Return StreamIn::prepareForReading(uint32_t frameSize, uint32_t framesCoun } // Create and launch the thread. - auto tempReadThread = - std::make_unique(&mStopReadThread, mStream, tempCommandMQ.get(), - tempDataMQ.get(), tempStatusMQ.get(), tempElfGroup.get()); + sp tempReadThread = + new ReadThread(&mStopReadThread, mStream, tempCommandMQ.get(), tempDataMQ.get(), + tempStatusMQ.get(), tempElfGroup.get()); if (!tempReadThread->init()) { ALOGW("failed to start reader thread: %s", strerror(-status)); sendError(Result::INVALID_ARGUMENTS); @@ -405,7 +405,7 @@ Return StreamIn::prepareForReading(uint32_t frameSize, uint32_t framesCoun mCommandMQ = std::move(tempCommandMQ); mDataMQ = std::move(tempDataMQ); mStatusMQ = std::move(tempStatusMQ); - mReadThread = tempReadThread.release(); + mReadThread = tempReadThread; mEfGroup = tempElfGroup.release(); threadInfo.pid = getpid(); threadInfo.tid = mReadThread->getTid(); diff --git a/audio/core/all-versions/default/StreamOut.cpp b/audio/core/all-versions/default/StreamOut.cpp index 82cc408e99..19f925ab4e 100644 --- a/audio/core/all-versions/default/StreamOut.cpp +++ b/audio/core/all-versions/default/StreamOut.cpp @@ -370,9 +370,9 @@ Return StreamOut::prepareForWriting(uint32_t frameSize, uint32_t framesCou } // Create and launch the thread. - auto tempWriteThread = - std::make_unique(&mStopWriteThread, mStream, tempCommandMQ.get(), - tempDataMQ.get(), tempStatusMQ.get(), tempElfGroup.get()); + sp tempWriteThread = + new WriteThread(&mStopWriteThread, mStream, tempCommandMQ.get(), tempDataMQ.get(), + tempStatusMQ.get(), tempElfGroup.get()); if (!tempWriteThread->init()) { ALOGW("failed to start writer thread: %s", strerror(-status)); sendError(Result::INVALID_ARGUMENTS); @@ -388,7 +388,7 @@ Return StreamOut::prepareForWriting(uint32_t frameSize, uint32_t framesCou mCommandMQ = std::move(tempCommandMQ); mDataMQ = std::move(tempDataMQ); mStatusMQ = std::move(tempStatusMQ); - mWriteThread = tempWriteThread.release(); + mWriteThread = tempWriteThread; mEfGroup = tempElfGroup.release(); threadInfo.pid = getpid(); threadInfo.tid = mWriteThread->getTid(); -- GitLab From bd78085f08d5e342a1e0b02dde7a25832c2dd62e Mon Sep 17 00:00:00 2001 From: Mikhail Naganov Date: Fri, 16 Apr 2021 18:54:28 +0000 Subject: [PATCH 616/790] audio HAL - fix UAFs Bug: 185259758 Test: N/A Change-Id: I5ec70b098a00746108e10ab39e966607d78c84ae Merged-In: I5ec70b098a00746108e10ab39e966607d78c84ae (cherry picked from commit a8ac7cf706be7a77589070ea7c62f8e1b94ce316) --- audio/2.0/default/StreamIn.cpp | 8 ++++---- audio/2.0/default/StreamOut.cpp | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/audio/2.0/default/StreamIn.cpp b/audio/2.0/default/StreamIn.cpp index 9c933a9201..fea9156f62 100644 --- a/audio/2.0/default/StreamIn.cpp +++ b/audio/2.0/default/StreamIn.cpp @@ -378,9 +378,9 @@ Return StreamIn::prepareForReading(uint32_t frameSize, } // Create and launch the thread. - auto tempReadThread = std::make_unique( - &mStopReadThread, mStream, tempCommandMQ.get(), tempDataMQ.get(), - tempStatusMQ.get(), tempElfGroup.get()); + sp tempReadThread = + new ReadThread(&mStopReadThread, mStream, tempCommandMQ.get(), tempDataMQ.get(), + tempStatusMQ.get(), tempElfGroup.get()); if (!tempReadThread->init()) { ALOGW("failed to start reader thread: %s", strerror(-status)); sendError(Result::INVALID_ARGUMENTS); @@ -396,7 +396,7 @@ Return StreamIn::prepareForReading(uint32_t frameSize, mCommandMQ = std::move(tempCommandMQ); mDataMQ = std::move(tempDataMQ); mStatusMQ = std::move(tempStatusMQ); - mReadThread = tempReadThread.release(); + mReadThread = tempReadThread; mEfGroup = tempElfGroup.release(); threadInfo.pid = getpid(); threadInfo.tid = mReadThread->getTid(); diff --git a/audio/2.0/default/StreamOut.cpp b/audio/2.0/default/StreamOut.cpp index 22dcd0c994..b9eaea8268 100644 --- a/audio/2.0/default/StreamOut.cpp +++ b/audio/2.0/default/StreamOut.cpp @@ -353,9 +353,9 @@ Return StreamOut::prepareForWriting(uint32_t frameSize, } // Create and launch the thread. - auto tempWriteThread = std::make_unique( - &mStopWriteThread, mStream, tempCommandMQ.get(), tempDataMQ.get(), - tempStatusMQ.get(), tempElfGroup.get()); + sp tempWriteThread = + new WriteThread(&mStopWriteThread, mStream, tempCommandMQ.get(), tempDataMQ.get(), + tempStatusMQ.get(), tempElfGroup.get()); if (!tempWriteThread->init()) { ALOGW("failed to start writer thread: %s", strerror(-status)); sendError(Result::INVALID_ARGUMENTS); @@ -371,7 +371,7 @@ Return StreamOut::prepareForWriting(uint32_t frameSize, mCommandMQ = std::move(tempCommandMQ); mDataMQ = std::move(tempDataMQ); mStatusMQ = std::move(tempStatusMQ); - mWriteThread = tempWriteThread.release(); + mWriteThread = tempWriteThread; mEfGroup = tempElfGroup.release(); threadInfo.pid = getpid(); threadInfo.tid = mWriteThread->getTid(); -- GitLab From 31d8bc6e4214156212d7c29238a41c9077130f95 Mon Sep 17 00:00:00 2001 From: Jack Yu Date: Fri, 16 Apr 2021 21:00:36 +0000 Subject: [PATCH 617/790] Revert "[ANAPIC Review] Modify radio 1.6 based on ANAPIC comment" Revert "[ANAPIC Review] Change the type of List by ANAPIC review" Revert "[ANAPIC Review] Modify radio 1.6 based on ANAPIC comment..." Revert "[ANAPIC Review] Modify radio 1.6 in telephony side" Revert submission 14098561-ANAPIC_1_6 Reason for revert: broke the builds Reverted Changes: Ibcbdc0cac:[ANAPIC Review] Change the type of List by ANAPIC ... Ie8d40439e:[ANAPIC Review] Modify radio 1.6 in telephony side... I24106cba4:[ANAPIC Review] Modify radio 1.6 based on ANAPIC c... I71b0d0014:[ANAPIC Review] Modify radio 1.6 based on ANAPIC c... Change-Id: I47274308a2e453ebf666aff160a8fa0c02fdc3fb --- radio/1.6/IRadio.hal | 9 +-- radio/1.6/IRadioResponse.hal | 2 +- radio/1.6/types.hal | 61 ++++++++++--------- .../1.6/vts/functional/radio_hidl_hal_api.cpp | 8 +-- .../functional/radio_hidl_hal_utils_v1_6.h | 2 +- radio/1.6/vts/functional/radio_response.cpp | 2 +- 6 files changed, 44 insertions(+), 40 deletions(-) diff --git a/radio/1.6/IRadio.hal b/radio/1.6/IRadio.hal index e2d35d059d..a4e8811993 100644 --- a/radio/1.6/IRadio.hal +++ b/radio/1.6/IRadio.hal @@ -145,6 +145,7 @@ interface IRadio extends @1.5::IRadio { * * Response function is IRadioResponse.setupDataCallResponse_1_6() * + * Note this API is the same as the 1.5 */ oneway setupDataCall_1_6(int32_t serial, AccessNetwork accessNetwork, DataProfileInfo dataProfileInfo, bool roamingAllowed, @@ -176,7 +177,7 @@ interface IRadio extends @1.5::IRadio { * @param serial Serial number of request. * @param message GsmSmsMessage as defined in types.hal * - * Response function is IRadioResponse.sendSmsExpectMoreResponse_1_6() + * Response function is IRadioResponse.sendSMSExpectMoreResponse_1_6() * * Note this API is the same as the 1.0 * @@ -184,7 +185,7 @@ interface IRadio extends @1.5::IRadio { * fails. RadioError:SMS_SEND_FAIL_RETRY means retry (i.e. error cause is 332) * and RadioError:GENERIC_FAILURE means no retry (i.e. error cause is 500) */ - oneway sendSmsExpectMore_1_6(int32_t serial, GsmSmsMessage message); + oneway sendSMSExpectMore_1_6(int32_t serial, GsmSmsMessage message); /** * Send a CDMA SMS message @@ -266,7 +267,7 @@ interface IRadio extends @1.5::IRadio { * 2. Disable NR dual connectivity {NrDualConnectivityState:DISABLE} * 3. Disable NR dual connectivity and force secondary cell to be released * {NrDualConnectivityState:DISABLE_IMMEDIATE} - * + * Response callback is IRadioResponse.setNRDualConnectivityStateResponse() */ oneway setNrDualConnectivityState(int32_t serial, @@ -371,7 +372,7 @@ interface IRadio extends @1.5::IRadio { * * Response callback is IRadioResponse.getAllowedNetworkTypesBitmapResponse() */ - oneway getAllowedNetworkTypesBitmap(int32_t serial); + oneway getAllowedNetworkTypesBitmap(uint32_t serial); /** * Control data throttling at modem. diff --git a/radio/1.6/IRadioResponse.hal b/radio/1.6/IRadioResponse.hal index d8614f7d65..33fe94fa4a 100644 --- a/radio/1.6/IRadioResponse.hal +++ b/radio/1.6/IRadioResponse.hal @@ -139,7 +139,7 @@ interface IRadioResponse extends @1.5::IRadioResponse { * RadioError:ACCESS_BARRED * RadioError:BLOCKED_DUE_TO_CALL */ - oneway sendSmsExpectMoreResponse_1_6(RadioResponseInfo info, SendSmsResult sms); + oneway sendSMSExpectMoreResponse_1_6(RadioResponseInfo info, SendSmsResult sms); /** * @param info Response info struct containing response type, serial no. and error diff --git a/radio/1.6/types.hal b/radio/1.6/types.hal index d843fd8676..3fd31cc7da 100644 --- a/radio/1.6/types.hal +++ b/radio/1.6/types.hal @@ -55,9 +55,9 @@ import android.hidl.safe_union@1.0::Monostate; struct QosBandwidth { /** Maximum bit rate possible on the bearer */ - uint32_t maxBitrateKbps; + int32_t maxBitrateKbps; /** Minimum bit rate that is guaranteed to be provided by the network */ - uint32_t guaranteedBitrateKbps; + int32_t guaranteedBitrateKbps; }; /** LTE/EPS Quality of Service parameters as per 3gpp spec 24.301 sec 9.9.4.3. */ @@ -106,7 +106,7 @@ safe_union Qos { /** * Next header protocol numbers defined by IANA, RFC 5237 */ -enum QosProtocol : int8_t { +enum QosProtocol : int32_t { /** No protocol specified */ UNSPECIFIED = -1, /** Transmission Control Protocol */ @@ -119,14 +119,14 @@ enum QosProtocol : int8_t { AH = 51, }; -enum QosFilterDirection : int8_t { +enum QosFilterDirection : int32_t { DOWNLINK = 0, UPLINK = 1, BIDIRECTIONAL = 2, }; /** Allowed port numbers */ -enum QosPortRange : uint16_t { +enum QosPortRange : int32_t { MIN = 20, MAX = 65535 }; @@ -248,7 +248,7 @@ struct QosSession { }; /** The allowed failure modes on an IWLAN handover failure. */ -enum HandoverFailureMode : int8_t { +enum HandoverFailureMode : int32_t { /** * On data handover failure, fallback to the source data transport when the * fail cause is due to a hand off preference change. @@ -379,7 +379,7 @@ struct SetupDataCallResult { /** * NR Dual connectivity state */ -enum NrDualConnectivityState: int8_t { +enum NrDualConnectivityState: int32_t { /** * Enable NR dual connectivity. Enabled state does not mean dual connectivity * is active. It means device is allowed to connect to both primary and secondary. @@ -443,7 +443,7 @@ struct LinkCapacityEstimate { uint32_t secondaryUplinkCapacityKbps; }; -enum DataThrottlingAction : int8_t { +enum DataThrottlingAction : int32_t { /* Clear all existing data throttling. */ NO_DATA_THROTTLING = 0, @@ -581,9 +581,9 @@ struct NrSignalStrength { * * Reference: 3GPP TS 138.214 section 5.2.2.1. * - * Range [0, 15], 0xFF means invalid/unreported. + * Range [0, 15], INT_MAX means invalid/unreported. */ - vec csiCqiReport; + vec csiCqiReport; }; /** @@ -740,19 +740,22 @@ struct RegStateResult { EutranRegistrationInfo eutranInfo; - /** - * Network capabilities for voice over PS services. This info is valid only on NR - * network and must be present when the device is camped on NR. VopsInfo must be - * empty when the device is not camped on NR. - */ - NrVopsInfo ngranNrVopsInfo; - - /** - * True if the dual transfer mode is supported. - * Refer to 3GPP TS 44.108 section 3.4.25.3 - */ - bool geranDtmSupported; - + struct NgranRegistrationInfo { + /** + * Network capabilities for voice over PS services. This info is valid only on NR + * network and must be present when the device is camped on NR. VopsInfo must be + * empty when the device is not camped on NR. + */ + NrVopsInfo nrVopsInfo; + } ngranInfo; + + struct GeranRegistrationInfo { + /** + * True if the dual transfer mode is supported. + * Refer to 3GPP TS 44.108 section 3.4.25.3 + */ + bool dtmSupported; + } geranInfo; } accessTechnologySpecificInfo; }; @@ -871,10 +874,10 @@ struct PhysicalChannelConfig { int32_t uplinkChannelNumber; /** Downlink cell bandwidth, in kHz */ - int32_t cellBandwidthDownlinkKhz; + int32_t cellBandwidthDownlink; /** Uplink cell bandwidth, in kHz */ - int32_t cellBandwidthUplinkKhz; + int32_t cellBandwidthUplink; /** * A list of data calls mapped to this physical channel. The context id must match the cid of @@ -1056,7 +1059,7 @@ safe_union OptionalSscMode { SscMode value; }; -enum SliceStatus : int8_t { +enum SliceStatus : int32_t { UNKNOWN, CONFIGURED, // Configured but not allowed or rejected yet ALLOWED, // Allowed to be used @@ -1069,7 +1072,7 @@ enum SliceStatus : int8_t { * Enum representing session and service continuity mode as defined in * 3GPP TS 23.501. */ -enum SscMode : int8_t { +enum SscMode : int32_t { MODE_1 = 1, MODE_2 = 2, MODE_3 = 3, @@ -1078,7 +1081,7 @@ enum SscMode : int8_t { /** * Public key type from carrier certificate. */ -enum PublicKeyType : int8_t { +enum PublicKeyType : int32_t { EPDG = 1, // Key type to be used for ePDG WLAN = 2, // Key type to be used for WLAN }; @@ -1187,7 +1190,7 @@ struct PhonebookCapacity { * chunk of phonebook data, means this is a last indication with the left * data. */ -enum PbReceivedStatus : int8_t { +enum PbReceivedStatus : int32_t { PB_RECEIVED_OK = 1, PB_RECEIVED_ERROR = 2, PB_RECEIVED_ABORT = 3, diff --git a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp index be2be76913..6cf4567782 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp +++ b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp @@ -213,10 +213,10 @@ TEST_P(RadioHidlTest_v1_6, sendSms_1_6) { } /* - * Test IRadio_1_6.sendSmsExpectMore() for the response returned. + * Test IRadio_1_6.sendSMSExpectMore() for the response returned. */ -TEST_P(RadioHidlTest_v1_6, sendSmsExpectMore_1_6) { - LOG(DEBUG) << "sendSmsExpectMore"; +TEST_P(RadioHidlTest_v1_6, sendSMSExpectMore_1_6) { + LOG(DEBUG) << "sendSMSExpectMore"; serial = GetRandomSerialNumber(); GsmSmsMessage msg; msg.smscPdu = ""; @@ -236,7 +236,7 @@ TEST_P(RadioHidlTest_v1_6, sendSmsExpectMore_1_6) { ::android::hardware::radio::V1_6::RadioError::SIM_ABSENT}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "sendSmsExpectMore finished"; + LOG(DEBUG) << "sendSMSExpectMore finished"; } /* diff --git a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h index 0689e9b52b..4fc17e54d0 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h +++ b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h @@ -762,7 +762,7 @@ class RadioResponse_v1_6 : public ::android::hardware::radio::V1_6::IRadioRespon const ::android::hardware::radio::V1_6::RadioResponseInfo& info, const SendSmsResult& sms); - Return sendSmsExpectMoreResponse_1_6( + Return sendSMSExpectMoreResponse_1_6( const ::android::hardware::radio::V1_6::RadioResponseInfo& info, const SendSmsResult& sms); diff --git a/radio/1.6/vts/functional/radio_response.cpp b/radio/1.6/vts/functional/radio_response.cpp index 942964bd8c..2b6d1bb57e 100644 --- a/radio/1.6/vts/functional/radio_response.cpp +++ b/radio/1.6/vts/functional/radio_response.cpp @@ -1090,7 +1090,7 @@ Return RadioResponse_v1_6::sendSmsResponse_1_6( return Void(); } -Return RadioResponse_v1_6::sendSmsExpectMoreResponse_1_6( +Return RadioResponse_v1_6::sendSMSExpectMoreResponse_1_6( const ::android::hardware::radio::V1_6::RadioResponseInfo& info, const SendSmsResult& sms) { rspInfo = info; -- GitLab From c181c27916fbc1ff7176bd763981ffeede9e3a01 Mon Sep 17 00:00:00 2001 From: Zoey Chen Date: Tue, 6 Apr 2021 23:23:55 +0800 Subject: [PATCH 618/790] [ANAPIC Review] Modify radio 1.6 based on ANAPIC comment - setupDataCall_1_6, remove "same as 1.5" comment - sendSMSExpectMore to sendSmsExpectMore - getAllowedNetworkTypesBitmap should use int32_t - csiCqiReport uses uint8_t - cellBandwidthDownlinkKhz and cellBandwidthUplinkKhz - AccessTechnologySpecificInfo, remove these struct NgranRegistrationInfo and GeranRegistrationInfo Bug: 183738486 Test: make Change-Id: Icae28d68831bbd01836b8d464e8ece134a9aa63d --- radio/1.6/IRadio.hal | 9 ++- radio/1.6/IRadioResponse.hal | 2 +- radio/1.6/types.hal | 61 +++++++++---------- .../1.6/vts/functional/radio_hidl_hal_api.cpp | 8 +-- .../functional/radio_hidl_hal_utils_v1_6.h | 2 +- radio/1.6/vts/functional/radio_response.cpp | 2 +- 6 files changed, 40 insertions(+), 44 deletions(-) diff --git a/radio/1.6/IRadio.hal b/radio/1.6/IRadio.hal index a4e8811993..e2d35d059d 100644 --- a/radio/1.6/IRadio.hal +++ b/radio/1.6/IRadio.hal @@ -145,7 +145,6 @@ interface IRadio extends @1.5::IRadio { * * Response function is IRadioResponse.setupDataCallResponse_1_6() * - * Note this API is the same as the 1.5 */ oneway setupDataCall_1_6(int32_t serial, AccessNetwork accessNetwork, DataProfileInfo dataProfileInfo, bool roamingAllowed, @@ -177,7 +176,7 @@ interface IRadio extends @1.5::IRadio { * @param serial Serial number of request. * @param message GsmSmsMessage as defined in types.hal * - * Response function is IRadioResponse.sendSMSExpectMoreResponse_1_6() + * Response function is IRadioResponse.sendSmsExpectMoreResponse_1_6() * * Note this API is the same as the 1.0 * @@ -185,7 +184,7 @@ interface IRadio extends @1.5::IRadio { * fails. RadioError:SMS_SEND_FAIL_RETRY means retry (i.e. error cause is 332) * and RadioError:GENERIC_FAILURE means no retry (i.e. error cause is 500) */ - oneway sendSMSExpectMore_1_6(int32_t serial, GsmSmsMessage message); + oneway sendSmsExpectMore_1_6(int32_t serial, GsmSmsMessage message); /** * Send a CDMA SMS message @@ -267,7 +266,7 @@ interface IRadio extends @1.5::IRadio { * 2. Disable NR dual connectivity {NrDualConnectivityState:DISABLE} * 3. Disable NR dual connectivity and force secondary cell to be released * {NrDualConnectivityState:DISABLE_IMMEDIATE} - + * * Response callback is IRadioResponse.setNRDualConnectivityStateResponse() */ oneway setNrDualConnectivityState(int32_t serial, @@ -372,7 +371,7 @@ interface IRadio extends @1.5::IRadio { * * Response callback is IRadioResponse.getAllowedNetworkTypesBitmapResponse() */ - oneway getAllowedNetworkTypesBitmap(uint32_t serial); + oneway getAllowedNetworkTypesBitmap(int32_t serial); /** * Control data throttling at modem. diff --git a/radio/1.6/IRadioResponse.hal b/radio/1.6/IRadioResponse.hal index 33fe94fa4a..d8614f7d65 100644 --- a/radio/1.6/IRadioResponse.hal +++ b/radio/1.6/IRadioResponse.hal @@ -139,7 +139,7 @@ interface IRadioResponse extends @1.5::IRadioResponse { * RadioError:ACCESS_BARRED * RadioError:BLOCKED_DUE_TO_CALL */ - oneway sendSMSExpectMoreResponse_1_6(RadioResponseInfo info, SendSmsResult sms); + oneway sendSmsExpectMoreResponse_1_6(RadioResponseInfo info, SendSmsResult sms); /** * @param info Response info struct containing response type, serial no. and error diff --git a/radio/1.6/types.hal b/radio/1.6/types.hal index 3fd31cc7da..d843fd8676 100644 --- a/radio/1.6/types.hal +++ b/radio/1.6/types.hal @@ -55,9 +55,9 @@ import android.hidl.safe_union@1.0::Monostate; struct QosBandwidth { /** Maximum bit rate possible on the bearer */ - int32_t maxBitrateKbps; + uint32_t maxBitrateKbps; /** Minimum bit rate that is guaranteed to be provided by the network */ - int32_t guaranteedBitrateKbps; + uint32_t guaranteedBitrateKbps; }; /** LTE/EPS Quality of Service parameters as per 3gpp spec 24.301 sec 9.9.4.3. */ @@ -106,7 +106,7 @@ safe_union Qos { /** * Next header protocol numbers defined by IANA, RFC 5237 */ -enum QosProtocol : int32_t { +enum QosProtocol : int8_t { /** No protocol specified */ UNSPECIFIED = -1, /** Transmission Control Protocol */ @@ -119,14 +119,14 @@ enum QosProtocol : int32_t { AH = 51, }; -enum QosFilterDirection : int32_t { +enum QosFilterDirection : int8_t { DOWNLINK = 0, UPLINK = 1, BIDIRECTIONAL = 2, }; /** Allowed port numbers */ -enum QosPortRange : int32_t { +enum QosPortRange : uint16_t { MIN = 20, MAX = 65535 }; @@ -248,7 +248,7 @@ struct QosSession { }; /** The allowed failure modes on an IWLAN handover failure. */ -enum HandoverFailureMode : int32_t { +enum HandoverFailureMode : int8_t { /** * On data handover failure, fallback to the source data transport when the * fail cause is due to a hand off preference change. @@ -379,7 +379,7 @@ struct SetupDataCallResult { /** * NR Dual connectivity state */ -enum NrDualConnectivityState: int32_t { +enum NrDualConnectivityState: int8_t { /** * Enable NR dual connectivity. Enabled state does not mean dual connectivity * is active. It means device is allowed to connect to both primary and secondary. @@ -443,7 +443,7 @@ struct LinkCapacityEstimate { uint32_t secondaryUplinkCapacityKbps; }; -enum DataThrottlingAction : int32_t { +enum DataThrottlingAction : int8_t { /* Clear all existing data throttling. */ NO_DATA_THROTTLING = 0, @@ -581,9 +581,9 @@ struct NrSignalStrength { * * Reference: 3GPP TS 138.214 section 5.2.2.1. * - * Range [0, 15], INT_MAX means invalid/unreported. + * Range [0, 15], 0xFF means invalid/unreported. */ - vec csiCqiReport; + vec csiCqiReport; }; /** @@ -740,22 +740,19 @@ struct RegStateResult { EutranRegistrationInfo eutranInfo; - struct NgranRegistrationInfo { - /** - * Network capabilities for voice over PS services. This info is valid only on NR - * network and must be present when the device is camped on NR. VopsInfo must be - * empty when the device is not camped on NR. - */ - NrVopsInfo nrVopsInfo; - } ngranInfo; - - struct GeranRegistrationInfo { - /** - * True if the dual transfer mode is supported. - * Refer to 3GPP TS 44.108 section 3.4.25.3 - */ - bool dtmSupported; - } geranInfo; + /** + * Network capabilities for voice over PS services. This info is valid only on NR + * network and must be present when the device is camped on NR. VopsInfo must be + * empty when the device is not camped on NR. + */ + NrVopsInfo ngranNrVopsInfo; + + /** + * True if the dual transfer mode is supported. + * Refer to 3GPP TS 44.108 section 3.4.25.3 + */ + bool geranDtmSupported; + } accessTechnologySpecificInfo; }; @@ -874,10 +871,10 @@ struct PhysicalChannelConfig { int32_t uplinkChannelNumber; /** Downlink cell bandwidth, in kHz */ - int32_t cellBandwidthDownlink; + int32_t cellBandwidthDownlinkKhz; /** Uplink cell bandwidth, in kHz */ - int32_t cellBandwidthUplink; + int32_t cellBandwidthUplinkKhz; /** * A list of data calls mapped to this physical channel. The context id must match the cid of @@ -1059,7 +1056,7 @@ safe_union OptionalSscMode { SscMode value; }; -enum SliceStatus : int32_t { +enum SliceStatus : int8_t { UNKNOWN, CONFIGURED, // Configured but not allowed or rejected yet ALLOWED, // Allowed to be used @@ -1072,7 +1069,7 @@ enum SliceStatus : int32_t { * Enum representing session and service continuity mode as defined in * 3GPP TS 23.501. */ -enum SscMode : int32_t { +enum SscMode : int8_t { MODE_1 = 1, MODE_2 = 2, MODE_3 = 3, @@ -1081,7 +1078,7 @@ enum SscMode : int32_t { /** * Public key type from carrier certificate. */ -enum PublicKeyType : int32_t { +enum PublicKeyType : int8_t { EPDG = 1, // Key type to be used for ePDG WLAN = 2, // Key type to be used for WLAN }; @@ -1190,7 +1187,7 @@ struct PhonebookCapacity { * chunk of phonebook data, means this is a last indication with the left * data. */ -enum PbReceivedStatus : int32_t { +enum PbReceivedStatus : int8_t { PB_RECEIVED_OK = 1, PB_RECEIVED_ERROR = 2, PB_RECEIVED_ABORT = 3, diff --git a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp index 6cf4567782..be2be76913 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp +++ b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp @@ -213,10 +213,10 @@ TEST_P(RadioHidlTest_v1_6, sendSms_1_6) { } /* - * Test IRadio_1_6.sendSMSExpectMore() for the response returned. + * Test IRadio_1_6.sendSmsExpectMore() for the response returned. */ -TEST_P(RadioHidlTest_v1_6, sendSMSExpectMore_1_6) { - LOG(DEBUG) << "sendSMSExpectMore"; +TEST_P(RadioHidlTest_v1_6, sendSmsExpectMore_1_6) { + LOG(DEBUG) << "sendSmsExpectMore"; serial = GetRandomSerialNumber(); GsmSmsMessage msg; msg.smscPdu = ""; @@ -236,7 +236,7 @@ TEST_P(RadioHidlTest_v1_6, sendSMSExpectMore_1_6) { ::android::hardware::radio::V1_6::RadioError::SIM_ABSENT}, CHECK_GENERAL_ERROR)); } - LOG(DEBUG) << "sendSMSExpectMore finished"; + LOG(DEBUG) << "sendSmsExpectMore finished"; } /* diff --git a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h index 4fc17e54d0..0689e9b52b 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h +++ b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h @@ -762,7 +762,7 @@ class RadioResponse_v1_6 : public ::android::hardware::radio::V1_6::IRadioRespon const ::android::hardware::radio::V1_6::RadioResponseInfo& info, const SendSmsResult& sms); - Return sendSMSExpectMoreResponse_1_6( + Return sendSmsExpectMoreResponse_1_6( const ::android::hardware::radio::V1_6::RadioResponseInfo& info, const SendSmsResult& sms); diff --git a/radio/1.6/vts/functional/radio_response.cpp b/radio/1.6/vts/functional/radio_response.cpp index 2b6d1bb57e..942964bd8c 100644 --- a/radio/1.6/vts/functional/radio_response.cpp +++ b/radio/1.6/vts/functional/radio_response.cpp @@ -1090,7 +1090,7 @@ Return RadioResponse_v1_6::sendSmsResponse_1_6( return Void(); } -Return RadioResponse_v1_6::sendSMSExpectMoreResponse_1_6( +Return RadioResponse_v1_6::sendSmsExpectMoreResponse_1_6( const ::android::hardware::radio::V1_6::RadioResponseInfo& info, const SendSmsResult& sms) { rspInfo = info; -- GitLab From 300b3245aed811ec6ac02b56e20a4ca09c3c3fda Mon Sep 17 00:00:00 2001 From: Lev Proleev Date: Wed, 14 Apr 2021 20:54:27 +0100 Subject: [PATCH 619/790] Add units to hal times and durations names The change adds "Ns" suffix to timeOnDevice, timeInDriver, loopTimeoutDuration, deadline and duration. Fix: 183118329 Test: mm Change-Id: Id1f9ee4b8e41873c97690bb19a5e84572dd9ccf1 --- .../hardware/neuralnetworks/IBurst.aidl | 2 +- .../hardware/neuralnetworks/IDevice.aidl | 4 +- .../neuralnetworks/IPreparedModel.aidl | 4 +- .../hardware/neuralnetworks/Timing.aidl | 4 +- .../hardware/neuralnetworks/IBurst.aidl | 26 ++++---- .../hardware/neuralnetworks/IDevice.aidl | 24 +++---- .../neuralnetworks/IPreparedModel.aidl | 63 ++++++++++--------- .../hardware/neuralnetworks/Timing.aidl | 4 +- neuralnetworks/aidl/utils/src/Conversions.cpp | 16 ++--- .../aidl/utils/test/PreparedModelTest.cpp | 2 +- .../vts/functional/GeneratedTestHarness.cpp | 16 ++--- .../vts/functional/QualityOfServiceTests.cpp | 22 +++---- neuralnetworks/aidl/vts/functional/Utils.h | 2 +- 13 files changed, 95 insertions(+), 94 deletions(-) diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IBurst.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IBurst.aidl index 634f39e670..eb3d0b004a 100644 --- a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IBurst.aidl +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IBurst.aidl @@ -34,6 +34,6 @@ 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 deadline, in long loopTimeoutDuration); + 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/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IDevice.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IDevice.aidl index b328b29eab..c9c67f2fcd 100644 --- a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IDevice.aidl +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IDevice.aidl @@ -41,8 +41,8 @@ interface IDevice { 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 deadline, in ParcelFileDescriptor[] modelCache, in ParcelFileDescriptor[] dataCache, in byte[] token, in android.hardware.neuralnetworks.IPreparedModelCallback callback); - void prepareModelFromCache(in long deadline, in ParcelFileDescriptor[] modelCache, in ParcelFileDescriptor[] dataCache, in byte[] token, in android.hardware.neuralnetworks.IPreparedModelCallback callback); + 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; 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 52882cd0ab..fccb5dc98e 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 @@ -34,8 +34,8 @@ package android.hardware.neuralnetworks; @VintfStability interface IPreparedModel { - android.hardware.neuralnetworks.ExecutionResult executeSynchronously(in android.hardware.neuralnetworks.Request request, in boolean measureTiming, in long deadline, in long loopTimeoutDuration); - android.hardware.neuralnetworks.FencedExecutionResult executeFenced(in android.hardware.neuralnetworks.Request request, in ParcelFileDescriptor[] waitFor, in boolean measureTiming, in long deadline, in long loopTimeoutDuration, in long duration); + 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/current/android/hardware/neuralnetworks/Timing.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/Timing.aidl index 9690e01db3..bcc83cfbee 100644 --- a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/Timing.aidl +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/Timing.aidl @@ -34,6 +34,6 @@ package android.hardware.neuralnetworks; @VintfStability parcelable Timing { - long timeOnDevice; - long timeInDriver; + long timeOnDeviceNs; + long timeInDriverNs; } diff --git a/neuralnetworks/aidl/android/hardware/neuralnetworks/IBurst.aidl b/neuralnetworks/aidl/android/hardware/neuralnetworks/IBurst.aidl index 85d2a03a48..decdc481f1 100644 --- a/neuralnetworks/aidl/android/hardware/neuralnetworks/IBurst.aidl +++ b/neuralnetworks/aidl/android/hardware/neuralnetworks/IBurst.aidl @@ -77,18 +77,18 @@ interface IBurst { * @param measure Specifies whether or not to measure duration of the execution. The duration * runs from the time the driver sees the call to the executeSynchronously * function to the time the driver returns from the function. - * @param deadline 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. - * @param loopTimeoutDuration 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 - * execution 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}. + * @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. + * @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 + * execution 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 ExecutionResult parcelable, containing the status of the execution, output shapes and * timing information. * @throws ServiceSpecificException with one of the following ErrorStatus values: @@ -100,7 +100,7 @@ interface IBurst { * - RESOURCE_EXHAUSTED_* if the task was aborted by the driver */ ExecutionResult executeSynchronously(in Request request, in long[] memoryIdentifierTokens, - in boolean measureTiming, in long deadline, in long loopTimeoutDuration); + in boolean measureTiming, in long deadlineNs, in long loopTimeoutDurationNs); /** * releaseMemoryResource is used by the client to signal to the service that a memory buffer diff --git a/neuralnetworks/aidl/android/hardware/neuralnetworks/IDevice.aidl b/neuralnetworks/aidl/android/hardware/neuralnetworks/IDevice.aidl index c5b4ab1b8f..72e26237f8 100644 --- a/neuralnetworks/aidl/android/hardware/neuralnetworks/IDevice.aidl +++ b/neuralnetworks/aidl/android/hardware/neuralnetworks/IDevice.aidl @@ -306,11 +306,11 @@ interface IDevice { * @param preference Indicates the intended execution behavior of a prepared model. * @param priority The priority of the prepared model relative to other prepared models owned by * the client. - * @param deadline The time by which the model is expected to be prepared. The time is measured - * in nanoseconds since boot (as from clock_gettime(CLOCK_BOOTTIME, &ts) - * or ::android::base::boot_clock). If the model cannot be prepared by the - * deadline, the preparation may be aborted. Passing -1 means the deadline is - * omitted. Other negative values are invalid. + * @param deadlineNs The time by which the model is expected to be prepared. The time is + * measured in nanoseconds since boot (as from clock_gettime(CLOCK_BOOTTIME, + * &ts) or ::android::base::boot_clock). If the model cannot be prepared by + * the deadline, the preparation may be aborted. Passing -1 means the deadline + * is omitted. Other negative values are invalid. * @param modelCache A vector of file descriptors for the security-sensitive cache. The length * of the vector must either be 0 indicating that caching information is not * provided, or match the numModelCache returned from @@ -344,7 +344,7 @@ interface IDevice { * - RESOURCE_EXHAUSTED_* if the task was aborted by the driver */ void prepareModel(in Model model, in ExecutionPreference preference, in Priority priority, - in long deadline, in ParcelFileDescriptor[] modelCache, + in long deadlineNs, in ParcelFileDescriptor[] modelCache, in ParcelFileDescriptor[] dataCache, in byte[] token, in IPreparedModelCallback callback); @@ -395,11 +395,11 @@ interface IDevice { * with a set of inputs to the model. Note that the same prepared model object may be used with * different shapes of inputs on different (possibly concurrent) executions. * - * @param deadline The time by which the model is expected to be prepared. The time is measured - * in nanoseconds since boot (as from clock_gettime(CLOCK_BOOTTIME, &ts) or - * ::android::base::boot_clock). If the model cannot be prepared by the - * deadline, the preparation may be aborted. Passing -1 means the deadline is - * omitted. Other negative values are invalid. + * @param deadlineNs The time by which the model is expected to be prepared. The time is + * measured in nanoseconds since boot (as from clock_gettime(CLOCK_BOOTTIME, + * &ts) or ::android::base::boot_clock). If the model cannot be prepared by + * the deadline, the preparation may be aborted. Passing -1 means the deadline + * is omitted. Other negative values are invalid. * @param modelCache A vector of file descriptors for the security-sensitive cache. The length * of the vector must match the numModelCache returned from * getNumberOfCacheFilesNeeded. The cache file descriptors will be provided in @@ -426,7 +426,7 @@ interface IDevice { * the deadline * - RESOURCE_EXHAUSTED_* if the task was aborted by the driver */ - void prepareModelFromCache(in long deadline, in ParcelFileDescriptor[] modelCache, + void prepareModelFromCache(in long deadlineNs, in ParcelFileDescriptor[] modelCache, in ParcelFileDescriptor[] dataCache, in byte[] token, in IPreparedModelCallback callback); } diff --git a/neuralnetworks/aidl/android/hardware/neuralnetworks/IPreparedModel.aidl b/neuralnetworks/aidl/android/hardware/neuralnetworks/IPreparedModel.aidl index bfab9067d1..956b626dd9 100644 --- a/neuralnetworks/aidl/android/hardware/neuralnetworks/IPreparedModel.aidl +++ b/neuralnetworks/aidl/android/hardware/neuralnetworks/IPreparedModel.aidl @@ -72,18 +72,18 @@ interface IPreparedModel { * @param measure Specifies whether or not to measure duration of the execution. The duration * runs from the time the driver sees the call to the executeSynchronously * function to the time the driver returns from the function. - * @param deadline 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 loopTimeoutDuration 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 - * execution 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}. + * @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 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 + * execution 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 ExecutionResult parcelable, containing the status of the execution, output shapes and * timing information. * @throws ServiceSpecificException with one of the following ErrorStatus values: @@ -95,7 +95,7 @@ interface IPreparedModel { * - RESOURCE_EXHAUSTED_* if the task was aborted by the driver */ ExecutionResult executeSynchronously(in Request request, in boolean measureTiming, - in long deadline, in long loopTimeoutDuration); + in long deadlineNs, in long loopTimeoutDurationNs); /** * Launch a fenced asynchronous execution on a prepared model. @@ -137,22 +137,23 @@ interface IPreparedModel { * @param waitFor A vector of sync fence file descriptors. Execution must not start until all * sync fences have been signaled. * @param measure Specifies whether or not to measure duration of the execution. - * @param deadline 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 loopTimeoutDuration 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 - * execution 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}. - * @param duration 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. + * @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 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 + * execution 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}. + * @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: @@ -165,8 +166,8 @@ interface IPreparedModel { * - RESOURCE_EXHAUSTED_* if the task was aborted by the driver */ FencedExecutionResult executeFenced(in Request request, in ParcelFileDescriptor[] waitFor, - in boolean measureTiming, in long deadline, in long loopTimeoutDuration, - in long duration); + in boolean measureTiming, in long deadlineNs, in long loopTimeoutDurationNs, + in long durationNs); /** * Configure a Burst object used to execute multiple inferences on a prepared model in rapid diff --git a/neuralnetworks/aidl/android/hardware/neuralnetworks/Timing.aidl b/neuralnetworks/aidl/android/hardware/neuralnetworks/Timing.aidl index 8130e08fce..5225096800 100644 --- a/neuralnetworks/aidl/android/hardware/neuralnetworks/Timing.aidl +++ b/neuralnetworks/aidl/android/hardware/neuralnetworks/Timing.aidl @@ -28,9 +28,9 @@ parcelable Timing { /** * Execution time on device (not driver, which runs on host processor). */ - long timeOnDevice; + long timeOnDeviceNs; /** * Execution time in driver (including time on device). */ - long timeInDriver; + long timeInDriverNs; } diff --git a/neuralnetworks/aidl/utils/src/Conversions.cpp b/neuralnetworks/aidl/utils/src/Conversions.cpp index 93ac51c233..4b263ee49d 100644 --- a/neuralnetworks/aidl/utils/src/Conversions.cpp +++ b/neuralnetworks/aidl/utils/src/Conversions.cpp @@ -410,11 +410,11 @@ GeneralResult unvalidatedConvert(const aidl_hal::Memory& memory) { } GeneralResult unvalidatedConvert(const aidl_hal::Timing& timing) { - if (timing.timeInDriver < -1) { - return NN_ERROR() << "Timing: timeInDriver must not be less than -1"; + if (timing.timeInDriverNs < -1) { + return NN_ERROR() << "Timing: timeInDriverNs must not be less than -1"; } - if (timing.timeOnDevice < -1) { - return NN_ERROR() << "Timing: timeOnDevice must not be less than -1"; + if (timing.timeOnDeviceNs < -1) { + return NN_ERROR() << "Timing: timeOnDeviceNs must not be less than -1"; } constexpr auto convertTiming = [](int64_t halTiming) -> OptionalDuration { if (halTiming == kNoTiming) { @@ -422,8 +422,8 @@ GeneralResult unvalidatedConvert(const aidl_hal::Timing& timing) { } return nn::Duration(static_cast(halTiming)); }; - return Timing{.timeOnDevice = convertTiming(timing.timeOnDevice), - .timeInDriver = convertTiming(timing.timeInDriver)}; + return Timing{.timeOnDevice = convertTiming(timing.timeOnDeviceNs), + .timeInDriver = convertTiming(timing.timeInDriverNs)}; } GeneralResult unvalidatedConvert(const std::vector& operandValues) { @@ -964,8 +964,8 @@ nn::GeneralResult unvalidatedConvert(const nn::Request::Memor nn::GeneralResult unvalidatedConvert(const nn::Timing& timing) { return Timing{ - .timeOnDevice = NN_TRY(unvalidatedConvert(timing.timeOnDevice)), - .timeInDriver = NN_TRY(unvalidatedConvert(timing.timeInDriver)), + .timeOnDeviceNs = NN_TRY(unvalidatedConvert(timing.timeOnDevice)), + .timeInDriverNs = NN_TRY(unvalidatedConvert(timing.timeInDriver)), }; } diff --git a/neuralnetworks/aidl/utils/test/PreparedModelTest.cpp b/neuralnetworks/aidl/utils/test/PreparedModelTest.cpp index 630a460cf5..ff98a7d947 100644 --- a/neuralnetworks/aidl/utils/test/PreparedModelTest.cpp +++ b/neuralnetworks/aidl/utils/test/PreparedModelTest.cpp @@ -39,7 +39,7 @@ using ::testing::InvokeWithoutArgs; using ::testing::SetArgPointee; const std::shared_ptr kInvalidPreparedModel; -constexpr auto kNoTiming = Timing{.timeOnDevice = -1, .timeInDriver = -1}; +constexpr auto kNoTiming = Timing{.timeOnDeviceNs = -1, .timeInDriverNs = -1}; constexpr auto makeStatusOk = [] { return ndk::ScopedAStatus::ok(); }; diff --git a/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp index 14404292c9..d3b041ddf7 100644 --- a/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp +++ b/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp @@ -547,7 +547,7 @@ void EvaluatePreparedModel(const std::shared_ptr& device, makeOutputInsufficientSize(kInsufficientOutputIndex, &request); } - int64_t loopTimeoutDuration = kOmittedTimeoutDuration; + int64_t loopTimeoutDurationNs = kOmittedTimeoutDuration; // OutputType::MISSED_DEADLINE is only used by // TestKind::INTINITE_LOOP_TIMEOUT tests to verify that an infinite loop is // aborted after a timeout. @@ -555,7 +555,7 @@ void EvaluatePreparedModel(const std::shared_ptr& device, // Override the default loop timeout duration with a small value to // speed up test execution. constexpr int64_t kMillisecond = 1'000'000; - loopTimeoutDuration = 1 * kMillisecond; + loopTimeoutDurationNs = 1 * kMillisecond; } ErrorStatus executionStatus; @@ -568,7 +568,7 @@ void EvaluatePreparedModel(const std::shared_ptr& device, ExecutionResult executionResult; // execute const auto ret = preparedModel->executeSynchronously(request, testConfig.measureTiming, - kNoDeadline, loopTimeoutDuration, + kNoDeadline, loopTimeoutDurationNs, &executionResult); ASSERT_TRUE(ret.isOk() || ret.getExceptionCode() == EX_SERVICE_SPECIFIC) << ret.getDescription(); @@ -608,7 +608,7 @@ void EvaluatePreparedModel(const std::shared_ptr& device, ExecutionResult executionResult; // execute ret = burst->executeSynchronously(request, slots, testConfig.measureTiming, kNoDeadline, - loopTimeoutDuration, &executionResult); + loopTimeoutDurationNs, &executionResult); ASSERT_TRUE(ret.isOk() || ret.getExceptionCode() == EX_SERVICE_SPECIFIC) << ret.getDescription(); if (ret.isOk()) { @@ -635,7 +635,7 @@ void EvaluatePreparedModel(const std::shared_ptr& device, ErrorStatus result = ErrorStatus::NONE; FencedExecutionResult executionResult; auto ret = preparedModel->executeFenced(request, {}, testConfig.measureTiming, - kNoDeadline, loopTimeoutDuration, kNoDuration, + kNoDeadline, loopTimeoutDurationNs, kNoDuration, &executionResult); ASSERT_TRUE(ret.isOk() || ret.getExceptionCode() == EX_SERVICE_SPECIFIC) << ret.getDescription(); @@ -649,7 +649,7 @@ void EvaluatePreparedModel(const std::shared_ptr& device, 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, loopTimeoutDuration, kNoDuration, + kNoDeadline, loopTimeoutDurationNs, kNoDuration, &executionResult); ASSERT_TRUE(ret.isOk()); waitForSyncFence(executionResult.syncFence.get()); @@ -686,8 +686,8 @@ void EvaluatePreparedModel(const std::shared_ptr& device, if (!testConfig.measureTiming) { EXPECT_EQ(timing, kNoTiming); } else { - if (timing.timeOnDevice != -1 && timing.timeInDriver != -1) { - EXPECT_LE(timing.timeOnDevice, timing.timeInDriver); + if (timing.timeOnDeviceNs != -1 && timing.timeInDriverNs != -1) { + EXPECT_LE(timing.timeOnDeviceNs, timing.timeInDriverNs); } } diff --git a/neuralnetworks/aidl/vts/functional/QualityOfServiceTests.cpp b/neuralnetworks/aidl/vts/functional/QualityOfServiceTests.cpp index e803e38092..bbba887e82 100644 --- a/neuralnetworks/aidl/vts/functional/QualityOfServiceTests.cpp +++ b/neuralnetworks/aidl/vts/functional/QualityOfServiceTests.cpp @@ -53,7 +53,7 @@ using MaybeResults = std::optional; using ExecutionFunction = std::function& preparedModel, - const Request& request, int64_t deadline)>; + const Request& request, int64_t deadlineNs)>; static int64_t makeDeadline(DeadlineBoundType deadlineBoundType) { const auto getNanosecondsSinceEpoch = [](const auto& time) -> int64_t { @@ -79,9 +79,9 @@ static int64_t makeDeadline(DeadlineBoundType deadlineBoundType) { void runPrepareModelTest(const std::shared_ptr& device, const Model& model, Priority priority, std::optional deadlineBound) { - int64_t deadline = kNoDeadline; + int64_t deadlineNs = kNoDeadline; if (deadlineBound.has_value()) { - deadline = makeDeadline(deadlineBound.value()); + deadlineNs = makeDeadline(deadlineBound.value()); } // see if service can handle model @@ -96,8 +96,8 @@ void runPrepareModelTest(const std::shared_ptr& device, const Model& mo const std::shared_ptr preparedModelCallback = ndk::SharedRefBase::make(); const auto prepareLaunchStatus = - device->prepareModel(model, ExecutionPreference::FAST_SINGLE_ANSWER, priority, deadline, - {}, {}, kEmptyCacheToken, preparedModelCallback); + device->prepareModel(model, ExecutionPreference::FAST_SINGLE_ANSWER, priority, + deadlineNs, {}, {}, kEmptyCacheToken, preparedModelCallback); ASSERT_TRUE(prepareLaunchStatus.isOk()) << "prepareLaunchStatus: " << prepareLaunchStatus.getDescription(); @@ -156,13 +156,13 @@ void runPrepareModelTests(const std::shared_ptr& device, const Model& m } static MaybeResults executeSynchronously(const std::shared_ptr& preparedModel, - const Request& request, int64_t deadline) { + const Request& request, int64_t deadlineNs) { SCOPED_TRACE("synchronous"); const bool measure = false; // run execution ExecutionResult executionResult; - const auto ret = preparedModel->executeSynchronously(request, measure, deadline, + const auto ret = preparedModel->executeSynchronously(request, measure, deadlineNs, kOmittedTimeoutDuration, &executionResult); EXPECT_TRUE(ret.isOk() || ret.getExceptionCode() == EX_SERVICE_SPECIFIC) << ret.getDescription(); @@ -182,7 +182,7 @@ static MaybeResults executeSynchronously(const std::shared_ptr& } static MaybeResults executeBurst(const std::shared_ptr& preparedModel, - const Request& request, int64_t deadline) { + const Request& request, int64_t deadlineNs) { SCOPED_TRACE("burst"); const bool measure = false; @@ -200,7 +200,7 @@ static MaybeResults executeBurst(const std::shared_ptr& prepared // run execution ExecutionResult executionResult; - ret = burst->executeSynchronously(request, slots, measure, deadline, kOmittedTimeoutDuration, + ret = burst->executeSynchronously(request, slots, measure, deadlineNs, kOmittedTimeoutDuration, &executionResult); EXPECT_TRUE(ret.isOk() || ret.getExceptionCode() == EX_SERVICE_SPECIFIC) << ret.getDescription(); @@ -224,10 +224,10 @@ void runExecutionTest(const std::shared_ptr& preparedModel, const ExecutionContext& context, bool synchronous, DeadlineBoundType deadlineBound) { const ExecutionFunction execute = synchronous ? executeSynchronously : executeBurst; - const auto deadline = makeDeadline(deadlineBound); + const auto deadlineNs = makeDeadline(deadlineBound); // Perform execution and unpack results. - const auto results = execute(preparedModel, request, deadline); + const auto results = execute(preparedModel, request, deadlineNs); if (!results.has_value()) return; const auto& [status, outputShapes, timing] = results.value(); diff --git a/neuralnetworks/aidl/vts/functional/Utils.h b/neuralnetworks/aidl/vts/functional/Utils.h index 266301ca97..77085a75ef 100644 --- a/neuralnetworks/aidl/vts/functional/Utils.h +++ b/neuralnetworks/aidl/vts/functional/Utils.h @@ -43,7 +43,7 @@ namespace nn = ::android::nn; inline constexpr Priority kDefaultPriority = Priority::MEDIUM; -inline constexpr Timing kNoTiming = {.timeOnDevice = -1, .timeInDriver = -1}; +inline constexpr Timing kNoTiming = {.timeOnDeviceNs = -1, .timeInDriverNs = -1}; inline constexpr int64_t kNoDeadline = -1; inline constexpr int64_t kOmittedTimeoutDuration = -1; inline constexpr int64_t kNoDuration = -1; -- GitLab From d4ac93a5140db94cbc01b32d06c2fbb74fd37542 Mon Sep 17 00:00:00 2001 From: Changyeon Jo Date: Mon, 19 Apr 2021 15:20:26 -0700 Subject: [PATCH 620/790] Update OWNERS Add Gary Sun to the owners of the EVS HAL interface Fix: 185830679 Test: N/A Change-Id: I732198ca3795d5d296d614b4f37a84110ab56f73 --- automotive/evs/OWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/automotive/evs/OWNERS b/automotive/evs/OWNERS index fec2a3ad33..6fc50248c7 100644 --- a/automotive/evs/OWNERS +++ b/automotive/evs/OWNERS @@ -1,3 +1,3 @@ changyeon@google.com +garysungang@google.com haoxiangl@google.com -swan@google.com -- GitLab From 38ec240f8f01e9a256c726269ef52e2ba8d330da Mon Sep 17 00:00:00 2001 From: Yuncheol Heo Date: Thu, 15 Apr 2021 15:25:39 -0700 Subject: [PATCH 621/790] Move the guard definition ENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING. - The target code is compiled with the libary, so move the definition to the libary. Bug: 181802283 Test: check if ClusterOSDouble gets the vendor messages. Change-Id: Id501be674844bda73ccf5ae74d97a363869db7b7 --- automotive/vehicle/2.0/default/Android.bp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/automotive/vehicle/2.0/default/Android.bp b/automotive/vehicle/2.0/default/Android.bp index d6f3120221..60b696d61b 100644 --- a/automotive/vehicle/2.0/default/Android.bp +++ b/automotive/vehicle/2.0/default/Android.bp @@ -78,6 +78,7 @@ cc_library_static { name: "android.hardware.automotive.vehicle@2.0-default-impl-lib", vendor: true, defaults: ["vhal_v2_0_target_defaults"], + cflags: ["-DENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING"], srcs: [ "impl/vhal_v2_0/CommConn.cpp", "impl/vhal_v2_0/EmulatedVehicleConnector.cpp", @@ -210,7 +211,6 @@ cc_binary { vendor: true, relative_install_path: "hw", srcs: ["VehicleService.cpp"], - cflags: ["-DENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING"], shared_libs: [ "libbase", "libjsoncpp", -- GitLab From 65becfa5689d5b626ff2409a9273f3886dd6c11a Mon Sep 17 00:00:00 2001 From: Yuncheol Heo Date: Mon, 19 Apr 2021 22:00:59 -0700 Subject: [PATCH 622/790] Change CLUSTER_DISPLAY_STATE message to be able to set the bounds. - Previously it can specify the size only, but we'll change the argument to set the rectangle area (to be able to set the starting position). Bug: 173454429 Test: it builds Change-Id: I15329983e1af4de82a474f5c3e803905f4742848 --- .../default/impl/vhal_v2_0/DefaultConfig.h | 4 +- automotive/vehicle/2.0/types.hal | 38 +++++++++++-------- 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h index 621c87df01..abf33a3f46 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h @@ -1260,7 +1260,7 @@ const ConfigDeclaration kVehicleProperties[]{ .prop = toInt(VehicleProperty::CLUSTER_REPORT_STATE), .access = VehiclePropertyAccess::WRITE, .changeMode = VehiclePropertyChangeMode::ON_CHANGE, - .configArray = {0, 0, 0, 9, 0, 0, 0, 0, 16}, + .configArray = {0, 0, 0, 11, 0, 0, 0, 0, 16}, }, }, { @@ -1303,7 +1303,7 @@ const ConfigDeclaration kVehicleProperties[]{ .prop = VENDOR_CLUSTER_REPORT_STATE, .access = VehiclePropertyAccess::READ, .changeMode = VehiclePropertyChangeMode::ON_CHANGE, - .configArray = {0, 0, 0, 9, 0, 0, 0, 0, 16}, + .configArray = {0, 0, 0, 11, 0, 0, 0, 0, 16}, }, }, { diff --git a/automotive/vehicle/2.0/types.hal b/automotive/vehicle/2.0/types.hal index 1f697ae677..e22f9fa5bd 100644 --- a/automotive/vehicle/2.0/types.hal +++ b/automotive/vehicle/2.0/types.hal @@ -3200,15 +3200,21 @@ enum VehicleProperty : int32_t { /** * Changes the state of the cluster display. * + * Bounds: the area to render the cluster Activity. + * Inset: the area which Activity should avoid from placing any important + * information. + * * int32[0]: on/off: 0 - off, 1 - on, -1 - don't care - * int32[1]: width: positive number - actual width in pixels - -1 - don't care (should set "don't care" both width and height) - * int32[2]: height: same format with 'width' - * int32[3]: Inset - left: positive number - actual left inset value in pixels + * int32[1]: Bounds - left: positive number - left position in pixels + -1 - don't care (should set all Bounds fields) + * int32[2]: Bounds - top: same format with 'left' + * int32[3]: Bounds - right: same format with 'left' + * int32[4]: Bounds - bottom: same format with 'left' + * int32[5]: Inset - left: positive number - actual left inset value in pixels -1 - don't care (should set "don't care" all Inset fields) - * int32[4]: Inset - top: same format with 'left' - * int32[5]: Inset - right: same format with 'left' - * int32[6]: Inset - bottom: same format with 'left' + * int32[6]: Inset - top: same format with 'left' + * int32[7]: Inset - right: same format with 'left' + * int32[8]: Inset - bottom: same format with 'left' * * @change_mode VehiclePropertyChangeMode:ON_CHANGE * @access VehiclePropertyAccess:READ @@ -3230,16 +3236,18 @@ enum VehicleProperty : int32_t { * match the state. * * int32[0]: on/off: 0 - off, 1 - on - * int32[1]: width - * int32[2]: height - * int32[3]: Inset - left - * int32[4]: Inset - top - * int32[5]: Inset - right - * int32[6]: Inset - bottom - * int32[7]: the type of ClusterUI in the fullscreen or main screen. + * int32[1]: Bounds - left + * int32[2]: Bounds - top + * int32[3]: Bounds - right + * int32[4]: Bounds - bottom + * int32[5]: Inset - left + * int32[6]: Inset - top + * int32[7]: Inset - right + * int32[8]: Inset - bottom + * int32[9]: the type of ClusterUI in the fullscreen or main screen. * 0 indicates ClusterHome. * the other values are followed by OEM's definition. - * int32[8]: the type of ClusterUI in sub screen if the currently two UIs are shown. + * int32[10]: the type of ClusterUI in sub screen if the currently two UIs are shown. * -1 indicates the area isn't used any more. * bytes: the array to represent the availability of ClusterUI. * 0 indicates non-available and 1 indicates available. -- GitLab From 0f2a75b4f85f25ff6a70dc24bd3a21ba253a5447 Mon Sep 17 00:00:00 2001 From: SongFerngWang Date: Wed, 21 Apr 2021 04:36:11 +0800 Subject: [PATCH 623/790] modemReducedFeatureSet add PhysicalChannelConfig_1_6 item Bug: 185925786 Test: build pass Change-Id: I7d0c1b2534f50bbb445e2929b2807da0835d6bfe --- radio/config/1.3/IRadioConfigResponse.hal | 2 ++ 1 file changed, 2 insertions(+) diff --git a/radio/config/1.3/IRadioConfigResponse.hal b/radio/config/1.3/IRadioConfigResponse.hal index 15eefed82c..f6aee3153a 100644 --- a/radio/config/1.3/IRadioConfigResponse.hal +++ b/radio/config/1.3/IRadioConfigResponse.hal @@ -37,6 +37,8 @@ interface IRadioConfigResponse extends @1.2::IRadioConfigResponse { * - Requesting android.hardware.radio@1.6::IRadio.setDataThrottling() * - Providing android.hardware.radio@1.6::SlicingConfig through * android.hardware.radio@1.6::getSlicingConfig() + * - Providing android.hardware.radio@1.6::PhysicalChannelConfig through + * android.hardware.radio@1.6::IRadioIndication.currentPhysicalChannelConfigs_1_6() * * Valid errors returned: * RadioError:NONE -- GitLab From 9072e5f0db8c2354d1e029ea960647c9f6322c66 Mon Sep 17 00:00:00 2001 From: Andy Hung Date: Tue, 20 Apr 2021 19:22:22 -0700 Subject: [PATCH 624/790] Audio: Add AUDIO_FORMAT_DRA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit China DTMB digital TV. See SJ/T11368-2006 “Specification for multichannel digital audio coding technology”. Test: atest AudioFormatTest Bug: 185950819 Change-Id: I941c4991e598e864babfb888a8827d1625d95990 --- audio/7.0/config/api/current.txt | 1 + audio/7.0/config/audio_policy_configuration.xsd | 1 + 2 files changed, 2 insertions(+) diff --git a/audio/7.0/config/api/current.txt b/audio/7.0/config/api/current.txt index 4a2ffdb4fd..3716cf0ea0 100644 --- a/audio/7.0/config/api/current.txt +++ b/audio/7.0/config/api/current.txt @@ -210,6 +210,7 @@ package android.audio.policy.configuration.V7_0 { enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_CELT; enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DEFAULT; enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DOLBY_TRUEHD; + enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DRA; enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DSD; enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DTS; enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DTS_HD; diff --git a/audio/7.0/config/audio_policy_configuration.xsd b/audio/7.0/config/audio_policy_configuration.xsd index 349b9d01d9..7f7fb61f4d 100644 --- a/audio/7.0/config/audio_policy_configuration.xsd +++ b/audio/7.0/config/audio_policy_configuration.xsd @@ -415,6 +415,7 @@ + -- GitLab From 8e485cc67eb40c9a197ae735a459da068914069a Mon Sep 17 00:00:00 2001 From: Grace Jia Date: Tue, 20 Apr 2021 18:46:19 -0700 Subject: [PATCH 625/790] Fix QC vts test failure The test is a value-parameterized test, so use TEST_P instead of TEST_F to prevent compile error. Bug: 184609812 Test: vts test Change-Id: I8a54568e1f109f8d9c748584ab50b195001d8218 --- radio/1.6/vts/functional/radio_hidl_hal_api.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp index 36eee1090b..f09b74edaf 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp +++ b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp @@ -756,7 +756,7 @@ TEST_P(RadioHidlTest_v1_6, setCarrierInfoForImsiEncryption_1_6) { /* * Test IRadio.getSimPhonebookRecords() for the response returned. */ -TEST_F(RadioHidlTest_v1_6, getSimPhonebookRecords) { +TEST_P(RadioHidlTest_v1_6, getSimPhonebookRecords) { serial = GetRandomSerialNumber(); radio_v1_6->getSimPhonebookRecords(serial); EXPECT_EQ(std::cv_status::no_timeout, wait()); -- GitLab From bd7ea386c9e160cefff36cabba618c04978ea75f Mon Sep 17 00:00:00 2001 From: Ady Abraham Date: Tue, 13 Apr 2021 20:58:03 -0700 Subject: [PATCH 626/790] composer: update VtsDisplay dimensions When the active config changes, the display dimension might change as well, so we need to update it to match the active config. Test: run composer 2.4 VTS Bug: 185195256 Change-Id: Ie2671e61498d2501901885b2a9986ee1974bd641 --- .../VtsHalGraphicsComposerV2_4TargetTest.cpp | 54 ++++++++++++++----- 1 file changed, 42 insertions(+), 12 deletions(-) diff --git a/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp b/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp index 25c990bd55..0df2b8dd45 100644 --- a/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp +++ b/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp @@ -73,10 +73,15 @@ class VtsDisplay { IComposerClient::Rect getFrameRect() const { return {0, 0, mDisplayWidth, mDisplayHeight}; } + void setDimensions(int32_t displayWidth, int32_t displayHeight) const { + mDisplayWidth = displayWidth; + mDisplayHeight = displayHeight; + } + private: const Display mDisplay; - const int32_t mDisplayWidth; - const int32_t mDisplayHeight; + mutable int32_t mDisplayWidth; + mutable int32_t mDisplayHeight; }; class GraphicsComposerHidlTest : public ::testing::TestWithParam { @@ -194,6 +199,31 @@ class GraphicsComposerHidlTest : public ::testing::TestWithParam { const std::vector& capabilities, const ContentType& contentType, const char* contentTypeStr); + Error setActiveConfigWithConstraints( + const VtsDisplay& display, Config config, + const IComposerClient::VsyncPeriodChangeConstraints& constraints, + VsyncPeriodChangeTimeline* timeline) { + const auto error = mComposerClient->setActiveConfigWithConstraints(display.get(), config, + constraints, timeline); + if (error == Error::NONE) { + const int32_t displayWidth = mComposerClient->getDisplayAttribute_2_4( + display.get(), config, IComposerClient::Attribute::WIDTH); + const int32_t displayHeight = mComposerClient->getDisplayAttribute_2_4( + display.get(), config, IComposerClient::Attribute::HEIGHT); + display.setDimensions(displayWidth, displayHeight); + } + return error; + } + + void setActiveConfig(const VtsDisplay& display, Config config) { + mComposerClient->setActiveConfig(display.get(), config); + const int32_t displayWidth = mComposerClient->getDisplayAttribute_2_4( + display.get(), config, IComposerClient::Attribute::WIDTH); + const int32_t displayHeight = mComposerClient->getDisplayAttribute_2_4( + display.get(), config, IComposerClient::Attribute::HEIGHT); + display.setDimensions(displayWidth, displayHeight); + } + private: // use the slot count usually set by SF static constexpr uint32_t kBufferSlotCount = 64; @@ -358,8 +388,8 @@ TEST_P(GraphicsComposerHidlTest, getDisplayVsyncPeriod) { constraints.desiredTimeNanos = systemTime(); constraints.seamlessRequired = false; - EXPECT_EQ(Error::NONE, mComposerClient->setActiveConfigWithConstraints( - display.get(), config, constraints, &timeline)); + EXPECT_EQ(Error::NONE, + setActiveConfigWithConstraints(display, config, constraints, &timeline)); if (timeline.refreshRequired) { sendRefreshFrame(display, &timeline); @@ -414,8 +444,7 @@ TEST_P(GraphicsComposerHidlTest, setActiveConfigWithConstraints_BadConfig) { for (const auto& display : mDisplays) { Config invalidConfigId = GetInvalidConfigId(display.get()); EXPECT_EQ(Error::BAD_CONFIG, - mComposerClient->setActiveConfigWithConstraints(display.get(), invalidConfigId, - constraints, &timeline)); + setActiveConfigWithConstraints(display, invalidConfigId, constraints, &timeline)); } } @@ -435,11 +464,10 @@ TEST_P(GraphicsComposerHidlTest, setActiveConfigWithConstraints_SeamlessNotAllow display.get(), config2, IComposerClient::IComposerClient::Attribute::CONFIG_GROUP); if (configGroup1 != configGroup2) { - mComposerClient->setActiveConfig(display.get(), config1); + setActiveConfig(display, config1); sendRefreshFrame(display, nullptr); EXPECT_EQ(Error::SEAMLESS_NOT_ALLOWED, - mComposerClient->setActiveConfigWithConstraints(display.get(), config2, - constraints, &timeline)); + setActiveConfigWithConstraints(display, config2, constraints, &timeline)); } }); } @@ -505,6 +533,8 @@ void GraphicsComposerHidlTest::sendRefreshFrame(const VtsDisplay& display, mWriter->presentDisplay(); execute(); + + ASSERT_NO_FATAL_FAILURE(mComposerClient->destroyLayer(display.get(), layer)); } void GraphicsComposerHidlTest::waitForVsyncPeriodChange(Display display, @@ -528,7 +558,7 @@ void GraphicsComposerHidlTest::waitForVsyncPeriodChange(Display display, void GraphicsComposerHidlTest::Test_setActiveConfigWithConstraints(const TestParameters& params) { for (const auto& display : mDisplays) { forEachTwoConfigs(display.get(), [&](Config config1, Config config2) { - mComposerClient->setActiveConfig(display.get(), config1); + setActiveConfig(display, config1); sendRefreshFrame(display, nullptr); int32_t vsyncPeriod1 = mComposerClient->getDisplayAttribute_2_4( @@ -546,8 +576,8 @@ void GraphicsComposerHidlTest::Test_setActiveConfigWithConstraints(const TestPar IComposerClient::VsyncPeriodChangeConstraints constraints = { .desiredTimeNanos = systemTime() + params.delayForChange, .seamlessRequired = false}; - EXPECT_EQ(Error::NONE, mComposerClient->setActiveConfigWithConstraints( - display.get(), config2, constraints, &timeline)); + EXPECT_EQ(Error::NONE, + setActiveConfigWithConstraints(display, config2, constraints, &timeline)); EXPECT_TRUE(timeline.newVsyncAppliedTimeNanos >= constraints.desiredTimeNanos); // Refresh rate should change within a reasonable time -- GitLab From 929146ecff0476a2745eefaa930a08f1c2ee8d0c Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Thu, 22 Apr 2021 00:29:01 -0700 Subject: [PATCH 627/790] Add Session#getEnrollmentConfig and better enum defaults Bug: 183738533 Bug: 181358178 Test: atest VtsHalBiometricsFaceTargetTest Change-Id: I45a60d58b0d32b7449bb7a2b04cc469b79454bcb --- .../biometrics/face/AcquiredInfo.aidl | 53 +++++++-------- .../hardware/biometrics/face/BaseFrame.aidl | 2 +- .../biometrics/face/EnrollmentFrame.aidl | 2 +- .../biometrics/face/EnrollmentStage.aidl | 13 ++-- .../face/EnrollmentStageConfig.aidl | 2 +- .../hardware/biometrics/face/Error.aidl | 5 +- .../hardware/biometrics/face/ISession.aidl | 1 + .../hardware/biometrics/face/SensorProps.aidl | 2 +- .../biometrics/face/AcquiredInfo.aidl | 58 ++++++++-------- .../biometrics/face/AuthenticationFrame.aidl | 1 - .../hardware/biometrics/face/BaseFrame.aidl | 2 +- .../biometrics/face/EnrollmentFrame.aidl | 2 +- .../biometrics/face/EnrollmentStage.aidl | 66 ++++++++++--------- .../face/EnrollmentStageConfig.aidl | 2 +- .../hardware/biometrics/face/Error.aidl | 38 ++++------- .../hardware/biometrics/face/ISession.aidl | 7 +- .../hardware/biometrics/face/SensorProps.aidl | 2 +- biometrics/face/aidl/default/Session.cpp | 6 ++ biometrics/face/aidl/default/Session.h | 3 + 19 files changed, 139 insertions(+), 128 deletions(-) diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl index c19534c016..eaa43f3f9e 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl @@ -34,30 +34,31 @@ package android.hardware.biometrics.face; @Backing(type="byte") @VintfStability enum AcquiredInfo { - GOOD = 0, - INSUFFICIENT = 1, - TOO_BRIGHT = 2, - TOO_DARK = 3, - TOO_CLOSE = 4, - TOO_FAR = 5, - FACE_TOO_HIGH = 6, - FACE_TOO_LOW = 7, - FACE_TOO_RIGHT = 8, - FACE_TOO_LEFT = 9, - POOR_GAZE = 10, - NOT_DETECTED = 11, - TOO_MUCH_MOTION = 12, - RECALIBRATE = 13, - TOO_DIFFERENT = 14, - TOO_SIMILAR = 15, - PAN_TOO_EXTREME = 16, - TILT_TOO_EXTREME = 17, - ROLL_TOO_EXTREME = 18, - FACE_OBSCURED = 19, - START = 20, - SENSOR_DIRTY = 21, - VENDOR = 22, - FIRST_FRAME_RECEIVED = 23, - DARK_GLASSES_DETECTED = 24, - MOUTH_COVERING_DETECTED = 25, + UNKNOWN = 0, + GOOD = 1, + INSUFFICIENT = 2, + TOO_BRIGHT = 3, + TOO_DARK = 4, + TOO_CLOSE = 5, + TOO_FAR = 6, + FACE_TOO_HIGH = 7, + FACE_TOO_LOW = 8, + FACE_TOO_RIGHT = 9, + FACE_TOO_LEFT = 10, + POOR_GAZE = 11, + NOT_DETECTED = 12, + TOO_MUCH_MOTION = 13, + RECALIBRATE = 14, + TOO_DIFFERENT = 15, + TOO_SIMILAR = 16, + PAN_TOO_EXTREME = 17, + TILT_TOO_EXTREME = 18, + ROLL_TOO_EXTREME = 19, + FACE_OBSCURED = 20, + START = 21, + SENSOR_DIRTY = 22, + VENDOR = 23, + FIRST_FRAME_RECEIVED = 24, + DARK_GLASSES_DETECTED = 25, + MOUTH_COVERING_DETECTED = 26, } diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/BaseFrame.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/BaseFrame.aidl index aa51343281..67b5cf4169 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/BaseFrame.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/BaseFrame.aidl @@ -34,7 +34,7 @@ package android.hardware.biometrics.face; @VintfStability parcelable BaseFrame { - android.hardware.biometrics.face.AcquiredInfo acquiredInfo = android.hardware.biometrics.face.AcquiredInfo.INSUFFICIENT; + android.hardware.biometrics.face.AcquiredInfo acquiredInfo = android.hardware.biometrics.face.AcquiredInfo.UNKNOWN; int vendorCode; float pan; float tilt; diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentFrame.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentFrame.aidl index 982e759180..0ea10d6ddb 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentFrame.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentFrame.aidl @@ -35,6 +35,6 @@ package android.hardware.biometrics.face; @VintfStability parcelable EnrollmentFrame { @nullable android.hardware.biometrics.face.Cell cell; - android.hardware.biometrics.face.EnrollmentStage stage = android.hardware.biometrics.face.EnrollmentStage.FIRST_FRAME_RECEIVED; + android.hardware.biometrics.face.EnrollmentStage stage = android.hardware.biometrics.face.EnrollmentStage.UNKNOWN; android.hardware.biometrics.face.BaseFrame data; } diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStage.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStage.aidl index 6be6e0bbdd..ce5679ab31 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStage.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStage.aidl @@ -34,10 +34,11 @@ package android.hardware.biometrics.face; @Backing(type="byte") @VintfStability enum EnrollmentStage { - FIRST_FRAME_RECEIVED = 0, - WAITING_FOR_CENTERING = 1, - HOLD_STILL_IN_CENTER = 2, - ENROLLING_MOVEMENT_1 = 3, - ENROLLING_MOVEMENT_2 = 4, - ENROLLMENT_FINISHED = 5, + UNKNOWN = 0, + FIRST_FRAME_RECEIVED = 1, + WAITING_FOR_CENTERING = 2, + HOLD_STILL_IN_CENTER = 3, + ENROLLING_MOVEMENT_1 = 4, + ENROLLING_MOVEMENT_2 = 5, + ENROLLMENT_FINISHED = 6, } diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStageConfig.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStageConfig.aidl index 232bd52813..48db2cf615 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStageConfig.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStageConfig.aidl @@ -34,6 +34,6 @@ package android.hardware.biometrics.face; @VintfStability parcelable EnrollmentStageConfig { - android.hardware.biometrics.face.EnrollmentStage stage = android.hardware.biometrics.face.EnrollmentStage.FIRST_FRAME_RECEIVED; + android.hardware.biometrics.face.EnrollmentStage stage = android.hardware.biometrics.face.EnrollmentStage.UNKNOWN; List cells; } diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Error.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Error.aidl index 0437f0708c..1a21661932 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Error.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Error.aidl @@ -34,12 +34,13 @@ package android.hardware.biometrics.face; @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 = 8, - REENROLL_REQUIRED = 16, + VENDOR = 7, + REENROLL_REQUIRED = 8, } 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 1ee3cafc81..d1c2c1dd47 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 @@ -36,6 +36,7 @@ package android.hardware.biometrics.face; interface ISession { void generateChallenge(); void revokeChallenge(in long challenge); + android.hardware.biometrics.face.EnrollmentStageConfig[] getEnrollmentConfig(in android.hardware.biometrics.face.EnrollmentType enrollmentType); android.hardware.biometrics.common.ICancellationSignal enroll(in android.hardware.keymaster.HardwareAuthToken hat, in android.hardware.biometrics.face.EnrollmentType type, in android.hardware.biometrics.face.Feature[] features, in android.hardware.common.NativeHandle previewSurface); android.hardware.biometrics.common.ICancellationSignal authenticate(in long operationId); android.hardware.biometrics.common.ICancellationSignal detectInteraction(); diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl index c55a600eed..e6ea9f981e 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl @@ -35,7 +35,7 @@ package android.hardware.biometrics.face; @VintfStability parcelable SensorProps { android.hardware.biometrics.common.CommonProps commonProps; - android.hardware.biometrics.face.FaceSensorType sensorType = android.hardware.biometrics.face.FaceSensorType.RGB; + android.hardware.biometrics.face.FaceSensorType sensorType = android.hardware.biometrics.face.FaceSensorType.UNKNOWN; boolean halControlsPreview; int enrollPreviewWidth; int enrollPreviewHeight; diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl index a3b229e83a..cf68421062 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl @@ -19,18 +19,24 @@ package android.hardware.biometrics.face; @VintfStability @Backing(type="byte") enum AcquiredInfo { + /** + * Placeholder value used for default initialization of AcquiredInfo. This + * value means AcquiredInfo wasn't explicitly initialized and must be + * discarded by the recipient. + */ + UNKNOWN, /** * The acquired face data was good, no further user interaction is necessary. */ - GOOD = 0, + GOOD, /** * The acquired face data was too noisy or did not have sufficient detail. * This is a catch-all for all acquisition errors not captured by the other * constants. */ - INSUFFICIENT = 1, + INSUFFICIENT, /** * Because there was too much ambient light, the captured face data was too @@ -40,7 +46,7 @@ enum AcquiredInfo { * The user is expected to take action to retry the operation in better * lighting conditions when this is returned. */ - TOO_BRIGHT = 2, + TOO_BRIGHT, /** * Because there was not enough illumination, the captured face data was too @@ -50,7 +56,7 @@ enum AcquiredInfo { * The user is expected to take action to retry the operation in better * lighting conditions when this is returned. */ - TOO_DARK = 3, + TOO_DARK, /** * The detected face is too close to the sensor, and the image cannot be @@ -59,7 +65,7 @@ enum AcquiredInfo { * The user is expected to be informed to move further from the sensor when * this is returned. */ - TOO_CLOSE = 4, + TOO_CLOSE, /** * The detected face is too small, as the user might be too far away from @@ -68,7 +74,7 @@ enum AcquiredInfo { * The user is expected to be informed to move closer to the sensor when * this is returned. */ - TOO_FAR = 5, + TOO_FAR, /** * Only the upper part of the face was detected. The sensor's field of view @@ -77,7 +83,7 @@ enum AcquiredInfo { * The user should be informed to move up with respect to the sensor when * this is returned. */ - FACE_TOO_HIGH = 6, + FACE_TOO_HIGH, /** * Only the lower part of the face was detected. The sensor's field of view @@ -86,7 +92,7 @@ enum AcquiredInfo { * The user should be informed to move down with respect to the sensor when * this is returned. */ - FACE_TOO_LOW = 7, + FACE_TOO_LOW, /** * Only the right part of the face was detected. The sensor's field of view @@ -95,7 +101,7 @@ enum AcquiredInfo { * The user should be informed to move to the right with respect to the * sensor when this is returned. */ - FACE_TOO_RIGHT = 8, + FACE_TOO_RIGHT, /** * Only the left part of the face was detected. The sensor's field of view @@ -104,7 +110,7 @@ enum AcquiredInfo { * The user should be informed to move to the left with respect to the * sensor when this is returned. */ - FACE_TOO_LEFT = 9, + FACE_TOO_LEFT, /** * The user's eyes have strayed away from the sensor. If this message is @@ -112,7 +118,7 @@ enum AcquiredInfo { * can't be found in the frame, one of the other acquisition messages * must be sent, e.g. NOT_DETECTED. */ - POOR_GAZE = 10, + POOR_GAZE, /** * No face was detected within the sensor's field of view. @@ -120,7 +126,7 @@ enum AcquiredInfo { * The user should be informed to point the sensor to a face when this is * returned. */ - NOT_DETECTED = 11, + NOT_DETECTED, /** * Too much motion was detected. @@ -128,7 +134,7 @@ enum AcquiredInfo { * The user should be informed to keep their face steady relative to the * sensor. */ - TOO_MUCH_MOTION = 12, + TOO_MUCH_MOTION, /** * The sensor needs to be re-calibrated. This is an unexpected condition, @@ -137,20 +143,20 @@ enum AcquiredInfo { * re-enrolling. The expected response to this message is to direct the * user to re-enroll. */ - RECALIBRATE = 13, + RECALIBRATE, /** * The face is too different from a previous acquisition. This condition * only applies to enrollment. This can happen if the user passes the * device to someone else in the middle of enrollment. */ - TOO_DIFFERENT = 14, + TOO_DIFFERENT, /** * The face is too similar to a previous acquisition. This condition only * applies to enrollment. The user should change their pose. */ - TOO_SIMILAR = 15, + TOO_SIMILAR, /** * The magnitude of the pan angle of the user’s face with respect to the sensor’s @@ -162,7 +168,7 @@ enum AcquiredInfo { * * The user should be informed to look more directly at the camera. */ - PAN_TOO_EXTREME = 16, + PAN_TOO_EXTREME, /** * The magnitude of the tilt angle of the user’s face with respect to the sensor’s @@ -173,7 +179,7 @@ enum AcquiredInfo { * * The user should be informed to look more directly at the camera. */ - TILT_TOO_EXTREME = 17, + TILT_TOO_EXTREME, /** * The magnitude of the roll angle of the user’s face with respect to the sensor’s @@ -185,7 +191,7 @@ enum AcquiredInfo { * * The user should be informed to look more directly at the camera. */ - ROLL_TOO_EXTREME = 18, + ROLL_TOO_EXTREME, /** * The user’s face has been obscured by some object. @@ -193,7 +199,7 @@ enum AcquiredInfo { * The user should be informed to remove any objects from the line of sight from * the sensor to the user’s face. */ - FACE_OBSCURED = 19, + FACE_OBSCURED, /** * This message represents the earliest message sent at the beginning of the authentication @@ -202,33 +208,33 @@ enum AcquiredInfo { * will measure latency based on the time between the last START message and the onAuthenticated * callback. */ - START = 20, + START, /** * The sensor is dirty. The user should be informed to clean the sensor. */ - SENSOR_DIRTY = 21, + SENSOR_DIRTY, /** * Vendor-specific acquisition message. See ISessionCallback#onAcquired vendorCode * documentation. */ - VENDOR = 22, + VENDOR, /** * The first frame from the camera has been received. */ - FIRST_FRAME_RECEIVED = 23, + FIRST_FRAME_RECEIVED, /** * Dark glasses detected. This can be useful for providing relevant feedback to the user and * enabling an alternative authentication logic if the implementation supports it. */ - DARK_GLASSES_DETECTED = 24, + DARK_GLASSES_DETECTED, /** * A face mask or face covering detected. This can be useful for providing relevant feedback to * the user and enabling an alternative authentication logic if the implementation supports it. */ - MOUTH_COVERING_DETECTED = 25, + MOUTH_COVERING_DETECTED, } diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/AuthenticationFrame.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/AuthenticationFrame.aidl index 47cad3c61d..be61a20c6f 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/AuthenticationFrame.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/AuthenticationFrame.aidl @@ -23,7 +23,6 @@ import android.hardware.biometrics.face.BaseFrame; */ @VintfStability parcelable AuthenticationFrame { - /** * The frame metadata. Can be used by the framework to provide user feedback. */ diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/BaseFrame.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/BaseFrame.aidl index 85535f920d..58ad01a0c0 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/BaseFrame.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/BaseFrame.aidl @@ -29,7 +29,7 @@ parcelable BaseFrame { * Information about the frame that can be used by the framework to provide feedback to the * user, for example ask the user to move their face in a certain way. */ - AcquiredInfo acquiredInfo = AcquiredInfo.INSUFFICIENT; + AcquiredInfo acquiredInfo = AcquiredInfo.UNKNOWN; /** * If acquiredInfo is set to AcquiredInfo::VENDOR. This is the index into the configuration diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentFrame.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentFrame.aidl index ea0a502166..ecb0e79aca 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentFrame.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentFrame.aidl @@ -33,7 +33,7 @@ parcelable EnrollmentFrame { /** * The enrollment stage for which this frame was captured. */ - EnrollmentStage stage = EnrollmentStage.FIRST_FRAME_RECEIVED; + EnrollmentStage stage = EnrollmentStage.UNKNOWN; /** * The frame metadata. Can be used by the framework to provide user feedback. diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentStage.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentStage.aidl index bbc874fb0c..5974838e01 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentStage.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentStage.aidl @@ -22,34 +22,40 @@ package android.hardware.biometrics.face; @VintfStability @Backing(type="byte") enum EnrollmentStage { - - /** - * HAL has obtained the first camera frame. - */ - FIRST_FRAME_RECEIVED, - - /** - * HAL is waiting for the user's face to be centered. - */ - WAITING_FOR_CENTERING, - - /** - * HAL is expecting the user's face to stay centered. - */ - HOLD_STILL_IN_CENTER, - - /** - * Vendor defined movement 1. - */ - ENROLLING_MOVEMENT_1, - - /** - * Vendor defined movement 2. - */ - ENROLLING_MOVEMENT_2, - - /** - * HAL has finished the enrollment. - */ - ENROLLMENT_FINISHED, + /** + * Placeholder value used for default initialization of EnrollmentStage. This + * value means EnrollmentStage wasn't explicitly initialized and must be + * discarded by the recipient. + */ + UNKNOWN, + + /** + * HAL has obtained the first camera frame. + */ + FIRST_FRAME_RECEIVED, + + /** + * HAL is waiting for the user's face to be centered. + */ + WAITING_FOR_CENTERING, + + /** + * HAL is expecting the user's face to stay centered. + */ + HOLD_STILL_IN_CENTER, + + /** + * Vendor defined movement 1. + */ + ENROLLING_MOVEMENT_1, + + /** + * Vendor defined movement 2. + */ + ENROLLING_MOVEMENT_2, + + /** + * HAL has finished the enrollment. + */ + ENROLLMENT_FINISHED, } diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentStageConfig.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentStageConfig.aidl index 3c31fcc977..a8fa9abc8e 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentStageConfig.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentStageConfig.aidl @@ -24,7 +24,7 @@ parcelable EnrollmentStageConfig { /** * The stage that's being configured. */ - EnrollmentStage stage = EnrollmentStage.FIRST_FRAME_RECEIVED; + EnrollmentStage stage = EnrollmentStage.UNKNOWN; /** * Optional list of cells that must be completed to finish this stage. diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/Error.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/Error.aidl index 6f3264b4b6..e99415ac36 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/Error.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/Error.aidl @@ -20,22 +20,22 @@ package android.hardware.biometrics.face; @Backing(type="byte") enum Error { /** - * Reserved for testing and to keep subsequent numbering consistent with - * older interfaces. - * - * NO_ERROR = 0, + * Placeholder value used for default initialization of Error. This value + * means Error wasn't explicitly initialized and must be discarded by the + * recipient. */ + UNKNOWN, /** * A hardware error has occurred that cannot be resolved. Try again later. */ - HW_UNAVAILABLE = 1, + HW_UNAVAILABLE, /** * The current operation could not be completed, e.g. the sensor was unable * to process the current image or the HAT was invalid. */ - UNABLE_TO_PROCESS = 2, + UNABLE_TO_PROCESS, /** * The current operation took too long to complete. This is intended to @@ -48,48 +48,34 @@ enum Error { * indicate that the implementation is no longer looking and the framework * should restart the operation on the next user interaction. */ - TIMEOUT = 3, + TIMEOUT, /** * The current operation could not be completed because there is not enough * storage space remaining to do so. */ - NO_SPACE = 4, + NO_SPACE, /** * The current operation has been cancelled. This may happen if a new * request (authenticate, remove, enumerate, enroll) is initiated while * an on-going operation is in progress, or if cancel() was called. */ - CANCELED = 5, + CANCELED, /** * The current remove operation could not be completed; the face template * provided could not be removed. */ - UNABLE_TO_REMOVE = 6, - - /** - * Reserved to maintain backwards compatibility. See - * ISessionCallback#onLockoutTimed instead. - * - * LOCKOUT = 7, - */ + UNABLE_TO_REMOVE, /** * Used to enable a vendor-specific error message. */ - VENDOR = 8, - - /** - * Reserved to maintain backwards compatibility. See - * ISessionCallback#onLockoutPermanent instead. - * - * LOCKOUT_PERMANENT = 9 - */ + VENDOR, /** * Authentication cannot be performed because re-enrollment is required. */ - REENROLL_REQUIRED = 16, + REENROLL_REQUIRED, } diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl index 12911e3ba7..a9a8c16cf2 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.face.EnrollmentStageConfig; import android.hardware.biometrics.face.EnrollmentType; import android.hardware.biometrics.face.Feature; import android.hardware.common.NativeHandle; @@ -104,9 +105,9 @@ interface ISession { * each of the stages. * * @param enrollmentType See the EnrollmentType enum. - * @return A list of EnrollmentStageConfig that describes each enrollment stage. - * - List getEnrollmentConfig(in EnrollmentType enrollmentType); + * @return An EnrollmentStageConfig array that describes each enrollment stage. + */ + EnrollmentStageConfig[] getEnrollmentConfig(in EnrollmentType enrollmentType); /** * enroll: diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl index b11b436098..994324d068 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl @@ -29,7 +29,7 @@ parcelable SensorProps { /** * A statically configured sensor type representing this face sensor. */ - FaceSensorType sensorType = FaceSensorType.RGB; + FaceSensorType sensorType = FaceSensorType.UNKNOWN; /** * Whether or not the HAL is responsible for showing the face enrollment preview to the user. diff --git a/biometrics/face/aidl/default/Session.cpp b/biometrics/face/aidl/default/Session.cpp index 4438d35ba4..d980c5f892 100644 --- a/biometrics/face/aidl/default/Session.cpp +++ b/biometrics/face/aidl/default/Session.cpp @@ -52,6 +52,12 @@ ndk::ScopedAStatus Session::revokeChallenge(int64_t challenge) { return ndk::ScopedAStatus::ok(); } +ndk::ScopedAStatus Session::getEnrollmentConfig(EnrollmentType /*enrollmentType*/, + std::vector* return_val) { + *return_val = {}; + return ndk::ScopedAStatus::ok(); +} + ndk::ScopedAStatus Session::enroll( const keymaster::HardwareAuthToken& /*hat*/, EnrollmentType /*enrollmentType*/, const std::vector& /*features*/, const NativeHandle& /*previewSurface*/, diff --git a/biometrics/face/aidl/default/Session.h b/biometrics/face/aidl/default/Session.h index c89985e31e..caf81f8702 100644 --- a/biometrics/face/aidl/default/Session.h +++ b/biometrics/face/aidl/default/Session.h @@ -34,6 +34,9 @@ class Session : public BnSession { ndk::ScopedAStatus revokeChallenge(int64_t challenge) override; + ndk::ScopedAStatus getEnrollmentConfig(EnrollmentType enrollmentType, + std::vector* return_val) override; + ndk::ScopedAStatus enroll(const keymaster::HardwareAuthToken& hat, EnrollmentType enrollmentType, const std::vector& features, const NativeHandle& previewSurface, -- GitLab From c316f63cbb896643e3195d6bd31e062c01b1bafe Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Thu, 22 Apr 2021 11:57:15 -0700 Subject: [PATCH 628/790] Add enum defaults and remove placeholder constants Bug: 181358178 Test: atest VtsHalBiometricsFingerprintTargetTest Change-Id: I7acc4796cb56234280a8ec97dd3cb7921553955f --- .../biometrics/fingerprint/AcquiredInfo.aidl | 25 ++++++++------- .../biometrics/fingerprint/Error.aidl | 3 +- .../biometrics/fingerprint/AcquiredInfo.aidl | 7 ++++ .../biometrics/fingerprint/Error.aidl | 32 +++++++------------ .../fingerprint/FingerprintSensorType.aidl | 1 - .../biometrics/fingerprint/ISession.aidl | 4 +-- .../fingerprint/SensorLocation.aidl | 2 +- 7 files changed, 36 insertions(+), 38 deletions(-) diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl index 2c2011a034..c51aa033d4 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl @@ -34,16 +34,17 @@ package android.hardware.biometrics.fingerprint; @Backing(type="byte") @VintfStability enum AcquiredInfo { - GOOD = 0, - PARTIAL = 1, - INSUFFICIENT = 2, - SENSOR_DIRTY = 3, - TOO_SLOW = 4, - TOO_FAST = 5, - VENDOR = 6, - START = 7, - TOO_DARK = 8, - TOO_BRIGHT = 9, - IMMOBILE = 10, - RETRYING_CAPTURE = 11, + 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, } diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl index f79c576fb1..060379d63c 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl @@ -34,11 +34,12 @@ 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 = 8, + VENDOR = 7, } diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl index b406947be5..8ec8574965 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl @@ -19,6 +19,13 @@ package android.hardware.biometrics.fingerprint; @VintfStability @Backing(type="byte") enum AcquiredInfo { + /** + * Placeholder value used for default initialization of AcquiredInfo. This + * value means AcquiredInfo wasn't explicitly initialized and must be + * discarded by the recipient. + */ + UNKNOWN, + /** * A high quality fingerprint image was detected, no further user interaction is necessary. */ diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/Error.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/Error.aidl index 4fe7f5f573..fc89da218a 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/Error.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/Error.aidl @@ -20,57 +20,47 @@ package android.hardware.biometrics.fingerprint; @Backing(type="byte") enum Error { /** - * Used for testing, and to keep subsequent numbering consistent with older HIDLs. + * Placeholder value used for default initialization of Error. This value + * means Error wasn't explicitly initialized and must be discarded by the + * recipient. */ - // NO_ERROR = 0, + UNKNOWN, /** * A hardware error has occurred that cannot be resolved. For example, I2C failure or a broken * sensor. */ - HW_UNAVAILABLE = 1, + HW_UNAVAILABLE, /** * The implementation is unable to process the request. For example, invalid arguments were * supplied. */ - UNABLE_TO_PROCESS = 2, + UNABLE_TO_PROCESS, /** * The current operation took too long to complete. */ - TIMEOUT = 3, + TIMEOUT, /** * No space available to store additional enrollments. */ - NO_SPACE = 4, + NO_SPACE, /** * The operation was canceled. See common::ICancellationSignal. */ - CANCELED = 5, + CANCELED, /** * The implementation was unable to remove an enrollment. * See ISession#removeEnrollments. */ - UNABLE_TO_REMOVE = 6, - - /** - * Reserved to maintain backwards compatibility. See ISessionCallback#onLockoutTimed instead. - */ - // LOCKOUT = 7, + UNABLE_TO_REMOVE, /** * Used to enable vendor-specific error messages. */ - VENDOR = 8, - - /** - * Reserved to maintain backwards compatibility. See ISessionCallback#onLockoutPermanent - * instead. - */ - // LOCKOUT_PERMANENT = 9, + VENDOR, } - diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl index 765a2ed664..dbe71377a2 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl @@ -26,4 +26,3 @@ enum FingerprintSensorType { POWER_BUTTON, HOME_BUTTON } - diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl index 940548ba88..02ef138427 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl @@ -42,8 +42,8 @@ import android.hardware.keymaster.HardwareAuthToken; * have callbacks. * * ISession only supports execution of one non-interrupting operation at a time, regardless of - * whether it's cancellable. The framework must wait for a corresponding callback indicating the end of - * the current non-interrupting operation before a new non-interrupting operation can be started. + * whether it's cancellable. The framework must wait for a corresponding callback indicating the end + * of the current non-interrupting operation before a new non-interrupting operation can be started. */ @VintfStability interface ISession { diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorLocation.aidl index 62a2e8cdbb..b1618b2d0c 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorLocation.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorLocation.aidl @@ -51,4 +51,4 @@ parcelable SensorLocation { * in pixels. */ int sensorRadius; -} \ No newline at end of file +} -- GitLab From d85ab6f7a713ffa46c4558f638e6595a77aae7b1 Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Thu, 22 Apr 2021 15:54:40 -0700 Subject: [PATCH 629/790] Add halHandlesDisplayTouches and halControlsIllumination Bug: 185522754 Test: m android.hardware.biometrics.fingerprint-update-api Change-Id: I3a1e71951e202212c0a0951d1b64249436619f56 --- .../biometrics/fingerprint/SensorProps.aidl | 2 ++ .../biometrics/fingerprint/SensorProps.aidl | 22 +++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl index c7a4002c11..782d2899d3 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl @@ -39,4 +39,6 @@ parcelable SensorProps { android.hardware.biometrics.fingerprint.SensorLocation[] sensorLocations; boolean supportsNavigationGestures; boolean supportsDetectInteraction; + boolean halHandlesDisplayTouches; + boolean halControlsIllumination; } diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl index fd2cf47d9e..fb516da51e 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl @@ -48,4 +48,26 @@ parcelable SensorProps { * Specifies whether or not the implementation supports ISession#detectInteraction. */ boolean supportsDetectInteraction; + + /** + * Whether the HAL is responsible for detecting and processing of display touches. This is only + * applicable to under-display fingerprint sensors (UDFPS). If the value is false, the framework + * will be responsible for handling the display touch events and passing them down to the HAL by + * using ISession#onPointerDown and ISession#onPointerUp. If the value is true, the framework + * will not notify the HAL about touch events. + * + * This value must be ignored for non-UDFPS sensors. + */ + boolean halHandlesDisplayTouches; + + /** + * Whether the HAL is responsible for fingerprint illumination, for example through enabling the + * display's high-brightness mode. This is only applicable to optical under-display fingerprint + * sensors (optical UDFPS). If the value is false, the framework will be responsible for + * illuminating the finger and reporting ISession#onUiReady. If the value is true, the framework + * will not illuminate the finger and will not report ISession#onUiReady. + * + * This value must be ignored for sensors that aren't optical UDFPS. + */ + boolean halControlsIllumination; } -- GitLab From 3d1d3e6f54fbb4175760663a603b16c44e7c74aa Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Thu, 22 Apr 2021 16:30:42 -0700 Subject: [PATCH 630/790] Add previewDisplayId to SensorProps Bug: 183738533 Test: m android.hardware.biometrics.face-update-api Change-Id: Ia0703815d2aaa616d6e8b8f607bfe6e905ffdb7f --- .../android/hardware/biometrics/face/SensorProps.aidl | 1 + .../aidl/android/hardware/biometrics/face/SensorProps.aidl | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl index c55a600eed..c4765d53ab 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl @@ -37,6 +37,7 @@ parcelable SensorProps { android.hardware.biometrics.common.CommonProps commonProps; android.hardware.biometrics.face.FaceSensorType sensorType = android.hardware.biometrics.face.FaceSensorType.RGB; boolean halControlsPreview; + int previewDisplayId; int enrollPreviewWidth; int enrollPreviewHeight; float enrollTranslationX; diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl index b11b436098..ee98d74b1d 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl @@ -40,6 +40,13 @@ parcelable SensorProps { */ boolean halControlsPreview; + /** + * The ID of the display that's used for enrollment preview. This must correspond to the + * android.hardware.DisplayManager#getDisplay Android API. This is useful for devices with + * multiple displays to ensure the correct display is used for this face sensor. + */ + int previewDisplayId; + /** * For implementations where the HAL manages the preview, this is the width, in pixels, of each * frame that the camera is set up to output. -- GitLab From 88027aa3c4b059e7feb025ed81722ae9b5e6795f Mon Sep 17 00:00:00 2001 From: Steven Moreland Date: Mon, 26 Apr 2021 21:50:23 +0000 Subject: [PATCH 631/790] Freeze HALs for Android S Bug: 178221726 Test: none Change-Id: I77ee02664242827d9aa96c985764cfc109c52b84 --- current.txt | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 92 insertions(+), 2 deletions(-) diff --git a/current.txt b/current.txt index 69c4565c23..ac65326749 100644 --- a/current.txt +++ b/current.txt @@ -797,5 +797,95 @@ bc3c8c233085fca3879dc74b490b9e5bc1063258470d3b4c12f7a74bf215cbbd android.hardwar 2b5afef68e3e2ff1dab63e4f2ee57337ef2635ec812f49080cadfce966d33b52 android.hardware.radio@1.2::IRadio # HALs released in Android S -# NOTE: waiting to freeze HALs until later in the release -# NOTE: new HALs are recommended to be in AIDL +59fa68432e374c8d3b7ec098a91a1e023a2c728110bb733237c551afa5929725 android.hardware.audio@7.0::IDevice +2207948ca127b801c94f667c99dfd139f150b50671e1408d3e855d03efbf631d android.hardware.audio@7.0::IDevicesFactory +1d201e15c553cd44c62864ac8d7039351ddf048a7ee61e380f6efb0904442eb8 android.hardware.audio@7.0::IPrimaryDevice +38afa920e6d36013b5a800e8c82eefeebd24602de24441e2f8ce5b3bdf62d3af android.hardware.audio@7.0::IStream +77d84330418abba5a92b0cdc4e27fa7c85c27344eaf7eeef441b8e88829ee475 android.hardware.audio@7.0::IStreamIn +40c5c43e923da23497c0e3d5a1c2d699b423a0268e1e971f918e4854e1c39951 android.hardware.audio@7.0::IStreamOut +54cbc3c637fe8d4b889ccb5690e5e3069ca8efd9c6607ce1d021a3f47576c67e android.hardware.audio@7.0::IStreamOutCallback +8036ae0a68a698a79207218018de5f41aed344723f644112ffc99e20e5e2e9ff android.hardware.audio@7.0::IStreamOutEventCallback +84978dbd15d4fa8be6073d0974755f7718ee0cde519ce71449fb734f53cee46b android.hardware.audio@7.0::types +6a03a9d8cc917da00e8b88f4abc42db2f741e2d50901e8ab6dea32084a238fbd android.hardware.audio.common@7.0::types +842b4485a00005fb938f674b12445cb592cd1636f56c7cc447966119070811bd android.hardware.audio.effect@7.0::IAcousticEchoCancelerEffect +b62a85e5d745dc35b5a60464c6b33a5bb7a2b8b95863a1374aee77ea29cf8f49 android.hardware.audio.effect@7.0::IAutomaticGainControlEffect +c8d5e30848191713db7cffccc482e4427816f33c98a24734c8769962f79f855b android.hardware.audio.effect@7.0::IBassBoostEffect +7d021ecdf5bb6a61eb9ad193585d4986d1a64cb7fb4b52f219d7380145f2c6f1 android.hardware.audio.effect@7.0::IDownmixEffect +7fee1e7c7bb3d513a524c8963d1f8f7c2ad856f26c745b4ebc286b40d503264a android.hardware.audio.effect@7.0::IEffect +7596050ccc00234458dcb4e692056ed3c16f3618c11d7b17cb749cfd5713705d android.hardware.audio.effect@7.0::IEffectBufferProviderCallback +f2e41467bcf1140a11b219c2e8f77981b955c2941befe66e1cc685b7863ae4c9 android.hardware.audio.effect@7.0::IEffectsFactory +af66fb4addbc477f9fea65fb63475203122a9189624ca8d14e757bc7826d60a4 android.hardware.audio.effect@7.0::IEnvironmentalReverbEffect +2878d007ed55e1a4149ddcd29606962c948d8610642276f91dffd5ed32281824 android.hardware.audio.effect@7.0::IEqualizerEffect +0260ef9e2a3e077de366ebebc0c117c7ee13f46a1eabd4abd66cc6245d0bed98 android.hardware.audio.effect@7.0::ILoudnessEnhancerEffect +3586bbc3a7cbe30f9aff0a522524eea9b78eea78280f09c35d43dbab48a1193e android.hardware.audio.effect@7.0::INoiseSuppressionEffect +a7d74d7e7e0b1e3b739f233b7776bf01e868856a536f5cdac0f307e9c2850e64 android.hardware.audio.effect@7.0::IPresetReverbEffect +b4cbc1f2d38787f2ad069a8e4d10c0896287531a2596f0de0283e390b0ecf05d android.hardware.audio.effect@7.0::IVirtualizerEffect +2b5681e1ea6a2db0dc1e84edb96d3de2f7daf306046543e7956be76dcb8f20fb android.hardware.audio.effect@7.0::IVisualizerEffect +fa1e2d78e66fd662de93cb479ffd55947fe54f51cb53915814b3d3e3036c86a5 android.hardware.audio.effect@7.0::types +b525e91d886379c13588f4975bb04d625d46e1f41b4453792c4b2db1e7ff4340 android.hardware.biometrics.fingerprint@2.3::IBiometricsFingerprint +4baf8e0eca4aa896cc9ceb7bb676aaf4fa21372ef8b49eed68eced1221c3dc0d android.hardware.bluetooth.audio@2.1::IBluetoothAudioProvider +d417a9212c8f96e3a06a2f221c8c5756c765355b2b81de2b2a65d4c9eee85401 android.hardware.bluetooth.audio@2.1::IBluetoothAudioProvidersFactory +c17d9e27abd37ae5a8ff8da08fc5c9b13a264670feef6bbbc9d3ab1915216130 android.hardware.bluetooth.audio@2.1::types +6763dd2273b1b47f3ac68af9b66870287eba33fb5b4d66e8fe1d30ae18ce24cb android.hardware.boot@1.2::IBootControl +1a1dff6e8d25dbc02a69fed3c077dd0782b30331ca3f345848ec52fc67744224 android.hardware.camera.device@3.7::ICameraDevice +3be6faa3d11ad9c7ec01a1a0a009cf11cb65d701d109dab37613ce9cfb3cdd60 android.hardware.camera.device@3.7::ICameraDeviceSession +3740ec773b2eb8fa6bd8c6e879eedb56c4e4306b88f1c20fa51103d791d871b1 android.hardware.camera.device@3.7::ICameraInjectionSession +21f023685571daf46148097d98b89cea353f07e3ed83b2ed5685b23bd136c3ee android.hardware.camera.device@3.7::types +f655c93132d223369ff6ddc621cb721f82dde6cc85ab9df2cbde6cb24cf2c885 android.hardware.camera.metadata@3.6::types +98ff825a7d37e5ab983502d13cec1f2e5a9cac9b674b6ff1a52bcf540f4e315e android.hardware.camera.provider@2.7::ICameraProvider +51fd14005859b16be55872660c34f5d423c77a2abcc5d4bdd5a537c40f32516b android.hardware.camera.provider@2.7::types +3500d3c4e2d49eeed2f3239330a166beb2db2d5071b84d9c738b048c2d54a3d9 android.hardware.contexthub@1.2::IContexthub +5ec58b1f9283d47857e3e70fbd39d9a4ff030c12d6fa3113af2b59fa3c77046e android.hardware.contexthub@1.2::IContexthubCallback +afe69d8a66fcbd87aa1d5c033e91017237d5466110538a57e8287d7efa114538 android.hardware.contexthub@1.2::types +c38a42661a90a0cef538b1757e29268d3a91867fcadf3c44185c992566da0b81 android.hardware.drm@1.4::ICryptoFactory +0e96e7699ee74d65432a8712e6b2474b425a3a079c55f4e3122aa65ff2b778a4 android.hardware.drm@1.4::ICryptoPlugin +4ebbe2b8ff3a6c8729619fe9ce62429f4b561d2e26e32eb54675babddfec9e59 android.hardware.drm@1.4::IDrmFactory +a71fa24841f1398620f9baf738863dbaf29bde62cd171ac7b4608797ca55e35d android.hardware.drm@1.4::IDrmPlugin +48127234347525a9d0fad9b7b79be5762d14e51cc87b1a09329a2452e06f3307 android.hardware.drm@1.4::types +0c0657fad2239c2c7ec363d3b13f2e002d1c267ca89d2cc96d2b1de0475386cb android.hardware.fastboot@1.1::IFastboot +61e5d73d12d558a3115e5b1e2e740fbe149235c36c607881f053f2f443cafdf5 android.hardware.media.c2@1.2::IComponent +fcd17fb86c1b5570c8b55d855fd2ab93e4a2c6629d9ba9374372928469aad961 android.hardware.media.c2@1.2::IComponentStore +8b149e213e77f4be50dcaf68ab55b8220ca62abd9443969e7f46a197b5adddfc android.hardware.media.c2@1.2::types +3e8866987de4ecb48807c09d4c88ec38365930a22415f1b74edf8b14da17846b android.hardware.radio@1.6::IRadio +715789427a44cc78f9d123b0ceb9e035e4ac2b1049501337c23a512e85b87850 android.hardware.radio@1.6::IRadioIndication +4443f5c5f789d77ab491aad4cf4673d131bba45014d6bb4816888cbac37aa8c1 android.hardware.radio@1.6::IRadioResponse +d06226cd3e916bb866b016b22f35c89c1d9286f62a4aa82a549daf8d52805183 android.hardware.radio@1.6::types +f22813615be1445ddd817655c054fc69dc9efea56c9035cd0757f3cbed190641 android.hardware.radio.config@1.3::IRadioConfig +c9ad18729268593d14681d88ffad1c97e707444a45e1b4ed804dab949edbd84f android.hardware.radio.config@1.3::IRadioConfigResponse +fd43298c43f70130c747a642ee43b0c242ac0cebffb377faa24f2725f0aa6caf android.hardware.tetheroffload.control@1.1::IOffloadControl +fe18c9032e4063efca3fff3c377dd69780de1f96e8e2bc3f7d100a5d8bd467b4 android.hardware.tetheroffload.control@1.1::ITetheringOffloadCallback +e34b4c7bec5e032c14804707ca924dd6b99ed5ba139da7505fe7d698d0fe178f android.hardware.tetheroffload.control@1.1::types +63dfdb433ac73fb2bf4a44d2ade7b7e289e155835206d1939640d6c88d208994 android.hardware.tv.cec@1.1::IHdmiCec +b9682587677ce9c872e04f0e9fd6c9c78a56ae795c07cbf8c50100e0351d4c44 android.hardware.tv.cec@1.1::IHdmiCecCallback +4c4243db0fad48931622b07c5ada346ed7b8e49ace30da88fde754c976e430c2 android.hardware.tv.cec@1.1::types +b8305da72fb09d5c8ae9f89bebdc30a4c1908a62253b705f9cb6df4dc28c9094 android.hardware.tv.tuner@1.1::IFilter +3e29c02ccc3f0c22414eb05604a0cfe93af4521c49fc4165f0fdcaa3c975dc4f android.hardware.tv.tuner@1.1::IFilterCallback +0f2deed38165f154f27a01c3e70e6ea770520d67f7dbf3630ee45992f7a644be android.hardware.tv.tuner@1.1::IFrontend +695213b5c7ccd13cc0227a7aaca652f77b5a5a2352483575f2905d1361562b5d android.hardware.tv.tuner@1.1::IFrontendCallback +6fd387a7ff5916def0d1c9010aa501b30ef2fe34f161164531c9631f67ff098a android.hardware.tv.tuner@1.1::ITuner +ea2453fa7563783fa0cd7c09aa86e6cd7ac799a1d0fc439b34c416d1c55062d1 android.hardware.tv.tuner@1.1::types +bcebdb0b3b59bd144eefc1b17aa96609c1b23bc9a5f7e0d7060dabd7f06ef9c0 android.hardware.usb@1.3::IUsb +f2a87e56164145160b3b3a097dba2ccc1b0ffc2fb87e8c984adfe59f47b5ecf7 android.hardware.usb.gadget@1.2::IUsbGadget +c539325b22bce686876f062b16292038555ae2857e8d34aa63a975df18e113b1 android.hardware.usb.gadget@1.2::IUsbGadgetCallback +95e23dbfcfb38d390f236e5fff77dd518ba272a85551df6ecb4707fe466e60bd android.hardware.usb.gadget@1.2::types +bb7b8f653452f2044e1db587ceb415edf72201ab9c1d547564c3f75bfab65a83 android.hardware.wifi@1.5::IWifi +c66c3ea1b375e69d7ad820d67950305a463b5a50908c4fddcbbdbab8bbac3951 android.hardware.wifi@1.5::IWifiApIface +a1193d37f7e13222bf79ef4b73dbad15b0f0a330d03356d12226dcda20de44a7 android.hardware.wifi@1.5::IWifiChip +d78f1c169cf7e92ddf49e0b6a2b6d5566730e8085a56aefd9140c76b107bb35d android.hardware.wifi@1.5::IWifiEventCallback +45ab93378f02a8bc3a658853ce4d3fdc1e9fa2c1d1c545821d490bf0f4d96cec android.hardware.wifi@1.5::IWifiNanIface +b20261b97359a8b8784700d4278aa00a8666fcd9fc259c3a8386ba34bad5ec83 android.hardware.wifi@1.5::IWifiNanIfaceEventCallback +b154b9fe8b94cf64392766bfd932c023edf658ba8ecc4b952f8424058120e5bd android.hardware.wifi@1.5::IWifiStaIface +ee214c95481f61aefc1255987c92be6c3b4519be327467b1692630572060b489 android.hardware.wifi@1.5::types +c972b342dd527a3952b5d2377bd6483dec48f6b85292ca537a97705381c7ea3c android.hardware.wifi.hostapd@1.3::IHostapd +6a3152de16dfa71b065c686e84ce8b85317745c0b9dd8f4790009ec6950d96c8 android.hardware.wifi.hostapd@1.3::IHostapdCallback +6d361bfd0ff1ecb6d2dddb72636ddce4d706453391de401852a6a53effb7b599 android.hardware.wifi.hostapd@1.3::types +17818b6b1952a75e4364ae82c534b9d2f5c0a9765a56256b16faa5a5cf45d3a8 android.hardware.wifi.supplicant@1.4::ISupplicant +d29fe62973c49b6fa40eb56c28567e37c4bbec015ff59111edfae446301dc06d android.hardware.wifi.supplicant@1.4::ISupplicantP2pIface +ea465970e96d9605ee6f6706b3b512726c66d2644738added9128c739f8f8b0c android.hardware.wifi.supplicant@1.4::ISupplicantP2pIfaceCallback +026b9a46658ee82b154ee624adc30a454f6401230db5eb446ead42e7ef51fc80 android.hardware.wifi.supplicant@1.4::ISupplicantStaIface +0d5adbc7ca369ca30c64a3e3f021335f991055787bc80ab44bbbbaa056d5515b android.hardware.wifi.supplicant@1.4::ISupplicantStaIfaceCallback +c8a57364f6ad20842be14f4db284df5304f7521ca8eac6bcc1fa6c5b466fb8a6 android.hardware.wifi.supplicant@1.4::ISupplicantStaNetwork +2123482b69f3b531c88023aa2a007110e130efbf4ed68ac9ce0bc55d5e82bc8b android.hardware.wifi.supplicant@1.4::ISupplicantStaNetworkCallback +0821f516e4d428bc15251969f7e19411c94d8f2ccbd99e1fc8168d8e49e38b0f android.hardware.wifi.supplicant@1.4::types + +# There should be no more HIDL HALs - please use AIDL instead. -- GitLab From 160a72c9e245c3576e4ee877f89718d456fccbfd Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Sat, 24 Apr 2021 21:15:26 -0700 Subject: [PATCH 632/790] Allow users to switch between FE source and DVR source when testing record/descrambling/broadcast Test: atest VtsHalTvTunerV1_0TargetTest Test: atest VtsHalTvTunerV1_1TargetTest Bug: 182519645 CTS-Coverage-Bug: 184077478 Change-Id: I6c57657ac3539d6a6fb3f63d2ecc9af7f6b9e2dc --- .../VtsHalTvTunerV1_0TargetTest.cpp | 232 ++++++++++++++---- .../VtsHalTvTunerV1_0TestConfigurations.h | 50 +++- tv/tuner/1.1/default/Demux.cpp | 4 + tv/tuner/1.1/default/Demux.h | 1 + tv/tuner/1.1/default/Dvr.cpp | 13 +- .../VtsHalTvTunerV1_1TargetTest.cpp | 92 +++++-- .../functional/VtsHalTvTunerV1_1TargetTest.h | 1 - .../VtsHalTvTunerV1_1TestConfigurations.h | 14 +- .../config/TunerTestingConfigReaderV1_0.h | 46 +++- tv/tuner/config/api/current.txt | 8 + .../config/sample_tuner_vts_config_1_0.xml | 6 +- .../config/sample_tuner_vts_config_1_1.xml | 9 +- .../tuner_testing_dynamic_configuration.xsd | 24 +- 13 files changed, 400 insertions(+), 100 deletions(-) diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp index 4c92665b63..62093ccbe5 100644 --- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp +++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp @@ -56,9 +56,6 @@ void TunerFilterHidlTest::configSingleFilterInDemuxTest(FilterConfig filterConf, } void TunerFilterHidlTest::testTimeFilter(TimeFilterConfig filterConf) { - if (!timeFilter.support) { - return; - } uint32_t demuxId; sp demux; DemuxCapabilities caps; @@ -161,27 +158,36 @@ void TunerPlaybackHidlTest::playbackSingleFilterTest(FilterConfig filterConf, Dv void TunerRecordHidlTest::recordSingleFilterTest(FilterConfig filterConf, FrontendConfig frontendConf, DvrConfig dvrConf) { - uint32_t feId; uint32_t demuxId; sp demux; - uint32_t filterId; - sp filter; + ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); + mDvrTests.setDemux(demux); - mFrontendTests.getFrontendIdByType(frontendConf.type, feId); - ASSERT_TRUE(feId != INVALID_ID); - ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); - ASSERT_TRUE(mFrontendTests.setFrontendCallback()); - if (mLnbId) { - ASSERT_TRUE(mFrontendTests.setLnb(*mLnbId)); - } - if (frontendConf.isSoftwareFe) { - mFrontendTests.setSoftwareFrontendDvrConfig(dvrMap[record.dvrSoftwareFeId]); + DvrConfig dvrSourceConfig; + if (mLnbId || record.hasFrontendConnection) { + uint32_t feId; + mFrontendTests.getFrontendIdByType(frontendConf.type, feId); + ASSERT_TRUE(feId != INVALID_ID); + ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); + ASSERT_TRUE(mFrontendTests.setFrontendCallback()); + if (mLnbId) { + ASSERT_TRUE(mFrontendTests.setLnb(*mLnbId)); + } + if (frontendConf.isSoftwareFe) { + mFrontendTests.setSoftwareFrontendDvrConfig(dvrMap[record.dvrSoftwareFeId]); + } + ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); + mFrontendTests.setDvrTests(mDvrTests); + } else { + dvrSourceConfig = dvrMap[record.dvrSourceId]; + ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrSourceConfig.type, dvrSourceConfig.bufferSize)); + ASSERT_TRUE(mDvrTests.configDvrPlayback(dvrSourceConfig.settings)); + ASSERT_TRUE(mDvrTests.getDvrPlaybackMQDescriptor()); } - ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); - ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); + + uint32_t filterId; + sp filter; mFilterTests.setDemux(demux); - mDvrTests.setDemux(demux); - mFrontendTests.setDvrTests(mDvrTests); ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrConf.type, dvrConf.bufferSize)); ASSERT_TRUE(mDvrTests.configDvrRecord(dvrConf.settings)); ASSERT_TRUE(mDvrTests.getDvrRecordMQDescriptor()); @@ -195,17 +201,39 @@ void TunerRecordHidlTest::recordSingleFilterTest(FilterConfig filterConf, ASSERT_TRUE(mDvrTests.attachFilterToDvr(filter)); ASSERT_TRUE(mDvrTests.startDvrRecord()); ASSERT_TRUE(mFilterTests.startFilter(filterId)); - ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/)); + + if (mLnbId || record.hasFrontendConnection) { + ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/)); + } else { + // Start DVR Source + mDvrTests.startPlaybackInputThread(dvrSourceConfig.playbackInputFile, + dvrSourceConfig.settings.playback()); + ASSERT_TRUE(mDvrTests.startDvrPlayback()); + } + mDvrTests.testRecordOutput(); mDvrTests.stopRecordThread(); - ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/)); + + if (mLnbId || record.hasFrontendConnection) { + ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/)); + } else { + mDvrTests.stopPlaybackThread(); + ASSERT_TRUE(mDvrTests.stopDvrPlayback()); + } + ASSERT_TRUE(mFilterTests.stopFilter(filterId)); ASSERT_TRUE(mDvrTests.stopDvrRecord()); ASSERT_TRUE(mDvrTests.detachFilterToDvr(filter)); ASSERT_TRUE(mFilterTests.closeFilter(filterId)); mDvrTests.closeDvrRecord(); + + if (mLnbId || record.hasFrontendConnection) { + ASSERT_TRUE(mFrontendTests.closeFrontend()); + } else { + mDvrTests.closeDvrPlayback(); + } + ASSERT_TRUE(mDemuxTests.closeDemux()); - ASSERT_TRUE(mFrontendTests.closeFrontend()); } void TunerRecordHidlTest::recordSingleFilterTestWithLnb(FilterConfig filterConf, @@ -236,23 +264,28 @@ void TunerRecordHidlTest::recordSingleFilterTestWithLnb(FilterConfig filterConf, void TunerRecordHidlTest::attachSingleFilterToRecordDvrTest(FilterConfig filterConf, FrontendConfig frontendConf, DvrConfig dvrConf) { - uint32_t feId; uint32_t demuxId; sp demux; + ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); + + if (record.hasFrontendConnection) { + uint32_t feId; + mFrontendTests.getFrontendIdByType(frontendConf.type, feId); + ASSERT_TRUE(feId != INVALID_ID); + ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); + ASSERT_TRUE(mFrontendTests.setFrontendCallback()); + ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); + } + uint32_t filterId; sp filter; - - mFrontendTests.getFrontendIdByType(frontendConf.type, feId); - ASSERT_TRUE(feId != INVALID_ID); - ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); - ASSERT_TRUE(mFrontendTests.setFrontendCallback()); - ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); - ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); mFilterTests.setDemux(demux); + mDvrTests.setDemux(demux); ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrConf.type, dvrConf.bufferSize)); ASSERT_TRUE(mDvrTests.configDvrRecord(dvrConf.settings)); ASSERT_TRUE(mDvrTests.getDvrRecordMQDescriptor()); + ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize)); ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId)); ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId)); @@ -268,30 +301,42 @@ void TunerRecordHidlTest::attachSingleFilterToRecordDvrTest(FilterConfig filterC ASSERT_TRUE(mFilterTests.closeFilter(filterId)); mDvrTests.closeDvrRecord(); ASSERT_TRUE(mDemuxTests.closeDemux()); - ASSERT_TRUE(mFrontendTests.closeFrontend()); + + if (record.hasFrontendConnection) { + ASSERT_TRUE(mFrontendTests.closeFrontend()); + } } void TunerDescramblerHidlTest::scrambledBroadcastTest(set mediaFilterConfs, FrontendConfig frontendConf, DescramblerConfig descConfig) { - uint32_t feId; uint32_t demuxId; sp demux; + ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); + + DvrConfig dvrSourceConfig; + if (descrambling.hasFrontendConnection) { + uint32_t feId; + mFrontendTests.getFrontendIdByType(frontendConf.type, feId); + ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); + ASSERT_TRUE(mFrontendTests.setFrontendCallback()); + if (frontendConf.isSoftwareFe) { + mFrontendTests.setSoftwareFrontendDvrConfig(dvrMap[descrambling.dvrSoftwareFeId]); + } + ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); + mFrontendTests.setDemux(demux); + } else { + dvrSourceConfig = dvrMap[descrambling.dvrSourceId]; + ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrSourceConfig.type, dvrSourceConfig.bufferSize)); + ASSERT_TRUE(mDvrTests.configDvrPlayback(dvrSourceConfig.settings)); + ASSERT_TRUE(mDvrTests.getDvrPlaybackMQDescriptor()); + } + set filterIds; uint32_t filterId; set::iterator config; set::iterator id; - - mFrontendTests.getFrontendIdByType(frontendConf.type, feId); - ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); - ASSERT_TRUE(mFrontendTests.setFrontendCallback()); - if (frontendConf.isSoftwareFe) { - mFrontendTests.setSoftwareFrontendDvrConfig(dvrMap[descrambling.dvrSoftwareFeId]); - } - ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); - ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); mFilterTests.setDemux(demux); - mFrontendTests.setDemux(demux); for (config = mediaFilterConfs.begin(); config != mediaFilterConfs.end(); config++) { ASSERT_TRUE(mFilterTests.openFilterInDemux((*config).type, (*config).bufferSize)); ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId)); @@ -314,10 +359,26 @@ void TunerDescramblerHidlTest::scrambledBroadcastTest(set m for (id = filterIds.begin(); id != filterIds.end(); id++) { ASSERT_TRUE(mFilterTests.startFilter(*id)); } - // tune test - ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/)); + + if (descrambling.hasFrontendConnection) { + // tune test + ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/)); + } else { + // Start DVR Source + mDvrTests.startPlaybackInputThread(dvrSourceConfig.playbackInputFile, + dvrSourceConfig.settings.playback()); + ASSERT_TRUE(mDvrTests.startDvrPlayback()); + } + ASSERT_TRUE(filterDataOutputTest()); - ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/)); + + if (descrambling.hasFrontendConnection) { + ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/)); + } else { + mDvrTests.stopPlaybackThread(); + ASSERT_TRUE(mDvrTests.stopDvrPlayback()); + } + for (id = filterIds.begin(); id != filterIds.end(); id++) { ASSERT_TRUE(mFilterTests.stopFilter(*id)); } @@ -328,27 +389,45 @@ void TunerDescramblerHidlTest::scrambledBroadcastTest(set m for (id = filterIds.begin(); id != filterIds.end(); id++) { ASSERT_TRUE(mFilterTests.closeFilter(*id)); } + + if (descrambling.hasFrontendConnection) { + ASSERT_TRUE(mFrontendTests.closeFrontend()); + } else { + mDvrTests.closeDvrPlayback(); + } + ASSERT_TRUE(mDemuxTests.closeDemux()); - ASSERT_TRUE(mFrontendTests.closeFrontend()); } TEST_P(TunerFrontendHidlTest, TuneFrontend) { description("Tune one Frontend with specific setting and check Lock event"); + if (!live.hasFrontendConnection) { + return; + } mFrontendTests.tuneTest(frontendMap[live.frontendId]); } TEST_P(TunerFrontendHidlTest, AutoScanFrontend) { description("Run an auto frontend scan with specific setting and check lock scanMessage"); + if (!scan.hasFrontendConnection) { + return; + } mFrontendTests.scanTest(frontendMap[scan.frontendId], FrontendScanType::SCAN_AUTO); } TEST_P(TunerFrontendHidlTest, BlindScanFrontend) { description("Run an blind frontend scan with specific setting and check lock scanMessage"); + if (!scan.hasFrontendConnection) { + return; + } mFrontendTests.scanTest(frontendMap[scan.frontendId], FrontendScanType::SCAN_BLIND); } TEST_P(TunerLnbHidlTest, SendDiseqcMessageToLnb) { description("Open and configure an Lnb with specific settings then send a diseqc msg to it."); + if (!lnbLive.support) { + return; + } if (lnbMap[lnbLive.lnbId].name.compare(emptyHardwareId) == 0) { vector ids; ASSERT_TRUE(mLnbTests.getLnbIds(ids)); @@ -370,6 +449,9 @@ TEST_P(TunerLnbHidlTest, SendDiseqcMessageToLnb) { TEST_P(TunerDemuxHidlTest, openDemux) { description("Open and close a Demux."); + if (!live.hasFrontendConnection) { + return; + } uint32_t feId; uint32_t demuxId; sp demux; @@ -385,6 +467,9 @@ TEST_P(TunerDemuxHidlTest, openDemux) { TEST_P(TunerDemuxHidlTest, getAvSyncTime) { description("Get the A/V sync time from a PCR filter."); + if (!live.hasFrontendConnection) { + return; + } if (live.pcrFilterId.compare(emptyHardwareId) == 0) { return; } @@ -423,6 +508,9 @@ TEST_P(TunerDemuxHidlTest, getAvSyncTime) { TEST_P(TunerFilterHidlTest, StartFilterInDemux) { description("Open and start a filter in Demux."); + if (!live.hasFrontendConnection) { + return; + } // TODO use paramterized tests configSingleFilterInDemuxTest(filterMap[live.videoFilterId], frontendMap[live.frontendId]); } @@ -457,22 +545,34 @@ TEST_P(TunerFilterHidlTest, SetFilterLinkage) { TEST_P(TunerFilterHidlTest, testTimeFilter) { description("Open a timer filter in Demux and set time stamp."); + if (!timeFilter.support) { + return; + } // TODO use paramterized tests testTimeFilter(timeFilterMap[timeFilter.timeFilterId]); } TEST_P(TunerBroadcastHidlTest, BroadcastDataFlowVideoFilterTest) { description("Test Video Filter functionality in Broadcast use case."); + if (!live.hasFrontendConnection) { + return; + } broadcastSingleFilterTest(filterMap[live.videoFilterId], frontendMap[live.frontendId]); } TEST_P(TunerBroadcastHidlTest, BroadcastDataFlowAudioFilterTest) { description("Test Audio Filter functionality in Broadcast use case."); + if (!live.hasFrontendConnection) { + return; + } broadcastSingleFilterTest(filterMap[live.audioFilterId], frontendMap[live.frontendId]); } TEST_P(TunerBroadcastHidlTest, BroadcastDataFlowSectionFilterTest) { description("Test Section Filter functionality in Broadcast use case."); + if (!live.hasFrontendConnection) { + return; + } if (live.sectionFilterId.compare(emptyHardwareId) == 0) { return; } @@ -481,6 +581,9 @@ TEST_P(TunerBroadcastHidlTest, BroadcastDataFlowSectionFilterTest) { TEST_P(TunerBroadcastHidlTest, IonBufferTest) { description("Test the av filter data bufferring."); + if (!live.hasFrontendConnection) { + return; + } broadcastSingleFilterTest(filterMap[live.videoFilterId], frontendMap[live.frontendId]); } @@ -501,6 +604,22 @@ TEST_P(TunerPlaybackHidlTest, PlaybackDataFlowWithTsSectionFilterTest) { playbackSingleFilterTest(filterMap[playback.sectionFilterId], dvrMap[playback.dvrId]); } +TEST_P(TunerPlaybackHidlTest, PlaybackDataFlowWithTsAudioFilterTest) { + description("Feed ts data from playback and configure Ts audio filter to get output"); + if (!playback.support) { + return; + } + playbackSingleFilterTest(filterMap[playback.audioFilterId], dvrMap[playback.dvrId]); +} + +TEST_P(TunerPlaybackHidlTest, PlaybackDataFlowWithTsVideoFilterTest) { + description("Feed ts data from playback and configure Ts video filter to get output"); + if (!playback.support) { + return; + } + playbackSingleFilterTest(filterMap[playback.videoFilterId], dvrMap[playback.dvrId]); +} + TEST_P(TunerRecordHidlTest, AttachFiltersToRecordTest) { description("Attach a single filter to the record dvr test."); // TODO use paramterized tests @@ -535,19 +654,26 @@ TEST_P(TunerDescramblerHidlTest, CreateDescrambler) { if (descrambling.support) { return; } - uint32_t feId; uint32_t demuxId; sp demux; - mFrontendTests.getFrontendIdByType(frontendMap[descrambling.frontendId].type, feId); - ASSERT_TRUE(feId != INVALID_ID); - ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); - ASSERT_TRUE(mFrontendTests.setFrontendCallback()); ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); - ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); + + if (descrambling.hasFrontendConnection) { + uint32_t feId; + mFrontendTests.getFrontendIdByType(frontendMap[descrambling.frontendId].type, feId); + ASSERT_TRUE(feId != INVALID_ID); + ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); + ASSERT_TRUE(mFrontendTests.setFrontendCallback()); + ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); + } + ASSERT_TRUE(mDescramblerTests.openDescrambler(demuxId)); ASSERT_TRUE(mDescramblerTests.closeDescrambler()); ASSERT_TRUE(mDemuxTests.closeDemux()); - ASSERT_TRUE(mFrontendTests.closeFrontend()); + + if (descrambling.hasFrontendConnection) { + ASSERT_TRUE(mFrontendTests.closeFrontend()); + } } TEST_P(TunerDescramblerHidlTest, ScrambledBroadcastDataFlowMediaFiltersTest) { diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h index a1597c7e95..885cafd303 100644 --- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h +++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h @@ -150,10 +150,32 @@ inline void connectHardwaresToTestCases() { }; inline bool validateConnections() { - bool feIsValid = frontendMap.find(live.frontendId) != frontendMap.end() && - frontendMap.find(scan.frontendId) != frontendMap.end(); - feIsValid &= record.support ? frontendMap.find(record.frontendId) != frontendMap.end() : true; - feIsValid &= descrambling.support + if ((!live.hasFrontendConnection || !scan.hasFrontendConnection) && !playback.support) { + ALOGW("[vts config] VTS must support either a DVR source or a Frontend source."); + return false; + } + + if (record.support && !record.hasFrontendConnection && + record.dvrSourceId.compare(emptyHardwareId) == 0) { + ALOGW("[vts config] Record must support either a DVR source or a Frontend source."); + return false; + } + + if (descrambling.support && !descrambling.hasFrontendConnection && + descrambling.dvrSourceId.compare(emptyHardwareId) == 0) { + ALOGW("[vts config] Descrambling must support either a DVR source or a Frontend source."); + return false; + } + + bool feIsValid = live.hasFrontendConnection + ? frontendMap.find(live.frontendId) != frontendMap.end() + : true; + feIsValid &= scan.hasFrontendConnection ? frontendMap.find(scan.frontendId) != frontendMap.end() + : true; + feIsValid &= record.support && record.hasFrontendConnection + ? frontendMap.find(record.frontendId) != frontendMap.end() + : true; + feIsValid &= (descrambling.support && descrambling.hasFrontendConnection) ? frontendMap.find(descrambling.frontendId) != frontendMap.end() : true; feIsValid &= lnbLive.support ? frontendMap.find(lnbLive.frontendId) != frontendMap.end() : true; @@ -165,18 +187,28 @@ inline bool validateConnections() { return false; } - bool dvrIsValid = frontendMap[live.frontendId].isSoftwareFe + bool dvrIsValid = (live.hasFrontendConnection && frontendMap[live.frontendId].isSoftwareFe) ? dvrMap.find(live.dvrSoftwareFeId) != dvrMap.end() : true; dvrIsValid &= playback.support ? dvrMap.find(playback.dvrId) != dvrMap.end() : true; if (record.support) { - if (frontendMap[record.frontendId].isSoftwareFe) { - dvrIsValid &= dvrMap.find(record.dvrSoftwareFeId) != dvrMap.end(); + if (record.hasFrontendConnection) { + if (frontendMap[record.frontendId].isSoftwareFe) { + dvrIsValid &= dvrMap.find(record.dvrSoftwareFeId) != dvrMap.end(); + } + } else { + dvrIsValid &= dvrMap.find(record.dvrSourceId) != dvrMap.end(); } dvrIsValid &= dvrMap.find(record.dvrRecordId) != dvrMap.end(); } - if (descrambling.support && frontendMap[descrambling.frontendId].isSoftwareFe) { - dvrIsValid &= dvrMap.find(descrambling.dvrSoftwareFeId) != dvrMap.end(); + if (descrambling.support) { + if (descrambling.hasFrontendConnection) { + if (frontendMap[descrambling.frontendId].isSoftwareFe) { + dvrIsValid &= dvrMap.find(descrambling.dvrSoftwareFeId) != dvrMap.end(); + } + } else { + dvrIsValid &= dvrMap.find(descrambling.dvrSourceId) != dvrMap.end(); + } } if (!dvrIsValid) { diff --git a/tv/tuner/1.1/default/Demux.cpp b/tv/tuner/1.1/default/Demux.cpp index db25c2e43d..15b8e6c82a 100644 --- a/tv/tuner/1.1/default/Demux.cpp +++ b/tv/tuner/1.1/default/Demux.cpp @@ -392,6 +392,10 @@ void Demux::setIsRecording(bool isRecording) { mIsRecording = isRecording; } +bool Demux::isRecording() { + return mIsRecording; +} + bool Demux::attachRecordFilter(uint64_t filterId) { if (mFilters[filterId] == nullptr || mDvrRecord == nullptr || !mFilters[filterId]->isRecordFilter()) { diff --git a/tv/tuner/1.1/default/Demux.h b/tv/tuner/1.1/default/Demux.h index 5212eae02d..ce46f9c10c 100644 --- a/tv/tuner/1.1/default/Demux.h +++ b/tv/tuner/1.1/default/Demux.h @@ -85,6 +85,7 @@ class Demux : public IDemux { void updateMediaFilterOutput(uint64_t filterId, vector data, uint64_t pts); uint16_t getFilterTpid(uint64_t filterId); void setIsRecording(bool isRecording); + bool isRecording(); void startFrontendInputLoop(); /** diff --git a/tv/tuner/1.1/default/Dvr.cpp b/tv/tuner/1.1/default/Dvr.cpp index 93bb6a875b..c487d98c36 100644 --- a/tv/tuner/1.1/default/Dvr.cpp +++ b/tv/tuner/1.1/default/Dvr.cpp @@ -218,19 +218,26 @@ void Dvr::playbackThreadLoop() { continue; } + // If the both dvr playback and dvr record are created, the playback will be treated as + // the source of the record. isVirtualFrontend set to true would direct the dvr playback + // input to the demux record filters or live broadcast filters. + bool isRecording = mDemux->isRecording(); + bool isVirtualFrontend = isRecording; + if (mDvrSettings.playback().dataFormat == DataFormat::ES) { - if (!processEsDataOnPlayback(false /*isVirtualFrontend*/, false /*isRecording*/)) { + if (!processEsDataOnPlayback(isVirtualFrontend, isRecording)) { ALOGE("[Dvr] playback es data failed to be filtered. Ending thread"); break; } maySendPlaybackStatusCallback(); continue; } + // Our current implementation filter the data and write it into the filter FMQ immediately // after the DATA_READY from the VTS/framework // This is for the non-ES data source, real playback use case handling. - if (!readPlaybackFMQ(false /*isVirtualFrontend*/, false /*isRecording*/) || - !startFilterDispatcher(false /*isVirtualFrontend*/, false /*isRecording*/)) { + if (!readPlaybackFMQ(isVirtualFrontend, isRecording) || + !startFilterDispatcher(isVirtualFrontend, isRecording)) { ALOGE("[Dvr] playback data failed to be filtered. Ending thread"); break; } diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp index 10808614f5..e70c320bf2 100644 --- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp @@ -22,10 +22,6 @@ AssertionResult TunerBroadcastHidlTest::filterDataOutputTest() { return filterDataOutputTestBase(mFilterTests); } -AssertionResult TunerRecordHidlTest::filterDataOutputTest() { - return filterDataOutputTestBase(mFilterTests); -} - void TunerFilterHidlTest::configSingleFilterInDemuxTest(FilterConfig1_1 filterConf, FrontendConfig1_1 frontendConf) { uint32_t feId; @@ -70,6 +66,9 @@ void TunerFilterHidlTest::reconfigSingleFilterInDemuxTest(FilterConfig1_1 filter ASSERT_TRUE(feId != INVALID_ID); ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); ASSERT_TRUE(mFrontendTests.setFrontendCallback()); + if (frontendConf.config1_0.isSoftwareFe) { + mFrontendTests.setSoftwareFrontendDvrConfig(dvrMap[live.dvrSoftwareFeId]); + } ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); mFrontendTests.setDemux(demux); @@ -103,6 +102,9 @@ void TunerBroadcastHidlTest::mediaFilterUsingSharedMemoryTest(FilterConfig1_1 fi ASSERT_TRUE(feId != INVALID_ID); ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); ASSERT_TRUE(mFrontendTests.setFrontendCallback()); + if (frontendConf.config1_0.isSoftwareFe) { + mFrontendTests.setSoftwareFrontendDvrConfig(dvrMap[live.dvrSoftwareFeId]); + } ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); mFrontendTests.setDemux(demux); @@ -129,21 +131,33 @@ void TunerBroadcastHidlTest::mediaFilterUsingSharedMemoryTest(FilterConfig1_1 fi void TunerRecordHidlTest::recordSingleFilterTest(FilterConfig1_1 filterConf, FrontendConfig1_1 frontendConf, DvrConfig dvrConf) { - uint32_t feId; uint32_t demuxId; sp demux; + ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); + mDvrTests.setDemux(demux); + + DvrConfig dvrSourceConfig; + if (record.hasFrontendConnection) { + uint32_t feId; + mFrontendTests.getFrontendIdByType(frontendConf.config1_0.type, feId); + ASSERT_TRUE(feId != INVALID_ID); + ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); + ASSERT_TRUE(mFrontendTests.setFrontendCallback()); + if (frontendConf.config1_0.isSoftwareFe) { + mFrontendTests.setSoftwareFrontendDvrConfig(dvrMap[record.dvrSoftwareFeId]); + } + ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); + mFrontendTests.setDvrTests(mDvrTests); + } else { + dvrSourceConfig = dvrMap[record.dvrSourceId]; + ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrSourceConfig.type, dvrSourceConfig.bufferSize)); + ASSERT_TRUE(mDvrTests.configDvrPlayback(dvrSourceConfig.settings)); + ASSERT_TRUE(mDvrTests.getDvrPlaybackMQDescriptor()); + } + uint64_t filterId; sp filter; - - mFrontendTests.getFrontendIdByType(frontendConf.config1_0.type, feId); - ASSERT_TRUE(feId != INVALID_ID); - ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); - ASSERT_TRUE(mFrontendTests.setFrontendCallback()); - ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); - ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); mFilterTests.setDemux(demux); - mDvrTests.setDemux(demux); - mFrontendTests.setDvrTests(mDvrTests); ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrConf.type, dvrConf.bufferSize)); ASSERT_TRUE(mDvrTests.configDvrRecord(dvrConf.settings)); ASSERT_TRUE(mDvrTests.getDvrRecordMQDescriptor()); @@ -158,22 +172,46 @@ void TunerRecordHidlTest::recordSingleFilterTest(FilterConfig1_1 filterConf, ASSERT_TRUE(mDvrTests.attachFilterToDvr(filter)); ASSERT_TRUE(mDvrTests.startDvrRecord()); ASSERT_TRUE(mFilterTests.startFilter(filterId)); - ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/)); + + if (record.hasFrontendConnection) { + ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/)); + } else { + // Start DVR Source + mDvrTests.startPlaybackInputThread(dvrSourceConfig.playbackInputFile, + dvrSourceConfig.settings.playback()); + ASSERT_TRUE(mDvrTests.startDvrPlayback()); + } + mDvrTests.testRecordOutput(); - ASSERT_TRUE(filterDataOutputTest()); mDvrTests.stopRecordThread(); - ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/)); + + if (record.hasFrontendConnection) { + ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/)); + } else { + mDvrTests.stopPlaybackThread(); + ASSERT_TRUE(mDvrTests.stopDvrPlayback()); + } + ASSERT_TRUE(mFilterTests.stopFilter(filterId)); ASSERT_TRUE(mDvrTests.stopDvrRecord()); ASSERT_TRUE(mDvrTests.detachFilterToDvr(filter)); ASSERT_TRUE(mFilterTests.closeFilter(filterId)); mDvrTests.closeDvrRecord(); + + if (record.hasFrontendConnection) { + ASSERT_TRUE(mFrontendTests.closeFrontend()); + } else { + mDvrTests.closeDvrPlayback(); + } + ASSERT_TRUE(mDemuxTests.closeDemux()); - ASSERT_TRUE(mFrontendTests.closeFrontend()); } TEST_P(TunerFilterHidlTest, StartFilterInDemux) { description("Open and start a filter in Demux."); + if (!live.hasFrontendConnection) { + return; + } // TODO use parameterized tests configSingleFilterInDemuxTest(filterMap[live.videoFilterId], frontendMap[live.frontendId]); } @@ -181,6 +219,9 @@ TEST_P(TunerFilterHidlTest, StartFilterInDemux) { TEST_P(TunerFilterHidlTest, ConfigIpFilterInDemuxWithCid) { description("Open and configure an ip filter in Demux."); // TODO use parameterized tests + if (!live.hasFrontendConnection) { + return; + } if (live.ipFilterId.compare(emptyHardwareId) == 0) { return; } @@ -189,6 +230,9 @@ TEST_P(TunerFilterHidlTest, ConfigIpFilterInDemuxWithCid) { TEST_P(TunerFilterHidlTest, ReconfigFilterToReceiveStartId) { description("Recofigure and restart a filter to test start id."); + if (!live.hasFrontendConnection) { + return; + } // TODO use parameterized tests reconfigSingleFilterInDemuxTest(filterMap[live.videoFilterId], filterMap[live.videoFilterId], frontendMap[live.frontendId]); @@ -205,16 +249,25 @@ TEST_P(TunerRecordHidlTest, RecordDataFlowWithTsRecordFilterTest) { TEST_P(TunerFrontendHidlTest, TuneFrontendWithFrontendSettingsExt1_1) { description("Tune one Frontend with v1_1 extended setting and check Lock event"); + if (!live.hasFrontendConnection) { + return; + } mFrontendTests.tuneTest(frontendMap[live.frontendId]); } TEST_P(TunerFrontendHidlTest, BlindScanFrontendWithEndFrequency) { description("Run an blind frontend scan with v1_1 extended setting and check lock scanMessage"); + if (!scan.hasFrontendConnection) { + return; + } mFrontendTests.scanTest(frontendMap[scan.frontendId], FrontendScanType::SCAN_BLIND); } TEST_P(TunerBroadcastHidlTest, MediaFilterWithSharedMemoryHandle) { description("Test the Media Filter with shared memory handle"); + if (!live.hasFrontendConnection) { + return; + } mediaFilterUsingSharedMemoryTest(filterMap[live.videoFilterId], frontendMap[live.frontendId]); } @@ -225,6 +278,9 @@ TEST_P(TunerFrontendHidlTest, GetFrontendDtmbCaps) { TEST_P(TunerFrontendHidlTest, LinkToCiCam) { description("Test Frontend link to CiCam"); + if (!live.hasFrontendConnection) { + return; + } if (!frontendMap[live.frontendId].canConnectToCiCam) { return; } diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h index 863f649dd8..007e3d53df 100644 --- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h @@ -97,7 +97,6 @@ class TunerRecordHidlTest : public testing::TestWithParam { void recordSingleFilterTest(FilterConfig1_1 filterConf, FrontendConfig1_1 frontendConf, DvrConfig dvrConf); - AssertionResult filterDataOutputTest(); sp mService; FrontendTests mFrontendTests; diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h index 390bd4c2d3..2b5ad466b8 100644 --- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h @@ -148,6 +148,11 @@ inline void connectHardwaresToTestCases() { }; inline bool validateConnections() { + if (record.support && !record.hasFrontendConnection && + record.dvrSourceId.compare(emptyHardwareId) == 0) { + ALOGW("[vts config] Record must support either a DVR source or a Frontend source."); + return false; + } bool feIsValid = frontendMap.find(live.frontendId) != frontendMap.end() && frontendMap.find(scan.frontendId) != frontendMap.end(); feIsValid &= record.support ? frontendMap.find(record.frontendId) != frontendMap.end() : true; @@ -160,9 +165,14 @@ inline bool validateConnections() { bool dvrIsValid = frontendMap[live.frontendId].config1_0.isSoftwareFe ? dvrMap.find(live.dvrSoftwareFeId) != dvrMap.end() : true; + if (record.support) { - if (frontendMap[record.frontendId].config1_0.isSoftwareFe) { - dvrIsValid &= dvrMap.find(record.dvrSoftwareFeId) != dvrMap.end(); + if (record.hasFrontendConnection) { + if (frontendMap[record.frontendId].config1_0.isSoftwareFe) { + dvrIsValid &= dvrMap.find(record.dvrSoftwareFeId) != dvrMap.end(); + } + } else { + dvrIsValid &= dvrMap.find(record.dvrSourceId) != dvrMap.end(); } dvrIsValid &= dvrMap.find(record.dvrRecordId) != dvrMap.end(); } diff --git a/tv/tuner/config/TunerTestingConfigReaderV1_0.h b/tv/tuner/config/TunerTestingConfigReaderV1_0.h index cff4af11d8..f7f72b038e 100644 --- a/tv/tuner/config/TunerTestingConfigReaderV1_0.h +++ b/tv/tuner/config/TunerTestingConfigReaderV1_0.h @@ -123,6 +123,7 @@ struct DescramblerConfig { }; struct LiveBroadcastHardwareConnections { + bool hasFrontendConnection; string frontendId; string dvrSoftwareFeId; string audioFilterId; @@ -134,6 +135,7 @@ struct LiveBroadcastHardwareConnections { }; struct ScanHardwareConnections { + bool hasFrontendConnection; string frontendId; }; @@ -149,19 +151,23 @@ struct DvrPlaybackHardwareConnections { struct DvrRecordHardwareConnections { bool support; + bool hasFrontendConnection; string frontendId; string dvrRecordId; string dvrSoftwareFeId; string recordFilterId; + string dvrSourceId; }; struct DescramblingHardwareConnections { bool support; + bool hasFrontendConnection; string frontendId; string dvrSoftwareFeId; string audioFilterId; string videoFilterId; string descramblerId; + string dvrSourceId; /* list string of extra filters; */ }; @@ -402,7 +408,14 @@ struct TunerTestingConfigReader1_0 { } static void connectLiveBroadcast(LiveBroadcastHardwareConnections& live) { - auto liveConfig = *getDataFlowConfiguration().getFirstClearLiveBroadcast(); + auto dataFlow = getDataFlowConfiguration(); + if (dataFlow.hasClearLiveBroadcast()) { + live.hasFrontendConnection = true; + } else { + live.hasFrontendConnection = false; + return; + } + auto liveConfig = *dataFlow.getFirstClearLiveBroadcast(); live.frontendId = liveConfig.getFrontendConnection(); live.audioFilterId = liveConfig.getAudioFilterConnection(); @@ -428,8 +441,15 @@ struct TunerTestingConfigReader1_0 { } static void connectScan(ScanHardwareConnections& scan) { - auto scanConfig = getDataFlowConfiguration().getFirstScan(); - scan.frontendId = scanConfig->getFrontendConnection(); + auto dataFlow = getDataFlowConfiguration(); + if (dataFlow.hasScan()) { + scan.hasFrontendConnection = true; + } else { + scan.hasFrontendConnection = false; + return; + } + auto scanConfig = *dataFlow.getFirstScan(); + scan.frontendId = scanConfig.getFrontendConnection(); } static void connectDvrPlayback(DvrPlaybackHardwareConnections& playback) { @@ -437,6 +457,7 @@ struct TunerTestingConfigReader1_0 { if (dataFlow.hasDvrPlayback()) { playback.support = true; } else { + playback.support = false; return; } auto playbackConfig = *dataFlow.getFirstDvrPlayback(); @@ -455,6 +476,7 @@ struct TunerTestingConfigReader1_0 { if (dataFlow.hasDvrRecord()) { record.support = true; } else { + record.support = false; return; } auto recordConfig = *dataFlow.getFirstDvrRecord(); @@ -464,6 +486,13 @@ struct TunerTestingConfigReader1_0 { if (recordConfig.hasDvrSoftwareFeConnection()) { record.dvrSoftwareFeId = recordConfig.getDvrSoftwareFeConnection(); } + if (recordConfig.getHasFrontendConnection()) { + record.hasFrontendConnection = true; + record.dvrSourceId = emptyHardwareId; + } else { + record.hasFrontendConnection = false; + record.dvrSourceId = recordConfig.getDvrSourceConnection(); + } } static void connectDescrambling(DescramblingHardwareConnections& descrambling) { @@ -471,6 +500,7 @@ struct TunerTestingConfigReader1_0 { if (dataFlow.hasDescrambling()) { descrambling.support = true; } else { + descrambling.support = false; return; } auto descConfig = *dataFlow.getFirstDescrambling(); @@ -481,6 +511,13 @@ struct TunerTestingConfigReader1_0 { if (descConfig.hasDvrSoftwareFeConnection()) { descrambling.dvrSoftwareFeId = descConfig.getDvrSoftwareFeConnection(); } + if (descConfig.getHasFrontendConnection()) { + descrambling.hasFrontendConnection = true; + descrambling.dvrSourceId = emptyHardwareId; + } else { + descrambling.hasFrontendConnection = false; + descrambling.dvrSourceId = descConfig.getDvrSourceConnection(); + } } static void connectLnbLive(LnbLiveHardwareConnections& lnbLive) { @@ -488,6 +525,7 @@ struct TunerTestingConfigReader1_0 { if (dataFlow.hasLnbLive()) { lnbLive.support = true; } else { + lnbLive.support = false; return; } auto lnbLiveConfig = *dataFlow.getFirstLnbLive(); @@ -507,6 +545,7 @@ struct TunerTestingConfigReader1_0 { if (dataFlow.hasLnbRecord()) { lnbRecord.support = true; } else { + lnbRecord.support = false; return; } auto lnbRecordConfig = *dataFlow.getFirstLnbRecord(); @@ -526,6 +565,7 @@ struct TunerTestingConfigReader1_0 { if (dataFlow.hasTimeFilter()) { timeFilter.support = true; } else { + timeFilter.support = false; return; } auto timeFilterConfig = *dataFlow.getFirstTimeFilter(); diff --git a/tv/tuner/config/api/current.txt b/tv/tuner/config/api/current.txt index a9602e705d..ef733151b1 100644 --- a/tv/tuner/config/api/current.txt +++ b/tv/tuner/config/api/current.txt @@ -54,12 +54,16 @@ package android.media.tuner.testing.configuration.V1_0 { method @Nullable public String getAudioFilterConnection(); method @Nullable public String getDescramblerConnection(); method @Nullable public String getDvrSoftwareFeConnection(); + method @Nullable public String getDvrSourceConnection(); method @Nullable public String getFrontendConnection(); + method @Nullable public boolean getHasFrontendConnection(); method @Nullable public String getVideoFilterConnection(); method public void setAudioFilterConnection(@Nullable String); method public void setDescramblerConnection(@Nullable String); method public void setDvrSoftwareFeConnection(@Nullable String); + method public void setDvrSourceConnection(@Nullable String); method public void setFrontendConnection(@Nullable String); + method public void setHasFrontendConnection(@Nullable boolean); method public void setVideoFilterConnection(@Nullable String); } @@ -79,11 +83,15 @@ package android.media.tuner.testing.configuration.V1_0 { ctor public DataFlowConfiguration.DvrRecord(); method @Nullable public String getDvrRecordConnection(); method @Nullable public String getDvrSoftwareFeConnection(); + method @Nullable public String getDvrSourceConnection(); method @Nullable public String getFrontendConnection(); + method @Nullable public boolean getHasFrontendConnection(); method @Nullable public String getRecordFilterConnection(); method public void setDvrRecordConnection(@Nullable String); method public void setDvrSoftwareFeConnection(@Nullable String); + method public void setDvrSourceConnection(@Nullable String); method public void setFrontendConnection(@Nullable String); + method public void setHasFrontendConnection(@Nullable boolean); method public void setRecordFilterConnection(@Nullable String); } diff --git a/tv/tuner/config/sample_tuner_vts_config_1_0.xml b/tv/tuner/config/sample_tuner_vts_config_1_0.xml index 570171edb7..26240765d6 100644 --- a/tv/tuner/config/sample_tuner_vts_config_1_0.xml +++ b/tv/tuner/config/sample_tuner_vts_config_1_0.xml @@ -196,7 +196,8 @@ sectionFilterConnection="FILTER_TS_SECTION_0" dvrSoftwareFeConnection="DVR_PLAYBACK_0"/> - - diff --git a/tv/tuner/config/sample_tuner_vts_config_1_1.xml b/tv/tuner/config/sample_tuner_vts_config_1_1.xml index 191e51cb81..8c99207a69 100644 --- a/tv/tuner/config/sample_tuner_vts_config_1_1.xml +++ b/tv/tuner/config/sample_tuner_vts_config_1_1.xml @@ -145,14 +145,15 @@ audioFilterConnection="FILTER_AUDIO_DEFAULT" videoFilterConnection="FILTER_VIDEO_DEFAULT" ipFilterConnection="FILTER_IP_IP_0" - dvrSoftwareFeConnection="DVR_PLAYBACK_0"/> + dvrSoftwareFeConnection="DVR_PLAYBACK_1"/> - - + dvrSoftwareFeConnection="DVR_PLAYBACK_1"/> diff --git a/tv/tuner/config/tuner_testing_dynamic_configuration.xsd b/tv/tuner/config/tuner_testing_dynamic_configuration.xsd index 3303657876..52168374f7 100644 --- a/tv/tuner/config/tuner_testing_dynamic_configuration.xsd +++ b/tv/tuner/config/tuner_testing_dynamic_configuration.xsd @@ -587,7 +587,9 @@ - + + @@ -600,20 +602,27 @@ - + + + + - + + + @@ -627,10 +636,15 @@ - + + + - + + + -- GitLab From 669be8417e4d23f41af15ebc6d4b9bab10376b92 Mon Sep 17 00:00:00 2001 From: Yu-Han Yang Date: Mon, 26 Apr 2021 20:17:53 -0700 Subject: [PATCH 633/790] Check gnssPowerStats increase after getting a location Bug: 168123084 Test: on device Change-Id: I5a306f91d1223cdc9f3616583d59cd2c707c80ea --- gnss/aidl/default/Gnss.cpp | 6 ++- gnss/aidl/default/Gnss.h | 2 + gnss/aidl/default/GnssHidlHal.cpp | 14 +++++- gnss/aidl/default/GnssHidlHal.h | 2 + gnss/aidl/default/GnssPowerIndication.cpp | 12 +++-- gnss/aidl/default/GnssPowerIndication.h | 4 ++ gnss/aidl/vts/gnss_hal_test_cases.cpp | 45 ++++++++++++++++++- .../utils/default/include/v2_1/GnssTemplate.h | 9 +++- 8 files changed, 86 insertions(+), 8 deletions(-) diff --git a/gnss/aidl/default/Gnss.cpp b/gnss/aidl/default/Gnss.cpp index 435afa3576..6061eec817 100644 --- a/gnss/aidl/default/Gnss.cpp +++ b/gnss/aidl/default/Gnss.cpp @@ -20,7 +20,6 @@ #include #include "GnssConfiguration.h" #include "GnssMeasurementInterface.h" -#include "GnssPowerIndication.h" #include "GnssPsds.h" namespace aidl::android::hardware::gnss { @@ -73,8 +72,11 @@ ndk::ScopedAStatus Gnss::getExtensionGnssConfiguration( ndk::ScopedAStatus Gnss::getExtensionGnssPowerIndication( std::shared_ptr* iGnssPowerIndication) { ALOGD("Gnss::getExtensionGnssPowerIndication"); + if (mGnssPowerIndication == nullptr) { + mGnssPowerIndication = SharedRefBase::make(); + } - *iGnssPowerIndication = SharedRefBase::make(); + *iGnssPowerIndication = mGnssPowerIndication; return ndk::ScopedAStatus::ok(); } diff --git a/gnss/aidl/default/Gnss.h b/gnss/aidl/default/Gnss.h index bccc7f2007..76ebe4d126 100644 --- a/gnss/aidl/default/Gnss.h +++ b/gnss/aidl/default/Gnss.h @@ -22,6 +22,7 @@ #include #include #include "GnssConfiguration.h" +#include "GnssPowerIndication.h" namespace aidl::android::hardware::gnss { @@ -38,6 +39,7 @@ class Gnss : public BnGnss { std::shared_ptr* iGnssMeasurement) override; std::shared_ptr mGnssConfiguration; + std::shared_ptr mGnssPowerIndication; private: static std::shared_ptr sGnssCallback; diff --git a/gnss/aidl/default/GnssHidlHal.cpp b/gnss/aidl/default/GnssHidlHal.cpp index 9529ec9f33..263715c47a 100644 --- a/gnss/aidl/default/GnssHidlHal.cpp +++ b/gnss/aidl/default/GnssHidlHal.cpp @@ -31,11 +31,19 @@ GnssHidlHal::GnssHidlHal(const std::shared_ptr& gnssAidl) : mGnssAidl(gnss } else { mGnssConfigurationAidl = iGnss->mGnssConfiguration; } + + std::shared_ptr iGnssPowerIndication; + status = iGnss->getExtensionGnssPowerIndication(&iGnssPowerIndication); + if (!status.isOk()) { + ALOGE("Failed to getExtensionGnssPowerIndication."); + } else { + mGnssPowerIndicationAidl = iGnss->mGnssPowerIndication; + } }; hidl_vec GnssHidlHal::filterBlocklistedSatellitesV2_1( hidl_vec gnssSvInfoList) { - ALOGD("filterBlocklistSatellitesV2_1 - overridden by GnssHidlHal class"); + ALOGD("GnssHidlHal::filterBlocklistSatellitesV2_1"); if (mGnssConfigurationAidl == nullptr) { ALOGE("Handle to AIDL GnssConfiguration is not available."); return gnssSvInfoList; @@ -51,4 +59,8 @@ hidl_vec GnssHidlHal::filterBlocklistedSatellitesV2_1( return gnssSvInfoList; } +void GnssHidlHal::notePowerConsumption() { + mGnssPowerIndicationAidl->notePowerConsumption(); +} + } // namespace aidl::android::hardware::gnss diff --git a/gnss/aidl/default/GnssHidlHal.h b/gnss/aidl/default/GnssHidlHal.h index 93a79a150a..5fb4f972de 100644 --- a/gnss/aidl/default/GnssHidlHal.h +++ b/gnss/aidl/default/GnssHidlHal.h @@ -32,9 +32,11 @@ class GnssHidlHal : public ::android::hardware::gnss::common::implementation::Gn filterBlocklistedSatellitesV2_1( hidl_vec<::android::hardware::gnss::V2_1::IGnssCallback::GnssSvInfo> gnssSvInfoList) override; + void notePowerConsumption() override; std::shared_ptr mGnssAidl; std::shared_ptr mGnssConfigurationAidl; + std::shared_ptr mGnssPowerIndicationAidl; }; } // namespace aidl::android::hardware::gnss diff --git a/gnss/aidl/default/GnssPowerIndication.cpp b/gnss/aidl/default/GnssPowerIndication.cpp index 429cc8c0e0..4dec1c6a85 100644 --- a/gnss/aidl/default/GnssPowerIndication.cpp +++ b/gnss/aidl/default/GnssPowerIndication.cpp @@ -50,13 +50,19 @@ ndk::ScopedAStatus GnssPowerIndication::requestGnssPowerStats() { }; GnssPowerStats gnssPowerStats = { .elapsedRealtime = elapsedRealtime, - .totalEnergyMilliJoule = 1.59975e+3, - .singlebandTrackingModeEnergyMilliJoule = 1.2342e+3, - .multibandTrackingModeEnergyMilliJoule = 3.653e+2, + .totalEnergyMilliJoule = 1.500e+3 + numLocationReported * 22.0, + .singlebandTrackingModeEnergyMilliJoule = 0.0, + .multibandTrackingModeEnergyMilliJoule = 1.28e+2 + numLocationReported * 4.0, + .singlebandAcquisitionModeEnergyMilliJoule = 0.0, + .multibandAcquisitionModeEnergyMilliJoule = 3.65e+2 + numLocationReported * 15.0, .otherModesEnergyMilliJoule = {1.232e+2, 3.234e+3}, }; sCallback->gnssPowerStatsCb(gnssPowerStats); return ndk::ScopedAStatus::ok(); } +void GnssPowerIndication::notePowerConsumption() { + numLocationReported++; +} + } // namespace aidl::android::hardware::gnss diff --git a/gnss/aidl/default/GnssPowerIndication.h b/gnss/aidl/default/GnssPowerIndication.h index e32fd72ac0..93ca0b7097 100644 --- a/gnss/aidl/default/GnssPowerIndication.h +++ b/gnss/aidl/default/GnssPowerIndication.h @@ -26,12 +26,16 @@ struct GnssPowerIndication : public BnGnssPowerIndication { const std::shared_ptr& callback) override; ndk::ScopedAStatus requestGnssPowerStats() override; + void notePowerConsumption(); + private: // Guarded by mMutex static std::shared_ptr sCallback; // Synchronization lock for sCallback mutable std::mutex mMutex; + + int numLocationReported; }; } // namespace aidl::android::hardware::gnss diff --git a/gnss/aidl/vts/gnss_hal_test_cases.cpp b/gnss/aidl/vts/gnss_hal_test_cases.cpp index ae0551d63d..9086b3d966 100644 --- a/gnss/aidl/vts/gnss_hal_test_cases.cpp +++ b/gnss/aidl/vts/gnss_hal_test_cases.cpp @@ -30,6 +30,7 @@ using android::hardware::gnss::BlocklistedSource; using android::hardware::gnss::ElapsedRealtime; using android::hardware::gnss::GnssClock; using android::hardware::gnss::GnssMeasurement; +using android::hardware::gnss::GnssPowerStats; using android::hardware::gnss::IGnss; using android::hardware::gnss::IGnssConfiguration; using android::hardware::gnss::IGnssMeasurementCallback; @@ -168,9 +169,12 @@ TEST_P(GnssHalTest, TestGnssMeasurementExtension) { * TestGnssPowerIndication * 1. Gets the GnssPowerIndicationExtension. * 2. Sets a GnssPowerIndicationCallback. - * 3. + * 3. Requests and verifies the 1st GnssPowerStats is received. + * 4. Gets a location. + * 5. Requests the 2nd GnssPowerStats, and verifies it has larger values than the 1st one. */ TEST_P(GnssHalTest, TestGnssPowerIndication) { + // Set up gnssPowerIndication and callback sp iGnssPowerIndication; auto status = aidl_gnss_hal_->getExtensionGnssPowerIndication(&iGnssPowerIndication); ASSERT_TRUE(status.isOk()); @@ -186,10 +190,49 @@ TEST_P(GnssHalTest, TestGnssPowerIndication) { EXPECT_EQ(gnssPowerIndicationCallback->capabilities_cbq_.calledCount(), 1); + // Request and verify a GnssPowerStats is received + gnssPowerIndicationCallback->gnss_power_stats_cbq_.reset(); iGnssPowerIndication->requestGnssPowerStats(); + EXPECT_TRUE(gnssPowerIndicationCallback->gnss_power_stats_cbq_.retrieve( gnssPowerIndicationCallback->last_gnss_power_stats_, kTimeoutSec)); EXPECT_EQ(gnssPowerIndicationCallback->gnss_power_stats_cbq_.calledCount(), 1); + auto powerStats1 = gnssPowerIndicationCallback->last_gnss_power_stats_; + + // Get a location and request another GnssPowerStats + gnss_cb_->location_cbq_.reset(); + StartAndCheckFirstLocation(); + + // Request and verify the 2nd GnssPowerStats has larger values than the 1st one + iGnssPowerIndication->requestGnssPowerStats(); + + EXPECT_TRUE(gnssPowerIndicationCallback->gnss_power_stats_cbq_.retrieve( + gnssPowerIndicationCallback->last_gnss_power_stats_, kTimeoutSec)); + EXPECT_EQ(gnssPowerIndicationCallback->gnss_power_stats_cbq_.calledCount(), 2); + auto powerStats2 = gnssPowerIndicationCallback->last_gnss_power_stats_; + + // Elapsed realtime must increase + EXPECT_GT(powerStats2.elapsedRealtime.timestampNs, powerStats1.elapsedRealtime.timestampNs); + + // Total energy must increase + EXPECT_GT(powerStats2.totalEnergyMilliJoule, powerStats1.totalEnergyMilliJoule); + + // At least oone of singleband and multiband acquisition energy must increase + bool singlebandAcqEnergyIncreased = powerStats2.singlebandAcquisitionModeEnergyMilliJoule > + powerStats1.singlebandAcquisitionModeEnergyMilliJoule; + bool multibandAcqEnergyIncreased = powerStats2.multibandAcquisitionModeEnergyMilliJoule > + powerStats1.multibandAcquisitionModeEnergyMilliJoule; + EXPECT_TRUE(singlebandAcqEnergyIncreased || multibandAcqEnergyIncreased); + + // At least one of singleband and multiband tracking energy must increase + bool singlebandTrackingEnergyIncreased = powerStats2.singlebandTrackingModeEnergyMilliJoule > + powerStats1.singlebandTrackingModeEnergyMilliJoule; + bool multibandTrackingEnergyIncreased = powerStats2.multibandTrackingModeEnergyMilliJoule > + powerStats1.multibandTrackingModeEnergyMilliJoule; + EXPECT_TRUE(singlebandTrackingEnergyIncreased || multibandTrackingEnergyIncreased); + + // Clean up + StopAndClearLocations(); } /* diff --git a/gnss/common/utils/default/include/v2_1/GnssTemplate.h b/gnss/common/utils/default/include/v2_1/GnssTemplate.h index a6e8f58206..a1d698167c 100644 --- a/gnss/common/utils/default/include/v2_1/GnssTemplate.h +++ b/gnss/common/utils/default/include/v2_1/GnssTemplate.h @@ -132,6 +132,7 @@ struct GnssTemplate : public T_IGnss { mutable std::mutex mMutex; virtual hidl_vec filterBlocklistedSatellitesV2_1( hidl_vec gnssSvInfoList); + virtual void notePowerConsumption(); }; template @@ -219,6 +220,7 @@ Return GnssTemplate::start() { auto svStatus = filterBlocklistedSatellitesV2_1(Utils::getMockSvInfoListV2_1()); this->reportSvStatus(svStatus); auto currentLocation = getLocationFromHW(); + notePowerConsumption(); if (mGnssFd != -1) { // Only report location if the return from hardware is valid // note that we can not merge these two "if" together, if didn't @@ -245,7 +247,7 @@ Return GnssTemplate::start() { template hidl_vec GnssTemplate::filterBlocklistedSatellitesV2_1( hidl_vec gnssSvInfoList) { - ALOGD("filterBlocklistedSatellitesV2_1"); + ALOGD("GnssTemplate::filterBlocklistedSatellitesV2_1"); for (uint32_t i = 0; i < gnssSvInfoList.size(); i++) { if (mGnssConfiguration->isBlacklistedV2_1(gnssSvInfoList[i])) { gnssSvInfoList[i].v2_0.v1_0.svFlag &= @@ -255,6 +257,11 @@ hidl_vec GnssTemplate::filterBlocklist return gnssSvInfoList; } +template +void GnssTemplate::notePowerConsumption() { + ALOGD("GnssTemplate::notePowerConsumption"); +} + template Return GnssTemplate::stop() { ALOGD("stop"); -- GitLab From 331db00232a494768e7ecf6b19629a17116ee71e Mon Sep 17 00:00:00 2001 From: Yu-Han Yang Date: Tue, 27 Apr 2021 09:31:49 -0700 Subject: [PATCH 634/790] Add HAL doc to clarify ISB sign Bug: 162508535 Test: doc only Change-Id: I8b79a153ebcd577dbbfc64b1c4dd6d7e621977a1 --- current.txt | 1 + gnss/2.1/IGnssMeasurementCallback.hal | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/current.txt b/current.txt index ac65326749..bdbe1b8082 100644 --- a/current.txt +++ b/current.txt @@ -771,6 +771,7 @@ e042522daa4b5f7fd4a0a19bcdadb93c79a1b04c09ef2c9813a3a8941032f3f5 android.hardwar c2f64133b83ede65c9939ef97ab5bd867b73faf3dba0e7e69f77c3c43d9e487e android.hardware.contexthub@1.0::IContexthubCallback bda492ec4021d13869de72bd6f8c15c5837b78d6136b8d538efec5320573a5ec android.hardware.gnss@1.0::IGnssMeasurementCallback 6a271e493907e8ba20912e42771bd0d99ae45431a851d5675ef9496d02510a34 android.hardware.gnss@1.1::IGnssMeasurementCallback +11e9e1a1fd0c9b3d9648750d4b10dc2a839d3a6688904c3fc49500a4e7ca75b0 android.hardware.gnss@2.1::IGnssMeasurementCallback 2c331a9605f3a08d9c1e0a36169ca57758bc43c11a78ef3f3730509885e52c15 android.hardware.graphics.composer@2.4::IComposerClient 3da3ce039247872d95c6bd48621dbfdfa1c2d2a91a90f257862f87ee2bc46300 android.hardware.health@2.1::types 9679f27a42f75781c8993ef163ed92808a1928de186639834841d0b8e326e63d android.hardware.gatekeeper@1.0::IGatekeeper diff --git a/gnss/2.1/IGnssMeasurementCallback.hal b/gnss/2.1/IGnssMeasurementCallback.hal index 60a542330d..beef4fd949 100644 --- a/gnss/2.1/IGnssMeasurementCallback.hal +++ b/gnss/2.1/IGnssMeasurementCallback.hal @@ -103,6 +103,9 @@ interface IGnssMeasurementCallback extends @2.0::IGnssMeasurementCallback { * * The value does not include the inter-frequency Ionospheric bias. * + * The sign of the value is defined by the following equation: + * corrected pseudorange = raw pseudorange - fullInterSignalBias + * * The full ISB of GnssClock.referenceSignalTypeForIsb is defined to be 0.0 nanoseconds. */ double fullInterSignalBiasNs; @@ -127,6 +130,9 @@ interface IGnssMeasurementCallback extends @2.0::IGnssMeasurementCallback { * - Satellite inter-code bias (e.g., Differential Code Bias (DCB)) (with respect to the * code type in GnssClock.referenceSignalTypeForIsb) * + * The sign of the value is defined by the following equation: + * corrected pseudorange = raw pseudorange - satelliteInterSignalBias + * * The satellite ISB of GnssClock.referenceSignalTypeForIsb is defined to be 0.0 * nanoseconds. */ -- GitLab From 6cb491a386ad9587d9e39906450d0acb9df866a8 Mon Sep 17 00:00:00 2001 From: junyulai Date: Thu, 29 Apr 2021 10:04:00 +0800 Subject: [PATCH 635/790] [SP37] Change requirement of older event callback. Currently, vendors are asked to duplicate old events to onEvent() and onEvent_1_1(). This is not the typically way other modules would do. Thus, remove the requirement of duplicate events, and replace it with only firing onEvent_1_1 when feasible. Note no VTS is added currently, from vendor feedback, there is no reliable way to guarantee the callbacks will be called in the test. Test: hidl-gen -L hash -r android.hardware:hardware/interfaces \ android.hardware.tetheroffload.control@1.1 Bug: 149467454 Change-Id: I75c1a7788e5d48fb3e2836d54b4fd854c0247214 --- current.txt | 2 +- tetheroffload/control/1.1/ITetheringOffloadCallback.hal | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/current.txt b/current.txt index bdbe1b8082..8432791a2a 100644 --- a/current.txt +++ b/current.txt @@ -854,7 +854,7 @@ d06226cd3e916bb866b016b22f35c89c1d9286f62a4aa82a549daf8d52805183 android.hardwar f22813615be1445ddd817655c054fc69dc9efea56c9035cd0757f3cbed190641 android.hardware.radio.config@1.3::IRadioConfig c9ad18729268593d14681d88ffad1c97e707444a45e1b4ed804dab949edbd84f android.hardware.radio.config@1.3::IRadioConfigResponse fd43298c43f70130c747a642ee43b0c242ac0cebffb377faa24f2725f0aa6caf android.hardware.tetheroffload.control@1.1::IOffloadControl -fe18c9032e4063efca3fff3c377dd69780de1f96e8e2bc3f7d100a5d8bd467b4 android.hardware.tetheroffload.control@1.1::ITetheringOffloadCallback +ead4ec8713a2cb40906fe31ba793d21a6b1190143c446690d16a6ea686aa2fea android.hardware.tetheroffload.control@1.1::ITetheringOffloadCallback e34b4c7bec5e032c14804707ca924dd6b99ed5ba139da7505fe7d698d0fe178f android.hardware.tetheroffload.control@1.1::types 63dfdb433ac73fb2bf4a44d2ade7b7e289e155835206d1939640d6c88d208994 android.hardware.tv.cec@1.1::IHdmiCec b9682587677ce9c872e04f0e9fd6c9c78a56ae795c07cbf8c50100e0351d4c44 android.hardware.tv.cec@1.1::IHdmiCecCallback diff --git a/tetheroffload/control/1.1/ITetheringOffloadCallback.hal b/tetheroffload/control/1.1/ITetheringOffloadCallback.hal index 7a7d56d9d3..9c74641764 100644 --- a/tetheroffload/control/1.1/ITetheringOffloadCallback.hal +++ b/tetheroffload/control/1.1/ITetheringOffloadCallback.hal @@ -26,8 +26,8 @@ import OffloadCallbackEvent; interface ITetheringOffloadCallback extends @1.0::ITetheringOffloadCallback { /** * Called when an asynchronous event is generated by the hardware - * management process. Events which are common for 1.0 and 1.1 HAL - * MUST be fired on both 1.0 and 1.1 callback. + * management process. Implementations that report events via this callback + * should not invoke onEvent of 1.0 HAL. */ oneway onEvent_1_1(OffloadCallbackEvent event); }; -- GitLab From de2c1edf46049a7a69ef25b7ce901b1a65eec41a Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Mon, 3 May 2021 20:32:00 +0000 Subject: [PATCH 636/790] Fix IFace VTS unable to link default HAL Bug: 184614916 Test: VtsHalBiometricsFaceTargetTest Change-Id: Ia811f581690c10251f38144ffaed55624587d281 --- biometrics/face/aidl/vts/Android.bp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/biometrics/face/aidl/vts/Android.bp b/biometrics/face/aidl/vts/Android.bp index c5660b1e01..99c8c99488 100644 --- a/biometrics/face/aidl/vts/Android.bp +++ b/biometrics/face/aidl/vts/Android.bp @@ -14,9 +14,14 @@ cc_test { "use_libaidlvintf_gtest_helper_static", ], srcs: ["VtsHalBiometricsFaceTargetTest.cpp"], + static_libs: [ + "android.hardware.biometrics.common-V1-ndk_platform", + "android.hardware.biometrics.face-V1-ndk_platform", + "android.hardware.common-V2-ndk_platform", + "android.hardware.keymaster-V3-ndk_platform", + ], shared_libs: [ "libbinder_ndk", - "android.hardware.biometrics.face-V1-ndk_platform", ], test_suites: [ "general-tests", -- GitLab From 3e1a1d32f56cc493340f08d6cc77513aed717549 Mon Sep 17 00:00:00 2001 From: Henry Fang Date: Tue, 4 May 2021 13:54:47 -0700 Subject: [PATCH 637/790] Fix bug for none fe test case bug: 182519645 Test: atest VtsHalTvTunerV1_0TargetTest Change-Id: I86458142ba4155274594a793eb939567bea24734 --- tv/tuner/1.0/vts/functional/DescramblerTests.cpp | 13 ++++++++----- .../functional/VtsHalTvTunerV1_0TargetTest.cpp | 15 +++++++++++---- .../VtsHalTvTunerV1_0TestConfigurations.h | 6 ++++-- tv/tuner/config/TunerTestingConfigReaderV1_0.h | 4 ++-- 4 files changed, 25 insertions(+), 13 deletions(-) diff --git a/tv/tuner/1.0/vts/functional/DescramblerTests.cpp b/tv/tuner/1.0/vts/functional/DescramblerTests.cpp index 2e27475e71..67f6baef38 100644 --- a/tv/tuner/1.0/vts/functional/DescramblerTests.cpp +++ b/tv/tuner/1.0/vts/functional/DescramblerTests.cpp @@ -53,12 +53,15 @@ AssertionResult DescramblerTests::openCasSession(TunerKeyToken& sessionId, return failure(); } - auto status = mCas->setSessionPrivateData(sessionId, hidlPvtData); - if (status != android::hardware::cas::V1_0::Status::OK) { - ALOGW("[vts] Failed to set session private data"); - mCas->closeSession(sessionId); - return failure(); + if (hidlPvtData.size() > 0) { + auto status = mCas->setSessionPrivateData(sessionId, hidlPvtData); + if (status != android::hardware::cas::V1_0::Status::OK) { + ALOGW("[vts] Failed to set session private data"); + mCas->closeSession(sessionId); + return failure(); + } } + return success(); } diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp index 62093ccbe5..b39abe3547 100644 --- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp +++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp @@ -267,7 +267,9 @@ void TunerRecordHidlTest::attachSingleFilterToRecordDvrTest(FilterConfig filterC uint32_t demuxId; sp demux; ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); + mDvrTests.setDemux(demux); + DvrConfig dvrSourceConfig; if (record.hasFrontendConnection) { uint32_t feId; mFrontendTests.getFrontendIdByType(frontendConf.type, feId); @@ -275,13 +277,17 @@ void TunerRecordHidlTest::attachSingleFilterToRecordDvrTest(FilterConfig filterC ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); ASSERT_TRUE(mFrontendTests.setFrontendCallback()); ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); + } else { + dvrSourceConfig = dvrMap[record.dvrSourceId]; + ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrSourceConfig.type, dvrSourceConfig.bufferSize)); + ASSERT_TRUE(mDvrTests.configDvrPlayback(dvrSourceConfig.settings)); + ASSERT_TRUE(mDvrTests.getDvrPlaybackMQDescriptor()); } uint32_t filterId; sp filter; mFilterTests.setDemux(demux); - mDvrTests.setDemux(demux); ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrConf.type, dvrConf.bufferSize)); ASSERT_TRUE(mDvrTests.configDvrRecord(dvrConf.settings)); ASSERT_TRUE(mDvrTests.getDvrRecordMQDescriptor()); @@ -327,6 +333,7 @@ void TunerDescramblerHidlTest::scrambledBroadcastTest(set m mFrontendTests.setDemux(demux); } else { dvrSourceConfig = dvrMap[descrambling.dvrSourceId]; + mDvrTests.setDemux(demux); ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrSourceConfig.type, dvrSourceConfig.bufferSize)); ASSERT_TRUE(mDvrTests.configDvrPlayback(dvrSourceConfig.settings)); ASSERT_TRUE(mDvrTests.getDvrPlaybackMQDescriptor()); @@ -641,7 +648,7 @@ TEST_P(TunerRecordHidlTest, RecordDataFlowWithTsRecordFilterTest) { TEST_P(TunerRecordHidlTest, LnbRecordDataFlowWithTsRecordFilterTest) { description("Feed ts data from Fe with Lnb to recording and test with ts record filter"); - if (lnbRecord.support) { + if (!lnbRecord.support) { return; } recordSingleFilterTestWithLnb(filterMap[lnbRecord.recordFilterId], @@ -651,7 +658,7 @@ TEST_P(TunerRecordHidlTest, LnbRecordDataFlowWithTsRecordFilterTest) { TEST_P(TunerDescramblerHidlTest, CreateDescrambler) { description("Create Descrambler"); - if (descrambling.support) { + if (!descrambling.support) { return; } uint32_t demuxId; @@ -678,7 +685,7 @@ TEST_P(TunerDescramblerHidlTest, CreateDescrambler) { TEST_P(TunerDescramblerHidlTest, ScrambledBroadcastDataFlowMediaFiltersTest) { description("Test ts audio filter in scrambled broadcast use case"); - if (descrambling.support) { + if (!descrambling.support) { return; } set filterConfs; diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h index 885cafd303..2cea181268 100644 --- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h +++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h @@ -216,8 +216,10 @@ inline bool validateConnections() { return false; } - bool filterIsValid = filterMap.find(live.audioFilterId) != filterMap.end() && - filterMap.find(live.videoFilterId) != filterMap.end(); + bool filterIsValid = (live.hasFrontendConnection) + ? filterMap.find(live.audioFilterId) != filterMap.end() && + filterMap.find(live.videoFilterId) != filterMap.end() + : true; filterIsValid &= playback.support ? (filterMap.find(playback.audioFilterId) != filterMap.end() && filterMap.find(playback.videoFilterId) != filterMap.end()) diff --git a/tv/tuner/config/TunerTestingConfigReaderV1_0.h b/tv/tuner/config/TunerTestingConfigReaderV1_0.h index f7f72b038e..0688219575 100644 --- a/tv/tuner/config/TunerTestingConfigReaderV1_0.h +++ b/tv/tuner/config/TunerTestingConfigReaderV1_0.h @@ -480,7 +480,6 @@ struct TunerTestingConfigReader1_0 { return; } auto recordConfig = *dataFlow.getFirstDvrRecord(); - record.frontendId = recordConfig.getFrontendConnection(); record.recordFilterId = recordConfig.getRecordFilterConnection(); record.dvrRecordId = recordConfig.getDvrRecordConnection(); if (recordConfig.hasDvrSoftwareFeConnection()) { @@ -489,6 +488,7 @@ struct TunerTestingConfigReader1_0 { if (recordConfig.getHasFrontendConnection()) { record.hasFrontendConnection = true; record.dvrSourceId = emptyHardwareId; + record.frontendId = recordConfig.getFrontendConnection(); } else { record.hasFrontendConnection = false; record.dvrSourceId = recordConfig.getDvrSourceConnection(); @@ -504,7 +504,6 @@ struct TunerTestingConfigReader1_0 { return; } auto descConfig = *dataFlow.getFirstDescrambling(); - descrambling.frontendId = descConfig.getFrontendConnection(); descrambling.descramblerId = descConfig.getDescramblerConnection(); descrambling.audioFilterId = descConfig.getAudioFilterConnection(); descrambling.videoFilterId = descConfig.getVideoFilterConnection(); @@ -514,6 +513,7 @@ struct TunerTestingConfigReader1_0 { if (descConfig.getHasFrontendConnection()) { descrambling.hasFrontendConnection = true; descrambling.dvrSourceId = emptyHardwareId; + descrambling.frontendId = descConfig.getFrontendConnection(); } else { descrambling.hasFrontendConnection = false; descrambling.dvrSourceId = descConfig.getDvrSourceConnection(); -- GitLab From 7b8606eaa15ff969578a97764bccaf86ad56e5c3 Mon Sep 17 00:00:00 2001 From: Vince Leung Date: Tue, 4 May 2021 13:56:48 -0700 Subject: [PATCH 638/790] Increase timeout values for callback We need to increase the timeout values for waiting for the callback to be called. Bug: 184719072 Test: atest to verify that the affected tests pass on P21 Change-Id: I5a5b2ae1fb99f98e3d94cd956685fabc45b89b30 --- vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp index 4d03ebf9f9..713ec75a20 100644 --- a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp +++ b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp @@ -276,7 +276,9 @@ TEST_P(VibratorAidl, ValidateEffectWithCallback) { if (!status.isOk()) continue; - std::chrono::milliseconds timeout{lengthMs * 2}; + //TODO(b/187207798): revert back to conservative timeout values once + //latencies have been fixed + std::chrono::milliseconds timeout{lengthMs * 8}; EXPECT_EQ(completionFuture.wait_for(timeout), std::future_status::ready); } } @@ -588,7 +590,9 @@ TEST_P(VibratorAidl, ComposeCallback) { EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, callback).exceptionCode()) << toString(primitive); - EXPECT_EQ(completionFuture.wait_for(duration * 2), std::future_status::ready) + //TODO(b/187207798): revert back to conservative timeout values once + //latencies have been fixed + EXPECT_EQ(completionFuture.wait_for(duration * 4), std::future_status::ready) << toString(primitive); end = high_resolution_clock::now(); @@ -739,7 +743,9 @@ TEST_P(VibratorAidl, ComposeValidPwleWithCallback) { sp callback = new CompletionCallback([&completionPromise] { completionPromise.set_value(); }); uint32_t durationMs = 2100; // Sum of 2 active and 1 braking below - std::chrono::milliseconds timeout{durationMs * 2}; + //TODO(b/187207798): revert back to conservative timeout values once + //latencies have been fixed + std::chrono::milliseconds timeout{durationMs * 4}; ActivePwle active = composeValidActivePwle(vibrator, capabilities); -- GitLab From 6c1aaa7ed0c4bcf2df95883b76cb5e7d71ff731a Mon Sep 17 00:00:00 2001 From: Yu-Han Yang Date: Mon, 3 May 2021 14:39:45 -0700 Subject: [PATCH 639/790] Specify minInterval in StartAndCheckFirstLocation Bug: 186499722 Test: on device Change-Id: Ie7cdc958333351863d71dccc89b2034c225d060a --- .../functional/VtsHalGnssV1_0TargetTest.cpp | 66 ++++++++++--------- gnss/1.1/vts/functional/gnss_hal_test.cpp | 8 ++- gnss/1.1/vts/functional/gnss_hal_test.h | 3 +- .../vts/functional/gnss_hal_test_cases.cpp | 4 +- gnss/2.0/vts/functional/gnss_hal_test.cpp | 8 ++- gnss/2.0/vts/functional/gnss_hal_test.h | 3 +- .../vts/functional/gnss_hal_test_cases.cpp | 12 +++- .../vts/functional/gnss_hal_test_cases.cpp | 2 +- gnss/aidl/vts/gnss_hal_test_cases.cpp | 2 +- .../vts/include/v2_1/gnss_hal_test_template.h | 10 +-- 10 files changed, 68 insertions(+), 50 deletions(-) diff --git a/gnss/1.0/vts/functional/VtsHalGnssV1_0TargetTest.cpp b/gnss/1.0/vts/functional/VtsHalGnssV1_0TargetTest.cpp index 237e8ec9d8..699ce9af14 100644 --- a/gnss/1.0/vts/functional/VtsHalGnssV1_0TargetTest.cpp +++ b/gnss/1.0/vts/functional/VtsHalGnssV1_0TargetTest.cpp @@ -134,13 +134,30 @@ class GnssHalTest : public testing::TestWithParam { return status; } + /* + * SetPositionMode: + * Helper function to set positioning mode and verify output + */ + void SetPositionMode(const int min_interval_msec) { + const int kPreferredAccuracy = 0; // Ideally perfect (matches GnssLocationProvider) + const int kPreferredTimeMsec = 0; // Ideally immediate + + auto result = gnss_hal_->setPositionMode( + IGnss::GnssPositionMode::MS_BASED, IGnss::GnssPositionRecurrence::RECURRENCE_PERIODIC, + min_interval_msec, kPreferredAccuracy, kPreferredTimeMsec); + + ASSERT_TRUE(result.isOk()); + EXPECT_TRUE(result); + } + /* * StartAndGetSingleLocation: * Helper function to get one Location and check fields * * returns true if a location was successfully generated */ - bool StartAndGetSingleLocation(bool checkAccuracies) { + bool StartAndGetSingleLocation(const bool checkAccuracies, const int min_interval_msec) { + SetPositionMode(min_interval_msec); auto result = gnss_hal_->start(); EXPECT_TRUE(result.isOk()); @@ -349,37 +366,24 @@ TEST_P(GnssHalTest, SetCallbackCapabilitiesCleanup) {} * and checks them for reasonable validity. */ TEST_P(GnssHalTest, GetLocation) { -#define MIN_INTERVAL_MSEC 500 -#define PREFERRED_ACCURACY 0 // Ideally perfect (matches GnssLocationProvider) -#define PREFERRED_TIME_MSEC 0 // Ideally immediate - -#define LOCATION_TIMEOUT_SUBSEQUENT_SEC 3 -#define LOCATIONS_TO_CHECK 5 - - bool checkMoreAccuracies = - (info_called_count_ > 0 && last_info_.yearOfHw >= 2017); + const int kMinIntervalMsec = 500; + const int kLocationTimeoutSubsequentSec = 3; + const int kLocationsToCheck = 5; - auto result = gnss_hal_->setPositionMode( - IGnss::GnssPositionMode::MS_BASED, - IGnss::GnssPositionRecurrence::RECURRENCE_PERIODIC, MIN_INTERVAL_MSEC, - PREFERRED_ACCURACY, PREFERRED_TIME_MSEC); + bool checkMoreAccuracies = (info_called_count_ > 0 && last_info_.yearOfHw >= 2017); - ASSERT_TRUE(result.isOk()); - EXPECT_TRUE(result); - - /* - * GPS signals initially optional for this test, so don't expect no timeout - * yet - */ - bool gotLocation = StartAndGetSingleLocation(checkMoreAccuracies); - - if (gotLocation) { - for (int i = 1; i < LOCATIONS_TO_CHECK; i++) { - EXPECT_EQ(std::cv_status::no_timeout, wait(LOCATION_TIMEOUT_SUBSEQUENT_SEC)); - EXPECT_EQ(location_called_count_, i + 1); - CheckLocation(last_location_, checkMoreAccuracies, true); + /* + * GPS signals initially optional for this test, so don't expect timeout yet. + */ + bool gotLocation = StartAndGetSingleLocation(checkMoreAccuracies, kMinIntervalMsec); + + if (gotLocation) { + for (int i = 1; i < kLocationsToCheck; i++) { + EXPECT_EQ(std::cv_status::no_timeout, wait(kLocationTimeoutSubsequentSec)); + EXPECT_EQ(location_called_count_, i + 1); + CheckLocation(last_location_, checkMoreAccuracies, true); + } } - } StopAndClearLocations(); } @@ -410,7 +414,7 @@ TEST_P(GnssHalTest, InjectDelete) { ASSERT_TRUE(resultVoid.isOk()); // Ensure we can get a good location after a bad injection has been deleted - StartAndGetSingleLocation(false); + StartAndGetSingleLocation(false, /* min_interval_sec= */ 1000); StopAndClearLocations(); } @@ -430,7 +434,7 @@ TEST_P(GnssHalTest, InjectSeedLocation) { ASSERT_TRUE(result.isOk()); EXPECT_TRUE(result); - StartAndGetSingleLocation(false); + StartAndGetSingleLocation(false, /* min_interval_msec= */ 1000); // Ensure we don't get a location anywhere within 111km (1 degree of lat or lng) of the seed // location. diff --git a/gnss/1.1/vts/functional/gnss_hal_test.cpp b/gnss/1.1/vts/functional/gnss_hal_test.cpp index 52aaa69753..6663a19abf 100644 --- a/gnss/1.1/vts/functional/gnss_hal_test.cpp +++ b/gnss/1.1/vts/functional/gnss_hal_test.cpp @@ -99,7 +99,9 @@ void GnssHalTest::SetPositionMode(const int min_interval_msec, const bool low_po EXPECT_TRUE(result); } -bool GnssHalTest::StartAndCheckFirstLocation(bool strict) { +bool GnssHalTest::StartAndCheckFirstLocation(const bool strict, const int min_interval_msec, + const bool low_power_mode) { + SetPositionMode(min_interval_msec, low_power_mode); auto result = gnss_hal_->start(); EXPECT_TRUE(result.isOk()); @@ -141,7 +143,9 @@ void GnssHalTest::StartAndCheckLocations(int count) { SetPositionMode(kMinIntervalMsec, kLowPowerMode); - EXPECT_TRUE(StartAndCheckFirstLocation(/* strict= */ true)); + EXPECT_TRUE(StartAndCheckFirstLocation(/* strict= */ true, + /* min_interval_msec= */ 1000, + /* low_power_mode= */ false)); for (int i = 1; i < count; i++) { EXPECT_TRUE(gnss_cb_->location_cbq_.retrieve(gnss_cb_->last_location_, diff --git a/gnss/1.1/vts/functional/gnss_hal_test.h b/gnss/1.1/vts/functional/gnss_hal_test.h index 75c4216e4a..c6420287c1 100644 --- a/gnss/1.1/vts/functional/gnss_hal_test.h +++ b/gnss/1.1/vts/functional/gnss_hal_test.h @@ -106,7 +106,8 @@ class GnssHalTest : public testing::TestWithParam { * * returns true if a location was successfully generated */ - bool StartAndCheckFirstLocation(bool strict); + bool StartAndCheckFirstLocation(const bool strict, const int min_interval_msec, + const bool low_power_mode); /* * CheckLocation: diff --git a/gnss/1.1/vts/functional/gnss_hal_test_cases.cpp b/gnss/1.1/vts/functional/gnss_hal_test_cases.cpp index e6a51eb731..ef64324aad 100644 --- a/gnss/1.1/vts/functional/gnss_hal_test_cases.cpp +++ b/gnss/1.1/vts/functional/gnss_hal_test_cases.cpp @@ -90,10 +90,8 @@ TEST_P(GnssHalTest, GetLocationLowPower) { gnss_cb_->location_cbq_.reset(); // Start of Low Power Mode test - SetPositionMode(kMinIntervalMsec, kLowPowerMode); - // Don't expect true - as without AGPS access - if (!StartAndCheckFirstLocation(/* strict= */ false)) { + if (!StartAndCheckFirstLocation(/* strict= */ false, kMinIntervalMsec, kLowPowerMode)) { ALOGW("GetLocationLowPower test - no first low power location received."); } diff --git a/gnss/2.0/vts/functional/gnss_hal_test.cpp b/gnss/2.0/vts/functional/gnss_hal_test.cpp index 1cb44c5761..522769313e 100644 --- a/gnss/2.0/vts/functional/gnss_hal_test.cpp +++ b/gnss/2.0/vts/functional/gnss_hal_test.cpp @@ -97,7 +97,9 @@ void GnssHalTest::SetPositionMode(const int min_interval_msec, const bool low_po EXPECT_TRUE(result); } -bool GnssHalTest::StartAndCheckFirstLocation(bool strict) { +bool GnssHalTest::StartAndCheckFirstLocation(const bool strict, const int min_interval_msec, + const bool low_power_mode) { + SetPositionMode(min_interval_msec, low_power_mode); const auto result = gnss_hal_->start(); EXPECT_TRUE(result.isOk()); @@ -137,7 +139,9 @@ void GnssHalTest::StartAndCheckLocations(int count) { SetPositionMode(kMinIntervalMsec, kLowPowerMode); - EXPECT_TRUE(StartAndCheckFirstLocation(/* strict= */ true)); + EXPECT_TRUE(StartAndCheckFirstLocation(/* strict= */ true, + /* min_interval_msec= */ 1000, + /* low_power_mode= */ false)); for (int i = 1; i < count; i++) { EXPECT_TRUE(gnss_cb_->location_cbq_.retrieve(gnss_cb_->last_location_, diff --git a/gnss/2.0/vts/functional/gnss_hal_test.h b/gnss/2.0/vts/functional/gnss_hal_test.h index 7fbd7350eb..28a19792b6 100644 --- a/gnss/2.0/vts/functional/gnss_hal_test.h +++ b/gnss/2.0/vts/functional/gnss_hal_test.h @@ -159,7 +159,8 @@ class GnssHalTest : public testing::TestWithParam { * * returns true if a location was successfully generated */ - bool StartAndCheckFirstLocation(bool strict); + bool StartAndCheckFirstLocation(const bool strict, const int min_interval_msec, + const bool low_power_mode); /* * CheckLocation: diff --git a/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp b/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp index 3e0058fa05..f17336bc25 100644 --- a/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp +++ b/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp @@ -403,7 +403,9 @@ TEST_P(GnssHalTest, TestGnssDataElapsedRealtimeFlags) { } TEST_P(GnssHalTest, TestGnssLocationElapsedRealtime) { - StartAndCheckFirstLocation(/* strict= */ true); + StartAndCheckFirstLocation(/* strict= */ true, + /* min_interval_msec= */ 1000, + /* low_power_mode= */ false); ASSERT_TRUE((int)gnss_cb_->last_location_.elapsedRealtime.flags <= (int)(ElapsedRealtimeFlags::HAS_TIMESTAMP_NS | @@ -419,7 +421,9 @@ TEST_P(GnssHalTest, TestGnssLocationElapsedRealtime) { // This test only verify that injectBestLocation_2_0 does not crash. TEST_P(GnssHalTest, TestInjectBestLocation_2_0) { - StartAndCheckFirstLocation(/* strict= */ true); + StartAndCheckFirstLocation(/* strict= */ true, + /* min_interval_msec= */ 1000, + /* low_power_mode= */ false); gnss_hal_->injectBestLocation_2_0(gnss_cb_->last_location_); StopAndClearLocations(); } @@ -463,7 +467,9 @@ TEST_P(GnssHalTest, GetLocationLowPower) { SetPositionMode(kMinIntervalMsec, kLowPowerMode); // Don't expect true - as without AGPS access - if (!StartAndCheckFirstLocation(/* strict= */ false)) { + if (!StartAndCheckFirstLocation(/* strict= */ false, + /* min_interval_msec= */ 1000, + /* low_power_mode= */ false)) { ALOGW("GetLocationLowPower test - no first low power location received."); } diff --git a/gnss/2.1/vts/functional/gnss_hal_test_cases.cpp b/gnss/2.1/vts/functional/gnss_hal_test_cases.cpp index deb80e8a0b..fcab8c4a04 100644 --- a/gnss/2.1/vts/functional/gnss_hal_test_cases.cpp +++ b/gnss/2.1/vts/functional/gnss_hal_test_cases.cpp @@ -254,7 +254,7 @@ TEST_P(GnssHalTest, TestGnssAntennaInfo) { */ TEST_P(GnssHalTest, TestGnssSvInfoFields) { gnss_cb_->location_cbq_.reset(); - StartAndCheckFirstLocation(); + StartAndCheckFirstLocation(/* min_interval_msec= */ 1000, /* low_power_mode= */ false); int location_called_count = gnss_cb_->location_cbq_.calledCount(); // Tolerate 1 less sv status to handle edge cases in reporting. diff --git a/gnss/aidl/vts/gnss_hal_test_cases.cpp b/gnss/aidl/vts/gnss_hal_test_cases.cpp index 9086b3d966..0fc2ff8a38 100644 --- a/gnss/aidl/vts/gnss_hal_test_cases.cpp +++ b/gnss/aidl/vts/gnss_hal_test_cases.cpp @@ -201,7 +201,7 @@ TEST_P(GnssHalTest, TestGnssPowerIndication) { // Get a location and request another GnssPowerStats gnss_cb_->location_cbq_.reset(); - StartAndCheckFirstLocation(); + StartAndCheckFirstLocation(/* min_interval_msec= */ 1000, /* low_power_mode= */ false); // Request and verify the 2nd GnssPowerStats has larger values than the 1st one iGnssPowerIndication->requestGnssPowerStats(); diff --git a/gnss/common/utils/vts/include/v2_1/gnss_hal_test_template.h b/gnss/common/utils/vts/include/v2_1/gnss_hal_test_template.h index fec3503cd6..03166be8d7 100644 --- a/gnss/common/utils/vts/include/v2_1/gnss_hal_test_template.h +++ b/gnss/common/utils/vts/include/v2_1/gnss_hal_test_template.h @@ -107,7 +107,7 @@ class GnssHalTestTemplate : public testing::TestWithParam { * * returns true if a location was successfully generated */ - bool StartAndCheckFirstLocation(); + bool StartAndCheckFirstLocation(const int min_interval_msec, const bool low_power_mode); /* * CheckLocation: @@ -234,7 +234,9 @@ void GnssHalTestTemplate::SetPositionMode(const int min_interval_msec, } template -bool GnssHalTestTemplate::StartAndCheckFirstLocation() { +bool GnssHalTestTemplate::StartAndCheckFirstLocation(const int min_interval_msec, + const bool low_power_mode) { + SetPositionMode(min_interval_msec, low_power_mode); const auto result = gnss_hal_->start(); EXPECT_TRUE(result.isOk()); @@ -274,9 +276,7 @@ void GnssHalTestTemplate::StartAndCheckLocations(int count) { const int kLocationTimeoutSubsequentSec = 2; const bool kLowPowerMode = false; - SetPositionMode(kMinIntervalMsec, kLowPowerMode); - - EXPECT_TRUE(StartAndCheckFirstLocation()); + EXPECT_TRUE(StartAndCheckFirstLocation(kMinIntervalMsec, kLowPowerMode)); for (int i = 1; i < count; i++) { EXPECT_TRUE(gnss_cb_->location_cbq_.retrieve(gnss_cb_->last_location_, -- GitLab From 9f6d6ae26c1f0a6d03fb8c035565a25104aa3c6d Mon Sep 17 00:00:00 2001 From: Mikhail Naganov Date: Wed, 5 May 2021 18:07:59 -0700 Subject: [PATCH 640/790] audio HAL - fix UAFs resolve merge conflicts of bd78085f08d5e342a1e0b02dde7a25832c2dd62e to pi-dev Bug: 185259758 Test: N/A Change-Id: Ia85fb88e85e94b4d63fc155d89063bba6c61e875 Merged-In: I5ec70b098a00746108e10ab39e966607d78c84ae --- .../include/core/all-versions/default/StreamIn.impl.h | 8 ++++---- .../include/core/all-versions/default/StreamOut.impl.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/audio/core/all-versions/default/include/core/all-versions/default/StreamIn.impl.h b/audio/core/all-versions/default/include/core/all-versions/default/StreamIn.impl.h index 64c85ab5fc..adad331de1 100644 --- a/audio/core/all-versions/default/include/core/all-versions/default/StreamIn.impl.h +++ b/audio/core/all-versions/default/include/core/all-versions/default/StreamIn.impl.h @@ -387,9 +387,9 @@ Return StreamIn::prepareForReading(uint32_t frameSize, uint32_t framesCoun } // Create and launch the thread. - auto tempReadThread = - std::make_unique(&mStopReadThread, mStream, tempCommandMQ.get(), - tempDataMQ.get(), tempStatusMQ.get(), tempElfGroup.get()); + sp tempReadThread = + new ReadThread(&mStopReadThread, mStream, tempCommandMQ.get(), + tempDataMQ.get(), tempStatusMQ.get(), tempElfGroup.get()); if (!tempReadThread->init()) { ALOGW("failed to start reader thread: %s", strerror(-status)); sendError(Result::INVALID_ARGUMENTS); @@ -405,7 +405,7 @@ Return StreamIn::prepareForReading(uint32_t frameSize, uint32_t framesCoun mCommandMQ = std::move(tempCommandMQ); mDataMQ = std::move(tempDataMQ); mStatusMQ = std::move(tempStatusMQ); - mReadThread = tempReadThread.release(); + mReadThread = tempReadThread; mEfGroup = tempElfGroup.release(); threadInfo.pid = getpid(); threadInfo.tid = mReadThread->getTid(); diff --git a/audio/core/all-versions/default/include/core/all-versions/default/StreamOut.impl.h b/audio/core/all-versions/default/include/core/all-versions/default/StreamOut.impl.h index 6fb157f7de..a49059ccba 100644 --- a/audio/core/all-versions/default/include/core/all-versions/default/StreamOut.impl.h +++ b/audio/core/all-versions/default/include/core/all-versions/default/StreamOut.impl.h @@ -370,9 +370,9 @@ Return StreamOut::prepareForWriting(uint32_t frameSize, uint32_t framesCou } // Create and launch the thread. - auto tempWriteThread = - std::make_unique(&mStopWriteThread, mStream, tempCommandMQ.get(), - tempDataMQ.get(), tempStatusMQ.get(), tempElfGroup.get()); + sp tempWriteThread = + new WriteThread(&mStopWriteThread, mStream, tempCommandMQ.get(), + tempDataMQ.get(), tempStatusMQ.get(), tempElfGroup.get()); if (!tempWriteThread->init()) { ALOGW("failed to start writer thread: %s", strerror(-status)); sendError(Result::INVALID_ARGUMENTS); @@ -388,7 +388,7 @@ Return StreamOut::prepareForWriting(uint32_t frameSize, uint32_t framesCou mCommandMQ = std::move(tempCommandMQ); mDataMQ = std::move(tempDataMQ); mStatusMQ = std::move(tempStatusMQ); - mWriteThread = tempWriteThread.release(); + mWriteThread = tempWriteThread; mEfGroup = tempElfGroup.release(); threadInfo.pid = getpid(); threadInfo.tid = mWriteThread->getTid(); -- GitLab From af88452fa97c6ba619a3cfddc303670e16f405d7 Mon Sep 17 00:00:00 2001 From: Shuzhen Wang Date: Wed, 5 May 2021 22:27:54 -0700 Subject: [PATCH 641/790] VTS: Cast camera device to lower versions If the camera device is of a certain version, it can be casted to all lower version numbers. Test: VtsHalCameraProviderV2_4TargetTest Bug: 187010354 Change-Id: Ib9515d898948fb2e04d20b0087d98334fa71def0 --- .../VtsHalCameraProviderV2_4TargetTest.cpp | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp index 7bb300ed2e..deb420d1e2 100644 --- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp +++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp @@ -7155,17 +7155,24 @@ void CameraHidlTest::castDevice(const sp& device, sp* device3_5 /*out*/, sp* device3_7 /*out*/) { ASSERT_NE(nullptr, device3_5); - if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_5) { - auto castResult = device::V3_5::ICameraDevice::castFrom(device); - ASSERT_TRUE(castResult.isOk()); - *device3_5 = castResult; - } - ASSERT_NE(nullptr, device3_7); - if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_7) { - auto castResult = device::V3_7::ICameraDevice::castFrom(device); - ASSERT_TRUE(castResult.isOk()); - *device3_7 = castResult; + + switch (deviceVersion) { + case CAMERA_DEVICE_API_VERSION_3_7: { + auto castResult = device::V3_7::ICameraDevice::castFrom(device); + ASSERT_TRUE(castResult.isOk()); + *device3_7 = castResult; + } + [[fallthrough]]; + case CAMERA_DEVICE_API_VERSION_3_5: { + auto castResult = device::V3_5::ICameraDevice::castFrom(device); + ASSERT_TRUE(castResult.isOk()); + *device3_5 = castResult; + break; + } + default: + // no-op + return; } } -- GitLab From 727a7b2104b0962509fedffe720eec508b2ee6de Mon Sep 17 00:00:00 2001 From: Xusong Wang Date: Wed, 3 Mar 2021 16:20:37 -0800 Subject: [PATCH 642/790] Introduce reusable execution to canonical interface -- HAL. This CL modifies the canonical interface for reusable executions: - Add new interface: IExecution with compute and computeFenced methods - Add new method IPreparedModel::createExecution In NNAPI runtime, the new interface IExecution is used to memoize request-specific execution resources (e.g. converted HAL request). The expected usage is that, IPreparedModel::createExecution will be invoked in the first computation of a reusable NDK ANNExecution object, and IExecution::compute* will be invoked repeatedly. The IPreparedModel::execute* methods are preserved to avoid redundant object creation and memoization overhead for a single-time (non-reusable) execution. For a vendor implementing the canonical interfaces, only the IPreparedModel::execute* methods will be called because there is currently no reusable execution at HAL interface. A DefaultExecution implementation is provided to reduce the work needed on the vendor side. Bug: 184073769 Test: NNT_static Test: neuralnetworks_utils_hal_1_0_test Test: neuralnetworks_utils_hal_1_1_test Test: neuralnetworks_utils_hal_1_2_test Test: neuralnetworks_utils_hal_1_3_test Test: neuralnetworks_utils_hal_common_test Test: neuralnetworks_utils_hal_aidl_test Change-Id: I91790bb5ccf5ae648687fe603f88ffda2c9fd2b2 --- .../utils/include/nnapi/hal/1.0/Execution.h | 64 ++++ .../include/nnapi/hal/1.0/PreparedModel.h | 7 + neuralnetworks/1.0/utils/src/Execution.cpp | 72 ++++ .../1.0/utils/src/PreparedModel.cpp | 38 +- .../1.0/utils/test/PreparedModelTest.cpp | 145 +++++++ .../utils/include/nnapi/hal/1.2/Execution.h | 66 ++++ .../include/nnapi/hal/1.2/PreparedModel.h | 8 + neuralnetworks/1.2/utils/src/Execution.cpp | 74 ++++ .../1.2/utils/src/PreparedModel.cpp | 42 +- .../1.2/utils/test/PreparedModelTest.cpp | 243 ++++++++++++ .../utils/include/nnapi/hal/1.3/Execution.h | 66 ++++ .../include/nnapi/hal/1.3/PreparedModel.h | 16 + neuralnetworks/1.3/utils/src/Execution.cpp | 84 ++++ .../1.3/utils/src/PreparedModel.cpp | 78 +++- .../1.3/utils/test/PreparedModelTest.cpp | 358 ++++++++++++++++++ .../utils/include/nnapi/hal/aidl/Execution.h | 65 ++++ .../include/nnapi/hal/aidl/PreparedModel.h | 19 +- neuralnetworks/aidl/utils/src/Burst.cpp | 16 +- neuralnetworks/aidl/utils/src/Execution.cpp | 79 ++++ .../aidl/utils/src/PreparedModel.cpp | 75 +++- .../aidl/utils/test/PreparedModelTest.cpp | 220 +++++++++++ .../common/include/nnapi/hal/CommonUtils.h | 70 +++- .../include/nnapi/hal/InvalidExecution.h | 41 ++ .../include/nnapi/hal/InvalidPreparedModel.h | 4 + .../include/nnapi/hal/ResilientExecution.h | 66 ++++ .../nnapi/hal/ResilientPreparedModel.h | 7 + .../utils/common/src/CommonUtils.cpp | 89 ++--- .../utils/common/src/InvalidExecution.cpp | 40 ++ .../utils/common/src/InvalidPreparedModel.cpp | 6 + .../utils/common/src/ResilientExecution.cpp | 126 ++++++ .../common/src/ResilientPreparedModel.cpp | 30 ++ .../utils/common/test/MockExecution.h | 38 ++ .../utils/common/test/MockPreparedModel.h | 4 + .../utils/common/test/ResilientExecution.cpp | 260 +++++++++++++ .../test/ResilientPreparedModelTest.cpp | 31 ++ 35 files changed, 2540 insertions(+), 107 deletions(-) create mode 100644 neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Execution.h create mode 100644 neuralnetworks/1.0/utils/src/Execution.cpp create mode 100644 neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Execution.h create mode 100644 neuralnetworks/1.2/utils/src/Execution.cpp create mode 100644 neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Execution.h create mode 100644 neuralnetworks/1.3/utils/src/Execution.cpp create mode 100644 neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Execution.h create mode 100644 neuralnetworks/aidl/utils/src/Execution.cpp create mode 100644 neuralnetworks/utils/common/include/nnapi/hal/InvalidExecution.h create mode 100644 neuralnetworks/utils/common/include/nnapi/hal/ResilientExecution.h create mode 100644 neuralnetworks/utils/common/src/InvalidExecution.cpp create mode 100644 neuralnetworks/utils/common/src/ResilientExecution.cpp create mode 100644 neuralnetworks/utils/common/test/MockExecution.h create mode 100644 neuralnetworks/utils/common/test/ResilientExecution.cpp diff --git a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Execution.h b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Execution.h new file mode 100644 index 0000000000..e201e25a13 --- /dev/null +++ b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Execution.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. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_0_UTILS_EXECUTION_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_0_UTILS_EXECUTION_H + +#include +#include +#include +#include +#include +#include + +#include "PreparedModel.h" + +#include +#include +#include + +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface +// lifetimes across processes and for protecting asynchronous calls across HIDL. + +namespace android::hardware::neuralnetworks::V1_0::utils { + +class Execution final : public nn::IExecution, public std::enable_shared_from_this { + struct PrivateConstructorTag {}; + + public: + static nn::GeneralResult> create( + std::shared_ptr preparedModel, Request request, + hal::utils::RequestRelocation relocation); + + Execution(PrivateConstructorTag tag, std::shared_ptr preparedModel, + Request request, hal::utils::RequestRelocation relocation); + + nn::ExecutionResult, nn::Timing>> compute( + const nn::OptionalTimePoint& deadline) const override; + + nn::GeneralResult> computeFenced( + const std::vector& waitFor, const nn::OptionalTimePoint& deadline, + const nn::OptionalDuration& timeoutDurationAfterFence) const override; + + private: + const std::shared_ptr kPreparedModel; + const Request kRequest; + const hal::utils::RequestRelocation kRelocation; +}; + +} // namespace android::hardware::neuralnetworks::V1_0::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_0_UTILS_EXECUTION_H diff --git a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/PreparedModel.h b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/PreparedModel.h index 8853eea048..48be595d41 100644 --- a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/PreparedModel.h +++ b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/PreparedModel.h @@ -57,10 +57,17 @@ class PreparedModel final : public nn::IPreparedModel, const nn::OptionalDuration& loopTimeoutDuration, const nn::OptionalDuration& timeoutDurationAfterFence) const override; + nn::GeneralResult createReusableExecution( + const nn::Request& request, nn::MeasureTiming measure, + const nn::OptionalDuration& loopTimeoutDuration) const override; + nn::GeneralResult configureExecutionBurst() const override; std::any getUnderlyingResource() const override; + nn::ExecutionResult, nn::Timing>> executeInternal( + const V1_0::Request& request, const hal::utils::RequestRelocation& relocation) const; + private: const sp kPreparedModel; const hal::utils::DeathHandler kDeathHandler; diff --git a/neuralnetworks/1.0/utils/src/Execution.cpp b/neuralnetworks/1.0/utils/src/Execution.cpp new file mode 100644 index 0000000000..7a3216b5db --- /dev/null +++ b/neuralnetworks/1.0/utils/src/Execution.cpp @@ -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. + */ + +#include "Execution.h" + +#include "Callbacks.h" +#include "Conversions.h" +#include "Utils.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface +// lifetimes across processes and for protecting asynchronous calls across HIDL. + +namespace android::hardware::neuralnetworks::V1_0::utils { + +nn::GeneralResult> Execution::create( + std::shared_ptr preparedModel, Request request, + hal::utils::RequestRelocation relocation) { + if (preparedModel == nullptr) { + return NN_ERROR() << "V1_0::utils::Execution::create must have non-null preparedModel"; + } + + return std::make_shared(PrivateConstructorTag{}, std::move(preparedModel), + std::move(request), std::move(relocation)); +} + +Execution::Execution(PrivateConstructorTag /*tag*/, + std::shared_ptr preparedModel, Request request, + hal::utils::RequestRelocation relocation) + : kPreparedModel(std::move(preparedModel)), + kRequest(std::move(request)), + kRelocation(std::move(relocation)) {} + +nn::ExecutionResult, nn::Timing>> Execution::compute( + const nn::OptionalTimePoint& /*deadline*/) const { + return kPreparedModel->executeInternal(kRequest, kRelocation); +} + +nn::GeneralResult> Execution::computeFenced( + const std::vector& /*waitFor*/, const nn::OptionalTimePoint& /*deadline*/, + const nn::OptionalDuration& /*timeoutDurationAfterFence*/) const { + return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) + << "IExecution::computeFenced is not supported on 1.0 HAL service"; +} + +} // namespace android::hardware::neuralnetworks::V1_0::utils diff --git a/neuralnetworks/1.0/utils/src/PreparedModel.cpp b/neuralnetworks/1.0/utils/src/PreparedModel.cpp index 858571d401..7987ab4d7f 100644 --- a/neuralnetworks/1.0/utils/src/PreparedModel.cpp +++ b/neuralnetworks/1.0/utils/src/PreparedModel.cpp @@ -19,6 +19,7 @@ #include "Burst.h" #include "Callbacks.h" #include "Conversions.h" +#include "Execution.h" #include "Utils.h" #include @@ -61,22 +62,34 @@ nn::ExecutionResult, nn::Timing>> Prepare const nn::OptionalDuration& /*loopTimeoutDuration*/) const { // Ensure that request is ready for IPC. std::optional maybeRequestInShared; - const nn::Request& requestInShared = NN_TRY(hal::utils::makeExecutionFailure( - hal::utils::flushDataFromPointerToShared(&request, &maybeRequestInShared))); + hal::utils::RequestRelocation relocation; + const nn::Request& requestInShared = + NN_TRY(hal::utils::makeExecutionFailure(hal::utils::convertRequestFromPointerToShared( + &request, &maybeRequestInShared, &relocation))); const auto hidlRequest = NN_TRY(hal::utils::makeExecutionFailure(convert(requestInShared))); + return executeInternal(hidlRequest, relocation); +} + +nn::ExecutionResult, nn::Timing>> +PreparedModel::executeInternal(const V1_0::Request& request, + const hal::utils::RequestRelocation& relocation) const { + if (relocation.input) { + relocation.input->flush(); + } + const auto cb = sp::make(); const auto scoped = kDeathHandler.protectCallback(cb.get()); - const auto ret = kPreparedModel->execute(hidlRequest, cb); + const auto ret = kPreparedModel->execute(request, cb); const auto status = HANDLE_TRANSPORT_FAILURE(ret); HANDLE_HAL_STATUS(status) << "execution failed with " << toString(status); auto result = NN_TRY(cb->get()); - NN_TRY(hal::utils::makeExecutionFailure( - hal::utils::unflushDataFromSharedToPointer(request, maybeRequestInShared))); - + if (relocation.output) { + relocation.output->flush(); + } return result; } @@ -91,6 +104,19 @@ PreparedModel::executeFenced(const nn::Request& /*request*/, << "IPreparedModel::executeFenced is not supported on 1.0 HAL service"; } +nn::GeneralResult PreparedModel::createReusableExecution( + const nn::Request& request, nn::MeasureTiming /*measure*/, + const nn::OptionalDuration& /*loopTimeoutDuration*/) const { + // Ensure that request is ready for IPC. + std::optional maybeRequestInShared; + hal::utils::RequestRelocation relocation; + const nn::Request& requestInShared = NN_TRY(hal::utils::convertRequestFromPointerToShared( + &request, &maybeRequestInShared, &relocation)); + + auto hidlRequest = NN_TRY(convert(requestInShared)); + return Execution::create(shared_from_this(), std::move(hidlRequest), std::move(relocation)); +} + nn::GeneralResult PreparedModel::configureExecutionBurst() const { return Burst::create(shared_from_this()); } diff --git a/neuralnetworks/1.0/utils/test/PreparedModelTest.cpp b/neuralnetworks/1.0/utils/test/PreparedModelTest.cpp index f19ed7756e..7820c06746 100644 --- a/neuralnetworks/1.0/utils/test/PreparedModelTest.cpp +++ b/neuralnetworks/1.0/utils/test/PreparedModelTest.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -224,6 +225,150 @@ TEST(PreparedModelTest, executeFencedNotSupported) { EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); } +TEST(PreparedModelTest, reusableExecute) { + // setup call + const uint32_t kNumberOfComputations = 2; + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + EXPECT_CALL(*mockPreparedModel, execute(_, _)) + .Times(kNumberOfComputations) + .WillRepeatedly(Invoke(makeExecute(V1_0::ErrorStatus::NONE, V1_0::ErrorStatus::NONE))); + + // create execution + const auto createResult = preparedModel->createReusableExecution({}, {}, {}); + ASSERT_TRUE(createResult.has_value()) + << "Failed with " << createResult.error().code << ": " << createResult.error().message; + ASSERT_NE(createResult.value(), nullptr); + + // invoke compute repeatedly + for (uint32_t i = 0; i < kNumberOfComputations; i++) { + const auto computeResult = createResult.value()->compute({}); + EXPECT_TRUE(computeResult.has_value()) << "Failed with " << computeResult.error().code + << ": " << computeResult.error().message; + } +} + +TEST(PreparedModelTest, reusableExecuteLaunchError) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + EXPECT_CALL(*mockPreparedModel, execute(_, _)) + .Times(1) + .WillOnce(Invoke(makeExecute(V1_0::ErrorStatus::GENERAL_FAILURE, + V1_0::ErrorStatus::GENERAL_FAILURE))); + + // create execution + const auto createResult = preparedModel->createReusableExecution({}, {}, {}); + ASSERT_TRUE(createResult.has_value()) + << "Failed with " << createResult.error().code << ": " << createResult.error().message; + ASSERT_NE(createResult.value(), nullptr); + + // invoke compute + const auto computeResult = createResult.value()->compute({}); + ASSERT_FALSE(computeResult.has_value()); + EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(PreparedModelTest, reusableExecuteReturnError) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + EXPECT_CALL(*mockPreparedModel, execute(_, _)) + .Times(1) + .WillOnce(Invoke( + makeExecute(V1_0::ErrorStatus::NONE, V1_0::ErrorStatus::GENERAL_FAILURE))); + + // create execution + const auto createResult = preparedModel->createReusableExecution({}, {}, {}); + ASSERT_TRUE(createResult.has_value()) + << "Failed with " << createResult.error().code << ": " << createResult.error().message; + ASSERT_NE(createResult.value(), nullptr); + + // invoke compute + const auto computeResult = createResult.value()->compute({}); + ASSERT_FALSE(computeResult.has_value()); + EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(PreparedModelTest, reusableExecuteTransportFailure) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + EXPECT_CALL(*mockPreparedModel, execute(_, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // create execution + const auto createResult = preparedModel->createReusableExecution({}, {}, {}); + ASSERT_TRUE(createResult.has_value()) + << "Failed with " << createResult.error().code << ": " << createResult.error().message; + ASSERT_NE(createResult.value(), nullptr); + + // invoke compute + const auto computeResult = createResult.value()->compute({}); + ASSERT_FALSE(computeResult.has_value()); + EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(PreparedModelTest, reusableExecuteDeadObject) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + EXPECT_CALL(*mockPreparedModel, execute(_, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // create execution + const auto createResult = preparedModel->createReusableExecution({}, {}, {}); + ASSERT_TRUE(createResult.has_value()) + << "Failed with " << createResult.error().code << ": " << createResult.error().message; + ASSERT_NE(createResult.value(), nullptr); + + // invoke compute + const auto computeResult = createResult.value()->compute({}); + ASSERT_FALSE(computeResult.has_value()); + EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(PreparedModelTest, reusableExecuteCrash) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto ret = [&mockPreparedModel]() -> hardware::Return { + mockPreparedModel->simulateCrash(); + return V1_0::ErrorStatus::NONE; + }; + EXPECT_CALL(*mockPreparedModel, execute(_, _)).Times(1).WillOnce(InvokeWithoutArgs(ret)); + + // create execution + const auto createResult = preparedModel->createReusableExecution({}, {}, {}); + ASSERT_TRUE(createResult.has_value()) + << "Failed with " << createResult.error().code << ": " << createResult.error().message; + ASSERT_NE(createResult.value(), nullptr); + + // invoke compute + const auto computeResult = createResult.value()->compute({}); + ASSERT_FALSE(computeResult.has_value()); + EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(PreparedModelTest, reusableExecuteFencedNotSupported) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + + // create execution + const auto createResult = preparedModel->createReusableExecution({}, {}, {}); + ASSERT_TRUE(createResult.has_value()) + << "Failed with " << createResult.error().code << ": " << createResult.error().message; + ASSERT_NE(createResult.value(), nullptr); + + // invoke compute + const auto computeResult = createResult.value()->computeFenced({}, {}, {}); + ASSERT_FALSE(computeResult.has_value()); + EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + TEST(PreparedModelTest, configureExecutionBurst) { // setup test const auto mockPreparedModel = MockPreparedModel::create(); diff --git a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Execution.h b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Execution.h new file mode 100644 index 0000000000..9c66446a2a --- /dev/null +++ b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Execution.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_1_2_UTILS_EXECUTION_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_2_UTILS_EXECUTION_H + +#include +#include +#include +#include +#include +#include + +#include "PreparedModel.h" + +#include +#include +#include + +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface +// lifetimes across processes and for protecting asynchronous calls across HIDL. + +namespace android::hardware::neuralnetworks::V1_2::utils { + +class Execution final : public nn::IExecution, public std::enable_shared_from_this { + struct PrivateConstructorTag {}; + + public: + static nn::GeneralResult> create( + std::shared_ptr preparedModel, V1_0::Request request, + hal::utils::RequestRelocation relocation, V1_2::MeasureTiming measure); + + Execution(PrivateConstructorTag tag, std::shared_ptr preparedModel, + V1_0::Request request, hal::utils::RequestRelocation relocation, + V1_2::MeasureTiming measure); + + nn::ExecutionResult, nn::Timing>> compute( + const nn::OptionalTimePoint& deadline) const override; + + nn::GeneralResult> computeFenced( + const std::vector& waitFor, const nn::OptionalTimePoint& deadline, + const nn::OptionalDuration& timeoutDurationAfterFence) const override; + + private: + const std::shared_ptr kPreparedModel; + const V1_0::Request kRequest; + const hal::utils::RequestRelocation kRelocation; + const MeasureTiming kMeasure; +}; + +} // namespace android::hardware::neuralnetworks::V1_2::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_2_UTILS_EXECUTION_H diff --git a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/PreparedModel.h b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/PreparedModel.h index fb1113051c..35abd7947b 100644 --- a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/PreparedModel.h +++ b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/PreparedModel.h @@ -58,10 +58,18 @@ class PreparedModel final : public nn::IPreparedModel, const nn::OptionalDuration& loopTimeoutDuration, const nn::OptionalDuration& timeoutDurationAfterFence) const override; + nn::GeneralResult createReusableExecution( + const nn::Request& request, nn::MeasureTiming measure, + const nn::OptionalDuration& loopTimeoutDuration) const override; + nn::GeneralResult configureExecutionBurst() const override; std::any getUnderlyingResource() const override; + nn::ExecutionResult, nn::Timing>> executeInternal( + const V1_0::Request& request, MeasureTiming measure, + const hal::utils::RequestRelocation& relocation) const; + private: nn::ExecutionResult, nn::Timing>> executeSynchronously( const V1_0::Request& request, MeasureTiming measure) const; diff --git a/neuralnetworks/1.2/utils/src/Execution.cpp b/neuralnetworks/1.2/utils/src/Execution.cpp new file mode 100644 index 0000000000..18d1c90edd --- /dev/null +++ b/neuralnetworks/1.2/utils/src/Execution.cpp @@ -0,0 +1,74 @@ +/* + * 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 "Execution.h" + +#include "Callbacks.h" +#include "Conversions.h" +#include "Utils.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface +// lifetimes across processes and for protecting asynchronous calls across HIDL. + +namespace android::hardware::neuralnetworks::V1_2::utils { + +nn::GeneralResult> Execution::create( + std::shared_ptr preparedModel, V1_0::Request request, + hal::utils::RequestRelocation relocation, V1_2::MeasureTiming measure) { + if (preparedModel == nullptr) { + return NN_ERROR() << "V1_2::utils::Execution::create must have non-null preparedModel"; + } + + return std::make_shared(PrivateConstructorTag{}, std::move(preparedModel), + std::move(request), std::move(relocation), measure); +} + +Execution::Execution(PrivateConstructorTag /*tag*/, + std::shared_ptr preparedModel, V1_0::Request request, + hal::utils::RequestRelocation relocation, V1_2::MeasureTiming measure) + : kPreparedModel(std::move(preparedModel)), + kRequest(std::move(request)), + kRelocation(std::move(relocation)), + kMeasure(measure) {} + +nn::ExecutionResult, nn::Timing>> Execution::compute( + const nn::OptionalTimePoint& /*deadline*/) const { + return kPreparedModel->executeInternal(kRequest, kMeasure, kRelocation); +} + +nn::GeneralResult> Execution::computeFenced( + const std::vector& /*waitFor*/, const nn::OptionalTimePoint& /*deadline*/, + const nn::OptionalDuration& /*timeoutDurationAfterFence*/) const { + return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) + << "IExecution::computeFenced is not supported on 1.2 HAL service"; +} + +} // namespace android::hardware::neuralnetworks::V1_2::utils diff --git a/neuralnetworks/1.2/utils/src/PreparedModel.cpp b/neuralnetworks/1.2/utils/src/PreparedModel.cpp index b209a44eba..e01401bdbb 100644 --- a/neuralnetworks/1.2/utils/src/PreparedModel.cpp +++ b/neuralnetworks/1.2/utils/src/PreparedModel.cpp @@ -18,6 +18,7 @@ #include "Callbacks.h" #include "Conversions.h" +#include "Execution.h" #include "ExecutionBurstController.h" #include "ExecutionBurstUtils.h" #include "Utils.h" @@ -93,19 +94,31 @@ nn::ExecutionResult, nn::Timing>> Prepare const nn::OptionalDuration& /*loopTimeoutDuration*/) const { // Ensure that request is ready for IPC. std::optional maybeRequestInShared; - const nn::Request& requestInShared = NN_TRY(hal::utils::makeExecutionFailure( - hal::utils::flushDataFromPointerToShared(&request, &maybeRequestInShared))); + hal::utils::RequestRelocation relocation; + const nn::Request& requestInShared = + NN_TRY(hal::utils::makeExecutionFailure(hal::utils::convertRequestFromPointerToShared( + &request, &maybeRequestInShared, &relocation))); const auto hidlRequest = NN_TRY(hal::utils::makeExecutionFailure(convert(requestInShared))); const auto hidlMeasure = NN_TRY(hal::utils::makeExecutionFailure(convert(measure))); - auto result = kExecuteSynchronously ? executeSynchronously(hidlRequest, hidlMeasure) - : executeAsynchronously(hidlRequest, hidlMeasure); - auto [outputShapes, timing] = NN_TRY(std::move(result)); + return executeInternal(hidlRequest, hidlMeasure, relocation); +} - NN_TRY(hal::utils::makeExecutionFailure( - hal::utils::unflushDataFromSharedToPointer(request, maybeRequestInShared))); +nn::ExecutionResult, nn::Timing>> +PreparedModel::executeInternal(const V1_0::Request& request, MeasureTiming measure, + const hal::utils::RequestRelocation& relocation) const { + if (relocation.input) { + relocation.input->flush(); + } + auto result = kExecuteSynchronously ? executeSynchronously(request, measure) + : executeAsynchronously(request, measure); + auto [outputShapes, timing] = NN_TRY(std::move(result)); + + if (relocation.output) { + relocation.output->flush(); + } return std::make_pair(std::move(outputShapes), timing); } @@ -120,6 +133,21 @@ PreparedModel::executeFenced(const nn::Request& /*request*/, << "IPreparedModel::executeFenced is not supported on 1.2 HAL service"; } +nn::GeneralResult PreparedModel::createReusableExecution( + const nn::Request& request, nn::MeasureTiming measure, + const nn::OptionalDuration& /*loopTimeoutDuration*/) const { + // Ensure that request is ready for IPC. + std::optional maybeRequestInShared; + hal::utils::RequestRelocation relocation; + const nn::Request& requestInShared = NN_TRY(hal::utils::convertRequestFromPointerToShared( + &request, &maybeRequestInShared, &relocation)); + + auto hidlRequest = NN_TRY(convert(requestInShared)); + auto hidlMeasure = NN_TRY(convert(measure)); + return Execution::create(shared_from_this(), std::move(hidlRequest), std::move(relocation), + hidlMeasure); +} + nn::GeneralResult PreparedModel::configureExecutionBurst() const { auto self = shared_from_this(); auto fallback = [preparedModel = std::move(self)]( diff --git a/neuralnetworks/1.2/utils/test/PreparedModelTest.cpp b/neuralnetworks/1.2/utils/test/PreparedModelTest.cpp index d297b1a417..5e2ad79df5 100644 --- a/neuralnetworks/1.2/utils/test/PreparedModelTest.cpp +++ b/neuralnetworks/1.2/utils/test/PreparedModelTest.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -334,6 +335,248 @@ TEST(PreparedModelTest, executeFencedNotSupported) { EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); } +TEST(PreparedModelTest, reusableExecuteSync) { + // setup call + const uint32_t kNumberOfComputations = 2; + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/true).value(); + EXPECT_CALL(*mockPreparedModel, executeSynchronously(_, _, _)) + .Times(kNumberOfComputations) + .WillRepeatedly( + Invoke(makeExecuteSynchronously(V1_0::ErrorStatus::NONE, {}, kNoTiming))); + + // create execution + const auto createResult = preparedModel->createReusableExecution({}, {}, {}); + ASSERT_TRUE(createResult.has_value()) + << "Failed with " << createResult.error().code << ": " << createResult.error().message; + ASSERT_NE(createResult.value(), nullptr); + + // invoke compute repeatedly + for (uint32_t i = 0; i < kNumberOfComputations; i++) { + const auto computeResult = createResult.value()->compute({}); + EXPECT_TRUE(computeResult.has_value()) << "Failed with " << computeResult.error().code + << ": " << computeResult.error().message; + } +} + +TEST(PreparedModelTest, reusableExecuteSyncError) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/true).value(); + EXPECT_CALL(*mockPreparedModel, executeSynchronously(_, _, _)) + .Times(1) + .WillOnce(Invoke( + makeExecuteSynchronously(V1_0::ErrorStatus::GENERAL_FAILURE, {}, kNoTiming))); + + // create execution + const auto createResult = preparedModel->createReusableExecution({}, {}, {}); + ASSERT_TRUE(createResult.has_value()) + << "Failed with " << createResult.error().code << ": " << createResult.error().message; + ASSERT_NE(createResult.value(), nullptr); + + // invoke compute + const auto computeResult = createResult.value()->compute({}); + ASSERT_FALSE(computeResult.has_value()); + EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(PreparedModelTest, reusableExecuteSyncTransportFailure) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/true).value(); + EXPECT_CALL(*mockPreparedModel, executeSynchronously(_, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // create execution + const auto createResult = preparedModel->createReusableExecution({}, {}, {}); + ASSERT_TRUE(createResult.has_value()) + << "Failed with " << createResult.error().code << ": " << createResult.error().message; + ASSERT_NE(createResult.value(), nullptr); + + // invoke compute + const auto computeResult = createResult.value()->compute({}); + ASSERT_FALSE(computeResult.has_value()); + EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(PreparedModelTest, reusableExecuteSyncDeadObject) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/true).value(); + EXPECT_CALL(*mockPreparedModel, executeSynchronously(_, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // create execution + const auto createResult = preparedModel->createReusableExecution({}, {}, {}); + ASSERT_TRUE(createResult.has_value()) + << "Failed with " << createResult.error().code << ": " << createResult.error().message; + ASSERT_NE(createResult.value(), nullptr); + + // invoke compute + const auto computeResult = createResult.value()->compute({}); + ASSERT_FALSE(computeResult.has_value()); + EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(PreparedModelTest, reusableExecuteAsync) { + // setup call + const uint32_t kNumberOfComputations = 2; + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/false).value(); + EXPECT_CALL(*mockPreparedModel, execute_1_2(_, _, _)) + .Times(kNumberOfComputations) + .WillRepeatedly(Invoke(makeExecuteAsynchronously( + V1_0::ErrorStatus::NONE, V1_0::ErrorStatus::NONE, {}, kNoTiming))); + + // create execution + const auto createResult = preparedModel->createReusableExecution({}, {}, {}); + ASSERT_TRUE(createResult.has_value()) + << "Failed with " << createResult.error().code << ": " << createResult.error().message; + ASSERT_NE(createResult.value(), nullptr); + + // invoke compute repeatedly + for (uint32_t i = 0; i < kNumberOfComputations; i++) { + const auto computeResult = createResult.value()->compute({}); + EXPECT_TRUE(computeResult.has_value()) << "Failed with " << computeResult.error().code + << ": " << computeResult.error().message; + } +} + +TEST(PreparedModelTest, reusableExecuteAsyncLaunchError) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/false).value(); + EXPECT_CALL(*mockPreparedModel, execute_1_2(_, _, _)) + .Times(1) + .WillOnce(Invoke(makeExecuteAsynchronously(V1_0::ErrorStatus::GENERAL_FAILURE, + V1_0::ErrorStatus::GENERAL_FAILURE, {}, + kNoTiming))); + + // create execution + const auto createResult = preparedModel->createReusableExecution({}, {}, {}); + ASSERT_TRUE(createResult.has_value()) + << "Failed with " << createResult.error().code << ": " << createResult.error().message; + ASSERT_NE(createResult.value(), nullptr); + + // invoke compute + const auto computeResult = createResult.value()->compute({}); + ASSERT_FALSE(computeResult.has_value()); + EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(PreparedModelTest, reusableExecuteAsyncReturnError) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/false).value(); + EXPECT_CALL(*mockPreparedModel, execute_1_2(_, _, _)) + .Times(1) + .WillOnce(Invoke(makeExecuteAsynchronously( + V1_0::ErrorStatus::NONE, V1_0::ErrorStatus::GENERAL_FAILURE, {}, kNoTiming))); + + // create execution + const auto createResult = preparedModel->createReusableExecution({}, {}, {}); + ASSERT_TRUE(createResult.has_value()) + << "Failed with " << createResult.error().code << ": " << createResult.error().message; + ASSERT_NE(createResult.value(), nullptr); + + // invoke compute + const auto computeResult = createResult.value()->compute({}); + ASSERT_FALSE(computeResult.has_value()); + EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(PreparedModelTest, reusableExecuteAsyncTransportFailure) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/false).value(); + EXPECT_CALL(*mockPreparedModel, execute_1_2(_, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // create execution + const auto createResult = preparedModel->createReusableExecution({}, {}, {}); + ASSERT_TRUE(createResult.has_value()) + << "Failed with " << createResult.error().code << ": " << createResult.error().message; + ASSERT_NE(createResult.value(), nullptr); + + // invoke compute + const auto computeResult = createResult.value()->compute({}); + ASSERT_FALSE(computeResult.has_value()); + EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(PreparedModelTest, reusableExecuteAsyncDeadObject) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/false).value(); + EXPECT_CALL(*mockPreparedModel, execute_1_2(_, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // create execution + const auto createResult = preparedModel->createReusableExecution({}, {}, {}); + ASSERT_TRUE(createResult.has_value()) + << "Failed with " << createResult.error().code << ": " << createResult.error().message; + ASSERT_NE(createResult.value(), nullptr); + + // invoke compute + const auto computeResult = createResult.value()->compute({}); + ASSERT_FALSE(computeResult.has_value()); + EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(PreparedModelTest, reusableExecuteAsyncCrash) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/false).value(); + const auto ret = [&mockPreparedModel]() -> hardware::Return { + mockPreparedModel->simulateCrash(); + return V1_0::ErrorStatus::NONE; + }; + EXPECT_CALL(*mockPreparedModel, execute_1_2(_, _, _)).Times(1).WillOnce(InvokeWithoutArgs(ret)); + + // create execution + const auto createResult = preparedModel->createReusableExecution({}, {}, {}); + ASSERT_TRUE(createResult.has_value()) + << "Failed with " << createResult.error().code << ": " << createResult.error().message; + ASSERT_NE(createResult.value(), nullptr); + + // invoke compute + const auto computeResult = createResult.value()->compute({}); + ASSERT_FALSE(computeResult.has_value()); + EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(PreparedModelTest, reusableExecuteFencedNotSupported) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/true).value(); + + // create execution + const auto createResult = preparedModel->createReusableExecution({}, {}, {}); + ASSERT_TRUE(createResult.has_value()) + << "Failed with " << createResult.error().code << ": " << createResult.error().message; + ASSERT_NE(createResult.value(), nullptr); + + // invoke compute + const auto computeResult = createResult.value()->computeFenced({}, {}, {}); + ASSERT_FALSE(computeResult.has_value()); + EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + TEST(PreparedModelTest, configureExecutionBurst) { // setup test const auto mockPreparedModel = MockPreparedModel::create(); diff --git a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Execution.h b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Execution.h new file mode 100644 index 0000000000..06c33d4274 --- /dev/null +++ b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Execution.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_1_3_UTILS_EXECUTION_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_3_UTILS_EXECUTION_H + +#include +#include +#include +#include + +#include "PreparedModel.h" + +#include +#include +#include + +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface +// lifetimes across processes and for protecting asynchronous calls across HIDL. + +namespace android::hardware::neuralnetworks::V1_3::utils { + +class Execution final : public nn::IExecution, public std::enable_shared_from_this { + struct PrivateConstructorTag {}; + + public: + static nn::GeneralResult> create( + std::shared_ptr preparedModel, Request request, + hal::utils::RequestRelocation relocation, V1_2::MeasureTiming measure, + OptionalTimeoutDuration loopTimeoutDuration); + + Execution(PrivateConstructorTag tag, std::shared_ptr preparedModel, + Request request, hal::utils::RequestRelocation relocation, + V1_2::MeasureTiming measure, OptionalTimeoutDuration loopTimeoutDuration); + + nn::ExecutionResult, nn::Timing>> compute( + const nn::OptionalTimePoint& deadline) const override; + + nn::GeneralResult> computeFenced( + const std::vector& waitFor, const nn::OptionalTimePoint& deadline, + const nn::OptionalDuration& timeoutDurationAfterFence) const override; + + private: + const std::shared_ptr kPreparedModel; + const Request kRequest; + const hal::utils::RequestRelocation kRelocation; + const V1_2::MeasureTiming kMeasure; + const OptionalTimeoutDuration kLoopTimeoutDuration; +}; + +} // namespace android::hardware::neuralnetworks::V1_3::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_1_3_UTILS_EXECUTION_H diff --git a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/PreparedModel.h b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/PreparedModel.h index 690fecccfb..5acba71826 100644 --- a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/PreparedModel.h +++ b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/PreparedModel.h @@ -57,10 +57,26 @@ class PreparedModel final : public nn::IPreparedModel, const nn::OptionalDuration& loopTimeoutDuration, const nn::OptionalDuration& timeoutDurationAfterFence) const override; + nn::GeneralResult createReusableExecution( + const nn::Request& request, nn::MeasureTiming measure, + const nn::OptionalDuration& loopTimeoutDuration) const override; + nn::GeneralResult configureExecutionBurst() const override; std::any getUnderlyingResource() const override; + nn::ExecutionResult, nn::Timing>> executeInternal( + const Request& request, V1_2::MeasureTiming measure, const OptionalTimePoint& deadline, + const OptionalTimeoutDuration& loopTimeoutDuration, + const hal::utils::RequestRelocation& relocation) const; + + nn::GeneralResult> + executeFencedInternal(const Request& request, const hidl_vec& waitFor, + V1_2::MeasureTiming measure, const OptionalTimePoint& deadline, + const OptionalTimeoutDuration& loopTimeoutDuration, + const OptionalTimeoutDuration& timeoutDurationAfterFence, + const hal::utils::RequestRelocation& relocation) const; + private: nn::ExecutionResult, nn::Timing>> executeSynchronously( const Request& request, V1_2::MeasureTiming measure, const OptionalTimePoint& deadline, diff --git a/neuralnetworks/1.3/utils/src/Execution.cpp b/neuralnetworks/1.3/utils/src/Execution.cpp new file mode 100644 index 0000000000..3d17cc3ef4 --- /dev/null +++ b/neuralnetworks/1.3/utils/src/Execution.cpp @@ -0,0 +1,84 @@ +/* + * 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 "Execution.h" + +#include "Conversions.h" +#include "PreparedModel.h" +#include "Utils.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface +// lifetimes across processes and for protecting asynchronous calls across HIDL. + +namespace android::hardware::neuralnetworks::V1_3::utils { + +nn::GeneralResult> Execution::create( + std::shared_ptr preparedModel, Request request, + hal::utils::RequestRelocation relocation, V1_2::MeasureTiming measure, + OptionalTimeoutDuration loopTimeoutDuration) { + if (preparedModel == nullptr) { + return NN_ERROR() << "V1_3::utils::Execution::create must have non-null preparedModel"; + } + + return std::make_shared(PrivateConstructorTag{}, std::move(preparedModel), + std::move(request), std::move(relocation), measure, + std::move(loopTimeoutDuration)); +} + +Execution::Execution(PrivateConstructorTag /*tag*/, + std::shared_ptr preparedModel, Request request, + hal::utils::RequestRelocation relocation, V1_2::MeasureTiming measure, + OptionalTimeoutDuration loopTimeoutDuration) + : kPreparedModel(std::move(preparedModel)), + kRequest(std::move(request)), + kRelocation(std::move(relocation)), + kMeasure(measure), + kLoopTimeoutDuration(std::move(loopTimeoutDuration)) {} + +nn::ExecutionResult, nn::Timing>> Execution::compute( + const nn::OptionalTimePoint& deadline) const { + const auto hidlDeadline = NN_TRY(hal::utils::makeExecutionFailure(convert(deadline))); + return kPreparedModel->executeInternal(kRequest, kMeasure, hidlDeadline, kLoopTimeoutDuration, + kRelocation); +} + +nn::GeneralResult> Execution::computeFenced( + const std::vector& waitFor, const nn::OptionalTimePoint& deadline, + const nn::OptionalDuration& timeoutDurationAfterFence) const { + const auto hidlWaitFor = NN_TRY(hal::utils::convertSyncFences(waitFor)); + const auto hidlDeadline = NN_TRY(convert(deadline)); + const auto hidlTimeoutDurationAfterFence = NN_TRY(convert(timeoutDurationAfterFence)); + return kPreparedModel->executeFencedInternal(kRequest, hidlWaitFor, kMeasure, hidlDeadline, + kLoopTimeoutDuration, + hidlTimeoutDurationAfterFence, kRelocation); +} + +} // namespace android::hardware::neuralnetworks::V1_3::utils diff --git a/neuralnetworks/1.3/utils/src/PreparedModel.cpp b/neuralnetworks/1.3/utils/src/PreparedModel.cpp index fd7f8f2ba8..5163e8ac9d 100644 --- a/neuralnetworks/1.3/utils/src/PreparedModel.cpp +++ b/neuralnetworks/1.3/utils/src/PreparedModel.cpp @@ -18,6 +18,7 @@ #include "Callbacks.h" #include "Conversions.h" +#include "Execution.h" #include "Utils.h" #include @@ -139,8 +140,10 @@ nn::ExecutionResult, nn::Timing>> Prepare const nn::OptionalDuration& loopTimeoutDuration) const { // Ensure that request is ready for IPC. std::optional maybeRequestInShared; - const nn::Request& requestInShared = NN_TRY(hal::utils::makeExecutionFailure( - hal::utils::flushDataFromPointerToShared(&request, &maybeRequestInShared))); + hal::utils::RequestRelocation relocation; + const nn::Request& requestInShared = + NN_TRY(hal::utils::makeExecutionFailure(hal::utils::convertRequestFromPointerToShared( + &request, &maybeRequestInShared, &relocation))); const auto hidlRequest = NN_TRY(hal::utils::makeExecutionFailure(convert(requestInShared))); const auto hidlMeasure = NN_TRY(hal::utils::makeExecutionFailure(convert(measure))); @@ -148,16 +151,27 @@ nn::ExecutionResult, nn::Timing>> Prepare const auto hidlLoopTimeoutDuration = NN_TRY(hal::utils::makeExecutionFailure(convert(loopTimeoutDuration))); + return executeInternal(hidlRequest, hidlMeasure, hidlDeadline, hidlLoopTimeoutDuration, + relocation); +} + +nn::ExecutionResult, nn::Timing>> +PreparedModel::executeInternal(const Request& request, V1_2::MeasureTiming measure, + const OptionalTimePoint& deadline, + const OptionalTimeoutDuration& loopTimeoutDuration, + const hal::utils::RequestRelocation& relocation) const { + if (relocation.input) { + relocation.input->flush(); + } + auto result = kExecuteSynchronously - ? executeSynchronously(hidlRequest, hidlMeasure, hidlDeadline, - hidlLoopTimeoutDuration) - : executeAsynchronously(hidlRequest, hidlMeasure, hidlDeadline, - hidlLoopTimeoutDuration); + ? executeSynchronously(request, measure, deadline, loopTimeoutDuration) + : executeAsynchronously(request, measure, deadline, loopTimeoutDuration); auto [outputShapes, timing] = NN_TRY(std::move(result)); - NN_TRY(hal::utils::makeExecutionFailure( - hal::utils::unflushDataFromSharedToPointer(request, maybeRequestInShared))); - + if (relocation.output) { + relocation.output->flush(); + } return std::make_pair(std::move(outputShapes), timing); } @@ -168,8 +182,9 @@ PreparedModel::executeFenced(const nn::Request& request, const std::vector maybeRequestInShared; - const nn::Request& requestInShared = - NN_TRY(hal::utils::flushDataFromPointerToShared(&request, &maybeRequestInShared)); + hal::utils::RequestRelocation relocation; + const nn::Request& requestInShared = NN_TRY(hal::utils::convertRequestFromPointerToShared( + &request, &maybeRequestInShared, &relocation)); const auto hidlRequest = NN_TRY(convert(requestInShared)); const auto hidlWaitFor = NN_TRY(hal::utils::convertSyncFences(waitFor)); @@ -178,27 +193,58 @@ PreparedModel::executeFenced(const nn::Request& request, const std::vector> +PreparedModel::executeFencedInternal(const Request& request, const hidl_vec& waitFor, + V1_2::MeasureTiming measure, const OptionalTimePoint& deadline, + const OptionalTimeoutDuration& loopTimeoutDuration, + const OptionalTimeoutDuration& timeoutDurationAfterFence, + const hal::utils::RequestRelocation& relocation) const { + if (relocation.input) { + relocation.input->flush(); + } + auto cb = hal::utils::CallbackValue(fencedExecutionCallback); - const auto ret = kPreparedModel->executeFenced(hidlRequest, hidlWaitFor, hidlMeasure, - hidlDeadline, hidlLoopTimeoutDuration, - hidlTimeoutDurationAfterFence, cb); + const auto ret = + kPreparedModel->executeFenced(request, waitFor, measure, deadline, loopTimeoutDuration, + timeoutDurationAfterFence, cb); HANDLE_TRANSPORT_FAILURE(ret); auto [syncFence, callback] = NN_TRY(cb.take()); // 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 (maybeRequestInShared.has_value()) { + if (relocation.output) { const auto state = syncFence.syncWait({}); if (state != nn::SyncFence::FenceState::SIGNALED) { return NN_ERROR() << "syncWait failed with " << state; } - NN_TRY(hal::utils::unflushDataFromSharedToPointer(request, maybeRequestInShared)); + relocation.output->flush(); } return std::make_pair(std::move(syncFence), std::move(callback)); } +nn::GeneralResult PreparedModel::createReusableExecution( + const nn::Request& request, nn::MeasureTiming measure, + const nn::OptionalDuration& loopTimeoutDuration) const { + // Ensure that request is ready for IPC. + std::optional maybeRequestInShared; + hal::utils::RequestRelocation relocation; + const nn::Request& requestInShared = NN_TRY(hal::utils::convertRequestFromPointerToShared( + &request, &maybeRequestInShared, &relocation)); + + auto hidlRequest = NN_TRY(convert(requestInShared)); + auto hidlMeasure = NN_TRY(convert(measure)); + auto hidlLoopTimeoutDuration = NN_TRY(convert(loopTimeoutDuration)); + return Execution::create(shared_from_this(), std::move(hidlRequest), std::move(relocation), + hidlMeasure, std::move(hidlLoopTimeoutDuration)); +} + nn::GeneralResult PreparedModel::configureExecutionBurst() const { auto self = shared_from_this(); auto fallback = [preparedModel = std::move(self)]( diff --git a/neuralnetworks/1.3/utils/test/PreparedModelTest.cpp b/neuralnetworks/1.3/utils/test/PreparedModelTest.cpp index 5303c2ad23..6dbbd6bd7e 100644 --- a/neuralnetworks/1.3/utils/test/PreparedModelTest.cpp +++ b/neuralnetworks/1.3/utils/test/PreparedModelTest.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -462,6 +463,363 @@ TEST(PreparedModelTest, executeFencedDeadObject) { EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); } +TEST(PreparedModelTest, reusableExecuteSync) { + // setup call + const uint32_t kNumberOfComputations = 2; + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/true).value(); + EXPECT_CALL(*mockPreparedModel, executeSynchronously_1_3(_, _, _, _, _)) + .Times(kNumberOfComputations) + .WillRepeatedly( + Invoke(makeExecuteSynchronously(V1_3::ErrorStatus::NONE, {}, kNoTiming))); + + // create execution + const auto createResult = preparedModel->createReusableExecution({}, {}, {}); + ASSERT_TRUE(createResult.has_value()) + << "Failed with " << createResult.error().code << ": " << createResult.error().message; + ASSERT_NE(createResult.value(), nullptr); + + // invoke compute repeatedly + for (uint32_t i = 0; i < kNumberOfComputations; i++) { + const auto computeResult = createResult.value()->compute({}); + EXPECT_TRUE(computeResult.has_value()) << "Failed with " << computeResult.error().code + << ": " << computeResult.error().message; + } +} + +TEST(PreparedModelTest, reusableExecuteSyncError) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/true).value(); + EXPECT_CALL(*mockPreparedModel, executeSynchronously_1_3(_, _, _, _, _)) + .Times(1) + .WillOnce(Invoke( + makeExecuteSynchronously(V1_3::ErrorStatus::GENERAL_FAILURE, {}, kNoTiming))); + + // create execution + const auto createResult = preparedModel->createReusableExecution({}, {}, {}); + ASSERT_TRUE(createResult.has_value()) + << "Failed with " << createResult.error().code << ": " << createResult.error().message; + ASSERT_NE(createResult.value(), nullptr); + + // invoke compute + const auto computeResult = createResult.value()->compute({}); + ASSERT_FALSE(computeResult.has_value()); + EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(PreparedModelTest, reusableExecuteSyncTransportFailure) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/true).value(); + EXPECT_CALL(*mockPreparedModel, executeSynchronously_1_3(_, _, _, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // create execution + const auto createResult = preparedModel->createReusableExecution({}, {}, {}); + ASSERT_TRUE(createResult.has_value()) + << "Failed with " << createResult.error().code << ": " << createResult.error().message; + ASSERT_NE(createResult.value(), nullptr); + + // invoke compute + const auto computeResult = createResult.value()->compute({}); + ASSERT_FALSE(computeResult.has_value()); + EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(PreparedModelTest, reusableExecuteSyncDeadObject) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/true).value(); + EXPECT_CALL(*mockPreparedModel, executeSynchronously_1_3(_, _, _, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // create execution + const auto createResult = preparedModel->createReusableExecution({}, {}, {}); + ASSERT_TRUE(createResult.has_value()) + << "Failed with " << createResult.error().code << ": " << createResult.error().message; + ASSERT_NE(createResult.value(), nullptr); + + // invoke compute + const auto computeResult = createResult.value()->compute({}); + ASSERT_FALSE(computeResult.has_value()); + EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(PreparedModelTest, reusableExecuteAsync) { + // setup call + const uint32_t kNumberOfComputations = 2; + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/false).value(); + EXPECT_CALL(*mockPreparedModel, execute_1_3(_, _, _, _, _)) + .Times(kNumberOfComputations) + .WillRepeatedly(Invoke(makeExecuteAsynchronously( + V1_3::ErrorStatus::NONE, V1_3::ErrorStatus::NONE, {}, kNoTiming))); + + // create execution + const auto createResult = preparedModel->createReusableExecution({}, {}, {}); + ASSERT_TRUE(createResult.has_value()) + << "Failed with " << createResult.error().code << ": " << createResult.error().message; + ASSERT_NE(createResult.value(), nullptr); + + // invoke compute repeatedly + for (uint32_t i = 0; i < kNumberOfComputations; i++) { + const auto computeResult = createResult.value()->compute({}); + EXPECT_TRUE(computeResult.has_value()) << "Failed with " << computeResult.error().code + << ": " << computeResult.error().message; + } +} + +TEST(PreparedModelTest, reusableExecuteAsyncLaunchError) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/false).value(); + EXPECT_CALL(*mockPreparedModel, execute_1_3(_, _, _, _, _)) + .Times(1) + .WillOnce(Invoke(makeExecuteAsynchronously(V1_3::ErrorStatus::GENERAL_FAILURE, + V1_3::ErrorStatus::GENERAL_FAILURE, {}, + kNoTiming))); + + // create execution + const auto createResult = preparedModel->createReusableExecution({}, {}, {}); + ASSERT_TRUE(createResult.has_value()) + << "Failed with " << createResult.error().code << ": " << createResult.error().message; + ASSERT_NE(createResult.value(), nullptr); + + // invoke compute + const auto computeResult = createResult.value()->compute({}); + ASSERT_FALSE(computeResult.has_value()); + EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(PreparedModelTest, reusableExecuteAsyncReturnError) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/false).value(); + EXPECT_CALL(*mockPreparedModel, execute_1_3(_, _, _, _, _)) + .Times(1) + .WillOnce(Invoke(makeExecuteAsynchronously( + V1_3::ErrorStatus::NONE, V1_3::ErrorStatus::GENERAL_FAILURE, {}, kNoTiming))); + + // run test + const auto result = preparedModel->execute({}, {}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(PreparedModelTest, reusableExecuteAsyncTransportFailure) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/false).value(); + EXPECT_CALL(*mockPreparedModel, execute_1_3(_, _, _, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // create execution + const auto createResult = preparedModel->createReusableExecution({}, {}, {}); + ASSERT_TRUE(createResult.has_value()) + << "Failed with " << createResult.error().code << ": " << createResult.error().message; + ASSERT_NE(createResult.value(), nullptr); + + // invoke compute + const auto computeResult = createResult.value()->compute({}); + ASSERT_FALSE(computeResult.has_value()); + EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(PreparedModelTest, reusableExecuteAsyncDeadObject) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/false).value(); + EXPECT_CALL(*mockPreparedModel, execute_1_3(_, _, _, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // create execution + const auto createResult = preparedModel->createReusableExecution({}, {}, {}); + ASSERT_TRUE(createResult.has_value()) + << "Failed with " << createResult.error().code << ": " << createResult.error().message; + ASSERT_NE(createResult.value(), nullptr); + + // invoke compute + const auto computeResult = createResult.value()->compute({}); + ASSERT_FALSE(computeResult.has_value()); + EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(PreparedModelTest, reusableExecuteAsyncCrash) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/false).value(); + const auto ret = [&mockPreparedModel]() -> hardware::Return { + mockPreparedModel->simulateCrash(); + return V1_3::ErrorStatus::NONE; + }; + EXPECT_CALL(*mockPreparedModel, execute_1_3(_, _, _, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(ret)); + + // create execution + const auto createResult = preparedModel->createReusableExecution({}, {}, {}); + ASSERT_TRUE(createResult.has_value()) + << "Failed with " << createResult.error().code << ": " << createResult.error().message; + ASSERT_NE(createResult.value(), nullptr); + + // invoke compute + const auto computeResult = createResult.value()->compute({}); + ASSERT_FALSE(computeResult.has_value()); + EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(PreparedModelTest, reusableExecuteFenced) { + // setup call + const uint32_t kNumberOfComputations = 2; + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/true).value(); + const auto mockCallback = MockFencedExecutionCallback::create(); + EXPECT_CALL(*mockCallback, getExecutionInfo(_)) + .Times(kNumberOfComputations) + .WillRepeatedly(Invoke(makeExecuteFencedCallbackReturn(V1_3::ErrorStatus::NONE, + kNoTiming, kNoTiming))); + EXPECT_CALL(*mockPreparedModel, executeFenced(_, _, _, _, _, _, _)) + .Times(kNumberOfComputations) + .WillRepeatedly( + Invoke(makeExecuteFencedReturn(V1_3::ErrorStatus::NONE, {}, mockCallback))); + + // create execution + const auto createResult = preparedModel->createReusableExecution({}, {}, {}); + ASSERT_TRUE(createResult.has_value()) + << "Failed with " << createResult.error().code << ": " << createResult.error().message; + ASSERT_NE(createResult.value(), nullptr); + + // invoke compute repeatedly + for (uint32_t i = 0; i < kNumberOfComputations; i++) { + const auto computeResult = createResult.value()->computeFenced({}, {}, {}); + ASSERT_TRUE(computeResult.has_value()) << "Failed with " << computeResult.error().code + << ": " << computeResult.error().message; + const auto& [syncFence, callback] = computeResult.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(PreparedModelTest, reusableExecuteFencedCallbackError) { + // setup call + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/true).value(); + const auto mockCallback = MockFencedExecutionCallback::create(); + EXPECT_CALL(*mockCallback, getExecutionInfo(_)) + .Times(1) + .WillOnce(Invoke(makeExecuteFencedCallbackReturn(V1_3::ErrorStatus::GENERAL_FAILURE, + kNoTiming, kNoTiming))); + EXPECT_CALL(*mockPreparedModel, executeFenced(_, _, _, _, _, _, _)) + .Times(1) + .WillOnce(Invoke(makeExecuteFencedReturn(V1_3::ErrorStatus::NONE, {}, mockCallback))); + + // create execution + const auto createResult = preparedModel->createReusableExecution({}, {}, {}); + ASSERT_TRUE(createResult.has_value()) + << "Failed with " << createResult.error().code << ": " << createResult.error().message; + ASSERT_NE(createResult.value(), nullptr); + + // invoke compute + const auto computeResult = createResult.value()->computeFenced({}, {}, {}); + ASSERT_TRUE(computeResult.has_value()) << "Failed with " << computeResult.error().code << ": " + << computeResult.error().message; + const auto& [syncFence, callback] = computeResult.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(PreparedModelTest, reusableExecuteFencedError) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/true).value(); + EXPECT_CALL(*mockPreparedModel, executeFenced(_, _, _, _, _, _, _)) + .Times(1) + .WillOnce(Invoke( + makeExecuteFencedReturn(V1_3::ErrorStatus::GENERAL_FAILURE, {}, nullptr))); + + // create execution + const auto createResult = preparedModel->createReusableExecution({}, {}, {}); + ASSERT_TRUE(createResult.has_value()) + << "Failed with " << createResult.error().code << ": " << createResult.error().message; + ASSERT_NE(createResult.value(), nullptr); + + // invoke compute + const auto computeResult = createResult.value()->computeFenced({}, {}, {}); + ASSERT_FALSE(computeResult.has_value()); + EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(PreparedModelTest, reusableExecuteFencedTransportFailure) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/true).value(); + EXPECT_CALL(*mockPreparedModel, executeFenced(_, _, _, _, _, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // create execution + const auto createResult = preparedModel->createReusableExecution({}, {}, {}); + ASSERT_TRUE(createResult.has_value()) + << "Failed with " << createResult.error().code << ": " << createResult.error().message; + ASSERT_NE(createResult.value(), nullptr); + + // invoke compute + const auto computeResult = createResult.value()->computeFenced({}, {}, {}); + ASSERT_FALSE(computeResult.has_value()); + EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(PreparedModelTest, reusableExecuteFencedDeadObject) { + // setup test + const auto mockPreparedModel = createMockPreparedModel(); + const auto preparedModel = + PreparedModel::create(mockPreparedModel, /*executeSynchronously=*/true).value(); + EXPECT_CALL(*mockPreparedModel, executeFenced(_, _, _, _, _, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // create execution + const auto createResult = preparedModel->createReusableExecution({}, {}, {}); + ASSERT_TRUE(createResult.has_value()) + << "Failed with " << createResult.error().code << ": " << createResult.error().message; + ASSERT_NE(createResult.value(), nullptr); + + // invoke compute + const auto computeResult = createResult.value()->computeFenced({}, {}, {}); + ASSERT_FALSE(computeResult.has_value()); + EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::DEAD_OBJECT); +} TEST(PreparedModelTest, configureExecutionBurst) { // setup test const auto mockPreparedModel = MockPreparedModel::create(); diff --git a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Execution.h b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Execution.h new file mode 100644 index 0000000000..a77ea984b2 --- /dev/null +++ b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Execution.h @@ -0,0 +1,65 @@ +/* + * 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_EXECUTION_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_AIDL_UTILS_EXECUTION_H + +#include +#include +#include +#include + +#include "PreparedModel.h" + +#include +#include +#include + +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface +// lifetimes across processes and for protecting asynchronous calls across HIDL. + +namespace aidl::android::hardware::neuralnetworks::utils { + +class Execution final : public nn::IExecution, public std::enable_shared_from_this { + struct PrivateConstructorTag {}; + + public: + static nn::GeneralResult> create( + std::shared_ptr preparedModel, Request request, + hal::utils::RequestRelocation relocation, bool measure, int64_t loopTimeoutDuration); + + Execution(PrivateConstructorTag tag, std::shared_ptr preparedModel, + Request request, hal::utils::RequestRelocation relocation, bool measure, + int64_t loopTimeoutDuration); + + nn::ExecutionResult, nn::Timing>> compute( + const nn::OptionalTimePoint& deadline) const override; + + nn::GeneralResult> computeFenced( + const std::vector& waitFor, const nn::OptionalTimePoint& deadline, + const nn::OptionalDuration& timeoutDurationAfterFence) const override; + + private: + const std::shared_ptr kPreparedModel; + const Request kRequest; + const hal::utils::RequestRelocation kRelocation; + const bool kMeasure; + const int64_t kLoopTimeoutDuration; +}; + +} // 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/PreparedModel.h b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/PreparedModel.h index abce6cc3aa..4035764ea4 100644 --- a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/PreparedModel.h +++ b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/PreparedModel.h @@ -18,6 +18,7 @@ #define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_AIDL_UTILS_PREPARED_MODEL_H #include +#include #include #include #include @@ -34,7 +35,8 @@ namespace aidl::android::hardware::neuralnetworks::utils { // Class that adapts aidl_hal::IPreparedModel to nn::IPreparedModel. -class PreparedModel final : public nn::IPreparedModel { +class PreparedModel final : public nn::IPreparedModel, + public std::enable_shared_from_this { struct PrivateConstructorTag {}; public: @@ -55,10 +57,25 @@ class PreparedModel final : public nn::IPreparedModel { const nn::OptionalDuration& loopTimeoutDuration, const nn::OptionalDuration& timeoutDurationAfterFence) const override; + nn::GeneralResult createReusableExecution( + const nn::Request& request, nn::MeasureTiming measure, + const nn::OptionalDuration& loopTimeoutDuration) const override; + nn::GeneralResult configureExecutionBurst() const override; std::any getUnderlyingResource() const override; + nn::ExecutionResult, nn::Timing>> executeInternal( + const Request& request, bool measure, int64_t deadline, int64_t loopTimeoutDuration, + const hal::utils::RequestRelocation& relocation) const; + + nn::GeneralResult> + executeFencedInternal(const Request& request, + const std::vector& waitFor, bool measure, + int64_t deadline, int64_t loopTimeoutDuration, + int64_t timeoutDurationAfterFence, + const hal::utils::RequestRelocation& relocation) const; + private: const std::shared_ptr kPreparedModel; }; diff --git a/neuralnetworks/aidl/utils/src/Burst.cpp b/neuralnetworks/aidl/utils/src/Burst.cpp index 0b475bcf53..b20f6ae8e1 100644 --- a/neuralnetworks/aidl/utils/src/Burst.cpp +++ b/neuralnetworks/aidl/utils/src/Burst.cpp @@ -148,8 +148,10 @@ nn::ExecutionResult, nn::Timing>> Burst:: // Ensure that request is ready for IPC. std::optional maybeRequestInShared; - const nn::Request& requestInShared = NN_TRY(hal::utils::makeExecutionFailure( - hal::utils::flushDataFromPointerToShared(&request, &maybeRequestInShared))); + hal::utils::RequestRelocation relocation; + const nn::Request& requestInShared = + NN_TRY(hal::utils::makeExecutionFailure(hal::utils::convertRequestFromPointerToShared( + &request, &maybeRequestInShared, &relocation))); const auto aidlRequest = NN_TRY(hal::utils::makeExecutionFailure(convert(requestInShared))); const auto aidlMeasure = NN_TRY(hal::utils::makeExecutionFailure(convert(measure))); @@ -174,6 +176,10 @@ nn::ExecutionResult, nn::Timing>> Burst:: } CHECK_EQ(request.pools.size(), memoryIdentifierTokens.size()); + if (relocation.input) { + relocation.input->flush(); + } + ExecutionResult executionResult; const auto ret = kBurst->executeSynchronously(aidlRequest, memoryIdentifierTokens, aidlMeasure, @@ -188,9 +194,9 @@ nn::ExecutionResult, nn::Timing>> Burst:: auto [outputShapes, timing] = NN_TRY(hal::utils::makeExecutionFailure( convertExecutionResults(executionResult.outputShapes, executionResult.timing))); - NN_TRY(hal::utils::makeExecutionFailure( - hal::utils::unflushDataFromSharedToPointer(request, maybeRequestInShared))); - + if (relocation.output) { + relocation.output->flush(); + } return std::make_pair(std::move(outputShapes), timing); } diff --git a/neuralnetworks/aidl/utils/src/Execution.cpp b/neuralnetworks/aidl/utils/src/Execution.cpp new file mode 100644 index 0000000000..2aee8a6713 --- /dev/null +++ b/neuralnetworks/aidl/utils/src/Execution.cpp @@ -0,0 +1,79 @@ +/* + * 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 "Execution.h" + +#include "Conversions.h" +#include "PreparedModel.h" +#include "Utils.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +// See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface +// lifetimes across processes and for protecting asynchronous calls across HIDL. + +namespace aidl::android::hardware::neuralnetworks::utils { + +nn::GeneralResult> Execution::create( + std::shared_ptr 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 std::make_shared(PrivateConstructorTag{}, std::move(preparedModel), + std::move(request), std::move(relocation), measure, + loopTimeoutDuration); +} + +Execution::Execution(PrivateConstructorTag /*tag*/, + std::shared_ptr 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, nn::Timing>> Execution::compute( + const nn::OptionalTimePoint& deadline) const { + const auto aidlDeadline = NN_TRY(hal::utils::makeExecutionFailure(convert(deadline))); + return kPreparedModel->executeInternal(kRequest, kMeasure, aidlDeadline, kLoopTimeoutDuration, + kRelocation); +} + +nn::GeneralResult> Execution::computeFenced( + const std::vector& 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)); + return kPreparedModel->executeFencedInternal(kRequest, aidlWaitFor, kMeasure, aidlDeadline, + kLoopTimeoutDuration, + aidlTimeoutDurationAfterFence, kRelocation); +} + +} // namespace aidl::android::hardware::neuralnetworks::utils diff --git a/neuralnetworks/aidl/utils/src/PreparedModel.cpp b/neuralnetworks/aidl/utils/src/PreparedModel.cpp index 003965b619..191560786f 100644 --- a/neuralnetworks/aidl/utils/src/PreparedModel.cpp +++ b/neuralnetworks/aidl/utils/src/PreparedModel.cpp @@ -19,8 +19,11 @@ #include "Burst.h" #include "Callbacks.h" #include "Conversions.h" +#include "Execution.h" +#include "ProtectCallback.h" #include "Utils.h" +#include #include #include #include @@ -74,18 +77,31 @@ nn::ExecutionResult, nn::Timing>> Prepare const nn::OptionalDuration& loopTimeoutDuration) const { // Ensure that request is ready for IPC. std::optional maybeRequestInShared; - const nn::Request& requestInShared = NN_TRY(hal::utils::makeExecutionFailure( - hal::utils::flushDataFromPointerToShared(&request, &maybeRequestInShared))); + hal::utils::RequestRelocation relocation; + const nn::Request& requestInShared = + NN_TRY(hal::utils::makeExecutionFailure(hal::utils::convertRequestFromPointerToShared( + &request, &maybeRequestInShared, &relocation))); const auto aidlRequest = NN_TRY(hal::utils::makeExecutionFailure(convert(requestInShared))); const auto aidlMeasure = NN_TRY(hal::utils::makeExecutionFailure(convert(measure))); const auto aidlDeadline = NN_TRY(hal::utils::makeExecutionFailure(convert(deadline))); const auto aidlLoopTimeoutDuration = NN_TRY(hal::utils::makeExecutionFailure(convert(loopTimeoutDuration))); + return executeInternal(aidlRequest, aidlMeasure, aidlDeadline, aidlLoopTimeoutDuration, + relocation); +} + +nn::ExecutionResult, nn::Timing>> +PreparedModel::executeInternal(const Request& request, bool measure, int64_t deadline, + int64_t loopTimeoutDuration, + const hal::utils::RequestRelocation& relocation) const { + if (relocation.input) { + relocation.input->flush(); + } ExecutionResult executionResult; - const auto ret = kPreparedModel->executeSynchronously( - aidlRequest, aidlMeasure, aidlDeadline, aidlLoopTimeoutDuration, &executionResult); + const auto ret = kPreparedModel->executeSynchronously(request, measure, deadline, + loopTimeoutDuration, &executionResult); HANDLE_ASTATUS(ret) << "executeSynchronously failed"; if (!executionResult.outputSufficientSize) { auto canonicalOutputShapes = @@ -96,9 +112,9 @@ nn::ExecutionResult, nn::Timing>> Prepare auto [outputShapes, timing] = NN_TRY(hal::utils::makeExecutionFailure( convertExecutionResults(executionResult.outputShapes, executionResult.timing))); - NN_TRY(hal::utils::makeExecutionFailure( - hal::utils::unflushDataFromSharedToPointer(request, maybeRequestInShared))); - + if (relocation.output) { + relocation.output->flush(); + } return std::make_pair(std::move(outputShapes), timing); } @@ -109,8 +125,9 @@ PreparedModel::executeFenced(const nn::Request& request, const std::vector maybeRequestInShared; - const nn::Request& requestInShared = - NN_TRY(hal::utils::flushDataFromPointerToShared(&request, &maybeRequestInShared)); + hal::utils::RequestRelocation relocation; + const nn::Request& requestInShared = NN_TRY(hal::utils::convertRequestFromPointerToShared( + &request, &maybeRequestInShared, &relocation)); const auto aidlRequest = NN_TRY(convert(requestInShared)); const auto aidlWaitFor = NN_TRY(convert(waitFor)); @@ -118,11 +135,25 @@ PreparedModel::executeFenced(const nn::Request& request, const std::vector> +PreparedModel::executeFencedInternal(const Request& request, + const std::vector& waitFor, + bool measure, int64_t deadline, int64_t loopTimeoutDuration, + int64_t timeoutDurationAfterFence, + const hal::utils::RequestRelocation& relocation) const { + if (relocation.input) { + relocation.input->flush(); + } FencedExecutionResult result; - const auto ret = kPreparedModel->executeFenced(aidlRequest, aidlWaitFor, aidlMeasure, - aidlDeadline, aidlLoopTimeoutDuration, - aidlTimeoutDurationAfterFence, &result); + const auto ret = + kPreparedModel->executeFenced(request, waitFor, measure, deadline, loopTimeoutDuration, + timeoutDurationAfterFence, &result); HANDLE_ASTATUS(ret) << "executeFenced failed"; auto resultSyncFence = nn::SyncFence::createAsSignaled(); @@ -137,12 +168,12 @@ PreparedModel::executeFenced(const nn::Request& request, const std::vectorflush(); } // Create callback which can be used to retrieve the execution error status and timings. @@ -159,6 +190,22 @@ PreparedModel::executeFenced(const nn::Request& request, const std::vector PreparedModel::createReusableExecution( + const nn::Request& request, nn::MeasureTiming measure, + const nn::OptionalDuration& loopTimeoutDuration) const { + // Ensure that request is ready for IPC. + std::optional maybeRequestInShared; + hal::utils::RequestRelocation relocation; + const nn::Request& requestInShared = NN_TRY(hal::utils::convertRequestFromPointerToShared( + &request, &maybeRequestInShared, &relocation)); + + 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); +} + nn::GeneralResult PreparedModel::configureExecutionBurst() const { std::shared_ptr burst; const auto ret = kPreparedModel->configureExecutionBurst(&burst); diff --git a/neuralnetworks/aidl/utils/test/PreparedModelTest.cpp b/neuralnetworks/aidl/utils/test/PreparedModelTest.cpp index ff98a7d947..8bb5c90d1e 100644 --- a/neuralnetworks/aidl/utils/test/PreparedModelTest.cpp +++ b/neuralnetworks/aidl/utils/test/PreparedModelTest.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -253,6 +254,225 @@ TEST(PreparedModelTest, executeFencedDeadObject) { EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); } +TEST(PreparedModelTest, reusableExecuteSync) { + // setup call + const uint32_t kNumberOfComputations = 2; + const auto mockPreparedModel = MockPreparedModel::create(); + const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto mockExecutionResult = ExecutionResult{ + .outputSufficientSize = true, + .outputShapes = {}, + .timing = kNoTiming, + }; + EXPECT_CALL(*mockPreparedModel, executeSynchronously(_, _, _, _, _)) + .Times(kNumberOfComputations) + .WillRepeatedly( + DoAll(SetArgPointee<4>(mockExecutionResult), InvokeWithoutArgs(makeStatusOk))); + + // create execution + const auto createResult = preparedModel->createReusableExecution({}, {}, {}); + ASSERT_TRUE(createResult.has_value()) + << "Failed with " << createResult.error().code << ": " << createResult.error().message; + ASSERT_NE(createResult.value(), nullptr); + + // invoke compute repeatedly + for (uint32_t i = 0; i < kNumberOfComputations; i++) { + const auto computeResult = createResult.value()->compute({}); + EXPECT_TRUE(computeResult.has_value()) << "Failed with " << computeResult.error().code + << ": " << computeResult.error().message; + } +} + +TEST(PreparedModelTest, reusableExecuteSyncError) { + // setup test + const auto mockPreparedModel = MockPreparedModel::create(); + const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + EXPECT_CALL(*mockPreparedModel, executeSynchronously(_, _, _, _, _)) + .Times(1) + .WillOnce(Invoke(makeGeneralFailure)); + + // create execution + const auto createResult = preparedModel->createReusableExecution({}, {}, {}); + ASSERT_TRUE(createResult.has_value()) + << "Failed with " << createResult.error().code << ": " << createResult.error().message; + ASSERT_NE(createResult.value(), nullptr); + + // invoke compute + const auto computeResult = createResult.value()->compute({}); + ASSERT_FALSE(computeResult.has_value()); + EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(PreparedModelTest, reusableExecuteSyncTransportFailure) { + // setup test + const auto mockPreparedModel = MockPreparedModel::create(); + const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + EXPECT_CALL(*mockPreparedModel, executeSynchronously(_, _, _, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // create execution + const auto createResult = preparedModel->createReusableExecution({}, {}, {}); + ASSERT_TRUE(createResult.has_value()) + << "Failed with " << createResult.error().code << ": " << createResult.error().message; + ASSERT_NE(createResult.value(), nullptr); + + // invoke compute + const auto computeResult = createResult.value()->compute({}); + ASSERT_FALSE(computeResult.has_value()); + EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(PreparedModelTest, reusableExecuteSyncDeadObject) { + // setup test + const auto mockPreparedModel = MockPreparedModel::create(); + const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + EXPECT_CALL(*mockPreparedModel, executeSynchronously(_, _, _, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // create execution + const auto createResult = preparedModel->createReusableExecution({}, {}, {}); + ASSERT_TRUE(createResult.has_value()) + << "Failed with " << createResult.error().code << ": " << createResult.error().message; + ASSERT_NE(createResult.value(), nullptr); + + // invoke compute + const auto computeResult = createResult.value()->compute({}); + ASSERT_FALSE(computeResult.has_value()); + EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(PreparedModelTest, reusableExecuteFenced) { + // setup call + const uint32_t kNumberOfComputations = 2; + const auto mockPreparedModel = MockPreparedModel::create(); + const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + const auto mockCallback = MockFencedExecutionCallback::create(); + EXPECT_CALL(*mockCallback, getExecutionInfo(_, _, _)) + .Times(kNumberOfComputations) + .WillRepeatedly(DoAll(SetArgPointee<0>(kNoTiming), SetArgPointee<1>(kNoTiming), + SetArgPointee<2>(ErrorStatus::NONE), Invoke(makeStatusOk))); + EXPECT_CALL(*mockPreparedModel, executeFenced(_, _, _, _, _, _, _)) + .Times(kNumberOfComputations) + .WillRepeatedly(Invoke(makeFencedExecutionResult(mockCallback))); + + // create execution + const auto createResult = preparedModel->createReusableExecution({}, {}, {}); + ASSERT_TRUE(createResult.has_value()) + << "Failed with " << createResult.error().code << ": " << createResult.error().message; + ASSERT_NE(createResult.value(), nullptr); + + // invoke compute repeatedly + for (uint32_t i = 0; i < kNumberOfComputations; i++) { + const auto computeResult = createResult.value()->computeFenced({}, {}, {}); + ASSERT_TRUE(computeResult.has_value()) << "Failed with " << computeResult.error().code + << ": " << computeResult.error().message; + const auto& [syncFence, callback] = computeResult.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(PreparedModelTest, reusableExecuteFencedCallbackError) { + // setup call + const auto mockPreparedModel = MockPreparedModel::create(); + const auto preparedModel = PreparedModel::create(mockPreparedModel).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(*mockPreparedModel, executeFenced(_, _, _, _, _, _, _)) + .Times(1) + .WillOnce(Invoke(makeFencedExecutionResult(mockCallback))); + + // create execution + const auto createResult = preparedModel->createReusableExecution({}, {}, {}); + ASSERT_TRUE(createResult.has_value()) + << "Failed with " << createResult.error().code << ": " << createResult.error().message; + ASSERT_NE(createResult.value(), nullptr); + + // invoke compute + const auto computeResult = createResult.value()->computeFenced({}, {}, {}); + ASSERT_TRUE(computeResult.has_value()) << "Failed with " << computeResult.error().code << ": " + << computeResult.error().message; + const auto& [syncFence, callback] = computeResult.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(PreparedModelTest, reusableExecuteFencedError) { + // setup test + const auto mockPreparedModel = MockPreparedModel::create(); + const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + EXPECT_CALL(*mockPreparedModel, executeFenced(_, _, _, _, _, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralFailure)); + + // create execution + const auto createResult = preparedModel->createReusableExecution({}, {}, {}); + ASSERT_TRUE(createResult.has_value()) + << "Failed with " << createResult.error().code << ": " << createResult.error().message; + ASSERT_NE(createResult.value(), nullptr); + + // invoke compute + const auto computeResult = createResult.value()->computeFenced({}, {}, {}); + ASSERT_FALSE(computeResult.has_value()); + EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(PreparedModelTest, reusableExecuteFencedTransportFailure) { + // setup test + const auto mockPreparedModel = MockPreparedModel::create(); + const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + EXPECT_CALL(*mockPreparedModel, executeFenced(_, _, _, _, _, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeGeneralTransportFailure)); + + // create execution + const auto createResult = preparedModel->createReusableExecution({}, {}, {}); + ASSERT_TRUE(createResult.has_value()) + << "Failed with " << createResult.error().code << ": " << createResult.error().message; + ASSERT_NE(createResult.value(), nullptr); + + // invoke compute + const auto computeResult = createResult.value()->computeFenced({}, {}, {}); + ASSERT_FALSE(computeResult.has_value()); + EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(PreparedModelTest, reusableExecuteFencedDeadObject) { + // setup test + const auto mockPreparedModel = MockPreparedModel::create(); + const auto preparedModel = PreparedModel::create(mockPreparedModel).value(); + EXPECT_CALL(*mockPreparedModel, executeFenced(_, _, _, _, _, _, _)) + .Times(1) + .WillOnce(InvokeWithoutArgs(makeDeadObjectFailure)); + + // create execution + const auto createResult = preparedModel->createReusableExecution({}, {}, {}); + ASSERT_TRUE(createResult.has_value()) + << "Failed with " << createResult.error().code << ": " << createResult.error().message; + ASSERT_NE(createResult.value(), nullptr); + + // invoke compute + const auto computeResult = createResult.value()->computeFenced({}, {}, {}); + ASSERT_FALSE(computeResult.has_value()); + EXPECT_EQ(computeResult.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + TEST(PreparedModelTest, configureExecutionBurst) { // setup test const auto mockPreparedModel = MockPreparedModel::create(); diff --git a/neuralnetworks/utils/common/include/nnapi/hal/CommonUtils.h b/neuralnetworks/utils/common/include/nnapi/hal/CommonUtils.h index 8fe6b904b2..fdc90dfb41 100644 --- a/neuralnetworks/utils/common/include/nnapi/hal/CommonUtils.h +++ b/neuralnetworks/utils/common/include/nnapi/hal/CommonUtils.h @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -59,19 +60,70 @@ bool hasNoPointerData(const nn::Request& request); nn::GeneralResult> flushDataFromPointerToShared( const nn::Model* model, std::optional* maybeModelInSharedOut); +// Record a relocation mapping between pointer-based data and shared memory. +// Only two specializations of this template may exist: +// - RelocationInfo for request inputs +// - RelocationInfo for request outputs +template +struct RelocationInfo { + PointerType data; + size_t length; + size_t offset; +}; +using InputRelocationInfo = RelocationInfo; +using OutputRelocationInfo = RelocationInfo; + +// Keep track of the relocation mapping between pointer-based data and shared memory pool, +// and provide method to copy the data between pointers and the shared memory pool. +// Only two specializations of this template may exist: +// - RelocationTracker for request inputs +// - RelocationTracker for request outputs +template +class RelocationTracker { + public: + static nn::GeneralResult> create( + std::vector relocationInfos, nn::SharedMemory memory) { + auto mapping = NN_TRY(map(memory)); + return std::make_unique>( + std::move(relocationInfos), std::move(memory), std::move(mapping)); + } + + RelocationTracker(std::vector relocationInfos, nn::SharedMemory memory, + nn::Mapping mapping) + : kRelocationInfos(std::move(relocationInfos)), + kMemory(std::move(memory)), + kMapping(std::move(mapping)) {} + + // Specializations defined in CommonUtils.cpp. + // For InputRelocationTracker, this method will copy pointer data to the shared memory pool. + // For OutputRelocationTracker, this method will copy shared memory data to the pointers. + void flush() const; + + private: + const std::vector kRelocationInfos; + const nn::SharedMemory kMemory; + const nn::Mapping kMapping; +}; +using InputRelocationTracker = RelocationTracker; +using OutputRelocationTracker = RelocationTracker; + +struct RequestRelocation { + std::unique_ptr input; + std::unique_ptr output; +}; + // Relocate pointer-based data to shared memory. If `request` has no // Request::Argument::LifeTime::POINTER data, the function returns with a reference to `request`. If // `request` has Request::Argument::LifeTime::POINTER data, the request is copied to // `maybeRequestInSharedOut` with the POINTER data relocated to a memory pool, and the function -// returns with a reference to `*maybeRequestInSharedOut`. -nn::GeneralResult> flushDataFromPointerToShared( - const nn::Request* request, std::optional* maybeRequestInSharedOut); - -// Undoes `flushDataFromPointerToShared` on a Request object. More specifically, -// `unflushDataFromSharedToPointer` copies the output shared memory data from the transformed -// Request object back to the output pointer-based memory in the original Request object. -nn::GeneralResult unflushDataFromSharedToPointer( - const nn::Request& request, const std::optional& maybeRequestInShared); +// returns with a reference to `*maybeRequestInSharedOut`. The `relocationOut` will be set to track +// the input and output relocations. +// +// Unlike `flushDataFromPointerToShared`, this method will not copy the input pointer data to the +// shared memory pool. Use `relocationOut` to flush the input or output data after the call. +nn::GeneralResult> convertRequestFromPointerToShared( + const nn::Request* request, std::optional* maybeRequestInSharedOut, + RequestRelocation* relocationOut); nn::GeneralResult> countNumberOfConsumers( size_t numberOfOperands, const std::vector& operations); diff --git a/neuralnetworks/utils/common/include/nnapi/hal/InvalidExecution.h b/neuralnetworks/utils/common/include/nnapi/hal/InvalidExecution.h new file mode 100644 index 0000000000..5b00221e1c --- /dev/null +++ b/neuralnetworks/utils/common/include/nnapi/hal/InvalidExecution.h @@ -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. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_INVALID_EXECUTION_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_INVALID_EXECUTION_H + +#include +#include +#include + +#include +#include + +namespace android::hardware::neuralnetworks::utils { + +class InvalidExecution final : public nn::IExecution { + public: + nn::ExecutionResult, nn::Timing>> compute( + const nn::OptionalTimePoint& deadline) const override; + + nn::GeneralResult> computeFenced( + const std::vector& waitFor, const nn::OptionalTimePoint& deadline, + const nn::OptionalDuration& timeoutDurationAfterFence) const override; +}; + +} // namespace android::hardware::neuralnetworks::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_INVALID_EXECUTION_H diff --git a/neuralnetworks/utils/common/include/nnapi/hal/InvalidPreparedModel.h b/neuralnetworks/utils/common/include/nnapi/hal/InvalidPreparedModel.h index 3e1dca7139..de30aaefc9 100644 --- a/neuralnetworks/utils/common/include/nnapi/hal/InvalidPreparedModel.h +++ b/neuralnetworks/utils/common/include/nnapi/hal/InvalidPreparedModel.h @@ -40,6 +40,10 @@ class InvalidPreparedModel final : public nn::IPreparedModel { const nn::OptionalDuration& loopTimeoutDuration, const nn::OptionalDuration& timeoutDurationAfterFence) const override; + nn::GeneralResult createReusableExecution( + const nn::Request& request, nn::MeasureTiming measure, + const nn::OptionalDuration& loopTimeoutDuration) const override; + nn::GeneralResult configureExecutionBurst() const override; std::any getUnderlyingResource() const override; diff --git a/neuralnetworks/utils/common/include/nnapi/hal/ResilientExecution.h b/neuralnetworks/utils/common/include/nnapi/hal/ResilientExecution.h new file mode 100644 index 0000000000..d0084e8a5a --- /dev/null +++ b/neuralnetworks/utils/common/include/nnapi/hal/ResilientExecution.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_COMMON_RESILIENT_EXECUTION_H +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_RESILIENT_EXECUTION_H + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::utils { + +class ResilientExecution final : public nn::IExecution, + public std::enable_shared_from_this { + struct PrivateConstructorTag {}; + + public: + using Factory = std::function()>; + + static nn::GeneralResult> create( + Factory makeExecution); + + ResilientExecution(PrivateConstructorTag tag, Factory makeExecution, + nn::SharedExecution execution); + + nn::SharedExecution getExecution() const; + nn::GeneralResult recover(const nn::IExecution* failingExecution) const; + + nn::ExecutionResult, nn::Timing>> compute( + const nn::OptionalTimePoint& deadline) const override; + + nn::GeneralResult> computeFenced( + const std::vector& waitFor, const nn::OptionalTimePoint& deadline, + const nn::OptionalDuration& timeoutDurationAfterFence) const override; + + private: + bool isValidInternal() const EXCLUDES(mMutex); + + const Factory kMakeExecution; + mutable std::mutex mMutex; + mutable nn::SharedExecution mExecution GUARDED_BY(mMutex); +}; + +} // namespace android::hardware::neuralnetworks::utils + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_RESILIENT_EXECUTION_H diff --git a/neuralnetworks/utils/common/include/nnapi/hal/ResilientPreparedModel.h b/neuralnetworks/utils/common/include/nnapi/hal/ResilientPreparedModel.h index a6c1b1911a..86533edd12 100644 --- a/neuralnetworks/utils/common/include/nnapi/hal/ResilientPreparedModel.h +++ b/neuralnetworks/utils/common/include/nnapi/hal/ResilientPreparedModel.h @@ -58,12 +58,19 @@ class ResilientPreparedModel final : public nn::IPreparedModel, const nn::OptionalDuration& loopTimeoutDuration, const nn::OptionalDuration& timeoutDurationAfterFence) const override; + nn::GeneralResult createReusableExecution( + const nn::Request& request, nn::MeasureTiming measure, + const nn::OptionalDuration& loopTimeoutDuration) const override; + nn::GeneralResult configureExecutionBurst() const override; std::any getUnderlyingResource() const override; private: bool isValidInternal() const EXCLUDES(mMutex); + nn::GeneralResult createReusableExecutionInternal( + const nn::Request& request, nn::MeasureTiming measure, + const nn::OptionalDuration& loopTimeoutDuration) const; nn::GeneralResult configureExecutionBurstInternal() const; const Factory kMakePreparedModel; diff --git a/neuralnetworks/utils/common/src/CommonUtils.cpp b/neuralnetworks/utils/common/src/CommonUtils.cpp index 4d26795d89..eaeb9ad872 100644 --- a/neuralnetworks/utils/common/src/CommonUtils.cpp +++ b/neuralnetworks/utils/common/src/CommonUtils.cpp @@ -200,10 +200,31 @@ nn::GeneralResult> flushDataFromPointerT return **maybeModelInSharedOut; } -nn::GeneralResult> flushDataFromPointerToShared( - const nn::Request* request, std::optional* maybeRequestInSharedOut) { +template <> +void InputRelocationTracker::flush() const { + // Copy from pointers to shared memory. + uint8_t* memoryPtr = static_cast(std::get(kMapping.pointer)); + for (const auto& [data, length, offset] : kRelocationInfos) { + std::memcpy(memoryPtr + offset, data, length); + } +} + +template <> +void OutputRelocationTracker::flush() const { + // Copy from shared memory to pointers. + const uint8_t* memoryPtr = static_cast( + std::visit([](auto ptr) { return static_cast(ptr); }, kMapping.pointer)); + for (const auto& [data, length, offset] : kRelocationInfos) { + std::memcpy(data, memoryPtr + offset, length); + } +} + +nn::GeneralResult> convertRequestFromPointerToShared( + const nn::Request* request, std::optional* maybeRequestInSharedOut, + RequestRelocation* relocationOut) { CHECK(request != nullptr); CHECK(maybeRequestInSharedOut != nullptr); + CHECK(relocationOut != nullptr); if (hasNoPointerData(*request)) { return *request; @@ -213,8 +234,11 @@ nn::GeneralResult> flushDataFromPointe // to the caller through `maybeRequestInSharedOut` if the function succeeds. nn::Request requestInShared = *request; + RequestRelocation relocation; + // Change input pointers to shared memory. - nn::ConstantMemoryBuilder inputBuilder(requestInShared.pools.size()); + nn::MutableMemoryBuilder inputBuilder(requestInShared.pools.size()); + std::vector inputRelocationInfos; for (auto& input : requestInShared.inputs) { const auto& location = input.location; if (input.lifetime != nn::Request::Argument::LifeTime::POINTER) { @@ -225,17 +249,21 @@ nn::GeneralResult> flushDataFromPointe const void* data = std::visit([](auto ptr) { return static_cast(ptr); }, location.pointer); CHECK(data != nullptr); - input.location = inputBuilder.append(data, location.length); + input.location = inputBuilder.append(location.length); + inputRelocationInfos.push_back({data, input.location.length, input.location.offset}); } // Allocate input memory. if (!inputBuilder.empty()) { auto memory = NN_TRY(inputBuilder.finish()); - requestInShared.pools.push_back(std::move(memory)); + requestInShared.pools.push_back(memory); + relocation.input = NN_TRY( + InputRelocationTracker::create(std::move(inputRelocationInfos), std::move(memory))); } // Change output pointers to shared memory. nn::MutableMemoryBuilder outputBuilder(requestInShared.pools.size()); + std::vector outputRelocationInfos; for (auto& output : requestInShared.outputs) { const auto& location = output.location; if (output.lifetime != nn::Request::Argument::LifeTime::POINTER) { @@ -243,62 +271,25 @@ nn::GeneralResult> flushDataFromPointe } output.lifetime = nn::Request::Argument::LifeTime::POOL; + void* data = std::get(location.pointer); + CHECK(data != nullptr); output.location = outputBuilder.append(location.length); + outputRelocationInfos.push_back({data, output.location.length, output.location.offset}); } // Allocate output memory. if (!outputBuilder.empty()) { auto memory = NN_TRY(outputBuilder.finish()); - requestInShared.pools.push_back(std::move(memory)); + requestInShared.pools.push_back(memory); + relocation.output = NN_TRY(OutputRelocationTracker::create(std::move(outputRelocationInfos), + std::move(memory))); } *maybeRequestInSharedOut = requestInShared; + *relocationOut = std::move(relocation); return **maybeRequestInSharedOut; } -nn::GeneralResult unflushDataFromSharedToPointer( - const nn::Request& request, const std::optional& maybeRequestInShared) { - if (!maybeRequestInShared.has_value() || maybeRequestInShared->pools.empty() || - !std::holds_alternative(maybeRequestInShared->pools.back())) { - return {}; - } - const auto& requestInShared = *maybeRequestInShared; - - // Map the memory. - const auto& outputMemory = std::get(requestInShared.pools.back()); - const auto [pointer, size, context] = NN_TRY(map(outputMemory)); - const uint8_t* constantPointer = - std::visit([](const auto& o) { return static_cast(o); }, pointer); - - // Flush each output pointer. - CHECK_EQ(request.outputs.size(), requestInShared.outputs.size()); - for (size_t i = 0; i < request.outputs.size(); ++i) { - const auto& location = request.outputs[i].location; - const auto& locationInShared = requestInShared.outputs[i].location; - if (!std::holds_alternative(location.pointer)) { - continue; - } - - // Get output pointer and size. - void* data = std::get(location.pointer); - CHECK(data != nullptr); - const size_t length = location.length; - - // Get output pool location. - CHECK(requestInShared.outputs[i].lifetime == nn::Request::Argument::LifeTime::POOL); - const size_t index = locationInShared.poolIndex; - const size_t offset = locationInShared.offset; - const size_t outputPoolIndex = requestInShared.pools.size() - 1; - CHECK(locationInShared.length == length); - CHECK(index == outputPoolIndex); - - // Flush memory. - std::memcpy(data, constantPointer + offset, length); - } - - return {}; -} - nn::GeneralResult> countNumberOfConsumers( size_t numberOfOperands, const std::vector& operations) { return makeGeneralFailure(nn::countNumberOfConsumers(numberOfOperands, operations)); diff --git a/neuralnetworks/utils/common/src/InvalidExecution.cpp b/neuralnetworks/utils/common/src/InvalidExecution.cpp new file mode 100644 index 0000000000..c4edd25218 --- /dev/null +++ b/neuralnetworks/utils/common/src/InvalidExecution.cpp @@ -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. + */ + +#include "InvalidExecution.h" + +#include +#include +#include + +#include +#include + +namespace android::hardware::neuralnetworks::utils { + +nn::ExecutionResult, nn::Timing>> InvalidExecution::compute( + const nn::OptionalTimePoint& /*deadline*/) const { + return NN_ERROR() << "InvalidExecution"; +} + +nn::GeneralResult> +InvalidExecution::computeFenced(const std::vector& /*waitFor*/, + const nn::OptionalTimePoint& /*deadline*/, + const nn::OptionalDuration& /*timeoutDurationAfterFence*/) const { + return NN_ERROR() << "InvalidExecution"; +} + +} // namespace android::hardware::neuralnetworks::utils diff --git a/neuralnetworks/utils/common/src/InvalidPreparedModel.cpp b/neuralnetworks/utils/common/src/InvalidPreparedModel.cpp index 9081e1fdd1..8195462ba8 100644 --- a/neuralnetworks/utils/common/src/InvalidPreparedModel.cpp +++ b/neuralnetworks/utils/common/src/InvalidPreparedModel.cpp @@ -42,6 +42,12 @@ InvalidPreparedModel::executeFenced( return NN_ERROR() << "InvalidPreparedModel"; } +nn::GeneralResult InvalidPreparedModel::createReusableExecution( + const nn::Request& /*request*/, nn::MeasureTiming /*measure*/, + const nn::OptionalDuration& /*loopTimeoutDuration*/) const { + return NN_ERROR() << "InvalidPreparedModel"; +} + nn::GeneralResult InvalidPreparedModel::configureExecutionBurst() const { return NN_ERROR() << "InvalidPreparedModel"; } diff --git a/neuralnetworks/utils/common/src/ResilientExecution.cpp b/neuralnetworks/utils/common/src/ResilientExecution.cpp new file mode 100644 index 0000000000..46b404a603 --- /dev/null +++ b/neuralnetworks/utils/common/src/ResilientExecution.cpp @@ -0,0 +1,126 @@ +/* + * 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 "ResilientExecution.h" + +#include "InvalidBurst.h" +#include "ResilientBurst.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace android::hardware::neuralnetworks::utils { +namespace { + +template +auto protect(const ResilientExecution& resilientExecution, const FnType& fn) + -> decltype(fn(*resilientExecution.getExecution())) { + auto execution = resilientExecution.getExecution(); + auto result = fn(*execution); + + // Immediately return if prepared model is not dead. + if (result.has_value() || result.error().code != nn::ErrorStatus::DEAD_OBJECT) { + return result; + } + + // Attempt recovery and return if it fails. + auto maybeExecution = resilientExecution.recover(execution.get()); + if (!maybeExecution.has_value()) { + const auto& [message, code] = maybeExecution.error(); + std::ostringstream oss; + oss << ", and failed to recover dead prepared model with error " << code << ": " << message; + result.error().message += oss.str(); + return result; + } + execution = std::move(maybeExecution).value(); + + return fn(*execution); +} + +} // namespace + +nn::GeneralResult> ResilientExecution::create( + Factory makeExecution) { + if (makeExecution == nullptr) { + return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) + << "utils::ResilientExecution::create must have non-empty makeExecution"; + } + auto execution = NN_TRY(makeExecution()); + CHECK(execution != nullptr); + return std::make_shared(PrivateConstructorTag{}, std::move(makeExecution), + std::move(execution)); +} + +ResilientExecution::ResilientExecution(PrivateConstructorTag /*tag*/, Factory makeExecution, + nn::SharedExecution execution) + : kMakeExecution(std::move(makeExecution)), mExecution(std::move(execution)) { + CHECK(kMakeExecution != nullptr); + CHECK(mExecution != nullptr); +} + +nn::SharedExecution ResilientExecution::getExecution() const { + std::lock_guard guard(mMutex); + return mExecution; +} + +nn::GeneralResult ResilientExecution::recover( + const nn::IExecution* failingExecution) const { + std::lock_guard guard(mMutex); + + // Another caller updated the failing prepared model. + if (mExecution.get() != failingExecution) { + return mExecution; + } + + mExecution = NN_TRY(kMakeExecution()); + return mExecution; +} + +nn::ExecutionResult, nn::Timing>> +ResilientExecution::compute(const nn::OptionalTimePoint& deadline) const { + const auto fn = [&deadline](const nn::IExecution& execution) { + return execution.compute(deadline); + }; + return protect(*this, fn); +} + +nn::GeneralResult> +ResilientExecution::computeFenced(const std::vector& waitFor, + const nn::OptionalTimePoint& deadline, + const nn::OptionalDuration& timeoutDurationAfterFence) const { + const auto fn = [&waitFor, &deadline, + &timeoutDurationAfterFence](const nn::IExecution& execution) { + return execution.computeFenced(waitFor, deadline, timeoutDurationAfterFence); + }; + return protect(*this, fn); +} + +bool ResilientExecution::isValidInternal() const { + return true; +} + +} // namespace android::hardware::neuralnetworks::utils diff --git a/neuralnetworks/utils/common/src/ResilientPreparedModel.cpp b/neuralnetworks/utils/common/src/ResilientPreparedModel.cpp index 5dd5f99f5f..1ae19bc6ca 100644 --- a/neuralnetworks/utils/common/src/ResilientPreparedModel.cpp +++ b/neuralnetworks/utils/common/src/ResilientPreparedModel.cpp @@ -17,7 +17,9 @@ #include "ResilientPreparedModel.h" #include "InvalidBurst.h" +#include "InvalidExecution.h" #include "ResilientBurst.h" +#include "ResilientExecution.h" #include #include @@ -127,6 +129,21 @@ ResilientPreparedModel::executeFenced(const nn::Request& request, return protect(*this, fn); } +nn::GeneralResult ResilientPreparedModel::createReusableExecution( + const nn::Request& request, nn::MeasureTiming measure, + const nn::OptionalDuration& loopTimeoutDuration) const { +#if 0 + auto self = shared_from_this(); + ResilientExecution::Factory makeExecution = + [preparedModel = std::move(self), request, measure, loopTimeoutDuration] { + return preparedModel->createReusableExecutionInternal(request, measure, loopTimeoutDuration); + }; + return ResilientExecution::create(std::move(makeExecution)); +#else + return createReusableExecutionInternal(request, measure, loopTimeoutDuration); +#endif +} + nn::GeneralResult ResilientPreparedModel::configureExecutionBurst() const { #if 0 auto self = shared_from_this(); @@ -140,6 +157,19 @@ nn::GeneralResult ResilientPreparedModel::configureExecutionBur #endif } +nn::GeneralResult ResilientPreparedModel::createReusableExecutionInternal( + const nn::Request& request, nn::MeasureTiming measure, + const nn::OptionalDuration& loopTimeoutDuration) const { + if (!isValidInternal()) { + return std::make_shared(); + } + const auto fn = [&request, measure, + &loopTimeoutDuration](const nn::IPreparedModel& preparedModel) { + return preparedModel.createReusableExecution(request, measure, loopTimeoutDuration); + }; + return protect(*this, fn); +} + std::any ResilientPreparedModel::getUnderlyingResource() const { return getPreparedModel()->getUnderlyingResource(); } diff --git a/neuralnetworks/utils/common/test/MockExecution.h b/neuralnetworks/utils/common/test/MockExecution.h new file mode 100644 index 0000000000..91e3428004 --- /dev/null +++ b/neuralnetworks/utils/common/test/MockExecution.h @@ -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. + */ + +#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_TEST_MOCK_EXECUTION +#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_TEST_MOCK_EXECUTION + +#include +#include +#include + +namespace android::nn { + +class MockExecution final : public IExecution { + public: + MOCK_METHOD((ExecutionResult, Timing>>), compute, + (const OptionalTimePoint& deadline), (const, override)); + MOCK_METHOD((GeneralResult>), computeFenced, + (const std::vector& waitFor, const OptionalTimePoint& deadline, + const OptionalDuration& timeoutDurationAfterFence), + (const, override)); +}; + +} // namespace android::nn + +#endif // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_COMMON_TEST_MOCK_EXECUTION diff --git a/neuralnetworks/utils/common/test/MockPreparedModel.h b/neuralnetworks/utils/common/test/MockPreparedModel.h index c0048615ef..c8ce006171 100644 --- a/neuralnetworks/utils/common/test/MockPreparedModel.h +++ b/neuralnetworks/utils/common/test/MockPreparedModel.h @@ -35,6 +35,10 @@ class MockPreparedModel final : public IPreparedModel { const OptionalDuration& loopTimeoutDuration, const OptionalDuration& timeoutDurationAfterFence), (const, override)); + MOCK_METHOD((GeneralResult), createReusableExecution, + (const nn::Request& request, nn::MeasureTiming measure, + const nn::OptionalDuration& loopTimeoutDuration), + (const, override)); MOCK_METHOD(GeneralResult, configureExecutionBurst, (), (const, override)); MOCK_METHOD(std::any, getUnderlyingResource, (), (const, override)); }; diff --git a/neuralnetworks/utils/common/test/ResilientExecution.cpp b/neuralnetworks/utils/common/test/ResilientExecution.cpp new file mode 100644 index 0000000000..c0737fb61d --- /dev/null +++ b/neuralnetworks/utils/common/test/ResilientExecution.cpp @@ -0,0 +1,260 @@ +/* + * 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 +#include +#include +#include +#include +#include "MockExecution.h" + +namespace android::hardware::neuralnetworks::utils { +namespace { + +using ::testing::_; +using ::testing::InvokeWithoutArgs; +using ::testing::Return; + +using SharedMockExecution = std::shared_ptr; +using MockExecutionFactory = ::testing::MockFunction()>; + +SharedMockExecution createMockExecution() { + return std::make_shared(); +} + +std::tuple, + std::shared_ptr> +setup() { + auto mockExecution = std::make_shared(); + + auto mockExecutionFactory = std::make_unique(); + EXPECT_CALL(*mockExecutionFactory, Call()).Times(1).WillOnce(Return(mockExecution)); + + auto buffer = ResilientExecution::create(mockExecutionFactory->AsStdFunction()).value(); + return std::make_tuple(std::move(mockExecution), std::move(mockExecutionFactory), + std::move(buffer)); +} + +constexpr auto makeError = [](nn::ErrorStatus status) { + return [status](const auto&... /*args*/) { return nn::error(status); }; +}; +const auto kReturnGeneralFailure = makeError(nn::ErrorStatus::GENERAL_FAILURE); +const auto kReturnDeadObject = makeError(nn::ErrorStatus::DEAD_OBJECT); + +const auto kNoExecutionError = + nn::ExecutionResult, nn::Timing>>{}; +const auto kNoFencedExecutionError = + nn::GeneralResult>( + std::make_pair(nn::SyncFence::createAsSignaled(), nullptr)); + +} // namespace + +TEST(ResilientExecutionTest, invalidExecutionFactory) { + // setup call + const auto invalidExecutionFactory = ResilientExecution::Factory{}; + + // run test + const auto result = ResilientExecution::create(invalidExecutionFactory); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::INVALID_ARGUMENT); +} + +TEST(ResilientExecutionTest, executionFactoryFailure) { + // setup call + const auto invalidExecutionFactory = kReturnGeneralFailure; + + // run test + const auto result = ResilientExecution::create(invalidExecutionFactory); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(ResilientExecutionTest, getExecution) { + // setup call + const auto [mockExecution, mockExecutionFactory, execution] = setup(); + + // run test + const auto result = execution->getExecution(); + + // verify result + EXPECT_TRUE(result == mockExecution); +} + +TEST(ResilientExecutionTest, compute) { + // setup call + const auto [mockExecution, mockExecutionFactory, execution] = setup(); + EXPECT_CALL(*mockExecution, compute(_)).Times(1).WillOnce(Return(kNoExecutionError)); + + // run test + const auto result = execution->compute({}); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; +} + +TEST(ResilientExecutionTest, computeError) { + // setup call + const auto [mockExecution, mockExecutionFactory, execution] = setup(); + EXPECT_CALL(*mockExecution, compute(_)).Times(1).WillOnce(kReturnGeneralFailure); + + // run test + const auto result = execution->compute({}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(ResilientExecutionTest, computeDeadObjectFailedRecovery) { + // setup call + const auto [mockExecution, mockExecutionFactory, execution] = setup(); + EXPECT_CALL(*mockExecution, compute(_)).Times(1).WillOnce(kReturnDeadObject); + EXPECT_CALL(*mockExecutionFactory, Call()).Times(1).WillOnce(kReturnGeneralFailure); + + // run test + const auto result = execution->compute({}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(ResilientExecutionTest, computeDeadObjectSuccessfulRecovery) { + // setup call + const auto [mockExecution, mockExecutionFactory, execution] = setup(); + EXPECT_CALL(*mockExecution, compute(_)).Times(1).WillOnce(kReturnDeadObject); + const auto recoveredMockExecution = createMockExecution(); + EXPECT_CALL(*recoveredMockExecution, compute(_)).Times(1).WillOnce(Return(kNoExecutionError)); + EXPECT_CALL(*mockExecutionFactory, Call()).Times(1).WillOnce(Return(recoveredMockExecution)); + + // run test + const auto result = execution->compute({}); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; +} + +TEST(ResilientExecutionTest, computeFenced) { + // setup call + const auto [mockExecution, mockExecutionFactory, execution] = setup(); + EXPECT_CALL(*mockExecution, computeFenced(_, _, _)) + .Times(1) + .WillOnce(Return(kNoFencedExecutionError)); + + // run test + const auto result = execution->computeFenced({}, {}, {}); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; +} + +TEST(ResilientExecutionTest, computeFencedError) { + // setup call + const auto [mockExecution, mockExecutionFactory, execution] = setup(); + EXPECT_CALL(*mockExecution, computeFenced(_, _, _)).Times(1).WillOnce(kReturnGeneralFailure); + + // run test + const auto result = execution->computeFenced({}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + +TEST(ResilientExecutionTest, computeFencedDeadObjectFailedRecovery) { + // setup call + const auto [mockExecution, mockExecutionFactory, execution] = setup(); + EXPECT_CALL(*mockExecution, computeFenced(_, _, _)).Times(1).WillOnce(kReturnDeadObject); + EXPECT_CALL(*mockExecutionFactory, Call()).Times(1).WillOnce(kReturnGeneralFailure); + + // run test + const auto result = execution->computeFenced({}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); +} + +TEST(ResilientExecutionTest, computeFencedDeadObjectSuccessfulRecovery) { + // setup call + const auto [mockExecution, mockExecutionFactory, execution] = setup(); + EXPECT_CALL(*mockExecution, computeFenced(_, _, _)).Times(1).WillOnce(kReturnDeadObject); + const auto recoveredMockExecution = createMockExecution(); + EXPECT_CALL(*recoveredMockExecution, computeFenced(_, _, _)) + .Times(1) + .WillOnce(Return(kNoFencedExecutionError)); + EXPECT_CALL(*mockExecutionFactory, Call()).Times(1).WillOnce(Return(recoveredMockExecution)); + + // run test + const auto result = execution->computeFenced({}, {}, {}); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; +} + +TEST(ResilientExecutionTest, recover) { + // setup call + const auto [mockExecution, mockExecutionFactory, execution] = setup(); + const auto recoveredMockExecution = createMockExecution(); + EXPECT_CALL(*mockExecutionFactory, Call()).Times(1).WillOnce(Return(recoveredMockExecution)); + + // run test + const auto result = execution->recover(mockExecution.get()); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; + EXPECT_TRUE(result.value() == recoveredMockExecution); +} + +TEST(ResilientExecutionTest, recoverFailure) { + // setup call + const auto [mockExecution, mockExecutionFactory, execution] = setup(); + const auto recoveredMockExecution = createMockExecution(); + EXPECT_CALL(*mockExecutionFactory, Call()).Times(1).WillOnce(kReturnGeneralFailure); + + // run test + const auto result = execution->recover(mockExecution.get()); + + // verify result + EXPECT_FALSE(result.has_value()); +} + +TEST(ResilientExecutionTest, someoneElseRecovered) { + // setup call + const auto [mockExecution, mockExecutionFactory, execution] = setup(); + const auto recoveredMockExecution = createMockExecution(); + EXPECT_CALL(*mockExecutionFactory, Call()).Times(1).WillOnce(Return(recoveredMockExecution)); + execution->recover(mockExecution.get()); + + // run test + const auto result = execution->recover(mockExecution.get()); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; + EXPECT_TRUE(result.value() == recoveredMockExecution); +} + +} // namespace android::hardware::neuralnetworks::utils diff --git a/neuralnetworks/utils/common/test/ResilientPreparedModelTest.cpp b/neuralnetworks/utils/common/test/ResilientPreparedModelTest.cpp index 6d86e10df2..d396ca88df 100644 --- a/neuralnetworks/utils/common/test/ResilientPreparedModelTest.cpp +++ b/neuralnetworks/utils/common/test/ResilientPreparedModelTest.cpp @@ -55,6 +55,7 @@ constexpr auto makeError = [](nn::ErrorStatus status) { const auto kReturnGeneralFailure = makeError(nn::ErrorStatus::GENERAL_FAILURE); const auto kReturnDeadObject = makeError(nn::ErrorStatus::DEAD_OBJECT); +const auto kNoCreateReusableExecutionError = nn::GeneralResult{}; const auto kNoExecutionError = nn::ExecutionResult, nn::Timing>>{}; const auto kNoFencedExecutionError = @@ -231,6 +232,36 @@ TEST(ResilientPreparedModelTest, executeFencedDeadObjectSuccessfulRecovery) { << "Failed with " << result.error().code << ": " << result.error().message; } +TEST(ResilientPreparedModelTest, createReusableExecution) { + // setup call + const auto [mockPreparedModel, mockPreparedModelFactory, preparedModel] = setup(); + EXPECT_CALL(*mockPreparedModel, createReusableExecution(_, _, _)) + .Times(1) + .WillOnce(Return(kNoCreateReusableExecutionError)); + + // run test + const auto result = preparedModel->createReusableExecution({}, {}, {}); + + // verify result + ASSERT_TRUE(result.has_value()) + << "Failed with " << result.error().code << ": " << result.error().message; +} + +TEST(ResilientPreparedModelTest, createReusableExecutionError) { + // setup call + const auto [mockPreparedModel, mockPreparedModelFactory, preparedModel] = setup(); + EXPECT_CALL(*mockPreparedModel, createReusableExecution(_, _, _)) + .Times(1) + .WillOnce(kReturnGeneralFailure); + + // run test + const auto result = preparedModel->createReusableExecution({}, {}, {}); + + // verify result + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(result.error().code, nn::ErrorStatus::GENERAL_FAILURE); +} + TEST(ResilientPreparedModelTest, getUnderlyingResource) { // setup call const auto [mockPreparedModel, mockPreparedModelFactory, preparedModel] = setup(); -- GitLab From ead6d37ae9fe5d840f4d92675814abea9216fc71 Mon Sep 17 00:00:00 2001 From: Xusong Wang Date: Tue, 23 Mar 2021 15:07:10 -0700 Subject: [PATCH 643/790] Introduce reusable burst to canonical interface -- HAL. This CL modifies the canonical interface for reusable burst executions: - Add new method IBurst::createExecution The reusable burst execution will not fallback to another execution path if sending request packet fails. The behavior of single-time burst execution remains unchanged. Additionally, this CL enables pointer -> shared memory conversion in 1.2/1.3 burst implementation. Bug: 184073769 Test: NNT_static Test: neuralnetworks_utils_hal_1_0_test Test: neuralnetworks_utils_hal_1_1_test Test: neuralnetworks_utils_hal_1_2_test Test: neuralnetworks_utils_hal_1_3_test Test: neuralnetworks_utils_hal_common_test Change-Id: Iaac81668d247c2cb76d70e6abbd10f00b397b19f --- .../1.0/utils/include/nnapi/hal/1.0/Burst.h | 4 + neuralnetworks/1.0/utils/src/Burst.cpp | 6 + .../nnapi/hal/1.2/ExecutionBurstController.h | 30 ++- .../utils/src/ExecutionBurstController.cpp | 182 +++++++++++++++--- .../1.2/utils/src/PreparedModel.cpp | 2 +- .../1.3/utils/src/PreparedModel.cpp | 2 +- .../aidl/utils/include/nnapi/hal/aidl/Burst.h | 12 +- neuralnetworks/aidl/utils/src/Burst.cpp | 147 ++++++++++++-- .../common/include/nnapi/hal/InvalidBurst.h | 4 + .../common/include/nnapi/hal/ResilientBurst.h | 9 + .../utils/common/src/InvalidBurst.cpp | 6 + .../utils/common/src/ResilientBurst.cpp | 45 ++++- 12 files changed, 395 insertions(+), 54 deletions(-) diff --git a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Burst.h b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Burst.h index 7849ca7a46..8bd2fbed7d 100644 --- a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Burst.h +++ b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Burst.h @@ -48,6 +48,10 @@ class Burst final : public nn::IBurst { const nn::OptionalTimePoint& deadline, const nn::OptionalDuration& loopTimeoutDuration) const override; + nn::GeneralResult createReusableExecution( + const nn::Request& request, nn::MeasureTiming measure, + const nn::OptionalDuration& loopTimeoutDuration) const override; + private: const nn::SharedPreparedModel kPreparedModel; }; diff --git a/neuralnetworks/1.0/utils/src/Burst.cpp b/neuralnetworks/1.0/utils/src/Burst.cpp index e3a97579cd..128472110d 100644 --- a/neuralnetworks/1.0/utils/src/Burst.cpp +++ b/neuralnetworks/1.0/utils/src/Burst.cpp @@ -55,4 +55,10 @@ nn::ExecutionResult, nn::Timing>> Burst:: return kPreparedModel->execute(request, measure, deadline, loopTimeoutDuration); } +nn::GeneralResult Burst::createReusableExecution( + const nn::Request& request, nn::MeasureTiming measure, + const nn::OptionalDuration& loopTimeoutDuration) const { + return kPreparedModel->createReusableExecution(request, measure, loopTimeoutDuration); +} + } // namespace android::hardware::neuralnetworks::V1_0::utils diff --git a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/ExecutionBurstController.h b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/ExecutionBurstController.h index 9669d8c031..dae1ff36c5 100644 --- a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/ExecutionBurstController.h +++ b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/ExecutionBurstController.h @@ -28,9 +28,11 @@ #include #include #include +#include #include #include #include +#include #include #include @@ -51,14 +53,14 @@ namespace android::hardware::neuralnetworks::V1_2::utils { * across FMQ, making it appear to the runtime as a regular synchronous inference. Additionally, * this class manages the burst's memory cache. */ -class ExecutionBurstController final : public nn::IBurst { +class ExecutionBurstController final + : public nn::IBurst, + public std::enable_shared_from_this { struct PrivateConstructorTag {}; public: - using FallbackFunction = - std::function, nn::Timing>>( - const nn::Request&, nn::MeasureTiming, const nn::OptionalTimePoint&, - const nn::OptionalDuration&)>; + using FallbackFunction = std::function< + nn::ExecutionResult, nn::Timing>>()>; /** * NN runtime memory cache. @@ -154,10 +156,10 @@ class ExecutionBurstController final : public nn::IBurst { * @return ExecutionBurstController Execution burst controller object. */ static nn::GeneralResult> create( - const sp& preparedModel, FallbackFunction fallback, + nn::SharedPreparedModel preparedModel, const sp& hidlPreparedModel, std::chrono::microseconds pollingTimeWindow); - ExecutionBurstController(PrivateConstructorTag tag, FallbackFunction fallback, + ExecutionBurstController(PrivateConstructorTag tag, nn::SharedPreparedModel preparedModel, std::unique_ptr requestChannelSender, std::unique_ptr resultChannelReceiver, sp callback, sp burstContext, @@ -173,9 +175,21 @@ class ExecutionBurstController final : public nn::IBurst { const nn::OptionalTimePoint& deadline, const nn::OptionalDuration& loopTimeoutDuration) const override; + // See IBurst::createReusableExecution for information on this method. + nn::GeneralResult createReusableExecution( + const nn::Request& request, nn::MeasureTiming measure, + const nn::OptionalDuration& loopTimeoutDuration) const override; + + // If fallback is not nullptr, this method will invoke the fallback function to try another + // execution path if the packet could not be sent. Otherwise, failing to send the packet will + // result in an error. + nn::ExecutionResult, nn::Timing>> executeInternal( + const std::vector& requestPacket, + const hal::utils::RequestRelocation& relocation, FallbackFunction fallback) const; + private: mutable std::atomic_flag mExecutionInFlight = ATOMIC_FLAG_INIT; - const FallbackFunction kFallback; + const nn::SharedPreparedModel kPreparedModel; const std::unique_ptr mRequestChannelSender; const std::unique_ptr mResultChannelReceiver; const sp mBurstCallback; diff --git a/neuralnetworks/1.2/utils/src/ExecutionBurstController.cpp b/neuralnetworks/1.2/utils/src/ExecutionBurstController.cpp index 7a17f257c2..8e82d2536d 100644 --- a/neuralnetworks/1.2/utils/src/ExecutionBurstController.cpp +++ b/neuralnetworks/1.2/utils/src/ExecutionBurstController.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -50,6 +51,35 @@ namespace android::hardware::neuralnetworks::V1_2::utils { namespace { +class BurstExecution final : public nn::IExecution, + public std::enable_shared_from_this { + struct PrivateConstructorTag {}; + + public: + static nn::GeneralResult> create( + std::shared_ptr controller, + std::vector request, hal::utils::RequestRelocation relocation, + std::vector cacheHolds); + + BurstExecution(PrivateConstructorTag tag, + std::shared_ptr controller, + std::vector request, hal::utils::RequestRelocation relocation, + std::vector cacheHolds); + + nn::ExecutionResult, nn::Timing>> compute( + const nn::OptionalTimePoint& deadline) const override; + + nn::GeneralResult> computeFenced( + const std::vector& waitFor, const nn::OptionalTimePoint& deadline, + const nn::OptionalDuration& timeoutDurationAfterFence) const override; + + private: + const std::shared_ptr kController; + const std::vector kRequest; + const hal::utils::RequestRelocation kRelocation; + const std::vector kCacheHolds; +}; + nn::GeneralResult> executionBurstResultCallback( V1_0::ErrorStatus status, const sp& burstContext) { HANDLE_HAL_STATUS(status) << "IPreparedModel::configureExecutionBurst failed with status " @@ -209,10 +239,10 @@ Return ExecutionBurstController::ExecutionBurstCallback::getMemories( // ExecutionBurstController methods nn::GeneralResult> ExecutionBurstController::create( - const sp& preparedModel, FallbackFunction fallback, + nn::SharedPreparedModel preparedModel, const sp& hidlPreparedModel, std::chrono::microseconds pollingTimeWindow) { // check inputs - if (preparedModel == nullptr) { + if (preparedModel == nullptr || hidlPreparedModel == nullptr) { return NN_ERROR() << "ExecutionBurstController::create passed a nullptr"; } @@ -236,7 +266,7 @@ nn::GeneralResult> ExecutionBurs auto cb = hal::utils::CallbackValue(executionBurstResultCallback); // configure burst - const Return ret = preparedModel->configureExecutionBurst( + const Return ret = hidlPreparedModel->configureExecutionBurst( burstCallback, *requestChannelDescriptor, *resultChannelDescriptor, cb); HANDLE_TRANSPORT_FAILURE(ret); @@ -250,18 +280,18 @@ nn::GeneralResult> ExecutionBurs // make and return controller return std::make_shared( - PrivateConstructorTag{}, std::move(fallback), std::move(requestChannelSender), + PrivateConstructorTag{}, std::move(preparedModel), std::move(requestChannelSender), std::move(resultChannelReceiver), std::move(burstCallback), std::move(burstContext), std::move(memoryCache), std::move(deathHandler)); } ExecutionBurstController::ExecutionBurstController( - PrivateConstructorTag /*tag*/, FallbackFunction fallback, + PrivateConstructorTag /*tag*/, nn::SharedPreparedModel preparedModel, std::unique_ptr requestChannelSender, std::unique_ptr resultChannelReceiver, sp callback, sp burstContext, std::shared_ptr memoryCache, neuralnetworks::utils::DeathHandler deathHandler) - : kFallback(std::move(fallback)), + : kPreparedModel(std::move(preparedModel)), mRequestChannelSender(std::move(requestChannelSender)), mResultChannelReceiver(std::move(resultChannelReceiver)), mBurstCallback(std::move(callback)), @@ -283,49 +313,113 @@ ExecutionBurstController::execute(const nn::Request& request, nn::MeasureTiming // systraces. Note that the first point we can begin collecting systraces in // ExecutionBurstServer is when the RequestChannelReceiver realizes there is data in the FMQ, so // ExecutionBurstServer collects systraces at different points in the code. - NNTRACE_FULL(NNTRACE_LAYER_IPC, NNTRACE_PHASE_EXECUTION, "ExecutionBurstController::execute"); + NNTRACE_RT(NNTRACE_PHASE_EXECUTION, "ExecutionBurstController::execute"); // if the request is valid but of a higher version than what's supported in burst execution, // fall back to another execution path if (const auto version = NN_TRY(hal::utils::makeExecutionFailure(nn::validate(request))); version > nn::Version::ANDROID_Q) { // fallback to another execution path if the packet could not be sent - if (kFallback) { - return kFallback(request, measure, deadline, loopTimeoutDuration); - } - return NN_ERROR() << "Request object has features not supported by IBurst::execute"; + return kPreparedModel->execute(request, measure, deadline, loopTimeoutDuration); } + // ensure that request is ready for IPC + std::optional maybeRequestInShared; + hal::utils::RequestRelocation relocation; + const nn::Request& requestInShared = + NN_TRY(hal::utils::makeExecutionFailure(hal::utils::convertRequestFromPointerToShared( + &request, &maybeRequestInShared, &relocation))); + // clear pools field of request, as they will be provided via slots - const auto requestWithoutPools = - nn::Request{.inputs = request.inputs, .outputs = request.outputs, .pools = {}}; + const auto requestWithoutPools = nn::Request{ + .inputs = requestInShared.inputs, .outputs = requestInShared.outputs, .pools = {}}; auto hidlRequest = NN_TRY( hal::utils::makeExecutionFailure(V1_0::utils::unvalidatedConvert(requestWithoutPools))); const auto hidlMeasure = NN_TRY(hal::utils::makeExecutionFailure(convert(measure))); - // Ensure that at most one execution is in flight at any given time. - const bool alreadyInFlight = mExecutionInFlight.test_and_set(); - if (alreadyInFlight) { - return NN_ERROR() << "IBurst already has an execution in flight"; + std::vector slots; + std::vector holds; + slots.reserve(requestInShared.pools.size()); + holds.reserve(requestInShared.pools.size()); + for (const auto& memoryPool : requestInShared.pools) { + auto [slot, hold] = mMemoryCache->cacheMemory(std::get(memoryPool)); + slots.push_back(slot); + holds.push_back(std::move(hold)); } - const auto guard = base::make_scope_guard([this] { mExecutionInFlight.clear(); }); + + // send request packet + const auto requestPacket = serialize(hidlRequest, hidlMeasure, slots); + const auto fallback = [this, &request, measure, &deadline, &loopTimeoutDuration] { + return kPreparedModel->execute(request, measure, deadline, loopTimeoutDuration); + }; + return executeInternal(requestPacket, relocation, fallback); +} + +// See IBurst::createReusableExecution for information on this method. +nn::GeneralResult ExecutionBurstController::createReusableExecution( + const nn::Request& request, nn::MeasureTiming measure, + const nn::OptionalDuration& loopTimeoutDuration) const { + NNTRACE_RT(NNTRACE_PHASE_EXECUTION, "ExecutionBurstController::createReusableExecution"); + + // if the request is valid but of a higher version than what's supported in burst execution, + // fall back to another execution path + if (const auto version = NN_TRY(hal::utils::makeGeneralFailure(nn::validate(request))); + version > nn::Version::ANDROID_Q) { + // fallback to another execution path if the packet could not be sent + return kPreparedModel->createReusableExecution(request, measure, loopTimeoutDuration); + } + + // ensure that request is ready for IPC + std::optional maybeRequestInShared; + hal::utils::RequestRelocation relocation; + const nn::Request& requestInShared = NN_TRY(hal::utils::convertRequestFromPointerToShared( + &request, &maybeRequestInShared, &relocation)); + + // clear pools field of request, as they will be provided via slots + const auto requestWithoutPools = nn::Request{ + .inputs = requestInShared.inputs, .outputs = requestInShared.outputs, .pools = {}}; + auto hidlRequest = NN_TRY(V1_0::utils::unvalidatedConvert(requestWithoutPools)); + const auto hidlMeasure = NN_TRY(convert(measure)); std::vector slots; std::vector holds; - slots.reserve(request.pools.size()); - holds.reserve(request.pools.size()); - for (const auto& memoryPool : request.pools) { + slots.reserve(requestInShared.pools.size()); + holds.reserve(requestInShared.pools.size()); + for (const auto& memoryPool : requestInShared.pools) { auto [slot, hold] = mMemoryCache->cacheMemory(std::get(memoryPool)); slots.push_back(slot); holds.push_back(std::move(hold)); } + const auto requestPacket = serialize(hidlRequest, hidlMeasure, slots); + return BurstExecution::create(shared_from_this(), std::move(requestPacket), + std::move(relocation), std::move(holds)); +} + +nn::ExecutionResult, nn::Timing>> +ExecutionBurstController::executeInternal(const std::vector& requestPacket, + const hal::utils::RequestRelocation& relocation, + FallbackFunction fallback) const { + NNTRACE_FULL(NNTRACE_LAYER_IPC, NNTRACE_PHASE_EXECUTION, + "ExecutionBurstController::executeInternal"); + + // Ensure that at most one execution is in flight at any given time. + const bool alreadyInFlight = mExecutionInFlight.test_and_set(); + if (alreadyInFlight) { + return NN_ERROR() << "IBurst already has an execution in flight"; + } + const auto guard = base::make_scope_guard([this] { mExecutionInFlight.clear(); }); + + if (relocation.input) { + relocation.input->flush(); + } + // send request packet - const auto sendStatus = mRequestChannelSender->send(hidlRequest, hidlMeasure, slots); + const auto sendStatus = mRequestChannelSender->sendPacket(requestPacket); if (!sendStatus.ok()) { // fallback to another execution path if the packet could not be sent - if (kFallback) { - return kFallback(request, measure, deadline, loopTimeoutDuration); + if (fallback) { + return fallback(); } return NN_ERROR() << "Error sending FMQ packet: " << sendStatus.error(); } @@ -333,7 +427,47 @@ ExecutionBurstController::execute(const nn::Request& request, nn::MeasureTiming // get result packet const auto [status, outputShapes, timing] = NN_TRY(hal::utils::makeExecutionFailure(mResultChannelReceiver->getBlocking())); + + if (relocation.output) { + relocation.output->flush(); + } return executionCallback(status, outputShapes, timing); } +nn::GeneralResult> BurstExecution::create( + std::shared_ptr controller, + std::vector request, hal::utils::RequestRelocation relocation, + std::vector cacheHolds) { + if (controller == nullptr) { + return NN_ERROR() << "V1_2::utils::BurstExecution::create must have non-null controller"; + } + + return std::make_shared(PrivateConstructorTag{}, std::move(controller), + std::move(request), std::move(relocation), + std::move(cacheHolds)); +} + +BurstExecution::BurstExecution(PrivateConstructorTag /*tag*/, + std::shared_ptr controller, + std::vector request, + hal::utils::RequestRelocation relocation, + std::vector cacheHolds) + : kController(std::move(controller)), + kRequest(std::move(request)), + kRelocation(std::move(relocation)), + kCacheHolds(std::move(cacheHolds)) {} + +nn::ExecutionResult, nn::Timing>> BurstExecution::compute( + const nn::OptionalTimePoint& /*deadline*/) const { + return kController->executeInternal(kRequest, kRelocation, /*fallback=*/nullptr); +} + +nn::GeneralResult> +BurstExecution::computeFenced(const std::vector& /*waitFor*/, + const nn::OptionalTimePoint& /*deadline*/, + const nn::OptionalDuration& /*timeoutDurationAfterFence*/) const { + return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) + << "IExecution::computeFenced is not supported on burst object"; +} + } // namespace android::hardware::neuralnetworks::V1_2::utils diff --git a/neuralnetworks/1.2/utils/src/PreparedModel.cpp b/neuralnetworks/1.2/utils/src/PreparedModel.cpp index e01401bdbb..1d8793733b 100644 --- a/neuralnetworks/1.2/utils/src/PreparedModel.cpp +++ b/neuralnetworks/1.2/utils/src/PreparedModel.cpp @@ -158,7 +158,7 @@ nn::GeneralResult PreparedModel::configureExecutionBurst() cons return preparedModel->execute(request, measure, deadline, loopTimeoutDuration); }; const auto pollingTimeWindow = getBurstControllerPollingTimeWindow(); - return ExecutionBurstController::create(kPreparedModel, std::move(fallback), pollingTimeWindow); + return ExecutionBurstController::create(shared_from_this(), kPreparedModel, pollingTimeWindow); } std::any PreparedModel::getUnderlyingResource() const { diff --git a/neuralnetworks/1.3/utils/src/PreparedModel.cpp b/neuralnetworks/1.3/utils/src/PreparedModel.cpp index 5163e8ac9d..cb56bdcb99 100644 --- a/neuralnetworks/1.3/utils/src/PreparedModel.cpp +++ b/neuralnetworks/1.3/utils/src/PreparedModel.cpp @@ -255,7 +255,7 @@ nn::GeneralResult PreparedModel::configureExecutionBurst() cons return preparedModel->execute(request, measure, deadline, loopTimeoutDuration); }; const auto pollingTimeWindow = V1_2::utils::getBurstControllerPollingTimeWindow(); - return V1_2::utils::ExecutionBurstController::create(kPreparedModel, std::move(fallback), + return V1_2::utils::ExecutionBurstController::create(shared_from_this(), kPreparedModel, pollingTimeWindow); } diff --git a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Burst.h b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Burst.h index 008e4e4fe3..0cc78d4f5e 100644 --- a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Burst.h +++ b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Burst.h @@ -38,7 +38,7 @@ namespace aidl::android::hardware::neuralnetworks::utils { // Class that adapts aidl_hal::IBurst to nn::IBurst. -class Burst final : public nn::IBurst { +class Burst final : public nn::IBurst, public std::enable_shared_from_this { struct PrivateConstructorTag {}; public: @@ -100,6 +100,16 @@ class Burst final : public nn::IBurst { const nn::OptionalTimePoint& deadline, const nn::OptionalDuration& loopTimeoutDuration) const override; + // See IBurst::createReusableExecution for information. + nn::GeneralResult createReusableExecution( + const nn::Request& request, nn::MeasureTiming measure, + const nn::OptionalDuration& loopTimeoutDuration) const override; + + nn::ExecutionResult, nn::Timing>> executeInternal( + const aidl_hal::Request& request, const std::vector& memoryIdentifierTokens, + bool measure, int64_t deadline, int64_t loopTimeoutDuration, + const hal::utils::RequestRelocation& relocation) const; + private: mutable std::atomic_flag mExecutionInFlight = ATOMIC_FLAG_INIT; const std::shared_ptr kBurst; diff --git a/neuralnetworks/aidl/utils/src/Burst.cpp b/neuralnetworks/aidl/utils/src/Burst.cpp index b20f6ae8e1..3cbba4d643 100644 --- a/neuralnetworks/aidl/utils/src/Burst.cpp +++ b/neuralnetworks/aidl/utils/src/Burst.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -35,6 +36,39 @@ namespace aidl::android::hardware::neuralnetworks::utils { namespace { +class BurstExecution final : public nn::IExecution, + public std::enable_shared_from_this { + struct PrivateConstructorTag {}; + + public: + static nn::GeneralResult> create( + std::shared_ptr burst, Request request, + std::vector memoryIdentifierTokens, bool measure, int64_t loopTimeoutDuration, + hal::utils::RequestRelocation relocation, + std::vector cacheHolds); + + BurstExecution(PrivateConstructorTag tag, std::shared_ptr burst, Request request, + std::vector memoryIdentifierTokens, bool measure, + int64_t loopTimeoutDuration, hal::utils::RequestRelocation relocation, + std::vector cacheHolds); + + nn::ExecutionResult, nn::Timing>> compute( + const nn::OptionalTimePoint& deadline) const override; + + nn::GeneralResult> computeFenced( + const std::vector& waitFor, const nn::OptionalTimePoint& deadline, + const nn::OptionalDuration& timeoutDurationAfterFence) const override; + + private: + const std::shared_ptr kBurst; + const Request kRequest; + const std::vector& kMemoryIdentifierTokens; + const bool kMeasure; + const int64_t kLoopTimeoutDuration; + const hal::utils::RequestRelocation kRelocation; + const std::vector kCacheHolds; +}; + nn::GeneralResult, nn::Timing>> convertExecutionResults( const std::vector& outputShapes, const Timing& timing) { return std::make_pair(NN_TRY(nn::convert(outputShapes)), NN_TRY(nn::convert(timing))); @@ -139,13 +173,6 @@ nn::ExecutionResult, nn::Timing>> Burst:: const nn::Request& request, nn::MeasureTiming measure, const nn::OptionalTimePoint& deadline, const nn::OptionalDuration& loopTimeoutDuration) const { - // Ensure that at most one execution is in flight at any given time. - const bool alreadyInFlight = mExecutionInFlight.test_and_set(); - if (alreadyInFlight) { - return NN_ERROR() << "IBurst already has an execution in flight"; - } - const auto guard = ::android::base::make_scope_guard([this] { mExecutionInFlight.clear(); }); - // Ensure that request is ready for IPC. std::optional maybeRequestInShared; hal::utils::RequestRelocation relocation; @@ -161,9 +188,9 @@ nn::ExecutionResult, nn::Timing>> Burst:: std::vector memoryIdentifierTokens; std::vector holds; - memoryIdentifierTokens.reserve(request.pools.size()); - holds.reserve(request.pools.size()); - for (const auto& memoryPool : request.pools) { + memoryIdentifierTokens.reserve(requestInShared.pools.size()); + holds.reserve(requestInShared.pools.size()); + for (const auto& memoryPool : requestInShared.pools) { if (const auto* memory = std::get_if(&memoryPool)) { if (auto cached = kMemoryCache->getMemoryIfAvailable(*memory)) { auto& [identifier, hold] = *cached; @@ -174,16 +201,30 @@ nn::ExecutionResult, nn::Timing>> Burst:: } memoryIdentifierTokens.push_back(-1); } - CHECK_EQ(request.pools.size(), memoryIdentifierTokens.size()); + CHECK_EQ(requestInShared.pools.size(), memoryIdentifierTokens.size()); + + return executeInternal(aidlRequest, memoryIdentifierTokens, aidlMeasure, aidlDeadline, + aidlLoopTimeoutDuration, relocation); +} + +nn::ExecutionResult, nn::Timing>> Burst::executeInternal( + const Request& request, const std::vector& memoryIdentifierTokens, bool measure, + int64_t deadline, int64_t loopTimeoutDuration, + const hal::utils::RequestRelocation& relocation) const { + // Ensure that at most one execution is in flight at any given time. + const bool alreadyInFlight = mExecutionInFlight.test_and_set(); + if (alreadyInFlight) { + return NN_ERROR() << "IBurst already has an execution in flight"; + } + const auto guard = ::android::base::make_scope_guard([this] { mExecutionInFlight.clear(); }); if (relocation.input) { relocation.input->flush(); } ExecutionResult executionResult; - const auto ret = - kBurst->executeSynchronously(aidlRequest, memoryIdentifierTokens, aidlMeasure, - aidlDeadline, aidlLoopTimeoutDuration, &executionResult); + const auto ret = kBurst->executeSynchronously(request, memoryIdentifierTokens, measure, + deadline, loopTimeoutDuration, &executionResult); HANDLE_ASTATUS(ret) << "execute failed"; if (!executionResult.outputSufficientSize) { auto canonicalOutputShapes = @@ -200,4 +241,82 @@ nn::ExecutionResult, nn::Timing>> Burst:: return std::make_pair(std::move(outputShapes), timing); } +nn::GeneralResult Burst::createReusableExecution( + const nn::Request& request, nn::MeasureTiming measure, + const nn::OptionalDuration& loopTimeoutDuration) const { + // Ensure that request is ready for IPC. + std::optional maybeRequestInShared; + hal::utils::RequestRelocation relocation; + const nn::Request& requestInShared = NN_TRY(hal::utils::convertRequestFromPointerToShared( + &request, &maybeRequestInShared, &relocation)); + + auto aidlRequest = NN_TRY(convert(requestInShared)); + const auto aidlMeasure = NN_TRY(convert(measure)); + const auto aidlLoopTimeoutDuration = NN_TRY(convert(loopTimeoutDuration)); + + std::vector memoryIdentifierTokens; + std::vector holds; + memoryIdentifierTokens.reserve(requestInShared.pools.size()); + holds.reserve(requestInShared.pools.size()); + for (const auto& memoryPool : requestInShared.pools) { + if (const auto* memory = std::get_if(&memoryPool)) { + if (auto cached = kMemoryCache->getMemoryIfAvailable(*memory)) { + auto& [identifier, hold] = *cached; + memoryIdentifierTokens.push_back(identifier); + holds.push_back(std::move(hold)); + continue; + } + } + memoryIdentifierTokens.push_back(-1); + } + CHECK_EQ(requestInShared.pools.size(), memoryIdentifierTokens.size()); + + return BurstExecution::create(shared_from_this(), std::move(aidlRequest), + std::move(memoryIdentifierTokens), aidlMeasure, + aidlLoopTimeoutDuration, std::move(relocation), std::move(holds)); +} + +nn::GeneralResult> BurstExecution::create( + std::shared_ptr burst, Request request, + std::vector memoryIdentifierTokens, bool measure, int64_t loopTimeoutDuration, + hal::utils::RequestRelocation relocation, + std::vector cacheHolds) { + if (burst == nullptr) { + return NN_ERROR() << "aidl::utils::BurstExecution::create must have non-null burst"; + } + + return std::make_shared( + PrivateConstructorTag{}, std::move(burst), std::move(request), + std::move(memoryIdentifierTokens), measure, loopTimeoutDuration, std::move(relocation), + std::move(cacheHolds)); +} + +BurstExecution::BurstExecution(PrivateConstructorTag /*tag*/, std::shared_ptr burst, + Request request, std::vector memoryIdentifierTokens, + bool measure, int64_t loopTimeoutDuration, + hal::utils::RequestRelocation relocation, + std::vector cacheHolds) + : kBurst(std::move(burst)), + kRequest(std::move(request)), + kMemoryIdentifierTokens(std::move(memoryIdentifierTokens)), + kMeasure(measure), + kLoopTimeoutDuration(loopTimeoutDuration), + kRelocation(std::move(relocation)), + kCacheHolds(std::move(cacheHolds)) {} + +nn::ExecutionResult, nn::Timing>> BurstExecution::compute( + const nn::OptionalTimePoint& deadline) const { + const auto aidlDeadline = NN_TRY(hal::utils::makeExecutionFailure(convert(deadline))); + return kBurst->executeInternal(kRequest, kMemoryIdentifierTokens, kMeasure, aidlDeadline, + kLoopTimeoutDuration, kRelocation); +} + +nn::GeneralResult> +BurstExecution::computeFenced(const std::vector& /*waitFor*/, + const nn::OptionalTimePoint& /*deadline*/, + const nn::OptionalDuration& /*timeoutDurationAfterFence*/) const { + return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) + << "IExecution::computeFenced is not supported on burst object"; +} + } // namespace aidl::android::hardware::neuralnetworks::utils diff --git a/neuralnetworks/utils/common/include/nnapi/hal/InvalidBurst.h b/neuralnetworks/utils/common/include/nnapi/hal/InvalidBurst.h index 17b3fd9d2b..e86eddab88 100644 --- a/neuralnetworks/utils/common/include/nnapi/hal/InvalidBurst.h +++ b/neuralnetworks/utils/common/include/nnapi/hal/InvalidBurst.h @@ -35,6 +35,10 @@ class InvalidBurst final : public nn::IBurst { const nn::Request& request, nn::MeasureTiming measure, const nn::OptionalTimePoint& deadline, const nn::OptionalDuration& loopTimeoutDuration) const override; + + nn::GeneralResult createReusableExecution( + const nn::Request& request, nn::MeasureTiming measure, + const nn::OptionalDuration& loopTimeoutDuration) const override; }; } // namespace android::hardware::neuralnetworks::utils diff --git a/neuralnetworks/utils/common/include/nnapi/hal/ResilientBurst.h b/neuralnetworks/utils/common/include/nnapi/hal/ResilientBurst.h index c92cc41dae..fde2486a53 100644 --- a/neuralnetworks/utils/common/include/nnapi/hal/ResilientBurst.h +++ b/neuralnetworks/utils/common/include/nnapi/hal/ResilientBurst.h @@ -51,7 +51,16 @@ class ResilientBurst final : public nn::IBurst, const nn::OptionalTimePoint& deadline, const nn::OptionalDuration& loopTimeoutDuration) const override; + nn::GeneralResult createReusableExecution( + const nn::Request& request, nn::MeasureTiming measure, + const nn::OptionalDuration& loopTimeoutDuration) const override; + private: + bool isValidInternal() const EXCLUDES(mMutex); + nn::GeneralResult createReusableExecutionInternal( + const nn::Request& request, nn::MeasureTiming measure, + const nn::OptionalDuration& loopTimeoutDuration) const; + const Factory kMakeBurst; mutable std::mutex mMutex; mutable nn::SharedBurst mBurst GUARDED_BY(mMutex); diff --git a/neuralnetworks/utils/common/src/InvalidBurst.cpp b/neuralnetworks/utils/common/src/InvalidBurst.cpp index 0c34f05265..01915337c4 100644 --- a/neuralnetworks/utils/common/src/InvalidBurst.cpp +++ b/neuralnetworks/utils/common/src/InvalidBurst.cpp @@ -38,4 +38,10 @@ nn::ExecutionResult, nn::Timing>> Invalid return NN_ERROR() << "InvalidBurst"; } +nn::GeneralResult InvalidBurst::createReusableExecution( + const nn::Request& /*request*/, nn::MeasureTiming /*measure*/, + const nn::OptionalDuration& /*loopTimeoutDuration*/) const { + return NN_ERROR() << "InvalidBurst"; +} + } // namespace android::hardware::neuralnetworks::utils diff --git a/neuralnetworks/utils/common/src/ResilientBurst.cpp b/neuralnetworks/utils/common/src/ResilientBurst.cpp index 38ccc62156..79cbe3991f 100644 --- a/neuralnetworks/utils/common/src/ResilientBurst.cpp +++ b/neuralnetworks/utils/common/src/ResilientBurst.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -29,6 +30,9 @@ #include #include +#include "InvalidExecution.h" +#include "ResilientExecution.h" + namespace android::hardware::neuralnetworks::utils { namespace { @@ -46,11 +50,11 @@ auto protect(const ResilientBurst& resilientBurst, const FnType& fn) // Attempt recovery and return if it fails. auto maybeBurst = resilientBurst.recover(burst.get()); if (!maybeBurst.has_value()) { - auto [resultErrorMessage, resultErrorCode, resultOutputShapes] = std::move(result).error(); - const auto& [recoveryErrorMessage, recoveryErrorCode] = maybeBurst.error(); - return nn::error(resultErrorCode, std::move(resultOutputShapes)) - << resultErrorMessage << ", and failed to recover dead burst object with error " - << recoveryErrorCode << ": " << recoveryErrorMessage; + const auto& [message, code] = maybeBurst.error(); + std::ostringstream oss; + oss << ", and failed to recover dead burst object with error " << code << ": " << message; + result.error().message += oss.str(); + return result; } burst = std::move(maybeBurst).value(); @@ -109,4 +113,35 @@ nn::ExecutionResult, nn::Timing>> Resilie return protect(*this, fn); } +nn::GeneralResult ResilientBurst::createReusableExecution( + const nn::Request& request, nn::MeasureTiming measure, + const nn::OptionalDuration& loopTimeoutDuration) const { +#if 0 + auto self = shared_from_this(); + ResilientExecution::Factory makeExecution = + [burst = std::move(self), request, measure, loopTimeoutDuration] { + return burst->createReusableExecutionInternal(request, measure, loopTimeoutDuration); + }; + return ResilientExecution::create(std::move(makeExecution)); +#else + return createReusableExecutionInternal(request, measure, loopTimeoutDuration); +#endif +} + +nn::GeneralResult ResilientBurst::createReusableExecutionInternal( + const nn::Request& request, nn::MeasureTiming measure, + const nn::OptionalDuration& loopTimeoutDuration) const { + if (!isValidInternal()) { + return std::make_shared(); + } + const auto fn = [&request, measure, &loopTimeoutDuration](const nn::IBurst& burst) { + return burst.createReusableExecution(request, measure, loopTimeoutDuration); + }; + return protect(*this, fn); +} + +bool ResilientBurst::isValidInternal() const { + return true; +} + } // namespace android::hardware::neuralnetworks::utils -- GitLab From 9ceb2ca13187f0bb16cb3a6534be98d0ca6be59d Mon Sep 17 00:00:00 2001 From: Yuncheol Heo Date: Fri, 7 May 2021 00:00:03 -0700 Subject: [PATCH 644/790] Set the intial value of Cluster VHAL. - This is the cause of the inital empty Cluster VHAL messages. Bug: 186455827 Test: Check the size of Cluster VHAL arguments by the logcat. Change-Id: I5703295c163af4bcc27bd7c41ff32eafcffcead3 --- .../vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h index abf33a3f46..81f31987e0 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h @@ -1245,6 +1245,7 @@ const ConfigDeclaration kVehicleProperties[]{ .access = VehiclePropertyAccess::READ, .changeMode = VehiclePropertyChangeMode::ON_CHANGE, }, + .initialValue = {.int32Values = {0 /* ClusterHome */, -1 /* ClusterNone */}}, }, { .config = @@ -1253,6 +1254,8 @@ const ConfigDeclaration kVehicleProperties[]{ .access = VehiclePropertyAccess::READ, .changeMode = VehiclePropertyChangeMode::ON_CHANGE, }, + .initialValue = {.int32Values = {0 /* Off */, -1, -1, -1, -1 /* Bounds */, + -1, -1, -1, -1 /* Insets */}}, }, { .config = @@ -1305,6 +1308,9 @@ const ConfigDeclaration kVehicleProperties[]{ .changeMode = VehiclePropertyChangeMode::ON_CHANGE, .configArray = {0, 0, 0, 11, 0, 0, 0, 0, 16}, }, + .initialValue = {.int32Values = {0 /* Off */, -1, -1, -1, -1 /* Bounds */, + -1, -1, -1, -1 /* Insets */, + 0 /* ClusterHome */, -1 /* ClusterNone */}}, }, { .config = @@ -1313,6 +1319,7 @@ const ConfigDeclaration kVehicleProperties[]{ .access = VehiclePropertyAccess::READ, .changeMode = VehiclePropertyChangeMode::ON_CHANGE, }, + .initialValue = {.int32Values = {0 /* ClusterHome */}}, }, { .config = -- GitLab From 8bfa243972d34c97111f0e7af6e77a0ab04d4f60 Mon Sep 17 00:00:00 2001 From: Xusong Wang Date: Fri, 7 May 2021 14:13:22 -0700 Subject: [PATCH 645/790] Use proper alignment and padding for pointer arguments -- HAL. This CL modifies the shared memory allocation for pointer arguments to use proper alignment and padding. We use default alignment (64) and min padding (1) for HIDL drivers, and default alignment (64) and default padding (64) for sAIDL drivers. Bug: 184164929 Test: NNT_static Change-Id: I22591640fa047d5f75d437edac1a7645d3b05526 --- neuralnetworks/1.0/utils/src/PreparedModel.cpp | 6 ++++-- .../1.2/utils/src/ExecutionBurstController.cpp | 6 ++++-- neuralnetworks/1.2/utils/src/PreparedModel.cpp | 6 ++++-- neuralnetworks/1.3/utils/src/PreparedModel.cpp | 9 ++++++--- neuralnetworks/aidl/utils/src/Burst.cpp | 6 ++++-- neuralnetworks/aidl/utils/src/PreparedModel.cpp | 9 ++++++--- .../utils/common/include/nnapi/hal/CommonUtils.h | 4 ++-- neuralnetworks/utils/common/src/CommonUtils.cpp | 8 ++++---- 8 files changed, 34 insertions(+), 20 deletions(-) diff --git a/neuralnetworks/1.0/utils/src/PreparedModel.cpp b/neuralnetworks/1.0/utils/src/PreparedModel.cpp index 7987ab4d7f..00970c090d 100644 --- a/neuralnetworks/1.0/utils/src/PreparedModel.cpp +++ b/neuralnetworks/1.0/utils/src/PreparedModel.cpp @@ -65,7 +65,8 @@ nn::ExecutionResult, nn::Timing>> Prepare hal::utils::RequestRelocation relocation; const nn::Request& requestInShared = NN_TRY(hal::utils::makeExecutionFailure(hal::utils::convertRequestFromPointerToShared( - &request, &maybeRequestInShared, &relocation))); + &request, nn::kDefaultRequestMemoryAlignment, nn::kMinMemoryPadding, + &maybeRequestInShared, &relocation))); const auto hidlRequest = NN_TRY(hal::utils::makeExecutionFailure(convert(requestInShared))); @@ -111,7 +112,8 @@ nn::GeneralResult PreparedModel::createReusableExecution( std::optional maybeRequestInShared; hal::utils::RequestRelocation relocation; const nn::Request& requestInShared = NN_TRY(hal::utils::convertRequestFromPointerToShared( - &request, &maybeRequestInShared, &relocation)); + &request, nn::kDefaultRequestMemoryAlignment, nn::kMinMemoryPadding, + &maybeRequestInShared, &relocation)); auto hidlRequest = NN_TRY(convert(requestInShared)); return Execution::create(shared_from_this(), std::move(hidlRequest), std::move(relocation)); diff --git a/neuralnetworks/1.2/utils/src/ExecutionBurstController.cpp b/neuralnetworks/1.2/utils/src/ExecutionBurstController.cpp index 8e82d2536d..b4b6f680d3 100644 --- a/neuralnetworks/1.2/utils/src/ExecutionBurstController.cpp +++ b/neuralnetworks/1.2/utils/src/ExecutionBurstController.cpp @@ -328,7 +328,8 @@ ExecutionBurstController::execute(const nn::Request& request, nn::MeasureTiming hal::utils::RequestRelocation relocation; const nn::Request& requestInShared = NN_TRY(hal::utils::makeExecutionFailure(hal::utils::convertRequestFromPointerToShared( - &request, &maybeRequestInShared, &relocation))); + &request, nn::kDefaultRequestMemoryAlignment, nn::kMinMemoryPadding, + &maybeRequestInShared, &relocation))); // clear pools field of request, as they will be provided via slots const auto requestWithoutPools = nn::Request{ @@ -373,7 +374,8 @@ nn::GeneralResult ExecutionBurstController::createReusableE std::optional maybeRequestInShared; hal::utils::RequestRelocation relocation; const nn::Request& requestInShared = NN_TRY(hal::utils::convertRequestFromPointerToShared( - &request, &maybeRequestInShared, &relocation)); + &request, nn::kDefaultRequestMemoryAlignment, nn::kMinMemoryPadding, + &maybeRequestInShared, &relocation)); // clear pools field of request, as they will be provided via slots const auto requestWithoutPools = nn::Request{ diff --git a/neuralnetworks/1.2/utils/src/PreparedModel.cpp b/neuralnetworks/1.2/utils/src/PreparedModel.cpp index 1d8793733b..d0ef36e7b5 100644 --- a/neuralnetworks/1.2/utils/src/PreparedModel.cpp +++ b/neuralnetworks/1.2/utils/src/PreparedModel.cpp @@ -97,7 +97,8 @@ nn::ExecutionResult, nn::Timing>> Prepare hal::utils::RequestRelocation relocation; const nn::Request& requestInShared = NN_TRY(hal::utils::makeExecutionFailure(hal::utils::convertRequestFromPointerToShared( - &request, &maybeRequestInShared, &relocation))); + &request, nn::kDefaultRequestMemoryAlignment, nn::kMinMemoryPadding, + &maybeRequestInShared, &relocation))); const auto hidlRequest = NN_TRY(hal::utils::makeExecutionFailure(convert(requestInShared))); const auto hidlMeasure = NN_TRY(hal::utils::makeExecutionFailure(convert(measure))); @@ -140,7 +141,8 @@ nn::GeneralResult PreparedModel::createReusableExecution( std::optional maybeRequestInShared; hal::utils::RequestRelocation relocation; const nn::Request& requestInShared = NN_TRY(hal::utils::convertRequestFromPointerToShared( - &request, &maybeRequestInShared, &relocation)); + &request, nn::kDefaultRequestMemoryAlignment, nn::kMinMemoryPadding, + &maybeRequestInShared, &relocation)); auto hidlRequest = NN_TRY(convert(requestInShared)); auto hidlMeasure = NN_TRY(convert(measure)); diff --git a/neuralnetworks/1.3/utils/src/PreparedModel.cpp b/neuralnetworks/1.3/utils/src/PreparedModel.cpp index cb56bdcb99..1623de5e9f 100644 --- a/neuralnetworks/1.3/utils/src/PreparedModel.cpp +++ b/neuralnetworks/1.3/utils/src/PreparedModel.cpp @@ -143,7 +143,8 @@ nn::ExecutionResult, nn::Timing>> Prepare hal::utils::RequestRelocation relocation; const nn::Request& requestInShared = NN_TRY(hal::utils::makeExecutionFailure(hal::utils::convertRequestFromPointerToShared( - &request, &maybeRequestInShared, &relocation))); + &request, nn::kDefaultRequestMemoryAlignment, nn::kMinMemoryPadding, + &maybeRequestInShared, &relocation))); const auto hidlRequest = NN_TRY(hal::utils::makeExecutionFailure(convert(requestInShared))); const auto hidlMeasure = NN_TRY(hal::utils::makeExecutionFailure(convert(measure))); @@ -184,7 +185,8 @@ PreparedModel::executeFenced(const nn::Request& request, const std::vector maybeRequestInShared; hal::utils::RequestRelocation relocation; const nn::Request& requestInShared = NN_TRY(hal::utils::convertRequestFromPointerToShared( - &request, &maybeRequestInShared, &relocation)); + &request, nn::kDefaultRequestMemoryAlignment, nn::kMinMemoryPadding, + &maybeRequestInShared, &relocation)); const auto hidlRequest = NN_TRY(convert(requestInShared)); const auto hidlWaitFor = NN_TRY(hal::utils::convertSyncFences(waitFor)); @@ -236,7 +238,8 @@ nn::GeneralResult PreparedModel::createReusableExecution( std::optional maybeRequestInShared; hal::utils::RequestRelocation relocation; const nn::Request& requestInShared = NN_TRY(hal::utils::convertRequestFromPointerToShared( - &request, &maybeRequestInShared, &relocation)); + &request, nn::kDefaultRequestMemoryAlignment, nn::kMinMemoryPadding, + &maybeRequestInShared, &relocation)); auto hidlRequest = NN_TRY(convert(requestInShared)); auto hidlMeasure = NN_TRY(convert(measure)); diff --git a/neuralnetworks/aidl/utils/src/Burst.cpp b/neuralnetworks/aidl/utils/src/Burst.cpp index 3cbba4d643..87cd0e4afe 100644 --- a/neuralnetworks/aidl/utils/src/Burst.cpp +++ b/neuralnetworks/aidl/utils/src/Burst.cpp @@ -178,7 +178,8 @@ nn::ExecutionResult, nn::Timing>> Burst:: hal::utils::RequestRelocation relocation; const nn::Request& requestInShared = NN_TRY(hal::utils::makeExecutionFailure(hal::utils::convertRequestFromPointerToShared( - &request, &maybeRequestInShared, &relocation))); + &request, nn::kDefaultRequestMemoryAlignment, nn::kDefaultRequestMemoryPadding, + &maybeRequestInShared, &relocation))); const auto aidlRequest = NN_TRY(hal::utils::makeExecutionFailure(convert(requestInShared))); const auto aidlMeasure = NN_TRY(hal::utils::makeExecutionFailure(convert(measure))); @@ -248,7 +249,8 @@ nn::GeneralResult Burst::createReusableExecution( std::optional maybeRequestInShared; hal::utils::RequestRelocation relocation; const nn::Request& requestInShared = NN_TRY(hal::utils::convertRequestFromPointerToShared( - &request, &maybeRequestInShared, &relocation)); + &request, nn::kDefaultRequestMemoryAlignment, nn::kDefaultRequestMemoryPadding, + &maybeRequestInShared, &relocation)); auto aidlRequest = NN_TRY(convert(requestInShared)); const auto aidlMeasure = NN_TRY(convert(measure)); diff --git a/neuralnetworks/aidl/utils/src/PreparedModel.cpp b/neuralnetworks/aidl/utils/src/PreparedModel.cpp index 191560786f..18e7636346 100644 --- a/neuralnetworks/aidl/utils/src/PreparedModel.cpp +++ b/neuralnetworks/aidl/utils/src/PreparedModel.cpp @@ -80,7 +80,8 @@ nn::ExecutionResult, nn::Timing>> Prepare hal::utils::RequestRelocation relocation; const nn::Request& requestInShared = NN_TRY(hal::utils::makeExecutionFailure(hal::utils::convertRequestFromPointerToShared( - &request, &maybeRequestInShared, &relocation))); + &request, nn::kDefaultRequestMemoryAlignment, nn::kDefaultRequestMemoryPadding, + &maybeRequestInShared, &relocation))); const auto aidlRequest = NN_TRY(hal::utils::makeExecutionFailure(convert(requestInShared))); const auto aidlMeasure = NN_TRY(hal::utils::makeExecutionFailure(convert(measure))); @@ -127,7 +128,8 @@ PreparedModel::executeFenced(const nn::Request& request, const std::vector maybeRequestInShared; hal::utils::RequestRelocation relocation; const nn::Request& requestInShared = NN_TRY(hal::utils::convertRequestFromPointerToShared( - &request, &maybeRequestInShared, &relocation)); + &request, nn::kDefaultRequestMemoryAlignment, nn::kDefaultRequestMemoryPadding, + &maybeRequestInShared, &relocation)); const auto aidlRequest = NN_TRY(convert(requestInShared)); const auto aidlWaitFor = NN_TRY(convert(waitFor)); @@ -197,7 +199,8 @@ nn::GeneralResult PreparedModel::createReusableExecution( std::optional maybeRequestInShared; hal::utils::RequestRelocation relocation; const nn::Request& requestInShared = NN_TRY(hal::utils::convertRequestFromPointerToShared( - &request, &maybeRequestInShared, &relocation)); + &request, nn::kDefaultRequestMemoryAlignment, nn::kDefaultRequestMemoryPadding, + &maybeRequestInShared, &relocation)); auto aidlRequest = NN_TRY(convert(requestInShared)); auto aidlMeasure = NN_TRY(convert(measure)); diff --git a/neuralnetworks/utils/common/include/nnapi/hal/CommonUtils.h b/neuralnetworks/utils/common/include/nnapi/hal/CommonUtils.h index fdc90dfb41..702ee92da8 100644 --- a/neuralnetworks/utils/common/include/nnapi/hal/CommonUtils.h +++ b/neuralnetworks/utils/common/include/nnapi/hal/CommonUtils.h @@ -122,8 +122,8 @@ struct RequestRelocation { // Unlike `flushDataFromPointerToShared`, this method will not copy the input pointer data to the // shared memory pool. Use `relocationOut` to flush the input or output data after the call. nn::GeneralResult> convertRequestFromPointerToShared( - const nn::Request* request, std::optional* maybeRequestInSharedOut, - RequestRelocation* relocationOut); + const nn::Request* request, uint32_t alignment, uint32_t padding, + std::optional* maybeRequestInSharedOut, RequestRelocation* relocationOut); nn::GeneralResult> countNumberOfConsumers( size_t numberOfOperands, const std::vector& operations); diff --git a/neuralnetworks/utils/common/src/CommonUtils.cpp b/neuralnetworks/utils/common/src/CommonUtils.cpp index eaeb9ad872..8e55bf0253 100644 --- a/neuralnetworks/utils/common/src/CommonUtils.cpp +++ b/neuralnetworks/utils/common/src/CommonUtils.cpp @@ -220,8 +220,8 @@ void OutputRelocationTracker::flush() const { } nn::GeneralResult> convertRequestFromPointerToShared( - const nn::Request* request, std::optional* maybeRequestInSharedOut, - RequestRelocation* relocationOut) { + const nn::Request* request, uint32_t alignment, uint32_t padding, + std::optional* maybeRequestInSharedOut, RequestRelocation* relocationOut) { CHECK(request != nullptr); CHECK(maybeRequestInSharedOut != nullptr); CHECK(relocationOut != nullptr); @@ -249,7 +249,7 @@ nn::GeneralResult> convertRequestFromP const void* data = std::visit([](auto ptr) { return static_cast(ptr); }, location.pointer); CHECK(data != nullptr); - input.location = inputBuilder.append(location.length); + input.location = inputBuilder.append(location.length, alignment, padding); inputRelocationInfos.push_back({data, input.location.length, input.location.offset}); } @@ -273,7 +273,7 @@ nn::GeneralResult> convertRequestFromP output.lifetime = nn::Request::Argument::LifeTime::POOL; void* data = std::get(location.pointer); CHECK(data != nullptr); - output.location = outputBuilder.append(location.length); + output.location = outputBuilder.append(location.length, alignment, padding); outputRelocationInfos.push_back({data, output.location.length, output.location.offset}); } -- GitLab From 952cbec10092d1608aee3294d2800d991b8e4862 Mon Sep 17 00:00:00 2001 From: Joe Huang Date: Tue, 27 Apr 2021 19:32:49 +0800 Subject: [PATCH 646/790] Add additonal doc for SatellitePvt Bug: 183239007 Test: atest VtsHalGnssTargetTest Change-Id: I83d1aefd594be9616630ef17cdc1027d39bc0086 --- .../hardware/gnss/GnssMeasurement.aidl | 11 ++++++++++ .../hardware/gnss/SatelliteClockInfo.aidl | 21 ++++++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl b/gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl index 336e9272a6..58f29c5f92 100644 --- a/gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl +++ b/gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl @@ -625,6 +625,17 @@ parcelable GnssMeasurement { * The position and velocity must be in ECEF coordinates. * * If the data is available, gnssMeasurementFlags must contain HAS_SATELLITE_PVT. + * + * If SatellitePvt is derived from Broadcast ephemeris, then the position is already w.r.t. + * the antenna phase center. However, if SatellitePvt is derived from other modeled orbits, + * such as long-term-orbits, or precise orbits, then the orbits may have been computed w.r.t. + * the satellite center of mass, and then GNSS vendors are expected to correct for the effect + * on different phase centers (can differ by meters) of different GNSS signals (e.g. L1, L5) + * on the reported satellite position. Accordingly, we might observe a different satellite + * position reported for L1 GnssMeasurement struct compared to L5 GnssMeasurement struct. + * + * If receivedSvTimeNs is not fully decoded, Satellite PVT could still be reported and + * receivedSvTimeNs uncertainty field would be used to provide confidence. */ SatellitePvt satellitePvt; diff --git a/gnss/aidl/android/hardware/gnss/SatelliteClockInfo.aidl b/gnss/aidl/android/hardware/gnss/SatelliteClockInfo.aidl index 844fd1c47d..4b7d5d68cb 100644 --- a/gnss/aidl/android/hardware/gnss/SatelliteClockInfo.aidl +++ b/gnss/aidl/android/hardware/gnss/SatelliteClockInfo.aidl @@ -24,6 +24,14 @@ parcelable SatelliteClockInfo { /** * Satellite hardware code bias of the reported code type w.r.t * ionosphere-free measurement in meters. + * + * When broadcast ephemeris is used, this is the offset caused + * by the satellite hardware delays at different frequencies; + * e.g. in IS-GPS-705D, this term is described in Section + * 20.3.3.3.1.2.1. + * + * For GPS this term is ~10ns, and affects the satellite position + * computation by less than a millimeter. */ double satHardwareCodeBiasMeters; @@ -31,9 +39,20 @@ parcelable SatelliteClockInfo { * Satellite time correction for ionospheric-free signal measurement * (meters). The satellite clock correction for the given signal type * = satTimeCorrectionMeters - satHardwareCodeBiasMeters. + * + * When broadcast ephemeris is used, this is the offset modeled in the + * clock terms broadcast over the air by the satellites; + * e.g. in IS-GPS-200H, Section 20.3.3.3.3.1, this term is + * ∆tsv = af0 + af1(t - toc) + af2(t - toc)^2 + ∆tr. + * + * If another source of ephemeris is used for SatellitePvt, then the + * equivalent value of satTimeCorrection must be provided. + * + * For GPS this term is ~1ms, and affects the satellite position + * computation by ~1m. */ double satTimeCorrectionMeters; /** Satellite clock drift (meters per second). */ double satClkDriftMps; -} \ No newline at end of file +} -- GitLab From f985398f1bc0892db136c652ec71ea0e1387be1b Mon Sep 17 00:00:00 2001 From: Joe Huang Date: Sat, 8 May 2021 13:27:29 +0800 Subject: [PATCH 647/790] Add valid satellite PVT fields in SatellitePvt Bug: 187145250 Test: atest VtsHalGnssTargetTest Change-Id: I6c43b22991173ed183ac47f7ffcf23f8481fe928 --- .../android/hardware/gnss/SatellitePvt.aidl | 4 ++ .../android/hardware/gnss/SatellitePvt.aidl | 32 +++++++++++- gnss/aidl/vts/gnss_hal_test_cases.cpp | 50 +++++++++++++------ gnss/common/utils/default/Utils.cpp | 5 +- 4 files changed, 72 insertions(+), 19 deletions(-) diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatellitePvt.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatellitePvt.aidl index 747ee90933..8c1784174d 100644 --- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatellitePvt.aidl +++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/SatellitePvt.aidl @@ -34,9 +34,13 @@ package android.hardware.gnss; @VintfStability parcelable SatellitePvt { + int flags; android.hardware.gnss.SatellitePositionEcef satPosEcef; android.hardware.gnss.SatelliteVelocityEcef satVelEcef; android.hardware.gnss.SatelliteClockInfo satClockInfo; double ionoDelayMeters; double tropoDelayMeters; + const int HAS_POSITION_VELOCITY_CLOCK_INFO = 1; + const int HAS_IONO = 2; + const int HAS_TROPO = 4; } diff --git a/gnss/aidl/android/hardware/gnss/SatellitePvt.aidl b/gnss/aidl/android/hardware/gnss/SatellitePvt.aidl index ea55f0c257..a238e3fc26 100644 --- a/gnss/aidl/android/hardware/gnss/SatellitePvt.aidl +++ b/gnss/aidl/android/hardware/gnss/SatellitePvt.aidl @@ -16,9 +16,9 @@ package android.hardware.gnss; +import android.hardware.gnss.SatelliteClockInfo; import android.hardware.gnss.SatellitePositionEcef; import android.hardware.gnss.SatelliteVelocityEcef; -import android.hardware.gnss.SatelliteClockInfo; /** * Contains estimates of the satellite position, velocity and time in the @@ -26,6 +26,34 @@ import android.hardware.gnss.SatelliteClockInfo; */ @VintfStability parcelable SatellitePvt { + /** + * Bit mask indicating valid satellite position, velocity and clock info fields are + * stored in the SatellitePvt. + */ + const int HAS_POSITION_VELOCITY_CLOCK_INFO = 1 << 0; + + /** + * Bit mask indicating a valid iono delay field is stored in the SatellitePvt. + */ + const int HAS_IONO = 1 << 1; + + /** + * Bit mask indicating a valid tropo delay field is stored in the SatellitePvt. + */ + const int HAS_TROPO = 1 << 2; + + /** + * A bitfield of flags indicating the validity of the fields in this SatellitePvt. + * The bit masks are defined in the constants with prefix HAS_* + * + * Fields for which there is no corresponding flag must be filled in with a valid value. + * For convenience, these are marked as mandatory. + * + * Others fields may have invalid information in them, if not marked as valid by the + * corresponding bit in flags. + */ + int flags; + /** * Satellite position in WGS84 ECEF. See comments of * SatellitePositionEcef for units. @@ -46,4 +74,4 @@ parcelable SatellitePvt { /** Tropospheric delay in meters. */ double tropoDelayMeters; -} \ No newline at end of file +} diff --git a/gnss/aidl/vts/gnss_hal_test_cases.cpp b/gnss/aidl/vts/gnss_hal_test_cases.cpp index 0fc2ff8a38..67ccf52c15 100644 --- a/gnss/aidl/vts/gnss_hal_test_cases.cpp +++ b/gnss/aidl/vts/gnss_hal_test_cases.cpp @@ -38,6 +38,7 @@ using android::hardware::gnss::IGnssMeasurementInterface; using android::hardware::gnss::IGnssPowerIndication; using android::hardware::gnss::IGnssPsds; using android::hardware::gnss::PsdsType; +using android::hardware::gnss::SatellitePvt; using GnssConstellationTypeAidl = android::hardware::gnss::GnssConstellationType; @@ -128,22 +129,39 @@ TEST_P(GnssHalTest, TestGnssMeasurementExtension) { GnssMeasurement::HAS_SATELLITE_PVT | GnssMeasurement::HAS_CORRELATION_VECTOR)); - if ((measurement.flags & GnssMeasurement::HAS_SATELLITE_PVT) && - (has_capability_satpvt == true)) { - ASSERT_TRUE(measurement.satellitePvt.satPosEcef.posXMeters >= -43000000 && - measurement.satellitePvt.satPosEcef.posXMeters <= 43000000); - ASSERT_TRUE(measurement.satellitePvt.satPosEcef.posYMeters >= -43000000 && - measurement.satellitePvt.satPosEcef.posYMeters <= 43000000); - ASSERT_TRUE(measurement.satellitePvt.satPosEcef.posZMeters >= -43000000 && - measurement.satellitePvt.satPosEcef.posZMeters <= 43000000); - ASSERT_TRUE(measurement.satellitePvt.satPosEcef.ureMeters > 0); - ASSERT_TRUE(measurement.satellitePvt.satVelEcef.velXMps >= -4000 && - measurement.satellitePvt.satVelEcef.velXMps <= 4000); - ASSERT_TRUE(measurement.satellitePvt.satVelEcef.velYMps >= -4000 && - measurement.satellitePvt.satVelEcef.velYMps <= 4000); - ASSERT_TRUE(measurement.satellitePvt.satVelEcef.velZMps >= -4000 && - measurement.satellitePvt.satVelEcef.velZMps <= 4000); - ASSERT_TRUE(measurement.satellitePvt.satVelEcef.ureRateMps > 0); + if (measurement.flags & GnssMeasurement::HAS_SATELLITE_PVT && + has_capability_satpvt == true) { + if (measurement.satellitePvt.flags & SatellitePvt::HAS_POSITION_VELOCITY_CLOCK_INFO) { + ASSERT_TRUE(measurement.satellitePvt.satPosEcef.posXMeters >= -43000000 && + measurement.satellitePvt.satPosEcef.posXMeters <= 43000000); + ASSERT_TRUE(measurement.satellitePvt.satPosEcef.posYMeters >= -43000000 && + measurement.satellitePvt.satPosEcef.posYMeters <= 43000000); + ASSERT_TRUE(measurement.satellitePvt.satPosEcef.posZMeters >= -43000000 && + measurement.satellitePvt.satPosEcef.posZMeters <= 43000000); + ASSERT_TRUE(measurement.satellitePvt.satPosEcef.ureMeters > 0); + ASSERT_TRUE(measurement.satellitePvt.satVelEcef.velXMps >= -4000 && + measurement.satellitePvt.satVelEcef.velXMps <= 4000); + ASSERT_TRUE(measurement.satellitePvt.satVelEcef.velYMps >= -4000 && + measurement.satellitePvt.satVelEcef.velYMps <= 4000); + ASSERT_TRUE(measurement.satellitePvt.satVelEcef.velZMps >= -4000 && + measurement.satellitePvt.satVelEcef.velZMps <= 4000); + ASSERT_TRUE(measurement.satellitePvt.satVelEcef.ureRateMps > 0); + ASSERT_TRUE( + measurement.satellitePvt.satClockInfo.satHardwareCodeBiasMeters > -17.869 && + measurement.satellitePvt.satClockInfo.satHardwareCodeBiasMeters < 17.729); + ASSERT_TRUE(measurement.satellitePvt.satClockInfo.satTimeCorrectionMeters > -3e6 && + measurement.satellitePvt.satClockInfo.satTimeCorrectionMeters < 3e6); + ASSERT_TRUE(measurement.satellitePvt.satClockInfo.satClkDriftMps > -1.117 && + measurement.satellitePvt.satClockInfo.satClkDriftMps < 1.117); + } + if (measurement.satellitePvt.flags & SatellitePvt::HAS_IONO) { + ASSERT_TRUE(measurement.satellitePvt.ionoDelayMeters > 0 && + measurement.satellitePvt.ionoDelayMeters < 100); + } + if (measurement.satellitePvt.flags & SatellitePvt::HAS_TROPO) { + ASSERT_TRUE(measurement.satellitePvt.tropoDelayMeters > 0 && + measurement.satellitePvt.tropoDelayMeters < 100); + } } if (kIsCorrelationVectorSupported && diff --git a/gnss/common/utils/default/Utils.cpp b/gnss/common/utils/default/Utils.cpp index 9bc6786b80..569dac4c59 100644 --- a/gnss/common/utils/default/Utils.cpp +++ b/gnss/common/utils/default/Utils.cpp @@ -31,6 +31,7 @@ using aidl::android::hardware::gnss::GnssData; using aidl::android::hardware::gnss::GnssMeasurement; using aidl::android::hardware::gnss::IGnss; using aidl::android::hardware::gnss::IGnssMeasurementCallback; +using aidl::android::hardware::gnss::SatellitePvt; using GnssSvFlags = V1_0::IGnssCallback::GnssSvFlags; using GnssMeasurementFlagsV1_0 = V1_0::IGnssMeasurementCallback::GnssMeasurementFlags; @@ -175,7 +176,9 @@ GnssData Utils::getMockMeasurement(const bool enableCorrVecOutputs) { .fullInterSignalBiasUncertaintyNs = 792.0, .satelliteInterSignalBiasNs = 233.9, .satelliteInterSignalBiasUncertaintyNs = 921.2, - .satellitePvt = {.satPosEcef = {.posXMeters = 10442993.1153328, + .satellitePvt = {.flags = SatellitePvt::HAS_POSITION_VELOCITY_CLOCK_INFO | + SatellitePvt::HAS_IONO | SatellitePvt::HAS_TROPO, + .satPosEcef = {.posXMeters = 10442993.1153328, .posYMeters = -19926932.8051666, .posZMeters = -12034295.0216203, .ureMeters = 1000.2345678}, -- GitLab From 92912b6300f4d1a1e51bfa7849514d78b58e13d1 Mon Sep 17 00:00:00 2001 From: masonwang Date: Fri, 7 May 2021 16:00:55 +0800 Subject: [PATCH 648/790] Fix VTS BatchingOperation Test. Change list: 1. Cap minFifoCount to batching period worth of samples. 2. Modify the test period: From : batchingPeriodInNs * (0.8 + 0.8) = 1.6 times the batchingPeriodInNs To batchingPeriodInNs * (0.8 + 0.2) = batchingPeriodInNs Bug: 185972775 Test: Verify pass by checking event count if it is closed to the criteria. Change-Id: Ied178150788e1a80d6fa6c87afbd1738ade48a0b --- .../utils/include/sensors-vts-utils/SensorsHidlTestBase.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlTestBase.h b/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlTestBase.h index a8e19967d5..af140096b8 100644 --- a/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlTestBase.h +++ b/sensors/common/vts/utils/include/sensors-vts-utils/SensorsHidlTestBase.h @@ -425,7 +425,10 @@ class SensorsHidlTestBase : public testing::TestWithParam { return; } - batchingPeriodInNs = std::min(batchingPeriodInNs, maxBatchingTestTimeNs); + if (batchingPeriodInNs > maxBatchingTestTimeNs) { + batchingPeriodInNs = maxBatchingTestTimeNs; + minFifoCount = (uint32_t)(batchingPeriodInNs / minSamplingPeriodInNs); + } ALOGI("Test batching for %d ms", (int)(batchingPeriodInNs / 1000 / 1000)); @@ -448,7 +451,7 @@ class SensorsHidlTestBase : public testing::TestWithParam { false /*change collection*/); // 0.8 + 0.2 times the batching period - usleep(batchingPeriodInNs / 1000 * 8 / 10); + usleep(batchingPeriodInNs / 1000 * 2 / 10); ASSERT_EQ(flush(handle), Result::OK); // plus some time for the event to deliver -- GitLab From 77160fad8aace240874ab1d02b8d7dc6bd117cff Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Mon, 10 May 2021 10:07:34 -0700 Subject: [PATCH 649/790] Deflake WorkerThreadTest Bug: 187402940 Test: atest --host --retry-until-failure 100 WorkerThreadTest Change-Id: Ie4abd413e9cf18f73c2a4e22004dc33561006e72 --- .../aidl/default/tests/WorkerThreadTest.cpp | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/biometrics/fingerprint/aidl/default/tests/WorkerThreadTest.cpp b/biometrics/fingerprint/aidl/default/tests/WorkerThreadTest.cpp index c548fe5bfb..84433364df 100644 --- a/biometrics/fingerprint/aidl/default/tests/WorkerThreadTest.cpp +++ b/biometrics/fingerprint/aidl/default/tests/WorkerThreadTest.cpp @@ -40,8 +40,7 @@ TEST(WorkerThreadTest, ScheduleReturnsTrueWhenQueueHasSpace) { promise.set_value(); }))); - auto status = future.wait_for(1s); - EXPECT_EQ(status, std::future_status::ready); + future.wait(); } } @@ -56,12 +55,11 @@ TEST(WorkerThreadTest, ScheduleReturnsFalseWhenQueueIsFull) { // Notify that the task has started. promise.set_value(); // Block for a "very long" time. - std::this_thread::sleep_for(2s); + std::this_thread::sleep_for(1s); }))); // Make sure the long-running task began executing. - auto status = future.wait_for(1s); - ASSERT_EQ(status, std::future_status::ready); + future.wait(); // The first task is already being worked on, which means the queue must be empty. // Fill the worker's queue to the maximum. @@ -91,8 +89,7 @@ TEST(WorkerThreadTest, TasksExecuteInOrder) { // Schedule a special task to signal when all of the tasks are finished. worker.schedule( Callable::from([promise = std::move(promise)]() mutable { promise.set_value(); })); - auto status = future.wait_for(1s); - ASSERT_EQ(status, std::future_status::ready); + future.wait(); ASSERT_EQ(results.size(), NUM_TASKS); EXPECT_TRUE(std::is_sorted(results.begin(), results.end())); @@ -115,8 +112,7 @@ TEST(WorkerThreadTest, ExecutionStopsAfterWorkerIsDestroyed) { }))); // The first task should start executing. - auto status = future1.wait_for(1s); - ASSERT_EQ(status, std::future_status::ready); + future1.wait(); // The second task should schedule successfully. ASSERT_TRUE( @@ -128,8 +124,7 @@ TEST(WorkerThreadTest, ExecutionStopsAfterWorkerIsDestroyed) { } // The second task should never execute. - auto status = future2.wait_for(1s); - ASSERT_EQ(status, std::future_status::ready); + future2.wait(); // The future is expected to be ready but contain an exception. // Cannot use ASSERT_THROW because exceptions are disabled in this codebase. // ASSERT_THROW(future2.get(), std::future_error); -- GitLab From d017b6d121d5d3483c3c573461631b762aa5e223 Mon Sep 17 00:00:00 2001 From: Shinru Han Date: Wed, 12 May 2021 13:52:52 +0800 Subject: [PATCH 650/790] Correct position mode in GetLocationLowPower test Bug: 184728670 Test: on device Change-Id: I3ee7078f0e7b87715c1b6d681bcdba421c6d5af7 --- gnss/2.0/vts/functional/gnss_hal_test_cases.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp b/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp index f17336bc25..f57c599125 100644 --- a/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp +++ b/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp @@ -464,12 +464,10 @@ TEST_P(GnssHalTest, GetLocationLowPower) { gnss_cb_->location_cbq_.reset(); // Start of Low Power Mode test - SetPositionMode(kMinIntervalMsec, kLowPowerMode); - // Don't expect true - as without AGPS access if (!StartAndCheckFirstLocation(/* strict= */ false, - /* min_interval_msec= */ 1000, - /* low_power_mode= */ false)) { + /* min_interval_msec= */ kMinIntervalMsec, + /* low_power_mode= */ kLowPowerMode)) { ALOGW("GetLocationLowPower test - no first low power location received."); } -- GitLab From efb934b15a4643936575b7baf8d962f541802684 Mon Sep 17 00:00:00 2001 From: Jack Yu Date: Wed, 12 May 2021 18:31:55 -0700 Subject: [PATCH 651/790] Skip tests for single SIM devices When device is configured as single SIM device, skip VTS on 2nd vendor radio service instance. Fix: 187998097 Test: atest VtsHalRadioV1_6TargetTest Change-Id: Ib634b22dd75f10e5059c9482764ca481184162be --- radio/1.0/vts/functional/vts_test_util.cpp | 7 ++++ radio/1.0/vts/functional/vts_test_util.h | 9 +++-- .../vts/functional/radio_hidl_hal_test.cpp | 33 ++++++++++++++++++- .../functional/radio_hidl_hal_utils_v1_6.h | 4 ++- 4 files changed, 49 insertions(+), 4 deletions(-) diff --git a/radio/1.0/vts/functional/vts_test_util.cpp b/radio/1.0/vts/functional/vts_test_util.cpp index fc372011ed..5b31accbd2 100644 --- a/radio/1.0/vts/functional/vts_test_util.cpp +++ b/radio/1.0/vts/functional/vts_test_util.cpp @@ -83,6 +83,13 @@ bool deviceSupportsFeature(const char* feature) { return hasFeature; } +bool isSsSsEnabled() { + // Do not use checkSubstringInCommandOutput("getprop persist.radio.multisim.config", "") + // until b/148904287 is fixed. We need exact matching instead of partial matching. (i.e. + // by definition the empty string "" is a substring of any string). + return !isDsDsEnabled() && !isTsTsEnabled(); +} + bool isDsDsEnabled() { return testing::checkSubstringInCommandOutput("getprop persist.radio.multisim.config", "dsds"); } diff --git a/radio/1.0/vts/functional/vts_test_util.h b/radio/1.0/vts/functional/vts_test_util.h index eeb1d299ab..fa338a38a5 100644 --- a/radio/1.0/vts/functional/vts_test_util.h +++ b/radio/1.0/vts/functional/vts_test_util.h @@ -80,12 +80,17 @@ int GetRandomSerialNumber(); bool deviceSupportsFeature(const char* feature); /* - * Check if device is in DSDS. + * Check if device is in SsSs (Single SIM Single Standby). + */ +bool isSsSsEnabled(); + +/* + * Check if device is in DSDS (Dual SIM Dual Standby). */ bool isDsDsEnabled(); /* - * Check if device is in TSTS. + * Check if device is in TSTS (Triple SIM Triple Standby). */ bool isTsTsEnabled(); diff --git a/radio/1.6/vts/functional/radio_hidl_hal_test.cpp b/radio/1.6/vts/functional/radio_hidl_hal_test.cpp index 5d514a0e6e..00f4468dce 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_test.cpp +++ b/radio/1.6/vts/functional/radio_hidl_hal_test.cpp @@ -16,8 +16,39 @@ #include +bool isServiceValidForDeviceConfiguration(hidl_string& serviceName) { + if (isSsSsEnabled()) { + // Device is configured as SSSS. + if (serviceName != RADIO_SERVICE_SLOT1_NAME) { + ALOGI("%s instance is not valid for SSSS device.", serviceName.c_str()); + return false; + } + } else if (isDsDsEnabled()) { + // Device is configured as DSDS. + if (serviceName != RADIO_SERVICE_SLOT1_NAME && serviceName != RADIO_SERVICE_SLOT2_NAME) { + ALOGI("%s instance is not valid for DSDS device.", serviceName.c_str()); + return false; + } + } else if (isTsTsEnabled()) { + // Device is configured as TSTS. + if (serviceName != RADIO_SERVICE_SLOT1_NAME && serviceName != RADIO_SERVICE_SLOT2_NAME && + serviceName != RADIO_SERVICE_SLOT3_NAME) { + ALOGI("%s instance is not valid for TSTS device.", serviceName.c_str()); + return false; + } + } + return true; +} + void RadioHidlTest_v1_6::SetUp() { - radio_v1_6 = android::hardware::radio::V1_6::IRadio::getService(GetParam()); + hidl_string serviceName = GetParam(); + + if (!isServiceValidForDeviceConfiguration(serviceName)) { + ALOGI("Skipped the test due to device configuration."); + GTEST_SKIP(); + } + + radio_v1_6 = android::hardware::radio::V1_6::IRadio::getService(serviceName); ASSERT_NE(nullptr, radio_v1_6.get()); radioRsp_v1_6 = new (std::nothrow) RadioResponse_v1_6(*this); diff --git a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h index 3185f98364..54c297719f 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h +++ b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h @@ -48,7 +48,9 @@ using ::android::hardware::Void; #define MODEM_EMERGENCY_CALL_ESTABLISH_TIME 3 #define MODEM_EMERGENCY_CALL_DISCONNECT_TIME 3 -#define RADIO_SERVICE_NAME "slot1" +#define RADIO_SERVICE_SLOT1_NAME "slot1" // HAL instance name for SIM slot 1 or single SIM device +#define RADIO_SERVICE_SLOT2_NAME "slot2" // HAL instance name for SIM slot 2 on dual SIM device +#define RADIO_SERVICE_SLOT3_NAME "slot3" // HAL instance name for SIM slot 3 on triple SIM device class RadioHidlTest_v1_6; extern ::android::hardware::radio::V1_5::CardStatus cardStatus; -- GitLab From 26c76353c44fbbde7312b748f3026a54ebdeee71 Mon Sep 17 00:00:00 2001 From: Yu-Han Yang Date: Tue, 11 May 2021 13:16:35 -0700 Subject: [PATCH 652/790] Detach thread so stop_measurement doesn't block Bug: 187361220 Test: atest android.location.cts.fine.LocationManagerFineTest.testRegisterGnssMeasurementsCallback --iterations=100 Change-Id: I02952c24cc5245375a75675e0a7fad02f1741e0d --- gnss/aidl/default/GnssMeasurementInterface.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/gnss/aidl/default/GnssMeasurementInterface.cpp b/gnss/aidl/default/GnssMeasurementInterface.cpp index cae9499077..a66bfc1864 100644 --- a/gnss/aidl/default/GnssMeasurementInterface.cpp +++ b/gnss/aidl/default/GnssMeasurementInterface.cpp @@ -69,6 +69,7 @@ void GnssMeasurementInterface::start(const bool enableCorrVecOutputs) { std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMillis)); } }); + mThread.detach(); } void GnssMeasurementInterface::stop() { -- GitLab From 0d591fd0a4580b34dc89e787ed3603cf1a934b9b Mon Sep 17 00:00:00 2001 From: Henry Fang Date: Thu, 13 May 2021 17:30:32 -0700 Subject: [PATCH 653/790] Add more configure items for DVBT bug: 182519645 Test: atest VtsHalTvTunerV1_0TargetTest Change-Id: I58bd8b941f6340d9e69153702b5269cc35c646da --- tv/tuner/config/TunerTestingConfigReaderV1_0.h | 11 +++++++++++ tv/tuner/config/api/current.txt | 18 ++++++++++++++++++ .../config/sample_tuner_vts_config_1_0.xml | 5 ++++- .../tuner_testing_dynamic_configuration.xsd | 13 +++++++++++-- 4 files changed, 44 insertions(+), 3 deletions(-) diff --git a/tv/tuner/config/TunerTestingConfigReaderV1_0.h b/tv/tuner/config/TunerTestingConfigReaderV1_0.h index 0688219575..d049b07232 100644 --- a/tv/tuner/config/TunerTestingConfigReaderV1_0.h +++ b/tv/tuner/config/TunerTestingConfigReaderV1_0.h @@ -52,6 +52,7 @@ using android::hardware::tv::tuner::V1_0::FrontendDvbtCoderate; using android::hardware::tv::tuner::V1_0::FrontendDvbtConstellation; using android::hardware::tv::tuner::V1_0::FrontendDvbtGuardInterval; using android::hardware::tv::tuner::V1_0::FrontendDvbtHierarchy; +using android::hardware::tv::tuner::V1_0::FrontendDvbtPlpMode; using android::hardware::tv::tuner::V1_0::FrontendDvbtSettings; using android::hardware::tv::tuner::V1_0::FrontendDvbtStandard; using android::hardware::tv::tuner::V1_0::FrontendDvbtTransmissionMode; @@ -593,6 +594,16 @@ struct TunerTestingConfigReader1_0 { } dvbtSettings.bandwidth = static_cast(dvbt->getBandwidth()); dvbtSettings.isHighPriority = dvbt->getIsHighPriority(); + dvbtSettings.hierarchy = static_cast(dvbt->getHierarchy()); + dvbtSettings.hpCoderate = static_cast(dvbt->getHpCoderate()); + dvbtSettings.lpCoderate = static_cast(dvbt->getLpCoderate()); + dvbtSettings.guardInterval = + static_cast(dvbt->getGuardInterval()); + dvbtSettings.standard = static_cast(dvbt->getStandard()); + dvbtSettings.isMiso = dvbt->getIsMiso(); + dvbtSettings.plpMode = static_cast(dvbt->getPlpMode()); + dvbtSettings.plpId = dvbt->getPlpId(); + dvbtSettings.plpGroupId = dvbt->getPlpGroupId(); if (dvbt->hasConstellation()) { dvbtSettings.constellation = static_cast(dvbt->getConstellation()); diff --git a/tv/tuner/config/api/current.txt b/tv/tuner/config/api/current.txt index ef733151b1..d026bf9e40 100644 --- a/tv/tuner/config/api/current.txt +++ b/tv/tuner/config/api/current.txt @@ -180,11 +180,29 @@ package android.media.tuner.testing.configuration.V1_0 { ctor public DvbtFrontendSettings(); method @Nullable public java.math.BigInteger getBandwidth(); method @Nullable public java.math.BigInteger getConstellation(); + method @Nullable public java.math.BigInteger getGuardInterval(); + method @Nullable public java.math.BigInteger getHierarchy(); + method @Nullable public java.math.BigInteger getHpCoderate(); method @Nullable public java.math.BigInteger getIsHighPriority(); + method @Nullable public java.math.BigInteger getIsMiso(); + method @Nullable public java.math.BigInteger getLpCoderate(); + method @Nullable public java.math.BigInteger getPlpGroupId(); + method @Nullable public java.math.BigInteger getPlpId(); + method @Nullable public java.math.BigInteger getPlpMode(); + method @Nullable public java.math.BigInteger getStandard(); method @Nullable public java.math.BigInteger getTransmissionMode(); method public void setBandwidth(@Nullable java.math.BigInteger); method public void setConstellation(@Nullable java.math.BigInteger); + method public void setGuardInterval(@Nullable java.math.BigInteger); + method public void setHierarchy(@Nullable java.math.BigInteger); + method public void setHpCoderate(@Nullable java.math.BigInteger); method public void setIsHighPriority(@Nullable java.math.BigInteger); + method public void setIsMiso(@Nullable java.math.BigInteger); + method public void setLpCoderate(@Nullable java.math.BigInteger); + method public void setPlpGroupId(@Nullable java.math.BigInteger); + method public void setPlpId(@Nullable java.math.BigInteger); + method public void setPlpMode(@Nullable java.math.BigInteger); + method public void setStandard(@Nullable java.math.BigInteger); method public void setTransmissionMode(@Nullable java.math.BigInteger); } diff --git a/tv/tuner/config/sample_tuner_vts_config_1_0.xml b/tv/tuner/config/sample_tuner_vts_config_1_0.xml index 26240765d6..347e98442b 100644 --- a/tv/tuner/config/sample_tuner_vts_config_1_0.xml +++ b/tv/tuner/config/sample_tuner_vts_config_1_0.xml @@ -54,7 +54,10 @@ - + diff --git a/tv/tuner/config/tuner_testing_dynamic_configuration.xsd b/tv/tuner/config/tuner_testing_dynamic_configuration.xsd index 52168374f7..6a04b7ebe1 100644 --- a/tv/tuner/config/tuner_testing_dynamic_configuration.xsd +++ b/tv/tuner/config/tuner_testing_dynamic_configuration.xsd @@ -61,9 +61,18 @@ - + + + + + - + + + + + + -- GitLab From 2eaf17e7674bb11f13ae166de0314f987802fe86 Mon Sep 17 00:00:00 2001 From: Henry Fang Date: Fri, 14 May 2021 10:53:57 -0700 Subject: [PATCH 654/790] Add timeout configure item and set it as 30m bug: 182519645 Test: atest VtsHalTvTunerV1_0TargetTest Change-Id: I82c4617ae4c9c3109b972b22984ca6db706c1e5d --- tv/tuner/1.0/vts/functional/AndroidTest.xml | 1 + tv/tuner/1.1/vts/functional/AndroidTest.xml | 1 + tv/tuner/1.1/vts/functional/FilterTests.cpp | 8 ++++++-- tv/tuner/1.1/vts/functional/FilterTests.h | 1 + .../1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp | 2 +- 5 files changed, 10 insertions(+), 3 deletions(-) diff --git a/tv/tuner/1.0/vts/functional/AndroidTest.xml b/tv/tuner/1.0/vts/functional/AndroidTest.xml index 3a2db27440..18c2b59093 100644 --- a/tv/tuner/1.0/vts/functional/AndroidTest.xml +++ b/tv/tuner/1.0/vts/functional/AndroidTest.xml @@ -30,5 +30,6 @@ + diff --git a/tv/tuner/1.1/vts/functional/AndroidTest.xml b/tv/tuner/1.1/vts/functional/AndroidTest.xml index 28f95db8a3..3e6878ce39 100644 --- a/tv/tuner/1.1/vts/functional/AndroidTest.xml +++ b/tv/tuner/1.1/vts/functional/AndroidTest.xml @@ -29,5 +29,6 @@ + diff --git a/tv/tuner/1.1/vts/functional/FilterTests.cpp b/tv/tuner/1.1/vts/functional/FilterTests.cpp index 3bcf32ac1d..4dff8533f3 100644 --- a/tv/tuner/1.1/vts/functional/FilterTests.cpp +++ b/tv/tuner/1.1/vts/functional/FilterTests.cpp @@ -306,8 +306,12 @@ AssertionResult FilterTests::configureMonitorEvent(uint64_t filterId, uint32_t m android::hardware::tv::tuner::V1_1::IFilter::castFrom(mFilters[filterId]); if (filter_v1_1 != NULL) { status = filter_v1_1->configureMonitorEvent(monitorEventTypes); - mFilterCallbacks[filterId]->testFilterScramblingEvent(); - mFilterCallbacks[filterId]->testFilterIpCidEvent(); + if (monitorEventTypes & DemuxFilterMonitorEventType::SCRAMBLING_STATUS) { + mFilterCallbacks[filterId]->testFilterScramblingEvent(); + } + if (monitorEventTypes & DemuxFilterMonitorEventType::IP_CID_CHANGE) { + mFilterCallbacks[filterId]->testFilterIpCidEvent(); + } } else { ALOGW("[vts] Can't cast IFilter into v1_1."); return failure(); diff --git a/tv/tuner/1.1/vts/functional/FilterTests.h b/tv/tuner/1.1/vts/functional/FilterTests.h index 59611fa7ae..72c8129f4a 100644 --- a/tv/tuner/1.1/vts/functional/FilterTests.h +++ b/tv/tuner/1.1/vts/functional/FilterTests.h @@ -57,6 +57,7 @@ using android::hardware::tv::tuner::V1_0::Result; using android::hardware::tv::tuner::V1_1::AvStreamType; using android::hardware::tv::tuner::V1_1::DemuxFilterEventExt; using android::hardware::tv::tuner::V1_1::DemuxFilterMonitorEvent; +using android::hardware::tv::tuner::V1_1::DemuxFilterMonitorEventType; using android::hardware::tv::tuner::V1_1::IFilterCallback; using android::hardware::tv::tuner::V1_1::ITuner; diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp index e70c320bf2..1a9def83b1 100644 --- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp @@ -112,8 +112,8 @@ void TunerBroadcastHidlTest::mediaFilterUsingSharedMemoryTest(FilterConfig1_1 fi ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.config1_0.type, filterConf.config1_0.bufferSize)); ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(filterId)); - ASSERT_TRUE(mFilterTests.getSharedAvMemoryHandle(filterId)); ASSERT_TRUE(mFilterTests.configFilter(filterConf.config1_0.settings, filterId)); + ASSERT_TRUE(mFilterTests.getSharedAvMemoryHandle(filterId)); ASSERT_TRUE(mFilterTests.configAvFilterStreamType(filterConf.streamType, filterId)); ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterConf.config1_0.getMqDesc)); ASSERT_TRUE(mFilterTests.startFilter(filterId)); -- GitLab From 879b3c0809534294d93768861e0f09e1f76fa4a6 Mon Sep 17 00:00:00 2001 From: Jack Yu Date: Thu, 13 May 2021 16:21:11 -0700 Subject: [PATCH 655/790] Fixed the obsolete VTS owners Fix: 188209583 Test: None Change-Id: I783cdedaad088ec1c52c2edfbea08f83c9b7a432 --- radio/1.0/vts/OWNERS | 5 ++--- radio/1.1/vts/OWNERS | 9 +-------- radio/1.2/vts/OWNERS | 10 +--------- radio/1.3/vts/OWNERS | 11 +---------- radio/1.4/vts/OWNERS | 9 +-------- radio/1.5/vts/OWNERS | 11 +---------- radio/1.6/vts/OWNERS | 11 +---------- 7 files changed, 8 insertions(+), 58 deletions(-) diff --git a/radio/1.0/vts/OWNERS b/radio/1.0/vts/OWNERS index 2384317995..9310f8e19b 100644 --- a/radio/1.0/vts/OWNERS +++ b/radio/1.0/vts/OWNERS @@ -1,8 +1,7 @@ # Telephony team amitmahajan@google.com -sanketpadawe@google.com shuoq@google.com +jackyu@google.com # VTS team -yuexima@google.com -yim@google.com +dshi@google.com diff --git a/radio/1.1/vts/OWNERS b/radio/1.1/vts/OWNERS index 2384317995..a07c91779e 100644 --- a/radio/1.1/vts/OWNERS +++ b/radio/1.1/vts/OWNERS @@ -1,8 +1 @@ -# Telephony team -amitmahajan@google.com -sanketpadawe@google.com -shuoq@google.com - -# VTS team -yuexima@google.com -yim@google.com +include ../../1.0/vts/OWNERS diff --git a/radio/1.2/vts/OWNERS b/radio/1.2/vts/OWNERS index 245d9d4771..a07c91779e 100644 --- a/radio/1.2/vts/OWNERS +++ b/radio/1.2/vts/OWNERS @@ -1,9 +1 @@ -# Telephony team -amitmahajan@google.com -sanketpadawe@google.com -shuoq@google.com -sasindran@google.com - -# VTS team -yuexima@google.com -yim@google.com +include ../../1.0/vts/OWNERS diff --git a/radio/1.3/vts/OWNERS b/radio/1.3/vts/OWNERS index d64206467a..a07c91779e 100644 --- a/radio/1.3/vts/OWNERS +++ b/radio/1.3/vts/OWNERS @@ -1,10 +1 @@ -# Telephony team -amitmahajan@google.com -sanketpadawe@google.com -shuoq@google.com -sasindran@google.com -nazaninb@google.com - -# VTS team -yuexima@google.com -yim@google.com +include ../../1.0/vts/OWNERS diff --git a/radio/1.4/vts/OWNERS b/radio/1.4/vts/OWNERS index fd69f361ed..a07c91779e 100644 --- a/radio/1.4/vts/OWNERS +++ b/radio/1.4/vts/OWNERS @@ -1,8 +1 @@ -# Telephony team -amitmahajan@google.com -shuoq@google.com -sasindran@google.com - -# VTS team -yuexima@google.com -yim@google.com \ No newline at end of file +include ../../1.0/vts/OWNERS diff --git a/radio/1.5/vts/OWNERS b/radio/1.5/vts/OWNERS index 3629a6c1f4..a07c91779e 100644 --- a/radio/1.5/vts/OWNERS +++ b/radio/1.5/vts/OWNERS @@ -1,10 +1 @@ -# Telephony team -refuhoo@google.com -amitmahajan@google.com -jackyu@google.com -fionaxu@google.com -# more to add - -# VTS team -yuexima@google.com -dshi@google.com \ No newline at end of file +include ../../1.0/vts/OWNERS diff --git a/radio/1.6/vts/OWNERS b/radio/1.6/vts/OWNERS index 3629a6c1f4..a07c91779e 100644 --- a/radio/1.6/vts/OWNERS +++ b/radio/1.6/vts/OWNERS @@ -1,10 +1 @@ -# Telephony team -refuhoo@google.com -amitmahajan@google.com -jackyu@google.com -fionaxu@google.com -# more to add - -# VTS team -yuexima@google.com -dshi@google.com \ No newline at end of file +include ../../1.0/vts/OWNERS -- GitLab From 945c430d1912321e04f88e83d78cebe90b31fb5d Mon Sep 17 00:00:00 2001 From: Hao Chen Date: Wed, 12 May 2021 12:21:33 -0700 Subject: [PATCH 656/790] Use PropStore on the Server Side to Simulate ECU Test: build and unit tests Bug: 188005769 Change-Id: I5aff41acbc4795def84ceb8e363019ff9668120c --- automotive/vehicle/2.0/default/Android.bp | 1 + .../include/vhal_v2_0/VehiclePropertyStore.h | 3 +- .../impl/vhal_v2_0/VehicleHalServer.cpp | 63 ++++++++++++++++--- .../default/impl/vhal_v2_0/VehicleHalServer.h | 4 ++ 4 files changed, 62 insertions(+), 9 deletions(-) diff --git a/automotive/vehicle/2.0/default/Android.bp b/automotive/vehicle/2.0/default/Android.bp index 21c1a6e854..ffa0c13958 100644 --- a/automotive/vehicle/2.0/default/Android.bp +++ b/automotive/vehicle/2.0/default/Android.bp @@ -134,6 +134,7 @@ cc_library_static { srcs: [ "common/src/Obd2SensorStore.cpp", "common/src/VehicleObjectPool.cpp", + "common/src/VehiclePropertyStore.cpp", "common/src/VehicleUtils.cpp", ], } diff --git a/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehiclePropertyStore.h b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehiclePropertyStore.h index 0a243fe352..6a02cf3cab 100644 --- a/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehiclePropertyStore.h +++ b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehiclePropertyStore.h @@ -19,10 +19,11 @@ #include #include +#include #include #include -#include +#include namespace android { namespace hardware { diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.cpp index 6b870527c3..1e468975a2 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.cpp +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.cpp @@ -30,6 +30,58 @@ namespace android::hardware::automotive::vehicle::V2_0::impl { +static bool isDiagnosticProperty(VehiclePropConfig propConfig) { + switch (propConfig.prop) { + case OBD2_LIVE_FRAME: + case OBD2_FREEZE_FRAME: + case OBD2_FREEZE_FRAME_CLEAR: + case OBD2_FREEZE_FRAME_INFO: + return true; + } + return false; +} + +VehicleHalServer::VehicleHalServer() { + constexpr bool shouldUpdateStatus = true; + + for (auto& it : kVehicleProperties) { + VehiclePropConfig cfg = it.config; + + mServerSidePropStore.registerProperty(cfg); + + if (isDiagnosticProperty(cfg)) { + continue; + } + + // A global property will have only a single area + int32_t numAreas = isGlobalProp(cfg.prop) ? 1 : cfg.areaConfigs.size(); + + for (int i = 0; i < numAreas; i++) { + int32_t curArea = isGlobalProp(cfg.prop) ? 0 : cfg.areaConfigs[i].areaId; + + // Create a separate instance for each individual zone + VehiclePropValue prop = { + .areaId = curArea, + .prop = cfg.prop, + }; + + if (it.initialAreaValues.empty()) { + prop.value = it.initialValue; + } else if (auto valueForAreaIt = it.initialAreaValues.find(curArea); + valueForAreaIt != it.initialAreaValues.end()) { + prop.value = valueForAreaIt->second; + } else { + LOG(WARNING) << __func__ << " failed to get default value for" + << " prop 0x" << std::hex << cfg.prop << " area 0x" << std::hex + << curArea; + prop.status = VehiclePropertyStatus::UNAVAILABLE; + } + + mServerSidePropStore.writeValue(prop, shouldUpdateStatus); + } + } +} + GeneratorHub* VehicleHalServer::getGenerator() { return &mGeneratorHub; } @@ -55,19 +107,13 @@ void VehicleHalServer::onFakeValueGenerated(const VehiclePropValue& value) { if (updatedPropValue) { updatedPropValue->timestamp = value.timestamp; updatedPropValue->status = VehiclePropertyStatus::AVAILABLE; + mServerSidePropStore.writeValue(*updatedPropValue, updateStatus); onPropertyValueFromCar(*updatedPropValue, updateStatus); } } std::vector VehicleHalServer::onGetAllPropertyConfig() const { - std::vector vehiclePropConfigs; - constexpr size_t numOfVehiclePropConfigs = - sizeof(kVehicleProperties) / sizeof(kVehicleProperties[0]); - vehiclePropConfigs.reserve(numOfVehiclePropConfigs); - for (auto& it : kVehicleProperties) { - vehiclePropConfigs.emplace_back(it.config); - } - return vehiclePropConfigs; + return mServerSidePropStore.getAllConfigs(); } StatusCode VehicleHalServer::handleGenerateFakeDataRequest(const VehiclePropValue& request) { @@ -278,6 +324,7 @@ StatusCode VehicleHalServer::onSetProperty(const VehiclePropValue& value, bool u auto updatedPropValue = getValuePool()->obtain(value); updatedPropValue->timestamp = elapsedRealtimeNano(); + mServerSidePropStore.writeValue(*updatedPropValue, updateStatus); onPropertyValueFromCar(*updatedPropValue, updateStatus); return StatusCode::OK; } diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.h index 117eadb1e2..2ad75e368a 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.h +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.h @@ -17,6 +17,7 @@ #pragma once #include +#include #include #include "GeneratorHub.h" @@ -28,6 +29,8 @@ namespace android::hardware::automotive::vehicle::V2_0::impl { // scenario, the server may be run on a different OS than Android. class VehicleHalServer : public IVehicleServer { public: + VehicleHalServer(); + // Methods from IVehicleServer std::vector onGetAllPropertyConfig() const override; @@ -58,6 +61,7 @@ class VehicleHalServer : public IVehicleServer { std::bind(&VehicleHalServer::onFakeValueGenerated, this, std::placeholders::_1)}; VehiclePropValuePool* mValuePool{nullptr}; + VehiclePropertyStore mServerSidePropStore; }; } // namespace android::hardware::automotive::vehicle::V2_0::impl -- GitLab From f2654a4c73eb56e958effa50877c2b5828b9c960 Mon Sep 17 00:00:00 2001 From: Hao Chen Date: Wed, 12 May 2021 14:24:52 -0700 Subject: [PATCH 657/790] Split the utility parts out of DefaultConfig.h So that the client side may use the utilities without introducing the "default configs". "default configs" should only be visible to the server, and the vehicle hal server will take care of configs. Test: build and unit tests Bug: 188005769 Change-Id: If418dcdd1c5b261179104bb414c52f3eb04d3ea8 --- .../default/impl/vhal_v2_0/DefaultConfig.h | 176 +--------------- .../default/impl/vhal_v2_0/PropertyUtils.h | 197 ++++++++++++++++++ 2 files changed, 198 insertions(+), 175 deletions(-) create mode 100644 automotive/vehicle/2.0/default/impl/vhal_v2_0/PropertyUtils.h diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h index 81f31987e0..1f3bac1a8a 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h @@ -17,8 +17,7 @@ #ifndef android_hardware_automotive_vehicle_V2_0_impl_DefaultConfig_H_ #define android_hardware_automotive_vehicle_V2_0_impl_DefaultConfig_H_ -#include -#include +#include "PropertyUtils.h" #include @@ -29,179 +28,6 @@ namespace vehicle { namespace V2_0 { namespace impl { -// -// Some handy constants to avoid conversions from enum to int. -constexpr int ABS_ACTIVE = (int)VehicleProperty::ABS_ACTIVE; -constexpr int AP_POWER_STATE_REQ = (int)VehicleProperty::AP_POWER_STATE_REQ; -constexpr int AP_POWER_STATE_REPORT = (int)VehicleProperty::AP_POWER_STATE_REPORT; -constexpr int DOOR_1_LEFT = (int)VehicleAreaDoor::ROW_1_LEFT; -constexpr int DOOR_1_RIGHT = (int)VehicleAreaDoor::ROW_1_RIGHT; -constexpr int DOOR_2_LEFT = (int)VehicleAreaDoor::ROW_2_LEFT; -constexpr int DOOR_2_RIGHT = (int)VehicleAreaDoor::ROW_2_RIGHT; -constexpr int DOOR_REAR = (int)VehicleAreaDoor::REAR; -constexpr int WINDOW_1_LEFT = (int)VehicleAreaWindow::ROW_1_LEFT; -constexpr int WINDOW_1_RIGHT = (int)VehicleAreaWindow::ROW_1_RIGHT; -constexpr int WINDOW_2_LEFT = (int)VehicleAreaWindow::ROW_2_LEFT; -constexpr int WINDOW_2_RIGHT = (int)VehicleAreaWindow::ROW_2_RIGHT; -constexpr int WINDOW_ROOF_TOP_1 = (int)VehicleAreaWindow::ROOF_TOP_1; -constexpr int FAN_DIRECTION_FACE = (int)VehicleHvacFanDirection::FACE; -constexpr int FAN_DIRECTION_FLOOR = (int)VehicleHvacFanDirection::FLOOR; -constexpr int OBD2_LIVE_FRAME = (int)VehicleProperty::OBD2_LIVE_FRAME; -constexpr int OBD2_FREEZE_FRAME = (int)VehicleProperty::OBD2_FREEZE_FRAME; -constexpr int OBD2_FREEZE_FRAME_INFO = (int)VehicleProperty::OBD2_FREEZE_FRAME_INFO; -constexpr int OBD2_FREEZE_FRAME_CLEAR = (int)VehicleProperty::OBD2_FREEZE_FRAME_CLEAR; -constexpr int TRACTION_CONTROL_ACTIVE = (int)VehicleProperty::TRACTION_CONTROL_ACTIVE; -constexpr int VEHICLE_MAP_SERVICE = (int)VehicleProperty::VEHICLE_MAP_SERVICE; -constexpr int WHEEL_TICK = (int)VehicleProperty::WHEEL_TICK; -constexpr int ALL_WHEELS = - (int)(VehicleAreaWheel::LEFT_FRONT | VehicleAreaWheel::RIGHT_FRONT | - VehicleAreaWheel::LEFT_REAR | VehicleAreaWheel::RIGHT_REAR); -constexpr int SEAT_1_LEFT = (int)(VehicleAreaSeat::ROW_1_LEFT); -constexpr int SEAT_1_RIGHT = (int)(VehicleAreaSeat::ROW_1_RIGHT); -constexpr int HVAC_LEFT = (int)(VehicleAreaSeat::ROW_1_LEFT | VehicleAreaSeat::ROW_2_LEFT | - VehicleAreaSeat::ROW_2_CENTER); -constexpr int HVAC_RIGHT = (int)(VehicleAreaSeat::ROW_1_RIGHT | VehicleAreaSeat::ROW_2_RIGHT); -constexpr int HVAC_ALL = HVAC_LEFT | HVAC_RIGHT; -constexpr int VENDOR_EXTENSION_BOOLEAN_PROPERTY = - (int)(0x101 | VehiclePropertyGroup::VENDOR | VehiclePropertyType::BOOLEAN | VehicleArea::DOOR); -constexpr int VENDOR_EXTENSION_FLOAT_PROPERTY = - (int)(0x102 | VehiclePropertyGroup::VENDOR | VehiclePropertyType::FLOAT | VehicleArea::SEAT); -constexpr int VENDOR_EXTENSION_INT_PROPERTY = - (int)(0x103 | VehiclePropertyGroup::VENDOR | VehiclePropertyType::INT32 | VehicleArea::WINDOW); -constexpr int VENDOR_EXTENSION_STRING_PROPERTY = - (int)(0x104 | VehiclePropertyGroup::VENDOR | VehiclePropertyType::STRING | VehicleArea::GLOBAL); -constexpr int FUEL_DOOR_REAR_LEFT = (int)PortLocationType::REAR_LEFT; -constexpr int CHARGE_PORT_FRONT_LEFT = (int)PortLocationType::FRONT_LEFT; -constexpr int CHARGE_PORT_REAR_LEFT = (int)PortLocationType::REAR_LEFT; -constexpr int LIGHT_STATE_ON = (int)VehicleLightState::ON; -constexpr int LIGHT_SWITCH_AUTO = (int)VehicleLightSwitch::AUTOMATIC; -constexpr int WHEEL_FRONT_LEFT = (int)VehicleAreaWheel::LEFT_FRONT; -constexpr int WHEEL_FRONT_RIGHT = (int)VehicleAreaWheel::RIGHT_FRONT; -constexpr int WHEEL_REAR_LEFT = (int)VehicleAreaWheel::LEFT_REAR; -constexpr int WHEEL_REAR_RIGHT = (int)VehicleAreaWheel::RIGHT_REAR; - -/** - * This property is used for test purpose to generate fake events. Here is the test package that - * is referencing this property definition: packages/services/Car/tests/vehiclehal_test - */ -const int32_t kGenerateFakeDataControllingProperty = - 0x0666 | VehiclePropertyGroup::VENDOR | VehicleArea::GLOBAL | VehiclePropertyType::MIXED; - -/** - * This property is used for test purpose to set properties' value from vehicle. - * For example: Mocking hard button press triggering a HVAC fan speed change. - * Android set kSetPropertyFromVehicleForTest with an array of integer {HVAC_FAN_SPEED, value of - * fan speed} and a long value indicates the timestamp of the events . - * It only works with integer type properties. - */ -const int32_t kSetIntPropertyFromVehicleForTest = - 0x1112 | VehiclePropertyGroup::VENDOR | VehicleArea::GLOBAL | VehiclePropertyType::MIXED; -/** - * This property is used for test purpose to set properties' value from vehicle. - * It only works with float type properties. - */ -const int32_t kSetFloatPropertyFromVehicleForTest = - 0x1113 | VehiclePropertyGroup::VENDOR | VehicleArea::GLOBAL | VehiclePropertyType::MIXED; -/** - * This property is used for test purpose to set properties' value from vehicle. - * It only works with boolean type properties. - */ -const int32_t kSetBooleanPropertyFromVehicleForTest = - 0x1114 | VehiclePropertyGroup::VENDOR | VehicleArea::GLOBAL | VehiclePropertyType::MIXED; - -/** - * This property is used for test purpose. End to end tests use this property to test set and get - * method for MIXED type properties. - */ -const int32_t kMixedTypePropertyForTest = - 0x1111 | VehiclePropertyGroup::VENDOR | VehicleArea::GLOBAL | VehiclePropertyType::MIXED; - -#ifdef ENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING -/** - * Converts the system property to the vendor property. - * WARNING: This is only for the end-to-end testing, Should NOT include in the - * user build */ -inline constexpr int32_t toVendor(VehicleProperty prop) { - return (toInt(prop) & ~toInt(VehiclePropertyGroup::MASK)) | VehiclePropertyGroup::VENDOR; -} - -/** - * These properties are used for the end-to-end testing of ClusterHomeService. - */ -constexpr int32_t VENDOR_CLUSTER_SWITCH_UI = toVendor(VehicleProperty::CLUSTER_SWITCH_UI); -constexpr int32_t VENDOR_CLUSTER_DISPLAY_STATE = toVendor(VehicleProperty::CLUSTER_DISPLAY_STATE); -constexpr int32_t VENDOR_CLUSTER_REPORT_STATE = toVendor(VehicleProperty::CLUSTER_REPORT_STATE); -constexpr int32_t VENDOR_CLUSTER_REQUEST_DISPLAY = - toVendor(VehicleProperty::CLUSTER_REQUEST_DISPLAY); -constexpr int32_t VENDOR_CLUSTER_NAVIGATION_STATE = - toVendor(VehicleProperty::CLUSTER_NAVIGATION_STATE); -#endif // ENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING - -/** - * FakeDataCommand enum defines the supported command type for kGenerateFakeDataControllingProperty. - * All those commands can be send independently with each other. And each will override the one sent - * previously. - * - * The controlling property has the following format: - * - * int32Values[0] - command enum defined in FakeDataCommand - * - * The format of the arguments is defined for each command type as below: - */ -enum class FakeDataCommand : int32_t { - /** - * Starts linear fake data generation. Caller must provide additional data: - * int32Values[1] - vehicle property to which command applies - * int64Values[0] - periodic interval in nanoseconds - * floatValues[0] - initial value - * floatValues[1] - dispersion defines the min/max value relative to initial value, where - * max = initial_value + dispersion, min = initial_value - dispersion. - * Dispersion should be non-negative, otherwise the behavior is undefined. - * floatValues[2] - increment, with every timer tick the value will be incremented by this - * amount. When reaching to max value, the current value will be set to - * min. It should be non-negative, otherwise the behavior is undefined. - */ - StartLinear = 0, - - /** Stops linear fake data generation that was triggered by StartLinear commands. - * int32Values[1] - vehicle property to which command applies. VHAL will stop the - * corresponding linear generation for that property. - */ - StopLinear = 1, - - /** - * Starts JSON-based fake data generation. It iterates through JSON-encoded VHAL events from a - * file and inject them to VHAL. The iteration can be repeated multiple times or infinitely. - * Caller must provide additional data: - * int32Values[1] - number of iterations. If it is not provided or -1. The iteration will be - * repeated infinite times. - * stringValue - path to the fake values JSON file - */ - StartJson = 2, - - /** - * Stops JSON-based fake data generation. As multiple JSON-based generation can happen at the - * same time. Caller must provide the path of fake value JSON file to stop the corresponding - * generation: - * stringValue - path to the fake values JSON file - */ - StopJson = 3, - - /** - * Injects key press event (HAL incorporates UP/DOWN acction and triggers 2 HAL events for every - * key-press). We set the enum with high number to leave space for future start/stop commands. - * Caller must provide the following data: - * int32Values[2] - Android key code - * int32Values[3] - target display (0 - for main display, 1 - for instrument cluster, see - * VehicleDisplay) - */ - KeyPress = 100, -}; - -const int32_t kHvacPowerProperties[] = { - toInt(VehicleProperty::HVAC_FAN_SPEED), - toInt(VehicleProperty::HVAC_FAN_DIRECTION), -}; struct ConfigDeclaration { VehiclePropConfig config; diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/PropertyUtils.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/PropertyUtils.h new file mode 100644 index 0000000000..d5f6a1841e --- /dev/null +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/PropertyUtils.h @@ -0,0 +1,197 @@ +/* + * 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 +#include + +namespace android::hardware::automotive::vehicle::V2_0::impl { + +// Some handy constants to avoid conversions from enum to int. +constexpr int ABS_ACTIVE = (int)VehicleProperty::ABS_ACTIVE; +constexpr int AP_POWER_STATE_REQ = (int)VehicleProperty::AP_POWER_STATE_REQ; +constexpr int AP_POWER_STATE_REPORT = (int)VehicleProperty::AP_POWER_STATE_REPORT; +constexpr int DOOR_1_LEFT = (int)VehicleAreaDoor::ROW_1_LEFT; +constexpr int DOOR_1_RIGHT = (int)VehicleAreaDoor::ROW_1_RIGHT; +constexpr int DOOR_2_LEFT = (int)VehicleAreaDoor::ROW_2_LEFT; +constexpr int DOOR_2_RIGHT = (int)VehicleAreaDoor::ROW_2_RIGHT; +constexpr int DOOR_REAR = (int)VehicleAreaDoor::REAR; +constexpr int WINDOW_1_LEFT = (int)VehicleAreaWindow::ROW_1_LEFT; +constexpr int WINDOW_1_RIGHT = (int)VehicleAreaWindow::ROW_1_RIGHT; +constexpr int WINDOW_2_LEFT = (int)VehicleAreaWindow::ROW_2_LEFT; +constexpr int WINDOW_2_RIGHT = (int)VehicleAreaWindow::ROW_2_RIGHT; +constexpr int WINDOW_ROOF_TOP_1 = (int)VehicleAreaWindow::ROOF_TOP_1; +constexpr int FAN_DIRECTION_FACE = (int)VehicleHvacFanDirection::FACE; +constexpr int FAN_DIRECTION_FLOOR = (int)VehicleHvacFanDirection::FLOOR; +constexpr int OBD2_LIVE_FRAME = (int)VehicleProperty::OBD2_LIVE_FRAME; +constexpr int OBD2_FREEZE_FRAME = (int)VehicleProperty::OBD2_FREEZE_FRAME; +constexpr int OBD2_FREEZE_FRAME_INFO = (int)VehicleProperty::OBD2_FREEZE_FRAME_INFO; +constexpr int OBD2_FREEZE_FRAME_CLEAR = (int)VehicleProperty::OBD2_FREEZE_FRAME_CLEAR; +constexpr int TRACTION_CONTROL_ACTIVE = (int)VehicleProperty::TRACTION_CONTROL_ACTIVE; +constexpr int VEHICLE_MAP_SERVICE = (int)VehicleProperty::VEHICLE_MAP_SERVICE; +constexpr int WHEEL_TICK = (int)VehicleProperty::WHEEL_TICK; +constexpr int ALL_WHEELS = + (int)(VehicleAreaWheel::LEFT_FRONT | VehicleAreaWheel::RIGHT_FRONT | + VehicleAreaWheel::LEFT_REAR | VehicleAreaWheel::RIGHT_REAR); +constexpr int SEAT_1_LEFT = (int)(VehicleAreaSeat::ROW_1_LEFT); +constexpr int SEAT_1_RIGHT = (int)(VehicleAreaSeat::ROW_1_RIGHT); +constexpr int HVAC_LEFT = (int)(VehicleAreaSeat::ROW_1_LEFT | VehicleAreaSeat::ROW_2_LEFT | + VehicleAreaSeat::ROW_2_CENTER); +constexpr int HVAC_RIGHT = (int)(VehicleAreaSeat::ROW_1_RIGHT | VehicleAreaSeat::ROW_2_RIGHT); +constexpr int HVAC_ALL = HVAC_LEFT | HVAC_RIGHT; +constexpr int VENDOR_EXTENSION_BOOLEAN_PROPERTY = + (int)(0x101 | VehiclePropertyGroup::VENDOR | VehiclePropertyType::BOOLEAN | VehicleArea::DOOR); +constexpr int VENDOR_EXTENSION_FLOAT_PROPERTY = + (int)(0x102 | VehiclePropertyGroup::VENDOR | VehiclePropertyType::FLOAT | VehicleArea::SEAT); +constexpr int VENDOR_EXTENSION_INT_PROPERTY = + (int)(0x103 | VehiclePropertyGroup::VENDOR | VehiclePropertyType::INT32 | VehicleArea::WINDOW); +constexpr int VENDOR_EXTENSION_STRING_PROPERTY = + (int)(0x104 | VehiclePropertyGroup::VENDOR | VehiclePropertyType::STRING | VehicleArea::GLOBAL); +constexpr int FUEL_DOOR_REAR_LEFT = (int)PortLocationType::REAR_LEFT; +constexpr int CHARGE_PORT_FRONT_LEFT = (int)PortLocationType::FRONT_LEFT; +constexpr int CHARGE_PORT_REAR_LEFT = (int)PortLocationType::REAR_LEFT; +constexpr int LIGHT_STATE_ON = (int)VehicleLightState::ON; +constexpr int LIGHT_SWITCH_AUTO = (int)VehicleLightSwitch::AUTOMATIC; +constexpr int WHEEL_FRONT_LEFT = (int)VehicleAreaWheel::LEFT_FRONT; +constexpr int WHEEL_FRONT_RIGHT = (int)VehicleAreaWheel::RIGHT_FRONT; +constexpr int WHEEL_REAR_LEFT = (int)VehicleAreaWheel::LEFT_REAR; +constexpr int WHEEL_REAR_RIGHT = (int)VehicleAreaWheel::RIGHT_REAR; + +/** + * This property is used for test purpose to generate fake events. Here is the test package that + * is referencing this property definition: packages/services/Car/tests/vehiclehal_test + */ +const int32_t kGenerateFakeDataControllingProperty = + 0x0666 | VehiclePropertyGroup::VENDOR | VehicleArea::GLOBAL | VehiclePropertyType::MIXED; + +/** + * This property is used for test purpose to set properties' value from vehicle. + * For example: Mocking hard button press triggering a HVAC fan speed change. + * Android set kSetPropertyFromVehicleForTest with an array of integer {HVAC_FAN_SPEED, value of + * fan speed} and a long value indicates the timestamp of the events . + * It only works with integer type properties. + */ +const int32_t kSetIntPropertyFromVehicleForTest = + 0x1112 | VehiclePropertyGroup::VENDOR | VehicleArea::GLOBAL | VehiclePropertyType::MIXED; +/** + * This property is used for test purpose to set properties' value from vehicle. + * It only works with float type properties. + */ +const int32_t kSetFloatPropertyFromVehicleForTest = + 0x1113 | VehiclePropertyGroup::VENDOR | VehicleArea::GLOBAL | VehiclePropertyType::MIXED; +/** + * This property is used for test purpose to set properties' value from vehicle. + * It only works with boolean type properties. + */ +const int32_t kSetBooleanPropertyFromVehicleForTest = + 0x1114 | VehiclePropertyGroup::VENDOR | VehicleArea::GLOBAL | VehiclePropertyType::MIXED; + +/** + * This property is used for test purpose. End to end tests use this property to test set and get + * method for MIXED type properties. + */ +const int32_t kMixedTypePropertyForTest = + 0x1111 | VehiclePropertyGroup::VENDOR | VehicleArea::GLOBAL | VehiclePropertyType::MIXED; + +#ifdef ENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING +/** + * Converts the system property to the vendor property. + * WARNING: This is only for the end-to-end testing, Should NOT include in the + * user build */ +inline constexpr int32_t toVendor(VehicleProperty prop) { + return (toInt(prop) & ~toInt(VehiclePropertyGroup::MASK)) | VehiclePropertyGroup::VENDOR; +} + +/** + * These properties are used for the end-to-end testing of ClusterHomeService. + */ +constexpr int32_t VENDOR_CLUSTER_SWITCH_UI = toVendor(VehicleProperty::CLUSTER_SWITCH_UI); +constexpr int32_t VENDOR_CLUSTER_DISPLAY_STATE = toVendor(VehicleProperty::CLUSTER_DISPLAY_STATE); +constexpr int32_t VENDOR_CLUSTER_REPORT_STATE = toVendor(VehicleProperty::CLUSTER_REPORT_STATE); +constexpr int32_t VENDOR_CLUSTER_REQUEST_DISPLAY = + toVendor(VehicleProperty::CLUSTER_REQUEST_DISPLAY); +constexpr int32_t VENDOR_CLUSTER_NAVIGATION_STATE = + toVendor(VehicleProperty::CLUSTER_NAVIGATION_STATE); +#endif // ENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING + +/** + * FakeDataCommand enum defines the supported command type for kGenerateFakeDataControllingProperty. + * All those commands can be send independently with each other. And each will override the one sent + * previously. + * + * The controlling property has the following format: + * + * int32Values[0] - command enum defined in FakeDataCommand + * + * The format of the arguments is defined for each command type as below: + */ +enum class FakeDataCommand : int32_t { + /** + * Starts linear fake data generation. Caller must provide additional data: + * int32Values[1] - vehicle property to which command applies + * int64Values[0] - periodic interval in nanoseconds + * floatValues[0] - initial value + * floatValues[1] - dispersion defines the min/max value relative to initial value, where + * max = initial_value + dispersion, min = initial_value - dispersion. + * Dispersion should be non-negative, otherwise the behavior is undefined. + * floatValues[2] - increment, with every timer tick the value will be incremented by this + * amount. When reaching to max value, the current value will be set to + * min. It should be non-negative, otherwise the behavior is undefined. + */ + StartLinear = 0, + + /** Stops linear fake data generation that was triggered by StartLinear commands. + * int32Values[1] - vehicle property to which command applies. VHAL will stop the + * corresponding linear generation for that property. + */ + StopLinear = 1, + + /** + * Starts JSON-based fake data generation. It iterates through JSON-encoded VHAL events from a + * file and inject them to VHAL. The iteration can be repeated multiple times or infinitely. + * Caller must provide additional data: + * int32Values[1] - number of iterations. If it is not provided or -1. The iteration will be + * repeated infinite times. + * stringValue - path to the fake values JSON file + */ + StartJson = 2, + + /** + * Stops JSON-based fake data generation. As multiple JSON-based generation can happen at the + * same time. Caller must provide the path of fake value JSON file to stop the corresponding + * generation: + * stringValue - path to the fake values JSON file + */ + StopJson = 3, + + /** + * Injects key press event (HAL incorporates UP/DOWN acction and triggers 2 HAL events for every + * key-press). We set the enum with high number to leave space for future start/stop commands. + * Caller must provide the following data: + * int32Values[2] - Android key code + * int32Values[3] - target display (0 - for main display, 1 - for instrument cluster, see + * VehicleDisplay) + */ + KeyPress = 100, +}; + +const int32_t kHvacPowerProperties[] = { + toInt(VehicleProperty::HVAC_FAN_SPEED), + toInt(VehicleProperty::HVAC_FAN_DIRECTION), +}; + +} // namespace android::hardware::automotive::vehicle::V2_0::impl -- GitLab From d2e8b5fdb24cb00d3aaa513c6c1472716d044599 Mon Sep 17 00:00:00 2001 From: Hao Chen Date: Wed, 12 May 2021 20:55:22 -0700 Subject: [PATCH 658/790] Remove duplicates in DefaultConfig.h Test: build and unit tests Bug: 188005769 Change-Id: I5c55bae2f54725542ac56ebd04ba58de6af63d9e --- .../vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h | 8 -------- 1 file changed, 8 deletions(-) diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h index 1f3bac1a8a..19a299569f 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h @@ -73,14 +73,6 @@ const ConfigDeclaration kVehicleProperties[]{ }, .initialValue = {.int32Values = {(int)EvConnectorType::IEC_TYPE_1_AC}}}, - {.config = - { - .prop = toInt(VehicleProperty::INFO_DRIVER_SEAT), - .access = VehiclePropertyAccess::READ, - .changeMode = VehiclePropertyChangeMode::STATIC, - }, - .initialValue = {.int32Values = {SEAT_1_LEFT}}}, - {.config = { .prop = toInt(VehicleProperty::INFO_FUEL_DOOR_LOCATION), -- GitLab From 3be21ccf01766b9f05b4078dd510defe6736d6ec Mon Sep 17 00:00:00 2001 From: Kai Wang Date: Fri, 14 May 2021 23:44:10 +0000 Subject: [PATCH 659/790] Rename Unix_time property to EPOCH_TIME Bug: 188227292 Test: build and flash with google VHAL check property from KitchenSink Change-Id: I7dc1833a000949f246a1a8be6f87970a1478832b --- automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h | 2 +- automotive/vehicle/2.0/types.hal | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h index abf33a3f46..e234aa9fdd 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h @@ -1201,7 +1201,7 @@ const ConfigDeclaration kVehicleProperties[]{ { .config = { - .prop = toInt(VehicleProperty::UNIX_TIME), + .prop = toInt(VehicleProperty::EPOCH_TIME), .access = VehiclePropertyAccess::READ_WRITE, .changeMode = VehiclePropertyChangeMode::ON_CHANGE, }, diff --git a/automotive/vehicle/2.0/types.hal b/automotive/vehicle/2.0/types.hal index e22f9fa5bd..6bfda32983 100644 --- a/automotive/vehicle/2.0/types.hal +++ b/automotive/vehicle/2.0/types.hal @@ -1446,7 +1446,7 @@ enum VehicleProperty : int32_t { * @access VehiclePropertyAccess:READ_WRITE * @unit VehicleUnit:MILLI_SECS */ - UNIX_TIME = ( + EPOCH_TIME = ( 0x0606 | VehiclePropertyGroup:SYSTEM | VehiclePropertyType:INT64 -- GitLab From a8d103dd09b17b0cf749860e466a4f6be4a9283e Mon Sep 17 00:00:00 2001 From: David Drysdale Date: Thu, 6 May 2021 08:24:06 +0100 Subject: [PATCH 660/790] KeyMint HAL: cert dates are in milliseconds Bug: 188385338 Test: None, comment change only Merged-In: I6251d4a0ba74d111f4c107f9a54a5c45811aa90f Change-Id: I6251d4a0ba74d111f4c107f9a54a5c45811aa90f --- .../hardware/security/keymint/KeyParameterValue.aidl | 2 +- .../aidl/android/hardware/security/keymint/Tag.aidl | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/security/keymint/aidl/android/hardware/security/keymint/KeyParameterValue.aidl b/security/keymint/aidl/android/hardware/security/keymint/KeyParameterValue.aidl index 59016f2c3b..924f4023ba 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/KeyParameterValue.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/KeyParameterValue.aidl @@ -48,7 +48,7 @@ union KeyParameterValue { boolean boolValue; // Always true, if present. int integer; long longInteger; - long dateTime; + long dateTime; // In milliseconds from epoch byte[] blob; } diff --git a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl index 8fbc91a0ef..66f79ce041 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl @@ -935,15 +935,15 @@ enum Tag { /** * Tag::CERTIFICATE_NOT_BEFORE the beginning of the validity of the certificate in UNIX epoch - * time in seconds. This value is used when generating attestation or self signed certificates. - * ErrorCode::MISSING_NOT_BEFORE must be returned if this tag is not provided if this tag is not - * provided to generateKey or importKey. + * time in milliseconds. This value is used when generating attestation or self signed + * certificates. ErrorCode::MISSING_NOT_BEFORE must be returned if this tag is not provided if + * this tag is not provided to generateKey or importKey. */ CERTIFICATE_NOT_BEFORE = (6 << 28) /* TagType:DATE */ | 1008, /** * Tag::CERTIFICATE_NOT_AFTER the end of the validity of the certificate in UNIX epoch time in - * seconds. This value is used when generating attestation or self signed certificates. + * milliseconds. This value is used when generating attestation or self signed certificates. * ErrorCode::MISSING_NOT_AFTER must be returned if this tag is not provided to generateKey or * importKey. */ -- GitLab From fe42aa3a3f6c8a21334ef002533fa1cca90e4134 Mon Sep 17 00:00:00 2001 From: David Drysdale Date: Thu, 6 May 2021 08:10:58 +0100 Subject: [PATCH 661/790] KeyMint VTS: local asymmetric verification Change verification of ECDSA and RSA signatures so it happens locally in the test, rather than by invoking a VERIFY operation against KeyMint. Bug: 188385353 Test: VtsAidlKeyMintTargetTest Merged-In: I0efc30f3c96cd70ac636d34718eff53cc23f1480 Change-Id: I0efc30f3c96cd70ac636d34718eff53cc23f1480 --- .../vts/functional/KeyMintAidlTestBase.cpp | 109 +++++++ .../aidl/vts/functional/KeyMintAidlTestBase.h | 2 + .../aidl/vts/functional/KeyMintTest.cpp | 292 +++++------------- 3 files changed, 194 insertions(+), 209 deletions(-) diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp index 47892042e7..1a05ac8b11 100644 --- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp +++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp @@ -59,6 +59,11 @@ using ::testing::MatchesRegex; namespace test { namespace { + +// Overhead for PKCS#1 v1.5 signature padding of undigested messages. Digested messages have +// additional overhead, for the digest algorithmIdentifier required by PKCS#1. +const size_t kPkcs1UndigestedSignaturePaddingOverhead = 11; + typedef KeyMintAidlTestBase::KeyData KeyData; // Predicate for testing basic characteristics validity in generation or import. bool KeyCharacteristicsBasicallyValid(SecurityLevel secLevel, @@ -590,6 +595,110 @@ void KeyMintAidlTestBase::VerifyMessage(const string& message, const string& sig VerifyMessage(key_blob_, message, signature, params); } +void KeyMintAidlTestBase::LocalVerifyMessage(const string& message, const string& signature, + const AuthorizationSet& params) { + SCOPED_TRACE("LocalVerifyMessage"); + + // Retrieve the public key from the leaf certificate. + ASSERT_GT(cert_chain_.size(), 0); + X509_Ptr key_cert(parse_cert_blob(cert_chain_[0].encodedCertificate)); + ASSERT_TRUE(key_cert.get()); + EVP_PKEY_Ptr pub_key(X509_get_pubkey(key_cert.get())); + ASSERT_TRUE(pub_key.get()); + + Digest digest = params.GetTagValue(TAG_DIGEST).value(); + PaddingMode padding = PaddingMode::NONE; + auto tag = params.GetTagValue(TAG_PADDING); + if (tag.has_value()) { + padding = tag.value(); + } + + if (digest == Digest::NONE) { + switch (EVP_PKEY_id(pub_key.get())) { + case EVP_PKEY_EC: { + vector data((EVP_PKEY_bits(pub_key.get()) + 7) / 8); + size_t data_size = std::min(data.size(), message.size()); + memcpy(data.data(), message.data(), data_size); + EC_KEY_Ptr ecdsa(EVP_PKEY_get1_EC_KEY(pub_key.get())); + ASSERT_TRUE(ecdsa.get()); + ASSERT_EQ(1, + ECDSA_verify(0, reinterpret_cast(data.data()), data_size, + reinterpret_cast(signature.data()), + signature.size(), ecdsa.get())); + break; + } + case EVP_PKEY_RSA: { + vector data(EVP_PKEY_size(pub_key.get())); + size_t data_size = std::min(data.size(), message.size()); + memcpy(data.data(), message.data(), data_size); + + RSA_Ptr rsa(EVP_PKEY_get1_RSA(const_cast(pub_key.get()))); + ASSERT_TRUE(rsa.get()); + + size_t key_len = RSA_size(rsa.get()); + int openssl_padding = RSA_NO_PADDING; + switch (padding) { + case PaddingMode::NONE: + ASSERT_TRUE(data_size <= key_len); + ASSERT_EQ(key_len, signature.size()); + openssl_padding = RSA_NO_PADDING; + break; + case PaddingMode::RSA_PKCS1_1_5_SIGN: + ASSERT_TRUE(data_size + kPkcs1UndigestedSignaturePaddingOverhead <= + key_len); + openssl_padding = RSA_PKCS1_PADDING; + break; + default: + ADD_FAILURE() << "Unsupported RSA padding mode " << padding; + } + + vector decrypted_data(key_len); + int bytes_decrypted = RSA_public_decrypt( + signature.size(), reinterpret_cast(signature.data()), + decrypted_data.data(), rsa.get(), openssl_padding); + ASSERT_GE(bytes_decrypted, 0); + + const uint8_t* compare_pos = decrypted_data.data(); + size_t bytes_to_compare = bytes_decrypted; + uint8_t zero_check_result = 0; + if (padding == PaddingMode::NONE && data_size < bytes_to_compare) { + // If the data is short, for "unpadded" signing we zero-pad to the left. So + // during verification we should have zeros on the left of the decrypted data. + // Do a constant-time check. + const uint8_t* zero_end = compare_pos + bytes_to_compare - data_size; + while (compare_pos < zero_end) zero_check_result |= *compare_pos++; + ASSERT_EQ(0, zero_check_result); + bytes_to_compare = data_size; + } + ASSERT_EQ(0, memcmp(compare_pos, data.data(), bytes_to_compare)); + break; + } + default: + ADD_FAILURE() << "Unknown public key type"; + } + } else { + EVP_MD_CTX digest_ctx; + EVP_MD_CTX_init(&digest_ctx); + EVP_PKEY_CTX* pkey_ctx; + const EVP_MD* md = openssl_digest(digest); + ASSERT_NE(md, nullptr); + ASSERT_EQ(1, EVP_DigestVerifyInit(&digest_ctx, &pkey_ctx, md, nullptr, pub_key.get())); + + 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); + } + + ASSERT_EQ(1, EVP_DigestVerifyUpdate(&digest_ctx, + reinterpret_cast(message.data()), + message.size())); + ASSERT_EQ(1, EVP_DigestVerifyFinal(&digest_ctx, + reinterpret_cast(signature.data()), + signature.size())); + EVP_MD_CTX_cleanup(&digest_ctx); + } +} + string KeyMintAidlTestBase::EncryptMessage(const vector& key_blob, const string& message, const AuthorizationSet& in_params, AuthorizationSet* out_params) { diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h index cb38938684..1a14d47904 100644 --- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h +++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h @@ -162,6 +162,8 @@ class KeyMintAidlTestBase : public ::testing::TestWithParam { const string& signature, const AuthorizationSet& params); void VerifyMessage(const string& message, const string& signature, const AuthorizationSet& params); + void LocalVerifyMessage(const string& message, const string& signature, + const AuthorizationSet& params); string EncryptMessage(const vector& key_blob, const string& message, const AuthorizationSet& in_params, AuthorizationSet* out_params); diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp index bcf8b951df..fa8ab3a5b1 100644 --- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp +++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp @@ -482,7 +482,6 @@ class NewKeyGenerationTest : public KeyMintAidlTestBase { void CheckBaseParams(const vector& keyCharacteristics) { AuthorizationSet auths = CheckCommonParams(keyCharacteristics); EXPECT_TRUE(auths.Contains(TAG_PURPOSE, KeyPurpose::SIGN)); - EXPECT_TRUE(auths.Contains(TAG_PURPOSE, KeyPurpose::VERIFY)); // Check that some unexpected tags/values are NOT present. EXPECT_FALSE(auths.Contains(TAG_PURPOSE, KeyPurpose::ENCRYPT)); @@ -495,7 +494,6 @@ class NewKeyGenerationTest : public KeyMintAidlTestBase { EXPECT_TRUE(auths.Contains(TAG_PURPOSE, KeyPurpose::DECRYPT)); EXPECT_FALSE(auths.Contains(TAG_PURPOSE, KeyPurpose::SIGN)); - EXPECT_FALSE(auths.Contains(TAG_PURPOSE, KeyPurpose::VERIFY)); } AuthorizationSet CheckCommonParams(const vector& keyCharacteristics) { @@ -1986,6 +1984,50 @@ TEST_P(SigningOperationsTest, RsaSuccess) { string message = "12345678901234567890123456789012"; string signature = SignMessage( message, AuthorizationSetBuilder().Digest(Digest::NONE).Padding(PaddingMode::NONE)); + LocalVerifyMessage(message, signature, + AuthorizationSetBuilder().Digest(Digest::NONE).Padding(PaddingMode::NONE)); +} + +/* + * SigningOperationsTest.RsaAllPaddingsAndDigests + * + * Verifies RSA signature/verification for all padding modes and digests. + */ +TEST_P(SigningOperationsTest, RsaAllPaddingsAndDigests) { + auto authorizations = AuthorizationSetBuilder() + .Authorization(TAG_NO_AUTH_REQUIRED) + .RsaSigningKey(2048, 65537) + .Digest(ValidDigests(true /* withNone */, true /* withMD5 */)) + .Padding(PaddingMode::NONE) + .Padding(PaddingMode::RSA_PSS) + .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN) + .SetDefaultValidity(); + + ASSERT_EQ(ErrorCode::OK, GenerateKey(authorizations)); + + string message(128, 'a'); + string corrupt_message(message); + ++corrupt_message[corrupt_message.size() / 2]; + + for (auto padding : + {PaddingMode::NONE, PaddingMode::RSA_PSS, PaddingMode::RSA_PKCS1_1_5_SIGN}) { + for (auto digest : ValidDigests(true /* withNone */, true /* withMD5 */)) { + if (padding == PaddingMode::NONE && digest != Digest::NONE) { + // Digesting only makes sense with padding. + continue; + } + + if (padding == PaddingMode::RSA_PSS && digest == Digest::NONE) { + // PSS requires digesting. + continue; + } + + string signature = + SignMessage(message, AuthorizationSetBuilder().Digest(digest).Padding(padding)); + LocalVerifyMessage(message, signature, + AuthorizationSetBuilder().Digest(digest).Padding(padding)); + } + } } /* @@ -2431,6 +2473,39 @@ TEST_P(SigningOperationsTest, EcdsaAllSizesAndHashes) { } } +/* + * SigningOperationsTest.EcdsaAllDigestsAndCurves + * + * Verifies ECDSA signature/verification for all digests and curves. + */ +TEST_P(SigningOperationsTest, EcdsaAllDigestsAndCurves) { + auto digests = ValidDigests(true /* withNone */, false /* withMD5 */); + + string message = "1234567890"; + string corrupt_message = "2234567890"; + for (auto curve : ValidCurves()) { + SCOPED_TRACE(testing::Message() << "Curve::" << curve); + ErrorCode error = GenerateKey(AuthorizationSetBuilder() + .Authorization(TAG_NO_AUTH_REQUIRED) + .EcdsaSigningKey(curve) + .Digest(digests) + .SetDefaultValidity()); + EXPECT_EQ(ErrorCode::OK, error) << "Failed to generate key for EC curve " << curve; + if (error != ErrorCode::OK) { + continue; + } + + for (auto digest : digests) { + SCOPED_TRACE(testing::Message() << "Digest::" << digest); + string signature = SignMessage(message, AuthorizationSetBuilder().Digest(digest)); + LocalVerifyMessage(message, signature, AuthorizationSetBuilder().Digest(digest)); + } + + auto rc = DeleteKey(); + ASSERT_TRUE(rc == ErrorCode::OK || rc == ErrorCode::UNIMPLEMENTED); + } +} + /* * SigningOperationsTest.EcdsaAllCurves * @@ -2698,207 +2773,6 @@ INSTANTIATE_KEYMINT_AIDL_TEST(SigningOperationsTest); typedef KeyMintAidlTestBase VerificationOperationsTest; -/* - * VerificationOperationsTest.RsaSuccess - * - * Verifies that a simple RSA signature/verification sequence succeeds. - */ -TEST_P(VerificationOperationsTest, RsaSuccess) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .RsaSigningKey(2048, 65537) - .Digest(Digest::NONE) - .Padding(PaddingMode::NONE) - .SetDefaultValidity())); - string message = "12345678901234567890123456789012"; - string signature = SignMessage( - message, AuthorizationSetBuilder().Digest(Digest::NONE).Padding(PaddingMode::NONE)); - VerifyMessage(message, signature, - AuthorizationSetBuilder().Digest(Digest::NONE).Padding(PaddingMode::NONE)); -} - -/* - * VerificationOperationsTest.RsaAllPaddingsAndDigests - * - * Verifies RSA signature/verification for all padding modes and digests. - */ -TEST_P(VerificationOperationsTest, RsaAllPaddingsAndDigests) { - auto authorizations = AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .RsaSigningKey(2048, 65537) - .Digest(ValidDigests(true /* withNone */, true /* withMD5 */)) - .Padding(PaddingMode::NONE) - .Padding(PaddingMode::RSA_PSS) - .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN) - .SetDefaultValidity(); - - ASSERT_EQ(ErrorCode::OK, GenerateKey(authorizations)); - - string message(128, 'a'); - string corrupt_message(message); - ++corrupt_message[corrupt_message.size() / 2]; - - for (auto padding : - {PaddingMode::NONE, PaddingMode::RSA_PSS, PaddingMode::RSA_PKCS1_1_5_SIGN}) { - for (auto digest : ValidDigests(true /* withNone */, true /* withMD5 */)) { - if (padding == PaddingMode::NONE && digest != Digest::NONE) { - // Digesting only makes sense with padding. - continue; - } - - if (padding == PaddingMode::RSA_PSS && digest == Digest::NONE) { - // PSS requires digesting. - continue; - } - - string signature = - SignMessage(message, AuthorizationSetBuilder().Digest(digest).Padding(padding)); - VerifyMessage(message, signature, - AuthorizationSetBuilder().Digest(digest).Padding(padding)); - - /* TODO(seleneh) add exportkey tests back later when we have decided on - * the new api. - if (digest != Digest::NONE) { - // Verify with OpenSSL. - vector pubkey; - ASSERT_EQ(ErrorCode::OK, ExportKey(KeyFormat::X509, &pubkey)); - - const uint8_t* p = pubkey.data(); - EVP_PKEY_Ptr pkey(d2i_PUBKEY(nullptr, &p, pubkey.size())); - ASSERT_TRUE(pkey.get()); - - EVP_MD_CTX digest_ctx; - EVP_MD_CTX_init(&digest_ctx); - EVP_PKEY_CTX* pkey_ctx; - const EVP_MD* md = openssl_digest(digest); - ASSERT_NE(md, nullptr); - EXPECT_EQ(1, EVP_DigestVerifyInit(&digest_ctx, &pkey_ctx, md, - nullptr, pkey.get())); - - switch (padding) { - 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); break; case PaddingMode::RSA_PKCS1_1_5_SIGN: - // PKCS1 is the default; don't need to set anything. - break; - default: - FAIL(); - break; - } - - EXPECT_EQ(1, EVP_DigestVerifyUpdate(&digest_ctx, message.data(), - message.size())); EXPECT_EQ(1, EVP_DigestVerifyFinal(&digest_ctx, - reinterpret_cast(signature.data()), signature.size())); EVP_MD_CTX_cleanup(&digest_ctx); - } - */ - - // Corrupt signature shouldn't verify. - string corrupt_signature(signature); - ++corrupt_signature[corrupt_signature.size() / 2]; - - EXPECT_EQ(ErrorCode::OK, - Begin(KeyPurpose::VERIFY, - AuthorizationSetBuilder().Digest(digest).Padding(padding))); - string result; - EXPECT_EQ(ErrorCode::VERIFICATION_FAILED, Finish(message, corrupt_signature, &result)); - - // Corrupt message shouldn't verify - EXPECT_EQ(ErrorCode::OK, - Begin(KeyPurpose::VERIFY, - AuthorizationSetBuilder().Digest(digest).Padding(padding))); - EXPECT_EQ(ErrorCode::VERIFICATION_FAILED, Finish(corrupt_message, signature, &result)); - } - } -} - -/* - * VerificationOperationsTest.RsaAllDigestsAndCurves - * - * Verifies ECDSA signature/verification for all digests and curves. - */ -TEST_P(VerificationOperationsTest, EcdsaAllDigestsAndCurves) { - auto digests = ValidDigests(true /* withNone */, false /* withMD5 */); - - string message = "1234567890"; - string corrupt_message = "2234567890"; - for (auto curve : ValidCurves()) { - ErrorCode error = GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .EcdsaSigningKey(curve) - .Digest(digests) - .SetDefaultValidity()); - EXPECT_EQ(ErrorCode::OK, error) << "Failed to generate key for EC curve " << curve; - if (error != ErrorCode::OK) { - continue; - } - - for (auto digest : digests) { - string signature = SignMessage(message, AuthorizationSetBuilder().Digest(digest)); - VerifyMessage(message, signature, AuthorizationSetBuilder().Digest(digest)); - - /* TODO(seleneh) add exportkey tests back later when we have decided on - * the new api. - - // Verify with OpenSSL - if (digest != Digest::NONE) { - vector pubkey; - ASSERT_EQ(ErrorCode::OK, ExportKey(KeyFormat::X509, &pubkey)) - << curve << ' ' << digest; - - const uint8_t* p = pubkey.data(); - EVP_PKEY_Ptr pkey(d2i_PUBKEY(nullptr, &p, pubkey.size())); - ASSERT_TRUE(pkey.get()); - - EVP_MD_CTX digest_ctx; - EVP_MD_CTX_init(&digest_ctx); - EVP_PKEY_CTX* pkey_ctx; - const EVP_MD* md = openssl_digest(digest); - - EXPECT_EQ(1, EVP_DigestVerifyInit(&digest_ctx, &pkey_ctx, md, - nullptr, pkey.get())) - << curve << ' ' << digest; - - EXPECT_EQ(1, EVP_DigestVerifyUpdate(&digest_ctx, message.data(), - message.size())) - << curve << ' ' << digest; - - EXPECT_EQ(1, - EVP_DigestVerifyFinal(&digest_ctx, - reinterpret_cast(signature.data()), signature.size())) - << curve << ' ' << digest; - - EVP_MD_CTX_cleanup(&digest_ctx); - } - */ - // Corrupt signature shouldn't verify. - string corrupt_signature(signature); - ++corrupt_signature[corrupt_signature.size() / 2]; - - EXPECT_EQ(ErrorCode::OK, - Begin(KeyPurpose::VERIFY, AuthorizationSetBuilder().Digest(digest))) - << curve << ' ' << digest; - - string result; - EXPECT_EQ(ErrorCode::VERIFICATION_FAILED, Finish(message, corrupt_signature, &result)) - << curve << ' ' << digest; - - // Corrupt message shouldn't verify - EXPECT_EQ(ErrorCode::OK, - Begin(KeyPurpose::VERIFY, AuthorizationSetBuilder().Digest(digest))) - << curve << ' ' << digest; - - EXPECT_EQ(ErrorCode::VERIFICATION_FAILED, Finish(corrupt_message, signature, &result)) - << curve << ' ' << digest; - } - - auto rc = DeleteKey(); - ASSERT_TRUE(rc == ErrorCode::OK || rc == ErrorCode::UNIMPLEMENTED); - } -} - /* * VerificationOperationsTest.HmacSigningKeyCannotVerify * @@ -3016,7 +2890,7 @@ TEST_P(ImportKeyTest, RsaSuccess) { string message(1024 / 8, 'a'); auto params = AuthorizationSetBuilder().Digest(Digest::SHA_2_256).Padding(PaddingMode::RSA_PSS); string signature = SignMessage(message, params); - VerifyMessage(message, signature, params); + LocalVerifyMessage(message, signature, params); } /* @@ -3058,7 +2932,7 @@ TEST_P(ImportKeyTest, RsaSuccessWithoutParams) { string message(1024 / 8, 'a'); auto params = AuthorizationSetBuilder().Digest(Digest::SHA_2_256).Padding(PaddingMode::RSA_PSS); string signature = SignMessage(message, params); - VerifyMessage(message, signature, params); + LocalVerifyMessage(message, signature, params); } /* @@ -3116,7 +2990,7 @@ TEST_P(ImportKeyTest, EcdsaSuccess) { string message(32, 'a'); auto params = AuthorizationSetBuilder().Digest(Digest::SHA_2_256); string signature = SignMessage(message, params); - VerifyMessage(message, signature, params); + LocalVerifyMessage(message, signature, params); } /* @@ -3143,7 +3017,7 @@ TEST_P(ImportKeyTest, EcdsaP256RFC5915Success) { string message(32, 'a'); auto params = AuthorizationSetBuilder().Digest(Digest::SHA_2_256); string signature = SignMessage(message, params); - VerifyMessage(message, signature, params); + LocalVerifyMessage(message, signature, params); } /* @@ -3169,7 +3043,7 @@ TEST_P(ImportKeyTest, EcdsaP256SEC1Success) { string message(32, 'a'); auto params = AuthorizationSetBuilder().Digest(Digest::SHA_2_256); string signature = SignMessage(message, params); - VerifyMessage(message, signature, params); + LocalVerifyMessage(message, signature, params); } /* @@ -3195,7 +3069,7 @@ TEST_P(ImportKeyTest, Ecdsa521Success) { string message(32, 'a'); auto params = AuthorizationSetBuilder().Digest(Digest::SHA_2_256); string signature = SignMessage(message, params); - VerifyMessage(message, signature, params); + LocalVerifyMessage(message, signature, params); } /* -- GitLab From 2b6c351a40139eb63ca0b9c1ee3343e8187e48b1 Mon Sep 17 00:00:00 2001 From: David Drysdale Date: Wed, 12 May 2021 13:52:03 +0100 Subject: [PATCH 662/790] KeyMint VTS: local RSA encryption Change RSA encryption (with public key) so it happens locally in the test, rather than by invoking an ENCRYPT operation against KeyMint. - Specify MGF1 digest for OAEP mode as (now) required by AIDL spec. - Drop tests for too-long encryption inputs. - Adjust test comments to reflect decryption-only nature. - Change parameter checking tests to do so on DECRYPT rather than ENCRYPT. Bug: 188385353 Test: VtsAidlKeyMintTargetTest Merged-In: I10c4beea28387eecfd0bc7c5dfd59a1b66fec21e Change-Id: I10c4beea28387eecfd0bc7c5dfd59a1b66fec21e --- .../vts/functional/KeyMintAidlTestBase.cpp | 95 +++++++++++ .../aidl/vts/functional/KeyMintAidlTestBase.h | 1 + .../aidl/vts/functional/KeyMintTest.cpp | 147 +++++------------- 3 files changed, 132 insertions(+), 111 deletions(-) diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp index 1a05ac8b11..8c4e0c3f25 100644 --- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp +++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp @@ -699,6 +699,101 @@ void KeyMintAidlTestBase::LocalVerifyMessage(const string& message, const string } } +string KeyMintAidlTestBase::LocalRsaEncryptMessage(const string& message, + const AuthorizationSet& params) { + SCOPED_TRACE("LocalRsaEncryptMessage"); + + // Retrieve the public key from the leaf certificate. + if (cert_chain_.empty()) { + ADD_FAILURE() << "No public key available"; + return "Failure"; + } + X509_Ptr key_cert(parse_cert_blob(cert_chain_[0].encodedCertificate)); + EVP_PKEY_Ptr pub_key(X509_get_pubkey(key_cert.get())); + RSA_Ptr rsa(EVP_PKEY_get1_RSA(const_cast(pub_key.get()))); + + // Retrieve relevant tags. + Digest digest = Digest::NONE; + Digest mgf_digest = Digest::NONE; + PaddingMode padding = PaddingMode::NONE; + + auto digest_tag = params.GetTagValue(TAG_DIGEST); + if (digest_tag.has_value()) digest = digest_tag.value(); + auto pad_tag = params.GetTagValue(TAG_PADDING); + if (pad_tag.has_value()) padding = pad_tag.value(); + auto mgf_tag = params.GetTagValue(TAG_RSA_OAEP_MGF_DIGEST); + if (mgf_tag.has_value()) mgf_digest = mgf_tag.value(); + + const EVP_MD* md = openssl_digest(digest); + const EVP_MD* mgf_md = openssl_digest(mgf_digest); + + // Set up encryption context. + EVP_PKEY_CTX_Ptr ctx(EVP_PKEY_CTX_new(pub_key.get(), /* engine= */ nullptr)); + if (EVP_PKEY_encrypt_init(ctx.get()) <= 0) { + ADD_FAILURE() << "Encryption init failed: " << ERR_peek_last_error(); + return "Failure"; + } + + int rc = -1; + switch (padding) { + case PaddingMode::NONE: + rc = EVP_PKEY_CTX_set_rsa_padding(ctx.get(), RSA_NO_PADDING); + break; + case PaddingMode::RSA_PKCS1_1_5_ENCRYPT: + rc = EVP_PKEY_CTX_set_rsa_padding(ctx.get(), RSA_PKCS1_PADDING); + break; + case PaddingMode::RSA_OAEP: + rc = EVP_PKEY_CTX_set_rsa_padding(ctx.get(), RSA_PKCS1_OAEP_PADDING); + break; + default: + break; + } + if (rc <= 0) { + ADD_FAILURE() << "Set padding failed: " << ERR_peek_last_error(); + return "Failure"; + } + if (padding == PaddingMode::RSA_OAEP) { + if (!EVP_PKEY_CTX_set_rsa_oaep_md(ctx.get(), md)) { + ADD_FAILURE() << "Set digest failed: " << ERR_peek_last_error(); + return "Failure"; + } + if (!EVP_PKEY_CTX_set_rsa_mgf1_md(ctx.get(), mgf_md)) { + ADD_FAILURE() << "Set MGF digest failed: " << ERR_peek_last_error(); + return "Failure"; + } + } + + // Determine output size. + size_t outlen; + if (EVP_PKEY_encrypt(ctx.get(), nullptr /* out */, &outlen, + reinterpret_cast(message.data()), message.size()) <= 0) { + ADD_FAILURE() << "Determine output size failed: " << ERR_peek_last_error(); + return "Failure"; + } + + // Left-zero-pad the input if necessary. + const uint8_t* to_encrypt = reinterpret_cast(message.data()); + size_t to_encrypt_len = message.size(); + + std::unique_ptr zero_padded_message; + if (padding == PaddingMode::NONE && to_encrypt_len < outlen) { + zero_padded_message.reset(new string(outlen, '\0')); + memcpy(zero_padded_message->data() + (outlen - to_encrypt_len), message.data(), + message.size()); + to_encrypt = reinterpret_cast(zero_padded_message->data()); + to_encrypt_len = outlen; + } + + // Do the encryption. + string output(outlen, '\0'); + if (EVP_PKEY_encrypt(ctx.get(), reinterpret_cast(output.data()), &outlen, to_encrypt, + to_encrypt_len) <= 0) { + ADD_FAILURE() << "Encryption failed: " << ERR_peek_last_error(); + return "Failure"; + } + return output; +} + string KeyMintAidlTestBase::EncryptMessage(const vector& key_blob, const string& message, const AuthorizationSet& in_params, AuthorizationSet* out_params) { diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h index 1a14d47904..d8f1bb3dbe 100644 --- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h +++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h @@ -165,6 +165,7 @@ class KeyMintAidlTestBase : public ::testing::TestWithParam { void LocalVerifyMessage(const string& message, const string& signature, const AuthorizationSet& params); + string LocalRsaEncryptMessage(const string& message, const AuthorizationSet& params); string EncryptMessage(const vector& key_blob, const string& message, const AuthorizationSet& in_params, AuthorizationSet* out_params); string EncryptMessage(const string& message, const AuthorizationSet& params, diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp index fa8ab3a5b1..293a010f50 100644 --- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp +++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp @@ -3627,7 +3627,7 @@ typedef KeyMintAidlTestBase EncryptionOperationsTest; /* * EncryptionOperationsTest.RsaNoPaddingSuccess * - * Verifies that raw RSA encryption works. + * Verifies that raw RSA decryption works. */ TEST_P(EncryptionOperationsTest, RsaNoPaddingSuccess) { for (uint64_t exponent : {3, 65537}) { @@ -3639,10 +3639,10 @@ TEST_P(EncryptionOperationsTest, RsaNoPaddingSuccess) { string message = string(2048 / 8, 'a'); auto params = AuthorizationSetBuilder().Padding(PaddingMode::NONE); - string ciphertext1 = EncryptMessage(message, params); + string ciphertext1 = LocalRsaEncryptMessage(message, params); EXPECT_EQ(2048U / 8, ciphertext1.size()); - string ciphertext2 = EncryptMessage(message, params); + string ciphertext2 = LocalRsaEncryptMessage(message, params); EXPECT_EQ(2048U / 8, ciphertext2.size()); // Unpadded RSA is deterministic @@ -3655,7 +3655,7 @@ TEST_P(EncryptionOperationsTest, RsaNoPaddingSuccess) { /* * EncryptionOperationsTest.RsaNoPaddingShortMessage * - * Verifies that raw RSA encryption of short messages works. + * Verifies that raw RSA decryption of short messages works. */ TEST_P(EncryptionOperationsTest, RsaNoPaddingShortMessage) { ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() @@ -3667,76 +3667,47 @@ TEST_P(EncryptionOperationsTest, RsaNoPaddingShortMessage) { string message = "1"; auto params = AuthorizationSetBuilder().Padding(PaddingMode::NONE); - string ciphertext = EncryptMessage(message, params); + string ciphertext = LocalRsaEncryptMessage(message, params); EXPECT_EQ(2048U / 8, ciphertext.size()); string expected_plaintext = string(2048U / 8 - 1, 0) + message; string plaintext = DecryptMessage(ciphertext, params); EXPECT_EQ(expected_plaintext, plaintext); - - // Degenerate case, encrypting a numeric 1 yields 0x00..01 as the ciphertext. - message = static_cast(1); - ciphertext = EncryptMessage(message, params); - EXPECT_EQ(2048U / 8, ciphertext.size()); - EXPECT_EQ(ciphertext, string(2048U / 8 - 1, 0) + message); -} - -/* - * EncryptionOperationsTest.RsaNoPaddingTooLong - * - * Verifies that raw RSA encryption of too-long messages fails in the expected way. - */ -TEST_P(EncryptionOperationsTest, RsaNoPaddingTooLong) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .RsaEncryptionKey(2048, 65537) - .Padding(PaddingMode::NONE) - .SetDefaultValidity())); - - string message(2048 / 8 + 1, 'a'); - - auto params = AuthorizationSetBuilder().Padding(PaddingMode::NONE); - EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params)); - - string result; - EXPECT_EQ(ErrorCode::INVALID_INPUT_LENGTH, Finish(message, &result)); } -/* - * EncryptionOperationsTest.RsaNoPaddingTooLarge - * - * Verifies that raw RSA encryption of too-large (numerically) messages fails in the expected - * way. - */ -// TODO(seleneh) add RsaNoPaddingTooLarge test back after decided and implemented new -// version of ExportKey inside generateKey - /* * EncryptionOperationsTest.RsaOaepSuccess * - * Verifies that RSA-OAEP encryption operations work, with all digests. + * Verifies that RSA-OAEP decryption operations work, with all digests. */ TEST_P(EncryptionOperationsTest, RsaOaepSuccess) { auto digests = ValidDigests(false /* withNone */, true /* withMD5 */); size_t key_size = 2048; // Need largish key for SHA-512 test. - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .RsaEncryptionKey(key_size, 65537) - .Padding(PaddingMode::RSA_OAEP) - .Digest(digests) - .SetDefaultValidity())); + ASSERT_EQ(ErrorCode::OK, + GenerateKey(AuthorizationSetBuilder() + .Authorization(TAG_NO_AUTH_REQUIRED) + .RsaEncryptionKey(key_size, 65537) + .Padding(PaddingMode::RSA_OAEP) + .Digest(digests) + .Authorization(TAG_RSA_OAEP_MGF_DIGEST, Digest::SHA1) + .SetDefaultValidity())); string message = "Hello"; for (auto digest : digests) { - auto params = AuthorizationSetBuilder().Digest(digest).Padding(PaddingMode::RSA_OAEP); - string ciphertext1 = EncryptMessage(message, params); + SCOPED_TRACE(testing::Message() << "digest-" << digest); + + auto params = AuthorizationSetBuilder() + .Digest(digest) + .Padding(PaddingMode::RSA_OAEP) + .Authorization(TAG_RSA_OAEP_MGF_DIGEST, Digest::SHA1); + string ciphertext1 = LocalRsaEncryptMessage(message, params); if (HasNonfatalFailure()) std::cout << "-->" << digest << std::endl; EXPECT_EQ(key_size / 8, ciphertext1.size()); - string ciphertext2 = EncryptMessage(message, params); + string ciphertext2 = LocalRsaEncryptMessage(message, params); EXPECT_EQ(key_size / 8, ciphertext2.size()); // OAEP randomizes padding so every result should be different (with astronomically high @@ -3766,7 +3737,7 @@ TEST_P(EncryptionOperationsTest, RsaOaepSuccess) { /* * EncryptionOperationsTest.RsaOaepInvalidDigest * - * Verifies that RSA-OAEP encryption operations fail in the correct way when asked to operate + * Verifies that RSA-OAEP decryption operations fail in the correct way when asked to operate * without a digest. */ TEST_P(EncryptionOperationsTest, RsaOaepInvalidDigest) { @@ -3778,13 +3749,13 @@ TEST_P(EncryptionOperationsTest, RsaOaepInvalidDigest) { .SetDefaultValidity())); auto params = AuthorizationSetBuilder().Padding(PaddingMode::RSA_OAEP).Digest(Digest::NONE); - EXPECT_EQ(ErrorCode::INCOMPATIBLE_DIGEST, Begin(KeyPurpose::ENCRYPT, params)); + EXPECT_EQ(ErrorCode::INCOMPATIBLE_DIGEST, Begin(KeyPurpose::DECRYPT, params)); } /* * EncryptionOperationsTest.RsaOaepInvalidPadding * - * Verifies that RSA-OAEP encryption operations fail in the correct way when asked to operate + * Verifies that RSA-OAEP decryption operations fail in the correct way when asked to operate * with a padding value that is only suitable for signing/verifying. */ TEST_P(EncryptionOperationsTest, RsaOaepInvalidPadding) { @@ -3796,13 +3767,13 @@ TEST_P(EncryptionOperationsTest, RsaOaepInvalidPadding) { .SetDefaultValidity())); auto params = AuthorizationSetBuilder().Padding(PaddingMode::RSA_PSS).Digest(Digest::NONE); - EXPECT_EQ(ErrorCode::UNSUPPORTED_PADDING_MODE, Begin(KeyPurpose::ENCRYPT, params)); + EXPECT_EQ(ErrorCode::UNSUPPORTED_PADDING_MODE, Begin(KeyPurpose::DECRYPT, params)); } /* * EncryptionOperationsTest.RsaOaepDecryptWithWrongDigest * - * Verifies that RSA-OAEP encryption operations fail in the correct way when asked to decrypt + * Verifies that RSA-OAEP decryption operations fail in the correct way when asked to decrypt * with a different digest than was used to encrypt. */ TEST_P(EncryptionOperationsTest, RsaOaepDecryptWithWrongDigest) { @@ -3815,7 +3786,7 @@ TEST_P(EncryptionOperationsTest, RsaOaepDecryptWithWrongDigest) { .Digest(Digest::SHA_2_224, Digest::SHA_2_256) .SetDefaultValidity())); string message = "Hello World!"; - string ciphertext = EncryptMessage( + string ciphertext = LocalRsaEncryptMessage( message, AuthorizationSetBuilder().Digest(Digest::SHA_2_224).Padding(PaddingMode::RSA_OAEP)); @@ -3827,35 +3798,10 @@ TEST_P(EncryptionOperationsTest, RsaOaepDecryptWithWrongDigest) { EXPECT_EQ(0U, result.size()); } -/* - * EncryptionOperationsTest.RsaOaepTooLarge - * - * Verifies that RSA-OAEP encryption operations fail in the correct way when asked to encrypt a - * too-large message. - */ -TEST_P(EncryptionOperationsTest, RsaOaepTooLarge) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .RsaEncryptionKey(2048, 65537) - .Padding(PaddingMode::RSA_OAEP) - .Digest(Digest::SHA_2_256) - .SetDefaultValidity())); - constexpr size_t digest_size = 256 /* SHA_2_256 */ / 8; - constexpr size_t oaep_overhead = 2 * digest_size + 2; - string message(2048 / 8 - oaep_overhead + 1, 'a'); - EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, AuthorizationSetBuilder() - .Padding(PaddingMode::RSA_OAEP) - .Digest(Digest::SHA_2_256))); - string result; - ErrorCode error = Finish(message, &result); - EXPECT_TRUE(error == ErrorCode::INVALID_INPUT_LENGTH || error == ErrorCode::INVALID_ARGUMENT); - EXPECT_EQ(0U, result.size()); -} - /* * EncryptionOperationsTest.RsaOaepWithMGFDigestSuccess * - * Verifies that RSA-OAEP encryption operations work, with all SHA 256 digests and all type of MGF1 + * Verifies that RSA-OAEP decryption operations work, with all SHA 256 digests and all type of MGF1 * digests. */ TEST_P(EncryptionOperationsTest, RsaOaepWithMGFDigestSuccess) { @@ -3877,11 +3823,11 @@ TEST_P(EncryptionOperationsTest, RsaOaepWithMGFDigestSuccess) { .Authorization(TAG_RSA_OAEP_MGF_DIGEST, digest) .Digest(Digest::SHA_2_256) .Padding(PaddingMode::RSA_OAEP); - string ciphertext1 = EncryptMessage(message, params); + string ciphertext1 = LocalRsaEncryptMessage(message, params); if (HasNonfatalFailure()) std::cout << "-->" << digest << std::endl; EXPECT_EQ(key_size / 8, ciphertext1.size()); - string ciphertext2 = EncryptMessage(message, params); + string ciphertext2 = LocalRsaEncryptMessage(message, params); EXPECT_EQ(key_size / 8, ciphertext2.size()); // OAEP randomizes padding so every result should be different (with astronomically high @@ -3911,7 +3857,7 @@ TEST_P(EncryptionOperationsTest, RsaOaepWithMGFDigestSuccess) { /* * EncryptionOperationsTest.RsaOaepWithMGFIncompatibleDigest * - * Verifies that RSA-OAEP encryption operations fail in the correct way when asked to operate + * Verifies that RSA-OAEP decryption operations fail in the correct way when asked to operate * with incompatible MGF digest. */ TEST_P(EncryptionOperationsTest, RsaOaepWithMGFIncompatibleDigest) { @@ -3929,7 +3875,7 @@ TEST_P(EncryptionOperationsTest, RsaOaepWithMGFIncompatibleDigest) { .Padding(PaddingMode::RSA_OAEP) .Digest(Digest::SHA_2_256) .Authorization(TAG_RSA_OAEP_MGF_DIGEST, Digest::SHA_2_224); - EXPECT_EQ(ErrorCode::INCOMPATIBLE_MGF_DIGEST, Begin(KeyPurpose::ENCRYPT, params)); + EXPECT_EQ(ErrorCode::INCOMPATIBLE_MGF_DIGEST, Begin(KeyPurpose::DECRYPT, params)); } /* @@ -3953,7 +3899,7 @@ TEST_P(EncryptionOperationsTest, RsaOaepWithMGFUnsupportedDigest) { .Padding(PaddingMode::RSA_OAEP) .Digest(Digest::SHA_2_256) .Authorization(TAG_RSA_OAEP_MGF_DIGEST, Digest::NONE); - EXPECT_EQ(ErrorCode::UNSUPPORTED_MGF_DIGEST, Begin(KeyPurpose::ENCRYPT, params)); + EXPECT_EQ(ErrorCode::UNSUPPORTED_MGF_DIGEST, Begin(KeyPurpose::DECRYPT, params)); } /* @@ -3970,10 +3916,10 @@ TEST_P(EncryptionOperationsTest, RsaPkcs1Success) { string message = "Hello World!"; auto params = AuthorizationSetBuilder().Padding(PaddingMode::RSA_PKCS1_1_5_ENCRYPT); - string ciphertext1 = EncryptMessage(message, params); + string ciphertext1 = LocalRsaEncryptMessage(message, params); EXPECT_EQ(2048U / 8, ciphertext1.size()); - string ciphertext2 = EncryptMessage(message, params); + string ciphertext2 = LocalRsaEncryptMessage(message, params); EXPECT_EQ(2048U / 8, ciphertext2.size()); // PKCS1 v1.5 randomizes padding so every result should be different. @@ -3996,27 +3942,6 @@ TEST_P(EncryptionOperationsTest, RsaPkcs1Success) { EXPECT_EQ(0U, result.size()); } -/* - * EncryptionOperationsTest.RsaPkcs1TooLarge - * - * Verifies that RSA PKCS encryption fails in the correct way when the message is too large. - */ -TEST_P(EncryptionOperationsTest, RsaPkcs1TooLarge) { - ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .RsaEncryptionKey(2048, 65537) - .Padding(PaddingMode::RSA_PKCS1_1_5_ENCRYPT) - .SetDefaultValidity())); - string message(2048 / 8 - 10, 'a'); - - auto params = AuthorizationSetBuilder().Padding(PaddingMode::RSA_PKCS1_1_5_ENCRYPT); - EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params)); - string result; - ErrorCode error = Finish(message, &result); - EXPECT_TRUE(error == ErrorCode::INVALID_INPUT_LENGTH || error == ErrorCode::INVALID_ARGUMENT); - EXPECT_EQ(0U, result.size()); -} - /* * EncryptionOperationsTest.EcdsaEncrypt * -- GitLab From 3177f58e30a1757d70a414085aff2a4455fc0767 Mon Sep 17 00:00:00 2001 From: Emilian Peev Date: Wed, 12 May 2021 12:35:16 -0700 Subject: [PATCH 663/790] Camera: Correct partial result entry count query Use the partial tag count instead of the size of the metadata buffer. Additionally initialize 'collectedResult' to avoid false positives when checking partial result entries against invalid/uninitialized accumulated results. Bug: 187156343 Test: Partner verified Change-Id: Iff55f53952c7b06bc2a0b9786247d8ec04227705 --- .../functional/VtsHalCameraProviderV2_4TargetTest.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp index deb420d1e2..0ec9fe34b0 100644 --- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp +++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp @@ -997,7 +997,8 @@ protected: frameNumber(0), partialResultCount(0), errorStreamId(-1), - hasInputBuffer(false) {} + hasInputBuffer(false), + collectedResult(1, 10) {} InFlightRequest(ssize_t numBuffers, bool hasInput, bool partialResults, uint32_t partialCount, @@ -1013,7 +1014,8 @@ protected: frameNumber(0), partialResultCount(0), errorStreamId(-1), - hasInputBuffer(hasInput) {} + hasInputBuffer(hasInput), + collectedResult(1, 10) {} InFlightRequest(ssize_t numBuffers, bool hasInput, bool partialResults, uint32_t partialCount, @@ -1031,6 +1033,7 @@ protected: partialResultCount(0), errorStreamId(-1), hasInputBuffer(hasInput), + collectedResult(1, 10), expectedPhysicalResults(extraPhysicalResult) {} }; @@ -1313,7 +1316,7 @@ bool CameraHidlTest::DeviceCb::processCaptureResultLocked(const CaptureResult& r reinterpret_cast(resultMetadata.data()); const camera_metadata_t* collectedMetadata = request->collectedResult.getAndLock(); camera_metadata_ro_entry_t searchEntry, foundEntry; - for (size_t i = 0; i < get_camera_metadata_size(partialMetadata); i++) { + for (size_t i = 0; i < get_camera_metadata_entry_count(partialMetadata); i++) { if (0 != get_camera_metadata_ro_entry(partialMetadata, i, &searchEntry)) { ADD_FAILURE(); request->collectedResult.unlock(collectedMetadata); -- GitLab From 4065fbfa46c45c8994613e570a675522146422f0 Mon Sep 17 00:00:00 2001 From: Hao Chen Date: Wed, 12 May 2021 15:19:06 -0700 Subject: [PATCH 664/790] Vehicle HAL client reads the config from the server instead of DefaultConfigs.h Test: Launch cf auto instance (with default vhal) and atest packages/services/Car/tests/vehiclehal_test/src/com/android/car/vehiclehal/test/CarPropertyTest.java Bug: 188005769 Change-Id: If98db799be8c894bd9a7ba44bf3075f1f7384e5c --- .../vhal_v2_0/EmulatedVehicleConnector.cpp | 5 +- .../impl/vhal_v2_0/EmulatedVehicleConnector.h | 4 +- .../impl/vhal_v2_0/EmulatedVehicleHal.cpp | 57 +++++++------------ .../impl/vhal_v2_0/EmulatedVehicleHal.h | 2 +- .../default/impl/vhal_v2_0/VehicleHalClient.h | 4 ++ .../impl/vhal_v2_0/VehicleHalServer.cpp | 8 +++ .../default/impl/vhal_v2_0/VehicleHalServer.h | 2 + 7 files changed, 44 insertions(+), 38 deletions(-) diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.cpp index ed3f4a2e8f..eae58d0759 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.cpp +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.cpp @@ -21,7 +21,6 @@ #include #include -#include "DefaultConfig.h" #include "EmulatedVehicleConnector.h" #include "JsonFakeValueGenerator.h" #include "LinearFakeValueGenerator.h" @@ -39,6 +38,10 @@ EmulatedUserHal* EmulatedVehicleConnector::getEmulatedUserHal() { return &mEmulatedUserHal; } +void EmulatedVehicleConnector::triggerSendAllValues() { + sendAllValuesToClient(); +} + StatusCode EmulatedVehicleConnector::onSetProperty(const VehiclePropValue& value, bool updateStatus) { if (mEmulatedUserHal.isSupported(value.prop)) { diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.h index 4c6c66150b..31ac7d8fb5 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.h +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.h @@ -33,11 +33,13 @@ namespace impl { class EmulatedVehicleConnector : public IPassThroughConnector { public: - EmulatedVehicleConnector() {} + EmulatedVehicleConnector() = default; EmulatedUserHal* getEmulatedUserHal(); // Methods from VehicleHalServer + void triggerSendAllValues() override; + StatusCode onSetProperty(const VehiclePropValue& value, bool updateStatus) override; bool onDump(const hidl_handle& fd, const hidl_vec& options) override; diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp index 1608e5294d..e8b79dc394 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp @@ -105,9 +105,6 @@ EmulatedVehicleHal::EmulatedVehicleHal(VehiclePropertyStore* propStore, VehicleH mVehicleClient(client), mEmulatedUserHal(emulatedUserHal) { initStaticConfig(); - for (size_t i = 0; i < arraysize(kVehicleProperties); i++) { - mPropStore->registerProperty(kVehicleProperties[i].config); - } mVehicleClient->registerPropertyValueCallback(std::bind(&EmulatedVehicleHal::onPropertyValue, this, std::placeholders::_1, std::placeholders::_2)); @@ -180,7 +177,13 @@ VehicleHal::VehiclePropValuePtr EmulatedVehicleHal::get( v = getValuePool()->obtain(*internalPropValue); } - *outStatus = v != nullptr ? StatusCode::OK : StatusCode::INVALID_ARG; + if (!v) { + *outStatus = StatusCode::INVALID_ARG; + } else if (v->status == VehiclePropertyStatus::AVAILABLE) { + *outStatus = StatusCode::OK; + } else { + *outStatus = StatusCode::TRY_AGAIN; + } break; } if (v.get()) { @@ -280,57 +283,41 @@ static bool isDiagnosticProperty(VehiclePropConfig propConfig) { void EmulatedVehicleHal::onCreate() { static constexpr bool shouldUpdateStatus = true; - for (auto& it : kVehicleProperties) { - VehiclePropConfig cfg = it.config; - int32_t numAreas = cfg.areaConfigs.size(); + auto configs = mVehicleClient->getAllPropertyConfig(); + for (const auto& cfg : configs) { if (isDiagnosticProperty(cfg)) { // do not write an initial empty value for the diagnostic properties // as we will initialize those separately. continue; } - // A global property will have only a single area - if (isGlobalProp(cfg.prop)) { - numAreas = 1; - } + int32_t numAreas = isGlobalProp(cfg.prop) ? 0 : cfg.areaConfigs.size(); for (int i = 0; i < numAreas; i++) { - int32_t curArea; - - if (isGlobalProp(cfg.prop)) { - curArea = 0; - } else { - curArea = cfg.areaConfigs[i].areaId; - } + int32_t curArea = isGlobalProp(cfg.prop) ? 0 : cfg.areaConfigs[i].areaId; // Create a separate instance for each individual zone VehiclePropValue prop = { .areaId = curArea, .prop = cfg.prop, + .status = VehiclePropertyStatus::UNAVAILABLE, }; - if (it.initialAreaValues.size() > 0) { - auto valueForAreaIt = it.initialAreaValues.find(curArea); - if (valueForAreaIt != it.initialAreaValues.end()) { - prop.value = valueForAreaIt->second; - } else { - ALOGW("%s failed to get default value for prop 0x%x area 0x%x", - __func__, cfg.prop, curArea); - } - } else { - prop.value = it.initialValue; - if (mInitVhalValueOverride) { - for (auto& itOverride : mVehiclePropertiesOverride) { - if (itOverride.prop == cfg.prop) { - prop.value = itOverride.value; - } + if (mInitVhalValueOverride) { + for (auto& itOverride : mVehiclePropertiesOverride) { + if (itOverride.prop == cfg.prop) { + prop.status = VehiclePropertyStatus::AVAILABLE; + prop.value = itOverride.value; } } } mPropStore->writeValue(prop, shouldUpdateStatus); } } + + mVehicleClient->triggerSendAllValues(); + initObd2LiveFrame(*mPropStore->getConfigOrDie(OBD2_LIVE_FRAME)); initObd2FreezeFrame(*mPropStore->getConfigOrDie(OBD2_FREEZE_FRAME)); mInEmulator = isInEmulator(); @@ -414,8 +401,8 @@ void EmulatedVehicleHal::onPropertyValue(const VehiclePropValue& value, bool upd } void EmulatedVehicleHal::initStaticConfig() { - for (auto&& it = std::begin(kVehicleProperties); it != std::end(kVehicleProperties); ++it) { - const auto& cfg = it->config; + auto configs = mVehicleClient->getAllPropertyConfig(); + for (auto&& cfg : configs) { VehiclePropertyStore::TokenFunction tokenFunction = nullptr; switch (cfg.prop) { diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h index 5c676416d7..7871c7b41a 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h @@ -29,10 +29,10 @@ #include #include "vhal_v2_0/VehiclePropertyStore.h" -#include "DefaultConfig.h" #include "EmulatedUserHal.h" #include "EmulatedVehicleConnector.h" #include "GeneratorHub.h" +#include "PropertyUtils.h" #include "VehicleEmulator.h" namespace android { diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalClient.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalClient.h index 6559e2aa84..81dfca1b06 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalClient.h +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalClient.h @@ -27,6 +27,10 @@ class VehicleHalClient : public IVehicleClient { // Type of callback function for handling the new property values using PropertyCallBackType = std::function; + // The server will call sendAllValuesToClient, onPropertyValue will be called when values are + // received. + virtual void triggerSendAllValues() = 0; + // Method from IVehicleClient void onPropertyValue(const VehiclePropValue& value, bool updateStatus) override; diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.cpp index 1e468975a2..57dd7d4215 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.cpp +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.cpp @@ -82,6 +82,14 @@ VehicleHalServer::VehicleHalServer() { } } +void VehicleHalServer::sendAllValuesToClient() { + constexpr bool update_status = true; + auto values = mServerSidePropStore.readAllValues(); + for (const auto& value : values) { + onPropertyValueFromCar(value, update_status); + } +} + GeneratorHub* VehicleHalServer::getGenerator() { return &mGeneratorHub; } diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.h index 2ad75e368a..be88cd94cd 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.h +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.h @@ -31,6 +31,8 @@ class VehicleHalServer : public IVehicleServer { public: VehicleHalServer(); + void sendAllValuesToClient(); + // Methods from IVehicleServer std::vector onGetAllPropertyConfig() const override; -- GitLab From 3b56cbca28c57787f34d6494fcbff1e1695f334d Mon Sep 17 00:00:00 2001 From: Tommy Chiu Date: Tue, 11 May 2021 18:36:50 +0800 Subject: [PATCH 665/790] KeyMint vts: Correct the EC curve parameter and some return code Strongbox doens't support p-224. Change the curve to p-256 for better compatibility. Also update the tags to be filtered on the hw-enforcement list. Bug: 186735514 Test: VtsAidlKeyMintTargetTest Change-Id: I3f587c5471ca68b88a565ee9ec2e27d1e9e11b17 Merged-In: Ia8eb4c8e28810de5f37295abd8baed6f01b19a3c --- .../hardware/security/keymint/IKeyMintDevice.aidl | 9 +++++---- security/keymint/aidl/vts/functional/AttestKeyTest.cpp | 8 ++++---- .../aidl/vts/functional/KeyMintAidlTestBase.cpp | 8 ++++---- security/keymint/aidl/vts/functional/KeyMintTest.cpp | 10 +++++----- 4 files changed, 18 insertions(+), 17 deletions(-) diff --git a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl index b6af8138c0..9cc795d582 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl @@ -318,10 +318,11 @@ interface IKeyMintDevice { * @param attestationKey, if provided, specifies the key that must be used to sign the * attestation certificate. If `keyParams` does not contain a Tag::ATTESTATION_CHALLENGE * but `attestationKey` is non-null, the IKeyMintDevice must return - * ErrorCode::INVALID_ARGUMENT. If the provided AttestationKey does not contain a key - * blob containing an asymmetric key with KeyPurpose::ATTEST_KEY, the IKeyMintDevice must - * return ErrorCode::INCOMPATIBLE_PURPOSE. If the provided AttestationKey has an empty - * issuer subject name, the IKeyMintDevice must return ErrorCode::INVALID_ARGUMENT. + * ErrorCode::ATTESTATION_CHALLENGE_MISSING. If the provided AttestationKey does not + * contain a key blob containing an asymmetric key with KeyPurpose::ATTEST_KEY, the + * IKeyMintDevice must return ErrorCode::INCOMPATIBLE_PURPOSE. If the provided + * AttestationKey has an empty issuer subject name, the IKeyMintDevice must return + * ErrorCode::INVALID_ARGUMENT. * * If `attestationKey` is null and `keyParams` contains Tag::ATTESTATION_CHALLENGE but * the KeyMint implementation does not have factory-provisioned attestation keys, it must diff --git a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp index 881354d41d..e4a877c0cb 100644 --- a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp +++ b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp @@ -361,7 +361,7 @@ TEST_P(AttestKeyTest, EcAttestKeyChaining) { EXPECT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .EcdsaSigningKey(224) + .EcdsaSigningKey(EcCurve::P_256) .AttestKey() .AttestationChallenge("foo") .AttestationApplicationId("bar") @@ -435,7 +435,7 @@ TEST_P(AttestKeyTest, AlternateAttestKeyChaining) { if ((i & 0x1) == 1) { EXPECT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .EcdsaSigningKey(224) + .EcdsaSigningKey(EcCurve::P_256) .AttestKey() .AttestationChallenge("foo") .AttestationApplicationId("bar") @@ -513,7 +513,7 @@ TEST_P(AttestKeyTest, MissingChallenge) { vector attested_key_blob; vector attested_key_characteristics; vector attested_key_cert_chain; - EXPECT_EQ(ErrorCode::INVALID_ARGUMENT, + EXPECT_EQ(ErrorCode::ATTESTATION_CHALLENGE_MISSING, GenerateKey(AuthorizationSetBuilder() .RsaSigningKey(2048, 65537) .Authorization(TAG_NO_AUTH_REQUIRED) @@ -522,7 +522,7 @@ TEST_P(AttestKeyTest, MissingChallenge) { attest_key, &attested_key_blob, &attested_key_characteristics, &attested_key_cert_chain)); - EXPECT_EQ(ErrorCode::INVALID_ARGUMENT, + EXPECT_EQ(ErrorCode::ATTESTATION_CHALLENGE_MISSING, GenerateKey(AuthorizationSetBuilder() .EcdsaSigningKey(EcCurve::P_256) .Authorization(TAG_NO_AUTH_REQUIRED) diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp index 47892042e7..675e01d54f 100644 --- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp +++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp @@ -119,10 +119,10 @@ char nibble2hex[16] = {'0', '1', '2', '3', '4', '5', '6', '7', // Attestations don't contain everything in key authorization lists, so we need to filter the key // lists to produce the lists that we expect to match the attestations. auto kTagsToFilter = { - Tag::CREATION_DATETIME, // - Tag::EC_CURVE, - Tag::HARDWARE_TYPE, - Tag::INCLUDE_UNIQUE_ID, + Tag::CREATION_DATETIME, + Tag::EC_CURVE, + Tag::HARDWARE_TYPE, + Tag::INCLUDE_UNIQUE_ID, }; AuthorizationSet filtered_tags(const AuthorizationSet& set) { diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp index bcf8b951df..22d26a55d6 100644 --- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp +++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp @@ -2261,11 +2261,11 @@ TEST_P(SigningOperationsTest, RsaNonUniqueParams) { .Padding(PaddingMode::NONE) .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN))); - ASSERT_EQ(ErrorCode::UNSUPPORTED_DIGEST, - Begin(KeyPurpose::SIGN, AuthorizationSetBuilder() - .Digest(Digest::NONE) - .Digest(Digest::SHA1) - .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN))); + auto result = Begin(KeyPurpose::SIGN, AuthorizationSetBuilder() + .Digest(Digest::NONE) + .Digest(Digest::SHA1) + .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)); + ASSERT_TRUE(result == ErrorCode::UNSUPPORTED_DIGEST || result == ErrorCode::INVALID_ARGUMENT); ASSERT_EQ(ErrorCode::UNSUPPORTED_DIGEST, Begin(KeyPurpose::SIGN, -- GitLab From 2082b871ab819aa58c26e5c93f961be052a01951 Mon Sep 17 00:00:00 2001 From: Xusong Wang Date: Tue, 18 May 2021 13:54:11 -0700 Subject: [PATCH 666/790] Fix a bug in reusable burst execution. The reusable burst execution incorrectly holds a reference to memory identifier tokens. Bug: 188568523 Test: NNT_static and inspect logcat Change-Id: Ic8fb8be12bf579a316e7df8480ab3ccdc5c0e635 --- neuralnetworks/aidl/utils/src/Burst.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neuralnetworks/aidl/utils/src/Burst.cpp b/neuralnetworks/aidl/utils/src/Burst.cpp index 87cd0e4afe..800ac32944 100644 --- a/neuralnetworks/aidl/utils/src/Burst.cpp +++ b/neuralnetworks/aidl/utils/src/Burst.cpp @@ -62,7 +62,7 @@ class BurstExecution final : public nn::IExecution, private: const std::shared_ptr kBurst; const Request kRequest; - const std::vector& kMemoryIdentifierTokens; + const std::vector kMemoryIdentifierTokens; const bool kMeasure; const int64_t kLoopTimeoutDuration; const hal::utils::RequestRelocation kRelocation; -- GitLab From 86a518cfa64fdc85ab349701e79f8adf7efdacd2 Mon Sep 17 00:00:00 2001 From: Steven Moreland Date: Thu, 20 May 2021 23:51:38 +0000 Subject: [PATCH 667/790] freeze compat matrix 6 for Android S The current matrix is left in this same CL because this way, downstream modifications to the current CL will automatically get absorbed into the level 7 compatibility matrix. A CL on top of this will disable the 7 matrix and then get reverted in the aosp/master..goog/master merge path. Bug: 178221726 Test: boot device, vts_treble_vintf_vendor_test Test: inspect matrix by diffing matrix with old matrix using: m analyze_matrix && system/libvintf/analyze_matrix/hals_for_release.py Change-Id: Id83986fc5089eefc2292f0042753f739f4e01a44 --- compatibility_matrices/Android.bp | 13 + compatibility_matrices/Android.mk | 1 + .../compatibility_matrix.6.xml | 650 ++++++++++++++++++ .../compatibility_matrix.current.xml | 2 +- 4 files changed, 665 insertions(+), 1 deletion(-) create mode 100644 compatibility_matrices/compatibility_matrix.6.xml diff --git a/compatibility_matrices/Android.bp b/compatibility_matrices/Android.bp index 314a809228..da55347d25 100644 --- a/compatibility_matrices/Android.bp +++ b/compatibility_matrices/Android.bp @@ -60,6 +60,19 @@ vintf_compatibility_matrix { ], } +vintf_compatibility_matrix { + name: "framework_compatibility_matrix.6.xml", + stem: "compatibility_matrix.6.xml", + srcs: [ + "compatibility_matrix.6.xml", + ], + kernel_configs: [ + "kernel_config_s_4.19", + "kernel_config_s_5.4", + "kernel_config_s_5.10", + ], +} + vintf_compatibility_matrix { name: "framework_compatibility_matrix.current.xml", stem: "compatibility_matrix.current.xml", diff --git a/compatibility_matrices/Android.mk b/compatibility_matrices/Android.mk index 85c8ca01a7..9e715bf37d 100644 --- a/compatibility_matrices/Android.mk +++ b/compatibility_matrices/Android.mk @@ -101,6 +101,7 @@ my_system_matrix_deps := \ framework_compatibility_matrix.3.xml \ framework_compatibility_matrix.4.xml \ framework_compatibility_matrix.5.xml \ + framework_compatibility_matrix.6.xml \ framework_compatibility_matrix.current.xml \ framework_compatibility_matrix.device.xml \ diff --git a/compatibility_matrices/compatibility_matrix.6.xml b/compatibility_matrices/compatibility_matrix.6.xml new file mode 100644 index 0000000000..01cd1f6c68 --- /dev/null +++ b/compatibility_matrices/compatibility_matrix.6.xml @@ -0,0 +1,650 @@ + + + android.hardware.atrace + 1.0 + + IAtraceDevice + default + + + + android.hardware.audio + 6.0 + 7.0 + + IDevicesFactory + default + + + + android.hardware.audio.effect + 6.0 + 7.0 + + IEffectsFactory + default + + + + android.hardware.authsecret + 1 + + IAuthSecret + default + + + + android.hardware.authsecret + 1.0 + + IAuthSecret + default + + + + android.hardware.automotive.audiocontrol + + IAudioControl + default + + + + android.hardware.automotive.can + 1.0 + + ICanBus + .* + + + ICanController + .* + + + + android.hardware.automotive.evs + 1.0-1 + + IEvsEnumerator + default + [a-z]+/[0-9]+ + + + + android.hardware.automotive.occupant_awareness + 1 + + IOccupantAwareness + default + + + + android.hardware.automotive.sv + 1.0 + + ISurroundViewService + default + + + + android.hardware.automotive.vehicle + 2.0 + + IVehicle + default + + + + android.hardware.biometrics.face + 1.0 + + IBiometricsFace + default + + + + android.hardware.biometrics.face + + IFace + default + + + + android.hardware.biometrics.fingerprint + 2.1-3 + + IBiometricsFingerprint + default + + + + android.hardware.biometrics.fingerprint + + IFingerprint + default + + + + android.hardware.bluetooth + 1.0-1 + + IBluetoothHci + default + + + + android.hardware.bluetooth.audio + 2.0-1 + + IBluetoothAudioProvidersFactory + default + + + + android.hardware.boot + 1.2 + + IBootControl + default + + + + android.hardware.broadcastradio + 1.0-1 + + IBroadcastRadioFactory + default + + + + android.hardware.broadcastradio + 2.0 + + IBroadcastRadio + .* + + + + android.hardware.camera.provider + 2.4-7 + + ICameraProvider + [^/]+/[0-9]+ + + + + android.hardware.cas + 1.1-2 + + IMediaCasService + default + + + + android.hardware.confirmationui + 1.0 + + IConfirmationUI + default + + + + android.hardware.contexthub + 1.2 + + IContexthub + default + + + + android.hardware.drm + 1.3-4 + + ICryptoFactory + .* + + + IDrmFactory + .* + + + + android.hardware.dumpstate + 1.1 + + IDumpstateDevice + default + + + + android.hardware.gatekeeper + 1.0 + + IGatekeeper + default + + + + android.hardware.gnss + 2.0-1 + + IGnss + default + + + + android.hardware.gnss + + IGnss + default + + + + android.hardware.graphics.allocator + + 2.0 + 3.0 + 4.0 + + IAllocator + default + + + + android.hardware.graphics.composer + 2.1-4 + + IComposer + default + + + + android.hardware.graphics.mapper + + 2.1 + 3.0 + 4.0 + + IMapper + default + + + + android.hardware.health + 2.1 + + IHealth + default + + + + android.hardware.health.storage + 1 + + IStorage + default + + + + android.hardware.identity + 1-3 + + IIdentityCredentialStore + default + + + + android.hardware.oemlock + 1 + + IOemLock + default + + + + android.hardware.ir + 1.0 + + IConsumerIr + default + + + + android.hardware.input.classifier + 1.0 + + IInputClassifier + default + + + + android.hardware.keymaster + 3.0 + 4.0-1 + + IKeymasterDevice + default + + + + android.hardware.keymaster + 4.0-1 + + IKeymasterDevice + strongbox + + + + android.hardware.security.keymint + 1 + + IKeyMintDevice + default + strongbox + + + + android.hardware.security.keymint + + IRemotelyProvisionedComponent + default + + + + android.hardware.light + 1 + + ILights + default + + + + android.hardware.media.c2 + 1.0-2 + + IComponentStore + default[0-9]* + vendor[0-9]*_software + + + + android.hardware.media.omx + 1.0 + + IOmx + default + + + IOmxStore + default + + + + android.hardware.memtrack + 1 + + IMemtrack + default + + + + android.hardware.neuralnetworks + 1.0-3 + + IDevice + .* + + + + android.hardware.neuralnetworks + + IDevice + .* + + + + android.hardware.nfc + 1.2 + + INfc + default + + + + android.hardware.oemlock + 1.0 + + IOemLock + default + + + + android.hardware.power + 1-2 + + IPower + default + + + + android.hardware.power.stats + + IPowerStats + default + + + + android.hardware.radio + 1.6 + + IRadio + slot1 + slot2 + slot3 + + + + android.hardware.radio + 1.2 + + ISap + slot1 + + + + android.hardware.radio.config + + 1.1 + + IRadioConfig + default + + + + android.hardware.radio.config + 1.3 + + IRadioConfig + default + + + + android.hardware.renderscript + 1.0 + + IDevice + default + + + + android.hardware.rebootescrow + 1 + + IRebootEscrow + default + + + + android.hardware.secure_element + 1.0-2 + + ISecureElement + eSE[1-9][0-9]* + SIM[1-9][0-9]* + + + + android.hardware.security.secureclock + 1 + + ISecureClock + default + + + + android.hardware.security.sharedsecret + 1 + + ISharedSecret + default + + + + android.hardware.sensors + 1.0 + 2.0-1 + + ISensors + default + + + + android.hardware.soundtrigger + 2.3 + + ISoundTriggerHw + default + + + + android.hardware.tetheroffload.config + 1.0 + + IOffloadConfig + default + + + + android.hardware.tetheroffload.control + 1.1 + + IOffloadControl + default + + + + android.hardware.thermal + 2.0 + + IThermal + default + + + + android.hardware.tv.cec + 1.0-1 + + IHdmiCec + default + + + + android.hardware.tv.input + 1.0 + + ITvInput + default + + + + android.hardware.tv.tuner + 1.0-1 + + ITuner + default + + + + android.hardware.usb + 1.0-3 + + IUsb + default + + + + android.hardware.usb.gadget + 1.0-2 + + IUsbGadget + default + + + + android.hardware.vibrator + 1-2 + + IVibrator + default + + + + android.hardware.vibrator + 1-2 + + IVibratorManager + default + + + + android.hardware.weaver + 1.0 + + IWeaver + default + + + + android.hardware.weaver + 1 + + IWeaver + default + + + + android.hardware.wifi + 1.3-5 + + IWifi + default + + + + android.hardware.wifi.hostapd + 1.0-3 + + IHostapd + default + + + + android.hardware.wifi.supplicant + 1.2-4 + + ISupplicant + default + + + diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index 01cd1f6c68..3b84b6ebf7 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -1,4 +1,4 @@ - + android.hardware.atrace 1.0 -- GitLab From e0bb84be37c5acc8ff84ad657242eca075a75726 Mon Sep 17 00:00:00 2001 From: Steven Moreland Date: Fri, 21 May 2021 00:34:09 +0000 Subject: [PATCH 668/790] DO NOT MERGE: Disable current matrix. The current matrix should not be used in Android S. However, it is left here so that any late fixes to the S matrix can be made in a way that will flow downstream. Reason for 'DO NOT MERGE' - avoid landing this change in goog/master, since the current matrix has HALs added there, some devices may be relying on it. In order to allow the (AOSP subset of) the S manifest to be frozen in AOSP, and the current matrix to be enabled from aosp/master -..-> goog/master, this will be reverted in sc-dev-plus-aosp immediately after it merges. Bug: 178221726 Test: boot devices and vts_treble_vintf_vendor_test passes Change-Id: I5716db7cfd629527dd33daac94244e5df41520f5 --- compatibility_matrices/Android.bp | 1 + compatibility_matrices/Android.mk | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/compatibility_matrices/Android.bp b/compatibility_matrices/Android.bp index da55347d25..31fa1ae403 100644 --- a/compatibility_matrices/Android.bp +++ b/compatibility_matrices/Android.bp @@ -75,6 +75,7 @@ vintf_compatibility_matrix { vintf_compatibility_matrix { name: "framework_compatibility_matrix.current.xml", + enabled: false, stem: "compatibility_matrix.current.xml", srcs: [ "compatibility_matrix.current.xml", diff --git a/compatibility_matrices/Android.mk b/compatibility_matrices/Android.mk index 9e715bf37d..4cefb5506e 100644 --- a/compatibility_matrices/Android.mk +++ b/compatibility_matrices/Android.mk @@ -102,7 +102,6 @@ my_system_matrix_deps := \ framework_compatibility_matrix.4.xml \ framework_compatibility_matrix.5.xml \ framework_compatibility_matrix.6.xml \ - framework_compatibility_matrix.current.xml \ framework_compatibility_matrix.device.xml \ my_framework_matrix_deps += \ -- GitLab From 216d99293f95fbbc57e84a8f1a37d0e82a36fe92 Mon Sep 17 00:00:00 2001 From: David Drysdale Date: Tue, 18 May 2021 11:43:31 +0100 Subject: [PATCH 669/790] KeyMint: improve HAL spec and tests - clarify & test BIGNUM spec - allow alternative return codes when requesting device unique attestation - use specific error for early boot import failure - test more early boot key scenarios (in post-early-boot mode) Bug: 188672564 Test: VtsAidlKeyMintTargetTest Merged-In: I70a342084a29144aef1ed0ff80fec02cc06ffbc0 Change-Id: I70a342084a29144aef1ed0ff80fec02cc06ffbc0 --- .../hardware/security/keymint/Tag.aidl | 2 +- .../hardware/security/keymint/TagType.aidl | 16 +++++++- .../aidl/vts/functional/AttestKeyTest.cpp | 6 ++- .../DeviceUniqueAttestationTest.cpp | 4 +- .../vts/functional/KeyMintAidlTestBase.cpp | 8 ++++ .../aidl/vts/functional/KeyMintTest.cpp | 41 +++++++++++++++++++ 6 files changed, 71 insertions(+), 6 deletions(-) diff --git a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl index 66f79ce041..4ff4574b58 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl @@ -234,7 +234,7 @@ enum Tag { * IKeyMintDevice::earlyBootEnded() is called. Early boot keys may be created after * early boot. Early boot keys may not be imported at all, if Tag::EARLY_BOOT_ONLY is * provided to IKeyMintDevice::importKey, the import must fail with - * ErrorCode::INVALID_ARGUMENT. + * ErrorCode::EARLY_BOOT_ENDED. */ EARLY_BOOT_ONLY = (7 << 28) /* TagType:BOOL */ | 305, diff --git a/security/keymint/aidl/android/hardware/security/keymint/TagType.aidl b/security/keymint/aidl/android/hardware/security/keymint/TagType.aidl index 1ba6ededf2..d46e504178 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/TagType.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/TagType.aidl @@ -39,7 +39,21 @@ enum TagType { DATE = 6 << 28, /** Boolean. If a tag with this type is present, the value is "true". If absent, "false". */ BOOL = 7 << 28, - /** Byte string containing an arbitrary-length integer, big-endian ordering. */ + /** + * Byte string containing an arbitrary-length integer, in a two's-complement big-endian + * ordering. The byte array contains the minimum number of bytes needed to represent the + * integer, including at least one sign bit (so zero encodes as the single byte 0x00. This + * matches the encoding of both java.math.BigInteger.toByteArray() and contents octets for an + * ASN.1 INTEGER value (X.690 section 8.3). Examples: + * - value 65536 encodes as 0x01 0x00 0x00 + * - value 65535 encodes as 0x00 0xFF 0xFF + * - value 255 encodes as 0x00 0xFF + * - value 1 encodes as 0x01 + * - value 0 encodes as 0x00 + * - value -1 encodes as 0xFF + * - value -255 encodes as 0xFF 0x01 + * - value -256 encodes as 0xFF 0x00 + */ BIGNUM = 8 << 28, /** Byte string */ BYTES = 9 << 28, diff --git a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp index 881354d41d..76f0a2475a 100644 --- a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp +++ b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp @@ -180,7 +180,9 @@ TEST_P(AttestKeyTest, RsaAttestedAttestKeys) { auto subject = "cert subj 2"; vector subject_der(make_name_from_str(subject)); - uint64_t serial_int = 66; + // An X.509 certificate serial number SHOULD be >0, but this is not policed. Check + // that a zero value doesn't cause problems. + uint64_t serial_int = 0; vector serial_blob(build_serial_blob(serial_int)); /* @@ -223,7 +225,7 @@ TEST_P(AttestKeyTest, RsaAttestedAttestKeys) { auto subject2 = "cert subject"; vector subject_der2(make_name_from_str(subject2)); - uint64_t serial_int2 = 987; + uint64_t serial_int2 = 255; vector serial_blob2(build_serial_blob(serial_int2)); EXPECT_EQ(ErrorCode::OK, diff --git a/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp b/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp index 6f0ee4e74d..b0f056a68c 100644 --- a/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp +++ b/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp @@ -75,7 +75,7 @@ TEST_P(DeviceUniqueAttestationTest, RsaNonStrongBoxUnimplemented) { .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION), &key_blob, &key_characteristics); - ASSERT_EQ(result, ErrorCode::INVALID_ARGUMENT); + ASSERT_TRUE(result == ErrorCode::INVALID_ARGUMENT || result == ErrorCode::UNSUPPORTED_TAG); } /* @@ -101,7 +101,7 @@ TEST_P(DeviceUniqueAttestationTest, EcdsaNonStrongBoxUnimplemented) { .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION), &key_blob, &key_characteristics); - ASSERT_EQ(result, ErrorCode::INVALID_ARGUMENT); + ASSERT_TRUE(result == ErrorCode::INVALID_ARGUMENT || result == ErrorCode::UNSUPPORTED_TAG); } /* diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp index 8c4e0c3f25..305364a275 100644 --- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp +++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp @@ -1185,6 +1185,14 @@ vector build_serial_blob(const uint64_t serial_int) { return {}; } + if (serial_blob.empty() || serial_blob[0] & 0x80) { + // An empty blob is OpenSSL's encoding of the zero value; we need single zero byte. + // Top bit being set indicates a negative number in two's complement, but our input + // was positive. + // In either case, prepend a zero byte. + serial_blob.insert(serial_blob.begin(), 0x00); + } + return serial_blob; } diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp index 293a010f50..349f44a9fe 100644 --- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp +++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp @@ -6320,7 +6320,13 @@ INSTANTIATE_KEYMINT_AIDL_TEST(DestroyAttestationIdsTest); using EarlyBootKeyTest = KeyMintAidlTestBase; +/* + * EarlyBootKeyTest.CreateEarlyBootKeys + * + * Verifies that creating early boot keys succeeds, even at a later stage (after boot). + */ TEST_P(EarlyBootKeyTest, CreateEarlyBootKeys) { + // Early boot keys can be created after early boot. auto [aesKeyData, hmacKeyData, rsaKeyData, ecdsaKeyData] = CreateTestKeys(TAG_EARLY_BOOT_ONLY, ErrorCode::OK); @@ -6330,6 +6336,41 @@ TEST_P(EarlyBootKeyTest, CreateEarlyBootKeys) { CheckedDeleteKey(&ecdsaKeyData.blob); } +/* + * EarlyBootKeyTest.UsetEarlyBootKeyFailure + * + * Verifies that using early boot keys at a later stage fails. + */ +TEST_P(EarlyBootKeyTest, UseEarlyBootKeyFailure) { + ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() + .Authorization(TAG_NO_AUTH_REQUIRED) + .Authorization(TAG_EARLY_BOOT_ONLY) + .HmacKey(128) + .Digest(Digest::SHA_2_256) + .Authorization(TAG_MIN_MAC_LENGTH, 256))); + AuthorizationSet output_params; + EXPECT_EQ(ErrorCode::EARLY_BOOT_ENDED, Begin(KeyPurpose::SIGN, key_blob_, + AuthorizationSetBuilder() + .Digest(Digest::SHA_2_256) + .Authorization(TAG_MAC_LENGTH, 256), + &output_params)); +} + +/* + * EarlyBootKeyTest.ImportEarlyBootKeyFailure + * + * Verifies that importing early boot keys fails. + */ +TEST_P(EarlyBootKeyTest, ImportEarlyBootKeyFailure) { + ASSERT_EQ(ErrorCode::EARLY_BOOT_ENDED, ImportKey(AuthorizationSetBuilder() + .Authorization(TAG_NO_AUTH_REQUIRED) + .Authorization(TAG_EARLY_BOOT_ONLY) + .EcdsaSigningKey(256) + .Digest(Digest::SHA_2_256) + .SetDefaultValidity(), + KeyFormat::PKCS8, ec_256_key)); +} + // This is a more comprehensive test, but it can only be run on a machine which is still in early // boot stage, which no proper Android device is by the time we can run VTS. To use this, // un-disable it and modify vold to remove the call to earlyBootEnded(). Running the test will end -- GitLab From 96f878f4ee64b5dac5cb20f087906cf757f10b9e Mon Sep 17 00:00:00 2001 From: Steven Moreland Date: Fri, 21 May 2021 18:19:36 +0000 Subject: [PATCH 670/790] Revert "Disable current matrix." This reverts commit e0bb84be37c5acc8ff84ad657242eca075a75726. Reason for revert: needs to be reverted in sc-dev-plus-aosp and below to re-enable the T matrix on aosp/master-..->goog/master Change-Id: I538533d21e624f8ee5a392d0ee7618ee0969ec87 Merged-In: I4525301ad1205cf41937a98b7b9f67f052cb5bd9 --- compatibility_matrices/Android.bp | 1 - compatibility_matrices/Android.mk | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/compatibility_matrices/Android.bp b/compatibility_matrices/Android.bp index 31fa1ae403..da55347d25 100644 --- a/compatibility_matrices/Android.bp +++ b/compatibility_matrices/Android.bp @@ -75,7 +75,6 @@ vintf_compatibility_matrix { vintf_compatibility_matrix { name: "framework_compatibility_matrix.current.xml", - enabled: false, stem: "compatibility_matrix.current.xml", srcs: [ "compatibility_matrix.current.xml", diff --git a/compatibility_matrices/Android.mk b/compatibility_matrices/Android.mk index 4cefb5506e..9e715bf37d 100644 --- a/compatibility_matrices/Android.mk +++ b/compatibility_matrices/Android.mk @@ -102,6 +102,7 @@ my_system_matrix_deps := \ framework_compatibility_matrix.4.xml \ framework_compatibility_matrix.5.xml \ framework_compatibility_matrix.6.xml \ + framework_compatibility_matrix.current.xml \ framework_compatibility_matrix.device.xml \ my_framework_matrix_deps += \ -- GitLab From dfc013adaa13cae38393279a98a3753a44814827 Mon Sep 17 00:00:00 2001 From: Xusong Wang Date: Fri, 21 May 2021 14:58:40 -0700 Subject: [PATCH 671/790] Test readonly request input in AIDL VTS. This CL modifies the AIDL generated tests to use readonly memory pool for request inputs. Bug: 188104713 Test: VtsHalNeuralnetworksTargetTest Change-Id: I9e62f1cdeb501bf29bcb9c56317a452c9105b272 --- .../vts/functional/GeneratedTestHarness.cpp | 4 +-- neuralnetworks/aidl/vts/functional/Utils.cpp | 29 ++++++++++++++++--- neuralnetworks/aidl/vts/functional/Utils.h | 9 ++++-- 3 files changed, 33 insertions(+), 9 deletions(-) diff --git a/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp index d3b041ddf7..2356ff0520 100644 --- a/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp +++ b/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp @@ -435,8 +435,8 @@ std::optional ExecutionContext::createRequest(const TestModel& testMode mInputMemory = TestBlobAHWB::create(std::max(inputSize, 1)); mOutputMemory = TestBlobAHWB::create(std::max(outputSize, 1)); } else { - mInputMemory = TestAshmem::create(std::max(inputSize, 1)); - mOutputMemory = TestAshmem::create(std::max(outputSize, 1)); + mInputMemory = TestAshmem::create(std::max(inputSize, 1), /*aidlReadonly=*/true); + mOutputMemory = TestAshmem::create(std::max(outputSize, 1), /*aidlReadonly=*/false); } CHECK_NE(mInputMemory, nullptr); CHECK_NE(mOutputMemory, nullptr); diff --git a/neuralnetworks/aidl/vts/functional/Utils.cpp b/neuralnetworks/aidl/vts/functional/Utils.cpp index 3c7f5f797d..9af362ea8a 100644 --- a/neuralnetworks/aidl/vts/functional/Utils.cpp +++ b/neuralnetworks/aidl/vts/functional/Utils.cpp @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -98,19 +99,39 @@ uint32_t sizeOfData(const Operand& operand) { std::multiplies<>{}); } -std::unique_ptr TestAshmem::create(uint32_t size) { - auto ashmem = std::make_unique(size); +std::unique_ptr TestAshmem::create(uint32_t size, bool aidlReadonly) { + auto ashmem = std::make_unique(size, aidlReadonly); return ashmem->mIsValid ? std::move(ashmem) : nullptr; } -void TestAshmem::initialize(uint32_t size) { +// This function will create a readonly shared memory with PROT_READ only. +// The input shared memory must be either Ashmem or mapped-FD. +static nn::SharedMemory convertSharedMemoryToReadonly(const nn::SharedMemory& sharedMemory) { + if (std::holds_alternative(sharedMemory->handle)) { + const auto& memory = std::get(sharedMemory->handle); + return nn::createSharedMemoryFromFd(memory.size, PROT_READ, memory.fd.get(), /*offset=*/0) + .value(); + } else if (std::holds_alternative(sharedMemory->handle)) { + const auto& memory = std::get(sharedMemory->handle); + return nn::createSharedMemoryFromFd(memory.size, PROT_READ, memory.fd.get(), memory.offset) + .value(); + } + CHECK(false) << "Unexpected shared memory type"; + return sharedMemory; +} + +void TestAshmem::initialize(uint32_t size, bool aidlReadonly) { mIsValid = false; ASSERT_GT(size, 0); const auto sharedMemory = nn::createSharedMemory(size).value(); mMappedMemory = nn::map(sharedMemory).value(); mPtr = static_cast(std::get(mMappedMemory.pointer)); CHECK_NE(mPtr, nullptr); - mAidlMemory = utils::convert(sharedMemory).value(); + if (aidlReadonly) { + mAidlMemory = utils::convert(convertSharedMemoryToReadonly(sharedMemory)).value(); + } else { + mAidlMemory = utils::convert(sharedMemory).value(); + } mIsValid = true; } diff --git a/neuralnetworks/aidl/vts/functional/Utils.h b/neuralnetworks/aidl/vts/functional/Utils.h index 77085a75ef..9dd73592dd 100644 --- a/neuralnetworks/aidl/vts/functional/Utils.h +++ b/neuralnetworks/aidl/vts/functional/Utils.h @@ -79,15 +79,18 @@ class TestMemoryBase { class TestAshmem : public TestMemoryBase { public: - static std::unique_ptr create(uint32_t size); + // If aidlReadonly is true, getAidlMemory will return a sAIDL memory with readonly access; + // otherwise, the sAIDL memory has read-write access. This only affects the sAIDL memory. + // getPointer will always return a valid address with read-write access. + static std::unique_ptr create(uint32_t size, bool aidlReadonly = false); // Prefer TestAshmem::create. // The constructor calls initialize, which constructs the memory resources. This is a workaround // that gtest macros cannot be used directly in a constructor. - TestAshmem(uint32_t size) { initialize(size); } + TestAshmem(uint32_t size, bool aidlReadonly) { initialize(size, aidlReadonly); } private: - void initialize(uint32_t size); + void initialize(uint32_t size, bool aidlReadonly); nn::Mapping mMappedMemory; }; -- GitLab From 77e2a67536cd1b90a87c43c0bea75f3b78b6496b Mon Sep 17 00:00:00 2001 From: Aaron Tsai Date: Fri, 21 May 2021 12:35:34 +0800 Subject: [PATCH 672/790] Fix emergencyDial tests in VTS 1.6 cherry-pick from aosp/1708089 - Change to calling getVoiceRegistrationState_1_6() instead of getVoiceRegistrationState(). - Fix incorrect voice registration state value Bug: 187488263 Test: atest VtsHalRadioV1_6TargetTest Merged-In: Iebf32061c7944104a8d4a0297af9204ca214e627 Merged-In: Ic2745c48b3d3451e5065a77054d9e7b930ea4ce5 Merged-In: I787ead62a70acd69a4676d5e53509fe2ff6b0fd8 Change-Id: I0a04238f03c7d4fe1eae00c33c18d6dd9da610a8 --- radio/1.6/vts/functional/radio_hidl_hal_api.cpp | 6 +++--- radio/1.6/vts/functional/radio_response.cpp | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp index 5af007e86d..de18279474 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp +++ b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp @@ -599,7 +599,7 @@ TEST_P(RadioHidlTest_v1_6, emergencyDial_1_6) { // or Emergency_Only. if (isDsDsEnabled() || isTsTsEnabled()) { serial = GetRandomSerialNumber(); - radio_v1_6->getVoiceRegistrationState(serial); + radio_v1_6->getVoiceRegistrationState_1_6(serial); EXPECT_EQ(std::cv_status::no_timeout, wait()); if (isVoiceEmergencyOnly(radioRsp_v1_6->voiceRegResp.regState) || isVoiceInService(radioRsp_v1_6->voiceRegResp.regState)) { @@ -653,7 +653,7 @@ TEST_P(RadioHidlTest_v1_6, emergencyDial_1_6_withServices) { // or Emergency_Only. if (isDsDsEnabled() || isTsTsEnabled()) { serial = GetRandomSerialNumber(); - radio_v1_6->getVoiceRegistrationState(serial); + radio_v1_6->getVoiceRegistrationState_1_6(serial); EXPECT_EQ(std::cv_status::no_timeout, wait()); if (isVoiceEmergencyOnly(radioRsp_v1_6->voiceRegResp.regState) || isVoiceInService(radioRsp_v1_6->voiceRegResp.regState)) { @@ -706,7 +706,7 @@ TEST_P(RadioHidlTest_v1_6, emergencyDial_1_6_withEmergencyRouting) { // or Emergency_Only. if (isDsDsEnabled() || isTsTsEnabled()) { serial = GetRandomSerialNumber(); - radio_v1_6->getVoiceRegistrationState(serial); + radio_v1_6->getVoiceRegistrationState_1_6(serial); EXPECT_EQ(std::cv_status::no_timeout, wait()); if (isVoiceEmergencyOnly(radioRsp_v1_6->voiceRegResp.regState) || isVoiceInService(radioRsp_v1_6->voiceRegResp.regState)) { diff --git a/radio/1.6/vts/functional/radio_response.cpp b/radio/1.6/vts/functional/radio_response.cpp index 6e7b86f5dd..b1e679b35b 100644 --- a/radio/1.6/vts/functional/radio_response.cpp +++ b/radio/1.6/vts/functional/radio_response.cpp @@ -1209,8 +1209,9 @@ Return RadioResponse_v1_6::getSystemSelectionChannelsResponse( Return RadioResponse_v1_6::getVoiceRegistrationStateResponse_1_6( const ::android::hardware::radio::V1_6::RadioResponseInfo& info, - const ::android::hardware::radio::V1_6::RegStateResult& /*regResponse*/) { + const ::android::hardware::radio::V1_6::RegStateResult& regResponse) { rspInfo = info; + voiceRegResp.regState = regResponse.regState; parent_v1_6.notify(info.serial); return Void(); } -- GitLab From 38dd36eaa81027112b66e4ba38adf61f64934278 Mon Sep 17 00:00:00 2001 From: Max Bires Date: Sun, 23 May 2021 15:06:23 -0700 Subject: [PATCH 673/790] Shifting VTS libs to static_lib entry If these HALs aren't present on the device, then the test runner will fail due to test binary trying to dynamically link to libs that aren't present. Statically linking them will allow the test to fail gracefully when the test harness sees that the HAL interfaces aren't available on device. Fixes: 184797684 Test: atest VtsAidlKeyMintTargetTest Change-Id: I0f8dea081a51256cfb0e50d6af20038e2b8f1f07 --- security/keymint/aidl/vts/functional/Android.bp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/security/keymint/aidl/vts/functional/Android.bp b/security/keymint/aidl/vts/functional/Android.bp index d5c45e26ed..ff08ce626e 100644 --- a/security/keymint/aidl/vts/functional/Android.bp +++ b/security/keymint/aidl/vts/functional/Android.bp @@ -37,15 +37,15 @@ cc_test { shared_libs: [ "libbinder_ndk", "libcrypto", - "libkeymint", - "libkeymint_support", ], static_libs: [ "android.hardware.security.keymint-V1-ndk_platform", "android.hardware.security.secureclock-V1-ndk_platform", "libcppbor_external", "libcppcose_rkp", + "libkeymint", "libkeymint_remote_prov_support", + "libkeymint_support", "libkeymint_vts_test_utils", ], test_suites: [ @@ -69,8 +69,6 @@ cc_test_library { shared_libs: [ "libbinder_ndk", "libcrypto", - "libkeymint", - "libkeymint_support", ], static_libs: [ "android.hardware.security.keymint-V1-ndk_platform", @@ -78,7 +76,9 @@ cc_test_library { "libcppbor_external", "libcppcose_rkp", "libgmock_ndk", + "libkeymint", "libkeymint_remote_prov_support", + "libkeymint_support", ], } -- GitLab From 7735ba5ea97f87329ce1adb65acd4fc58722f7fd Mon Sep 17 00:00:00 2001 From: Seth Moore Date: Fri, 30 Apr 2021 11:41:18 -0700 Subject: [PATCH 674/790] Generate COSE MAC with a callback, not raw key The cppcose_rkp library was updated to generate MAC via callback instead of passing keys around to allow for stronger MAC key protection. Bug: 182928606 Test: VtsHalRemotelyProvisionedComponentTargetTest Test: RemoteProvisionerUnitTests Change-Id: Ia8a0410408fe3064e904c5282b52f172f8134b9a --- .../aidl/vts/functional/KeyMintAidlTestBase.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp index 0eac033cd1..a9a67bcc50 100644 --- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp +++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp @@ -44,7 +44,9 @@ using std::unique_ptr; using ::testing::AssertionFailure; using ::testing::AssertionResult; using ::testing::AssertionSuccess; +using ::testing::ElementsAreArray; using ::testing::MatchesRegex; +using ::testing::Not; ::std::ostream& operator<<(::std::ostream& os, const AuthorizationSet& set) { if (set.size() == 0) @@ -1548,14 +1550,17 @@ void check_maced_pubkey(const MacedPublicKey& macedPubKey, bool testMode, EXPECT_EQ(extractedTag.size(), 32U); // Compare with tag generated with kTestMacKey. Should only match in test mode - auto testTag = cppcose::generateCoseMac0Mac(remote_prov::kTestMacKey, {} /* external_aad */, - payload->value()); + auto macFunction = [](const cppcose::bytevec& input) { + return cppcose::generateHmacSha256(remote_prov::kTestMacKey, input); + }; + auto testTag = + cppcose::generateCoseMac0Mac(macFunction, {} /* external_aad */, payload->value()); ASSERT_TRUE(testTag) << "Tag calculation failed: " << testTag.message(); if (testMode) { - EXPECT_EQ(*testTag, extractedTag); + EXPECT_THAT(*testTag, ElementsAreArray(extractedTag)); } else { - EXPECT_NE(*testTag, extractedTag); + EXPECT_THAT(*testTag, Not(ElementsAreArray(extractedTag))); } if (payload_value != nullptr) { *payload_value = payload->value(); -- GitLab From 7435e8d77c36dfce7aabf9b9db13311f6ed4df1b Mon Sep 17 00:00:00 2001 From: Kevin Chyn Date: Mon, 24 May 2021 16:53:53 -0700 Subject: [PATCH 675/790] Add Error::BAD_CALIBRATION Bug: 189133688 Test: make -j56 android.hardware.biometrics.fingerprint-update-api Change-Id: Iea26fa2efb8e60fb5d89e89762dc76f0f0c6dce1 --- .../android/hardware/biometrics/fingerprint/Error.aidl | 1 + .../aidl/android/hardware/biometrics/fingerprint/Error.aidl | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl index 060379d63c..af7bc3c56b 100644 --- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl @@ -42,4 +42,5 @@ enum Error { CANCELED = 5, UNABLE_TO_REMOVE = 6, VENDOR = 7, + BAD_CALIBRATION = 8, } diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/Error.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/Error.aidl index fc89da218a..e69859a442 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/Error.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/Error.aidl @@ -63,4 +63,9 @@ enum Error { * Used to enable vendor-specific error messages. */ VENDOR, + + /** + * There's a problem with the sensor's calibration. + */ + BAD_CALIBRATION, } -- GitLab From 72b63598590474cb758fbe6b5bc85f2328581fd0 Mon Sep 17 00:00:00 2001 From: Jiyong Park Date: Fri, 21 May 2021 11:28:05 +0900 Subject: [PATCH 676/790] Freeze AIDL APIs for SC Ignore-AOSP-First: part of SC finalization Bug: 188713899 Test: m Change-Id: Iee18cd05954dc8ea08cc4f985499a70977d1af4f --- authsecret/aidl/Android.bp | 1 + .../android.hardware.authsecret/1/.hash | 1 + .../hardware/authsecret/IAuthSecret.aidl | 38 +++++ automotive/audiocontrol/aidl/Android.bp | 1 + .../1/.hash | 1 + .../audiocontrol/AudioFocusChange.aidl | 45 ++++++ .../automotive/audiocontrol/DuckingInfo.aidl | 41 ++++++ .../audiocontrol/IAudioControl.aidl | 43 ++++++ .../audiocontrol/IFocusListener.aidl | 39 +++++ .../automotive/audiocontrol/MutingInfo.aidl | 40 +++++ biometrics/common/aidl/Android.bp | 3 +- .../1/.hash | 1 + .../biometrics/common/CommonProps.aidl | 41 ++++++ .../biometrics/common/ComponentInfo.aidl | 42 ++++++ .../common/ICancellationSignal.aidl | 38 +++++ .../biometrics/common/SensorStrength.aidl | 40 +++++ biometrics/face/aidl/Android.bp | 1 + .../android.hardware.biometrics.face/1/.hash | 1 + .../biometrics/face/AcquiredInfo.aidl | 64 ++++++++ .../biometrics/face/AuthenticationFrame.aidl | 38 +++++ .../hardware/biometrics/face/BaseFrame.aidl | 43 ++++++ .../hardware/biometrics/face/Cell.aidl | 40 +++++ .../biometrics/face/EnrollmentFrame.aidl | 40 +++++ .../biometrics/face/EnrollmentStage.aidl | 44 ++++++ .../face/EnrollmentStageConfig.aidl | 39 +++++ .../biometrics/face/EnrollmentType.aidl | 39 +++++ .../hardware/biometrics/face/Error.aidl | 46 ++++++ .../biometrics/face/FaceSensorType.aidl | 40 +++++ .../hardware/biometrics/face/Feature.aidl | 40 +++++ .../hardware/biometrics/face/IFace.aidl | 39 +++++ .../hardware/biometrics/face/ISession.aidl | 51 +++++++ .../biometrics/face/ISessionCallback.aidl | 56 +++++++ .../hardware/biometrics/face/SensorProps.aidl | 47 ++++++ biometrics/fingerprint/aidl/Android.bp | 1 + .../1/.hash | 1 + .../biometrics/fingerprint/AcquiredInfo.aidl | 50 +++++++ .../biometrics/fingerprint/Error.aidl | 46 ++++++ .../fingerprint/FingerprintSensorType.aidl | 43 ++++++ .../biometrics/fingerprint/IFingerprint.aidl | 39 +++++ .../biometrics/fingerprint/ISession.aidl | 51 +++++++ .../fingerprint/ISessionCallback.aidl | 53 +++++++ .../fingerprint/SensorLocation.aidl | 41 ++++++ .../biometrics/fingerprint/SensorProps.aidl | 44 ++++++ common/aidl/Android.bp | 5 +- .../aidl_api/android.hardware.common/2/.hash | 1 + .../2/android/hardware/common/Ashmem.aidl | 39 +++++ .../android/hardware/common/MappableFile.aidl | 41 ++++++ .../android/hardware/common/NativeHandle.aidl | 39 +++++ common/fmq/aidl/Android.bp | 1 + .../android.hardware.common.fmq/1/.hash | 1 + .../common/fmq/GrantorDescriptor.aidl | 40 +++++ .../hardware/common/fmq/MQDescriptor.aidl | 41 ++++++ .../common/fmq/SynchronizedReadWrite.aidl | 38 +++++ .../common/fmq/UnsynchronizedWrite.aidl | 38 +++++ .../common/fmq/GrantorDescriptor.aidl | 15 ++ .../hardware/common/fmq/MQDescriptor.aidl | 17 ++- .../common/fmq/SynchronizedReadWrite.aidl | 15 ++ .../common/fmq/UnsynchronizedWrite.aidl | 15 ++ gnss/aidl/Android.bp | 1 + .../aidl_api/android.hardware.gnss/1/.hash | 1 + .../hardware/gnss/BlocklistedSource.aidl | 39 +++++ .../hardware/gnss/CorrelationVector.aidl | 41 ++++++ .../hardware/gnss/ElapsedRealtime.aidl | 42 ++++++ .../1/android/hardware/gnss/GnssClock.aidl | 55 +++++++ .../hardware/gnss/GnssConstellationType.aidl | 45 ++++++ .../1/android/hardware/gnss/GnssData.aidl | 40 +++++ .../hardware/gnss/GnssMeasurement.aidl | 98 ++++++++++++ .../hardware/gnss/GnssMultipathIndicator.aidl | 40 +++++ .../android/hardware/gnss/GnssPowerStats.aidl | 44 ++++++ .../android/hardware/gnss/GnssSignalType.aidl | 56 +++++++ .../1/android/hardware/gnss/IGnss.aidl | 46 ++++++ .../android/hardware/gnss/IGnssCallback.aidl | 42 ++++++ .../hardware/gnss/IGnssConfiguration.aidl | 51 +++++++ .../gnss/IGnssMeasurementCallback.aidl | 38 +++++ .../gnss/IGnssMeasurementInterface.aidl | 39 +++++ .../hardware/gnss/IGnssPowerIndication.aidl | 39 +++++ .../gnss/IGnssPowerIndicationCallback.aidl | 45 ++++++ .../1/android/hardware/gnss/IGnssPsds.aidl | 39 +++++ .../hardware/gnss/IGnssPsdsCallback.aidl | 38 +++++ .../1/android/hardware/gnss/PsdsType.aidl | 40 +++++ .../hardware/gnss/SatelliteClockInfo.aidl | 40 +++++ .../hardware/gnss/SatellitePositionEcef.aidl | 41 ++++++ .../1/android/hardware/gnss/SatellitePvt.aidl | 46 ++++++ .../hardware/gnss/SatelliteVelocityEcef.aidl | 41 ++++++ graphics/common/aidl/Android.bp | 5 +- .../android.hardware.graphics.common/2/.hash | 1 + .../hardware/graphics/common/BlendMode.aidl | 41 ++++++ .../hardware/graphics/common/BufferUsage.aidl | 63 ++++++++ .../graphics/common/ChromaSiting.aidl | 41 ++++++ .../hardware/graphics/common/Compression.aidl | 39 +++++ .../hardware/graphics/common/Cta861_3.aidl | 39 +++++ .../hardware/graphics/common/Dataspace.aidl | 97 ++++++++++++ .../graphics/common/ExtendableType.aidl | 39 +++++ .../graphics/common/HardwareBuffer.aidl | 39 +++++ .../common/HardwareBufferDescription.aidl | 43 ++++++ .../hardware/graphics/common/Interlaced.aidl | 40 +++++ .../hardware/graphics/common/PixelFormat.aidl | 66 +++++++++ .../hardware/graphics/common/PlaneLayout.aidl | 46 ++++++ .../graphics/common/PlaneLayoutComponent.aidl | 40 +++++ .../common/PlaneLayoutComponentType.aidl | 45 ++++++ .../hardware/graphics/common/Rect.aidl | 41 ++++++ .../hardware/graphics/common/Smpte2086.aidl | 43 ++++++ .../graphics/common/StandardMetadataType.aidl | 59 ++++++++ .../hardware/graphics/common/XyColor.aidl | 39 +++++ health/storage/aidl/Android.bp | 1 + .../android.hardware.health.storage/1/.hash | 1 + .../storage/IGarbageCollectCallback.aidl | 38 +++++ .../hardware/health/storage/IStorage.aidl | 38 +++++ .../hardware/health/storage/Result.aidl | 40 +++++ identity/aidl/Android.bp | 1 + .../android.hardware.identity/3/.hash | 1 + .../hardware/identity/Certificate.aidl | 38 +++++ .../hardware/identity/CipherSuite.aidl | 38 +++++ .../identity/HardwareInformation.aidl | 42 ++++++ .../identity/IIdentityCredential.aidl | 54 +++++++ .../identity/IIdentityCredentialStore.aidl | 53 +++++++ .../identity/IWritableIdentityCredential.aidl | 44 ++++++ .../hardware/identity/RequestDataItem.aidl | 40 +++++ .../hardware/identity/RequestNamespace.aidl | 39 +++++ .../identity/SecureAccessControlProfile.aidl | 43 ++++++ keymaster/aidl/Android.bp | 1 + .../android.hardware.keymaster/3/.hash | 1 + .../hardware/keymaster/HardwareAuthToken.aidl | 43 ++++++ .../keymaster/HardwareAuthenticatorType.aidl | 41 ++++++ .../hardware/keymaster/SecurityLevel.aidl | 40 +++++ .../android/hardware/keymaster/Timestamp.aidl | 38 +++++ .../hardware/keymaster/VerificationToken.aidl | 41 ++++++ memtrack/aidl/Android.bp | 1 + .../android.hardware.memtrack/1/.hash | 1 + .../android/hardware/memtrack/DeviceInfo.aidl | 39 +++++ .../android/hardware/memtrack/IMemtrack.aidl | 39 +++++ .../hardware/memtrack/MemtrackRecord.aidl | 48 ++++++ .../hardware/memtrack/MemtrackType.aidl | 42 ++++++ neuralnetworks/aidl/Android.bp | 1 + .../android.hardware.neuralnetworks/1/.hash | 1 + .../hardware/neuralnetworks/BufferDesc.aidl | 38 +++++ .../hardware/neuralnetworks/BufferRole.aidl | 40 +++++ .../hardware/neuralnetworks/Capabilities.aidl | 42 ++++++ .../hardware/neuralnetworks/DataLocation.aidl | 41 ++++++ .../hardware/neuralnetworks/DeviceBuffer.aidl | 39 +++++ .../hardware/neuralnetworks/DeviceType.aidl | 41 ++++++ .../hardware/neuralnetworks/ErrorStatus.aidl | 46 ++++++ .../neuralnetworks/ExecutionPreference.aidl | 40 +++++ .../neuralnetworks/ExecutionResult.aidl | 40 +++++ .../hardware/neuralnetworks/Extension.aidl | 39 +++++ .../ExtensionNameAndPrefix.aidl | 39 +++++ .../ExtensionOperandTypeInformation.aidl | 40 +++++ .../neuralnetworks/FencedExecutionResult.aidl | 39 +++++ .../neuralnetworks/FusedActivationFunc.aidl | 41 ++++++ .../hardware/neuralnetworks/IBuffer.aidl | 39 +++++ .../hardware/neuralnetworks/IBurst.aidl | 39 +++++ .../hardware/neuralnetworks/IDevice.aidl | 52 +++++++ .../IFencedExecutionCallback.aidl | 38 +++++ .../neuralnetworks/IPreparedModel.aidl | 42 ++++++ .../IPreparedModelCallback.aidl | 38 +++++ .../neuralnetworks/IPreparedModelParcel.aidl | 38 +++++ .../hardware/neuralnetworks/Memory.aidl | 40 +++++ .../hardware/neuralnetworks/Model.aidl | 43 ++++++ .../neuralnetworks/NumberOfCacheFiles.aidl | 39 +++++ .../hardware/neuralnetworks/Operand.aidl | 44 ++++++ .../neuralnetworks/OperandExtraParams.aidl | 39 +++++ .../neuralnetworks/OperandLifeTime.aidl | 44 ++++++ .../neuralnetworks/OperandPerformance.aidl | 39 +++++ .../hardware/neuralnetworks/OperandType.aidl | 53 +++++++ .../hardware/neuralnetworks/Operation.aidl | 40 +++++ .../neuralnetworks/OperationType.aidl | 139 ++++++++++++++++++ .../hardware/neuralnetworks/OutputShape.aidl | 39 +++++ .../neuralnetworks/PerformanceInfo.aidl | 39 +++++ .../hardware/neuralnetworks/Priority.aidl | 40 +++++ .../hardware/neuralnetworks/Request.aidl | 40 +++++ .../neuralnetworks/RequestArgument.aidl | 40 +++++ .../neuralnetworks/RequestMemoryPool.aidl | 39 +++++ .../hardware/neuralnetworks/Subgraph.aidl | 41 ++++++ .../SymmPerChannelQuantParams.aidl | 39 +++++ .../hardware/neuralnetworks/Timing.aidl | 39 +++++ oemlock/aidl/Android.bp | 1 + .../aidl_api/android.hardware.oemlock/1/.hash | 1 + .../1/android/hardware/oemlock/IOemLock.aidl | 42 ++++++ .../hardware/oemlock/OemLockSecureStatus.aidl | 40 +++++ power/aidl/Android.bp | 1 + .../aidl_api/android.hardware.power/2/.hash | 1 + .../2/android/hardware/power/Boost.aidl | 43 ++++++ .../2/android/hardware/power/IPower.aidl | 43 ++++++ .../hardware/power/IPowerHintSession.aidl | 42 ++++++ .../2/android/hardware/power/Mode.aidl | 52 +++++++ .../android/hardware/power/WorkDuration.aidl | 39 +++++ power/stats/aidl/Android.bp | 1 + .../android.hardware.power.stats/1/.hash | 1 + .../android/hardware/power/stats/Channel.aidl | 40 +++++ .../hardware/power/stats/EnergyConsumer.aidl | 41 ++++++ .../stats/EnergyConsumerAttribution.aidl | 39 +++++ .../power/stats/EnergyConsumerResult.aidl | 41 ++++++ .../power/stats/EnergyConsumerType.aidl | 44 ++++++ .../power/stats/EnergyMeasurement.aidl | 41 ++++++ .../hardware/power/stats/IPowerStats.aidl | 43 ++++++ .../hardware/power/stats/PowerEntity.aidl | 40 +++++ .../1/android/hardware/power/stats/State.aidl | 39 +++++ .../hardware/power/stats/StateResidency.aidl | 41 ++++++ .../power/stats/StateResidencyResult.aidl | 39 +++++ security/keymint/aidl/Android.bp | 1 + .../android.hardware.security.keymint/1/.hash | 1 + .../hardware/security/keymint/Algorithm.aidl | 43 ++++++ .../security/keymint/AttestationKey.aidl | 41 ++++++ .../security/keymint/BeginResult.aidl | 41 ++++++ .../hardware/security/keymint/BlockMode.aidl | 42 ++++++ .../security/keymint/Certificate.aidl | 39 +++++ .../hardware/security/keymint/DeviceInfo.aidl | 39 +++++ .../hardware/security/keymint/Digest.aidl | 45 ++++++ .../hardware/security/keymint/EcCurve.aidl | 42 ++++++ .../hardware/security/keymint/ErrorCode.aidl | 125 ++++++++++++++++ .../security/keymint/HardwareAuthToken.aidl | 44 ++++++ .../keymint/HardwareAuthenticatorType.aidl | 42 ++++++ .../security/keymint/IKeyMintDevice.aidl | 53 +++++++ .../security/keymint/IKeyMintOperation.aidl | 42 ++++++ .../IRemotelyProvisionedComponent.aidl | 46 ++++++ .../security/keymint/KeyCharacteristics.aidl | 40 +++++ .../security/keymint/KeyCreationResult.aidl | 41 ++++++ .../hardware/security/keymint/KeyFormat.aidl | 41 ++++++ .../security/keymint/KeyMintHardwareInfo.aidl | 43 ++++++ .../hardware/security/keymint/KeyOrigin.aidl | 43 ++++++ .../security/keymint/KeyParameter.aidl | 40 +++++ .../security/keymint/KeyParameterValue.aidl | 53 +++++++ .../hardware/security/keymint/KeyPurpose.aidl | 45 ++++++ .../security/keymint/MacedPublicKey.aidl | 39 +++++ .../security/keymint/PaddingMode.aidl | 44 ++++++ .../security/keymint/ProtectedData.aidl | 39 +++++ .../security/keymint/RpcHardwareInfo.aidl | 44 ++++++ .../security/keymint/SecurityLevel.aidl | 42 ++++++ .../hardware/security/keymint/Tag.aidl | 103 +++++++++++++ .../hardware/security/keymint/TagType.aidl | 49 ++++++ security/secureclock/aidl/Android.bp | 1 + .../1/.hash | 1 + .../security/secureclock/ISecureClock.aidl | 39 +++++ .../security/secureclock/TimeStampToken.aidl | 41 ++++++ .../security/secureclock/Timestamp.aidl | 39 +++++ security/sharedsecret/aidl/Android.bp | 1 + .../1/.hash | 1 + .../security/sharedsecret/ISharedSecret.aidl | 41 ++++++ .../sharedsecret/SharedSecretParameters.aidl | 40 +++++ tests/extension/vibrator/aidl/Android.bp | 2 +- .../extension/vibrator/aidl/client/Android.bp | 4 +- vibrator/aidl/Android.bp | 5 +- .../android.hardware.vibrator/2/.hash | 1 + .../android/hardware/vibrator/ActivePwle.aidl | 42 ++++++ .../2/android/hardware/vibrator/Braking.aidl | 39 +++++ .../hardware/vibrator/BrakingPwle.aidl | 39 +++++ .../hardware/vibrator/CompositeEffect.aidl | 40 +++++ .../hardware/vibrator/CompositePrimitive.aidl | 46 ++++++ .../2/android/hardware/vibrator/Effect.aidl | 59 ++++++++ .../hardware/vibrator/EffectStrength.aidl | 40 +++++ .../android/hardware/vibrator/IVibrator.aidl | 72 +++++++++ .../hardware/vibrator/IVibratorCallback.aidl | 38 +++++ .../hardware/vibrator/IVibratorManager.aidl | 51 +++++++ .../hardware/vibrator/PrimitivePwle.aidl | 39 +++++ weaver/aidl/Android.bp | 1 + .../aidl_api/android.hardware.weaver/1/.hash | 1 + .../1/android/hardware/weaver/IWeaver.aidl | 43 ++++++ .../android/hardware/weaver/WeaverConfig.aidl | 40 +++++ .../hardware/weaver/WeaverReadResponse.aidl | 39 +++++ 259 files changed, 9350 insertions(+), 8 deletions(-) create mode 100644 authsecret/aidl/aidl_api/android.hardware.authsecret/1/.hash create mode 100644 authsecret/aidl/aidl_api/android.hardware.authsecret/1/android/hardware/authsecret/IAuthSecret.aidl create mode 100644 automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/1/.hash create mode 100644 automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/1/android/hardware/automotive/audiocontrol/AudioFocusChange.aidl create mode 100644 automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/1/android/hardware/automotive/audiocontrol/DuckingInfo.aidl create mode 100644 automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/1/android/hardware/automotive/audiocontrol/IAudioControl.aidl create mode 100644 automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/1/android/hardware/automotive/audiocontrol/IFocusListener.aidl create mode 100644 automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/1/android/hardware/automotive/audiocontrol/MutingInfo.aidl create mode 100644 biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/1/.hash create mode 100644 biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/1/android/hardware/biometrics/common/CommonProps.aidl create mode 100644 biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/1/android/hardware/biometrics/common/ComponentInfo.aidl create mode 100644 biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/1/android/hardware/biometrics/common/ICancellationSignal.aidl create mode 100644 biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/1/android/hardware/biometrics/common/SensorStrength.aidl create mode 100644 biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/.hash create mode 100644 biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/AcquiredInfo.aidl create mode 100644 biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/AuthenticationFrame.aidl create mode 100644 biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/BaseFrame.aidl create mode 100644 biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/Cell.aidl create mode 100644 biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/EnrollmentFrame.aidl create mode 100644 biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/EnrollmentStage.aidl create mode 100644 biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/EnrollmentStageConfig.aidl create mode 100644 biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/EnrollmentType.aidl create mode 100644 biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/Error.aidl create mode 100644 biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/FaceSensorType.aidl create mode 100644 biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/Feature.aidl create mode 100644 biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/IFace.aidl create mode 100644 biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/ISession.aidl create mode 100644 biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/ISessionCallback.aidl create mode 100644 biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/SensorProps.aidl create mode 100644 biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/1/.hash create mode 100644 biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/1/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl create mode 100644 biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/1/android/hardware/biometrics/fingerprint/Error.aidl create mode 100644 biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/1/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl create mode 100644 biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/1/android/hardware/biometrics/fingerprint/IFingerprint.aidl create mode 100644 biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/1/android/hardware/biometrics/fingerprint/ISession.aidl create mode 100644 biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/1/android/hardware/biometrics/fingerprint/ISessionCallback.aidl create mode 100644 biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/1/android/hardware/biometrics/fingerprint/SensorLocation.aidl create mode 100644 biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/1/android/hardware/biometrics/fingerprint/SensorProps.aidl create mode 100644 common/aidl/aidl_api/android.hardware.common/2/.hash create mode 100644 common/aidl/aidl_api/android.hardware.common/2/android/hardware/common/Ashmem.aidl create mode 100644 common/aidl/aidl_api/android.hardware.common/2/android/hardware/common/MappableFile.aidl create mode 100644 common/aidl/aidl_api/android.hardware.common/2/android/hardware/common/NativeHandle.aidl create mode 100644 common/fmq/aidl/aidl_api/android.hardware.common.fmq/1/.hash create mode 100644 common/fmq/aidl/aidl_api/android.hardware.common.fmq/1/android/hardware/common/fmq/GrantorDescriptor.aidl create mode 100644 common/fmq/aidl/aidl_api/android.hardware.common.fmq/1/android/hardware/common/fmq/MQDescriptor.aidl create mode 100644 common/fmq/aidl/aidl_api/android.hardware.common.fmq/1/android/hardware/common/fmq/SynchronizedReadWrite.aidl create mode 100644 common/fmq/aidl/aidl_api/android.hardware.common.fmq/1/android/hardware/common/fmq/UnsynchronizedWrite.aidl create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/1/.hash create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/BlocklistedSource.aidl create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/CorrelationVector.aidl create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/ElapsedRealtime.aidl create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/GnssClock.aidl create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/GnssConstellationType.aidl create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/GnssData.aidl create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/GnssMeasurement.aidl create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/GnssMultipathIndicator.aidl create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/GnssPowerStats.aidl create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/GnssSignalType.aidl create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/IGnss.aidl create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/IGnssCallback.aidl create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/IGnssConfiguration.aidl create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/IGnssMeasurementCallback.aidl create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/IGnssMeasurementInterface.aidl create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/IGnssPowerIndication.aidl create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/IGnssPowerIndicationCallback.aidl create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/IGnssPsds.aidl create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/IGnssPsdsCallback.aidl create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/PsdsType.aidl create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/SatelliteClockInfo.aidl create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/SatellitePositionEcef.aidl create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/SatellitePvt.aidl create mode 100644 gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/SatelliteVelocityEcef.aidl create mode 100644 graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/.hash create mode 100644 graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/BlendMode.aidl create mode 100644 graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/BufferUsage.aidl create mode 100644 graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/ChromaSiting.aidl create mode 100644 graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/Compression.aidl create mode 100644 graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/Cta861_3.aidl create mode 100644 graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/Dataspace.aidl create mode 100644 graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/ExtendableType.aidl create mode 100644 graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/HardwareBuffer.aidl create mode 100644 graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/HardwareBufferDescription.aidl create mode 100644 graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/Interlaced.aidl create mode 100644 graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/PixelFormat.aidl create mode 100644 graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/PlaneLayout.aidl create mode 100644 graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/PlaneLayoutComponent.aidl create mode 100644 graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/PlaneLayoutComponentType.aidl create mode 100644 graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/Rect.aidl create mode 100644 graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/Smpte2086.aidl create mode 100644 graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/StandardMetadataType.aidl create mode 100644 graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/XyColor.aidl create mode 100644 health/storage/aidl/aidl_api/android.hardware.health.storage/1/.hash create mode 100644 health/storage/aidl/aidl_api/android.hardware.health.storage/1/android/hardware/health/storage/IGarbageCollectCallback.aidl create mode 100644 health/storage/aidl/aidl_api/android.hardware.health.storage/1/android/hardware/health/storage/IStorage.aidl create mode 100644 health/storage/aidl/aidl_api/android.hardware.health.storage/1/android/hardware/health/storage/Result.aidl create mode 100644 identity/aidl/aidl_api/android.hardware.identity/3/.hash create mode 100644 identity/aidl/aidl_api/android.hardware.identity/3/android/hardware/identity/Certificate.aidl create mode 100644 identity/aidl/aidl_api/android.hardware.identity/3/android/hardware/identity/CipherSuite.aidl create mode 100644 identity/aidl/aidl_api/android.hardware.identity/3/android/hardware/identity/HardwareInformation.aidl create mode 100644 identity/aidl/aidl_api/android.hardware.identity/3/android/hardware/identity/IIdentityCredential.aidl create mode 100644 identity/aidl/aidl_api/android.hardware.identity/3/android/hardware/identity/IIdentityCredentialStore.aidl create mode 100644 identity/aidl/aidl_api/android.hardware.identity/3/android/hardware/identity/IWritableIdentityCredential.aidl create mode 100644 identity/aidl/aidl_api/android.hardware.identity/3/android/hardware/identity/RequestDataItem.aidl create mode 100644 identity/aidl/aidl_api/android.hardware.identity/3/android/hardware/identity/RequestNamespace.aidl create mode 100644 identity/aidl/aidl_api/android.hardware.identity/3/android/hardware/identity/SecureAccessControlProfile.aidl create mode 100644 keymaster/aidl/aidl_api/android.hardware.keymaster/3/.hash create mode 100644 keymaster/aidl/aidl_api/android.hardware.keymaster/3/android/hardware/keymaster/HardwareAuthToken.aidl create mode 100644 keymaster/aidl/aidl_api/android.hardware.keymaster/3/android/hardware/keymaster/HardwareAuthenticatorType.aidl create mode 100644 keymaster/aidl/aidl_api/android.hardware.keymaster/3/android/hardware/keymaster/SecurityLevel.aidl create mode 100644 keymaster/aidl/aidl_api/android.hardware.keymaster/3/android/hardware/keymaster/Timestamp.aidl create mode 100644 keymaster/aidl/aidl_api/android.hardware.keymaster/3/android/hardware/keymaster/VerificationToken.aidl create mode 100644 memtrack/aidl/aidl_api/android.hardware.memtrack/1/.hash create mode 100644 memtrack/aidl/aidl_api/android.hardware.memtrack/1/android/hardware/memtrack/DeviceInfo.aidl create mode 100644 memtrack/aidl/aidl_api/android.hardware.memtrack/1/android/hardware/memtrack/IMemtrack.aidl create mode 100644 memtrack/aidl/aidl_api/android.hardware.memtrack/1/android/hardware/memtrack/MemtrackRecord.aidl create mode 100644 memtrack/aidl/aidl_api/android.hardware.memtrack/1/android/hardware/memtrack/MemtrackType.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/.hash create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/BufferDesc.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/BufferRole.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/Capabilities.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/DataLocation.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/DeviceBuffer.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/DeviceType.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/ErrorStatus.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/ExecutionPreference.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/ExecutionResult.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/Extension.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/ExtensionNameAndPrefix.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/ExtensionOperandTypeInformation.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/FencedExecutionResult.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/FusedActivationFunc.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/IBuffer.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/IBurst.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/IDevice.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/IFencedExecutionCallback.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/IPreparedModel.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/IPreparedModelCallback.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/IPreparedModelParcel.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/Memory.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/Model.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/NumberOfCacheFiles.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/Operand.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/OperandExtraParams.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/OperandLifeTime.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/OperandPerformance.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/OperandType.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/Operation.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/OperationType.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/OutputShape.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/PerformanceInfo.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/Priority.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/Request.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/RequestArgument.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/RequestMemoryPool.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/Subgraph.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/SymmPerChannelQuantParams.aidl create mode 100644 neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/Timing.aidl create mode 100644 oemlock/aidl/aidl_api/android.hardware.oemlock/1/.hash create mode 100644 oemlock/aidl/aidl_api/android.hardware.oemlock/1/android/hardware/oemlock/IOemLock.aidl create mode 100644 oemlock/aidl/aidl_api/android.hardware.oemlock/1/android/hardware/oemlock/OemLockSecureStatus.aidl create mode 100644 power/aidl/aidl_api/android.hardware.power/2/.hash create mode 100644 power/aidl/aidl_api/android.hardware.power/2/android/hardware/power/Boost.aidl create mode 100644 power/aidl/aidl_api/android.hardware.power/2/android/hardware/power/IPower.aidl create mode 100644 power/aidl/aidl_api/android.hardware.power/2/android/hardware/power/IPowerHintSession.aidl create mode 100644 power/aidl/aidl_api/android.hardware.power/2/android/hardware/power/Mode.aidl create mode 100644 power/aidl/aidl_api/android.hardware.power/2/android/hardware/power/WorkDuration.aidl create mode 100644 power/stats/aidl/aidl_api/android.hardware.power.stats/1/.hash create mode 100644 power/stats/aidl/aidl_api/android.hardware.power.stats/1/android/hardware/power/stats/Channel.aidl create mode 100644 power/stats/aidl/aidl_api/android.hardware.power.stats/1/android/hardware/power/stats/EnergyConsumer.aidl create mode 100644 power/stats/aidl/aidl_api/android.hardware.power.stats/1/android/hardware/power/stats/EnergyConsumerAttribution.aidl create mode 100644 power/stats/aidl/aidl_api/android.hardware.power.stats/1/android/hardware/power/stats/EnergyConsumerResult.aidl create mode 100644 power/stats/aidl/aidl_api/android.hardware.power.stats/1/android/hardware/power/stats/EnergyConsumerType.aidl create mode 100644 power/stats/aidl/aidl_api/android.hardware.power.stats/1/android/hardware/power/stats/EnergyMeasurement.aidl create mode 100644 power/stats/aidl/aidl_api/android.hardware.power.stats/1/android/hardware/power/stats/IPowerStats.aidl create mode 100644 power/stats/aidl/aidl_api/android.hardware.power.stats/1/android/hardware/power/stats/PowerEntity.aidl create mode 100644 power/stats/aidl/aidl_api/android.hardware.power.stats/1/android/hardware/power/stats/State.aidl create mode 100644 power/stats/aidl/aidl_api/android.hardware.power.stats/1/android/hardware/power/stats/StateResidency.aidl create mode 100644 power/stats/aidl/aidl_api/android.hardware.power.stats/1/android/hardware/power/stats/StateResidencyResult.aidl create mode 100644 security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/.hash create mode 100644 security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/Algorithm.aidl create mode 100644 security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/AttestationKey.aidl create mode 100644 security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/BeginResult.aidl create mode 100644 security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/BlockMode.aidl create mode 100644 security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/Certificate.aidl create mode 100644 security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/DeviceInfo.aidl create mode 100644 security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/Digest.aidl create mode 100644 security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/EcCurve.aidl create mode 100644 security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/ErrorCode.aidl create mode 100644 security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/HardwareAuthToken.aidl create mode 100644 security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/HardwareAuthenticatorType.aidl create mode 100644 security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/IKeyMintDevice.aidl create mode 100644 security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/IKeyMintOperation.aidl create mode 100644 security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl create mode 100644 security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/KeyCharacteristics.aidl create mode 100644 security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/KeyCreationResult.aidl create mode 100644 security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/KeyFormat.aidl create mode 100644 security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/KeyMintHardwareInfo.aidl create mode 100644 security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/KeyOrigin.aidl create mode 100644 security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/KeyParameter.aidl create mode 100644 security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/KeyParameterValue.aidl create mode 100644 security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/KeyPurpose.aidl create mode 100644 security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/MacedPublicKey.aidl create mode 100644 security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/PaddingMode.aidl create mode 100644 security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/ProtectedData.aidl create mode 100644 security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/RpcHardwareInfo.aidl create mode 100644 security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/SecurityLevel.aidl create mode 100644 security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/Tag.aidl create mode 100644 security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/TagType.aidl create mode 100644 security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/1/.hash create mode 100644 security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/1/android/hardware/security/secureclock/ISecureClock.aidl create mode 100644 security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/1/android/hardware/security/secureclock/TimeStampToken.aidl create mode 100644 security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/1/android/hardware/security/secureclock/Timestamp.aidl create mode 100644 security/sharedsecret/aidl/aidl_api/android.hardware.security.sharedsecret/1/.hash create mode 100644 security/sharedsecret/aidl/aidl_api/android.hardware.security.sharedsecret/1/android/hardware/security/sharedsecret/ISharedSecret.aidl create mode 100644 security/sharedsecret/aidl/aidl_api/android.hardware.security.sharedsecret/1/android/hardware/security/sharedsecret/SharedSecretParameters.aidl create mode 100644 vibrator/aidl/aidl_api/android.hardware.vibrator/2/.hash create mode 100644 vibrator/aidl/aidl_api/android.hardware.vibrator/2/android/hardware/vibrator/ActivePwle.aidl create mode 100644 vibrator/aidl/aidl_api/android.hardware.vibrator/2/android/hardware/vibrator/Braking.aidl create mode 100644 vibrator/aidl/aidl_api/android.hardware.vibrator/2/android/hardware/vibrator/BrakingPwle.aidl create mode 100644 vibrator/aidl/aidl_api/android.hardware.vibrator/2/android/hardware/vibrator/CompositeEffect.aidl create mode 100644 vibrator/aidl/aidl_api/android.hardware.vibrator/2/android/hardware/vibrator/CompositePrimitive.aidl create mode 100644 vibrator/aidl/aidl_api/android.hardware.vibrator/2/android/hardware/vibrator/Effect.aidl create mode 100644 vibrator/aidl/aidl_api/android.hardware.vibrator/2/android/hardware/vibrator/EffectStrength.aidl create mode 100644 vibrator/aidl/aidl_api/android.hardware.vibrator/2/android/hardware/vibrator/IVibrator.aidl create mode 100644 vibrator/aidl/aidl_api/android.hardware.vibrator/2/android/hardware/vibrator/IVibratorCallback.aidl create mode 100644 vibrator/aidl/aidl_api/android.hardware.vibrator/2/android/hardware/vibrator/IVibratorManager.aidl create mode 100644 vibrator/aidl/aidl_api/android.hardware.vibrator/2/android/hardware/vibrator/PrimitivePwle.aidl create mode 100644 weaver/aidl/aidl_api/android.hardware.weaver/1/.hash create mode 100644 weaver/aidl/aidl_api/android.hardware.weaver/1/android/hardware/weaver/IWeaver.aidl create mode 100644 weaver/aidl/aidl_api/android.hardware.weaver/1/android/hardware/weaver/WeaverConfig.aidl create mode 100644 weaver/aidl/aidl_api/android.hardware.weaver/1/android/hardware/weaver/WeaverReadResponse.aidl diff --git a/authsecret/aidl/Android.bp b/authsecret/aidl/Android.bp index 8fe9f27d7e..432c1b97c3 100644 --- a/authsecret/aidl/Android.bp +++ b/authsecret/aidl/Android.bp @@ -22,4 +22,5 @@ aidl_interface { }, }, }, + versions: ["1"], } diff --git a/authsecret/aidl/aidl_api/android.hardware.authsecret/1/.hash b/authsecret/aidl/aidl_api/android.hardware.authsecret/1/.hash new file mode 100644 index 0000000000..4a5c24a154 --- /dev/null +++ b/authsecret/aidl/aidl_api/android.hardware.authsecret/1/.hash @@ -0,0 +1 @@ +729cca96cb4732246b6ed1b3d15e2cbe63413afd diff --git a/authsecret/aidl/aidl_api/android.hardware.authsecret/1/android/hardware/authsecret/IAuthSecret.aidl b/authsecret/aidl/aidl_api/android.hardware.authsecret/1/android/hardware/authsecret/IAuthSecret.aidl new file mode 100644 index 0000000000..76b96f284d --- /dev/null +++ b/authsecret/aidl/aidl_api/android.hardware.authsecret/1/android/hardware/authsecret/IAuthSecret.aidl @@ -0,0 +1,38 @@ +/* + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.authsecret; +@VintfStability +interface IAuthSecret { + oneway void setPrimaryUserCredential(in byte[] secret); +} diff --git a/automotive/audiocontrol/aidl/Android.bp b/automotive/audiocontrol/aidl/Android.bp index 7a947d3ab5..4acfd82d6a 100644 --- a/automotive/audiocontrol/aidl/Android.bp +++ b/automotive/audiocontrol/aidl/Android.bp @@ -19,4 +19,5 @@ aidl_interface { sdk_version: "module_current", }, }, + versions: ["1"], } diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/1/.hash b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/1/.hash new file mode 100644 index 0000000000..c4bb36b470 --- /dev/null +++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/1/.hash @@ -0,0 +1 @@ +ba2a7caca61683385b3b100e4faab1b4139fc547 diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/1/android/hardware/automotive/audiocontrol/AudioFocusChange.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/1/android/hardware/automotive/audiocontrol/AudioFocusChange.aidl new file mode 100644 index 0000000000..58a36673cd --- /dev/null +++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/1/android/hardware/automotive/audiocontrol/AudioFocusChange.aidl @@ -0,0 +1,45 @@ +/* + * 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 -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.automotive.audiocontrol; +@Backing(type="int") @VintfStability +enum AudioFocusChange { + NONE = 0, + GAIN = 1, + GAIN_TRANSIENT = 2, + GAIN_TRANSIENT_MAY_DUCK = 3, + GAIN_TRANSIENT_EXCLUSIVE = 4, + LOSS = -1, + LOSS_TRANSIENT = -2, + LOSS_TRANSIENT_CAN_DUCK = -3, +} diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/1/android/hardware/automotive/audiocontrol/DuckingInfo.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/1/android/hardware/automotive/audiocontrol/DuckingInfo.aidl new file mode 100644 index 0000000000..a0f7db97ad --- /dev/null +++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/1/android/hardware/automotive/audiocontrol/DuckingInfo.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 -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.automotive.audiocontrol; +@VintfStability +parcelable DuckingInfo { + int zoneId; + String[] deviceAddressesToDuck; + String[] deviceAddressesToUnduck; + String[] usagesHoldingFocus; +} diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/1/android/hardware/automotive/audiocontrol/IAudioControl.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/1/android/hardware/automotive/audiocontrol/IAudioControl.aidl new file mode 100644 index 0000000000..c10713d0ec --- /dev/null +++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/1/android/hardware/automotive/audiocontrol/IAudioControl.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 -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.automotive.audiocontrol; +@VintfStability +interface IAudioControl { + oneway void onAudioFocusChange(in String usage, in int zoneId, in android.hardware.automotive.audiocontrol.AudioFocusChange focusChange); + oneway void onDevicesToDuckChange(in android.hardware.automotive.audiocontrol.DuckingInfo[] duckingInfos); + oneway void onDevicesToMuteChange(in android.hardware.automotive.audiocontrol.MutingInfo[] mutingInfos); + oneway void registerFocusListener(in android.hardware.automotive.audiocontrol.IFocusListener listener); + oneway void setBalanceTowardRight(in float value); + oneway void setFadeTowardFront(in float value); +} diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/1/android/hardware/automotive/audiocontrol/IFocusListener.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/1/android/hardware/automotive/audiocontrol/IFocusListener.aidl new file mode 100644 index 0000000000..046c19d930 --- /dev/null +++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/1/android/hardware/automotive/audiocontrol/IFocusListener.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 -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.automotive.audiocontrol; +@VintfStability +interface IFocusListener { + oneway void abandonAudioFocus(in String usage, in int zoneId); + oneway void requestAudioFocus(in String usage, in int zoneId, in android.hardware.automotive.audiocontrol.AudioFocusChange focusGain); +} diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/1/android/hardware/automotive/audiocontrol/MutingInfo.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/1/android/hardware/automotive/audiocontrol/MutingInfo.aidl new file mode 100644 index 0000000000..b25ed0f1e9 --- /dev/null +++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/1/android/hardware/automotive/audiocontrol/MutingInfo.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 -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.automotive.audiocontrol; +@VintfStability +parcelable MutingInfo { + int zoneId; + String[] deviceAddressesToMute; + String[] deviceAddressesToUnmute; +} diff --git a/biometrics/common/aidl/Android.bp b/biometrics/common/aidl/Android.bp index 829f8c2625..05028c4e50 100644 --- a/biometrics/common/aidl/Android.bp +++ b/biometrics/common/aidl/Android.bp @@ -21,5 +21,6 @@ aidl_interface { cpp: { enabled: false, }, - } + }, + versions: ["1"], } diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/1/.hash b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/1/.hash new file mode 100644 index 0000000000..e7609fbc86 --- /dev/null +++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/1/.hash @@ -0,0 +1 @@ +9ad0b938db247283c4a8c1bf7e4218a420019024 diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/1/android/hardware/biometrics/common/CommonProps.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/1/android/hardware/biometrics/common/CommonProps.aidl new file mode 100644 index 0000000000..d4433c5bde --- /dev/null +++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/1/android/hardware/biometrics/common/CommonProps.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 -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 CommonProps { + int sensorId; + android.hardware.biometrics.common.SensorStrength sensorStrength = android.hardware.biometrics.common.SensorStrength.CONVENIENCE; + int maxEnrollmentsPerUser; + android.hardware.biometrics.common.ComponentInfo[] componentInfo; +} diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/1/android/hardware/biometrics/common/ComponentInfo.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/1/android/hardware/biometrics/common/ComponentInfo.aidl new file mode 100644 index 0000000000..ad11ddaa6d --- /dev/null +++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/1/android/hardware/biometrics/common/ComponentInfo.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 -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 ComponentInfo { + String componentId; + String hardwareVersion; + String firmwareVersion; + String serialNumber; + String softwareVersion; +} diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/1/android/hardware/biometrics/common/ICancellationSignal.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/1/android/hardware/biometrics/common/ICancellationSignal.aidl new file mode 100644 index 0000000000..2bc6a6df05 --- /dev/null +++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/1/android/hardware/biometrics/common/ICancellationSignal.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 -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 +interface ICancellationSignal { + oneway void cancel(); +} diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/1/android/hardware/biometrics/common/SensorStrength.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/1/android/hardware/biometrics/common/SensorStrength.aidl new file mode 100644 index 0000000000..6675d091e5 --- /dev/null +++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/1/android/hardware/biometrics/common/SensorStrength.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 -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 SensorStrength { + CONVENIENCE = 0, + WEAK = 1, + STRONG = 2, +} diff --git a/biometrics/face/aidl/Android.bp b/biometrics/face/aidl/Android.bp index 63f5ae41af..54d3ecd1e1 100644 --- a/biometrics/face/aidl/Android.bp +++ b/biometrics/face/aidl/Android.bp @@ -27,4 +27,5 @@ aidl_interface { enabled: false, }, }, + versions: ["1"], } diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/.hash b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/.hash new file mode 100644 index 0000000000..b8d5097cc9 --- /dev/null +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/.hash @@ -0,0 +1 @@ +945de3635b7f5a09244820eef56035c92fdbd324 diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/AcquiredInfo.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/AcquiredInfo.aidl new file mode 100644 index 0000000000..eaa43f3f9e --- /dev/null +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/AcquiredInfo.aidl @@ -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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.face; +@Backing(type="byte") @VintfStability +enum AcquiredInfo { + UNKNOWN = 0, + GOOD = 1, + INSUFFICIENT = 2, + TOO_BRIGHT = 3, + TOO_DARK = 4, + TOO_CLOSE = 5, + TOO_FAR = 6, + FACE_TOO_HIGH = 7, + FACE_TOO_LOW = 8, + FACE_TOO_RIGHT = 9, + FACE_TOO_LEFT = 10, + POOR_GAZE = 11, + NOT_DETECTED = 12, + TOO_MUCH_MOTION = 13, + RECALIBRATE = 14, + TOO_DIFFERENT = 15, + TOO_SIMILAR = 16, + PAN_TOO_EXTREME = 17, + TILT_TOO_EXTREME = 18, + ROLL_TOO_EXTREME = 19, + FACE_OBSCURED = 20, + START = 21, + SENSOR_DIRTY = 22, + VENDOR = 23, + FIRST_FRAME_RECEIVED = 24, + DARK_GLASSES_DETECTED = 25, + MOUTH_COVERING_DETECTED = 26, +} diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/AuthenticationFrame.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/AuthenticationFrame.aidl new file mode 100644 index 0000000000..20bc76779b --- /dev/null +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/AuthenticationFrame.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 -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.face; +@VintfStability +parcelable AuthenticationFrame { + android.hardware.biometrics.face.BaseFrame data; +} diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/BaseFrame.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/BaseFrame.aidl new file mode 100644 index 0000000000..67b5cf4169 --- /dev/null +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/BaseFrame.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 -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.face; +@VintfStability +parcelable BaseFrame { + android.hardware.biometrics.face.AcquiredInfo acquiredInfo = android.hardware.biometrics.face.AcquiredInfo.UNKNOWN; + int vendorCode; + float pan; + float tilt; + float distance; + boolean isCancellable; +} diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/Cell.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/Cell.aidl new file mode 100644 index 0000000000..6be8c8e975 --- /dev/null +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/Cell.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 -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.face; +@VintfStability +parcelable Cell { + int x; + int y; + int z; +} diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/EnrollmentFrame.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/EnrollmentFrame.aidl new file mode 100644 index 0000000000..0ea10d6ddb --- /dev/null +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/EnrollmentFrame.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 -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.face; +@VintfStability +parcelable EnrollmentFrame { + @nullable android.hardware.biometrics.face.Cell cell; + android.hardware.biometrics.face.EnrollmentStage stage = android.hardware.biometrics.face.EnrollmentStage.UNKNOWN; + android.hardware.biometrics.face.BaseFrame data; +} diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/EnrollmentStage.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/EnrollmentStage.aidl new file mode 100644 index 0000000000..ce5679ab31 --- /dev/null +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/EnrollmentStage.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 -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.face; +@Backing(type="byte") @VintfStability +enum EnrollmentStage { + UNKNOWN = 0, + FIRST_FRAME_RECEIVED = 1, + WAITING_FOR_CENTERING = 2, + HOLD_STILL_IN_CENTER = 3, + ENROLLING_MOVEMENT_1 = 4, + ENROLLING_MOVEMENT_2 = 5, + ENROLLMENT_FINISHED = 6, +} diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/EnrollmentStageConfig.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/EnrollmentStageConfig.aidl new file mode 100644 index 0000000000..48db2cf615 --- /dev/null +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/EnrollmentStageConfig.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 -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.face; +@VintfStability +parcelable EnrollmentStageConfig { + android.hardware.biometrics.face.EnrollmentStage stage = android.hardware.biometrics.face.EnrollmentStage.UNKNOWN; + List cells; +} diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/EnrollmentType.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/EnrollmentType.aidl new file mode 100644 index 0000000000..8e99ad6529 --- /dev/null +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/EnrollmentType.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 -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.face; +@Backing(type="byte") @VintfStability +enum EnrollmentType { + DEFAULT = 0, + ACCESSIBILITY = 1, +} diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/Error.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/Error.aidl new file mode 100644 index 0000000000..1a21661932 --- /dev/null +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/Error.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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.face; +@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, + REENROLL_REQUIRED = 8, +} diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/FaceSensorType.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/FaceSensorType.aidl new file mode 100644 index 0000000000..a215b99f72 --- /dev/null +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/FaceSensorType.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 -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.face; +@Backing(type="byte") @VintfStability +enum FaceSensorType { + UNKNOWN = 0, + RGB = 1, + IR = 2, +} diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/Feature.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/Feature.aidl new file mode 100644 index 0000000000..1875b97431 --- /dev/null +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/Feature.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 -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.face; +@Backing(type="byte") @VintfStability +enum Feature { + REQUIRE_ATTENTION = 0, + REQUIRE_DIVERSE_POSES = 1, + DEBUG = 2, +} diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/IFace.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/IFace.aidl new file mode 100644 index 0000000000..fc4a4d04bb --- /dev/null +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/IFace.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 -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.face; +@VintfStability +interface IFace { + android.hardware.biometrics.face.SensorProps[] getSensorProps(); + android.hardware.biometrics.face.ISession createSession(in int sensorId, in int userId, in android.hardware.biometrics.face.ISessionCallback cb); +} diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/ISession.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/ISession.aidl new file mode 100644 index 0000000000..d1c2c1dd47 --- /dev/null +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/ISession.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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.face; +@VintfStability +interface ISession { + void generateChallenge(); + void revokeChallenge(in long challenge); + android.hardware.biometrics.face.EnrollmentStageConfig[] getEnrollmentConfig(in android.hardware.biometrics.face.EnrollmentType enrollmentType); + android.hardware.biometrics.common.ICancellationSignal enroll(in android.hardware.keymaster.HardwareAuthToken hat, in android.hardware.biometrics.face.EnrollmentType type, in android.hardware.biometrics.face.Feature[] features, in android.hardware.common.NativeHandle previewSurface); + android.hardware.biometrics.common.ICancellationSignal authenticate(in long operationId); + android.hardware.biometrics.common.ICancellationSignal detectInteraction(); + void enumerateEnrollments(); + void removeEnrollments(in int[] enrollmentIds); + void getFeatures(); + void setFeature(in android.hardware.keymaster.HardwareAuthToken hat, in android.hardware.biometrics.face.Feature feature, boolean enabled); + void getAuthenticatorId(); + void invalidateAuthenticatorId(); + void resetLockout(in android.hardware.keymaster.HardwareAuthToken hat); + void close(); +} diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/ISessionCallback.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/ISessionCallback.aidl new file mode 100644 index 0000000000..bbace29aa0 --- /dev/null +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/ISessionCallback.aidl @@ -0,0 +1,56 @@ +/* + * 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 -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.face; +@VintfStability +interface ISessionCallback { + void onChallengeGenerated(in long challenge); + void onChallengeRevoked(in long challenge); + void onAuthenticationFrame(in android.hardware.biometrics.face.AuthenticationFrame frame); + void onEnrollmentFrame(in android.hardware.biometrics.face.EnrollmentFrame frame); + void onError(in android.hardware.biometrics.face.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 onFeaturesRetrieved(in android.hardware.biometrics.face.Feature[] features); + void onFeatureSet(android.hardware.biometrics.face.Feature feature); + void onEnrollmentsRemoved(in int[] enrollmentIds); + void onAuthenticatorIdRetrieved(in long authenticatorId); + void onAuthenticatorIdInvalidated(in long newAuthenticatorId); + void onSessionClosed(); +} diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/SensorProps.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/SensorProps.aidl new file mode 100644 index 0000000000..8b3c51bb12 --- /dev/null +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/SensorProps.aidl @@ -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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.face; +@VintfStability +parcelable SensorProps { + android.hardware.biometrics.common.CommonProps commonProps; + android.hardware.biometrics.face.FaceSensorType sensorType = android.hardware.biometrics.face.FaceSensorType.UNKNOWN; + boolean halControlsPreview; + int previewDisplayId; + int enrollPreviewWidth; + int enrollPreviewHeight; + float enrollTranslationX; + float enrollTranslationY; + float enrollPreviewScale; + boolean supportsDetectInteraction; +} diff --git a/biometrics/fingerprint/aidl/Android.bp b/biometrics/fingerprint/aidl/Android.bp index 7ee957dd88..5295098c79 100644 --- a/biometrics/fingerprint/aidl/Android.bp +++ b/biometrics/fingerprint/aidl/Android.bp @@ -26,4 +26,5 @@ aidl_interface { enabled: false, }, }, + versions: ["1"], } diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/1/.hash b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/1/.hash new file mode 100644 index 0000000000..64b20831d8 --- /dev/null +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/1/.hash @@ -0,0 +1 @@ +3621eefdbae063097dad0037cd1f111792ff12ec diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/1/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/1/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl new file mode 100644 index 0000000000..c51aa033d4 --- /dev/null +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/1/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.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, +} diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/1/android/hardware/biometrics/fingerprint/Error.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/1/android/hardware/biometrics/fingerprint/Error.aidl new file mode 100644 index 0000000000..af7bc3c56b --- /dev/null +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/1/android/hardware/biometrics/fingerprint/Error.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 -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.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, +} diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/1/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/1/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl new file mode 100644 index 0000000000..9c208c4e7c --- /dev/null +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/1/android/hardware/biometrics/fingerprint/FingerprintSensorType.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 -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.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, +} diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/1/android/hardware/biometrics/fingerprint/IFingerprint.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/1/android/hardware/biometrics/fingerprint/IFingerprint.aidl new file mode 100644 index 0000000000..5d3df6fbaa --- /dev/null +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/1/android/hardware/biometrics/fingerprint/IFingerprint.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 -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.fingerprint; +@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); +} diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/1/android/hardware/biometrics/fingerprint/ISession.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/1/android/hardware/biometrics/fingerprint/ISession.aidl new file mode 100644 index 0000000000..9934a763e7 --- /dev/null +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/1/android/hardware/biometrics/fingerprint/ISession.aidl @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.fingerprint; +@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(); +} diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/1/android/hardware/biometrics/fingerprint/ISessionCallback.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/1/android/hardware/biometrics/fingerprint/ISessionCallback.aidl new file mode 100644 index 0000000000..3c40ad63bf --- /dev/null +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/1/android/hardware/biometrics/fingerprint/ISessionCallback.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 -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.fingerprint; +@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(); +} diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/1/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/1/android/hardware/biometrics/fingerprint/SensorLocation.aidl new file mode 100644 index 0000000000..515ddaa358 --- /dev/null +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/1/android/hardware/biometrics/fingerprint/SensorLocation.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 -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.fingerprint; +@VintfStability +parcelable SensorLocation { + int displayId; + int sensorLocationX; + int sensorLocationY; + int sensorRadius; +} diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/1/android/hardware/biometrics/fingerprint/SensorProps.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/1/android/hardware/biometrics/fingerprint/SensorProps.aidl new file mode 100644 index 0000000000..782d2899d3 --- /dev/null +++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/1/android/hardware/biometrics/fingerprint/SensorProps.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 -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.fingerprint; +@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; +} diff --git a/common/aidl/Android.bp b/common/aidl/Android.bp index 912bfdc1f8..028c923de6 100644 --- a/common/aidl/Android.bp +++ b/common/aidl/Android.bp @@ -36,5 +36,8 @@ aidl_interface { min_sdk_version: "29", }, }, - versions: ["1"], + versions: [ + "1", + "2", + ], } diff --git a/common/aidl/aidl_api/android.hardware.common/2/.hash b/common/aidl/aidl_api/android.hardware.common/2/.hash new file mode 100644 index 0000000000..5ef5e089a7 --- /dev/null +++ b/common/aidl/aidl_api/android.hardware.common/2/.hash @@ -0,0 +1 @@ +c32ddfdeb69c6e4a8a45519e6f9a39c4b66fd99f diff --git a/common/aidl/aidl_api/android.hardware.common/2/android/hardware/common/Ashmem.aidl b/common/aidl/aidl_api/android.hardware.common/2/android/hardware/common/Ashmem.aidl new file mode 100644 index 0000000000..a4380315c9 --- /dev/null +++ b/common/aidl/aidl_api/android.hardware.common/2/android/hardware/common/Ashmem.aidl @@ -0,0 +1,39 @@ +/* + * 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 -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.common; +@VintfStability +parcelable Ashmem { + ParcelFileDescriptor fd; + long size; +} diff --git a/common/aidl/aidl_api/android.hardware.common/2/android/hardware/common/MappableFile.aidl b/common/aidl/aidl_api/android.hardware.common/2/android/hardware/common/MappableFile.aidl new file mode 100644 index 0000000000..394ea8ff07 --- /dev/null +++ b/common/aidl/aidl_api/android.hardware.common/2/android/hardware/common/MappableFile.aidl @@ -0,0 +1,41 @@ +/* + * 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 -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.common; +@VintfStability +parcelable MappableFile { + long length; + int prot; + ParcelFileDescriptor fd; + long offset; +} diff --git a/common/aidl/aidl_api/android.hardware.common/2/android/hardware/common/NativeHandle.aidl b/common/aidl/aidl_api/android.hardware.common/2/android/hardware/common/NativeHandle.aidl new file mode 100644 index 0000000000..2ed5c0b22d --- /dev/null +++ b/common/aidl/aidl_api/android.hardware.common/2/android/hardware/common/NativeHandle.aidl @@ -0,0 +1,39 @@ +/* + * Copyright 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.common; +@VintfStability +parcelable NativeHandle { + ParcelFileDescriptor[] fds; + int[] ints; +} diff --git a/common/fmq/aidl/Android.bp b/common/fmq/aidl/Android.bp index 1ab724f097..fb2f4e0651 100644 --- a/common/fmq/aidl/Android.bp +++ b/common/fmq/aidl/Android.bp @@ -30,4 +30,5 @@ aidl_interface { enabled: false, }, }, + versions: ["1"], } diff --git a/common/fmq/aidl/aidl_api/android.hardware.common.fmq/1/.hash b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/1/.hash new file mode 100644 index 0000000000..da122e601c --- /dev/null +++ b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/1/.hash @@ -0,0 +1 @@ +12cf0ce8614557cc0efe73bdf011f5193f7a8653 diff --git a/common/fmq/aidl/aidl_api/android.hardware.common.fmq/1/android/hardware/common/fmq/GrantorDescriptor.aidl b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/1/android/hardware/common/fmq/GrantorDescriptor.aidl new file mode 100644 index 0000000000..cf7048bc02 --- /dev/null +++ b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/1/android/hardware/common/fmq/GrantorDescriptor.aidl @@ -0,0 +1,40 @@ +/* + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.common.fmq; +@VintfStability +parcelable GrantorDescriptor { + int fdIndex; + int offset; + long extent; +} diff --git a/common/fmq/aidl/aidl_api/android.hardware.common.fmq/1/android/hardware/common/fmq/MQDescriptor.aidl b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/1/android/hardware/common/fmq/MQDescriptor.aidl new file mode 100644 index 0000000000..add4b64cf1 --- /dev/null +++ b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/1/android/hardware/common/fmq/MQDescriptor.aidl @@ -0,0 +1,41 @@ +/* + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.common.fmq; +@VintfStability +parcelable MQDescriptor { + android.hardware.common.fmq.GrantorDescriptor[] grantors; + android.hardware.common.NativeHandle handle; + int quantum; + int flags; +} diff --git a/common/fmq/aidl/aidl_api/android.hardware.common.fmq/1/android/hardware/common/fmq/SynchronizedReadWrite.aidl b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/1/android/hardware/common/fmq/SynchronizedReadWrite.aidl new file mode 100644 index 0000000000..12c61bab2e --- /dev/null +++ b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/1/android/hardware/common/fmq/SynchronizedReadWrite.aidl @@ -0,0 +1,38 @@ +/* + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.common.fmq; +@VintfStability +enum SynchronizedReadWrite { + EMPTY = 0, +} diff --git a/common/fmq/aidl/aidl_api/android.hardware.common.fmq/1/android/hardware/common/fmq/UnsynchronizedWrite.aidl b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/1/android/hardware/common/fmq/UnsynchronizedWrite.aidl new file mode 100644 index 0000000000..f99528d398 --- /dev/null +++ b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/1/android/hardware/common/fmq/UnsynchronizedWrite.aidl @@ -0,0 +1,38 @@ +/* + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.common.fmq; +@VintfStability +enum UnsynchronizedWrite { + EMPTY = 0, +} diff --git a/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/GrantorDescriptor.aidl b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/GrantorDescriptor.aidl index 03277964ae..cf7048bc02 100644 --- a/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/GrantorDescriptor.aidl +++ b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/GrantorDescriptor.aidl @@ -1,3 +1,18 @@ +/* + * 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. + */ /////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/MQDescriptor.aidl b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/MQDescriptor.aidl index 56f1de3cd8..add4b64cf1 100644 --- a/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/MQDescriptor.aidl +++ b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/MQDescriptor.aidl @@ -1,3 +1,18 @@ +/* + * 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. + */ /////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// @@ -18,7 +33,7 @@ package android.hardware.common.fmq; @VintfStability -parcelable MQDescriptor { +parcelable MQDescriptor { android.hardware.common.fmq.GrantorDescriptor[] grantors; android.hardware.common.NativeHandle handle; int quantum; diff --git a/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/SynchronizedReadWrite.aidl b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/SynchronizedReadWrite.aidl index 264171dca1..12c61bab2e 100644 --- a/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/SynchronizedReadWrite.aidl +++ b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/SynchronizedReadWrite.aidl @@ -1,3 +1,18 @@ +/* + * 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. + */ /////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/UnsynchronizedWrite.aidl b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/UnsynchronizedWrite.aidl index eaf2ffdd16..f99528d398 100644 --- a/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/UnsynchronizedWrite.aidl +++ b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/UnsynchronizedWrite.aidl @@ -1,3 +1,18 @@ +/* + * 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. + */ /////////////////////////////////////////////////////////////////////////////// // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // /////////////////////////////////////////////////////////////////////////////// diff --git a/gnss/aidl/Android.bp b/gnss/aidl/Android.bp index 7725b9549b..b197eae32d 100644 --- a/gnss/aidl/Android.bp +++ b/gnss/aidl/Android.bp @@ -38,4 +38,5 @@ aidl_interface { }, }, }, + versions: ["1"], } diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/1/.hash b/gnss/aidl/aidl_api/android.hardware.gnss/1/.hash new file mode 100644 index 0000000000..2f689c4054 --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/1/.hash @@ -0,0 +1 @@ +10839720b90aaec329521e810d9e0501cfcef0d3 diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/BlocklistedSource.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/BlocklistedSource.aidl new file mode 100644 index 0000000000..a4f00971c5 --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/BlocklistedSource.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 -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.gnss; +@VintfStability +parcelable BlocklistedSource { + android.hardware.gnss.GnssConstellationType constellation = android.hardware.gnss.GnssConstellationType.UNKNOWN; + int svid; +} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/CorrelationVector.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/CorrelationVector.aidl new file mode 100644 index 0000000000..b0848bb9c4 --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/CorrelationVector.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 -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.gnss; +@VintfStability +parcelable CorrelationVector { + double frequencyOffsetMps; + double samplingWidthM; + double samplingStartM; + int[] magnitude; +} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/ElapsedRealtime.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/ElapsedRealtime.aidl new file mode 100644 index 0000000000..7d3baa41f2 --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/ElapsedRealtime.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 -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.gnss; +@VintfStability +parcelable ElapsedRealtime { + int flags; + long timestampNs; + double timeUncertaintyNs; + const int HAS_TIMESTAMP_NS = 1; + const int HAS_TIME_UNCERTAINTY_NS = 2; +} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/GnssClock.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/GnssClock.aidl new file mode 100644 index 0000000000..c54cc2c500 --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/GnssClock.aidl @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.gnss; +@VintfStability +parcelable GnssClock { + int gnssClockFlags; + int leapSecond; + long timeNs; + double timeUncertaintyNs; + long fullBiasNs; + double biasNs; + double biasUncertaintyNs; + double driftNsps; + double driftUncertaintyNsps; + int hwClockDiscontinuityCount; + android.hardware.gnss.GnssSignalType referenceSignalTypeForIsb; + const int HAS_LEAP_SECOND = 1; + const int HAS_TIME_UNCERTAINTY = 2; + const int HAS_FULL_BIAS = 4; + const int HAS_BIAS = 8; + const int HAS_BIAS_UNCERTAINTY = 16; + const int HAS_DRIFT = 32; + const int HAS_DRIFT_UNCERTAINTY = 64; +} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/GnssConstellationType.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/GnssConstellationType.aidl new file mode 100644 index 0000000000..c1fcfcc741 --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/GnssConstellationType.aidl @@ -0,0 +1,45 @@ +/* + * 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 -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; +@Backing(type="int") @VintfStability +enum GnssConstellationType { + UNKNOWN = 0, + GPS = 1, + SBAS = 2, + GLONASS = 3, + QZSS = 4, + BEIDOU = 5, + GALILEO = 6, + IRNSS = 7, +} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/GnssData.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/GnssData.aidl new file mode 100644 index 0000000000..ebb5d0bdff --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/GnssData.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 -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.gnss; +@VintfStability +parcelable GnssData { + android.hardware.gnss.GnssMeasurement[] measurements; + android.hardware.gnss.GnssClock clock; + android.hardware.gnss.ElapsedRealtime elapsedRealtime; +} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/GnssMeasurement.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/GnssMeasurement.aidl new file mode 100644 index 0000000000..948c540fc3 --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/GnssMeasurement.aidl @@ -0,0 +1,98 @@ +/* + * 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 -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.gnss; +@VintfStability +parcelable GnssMeasurement { + int flags; + int svid; + android.hardware.gnss.GnssSignalType signalType; + double timeOffsetNs; + int state; + long receivedSvTimeInNs; + long receivedSvTimeUncertaintyInNs; + double antennaCN0DbHz; + double basebandCN0DbHz; + double pseudorangeRateMps; + double pseudorangeRateUncertaintyMps; + int accumulatedDeltaRangeState; + double accumulatedDeltaRangeM; + double accumulatedDeltaRangeUncertaintyM; + long carrierCycles; + double carrierPhase; + double carrierPhaseUncertainty; + android.hardware.gnss.GnssMultipathIndicator multipathIndicator = android.hardware.gnss.GnssMultipathIndicator.UNKNOWN; + double snrDb; + double agcLevelDb; + double fullInterSignalBiasNs; + double fullInterSignalBiasUncertaintyNs; + double satelliteInterSignalBiasNs; + double satelliteInterSignalBiasUncertaintyNs; + android.hardware.gnss.SatellitePvt satellitePvt; + android.hardware.gnss.CorrelationVector[] correlationVectors; + const int HAS_SNR = 1; + const int HAS_CARRIER_FREQUENCY = 512; + const int HAS_CARRIER_CYCLES = 1024; + const int HAS_CARRIER_PHASE = 2048; + const int HAS_CARRIER_PHASE_UNCERTAINTY = 4096; + const int HAS_AUTOMATIC_GAIN_CONTROL = 8192; + const int HAS_FULL_ISB = 65536; + const int HAS_FULL_ISB_UNCERTAINTY = 131072; + const int HAS_SATELLITE_ISB = 262144; + const int HAS_SATELLITE_ISB_UNCERTAINTY = 524288; + const int HAS_SATELLITE_PVT = 1048576; + const int HAS_CORRELATION_VECTOR = 2097152; + const int STATE_UNKNOWN = 0; + const int STATE_CODE_LOCK = 1; + const int STATE_BIT_SYNC = 2; + const int STATE_SUBFRAME_SYNC = 4; + const int STATE_TOW_DECODED = 8; + const int STATE_MSEC_AMBIGUOUS = 16; + const int STATE_SYMBOL_SYNC = 32; + const int STATE_GLO_STRING_SYNC = 64; + const int STATE_GLO_TOD_DECODED = 128; + const int STATE_BDS_D2_BIT_SYNC = 256; + const int STATE_BDS_D2_SUBFRAME_SYNC = 512; + const int STATE_GAL_E1BC_CODE_LOCK = 1024; + const int STATE_GAL_E1C_2ND_CODE_LOCK = 2048; + const int STATE_GAL_E1B_PAGE_SYNC = 4096; + const int STATE_SBAS_SYNC = 8192; + const int STATE_TOW_KNOWN = 16384; + const int STATE_GLO_TOD_KNOWN = 32768; + const int STATE_2ND_CODE_LOCK = 65536; + const int ADR_STATE_UNKNOWN = 0; + const int ADR_STATE_VALID = 1; + const int ADR_STATE_RESET = 2; + const int ADR_STATE_CYCLE_SLIP = 4; + const int ADR_STATE_HALF_CYCLE_RESOLVED = 8; +} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/GnssMultipathIndicator.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/GnssMultipathIndicator.aidl new file mode 100644 index 0000000000..24f45c42fa --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/GnssMultipathIndicator.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 -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; +@Backing(type="int") @VintfStability +enum GnssMultipathIndicator { + UNKNOWN = 0, + PRESENT = 1, + NOT_PRESENT = 2, +} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/GnssPowerStats.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/GnssPowerStats.aidl new file mode 100644 index 0000000000..670244fd1f --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/GnssPowerStats.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 -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.gnss; +@VintfStability +parcelable GnssPowerStats { + android.hardware.gnss.ElapsedRealtime elapsedRealtime; + double totalEnergyMilliJoule; + double singlebandTrackingModeEnergyMilliJoule; + double multibandTrackingModeEnergyMilliJoule; + double singlebandAcquisitionModeEnergyMilliJoule; + double multibandAcquisitionModeEnergyMilliJoule; + double[] otherModesEnergyMilliJoule; +} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/GnssSignalType.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/GnssSignalType.aidl new file mode 100644 index 0000000000..c2a5b51e15 --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/GnssSignalType.aidl @@ -0,0 +1,56 @@ +/* + * 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 -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.gnss; +@VintfStability +parcelable GnssSignalType { + android.hardware.gnss.GnssConstellationType constellation = android.hardware.gnss.GnssConstellationType.UNKNOWN; + double carrierFrequencyHz; + @utf8InCpp String codeType; + const @utf8InCpp String CODE_TYPE_A = "A"; + const @utf8InCpp String CODE_TYPE_B = "B"; + const @utf8InCpp String CODE_TYPE_C = "C"; + const @utf8InCpp String CODE_TYPE_D = "D"; + const @utf8InCpp String CODE_TYPE_I = "I"; + const @utf8InCpp String CODE_TYPE_L = "L"; + const @utf8InCpp String CODE_TYPE_M = "M"; + const @utf8InCpp String CODE_TYPE_N = "N"; + const @utf8InCpp String CODE_TYPE_P = "P"; + const @utf8InCpp String CODE_TYPE_Q = "Q"; + const @utf8InCpp String CODE_TYPE_S = "S"; + const @utf8InCpp String CODE_TYPE_W = "W"; + const @utf8InCpp String CODE_TYPE_X = "X"; + const @utf8InCpp String CODE_TYPE_Y = "Y"; + const @utf8InCpp String CODE_TYPE_Z = "Z"; + const @utf8InCpp String CODE_TYPE_UNKNOWN = "UNKNOWN"; +} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/IGnss.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/IGnss.aidl new file mode 100644 index 0000000000..f93b496cdd --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/IGnss.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 -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 IGnss { + void setCallback(in android.hardware.gnss.IGnssCallback callback); + void close(); + android.hardware.gnss.IGnssPsds getExtensionPsds(); + android.hardware.gnss.IGnssConfiguration getExtensionGnssConfiguration(); + android.hardware.gnss.IGnssMeasurementInterface getExtensionGnssMeasurement(); + android.hardware.gnss.IGnssPowerIndication getExtensionGnssPowerIndication(); + 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/1/android/hardware/gnss/IGnssCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/IGnssCallback.aidl new file mode 100644 index 0000000000..fb0931c59a --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/IGnssCallback.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 -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 IGnssCallback { + void gnssSetCapabilitiesCb(in int capabilities); + const int CAPABILITY_SATELLITE_BLOCKLIST = 512; + const int CAPABILITY_CORRELATION_VECTOR = 4096; + const int CAPABILITY_SATELLITE_PVT = 8192; + const int CAPABILITY_MEASUREMENT_CORRECTIONS_FOR_DRIVING = 16384; +} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/IGnssConfiguration.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/IGnssConfiguration.aidl new file mode 100644 index 0000000000..54cd022f66 --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/IGnssConfiguration.aidl @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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 IGnssConfiguration { + void setSuplVersion(in int version); + void setSuplMode(in int mode); + void setLppProfile(in int lppProfile); + void setGlonassPositioningProtocol(in int protocol); + void setEmergencySuplPdn(in boolean enable); + void setEsExtensionSec(in int emergencyExtensionSeconds); + void setBlocklist(in android.hardware.gnss.BlocklistedSource[] blocklist); + const int SUPL_MODE_MSB = 1; + const int SUPL_MODE_MSA = 2; + const int LPP_PROFILE_USER_PLANE = 1; + const int LPP_PROFILE_CONTROL_PLANE = 2; + const int GLONASS_POS_PROTOCOL_RRC_CPLANE = 1; + const int GLONASS_POS_PROTOCOL_RRLP_UPLANE = 2; + const int GLONASS_POS_PROTOCOL_LPP_UPLANE = 4; +} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/IGnssMeasurementCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/IGnssMeasurementCallback.aidl new file mode 100644 index 0000000000..6e626172b9 --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/IGnssMeasurementCallback.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 -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 IGnssMeasurementCallback { + void gnssMeasurementCb(in android.hardware.gnss.GnssData data); +} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/IGnssMeasurementInterface.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/IGnssMeasurementInterface.aidl new file mode 100644 index 0000000000..24d6f9c4cf --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/IGnssMeasurementInterface.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 -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 IGnssMeasurementInterface { + void setCallback(in android.hardware.gnss.IGnssMeasurementCallback callback, in boolean enableFullTracking, in boolean enableCorrVecOutputs); + void close(); +} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/IGnssPowerIndication.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/IGnssPowerIndication.aidl new file mode 100644 index 0000000000..fbf1f6ffb6 --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/IGnssPowerIndication.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 -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 IGnssPowerIndication { + void setCallback(in android.hardware.gnss.IGnssPowerIndicationCallback callback); + oneway void requestGnssPowerStats(); +} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/IGnssPowerIndicationCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/IGnssPowerIndicationCallback.aidl new file mode 100644 index 0000000000..bfa787e3e2 --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/IGnssPowerIndicationCallback.aidl @@ -0,0 +1,45 @@ +/* + * 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 -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 IGnssPowerIndicationCallback { + void setCapabilitiesCb(in int capabilities); + oneway void gnssPowerStatsCb(in android.hardware.gnss.GnssPowerStats gnssPowerStats); + const int CAPABILITY_TOTAL = 1; + const int CAPABILITY_SINGLEBAND_TRACKING = 2; + const int CAPABILITY_MULTIBAND_TRACKING = 4; + const int CAPABILITY_SINGLEBAND_ACQUISITION = 8; + const int CAPABILITY_MULTIBAND_ACQUISITION = 16; + const int CAPABILITY_OTHER_MODES = 32; +} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/IGnssPsds.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/IGnssPsds.aidl new file mode 100644 index 0000000000..526ecc8fcd --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/IGnssPsds.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 -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 IGnssPsds { + void injectPsdsData(in android.hardware.gnss.PsdsType psdsType, in byte[] psdsData); + void setCallback(in android.hardware.gnss.IGnssPsdsCallback callback); +} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/IGnssPsdsCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/IGnssPsdsCallback.aidl new file mode 100644 index 0000000000..2205bc46dd --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/IGnssPsdsCallback.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 -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 IGnssPsdsCallback { + void downloadRequestCb(in android.hardware.gnss.PsdsType psdsType); +} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/PsdsType.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/PsdsType.aidl new file mode 100644 index 0000000000..727bb6912b --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/PsdsType.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 -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; +@Backing(type="int") @VintfStability +enum PsdsType { + LONG_TERM = 1, + NORMAL = 2, + REALTIME = 3, +} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/SatelliteClockInfo.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/SatelliteClockInfo.aidl new file mode 100644 index 0000000000..ed23e639a8 --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/SatelliteClockInfo.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 -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.gnss; +@VintfStability +parcelable SatelliteClockInfo { + double satHardwareCodeBiasMeters; + double satTimeCorrectionMeters; + double satClkDriftMps; +} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/SatellitePositionEcef.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/SatellitePositionEcef.aidl new file mode 100644 index 0000000000..e1a20c378e --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/SatellitePositionEcef.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 -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.gnss; +@VintfStability +parcelable SatellitePositionEcef { + double posXMeters; + double posYMeters; + double posZMeters; + double ureMeters; +} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/SatellitePvt.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/SatellitePvt.aidl new file mode 100644 index 0000000000..8c1784174d --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/SatellitePvt.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 -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.gnss; +@VintfStability +parcelable SatellitePvt { + int flags; + android.hardware.gnss.SatellitePositionEcef satPosEcef; + android.hardware.gnss.SatelliteVelocityEcef satVelEcef; + android.hardware.gnss.SatelliteClockInfo satClockInfo; + double ionoDelayMeters; + double tropoDelayMeters; + const int HAS_POSITION_VELOCITY_CLOCK_INFO = 1; + const int HAS_IONO = 2; + const int HAS_TROPO = 4; +} diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/SatelliteVelocityEcef.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/SatelliteVelocityEcef.aidl new file mode 100644 index 0000000000..a571048c20 --- /dev/null +++ b/gnss/aidl/aidl_api/android.hardware.gnss/1/android/hardware/gnss/SatelliteVelocityEcef.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 -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.gnss; +@VintfStability +parcelable SatelliteVelocityEcef { + double velXMps; + double velYMps; + double velZMps; + double ureRateMps; +} diff --git a/graphics/common/aidl/Android.bp b/graphics/common/aidl/Android.bp index cadd13cdde..97d7a98062 100644 --- a/graphics/common/aidl/Android.bp +++ b/graphics/common/aidl/Android.bp @@ -39,5 +39,8 @@ aidl_interface { min_sdk_version: "29", }, }, - versions: ["1"], + versions: [ + "1", + "2", + ], } diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/.hash b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/.hash new file mode 100644 index 0000000000..167ed0e300 --- /dev/null +++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/.hash @@ -0,0 +1 @@ +bd2f5e2ab1d5112dfe982f64012e425f544c9d60 diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/BlendMode.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/BlendMode.aidl new file mode 100644 index 0000000000..1c1938105e --- /dev/null +++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/BlendMode.aidl @@ -0,0 +1,41 @@ +/** + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.graphics.common; +@Backing(type="int") @VintfStability +enum BlendMode { + INVALID = 0, + NONE = 1, + PREMULTIPLIED = 2, + COVERAGE = 3, +} diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/BufferUsage.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/BufferUsage.aidl new file mode 100644 index 0000000000..b4ef4515c7 --- /dev/null +++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/BufferUsage.aidl @@ -0,0 +1,63 @@ +/* + * Copyright 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.graphics.common; +@Backing(type="long") @VintfStability +enum BufferUsage { + CPU_READ_MASK = 15, + CPU_READ_NEVER = 0, + CPU_READ_RARELY = 2, + CPU_READ_OFTEN = 3, + CPU_WRITE_MASK = 240, + CPU_WRITE_NEVER = 0, + CPU_WRITE_RARELY = 32, + CPU_WRITE_OFTEN = 48, + GPU_TEXTURE = 256, + GPU_RENDER_TARGET = 512, + COMPOSER_OVERLAY = 2048, + COMPOSER_CLIENT_TARGET = 4096, + PROTECTED = 16384, + COMPOSER_CURSOR = 32768, + VIDEO_ENCODER = 65536, + CAMERA_OUTPUT = 131072, + CAMERA_INPUT = 262144, + RENDERSCRIPT = 1048576, + VIDEO_DECODER = 4194304, + SENSOR_DIRECT_DATA = 8388608, + GPU_CUBE_MAP = 33554432, + GPU_MIPMAP_COMPLETE = 67108864, + HW_IMAGE_ENCODER = 134217728, + GPU_DATA_BUFFER = 16777216, + VENDOR_MASK = -268435456, + VENDOR_MASK_HI = -281474976710656, +} diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/ChromaSiting.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/ChromaSiting.aidl new file mode 100644 index 0000000000..7f0d73460a --- /dev/null +++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/ChromaSiting.aidl @@ -0,0 +1,41 @@ +/** + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.graphics.common; +@Backing(type="long") @VintfStability +enum ChromaSiting { + NONE = 0, + UNKNOWN = 1, + SITED_INTERSTITIAL = 2, + COSITED_HORIZONTAL = 3, +} diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/Compression.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/Compression.aidl new file mode 100644 index 0000000000..5b76376a2e --- /dev/null +++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/Compression.aidl @@ -0,0 +1,39 @@ +/** + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.graphics.common; +@Backing(type="long") @VintfStability +enum Compression { + NONE = 0, + DISPLAY_STREAM_COMPRESSION = 1, +} diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/Cta861_3.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/Cta861_3.aidl new file mode 100644 index 0000000000..fbe4b2a4d2 --- /dev/null +++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/Cta861_3.aidl @@ -0,0 +1,39 @@ +/** + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.graphics.common; +@VintfStability +parcelable Cta861_3 { + float maxContentLightLevel; + float maxFrameAverageLightLevel; +} diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/Dataspace.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/Dataspace.aidl new file mode 100644 index 0000000000..3d97cff0d2 --- /dev/null +++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/Dataspace.aidl @@ -0,0 +1,97 @@ +/** + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.graphics.common; +@Backing(type="int") @VintfStability +enum Dataspace { + UNKNOWN = 0, + ARBITRARY = 1, + STANDARD_SHIFT = 16, + STANDARD_MASK = 4128768, + STANDARD_UNSPECIFIED = 0, + STANDARD_BT709 = 65536, + STANDARD_BT601_625 = 131072, + STANDARD_BT601_625_UNADJUSTED = 196608, + STANDARD_BT601_525 = 262144, + STANDARD_BT601_525_UNADJUSTED = 327680, + STANDARD_BT2020 = 393216, + STANDARD_BT2020_CONSTANT_LUMINANCE = 458752, + STANDARD_BT470M = 524288, + STANDARD_FILM = 589824, + STANDARD_DCI_P3 = 655360, + STANDARD_ADOBE_RGB = 720896, + TRANSFER_SHIFT = 22, + TRANSFER_MASK = 130023424, + TRANSFER_UNSPECIFIED = 0, + TRANSFER_LINEAR = 4194304, + TRANSFER_SRGB = 8388608, + TRANSFER_SMPTE_170M = 12582912, + TRANSFER_GAMMA2_2 = 16777216, + TRANSFER_GAMMA2_6 = 20971520, + TRANSFER_GAMMA2_8 = 25165824, + TRANSFER_ST2084 = 29360128, + TRANSFER_HLG = 33554432, + RANGE_SHIFT = 27, + RANGE_MASK = 939524096, + RANGE_UNSPECIFIED = 0, + RANGE_FULL = 134217728, + RANGE_LIMITED = 268435456, + RANGE_EXTENDED = 402653184, + SRGB_LINEAR = 138477568, + SCRGB_LINEAR = 406913024, + SRGB = 142671872, + SCRGB = 411107328, + JFIF = 146931712, + BT601_625 = 281149440, + BT601_525 = 281280512, + BT709 = 281083904, + DCI_P3_LINEAR = 139067392, + DCI_P3 = 155844608, + DISPLAY_P3_LINEAR = 139067392, + DISPLAY_P3 = 143261696, + ADOBE_RGB = 151715840, + BT2020_LINEAR = 138805248, + BT2020 = 147193856, + BT2020_PQ = 163971072, + DEPTH = 4096, + SENSOR = 4097, + BT2020_ITU = 281411584, + BT2020_ITU_PQ = 298188800, + BT2020_ITU_HLG = 302383104, + BT2020_HLG = 168165376, + DISPLAY_BT2020 = 142999552, + DYNAMIC_DEPTH = 4098, + JPEG_APP_SEGMENTS = 4099, + HEIF = 4100, + BT709_FULL_RANGE = 146866176, +} diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/ExtendableType.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/ExtendableType.aidl new file mode 100644 index 0000000000..3ada312a5c --- /dev/null +++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/ExtendableType.aidl @@ -0,0 +1,39 @@ +/** + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.graphics.common; +@VintfStability +parcelable ExtendableType { + @utf8InCpp String name; + long value = 0; +} diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/HardwareBuffer.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/HardwareBuffer.aidl new file mode 100644 index 0000000000..4d8f78d77c --- /dev/null +++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/HardwareBuffer.aidl @@ -0,0 +1,39 @@ +/* + * Copyright 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.graphics.common; +@VintfStability +parcelable HardwareBuffer { + android.hardware.graphics.common.HardwareBufferDescription description; + android.hardware.common.NativeHandle handle; +} diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/HardwareBufferDescription.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/HardwareBufferDescription.aidl new file mode 100644 index 0000000000..495504931d --- /dev/null +++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/HardwareBufferDescription.aidl @@ -0,0 +1,43 @@ +/* + * Copyright 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.graphics.common; +@VintfStability +parcelable HardwareBufferDescription { + int width; + int height; + int layers; + android.hardware.graphics.common.PixelFormat format = android.hardware.graphics.common.PixelFormat.UNSPECIFIED; + android.hardware.graphics.common.BufferUsage usage = android.hardware.graphics.common.BufferUsage.CPU_READ_NEVER; + int stride; +} diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/Interlaced.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/Interlaced.aidl new file mode 100644 index 0000000000..30b4e03c45 --- /dev/null +++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/Interlaced.aidl @@ -0,0 +1,40 @@ +/** + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.graphics.common; +@Backing(type="long") @VintfStability +enum Interlaced { + NONE = 0, + TOP_BOTTOM = 1, + RIGHT_LEFT = 2, +} diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/PixelFormat.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/PixelFormat.aidl new file mode 100644 index 0000000000..04a863be0a --- /dev/null +++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/PixelFormat.aidl @@ -0,0 +1,66 @@ +/* + * Copyright 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.graphics.common; +@Backing(type="int") @VintfStability +enum PixelFormat { + UNSPECIFIED = 0, + RGBA_8888 = 1, + RGBX_8888 = 2, + RGB_888 = 3, + RGB_565 = 4, + BGRA_8888 = 5, + YCBCR_422_SP = 16, + YCRCB_420_SP = 17, + YCBCR_422_I = 20, + RGBA_FP16 = 22, + RAW16 = 32, + BLOB = 33, + IMPLEMENTATION_DEFINED = 34, + YCBCR_420_888 = 35, + RAW_OPAQUE = 36, + RAW10 = 37, + RAW12 = 38, + RGBA_1010102 = 43, + Y8 = 538982489, + Y16 = 540422489, + YV12 = 842094169, + DEPTH_16 = 48, + DEPTH_24 = 49, + DEPTH_24_STENCIL_8 = 50, + DEPTH_32F = 51, + DEPTH_32F_STENCIL_8 = 52, + STENCIL_8 = 53, + YCBCR_P010 = 54, + HSV_888 = 55, +} diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/PlaneLayout.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/PlaneLayout.aidl new file mode 100644 index 0000000000..75fac9f3db --- /dev/null +++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/PlaneLayout.aidl @@ -0,0 +1,46 @@ +/** + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.graphics.common; +@VintfStability +parcelable PlaneLayout { + android.hardware.graphics.common.PlaneLayoutComponent[] components; + long offsetInBytes; + long sampleIncrementInBits; + long strideInBytes; + long widthInSamples; + long heightInSamples; + long totalSizeInBytes; + long horizontalSubsampling; + long verticalSubsampling; +} diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/PlaneLayoutComponent.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/PlaneLayoutComponent.aidl new file mode 100644 index 0000000000..20c0a0bb01 --- /dev/null +++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/PlaneLayoutComponent.aidl @@ -0,0 +1,40 @@ +/** + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.graphics.common; +@VintfStability +parcelable PlaneLayoutComponent { + android.hardware.graphics.common.ExtendableType type; + long offsetInBits; + long sizeInBits; +} diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/PlaneLayoutComponentType.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/PlaneLayoutComponentType.aidl new file mode 100644 index 0000000000..2f7d414aac --- /dev/null +++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/PlaneLayoutComponentType.aidl @@ -0,0 +1,45 @@ +/** + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.graphics.common; +@Backing(type="long") @VintfStability +enum PlaneLayoutComponentType { + Y = 1, + CB = 2, + CR = 4, + R = 1024, + G = 2048, + B = 4096, + RAW = 1048576, + A = 1073741824, +} diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/Rect.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/Rect.aidl new file mode 100644 index 0000000000..eb42027f16 --- /dev/null +++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/Rect.aidl @@ -0,0 +1,41 @@ +/** + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.graphics.common; +@VintfStability +parcelable Rect { + int left; + int top; + int right; + int bottom; +} diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/Smpte2086.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/Smpte2086.aidl new file mode 100644 index 0000000000..2be31d8e99 --- /dev/null +++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/Smpte2086.aidl @@ -0,0 +1,43 @@ +/** + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.graphics.common; +@VintfStability +parcelable Smpte2086 { + android.hardware.graphics.common.XyColor primaryRed; + android.hardware.graphics.common.XyColor primaryGreen; + android.hardware.graphics.common.XyColor primaryBlue; + android.hardware.graphics.common.XyColor whitePoint; + float maxLuminance; + float minLuminance; +} diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/StandardMetadataType.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/StandardMetadataType.aidl new file mode 100644 index 0000000000..20273501b9 --- /dev/null +++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/StandardMetadataType.aidl @@ -0,0 +1,59 @@ +/** + * Copyright (c) 2019,libgralloctypes_helper The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 -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.graphics.common; +@Backing(type="long") @VintfStability +enum StandardMetadataType { + INVALID = 0, + BUFFER_ID = 1, + NAME = 2, + WIDTH = 3, + HEIGHT = 4, + LAYER_COUNT = 5, + PIXEL_FORMAT_REQUESTED = 6, + PIXEL_FORMAT_FOURCC = 7, + PIXEL_FORMAT_MODIFIER = 8, + USAGE = 9, + ALLOCATION_SIZE = 10, + PROTECTED_CONTENT = 11, + COMPRESSION = 12, + INTERLACED = 13, + CHROMA_SITING = 14, + PLANE_LAYOUTS = 15, + CROP = 16, + DATASPACE = 17, + BLEND_MODE = 18, + SMPTE2086 = 19, + CTA861_3 = 20, + SMPTE2094_40 = 21, +} diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/XyColor.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/XyColor.aidl new file mode 100644 index 0000000000..b42de183dd --- /dev/null +++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/2/android/hardware/graphics/common/XyColor.aidl @@ -0,0 +1,39 @@ +/** + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.graphics.common; +@VintfStability +parcelable XyColor { + float x; + float y; +} diff --git a/health/storage/aidl/Android.bp b/health/storage/aidl/Android.bp index bf49466a91..4cd9263b2b 100644 --- a/health/storage/aidl/Android.bp +++ b/health/storage/aidl/Android.bp @@ -39,4 +39,5 @@ aidl_interface { }, }, }, + versions: ["1"], } diff --git a/health/storage/aidl/aidl_api/android.hardware.health.storage/1/.hash b/health/storage/aidl/aidl_api/android.hardware.health.storage/1/.hash new file mode 100644 index 0000000000..b1c5f89f97 --- /dev/null +++ b/health/storage/aidl/aidl_api/android.hardware.health.storage/1/.hash @@ -0,0 +1 @@ +3828640730cbf161d79e54dafce9470fdafcca1e diff --git a/health/storage/aidl/aidl_api/android.hardware.health.storage/1/android/hardware/health/storage/IGarbageCollectCallback.aidl b/health/storage/aidl/aidl_api/android.hardware.health.storage/1/android/hardware/health/storage/IGarbageCollectCallback.aidl new file mode 100644 index 0000000000..dc828c75eb --- /dev/null +++ b/health/storage/aidl/aidl_api/android.hardware.health.storage/1/android/hardware/health/storage/IGarbageCollectCallback.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 -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.health.storage; +@VintfStability +interface IGarbageCollectCallback { + oneway void onFinish(in android.hardware.health.storage.Result result); +} diff --git a/health/storage/aidl/aidl_api/android.hardware.health.storage/1/android/hardware/health/storage/IStorage.aidl b/health/storage/aidl/aidl_api/android.hardware.health.storage/1/android/hardware/health/storage/IStorage.aidl new file mode 100644 index 0000000000..b60cc971ba --- /dev/null +++ b/health/storage/aidl/aidl_api/android.hardware.health.storage/1/android/hardware/health/storage/IStorage.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 -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.health.storage; +@VintfStability +interface IStorage { + oneway void garbageCollect(in long timeoutSeconds, in android.hardware.health.storage.IGarbageCollectCallback callback); +} diff --git a/health/storage/aidl/aidl_api/android.hardware.health.storage/1/android/hardware/health/storage/Result.aidl b/health/storage/aidl/aidl_api/android.hardware.health.storage/1/android/hardware/health/storage/Result.aidl new file mode 100644 index 0000000000..c57a20cee8 --- /dev/null +++ b/health/storage/aidl/aidl_api/android.hardware.health.storage/1/android/hardware/health/storage/Result.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 -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.health.storage; +@Backing(type="int") @VintfStability +enum Result { + SUCCESS = 0, + IO_ERROR = 1, + UNKNOWN_ERROR = 2, +} diff --git a/identity/aidl/Android.bp b/identity/aidl/Android.bp index 8da664245d..dad3b8d74c 100644 --- a/identity/aidl/Android.bp +++ b/identity/aidl/Android.bp @@ -30,5 +30,6 @@ aidl_interface { versions: [ "1", "2", + "3", ], } diff --git a/identity/aidl/aidl_api/android.hardware.identity/3/.hash b/identity/aidl/aidl_api/android.hardware.identity/3/.hash new file mode 100644 index 0000000000..4f91388b57 --- /dev/null +++ b/identity/aidl/aidl_api/android.hardware.identity/3/.hash @@ -0,0 +1 @@ +1b6d65bb827aecd66860e06a8806dc77a8d3382b diff --git a/identity/aidl/aidl_api/android.hardware.identity/3/android/hardware/identity/Certificate.aidl b/identity/aidl/aidl_api/android.hardware.identity/3/android/hardware/identity/Certificate.aidl new file mode 100644 index 0000000000..83e1797386 --- /dev/null +++ b/identity/aidl/aidl_api/android.hardware.identity/3/android/hardware/identity/Certificate.aidl @@ -0,0 +1,38 @@ +/* + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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 +parcelable Certificate { + byte[] encodedCertificate; +} diff --git a/identity/aidl/aidl_api/android.hardware.identity/3/android/hardware/identity/CipherSuite.aidl b/identity/aidl/aidl_api/android.hardware.identity/3/android/hardware/identity/CipherSuite.aidl new file mode 100644 index 0000000000..e6ec04e805 --- /dev/null +++ b/identity/aidl/aidl_api/android.hardware.identity/3/android/hardware/identity/CipherSuite.aidl @@ -0,0 +1,38 @@ +/* + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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; +@Backing(type="int") @VintfStability +enum CipherSuite { + CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256 = 1, +} diff --git a/identity/aidl/aidl_api/android.hardware.identity/3/android/hardware/identity/HardwareInformation.aidl b/identity/aidl/aidl_api/android.hardware.identity/3/android/hardware/identity/HardwareInformation.aidl new file mode 100644 index 0000000000..cd8d56b5bd --- /dev/null +++ b/identity/aidl/aidl_api/android.hardware.identity/3/android/hardware/identity/HardwareInformation.aidl @@ -0,0 +1,42 @@ +/* + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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 +parcelable HardwareInformation { + @utf8InCpp String credentialStoreName; + @utf8InCpp String credentialStoreAuthorName; + int dataChunkSize; + boolean isDirectAccess; + @utf8InCpp String[] supportedDocTypes; +} diff --git a/identity/aidl/aidl_api/android.hardware.identity/3/android/hardware/identity/IIdentityCredential.aidl b/identity/aidl/aidl_api/android.hardware.identity/3/android/hardware/identity/IIdentityCredential.aidl new file mode 100644 index 0000000000..5065641109 --- /dev/null +++ b/identity/aidl/aidl_api/android.hardware.identity/3/android/hardware/identity/IIdentityCredential.aidl @@ -0,0 +1,54 @@ +/* + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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 IIdentityCredential { + /** + * @deprecated use deleteCredentalWithChallenge() instead. + */ + byte[] deleteCredential(); + byte[] createEphemeralKeyPair(); + void setReaderEphemeralPublicKey(in byte[] publicKey); + long createAuthChallenge(); + void startRetrieval(in android.hardware.identity.SecureAccessControlProfile[] accessControlProfiles, in android.hardware.keymaster.HardwareAuthToken authToken, in byte[] itemsRequest, in byte[] signingKeyBlob, in byte[] sessionTranscript, in byte[] readerSignature, in int[] requestCounts); + void startRetrieveEntryValue(in @utf8InCpp String nameSpace, in @utf8InCpp String name, in int entrySize, in int[] accessControlProfileIds); + byte[] retrieveEntryValue(in byte[] encryptedContent); + @SuppressWarnings(value={"out-array"}) void finishRetrieval(out byte[] mac, out byte[] deviceNameSpaces); + @SuppressWarnings(value={"out-array"}) android.hardware.identity.Certificate generateSigningKeyPair(out byte[] signingKeyBlob); + void setRequestedNamespaces(in android.hardware.identity.RequestNamespace[] requestNamespaces); + void setVerificationToken(in android.hardware.keymaster.VerificationToken verificationToken); + byte[] deleteCredentialWithChallenge(in byte[] challenge); + byte[] proveOwnership(in byte[] challenge); + android.hardware.identity.IWritableIdentityCredential updateCredential(); +} diff --git a/identity/aidl/aidl_api/android.hardware.identity/3/android/hardware/identity/IIdentityCredentialStore.aidl b/identity/aidl/aidl_api/android.hardware.identity/3/android/hardware/identity/IIdentityCredentialStore.aidl new file mode 100644 index 0000000000..c0eeabfd91 --- /dev/null +++ b/identity/aidl/aidl_api/android.hardware.identity/3/android/hardware/identity/IIdentityCredentialStore.aidl @@ -0,0 +1,53 @@ +/* + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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 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); + const int STATUS_OK = 0; + const int STATUS_FAILED = 1; + const int STATUS_CIPHER_SUITE_NOT_SUPPORTED = 2; + const int STATUS_INVALID_DATA = 3; + const int STATUS_INVALID_AUTH_TOKEN = 4; + const int STATUS_INVALID_ITEMS_REQUEST_MESSAGE = 5; + const int STATUS_READER_SIGNATURE_CHECK_FAILED = 6; + const int STATUS_EPHEMERAL_PUBLIC_KEY_NOT_FOUND = 7; + const int STATUS_USER_AUTHENTICATION_FAILED = 8; + const int STATUS_READER_AUTHENTICATION_FAILED = 9; + const int STATUS_NO_ACCESS_CONTROL_PROFILES = 10; + const int STATUS_NOT_IN_REQUEST_MESSAGE = 11; + const int STATUS_SESSION_TRANSCRIPT_MISMATCH = 12; +} diff --git a/identity/aidl/aidl_api/android.hardware.identity/3/android/hardware/identity/IWritableIdentityCredential.aidl b/identity/aidl/aidl_api/android.hardware.identity/3/android/hardware/identity/IWritableIdentityCredential.aidl new file mode 100644 index 0000000000..9a0fa9e9e5 --- /dev/null +++ b/identity/aidl/aidl_api/android.hardware.identity/3/android/hardware/identity/IWritableIdentityCredential.aidl @@ -0,0 +1,44 @@ +/* + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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 IWritableIdentityCredential { + android.hardware.identity.Certificate[] getAttestationCertificate(in byte[] attestationApplicationId, in byte[] attestationChallenge); + void startPersonalization(in int accessControlProfileCount, in int[] entryCounts); + android.hardware.identity.SecureAccessControlProfile addAccessControlProfile(in int id, in android.hardware.identity.Certificate readerCertificate, in boolean userAuthenticationRequired, in long timeoutMillis, in long secureUserId); + void beginAddEntry(in int[] accessControlProfileIds, in @utf8InCpp String nameSpace, in @utf8InCpp String name, in int entrySize); + byte[] addEntryValue(in byte[] content); + @SuppressWarnings(value={"out-array"}) void finishAddingEntries(out byte[] credentialData, out byte[] proofOfProvisioningSignature); + void setExpectedProofOfProvisioningSize(in int expectedProofOfProvisioningSize); +} diff --git a/identity/aidl/aidl_api/android.hardware.identity/3/android/hardware/identity/RequestDataItem.aidl b/identity/aidl/aidl_api/android.hardware.identity/3/android/hardware/identity/RequestDataItem.aidl new file mode 100644 index 0000000000..cec8e0c94d --- /dev/null +++ b/identity/aidl/aidl_api/android.hardware.identity/3/android/hardware/identity/RequestDataItem.aidl @@ -0,0 +1,40 @@ +/* + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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 +parcelable RequestDataItem { + @utf8InCpp String name; + long size; + int[] accessControlProfileIds; +} diff --git a/identity/aidl/aidl_api/android.hardware.identity/3/android/hardware/identity/RequestNamespace.aidl b/identity/aidl/aidl_api/android.hardware.identity/3/android/hardware/identity/RequestNamespace.aidl new file mode 100644 index 0000000000..05b9ec295f --- /dev/null +++ b/identity/aidl/aidl_api/android.hardware.identity/3/android/hardware/identity/RequestNamespace.aidl @@ -0,0 +1,39 @@ +/* + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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 +parcelable RequestNamespace { + @utf8InCpp String namespaceName; + android.hardware.identity.RequestDataItem[] items; +} diff --git a/identity/aidl/aidl_api/android.hardware.identity/3/android/hardware/identity/SecureAccessControlProfile.aidl b/identity/aidl/aidl_api/android.hardware.identity/3/android/hardware/identity/SecureAccessControlProfile.aidl new file mode 100644 index 0000000000..2003594eb4 --- /dev/null +++ b/identity/aidl/aidl_api/android.hardware.identity/3/android/hardware/identity/SecureAccessControlProfile.aidl @@ -0,0 +1,43 @@ +/* + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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 +parcelable SecureAccessControlProfile { + int id; + android.hardware.identity.Certificate readerCertificate; + boolean userAuthenticationRequired; + long timeoutMillis; + long secureUserId; + byte[] mac; +} diff --git a/keymaster/aidl/Android.bp b/keymaster/aidl/Android.bp index b7a261c596..c4b6740ed4 100644 --- a/keymaster/aidl/Android.bp +++ b/keymaster/aidl/Android.bp @@ -27,5 +27,6 @@ aidl_interface { versions: [ "1", "2", + "3", ], } diff --git a/keymaster/aidl/aidl_api/android.hardware.keymaster/3/.hash b/keymaster/aidl/aidl_api/android.hardware.keymaster/3/.hash new file mode 100644 index 0000000000..acec81a5eb --- /dev/null +++ b/keymaster/aidl/aidl_api/android.hardware.keymaster/3/.hash @@ -0,0 +1 @@ +38887f224e43273b344a5400e5441d6609bf8b2f diff --git a/keymaster/aidl/aidl_api/android.hardware.keymaster/3/android/hardware/keymaster/HardwareAuthToken.aidl b/keymaster/aidl/aidl_api/android.hardware.keymaster/3/android/hardware/keymaster/HardwareAuthToken.aidl new file mode 100644 index 0000000000..058f23ee96 --- /dev/null +++ b/keymaster/aidl/aidl_api/android.hardware.keymaster/3/android/hardware/keymaster/HardwareAuthToken.aidl @@ -0,0 +1,43 @@ +/* + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.keymaster; +@VintfStability +parcelable HardwareAuthToken { + long challenge; + long userId; + long authenticatorId; + android.hardware.keymaster.HardwareAuthenticatorType authenticatorType = android.hardware.keymaster.HardwareAuthenticatorType.NONE; + android.hardware.keymaster.Timestamp timestamp; + byte[] mac; +} diff --git a/keymaster/aidl/aidl_api/android.hardware.keymaster/3/android/hardware/keymaster/HardwareAuthenticatorType.aidl b/keymaster/aidl/aidl_api/android.hardware.keymaster/3/android/hardware/keymaster/HardwareAuthenticatorType.aidl new file mode 100644 index 0000000000..74535ebe87 --- /dev/null +++ b/keymaster/aidl/aidl_api/android.hardware.keymaster/3/android/hardware/keymaster/HardwareAuthenticatorType.aidl @@ -0,0 +1,41 @@ +/* + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.keymaster; +@Backing(type="int") @VintfStability +enum HardwareAuthenticatorType { + NONE = 0, + PASSWORD = 1, + FINGERPRINT = 2, + ANY = -1, +} diff --git a/keymaster/aidl/aidl_api/android.hardware.keymaster/3/android/hardware/keymaster/SecurityLevel.aidl b/keymaster/aidl/aidl_api/android.hardware.keymaster/3/android/hardware/keymaster/SecurityLevel.aidl new file mode 100644 index 0000000000..458303218e --- /dev/null +++ b/keymaster/aidl/aidl_api/android.hardware.keymaster/3/android/hardware/keymaster/SecurityLevel.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 -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.keymaster; +@Backing(type="int") @VintfStability +enum SecurityLevel { + SOFTWARE = 0, + TRUSTED_ENVIRONMENT = 1, + STRONGBOX = 2, +} diff --git a/keymaster/aidl/aidl_api/android.hardware.keymaster/3/android/hardware/keymaster/Timestamp.aidl b/keymaster/aidl/aidl_api/android.hardware.keymaster/3/android/hardware/keymaster/Timestamp.aidl new file mode 100644 index 0000000000..e0b7c4874f --- /dev/null +++ b/keymaster/aidl/aidl_api/android.hardware.keymaster/3/android/hardware/keymaster/Timestamp.aidl @@ -0,0 +1,38 @@ +/* + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.keymaster; +@VintfStability +parcelable Timestamp { + long milliSeconds; +} diff --git a/keymaster/aidl/aidl_api/android.hardware.keymaster/3/android/hardware/keymaster/VerificationToken.aidl b/keymaster/aidl/aidl_api/android.hardware.keymaster/3/android/hardware/keymaster/VerificationToken.aidl new file mode 100644 index 0000000000..7862b5e83c --- /dev/null +++ b/keymaster/aidl/aidl_api/android.hardware.keymaster/3/android/hardware/keymaster/VerificationToken.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 -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.keymaster; +@VintfStability +parcelable VerificationToken { + long challenge; + android.hardware.keymaster.Timestamp timestamp; + android.hardware.keymaster.SecurityLevel securityLevel = android.hardware.keymaster.SecurityLevel.SOFTWARE; + byte[] mac; +} diff --git a/memtrack/aidl/Android.bp b/memtrack/aidl/Android.bp index 29fec2451f..79effcb7a8 100644 --- a/memtrack/aidl/Android.bp +++ b/memtrack/aidl/Android.bp @@ -39,4 +39,5 @@ aidl_interface { }, }, }, + versions: ["1"], } diff --git a/memtrack/aidl/aidl_api/android.hardware.memtrack/1/.hash b/memtrack/aidl/aidl_api/android.hardware.memtrack/1/.hash new file mode 100644 index 0000000000..d2c24d0bb1 --- /dev/null +++ b/memtrack/aidl/aidl_api/android.hardware.memtrack/1/.hash @@ -0,0 +1 @@ +25438132a462bf5b6f4334d966c95b70824e66c0 diff --git a/memtrack/aidl/aidl_api/android.hardware.memtrack/1/android/hardware/memtrack/DeviceInfo.aidl b/memtrack/aidl/aidl_api/android.hardware.memtrack/1/android/hardware/memtrack/DeviceInfo.aidl new file mode 100644 index 0000000000..671e118e92 --- /dev/null +++ b/memtrack/aidl/aidl_api/android.hardware.memtrack/1/android/hardware/memtrack/DeviceInfo.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 -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.memtrack; +@VintfStability +parcelable DeviceInfo { + int id; + @utf8InCpp String name; +} diff --git a/memtrack/aidl/aidl_api/android.hardware.memtrack/1/android/hardware/memtrack/IMemtrack.aidl b/memtrack/aidl/aidl_api/android.hardware.memtrack/1/android/hardware/memtrack/IMemtrack.aidl new file mode 100644 index 0000000000..9d490c0819 --- /dev/null +++ b/memtrack/aidl/aidl_api/android.hardware.memtrack/1/android/hardware/memtrack/IMemtrack.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 -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.memtrack; +@VintfStability +interface IMemtrack { + android.hardware.memtrack.MemtrackRecord[] getMemory(in int pid, in android.hardware.memtrack.MemtrackType type); + android.hardware.memtrack.DeviceInfo[] getGpuDeviceInfo(); +} diff --git a/memtrack/aidl/aidl_api/android.hardware.memtrack/1/android/hardware/memtrack/MemtrackRecord.aidl b/memtrack/aidl/aidl_api/android.hardware.memtrack/1/android/hardware/memtrack/MemtrackRecord.aidl new file mode 100644 index 0000000000..8c9109b353 --- /dev/null +++ b/memtrack/aidl/aidl_api/android.hardware.memtrack/1/android/hardware/memtrack/MemtrackRecord.aidl @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * 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 -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.memtrack; +@VintfStability +parcelable MemtrackRecord { + int flags; + long sizeInBytes; + const int FLAG_SMAPS_ACCOUNTED = 2; + const int FLAG_SMAPS_UNACCOUNTED = 4; + const int FLAG_SHARED = 8; + const int FLAG_SHARED_PSS = 16; + const int FLAG_PRIVATE = 32; + const int FLAG_SYSTEM = 64; + const int FLAG_DEDICATED = 128; + const int FLAG_NONSECURE = 256; + const int FLAG_SECURE = 512; +} diff --git a/memtrack/aidl/aidl_api/android.hardware.memtrack/1/android/hardware/memtrack/MemtrackType.aidl b/memtrack/aidl/aidl_api/android.hardware.memtrack/1/android/hardware/memtrack/MemtrackType.aidl new file mode 100644 index 0000000000..1458640a24 --- /dev/null +++ b/memtrack/aidl/aidl_api/android.hardware.memtrack/1/android/hardware/memtrack/MemtrackType.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 -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.memtrack; +@Backing(type="int") @VintfStability +enum MemtrackType { + OTHER = 0, + GL = 1, + GRAPHICS = 2, + MULTIMEDIA = 3, + CAMERA = 4, +} diff --git a/neuralnetworks/aidl/Android.bp b/neuralnetworks/aidl/Android.bp index ebf4654885..1b1e78fb5c 100644 --- a/neuralnetworks/aidl/Android.bp +++ b/neuralnetworks/aidl/Android.bp @@ -34,4 +34,5 @@ aidl_interface { min_sdk_version: "30", }, }, + versions: ["1"], } diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/.hash b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/.hash new file mode 100644 index 0000000000..b0dfd99800 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/.hash @@ -0,0 +1 @@ +ae57b48403df6752d8d8d56d215c3e31db74935d diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/BufferDesc.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/BufferDesc.aidl new file mode 100644 index 0000000000..05cec76c88 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/BufferDesc.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 -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 BufferDesc { + int[] dimensions; +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/BufferRole.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/BufferRole.aidl new file mode 100644 index 0000000000..10a6b75ac7 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/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 -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/1/android/hardware/neuralnetworks/Capabilities.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/Capabilities.aidl new file mode 100644 index 0000000000..30877c0294 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/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 -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/1/android/hardware/neuralnetworks/DataLocation.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/DataLocation.aidl new file mode 100644 index 0000000000..db49a38979 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/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 -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/1/android/hardware/neuralnetworks/DeviceBuffer.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/DeviceBuffer.aidl new file mode 100644 index 0000000000..7cdd6db742 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/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 -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/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/DeviceType.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/DeviceType.aidl new file mode 100644 index 0000000000..82fe8ae3e7 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/DeviceType.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 -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 DeviceType { + OTHER = 1, + CPU = 2, + GPU = 3, + ACCELERATOR = 4, +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/ErrorStatus.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/ErrorStatus.aidl new file mode 100644 index 0000000000..57d5d6e4cd --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/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 -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/1/android/hardware/neuralnetworks/ExecutionPreference.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/ExecutionPreference.aidl new file mode 100644 index 0000000000..4352d8f334 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/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 -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/1/android/hardware/neuralnetworks/ExecutionResult.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/ExecutionResult.aidl new file mode 100644 index 0000000000..44e9922f52 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/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 -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/1/android/hardware/neuralnetworks/Extension.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/Extension.aidl new file mode 100644 index 0000000000..c47028d99f --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/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 -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/1/android/hardware/neuralnetworks/ExtensionNameAndPrefix.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/ExtensionNameAndPrefix.aidl new file mode 100644 index 0000000000..6c287fd460 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/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 -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/1/android/hardware/neuralnetworks/ExtensionOperandTypeInformation.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/ExtensionOperandTypeInformation.aidl new file mode 100644 index 0000000000..a3680aa9dd --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/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 -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/1/android/hardware/neuralnetworks/FencedExecutionResult.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/FencedExecutionResult.aidl new file mode 100644 index 0000000000..7952b34632 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/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 -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/1/android/hardware/neuralnetworks/FusedActivationFunc.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/FusedActivationFunc.aidl new file mode 100644 index 0000000000..7e61bbbdb1 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/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 -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/1/android/hardware/neuralnetworks/IBuffer.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/IBuffer.aidl new file mode 100644 index 0000000000..f10e7e24ca --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/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 -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/1/android/hardware/neuralnetworks/IBurst.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/IBurst.aidl new file mode 100644 index 0000000000..eb3d0b004a --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/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 -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/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/IDevice.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/IDevice.aidl new file mode 100644 index 0000000000..c9c67f2fcd --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/IDevice.aidl @@ -0,0 +1,52 @@ +/* + * 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 -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 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/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/IFencedExecutionCallback.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/IFencedExecutionCallback.aidl new file mode 100644 index 0000000000..0bfb80ac78 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/IFencedExecutionCallback.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 -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 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/1/android/hardware/neuralnetworks/IPreparedModel.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/IPreparedModel.aidl new file mode 100644 index 0000000000..fccb5dc98e --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/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 -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/1/android/hardware/neuralnetworks/IPreparedModelCallback.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/IPreparedModelCallback.aidl new file mode 100644 index 0000000000..e0c763bc2a --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/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 -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/1/android/hardware/neuralnetworks/IPreparedModelParcel.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/IPreparedModelParcel.aidl new file mode 100644 index 0000000000..dbedf12772 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/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 -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/1/android/hardware/neuralnetworks/Memory.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/Memory.aidl new file mode 100644 index 0000000000..37fa102cf4 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/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 -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/1/android/hardware/neuralnetworks/Model.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/Model.aidl new file mode 100644 index 0000000000..30d8dda55d --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/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 -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/1/android/hardware/neuralnetworks/NumberOfCacheFiles.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/NumberOfCacheFiles.aidl new file mode 100644 index 0000000000..9314760a43 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/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 -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/1/android/hardware/neuralnetworks/Operand.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/Operand.aidl new file mode 100644 index 0000000000..1d9bdd8446 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/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 -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/1/android/hardware/neuralnetworks/OperandExtraParams.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/OperandExtraParams.aidl new file mode 100644 index 0000000000..14792cff08 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/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 -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/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/OperandLifeTime.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/OperandLifeTime.aidl new file mode 100644 index 0000000000..40adfb1dd8 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/OperandLifeTime.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 -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 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/1/android/hardware/neuralnetworks/OperandPerformance.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/OperandPerformance.aidl new file mode 100644 index 0000000000..ebb361b762 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/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 -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/1/android/hardware/neuralnetworks/OperandType.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/OperandType.aidl new file mode 100644 index 0000000000..9f2c759d38 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/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 -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/1/android/hardware/neuralnetworks/Operation.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/Operation.aidl new file mode 100644 index 0000000000..a4a3fbee60 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/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 -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/1/android/hardware/neuralnetworks/OperationType.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/OperationType.aidl new file mode 100644 index 0000000000..de3b438115 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/OperationType.aidl @@ -0,0 +1,139 @@ +/* + * 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 -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, +} diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/OutputShape.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/OutputShape.aidl new file mode 100644 index 0000000000..f7335054cf --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/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 -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/1/android/hardware/neuralnetworks/PerformanceInfo.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/PerformanceInfo.aidl new file mode 100644 index 0000000000..04910f5410 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/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 -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/1/android/hardware/neuralnetworks/Priority.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/Priority.aidl new file mode 100644 index 0000000000..8f357097ab --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/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 -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/1/android/hardware/neuralnetworks/Request.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/Request.aidl new file mode 100644 index 0000000000..39ec7a9acd --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/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 -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/1/android/hardware/neuralnetworks/RequestArgument.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/RequestArgument.aidl new file mode 100644 index 0000000000..e3541c0ece --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/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 -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/1/android/hardware/neuralnetworks/RequestMemoryPool.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/RequestMemoryPool.aidl new file mode 100644 index 0000000000..312f5813bc --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/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 -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/1/android/hardware/neuralnetworks/Subgraph.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/Subgraph.aidl new file mode 100644 index 0000000000..b7d44515f4 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/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 -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/1/android/hardware/neuralnetworks/SymmPerChannelQuantParams.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/SymmPerChannelQuantParams.aidl new file mode 100644 index 0000000000..02d68f9ed1 --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/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 -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/1/android/hardware/neuralnetworks/Timing.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/android/hardware/neuralnetworks/Timing.aidl new file mode 100644 index 0000000000..bcc83cfbee --- /dev/null +++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/1/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 -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/oemlock/aidl/Android.bp b/oemlock/aidl/Android.bp index 439d43d760..d1930f982e 100644 --- a/oemlock/aidl/Android.bp +++ b/oemlock/aidl/Android.bp @@ -22,4 +22,5 @@ aidl_interface { }, }, }, + versions: ["1"], } diff --git a/oemlock/aidl/aidl_api/android.hardware.oemlock/1/.hash b/oemlock/aidl/aidl_api/android.hardware.oemlock/1/.hash new file mode 100644 index 0000000000..79fe165613 --- /dev/null +++ b/oemlock/aidl/aidl_api/android.hardware.oemlock/1/.hash @@ -0,0 +1 @@ +782d36d56fbdca1105672dd96b8e955b6a81dadf diff --git a/oemlock/aidl/aidl_api/android.hardware.oemlock/1/android/hardware/oemlock/IOemLock.aidl b/oemlock/aidl/aidl_api/android.hardware.oemlock/1/android/hardware/oemlock/IOemLock.aidl new file mode 100644 index 0000000000..977746c4dd --- /dev/null +++ b/oemlock/aidl/aidl_api/android.hardware.oemlock/1/android/hardware/oemlock/IOemLock.aidl @@ -0,0 +1,42 @@ +/* + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.oemlock; +@VintfStability +interface IOemLock { + String getName(); + boolean isOemUnlockAllowedByCarrier(); + boolean isOemUnlockAllowedByDevice(); + android.hardware.oemlock.OemLockSecureStatus setOemUnlockAllowedByCarrier(in boolean allowed, in byte[] signature); + void setOemUnlockAllowedByDevice(in boolean allowed); +} diff --git a/oemlock/aidl/aidl_api/android.hardware.oemlock/1/android/hardware/oemlock/OemLockSecureStatus.aidl b/oemlock/aidl/aidl_api/android.hardware.oemlock/1/android/hardware/oemlock/OemLockSecureStatus.aidl new file mode 100644 index 0000000000..8376744edc --- /dev/null +++ b/oemlock/aidl/aidl_api/android.hardware.oemlock/1/android/hardware/oemlock/OemLockSecureStatus.aidl @@ -0,0 +1,40 @@ +/* + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.oemlock; +@Backing(type="int") @VintfStability +enum OemLockSecureStatus { + OK = 0, + FAILED = 1, + INVALID_SIGNATURE = 2, +} diff --git a/power/aidl/Android.bp b/power/aidl/Android.bp index dbd18fd5ec..c722795a6c 100644 --- a/power/aidl/Android.bp +++ b/power/aidl/Android.bp @@ -43,5 +43,6 @@ aidl_interface { }, versions: [ "1", + "2", ], } diff --git a/power/aidl/aidl_api/android.hardware.power/2/.hash b/power/aidl/aidl_api/android.hardware.power/2/.hash new file mode 100644 index 0000000000..0671909cca --- /dev/null +++ b/power/aidl/aidl_api/android.hardware.power/2/.hash @@ -0,0 +1 @@ +ef4f5ed58e39693f25c1f8fdcfe7b958c6b800bc diff --git a/power/aidl/aidl_api/android.hardware.power/2/android/hardware/power/Boost.aidl b/power/aidl/aidl_api/android.hardware.power/2/android/hardware/power/Boost.aidl new file mode 100644 index 0000000000..c792d4e0c2 --- /dev/null +++ b/power/aidl/aidl_api/android.hardware.power/2/android/hardware/power/Boost.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 -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.power; +@Backing(type="int") @VintfStability +enum Boost { + INTERACTION = 0, + DISPLAY_UPDATE_IMMINENT = 1, + ML_ACC = 2, + AUDIO_LAUNCH = 3, + CAMERA_LAUNCH = 4, + CAMERA_SHOT = 5, +} diff --git a/power/aidl/aidl_api/android.hardware.power/2/android/hardware/power/IPower.aidl b/power/aidl/aidl_api/android.hardware.power/2/android/hardware/power/IPower.aidl new file mode 100644 index 0000000000..ae03313f11 --- /dev/null +++ b/power/aidl/aidl_api/android.hardware.power/2/android/hardware/power/IPower.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 -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.power; +@VintfStability +interface IPower { + oneway void setMode(in android.hardware.power.Mode type, in boolean enabled); + boolean isModeSupported(in android.hardware.power.Mode type); + oneway void setBoost(in android.hardware.power.Boost type, in int durationMs); + boolean isBoostSupported(in android.hardware.power.Boost type); + android.hardware.power.IPowerHintSession createHintSession(in int tgid, in int uid, in int[] threadIds, in long durationNanos); + long getHintSessionPreferredRate(); +} diff --git a/power/aidl/aidl_api/android.hardware.power/2/android/hardware/power/IPowerHintSession.aidl b/power/aidl/aidl_api/android.hardware.power/2/android/hardware/power/IPowerHintSession.aidl new file mode 100644 index 0000000000..1d3ecb7eee --- /dev/null +++ b/power/aidl/aidl_api/android.hardware.power/2/android/hardware/power/IPowerHintSession.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 -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.power; +@VintfStability +interface IPowerHintSession { + oneway void updateTargetWorkDuration(long targetDurationNanos); + oneway void reportActualWorkDuration(in android.hardware.power.WorkDuration[] durations); + oneway void pause(); + oneway void resume(); + oneway void close(); +} diff --git a/power/aidl/aidl_api/android.hardware.power/2/android/hardware/power/Mode.aidl b/power/aidl/aidl_api/android.hardware.power/2/android/hardware/power/Mode.aidl new file mode 100644 index 0000000000..8920c014e3 --- /dev/null +++ b/power/aidl/aidl_api/android.hardware.power/2/android/hardware/power/Mode.aidl @@ -0,0 +1,52 @@ +/* + * 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 -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.power; +@Backing(type="int") @VintfStability +enum Mode { + DOUBLE_TAP_TO_WAKE = 0, + LOW_POWER = 1, + SUSTAINED_PERFORMANCE = 2, + FIXED_PERFORMANCE = 3, + VR = 4, + LAUNCH = 5, + EXPENSIVE_RENDERING = 6, + INTERACTIVE = 7, + DEVICE_IDLE = 8, + DISPLAY_INACTIVE = 9, + AUDIO_STREAMING_LOW_LATENCY = 10, + CAMERA_STREAMING_SECURE = 11, + CAMERA_STREAMING_LOW = 12, + CAMERA_STREAMING_MID = 13, + CAMERA_STREAMING_HIGH = 14, +} diff --git a/power/aidl/aidl_api/android.hardware.power/2/android/hardware/power/WorkDuration.aidl b/power/aidl/aidl_api/android.hardware.power/2/android/hardware/power/WorkDuration.aidl new file mode 100644 index 0000000000..e86cd40ec2 --- /dev/null +++ b/power/aidl/aidl_api/android.hardware.power/2/android/hardware/power/WorkDuration.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 -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.power; +@VintfStability +parcelable WorkDuration { + long timeStampNanos; + long durationNanos; +} diff --git a/power/stats/aidl/Android.bp b/power/stats/aidl/Android.bp index 0dbf9b49e0..48d3c51f1a 100644 --- a/power/stats/aidl/Android.bp +++ b/power/stats/aidl/Android.bp @@ -42,4 +42,5 @@ aidl_interface { }, }, host_supported: true, + versions: ["1"], } diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/1/.hash b/power/stats/aidl/aidl_api/android.hardware.power.stats/1/.hash new file mode 100644 index 0000000000..c248cc300a --- /dev/null +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/1/.hash @@ -0,0 +1 @@ +93253458fae451cf1187db6120a59fab428f7d02 diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/1/android/hardware/power/stats/Channel.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/1/android/hardware/power/stats/Channel.aidl new file mode 100644 index 0000000000..d1048a4095 --- /dev/null +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/1/android/hardware/power/stats/Channel.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 -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.power.stats; +@VintfStability +parcelable Channel { + int id; + @utf8InCpp String name; + @utf8InCpp String subsystem; +} diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/1/android/hardware/power/stats/EnergyConsumer.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/1/android/hardware/power/stats/EnergyConsumer.aidl new file mode 100644 index 0000000000..13f528d57b --- /dev/null +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/1/android/hardware/power/stats/EnergyConsumer.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 -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.power.stats; +@VintfStability +parcelable EnergyConsumer { + int id; + int ordinal; + android.hardware.power.stats.EnergyConsumerType type = android.hardware.power.stats.EnergyConsumerType.OTHER; + @utf8InCpp String name; +} diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/1/android/hardware/power/stats/EnergyConsumerAttribution.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/1/android/hardware/power/stats/EnergyConsumerAttribution.aidl new file mode 100644 index 0000000000..ee120685c7 --- /dev/null +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/1/android/hardware/power/stats/EnergyConsumerAttribution.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 -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.power.stats; +@VintfStability +parcelable EnergyConsumerAttribution { + int uid; + long energyUWs; +} diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/1/android/hardware/power/stats/EnergyConsumerResult.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/1/android/hardware/power/stats/EnergyConsumerResult.aidl new file mode 100644 index 0000000000..7d8aa989cd --- /dev/null +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/1/android/hardware/power/stats/EnergyConsumerResult.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 -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.power.stats; +@VintfStability +parcelable EnergyConsumerResult { + int id; + long timestampMs; + long energyUWs; + android.hardware.power.stats.EnergyConsumerAttribution[] attribution; +} diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/1/android/hardware/power/stats/EnergyConsumerType.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/1/android/hardware/power/stats/EnergyConsumerType.aidl new file mode 100644 index 0000000000..fbd31970b6 --- /dev/null +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/1/android/hardware/power/stats/EnergyConsumerType.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 -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.power.stats; +@VintfStability +enum EnergyConsumerType { + OTHER = 0, + BLUETOOTH = 1, + CPU_CLUSTER = 2, + DISPLAY = 3, + GNSS = 4, + MOBILE_RADIO = 5, + WIFI = 6, +} diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/1/android/hardware/power/stats/EnergyMeasurement.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/1/android/hardware/power/stats/EnergyMeasurement.aidl new file mode 100644 index 0000000000..ffe3aa48c5 --- /dev/null +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/1/android/hardware/power/stats/EnergyMeasurement.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 -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.power.stats; +@VintfStability +parcelable EnergyMeasurement { + int id; + long timestampMs; + long durationMs; + long energyUWs; +} diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/1/android/hardware/power/stats/IPowerStats.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/1/android/hardware/power/stats/IPowerStats.aidl new file mode 100644 index 0000000000..79175158e4 --- /dev/null +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/1/android/hardware/power/stats/IPowerStats.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 -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.power.stats; +@VintfStability +interface IPowerStats { + android.hardware.power.stats.PowerEntity[] getPowerEntityInfo(); + android.hardware.power.stats.StateResidencyResult[] getStateResidency(in int[] powerEntityIds); + android.hardware.power.stats.EnergyConsumer[] getEnergyConsumerInfo(); + android.hardware.power.stats.EnergyConsumerResult[] getEnergyConsumed(in int[] energyConsumerIds); + android.hardware.power.stats.Channel[] getEnergyMeterInfo(); + android.hardware.power.stats.EnergyMeasurement[] readEnergyMeter(in int[] channelIds); +} diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/1/android/hardware/power/stats/PowerEntity.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/1/android/hardware/power/stats/PowerEntity.aidl new file mode 100644 index 0000000000..f42e715cfd --- /dev/null +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/1/android/hardware/power/stats/PowerEntity.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 -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.power.stats; +@VintfStability +parcelable PowerEntity { + int id; + @utf8InCpp String name; + android.hardware.power.stats.State[] states; +} diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/1/android/hardware/power/stats/State.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/1/android/hardware/power/stats/State.aidl new file mode 100644 index 0000000000..cf29dd714f --- /dev/null +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/1/android/hardware/power/stats/State.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 -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.power.stats; +@VintfStability +parcelable State { + int id; + @utf8InCpp String name; +} diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/1/android/hardware/power/stats/StateResidency.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/1/android/hardware/power/stats/StateResidency.aidl new file mode 100644 index 0000000000..0af35b391c --- /dev/null +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/1/android/hardware/power/stats/StateResidency.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 -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.power.stats; +@VintfStability +parcelable StateResidency { + int id; + long totalTimeInStateMs; + long totalStateEntryCount; + long lastEntryTimestampMs; +} diff --git a/power/stats/aidl/aidl_api/android.hardware.power.stats/1/android/hardware/power/stats/StateResidencyResult.aidl b/power/stats/aidl/aidl_api/android.hardware.power.stats/1/android/hardware/power/stats/StateResidencyResult.aidl new file mode 100644 index 0000000000..14358b7fed --- /dev/null +++ b/power/stats/aidl/aidl_api/android.hardware.power.stats/1/android/hardware/power/stats/StateResidencyResult.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 -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.power.stats; +@VintfStability +parcelable StateResidencyResult { + int id; + android.hardware.power.stats.StateResidency[] stateResidencyData; +} diff --git a/security/keymint/aidl/Android.bp b/security/keymint/aidl/Android.bp index 0c11f3b787..694ce6a22e 100644 --- a/security/keymint/aidl/Android.bp +++ b/security/keymint/aidl/Android.bp @@ -32,4 +32,5 @@ aidl_interface { enabled: true, }, }, + versions: ["1"], } diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/.hash b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/.hash new file mode 100644 index 0000000000..b712a5231b --- /dev/null +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/.hash @@ -0,0 +1 @@ +976674616001f714f4a4df49ee45f548de828524 diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/Algorithm.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/Algorithm.aidl new file mode 100644 index 0000000000..6da124f601 --- /dev/null +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/Algorithm.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 -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.security.keymint; +/* @hide */ +@Backing(type="int") @VintfStability +enum Algorithm { + RSA = 1, + EC = 3, + AES = 32, + TRIPLE_DES = 33, + HMAC = 128, +} diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/AttestationKey.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/AttestationKey.aidl new file mode 100644 index 0000000000..90f2e6ee54 --- /dev/null +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/AttestationKey.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 -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.security.keymint; +/* @hide */ +@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability +parcelable AttestationKey { + byte[] keyBlob; + android.hardware.security.keymint.KeyParameter[] attestKeyParams; + byte[] issuerSubjectName; +} diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/BeginResult.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/BeginResult.aidl new file mode 100644 index 0000000000..c952a3152a --- /dev/null +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/BeginResult.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 -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.security.keymint; +/* @hide */ +@VintfStability +parcelable BeginResult { + long challenge; + android.hardware.security.keymint.KeyParameter[] params; + android.hardware.security.keymint.IKeyMintOperation operation; +} diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/BlockMode.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/BlockMode.aidl new file mode 100644 index 0000000000..004988326b --- /dev/null +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/BlockMode.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 -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.security.keymint; +/* @hide */ +@Backing(type="int") @VintfStability +enum BlockMode { + ECB = 1, + CBC = 2, + CTR = 3, + GCM = 32, +} diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/Certificate.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/Certificate.aidl new file mode 100644 index 0000000000..645f0a72ee --- /dev/null +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/Certificate.aidl @@ -0,0 +1,39 @@ +/* + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.security.keymint; +/* @hide */ +@VintfStability +parcelable Certificate { + byte[] encodedCertificate; +} diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/DeviceInfo.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/DeviceInfo.aidl new file mode 100644 index 0000000000..d04d49cea8 --- /dev/null +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/DeviceInfo.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 -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.security.keymint; +/* @hide */ +@VintfStability +parcelable DeviceInfo { + byte[] deviceInfo; +} diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/Digest.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/Digest.aidl new file mode 100644 index 0000000000..0df709609f --- /dev/null +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/Digest.aidl @@ -0,0 +1,45 @@ +/* + * 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 -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.security.keymint; +/* @hide */ +@Backing(type="int") @VintfStability +enum Digest { + NONE = 0, + MD5 = 1, + SHA1 = 2, + SHA_2_224 = 3, + SHA_2_256 = 4, + SHA_2_384 = 5, + SHA_2_512 = 6, +} diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/EcCurve.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/EcCurve.aidl new file mode 100644 index 0000000000..6b4a9aefb2 --- /dev/null +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/EcCurve.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 -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.security.keymint; +/* @hide */ +@Backing(type="int") @VintfStability +enum EcCurve { + P_224 = 0, + P_256 = 1, + P_384 = 2, + P_521 = 3, +} diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/ErrorCode.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/ErrorCode.aidl new file mode 100644 index 0000000000..b05a0f3d83 --- /dev/null +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/ErrorCode.aidl @@ -0,0 +1,125 @@ +/* + * 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 -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.security.keymint; +/* @hide */ +@Backing(type="int") @VintfStability +enum ErrorCode { + OK = 0, + ROOT_OF_TRUST_ALREADY_SET = -1, + UNSUPPORTED_PURPOSE = -2, + INCOMPATIBLE_PURPOSE = -3, + UNSUPPORTED_ALGORITHM = -4, + INCOMPATIBLE_ALGORITHM = -5, + UNSUPPORTED_KEY_SIZE = -6, + UNSUPPORTED_BLOCK_MODE = -7, + INCOMPATIBLE_BLOCK_MODE = -8, + UNSUPPORTED_MAC_LENGTH = -9, + UNSUPPORTED_PADDING_MODE = -10, + INCOMPATIBLE_PADDING_MODE = -11, + UNSUPPORTED_DIGEST = -12, + INCOMPATIBLE_DIGEST = -13, + INVALID_EXPIRATION_TIME = -14, + INVALID_USER_ID = -15, + INVALID_AUTHORIZATION_TIMEOUT = -16, + UNSUPPORTED_KEY_FORMAT = -17, + INCOMPATIBLE_KEY_FORMAT = -18, + UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM = -19, + UNSUPPORTED_KEY_VERIFICATION_ALGORITHM = -20, + INVALID_INPUT_LENGTH = -21, + KEY_EXPORT_OPTIONS_INVALID = -22, + DELEGATION_NOT_ALLOWED = -23, + KEY_NOT_YET_VALID = -24, + KEY_EXPIRED = -25, + KEY_USER_NOT_AUTHENTICATED = -26, + OUTPUT_PARAMETER_NULL = -27, + INVALID_OPERATION_HANDLE = -28, + INSUFFICIENT_BUFFER_SPACE = -29, + VERIFICATION_FAILED = -30, + TOO_MANY_OPERATIONS = -31, + UNEXPECTED_NULL_POINTER = -32, + INVALID_KEY_BLOB = -33, + IMPORTED_KEY_NOT_ENCRYPTED = -34, + IMPORTED_KEY_DECRYPTION_FAILED = -35, + IMPORTED_KEY_NOT_SIGNED = -36, + IMPORTED_KEY_VERIFICATION_FAILED = -37, + INVALID_ARGUMENT = -38, + UNSUPPORTED_TAG = -39, + INVALID_TAG = -40, + MEMORY_ALLOCATION_FAILED = -41, + IMPORT_PARAMETER_MISMATCH = -44, + SECURE_HW_ACCESS_DENIED = -45, + OPERATION_CANCELLED = -46, + CONCURRENT_ACCESS_CONFLICT = -47, + SECURE_HW_BUSY = -48, + SECURE_HW_COMMUNICATION_FAILED = -49, + UNSUPPORTED_EC_FIELD = -50, + MISSING_NONCE = -51, + INVALID_NONCE = -52, + MISSING_MAC_LENGTH = -53, + KEY_RATE_LIMIT_EXCEEDED = -54, + CALLER_NONCE_PROHIBITED = -55, + KEY_MAX_OPS_EXCEEDED = -56, + INVALID_MAC_LENGTH = -57, + MISSING_MIN_MAC_LENGTH = -58, + UNSUPPORTED_MIN_MAC_LENGTH = -59, + UNSUPPORTED_KDF = -60, + UNSUPPORTED_EC_CURVE = -61, + KEY_REQUIRES_UPGRADE = -62, + ATTESTATION_CHALLENGE_MISSING = -63, + KEYMINT_NOT_CONFIGURED = -64, + ATTESTATION_APPLICATION_ID_MISSING = -65, + CANNOT_ATTEST_IDS = -66, + ROLLBACK_RESISTANCE_UNAVAILABLE = -67, + HARDWARE_TYPE_UNAVAILABLE = -68, + PROOF_OF_PRESENCE_REQUIRED = -69, + CONCURRENT_PROOF_OF_PRESENCE_REQUESTED = -70, + NO_USER_CONFIRMATION = -71, + DEVICE_LOCKED = -72, + EARLY_BOOT_ENDED = -73, + ATTESTATION_KEYS_NOT_PROVISIONED = -74, + ATTESTATION_IDS_NOT_PROVISIONED = -75, + INVALID_OPERATION = -76, + STORAGE_KEY_UNSUPPORTED = -77, + INCOMPATIBLE_MGF_DIGEST = -78, + UNSUPPORTED_MGF_DIGEST = -79, + MISSING_NOT_BEFORE = -80, + MISSING_NOT_AFTER = -81, + MISSING_ISSUER_SUBJECT = -82, + INVALID_ISSUER_SUBJECT = -83, + BOOT_LEVEL_EXCEEDED = -84, + HARDWARE_NOT_YET_AVAILABLE = -85, + UNIMPLEMENTED = -100, + VERSION_MISMATCH = -101, + UNKNOWN_ERROR = -1000, +} diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/HardwareAuthToken.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/HardwareAuthToken.aidl new file mode 100644 index 0000000000..2e07924382 --- /dev/null +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/HardwareAuthToken.aidl @@ -0,0 +1,44 @@ +/* + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.security.keymint; +/* @hide */ +@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability +parcelable HardwareAuthToken { + long challenge; + long userId; + long authenticatorId; + android.hardware.security.keymint.HardwareAuthenticatorType authenticatorType = android.hardware.security.keymint.HardwareAuthenticatorType.NONE; + android.hardware.security.secureclock.Timestamp timestamp; + byte[] mac; +} diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/HardwareAuthenticatorType.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/HardwareAuthenticatorType.aidl new file mode 100644 index 0000000000..dfc98f0066 --- /dev/null +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/HardwareAuthenticatorType.aidl @@ -0,0 +1,42 @@ +/* + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.security.keymint; +/* @hide */ +@Backing(type="int") @VintfStability +enum HardwareAuthenticatorType { + NONE = 0, + PASSWORD = 1, + FINGERPRINT = 2, + ANY = -1, +} diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/IKeyMintDevice.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/IKeyMintDevice.aidl new file mode 100644 index 0000000000..fa643fc494 --- /dev/null +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/IKeyMintDevice.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 -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.security.keymint; +/* @hide */ +@SensitiveData @VintfStability +interface IKeyMintDevice { + android.hardware.security.keymint.KeyMintHardwareInfo getHardwareInfo(); + void addRngEntropy(in byte[] data); + android.hardware.security.keymint.KeyCreationResult generateKey(in android.hardware.security.keymint.KeyParameter[] keyParams, in @nullable android.hardware.security.keymint.AttestationKey attestationKey); + android.hardware.security.keymint.KeyCreationResult importKey(in android.hardware.security.keymint.KeyParameter[] keyParams, in android.hardware.security.keymint.KeyFormat keyFormat, in byte[] keyData, in @nullable android.hardware.security.keymint.AttestationKey attestationKey); + android.hardware.security.keymint.KeyCreationResult importWrappedKey(in byte[] wrappedKeyData, in byte[] wrappingKeyBlob, in byte[] maskingKey, in android.hardware.security.keymint.KeyParameter[] unwrappingParams, in long passwordSid, in long biometricSid); + byte[] upgradeKey(in byte[] keyBlobToUpgrade, in android.hardware.security.keymint.KeyParameter[] upgradeParams); + void deleteKey(in byte[] keyBlob); + void deleteAllKeys(); + void destroyAttestationIds(); + android.hardware.security.keymint.BeginResult begin(in android.hardware.security.keymint.KeyPurpose purpose, in byte[] keyBlob, in android.hardware.security.keymint.KeyParameter[] params, in @nullable android.hardware.security.keymint.HardwareAuthToken authToken); + void deviceLocked(in boolean passwordOnly, in @nullable android.hardware.security.secureclock.TimeStampToken timestampToken); + void earlyBootEnded(); + byte[] convertStorageKeyToEphemeral(in byte[] storageKeyBlob); + android.hardware.security.keymint.KeyCharacteristics[] getKeyCharacteristics(in byte[] keyBlob, in byte[] appId, in byte[] appData); + const int AUTH_TOKEN_MAC_LENGTH = 32; +} diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/IKeyMintOperation.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/IKeyMintOperation.aidl new file mode 100644 index 0000000000..4ab4ffed11 --- /dev/null +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/IKeyMintOperation.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 -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.security.keymint; +/* @hide */ +@SensitiveData @VintfStability +interface IKeyMintOperation { + void updateAad(in byte[] input, in @nullable android.hardware.security.keymint.HardwareAuthToken authToken, in @nullable android.hardware.security.secureclock.TimeStampToken timeStampToken); + byte[] update(in byte[] input, in @nullable android.hardware.security.keymint.HardwareAuthToken authToken, in @nullable android.hardware.security.secureclock.TimeStampToken timeStampToken); + byte[] finish(in @nullable byte[] input, in @nullable byte[] signature, in @nullable android.hardware.security.keymint.HardwareAuthToken authToken, in @nullable android.hardware.security.secureclock.TimeStampToken timestampToken, in @nullable byte[] confirmationToken); + void abort(); +} diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl new file mode 100644 index 0000000000..f56646227b --- /dev/null +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/IRemotelyProvisionedComponent.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 -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.security.keymint; +/* @hide */ +@VintfStability +interface IRemotelyProvisionedComponent { + android.hardware.security.keymint.RpcHardwareInfo getHardwareInfo(); + byte[] generateEcdsaP256KeyPair(in boolean testMode, out android.hardware.security.keymint.MacedPublicKey macedPublicKey); + byte[] generateCertificateRequest(in boolean testMode, in android.hardware.security.keymint.MacedPublicKey[] keysToSign, in byte[] endpointEncryptionCertChain, in byte[] challenge, out android.hardware.security.keymint.DeviceInfo deviceInfo, out android.hardware.security.keymint.ProtectedData protectedData); + const int STATUS_FAILED = 1; + const int STATUS_INVALID_MAC = 2; + const int STATUS_PRODUCTION_KEY_IN_TEST_REQUEST = 3; + const int STATUS_TEST_KEY_IN_PRODUCTION_REQUEST = 4; + const int STATUS_INVALID_EEK = 5; +} diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/KeyCharacteristics.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/KeyCharacteristics.aidl new file mode 100644 index 0000000000..008381f282 --- /dev/null +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/KeyCharacteristics.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 -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.security.keymint; +/* @hide */ +@VintfStability +parcelable KeyCharacteristics { + android.hardware.security.keymint.SecurityLevel securityLevel = android.hardware.security.keymint.SecurityLevel.SOFTWARE; + android.hardware.security.keymint.KeyParameter[] authorizations; +} diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/KeyCreationResult.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/KeyCreationResult.aidl new file mode 100644 index 0000000000..9f77d3e3d5 --- /dev/null +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/KeyCreationResult.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 -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.security.keymint; +/* @hide */ +@VintfStability +parcelable KeyCreationResult { + byte[] keyBlob; + android.hardware.security.keymint.KeyCharacteristics[] keyCharacteristics; + android.hardware.security.keymint.Certificate[] certificateChain; +} diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/KeyFormat.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/KeyFormat.aidl new file mode 100644 index 0000000000..9560d8d2b5 --- /dev/null +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/KeyFormat.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 -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.security.keymint; +/* @hide */ +@Backing(type="int") @VintfStability +enum KeyFormat { + X509 = 0, + PKCS8 = 1, + RAW = 3, +} diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/KeyMintHardwareInfo.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/KeyMintHardwareInfo.aidl new file mode 100644 index 0000000000..2113e42a8e --- /dev/null +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/KeyMintHardwareInfo.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 -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.security.keymint; +/* @hide */ +@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability +parcelable KeyMintHardwareInfo { + int versionNumber; + android.hardware.security.keymint.SecurityLevel securityLevel = android.hardware.security.keymint.SecurityLevel.SOFTWARE; + @utf8InCpp String keyMintName; + @utf8InCpp String keyMintAuthorName; + boolean timestampTokenRequired; +} diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/KeyOrigin.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/KeyOrigin.aidl new file mode 100644 index 0000000000..4b3c659ffe --- /dev/null +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/KeyOrigin.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 -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.security.keymint; +/* @hide */ +@Backing(type="int") @VintfStability +enum KeyOrigin { + GENERATED = 0, + DERIVED = 1, + IMPORTED = 2, + RESERVED = 3, + SECURELY_IMPORTED = 4, +} diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/KeyParameter.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/KeyParameter.aidl new file mode 100644 index 0000000000..c5a1e011d2 --- /dev/null +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/KeyParameter.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 -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.security.keymint; +/* @hide */ +@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability +parcelable KeyParameter { + android.hardware.security.keymint.Tag tag = android.hardware.security.keymint.Tag.INVALID; + android.hardware.security.keymint.KeyParameterValue value; +} diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/KeyParameterValue.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/KeyParameterValue.aidl new file mode 100644 index 0000000000..7a0b074fe5 --- /dev/null +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/KeyParameterValue.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 -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.security.keymint; +/* @hide */ +@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability +union KeyParameterValue { + int invalid; + android.hardware.security.keymint.Algorithm algorithm; + android.hardware.security.keymint.BlockMode blockMode; + android.hardware.security.keymint.PaddingMode paddingMode; + android.hardware.security.keymint.Digest digest; + android.hardware.security.keymint.EcCurve ecCurve; + android.hardware.security.keymint.KeyOrigin origin; + android.hardware.security.keymint.KeyPurpose keyPurpose; + android.hardware.security.keymint.HardwareAuthenticatorType hardwareAuthenticatorType; + android.hardware.security.keymint.SecurityLevel securityLevel; + boolean boolValue; + int integer; + long longInteger; + long dateTime; + byte[] blob; +} diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/KeyPurpose.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/KeyPurpose.aidl new file mode 100644 index 0000000000..b84bec1fc0 --- /dev/null +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/KeyPurpose.aidl @@ -0,0 +1,45 @@ +/* + * 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 -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.security.keymint; +/* @hide */ +@Backing(type="int") @VintfStability +enum KeyPurpose { + ENCRYPT = 0, + DECRYPT = 1, + SIGN = 2, + VERIFY = 3, + WRAP_KEY = 5, + AGREE_KEY = 6, + ATTEST_KEY = 7, +} diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/MacedPublicKey.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/MacedPublicKey.aidl new file mode 100644 index 0000000000..8095e8ce04 --- /dev/null +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/MacedPublicKey.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 -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.security.keymint; +/* @hide */ +@VintfStability +parcelable MacedPublicKey { + byte[] macedKey; +} diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/PaddingMode.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/PaddingMode.aidl new file mode 100644 index 0000000000..dba4a8a06e --- /dev/null +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/PaddingMode.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 -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.security.keymint; +/* @hide */ +@Backing(type="int") @VintfStability +enum PaddingMode { + NONE = 1, + RSA_OAEP = 2, + RSA_PSS = 3, + RSA_PKCS1_1_5_ENCRYPT = 4, + RSA_PKCS1_1_5_SIGN = 5, + PKCS7 = 64, +} diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/ProtectedData.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/ProtectedData.aidl new file mode 100644 index 0000000000..d1610b4d6f --- /dev/null +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/ProtectedData.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 -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.security.keymint; +/* @hide */ +@VintfStability +parcelable ProtectedData { + byte[] protectedData; +} diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/RpcHardwareInfo.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/RpcHardwareInfo.aidl new file mode 100644 index 0000000000..06bce19c82 --- /dev/null +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/RpcHardwareInfo.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 -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.security.keymint; +/* @hide */ +@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability +parcelable RpcHardwareInfo { + int versionNumber; + @utf8InCpp String rpcAuthorName; + int supportedEekCurve = 0; + const int CURVE_NONE = 0; + const int CURVE_P256 = 1; + const int CURVE_25519 = 2; +} diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/SecurityLevel.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/SecurityLevel.aidl new file mode 100644 index 0000000000..0d278e0af9 --- /dev/null +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/SecurityLevel.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 -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.security.keymint; +/* @hide */ +@Backing(type="int") @VintfStability +enum SecurityLevel { + SOFTWARE = 0, + TRUSTED_ENVIRONMENT = 1, + STRONGBOX = 2, + KEYSTORE = 100, +} diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/Tag.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/Tag.aidl new file mode 100644 index 0000000000..e310b4448f --- /dev/null +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/Tag.aidl @@ -0,0 +1,103 @@ +/* + * 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 -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.security.keymint; +/* @hide */ +@Backing(type="int") @VintfStability +enum Tag { + INVALID = 0, + PURPOSE = 536870913, + ALGORITHM = 268435458, + KEY_SIZE = 805306371, + BLOCK_MODE = 536870916, + DIGEST = 536870917, + PADDING = 536870918, + CALLER_NONCE = 1879048199, + MIN_MAC_LENGTH = 805306376, + EC_CURVE = 268435466, + RSA_PUBLIC_EXPONENT = 1342177480, + INCLUDE_UNIQUE_ID = 1879048394, + RSA_OAEP_MGF_DIGEST = 536871115, + BOOTLOADER_ONLY = 1879048494, + ROLLBACK_RESISTANCE = 1879048495, + HARDWARE_TYPE = 268435760, + EARLY_BOOT_ONLY = 1879048497, + ACTIVE_DATETIME = 1610613136, + ORIGINATION_EXPIRE_DATETIME = 1610613137, + USAGE_EXPIRE_DATETIME = 1610613138, + MIN_SECONDS_BETWEEN_OPS = 805306771, + MAX_USES_PER_BOOT = 805306772, + USAGE_COUNT_LIMIT = 805306773, + USER_ID = 805306869, + USER_SECURE_ID = -1610612234, + NO_AUTH_REQUIRED = 1879048695, + USER_AUTH_TYPE = 268435960, + AUTH_TIMEOUT = 805306873, + ALLOW_WHILE_ON_BODY = 1879048698, + TRUSTED_USER_PRESENCE_REQUIRED = 1879048699, + TRUSTED_CONFIRMATION_REQUIRED = 1879048700, + UNLOCKED_DEVICE_REQUIRED = 1879048701, + APPLICATION_ID = -1879047591, + APPLICATION_DATA = -1879047492, + CREATION_DATETIME = 1610613437, + ORIGIN = 268436158, + ROOT_OF_TRUST = -1879047488, + OS_VERSION = 805307073, + OS_PATCHLEVEL = 805307074, + UNIQUE_ID = -1879047485, + ATTESTATION_CHALLENGE = -1879047484, + ATTESTATION_APPLICATION_ID = -1879047483, + ATTESTATION_ID_BRAND = -1879047482, + ATTESTATION_ID_DEVICE = -1879047481, + ATTESTATION_ID_PRODUCT = -1879047480, + ATTESTATION_ID_SERIAL = -1879047479, + ATTESTATION_ID_IMEI = -1879047478, + ATTESTATION_ID_MEID = -1879047477, + ATTESTATION_ID_MANUFACTURER = -1879047476, + ATTESTATION_ID_MODEL = -1879047475, + VENDOR_PATCHLEVEL = 805307086, + BOOT_PATCHLEVEL = 805307087, + DEVICE_UNIQUE_ATTESTATION = 1879048912, + IDENTITY_CREDENTIAL_KEY = 1879048913, + STORAGE_KEY = 1879048914, + ASSOCIATED_DATA = -1879047192, + NONCE = -1879047191, + MAC_LENGTH = 805307371, + RESET_SINCE_ID_ROTATION = 1879049196, + CONFIRMATION_TOKEN = -1879047187, + CERTIFICATE_SERIAL = -2147482642, + CERTIFICATE_SUBJECT = -1879047185, + CERTIFICATE_NOT_BEFORE = 1610613744, + CERTIFICATE_NOT_AFTER = 1610613745, + MAX_BOOT_LEVEL = 805307378, +} diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/TagType.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/TagType.aidl new file mode 100644 index 0000000000..a7d1de5fd4 --- /dev/null +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/1/android/hardware/security/keymint/TagType.aidl @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.security.keymint; +/* @hide */ +@Backing(type="int") @VintfStability +enum TagType { + INVALID = 0, + ENUM = 268435456, + ENUM_REP = 536870912, + UINT = 805306368, + UINT_REP = 1073741824, + ULONG = 1342177280, + DATE = 1610612736, + BOOL = 1879048192, + BIGNUM = -2147483648, + BYTES = -1879048192, + ULONG_REP = -1610612736, +} diff --git a/security/secureclock/aidl/Android.bp b/security/secureclock/aidl/Android.bp index c78be3b20c..b70dda9b3a 100644 --- a/security/secureclock/aidl/Android.bp +++ b/security/secureclock/aidl/Android.bp @@ -28,4 +28,5 @@ aidl_interface { enabled: true, }, }, + versions: ["1"], } diff --git a/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/1/.hash b/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/1/.hash new file mode 100644 index 0000000000..f6b25a0a49 --- /dev/null +++ b/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/1/.hash @@ -0,0 +1 @@ +cd55ca9963c6a57fa5f2f120a45c6e0c4fafb423 diff --git a/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/1/android/hardware/security/secureclock/ISecureClock.aidl b/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/1/android/hardware/security/secureclock/ISecureClock.aidl new file mode 100644 index 0000000000..4ecc1e4430 --- /dev/null +++ b/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/1/android/hardware/security/secureclock/ISecureClock.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. + * 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 -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.security.secureclock; +/* @hide */ +@VintfStability +interface ISecureClock { + android.hardware.security.secureclock.TimeStampToken generateTimeStamp(in long challenge); + const String TIME_STAMP_MAC_LABEL = "Auth Verification"; +} diff --git a/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/1/android/hardware/security/secureclock/TimeStampToken.aidl b/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/1/android/hardware/security/secureclock/TimeStampToken.aidl new file mode 100644 index 0000000000..d105ac8f6c --- /dev/null +++ b/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/1/android/hardware/security/secureclock/TimeStampToken.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 -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.security.secureclock; +/* @hide */ +@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability +parcelable TimeStampToken { + long challenge; + android.hardware.security.secureclock.Timestamp timestamp; + byte[] mac; +} diff --git a/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/1/android/hardware/security/secureclock/Timestamp.aidl b/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/1/android/hardware/security/secureclock/Timestamp.aidl new file mode 100644 index 0000000000..2e0e389d9e --- /dev/null +++ b/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/1/android/hardware/security/secureclock/Timestamp.aidl @@ -0,0 +1,39 @@ +/* + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.security.secureclock; +/* @hide */ +@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability +parcelable Timestamp { + long milliSeconds; +} diff --git a/security/sharedsecret/aidl/Android.bp b/security/sharedsecret/aidl/Android.bp index 16830598f5..f1fce7455b 100644 --- a/security/sharedsecret/aidl/Android.bp +++ b/security/sharedsecret/aidl/Android.bp @@ -27,4 +27,5 @@ aidl_interface { enabled: true, }, }, + versions: ["1"], } diff --git a/security/sharedsecret/aidl/aidl_api/android.hardware.security.sharedsecret/1/.hash b/security/sharedsecret/aidl/aidl_api/android.hardware.security.sharedsecret/1/.hash new file mode 100644 index 0000000000..7d22dc4e6e --- /dev/null +++ b/security/sharedsecret/aidl/aidl_api/android.hardware.security.sharedsecret/1/.hash @@ -0,0 +1 @@ +aea3745b559d2977f0676952e510fb0547a52140 diff --git a/security/sharedsecret/aidl/aidl_api/android.hardware.security.sharedsecret/1/android/hardware/security/sharedsecret/ISharedSecret.aidl b/security/sharedsecret/aidl/aidl_api/android.hardware.security.sharedsecret/1/android/hardware/security/sharedsecret/ISharedSecret.aidl new file mode 100644 index 0000000000..e76efe7f5d --- /dev/null +++ b/security/sharedsecret/aidl/aidl_api/android.hardware.security.sharedsecret/1/android/hardware/security/sharedsecret/ISharedSecret.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. + * 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 -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.security.sharedsecret; +/* @hide */ +@VintfStability +interface ISharedSecret { + android.hardware.security.sharedsecret.SharedSecretParameters getSharedSecretParameters(); + byte[] computeSharedSecret(in android.hardware.security.sharedsecret.SharedSecretParameters[] params); + const String KEY_AGREEMENT_LABEL = "KeymasterSharedMac"; + const String KEY_CHECK_LABEL = "Keymaster HMAC Verification"; +} diff --git a/security/sharedsecret/aidl/aidl_api/android.hardware.security.sharedsecret/1/android/hardware/security/sharedsecret/SharedSecretParameters.aidl b/security/sharedsecret/aidl/aidl_api/android.hardware.security.sharedsecret/1/android/hardware/security/sharedsecret/SharedSecretParameters.aidl new file mode 100644 index 0000000000..e15fd49aa6 --- /dev/null +++ b/security/sharedsecret/aidl/aidl_api/android.hardware.security.sharedsecret/1/android/hardware/security/sharedsecret/SharedSecretParameters.aidl @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.security.sharedsecret; +/* @hide */ +@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability +parcelable SharedSecretParameters { + byte[] seed; + byte[] nonce; +} diff --git a/tests/extension/vibrator/aidl/Android.bp b/tests/extension/vibrator/aidl/Android.bp index 4d544e11fb..96cfa082f9 100644 --- a/tests/extension/vibrator/aidl/Android.bp +++ b/tests/extension/vibrator/aidl/Android.bp @@ -27,7 +27,7 @@ aidl_interface { // This happens to use types from a core interface, so we import it, but // this won't always be needed. imports: [ - "android.hardware.vibrator", + "android.hardware.vibrator-V2", ], backend: { diff --git a/tests/extension/vibrator/aidl/client/Android.bp b/tests/extension/vibrator/aidl/client/Android.bp index fb34d7e771..afab263b82 100644 --- a/tests/extension/vibrator/aidl/client/Android.bp +++ b/tests/extension/vibrator/aidl/client/Android.bp @@ -23,11 +23,11 @@ cc_test { shared_libs: [ "libbinder", "libutils", - "android.hardware.vibrator-V1-cpp", + "android.hardware.vibrator-V2-cpp", "android.hardware.tests.extension.vibrator-V1-cpp", "libbinder_ndk", - "android.hardware.vibrator-V1-ndk_platform", + "android.hardware.vibrator-V2-ndk_platform", "android.hardware.tests.extension.vibrator-V1-ndk_platform", ], } diff --git a/vibrator/aidl/Android.bp b/vibrator/aidl/Android.bp index 4363407d77..22219b0f73 100644 --- a/vibrator/aidl/Android.bp +++ b/vibrator/aidl/Android.bp @@ -24,5 +24,8 @@ aidl_interface { }, }, }, - versions: ["1"], + versions: [ + "1", + "2", + ], } diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/2/.hash b/vibrator/aidl/aidl_api/android.hardware.vibrator/2/.hash new file mode 100644 index 0000000000..cf5edcc89a --- /dev/null +++ b/vibrator/aidl/aidl_api/android.hardware.vibrator/2/.hash @@ -0,0 +1 @@ +ea8742d6993e1a82917da38b9938e537aa7fcb54 diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/2/android/hardware/vibrator/ActivePwle.aidl b/vibrator/aidl/aidl_api/android.hardware.vibrator/2/android/hardware/vibrator/ActivePwle.aidl new file mode 100644 index 0000000000..de3ad3c032 --- /dev/null +++ b/vibrator/aidl/aidl_api/android.hardware.vibrator/2/android/hardware/vibrator/ActivePwle.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 -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.vibrator; +@VintfStability +parcelable ActivePwle { + float startAmplitude; + float startFrequency; + float endAmplitude; + float endFrequency; + int duration; +} diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/2/android/hardware/vibrator/Braking.aidl b/vibrator/aidl/aidl_api/android.hardware.vibrator/2/android/hardware/vibrator/Braking.aidl new file mode 100644 index 0000000000..d38c584d76 --- /dev/null +++ b/vibrator/aidl/aidl_api/android.hardware.vibrator/2/android/hardware/vibrator/Braking.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 -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.vibrator; +@Backing(type="int") @VintfStability +enum Braking { + NONE = 0, + CLAB = 1, +} diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/2/android/hardware/vibrator/BrakingPwle.aidl b/vibrator/aidl/aidl_api/android.hardware.vibrator/2/android/hardware/vibrator/BrakingPwle.aidl new file mode 100644 index 0000000000..fa7b43abd0 --- /dev/null +++ b/vibrator/aidl/aidl_api/android.hardware.vibrator/2/android/hardware/vibrator/BrakingPwle.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 -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.vibrator; +@VintfStability +parcelable BrakingPwle { + android.hardware.vibrator.Braking braking; + int duration; +} diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/2/android/hardware/vibrator/CompositeEffect.aidl b/vibrator/aidl/aidl_api/android.hardware.vibrator/2/android/hardware/vibrator/CompositeEffect.aidl new file mode 100644 index 0000000000..679c82cc3b --- /dev/null +++ b/vibrator/aidl/aidl_api/android.hardware.vibrator/2/android/hardware/vibrator/CompositeEffect.aidl @@ -0,0 +1,40 @@ +/* + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.vibrator; +@VintfStability +parcelable CompositeEffect { + int delayMs; + android.hardware.vibrator.CompositePrimitive primitive = android.hardware.vibrator.CompositePrimitive.NOOP; + float scale; +} diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/2/android/hardware/vibrator/CompositePrimitive.aidl b/vibrator/aidl/aidl_api/android.hardware.vibrator/2/android/hardware/vibrator/CompositePrimitive.aidl new file mode 100644 index 0000000000..50de13fc27 --- /dev/null +++ b/vibrator/aidl/aidl_api/android.hardware.vibrator/2/android/hardware/vibrator/CompositePrimitive.aidl @@ -0,0 +1,46 @@ +/* + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.vibrator; +@Backing(type="int") @VintfStability +enum CompositePrimitive { + NOOP = 0, + CLICK = 1, + THUD = 2, + SPIN = 3, + QUICK_RISE = 4, + SLOW_RISE = 5, + QUICK_FALL = 6, + LIGHT_TICK = 7, + LOW_TICK = 8, +} diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/2/android/hardware/vibrator/Effect.aidl b/vibrator/aidl/aidl_api/android.hardware.vibrator/2/android/hardware/vibrator/Effect.aidl new file mode 100644 index 0000000000..adf0f2009f --- /dev/null +++ b/vibrator/aidl/aidl_api/android.hardware.vibrator/2/android/hardware/vibrator/Effect.aidl @@ -0,0 +1,59 @@ +/* + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.vibrator; +@Backing(type="int") @VintfStability +enum Effect { + CLICK = 0, + DOUBLE_CLICK = 1, + TICK = 2, + THUD = 3, + POP = 4, + HEAVY_CLICK = 5, + RINGTONE_1 = 6, + RINGTONE_2 = 7, + RINGTONE_3 = 8, + RINGTONE_4 = 9, + RINGTONE_5 = 10, + RINGTONE_6 = 11, + RINGTONE_7 = 12, + RINGTONE_8 = 13, + RINGTONE_9 = 14, + RINGTONE_10 = 15, + RINGTONE_11 = 16, + RINGTONE_12 = 17, + RINGTONE_13 = 18, + RINGTONE_14 = 19, + RINGTONE_15 = 20, + TEXTURE_TICK = 21, +} diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/2/android/hardware/vibrator/EffectStrength.aidl b/vibrator/aidl/aidl_api/android.hardware.vibrator/2/android/hardware/vibrator/EffectStrength.aidl new file mode 100644 index 0000000000..af5e15871b --- /dev/null +++ b/vibrator/aidl/aidl_api/android.hardware.vibrator/2/android/hardware/vibrator/EffectStrength.aidl @@ -0,0 +1,40 @@ +/* + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.vibrator; +@Backing(type="byte") @VintfStability +enum EffectStrength { + LIGHT = 0, + MEDIUM = 1, + STRONG = 2, +} diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/2/android/hardware/vibrator/IVibrator.aidl b/vibrator/aidl/aidl_api/android.hardware.vibrator/2/android/hardware/vibrator/IVibrator.aidl new file mode 100644 index 0000000000..b7afb663cf --- /dev/null +++ b/vibrator/aidl/aidl_api/android.hardware.vibrator/2/android/hardware/vibrator/IVibrator.aidl @@ -0,0 +1,72 @@ +/* + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.vibrator; +@VintfStability +interface IVibrator { + int getCapabilities(); + void off(); + void on(in int timeoutMs, in android.hardware.vibrator.IVibratorCallback callback); + int perform(in android.hardware.vibrator.Effect effect, in android.hardware.vibrator.EffectStrength strength, in android.hardware.vibrator.IVibratorCallback callback); + android.hardware.vibrator.Effect[] getSupportedEffects(); + void setAmplitude(in float amplitude); + void setExternalControl(in boolean enabled); + int getCompositionDelayMax(); + int getCompositionSizeMax(); + android.hardware.vibrator.CompositePrimitive[] getSupportedPrimitives(); + int getPrimitiveDuration(android.hardware.vibrator.CompositePrimitive primitive); + void compose(in android.hardware.vibrator.CompositeEffect[] composite, in android.hardware.vibrator.IVibratorCallback callback); + android.hardware.vibrator.Effect[] getSupportedAlwaysOnEffects(); + void alwaysOnEnable(in int id, in android.hardware.vibrator.Effect effect, in android.hardware.vibrator.EffectStrength strength); + void alwaysOnDisable(in int id); + float getResonantFrequency(); + float getQFactor(); + float getFrequencyResolution(); + float getFrequencyMinimum(); + float[] getBandwidthAmplitudeMap(); + int getPwlePrimitiveDurationMax(); + int getPwleCompositionSizeMax(); + android.hardware.vibrator.Braking[] getSupportedBraking(); + void composePwle(in android.hardware.vibrator.PrimitivePwle[] composite, in android.hardware.vibrator.IVibratorCallback callback); + const int CAP_ON_CALLBACK = 1; + const int CAP_PERFORM_CALLBACK = 2; + const int CAP_AMPLITUDE_CONTROL = 4; + const int CAP_EXTERNAL_CONTROL = 8; + const int CAP_EXTERNAL_AMPLITUDE_CONTROL = 16; + const int CAP_COMPOSE_EFFECTS = 32; + const int CAP_ALWAYS_ON_CONTROL = 64; + const int CAP_GET_RESONANT_FREQUENCY = 128; + const int CAP_GET_Q_FACTOR = 256; + const int CAP_FREQUENCY_CONTROL = 512; + const int CAP_COMPOSE_PWLE_EFFECTS = 1024; +} diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/2/android/hardware/vibrator/IVibratorCallback.aidl b/vibrator/aidl/aidl_api/android.hardware.vibrator/2/android/hardware/vibrator/IVibratorCallback.aidl new file mode 100644 index 0000000000..99d6d2290d --- /dev/null +++ b/vibrator/aidl/aidl_api/android.hardware.vibrator/2/android/hardware/vibrator/IVibratorCallback.aidl @@ -0,0 +1,38 @@ +/* + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.vibrator; +@VintfStability +interface IVibratorCallback { + oneway void onComplete(); +} diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/2/android/hardware/vibrator/IVibratorManager.aidl b/vibrator/aidl/aidl_api/android.hardware.vibrator/2/android/hardware/vibrator/IVibratorManager.aidl new file mode 100644 index 0000000000..290c68d877 --- /dev/null +++ b/vibrator/aidl/aidl_api/android.hardware.vibrator/2/android/hardware/vibrator/IVibratorManager.aidl @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.vibrator; +@VintfStability +interface IVibratorManager { + int getCapabilities(); + int[] getVibratorIds(); + android.hardware.vibrator.IVibrator getVibrator(in int vibratorId); + void prepareSynced(in int[] vibratorIds); + void triggerSynced(in android.hardware.vibrator.IVibratorCallback callback); + void cancelSynced(); + const int CAP_SYNC = 1; + const int CAP_PREPARE_ON = 2; + const int CAP_PREPARE_PERFORM = 4; + const int CAP_PREPARE_COMPOSE = 8; + const int CAP_MIXED_TRIGGER_ON = 16; + const int CAP_MIXED_TRIGGER_PERFORM = 32; + const int CAP_MIXED_TRIGGER_COMPOSE = 64; + const int CAP_TRIGGER_CALLBACK = 128; +} diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/2/android/hardware/vibrator/PrimitivePwle.aidl b/vibrator/aidl/aidl_api/android.hardware.vibrator/2/android/hardware/vibrator/PrimitivePwle.aidl new file mode 100644 index 0000000000..584bcf4a47 --- /dev/null +++ b/vibrator/aidl/aidl_api/android.hardware.vibrator/2/android/hardware/vibrator/PrimitivePwle.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 -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.vibrator; +@VintfStability +union PrimitivePwle { + android.hardware.vibrator.ActivePwle active; + android.hardware.vibrator.BrakingPwle braking; +} diff --git a/weaver/aidl/Android.bp b/weaver/aidl/Android.bp index 60925ecb89..8b4306f3f1 100644 --- a/weaver/aidl/Android.bp +++ b/weaver/aidl/Android.bp @@ -22,4 +22,5 @@ aidl_interface { }, }, }, + versions: ["1"], } diff --git a/weaver/aidl/aidl_api/android.hardware.weaver/1/.hash b/weaver/aidl/aidl_api/android.hardware.weaver/1/.hash new file mode 100644 index 0000000000..84288bb9f5 --- /dev/null +++ b/weaver/aidl/aidl_api/android.hardware.weaver/1/.hash @@ -0,0 +1 @@ +c2ea8ac04f236492c02b992dc46ae904db0acc7e diff --git a/weaver/aidl/aidl_api/android.hardware.weaver/1/android/hardware/weaver/IWeaver.aidl b/weaver/aidl/aidl_api/android.hardware.weaver/1/android/hardware/weaver/IWeaver.aidl new file mode 100644 index 0000000000..61627d95c4 --- /dev/null +++ b/weaver/aidl/aidl_api/android.hardware.weaver/1/android/hardware/weaver/IWeaver.aidl @@ -0,0 +1,43 @@ +/* + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.weaver; +@VintfStability +interface IWeaver { + android.hardware.weaver.WeaverConfig getConfig(); + android.hardware.weaver.WeaverReadResponse read(in int slotId, in byte[] key); + void write(in int slotId, in byte[] key, in byte[] value); + const int STATUS_FAILED = 1; + const int STATUS_INCORRECT_KEY = 2; + const int STATUS_THROTTLE = 3; +} diff --git a/weaver/aidl/aidl_api/android.hardware.weaver/1/android/hardware/weaver/WeaverConfig.aidl b/weaver/aidl/aidl_api/android.hardware.weaver/1/android/hardware/weaver/WeaverConfig.aidl new file mode 100644 index 0000000000..7491f32872 --- /dev/null +++ b/weaver/aidl/aidl_api/android.hardware.weaver/1/android/hardware/weaver/WeaverConfig.aidl @@ -0,0 +1,40 @@ +/* + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.weaver; +@VintfStability +parcelable WeaverConfig { + int slots; + int keySize; + int valueSize; +} diff --git a/weaver/aidl/aidl_api/android.hardware.weaver/1/android/hardware/weaver/WeaverReadResponse.aidl b/weaver/aidl/aidl_api/android.hardware.weaver/1/android/hardware/weaver/WeaverReadResponse.aidl new file mode 100644 index 0000000000..47ee4c8a13 --- /dev/null +++ b/weaver/aidl/aidl_api/android.hardware.weaver/1/android/hardware/weaver/WeaverReadResponse.aidl @@ -0,0 +1,39 @@ +/* + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.weaver; +@VintfStability +parcelable WeaverReadResponse { + long timeout; + byte[] value; +} -- GitLab From a96ae35fb4de2c24e944cc123d144e00d9522e6e Mon Sep 17 00:00:00 2001 From: Tommy Chiu Date: Thu, 20 May 2021 20:21:20 +0800 Subject: [PATCH 677/790] ISharedSecret: Add strongbox definition Bug: 188728065 Change-Id: I0cbf50f385b00a90c3647e67f34527f21131985a --- compatibility_matrices/compatibility_matrix.6.xml | 1 + compatibility_matrices/compatibility_matrix.current.xml | 1 + 2 files changed, 2 insertions(+) diff --git a/compatibility_matrices/compatibility_matrix.6.xml b/compatibility_matrices/compatibility_matrix.6.xml index 01cd1f6c68..aee2c5164b 100644 --- a/compatibility_matrices/compatibility_matrix.6.xml +++ b/compatibility_matrices/compatibility_matrix.6.xml @@ -508,6 +508,7 @@ ISharedSecret default + strongbox diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index 3b84b6ebf7..8b6e8414d0 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -508,6 +508,7 @@ ISharedSecret default + strongbox -- GitLab From 6a2572b7ea2358701bc5edc25c2967d307040775 Mon Sep 17 00:00:00 2001 From: Emilian Peev Date: Mon, 24 May 2021 16:51:17 -0700 Subject: [PATCH 678/790] Camera: Add support for single plane stride queries Allow buffer mapper clients to query the current buffer stride of the first plane. Bug: 188992806 Test: Camera CTS Change-Id: I503ad8ae2e144405f0f365636210275f8e56ae82 --- camera/common/1.0/default/HandleImporter.cpp | 59 +++++++++++++++---- .../1.0/default/include/HandleImporter.h | 3 + 2 files changed, 49 insertions(+), 13 deletions(-) diff --git a/camera/common/1.0/default/HandleImporter.cpp b/camera/common/1.0/default/HandleImporter.cpp index 05a552cd95..7fcf52330c 100644 --- a/camera/common/1.0/default/HandleImporter.cpp +++ b/camera/common/1.0/default/HandleImporter.cpp @@ -123,6 +123,24 @@ YCbCrLayout HandleImporter::lockYCbCrInternal(const sp mapper, buffer_handle_ return layout; } +std::vector getPlaneLayouts(const sp mapper, buffer_handle_t& buf) { + auto buffer = const_cast(buf); + std::vector planeLayouts; + hidl_vec encodedPlaneLayouts; + mapper->get(buffer, gralloc4::MetadataType_PlaneLayouts, + [&](const auto& tmpError, const auto& tmpEncodedPlaneLayouts) { + if (tmpError == MapperErrorV4::NONE) { + encodedPlaneLayouts = tmpEncodedPlaneLayouts; + } else { + ALOGE("%s: failed to get plane layouts %d!", __FUNCTION__, tmpError); + } + }); + + gralloc4::decodePlaneLayouts(encodedPlaneLayouts, &planeLayouts); + + return planeLayouts; +} + template <> YCbCrLayout HandleImporter::lockYCbCrInternal( const sp mapper, buffer_handle_t& buf, uint64_t cpuUsage, @@ -147,19 +165,7 @@ YCbCrLayout HandleImporter::lockYCbCrInternal( return layout; } - hidl_vec encodedPlaneLayouts; - mapper->get(buffer, gralloc4::MetadataType_PlaneLayouts, - [&](const auto& tmpError, const auto& tmpEncodedPlaneLayouts) { - if (tmpError == MapperErrorV4::NONE) { - encodedPlaneLayouts = tmpEncodedPlaneLayouts; - } else { - ALOGE("%s: failed to get plane layouts %d!", __FUNCTION__, tmpError); - } - }); - - std::vector planeLayouts; - gralloc4::decodePlaneLayouts(encodedPlaneLayouts, &planeLayouts); - + std::vector planeLayouts = getPlaneLayouts(mapper, buf); for (const auto& planeLayout : planeLayouts) { for (const auto& planeLayoutComponent : planeLayout.components) { const auto& type = planeLayoutComponent.type; @@ -401,6 +407,33 @@ YCbCrLayout HandleImporter::lockYCbCr( return {}; } +status_t HandleImporter::getMonoPlanarStrideBytes(buffer_handle_t &buf, uint32_t *stride /*out*/) { + if (stride == nullptr) { + return BAD_VALUE; + } + + Mutex::Autolock lock(mLock); + + if (!mInitialized) { + initializeLocked(); + } + + if (mMapperV4 != nullptr) { + std::vector planeLayouts = getPlaneLayouts(mMapperV4, buf); + if (planeLayouts.size() != 1) { + ALOGE("%s: Unexpected number of planes %zu!", __FUNCTION__, planeLayouts.size()); + return BAD_VALUE; + } + + *stride = planeLayouts[0].strideInBytes; + } else { + ALOGE("%s: mMapperV4 is null! Query not supported!", __FUNCTION__); + return NO_INIT; + } + + return OK; +} + int HandleImporter::unlock(buffer_handle_t& buf) { if (mMapperV4 != nullptr) { return unlockInternal(mMapperV4, buf); diff --git a/camera/common/1.0/default/include/HandleImporter.h b/camera/common/1.0/default/include/HandleImporter.h index edc97ad9a7..e404439cb6 100644 --- a/camera/common/1.0/default/include/HandleImporter.h +++ b/camera/common/1.0/default/include/HandleImporter.h @@ -56,6 +56,9 @@ public: YCbCrLayout lockYCbCr(buffer_handle_t& buf, uint64_t cpuUsage, const IMapper::Rect& accessRegion); + // Query the stride of the first plane in bytes. + status_t getMonoPlanarStrideBytes(buffer_handle_t& buf, uint32_t* stride /*out*/); + int unlock(buffer_handle_t& buf); // returns release fence private: -- GitLab From f884283cd6bebe61c7d745b561e3beb194cd6948 Mon Sep 17 00:00:00 2001 From: Max Bires Date: Wed, 26 May 2021 13:05:09 -0700 Subject: [PATCH 679/790] Fixing tests to reflect change in CDDL This fixes up the tests to go along with the change to the signature of the MAC key. Primarily, this adds the MAC tag from the MACing operation over the public key set to be signed into the AAD of the signature of said MAC key. Bug: 189018262 Test: atest VtsHalRemotelyProvisionedComponentTargetTest Change-Id: Ibdcf242e0ae73dee1a08fe98d939130055e4492e --- .../aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp index a2071c2c38..a177317297 100644 --- a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp +++ b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp @@ -340,6 +340,7 @@ class CertificateRequestTest : public VtsRemotelyProvisionedComponentTests { cppbor::Array() // SignedMacAad .add(challenge_) .add(std::move(deviceInfoMap)) + .add(keysToSignMac) .encode()); ASSERT_TRUE(macKey) << macKey.message(); -- GitLab From 12ea07108ede53f5da7fd574031e32104127be64 Mon Sep 17 00:00:00 2001 From: Max Bires Date: Wed, 26 May 2021 18:07:27 -0700 Subject: [PATCH 680/790] Updating CDDL schemas to match the finalized spec. This primarily updates CDDL to allow for OEMs who wish to use P256 instead of Ed25519 to do so. One structural change of note that affects all implementors is that SignedMacAad now includes the tag from the COSE_Mac0 of MacedKeysToSign to prevent a potential vulnerability that would exist if an attacker compromised the server's EEK private key. Bug: 189018262 Test: Purely a comment change Change-Id: I043a19c6aba0f771315d45c04ab5263b610b5de8 --- .../hardware/security/keymint/DeviceInfo.aidl | 3 + .../IRemotelyProvisionedComponent.aidl | 103 +++++++++------- .../security/keymint/ProtectedData.aidl | 110 ++++++++++++------ 3 files changed, 141 insertions(+), 75 deletions(-) diff --git a/security/keymint/aidl/android/hardware/security/keymint/DeviceInfo.aidl b/security/keymint/aidl/android/hardware/security/keymint/DeviceInfo.aidl index 3ea14a1b97..32d69cd227 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/DeviceInfo.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/DeviceInfo.aidl @@ -37,10 +37,13 @@ parcelable DeviceInfo { * ? "board" : tstr, * ? "vb_state" : "green" / "yellow" / "orange", // Taken from the AVB values * ? "bootloader_state" : "locked" / "unlocked", // Taken from the AVB values + * ? "vbmeta_digest": bstr, // Taken from the AVB values * ? "os_version" : tstr, // Same as android.os.Build.VERSION.release * ? "system_patch_level" : uint, // YYYYMMDD * ? "boot_patch_level" : uint, // YYYYMMDD * ? "vendor_patch_level" : uint, // YYYYMMDD + * "version" : 1, // The CDDL schema version. + * "security_level" : "tee" / "strongbox" * } */ byte[] deviceInfo; diff --git a/security/keymint/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl b/security/keymint/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl index 04d91d0373..a29fb08553 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl @@ -33,8 +33,8 @@ import android.hardware.security.keymint.RpcHardwareInfo; * * The root of trust for secure provisioning is something called the "Boot Certificate Chain", or * BCC. The BCC is a chain of public key certificates, represented as COSE_Sign1 objects containing - * COSE_Key representations of the public keys. The "root" of the BCC is a self-signed certificate - * for a device-unique public key, denoted DK_pub. All public keys in the BCC are device-unique. The + * COSE_Key representations of the public keys. The "root" of the BCC is + * a device-unique public key, denoted DK_pub. All public keys in the BCC are device-unique. The * public key from each certificate in the chain is used to sign the next certificate in the * chain. The final, "leaf" certificate contains a public key, denoted KM_pub, whose corresponding * private key, denoted KM_priv, is available for use by the IRemotelyProvisionedComponent. @@ -58,12 +58,8 @@ import android.hardware.security.keymint.RpcHardwareInfo; * (given the necessary input), but no stage can compute the secret of any preceding stage. Updating * the firmware or configuration of any stage changes the key pair of that stage, and of all * subsequent stages, and no attacker who compromised the previous version of the updated firmware - * can know or predict the post-update key pairs. - * - * The first BCC certificate is special because its contained public key, DK_pub, will never change, - * making it a permanent, device-unique identifier. Although the remaining keys in the BCC are also - * device-unique, they are not necessarily permanent, since they can change when the device software - * is updated. + * can know or predict the post-update key pairs. It is recommended and expected that the BCC is + * constructed using the Open Profile for DICE. * * When the provisioning server receives a message signed by KM_priv and containing a BCC that * chains from DK_pub to KM_pub, it can be certain that (barring vulnerabilities in some boot @@ -78,7 +74,7 @@ import android.hardware.security.keymint.RpcHardwareInfo; * While a proper BCC, as described above, reflects the complete boot sequence from boot ROM to the * secure area image of the IRemotelyProvisionedComponent, it's also possible to use a "degenerate" * BCC which consists only of a single, self-signed certificate containing the public key of a - * hardware-bound key pair. This is an appropriate solution for devices which haven't implemented + * hardware-bound key pair. This is an appopriate solution for devices which haven't implemented * everything necessary to produce a proper BCC, but can derive a unique key pair in the secure * area. In this degenerate case, DK_pub is the same as KM_pub. * @@ -141,7 +137,7 @@ interface IRemotelyProvisionedComponent { * privateKeyHandle, that the contained public key is for remote certification. * * @return data representing a handle to the private key. The format is implementation-defined, - * but note that specific services may define a required format. + * but note that specific services may define a required format. KeyMint does. */ byte[] generateEcdsaP256KeyPair(in boolean testMode, out MacedPublicKey macedPublicKey); @@ -162,65 +158,90 @@ interface IRemotelyProvisionedComponent { * If testMode is false, the keysToCertify array must not contain any keys flagged as * test keys. Otherwise, the method must return STATUS_TEST_KEY_IN_PRODUCTION_REQUEST. * - * @param in endpointEncryptionKey contains an X25519 public key which will be used to encrypt + * @param in endpointEncryptionKey contains an X22519 public key which will be used to encrypt * the BCC. For flexibility, this is represented as a certificate chain, represented as a * CBOR array of COSE_Sign1 objects, ordered from root to leaf. The leaf contains the * X25519 encryption key, each other element is an Ed25519 key signing the next in the - * chain. The root is self-signed. + * chain. The root is self-signed. An implementor may also choose to use P256 as an + * alternative curve for signing and encryption instead of Curve 25519. * * EekChain = [ + SignedSignatureKey, SignedEek ] * * SignedSignatureKey = [ // COSE_Sign1 * protected: bstr .cbor { - * 1 : -8, // Algorithm : EdDSA + * 1 : AlgorithmEdDSA / AlgorithmES256, // Algorithm * }, - * unprotected: { }, - * payload: bstr .cbor SignatureKey, - * signature: bstr PureEd25519(.cbor SignatureKeySignatureInput) + * unprotected: {}, + * payload: bstr .cbor SignatureKeyEd25519 / + * bstr .cbor SignatureKeyP256, + * signature: bstr PureEd25519(.cbor SignatureKeySignatureInput) / + * bstr ECDSA(.cbor SignatureKeySignatureInput) * ] * - * SignatureKey = { // COSE_Key + * SignatureKeyEd25519 = { // COSE_Key * 1 : 1, // Key type : Octet Key Pair - * 3 : -8, // Algorithm : EdDSA + * 3 : AlgorithmEdDSA, // Algorithm * -1 : 6, // Curve : Ed25519 * -2 : bstr // Ed25519 public key * } * + * SignatureKeyP256 = { + * 1 : 2, // Key type : EC2 + * 3 : AlgorithmES256, // Algorithm + * -1 : 1, // Curve: P256 + * -2 : bstr, // X coordinate + * -3 : bstr // Y coordinate + * } + * * SignatureKeySignatureInput = [ * context: "Signature1", * body_protected: bstr .cbor { - * 1 : -8, // Algorithm : EdDSA + * 1 : AlgorithmEdDSA / AlgorithmES256, // Algorithm * }, * external_aad: bstr .size 0, - * payload: bstr .cbor SignatureKey + * payload: bstr .cbor SignatureKeyEd25519 / + * bstr .cbor SignatureKeyP256 * ] * * SignedEek = [ // COSE_Sign1 * protected: bstr .cbor { - * 1 : -8, // Algorithm : EdDSA + * 1 : AlgorithmEdDSA / AlgorithmES256, // Algorithm * }, - * unprotected: { }, - * payload: bstr .cbor Eek, - * signature: bstr PureEd25519(.cbor EekSignatureInput) + * unprotected: {}, + * payload: bstr .cbor EekX25519 / .cbor EekP256, + * signature: bstr PureEd25519(.cbor EekSignatureInput) / + * bstr ECDSA(.cbor EekSignatureInput) * ] * - * Eek = { // COSE_Key - * 1 : 1, // Key type : Octet Key Pair - * 2 : bstr // KID : EEK ID - * 3 : -25, // Algorithm : ECDH-ES + HKDF-256 - * -1 : 4, // Curve : X25519 - * -2 : bstr // X25519 public key + * EekX25519 = { // COSE_Key + * 1 : 1, // Key type : Octet Key Pair + * 2 : bstr // KID : EEK ID + * 3 : -25, // Algorithm : ECDH-ES + HKDF-256 + * -1 : 4, // Curve : X25519 + * -2 : bstr // Ed25519 public key + * } + * + * EekP256 = { // COSE_Key + * 1 : 2, // Key type : EC2 + * 2 : bstr // KID : EEK ID + * 3 : -25, // Algorithm : ECDH-ES + HKDF-256 + * -1 : 1, // Curve : P256 + * -2 : bstr // Sender X coordinate + * -3 : bstr // Sender Y coordinate * } * * EekSignatureInput = [ * context: "Signature1", * body_protected: bstr .cbor { - * 1 : -8, // Algorithm : EdDSA + * 1 : AlgorithmEdDSA / AlgorithmES256, // Algorithm * }, * external_aad: bstr .size 0, - * payload: bstr .cbor Eek + * payload: bstr .cbor EekX25519 / .cbor EekP256 * ] * + * AlgorithmES256 = -7 + * AlgorithmEdDSA = -8 + * * If the contents of endpointEncryptionKey do not match the SignedEek structure above, * the method must return STATUS_INVALID_EEK. * @@ -228,7 +249,7 @@ interface IRemotelyProvisionedComponent { * in the chain, which implies that it must not attempt to validate the signature. * * If testMode is false, the method must validate the chain signatures, and must verify - * that the public key in the root certificate is in its pre-configured set of + * that the public key in the root certifictate is in its pre-configured set of * authorized EEK root keys. If the public key is not in the database, or if signature * verification fails, the method must return STATUS_INVALID_EEK. * @@ -236,8 +257,13 @@ interface IRemotelyProvisionedComponent { * by the secure area. See the description of the 'signature' output parameter for * details. * - * @param out keysToSignMac contains the MAC of KeysToSign in the CertificateRequest - * structure. Specifically, it contains: + * @param out DeviceInfo contains the VerifiedDeviceInfo portion of the DeviceInfo array in + * CertificateRequest. The structure is described within the DeviceInfo.aidl file. + * + * @param out ProtectedData contains the encrypted BCC and the ephemeral MAC key used to + * authenticate the keysToSign (see keysToSignMac output argument). + * + * @return The of KeysToSign in the CertificateRequest structure. Specifically, it contains: * * HMAC-256(EK_mac, .cbor KeysToMacStructure) * @@ -248,11 +274,11 @@ interface IRemotelyProvisionedComponent { * protected : bstr .cbor { * 1 : 5, // Algorithm : HMAC-256 * }, - * unprotected : { }, + * unprotected : {}, * // Payload is PublicKeys from keysToSign argument, in provided order. * payload: bstr .cbor [ * PublicKey ], * tag: bstr - * ] + * ] * * KeysToMacStructure = [ * context : "MAC0", @@ -261,9 +287,6 @@ interface IRemotelyProvisionedComponent { * // Payload is PublicKeys from keysToSign argument, in provided order. * payload : bstr .cbor [ * PublicKey ] * ] - * - * @param out ProtectedData contains the encrypted BCC and the ephemeral MAC key used to - * authenticate the keysToSign (see keysToSignMac output argument). */ byte[] generateCertificateRequest(in boolean testMode, in MacedPublicKey[] keysToSign, in byte[] endpointEncryptionCertChain, in byte[] challenge, out DeviceInfo deviceInfo, diff --git a/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl b/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl index 519906203d..31dbb288ab 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl @@ -40,11 +40,7 @@ parcelable ProtectedData { * 1 : -25 // Algorithm : ECDH-ES + HKDF-256 * }, * unprotected : { - * -1 : { // COSE_Key - * 1 : 1, // Key type : Octet Key Pair - * -1 : 4, // Curve : X25519 - * -2 : bstr // Sender X25519 public key - * } + * -1 : PubKeyX25519 / PubKeyEcdhP256 // Of the sender * 4 : bstr, // KID : EEK ID * }, * ciphertext : nil @@ -67,7 +63,7 @@ parcelable ProtectedData { * other : bstr // EEK pubkey * ], * SuppPubInfo : [ - * 128, // Output key length + * 256, // Output key length * protected : bstr .size 0 * ] * ] @@ -75,34 +71,51 @@ parcelable ProtectedData { * ProtectedDataPayload [ * SignedMac, * Bcc, + * ? AdditionalDKSignatures, + * ] + * AdditionalDKSignatures = { + * + SignerName => DKCertChain + * } + * + * SignerName = tstr + * + * DKCertChain = [ + * 2* Certificate // Root -> Leaf. Root is the vendor + * // self-signed cert, leaf contains DK_pub * ] * - * SignedMac = [ // COSE_Sign1 - * bstr .cbor { // Protected params - * 1 : -8, // Algorithm : EdDSA + * Certificate = COSE_Sign1 of a public key + * + * SignedMac = [ // COSE_Sign1 + * bstr .cbor { // Protected params + * 1 : AlgorithmEdDSA / AlgorithmES256, // Algorithm * }, - * { }, // Unprotected params + * {}, // Unprotected params * bstr .size 32, // MAC key - * bstr PureEd25519(DK_priv, .cbor SignedMac_structure) + * bstr PureEd25519(KM_priv, .cbor SignedMac_structure) / + * ECDSA(KM_priv, bstr .cbor SignedMac_structure) * ] * * SignedMac_structure = [ * "Signature1", - * bstr .cbor { // Protected params - * 1 : -8, // Algorithm : EdDSA + * bstr .cbor { // Protected params + * 1 : AlgorithmEdDSA / AlgorithmES256, // Algorithm * }, * bstr .cbor SignedMacAad - * bstr .size 32 // MAC key + * bstr .size 32 // MAC key * ] * * SignedMacAad = [ * challenge : bstr, - * DeviceInfo + * VerifiedDeviceInfo, + * tag: bstr // This is the tag from COSE_Mac0 of + * // KeysToCertify, to tie the key set to + * // the signature. * ] * * Bcc = [ - * PubKey, // DK_pub - * + BccEntry, // Root -> leaf (KM_pub) + * PubKeyEd25519 / PubKeyECDSA256, // DK_pub + * + BccEntry, // Root -> leaf (KM_pub) * ] * * BccPayload = { // CWT @@ -120,44 +133,38 @@ parcelable ProtectedData { * ? -4670549 : bstr, // Authority Hash * ? -4670550 : bstr, // Authority Descriptor * ? -4670551 : bstr, // Mode - * -4670552 : bstr .cbor PubKey // Subject Public Key + * -4670552 : bstr .cbor PubKeyEd25519 / + * bstr .cbor PubKeyECDSA256 // Subject Public Key * -4670553 : bstr // Key Usage * } * - * BccEntry = [ // COSE_Sign1 - * protected: bstr .cbor { - * 1 : -8, // Algorithm : EdDSA + * BccEntry = [ // COSE_Sign1 (untagged) + * protected : bstr .cbor { + * 1 : AlgorithmEdDSA / AlgorithmES256, // Algorithm * }, - * unprotected: { }, + * unprotected: {}, * payload: bstr .cbor BccPayload, - * // First entry in the chain is signed by DK_pub, the others are each signed by their - * // immediate predecessor. See RFC 8032 for signature representation. - * signature: bstr .cbor PureEd25519(SigningKey, bstr .cbor BccEntryInput) + * signature: bstr .cbor PureEd25519(SigningKey, bstr .cbor BccEntryInput) / + * bstr .cbor ECDSA(SigningKey, bstr .cbor BccEntryInput) + * // See RFC 8032 for details of how to encode the signature value for Ed25519. * ] * - * PubKey = { // COSE_Key - * 1 : 1, // Key type : octet key pair - * 3 : -8, // Algorithm : EdDSA - * 4 : 2, // Ops: Verify - * -1 : 6, // Curve : Ed25519 - * -2 : bstr // X coordinate, little-endian - * } - * * BccEntryInput = [ * context: "Signature1", * protected: bstr .cbor { - * 1 : -8, // Algorithm : EdDSA + * 1 : AlgorithmEdDSA / AlgorithmES256, // Algorithm * }, * external_aad: bstr .size 0, * payload: bstr .cbor BccPayload * ] * - * DeviceInfo = { + * VerifiedDeviceInfo = { * ? "brand" : tstr, * ? "manufacturer" : tstr, * ? "product" : tstr, * ? "model" : tstr, * ? "board" : tstr, + * ? "device" : tstr, * ? "vb_state" : "green" / "yellow" / "orange", * ? "bootloader_state" : "locked" / "unlocked", * ? "os_version" : tstr, @@ -165,6 +172,39 @@ parcelable ProtectedData { * ? "boot_patch_level" : uint, // YYYYMMDD * ? "vendor_patch_level" : uint, // YYYYMMDD * } + * + * PubKeyX25519 = { // COSE_Key + * 1 : 1, // Key type : Octet Key Pair + * -1 : 4, // Curve : X25519 + * -2 : bstr // Sender X25519 public key + * } + * + * PubKeyEd25519 = { // COSE_Key + * 1 : 1, // Key type : octet key pair + * 3 : AlgorithmEdDSA, // Algorithm : EdDSA + * 4 : 2, // Ops: Verify + * -1 : 6, // Curve : Ed25519 + * -2 : bstr // X coordinate, little-endian + * } + * + * PubKeyEcdhP256 = { // COSE_Key + * 1 : 2, // Key type : EC2 + * -1 : 1, // Curve : P256 + * -2 : bstr // Sender X coordinate + * -3 : bstr // Sender Y coordinate + * } + * + * PubKeyECDSA256 = { // COSE_Key + * 1 : 2, // Key type : EC2 + * 3 : AlgorithmES256, // Algorithm : ECDSA w/ SHA-256 + * 4 : 2, // Ops: Verify + * -1 : 1, // Curve: P256 + * -2 : bstr, // X coordinate + * -3 : bstr // Y coordinate + * } + * + * AlgorithmES256 = -7 + * AlgorithmEdDSA = -8 */ byte[] protectedData; } -- GitLab From ee49e56f260a79c5477a9e074994b43f2d07a716 Mon Sep 17 00:00:00 2001 From: Cliff Wu Date: Fri, 21 May 2021 21:29:40 +0800 Subject: [PATCH 681/790] [VTS] Add test cases for ICameraInjectionSession.hal - Add test cases for ICameraInjectionSession.hal in VtsHalCameraProviderV2_4TargetTest. Bug: 171024665 Test: Camera VTS Change-Id: I5c16cc090b8bf0072163fbc928f4180d60c4206d --- .../VtsHalCameraProviderV2_4TargetTest.cpp | 315 ++++++++++++++++++ 1 file changed, 315 insertions(+) diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp index 0ec9fe34b0..41a08f9843 100644 --- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp +++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -767,6 +768,9 @@ public: sp *session3_5 /*out*/, sp *session3_6 /*out*/, sp *session3_7 /*out*/); + void castInjectionSession( + const sp& session, + sp* injectionSession3_7 /*out*/); void castDevice(const sp& device, int32_t deviceVersion, sp* device3_5 /*out*/, sp* device3_7 /*out*/); @@ -5880,6 +5884,301 @@ TEST_P(CameraHidlTest, providerDeviceStateNotification) { notifyDeviceState(provider::V2_5::DeviceState::NORMAL); } +// Verify that all supported stream formats and sizes can be configured +// successfully for injection camera. +TEST_P(CameraHidlTest, configureInjectionStreamsAvailableOutputs) { + hidl_vec cameraDeviceNames = getCameraDeviceNames(mProvider); + std::vector outputStreams; + + for (const auto& name : cameraDeviceNames) { + int deviceVersion = getCameraDeviceVersion(name, mProviderType); + if (deviceVersion <= 0) { + ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); + ADD_FAILURE(); + return; + } else if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_7) { + continue; + } + + camera_metadata_t* staticMetaBuffer; + Return ret; + Status s; + sp session; + sp injectionSession3_7; + openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMetaBuffer /*out*/); + castInjectionSession(session, &injectionSession3_7); + if (injectionSession3_7 == nullptr) { + ALOGW("%s: The provider %s doesn't support ICameraInjectionSession", __func__, + mProviderType.c_str()); + continue; + } + + ::android::hardware::camera::device::V3_2::CameraMetadata hidlChars = {}; + hidlChars.setToExternal( + reinterpret_cast(const_cast(staticMetaBuffer)), + get_camera_metadata_size(staticMetaBuffer)); + + outputStreams.clear(); + ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMetaBuffer, outputStreams)); + ASSERT_NE(0u, outputStreams.size()); + + uint32_t jpegBufferSize = 0; + ASSERT_EQ(Status::OK, getJpegBufferSize(staticMetaBuffer, &jpegBufferSize)); + ASSERT_NE(0u, jpegBufferSize); + + int32_t streamId = 0; + uint32_t streamConfigCounter = 0; + for (auto& it : outputStreams) { + V3_2::Stream stream3_2; + V3_2::DataspaceFlags dataspaceFlag = getDataspace(static_cast(it.format)); + stream3_2 = {streamId, + StreamType::OUTPUT, + static_cast(it.width), + static_cast(it.height), + static_cast(it.format), + GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, + dataspaceFlag, + StreamRotation::ROTATION_0}; + ::android::hardware::hidl_vec streams3_2 = {stream3_2}; + ::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; + ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2; + createStreamConfiguration(streams3_2, StreamConfigurationMode::NORMAL_MODE, &config3_2, + &config3_4, &config3_5, &config3_7, jpegBufferSize); + + config3_7.streamConfigCounter = streamConfigCounter++; + s = injectionSession3_7->configureInjectionStreams(config3_7, hidlChars); + ASSERT_EQ(Status::OK, s); + streamId++; + } + + free_camera_metadata(staticMetaBuffer); + ret = session->close(); + ASSERT_TRUE(ret.isOk()); + } +} + +// Check for correct handling of invalid/incorrect configuration parameters for injection camera. +TEST_P(CameraHidlTest, configureInjectionStreamsInvalidOutputs) { + hidl_vec cameraDeviceNames = getCameraDeviceNames(mProvider); + std::vector outputStreams; + + for (const auto& name : cameraDeviceNames) { + int deviceVersion = getCameraDeviceVersion(name, mProviderType); + if (deviceVersion <= 0) { + ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); + ADD_FAILURE(); + return; + } else if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_7) { + continue; + } + + camera_metadata_t* staticMetaBuffer; + Return ret; + Status s; + sp session; + sp injectionSession3_7; + openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMetaBuffer /*out*/); + castInjectionSession(session, &injectionSession3_7); + if (injectionSession3_7 == nullptr) { + ALOGW("%s: The provider %s doesn't support ICameraInjectionSession", __func__, + mProviderType.c_str()); + continue; + } + + ::android::hardware::camera::device::V3_2::CameraMetadata hidlChars = {}; + hidlChars.setToExternal( + reinterpret_cast(const_cast(staticMetaBuffer)), + get_camera_metadata_size(staticMetaBuffer)); + + outputStreams.clear(); + ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMetaBuffer, outputStreams)); + ASSERT_NE(0u, outputStreams.size()); + + uint32_t jpegBufferSize = 0; + ASSERT_EQ(Status::OK, getJpegBufferSize(staticMetaBuffer, &jpegBufferSize)); + ASSERT_NE(0u, jpegBufferSize); + + int32_t streamId = 0; + V3_2::Stream stream3_2 = {streamId++, + StreamType::OUTPUT, + static_cast(0), + static_cast(0), + static_cast(outputStreams[0].format), + GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, + 0, + StreamRotation::ROTATION_0}; + uint32_t streamConfigCounter = 0; + ::android::hardware::hidl_vec streams = {stream3_2}; + ::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; + ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2; + createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, &config3_2, + &config3_4, &config3_5, &config3_7, jpegBufferSize); + + config3_7.streamConfigCounter = streamConfigCounter++; + s = injectionSession3_7->configureInjectionStreams(config3_7, hidlChars); + ASSERT_TRUE((Status::ILLEGAL_ARGUMENT == s) || (Status::INTERNAL_ERROR == s)); + + stream3_2 = {streamId++, + StreamType::OUTPUT, + static_cast(UINT32_MAX), + static_cast(UINT32_MAX), + static_cast(outputStreams[0].format), + GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, + 0, + StreamRotation::ROTATION_0}; + streams[0] = stream3_2; + createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, &config3_2, + &config3_4, &config3_5, &config3_7, jpegBufferSize); + config3_7.streamConfigCounter = streamConfigCounter++; + s = injectionSession3_7->configureInjectionStreams(config3_7, hidlChars); + ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); + + for (auto& it : outputStreams) { + stream3_2 = {streamId++, + StreamType::OUTPUT, + static_cast(it.width), + static_cast(it.height), + static_cast(UINT32_MAX), + GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, + 0, + StreamRotation::ROTATION_0}; + streams[0] = stream3_2; + createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, &config3_2, + &config3_4, &config3_5, &config3_7, jpegBufferSize); + config3_7.streamConfigCounter = streamConfigCounter++; + s = injectionSession3_7->configureInjectionStreams(config3_7, hidlChars); + ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); + + stream3_2 = {streamId++, + StreamType::OUTPUT, + static_cast(it.width), + static_cast(it.height), + static_cast(it.format), + GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, + 0, + static_cast(UINT32_MAX)}; + streams[0] = stream3_2; + createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, &config3_2, + &config3_4, &config3_5, &config3_7, jpegBufferSize); + config3_7.streamConfigCounter = streamConfigCounter++; + s = injectionSession3_7->configureInjectionStreams(config3_7, hidlChars); + ASSERT_EQ(Status::ILLEGAL_ARGUMENT, s); + } + + free_camera_metadata(staticMetaBuffer); + ret = session->close(); + ASSERT_TRUE(ret.isOk()); + } +} + +// Check whether session parameters are supported for injection camera. If Hal support for them +// exist, then try to configure a preview stream using them. +TEST_P(CameraHidlTest, configureInjectionStreamsWithSessionParameters) { + hidl_vec cameraDeviceNames = getCameraDeviceNames(mProvider); + std::vector outputPreviewStreams; + AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight, + static_cast(PixelFormat::IMPLEMENTATION_DEFINED)}; + + for (const auto& name : cameraDeviceNames) { + int deviceVersion = getCameraDeviceVersion(name, mProviderType); + if (deviceVersion <= 0) { + ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); + ADD_FAILURE(); + return; + } else if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_7) { + continue; + } + + camera_metadata_t* staticMetaBuffer; + Return ret; + Status s; + sp session; + sp injectionSession3_7; + openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMetaBuffer /*out*/); + castInjectionSession(session, &injectionSession3_7); + if (injectionSession3_7 == nullptr) { + ALOGW("%s: The provider %s doesn't support ICameraInjectionSession", __func__, + mProviderType.c_str()); + continue; + } + + ::android::hardware::camera::device::V3_2::CameraMetadata hidlChars = {}; + hidlChars.setToExternal( + reinterpret_cast(const_cast(staticMetaBuffer)), + get_camera_metadata_size(staticMetaBuffer)); + + std::unordered_set availableSessionKeys; + auto rc = getSupportedKeys(staticMetaBuffer, ANDROID_REQUEST_AVAILABLE_SESSION_KEYS, + &availableSessionKeys); + ASSERT_TRUE(Status::OK == rc); + if (availableSessionKeys.empty()) { + free_camera_metadata(staticMetaBuffer); + ret = session->close(); + ASSERT_TRUE(ret.isOk()); + continue; + } + + android::hardware::camera::common::V1_0::helper::CameraMetadata previewRequestSettings; + android::hardware::camera::common::V1_0::helper::CameraMetadata sessionParams, + modifiedSessionParams; + constructFilteredSettings(session, availableSessionKeys, RequestTemplate::PREVIEW, + &previewRequestSettings, &sessionParams); + if (sessionParams.isEmpty()) { + free_camera_metadata(staticMetaBuffer); + ret = session->close(); + ASSERT_TRUE(ret.isOk()); + continue; + } + + outputPreviewStreams.clear(); + + ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMetaBuffer, outputPreviewStreams, + &previewThreshold)); + ASSERT_NE(0u, outputPreviewStreams.size()); + + V3_4::Stream previewStream; + previewStream.v3_2 = {0, + StreamType::OUTPUT, + static_cast(outputPreviewStreams[0].width), + static_cast(outputPreviewStreams[0].height), + static_cast(outputPreviewStreams[0].format), + GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, + 0, + StreamRotation::ROTATION_0}; + previewStream.bufferSize = 0; + ::android::hardware::hidl_vec streams = {previewStream}; + ::android::hardware::camera::device::V3_4::StreamConfiguration config; + ::android::hardware::camera::device::V3_5::StreamConfiguration config3_5; + ::android::hardware::camera::device::V3_7::StreamConfiguration config3_7; + config.streams = streams; + config.operationMode = StreamConfigurationMode::NORMAL_MODE; + modifiedSessionParams = sessionParams; + auto sessionParamsBuffer = sessionParams.release(); + config.sessionParams.setToExternal(reinterpret_cast(sessionParamsBuffer), + get_camera_metadata_size(sessionParamsBuffer)); + config3_5.v3_4 = config; + config3_5.streamConfigCounter = 0; + config3_7.streams = {{previewStream, -1, {ANDROID_SENSOR_PIXEL_MODE_DEFAULT}}}; + config3_7.operationMode = config.operationMode; + config3_7.sessionParams.setToExternal(reinterpret_cast(sessionParamsBuffer), + get_camera_metadata_size(sessionParamsBuffer)); + config3_7.streamConfigCounter = 0; + config3_7.multiResolutionInputImage = false; + + s = injectionSession3_7->configureInjectionStreams(config3_7, hidlChars); + sessionParams.acquire(sessionParamsBuffer); + ASSERT_EQ(Status::OK, s); + + free_camera_metadata(staticMetaBuffer); + ret = session->close(); + ASSERT_TRUE(ret.isOk()); + } +} + // Retrieve all valid output stream resolutions from the camera // static characteristics. Status CameraHidlTest::getAvailableOutputStreams(const camera_metadata_t* staticMeta, @@ -7253,6 +7552,22 @@ void CameraHidlTest::castSession(const sp &session, int32_ } } +// Cast camera device session to injection session +void CameraHidlTest::castInjectionSession( + const sp& session, + sp* injectionSession3_7 /*out*/) { + ASSERT_NE(nullptr, injectionSession3_7); + + sp session3_7; + auto castResult = device::V3_7::ICameraDeviceSession::castFrom(session); + ASSERT_TRUE(castResult.isOk()); + session3_7 = castResult; + + auto castInjectionResult = device::V3_7::ICameraInjectionSession::castFrom(session3_7); + ASSERT_TRUE(castInjectionResult.isOk()); + *injectionSession3_7 = castInjectionResult; +} + void CameraHidlTest::verifyStreamCombination( sp cameraDevice3_7, const ::android::hardware::camera::device::V3_7::StreamConfiguration& config3_7, -- GitLab From 266c36a509685f183cc7d9b904937fcaa239ee43 Mon Sep 17 00:00:00 2001 From: Yu-Han Yang Date: Thu, 27 May 2021 16:00:59 -0700 Subject: [PATCH 682/790] Fix deadlock in reportMeasurement() and stop() Bug: 187361220 Test: atest android.location.cts.fine.LocationManagerFineTest#testRegisterGnssMeasurementsCallback --iteration=20 Change-Id: I4c35be19864d851170c0c8f0981fecab423f2a74 --- gnss/aidl/default/GnssHidlHal.cpp | 1 - gnss/aidl/default/GnssMeasurementInterface.cpp | 17 +++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/gnss/aidl/default/GnssHidlHal.cpp b/gnss/aidl/default/GnssHidlHal.cpp index 263715c47a..10b0106f32 100644 --- a/gnss/aidl/default/GnssHidlHal.cpp +++ b/gnss/aidl/default/GnssHidlHal.cpp @@ -43,7 +43,6 @@ GnssHidlHal::GnssHidlHal(const std::shared_ptr& gnssAidl) : mGnssAidl(gnss hidl_vec GnssHidlHal::filterBlocklistedSatellitesV2_1( hidl_vec gnssSvInfoList) { - ALOGD("GnssHidlHal::filterBlocklistSatellitesV2_1"); if (mGnssConfigurationAidl == nullptr) { ALOGE("Handle to AIDL GnssConfiguration is not available."); return gnssSvInfoList; diff --git a/gnss/aidl/default/GnssMeasurementInterface.cpp b/gnss/aidl/default/GnssMeasurementInterface.cpp index a66bfc1864..fcc1f986cc 100644 --- a/gnss/aidl/default/GnssMeasurementInterface.cpp +++ b/gnss/aidl/default/GnssMeasurementInterface.cpp @@ -75,19 +75,20 @@ void GnssMeasurementInterface::start(const bool enableCorrVecOutputs) { void GnssMeasurementInterface::stop() { ALOGD("stop"); mIsActive = false; - if (mThread.joinable()) { - mThread.join(); - } } void GnssMeasurementInterface::reportMeasurement(const GnssData& data) { ALOGD("reportMeasurement()"); - std::unique_lock lock(mMutex); - if (sCallback == nullptr) { - ALOGE("%s: GnssMeasurement::sCallback is null.", __func__); - return; + std::shared_ptr callbackCopy; + { + std::unique_lock lock(mMutex); + if (sCallback == nullptr) { + ALOGE("%s: GnssMeasurement::sCallback is null.", __func__); + return; + } + callbackCopy = sCallback; } - sCallback->gnssMeasurementCb(data); + callbackCopy->gnssMeasurementCb(data); } } // namespace aidl::android::hardware::gnss -- GitLab From 6d3fa0a331aac552fe09f8414f8792e11db80ad9 Mon Sep 17 00:00:00 2001 From: Eino-Ville Talvala Date: Thu, 27 May 2021 14:05:57 -0700 Subject: [PATCH 683/790] Camera: Add framework-only enum value to test pattern mode Adding TEST_PATTERN_MODE_BLACK to support the new sensor privacy feature on more limited-capability camera implementations. Also updating older docs due to an API being moved to public. Test: Camera CTS continues to pass Bug: 189507251 Change-Id: I043d011ad43070d6c402cdffbff3d2e9b70ffd7b --- camera/metadata/3.5/types.hal | 4 ++-- camera/metadata/3.6/types.hal | 8 ++++++++ current.txt | 3 ++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/camera/metadata/3.5/types.hal b/camera/metadata/3.5/types.hal index 99d61152ac..d32bc91968 100644 --- a/camera/metadata/3.5/types.hal +++ b/camera/metadata/3.5/types.hal @@ -73,7 +73,7 @@ enum CameraMetadataTag : @3.4::CameraMetadataTag { ANDROID_CONTROL_END_3_5, - /** android.scaler.availableRotateAndCropModes [static, byte[], hidden] + /** android.scaler.availableRotateAndCropModes [static, byte[], public] * *

    List of rotate-and-crop modes for ANDROID_SCALER_ROTATE_AND_CROP that are supported by this camera device.

    * @@ -81,7 +81,7 @@ enum CameraMetadataTag : @3.4::CameraMetadataTag { */ ANDROID_SCALER_AVAILABLE_ROTATE_AND_CROP_MODES = android.hardware.camera.metadata@3.4::CameraMetadataTag:ANDROID_SCALER_END_3_4, - /** android.scaler.rotateAndCrop [dynamic, enum, hidden] + /** android.scaler.rotateAndCrop [dynamic, enum, public] * *

    Whether a rotation-and-crop operation is applied to processed * outputs from the camera.

    diff --git a/camera/metadata/3.6/types.hal b/camera/metadata/3.6/types.hal index 97cac7c3e8..185687c4df 100644 --- a/camera/metadata/3.6/types.hal +++ b/camera/metadata/3.6/types.hal @@ -348,6 +348,14 @@ enum CameraMetadataEnumAndroidScalerMultiResolutionStreamSupported : uint32_t { ANDROID_SCALER_MULTI_RESOLUTION_STREAM_SUPPORTED_TRUE, }; +/** android.sensor.testPatternMode enumeration values added since v3.2 + * @see ANDROID_SENSOR_TEST_PATTERN_MODE + */ +enum CameraMetadataEnumAndroidSensorTestPatternMode : + @3.2::CameraMetadataEnumAndroidSensorTestPatternMode { + ANDROID_SENSOR_TEST_PATTERN_MODE_BLACK, +}; + /** android.sensor.pixelMode enumeration values * @see ANDROID_SENSOR_PIXEL_MODE */ diff --git a/current.txt b/current.txt index 3102972081..ca4fb61e6d 100644 --- a/current.txt +++ b/current.txt @@ -767,6 +767,7 @@ a64467bae843569f0d465c5be7f0c7a5b987985b55a3ef4794dd5afc68538650 android.hardwar 98592d193a717066facf91428426e5abe211e3bd718bc372e29fb944ddbe6e7c android.hardware.wifi.supplicant@1.3::types # ABI preserving changes to HALs during Android S +159a0069336035852e9eca6354b86b7990680d1b239f23ef2f631b01807c4cb9 android.hardware.camera.metadata@3.5::types e042522daa4b5f7fd4a0a19bcdadb93c79a1b04c09ef2c9813a3a8941032f3f5 android.hardware.contexthub@1.0::IContexthub c2f64133b83ede65c9939ef97ab5bd867b73faf3dba0e7e69f77c3c43d9e487e android.hardware.contexthub@1.0::IContexthubCallback bda492ec4021d13869de72bd6f8c15c5837b78d6136b8d538efec5320573a5ec android.hardware.gnss@1.0::IGnssMeasurementCallback @@ -834,7 +835,7 @@ c17d9e27abd37ae5a8ff8da08fc5c9b13a264670feef6bbbc9d3ab1915216130 android.hardwar 3be6faa3d11ad9c7ec01a1a0a009cf11cb65d701d109dab37613ce9cfb3cdd60 android.hardware.camera.device@3.7::ICameraDeviceSession 3740ec773b2eb8fa6bd8c6e879eedb56c4e4306b88f1c20fa51103d791d871b1 android.hardware.camera.device@3.7::ICameraInjectionSession 21f023685571daf46148097d98b89cea353f07e3ed83b2ed5685b23bd136c3ee android.hardware.camera.device@3.7::types -f655c93132d223369ff6ddc621cb721f82dde6cc85ab9df2cbde6cb24cf2c885 android.hardware.camera.metadata@3.6::types +e932e7ef95210142e1fd3a4504e1d19bdb1acc988450f1ced543f3401f67855a android.hardware.camera.metadata@3.6::types 98ff825a7d37e5ab983502d13cec1f2e5a9cac9b674b6ff1a52bcf540f4e315e android.hardware.camera.provider@2.7::ICameraProvider 51fd14005859b16be55872660c34f5d423c77a2abcc5d4bdd5a537c40f32516b android.hardware.camera.provider@2.7::types 3500d3c4e2d49eeed2f3239330a166beb2db2d5071b84d9c738b048c2d54a3d9 android.hardware.contexthub@1.2::IContexthub -- GitLab From b098e79d834bc2a7f78c7fc2aaaf102a3bf9d966 Mon Sep 17 00:00:00 2001 From: David Zeuthen Date: Tue, 1 Jun 2021 09:51:30 -0400 Subject: [PATCH 684/790] identity: Fix VTS test failure caused by unrelated change to system/keymaster. Bug: 189447009 Test: atest VtsHalIdentityTargetTest Test: atest CtsIdentityTestCases Change-Id: I58426f1551efa920909c759cf5e10f44c6cfc5d4 Merged-In: I58426f1551efa920909c759cf5e10f44c6cfc5d4 --- identity/support/src/IdentityCredentialSupport.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/identity/support/src/IdentityCredentialSupport.cpp b/identity/support/src/IdentityCredentialSupport.cpp index 4547624fde..7f4674d24a 100644 --- a/identity/support/src/IdentityCredentialSupport.cpp +++ b/identity/support/src/IdentityCredentialSupport.cpp @@ -644,7 +644,7 @@ optional>> createAttestation( // the VTS tests. Of course, this is a pretend-only game since hopefully no // relying party is ever going to trust our batch key and those keys above // it. - ::keymaster::PureSoftKeymasterContext context(::keymaster::KmVersion::KEYMASTER_4_1, + ::keymaster::PureSoftKeymasterContext context(::keymaster::KmVersion::KEYMINT_1, KM_SECURITY_LEVEL_TRUSTED_ENVIRONMENT); keymaster_error_t error; @@ -682,10 +682,9 @@ optional>> createAttestation( i2d_X509_NAME(subjectName.get(), &subjectPtr); - uint64_t nowMilliSeconds = time(nullptr) * 1000; ::keymaster::AuthorizationSet auth_set( ::keymaster::AuthorizationSetBuilder() - .Authorization(::keymaster::TAG_CERTIFICATE_NOT_BEFORE, nowMilliSeconds) + .Authorization(::keymaster::TAG_CERTIFICATE_NOT_BEFORE, activeTimeMilliSeconds) .Authorization(::keymaster::TAG_CERTIFICATE_NOT_AFTER, expireTimeMilliSeconds) .Authorization(::keymaster::TAG_ATTESTATION_CHALLENGE, challenge.data(), challenge.size()) -- GitLab From 95accb094ecf5bc272bce34f371888a8bec39280 Mon Sep 17 00:00:00 2001 From: David Zeuthen Date: Thu, 27 May 2021 18:24:36 -0400 Subject: [PATCH 685/790] identity: Don't pass invalid profileIds in VTS test. Also add a check in the default implementation to help catch bugs like this in the future. Bug: 189865806 Test: atest VtsHalIdentityTargetTest Test: atest CtsIdentityTestCases Change-Id: Ief55528af8e14707b5c4d9431a851f9c8ccfae0c Merged-In: Ief55528af8e14707b5c4d9431a851f9c8ccfae0c --- .../aidl/default/common/WritableIdentityCredential.cpp | 9 +++++++++ identity/aidl/vts/DeleteCredentialTests.cpp | 2 +- identity/aidl/vts/ProveOwnershipTests.cpp | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/identity/aidl/default/common/WritableIdentityCredential.cpp b/identity/aidl/default/common/WritableIdentityCredential.cpp index 25f129b14b..200ee61df4 100644 --- a/identity/aidl/default/common/WritableIdentityCredential.cpp +++ b/identity/aidl/default/common/WritableIdentityCredential.cpp @@ -210,6 +210,15 @@ ndk::ScopedAStatus WritableIdentityCredential::beginAddEntry( "numAccessControlProfileRemaining_ is not zero")); } + // Ensure passed-in profile ids reference valid access control profiles + for (const int32_t id : accessControlProfileIds) { + if (accessControlProfileIds_.find(id) == accessControlProfileIds_.end()) { + return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( + IIdentityCredentialStore::STATUS_INVALID_DATA, + "An id in accessControlProfileIds references non-existing ACP")); + } + } + if (remainingEntryCounts_.size() == 0) { return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( IIdentityCredentialStore::STATUS_INVALID_DATA, "No more namespaces to add to")); diff --git a/identity/aidl/vts/DeleteCredentialTests.cpp b/identity/aidl/vts/DeleteCredentialTests.cpp index d3addf4b90..7627c9cbb9 100644 --- a/identity/aidl/vts/DeleteCredentialTests.cpp +++ b/identity/aidl/vts/DeleteCredentialTests.cpp @@ -102,7 +102,7 @@ void DeleteCredentialTests::provisionData() { ASSERT_TRUE(wc->addAccessControlProfile(1, {}, false, 0, 0, &sacp).isOk()); // Single entry - don't care about the returned encrypted data - ASSERT_TRUE(wc->beginAddEntry({0}, "ns", "Some Data", 1).isOk()); + ASSERT_TRUE(wc->beginAddEntry({1}, "ns", "Some Data", 1).isOk()); vector encryptedData; ASSERT_TRUE(wc->addEntryValue({9}, &encryptedData).isOk()); diff --git a/identity/aidl/vts/ProveOwnershipTests.cpp b/identity/aidl/vts/ProveOwnershipTests.cpp index fa0e293388..c622193ef5 100644 --- a/identity/aidl/vts/ProveOwnershipTests.cpp +++ b/identity/aidl/vts/ProveOwnershipTests.cpp @@ -102,7 +102,7 @@ void ProveOwnershipTests::provisionData() { ASSERT_TRUE(wc->addAccessControlProfile(1, {}, false, 0, 0, &sacp).isOk()); // Single entry - don't care about the returned encrypted data - ASSERT_TRUE(wc->beginAddEntry({0}, "ns", "Some Data", 1).isOk()); + ASSERT_TRUE(wc->beginAddEntry({1}, "ns", "Some Data", 1).isOk()); vector encryptedData; ASSERT_TRUE(wc->addEntryValue({9}, &encryptedData).isOk()); -- GitLab From dff39c00812fcc57a7b2b04e1c478d4ad1ed0e93 Mon Sep 17 00:00:00 2001 From: Slava Shklyaev Date: Fri, 30 Apr 2021 12:21:07 +0100 Subject: [PATCH 686/790] Modify VTS to allow testing shim caching Bug: 185777967 Bug: 182877255 Test: VtsHalNeuralnetworksTargetTest Change-Id: Ibaba149715cfd5e655ce4916b75a29473170f013 Merged-In: Ibaba149715cfd5e655ce4916b75a29473170f013 (cherry picked from commit 2980a7c9fc50aff7613ac96abd8294bed5560b88) --- .../functional/CompilationCachingTests.cpp | 177 +++++++++--------- 1 file changed, 89 insertions(+), 88 deletions(-) diff --git a/neuralnetworks/aidl/vts/functional/CompilationCachingTests.cpp b/neuralnetworks/aidl/vts/functional/CompilationCachingTests.cpp index e0b529f280..94ce5c1130 100644 --- a/neuralnetworks/aidl/vts/functional/CompilationCachingTests.cpp +++ b/neuralnetworks/aidl/vts/functional/CompilationCachingTests.cpp @@ -357,16 +357,40 @@ class CompilationCachingTestBase : public testing::Test { return false; } + // If fallbackModel is not provided, call prepareModelFromCache. + // If fallbackModel is provided, and prepareModelFromCache returns GENERAL_FAILURE, + // then prepareModel(fallbackModel) will be called. + // This replicates the behaviour of the runtime when loading a model from cache. + // NNAPI Shim depends on this behaviour and may try to load the model from cache in + // prepareModel (shim needs model information when loading from cache). void prepareModelFromCache(const std::vector& modelCache, const std::vector& dataCache, - std::shared_ptr* preparedModel, - ErrorStatus* status) { + std::shared_ptr* preparedModel, ErrorStatus* status, + const Model* fallbackModel = nullptr) { // Launch prepare model from cache. std::shared_ptr preparedModelCallback = ndk::SharedRefBase::make(); std::vector cacheToken(std::begin(mToken), std::end(mToken)); - const auto prepareLaunchStatus = kDevice->prepareModelFromCache( + auto prepareLaunchStatus = kDevice->prepareModelFromCache( kNoDeadline, modelCache, dataCache, cacheToken, preparedModelCallback); + + // The shim does not support prepareModelFromCache() properly, but it + // will still attempt to create a model from cache when modelCache or + // dataCache is provided in prepareModel(). Instead of failing straight + // away, we try to utilize that other code path when fallbackModel is + // set. Note that we cannot verify whether the returned model was + // actually prepared from cache in that case. + if (!prepareLaunchStatus.isOk() && + prepareLaunchStatus.getExceptionCode() == EX_SERVICE_SPECIFIC && + static_cast(prepareLaunchStatus.getServiceSpecificError()) == + ErrorStatus::GENERAL_FAILURE && + mIsCachingSupported && fallbackModel != nullptr) { + preparedModelCallback = ndk::SharedRefBase::make(); + prepareLaunchStatus = kDevice->prepareModel( + *fallbackModel, ExecutionPreference::FAST_SINGLE_ANSWER, kDefaultPriority, + kNoDeadline, modelCache, dataCache, cacheToken, preparedModelCallback); + } + ASSERT_TRUE(prepareLaunchStatus.isOk() || prepareLaunchStatus.getExceptionCode() == EX_SERVICE_SPECIFIC) << "prepareLaunchStatus: " << prepareLaunchStatus.getDescription(); @@ -382,6 +406,42 @@ class CompilationCachingTestBase : public testing::Test { *preparedModel = preparedModelCallback->getPreparedModel(); } + // Replicate behaviour of runtime when loading model from cache. + // Test if prepareModelFromCache behaves correctly when faced with bad + // arguments. If prepareModelFromCache is not supported (GENERAL_FAILURE), + // it attempts to call prepareModel with same arguments, which is expected either + // to not support the model (GENERAL_FAILURE) or return a valid model. + void verifyModelPreparationBehaviour(const std::vector& modelCache, + const std::vector& dataCache, + const Model* model, const TestModel& testModel) { + std::shared_ptr preparedModel; + ErrorStatus status; + + // Verify that prepareModelFromCache fails either due to bad + // arguments (INVALID_ARGUMENT) or GENERAL_FAILURE if not supported. + prepareModelFromCache(modelCache, dataCache, &preparedModel, &status, + /*fallbackModel=*/nullptr); + if (status != ErrorStatus::INVALID_ARGUMENT) { + ASSERT_EQ(status, ErrorStatus::GENERAL_FAILURE); + } + ASSERT_EQ(preparedModel, nullptr); + + // If caching is not supported, attempt calling prepareModel. + if (status == ErrorStatus::GENERAL_FAILURE) { + // Fallback with prepareModel should succeed regardless of cache files + prepareModelFromCache(modelCache, dataCache, &preparedModel, &status, + /*fallbackModel=*/model); + // Unless caching is not supported? + if (status != ErrorStatus::GENERAL_FAILURE) { + // But if it is, we should see a valid model. + ASSERT_EQ(status, ErrorStatus::NONE); + ASSERT_NE(preparedModel, nullptr); + EvaluatePreparedModel(kDevice, preparedModel, testModel, + /*testKind=*/TestKind::GENERAL); + } + } + } + // Absolute path to the temporary cache directory. std::string mCacheDir; @@ -397,7 +457,7 @@ class CompilationCachingTestBase : public testing::Test { uint8_t mToken[static_cast(IDevice::BYTE_SIZE_OF_CACHE_TOKEN)] = {}; uint32_t mNumModelCache; uint32_t mNumDataCache; - uint32_t mIsCachingSupported; + bool mIsCachingSupported; const std::shared_ptr kDevice; // The primary data type of the testModel. @@ -438,7 +498,8 @@ TEST_P(CompilationCachingTest, CacheSavingAndRetrieval) { std::vector modelCache, dataCache; createCacheFds(mModelCache, AccessMode::READ_WRITE, &modelCache); createCacheFds(mDataCache, AccessMode::READ_WRITE, &dataCache); - prepareModelFromCache(modelCache, dataCache, &preparedModel, &status); + prepareModelFromCache(modelCache, dataCache, &preparedModel, &status, + /*fallbackModel=*/&model); if (!mIsCachingSupported) { ASSERT_EQ(status, ErrorStatus::GENERAL_FAILURE); ASSERT_EQ(preparedModel, nullptr); @@ -498,7 +559,8 @@ TEST_P(CompilationCachingTest, CacheSavingAndRetrievalNonZeroOffset) { for (uint32_t i = 0; i < dataCache.size(); i++) { ASSERT_GE(read(dataCache[i].get(), &placeholderByte, 1), 0); } - prepareModelFromCache(modelCache, dataCache, &preparedModel, &status); + prepareModelFromCache(modelCache, dataCache, &preparedModel, &status, + /*fallbackModel=*/&model); if (!mIsCachingSupported) { ASSERT_EQ(status, ErrorStatus::GENERAL_FAILURE); ASSERT_EQ(preparedModel, nullptr); @@ -536,13 +598,7 @@ TEST_P(CompilationCachingTest, SaveToCacheInvalidNumCache) { // Execute and verify results. EvaluatePreparedModel(kDevice, preparedModel, testModel, /*testKind=*/TestKind::GENERAL); // Check if prepareModelFromCache fails. - preparedModel = nullptr; - ErrorStatus status; - prepareModelFromCache(modelCache, dataCache, &preparedModel, &status); - if (status != ErrorStatus::INVALID_ARGUMENT) { - ASSERT_EQ(status, ErrorStatus::GENERAL_FAILURE); - } - ASSERT_EQ(preparedModel, nullptr); + verifyModelPreparationBehaviour(modelCache, dataCache, &model, testModel); } // Test with number of model cache files smaller than mNumModelCache. @@ -560,13 +616,7 @@ TEST_P(CompilationCachingTest, SaveToCacheInvalidNumCache) { // Execute and verify results. EvaluatePreparedModel(kDevice, preparedModel, testModel, /*testKind=*/TestKind::GENERAL); // Check if prepareModelFromCache fails. - preparedModel = nullptr; - ErrorStatus status; - prepareModelFromCache(modelCache, dataCache, &preparedModel, &status); - if (status != ErrorStatus::INVALID_ARGUMENT) { - ASSERT_EQ(status, ErrorStatus::GENERAL_FAILURE); - } - ASSERT_EQ(preparedModel, nullptr); + verifyModelPreparationBehaviour(modelCache, dataCache, &model, testModel); } // Test with number of data cache files greater than mNumDataCache. @@ -583,13 +633,7 @@ TEST_P(CompilationCachingTest, SaveToCacheInvalidNumCache) { // Execute and verify results. EvaluatePreparedModel(kDevice, preparedModel, testModel, /*testKind=*/TestKind::GENERAL); // Check if prepareModelFromCache fails. - preparedModel = nullptr; - ErrorStatus status; - prepareModelFromCache(modelCache, dataCache, &preparedModel, &status); - if (status != ErrorStatus::INVALID_ARGUMENT) { - ASSERT_EQ(status, ErrorStatus::GENERAL_FAILURE); - } - ASSERT_EQ(preparedModel, nullptr); + verifyModelPreparationBehaviour(modelCache, dataCache, &model, testModel); } // Test with number of data cache files smaller than mNumDataCache. @@ -607,13 +651,7 @@ TEST_P(CompilationCachingTest, SaveToCacheInvalidNumCache) { // Execute and verify results. EvaluatePreparedModel(kDevice, preparedModel, testModel, /*testKind=*/TestKind::GENERAL); // Check if prepareModelFromCache fails. - preparedModel = nullptr; - ErrorStatus status; - prepareModelFromCache(modelCache, dataCache, &preparedModel, &status); - if (status != ErrorStatus::INVALID_ARGUMENT) { - ASSERT_EQ(status, ErrorStatus::GENERAL_FAILURE); - } - ASSERT_EQ(preparedModel, nullptr); + verifyModelPreparationBehaviour(modelCache, dataCache, &model, testModel); } } @@ -633,68 +671,48 @@ TEST_P(CompilationCachingTest, PrepareModelFromCacheInvalidNumCache) { // Test with number of model cache files greater than mNumModelCache. { - std::shared_ptr preparedModel = nullptr; - ErrorStatus status; std::vector modelCache, dataCache; mModelCache.push_back({mTmpCache}); createCacheFds(mModelCache, AccessMode::READ_WRITE, &modelCache); createCacheFds(mDataCache, AccessMode::READ_WRITE, &dataCache); mModelCache.pop_back(); - prepareModelFromCache(modelCache, dataCache, &preparedModel, &status); - if (status != ErrorStatus::GENERAL_FAILURE) { - ASSERT_EQ(status, ErrorStatus::INVALID_ARGUMENT); - } - ASSERT_EQ(preparedModel, nullptr); + + verifyModelPreparationBehaviour(modelCache, dataCache, &model, testModel); } // Test with number of model cache files smaller than mNumModelCache. if (mModelCache.size() > 0) { - std::shared_ptr preparedModel = nullptr; - ErrorStatus status; std::vector modelCache, dataCache; auto tmp = mModelCache.back(); mModelCache.pop_back(); createCacheFds(mModelCache, AccessMode::READ_WRITE, &modelCache); createCacheFds(mDataCache, AccessMode::READ_WRITE, &dataCache); mModelCache.push_back(tmp); - prepareModelFromCache(modelCache, dataCache, &preparedModel, &status); - if (status != ErrorStatus::GENERAL_FAILURE) { - ASSERT_EQ(status, ErrorStatus::INVALID_ARGUMENT); - } - ASSERT_EQ(preparedModel, nullptr); + + verifyModelPreparationBehaviour(modelCache, dataCache, &model, testModel); } // Test with number of data cache files greater than mNumDataCache. { - std::shared_ptr preparedModel = nullptr; - ErrorStatus status; std::vector modelCache, dataCache; mDataCache.push_back({mTmpCache}); createCacheFds(mModelCache, AccessMode::READ_WRITE, &modelCache); createCacheFds(mDataCache, AccessMode::READ_WRITE, &dataCache); mDataCache.pop_back(); - prepareModelFromCache(modelCache, dataCache, &preparedModel, &status); - if (status != ErrorStatus::GENERAL_FAILURE) { - ASSERT_EQ(status, ErrorStatus::INVALID_ARGUMENT); - } - ASSERT_EQ(preparedModel, nullptr); + + verifyModelPreparationBehaviour(modelCache, dataCache, &model, testModel); } // Test with number of data cache files smaller than mNumDataCache. if (mDataCache.size() > 0) { - std::shared_ptr preparedModel = nullptr; - ErrorStatus status; std::vector modelCache, dataCache; auto tmp = mDataCache.back(); mDataCache.pop_back(); createCacheFds(mModelCache, AccessMode::READ_WRITE, &modelCache); createCacheFds(mDataCache, AccessMode::READ_WRITE, &dataCache); mDataCache.push_back(tmp); - prepareModelFromCache(modelCache, dataCache, &preparedModel, &status); - if (status != ErrorStatus::GENERAL_FAILURE) { - ASSERT_EQ(status, ErrorStatus::INVALID_ARGUMENT); - } - ASSERT_EQ(preparedModel, nullptr); + + verifyModelPreparationBehaviour(modelCache, dataCache, &model, testModel); } } @@ -719,13 +737,7 @@ TEST_P(CompilationCachingTest, SaveToCacheInvalidAccessMode) { // Execute and verify results. EvaluatePreparedModel(kDevice, preparedModel, testModel, /*testKind=*/TestKind::GENERAL); // Check if prepareModelFromCache fails. - preparedModel = nullptr; - ErrorStatus status; - prepareModelFromCache(modelCache, dataCache, &preparedModel, &status); - if (status != ErrorStatus::INVALID_ARGUMENT) { - ASSERT_EQ(status, ErrorStatus::GENERAL_FAILURE); - } - ASSERT_EQ(preparedModel, nullptr); + verifyModelPreparationBehaviour(modelCache, dataCache, &model, testModel); } // Go through each handle in data cache, test with invalid access mode. @@ -741,13 +753,7 @@ TEST_P(CompilationCachingTest, SaveToCacheInvalidAccessMode) { // Execute and verify results. EvaluatePreparedModel(kDevice, preparedModel, testModel, /*testKind=*/TestKind::GENERAL); // Check if prepareModelFromCache fails. - preparedModel = nullptr; - ErrorStatus status; - prepareModelFromCache(modelCache, dataCache, &preparedModel, &status); - if (status != ErrorStatus::INVALID_ARGUMENT) { - ASSERT_EQ(status, ErrorStatus::GENERAL_FAILURE); - } - ASSERT_EQ(preparedModel, nullptr); + verifyModelPreparationBehaviour(modelCache, dataCache, &model, testModel); } } @@ -769,30 +775,23 @@ TEST_P(CompilationCachingTest, PrepareModelFromCacheInvalidAccessMode) { // Go through each handle in model cache, test with invalid access mode. for (uint32_t i = 0; i < mNumModelCache; i++) { - std::shared_ptr preparedModel = nullptr; - ErrorStatus status; std::vector modelCache, dataCache; modelCacheMode[i] = AccessMode::WRITE_ONLY; createCacheFds(mModelCache, modelCacheMode, &modelCache); createCacheFds(mDataCache, dataCacheMode, &dataCache); modelCacheMode[i] = AccessMode::READ_WRITE; - prepareModelFromCache(modelCache, dataCache, &preparedModel, &status); - ASSERT_EQ(status, ErrorStatus::GENERAL_FAILURE); - ASSERT_EQ(preparedModel, nullptr); + + verifyModelPreparationBehaviour(modelCache, dataCache, &model, testModel); } // Go through each handle in data cache, test with invalid access mode. for (uint32_t i = 0; i < mNumDataCache; i++) { - std::shared_ptr preparedModel = nullptr; - ErrorStatus status; std::vector modelCache, dataCache; dataCacheMode[i] = AccessMode::WRITE_ONLY; createCacheFds(mModelCache, modelCacheMode, &modelCache); createCacheFds(mDataCache, dataCacheMode, &dataCache); dataCacheMode[i] = AccessMode::READ_WRITE; - prepareModelFromCache(modelCache, dataCache, &preparedModel, &status); - ASSERT_EQ(status, ErrorStatus::GENERAL_FAILURE); - ASSERT_EQ(preparedModel, nullptr); + verifyModelPreparationBehaviour(modelCache, dataCache, &model, testModel); } } @@ -872,7 +871,8 @@ TEST_P(CompilationCachingTest, SaveToCache_TOCTOU) { std::vector modelCache, dataCache; createCacheFds(mModelCache, AccessMode::READ_WRITE, &modelCache); createCacheFds(mDataCache, AccessMode::READ_WRITE, &dataCache); - prepareModelFromCache(modelCache, dataCache, &preparedModel, &status); + prepareModelFromCache(modelCache, dataCache, &preparedModel, &status, + /*fallbackModel=*/nullptr); // The preparation may fail or succeed, but must not crash. If the preparation succeeds, // the prepared model must be executed with the correct result and not crash. @@ -933,7 +933,8 @@ TEST_P(CompilationCachingTest, PrepareFromCache_TOCTOU) { // Spawn a thread to copy the cache content concurrently while preparing from cache. std::thread thread(copyCacheFiles, std::cref(modelCacheMul), std::cref(mModelCache)); - prepareModelFromCache(modelCache, dataCache, &preparedModel, &status); + prepareModelFromCache(modelCache, dataCache, &preparedModel, &status, + /*fallbackModel=*/nullptr); thread.join(); // The preparation may fail or succeed, but must not crash. If the preparation succeeds, -- GitLab From 8c35c57811867e6f72694e1f4bb55794a1418878 Mon Sep 17 00:00:00 2001 From: Siarhei Vishniakou Date: Thu, 3 Jun 2021 16:38:58 +0000 Subject: [PATCH 687/790] Add IInputConstants dependency for Input.h In this VTS test, we are #including InputDevice.h, which in turn depends on Input.h. Since we are adding a depending on IInputConstants inside Input.h, update the makefiles here to pass the build. Bug: 175069843 Test: m VtsHalInputClassifierV1_0TargetTest Change-Id: I6acded6137362fb9554e7c0c74abb1e6370acff6 --- input/classifier/1.0/vts/functional/Android.bp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/input/classifier/1.0/vts/functional/Android.bp b/input/classifier/1.0/vts/functional/Android.bp index e170f4a613..58945d3f63 100644 --- a/input/classifier/1.0/vts/functional/Android.bp +++ b/input/classifier/1.0/vts/functional/Android.bp @@ -26,7 +26,10 @@ package { cc_test { name: "VtsHalInputClassifierV1_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], - srcs: ["VtsHalInputClassifierV1_0TargetTest.cpp"], + srcs: [ + ":inputconstants_aidl", + "VtsHalInputClassifierV1_0TargetTest.cpp", + ], header_libs: ["jni_headers"], static_libs: [ "android.hardware.input.classifier@1.0", -- GitLab From ad0bed60e9ac5b1f57e0784e443a8f57747a0084 Mon Sep 17 00:00:00 2001 From: Jiyong Park Date: Fri, 4 Jun 2021 12:10:18 +0900 Subject: [PATCH 688/790] Add owner field to android.hardware.tests.extension.vibrator This will prevent the interface from being updated with aidl-freeze-api. As the interface is for testing purpose, we really don't need to keep the latest ToT version and the latest stable version to be the same. Exempt that by adding the owner field to the interface. Bug: 188713899 Test: m Change-Id: I9a670f763c8f31f7c847f8ba8d4706efa075285e --- tests/extension/vibrator/aidl/Android.bp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/extension/vibrator/aidl/Android.bp b/tests/extension/vibrator/aidl/Android.bp index 96cfa082f9..20df5bb348 100644 --- a/tests/extension/vibrator/aidl/Android.bp +++ b/tests/extension/vibrator/aidl/Android.bp @@ -24,6 +24,9 @@ aidl_interface { // This is agreeing to keep the interface stable. stability: "vintf", + // This is a testing-purpose interface. Fine to use unstable version on REL platform. + owner: "test", + // This happens to use types from a core interface, so we import it, but // this won't always be needed. imports: [ -- GitLab From c0490422cf7efda9f1018a019a6d4a7544b55d3f Mon Sep 17 00:00:00 2001 From: Aaron Tsai Date: Wed, 2 Jun 2021 01:18:12 +0800 Subject: [PATCH 689/790] Allow REQUEST_NOT_SUPPORTED for HAL interface updateSimPhonebookRecords Bug: 188309710 Test: atest VtsHalRadioV1_6TargetTest Merged-In: Iad9c88582ddcd7f460be4276286fd5005cd9ae29 Merged-In: I75486da2210340980229e752f9bc2d93cedaa8c5 Merged-In: I7fc7667f9a2c0c52511febe2ca8061b0bab7ce7b Change-Id: Ia7f2a3983664ab4fcd16123026de87095a39f18e --- radio/1.6/vts/functional/radio_hidl_hal_api.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp index de18279474..35abb15369 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp +++ b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp @@ -865,7 +865,11 @@ TEST_P(RadioHidlTest_v1_6, updateSimPhonebookRecords) { EXPECT_EQ(std::cv_status::no_timeout, wait()); EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type); EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial); - EXPECT_EQ(::android::hardware::radio::V1_6::RadioError::NONE, radioRsp_v1_6->rspInfo.error); + ASSERT_TRUE(CheckAnyOfErrors( + radioRsp_v1_6->rspInfo.error, + {::android::hardware::radio::V1_6::RadioError::NONE, + ::android::hardware::radio::V1_6::RadioError::REQUEST_NOT_SUPPORTED}, + CHECK_GENERAL_ERROR)); if(pbCapacity.maxAdnRecords > 0 && pbCapacity.usedAdnRecords < pbCapacity.maxAdnRecords) { -- GitLab From 96ad2036b29bc13a133be3683649cf7c4256c0d0 Mon Sep 17 00:00:00 2001 From: David Drysdale Date: Thu, 20 May 2021 12:05:26 +0100 Subject: [PATCH 690/790] KeyMint VTS: test getKeyCharacteristics() Bug: 186685601 Bug: 188855306 Test: VtsAidlKeyMintTargetTest Merged-In: Icf400533b0ded98b9338f2d782d95d90c7efbff4 Change-Id: Icf400533b0ded98b9338f2d782d95d90c7efbff4 Ignore-AOSP-First: already merged in aosp/master --- .../aidl/vts/functional/AttestKeyTest.cpp | 7 ++ .../vts/functional/KeyMintAidlTestBase.cpp | 68 +++++++++++++++++++ .../aidl/vts/functional/KeyMintAidlTestBase.h | 14 ++++ .../aidl/vts/functional/KeyMintTest.cpp | 25 +++++++ 4 files changed, 114 insertions(+) diff --git a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp index b8699e9d50..ae2becdf9b 100644 --- a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp +++ b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp @@ -141,11 +141,18 @@ TEST_P(AttestKeyTest, AllRsaSizes) { attest_key, &attested_key_blob, &attested_key_characteristics, &attested_key_cert_chain)); + // The returned key characteristics will include CREATION_DATETIME (checked below) + // in SecurityLevel::KEYSTORE; this will be stripped out in the CheckCharacteristics() + // call below, to match what getKeyCharacteristics() returns (which doesn't include + // any SecurityLevel::KEYSTORE characteristics). + CheckCharacteristics(attested_key_blob, attested_key_characteristics); + CheckedDeleteKey(&attested_key_blob); CheckedDeleteKey(&attest_key.keyBlob); hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics); sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics); + // The client-specified CREATION_DATETIME should be in sw_enforced. // Its presence will also trigger verify_attestation_record() to check that it // is in the attestation extension with a matching value. diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp index a9a67bcc50..44b8274540 100644 --- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp +++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp @@ -142,6 +142,15 @@ AuthorizationSet filtered_tags(const AuthorizationSet& set) { return filtered; } +// Remove any SecurityLevel::KEYSTORE entries from a list of key characteristics. +void strip_keystore_tags(vector* characteristics) { + characteristics->erase(std::remove_if(characteristics->begin(), characteristics->end(), + [](const auto& entry) { + return entry.securityLevel == SecurityLevel::KEYSTORE; + }), + characteristics->end()); +} + string x509NameToStr(X509_NAME* name) { char* s = X509_NAME_oneline(name, nullptr, 0); string retval(s); @@ -320,6 +329,65 @@ ErrorCode KeyMintAidlTestBase::ImportWrappedKey(string wrapped_key, string wrapp return GetReturnErrorCode(result); } +ErrorCode KeyMintAidlTestBase::GetCharacteristics(const vector& key_blob, + const vector& app_id, + const vector& app_data, + vector* key_characteristics) { + Status result = + keymint_->getKeyCharacteristics(key_blob, app_id, app_data, key_characteristics); + return GetReturnErrorCode(result); +} + +ErrorCode KeyMintAidlTestBase::GetCharacteristics(const vector& key_blob, + vector* key_characteristics) { + vector empty_app_id, empty_app_data; + return GetCharacteristics(key_blob, empty_app_id, empty_app_data, key_characteristics); +} + +void KeyMintAidlTestBase::CheckCharacteristics( + const vector& key_blob, + const vector& generate_characteristics) { + // Any key characteristics that were in SecurityLevel::KEYSTORE when returned from + // generateKey() should be excluded, as KeyMint will have no record of them. + // This applies to CREATION_DATETIME in particular. + vector expected_characteristics(generate_characteristics); + strip_keystore_tags(&expected_characteristics); + + vector retrieved; + ASSERT_EQ(ErrorCode::OK, GetCharacteristics(key_blob, &retrieved)); + EXPECT_EQ(expected_characteristics, retrieved); +} + +void KeyMintAidlTestBase::CheckAppIdCharacteristics( + const vector& key_blob, std::string_view app_id_string, + std::string_view app_data_string, + const vector& generate_characteristics) { + // Exclude any SecurityLevel::KEYSTORE characteristics for comparisons. + vector expected_characteristics(generate_characteristics); + strip_keystore_tags(&expected_characteristics); + + vector app_id(app_id_string.begin(), app_id_string.end()); + vector app_data(app_data_string.begin(), app_data_string.end()); + vector retrieved; + ASSERT_EQ(ErrorCode::OK, GetCharacteristics(key_blob, app_id, app_data, &retrieved)); + EXPECT_EQ(expected_characteristics, retrieved); + + // Check that key characteristics can't be retrieved if the app ID or app data is missing. + vector empty; + vector not_retrieved; + EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB, + GetCharacteristics(key_blob, empty, app_data, ¬_retrieved)); + EXPECT_EQ(not_retrieved.size(), 0); + + EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB, + GetCharacteristics(key_blob, app_id, empty, ¬_retrieved)); + EXPECT_EQ(not_retrieved.size(), 0); + + EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB, + GetCharacteristics(key_blob, empty, empty, ¬_retrieved)); + EXPECT_EQ(not_retrieved.size(), 0); +} + ErrorCode KeyMintAidlTestBase::DeleteKey(vector* key_blob, bool keep_key_blob) { Status result = keymint_->deleteKey(*key_blob); if (!keep_key_blob) { diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h index d8f1bb3dbe..c49b303f50 100644 --- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h +++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h @@ -16,6 +16,8 @@ #pragma once +#include + #include #include #include @@ -104,6 +106,18 @@ class KeyMintAidlTestBase : public ::testing::TestWithParam { unwrapping_params, 0 /* password_sid */, 0 /* biometric_sid */); } + ErrorCode GetCharacteristics(const vector& key_blob, const vector& app_id, + const vector& app_data, + vector* key_characteristics); + ErrorCode GetCharacteristics(const vector& key_blob, + vector* key_characteristics); + + void CheckCharacteristics(const vector& key_blob, + const vector& generate_characteristics); + void CheckAppIdCharacteristics(const vector& key_blob, std::string_view app_id_string, + std::string_view app_data_string, + const vector& generate_characteristics); + ErrorCode DeleteKey(vector* key_blob, bool keep_key_blob = false); ErrorCode DeleteKey(bool keep_key_blob = false); diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp index 8b1eb30959..5dcfcaaa63 100644 --- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp +++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp @@ -560,6 +560,7 @@ TEST_P(NewKeyGenerationTest, Aes) { EXPECT_GT(key_blob.size(), 0U); CheckSymmetricParams(key_characteristics); + CheckCharacteristics(key_blob, key_characteristics); AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics); @@ -742,6 +743,7 @@ TEST_P(NewKeyGenerationTest, TripleDes) { EXPECT_GT(key_blob.size(), 0U); CheckSymmetricParams(key_characteristics); + CheckCharacteristics(key_blob, key_characteristics); AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics); @@ -788,6 +790,7 @@ TEST_P(NewKeyGenerationTest, TripleDesWithAttestation) { EXPECT_GT(key_blob.size(), 0U); CheckSymmetricParams(key_characteristics); + CheckCharacteristics(key_blob, key_characteristics); AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics); @@ -865,6 +868,7 @@ TEST_P(NewKeyGenerationTest, Rsa) { ASSERT_GT(key_blob.size(), 0U); CheckBaseParams(key_characteristics); + CheckCharacteristics(key_blob, key_characteristics); AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics); @@ -911,6 +915,7 @@ TEST_P(NewKeyGenerationTest, RsaWithAttestation) { ASSERT_GT(key_blob.size(), 0U); CheckBaseParams(key_characteristics); + CheckCharacteristics(key_blob, key_characteristics); AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics); @@ -978,6 +983,7 @@ TEST_P(NewKeyGenerationTest, RsaWithRpkAttestation) { ASSERT_GT(key_blob.size(), 0U); CheckBaseParams(key_characteristics); + CheckCharacteristics(key_blob, key_characteristics); AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics); @@ -1108,6 +1114,7 @@ TEST_P(NewKeyGenerationTest, RsaWithSelfSign) { ASSERT_GT(key_blob.size(), 0U); CheckBaseParams(key_characteristics); + CheckCharacteristics(key_blob, key_characteristics); AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics); @@ -1176,6 +1183,7 @@ TEST_P(NewKeyGenerationTest, RsaWithAttestationAppIdIgnored) { ASSERT_GT(key_blob.size(), 0U); CheckBaseParams(key_characteristics); + CheckCharacteristics(key_blob, key_characteristics); AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics); @@ -1211,6 +1219,7 @@ TEST_P(NewKeyGenerationTest, LimitedUsageRsa) { ASSERT_GT(key_blob.size(), 0U); CheckBaseParams(key_characteristics); + CheckCharacteristics(key_blob, key_characteristics); AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics); @@ -1266,6 +1275,7 @@ TEST_P(NewKeyGenerationTest, LimitedUsageRsaWithAttestation) { ASSERT_GT(key_blob.size(), 0U); CheckBaseParams(key_characteristics); + CheckCharacteristics(key_blob, key_characteristics); AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics); @@ -1362,6 +1372,7 @@ TEST_P(NewKeyGenerationTest, Ecdsa) { &key_blob, &key_characteristics)); ASSERT_GT(key_blob.size(), 0U); CheckBaseParams(key_characteristics); + CheckCharacteristics(key_blob, key_characteristics); AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics); @@ -1405,6 +1416,7 @@ TEST_P(NewKeyGenerationTest, EcdsaAttestation) { &key_blob, &key_characteristics)); ASSERT_GT(key_blob.size(), 0U); CheckBaseParams(key_characteristics); + CheckCharacteristics(key_blob, key_characteristics); AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics); @@ -1452,6 +1464,7 @@ TEST_P(NewKeyGenerationTest, EcdsaSelfSignAttestation) { &key_blob, &key_characteristics)); ASSERT_GT(key_blob.size(), 0U); CheckBaseParams(key_characteristics); + CheckCharacteristics(key_blob, key_characteristics); AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics); @@ -1511,6 +1524,7 @@ TEST_P(NewKeyGenerationTest, EcdsaIgnoreAppId) { ASSERT_GT(key_blob.size(), 0U); CheckBaseParams(key_characteristics); + CheckCharacteristics(key_blob, key_characteristics); AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics); @@ -1555,6 +1569,7 @@ TEST_P(NewKeyGenerationTest, AttestationApplicationIDLengthProperlyEncoded) { &key_blob, &key_characteristics)); ASSERT_GT(key_blob.size(), 0U); CheckBaseParams(key_characteristics); + CheckCharacteristics(key_blob, key_characteristics); AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics); @@ -1594,6 +1609,7 @@ TEST_P(NewKeyGenerationTest, LimitedUsageEcdsa) { ASSERT_GT(key_blob.size(), 0U); CheckBaseParams(key_characteristics); + CheckCharacteristics(key_blob, key_characteristics); AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics); @@ -1726,6 +1742,7 @@ TEST_P(NewKeyGenerationTest, Hmac) { ASSERT_GT(key_blob.size(), 0U); CheckBaseParams(key_characteristics); + CheckCharacteristics(key_blob, key_characteristics); AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics); EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::HMAC)); @@ -1761,6 +1778,7 @@ TEST_P(NewKeyGenerationTest, HmacNoAttestation) { ASSERT_GT(key_blob.size(), 0U); ASSERT_EQ(cert_chain_.size(), 0); CheckBaseParams(key_characteristics); + CheckCharacteristics(key_blob, key_characteristics); AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics); EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::HMAC)); @@ -1791,6 +1809,7 @@ TEST_P(NewKeyGenerationTest, LimitedUsageHmac) { ASSERT_GT(key_blob.size(), 0U); CheckBaseParams(key_characteristics); + CheckCharacteristics(key_blob, key_characteristics); AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics); EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::HMAC)); @@ -2044,6 +2063,9 @@ TEST_P(SigningOperationsTest, RsaUseRequiresCorrectAppIdAppData) { .Authorization(TAG_APPLICATION_ID, "clientid") .Authorization(TAG_APPLICATION_DATA, "appdata") .SetDefaultValidity())); + + CheckAppIdCharacteristics(key_blob_, "clientid", "appdata", key_characteristics_); + EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB, Begin(KeyPurpose::SIGN, AuthorizationSetBuilder().Digest(Digest::NONE).Padding(PaddingMode::NONE))); @@ -2558,6 +2580,9 @@ TEST_P(SigningOperationsTest, EcUseRequiresCorrectAppIdAppData) { .Authorization(TAG_APPLICATION_ID, "clientid") .Authorization(TAG_APPLICATION_DATA, "appdata") .SetDefaultValidity())); + + CheckAppIdCharacteristics(key_blob_, "clientid", "appdata", key_characteristics_); + EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB, Begin(KeyPurpose::SIGN, AuthorizationSetBuilder().Digest(Digest::NONE))); AbortIfNeeded(); -- GitLab From 8fc14a8d991a2508d045079a58a2d79b7e205c82 Mon Sep 17 00:00:00 2001 From: Hongguang Chen Date: Wed, 19 May 2021 15:43:29 -0700 Subject: [PATCH 691/790] Remove some TODOs from tuner HAL and its VTS. 1) The tuner cases should be always allowed on devices w/o tuner. -- VTS is common for all devices, we must allow the tuner cases to pass/skip on non TV devices. -- The tuner HAL is also optional on TV devices, like OTT, the tuner VTS cases should be skipped on those devices too. 2) Filter type has been checked in Demux::attachRecordFilter(). Bug: 188709323 Test: make vts Change-Id: Ifd1cb805d7f5d552a4aa7365ba78ff87b8a3ccc1 --- tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h | 8 -------- tv/tuner/1.1/default/Dvr.cpp | 1 - tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h | 3 +-- 3 files changed, 1 insertion(+), 11 deletions(-) diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h index 8358291cf3..7243a42c60 100644 --- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h +++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h @@ -79,7 +79,6 @@ class TunerFrontendHidlTest : public testing::TestWithParam { FrontendTests mFrontendTests; }; -// TODO remove from the allow list once the cf tv target is enabled for testing GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerFrontendHidlTest); class TunerLnbHidlTest : public testing::TestWithParam { @@ -101,7 +100,6 @@ class TunerLnbHidlTest : public testing::TestWithParam { LnbTests mLnbTests; }; -// TODO remove from the allow list once the cf tv target is enabled for testing GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerLnbHidlTest); class TunerDemuxHidlTest : public testing::TestWithParam { @@ -127,7 +125,6 @@ class TunerDemuxHidlTest : public testing::TestWithParam { FilterTests mFilterTests; }; -// TODO remove from the allow list once the cf tv target is enabled for testing GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerDemuxHidlTest); class TunerFilterHidlTest : public testing::TestWithParam { @@ -179,7 +176,6 @@ class TunerFilterHidlTest : public testing::TestWithParam { FilterTests mFilterTests; }; -// TODO remove from the allow list once the cf tv target is enabled for testing GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerFilterHidlTest); class TunerBroadcastHidlTest : public testing::TestWithParam { @@ -218,7 +214,6 @@ class TunerBroadcastHidlTest : public testing::TestWithParam { uint32_t* mLnbId = nullptr; }; -// TODO remove from the allow list once the cf tv target is enabled for testing GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerBroadcastHidlTest); class TunerPlaybackHidlTest : public testing::TestWithParam { @@ -250,7 +245,6 @@ class TunerPlaybackHidlTest : public testing::TestWithParam { void playbackSingleFilterTest(FilterConfig filterConf, DvrConfig dvrConf); }; -// TODO remove from the allow list once the cf tv target is enabled for testing GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerPlaybackHidlTest); class TunerRecordHidlTest : public testing::TestWithParam { @@ -290,7 +284,6 @@ class TunerRecordHidlTest : public testing::TestWithParam { uint32_t* mLnbId = nullptr; }; -// TODO remove from the allow list once the cf tv target is enabled for testing GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerRecordHidlTest); class TunerDescramblerHidlTest : public testing::TestWithParam { @@ -327,6 +320,5 @@ class TunerDescramblerHidlTest : public testing::TestWithParam { DvrTests mDvrTests; }; -// TODO remove from the allow list once the cf tv target is enabled for testing GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerDescramblerHidlTest); } // namespace diff --git a/tv/tuner/1.1/default/Dvr.cpp b/tv/tuner/1.1/default/Dvr.cpp index c487d98c36..93f4519f10 100644 --- a/tv/tuner/1.1/default/Dvr.cpp +++ b/tv/tuner/1.1/default/Dvr.cpp @@ -81,7 +81,6 @@ Return Dvr::attachFilter(const sp& filter) { return status; } - // TODO check if the attached filter is a record filter if (!mDemux->attachRecordFilter(filterId)) { return Result::INVALID_ARGUMENT; } diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h index 007e3d53df..13b9640749 100644 --- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h @@ -156,6 +156,5 @@ class TunerBroadcastHidlTest : public testing::TestWithParam { FrontendConfig1_1 frontendConf); }; -// TODO remove from the allow list once the cf tv target is enabled for testing GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerBroadcastHidlTest); -} // namespace \ No newline at end of file +} // namespace -- GitLab From c3d2bd4c564c5df51cf51dad9af1382908dd4cc3 Mon Sep 17 00:00:00 2001 From: Yomna Nasser Date: Wed, 2 Jun 2021 20:00:58 +0000 Subject: [PATCH 692/790] Adds VTS test for setAllowedNetworkTypesBitmap Adds a VTS test for setAllowedNetworkTypesBitmap, the newly defined HAL radio API. Bug: b/190398554 Test: atest VtsHalRadioV1_6TargetTest Change-Id: I1b7d85ddd70a2d116a3b54a10d168c20804f2524 --- .../1.6/vts/functional/radio_hidl_hal_api.cpp | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp index de18279474..ef9a08de73 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp +++ b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp @@ -18,6 +18,39 @@ #define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk()) +/* + * Test IRadio.setAllowedNetworkTypesBitmap for the response returned. + */ +TEST_P(RadioHidlTest_v1_6, setAllowedNetworkTypesBitmap) { + serial = GetRandomSerialNumber(); + ::android::hardware::hidl_bitfield<::android::hardware::radio::V1_4::RadioAccessFamily> + allowedNetworkTypesBitmap{}; + allowedNetworkTypesBitmap |= ::android::hardware::radio::V1_4::RadioAccessFamily::LTE; + + radio_v1_6->setAllowedNetworkTypesBitmap(serial, allowedNetworkTypesBitmap); + + EXPECT_EQ(std::cv_status::no_timeout, wait()); + EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type); + EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial); + + if (getRadioHalCapabilities()) { + ASSERT_TRUE(CheckAnyOfErrors( + radioRsp_v1_6->rspInfo.error, + {::android::hardware::radio::V1_6::RadioError::REQUEST_NOT_SUPPORTED})); + } else { + ASSERT_TRUE(CheckAnyOfErrors( + radioRsp_v1_6->rspInfo.error, + {::android::hardware::radio::V1_6::RadioError::NONE, + ::android::hardware::radio::V1_6::RadioError::RADIO_NOT_AVAILABLE, + ::android::hardware::radio::V1_6::RadioError::OPERATION_NOT_ALLOWED, + ::android::hardware::radio::V1_6::RadioError::MODE_NOT_SUPPORTED, + ::android::hardware::radio::V1_6::RadioError::INTERNAL_ERR, + ::android::hardware::radio::V1_6::RadioError::INVALID_ARGUMENTS, + ::android::hardware::radio::V1_6::RadioError::MODEM_ERR, + ::android::hardware::radio::V1_6::RadioError::NO_RESOURCES})); + } +} + /* * Test IRadio.setupDataCall_1_6() for the response returned. */ -- GitLab From b8d98f0be3b5ff793ae73e646f26741ef59ba5e8 Mon Sep 17 00:00:00 2001 From: Yu-Han Yang Date: Thu, 20 May 2021 19:26:10 -0700 Subject: [PATCH 693/790] Update VTS tests for SatellitePvt and CorrelationVector Wait until a measurement with SatellitePvt is received if it's supported. Similarly, wait until a measurement with Correlation Vector is received if it's supported. Bug: 184906297 Test: on device Change-Id: I4b26a2ec6f9f77fdc638dd5ab1ed8c131a55f545 --- gnss/aidl/vts/gnss_hal_test_cases.cpp | 258 +++++++++++++++++--------- 1 file changed, 171 insertions(+), 87 deletions(-) diff --git a/gnss/aidl/vts/gnss_hal_test_cases.cpp b/gnss/aidl/vts/gnss_hal_test_cases.cpp index 67ccf52c15..9d8562d9da 100644 --- a/gnss/aidl/vts/gnss_hal_test_cases.cpp +++ b/gnss/aidl/vts/gnss_hal_test_cases.cpp @@ -29,6 +29,7 @@ using android::sp; using android::hardware::gnss::BlocklistedSource; using android::hardware::gnss::ElapsedRealtime; using android::hardware::gnss::GnssClock; +using android::hardware::gnss::GnssData; using android::hardware::gnss::GnssMeasurement; using android::hardware::gnss::GnssPowerStats; using android::hardware::gnss::IGnss; @@ -65,59 +66,73 @@ TEST_P(GnssHalTest, TestPsdsExtension) { ASSERT_FALSE(status.isOk()); } -/* - * TestGnssMeasurementExtension: - * 1. Gets the GnssMeasurementExtension and verifies that it returns a non-null extension. - * 2. Sets a GnssMeasurementCallback, waits for a measurement, and verifies fields are valid. - */ -TEST_P(GnssHalTest, TestGnssMeasurementExtension) { - const bool kIsCorrelationVectorSupported = aidl_gnss_cb_->last_capabilities_ & - (int)GnssCallbackAidl::CAPABILITY_CORRELATION_VECTOR; - const int kFirstGnssMeasurementTimeoutSeconds = 10; - - bool has_capability_satpvt = false; - - sp iGnssMeasurement; - auto status = aidl_gnss_hal_->getExtensionGnssMeasurement(&iGnssMeasurement); - ASSERT_TRUE(status.isOk()); - ASSERT_TRUE(iGnssMeasurement != nullptr); - - auto callback = sp::make(); - status = - iGnssMeasurement->setCallback(callback, /* enableFullTracking= */ true, - /* enableCorrVecOutputs */ kIsCorrelationVectorSupported); - ASSERT_TRUE(status.isOk()); +void CheckSatellitePvt(const SatellitePvt& satellitePvt) { + const double kMaxOrbitRadiusMeters = 43000000.0; + const double kMaxVelocityMps = 4000.0; + // The below values are determined using GPS ICD Table 20-1 + const double kMinHardwareCodeBiasMeters = -17.869; + const double kMaxHardwareCodeBiasMeters = 17.729; + const double kMaxTimeCorrelationMeters = 3e6; + const double kMaxSatClkDriftMps = 1.117; + + ASSERT_TRUE(satellitePvt.flags & SatellitePvt::HAS_POSITION_VELOCITY_CLOCK_INFO || + satellitePvt.flags & SatellitePvt::HAS_IONO || + satellitePvt.flags & SatellitePvt::HAS_TROPO); + if (satellitePvt.flags & SatellitePvt::HAS_POSITION_VELOCITY_CLOCK_INFO) { + ALOGD("Found HAS_POSITION_VELOCITY_CLOCK_INFO"); + ASSERT_TRUE(satellitePvt.satPosEcef.posXMeters >= -kMaxOrbitRadiusMeters && + satellitePvt.satPosEcef.posXMeters <= kMaxOrbitRadiusMeters); + ASSERT_TRUE(satellitePvt.satPosEcef.posYMeters >= -kMaxOrbitRadiusMeters && + satellitePvt.satPosEcef.posYMeters <= kMaxOrbitRadiusMeters); + ASSERT_TRUE(satellitePvt.satPosEcef.posZMeters >= -kMaxOrbitRadiusMeters && + satellitePvt.satPosEcef.posZMeters <= kMaxOrbitRadiusMeters); + ASSERT_TRUE(satellitePvt.satPosEcef.ureMeters > 0); + ASSERT_TRUE(satellitePvt.satVelEcef.velXMps >= -kMaxVelocityMps && + satellitePvt.satVelEcef.velXMps <= kMaxVelocityMps); + ASSERT_TRUE(satellitePvt.satVelEcef.velYMps >= -kMaxVelocityMps && + satellitePvt.satVelEcef.velYMps <= kMaxVelocityMps); + ASSERT_TRUE(satellitePvt.satVelEcef.velZMps >= -kMaxVelocityMps && + satellitePvt.satVelEcef.velZMps <= kMaxVelocityMps); + ASSERT_TRUE(satellitePvt.satVelEcef.ureRateMps > 0); + ASSERT_TRUE( + satellitePvt.satClockInfo.satHardwareCodeBiasMeters > kMinHardwareCodeBiasMeters && + satellitePvt.satClockInfo.satHardwareCodeBiasMeters < kMaxHardwareCodeBiasMeters); + ASSERT_TRUE(satellitePvt.satClockInfo.satTimeCorrectionMeters > + -kMaxTimeCorrelationMeters && + satellitePvt.satClockInfo.satTimeCorrectionMeters < kMaxTimeCorrelationMeters); + ASSERT_TRUE(satellitePvt.satClockInfo.satClkDriftMps > -kMaxSatClkDriftMps && + satellitePvt.satClockInfo.satClkDriftMps < kMaxSatClkDriftMps); + } + if (satellitePvt.flags & SatellitePvt::HAS_IONO) { + ALOGD("Found HAS_IONO"); + ASSERT_TRUE(satellitePvt.ionoDelayMeters > 0 && satellitePvt.ionoDelayMeters < 100); + } + if (satellitePvt.flags & SatellitePvt::HAS_TROPO) { + ALOGD("Found HAS_TROPO"); + ASSERT_TRUE(satellitePvt.tropoDelayMeters > 0 && satellitePvt.tropoDelayMeters < 100); + } +} - android::hardware::gnss::GnssData lastMeasurement; - ASSERT_TRUE(callback->gnss_data_cbq_.retrieve(lastMeasurement, - kFirstGnssMeasurementTimeoutSeconds)); - EXPECT_EQ(callback->gnss_data_cbq_.calledCount(), 1); - ASSERT_TRUE(lastMeasurement.measurements.size() > 0); - - // Validity check GnssData fields - ASSERT_TRUE( - lastMeasurement.elapsedRealtime.flags >= 0 && - lastMeasurement.elapsedRealtime.flags <= - (ElapsedRealtime::HAS_TIMESTAMP_NS | ElapsedRealtime::HAS_TIME_UNCERTAINTY_NS)); - if (lastMeasurement.elapsedRealtime.flags & ElapsedRealtime::HAS_TIMESTAMP_NS) { - ASSERT_TRUE(lastMeasurement.elapsedRealtime.timestampNs > 0); +void CheckGnssMeasurementClockFields(const GnssData& measurement) { + ASSERT_TRUE(measurement.elapsedRealtime.flags >= 0 && + measurement.elapsedRealtime.flags <= (ElapsedRealtime::HAS_TIMESTAMP_NS | + ElapsedRealtime::HAS_TIME_UNCERTAINTY_NS)); + if (measurement.elapsedRealtime.flags & ElapsedRealtime::HAS_TIMESTAMP_NS) { + ASSERT_TRUE(measurement.elapsedRealtime.timestampNs > 0); } - if (lastMeasurement.elapsedRealtime.flags & ElapsedRealtime::HAS_TIME_UNCERTAINTY_NS) { - ASSERT_TRUE(lastMeasurement.elapsedRealtime.timeUncertaintyNs > 0); + if (measurement.elapsedRealtime.flags & ElapsedRealtime::HAS_TIME_UNCERTAINTY_NS) { + ASSERT_TRUE(measurement.elapsedRealtime.timeUncertaintyNs > 0); } - ASSERT_TRUE(lastMeasurement.clock.gnssClockFlags >= 0 && - lastMeasurement.clock.gnssClockFlags <= + ASSERT_TRUE(measurement.clock.gnssClockFlags >= 0 && + measurement.clock.gnssClockFlags <= (GnssClock::HAS_LEAP_SECOND | GnssClock::HAS_TIME_UNCERTAINTY | GnssClock::HAS_FULL_BIAS | GnssClock::HAS_BIAS | GnssClock::HAS_BIAS_UNCERTAINTY | GnssClock::HAS_DRIFT | GnssClock::HAS_DRIFT_UNCERTAINTY)); +} - if (aidl_gnss_cb_->last_capabilities_ & (int)GnssCallbackAidl::CAPABILITY_SATELLITE_PVT) { - has_capability_satpvt = true; - } - for (const auto& measurement : lastMeasurement.measurements) { - ASSERT_TRUE( - measurement.flags >= 0 && +void CheckGnssMeasurementFlags(const GnssMeasurement& measurement) { + ASSERT_TRUE(measurement.flags >= 0 && measurement.flags <= (GnssMeasurement::HAS_SNR | GnssMeasurement::HAS_CARRIER_FREQUENCY | GnssMeasurement::HAS_CARRIER_CYCLES | GnssMeasurement::HAS_CARRIER_PHASE | @@ -128,56 +143,125 @@ TEST_P(GnssHalTest, TestGnssMeasurementExtension) { GnssMeasurement::HAS_SATELLITE_ISB_UNCERTAINTY | GnssMeasurement::HAS_SATELLITE_PVT | GnssMeasurement::HAS_CORRELATION_VECTOR)); +} - if (measurement.flags & GnssMeasurement::HAS_SATELLITE_PVT && - has_capability_satpvt == true) { - if (measurement.satellitePvt.flags & SatellitePvt::HAS_POSITION_VELOCITY_CLOCK_INFO) { - ASSERT_TRUE(measurement.satellitePvt.satPosEcef.posXMeters >= -43000000 && - measurement.satellitePvt.satPosEcef.posXMeters <= 43000000); - ASSERT_TRUE(measurement.satellitePvt.satPosEcef.posYMeters >= -43000000 && - measurement.satellitePvt.satPosEcef.posYMeters <= 43000000); - ASSERT_TRUE(measurement.satellitePvt.satPosEcef.posZMeters >= -43000000 && - measurement.satellitePvt.satPosEcef.posZMeters <= 43000000); - ASSERT_TRUE(measurement.satellitePvt.satPosEcef.ureMeters > 0); - ASSERT_TRUE(measurement.satellitePvt.satVelEcef.velXMps >= -4000 && - measurement.satellitePvt.satVelEcef.velXMps <= 4000); - ASSERT_TRUE(measurement.satellitePvt.satVelEcef.velYMps >= -4000 && - measurement.satellitePvt.satVelEcef.velYMps <= 4000); - ASSERT_TRUE(measurement.satellitePvt.satVelEcef.velZMps >= -4000 && - measurement.satellitePvt.satVelEcef.velZMps <= 4000); - ASSERT_TRUE(measurement.satellitePvt.satVelEcef.ureRateMps > 0); - ASSERT_TRUE( - measurement.satellitePvt.satClockInfo.satHardwareCodeBiasMeters > -17.869 && - measurement.satellitePvt.satClockInfo.satHardwareCodeBiasMeters < 17.729); - ASSERT_TRUE(measurement.satellitePvt.satClockInfo.satTimeCorrectionMeters > -3e6 && - measurement.satellitePvt.satClockInfo.satTimeCorrectionMeters < 3e6); - ASSERT_TRUE(measurement.satellitePvt.satClockInfo.satClkDriftMps > -1.117 && - measurement.satellitePvt.satClockInfo.satClkDriftMps < 1.117); - } - if (measurement.satellitePvt.flags & SatellitePvt::HAS_IONO) { - ASSERT_TRUE(measurement.satellitePvt.ionoDelayMeters > 0 && - measurement.satellitePvt.ionoDelayMeters < 100); - } - if (measurement.satellitePvt.flags & SatellitePvt::HAS_TROPO) { - ASSERT_TRUE(measurement.satellitePvt.tropoDelayMeters > 0 && - measurement.satellitePvt.tropoDelayMeters < 100); +/* + * TestGnssMeasurementExtensionAndSatellitePvt: + * 1. Gets the GnssMeasurementExtension and verifies that it returns a non-null extension. + * 2. Sets a GnssMeasurementCallback, waits for a measurement, and verifies mandatory fields are + * valid. + * 3. If SatellitePvt is supported, waits for a measurement with SatellitePvt, and verifies the + * fields are valid. + */ +TEST_P(GnssHalTest, TestGnssMeasurementExtensionAndSatellitePvt) { + const bool kIsSatellitePvtSupported = + aidl_gnss_cb_->last_capabilities_ & (int)GnssCallbackAidl::CAPABILITY_SATELLITE_PVT; + ALOGD("SatellitePvt supported: %s", kIsSatellitePvtSupported ? "true" : "false"); + const int kFirstGnssMeasurementTimeoutSeconds = 10; + const int kNumMeasurementEvents = 75; + + sp iGnssMeasurement; + auto status = aidl_gnss_hal_->getExtensionGnssMeasurement(&iGnssMeasurement); + ASSERT_TRUE(status.isOk()); + ASSERT_TRUE(iGnssMeasurement != nullptr); + + auto callback = sp::make(); + status = iGnssMeasurement->setCallback(callback, /* enableFullTracking= */ true, + /* enableCorrVecOutputs */ false); + ASSERT_TRUE(status.isOk()); + + bool satellitePvtFound = false; + for (int i = 0; i < kNumMeasurementEvents; i++) { + if (i > 0 && (!kIsSatellitePvtSupported || satellitePvtFound)) { + break; + } + 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); + + for (const auto& measurement : lastMeasurement.measurements) { + CheckGnssMeasurementFlags(measurement); + if (measurement.flags & GnssMeasurement::HAS_SATELLITE_PVT && + kIsSatellitePvtSupported == true) { + ALOGD("Found a measurement with SatellitePvt"); + satellitePvtFound = true; + CheckSatellitePvt(measurement.satellitePvt); } } + } + if (kIsSatellitePvtSupported) { + ASSERT_TRUE(satellitePvtFound); + } - if (kIsCorrelationVectorSupported && - measurement.flags & GnssMeasurement::HAS_CORRELATION_VECTOR) { - ASSERT_TRUE(measurement.correlationVectors.size() > 0); - for (const auto& correlationVector : measurement.correlationVectors) { - ASSERT_GE(correlationVector.frequencyOffsetMps, 0); - ASSERT_GT(correlationVector.samplingWidthM, 0); - ASSERT_GE(correlationVector.samplingStartM, 0); - ASSERT_TRUE(correlationVector.magnitude.size() > 0); - for (const auto& magnitude : correlationVector.magnitude) { - ASSERT_TRUE(magnitude >= -32768 && magnitude <= 32767); + status = iGnssMeasurement->close(); + ASSERT_TRUE(status.isOk()); +} + +/* + * TestCorrelationVector: + * 1. Gets the GnssMeasurementExtension and verifies that it returns a non-null extension. + * 2. Sets a GnssMeasurementCallback, waits for GnssMeasurements with CorrelationVector, and + * verifies fields are valid. + */ +TEST_P(GnssHalTest, TestCorrelationVector) { + const bool kIsCorrelationVectorSupported = aidl_gnss_cb_->last_capabilities_ & + (int)GnssCallbackAidl::CAPABILITY_CORRELATION_VECTOR; + const int kNumMeasurementEvents = 75; + // Pass the test if CorrelationVector is not supported + if (!kIsCorrelationVectorSupported) { + return; + } + + const int kFirstGnssMeasurementTimeoutSeconds = 10; + sp iGnssMeasurement; + auto status = aidl_gnss_hal_->getExtensionGnssMeasurement(&iGnssMeasurement); + ASSERT_TRUE(status.isOk()); + ASSERT_TRUE(iGnssMeasurement != nullptr); + + auto callback = sp::make(); + status = + iGnssMeasurement->setCallback(callback, /* enableFullTracking= */ true, + /* enableCorrVecOutputs */ kIsCorrelationVectorSupported); + ASSERT_TRUE(status.isOk()); + + bool correlationVectorFound = false; + for (int i = 0; i < kNumMeasurementEvents; i++) { + // Pass the test if at least one CorrelationVector has been found. + if (correlationVectorFound) { + break; + } + 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); + + for (const auto& measurement : lastMeasurement.measurements) { + CheckGnssMeasurementFlags(measurement); + if (measurement.flags & GnssMeasurement::HAS_CORRELATION_VECTOR) { + correlationVectorFound = true; + ASSERT_TRUE(measurement.correlationVectors.size() > 0); + for (const auto& correlationVector : measurement.correlationVectors) { + ASSERT_GE(correlationVector.frequencyOffsetMps, 0); + ASSERT_GT(correlationVector.samplingWidthM, 0); + ASSERT_GE(correlationVector.samplingStartM, 0); + ASSERT_TRUE(correlationVector.magnitude.size() > 0); + for (const auto& magnitude : correlationVector.magnitude) { + ASSERT_TRUE(magnitude >= -32768 && magnitude <= 32767); + } } } } } + ASSERT_TRUE(correlationVectorFound); status = iGnssMeasurement->close(); ASSERT_TRUE(status.isOk()); -- GitLab From 13d8406217824aa311c7a3b16133c20807af2457 Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Mon, 7 Jun 2021 16:56:11 -0700 Subject: [PATCH 694/790] Fix VTS test Bug: 187128449 Test: atest VtsHalBiometricsFaceTargetTest Change-Id: I8e77b18a5e79ae905a78e540b4da0b304672b514 --- .../vts/VtsHalBiometricsFaceTargetTest.cpp | 52 ++++++++----------- 1 file changed, 22 insertions(+), 30 deletions(-) diff --git a/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp b/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp index ada6f734ca..47a78139f2 100644 --- a/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp +++ b/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp @@ -32,21 +32,8 @@ using namespace std::literals::chrono_literals; constexpr int kSensorId = 0; constexpr int kUserId = 0; -enum class MethodName { - kOnError, - kOnSessionClosed, -}; - -struct Invocation { - MethodName methodName; - Error error; - int32_t vendorCode; -}; - class SessionCallback : public BnSessionCallback { public: - explicit SessionCallback(Invocation* inv) : mInv(inv) {} - ndk::ScopedAStatus onChallengeGenerated(int64_t /*challenge*/) override { return ndk::ScopedAStatus::ok(); } @@ -64,11 +51,11 @@ class SessionCallback : public BnSessionCallback { } ndk::ScopedAStatus onError(Error error, int32_t vendorCode) override { - *mInv = {}; - mInv->methodName = MethodName::kOnError; - mInv->error = error; - mInv->vendorCode = vendorCode; - + auto lock = std::lock_guard{mMutex}; + mError = error; + mVendorCode = vendorCode; + mOnErrorInvoked = true; + mCv.notify_one(); return ndk::ScopedAStatus::ok(); } @@ -121,14 +108,18 @@ class SessionCallback : public BnSessionCallback { } ndk::ScopedAStatus onSessionClosed() override { - *mInv = {}; - mInv->methodName = MethodName::kOnSessionClosed; - + auto lock = std::lock_guard{mMutex}; + mOnSessionClosedInvoked = true; + mCv.notify_one(); return ndk::ScopedAStatus::ok(); } - private: - Invocation* mInv; + std::mutex mMutex; + std::condition_variable mCv; + Error mError = Error::UNKNOWN; + int32_t mVendorCode = 0; + bool mOnErrorInvoked = false; + bool mOnSessionClosedInvoked = false; }; class Face : public testing::TestWithParam { @@ -140,12 +131,11 @@ class Face : public testing::TestWithParam { } std::shared_ptr mHal; - Invocation mInv; }; TEST_P(Face, AuthenticateTest) { // Prepare the callback. - auto cb = ndk::SharedRefBase::make(&mInv); + auto cb = ndk::SharedRefBase::make(); // Create a session std::shared_ptr session; @@ -155,15 +145,18 @@ TEST_P(Face, AuthenticateTest) { std::shared_ptr cancellationSignal; ASSERT_TRUE(session->authenticate(0 /* operationId */, &cancellationSignal).isOk()); + auto lock = std::unique_lock(cb->mMutex); + cb->mCv.wait(lock, [&cb] { return cb->mOnErrorInvoked; }); // Get the results - EXPECT_EQ(mInv.methodName, MethodName::kOnError); - EXPECT_EQ(mInv.error, Error::UNABLE_TO_PROCESS); - EXPECT_EQ(mInv.vendorCode, 0); + EXPECT_EQ(cb->mError, Error::UNABLE_TO_PROCESS); + EXPECT_EQ(cb->mVendorCode, 0); + lock.unlock(); // Close the session ASSERT_TRUE(session->close().isOk()); - EXPECT_EQ(mInv.methodName, MethodName::kOnSessionClosed); + lock.lock(); + cb->mCv.wait(lock, [&cb] { return cb->mOnSessionClosedInvoked; }); } GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Face); @@ -180,4 +173,3 @@ int main(int argc, char** argv) { ABinderProcess_startThreadPool(); return RUN_ALL_TESTS(); } - -- GitLab From e41878b480b2f35eec388efa391bfb509c1f16a8 Mon Sep 17 00:00:00 2001 From: Kai Date: Mon, 7 Jun 2021 20:57:42 -0700 Subject: [PATCH 695/790] Freeze Vehicle HAL interface Freeze vehicle hal interface for android s. Bug: 157608908 Test: atest vts_treble_vintf_vendor_test Change-Id: I092f7c7facbb08f381560840c449ae1211625c65 --- current.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/current.txt b/current.txt index 3102972081..9bc2713f11 100644 --- a/current.txt +++ b/current.txt @@ -825,6 +825,9 @@ a7d74d7e7e0b1e3b739f233b7776bf01e868856a536f5cdac0f307e9c2850e64 android.hardwar b4cbc1f2d38787f2ad069a8e4d10c0896287531a2596f0de0283e390b0ecf05d android.hardware.audio.effect@7.0::IVirtualizerEffect 2b5681e1ea6a2db0dc1e84edb96d3de2f7daf306046543e7956be76dcb8f20fb android.hardware.audio.effect@7.0::IVisualizerEffect fa1e2d78e66fd662de93cb479ffd55947fe54f51cb53915814b3d3e3036c86a5 android.hardware.audio.effect@7.0::types +e3865e74cb1a6e6afd38c7aa84115cb109ce47b972132de5242bc3838d2771f6 android.hardware.automotive.vehicle@2.0::types +b3caf524c46a47d67e6453a34419e1881942d059e146cda740502670e9a752c3 android.hardware.automotive.vehicle@2.0::IVehicle +7ce8728b27600e840cacf0a832f6942819fe535f9d3797ae052d5eef5065921c android.hardware.automotive.vehicle@2.0::IVehicleCallback b525e91d886379c13588f4975bb04d625d46e1f41b4453792c4b2db1e7ff4340 android.hardware.biometrics.fingerprint@2.3::IBiometricsFingerprint 4baf8e0eca4aa896cc9ceb7bb676aaf4fa21372ef8b49eed68eced1221c3dc0d android.hardware.bluetooth.audio@2.1::IBluetoothAudioProvider d417a9212c8f96e3a06a2f221c8c5756c765355b2b81de2b2a65d4c9eee85401 android.hardware.bluetooth.audio@2.1::IBluetoothAudioProvidersFactory -- GitLab From eaab0f281603e674ae393876227e020c47e0b9ea Mon Sep 17 00:00:00 2001 From: David Drysdale Date: Thu, 27 May 2021 12:00:53 +0100 Subject: [PATCH 696/790] KeyMint VTS: better early boot key tests Add a check that the TAG_EARLY_BOOT_ONLY is included in the returned key characteristics. Bug: 188672564 Test: VtsAidlKeyMintTargetTest Merged-In: I200c61f34888c720c47f6289d79cd21d78436b58 Change-Id: I200c61f34888c720c47f6289d79cd21d78436b58 Ignore-AOSP-First: already merged in aosp/master --- .../aidl/vts/functional/KeyMintAidlTestBase.h | 69 +++++++++++-------- .../aidl/vts/functional/KeyMintTest.cpp | 30 +++++++- 2 files changed, 68 insertions(+), 31 deletions(-) diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h index c49b303f50..4d31fa4d36 100644 --- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h +++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h @@ -16,6 +16,7 @@ #pragma once +#include #include #include @@ -206,50 +207,58 @@ class KeyMintAidlTestBase : public ::testing::TestWithParam { template std::tuple - CreateTestKeys(TagType tagToTest, ErrorCode expectedReturn) { + CreateTestKeys( + TagType tagToTest, ErrorCode expectedReturn, + std::function tagModifier = + [](AuthorizationSetBuilder*) {}) { /* AES */ KeyData aesKeyData; - ErrorCode errorCode = GenerateKey(AuthorizationSetBuilder() - .AesEncryptionKey(128) - .Authorization(tagToTest) - .BlockMode(BlockMode::ECB) - .Padding(PaddingMode::NONE) - .Authorization(TAG_NO_AUTH_REQUIRED), - &aesKeyData.blob, &aesKeyData.characteristics); + AuthorizationSetBuilder aesBuilder = AuthorizationSetBuilder() + .AesEncryptionKey(128) + .Authorization(tagToTest) + .BlockMode(BlockMode::ECB) + .Padding(PaddingMode::NONE) + .Authorization(TAG_NO_AUTH_REQUIRED); + tagModifier(&aesBuilder); + ErrorCode errorCode = + GenerateKey(aesBuilder, &aesKeyData.blob, &aesKeyData.characteristics); EXPECT_EQ(expectedReturn, errorCode); /* HMAC */ KeyData hmacKeyData; - errorCode = GenerateKey(AuthorizationSetBuilder() - .HmacKey(128) - .Authorization(tagToTest) - .Digest(Digest::SHA_2_256) - .Authorization(TAG_MIN_MAC_LENGTH, 128) - .Authorization(TAG_NO_AUTH_REQUIRED), - &hmacKeyData.blob, &hmacKeyData.characteristics); + AuthorizationSetBuilder hmacBuilder = AuthorizationSetBuilder() + .HmacKey(128) + .Authorization(tagToTest) + .Digest(Digest::SHA_2_256) + .Authorization(TAG_MIN_MAC_LENGTH, 128) + .Authorization(TAG_NO_AUTH_REQUIRED); + tagModifier(&hmacBuilder); + errorCode = GenerateKey(hmacBuilder, &hmacKeyData.blob, &hmacKeyData.characteristics); EXPECT_EQ(expectedReturn, errorCode); /* RSA */ KeyData rsaKeyData; - errorCode = GenerateKey(AuthorizationSetBuilder() - .RsaSigningKey(2048, 65537) - .Authorization(tagToTest) - .Digest(Digest::NONE) - .Padding(PaddingMode::NONE) - .Authorization(TAG_NO_AUTH_REQUIRED) - .SetDefaultValidity(), - &rsaKeyData.blob, &rsaKeyData.characteristics); + AuthorizationSetBuilder rsaBuilder = AuthorizationSetBuilder() + .RsaSigningKey(2048, 65537) + .Authorization(tagToTest) + .Digest(Digest::NONE) + .Padding(PaddingMode::NONE) + .Authorization(TAG_NO_AUTH_REQUIRED) + .SetDefaultValidity(); + tagModifier(&rsaBuilder); + errorCode = GenerateKey(rsaBuilder, &rsaKeyData.blob, &rsaKeyData.characteristics); EXPECT_EQ(expectedReturn, errorCode); /* ECDSA */ KeyData ecdsaKeyData; - errorCode = GenerateKey(AuthorizationSetBuilder() - .EcdsaSigningKey(256) - .Authorization(tagToTest) - .Digest(Digest::SHA_2_256) - .Authorization(TAG_NO_AUTH_REQUIRED) - .SetDefaultValidity(), - &ecdsaKeyData.blob, &ecdsaKeyData.characteristics); + AuthorizationSetBuilder ecdsaBuilder = AuthorizationSetBuilder() + .EcdsaSigningKey(256) + .Authorization(tagToTest) + .Digest(Digest::SHA_2_256) + .Authorization(TAG_NO_AUTH_REQUIRED) + .SetDefaultValidity(); + tagModifier(&ecdsaBuilder); + errorCode = GenerateKey(ecdsaBuilder, &ecdsaKeyData.blob, &ecdsaKeyData.characteristics); EXPECT_EQ(expectedReturn, errorCode); return {aesKeyData, hmacKeyData, rsaKeyData, ecdsaKeyData}; } diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp index 5dcfcaaa63..295be1a48d 100644 --- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp +++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp @@ -6355,6 +6355,34 @@ TEST_P(EarlyBootKeyTest, CreateEarlyBootKeys) { auto [aesKeyData, hmacKeyData, rsaKeyData, ecdsaKeyData] = CreateTestKeys(TAG_EARLY_BOOT_ONLY, ErrorCode::OK); + for (const auto& keyData : {aesKeyData, hmacKeyData, rsaKeyData, ecdsaKeyData}) { + ASSERT_GT(keyData.blob.size(), 0U); + AuthorizationSet crypto_params = SecLevelAuthorizations(keyData.characteristics); + EXPECT_TRUE(crypto_params.Contains(TAG_EARLY_BOOT_ONLY)) << crypto_params; + } + CheckedDeleteKey(&aesKeyData.blob); + CheckedDeleteKey(&hmacKeyData.blob); + CheckedDeleteKey(&rsaKeyData.blob); + CheckedDeleteKey(&ecdsaKeyData.blob); +} + +/* + * EarlyBootKeyTest.CreateAttestedEarlyBootKey + * + * Verifies that creating an early boot key with attestation succeeds. + */ +TEST_P(EarlyBootKeyTest, CreateAttestedEarlyBootKey) { + auto [aesKeyData, hmacKeyData, rsaKeyData, ecdsaKeyData] = CreateTestKeys( + TAG_EARLY_BOOT_ONLY, ErrorCode::OK, [](AuthorizationSetBuilder* builder) { + builder->AttestationChallenge("challenge"); + builder->AttestationApplicationId("app_id"); + }); + + for (const auto& keyData : {aesKeyData, hmacKeyData, rsaKeyData, ecdsaKeyData}) { + ASSERT_GT(keyData.blob.size(), 0U); + AuthorizationSet crypto_params = SecLevelAuthorizations(keyData.characteristics); + EXPECT_TRUE(crypto_params.Contains(TAG_EARLY_BOOT_ONLY)) << crypto_params; + } CheckedDeleteKey(&aesKeyData.blob); CheckedDeleteKey(&hmacKeyData.blob); CheckedDeleteKey(&rsaKeyData.blob); @@ -6362,7 +6390,7 @@ TEST_P(EarlyBootKeyTest, CreateEarlyBootKeys) { } /* - * EarlyBootKeyTest.UsetEarlyBootKeyFailure + * EarlyBootKeyTest.UseEarlyBootKeyFailure * * Verifies that using early boot keys at a later stage fails. */ -- GitLab From a2d1520283087e2cff2171994749c1e5356e5614 Mon Sep 17 00:00:00 2001 From: Yu-Han Yang Date: Tue, 8 Jun 2021 15:21:13 -0700 Subject: [PATCH 697/790] Check PowerIndication capabilities Bug: 190458839 Test: on device Change-Id: I8ca33778c687a433b1194d55099c844f696093c2 --- gnss/aidl/vts/gnss_hal_test_cases.cpp | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/gnss/aidl/vts/gnss_hal_test_cases.cpp b/gnss/aidl/vts/gnss_hal_test_cases.cpp index 9d8562d9da..5964f815a8 100644 --- a/gnss/aidl/vts/gnss_hal_test_cases.cpp +++ b/gnss/aidl/vts/gnss_hal_test_cases.cpp @@ -311,27 +311,42 @@ TEST_P(GnssHalTest, TestGnssPowerIndication) { EXPECT_TRUE(gnssPowerIndicationCallback->gnss_power_stats_cbq_.retrieve( gnssPowerIndicationCallback->last_gnss_power_stats_, kTimeoutSec)); EXPECT_EQ(gnssPowerIndicationCallback->gnss_power_stats_cbq_.calledCount(), 2); + auto powerStats2 = gnssPowerIndicationCallback->last_gnss_power_stats_; - // Elapsed realtime must increase - EXPECT_GT(powerStats2.elapsedRealtime.timestampNs, powerStats1.elapsedRealtime.timestampNs); + if ((gnssPowerIndicationCallback->last_capabilities_ & + (int)GnssPowerIndicationCallback::CAPABILITY_TOTAL)) { + // Elapsed realtime must increase + EXPECT_GT(powerStats2.elapsedRealtime.timestampNs, powerStats1.elapsedRealtime.timestampNs); - // Total energy must increase - EXPECT_GT(powerStats2.totalEnergyMilliJoule, powerStats1.totalEnergyMilliJoule); + // Total energy must increase + EXPECT_GT(powerStats2.totalEnergyMilliJoule, powerStats1.totalEnergyMilliJoule); + } // At least oone of singleband and multiband acquisition energy must increase bool singlebandAcqEnergyIncreased = powerStats2.singlebandAcquisitionModeEnergyMilliJoule > powerStats1.singlebandAcquisitionModeEnergyMilliJoule; bool multibandAcqEnergyIncreased = powerStats2.multibandAcquisitionModeEnergyMilliJoule > powerStats1.multibandAcquisitionModeEnergyMilliJoule; - EXPECT_TRUE(singlebandAcqEnergyIncreased || multibandAcqEnergyIncreased); + + if ((gnssPowerIndicationCallback->last_capabilities_ & + (int)GnssPowerIndicationCallback::CAPABILITY_SINGLEBAND_ACQUISITION) || + (gnssPowerIndicationCallback->last_capabilities_ & + (int)GnssPowerIndicationCallback::CAPABILITY_MULTIBAND_ACQUISITION)) { + EXPECT_TRUE(singlebandAcqEnergyIncreased || multibandAcqEnergyIncreased); + } // At least one of singleband and multiband tracking energy must increase bool singlebandTrackingEnergyIncreased = powerStats2.singlebandTrackingModeEnergyMilliJoule > powerStats1.singlebandTrackingModeEnergyMilliJoule; bool multibandTrackingEnergyIncreased = powerStats2.multibandTrackingModeEnergyMilliJoule > powerStats1.multibandTrackingModeEnergyMilliJoule; - EXPECT_TRUE(singlebandTrackingEnergyIncreased || multibandTrackingEnergyIncreased); + if ((gnssPowerIndicationCallback->last_capabilities_ & + (int)GnssPowerIndicationCallback::CAPABILITY_SINGLEBAND_TRACKING) || + (gnssPowerIndicationCallback->last_capabilities_ & + (int)GnssPowerIndicationCallback::CAPABILITY_MULTIBAND_TRACKING)) { + EXPECT_TRUE(singlebandTrackingEnergyIncreased || multibandTrackingEnergyIncreased); + } // Clean up StopAndClearLocations(); -- GitLab From 9ba9f5e2f2d8729581f466ccc26b3bbe5eda8f06 Mon Sep 17 00:00:00 2001 From: Kai Date: Tue, 8 Jun 2021 16:06:24 -0700 Subject: [PATCH 698/790] Fix VHAL VTS issue on GSI image Bug: 183961835 Test: atest VtsHalAutomotiveVehicleV2_0TargetTest Change-Id: I78b4e38e7462cb8cc69ca999f0da64a1e396df90 --- .../2.0/vts/functional/VtsHalAutomotiveVehicleV2_0TargetTest.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/automotive/vehicle/2.0/vts/functional/VtsHalAutomotiveVehicleV2_0TargetTest.cpp b/automotive/vehicle/2.0/vts/functional/VtsHalAutomotiveVehicleV2_0TargetTest.cpp index 7f1d4d10b6..4ac0aa565e 100644 --- a/automotive/vehicle/2.0/vts/functional/VtsHalAutomotiveVehicleV2_0TargetTest.cpp +++ b/automotive/vehicle/2.0/vts/functional/VtsHalAutomotiveVehicleV2_0TargetTest.cpp @@ -241,6 +241,7 @@ TEST_P(VehicleHalHidlTest, subscribeInvalidProp) { ASSERT_NE(StatusCode::OK, mVehicle->subscribe(cb, options)); } +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VehicleHalHidlTest); INSTANTIATE_TEST_SUITE_P( PerInstance, VehicleHalHidlTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames(IVehicle::descriptor)), -- GitLab From 8bd3c2f00fb13c82e8fef3f29398319064aa4183 Mon Sep 17 00:00:00 2001 From: Ady Abraham Date: Tue, 8 Jun 2021 17:03:20 -0700 Subject: [PATCH 699/790] composer: 2.4: vts: do not try to delay a config change outside a group When switching to a new config, we can set the desiredTimeNanos to be in the future only for configs within the same config groups. Bug: 190250110 Test: atest VtsHalGraphicsComposerV2_4TargetTest Change-Id: I5e292b656eccf6e90c06e08c6eb202d689b6f026 --- .../VtsHalGraphicsComposerV2_4TargetTest.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp b/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp index 7d0a83b788..2f0429c01c 100644 --- a/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp +++ b/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp @@ -561,17 +561,28 @@ void GraphicsComposerHidlTest::Test_setActiveConfigWithConstraints(const TestPar setActiveConfig(display, config1); sendRefreshFrame(display, nullptr); - int32_t vsyncPeriod1 = mComposerClient->getDisplayAttribute_2_4( + const auto vsyncPeriod1 = mComposerClient->getDisplayAttribute_2_4( display.get(), config1, IComposerClient::IComposerClient::Attribute::VSYNC_PERIOD); - int32_t vsyncPeriod2 = mComposerClient->getDisplayAttribute_2_4( + const auto configGroup1 = mComposerClient->getDisplayAttribute_2_4( + display.get(), config1, + IComposerClient::IComposerClient::Attribute::CONFIG_GROUP); + const auto vsyncPeriod2 = mComposerClient->getDisplayAttribute_2_4( display.get(), config2, IComposerClient::IComposerClient::Attribute::VSYNC_PERIOD); + const auto configGroup2 = mComposerClient->getDisplayAttribute_2_4( + display.get(), config2, + IComposerClient::IComposerClient::Attribute::CONFIG_GROUP); if (vsyncPeriod1 == vsyncPeriod2) { return; // continue } + // We don't allow delayed change when changing config groups + if (params.delayForChange > 0 && configGroup1 != configGroup2) { + return; // continue + } + VsyncPeriodChangeTimeline timeline; IComposerClient::VsyncPeriodChangeConstraints constraints = { .desiredTimeNanos = systemTime() + params.delayForChange, -- GitLab From fd5b1a6da8fff485a566396af3621d1e755748ec Mon Sep 17 00:00:00 2001 From: David Drysdale Date: Wed, 26 May 2021 14:45:31 +0100 Subject: [PATCH 700/790] KeyMint: sync all attestation tags Get description of ASN.1 schema in HAL and the keymint support library in sync with each other. Change code to always list tags in the same order (by numeric tag). Bug: 188672564 Bug: 186735514 Test: VtsAidlKeyMintTargetTest Merged-In: I620f54ba4a265ea69d174f6f44765a8508bfe803 Change-Id: I620f54ba4a265ea69d174f6f44765a8508bfe803 Ignore-AOSP-First: already merged into aosp/master --- .../security/keymint/KeyCreationResult.aidl | 8 +- .../keymint/support/attestation_record.cpp | 105 ++++++++++++------ 2 files changed, 74 insertions(+), 39 deletions(-) diff --git a/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl b/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl index f93dbba408..fd6bf65230 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl @@ -159,18 +159,17 @@ parcelable KeyCreationResult { * purpose [1] EXPLICIT SET OF INTEGER OPTIONAL, * algorithm [2] EXPLICIT INTEGER OPTIONAL, * keySize [3] EXPLICIT INTEGER OPTIONAL, - * blockMode [4] EXPLICIT SET OF INTEGER OPTIONAL, * digest [5] EXPLICIT SET OF INTEGER OPTIONAL, * padding [6] EXPLICIT SET OF INTEGER OPTIONAL, - * callerNonce [7] EXPLICIT NULL OPTIONAL, - * minMacLength [8] EXPLICIT INTEGER OPTIONAL, * ecCurve [10] EXPLICIT INTEGER OPTIONAL, * rsaPublicExponent [200] EXPLICIT INTEGER OPTIONAL, + * mgfDigest [203] EXPLICIT SET OF INTEGER OPTIONAL, * rollbackResistance [303] EXPLICIT NULL OPTIONAL, + * earlyBootOnly [305] EXPLICIT NULL OPTIONAL, * activeDateTime [400] EXPLICIT INTEGER OPTIONAL, * originationExpireDateTime [401] EXPLICIT INTEGER OPTIONAL, * usageExpireDateTime [402] EXPLICIT INTEGER OPTIONAL, - * userSecureId [502] EXPLICIT INTEGER OPTIONAL, + * usageCountLimit [405] EXPLICIT INTEGER OPTIONAL, * noAuthRequired [503] EXPLICIT NULL OPTIONAL, * userAuthType [504] EXPLICIT INTEGER OPTIONAL, * authTimeout [505] EXPLICIT INTEGER OPTIONAL, @@ -194,6 +193,7 @@ parcelable KeyCreationResult { * attestationIdModel [717] EXPLICIT OCTET_STRING OPTIONAL, * vendorPatchLevel [718] EXPLICIT INTEGER OPTIONAL, * bootPatchLevel [719] EXPLICIT INTEGER OPTIONAL, + * deviceUniqueAttestation [720] EXPLICIT NULL OPTIONAL, * } */ Certificate[] certificateChain; diff --git a/security/keymint/support/attestation_record.cpp b/security/keymint/support/attestation_record.cpp index a48f770700..2462228a6e 100644 --- a/security/keymint/support/attestation_record.cpp +++ b/security/keymint/support/attestation_record.cpp @@ -64,6 +64,7 @@ ASN1_SEQUENCE(KM_ROOT_OF_TRUST) = { } ASN1_SEQUENCE_END(KM_ROOT_OF_TRUST); IMPLEMENT_ASN1_FUNCTIONS(KM_ROOT_OF_TRUST); +// Fields ordered in tag order. typedef struct km_auth_list { ASN1_INTEGER_SET* purpose; ASN1_INTEGER* algorithm; @@ -72,32 +73,38 @@ typedef struct km_auth_list { ASN1_INTEGER_SET* padding; ASN1_INTEGER* ec_curve; ASN1_INTEGER* rsa_public_exponent; + ASN1_INTEGER_SET* mgf_digest; + ASN1_NULL* rollback_resistance; + ASN1_NULL* early_boot_only; ASN1_INTEGER* active_date_time; ASN1_INTEGER* origination_expire_date_time; ASN1_INTEGER* usage_expire_date_time; + ASN1_INTEGER* usage_count_limit; ASN1_NULL* no_auth_required; ASN1_INTEGER* user_auth_type; ASN1_INTEGER* auth_timeout; ASN1_NULL* allow_while_on_body; - ASN1_NULL* all_applications; - ASN1_OCTET_STRING* application_id; + ASN1_NULL* trusted_user_presence_required; + ASN1_NULL* trusted_confirmation_required; + ASN1_NULL* unlocked_device_required; ASN1_INTEGER* creation_date_time; ASN1_INTEGER* origin; - ASN1_NULL* rollback_resistance; KM_ROOT_OF_TRUST* root_of_trust; ASN1_INTEGER* os_version; ASN1_INTEGER* os_patchlevel; ASN1_OCTET_STRING* attestation_application_id; - ASN1_NULL* trusted_user_presence_required; - ASN1_NULL* trusted_confirmation_required; - ASN1_NULL* unlocked_device_required; + ASN1_OCTET_STRING* attestation_id_brand; + ASN1_OCTET_STRING* attestation_id_device; + ASN1_OCTET_STRING* attestation_id_product; + ASN1_OCTET_STRING* attestation_id_serial; + ASN1_OCTET_STRING* attestation_id_imei; + ASN1_OCTET_STRING* attestation_id_meid; + ASN1_OCTET_STRING* attestation_id_manufacturer; + ASN1_OCTET_STRING* attestation_id_model; ASN1_INTEGER* vendor_patchlevel; ASN1_INTEGER* boot_patchlevel; - ASN1_NULL* early_boot_only; ASN1_NULL* device_unique_attestation; - ASN1_NULL* storage_key; ASN1_NULL* identity_credential; - ASN1_INTEGER* usage_count_limit; } KM_AUTH_LIST; ASN1_SEQUENCE(KM_AUTH_LIST) = { @@ -109,13 +116,18 @@ ASN1_SEQUENCE(KM_AUTH_LIST) = { ASN1_EXP_OPT(KM_AUTH_LIST, ec_curve, ASN1_INTEGER, TAG_EC_CURVE.maskedTag()), ASN1_EXP_OPT(KM_AUTH_LIST, rsa_public_exponent, ASN1_INTEGER, TAG_RSA_PUBLIC_EXPONENT.maskedTag()), + ASN1_EXP_SET_OF_OPT(KM_AUTH_LIST, mgf_digest, ASN1_INTEGER, + TAG_RSA_OAEP_MGF_DIGEST.maskedTag()), ASN1_EXP_OPT(KM_AUTH_LIST, rollback_resistance, ASN1_NULL, TAG_ROLLBACK_RESISTANCE.maskedTag()), + ASN1_EXP_OPT(KM_AUTH_LIST, early_boot_only, ASN1_NULL, TAG_EARLY_BOOT_ONLY.maskedTag()), ASN1_EXP_OPT(KM_AUTH_LIST, active_date_time, ASN1_INTEGER, TAG_ACTIVE_DATETIME.maskedTag()), ASN1_EXP_OPT(KM_AUTH_LIST, origination_expire_date_time, ASN1_INTEGER, TAG_ORIGINATION_EXPIRE_DATETIME.maskedTag()), ASN1_EXP_OPT(KM_AUTH_LIST, usage_expire_date_time, ASN1_INTEGER, TAG_USAGE_EXPIRE_DATETIME.maskedTag()), + ASN1_EXP_OPT(KM_AUTH_LIST, usage_count_limit, ASN1_INTEGER, + TAG_USAGE_COUNT_LIMIT.maskedTag()), ASN1_EXP_OPT(KM_AUTH_LIST, no_auth_required, ASN1_NULL, TAG_NO_AUTH_REQUIRED.maskedTag()), ASN1_EXP_OPT(KM_AUTH_LIST, user_auth_type, ASN1_INTEGER, TAG_USER_AUTH_TYPE.maskedTag()), ASN1_EXP_OPT(KM_AUTH_LIST, auth_timeout, ASN1_INTEGER, TAG_AUTH_TIMEOUT.maskedTag()), @@ -133,19 +145,31 @@ ASN1_SEQUENCE(KM_AUTH_LIST) = { ASN1_EXP_OPT(KM_AUTH_LIST, root_of_trust, KM_ROOT_OF_TRUST, TAG_ROOT_OF_TRUST.maskedTag()), ASN1_EXP_OPT(KM_AUTH_LIST, os_version, ASN1_INTEGER, TAG_OS_VERSION.maskedTag()), ASN1_EXP_OPT(KM_AUTH_LIST, os_patchlevel, ASN1_INTEGER, TAG_OS_PATCHLEVEL.maskedTag()), + ASN1_EXP_OPT(KM_AUTH_LIST, attestation_application_id, ASN1_OCTET_STRING, + TAG_ATTESTATION_APPLICATION_ID.maskedTag()), + ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_brand, ASN1_OCTET_STRING, + TAG_ATTESTATION_ID_BRAND.maskedTag()), + ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_device, ASN1_OCTET_STRING, + TAG_ATTESTATION_ID_DEVICE.maskedTag()), + ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_product, ASN1_OCTET_STRING, + TAG_ATTESTATION_ID_PRODUCT.maskedTag()), + ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_serial, ASN1_OCTET_STRING, + TAG_ATTESTATION_ID_SERIAL.maskedTag()), + ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_imei, ASN1_OCTET_STRING, + TAG_ATTESTATION_ID_IMEI.maskedTag()), + ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_meid, ASN1_OCTET_STRING, + TAG_ATTESTATION_ID_MEID.maskedTag()), + ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_manufacturer, ASN1_OCTET_STRING, + TAG_ATTESTATION_ID_MANUFACTURER.maskedTag()), + ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_model, ASN1_OCTET_STRING, + TAG_ATTESTATION_ID_MODEL.maskedTag()), ASN1_EXP_OPT(KM_AUTH_LIST, vendor_patchlevel, ASN1_INTEGER, TAG_VENDOR_PATCHLEVEL.maskedTag()), ASN1_EXP_OPT(KM_AUTH_LIST, boot_patchlevel, ASN1_INTEGER, TAG_BOOT_PATCHLEVEL.maskedTag()), - ASN1_EXP_OPT(KM_AUTH_LIST, attestation_application_id, ASN1_OCTET_STRING, - TAG_ATTESTATION_APPLICATION_ID.maskedTag()), - ASN1_EXP_OPT(KM_AUTH_LIST, early_boot_only, ASN1_NULL, TAG_EARLY_BOOT_ONLY.maskedTag()), ASN1_EXP_OPT(KM_AUTH_LIST, device_unique_attestation, ASN1_NULL, TAG_DEVICE_UNIQUE_ATTESTATION.maskedTag()), - ASN1_EXP_OPT(KM_AUTH_LIST, storage_key, ASN1_NULL, TAG_STORAGE_KEY.maskedTag()), ASN1_EXP_OPT(KM_AUTH_LIST, identity_credential, ASN1_NULL, TAG_IDENTITY_CREDENTIAL_KEY.maskedTag()), - ASN1_EXP_OPT(KM_AUTH_LIST, usage_count_limit, ASN1_INTEGER, - TAG_USAGE_COUNT_LIMIT.maskedTag()), } ASN1_SEQUENCE_END(KM_AUTH_LIST); IMPLEMENT_ASN1_FUNCTIONS(KM_AUTH_LIST); @@ -155,9 +179,9 @@ typedef struct km_key_description { ASN1_INTEGER* keymint_version; ASN1_ENUMERATED* keymint_security_level; ASN1_OCTET_STRING* attestation_challenge; + ASN1_INTEGER* unique_id; KM_AUTH_LIST* software_enforced; KM_AUTH_LIST* tee_enforced; - ASN1_INTEGER* unique_id; } KM_KEY_DESCRIPTION; ASN1_SEQUENCE(KM_KEY_DESCRIPTION) = { @@ -253,41 +277,52 @@ void copyAuthTag(const ASN1_OCTET_STRING* asn1_string, TypedTagactive_date_time, TAG_ACTIVE_DATETIME, auth_list); + // Fields ordered in tag order. + copyAuthTag(record->purpose, TAG_PURPOSE, auth_list); copyAuthTag(record->algorithm, TAG_ALGORITHM, auth_list); - copyAuthTag(record->application_id, TAG_APPLICATION_ID, auth_list); - copyAuthTag(record->auth_timeout, TAG_AUTH_TIMEOUT, auth_list); - copyAuthTag(record->creation_date_time, TAG_CREATION_DATETIME, auth_list); - copyAuthTag(record->digest, TAG_DIGEST, auth_list); - copyAuthTag(record->ec_curve, TAG_EC_CURVE, auth_list); copyAuthTag(record->key_size, TAG_KEY_SIZE, auth_list); - copyAuthTag(record->no_auth_required, TAG_NO_AUTH_REQUIRED, auth_list); - copyAuthTag(record->origin, TAG_ORIGIN, auth_list); - copyAuthTag(record->origination_expire_date_time, TAG_ORIGINATION_EXPIRE_DATETIME, auth_list); - copyAuthTag(record->os_patchlevel, TAG_OS_PATCHLEVEL, auth_list); - copyAuthTag(record->os_version, TAG_OS_VERSION, auth_list); + copyAuthTag(record->digest, TAG_DIGEST, auth_list); copyAuthTag(record->padding, TAG_PADDING, auth_list); - copyAuthTag(record->purpose, TAG_PURPOSE, auth_list); - copyAuthTag(record->rollback_resistance, TAG_ROLLBACK_RESISTANCE, auth_list); + copyAuthTag(record->ec_curve, TAG_EC_CURVE, auth_list); copyAuthTag(record->rsa_public_exponent, TAG_RSA_PUBLIC_EXPONENT, auth_list); + copyAuthTag(record->mgf_digest, TAG_RSA_OAEP_MGF_DIGEST, auth_list); + copyAuthTag(record->rollback_resistance, TAG_ROLLBACK_RESISTANCE, auth_list); + copyAuthTag(record->early_boot_only, TAG_EARLY_BOOT_ONLY, auth_list); + copyAuthTag(record->active_date_time, TAG_ACTIVE_DATETIME, auth_list); + copyAuthTag(record->origination_expire_date_time, TAG_ORIGINATION_EXPIRE_DATETIME, auth_list); copyAuthTag(record->usage_expire_date_time, TAG_USAGE_EXPIRE_DATETIME, auth_list); + copyAuthTag(record->usage_count_limit, TAG_USAGE_COUNT_LIMIT, auth_list); + copyAuthTag(record->no_auth_required, TAG_NO_AUTH_REQUIRED, auth_list); copyAuthTag(record->user_auth_type, TAG_USER_AUTH_TYPE, auth_list); - copyAuthTag(record->attestation_application_id, TAG_ATTESTATION_APPLICATION_ID, auth_list); - copyAuthTag(record->vendor_patchlevel, TAG_VENDOR_PATCHLEVEL, auth_list); - copyAuthTag(record->boot_patchlevel, TAG_BOOT_PATCHLEVEL, auth_list); + copyAuthTag(record->auth_timeout, TAG_AUTH_TIMEOUT, auth_list); + copyAuthTag(record->allow_while_on_body, TAG_ALLOW_WHILE_ON_BODY, auth_list); copyAuthTag(record->trusted_user_presence_required, TAG_TRUSTED_USER_PRESENCE_REQUIRED, auth_list); copyAuthTag(record->trusted_confirmation_required, TAG_TRUSTED_CONFIRMATION_REQUIRED, auth_list); copyAuthTag(record->unlocked_device_required, TAG_UNLOCKED_DEVICE_REQUIRED, auth_list); - copyAuthTag(record->early_boot_only, TAG_EARLY_BOOT_ONLY, auth_list); + copyAuthTag(record->creation_date_time, TAG_CREATION_DATETIME, auth_list); + copyAuthTag(record->origin, TAG_ORIGIN, auth_list); + // root_of_trust dealt with separately + copyAuthTag(record->os_version, TAG_OS_VERSION, auth_list); + copyAuthTag(record->os_patchlevel, TAG_OS_PATCHLEVEL, auth_list); + copyAuthTag(record->attestation_application_id, TAG_ATTESTATION_APPLICATION_ID, auth_list); + copyAuthTag(record->attestation_id_brand, TAG_ATTESTATION_ID_BRAND, auth_list); + copyAuthTag(record->attestation_id_device, TAG_ATTESTATION_ID_DEVICE, auth_list); + copyAuthTag(record->attestation_id_product, TAG_ATTESTATION_ID_PRODUCT, auth_list); + copyAuthTag(record->attestation_id_serial, TAG_ATTESTATION_ID_SERIAL, auth_list); + copyAuthTag(record->attestation_id_imei, TAG_ATTESTATION_ID_IMEI, auth_list); + copyAuthTag(record->attestation_id_meid, TAG_ATTESTATION_ID_MEID, auth_list); + copyAuthTag(record->attestation_id_manufacturer, TAG_ATTESTATION_ID_MANUFACTURER, auth_list); + copyAuthTag(record->attestation_id_model, TAG_ATTESTATION_ID_MODEL, auth_list); + copyAuthTag(record->vendor_patchlevel, TAG_VENDOR_PATCHLEVEL, auth_list); + copyAuthTag(record->boot_patchlevel, TAG_BOOT_PATCHLEVEL, auth_list); copyAuthTag(record->device_unique_attestation, TAG_DEVICE_UNIQUE_ATTESTATION, auth_list); - copyAuthTag(record->storage_key, TAG_STORAGE_KEY, auth_list); copyAuthTag(record->identity_credential, TAG_IDENTITY_CREDENTIAL_KEY, auth_list); - copyAuthTag(record->usage_count_limit, TAG_USAGE_COUNT_LIMIT, auth_list); return ErrorCode::OK; } -- GitLab From 916410f1b110b420736c820970e2fdb7e8ab7900 Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Wed, 9 Jun 2021 17:52:35 -0700 Subject: [PATCH 701/790] Deflake WorkerThreadTest Bug: 187402940 Test: atest --host --rerun-until-failure 1000 WorkerThreadTest Change-Id: I65dc183d7a616a684a42a3780b32f6f8f55ae9c4 --- .../aidl/default/tests/WorkerThreadTest.cpp | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/biometrics/fingerprint/aidl/default/tests/WorkerThreadTest.cpp b/biometrics/fingerprint/aidl/default/tests/WorkerThreadTest.cpp index 84433364df..b2417bd242 100644 --- a/biometrics/fingerprint/aidl/default/tests/WorkerThreadTest.cpp +++ b/biometrics/fingerprint/aidl/default/tests/WorkerThreadTest.cpp @@ -73,24 +73,29 @@ TEST(WorkerThreadTest, TasksExecuteInOrder) { constexpr int NUM_TASKS = 10000; WorkerThread worker(NUM_TASKS); + std::mutex mut; + std::condition_variable cv; + bool finished = false; std::vector results; + for (int i = 0; i < NUM_TASKS; ++i) { - worker.schedule(Callable::from([&results, i] { + worker.schedule(Callable::from([&mut, &results, i] { // Delay tasks differently to provoke races. std::this_thread::sleep_for(std::chrono::nanoseconds(100 - i % 100)); - // Unguarded write to results to provoke races. + auto lock = std::lock_guard(mut); results.push_back(i); })); } - std::promise promise; - auto future = promise.get_future(); - // Schedule a special task to signal when all of the tasks are finished. - worker.schedule( - Callable::from([promise = std::move(promise)]() mutable { promise.set_value(); })); - future.wait(); - + worker.schedule(Callable::from([&mut, &cv, &finished] { + auto lock = std::lock_guard(mut); + finished = true; + cv.notify_one(); + })); + + auto lock = std::unique_lock(mut); + cv.wait(lock, [&finished] { return finished; }); ASSERT_EQ(results.size(), NUM_TASKS); EXPECT_TRUE(std::is_sorted(results.begin(), results.end())); } -- GitLab From 4b54b1fc491895adec637d0346dad1628cb601fb Mon Sep 17 00:00:00 2001 From: Lais Andrade Date: Thu, 10 Jun 2021 16:38:34 +0100 Subject: [PATCH 702/790] Fix vibrator VTS failure on older HAL versions Fix tests to expect STATUS_UNKNOWN_TRANSACTION as well as EX_UNSUPPORTED_OPERATION when the vibrator does not have a capability required for the method being tested. Older versions of the HAL will return that status code instead of unsupported, as explained at: https://source.android.com/devices/architecture/aidl/stable-aidl#versioning-interfaces Fix: 190526054 Test: VtsHalVibratorTargetTest & VtsHalVibratorManagerTargetTest Change-Id: I538843fbbdbf8353cd57f1c83392baeabdcbadd2 --- .../vts/VtsHalVibratorManagerTargetTest.cpp | 25 +++++---- .../aidl/vts/VtsHalVibratorTargetTest.cpp | 55 +++++++++++-------- 2 files changed, 46 insertions(+), 34 deletions(-) diff --git a/vibrator/aidl/vts/VtsHalVibratorManagerTargetTest.cpp b/vibrator/aidl/vts/VtsHalVibratorManagerTargetTest.cpp index 9789188858..44fa3be7ab 100644 --- a/vibrator/aidl/vts/VtsHalVibratorManagerTargetTest.cpp +++ b/vibrator/aidl/vts/VtsHalVibratorManagerTargetTest.cpp @@ -71,6 +71,11 @@ class VibratorAidl : public testing::TestWithParam { std::vector vibratorIds; }; +inline bool isUnknownOrUnsupported(Status status) { + return status.exceptionCode() == Status::EX_UNSUPPORTED_OPERATION || + status.transactionError() == android::UNKNOWN_TRANSACTION; +} + TEST_P(VibratorAidl, ValidateExistingVibrators) { sp vibrator; for (auto& id : vibratorIds) { @@ -101,8 +106,8 @@ TEST_P(VibratorAidl, PrepareSyncedEmptySetIsInvalid) { TEST_P(VibratorAidl, PrepareSyncedNotSupported) { if (!(capabilities & IVibratorManager::CAP_SYNC)) { - EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION, - manager->prepareSynced(vibratorIds).exceptionCode()); + Status status = manager->prepareSynced(vibratorIds); + EXPECT_TRUE(isUnknownOrUnsupported(status)) << status; } } @@ -116,8 +121,8 @@ TEST_P(VibratorAidl, PrepareOnNotSupported) { for (auto& id : vibratorIds) { EXPECT_TRUE(manager->getVibrator(id, &vibrator).isOk()); ASSERT_NE(vibrator, nullptr); - EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION, - vibrator->on(durationMs, nullptr).exceptionCode()); + Status status = vibrator->on(durationMs, nullptr); + EXPECT_TRUE(isUnknownOrUnsupported(status)) << status; } EXPECT_TRUE(manager->cancelSynced().isOk()); } @@ -134,7 +139,7 @@ TEST_P(VibratorAidl, PreparePerformNotSupported) { ASSERT_NE(vibrator, nullptr); int32_t lengthMs = 0; Status status = vibrator->perform(kEffects[0], kEffectStrengths[0], nullptr, &lengthMs); - EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION, status.exceptionCode()); + EXPECT_TRUE(isUnknownOrUnsupported(status)) << status; } EXPECT_TRUE(manager->cancelSynced().isOk()); } @@ -157,7 +162,7 @@ TEST_P(VibratorAidl, PrepareComposeNotSupported) { EXPECT_TRUE(manager->getVibrator(id, &vibrator).isOk()); ASSERT_NE(vibrator, nullptr); Status status = vibrator->compose(composite, nullptr); - EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION, status.exceptionCode()); + EXPECT_TRUE(isUnknownOrUnsupported(status)) << status; } EXPECT_TRUE(manager->cancelSynced().isOk()); } @@ -191,8 +196,8 @@ TEST_P(VibratorAidl, TriggerWithCallback) { TEST_P(VibratorAidl, TriggerSyncNotSupported) { if (!(capabilities & IVibratorManager::CAP_SYNC)) { - EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION, - manager->triggerSynced(nullptr).exceptionCode()); + Status status = manager->triggerSynced(nullptr); + EXPECT_TRUE(isUnknownOrUnsupported(status)) << status; } } @@ -201,8 +206,8 @@ TEST_P(VibratorAidl, TriggerCallbackNotSupported) { if (!(capabilities & IVibratorManager::CAP_TRIGGER_CALLBACK)) { sp callback = new CompletionCallback([] {}); EXPECT_TRUE(manager->prepareSynced(vibratorIds).isOk()); - EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION, - manager->triggerSynced(callback).exceptionCode()); + Status status = manager->triggerSynced(callback); + EXPECT_TRUE(isUnknownOrUnsupported(status)) << status; } } diff --git a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp index 713ec75a20..4d49a12661 100644 --- a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp +++ b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp @@ -112,6 +112,11 @@ class VibratorAidl : public testing::TestWithParam> int32_t capabilities; }; +inline bool isUnknownOrUnsupported(Status status) { + return status.exceptionCode() == Status::EX_UNSUPPORTED_OPERATION || + status.transactionError() == android::UNKNOWN_TRANSACTION; +} + static float getResonantFrequencyHz(sp vibrator, int32_t capabilities) { float resonantFrequencyHz; Status status = vibrator->getResonantFrequency(&resonantFrequencyHz); @@ -119,7 +124,7 @@ static float getResonantFrequencyHz(sp vibrator, int32_t capabilities EXPECT_GT(resonantFrequencyHz, 0); EXPECT_EQ(status.exceptionCode(), Status::EX_NONE); } else { - EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION); + EXPECT_TRUE(isUnknownOrUnsupported(status)) << status; } return resonantFrequencyHz; } @@ -131,7 +136,7 @@ static float getFrequencyResolutionHz(sp vibrator, int32_t capabiliti EXPECT_GT(freqResolutionHz, 0); EXPECT_EQ(status.exceptionCode(), Status::EX_NONE); } else { - EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION); + EXPECT_TRUE(isUnknownOrUnsupported(status)) << status; } return freqResolutionHz; } @@ -147,7 +152,7 @@ static float getFrequencyMinimumHz(sp vibrator, int32_t capabilities) EXPECT_GT(freqMinimumHz, 0); EXPECT_LE(freqMinimumHz, resonantFrequencyHz); } else { - EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION); + EXPECT_TRUE(isUnknownOrUnsupported(status)) << status; } return freqMinimumHz; } @@ -158,7 +163,7 @@ static float getFrequencyMaximumHz(sp vibrator, int32_t capabilities) if (capabilities & IVibrator::CAP_FREQUENCY_CONTROL) { EXPECT_EQ(status.exceptionCode(), Status::EX_NONE); } else { - EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION); + EXPECT_TRUE(isUnknownOrUnsupported(status)) << status; } float freqMaximumHz = @@ -219,7 +224,8 @@ TEST_P(VibratorAidl, OnWithCallback) { TEST_P(VibratorAidl, OnCallbackNotSupported) { if (!(capabilities & IVibrator::CAP_ON_CALLBACK)) { sp callback = new CompletionCallback([] {}); - EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION, vibrator->on(250, callback).exceptionCode()); + Status status = vibrator->on(250, callback); + EXPECT_TRUE(isUnknownOrUnsupported(status)) << status; } } @@ -240,8 +246,8 @@ TEST_P(VibratorAidl, ValidateEffect) { EXPECT_GT(lengthMs, 0); usleep(lengthMs * 1000); } else { - EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION) - << toString(effect) << " " << toString(strength); + EXPECT_TRUE(isUnknownOrUnsupported(status)) + << status << " " << toString(effect) << " " << toString(strength); } } } @@ -270,7 +276,7 @@ TEST_P(VibratorAidl, ValidateEffectWithCallback) { EXPECT_TRUE(status.isOk()); EXPECT_GT(lengthMs, 0); } else { - EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION); + EXPECT_TRUE(isUnknownOrUnsupported(status)) << status; } if (!status.isOk()) @@ -293,7 +299,7 @@ TEST_P(VibratorAidl, ValidateEffectWithCallbackNotSupported) { sp callback = new CompletionCallback([] {}); int lengthMs; Status status = vibrator->perform(effect, strength, callback, &lengthMs); - EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION, status.exceptionCode()); + EXPECT_TRUE(isUnknownOrUnsupported(status)) << status; } } } @@ -311,8 +317,8 @@ TEST_P(VibratorAidl, InvalidEffectsUnsupported) { for (EffectStrength strength : kInvalidEffectStrengths) { int32_t lengthMs; Status status = vibrator->perform(effect, strength, nullptr /*callback*/, &lengthMs); - EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION) - << toString(effect) << " " << toString(strength); + EXPECT_TRUE(isUnknownOrUnsupported(status)) + << status << " " << toString(effect) << " " << toString(strength); } } } @@ -338,7 +344,8 @@ TEST_P(VibratorAidl, AmplitudeOutsideRangeFails) { TEST_P(VibratorAidl, AmplitudeReturnsUnsupportedMatchingCapabilities) { if ((capabilities & IVibrator::CAP_AMPLITUDE_CONTROL) == 0) { - EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION, vibrator->setAmplitude(1).exceptionCode()); + Status status = vibrator->setAmplitude(1); + EXPECT_TRUE(isUnknownOrUnsupported(status)) << status; } } @@ -362,7 +369,7 @@ TEST_P(VibratorAidl, ExternalAmplitudeControl) { if (supportsExternalAmplitudeControl) { EXPECT_TRUE(amplitudeStatus.isOk()); } else { - EXPECT_EQ(amplitudeStatus.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION); + EXPECT_TRUE(isUnknownOrUnsupported(amplitudeStatus)) << amplitudeStatus; } EXPECT_TRUE(vibrator->setExternalControl(false).isOk()); } else { @@ -372,8 +379,8 @@ TEST_P(VibratorAidl, ExternalAmplitudeControl) { TEST_P(VibratorAidl, ExternalControlUnsupportedMatchingCapabilities) { if ((capabilities & IVibrator::CAP_EXTERNAL_CONTROL) == 0) { - EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION, - vibrator->setExternalControl(true).exceptionCode()); + Status status = vibrator->setExternalControl(true); + EXPECT_TRUE(isUnknownOrUnsupported(status)) << status; } } @@ -410,7 +417,7 @@ TEST_P(VibratorAidl, GetPrimitiveDuration) { if (isPrimitiveSupported) { EXPECT_EQ(Status::EX_NONE, status.exceptionCode()); } else { - EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION, status.exceptionCode()); + EXPECT_TRUE(isUnknownOrUnsupported(status)) << status; } } } @@ -473,8 +480,8 @@ TEST_P(VibratorAidl, ComposeUnsupportedPrimitives) { effect.primitive = primitive; effect.scale = 1.0f; } - EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION, - vibrator->compose(composite, nullptr).exceptionCode()); + Status status = vibrator->compose(composite, nullptr); + EXPECT_TRUE(isUnknownOrUnsupported(status)) << status; vibrator->off(); } } @@ -618,8 +625,8 @@ TEST_P(VibratorAidl, AlwaysOn) { EXPECT_EQ(Status::EX_NONE, status.exceptionCode()) << toString(effect) << " " << toString(strength); } else { - EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION, status.exceptionCode()) - << toString(effect) << " " << toString(strength); + EXPECT_TRUE(isUnknownOrUnsupported(status)) + << status << " " << toString(effect) << " " << toString(strength); } } } @@ -639,7 +646,7 @@ TEST_P(VibratorAidl, GetQFactor) { ASSERT_GT(qFactor, 0); EXPECT_EQ(status.exceptionCode(), Status::EX_NONE); } else { - EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION); + EXPECT_TRUE(isUnknownOrUnsupported(status)) << status; } } @@ -668,7 +675,7 @@ TEST_P(VibratorAidl, GetBandwidthAmplitudeMap) { ASSERT_LE(e, 1.0); } } else { - EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION); + EXPECT_TRUE(isUnknownOrUnsupported(status)) << status; } } @@ -690,7 +697,7 @@ TEST_P(VibratorAidl, GetPwleCompositionSizeMax) { ASSERT_NE(maxSize, 0); EXPECT_EQ(status.exceptionCode(), Status::EX_NONE); } else { - EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION); + EXPECT_TRUE(isUnknownOrUnsupported(status)) << status; } } @@ -703,7 +710,7 @@ TEST_P(VibratorAidl, GetSupportedBraking) { ASSERT_TRUE(isDefaultNoneSupported); EXPECT_EQ(status.exceptionCode(), Status::EX_NONE); } else { - EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION); + EXPECT_TRUE(isUnknownOrUnsupported(status)) << status; } } -- GitLab From d262fa3f01b2f66071908db5ba098ad1dbbedee9 Mon Sep 17 00:00:00 2001 From: Sasha Kuznetsov Date: Wed, 26 May 2021 19:38:46 -0700 Subject: [PATCH 703/790] Fix ADR half cycle ambiguity doc (hardware/interfaces) Bug: 190846015 Test: n/a Change-Id: I6339018bc5b3764d51db61458d208ca7e99b4d81 --- current.txt | 2 +- gnss/1.1/IGnssMeasurementCallback.hal | 27 ++++++++++++++++++- .../hardware/gnss/GnssMeasurement.aidl | 25 +++++++++++++++++ 3 files changed, 52 insertions(+), 2 deletions(-) diff --git a/current.txt b/current.txt index 3102972081..387f9ec6c5 100644 --- a/current.txt +++ b/current.txt @@ -770,7 +770,7 @@ a64467bae843569f0d465c5be7f0c7a5b987985b55a3ef4794dd5afc68538650 android.hardwar e042522daa4b5f7fd4a0a19bcdadb93c79a1b04c09ef2c9813a3a8941032f3f5 android.hardware.contexthub@1.0::IContexthub c2f64133b83ede65c9939ef97ab5bd867b73faf3dba0e7e69f77c3c43d9e487e android.hardware.contexthub@1.0::IContexthubCallback bda492ec4021d13869de72bd6f8c15c5837b78d6136b8d538efec5320573a5ec android.hardware.gnss@1.0::IGnssMeasurementCallback -6a271e493907e8ba20912e42771bd0d99ae45431a851d5675ef9496d02510a34 android.hardware.gnss@1.1::IGnssMeasurementCallback +7ae2025662e30e690a3ffa1c65cc972c6297a68638174055c33cbf3d2e4bbddc android.hardware.gnss@1.1::IGnssMeasurementCallback 11e9e1a1fd0c9b3d9648750d4b10dc2a839d3a6688904c3fc49500a4e7ca75b0 android.hardware.gnss@2.1::IGnssMeasurementCallback 2c331a9605f3a08d9c1e0a36169ca57758bc43c11a78ef3f3730509885e52c15 android.hardware.graphics.composer@2.4::IComposerClient 3da3ce039247872d95c6bd48621dbfdfa1c2d2a91a90f257862f87ee2bc46300 android.hardware.health@2.1::types diff --git a/gnss/1.1/IGnssMeasurementCallback.hal b/gnss/1.1/IGnssMeasurementCallback.hal index 36841ee0e6..f94c67a8ea 100644 --- a/gnss/1.1/IGnssMeasurementCallback.hal +++ b/gnss/1.1/IGnssMeasurementCallback.hal @@ -24,13 +24,38 @@ interface IGnssMeasurementCallback extends @1.0::IGnssMeasurementCallback { * Flags indicating the Accumulated Delta Range's states. * * See the table below for a detailed interpretation of each state. This is - * a continuation of the table from 1.1/IGnssMeasurementCallback.hal. + * a continuation of the table from 1.0/IGnssMeasurementCallback.hal. * * +---------------------+-------------------+-----------------------------+ * | ADR_STATE | Time of relevance | Interpretation | * +---------------------+-------------------+-----------------------------+ * | HALF_CYCLE_RESOLVED | ADR(t) | Half cycle ambiguity is | * | | | resolved at time t. | + * | | | | + * | | | For signals that have | + * | | | databits, the carrier phase | + * | | | tracking loops typically | + * | | | use a costas loop | + * | | | discriminator. This type of | + * | | | tracking loop introduces a | + * | | | half-cycle ambiguity that | + * | | | is resolved by searching | + * | | | through the received data | + * | | | for known patterns of | + * | | | databits (e.g. GPS uses the | + * | | | TLM word) which then | + * | | | determines the polarity of | + * | | | the incoming data and | + * | | | resolves the half-cycle | + * | | | ambiguity. | + * | | | | + * | | | Before the half-cycle | + * | | | ambiguity has been resolved | + * | | | it is possible that the | + * | | | ADR_STATE_VALID flag is | + * | | | set, but the ADR_STATE_ | + * | | | HALF_CYCLE_RESOLVED flag is | + * | | | not set. | * +---------------------+-------------------+-----------------------------+ */ enum GnssAccumulatedDeltaRangeState diff --git a/gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl b/gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl index 58f29c5f92..efecddd41e 100644 --- a/gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl +++ b/gnss/aidl/android/hardware/gnss/GnssMeasurement.aidl @@ -438,6 +438,31 @@ parcelable GnssMeasurement { * +---------------------+-------------------+-----------------------------+ * | HALF_CYCLE_RESOLVED | ADR(t) | Half cycle ambiguity is | * | | | resolved at time t. | + * | | | | + * | | | For signals that have | + * | | | databits, the carrier phase | + * | | | tracking loops typically | + * | | | use a costas loop | + * | | | discriminator. This type of | + * | | | tracking loop introduces a | + * | | | half-cycle ambiguity that | + * | | | is resolved by searching | + * | | | through the received data | + * | | | for known patterns of | + * | | | databits (e.g. GPS uses the | + * | | | TLM word) which then | + * | | | determines the polarity of | + * | | | the incoming data and | + * | | | resolves the half-cycle | + * | | | ambiguity. | + * | | | | + * | | | Before the half-cycle | + * | | | ambiguity has been resolved | + * | | | it is possible that the | + * | | | ADR_STATE_VALID flag is | + * | | | set, but the ADR_STATE_ | + * | | | HALF_CYCLE_RESOLVED flag is | + * | | | not set. | * +---------------------+-------------------+-----------------------------+ */ const int ADR_STATE_UNKNOWN = 0; -- GitLab From 9df909dba11b753d651e3c7bdc6fdd94714cfb69 Mon Sep 17 00:00:00 2001 From: Wei Wang Date: Sat, 12 Jun 2021 18:26:38 -0700 Subject: [PATCH 704/790] Power: allow vts to pass with earlier version of server Bug: 189976527 Test: Build Signed-off-by: Wei Wang Change-Id: I3e1ce05e62e9581c9a66f65e82e1599d77de7a85 --- power/aidl/vts/VtsHalPowerTargetTest.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/power/aidl/vts/VtsHalPowerTargetTest.cpp b/power/aidl/vts/VtsHalPowerTargetTest.cpp index 5bb088a121..ffab66c312 100644 --- a/power/aidl/vts/VtsHalPowerTargetTest.cpp +++ b/power/aidl/vts/VtsHalPowerTargetTest.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include @@ -82,6 +83,11 @@ const std::vector kDurations = { DurationWrapper(1000000000L, 4L), }; +inline bool isUnknownOrUnsupported(const ndk::ScopedAStatus& status) { + return status.getStatus() == STATUS_UNKNOWN_TRANSACTION || + status.getExceptionCode() == EX_UNSUPPORTED_OPERATION; +} + class PowerAidl : public testing::TestWithParam { public: virtual void SetUp() override { @@ -147,7 +153,7 @@ TEST_P(PowerAidl, getHintSessionPreferredRate) { int64_t rate = -1; auto status = power->getHintSessionPreferredRate(&rate); if (!status.isOk()) { - ASSERT_EQ(EX_UNSUPPORTED_OPERATION, status.getExceptionCode()); + EXPECT_TRUE(isUnknownOrUnsupported(status)); return; } @@ -159,7 +165,7 @@ TEST_P(PowerAidl, createAndCloseHintSession) { std::shared_ptr session; auto status = power->createHintSession(getpid(), getuid(), kSelfTids, 16666666L, &session); if (!status.isOk()) { - ASSERT_EQ(EX_UNSUPPORTED_OPERATION, status.getExceptionCode()); + EXPECT_TRUE(isUnknownOrUnsupported(status)); return; } ASSERT_NE(nullptr, session); @@ -173,10 +179,9 @@ TEST_P(PowerAidl, createHintSessionFailed) { std::shared_ptr session; auto status = power->createHintSession(getpid(), getuid(), kEmptyTids, 16666666L, &session); ASSERT_FALSE(status.isOk()); - if (EX_UNSUPPORTED_OPERATION == status.getExceptionCode()) { + if (isUnknownOrUnsupported(status)) { return; } - // Test with empty tid list ASSERT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode()); } @@ -184,7 +189,7 @@ TEST_P(PowerAidl, updateAndReportDurations) { std::shared_ptr session; auto status = power->createHintSession(getpid(), getuid(), kSelfTids, 16666666L, &session); if (!status.isOk()) { - ASSERT_EQ(EX_UNSUPPORTED_OPERATION, status.getExceptionCode()); + EXPECT_TRUE(isUnknownOrUnsupported(status)); return; } ASSERT_NE(nullptr, session); -- GitLab From 1e5f72a2cc60e6fc021cf25091f5d9e484dd8b3b Mon Sep 17 00:00:00 2001 From: David Zeuthen Date: Thu, 10 Jun 2021 18:34:24 -0400 Subject: [PATCH 705/790] identity: fix access control checks in libeic. Also add a new libeic_test binary which has a regression test for this vulnerability. Bug: 190757775 Test: atest libeic_test Test: atest VtsHalIdentityTargetTest Test: atest CtsIdentityTestCases Change-Id: I8344655c59930d6bf1baa4e0f8d0f60e4fc9e48d --- identity/TEST_MAPPING | 3 + identity/aidl/default/Android.bp | 37 ++++++++ identity/aidl/default/EicTests.cpp | 85 +++++++++++++++++++ .../aidl/default/libeic/EicPresentation.c | 8 ++ .../aidl/default/libeic/EicPresentation.h | 4 + 5 files changed, 137 insertions(+) create mode 100644 identity/aidl/default/EicTests.cpp diff --git a/identity/TEST_MAPPING b/identity/TEST_MAPPING index f35f4b7ef9..85cf91f15c 100644 --- a/identity/TEST_MAPPING +++ b/identity/TEST_MAPPING @@ -8,6 +8,9 @@ }, { "name": "android.hardware.identity-support-lib-test" + }, + { + "name": "libeic_test" } ] } diff --git a/identity/aidl/default/Android.bp b/identity/aidl/default/Android.bp index 7c68aee26d..28c489309f 100644 --- a/identity/aidl/default/Android.bp +++ b/identity/aidl/default/Android.bp @@ -114,6 +114,43 @@ cc_binary { ], } +cc_test { + name: "libeic_test", + srcs: [ + "EicTests.cpp", + "FakeSecureHardwareProxy.cpp", + ], + cflags: [ + "-Wall", + "-Wextra", + "-g", + "-DEIC_DEBUG", + ], + local_include_dirs: [ + "common", + ], + shared_libs: [ + "liblog", + "libcrypto", + "libkeymaster_messages", + ], + static_libs: [ + "libbase", + "libcppbor_external", + "libcppcose_rkp", + "libutils", + "libsoft_attestation_cert", + "libkeymaster_portable", + "libsoft_attestation_cert", + "libpuresoftkeymasterdevice", + "android.hardware.identity-support-lib", + "android.hardware.identity-libeic-library", + ], + test_suites: [ + "general-tests", + ], +} + prebuilt_etc { name: "android.hardware.identity_credential.xml", sub_dir: "permissions", diff --git a/identity/aidl/default/EicTests.cpp b/identity/aidl/default/EicTests.cpp new file mode 100644 index 0000000000..a28080d009 --- /dev/null +++ b/identity/aidl/default/EicTests.cpp @@ -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. + */ + +#include +#include +#include +#include + +#include "FakeSecureHardwareProxy.h" + +// Most of libeic is tested as part of VTS since there's almost a 1:1 mapping between +// the HAL and libeic interfaces. This test suite is mainly for the few things which +// doesn't map directly. +// + +using std::optional; +using std::string; +using std::vector; + +using android::hardware::identity::AccessCheckResult; +using android::hardware::identity::FakeSecureHardwarePresentationProxy; +using android::hardware::identity::FakeSecureHardwareProvisioningProxy; + +TEST(EicTest, AccessControlIsEnforced) { + // First provision the credential... + // + FakeSecureHardwareProvisioningProxy provisioningProxy; + bool isTestCredential = false; + provisioningProxy.initialize(isTestCredential); + optional> credKey = + provisioningProxy.createCredentialKey({0x01, 0x02}, {0x03, 0x04}); + ASSERT_TRUE(credKey.has_value()); + string docType = "org.iso.18013.5.1.mDL"; + ASSERT_TRUE(provisioningProxy.startPersonalization(0, {1}, docType, 125)); + + vector acpIds = {}; + string nameSpace = "org.iso.18013.5.1"; + string name = "NonAccessibleElement"; + vector content = {0x63, 0x46, 0x6f, 0x6f}; // "Foo" tstr + ASSERT_TRUE(provisioningProxy.beginAddEntry(acpIds, nameSpace, name, content.size())); + optional> encContent = + provisioningProxy.addEntryValue(acpIds, nameSpace, name, content); + ASSERT_TRUE(encContent.has_value()); + ASSERT_EQ(encContent->size(), content.size() + 28); + + optional> signatureOfToBeSigned = provisioningProxy.finishAddingEntries(); + ASSERT_TRUE(signatureOfToBeSigned.has_value()); + + optional> credData = provisioningProxy.finishGetCredentialData(docType); + ASSERT_TRUE(credData.has_value()); + ASSERT_TRUE(provisioningProxy.shutdown()); + + // Then present data from it... + // + FakeSecureHardwarePresentationProxy presentationProxy; + ASSERT_TRUE(presentationProxy.initialize(isTestCredential, docType, credData.value())); + AccessCheckResult res = + presentationProxy.startRetrieveEntryValue(nameSpace, name, 1, content.size(), acpIds); + ASSERT_EQ(res, AccessCheckResult::kNoAccessControlProfiles); + + // Ensure that we can't get the data out if startRetrieveEntryValue() returned + // something other than kOk... See b/190757775 for details. + // + optional> decContent = + presentationProxy.retrieveEntryValue(encContent.value(), nameSpace, name, acpIds); + ASSERT_FALSE(decContent.has_value()); +} + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/identity/aidl/default/libeic/EicPresentation.c b/identity/aidl/default/libeic/EicPresentation.c index 9e033b39fb..3d13766f1e 100644 --- a/identity/aidl/default/libeic/EicPresentation.c +++ b/identity/aidl/default/libeic/EicPresentation.c @@ -633,6 +633,8 @@ EicAccessCheckResult eicPresentationStartRetrieveEntryValue( // We'll need to calc and store a digest of additionalData to check that it's the same // additionalData being passed in for every eicPresentationRetrieveEntryValue() call... + // + ctx->accessCheckOk = false; if (!eicCborCalcEntryAdditionalData(accessControlProfileIds, numAccessControlProfileIds, nameSpace, name, additionalDataCbor, additionalDataCborBufSize, &additionalDataCborSize, @@ -680,6 +682,7 @@ EicAccessCheckResult eicPresentationStartRetrieveEntryValue( if (result == EIC_ACCESS_CHECK_RESULT_OK) { eicCborAppendString(&ctx->cbor, name); + ctx->accessCheckOk = true; } return result; } @@ -702,10 +705,15 @@ bool eicPresentationRetrieveEntryValue(EicPresentation* ctx, const uint8_t* encr calculatedSha256)) { return false; } + if (eicCryptoMemCmp(calculatedSha256, ctx->additionalDataSha256, EIC_SHA256_DIGEST_SIZE) != 0) { eicDebug("SHA-256 mismatch of additionalData"); return false; } + if (!ctx->accessCheckOk) { + eicDebug("Attempting to retrieve a value for which access is not granted"); + return false; + } if (!eicOpsDecryptAes128Gcm(ctx->storageKey, encryptedContent, encryptedContentSize, additionalDataCbor, additionalDataCborSize, content)) { diff --git a/identity/aidl/default/libeic/EicPresentation.h b/identity/aidl/default/libeic/EicPresentation.h index 7cad068772..c888049dbe 100644 --- a/identity/aidl/default/libeic/EicPresentation.h +++ b/identity/aidl/default/libeic/EicPresentation.h @@ -70,6 +70,10 @@ typedef struct { // Set to true initialized as a test credential. bool testCredential; + // Set to true if the evaluation of access control checks in + // eicPresentationStartRetrieveEntryValue() resulted EIC_ACCESS_CHECK_RESULT_OK + bool accessCheckOk; + // These are bitmasks indicating which of the possible 32 access control profiles are // authorized. They are built up by eicPresentationValidateAccessControlProfile(). // -- GitLab From 126ae7c316ae6f4a9074c816f853903952edb270 Mon Sep 17 00:00:00 2001 From: Yomna Nasser Date: Wed, 9 Jun 2021 22:21:49 +0000 Subject: [PATCH 706/790] Adds VTS test for getAllowedNetworkTypesBitmap Adds VTS test for the new HAL API getAllowedNetworkTypesBitmap Bug: b/190398554 Test: atest VtsHalRadioV1_6TargetTest Change-Id: Ida0aff8e239cad324627db83903f4a1adcc479d1 --- .../1.6/vts/functional/radio_hidl_hal_api.cpp | 43 +++++++++++++++++++ radio/1.6/vts/functional/radio_response.cpp | 7 ++- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp index fd8da6e2ef..a6eb2d8e9a 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp +++ b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp @@ -51,6 +51,49 @@ TEST_P(RadioHidlTest_v1_6, setAllowedNetworkTypesBitmap) { } } +/* + * Test IRadio.getAllowedNetworkTypesBitmap for the response returned. + */ +TEST_P(RadioHidlTest_v1_6, getAllowedNetworkTypesBitmap) { + serial = GetRandomSerialNumber(); + ::android::hardware::hidl_bitfield<::android::hardware::radio::V1_4::RadioAccessFamily> + allowedNetworkTypesBitmap{}; + allowedNetworkTypesBitmap |= ::android::hardware::radio::V1_4::RadioAccessFamily::LTE; + + radio_v1_6->setAllowedNetworkTypesBitmap(serial, allowedNetworkTypesBitmap); + + EXPECT_EQ(std::cv_status::no_timeout, wait()); + EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type); + EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial); + + if (radioRsp_v1_6->rspInfo.error == ::android::hardware::radio::V1_6::RadioError::NONE) { + sleep(3); // wait for modem + serial = GetRandomSerialNumber(); + radio_v1_6->getAllowedNetworkTypesBitmap(serial); + + EXPECT_EQ(std::cv_status::no_timeout, wait()); + EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type); + EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial); + + if (getRadioHalCapabilities()) { + ASSERT_TRUE(CheckAnyOfErrors( + radioRsp_v1_6->rspInfo.error, + {::android::hardware::radio::V1_6::RadioError::REQUEST_NOT_SUPPORTED})); + } else { + ASSERT_TRUE(CheckAnyOfErrors( + radioRsp_v1_6->rspInfo.error, + {::android::hardware::radio::V1_6::RadioError::NONE, + ::android::hardware::radio::V1_6::RadioError::RADIO_NOT_AVAILABLE, + ::android::hardware::radio::V1_6::RadioError::OPERATION_NOT_ALLOWED, + ::android::hardware::radio::V1_6::RadioError::MODE_NOT_SUPPORTED, + ::android::hardware::radio::V1_6::RadioError::INTERNAL_ERR, + ::android::hardware::radio::V1_6::RadioError::INVALID_ARGUMENTS, + ::android::hardware::radio::V1_6::RadioError::MODEM_ERR, + ::android::hardware::radio::V1_6::RadioError::NO_RESOURCES})); + } + } +} + /* * Test IRadio.setupDataCall_1_6() for the response returned. */ diff --git a/radio/1.6/vts/functional/radio_response.cpp b/radio/1.6/vts/functional/radio_response.cpp index b1e679b35b..e1b9f56de0 100644 --- a/radio/1.6/vts/functional/radio_response.cpp +++ b/radio/1.6/vts/functional/radio_response.cpp @@ -1172,10 +1172,13 @@ Return RadioResponse_v1_6::setAllowedNetworkTypesBitmapResponse( } Return RadioResponse_v1_6::getAllowedNetworkTypesBitmapResponse( - const ::android::hardware::radio::V1_6::RadioResponseInfo& /*info*/, + const ::android::hardware::radio::V1_6::RadioResponseInfo& info, const ::android::hardware::hidl_bitfield< ::android::hardware::radio::V1_4::RadioAccessFamily> - /*networkTypeBitmap*/) { + networkTypeBitmap) { + rspInfo = info; + networkTypeBitmapResponse = networkTypeBitmap; + parent_v1_6.notify(info.serial); return Void(); } -- GitLab From 7e8409bb5164555ddd10f3a55d94a933a8845a0e Mon Sep 17 00:00:00 2001 From: Ahmed ElArabawy Date: Tue, 15 Jun 2021 10:20:29 -0700 Subject: [PATCH 707/790] WiFi: Modify OWNERS files Replace kumaranand@ with arabawy@ in OWNERS files Bug: 191158491 Test: None Change-Id: I585e95449e0aafdaa9687b363af0418032f41dfa --- wifi/1.0/vts/OWNERS | 2 +- wifi/1.1/vts/OWNERS | 2 +- wifi/1.2/vts/OWNERS | 2 +- wifi/1.3/vts/OWNERS | 2 +- wifi/1.4/vts/OWNERS | 2 +- wifi/1.5/default/OWNERS | 2 +- wifi/1.5/vts/OWNERS | 2 +- wifi/hostapd/1.0/vts/OWNERS | 2 +- wifi/hostapd/1.1/vts/OWNERS | 2 +- wifi/hostapd/1.2/vts/OWNERS | 2 +- wifi/hostapd/1.3/vts/OWNERS | 2 +- wifi/supplicant/1.2/vts/OWNERS | 2 +- wifi/supplicant/1.3/vts/OWNERS | 2 +- wifi/supplicant/1.4/vts/OWNERS | 2 +- 14 files changed, 14 insertions(+), 14 deletions(-) diff --git a/wifi/1.0/vts/OWNERS b/wifi/1.0/vts/OWNERS index e7b2fc5284..cf81c79892 100644 --- a/wifi/1.0/vts/OWNERS +++ b/wifi/1.0/vts/OWNERS @@ -1,2 +1,2 @@ -kumaranand@google.com +arabawy@google.com etancohen@google.com diff --git a/wifi/1.1/vts/OWNERS b/wifi/1.1/vts/OWNERS index e7b2fc5284..cf81c79892 100644 --- a/wifi/1.1/vts/OWNERS +++ b/wifi/1.1/vts/OWNERS @@ -1,2 +1,2 @@ -kumaranand@google.com +arabawy@google.com etancohen@google.com diff --git a/wifi/1.2/vts/OWNERS b/wifi/1.2/vts/OWNERS index e7b2fc5284..cf81c79892 100644 --- a/wifi/1.2/vts/OWNERS +++ b/wifi/1.2/vts/OWNERS @@ -1,2 +1,2 @@ -kumaranand@google.com +arabawy@google.com etancohen@google.com diff --git a/wifi/1.3/vts/OWNERS b/wifi/1.3/vts/OWNERS index e7b2fc5284..cf81c79892 100644 --- a/wifi/1.3/vts/OWNERS +++ b/wifi/1.3/vts/OWNERS @@ -1,2 +1,2 @@ -kumaranand@google.com +arabawy@google.com etancohen@google.com diff --git a/wifi/1.4/vts/OWNERS b/wifi/1.4/vts/OWNERS index e7b2fc5284..cf81c79892 100644 --- a/wifi/1.4/vts/OWNERS +++ b/wifi/1.4/vts/OWNERS @@ -1,2 +1,2 @@ -kumaranand@google.com +arabawy@google.com etancohen@google.com diff --git a/wifi/1.5/default/OWNERS b/wifi/1.5/default/OWNERS index e7b2fc5284..cf81c79892 100644 --- a/wifi/1.5/default/OWNERS +++ b/wifi/1.5/default/OWNERS @@ -1,2 +1,2 @@ -kumaranand@google.com +arabawy@google.com etancohen@google.com diff --git a/wifi/1.5/vts/OWNERS b/wifi/1.5/vts/OWNERS index e7b2fc5284..cf81c79892 100644 --- a/wifi/1.5/vts/OWNERS +++ b/wifi/1.5/vts/OWNERS @@ -1,2 +1,2 @@ -kumaranand@google.com +arabawy@google.com etancohen@google.com diff --git a/wifi/hostapd/1.0/vts/OWNERS b/wifi/hostapd/1.0/vts/OWNERS index e7b2fc5284..cf81c79892 100644 --- a/wifi/hostapd/1.0/vts/OWNERS +++ b/wifi/hostapd/1.0/vts/OWNERS @@ -1,2 +1,2 @@ -kumaranand@google.com +arabawy@google.com etancohen@google.com diff --git a/wifi/hostapd/1.1/vts/OWNERS b/wifi/hostapd/1.1/vts/OWNERS index e7b2fc5284..cf81c79892 100644 --- a/wifi/hostapd/1.1/vts/OWNERS +++ b/wifi/hostapd/1.1/vts/OWNERS @@ -1,2 +1,2 @@ -kumaranand@google.com +arabawy@google.com etancohen@google.com diff --git a/wifi/hostapd/1.2/vts/OWNERS b/wifi/hostapd/1.2/vts/OWNERS index e7b2fc5284..cf81c79892 100644 --- a/wifi/hostapd/1.2/vts/OWNERS +++ b/wifi/hostapd/1.2/vts/OWNERS @@ -1,2 +1,2 @@ -kumaranand@google.com +arabawy@google.com etancohen@google.com diff --git a/wifi/hostapd/1.3/vts/OWNERS b/wifi/hostapd/1.3/vts/OWNERS index e7b2fc5284..cf81c79892 100644 --- a/wifi/hostapd/1.3/vts/OWNERS +++ b/wifi/hostapd/1.3/vts/OWNERS @@ -1,2 +1,2 @@ -kumaranand@google.com +arabawy@google.com etancohen@google.com diff --git a/wifi/supplicant/1.2/vts/OWNERS b/wifi/supplicant/1.2/vts/OWNERS index e7b2fc5284..cf81c79892 100644 --- a/wifi/supplicant/1.2/vts/OWNERS +++ b/wifi/supplicant/1.2/vts/OWNERS @@ -1,2 +1,2 @@ -kumaranand@google.com +arabawy@google.com etancohen@google.com diff --git a/wifi/supplicant/1.3/vts/OWNERS b/wifi/supplicant/1.3/vts/OWNERS index e7b2fc5284..cf81c79892 100644 --- a/wifi/supplicant/1.3/vts/OWNERS +++ b/wifi/supplicant/1.3/vts/OWNERS @@ -1,2 +1,2 @@ -kumaranand@google.com +arabawy@google.com etancohen@google.com diff --git a/wifi/supplicant/1.4/vts/OWNERS b/wifi/supplicant/1.4/vts/OWNERS index e7b2fc5284..cf81c79892 100644 --- a/wifi/supplicant/1.4/vts/OWNERS +++ b/wifi/supplicant/1.4/vts/OWNERS @@ -1,2 +1,2 @@ -kumaranand@google.com +arabawy@google.com etancohen@google.com -- GitLab From f164c06afb7e9de37b20709e4f488ccf4a0bde07 Mon Sep 17 00:00:00 2001 From: David Drysdale Date: Fri, 14 May 2021 18:03:33 +0100 Subject: [PATCH 708/790] KeyMint VTS: extract full vendor patchlevel The vendor patchlevel is YYYYMMDD not YYYYMM Bug: 188672564 Bug: 186735514 Test: VtsAidlKeyMintTargetTest Merged-In: Ia641f8eef84a85aec8f2a0551c192b6874301126 Change-Id: Ia641f8eef84a85aec8f2a0551c192b6874301126 Ignore-AOSP-First: already present in aosp/master --- security/keymint/support/keymint_utils.cpp | 38 +++++++++++++++------- 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/security/keymint/support/keymint_utils.cpp b/security/keymint/support/keymint_utils.cpp index 2dbdfa8e13..1e0733f923 100644 --- a/security/keymint/support/keymint_utils.cpp +++ b/security/keymint/support/keymint_utils.cpp @@ -32,10 +32,11 @@ constexpr size_t kPlatformVersionMatchCount = kSubminorVersionMatch + 1; constexpr char kPlatformPatchlevelProp[] = "ro.build.version.security_patch"; constexpr char kVendorPatchlevelProp[] = "ro.vendor.build.security_patch"; -constexpr char kPatchlevelRegex[] = "^([0-9]{4})-([0-9]{2})-[0-9]{2}$"; +constexpr char kPatchlevelRegex[] = "^([0-9]{4})-([0-9]{2})-([0-9]{2})$"; constexpr size_t kYearMatch = 1; constexpr size_t kMonthMatch = 2; -constexpr size_t kPatchlevelMatchCount = kMonthMatch + 1; +constexpr size_t kDayMatch = 3; +constexpr size_t kPatchlevelMatchCount = kDayMatch + 1; uint32_t match_to_uint32(const char* expression, const regmatch_t& match) { if (match.rm_so == -1) return 0; @@ -53,8 +54,6 @@ std::string wait_and_get_property(const char* prop) { return prop_value; } -} // anonymous namespace - uint32_t getOsVersion(const char* version_str) { regex_t regex; if (regcomp(®ex, kPlatformVersionRegex, REG_EXTENDED)) { @@ -76,12 +75,9 @@ uint32_t getOsVersion(const char* version_str) { return (major * 100 + minor) * 100 + subminor; } -uint32_t getOsVersion() { - std::string version = wait_and_get_property(kPlatformVersionProp); - return getOsVersion(version.c_str()); -} +enum class PatchlevelOutput { kYearMonthDay, kYearMonth }; -uint32_t getPatchlevel(const char* patchlevel_str) { +uint32_t getPatchlevel(const char* patchlevel_str, PatchlevelOutput detail) { regex_t regex; if (regcomp(®ex, kPatchlevelRegex, REG_EXTENDED) != 0) { return 0; @@ -100,17 +96,35 @@ uint32_t getPatchlevel(const char* patchlevel_str) { if (month < 1 || month > 12) { return 0; } - return year * 100 + month; + + switch (detail) { + case PatchlevelOutput::kYearMonthDay: { + uint32_t day = match_to_uint32(patchlevel_str, matches[kDayMatch]); + if (day < 1 || day > 31) { + return 0; + } + return year * 10000 + month * 100 + day; + } + case PatchlevelOutput::kYearMonth: + return year * 100 + month; + } +} + +} // anonymous namespace + +uint32_t getOsVersion() { + std::string version = wait_and_get_property(kPlatformVersionProp); + return getOsVersion(version.c_str()); } uint32_t getOsPatchlevel() { std::string patchlevel = wait_and_get_property(kPlatformPatchlevelProp); - return getPatchlevel(patchlevel.c_str()); + return getPatchlevel(patchlevel.c_str(), PatchlevelOutput::kYearMonth); } uint32_t getVendorPatchlevel() { std::string patchlevel = wait_and_get_property(kVendorPatchlevelProp); - return getPatchlevel(patchlevel.c_str()); + return getPatchlevel(patchlevel.c_str(), PatchlevelOutput::kYearMonthDay); } } // namespace aidl::android::hardware::security::keymint -- GitLab From c14f322159959def16542be3169b1baabf3a8a40 Mon Sep 17 00:00:00 2001 From: David Drysdale Date: Thu, 10 Jun 2021 14:33:25 +0100 Subject: [PATCH 709/790] VTS tests: check size of byte strings Bug: 181883620 Test: VtsAidlSecureClockTargetTest, VtsAidlSharedSecretTargetTest Merged-In: I9ea8687e0c9e89140bcddfefcc2a6177c99b2e4d Change-Id: I9ea8687e0c9e89140bcddfefcc2a6177c99b2e4d Ignore-AOSP-First: already present in aosp/master --- .../vts/functional/SecureClockAidlTest.cpp | 4 + .../vts/functional/SharedSecretAidlTest.cpp | 81 +++++++++++++++++++ 2 files changed, 85 insertions(+) diff --git a/security/secureclock/aidl/vts/functional/SecureClockAidlTest.cpp b/security/secureclock/aidl/vts/functional/SecureClockAidlTest.cpp index 31f4854e8e..bf332d5428 100644 --- a/security/secureclock/aidl/vts/functional/SecureClockAidlTest.cpp +++ b/security/secureclock/aidl/vts/functional/SecureClockAidlTest.cpp @@ -114,6 +114,7 @@ TEST_P(SecureClockAidlTest, TestCreation) { EXPECT_EQ(ErrorCode::OK, result1.error); EXPECT_EQ(1U, result1.token.challenge); EXPECT_GT(result1.token.timestamp.milliSeconds, 0U); + EXPECT_EQ(32U, result1.token.mac.size()); unsigned long time_to_sleep = 200; sleep_ms(time_to_sleep); @@ -123,6 +124,7 @@ TEST_P(SecureClockAidlTest, TestCreation) { EXPECT_EQ(ErrorCode::OK, result2.error); EXPECT_EQ(2U, result2.token.challenge); EXPECT_GT(result2.token.timestamp.milliSeconds, 0U); + EXPECT_EQ(32U, result2.token.mac.size()); auto host_time_delta = result2_time - result1_time; @@ -153,6 +155,7 @@ TEST_P(SecureClockAidlTest, MacChangesOnChangingTimestamp) { EXPECT_EQ(ErrorCode::OK, result1.error); EXPECT_EQ(0U, result1.token.challenge); EXPECT_GT(result1.token.timestamp.milliSeconds, 0U); + EXPECT_EQ(32U, result1.token.mac.size()); unsigned long time_to_sleep = 200; sleep_ms(time_to_sleep); @@ -162,6 +165,7 @@ TEST_P(SecureClockAidlTest, MacChangesOnChangingTimestamp) { EXPECT_EQ(ErrorCode::OK, result2.error); EXPECT_EQ(1U, result2.token.challenge); EXPECT_GT(result2.token.timestamp.milliSeconds, 0U); + EXPECT_EQ(32U, result2.token.mac.size()); auto host_time_delta = result2_time - result1_time; diff --git a/security/sharedsecret/aidl/vts/functional/SharedSecretAidlTest.cpp b/security/sharedsecret/aidl/vts/functional/SharedSecretAidlTest.cpp index 842612087f..919f882631 100644 --- a/security/sharedsecret/aidl/vts/functional/SharedSecretAidlTest.cpp +++ b/security/sharedsecret/aidl/vts/functional/SharedSecretAidlTest.cpp @@ -48,6 +48,9 @@ class SharedSecretAidlTest : public ::testing::Test { SharedSecretParameters params; auto error = GetReturnErrorCode(sharedSecret->getSharedSecretParameters(¶ms)); EXPECT_EQ(ErrorCode::OK, error); + EXPECT_TRUE(params.seed.size() == 0 || params.seed.size() == 32); + EXPECT_TRUE(params.nonce.size() == 32); + GetParamsResult result; result.tie() = std::tie(error, params); return result; @@ -234,6 +237,45 @@ TEST_F(SharedSecretAidlTest, ComputeSharedSecretCorruptNonce) { } } +TEST_F(SharedSecretAidlTest, ComputeSharedSecretShortNonce) { + auto sharedSecrets = allSharedSecrets(); + if (sharedSecrets.empty()) { + GTEST_SKIP() << "Skipping the test as no shared secret service is found."; + } + auto fixup_hmac = finally([&]() { computeAllSharedSecrets(getAllSharedSecretParameters()); }); + + auto params = getAllSharedSecretParameters(); + ASSERT_EQ(sharedSecrets.size(), params.size()) + << "One or more shared secret services failed to provide parameters."; + + // All should be well in the normal case + auto responses = computeAllSharedSecrets(params); + + ASSERT_GT(responses.size(), 0U); + vector correct_response = responses[0].sharing_check; + verifyResponses(correct_response, responses); + + // Pick a random param and shorten that nonce by one. + size_t param_to_tweak = rand() % params.size(); + auto& to_tweak = params[param_to_tweak].nonce; + ASSERT_TRUE(to_tweak.size() == 32); + to_tweak.resize(31); + + responses = computeAllSharedSecrets(params); + for (size_t i = 0; i < responses.size(); ++i) { + if (i == param_to_tweak) { + EXPECT_EQ(ErrorCode::INVALID_ARGUMENT, responses[i].error) + << "Shared secret service that provided tweaked param should fail to compute " + "shared secret"; + } else { + EXPECT_EQ(ErrorCode::OK, responses[i].error) << "Others should succeed"; + EXPECT_NE(correct_response, responses[i].sharing_check) + << "Others should calculate a different shared secret, due to the tweaked " + "nonce."; + } + } +} + TEST_F(SharedSecretAidlTest, ComputeSharedSecretCorruptSeed) { auto sharedSecrets = allSharedSecrets(); if (sharedSecrets.empty()) { @@ -275,6 +317,45 @@ TEST_F(SharedSecretAidlTest, ComputeSharedSecretCorruptSeed) { } } } + +TEST_F(SharedSecretAidlTest, ComputeSharedSecretShortSeed) { + auto sharedSecrets = allSharedSecrets(); + if (sharedSecrets.empty()) { + GTEST_SKIP() << "Skipping the test as no shared secret service is found."; + } + auto fixup_hmac = finally([&]() { computeAllSharedSecrets(getAllSharedSecretParameters()); }); + auto params = getAllSharedSecretParameters(); + ASSERT_EQ(sharedSecrets.size(), params.size()) + << "One or more shared secret service failed to provide parameters."; + + // All should be well in the normal case + auto responses = computeAllSharedSecrets(params); + + ASSERT_GT(responses.size(), 0U); + vector correct_response = responses[0].sharing_check; + verifyResponses(correct_response, responses); + + // Pick a random param and modify the seed to be of (invalid) length 31. + auto param_to_tweak = rand() % params.size(); + auto& to_tweak = params[param_to_tweak].seed; + ASSERT_TRUE(to_tweak.size() == 32 || to_tweak.size() == 0); + to_tweak.resize(31); + + responses = computeAllSharedSecrets(params); + for (size_t i = 0; i < responses.size(); ++i) { + if (i == param_to_tweak) { + EXPECT_EQ(ErrorCode::INVALID_ARGUMENT, responses[i].error) + << "Shared secret service that provided tweaked param should fail to compute " + "shared secret"; + } else { + EXPECT_EQ(ErrorCode::OK, responses[i].error) << "Others should succeed"; + EXPECT_NE(correct_response, responses[i].sharing_check) + << "Others should calculate a different shared secret, due to the tweaked " + "nonce."; + } + } +} + } // namespace aidl::android::hardware::security::sharedsecret::test int main(int argc, char** argv) { -- GitLab From 3c7f0d90bac9ef33c4f43710374ce5c8fc3ca96f Mon Sep 17 00:00:00 2001 From: Lais Andrade Date: Wed, 16 Jun 2021 10:20:09 +0000 Subject: [PATCH 710/790] Fix default vibrator HAL to check support on getPrimitiveDuration Change-Id: I09219cca0a1b0bb985cae70734b0dd03cca441fc Fix: 191115802 Test: VtsHalVibratorTargetTest --- vibrator/aidl/default/Vibrator.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/vibrator/aidl/default/Vibrator.cpp b/vibrator/aidl/default/Vibrator.cpp index c6682b318f..5755ce55b6 100644 --- a/vibrator/aidl/default/Vibrator.cpp +++ b/vibrator/aidl/default/Vibrator.cpp @@ -138,6 +138,11 @@ ndk::ScopedAStatus Vibrator::getSupportedPrimitives(std::vector supported; + getSupportedPrimitives(&supported); + if (std::find(supported.begin(), supported.end(), primitive) == supported.end()) { + return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); + } if (primitive != CompositePrimitive::NOOP) { *durationMs = 100; } else { -- GitLab From f876a7d123cd7de55a9ed1e1dd90f546ab26889b Mon Sep 17 00:00:00 2001 From: Marin Shalamanov Date: Wed, 16 Jun 2021 11:37:37 +0200 Subject: [PATCH 711/790] Update OWNERS for composer/2.1/vts Update the OWNERS file to match the respective files from 2.2, 2.3 and 2.4. Bug: 188686850 Test: n/a Change-Id: I0ff9923695813da3dbec1aa94fe1a2bd988e521e --- graphics/composer/2.1/vts/OWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/graphics/composer/2.1/vts/OWNERS b/graphics/composer/2.1/vts/OWNERS index 0b42d2ef84..ea06752da7 100644 --- a/graphics/composer/2.1/vts/OWNERS +++ b/graphics/composer/2.1/vts/OWNERS @@ -1,6 +1,6 @@ # Graphics team +adyabr@google.com lpy@google.com -vhau@google.com # VTS team yim@google.com -- GitLab From 513ae73a91343b596d7cf3f7909175833250e793 Mon Sep 17 00:00:00 2001 From: Marin Shalamanov Date: Mon, 14 Jun 2021 11:07:30 +0200 Subject: [PATCH 712/790] VTS: Free allocated buffers The native handle was not freed which causes some devices to run out of memory when executing the test. This change creates a RAII wrapper around native_handle_t, which automatically deallocates buffers when they go out of scope. Bug: 188686850 Test: atest VtsHalGraphicsComposerV2_4TargetTest Change-Id: I19a22a5a3202e048de77926ce4a116a31d9de906 --- .../composer/2.1/utils/vts/ComposerVts.cpp | 20 +++-- .../include/composer-vts/2.1/ComposerVts.h | 23 ++++- .../VtsHalGraphicsComposerV2_1TargetTest.cpp | 28 +++--- .../composer/2.2/utils/vts/ReadbackVts.cpp | 54 ++++-------- .../include/composer-vts/2.2/ComposerVts.h | 8 +- .../include/composer-vts/2.2/ReadbackVts.h | 9 +- ...VtsHalGraphicsComposerV2_2ReadbackTest.cpp | 28 +++--- .../VtsHalGraphicsComposerV2_2TargetTest.cpp | 23 +++-- .../VtsHalGraphicsComposerV2_3TargetTest.cpp | 8 -- .../VtsHalGraphicsComposerV2_4TargetTest.cpp | 87 ++++++++++--------- 10 files changed, 146 insertions(+), 142 deletions(-) diff --git a/graphics/composer/2.1/utils/vts/ComposerVts.cpp b/graphics/composer/2.1/utils/vts/ComposerVts.cpp index 4b6b7c86b8..55aaf12b8e 100644 --- a/graphics/composer/2.1/utils/vts/ComposerVts.cpp +++ b/graphics/composer/2.1/utils/vts/ComposerVts.cpp @@ -308,6 +308,12 @@ void ComposerClient::execute(TestCommandReader* reader, CommandWriterBase* write writer->reset(); } +NativeHandleWrapper::~NativeHandleWrapper() { + if (mHandle) { + mGralloc.freeBuffer(mHandle); + } +} + Gralloc::Gralloc() { [this] { ASSERT_NO_FATAL_FAILURE(mGralloc4 = std::make_shared("default", "default", @@ -324,9 +330,10 @@ Gralloc::Gralloc() { }(); } -const native_handle_t* Gralloc::allocate(uint32_t width, uint32_t height, uint32_t layerCount, - PixelFormat format, uint64_t usage, bool import, - uint32_t* outStride) { +const NativeHandleWrapper Gralloc::allocate(uint32_t width, uint32_t height, uint32_t layerCount, + PixelFormat format, uint64_t usage, bool import, + uint32_t* outStride) { + const native_handle_t* handle; if (mGralloc4) { IMapper4::BufferDescriptorInfo info{}; info.width = width; @@ -334,7 +341,7 @@ const native_handle_t* Gralloc::allocate(uint32_t width, uint32_t height, uint32 info.layerCount = layerCount; info.format = static_cast(format); info.usage = usage; - return mGralloc4->allocate(info, import, outStride); + handle = mGralloc4->allocate(info, import, outStride); } else if (mGralloc3) { IMapper3::BufferDescriptorInfo info{}; info.width = width; @@ -342,7 +349,7 @@ const native_handle_t* Gralloc::allocate(uint32_t width, uint32_t height, uint32 info.layerCount = layerCount; info.format = static_cast(format); info.usage = usage; - return mGralloc3->allocate(info, import, outStride); + handle = mGralloc3->allocate(info, import, outStride); } else { IMapper2::BufferDescriptorInfo info{}; info.width = width; @@ -350,8 +357,9 @@ const native_handle_t* Gralloc::allocate(uint32_t width, uint32_t height, uint32 info.layerCount = layerCount; info.format = format; info.usage = usage; - return mGralloc2->allocate(info, import, outStride); + handle = mGralloc2->allocate(info, import, outStride); } + return NativeHandleWrapper(*this, handle); } void* Gralloc::lock(const native_handle_t* bufferHandle, uint64_t cpuUsage, diff --git a/graphics/composer/2.1/utils/vts/include/composer-vts/2.1/ComposerVts.h b/graphics/composer/2.1/utils/vts/include/composer-vts/2.1/ComposerVts.h index 63aa713e54..2949823364 100644 --- a/graphics/composer/2.1/utils/vts/include/composer-vts/2.1/ComposerVts.h +++ b/graphics/composer/2.1/utils/vts/include/composer-vts/2.1/ComposerVts.h @@ -136,13 +136,30 @@ class AccessRegion { int32_t height; }; +class Gralloc; + +// RAII wrapper around native_handle_t* +class NativeHandleWrapper { + public: + NativeHandleWrapper(Gralloc& gralloc, const native_handle_t* handle) + : mGralloc(gralloc), mHandle(handle) {} + + ~NativeHandleWrapper(); + + const native_handle_t* get() { return mHandle; } + + private: + Gralloc& mGralloc; + const native_handle_t* mHandle; +}; + class Gralloc { public: explicit Gralloc(); - const native_handle_t* allocate(uint32_t width, uint32_t height, uint32_t layerCount, - PixelFormat format, uint64_t usage, bool import = true, - uint32_t* outStride = nullptr); + const NativeHandleWrapper allocate(uint32_t width, uint32_t height, uint32_t layerCount, + PixelFormat format, uint64_t usage, bool import = true, + uint32_t* outStride = nullptr); void* lock(const native_handle_t* bufferHandle, uint64_t cpuUsage, const AccessRegion& accessRegionRect, int acquireFence); diff --git a/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp b/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp index f0250c07f3..48226785d5 100644 --- a/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp +++ b/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp @@ -666,7 +666,7 @@ class GraphicsComposerHidlCommandTest : public GraphicsComposerHidlTest { ASSERT_NO_FATAL_FAILURE(GraphicsComposerHidlTest::TearDown()); } - const native_handle_t* allocate() { + NativeHandleWrapper allocate() { uint64_t usage = static_cast(BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN | BufferUsage::COMPOSER_OVERLAY); @@ -727,11 +727,11 @@ TEST_P(GraphicsComposerHidlCommandTest, SET_OUTPUT_BUFFER) { display = mComposerClient->createVirtualDisplay(64, 64, PixelFormat::IMPLEMENTATION_DEFINED, kBufferSlotCount, &format)); - const native_handle_t* handle; - ASSERT_NO_FATAL_FAILURE(handle = allocate()); + std::unique_ptr handle; + ASSERT_NO_FATAL_FAILURE(handle.reset(new NativeHandleWrapper(allocate()))); mWriter->selectDisplay(display); - mWriter->setOutputBuffer(0, handle, -1); + mWriter->setOutputBuffer(0, handle->get(), -1); execute(); } @@ -783,7 +783,7 @@ TEST_P(GraphicsComposerHidlCommandTest, PRESENT_DISPLAY_NO_LAYER_STATE_CHANGES) mComposerClient->setColorMode(mPrimaryDisplay, ColorMode::NATIVE); auto handle = allocate(); - ASSERT_NE(nullptr, handle); + ASSERT_NE(nullptr, handle.get()); IComposerClient::Rect displayFrame{0, 0, mDisplayWidth, mDisplayHeight}; @@ -800,7 +800,7 @@ TEST_P(GraphicsComposerHidlCommandTest, PRESENT_DISPLAY_NO_LAYER_STATE_CHANGES) mWriter->setLayerZOrder(10); mWriter->setLayerBlendMode(IComposerClient::BlendMode::NONE); mWriter->setLayerSurfaceDamage(std::vector(1, displayFrame)); - mWriter->setLayerBuffer(0, handle, -1); + mWriter->setLayerBuffer(0, handle.get(), -1); mWriter->setLayerDataspace(Dataspace::UNKNOWN); mWriter->validateDisplay(); @@ -817,8 +817,8 @@ TEST_P(GraphicsComposerHidlCommandTest, PRESENT_DISPLAY_NO_LAYER_STATE_CHANGES) mWriter->selectLayer(layer); auto handle2 = allocate(); - ASSERT_NE(nullptr, handle2); - mWriter->setLayerBuffer(0, handle2, -1); + ASSERT_NE(nullptr, handle2.get()); + mWriter->setLayerBuffer(0, handle2.get(), -1); mWriter->setLayerSurfaceDamage(std::vector(1, {0, 0, 10, 10})); mWriter->presentDisplay(); execute(); @@ -833,12 +833,12 @@ TEST_P(GraphicsComposerHidlCommandTest, SET_LAYER_CURSOR_POSITION) { mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount)); auto handle = allocate(); - ASSERT_NE(nullptr, handle); + ASSERT_NE(nullptr, handle.get()); IComposerClient::Rect displayFrame{0, 0, mDisplayWidth, mDisplayHeight}; mWriter->selectDisplay(mPrimaryDisplay); mWriter->selectLayer(layer); - mWriter->setLayerBuffer(0, handle, -1); + mWriter->setLayerBuffer(0, handle.get(), -1); mWriter->setLayerCompositionType(IComposerClient::Composition::CURSOR); mWriter->setLayerDisplayFrame(displayFrame); mWriter->setLayerPlaneAlpha(1); @@ -871,7 +871,7 @@ TEST_P(GraphicsComposerHidlCommandTest, SET_LAYER_CURSOR_POSITION) { */ TEST_P(GraphicsComposerHidlCommandTest, SET_LAYER_BUFFER) { auto handle = allocate(); - ASSERT_NE(nullptr, handle); + ASSERT_NE(nullptr, handle.get()); Layer layer; ASSERT_NO_FATAL_FAILURE(layer = @@ -879,7 +879,7 @@ TEST_P(GraphicsComposerHidlCommandTest, SET_LAYER_BUFFER) { mWriter->selectDisplay(mPrimaryDisplay); mWriter->selectLayer(layer); - mWriter->setLayerBuffer(0, handle, -1); + mWriter->setLayerBuffer(0, handle.get(), -1); execute(); } @@ -1003,7 +1003,7 @@ TEST_P(GraphicsComposerHidlCommandTest, SET_LAYER_SIDEBAND_STREAM) { } auto handle = allocate(); - ASSERT_NE(nullptr, handle); + ASSERT_NE(nullptr, handle.get()); Layer layer; ASSERT_NO_FATAL_FAILURE(layer = @@ -1011,7 +1011,7 @@ TEST_P(GraphicsComposerHidlCommandTest, SET_LAYER_SIDEBAND_STREAM) { mWriter->selectDisplay(mPrimaryDisplay); mWriter->selectLayer(layer); - mWriter->setLayerSidebandStream(handle); + mWriter->setLayerSidebandStream(handle.get()); execute(); } diff --git a/graphics/composer/2.2/utils/vts/ReadbackVts.cpp b/graphics/composer/2.2/utils/vts/ReadbackVts.cpp index 19f5e8c614..30596fc4c9 100644 --- a/graphics/composer/2.2/utils/vts/ReadbackVts.cpp +++ b/graphics/composer/2.2/utils/vts/ReadbackVts.cpp @@ -208,22 +208,13 @@ ReadbackBuffer::ReadbackBuffer(Display display, const std::shared_ptrfreeBuffer(mBufferHandle); - } -} - void ReadbackBuffer::setReadbackBuffer() { - if (mBufferHandle != nullptr) { - mGralloc->freeBuffer(mBufferHandle); - mBufferHandle = nullptr; - } - mBufferHandle = mGralloc->allocate(mWidth, mHeight, mLayerCount, mFormat, mUsage, - /*import*/ true, &mStride); - ASSERT_NE(false, mGralloc->validateBufferSize(mBufferHandle, mWidth, mHeight, mLayerCount, - mFormat, mUsage, mStride)); - ASSERT_NO_FATAL_FAILURE(mComposerClient->setReadbackBuffer(mDisplay, mBufferHandle, -1)); + mBufferHandle.reset(new Gralloc::NativeHandleWrapper( + mGralloc->allocate(mWidth, mHeight, mLayerCount, mFormat, mUsage, + /*import*/ true, &mStride))); + ASSERT_NE(false, mGralloc->validateBufferSize(mBufferHandle->get(), mWidth, mHeight, + mLayerCount, mFormat, mUsage, mStride)); + ASSERT_NO_FATAL_FAILURE(mComposerClient->setReadbackBuffer(mDisplay, mBufferHandle->get(), -1)); } void ReadbackBuffer::checkReadbackBuffer(std::vector expectedColors) { @@ -231,11 +222,11 @@ void ReadbackBuffer::checkReadbackBuffer(std::vector exp int32_t fenceHandle; ASSERT_NO_FATAL_FAILURE(mComposerClient->getReadbackBufferFence(mDisplay, &fenceHandle)); - void* bufData = mGralloc->lock(mBufferHandle, mUsage, mAccessRegion, fenceHandle); + void* bufData = mGralloc->lock(mBufferHandle->get(), mUsage, mAccessRegion, fenceHandle); ASSERT_TRUE(mPixelFormat == PixelFormat::RGB_888 || mPixelFormat == PixelFormat::RGBA_8888); ReadbackHelper::compareColorBuffers(expectedColors, bufData, mStride, mWidth, mHeight, mPixelFormat); - int32_t unlockFence = mGralloc->unlock(mBufferHandle); + int32_t unlockFence = mGralloc->unlock(mBufferHandle->get()); if (unlockFence != -1) { sync_wait(unlockFence, -1); close(unlockFence); @@ -281,23 +272,17 @@ TestBufferLayer::TestBufferLayer(const std::shared_ptr& client, setSourceCrop({0, 0, (float)width, (float)height}); } -TestBufferLayer::~TestBufferLayer() { - if (mBufferHandle != nullptr) { - mGralloc->freeBuffer(mBufferHandle); - } -} - void TestBufferLayer::write(const std::shared_ptr& writer) { TestLayer::write(writer); writer->setLayerCompositionType(mComposition); writer->setLayerVisibleRegion(std::vector(1, mDisplayFrame)); - if (mBufferHandle != nullptr) writer->setLayerBuffer(0, mBufferHandle, mFillFence); + if (mBufferHandle != nullptr) writer->setLayerBuffer(0, mBufferHandle->get(), mFillFence); } LayerSettings TestBufferLayer::toRenderEngineLayerSettings() { LayerSettings layerSettings = TestLayer::toRenderEngineLayerSettings(); layerSettings.source.buffer.buffer = std::make_shared( - new GraphicBuffer(mBufferHandle, GraphicBuffer::CLONE_HANDLE, mWidth, mHeight, + new GraphicBuffer(mBufferHandle->get(), GraphicBuffer::CLONE_HANDLE, mWidth, mHeight, static_cast(mFormat), 1, mUsage, mStride), mRenderEngine.getInternalRenderEngine(), renderengine::ExternalTexture::Usage::READABLE); @@ -318,10 +303,10 @@ LayerSettings TestBufferLayer::toRenderEngineLayerSettings() { } void TestBufferLayer::fillBuffer(std::vector expectedColors) { - void* bufData = mGralloc->lock(mBufferHandle, mUsage, mAccessRegion, -1); + void* bufData = mGralloc->lock(mBufferHandle->get(), mUsage, mAccessRegion, -1); ASSERT_NO_FATAL_FAILURE( ReadbackHelper::fillBuffer(mWidth, mHeight, mStride, bufData, mFormat, expectedColors)); - mFillFence = mGralloc->unlock(mBufferHandle); + mFillFence = mGralloc->unlock(mBufferHandle->get()); if (mFillFence != -1) { sync_wait(mFillFence, -1); close(mFillFence); @@ -329,16 +314,13 @@ void TestBufferLayer::fillBuffer(std::vector expectedCol } void TestBufferLayer::setBuffer(std::vector colors) { - if (mBufferHandle != nullptr) { - mGralloc->freeBuffer(mBufferHandle); - mBufferHandle = nullptr; - } - mBufferHandle = mGralloc->allocate(mWidth, mHeight, mLayerCount, mFormat, mUsage, - /*import*/ true, &mStride); - ASSERT_NE(nullptr, mBufferHandle); + mBufferHandle.reset(new Gralloc::NativeHandleWrapper( + mGralloc->allocate(mWidth, mHeight, mLayerCount, mFormat, mUsage, + /*import*/ true, &mStride))); + ASSERT_NE(nullptr, mBufferHandle->get()); ASSERT_NO_FATAL_FAILURE(fillBuffer(colors)); - ASSERT_NE(false, mGralloc->validateBufferSize(mBufferHandle, mWidth, mHeight, mLayerCount, - mFormat, mUsage, mStride)); + ASSERT_NE(false, mGralloc->validateBufferSize(mBufferHandle->get(), mWidth, mHeight, + mLayerCount, mFormat, mUsage, mStride)); } void TestBufferLayer::setDataspace(Dataspace dataspace, diff --git a/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ComposerVts.h b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ComposerVts.h index 6bc2732d7d..d3bba17ed3 100644 --- a/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ComposerVts.h +++ b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ComposerVts.h @@ -93,10 +93,12 @@ class ComposerClient : public V2_1::vts::ComposerClient { class Gralloc : public V2_1::vts::Gralloc { public: + using NativeHandleWrapper = V2_1::vts::NativeHandleWrapper; + Gralloc(); - const native_handle_t* allocate(uint32_t width, uint32_t height, uint32_t layerCount, - PixelFormat format, uint64_t usage, bool import = true, - uint32_t* outStride = nullptr) { + const NativeHandleWrapper allocate(uint32_t width, uint32_t height, uint32_t layerCount, + PixelFormat format, uint64_t usage, bool import = true, + uint32_t* outStride = nullptr) { return V2_1::vts::Gralloc::allocate( width, height, layerCount, static_cast(format), usage, diff --git a/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ReadbackVts.h b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ReadbackVts.h index b24e3b63bd..58efde9b5a 100644 --- a/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ReadbackVts.h +++ b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ReadbackVts.h @@ -25,6 +25,8 @@ #include #include +#include + namespace android { namespace hardware { namespace graphics { @@ -116,8 +118,6 @@ class TestBufferLayer : public TestLayer { PixelFormat format, IComposerClient::Composition composition = IComposerClient::Composition::DEVICE); - ~TestBufferLayer(); - void write(const std::shared_ptr& writer) override; LayerSettings toRenderEngineLayerSettings() override; @@ -143,7 +143,7 @@ class TestBufferLayer : public TestLayer { std::shared_ptr mGralloc; TestRenderEngine& mRenderEngine; int32_t mFillFence; - const native_handle_t* mBufferHandle = nullptr; + std::unique_ptr mBufferHandle; }; class ReadbackHelper { @@ -182,7 +182,6 @@ class ReadbackBuffer { ReadbackBuffer(Display display, const std::shared_ptr& client, const std::shared_ptr& gralloc, uint32_t width, uint32_t height, PixelFormat pixelFormat, Dataspace dataspace); - ~ReadbackBuffer(); void setReadbackBuffer(); @@ -196,7 +195,7 @@ class ReadbackBuffer { uint64_t mUsage; AccessRegion mAccessRegion; uint32_t mStride; - const native_handle_t* mBufferHandle = nullptr; + std::unique_ptr mBufferHandle = nullptr; PixelFormat mPixelFormat; Dataspace mDataspace; Display mDisplay; diff --git a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp index 8d52173e59..7a1568bd9f 100644 --- a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp +++ b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp @@ -39,15 +39,13 @@ namespace V2_2 { namespace vts { namespace { -using android::GraphicBuffer; using android::Rect; -using android::hardware::hidl_handle; using common::V1_1::BufferUsage; using common::V1_1::Dataspace; using common::V1_1::PixelFormat; -using mapper::V2_1::IMapper; using V2_1::Config; using V2_1::Display; +using V2_1::vts::NativeHandleWrapper; using V2_1::vts::TestCommandReader; using vts::Gralloc; @@ -355,9 +353,9 @@ TEST_P(GraphicsCompositionTest, SetLayerBufferNoEffect) { // This following buffer call should have no effect uint64_t usage = static_cast(BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN); - const native_handle_t* bufferHandle = + NativeHandleWrapper bufferHandle = mGralloc->allocate(mDisplayWidth, mDisplayHeight, 1, PixelFormat::RGBA_8888, usage); - mWriter->setLayerBuffer(0, bufferHandle, -1); + mWriter->setLayerBuffer(0, bufferHandle.get(), -1); // expected color for each pixel std::vector expectedColors(mDisplayWidth * mDisplayHeight); @@ -465,24 +463,24 @@ TEST_P(GraphicsCompositionTest, ClientComposition) { // create client target buffer uint32_t clientStride; - const native_handle_t* clientBufferHandle = + NativeHandleWrapper clientBufferHandle = mGralloc->allocate(layer->mWidth, layer->mHeight, layer->mLayerCount, clientFormat, clientUsage, /*import*/ true, &clientStride); - ASSERT_NE(nullptr, clientBufferHandle); + ASSERT_NE(nullptr, clientBufferHandle.get()); void* clientBufData = - mGralloc->lock(clientBufferHandle, clientUsage, layer->mAccessRegion, -1); + mGralloc->lock(clientBufferHandle.get(), clientUsage, layer->mAccessRegion, -1); ASSERT_NO_FATAL_FAILURE(ReadbackHelper::fillBuffer(layer->mWidth, layer->mHeight, clientStride, clientBufData, clientFormat, expectedColors)); - int clientFence = mGralloc->unlock(clientBufferHandle); + int clientFence = mGralloc->unlock(clientBufferHandle.get()); if (clientFence != -1) { sync_wait(clientFence, -1); close(clientFence); } - mWriter->setClientTarget(0, clientBufferHandle, clientFence, clientDataspace, + mWriter->setClientTarget(0, clientBufferHandle.get(), clientFence, clientDataspace, std::vector(1, damage)); layer->setToClientComposition(mWriter); @@ -593,12 +591,12 @@ TEST_P(GraphicsCompositionTest, DeviceAndClientComposition) { // create client target buffer ASSERT_EQ(1, mReader->mCompositionChanges[0].second); uint32_t clientStride; - const native_handle_t* clientBufferHandle = + NativeHandleWrapper clientBufferHandle = mGralloc->allocate(mDisplayWidth, mDisplayHeight, clientLayer->mLayerCount, clientFormat, clientUsage, /*import*/ true, &clientStride); - ASSERT_NE(nullptr, clientBufferHandle); + ASSERT_NE(nullptr, clientBufferHandle.get()); - void* clientBufData = mGralloc->lock(clientBufferHandle, clientUsage, + void* clientBufData = mGralloc->lock(clientBufferHandle.get(), clientUsage, {0, 0, mDisplayWidth, mDisplayHeight}, -1); std::vector clientColors(mDisplayWidth * mDisplayHeight); @@ -606,13 +604,13 @@ TEST_P(GraphicsCompositionTest, DeviceAndClientComposition) { ASSERT_NO_FATAL_FAILURE(ReadbackHelper::fillBuffer(mDisplayWidth, mDisplayHeight, clientStride, clientBufData, clientFormat, clientColors)); - int clientFence = mGralloc->unlock(clientBufferHandle); + int clientFence = mGralloc->unlock(clientBufferHandle.get()); if (clientFence != -1) { sync_wait(clientFence, -1); close(clientFence); } - mWriter->setClientTarget(0, clientBufferHandle, clientFence, clientDataspace, + mWriter->setClientTarget(0, clientBufferHandle.get(), clientFence, clientDataspace, std::vector(1, clientFrame)); clientLayer->setToClientComposition(mWriter); mWriter->validateDisplay(); diff --git a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp index 31ec88513c..7e25a2e125 100644 --- a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp +++ b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp @@ -36,13 +36,11 @@ namespace vts { namespace { using common::V1_0::BufferUsage; -using common::V1_0::ColorTransform; -using common::V1_0::Transform; using common::V1_1::ColorMode; using common::V1_1::Dataspace; using common::V1_1::PixelFormat; using common::V1_1::RenderIntent; -using mapper::V2_0::IMapper; +using V2_1::vts::NativeHandleWrapper; class GraphicsComposerHidlTest : public ::testing::TestWithParam { protected: @@ -154,7 +152,7 @@ class GraphicsComposerHidlCommandTest : public GraphicsComposerHidlTest { ASSERT_NO_FATAL_FAILURE(GraphicsComposerHidlTest::TearDown()); } - const native_handle_t* allocate() { + NativeHandleWrapper allocate() { uint64_t usage = static_cast(BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN); return mGralloc->allocate(/*width*/ 64, /*height*/ 64, /*layerCount*/ 1, @@ -440,12 +438,12 @@ TEST_P(GraphicsComposerHidlTest, SetReadbackBuffer) { static_cast(BufferUsage::COMPOSER_OVERLAY | BufferUsage::CPU_READ_OFTEN); std::unique_ptr gralloc; - const native_handle_t* buffer; + std::unique_ptr buffer; ASSERT_NO_FATAL_FAILURE(gralloc = std::make_unique()); - ASSERT_NO_FATAL_FAILURE(buffer = gralloc->allocate(mDisplayWidth, mDisplayHeight, 1, - mReadbackPixelFormat, usage)); + ASSERT_NO_FATAL_FAILURE(buffer.reset(new NativeHandleWrapper( + gralloc->allocate(mDisplayWidth, mDisplayHeight, 1, mReadbackPixelFormat, usage)))); - mComposerClient->setReadbackBuffer(mPrimaryDisplay, buffer, -1); + mComposerClient->setReadbackBuffer(mPrimaryDisplay, buffer->get(), -1); } /** @@ -463,12 +461,13 @@ TEST_P(GraphicsComposerHidlTest, SetReadbackBufferBadDisplay) { static_cast(BufferUsage::COMPOSER_OVERLAY | BufferUsage::CPU_READ_OFTEN); std::unique_ptr gralloc; - const native_handle_t* buffer; + std::unique_ptr buffer; ASSERT_NO_FATAL_FAILURE(gralloc = std::make_unique()); - ASSERT_NO_FATAL_FAILURE(buffer = gralloc->allocate(mDisplayWidth, mDisplayHeight, 1, - mReadbackPixelFormat, usage)); + ASSERT_NO_FATAL_FAILURE(buffer.reset(new NativeHandleWrapper( + gralloc->allocate(mDisplayWidth, mDisplayHeight, 1, mReadbackPixelFormat, usage)))); - Error error = mComposerClient->getRaw()->setReadbackBuffer(mInvalidDisplayId, buffer, nullptr); + Error error = + mComposerClient->getRaw()->setReadbackBuffer(mInvalidDisplayId, buffer->get(), nullptr); ASSERT_EQ(Error::BAD_DISPLAY, error); } diff --git a/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp b/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp index 8b42654a55..54ba79dcc1 100644 --- a/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp +++ b/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp @@ -38,12 +38,10 @@ namespace V2_3 { namespace vts { namespace { -using common::V1_0::BufferUsage; using common::V1_1::RenderIntent; using common::V1_2::ColorMode; using common::V1_2::Dataspace; using common::V1_2::PixelFormat; -using mapper::V2_0::IMapper; using V2_2::vts::Gralloc; class GraphicsComposerHidlTest : public ::testing::TestWithParam { @@ -140,12 +138,6 @@ class GraphicsComposerHidlCommandTest : public GraphicsComposerHidlTest { ASSERT_NO_FATAL_FAILURE(GraphicsComposerHidlTest::TearDown()); } - const native_handle_t* allocate() { - return mGralloc->allocate( - 64, 64, 1, static_cast(PixelFormat::RGBA_8888), - static_cast(BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN)); - } - void execute() { mComposerClient->execute(mReader.get(), mWriter.get()); } std::unique_ptr mWriter; diff --git a/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp b/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp index 2f0429c01c..5aceda721e 100644 --- a/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp +++ b/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp @@ -52,8 +52,8 @@ using common::V1_1::RenderIntent; using common::V1_2::ColorMode; using common::V1_2::Dataspace; using common::V1_2::PixelFormat; -using mapper::V2_0::IMapper; using V2_1::Layer; +using V2_1::vts::NativeHandleWrapper; using V2_2::Transform; using V2_2::vts::Gralloc; @@ -159,7 +159,7 @@ class GraphicsComposerHidlTest : public ::testing::TestWithParam { void execute() { mComposerClient->execute(mReader.get(), mWriter.get()); } - const native_handle_t* allocate(int32_t width, int32_t height) { + NativeHandleWrapper allocate(int32_t width, int32_t height) { return mGralloc->allocate( width, height, /*layerCount*/ 1, static_cast(PixelFormat::RGBA_8888), @@ -493,46 +493,53 @@ void GraphicsComposerHidlTest::sendRefreshFrame(const VtsDisplay& display, IComposerClient::FRect displayCrop = display.getCrop(); int32_t displayWidth = static_cast(std::ceilf(displayCrop.right - displayCrop.left)); int32_t displayHeight = static_cast(std::ceilf(displayCrop.bottom - displayCrop.top)); - auto handle = allocate(displayWidth, displayHeight); - ASSERT_NE(nullptr, handle); - Layer layer; ASSERT_NO_FATAL_FAILURE(layer = mComposerClient->createLayer(display.get(), kBufferSlotCount)); - mWriter->selectLayer(layer); - mWriter->setLayerCompositionType(IComposerClient::Composition::DEVICE); - mWriter->setLayerDisplayFrame(display.getFrameRect()); - mWriter->setLayerPlaneAlpha(1); - mWriter->setLayerSourceCrop(display.getCrop()); - mWriter->setLayerTransform(static_cast(0)); - mWriter->setLayerVisibleRegion(std::vector(1, display.getFrameRect())); - mWriter->setLayerZOrder(10); - mWriter->setLayerBlendMode(IComposerClient::BlendMode::NONE); - mWriter->setLayerSurfaceDamage(std::vector(1, display.getFrameRect())); - mWriter->setLayerBuffer(0, handle, -1); - mWriter->setLayerDataspace(Dataspace::UNKNOWN); - - mWriter->validateDisplay(); - execute(); - ASSERT_EQ(0, mReader->mErrors.size()); - mReader->mCompositionChanges.clear(); - - mWriter->presentDisplay(); - execute(); - ASSERT_EQ(0, mReader->mErrors.size()); - - mWriter->selectLayer(layer); - auto handle2 = allocate(displayWidth, displayHeight); - ASSERT_NE(nullptr, handle2); - - mWriter->setLayerBuffer(0, handle2, -1); - mWriter->setLayerSurfaceDamage(std::vector(1, {0, 0, 10, 10})); - mWriter->validateDisplay(); - execute(); - ASSERT_EQ(0, mReader->mErrors.size()); - mReader->mCompositionChanges.clear(); - - mWriter->presentDisplay(); - execute(); + + { + auto handle = allocate(displayWidth, displayHeight); + ASSERT_NE(nullptr, handle.get()); + + mWriter->selectLayer(layer); + mWriter->setLayerCompositionType(IComposerClient::Composition::DEVICE); + mWriter->setLayerDisplayFrame(display.getFrameRect()); + mWriter->setLayerPlaneAlpha(1); + mWriter->setLayerSourceCrop(display.getCrop()); + mWriter->setLayerTransform(static_cast(0)); + mWriter->setLayerVisibleRegion( + std::vector(1, display.getFrameRect())); + mWriter->setLayerZOrder(10); + mWriter->setLayerBlendMode(IComposerClient::BlendMode::NONE); + mWriter->setLayerSurfaceDamage( + std::vector(1, display.getFrameRect())); + mWriter->setLayerBuffer(0, handle.get(), -1); + mWriter->setLayerDataspace(Dataspace::UNKNOWN); + + mWriter->validateDisplay(); + execute(); + ASSERT_EQ(0, mReader->mErrors.size()); + mReader->mCompositionChanges.clear(); + + mWriter->presentDisplay(); + execute(); + ASSERT_EQ(0, mReader->mErrors.size()); + } + + { + auto handle = allocate(displayWidth, displayHeight); + ASSERT_NE(nullptr, handle.get()); + + mWriter->selectLayer(layer); + mWriter->setLayerBuffer(0, handle.get(), -1); + mWriter->setLayerSurfaceDamage(std::vector(1, {0, 0, 10, 10})); + mWriter->validateDisplay(); + execute(); + ASSERT_EQ(0, mReader->mErrors.size()); + mReader->mCompositionChanges.clear(); + + mWriter->presentDisplay(); + execute(); + } ASSERT_NO_FATAL_FAILURE(mComposerClient->destroyLayer(display.get(), layer)); } -- GitLab From 149320003e99b0d4a4f43dfe1f69387c6c8388ae Mon Sep 17 00:00:00 2001 From: Lais Andrade Date: Wed, 16 Jun 2021 13:37:37 +0100 Subject: [PATCH 713/790] Fix vibrator VTS failure on older HAL versions Fixing tests missed by ag/14937086. Fix: 186481596 Test: VtsHalVibratorTargetTest Change-Id: Ib4b4885a99effb6c010573146f5b016872f7a202 --- vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp index 4d49a12661..c56bd9a4d4 100644 --- a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp +++ b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp @@ -309,8 +309,8 @@ TEST_P(VibratorAidl, InvalidEffectsUnsupported) { for (EffectStrength strength : kEffectStrengths) { int32_t lengthMs; Status status = vibrator->perform(effect, strength, nullptr /*callback*/, &lengthMs); - EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION) - << toString(effect) << " " << toString(strength); + EXPECT_TRUE(isUnknownOrUnsupported(status)) + << status << toString(effect) << " " << toString(strength); } } for (Effect effect : kEffects) { @@ -686,7 +686,7 @@ TEST_P(VibratorAidl, GetPwlePrimitiveDurationMax) { ASSERT_NE(durationMs, 0); EXPECT_EQ(status.exceptionCode(), Status::EX_NONE); } else { - EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION); + EXPECT_TRUE(isUnknownOrUnsupported(status)) << status; } } -- GitLab From a7e867a9113677b19360baf6ac93b6f48a9d50c5 Mon Sep 17 00:00:00 2001 From: Eran Messeri Date: Tue, 8 Jun 2021 11:38:31 +0100 Subject: [PATCH 714/790] Test validity of device-unique attestation chain Test the validity of the chain produced when device-unique attestation is requested. When the caller requests that the key attestation be signed using the device-unique attestation key, the chain will look different than a chain signed by the batch key (common case): (1) The chain is exactly of length 2. (2) The root is self-signed and is unique to the device. Test that the chain is correctly signed in this change. The root is not currently correctly self-signed, so don't test (2) yet. Bug: 189425310 Bug: 187803288 Test: atest VtsHalKeymasterV4_1TargetTest:PerInstance/DeviceUniqueAttestationTest Ignore-AOSP-First: Already merged in aosp Merged-In: I91578eb2b7588685cc86c467423e9394c3f3c262 Change-Id: I7e83ba7c9c8c68b95b1456fb37bb5aa939c4e6f8 --- .../DeviceUniqueAttestationTest.cpp | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/keymaster/4.1/vts/functional/DeviceUniqueAttestationTest.cpp b/keymaster/4.1/vts/functional/DeviceUniqueAttestationTest.cpp index 0639da8ab1..3d97daf274 100644 --- a/keymaster/4.1/vts/functional/DeviceUniqueAttestationTest.cpp +++ b/keymaster/4.1/vts/functional/DeviceUniqueAttestationTest.cpp @@ -16,6 +16,7 @@ #define LOG_TAG "keymaster_hidl_hal_test" #include +#include #include "Keymaster4_1HidlTest.h" @@ -178,6 +179,33 @@ void check_attestation_record(AttestationRecord attestation, const HidlBuf& chal << DIFFERENCE(expected_hw_enforced, attestation.hardware_enforced); } +X509_Ptr parse_cert_blob(const std::vector& blob) { + const uint8_t* p = blob.data(); + return X509_Ptr(d2i_X509(nullptr /* allocate new */, &p, blob.size())); +} + +bool check_certificate_chain_signatures(const hidl_vec>& cert_chain) { + // TODO: Check that root is self-signed once b/187803288 is resolved. + for (size_t i = 0; i < cert_chain.size() - 1; ++i) { + X509_Ptr key_cert(parse_cert_blob(cert_chain[i])); + X509_Ptr signing_cert(parse_cert_blob(cert_chain[i + 1])); + + if (!key_cert.get() || !signing_cert.get()) { + return false; + } + + EVP_PKEY_Ptr signing_pubkey(X509_get_pubkey(signing_cert.get())); + if (!signing_pubkey.get()) { + return false; + } + + if (!X509_verify(key_cert.get(), signing_pubkey.get())) { + return false; + } + } + return true; +} + } // namespace using std::string; @@ -243,6 +271,7 @@ TEST_P(DeviceUniqueAttestationTest, Rsa) { EXPECT_EQ(ErrorCode::OK, result); EXPECT_EQ(2U, cert_chain.size()); + EXPECT_TRUE(check_certificate_chain_signatures(cert_chain)); if (dumpAttestations) { for (auto cert_ : cert_chain) dumpContent(bin2hex(cert_)); } @@ -289,6 +318,7 @@ TEST_P(DeviceUniqueAttestationTest, Ecdsa) { EXPECT_EQ(ErrorCode::OK, result); EXPECT_EQ(2U, cert_chain.size()); + EXPECT_TRUE(check_certificate_chain_signatures(cert_chain)); if (dumpAttestations) { for (auto cert_ : cert_chain) dumpContent(bin2hex(cert_)); } -- GitLab From a9ce01cfed8367e01ea8a2ec5dd142229b5cf4d4 Mon Sep 17 00:00:00 2001 From: Eran Messeri Date: Thu, 27 May 2021 15:08:03 +0100 Subject: [PATCH 715/790] Improve unique attestation docs & tests Improve the documentation and tests related to device-unique attestation on StrongBox KeyMint devices: * Test that the chain produced is exactly of length 2. * Document how the chain needs to be structured. * Explain the trust properties of the key used for the self-signed root. Test: atest VtsAidlKeyMintTargetTest Bug: 187803288 Ignore-AOSP-First: Already merged in AOSP Merged-In: I09bb16d6938b567c114485d2df00bde9d3e1ccf9 Change-Id: Ib7efdd428ce5a2e14c281077e3a77048c9721702 --- .../hardware/security/keymint/Tag.aidl | 20 ++++++++++++++----- .../DeviceUniqueAttestationTest.cpp | 5 ++++- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl index 4ff4574b58..58e02b35b2 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl @@ -831,14 +831,24 @@ enum Tag { /** * DEVICE_UNIQUE_ATTESTATION is an argument to IKeyMintDevice::attested key generation/import * operations. It indicates that attestation using a device-unique key is requested, rather - * than a batch key. When a device-unique key is used, only the attestation certificate is - * returned; no additional chained certificates are provided. It's up to the caller to - * recognize the device-unique signing key. Only SecurityLevel::STRONGBOX IKeyMintDevices may - * support device-unique attestations. SecurityLevel::TRUSTED_ENVIRONMENT IKeyMintDevices must - * return ErrorCode::INVALID_ARGUMENT if they receive DEVICE_UNIQUE_ATTESTATION. + * than a batch key. When a device-unique key is used, the returned chain should contain two + * certificates: + * * The attestation certificate, containing the attestation extension, as described in + KeyCreationResult.aidl. + * * A self-signed root certificate, signed by the device-unique key. + * No additional chained certificates are provided. Only SecurityLevel::STRONGBOX + * IKeyMintDevices may support device-unique attestations. SecurityLevel::TRUSTED_ENVIRONMENT + * IKeyMintDevices must return ErrorCode::INVALID_ARGUMENT if they receive + * DEVICE_UNIQUE_ATTESTATION. * SecurityLevel::STRONGBOX IKeyMintDevices need not support DEVICE_UNIQUE_ATTESTATION, and * return ErrorCode::CANNOT_ATTEST_IDS if they do not support it. * + * The caller needs to obtain the device-unique keys out-of-band and compare them against the + * key used to sign the self-signed root certificate. + * To ease this process, the IKeyMintDevice implementation should include, both in the subject + * and issuer fields of the self-signed root, the unique identifier of the device. Using the + * unique identifier will make it straightforward for the caller to link a device to its key. + * * IKeyMintDevice implementations that support device-unique attestation MUST add the * DEVICE_UNIQUE_ATTESTATION tag to device-unique attestations. */ diff --git a/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp b/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp index b0f056a68c..732d9ebadd 100644 --- a/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp +++ b/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp @@ -42,8 +42,11 @@ class DeviceUniqueAttestationTest : public KeyMintAidlTestBase { EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size)) << "Key size missing"; + // The device-unique attestation chain should contain exactly two certificates: + // * The leaf with the attestation extension. + // * A self-signed root, signed using the device-unique key. + ASSERT_EQ(cert_chain_.size(), 2); EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_)); - ASSERT_GT(cert_chain_.size(), 0); AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics); EXPECT_TRUE(verify_attestation_record("challenge", "foo", sw_enforced, hw_enforced, -- GitLab From 03346e175efdf30e204560dd0c574d2d6c343eaa Mon Sep 17 00:00:00 2001 From: David Drysdale Date: Mon, 14 Jun 2021 14:46:02 +0100 Subject: [PATCH 716/790] KeyMint VTS: improve attestation tests Check that the various ATTESTATION_ID_* tags are included if they have the correct value, and that keygen fails if they have an invalid value. Also update attestation tags to include vendor/boot patchlevel if they're available. (They always should be, but fixing that is a separate task.) Bug: 190757200 Test: VtsAidlKeyMintTargetTest Change-Id: Ibaed7364c6d08c0982e2a9fb6cb864ae42cf39fe --- .../aidl/vts/functional/AttestKeyTest.cpp | 122 +++++++++++- .../DeviceUniqueAttestationTest.cpp | 186 +++++++++++++++--- .../aidl/vts/functional/KeyMintAidlTestBase.h | 11 ++ 3 files changed, 290 insertions(+), 29 deletions(-) diff --git a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp index ae2becdf9b..a3127237ac 100644 --- a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp +++ b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp @@ -556,7 +556,7 @@ TEST_P(AttestKeyTest, AllEcCurves) { .EcdsaSigningKey(curve) .AttestKey() .SetDefaultValidity(), - {} /* attestation siging key */, &attest_key.keyBlob, + {} /* attestation signing key */, &attest_key.keyBlob, &attest_key_characteristics, &attest_key_cert_chain)); ASSERT_GT(attest_key_cert_chain.size(), 0); @@ -640,7 +640,7 @@ TEST_P(AttestKeyTest, AttestWithNonAttestKey) { ErrorCode::OK, GenerateKey( AuthorizationSetBuilder().EcdsaSigningKey(EcCurve::P_256).SetDefaultValidity(), - {} /* attestation siging key */, &non_attest_key.keyBlob, + {} /* attestation signing key */, &non_attest_key.keyBlob, &non_attest_key_characteristics, &non_attest_key_cert_chain)); ASSERT_GT(non_attest_key_cert_chain.size(), 0); @@ -662,6 +662,124 @@ TEST_P(AttestKeyTest, AttestWithNonAttestKey) { &attested_key_cert_chain)); } +TEST_P(AttestKeyTest, EcdsaAttestationID) { + // Create attestation key. + AttestationKey attest_key; + vector attest_key_characteristics; + vector attest_key_cert_chain; + ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() + .EcdsaSigningKey(EcCurve::P_256) + .AttestKey() + .SetDefaultValidity(), + {} /* attestation signing key */, &attest_key.keyBlob, + &attest_key_characteristics, &attest_key_cert_chain)); + attest_key.issuerSubjectName = make_name_from_str("Android Keystore Key"); + ASSERT_GT(attest_key_cert_chain.size(), 0); + EXPECT_EQ(attest_key_cert_chain.size(), 1); + EXPECT_TRUE(IsSelfSigned(attest_key_cert_chain)); + + // Collection of valid attestation ID tags. + auto attestation_id_tags = AuthorizationSetBuilder(); + add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_BRAND, "ro.product.brand"); + add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_DEVICE, "ro.product.device"); + add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_PRODUCT, "ro.product.name"); + add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_SERIAL, "ro.serial"); + add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_MANUFACTURER, + "ro.product.manufacturer"); + add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_MODEL, "ro.product.model"); + + for (const KeyParameter& tag : attestation_id_tags) { + SCOPED_TRACE(testing::Message() << "+tag-" << tag); + // Use attestation key to sign an ECDSA key, but include an attestation ID field. + AuthorizationSetBuilder builder = AuthorizationSetBuilder() + .EcdsaSigningKey(EcCurve::P_256) + .Authorization(TAG_NO_AUTH_REQUIRED) + .AttestationChallenge("challenge") + .AttestationApplicationId("foo") + .SetDefaultValidity(); + builder.push_back(tag); + vector attested_key_blob; + vector attested_key_characteristics; + vector attested_key_cert_chain; + auto result = GenerateKey(builder, attest_key, &attested_key_blob, + &attested_key_characteristics, &attested_key_cert_chain); + if (result == ErrorCode::CANNOT_ATTEST_IDS) { + continue; + } + + ASSERT_EQ(result, ErrorCode::OK); + + CheckedDeleteKey(&attested_key_blob); + + AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics); + AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics); + + // The attested key characteristics will not contain APPLICATION_ID_* fields (their + // spec definitions all have "Must never appear in KeyCharacteristics"), but the + // attestation extension should contain them, so make sure the extra tag is added. + hw_enforced.push_back(tag); + + EXPECT_TRUE(verify_attestation_record("challenge", "foo", sw_enforced, hw_enforced, + SecLevel(), + attested_key_cert_chain[0].encodedCertificate)); + } + CheckedDeleteKey(&attest_key.keyBlob); +} + +TEST_P(AttestKeyTest, EcdsaAttestationMismatchID) { + // Create attestation key. + AttestationKey attest_key; + vector attest_key_characteristics; + vector attest_key_cert_chain; + ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() + .EcdsaSigningKey(EcCurve::P_256) + .AttestKey() + .SetDefaultValidity(), + {} /* attestation signing key */, &attest_key.keyBlob, + &attest_key_characteristics, &attest_key_cert_chain)); + attest_key.issuerSubjectName = make_name_from_str("Android Keystore Key"); + ASSERT_GT(attest_key_cert_chain.size(), 0); + EXPECT_EQ(attest_key_cert_chain.size(), 1); + EXPECT_TRUE(IsSelfSigned(attest_key_cert_chain)); + + // Collection of invalid attestation ID tags. + auto attestation_id_tags = + AuthorizationSetBuilder() + .Authorization(TAG_ATTESTATION_ID_BRAND, "bogus-brand") + .Authorization(TAG_ATTESTATION_ID_DEVICE, "devious-device") + .Authorization(TAG_ATTESTATION_ID_PRODUCT, "punctured-product") + .Authorization(TAG_ATTESTATION_ID_SERIAL, "suspicious-serial") + .Authorization(TAG_ATTESTATION_ID_IMEI, "invalid-imei") + .Authorization(TAG_ATTESTATION_ID_MEID, "mismatching-meid") + .Authorization(TAG_ATTESTATION_ID_MANUFACTURER, "malformed-manufacturer") + .Authorization(TAG_ATTESTATION_ID_MODEL, "malicious-model"); + vector key_blob; + vector key_characteristics; + + for (const KeyParameter& invalid_tag : attestation_id_tags) { + SCOPED_TRACE(testing::Message() << "+tag-" << invalid_tag); + + // Use attestation key to sign an ECDSA key, but include an invalid + // attestation ID field. + AuthorizationSetBuilder builder = AuthorizationSetBuilder() + .EcdsaSigningKey(EcCurve::P_256) + .Authorization(TAG_NO_AUTH_REQUIRED) + .AttestationChallenge("challenge") + .AttestationApplicationId("foo") + .SetDefaultValidity(); + builder.push_back(invalid_tag); + vector attested_key_blob; + vector attested_key_characteristics; + vector attested_key_cert_chain; + auto result = GenerateKey(builder, attest_key, &attested_key_blob, + &attested_key_characteristics, &attested_key_cert_chain); + + ASSERT_TRUE(result == ErrorCode::CANNOT_ATTEST_IDS || result == ErrorCode::INVALID_TAG) + << "result = " << result; + } + CheckedDeleteKey(&attest_key.keyBlob); +} + INSTANTIATE_KEYMINT_AIDL_TEST(AttestKeyTest); } // namespace aidl::android::hardware::security::keymint::test diff --git a/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp b/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp index 732d9ebadd..a3ed3ad4a0 100644 --- a/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp +++ b/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp @@ -29,7 +29,7 @@ class DeviceUniqueAttestationTest : public KeyMintAidlTestBase { protected: void CheckUniqueAttestationResults(const vector& key_blob, const vector& key_characteristics, - const AuthorizationSet& hw_enforced, int key_size) { + const AuthorizationSet& hw_enforced) { ASSERT_GT(cert_chain_.size(), 0); if (KeyMintAidlTestBase::dump_Attestations) { @@ -40,8 +40,6 @@ class DeviceUniqueAttestationTest : public KeyMintAidlTestBase { AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics); - EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size)) << "Key size missing"; - // The device-unique attestation chain should contain exactly two certificates: // * The leaf with the attestation extension. // * A self-signed root, signed using the device-unique key. @@ -136,17 +134,32 @@ TEST_P(DeviceUniqueAttestationTest, RsaDeviceUniqueAttestation) { ASSERT_EQ(ErrorCode::OK, result); - AuthorizationSet hw_enforced = AuthorizationSetBuilder() - .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION) - .Authorization(TAG_NO_AUTH_REQUIRED) - .RsaSigningKey(2048, 65537) - .Digest(Digest::SHA_2_256) - .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN) - .Authorization(TAG_ORIGIN, KeyOrigin::GENERATED) - .Authorization(TAG_OS_VERSION, os_version()) - .Authorization(TAG_OS_PATCHLEVEL, os_patch_level()); - - CheckUniqueAttestationResults(key_blob, key_characteristics, hw_enforced, key_size); + AuthorizationSetBuilder hw_enforced = + AuthorizationSetBuilder() + .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION) + .Authorization(TAG_NO_AUTH_REQUIRED) + .RsaSigningKey(2048, 65537) + .Digest(Digest::SHA_2_256) + .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN) + .Authorization(TAG_ORIGIN, KeyOrigin::GENERATED) + .Authorization(TAG_OS_VERSION, os_version()) + .Authorization(TAG_OS_PATCHLEVEL, os_patch_level()); + + // Any patchlevels attached to the key should also be present in the attestation extension. + AuthorizationSet auths; + for (const auto& entry : key_characteristics) { + auths.push_back(AuthorizationSet(entry.authorizations)); + } + auto vendor_pl = auths.GetTagValue(TAG_VENDOR_PATCHLEVEL); + if (vendor_pl) { + hw_enforced.Authorization(TAG_VENDOR_PATCHLEVEL, *vendor_pl); + } + auto boot_pl = auths.GetTagValue(TAG_BOOT_PATCHLEVEL); + if (boot_pl) { + hw_enforced.Authorization(TAG_BOOT_PATCHLEVEL, *boot_pl); + } + + CheckUniqueAttestationResults(key_blob, key_characteristics, hw_enforced); } /* @@ -160,11 +173,10 @@ TEST_P(DeviceUniqueAttestationTest, EcdsaDeviceUniqueAttestation) { vector key_blob; vector key_characteristics; - int key_size = 256; auto result = GenerateKey(AuthorizationSetBuilder() .Authorization(TAG_NO_AUTH_REQUIRED) - .EcdsaSigningKey(256) + .EcdsaSigningKey(EcCurve::P_256) .Digest(Digest::SHA_2_256) .Authorization(TAG_INCLUDE_UNIQUE_ID) .AttestationChallenge("challenge") @@ -176,17 +188,137 @@ TEST_P(DeviceUniqueAttestationTest, EcdsaDeviceUniqueAttestation) { if (result == ErrorCode::CANNOT_ATTEST_IDS) return; ASSERT_EQ(ErrorCode::OK, result); - AuthorizationSet hw_enforced = AuthorizationSetBuilder() - .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION) - .Authorization(TAG_NO_AUTH_REQUIRED) - .EcdsaSigningKey(EcCurve::P_256) - .Digest(Digest::SHA_2_256) - .Authorization(TAG_EC_CURVE, EcCurve::P_256) - .Authorization(TAG_ORIGIN, KeyOrigin::GENERATED) - .Authorization(TAG_OS_VERSION, os_version()) - .Authorization(TAG_OS_PATCHLEVEL, os_patch_level()); - - CheckUniqueAttestationResults(key_blob, key_characteristics, hw_enforced, key_size); + AuthorizationSetBuilder hw_enforced = + AuthorizationSetBuilder() + .Authorization(TAG_NO_AUTH_REQUIRED) + .EcdsaSigningKey(EcCurve::P_256) + .Digest(Digest::SHA_2_256) + .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION) + .Authorization(TAG_ORIGIN, KeyOrigin::GENERATED) + .Authorization(TAG_OS_VERSION, os_version()) + .Authorization(TAG_OS_PATCHLEVEL, os_patch_level()); + // Any patchlevels attached to the key should also be present in the attestation extension. + AuthorizationSet auths; + for (const auto& entry : key_characteristics) { + auths.push_back(AuthorizationSet(entry.authorizations)); + } + auto vendor_pl = auths.GetTagValue(TAG_VENDOR_PATCHLEVEL); + if (vendor_pl) { + hw_enforced.Authorization(TAG_VENDOR_PATCHLEVEL, *vendor_pl); + } + auto boot_pl = auths.GetTagValue(TAG_BOOT_PATCHLEVEL); + if (boot_pl) { + hw_enforced.Authorization(TAG_BOOT_PATCHLEVEL, *boot_pl); + } + + CheckUniqueAttestationResults(key_blob, key_characteristics, hw_enforced); +} + +/* + * DeviceUniqueAttestationTest.EcdsaDeviceUniqueAttestationID + * + * Verifies that device unique attestation can include IDs that do match the + * local device. + */ +TEST_P(DeviceUniqueAttestationTest, EcdsaDeviceUniqueAttestationID) { + if (SecLevel() != SecurityLevel::STRONGBOX) return; + + // Collection of valid attestation ID tags. + auto attestation_id_tags = AuthorizationSetBuilder(); + add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_BRAND, "ro.product.brand"); + add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_DEVICE, "ro.product.device"); + add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_PRODUCT, "ro.product.name"); + add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_SERIAL, "ro.serial"); + add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_MANUFACTURER, + "ro.product.manufacturer"); + add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_MODEL, "ro.product.model"); + vector key_blob; + vector key_characteristics; + + for (const KeyParameter& tag : attestation_id_tags) { + SCOPED_TRACE(testing::Message() << "+tag-" << tag); + AuthorizationSetBuilder builder = AuthorizationSetBuilder() + .Authorization(TAG_NO_AUTH_REQUIRED) + .EcdsaSigningKey(EcCurve::P_256) + .Digest(Digest::SHA_2_256) + .Authorization(TAG_INCLUDE_UNIQUE_ID) + .AttestationChallenge("challenge") + .AttestationApplicationId("foo") + .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION); + builder.push_back(tag); + auto result = GenerateKey(builder, &key_blob, &key_characteristics); + + // It is optional for Strong box to support DeviceUniqueAttestation. + if (result == ErrorCode::CANNOT_ATTEST_IDS) return; + ASSERT_EQ(ErrorCode::OK, result); + + AuthorizationSetBuilder hw_enforced = + AuthorizationSetBuilder() + .Authorization(TAG_NO_AUTH_REQUIRED) + .EcdsaSigningKey(EcCurve::P_256) + .Digest(Digest::SHA_2_256) + .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION) + .Authorization(TAG_ORIGIN, KeyOrigin::GENERATED) + .Authorization(TAG_OS_VERSION, os_version()) + .Authorization(TAG_OS_PATCHLEVEL, os_patch_level()); + // Expect the specified tag to be present in the attestation extension. + hw_enforced.push_back(tag); + // Any patchlevels attached to the key should also be present in the attestation extension. + AuthorizationSet auths; + for (const auto& entry : key_characteristics) { + auths.push_back(AuthorizationSet(entry.authorizations)); + } + auto vendor_pl = auths.GetTagValue(TAG_VENDOR_PATCHLEVEL); + if (vendor_pl) { + hw_enforced.Authorization(TAG_VENDOR_PATCHLEVEL, *vendor_pl); + } + auto boot_pl = auths.GetTagValue(TAG_BOOT_PATCHLEVEL); + if (boot_pl) { + hw_enforced.Authorization(TAG_BOOT_PATCHLEVEL, *boot_pl); + } + CheckUniqueAttestationResults(key_blob, key_characteristics, hw_enforced); + } +} + +/* + * DeviceUniqueAttestationTest.EcdsaDeviceUniqueAttestationMismatchID + * + * Verifies that device unique attestation rejects attempts to attest to IDs that + * don't match the local device. + */ +TEST_P(DeviceUniqueAttestationTest, EcdsaDeviceUniqueAttestationMismatchID) { + if (SecLevel() != SecurityLevel::STRONGBOX) return; + + // Collection of invalid attestation ID tags. + auto attestation_id_tags = + AuthorizationSetBuilder() + .Authorization(TAG_ATTESTATION_ID_BRAND, "bogus-brand") + .Authorization(TAG_ATTESTATION_ID_DEVICE, "devious-device") + .Authorization(TAG_ATTESTATION_ID_PRODUCT, "punctured-product") + .Authorization(TAG_ATTESTATION_ID_SERIAL, "suspicious-serial") + .Authorization(TAG_ATTESTATION_ID_IMEI, "invalid-imei") + .Authorization(TAG_ATTESTATION_ID_MEID, "mismatching-meid") + .Authorization(TAG_ATTESTATION_ID_MANUFACTURER, "malformed-manufacturer") + .Authorization(TAG_ATTESTATION_ID_MODEL, "malicious-model"); + vector key_blob; + vector key_characteristics; + + for (const KeyParameter& invalid_tag : attestation_id_tags) { + SCOPED_TRACE(testing::Message() << "+tag-" << invalid_tag); + AuthorizationSetBuilder builder = AuthorizationSetBuilder() + .Authorization(TAG_NO_AUTH_REQUIRED) + .EcdsaSigningKey(EcCurve::P_256) + .Digest(Digest::SHA_2_256) + .Authorization(TAG_INCLUDE_UNIQUE_ID) + .AttestationChallenge("challenge") + .AttestationApplicationId("foo") + .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION); + // Add the tag that doesn't match the local device's real ID. + builder.push_back(invalid_tag); + auto result = GenerateKey(builder, &key_blob, &key_characteristics); + + ASSERT_TRUE(result == ErrorCode::CANNOT_ATTEST_IDS || result == ErrorCode::INVALID_TAG); + } } INSTANTIATE_KEYMINT_AIDL_TEST(DeviceUniqueAttestationTest); diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h index 4d31fa4d36..82f192aa49 100644 --- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h +++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -313,6 +314,16 @@ class KeyMintAidlTestBase : public ::testing::TestWithParam { long challenge_; }; +// If the given property is available, add it to the tag set under the given tag ID. +template +void add_tag_from_prop(AuthorizationSetBuilder* tags, TypedTag ttag, + const char* prop) { + std::string prop_value = ::android::base::GetProperty(prop, /* default= */ ""); + if (!prop_value.empty()) { + tags->Authorization(ttag, prop_value.data(), prop_value.size()); + } +} + vector build_serial_blob(const uint64_t serial_int); void verify_subject(const X509* cert, const string& subject, bool self_signed); void verify_serial(X509* cert, const uint64_t expected_serial); -- GitLab From 66ab046f1851ecdb1b7078f6641e24025ded583e Mon Sep 17 00:00:00 2001 From: David Drysdale Date: Tue, 15 Jun 2021 10:11:12 +0100 Subject: [PATCH 717/790] KeyMaster VTS: improve attestation tests Check that the various ATTESTATION_ID_* tags are included if they have the correct value, and that keygen fails if they have an invalid value. Also fix the support libraries to add the missing fields to the ASN.1 schema and fix the existing ordering. Bug: 190757200 Test: VtsHalKeymasterV4_1TargetTest, VtsHalKeymasterV4_0TargetTest Change-Id: I11d28d71676d44ebdc79b25b2eb70947022bb1cf Ignore-AOSP-First: to be cross-merged manually --- keymaster/4.0/support/attestation_record.cpp | 111 +++++++++++------ .../functional/keymaster_hidl_hal_test.cpp | 101 +++++++++++++++ keymaster/4.1/support/attestation_record.cpp | 48 ++++++-- .../include/keymasterV4_1/keymaster_tags.h | 8 ++ .../DeviceUniqueAttestationTest.cpp | 115 +++++++++++++++++- .../4.1/vts/functional/Keymaster4_1HidlTest.h | 16 +++ 6 files changed, 350 insertions(+), 49 deletions(-) diff --git a/keymaster/4.0/support/attestation_record.cpp b/keymaster/4.0/support/attestation_record.cpp index bc294bd35b..342b3e2525 100644 --- a/keymaster/4.0/support/attestation_record.cpp +++ b/keymaster/4.0/support/attestation_record.cpp @@ -71,6 +71,7 @@ typedef struct km_auth_list { ASN1_INTEGER_SET* padding; ASN1_INTEGER* ec_curve; ASN1_INTEGER* rsa_public_exponent; + ASN1_NULL* rollback_resistance; ASN1_INTEGER* active_date_time; ASN1_INTEGER* origination_expire_date_time; ASN1_INTEGER* usage_expire_date_time; @@ -78,56 +79,84 @@ typedef struct km_auth_list { ASN1_INTEGER* user_auth_type; ASN1_INTEGER* auth_timeout; ASN1_NULL* allow_while_on_body; + ASN1_NULL* trusted_user_presence_required; + ASN1_NULL* trusted_confirmation_required; + ASN1_NULL* unlocked_device_required; ASN1_NULL* all_applications; ASN1_OCTET_STRING* application_id; ASN1_INTEGER* creation_date_time; ASN1_INTEGER* origin; - ASN1_NULL* rollback_resistance; KM_ROOT_OF_TRUST* root_of_trust; ASN1_INTEGER* os_version; ASN1_INTEGER* os_patchlevel; ASN1_OCTET_STRING* attestation_application_id; - ASN1_NULL* trusted_user_presence_required; - ASN1_NULL* trusted_confirmation_required; - ASN1_NULL* unlocked_device_required; + ASN1_OCTET_STRING* attestation_id_brand; + ASN1_OCTET_STRING* attestation_id_device; + ASN1_OCTET_STRING* attestation_id_product; + ASN1_OCTET_STRING* attestation_id_serial; + ASN1_OCTET_STRING* attestation_id_imei; + ASN1_OCTET_STRING* attestation_id_meid; + ASN1_OCTET_STRING* attestation_id_manufacturer; + ASN1_OCTET_STRING* attestation_id_model; ASN1_INTEGER* vendor_patchlevel; ASN1_INTEGER* boot_patchlevel; } KM_AUTH_LIST; ASN1_SEQUENCE(KM_AUTH_LIST) = { - ASN1_EXP_SET_OF_OPT(KM_AUTH_LIST, purpose, ASN1_INTEGER, TAG_PURPOSE.maskedTag()), - ASN1_EXP_OPT(KM_AUTH_LIST, algorithm, ASN1_INTEGER, TAG_ALGORITHM.maskedTag()), - ASN1_EXP_OPT(KM_AUTH_LIST, key_size, ASN1_INTEGER, TAG_KEY_SIZE.maskedTag()), - ASN1_EXP_SET_OF_OPT(KM_AUTH_LIST, digest, ASN1_INTEGER, TAG_DIGEST.maskedTag()), - ASN1_EXP_SET_OF_OPT(KM_AUTH_LIST, padding, ASN1_INTEGER, TAG_PADDING.maskedTag()), - ASN1_EXP_OPT(KM_AUTH_LIST, ec_curve, ASN1_INTEGER, TAG_EC_CURVE.maskedTag()), - ASN1_EXP_OPT(KM_AUTH_LIST, rsa_public_exponent, ASN1_INTEGER, - TAG_RSA_PUBLIC_EXPONENT.maskedTag()), - ASN1_EXP_OPT(KM_AUTH_LIST, rollback_resistance, ASN1_NULL, TAG_ROLLBACK_RESISTANCE.maskedTag()), - ASN1_EXP_OPT(KM_AUTH_LIST, active_date_time, ASN1_INTEGER, TAG_ACTIVE_DATETIME.maskedTag()), - ASN1_EXP_OPT(KM_AUTH_LIST, origination_expire_date_time, ASN1_INTEGER, - TAG_ORIGINATION_EXPIRE_DATETIME.maskedTag()), - ASN1_EXP_OPT(KM_AUTH_LIST, usage_expire_date_time, ASN1_INTEGER, - TAG_USAGE_EXPIRE_DATETIME.maskedTag()), - ASN1_EXP_OPT(KM_AUTH_LIST, no_auth_required, ASN1_NULL, TAG_NO_AUTH_REQUIRED.maskedTag()), - ASN1_EXP_OPT(KM_AUTH_LIST, user_auth_type, ASN1_INTEGER, TAG_USER_AUTH_TYPE.maskedTag()), - ASN1_EXP_OPT(KM_AUTH_LIST, auth_timeout, ASN1_INTEGER, TAG_AUTH_TIMEOUT.maskedTag()), - ASN1_EXP_OPT(KM_AUTH_LIST, allow_while_on_body, ASN1_NULL, TAG_ALLOW_WHILE_ON_BODY.maskedTag()), - ASN1_EXP_OPT(KM_AUTH_LIST, trusted_user_presence_required, ASN1_NULL, - TAG_TRUSTED_USER_PRESENCE_REQUIRED.maskedTag()), - ASN1_EXP_OPT(KM_AUTH_LIST, trusted_confirmation_required, ASN1_NULL, - TAG_TRUSTED_CONFIRMATION_REQUIRED.maskedTag()), - ASN1_EXP_OPT(KM_AUTH_LIST, unlocked_device_required, ASN1_NULL, - TAG_UNLOCKED_DEVICE_REQUIRED.maskedTag()), - ASN1_EXP_OPT(KM_AUTH_LIST, creation_date_time, ASN1_INTEGER, TAG_CREATION_DATETIME.maskedTag()), - ASN1_EXP_OPT(KM_AUTH_LIST, origin, ASN1_INTEGER, TAG_ORIGIN.maskedTag()), - ASN1_EXP_OPT(KM_AUTH_LIST, root_of_trust, KM_ROOT_OF_TRUST, TAG_ROOT_OF_TRUST.maskedTag()), - ASN1_EXP_OPT(KM_AUTH_LIST, os_version, ASN1_INTEGER, TAG_OS_VERSION.maskedTag()), - ASN1_EXP_OPT(KM_AUTH_LIST, os_patchlevel, ASN1_INTEGER, TAG_OS_PATCHLEVEL.maskedTag()), - ASN1_EXP_OPT(KM_AUTH_LIST, vendor_patchlevel, ASN1_INTEGER, TAG_VENDOR_PATCHLEVEL.maskedTag()), - ASN1_EXP_OPT(KM_AUTH_LIST, boot_patchlevel, ASN1_INTEGER, TAG_BOOT_PATCHLEVEL.maskedTag()), - ASN1_EXP_OPT(KM_AUTH_LIST, attestation_application_id, ASN1_OCTET_STRING, - TAG_ATTESTATION_APPLICATION_ID.maskedTag()), + ASN1_EXP_SET_OF_OPT(KM_AUTH_LIST, purpose, ASN1_INTEGER, TAG_PURPOSE.maskedTag()), + ASN1_EXP_OPT(KM_AUTH_LIST, algorithm, ASN1_INTEGER, TAG_ALGORITHM.maskedTag()), + ASN1_EXP_OPT(KM_AUTH_LIST, key_size, ASN1_INTEGER, TAG_KEY_SIZE.maskedTag()), + ASN1_EXP_SET_OF_OPT(KM_AUTH_LIST, digest, ASN1_INTEGER, TAG_DIGEST.maskedTag()), + ASN1_EXP_SET_OF_OPT(KM_AUTH_LIST, padding, ASN1_INTEGER, TAG_PADDING.maskedTag()), + ASN1_EXP_OPT(KM_AUTH_LIST, ec_curve, ASN1_INTEGER, TAG_EC_CURVE.maskedTag()), + ASN1_EXP_OPT(KM_AUTH_LIST, rsa_public_exponent, ASN1_INTEGER, + TAG_RSA_PUBLIC_EXPONENT.maskedTag()), + ASN1_EXP_OPT(KM_AUTH_LIST, rollback_resistance, ASN1_NULL, + TAG_ROLLBACK_RESISTANCE.maskedTag()), + + ASN1_EXP_OPT(KM_AUTH_LIST, active_date_time, ASN1_INTEGER, TAG_ACTIVE_DATETIME.maskedTag()), + ASN1_EXP_OPT(KM_AUTH_LIST, origination_expire_date_time, ASN1_INTEGER, + TAG_ORIGINATION_EXPIRE_DATETIME.maskedTag()), + ASN1_EXP_OPT(KM_AUTH_LIST, usage_expire_date_time, ASN1_INTEGER, + TAG_USAGE_EXPIRE_DATETIME.maskedTag()), + ASN1_EXP_OPT(KM_AUTH_LIST, no_auth_required, ASN1_NULL, TAG_NO_AUTH_REQUIRED.maskedTag()), + ASN1_EXP_OPT(KM_AUTH_LIST, user_auth_type, ASN1_INTEGER, TAG_USER_AUTH_TYPE.maskedTag()), + ASN1_EXP_OPT(KM_AUTH_LIST, auth_timeout, ASN1_INTEGER, TAG_AUTH_TIMEOUT.maskedTag()), + ASN1_EXP_OPT(KM_AUTH_LIST, allow_while_on_body, ASN1_NULL, + TAG_ALLOW_WHILE_ON_BODY.maskedTag()), + ASN1_EXP_OPT(KM_AUTH_LIST, trusted_user_presence_required, ASN1_NULL, + TAG_TRUSTED_USER_PRESENCE_REQUIRED.maskedTag()), + ASN1_EXP_OPT(KM_AUTH_LIST, trusted_confirmation_required, ASN1_NULL, + TAG_TRUSTED_CONFIRMATION_REQUIRED.maskedTag()), + ASN1_EXP_OPT(KM_AUTH_LIST, unlocked_device_required, ASN1_NULL, + TAG_UNLOCKED_DEVICE_REQUIRED.maskedTag()), + ASN1_EXP_OPT(KM_AUTH_LIST, creation_date_time, ASN1_INTEGER, + TAG_CREATION_DATETIME.maskedTag()), + ASN1_EXP_OPT(KM_AUTH_LIST, origin, ASN1_INTEGER, TAG_ORIGIN.maskedTag()), + ASN1_EXP_OPT(KM_AUTH_LIST, root_of_trust, KM_ROOT_OF_TRUST, TAG_ROOT_OF_TRUST.maskedTag()), + ASN1_EXP_OPT(KM_AUTH_LIST, os_version, ASN1_INTEGER, TAG_OS_VERSION.maskedTag()), + ASN1_EXP_OPT(KM_AUTH_LIST, os_patchlevel, ASN1_INTEGER, TAG_OS_PATCHLEVEL.maskedTag()), + ASN1_EXP_OPT(KM_AUTH_LIST, attestation_application_id, ASN1_OCTET_STRING, + TAG_ATTESTATION_APPLICATION_ID.maskedTag()), + ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_brand, ASN1_OCTET_STRING, + TAG_ATTESTATION_ID_BRAND.maskedTag()), + ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_device, ASN1_OCTET_STRING, + TAG_ATTESTATION_ID_DEVICE.maskedTag()), + ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_product, ASN1_OCTET_STRING, + TAG_ATTESTATION_ID_PRODUCT.maskedTag()), + ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_serial, ASN1_OCTET_STRING, + TAG_ATTESTATION_ID_SERIAL.maskedTag()), + ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_imei, ASN1_OCTET_STRING, + TAG_ATTESTATION_ID_IMEI.maskedTag()), + ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_meid, ASN1_OCTET_STRING, + TAG_ATTESTATION_ID_MEID.maskedTag()), + ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_manufacturer, ASN1_OCTET_STRING, + TAG_ATTESTATION_ID_MANUFACTURER.maskedTag()), + ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_model, ASN1_OCTET_STRING, + TAG_ATTESTATION_ID_MODEL.maskedTag()), + ASN1_EXP_OPT(KM_AUTH_LIST, vendor_patchlevel, ASN1_INTEGER, + TAG_VENDOR_PATCHLEVEL.maskedTag()), + ASN1_EXP_OPT(KM_AUTH_LIST, boot_patchlevel, ASN1_INTEGER, TAG_BOOT_PATCHLEVEL.maskedTag()), } ASN1_SEQUENCE_END(KM_AUTH_LIST); IMPLEMENT_ASN1_FUNCTIONS(KM_AUTH_LIST); @@ -259,6 +288,14 @@ static ErrorCode extract_auth_list(const KM_AUTH_LIST* record, AuthorizationSet* copyAuthTag(record->usage_expire_date_time, TAG_USAGE_EXPIRE_DATETIME, auth_list); copyAuthTag(record->user_auth_type, TAG_USER_AUTH_TYPE, auth_list); copyAuthTag(record->attestation_application_id, TAG_ATTESTATION_APPLICATION_ID, auth_list); + copyAuthTag(record->attestation_id_brand, TAG_ATTESTATION_ID_BRAND, auth_list); + copyAuthTag(record->attestation_id_device, TAG_ATTESTATION_ID_DEVICE, auth_list); + copyAuthTag(record->attestation_id_product, TAG_ATTESTATION_ID_PRODUCT, auth_list); + copyAuthTag(record->attestation_id_serial, TAG_ATTESTATION_ID_SERIAL, auth_list); + copyAuthTag(record->attestation_id_imei, TAG_ATTESTATION_ID_IMEI, auth_list); + copyAuthTag(record->attestation_id_meid, TAG_ATTESTATION_ID_MEID, auth_list); + copyAuthTag(record->attestation_id_manufacturer, TAG_ATTESTATION_ID_MANUFACTURER, auth_list); + copyAuthTag(record->attestation_id_model, TAG_ATTESTATION_ID_MODEL, auth_list); copyAuthTag(record->vendor_patchlevel, TAG_VENDOR_PATCHLEVEL, auth_list); copyAuthTag(record->boot_patchlevel, TAG_BOOT_PATCHLEVEL, auth_list); copyAuthTag(record->trusted_user_presence_required, TAG_TRUSTED_USER_PRESENCE_REQUIRED, 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 9e37ed0a44..01c502c586 100644 --- a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp +++ b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp @@ -96,6 +96,18 @@ bool contains(hidl_vec& set, TypedTag) { return count > 0; } +// If the given property is available, add it to the tag set under the given tag ID. +template +void add_tag_from_prop(AuthorizationSetBuilder* tags, TypedTag ttag, + const char* prop) { + char value[PROPERTY_VALUE_MAX]; + int len = property_get(prop, value, /* default = */ ""); + if (len > 0) { + tags->Authorization(ttag, reinterpret_cast(value), + static_cast(len)); + } +} + constexpr char hex_value[256] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // @@ -4408,6 +4420,95 @@ TEST_P(AttestationTest, EcAttestation) { SecLevel(), cert_chain[0])); } +/* + * AttestationTest.EcAttestationID + * + * Verifies that attesting to EC keys with correct attestation ID fields works and generates the + * expected output. + */ +TEST_P(AttestationTest, EcAttestationID) { + ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() + .Authorization(TAG_NO_AUTH_REQUIRED) + .EcdsaSigningKey(EcCurve::P_256) + .Digest(Digest::SHA_2_256) + .Authorization(TAG_INCLUDE_UNIQUE_ID))); + + // Collection of valid attestation ID tags. + auto attestation_id_tags = AuthorizationSetBuilder(); + add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_BRAND, "ro.product.brand"); + add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_DEVICE, "ro.product.device"); + add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_PRODUCT, "ro.product.name"); + add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_SERIAL, "ro.serial"); + add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_MANUFACTURER, + "ro.product.manufacturer"); + add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_MODEL, "ro.product.model"); + + for (const KeyParameter& tag : attestation_id_tags) { + AuthorizationSetBuilder builder = + AuthorizationSetBuilder() + .Authorization(TAG_ATTESTATION_CHALLENGE, HidlBuf("challenge")) + .Authorization(TAG_ATTESTATION_APPLICATION_ID, HidlBuf("foo")); + // Include one of the (valid) attestation ID tags. + builder.push_back(tag); + hidl_vec> cert_chain; + auto result = AttestKey(builder, &cert_chain); + if (result == ErrorCode::CANNOT_ATTEST_IDS) { + continue; + } + + ASSERT_EQ(ErrorCode::OK, result); + EXPECT_GE(cert_chain.size(), 2U); + + std::vector expected_hw_enforced = key_characteristics_.hardwareEnforced; + expected_hw_enforced.push_back(tag); + + EXPECT_TRUE(verify_attestation_record( + "challenge", "foo", key_characteristics_.softwareEnforced, + hidl_vec(expected_hw_enforced), SecLevel(), cert_chain[0])); + } +} + +/* + * AttestationTest.EcAttestationMismatchID + * + * Verifies that attesting to EC keys with incorrect attestation ID fields fails. + */ +TEST_P(AttestationTest, EcAttestationMismatchID) { + ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() + .Authorization(TAG_NO_AUTH_REQUIRED) + .EcdsaSigningKey(EcCurve::P_256) + .Digest(Digest::SHA_2_256) + .Authorization(TAG_INCLUDE_UNIQUE_ID))); + + // Collection of invalid attestation ID tags. + std::string invalid = "completely-invalid"; + auto invalid_tags = + AuthorizationSetBuilder() + .Authorization(V4_0::TAG_ATTESTATION_ID_BRAND, invalid.data(), invalid.size()) + .Authorization(V4_0::TAG_ATTESTATION_ID_DEVICE, invalid.data(), invalid.size()) + .Authorization(V4_0::TAG_ATTESTATION_ID_PRODUCT, invalid.data(), invalid.size()) + .Authorization(V4_0::TAG_ATTESTATION_ID_SERIAL, invalid.data(), invalid.size()) + .Authorization(V4_0::TAG_ATTESTATION_ID_IMEI, invalid.data(), invalid.size()) + .Authorization(V4_0::TAG_ATTESTATION_ID_MEID, invalid.data(), invalid.size()) + .Authorization(V4_0::TAG_ATTESTATION_ID_MANUFACTURER, invalid.data(), + invalid.size()) + .Authorization(V4_0::TAG_ATTESTATION_ID_MODEL, invalid.data(), invalid.size()); + + for (const KeyParameter& invalid_tag : invalid_tags) { + AuthorizationSetBuilder builder = + AuthorizationSetBuilder() + .Authorization(TAG_ATTESTATION_CHALLENGE, HidlBuf("challenge")) + .Authorization(TAG_ATTESTATION_APPLICATION_ID, HidlBuf("foo")); + // Include one of the invalid attestation ID tags. + builder.push_back(invalid_tag); + hidl_vec> cert_chain; + auto result = AttestKey(builder, &cert_chain); + + EXPECT_TRUE(result == ErrorCode::CANNOT_ATTEST_IDS || result == ErrorCode::INVALID_TAG) + << "result: " << static_cast(result); + } +} + /* * AttestationTest.EcAttestationRequiresAttestationAppId * diff --git a/keymaster/4.1/support/attestation_record.cpp b/keymaster/4.1/support/attestation_record.cpp index 207a7e8264..15230d5def 100644 --- a/keymaster/4.1/support/attestation_record.cpp +++ b/keymaster/4.1/support/attestation_record.cpp @@ -79,6 +79,8 @@ typedef struct km_auth_list { ASN1_INTEGER_SET* padding; ASN1_INTEGER* ec_curve; ASN1_INTEGER* rsa_public_exponent; + ASN1_NULL* rollback_resistance; + ASN1_NULL* early_boot_only; ASN1_INTEGER* active_date_time; ASN1_INTEGER* origination_expire_date_time; ASN1_INTEGER* usage_expire_date_time; @@ -86,21 +88,27 @@ typedef struct km_auth_list { ASN1_INTEGER* user_auth_type; ASN1_INTEGER* auth_timeout; ASN1_NULL* allow_while_on_body; + ASN1_NULL* trusted_user_presence_required; + ASN1_NULL* trusted_confirmation_required; + ASN1_NULL* unlocked_device_required; ASN1_NULL* all_applications; ASN1_OCTET_STRING* application_id; ASN1_INTEGER* creation_date_time; ASN1_INTEGER* origin; - ASN1_NULL* rollback_resistance; KM_ROOT_OF_TRUST* root_of_trust; ASN1_INTEGER* os_version; ASN1_INTEGER* os_patchlevel; ASN1_OCTET_STRING* attestation_application_id; - ASN1_NULL* trusted_user_presence_required; - ASN1_NULL* trusted_confirmation_required; - ASN1_NULL* unlocked_device_required; + ASN1_OCTET_STRING* attestation_id_brand; + ASN1_OCTET_STRING* attestation_id_device; + ASN1_OCTET_STRING* attestation_id_product; + ASN1_OCTET_STRING* attestation_id_serial; + ASN1_OCTET_STRING* attestation_id_imei; + ASN1_OCTET_STRING* attestation_id_meid; + ASN1_OCTET_STRING* attestation_id_manufacturer; + ASN1_OCTET_STRING* attestation_id_model; ASN1_INTEGER* vendor_patchlevel; ASN1_INTEGER* boot_patchlevel; - ASN1_NULL* early_boot_only; ASN1_NULL* device_unique_attestation; ASN1_NULL* identity_credential_key; } KM_AUTH_LIST; @@ -116,6 +124,7 @@ ASN1_SEQUENCE(KM_AUTH_LIST) = { TAG_RSA_PUBLIC_EXPONENT.maskedTag()), ASN1_EXP_OPT(KM_AUTH_LIST, rollback_resistance, ASN1_NULL, TAG_ROLLBACK_RESISTANCE.maskedTag()), + ASN1_EXP_OPT(KM_AUTH_LIST, early_boot_only, ASN1_NULL, TAG_EARLY_BOOT_ONLY.maskedTag()), ASN1_EXP_OPT(KM_AUTH_LIST, active_date_time, ASN1_INTEGER, TAG_ACTIVE_DATETIME.maskedTag()), ASN1_EXP_OPT(KM_AUTH_LIST, origination_expire_date_time, ASN1_INTEGER, TAG_ORIGINATION_EXPIRE_DATETIME.maskedTag()), @@ -138,12 +147,27 @@ ASN1_SEQUENCE(KM_AUTH_LIST) = { ASN1_EXP_OPT(KM_AUTH_LIST, root_of_trust, KM_ROOT_OF_TRUST, TAG_ROOT_OF_TRUST.maskedTag()), ASN1_EXP_OPT(KM_AUTH_LIST, os_version, ASN1_INTEGER, TAG_OS_VERSION.maskedTag()), ASN1_EXP_OPT(KM_AUTH_LIST, os_patchlevel, ASN1_INTEGER, TAG_OS_PATCHLEVEL.maskedTag()), + ASN1_EXP_OPT(KM_AUTH_LIST, attestation_application_id, ASN1_OCTET_STRING, + TAG_ATTESTATION_APPLICATION_ID.maskedTag()), + ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_brand, ASN1_OCTET_STRING, + TAG_ATTESTATION_ID_BRAND.maskedTag()), + ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_device, ASN1_OCTET_STRING, + TAG_ATTESTATION_ID_DEVICE.maskedTag()), + ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_product, ASN1_OCTET_STRING, + TAG_ATTESTATION_ID_PRODUCT.maskedTag()), + ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_serial, ASN1_OCTET_STRING, + TAG_ATTESTATION_ID_SERIAL.maskedTag()), + ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_imei, ASN1_OCTET_STRING, + TAG_ATTESTATION_ID_IMEI.maskedTag()), + ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_meid, ASN1_OCTET_STRING, + TAG_ATTESTATION_ID_MEID.maskedTag()), + ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_manufacturer, ASN1_OCTET_STRING, + TAG_ATTESTATION_ID_MANUFACTURER.maskedTag()), + ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_model, ASN1_OCTET_STRING, + TAG_ATTESTATION_ID_MODEL.maskedTag()), ASN1_EXP_OPT(KM_AUTH_LIST, vendor_patchlevel, ASN1_INTEGER, TAG_VENDOR_PATCHLEVEL.maskedTag()), ASN1_EXP_OPT(KM_AUTH_LIST, boot_patchlevel, ASN1_INTEGER, TAG_BOOT_PATCHLEVEL.maskedTag()), - ASN1_EXP_OPT(KM_AUTH_LIST, attestation_application_id, ASN1_OCTET_STRING, - TAG_ATTESTATION_APPLICATION_ID.maskedTag()), - ASN1_EXP_OPT(KM_AUTH_LIST, early_boot_only, ASN1_NULL, TAG_EARLY_BOOT_ONLY.maskedTag()), ASN1_EXP_OPT(KM_AUTH_LIST, device_unique_attestation, ASN1_NULL, TAG_DEVICE_UNIQUE_ATTESTATION.maskedTag()), ASN1_EXP_OPT(KM_AUTH_LIST, identity_credential_key, ASN1_NULL, @@ -279,6 +303,14 @@ static ErrorCode extract_auth_list(const KM_AUTH_LIST* record, AuthorizationSet* copyAuthTag(record->usage_expire_date_time, TAG_USAGE_EXPIRE_DATETIME, auth_list); copyAuthTag(record->user_auth_type, TAG_USER_AUTH_TYPE, auth_list); copyAuthTag(record->attestation_application_id, TAG_ATTESTATION_APPLICATION_ID, auth_list); + copyAuthTag(record->attestation_id_brand, TAG_ATTESTATION_ID_BRAND, auth_list); + copyAuthTag(record->attestation_id_device, TAG_ATTESTATION_ID_DEVICE, auth_list); + copyAuthTag(record->attestation_id_product, TAG_ATTESTATION_ID_PRODUCT, auth_list); + copyAuthTag(record->attestation_id_serial, TAG_ATTESTATION_ID_SERIAL, auth_list); + copyAuthTag(record->attestation_id_imei, TAG_ATTESTATION_ID_IMEI, auth_list); + copyAuthTag(record->attestation_id_meid, TAG_ATTESTATION_ID_MEID, auth_list); + copyAuthTag(record->attestation_id_manufacturer, TAG_ATTESTATION_ID_MANUFACTURER, auth_list); + copyAuthTag(record->attestation_id_model, TAG_ATTESTATION_ID_MODEL, auth_list); copyAuthTag(record->vendor_patchlevel, TAG_VENDOR_PATCHLEVEL, auth_list); copyAuthTag(record->boot_patchlevel, TAG_BOOT_PATCHLEVEL, auth_list); copyAuthTag(record->trusted_user_presence_required, TAG_TRUSTED_USER_PRESENCE_REQUIRED, diff --git a/keymaster/4.1/support/include/keymasterV4_1/keymaster_tags.h b/keymaster/4.1/support/include/keymasterV4_1/keymaster_tags.h index 40eb1426ef..e8db56a85c 100644 --- a/keymaster/4.1/support/include/keymasterV4_1/keymaster_tags.h +++ b/keymaster/4.1/support/include/keymasterV4_1/keymaster_tags.h @@ -53,6 +53,14 @@ using V4_0::TAG_APPLICATION_ID; using V4_0::TAG_ASSOCIATED_DATA; using V4_0::TAG_ATTESTATION_APPLICATION_ID; using V4_0::TAG_ATTESTATION_CHALLENGE; +using V4_0::TAG_ATTESTATION_ID_BRAND; +using V4_0::TAG_ATTESTATION_ID_DEVICE; +using V4_0::TAG_ATTESTATION_ID_IMEI; +using V4_0::TAG_ATTESTATION_ID_MANUFACTURER; +using V4_0::TAG_ATTESTATION_ID_MEID; +using V4_0::TAG_ATTESTATION_ID_MODEL; +using V4_0::TAG_ATTESTATION_ID_PRODUCT; +using V4_0::TAG_ATTESTATION_ID_SERIAL; using V4_0::TAG_AUTH_TIMEOUT; using V4_0::TAG_BLOB_USAGE_REQUIREMENTS; using V4_0::TAG_BLOCK_MODE; diff --git a/keymaster/4.1/vts/functional/DeviceUniqueAttestationTest.cpp b/keymaster/4.1/vts/functional/DeviceUniqueAttestationTest.cpp index 3d97daf274..4a57f44dd9 100644 --- a/keymaster/4.1/vts/functional/DeviceUniqueAttestationTest.cpp +++ b/keymaster/4.1/vts/functional/DeviceUniqueAttestationTest.cpp @@ -27,6 +27,8 @@ #include #include +using android::hardware::keymaster::V4_0::test::add_tag_from_prop; + // Not to dump the attestation by default. Can enable by specify the parameter // "--dump_attestations" on lunching VTS static bool dumpAttestations = false; @@ -173,10 +175,15 @@ void check_attestation_record(AttestationRecord attestation, const HidlBuf& chal attestation.software_enforced.Sort(); attestation.hardware_enforced.Sort(); - EXPECT_EQ(filter_tags(expected_sw_enforced), filter_tags(attestation.software_enforced)) - << DIFFERENCE(expected_sw_enforced, attestation.software_enforced); - EXPECT_EQ(filter_tags(expected_hw_enforced), filter_tags(attestation.hardware_enforced)) - << DIFFERENCE(expected_hw_enforced, attestation.hardware_enforced); + expected_sw_enforced = filter_tags(expected_sw_enforced); + expected_hw_enforced = filter_tags(expected_hw_enforced); + AuthorizationSet attestation_sw_enforced = filter_tags(attestation.software_enforced); + AuthorizationSet attestation_hw_enforced = filter_tags(attestation.hardware_enforced); + + EXPECT_EQ(expected_sw_enforced, attestation_sw_enforced) + << DIFFERENCE(expected_sw_enforced, attestation_sw_enforced); + EXPECT_EQ(expected_hw_enforced, attestation_hw_enforced) + << DIFFERENCE(expected_hw_enforced, attestation_hw_enforced); } X509_Ptr parse_cert_blob(const std::vector& blob) { @@ -342,6 +349,106 @@ TEST_P(DeviceUniqueAttestationTest, Ecdsa) { SecLevel()); } +TEST_P(DeviceUniqueAttestationTest, EcdsaDeviceUniqueAttestationID) { + if (SecLevel() != SecurityLevel::STRONGBOX) return; + + ASSERT_EQ(ErrorCode::OK, convert(GenerateKey(AuthorizationSetBuilder() + .Authorization(TAG_NO_AUTH_REQUIRED) + .EcdsaSigningKey(256) + .Digest(Digest::SHA_2_256) + .Authorization(TAG_INCLUDE_UNIQUE_ID)))); + + // Collection of valid attestation ID tags. + auto attestation_id_tags = AuthorizationSetBuilder(); + add_tag_from_prop(&attestation_id_tags, V4_0::TAG_ATTESTATION_ID_BRAND, "ro.product.brand"); + add_tag_from_prop(&attestation_id_tags, V4_0::TAG_ATTESTATION_ID_DEVICE, "ro.product.device"); + add_tag_from_prop(&attestation_id_tags, V4_0::TAG_ATTESTATION_ID_PRODUCT, "ro.product.name"); + add_tag_from_prop(&attestation_id_tags, V4_0::TAG_ATTESTATION_ID_SERIAL, "ro.serial"); + add_tag_from_prop(&attestation_id_tags, V4_0::TAG_ATTESTATION_ID_MANUFACTURER, + "ro.product.manufacturer"); + add_tag_from_prop(&attestation_id_tags, V4_0::TAG_ATTESTATION_ID_MODEL, "ro.product.model"); + + for (const KeyParameter& tag : attestation_id_tags) { + hidl_vec> cert_chain; + HidlBuf challenge("challenge"); + HidlBuf app_id("foo"); + AuthorizationSetBuilder builder = + AuthorizationSetBuilder() + .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION) + .Authorization(TAG_ATTESTATION_CHALLENGE, challenge) + .Authorization(TAG_ATTESTATION_APPLICATION_ID, app_id); + builder.push_back(tag); + ErrorCode result = convert(AttestKey(builder, &cert_chain)); + + // It is optional for Strong box to support DeviceUniqueAttestation. + if (result == ErrorCode::CANNOT_ATTEST_IDS) return; + + ASSERT_EQ(ErrorCode::OK, result); + EXPECT_EQ(2U, cert_chain.size()); + if (dumpAttestations) { + for (auto cert_ : cert_chain) dumpContent(bin2hex(cert_)); + } + auto [err, attestation] = parse_attestation_record(cert_chain[0]); + ASSERT_EQ(ErrorCode::OK, err); + + AuthorizationSetBuilder hw_enforced = + AuthorizationSetBuilder() + .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION) + .Authorization(TAG_NO_AUTH_REQUIRED) + .EcdsaSigningKey(256) + .Digest(Digest::SHA_2_256) + .Authorization(TAG_ORIGIN, KeyOrigin::GENERATED) + .Authorization(TAG_OS_VERSION, os_version()) + .Authorization(TAG_OS_PATCHLEVEL, os_patch_level()); + hw_enforced.push_back(tag); + check_attestation_record( + attestation, challenge, + /* sw_enforced */ + AuthorizationSetBuilder().Authorization(TAG_ATTESTATION_APPLICATION_ID, app_id), + hw_enforced, SecLevel()); + } +} + +TEST_P(DeviceUniqueAttestationTest, EcdsaDeviceUniqueAttestationMismatchID) { + if (SecLevel() != SecurityLevel::STRONGBOX) return; + + ASSERT_EQ(ErrorCode::OK, convert(GenerateKey(AuthorizationSetBuilder() + .Authorization(TAG_NO_AUTH_REQUIRED) + .EcdsaSigningKey(256) + .Digest(Digest::SHA_2_256) + .Authorization(TAG_INCLUDE_UNIQUE_ID)))); + + // Collection of invalid attestation ID tags. + std::string invalid = "completely-invalid"; + auto attestation_id_tags = + AuthorizationSetBuilder() + .Authorization(V4_0::TAG_ATTESTATION_ID_BRAND, invalid.data(), invalid.size()) + .Authorization(V4_0::TAG_ATTESTATION_ID_DEVICE, invalid.data(), invalid.size()) + .Authorization(V4_0::TAG_ATTESTATION_ID_PRODUCT, invalid.data(), invalid.size()) + .Authorization(V4_0::TAG_ATTESTATION_ID_SERIAL, invalid.data(), invalid.size()) + .Authorization(V4_0::TAG_ATTESTATION_ID_IMEI, invalid.data(), invalid.size()) + .Authorization(V4_0::TAG_ATTESTATION_ID_MEID, invalid.data(), invalid.size()) + .Authorization(V4_0::TAG_ATTESTATION_ID_MANUFACTURER, invalid.data(), + invalid.size()) + .Authorization(V4_0::TAG_ATTESTATION_ID_MODEL, invalid.data(), invalid.size()); + + for (const KeyParameter& invalid_tag : attestation_id_tags) { + hidl_vec> cert_chain; + HidlBuf challenge("challenge"); + HidlBuf app_id("foo"); + AuthorizationSetBuilder builder = + AuthorizationSetBuilder() + .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION) + .Authorization(TAG_ATTESTATION_CHALLENGE, challenge) + .Authorization(TAG_ATTESTATION_APPLICATION_ID, app_id); + builder.push_back(invalid_tag); + ErrorCode result = convert(AttestKey(builder, &cert_chain)); + + EXPECT_TRUE(result == ErrorCode::CANNOT_ATTEST_IDS || result == ErrorCode::INVALID_TAG) + << "result: " << static_cast(result); + } +} + INSTANTIATE_KEYMASTER_4_1_HIDL_TEST(DeviceUniqueAttestationTest); } // namespace test diff --git a/keymaster/4.1/vts/functional/Keymaster4_1HidlTest.h b/keymaster/4.1/vts/functional/Keymaster4_1HidlTest.h index f8c1fad233..670ccfbeaf 100644 --- a/keymaster/4.1/vts/functional/Keymaster4_1HidlTest.h +++ b/keymaster/4.1/vts/functional/Keymaster4_1HidlTest.h @@ -18,6 +18,8 @@ #include +#include + #include #include @@ -159,3 +161,17 @@ bool contains(hidl_vec& set, TypedTag typedTag) { android::hardware::PrintInstanceNameToString) } // namespace android::hardware::keymaster::V4_1::test + +namespace android::hardware::keymaster::V4_0::test { + +// If the given property is available, add it to the tag set under the given tag ID. +template +void add_tag_from_prop(AuthorizationSetBuilder* tags, TypedTag ttag, + const char* prop) { + std::string prop_value = ::android::base::GetProperty(prop, /* default= */ ""); + if (!prop_value.empty()) { + tags->Authorization(ttag, prop_value.data(), prop_value.size()); + } +} + +} // namespace android::hardware::keymaster::V4_0::test -- GitLab From 0709a29350ee90e1be9fe962c717ecc3aaff65f6 Mon Sep 17 00:00:00 2001 From: Steven Moreland Date: Thu, 17 Jun 2021 18:14:28 +0000 Subject: [PATCH 718/790] freeze @1.1::ILazy, which is causing cf to fail VTS This is used on cuttlefish for tests, and so it has to be frozen like 1.0 in order to avoid having to add an exception to the test (which is considered the worst of all bad solutions here). Bug: 191115626 Test: build (hash correctness check is done at build time) Change-Id: I3bbe18e6f6e21c39f8e5efd0ddcbfb0c66385f8c --- current.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/current.txt b/current.txt index 3102972081..605f816c0a 100644 --- a/current.txt +++ b/current.txt @@ -4,6 +4,7 @@ # Test HALs 717c17cd380bb48710dff601d1a03351d4ebc28028353d5d60489248f506523c android.hardware.tests.lazy@1.0::ILazy +67222a2ed4071b6c232e671ce0f4be4f85c1c6fb017ec2355396adaae1fe26be android.hardware.tests.lazy@1.1::ILazy # HALs released in Android O -- GitLab From 474eee3351339df1ef7fa9c6749d6ba65d21ac81 Mon Sep 17 00:00:00 2001 From: Seth Moore Date: Thu, 17 Jun 2021 10:58:27 -0700 Subject: [PATCH 719/790] Remove ignoreSignature for cose signature checks This flag is never used anywhere, so just remove it. When used, it would bypass signature checks. This is something we generally don't want to do, even in testing. So remove the flag so there's no temptation to use it. Ignore-AOSP-First: Will cherry-pick to AOSP Bug: 190942528 Test: VtsHalRemotelyProvisionedComponentTargetTest Change-Id: I0433c1eedc08e9a5a5ad71347154867dba61689e --- .../VtsRemotelyProvisionedComponentTests.cpp | 3 +- .../keymint/support/remote_prov_utils.cpp | 34 ++++++++----------- 2 files changed, 15 insertions(+), 22 deletions(-) diff --git a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp index a177317297..78f8f08637 100644 --- a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp +++ b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp @@ -335,8 +335,7 @@ class CertificateRequestTest : public VtsRemotelyProvisionedComponentTests { ASSERT_TRUE(deviceInfoMap->asMap()); auto& signingKey = bccContents->back().pubKey; - auto macKey = verifyAndParseCoseSign1(/* ignore_signature = */ false, signedMac->asArray(), - signingKey, + auto macKey = verifyAndParseCoseSign1(signedMac->asArray(), signingKey, cppbor::Array() // SignedMacAad .add(challenge_) .add(std::move(deviceInfoMap)) diff --git a/security/keymint/support/remote_prov_utils.cpp b/security/keymint/support/remote_prov_utils.cpp index da10eb258d..33f1ed3353 100644 --- a/security/keymint/support/remote_prov_utils.cpp +++ b/security/keymint/support/remote_prov_utils.cpp @@ -78,7 +78,7 @@ ErrMsgOr generateEekChain(size_t length, const bytevec& eekId) { return EekChain{eekChain.encode(), pub_key, priv_key}; } -ErrMsgOr verifyAndParseCoseSign1Cwt(bool ignoreSignature, const cppbor::Array* coseSign1, +ErrMsgOr verifyAndParseCoseSign1Cwt(const cppbor::Array* coseSign1, const bytevec& signingCoseKey, const bytevec& aad) { if (!coseSign1 || coseSign1->size() != kCoseSign1EntryCount) { return "Invalid COSE_Sign1"; @@ -115,27 +115,22 @@ ErrMsgOr verifyAndParseCoseSign1Cwt(bool ignoreSignature, const cppbor: auto serializedKey = parsedPayload->asMap()->get(-4670552)->clone(); if (!serializedKey || !serializedKey->asBstr()) return "Could not find key entry"; - if (!ignoreSignature) { - bool selfSigned = signingCoseKey.empty(); - auto key = CoseKey::parseEd25519(selfSigned ? serializedKey->asBstr()->value() - : signingCoseKey); - if (!key) return "Bad signing key: " + key.moveMessage(); - - bytevec signatureInput = cppbor::Array() - .add("Signature1") - .add(*protectedParams) - .add(aad) - .add(*payload) - .encode(); - - if (!ED25519_verify(signatureInput.data(), signatureInput.size(), signature->value().data(), - key->getBstrValue(CoseKey::PUBKEY_X)->data())) { - return "Signature verification failed"; - } + bool selfSigned = signingCoseKey.empty(); + auto key = + CoseKey::parseEd25519(selfSigned ? serializedKey->asBstr()->value() : signingCoseKey); + if (!key) return "Bad signing key: " + key.moveMessage(); + + bytevec signatureInput = + cppbor::Array().add("Signature1").add(*protectedParams).add(aad).add(*payload).encode(); + + if (!ED25519_verify(signatureInput.data(), signatureInput.size(), signature->value().data(), + key->getBstrValue(CoseKey::PUBKEY_X)->data())) { + return "Signature verification failed"; } return serializedKey->asBstr()->value(); } + ErrMsgOr> validateBcc(const cppbor::Array* bcc) { if (!bcc || bcc->size() == 0) return "Invalid BCC"; @@ -148,8 +143,7 @@ ErrMsgOr> validateBcc(const cppbor::Array* bcc) { if (!entry || entry->size() != kCoseSign1EntryCount) { return "Invalid BCC entry " + std::to_string(i) + ": " + prettyPrint(entry); } - auto payload = verifyAndParseCoseSign1Cwt(false /* ignoreSignature */, entry, - std::move(prevKey), bytevec{} /* AAD */); + auto payload = verifyAndParseCoseSign1Cwt(entry, std::move(prevKey), bytevec{} /* AAD */); if (!payload) { return "Failed to verify entry " + std::to_string(i) + ": " + payload.moveMessage(); } -- GitLab From 9228043bbc89d3715b63940150a60bc9b977bc8a Mon Sep 17 00:00:00 2001 From: Kai Date: Thu, 17 Jun 2021 13:51:04 -0700 Subject: [PATCH 720/790] Skip vts for hvac properties Setting hvac properties might have a lot of dependency issue. Uses other properties for testing set method. Bug: 189948885 Test: atest VtsHalAutomotiveVehicleV2_0TargetTest Change-Id: I715e9ce68e9e81618cdc6b433f0c108ebc057610 --- .../VtsHalAutomotiveVehicleV2_0TargetTest.cpp | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/automotive/vehicle/2.0/vts/functional/VtsHalAutomotiveVehicleV2_0TargetTest.cpp b/automotive/vehicle/2.0/vts/functional/VtsHalAutomotiveVehicleV2_0TargetTest.cpp index 4ac0aa565e..8adec8486f 100644 --- a/automotive/vehicle/2.0/vts/functional/VtsHalAutomotiveVehicleV2_0TargetTest.cpp +++ b/automotive/vehicle/2.0/vts/functional/VtsHalAutomotiveVehicleV2_0TargetTest.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -184,20 +185,34 @@ TEST_P(VehicleHalHidlTest, getInvalidProp) { TEST_P(VehicleHalHidlTest, setProp) { ALOGD("VehicleHalHidlTest::setProp"); hidl_vec propConfigs; + // skip hvac related properties + std::unordered_set hvacProps = {(int)VehicleProperty::HVAC_DEFROSTER, + (int)VehicleProperty::HVAC_AC_ON, + (int)VehicleProperty::HVAC_MAX_AC_ON, + (int)VehicleProperty::HVAC_MAX_DEFROST_ON, + (int)VehicleProperty::HVAC_RECIRC_ON, + (int)VehicleProperty::HVAC_DUAL_ON, + (int)VehicleProperty::HVAC_AUTO_ON, + (int)VehicleProperty::HVAC_POWER_ON, + (int)VehicleProperty::HVAC_AUTO_RECIRC_ON, + (int)VehicleProperty::HVAC_ELECTRIC_DEFROSTER_ON}; mVehicle->getAllPropConfigs( [&propConfigs](const hidl_vec& cfgs) { propConfigs = cfgs; }); for (const VehiclePropConfig& cfg : propConfigs) { // test on boolean and writable property - if (cfg.access == VehiclePropertyAccess::READ_WRITE && isBooleanGlobalProp(cfg.prop)) { + if (cfg.access == VehiclePropertyAccess::READ_WRITE && isBooleanGlobalProp(cfg.prop) && + !hvacProps.count(cfg.prop)) { invokeGet(cfg.prop, 0); int setValue = mActualValue.value.int32Values[0] == 1 ? 0 : 1; VehiclePropValue propToSet = mActualValue; propToSet.value.int32Values[0] = setValue; - ASSERT_EQ(StatusCode::OK, mVehicle->set(propToSet)); + ASSERT_EQ(StatusCode::OK, mVehicle->set(propToSet)) + << "Invalid status code for setting property: " << cfg.prop; // check set success invokeGet(cfg.prop, 0); ASSERT_EQ(StatusCode::OK, mActualStatusCode); - ASSERT_EQ(setValue, mActualValue.value.int32Values[0]); + ASSERT_EQ(setValue, mActualValue.value.int32Values[0]) + << "Failed to set value for property: " << cfg.prop; } } } -- GitLab From a5b5c359cbc451a22f35919c57464bb2f90303f2 Mon Sep 17 00:00:00 2001 From: karthik bharadwaj Date: Tue, 15 Jun 2021 13:55:43 -0700 Subject: [PATCH 721/790] Enforce sensors of the same type having a unique name. Bug: 179076515 Test: run vts -m VtsHalSensorsV2_0Target Change-Id: Ibf0d90afdcdce5ee5908dc35f8c392ee06e4b49e --- .../vts/functional/VtsHalSensorsV1_0TargetTest.cpp | 11 +++++++++++ sensors/common/vts/2_X/VtsHalSensorsV2_XTargetTest.h | 11 +++++++++++ 2 files changed, 22 insertions(+) diff --git a/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp b/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp index 1f579ba61e..d46cf5a490 100644 --- a/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp +++ b/sensors/1.0/vts/functional/VtsHalSensorsV1_0TargetTest.cpp @@ -24,7 +24,9 @@ #include #include +#include #include +#include #include using ::android::hardware::Return; @@ -149,6 +151,7 @@ std::vector SensorsHidlTest::getSensorsList() { TEST_P(SensorsHidlTest, SensorListValid) { S()->getSensorsList([&](const auto& list) { const size_t count = list.size(); + std::unordered_map> sensorTypeNameMap; for (size_t i = 0; i < count; ++i) { const auto& s = list[i]; SCOPED_TRACE(::testing::Message() @@ -167,6 +170,14 @@ TEST_P(SensorsHidlTest, SensorListValid) { EXPECT_FALSE(s.name.empty()); EXPECT_FALSE(s.vendor.empty()); + // Make sure that sensors of the same type have a unique name. + std::vector& v = sensorTypeNameMap[static_cast(s.type)]; + bool isUniqueName = std::find(v.begin(), v.end(), s.name) == v.end(); + EXPECT_TRUE(isUniqueName) << "Duplicate sensor Name: " << s.name; + if (isUniqueName) { + v.push_back(s.name); + } + // Test power > 0, maxRange > 0 EXPECT_LE(0, s.power); EXPECT_LT(0, s.maxRange); diff --git a/sensors/common/vts/2_X/VtsHalSensorsV2_XTargetTest.h b/sensors/common/vts/2_X/VtsHalSensorsV2_XTargetTest.h index 47a8cc0b4a..ea5dc70c5b 100644 --- a/sensors/common/vts/2_X/VtsHalSensorsV2_XTargetTest.h +++ b/sensors/common/vts/2_X/VtsHalSensorsV2_XTargetTest.h @@ -26,10 +26,12 @@ #include #include +#include #include #include #include #include +#include #include /** @@ -373,6 +375,7 @@ int32_t SensorsHidlTest::getInvalidSensorHandle() { TEST_P(SensorsHidlTest, SensorListValid) { getSensors()->getSensorsList([&](const auto& list) { const size_t count = list.size(); + std::unordered_map> sensorTypeNameMap; for (size_t i = 0; i < count; ++i) { const auto& s = list[i]; SCOPED_TRACE(::testing::Message() @@ -393,6 +396,14 @@ TEST_P(SensorsHidlTest, SensorListValid) { EXPECT_FALSE(s.name.empty()); EXPECT_FALSE(s.vendor.empty()); + // Make sure that sensors of the same type have a unique name. + std::vector& v = sensorTypeNameMap[static_cast(s.type)]; + bool isUniqueName = std::find(v.begin(), v.end(), s.name) == v.end(); + EXPECT_TRUE(isUniqueName) << "Duplicate sensor Name: " << s.name; + if (isUniqueName) { + v.push_back(s.name); + } + // Test power > 0, maxRange > 0 EXPECT_LE(0, s.power); EXPECT_LT(0, s.maxRange); -- GitLab From 924643748b0551656ebae7485079256f1ed23398 Mon Sep 17 00:00:00 2001 From: David Drysdale Date: Fri, 14 May 2021 16:46:59 +0100 Subject: [PATCH 722/790] KeyMint VTS: more attestation info tests Try all tags in attestion extension one by one Test: VtsAidlKeyMintTargetTest on CF Bug: 186735514 Merged-In: I63ca8d298d2d16f707f2437ab48aaa69c1d7563d Change-Id: I63ca8d298d2d16f707f2437ab48aaa69c1d7563d Ignore-AOSP-First: already merged in aosp/master --- .../vts/functional/KeyMintAidlTestBase.cpp | 57 +++--- .../aidl/vts/functional/KeyMintAidlTestBase.h | 2 + .../aidl/vts/functional/KeyMintTest.cpp | 166 ++++++++++++++++++ 3 files changed, 204 insertions(+), 21 deletions(-) diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp index 44b8274540..5a511752b5 100644 --- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp +++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp @@ -62,6 +62,9 @@ namespace test { namespace { +// Invalid value for a patchlevel (which is of form YYYYMMDD). +const uint32_t kInvalidPatchlevel = 99998877; + // Overhead for PKCS#1 v1.5 signature padding of undigested messages. Digested messages have // additional overhead, for the digest algorithmIdentifier required by PKCS#1. const size_t kPkcs1UndigestedSignaturePaddingOverhead = 11; @@ -126,10 +129,9 @@ char nibble2hex[16] = {'0', '1', '2', '3', '4', '5', '6', '7', // Attestations don't contain everything in key authorization lists, so we need to filter the key // lists to produce the lists that we expect to match the attestations. auto kTagsToFilter = { - Tag::CREATION_DATETIME, - Tag::EC_CURVE, - Tag::HARDWARE_TYPE, - Tag::INCLUDE_UNIQUE_ID, + Tag::CREATION_DATETIME, + Tag::HARDWARE_TYPE, + Tag::INCLUDE_UNIQUE_ID, }; AuthorizationSet filtered_tags(const AuthorizationSet& set) { @@ -163,6 +165,28 @@ string x509NameToStr(X509_NAME* name) { bool KeyMintAidlTestBase::arm_deleteAllKeys = false; bool KeyMintAidlTestBase::dump_Attestations = false; +uint32_t KeyMintAidlTestBase::boot_patch_level( + const vector& key_characteristics) { + // The boot patchlevel is not available as a property, but should be present + // in the key characteristics of any created key. + AuthorizationSet allAuths; + for (auto& entry : key_characteristics) { + allAuths.push_back(AuthorizationSet(entry.authorizations)); + } + auto patchlevel = allAuths.GetTagValue(TAG_BOOT_PATCHLEVEL); + if (patchlevel.has_value()) { + return patchlevel.value(); + } else { + // No boot patchlevel is available. Return a value that won't match anything + // and so will trigger test failures. + return kInvalidPatchlevel; + } +} + +uint32_t KeyMintAidlTestBase::boot_patch_level() { + return boot_patch_level(key_characteristics_); +} + ErrorCode KeyMintAidlTestBase::GetReturnErrorCode(const Status& result) { if (result.isOk()) return ErrorCode::OK; @@ -1293,9 +1317,9 @@ bool verify_attestation_record(const string& challenge, // AuthorizationSet att_sw_enforced; AuthorizationSet att_hw_enforced; uint32_t att_attestation_version; - uint32_t att_keymaster_version; + uint32_t att_keymint_version; SecurityLevel att_attestation_security_level; - SecurityLevel att_keymaster_security_level; + SecurityLevel att_keymint_security_level; vector att_challenge; vector att_unique_id; vector att_app_id; @@ -1304,8 +1328,8 @@ bool verify_attestation_record(const string& challenge, // attest_rec->length, // &att_attestation_version, // &att_attestation_security_level, // - &att_keymaster_version, // - &att_keymaster_security_level, // + &att_keymint_version, // + &att_keymint_security_level, // &att_challenge, // &att_sw_enforced, // &att_hw_enforced, // @@ -1324,14 +1348,14 @@ bool verify_attestation_record(const string& challenge, // expected_sw_enforced.push_back(TAG_ATTESTATION_APPLICATION_ID, appId); } - EXPECT_EQ(att_keymaster_version, 100U); - EXPECT_EQ(security_level, att_keymaster_security_level); + EXPECT_EQ(att_keymint_version, 100U); + EXPECT_EQ(security_level, att_keymint_security_level); EXPECT_EQ(security_level, att_attestation_security_level); char property_value[PROPERTY_VALUE_MAX] = {}; // TODO(b/136282179): When running under VTS-on-GSI the TEE-backed - // keymaster implementation will report YYYYMM dates instead of YYYYMMDD + // keymint implementation will report YYYYMM dates instead of YYYYMMDD // for the BOOT_PATCH_LEVEL. if (avb_verification_enabled()) { for (int i = 0; i < att_hw_enforced.size(); i++) { @@ -1370,13 +1394,6 @@ bool verify_attestation_record(const string& challenge, // EXPECT_TRUE(expected_hw_enforced.Contains(TAG_NO_AUTH_REQUIRED)); } - // Alternatively this checks the opposite - a false boolean tag (one that isn't provided in - // the authorization list during key generation) isn't being attested to in the certificate. - EXPECT_FALSE(expected_sw_enforced.Contains(TAG_TRUSTED_USER_PRESENCE_REQUIRED)); - EXPECT_FALSE(att_sw_enforced.Contains(TAG_TRUSTED_USER_PRESENCE_REQUIRED)); - EXPECT_FALSE(expected_hw_enforced.Contains(TAG_TRUSTED_USER_PRESENCE_REQUIRED)); - EXPECT_FALSE(att_hw_enforced.Contains(TAG_TRUSTED_USER_PRESENCE_REQUIRED)); - if (att_hw_enforced.Contains(TAG_ALGORITHM, Algorithm::EC)) { // For ECDSA keys, either an EC_CURVE or a KEY_SIZE can be specified, but one must be. EXPECT_TRUE(att_hw_enforced.Contains(TAG_EC_CURVE) || @@ -1442,9 +1459,7 @@ bool verify_attestation_record(const string& challenge, // att_sw_enforced.Sort(); expected_sw_enforced.Sort(); - auto a = filtered_tags(expected_sw_enforced); - auto b = filtered_tags(att_sw_enforced); - EXPECT_EQ(a, b); + EXPECT_EQ(filtered_tags(expected_sw_enforced), filtered_tags(att_sw_enforced)); att_hw_enforced.Sort(); expected_hw_enforced.Sort(); diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h index 82f192aa49..c8d6f1162b 100644 --- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h +++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h @@ -76,6 +76,8 @@ class KeyMintAidlTestBase : public ::testing::TestWithParam { uint32_t os_version() { return os_version_; } uint32_t os_patch_level() { return os_patch_level_; } uint32_t vendor_patch_level() { return vendor_patch_level_; } + uint32_t boot_patch_level(const vector& key_characteristics); + uint32_t boot_patch_level(); ErrorCode GetReturnErrorCode(const Status& result); diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp index 295be1a48d..d4b828afd2 100644 --- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp +++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp @@ -18,6 +18,8 @@ #include #include + +#include #include #include @@ -1438,6 +1440,170 @@ TEST_P(NewKeyGenerationTest, EcdsaAttestation) { } } +/* + * NewKeyGenerationTest.EcdsaAttestationTags + * + * Verifies that creation of an attested ECDSA key includes various tags in the + * attestation extension. + */ +TEST_P(NewKeyGenerationTest, EcdsaAttestationTags) { + auto challenge = "hello"; + auto app_id = "foo"; + auto subject = "cert subj 2"; + vector subject_der(make_name_from_str(subject)); + uint64_t serial_int = 0x1010; + vector serial_blob(build_serial_blob(serial_int)); + const AuthorizationSetBuilder base_builder = + AuthorizationSetBuilder() + .Authorization(TAG_NO_AUTH_REQUIRED) + .EcdsaSigningKey(256) + .Digest(Digest::NONE) + .AttestationChallenge(challenge) + .AttestationApplicationId(app_id) + .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob) + .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der) + .SetDefaultValidity(); + + // Various tags that map to fields in the attestation extension ASN.1 schema. + auto extra_tags = AuthorizationSetBuilder() + .Authorization(TAG_ROLLBACK_RESISTANCE) + .Authorization(TAG_EARLY_BOOT_ONLY) + .Authorization(TAG_ACTIVE_DATETIME, 1619621648000) + .Authorization(TAG_ORIGINATION_EXPIRE_DATETIME, 1619621648000) + .Authorization(TAG_USAGE_EXPIRE_DATETIME, 1619621999000) + .Authorization(TAG_USAGE_COUNT_LIMIT, 42) + .Authorization(TAG_AUTH_TIMEOUT, 100000) + .Authorization(TAG_ALLOW_WHILE_ON_BODY) + .Authorization(TAG_TRUSTED_USER_PRESENCE_REQUIRED) + .Authorization(TAG_TRUSTED_CONFIRMATION_REQUIRED) + .Authorization(TAG_UNLOCKED_DEVICE_REQUIRED) + .Authorization(TAG_CREATION_DATETIME, 1619621648000); + for (const KeyParameter& tag : extra_tags) { + SCOPED_TRACE(testing::Message() << "tag-" << tag); + vector key_blob; + vector key_characteristics; + AuthorizationSetBuilder builder = base_builder; + builder.push_back(tag); + auto result = GenerateKey(builder, &key_blob, &key_characteristics); + if (result == ErrorCode::ROLLBACK_RESISTANCE_UNAVAILABLE && + tag.tag == TAG_ROLLBACK_RESISTANCE) { + continue; + } + if (result == ErrorCode::UNSUPPORTED_TAG && + (tag.tag == TAG_ALLOW_WHILE_ON_BODY || tag.tag == TAG_TRUSTED_USER_PRESENCE_REQUIRED)) { + // Optional tag not supported by this KeyMint implementation. + continue; + } + ASSERT_EQ(result, ErrorCode::OK); + ASSERT_GT(key_blob.size(), 0U); + + EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_)); + ASSERT_GT(cert_chain_.size(), 0); + verify_subject_and_serial(cert_chain_[0], serial_int, subject, /* self_signed = */ false); + + AuthorizationSet hw_enforced = HwEnforcedAuthorizations(key_characteristics); + AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics); + if (tag.tag != TAG_ATTESTATION_APPLICATION_ID) { + // Expect to find most of the extra tags in the key characteristics + // of the generated key (but not for ATTESTATION_APPLICATION_ID). + EXPECT_TRUE(hw_enforced.Contains(tag.tag) || sw_enforced.Contains(tag.tag)) + << tag << " not in hw:" << hw_enforced << " nor sw:" << sw_enforced; + } + + // Verifying the attestation record will check for the specific tag because + // it's included in the authorizations. + EXPECT_TRUE(verify_attestation_record(challenge, app_id, sw_enforced, hw_enforced, + SecLevel(), cert_chain_[0].encodedCertificate)); + + CheckedDeleteKey(&key_blob); + } + + // Device attestation IDs should be rejected for normal attestation requests; these fields + // are only used for device unique attestation. + auto invalid_tags = AuthorizationSetBuilder() + .Authorization(TAG_ATTESTATION_ID_BRAND, "brand") + .Authorization(TAG_ATTESTATION_ID_DEVICE, "device") + .Authorization(TAG_ATTESTATION_ID_PRODUCT, "product") + .Authorization(TAG_ATTESTATION_ID_SERIAL, "serial") + .Authorization(TAG_ATTESTATION_ID_IMEI, "imei") + .Authorization(TAG_ATTESTATION_ID_MEID, "meid") + .Authorization(TAG_ATTESTATION_ID_MANUFACTURER, "manufacturer") + .Authorization(TAG_ATTESTATION_ID_MODEL, "model"); + for (const KeyParameter& tag : invalid_tags) { + SCOPED_TRACE(testing::Message() << "tag-" << tag); + vector key_blob; + vector key_characteristics; + AuthorizationSetBuilder builder = + AuthorizationSetBuilder() + .Authorization(TAG_NO_AUTH_REQUIRED) + .EcdsaSigningKey(256) + .Digest(Digest::NONE) + .AttestationChallenge(challenge) + .AttestationApplicationId(app_id) + .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob) + .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der) + .SetDefaultValidity(); + builder.push_back(tag); + ASSERT_EQ(ErrorCode::CANNOT_ATTEST_IDS, + GenerateKey(builder, &key_blob, &key_characteristics)); + } +} + +/* + * NewKeyGenerationTest.EcdsaAttestationTagNoApplicationId + * + * Verifies that creation of an attested ECDSA key does not include APPLICATION_ID. + */ +TEST_P(NewKeyGenerationTest, EcdsaAttestationTagNoApplicationId) { + auto challenge = "hello"; + auto attest_app_id = "foo"; + auto subject = "cert subj 2"; + vector subject_der(make_name_from_str(subject)); + uint64_t serial_int = 0x1010; + vector serial_blob(build_serial_blob(serial_int)); + + // Earlier versions of the attestation extension schema included a slot: + // applicationId [601] EXPLICIT OCTET_STRING OPTIONAL, + // This should never have been included, and should never be filled in. + // Generate an attested key that include APPLICATION_ID and APPLICATION_DATA, + // to confirm that this field never makes it into the attestation extension. + vector key_blob; + vector key_characteristics; + auto result = GenerateKey(AuthorizationSetBuilder() + .Authorization(TAG_NO_AUTH_REQUIRED) + .EcdsaSigningKey(EcCurve::P_256) + .Digest(Digest::NONE) + .AttestationChallenge(challenge) + .AttestationApplicationId(attest_app_id) + .Authorization(TAG_APPLICATION_ID, "client_id") + .Authorization(TAG_APPLICATION_DATA, "appdata") + .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob) + .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der) + .SetDefaultValidity(), + &key_blob, &key_characteristics); + ASSERT_EQ(result, ErrorCode::OK); + ASSERT_GT(key_blob.size(), 0U); + + EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_)); + ASSERT_GT(cert_chain_.size(), 0); + verify_subject_and_serial(cert_chain_[0], serial_int, subject, /* self_signed = */ false); + + AuthorizationSet hw_enforced = HwEnforcedAuthorizations(key_characteristics); + AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics); + EXPECT_TRUE(verify_attestation_record(challenge, attest_app_id, sw_enforced, hw_enforced, + SecLevel(), cert_chain_[0].encodedCertificate)); + + // Check that the app id is not in the cert. + string app_id = "clientid"; + std::vector needle(reinterpret_cast(app_id.data()), + reinterpret_cast(app_id.data()) + app_id.size()); + ASSERT_EQ(std::search(cert_chain_[0].encodedCertificate.begin(), + cert_chain_[0].encodedCertificate.end(), needle.begin(), needle.end()), + cert_chain_[0].encodedCertificate.end()); + + CheckedDeleteKey(&key_blob); +} + /* * NewKeyGenerationTest.EcdsaSelfSignAttestation * -- GitLab From 308916bfafd3acb45a89d82208c1b9b952059960 Mon Sep 17 00:00:00 2001 From: David Drysdale Date: Tue, 8 Jun 2021 15:46:11 +0100 Subject: [PATCH 723/790] KeyMint VTS: require curve for ECDSA keys The KeyMint AIDL spec requires that "Tag::EC_CURVE must be provided to generate an ECDSA key". Move the VTS tests to always create ECDSA keys by curve not key size. Bug: 188672564 Test: VtsAidlKeyMintTargetTest Merged-In: I33036387c243b21ab0ecd49221b7e7757598913e Change-Id: I33036387c243b21ab0ecd49221b7e7757598913e Ignore-AOSP-First: already merged in aosp/master --- .../vts/functional/KeyMintAidlTestBase.cpp | 19 +-- .../aidl/vts/functional/KeyMintAidlTestBase.h | 2 +- .../aidl/vts/functional/KeyMintTest.cpp | 154 +++++------------- 3 files changed, 52 insertions(+), 123 deletions(-) diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp index 5a511752b5..5359b3b667 100644 --- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp +++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp @@ -1022,16 +1022,7 @@ vector KeyMintAidlTestBase::ValidKeySizes(Algorithm algorithm) { } break; case Algorithm::EC: - switch (SecLevel()) { - case SecurityLevel::SOFTWARE: - case SecurityLevel::TRUSTED_ENVIRONMENT: - return {224, 256, 384, 521}; - case SecurityLevel::STRONGBOX: - return {256}; - default: - ADD_FAILURE() << "Invalid security level " << uint32_t(SecLevel()); - break; - } + ADD_FAILURE() << "EC keys must be specified by curve not size"; break; case Algorithm::AES: return {128, 256}; @@ -1147,9 +1138,11 @@ vector KeyMintAidlTestBase::ValidCurves() { } vector KeyMintAidlTestBase::InvalidCurves() { - if (SecLevel() == SecurityLevel::TRUSTED_ENVIRONMENT) return {}; - CHECK(SecLevel() == SecurityLevel::STRONGBOX); - return {EcCurve::P_224, EcCurve::P_384, EcCurve::P_521}; + if (SecLevel() == SecurityLevel::STRONGBOX) { + return {EcCurve::P_224, EcCurve::P_384, EcCurve::P_521}; + } else { + return {}; + } } vector KeyMintAidlTestBase::ValidDigests(bool withNone, bool withMD5) { diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h index c8d6f1162b..d592d3686b 100644 --- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h +++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h @@ -255,7 +255,7 @@ class KeyMintAidlTestBase : public ::testing::TestWithParam { /* ECDSA */ KeyData ecdsaKeyData; AuthorizationSetBuilder ecdsaBuilder = AuthorizationSetBuilder() - .EcdsaSigningKey(256) + .EcdsaSigningKey(EcCurve::P_256) .Authorization(tagToTest) .Digest(Digest::SHA_2_256) .Authorization(TAG_NO_AUTH_REQUIRED) diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp index d4b828afd2..d41d270764 100644 --- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp +++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp @@ -1364,11 +1364,11 @@ TEST_P(NewKeyGenerationTest, RsaMissingParams) { * have correct characteristics. */ TEST_P(NewKeyGenerationTest, Ecdsa) { - for (auto key_size : ValidKeySizes(Algorithm::EC)) { + for (auto curve : ValidCurves()) { vector key_blob; vector key_characteristics; ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .EcdsaSigningKey(key_size) + .EcdsaSigningKey(curve) .Digest(Digest::NONE) .SetDefaultValidity(), &key_blob, &key_characteristics)); @@ -1379,8 +1379,7 @@ TEST_P(NewKeyGenerationTest, Ecdsa) { AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics); EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::EC)); - EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size)) - << "Key size " << key_size << "missing"; + EXPECT_TRUE(crypto_params.Contains(TAG_EC_CURVE, curve)) << "Curve " << curve << "missing"; CheckedDeleteKey(&key_blob); } @@ -1402,13 +1401,13 @@ TEST_P(NewKeyGenerationTest, EcdsaAttestation) { uint64_t serial_int = 0xFFFFFFFFFFFFFFFF; vector serial_blob(build_serial_blob(serial_int)); - for (auto key_size : ValidKeySizes(Algorithm::EC)) { + for (auto curve : ValidCurves()) { vector key_blob; vector key_characteristics; ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() .Authorization(TAG_NO_AUTH_REQUIRED) - .EcdsaSigningKey(key_size) + .EcdsaSigningKey(curve) .Digest(Digest::NONE) .AttestationChallenge(challenge) .AttestationApplicationId(app_id) @@ -1423,8 +1422,7 @@ TEST_P(NewKeyGenerationTest, EcdsaAttestation) { AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics); EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::EC)); - EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size)) - << "Key size " << key_size << "missing"; + EXPECT_TRUE(crypto_params.Contains(TAG_EC_CURVE, curve)) << "Curve " << curve << "missing"; EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_)); ASSERT_GT(cert_chain_.size(), 0); @@ -1456,7 +1454,7 @@ TEST_P(NewKeyGenerationTest, EcdsaAttestationTags) { const AuthorizationSetBuilder base_builder = AuthorizationSetBuilder() .Authorization(TAG_NO_AUTH_REQUIRED) - .EcdsaSigningKey(256) + .EcdsaSigningKey(EcCurve::P_256) .Digest(Digest::NONE) .AttestationChallenge(challenge) .AttestationApplicationId(app_id) @@ -1536,7 +1534,7 @@ TEST_P(NewKeyGenerationTest, EcdsaAttestationTags) { AuthorizationSetBuilder builder = AuthorizationSetBuilder() .Authorization(TAG_NO_AUTH_REQUIRED) - .EcdsaSigningKey(256) + .EcdsaSigningKey(EcCurve::P_256) .Digest(Digest::NONE) .AttestationChallenge(challenge) .AttestationApplicationId(app_id) @@ -1617,12 +1615,12 @@ TEST_P(NewKeyGenerationTest, EcdsaSelfSignAttestation) { uint64_t serial_int = 0x123456FFF1234; vector serial_blob(build_serial_blob(serial_int)); - for (auto key_size : ValidKeySizes(Algorithm::EC)) { + for (auto curve : ValidCurves()) { vector key_blob; vector key_characteristics; ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .EcdsaSigningKey(key_size) + .EcdsaSigningKey(curve) .Digest(Digest::NONE) .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob) .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der) @@ -1635,8 +1633,7 @@ TEST_P(NewKeyGenerationTest, EcdsaSelfSignAttestation) { AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics); EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::EC)); - EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size)) - << "Key size " << key_size << "missing"; + EXPECT_TRUE(crypto_params.Contains(TAG_EC_CURVE, curve)) << "Curve " << curve << "missing"; EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_)); verify_subject_and_serial(cert_chain_[0], serial_int, subject, false); @@ -1678,11 +1675,11 @@ TEST_P(NewKeyGenerationTest, EcdsaAttestationRequireAppId) { TEST_P(NewKeyGenerationTest, EcdsaIgnoreAppId) { auto app_id = "foo"; - for (auto key_size : ValidKeySizes(Algorithm::EC)) { + for (auto curve : ValidCurves()) { vector key_blob; vector key_characteristics; ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .EcdsaSigningKey(key_size) + .EcdsaSigningKey(curve) .Digest(Digest::NONE) .AttestationApplicationId(app_id) .SetDefaultValidity(), @@ -1695,8 +1692,7 @@ TEST_P(NewKeyGenerationTest, EcdsaIgnoreAppId) { AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics); EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::EC)); - EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size)) - << "Key size " << key_size << "missing"; + EXPECT_TRUE(crypto_params.Contains(TAG_EC_CURVE, curve)) << "Curve " << curve << "missing"; EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_)); ASSERT_EQ(cert_chain_.size(), 1); @@ -1718,7 +1714,6 @@ TEST_P(NewKeyGenerationTest, EcdsaIgnoreAppId) { */ TEST_P(NewKeyGenerationTest, AttestationApplicationIDLengthProperlyEncoded) { auto challenge = "hello"; - auto key_size = 256; std::vector app_id_lengths{143, 258}; for (uint32_t length : app_id_lengths) { @@ -1727,7 +1722,7 @@ TEST_P(NewKeyGenerationTest, AttestationApplicationIDLengthProperlyEncoded) { vector key_characteristics; ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() .Authorization(TAG_NO_AUTH_REQUIRED) - .EcdsaSigningKey(key_size) + .EcdsaSigningKey(EcCurve::P_256) .Digest(Digest::NONE) .AttestationChallenge(challenge) .AttestationApplicationId(app_id) @@ -1740,8 +1735,7 @@ TEST_P(NewKeyGenerationTest, AttestationApplicationIDLengthProperlyEncoded) { AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics); EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::EC)); - EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size)) - << "Key size " << key_size << "missing"; + EXPECT_TRUE(crypto_params.Contains(TAG_EC_CURVE, EcCurve::P_256)) << "Curve P256 missing"; EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_)); ASSERT_GT(cert_chain_.size(), 0); @@ -1763,11 +1757,11 @@ TEST_P(NewKeyGenerationTest, AttestationApplicationIDLengthProperlyEncoded) { * resulting keys have correct characteristics. */ TEST_P(NewKeyGenerationTest, LimitedUsageEcdsa) { - for (auto key_size : ValidKeySizes(Algorithm::EC)) { + for (auto curve : ValidCurves()) { vector key_blob; vector key_characteristics; ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .EcdsaSigningKey(key_size) + .EcdsaSigningKey(curve) .Digest(Digest::NONE) .Authorization(TAG_USAGE_COUNT_LIMIT, 1) .SetDefaultValidity(), @@ -1780,8 +1774,7 @@ TEST_P(NewKeyGenerationTest, LimitedUsageEcdsa) { AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics); EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::EC)); - EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size)) - << "Key size " << key_size << "missing"; + EXPECT_TRUE(crypto_params.Contains(TAG_EC_CURVE, curve)) << "Curve " << curve << "missing"; // Check the usage count limit tag appears in the authorizations. AuthorizationSet auths; @@ -1798,7 +1791,7 @@ TEST_P(NewKeyGenerationTest, LimitedUsageEcdsa) { /* * NewKeyGenerationTest.EcdsaDefaultSize * - * Verifies that failing to specify a key size for EC key generation returns + * Verifies that failing to specify a curve for EC key generation returns * UNSUPPORTED_KEY_SIZE. */ TEST_P(NewKeyGenerationTest, EcdsaDefaultSize) { @@ -1817,20 +1810,23 @@ TEST_P(NewKeyGenerationTest, EcdsaDefaultSize) { * UNSUPPORTED_KEY_SIZE. */ TEST_P(NewKeyGenerationTest, EcdsaInvalidSize) { - for (auto key_size : InvalidKeySizes(Algorithm::EC)) { + for (auto curve : InvalidCurves()) { vector key_blob; vector key_characteristics; ASSERT_EQ(ErrorCode::UNSUPPORTED_KEY_SIZE, GenerateKey(AuthorizationSetBuilder() - .EcdsaSigningKey(key_size) + .EcdsaSigningKey(curve) .Digest(Digest::NONE) .SetDefaultValidity(), &key_blob, &key_characteristics)); } - ASSERT_EQ(ErrorCode::UNSUPPORTED_KEY_SIZE, GenerateKey(AuthorizationSetBuilder() - .EcdsaSigningKey(190) - .Digest(Digest::NONE) - .SetDefaultValidity())); + ASSERT_EQ(ErrorCode::UNSUPPORTED_KEY_SIZE, + GenerateKey(AuthorizationSetBuilder() + .Authorization(TAG_ALGORITHM, Algorithm::EC) + .Authorization(TAG_KEY_SIZE, 190) + .SigningKey() + .Digest(Digest::NONE) + .SetDefaultValidity())); } /* @@ -1842,29 +1838,13 @@ TEST_P(NewKeyGenerationTest, EcdsaInvalidSize) { TEST_P(NewKeyGenerationTest, EcdsaMismatchKeySize) { if (SecLevel() == SecurityLevel::STRONGBOX) return; - ASSERT_EQ(ErrorCode::INVALID_ARGUMENT, - GenerateKey(AuthorizationSetBuilder() - .EcdsaSigningKey(224) - .Authorization(TAG_EC_CURVE, EcCurve::P_256) - .Digest(Digest::NONE) - .SetDefaultValidity())); -} - -/* - * NewKeyGenerationTest.EcdsaAllValidSizes - * - * Verifies that keymint supports all required EC key sizes. - */ -TEST_P(NewKeyGenerationTest, EcdsaAllValidSizes) { - auto valid_sizes = ValidKeySizes(Algorithm::EC); - for (size_t size : valid_sizes) { - EXPECT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() - .EcdsaSigningKey(size) - .Digest(Digest::NONE) - .SetDefaultValidity())) - << "Failed to generate size: " << size; - CheckedDeleteKey(); - } + auto result = GenerateKey(AuthorizationSetBuilder() + .Authorization(TAG_KEY_SIZE, 224) + .Authorization(TAG_EC_CURVE, EcCurve::P_256) + .Digest(Digest::NONE) + .SetDefaultValidity()); + ASSERT_TRUE(result == ErrorCode::INVALID_ARGUMENT || + result == ErrorCode::UNSUPPORTED_ALGORITHM); } /* @@ -2636,31 +2616,6 @@ TEST_P(SigningOperationsTest, RsaSignTooLargeMessage) { ASSERT_EQ(ErrorCode::INVALID_ARGUMENT, Finish(message, &signature)); } -/* - * SigningOperationsTest.EcdsaAllSizesAndHashes - * - * Verifies that ECDSA operations succeed with all possible key sizes and hashes. - */ -TEST_P(SigningOperationsTest, EcdsaAllSizesAndHashes) { - for (auto key_size : ValidKeySizes(Algorithm::EC)) { - for (auto digest : ValidDigests(false /* withNone */, false /* withMD5 */)) { - ErrorCode error = GenerateKey(AuthorizationSetBuilder() - .Authorization(TAG_NO_AUTH_REQUIRED) - .EcdsaSigningKey(key_size) - .Digest(digest) - .SetDefaultValidity()); - EXPECT_EQ(ErrorCode::OK, error) << "Failed to generate ECDSA key with size " << key_size - << " and digest " << digest; - if (error != ErrorCode::OK) continue; - - string message(1024, 'a'); - if (digest == Digest::NONE) message.resize(key_size / 8); - SignMessage(message, AuthorizationSetBuilder().Digest(digest)); - CheckedDeleteKey(); - } - } -} - /* * SigningOperationsTest.EcdsaAllDigestsAndCurves * @@ -2726,7 +2681,7 @@ TEST_P(SigningOperationsTest, EcdsaAllCurves) { TEST_P(SigningOperationsTest, EcdsaNoDigestHugeData) { ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() .Authorization(TAG_NO_AUTH_REQUIRED) - .EcdsaSigningKey(256) + .EcdsaSigningKey(EcCurve::P_256) .Digest(Digest::NONE) .SetDefaultValidity())); string message(1 * 1024, 'a'); @@ -2741,7 +2696,7 @@ TEST_P(SigningOperationsTest, EcdsaNoDigestHugeData) { TEST_P(SigningOperationsTest, EcUseRequiresCorrectAppIdAppData) { ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() .Authorization(TAG_NO_AUTH_REQUIRED) - .EcdsaSigningKey(256) + .EcdsaSigningKey(EcCurve::P_256) .Digest(Digest::NONE) .Authorization(TAG_APPLICATION_ID, "clientid") .Authorization(TAG_APPLICATION_DATA, "appdata") @@ -2778,7 +2733,7 @@ TEST_P(SigningOperationsTest, EcUseRequiresCorrectAppIdAppData) { TEST_P(SigningOperationsTest, EcdsaIncompatibleDigest) { ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() .Authorization(TAG_NO_AUTH_REQUIRED) - .EcdsaSigningKey(256) + .EcdsaSigningKey(EcCurve::P_256) .Digest(Digest::NONE) .Digest(Digest::SHA1) .SetDefaultValidity())); @@ -3166,13 +3121,12 @@ TEST_P(ImportKeyTest, RsaPublicExponentMismatch) { TEST_P(ImportKeyTest, EcdsaSuccess) { ASSERT_EQ(ErrorCode::OK, ImportKey(AuthorizationSetBuilder() .Authorization(TAG_NO_AUTH_REQUIRED) - .EcdsaSigningKey(256) + .EcdsaSigningKey(EcCurve::P_256) .Digest(Digest::SHA_2_256) .SetDefaultValidity(), KeyFormat::PKCS8, ec_256_key)); CheckCryptoParam(TAG_ALGORITHM, Algorithm::EC); - CheckCryptoParam(TAG_KEY_SIZE, 256U); CheckCryptoParam(TAG_DIGEST, Digest::SHA_2_256); CheckCryptoParam(TAG_EC_CURVE, EcCurve::P_256); @@ -3193,13 +3147,12 @@ TEST_P(ImportKeyTest, EcdsaSuccess) { TEST_P(ImportKeyTest, EcdsaP256RFC5915Success) { ASSERT_EQ(ErrorCode::OK, ImportKey(AuthorizationSetBuilder() .Authorization(TAG_NO_AUTH_REQUIRED) - .EcdsaSigningKey(256) + .EcdsaSigningKey(EcCurve::P_256) .Digest(Digest::SHA_2_256) .SetDefaultValidity(), KeyFormat::PKCS8, ec_256_key_rfc5915)); CheckCryptoParam(TAG_ALGORITHM, Algorithm::EC); - CheckCryptoParam(TAG_KEY_SIZE, 256U); CheckCryptoParam(TAG_DIGEST, Digest::SHA_2_256); CheckCryptoParam(TAG_EC_CURVE, EcCurve::P_256); @@ -3219,13 +3172,12 @@ TEST_P(ImportKeyTest, EcdsaP256RFC5915Success) { TEST_P(ImportKeyTest, EcdsaP256SEC1Success) { ASSERT_EQ(ErrorCode::OK, ImportKey(AuthorizationSetBuilder() .Authorization(TAG_NO_AUTH_REQUIRED) - .EcdsaSigningKey(256) + .EcdsaSigningKey(EcCurve::P_256) .Digest(Digest::SHA_2_256) .SetDefaultValidity(), KeyFormat::PKCS8, ec_256_key_sec1)); CheckCryptoParam(TAG_ALGORITHM, Algorithm::EC); - CheckCryptoParam(TAG_KEY_SIZE, 256U); CheckCryptoParam(TAG_DIGEST, Digest::SHA_2_256); CheckCryptoParam(TAG_EC_CURVE, EcCurve::P_256); @@ -3246,13 +3198,12 @@ TEST_P(ImportKeyTest, Ecdsa521Success) { if (SecLevel() == SecurityLevel::STRONGBOX) return; ASSERT_EQ(ErrorCode::OK, ImportKey(AuthorizationSetBuilder() .Authorization(TAG_NO_AUTH_REQUIRED) - .EcdsaSigningKey(521) + .EcdsaSigningKey(EcCurve::P_521) .Digest(Digest::SHA_2_256) .SetDefaultValidity(), KeyFormat::PKCS8, ec_521_key)); CheckCryptoParam(TAG_ALGORITHM, Algorithm::EC); - CheckCryptoParam(TAG_KEY_SIZE, 521U); CheckCryptoParam(TAG_DIGEST, Digest::SHA_2_256); CheckCryptoParam(TAG_EC_CURVE, EcCurve::P_521); CheckOrigin(); @@ -3263,21 +3214,6 @@ TEST_P(ImportKeyTest, Ecdsa521Success) { LocalVerifyMessage(message, signature, params); } -/* - * ImportKeyTest.EcdsaSizeMismatch - * - * Verifies that importing an ECDSA key pair with a size that doesn't match the key fails in the - * correct way. - */ -TEST_P(ImportKeyTest, EcdsaSizeMismatch) { - ASSERT_EQ(ErrorCode::IMPORT_PARAMETER_MISMATCH, - ImportKey(AuthorizationSetBuilder() - .EcdsaSigningKey(224 /* Doesn't match key */) - .Digest(Digest::NONE) - .SetDefaultValidity(), - KeyFormat::PKCS8, ec_256_key)); -} - /* * ImportKeyTest.EcdsaCurveMismatch * @@ -4141,7 +4077,7 @@ TEST_P(EncryptionOperationsTest, RsaPkcs1Success) { TEST_P(EncryptionOperationsTest, EcdsaEncrypt) { ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() .Authorization(TAG_NO_AUTH_REQUIRED) - .EcdsaSigningKey(256) + .EcdsaSigningKey(EcCurve::P_256) .Digest(Digest::NONE) .SetDefaultValidity())); auto params = AuthorizationSetBuilder().Digest(Digest::NONE); @@ -6584,7 +6520,7 @@ TEST_P(EarlyBootKeyTest, ImportEarlyBootKeyFailure) { ASSERT_EQ(ErrorCode::EARLY_BOOT_ENDED, ImportKey(AuthorizationSetBuilder() .Authorization(TAG_NO_AUTH_REQUIRED) .Authorization(TAG_EARLY_BOOT_ONLY) - .EcdsaSigningKey(256) + .EcdsaSigningKey(EcCurve::P_256) .Digest(Digest::SHA_2_256) .SetDefaultValidity(), KeyFormat::PKCS8, ec_256_key)); -- GitLab From 03d642f6d94af339a3bb317c960f43b048101413 Mon Sep 17 00:00:00 2001 From: Les Lee Date: Mon, 21 Jun 2021 21:25:20 +0800 Subject: [PATCH 724/790] wifi: Update active iface when bridged AP instance down The active interface need to be updated when any of interface changecd. Also fix the local cache bridged_ap_instances value incorrect when erasing. Bug: 191625124 Test: Manual check property "wifi.active.interface" after wlan2 down Test: Manual test with command "halutil -sar enable 0" after wlan2 down Change-Id: I40150c231313505ca355228e711c2448088f41ad --- wifi/1.5/default/wifi_chip.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/wifi/1.5/default/wifi_chip.cpp b/wifi/1.5/default/wifi_chip.cpp index 961f9da4c2..6fa9601672 100644 --- a/wifi/1.5/default/wifi_chip.cpp +++ b/wifi/1.5/default/wifi_chip.cpp @@ -1059,7 +1059,8 @@ WifiStatus WifiChip::removeIfaceInstanceFromBridgedApIfaceInternal( // Requires to remove one of the instance in bridge mode for (auto const& it : br_ifaces_ap_instances_) { if (it.first == ifname) { - for (auto const& iface : it.second) { + std::vector ap_instances = it.second; + for (auto const& iface : ap_instances) { if (iface == ifInstanceName) { if (!iface_util_->removeIfaceFromBridge(it.first, iface)) { LOG(ERROR) @@ -1075,13 +1076,20 @@ WifiStatus WifiChip::removeIfaceInstanceFromBridgedApIfaceInternal( << " " << legacyErrorToString(legacy_status); return createWifiStatusFromLegacyError(legacy_status); } + ap_instances.erase( + std::remove(ap_instances.begin(), ap_instances.end(), + ifInstanceName), + ap_instances.end()); + br_ifaces_ap_instances_[ifname] = ap_instances; + break; } } break; } } - br_ifaces_ap_instances_.erase(ifInstanceName); iface->removeInstance(ifInstanceName); + setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName()); + return createWifiStatus(WifiStatusCode::SUCCESS); } -- GitLab From 7a55bb5cf8efa7570cd672dad08cff6a78fb8f88 Mon Sep 17 00:00:00 2001 From: Seth Moore Date: Tue, 22 Jun 2021 16:47:48 -0700 Subject: [PATCH 725/790] Add a unit test for remote_prov_utils This functionality will be used for the factory tooling, so we should test it. Additionally, some new functionality will soon be added, and it also needs to be tested. Ignore-AOSP-First: No merge path to aosp, will manually merge Test: libkeymint_remote_prov_support_test Bug: 191301285 Change-Id: I6a8798fc4b09fff1e829185a4b9e471921e5d2a9 --- security/keymint/support/Android.bp | 16 ++++++ .../keymint/support/remote_prov_utils.cpp | 4 ++ .../support/remote_prov_utils_test.cpp | 55 +++++++++++++++++++ 3 files changed, 75 insertions(+) create mode 100644 security/keymint/support/remote_prov_utils_test.cpp diff --git a/security/keymint/support/Android.bp b/security/keymint/support/Android.bp index 718133aa41..c2dba044bf 100644 --- a/security/keymint/support/Android.bp +++ b/security/keymint/support/Android.bp @@ -62,3 +62,19 @@ cc_library { "libcrypto", ], } + +cc_test { + name: "libkeymint_remote_prov_support_test", + srcs: ["remote_prov_utils_test.cpp"], + static_libs: [ + "libgmock", + "libgtest_main", + ], + shared_libs: [ + "libcppbor_external", + "libcppcose_rkp", + "libcrypto", + "libkeymaster_portable", + "libkeymint_remote_prov_support", + ], +} diff --git a/security/keymint/support/remote_prov_utils.cpp b/security/keymint/support/remote_prov_utils.cpp index 33f1ed3353..ac7cb6219f 100644 --- a/security/keymint/support/remote_prov_utils.cpp +++ b/security/keymint/support/remote_prov_utils.cpp @@ -31,6 +31,10 @@ bytevec randomBytes(size_t numBytes) { } ErrMsgOr generateEekChain(size_t length, const bytevec& eekId) { + if (length < 2) { + return "EEK chain must contain at least 2 certs."; + } + auto eekChain = cppbor::Array(); bytevec prev_priv_key; diff --git a/security/keymint/support/remote_prov_utils_test.cpp b/security/keymint/support/remote_prov_utils_test.cpp new file mode 100644 index 0000000000..fbf5b95897 --- /dev/null +++ b/security/keymint/support/remote_prov_utils_test.cpp @@ -0,0 +1,55 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include + +namespace aidl::android::hardware::security::keymint::remote_prov { +namespace { + +using ::keymaster::KeymasterBlob; +using ::keymaster::validateAndExtractEekPubAndId; +using ::testing::ElementsAreArray; + +TEST(RemoteProvUtilsTest, GenerateEekChainInvalidLength) { + ASSERT_FALSE(generateEekChain(1, /*eekId=*/{})); +} + +TEST(RemoteProvUtilsTest, GenerateEekChain) { + bytevec kTestEekId = {'t', 'e', 's', 't', 'I', 'd', 0}; + for (size_t length : {2, 3, 31}) { + auto get_eek_result = generateEekChain(length, kTestEekId); + ASSERT_TRUE(get_eek_result) << get_eek_result.message(); + + auto& [chain, pubkey, privkey] = *get_eek_result; + + auto validation_result = validateAndExtractEekPubAndId( + /*testMode=*/true, KeymasterBlob(chain.data(), chain.size())); + ASSERT_TRUE(validation_result.isOk()); + + auto& [eekPub, eekId] = *validation_result; + EXPECT_THAT(eekId, ElementsAreArray(kTestEekId)); + EXPECT_THAT(eekPub, ElementsAreArray(pubkey)); + } +} + +} // namespace +} // namespace aidl::android::hardware::security::keymint::remote_prov -- GitLab From 415f0ce4fe05f37ddd47a23dafc4489c3aea7ebb Mon Sep 17 00:00:00 2001 From: Seth Moore Date: Tue, 22 Jun 2021 17:13:05 -0700 Subject: [PATCH 726/790] Add real GEEK for RKP factory enrollment Include a unit test to verify the GEEK cert chain is valid. Test: libkeymint_remote_prov_support_test Ignore-AOSP-First: No merge path to aosp, will manually merge Bug: 191301285 Change-Id: Icf9cfa165fbccb24b36b03ff3ce729a7e9c44cfd --- .../include/remote_prov/remote_prov_utils.h | 30 +++++++++++++++++++ .../keymint/support/remote_prov_utils.cpp | 14 +++++++++ .../support/remote_prov_utils_test.cpp | 29 ++++++++++++++++++ 3 files changed, 73 insertions(+) diff --git a/security/keymint/support/include/remote_prov/remote_prov_utils.h b/security/keymint/support/include/remote_prov/remote_prov_utils.h index e4261f31bc..b02d273fde 100644 --- a/security/keymint/support/include/remote_prov/remote_prov_utils.h +++ b/security/keymint/support/include/remote_prov/remote_prov_utils.h @@ -27,6 +27,31 @@ using namespace cppcose; extern bytevec kTestMacKey; +// The Google root key for the Endpoint Encryption Key chain, encoded as COSE_Sign1 +inline constexpr uint8_t kCoseEncodedRootCert[] = { + 0x84, 0x43, 0xa1, 0x01, 0x27, 0xa0, 0x58, 0x2a, 0xa4, 0x01, 0x01, 0x03, 0x27, 0x20, 0x06, + 0x21, 0x58, 0x20, 0x99, 0xb9, 0xee, 0xdd, 0x5e, 0xe4, 0x52, 0xf6, 0x85, 0xc6, 0x4c, 0x62, + 0xdc, 0x3e, 0x61, 0xab, 0x57, 0x48, 0x7d, 0x75, 0x37, 0x29, 0xad, 0x76, 0x80, 0x32, 0xd2, + 0xb3, 0xcb, 0x63, 0x58, 0xd9, 0x58, 0x40, 0x1e, 0x22, 0x08, 0x4b, 0xa4, 0xb7, 0xa4, 0xc8, + 0xd7, 0x4e, 0x03, 0x0e, 0xfe, 0xb8, 0xaf, 0x14, 0x4c, 0xa7, 0x3b, 0x6f, 0xa5, 0xcd, 0xdc, + 0xda, 0x79, 0xc6, 0x2b, 0x64, 0xfe, 0x99, 0x39, 0xaf, 0x76, 0xe7, 0x80, 0xfa, 0x66, 0x00, + 0x85, 0x0d, 0x07, 0x98, 0x2a, 0xac, 0x91, 0x5c, 0xa7, 0x25, 0x14, 0x49, 0x06, 0x34, 0x75, + 0xca, 0x8a, 0x27, 0x7a, 0xd9, 0xe3, 0x5a, 0x49, 0xeb, 0x02, 0x03}; + +// The Google Endpoint Encryption Key certificate, encoded as COSE_Sign1 +inline constexpr uint8_t kCoseEncodedGeekCert[] = { + 0x84, 0x43, 0xa1, 0x01, 0x27, 0xa0, 0x58, 0x4e, 0xa5, 0x01, 0x01, 0x02, 0x58, 0x20, + 0xd0, 0xae, 0xc1, 0x15, 0xca, 0x2a, 0xcf, 0x73, 0xae, 0x6b, 0xcc, 0xcb, 0xd1, 0x96, + 0x1d, 0x65, 0xe8, 0xb1, 0xdd, 0xd7, 0x4a, 0x1a, 0x37, 0xb9, 0x43, 0x3a, 0x97, 0xd5, + 0x99, 0xdf, 0x98, 0x08, 0x03, 0x38, 0x18, 0x20, 0x04, 0x21, 0x58, 0x20, 0xbe, 0x85, + 0xe7, 0x46, 0xc4, 0xa3, 0x42, 0x5a, 0x40, 0xd9, 0x36, 0x3a, 0xa6, 0x15, 0xd0, 0x2c, + 0x58, 0x7e, 0x3d, 0xdc, 0x33, 0x02, 0x32, 0xd2, 0xfc, 0x5e, 0x1e, 0x87, 0x25, 0x5f, + 0x72, 0x60, 0x58, 0x40, 0x9b, 0xcf, 0x90, 0xe2, 0x2e, 0x4b, 0xab, 0xd1, 0x18, 0xb1, + 0x0e, 0x8e, 0x5d, 0x20, 0x27, 0x4b, 0x84, 0x58, 0xfe, 0xfc, 0x32, 0x90, 0x7e, 0x72, + 0x05, 0x83, 0xbc, 0xd7, 0x82, 0xbe, 0xfa, 0x64, 0x78, 0x2d, 0x54, 0x10, 0x4b, 0xc0, + 0x31, 0xbf, 0x6b, 0xe8, 0x1e, 0x35, 0xe2, 0xf0, 0x2d, 0xce, 0x6c, 0x2f, 0x4f, 0xf2, + 0xf5, 0x4f, 0xa5, 0xd4, 0x83, 0xad, 0x96, 0xa2, 0xf1, 0x87, 0x58, 0x04}; + /** * Generates random bytes. */ @@ -44,6 +69,11 @@ struct EekChain { */ ErrMsgOr generateEekChain(size_t length, const bytevec& eekId); +/** + * Returns the CBOR-encoded, production Google Endpoint Encryption Key chain. + */ +bytevec getProdEekChain(); + struct BccEntryData { bytevec pubKey; }; diff --git a/security/keymint/support/remote_prov_utils.cpp b/security/keymint/support/remote_prov_utils.cpp index ac7cb6219f..982a1eb7b1 100644 --- a/security/keymint/support/remote_prov_utils.cpp +++ b/security/keymint/support/remote_prov_utils.cpp @@ -14,6 +14,8 @@ * limitations under the License. */ +#include + #include #include @@ -82,6 +84,18 @@ ErrMsgOr generateEekChain(size_t length, const bytevec& eekId) { return EekChain{eekChain.encode(), pub_key, priv_key}; } +bytevec getProdEekChain() { + bytevec prodEek; + prodEek.reserve(1 + sizeof(kCoseEncodedRootCert) + sizeof(kCoseEncodedGeekCert)); + + // In CBOR encoding, 0x82 indicates an array of two items + prodEek.push_back(0x82); + prodEek.insert(prodEek.end(), std::begin(kCoseEncodedRootCert), std::end(kCoseEncodedRootCert)); + prodEek.insert(prodEek.end(), std::begin(kCoseEncodedGeekCert), std::end(kCoseEncodedGeekCert)); + + return prodEek; +} + ErrMsgOr verifyAndParseCoseSign1Cwt(const cppbor::Array* coseSign1, const bytevec& signingCoseKey, const bytevec& aad) { if (!coseSign1 || coseSign1->size() != kCoseSign1EntryCount) { diff --git a/security/keymint/support/remote_prov_utils_test.cpp b/security/keymint/support/remote_prov_utils_test.cpp index fbf5b95897..c360c06506 100644 --- a/security/keymint/support/remote_prov_utils_test.cpp +++ b/security/keymint/support/remote_prov_utils_test.cpp @@ -14,13 +14,16 @@ * limitations under the License. */ +#include #include #include #include +#include #include #include #include #include +#include "keymaster/cppcose/cppcose.h" namespace aidl::android::hardware::security::keymint::remote_prov { namespace { @@ -51,5 +54,31 @@ TEST(RemoteProvUtilsTest, GenerateEekChain) { } } +TEST(RemoteProvUtilsTest, GetProdEekChain) { + auto chain = getProdEekChain(); + + auto validation_result = validateAndExtractEekPubAndId( + /*testMode=*/false, KeymasterBlob(chain.data(), chain.size())); + ASSERT_TRUE(validation_result.isOk()) << "Error: " << validation_result.moveError(); + + auto& [eekPub, eekId] = *validation_result; + + auto [geekCert, ignoredNewPos, error] = + cppbor::parse(kCoseEncodedGeekCert, sizeof(kCoseEncodedGeekCert)); + ASSERT_NE(geekCert, nullptr) << "Error: " << error; + ASSERT_NE(geekCert->asArray(), nullptr); + + auto& encodedGeekCoseKey = geekCert->asArray()->get(kCoseSign1Payload); + ASSERT_NE(encodedGeekCoseKey, nullptr); + ASSERT_NE(encodedGeekCoseKey->asBstr(), nullptr); + + auto geek = CoseKey::parse(encodedGeekCoseKey->asBstr()->value()); + ASSERT_TRUE(geek) << "Error: " << geek.message(); + + const std::vector empty; + EXPECT_THAT(eekId, ElementsAreArray(geek->getBstrValue(CoseKey::KEY_ID).value_or(empty))); + EXPECT_THAT(eekPub, ElementsAreArray(geek->getBstrValue(CoseKey::PUBKEY_X).value_or(empty))); +} + } // namespace } // namespace aidl::android::hardware::security::keymint::remote_prov -- GitLab From 3fd4ec47060c3e55de54bcb6678160fb5bdd01e4 Mon Sep 17 00:00:00 2001 From: Lev Proleev Date: Mon, 28 Jun 2021 13:10:54 +0100 Subject: [PATCH 727/790] Fix ordering of cache files requirements from device Data and model numbers were switched in the AIDL implementation of canonical Device. Bug: 190757709 Test: neuralnetworks_utils_hal_aidl_test Change-Id: I0d95b2d436994ffc877a4e02eb31f449b983e61e --- neuralnetworks/aidl/utils/src/Device.cpp | 2 +- neuralnetworks/aidl/utils/test/DeviceTest.cpp | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/neuralnetworks/aidl/utils/src/Device.cpp b/neuralnetworks/aidl/utils/src/Device.cpp index 0fd453b3c7..e80de0be76 100644 --- a/neuralnetworks/aidl/utils/src/Device.cpp +++ b/neuralnetworks/aidl/utils/src/Device.cpp @@ -119,7 +119,7 @@ nn::GeneralResult> getNumberOfCacheFilesNeededFrom << numberOfCacheFiles.numDataCache << " vs " << nn::kMaxNumberOfCacheFiles << ")"; } - return std::make_pair(numberOfCacheFiles.numDataCache, numberOfCacheFiles.numModelCache); + return std::make_pair(numberOfCacheFiles.numModelCache, numberOfCacheFiles.numDataCache); } } // namespace diff --git a/neuralnetworks/aidl/utils/test/DeviceTest.cpp b/neuralnetworks/aidl/utils/test/DeviceTest.cpp index e53b0a8df9..f121acaf7b 100644 --- a/neuralnetworks/aidl/utils/test/DeviceTest.cpp +++ b/neuralnetworks/aidl/utils/test/DeviceTest.cpp @@ -58,7 +58,7 @@ const std::string kInvalidName = ""; const std::shared_ptr kInvalidDevice; constexpr PerformanceInfo kNoPerformanceInfo = {.execTime = std::numeric_limits::max(), .powerUsage = std::numeric_limits::max()}; -constexpr NumberOfCacheFiles kNumberOfCacheFiles = {.numModelCache = nn::kMaxNumberOfCacheFiles, +constexpr NumberOfCacheFiles kNumberOfCacheFiles = {.numModelCache = nn::kMaxNumberOfCacheFiles - 1, .numDataCache = nn::kMaxNumberOfCacheFiles}; constexpr auto makeStatusOk = [] { return ndk::ScopedAStatus::ok(); }; @@ -300,6 +300,21 @@ TEST(DeviceTest, getSupportedExtensionsDeadObject) { EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT); } +TEST(DeviceTest, getNumberOfCacheFilesNeeded) { + // setup call + const auto mockDevice = createMockDevice(); + EXPECT_CALL(*mockDevice, getNumberOfCacheFilesNeeded(_)).Times(1); + + // run test + const auto result = Device::create(kName, mockDevice); + + // verify result + ASSERT_TRUE(result.has_value()); + constexpr auto kNumberOfCacheFilesPair = std::make_pair( + kNumberOfCacheFiles.numModelCache, kNumberOfCacheFiles.numDataCache); + EXPECT_EQ(result.value()->getNumberOfCacheFilesNeeded(), kNumberOfCacheFilesPair); +} + TEST(DeviceTest, getNumberOfCacheFilesNeededError) { // setup call const auto mockDevice = createMockDevice(); -- GitLab From 62272fc2f5fb8ed60eb42aaa2e7e417a7a4223b6 Mon Sep 17 00:00:00 2001 From: David Drysdale Date: Mon, 28 Jun 2021 13:18:23 +0100 Subject: [PATCH 728/790] KeyMint VTS: allow for stricter SharedSecret impls Bug: 192223752 Test: VtsAidlSharedSecretTargetTest Merged-Ind: Iccf2d0fe2a2d10ad12269dfecf78ea1d831c3ad4 Change-Id: Iccf2d0fe2a2d10ad12269dfecf78ea1d831c3ad4 Ignore-AOSP-First: already merged in aosp/master --- .../vts/functional/SharedSecretAidlTest.cpp | 28 +++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/security/sharedsecret/aidl/vts/functional/SharedSecretAidlTest.cpp b/security/sharedsecret/aidl/vts/functional/SharedSecretAidlTest.cpp index 919f882631..51938baa82 100644 --- a/security/sharedsecret/aidl/vts/functional/SharedSecretAidlTest.cpp +++ b/security/sharedsecret/aidl/vts/functional/SharedSecretAidlTest.cpp @@ -268,10 +268,16 @@ TEST_F(SharedSecretAidlTest, ComputeSharedSecretShortNonce) { << "Shared secret service that provided tweaked param should fail to compute " "shared secret"; } else { - EXPECT_EQ(ErrorCode::OK, responses[i].error) << "Others should succeed"; - EXPECT_NE(correct_response, responses[i].sharing_check) - << "Others should calculate a different shared secret, due to the tweaked " - "nonce."; + // Other services *may* succeed, or may notice the invalid size for the nonce. + // However, if another service completes the computation, it should get the 'wrong' + // answer. + if (responses[i].error == ErrorCode::OK) { + EXPECT_NE(correct_response, responses[i].sharing_check) + << "Others should calculate a different shared secret, due to the tweaked " + "nonce."; + } else { + EXPECT_EQ(ErrorCode::INVALID_ARGUMENT, responses[i].error); + } } } } @@ -348,10 +354,16 @@ TEST_F(SharedSecretAidlTest, ComputeSharedSecretShortSeed) { << "Shared secret service that provided tweaked param should fail to compute " "shared secret"; } else { - EXPECT_EQ(ErrorCode::OK, responses[i].error) << "Others should succeed"; - EXPECT_NE(correct_response, responses[i].sharing_check) - << "Others should calculate a different shared secret, due to the tweaked " - "nonce."; + // Other services *may* succeed, or may notice the invalid size for the seed. + // However, if another service completes the computation, it should get the 'wrong' + // answer. + if (responses[i].error == ErrorCode::OK) { + EXPECT_NE(correct_response, responses[i].sharing_check) + << "Others should calculate a different shared secret, due to the tweaked " + "seed."; + } else { + EXPECT_EQ(ErrorCode::INVALID_ARGUMENT, responses[i].error); + } } } } -- GitLab From 382e34835d5c73447728378f244c99e16f91461a Mon Sep 17 00:00:00 2001 From: David Drysdale Date: Mon, 28 Jun 2021 09:36:22 +0100 Subject: [PATCH 729/790] KeyMint HAL: clarify spec text - Make clear that CERTIFICATE_NOT_{BEFORE,AFTER} must be specified for generating/importing asymmetric keys. - Fix enforcement level of Tag::UNLOCKED_DEVICE_REQUIRED. - Fix reference to exportKey() for Tag::STORAGE_KEY to mention convertStorageKeyToEphemeral instead. - Mark Tag::CONFIRMATION_TOKEN as deprecated. Test: none, comment change Bug: 188672564 Merged-In: I68727b024f6b6743403941763aefca64e3eb091a Change-Id: I68727b024f6b6743403941763aefca64e3eb091a Ignore-AOSP-First: already merged in aosp/master --- .../security/keymint/IKeyMintDevice.aidl | 8 ++++++ .../hardware/security/keymint/Tag.aidl | 26 ++++++++++--------- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl index 9cc795d582..4cecff7f7a 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl @@ -277,6 +277,10 @@ interface IKeyMintDevice { * must return ErrorCode::INVALID_ARGUMENT. The values 3 and 65537 must be supported. It is * recommended to support all prime values up to 2^64. * + * o Tag::CERTIFICATE_NOT_BEFORE and Tag::CERTIFICATE_NOT_AFTER specify the valid date range for + * the returned X.509 certificate holding the public key. If omitted, generateKey must return + * ErrorCode::MISSING_NOT_BEFORE or ErrorCode::MISSING_NOT_AFTER. + * * The following parameters are not necessary to generate a usable RSA key, but generateKey must * not return an error if they are omitted: * @@ -297,6 +301,10 @@ interface IKeyMintDevice { * Tag::EC_CURVE must be provided to generate an ECDSA key. If it is not provided, generateKey * must return ErrorCode::UNSUPPORTED_KEY_SIZE. TEE IKeyMintDevice implementations must support * all curves. StrongBox implementations must support P_256. + + * Tag::CERTIFICATE_NOT_BEFORE and Tag::CERTIFICATE_NOT_AFTER must be provided to specify the + * valid date range for the returned X.509 certificate holding the public key. If omitted, + * generateKey must return ErrorCode::MISSING_NOT_BEFORE or ErrorCode::MISSING_NOT_AFTER. * * == AES Keys == * diff --git a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl index 58e02b35b2..270574bbfb 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl @@ -483,12 +483,12 @@ enum Tag { /** * Tag::TRUSTED_CONFIRMATION_REQUIRED is only applicable to keys with KeyPurpose SIGN, and - * specifies that this key must not be usable unless the user provides confirmation of the data - * to be signed. Confirmation is proven to keyMint via an approval token. See - * CONFIRMATION_TOKEN, as well as the ConfirmationUI HAL. + * specifies that this key must not be usable unless the user provides confirmation of the data + * to be signed. Confirmation is proven to keyMint via an approval token. See the authToken + * parameter of begin(), as well as the ConfirmationUI HAL. * * If an attempt to use a key with this tag does not have a cryptographically valid - * CONFIRMATION_TOKEN provided to finish() or if the data provided to update()/finish() does not + * token provided to finish() or if the data provided to update()/finish() does not * match the data described in the token, keyMint must return NO_USER_CONFIRMATION. * * Must be hardware-enforced. @@ -497,9 +497,11 @@ enum Tag { /** * Tag::UNLOCKED_DEVICE_REQUIRED specifies that the key may only be used when the device is - * unlocked. + * unlocked, as reported to KeyMint via authToken operation parameter and the + * IKeyMintDevice::deviceLocked() method * - * Must be software-enforced. + * Must be hardware-enforced (but is also keystore-enforced on a per-user basis: see the + * deviceLocked() documentation). */ UNLOCKED_DEVICE_REQUIRED = (7 << 28) /* TagType:BOOL */ | 509, @@ -870,8 +872,9 @@ enum Tag { * * STORAGE_KEY is used to denote that a key generated or imported is a key used for storage * encryption. Keys of this type can either be generated or imported or secure imported using - * keyMint. exportKey() can be used to re-wrap storage key with a per-boot ephemeral key - * wrapped key once the key characteristics are enforced. + * keyMint. The convertStorageKeyToEphemeral() method of IKeyMintDevice can be used to re-wrap + * storage key with a per-boot ephemeral key wrapped key once the key characteristics are + * enforced. * * Keys with this tag cannot be used for any operation within keyMint. * ErrorCode::INVALID_OPERATION is returned when a key with Tag::STORAGE_KEY is provided to @@ -919,11 +922,10 @@ enum Tag { RESET_SINCE_ID_ROTATION = (7 << 28) /* TagType:BOOL */ | 1004, /** - * Tag::CONFIRMATION_TOKEN is used to deliver a cryptographic token proving that the user - * confirmed a signing request. The content is a full-length HMAC-SHA256 value. See the - * ConfirmationUI HAL for details of token computation. + * OBSOLETE: Do not use. See the authToken parameter for IKeyMintDevice::begin and for + * IKeyMintOperation methods instead. * - * Must never appear in KeyCharacteristics. + * TODO(b/191738660): Delete when keystore1 is deleted. */ CONFIRMATION_TOKEN = (9 << 28) /* TagType:BYTES */ | 1005, -- GitLab From ba831331399e310d53f766920f16a8da062b0f2a Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Tue, 29 Jun 2021 21:42:43 +0000 Subject: [PATCH 730/790] IFace: Add more comments Bug: 152412683 Test: N/A Change-Id: I0d444804acdd7e063c411cc2dec05efb26c6facf --- .../biometrics/face/EnrollmentType.aidl | 9 ++++++++ .../biometrics/face/FaceSensorType.aidl | 21 ++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentType.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentType.aidl index d7f31756bc..c960933996 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentType.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentType.aidl @@ -19,6 +19,15 @@ package android.hardware.biometrics.face; @VintfStability @Backing(type="byte") enum EnrollmentType { + /** + * Default enrollment type. + */ DEFAULT, + + /** + * Enrollment type for people with limited vision or mobility. For example, + * enrollment of this type will not ask the user to move their head or + * look directly at the device. + */ ACCESSIBILITY, } diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/FaceSensorType.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/FaceSensorType.aidl index 57f39d4f51..a5ed2e84e7 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/FaceSensorType.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/FaceSensorType.aidl @@ -16,4 +16,23 @@ package android.hardware.biometrics.face; -@VintfStability @Backing(type="byte") enum FaceSensorType { UNKNOWN, RGB, IR } +@VintfStability +@Backing(type="byte") +enum FaceSensorType { + /** + * Placeholder value used for default initialization of FaceSensorType. + * This value means FaceSensorType wasn't explicitly initialized and must + * be discarded by the recipient. + */ + UNKNOWN, + + /** + * The face sensor is an RGB camera. + */ + RGB, + + /** + * The face sensor is an infrared camera. + */ + IR, +} -- GitLab From b22f307ccfd1072e3d61deb4e03659db7a168b7d Mon Sep 17 00:00:00 2001 From: Carter Hsu Date: Wed, 30 Jun 2021 14:33:09 +0800 Subject: [PATCH 731/790] audio: exclude the echo reference device in capture position test Bug: 192307382 Test: VtsHalAudioV7_0TargetTest --gtest_filter=*PcmOnlyConfigInputStreamTest* Signed-off-by: Carter Hsu Change-Id: I4e38e093bc3be7ee54c0c7cce4d1181e260a23bb --- .../android_audio_policy_configuration_V7_0-enums.h | 8 ++++++++ .../vts/functional/7.0/AudioPrimaryHidlHalTest.cpp | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/audio/common/7.0/enums/include/android_audio_policy_configuration_V7_0-enums.h b/audio/common/7.0/enums/include/android_audio_policy_configuration_V7_0-enums.h index a92a277471..79243b6e05 100644 --- a/audio/common/7.0/enums/include/android_audio_policy_configuration_V7_0-enums.h +++ b/audio/common/7.0/enums/include/android_audio_policy_configuration_V7_0-enums.h @@ -225,6 +225,14 @@ static inline bool isTelephonyDevice(const std::string& device) { return isTelephonyDevice(stringToAudioDevice(device)); } +static inline bool isEchoReferenceDevice(AudioDevice device) { + return device == AudioDevice::AUDIO_DEVICE_IN_ECHO_REFERENCE; +} + +static inline bool isEchoReferenceDevice(const std::string& device) { + return isEchoReferenceDevice(stringToAudioDevice(device)); +} + static inline bool maybeVendorExtension(const std::string& s) { // Only checks whether the string starts with the "vendor prefix". static const std::string vendorPrefix = "VX_"; diff --git a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp index 0b3098b872..79ac295151 100644 --- a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp +++ b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp @@ -710,7 +710,8 @@ class PcmOnlyConfigInputStreamTest : public InputStreamTest { // Returning 'true' when no source is found so the test can fail later with a more clear // problem description. return !maybeSourceAddress.has_value() || - !xsd::isTelephonyDevice(maybeSourceAddress.value().deviceType); + !(xsd::isTelephonyDevice(maybeSourceAddress.value().deviceType) || + xsd::isEchoReferenceDevice(maybeSourceAddress.value().deviceType)); } void createPatchIfNeeded() { -- GitLab From 23f624599f4f72b9e07a051104ccbfcaaaeda3d9 Mon Sep 17 00:00:00 2001 From: Seth Moore Date: Fri, 25 Jun 2021 14:20:15 -0700 Subject: [PATCH 732/790] Add a utility to JSON-format a CSR with build info We need both the build fingerprint as well as the CSR when uploading data to the APFE provisioning server. Add a utility function to format the output as a JSON blob so that it may be easily collected in the factory in a serialized data format, then later uploaded. Test: libkeymint_remote_prov_support_test Test: VtsAidlKeyMintTargetTest Test: VtsHalRemotelyProvisionedComponentTargetTest Bug: 191301285 Change-Id: I751c5461876d83251869539f1a395ba13cb5cf84 --- .../keymint/aidl/vts/functional/Android.bp | 54 +++++++------------ security/keymint/support/Android.bp | 4 ++ .../include/remote_prov/remote_prov_utils.h | 22 ++++++++ .../keymint/support/remote_prov_utils.cpp | 42 +++++++++++++-- .../support/remote_prov_utils_test.cpp | 17 ++++++ 5 files changed, 101 insertions(+), 38 deletions(-) diff --git a/security/keymint/aidl/vts/functional/Android.bp b/security/keymint/aidl/vts/functional/Android.bp index ff08ce626e..386029f306 100644 --- a/security/keymint/aidl/vts/functional/Android.bp +++ b/security/keymint/aidl/vts/functional/Android.bp @@ -23,16 +23,11 @@ package { default_applicable_licenses: ["hardware_interfaces_license"], } -cc_test { - name: "VtsAidlKeyMintTargetTest", +cc_defaults { + name: "keymint_vts_defaults", defaults: [ - "VtsHalTargetTestDefaults", "use_libaidlvintf_gtest_helper_static", - ], - srcs: [ - "AttestKeyTest.cpp", - "DeviceUniqueAttestationTest.cpp", - "KeyMintTest.cpp", + "VtsHalTargetTestDefaults", ], shared_libs: [ "libbinder_ndk", @@ -43,9 +38,24 @@ cc_test { "android.hardware.security.secureclock-V1-ndk_platform", "libcppbor_external", "libcppcose_rkp", + "libjsoncpp", "libkeymint", "libkeymint_remote_prov_support", "libkeymint_support", + ], +} + +cc_test { + name: "VtsAidlKeyMintTargetTest", + defaults: [ + "keymint_vts_defaults", + ], + srcs: [ + "AttestKeyTest.cpp", + "DeviceUniqueAttestationTest.cpp", + "KeyMintTest.cpp", + ], + static_libs: [ "libkeymint_vts_test_utils", ], test_suites: [ @@ -57,8 +67,7 @@ cc_test { cc_test_library { name: "libkeymint_vts_test_utils", defaults: [ - "VtsHalTargetTestDefaults", - "use_libaidlvintf_gtest_helper_static", + "keymint_vts_defaults", ], srcs: [ "KeyMintAidlTestBase.cpp", @@ -66,45 +75,22 @@ cc_test_library { export_include_dirs: [ ".", ], - shared_libs: [ - "libbinder_ndk", - "libcrypto", - ], static_libs: [ - "android.hardware.security.keymint-V1-ndk_platform", - "android.hardware.security.secureclock-V1-ndk_platform", - "libcppbor_external", - "libcppcose_rkp", "libgmock_ndk", - "libkeymint", - "libkeymint_remote_prov_support", - "libkeymint_support", ], } cc_test { name: "VtsHalRemotelyProvisionedComponentTargetTest", defaults: [ - "VtsHalTargetTestDefaults", - "use_libaidlvintf_gtest_helper_static", + "keymint_vts_defaults", ], srcs: [ "VtsRemotelyProvisionedComponentTests.cpp", ], - shared_libs: [ - "libbinder_ndk", - "libcrypto", - ], static_libs: [ - "android.hardware.security.keymint-V1-ndk_platform", - "android.hardware.security.secureclock-V1-ndk_platform", - "libcppbor_external", - "libcppcose_rkp", "libgmock_ndk", "libkeymaster_portable", - "libkeymint", - "libkeymint_support", - "libkeymint_remote_prov_support", "libkeymint_vts_test_utils", "libpuresoftkeymasterdevice", ], diff --git a/security/keymint/support/Android.bp b/security/keymint/support/Android.bp index c2dba044bf..9e218b6a3d 100644 --- a/security/keymint/support/Android.bp +++ b/security/keymint/support/Android.bp @@ -57,9 +57,11 @@ cc_library { "include", ], shared_libs: [ + "libbase", "libcppbor_external", "libcppcose_rkp", "libcrypto", + "libjsoncpp", ], } @@ -71,9 +73,11 @@ cc_test { "libgtest_main", ], shared_libs: [ + "libbase", "libcppbor_external", "libcppcose_rkp", "libcrypto", + "libjsoncpp", "libkeymaster_portable", "libkeymint_remote_prov_support", ], diff --git a/security/keymint/support/include/remote_prov/remote_prov_utils.h b/security/keymint/support/include/remote_prov/remote_prov_utils.h index b02d273fde..406b7a9b79 100644 --- a/security/keymint/support/include/remote_prov/remote_prov_utils.h +++ b/security/keymint/support/include/remote_prov/remote_prov_utils.h @@ -87,4 +87,26 @@ struct BccEntryData { */ ErrMsgOr> validateBcc(const cppbor::Array* bcc); +struct JsonOutput { + static JsonOutput Ok(std::string json) { return {std::move(json), ""}; } + static JsonOutput Error(std::string error) { return {"", std::move(error)}; } + + std::string output; + std::string error; // if non-empty, this describes what went wrong +}; + +/** + * Take a given certificate request and output a JSON blob containing both the + * build fingerprint and certificate request. This data may be serialized, then + * later uploaded to the remote provisioning service. The input csr is not + * validated, only encoded. + * + * Output format: + * { + * "build_fingerprint": + * "csr": + * } + */ +JsonOutput jsonEncodeCsrWithBuild(const cppbor::Array& csr); + } // namespace aidl::android::hardware::security::keymint::remote_prov diff --git a/security/keymint/support/remote_prov_utils.cpp b/security/keymint/support/remote_prov_utils.cpp index 982a1eb7b1..0cbee51044 100644 --- a/security/keymint/support/remote_prov_utils.cpp +++ b/security/keymint/support/remote_prov_utils.cpp @@ -14,13 +14,15 @@ * limitations under the License. */ +#include #include -#include - -#include - +#include #include +#include +#include +#include +#include namespace aidl::android::hardware::security::keymint::remote_prov { @@ -180,4 +182,36 @@ ErrMsgOr> validateBcc(const cppbor::Array* bcc) { return result; } +JsonOutput jsonEncodeCsrWithBuild(const cppbor::Array& csr) { + const std::string kFingerprintProp = "ro.build.fingerprint"; + + if (!::android::base::WaitForPropertyCreation(kFingerprintProp)) { + return JsonOutput::Error("Unable to read build fingerprint"); + } + + bytevec csrCbor = csr.encode(); + size_t base64Length; + int rc = EVP_EncodedLength(&base64Length, csrCbor.size()); + if (!rc) { + return JsonOutput::Error("Error getting base64 length. Size overflow?"); + } + + std::vector base64(base64Length); + rc = EVP_EncodeBlock(reinterpret_cast(base64.data()), csrCbor.data(), csrCbor.size()); + ++rc; // Account for NUL, which BoringSSL does not for some reason. + if (rc != base64Length) { + return JsonOutput::Error("Error writing base64. Expected " + std::to_string(base64Length) + + " bytes to be written, but " + std::to_string(rc) + + " bytes were actually written."); + } + + Json::Value json(Json::objectValue); + json["build_fingerprint"] = ::android::base::GetProperty(kFingerprintProp, /*default=*/""); + json["csr"] = base64.data(); // Boring writes a NUL-terminated c-string + + Json::StreamWriterBuilder factory; + factory["indentation"] = ""; // disable pretty formatting + return JsonOutput::Ok(Json::writeString(factory, json)); +} + } // namespace aidl::android::hardware::security::keymint::remote_prov diff --git a/security/keymint/support/remote_prov_utils_test.cpp b/security/keymint/support/remote_prov_utils_test.cpp index c360c06506..8697c5190f 100644 --- a/security/keymint/support/remote_prov_utils_test.cpp +++ b/security/keymint/support/remote_prov_utils_test.cpp @@ -14,6 +14,7 @@ * limitations under the License. */ +#include #include #include #include @@ -23,6 +24,7 @@ #include #include #include +#include "cppbor.h" #include "keymaster/cppcose/cppcose.h" namespace aidl::android::hardware::security::keymint::remote_prov { @@ -80,5 +82,20 @@ TEST(RemoteProvUtilsTest, GetProdEekChain) { EXPECT_THAT(eekPub, ElementsAreArray(geek->getBstrValue(CoseKey::PUBKEY_X).value_or(empty))); } +TEST(RemoteProvUtilsTest, JsonEncodeCsr) { + cppbor::Array array; + array.add(1); + + auto [json, error] = jsonEncodeCsrWithBuild(array); + + ASSERT_TRUE(error.empty()) << error; + + std::string expected = R"({"build_fingerprint":")" + + ::android::base::GetProperty("ro.build.fingerprint", /*default=*/"") + + R"(","csr":"gQE="})"; + + ASSERT_EQ(json, expected); +} + } // namespace } // namespace aidl::android::hardware::security::keymint::remote_prov -- GitLab From 8b372b6734a9e787a94dd7a5c541ba30c11df060 Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Wed, 30 Jun 2021 18:26:35 +0000 Subject: [PATCH 733/790] IFace: update comments Bug: 152412683 Test: N/A Change-Id: I4bae4ba9eaa5631d72d5665b54dd5c2b23f7f4d5 --- .../hardware/biometrics/face/IFace.aidl | 22 +- .../hardware/biometrics/face/ISession.aidl | 192 +++++++++++------- .../biometrics/face/ISessionCallback.aidl | 26 +-- 3 files changed, 147 insertions(+), 93 deletions(-) diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/IFace.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/IFace.aidl index 11cdf7753e..4d7e59ebb7 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/IFace.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/IFace.aidl @@ -25,28 +25,30 @@ interface IFace { /** * getSensorProps: * - * @return A list of properties for all face sensors available to the HAL. + * @return A list of properties for all of the face sensors supported by the HAL. */ SensorProps[] getSensorProps(); /** * createSession: * - * Creates a session that can be used by the framework to perform operations such as - * enroll, authenticate, etc. for the given sensorId and userId. + * Creates an instance of ISession that can be used by the framework to perform operations such + * as ISession#enroll, ISession#authenticate, etc. for the given sensorId and userId. * - * Calling this method while there is an active session is considered an error. If the - * framework is in a bad state and for some reason cannot close its session, it should use - * the reset method below. + * Calling this method while there is an active session is considered an error. If the framework + * wants to create a new session when it already has an active session, it must first cancel the + * current operation if it's cancellable or wait until it completes. Then, the framework must + * explicitly close the session with ISession#close. Once the framework receives + * ISessionCallback#onSessionClosed, a new session can be created. * * Implementations must store user-specific state or metadata in /data/vendor_de//facedata * as specified by the SELinux policy. The directory /data/vendor_de is managed by vold (see * vold_prepare_subdirs.cpp). Implementations may store additional user-specific data, such as - * embeddings or templates in StrongBox. + * embeddings or templates, in StrongBox. * - * @param sensorId The sensorId with which this session is being created. - * @param userId The userId with which this session is being created. - * @param cb A callback to notify the framework about the session's results and events. + * @param sensorId The sensorId for which this session is being created. + * @param userId The userId for which this session is being created. + * @param cb A callback to notify the framework about the session's events. * @return A new session. */ ISession createSession(in int sensorId, in int userId, in ISessionCallback cb); diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl index a9a8c16cf2..2a57e3aa46 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl @@ -24,13 +24,12 @@ import android.hardware.common.NativeHandle; import android.hardware.keymaster.HardwareAuthToken; /** - * Operations that can be performed for unique sessions retrieved via IFace#createSession. * Operations defined within this interface can be divided into the following categories: * 1) Cancellable operations. These are usually the operations that can execute for several - * minutes. To allow for cancellation, they return an instance of ICancellationSignal that - * lets the framework cancel them by calling ICancellationSignal#cancel. If such an operation - * is cancelled, it must notify the framework by calling ISessionCallback#onError with - * Error::CANCELED. + * minutes. To allow for cancellation, they return an instance of ICancellationSignal that + * lets the framework cancel them by calling ICancellationSignal#cancel. If such an operation + * is cancelled, it must notify the framework by calling ISessionCallback#onError with + * Error::CANCELED. * 2) Non-cancellable operations. Such operations cannot be cancelled once started. * * The lifecycle of an operation ends when one of its terminal callbacks is called. For example, @@ -83,15 +82,20 @@ interface ISession { * | 0 | 10 | | | * ---------------------------------------------- * + * Callbacks that signify the end of this operation's lifecycle: + * - ISessionCallback#onChallengeGenerated + * */ void generateChallenge(); /** * revokeChallenge: * - * Revokes a challenge that was previously generated. Note that if an invalid combination of - * parameters is requested, the implementation must still notify the framework using the - * provided callback. + * Revokes a challenge that was previously generated. Note that if a non-existent challenge is + * provided, the HAL must still notify the framework using ISessionCallback#onChallengeRevoked. + * + * Callbacks that signify the end of this operation's lifecycle: + * - ISessionCallback#onChallengeRevoked * * @param challenge Challenge that should be revoked. */ @@ -100,9 +104,9 @@ interface ISession { /** * getEnrollmentConfig: * - * Returns the enrollment configuration depending on the provided enrollment type. Enrollment - * configuration determines how many stages the enrollment will have and the requirements for - * each of the stages. + * Returns the enrollment configuration for the provided enrollment type. Enrollment + * configuration determines how many stages the enrollment will have and the requirements + * for each of the stages. * * @param enrollmentType See the EnrollmentType enum. * @return An EnrollmentStageConfig array that describes each enrollment stage. @@ -117,22 +121,28 @@ interface ISession { * At any point during enrollment, if a non-recoverable error occurs, the HAL must notify the * framework via ISessionCallback#onError with the applicable enrollment-specific error. * - * Before capturing face data, the implementation must first verify the authenticity and - * integrity of the provided HardwareAuthToken. In addition, it must check that the challenge - * within the provided HardwareAuthToken is valid. See ISession#generateChallenge. If any of - * the above checks fail, the framework must be notified using ISessionCallback#onError with - * Error::UNABLE_TO_PROCESS. + * Before capturing face data, the HAL must first verify the authenticity and integrity of the + * provided HardwareAuthToken. In addition, it must check that the challenge within the provided + * HardwareAuthToken is valid. See ISession#generateChallenge. If any of the above checks fail, + * the framework must be notified using ISessionCallback#onError with Error::UNABLE_TO_PROCESS. * - * During enrollment, the implementation may notify the framework via - * ISessionCallback#onAcquired with messages that may be used to guide the user. This callback - * can be invoked multiple times if necessary. Similarly, the framework may be notified of - * enrollment progress changes via ISessionCallback#onEnrollmentProgress. Once the framework is - * notified that there are 0 "remaining" steps, the framework may cache the "enrollmentId". See + * During enrollment, the HAL may notify the framework via ISessionCallback#onAcquired with + * messages that may be used to guide the user. This callback can be invoked multiple times if + * necessary. Similarly, the framework may be notified of enrollment progress changes via + * ISessionCallback#onEnrollmentProgress. Once the framework is notified that there are 0 + * "remaining" steps, the framework may cache the "enrollmentId". See * ISessionCallback#onEnrollmentProgress for more info. * * When a face is successfully added and before the framework is notified of remaining=0, the - * implementation MUST update and associate this (sensorId, userId) pair with a new - * entropy-encoded random identifier. See ISession#getAuthenticatorId for more information. + * HAL must update and associate this (sensorId, userId) pair with a new entropy-encoded random + * identifier. See ISession#getAuthenticatorId for more information. + * + * Callbacks that signify the end of this operation's lifecycle: + * - ISessionCallback#onError + * - ISessionCallback#onEnrollmentProgress(enrollmentId, remaining=0) + * + * Other applicable callbacks: + * - ISessionCallback#onAcquired * * @param hat See above documentation. * @param enrollmentType See the EnrollmentType enum. @@ -154,15 +164,18 @@ interface ISession { * At any point during authentication, if a non-recoverable error occurs, the HAL must notify * the framework via ISessionCallback#onError with the applicable authentication-specific error. * - * During authentication, the implementation may notify the framework via - * ISessionCallback#onAcquired with messages that may be used to guide the user. This callback - * can be invoked multiple times if necessary. + * During authentication, the HAL may notify the framework via ISessionCallback#onAcquired with + * messages that may be used to guide the user. This callback can be invoked multiple times if + * necessary. * - * The HAL must notify the framework of accepts/rejects via ISessionCallback#onAuthentication*. + * The HAL must notify the framework of accepts/rejects via + * ISessionCallback#onAuthenticationSucceeded and ISessionCallback#onAuthenticationFailed, + * correspondingly. * - * The authentication lifecycle ends when either - * 1) A face is accepted, and ISessionCallback#onAuthenticationSucceeded is invoked, or - * 2) Any non-recoverable error occurs (such as lockout). See the full list of + * The authentication lifecycle ends when any of the following happens: + * 1) A face is accepted, and ISessionCallback#onAuthenticationSucceeded is invoked. + * 2) A face is rejected, and ISessionCallback#onAuthenticationFailed is invoked. + * 3) Any non-recoverable error occurs (such as lockout). See the full list of * authentication-specific errors in the Error enum. * * Note that upon successful authentication, the lockout counter for this (sensorId, userId) @@ -174,16 +187,26 @@ interface ISession { * must be set with the operationId passed in during #authenticate. If the sensor is NOT * SensorStrength::STRONG, the HardwareAuthToken MUST be null. * + * Callbacks that signify the end of this operation's lifecycle: + * - ISessionCallback#onError + * - ISessionCallback#onAuthenticationSucceeded + * - ISessionCallback#onAuthenticationFailed + * + * Other applicable callbacks: + * - ISessionCallback#onAcquired + * - ISessionCallback#onLockoutTimed + * - ISessionCallback#onLockoutPermanent + * * @param operationId For sensors configured as SensorStrength::STRONG, this must be used ONLY * upon successful authentication and wrapped in the HardwareAuthToken's * "challenge" field and sent to the framework via - * ISessionCallback#onAuthenticated. The operationId is an opaque identifier - * created from a separate secure subsystem such as, but not limited to - * KeyStore/KeyMaster. The HardwareAuthToken can then be used as an - * attestation for the provided operation. For example, this is used - * to unlock biometric-bound auth-per-use keys (see + * ISessionCallback#onAuthenticationSucceeded. The operationId is an opaque + * identifier created from a separate secure subsystem such as, but not + * limited to KeyStore/KeyMaster. The HardwareAuthToken can then be used as + * an attestation for the provided operation. For example, this is used to + * unlock biometric-bound auth-per-use keys (see * setUserAuthenticationParameters in KeyGenParameterSpec.Builder and - * KeyProtection.Builder. + * KeyProtection.Builder). * @return ICancellationSignal An object that can be used by the framework to cancel this * operation. */ @@ -193,32 +216,36 @@ interface ISession { * detectInteraction: * * A request to start looking for faces without performing matching. Must only be called if - * SensorProps#supportsDetectInteraction is true. If invoked on implementations that do not - * support this functionality, the HAL must respond with ISession#onError(UNABLE_TO_PROCESS, 0). + * SensorProps#supportsDetectInteraction is true. If invoked on HALs that do not support this + * functionality, the HAL must respond with ISession#onError(UNABLE_TO_PROCESS, 0). * - * The framework will use this method in cases where determing user presence is required, but - * identifying/authentication is not. For example, when the device is encrypted (first boot) or - * in lockdown mode. + * The framework will use this operation in cases where determining user presence is required, + * but identifying/authenticating is not. For example, when the device is encrypted (first boot) + * or in lockdown mode. * * At any point during detectInteraction, if a non-recoverable error occurs, the HAL must notify * the framework via ISessionCallback#onError with the applicable error. * - * The implementation must only check for a face-like image was detected (e.g. to - * minimize interactions due to non-face objects), and the lockout counter must not - * be modified. + * The HAL must only check whether a face-like image was detected (e.g. to minimize interactions + * due to non-face objects), and the lockout counter must not be modified. * - * Upon detecting any face, the implementation must invoke - * ISessionCallback#onInteractionDetected. + * Upon detecting any face, the HAL must invoke ISessionCallback#onInteractionDetected. * - * The lifecycle of this operation ends when either + * The lifecycle of this operation ends when either: * 1) Any face is detected and the framework is notified via - * ISessionCallback#onInteractiondetected - * 2) The operation was cancelled by the framework (see ICancellationSignal) - * 3) An error occurred, for example ERROR::TIMEOUT + * ISessionCallback#onInteractionDetected. + * 2) An error occurrs, for example Error::TIMEOUT. * - * Note that if the operation is canceled, the implementation must notify the framework via + * Note that if the operation is canceled, the HAL must notify the framework via * ISessionCallback#onError with Error::CANCELED. * + * Callbacks that signify the end of this operation's lifecycle: + * - ISessionCallback#onError + * - ISessionCallback#onInteractionDetected + * + * Other applicable callbacks: + * - ISessionCallback#onAcquired + * * @return ICancellationSignal An object that can be used by the framework to cancel this * operation. */ @@ -227,12 +254,14 @@ interface ISession { /* * enumerateEnrollments: * - * A request to enumerate (list) the enrollments for this (sensorId, userId) pair. The - * framework typically uses this to ensure that its cache is in sync with the HAL. + * A request to enumerate (list) the enrollments for this (sensorId, userId) pair. The framework + * typically uses this to ensure that its cache is in sync with the HAL. * - * The implementation must then notify the framework with a list of enrollments applicable - * for the current session via ISessionCallback#onEnrollmentsEnumerated. + * The HAL must then notify the framework with a list of enrollments applicable for the current + * session via ISessionCallback#onEnrollmentsEnumerated. * + * Callbacks that signify the end of this operation's lifecycle: + * - ISessionCallback#onEnrollmentsEnumerated */ void enumerateEnrollments(); @@ -242,8 +271,12 @@ interface ISession { * A request to remove the enrollments for this (sensorId, userId) pair. * * After removing the enrollmentIds from everywhere necessary (filesystem, secure subsystems, - * etc), the implementation must notify the framework via ISessionCallback#onEnrollmentsRemoved. + * etc), the HAL must notify the framework via ISessionCallback#onEnrollmentsRemoved. * + * Callbacks that signify the end of this operation's lifecycle: + * - ISessionCallback#onEnrollmentsRemoved + * + * @param enrollmentIds a list of enrollments that should be removed. */ void removeEnrollments(in int[] enrollmentIds); @@ -257,6 +290,10 @@ interface ISession { * * The HAL must notify the framework about the result by calling * ISessionCallback#onFeaturesRetrieved. + * + * Callbacks that signify the end of this operation's lifecycle: + * - ISessionCallback#onError + * - ISessionCallback#onFeaturesRetrieved */ void getFeatures(); @@ -264,15 +301,19 @@ interface ISession { * setFeature: * * Enables or disables a feature for this (sensorId, userId) pair. Because certain features may - * decrease security, the user must enter their password before this method is invoked - * (see @param hat). The HAL must verify the hat before changing any feature state. + * decrease security, the user must enter their password before this operation is invoked + * (see @param hat). The HAL must verify the HAT before changing any feature state. * - * If the hat is invalid or if the user is not enrolled, the HAL must invoke + * If the HAT is invalid or if the user is not enrolled, the HAL must invoke * ISessionCallback#onError with Error::UNABLE_TO_PROCESS. * * After the feature is successfully set, the HAL must notify the framework by calling * ISessionCallback#onFeatureSet. * + * Callbacks that signify the end of this operation's lifecycle: + * - ISessionCallback#onError + * - ISessionCallback#onFeatureSet + * * @param hat HardwareAuthToken See above documentation. * @param feature The feature to be enabled or disabled. * @param enabled Whether the provided features should be enabled or disabled. @@ -295,8 +336,8 @@ interface ISession { * KeyProtection.Builder.setInvalidatedByBiometricEnrollment. * * In addition, upon successful face authentication, the signed HAT that is returned to - * the framework via ISessionCallback#onAuthenticated must contain this identifier in the - * authenticatorId field. + * the framework via ISessionCallback#onAuthenticationSucceeded must contain this identifier in + * the authenticatorId field. * * Returns an entropy-encoded random identifier associated with the current set of enrollments * via ISessionCallback#onAuthenticatorIdRetrieved. The authenticatorId @@ -305,20 +346,21 @@ interface ISession { * 3) MUST not change if a face is deleted. * 4) MUST be an entropy-encoded random number * + * Callbacks that signify the end of this operation's lifecycle: + * - ISessionCallback#onAuthenticatorIdRetrieved */ void getAuthenticatorId(); /** * invalidateAuthenticatorId: * - * This method only applies to sensors that are configured as SensorStrength::STRONG. If invoked - * by the framework for sensor of other strengths, the HAL should immediately invoke + * This operation only applies to sensors that are configured as SensorStrength::STRONG. If + * invoked by the framework for sensors of other strengths, the HAL should immediately invoke * ISessionCallback#onAuthenticatorIdInvalidated. * * The following only applies to sensors that are configured as SensorStrength::STRONG. * - * When invoked by the framework, the implementation must perform the following sequence of - * events: + * When invoked by the framework, the HAL must perform the following sequence of events: * 1) Update the authenticatorId with a new entropy-encoded random number * 2) Persist the new authenticatorId to non-ephemeral storage * 3) Notify the framework that the above is completed, via @@ -326,18 +368,20 @@ interface ISession { * * A practical use case of invalidation would be when the user adds a new enrollment to a sensor * managed by a different HAL instance. The public android.security.keystore APIs bind keys to - * "all biometrics" rather than "face-only" or "face-only" (see #getAuthenticatorId - * for more details). As such, the framework would coordinate invalidation across multiple - * biometric HALs as necessary. + * "all biometrics" rather than "fingerprint-only" or "face-only" (see #getAuthenticatorId for + * more details). As such, the framework would coordinate invalidation across multiple biometric + * HALs as necessary. * + * Callbacks that signify the end of this operation's lifecycle: + * - ISessionCallback#onAuthenticatorIdInvalidated */ void invalidateAuthenticatorId(); /** * resetLockout: * - * Requests the implementation to clear the lockout counter. Upon receiving this request, the - * implementation must perform the following: + * Requests the HAL to clear the lockout counter. Upon receiving this request, the HAL must + * perform the following: * 1) Verify the authenticity and integrity of the provided HAT * 2) Verify that the timestamp provided within the HAT is relatively recent (e.g. on the * order of minutes, not hours). @@ -373,6 +417,9 @@ interface ISession { * See the Android CDD section 7.3.10 for the full set of lockout and rate-limiting * requirements. * + * Callbacks that signify the end of this operation's lifecycle: + * - ISessionCallback#onLockoutCleared + * * @param hat HardwareAuthToken See above documentation. */ void resetLockout(in HardwareAuthToken hat); @@ -384,9 +431,14 @@ interface ISession { * If the HAL is busy performing a cancellable operation, the operation must be explicitly * cancelled with a call to ICancellationSignal#cancel before the session can be closed. * + * After a session is closed, the HAL must notify the framework by calling + * ISessionCallback#onSessionClosed. + * * All sessions must be explicitly closed. Calling IFace#createSession while there is an active * session is considered an error. * + * Callbacks that signify the end of this operation's lifecycle: + * - ISessionCallback#onSessionClosed */ void close(); } diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl index 23570bd753..b3c348d521 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl @@ -37,11 +37,11 @@ interface ISessionCallback { /** * This method must only be used to notify the framework during the following operations: - * 1) ISession#authenticate - * 2) ISession#detectInteraction + * - ISession#authenticate + * - ISession#detectInteraction * - * These messages may be used to provide user guidance multiple times if necessary per - * operation. + * These messages may be used to provide user guidance multiple times per operation if + * necessary. * * @param frame See the AuthenticationFrame enum. */ @@ -51,8 +51,8 @@ interface ISessionCallback { * This method must only be used to notify the framework during the ISession#enroll * operation. * - * These messages may be used to provide user guidance multiple times if necessary per - * operation. + * These messages may be used to provide user guidance multiple times per operation if + * necessary. * * @param frame See the EnrollmentFrame enum. */ @@ -60,18 +60,18 @@ interface ISessionCallback { /** * This method must only be used to notify the framework during the following operations: - * 1) ISession#enroll - * 2) ISession#authenticate - * 3) ISession#detectInteraction - * 4) ISession#invalidateAuthenticatorId - * 5) ISession#resetLockout + * - ISession#enroll + * - ISession#authenticate + * - ISession#detectInteraction + * - ISession#invalidateAuthenticatorId + * - ISession#resetLockout * * These messages may be used to notify the framework or user that a non-recoverable error * has occurred. The operation is finished, and the HAL must proceed with the next operation * or return to the idling state. * - * Note that cancellation (see common::ICancellationSignal) and preemption must be followed with - * an Error::CANCELED message. + * Note that cancellation (see common::ICancellationSignal) must be followed with an + * Error::CANCELED message. * * @param error See the Error enum. * @param vendorCode Only valid if error == Error::VENDOR. The vendorCode must be used to index -- GitLab From ea8115d85d4530ae204abffb613059337c62c2ce Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Wed, 30 Jun 2021 18:27:27 +0000 Subject: [PATCH 734/790] IFingerprint: update comments Bug: 166824758 Test: N/A Change-Id: Ie77034b88bea1c1317e8d057f19f57167d48d2c3 --- .../biometrics/fingerprint/IFingerprint.aidl | 20 +- .../biometrics/fingerprint/ISession.aidl | 226 +++++++++++------- .../fingerprint/ISessionCallback.aidl | 28 +-- 3 files changed, 162 insertions(+), 112 deletions(-) diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl index 271a9bf1cf..75f90a12ae 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl @@ -25,31 +25,31 @@ interface IFingerprint { /** * getSensorProps: * - * @return A list of properties for all sensors that an instance of the HAL supports. + * @return A list of properties for all of the fingerprint sensors supported by the HAL. */ SensorProps[] getSensorProps(); /** * createSession: * - * Creates a instance of ISession which can be used by the framework to perform operations - * such as ISession#enroll, ISession#authenticate, etc. for the given sensorId and userId. + * Creates an instance of ISession that can be used by the framework to perform operations such + * as ISession#enroll, ISession#authenticate, etc. for the given sensorId and userId. * * Calling this method while there is an active session is considered an error. If the framework * wants to create a new session when it already has an active session, it must first cancel the - * current operation if it's cancellable, or wait until it completes. Then, the framework must + * current operation if it's cancellable or wait until it completes. Then, the framework must * explicitly close the session with ISession#close. Once the framework receives * ISessionCallback#onSessionClosed, a new session can be created. * * Implementations must store user-specific state or metadata in /data/vendor_de//fpdata - * as specified by the SeLinux policy. This directory is created/removed by vold (see + * as specified by the SELinux policy. The directory /data/vendor_de is managed by vold (see * vold_prepare_subdirs.cpp). Implementations may store additional user-specific data, such as - * embeddings or templates in StrongBox. + * embeddings or templates, in StrongBox. * - * @param sensorId The sensor with which this session is being created. - * @param userId The userId with which this session is being created. - * @param cb Used to notify the framework. - * @return A new session + * @param sensorId The sensorId for which this session is being created. + * @param userId The userId for which this session is being created. + * @param cb A callback to notify the framework about the session's events. + * @return A new session. */ ISession createSession(in int sensorId, in int userId, in ISessionCallback cb); } diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl index 02ef138427..f1d96d3039 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl @@ -20,30 +20,29 @@ import android.hardware.biometrics.common.ICancellationSignal; import android.hardware.keymaster.HardwareAuthToken; /** - * Operations that can be performed for unique sessions retrieved via IFingerprint#createSession. - * Methods defined within this interface can be split into the following categories: - * 1) Non-interrupting operations. These operations are handled by the HAL in FIFO order. - * 1a) Cancellable operations. These are usually the operations that can execute for several - * minutes. To allow for cancellation, they return an instance of ICancellationSignal that - * lets the framework cancel them by calling ICancellationSignal#cancel. If such an operation - * is cancelled, it must notify the framework by calling ISessionCallback#onError with - * Error::CANCELED. - * 1b) Non-cancellable operations. Such operations cannot be cancelled once started. + * Operations defined within this interface can be split into the following categories: + * 1) Non-interrupting operations. These operations are handled by the HAL in a FIFO order. + * 1a) Cancellable operations. These operations can usually run for several minutes. To allow + * for cancellation, they return an instance of ICancellationSignal that allows the + * framework to cancel them by calling ICancellationSignal#cancel. If such an operation is + * cancelled, it must notify the framework by calling ISessionCallback#onError with + * Error::CANCELED. + * 1b) Non-cancellable operations. Such operations cannot be cancelled once started. * 2) Interrupting operations. These operations may be invoked by the framework immediately, * regardless of whether another operation is executing. For example, on devices with sensors - * of FingerprintSensorType::UNDER_DISPLAY_*, ISession#onFingerDown may be invoked while the + * of FingerprintSensorType::UNDER_DISPLAY_*, ISession#onPointerDown may be invoked while the * HAL is executing ISession#enroll, ISession#authenticate or ISession#detectInteraction. * - * The lifecycle of a non-interrupting operation ends when one of its terminal callbacks is called. - * For example, ISession#authenticate is considered completed when either of the following callbacks - * is called: ISessionCallback#onError or ISessionCallback#onAuthenticationSucceeded. + * The lifecycle of a non-interrupting operation ends when one of its final callbacks is called. + * For example, ISession#authenticate is considered completed when either ISessionCallback#onError + * or ISessionCallback#onAuthenticationSucceeded is called. * * The lifecycle of an interrupting operation ends when it returns. Interrupting operations do not * have callbacks. * * ISession only supports execution of one non-interrupting operation at a time, regardless of - * whether it's cancellable. The framework must wait for a corresponding callback indicating the end - * of the current non-interrupting operation before a new non-interrupting operation can be started. + * whether it's cancellable. The framework must wait for a callback indicating the end of the + * current non-interrupting operation before a new non-interrupting operation can be started. */ @VintfStability interface ISession { @@ -89,15 +88,19 @@ interface ISession { * | 0 | 10 | | | * ---------------------------------------------- * + * Callbacks that signify the end of this operation's lifecycle: + * - ISessionCallback#onChallengeGenerated */ void generateChallenge(); /** * revokeChallenge: * - * Revokes a challenge that was previously generated. Note that if an invalid combination of - * parameters is requested, the implementation must still notify the framework using the - * provided callback. + * Revokes a challenge that was previously generated. Note that if a non-existent challenge is + * provided, the HAL must still notify the framework using ISessionCallback#onChallengeRevoked. + * + * Callbacks that signify the end of this operation's lifecycle: + * - ISessionCallback#onChallengeRevoked * * @param challenge Challenge that should be revoked. */ @@ -111,26 +114,33 @@ interface ISession { * At any point during enrollment, if a non-recoverable error occurs, the HAL must notify the * framework via ISessionCallback#onError with the applicable enrollment-specific error. * - * Before capturing fingerprint data, the implementation must first verify the authenticity and - * integrity of the provided HardwareAuthToken. In addition, it must check that the challenge - * within the provided HardwareAuthToken is valid. See ISession#generateChallenge. If any of - * the above checks fail, the framework must be notified via ISessionCallback#onError and the - * HAL must notify the framework when it returns to the idle state. See + * Before capturing fingerprint data, the HAL must first verify the authenticity and integrity + * of the provided HardwareAuthToken. In addition, it must check that the challenge within the + * provided HardwareAuthToken is valid. See ISession#generateChallenge. If any of the above + * checks fail, the framework must be notified using ISessionCallback#onError with * Error::UNABLE_TO_PROCESS. * - * During enrollment, the implementation may notify the framework via - * ISessionCallback#onAcquired with messages that may be used to guide the user. This callback - * can be invoked multiple times if necessary. Similarly, the framework may be notified of - * enrollment progress changes via ISessionCallback#onEnrollmentProgress. Once the framework is - * notified that there are 0 "remaining" steps, the framework may cache the "enrollmentId". See - * ISessionCallback#onEnrollmentProgress for more info. The HAL must notify the framework once - * it returns to the idle state. + * During enrollment, the HAL may notify the framework via ISessionCallback#onAcquired with + * messages that may be used to guide the user. This callback can be invoked multiple times if + * necessary. Similarly, the framework may be notified of enrollment progress changes via + * ISessionCallback#onEnrollmentProgress. Once the framework is notified that there are 0 + * "remaining" steps, the framework may cache the "enrollmentId". See + * ISessionCallback#onEnrollmentProgress for more info. * * When a finger is successfully added and before the framework is notified of remaining=0, the - * implementation MUST update and associate this (sensorId, userId) pair with a new new - * entropy-encoded random identifier. See ISession#getAuthenticatorId for more information. + * HAL must update and associate this (sensorId, userId) pair with a new entropy-encoded random + * identifier. See ISession#getAuthenticatorId for more information. + * + * Callbacks that signify the end of this operation's lifecycle: + * - ISessionCallback#onError + * - ISessionCallback#onEnrollmentProgress(enrollmentId, remaining=0) + * + * Other applicable callbacks: + * - ISessionCallback#onAcquired * * @param hat See above documentation. + * @return ICancellationSignal An object that can be used by the framework to cancel this + * operation. */ ICancellationSignal enroll(in HardwareAuthToken hat); @@ -142,14 +152,16 @@ interface ISession { * At any point during authentication, if a non-recoverable error occurs, the HAL must notify * the framework via ISessionCallback#onError with the applicable authentication-specific error. * - * During authentication, the implementation may notify the framework via - * ISessionCallback#onAcquired with messages that may be used to guide the user. This callback - * can be invoked multiple times if necessary. + * During authentication, the HAL may notify the framework via ISessionCallback#onAcquired with + * messages that may be used to guide the user. This callback can be invoked multiple times if + * necessary. * - * The HAL must notify the framework of accepts/rejects via ISessionCallback#onAuthentication*. + * The HAL must notify the framework of accepts and rejects via + * ISessionCallback#onAuthenticationSucceeded and ISessionCallback#onAuthenticationFailed, + * correspondingly. * - * The authentication lifecycle ends when either - * 1) A fingerprint is accepted, and ISessionCallback#onAuthenticationSucceeded is invoked, or + * The authentication lifecycle ends when either: + * 1) A fingerprint is accepted, and ISessionCallback#onAuthenticationSucceeded is invoked. * 2) Any non-recoverable error occurs (such as lockout). See the full list of * authentication-specific errors in the Error enum. * @@ -162,16 +174,28 @@ interface ISession { * must be set with the operationId passed in during #authenticate. If the sensor is NOT * SensorStrength::STRONG, the HardwareAuthToken MUST be null. * + * Callbacks that signify the end of this operation's lifecycle: + * - ISessionCallback#onError + * - ISessionCallback#onAuthenticationSucceeded + * + * Other applicable callbacks: + * - ISessionCallback#onAcquired + * - ISessionCallback#onAuthenticationFailed + * - ISessionCallback#onLockoutTimed + * - ISessionCallback#onLockoutPermanent + * * @param operationId For sensors configured as SensorStrength::STRONG, this must be used ONLY * upon successful authentication and wrapped in the HardwareAuthToken's * "challenge" field and sent to the framework via - * ISessionCallback#onAuthenticated. The operationId is an opaque identifier - * created from a separate secure subsystem such as, but not limited to - * KeyStore/KeyMaster. The HardwareAuthToken can then be used as an - * attestation for the provided operation. For example, this is used - * to unlock biometric-bound auth-per-use keys (see + * ISessionCallback#onAuthenticationSucceeded. The operationId is an opaque + * identifier created from a separate secure subsystem such as, but not + * limited to KeyStore/KeyMaster. The HardwareAuthToken can then be used as + * an attestation for the provided operation. For example, this is used to + * unlock biometric-bound auth-per-use keys (see * setUserAuthenticationParameters in KeyGenParameterSpec.Builder and - * KeyProtection.Builder. + * KeyProtection.Builder). + * @return ICancellationSignal An object that can be used by the framework to cancel this + * operation. */ ICancellationSignal authenticate(in long operationId); @@ -179,44 +203,52 @@ interface ISession { * detectInteraction: * * A request to start looking for fingerprints without performing matching. Must only be called - * if SensorProps#supportsDetectInteraction is true. If invoked on implementations that do not - * support this functionality, the HAL must respond with ISession#onError(UNABLE_TO_PROCESS, 0). + * if SensorProps#supportsDetectInteraction is true. If invoked on HALs that do not support this + * functionality, the HAL must respond with ISession#onError(UNABLE_TO_PROCESS, 0). * - * The framework will use this method in cases where determing user presence is required, but - * identifying/authentication is not. For example, when the device is encrypted (first boot) or - * in lockdown mode. + * The framework will use this operation in cases where determining user presence is required, + * but identifying/authenticating is not. For example, when the device is encrypted (first boot) + * or in lockdown mode. * * At any point during detectInteraction, if a non-recoverable error occurs, the HAL must notify * the framework via ISessionCallback#onError with the applicable error. * - * The implementation must only check for a fingerprint-like image was detected (e.g. to - * minimize interactions due to non-fingerprint objects), and the lockout counter must not - * be modified. + * The HAL must only check whether a fingerprint-like image was detected (e.g. to minimize + * interactions due to non-fingerprint objects), and the lockout counter must not be modified. * - * Upon detecting any fingerprint, the implementation must invoke - * ISessionCallback#onInteractionDetected. + * Upon detecting any fingerprint, the HAL must invoke ISessionCallback#onInteractionDetected. * - * The lifecycle of this operation ends when either + * The lifecycle of this operation ends when either: * 1) Any fingerprint is detected and the framework is notified via - * ISessionCallback#onInteractiondetected - * 2) The operation was cancelled by the framework (see ICancellationSignal) - * 3) The HAL ends the operation, for example when a subsequent operation pre-empts this one. + * ISessionCallback#onInteractionDetected. + * 2) An error occurs, for example Error::TIMEOUT. * - * Note that if the operation is canceled, the implementation must notify the framework via + * Note that if the operation is canceled, the HAL must notify the framework via * ISessionCallback#onError with Error::CANCELED. * + * Callbacks that signify the end of this operation's lifecycle: + * - ISessionCallback#onError + * - ISessionCallback#onInteractionDetected + * + * Other applicable callbacks: + * - ISessionCallback#onAcquired + * + * @return ICancellationSignal An object that can be used by the framework to cancel this + * operation. */ ICancellationSignal detectInteraction(); /* * enumerateEnrollments: * - * A request to enumerate (list) the enrollments for this (sensorId, userId) pair. The - * framework typically uses this to ensure that its cache is in sync with the HAL. + * A request to enumerate (list) the enrollments for this (sensorId, userId) pair. The framework + * typically uses this to ensure that its cache is in sync with the HAL. * - * The implementation must then notify the framework with a list of enrollments applicable - * for the current session via ISessionCallback#onEnrollmentsEnumerated. + * The HAL must then notify the framework with a list of enrollments applicable for the current + * session via ISessionCallback#onEnrollmentsEnumerated. * + * Callbacks that signify the end of this operation's lifecycle: + * - ISessionCallback#onEnrollmentsEnumerated */ void enumerateEnrollments(); @@ -226,8 +258,12 @@ interface ISession { * A request to remove the enrollments for this (sensorId, userId) pair. * * After removing the enrollmentIds from everywhere necessary (filesystem, secure subsystems, - * etc), the implementation must notify the framework via ISessionCallback#onEnrollmentsRemoved. + * etc), the HAL must notify the framework via ISessionCallback#onEnrollmentsRemoved. + * + * Callbacks that signify the end of this operation's lifecycle: + * - ISessionCallback#onEnrollmentsRemoved * + * @param enrollmentIds a list of enrollments that should be removed. */ void removeEnrollments(in int[] enrollmentIds); @@ -240,15 +276,15 @@ interface ISession { * The following only applies to sensors that are configured as SensorStrength::STRONG. * * The authenticatorId is a (sensorId, user)-specific identifier which can be used during key - * generation and key import to to associate a key (in KeyStore / KeyMaster) with the current - * set of enrolled fingerprints. For example, the following public Android APIs allow for keys - * to be invalidated when the user adds a new enrollment after the key was created: + * generation and import to associate the key (in KeyStore / KeyMaster) with the current set of + * enrolled fingerprints. For example, the following public Android APIs allow for keys to be + * invalidated when the user adds a new enrollment after the key was created: * KeyGenParameterSpec.Builder.setInvalidatedByBiometricEnrollment and * KeyProtection.Builder.setInvalidatedByBiometricEnrollment. * * In addition, upon successful fingerprint authentication, the signed HAT that is returned to - * the framework via ISessionCallback#onAuthenticated must contain this identifier in the - * authenticatorId field. + * the framework via ISessionCallback#onAuthenticationSucceeded must contain this identifier in + * the authenticatorId field. * * Returns an entropy-encoded random identifier associated with the current set of enrollments * via ISessionCallback#onAuthenticatorIdRetrieved. The authenticatorId @@ -257,20 +293,21 @@ interface ISession { * 3) MUST not change if a fingerprint is deleted. * 4) MUST be an entropy-encoded random number * + * Callbacks that signify the end of this operation's lifecycle: + * - ISessionCallback#onAuthenticatorIdRetrieved */ void getAuthenticatorId(); /** * invalidateAuthenticatorId: * - * This method only applies to sensors that are configured as SensorStrength::STRONG. If invoked - * by the framework for sensor of other strengths, the HAL should immediately invoke + * This operation only applies to sensors that are configured as SensorStrength::STRONG. If + * invoked by the framework for sensors of other strengths, the HAL should immediately invoke * ISessionCallback#onAuthenticatorIdInvalidated. * * The following only applies to sensors that are configured as SensorStrength::STRONG. * - * When invoked by the framework, the implementation must perform the following sequence of - * events: + * When invoked by the framework, the HAL must perform the following sequence of events: * 1) Update the authenticatorId with a new entropy-encoded random number * 2) Persist the new authenticatorId to non-ephemeral storage * 3) Notify the framework that the above is completed, via @@ -278,23 +315,25 @@ interface ISession { * * A practical use case of invalidation would be when the user adds a new enrollment to a sensor * managed by a different HAL instance. The public android.security.keystore APIs bind keys to - * "all biometrics" rather than "fingerprint-only" or "face-only" (see #getAuthenticatorId - * for more details). As such, the framework would coordinate invalidation across multiple - * biometric HALs as necessary. + * "all biometrics" rather than "fingerprint-only" or "face-only" (see #getAuthenticatorId for + * more details). As such, the framework would coordinate invalidation across multiple biometric + * HALs as necessary. * + * Callbacks that signify the end of this operation's lifecycle: + * - ISessionCallback#onAuthenticatorIdInvalidated */ void invalidateAuthenticatorId(); /** * resetLockout: * - * Requests the implementation to clear the lockout counter. Upon receiving this request, the - * implementation must perform the following: + * Requests the HAL to clear the lockout counter. Upon receiving this request, the HAL must + * perform the following: * 1) Verify the authenticity and integrity of the provided HAT * 2) Verify that the timestamp provided within the HAT is relatively recent (e.g. on the * order of minutes, not hours). * If either of the checks fail, the HAL must invoke ISessionCallback#onError with - * Error::UNABLE_TO_PROCESS and return to the idling state. + * Error::UNABLE_TO_PROCESS. * * Upon successful verification, the HAL must clear the lockout counter and notify the framework * via ISessionCallback#onLockoutCleared. @@ -325,6 +364,9 @@ interface ISession { * See the Android CDD section 7.3.10 for the full set of lockout and rate-limiting * requirements. * + * Callbacks that signify the end of this operation's lifecycle: + * - ISessionCallback#onLockoutCleared + * * @param hat HardwareAuthToken See above documentation. */ void resetLockout(in HardwareAuthToken hat); @@ -343,6 +385,8 @@ interface ISession { * All sessions must be explicitly closed. Calling IFingerprint#createSession while there is an * active session is considered an error. * + * Callbacks that signify the end of this operation's lifecycle: + * - ISessionCallback#onSessionClosed */ void close(); @@ -353,16 +397,16 @@ interface ISession { /** * onPointerDown: * - * This method only applies to sensors that are configured as + * This operation only applies to sensors that are configured as * FingerprintSensorType::UNDER_DISPLAY_*. If invoked erroneously by the framework for sensors * of other types, the HAL must treat this as a no-op and return immediately. * - * For sensors of type FingerprintSensorType::UNDER_DISPLAY_*, this method is used to notify the - * HAL of display touches. This method can be invoked when the HAL is performing any one of: - * ISession#authenticate, ISession#enroll, ISession#detectInteraction. + * This operation is used to notify the HAL of display touches. This operation can be invoked + * when the HAL is performing any one of: ISession#authenticate, ISession#enroll, + * ISession#detectInteraction. * - * Note that the framework will only invoke this method if the event occurred on the display on - * which this sensor is located. + * Note that the framework will only invoke this operation if the event occurred on the display + * on which this sensor is located. * * Note that for sensors which require illumination such as * FingerprintSensorType::UNDER_DISPLAY_OPTICAL, and where illumination is handled below the @@ -379,10 +423,13 @@ interface ISession { /** * onPointerUp: * - * This method only applies to sensors that are configured as + * This operation only applies to sensors that are configured as * FingerprintSensorType::UNDER_DISPLAY_*. If invoked for sensors of other types, the HAL must * treat this as a no-op and return immediately. * + * This operation can be invoked when the HAL is performing any one of: ISession#authenticate, + * ISession#enroll, ISession#detectInteraction. + * * @param pointerId See android.view.MotionEvent#getPointerId */ void onPointerUp(in int pointerId); @@ -390,12 +437,15 @@ interface ISession { /* * onUiReady: * - * This method only applies to sensors that are configured as + * This operation only applies to sensors that are configured as * FingerprintSensorType::UNDER_DISPLAY_OPTICAL. If invoked for sensors of other types, the HAL * must treat this as a no-op and return immediately. * + * This operation can be invoked when the HAL is performing any one of: ISession#authenticate, + * ISession#enroll, ISession#detectInteraction. + * * For FingerprintSensorType::UNDER_DISPLAY_OPTICAL where illumination is handled above the - * HAL, the framework will invoke this method to notify that the illumination has started. + * HAL, the framework will invoke this operation to notify when the illumination is showing. */ void onUiReady(); } diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl index 95657b3d7b..f699966f59 100644 --- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl +++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISessionCallback.aidl @@ -34,12 +34,12 @@ interface ISessionCallback { /** * This method must only be used to notify the framework during the following operations: - * 1) ISession#enroll - * 2) ISession#authenticate - * 3) ISession#detectInteraction + * - ISession#enroll + * - ISession#authenticate + * - ISession#detectInteraction * - * These messages may be used to provide user guidance multiple times if necessary per - * operation. + * These messages may be used to provide user guidance multiple times per operation if + * necessary. * * @param info See the AcquiredInfo enum. * @param vendorCode Only valid if info == AcquiredInfo::VENDOR. The vendorCode must be used to @@ -51,18 +51,18 @@ interface ISessionCallback { /** * This method must only be used to notify the framework during the following operations: - * 1) ISession#enroll - * 2) ISession#authenticate - * 3) ISession#detectInteraction - * 4) ISession#invalidateAuthenticatorId - * 5) ISession#resetLockout + * - ISession#enroll + * - ISession#authenticate + * - ISession#detectInteraction + * - ISession#invalidateAuthenticatorId + * - ISession#resetLockout * * These messages may be used to notify the framework or user that a non-recoverable error * has occurred. The operation is finished, and the HAL can proceed with the next operation * or return to the idling state. * - * Note that cancellation (see common::ICancellationSignal) and preemption must be followed with - * an Error::CANCELED message. + * Note that cancellation (see common::ICancellationSignal) must be followed with an + * Error::CANCELED message. * * @param error See the Error enum. * @param vendorCode Only valid if error == Error::VENDOR. The vendorCode must be used to index @@ -100,8 +100,8 @@ interface ISessionCallback { * This method must only be used to notify the framework during ISession#authenticate. * * Used to notify the framework upon rejected attempts. Note that the authentication - * lifecycle ends when either 1) a fingerprint is accepted, or 2) an occurred. The - * authentication lifecycle does NOT end when a fingerprint is rejected. + * lifecycle ends when either 1) a fingerprint is accepted, or 2) an error occurred. + * The authentication lifecycle does NOT end when a fingerprint is rejected. */ void onAuthenticationFailed(); -- GitLab From 90e4a2f96e82a38871495e561f2c02cf0359cb05 Mon Sep 17 00:00:00 2001 From: Kalesh Singh Date: Tue, 29 Jun 2021 21:43:27 +0000 Subject: [PATCH 735/790] memtrack: Update AIDL memtrack hal documentation Fix Memtrack GRAPHICS type definition to also inculde GPU-mapped DMA-BUF memory. Clarify SMAPS_UNACCOUTNED should also include memory mapped with VM_PFNMAP set. Bug: 192384999 Test: N/A Change-Id: I5370efa731bc6307e4fe9b454796361e9a1ac5eb Merged-In: I5370efa731bc6307e4fe9b454796361e9a1ac5eb --- .../aidl/android/hardware/memtrack/IMemtrack.aidl | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/memtrack/aidl/android/hardware/memtrack/IMemtrack.aidl b/memtrack/aidl/android/hardware/memtrack/IMemtrack.aidl index e78d4d7c32..13c3389730 100644 --- a/memtrack/aidl/android/hardware/memtrack/IMemtrack.aidl +++ b/memtrack/aidl/android/hardware/memtrack/IMemtrack.aidl @@ -31,12 +31,14 @@ import android.hardware.memtrack.MemtrackType; * accounting for stride, bit depth, rounding up to page size, etc. * * The following getMemory() categories are important for memory accounting in - * `dumpsys meminfo` and should be reported as described below: + * Android frameworks (e.g. `dumpsys meminfo`) and should be reported as described + * below: * * - MemtrackType::GRAPHICS and MemtrackRecord::FLAG_SMAPS_UNACCOUNTED - * This should report the PSS of all DMA buffers mapped by the process - * with the specified PID. This PSS can be calculated using ReadDmaBufPss() - * form libdmabufinfo. + * This should report the PSS of all CPU-Mapped DMA-BUFs (buffers mapped into + * the process address space) and all GPU-Mapped DMA-BUFs (buffers mapped into + * the GPU device address space on behalf of the process), removing any overlap + * between the CPU-mapped and GPU-mapped sets. * * - MemtrackType::GL and MemtrackRecord::FLAG_SMAPS_UNACCOUNTED * This category should report all GPU private allocations for the specified @@ -46,6 +48,10 @@ import android.hardware.memtrack.MemtrackType; * Any other memory not accounted for in /proc//smaps if any, otherwise * this should return 0. * + * SMAPS_UNACCOUNTED memory should also include memory that is mapped with + * VM_PFNMAP flag set. For these mappings PSS and RSS are reported as 0 in smaps. + * Such mappings have no backing page structs from which PSS/RSS can be calculated. + * * Constructor for the interface should be used to perform memtrack management * setup actions and must be called once before any calls to getMemory(). */ -- GitLab From f5a84a23226468ced5a1faef81ff18d10522df31 Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Thu, 1 Jul 2021 16:23:18 +0800 Subject: [PATCH 736/790] wifi: add 1.5 HIDL service in lazy rc 1.5 HIDL service is not declared in lazy init rc. Bug: 191940153 Test: atest VtsHalBaseV1_0TargetTest Change-Id: Idc4d01e9696c35c8fc2390a2639ff8d7ebf0bbf0 --- wifi/1.5/default/android.hardware.wifi@1.0-service-lazy.rc | 1 + 1 file changed, 1 insertion(+) diff --git a/wifi/1.5/default/android.hardware.wifi@1.0-service-lazy.rc b/wifi/1.5/default/android.hardware.wifi@1.0-service-lazy.rc index 061689dbe5..bc6bb6a7e6 100644 --- a/wifi/1.5/default/android.hardware.wifi@1.0-service-lazy.rc +++ b/wifi/1.5/default/android.hardware.wifi@1.0-service-lazy.rc @@ -4,6 +4,7 @@ service vendor.wifi_hal_legacy /vendor/bin/hw/android.hardware.wifi@1.0-service- interface android.hardware.wifi@1.2::IWifi default interface android.hardware.wifi@1.3::IWifi default interface android.hardware.wifi@1.4::IWifi default + interface android.hardware.wifi@1.5::IWifi default oneshot disabled class hal -- GitLab From 8b78dc5031a12819a477399374f3e3807777c7b2 Mon Sep 17 00:00:00 2001 From: Seth Moore Date: Tue, 1 Jun 2021 11:30:24 -0700 Subject: [PATCH 737/790] Correct the description for getKeyCharacteristics The description should note that keystore-enforced tags are not to be returned. This is done so that the keymint implementation doesn't have to bother keeping track of tags it's not repsonsible for dealing with. Fixes: 192575557 Test: none (it's just a comment change) Change-Id: I3ff94201c262a5071d271b150dbbf21888d678aa Merged-In: I3ff94201c262a5071d271b150dbbf21888d678aa --- .../android/hardware/security/keymint/IKeyMintDevice.aidl | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl index 4cecff7f7a..2241735928 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl @@ -813,9 +813,10 @@ interface IKeyMintDevice { byte[] convertStorageKeyToEphemeral(in byte[] storageKeyBlob); /** - * Returns parameters associated with the provided key. This should match the - * KeyCharacteristics present in the KeyCreationResult returned by generateKey(), - * importKey(), or importWrappedKey(). + * Returns KeyMint-enforced parameters associated with the provided key. The returned tags are + * a subset of KeyCharacteristics found in the KeyCreationResult returned by generateKey(), + * importKey(), or importWrappedKey(). The returned value is a subset, as it does not include + * any Keystore-enforced parameters. * * @param keyBlob The opaque descriptor returned by generateKey, importKey or importWrappedKey. * -- GitLab From da9f5fe137ffaf1b020657e6a9ac8b820f28a089 Mon Sep 17 00:00:00 2001 From: Les Lee Date: Tue, 29 Jun 2021 22:48:11 +0800 Subject: [PATCH 738/790] WIFI: Set MAC address for bridged interface The MAC address of the bridged interface will be dynamically generated by kernel when any bridged iface is changed. This means that the bridged interface MAC address will be changed when we remove one of the instances from the bridged interface (shutdown unused interface case). The MAC change will break operation of bpf and it may cause the SAP client to send wrong ns packets because the tethering module is still using the old MAC in the ra packet. Always set MAC address so the bridged interface can avoid MAC changing. Bug: 191611764 Bug: 192315721 Test: Manual test with IPv6 tethering. Make sure client won't disconnect because it doesn't get na response. Test: Manual test in two scenarios: 1. MAC randomization 2. reset to factory MAC. Change-Id: I854fc74b6532824b7d7b5a1aa4bc20a3cf9fd588 --- wifi/1.5/default/wifi_ap_iface.cpp | 27 ++++++++++++++++++++------- wifi/1.5/default/wifi_iface_util.cpp | 4 ++-- wifi/1.5/default/wifi_iface_util.h | 4 ++-- 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/wifi/1.5/default/wifi_ap_iface.cpp b/wifi/1.5/default/wifi_ap_iface.cpp index b438a4a832..1ae7905f74 100644 --- a/wifi/1.5/default/wifi_ap_iface.cpp +++ b/wifi/1.5/default/wifi_ap_iface.cpp @@ -136,24 +136,25 @@ WifiApIface::getValidFrequenciesForBandInternal(V1_0::WifiBand band) { WifiStatus WifiApIface::setMacAddressInternal( const std::array& mac) { - bool status; // Support random MAC up to 2 interfaces if (instances_.size() == 2) { int rbyte = 1; for (auto const& intf : instances_) { std::array rmac = mac; - // reverse the bits to avoid clision + // reverse the bits to avoid collision rmac[rbyte] = 0xff - rmac[rbyte]; - status = iface_util_.lock()->setMacAddress(intf, rmac); - if (!status) { + if (!iface_util_.lock()->setMacAddress(intf, rmac)) { LOG(INFO) << "Failed to set random mac address on " << intf; + return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); } rbyte++; } - } else { - status = iface_util_.lock()->setMacAddress(ifname_, mac); } - if (!status) { + // It also needs to set mac address for bridged interface, otherwise the mac + // address of bridged interface will be changed after one of instance + // down. + if (!iface_util_.lock()->setMacAddress(ifname_, mac)) { + LOG(ERROR) << "Fail to config MAC for interface " << ifname_; return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); } return createWifiStatus(WifiStatusCode::SUCCESS); @@ -181,6 +182,18 @@ WifiStatus WifiApIface::resetToFactoryMacAddressInternal() { return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); } } + // It needs to set mac address for bridged interface, otherwise the mac + // address of the bridged interface will be changed after one of the + // instance down. Thus we are generating a random MAC address for the + // 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_; + return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); + } } else { getMacResult = getFactoryMacAddressInternal(ifname_); LOG(DEBUG) << "Reset MAC to factory MAC on " << ifname_; diff --git a/wifi/1.5/default/wifi_iface_util.cpp b/wifi/1.5/default/wifi_iface_util.cpp index d1434e3a41..7bf830b875 100644 --- a/wifi/1.5/default/wifi_iface_util.cpp +++ b/wifi/1.5/default/wifi_iface_util.cpp @@ -86,9 +86,9 @@ bool WifiIfaceUtil::setMacAddress(const std::string& iface_name, event_handlers.on_state_toggle_off_on(iface_name); } if (!success) { - LOG(ERROR) << "SetMacAddress failed."; + LOG(ERROR) << "SetMacAddress failed on " << iface_name; } else { - LOG(DEBUG) << "SetMacAddress succeeded."; + LOG(DEBUG) << "SetMacAddress succeeded on " << iface_name; } return success; } diff --git a/wifi/1.5/default/wifi_iface_util.h b/wifi/1.5/default/wifi_iface_util.h index b449077e9e..544f575d41 100644 --- a/wifi/1.5/default/wifi_iface_util.h +++ b/wifi/1.5/default/wifi_iface_util.h @@ -71,10 +71,10 @@ class WifiIfaceUtil { virtual bool removeIfaceFromBridge(const std::string& br_name, const std::string& if_name); + // Get a random MAC address. + virtual std::array createRandomMacAddress(); private: - std::array createRandomMacAddress(); - std::weak_ptr iface_tool_; std::weak_ptr legacy_hal_; std::unique_ptr> random_mac_address_; -- GitLab From 1d52438592c4aa3533b495b48e1409f46f481018 Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Fri, 2 Jul 2021 20:33:51 +0000 Subject: [PATCH 739/790] IFingerprint: update default implementation Bug: 166800618 Test: atest VtsHalBiometricsFingerprintTargetTest Change-Id: I0ac3a019081f4f5db6943fc019165ad1aa2e0bc8 --- .../aidl/default/include/FakeFingerprintEngine.h | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h index 6667f7a7f0..b92777068c 100644 --- a/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h +++ b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h @@ -17,14 +17,19 @@ #pragma once #include +#include namespace aidl::android::hardware::biometrics::fingerprint { class FakeFingerprintEngine { public: + FakeFingerprintEngine() : mRandom(std::mt19937::default_seed) {} + void generateChallengeImpl(ISessionCallback* cb) { LOG(INFO) << "generateChallengeImpl"; - cb->onChallengeGenerated(0 /* challenge */); + std::uniform_int_distribution dist; + auto challenge = dist(mRandom); + cb->onChallengeGenerated(challenge); } void revokeChallengeImpl(ISessionCallback* cb, int64_t challenge) { @@ -32,8 +37,13 @@ class FakeFingerprintEngine { cb->onChallengeRevoked(challenge); } - void enrollImpl(ISessionCallback* cb, const keymaster::HardwareAuthToken& /*hat*/) { + void enrollImpl(ISessionCallback* cb, const keymaster::HardwareAuthToken& hat) { LOG(INFO) << "enrollImpl"; + // Do proper HAT verification in the real implementation. + if (hat.mac.empty()) { + cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */); + return; + } cb->onEnrollmentProgress(0 /* enrollmentId */, 0 /* remaining */); } @@ -71,6 +81,8 @@ class FakeFingerprintEngine { LOG(INFO) << "resetLockoutImpl"; cb->onLockoutCleared(); } + + std::mt19937 mRandom; }; } // namespace aidl::android::hardware::biometrics::fingerprint -- GitLab From 04247248ceb8b41950bcfc59e89cace7704565e5 Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Fri, 2 Jul 2021 20:34:52 +0000 Subject: [PATCH 740/790] IFingerprint: update VTS tests Bug: 166799066 Test: VtsHalBiometricsFingerprintTargetTest Change-Id: I2bf765890203a4edc016d1b7f0abd1d205b2a0ba --- .../VtsHalBiometricsFingerprintTargetTest.cpp | 204 +++++++++++++++--- 1 file changed, 177 insertions(+), 27 deletions(-) diff --git a/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp b/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp index f1cfb17837..1cd8c769f2 100644 --- a/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp +++ b/biometrics/fingerprint/aidl/vts/VtsHalBiometricsFingerprintTargetTest.cpp @@ -35,13 +35,19 @@ constexpr int kUserId = 0; class SessionCallback : public BnSessionCallback { public: - explicit SessionCallback(std::promise&& promise) : mPromise(std::move(promise)) {} - - ndk::ScopedAStatus onChallengeGenerated(int64_t /*challenge*/) override { + ndk::ScopedAStatus onChallengeGenerated(int64_t challenge) override { + auto lock = std::lock_guard{mMutex}; + mOnChallengeGeneratedInvoked = true; + mGeneratedChallenge = challenge; + mCv.notify_one(); return ndk::ScopedAStatus::ok(); } - ndk::ScopedAStatus onChallengeRevoked(int64_t /*challenge*/) override { + ndk::ScopedAStatus onChallengeRevoked(int64_t challenge) override { + auto lock = std::lock_guard{mMutex}; + mOnChallengeRevokedInvoked = true; + mRevokedChallenge = challenge; + mCv.notify_one(); return ndk::ScopedAStatus::ok(); } @@ -49,7 +55,11 @@ class SessionCallback : public BnSessionCallback { return ndk::ScopedAStatus::ok(); } - ndk::ScopedAStatus onError(Error /*error*/, int32_t /*vendorCode*/) override { + ndk::ScopedAStatus onError(Error error, int32_t /*vendorCode*/) override { + auto lock = std::lock_guard{mMutex}; + mError = error; + mOnErrorInvoked = true; + mCv.notify_one(); return ndk::ScopedAStatus::ok(); } @@ -77,63 +87,203 @@ class SessionCallback : public BnSessionCallback { ndk::ScopedAStatus onEnrollmentsEnumerated( const std::vector& /*enrollmentIds*/) override { + auto lock = std::lock_guard{mMutex}; + mOnEnrollmentsEnumeratedInvoked = true; + mCv.notify_one(); return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus onEnrollmentsRemoved( const std::vector& /*enrollmentIds*/) override { + auto lock = std::lock_guard{mMutex}; + mOnEnrollmentsRemovedInvoked = true; + mCv.notify_one(); return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus onAuthenticatorIdRetrieved(int64_t /*authenticatorId*/) override { + auto lock = std::lock_guard{mMutex}; + mOnAuthenticatorIdRetrievedInvoked = true; + mCv.notify_one(); return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus onAuthenticatorIdInvalidated(int64_t /*newAuthenticatorId*/) override { + auto lock = std::lock_guard{mMutex}; + mOnAuthenticatorIdInvalidatedInvoked = true; + mCv.notify_one(); return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus onSessionClosed() override { - mPromise.set_value(); + auto lock = std::lock_guard{mMutex}; + mOnSessionClosedInvoked = true; + mCv.notify_one(); return ndk::ScopedAStatus::ok(); } - private: - std::promise mPromise; + std::mutex mMutex; + std::condition_variable mCv; + Error mError = Error::UNKNOWN; + int64_t mGeneratedChallenge = 0; + int64_t mRevokedChallenge = 0; + bool mOnChallengeGeneratedInvoked = false; + bool mOnChallengeRevokedInvoked = false; + bool mOnErrorInvoked = false; + bool mOnEnrollmentsEnumeratedInvoked = false; + bool mOnEnrollmentsRemovedInvoked = false; + bool mOnAuthenticatorIdRetrievedInvoked = false; + bool mOnAuthenticatorIdInvalidatedInvoked = false; + bool mOnSessionClosedInvoked = false; }; class Fingerprint : public testing::TestWithParam { protected: void SetUp() override { - AIBinder* binder = AServiceManager_waitForService(GetParam().c_str()); - ASSERT_NE(binder, nullptr); - mHal = IFingerprint::fromBinder(ndk::SpAIBinder(binder)); + // Prepare the callback. + mCb = ndk::SharedRefBase::make(); + + int retries = 0; + bool isOk = false; + // If the first attempt to create a session fails, we try to create a session again. The + // first attempt might fail if the framework already has an active session. The AIDL + // contract doesn't allow to create a new session without closing the old one. However, we + // can't close the framework's session from VTS. The expectation here is that the HAL will + // crash after the first illegal attempt to create a session, then it will restart, and then + // we'll be able to create a session. + do { + // Get an instance of the HAL. + AIBinder* binder = AServiceManager_waitForService(GetParam().c_str()); + ASSERT_NE(binder, nullptr); + mHal = IFingerprint::fromBinder(ndk::SpAIBinder(binder)); + + // Create a session. + isOk = mHal->createSession(kSensorId, kUserId, mCb, &mSession).isOk(); + ++retries; + } while (!isOk && retries < 2); + + ASSERT_TRUE(isOk); + } + + void TearDown() override { + // Close the mSession. + ASSERT_TRUE(mSession->close().isOk()); + + // Make sure the mSession is closed. + auto lock = std::unique_lock(mCb->mMutex); + mCb->mCv.wait(lock, [this] { return mCb->mOnSessionClosedInvoked; }); } std::shared_ptr mHal; + std::shared_ptr mCb; + std::shared_ptr mSession; }; -TEST_P(Fingerprint, AuthenticateTest) { - auto promise = std::promise{}; - auto future = promise.get_future(); - // Prepare the callback. - auto cb = ndk::SharedRefBase::make(std::move(promise)); +TEST_P(Fingerprint, GetSensorPropsWorksTest) { + std::vector sensorProps; - // Create a session - std::shared_ptr session; - ASSERT_TRUE(mHal->createSession(kSensorId, kUserId, cb, &session).isOk()); + // Call the method. + ASSERT_TRUE(mHal->getSensorProps(&sensorProps).isOk()); - // Call authenticate + // Make sure the sensorProps aren't empty. + ASSERT_FALSE(sensorProps.empty()); + ASSERT_FALSE(sensorProps[0].commonProps.componentInfo.empty()); +} + +TEST_P(Fingerprint, EnrollWithBadHatResultsInErrorTest) { + // Call the method. + auto hat = keymaster::HardwareAuthToken{}; std::shared_ptr cancellationSignal; - ASSERT_TRUE(session->authenticate(-1 /* operationId */, &cancellationSignal).isOk()); + ASSERT_TRUE(mSession->enroll(hat, &cancellationSignal).isOk()); + + // Make sure an error is returned. + auto lock = std::unique_lock{mCb->mMutex}; + mCb->mCv.wait(lock, [this] { return mCb->mOnErrorInvoked; }); +} + +TEST_P(Fingerprint, GenerateChallengeProducesUniqueChallengesTest) { + static constexpr int kIterations = 100; + + auto challenges = std::set{}; + for (unsigned int i = 0; i < kIterations; ++i) { + // Call the method. + ASSERT_TRUE(mSession->generateChallenge().isOk()); + + // Check that the generated challenge is unique and not 0. + auto lock = std::unique_lock{mCb->mMutex}; + mCb->mCv.wait(lock, [this] { return mCb->mOnChallengeGeneratedInvoked; }); + ASSERT_NE(mCb->mGeneratedChallenge, 0); + ASSERT_EQ(challenges.find(mCb->mGeneratedChallenge), challenges.end()); + + challenges.insert(mCb->mGeneratedChallenge); + mCb->mOnChallengeGeneratedInvoked = false; + } +} + +TEST_P(Fingerprint, RevokeChallengeWorksForNonexistentChallengeTest) { + const int64_t nonexistentChallenge = 123; + + // Call the method. + ASSERT_TRUE(mSession->revokeChallenge(nonexistentChallenge).isOk()); + + // Check that the challenge is revoked and matches the requested challenge. + auto lock = std::unique_lock{mCb->mMutex}; + mCb->mCv.wait(lock, [this] { return mCb->mOnChallengeRevokedInvoked; }); + ASSERT_EQ(mCb->mRevokedChallenge, nonexistentChallenge); +} + +TEST_P(Fingerprint, RevokeChallengeWorksForExistentChallengeTest) { + // Generate a challenge. + ASSERT_TRUE(mSession->generateChallenge().isOk()); + + // Wait for the result. + auto lock = std::unique_lock{mCb->mMutex}; + mCb->mCv.wait(lock, [this] { return mCb->mOnChallengeGeneratedInvoked; }); + lock.unlock(); + + // Revoke the challenge. + ASSERT_TRUE(mSession->revokeChallenge(mCb->mGeneratedChallenge).isOk()); + + // Check that the challenge is revoked and matches the requested challenge. + lock.lock(); + mCb->mCv.wait(lock, [this] { return mCb->mOnChallengeRevokedInvoked; }); + ASSERT_EQ(mCb->mRevokedChallenge, mCb->mGeneratedChallenge); +} + +TEST_P(Fingerprint, EnumerateEnrollmentsWorksTest) { + // Call the method. + ASSERT_TRUE(mSession->enumerateEnrollments().isOk()); + + // Wait for the result. + auto lock = std::unique_lock{mCb->mMutex}; + mCb->mCv.wait(lock, [this] { return mCb->mOnEnrollmentsEnumeratedInvoked; }); +} + +TEST_P(Fingerprint, RemoveEnrollmentsWorksTest) { + // Call the method. + ASSERT_TRUE(mSession->removeEnrollments({}).isOk()); + + // Wait for the result. + auto lock = std::unique_lock{mCb->mMutex}; + mCb->mCv.wait(lock, [this] { return mCb->mOnEnrollmentsRemovedInvoked; }); +} + +TEST_P(Fingerprint, GetAuthenticatorIdWorksTest) { + // Call the method. + ASSERT_TRUE(mSession->getAuthenticatorId().isOk()); + + // Wait for the result. + auto lock = std::unique_lock{mCb->mMutex}; + mCb->mCv.wait(lock, [this] { return mCb->mOnAuthenticatorIdRetrievedInvoked; }); +} - // Get the results - // TODO(b/166799066): test authenticate. +TEST_P(Fingerprint, InvalidateAuthenticatorIdWorksTest) { + // Call the method. + ASSERT_TRUE(mSession->invalidateAuthenticatorId().isOk()); - // Close the session - ASSERT_TRUE(session->close().isOk()); - auto status = future.wait_for(1s); - ASSERT_EQ(status, std::future_status::ready); + // Wait for the result. + auto lock = std::unique_lock{mCb->mMutex}; + mCb->mCv.wait(lock, [this] { return mCb->mOnAuthenticatorIdInvalidatedInvoked; }); } GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Fingerprint); -- GitLab From 753a594aec166bb53a3e72f00ea0780297b38c86 Mon Sep 17 00:00:00 2001 From: Shuzhen Wang Date: Fri, 2 Jul 2021 11:38:20 -0700 Subject: [PATCH 741/790] Camera: Fix a typo in the 3.7 device comment Test: Build Bug: 192701691 Change-Id: Iba9ce48fc7e50bf632e93408072c89d3eb74ab99 --- camera/device/3.7/types.hal | 2 +- current.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/camera/device/3.7/types.hal b/camera/device/3.7/types.hal index 6910e6574c..55aceb8fa4 100644 --- a/camera/device/3.7/types.hal +++ b/camera/device/3.7/types.hal @@ -42,7 +42,7 @@ struct Stream { /** * The surface group id used for multi-resolution output streams. * - * This works simliar to the surfaceGroupId of OutputConfiguration in the + * This works similar to the surfaceGroupId of OutputConfiguration in the * public API, with the exception that this is for multi-resolution image * reader and is used by the camera HAL to choose a target stream within * the same group to which images are written. All streams in the same group diff --git a/current.txt b/current.txt index 908ecc4ed2..9fdd81dd67 100644 --- a/current.txt +++ b/current.txt @@ -838,7 +838,7 @@ c17d9e27abd37ae5a8ff8da08fc5c9b13a264670feef6bbbc9d3ab1915216130 android.hardwar 1a1dff6e8d25dbc02a69fed3c077dd0782b30331ca3f345848ec52fc67744224 android.hardware.camera.device@3.7::ICameraDevice 3be6faa3d11ad9c7ec01a1a0a009cf11cb65d701d109dab37613ce9cfb3cdd60 android.hardware.camera.device@3.7::ICameraDeviceSession 3740ec773b2eb8fa6bd8c6e879eedb56c4e4306b88f1c20fa51103d791d871b1 android.hardware.camera.device@3.7::ICameraInjectionSession -21f023685571daf46148097d98b89cea353f07e3ed83b2ed5685b23bd136c3ee android.hardware.camera.device@3.7::types +d272697484c41bbf76a0924d2aaebf065ce37a822fcb438316eb5dd2d112f052 android.hardware.camera.device@3.7::types e932e7ef95210142e1fd3a4504e1d19bdb1acc988450f1ced543f3401f67855a android.hardware.camera.metadata@3.6::types 98ff825a7d37e5ab983502d13cec1f2e5a9cac9b674b6ff1a52bcf540f4e315e android.hardware.camera.provider@2.7::ICameraProvider 51fd14005859b16be55872660c34f5d423c77a2abcc5d4bdd5a537c40f32516b android.hardware.camera.provider@2.7::types -- GitLab From 60406beac63ecbcd303a4b9a5f4b2010b8cffe59 Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Sat, 3 Jul 2021 00:04:43 +0000 Subject: [PATCH 742/790] IFace: update default implementation Bug: 170651283 Test: atest VtsHalBiometricsFaceTargetTest Change-Id: I6f8e6ec12e597034264e2b1383bc7325b0f697b7 --- biometrics/face/aidl/default/Session.cpp | 16 ++++++++++++++-- biometrics/face/aidl/default/Session.h | 3 +++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/biometrics/face/aidl/default/Session.cpp b/biometrics/face/aidl/default/Session.cpp index d980c5f892..0cb7c95de8 100644 --- a/biometrics/face/aidl/default/Session.cpp +++ b/biometrics/face/aidl/default/Session.cpp @@ -34,12 +34,15 @@ class CancellationSignal : public common::BnCancellationSignal { } }; -Session::Session(std::shared_ptr cb) : cb_(std::move(cb)) {} +Session::Session(std::shared_ptr cb) + : cb_(std::move(cb)), mRandom(std::mt19937::default_seed) {} ndk::ScopedAStatus Session::generateChallenge() { LOG(INFO) << "generateChallenge"; if (cb_) { - cb_->onChallengeGenerated(0); + std::uniform_int_distribution dist; + auto challenge = dist(mRandom); + cb_->onChallengeGenerated(challenge); } return ndk::ScopedAStatus::ok(); } @@ -63,6 +66,9 @@ ndk::ScopedAStatus Session::enroll( const std::vector& /*features*/, const NativeHandle& /*previewSurface*/, std::shared_ptr* /*return_val*/) { LOG(INFO) << "enroll"; + if (cb_) { + cb_->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */); + } return ndk::ScopedAStatus::ok(); } @@ -100,6 +106,9 @@ ndk::ScopedAStatus Session::removeEnrollments(const std::vector& /*enro ndk::ScopedAStatus Session::getFeatures() { LOG(INFO) << "getFeatures"; + if (cb_) { + cb_->onFeaturesRetrieved({}); + } return ndk::ScopedAStatus::ok(); } @@ -119,6 +128,9 @@ ndk::ScopedAStatus Session::getAuthenticatorId() { ndk::ScopedAStatus Session::invalidateAuthenticatorId() { LOG(INFO) << "invalidateAuthenticatorId"; + if (cb_) { + cb_->onAuthenticatorIdInvalidated(0); + } return ndk::ScopedAStatus::ok(); } diff --git a/biometrics/face/aidl/default/Session.h b/biometrics/face/aidl/default/Session.h index caf81f8702..4d213e3860 100644 --- a/biometrics/face/aidl/default/Session.h +++ b/biometrics/face/aidl/default/Session.h @@ -16,6 +16,8 @@ #pragma once +#include + #include #include @@ -68,6 +70,7 @@ class Session : public BnSession { private: std::shared_ptr cb_; + std::mt19937 mRandom; }; } // namespace aidl::android::hardware::biometrics::face -- GitLab From 046020b149aaa9aca90d294356114cde7af94633 Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Sat, 3 Jul 2021 00:05:47 +0000 Subject: [PATCH 743/790] IFace: update VTS tests Bug: 170650876 Test: atest VtsHalBiometricsFaceTargetTest Change-Id: I0b38a98acaec654b144dbe56fc64c5c741bd4488 --- .../vts/VtsHalBiometricsFaceTargetTest.cpp | 203 +++++++++++++++--- 1 file changed, 179 insertions(+), 24 deletions(-) diff --git a/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp b/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp index 47a78139f2..4dc44f16c7 100644 --- a/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp +++ b/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp @@ -29,16 +29,26 @@ namespace { using namespace std::literals::chrono_literals; +using aidl::android::hardware::common::NativeHandle; + constexpr int kSensorId = 0; constexpr int kUserId = 0; class SessionCallback : public BnSessionCallback { public: - ndk::ScopedAStatus onChallengeGenerated(int64_t /*challenge*/) override { + ndk::ScopedAStatus onChallengeGenerated(int64_t challenge) override { + auto lock = std::lock_guard{mMutex}; + mOnChallengeGeneratedInvoked = true; + mGeneratedChallenge = challenge; + mCv.notify_one(); return ndk::ScopedAStatus::ok(); } - ndk::ScopedAStatus onChallengeRevoked(int64_t /*challenge*/) override { + ndk::ScopedAStatus onChallengeRevoked(int64_t challenge) override { + auto lock = std::lock_guard{mMutex}; + mOnChallengeRevokedInvoked = true; + mRevokedChallenge = challenge; + mCv.notify_one(); return ndk::ScopedAStatus::ok(); } @@ -50,10 +60,9 @@ class SessionCallback : public BnSessionCallback { return ndk::ScopedAStatus::ok(); } - ndk::ScopedAStatus onError(Error error, int32_t vendorCode) override { + ndk::ScopedAStatus onError(Error error, int32_t /*vendorCode*/) override { auto lock = std::lock_guard{mMutex}; mError = error; - mVendorCode = vendorCode; mOnErrorInvoked = true; mCv.notify_one(); return ndk::ScopedAStatus::ok(); @@ -83,15 +92,24 @@ class SessionCallback : public BnSessionCallback { ndk::ScopedAStatus onEnrollmentsEnumerated( const std::vector& /*enrollmentIds*/) override { + auto lock = std::lock_guard{mMutex}; + mOnEnrollmentsEnumeratedInvoked = true; + mCv.notify_one(); return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus onEnrollmentsRemoved( const std::vector& /*enrollmentIds*/) override { + auto lock = std::lock_guard{mMutex}; + mOnEnrollmentsRemovedInvoked = true; + mCv.notify_one(); return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus onFeaturesRetrieved(const std::vector& /*features*/) override { + auto lock = std::lock_guard{mMutex}; + mOnFeaturesRetrievedInvoked = true; + mCv.notify_one(); return ndk::ScopedAStatus::ok(); } @@ -100,10 +118,16 @@ class SessionCallback : public BnSessionCallback { } ndk::ScopedAStatus onAuthenticatorIdRetrieved(int64_t /*authenticatorId*/) override { + auto lock = std::lock_guard{mMutex}; + mOnAuthenticatorIdRetrievedInvoked = true; + mCv.notify_one(); return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus onAuthenticatorIdInvalidated(int64_t /*newAuthenticatorId*/) override { + auto lock = std::lock_guard{mMutex}; + mOnAuthenticatorIdInvalidatedInvoked = true; + mCv.notify_one(); return ndk::ScopedAStatus::ok(); } @@ -117,46 +141,177 @@ class SessionCallback : public BnSessionCallback { std::mutex mMutex; std::condition_variable mCv; Error mError = Error::UNKNOWN; - int32_t mVendorCode = 0; + int64_t mGeneratedChallenge = 0; + int64_t mRevokedChallenge = 0; + bool mOnChallengeGeneratedInvoked = false; + bool mOnChallengeRevokedInvoked = false; bool mOnErrorInvoked = false; + bool mOnEnrollmentsEnumeratedInvoked = false; + bool mOnEnrollmentsRemovedInvoked = false; + bool mOnFeaturesRetrievedInvoked = false; + bool mOnAuthenticatorIdRetrievedInvoked = false; + bool mOnAuthenticatorIdInvalidatedInvoked = false; bool mOnSessionClosedInvoked = false; }; class Face : public testing::TestWithParam { protected: void SetUp() override { - AIBinder* binder = AServiceManager_waitForService(GetParam().c_str()); - ASSERT_NE(binder, nullptr); - mHal = IFace::fromBinder(ndk::SpAIBinder(binder)); + // Prepare the callback. + mCb = ndk::SharedRefBase::make(); + + int retries = 0; + bool isOk = false; + // If the first attempt to create a session fails, we try to create a session again. The + // first attempt might fail if the framework already has an active session. The AIDL + // contract doesn't allow to create a new session without closing the old one. However, we + // can't close the framework's session from VTS. The expectation here is that the HAL will + // crash after the first illegal attempt to create a session, then it will restart, and then + // we'll be able to create a session. + do { + // Get an instance of the HAL. + AIBinder* binder = AServiceManager_waitForService(GetParam().c_str()); + ASSERT_NE(binder, nullptr); + mHal = IFace::fromBinder(ndk::SpAIBinder(binder)); + + // Create a session. + isOk = mHal->createSession(kSensorId, kUserId, mCb, &mSession).isOk(); + ++retries; + } while (!isOk && retries < 2); + + ASSERT_TRUE(isOk); + } + + void TearDown() override { + // Close the mSession. + ASSERT_TRUE(mSession->close().isOk()); + + // Make sure the mSession is closed. + auto lock = std::unique_lock(mCb->mMutex); + mCb->mCv.wait(lock, [this] { return mCb->mOnSessionClosedInvoked; }); } std::shared_ptr mHal; + std::shared_ptr mCb; + std::shared_ptr mSession; }; -TEST_P(Face, AuthenticateTest) { - // Prepare the callback. - auto cb = ndk::SharedRefBase::make(); +TEST_P(Face, GetSensorPropsWorksTest) { + std::vector sensorProps; - // Create a session - std::shared_ptr session; - ASSERT_TRUE(mHal->createSession(kSensorId, kUserId, cb, &session).isOk()); + // Call the method. + ASSERT_TRUE(mHal->getSensorProps(&sensorProps).isOk()); - // Call authenticate + // Make sure the sensorProps aren't empty. + ASSERT_FALSE(sensorProps.empty()); + ASSERT_FALSE(sensorProps[0].commonProps.componentInfo.empty()); +} + +TEST_P(Face, EnrollWithBadHatResultsInErrorTest) { + // Call the method. + auto hat = keymaster::HardwareAuthToken{}; std::shared_ptr cancellationSignal; - ASSERT_TRUE(session->authenticate(0 /* operationId */, &cancellationSignal).isOk()); + ASSERT_TRUE( + mSession->enroll(hat, EnrollmentType::DEFAULT, {}, NativeHandle{}, &cancellationSignal) + .isOk()); + + // Make sure an error is returned. + auto lock = std::unique_lock{mCb->mMutex}; + mCb->mCv.wait(lock, [this] { return mCb->mOnErrorInvoked; }); +} + +TEST_P(Face, GenerateChallengeProducesUniqueChallengesTest) { + static constexpr int kIterations = 100; + + auto challenges = std::set{}; + for (unsigned int i = 0; i < kIterations; ++i) { + // Call the method. + ASSERT_TRUE(mSession->generateChallenge().isOk()); + + // Check that the generated challenge is unique and not 0. + auto lock = std::unique_lock{mCb->mMutex}; + mCb->mCv.wait(lock, [this] { return mCb->mOnChallengeGeneratedInvoked; }); + ASSERT_NE(mCb->mGeneratedChallenge, 0); + ASSERT_EQ(challenges.find(mCb->mGeneratedChallenge), challenges.end()); + + challenges.insert(mCb->mGeneratedChallenge); + mCb->mOnChallengeGeneratedInvoked = false; + } +} - auto lock = std::unique_lock(cb->mMutex); - cb->mCv.wait(lock, [&cb] { return cb->mOnErrorInvoked; }); - // Get the results - EXPECT_EQ(cb->mError, Error::UNABLE_TO_PROCESS); - EXPECT_EQ(cb->mVendorCode, 0); +TEST_P(Face, RevokeChallengeWorksForNonexistentChallengeTest) { + const int64_t nonexistentChallenge = 123; + + // Call the method. + ASSERT_TRUE(mSession->revokeChallenge(nonexistentChallenge).isOk()); + + // Check that the challenge is revoked and matches the requested challenge. + auto lock = std::unique_lock{mCb->mMutex}; + mCb->mCv.wait(lock, [this] { return mCb->mOnChallengeRevokedInvoked; }); + ASSERT_EQ(mCb->mRevokedChallenge, nonexistentChallenge); +} + +TEST_P(Face, RevokeChallengeWorksForExistentChallengeTest) { + // Generate a challenge. + ASSERT_TRUE(mSession->generateChallenge().isOk()); + + // Wait for the result. + auto lock = std::unique_lock{mCb->mMutex}; + mCb->mCv.wait(lock, [this] { return mCb->mOnChallengeGeneratedInvoked; }); lock.unlock(); - // Close the session - ASSERT_TRUE(session->close().isOk()); + // Revoke the challenge. + ASSERT_TRUE(mSession->revokeChallenge(mCb->mGeneratedChallenge).isOk()); + // Check that the challenge is revoked and matches the requested challenge. lock.lock(); - cb->mCv.wait(lock, [&cb] { return cb->mOnSessionClosedInvoked; }); + mCb->mCv.wait(lock, [this] { return mCb->mOnChallengeRevokedInvoked; }); + ASSERT_EQ(mCb->mRevokedChallenge, mCb->mGeneratedChallenge); +} + +TEST_P(Face, EnumerateEnrollmentsWorksTest) { + // Call the method. + ASSERT_TRUE(mSession->enumerateEnrollments().isOk()); + + // Wait for the result. + auto lock = std::unique_lock{mCb->mMutex}; + mCb->mCv.wait(lock, [this] { return mCb->mOnEnrollmentsEnumeratedInvoked; }); +} + +TEST_P(Face, RemoveEnrollmentsWorksTest) { + // Call the method. + ASSERT_TRUE(mSession->removeEnrollments({}).isOk()); + + // Wait for the result. + auto lock = std::unique_lock{mCb->mMutex}; + mCb->mCv.wait(lock, [this] { return mCb->mOnEnrollmentsRemovedInvoked; }); +} + +TEST_P(Face, GetFeaturesWorksTest) { + // Call the method. + ASSERT_TRUE(mSession->getFeatures().isOk()); + + // Wait for the result. + auto lock = std::unique_lock{mCb->mMutex}; + mCb->mCv.wait(lock, [this] { return mCb->mOnFeaturesRetrievedInvoked; }); +} + +TEST_P(Face, GetAuthenticatorIdWorksTest) { + // Call the method. + ASSERT_TRUE(mSession->getAuthenticatorId().isOk()); + + // Wait for the result. + auto lock = std::unique_lock{mCb->mMutex}; + mCb->mCv.wait(lock, [this] { return mCb->mOnAuthenticatorIdRetrievedInvoked; }); +} + +TEST_P(Face, InvalidateAuthenticatorIdWorksTest) { + // Call the method. + ASSERT_TRUE(mSession->invalidateAuthenticatorId().isOk()); + + // Wait for the result. + auto lock = std::unique_lock{mCb->mMutex}; + mCb->mCv.wait(lock, [this] { return mCb->mOnAuthenticatorIdInvalidatedInvoked; }); } GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Face); -- GitLab From d65b354deee2d3a90d670838180212329ec37abc Mon Sep 17 00:00:00 2001 From: Marin Shalamanov Date: Wed, 23 Jun 2021 14:12:37 +0200 Subject: [PATCH 744/790] VTS: Validate that getDisplayIdentificationData returns EDID Accroding to the documentation getDisplayIdentificationData "data is the EDID 1.3 blob identifying the display". This CL runs a basic validation that the returned data is an EDID. Test: atest VtsHalGraphicsComposerV2_3TargetTest Bug: 191851265 Change-Id: I7604f3dc68095612d79bb04243918d6348de6c89 --- .../VtsHalGraphicsComposerV2_3TargetTest.cpp | 34 ++++++++++++++----- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp b/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp index 54ba79dcc1..ecfe66c80d 100644 --- a/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp +++ b/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp @@ -17,6 +17,7 @@ #define LOG_TAG "graphics_composer_hidl_hal_test@2.3" #include +#include #include #include @@ -155,16 +156,31 @@ class GraphicsComposerHidlCommandTest : public GraphicsComposerHidlTest { TEST_P(GraphicsComposerHidlTest, GetDisplayIdentificationData) { uint8_t port0; std::vector data0; - if (mComposerClient->getDisplayIdentificationData(mPrimaryDisplay, &port0, &data0)) { - uint8_t port1; - std::vector data1; - ASSERT_TRUE(mComposerClient->getDisplayIdentificationData(mPrimaryDisplay, &port1, &data1)); - - ASSERT_EQ(port0, port1) << "ports are not stable"; - ASSERT_TRUE(data0.size() == data1.size() && - std::equal(data0.begin(), data0.end(), data1.begin())) - << "data is not stable"; + + if (!mComposerClient->getDisplayIdentificationData(mPrimaryDisplay, &port0, &data0)) { + return; } + + ASSERT_FALSE(data0.empty()); + constexpr size_t kEdidBlockSize = 128; + ASSERT_TRUE(data0.size() % kEdidBlockSize == 0) + << "EDID blob length is not a multiple of " << kEdidBlockSize; + + const uint8_t kEdidHeader[] = {0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00}; + ASSERT_TRUE(std::equal(std::begin(kEdidHeader), std::end(kEdidHeader), data0.begin())) + << "EDID blob doesn't start with the fixed EDID header"; + ASSERT_EQ(0, std::accumulate(data0.begin(), data0.begin() + kEdidBlockSize, + static_cast(0))) + << "EDID base block doesn't checksum"; + + uint8_t port1; + std::vector data1; + ASSERT_TRUE(mComposerClient->getDisplayIdentificationData(mPrimaryDisplay, &port1, &data1)); + + ASSERT_EQ(port0, port1) << "ports are not stable"; + ASSERT_TRUE(data0.size() == data1.size() && + std::equal(data0.begin(), data0.end(), data1.begin())) + << "data is not stable"; } /** -- GitLab From dd0e20eba3a0b7a2fbbe6f0429b9eb3cadd8b883 Mon Sep 17 00:00:00 2001 From: Mikhail Naganov Date: Wed, 7 Jul 2021 17:07:15 +0000 Subject: [PATCH 745/790] Revert "audio: exclude the echo reference device in capture position test" This reverts commit b22f307ccfd1072e3d61deb4e03659db7a168b7d. Reason for revert: As explained in b/192307382#comment12, the HAL must provide capture positions for the echo reference input regardless of whether there is any actual output. This should not affect O6/R4 as according to b/192307382#comment10, the VTS tests pass w/o this patch after the HAL has been fixed. Bug: 192307382 Change-Id: I224bd9de1dcb2e2c8dc138dbfd85f848378aea4f Test: VtsHalAudioV7_0TargetTest --gtest_filter=*PcmOnlyConfigInputStreamTest* --- .../android_audio_policy_configuration_V7_0-enums.h | 8 -------- .../vts/functional/7.0/AudioPrimaryHidlHalTest.cpp | 3 +-- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/audio/common/7.0/enums/include/android_audio_policy_configuration_V7_0-enums.h b/audio/common/7.0/enums/include/android_audio_policy_configuration_V7_0-enums.h index 79243b6e05..a92a277471 100644 --- a/audio/common/7.0/enums/include/android_audio_policy_configuration_V7_0-enums.h +++ b/audio/common/7.0/enums/include/android_audio_policy_configuration_V7_0-enums.h @@ -225,14 +225,6 @@ static inline bool isTelephonyDevice(const std::string& device) { return isTelephonyDevice(stringToAudioDevice(device)); } -static inline bool isEchoReferenceDevice(AudioDevice device) { - return device == AudioDevice::AUDIO_DEVICE_IN_ECHO_REFERENCE; -} - -static inline bool isEchoReferenceDevice(const std::string& device) { - return isEchoReferenceDevice(stringToAudioDevice(device)); -} - static inline bool maybeVendorExtension(const std::string& s) { // Only checks whether the string starts with the "vendor prefix". static const std::string vendorPrefix = "VX_"; diff --git a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp index 79ac295151..0b3098b872 100644 --- a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp +++ b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp @@ -710,8 +710,7 @@ class PcmOnlyConfigInputStreamTest : public InputStreamTest { // Returning 'true' when no source is found so the test can fail later with a more clear // problem description. return !maybeSourceAddress.has_value() || - !(xsd::isTelephonyDevice(maybeSourceAddress.value().deviceType) || - xsd::isEchoReferenceDevice(maybeSourceAddress.value().deviceType)); + !xsd::isTelephonyDevice(maybeSourceAddress.value().deviceType); } void createPatchIfNeeded() { -- GitLab From 13c679652834db45e2df4137f088ecd06351f017 Mon Sep 17 00:00:00 2001 From: Mikhail Naganov Date: Sat, 3 Jul 2021 00:49:13 +0000 Subject: [PATCH 746/790] audio: Fix handling of relative XML include paths in VTS Pass "no fixup base dirs" flag to the XInclude processor to avoid modifications of the top-level elements from included XML files as a result of "fixup." Added tests to ensure that all relevant XInclude scenarios work. Bug: 192619060 Test: atest -host android.hardware.audio.common.test.utility_tests Change-Id: Id595c9fd30be378d76387ee55a8937e0bf28d1cd --- .../all-versions/test/utility/Android.bp | 31 ++- .../all-versions/test/utility/TEST_MAPPING | 7 + .../test/utility/src/ValidateXml.cpp | 3 +- .../test/utility/tests/utility_tests.cpp | 176 ++++++++++++++++++ 4 files changed, 214 insertions(+), 3 deletions(-) create mode 100644 audio/common/all-versions/test/utility/TEST_MAPPING create mode 100644 audio/common/all-versions/test/utility/tests/utility_tests.cpp diff --git a/audio/common/all-versions/test/utility/Android.bp b/audio/common/all-versions/test/utility/Android.bp index 1602d25b2f..757f8a853d 100644 --- a/audio/common/all-versions/test/utility/Android.bp +++ b/audio/common/all-versions/test/utility/Android.bp @@ -25,7 +25,7 @@ package { cc_library_static { name: "android.hardware.audio.common.test.utility", - defaults : ["hidl_defaults"], + defaults: ["hidl_defaults"], srcs: ["src/ValidateXml.cpp"], cflags: [ "-O0", @@ -34,7 +34,34 @@ cc_library_static { ], local_include_dirs: ["include/utility"], export_include_dirs: ["include"], - shared_libs: ["libxml2", "liblog"], + shared_libs: [ + "libxml2", + "liblog", + ], static_libs: ["libgtest"], export_static_lib_headers: ["libgtest"], } + +// Note: this isn't a VTS test, but rather a unit test +// to verify correctness of test utilities. +cc_test { + name: "android.hardware.audio.common.test.utility_tests", + host_supported: true, + local_include_dirs: ["include/utility"], + srcs: [ + "src/ValidateXml.cpp", + "tests/utility_tests.cpp", + ], + cflags: [ + "-Werror", + "-Wall", + "-g", + ], + shared_libs: [ + "libbase", + "libxml2", + "liblog", + ], + static_libs: ["libgtest"], + test_suites: ["general-tests"], +} diff --git a/audio/common/all-versions/test/utility/TEST_MAPPING b/audio/common/all-versions/test/utility/TEST_MAPPING new file mode 100644 index 0000000000..0bc187157a --- /dev/null +++ b/audio/common/all-versions/test/utility/TEST_MAPPING @@ -0,0 +1,7 @@ +{ + "presubmit": [ + { + "name": "android.hardware.audio.common.test.utility_tests" + } + ] +} diff --git a/audio/common/all-versions/test/utility/src/ValidateXml.cpp b/audio/common/all-versions/test/utility/src/ValidateXml.cpp index a866104b38..f111c011d9 100644 --- a/audio/common/all-versions/test/utility/src/ValidateXml.cpp +++ b/audio/common/all-versions/test/utility/src/ValidateXml.cpp @@ -112,7 +112,8 @@ struct Libxml2Global { return ::testing::AssertionFailure() << "Failed to parse xml\n" << context(); } - if (xmlXIncludeProcess(doc.get()) == -1) { + // Process 'include' directives w/o modifying elements loaded from included files. + if (xmlXIncludeProcessFlags(doc.get(), XML_PARSE_NOBASEFIX) == -1) { return ::testing::AssertionFailure() << "Failed to resolve xincludes in xml\n" << context(); } diff --git a/audio/common/all-versions/test/utility/tests/utility_tests.cpp b/audio/common/all-versions/test/utility/tests/utility_tests.cpp new file mode 100644 index 0000000000..c52306638f --- /dev/null +++ b/audio/common/all-versions/test/utility/tests/utility_tests.cpp @@ -0,0 +1,176 @@ +/* + * 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 +#include + +#include + +using ::android::hardware::audio::common::test::utility::validateXml; + +const char* XSD_SOURCE = + "" + "" + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + ""; + +const char* INVALID_XML_SOURCE = + "" + ""; + +const char* VALID_XML_SOURCE = + "" + "" + " " + " " + " %s" + " " + ""; + +const char* MODULE_SOURCE = ""; + +const char* XI_INCLUDE = ""; + +const char* XML_INCLUDED_SOURCE = "%s"; + +namespace { + +std::string substitute(const char* fmt, const char* param) { + std::string buffer(static_cast(strlen(fmt) + strlen(param)), '\0'); + snprintf(buffer.data(), buffer.size(), fmt, param); + return buffer; +} + +std::string substitute(const char* fmt, const std::string& s) { + return substitute(fmt, s.c_str()); +} + +} // namespace + +TEST(ValidateXml, InvalidXml) { + TemporaryFile xml; + ASSERT_TRUE(android::base::WriteStringToFile(INVALID_XML_SOURCE, xml.path)) << strerror(errno); + TemporaryFile xsd; + ASSERT_TRUE(android::base::WriteStringToFile(XSD_SOURCE, xsd.path)) << strerror(errno); + EXPECT_FALSE(validateXml("xml", "xsd", xml.path, xsd.path)); +} + +TEST(ValidateXml, ValidXml) { + TemporaryFile xml; + ASSERT_TRUE( + android::base::WriteStringToFile(substitute(VALID_XML_SOURCE, MODULE_SOURCE), xml.path)) + << strerror(errno); + TemporaryFile xsd; + ASSERT_TRUE(android::base::WriteStringToFile(XSD_SOURCE, xsd.path)) << strerror(errno); + EXPECT_TRUE(validateXml("xml", "xsd", xml.path, xsd.path)); +} + +TEST(ValidateXml, IncludeAbsolutePath) { + TemporaryFile xmlInclude; + ASSERT_TRUE(android::base::WriteStringToFile(substitute(XML_INCLUDED_SOURCE, MODULE_SOURCE), + xmlInclude.path)) + << strerror(errno); + TemporaryFile xml; + ASSERT_TRUE(android::base::WriteStringToFile( + substitute(VALID_XML_SOURCE, substitute(XI_INCLUDE, xmlInclude.path)), xml.path)) + << strerror(errno); + TemporaryFile xsd; + ASSERT_TRUE(android::base::WriteStringToFile(XSD_SOURCE, xsd.path)) << strerror(errno); + EXPECT_TRUE(validateXml("xml", "xsd", xml.path, xsd.path)); +} + +TEST(ValidateXml, IncludeSameDirRelativePath) { + TemporaryFile xmlInclude; + ASSERT_TRUE(android::base::WriteStringToFile(substitute(XML_INCLUDED_SOURCE, MODULE_SOURCE), + xmlInclude.path)) + << strerror(errno); + TemporaryFile xml; + ASSERT_EQ(android::base::Dirname(xml.path), android::base::Dirname(xmlInclude.path)); + ASSERT_TRUE(android::base::WriteStringToFile( + substitute(VALID_XML_SOURCE, + substitute(XI_INCLUDE, android::base::Basename(xmlInclude.path))), + xml.path)) + << strerror(errno); + TemporaryFile xsd; + ASSERT_TRUE(android::base::WriteStringToFile(XSD_SOURCE, xsd.path)) << strerror(errno); + EXPECT_TRUE(validateXml("xml", "xsd", xml.path, xsd.path)); +} + +TEST(ValidateXml, IncludeSubdirRelativePath) { + TemporaryDir xmlIncludeDir; + TemporaryFile xmlInclude(xmlIncludeDir.path); + ASSERT_TRUE(android::base::WriteStringToFile(substitute(XML_INCLUDED_SOURCE, MODULE_SOURCE), + xmlInclude.path)) + << strerror(errno); + TemporaryFile xml; + ASSERT_EQ(android::base::Dirname(xml.path), android::base::Dirname(xmlIncludeDir.path)); + ASSERT_TRUE(android::base::WriteStringToFile( + substitute(VALID_XML_SOURCE, + substitute(XI_INCLUDE, android::base::Basename(xmlIncludeDir.path) + "/" + + android::base::Basename(xmlInclude.path))), + xml.path)) + << strerror(errno); + TemporaryFile xsd; + ASSERT_TRUE(android::base::WriteStringToFile(XSD_SOURCE, xsd.path)) << strerror(errno); + EXPECT_TRUE(validateXml("xml", "xsd", xml.path, xsd.path)); +} + +TEST(ValidateXml, IncludeParentDirRelativePath) { + // An XML file from a subdirectory includes a file from the parent directory using '..' syntax. + TemporaryFile xmlInclude; + ASSERT_TRUE(android::base::WriteStringToFile(substitute(XML_INCLUDED_SOURCE, MODULE_SOURCE), + xmlInclude.path)) + << strerror(errno); + TemporaryDir xmlIncludeDir; + TemporaryFile xmlParentInclude(xmlIncludeDir.path); + ASSERT_TRUE(android::base::WriteStringToFile( + substitute(XML_INCLUDED_SOURCE, + substitute(XI_INCLUDE, "../" + android::base::Basename(xmlInclude.path))), + xmlParentInclude.path)) + << strerror(errno); + TemporaryFile xml; + ASSERT_EQ(android::base::Dirname(xml.path), android::base::Dirname(xmlInclude.path)); + ASSERT_EQ(android::base::Dirname(xml.path), android::base::Dirname(xmlIncludeDir.path)); + ASSERT_TRUE(android::base::WriteStringToFile( + substitute( + VALID_XML_SOURCE, + substitute(XI_INCLUDE, android::base::Basename(xmlIncludeDir.path) + "/" + + android::base::Basename(xmlParentInclude.path))), + xml.path)) + << strerror(errno); + TemporaryFile xsd; + ASSERT_TRUE(android::base::WriteStringToFile(XSD_SOURCE, xsd.path)) << strerror(errno); + EXPECT_TRUE(validateXml("xml", "xsd", xml.path, xsd.path)); +} -- GitLab From 12ee28322da50ee86484f401c70bd119cc4b4042 Mon Sep 17 00:00:00 2001 From: Eran Messeri Date: Mon, 28 Jun 2021 12:07:37 +0100 Subject: [PATCH 747/790] Annotate some TODOs There are two tags that cannot be currently removed but should be removed in KeyMint V2. Mark them as deprecated and point to the bug for deletion. Bug: 183737811 Test: That it compiles. Change-Id: I98b96cc8c49eb339a998d0abed9216aa57f6b19f Merged-In: I80ccaedeb777fdb249a8cb021db6628da32d6029 --- .../keymint/aidl/android/hardware/security/keymint/Tag.aidl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl index 270574bbfb..5600889393 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl @@ -293,6 +293,8 @@ enum Tag { * fails because the table is full, KeyMint returns ErrorCode::TOO_MANY_OPERATIONS. * * Must be hardware-enforced. + * + * TODO(b/191738660): Remove in KeyMint V2. Currently only used for FDE. */ MIN_SECONDS_BETWEEN_OPS = (3 << 28) /* TagType:UINT */ | 403, @@ -883,7 +885,8 @@ enum Tag { STORAGE_KEY = (7 << 28) /* TagType:BOOL */ | 722, /** - * TODO: Delete when keystore1 is deleted. + * OBSOLETE: Do not use. See IKeyMintOperation.updateAad instead. + * TODO(b/191738660): Remove in KeyMint v2. */ ASSOCIATED_DATA = (9 << 28) /* TagType:BYTES */ | 1000, -- GitLab From befeda6b00eef1042aba3a3d0e3d401636da5289 Mon Sep 17 00:00:00 2001 From: Eran Messeri Date: Tue, 15 Jun 2021 14:26:59 +0100 Subject: [PATCH 748/790] Use TagType constants Now that the aidl compiler supports it, use constants from TagType to indicate the type of each tag, rather than duplicating the values of the constants. Test: atest VtsAidlKeyMintTargetTest Bug: 183737811 Merged-In: Ie8af1f00d04fa05c59cfc72692caecbcf2fae483 Change-Id: Ie62b6ee8a8ced05a870711073bb3be16931f3d4d --- .../hardware/security/keymint/Tag.aidl | 134 +++++++++--------- 1 file changed, 65 insertions(+), 69 deletions(-) diff --git a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl index 270574bbfb..a785480dac 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl @@ -18,10 +18,6 @@ package android.hardware.security.keymint; import android.hardware.security.keymint.TagType; -// TODO(seleneh) : note aidl currently does not support double nested enum definitions such as -// ROOT_OF_TRUST = TagType:BYTES | 704. So we are forced to write definitions as -// ROOT_OF_TRUST = (9 << 28) for now. Will need to flip this back later when aidl support is added. - /** * Tag specifies various kinds of tags that can be set in KeyParameter to identify what kind of * data are stored in KeyParameter. @@ -33,7 +29,7 @@ enum Tag { /** * Tag::INVALID should never be set. It means you hit an error. */ - INVALID = (0 << 28) | 0, + INVALID = 0, /** * Tag::PURPOSE specifies the set of purposes for which the key may be used. Possible values @@ -47,7 +43,7 @@ enum Tag { * * Must be hardware-enforced. */ - PURPOSE = (2 << 28) /* TagType:ENUM_REP */ | 1, + PURPOSE = TagType.ENUM_REP | 1, /** * Tag::ALGORITHM specifies the cryptographic algorithm with which the key is used. This tag @@ -56,7 +52,7 @@ enum Tag { * * Must be hardware-enforced. */ - ALGORITHM = (1 << 28) /* TagType:ENUM */ | 2, + ALGORITHM = TagType.ENUM | 2, /** * Tag::KEY_SIZE specifies the size, in bits, of the key, measuring in the normal way for the @@ -68,7 +64,7 @@ enum Tag { * * Must be hardware-enforced. */ - KEY_SIZE = (3 << 28) /* TagType:UINT */ | 3, + KEY_SIZE = TagType.UINT | 3, /** * Tag::BLOCK_MODE specifies the block cipher mode(s) with which the key may be used. This tag @@ -81,7 +77,7 @@ enum Tag { * * Must be hardware-enforced. */ - BLOCK_MODE = (2 << 28) /* TagType:ENUM_REP */ | 4, + BLOCK_MODE = TagType.ENUM_REP | 4, /** * Tag::DIGEST specifies the digest algorithms that may be used with the key to perform signing @@ -95,7 +91,7 @@ enum Tag { * * Must be hardware-enforced. */ - DIGEST = (2 << 28) /* TagType:ENUM_REP */ | 5, + DIGEST = TagType.ENUM_REP | 5, /** * Tag::PADDING specifies the padding modes that may be used with the key. This tag is relevant @@ -123,7 +119,7 @@ enum Tag { * * Must be hardware-enforced. */ - PADDING = (2 << 28) /* TagType:ENUM_REP */ | 6, + PADDING = TagType.ENUM_REP | 6, /** * Tag::CALLER_NONCE specifies that the caller can provide a nonce for nonce-requiring @@ -136,7 +132,7 @@ enum Tag { * * Must be hardware-enforced. */ - CALLER_NONCE = (7 << 28) /* TagType:BOOL */ | 7, + CALLER_NONCE = TagType.BOOL | 7, /** * Tag::MIN_MAC_LENGTH specifies the minimum length of MAC that can be requested or verified @@ -149,7 +145,7 @@ enum Tag { * * Must be hardware-enforced. */ - MIN_MAC_LENGTH = (3 << 28) /* TagType:UINT */ | 8, + MIN_MAC_LENGTH = TagType.UINT | 8, // Tag 9 reserved @@ -159,7 +155,7 @@ enum Tag { * * Must be hardware-enforced. */ - EC_CURVE = (1 << 28) /* TagType:ENUM */ | 10, + EC_CURVE = TagType.ENUM | 10, /** * Tag::RSA_PUBLIC_EXPONENT specifies the value of the public exponent for an RSA key pair. @@ -173,7 +169,7 @@ enum Tag { * * Must be hardware-enforced. */ - RSA_PUBLIC_EXPONENT = (5 << 28) /* TagType:ULONG */ | 200, + RSA_PUBLIC_EXPONENT = TagType.ULONG | 200, // Tag 201 reserved @@ -184,7 +180,7 @@ enum Tag { * * Must be hardware-enforced. */ - INCLUDE_UNIQUE_ID = (7 << 28) /* TagType:BOOL */ | 202, + INCLUDE_UNIQUE_ID = TagType.BOOL | 202, /** * Tag::RSA_OAEP_MGF_DIGEST specifies the MGF1 digest algorithms that may be used with RSA @@ -197,7 +193,7 @@ enum Tag { * * Must be hardware-enforced. */ - RSA_OAEP_MGF_DIGEST = (2 << 28) /* TagType:ENUM_REP */ | 203, + RSA_OAEP_MGF_DIGEST = TagType.ENUM_REP | 203, // Tag 301 reserved @@ -209,7 +205,7 @@ enum Tag { * * Must be hardware-enforced. */ - BOOTLOADER_ONLY = (7 << 28) /* TagType:BOOL */ | 302, + BOOTLOADER_ONLY = TagType.BOOL | 302, /** * Tag::ROLLBACK_RESISTANCE specifies that the key has rollback resistance, meaning that when @@ -224,10 +220,10 @@ enum Tag { * * Must be hardware-enforced. */ - ROLLBACK_RESISTANCE = (7 << 28) /* TagType:BOOL */ | 303, + ROLLBACK_RESISTANCE = TagType.BOOL | 303, // Reserved for future use. - HARDWARE_TYPE = (1 << 28) /* TagType:ENUM */ | 304, + HARDWARE_TYPE = TagType.ENUM | 304, /** * Keys tagged with EARLY_BOOT_ONLY may only be used during early boot, until @@ -236,7 +232,7 @@ enum Tag { * provided to IKeyMintDevice::importKey, the import must fail with * ErrorCode::EARLY_BOOT_ENDED. */ - EARLY_BOOT_ONLY = (7 << 28) /* TagType:BOOL */ | 305, + EARLY_BOOT_ONLY = TagType.BOOL | 305, /** * Tag::ACTIVE_DATETIME specifies the date and time at which the key becomes active, in @@ -245,7 +241,7 @@ enum Tag { * * Need not be hardware-enforced. */ - ACTIVE_DATETIME = (6 << 28) /* TagType:DATE */ | 400, + ACTIVE_DATETIME = TagType.DATE | 400, /** * Tag::ORIGINATION_EXPIRE_DATETIME specifies the date and time at which the key expires for @@ -257,7 +253,7 @@ enum Tag { * * Need not be hardware-enforced. */ - ORIGINATION_EXPIRE_DATETIME = (6 << 28) /* TagType:DATE */ | 401, + ORIGINATION_EXPIRE_DATETIME = TagType.DATE | 401, /** * Tag::USAGE_EXPIRE_DATETIME specifies the date and time at which the key expires for @@ -269,7 +265,7 @@ enum Tag { * * Need not be hardware-enforced. */ - USAGE_EXPIRE_DATETIME = (6 << 28) /* TagType:DATE */ | 402, + USAGE_EXPIRE_DATETIME = TagType.DATE | 402, /** * TODO(seleneh) this tag need to be deleted. @@ -294,7 +290,7 @@ enum Tag { * * Must be hardware-enforced. */ - MIN_SECONDS_BETWEEN_OPS = (3 << 28) /* TagType:UINT */ | 403, + MIN_SECONDS_BETWEEN_OPS = TagType.UINT | 403, /** * Tag::MAX_USES_PER_BOOT specifies the maximum number of times that a key may be used between @@ -314,7 +310,7 @@ enum Tag { * * Must be hardware-enforced. */ - MAX_USES_PER_BOOT = (3 << 28) /* TagType:UINT */ | 404, + MAX_USES_PER_BOOT = TagType.UINT | 404, /** * Tag::USAGE_COUNT_LIMIT specifies the number of times that a key may be used. This can be @@ -343,14 +339,14 @@ enum Tag { * record. This tag must have the same SecurityLevel as the tag that is added to the key * characteristics. */ - USAGE_COUNT_LIMIT = (3 << 28) | 405, /* TagType:UINT */ + USAGE_COUNT_LIMIT = TagType.UINT | 405, /** * Tag::USER_ID specifies the ID of the Android user that is permitted to use the key. * * Must not be hardware-enforced. */ - USER_ID = (3 << 28) /* TagType:UINT */ | 501, + USER_ID = TagType.UINT | 501, /** * Tag::USER_SECURE_ID specifies that a key may only be used under a particular secure user @@ -383,7 +379,7 @@ enum Tag { * * Must be hardware-enforced. */ - USER_SECURE_ID = (10 << 28) /* TagType:ULONG_REP */ | 502, + USER_SECURE_ID = TagType.ULONG_REP | 502, /** * Tag::NO_AUTH_REQUIRED specifies that no authentication is required to use this key. This tag @@ -391,7 +387,7 @@ enum Tag { * * Must be hardware-enforced. */ - NO_AUTH_REQUIRED = (7 << 28) /* TagType:BOOL */ | 503, + NO_AUTH_REQUIRED = TagType.BOOL | 503, /** * Tag::USER_AUTH_TYPE specifies the types of user authenticators that may be used to authorize @@ -410,7 +406,7 @@ enum Tag { * * Must be hardware-enforced. */ - USER_AUTH_TYPE = (1 << 28) /* TagType:ENUM */ | 504, + USER_AUTH_TYPE = TagType.ENUM | 504, /** * Tag::AUTH_TIMEOUT specifies the time in seconds for which the key is authorized for use, @@ -424,7 +420,7 @@ enum Tag { * * Must be hardware-enforced. */ - AUTH_TIMEOUT = (3 << 28) /* TagType:UINT */ | 505, + AUTH_TIMEOUT = TagType.UINT | 505, /** * Tag::ALLOW_WHILE_ON_BODY specifies that the key may be used after authentication timeout if @@ -432,7 +428,7 @@ enum Tag { * * Cannot be hardware-enforced. */ - ALLOW_WHILE_ON_BODY = (7 << 28) /* TagType:BOOL */ | 506, + ALLOW_WHILE_ON_BODY = TagType.BOOL | 506, /** * TRUSTED_USER_PRESENCE_REQUIRED is an optional feature that specifies that this key must be @@ -479,7 +475,7 @@ enum Tag { * * Must be hardware-enforced. */ - TRUSTED_USER_PRESENCE_REQUIRED = (7 << 28) /* TagType:BOOL */ | 507, + TRUSTED_USER_PRESENCE_REQUIRED = TagType.BOOL | 507, /** * Tag::TRUSTED_CONFIRMATION_REQUIRED is only applicable to keys with KeyPurpose SIGN, and @@ -493,7 +489,7 @@ enum Tag { * * Must be hardware-enforced. */ - TRUSTED_CONFIRMATION_REQUIRED = (7 << 28) /* TagType:BOOL */ | 508, + TRUSTED_CONFIRMATION_REQUIRED = TagType.BOOL | 508, /** * Tag::UNLOCKED_DEVICE_REQUIRED specifies that the key may only be used when the device is @@ -503,7 +499,7 @@ enum Tag { * Must be hardware-enforced (but is also keystore-enforced on a per-user basis: see the * deviceLocked() documentation). */ - UNLOCKED_DEVICE_REQUIRED = (7 << 28) /* TagType:BOOL */ | 509, + UNLOCKED_DEVICE_REQUIRED = TagType.BOOL | 509, /** * Tag::APPLICATION_ID. When provided to generateKey or importKey, this tag specifies data @@ -519,7 +515,7 @@ enum Tag { * * Must never appear in KeyCharacteristics. */ - APPLICATION_ID = (9 << 28) /* TagType:BYTES */ | 601, + APPLICATION_ID = TagType.BYTES | 601, /* * Semantically unenforceable tags, either because they have no specific meaning or because @@ -540,7 +536,7 @@ enum Tag { * * Must never appear in KeyCharacteristics. */ - APPLICATION_DATA = (9 << 28) /* TagType:BYTES */ | 700, + APPLICATION_DATA = TagType.BYTES | 700, /** * Tag::CREATION_DATETIME specifies the date and time the key was created, in milliseconds since @@ -548,7 +544,7 @@ enum Tag { * * Must be in the software-enforced list, if provided. */ - CREATION_DATETIME = (6 << 28) /* TagType:DATE */ | 701, + CREATION_DATETIME = TagType.DATE | 701, /** * Tag::ORIGIN specifies where the key was created, if known. This tag must not be specified @@ -557,7 +553,7 @@ enum Tag { * * Must be hardware-enforced. */ - ORIGIN = (1 << 28) /* TagType:ENUM */ | 702, + ORIGIN = TagType.ENUM | 702, // 703 is unused. @@ -569,7 +565,7 @@ enum Tag { * * Must never appear in KeyCharacteristics. */ - ROOT_OF_TRUST = (9 << 28) /* TagType:BYTES */ | 704, + ROOT_OF_TRUST = TagType.BYTES | 704, /** * Tag::OS_VERSION specifies the system OS version with which the key may be used. This tag is @@ -592,7 +588,7 @@ enum Tag { * * Must be hardware-enforced. */ - OS_VERSION = (3 << 28) /* TagType:UINT */ | 705, + OS_VERSION = TagType.UINT | 705, /** * Tag::OS_PATCHLEVEL specifies the system security patch level with which the key may be used. @@ -613,7 +609,7 @@ enum Tag { * * Must be hardware-enforced. */ - OS_PATCHLEVEL = (3 << 28) /* TagType:UINT */ | 706, + OS_PATCHLEVEL = TagType.UINT | 706, /** * Tag::UNIQUE_ID specifies a unique, time-based identifier. This tag is never provided to or @@ -648,7 +644,7 @@ enum Tag { * * Must be hardware-enforced. */ - UNIQUE_ID = (9 << 28) /* TagType:BYTES */ | 707, + UNIQUE_ID = TagType.BYTES | 707, /** * Tag::ATTESTATION_CHALLENGE is used to deliver a "challenge" value to the attested key @@ -657,7 +653,7 @@ enum Tag { * * Must never appear in KeyCharacteristics. */ - ATTESTATION_CHALLENGE = (9 << 28) /* TagType:BYTES */ | 708, + ATTESTATION_CHALLENGE = TagType.BYTES | 708, /** * Tag::ATTESTATION_APPLICATION_ID identifies the set of applications which may use a key, used @@ -683,7 +679,7 @@ enum Tag { * * Cannot be hardware-enforced. */ - ATTESTATION_APPLICATION_ID = (9 << 28) /* TagType:BYTES */ | 709, + ATTESTATION_APPLICATION_ID = TagType.BYTES | 709, /** * Tag::ATTESTATION_ID_BRAND provides the device's brand name, as returned by Build.BRAND in @@ -696,7 +692,7 @@ enum Tag { * * Must never appear in KeyCharacteristics. */ - ATTESTATION_ID_BRAND = (9 << 28) /* TagType:BYTES */ | 710, + ATTESTATION_ID_BRAND = TagType.BYTES | 710, /** * Tag::ATTESTATION_ID_DEVICE provides the device's device name, as returned by Build.DEVICE in @@ -709,7 +705,7 @@ enum Tag { * * Must never appear in KeyCharacteristics. */ - ATTESTATION_ID_DEVICE = (9 << 28) /* TagType:BYTES */ | 711, + ATTESTATION_ID_DEVICE = TagType.BYTES | 711, /** * Tag::ATTESTATION_ID_PRODUCT provides the device's product name, as returned by Build.PRODUCT @@ -722,7 +718,7 @@ enum Tag { * * Must never appear in KeyCharacteristics. */ - ATTESTATION_ID_PRODUCT = (9 << 28) /* TagType:BYTES */ | 712, + ATTESTATION_ID_PRODUCT = TagType.BYTES | 712, /** * Tag::ATTESTATION_ID_SERIAL the device's serial number. This field must be set only when @@ -734,7 +730,7 @@ enum Tag { * * Must never appear in KeyCharacteristics. */ - ATTESTATION_ID_SERIAL = (9 << 28) /* TagType:BYTES */ | 713, + ATTESTATION_ID_SERIAL = TagType.BYTES | 713, /** * Tag::ATTESTATION_ID_IMEI provides the IMEIs for all radios on the device to attested key @@ -747,7 +743,7 @@ enum Tag { * * Must never appear in KeyCharacteristics. */ - ATTESTATION_ID_IMEI = (9 << 28) /* TagType:BYTES */ | 714, + ATTESTATION_ID_IMEI = TagType.BYTES | 714, /** * Tag::ATTESTATION_ID_MEID provides the MEIDs for all radios on the device to attested key @@ -760,7 +756,7 @@ enum Tag { * * Must never appear in KeyCharacteristics. */ - ATTESTATION_ID_MEID = (9 << 28) /* TagType:BYTES */ | 715, + ATTESTATION_ID_MEID = TagType.BYTES | 715, /** * Tag::ATTESTATION_ID_MANUFACTURER provides the device's manufacturer name, as returned by @@ -773,7 +769,7 @@ enum Tag { * * Must never appear in KeyCharacteristics. */ - ATTESTATION_ID_MANUFACTURER = (9 << 28) /* TagType:BYTES */ | 716, + ATTESTATION_ID_MANUFACTURER = TagType.BYTES | 716, /** * Tag::ATTESTATION_ID_MODEL provides the device's model name, as returned by Build.MODEL in @@ -786,7 +782,7 @@ enum Tag { * * Must never appear in KeyCharacteristics. */ - ATTESTATION_ID_MODEL = (9 << 28) /* TagType:BYTES */ | 717, + ATTESTATION_ID_MODEL = TagType.BYTES | 717, /** * Tag::VENDOR_PATCHLEVEL specifies the vendor image security patch level with which the key may @@ -808,7 +804,7 @@ enum Tag { * * Must be hardware-enforced. */ - VENDOR_PATCHLEVEL = (3 << 28) /* TagType:UINT */ | 718, + VENDOR_PATCHLEVEL = TagType.UINT | 718, /** * Tag::BOOT_PATCHLEVEL specifies the boot image (kernel) security patch level with which the @@ -828,7 +824,7 @@ enum Tag { * * Must be hardware-enforced. */ - BOOT_PATCHLEVEL = (3 << 28) /* TagType:UINT */ | 719, + BOOT_PATCHLEVEL = TagType.UINT | 719, /** * DEVICE_UNIQUE_ATTESTATION is an argument to IKeyMintDevice::attested key generation/import @@ -854,7 +850,7 @@ enum Tag { * IKeyMintDevice implementations that support device-unique attestation MUST add the * DEVICE_UNIQUE_ATTESTATION tag to device-unique attestations. */ - DEVICE_UNIQUE_ATTESTATION = (7 << 28) /* TagType:BOOL */ | 720, + DEVICE_UNIQUE_ATTESTATION = TagType.BOOL | 720, /** * IDENTITY_CREDENTIAL_KEY is never used by IKeyMintDevice, is not a valid argument to key @@ -862,7 +858,7 @@ enum Tag { * attestation. It is used in attestations produced by the IIdentityCredential HAL when that * HAL attests to Credential Keys. IIdentityCredential produces KeyMint-style attestations. */ - IDENTITY_CREDENTIAL_KEY = (7 << 28) /* TagType:BOOL */ | 721, + IDENTITY_CREDENTIAL_KEY = TagType.BOOL | 721, /** * To prevent keys from being compromised if an attacker acquires read access to system / kernel @@ -880,12 +876,12 @@ enum Tag { * ErrorCode::INVALID_OPERATION is returned when a key with Tag::STORAGE_KEY is provided to * begin(). */ - STORAGE_KEY = (7 << 28) /* TagType:BOOL */ | 722, + STORAGE_KEY = TagType.BOOL | 722, /** * TODO: Delete when keystore1 is deleted. */ - ASSOCIATED_DATA = (9 << 28) /* TagType:BYTES */ | 1000, + ASSOCIATED_DATA = TagType.BYTES | 1000, /** * Tag::NONCE is used to provide or return a nonce or Initialization Vector (IV) for AES-GCM, @@ -900,7 +896,7 @@ enum Tag { * * Must never appear in KeyCharacteristics. */ - NONCE = (9 << 28) /* TagType:BYTES */ | 1001, + NONCE = TagType.BYTES | 1001, /** * Tag::MAC_LENGTH provides the requested length of a MAC or GCM authentication tag, in bits. @@ -911,7 +907,7 @@ enum Tag { * * Must never appear in KeyCharacteristics. */ - MAC_LENGTH = (3 << 28) /* TagType:UINT */ | 1003, + MAC_LENGTH = TagType.UINT | 1003, /** * Tag::RESET_SINCE_ID_ROTATION specifies whether the device has been factory reset since the @@ -919,7 +915,7 @@ enum Tag { * * Must never appear in KeyCharacteristics. */ - RESET_SINCE_ID_ROTATION = (7 << 28) /* TagType:BOOL */ | 1004, + RESET_SINCE_ID_ROTATION = TagType.BOOL | 1004, /** * OBSOLETE: Do not use. See the authToken parameter for IKeyMintDevice::begin and for @@ -927,7 +923,7 @@ enum Tag { * * TODO(b/191738660): Delete when keystore1 is deleted. */ - CONFIRMATION_TOKEN = (9 << 28) /* TagType:BYTES */ | 1005, + CONFIRMATION_TOKEN = TagType.BYTES | 1005, /** * Tag::CERTIFICATE_SERIAL specifies the serial number to be assigned to the attestation @@ -935,7 +931,7 @@ enum Tag { * keyMint in the attestation parameters during generateKey() and importKey(). If not provided, * the serial shall default to 1. */ - CERTIFICATE_SERIAL = (8 << 28) /* TagType:BIGNUM */ | 1006, + CERTIFICATE_SERIAL = TagType.BIGNUM | 1006, /** * Tag::CERTIFICATE_SUBJECT the certificate subject. The value is a DER encoded X509 NAME. @@ -943,7 +939,7 @@ enum Tag { * during generateKey and importKey. If not provided the subject name shall default to * CN="Android Keystore Key". */ - CERTIFICATE_SUBJECT = (9 << 28) /* TagType:BYTES */ | 1007, + CERTIFICATE_SUBJECT = TagType.BYTES | 1007, /** * Tag::CERTIFICATE_NOT_BEFORE the beginning of the validity of the certificate in UNIX epoch @@ -951,7 +947,7 @@ enum Tag { * certificates. ErrorCode::MISSING_NOT_BEFORE must be returned if this tag is not provided if * this tag is not provided to generateKey or importKey. */ - CERTIFICATE_NOT_BEFORE = (6 << 28) /* TagType:DATE */ | 1008, + CERTIFICATE_NOT_BEFORE = TagType.DATE | 1008, /** * Tag::CERTIFICATE_NOT_AFTER the end of the validity of the certificate in UNIX epoch time in @@ -959,7 +955,7 @@ enum Tag { * ErrorCode::MISSING_NOT_AFTER must be returned if this tag is not provided to generateKey or * importKey. */ - CERTIFICATE_NOT_AFTER = (6 << 28) /* TagType:DATE */ | 1009, + CERTIFICATE_NOT_AFTER = TagType.DATE | 1009, /** * Tag::MAX_BOOT_LEVEL specifies a maximum boot level at which a key should function. @@ -970,5 +966,5 @@ enum Tag { * * Cannot be hardware enforced in this version. */ - MAX_BOOT_LEVEL = (3 << 28) /* TagType:UINT */ | 1010, + MAX_BOOT_LEVEL = TagType.UINT | 1010, } -- GitLab From 17587b018339160071ca601db32e283dfe7d7abf Mon Sep 17 00:00:00 2001 From: Seth Moore Date: Fri, 2 Jul 2021 15:38:17 -0700 Subject: [PATCH 749/790] Add test ensuring that BCC keys not unique ids Get two test BCCs, then ensure that no repeated keys are found. Ignore-AOSP-First: No merge path to AOSP, will manually port. Bug: 192687735 Test: VtsHalRemotelyProvisionedComponentTargetTest Change-Id: I48f86e7dfa9ab4bc6303a8d1b64ac7ca6ac76bbf --- .../VtsRemotelyProvisionedComponentTests.cpp | 50 ++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp index 78f8f08637..32765ad460 100644 --- a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp +++ b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include "KeyMintAidlTestBase.h" @@ -297,7 +298,8 @@ class CertificateRequestTest : public VtsRemotelyProvisionedComponentTests { } void checkProtectedData(const DeviceInfo& deviceInfo, const cppbor::Array& keysToSign, - const bytevec& keysToSignMac, const ProtectedData& protectedData) { + const bytevec& keysToSignMac, const ProtectedData& protectedData, + std::vector* bccOutput = nullptr) { auto [parsedProtectedData, _, protDataErrMsg] = cppbor::parse(protectedData.protectedData); ASSERT_TRUE(parsedProtectedData) << protDataErrMsg; ASSERT_TRUE(parsedProtectedData->asArray()); @@ -354,6 +356,10 @@ class CertificateRequestTest : public VtsRemotelyProvisionedComponentTests { auto macPayload = verifyAndParseCoseMac0(&coseMac0, *macKey); ASSERT_TRUE(macPayload) << macPayload.message(); + + if (bccOutput) { + *bccOutput = std::move(*bccContents); + } } bytevec eekId_; @@ -386,6 +392,48 @@ TEST_P(CertificateRequestTest, EmptyRequest_testMode) { } } +/** + * Ensure that test mode outputs a unique BCC root key every time we request a + * certificate request. Else, it's possible that the test mode API could be used + * to fingerprint devices. Only the GEEK should be allowed to decrypt the same + * device public key multiple times. + */ +TEST_P(CertificateRequestTest, NewKeyPerCallInTestMode) { + constexpr bool testMode = true; + constexpr size_t eekLength = 2; + + generateEek(eekLength); + + bytevec keysToSignMac; + DeviceInfo deviceInfo; + ProtectedData protectedData; + auto status = provisionable_->generateCertificateRequest( + testMode, {} /* keysToSign */, eekChain_.chain, challenge_, &deviceInfo, &protectedData, + &keysToSignMac); + ASSERT_TRUE(status.isOk()) << status.getMessage(); + + std::vector firstBcc; + checkProtectedData(deviceInfo, /*keysToSign=*/cppbor::Array(), keysToSignMac, protectedData, + &firstBcc); + + status = provisionable_->generateCertificateRequest(testMode, {} /* keysToSign */, + eekChain_.chain, challenge_, &deviceInfo, + &protectedData, &keysToSignMac); + ASSERT_TRUE(status.isOk()) << status.getMessage(); + + std::vector secondBcc; + checkProtectedData(deviceInfo, /*keysToSign=*/cppbor::Array(), keysToSignMac, protectedData, + &secondBcc); + + // Verify that none of the keys in the first BCC are repeated in the second one. + for (const auto& i : firstBcc) { + for (auto& j : secondBcc) { + ASSERT_THAT(i.pubKey, testing::Not(testing::ElementsAreArray(j.pubKey))) + << "Found a repeated pubkey in two generateCertificateRequest test mode calls"; + } + } +} + /** * Generate an empty certificate request in prod mode. Generation will fail because we don't have a * valid GEEK. -- GitLab From 3ed299dfcae89db2cc3e75f6e0a0efbb5a3910eb Mon Sep 17 00:00:00 2001 From: Shuzhen Wang Date: Fri, 23 Apr 2021 13:55:51 -0700 Subject: [PATCH 750/790] Camera: Add logical camera requirement test for GVF The test verifies that if more than one color camera is available for a particular facing, a logical mulit-camera must be supported consisting all color cameras facing that direction. Test: Run VTS test on Pixel4 and cuttlefish emulator Bug: 178633246 Change-Id: I7b02a4057064a7f4a236c1bbc49f768ac80232cf --- .../VtsHalCameraProviderV2_4TargetTest.cpp | 190 +++++++++++++++++- 1 file changed, 187 insertions(+), 3 deletions(-) diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp index 41a08f9843..49e00f4f4b 100644 --- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp +++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp @@ -230,10 +230,10 @@ namespace { return false; } - int getCameraDeviceVersion(const hidl_string& deviceName, - const hidl_string &providerType) { + int getCameraDeviceVersionAndId(const hidl_string& deviceName, + const hidl_string &providerType, std::string* id) { std::string version; - bool match = matchDeviceName(deviceName, providerType, &version, nullptr); + bool match = matchDeviceName(deviceName, providerType, &version, id); if (!match) { return -1; } @@ -256,6 +256,11 @@ namespace { return 0; } + int getCameraDeviceVersion(const hidl_string& deviceName, + const hidl_string &providerType) { + return getCameraDeviceVersionAndId(deviceName, providerType, nullptr); + } + bool parseProviderName(const std::string& name, std::string *type /*out*/, uint32_t *id /*out*/) { if (!type || !id) { @@ -930,6 +935,7 @@ public: camera_metadata_ro_entry* streamConfigs, camera_metadata_ro_entry* maxResolutionStreamConfigs, const camera_metadata_t* staticMetadata); + static bool isColorCamera(const camera_metadata_t *metadata); static V3_2::DataspaceFlags getDataspace(PixelFormat format); @@ -6179,6 +6185,167 @@ TEST_P(CameraHidlTest, configureInjectionStreamsWithSessionParameters) { } } +// Test the multi-camera API requirement for Google Requirement Freeze S +// Note that this requirement can only be partially tested. If a vendor +// device doesn't expose a physical camera in any shape or form, there is no way +// the test can catch it. +TEST_P(CameraHidlTest, grfSMultiCameraTest) { + const int socGrfApi = property_get_int32("ro.board.first_api_level", /*default*/ -1); + if (socGrfApi < 31 /*S*/) { + // Non-GRF devices, or version < 31 Skip + ALOGI("%s: socGrfApi level is %d. Skipping", __FUNCTION__, socGrfApi); + return; + } + + // Test that if more than one color cameras facing the same direction are + // supported, there must be at least one logical camera facing that + // direction. + hidl_vec cameraDeviceNames = getCameraDeviceNames(mProvider); + // Front and back facing non-logical color cameras + std::set frontColorCameras, rearColorCameras; + // Front and back facing logical cameras' physical camera Id sets + std::set> frontPhysicalIds, rearPhysicalIds; + for (const auto& name : cameraDeviceNames) { + std::string cameraId; + int deviceVersion = getCameraDeviceVersionAndId(name, mProviderType, &cameraId); + switch (deviceVersion) { + case CAMERA_DEVICE_API_VERSION_3_7: + case CAMERA_DEVICE_API_VERSION_3_6: + case CAMERA_DEVICE_API_VERSION_3_5: + case CAMERA_DEVICE_API_VERSION_3_4: + case CAMERA_DEVICE_API_VERSION_3_3: + case CAMERA_DEVICE_API_VERSION_3_2: { + ::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> device3_x; + ALOGI("getCameraCharacteristics: Testing camera device %s", name.c_str()); + Return ret; + ret = mProvider->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()); + + ret = device3_x->getCameraCharacteristics([&](auto status, const auto& chars) { + ASSERT_EQ(Status::OK, status); + const camera_metadata_t* metadata = (camera_metadata_t*)chars.data(); + + // Skip if this is not a color camera. + if (!CameraHidlTest::isColorCamera(metadata)) { + return; + } + + // Check camera facing. Skip if facing is neither FRONT + // nor BACK. If this is not a logical camera, only note down + // the camera ID, and skip. + camera_metadata_ro_entry entry; + int retcode = find_camera_metadata_ro_entry( + metadata, ANDROID_LENS_FACING, &entry); + ASSERT_EQ(retcode, 0); + ASSERT_GT(entry.count, 0); + uint8_t facing = entry.data.u8[0]; + bool isLogicalCamera = (isLogicalMultiCamera(metadata) == Status::OK); + if (facing == ANDROID_LENS_FACING_FRONT) { + if (!isLogicalCamera) { + frontColorCameras.insert(cameraId); + return; + } + } else if (facing == ANDROID_LENS_FACING_BACK) { + if (!isLogicalCamera) { + rearColorCameras.insert(cameraId); + return; + } + } else { + // Not FRONT or BACK facing. Skip. + return; + } + + // Check logical camera's physical camera IDs for color + // cameras. + std::unordered_set physicalCameraIds; + Status s = getPhysicalCameraIds(metadata, &physicalCameraIds); + ASSERT_EQ(Status::OK, s); + if (facing == ANDROID_LENS_FACING_FRONT) { + frontPhysicalIds.emplace(physicalCameraIds.begin(), physicalCameraIds.end()); + } else { + rearPhysicalIds.emplace(physicalCameraIds.begin(), physicalCameraIds.end()); + } + for (const auto& physicalId : physicalCameraIds) { + // Skip if the physicalId is publicly available + for (auto& deviceName : cameraDeviceNames) { + std::string publicVersion, publicId; + ASSERT_TRUE(::matchDeviceName(deviceName, mProviderType, + &publicVersion, &publicId)); + if (physicalId == publicId) { + // Skip because public Ids will be iterated in outer loop. + return; + } + } + + auto castResult = device::V3_5::ICameraDevice::castFrom(device3_x); + ASSERT_TRUE(castResult.isOk()); + ::android::sp<::android::hardware::camera::device::V3_5::ICameraDevice> + device3_5 = castResult; + ASSERT_NE(device3_5, nullptr); + + // Check camera characteristics for hidden camera id + Return ret = device3_5->getPhysicalCameraCharacteristics( + physicalId, [&](auto status, const auto& chars) { + ASSERT_EQ(Status::OK, status); + const camera_metadata_t* physicalMetadata = + (camera_metadata_t*)chars.data(); + + if (CameraHidlTest::isColorCamera(physicalMetadata)) { + if (facing == ANDROID_LENS_FACING_FRONT) { + frontColorCameras.insert(physicalId); + } else if (facing == ANDROID_LENS_FACING_BACK) { + rearColorCameras.insert(physicalId); + } + } + }); + ASSERT_TRUE(ret.isOk()); + } + }); + ASSERT_TRUE(ret.isOk()); + } break; + case CAMERA_DEVICE_API_VERSION_1_0: { + // Not applicable + } break; + default: { + ALOGE("%s: Unsupported device version %d", __func__, deviceVersion); + ADD_FAILURE(); + } break; + } + } + + // If there are more than one color cameras facing one direction, a logical + // multi-camera must be defined consisting of all color cameras facing that + // direction. + if (frontColorCameras.size() > 1) { + bool hasFrontLogical = false; + for (const auto& physicalIds : frontPhysicalIds) { + if (std::includes(physicalIds.begin(), physicalIds.end(), + frontColorCameras.begin(), frontColorCameras.end())) { + hasFrontLogical = true; + break; + } + } + ASSERT_TRUE(hasFrontLogical); + } + if (rearColorCameras.size() > 1) { + bool hasRearLogical = false; + for (const auto& physicalIds : rearPhysicalIds) { + if (std::includes(physicalIds.begin(), physicalIds.end(), + rearColorCameras.begin(), rearColorCameras.end())) { + hasRearLogical = true; + break; + } + } + ASSERT_TRUE(hasRearLogical); + } +} + // Retrieve all valid output stream resolutions from the camera // static characteristics. Status CameraHidlTest::getAvailableOutputStreams(const camera_metadata_t* staticMeta, @@ -6651,6 +6818,23 @@ Status CameraHidlTest::isMonochromeCamera(const camera_metadata_t *staticMeta) { return ret; } +bool CameraHidlTest::isColorCamera(const camera_metadata_t *metadata) { + camera_metadata_ro_entry entry; + int retcode = find_camera_metadata_ro_entry( + metadata, ANDROID_REQUEST_AVAILABLE_CAPABILITIES, &entry); + if ((0 == retcode) && (entry.count > 0)) { + bool isBackwardCompatible = (std::find(entry.data.u8, entry.data.u8 + entry.count, + ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE) != + entry.data.u8 + entry.count); + bool isMonochrome = (std::find(entry.data.u8, entry.data.u8 + entry.count, + ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME) != + entry.data.u8 + entry.count); + bool isColor = isBackwardCompatible && !isMonochrome; + return isColor; + } + return false; +} + // Retrieve the reprocess input-output format map from the static // camera characteristics. Status CameraHidlTest::getZSLInputOutputMap(camera_metadata_t *staticMeta, -- GitLab From f594fce5ddb008143f09de27a3a4d942cbb0bb05 Mon Sep 17 00:00:00 2001 From: Seth Moore Date: Thu, 24 Jun 2021 16:29:38 -0700 Subject: [PATCH 751/790] Add Attestation IDs State to DeviceInfo We will use the 'Attestation IDs State' field in DeviceInfo to determine whether a device is still provisionable or not. Once a production device has left the factory, certain attestated device ids should be fixed, and 'Attestation IDs State' should reflect this by reporting "locked". Remove stale, duplicated DeviceInfo description from ProtectedData.aidl Test: None, just a doc change Bug: 192017485 Change-Id: I4e0a840a8f415b3b410801805a158c46be30ec6a --- .../hardware/security/keymint/DeviceInfo.aidl | 6 ++++++ .../hardware/security/keymint/ProtectedData.aidl | 15 +-------------- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/security/keymint/aidl/android/hardware/security/keymint/DeviceInfo.aidl b/security/keymint/aidl/android/hardware/security/keymint/DeviceInfo.aidl index 32d69cd227..b0761bf828 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/DeviceInfo.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/DeviceInfo.aidl @@ -44,6 +44,12 @@ parcelable DeviceInfo { * ? "vendor_patch_level" : uint, // YYYYMMDD * "version" : 1, // The CDDL schema version. * "security_level" : "tee" / "strongbox" + * "att_id_state": "locked" / "open", // Attestation IDs State. If "locked", this + * // indicates a device's attestable IDs are + * // factory-locked and immutable. If "open", + * // this indicates the device is still in a + * // provisionable state and the attestable IDs + * // are not yet frozen. * } */ byte[] deviceInfo; diff --git a/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl b/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl index 31dbb288ab..24cdbc1fa7 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl @@ -158,20 +158,7 @@ parcelable ProtectedData { * payload: bstr .cbor BccPayload * ] * - * VerifiedDeviceInfo = { - * ? "brand" : tstr, - * ? "manufacturer" : tstr, - * ? "product" : tstr, - * ? "model" : tstr, - * ? "board" : tstr, - * ? "device" : tstr, - * ? "vb_state" : "green" / "yellow" / "orange", - * ? "bootloader_state" : "locked" / "unlocked", - * ? "os_version" : tstr, - * ? "system_patch_level" : uint, // YYYYMMDD - * ? "boot_patch_level" : uint, // YYYYMMDD - * ? "vendor_patch_level" : uint, // YYYYMMDD - * } + * VerifiedDeviceInfo = DeviceInfo // See DeviceInfo.aidl * * PubKeyX25519 = { // COSE_Key * 1 : 1, // Key type : Octet Key Pair -- GitLab From 3e6c2ef9c8b7a59055a604ab50d0c527675d6f86 Mon Sep 17 00:00:00 2001 From: Eran Messeri Date: Tue, 6 Jul 2021 12:07:57 +0100 Subject: [PATCH 752/790] KeyMint: Fix device-unique attestation chain specification Fix the device-unique attestation chain specification: The chain should have two or three certificates. In case of two certificates, the device-unique key should be used for the self-signed root. In case of three certificates, the device-unique key should be certified by another key (ideally shared by all StrongBox instances from the same manufacturer, to ease validation). Adjust the device-unique attestation tests to accept two or three certificates in the chain. Additionally, the current StrongBox KeyMint implementation can not yet generate fully-valid chains (with matching subjects and issuers), so relax that check. Bug: 191361618 Test: m VtsAidlKeyMintTargetTest Merged-In: I6e6bca33ebb4af67cac8e41a39e9c305d0f1345f Change-Id: Iebefafe72148c919d10308eff7a19fc1bc40c619 --- .../android/hardware/security/keymint/Tag.aidl | 16 +++++++++++++--- .../functional/DeviceUniqueAttestationTest.cpp | 13 +++++++++---- .../aidl/vts/functional/KeyMintAidlTestBase.cpp | 5 +++-- .../aidl/vts/functional/KeyMintAidlTestBase.h | 3 ++- 4 files changed, 27 insertions(+), 10 deletions(-) diff --git a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl index 270574bbfb..e5307fd812 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl @@ -833,11 +833,21 @@ enum Tag { /** * DEVICE_UNIQUE_ATTESTATION is an argument to IKeyMintDevice::attested key generation/import * operations. It indicates that attestation using a device-unique key is requested, rather - * than a batch key. When a device-unique key is used, the returned chain should contain two - * certificates: + * than a batch key. When a device-unique key is used, the returned chain contains two or + * three certificates. + * + * In case the chain contains two certificates, they should be: * * The attestation certificate, containing the attestation extension, as described in - KeyCreationResult.aidl. + * KeyCreationResult.aidl. * * A self-signed root certificate, signed by the device-unique key. + * + * In case the chain contains three certificates, they should be: + * * The attestation certificate, containing the attestation extension, as described in + * KeyCreationResult.aidl, signed by the device-unique key. + * * An intermediate certificate, containing the public portion of the device-unique key. + * * A self-signed root certificate, signed by a dedicated key, certifying the + * intermediate. + * * No additional chained certificates are provided. Only SecurityLevel::STRONGBOX * IKeyMintDevices may support device-unique attestations. SecurityLevel::TRUSTED_ENVIRONMENT * IKeyMintDevices must return ErrorCode::INVALID_ARGUMENT if they receive diff --git a/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp b/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp index a3ed3ad4a0..d7abf0790c 100644 --- a/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp +++ b/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp @@ -40,11 +40,16 @@ class DeviceUniqueAttestationTest : public KeyMintAidlTestBase { AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics); - // The device-unique attestation chain should contain exactly two certificates: + // The device-unique attestation chain should contain exactly three certificates: // * The leaf with the attestation extension. - // * A self-signed root, signed using the device-unique key. - ASSERT_EQ(cert_chain_.size(), 2); - EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_)); + // * An intermediate, signing the leaf using the device-unique key. + // * A self-signed root, signed using some authority's key, certifying + // the device-unique key. + const size_t chain_length = cert_chain_.size(); + ASSERT_TRUE(chain_length == 2 || chain_length == 3); + // TODO(b/191361618): Once StrongBox implementations use a correctly-issued + // certificate chain, do not skip issuers matching. + EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_, /* strict_issuer_check= */ false)); AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics); EXPECT_TRUE(verify_attestation_record("challenge", "foo", sw_enforced, hw_enforced, diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp index 5359b3b667..20324117b9 100644 --- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp +++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp @@ -1493,7 +1493,8 @@ AuthorizationSet SwEnforcedAuthorizations(const vector& key_ return authList; } -AssertionResult ChainSignaturesAreValid(const vector& chain) { +AssertionResult ChainSignaturesAreValid(const vector& chain, + bool strict_issuer_check) { std::stringstream cert_data; for (size_t i = 0; i < chain.size(); ++i) { @@ -1520,7 +1521,7 @@ AssertionResult ChainSignaturesAreValid(const vector& chain) { string cert_issuer = x509NameToStr(X509_get_issuer_name(key_cert.get())); string signer_subj = x509NameToStr(X509_get_subject_name(signing_cert.get())); - if (cert_issuer != signer_subj) { + if (cert_issuer != signer_subj && strict_issuer_check) { return AssertionFailure() << "Cert " << i << " has wrong issuer.\n" << " Signer subject is " << signer_subj << " Issuer subject is " << cert_issuer << endl diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h index d592d3686b..ec3fcf6a3e 100644 --- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h +++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h @@ -349,7 +349,8 @@ void p256_pub_key(const vector& coseKeyData, EVP_PKEY_Ptr* signingKey); AuthorizationSet HwEnforcedAuthorizations(const vector& key_characteristics); AuthorizationSet SwEnforcedAuthorizations(const vector& key_characteristics); -::testing::AssertionResult ChainSignaturesAreValid(const vector& chain); +::testing::AssertionResult ChainSignaturesAreValid(const vector& chain, + bool strict_issuer_check = true); #define INSTANTIATE_KEYMINT_AIDL_TEST(name) \ INSTANTIATE_TEST_SUITE_P(PerInstance, name, \ -- GitLab From 7e643777e125a0caf655629c8d993390bdeb7aa4 Mon Sep 17 00:00:00 2001 From: Lais Andrade Date: Fri, 9 Jul 2021 14:59:44 +0100 Subject: [PATCH 753/790] Update vibrator VTS to only validate support from required primitives Bug: 193196353 Test: VtsHalVibratorTargetTest Change-Id: I7ec2f0d82290f42259f8383db9ff00a126a2a7a4 --- vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp index c56bd9a4d4..553d7f0a4a 100644 --- a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp +++ b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp @@ -60,9 +60,10 @@ const std::vector kCompositePrimitives{ android::enum_range().begin(), android::enum_range().end()}; -const std::vector kOptionalPrimitives = { - CompositePrimitive::THUD, - CompositePrimitive::SPIN, +const std::vector kRequiredPrimitives = { + CompositePrimitive::CLICK, CompositePrimitive::LIGHT_TICK, + CompositePrimitive::QUICK_RISE, CompositePrimitive::SLOW_RISE, + CompositePrimitive::QUICK_FALL, }; const std::vector kInvalidPrimitives = { @@ -393,11 +394,11 @@ TEST_P(VibratorAidl, GetSupportedPrimitives) { for (auto primitive : kCompositePrimitives) { bool isPrimitiveSupported = std::find(supported.begin(), supported.end(), primitive) != supported.end(); - bool isPrimitiveOptional = - std::find(kOptionalPrimitives.begin(), kOptionalPrimitives.end(), primitive) != - kOptionalPrimitives.end(); + bool isPrimitiveRequired = + std::find(kRequiredPrimitives.begin(), kRequiredPrimitives.end(), primitive) != + kRequiredPrimitives.end(); - EXPECT_TRUE(isPrimitiveSupported || isPrimitiveOptional) << toString(primitive); + EXPECT_TRUE(isPrimitiveSupported || !isPrimitiveRequired) << toString(primitive); } } } -- GitLab From 87eb1dd928dd8e4934f18dfe3a6f7c45fbe95424 Mon Sep 17 00:00:00 2001 From: Seth Moore Date: Wed, 23 Jun 2021 15:15:52 -0700 Subject: [PATCH 754/790] Update KeyMint VTS tests with prod GEEK Now that we have the production Google Endpoint Encryption Key, we can update the tests to use the correct GEEK cert chain where applicable. Ignore-AOSP-First: No merge path to aosp, will manually merge Test: VtsHalRemotelyProvisionedComponentTargetTest Test: VtsAidlKeyMintTargetTest Bug: 191301285 Change-Id: I84b557c6bad34741ffe6671fc941d9e266b73241 --- .../VtsRemotelyProvisionedComponentTests.cpp | 149 ++++++++---------- 1 file changed, 62 insertions(+), 87 deletions(-) diff --git a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp index 32765ad460..af951e8861 100644 --- a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp +++ b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp @@ -103,8 +103,8 @@ ErrMsgOr corrupt_sig(const cppbor::Array* coseSign1) { return std::move(corruptSig); } -ErrMsgOr corrupt_sig_chain(const EekChain& eek, int which) { - auto [chain, _, parseErr] = cppbor::parse(eek.chain); +ErrMsgOr corrupt_sig_chain(const bytevec& encodedEekChain, int which) { + auto [chain, _, parseErr] = cppbor::parse(encodedEekChain); if (!chain || !chain->asArray()) { return "EekChain parse failed"; } @@ -126,7 +126,7 @@ ErrMsgOr corrupt_sig_chain(const EekChain& eek, int which) { corruptChain.add(eekChain->get(ii)->clone()); } } - return EekChain{corruptChain.encode(), eek.last_pubkey, eek.last_privkey}; + return corruptChain.encode(); } string device_suffix(const string& name) { @@ -272,14 +272,14 @@ TEST_P(GenerateKeyTests, generateEcdsaP256Key_testMode) { class CertificateRequestTest : public VtsRemotelyProvisionedComponentTests { protected: CertificateRequestTest() : eekId_(string_to_bytevec("eekid")), challenge_(randomBytes(32)) { - generateEek(3); + generateTestEekChain(3); } - void generateEek(size_t eekLength) { + void generateTestEekChain(size_t eekLength) { auto chain = generateEekChain(eekLength, eekId_); EXPECT_TRUE(chain) << chain.message(); - if (chain) eekChain_ = chain.moveValue(); - eekLength_ = eekLength; + if (chain) testEekChain_ = chain.moveValue(); + testEekLength_ = eekLength; } void generateKeys(bool testMode, size_t numKeys) { @@ -309,8 +309,9 @@ class CertificateRequestTest : public VtsRemotelyProvisionedComponentTests { ASSERT_TRUE(senderPubkey) << senderPubkey.message(); EXPECT_EQ(senderPubkey->second, eekId_); - auto sessionKey = x25519_HKDF_DeriveKey(eekChain_.last_pubkey, eekChain_.last_privkey, - senderPubkey->first, false /* senderIsA */); + auto sessionKey = + x25519_HKDF_DeriveKey(testEekChain_.last_pubkey, testEekChain_.last_privkey, + senderPubkey->first, false /* senderIsA */); ASSERT_TRUE(sessionKey) << sessionKey.message(); auto protectedDataPayload = @@ -363,8 +364,8 @@ class CertificateRequestTest : public VtsRemotelyProvisionedComponentTests { } bytevec eekId_; - size_t eekLength_; - EekChain eekChain_; + size_t testEekLength_; + EekChain testEekChain_; bytevec challenge_; std::vector keysToSign_; cppbor::Array cborKeysToSign_; @@ -378,13 +379,13 @@ TEST_P(CertificateRequestTest, EmptyRequest_testMode) { bool testMode = true; for (size_t eekLength : {2, 3, 7}) { SCOPED_TRACE(testing::Message() << "EEK of length " << eekLength); - generateEek(eekLength); + generateTestEekChain(eekLength); bytevec keysToSignMac; DeviceInfo deviceInfo; ProtectedData protectedData; auto status = provisionable_->generateCertificateRequest( - testMode, {} /* keysToSign */, eekChain_.chain, challenge_, &deviceInfo, + testMode, {} /* keysToSign */, testEekChain_.chain, challenge_, &deviceInfo, &protectedData, &keysToSignMac); ASSERT_TRUE(status.isOk()) << status.getMessage(); @@ -400,25 +401,22 @@ TEST_P(CertificateRequestTest, EmptyRequest_testMode) { */ TEST_P(CertificateRequestTest, NewKeyPerCallInTestMode) { constexpr bool testMode = true; - constexpr size_t eekLength = 2; - - generateEek(eekLength); bytevec keysToSignMac; DeviceInfo deviceInfo; ProtectedData protectedData; auto status = provisionable_->generateCertificateRequest( - testMode, {} /* keysToSign */, eekChain_.chain, challenge_, &deviceInfo, &protectedData, - &keysToSignMac); + testMode, {} /* keysToSign */, testEekChain_.chain, challenge_, &deviceInfo, + &protectedData, &keysToSignMac); ASSERT_TRUE(status.isOk()) << status.getMessage(); std::vector firstBcc; checkProtectedData(deviceInfo, /*keysToSign=*/cppbor::Array(), keysToSignMac, protectedData, &firstBcc); - status = provisionable_->generateCertificateRequest(testMode, {} /* keysToSign */, - eekChain_.chain, challenge_, &deviceInfo, - &protectedData, &keysToSignMac); + status = provisionable_->generateCertificateRequest( + testMode, {} /* keysToSign */, testEekChain_.chain, challenge_, &deviceInfo, + &protectedData, &keysToSignMac); ASSERT_TRUE(status.isOk()) << status.getMessage(); std::vector secondBcc; @@ -435,28 +433,20 @@ TEST_P(CertificateRequestTest, NewKeyPerCallInTestMode) { } /** - * Generate an empty certificate request in prod mode. Generation will fail because we don't have a - * valid GEEK. - * - * TODO(swillden): Get a valid GEEK and use it so the generation can succeed, though we won't be - * able to decrypt. + * Generate an empty certificate request in prod mode. This test must be run explicitly, and + * is not run by default. Not all devices are GMS devices, and therefore they do not all + * trust the Google EEK root. */ -TEST_P(CertificateRequestTest, EmptyRequest_prodMode) { +TEST_P(CertificateRequestTest, DISABLED_EmptyRequest_prodMode) { bool testMode = false; - for (size_t eekLength : {2, 3, 7}) { - SCOPED_TRACE(testing::Message() << "EEK of length " << eekLength); - generateEek(eekLength); - bytevec keysToSignMac; - DeviceInfo deviceInfo; - ProtectedData protectedData; - auto status = provisionable_->generateCertificateRequest( - testMode, {} /* keysToSign */, eekChain_.chain, challenge_, &deviceInfo, - &protectedData, &keysToSignMac); - EXPECT_FALSE(status.isOk()); - EXPECT_EQ(status.getServiceSpecificError(), - BnRemotelyProvisionedComponent::STATUS_INVALID_EEK); - } + bytevec keysToSignMac; + DeviceInfo deviceInfo; + ProtectedData protectedData; + auto status = provisionable_->generateCertificateRequest( + testMode, {} /* keysToSign */, getProdEekChain(), challenge_, &deviceInfo, + &protectedData, &keysToSignMac); + EXPECT_TRUE(status.isOk()); } /** @@ -468,13 +458,13 @@ TEST_P(CertificateRequestTest, NonEmptyRequest_testMode) { for (size_t eekLength : {2, 3, 7}) { SCOPED_TRACE(testing::Message() << "EEK of length " << eekLength); - generateEek(eekLength); + generateTestEekChain(eekLength); bytevec keysToSignMac; DeviceInfo deviceInfo; ProtectedData protectedData; auto status = provisionable_->generateCertificateRequest( - testMode, keysToSign_, eekChain_.chain, challenge_, &deviceInfo, &protectedData, + testMode, keysToSign_, testEekChain_.chain, challenge_, &deviceInfo, &protectedData, &keysToSignMac); ASSERT_TRUE(status.isOk()) << status.getMessage(); @@ -483,30 +473,21 @@ TEST_P(CertificateRequestTest, NonEmptyRequest_testMode) { } /** - * Generate a non-empty certificate request in prod mode. Must fail because we don't have a valid - * GEEK. - * - * TODO(swillden): Get a valid GEEK and use it so the generation can succeed, though we won't be - * able to decrypt. + * Generate a non-empty certificate request in prod mode. This test must be run explicitly, and + * is not run by default. Not all devices are GMS devices, and therefore they do not all + * trust the Google EEK root. */ -TEST_P(CertificateRequestTest, NonEmptyRequest_prodMode) { +TEST_P(CertificateRequestTest, DISABLED_NonEmptyRequest_prodMode) { bool testMode = false; generateKeys(testMode, 4 /* numKeys */); - for (size_t eekLength : {2, 3, 7}) { - SCOPED_TRACE(testing::Message() << "EEK of length " << eekLength); - generateEek(eekLength); - - bytevec keysToSignMac; - DeviceInfo deviceInfo; - ProtectedData protectedData; - auto status = provisionable_->generateCertificateRequest( - testMode, keysToSign_, eekChain_.chain, challenge_, &deviceInfo, &protectedData, - &keysToSignMac); - EXPECT_FALSE(status.isOk()); - EXPECT_EQ(status.getServiceSpecificError(), - BnRemotelyProvisionedComponent::STATUS_INVALID_EEK); - } + bytevec keysToSignMac; + DeviceInfo deviceInfo; + ProtectedData protectedData; + auto status = provisionable_->generateCertificateRequest( + testMode, keysToSign_, getProdEekChain(), challenge_, &deviceInfo, &protectedData, + &keysToSignMac); + EXPECT_TRUE(status.isOk()); } /** @@ -521,8 +502,8 @@ TEST_P(CertificateRequestTest, NonEmptyRequestCorruptMac_testMode) { DeviceInfo deviceInfo; ProtectedData protectedData; auto status = provisionable_->generateCertificateRequest( - testMode, {keyWithCorruptMac}, eekChain_.chain, challenge_, &deviceInfo, &protectedData, - &keysToSignMac); + testMode, {keyWithCorruptMac}, testEekChain_.chain, challenge_, &deviceInfo, + &protectedData, &keysToSignMac); ASSERT_FALSE(status.isOk()) << status.getMessage(); EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_INVALID_MAC); } @@ -531,7 +512,7 @@ TEST_P(CertificateRequestTest, NonEmptyRequestCorruptMac_testMode) { * Generate a non-empty certificate request in prod mode, but with the MAC corrupted on the keypair. */ TEST_P(CertificateRequestTest, NonEmptyRequestCorruptMac_prodMode) { - bool testMode = true; + bool testMode = false; generateKeys(testMode, 1 /* numKeys */); MacedPublicKey keyWithCorruptMac = corrupt_maced_key(keysToSign_[0]).moveValue(); @@ -539,38 +520,35 @@ TEST_P(CertificateRequestTest, NonEmptyRequestCorruptMac_prodMode) { DeviceInfo deviceInfo; ProtectedData protectedData; auto status = provisionable_->generateCertificateRequest( - testMode, {keyWithCorruptMac}, eekChain_.chain, challenge_, &deviceInfo, &protectedData, - &keysToSignMac); + testMode, {keyWithCorruptMac}, getProdEekChain(), challenge_, &deviceInfo, + &protectedData, &keysToSignMac); ASSERT_FALSE(status.isOk()) << status.getMessage(); - auto rc = status.getServiceSpecificError(); - - // TODO(drysdale): drop the INVALID_EEK potential error code when a real GEEK is available. - EXPECT_TRUE(rc == BnRemotelyProvisionedComponent::STATUS_INVALID_EEK || - rc == BnRemotelyProvisionedComponent::STATUS_INVALID_MAC); + EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_INVALID_MAC); } /** * Generate a non-empty certificate request in prod mode that has a corrupt EEK chain. * Confirm that the request is rejected. - * - * TODO(drysdale): Update to use a valid GEEK, so that the test actually confirms that the - * implementation is checking signatures. */ TEST_P(CertificateRequestTest, NonEmptyCorruptEekRequest_prodMode) { bool testMode = false; generateKeys(testMode, 4 /* numKeys */); - for (size_t ii = 0; ii < eekLength_; ii++) { - auto chain = corrupt_sig_chain(eekChain_, ii); + auto prodEekChain = getProdEekChain(); + auto [parsedChain, _, parseErr] = cppbor::parse(prodEekChain); + ASSERT_NE(parsedChain, nullptr) << parseErr; + ASSERT_NE(parsedChain->asArray(), nullptr); + + for (int ii = 0; ii < parsedChain->asArray()->size(); ++ii) { + auto chain = corrupt_sig_chain(prodEekChain, ii); ASSERT_TRUE(chain) << chain.message(); - EekChain corruptEek = chain.moveValue(); bytevec keysToSignMac; DeviceInfo deviceInfo; ProtectedData protectedData; - auto status = provisionable_->generateCertificateRequest( - testMode, keysToSign_, corruptEek.chain, challenge_, &deviceInfo, &protectedData, - &keysToSignMac); + auto status = provisionable_->generateCertificateRequest(testMode, keysToSign_, *chain, + challenge_, &deviceInfo, + &protectedData, &keysToSignMac); ASSERT_FALSE(status.isOk()); ASSERT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_INVALID_EEK); @@ -580,9 +558,6 @@ TEST_P(CertificateRequestTest, NonEmptyCorruptEekRequest_prodMode) { /** * Generate a non-empty certificate request in prod mode that has an incomplete EEK chain. * Confirm that the request is rejected. - * - * TODO(drysdale): Update to use a valid GEEK, so that the test actually confirms that the - * implementation is checking signatures. */ TEST_P(CertificateRequestTest, NonEmptyIncompleteEekRequest_prodMode) { bool testMode = false; @@ -590,7 +565,7 @@ TEST_P(CertificateRequestTest, NonEmptyIncompleteEekRequest_prodMode) { // Build an EEK chain that omits the first self-signed cert. auto truncatedChain = cppbor::Array(); - auto [chain, _, parseErr] = cppbor::parse(eekChain_.chain); + auto [chain, _, parseErr] = cppbor::parse(getProdEekChain()); ASSERT_TRUE(chain); auto eekChain = chain->asArray(); ASSERT_NE(eekChain, nullptr); @@ -619,7 +594,7 @@ TEST_P(CertificateRequestTest, NonEmptyRequest_prodKeyInTestCert) { DeviceInfo deviceInfo; ProtectedData protectedData; auto status = provisionable_->generateCertificateRequest( - true /* testMode */, keysToSign_, eekChain_.chain, challenge_, &deviceInfo, + true /* testMode */, keysToSign_, testEekChain_.chain, challenge_, &deviceInfo, &protectedData, &keysToSignMac); ASSERT_FALSE(status.isOk()); ASSERT_EQ(status.getServiceSpecificError(), @@ -637,7 +612,7 @@ TEST_P(CertificateRequestTest, NonEmptyRequest_testKeyInProdCert) { DeviceInfo deviceInfo; ProtectedData protectedData; auto status = provisionable_->generateCertificateRequest( - false /* testMode */, keysToSign_, eekChain_.chain, challenge_, &deviceInfo, + false /* testMode */, keysToSign_, testEekChain_.chain, challenge_, &deviceInfo, &protectedData, &keysToSignMac); ASSERT_FALSE(status.isOk()); ASSERT_EQ(status.getServiceSpecificError(), -- GitLab From b1bd1e8a3253242a164ce80476452027bc0da2eb Mon Sep 17 00:00:00 2001 From: Alec Mouri Date: Fri, 9 Jul 2021 11:15:18 -0700 Subject: [PATCH 755/790] Clear composition changes when a color mode is not supported Otherwise this may cause a test to spuriously fail during teardown. Bug: 184726169 Test: VtsHalGraphicsComposerV2_2TargetTest Change-Id: I569680a0fe6c866199ba0711e8cc263b9b3efd58 --- .../vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp index 7a1568bd9f..7a053f1eb7 100644 --- a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp +++ b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp @@ -458,6 +458,7 @@ TEST_P(GraphicsCompositionTest, ClientComposition) { << " pixel format: PixelFormat::RGBA_8888 dataspace: " << ReadbackHelper::getDataspaceString(clientDataspace) << " unsupported for display" << std::endl; + mReader->mCompositionChanges.clear(); continue; } -- GitLab From c905ea66d41b9418a73cbaf860b7ea6661313f59 Mon Sep 17 00:00:00 2001 From: xshu Date: Sun, 11 Jul 2021 19:57:02 -0700 Subject: [PATCH 756/790] Clear ringbuffer after dumping to file Clear the in-memory ringbuffer after writing to file. Bug: 193007899 Test: Manually verified ringbuffers are cleared with command "adb shell lshal debug android.hardware.wifi@1.5::IWifi" Change-Id: Icfa08634e948d7155e231458edd394a4d699fbaa --- wifi/1.5/default/ringbuffer.cpp | 5 +++++ wifi/1.5/default/ringbuffer.h | 1 + wifi/1.5/default/wifi_chip.cpp | 5 +++-- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/wifi/1.5/default/ringbuffer.cpp b/wifi/1.5/default/ringbuffer.cpp index 26971ff25b..f554111e61 100644 --- a/wifi/1.5/default/ringbuffer.cpp +++ b/wifi/1.5/default/ringbuffer.cpp @@ -47,6 +47,11 @@ const std::list>& Ringbuffer::getData() const { return data_; } +void Ringbuffer::clear() { + data_.clear(); + size_ = 0; +} + } // namespace implementation } // namespace V1_5 } // namespace wifi diff --git a/wifi/1.5/default/ringbuffer.h b/wifi/1.5/default/ringbuffer.h index d8b87f2171..03fb37a6a2 100644 --- a/wifi/1.5/default/ringbuffer.h +++ b/wifi/1.5/default/ringbuffer.h @@ -37,6 +37,7 @@ class Ringbuffer { // within |maxSize_|. void append(const std::vector& input); const std::list>& getData() const; + void clear(); private: std::list> data_; diff --git a/wifi/1.5/default/wifi_chip.cpp b/wifi/1.5/default/wifi_chip.cpp index 961f9da4c2..024747af43 100644 --- a/wifi/1.5/default/wifi_chip.cpp +++ b/wifi/1.5/default/wifi_chip.cpp @@ -1940,8 +1940,8 @@ bool WifiChip::writeRingbufferFilesInternal() { // write ringbuffers to file { std::unique_lock lk(lock_t); - for (const auto& item : ringbuffer_map_) { - const Ringbuffer& cur_buffer = item.second; + for (auto& item : ringbuffer_map_) { + Ringbuffer& cur_buffer = item.second; if (cur_buffer.getData().empty()) { continue; } @@ -1959,6 +1959,7 @@ bool WifiChip::writeRingbufferFilesInternal() { PLOG(ERROR) << "Error writing to file"; } } + cur_buffer.clear(); } // unique_lock unlocked here } -- GitLab From 3dbdaa9717149eaf4f4be86443c78a3c1e72ac32 Mon Sep 17 00:00:00 2001 From: Seth Moore Date: Mon, 12 Jul 2021 14:18:28 -0700 Subject: [PATCH 757/790] Don't fail if TAG_ALLOW_WHILE_ON_BODY is missing The TAG_ALLOW_WHILE_ON_BODY authorization is not required to be supported, and if it is not supported it's a noop. Don't expect the tag to fail with UNSUPPORTED_TAG on devices that don't support it. Test: VtsAidlKeyMintTargetTest Bug: 192222727 Change-Id: I2e80ca59151e79f595a65cae94ac966b4ba7020d --- security/keymint/aidl/vts/functional/KeyMintTest.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp index d41d270764..5a87b83854 100644 --- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp +++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp @@ -1487,9 +1487,8 @@ TEST_P(NewKeyGenerationTest, EcdsaAttestationTags) { tag.tag == TAG_ROLLBACK_RESISTANCE) { continue; } - if (result == ErrorCode::UNSUPPORTED_TAG && - (tag.tag == TAG_ALLOW_WHILE_ON_BODY || tag.tag == TAG_TRUSTED_USER_PRESENCE_REQUIRED)) { - // Optional tag not supported by this KeyMint implementation. + if (result == ErrorCode::UNSUPPORTED_TAG && tag.tag == TAG_TRUSTED_USER_PRESENCE_REQUIRED) { + // Tag not required to be supported by all KeyMint implementations. continue; } ASSERT_EQ(result, ErrorCode::OK); @@ -1501,9 +1500,8 @@ TEST_P(NewKeyGenerationTest, EcdsaAttestationTags) { AuthorizationSet hw_enforced = HwEnforcedAuthorizations(key_characteristics); AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics); - if (tag.tag != TAG_ATTESTATION_APPLICATION_ID) { - // Expect to find most of the extra tags in the key characteristics - // of the generated key (but not for ATTESTATION_APPLICATION_ID). + // Some tags are optional, so don't require them to be in the enforcements. + if (tag.tag != TAG_ATTESTATION_APPLICATION_ID && tag.tag != TAG_ALLOW_WHILE_ON_BODY) { EXPECT_TRUE(hw_enforced.Contains(tag.tag) || sw_enforced.Contains(tag.tag)) << tag << " not in hw:" << hw_enforced << " nor sw:" << sw_enforced; } -- GitLab From 36f01d9083d71b70b021032adce9ac711cbd14eb Mon Sep 17 00:00:00 2001 From: Jayant Chowdhary Date: Mon, 12 Jul 2021 09:42:53 -0700 Subject: [PATCH 758/790] camera: Clarify that ANDROID_JPEG_MAX_SIZE applies to default sensor pixel mode. Bug: 193346383 Test: builds Change-Id: I451e4a8da7598f878f8fa5024e6bda5d8dbb1868 Signed-off-by: Jayant Chowdhary --- camera/metadata/3.2/types.hal | 4 +++- current.txt | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/camera/metadata/3.2/types.hal b/camera/metadata/3.2/types.hal index ad671d9db4..4b02830402 100644 --- a/camera/metadata/3.2/types.hal +++ b/camera/metadata/3.2/types.hal @@ -686,7 +686,9 @@ enum CameraMetadataTag : uint32_t { /** android.jpeg.maxSize [static, int32, system] * *

    Maximum size in bytes for the compressed - * JPEG buffer

    + * JPEG buffer, in default sensor pixel mode (see ANDROID_SENSOR_PIXEL_MODE)

    + * + * @see ANDROID_SENSOR_PIXEL_MODE */ ANDROID_JPEG_MAX_SIZE, diff --git a/current.txt b/current.txt index 908ecc4ed2..2307c14b98 100644 --- a/current.txt +++ b/current.txt @@ -768,6 +768,8 @@ a64467bae843569f0d465c5be7f0c7a5b987985b55a3ef4794dd5afc68538650 android.hardwar 98592d193a717066facf91428426e5abe211e3bd718bc372e29fb944ddbe6e7c android.hardware.wifi.supplicant@1.3::types # ABI preserving changes to HALs during Android S +# b/193346383 +93d29fbe2fcc5e4e053a9db7c9abbd9190c46b85b443f2698a3460db2ee76c8d android.hardware.camera.metadata@3.2::types 159a0069336035852e9eca6354b86b7990680d1b239f23ef2f631b01807c4cb9 android.hardware.camera.metadata@3.5::types e042522daa4b5f7fd4a0a19bcdadb93c79a1b04c09ef2c9813a3a8941032f3f5 android.hardware.contexthub@1.0::IContexthub c2f64133b83ede65c9939ef97ab5bd867b73faf3dba0e7e69f77c3c43d9e487e android.hardware.contexthub@1.0::IContexthubCallback -- GitLab From 1c93999d3d6b6929aa1c812219c5df9925db1474 Mon Sep 17 00:00:00 2001 From: David Drysdale Date: Wed, 14 Jul 2021 16:50:14 +0100 Subject: [PATCH 759/790] KeyMaster 4.0 VTS: fix GSI detection Commit f18a8328a1ed ("keymaster: Relax testing under GSI") disabled some tag checks for devices running with GSI, but detected GSI by looking for an absence of the ro.boot.vbmeta.device_state property. This property is currently present on GSI, so instead detect GSI using the existing is_gsi() helper, which checks ro.product.system.name against "mainline". Bug: 192513934 Test: atest VtsHalKeymasterV4_0TargetTest:PerInstance/AttestationTest Change-Id: If3c7d84a9e091b9b0842e4d8919453600bc239ea Ignore-AOSP-First: manual merge to aosp/master to follow --- keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 01c502c586..476eed8b19 100644 --- a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp +++ b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp @@ -438,7 +438,7 @@ bool verify_attestation_record(const string& challenge, const string& app_id, // TODO(b/136282179): When running under VTS-on-GSI the TEE-backed // keymaster implementation will report YYYYMM dates instead of YYYYMMDD // for the BOOT_PATCH_LEVEL. - if (avb_verification_enabled()) { + if (!is_gsi()) { for (int i = 0; i < att_hw_enforced.size(); i++) { if (att_hw_enforced[i].tag == TAG_BOOT_PATCHLEVEL || att_hw_enforced[i].tag == TAG_VENDOR_PATCHLEVEL) { -- GitLab From eeac52c8f1da95cc6ed1e046c0f5ba7f04a194e0 Mon Sep 17 00:00:00 2001 From: Kalesh Singh Date: Tue, 13 Jul 2021 01:45:41 +0000 Subject: [PATCH 760/790] Memtrack HAL: Report global total GPU-private memory Update memtrack hal documentation to allow reporting the global total GPU-private memory from the getMemory() API. Specify how to handle unsupported memtrack operations. Bug: 193226716 Bug: 193465681 Bug: 192621117 Test: N/A Change-Id: I6fcebd16fafdc34cc662137784e86750ee907eee --- memtrack/aidl/android/hardware/memtrack/IMemtrack.aidl | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/memtrack/aidl/android/hardware/memtrack/IMemtrack.aidl b/memtrack/aidl/android/hardware/memtrack/IMemtrack.aidl index 13c3389730..88b090b68e 100644 --- a/memtrack/aidl/android/hardware/memtrack/IMemtrack.aidl +++ b/memtrack/aidl/android/hardware/memtrack/IMemtrack.aidl @@ -44,6 +44,12 @@ import android.hardware.memtrack.MemtrackType; * This category should report all GPU private allocations for the specified * PID that are not accounted in /proc//smaps. * + * getMemory() called with PID 0 should report the global total GPU-private + * memory, for MemtrackType::GL and MemtrackRecord::FLAG_SMAPS_UNACCOUNTED. + * + * getMemory() called with PID 0 for a MemtrackType other than GL should + * report 0. + * * - MemtrackType::OTHER and MemtrackRecord::FLAG_SMAPS_UNACCOUNTED * Any other memory not accounted for in /proc//smaps if any, otherwise * this should return 0. @@ -52,6 +58,9 @@ import android.hardware.memtrack.MemtrackType; * VM_PFNMAP flag set. For these mappings PSS and RSS are reported as 0 in smaps. * Such mappings have no backing page structs from which PSS/RSS can be calculated. * + * Any memtrack operation that is not supported should return a binder status with + * exception code EX_UNSUPPORTED_OPERATION. + * * Constructor for the interface should be used to perform memtrack management * setup actions and must be called once before any calls to getMemory(). */ -- GitLab From 238fbcc61a393b672cf59db6a4d29ef476cd56d3 Mon Sep 17 00:00:00 2001 From: David Li Date: Mon, 19 Jul 2021 12:48:06 +0800 Subject: [PATCH 761/790] audio: make sure to set back to AudioMode::NORMAL after the test case If the major version is greater than or equal to 6, the test tries to set the mode to AudioMode::CALL_SCREEN. However, it doesn't set back to AudioMode::NORMAL. Replace all ASSERT with EXPECT to ensure the test can reach to the explicit call to reset to AudioMode::NORMAL. Bug: 194022995 Test: atest VtsHalAudioV7_0TargetTest Change-Id: Ib9b6e310965a85b016853b72c60716fa054641c6 --- .../functional/4.0/AudioPrimaryHidlHalTest.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp index b96cc83673..f8af0304ad 100644 --- a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp +++ b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp @@ -343,18 +343,21 @@ TEST_P(AudioPrimaryHidlTest, setMode) { #endif for (int mode : {-2, -1, maxMode + 1}) { - ASSERT_RESULT(Result::INVALID_ARGUMENTS, getDevice()->setMode(AudioMode(mode))) + EXPECT_RESULT(Result::INVALID_ARGUMENTS, getDevice()->setMode(AudioMode(mode))) << "mode=" << mode; } - // Test valid values - for (AudioMode mode : {AudioMode::IN_CALL, AudioMode::IN_COMMUNICATION, AudioMode::RINGTONE, - AudioMode::NORMAL /* Make sure to leave the test in normal mode */}) { - ASSERT_OK(getDevice()->setMode(mode)) << "mode=" << toString(mode); - } + // AudioMode::CALL_SCREEN as support is optional #if MAJOR_VERSION >= 6 - ASSERT_RESULT(okOrNotSupportedOrInvalidArgs, getDevice()->setMode(AudioMode::CALL_SCREEN)); + EXPECT_RESULT(okOrNotSupportedOrInvalidArgs, getDevice()->setMode(AudioMode::CALL_SCREEN)); #endif + // Test valid values + for (AudioMode mode : {AudioMode::IN_CALL, AudioMode::IN_COMMUNICATION, AudioMode::RINGTONE, + AudioMode::NORMAL}) { + EXPECT_OK(getDevice()->setMode(mode)) << "mode=" << toString(mode); + } + // Make sure to leave the test in normal mode + getDevice()->setMode(AudioMode::NORMAL); } TEST_P(AudioPrimaryHidlTest, setBtHfpSampleRate) { -- GitLab From 70082bb98384fadc8da979e60630bab9d2cf7250 Mon Sep 17 00:00:00 2001 From: Yu-Han Yang Date: Thu, 15 Jul 2021 14:07:37 -0700 Subject: [PATCH 762/790] Ensure non-empty SvInfo is received Bug: 193806881 Test: atest VtsHalGnssV2_1TargetTest Change-Id: I79f0c7041af51403ec5a2d17a430cac6d7a88b80 --- .../vts/functional/gnss_hal_test_cases.cpp | 35 +++++++++++-------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/gnss/2.1/vts/functional/gnss_hal_test_cases.cpp b/gnss/2.1/vts/functional/gnss_hal_test_cases.cpp index fcab8c4a04..8fa5f7e668 100644 --- a/gnss/2.1/vts/functional/gnss_hal_test_cases.cpp +++ b/gnss/2.1/vts/functional/gnss_hal_test_cases.cpp @@ -249,35 +249,40 @@ TEST_P(GnssHalTest, TestGnssAntennaInfo) { /* * TestGnssSvInfoFields: - * Gets 1 location and a GnssSvInfo, and verifies - * 1. basebandCN0DbHz is valid. + * Gets 1 location and a (non-empty) GnssSvInfo, and verifies basebandCN0DbHz is valid. */ TEST_P(GnssHalTest, TestGnssSvInfoFields) { gnss_cb_->location_cbq_.reset(); + gnss_cb_->sv_info_list_cbq_.reset(); StartAndCheckFirstLocation(/* min_interval_msec= */ 1000, /* low_power_mode= */ false); int location_called_count = gnss_cb_->location_cbq_.calledCount(); - - // Tolerate 1 less sv status to handle edge cases in reporting. - int sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size(); - EXPECT_GE(sv_info_list_cbq_size, 0); ALOGD("Observed %d GnssSvStatus, while awaiting one location (%d received)", - sv_info_list_cbq_size, location_called_count); - - // Get the last sv_info_list - std::list> sv_info_vec_list; - gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec_list, sv_info_list_cbq_size, 1); - hidl_vec last_sv_info_list = sv_info_vec_list.back(); - + gnss_cb_->sv_info_list_cbq_.size(), location_called_count); + + // Wait for up to kNumSvInfoLists events for kTimeoutSeconds for each event. + int kTimeoutSeconds = 2; + int kNumSvInfoLists = 4; + std::list> sv_info_lists; + hidl_vec last_sv_info_list; + + do { + EXPECT_GT(gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_lists, kNumSvInfoLists, + kTimeoutSeconds), + 0); + last_sv_info_list = sv_info_lists.back(); + } while (last_sv_info_list.size() == 0); + + ALOGD("last_sv_info size = %d", (int)last_sv_info_list.size()); bool nonZeroCn0Found = false; for (auto sv_info : last_sv_info_list) { - ASSERT_TRUE(sv_info.basebandCN0DbHz >= 0.0 && sv_info.basebandCN0DbHz <= 65.0); + EXPECT_TRUE(sv_info.basebandCN0DbHz >= 0.0 && sv_info.basebandCN0DbHz <= 65.0); if (sv_info.basebandCN0DbHz > 0.0) { nonZeroCn0Found = true; } } // Assert at least one value is non-zero. Zero is ok in status as it's possibly // reporting a searched but not found satellite. - ASSERT_TRUE(nonZeroCn0Found); + EXPECT_TRUE(nonZeroCn0Found); StopAndClearLocations(); } -- GitLab From e4ce86bfb7bd81eea39da5d76dbf796e2c1dbe1d Mon Sep 17 00:00:00 2001 From: Mikhail Naganov Date: Mon, 19 Jul 2021 22:58:02 +0000 Subject: [PATCH 763/790] Audio VTS: Make the active microphone query test more robust in V7 Prior to V7 the test which exercises IStreamIn.getActiveMicrophones was using a hardcoded configuration for the input stream. This configuration no longer works for some of new devices. To fix that, the part of the test which calls getActiveMicrophones has been moved into a separate test--a descendant of InputStreamTest which is parametrized using the actual configuration of the DUT. Tests for HAL versions prior to V7 are not affected because they don't use a full parser for the DUT config. Bug: 193849687 Test: atest VtsHalAudioV7_0TargetTest Change-Id: I00fe8fedb6bfc6e034387b35c88f954cb2638dfa --- .../4.0/AudioPrimaryHidlHalTest.cpp | 23 ++----- .../7.0/AudioPrimaryHidlHalTest.cpp | 61 +++++++++++++++++++ 2 files changed, 67 insertions(+), 17 deletions(-) diff --git a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp index b96cc83673..28bcd0b713 100644 --- a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp +++ b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp @@ -53,6 +53,11 @@ TEST_P(AudioHidlDeviceTest, GetMicrophonesTest) { GTEST_SKIP() << "getMicrophones is not supported"; // returns } ASSERT_OK(res); + +#if MAJOR_VERSION <= 6 + // In V7, 'getActiveMicrophones' is tested by the 'MicrophoneInfoInputStream' + // test which uses the actual configuration of the device. + if (microphones.size() > 0) { // When there is microphone on the phone, try to open an input stream // and query for the active microphones. @@ -60,30 +65,13 @@ TEST_P(AudioHidlDeviceTest, GetMicrophonesTest) { "Make sure getMicrophones always succeeds" "and getActiveMicrophones always succeeds when recording from these microphones."); AudioConfig config{}; -#if MAJOR_VERSION <= 6 config.channelMask = mkEnumBitfield(AudioChannelMask::IN_MONO); config.sampleRateHz = 8000; config.format = AudioFormat::PCM_16_BIT; auto flags = hidl_bitfield(AudioInputFlag::NONE); const SinkMetadata initMetadata = {{{.source = AudioSource::MIC, .gain = 1}}}; -#elif MAJOR_VERSION >= 7 - config.base.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_IN_MONO); - config.base.sampleRateHz = 8000; - config.base.format = toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT); - hidl_vec flags; - const SinkMetadata initMetadata = { - {{.source = toString(xsd::AudioSource::AUDIO_SOURCE_MIC), - .gain = 1, - .tags = {}, - .channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_IN_MONO)}}}; -#endif for (auto microphone : microphones) { -#if MAJOR_VERSION <= 6 if (microphone.deviceAddress.device != AudioDevice::IN_BUILTIN_MIC) { -#elif MAJOR_VERSION >= 7 - if (xsd::stringToAudioDevice(microphone.deviceAddress.deviceType) != - xsd::AudioDevice::AUDIO_DEVICE_IN_BUILTIN_MIC) { -#endif continue; } sp stream; @@ -106,6 +94,7 @@ TEST_P(AudioHidlDeviceTest, GetMicrophonesTest) { EXPECT_NE(0U, activeMicrophones.size()); } } +#endif // MAJOR_VERSION <= 6 } TEST_P(AudioHidlDeviceTest, SetConnectedState) { diff --git a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp index 0b3098b872..0cc6a5b964 100644 --- a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp +++ b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp @@ -839,3 +839,64 @@ INSTANTIATE_TEST_CASE_P(PcmOnlyConfigInputStream, PcmOnlyConfigInputStreamTest, ::testing::ValuesIn(getInputDevicePcmOnlyConfigParameters()), &DeviceConfigParameterToString); GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(PcmOnlyConfigInputStreamTest); + +static const std::vector& getBuiltinMicConfigParameters() { + static const std::vector parameters = [] { + auto allParams = getInputDeviceConfigParameters(); + std::vector builtinMicParams; + std::copy_if(allParams.begin(), allParams.end(), std::back_inserter(builtinMicParams), + [](auto cfg) { + // The built in mic may participate in various scenarios: + // FAST, HW_HOTWORD, MMAP NOIRQ, which are indicated by flags. + // We are only interested in testing the simplest scenario w/o any flags. + if (!std::get(cfg).empty()) return false; + auto maybeSourceDevice = getCachedPolicyConfig().getSourceDeviceForMixPort( + std::get(std::get(cfg)), + std::get(cfg)); + return maybeSourceDevice.has_value() && + xsd::stringToAudioDevice(maybeSourceDevice.value().deviceType) == + xsd::AudioDevice::AUDIO_DEVICE_IN_BUILTIN_MIC; + }); + return builtinMicParams; + }(); + return parameters; +} + +class MicrophoneInfoInputStreamTest : public InputStreamTest {}; + +TEST_P(MicrophoneInfoInputStreamTest, GetActiveMicrophones) { + doc::test( + "Make sure getActiveMicrophones always succeeds when recording " + "from the built-in microphone."); + hidl_vec microphones; + ASSERT_OK(getDevice()->getMicrophones(returnIn(res, microphones))); + if (res == Result::NOT_SUPPORTED) { + GTEST_SKIP() << "getMicrophones is not supported"; // returns + } + ASSERT_OK(res); + + auto maybeSourceAddress = + getCachedPolicyConfig().getSourceDeviceForMixPort(getDeviceName(), getMixPortName()); + ASSERT_TRUE(maybeSourceAddress.has_value()) + << "No source device found for mix port " << getMixPortName() << " (module " + << getDeviceName() << ")"; + + for (auto microphone : microphones) { + if (microphone.deviceAddress == maybeSourceAddress.value()) { + StreamReader reader(stream.get(), stream->getBufferSize()); + ASSERT_TRUE(reader.start()); + reader.pause(); // This ensures that at least one read has happened. + EXPECT_FALSE(reader.hasError()); + + hidl_vec activeMicrophones; + ASSERT_OK(stream->getActiveMicrophones(returnIn(res, activeMicrophones))); + ASSERT_OK(res); + EXPECT_NE(0U, activeMicrophones.size()); + } + } +} + +INSTANTIATE_TEST_CASE_P(MicrophoneInfoInputStream, MicrophoneInfoInputStreamTest, + ::testing::ValuesIn(getBuiltinMicConfigParameters()), + &DeviceConfigParameterToString); +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MicrophoneInfoInputStreamTest); -- GitLab From 643a79417231ed837bea71571420204992e5b37e Mon Sep 17 00:00:00 2001 From: Seth Moore Date: Tue, 20 Jul 2021 15:44:01 -0700 Subject: [PATCH 764/790] Add VtsRemotelyProvisionedComponentTests config VtsHalRemotelyProvisionedComponentTargetTest was picking up the same config file (AndroidTest.xml) as VtsAidlKeyMintTargetTest. When atest or TF was used to run VtsHalRemotelyProvisionedComponentTargetTest, it actually ran VtsAidlKeyMintTargetTest. Add a separate test config file so that we run the correct test binary. Test: atest VtsAidlKeyMintTargetTest Test: atest VtsHalRemotelyProvisionedComponentTargetTest Fixes: 192824779 Change-Id: I7ba0f8d364690209722f9a06c6c0ce2957781beb --- .../keymint/aidl/vts/functional/Android.bp | 1 + .../VtsRemotelyProvisionedComponentTests.xml | 34 +++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.xml diff --git a/security/keymint/aidl/vts/functional/Android.bp b/security/keymint/aidl/vts/functional/Android.bp index 386029f306..77eea8afd6 100644 --- a/security/keymint/aidl/vts/functional/Android.bp +++ b/security/keymint/aidl/vts/functional/Android.bp @@ -94,6 +94,7 @@ cc_test { "libkeymint_vts_test_utils", "libpuresoftkeymasterdevice", ], + test_config: "VtsRemotelyProvisionedComponentTests.xml", test_suites: [ "general-tests", "vts", diff --git a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.xml b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.xml new file mode 100644 index 0000000000..2375bde0ff --- /dev/null +++ b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.xml @@ -0,0 +1,34 @@ + + + + -- GitLab From 703ac9601ceacdaa7325c59c28586e3d6ff69534 Mon Sep 17 00:00:00 2001 From: Yu-Han Yang Date: Tue, 20 Jul 2021 16:47:37 -0700 Subject: [PATCH 765/790] Report GnssStatusValue when GNSS start/stop Also add carrier frequencies to the mock GnssStatus and GnssAntennaInfo Bug: 194117673 Test: atest GnssStatusTest Change-Id: Ib22aefe8e4dc8389a933e9009e36872287546c7b --- gnss/1.1/default/Gnss.cpp | 28 ++++++++++------ gnss/common/utils/default/Utils.cpp | 32 ++++++++++--------- gnss/common/utils/default/include/Constants.h | 4 +++ gnss/common/utils/default/include/Utils.h | 3 +- .../utils/default/include/v2_1/GnssTemplate.h | 17 ++++++++++ 5 files changed, 58 insertions(+), 26 deletions(-) diff --git a/gnss/1.1/default/Gnss.cpp b/gnss/1.1/default/Gnss.cpp index 5043649b2d..0d77ce4273 100644 --- a/gnss/1.1/default/Gnss.cpp +++ b/gnss/1.1/default/Gnss.cpp @@ -1,9 +1,9 @@ #define LOG_TAG "Gnss" +#include "Gnss.h" #include #include - -#include "Gnss.h" +#include "Constants.h" #include "GnssDebug.h" #include "GnssMeasurement.h" #include "Utils.h" @@ -16,6 +16,7 @@ namespace implementation { using ::android::hardware::gnss::common::Utils; using GnssSvFlags = IGnssCallback::GnssSvFlags; +using namespace ::android::hardware::gnss::common; const uint32_t MIN_INTERVAL_MILLIS = 100; sp<::android::hardware::gnss::V1_1::IGnssCallback> Gnss::sGnssCallback = nullptr; @@ -197,14 +198,21 @@ Return Gnss::injectBestLocation(const GnssLocation&) { Return Gnss::getMockSvStatus() const { std::unique_lock lock(mGnssConfiguration->getMutex()); GnssSvInfo mockGnssSvInfoList[] = { - Utils::getMockSvInfoV1_0(3, GnssConstellationType::GPS, 32.5, 59.1, 166.5), - Utils::getMockSvInfoV1_0(5, GnssConstellationType::GPS, 27.0, 29.0, 56.5), - Utils::getMockSvInfoV1_0(17, GnssConstellationType::GPS, 30.5, 71.0, 77.0), - Utils::getMockSvInfoV1_0(26, GnssConstellationType::GPS, 24.1, 28.0, 253.0), - Utils::getMockSvInfoV1_0(5, GnssConstellationType::GLONASS, 20.5, 11.5, 116.0), - Utils::getMockSvInfoV1_0(17, GnssConstellationType::GLONASS, 21.5, 28.5, 186.0), - Utils::getMockSvInfoV1_0(18, GnssConstellationType::GLONASS, 28.3, 38.8, 69.0), - Utils::getMockSvInfoV1_0(10, GnssConstellationType::GLONASS, 25.0, 66.0, 247.0)}; + Utils::getMockSvInfoV1_0(3, GnssConstellationType::GPS, 32.5, 59.1, 166.5, + kGpsL1FreqHz), + Utils::getMockSvInfoV1_0(5, GnssConstellationType::GPS, 27.0, 29.0, 56.5, kGpsL1FreqHz), + Utils::getMockSvInfoV1_0(17, GnssConstellationType::GPS, 30.5, 71.0, 77.0, + kGpsL5FreqHz), + Utils::getMockSvInfoV1_0(26, GnssConstellationType::GPS, 24.1, 28.0, 253.0, + kGpsL5FreqHz), + Utils::getMockSvInfoV1_0(5, GnssConstellationType::GLONASS, 20.5, 11.5, 116.0, + kGloG1FreqHz), + Utils::getMockSvInfoV1_0(17, GnssConstellationType::GLONASS, 21.5, 28.5, 186.0, + kGloG1FreqHz), + Utils::getMockSvInfoV1_0(18, GnssConstellationType::GLONASS, 28.3, 38.8, 69.0, + kGloG1FreqHz), + Utils::getMockSvInfoV1_0(10, GnssConstellationType::GLONASS, 25.0, 66.0, 247.0, + kGloG1FreqHz)}; GnssSvStatus svStatus = {.numSvs = sizeof(mockGnssSvInfoList) / sizeof(GnssSvInfo)}; for (uint32_t i = 0; i < svStatus.numSvs; i++) { diff --git a/gnss/common/utils/default/Utils.cpp b/gnss/common/utils/default/Utils.cpp index 569dac4c59..d136448ed9 100644 --- a/gnss/common/utils/default/Utils.cpp +++ b/gnss/common/utils/default/Utils.cpp @@ -265,50 +265,50 @@ V1_0::GnssLocation Utils::getMockLocationV1_0() { } hidl_vec Utils::getMockSvInfoListV2_1() { - GnssSvInfoV1_0 gnssSvInfoV1_0 = - Utils::getMockSvInfoV1_0(3, V1_0::GnssConstellationType::GPS, 32.5, 59.1, 166.5); + GnssSvInfoV1_0 gnssSvInfoV1_0 = Utils::getMockSvInfoV1_0(3, V1_0::GnssConstellationType::GPS, + 32.5, 59.1, 166.5, kGpsL1FreqHz); GnssSvInfoV2_0 gnssSvInfoV2_0 = Utils::getMockSvInfoV2_0(gnssSvInfoV1_0, V2_0::GnssConstellationType::GPS); hidl_vec gnssSvInfoList = { Utils::getMockSvInfoV2_1(gnssSvInfoV2_0, 27.5), getMockSvInfoV2_1( getMockSvInfoV2_0(getMockSvInfoV1_0(5, V1_0::GnssConstellationType::GPS, 27.0, - 29.0, 56.5), + 29.0, 56.5, kGpsL1FreqHz), V2_0::GnssConstellationType::GPS), 22.0), getMockSvInfoV2_1( getMockSvInfoV2_0(getMockSvInfoV1_0(17, V1_0::GnssConstellationType::GPS, 30.5, - 71.0, 77.0), + 71.0, 77.0, kGpsL5FreqHz), V2_0::GnssConstellationType::GPS), 25.5), getMockSvInfoV2_1( getMockSvInfoV2_0(getMockSvInfoV1_0(26, V1_0::GnssConstellationType::GPS, 24.1, - 28.0, 253.0), + 28.0, 253.0, kGpsL5FreqHz), V2_0::GnssConstellationType::GPS), 19.1), getMockSvInfoV2_1( getMockSvInfoV2_0(getMockSvInfoV1_0(5, V1_0::GnssConstellationType::GLONASS, - 20.5, 11.5, 116.0), + 20.5, 11.5, 116.0, kGloG1FreqHz), V2_0::GnssConstellationType::GLONASS), 15.5), getMockSvInfoV2_1( getMockSvInfoV2_0(getMockSvInfoV1_0(17, V1_0::GnssConstellationType::GLONASS, - 21.5, 28.5, 186.0), + 21.5, 28.5, 186.0, kGloG1FreqHz), V2_0::GnssConstellationType::GLONASS), 16.5), getMockSvInfoV2_1( getMockSvInfoV2_0(getMockSvInfoV1_0(18, V1_0::GnssConstellationType::GLONASS, - 28.3, 38.8, 69.0), + 28.3, 38.8, 69.0, kGloG1FreqHz), V2_0::GnssConstellationType::GLONASS), 25.3), getMockSvInfoV2_1( getMockSvInfoV2_0(getMockSvInfoV1_0(10, V1_0::GnssConstellationType::GLONASS, - 25.0, 66.0, 247.0), + 25.0, 66.0, 247.0, kGloG1FreqHz), V2_0::GnssConstellationType::GLONASS), 20.0), getMockSvInfoV2_1( getMockSvInfoV2_0(getMockSvInfoV1_0(3, V1_0::GnssConstellationType::UNKNOWN, - 22.0, 35.0, 112.0), + 22.0, 35.0, 112.0, kIrnssL5FreqHz), V2_0::GnssConstellationType::IRNSS), 19.7), }; @@ -333,21 +333,23 @@ GnssSvInfoV2_0 Utils::getMockSvInfoV2_0(GnssSvInfoV1_0 gnssSvInfoV1_0, } GnssSvInfoV1_0 Utils::getMockSvInfoV1_0(int16_t svid, V1_0::GnssConstellationType type, - float cN0DbHz, float elevationDegrees, - float azimuthDegrees) { + float cN0DbHz, float elevationDegrees, float azimuthDegrees, + float carrierFrequencyHz) { GnssSvInfoV1_0 svInfo = {.svid = svid, .constellation = type, .cN0Dbhz = cN0DbHz, .elevationDegrees = elevationDegrees, .azimuthDegrees = azimuthDegrees, + .carrierFrequencyHz = carrierFrequencyHz, .svFlag = GnssSvFlags::USED_IN_FIX | GnssSvFlags::HAS_EPHEMERIS_DATA | - GnssSvFlags::HAS_ALMANAC_DATA}; + GnssSvFlags::HAS_ALMANAC_DATA | + GnssSvFlags::HAS_CARRIER_FREQUENCY}; return svInfo; } hidl_vec Utils::getMockAntennaInfos() { GnssAntennaInfo mockAntennaInfo_1 = { - .carrierFrequencyMHz = 123412.12, + .carrierFrequencyMHz = kGpsL1FreqHz * 1e-6, .phaseCenterOffsetCoordinateMillimeters = Coord{.x = 1, .xUncertainty = 0.1, .y = 2, @@ -381,7 +383,7 @@ hidl_vec Utils::getMockAntennaInfos() { }; GnssAntennaInfo mockAntennaInfo_2 = { - .carrierFrequencyMHz = 532324.23, + .carrierFrequencyMHz = kGpsL5FreqHz * 1e-6, .phaseCenterOffsetCoordinateMillimeters = Coord{.x = 5, .xUncertainty = 0.1, .y = 6, diff --git a/gnss/common/utils/default/include/Constants.h b/gnss/common/utils/default/include/Constants.h index a290ed243f..22afee1ad1 100644 --- a/gnss/common/utils/default/include/Constants.h +++ b/gnss/common/utils/default/include/Constants.h @@ -29,6 +29,10 @@ const float kMockVerticalAccuracyMeters = 5; const float kMockSpeedAccuracyMetersPerSecond = 1; const float kMockBearingAccuracyDegrees = 90; const int64_t kMockTimestamp = 1519930775453L; +const float kGpsL1FreqHz = 1575.42 * 1e6; +const float kGpsL5FreqHz = 1176.45 * 1e6; +const float kGloG1FreqHz = 1602.0 * 1e6; +const float kIrnssL5FreqHz = 1176.45 * 1e6; } // namespace common } // namespace gnss diff --git a/gnss/common/utils/default/include/Utils.h b/gnss/common/utils/default/include/Utils.h index 771d39dbd1..43772ce11a 100644 --- a/gnss/common/utils/default/include/Utils.h +++ b/gnss/common/utils/default/include/Utils.h @@ -44,7 +44,8 @@ struct Utils { static V1_0::IGnssCallback::GnssSvInfo getMockSvInfoV1_0(int16_t svid, V1_0::GnssConstellationType type, float cN0DbHz, float elevationDegrees, - float azimuthDegrees); + float azimuthDegrees, + float carrierFrequencyHz); static hidl_vec getMockAntennaInfos(); }; diff --git a/gnss/common/utils/default/include/v2_1/GnssTemplate.h b/gnss/common/utils/default/include/v2_1/GnssTemplate.h index a1d698167c..131af24fbe 100644 --- a/gnss/common/utils/default/include/v2_1/GnssTemplate.h +++ b/gnss/common/utils/default/include/v2_1/GnssTemplate.h @@ -113,6 +113,7 @@ struct GnssTemplate : public T_IGnss { void reportLocation(const V2_0::GnssLocation&) const; void reportLocation(const V1_0::GnssLocation&) const; void reportSvStatus(const hidl_vec&) const; + void reportGnssStatusValue(const V1_0::IGnssCallback::GnssStatusValue) const; Return help(const hidl_handle& fd); Return setLocation(const hidl_handle& fd, const hidl_vec& options); @@ -215,6 +216,7 @@ Return GnssTemplate::start() { } mIsActive = true; + this->reportGnssStatusValue(V1_0::IGnssCallback::GnssStatusValue::SESSION_BEGIN); mThread = std::thread([this]() { while (mIsActive == true) { auto svStatus = filterBlocklistedSatellitesV2_1(Utils::getMockSvInfoListV2_1()); @@ -266,6 +268,7 @@ template Return GnssTemplate::stop() { ALOGD("stop"); mIsActive = false; + this->reportGnssStatusValue(V1_0::IGnssCallback::GnssStatusValue::SESSION_END); if (mThread.joinable()) { mThread.join(); } @@ -605,6 +608,20 @@ Return> GnssTemplate::getExtensionGnssAntenn return new V2_1::implementation::GnssAntennaInfo(); } +template +void GnssTemplate::reportGnssStatusValue( + const V1_0::IGnssCallback::GnssStatusValue gnssStatusValue) const { + std::unique_lock lock(mMutex); + if (sGnssCallback_2_1 == nullptr) { + ALOGE("%s: sGnssCallback v2.1 is null.", __func__); + return; + } + auto ret = sGnssCallback_2_1->gnssStatusCb(gnssStatusValue); + if (!ret.isOk()) { + ALOGE("%s: Unable to invoke callback", __func__); + } +} + template void GnssTemplate::reportSvStatus( const hidl_vec& svInfoList) const { -- GitLab From db3c830bc8be77b7cdf6a2fea17ecd31b2ffa632 Mon Sep 17 00:00:00 2001 From: Aaron Tsai Date: Tue, 13 Jul 2021 12:14:48 +0800 Subject: [PATCH 766/790] Waiting 10s at the beginning of getBarringInfo test if not yet in-service. If the previous setRadioPower_1_5_emergencyCall_cancelled test has just finished. Due to radio restarting, modem may need a little more time to acquire network service. Otherwise, the barring info will be empty. Bug: 191866257 Test: atest VtsHalRadioV1_5TargetTest Change-Id: I9ae4e7a07b9f47353554ffb63a23b6518aa344b7 --- radio/1.5/vts/functional/radio_hidl_hal_api.cpp | 12 ++++++++++++ radio/1.5/vts/functional/radio_hidl_hal_utils_v1_5.h | 3 +++ radio/1.5/vts/functional/radio_response.cpp | 6 ++++-- 3 files changed, 19 insertions(+), 2 deletions(-) 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 0b49b36927..d108951c0e 100644 --- a/radio/1.5/vts/functional/radio_hidl_hal_api.cpp +++ b/radio/1.5/vts/functional/radio_hidl_hal_api.cpp @@ -1251,8 +1251,20 @@ TEST_P(RadioHidlTest_v1_5, sendCdmaSmsExpectMore) { * Test IRadio.getBarringInfo() for the response returned. */ TEST_P(RadioHidlTest_v1_5, getBarringInfo) { + // If the previous setRadioPower_1_5_emergencyCall_cancelled test has just finished. + // Due to radio restarting, modem may need a little more time to acquire network service + // and barring infos. If voice status is in-service, waiting 3s to get barring infos ready. + // Or waiting 10s if voice status is not in-service. serial = GetRandomSerialNumber(); + radio_v1_5->getVoiceRegistrationState_1_5(serial); + EXPECT_EQ(std::cv_status::no_timeout, wait()); + if (isVoiceInService(radioRsp_v1_5->voiceRegResp.regState)) { + sleep(BARRING_INFO_MAX_WAIT_TIME_SECONDS); + } else { + sleep(VOICE_SERVICE_MAX_WAIT_TIME_SECONDS); + } + serial = GetRandomSerialNumber(); Return res = radio_v1_5->getBarringInfo(serial); EXPECT_EQ(std::cv_status::no_timeout, wait()); EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type); diff --git a/radio/1.5/vts/functional/radio_hidl_hal_utils_v1_5.h b/radio/1.5/vts/functional/radio_hidl_hal_utils_v1_5.h index 87ce675c5c..65442caff1 100644 --- a/radio/1.5/vts/functional/radio_hidl_hal_utils_v1_5.h +++ b/radio/1.5/vts/functional/radio_hidl_hal_utils_v1_5.h @@ -51,6 +51,8 @@ using ::android::hardware::Void; #define TIMEOUT_PERIOD 75 #define MODEM_EMERGENCY_CALL_ESTABLISH_TIME 3 #define MODEM_EMERGENCY_CALL_DISCONNECT_TIME 3 +#define VOICE_SERVICE_MAX_WAIT_TIME_SECONDS 10 +#define BARRING_INFO_MAX_WAIT_TIME_SECONDS 3 #define RADIO_SERVICE_NAME "slot1" @@ -69,6 +71,7 @@ class RadioResponse_v1_5 : public ::android::hardware::radio::V1_5::IRadioRespon // Call hidl_vec<::android::hardware::radio::V1_2::Call> currentCalls; + ::android::hardware::radio::V1_2::VoiceRegStateResult voiceRegResp; // Modem bool isModemEnabled; diff --git a/radio/1.5/vts/functional/radio_response.cpp b/radio/1.5/vts/functional/radio_response.cpp index 9b6d450e83..3d6fc17f5b 100644 --- a/radio/1.5/vts/functional/radio_response.cpp +++ b/radio/1.5/vts/functional/radio_response.cpp @@ -763,8 +763,9 @@ Return RadioResponse_v1_5::getCellInfoListResponse_1_2( Return RadioResponse_v1_5::getVoiceRegistrationStateResponse_1_2( const RadioResponseInfo& info, - const ::android::hardware::radio::V1_2::VoiceRegStateResult& /*voiceRegResponse*/) { + const ::android::hardware::radio::V1_2::VoiceRegStateResult& voiceRegResponse) { rspInfo = info; + voiceRegResp = voiceRegResponse; parent_v1_5.notify(info.serial); return Void(); } @@ -989,8 +990,9 @@ Return RadioResponse_v1_5::getBarringInfoResponse( Return RadioResponse_v1_5::getVoiceRegistrationStateResponse_1_5( const RadioResponseInfo& info, - const ::android::hardware::radio::V1_5::RegStateResult& /*regResponse*/) { + const ::android::hardware::radio::V1_5::RegStateResult& regResponse) { rspInfo = info; + voiceRegResp.regState = regResponse.regState; parent_v1_5.notify(info.serial); return Void(); } -- GitLab From 61a6d8d72effaedf8ed6bc5461e36859faac4f4f Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Wed, 21 Jul 2021 13:22:45 -0700 Subject: [PATCH 767/790] IFace: fix VTS test to match the interface contract Bug: 193849101 Test: atest VtsHalBiometricsFaceTargetTest Change-Id: I5b3ed1b87244d6265d23c15ef2c2efe4f6155973 --- .../face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp b/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp index 4dc44f16c7..8906b8d935 100644 --- a/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp +++ b/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp @@ -60,9 +60,10 @@ class SessionCallback : public BnSessionCallback { return ndk::ScopedAStatus::ok(); } - ndk::ScopedAStatus onError(Error error, int32_t /*vendorCode*/) override { + ndk::ScopedAStatus onError(Error error, int32_t vendorCode) override { auto lock = std::lock_guard{mMutex}; mError = error; + mVendorCode = vendorCode; mOnErrorInvoked = true; mCv.notify_one(); return ndk::ScopedAStatus::ok(); @@ -141,6 +142,7 @@ class SessionCallback : public BnSessionCallback { std::mutex mMutex; std::condition_variable mCv; Error mError = Error::UNKNOWN; + int32_t mVendorCode = 0; int64_t mGeneratedChallenge = 0; int64_t mRevokedChallenge = 0; bool mOnChallengeGeneratedInvoked = false; @@ -218,6 +220,8 @@ TEST_P(Face, EnrollWithBadHatResultsInErrorTest) { // Make sure an error is returned. auto lock = std::unique_lock{mCb->mMutex}; mCb->mCv.wait(lock, [this] { return mCb->mOnErrorInvoked; }); + EXPECT_EQ(mCb->mError, Error::UNABLE_TO_PROCESS); + EXPECT_EQ(mCb->mVendorCode, 0); } TEST_P(Face, GenerateChallengeProducesUniqueChallengesTest) { @@ -287,13 +291,15 @@ TEST_P(Face, RemoveEnrollmentsWorksTest) { mCb->mCv.wait(lock, [this] { return mCb->mOnEnrollmentsRemovedInvoked; }); } -TEST_P(Face, GetFeaturesWorksTest) { +TEST_P(Face, GetFeaturesWithoutEnrollmentsResultsInUnableToProcess) { // Call the method. ASSERT_TRUE(mSession->getFeatures().isOk()); // Wait for the result. auto lock = std::unique_lock{mCb->mMutex}; - mCb->mCv.wait(lock, [this] { return mCb->mOnFeaturesRetrievedInvoked; }); + mCb->mCv.wait(lock, [this] { return mCb->mOnErrorInvoked; }); + EXPECT_EQ(mCb->mError, Error::UNABLE_TO_PROCESS); + EXPECT_EQ(mCb->mVendorCode, 0); } TEST_P(Face, GetAuthenticatorIdWorksTest) { -- GitLab From 9208a095686a2b39e6ef3f6a664719ed933563f5 Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Wed, 21 Jul 2021 23:13:12 +0000 Subject: [PATCH 768/790] IFace: fix default implementation to pass VTS Bug: 193849101 Test: atest VtsHalBiometricsFaceTargetTest Change-Id: Ia90c639074a6a9ed270f7c499c8816a8c7224b7f --- biometrics/face/aidl/default/Session.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/biometrics/face/aidl/default/Session.cpp b/biometrics/face/aidl/default/Session.cpp index 0cb7c95de8..39f37538f7 100644 --- a/biometrics/face/aidl/default/Session.cpp +++ b/biometrics/face/aidl/default/Session.cpp @@ -107,7 +107,8 @@ ndk::ScopedAStatus Session::removeEnrollments(const std::vector& /*enro ndk::ScopedAStatus Session::getFeatures() { LOG(INFO) << "getFeatures"; if (cb_) { - cb_->onFeaturesRetrieved({}); + // Must error out with UNABLE_TO_PROCESS when no faces are enrolled. + cb_->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorCode */); } return ndk::ScopedAStatus::ok(); } -- GitLab From 5beafca660e8ec4cf685f8acf20c84fb2a9f6c43 Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Wed, 21 Jul 2021 18:57:36 -0700 Subject: [PATCH 769/790] IFace: annotate the previewSurface as @nullable in enroll Bug: 194346408 Test: android.hardware.biometrics.face-update-api Change-Id: Id8809b27f121a738a41abeee66f5c1fd3840cc44 --- .../face/aidl/aidl_api/android.hardware.biometrics.face/1/.hash | 2 +- .../1/android/hardware/biometrics/face/ISession.aidl | 2 +- .../current/android/hardware/biometrics/face/ISession.aidl | 2 +- .../face/aidl/android/hardware/biometrics/face/ISession.aidl | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/.hash b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/.hash index b8d5097cc9..f5ad87fca7 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/.hash +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/.hash @@ -1 +1 @@ -945de3635b7f5a09244820eef56035c92fdbd324 +3b10f5094c5af9fe551093597fab007d1e148256 diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/ISession.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/ISession.aidl index d1c2c1dd47..78178642cd 100644 --- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/ISession.aidl +++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/ISession.aidl @@ -37,7 +37,7 @@ interface ISession { void generateChallenge(); void revokeChallenge(in long challenge); android.hardware.biometrics.face.EnrollmentStageConfig[] getEnrollmentConfig(in android.hardware.biometrics.face.EnrollmentType enrollmentType); - android.hardware.biometrics.common.ICancellationSignal enroll(in android.hardware.keymaster.HardwareAuthToken hat, in android.hardware.biometrics.face.EnrollmentType type, in android.hardware.biometrics.face.Feature[] features, in android.hardware.common.NativeHandle previewSurface); + android.hardware.biometrics.common.ICancellationSignal enroll(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); android.hardware.biometrics.common.ICancellationSignal authenticate(in long operationId); android.hardware.biometrics.common.ICancellationSignal detectInteraction(); void enumerateEnrollments(); 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 d1c2c1dd47..78178642cd 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 @@ -37,7 +37,7 @@ interface ISession { void generateChallenge(); void revokeChallenge(in long challenge); android.hardware.biometrics.face.EnrollmentStageConfig[] getEnrollmentConfig(in android.hardware.biometrics.face.EnrollmentType enrollmentType); - android.hardware.biometrics.common.ICancellationSignal enroll(in android.hardware.keymaster.HardwareAuthToken hat, in android.hardware.biometrics.face.EnrollmentType type, in android.hardware.biometrics.face.Feature[] features, in android.hardware.common.NativeHandle previewSurface); + android.hardware.biometrics.common.ICancellationSignal enroll(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); android.hardware.biometrics.common.ICancellationSignal authenticate(in long operationId); android.hardware.biometrics.common.ICancellationSignal detectInteraction(); void enumerateEnrollments(); diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl index 2a57e3aa46..5f06b408e8 100644 --- a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl +++ b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl @@ -154,7 +154,7 @@ interface ISession { * operation. */ ICancellationSignal enroll(in HardwareAuthToken hat, in EnrollmentType type, - in Feature[] features, in NativeHandle previewSurface); + in Feature[] features, in @nullable NativeHandle previewSurface); /** * authenticate: -- GitLab From bde61ca1d32ddde39989f0bcd944a51349bbcdad Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Wed, 21 Jul 2021 19:01:07 -0700 Subject: [PATCH 770/790] IFace: update default implementation to use optional previewSurface Bug: 194346408 Test: atest VtsHalBiometricsFaceTargetTest Change-Id: I72d3d6d638a1662ebd1a53a7029ea3bf200efe48 --- biometrics/face/aidl/default/Session.cpp | 3 ++- biometrics/face/aidl/default/Session.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/biometrics/face/aidl/default/Session.cpp b/biometrics/face/aidl/default/Session.cpp index 0cb7c95de8..bf5202850a 100644 --- a/biometrics/face/aidl/default/Session.cpp +++ b/biometrics/face/aidl/default/Session.cpp @@ -63,7 +63,8 @@ ndk::ScopedAStatus Session::getEnrollmentConfig(EnrollmentType /*enrollmentType* ndk::ScopedAStatus Session::enroll( const keymaster::HardwareAuthToken& /*hat*/, EnrollmentType /*enrollmentType*/, - const std::vector& /*features*/, const NativeHandle& /*previewSurface*/, + const std::vector& /*features*/, + const std::optional& /*previewSurface*/, std::shared_ptr* /*return_val*/) { LOG(INFO) << "enroll"; if (cb_) { diff --git a/biometrics/face/aidl/default/Session.h b/biometrics/face/aidl/default/Session.h index 4d213e3860..4152909a49 100644 --- a/biometrics/face/aidl/default/Session.h +++ b/biometrics/face/aidl/default/Session.h @@ -41,7 +41,7 @@ class Session : public BnSession { ndk::ScopedAStatus enroll(const keymaster::HardwareAuthToken& hat, EnrollmentType enrollmentType, const std::vector& features, - const NativeHandle& previewSurface, + const std::optional& previewSurface, std::shared_ptr* return_val) override; ndk::ScopedAStatus authenticate( -- GitLab From 88796f4992dc308102be052c9ab980ac51ed43ee Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Wed, 21 Jul 2021 22:54:40 -0700 Subject: [PATCH 771/790] IFace: update VTS test to pass std::nullopt for previewSurface Bug: 194346408 Test: atest VtsHalBiometricsFaceTargetTest Change-Id: I1e945d821d4b91b9a9ea8f74ae6f817ef04a0f85 --- biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp b/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp index 4dc44f16c7..f3eac8f460 100644 --- a/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp +++ b/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp @@ -212,7 +212,7 @@ TEST_P(Face, EnrollWithBadHatResultsInErrorTest) { auto hat = keymaster::HardwareAuthToken{}; std::shared_ptr cancellationSignal; ASSERT_TRUE( - mSession->enroll(hat, EnrollmentType::DEFAULT, {}, NativeHandle{}, &cancellationSignal) + mSession->enroll(hat, EnrollmentType::DEFAULT, {}, std::nullopt, &cancellationSignal) .isOk()); // Make sure an error is returned. -- GitLab From 4d375a10b9d6d09843c02d660a745a2dcb2d08e6 Mon Sep 17 00:00:00 2001 From: Amos Bianchi Date: Fri, 2 Jul 2021 14:22:38 -0700 Subject: [PATCH 772/790] Add test service for HIDL active services callback. Bug: 191781736 Test: atest hidl_lazy_test Change-Id: Ie743d9d8635165f820977bfcb1548a83b56ccc1b --- tests/lazy_cb/1.0/.hidl_for_system_ext | 0 tests/lazy_cb/1.0/Android.bp | 23 +++++++++++++++++++++++ tests/lazy_cb/1.0/ILazyCb.hal | 25 +++++++++++++++++++++++++ 3 files changed, 48 insertions(+) create mode 100644 tests/lazy_cb/1.0/.hidl_for_system_ext create mode 100644 tests/lazy_cb/1.0/Android.bp create mode 100644 tests/lazy_cb/1.0/ILazyCb.hal diff --git a/tests/lazy_cb/1.0/.hidl_for_system_ext b/tests/lazy_cb/1.0/.hidl_for_system_ext new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/lazy_cb/1.0/Android.bp b/tests/lazy_cb/1.0/Android.bp new file mode 100644 index 0000000000..4d82b63155 --- /dev/null +++ b/tests/lazy_cb/1.0/Android.bp @@ -0,0 +1,23 @@ +// 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.tests.lazy_cb@1.0", + root: "android.hardware", + system_ext_specific: true, + srcs: [ + "ILazyCb.hal", + ], + interfaces: [ + "android.hidl.base@1.0", + ], + gen_java: true, +} diff --git a/tests/lazy_cb/1.0/ILazyCb.hal b/tests/lazy_cb/1.0/ILazyCb.hal new file mode 100644 index 0000000000..a9046b3353 --- /dev/null +++ b/tests/lazy_cb/1.0/ILazyCb.hal @@ -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.tests.lazy_cb@1.0; + +interface ILazyCb { + /** + * Set the eventfd used to notify that the active services + * callback is being executed and is about to terminate the process. + */ + setEventFd(handle fds) generates (bool success); +}; -- GitLab From ac11a2e82480ffef7122f5d30d5e2901fb0955eb Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Mon, 12 Jul 2021 18:25:11 -0700 Subject: [PATCH 773/790] Update comments for IBiometricsFingerprint@2.3 This CL adds a comment that discourages use of this interface. The AIDL interface, IFingerprint, should be used instead. Bug: 160189286 Test: hidl-gen -L check android.hardware.biometrics.fingerprint@2.3::IBiometricsFingerprint Change-Id: Ifafb191ac16e03e60d677fce6dc9e41e87bad0c0 --- biometrics/fingerprint/2.3/IBiometricsFingerprint.hal | 4 ++++ current.txt | 1 + 2 files changed, 5 insertions(+) diff --git a/biometrics/fingerprint/2.3/IBiometricsFingerprint.hal b/biometrics/fingerprint/2.3/IBiometricsFingerprint.hal index 13f03c5eea..378b564537 100644 --- a/biometrics/fingerprint/2.3/IBiometricsFingerprint.hal +++ b/biometrics/fingerprint/2.3/IBiometricsFingerprint.hal @@ -19,6 +19,10 @@ package android.hardware.biometrics.fingerprint@2.3; import @2.2::IBiometricsFingerprint; /** + * New use of this interface is strongly discouraged. The recommended option is + * to use the AIDL interface, android.hardware.biometrics.fingerprint + * (IFingerprint). + * * The interface for biometric fingerprint authentication. */ interface IBiometricsFingerprint extends @2.2::IBiometricsFingerprint { diff --git a/current.txt b/current.txt index fbad3dabf1..8c631d9e70 100644 --- a/current.txt +++ b/current.txt @@ -833,6 +833,7 @@ e3865e74cb1a6e6afd38c7aa84115cb109ce47b972132de5242bc3838d2771f6 android.hardwar b3caf524c46a47d67e6453a34419e1881942d059e146cda740502670e9a752c3 android.hardware.automotive.vehicle@2.0::IVehicle 7ce8728b27600e840cacf0a832f6942819fe535f9d3797ae052d5eef5065921c android.hardware.automotive.vehicle@2.0::IVehicleCallback b525e91d886379c13588f4975bb04d625d46e1f41b4453792c4b2db1e7ff4340 android.hardware.biometrics.fingerprint@2.3::IBiometricsFingerprint +7a78e9963bec0b071e7d46928c6100e2174270892d3f15a1eaad074997adf279 android.hardware.biometrics.fingerprint@2.3::IBiometricsFingerprint # Added for b/160189286 for Android S 4baf8e0eca4aa896cc9ceb7bb676aaf4fa21372ef8b49eed68eced1221c3dc0d android.hardware.bluetooth.audio@2.1::IBluetoothAudioProvider d417a9212c8f96e3a06a2f221c8c5756c765355b2b81de2b2a65d4c9eee85401 android.hardware.bluetooth.audio@2.1::IBluetoothAudioProvidersFactory c17d9e27abd37ae5a8ff8da08fc5c9b13a264670feef6bbbc9d3ab1915216130 android.hardware.bluetooth.audio@2.1::types -- GitLab From 97d1039dfd16414fd7f12868379e772b087b43ed Mon Sep 17 00:00:00 2001 From: garysungang Date: Wed, 7 Jul 2021 22:30:35 -0700 Subject: [PATCH 774/790] Update EVS VTS test case Update test case - CameraStreamExternalBuffering Use native resolution instead of fixed test buffer 640x320 Bug: 190127973 Test: Manually run VTS on seahawk Change-Id: I11043af4215fb9c5a2658591e9bdf9e468542a1b --- .../functional/VtsHalEvsV1_1TargetTest.cpp | 115 +++++++++++------- 1 file changed, 70 insertions(+), 45 deletions(-) diff --git a/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp b/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp index a3dc45bb5b..8cc18822f2 100644 --- a/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp +++ b/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp @@ -2269,48 +2269,74 @@ TEST_P(EvsHidlTest, CameraStreamExternalBuffering) { // Acquire the graphics buffer allocator android::GraphicBufferAllocator& alloc(android::GraphicBufferAllocator::get()); - const auto usage = GRALLOC_USAGE_HW_TEXTURE | - GRALLOC_USAGE_SW_READ_RARELY | - GRALLOC_USAGE_SW_WRITE_OFTEN; + const auto usage = + GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_SW_READ_RARELY | GRALLOC_USAGE_SW_WRITE_OFTEN; const auto format = HAL_PIXEL_FORMAT_RGBA_8888; - const auto width = 640; - const auto height = 360; - - // Allocate buffers to use - hidl_vec buffers; - buffers.resize(kBuffersToHold); - for (auto i = 0; i < kBuffersToHold; ++i) { - unsigned pixelsPerLine; - buffer_handle_t memHandle = nullptr; - android::status_t result = alloc.allocate(width, - height, - format, - 1, - usage, - &memHandle, - &pixelsPerLine, - 0, - "EvsApp"); - if (result != android::NO_ERROR) { - LOG(ERROR) << __FUNCTION__ << " failed to allocate memory."; - } else { - BufferDesc buf; - AHardwareBuffer_Desc* pDesc = - reinterpret_cast(&buf.buffer.description); - pDesc->width = width; - pDesc->height = height; - pDesc->layers = 1; - pDesc->format = format; - pDesc->usage = usage; - pDesc->stride = pixelsPerLine; - buf.buffer.nativeHandle = memHandle; - buf.bufferId = i; // Unique number to identify this buffer - buffers[i] = buf; - } - } + uint32_t width = 640; + uint32_t height = 360; + camera_metadata_entry_t streamCfgs; // Test each reported camera - for (auto&& cam: cameraInfo) { + for (auto&& cam : cameraInfo) { + bool foundCfg = false; + if (!find_camera_metadata_entry(reinterpret_cast(cam.metadata.data()), + ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, + &streamCfgs)) { + // Stream configurations are found in metadata + RawStreamConfig* ptr = reinterpret_cast(streamCfgs.data.i32); + + LOG(DEBUG) << __LINE__ << " start searching " << streamCfgs.count; + for (unsigned idx = 0; idx < streamCfgs.count; idx++) { + LOG(DEBUG) << "ptr->direction= " << ptr->direction + << " ptr->format= " << ptr->format; + if (ptr->direction == ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT && + ptr->format == HAL_PIXEL_FORMAT_RGBA_8888) { + width = ptr->width; + height = ptr->height; + foundCfg = true; + // Always use the 1st available configuration + break; + } + ++ptr; + } + } + + if (!foundCfg) { + LOG(INFO) << "No configuration found. Use default stream configurations."; + } + + // Allocate buffers to use + hidl_vec buffers; + buffers.resize(kBuffersToHold); + for (auto i = 0; i < kBuffersToHold; ++i) { + unsigned pixelsPerLine; + buffer_handle_t memHandle = nullptr; + android::status_t result = + alloc.allocate(width, height, format, 1, usage, &memHandle, &pixelsPerLine, 0, + "CameraStreamExternalBufferingTest"); + if (result != android::NO_ERROR) { + LOG(ERROR) << __FUNCTION__ << " failed to allocate memory."; + // Release previous allocated buffers + for (auto j = 0; j < i; j++) { + alloc.free(buffers[i].buffer.nativeHandle); + } + return; + } else { + BufferDesc buf; + AHardwareBuffer_Desc* pDesc = + reinterpret_cast(&buf.buffer.description); + pDesc->width = width; + pDesc->height = height; + pDesc->layers = 1; + pDesc->format = format; + pDesc->usage = usage; + pDesc->stride = pixelsPerLine; + buf.buffer.nativeHandle = memHandle; + buf.bufferId = i; // Unique number to identify this buffer + buffers[i] = buf; + } + } + bool isLogicalCam = false; getPhysicalCameraIds(cam.v1.cameraId, isLogicalCam); @@ -2374,13 +2400,12 @@ TEST_P(EvsHidlTest, CameraStreamExternalBuffering) { // Explicitly release the camera pEnumerator->closeCamera(pCam); activeCameras.clear(); + // Release buffers + for (auto& b : buffers) { + alloc.free(b.buffer.nativeHandle); + } + buffers.resize(0); } - - // Release buffers - for (auto& b : buffers) { - alloc.free(b.buffer.nativeHandle); - } - buffers.resize(0); } -- GitLab From 8aee4a857ca912dc8975e8f5e50634dcd342560e Mon Sep 17 00:00:00 2001 From: Seth Moore Date: Tue, 27 Jul 2021 14:20:17 -0700 Subject: [PATCH 775/790] Allow uninstantiated remote provisioning tests Not all devices have an IRemotelyProvisionedComponent HAL, so on those devices 0 of the tests in VtsRemotelyProvisionedComponentTests will be run. Fixes: 194770385 Test: Ran tests on two devices: one with and one without the HAL. Change-Id: I8624096158f29058189dfab7cd876804ae178e60 --- .../aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp index af951e8861..38f3586862 100644 --- a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp +++ b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp @@ -41,6 +41,7 @@ using ::std::vector; namespace { #define INSTANTIATE_REM_PROV_AIDL_TEST(name) \ + GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(name); \ INSTANTIATE_TEST_SUITE_P( \ PerInstance, name, \ testing::ValuesIn(VtsRemotelyProvisionedComponentTests::build_params()), \ -- GitLab From 6ac46d6bf22fe5a1339eac85666d865b63376999 Mon Sep 17 00:00:00 2001 From: Tyler Trephan Date: Thu, 29 Jul 2021 09:46:06 -0700 Subject: [PATCH 776/790] Fixed failing CTS tests related vehicle properties on the AAOS emulator. -Added supported gears to CURRENT_GEAR config. -Changed INFO_EXTERIOR_DIMENSIONS to int32 array Test: atest CarPropertyManagerTest Bug: 194182294 Change-Id: I96d241d0c388b8fc397af9f45a8a8072a05ee8d1 --- .../2.0/default/impl/vhal_v2_0/DefaultConfig.h | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h index a85cdf06a5..6a0288f3a4 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h @@ -124,7 +124,7 @@ const ConfigDeclaration kVehicleProperties[]{ .access = VehiclePropertyAccess::READ, .changeMode = VehiclePropertyChangeMode::STATIC, }, - .initialValue = {.floatValues = {1776, 4950, 2008, 2140, 2984, 1665, 1667, 11800}}}, + .initialValue = {.int32Values = {1776, 4950, 2008, 2140, 2984, 1665, 1667, 11800}}}, {.config = { .prop = toInt(VehicleProperty::PERF_VEHICLE_SPEED), @@ -328,6 +328,11 @@ const ConfigDeclaration kVehicleProperties[]{ .prop = toInt(VehicleProperty::CURRENT_GEAR), .access = VehiclePropertyAccess::READ, .changeMode = VehiclePropertyChangeMode::ON_CHANGE, + .configArray = {(int)VehicleGear::GEAR_PARK, + (int)VehicleGear::GEAR_NEUTRAL, + (int)VehicleGear::GEAR_REVERSE, (int)VehicleGear::GEAR_1, + (int)VehicleGear::GEAR_2, (int)VehicleGear::GEAR_3, + (int)VehicleGear::GEAR_4, (int)VehicleGear::GEAR_5}, }, .initialValue = {.int32Values = {toInt(VehicleGear::GEAR_PARK)}}}, @@ -1072,8 +1077,8 @@ const ConfigDeclaration kVehicleProperties[]{ .access = VehiclePropertyAccess::READ, .changeMode = VehiclePropertyChangeMode::ON_CHANGE, }, - .initialValue = {.int32Values = {0 /* Off */, -1, -1, -1, -1 /* Bounds */, - -1, -1, -1, -1 /* Insets */}}, + .initialValue = {.int32Values = {0 /* Off */, -1, -1, -1, -1 /* Bounds */, -1, -1, + -1, -1 /* Insets */}}, }, { .config = @@ -1126,9 +1131,9 @@ const ConfigDeclaration kVehicleProperties[]{ .changeMode = VehiclePropertyChangeMode::ON_CHANGE, .configArray = {0, 0, 0, 11, 0, 0, 0, 0, 16}, }, - .initialValue = {.int32Values = {0 /* Off */, -1, -1, -1, -1 /* Bounds */, - -1, -1, -1, -1 /* Insets */, - 0 /* ClusterHome */, -1 /* ClusterNone */}}, + .initialValue = {.int32Values = {0 /* Off */, -1, -1, -1, -1 /* Bounds */, -1, -1, + -1, -1 /* Insets */, 0 /* ClusterHome */, + -1 /* ClusterNone */}}, }, { .config = -- GitLab From 53ba71df99b4c41fef7e708632df3d6acd800a83 Mon Sep 17 00:00:00 2001 From: Cheney Ni Date: Thu, 29 Jul 2021 00:50:03 +0800 Subject: [PATCH 777/790] BluetoothAudio: Refine the FMQ size for A2DP software encoding For those high-resolution codecs, they are 24 or 32 bits per sample, so the buffer size must be the LCM of 16, 24, and 32. Bug: 194980528 Test: A2DP playing with aptX and / or LDAC Change-Id: I788e185496dea4a1b40fa369e032a4f8491b835b Merged-In: I788e185496dea4a1b40fa369e032a4f8491b835b (cherry picked from commit a0cc24730eafe91021643b9b36889d61728f58f0) --- bluetooth/audio/2.0/default/A2dpSoftwareAudioProvider.cpp | 8 ++++++-- bluetooth/audio/2.1/default/A2dpSoftwareAudioProvider.cpp | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/bluetooth/audio/2.0/default/A2dpSoftwareAudioProvider.cpp b/bluetooth/audio/2.0/default/A2dpSoftwareAudioProvider.cpp index f71a73e233..0c0b85fdf3 100644 --- a/bluetooth/audio/2.0/default/A2dpSoftwareAudioProvider.cpp +++ b/bluetooth/audio/2.0/default/A2dpSoftwareAudioProvider.cpp @@ -32,10 +32,14 @@ namespace implementation { using ::android::bluetooth::audio::BluetoothAudioSessionReport; using ::android::hardware::Void; +// Here the buffer size is based on SBC static constexpr uint32_t kPcmFrameSize = 4; // 16 bits per sample / stereo -static constexpr uint32_t kPcmFrameCount = 128; +// SBC is 128, and here choose the LCM of 16, 24, and 32 +static constexpr uint32_t kPcmFrameCount = 96; static constexpr uint32_t kRtpFrameSize = kPcmFrameSize * kPcmFrameCount; -static constexpr uint32_t kRtpFrameCount = 7; // max counts by 1 tick (20ms) +// 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; diff --git a/bluetooth/audio/2.1/default/A2dpSoftwareAudioProvider.cpp b/bluetooth/audio/2.1/default/A2dpSoftwareAudioProvider.cpp index a37176ba4d..4928cea66d 100644 --- a/bluetooth/audio/2.1/default/A2dpSoftwareAudioProvider.cpp +++ b/bluetooth/audio/2.1/default/A2dpSoftwareAudioProvider.cpp @@ -34,10 +34,14 @@ using ::android::bluetooth::audio::BluetoothAudioSessionReport_2_1; using ::android::hardware::Void; using ::android::hardware::bluetooth::audio::V2_0::AudioConfiguration; +// Here the buffer size is based on SBC static constexpr uint32_t kPcmFrameSize = 4; // 16 bits per sample / stereo -static constexpr uint32_t kPcmFrameCount = 128; +// 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; -static constexpr uint32_t kRtpFrameCount = 7; // max counts by 1 tick (20ms) +// 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; -- GitLab From 0fc5b6ce50b2e9632ff122ad54d0d469d7628210 Mon Sep 17 00:00:00 2001 From: Hongguang Date: Thu, 29 Jul 2021 18:42:13 -0700 Subject: [PATCH 778/790] Generate fmq java-source. Add @hide to adil to avoid API export in framework. Bug: 194739778 Test: make and use fmq java-source in framework Change-Id: Ie1f7e8f9a36a1f09258581d484843f372f56e03e Merged-In: Ie1f7e8f9a36a1f09258581d484843f372f56e03e --- common/fmq/aidl/Android.bp | 1 + common/fmq/aidl/aidl_api/android.hardware.common.fmq/1/.hash | 1 + .../1/android/hardware/common/fmq/GrantorDescriptor.aidl | 1 + .../1/android/hardware/common/fmq/MQDescriptor.aidl | 1 + .../1/android/hardware/common/fmq/SynchronizedReadWrite.aidl | 1 + .../1/android/hardware/common/fmq/UnsynchronizedWrite.aidl | 1 + .../current/android/hardware/common/fmq/GrantorDescriptor.aidl | 1 + .../current/android/hardware/common/fmq/MQDescriptor.aidl | 1 + .../android/hardware/common/fmq/SynchronizedReadWrite.aidl | 1 + .../current/android/hardware/common/fmq/UnsynchronizedWrite.aidl | 1 + .../fmq/aidl/android/hardware/common/fmq/GrantorDescriptor.aidl | 1 + common/fmq/aidl/android/hardware/common/fmq/MQDescriptor.aidl | 1 + .../aidl/android/hardware/common/fmq/SynchronizedReadWrite.aidl | 1 + .../aidl/android/hardware/common/fmq/UnsynchronizedWrite.aidl | 1 + 14 files changed, 14 insertions(+) diff --git a/common/fmq/aidl/Android.bp b/common/fmq/aidl/Android.bp index 4b38241e03..3c414e7876 100644 --- a/common/fmq/aidl/Android.bp +++ b/common/fmq/aidl/Android.bp @@ -25,6 +25,7 @@ aidl_interface { backend: { java: { sdk_version: "module_current", + srcs_available: true, }, cpp: { enabled: false, diff --git a/common/fmq/aidl/aidl_api/android.hardware.common.fmq/1/.hash b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/1/.hash index da122e601c..b88c5fcacb 100644 --- a/common/fmq/aidl/aidl_api/android.hardware.common.fmq/1/.hash +++ b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/1/.hash @@ -1 +1,2 @@ 12cf0ce8614557cc0efe73bdf011f5193f7a8653 +6a780550f6e6965d6969fd7964c3ca81b6b0ccdf diff --git a/common/fmq/aidl/aidl_api/android.hardware.common.fmq/1/android/hardware/common/fmq/GrantorDescriptor.aidl b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/1/android/hardware/common/fmq/GrantorDescriptor.aidl index cf7048bc02..0430c6e65c 100644 --- a/common/fmq/aidl/aidl_api/android.hardware.common.fmq/1/android/hardware/common/fmq/GrantorDescriptor.aidl +++ b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/1/android/hardware/common/fmq/GrantorDescriptor.aidl @@ -32,6 +32,7 @@ // later when a module using the interface is updated, e.g., Mainline modules. package android.hardware.common.fmq; +/* @hide */ @VintfStability parcelable GrantorDescriptor { int fdIndex; diff --git a/common/fmq/aidl/aidl_api/android.hardware.common.fmq/1/android/hardware/common/fmq/MQDescriptor.aidl b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/1/android/hardware/common/fmq/MQDescriptor.aidl index add4b64cf1..ab3af0f5d0 100644 --- a/common/fmq/aidl/aidl_api/android.hardware.common.fmq/1/android/hardware/common/fmq/MQDescriptor.aidl +++ b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/1/android/hardware/common/fmq/MQDescriptor.aidl @@ -32,6 +32,7 @@ // later when a module using the interface is updated, e.g., Mainline modules. package android.hardware.common.fmq; +/* @hide */ @VintfStability parcelable MQDescriptor { android.hardware.common.fmq.GrantorDescriptor[] grantors; diff --git a/common/fmq/aidl/aidl_api/android.hardware.common.fmq/1/android/hardware/common/fmq/SynchronizedReadWrite.aidl b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/1/android/hardware/common/fmq/SynchronizedReadWrite.aidl index 12c61bab2e..72bab1c6e2 100644 --- a/common/fmq/aidl/aidl_api/android.hardware.common.fmq/1/android/hardware/common/fmq/SynchronizedReadWrite.aidl +++ b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/1/android/hardware/common/fmq/SynchronizedReadWrite.aidl @@ -32,6 +32,7 @@ // later when a module using the interface is updated, e.g., Mainline modules. package android.hardware.common.fmq; +/* @hide */ @VintfStability enum SynchronizedReadWrite { EMPTY = 0, diff --git a/common/fmq/aidl/aidl_api/android.hardware.common.fmq/1/android/hardware/common/fmq/UnsynchronizedWrite.aidl b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/1/android/hardware/common/fmq/UnsynchronizedWrite.aidl index f99528d398..f3086881cb 100644 --- a/common/fmq/aidl/aidl_api/android.hardware.common.fmq/1/android/hardware/common/fmq/UnsynchronizedWrite.aidl +++ b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/1/android/hardware/common/fmq/UnsynchronizedWrite.aidl @@ -32,6 +32,7 @@ // later when a module using the interface is updated, e.g., Mainline modules. package android.hardware.common.fmq; +/* @hide */ @VintfStability enum UnsynchronizedWrite { EMPTY = 0, diff --git a/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/GrantorDescriptor.aidl b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/GrantorDescriptor.aidl index cf7048bc02..0430c6e65c 100644 --- a/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/GrantorDescriptor.aidl +++ b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/GrantorDescriptor.aidl @@ -32,6 +32,7 @@ // later when a module using the interface is updated, e.g., Mainline modules. package android.hardware.common.fmq; +/* @hide */ @VintfStability parcelable GrantorDescriptor { int fdIndex; diff --git a/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/MQDescriptor.aidl b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/MQDescriptor.aidl index add4b64cf1..ab3af0f5d0 100644 --- a/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/MQDescriptor.aidl +++ b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/MQDescriptor.aidl @@ -32,6 +32,7 @@ // later when a module using the interface is updated, e.g., Mainline modules. package android.hardware.common.fmq; +/* @hide */ @VintfStability parcelable MQDescriptor { android.hardware.common.fmq.GrantorDescriptor[] grantors; diff --git a/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/SynchronizedReadWrite.aidl b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/SynchronizedReadWrite.aidl index 12c61bab2e..72bab1c6e2 100644 --- a/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/SynchronizedReadWrite.aidl +++ b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/SynchronizedReadWrite.aidl @@ -32,6 +32,7 @@ // later when a module using the interface is updated, e.g., Mainline modules. package android.hardware.common.fmq; +/* @hide */ @VintfStability enum SynchronizedReadWrite { EMPTY = 0, diff --git a/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/UnsynchronizedWrite.aidl b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/UnsynchronizedWrite.aidl index f99528d398..f3086881cb 100644 --- a/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/UnsynchronizedWrite.aidl +++ b/common/fmq/aidl/aidl_api/android.hardware.common.fmq/current/android/hardware/common/fmq/UnsynchronizedWrite.aidl @@ -32,6 +32,7 @@ // later when a module using the interface is updated, e.g., Mainline modules. package android.hardware.common.fmq; +/* @hide */ @VintfStability enum UnsynchronizedWrite { EMPTY = 0, diff --git a/common/fmq/aidl/android/hardware/common/fmq/GrantorDescriptor.aidl b/common/fmq/aidl/android/hardware/common/fmq/GrantorDescriptor.aidl index 672415e65a..c6ca470e91 100644 --- a/common/fmq/aidl/android/hardware/common/fmq/GrantorDescriptor.aidl +++ b/common/fmq/aidl/android/hardware/common/fmq/GrantorDescriptor.aidl @@ -18,6 +18,7 @@ package android.hardware.common.fmq; /* * Included in MQDescriptor, for use with libfmq. + * @hide */ @VintfStability parcelable GrantorDescriptor { diff --git a/common/fmq/aidl/android/hardware/common/fmq/MQDescriptor.aidl b/common/fmq/aidl/android/hardware/common/fmq/MQDescriptor.aidl index 46622f00a9..f2fcb313b7 100644 --- a/common/fmq/aidl/android/hardware/common/fmq/MQDescriptor.aidl +++ b/common/fmq/aidl/android/hardware/common/fmq/MQDescriptor.aidl @@ -26,6 +26,7 @@ import android.hardware.common.fmq.GrantorDescriptor; * T - is used to specify the type of the payload * Flavor - is used to specify the type of the queue using * android.hardware.common.SynchronizedReadWrite or UnsynchronizedWrite + * @hide */ @VintfStability parcelable MQDescriptor { diff --git a/common/fmq/aidl/android/hardware/common/fmq/SynchronizedReadWrite.aidl b/common/fmq/aidl/android/hardware/common/fmq/SynchronizedReadWrite.aidl index 8c334423e0..8b1d0a1177 100644 --- a/common/fmq/aidl/android/hardware/common/fmq/SynchronizedReadWrite.aidl +++ b/common/fmq/aidl/android/hardware/common/fmq/SynchronizedReadWrite.aidl @@ -20,6 +20,7 @@ package android.hardware.common.fmq; * For use with android.hardware.common.MQDescriptor to specify which type of * queue to use. SynchronizedReadWrite is single reader, single writer, with no * overflow. All messages written need to be read. + * @hide */ @VintfStability enum SynchronizedReadWrite { diff --git a/common/fmq/aidl/android/hardware/common/fmq/UnsynchronizedWrite.aidl b/common/fmq/aidl/android/hardware/common/fmq/UnsynchronizedWrite.aidl index 24c4cce74c..5fe48c88d3 100644 --- a/common/fmq/aidl/android/hardware/common/fmq/UnsynchronizedWrite.aidl +++ b/common/fmq/aidl/android/hardware/common/fmq/UnsynchronizedWrite.aidl @@ -20,6 +20,7 @@ package android.hardware.common.fmq; * For use with android.hardware.common.MQDescriptor to specify which type of * queue to use. UnsynchronizedWrite is single writer, multiple reader, with * overflow. If messages are not read fast enough, they can be overwritten. + * @hide */ @VintfStability enum UnsynchronizedWrite { -- GitLab From 237a6ea5eab4be6500cb447b7f6712ab145f032b Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Thu, 5 Aug 2021 11:29:18 +0800 Subject: [PATCH 779/790] wifi: use 1.4 ISupplicant object for 1.4 vts tests This would ensure that 1.4 vts tests are run with ISupplicant 1.4 support. Bug: 194979754 Test: atest VtsHalWifiSupplicantV1_4TargetTest Change-Id: Ifaa3e1bb27f1df350b83fb7a4c05b6251a7c2d10 --- .../1.4/vts/functional/supplicant_sta_network_hidl_test.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wifi/supplicant/1.4/vts/functional/supplicant_sta_network_hidl_test.cpp b/wifi/supplicant/1.4/vts/functional/supplicant_sta_network_hidl_test.cpp index e3fbaf36f1..49d471bbc4 100644 --- a/wifi/supplicant/1.4/vts/functional/supplicant_sta_network_hidl_test.cpp +++ b/wifi/supplicant/1.4/vts/functional/supplicant_sta_network_hidl_test.cpp @@ -155,5 +155,6 @@ INSTANTIATE_TEST_CASE_P( testing::ValuesIn( android::hardware::getAllHalInstanceNames(IWifi::descriptor)), testing::ValuesIn(android::hardware::getAllHalInstanceNames( - ISupplicant::descriptor))), + android::hardware::wifi::supplicant::V1_4::ISupplicant:: + descriptor))), android::hardware::PrintInstanceTupleNameToString<>); -- GitLab From d55d28a1d0797fc3d3cbe8f843186383f9139ae7 Mon Sep 17 00:00:00 2001 From: Jiyong Park Date: Mon, 9 Aug 2021 09:47:37 +0900 Subject: [PATCH 780/790] Remove ndk_platform backend. Use the ndk backend. The ndk_platform backend will soon be deprecated because the ndk backend can serve the same purpose. This is to eliminate the confusion about having two variants (ndk and ndk_platform) for the same ndk backend. Bug: 161456198 Test: m Merged-In: I0652f1efe920111d79dd8c2ecd52e55dda54538f Change-Id: Ib58c9f1cb80d083a3c62d03415610be855b80f03 (cherry picked from commit c426c6dbdc8db86cc35d15cca6fb2b703280e4c2) --- automotive/audiocontrol/aidl/default/Android.bp | 4 ++-- automotive/vehicle/2.0/default/Android.bp | 2 +- biometrics/face/aidl/default/Android.bp | 4 ++-- biometrics/face/aidl/vts/Android.bp | 8 ++++---- biometrics/fingerprint/aidl/default/Android.bp | 4 ++-- biometrics/fingerprint/aidl/vts/Android.bp | 6 +++--- gnss/1.1/default/Android.bp | 2 +- gnss/2.0/default/Android.bp | 2 +- gnss/2.1/default/Android.bp | 2 +- gnss/aidl/default/Android.bp | 2 +- gnss/common/utils/default/Android.bp | 2 +- power/aidl/default/Android.bp | 2 +- power/aidl/vts/Android.bp | 2 +- tests/extension/vibrator/aidl/client/Android.bp | 4 ++-- tests/extension/vibrator/aidl/default/Android.bp | 4 ++-- vibrator/aidl/default/Android.bp | 4 ++-- 16 files changed, 27 insertions(+), 27 deletions(-) diff --git a/automotive/audiocontrol/aidl/default/Android.bp b/automotive/audiocontrol/aidl/default/Android.bp index 7694bdf160..1439cce606 100644 --- a/automotive/audiocontrol/aidl/default/Android.bp +++ b/automotive/audiocontrol/aidl/default/Android.bp @@ -29,8 +29,8 @@ cc_binary { vendor: true, shared_libs: [ "android.hardware.audio.common@7.0-enums", - "android.frameworks.automotive.powerpolicy-V1-ndk_platform", - "android.hardware.automotive.audiocontrol-V1-ndk_platform", + "android.frameworks.automotive.powerpolicy-V1-ndk", + "android.hardware.automotive.audiocontrol-V1-ndk", "libbase", "libbinder_ndk", "libcutils", diff --git a/automotive/vehicle/2.0/default/Android.bp b/automotive/vehicle/2.0/default/Android.bp index ffa0c13958..869c0c9124 100644 --- a/automotive/vehicle/2.0/default/Android.bp +++ b/automotive/vehicle/2.0/default/Android.bp @@ -41,7 +41,7 @@ cc_defaults { defaults: ["vhal_v2_0_defaults"], shared_libs: [ "libbinder_ndk", - "android.automotive.watchdog-V2-ndk_platform", + "android.automotive.watchdog-V2-ndk", ], } diff --git a/biometrics/face/aidl/default/Android.bp b/biometrics/face/aidl/default/Android.bp index d72411e6e2..509231859d 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_platform", - "android.hardware.biometrics.common-V1-ndk_platform", + "android.hardware.biometrics.face-V1-ndk", + "android.hardware.biometrics.common-V1-ndk", ], srcs: [ "main.cpp", diff --git a/biometrics/face/aidl/vts/Android.bp b/biometrics/face/aidl/vts/Android.bp index 99c8c99488..09ec4d06e3 100644 --- a/biometrics/face/aidl/vts/Android.bp +++ b/biometrics/face/aidl/vts/Android.bp @@ -15,10 +15,10 @@ cc_test { ], srcs: ["VtsHalBiometricsFaceTargetTest.cpp"], static_libs: [ - "android.hardware.biometrics.common-V1-ndk_platform", - "android.hardware.biometrics.face-V1-ndk_platform", - "android.hardware.common-V2-ndk_platform", - "android.hardware.keymaster-V3-ndk_platform", + "android.hardware.biometrics.common-V1-ndk", + "android.hardware.biometrics.face-V1-ndk", + "android.hardware.common-V2-ndk", + "android.hardware.keymaster-V3-ndk", ], shared_libs: [ "libbinder_ndk", diff --git a/biometrics/fingerprint/aidl/default/Android.bp b/biometrics/fingerprint/aidl/default/Android.bp index 80e6e02cf1..08fe4b04b7 100644 --- a/biometrics/fingerprint/aidl/default/Android.bp +++ b/biometrics/fingerprint/aidl/default/Android.bp @@ -24,8 +24,8 @@ cc_binary { shared_libs: [ "libbase", "libbinder_ndk", - "android.hardware.biometrics.fingerprint-V1-ndk_platform", - "android.hardware.biometrics.common-V1-ndk_platform", + "android.hardware.biometrics.fingerprint-V1-ndk", + "android.hardware.biometrics.common-V1-ndk", ], } diff --git a/biometrics/fingerprint/aidl/vts/Android.bp b/biometrics/fingerprint/aidl/vts/Android.bp index 5539548856..30d5624144 100644 --- a/biometrics/fingerprint/aidl/vts/Android.bp +++ b/biometrics/fingerprint/aidl/vts/Android.bp @@ -15,9 +15,9 @@ cc_test { ], srcs: ["VtsHalBiometricsFingerprintTargetTest.cpp"], static_libs: [ - "android.hardware.biometrics.common-V1-ndk_platform", - "android.hardware.biometrics.fingerprint-V1-ndk_platform", - "android.hardware.keymaster-V3-ndk_platform", + "android.hardware.biometrics.common-V1-ndk", + "android.hardware.biometrics.fingerprint-V1-ndk", + "android.hardware.keymaster-V3-ndk", ], shared_libs: [ "libbinder_ndk", diff --git a/gnss/1.1/default/Android.bp b/gnss/1.1/default/Android.bp index ab87990ed1..3c9c29a7d6 100644 --- a/gnss/1.1/default/Android.bp +++ b/gnss/1.1/default/Android.bp @@ -27,7 +27,7 @@ cc_binary { "android.hardware.gnss@2.0", "android.hardware.gnss@1.1", "android.hardware.gnss@1.0", - "android.hardware.gnss-V1-ndk_platform", + "android.hardware.gnss-V1-ndk", ], static_libs: [ "android.hardware.gnss@common-default-lib", diff --git a/gnss/2.0/default/Android.bp b/gnss/2.0/default/Android.bp index 8ae9f956c4..695246ad53 100644 --- a/gnss/2.0/default/Android.bp +++ b/gnss/2.0/default/Android.bp @@ -50,7 +50,7 @@ cc_binary { "android.hardware.gnss@2.0", "android.hardware.gnss@1.1", "android.hardware.gnss@1.0", - "android.hardware.gnss-V1-ndk_platform", + "android.hardware.gnss-V1-ndk", ], static_libs: [ "android.hardware.gnss@common-default-lib", diff --git a/gnss/2.1/default/Android.bp b/gnss/2.1/default/Android.bp index 609f59e60f..c46c73545c 100644 --- a/gnss/2.1/default/Android.bp +++ b/gnss/2.1/default/Android.bp @@ -44,7 +44,7 @@ cc_binary { "android.hardware.gnss@1.0", "android.hardware.gnss@1.1", "android.hardware.gnss@2.0", - "android.hardware.gnss-V1-ndk_platform", + "android.hardware.gnss-V1-ndk", ], static_libs: [ "android.hardware.gnss@common-default-lib", diff --git a/gnss/aidl/default/Android.bp b/gnss/aidl/default/Android.bp index 4cc2b6e251..c028dd764e 100644 --- a/gnss/aidl/default/Android.bp +++ b/gnss/aidl/default/Android.bp @@ -52,7 +52,7 @@ 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-V1-ndk_platform", + "android.hardware.gnss-V1-ndk", ], srcs: [ "Gnss.cpp", diff --git a/gnss/common/utils/default/Android.bp b/gnss/common/utils/default/Android.bp index 43db8739d1..a1d3123500 100644 --- a/gnss/common/utils/default/Android.bp +++ b/gnss/common/utils/default/Android.bp @@ -52,6 +52,6 @@ cc_library_static { "android.hardware.gnss@2.1", "android.hardware.gnss.measurement_corrections@1.1", "android.hardware.gnss.measurement_corrections@1.0", - "android.hardware.gnss-V1-ndk_platform", + "android.hardware.gnss-V1-ndk", ], } diff --git a/power/aidl/default/Android.bp b/power/aidl/default/Android.bp index c0ba9a079c..e10d329cd5 100644 --- a/power/aidl/default/Android.bp +++ b/power/aidl/default/Android.bp @@ -30,7 +30,7 @@ cc_binary { shared_libs: [ "libbase", "libbinder_ndk", - "android.hardware.power-V2-ndk_platform", + "android.hardware.power-V2-ndk", ], srcs: [ "main.cpp", diff --git a/power/aidl/vts/Android.bp b/power/aidl/vts/Android.bp index 3036b8202d..eccd872716 100644 --- a/power/aidl/vts/Android.bp +++ b/power/aidl/vts/Android.bp @@ -32,7 +32,7 @@ cc_test { "libbinder_ndk", ], static_libs: [ - "android.hardware.power-V2-ndk_platform", + "android.hardware.power-V2-ndk", ], test_suites: [ "vts", diff --git a/tests/extension/vibrator/aidl/client/Android.bp b/tests/extension/vibrator/aidl/client/Android.bp index afab263b82..284ac7459b 100644 --- a/tests/extension/vibrator/aidl/client/Android.bp +++ b/tests/extension/vibrator/aidl/client/Android.bp @@ -27,7 +27,7 @@ cc_test { "android.hardware.tests.extension.vibrator-V1-cpp", "libbinder_ndk", - "android.hardware.vibrator-V2-ndk_platform", - "android.hardware.tests.extension.vibrator-V1-ndk_platform", + "android.hardware.vibrator-V2-ndk", + "android.hardware.tests.extension.vibrator-V1-ndk", ], } diff --git a/tests/extension/vibrator/aidl/default/Android.bp b/tests/extension/vibrator/aidl/default/Android.bp index a200292330..0f3895f8de 100644 --- a/tests/extension/vibrator/aidl/default/Android.bp +++ b/tests/extension/vibrator/aidl/default/Android.bp @@ -28,7 +28,7 @@ cc_binary { shared_libs: [ "libbase", "libbinder_ndk", - "android.hardware.vibrator-V2-ndk_platform", - "android.hardware.tests.extension.vibrator-V2-ndk_platform", + "android.hardware.vibrator-V2-ndk", + "android.hardware.tests.extension.vibrator-V2-ndk", ], } diff --git a/vibrator/aidl/default/Android.bp b/vibrator/aidl/default/Android.bp index d463f51511..5a65e759f0 100644 --- a/vibrator/aidl/default/Android.bp +++ b/vibrator/aidl/default/Android.bp @@ -13,7 +13,7 @@ cc_library_static { shared_libs: [ "libbase", "libbinder_ndk", - "android.hardware.vibrator-V2-ndk_platform", + "android.hardware.vibrator-V2-ndk", ], export_include_dirs: ["include"], srcs: [ @@ -35,7 +35,7 @@ cc_binary { shared_libs: [ "libbase", "libbinder_ndk", - "android.hardware.vibrator-V2-ndk_platform", + "android.hardware.vibrator-V2-ndk", ], static_libs: [ "libvibratorexampleimpl", -- GitLab From d1705d569a82a1fc67cb0beaacae50e2e8928d5b Mon Sep 17 00:00:00 2001 From: Tyler Trephan Date: Fri, 6 Aug 2021 13:27:27 -0700 Subject: [PATCH 781/790] Set the minSampleRate > 0 for continuous properties on the AAOS emulator. Test: atest CarPropertyManagerTest Bug: 194680297 Change-Id: I3b9c359885d173c89e825b206b629ed9dfa38d13 --- .../vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h index 6a0288f3a4..f09d75ba21 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h @@ -174,7 +174,7 @@ const ConfigDeclaration kVehicleProperties[]{ .prop = toInt(VehicleProperty::PERF_ODOMETER), .access = VehiclePropertyAccess::READ, .changeMode = VehiclePropertyChangeMode::CONTINUOUS, - .minSampleRate = 0.0f, + .minSampleRate = 1.0f, .maxSampleRate = 10.0f, }, .initialValue = {.floatValues = {0.0f}}}, @@ -183,7 +183,7 @@ const ConfigDeclaration kVehicleProperties[]{ .prop = toInt(VehicleProperty::PERF_STEERING_ANGLE), .access = VehiclePropertyAccess::READ, .changeMode = VehiclePropertyChangeMode::CONTINUOUS, - .minSampleRate = 0.0f, + .minSampleRate = 1.0f, .maxSampleRate = 10.0f, }, .initialValue = {.floatValues = {0.0f}}}, @@ -192,7 +192,7 @@ const ConfigDeclaration kVehicleProperties[]{ .prop = toInt(VehicleProperty::PERF_REAR_STEERING_ANGLE), .access = VehiclePropertyAccess::READ, .changeMode = VehiclePropertyChangeMode::CONTINUOUS, - .minSampleRate = 0.0f, + .minSampleRate = 1.0f, .maxSampleRate = 10.0f, }, .initialValue = {.floatValues = {0.0f}}}, @@ -213,7 +213,7 @@ const ConfigDeclaration kVehicleProperties[]{ .prop = toInt(VehicleProperty::FUEL_LEVEL), .access = VehiclePropertyAccess::READ, .changeMode = VehiclePropertyChangeMode::CONTINUOUS, - .minSampleRate = 0.0f, + .minSampleRate = 1.0f, .maxSampleRate = 100.0f, }, .initialValue = {.floatValues = {15000.0f}}}, @@ -231,7 +231,7 @@ const ConfigDeclaration kVehicleProperties[]{ .prop = toInt(VehicleProperty::EV_BATTERY_LEVEL), .access = VehiclePropertyAccess::READ, .changeMode = VehiclePropertyChangeMode::CONTINUOUS, - .minSampleRate = 0.0f, + .minSampleRate = 1.0f, .maxSampleRate = 100.0f, }, .initialValue = {.floatValues = {150000.0f}}}, -- GitLab From e7a2d287b2abc7f8e566e7758f61b6ea6a04f291 Mon Sep 17 00:00:00 2001 From: Marin Shalamanov Date: Mon, 9 Aug 2021 17:51:12 +0200 Subject: [PATCH 782/790] Increase timeout for VtsHalGraphicsComposerV2_4TargetTest The current timout of 5 mins is not enough for setActiveConfigWithConstraints to complete on devices which have ~30 display modes and which can't do seamless switching. The test needs 8 mins to complete locally -- increasing the timeout to 15 to have some margin. Bug: 188686850 Test: atest VtsHalGraphicsComposerV2_4TargetTest Change-Id: I07cf1825c23e2467852d5cd93436eb9dee23b408 --- graphics/composer/2.4/vts/functional/AndroidTest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/graphics/composer/2.4/vts/functional/AndroidTest.xml b/graphics/composer/2.4/vts/functional/AndroidTest.xml index 583aa6866c..773db93255 100644 --- a/graphics/composer/2.4/vts/functional/AndroidTest.xml +++ b/graphics/composer/2.4/vts/functional/AndroidTest.xml @@ -31,6 +31,6 @@ -- GitLab From 2eb2d2cb097c057585386a86cde6948bf3f51e22 Mon Sep 17 00:00:00 2001 From: Shinru Han Date: Tue, 10 Aug 2021 16:53:17 +0800 Subject: [PATCH 783/790] Allow negative value for CorrelationVector#samplingStartM Bug: 195934893 Test: on cuttlefish Change-Id: Ief1514c8d8e48c9c3f13b93c3d2c355a508a84a7 (cherry picked from commit 37f63ed771ca2f4d02ac0625b0129c80549704fc) --- gnss/aidl/vts/gnss_hal_test_cases.cpp | 1 - gnss/common/utils/default/Utils.cpp | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/gnss/aidl/vts/gnss_hal_test_cases.cpp b/gnss/aidl/vts/gnss_hal_test_cases.cpp index 5964f815a8..b484f9c383 100644 --- a/gnss/aidl/vts/gnss_hal_test_cases.cpp +++ b/gnss/aidl/vts/gnss_hal_test_cases.cpp @@ -252,7 +252,6 @@ TEST_P(GnssHalTest, TestCorrelationVector) { for (const auto& correlationVector : measurement.correlationVectors) { ASSERT_GE(correlationVector.frequencyOffsetMps, 0); ASSERT_GT(correlationVector.samplingWidthM, 0); - ASSERT_GE(correlationVector.samplingStartM, 0); ASSERT_TRUE(correlationVector.magnitude.size() > 0); for (const auto& magnitude : correlationVector.magnitude) { ASSERT_TRUE(magnitude >= -32768 && magnitude <= 32767); diff --git a/gnss/common/utils/default/Utils.cpp b/gnss/common/utils/default/Utils.cpp index d136448ed9..23e39b26ec 100644 --- a/gnss/common/utils/default/Utils.cpp +++ b/gnss/common/utils/default/Utils.cpp @@ -221,7 +221,7 @@ GnssData Utils::getMockMeasurement(const bool enableCorrVecOutputs) { aidl::android::hardware::gnss::CorrelationVector correlationVector2 = { .frequencyOffsetMps = 20, .samplingWidthM = 30, - .samplingStartM = 0, + .samplingStartM = -10, .magnitude = {0, 3000, 5000, 3000, 0, 0, 1000, 0}}; measurement.correlationVectors = {correlationVector1, correlationVector2}; measurement.flags |= GnssMeasurement::HAS_CORRELATION_VECTOR; -- GitLab From 21d67fc673165429eaba4b62435920c863699b87 Mon Sep 17 00:00:00 2001 From: Michael Butler Date: Mon, 23 Aug 2021 18:14:50 -0700 Subject: [PATCH 784/790] Quick-fail NNAPI VTS test case if driver is dead This CL adds a check during SetUp that an NNAPI driver service is still alive by pinging the driver service. If it is not alive, the test will fail during SetUp. Without this quick-fail, the test case would continue as if the driver were still active, which would result in multiple EXPECT_* and ASSERT_* statements failing instead of a single, clear failure message. Bug: 197035200 Test: mma Test: presubmit: VtsHalNeuralnetworks*TargetTest Change-Id: Ib1b75ed20f764055699590581d5ad4e5aff4baae Merged-In: Ib1b75ed20f764055699590581d5ad4e5aff4baae (cherry picked from commit 9c3c8642fba1a85f7cdcd1a30a6f82fdc0025b40) (cherry picked from commit 669dbab452f059d63a33bfe0b6b02c8b3ca9a7b8) --- neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp | 2 ++ neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworks.cpp | 2 ++ neuralnetworks/1.1/vts/functional/GeneratedTestHarness.cpp | 2 ++ neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworks.cpp | 2 ++ neuralnetworks/1.2/vts/functional/CompilationCachingTests.cpp | 2 ++ neuralnetworks/1.2/vts/functional/GeneratedTestHarness.cpp | 2 ++ neuralnetworks/1.2/vts/functional/VtsHalNeuralnetworks.cpp | 2 ++ neuralnetworks/1.3/vts/functional/CompilationCachingTests.cpp | 2 ++ neuralnetworks/1.3/vts/functional/GeneratedTestHarness.cpp | 2 ++ neuralnetworks/1.3/vts/functional/MemoryDomainTests.cpp | 2 ++ neuralnetworks/1.3/vts/functional/VtsHalNeuralnetworks.cpp | 2 ++ neuralnetworks/aidl/vts/functional/CompilationCachingTests.cpp | 3 +++ neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp | 3 +++ neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp | 3 +++ neuralnetworks/aidl/vts/functional/VtsHalNeuralnetworks.cpp | 3 +++ 15 files changed, 34 insertions(+) diff --git a/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp index ae1e3a220d..2ef66c20e6 100644 --- a/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp +++ b/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp @@ -154,6 +154,8 @@ void Execute(const sp& device, const TestModel& testModel) { void GeneratedTestBase::SetUp() { testing::TestWithParam::SetUp(); ASSERT_NE(kDevice, nullptr); + const bool deviceIsResponsive = kDevice->ping().isOk(); + ASSERT_TRUE(deviceIsResponsive); } std::vector getNamedModels(const FilterFn& filter) { diff --git a/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworks.cpp b/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworks.cpp index 2c17796f2e..e2c0511441 100644 --- a/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworks.cpp +++ b/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworks.cpp @@ -81,6 +81,8 @@ void createPreparedModel(const sp& device, const Model& model, void NeuralnetworksHidlTest::SetUp() { testing::TestWithParam::SetUp(); ASSERT_NE(kDevice, nullptr); + const bool deviceIsResponsive = kDevice->ping().isOk(); + ASSERT_TRUE(deviceIsResponsive); } static NamedDevice makeNamedDevice(const std::string& name) { diff --git a/neuralnetworks/1.1/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/1.1/vts/functional/GeneratedTestHarness.cpp index a2338350aa..faf7bb47ce 100644 --- a/neuralnetworks/1.1/vts/functional/GeneratedTestHarness.cpp +++ b/neuralnetworks/1.1/vts/functional/GeneratedTestHarness.cpp @@ -162,6 +162,8 @@ void Execute(const sp& device, const TestModel& testModel) { void GeneratedTestBase::SetUp() { testing::TestWithParam::SetUp(); ASSERT_NE(kDevice, nullptr); + const bool deviceIsResponsive = kDevice->ping().isOk(); + ASSERT_TRUE(deviceIsResponsive); } std::vector getNamedModels(const FilterFn& filter) { diff --git a/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworks.cpp b/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworks.cpp index 54e8802a54..613b828ef1 100644 --- a/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworks.cpp +++ b/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworks.cpp @@ -84,6 +84,8 @@ void createPreparedModel(const sp& device, const Model& model, void NeuralnetworksHidlTest::SetUp() { testing::TestWithParam::SetUp(); ASSERT_NE(kDevice, nullptr); + const bool deviceIsResponsive = kDevice->ping().isOk(); + ASSERT_TRUE(deviceIsResponsive); } static NamedDevice makeNamedDevice(const std::string& name) { diff --git a/neuralnetworks/1.2/vts/functional/CompilationCachingTests.cpp b/neuralnetworks/1.2/vts/functional/CompilationCachingTests.cpp index ede1600090..3d783d9aa1 100644 --- a/neuralnetworks/1.2/vts/functional/CompilationCachingTests.cpp +++ b/neuralnetworks/1.2/vts/functional/CompilationCachingTests.cpp @@ -225,6 +225,8 @@ class CompilationCachingTestBase : public testing::Test { void SetUp() override { testing::Test::SetUp(); ASSERT_NE(kDevice.get(), nullptr); + const bool deviceIsResponsive = kDevice->ping().isOk(); + ASSERT_TRUE(deviceIsResponsive); // Create cache directory. The cache directory and a temporary cache file is always created // to test the behavior of prepareModelFromCache, even when caching is not supported. diff --git a/neuralnetworks/1.2/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/1.2/vts/functional/GeneratedTestHarness.cpp index 56f3c0b7e2..9fa139a2a8 100644 --- a/neuralnetworks/1.2/vts/functional/GeneratedTestHarness.cpp +++ b/neuralnetworks/1.2/vts/functional/GeneratedTestHarness.cpp @@ -384,6 +384,8 @@ void Execute(const sp& device, const TestModel& testModel, bool testDyn void GeneratedTestBase::SetUp() { testing::TestWithParam::SetUp(); ASSERT_NE(kDevice, nullptr); + const bool deviceIsResponsive = kDevice->ping().isOk(); + ASSERT_TRUE(deviceIsResponsive); } std::vector getNamedModels(const FilterFn& filter) { diff --git a/neuralnetworks/1.2/vts/functional/VtsHalNeuralnetworks.cpp b/neuralnetworks/1.2/vts/functional/VtsHalNeuralnetworks.cpp index a60ec4d1d2..729d584863 100644 --- a/neuralnetworks/1.2/vts/functional/VtsHalNeuralnetworks.cpp +++ b/neuralnetworks/1.2/vts/functional/VtsHalNeuralnetworks.cpp @@ -87,6 +87,8 @@ void createPreparedModel(const sp& device, const Model& model, void NeuralnetworksHidlTest::SetUp() { testing::TestWithParam::SetUp(); ASSERT_NE(kDevice, nullptr); + const bool deviceIsResponsive = kDevice->ping().isOk(); + ASSERT_TRUE(deviceIsResponsive); } static NamedDevice makeNamedDevice(const std::string& name) { diff --git a/neuralnetworks/1.3/vts/functional/CompilationCachingTests.cpp b/neuralnetworks/1.3/vts/functional/CompilationCachingTests.cpp index edffa22cca..a2013ecd3a 100644 --- a/neuralnetworks/1.3/vts/functional/CompilationCachingTests.cpp +++ b/neuralnetworks/1.3/vts/functional/CompilationCachingTests.cpp @@ -228,6 +228,8 @@ class CompilationCachingTestBase : public testing::Test { void SetUp() override { testing::Test::SetUp(); ASSERT_NE(kDevice.get(), nullptr); + const bool deviceIsResponsive = kDevice->ping().isOk(); + ASSERT_TRUE(deviceIsResponsive); // Create cache directory. The cache directory and a temporary cache file is always created // to test the behavior of prepareModelFromCache_1_3, even when caching is not supported. diff --git a/neuralnetworks/1.3/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/1.3/vts/functional/GeneratedTestHarness.cpp index 0a956958f9..6d30d85f1b 100644 --- a/neuralnetworks/1.3/vts/functional/GeneratedTestHarness.cpp +++ b/neuralnetworks/1.3/vts/functional/GeneratedTestHarness.cpp @@ -926,6 +926,8 @@ void Execute(const sp& device, const TestModel& testModel, TestKind tes void GeneratedTestBase::SetUp() { testing::TestWithParam::SetUp(); ASSERT_NE(kDevice, nullptr); + const bool deviceIsResponsive = kDevice->ping().isOk(); + ASSERT_TRUE(deviceIsResponsive); } std::vector getNamedModels(const FilterFn& filter) { diff --git a/neuralnetworks/1.3/vts/functional/MemoryDomainTests.cpp b/neuralnetworks/1.3/vts/functional/MemoryDomainTests.cpp index 5facc5ee96..e2fa6e4d42 100644 --- a/neuralnetworks/1.3/vts/functional/MemoryDomainTests.cpp +++ b/neuralnetworks/1.3/vts/functional/MemoryDomainTests.cpp @@ -243,6 +243,8 @@ class MemoryDomainTestBase : public testing::Test { void SetUp() override { testing::Test::SetUp(); ASSERT_NE(kDevice, nullptr); + const bool deviceIsResponsive = kDevice->ping().isOk(); + ASSERT_TRUE(deviceIsResponsive); } sp createConvPreparedModel(const TestOperand& testOperand, diff --git a/neuralnetworks/1.3/vts/functional/VtsHalNeuralnetworks.cpp b/neuralnetworks/1.3/vts/functional/VtsHalNeuralnetworks.cpp index df1e4535be..eb8cb4bc6d 100644 --- a/neuralnetworks/1.3/vts/functional/VtsHalNeuralnetworks.cpp +++ b/neuralnetworks/1.3/vts/functional/VtsHalNeuralnetworks.cpp @@ -92,6 +92,8 @@ void createPreparedModel(const sp& device, const Model& model, void NeuralnetworksHidlTest::SetUp() { testing::TestWithParam::SetUp(); ASSERT_NE(kDevice, nullptr); + const bool deviceIsResponsive = kDevice->ping().isOk(); + ASSERT_TRUE(deviceIsResponsive); } static NamedDevice makeNamedDevice(const std::string& name) { diff --git a/neuralnetworks/aidl/vts/functional/CompilationCachingTests.cpp b/neuralnetworks/aidl/vts/functional/CompilationCachingTests.cpp index 94ce5c1130..77208aaf87 100644 --- a/neuralnetworks/aidl/vts/functional/CompilationCachingTests.cpp +++ b/neuralnetworks/aidl/vts/functional/CompilationCachingTests.cpp @@ -223,6 +223,9 @@ class CompilationCachingTestBase : public testing::Test { void SetUp() override { testing::Test::SetUp(); ASSERT_NE(kDevice.get(), nullptr); + const bool deviceIsResponsive = + ndk::ScopedAStatus::fromStatus(AIBinder_ping(kDevice->asBinder().get())).isOk(); + ASSERT_TRUE(deviceIsResponsive); // Create cache directory. The cache directory and a temporary cache file is always created // to test the behavior of prepareModelFromCache, even when caching is not supported. diff --git a/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp index 2356ff0520..ac5b96a8a4 100644 --- a/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp +++ b/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp @@ -904,6 +904,9 @@ void Execute(const std::shared_ptr& device, const TestModel& testModel, void GeneratedTestBase::SetUp() { testing::TestWithParam::SetUp(); ASSERT_NE(kDevice, nullptr); + const bool deviceIsResponsive = + ndk::ScopedAStatus::fromStatus(AIBinder_ping(kDevice->asBinder().get())).isOk(); + ASSERT_TRUE(deviceIsResponsive); } std::vector getNamedModels(const FilterFn& filter) { diff --git a/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp b/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp index e8313f19eb..1819699ab2 100644 --- a/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp +++ b/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp @@ -233,6 +233,9 @@ class MemoryDomainTestBase : public testing::Test { void SetUp() override { testing::Test::SetUp(); ASSERT_NE(kDevice, nullptr); + const bool deviceIsResponsive = + ndk::ScopedAStatus::fromStatus(AIBinder_ping(kDevice->asBinder().get())).isOk(); + ASSERT_TRUE(deviceIsResponsive); } std::shared_ptr createConvPreparedModel(const TestOperand& testOperand, diff --git a/neuralnetworks/aidl/vts/functional/VtsHalNeuralnetworks.cpp b/neuralnetworks/aidl/vts/functional/VtsHalNeuralnetworks.cpp index ee7cf89d4f..c417356005 100644 --- a/neuralnetworks/aidl/vts/functional/VtsHalNeuralnetworks.cpp +++ b/neuralnetworks/aidl/vts/functional/VtsHalNeuralnetworks.cpp @@ -91,6 +91,9 @@ void createPreparedModel(const std::shared_ptr& device, const Model& mo void NeuralNetworksAidlTest::SetUp() { testing::TestWithParam::SetUp(); ASSERT_NE(kDevice, nullptr); + const bool deviceIsResponsive = + ndk::ScopedAStatus::fromStatus(AIBinder_ping(kDevice->asBinder().get())).isOk(); + ASSERT_TRUE(deviceIsResponsive); } static NamedDevice makeNamedDevice(const std::string& name) { -- GitLab From 50dd1b9e930f96e04b4546e22989f7aa8ff52722 Mon Sep 17 00:00:00 2001 From: Michael Butler Date: Tue, 24 Aug 2021 23:25:45 -0700 Subject: [PATCH 785/790] Quickly exit VtsHalNeuralnetworks*TargetTest on failure This change adds the AndroidTest.xml flag --gtest_break_on_failure to cause the gtest to terminate after an error has been reached. This early termination is important in the case where an NN HAL service crashes mid-test, and all remaining tests would otherwise continue to run. Bug: 197035200 Test: m vts -j Test: vts-tradefed Change-Id: I0b9a14345475e432b93f92c23010a8b39712443a Merged-In: I0b9a14345475e432b93f92c23010a8b39712443a (cherry picked from commit ac45a5d77ea1a466aa73a5e4ca0a07c1db4f8fc6) (cherry picked from commit 535f8c809874da71efddb838e01f4d2e95b1971e) --- neuralnetworks/1.0/vts/functional/AndroidTest.xml | 1 + neuralnetworks/1.1/vts/functional/AndroidTest.xml | 1 + neuralnetworks/1.2/vts/functional/AndroidTest.xml | 1 + neuralnetworks/1.3/vts/functional/AndroidTest.xml | 1 + neuralnetworks/aidl/vts/functional/AndroidTest.xml | 1 + 5 files changed, 5 insertions(+) diff --git a/neuralnetworks/1.0/vts/functional/AndroidTest.xml b/neuralnetworks/1.0/vts/functional/AndroidTest.xml index 9dd85ae7f1..8f56ff9c1f 100644 --- a/neuralnetworks/1.0/vts/functional/AndroidTest.xml +++ b/neuralnetworks/1.0/vts/functional/AndroidTest.xml @@ -29,5 +29,6 @@
    + + android.hardware.radio + 1 + + IRadio + slot1 + slot2 + slot3 + + android.hardware.radio 1.6 diff --git a/radio/aidl/Android.bp b/radio/aidl/Android.bp new file mode 100644 index 0000000000..29d7a58471 --- /dev/null +++ b/radio/aidl/Android.bp @@ -0,0 +1,54 @@ +aidl_interface { + name: "android.hardware.radio", + vendor_available: true, + srcs: ["android/hardware/radio/*.aidl"], + stability: "vintf", + backend: { + cpp: { + enabled: false, + }, + java: { + sdk_version: "module_current", + }, + ndk: { + vndk: { + enabled: true, + }, + }, + }, +} + +cc_library { + name: "android.hardware.radio-translate-ndk", + vendor_available: true, + srcs: ["android/hardware/radio/translate-ndk.cpp"], + shared_libs: [ + "libbinder_ndk", + "libhidlbase", + "android.hardware.radio-V1-ndk_platform", + "android.hardware.radio@1.0", + "android.hardware.radio@1.1", + "android.hardware.radio@1.2", + "android.hardware.radio@1.3", + "android.hardware.radio@1.4", + "android.hardware.radio@1.5", + "android.hardware.radio@1.6", + ], + export_include_dirs: ["include"], +} + +java_library { + name: "android.hardware.radio-translate-java", + srcs: ["android/hardware/radio/Translate.java"], + libs: [ + "android.hardware.radio-V1-java", + "android.hardware.radio-V1.0-java", + "android.hardware.radio-V1.1-java", + "android.hardware.radio-V1.2-java", + "android.hardware.radio-V1.3-java", + "android.hardware.radio-V1.4-java", + "android.hardware.radio-V1.5-java", + "android.hardware.radio-V1.6-java", + ], + sdk_version: "module_current", +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/AccessNetwork.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/AccessNetwork.aidl new file mode 100644 index 0000000000..0327d6c19d --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/AccessNetwork.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 -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.radio; +@Backing(type="int") @VintfStability +enum AccessNetwork { + UNKNOWN = 0, + GERAN = 1, + UTRAN = 2, + EUTRAN = 3, + CDMA2000 = 4, + IWLAN = 5, + NGRAN = 6, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ActivityStatsInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ActivityStatsInfo.aidl new file mode 100644 index 0000000000..f9ef742549 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ActivityStatsInfo.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 -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.radio; +@VintfStability +parcelable ActivityStatsInfo { + int sleepModeTimeMs; + int idleModeTimeMs; + int[] txmModetimeMs; + int rxModeTimeMs; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/AddressProperty.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/AddressProperty.aidl new file mode 100644 index 0000000000..dd6e79a1c1 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/AddressProperty.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 -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.radio; +@Backing(type="int") @VintfStability +enum AddressProperty { + NONE = 0, + DEPRECATED = 32, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ApnAuthType.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ApnAuthType.aidl new file mode 100644 index 0000000000..bae7d1f261 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ApnAuthType.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 -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.radio; +@Backing(type="int") @VintfStability +enum ApnAuthType { + NO_PAP_NO_CHAP = 0, + PAP_NO_CHAP = 1, + NO_PAP_CHAP = 2, + PAP_CHAP = 3, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ApnTypes.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ApnTypes.aidl new file mode 100644 index 0000000000..0829fa619f --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ApnTypes.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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.radio; +@Backing(type="int") @VintfStability +enum ApnTypes { + NONE = 0, + DEFAULT = 1, + MMS = 2, + SUPL = 4, + DUN = 8, + HIPRI = 16, + FOTA = 32, + IMS = 64, + CBS = 128, + IA = 256, + EMERGENCY = 512, + ALL = 1023, + MCX = 1024, + XCAP = 2048, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/AppState.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/AppState.aidl new file mode 100644 index 0000000000..59e2bd43ce --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/AppState.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 -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.radio; +@Backing(type="int") @VintfStability +enum AppState { + UNKNOWN = 0, + DETECTED = 1, + PIN = 2, + PUK = 3, + SUBSCRIPTION_PERSO = 4, + READY = 5, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/AppStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/AppStatus.aidl new file mode 100644 index 0000000000..c9abe3263c --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/AppStatus.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 -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.radio; +@VintfStability +parcelable AppStatus { + android.hardware.radio.AppType appType; + android.hardware.radio.AppState appState; + android.hardware.radio.PersoSubstate persoSubstate; + String aidPtr; + String appLabelPtr; + int pin1Replaced; + android.hardware.radio.PinState pin1; + android.hardware.radio.PinState pin2; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/AppType.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/AppType.aidl new file mode 100644 index 0000000000..adbbe9f002 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/AppType.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 -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.radio; +@Backing(type="int") @VintfStability +enum AppType { + UNKNOWN = 0, + SIM = 1, + USIM = 2, + RUIM = 3, + CSIM = 4, + ISIM = 5, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/AudioQuality.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/AudioQuality.aidl new file mode 100644 index 0000000000..a596969147 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/AudioQuality.aidl @@ -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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.radio; +@Backing(type="int") @VintfStability +enum AudioQuality { + UNSPECIFIED = 0, + AMR = 1, + AMR_WB = 2, + GSM_EFR = 3, + GSM_FR = 4, + GSM_HR = 5, + EVRC = 6, + EVRC_B = 7, + EVRC_WB = 8, + EVRC_NW = 9, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/BarringInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/BarringInfo.aidl new file mode 100644 index 0000000000..ac0b4aa6da --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/BarringInfo.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 -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.radio; +@VintfStability +parcelable BarringInfo { + android.hardware.radio.BarringInfoServiceType serviceType; + android.hardware.radio.BarringInfoBarringType barringType; + android.hardware.radio.BarringInfoBarringTypeSpecificInfo barringTypeSpecificInfo; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/BarringInfoBarringType.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/BarringInfoBarringType.aidl new file mode 100644 index 0000000000..6b8006ebaa --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/BarringInfoBarringType.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 -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.radio; +@Backing(type="int") @VintfStability +enum BarringInfoBarringType { + NONE = 0, + CONDITIONAL = 1, + UNCONDITIONAL = 2, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/BarringInfoBarringTypeSpecificInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/BarringInfoBarringTypeSpecificInfo.aidl new file mode 100644 index 0000000000..c2ba1d2e2d --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/BarringInfoBarringTypeSpecificInfo.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 -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.radio; +@VintfStability +union BarringInfoBarringTypeSpecificInfo { + boolean noinit; + android.hardware.radio.BarringInfoBarringTypeSpecificInfoConditional conditional; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/BarringInfoBarringTypeSpecificInfoConditional.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/BarringInfoBarringTypeSpecificInfoConditional.aidl new file mode 100644 index 0000000000..8c079e2e3a --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/BarringInfoBarringTypeSpecificInfoConditional.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 -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.radio; +@VintfStability +parcelable BarringInfoBarringTypeSpecificInfoConditional { + int factor; + int timeSeconds; + boolean isBarred; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/BarringInfoServiceType.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/BarringInfoServiceType.aidl new file mode 100644 index 0000000000..faea9b9ab8 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/BarringInfoServiceType.aidl @@ -0,0 +1,79 @@ +/* + * 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 -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.radio; +@Backing(type="int") @VintfStability +enum BarringInfoServiceType { + CS_SERVICE = 0, + PS_SERVICE = 1, + CS_VOICE = 2, + MO_SIGNALLING = 3, + MO_DATA = 4, + CS_FALLBACK = 5, + MMTEL_VOICE = 6, + MMTEL_VIDEO = 7, + EMERGENCY = 8, + SMS = 9, + OPERATOR_1 = 1001, + OPERATOR_2 = 1002, + OPERATOR_3 = 1003, + OPERATOR_4 = 1004, + OPERATOR_5 = 1005, + OPERATOR_6 = 1006, + OPERATOR_7 = 1007, + OPERATOR_8 = 1008, + OPERATOR_9 = 1009, + OPERATOR_10 = 1010, + OPERATOR_11 = 1011, + OPERATOR_12 = 1012, + OPERATOR_13 = 1013, + OPERATOR_14 = 1014, + OPERATOR_15 = 1015, + OPERATOR_16 = 1016, + OPERATOR_17 = 1017, + OPERATOR_18 = 1018, + OPERATOR_19 = 1019, + OPERATOR_20 = 1020, + OPERATOR_21 = 1021, + OPERATOR_22 = 1022, + OPERATOR_23 = 1023, + OPERATOR_24 = 1024, + OPERATOR_25 = 1025, + OPERATOR_26 = 1026, + OPERATOR_27 = 1027, + OPERATOR_28 = 1028, + OPERATOR_29 = 1029, + OPERATOR_30 = 1030, + OPERATOR_31 = 1031, + OPERATOR_32 = 1032, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/Call.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/Call.aidl new file mode 100644 index 0000000000..36e1ae31e5 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/Call.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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.radio; +@VintfStability +parcelable Call { + android.hardware.radio.CallState state; + int index; + int toa; + boolean isMpty; + boolean isMT; + byte als; + boolean isVoice; + boolean isVoicePrivacy; + String number; + android.hardware.radio.CallPresentation numberPresentation; + String name; + android.hardware.radio.CallPresentation namePresentation; + android.hardware.radio.UusInfo[] uusInfo; + android.hardware.radio.AudioQuality audioQuality; + String forwardedNumber; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CallForwardInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CallForwardInfo.aidl new file mode 100644 index 0000000000..bcfa90fcdc --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CallForwardInfo.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 -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.radio; +@VintfStability +parcelable CallForwardInfo { + android.hardware.radio.CallForwardInfoStatus status; + int reason; + int serviceClass; + int toa; + String number; + int timeSeconds; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CallForwardInfoStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CallForwardInfoStatus.aidl new file mode 100644 index 0000000000..5ac129a0ee --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CallForwardInfoStatus.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 -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.radio; +@Backing(type="int") @VintfStability +enum CallForwardInfoStatus { + DISABLE = 0, + ENABLE = 1, + INTERROGATE = 2, + REGISTRATION = 3, + ERASURE = 4, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CallPresentation.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CallPresentation.aidl new file mode 100644 index 0000000000..c32cd08201 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CallPresentation.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 -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.radio; +@Backing(type="int") @VintfStability +enum CallPresentation { + ALLOWED = 0, + RESTRICTED = 1, + UNKNOWN = 2, + PAYPHONE = 3, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CallState.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CallState.aidl new file mode 100644 index 0000000000..375ca2c5af --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CallState.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 -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.radio; +@Backing(type="int") @VintfStability +enum CallState { + ACTIVE = 0, + HOLDING = 1, + DIALING = 2, + ALERTING = 3, + INCOMING = 4, + WAITING = 5, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CardPowerState.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CardPowerState.aidl new file mode 100644 index 0000000000..1a3b4c6295 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CardPowerState.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 -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.radio; +@Backing(type="int") @VintfStability +enum CardPowerState { + POWER_DOWN = 0, + POWER_UP = 1, + POWER_UP_PASS_THROUGH = 2, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CardState.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CardState.aidl new file mode 100644 index 0000000000..d200b9757f --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CardState.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 -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.radio; +@Backing(type="int") @VintfStability +enum CardState { + ABSENT = 0, + PRESENT = 1, + ERROR = 2, + RESTRICTED = 3, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CardStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CardStatus.aidl new file mode 100644 index 0000000000..e11bb21b5d --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CardStatus.aidl @@ -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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.radio; +@VintfStability +parcelable CardStatus { + android.hardware.radio.CardState cardState; + android.hardware.radio.PinState universalPinState; + int gsmUmtsSubscriptionAppIndex; + int cdmaSubscriptionAppIndex; + int imsSubscriptionAppIndex; + android.hardware.radio.AppStatus[] applications; + int physicalSlotId; + String atr; + String iccid; + String eid; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/Carrier.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/Carrier.aidl new file mode 100644 index 0000000000..bbf777f94a --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/Carrier.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 -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.radio; +@VintfStability +parcelable Carrier { + String mcc; + String mnc; + android.hardware.radio.CarrierMatchType matchType; + String matchData; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CarrierMatchType.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CarrierMatchType.aidl new file mode 100644 index 0000000000..c3596cde1a --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CarrierMatchType.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 -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.radio; +@Backing(type="int") @VintfStability +enum CarrierMatchType { + ALL = 0, + SPN = 1, + IMSI_PREFIX = 2, + GID1 = 3, + GID2 = 4, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CarrierRestrictions.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CarrierRestrictions.aidl new file mode 100644 index 0000000000..f8cafb58a2 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CarrierRestrictions.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 -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.radio; +@VintfStability +parcelable CarrierRestrictions { + android.hardware.radio.Carrier[] allowedCarriers; + android.hardware.radio.Carrier[] excludedCarriers; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CarrierRestrictionsWithPriority.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CarrierRestrictionsWithPriority.aidl new file mode 100644 index 0000000000..1f06980416 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CarrierRestrictionsWithPriority.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 -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.radio; +@VintfStability +parcelable CarrierRestrictionsWithPriority { + android.hardware.radio.Carrier[] allowedCarriers; + android.hardware.radio.Carrier[] excludedCarriers; + boolean allowedCarriersPrioritized; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaBroadcastSmsConfigInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaBroadcastSmsConfigInfo.aidl new file mode 100644 index 0000000000..73c7faeeab --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaBroadcastSmsConfigInfo.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 -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.radio; +@VintfStability +parcelable CdmaBroadcastSmsConfigInfo { + int serviceCategory; + int language; + boolean selected; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaCallWaiting.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaCallWaiting.aidl new file mode 100644 index 0000000000..564433fc9c --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaCallWaiting.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 -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.radio; +@VintfStability +parcelable CdmaCallWaiting { + String number; + android.hardware.radio.CdmaCallWaitingNumberPresentation numberPresentation; + String name; + android.hardware.radio.CdmaSignalInfoRecord signalInfoRecord; + android.hardware.radio.CdmaCallWaitingNumberType numberType; + android.hardware.radio.CdmaCallWaitingNumberPlan numberPlan; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaCallWaitingNumberPlan.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaCallWaitingNumberPlan.aidl new file mode 100644 index 0000000000..6dcd594c09 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaCallWaitingNumberPlan.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 -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.radio; +@Backing(type="int") @VintfStability +enum CdmaCallWaitingNumberPlan { + UNKNOWN = 0, + ISDN = 1, + DATA = 3, + TELEX = 4, + NATIONAL = 8, + PRIVATE = 9, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaCallWaitingNumberPresentation.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaCallWaitingNumberPresentation.aidl new file mode 100644 index 0000000000..22eaf6bedd --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaCallWaitingNumberPresentation.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 -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.radio; +@Backing(type="int") @VintfStability +enum CdmaCallWaitingNumberPresentation { + ALLOWED = 0, + RESTRICTED = 1, + UNKNOWN = 2, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaCallWaitingNumberType.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaCallWaitingNumberType.aidl new file mode 100644 index 0000000000..47401083c1 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaCallWaitingNumberType.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 -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.radio; +@Backing(type="int") @VintfStability +enum CdmaCallWaitingNumberType { + UNKNOWN = 0, + INTERNATIONAL = 1, + NATIONAL = 2, + NETWORK_SPECIFIC = 3, + SUBSCRIBER = 4, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaDisplayInfoRecord.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaDisplayInfoRecord.aidl new file mode 100644 index 0000000000..11f082f1b0 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaDisplayInfoRecord.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 -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.radio; +@VintfStability +parcelable CdmaDisplayInfoRecord { + String alphaBuf; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaInfoRecName.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaInfoRecName.aidl new file mode 100644 index 0000000000..182dcc0cca --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaInfoRecName.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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.radio; +@Backing(type="int") @VintfStability +enum CdmaInfoRecName { + DISPLAY = 0, + CALLED_PARTY_NUMBER = 1, + CALLING_PARTY_NUMBER = 2, + CONNECTED_NUMBER = 3, + SIGNAL = 4, + REDIRECTING_NUMBER = 5, + LINE_CONTROL = 6, + EXTENDED_DISPLAY = 7, + T53_CLIR = 8, + T53_RELEASE = 9, + T53_AUDIO_CONTROL = 10, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaInformationRecord.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaInformationRecord.aidl new file mode 100644 index 0000000000..844a1bf86d --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaInformationRecord.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 -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.radio; +@VintfStability +parcelable CdmaInformationRecord { + android.hardware.radio.CdmaInfoRecName name; + android.hardware.radio.CdmaDisplayInfoRecord[] display; + android.hardware.radio.CdmaNumberInfoRecord[] number; + android.hardware.radio.CdmaSignalInfoRecord[] signal; + android.hardware.radio.CdmaRedirectingNumberInfoRecord[] redir; + android.hardware.radio.CdmaLineControlInfoRecord[] lineCtrl; + android.hardware.radio.CdmaT53ClirInfoRecord[] clir; + android.hardware.radio.CdmaT53AudioControlInfoRecord[] audioCtrl; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaInformationRecords.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaInformationRecords.aidl new file mode 100644 index 0000000000..88a433148b --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaInformationRecords.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 -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.radio; +@VintfStability +parcelable CdmaInformationRecords { + android.hardware.radio.CdmaInformationRecord[] infoRec; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaLineControlInfoRecord.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaLineControlInfoRecord.aidl new file mode 100644 index 0000000000..48180a7717 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaLineControlInfoRecord.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 -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.radio; +@VintfStability +parcelable CdmaLineControlInfoRecord { + byte lineCtrlPolarityIncluded; + byte lineCtrlToggle; + byte lineCtrlReverse; + byte lineCtrlPowerDenial; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaNumberInfoRecord.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaNumberInfoRecord.aidl new file mode 100644 index 0000000000..86376a7034 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaNumberInfoRecord.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 -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.radio; +@VintfStability +parcelable CdmaNumberInfoRecord { + String number; + byte numberType; + byte numberPlan; + byte pi; + byte si; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaOtaProvisionStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaOtaProvisionStatus.aidl new file mode 100644 index 0000000000..7cd88ac9cd --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaOtaProvisionStatus.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 -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.radio; +@Backing(type="int") @VintfStability +enum CdmaOtaProvisionStatus { + SPL_UNLOCKED = 0, + SPC_RETRIES_EXCEEDED = 1, + A_KEY_EXCHANGED = 2, + SSD_UPDATED = 3, + NAM_DOWNLOADED = 4, + MDN_DOWNLOADED = 5, + IMSI_DOWNLOADED = 6, + PRL_DOWNLOADED = 7, + COMMITTED = 8, + OTAPA_STARTED = 9, + OTAPA_STOPPED = 10, + OTAPA_ABORTED = 11, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaRedirectingNumberInfoRecord.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaRedirectingNumberInfoRecord.aidl new file mode 100644 index 0000000000..44b799323c --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaRedirectingNumberInfoRecord.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 -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.radio; +@VintfStability +parcelable CdmaRedirectingNumberInfoRecord { + android.hardware.radio.CdmaNumberInfoRecord redirectingNumber; + android.hardware.radio.CdmaRedirectingReason redirectingReason; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaRedirectingReason.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaRedirectingReason.aidl new file mode 100644 index 0000000000..e109c5b146 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaRedirectingReason.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 -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.radio; +@Backing(type="int") @VintfStability +enum CdmaRedirectingReason { + UNKNOWN = 0, + CALL_FORWARDING_BUSY = 1, + CALL_FORWARDING_NO_REPLY = 2, + CALLED_DTE_OUT_OF_ORDER = 9, + CALL_FORWARDING_BY_THE_CALLED_DTE = 10, + CALL_FORWARDING_UNCONDITIONAL = 15, + RESERVED = 16, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaRoamingType.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaRoamingType.aidl new file mode 100644 index 0000000000..09a59a0c35 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaRoamingType.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 -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.radio; +@Backing(type="int") @VintfStability +enum CdmaRoamingType { + HOME_NETWORK = 0, + AFFILIATED_ROAM = 1, + ANY_ROAM = 2, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSignalInfoRecord.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSignalInfoRecord.aidl new file mode 100644 index 0000000000..efb396af56 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSignalInfoRecord.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 -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.radio; +@VintfStability +parcelable CdmaSignalInfoRecord { + boolean isPresent; + byte signalType; + byte alertPitch; + byte signal; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSignalStrength.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSignalStrength.aidl new file mode 100644 index 0000000000..29391838f4 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSignalStrength.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 -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.radio; +@VintfStability +parcelable CdmaSignalStrength { + int dbm; + int ecio; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSmsAck.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSmsAck.aidl new file mode 100644 index 0000000000..0ef4331777 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSmsAck.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 -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.radio; +@VintfStability +parcelable CdmaSmsAck { + android.hardware.radio.CdmaSmsErrorClass errorClass; + int smsCauseCode; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSmsAddress.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSmsAddress.aidl new file mode 100644 index 0000000000..a37f1e75e2 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSmsAddress.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 -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.radio; +@VintfStability +parcelable CdmaSmsAddress { + android.hardware.radio.CdmaSmsDigitMode digitMode; + android.hardware.radio.CdmaSmsNumberMode numberMode; + android.hardware.radio.CdmaSmsNumberType numberType; + android.hardware.radio.CdmaSmsNumberPlan numberPlan; + byte[] digits; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSmsDigitMode.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSmsDigitMode.aidl new file mode 100644 index 0000000000..7c7783057e --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSmsDigitMode.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 -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.radio; +@Backing(type="int") @VintfStability +enum CdmaSmsDigitMode { + FOUR_BIT = 0, + EIGHT_BIT = 1, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSmsErrorClass.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSmsErrorClass.aidl new file mode 100644 index 0000000000..3ad5c1a3f3 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSmsErrorClass.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 -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.radio; +@Backing(type="int") @VintfStability +enum CdmaSmsErrorClass { + NO_ERROR = 0, + ERROR = 1, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSmsMessage.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSmsMessage.aidl new file mode 100644 index 0000000000..c419bada63 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSmsMessage.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 -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.radio; +@VintfStability +parcelable CdmaSmsMessage { + int teleserviceId; + boolean isServicePresent; + int serviceCategory; + android.hardware.radio.CdmaSmsAddress address; + android.hardware.radio.CdmaSmsSubaddress subAddress; + byte[] bearerData; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSmsNumberMode.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSmsNumberMode.aidl new file mode 100644 index 0000000000..31d49d4373 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSmsNumberMode.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 -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.radio; +@Backing(type="int") @VintfStability +enum CdmaSmsNumberMode { + NOT_DATA_NETWORK = 0, + DATA_NETWORK = 1, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSmsNumberPlan.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSmsNumberPlan.aidl new file mode 100644 index 0000000000..fcbd1cc637 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSmsNumberPlan.aidl @@ -0,0 +1,53 @@ +/* + * 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 -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.radio; +@Backing(type="int") @VintfStability +enum CdmaSmsNumberPlan { + UNKNOWN = 0, + TELEPHONY = 1, + RESERVED_2 = 2, + DATA = 3, + TELEX = 4, + RESERVED_5 = 5, + RESERVED_6 = 6, + RESERVED_7 = 7, + RESERVED_8 = 8, + PRIVATE = 9, + RESERVED_10 = 10, + RESERVED_11 = 11, + RESERVED_12 = 12, + RESERVED_13 = 13, + RESERVED_14 = 14, + RESERVED_15 = 15, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSmsNumberType.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSmsNumberType.aidl new file mode 100644 index 0000000000..ca14dbc91f --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSmsNumberType.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 -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.radio; +@Backing(type="int") @VintfStability +enum CdmaSmsNumberType { + UNKNOWN = 0, + INTERNATIONAL_OR_DATA_IP = 1, + NATIONAL_OR_INTERNET_MAIL = 2, + NETWORK = 3, + SUBSCRIBER = 4, + ALPHANUMERIC = 5, + ABBREVIATED = 6, + RESERVED_7 = 7, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSmsSubaddress.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSmsSubaddress.aidl new file mode 100644 index 0000000000..a0155daae1 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSmsSubaddress.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 -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.radio; +@VintfStability +parcelable CdmaSmsSubaddress { + android.hardware.radio.CdmaSmsSubaddressType subaddressType; + boolean odd; + byte[] digits; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSmsSubaddressType.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSmsSubaddressType.aidl new file mode 100644 index 0000000000..a4db5ec6e1 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSmsSubaddressType.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 -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.radio; +@Backing(type="int") @VintfStability +enum CdmaSmsSubaddressType { + NSAP = 0, + USER_SPECIFIED = 1, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSmsWriteArgs.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSmsWriteArgs.aidl new file mode 100644 index 0000000000..3202314f34 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSmsWriteArgs.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 -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.radio; +@VintfStability +parcelable CdmaSmsWriteArgs { + android.hardware.radio.CdmaSmsWriteArgsStatus status; + android.hardware.radio.CdmaSmsMessage message; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSmsWriteArgsStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSmsWriteArgsStatus.aidl new file mode 100644 index 0000000000..4bad261e2b --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSmsWriteArgsStatus.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 -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.radio; +@Backing(type="int") @VintfStability +enum CdmaSmsWriteArgsStatus { + REC_UNREAD = 0, + REC_READ = 1, + STO_UNSENT = 2, + STO_SENT = 3, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSubscriptionSource.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSubscriptionSource.aidl new file mode 100644 index 0000000000..11e8a2466e --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSubscriptionSource.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 -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.radio; +@Backing(type="int") @VintfStability +enum CdmaSubscriptionSource { + RUIM_SIM = 0, + NV = 1, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaT53AudioControlInfoRecord.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaT53AudioControlInfoRecord.aidl new file mode 100644 index 0000000000..9285eb79f1 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaT53AudioControlInfoRecord.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 -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.radio; +@VintfStability +parcelable CdmaT53AudioControlInfoRecord { + byte upLink; + byte downLink; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaT53ClirInfoRecord.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaT53ClirInfoRecord.aidl new file mode 100644 index 0000000000..ff4d3c3da5 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaT53ClirInfoRecord.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 -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.radio; +@VintfStability +parcelable CdmaT53ClirInfoRecord { + byte cause; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellConfigLte.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellConfigLte.aidl new file mode 100644 index 0000000000..184af1cb04 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellConfigLte.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 -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.radio; +@VintfStability +parcelable CellConfigLte { + boolean isEndcAvailable; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellConnectionStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellConnectionStatus.aidl new file mode 100644 index 0000000000..96f8368a7a --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellConnectionStatus.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 -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.radio; +@Backing(type="int") @VintfStability +enum CellConnectionStatus { + NONE = 0, + PRIMARY_SERVING = 1, + SECONDARY_SERVING = 2, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellIdentity.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellIdentity.aidl new file mode 100644 index 0000000000..aa37fdfa71 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellIdentity.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 -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.radio; +@VintfStability +union CellIdentity { + boolean noinit; + android.hardware.radio.CellIdentityGsm gsm; + android.hardware.radio.CellIdentityWcdma wcdma; + android.hardware.radio.CellIdentityTdscdma tdscdma; + android.hardware.radio.CellIdentityCdma cdma; + android.hardware.radio.CellIdentityLte lte; + android.hardware.radio.CellIdentityNr nr; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellIdentityCdma.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellIdentityCdma.aidl new file mode 100644 index 0000000000..d24b91d213 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellIdentityCdma.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 -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.radio; +@VintfStability +parcelable CellIdentityCdma { + int networkId; + int systemId; + int baseStationId; + int longitude; + int latitude; + android.hardware.radio.CellIdentityOperatorNames operatorNames; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellIdentityGsm.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellIdentityGsm.aidl new file mode 100644 index 0000000000..4ee2148798 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellIdentityGsm.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 -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.radio; +@VintfStability +parcelable CellIdentityGsm { + String mcc; + String mnc; + int lac; + int cid; + int arfcn; + byte bsic; + android.hardware.radio.CellIdentityOperatorNames operatorNames; + String[] additionalPlmns; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellIdentityLte.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellIdentityLte.aidl new file mode 100644 index 0000000000..5a8c272080 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellIdentityLte.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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.radio; +@VintfStability +parcelable CellIdentityLte { + String mcc; + String mnc; + int ci; + int pci; + int tac; + int earfcn; + android.hardware.radio.CellIdentityOperatorNames operatorNames; + int bandwidth; + String[] additionalPlmns; + android.hardware.radio.OptionalCsgInfo optionalCsgInfo; + android.hardware.radio.EutranBands[] bands; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellIdentityNr.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellIdentityNr.aidl new file mode 100644 index 0000000000..60a24d7e38 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellIdentityNr.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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.radio; +@VintfStability +parcelable CellIdentityNr { + String mcc; + String mnc; + long nci; + int pci; + int tac; + int nrarfcn; + android.hardware.radio.CellIdentityOperatorNames operatorNames; + String[] additionalPlmns; + android.hardware.radio.NgranBands[] bands; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellIdentityOperatorNames.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellIdentityOperatorNames.aidl new file mode 100644 index 0000000000..161797f3f8 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellIdentityOperatorNames.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 -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.radio; +@VintfStability +parcelable CellIdentityOperatorNames { + String alphaLong; + String alphaShort; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellIdentityTdscdma.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellIdentityTdscdma.aidl new file mode 100644 index 0000000000..35e1f5d0b6 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellIdentityTdscdma.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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.radio; +@VintfStability +parcelable CellIdentityTdscdma { + String mcc; + String mnc; + int lac; + int cid; + int cpid; + int uarfcn; + android.hardware.radio.CellIdentityOperatorNames operatorNames; + String[] additionalPlmns; + android.hardware.radio.OptionalCsgInfo optionalCsgInfo; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellIdentityWcdma.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellIdentityWcdma.aidl new file mode 100644 index 0000000000..7bcc4d5d1c --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellIdentityWcdma.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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.radio; +@VintfStability +parcelable CellIdentityWcdma { + String mcc; + String mnc; + int lac; + int cid; + int psc; + int uarfcn; + android.hardware.radio.CellIdentityOperatorNames operatorNames; + String[] additionalPlmns; + android.hardware.radio.OptionalCsgInfo optionalCsgInfo; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfo.aidl new file mode 100644 index 0000000000..20ea3cb18a --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfo.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 -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.radio; +@VintfStability +parcelable CellInfo { + boolean registered; + android.hardware.radio.CellConnectionStatus connectionStatus; + android.hardware.radio.CellInfoCellInfoRatSpecificInfo ratSpecificInfo; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoCdma.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoCdma.aidl new file mode 100644 index 0000000000..dd940c2fa7 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoCdma.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 -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.radio; +@VintfStability +parcelable CellInfoCdma { + android.hardware.radio.CellIdentityCdma cellIdentityCdma; + android.hardware.radio.CdmaSignalStrength signalStrengthCdma; + android.hardware.radio.EvdoSignalStrength signalStrengthEvdo; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoCellInfoRatSpecificInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoCellInfoRatSpecificInfo.aidl new file mode 100644 index 0000000000..7084e5e2ad --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoCellInfoRatSpecificInfo.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 -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.radio; +@VintfStability +union CellInfoCellInfoRatSpecificInfo { + android.hardware.radio.CellInfoGsm gsm; + android.hardware.radio.CellInfoWcdma wcdma; + android.hardware.radio.CellInfoTdscdma tdscdma; + android.hardware.radio.CellInfoLte lte; + android.hardware.radio.CellInfoNr nr; + android.hardware.radio.CellInfoCdma cdma; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoGsm.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoGsm.aidl new file mode 100644 index 0000000000..fda976c6b3 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoGsm.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 -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.radio; +@VintfStability +parcelable CellInfoGsm { + android.hardware.radio.CellIdentityGsm cellIdentityGsm; + android.hardware.radio.GsmSignalStrength signalStrengthGsm; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoInfo.aidl new file mode 100644 index 0000000000..9c2255520d --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoInfo.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 -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.radio; +@VintfStability +union CellInfoInfo { + android.hardware.radio.CellInfoGsm gsm; + android.hardware.radio.CellInfoCdma cdma; + android.hardware.radio.CellInfoWcdma wcdma; + android.hardware.radio.CellInfoTdscdma tdscdma; + android.hardware.radio.CellInfoLte lte; + android.hardware.radio.CellInfoNr nr; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoLte.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoLte.aidl new file mode 100644 index 0000000000..9976feb52a --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoLte.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 -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.radio; +@VintfStability +parcelable CellInfoLte { + android.hardware.radio.CellIdentityLte cellIdentityLte; + android.hardware.radio.LteSignalStrength signalStrengthLte; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoNr.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoNr.aidl new file mode 100644 index 0000000000..7883692b55 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoNr.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 -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.radio; +@VintfStability +parcelable CellInfoNr { + android.hardware.radio.CellIdentityNr cellIdentityNr; + android.hardware.radio.NrSignalStrength signalStrengthNr; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoTdscdma.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoTdscdma.aidl new file mode 100644 index 0000000000..4fbe5b61e6 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoTdscdma.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 -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.radio; +@VintfStability +parcelable CellInfoTdscdma { + android.hardware.radio.CellIdentityTdscdma cellIdentityTdscdma; + android.hardware.radio.TdscdmaSignalStrength signalStrengthTdscdma; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoType.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoType.aidl new file mode 100644 index 0000000000..cb92ed9fd4 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoType.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 -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.radio; +@Backing(type="int") @VintfStability +enum CellInfoType { + NONE = 0, + GSM = 1, + CDMA = 2, + LTE = 3, + WCDMA = 4, + TD_SCDMA = 5, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoWcdma.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoWcdma.aidl new file mode 100644 index 0000000000..88ca975ba6 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoWcdma.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 -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.radio; +@VintfStability +parcelable CellInfoWcdma { + android.hardware.radio.CellIdentityWcdma cellIdentityWcdma; + android.hardware.radio.WcdmaSignalStrength signalStrengthWcdma; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CfData.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CfData.aidl new file mode 100644 index 0000000000..6a2b0269e5 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CfData.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 -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.radio; +@VintfStability +parcelable CfData { + android.hardware.radio.CallForwardInfo[] cfInfo; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ClipStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ClipStatus.aidl new file mode 100644 index 0000000000..36a15100b9 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ClipStatus.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 -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.radio; +@Backing(type="int") @VintfStability +enum ClipStatus { + CLIP_PROVISIONED = 0, + CLIP_UNPROVISIONED = 1, + UNKNOWN = 2, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/Clir.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/Clir.aidl new file mode 100644 index 0000000000..97ba4ed2df --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/Clir.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 -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.radio; +@Backing(type="int") @VintfStability +enum Clir { + DEFAULT = 0, + INVOCATION = 1, + SUPPRESSION = 2, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ClosedSubscriberGroupInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ClosedSubscriberGroupInfo.aidl new file mode 100644 index 0000000000..0c10ca4622 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ClosedSubscriberGroupInfo.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 -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.radio; +@VintfStability +parcelable ClosedSubscriberGroupInfo { + boolean csgIndication; + String homeNodebName; + int csgIdentity; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/DataCallFailCause.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/DataCallFailCause.aidl new file mode 100644 index 0000000000..df895f825c --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/DataCallFailCause.aidl @@ -0,0 +1,377 @@ +/* + * 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 -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.radio; +@Backing(type="int") @VintfStability +enum DataCallFailCause { + NONE = 0, + OPERATOR_BARRED = 8, + NAS_SIGNALLING = 14, + INSUFFICIENT_RESOURCES = 26, + MISSING_UNKNOWN_APN = 27, + UNKNOWN_PDP_ADDRESS_TYPE = 28, + USER_AUTHENTICATION = 29, + ACTIVATION_REJECT_GGSN = 30, + ACTIVATION_REJECT_UNSPECIFIED = 31, + SERVICE_OPTION_NOT_SUPPORTED = 32, + SERVICE_OPTION_NOT_SUBSCRIBED = 33, + SERVICE_OPTION_OUT_OF_ORDER = 34, + NSAPI_IN_USE = 35, + REGULAR_DEACTIVATION = 36, + QOS_NOT_ACCEPTED = 37, + NETWORK_FAILURE = 38, + UMTS_REACTIVATION_REQ = 39, + FEATURE_NOT_SUPP = 40, + TFT_SEMANTIC_ERROR = 41, + TFT_SYTAX_ERROR = 42, + UNKNOWN_PDP_CONTEXT = 43, + FILTER_SEMANTIC_ERROR = 44, + FILTER_SYTAX_ERROR = 45, + PDP_WITHOUT_ACTIVE_TFT = 46, + ONLY_IPV4_ALLOWED = 50, + ONLY_IPV6_ALLOWED = 51, + ONLY_SINGLE_BEARER_ALLOWED = 52, + ESM_INFO_NOT_RECEIVED = 53, + PDN_CONN_DOES_NOT_EXIST = 54, + MULTI_CONN_TO_SAME_PDN_NOT_ALLOWED = 55, + MAX_ACTIVE_PDP_CONTEXT_REACHED = 65, + UNSUPPORTED_APN_IN_CURRENT_PLMN = 66, + INVALID_TRANSACTION_ID = 81, + MESSAGE_INCORRECT_SEMANTIC = 95, + INVALID_MANDATORY_INFO = 96, + MESSAGE_TYPE_UNSUPPORTED = 97, + MSG_TYPE_NONCOMPATIBLE_STATE = 98, + UNKNOWN_INFO_ELEMENT = 99, + CONDITIONAL_IE_ERROR = 100, + MSG_AND_PROTOCOL_STATE_UNCOMPATIBLE = 101, + PROTOCOL_ERRORS = 111, + APN_TYPE_CONFLICT = 112, + INVALID_PCSCF_ADDR = 113, + INTERNAL_CALL_PREEMPT_BY_HIGH_PRIO_APN = 114, + EMM_ACCESS_BARRED = 115, + EMERGENCY_IFACE_ONLY = 116, + IFACE_MISMATCH = 117, + COMPANION_IFACE_IN_USE = 118, + IP_ADDRESS_MISMATCH = 119, + IFACE_AND_POL_FAMILY_MISMATCH = 120, + EMM_ACCESS_BARRED_INFINITE_RETRY = 121, + AUTH_FAILURE_ON_EMERGENCY_CALL = 122, + OEM_DCFAILCAUSE_1 = 4097, + OEM_DCFAILCAUSE_2 = 4098, + OEM_DCFAILCAUSE_3 = 4099, + OEM_DCFAILCAUSE_4 = 4100, + OEM_DCFAILCAUSE_5 = 4101, + OEM_DCFAILCAUSE_6 = 4102, + OEM_DCFAILCAUSE_7 = 4103, + OEM_DCFAILCAUSE_8 = 4104, + OEM_DCFAILCAUSE_9 = 4105, + OEM_DCFAILCAUSE_10 = 4106, + OEM_DCFAILCAUSE_11 = 4107, + OEM_DCFAILCAUSE_12 = 4108, + OEM_DCFAILCAUSE_13 = 4109, + OEM_DCFAILCAUSE_14 = 4110, + OEM_DCFAILCAUSE_15 = 4111, + VOICE_REGISTRATION_FAIL = -1, + DATA_REGISTRATION_FAIL = -2, + SIGNAL_LOST = -3, + PREF_RADIO_TECH_CHANGED = -4, + RADIO_POWER_OFF = -5, + TETHERED_CALL_ACTIVE = -6, + ERROR_UNSPECIFIED = 65535, + LLC_SNDCP = 25, + ACTIVATION_REJECTED_BCM_VIOLATION = 48, + COLLISION_WITH_NETWORK_INITIATED_REQUEST = 56, + ONLY_IPV4V6_ALLOWED = 57, + ONLY_NON_IP_ALLOWED = 58, + UNSUPPORTED_QCI_VALUE = 59, + BEARER_HANDLING_NOT_SUPPORTED = 60, + INVALID_DNS_ADDR = 123, + INVALID_PCSCF_OR_DNS_ADDRESS = 124, + CALL_PREEMPT_BY_EMERGENCY_APN = 127, + UE_INITIATED_DETACH_OR_DISCONNECT = 128, + MIP_FA_REASON_UNSPECIFIED = 2000, + MIP_FA_ADMIN_PROHIBITED = 2001, + MIP_FA_INSUFFICIENT_RESOURCES = 2002, + MIP_FA_MOBILE_NODE_AUTHENTICATION_FAILURE = 2003, + MIP_FA_HOME_AGENT_AUTHENTICATION_FAILURE = 2004, + MIP_FA_REQUESTED_LIFETIME_TOO_LONG = 2005, + MIP_FA_MALFORMED_REQUEST = 2006, + MIP_FA_MALFORMED_REPLY = 2007, + MIP_FA_ENCAPSULATION_UNAVAILABLE = 2008, + MIP_FA_VJ_HEADER_COMPRESSION_UNAVAILABLE = 2009, + MIP_FA_REVERSE_TUNNEL_UNAVAILABLE = 2010, + MIP_FA_REVERSE_TUNNEL_IS_MANDATORY = 2011, + MIP_FA_DELIVERY_STYLE_NOT_SUPPORTED = 2012, + MIP_FA_MISSING_NAI = 2013, + MIP_FA_MISSING_HOME_AGENT = 2014, + MIP_FA_MISSING_HOME_ADDRESS = 2015, + MIP_FA_UNKNOWN_CHALLENGE = 2016, + MIP_FA_MISSING_CHALLENGE = 2017, + MIP_FA_STALE_CHALLENGE = 2018, + MIP_HA_REASON_UNSPECIFIED = 2019, + MIP_HA_ADMIN_PROHIBITED = 2020, + MIP_HA_INSUFFICIENT_RESOURCES = 2021, + MIP_HA_MOBILE_NODE_AUTHENTICATION_FAILURE = 2022, + MIP_HA_FOREIGN_AGENT_AUTHENTICATION_FAILURE = 2023, + MIP_HA_REGISTRATION_ID_MISMATCH = 2024, + MIP_HA_MALFORMED_REQUEST = 2025, + MIP_HA_UNKNOWN_HOME_AGENT_ADDRESS = 2026, + MIP_HA_REVERSE_TUNNEL_UNAVAILABLE = 2027, + MIP_HA_REVERSE_TUNNEL_IS_MANDATORY = 2028, + MIP_HA_ENCAPSULATION_UNAVAILABLE = 2029, + CLOSE_IN_PROGRESS = 2030, + NETWORK_INITIATED_TERMINATION = 2031, + MODEM_APP_PREEMPTED = 2032, + PDN_IPV4_CALL_DISALLOWED = 2033, + PDN_IPV4_CALL_THROTTLED = 2034, + PDN_IPV6_CALL_DISALLOWED = 2035, + PDN_IPV6_CALL_THROTTLED = 2036, + MODEM_RESTART = 2037, + PDP_PPP_NOT_SUPPORTED = 2038, + UNPREFERRED_RAT = 2039, + PHYSICAL_LINK_CLOSE_IN_PROGRESS = 2040, + APN_PENDING_HANDOVER = 2041, + PROFILE_BEARER_INCOMPATIBLE = 2042, + SIM_CARD_CHANGED = 2043, + LOW_POWER_MODE_OR_POWERING_DOWN = 2044, + APN_DISABLED = 2045, + MAX_PPP_INACTIVITY_TIMER_EXPIRED = 2046, + IPV6_ADDRESS_TRANSFER_FAILED = 2047, + TRAT_SWAP_FAILED = 2048, + EHRPD_TO_HRPD_FALLBACK = 2049, + MIP_CONFIG_FAILURE = 2050, + PDN_INACTIVITY_TIMER_EXPIRED = 2051, + MAX_IPV4_CONNECTIONS = 2052, + MAX_IPV6_CONNECTIONS = 2053, + APN_MISMATCH = 2054, + IP_VERSION_MISMATCH = 2055, + DUN_CALL_DISALLOWED = 2056, + INTERNAL_EPC_NONEPC_TRANSITION = 2057, + INTERFACE_IN_USE = 2058, + APN_DISALLOWED_ON_ROAMING = 2059, + APN_PARAMETERS_CHANGED = 2060, + NULL_APN_DISALLOWED = 2061, + THERMAL_MITIGATION = 2062, + DATA_SETTINGS_DISABLED = 2063, + DATA_ROAMING_SETTINGS_DISABLED = 2064, + DDS_SWITCHED = 2065, + FORBIDDEN_APN_NAME = 2066, + DDS_SWITCH_IN_PROGRESS = 2067, + CALL_DISALLOWED_IN_ROAMING = 2068, + NON_IP_NOT_SUPPORTED = 2069, + PDN_NON_IP_CALL_THROTTLED = 2070, + PDN_NON_IP_CALL_DISALLOWED = 2071, + CDMA_LOCK = 2072, + CDMA_INTERCEPT = 2073, + CDMA_REORDER = 2074, + CDMA_RELEASE_DUE_TO_SO_REJECTION = 2075, + CDMA_INCOMING_CALL = 2076, + CDMA_ALERT_STOP = 2077, + CHANNEL_ACQUISITION_FAILURE = 2078, + MAX_ACCESS_PROBE = 2079, + CONCURRENT_SERVICE_NOT_SUPPORTED_BY_BASE_STATION = 2080, + NO_RESPONSE_FROM_BASE_STATION = 2081, + REJECTED_BY_BASE_STATION = 2082, + CONCURRENT_SERVICES_INCOMPATIBLE = 2083, + NO_CDMA_SERVICE = 2084, + RUIM_NOT_PRESENT = 2085, + CDMA_RETRY_ORDER = 2086, + ACCESS_BLOCK = 2087, + ACCESS_BLOCK_ALL = 2088, + IS707B_MAX_ACCESS_PROBES = 2089, + THERMAL_EMERGENCY = 2090, + CONCURRENT_SERVICES_NOT_ALLOWED = 2091, + INCOMING_CALL_REJECTED = 2092, + NO_SERVICE_ON_GATEWAY = 2093, + NO_GPRS_CONTEXT = 2094, + ILLEGAL_MS = 2095, + ILLEGAL_ME = 2096, + GPRS_SERVICES_AND_NON_GPRS_SERVICES_NOT_ALLOWED = 2097, + GPRS_SERVICES_NOT_ALLOWED = 2098, + MS_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK = 2099, + IMPLICITLY_DETACHED = 2100, + PLMN_NOT_ALLOWED = 2101, + LOCATION_AREA_NOT_ALLOWED = 2102, + GPRS_SERVICES_NOT_ALLOWED_IN_THIS_PLMN = 2103, + PDP_DUPLICATE = 2104, + UE_RAT_CHANGE = 2105, + CONGESTION = 2106, + NO_PDP_CONTEXT_ACTIVATED = 2107, + ACCESS_CLASS_DSAC_REJECTION = 2108, + PDP_ACTIVATE_MAX_RETRY_FAILED = 2109, + RADIO_ACCESS_BEARER_FAILURE = 2110, + ESM_UNKNOWN_EPS_BEARER_CONTEXT = 2111, + DRB_RELEASED_BY_RRC = 2112, + CONNECTION_RELEASED = 2113, + EMM_DETACHED = 2114, + EMM_ATTACH_FAILED = 2115, + EMM_ATTACH_STARTED = 2116, + LTE_NAS_SERVICE_REQUEST_FAILED = 2117, + DUPLICATE_BEARER_ID = 2118, + ESM_COLLISION_SCENARIOS = 2119, + ESM_BEARER_DEACTIVATED_TO_SYNC_WITH_NETWORK = 2120, + ESM_NW_ACTIVATED_DED_BEARER_WITH_ID_OF_DEF_BEARER = 2121, + ESM_BAD_OTA_MESSAGE = 2122, + ESM_DOWNLOAD_SERVER_REJECTED_THE_CALL = 2123, + ESM_CONTEXT_TRANSFERRED_DUE_TO_IRAT = 2124, + DS_EXPLICIT_DEACTIVATION = 2125, + ESM_LOCAL_CAUSE_NONE = 2126, + LTE_THROTTLING_NOT_REQUIRED = 2127, + ACCESS_CONTROL_LIST_CHECK_FAILURE = 2128, + SERVICE_NOT_ALLOWED_ON_PLMN = 2129, + EMM_T3417_EXPIRED = 2130, + EMM_T3417_EXT_EXPIRED = 2131, + RRC_UPLINK_DATA_TRANSMISSION_FAILURE = 2132, + RRC_UPLINK_DELIVERY_FAILED_DUE_TO_HANDOVER = 2133, + RRC_UPLINK_CONNECTION_RELEASE = 2134, + RRC_UPLINK_RADIO_LINK_FAILURE = 2135, + RRC_UPLINK_ERROR_REQUEST_FROM_NAS = 2136, + RRC_CONNECTION_ACCESS_STRATUM_FAILURE = 2137, + RRC_CONNECTION_ANOTHER_PROCEDURE_IN_PROGRESS = 2138, + RRC_CONNECTION_ACCESS_BARRED = 2139, + RRC_CONNECTION_CELL_RESELECTION = 2140, + RRC_CONNECTION_CONFIG_FAILURE = 2141, + RRC_CONNECTION_TIMER_EXPIRED = 2142, + RRC_CONNECTION_LINK_FAILURE = 2143, + RRC_CONNECTION_CELL_NOT_CAMPED = 2144, + RRC_CONNECTION_SYSTEM_INTERVAL_FAILURE = 2145, + RRC_CONNECTION_REJECT_BY_NETWORK = 2146, + RRC_CONNECTION_NORMAL_RELEASE = 2147, + RRC_CONNECTION_RADIO_LINK_FAILURE = 2148, + RRC_CONNECTION_REESTABLISHMENT_FAILURE = 2149, + RRC_CONNECTION_OUT_OF_SERVICE_DURING_CELL_REGISTER = 2150, + RRC_CONNECTION_ABORT_REQUEST = 2151, + RRC_CONNECTION_SYSTEM_INFORMATION_BLOCK_READ_ERROR = 2152, + NETWORK_INITIATED_DETACH_WITH_AUTO_REATTACH = 2153, + NETWORK_INITIATED_DETACH_NO_AUTO_REATTACH = 2154, + ESM_PROCEDURE_TIME_OUT = 2155, + INVALID_CONNECTION_ID = 2156, + MAXIMIUM_NSAPIS_EXCEEDED = 2157, + INVALID_PRIMARY_NSAPI = 2158, + CANNOT_ENCODE_OTA_MESSAGE = 2159, + RADIO_ACCESS_BEARER_SETUP_FAILURE = 2160, + PDP_ESTABLISH_TIMEOUT_EXPIRED = 2161, + PDP_MODIFY_TIMEOUT_EXPIRED = 2162, + PDP_INACTIVE_TIMEOUT_EXPIRED = 2163, + PDP_LOWERLAYER_ERROR = 2164, + PDP_MODIFY_COLLISION = 2165, + MAXINUM_SIZE_OF_L2_MESSAGE_EXCEEDED = 2166, + NAS_REQUEST_REJECTED_BY_NETWORK = 2167, + RRC_CONNECTION_INVALID_REQUEST = 2168, + RRC_CONNECTION_TRACKING_AREA_ID_CHANGED = 2169, + RRC_CONNECTION_RF_UNAVAILABLE = 2170, + RRC_CONNECTION_ABORTED_DUE_TO_IRAT_CHANGE = 2171, + RRC_CONNECTION_RELEASED_SECURITY_NOT_ACTIVE = 2172, + RRC_CONNECTION_ABORTED_AFTER_HANDOVER = 2173, + RRC_CONNECTION_ABORTED_AFTER_IRAT_CELL_CHANGE = 2174, + RRC_CONNECTION_ABORTED_DURING_IRAT_CELL_CHANGE = 2175, + IMSI_UNKNOWN_IN_HOME_SUBSCRIBER_SERVER = 2176, + IMEI_NOT_ACCEPTED = 2177, + EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED = 2178, + EPS_SERVICES_NOT_ALLOWED_IN_PLMN = 2179, + MSC_TEMPORARILY_NOT_REACHABLE = 2180, + CS_DOMAIN_NOT_AVAILABLE = 2181, + ESM_FAILURE = 2182, + MAC_FAILURE = 2183, + SYNCHRONIZATION_FAILURE = 2184, + UE_SECURITY_CAPABILITIES_MISMATCH = 2185, + SECURITY_MODE_REJECTED = 2186, + UNACCEPTABLE_NON_EPS_AUTHENTICATION = 2187, + CS_FALLBACK_CALL_ESTABLISHMENT_NOT_ALLOWED = 2188, + NO_EPS_BEARER_CONTEXT_ACTIVATED = 2189, + INVALID_EMM_STATE = 2190, + NAS_LAYER_FAILURE = 2191, + MULTIPLE_PDP_CALL_NOT_ALLOWED = 2192, + EMBMS_NOT_ENABLED = 2193, + IRAT_HANDOVER_FAILED = 2194, + EMBMS_REGULAR_DEACTIVATION = 2195, + TEST_LOOPBACK_REGULAR_DEACTIVATION = 2196, + LOWER_LAYER_REGISTRATION_FAILURE = 2197, + DATA_PLAN_EXPIRED = 2198, + UMTS_HANDOVER_TO_IWLAN = 2199, + EVDO_CONNECTION_DENY_BY_GENERAL_OR_NETWORK_BUSY = 2200, + EVDO_CONNECTION_DENY_BY_BILLING_OR_AUTHENTICATION_FAILURE = 2201, + EVDO_HDR_CHANGED = 2202, + EVDO_HDR_EXITED = 2203, + EVDO_HDR_NO_SESSION = 2204, + EVDO_USING_GPS_FIX_INSTEAD_OF_HDR_CALL = 2205, + EVDO_HDR_CONNECTION_SETUP_TIMEOUT = 2206, + FAILED_TO_ACQUIRE_COLOCATED_HDR = 2207, + OTASP_COMMIT_IN_PROGRESS = 2208, + NO_HYBRID_HDR_SERVICE = 2209, + HDR_NO_LOCK_GRANTED = 2210, + DBM_OR_SMS_IN_PROGRESS = 2211, + HDR_FADE = 2212, + HDR_ACCESS_FAILURE = 2213, + UNSUPPORTED_1X_PREV = 2214, + LOCAL_END = 2215, + NO_SERVICE = 2216, + FADE = 2217, + NORMAL_RELEASE = 2218, + ACCESS_ATTEMPT_ALREADY_IN_PROGRESS = 2219, + REDIRECTION_OR_HANDOFF_IN_PROGRESS = 2220, + EMERGENCY_MODE = 2221, + PHONE_IN_USE = 2222, + INVALID_MODE = 2223, + INVALID_SIM_STATE = 2224, + NO_COLLOCATED_HDR = 2225, + UE_IS_ENTERING_POWERSAVE_MODE = 2226, + DUAL_SWITCH = 2227, + PPP_TIMEOUT = 2228, + PPP_AUTH_FAILURE = 2229, + PPP_OPTION_MISMATCH = 2230, + PPP_PAP_FAILURE = 2231, + PPP_CHAP_FAILURE = 2232, + PPP_CLOSE_IN_PROGRESS = 2233, + LIMITED_TO_IPV4 = 2234, + LIMITED_TO_IPV6 = 2235, + VSNCP_TIMEOUT = 2236, + VSNCP_GEN_ERROR = 2237, + VSNCP_APN_UNAUTHORIZED = 2238, + VSNCP_PDN_LIMIT_EXCEEDED = 2239, + VSNCP_NO_PDN_GATEWAY_ADDRESS = 2240, + VSNCP_PDN_GATEWAY_UNREACHABLE = 2241, + VSNCP_PDN_GATEWAY_REJECT = 2242, + VSNCP_INSUFFICIENT_PARAMETERS = 2243, + VSNCP_RESOURCE_UNAVAILABLE = 2244, + VSNCP_ADMINISTRATIVELY_PROHIBITED = 2245, + VSNCP_PDN_ID_IN_USE = 2246, + VSNCP_SUBSCRIBER_LIMITATION = 2247, + VSNCP_PDN_EXISTS_FOR_THIS_APN = 2248, + VSNCP_RECONNECT_NOT_ALLOWED = 2249, + IPV6_PREFIX_UNAVAILABLE = 2250, + HANDOFF_PREFERENCE_CHANGED = 2251, + SLICE_REJECTED = 2252, + MATCH_ALL_RULE_NOT_ALLOWED = 2253, + ALL_MATCHING_RULES_FAILED = 2254, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/DataConnActiveStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/DataConnActiveStatus.aidl new file mode 100644 index 0000000000..0d11390aef --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/DataConnActiveStatus.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 -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.radio; +@Backing(type="int") @VintfStability +enum DataConnActiveStatus { + INACTIVE = 0, + DORMANT = 1, + ACTIVE = 2, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/DataProfileId.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/DataProfileId.aidl new file mode 100644 index 0000000000..2c86c0fc49 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/DataProfileId.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 -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.radio; +@Backing(type="int") @VintfStability +enum DataProfileId { + DEFAULT = 0, + TETHERED = 1, + IMS = 2, + FOTA = 3, + CBS = 4, + OEM_BASE = 1000, + INVALID = -1, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/DataProfileInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/DataProfileInfo.aidl new file mode 100644 index 0000000000..d9d0487e5a --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/DataProfileInfo.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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.radio; +@VintfStability +parcelable DataProfileInfo { + android.hardware.radio.DataProfileId profileId; + String apn; + android.hardware.radio.PdpProtocolType protocol; + android.hardware.radio.PdpProtocolType roamingProtocol; + android.hardware.radio.ApnAuthType authType; + String user; + String password; + android.hardware.radio.DataProfileInfoType type; + int maxConnsTime; + int maxConns; + int waitTime; + boolean enabled; + android.hardware.radio.ApnTypes supportedApnTypesBitmap; + android.hardware.radio.RadioAccessFamily bearerBitmap; + int mtuV4; + int mtuV6; + boolean preferred; + boolean persistent; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/DataProfileInfoType.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/DataProfileInfoType.aidl new file mode 100644 index 0000000000..a559de0829 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/DataProfileInfoType.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 -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.radio; +@Backing(type="int") @VintfStability +enum DataProfileInfoType { + COMMON = 0, + THREE_GPP = 1, + THREE_GPP2 = 2, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/DataRegStateResult.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/DataRegStateResult.aidl new file mode 100644 index 0000000000..303035f620 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/DataRegStateResult.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 -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.radio; +@VintfStability +parcelable DataRegStateResult { + android.hardware.radio.RegState regState; + int rat; + int reasonDataDenied; + int maxDataCalls; + android.hardware.radio.CellIdentity cellIdentity; + android.hardware.radio.DataRegStateResultVopsInfo vopsInfo; + android.hardware.radio.NrIndicators nrIndicators; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/DataRegStateResultVopsInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/DataRegStateResultVopsInfo.aidl new file mode 100644 index 0000000000..2ce646e386 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/DataRegStateResultVopsInfo.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 -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.radio; +@VintfStability +union DataRegStateResultVopsInfo { + boolean noinit; + android.hardware.radio.LteVopsInfo lteVopsInfo; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/DataRequestReason.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/DataRequestReason.aidl new file mode 100644 index 0000000000..1dd0e08ca9 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/DataRequestReason.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 -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.radio; +@Backing(type="int") @VintfStability +enum DataRequestReason { + NORMAL = 1, + SHUTDOWN = 2, + HANDOVER = 3, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/DataThrottlingAction.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/DataThrottlingAction.aidl new file mode 100644 index 0000000000..70aaa0f4af --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/DataThrottlingAction.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 -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.radio; +@Backing(type="byte") @VintfStability +enum DataThrottlingAction { + NO_DATA_THROTTLING = 0, + THROTTLE_SECONDARY_CARRIER = 1, + THROTTLE_ANCHOR_CARRIER = 2, + HOLD = 3, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/DeviceStateType.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/DeviceStateType.aidl new file mode 100644 index 0000000000..2d3cea8bba --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/DeviceStateType.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 -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.radio; +@Backing(type="int") @VintfStability +enum DeviceStateType { + POWER_SAVE_MODE = 0, + CHARGING_STATE = 1, + LOW_DATA_EXPECTED = 2, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/Dial.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/Dial.aidl new file mode 100644 index 0000000000..f8edf48d44 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/Dial.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 -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.radio; +@VintfStability +parcelable Dial { + String address; + android.hardware.radio.Clir clir; + android.hardware.radio.UusInfo[] uusInfo; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/Domain.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/Domain.aidl new file mode 100644 index 0000000000..062af35c27 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/Domain.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 -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.radio; +@Backing(type="int") @VintfStability +enum Domain { + CS = 1, + PS = 2, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/EmcIndicator.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/EmcIndicator.aidl new file mode 100644 index 0000000000..846084b401 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/EmcIndicator.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 -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.radio; +@Backing(type="byte") @VintfStability +enum EmcIndicator { + EMC_NOT_SUPPORTED = 0, + EMC_NR_CONNECTED_TO_5GCN = 1, + EMC_EUTRA_CONNECTED_TO_5GCN = 2, + EMC_BOTH_NR_EUTRA_CONNECTED_TO_5GCN = 3, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/EmergencyCallRouting.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/EmergencyCallRouting.aidl new file mode 100644 index 0000000000..95f5a46059 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/EmergencyCallRouting.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 -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.radio; +@Backing(type="int") @VintfStability +enum EmergencyCallRouting { + UNKNOWN = 0, + EMERGENCY = 1, + NORMAL = 2, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/EmergencyNumber.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/EmergencyNumber.aidl new file mode 100644 index 0000000000..7aa4cd8f9e --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/EmergencyNumber.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 -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.radio; +@VintfStability +parcelable EmergencyNumber { + String number; + String mcc; + String mnc; + android.hardware.radio.EmergencyServiceCategory categories; + String[] urns; + android.hardware.radio.EmergencyNumberSource sources; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/EmergencyNumberSource.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/EmergencyNumberSource.aidl new file mode 100644 index 0000000000..1424bfa6ea --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/EmergencyNumberSource.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 -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.radio; +@Backing(type="int") @VintfStability +enum EmergencyNumberSource { + NETWORK_SIGNALING = 1, + SIM = 2, + MODEM_CONFIG = 4, + DEFAULT = 8, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/EmergencyServiceCategory.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/EmergencyServiceCategory.aidl new file mode 100644 index 0000000000..0341572f10 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/EmergencyServiceCategory.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 -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.radio; +@Backing(type="int") @VintfStability +enum EmergencyServiceCategory { + UNSPECIFIED = 0, + POLICE = 1, + AMBULANCE = 2, + FIRE_BRIGADE = 4, + MARINE_GUARD = 8, + MOUNTAIN_RESCUE = 16, + MIEC = 32, + AIEC = 64, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/EmfIndicator.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/EmfIndicator.aidl new file mode 100644 index 0000000000..21100f2a12 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/EmfIndicator.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 -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.radio; +@Backing(type="byte") @VintfStability +enum EmfIndicator { + EMF_NOT_SUPPORTED = 0, + EMF_NR_CONNECTED_TO_5GCN = 1, + EMF_EUTRA_CONNECTED_TO_5GCN = 2, + EMF_BOTH_NR_EUTRA_CONNECTED_TO_5GCN = 3, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/EpsQos.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/EpsQos.aidl new file mode 100644 index 0000000000..8eb3fdaa25 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/EpsQos.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 -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.radio; +@VintfStability +parcelable EpsQos { + int qci; + android.hardware.radio.QosBandwidth downlink; + android.hardware.radio.QosBandwidth uplink; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/EutranBands.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/EutranBands.aidl new file mode 100644 index 0000000000..1449865474 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/EutranBands.aidl @@ -0,0 +1,97 @@ +/* + * 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 -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.radio; +@Backing(type="int") @VintfStability +enum EutranBands { + BAND_1 = 1, + BAND_2 = 2, + BAND_3 = 3, + BAND_4 = 4, + BAND_5 = 5, + BAND_6 = 6, + BAND_7 = 7, + BAND_8 = 8, + BAND_9 = 9, + BAND_10 = 10, + BAND_11 = 11, + BAND_12 = 12, + BAND_13 = 13, + BAND_14 = 14, + BAND_17 = 17, + BAND_18 = 18, + BAND_19 = 19, + BAND_20 = 20, + BAND_21 = 21, + BAND_22 = 22, + BAND_23 = 23, + BAND_24 = 24, + BAND_25 = 25, + BAND_26 = 26, + BAND_27 = 27, + BAND_28 = 28, + BAND_30 = 30, + BAND_31 = 31, + BAND_33 = 33, + BAND_34 = 34, + BAND_35 = 35, + BAND_36 = 36, + BAND_37 = 37, + BAND_38 = 38, + BAND_39 = 39, + BAND_40 = 40, + BAND_41 = 41, + BAND_42 = 42, + BAND_43 = 43, + BAND_44 = 44, + BAND_45 = 45, + BAND_46 = 46, + BAND_47 = 47, + BAND_48 = 48, + BAND_65 = 65, + BAND_66 = 66, + BAND_68 = 68, + BAND_70 = 70, + BAND_49 = 49, + BAND_50 = 50, + BAND_51 = 51, + BAND_52 = 52, + BAND_53 = 53, + BAND_71 = 71, + BAND_72 = 72, + BAND_73 = 73, + BAND_74 = 74, + BAND_85 = 85, + BAND_87 = 87, + BAND_88 = 88, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/EvdoSignalStrength.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/EvdoSignalStrength.aidl new file mode 100644 index 0000000000..148dfa093c --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/EvdoSignalStrength.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 -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.radio; +@VintfStability +parcelable EvdoSignalStrength { + int dbm; + int ecio; + int signalNoiseRatio; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/FrequencyRange.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/FrequencyRange.aidl new file mode 100644 index 0000000000..243b54e4d1 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/FrequencyRange.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 -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.radio; +@Backing(type="int") @VintfStability +enum FrequencyRange { + LOW = 1, + MID = 2, + HIGH = 3, + MMWAVE = 4, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/GeranBands.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/GeranBands.aidl new file mode 100644 index 0000000000..0efe023429 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/GeranBands.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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.radio; +@Backing(type="int") @VintfStability +enum GeranBands { + BAND_T380 = 1, + BAND_T410 = 2, + BAND_450 = 3, + BAND_480 = 4, + BAND_710 = 5, + BAND_750 = 6, + BAND_T810 = 7, + BAND_850 = 8, + BAND_P900 = 9, + BAND_E900 = 10, + BAND_R900 = 11, + BAND_DCS1800 = 12, + BAND_PCS1900 = 13, + BAND_ER900 = 14, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/GsmBroadcastSmsConfigInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/GsmBroadcastSmsConfigInfo.aidl new file mode 100644 index 0000000000..e74845e250 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/GsmBroadcastSmsConfigInfo.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 -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.radio; +@VintfStability +parcelable GsmBroadcastSmsConfigInfo { + int fromServiceId; + int toServiceId; + int fromCodeScheme; + int toCodeScheme; + boolean selected; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/GsmSignalStrength.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/GsmSignalStrength.aidl new file mode 100644 index 0000000000..5d3a6e1a32 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/GsmSignalStrength.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 -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.radio; +@VintfStability +parcelable GsmSignalStrength { + int signalStrength; + int bitErrorRate; + int timingAdvance; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/GsmSmsMessage.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/GsmSmsMessage.aidl new file mode 100644 index 0000000000..1b00b0f099 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/GsmSmsMessage.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 -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.radio; +@VintfStability +parcelable GsmSmsMessage { + String smscPdu; + String pdu; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/HandoverFailureMode.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/HandoverFailureMode.aidl new file mode 100644 index 0000000000..661b7b771a --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/HandoverFailureMode.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 -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.radio; +@Backing(type="byte") @VintfStability +enum HandoverFailureMode { + LEGACY = 0, + DO_FALLBACK = 1, + NO_FALLBACK_RETRY_HANDOVER = 2, + NO_FALLBACK_RETRY_SETUP_NORMAL = 3, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/HardwareConfig.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/HardwareConfig.aidl new file mode 100644 index 0000000000..4a5c1076bc --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/HardwareConfig.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 -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.radio; +@VintfStability +parcelable HardwareConfig { + android.hardware.radio.HardwareConfigType type; + String uuid; + android.hardware.radio.HardwareConfigState state; + android.hardware.radio.HardwareConfigModem[] modem; + android.hardware.radio.HardwareConfigSim[] sim; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/HardwareConfigModem.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/HardwareConfigModem.aidl new file mode 100644 index 0000000000..08e12e6f25 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/HardwareConfigModem.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 -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.radio; +@VintfStability +parcelable HardwareConfigModem { + int rilModel; + int rat; + int maxVoice; + int maxData; + int maxStandby; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/HardwareConfigSim.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/HardwareConfigSim.aidl new file mode 100644 index 0000000000..8df23b4bcc --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/HardwareConfigSim.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 -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.radio; +@VintfStability +parcelable HardwareConfigSim { + String modemUuid; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/HardwareConfigState.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/HardwareConfigState.aidl new file mode 100644 index 0000000000..672fe47462 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/HardwareConfigState.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 -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.radio; +@Backing(type="int") @VintfStability +enum HardwareConfigState { + ENABLED = 0, + STANDBY = 1, + DISABLED = 2, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/HardwareConfigType.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/HardwareConfigType.aidl new file mode 100644 index 0000000000..a152282dc9 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/HardwareConfigType.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 -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.radio; +@Backing(type="int") @VintfStability +enum HardwareConfigType { + MODEM = 0, + SIM = 1, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/IRadio.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/IRadio.aidl new file mode 100644 index 0000000000..5a7b251271 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/IRadio.aidl @@ -0,0 +1,200 @@ +/* + * 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 -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.radio; +@VintfStability +interface IRadio { + oneway void acceptCall(in int serial); + oneway void acknowledgeIncomingGsmSmsWithPdu(in int serial, in boolean success, in String ackPdu); + oneway void acknowledgeLastIncomingCdmaSms(in int serial, in android.hardware.radio.CdmaSmsAck smsAck); + oneway void acknowledgeLastIncomingGsmSms(in int serial, in boolean success, in android.hardware.radio.SmsAcknowledgeFailCause cause); + oneway void allocatePduSessionId(in int serial); + oneway void areUiccApplicationsEnabled(in int serial); + oneway void cancelHandover(in int serial, in int callId); + oneway void cancelPendingUssd(in int serial); + oneway void changeIccPin2ForApp(in int serial, in String oldPin2, in String newPin2, in String aid); + oneway void changeIccPinForApp(in int serial, in String oldPin, in String newPin, in String aid); + oneway void conference(in int serial); + oneway void deactivateDataCall(in int serial, in int cid, in android.hardware.radio.DataRequestReason reason); + oneway void deleteSmsOnRuim(in int serial, in int index); + oneway void deleteSmsOnSim(in int serial, in int index); + oneway void dial(in int serial, in android.hardware.radio.Dial dialInfo); + oneway void emergencyDial(in int serial, in android.hardware.radio.Dial dialInfo, in android.hardware.radio.EmergencyServiceCategory categories, in String[] urns, in android.hardware.radio.EmergencyCallRouting routing, in boolean hasKnownUserIntentEmergency, in boolean isTesting); + oneway void enableModem(in int serial, in boolean on); + oneway void enableUiccApplications(in int serial, in boolean enable); + oneway void exitEmergencyCallbackMode(in int serial); + oneway void explicitCallTransfer(in int serial); + oneway void getAllowedCarriers(in int serial); + oneway void getAllowedNetworkTypesBitmap(in int serial); + oneway void getAvailableBandModes(in int serial); + oneway void getAvailableNetworks(in int serial); + oneway void getBarringInfo(in int serial); + oneway void getBasebandVersion(in int serial); + oneway void getCDMASubscription(in int serial); + oneway void getCallForwardStatus(in int serial, in android.hardware.radio.CallForwardInfo callInfo); + oneway void getCallWaiting(in int serial, in int serviceClass); + oneway void getCdmaBroadcastConfig(in int serial); + oneway void getCdmaRoamingPreference(in int serial); + oneway void getCdmaSubscriptionSource(in int serial); + oneway void getCellInfoList(in int serial); + oneway void getClip(in int serial); + oneway void getClir(in int serial); + oneway void getCurrentCalls(in int serial); + oneway void getDataCallList(in int serial); + oneway void getDataRegistrationState(in int serial); + oneway void getDeviceIdentity(in int serial); + oneway void getFacilityLockForApp(in int serial, in String facility, in String password, in int serviceClass, in String appId); + oneway void getGsmBroadcastConfig(in int serial); + oneway void getHardwareConfig(in int serial); + oneway void getIccCardStatus(in int serial); + oneway void getImsRegistrationState(in int serial); + oneway void getImsiForApp(in int serial, in String aid); + oneway void getLastCallFailCause(in int serial); + oneway void getModemActivityInfo(in int serial); + oneway void getModemStackStatus(in int serial); + oneway void getMute(in int serial); + oneway void getNeighboringCids(in int serial); + oneway void getNetworkSelectionMode(in int serial); + oneway void getOperator(in int serial); + oneway void getPreferredNetworkType(in int serial); + oneway void getPreferredNetworkTypeBitmap(in int serial); + oneway void getPreferredVoicePrivacy(in int serial); + oneway void getRadioCapability(in int serial); + oneway void getSignalStrength(in int serial); + oneway void getSimPhonebookCapacity(in int serial); + oneway void getSimPhonebookRecords(in int serial); + oneway void getSlicingConfig(in int serial); + oneway void getSmscAddress(in int serial); + oneway void getSystemSelectionChannels(in int serial); + oneway void getTTYMode(in int serial); + oneway void getVoiceRadioTechnology(in int serial); + oneway void getVoiceRegistrationState(in int serial); + oneway void handleStkCallSetupRequestFromSim(in int serial, in boolean accept); + oneway void hangup(in int serial, in int gsmIndex); + oneway void hangupForegroundResumeBackground(in int serial); + oneway void hangupWaitingOrBackground(in int serial); + oneway void iccCloseLogicalChannel(in int serial, in int channelId); + oneway void iccIOForApp(in int serial, in android.hardware.radio.IccIo iccIo); + oneway void iccOpenLogicalChannel(in int serial, in String aid, in int p2); + oneway void iccTransmitApduBasicChannel(in int serial, in android.hardware.radio.SimApdu message); + oneway void iccTransmitApduLogicalChannel(in int serial, in android.hardware.radio.SimApdu message); + oneway void isNrDualConnectivityEnabled(in int serial); + oneway void nvReadItem(in int serial, in android.hardware.radio.NvItem itemId); + oneway void nvResetConfig(in int serial, in android.hardware.radio.ResetNvType resetType); + oneway void nvWriteCdmaPrl(in int serial, in byte[] prl); + oneway void nvWriteItem(in int serial, in android.hardware.radio.NvWriteItem item); + oneway void pullLceData(in int serial); + oneway void rejectCall(in int serial); + oneway void releasePduSessionId(in int serial, in int id); + oneway void reportSmsMemoryStatus(in int serial, in boolean available); + oneway void reportStkServiceIsRunning(in int serial); + oneway void requestIccSimAuthentication(in int serial, in int authContext, in String authData, in String aid); + oneway void requestIsimAuthentication(in int serial, in String challenge); + oneway void requestShutdown(in int serial); + oneway void responseAcknowledgement(); + oneway void sendBurstDtmf(in int serial, in String dtmf, in int on, in int off); + oneway void sendCDMAFeatureCode(in int serial, in String featureCode); + oneway void sendCdmaSms(in int serial, in android.hardware.radio.CdmaSmsMessage sms); + oneway void sendCdmaSmsExpectMore(in int serial, in android.hardware.radio.CdmaSmsMessage sms); + oneway void sendDeviceState(in int serial, in android.hardware.radio.DeviceStateType deviceStateType, in boolean state); + oneway void sendDtmf(in int serial, in String s); + oneway void sendEnvelope(in int serial, in String command); + oneway void sendEnvelopeWithStatus(in int serial, in String contents); + oneway void sendImsSms(in int serial, in android.hardware.radio.ImsSmsMessage message); + oneway void sendSMSExpectMore(in int serial, in android.hardware.radio.GsmSmsMessage message); + oneway void sendSms(in int serial, in android.hardware.radio.GsmSmsMessage message); + oneway void sendSmsExpectMore(in int serial, in android.hardware.radio.GsmSmsMessage message); + oneway void sendTerminalResponseToSim(in int serial, in String commandResponse); + oneway void sendUssd(in int serial, in String ussd); + oneway void separateConnection(in int serial, in int gsmIndex); + oneway void setAllowedCarriers(in int serial, in android.hardware.radio.CarrierRestrictionsWithPriority carriers, in android.hardware.radio.SimLockMultiSimPolicy multiSimPolicy); + oneway void setAllowedNetworkTypesBitmap(in int serial, in android.hardware.radio.RadioAccessFamily networkTypeBitmap); + oneway void setBandMode(in int serial, in android.hardware.radio.RadioBandMode mode); + oneway void setBarringPassword(in int serial, in String facility, in String oldPassword, in String newPassword); + oneway void setCallForward(in int serial, in android.hardware.radio.CallForwardInfo callInfo); + oneway void setCallWaiting(in int serial, in boolean enable, in int serviceClass); + oneway void setCarrierInfoForImsiEncryption(in int serial, in android.hardware.radio.ImsiEncryptionInfo imsiEncryptionInfo); + oneway void setCdmaBroadcastActivation(in int serial, in boolean activate); + oneway void setCdmaBroadcastConfig(in int serial, in android.hardware.radio.CdmaBroadcastSmsConfigInfo[] configInfo); + oneway void setCdmaRoamingPreference(in int serial, in android.hardware.radio.CdmaRoamingType type); + oneway void setCdmaSubscriptionSource(in int serial, in android.hardware.radio.CdmaSubscriptionSource cdmaSub); + oneway void setCellInfoListRate(in int serial, in int rate); + oneway void setClir(in int serial, in int status); + oneway void setDataAllowed(in int serial, in boolean allow); + oneway void setDataProfile(in int serial, in android.hardware.radio.DataProfileInfo[] profiles); + oneway void setDataThrottling(in int serial, in android.hardware.radio.DataThrottlingAction dataThrottlingAction, in long completionDurationMillis); + oneway void setFacilityLockForApp(in int serial, in String facility, in boolean lockState, in String password, in int serviceClass, in String appId); + oneway void setGsmBroadcastActivation(in int serial, in boolean activate); + oneway void setGsmBroadcastConfig(in int serial, in android.hardware.radio.GsmBroadcastSmsConfigInfo[] configInfo); + oneway void setIndicationFilter(in int serial, in android.hardware.radio.IndicationFilter indicationFilter); + oneway void setInitialAttachApn(in int serial, in android.hardware.radio.DataProfileInfo dataProfileInfo); + oneway void setLinkCapacityReportingCriteria(in int serial, in int hysteresisMs, in int hysteresisDlKbps, in int hysteresisUlKbps, in int[] thresholdsDownlinkKbps, in int[] thresholdsUplinkKbps, in android.hardware.radio.AccessNetwork accessNetwork); + oneway void setLocationUpdates(in int serial, in boolean enable); + oneway void setMute(in int serial, in boolean enable); + oneway void setNetworkSelectionModeAutomatic(in int serial); + oneway void setNetworkSelectionModeManual(in int serial, in String operatorNumeric, in android.hardware.radio.RadioAccessNetworks ran); + oneway void setNrDualConnectivityState(in int serial, in android.hardware.radio.NrDualConnectivityState nrDualConnectivityState); + oneway void setPreferredNetworkType(in int serial, in android.hardware.radio.PreferredNetworkType nwType); + oneway void setPreferredNetworkTypeBitmap(in int serial, in android.hardware.radio.RadioAccessFamily networkTypeBitmap); + oneway void setPreferredVoicePrivacy(in int serial, in boolean enable); + oneway void setRadioCapability(in int serial, in android.hardware.radio.RadioCapability rc); + oneway void setRadioPower(in int serial, in boolean powerOn, in boolean forEmergencyCall, in boolean preferredForEmergencyCall); + void setResponseFunctions(in android.hardware.radio.IRadioResponse radioResponse, in android.hardware.radio.IRadioIndication radioIndication); + oneway void setSignalStrengthReportingCriteria(in int serial, in android.hardware.radio.SignalThresholdInfo signalThresholdInfo, in android.hardware.radio.AccessNetwork accessNetwork); + oneway void setSimCardPower(in int serial, in android.hardware.radio.CardPowerState powerUp); + oneway void setSmscAddress(in int serial, in String smsc); + oneway void setSuppServiceNotifications(in int serial, in boolean enable); + oneway void setSystemSelectionChannels(in int serial, in boolean specifyChannels, in android.hardware.radio.RadioAccessSpecifier[] specifiers); + oneway void setTTYMode(in int serial, in android.hardware.radio.TtyMode mode); + oneway void setUiccSubscription(in int serial, in android.hardware.radio.SelectUiccSub uiccSub); + oneway void setupDataCall(in int serial, in android.hardware.radio.AccessNetwork accessNetwork, in android.hardware.radio.DataProfileInfo dataProfileInfo, in boolean roamingAllowed, in android.hardware.radio.DataRequestReason reason, in android.hardware.radio.LinkAddress[] addresses, in String[] dnses, in int pduSessionId, in android.hardware.radio.OptionalSliceInfo sliceInfo, in android.hardware.radio.OptionalTrafficDescriptor trafficDescriptor, in boolean matchAllRuleAllowed); + oneway void startDtmf(in int serial, in String s); + oneway void startHandover(in int serial, in int callId); + oneway void startKeepalive(in int serial, in android.hardware.radio.KeepaliveRequest keepalive); + oneway void startLceService(in int serial, in int reportInterval, in boolean pullMode); + oneway void startNetworkScan(in int serial, in android.hardware.radio.NetworkScanRequest request); + oneway void stopDtmf(in int serial); + oneway void stopKeepalive(in int serial, in int sessionHandle); + oneway void stopLceService(in int serial); + oneway void stopNetworkScan(in int serial); + oneway void supplyIccPin2ForApp(in int serial, in String pin2, in String aid); + oneway void supplyIccPinForApp(in int serial, in String pin, in String aid); + oneway void supplyIccPuk2ForApp(in int serial, in String puk2, in String pin2, in String aid); + oneway void supplyIccPukForApp(in int serial, in String puk, in String pin, in String aid); + oneway void supplyNetworkDepersonalization(in int serial, in String netPin); + oneway void supplySimDepersonalization(in int serial, in android.hardware.radio.PersoSubstate persoType, in String controlKey); + oneway void switchWaitingOrHoldingAndActive(in int serial); + oneway void updateSimPhonebookRecords(in int serial, in android.hardware.radio.PhonebookRecordInfo recordInfo); + oneway void writeSmsToRuim(in int serial, in android.hardware.radio.CdmaSmsWriteArgs cdmaSms); + oneway void writeSmsToSim(in int serial, in android.hardware.radio.SmsWriteArgs smsWriteArgs); +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/IRadioIndication.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/IRadioIndication.aidl new file mode 100644 index 0000000000..48e9e3ec3e --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/IRadioIndication.aidl @@ -0,0 +1,94 @@ +/* + * 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 -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.radio; +@VintfStability +interface IRadioIndication { + oneway void barringInfoChanged(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.CellIdentity cellIdentity, in android.hardware.radio.BarringInfo[] barringInfos); + oneway void callRing(in android.hardware.radio.RadioIndicationType type, in boolean isGsm, in android.hardware.radio.CdmaSignalInfoRecord record); + oneway void callStateChanged(in android.hardware.radio.RadioIndicationType type); + oneway void carrierInfoForImsiEncryption(in android.hardware.radio.RadioIndicationType info); + oneway void cdmaCallWaiting(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.CdmaCallWaiting callWaitingRecord); + oneway void cdmaInfoRec(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.CdmaInformationRecords records); + oneway void cdmaNewSms(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.CdmaSmsMessage msg); + oneway void cdmaOtaProvisionStatus(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.CdmaOtaProvisionStatus status); + oneway void cdmaPrlChanged(in android.hardware.radio.RadioIndicationType type, in int version); + oneway void cdmaRuimSmsStorageFull(in android.hardware.radio.RadioIndicationType type); + oneway void cdmaSubscriptionSourceChanged(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.CdmaSubscriptionSource cdmaSource); + oneway void cellInfoList(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.CellInfo[] records); + oneway void currentEmergencyNumberList(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.EmergencyNumber[] emergencyNumberList); + oneway void currentLinkCapacityEstimate(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.LinkCapacityEstimate lce); + oneway void currentPhysicalChannelConfigs(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.PhysicalChannelConfig[] configs); + oneway void currentSignalStrength(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.SignalStrength signalStrength); + oneway void dataCallListChanged(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.SetupDataCallResult[] dcList); + oneway void enterEmergencyCallbackMode(in android.hardware.radio.RadioIndicationType type); + oneway void exitEmergencyCallbackMode(in android.hardware.radio.RadioIndicationType type); + oneway void hardwareConfigChanged(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.HardwareConfig[] configs); + oneway void imsNetworkStateChanged(in android.hardware.radio.RadioIndicationType type); + oneway void indicateRingbackTone(in android.hardware.radio.RadioIndicationType type, in boolean start); + oneway void keepaliveStatus(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.KeepaliveStatus status); + oneway void lceData(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.LceDataInfo lce); + oneway void modemReset(in android.hardware.radio.RadioIndicationType type, in String reason); + oneway void networkScanResult(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.NetworkScanResult result); + oneway void networkStateChanged(in android.hardware.radio.RadioIndicationType type); + oneway void newBroadcastSms(in android.hardware.radio.RadioIndicationType type, in byte[] data); + oneway void newSms(in android.hardware.radio.RadioIndicationType type, in byte[] pdu); + oneway void newSmsOnSim(in android.hardware.radio.RadioIndicationType type, in int recordNumber); + oneway void newSmsStatusReport(in android.hardware.radio.RadioIndicationType type, in byte[] pdu); + oneway void nitzTimeReceived(in android.hardware.radio.RadioIndicationType type, in String nitzTime, in long receivedTime); + oneway void onSupplementaryServiceIndication(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.StkCcUnsolSsResult ss); + oneway void onUssd(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.UssdModeType modeType, in String msg); + oneway void pcoData(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.PcoDataInfo pco); + oneway void radioCapabilityIndication(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.RadioCapability rc); + oneway void radioStateChanged(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.RadioState radioState); + oneway void registrationFailed(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.CellIdentity cellIdentity, in String chosenPlmn, in android.hardware.radio.Domain domain, in int causeCode, in int additionalCauseCode); + oneway void resendIncallMute(in android.hardware.radio.RadioIndicationType type); + oneway void restrictedStateChanged(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.PhoneRestrictedState state); + oneway void rilConnected(in android.hardware.radio.RadioIndicationType type); + oneway void simPhonebookChanged(in android.hardware.radio.RadioIndicationType type); + oneway void simPhonebookRecordsReceived(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.PbReceivedStatus status, in android.hardware.radio.PhonebookRecordInfo[] records); + oneway void simRefresh(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.SimRefreshResult refreshResult); + oneway void simSmsStorageFull(in android.hardware.radio.RadioIndicationType type); + oneway void simStatusChanged(in android.hardware.radio.RadioIndicationType type); + oneway void srvccStateNotify(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.SrvccState state); + oneway void stkCallControlAlphaNotify(in android.hardware.radio.RadioIndicationType type, in String alpha); + oneway void stkCallSetup(in android.hardware.radio.RadioIndicationType type, in long timeout); + oneway void stkEventNotify(in android.hardware.radio.RadioIndicationType type, in String cmd); + oneway void stkProactiveCommand(in android.hardware.radio.RadioIndicationType type, in String cmd); + oneway void stkSessionEnd(in android.hardware.radio.RadioIndicationType type); + oneway void subscriptionStatusChanged(in android.hardware.radio.RadioIndicationType type, in boolean activate); + oneway void suppSvcNotify(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.SuppSvcNotification suppSvc); + oneway void uiccApplicationsEnablementChanged(in android.hardware.radio.RadioIndicationType type, in boolean enabled); + oneway void unthrottleApn(in android.hardware.radio.RadioIndicationType type, in String apn); + oneway void voiceRadioTechChanged(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.RadioTechnology rat); +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/IRadioResponse.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/IRadioResponse.aidl new file mode 100644 index 0000000000..9137b973ba --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/IRadioResponse.aidl @@ -0,0 +1,199 @@ +/* + * 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 -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.radio; +@VintfStability +interface IRadioResponse { + oneway void acceptCallResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void acknowledgeIncomingGsmSmsWithPduResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void acknowledgeLastIncomingCdmaSmsResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void acknowledgeLastIncomingGsmSmsResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void acknowledgeRequest(in int serial); + oneway void allocatePduSessionIdResponse(in android.hardware.radio.RadioResponseInfo info, in int id); + oneway void areUiccApplicationsEnabledResponse(in android.hardware.radio.RadioResponseInfo info, in boolean enabled); + oneway void cancelHandoverResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void cancelPendingUssdResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void changeIccPin2ForAppResponse(in android.hardware.radio.RadioResponseInfo info, in int remainingRetries); + oneway void changeIccPinForAppResponse(in android.hardware.radio.RadioResponseInfo info, in int remainingRetries); + oneway void conferenceResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void deactivateDataCallResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void deleteSmsOnRuimResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void deleteSmsOnSimResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void dialResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void emergencyDialResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void enableModemResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void enableUiccApplicationsResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void exitEmergencyCallbackModeResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void explicitCallTransferResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void getAllowedCarriersResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.CarrierRestrictionsWithPriority carriers, in android.hardware.radio.SimLockMultiSimPolicy multiSimPolicy); + oneway void getAllowedNetworkTypesBitmapResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.RadioAccessFamily networkTypeBitmap); + oneway void getAvailableBandModesResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.RadioBandMode[] bandModes); + oneway void getAvailableNetworksResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.OperatorInfo[] networkInfos); + oneway void getBarringInfoResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.CellIdentity cellIdentity, in android.hardware.radio.BarringInfo[] barringInfos); + oneway void getBasebandVersionResponse(in android.hardware.radio.RadioResponseInfo info, in String version); + oneway void getCDMASubscriptionResponse(in android.hardware.radio.RadioResponseInfo info, in String mdn, in String hSid, in String hNid, in String min, in String prl); + oneway void getCallForwardStatusResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.CallForwardInfo[] callForwardInfos); + oneway void getCallWaitingResponse(in android.hardware.radio.RadioResponseInfo info, in boolean enable, in int serviceClass); + oneway void getCdmaBroadcastConfigResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.CdmaBroadcastSmsConfigInfo[] configs); + oneway void getCdmaRoamingPreferenceResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.CdmaRoamingType type); + oneway void getCdmaSubscriptionSourceResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.CdmaSubscriptionSource source); + oneway void getCellInfoListResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.CellInfo[] cellInfo); + oneway void getClipResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.ClipStatus status); + oneway void getClirResponse(in android.hardware.radio.RadioResponseInfo info, in int n, in int m); + oneway void getCurrentCallsResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.Call[] calls); + oneway void getDataCallListResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.SetupDataCallResult[] dcResponse); + oneway void getDataRegistrationStateResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.RegStateResult dataRegResponse); + oneway void getDeviceIdentityResponse(in android.hardware.radio.RadioResponseInfo info, in String imei, in String imeisv, in String esn, in String meid); + oneway void getFacilityLockForAppResponse(in android.hardware.radio.RadioResponseInfo info, in int response); + oneway void getGsmBroadcastConfigResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.GsmBroadcastSmsConfigInfo[] configs); + oneway void getHardwareConfigResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.HardwareConfig[] config); + oneway void getIMSIForAppResponse(in android.hardware.radio.RadioResponseInfo info, in String imsi); + oneway void getIccCardStatusResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.CardStatus cardStatus); + oneway void getImsRegistrationStateResponse(in android.hardware.radio.RadioResponseInfo info, in boolean isRegistered, in android.hardware.radio.RadioTechnologyFamily ratFamily); + oneway void getLastCallFailCauseResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.LastCallFailCauseInfo failCauseinfo); + oneway void getModemActivityInfoResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.ActivityStatsInfo activityInfo); + oneway void getModemStackStatusResponse(in android.hardware.radio.RadioResponseInfo info, in boolean isEnabled); + oneway void getMuteResponse(in android.hardware.radio.RadioResponseInfo info, in boolean enable); + oneway void getNeighboringCidsResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.NeighboringCell[] cells); + oneway void getNetworkSelectionModeResponse(in android.hardware.radio.RadioResponseInfo info, in boolean manual); + oneway void getOperatorResponse(in android.hardware.radio.RadioResponseInfo info, in String longName, in String shortName, in String numeric); + oneway void getPreferredNetworkTypeBitmapResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.RadioAccessFamily networkTypeBitmap); + oneway void getPreferredNetworkTypeResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.PreferredNetworkType nwType); + oneway void getPreferredVoicePrivacyResponse(in android.hardware.radio.RadioResponseInfo info, in boolean enable); + oneway void getRadioCapabilityResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.RadioCapability rc); + oneway void getSignalStrengthResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.SignalStrength signalStrength); + oneway void getSimPhonebookCapacityResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.PhonebookCapacity capacity); + oneway void getSimPhonebookRecordsResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void getSlicingConfigResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.SlicingConfig slicingConfig); + oneway void getSmscAddressResponse(in android.hardware.radio.RadioResponseInfo info, in String smsc); + oneway void getSystemSelectionChannelsResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.RadioAccessSpecifier[] specifiers); + oneway void getTTYModeResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.TtyMode mode); + oneway void getVoiceRadioTechnologyResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.RadioTechnology rat); + oneway void getVoiceRegistrationStateResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.RegStateResult voiceRegResponse); + oneway void handleStkCallSetupRequestFromSimResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void hangupConnectionResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void hangupForegroundResumeBackgroundResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void hangupWaitingOrBackgroundResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void iccCloseLogicalChannelResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void iccIOForAppResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.IccIoResult iccIo); + oneway void iccOpenLogicalChannelResponse(in android.hardware.radio.RadioResponseInfo info, in int channelId, in byte[] selectResponse); + oneway void iccTransmitApduBasicChannelResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.IccIoResult result); + oneway void iccTransmitApduLogicalChannelResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.IccIoResult result); + oneway void isNrDualConnectivityEnabledResponse(in android.hardware.radio.RadioResponseInfo info, in boolean isEnabled); + oneway void nvReadItemResponse(in android.hardware.radio.RadioResponseInfo info, in String result); + oneway void nvResetConfigResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void nvWriteCdmaPrlResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void nvWriteItemResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void pullLceDataResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.LceDataInfo lceInfo); + oneway void rejectCallResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void releasePduSessionIdResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void reportSmsMemoryStatusResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void reportStkServiceIsRunningResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void requestIccSimAuthenticationResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.IccIoResult result); + oneway void requestIsimAuthenticationResponse(in android.hardware.radio.RadioResponseInfo info, in String response); + oneway void requestShutdownResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void sendBurstDtmfResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void sendCDMAFeatureCodeResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void sendCdmaSmsExpectMoreResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.SendSmsResult sms); + oneway void sendCdmaSmsResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.SendSmsResult sms); + oneway void sendDeviceStateResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void sendDtmfResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void sendEnvelopeResponse(in android.hardware.radio.RadioResponseInfo info, in String commandResponse); + oneway void sendEnvelopeWithStatusResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.IccIoResult iccIo); + oneway void sendImsSmsResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.SendSmsResult sms); + oneway void sendSMSExpectMoreResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.SendSmsResult sms); + oneway void sendSmsExpectMoreResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.SendSmsResult sms); + oneway void sendSmsResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.SendSmsResult sms); + oneway void sendTerminalResponseToSimResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void sendUssdResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void separateConnectionResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setAllowedCarriersResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setAllowedNetworkTypesBitmapResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setBandModeResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setBarringPasswordResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setCallForwardResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setCallWaitingResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setCarrierInfoForImsiEncryptionResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setCdmaBroadcastActivationResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setCdmaBroadcastConfigResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setCdmaRoamingPreferenceResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setCdmaSubscriptionSourceResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setCellInfoListRateResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setClirResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setDataAllowedResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setDataProfileResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setDataThrottlingResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setFacilityLockForAppResponse(in android.hardware.radio.RadioResponseInfo info, in int retry); + oneway void setGsmBroadcastActivationResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setGsmBroadcastConfigResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setIndicationFilterResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setInitialAttachApnResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setLinkCapacityReportingCriteriaResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setLocationUpdatesResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setMuteResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setNetworkSelectionModeAutomaticResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setNetworkSelectionModeManualResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setNrDualConnectivityStateResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setPreferredNetworkTypeBitmapResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setPreferredNetworkTypeResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setPreferredVoicePrivacyResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setRadioCapabilityResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.RadioCapability rc); + oneway void setRadioPowerResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setSignalStrengthReportingCriteriaResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setSimCardPowerResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setSmscAddressResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setSuppServiceNotificationsResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setSystemSelectionChannelsResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setTTYModeResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setUiccSubscriptionResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setupDataCallResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.SetupDataCallResult dcResponse); + oneway void startDtmfResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void startHandoverResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void startKeepaliveResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.KeepaliveStatus status); + oneway void startLceServiceResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.LceStatusInfo statusInfo); + oneway void startNetworkScanResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void stopDtmfResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void stopKeepaliveResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void stopLceServiceResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.LceStatusInfo statusInfo); + oneway void stopNetworkScanResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void supplyIccPin2ForAppResponse(in android.hardware.radio.RadioResponseInfo info, in int remainingRetries); + oneway void supplyIccPinForAppResponse(in android.hardware.radio.RadioResponseInfo info, in int remainingRetries); + oneway void supplyIccPuk2ForAppResponse(in android.hardware.radio.RadioResponseInfo info, in int remainingRetries); + oneway void supplyIccPukForAppResponse(in android.hardware.radio.RadioResponseInfo info, in int remainingRetries); + oneway void supplyNetworkDepersonalizationResponse(in android.hardware.radio.RadioResponseInfo info, in int remainingRetries); + oneway void supplySimDepersonalizationResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.PersoSubstate persoType, in int remainingRetries); + oneway void switchWaitingOrHoldingAndActiveResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void updateSimPhonebookRecordsResponse(in android.hardware.radio.RadioResponseInfo info, in int updatedRecordIndex); + oneway void writeSmsToRuimResponse(in android.hardware.radio.RadioResponseInfo info, in int index); + oneway void writeSmsToSimResponse(in android.hardware.radio.RadioResponseInfo info, in int index); +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ISap.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ISap.aidl new file mode 100644 index 0000000000..fa0426442a --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ISap.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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.radio; +@VintfStability +interface ISap { + oneway void apduReq(in int token, in android.hardware.radio.SapApduType type, in byte[] command); + oneway void connectReq(in int token, in int maxMsgSize); + oneway void disconnectReq(in int token); + oneway void powerReq(in int token, in boolean state); + oneway void resetSimReq(in int token); + void setCallback(in android.hardware.radio.ISapCallback sapCallback); + oneway void setTransferProtocolReq(in int token, in android.hardware.radio.SapTransferProtocol transferProtocol); + oneway void transferAtrReq(in int token); + oneway void transferCardReaderStatusReq(in int token); +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ISapCallback.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ISapCallback.aidl new file mode 100644 index 0000000000..5ae0392c29 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ISapCallback.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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.radio; +@VintfStability +interface ISapCallback { + oneway void apduResponse(in int token, in android.hardware.radio.SapResultCode resultCode, in byte[] apduRsp); + oneway void connectResponse(in int token, in android.hardware.radio.SapConnectRsp sapConnectRsp, in int maxMsgSize); + oneway void disconnectIndication(in int token, in android.hardware.radio.SapDisconnectType disconnectType); + oneway void disconnectResponse(in int token); + oneway void errorResponse(in int token); + oneway void powerResponse(in int token, in android.hardware.radio.SapResultCode resultCode); + oneway void resetSimResponse(in int token, in android.hardware.radio.SapResultCode resultCode); + oneway void statusIndication(in int token, in android.hardware.radio.SapStatus status); + oneway void transferAtrResponse(in int token, in android.hardware.radio.SapResultCode resultCode, in byte[] atr); + oneway void transferCardReaderStatusResponse(in int token, in android.hardware.radio.SapResultCode resultCode, in int cardReaderStatus); + oneway void transferProtocolResponse(in int token, in android.hardware.radio.SapResultCode resultCode); +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/IccIo.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/IccIo.aidl new file mode 100644 index 0000000000..1bea23a438 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/IccIo.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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.radio; +@VintfStability +parcelable IccIo { + int command; + int fileId; + String path; + int p1; + int p2; + int p3; + String data; + String pin2; + String aid; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/IccIoResult.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/IccIoResult.aidl new file mode 100644 index 0000000000..50b1e9e68f --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/IccIoResult.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 -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.radio; +@VintfStability +parcelable IccIoResult { + int sw1; + int sw2; + String simResponse; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ImsSmsMessage.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ImsSmsMessage.aidl new file mode 100644 index 0000000000..b5ffcc6474 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ImsSmsMessage.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 -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.radio; +@VintfStability +parcelable ImsSmsMessage { + android.hardware.radio.RadioTechnologyFamily tech; + boolean retry; + int messageRef; + android.hardware.radio.CdmaSmsMessage[] cdmaMessage; + android.hardware.radio.GsmSmsMessage[] gsmMessage; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ImsiEncryptionInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ImsiEncryptionInfo.aidl new file mode 100644 index 0000000000..c89c3a0f7a --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ImsiEncryptionInfo.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 -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.radio; +@VintfStability +parcelable ImsiEncryptionInfo { + String mcc; + String mnc; + byte[] carrierKey; + String keyIdentifier; + long expirationTime; + android.hardware.radio.PublicKeyType keyType; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/IncrementalResultsPeriodicityRange.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/IncrementalResultsPeriodicityRange.aidl new file mode 100644 index 0000000000..ad3441f445 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/IncrementalResultsPeriodicityRange.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 -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.radio; +@Backing(type="int") @VintfStability +enum IncrementalResultsPeriodicityRange { + MIN = 1, + MAX = 10, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/IndicationFilter.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/IndicationFilter.aidl new file mode 100644 index 0000000000..629af68d64 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/IndicationFilter.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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.radio; +@Backing(type="int") @VintfStability +enum IndicationFilter { + NONE = 0, + ALL = -1, + SIGNAL_STRENGTH = 1, + FULL_NETWORK_STATE = 2, + DATA_CALL_DORMANCY_CHANGED = 4, + LINK_CAPACITY_ESTIMATE = 8, + PHYSICAL_CHANNEL_CONFIG = 16, + REGISTRATION_FAILURE = 32, + BARRING_INFO = 64, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/KeepaliveRequest.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/KeepaliveRequest.aidl new file mode 100644 index 0000000000..1f23a6927f --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/KeepaliveRequest.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 -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.radio; +@VintfStability +parcelable KeepaliveRequest { + android.hardware.radio.KeepaliveType type; + byte[] sourceAddress; + int sourcePort; + byte[] destinationAddress; + int destinationPort; + int maxKeepaliveIntervalMillis; + int cid; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/KeepaliveStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/KeepaliveStatus.aidl new file mode 100644 index 0000000000..8729b69e39 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/KeepaliveStatus.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 -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.radio; +@VintfStability +parcelable KeepaliveStatus { + int sessionHandle; + android.hardware.radio.KeepaliveStatusCode code; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/KeepaliveStatusCode.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/KeepaliveStatusCode.aidl new file mode 100644 index 0000000000..8ad5dc5dba --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/KeepaliveStatusCode.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 -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.radio; +@Backing(type="int") @VintfStability +enum KeepaliveStatusCode { + ACTIVE = 0, + INACTIVE = 1, + PENDING = 2, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/KeepaliveType.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/KeepaliveType.aidl new file mode 100644 index 0000000000..f0dd5216fb --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/KeepaliveType.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 -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.radio; +@Backing(type="int") @VintfStability +enum KeepaliveType { + NATT_IPV4 = 0, + NATT_IPV6 = 1, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LastCallFailCause.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LastCallFailCause.aidl new file mode 100644 index 0000000000..024f7ead24 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LastCallFailCause.aidl @@ -0,0 +1,133 @@ +/* + * 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 -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.radio; +@Backing(type="int") @VintfStability +enum LastCallFailCause { + UNOBTAINABLE_NUMBER = 1, + NO_ROUTE_TO_DESTINATION = 3, + CHANNEL_UNACCEPTABLE = 6, + OPERATOR_DETERMINED_BARRING = 8, + NORMAL = 16, + BUSY = 17, + NO_USER_RESPONDING = 18, + NO_ANSWER_FROM_USER = 19, + CALL_REJECTED = 21, + NUMBER_CHANGED = 22, + PREEMPTION = 25, + DESTINATION_OUT_OF_ORDER = 27, + INVALID_NUMBER_FORMAT = 28, + FACILITY_REJECTED = 29, + RESP_TO_STATUS_ENQUIRY = 30, + NORMAL_UNSPECIFIED = 31, + CONGESTION = 34, + NETWORK_OUT_OF_ORDER = 38, + TEMPORARY_FAILURE = 41, + SWITCHING_EQUIPMENT_CONGESTION = 42, + ACCESS_INFORMATION_DISCARDED = 43, + REQUESTED_CIRCUIT_OR_CHANNEL_NOT_AVAILABLE = 44, + RESOURCES_UNAVAILABLE_OR_UNSPECIFIED = 47, + QOS_UNAVAILABLE = 49, + REQUESTED_FACILITY_NOT_SUBSCRIBED = 50, + INCOMING_CALLS_BARRED_WITHIN_CUG = 55, + BEARER_CAPABILITY_NOT_AUTHORIZED = 57, + BEARER_CAPABILITY_UNAVAILABLE = 58, + SERVICE_OPTION_NOT_AVAILABLE = 63, + BEARER_SERVICE_NOT_IMPLEMENTED = 65, + ACM_LIMIT_EXCEEDED = 68, + REQUESTED_FACILITY_NOT_IMPLEMENTED = 69, + ONLY_DIGITAL_INFORMATION_BEARER_AVAILABLE = 70, + SERVICE_OR_OPTION_NOT_IMPLEMENTED = 79, + INVALID_TRANSACTION_IDENTIFIER = 81, + USER_NOT_MEMBER_OF_CUG = 87, + INCOMPATIBLE_DESTINATION = 88, + INVALID_TRANSIT_NW_SELECTION = 91, + SEMANTICALLY_INCORRECT_MESSAGE = 95, + INVALID_MANDATORY_INFORMATION = 96, + MESSAGE_TYPE_NON_IMPLEMENTED = 97, + MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE = 98, + INFORMATION_ELEMENT_NON_EXISTENT = 99, + CONDITIONAL_IE_ERROR = 100, + MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE = 101, + RECOVERY_ON_TIMER_EXPIRED = 102, + PROTOCOL_ERROR_UNSPECIFIED = 111, + INTERWORKING_UNSPECIFIED = 127, + CALL_BARRED = 240, + FDN_BLOCKED = 241, + IMSI_UNKNOWN_IN_VLR = 242, + IMEI_NOT_ACCEPTED = 243, + DIAL_MODIFIED_TO_USSD = 244, + DIAL_MODIFIED_TO_SS = 245, + DIAL_MODIFIED_TO_DIAL = 246, + RADIO_OFF = 247, + OUT_OF_SERVICE = 248, + NO_VALID_SIM = 249, + RADIO_INTERNAL_ERROR = 250, + NETWORK_RESP_TIMEOUT = 251, + NETWORK_REJECT = 252, + RADIO_ACCESS_FAILURE = 253, + RADIO_LINK_FAILURE = 254, + RADIO_LINK_LOST = 255, + RADIO_UPLINK_FAILURE = 256, + RADIO_SETUP_FAILURE = 257, + RADIO_RELEASE_NORMAL = 258, + RADIO_RELEASE_ABNORMAL = 259, + ACCESS_CLASS_BLOCKED = 260, + NETWORK_DETACH = 261, + CDMA_LOCKED_UNTIL_POWER_CYCLE = 1000, + CDMA_DROP = 1001, + CDMA_INTERCEPT = 1002, + CDMA_REORDER = 1003, + CDMA_SO_REJECT = 1004, + CDMA_RETRY_ORDER = 1005, + CDMA_ACCESS_FAILURE = 1006, + CDMA_PREEMPTED = 1007, + CDMA_NOT_EMERGENCY = 1008, + CDMA_ACCESS_BLOCKED = 1009, + OEM_CAUSE_1 = 61441, + OEM_CAUSE_2 = 61442, + OEM_CAUSE_3 = 61443, + OEM_CAUSE_4 = 61444, + OEM_CAUSE_5 = 61445, + OEM_CAUSE_6 = 61446, + OEM_CAUSE_7 = 61447, + OEM_CAUSE_8 = 61448, + OEM_CAUSE_9 = 61449, + OEM_CAUSE_10 = 61450, + OEM_CAUSE_11 = 61451, + OEM_CAUSE_12 = 61452, + OEM_CAUSE_13 = 61453, + OEM_CAUSE_14 = 61454, + OEM_CAUSE_15 = 61455, + ERROR_UNSPECIFIED = 65535, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LastCallFailCauseInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LastCallFailCauseInfo.aidl new file mode 100644 index 0000000000..43ef0cd01b --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LastCallFailCauseInfo.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 -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.radio; +@VintfStability +parcelable LastCallFailCauseInfo { + android.hardware.radio.LastCallFailCause causeCode; + String vendorCause; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LceDataInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LceDataInfo.aidl new file mode 100644 index 0000000000..64c63674c6 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LceDataInfo.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 -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.radio; +@VintfStability +parcelable LceDataInfo { + int lastHopCapacityKbps; + byte confidenceLevel; + boolean lceSuspended; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LceStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LceStatus.aidl new file mode 100644 index 0000000000..2542cc7de9 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LceStatus.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 -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.radio; +@Backing(type="int") @VintfStability +enum LceStatus { + NOT_SUPPORTED = 0, + STOPPED = 1, + ACTIVE = 2, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LceStatusInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LceStatusInfo.aidl new file mode 100644 index 0000000000..29f5ab60f2 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LceStatusInfo.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 -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.radio; +@VintfStability +parcelable LceStatusInfo { + android.hardware.radio.LceStatus lceStatus; + byte actualIntervalMs; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LinkAddress.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LinkAddress.aidl new file mode 100644 index 0000000000..b64daf9de1 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LinkAddress.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 -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.radio; +@VintfStability +parcelable LinkAddress { + String address; + android.hardware.radio.AddressProperty properties; + long deprecationTime; + long expirationTime; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LinkCapacityEstimate.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LinkCapacityEstimate.aidl new file mode 100644 index 0000000000..d2a5c83a3c --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LinkCapacityEstimate.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 -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.radio; +@VintfStability +parcelable LinkCapacityEstimate { + int downlinkCapacityKbps; + int uplinkCapacityKbps; + int secondaryDownlinkCapacityKbps; + int secondaryUplinkCapacityKbps; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LteSignalStrength.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LteSignalStrength.aidl new file mode 100644 index 0000000000..28840bccef --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LteSignalStrength.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 -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.radio; +@VintfStability +parcelable LteSignalStrength { + int signalStrength; + int rsrp; + int rsrq; + int rssnr; + int cqi; + int timingAdvance; + int cqiTableIndex; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LteVopsInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LteVopsInfo.aidl new file mode 100644 index 0000000000..b28c415c3e --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LteVopsInfo.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 -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.radio; +@VintfStability +parcelable LteVopsInfo { + boolean isVopsSupported; + boolean isEmcBearerSupported; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/MaxSearchTimeRange.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/MaxSearchTimeRange.aidl new file mode 100644 index 0000000000..88cdf5fe18 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/MaxSearchTimeRange.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 -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.radio; +@Backing(type="int") @VintfStability +enum MaxSearchTimeRange { + MIN = 60, + MAX = 3600, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/MaybePort.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/MaybePort.aidl new file mode 100644 index 0000000000..f556c7f8a3 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/MaybePort.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 -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.radio; +@VintfStability +union MaybePort { + boolean noinit; + android.hardware.radio.PortRange range; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/MvnoType.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/MvnoType.aidl new file mode 100644 index 0000000000..8be23b6607 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/MvnoType.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 -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.radio; +@Backing(type="int") @VintfStability +enum MvnoType { + NONE = 0, + IMSI = 1, + GID = 2, + SPN = 3, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NeighboringCell.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NeighboringCell.aidl new file mode 100644 index 0000000000..89d7818fe8 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NeighboringCell.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 -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.radio; +@VintfStability +parcelable NeighboringCell { + String cid; + int rssi; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NetworkScanRequest.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NetworkScanRequest.aidl new file mode 100644 index 0000000000..4e6f6139b1 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NetworkScanRequest.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 -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.radio; +@VintfStability +parcelable NetworkScanRequest { + android.hardware.radio.ScanType type; + int interval; + android.hardware.radio.RadioAccessSpecifier[] specifiers; + int maxSearchTime; + boolean incrementalResults; + int incrementalResultsPeriodicity; + String[] mccMncs; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NetworkScanResult.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NetworkScanResult.aidl new file mode 100644 index 0000000000..86543e3e1b --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NetworkScanResult.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 -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.radio; +@VintfStability +parcelable NetworkScanResult { + android.hardware.radio.ScanStatus status; + android.hardware.radio.RadioError error; + android.hardware.radio.CellInfo[] networkInfos; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NgranBands.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NgranBands.aidl new file mode 100644 index 0000000000..14db49b1ec --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NgranBands.aidl @@ -0,0 +1,90 @@ +/* + * 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 -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.radio; +@Backing(type="int") @VintfStability +enum NgranBands { + BAND_1 = 1, + BAND_2 = 2, + BAND_3 = 3, + BAND_5 = 5, + BAND_7 = 7, + BAND_8 = 8, + BAND_12 = 12, + BAND_14 = 14, + BAND_18 = 18, + BAND_20 = 20, + BAND_25 = 25, + BAND_26 = 26, + BAND_28 = 28, + BAND_29 = 29, + BAND_30 = 30, + BAND_34 = 34, + BAND_38 = 38, + BAND_39 = 39, + BAND_40 = 40, + BAND_41 = 41, + BAND_46 = 46, + BAND_48 = 48, + BAND_50 = 50, + BAND_51 = 51, + BAND_53 = 53, + BAND_65 = 65, + BAND_66 = 66, + BAND_70 = 70, + BAND_71 = 71, + BAND_74 = 74, + BAND_75 = 75, + BAND_76 = 76, + BAND_77 = 77, + BAND_78 = 78, + BAND_79 = 79, + BAND_80 = 80, + BAND_81 = 81, + BAND_82 = 82, + BAND_83 = 83, + BAND_84 = 84, + BAND_86 = 86, + BAND_89 = 89, + BAND_90 = 90, + BAND_91 = 91, + BAND_92 = 92, + BAND_93 = 93, + BAND_94 = 94, + BAND_95 = 95, + BAND_96 = 96, + BAND_257 = 257, + BAND_258 = 258, + BAND_260 = 260, + BAND_261 = 261, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NrDualConnectivityState.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NrDualConnectivityState.aidl new file mode 100644 index 0000000000..c3fb9f2fd8 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NrDualConnectivityState.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 -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.radio; +@Backing(type="byte") @VintfStability +enum NrDualConnectivityState { + ENABLE = 1, + DISABLE = 2, + DISABLE_IMMEDIATE = 3, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NrIndicators.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NrIndicators.aidl new file mode 100644 index 0000000000..81dc51c36e --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NrIndicators.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 -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.radio; +@VintfStability +parcelable NrIndicators { + boolean isEndcAvailable; + boolean isDcNrRestricted; + boolean isNrAvailable; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NrQos.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NrQos.aidl new file mode 100644 index 0000000000..6cb8f33704 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NrQos.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 -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.radio; +@VintfStability +parcelable NrQos { + int fiveQi; + android.hardware.radio.QosBandwidth downlink; + android.hardware.radio.QosBandwidth uplink; + byte qfi; + char averagingWindowMs; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NrSignalStrength.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NrSignalStrength.aidl new file mode 100644 index 0000000000..daf6a418ff --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NrSignalStrength.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 -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.radio; +@VintfStability +parcelable NrSignalStrength { + int ssRsrp; + int ssRsrq; + int ssSinr; + int csiRsrp; + int csiRsrq; + int csiSinr; + int csiCqiTableIndex; + byte[] csiCqiReport; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NrVopsInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NrVopsInfo.aidl new file mode 100644 index 0000000000..b737aaf414 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NrVopsInfo.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 -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.radio; +@VintfStability +parcelable NrVopsInfo { + android.hardware.radio.VopsIndicator vopsSupported; + android.hardware.radio.EmcIndicator emcSupported; + android.hardware.radio.EmfIndicator emfSupported; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NvItem.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NvItem.aidl new file mode 100644 index 0000000000..d7706c5dc2 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NvItem.aidl @@ -0,0 +1,78 @@ +/* + * 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 -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.radio; +@Backing(type="int") @VintfStability +enum NvItem { + CDMA_MEID = 1, + CDMA_MIN = 2, + CDMA_MDN = 3, + CDMA_ACCOLC = 4, + DEVICE_MSL = 11, + RTN_RECONDITIONED_STATUS = 12, + RTN_ACTIVATION_DATE = 13, + RTN_LIFE_TIMER = 14, + RTN_LIFE_CALLS = 15, + RTN_LIFE_DATA_TX = 16, + RTN_LIFE_DATA_RX = 17, + OMADM_HFA_LEVEL = 18, + MIP_PROFILE_NAI = 31, + MIP_PROFILE_HOME_ADDRESS = 32, + MIP_PROFILE_AAA_AUTH = 33, + MIP_PROFILE_HA_AUTH = 34, + MIP_PROFILE_PRI_HA_ADDR = 35, + MIP_PROFILE_SEC_HA_ADDR = 36, + MIP_PROFILE_REV_TUN_PREF = 37, + MIP_PROFILE_HA_SPI = 38, + MIP_PROFILE_AAA_SPI = 39, + MIP_PROFILE_MN_HA_SS = 40, + MIP_PROFILE_MN_AAA_SS = 41, + CDMA_PRL_VERSION = 51, + CDMA_BC10 = 52, + CDMA_BC14 = 53, + CDMA_SO68 = 54, + CDMA_SO73_COP0 = 55, + CDMA_SO73_COP1TO7 = 56, + CDMA_1X_ADVANCED_ENABLED = 57, + CDMA_EHRPD_ENABLED = 58, + CDMA_EHRPD_FORCED = 59, + LTE_BAND_ENABLE_25 = 71, + LTE_BAND_ENABLE_26 = 72, + LTE_BAND_ENABLE_41 = 73, + LTE_SCAN_PRIORITY_25 = 74, + LTE_SCAN_PRIORITY_26 = 75, + LTE_SCAN_PRIORITY_41 = 76, + LTE_HIDDEN_BAND_PRIORITY_25 = 77, + LTE_HIDDEN_BAND_PRIORITY_26 = 78, + LTE_HIDDEN_BAND_PRIORITY_41 = 79, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NvWriteItem.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NvWriteItem.aidl new file mode 100644 index 0000000000..9e60db6a28 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NvWriteItem.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 -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.radio; +@VintfStability +parcelable NvWriteItem { + android.hardware.radio.NvItem itemId; + String value; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/OperatorInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/OperatorInfo.aidl new file mode 100644 index 0000000000..2f29c022f7 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/OperatorInfo.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 -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.radio; +@VintfStability +parcelable OperatorInfo { + String alphaLong; + String alphaShort; + String operatorNumeric; + android.hardware.radio.OperatorStatus status; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/OperatorStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/OperatorStatus.aidl new file mode 100644 index 0000000000..4ef10caada --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/OperatorStatus.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 -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.radio; +@Backing(type="int") @VintfStability +enum OperatorStatus { + UNKNOWN = 0, + AVAILABLE = 1, + CURRENT = 2, + FORBIDDEN = 3, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/OptionalCsgInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/OptionalCsgInfo.aidl new file mode 100644 index 0000000000..6866dcaf94 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/OptionalCsgInfo.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 -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.radio; +@VintfStability +union OptionalCsgInfo { + boolean noinit; + android.hardware.radio.ClosedSubscriberGroupInfo csgInfo; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/OptionalDnn.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/OptionalDnn.aidl new file mode 100644 index 0000000000..88582dea50 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/OptionalDnn.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 -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.radio; +@VintfStability +union OptionalDnn { + boolean noinit; + String value; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/OptionalOsAppId.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/OptionalOsAppId.aidl new file mode 100644 index 0000000000..40bfa41026 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/OptionalOsAppId.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 -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.radio; +@VintfStability +union OptionalOsAppId { + boolean noinit; + android.hardware.radio.OsAppId value; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/OptionalPdpProtocolType.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/OptionalPdpProtocolType.aidl new file mode 100644 index 0000000000..5b4964f0c8 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/OptionalPdpProtocolType.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 -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.radio; +@VintfStability +union OptionalPdpProtocolType { + boolean noinit; + android.hardware.radio.PdpProtocolType value; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/OptionalSliceInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/OptionalSliceInfo.aidl new file mode 100644 index 0000000000..d640aac680 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/OptionalSliceInfo.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 -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.radio; +@VintfStability +union OptionalSliceInfo { + boolean noinit; + android.hardware.radio.SliceInfo value; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/OptionalSscMode.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/OptionalSscMode.aidl new file mode 100644 index 0000000000..047261524d --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/OptionalSscMode.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 -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.radio; +@VintfStability +union OptionalSscMode { + boolean noinit; + android.hardware.radio.SscMode value; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/OptionalTrafficDescriptor.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/OptionalTrafficDescriptor.aidl new file mode 100644 index 0000000000..6b575255f8 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/OptionalTrafficDescriptor.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 -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.radio; +@VintfStability +union OptionalTrafficDescriptor { + boolean noinit; + android.hardware.radio.TrafficDescriptor value; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/OsAppId.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/OsAppId.aidl new file mode 100644 index 0000000000..bc112296e9 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/OsAppId.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 -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.radio; +@VintfStability +parcelable OsAppId { + byte[] osAppId; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/P2Constant.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/P2Constant.aidl new file mode 100644 index 0000000000..eb8b442c98 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/P2Constant.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 -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.radio; +@Backing(type="int") @VintfStability +enum P2Constant { + NO_P2 = -1, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PbReceivedStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PbReceivedStatus.aidl new file mode 100644 index 0000000000..dd95ad5127 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PbReceivedStatus.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 -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.radio; +@Backing(type="byte") @VintfStability +enum PbReceivedStatus { + PB_RECEIVED_OK = 1, + PB_RECEIVED_ERROR = 2, + PB_RECEIVED_ABORT = 3, + PB_RECEIVED_FINAL = 4, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PcoDataInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PcoDataInfo.aidl new file mode 100644 index 0000000000..828b08c610 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PcoDataInfo.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 -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.radio; +@VintfStability +parcelable PcoDataInfo { + int cid; + String bearerProto; + int pcoId; + byte[] contents; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PdpProtocolType.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PdpProtocolType.aidl new file mode 100644 index 0000000000..980d3afc39 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PdpProtocolType.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 -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.radio; +@Backing(type="int") @VintfStability +enum PdpProtocolType { + UNKNOWN = -1, + IP = 0, + IPV6 = 1, + IPV4V6 = 2, + PPP = 3, + NON_IP = 4, + UNSTRUCTURED = 5, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PersoSubstate.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PersoSubstate.aidl new file mode 100644 index 0000000000..35b75c63dd --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PersoSubstate.aidl @@ -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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.radio; +@Backing(type="int") @VintfStability +enum PersoSubstate { + UNKNOWN = 0, + IN_PROGRESS = 1, + READY = 2, + SIM_NETWORK = 3, + SIM_NETWORK_SUBSET = 4, + SIM_CORPORATE = 5, + SIM_SERVICE_PROVIDER = 6, + SIM_SIM = 7, + SIM_NETWORK_PUK = 8, + SIM_NETWORK_SUBSET_PUK = 9, + SIM_CORPORATE_PUK = 10, + SIM_SERVICE_PROVIDER_PUK = 11, + SIM_SIM_PUK = 12, + RUIM_NETWORK1 = 13, + RUIM_NETWORK2 = 14, + RUIM_HRPD = 15, + RUIM_CORPORATE = 16, + RUIM_SERVICE_PROVIDER = 17, + RUIM_RUIM = 18, + RUIM_NETWORK1_PUK = 19, + RUIM_NETWORK2_PUK = 20, + RUIM_HRPD_PUK = 21, + RUIM_CORPORATE_PUK = 22, + RUIM_SERVICE_PROVIDER_PUK = 23, + RUIM_RUIM_PUK = 24, + SIM_SPN = 25, + SIM_SPN_PUK = 26, + SIM_SP_EHPLMN = 27, + SIM_SP_EHPLMN_PUK = 28, + SIM_ICCID = 29, + SIM_ICCID_PUK = 30, + SIM_IMPI = 31, + SIM_IMPI_PUK = 32, + SIM_NS_SP = 33, + SIM_NS_SP_PUK = 34, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PhoneRestrictedState.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PhoneRestrictedState.aidl new file mode 100644 index 0000000000..7a4982f5ea --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PhoneRestrictedState.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 -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.radio; +@Backing(type="int") @VintfStability +enum PhoneRestrictedState { + NONE = 0, + CS_EMERGENCY = 1, + CS_NORMAL = 2, + CS_ALL = 4, + PS_ALL = 16, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PhonebookCapacity.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PhonebookCapacity.aidl new file mode 100644 index 0000000000..8d2623bbb5 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PhonebookCapacity.aidl @@ -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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.radio; +@VintfStability +parcelable PhonebookCapacity { + int maxAdnRecords; + int usedAdnRecords; + int maxEmailRecords; + int usedEmailRecords; + int maxAdditionalNumberRecords; + int usedAdditionalNumberRecords; + int maxNameLen; + int maxNumberLen; + int maxEmailLen; + int maxAdditionalNumberLen; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PhonebookRecordInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PhonebookRecordInfo.aidl new file mode 100644 index 0000000000..02a166e18c --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PhonebookRecordInfo.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 -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.radio; +@VintfStability +parcelable PhonebookRecordInfo { + int recordId; + String name; + String number; + String[] emails; + String[] additionalNumbers; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PhysicalChannelConfig.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PhysicalChannelConfig.aidl new file mode 100644 index 0000000000..91c4a96a1f --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PhysicalChannelConfig.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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.radio; +@VintfStability +parcelable PhysicalChannelConfig { + android.hardware.radio.CellConnectionStatus status; + android.hardware.radio.RadioTechnology rat; + int downlinkChannelNumber; + int uplinkChannelNumber; + int cellBandwidthDownlinkKhz; + int cellBandwidthUplinkKhz; + int[] contextIds; + int physicalCellId; + android.hardware.radio.PhysicalChannelConfigBand band; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PhysicalChannelConfigBand.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PhysicalChannelConfigBand.aidl new file mode 100644 index 0000000000..1953083771 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PhysicalChannelConfigBand.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 -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.radio; +@VintfStability +union PhysicalChannelConfigBand { + boolean noinit; + android.hardware.radio.GeranBands geranBand; + android.hardware.radio.UtranBands utranBand; + android.hardware.radio.EutranBands eutranBand; + android.hardware.radio.NgranBands ngranBand; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PinState.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PinState.aidl new file mode 100644 index 0000000000..3b65179748 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PinState.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 -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.radio; +@Backing(type="int") @VintfStability +enum PinState { + UNKNOWN = 0, + ENABLED_NOT_VERIFIED = 1, + ENABLED_VERIFIED = 2, + DISABLED = 3, + ENABLED_BLOCKED = 4, + ENABLED_PERM_BLOCKED = 5, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PortRange.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PortRange.aidl new file mode 100644 index 0000000000..9e4d2720f8 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PortRange.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 -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.radio; +@VintfStability +parcelable PortRange { + int start; + int end; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PreferredNetworkType.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PreferredNetworkType.aidl new file mode 100644 index 0000000000..7615dff86f --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PreferredNetworkType.aidl @@ -0,0 +1,60 @@ +/* + * 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 -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.radio; +@Backing(type="int") @VintfStability +enum PreferredNetworkType { + GSM_WCDMA = 0, + GSM_ONLY = 1, + WCDMA = 2, + GSM_WCDMA_AUTO = 3, + CDMA_EVDO_AUTO = 4, + CDMA_ONLY = 5, + EVDO_ONLY = 6, + GSM_WCDMA_CDMA_EVDO_AUTO = 7, + LTE_CDMA_EVDO = 8, + LTE_GSM_WCDMA = 9, + LTE_CMDA_EVDO_GSM_WCDMA = 10, + LTE_ONLY = 11, + LTE_WCDMA = 12, + TD_SCDMA_ONLY = 13, + TD_SCDMA_WCDMA = 14, + TD_SCDMA_LTE = 15, + TD_SCDMA_GSM = 16, + TD_SCDMA_GSM_LTE = 17, + TD_SCDMA_GSM_WCDMA = 18, + TD_SCDMA_WCDMA_LTE = 19, + TD_SCDMA_GSM_WCDMA_LTE = 20, + TD_SCDMA_GSM_WCDMA_CDMA_EVDO_AUTO = 21, + TD_SCDMA_LTE_CDMA_EVDO_GSM_WCDMA = 22, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PrlIndicator.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PrlIndicator.aidl new file mode 100644 index 0000000000..b596d305b4 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PrlIndicator.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 -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.radio; +@Backing(type="int") @VintfStability +enum PrlIndicator { + NOT_REGISTERED = -1, + NOT_IN_PRL = 0, + IN_PRL = 1, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PublicKeyType.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PublicKeyType.aidl new file mode 100644 index 0000000000..68d96e86ed --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PublicKeyType.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 -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.radio; +@Backing(type="byte") @VintfStability +enum PublicKeyType { + EPDG = 1, + WLAN = 2, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/Qos.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/Qos.aidl new file mode 100644 index 0000000000..d69853fa2b --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/Qos.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 -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.radio; +@VintfStability +union Qos { + boolean noinit; + android.hardware.radio.EpsQos eps; + android.hardware.radio.NrQos nr; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/QosBandwidth.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/QosBandwidth.aidl new file mode 100644 index 0000000000..95622bc31e --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/QosBandwidth.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 -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.radio; +@VintfStability +parcelable QosBandwidth { + int maxBitrateKbps; + int guaranteedBitrateKbps; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/QosFilter.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/QosFilter.aidl new file mode 100644 index 0000000000..3376c6626b --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/QosFilter.aidl @@ -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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.radio; +@VintfStability +parcelable QosFilter { + String[] localAddresses; + String[] remoteAddresses; + android.hardware.radio.MaybePort localPort; + android.hardware.radio.MaybePort remotePort; + android.hardware.radio.QosProtocol protocol; + android.hardware.radio.QosFilterTypeOfService tos; + android.hardware.radio.QosFilterIpv6FlowLabel flowLabel; + android.hardware.radio.QosFilterIpsecSpi spi; + android.hardware.radio.QosFilterDirection direction; + int precedence; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/QosFilterDirection.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/QosFilterDirection.aidl new file mode 100644 index 0000000000..efb9c504cf --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/QosFilterDirection.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 -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.radio; +@Backing(type="byte") @VintfStability +enum QosFilterDirection { + DOWNLINK = 0, + UPLINK = 1, + BIDIRECTIONAL = 2, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/QosFilterIpsecSpi.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/QosFilterIpsecSpi.aidl new file mode 100644 index 0000000000..695b7352a2 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/QosFilterIpsecSpi.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 -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.radio; +@VintfStability +union QosFilterIpsecSpi { + boolean noinit; + int value; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/QosFilterIpv6FlowLabel.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/QosFilterIpv6FlowLabel.aidl new file mode 100644 index 0000000000..5b9c82c188 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/QosFilterIpv6FlowLabel.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 -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.radio; +@VintfStability +union QosFilterIpv6FlowLabel { + boolean noinit; + int value; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/QosFilterTypeOfService.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/QosFilterTypeOfService.aidl new file mode 100644 index 0000000000..c7c0331afc --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/QosFilterTypeOfService.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 -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.radio; +@VintfStability +union QosFilterTypeOfService { + boolean noinit; + byte value; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/QosFlowIdRange.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/QosFlowIdRange.aidl new file mode 100644 index 0000000000..95468e0074 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/QosFlowIdRange.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 -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.radio; +@Backing(type="byte") @VintfStability +enum QosFlowIdRange { + MIN = 1, + MAX = 63, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/QosPortRange.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/QosPortRange.aidl new file mode 100644 index 0000000000..7171c7ebd5 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/QosPortRange.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 -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.radio; +@Backing(type="int") @VintfStability +enum QosPortRange { + MIN = 20, + MAX = 65535, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/QosProtocol.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/QosProtocol.aidl new file mode 100644 index 0000000000..cb68f04418 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/QosProtocol.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 -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.radio; +@Backing(type="byte") @VintfStability +enum QosProtocol { + UNSPECIFIED = -1, + TCP = 6, + UDP = 17, + ESP = 50, + AH = 51, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/QosSession.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/QosSession.aidl new file mode 100644 index 0000000000..8f1b913fb2 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/QosSession.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 -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.radio; +@VintfStability +parcelable QosSession { + int qosSessionId; + android.hardware.radio.Qos qos; + android.hardware.radio.QosFilter[] qosFilters; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioAccessFamily.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioAccessFamily.aidl new file mode 100644 index 0000000000..10a956e4d8 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioAccessFamily.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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.radio; +@Backing(type="int") @VintfStability +enum RadioAccessFamily { + UNKNOWN = 1, + GPRS = 2, + EDGE = 4, + UMTS = 8, + IS95A = 16, + IS95B = 32, + ONE_X_RTT = 64, + EVDO_0 = 128, + EVDO_A = 256, + HSDPA = 512, + HSUPA = 1024, + HSPA = 2048, + EVDO_B = 4096, + EHRPD = 8192, + LTE = 16384, + HSPAP = 32768, + GSM = 65536, + TD_SCDMA = 131072, + LTE_CA = 524288, + NR = 1048576, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioAccessNetworks.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioAccessNetworks.aidl new file mode 100644 index 0000000000..67f5e8a246 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioAccessNetworks.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 -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.radio; +@Backing(type="int") @VintfStability +enum RadioAccessNetworks { + UNKNOWN = 0, + GERAN = 1, + UTRAN = 2, + EUTRAN = 3, + NGRAN = 4, + CDMA2000 = 5, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioAccessSpecifier.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioAccessSpecifier.aidl new file mode 100644 index 0000000000..b47ee2d49c --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioAccessSpecifier.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 -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.radio; +@VintfStability +parcelable RadioAccessSpecifier { + android.hardware.radio.RadioAccessNetworks radioAccessNetwork; + android.hardware.radio.RadioAccessSpecifierBands bands; + int[] channels; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioAccessSpecifierBands.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioAccessSpecifierBands.aidl new file mode 100644 index 0000000000..9d0a99733c --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioAccessSpecifierBands.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 -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.radio; +@VintfStability +union RadioAccessSpecifierBands { + boolean noinit; + android.hardware.radio.GeranBands[] geranBands; + android.hardware.radio.UtranBands[] utranBands; + android.hardware.radio.EutranBands[] eutranBands; + android.hardware.radio.NgranBands[] ngranBands; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioBandMode.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioBandMode.aidl new file mode 100644 index 0000000000..973ca524b1 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioBandMode.aidl @@ -0,0 +1,56 @@ +/* + * 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 -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.radio; +@Backing(type="int") @VintfStability +enum RadioBandMode { + BAND_MODE_UNSPECIFIED = 0, + BAND_MODE_EURO = 1, + BAND_MODE_USA = 2, + BAND_MODE_JPN = 3, + BAND_MODE_AUS = 4, + BAND_MODE_AUS_2 = 5, + BAND_MODE_CELL_800 = 6, + BAND_MODE_PCS = 7, + BAND_MODE_JTACS = 8, + BAND_MODE_KOREA_PCS = 9, + BAND_MODE_5_450M = 10, + BAND_MODE_IMT2000 = 11, + BAND_MODE_7_700M_2 = 12, + BAND_MODE_8_1800M = 13, + BAND_MODE_9_900M = 14, + BAND_MODE_10_800M_2 = 15, + BAND_MODE_EURO_PAMR_400M = 16, + BAND_MODE_AWS = 17, + BAND_MODE_USA_2500M = 18, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioCapability.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioCapability.aidl new file mode 100644 index 0000000000..99c1a41363 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioCapability.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 -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.radio; +@VintfStability +parcelable RadioCapability { + int session; + android.hardware.radio.RadioCapabilityPhase phase; + android.hardware.radio.RadioAccessFamily raf; + String logicalModemUuid; + android.hardware.radio.RadioCapabilityStatus status; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioCapabilityPhase.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioCapabilityPhase.aidl new file mode 100644 index 0000000000..7a4b9adac2 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioCapabilityPhase.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 -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.radio; +@Backing(type="int") @VintfStability +enum RadioCapabilityPhase { + CONFIGURED = 0, + START = 1, + APPLY = 2, + UNSOL_RSP = 3, + FINISH = 4, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioCapabilityStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioCapabilityStatus.aidl new file mode 100644 index 0000000000..72e0bd53f2 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioCapabilityStatus.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 -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.radio; +@Backing(type="int") @VintfStability +enum RadioCapabilityStatus { + NONE = 0, + SUCCESS = 1, + FAIL = 2, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioCdmaSmsConst.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioCdmaSmsConst.aidl new file mode 100644 index 0000000000..7e5c471841 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioCdmaSmsConst.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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.radio; +@Backing(type="int") @VintfStability +enum RadioCdmaSmsConst { + ADDRESS_MAX = 36, + SUBADDRESS_MAX = 36, + BEARER_DATA_MAX = 255, + UDH_MAX_SND_SIZE = 128, + UDH_EO_DATA_SEGMENT_MAX = 131, + MAX_UD_HEADERS = 7, + USER_DATA_MAX = 229, + UDH_LARGE_PIC_SIZE = 128, + UDH_SMALL_PIC_SIZE = 32, + UDH_VAR_PIC_SIZE = 134, + UDH_ANIM_NUM_BITMAPS = 4, + UDH_LARGE_BITMAP_SIZE = 32, + UDH_SMALL_BITMAP_SIZE = 8, + UDH_OTHER_SIZE = 226, + IP_ADDRESS_SIZE = 4, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioConst.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioConst.aidl new file mode 100644 index 0000000000..d37f13bf0f --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioConst.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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.radio; +@Backing(type="int") @VintfStability +enum RadioConst { + CDMA_ALPHA_INFO_BUFFER_LENGTH = 64, + CDMA_NUMBER_INFO_BUFFER_LENGTH = 81, + MAX_RILDS = 3, + MAX_SOCKET_NAME_LENGTH = 6, + MAX_CLIENT_ID_LENGTH = 2, + MAX_DEBUG_SOCKET_NAME_LENGTH = 12, + MAX_QEMU_PIPE_NAME_LENGTH = 11, + MAX_UUID_LENGTH = 64, + CARD_MAX_APPS = 8, + CDMA_MAX_NUMBER_OF_INFO_RECS = 10, + SS_INFO_MAX = 4, + NUM_SERVICE_CLASSES = 7, + NUM_TX_POWER_LEVELS = 5, + RADIO_ACCESS_SPECIFIER_MAX_SIZE = 8, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioError.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioError.aidl new file mode 100644 index 0000000000..3ef67bccdb --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioError.aidl @@ -0,0 +1,126 @@ +/* + * 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 -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.radio; +@Backing(type="int") @VintfStability +enum RadioError { + NONE = 0, + RADIO_NOT_AVAILABLE = 1, + GENERIC_FAILURE = 2, + PASSWORD_INCORRECT = 3, + SIM_PIN2 = 4, + SIM_PUK2 = 5, + REQUEST_NOT_SUPPORTED = 6, + CANCELLED = 7, + OP_NOT_ALLOWED_DURING_VOICE_CALL = 8, + OP_NOT_ALLOWED_BEFORE_REG_TO_NW = 9, + SMS_SEND_FAIL_RETRY = 10, + SIM_ABSENT = 11, + SUBSCRIPTION_NOT_AVAILABLE = 12, + MODE_NOT_SUPPORTED = 13, + FDN_CHECK_FAILURE = 14, + ILLEGAL_SIM_OR_ME = 15, + MISSING_RESOURCE = 16, + NO_SUCH_ELEMENT = 17, + DIAL_MODIFIED_TO_USSD = 18, + DIAL_MODIFIED_TO_SS = 19, + DIAL_MODIFIED_TO_DIAL = 20, + USSD_MODIFIED_TO_DIAL = 21, + USSD_MODIFIED_TO_SS = 22, + USSD_MODIFIED_TO_USSD = 23, + SS_MODIFIED_TO_DIAL = 24, + SS_MODIFIED_TO_USSD = 25, + SUBSCRIPTION_NOT_SUPPORTED = 26, + SS_MODIFIED_TO_SS = 27, + LCE_NOT_SUPPORTED = 36, + NO_MEMORY = 37, + INTERNAL_ERR = 38, + SYSTEM_ERR = 39, + MODEM_ERR = 40, + INVALID_STATE = 41, + NO_RESOURCES = 42, + SIM_ERR = 43, + INVALID_ARGUMENTS = 44, + INVALID_SIM_STATE = 45, + INVALID_MODEM_STATE = 46, + INVALID_CALL_ID = 47, + NO_SMS_TO_ACK = 48, + NETWORK_ERR = 49, + REQUEST_RATE_LIMITED = 50, + SIM_BUSY = 51, + SIM_FULL = 52, + NETWORK_REJECT = 53, + OPERATION_NOT_ALLOWED = 54, + EMPTY_RECORD = 55, + INVALID_SMS_FORMAT = 56, + ENCODING_ERR = 57, + INVALID_SMSC_ADDRESS = 58, + NO_SUCH_ENTRY = 59, + NETWORK_NOT_READY = 60, + NOT_PROVISIONED = 61, + NO_SUBSCRIPTION = 62, + NO_NETWORK_FOUND = 63, + DEVICE_IN_USE = 64, + ABORTED = 65, + INVALID_RESPONSE = 66, + OEM_ERROR_1 = 501, + OEM_ERROR_2 = 502, + OEM_ERROR_3 = 503, + OEM_ERROR_4 = 504, + OEM_ERROR_5 = 505, + OEM_ERROR_6 = 506, + OEM_ERROR_7 = 507, + OEM_ERROR_8 = 508, + OEM_ERROR_9 = 509, + OEM_ERROR_10 = 510, + OEM_ERROR_11 = 511, + OEM_ERROR_12 = 512, + OEM_ERROR_13 = 513, + OEM_ERROR_14 = 514, + OEM_ERROR_15 = 515, + OEM_ERROR_16 = 516, + OEM_ERROR_17 = 517, + OEM_ERROR_18 = 518, + OEM_ERROR_19 = 519, + OEM_ERROR_20 = 520, + OEM_ERROR_21 = 521, + OEM_ERROR_22 = 522, + OEM_ERROR_23 = 523, + OEM_ERROR_24 = 524, + OEM_ERROR_25 = 525, + SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED = 67, + ACCESS_BARRED = 68, + BLOCKED_DUE_TO_CALL = 69, + RF_HARDWARE_ISSUE = 70, + NO_RF_CALIBRATION_INFO = 71, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioFrequencyInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioFrequencyInfo.aidl new file mode 100644 index 0000000000..6c0704585e --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioFrequencyInfo.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 -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.radio; +@VintfStability +union RadioFrequencyInfo { + boolean noinit; + android.hardware.radio.FrequencyRange range; + int channelNumber; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioIndicationType.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioIndicationType.aidl new file mode 100644 index 0000000000..fc5d4dfc04 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioIndicationType.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 -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.radio; +@Backing(type="int") @VintfStability +enum RadioIndicationType { + UNSOLICITED = 0, + UNSOLICITED_ACK_EXP = 1, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioResponseInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioResponseInfo.aidl new file mode 100644 index 0000000000..08c30232f5 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioResponseInfo.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 -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.radio; +@VintfStability +parcelable RadioResponseInfo { + android.hardware.radio.RadioResponseType type; + int serial; + android.hardware.radio.RadioError error; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioResponseInfoModem.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioResponseInfoModem.aidl new file mode 100644 index 0000000000..cbc4ab9759 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioResponseInfoModem.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 -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.radio; +@VintfStability +parcelable RadioResponseInfoModem { + android.hardware.radio.RadioResponseType type; + int serial; + android.hardware.radio.RadioError error; + boolean isEnabled; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioResponseType.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioResponseType.aidl new file mode 100644 index 0000000000..cf24183016 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioResponseType.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 -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.radio; +@Backing(type="int") @VintfStability +enum RadioResponseType { + SOLICITED = 0, + SOLICITED_ACK = 1, + SOLICITED_ACK_EXP = 2, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioState.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioState.aidl new file mode 100644 index 0000000000..3dad483679 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioState.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 -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.radio; +@Backing(type="int") @VintfStability +enum RadioState { + OFF = 0, + UNAVAILABLE = 1, + ON = 10, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioTechnology.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioTechnology.aidl new file mode 100644 index 0000000000..d0ca9b5cf5 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioTechnology.aidl @@ -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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.radio; +@Backing(type="int") @VintfStability +enum RadioTechnology { + UNKNOWN = 0, + GPRS = 1, + EDGE = 2, + UMTS = 3, + IS95A = 4, + IS95B = 5, + ONE_X_RTT = 6, + EVDO_0 = 7, + EVDO_A = 8, + HSDPA = 9, + HSUPA = 10, + HSPA = 11, + EVDO_B = 12, + EHRPD = 13, + LTE = 14, + HSPAP = 15, + GSM = 16, + TD_SCDMA = 17, + IWLAN = 18, + LTE_CA = 19, + NR = 20, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioTechnologyFamily.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioTechnologyFamily.aidl new file mode 100644 index 0000000000..c11cd1cac6 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioTechnologyFamily.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 -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.radio; +@Backing(type="int") @VintfStability +enum RadioTechnologyFamily { + THREE_GPP = 0, + THREE_GPP2 = 1, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RegState.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RegState.aidl new file mode 100644 index 0000000000..049ded1c1d --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RegState.aidl @@ -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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.radio; +@Backing(type="int") @VintfStability +enum RegState { + NOT_REG_MT_NOT_SEARCHING_OP = 0, + REG_HOME = 1, + NOT_REG_MT_SEARCHING_OP = 2, + REG_DENIED = 3, + UNKNOWN = 4, + REG_ROAMING = 5, + NOT_REG_MT_NOT_SEARCHING_OP_EM = 10, + NOT_REG_MT_SEARCHING_OP_EM = 12, + REG_DENIED_EM = 13, + UNKNOWN_EM = 14, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RegStateResult.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RegStateResult.aidl new file mode 100644 index 0000000000..78c5c2d30f --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RegStateResult.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 -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.radio; +@VintfStability +parcelable RegStateResult { + android.hardware.radio.RegState regState; + android.hardware.radio.RadioTechnology rat; + android.hardware.radio.RegistrationFailCause reasonForDenial; + android.hardware.radio.CellIdentity cellIdentity; + String registeredPlmn; + android.hardware.radio.RegStateResultAccessTechnologySpecificInfo accessTechnologySpecificInfo; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RegStateResultAccessTechnologySpecificInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RegStateResultAccessTechnologySpecificInfo.aidl new file mode 100644 index 0000000000..6ce6398498 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RegStateResultAccessTechnologySpecificInfo.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 -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.radio; +@VintfStability +union RegStateResultAccessTechnologySpecificInfo { + boolean noinit; + android.hardware.radio.RegStateResultAccessTechnologySpecificInfoCdma2000RegistrationInfo cdmaInfo; + android.hardware.radio.RegStateResultAccessTechnologySpecificInfoEutranRegistrationInfo eutranInfo; + android.hardware.radio.NrVopsInfo ngranNrVopsInfo; + boolean geranDtmSupported; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RegStateResultAccessTechnologySpecificInfoCdma2000RegistrationInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RegStateResultAccessTechnologySpecificInfoCdma2000RegistrationInfo.aidl new file mode 100644 index 0000000000..a56a791c7a --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RegStateResultAccessTechnologySpecificInfoCdma2000RegistrationInfo.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 -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.radio; +@VintfStability +parcelable RegStateResultAccessTechnologySpecificInfoCdma2000RegistrationInfo { + boolean cssSupported; + int roamingIndicator; + android.hardware.radio.PrlIndicator systemIsInPrl; + int defaultRoamingIndicator; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RegStateResultAccessTechnologySpecificInfoEutranRegistrationInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RegStateResultAccessTechnologySpecificInfoEutranRegistrationInfo.aidl new file mode 100644 index 0000000000..ed422eb967 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RegStateResultAccessTechnologySpecificInfoEutranRegistrationInfo.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 -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.radio; +@VintfStability +parcelable RegStateResultAccessTechnologySpecificInfoEutranRegistrationInfo { + android.hardware.radio.LteVopsInfo lteVopsInfo; + android.hardware.radio.NrIndicators nrIndicators; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RegistrationFailCause.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RegistrationFailCause.aidl new file mode 100644 index 0000000000..c5529b6ddb --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RegistrationFailCause.aidl @@ -0,0 +1,89 @@ +/* + * 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 -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.radio; +@Backing(type="int") @VintfStability +enum RegistrationFailCause { + NONE = 0, + IMSI_UNKNOWN_IN_HLR = 2, + ILLEGAL_MS = 3, + IMSI_UNKNOWN_IN_VLR = 4, + IMEI_NOT_ACCEPTED = 5, + ILLEGAL_ME = 6, + GPRS_SERVICES_NOT_ALLOWED = 7, + GPRS_AND_NON_GPRS_SERVICES_NOT_ALLOWED = 8, + MS_IDENTITY_CANNOT_BE_DERIVED_BY_NETWORK = 9, + IMPLICITLY_DETACHED = 10, + PLMN_NOT_ALLOWED = 11, + LOCATION_AREA_NOT_ALLOWED = 12, + ROAMING_NOT_ALLOWED = 13, + GPRS_SERVICES_NOT_ALLOWED_IN_PLMN = 14, + NO_SUITABLE_CELLS = 15, + MSC_TEMPORARILY_NOT_REACHABLE = 15, + NETWORK_FAILURE = 17, + MAC_FAILURE = 20, + SYNC_FAILURE = 21, + CONGESTION = 22, + GSM_AUTHENTICATION_UNACCEPTABLE = 23, + NOT_AUTHORIZED_FOR_THIS_CSG = 25, + SMS_PROVIDED_BY_GPRS_IN_ROUTING_AREA = 26, + SERVICE_OPTION_NOT_SUPPORTED = 32, + SERVICE_OPTION_NOT_SUBSCRIBED = 33, + SERVICE_OPTION_TEMPORARILY_OUT_OF_ORDER = 34, + CALL_CANNOT_BE_IDENTIFIED = 38, + NO_PDP_CONTEXT_ACTIVATED = 40, + RETRY_UPON_ENTRY_INTO_NEW_CELL_1 = 48, + RETRY_UPON_ENTRY_INTO_NEW_CELL_2 = 49, + RETRY_UPON_ENTRY_INTO_NEW_CELL_3 = 50, + RETRY_UPON_ENTRY_INTO_NEW_CELL_4 = 51, + RETRY_UPON_ENTRY_INTO_NEW_CELL_5 = 52, + RETRY_UPON_ENTRY_INTO_NEW_CELL_6 = 53, + RETRY_UPON_ENTRY_INTO_NEW_CELL_7 = 54, + RETRY_UPON_ENTRY_INTO_NEW_CELL_8 = 55, + RETRY_UPON_ENTRY_INTO_NEW_CELL_9 = 56, + RETRY_UPON_ENTRY_INTO_NEW_CELL_10 = 57, + RETRY_UPON_ENTRY_INTO_NEW_CELL_11 = 58, + RETRY_UPON_ENTRY_INTO_NEW_CELL_12 = 59, + RETRY_UPON_ENTRY_INTO_NEW_CELL_13 = 60, + RETRY_UPON_ENTRY_INTO_NEW_CELL_14 = 61, + RETRY_UPON_ENTRY_INTO_NEW_CELL_15 = 62, + RETRY_UPON_ENTRY_INTO_NEW_CELL_16 = 63, + SEMANTICALLY_INCORRECT_MESSAGE = 95, + INVALID_MANDATORY_INFORMATION = 96, + MESSAGE_TYPE_NON_EXISTENT_OR_NOT_IMPLEMENTED = 97, + MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE = 98, + INFORMATION_ELEMENT_NON_EXISTENT_OR_NOT_IMPLEMENTED = 99, + CONDITIONAL_IE_ERROR = 100, + MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE = 101, + PROTOCOL_ERROR_UNSPECIFIED = 111, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ResetNvType.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ResetNvType.aidl new file mode 100644 index 0000000000..3852a7719e --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ResetNvType.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 -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.radio; +@Backing(type="int") @VintfStability +enum ResetNvType { + RELOAD = 0, + ERASE = 1, + FACTORY_RESET = 2, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RestrictedState.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RestrictedState.aidl new file mode 100644 index 0000000000..dc83ba57af --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RestrictedState.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 -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.radio; +@Backing(type="int") @VintfStability +enum RestrictedState { + NONE = 0, + CS_EMERGENCY = 1, + CS_NORMAL = 2, + CS_ALL = 4, + PS_ALL = 16, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RouteSelectionDescriptor.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RouteSelectionDescriptor.aidl new file mode 100644 index 0000000000..689ee2ff97 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RouteSelectionDescriptor.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 -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.radio; +@VintfStability +parcelable RouteSelectionDescriptor { + byte precedence; + android.hardware.radio.OptionalPdpProtocolType sessionType; + android.hardware.radio.OptionalSscMode sscMode; + android.hardware.radio.SliceInfo[] sliceInfo; + String[] dnn; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapApduType.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapApduType.aidl new file mode 100644 index 0000000000..9bfb725bfa --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapApduType.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 -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.radio; +@Backing(type="int") @VintfStability +enum SapApduType { + APDU = 0, + APDU7816 = 1, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapConnectRsp.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapConnectRsp.aidl new file mode 100644 index 0000000000..7e4d246765 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapConnectRsp.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 -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.radio; +@Backing(type="int") @VintfStability +enum SapConnectRsp { + SUCCESS = 0, + CONNECT_FAILURE = 1, + MSG_SIZE_TOO_LARGE = 2, + MSG_SIZE_TOO_SMALL = 3, + CONNECT_OK_CALL_ONGOING = 4, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapDisconnectType.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapDisconnectType.aidl new file mode 100644 index 0000000000..e0d8eb2481 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapDisconnectType.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 -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.radio; +@Backing(type="int") @VintfStability +enum SapDisconnectType { + GRACEFUL = 0, + IMMEDIATE = 1, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapResultCode.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapResultCode.aidl new file mode 100644 index 0000000000..0c6c5139dd --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapResultCode.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 -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.radio; +@Backing(type="int") @VintfStability +enum SapResultCode { + SUCCESS = 0, + GENERIC_FAILURE = 1, + CARD_NOT_ACCESSSIBLE = 2, + CARD_ALREADY_POWERED_OFF = 3, + CARD_REMOVED = 4, + CARD_ALREADY_POWERED_ON = 5, + DATA_NOT_AVAILABLE = 6, + NOT_SUPPORTED = 7, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapStatus.aidl new file mode 100644 index 0000000000..715c5074a5 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapStatus.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 -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.radio; +@Backing(type="int") @VintfStability +enum SapStatus { + UNKNOWN_ERROR = 0, + CARD_RESET = 1, + CARD_NOT_ACCESSIBLE = 2, + CARD_REMOVED = 3, + CARD_INSERTED = 4, + RECOVERED = 5, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.aidl new file mode 100644 index 0000000000..6eadbb7737 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SapTransferProtocol.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 -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.radio; +@Backing(type="int") @VintfStability +enum SapTransferProtocol { + T0 = 0, + T1 = 1, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ScanIntervalRange.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ScanIntervalRange.aidl new file mode 100644 index 0000000000..3e6539b8f9 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ScanIntervalRange.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 -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.radio; +@Backing(type="int") @VintfStability +enum ScanIntervalRange { + MIN = 5, + MAX = 300, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ScanStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ScanStatus.aidl new file mode 100644 index 0000000000..f8810b6690 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ScanStatus.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 -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.radio; +@Backing(type="int") @VintfStability +enum ScanStatus { + PARTIAL = 1, + COMPLETE = 2, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ScanType.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ScanType.aidl new file mode 100644 index 0000000000..7d51ce25f1 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ScanType.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 -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.radio; +@Backing(type="int") @VintfStability +enum ScanType { + ONE_SHOT = 0, + PERIODIC = 1, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SelectUiccSub.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SelectUiccSub.aidl new file mode 100644 index 0000000000..a285f64891 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SelectUiccSub.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 -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.radio; +@VintfStability +parcelable SelectUiccSub { + int slot; + int appIndex; + android.hardware.radio.SubscriptionType subType; + android.hardware.radio.UiccSubActStatus actStatus; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SendSmsResult.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SendSmsResult.aidl new file mode 100644 index 0000000000..7063db5a3a --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SendSmsResult.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 -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.radio; +@VintfStability +parcelable SendSmsResult { + int messageRef; + String ackPDU; + int errorCode; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SetupDataCallResult.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SetupDataCallResult.aidl new file mode 100644 index 0000000000..ae4493d50e --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SetupDataCallResult.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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.radio; +@VintfStability +parcelable SetupDataCallResult { + android.hardware.radio.DataCallFailCause cause; + long suggestedRetryTime; + int cid; + android.hardware.radio.DataConnActiveStatus active; + android.hardware.radio.PdpProtocolType type; + String ifname; + android.hardware.radio.LinkAddress[] addresses; + String[] dnses; + String[] gateways; + String[] pcscf; + int mtuV4; + int mtuV6; + android.hardware.radio.Qos defaultQos; + android.hardware.radio.QosSession[] qosSessions; + android.hardware.radio.HandoverFailureMode handoverFailureMode; + int pduSessionId; + android.hardware.radio.OptionalSliceInfo sliceInfo; + android.hardware.radio.TrafficDescriptor[] trafficDescriptors; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SignalMeasurementType.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SignalMeasurementType.aidl new file mode 100644 index 0000000000..7f864e5b32 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SignalMeasurementType.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 -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.radio; +@Backing(type="int") @VintfStability +enum SignalMeasurementType { + RSSI = 1, + RSCP = 2, + RSRP = 3, + RSRQ = 4, + RSSNR = 5, + SSRSRP = 6, + SSRSRQ = 7, + SSSINR = 8, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SignalStrength.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SignalStrength.aidl new file mode 100644 index 0000000000..7c7eade8a3 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SignalStrength.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 -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.radio; +@VintfStability +parcelable SignalStrength { + android.hardware.radio.GsmSignalStrength gsm; + android.hardware.radio.CdmaSignalStrength cdma; + android.hardware.radio.EvdoSignalStrength evdo; + android.hardware.radio.LteSignalStrength lte; + android.hardware.radio.TdscdmaSignalStrength tdscdma; + android.hardware.radio.WcdmaSignalStrength wcdma; + android.hardware.radio.NrSignalStrength nr; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SignalThresholdInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SignalThresholdInfo.aidl new file mode 100644 index 0000000000..f519d69b5b --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SignalThresholdInfo.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 -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.radio; +@VintfStability +parcelable SignalThresholdInfo { + android.hardware.radio.SignalMeasurementType signalMeasurement; + int hysteresisMs; + int hysteresisDb; + int[] thresholds; + boolean isEnabled; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SimApdu.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SimApdu.aidl new file mode 100644 index 0000000000..511031aec7 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SimApdu.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 -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.radio; +@VintfStability +parcelable SimApdu { + int sessionId; + int cla; + int instruction; + int p1; + int p2; + int p3; + String data; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SimLockMultiSimPolicy.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SimLockMultiSimPolicy.aidl new file mode 100644 index 0000000000..ad967940fd --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SimLockMultiSimPolicy.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 -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.radio; +@Backing(type="int") @VintfStability +enum SimLockMultiSimPolicy { + NO_MULTISIM_POLICY = 0, + ONE_VALID_SIM_MUST_BE_PRESENT = 1, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SimRefreshResult.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SimRefreshResult.aidl new file mode 100644 index 0000000000..720c8a20fc --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SimRefreshResult.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 -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.radio; +@VintfStability +parcelable SimRefreshResult { + android.hardware.radio.SimRefreshType type; + int efId; + String aid; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SimRefreshType.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SimRefreshType.aidl new file mode 100644 index 0000000000..b114ec7c92 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SimRefreshType.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 -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.radio; +@Backing(type="int") @VintfStability +enum SimRefreshType { + SIM_FILE_UPDATE = 0, + SIM_INIT = 1, + SIM_RESET = 2, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SliceInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SliceInfo.aidl new file mode 100644 index 0000000000..8b363801ce --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SliceInfo.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 -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.radio; +@VintfStability +parcelable SliceInfo { + android.hardware.radio.SliceServiceType sst; + int sliceDifferentiator; + android.hardware.radio.SliceServiceType mappedHplmnSst; + int mappedHplmnSD; + android.hardware.radio.SliceStatus status; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SliceServiceType.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SliceServiceType.aidl new file mode 100644 index 0000000000..d0a9f58d80 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SliceServiceType.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 -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.radio; +@Backing(type="byte") @VintfStability +enum SliceServiceType { + NONE = 0, + EMBB = 1, + URLLC = 2, + MIOT = 3, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SliceStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SliceStatus.aidl new file mode 100644 index 0000000000..3fa1ee6b15 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SliceStatus.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 -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.radio; +@Backing(type="byte") @VintfStability +enum SliceStatus { + UNKNOWN = 0, + CONFIGURED = 1, + ALLOWED = 2, + REJECTED_NOT_AVAILABLE_IN_PLMN = 3, + REJECTED_NOT_AVAILABLE_IN_REG_AREA = 4, + DEFAULT_CONFIGURED = 5, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SlicingConfig.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SlicingConfig.aidl new file mode 100644 index 0000000000..9d3633836c --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SlicingConfig.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 -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.radio; +@VintfStability +parcelable SlicingConfig { + android.hardware.radio.UrspRule[] urspRules; + android.hardware.radio.SliceInfo[] sliceInfo; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SmsAcknowledgeFailCause.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SmsAcknowledgeFailCause.aidl new file mode 100644 index 0000000000..c5b13b934a --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SmsAcknowledgeFailCause.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 -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.radio; +@Backing(type="int") @VintfStability +enum SmsAcknowledgeFailCause { + MEMORY_CAPACITY_EXCEEDED = 211, + UNSPECIFIED_ERROR = 255, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SmsWriteArgs.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SmsWriteArgs.aidl new file mode 100644 index 0000000000..6b0d9bf3bd --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SmsWriteArgs.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 -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.radio; +@VintfStability +parcelable SmsWriteArgs { + android.hardware.radio.SmsWriteArgsStatus status; + String pdu; + String smsc; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SmsWriteArgsStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SmsWriteArgsStatus.aidl new file mode 100644 index 0000000000..31a3f42e77 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SmsWriteArgsStatus.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 -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.radio; +@Backing(type="int") @VintfStability +enum SmsWriteArgsStatus { + REC_UNREAD = 0, + REC_READ = 1, + STO_UNSENT = 2, + STO_SENT = 3, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SrvccState.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SrvccState.aidl new file mode 100644 index 0000000000..d4a941763c --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SrvccState.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 -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.radio; +@Backing(type="int") @VintfStability +enum SrvccState { + HANDOVER_STARTED = 0, + HANDOVER_COMPLETED = 1, + HANDOVER_FAILED = 2, + HANDOVER_CANCELED = 3, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SsInfoData.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SsInfoData.aidl new file mode 100644 index 0000000000..10b4c3d81a --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SsInfoData.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 -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.radio; +@VintfStability +parcelable SsInfoData { + int[] ssInfo; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SsRequestType.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SsRequestType.aidl new file mode 100644 index 0000000000..75ad9bb2c5 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SsRequestType.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 -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.radio; +@Backing(type="int") @VintfStability +enum SsRequestType { + ACTIVATION = 0, + DEACTIVATION = 1, + INTERROGATION = 2, + REGISTRATION = 3, + ERASURE = 4, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SsServiceType.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SsServiceType.aidl new file mode 100644 index 0000000000..c3506b10c6 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SsServiceType.aidl @@ -0,0 +1,56 @@ +/* + * 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 -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.radio; +@Backing(type="int") @VintfStability +enum SsServiceType { + CFU = 0, + CF_BUSY = 1, + CF_NO_REPLY = 2, + CF_NOT_REACHABLE = 3, + CF_ALL = 4, + CF_ALL_CONDITIONAL = 5, + CLIP = 6, + CLIR = 7, + COLP = 8, + COLR = 9, + WAIT = 10, + BAOC = 11, + BAOIC = 12, + BAOIC_EXC_HOME = 13, + BAIC = 14, + BAIC_ROAMING = 15, + ALL_BARRING = 16, + OUTGOING_BARRING = 17, + INCOMING_BARRING = 18, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SsTeleserviceType.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SsTeleserviceType.aidl new file mode 100644 index 0000000000..f06014cd50 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SsTeleserviceType.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 -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.radio; +@Backing(type="int") @VintfStability +enum SsTeleserviceType { + ALL_TELE_AND_BEARER_SERVICES = 0, + ALL_TELESEVICES = 1, + TELEPHONY = 2, + ALL_DATA_TELESERVICES = 3, + SMS_SERVICES = 4, + ALL_TELESERVICES_EXCEPT_SMS = 5, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SscMode.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SscMode.aidl new file mode 100644 index 0000000000..e2c3e09492 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SscMode.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 -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.radio; +@Backing(type="byte") @VintfStability +enum SscMode { + MODE_1 = 1, + MODE_2 = 2, + MODE_3 = 3, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/StkCcUnsolSsResult.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/StkCcUnsolSsResult.aidl new file mode 100644 index 0000000000..1e4f95b69d --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/StkCcUnsolSsResult.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 -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.radio; +@VintfStability +parcelable StkCcUnsolSsResult { + android.hardware.radio.SsServiceType serviceType; + android.hardware.radio.SsRequestType requestType; + android.hardware.radio.SsTeleserviceType teleserviceType; + android.hardware.radio.SuppServiceClass serviceClass; + android.hardware.radio.RadioError result; + android.hardware.radio.SsInfoData[] ssInfo; + android.hardware.radio.CfData[] cfData; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SubscriptionType.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SubscriptionType.aidl new file mode 100644 index 0000000000..f469f2faef --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SubscriptionType.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 -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.radio; +@Backing(type="int") @VintfStability +enum SubscriptionType { + SUBSCRIPTION_1 = 0, + SUBSCRIPTION_2 = 1, + SUBSCRIPTION_3 = 2, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SuppServiceClass.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SuppServiceClass.aidl new file mode 100644 index 0000000000..e59f40b1df --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SuppServiceClass.aidl @@ -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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.radio; +@Backing(type="int") @VintfStability +enum SuppServiceClass { + NONE = 0, + VOICE = 1, + DATA = 2, + FAX = 4, + SMS = 8, + DATA_SYNC = 16, + DATA_ASYNC = 32, + PACKET = 64, + PAD = 128, + MAX = 128, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SuppSvcNotification.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SuppSvcNotification.aidl new file mode 100644 index 0000000000..c098e245fc --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SuppSvcNotification.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 -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.radio; +@VintfStability +parcelable SuppSvcNotification { + boolean isMT; + int code; + int index; + int type; + String number; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/TdscdmaSignalStrength.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/TdscdmaSignalStrength.aidl new file mode 100644 index 0000000000..a2ba211d3f --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/TdscdmaSignalStrength.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 -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.radio; +@VintfStability +parcelable TdscdmaSignalStrength { + int signalStrength; + int bitErrorRate; + int rscp; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/TimeStampType.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/TimeStampType.aidl new file mode 100644 index 0000000000..ae70522aa7 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/TimeStampType.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 -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.radio; +@Backing(type="int") @VintfStability +enum TimeStampType { + UNKNOWN = 0, + ANTENNA = 1, + MODEM = 2, + OEM_RIL = 3, + JAVA_RIL = 4, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/TrafficDescriptor.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/TrafficDescriptor.aidl new file mode 100644 index 0000000000..9f46848d44 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/TrafficDescriptor.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 -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.radio; +@VintfStability +parcelable TrafficDescriptor { + android.hardware.radio.OptionalDnn dnn; + android.hardware.radio.OptionalOsAppId osAppId; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/TtyMode.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/TtyMode.aidl new file mode 100644 index 0000000000..cee3057c27 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/TtyMode.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 -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.radio; +@Backing(type="int") @VintfStability +enum TtyMode { + OFF = 0, + FULL = 1, + HCO = 2, + VCO = 3, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/UiccSubActStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/UiccSubActStatus.aidl new file mode 100644 index 0000000000..5ec511e989 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/UiccSubActStatus.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 -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.radio; +@Backing(type="int") @VintfStability +enum UiccSubActStatus { + DEACTIVATE = 0, + ACTIVATE = 1, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/UrspRule.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/UrspRule.aidl new file mode 100644 index 0000000000..ababb29539 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/UrspRule.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 -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.radio; +@VintfStability +parcelable UrspRule { + byte precedence; + android.hardware.radio.TrafficDescriptor[] trafficDescriptors; + android.hardware.radio.RouteSelectionDescriptor[] routeSelectionDescriptor; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/UssdModeType.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/UssdModeType.aidl new file mode 100644 index 0000000000..992a55f5d0 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/UssdModeType.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 -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.radio; +@Backing(type="int") @VintfStability +enum UssdModeType { + NOTIFY = 0, + REQUEST = 1, + NW_RELEASE = 2, + LOCAL_CLIENT = 3, + NOT_SUPPORTED = 4, + NW_TIMEOUT = 5, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/UtranBands.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/UtranBands.aidl new file mode 100644 index 0000000000..32cff727ff --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/UtranBands.aidl @@ -0,0 +1,63 @@ +/* + * 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 -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.radio; +@Backing(type="int") @VintfStability +enum UtranBands { + BAND_1 = 1, + BAND_2 = 2, + BAND_3 = 3, + BAND_4 = 4, + BAND_5 = 5, + BAND_6 = 6, + BAND_7 = 7, + BAND_8 = 8, + BAND_9 = 9, + BAND_10 = 10, + BAND_11 = 11, + BAND_12 = 12, + BAND_13 = 13, + BAND_14 = 14, + BAND_19 = 19, + BAND_20 = 20, + BAND_21 = 21, + BAND_22 = 22, + BAND_25 = 25, + BAND_26 = 26, + BAND_A = 101, + BAND_B = 102, + BAND_C = 103, + BAND_D = 104, + BAND_E = 105, + BAND_F = 106, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/UusDcs.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/UusDcs.aidl new file mode 100644 index 0000000000..cf1bacacb3 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/UusDcs.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 -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.radio; +@Backing(type="int") @VintfStability +enum UusDcs { + USP = 0, + OSIHLP = 1, + X244 = 2, + RMCF = 3, + IA5C = 4, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/UusInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/UusInfo.aidl new file mode 100644 index 0000000000..3551fe3b70 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/UusInfo.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 -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.radio; +@VintfStability +parcelable UusInfo { + android.hardware.radio.UusType uusType; + android.hardware.radio.UusDcs uusDcs; + String uusData; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/UusType.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/UusType.aidl new file mode 100644 index 0000000000..7176d400c5 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/UusType.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 -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.radio; +@Backing(type="int") @VintfStability +enum UusType { + TYPE1_IMPLICIT = 0, + TYPE1_REQUIRED = 1, + TYPE1_NOT_REQUIRED = 2, + TYPE2_REQUIRED = 3, + TYPE2_NOT_REQUIRED = 4, + TYPE3_REQUIRED = 5, + TYPE3_NOT_REQUIRED = 6, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/VoiceRegStateResult.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/VoiceRegStateResult.aidl new file mode 100644 index 0000000000..a693ff5240 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/VoiceRegStateResult.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 -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.radio; +@VintfStability +parcelable VoiceRegStateResult { + android.hardware.radio.RegState regState; + int rat; + boolean cssSupported; + int roamingIndicator; + int systemIsInPrl; + int defaultRoamingIndicator; + int reasonForDenial; + android.hardware.radio.CellIdentity cellIdentity; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/VopsIndicator.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/VopsIndicator.aidl new file mode 100644 index 0000000000..028b71907d --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/VopsIndicator.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 -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.radio; +@Backing(type="byte") @VintfStability +enum VopsIndicator { + VOPS_NOT_SUPPORTED = 0, + VOPS_OVER_3GPP = 1, + VOPS_OVER_NON_3GPP = 2, +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/WcdmaSignalStrength.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/WcdmaSignalStrength.aidl new file mode 100644 index 0000000000..764ddedfa1 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/WcdmaSignalStrength.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 -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.radio; +@VintfStability +parcelable WcdmaSignalStrength { + int signalStrength; + int bitErrorRate; + int rscp; + int ecno; +} diff --git a/radio/aidl/android/hardware/radio/AccessNetwork.aidl b/radio/aidl/android/hardware/radio/AccessNetwork.aidl new file mode 100644 index 0000000000..10b84f4948 --- /dev/null +++ b/radio/aidl/android/hardware/radio/AccessNetwork.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.radio; + +@VintfStability +@Backing(type="int") +enum AccessNetwork { + /** + * Unknown access network + */ + UNKNOWN, + /** + * GSM EDGE Radio Access Network + */ + GERAN, + /** + * Universal Terrestrial Radio Access Network + */ + UTRAN, + /** + * Evolved Universal Terrestrial Radio Access Network + */ + EUTRAN, + /** + * CDMA 2000 network + */ + CDMA2000, + /** + * Interworking Wireless LAN + */ + IWLAN, + /** + * Next-Generation Radio Access Network (NGRAN). + * Note NGRAN is only for standalone mode. Non-standalone mode uses AccessNetwork EUTRAN. + */ + NGRAN, +} diff --git a/radio/aidl/android/hardware/radio/ActivityStatsInfo.aidl b/radio/aidl/android/hardware/radio/ActivityStatsInfo.aidl new file mode 100644 index 0000000000..f1a6e0e355 --- /dev/null +++ b/radio/aidl/android/hardware/radio/ActivityStatsInfo.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. + */ + +package android.hardware.radio; + +@VintfStability +parcelable ActivityStatsInfo { + /** + * Total time (in ms) when modem is in a low power or sleep state + */ + int sleepModeTimeMs; + /** + * Total time (in ms) when modem is awake but neither the transmitter nor receiver are + * active/awake + */ + int idleModeTimeMs; + /** + * Each index represent total time (in ms) during which the transmitter is active/awake for a + * particular power range as shown below. + * index 0 = tx_power < 0dBm + * index 1 = 0dBm < tx_power < 5dBm + * index 2 = 5dBm < tx_power < 15dBm + * index 3 = 15dBm < tx_power < 20dBm + * index 4 = tx_power > 20dBm + */ + int[] txmModetimeMs; + /** + * Total time (in ms) for which receiver is active/awake and the transmitter is inactive + */ + int rxModeTimeMs; +} diff --git a/radio/aidl/android/hardware/radio/AddressProperty.aidl b/radio/aidl/android/hardware/radio/AddressProperty.aidl new file mode 100644 index 0000000000..dbafc17b2b --- /dev/null +++ b/radio/aidl/android/hardware/radio/AddressProperty.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.radio; + +/** + * The properties of the link address. This enum reflects the definition in if_addr.h in + * Linux kernel. + */ +@VintfStability +@Backing(type="int") +enum AddressProperty { + NONE = 0, + /** + * Indicates this address is deprecated + */ + DEPRECATED = 0x20, +} diff --git a/radio/aidl/android/hardware/radio/ApnAuthType.aidl b/radio/aidl/android/hardware/radio/ApnAuthType.aidl new file mode 100644 index 0000000000..c836a31476 --- /dev/null +++ b/radio/aidl/android/hardware/radio/ApnAuthType.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.radio; + +@VintfStability +@Backing(type="int") +enum ApnAuthType { + /** + * PAP and CHAP is never performed. + */ + NO_PAP_NO_CHAP, + /** + * PAP may be performed; CHAP is never performed. + */ + PAP_NO_CHAP, + /** + * CHAP may be performed; PAP is never performed. + */ + NO_PAP_CHAP, + /** + * PAP / CHAP may be performed - baseband dependent. + */ + PAP_CHAP, +} diff --git a/radio/aidl/android/hardware/radio/ApnTypes.aidl b/radio/aidl/android/hardware/radio/ApnTypes.aidl new file mode 100644 index 0000000000..340301fd40 --- /dev/null +++ b/radio/aidl/android/hardware/radio/ApnTypes.aidl @@ -0,0 +1,81 @@ +/* + * 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.radio; + +@VintfStability +@Backing(type="int") +enum ApnTypes { + /** + * None + */ + NONE = 0, + /** + * APN type for default data traffic + */ + DEFAULT = 1 << 0, + /** + * APN type for MMS traffic + */ + MMS = 1 << 1, + /** + * APN type for SUPL assisted GPS + */ + SUPL = 1 << 2, + /** + * APN type for DUN traffic + */ + DUN = 1 << 3, + /** + * APN type for HiPri traffic + */ + HIPRI = 1 << 4, + /** + * APN type for FOTA + */ + FOTA = 1 << 5, + /** + * APN type for IMS + */ + IMS = 1 << 6, + /** + * APN type for CBS + */ + CBS = 1 << 7, + /** + * APN type for IA Initial Attach APN + */ + IA = 1 << 8, + /** + * APN type for Emergency PDN. This is not an IA apn, but is used for access to carrier services + * in an emergency call situation. + */ + EMERGENCY = 1 << 9, + /** + * Due to the addition of values after EMERGENCY (eg. MCX, XCAP), this value is now deprecated + * and should not be used. + */ + ALL = DEFAULT | MMS | SUPL | DUN | HIPRI | FOTA | IMS | CBS | IA | EMERGENCY, + /** + * APN type for Mission Critical Service + * Reference: 3GPP TS 22.280 V15.3.0 + */ + MCX = 1 << 10, + /** + * APN type for XCAP + */ + XCAP = 1 << 11, +} diff --git a/radio/aidl/android/hardware/radio/AppState.aidl b/radio/aidl/android/hardware/radio/AppState.aidl new file mode 100644 index 0000000000..9488282cc2 --- /dev/null +++ b/radio/aidl/android/hardware/radio/AppState.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.radio; + +@VintfStability +@Backing(type="int") +enum AppState { + UNKNOWN, + DETECTED, + /** + * If PIN1 or UPin is required + */ + PIN, + /** + * If PUK1 or Puk for Upin is required + */ + PUK, + /** + * perso_substate must be looked at when app_state is assigned to this value + */ + SUBSCRIPTION_PERSO, + READY, +} diff --git a/radio/aidl/android/hardware/radio/AppStatus.aidl b/radio/aidl/android/hardware/radio/AppStatus.aidl new file mode 100644 index 0000000000..6b6269754d --- /dev/null +++ b/radio/aidl/android/hardware/radio/AppStatus.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.radio; + +import android.hardware.radio.AppState; +import android.hardware.radio.AppType; +import android.hardware.radio.PersoSubstate; +import android.hardware.radio.PinState; + +@VintfStability +parcelable AppStatus { + AppType appType; + AppState appState; + /** + * Applicable only if appState == SUBSCRIPTION_PERSO + */ + PersoSubstate persoSubstate; + /** + * e.g., from 0xA0, 0x00 -> 0x41, 0x30, 0x30, 0x30 + */ + String aidPtr; + String appLabelPtr; + /** + * Applicable to USIM, CSIM and ISIM + */ + int pin1Replaced; + PinState pin1; + PinState pin2; +} diff --git a/radio/aidl/android/hardware/radio/AppType.aidl b/radio/aidl/android/hardware/radio/AppType.aidl new file mode 100644 index 0000000000..8403f7dd63 --- /dev/null +++ b/radio/aidl/android/hardware/radio/AppType.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.radio; + +@VintfStability +@Backing(type="int") +enum AppType { + UNKNOWN, + SIM, + USIM, + RUIM, + CSIM, + ISIM, +} diff --git a/radio/aidl/android/hardware/radio/AudioQuality.aidl b/radio/aidl/android/hardware/radio/AudioQuality.aidl new file mode 100644 index 0000000000..bc4c2f1201 --- /dev/null +++ b/radio/aidl/android/hardware/radio/AudioQuality.aidl @@ -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. + */ + +package android.hardware.radio; + +/** + * Audio codec which is used on GSM, UMTS, and CDMA. These values must be opaque to the Android + * framework. Only for display. + */ +@VintfStability +@Backing(type="int") +enum AudioQuality { + /** + * Unspecified audio codec + */ + UNSPECIFIED, + /** + * AMR (Narrowband) audio codec + */ + AMR, + /** + * AMR (Wideband) audio codec + */ + AMR_WB, + /** + * GSM Enhanced Full-Rate audio codec + */ + GSM_EFR, + /** + * GSM Full-Rate audio codec + */ + GSM_FR, + /** + * GSM Half-Rate audio codec + */ + GSM_HR, + /** + * Enhanced Variable rate codec + */ + EVRC, + /** + * Enhanced Variable rate codec revision B + */ + EVRC_B, + /** + * Enhanced Variable rate codec (Wideband) + */ + EVRC_WB, + /** + * Enhanced Variable rate codec (Narrowband) + */ + EVRC_NW, +} diff --git a/radio/aidl/android/hardware/radio/BarringInfo.aidl b/radio/aidl/android/hardware/radio/BarringInfo.aidl new file mode 100644 index 0000000000..c50fa4b5db --- /dev/null +++ b/radio/aidl/android/hardware/radio/BarringInfo.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. + */ + +package android.hardware.radio; + +import android.hardware.radio.BarringInfoBarringType; +import android.hardware.radio.BarringInfoBarringTypeSpecificInfo; +import android.hardware.radio.BarringInfoServiceType; + +@VintfStability +parcelable BarringInfo { + /** + * Combined list of barring services for UTRAN, EUTRAN, and NGRAN. + * + * Barring information is defined in: + * -UTRAN - 3gpp 25.331 Sec 10.2.48.8.6. + * -EUTRAN - 3gpp 36.331 Sec 6.3.1 SystemInformationBlockType2 + * -NGRAN - 3gpp 38.331 Sec 6.3.2 UAC-BarringInfo and 22.261 Sec 6.22.2.[2-3] + */ + BarringInfoServiceType serviceType; + /** + * The type of barring applied to the service + */ + BarringInfoBarringType barringType; + /** + * Type-specific barring info if applicable + */ + BarringInfoBarringTypeSpecificInfo barringTypeSpecificInfo; +} diff --git a/radio/aidl/android/hardware/radio/BarringInfoBarringType.aidl b/radio/aidl/android/hardware/radio/BarringInfoBarringType.aidl new file mode 100644 index 0000000000..41f5fbb719 --- /dev/null +++ b/radio/aidl/android/hardware/radio/BarringInfoBarringType.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.radio; + +@VintfStability +@Backing(type="int") +enum BarringInfoBarringType { + /** + * Device is not barred for the given service + */ + NONE, + /** + * Device may be barred based on time and probability factors + */ + CONDITIONAL, + /* + * Device is unconditionally barred + */ + UNCONDITIONAL, +} diff --git a/radio/aidl/android/hardware/radio/BarringInfoBarringTypeSpecificInfo.aidl b/radio/aidl/android/hardware/radio/BarringInfoBarringTypeSpecificInfo.aidl new file mode 100644 index 0000000000..18f309dad4 --- /dev/null +++ b/radio/aidl/android/hardware/radio/BarringInfoBarringTypeSpecificInfo.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.radio; + +import android.hardware.radio.BarringInfoBarringTypeSpecificInfoConditional; + +@VintfStability +union BarringInfoBarringTypeSpecificInfo { + /** + * Barring type is either none or unconditional + */ + boolean noinit; + /** + * Must be included if barring is conditional + */ + BarringInfoBarringTypeSpecificInfoConditional conditional; +} diff --git a/radio/aidl/android/hardware/radio/BarringInfoBarringTypeSpecificInfoConditional.aidl b/radio/aidl/android/hardware/radio/BarringInfoBarringTypeSpecificInfoConditional.aidl new file mode 100644 index 0000000000..e3b7dfa657 --- /dev/null +++ b/radio/aidl/android/hardware/radio/BarringInfoBarringTypeSpecificInfoConditional.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.radio; + +@VintfStability +parcelable BarringInfoBarringTypeSpecificInfoConditional { + /** + * The barring factor as a percentage 0-100 + */ + int factor; + /** + * The number of seconds between re-evaluations of barring + */ + int timeSeconds; + /** + * Indicates whether barring is currently being applied. + * + *

    True if the UE applies barring to a conditionally barred service based on the conditional + * barring parameters. + * + *

    False if the service is conditionally barred but barring is not currently applied, which + * could be due to either the barring criteria not having been evaluated (if the UE has not + * attempted to use the service) or due to the criteria being evaluated and the UE being + * permitted to use the service despite conditional barring. + */ + boolean isBarred; +} diff --git a/radio/aidl/android/hardware/radio/BarringInfoServiceType.aidl b/radio/aidl/android/hardware/radio/BarringInfoServiceType.aidl new file mode 100644 index 0000000000..1fa52a06d5 --- /dev/null +++ b/radio/aidl/android/hardware/radio/BarringInfoServiceType.aidl @@ -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. + */ + +package android.hardware.radio; + +@VintfStability +@Backing(type="int") +enum BarringInfoServiceType { + /** + * Applicable to UTRAN + * Barring for all CS services, including registration + */ + CS_SERVICE, + /** + * Barring for all PS services, including registration + */ + PS_SERVICE, + /** + * Barring for mobile-originated circuit-switched voice calls + */ + CS_VOICE, + /** + * Applicable to EUTRAN, NGRAN + * Barring for mobile-originated signalling for any purpose + */ + MO_SIGNALLING, + /** + * Barring for mobile-originated internet or other interactive data + */ + MO_DATA, + /** + * Barring for circuit-switched fallback calling + */ + CS_FALLBACK, + /** + * Barring for IMS voice calling + */ + MMTEL_VOICE, + /** + * Barring for IMS video calling + */ + MMTEL_VIDEO, + /** + * Applicable to UTRAN, EUTRAN, NGRAN + * Barring for emergency services, either CS or emergency MMTEL + */ + EMERGENCY, + /** + * Barring for short message services + */ + SMS, + /** + * Operator-specific barring codes; applicable to NGRAN + */ + OPERATOR_1 = 1001, + OPERATOR_2 = 1002, + OPERATOR_3 = 1003, + OPERATOR_4 = 1004, + OPERATOR_5 = 1005, + OPERATOR_6 = 1006, + OPERATOR_7 = 1007, + OPERATOR_8 = 1008, + OPERATOR_9 = 1009, + OPERATOR_10 = 1010, + OPERATOR_11 = 1011, + OPERATOR_12 = 1012, + OPERATOR_13 = 1013, + OPERATOR_14 = 1014, + OPERATOR_15 = 1015, + OPERATOR_16 = 1016, + OPERATOR_17 = 1017, + OPERATOR_18 = 1018, + OPERATOR_19 = 1019, + OPERATOR_20 = 1020, + OPERATOR_21 = 1021, + OPERATOR_22 = 1022, + OPERATOR_23 = 1023, + OPERATOR_24 = 1024, + OPERATOR_25 = 1025, + OPERATOR_26 = 1026, + OPERATOR_27 = 1027, + OPERATOR_28 = 1028, + OPERATOR_29 = 1029, + OPERATOR_30 = 1030, + OPERATOR_31 = 1031, + OPERATOR_32 = 1032, +} diff --git a/radio/aidl/android/hardware/radio/Call.aidl b/radio/aidl/android/hardware/radio/Call.aidl new file mode 100644 index 0000000000..38cb3d3fdc --- /dev/null +++ b/radio/aidl/android/hardware/radio/Call.aidl @@ -0,0 +1,75 @@ +/* + * 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.radio; + +import android.hardware.radio.AudioQuality; +import android.hardware.radio.CallPresentation; +import android.hardware.radio.CallState; +import android.hardware.radio.UusInfo; + +@VintfStability +parcelable Call { + CallState state; + /** + * Connection index for use with, eg, AT+CHLD + */ + int index; + /** + * Type of address, eg 145 = intl + */ + int toa; + /** + * true if is mpty call + */ + boolean isMpty; + /** + * true if call is mobile terminated + */ + boolean isMT; + /** + * ALS line indicator if availale (0 = line 1) + */ + byte als; + /** + * true if this is a voice call + */ + boolean isVoice; + /** + * true if CDMA voice privacy mode is active + */ + boolean isVoicePrivacy; + /** + * Remote party nummber + */ + String number; + CallPresentation numberPresentation; + /** + * Remote party name + */ + String name; + CallPresentation namePresentation; + /** + * Vector of User-User Signaling Information + */ + UusInfo[] uusInfo; + AudioQuality audioQuality; + /** + * Forwarded number. It can set only one forwarded number based on 3GPP rule of the CS. + * Reference: 3GPP TS 24.008 section 10.5.4.21b + */ + String forwardedNumber; +} diff --git a/radio/aidl/android/hardware/radio/CallForwardInfo.aidl b/radio/aidl/android/hardware/radio/CallForwardInfo.aidl new file mode 100644 index 0000000000..91a30555eb --- /dev/null +++ b/radio/aidl/android/hardware/radio/CallForwardInfo.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.radio; + +import android.hardware.radio.CallForwardInfoStatus; + +/** + * See also com.android.internal.telephony.gsm.CallForwardInfo + */ +@VintfStability +parcelable CallForwardInfo { + /** + * For queryCallForwardStatus() status is DISABLE (Not used by vendor code currently) + * For setCallForward() status must be DISABLE, ENABLE, INTERROGATE, REGISTRATION, ERASURE + */ + CallForwardInfoStatus status; + /** + * From TS 27.007 7.11 "reason" + */ + int reason; + /** + * From TS 27.007 +CCFC/+CLCK "class". See table for Android mapping from MMI service code. + * 0 means user doesn't input class. + */ + int serviceClass; + /** + * From TS 27.007 7.11 "type" + */ + int toa; + /** + * From TS 27.007 7.11 "number" + */ + String number; + int timeSeconds; +} diff --git a/radio/aidl/android/hardware/radio/CallForwardInfoStatus.aidl b/radio/aidl/android/hardware/radio/CallForwardInfoStatus.aidl new file mode 100644 index 0000000000..f4ae503e4c --- /dev/null +++ b/radio/aidl/android/hardware/radio/CallForwardInfoStatus.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.radio; + +@VintfStability +@Backing(type="int") +enum CallForwardInfoStatus { + DISABLE, + ENABLE, + INTERROGATE, + REGISTRATION, + ERASURE, +} diff --git a/radio/aidl/android/hardware/radio/CallPresentation.aidl b/radio/aidl/android/hardware/radio/CallPresentation.aidl new file mode 100644 index 0000000000..76b5f21a2a --- /dev/null +++ b/radio/aidl/android/hardware/radio/CallPresentation.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.radio; + +@VintfStability +@Backing(type="int") +enum CallPresentation { + ALLOWED, + RESTRICTED, + UNKNOWN, + PAYPHONE, +} diff --git a/radio/aidl/android/hardware/radio/CallState.aidl b/radio/aidl/android/hardware/radio/CallState.aidl new file mode 100644 index 0000000000..4b6f1ac235 --- /dev/null +++ b/radio/aidl/android/hardware/radio/CallState.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. + */ + +package android.hardware.radio; + +@VintfStability +@Backing(type="int") +enum CallState { + ACTIVE, + HOLDING, + /** + * MO call only + */ + DIALING, + /** + * MO call only + */ + ALERTING, + /** + * MT call only + */ + INCOMING, + /** + * MT call only + */ + WAITING, +} diff --git a/radio/aidl/android/hardware/radio/CardPowerState.aidl b/radio/aidl/android/hardware/radio/CardPowerState.aidl new file mode 100644 index 0000000000..23088c9635 --- /dev/null +++ b/radio/aidl/android/hardware/radio/CardPowerState.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.radio; + +@VintfStability +@Backing(type="int") +enum CardPowerState { + POWER_DOWN, + POWER_UP, + POWER_UP_PASS_THROUGH, +} diff --git a/radio/aidl/android/hardware/radio/CardState.aidl b/radio/aidl/android/hardware/radio/CardState.aidl new file mode 100644 index 0000000000..c1bbee6b0a --- /dev/null +++ b/radio/aidl/android/hardware/radio/CardState.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.radio; + +@VintfStability +@Backing(type="int") +enum CardState { + /* + * Card is physically absent from device. (Some old modems use CardState.ABSENT when the SIM + * is powered off. This is no longer correct, however the platform will still support this + * legacy behavior.) + */ + ABSENT, + /* + * Card is inserted in the device + */ + PRESENT, + ERROR, + /* + * Card is present but not usable due to carrier restrictions + */ + RESTRICTED, +} diff --git a/radio/aidl/android/hardware/radio/CardStatus.aidl b/radio/aidl/android/hardware/radio/CardStatus.aidl new file mode 100644 index 0000000000..a8df53d81c --- /dev/null +++ b/radio/aidl/android/hardware/radio/CardStatus.aidl @@ -0,0 +1,71 @@ +/* + * 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.radio; + +import android.hardware.radio.AppStatus; +import android.hardware.radio.CardState; +import android.hardware.radio.PinState; + +@VintfStability +parcelable CardStatus { + CardState cardState; + /** + * Applicable to USIM and CSIM + */ + PinState universalPinState; + /** + * Value < RadioConst:CARD_MAX_APPS, -1 if none + */ + int gsmUmtsSubscriptionAppIndex; + /** + * Value < RadioConst:CARD_MAX_APPS, -1 if none + */ + int cdmaSubscriptionAppIndex; + /** + * Value < RadioConst:CARD_MAX_APPS, -1 if none + */ + int imsSubscriptionAppIndex; + /** + * size <= RadioConst::CARD_MAX_APPS + */ + AppStatus[] applications; + int physicalSlotId; + /** + * An Answer To Reset (ATR) is a message output by a Smart Card conforming to ISO/IEC 7816 + * standards, following electrical reset of the card's chip. The ATR conveys information about + * the communication parameters proposed by the card, and the card's nature and state. + * + * This data is applicable only when cardState is CardState:PRESENT. + */ + String atr; + /** + * Integrated Circuit Card IDentifier (ICCID) is Unique Identifier of the SIM CARD. File is + * located in the SIM card at EFiccid (0x2FE2) as per ETSI 102.221. The ICCID is defined by + * the ITU-T recommendation E.118 ISO/IEC 7816. + * + * This data is applicable only when cardState is CardState:PRESENT. + */ + String iccid; + /** + * The EID is the eUICC identifier. The EID shall be stored within the ECASD and can be + * retrieved by the Device at any time using the standard GlobalPlatform GET DATA command. + * + * This data is mandatory and applicable only when cardState is CardState:PRESENT and SIM card + * supports eUICC. + */ + String eid; +} diff --git a/radio/aidl/android/hardware/radio/Carrier.aidl b/radio/aidl/android/hardware/radio/Carrier.aidl new file mode 100644 index 0000000000..be619b941b --- /dev/null +++ b/radio/aidl/android/hardware/radio/Carrier.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.radio; + +import android.hardware.radio.CarrierMatchType; + +@VintfStability +parcelable Carrier { + String mcc; + String mnc; + /** + * Specify match type for the carrier. If it’s ALL, matchData is empty string; otherwise, + * matchData is the value for the match type. + */ + CarrierMatchType matchType; + String matchData; +} diff --git a/radio/aidl/android/hardware/radio/CarrierMatchType.aidl b/radio/aidl/android/hardware/radio/CarrierMatchType.aidl new file mode 100644 index 0000000000..39b9466d69 --- /dev/null +++ b/radio/aidl/android/hardware/radio/CarrierMatchType.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. + */ + +package android.hardware.radio; + +@VintfStability +@Backing(type="int") +enum CarrierMatchType { + /** + * Apply to all carrier with the same mcc/mnc + */ + ALL, + /** + * Use SPN and mcc/mnc to identify the carrier + */ + SPN, + /** + * Use IMSI prefix and mcc/mnc to identify the carrier + */ + IMSI_PREFIX, + /** + * Use GID1 and mcc/mnc to identify the carrier + */ + GID1, + /** + * Use GID2 and mcc/mnc to identify the carrier + */ + GID2, +} diff --git a/radio/aidl/android/hardware/radio/CarrierRestrictions.aidl b/radio/aidl/android/hardware/radio/CarrierRestrictions.aidl new file mode 100644 index 0000000000..70df637f6e --- /dev/null +++ b/radio/aidl/android/hardware/radio/CarrierRestrictions.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.radio; + +import android.hardware.radio.Carrier; + +@VintfStability +parcelable CarrierRestrictions { + /** + * Allowed carriers + */ + Carrier[] allowedCarriers; + /** + * Explicitly excluded carriers which match allowed_carriers. Eg. allowedCarriers match mcc/mnc, + * excludedCarriers has same mcc/mnc and gid1 is ABCD. It means except the carrier whose gid1 + * is ABCD, all carriers with the same mcc/mnc are allowed. + */ + Carrier[] excludedCarriers; +} diff --git a/radio/aidl/android/hardware/radio/CarrierRestrictionsWithPriority.aidl b/radio/aidl/android/hardware/radio/CarrierRestrictionsWithPriority.aidl new file mode 100644 index 0000000000..057b016415 --- /dev/null +++ b/radio/aidl/android/hardware/radio/CarrierRestrictionsWithPriority.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. + */ + +package android.hardware.radio; + +import android.hardware.radio.Carrier; + +@VintfStability +parcelable CarrierRestrictionsWithPriority { + /** + * List of allowed carriers. + * The character '?' is used as wildcard character to match any value. + */ + Carrier[] allowedCarriers; + /** + * List of excluded carriers. + * The character '?' is used as wildcard character to match any value. + */ + Carrier[] excludedCarriers; + /** + * True means that only carriers included in the allowed list and not in the excluded list + * are permitted. Eg. allowedCarriers match mcc/mnc, excludedCarriers has same mcc/mnc and + * gid1 is ABCD. It means except the carrier whose gid1 is ABCD, all carriers with the + * same mcc/mnc are allowed. + * False means that all carriers are allowed except those included in the excluded list + * and not in the allowed list. + */ + boolean allowedCarriersPrioritized; +} diff --git a/radio/aidl/android/hardware/radio/CdmaBroadcastSmsConfigInfo.aidl b/radio/aidl/android/hardware/radio/CdmaBroadcastSmsConfigInfo.aidl new file mode 100644 index 0000000000..46f634558c --- /dev/null +++ b/radio/aidl/android/hardware/radio/CdmaBroadcastSmsConfigInfo.aidl @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.radio; + +@VintfStability +parcelable CdmaBroadcastSmsConfigInfo { + /** + * Defines a broadcast message identifier whose value is 0x0000 - 0xFFFF as defined in + * C.R1001G 9.3.1 and 9.3.2. + */ + int serviceCategory; + /** + * Language code of broadcast message whose value is 0x00 - 0x07 as defined in C.R1001G 9.2. + */ + int language; + /** + * Selected false means message types specified in serviceCategory are not accepted, + * while true means accepted. + */ + boolean selected; +} diff --git a/radio/aidl/android/hardware/radio/CdmaCallWaiting.aidl b/radio/aidl/android/hardware/radio/CdmaCallWaiting.aidl new file mode 100644 index 0000000000..3db6ee003b --- /dev/null +++ b/radio/aidl/android/hardware/radio/CdmaCallWaiting.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. + */ + +package android.hardware.radio; + +import android.hardware.radio.CdmaCallWaitingNumberPlan; +import android.hardware.radio.CdmaCallWaitingNumberPresentation; +import android.hardware.radio.CdmaCallWaitingNumberType; +import android.hardware.radio.CdmaSignalInfoRecord; + +@VintfStability +parcelable CdmaCallWaiting { + /** + * Remote party number + */ + String number; + CdmaCallWaitingNumberPresentation numberPresentation; + /** + * Remote party name + */ + String name; + CdmaSignalInfoRecord signalInfoRecord; + /** + * Required to support International Call Waiting + */ + CdmaCallWaitingNumberType numberType; + /** + * Required to support International Call Waiting + */ + CdmaCallWaitingNumberPlan numberPlan; +} diff --git a/radio/aidl/android/hardware/radio/CdmaCallWaitingNumberPlan.aidl b/radio/aidl/android/hardware/radio/CdmaCallWaitingNumberPlan.aidl new file mode 100644 index 0000000000..76d2197060 --- /dev/null +++ b/radio/aidl/android/hardware/radio/CdmaCallWaitingNumberPlan.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.radio; + +@VintfStability +@Backing(type="int") +enum CdmaCallWaitingNumberPlan { + UNKNOWN = 0, + ISDN = 1, + DATA = 3, + TELEX = 4, + NATIONAL = 8, + PRIVATE = 9, +} diff --git a/radio/aidl/android/hardware/radio/CdmaCallWaitingNumberPresentation.aidl b/radio/aidl/android/hardware/radio/CdmaCallWaitingNumberPresentation.aidl new file mode 100644 index 0000000000..f9fca965d9 --- /dev/null +++ b/radio/aidl/android/hardware/radio/CdmaCallWaitingNumberPresentation.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.radio; + +@VintfStability +@Backing(type="int") +enum CdmaCallWaitingNumberPresentation { + ALLOWED, + RESTRICTED, + UNKNOWN, +} diff --git a/radio/aidl/android/hardware/radio/CdmaCallWaitingNumberType.aidl b/radio/aidl/android/hardware/radio/CdmaCallWaitingNumberType.aidl new file mode 100644 index 0000000000..9c5b8ed9ac --- /dev/null +++ b/radio/aidl/android/hardware/radio/CdmaCallWaitingNumberType.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.radio; + +@VintfStability +@Backing(type="int") +enum CdmaCallWaitingNumberType { + UNKNOWN, + INTERNATIONAL, + NATIONAL, + NETWORK_SPECIFIC, + SUBSCRIBER, +} diff --git a/radio/aidl/android/hardware/radio/CdmaDisplayInfoRecord.aidl b/radio/aidl/android/hardware/radio/CdmaDisplayInfoRecord.aidl new file mode 100644 index 0000000000..9b11f37c6d --- /dev/null +++ b/radio/aidl/android/hardware/radio/CdmaDisplayInfoRecord.aidl @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.radio; + +/** + * Display Info Rec as defined in C.S0005 section 3.7.5.1. Extended Display Info Rec as defined in + * C.S0005 section 3.7.5.16. Note that the Extended Display info rec contains multiple records of + * the form: display_tag, display_len, and display_len occurrences of the char field if the + * display_tag is not 10000000 or 10000001. To save space, the records are stored consecutively in + * a byte buffer. The display_tag, display_len and chari fields are all 1 byte. + */ +@VintfStability +parcelable CdmaDisplayInfoRecord { + /** + * Max length = RadioConst:CDMA_ALPHA_INFO_BUFFER_LENGTH + */ + String alphaBuf; +} diff --git a/radio/aidl/android/hardware/radio/CdmaInfoRecName.aidl b/radio/aidl/android/hardware/radio/CdmaInfoRecName.aidl new file mode 100644 index 0000000000..63ec699a57 --- /dev/null +++ b/radio/aidl/android/hardware/radio/CdmaInfoRecName.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.radio; + +/** + * Names of the CDMA info records (C.S0005 section 3.7.5) + */ +@VintfStability +@Backing(type="int") +enum CdmaInfoRecName { + DISPLAY, + CALLED_PARTY_NUMBER, + CALLING_PARTY_NUMBER, + CONNECTED_NUMBER, + SIGNAL, + REDIRECTING_NUMBER, + LINE_CONTROL, + EXTENDED_DISPLAY, + T53_CLIR, + T53_RELEASE, + T53_AUDIO_CONTROL, +} diff --git a/radio/aidl/android/hardware/radio/CdmaInformationRecord.aidl b/radio/aidl/android/hardware/radio/CdmaInformationRecord.aidl new file mode 100644 index 0000000000..7d9cb0ac13 --- /dev/null +++ b/radio/aidl/android/hardware/radio/CdmaInformationRecord.aidl @@ -0,0 +1,63 @@ +/* + * 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.radio; + +import android.hardware.radio.CdmaDisplayInfoRecord; +import android.hardware.radio.CdmaInfoRecName; +import android.hardware.radio.CdmaLineControlInfoRecord; +import android.hardware.radio.CdmaNumberInfoRecord; +import android.hardware.radio.CdmaRedirectingNumberInfoRecord; +import android.hardware.radio.CdmaSignalInfoRecord; +import android.hardware.radio.CdmaT53AudioControlInfoRecord; +import android.hardware.radio.CdmaT53ClirInfoRecord; + +@VintfStability +parcelable CdmaInformationRecord { + /** + * Based on CdmaInfoRecName, only one of the below vectors must have size = 1. + * All other vectors must have size 0. + */ + CdmaInfoRecName name; + /** + * Display and extended display info rec + */ + CdmaDisplayInfoRecord[] display; + /** + * Called party number, calling party number, connected number info rec + */ + CdmaNumberInfoRecord[] number; + /** + * Signal info rec + */ + CdmaSignalInfoRecord[] signal; + /** + * Redirecting number info rec + */ + CdmaRedirectingNumberInfoRecord[] redir; + /** + * Line control info rec + */ + CdmaLineControlInfoRecord[] lineCtrl; + /** + * T53 CLIR info rec + */ + CdmaT53ClirInfoRecord[] clir; + /** + * T53 Audio Control info rec + */ + CdmaT53AudioControlInfoRecord[] audioCtrl; +} diff --git a/radio/aidl/android/hardware/radio/CdmaInformationRecords.aidl b/radio/aidl/android/hardware/radio/CdmaInformationRecords.aidl new file mode 100644 index 0000000000..dcf0ed20ac --- /dev/null +++ b/radio/aidl/android/hardware/radio/CdmaInformationRecords.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.radio; + +import android.hardware.radio.CdmaInformationRecord; + +@VintfStability +parcelable CdmaInformationRecords { + /** + * Max length = RadioConst:CDMA_MAX_NUMBER_OF_INFO_RECS + */ + CdmaInformationRecord[] infoRec; +} diff --git a/radio/aidl/android/hardware/radio/CdmaLineControlInfoRecord.aidl b/radio/aidl/android/hardware/radio/CdmaLineControlInfoRecord.aidl new file mode 100644 index 0000000000..a6178afd52 --- /dev/null +++ b/radio/aidl/android/hardware/radio/CdmaLineControlInfoRecord.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.radio; + +/** + * Line Control Information Record as defined in C.S0005 section 3.7.5.15 + */ +@VintfStability +parcelable CdmaLineControlInfoRecord { + byte lineCtrlPolarityIncluded; + byte lineCtrlToggle; + byte lineCtrlReverse; + byte lineCtrlPowerDenial; +} diff --git a/radio/aidl/android/hardware/radio/CdmaNumberInfoRecord.aidl b/radio/aidl/android/hardware/radio/CdmaNumberInfoRecord.aidl new file mode 100644 index 0000000000..06e8317bd0 --- /dev/null +++ b/radio/aidl/android/hardware/radio/CdmaNumberInfoRecord.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.radio; + +/** + * Called Party Number Info Rec as defined in C.S0005 section 3.7.5.2 + * Calling Party Number Info Rec as defined in C.S0005 section 3.7.5.3 + * Connected Number Info Rec as defined in C.S0005 section 3.7.5.4 + */ +@VintfStability +parcelable CdmaNumberInfoRecord { + /** + * Max length = RADIO_CDMA_NUMBER_INFO_BUFFER_LENGTH + */ + String number; + byte numberType; + byte numberPlan; + byte pi; + byte si; +} diff --git a/radio/aidl/android/hardware/radio/CdmaOtaProvisionStatus.aidl b/radio/aidl/android/hardware/radio/CdmaOtaProvisionStatus.aidl new file mode 100644 index 0000000000..0cb43141f6 --- /dev/null +++ b/radio/aidl/android/hardware/radio/CdmaOtaProvisionStatus.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.radio; + +@VintfStability +@Backing(type="int") +enum CdmaOtaProvisionStatus { + SPL_UNLOCKED, + SPC_RETRIES_EXCEEDED, + A_KEY_EXCHANGED, + SSD_UPDATED, + NAM_DOWNLOADED, + MDN_DOWNLOADED, + IMSI_DOWNLOADED, + PRL_DOWNLOADED, + COMMITTED, + OTAPA_STARTED, + OTAPA_STOPPED, + OTAPA_ABORTED, +} diff --git a/radio/aidl/android/hardware/radio/CdmaRedirectingNumberInfoRecord.aidl b/radio/aidl/android/hardware/radio/CdmaRedirectingNumberInfoRecord.aidl new file mode 100644 index 0000000000..d15621a5b5 --- /dev/null +++ b/radio/aidl/android/hardware/radio/CdmaRedirectingNumberInfoRecord.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.radio; + +import android.hardware.radio.CdmaNumberInfoRecord; +import android.hardware.radio.CdmaRedirectingReason; + +@VintfStability +parcelable CdmaRedirectingNumberInfoRecord { + CdmaNumberInfoRecord redirectingNumber; + /** + * Set to UNKNOWN if not included. + */ + CdmaRedirectingReason redirectingReason; +} diff --git a/radio/aidl/android/hardware/radio/CdmaRedirectingReason.aidl b/radio/aidl/android/hardware/radio/CdmaRedirectingReason.aidl new file mode 100644 index 0000000000..c86b9b2265 --- /dev/null +++ b/radio/aidl/android/hardware/radio/CdmaRedirectingReason.aidl @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.radio; + +/** + * Redirecting Number Information Record as defined in C.S0005 section 3.7.5.11 + */ +@VintfStability +@Backing(type="int") +enum CdmaRedirectingReason { + UNKNOWN = 0, + CALL_FORWARDING_BUSY = 1, + CALL_FORWARDING_NO_REPLY = 2, + CALLED_DTE_OUT_OF_ORDER = 9, + CALL_FORWARDING_BY_THE_CALLED_DTE = 10, + CALL_FORWARDING_UNCONDITIONAL = 15, + RESERVED, +} diff --git a/radio/aidl/android/hardware/radio/CdmaRoamingType.aidl b/radio/aidl/android/hardware/radio/CdmaRoamingType.aidl new file mode 100644 index 0000000000..df09e0337c --- /dev/null +++ b/radio/aidl/android/hardware/radio/CdmaRoamingType.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.radio; + +@VintfStability +@Backing(type="int") +enum CdmaRoamingType { + HOME_NETWORK, + AFFILIATED_ROAM, + ANY_ROAM, +} diff --git a/radio/aidl/android/hardware/radio/CdmaSignalInfoRecord.aidl b/radio/aidl/android/hardware/radio/CdmaSignalInfoRecord.aidl new file mode 100644 index 0000000000..36ecb1813d --- /dev/null +++ b/radio/aidl/android/hardware/radio/CdmaSignalInfoRecord.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. + */ + +package android.hardware.radio; + +/** + * CDMA Signal Information Record as defined in C.S0005 section 3.7.5.5 + */ +@VintfStability +parcelable CdmaSignalInfoRecord { + /** + * True if signal information record is present + */ + boolean isPresent; + /** + * Defined in 3.7.5.5-1 + */ + byte signalType; + /** + * Defined in 3.7.5.5-2 + */ + byte alertPitch; + /** + * Defined in 3.7.5.5-3, 3.7.5.5-4 or 3.7.5.5-5 + */ + byte signal; +} diff --git a/radio/aidl/android/hardware/radio/CdmaSignalStrength.aidl b/radio/aidl/android/hardware/radio/CdmaSignalStrength.aidl new file mode 100644 index 0000000000..e6c2fb5e2f --- /dev/null +++ b/radio/aidl/android/hardware/radio/CdmaSignalStrength.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.radio; + +@VintfStability +parcelable CdmaSignalStrength { + /** + * This value is the actual RSSI value multiplied by -1. Example: If the actual RSSI is -75, + * then this response value will be 75. INT_MAX means invalid/unreported. + */ + int dbm; + /** + * This value is the actual Ec/Io multiplied by -10. Example: If the actual Ec/Io is -12.5 dB, + * then this response value will be 125. INT_MAX means invalid/unreported. + */ + int ecio; +} diff --git a/radio/aidl/android/hardware/radio/CdmaSmsAck.aidl b/radio/aidl/android/hardware/radio/CdmaSmsAck.aidl new file mode 100644 index 0000000000..b412b704d5 --- /dev/null +++ b/radio/aidl/android/hardware/radio/CdmaSmsAck.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.radio; + +import android.hardware.radio.CdmaSmsErrorClass; + +@VintfStability +parcelable CdmaSmsAck { + CdmaSmsErrorClass errorClass; + /** + * SMS cause code as defined in N.S00005, 6.5.2.125. + * Currently, only 35 (resource shortage) and 39 (other terminal problem) are reported. + */ + int smsCauseCode; +} diff --git a/radio/aidl/android/hardware/radio/CdmaSmsAddress.aidl b/radio/aidl/android/hardware/radio/CdmaSmsAddress.aidl new file mode 100644 index 0000000000..83e883925e --- /dev/null +++ b/radio/aidl/android/hardware/radio/CdmaSmsAddress.aidl @@ -0,0 +1,53 @@ +/* + * 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.radio; + +import android.hardware.radio.CdmaSmsDigitMode; +import android.hardware.radio.CdmaSmsNumberMode; +import android.hardware.radio.CdmaSmsNumberPlan; +import android.hardware.radio.CdmaSmsNumberType; + +@VintfStability +parcelable CdmaSmsAddress { + /** + * CdmaSmsDigitMode is of two types : 4 bit and 8 bit. + * For 4-bit type, only "digits" field defined below in this struct is used. + */ + CdmaSmsDigitMode digitMode; + /** + * Used only when digitMode is 8-bit. + */ + CdmaSmsNumberMode numberMode; + /** + * Used only when digitMode is 8-bit. To specify an international address, use the following: + * digitMode = CdmaSmsDigitMode:EIGHT_BIT: + * numberMode = CdmaSmsNumberMode:NOT_DATA_NETWORK + * numberType = CdmaSmsNumberType:INTERNATIONAL_OR_DATA_IP + * numberPlan = CdmaSmsNumberPlan:TELEPHONY + * numberOfDigits = number of digits + * digits = ASCII digits, e.g. '1', '2', '3', '4', and '5' + */ + CdmaSmsNumberType numberType; + /** + * Used only when digitMode is 8-bit. + */ + CdmaSmsNumberPlan numberPlan; + /** + * Each byte in this array represents a 4 bit or 8-bit digit of address data. + */ + byte[] digits; +} diff --git a/radio/aidl/android/hardware/radio/CdmaSmsDigitMode.aidl b/radio/aidl/android/hardware/radio/CdmaSmsDigitMode.aidl new file mode 100644 index 0000000000..662311dd06 --- /dev/null +++ b/radio/aidl/android/hardware/radio/CdmaSmsDigitMode.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.radio; + +@VintfStability +@Backing(type="int") +enum CdmaSmsDigitMode { + /** + * DTMF digits + */ + FOUR_BIT, + EIGHT_BIT, +} diff --git a/radio/aidl/android/hardware/radio/CdmaSmsErrorClass.aidl b/radio/aidl/android/hardware/radio/CdmaSmsErrorClass.aidl new file mode 100644 index 0000000000..ec8c74edcc --- /dev/null +++ b/radio/aidl/android/hardware/radio/CdmaSmsErrorClass.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.radio; + +@VintfStability +@Backing(type="int") +enum CdmaSmsErrorClass { + NO_ERROR, + ERROR, +} diff --git a/radio/aidl/android/hardware/radio/CdmaSmsMessage.aidl b/radio/aidl/android/hardware/radio/CdmaSmsMessage.aidl new file mode 100644 index 0000000000..f38cc5b5ea --- /dev/null +++ b/radio/aidl/android/hardware/radio/CdmaSmsMessage.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.radio; + +import android.hardware.radio.CdmaSmsAddress; +import android.hardware.radio.CdmaSmsSubaddress; + +@VintfStability +parcelable CdmaSmsMessage { + int teleserviceId; + boolean isServicePresent; + int serviceCategory; + CdmaSmsAddress address; + CdmaSmsSubaddress subAddress; + /** + * 3GPP2 C.S0015-B, v2.0 + */ + byte[] bearerData; +} diff --git a/radio/aidl/android/hardware/radio/CdmaSmsNumberMode.aidl b/radio/aidl/android/hardware/radio/CdmaSmsNumberMode.aidl new file mode 100644 index 0000000000..e1e96dd9f2 --- /dev/null +++ b/radio/aidl/android/hardware/radio/CdmaSmsNumberMode.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.radio; + +@VintfStability +@Backing(type="int") +enum CdmaSmsNumberMode { + NOT_DATA_NETWORK, + DATA_NETWORK, +} diff --git a/radio/aidl/android/hardware/radio/CdmaSmsNumberPlan.aidl b/radio/aidl/android/hardware/radio/CdmaSmsNumberPlan.aidl new file mode 100644 index 0000000000..23dea9be9d --- /dev/null +++ b/radio/aidl/android/hardware/radio/CdmaSmsNumberPlan.aidl @@ -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. + */ + +package android.hardware.radio; + +@VintfStability +@Backing(type="int") +enum CdmaSmsNumberPlan { + UNKNOWN, + /** + * CCITT E.164 and E.163, including ISDN plan + */ + TELEPHONY, + RESERVED_2, + /** + * CCITT X.121 + */ + DATA, + /** + * CCITT F.69 + */ + TELEX, + RESERVED_5, + RESERVED_6, + RESERVED_7, + RESERVED_8, + PRIVATE, + RESERVED_10, + RESERVED_11, + RESERVED_12, + RESERVED_13, + RESERVED_14, + RESERVED_15, +} diff --git a/radio/aidl/android/hardware/radio/CdmaSmsNumberType.aidl b/radio/aidl/android/hardware/radio/CdmaSmsNumberType.aidl new file mode 100644 index 0000000000..e439d1fe7b --- /dev/null +++ b/radio/aidl/android/hardware/radio/CdmaSmsNumberType.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.radio; + +@VintfStability +@Backing(type="int") +enum CdmaSmsNumberType { + UNKNOWN, + /** + * INTERNATIONAL is used when number mode is not data network address. DATA_IP is used when the + * number mode is data network address. + */ + INTERNATIONAL_OR_DATA_IP, + /** + * NATIONAL is used when the number mode is not data netework address. INTERNET_MAIL is used + * when the number mode is data network address. For INTERNET_MAIL, in the address data + * "digits", each byte contains an ASCII character. Examples are: "x@y.com,a@b.com" + * Ref TIA/EIA-637A 3.4.3.3 + */ + NATIONAL_OR_INTERNET_MAIL, + NETWORK, + SUBSCRIBER, + /** + * GSM SMS: address value is GSM 7-bit chars + */ + ALPHANUMERIC, + ABBREVIATED, + RESERVED_7, +} diff --git a/radio/aidl/android/hardware/radio/CdmaSmsSubaddress.aidl b/radio/aidl/android/hardware/radio/CdmaSmsSubaddress.aidl new file mode 100644 index 0000000000..4a84c792be --- /dev/null +++ b/radio/aidl/android/hardware/radio/CdmaSmsSubaddress.aidl @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.radio; + +import android.hardware.radio.CdmaSmsSubaddressType; + +@VintfStability +parcelable CdmaSmsSubaddress { + CdmaSmsSubaddressType subaddressType; + /** + * True means the last byte's lower 4 bits must be ignored + */ + boolean odd; + /** + * Each byte represents an 8-bit digit of subaddress data + */ + byte[] digits; +} diff --git a/radio/aidl/android/hardware/radio/CdmaSmsSubaddressType.aidl b/radio/aidl/android/hardware/radio/CdmaSmsSubaddressType.aidl new file mode 100644 index 0000000000..60aa37bd8a --- /dev/null +++ b/radio/aidl/android/hardware/radio/CdmaSmsSubaddressType.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.radio; + +@VintfStability +@Backing(type="int") +enum CdmaSmsSubaddressType { + /** + * CCITT X.213 or ISO 8348 AD2 + */ + NSAP, + /** + * e.g. X.25 + */ + USER_SPECIFIED, +} diff --git a/radio/aidl/android/hardware/radio/CdmaSmsWriteArgs.aidl b/radio/aidl/android/hardware/radio/CdmaSmsWriteArgs.aidl new file mode 100644 index 0000000000..f613e392b6 --- /dev/null +++ b/radio/aidl/android/hardware/radio/CdmaSmsWriteArgs.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.radio; + +import android.hardware.radio.CdmaSmsMessage; +import android.hardware.radio.CdmaSmsWriteArgsStatus; + +@VintfStability +parcelable CdmaSmsWriteArgs { + /** + * Status of message. See TS 27.005 3.1 + */ + CdmaSmsWriteArgsStatus status; + CdmaSmsMessage message; +} diff --git a/radio/aidl/android/hardware/radio/CdmaSmsWriteArgsStatus.aidl b/radio/aidl/android/hardware/radio/CdmaSmsWriteArgsStatus.aidl new file mode 100644 index 0000000000..009e8a913f --- /dev/null +++ b/radio/aidl/android/hardware/radio/CdmaSmsWriteArgsStatus.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.radio; + +@VintfStability +@Backing(type="int") +enum CdmaSmsWriteArgsStatus { + REC_UNREAD, + REC_READ, + STO_UNSENT, + STO_SENT, +} diff --git a/radio/aidl/android/hardware/radio/CdmaSubscriptionSource.aidl b/radio/aidl/android/hardware/radio/CdmaSubscriptionSource.aidl new file mode 100644 index 0000000000..b83e81a227 --- /dev/null +++ b/radio/aidl/android/hardware/radio/CdmaSubscriptionSource.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.radio; + +@VintfStability +@Backing(type="int") +enum CdmaSubscriptionSource { + RUIM_SIM, + NV, +} diff --git a/radio/aidl/android/hardware/radio/CdmaT53AudioControlInfoRecord.aidl b/radio/aidl/android/hardware/radio/CdmaT53AudioControlInfoRecord.aidl new file mode 100644 index 0000000000..715a2f7b2c --- /dev/null +++ b/radio/aidl/android/hardware/radio/CdmaT53AudioControlInfoRecord.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.radio; + +/** + * T53 Audio Control Information Record + */ +@VintfStability +parcelable CdmaT53AudioControlInfoRecord { + byte upLink; + byte downLink; +} diff --git a/radio/aidl/android/hardware/radio/CdmaT53ClirInfoRecord.aidl b/radio/aidl/android/hardware/radio/CdmaT53ClirInfoRecord.aidl new file mode 100644 index 0000000000..636d40c48a --- /dev/null +++ b/radio/aidl/android/hardware/radio/CdmaT53ClirInfoRecord.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.radio; + +/** + * T53 CLIR Information Record + */ +@VintfStability +parcelable CdmaT53ClirInfoRecord { + byte cause; +} diff --git a/radio/aidl/android/hardware/radio/CellConfigLte.aidl b/radio/aidl/android/hardware/radio/CellConfigLte.aidl new file mode 100644 index 0000000000..56a1a10c1d --- /dev/null +++ b/radio/aidl/android/hardware/radio/CellConfigLte.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.radio; + +/** + * Contains the configuration of the LTE cell tower. + */ +@VintfStability +parcelable CellConfigLte { + /** + * Indicates that if E-UTRA-NR Dual Connectivity (EN-DC) is supported by the LTE cell. + * True if the plmn-InfoList-r15 is present in SIB2 and at least one bit in this list is true, + * otherwise this value should be false. + * Reference: 3GPP TS 36.331 v15.2.2 6.3.1 System information blocks. + */ + boolean isEndcAvailable; +} diff --git a/radio/aidl/android/hardware/radio/CellConnectionStatus.aidl b/radio/aidl/android/hardware/radio/CellConnectionStatus.aidl new file mode 100644 index 0000000000..faa9b28635 --- /dev/null +++ b/radio/aidl/android/hardware/radio/CellConnectionStatus.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.radio; + +@VintfStability +@Backing(type="int") +enum CellConnectionStatus { + /** + * Cell is not a serving cell. + */ + NONE, + /** + * UE has connection to cell for signalling and possibly data (3GPP 36.331, 25.331). + */ + PRIMARY_SERVING, + /** + * UE has connection to cell for data (3GPP 36.331, 25.331). + */ + SECONDARY_SERVING, +} diff --git a/radio/aidl/android/hardware/radio/CellIdentity.aidl b/radio/aidl/android/hardware/radio/CellIdentity.aidl new file mode 100644 index 0000000000..abfcc9d11f --- /dev/null +++ b/radio/aidl/android/hardware/radio/CellIdentity.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.radio; + +import android.hardware.radio.CellIdentityCdma; +import android.hardware.radio.CellIdentityGsm; +import android.hardware.radio.CellIdentityLte; +import android.hardware.radio.CellIdentityNr; +import android.hardware.radio.CellIdentityTdscdma; +import android.hardware.radio.CellIdentityWcdma; + +/** + * A union representing the CellIdentity of a single cell. + */ +@VintfStability +union CellIdentity { + boolean noinit; + CellIdentityGsm gsm; + CellIdentityWcdma wcdma; + CellIdentityTdscdma tdscdma; + CellIdentityCdma cdma; + CellIdentityLte lte; + CellIdentityNr nr; +} diff --git a/radio/aidl/android/hardware/radio/CellIdentityCdma.aidl b/radio/aidl/android/hardware/radio/CellIdentityCdma.aidl new file mode 100644 index 0000000000..56867e982b --- /dev/null +++ b/radio/aidl/android/hardware/radio/CellIdentityCdma.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.radio; + +import android.hardware.radio.CellIdentityOperatorNames; + +@VintfStability +parcelable CellIdentityCdma { + /** + * Network Id 0..65535, INT_MAX if unknown + */ + int networkId; + /** + * CDMA System Id 0..32767, INT_MAX if unknown + */ + int systemId; + /** + * Base Station Id 0..65535, INT_MAX if unknown + */ + int baseStationId; + /** + * Longitude is a decimal number as specified in 3GPP2 C.S0005-A v6.0. It is represented in + * units of 0.25 seconds and ranges from -2592000 to 2592000, both values inclusive + * (corresponding to a range of -180 to +180 degrees). INT_MAX if unknown + */ + int longitude; + /** + * Latitude is a decimal number as specified in 3GPP2 C.S0005-A v6.0. It is represented in + * units of 0.25 seconds and ranges from -1296000 to 1296000, both values inclusive + * (corresponding to a range of -90 to +90 degrees). INT_MAX if unknown + */ + int latitude; + CellIdentityOperatorNames operatorNames; +} diff --git a/radio/aidl/android/hardware/radio/CellIdentityGsm.aidl b/radio/aidl/android/hardware/radio/CellIdentityGsm.aidl new file mode 100644 index 0000000000..f1c5042fe8 --- /dev/null +++ b/radio/aidl/android/hardware/radio/CellIdentityGsm.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.radio; + +import android.hardware.radio.CellIdentityOperatorNames; + +@VintfStability +parcelable CellIdentityGsm { + /** + * 3-digit Mobile Country Code, 0..999, empty string if unknown + */ + String mcc; + /** + * 2 or 3-digit Mobile Network Code, 0..999, empty string if unknown + */ + String mnc; + /** + * 16-bit Location Area Code, 0..65535, INT_MAX if unknown + */ + int lac; + /** + * 16-bit GSM Cell Identity described in TS 27.007, 0..65535, INT_MAX if unknown + */ + int cid; + /** + * 16-bit GSM Absolute RF channel number; this value must be valid + */ + int arfcn; + /** + * 6-bit Base Station Identity Code, 0xFF if unknown + */ + byte bsic; + CellIdentityOperatorNames operatorNames; + /** + * Additional PLMN-IDs beyond the primary PLMN broadcast for this cell + */ + String[] additionalPlmns; +} diff --git a/radio/aidl/android/hardware/radio/CellIdentityLte.aidl b/radio/aidl/android/hardware/radio/CellIdentityLte.aidl new file mode 100644 index 0000000000..f7f8fef663 --- /dev/null +++ b/radio/aidl/android/hardware/radio/CellIdentityLte.aidl @@ -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. + */ + +package android.hardware.radio; + +import android.hardware.radio.CellIdentityOperatorNames; +import android.hardware.radio.EutranBands; +import android.hardware.radio.OptionalCsgInfo; + +@VintfStability +parcelable CellIdentityLte { + /** + * 3-digit Mobile Country Code, 0..999, empty string if unknown + */ + String mcc; + /** + * 2 or 3-digit Mobile Network Code, 0..999, empty string if unknown + */ + String mnc; + /** + * 28-bit Cell Identity described in TS TS 27.007, INT_MAX if unknown + */ + int ci; + /** + * Physical cell id 0..503; this value must be valid + */ + int pci; + /** + * 16-bit tracking area code, INT_MAX if unknown + */ + int tac; + /** + * 18-bit LTE Absolute RF Channel Number; this value must be valid + */ + int earfcn; + CellIdentityOperatorNames operatorNames; + /** + * Cell bandwidth, in kHz. + */ + int bandwidth; + /** + * Additional PLMN-IDs beyond the primary PLMN broadcast for this cell + */ + String[] additionalPlmns; + /** + * Information about any closed subscriber group ID for this cell + */ + OptionalCsgInfo optionalCsgInfo; + /** + * Bands used by the cell. + */ + EutranBands[] bands; +} diff --git a/radio/aidl/android/hardware/radio/CellIdentityNr.aidl b/radio/aidl/android/hardware/radio/CellIdentityNr.aidl new file mode 100644 index 0000000000..6879c63faa --- /dev/null +++ b/radio/aidl/android/hardware/radio/CellIdentityNr.aidl @@ -0,0 +1,67 @@ +/* + * 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.radio; + +import android.hardware.radio.CellIdentityOperatorNames; +import android.hardware.radio.NgranBands; + +/** + * The CellIdentity structure should be reported once for each element of the PLMN-IdentityInfoList + * broadcast in SIB1 CellAccessRelatedInfo as per 3GPP TS 38.331 Section 6.3.2. + */ +@VintfStability +parcelable CellIdentityNr { + /** + * 3-digit Mobile Country Code, in range[0, 999]; This value must be valid for registered or + * camped cells; INT_MAX means invalid/unreported. + */ + String mcc; + /** + * 2 or 3-digit Mobile Network Code, in range [0, 999], This value must be valid for + * registered or camped cells; INT_MAX means invalid/unreported. + */ + String mnc; + /** + * NR Cell Identity in range [0, 68719476735] (36 bits) described in 3GPP TS 38.331, which + * unambiguously identifies a cell within a PLMN. This value must be valid for registered or + * camped cells; LONG_MAX (2^63-1) means invalid/unreported. + */ + long nci; + /** + * Physical cell id in range [0, 1007] described in 3GPP TS 38.331. This value must be valid. + */ + int pci; + /** + * 16-bit tracking area code, INT_MAX means invalid/unreported. + */ + int tac; + /** + * NR Absolute Radio Frequency Channel Number, in range [0, 3279165]. + * Reference: 3GPP TS 38.101-1 and 3GPP TS 38.101-2 section 5.4.2.1. + * This value must be valid. + */ + int nrarfcn; + CellIdentityOperatorNames operatorNames; + /** + * Additional PLMN-IDs beyond the primary PLMN broadcast for this cell + */ + String[] additionalPlmns; + /** + * Bands used by the cell. + */ + NgranBands[] bands; +} diff --git a/radio/aidl/android/hardware/radio/CellIdentityOperatorNames.aidl b/radio/aidl/android/hardware/radio/CellIdentityOperatorNames.aidl new file mode 100644 index 0000000000..dea9929f73 --- /dev/null +++ b/radio/aidl/android/hardware/radio/CellIdentityOperatorNames.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.radio; + +@VintfStability +parcelable CellIdentityOperatorNames { + /** + * Long alpha operator name string or enhanced operator name string. + */ + String alphaLong; + /** + * Short alpha operator name string or enhanced operator name string. + */ + String alphaShort; +} diff --git a/radio/aidl/android/hardware/radio/CellIdentityTdscdma.aidl b/radio/aidl/android/hardware/radio/CellIdentityTdscdma.aidl new file mode 100644 index 0000000000..8268bba14a --- /dev/null +++ b/radio/aidl/android/hardware/radio/CellIdentityTdscdma.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.radio; + +import android.hardware.radio.CellIdentityOperatorNames; +import android.hardware.radio.OptionalCsgInfo; + +@VintfStability +parcelable CellIdentityTdscdma { + /** + * 3-digit Mobile Country Code, 0..999, empty string if unknown. + */ + String mcc; + /** + * 2 or 3-digit Mobile Network Code, 0..999, empty string if unknown. + */ + String mnc; + /** + * 16-bit Location Area Code, 0..65535, INT_MAX if unknown. + */ + int lac; + /** + * 28-bit UMTS Cell Identity described in TS 25.331, 0..268435455, INT_MAX if unknown. + */ + int cid; + /** + * 8-bit Cell Parameters ID described in TS 25.331, 0..127, INT_MAX if unknown. + */ + int cpid; + /** + * 16-bit UMTS Absolute RF Channel Number defined in TS 25.102 5.4.4; this value must be valid. + */ + int uarfcn; + CellIdentityOperatorNames operatorNames; + /** + * Additional PLMN-IDs beyond the primary PLMN broadcast for this cell. + */ + String[] additionalPlmns; + /** + * Information about any closed subscriber group ID for this cell. + */ + OptionalCsgInfo optionalCsgInfo; +} diff --git a/radio/aidl/android/hardware/radio/CellIdentityWcdma.aidl b/radio/aidl/android/hardware/radio/CellIdentityWcdma.aidl new file mode 100644 index 0000000000..667c15b65c --- /dev/null +++ b/radio/aidl/android/hardware/radio/CellIdentityWcdma.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.radio; + +import android.hardware.radio.CellIdentityOperatorNames; +import android.hardware.radio.OptionalCsgInfo; + +@VintfStability +parcelable CellIdentityWcdma { + /** + * 3-digit Mobile Country Code, 0..999, empty string if unknown. + */ + String mcc; + /** + * 2 or 3-digit Mobile Network Code, 0..999, empty string if unknown. + */ + String mnc; + /** + * 16-bit Location Area Code, 0..65535, INT_MAX if unknown. + */ + int lac; + /** + * 28-bit UMTS Cell Identity described in TS 25.331, 0..268435455, INT_MAX if unknown. + */ + int cid; + /** + * 9-bit UMTS Primary Scrambling Code described in TS 25.331, 0..511; this value must be valid. + */ + int psc; + /** + * 16-bit UMTS Absolute RF Channel Number; this value must be valid. + */ + int uarfcn; + CellIdentityOperatorNames operatorNames; + /** + * Additional PLMN-IDs beyond the primary PLMN broadcast for this cell. + */ + String[] additionalPlmns; + /** + * Information about any closed subscriber group ID for this cell. + */ + OptionalCsgInfo optionalCsgInfo; +} diff --git a/radio/aidl/android/hardware/radio/CellInfo.aidl b/radio/aidl/android/hardware/radio/CellInfo.aidl new file mode 100644 index 0000000000..fe4f330611 --- /dev/null +++ b/radio/aidl/android/hardware/radio/CellInfo.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.radio; + +import android.hardware.radio.CellConnectionStatus; +import android.hardware.radio.CellInfoCellInfoRatSpecificInfo; + +@VintfStability +parcelable CellInfo { + /** + * True if this cell is registered false if not registered. + */ + boolean registered; + /** + * Connection status for the cell. + */ + CellConnectionStatus connectionStatus; + CellInfoCellInfoRatSpecificInfo ratSpecificInfo; +} diff --git a/radio/aidl/android/hardware/radio/CellInfoCdma.aidl b/radio/aidl/android/hardware/radio/CellInfoCdma.aidl new file mode 100644 index 0000000000..27a35d1247 --- /dev/null +++ b/radio/aidl/android/hardware/radio/CellInfoCdma.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.radio; + +import android.hardware.radio.CdmaSignalStrength; +import android.hardware.radio.CellIdentityCdma; +import android.hardware.radio.EvdoSignalStrength; + +@VintfStability +parcelable CellInfoCdma { + CellIdentityCdma cellIdentityCdma; + CdmaSignalStrength signalStrengthCdma; + EvdoSignalStrength signalStrengthEvdo; +} diff --git a/radio/aidl/android/hardware/radio/CellInfoCellInfoRatSpecificInfo.aidl b/radio/aidl/android/hardware/radio/CellInfoCellInfoRatSpecificInfo.aidl new file mode 100644 index 0000000000..cdd33863de --- /dev/null +++ b/radio/aidl/android/hardware/radio/CellInfoCellInfoRatSpecificInfo.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. + */ + +package android.hardware.radio; + +import android.hardware.radio.CellInfoCdma; +import android.hardware.radio.CellInfoGsm; +import android.hardware.radio.CellInfoLte; +import android.hardware.radio.CellInfoNr; +import android.hardware.radio.CellInfoTdscdma; +import android.hardware.radio.CellInfoWcdma; + +@VintfStability +union CellInfoCellInfoRatSpecificInfo { + /** + * 3gpp CellInfo types. + */ + CellInfoGsm gsm; + CellInfoWcdma wcdma; + CellInfoTdscdma tdscdma; + CellInfoLte lte; + CellInfoNr nr; + /** + * 3gpp2 CellInfo types; + */ + CellInfoCdma cdma; +} diff --git a/radio/aidl/android/hardware/radio/CellInfoGsm.aidl b/radio/aidl/android/hardware/radio/CellInfoGsm.aidl new file mode 100644 index 0000000000..16ba8574ef --- /dev/null +++ b/radio/aidl/android/hardware/radio/CellInfoGsm.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.radio; + +import android.hardware.radio.CellIdentityGsm; +import android.hardware.radio.GsmSignalStrength; + +@VintfStability +parcelable CellInfoGsm { + CellIdentityGsm cellIdentityGsm; + GsmSignalStrength signalStrengthGsm; +} diff --git a/radio/aidl/android/hardware/radio/CellInfoInfo.aidl b/radio/aidl/android/hardware/radio/CellInfoInfo.aidl new file mode 100644 index 0000000000..4d5e12d4cd --- /dev/null +++ b/radio/aidl/android/hardware/radio/CellInfoInfo.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.radio; + +import android.hardware.radio.CellInfoCdma; +import android.hardware.radio.CellInfoGsm; +import android.hardware.radio.CellInfoLte; +import android.hardware.radio.CellInfoNr; +import android.hardware.radio.CellInfoTdscdma; +import android.hardware.radio.CellInfoWcdma; + +@VintfStability +union CellInfoInfo { + CellInfoGsm gsm; + CellInfoCdma cdma; + CellInfoWcdma wcdma; + CellInfoTdscdma tdscdma; + CellInfoLte lte; + CellInfoNr nr; +} diff --git a/radio/aidl/android/hardware/radio/CellInfoLte.aidl b/radio/aidl/android/hardware/radio/CellInfoLte.aidl new file mode 100644 index 0000000000..d3389c1564 --- /dev/null +++ b/radio/aidl/android/hardware/radio/CellInfoLte.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.radio; + +import android.hardware.radio.CellIdentityLte; +import android.hardware.radio.LteSignalStrength; + +@VintfStability +parcelable CellInfoLte { + CellIdentityLte cellIdentityLte; + LteSignalStrength signalStrengthLte; +} diff --git a/radio/aidl/android/hardware/radio/CellInfoNr.aidl b/radio/aidl/android/hardware/radio/CellInfoNr.aidl new file mode 100644 index 0000000000..b1f311f113 --- /dev/null +++ b/radio/aidl/android/hardware/radio/CellInfoNr.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.radio; + +import android.hardware.radio.CellIdentityNr; +import android.hardware.radio.NrSignalStrength; + +@VintfStability +parcelable CellInfoNr { + CellIdentityNr cellIdentityNr; + NrSignalStrength signalStrengthNr; +} diff --git a/radio/aidl/android/hardware/radio/CellInfoTdscdma.aidl b/radio/aidl/android/hardware/radio/CellInfoTdscdma.aidl new file mode 100644 index 0000000000..b7d09bc07b --- /dev/null +++ b/radio/aidl/android/hardware/radio/CellInfoTdscdma.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.radio; + +import android.hardware.radio.CellIdentityTdscdma; +import android.hardware.radio.TdscdmaSignalStrength; + +@VintfStability +parcelable CellInfoTdscdma { + CellIdentityTdscdma cellIdentityTdscdma; + TdscdmaSignalStrength signalStrengthTdscdma; +} diff --git a/radio/aidl/android/hardware/radio/CellInfoType.aidl b/radio/aidl/android/hardware/radio/CellInfoType.aidl new file mode 100644 index 0000000000..8e5e8c92d3 --- /dev/null +++ b/radio/aidl/android/hardware/radio/CellInfoType.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.radio; + +@VintfStability +@Backing(type="int") +enum CellInfoType { + NONE, + GSM, + CDMA, + LTE, + WCDMA, + TD_SCDMA, +} diff --git a/radio/aidl/android/hardware/radio/CellInfoWcdma.aidl b/radio/aidl/android/hardware/radio/CellInfoWcdma.aidl new file mode 100644 index 0000000000..03b086367a --- /dev/null +++ b/radio/aidl/android/hardware/radio/CellInfoWcdma.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.radio; + +import android.hardware.radio.CellIdentityWcdma; +import android.hardware.radio.WcdmaSignalStrength; + +@VintfStability +parcelable CellInfoWcdma { + CellIdentityWcdma cellIdentityWcdma; + WcdmaSignalStrength signalStrengthWcdma; +} diff --git a/radio/aidl/android/hardware/radio/CfData.aidl b/radio/aidl/android/hardware/radio/CfData.aidl new file mode 100644 index 0000000000..c6a91b9807 --- /dev/null +++ b/radio/aidl/android/hardware/radio/CfData.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.radio; + +import android.hardware.radio.CallForwardInfo; + +@VintfStability +parcelable CfData { + /** + * This is the response data for SS request to query call forward status. + * See getCallForwardStatus(). Max size = RadioConst:NUM_SERVICE_CLASSES. + */ + CallForwardInfo[] cfInfo; +} diff --git a/radio/aidl/android/hardware/radio/ClipStatus.aidl b/radio/aidl/android/hardware/radio/ClipStatus.aidl new file mode 100644 index 0000000000..c75c609092 --- /dev/null +++ b/radio/aidl/android/hardware/radio/ClipStatus.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.radio; + +@VintfStability +@Backing(type="int") +enum ClipStatus { + /** + * CLIP provisioned + */ + CLIP_PROVISIONED, + /** + * CLIP not provisioned + */ + CLIP_UNPROVISIONED, + /** + * Unknown, e.g. no networks etc + */ + UNKNOWN, +} diff --git a/radio/aidl/android/hardware/radio/Clir.aidl b/radio/aidl/android/hardware/radio/Clir.aidl new file mode 100644 index 0000000000..a13ff9da3e --- /dev/null +++ b/radio/aidl/android/hardware/radio/Clir.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.radio; + +@VintfStability +@Backing(type="int") +enum Clir { + /** + * Use subscription default value + */ + DEFAULT, + /** + * Restrict CLI presentation + */ + INVOCATION, + /** + * Allow CLI presentation + */ + SUPPRESSION, +} diff --git a/radio/aidl/android/hardware/radio/ClosedSubscriberGroupInfo.aidl b/radio/aidl/android/hardware/radio/ClosedSubscriberGroupInfo.aidl new file mode 100644 index 0000000000..7c6fb7a5fe --- /dev/null +++ b/radio/aidl/android/hardware/radio/ClosedSubscriberGroupInfo.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.radio; + +@VintfStability +parcelable ClosedSubscriberGroupInfo { + /** + * Indicates whether the cell is restricted to only CSG members. A cell not broadcasting the + * CSG Indication but reporting CSG information is considered a Hybrid Cell. + * Refer to the "csg-Indication" field in 3GPP TS 36.331 section 6.2.2 + * SystemInformationBlockType1. + * Also refer to "CSG Indicator" in 3GPP TS 25.331 section 10.2.48.8.1 and TS 25.304. + */ + boolean csgIndication; + /** + * The human-readable name of the closed subscriber group operating this cell. + * Refer to "hnb-Name" in TS 36.331 section 6.2.2 SystemInformationBlockType9. + * Also refer to "HNB Name" in 3GPP TS25.331 section 10.2.48.8.23 and TS 23.003 section 4.8. + */ + String homeNodebName; + /** + * The identity of the closed subscriber group that the cell belongs to. + * Refer to "CSG-Identity" in TS 36.336 section 6.3.4. + * Also refer to "CSG Identity" in 3GPP TS 25.331 section 10.3.2.8 and TS 23.003 section 4.7. + */ + int csgIdentity; +} diff --git a/radio/aidl/android/hardware/radio/DataCallFailCause.aidl b/radio/aidl/android/hardware/radio/DataCallFailCause.aidl new file mode 100644 index 0000000000..021988b221 --- /dev/null +++ b/radio/aidl/android/hardware/radio/DataCallFailCause.aidl @@ -0,0 +1,1303 @@ +/* + * 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.radio; + +@VintfStability +@Backing(type="int") +enum DataCallFailCause { + /** + * An integer cause code defined in TS 24.008 section 6.1.3.1.3 or TS 24.301 Release 8+ Annex B. + * If the implementation does not have access to the exact cause codes, then it must return one + * of the following values, as the UI layer needs to distinguish these cases for error + * notification and potential retries. + */ + NONE = 0, + /** + * No retry + */ + OPERATOR_BARRED = 0x08, + /** + * PDP_FAIL_LLC_SNDCP = 0x19 + */ + NAS_SIGNALLING = 0x0E, + INSUFFICIENT_RESOURCES = 0x1A, + /** + * No retry + */ + MISSING_UNKNOWN_APN = 0x1B, + /** + * No retry + */ + UNKNOWN_PDP_ADDRESS_TYPE = 0x1C, + /** + * No retry + */ + USER_AUTHENTICATION = 0x1D, + /** + * No retry + */ + ACTIVATION_REJECT_GGSN = 0x1E, + ACTIVATION_REJECT_UNSPECIFIED = 0x1F, + /** + * No retry + */ + SERVICE_OPTION_NOT_SUPPORTED = 0x20, + /** + * No retry + */ + SERVICE_OPTION_NOT_SUBSCRIBED = 0x21, + SERVICE_OPTION_OUT_OF_ORDER = 0x22, + /** + * No retry + */ + NSAPI_IN_USE = 0x23, + /** + * Possibly restart radio, based on framework config + */ + REGULAR_DEACTIVATION = 0x24, + QOS_NOT_ACCEPTED = 0x25, + NETWORK_FAILURE = 0x26, + UMTS_REACTIVATION_REQ = 0x27, + FEATURE_NOT_SUPP = 0x28, + TFT_SEMANTIC_ERROR = 0x29, + TFT_SYTAX_ERROR = 0x2A, + UNKNOWN_PDP_CONTEXT = 0x2B, + FILTER_SEMANTIC_ERROR = 0x2C, + FILTER_SYTAX_ERROR = 0x2D, + PDP_WITHOUT_ACTIVE_TFT = 0x2E, + /** + * No retry + */ + ONLY_IPV4_ALLOWED = 0x32, + /** + * No retry + */ + ONLY_IPV6_ALLOWED = 0x33, + ONLY_SINGLE_BEARER_ALLOWED = 0x34, + ESM_INFO_NOT_RECEIVED = 0x35, + PDN_CONN_DOES_NOT_EXIST = 0x36, + MULTI_CONN_TO_SAME_PDN_NOT_ALLOWED = 0x37, + MAX_ACTIVE_PDP_CONTEXT_REACHED = 0x41, + UNSUPPORTED_APN_IN_CURRENT_PLMN = 0x42, + INVALID_TRANSACTION_ID = 0x51, + MESSAGE_INCORRECT_SEMANTIC = 0x5F, + INVALID_MANDATORY_INFO = 0x60, + MESSAGE_TYPE_UNSUPPORTED = 0x61, + MSG_TYPE_NONCOMPATIBLE_STATE = 0x62, + UNKNOWN_INFO_ELEMENT = 0x63, + CONDITIONAL_IE_ERROR = 0x64, + MSG_AND_PROTOCOL_STATE_UNCOMPATIBLE = 0x65, + /** + * No retry + */ + PROTOCOL_ERRORS = 0x6F, + APN_TYPE_CONFLICT = 0x70, + INVALID_PCSCF_ADDR = 0x71, + INTERNAL_CALL_PREEMPT_BY_HIGH_PRIO_APN = 0x72, + EMM_ACCESS_BARRED = 0x73, + EMERGENCY_IFACE_ONLY = 0x74, + IFACE_MISMATCH = 0x75, + COMPANION_IFACE_IN_USE = 0x76, + IP_ADDRESS_MISMATCH = 0x77, + IFACE_AND_POL_FAMILY_MISMATCH = 0x78, + EMM_ACCESS_BARRED_INFINITE_RETRY = 0x79, + AUTH_FAILURE_ON_EMERGENCY_CALL = 0x7A, + OEM_DCFAILCAUSE_1 = 0x1001, + OEM_DCFAILCAUSE_2 = 0x1002, + OEM_DCFAILCAUSE_3 = 0x1003, + OEM_DCFAILCAUSE_4 = 0x1004, + OEM_DCFAILCAUSE_5 = 0x1005, + OEM_DCFAILCAUSE_6 = 0x1006, + OEM_DCFAILCAUSE_7 = 0x1007, + OEM_DCFAILCAUSE_8 = 0x1008, + OEM_DCFAILCAUSE_9 = 0x1009, + OEM_DCFAILCAUSE_10 = 0x100A, + OEM_DCFAILCAUSE_11 = 0x100B, + OEM_DCFAILCAUSE_12 = 0x100C, + OEM_DCFAILCAUSE_13 = 0x100D, + OEM_DCFAILCAUSE_14 = 0x100E, + OEM_DCFAILCAUSE_15 = 0x100F, + /** + * Not mentioned in the specification + */ + VOICE_REGISTRATION_FAIL = -1, + /** + * Not mentioned in the specification + */ + DATA_REGISTRATION_FAIL = -2, + /** + * Network/modem disonnect + */ + SIGNAL_LOST = -3, + /** + * Preferred technology has changed, must retry with parameters appropriate for new technology + */ + PREF_RADIO_TECH_CHANGED = -4, + /** + * Data call was disconnected because radio was resetting, powered off - no retry + */ + RADIO_POWER_OFF = -5, + /** + * Data call was disconnected by modem because tethered mode was up on same APN/data profile + * No retry until tethered call is off + */ + TETHERED_CALL_ACTIVE = -6, + ERROR_UNSPECIFIED = 0xffff, + /** + * Network cannot provide the requested service and PDP context is deactivated because of LLC + * or SNDCP failure. + */ + LLC_SNDCP = 0x19, + /** + * UE requested to modify QoS parameters or the bearer control mode, which is not compatible + * with the selected bearer control mode. + */ + ACTIVATION_REJECTED_BCM_VIOLATION = 0x30, + /** + * Network has already initiated the activation, modification, or deactivation of bearer + * resources that was requested by the UE. + */ + COLLISION_WITH_NETWORK_INITIATED_REQUEST = 0x38, + /** + * Network supports IPv4v6 PDP type only. Non-IP type is not allowed. In LTE mode of operation, + * this is a PDN throttling cause code, meaning the UE may throttle further requests to the + * same APN. + */ + ONLY_IPV4V6_ALLOWED = 0x39, + /** + * Network supports non-IP PDP type only. IPv4, IPv6 and IPv4v6 is not allowed. In LTE mode of + * operation, this is a PDN throttling cause code, meaning the UE can throttle further requests + * to the same APN. + */ + ONLY_NON_IP_ALLOWED = 0x3A, + /** + * QCI (QoS Class Identifier) indicated in the UE request cannot be supported. + */ + UNSUPPORTED_QCI_VALUE = 0x3B, + /** + * Procedure requested by the UE was rejected because the bearer handling is not supported. + */ + BEARER_HANDLING_NOT_SUPPORTED = 0x3C, + /** + * Not receiving a DNS address that was mandatory. + */ + INVALID_DNS_ADDR = 0x7B, + /** + * Not receiving either a PCSCF or a DNS address, one of them being mandatory. + */ + INVALID_PCSCF_OR_DNS_ADDRESS = 0x7C, + /** + * Emergency call bring up on a different ePDG. + */ + CALL_PREEMPT_BY_EMERGENCY_APN = 0x7F, + /** + * UE performs a detach or disconnect PDN action based on TE requirements. + */ + UE_INITIATED_DETACH_OR_DISCONNECT = 0x80, + /** + * Reason unspecified for foreign agent rejected MIP (Mobile IP) registration. + */ + MIP_FA_REASON_UNSPECIFIED = 0x7D0, + /** + * Foreign agent administratively prohibited MIP (Mobile IP) registration. + */ + MIP_FA_ADMIN_PROHIBITED = 0x7D1, + /** + * Foreign agent rejected MIP (Mobile IP) registration because of insufficient resources. + */ + MIP_FA_INSUFFICIENT_RESOURCES = 0x7D2, + /** + * Foreign agent rejected MIP (Mobile IP) registration because of MN-AAA authenticator was + * wrong. + */ + MIP_FA_MOBILE_NODE_AUTHENTICATION_FAILURE = 0x7D3, + /** + * Foreign agent rejected MIP (Mobile IP) registration because of home agent authentication + * failure. + */ + MIP_FA_HOME_AGENT_AUTHENTICATION_FAILURE = 0x7D4, + /** + * Foreign agent rejected MIP (Mobile IP) registration because of requested lifetime was too + * long. + */ + MIP_FA_REQUESTED_LIFETIME_TOO_LONG = 0x7D5, + /** + * Foreign agent rejected MIP (Mobile IP) registration because of malformed request. + */ + MIP_FA_MALFORMED_REQUEST = 0x7D6, + /** + * Foreign agent rejected MIP (Mobile IP) registration because of malformed reply. + */ + MIP_FA_MALFORMED_REPLY = 0x7D7, + /** + * Foreign agent rejected MIP (Mobile IP) registration because of requested encapsulation was + * unavailable. + */ + MIP_FA_ENCAPSULATION_UNAVAILABLE = 0x7D8, + /** + * Foreign agent rejected MIP (Mobile IP) registration of VJ Header Compression was unavailable. + */ + MIP_FA_VJ_HEADER_COMPRESSION_UNAVAILABLE = 0x7D9, + /** + * Foreign agent rejected MIP (Mobile IP) registration because of reverse tunnel was + * unavailable. + */ + MIP_FA_REVERSE_TUNNEL_UNAVAILABLE = 0x7DA, + /** + * Foreign agent rejected MIP (Mobile IP) registration because of reverse tunnel was mandatory + * but not requested by device. + */ + MIP_FA_REVERSE_TUNNEL_IS_MANDATORY = 0x7DB, + /** + * Foreign agent rejected MIP (Mobile IP) registration because of delivery style was not + * supported. + */ + MIP_FA_DELIVERY_STYLE_NOT_SUPPORTED = 0x7DC, + /** + * Foreign agent rejected MIP (Mobile IP) registration because of missing NAI (Network Access + * Identifier). + */ + MIP_FA_MISSING_NAI = 0x7DD, + /** + * Foreign agent rejected MIP (Mobile IP) registration because of missing Home Agent. + */ + MIP_FA_MISSING_HOME_AGENT = 0x7DE, + /** + * Foreign agent rejected MIP (Mobile IP) registration because of missing Home Address. + */ + MIP_FA_MISSING_HOME_ADDRESS = 0x7DF, + /** + * Foreign agent rejected MIP (Mobile IP) registration because of unknown challenge. + */ + MIP_FA_UNKNOWN_CHALLENGE = 0x7E0, + /** + * Foreign agent rejected MIP (Mobile IP) registration because of missing challenge. + */ + MIP_FA_MISSING_CHALLENGE = 0x7E1, + /** + * Foreign agent rejected MIP (Mobile IP) registration because of stale challenge. + */ + MIP_FA_STALE_CHALLENGE = 0x7E2, + /** + * Reason unspecified for home agent rejected MIP (Mobile IP) registration. + */ + MIP_HA_REASON_UNSPECIFIED = 0x7E3, + /** + * Home agent administratively prohibited MIP (Mobile IP) registration. + */ + MIP_HA_ADMIN_PROHIBITED = 0x7E4, + /** + * Home agent rejected MIP (Mobile IP) registration because of insufficient resources. + */ + MIP_HA_INSUFFICIENT_RESOURCES = 0x7E5, + /** + * Home agent rejected MIP (Mobile IP) registration because of MN-HA authenticator was wrong. + */ + MIP_HA_MOBILE_NODE_AUTHENTICATION_FAILURE = 0x7E6, + /** + * Home agent rejected MIP (Mobile IP) registration because of foreign agent authentication + * failure. + */ + MIP_HA_FOREIGN_AGENT_AUTHENTICATION_FAILURE = 0x7E7, + /** + * Home agent rejected MIP (Mobile IP) registration because of registration id mismatch. + */ + MIP_HA_REGISTRATION_ID_MISMATCH = 0x7E8, + /** + * Home agent rejected MIP (Mobile IP) registration because of malformed request. + */ + MIP_HA_MALFORMED_REQUEST = 0x7E9, + /** + * Home agent rejected MIP (Mobile IP) registration because of unknown home agent address. + */ + MIP_HA_UNKNOWN_HOME_AGENT_ADDRESS = 0x7EA, + /** + * Home agent rejected MIP (Mobile IP) registration because of reverse tunnel was unavailable. + */ + MIP_HA_REVERSE_TUNNEL_UNAVAILABLE = 0x7EB, + /** + * Home agent rejected MIP (Mobile IP) registration because of reverse tunnel is mandatory but + * not requested by device. + */ + MIP_HA_REVERSE_TUNNEL_IS_MANDATORY = 0x7EC, + /** + * Home agent rejected MIP (Mobile IP) registration because of encapsulation unavailable. + */ + MIP_HA_ENCAPSULATION_UNAVAILABLE = 0x7ED, + /** + * Tearing down is in progress. + */ + CLOSE_IN_PROGRESS = 0x7EE, + /** + * Brought down by the network. + */ + NETWORK_INITIATED_TERMINATION = 0x7EF, + /** + * Another application in modem preempts the data call. + */ + MODEM_APP_PREEMPTED = 0x7F0, + /** + * IPV4 PDN is in throttled state due to network providing only IPV6 address during the previous + * VSNCP bringup (subs_limited_to_v6). + */ + PDN_IPV4_CALL_DISALLOWED = 0x7F1, + /** + * IPV4 PDN is in throttled state due to previous VSNCP bringup failure(s). + */ + PDN_IPV4_CALL_THROTTLED = 0x7F2, + /** + * IPV6 PDN is in throttled state due to network providing only IPV4 address during the previous + * VSNCP bringup (subs_limited_to_v4). + */ + PDN_IPV6_CALL_DISALLOWED = 0x7F3, + /** + * IPV6 PDN is in throttled state due to previous VSNCP bringup failure(s). + */ + PDN_IPV6_CALL_THROTTLED = 0x7F4, + /** + * Modem restart. + */ + MODEM_RESTART = 0x7F5, + /** + * PDP PPP calls are not supported. + */ + PDP_PPP_NOT_SUPPORTED = 0x7F6, + /** + * RAT on which the data call is attempted/connected is no longer the preferred RAT. + */ + UNPREFERRED_RAT = 0x7F7, + /** + * Physical link is in the process of cleanup. + */ + PHYSICAL_LINK_CLOSE_IN_PROGRESS = 0x7F8, + /** + * Interface bring up is attempted for an APN that is yet to be handed over to target RAT. + */ + APN_PENDING_HANDOVER = 0x7F9, + /** + * APN bearer type in the profile does not match preferred network mode. + */ + PROFILE_BEARER_INCOMPATIBLE = 0x7FA, + /** + * Card was refreshed or removed. + */ + SIM_CARD_CHANGED = 0x7FB, + /** + * Device is going into lower power mode or powering down. + */ + LOW_POWER_MODE_OR_POWERING_DOWN = 0x7FC, + /** + * APN has been disabled. + */ + APN_DISABLED = 0x7FD, + /** + * Maximum PPP inactivity timer expired. + */ + MAX_PPP_INACTIVITY_TIMER_EXPIRED = 0x7FE, + /** + * IPv6 address transfer failed. + */ + IPV6_ADDRESS_TRANSFER_FAILED = 0x7FF, + /** + * Target RAT swap failed. + */ + TRAT_SWAP_FAILED = 0x800, + /** + * Device falls back from eHRPD to HRPD. + */ + EHRPD_TO_HRPD_FALLBACK = 0x801, + /** + * UE is in MIP-only configuration but the MIP configuration fails on call bring up due to + * incorrect provisioning. + */ + MIP_CONFIG_FAILURE = 0x802, + /** + * PDN inactivity timer expired due to no data transmission in a configurable duration of time. + */ + PDN_INACTIVITY_TIMER_EXPIRED = 0x803, + /** + * IPv4 data call bring up is rejected because the UE already maintains the allotted maximum + * number of IPv4 data connections. + */ + MAX_IPV4_CONNECTIONS = 0x804, + /** + * IPv6 data call bring up is rejected because the UE already maintains the allotted maximum + * number of IPv6 data connections. + */ + MAX_IPV6_CONNECTIONS = 0x805, + /** + * New PDN bring up is rejected during interface selection because the UE has already allotted + * the available interfaces for other PDNs. + */ + APN_MISMATCH = 0x806, + /** + * New call bring up is rejected since the existing data call IP type doesn't match the + * requested IP. + */ + IP_VERSION_MISMATCH = 0x807, + /** + * Dial up networking (DUN) call bring up is rejected since UE is in eHRPD RAT. + */ + DUN_CALL_DISALLOWED = 0x808, + /** + * Rejected/Brought down since UE is transition between EPC and NONEPC RAT. + */ + INTERNAL_EPC_NONEPC_TRANSITION = 0x809, + /** + * The current interface is being in use. + */ + INTERFACE_IN_USE = 0x80A, + /** + * PDN connection to the APN is disallowed on the roaming network. + */ + APN_DISALLOWED_ON_ROAMING = 0x80B, + /** + * APN-related parameters are changed. + */ + APN_PARAMETERS_CHANGED = 0x80C, + /** + * PDN is attempted to be brought up with NULL APN but NULL APN is not supported. + */ + NULL_APN_DISALLOWED = 0x80D, + /** + * Thermal level increases and causes calls to be torn down when normal mode of operation is + * not allowed. + */ + THERMAL_MITIGATION = 0x80E, + /** + * PDN Connection to a given APN is disallowed because data is disabled from the device user + * interface settings. + */ + DATA_SETTINGS_DISABLED = 0x80F, + /** + * PDN Connection to a given APN is disallowed because data roaming is disabled from the device + * user interface settings and the UE is roaming. + */ + DATA_ROAMING_SETTINGS_DISABLED = 0x810, + /** + * DDS (Default data subscription) switch occurs. + */ + DDS_SWITCHED = 0x811, + /** + * PDN being brought up with an APN that is part of forbidden APN Name list. + */ + FORBIDDEN_APN_NAME = 0x812, + /** + * Default data subscription switch is in progress. + */ + DDS_SWITCH_IN_PROGRESS = 0x813, + /** + * Roaming is disallowed during call bring up. + */ + CALL_DISALLOWED_IN_ROAMING = 0x814, + /** + * UE is unable to bring up a non-IP data call because the device is not camped on a NB1 cell. + */ + NON_IP_NOT_SUPPORTED = 0x815, + /** + * Non-IP PDN is in throttled state due to previous VSNCP bringup failure(s). + */ + PDN_NON_IP_CALL_THROTTLED = 0x816, + /** + * Non-IP PDN is in disallowed state due to the network providing only an IP address. + */ + PDN_NON_IP_CALL_DISALLOWED = 0x817, + /** + * Device in CDMA locked state. + */ + CDMA_LOCK = 0x818, + /** + * Received an intercept order from the base station. + */ + CDMA_INTERCEPT = 0x819, + /** + * Receiving a reorder from the base station. + */ + CDMA_REORDER = 0x81A, + /** + * Receiving a release from the base station with a SO (Service Option) Reject reason. + */ + CDMA_RELEASE_DUE_TO_SO_REJECTION = 0x81B, + /** + * Receiving an incoming call from the base station. + */ + CDMA_INCOMING_CALL = 0x81C, + /** + * Received an alert stop from the base station due to incoming only. + */ + CDMA_ALERT_STOP = 0x81D, + /** + * Channel acquisition failures. This indicates that device has failed acquiring all the + * channels in the PRL. + */ + CHANNEL_ACQUISITION_FAILURE = 0x81E, + /** + * Maximum access probes transmitted. + */ + MAX_ACCESS_PROBE = 0x81F, + /** + * Concurrent service is not supported by base station. + */ + CONCURRENT_SERVICE_NOT_SUPPORTED_BY_BASE_STATION = 0x820, + /** + * There was no response received from the base station. + */ + NO_RESPONSE_FROM_BASE_STATION = 0x821, + /** + * The base station rejecting the call. + */ + REJECTED_BY_BASE_STATION = 0x822, + /** + * The concurrent services requested were not compatible. + */ + CONCURRENT_SERVICES_INCOMPATIBLE = 0x823, + /** + * Device does not have CDMA service. + */ + NO_CDMA_SERVICE = 0x824, + /** + * RUIM not being present. + */ + RUIM_NOT_PRESENT = 0x825, + /** + * Receiving a retry order from the base station. + */ + CDMA_RETRY_ORDER = 0x826, + /** + * Access blocked by the base station. + */ + ACCESS_BLOCK = 0x827, + /** + * Access blocked by the base station for all mobile devices. + */ + ACCESS_BLOCK_ALL = 0x828, + /** + * Maximum access probes for the IS-707B call. + */ + IS707B_MAX_ACCESS_PROBES = 0x829, + /** + * Put device in thermal emergency. + */ + THERMAL_EMERGENCY = 0x82A, + /** + * In favor of a voice call or SMS when concurrent voice and data are not supported. + */ + CONCURRENT_SERVICES_NOT_ALLOWED = 0x82B, + /** + * The other clients rejected incoming call. + */ + INCOMING_CALL_REJECTED = 0x82C, + /** + * No service on the gateway. + */ + NO_SERVICE_ON_GATEWAY = 0x82D, + /** + * GPRS context is not available. + */ + NO_GPRS_CONTEXT = 0x82E, + /** + * Network refuses service to the MS because either an identity of the MS is not acceptable to + * the network or the MS does not pass the authentication check. + */ + ILLEGAL_MS = 0x82F, + /** + * ME could not be authenticated and the ME used is not acceptable to the network. + */ + ILLEGAL_ME = 0x830, + /** + * Not allowed to operate either GPRS or non-GPRS services. + */ + GPRS_SERVICES_AND_NON_GPRS_SERVICES_NOT_ALLOWED = 0x831, + /** + * MS is not allowed to operate GPRS services. + */ + GPRS_SERVICES_NOT_ALLOWED = 0x832, + /** + * No matching identity or context could be found in the network. + */ + MS_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK = 0x833, + /** + * Mobile reachable timer has expired, or the GMM context data related to the subscription does + * not exist in the SGSN. + */ + IMPLICITLY_DETACHED = 0x834, + /** + * UE requests GPRS service, or the network initiates a detach request in a PLMN which does not + * offer roaming for GPRS services to that MS. + */ + PLMN_NOT_ALLOWED = 0x835, + /** + * MS requests service, or the network initiates a detach request, in a location area where the + * HPLMN determines that the MS, by subscription, is not allowed to operate. + */ + LOCATION_AREA_NOT_ALLOWED = 0x836, + /** + * UE requests GPRS service or the network initiates a detach request in a PLMN that does not + * offer roaming for GPRS services. + */ + GPRS_SERVICES_NOT_ALLOWED_IN_THIS_PLMN = 0x837, + /** + * PDP context already exists. + */ + PDP_DUPLICATE = 0x838, + /** + * RAT change on the UE. + */ + UE_RAT_CHANGE = 0x839, + /** + * Network cannot serve a request from the MS due to congestion. + */ + CONGESTION = 0x83A, + /** + * MS requests an establishment of the radio access bearers for all active PDP contexts by + * sending a service request message indicating data to the network, but the SGSN does not have + * any active PDP context. + */ + NO_PDP_CONTEXT_ACTIVATED = 0x83B, + /** + * Access class blocking restrictions for the current camped cell. + */ + ACCESS_CLASS_DSAC_REJECTION = 0x83C, + /** + * SM attempts PDP activation for a maximum of four attempts. + */ + PDP_ACTIVATE_MAX_RETRY_FAILED = 0x83D, + /** + * Radio access bearer failure. + */ + RADIO_ACCESS_BEARER_FAILURE = 0x83E, + /** + * Invalid EPS bearer identity in the request. + */ + ESM_UNKNOWN_EPS_BEARER_CONTEXT = 0x83F, + /** + * Data radio bearer is released by the RRC. + */ + DRB_RELEASED_BY_RRC = 0x840, + /** + * Indicate the connection was released. + */ + CONNECTION_RELEASED = 0x841, + /** + * UE is detached. + */ + EMM_DETACHED = 0x842, + /** + * Attach procedure is rejected by the network. + */ + EMM_ATTACH_FAILED = 0x843, + /** + * Attach procedure is started for EMC purposes. + */ + EMM_ATTACH_STARTED = 0x844, + /** + * Service request procedure failure. + */ + LTE_NAS_SERVICE_REQUEST_FAILED = 0x845, + /** + * Active dedicated bearer was requested using the same default bearer ID. + */ + DUPLICATE_BEARER_ID = 0x846, + /** + * Collision scenarios for the UE and network-initiated procedures. + */ + ESM_COLLISION_SCENARIOS = 0x847, + /** + * Bearer must be deactivated to synchronize with the network. + */ + ESM_BEARER_DEACTIVATED_TO_SYNC_WITH_NETWORK = 0x848, + /** + * Active dedicated bearer was requested for an existing default bearer. + */ + ESM_NW_ACTIVATED_DED_BEARER_WITH_ID_OF_DEF_BEARER = 0x849, + /** + * Bad OTA message is received from the network. + */ + ESM_BAD_OTA_MESSAGE = 0x84A, + /** + * Download server rejected the call. + */ + ESM_DOWNLOAD_SERVER_REJECTED_THE_CALL = 0x84B, + /** + * PDN was disconnected by the downlaod server due to IRAT. + */ + ESM_CONTEXT_TRANSFERRED_DUE_TO_IRAT = 0x84C, + /** + * Dedicated bearer will be deactivated regardless of the network response. + */ + DS_EXPLICIT_DEACTIVATION = 0x84D, + /** + * No specific local cause is mentioned, usually a valid OTA cause. + */ + ESM_LOCAL_CAUSE_NONE = 0x84E, + /** + * Throttling is not needed for this service request failure. + */ + LTE_THROTTLING_NOT_REQUIRED = 0x84F, + /** + * Access control list check failure at the lower layer. + */ + ACCESS_CONTROL_LIST_CHECK_FAILURE = 0x850, + /** + * Service is not allowed on the requested PLMN. + */ + SERVICE_NOT_ALLOWED_ON_PLMN = 0x851, + /** + * T3417 timer expiration of the service request procedure. + */ + EMM_T3417_EXPIRED = 0x852, + /** + * Extended service request fails due to expiration of the T3417 EXT timer. + */ + EMM_T3417_EXT_EXPIRED = 0x853, + /** + * Transmission failure of radio resource control (RRC) uplink data. + */ + RRC_UPLINK_DATA_TRANSMISSION_FAILURE = 0x854, + /** + * Radio resource control (RRC) uplink data delivery failed due to a handover. + */ + RRC_UPLINK_DELIVERY_FAILED_DUE_TO_HANDOVER = 0x855, + /** + * Radio resource control (RRC) uplink data delivery failed due to a connection release. + */ + RRC_UPLINK_CONNECTION_RELEASE = 0x856, + /** + * Radio resource control (RRC) uplink data delivery failed due to a radio link failure. + */ + RRC_UPLINK_RADIO_LINK_FAILURE = 0x857, + /** + * Radio resource control (RRC) is not connected but the non-access stratum (NAS) sends an + * uplink data request. + */ + RRC_UPLINK_ERROR_REQUEST_FROM_NAS = 0x858, + /** + * Radio resource control (RRC) connection failure at access stratum. + */ + RRC_CONNECTION_ACCESS_STRATUM_FAILURE = 0x859, + /** + * Radio resource control (RRC) connection establishment is aborted due to another procedure. + */ + RRC_CONNECTION_ANOTHER_PROCEDURE_IN_PROGRESS = 0x85A, + /** + * Radio resource control (RRC) connection establishment failed due to access barrred. + */ + RRC_CONNECTION_ACCESS_BARRED = 0x85B, + /** + * Radio resource control (RRC) connection establishment failed due to cell reselection at + * access stratum. + */ + RRC_CONNECTION_CELL_RESELECTION = 0x85C, + /** + * Connection establishment failed due to configuration failure at the radio resource control + * (RRC). + */ + RRC_CONNECTION_CONFIG_FAILURE = 0x85D, + /** + * Radio resource control (RRC) connection could not be established in the time limit. + */ + RRC_CONNECTION_TIMER_EXPIRED = 0x85E, + /** + * Connection establishment failed due to a link failure at the radio resource control (RRC). + */ + RRC_CONNECTION_LINK_FAILURE = 0x85F, + /** + * Connection establishment failed as the radio resource control (RRC) is not camped on any + * cell. + */ + RRC_CONNECTION_CELL_NOT_CAMPED = 0x860, + /** + * Connection establishment failed due to a service interval failure at the radio resource + * control (RRC). + */ + RRC_CONNECTION_SYSTEM_INTERVAL_FAILURE = 0x861, + /** + * Radio resource control (RRC) connection establishment failed due to the network rejecting the + * UE connection request. + */ + RRC_CONNECTION_REJECT_BY_NETWORK = 0x862, + /** + * Normal radio resource control (RRC) connection release. + */ + RRC_CONNECTION_NORMAL_RELEASE = 0x863, + /** + * Radio resource control (RRC) connection release failed due to radio link failure conditions. + */ + RRC_CONNECTION_RADIO_LINK_FAILURE = 0x864, + /** + * Radio resource control (RRC) connection re-establishment failure. + */ + RRC_CONNECTION_REESTABLISHMENT_FAILURE = 0x865, + /** + * UE is out of service during the call register. + */ + RRC_CONNECTION_OUT_OF_SERVICE_DURING_CELL_REGISTER = 0x866, + /** + * Connection has been released by the radio resource control (RRC) due to an abort request. + */ + RRC_CONNECTION_ABORT_REQUEST = 0x867, + /** + * Radio resource control (RRC) connection released due to a system information block read + * error. + */ + RRC_CONNECTION_SYSTEM_INFORMATION_BLOCK_READ_ERROR = 0x868, + /** + * Network-initiated detach with reattach. + */ + NETWORK_INITIATED_DETACH_WITH_AUTO_REATTACH = 0x869, + /** + * Network-initiated detach without reattach. + */ + NETWORK_INITIATED_DETACH_NO_AUTO_REATTACH = 0x86A, + /** + * ESM procedure maximum attempt timeout failure. + */ + ESM_PROCEDURE_TIME_OUT = 0x86B, + /** + * No PDP exists with the given connection ID while modifying or deactivating or activation for + * an already active PDP. + */ + INVALID_CONNECTION_ID = 0x86C, + /** + * Maximum NSAPIs have been exceeded during PDP activation. + */ + MAXIMIUM_NSAPIS_EXCEEDED = 0x86D, + /** + * Primary context for NSAPI does not exist. + */ + INVALID_PRIMARY_NSAPI = 0x86E, + /** + * Unable to encode the OTA message for MT PDP or deactivate PDP. + */ + CANNOT_ENCODE_OTA_MESSAGE = 0x86F, + /** + * Radio access bearer is not established by the lower layers during activation, modification, + * or deactivation. + */ + RADIO_ACCESS_BEARER_SETUP_FAILURE = 0x870, + /** + * Expiration of the PDP establish timer with a maximum of five retries. + */ + PDP_ESTABLISH_TIMEOUT_EXPIRED = 0x871, + /** + * Expiration of the PDP modify timer with a maximum of four retries. + */ + PDP_MODIFY_TIMEOUT_EXPIRED = 0x872, + /** + * Expiration of the PDP deactivate timer with a maximum of four retries. + */ + PDP_INACTIVE_TIMEOUT_EXPIRED = 0x873, + /** + * PDP activation failed due to RRC_ABORT or a forbidden PLMN. + */ + PDP_LOWERLAYER_ERROR = 0x874, + /** + * MO PDP modify collision when the MT PDP is already in progress. + */ + PDP_MODIFY_COLLISION = 0x875, + /** + * Maximum size of the L2 message was exceeded. + */ + MAXINUM_SIZE_OF_L2_MESSAGE_EXCEEDED = 0x876, + /** + * Non-access stratum (NAS) request was rejected by the network. + */ + NAS_REQUEST_REJECTED_BY_NETWORK = 0x877, + /** + * Radio resource control (RRC) connection establishment failure due to an error in the request + * message. + */ + RRC_CONNECTION_INVALID_REQUEST = 0x878, + /** + * Radio resource control (RRC) connection establishment failure due to a change in the tracking + * area ID. + */ + RRC_CONNECTION_TRACKING_AREA_ID_CHANGED = 0x879, + /** + * Radio resource control (RRC) connection establishment failure due to the RF was unavailable. + */ + RRC_CONNECTION_RF_UNAVAILABLE = 0x87A, + /** + * Radio resource control (RRC) connection was aborted before deactivating the LTE stack due to + * a successful LTE to WCDMA/GSM/TD-SCDMA IRAT change. + */ + RRC_CONNECTION_ABORTED_DUE_TO_IRAT_CHANGE = 0x87B, + /** + * If the UE has an LTE radio link failure before security is established, the radio resource + * control (RRC) connection must be released and the UE must return to idle. + */ + RRC_CONNECTION_RELEASED_SECURITY_NOT_ACTIVE = 0x87C, + /** + * Radio resource control (RRC) connection was aborted by the non-access stratum (NAS) after an + * IRAT to LTE IRAT handover. + */ + RRC_CONNECTION_ABORTED_AFTER_HANDOVER = 0x87D, + /** + * Radio resource control (RRC) connection was aborted before deactivating the LTE stack after a + * successful LTE to GSM/EDGE IRAT cell change order procedure. + */ + RRC_CONNECTION_ABORTED_AFTER_IRAT_CELL_CHANGE = 0x87E, + /** + * Radio resource control (RRC) connection was aborted in the middle of a LTE to GSM IRAT cell + * change order procedure. + */ + RRC_CONNECTION_ABORTED_DURING_IRAT_CELL_CHANGE = 0x87F, + /** + * IMSI present in the UE is unknown in the home subscriber server. + */ + IMSI_UNKNOWN_IN_HOME_SUBSCRIBER_SERVER = 0x880, + /** + * IMEI of the UE is not accepted by the network. + */ + IMEI_NOT_ACCEPTED = 0x881, + /** + * EPS and non-EPS services are not allowed by the network. + */ + EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED = 0x882, + /** + * EPS services are not allowed in the PLMN. + */ + EPS_SERVICES_NOT_ALLOWED_IN_PLMN = 0x883, + /** + * Mobile switching center is temporarily unreachable. + */ + MSC_TEMPORARILY_NOT_REACHABLE = 0x884, + /** + * CS domain is not available. + */ + CS_DOMAIN_NOT_AVAILABLE = 0x885, + /** + * ESM level failure. + */ + ESM_FAILURE = 0x886, + /** + * MAC level failure. + */ + MAC_FAILURE = 0x887, + /** + * Synchronization failure. + */ + SYNCHRONIZATION_FAILURE = 0x888, + /** + * UE security capabilities mismatch. + */ + UE_SECURITY_CAPABILITIES_MISMATCH = 0x889, + /** + * Unspecified security mode reject. + */ + SECURITY_MODE_REJECTED = 0x88A, + /** + * Unacceptable non-EPS authentication. + */ + UNACCEPTABLE_NON_EPS_AUTHENTICATION = 0x88B, + /** + * CS fallback call establishment is not allowed. + */ + CS_FALLBACK_CALL_ESTABLISHMENT_NOT_ALLOWED = 0x88C, + /** + * No EPS bearer context was activated. + */ + NO_EPS_BEARER_CONTEXT_ACTIVATED = 0x88D, + /** + * Invalid EMM state. + */ + INVALID_EMM_STATE = 0x88E, + /** + * Non-Access Spectrum layer failure. + */ + NAS_LAYER_FAILURE = 0x88F, + /** + * Multiple PDP call feature is disabled. + */ + MULTIPLE_PDP_CALL_NOT_ALLOWED = 0x890, + /** + * Data call has been brought down because EMBMS is not enabled at the RRC layer. + */ + EMBMS_NOT_ENABLED = 0x891, + /** + * Data call was unsuccessfully transferred during the IRAT handover. + */ + IRAT_HANDOVER_FAILED = 0x892, + /** + * EMBMS data call has been successfully brought down. + */ + EMBMS_REGULAR_DEACTIVATION = 0x893, + /** + * Test loop-back data call has been successfully brought down. + */ + TEST_LOOPBACK_REGULAR_DEACTIVATION = 0x894, + /** + * Lower layer registration failure. + */ + LOWER_LAYER_REGISTRATION_FAILURE = 0x895, + /** + * Network initiates a detach on LTE with error cause "data plan has been replenished or has + * expired". + */ + DATA_PLAN_EXPIRED = 0x896, + /** + * UMTS interface is brought down due to handover from UMTS to iWLAN. + */ + UMTS_HANDOVER_TO_IWLAN = 0x897, + /** + * Received a connection deny due to general or network busy on EVDO network. + */ + EVDO_CONNECTION_DENY_BY_GENERAL_OR_NETWORK_BUSY = 0x898, + /** + * Received a connection deny due to billing or authentication failure on EVDO network. + */ + EVDO_CONNECTION_DENY_BY_BILLING_OR_AUTHENTICATION_FAILURE = 0x899, + /** + * HDR system has been changed due to redirection or the PRL was not preferred. + */ + EVDO_HDR_CHANGED = 0x89A, + /** + * Device exited HDR due to redirection or the PRL was not preferred. + */ + EVDO_HDR_EXITED = 0x89B, + /** + * Device does not have an HDR session. + */ + EVDO_HDR_NO_SESSION = 0x89C, + /** + * It is ending an HDR call origination in favor of a GPS fix. + */ + EVDO_USING_GPS_FIX_INSTEAD_OF_HDR_CALL = 0x89D, + /** + * Connection setup on the HDR system was time out. + */ + EVDO_HDR_CONNECTION_SETUP_TIMEOUT = 0x89E, + /** + * Device failed to acquire a co-located HDR for origination. + */ + FAILED_TO_ACQUIRE_COLOCATED_HDR = 0x89F, + /** + * OTASP commit is in progress. + */ + OTASP_COMMIT_IN_PROGRESS = 0x8A0, + /** + * Device has no hybrid HDR service. + */ + NO_HYBRID_HDR_SERVICE = 0x8A1, + /** + * HDR module could not be obtained because of the RF locked. + */ + HDR_NO_LOCK_GRANTED = 0x8A2, + /** + * DBM or SMS is in progress. + */ + DBM_OR_SMS_IN_PROGRESS = 0x8A3, + /** + * HDR module released the call due to fade. + */ + HDR_FADE = 0x8A4, + /** + * HDR system access failure. + */ + HDR_ACCESS_FAILURE = 0x8A5, + /** + * P_rev supported by 1 base station is less than 6, which is not supported for a 1X data call. + * The UE must be in the footprint of BS which has p_rev >= 6 to support this SO33 call. + */ + UNSUPPORTED_1X_PREV = 0x8A6, + /** + * Client ended the data call. + */ + LOCAL_END = 0x8A7, + /** + * Device has no service. + */ + NO_SERVICE = 0x8A8, + /** + * Device lost the system due to fade. + */ + FADE = 0x8A9, + /** + * Receiving a release from the base station with no reason. + */ + NORMAL_RELEASE = 0x8AA, + /** + * Access attempt is already in progress. + */ + ACCESS_ATTEMPT_ALREADY_IN_PROGRESS = 0x8AB, + /** + * Device is in the process of redirecting or handing off to a different target system. + */ + REDIRECTION_OR_HANDOFF_IN_PROGRESS = 0x8AC, + /** + * Device is operating in Emergency mode. + */ + EMERGENCY_MODE = 0x8AD, + /** + * Device is in use (e.g., voice call). + */ + PHONE_IN_USE = 0x8AE, + /** + * Device operational mode is different from the mode requested in the traffic channel bring up. + */ + INVALID_MODE = 0x8AF, + /** + * SIM was marked by the network as invalid for the circuit and/or packet service domain. + */ + INVALID_SIM_STATE = 0x8B0, + /** + * There is no co-located HDR. + */ + NO_COLLOCATED_HDR = 0x8B1, + /** + * UE is entering power save mode. + */ + UE_IS_ENTERING_POWERSAVE_MODE = 0x8B2, + /** + * Dual switch from single standby to dual standby is in progress. + */ + DUAL_SWITCH = 0x8B3, + /** + * Data call bring up fails in the PPP setup due to a timeout. (e.g., an LCP conf ack was not + * received from the network) + */ + PPP_TIMEOUT = 0x8B4, + /** + * Data call bring up fails in the PPP setup due to an authorization failure. + * (e.g., authorization is required, but not negotiated with the network during an LCP phase) + */ + PPP_AUTH_FAILURE = 0x8B5, + /** + * Data call bring up fails in the PPP setup due to an option mismatch. + */ + PPP_OPTION_MISMATCH = 0x8B6, + /** + * Data call bring up fails in the PPP setup due to a PAP failure. + */ + PPP_PAP_FAILURE = 0x8B7, + /** + * Data call bring up fails in the PPP setup due to a CHAP failure. + */ + PPP_CHAP_FAILURE = 0x8B8, + /** + * Data call bring up fails in the PPP setup because the PPP is in the process of cleaning the + * previous PPP session. + */ + PPP_CLOSE_IN_PROGRESS = 0x8B9, + /** + * IPv6 interface bring up fails because the network provided only the IPv4 address for the + * upcoming PDN permanent client can reattempt a IPv6 call bring up after the IPv4 interface is + * also brought down. However, there is no guarantee that the network will provide a IPv6 + * address. + */ + LIMITED_TO_IPV4 = 0x8BA, + /** + * IPv4 interface bring up fails because the network provided only the IPv6 address for the + * upcoming PDN permanent client can reattempt a IPv4 call bring up after the IPv6 interface is + * also brought down. However there is no guarantee that the network will provide a IPv4 + * address. + */ + LIMITED_TO_IPV6 = 0x8BB, + /** + * Data call bring up fails in the VSNCP phase due to a VSNCP timeout error. + */ + VSNCP_TIMEOUT = 0x8BC, + /** + * Data call bring up fails in the VSNCP phase due to a general error. It's used when there is + * no other specific error code available to report the failure. + */ + VSNCP_GEN_ERROR = 0x8BD, + /** + * Data call bring up fails in the VSNCP phase due to a network rejection of the VSNCP + * configuration request because the requested APN is unauthorized. + */ + VSNCP_APN_UNAUTHORIZED = 0x8BE, + /** + * Data call bring up fails in the VSNCP phase due to a network rejection of the VSNCP + * configuration request because the PDN limit has been exceeded. + */ + VSNCP_PDN_LIMIT_EXCEEDED = 0x8BF, + /** + * Data call bring up fails in the VSNCP phase due to the network rejected the VSNCP + * configuration request due to no PDN gateway address. + */ + VSNCP_NO_PDN_GATEWAY_ADDRESS = 0x8C0, + /** + * Data call bring up fails in the VSNCP phase due to a network rejection of the VSNCP + * configuration request because the PDN gateway is unreachable. + */ + VSNCP_PDN_GATEWAY_UNREACHABLE = 0x8C1, + /** + * Data call bring up fails in the VSNCP phase due to a network rejection of the VSNCP + * configuration request due to a PDN gateway reject. + */ + VSNCP_PDN_GATEWAY_REJECT = 0x8C2, + /** + * Data call bring up fails in the VSNCP phase due to a network rejection of the VSNCP + * configuration request with the reason of insufficient parameter. + */ + VSNCP_INSUFFICIENT_PARAMETERS = 0x8C3, + /** + * Data call bring up fails in the VSNCP phase due to a network rejection of the VSNCP + * configuration request with the reason of resource unavailable. + */ + VSNCP_RESOURCE_UNAVAILABLE = 0x8C4, + /** + * Data call bring up fails in the VSNCP phase due to a network rejection of the VSNCP + * configuration request with the reason of administratively prohibited at the HSGW. + */ + VSNCP_ADMINISTRATIVELY_PROHIBITED = 0x8C5, + /** + * Data call bring up fails in the VSNCP phase due to a network rejection of PDN ID in use, or + * all existing PDNs are brought down with this end reason because one of the PDN bring up was + * rejected by the network with the reason of PDN ID in use. + */ + VSNCP_PDN_ID_IN_USE = 0x8C6, + /** + * Data call bring up fails in the VSNCP phase due to a network rejection of the VSNCP + * configuration request for the reason of subscriber limitation. + */ + VSNCP_SUBSCRIBER_LIMITATION = 0x8C7, + /** + * Data call bring up fails in the VSNCP phase due to a network rejection of the VSNCP + * configuration request because the PDN exists for this APN. + */ + VSNCP_PDN_EXISTS_FOR_THIS_APN = 0x8C8, + /** + * Data call bring up fails in the VSNCP phase due to a network rejection of the VSNCP + * configuration request with reconnect to this PDN not allowed, or an active data call is + * terminated by the network because reconnection to this PDN is not allowed. Upon receiving + * this error code from the network, the modem infinitely throttles the PDN until the next power + * cycle. + */ + VSNCP_RECONNECT_NOT_ALLOWED = 0x8C9, + /** + * Device failure to obtain the prefix from the network. + */ + IPV6_PREFIX_UNAVAILABLE = 0x8CA, + /** + * System preference change back to SRAT during handoff + */ + HANDOFF_PREFERENCE_CHANGED = 0x8CB, + /** + * Data call fail due to the slice not being allowed for the data call. + */ + SLICE_REJECTED = 0x8CC, + /** + * No matching rule available for the request, and match-all rule is not allowed for it. + */ + MATCH_ALL_RULE_NOT_ALLOWED = 0x8CD, + /** + * If connection failed for all matching URSP rules. + */ + ALL_MATCHING_RULES_FAILED = 0x8CE, +} diff --git a/radio/aidl/android/hardware/radio/DataConnActiveStatus.aidl b/radio/aidl/android/hardware/radio/DataConnActiveStatus.aidl new file mode 100644 index 0000000000..1e837275d0 --- /dev/null +++ b/radio/aidl/android/hardware/radio/DataConnActiveStatus.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.radio; + +/** + * Data connection active status + */ +@VintfStability +@Backing(type="int") +enum DataConnActiveStatus { + /** + * Indicates the data connection is inactive. + */ + INACTIVE, + /** + * Indicates the data connection is active with physical link dormant. + */ + DORMANT, + /** + * Indicates the data connection is active with physical link up. + */ + ACTIVE, +} diff --git a/radio/aidl/android/hardware/radio/DataProfileId.aidl b/radio/aidl/android/hardware/radio/DataProfileId.aidl new file mode 100644 index 0000000000..f173f1f1e4 --- /dev/null +++ b/radio/aidl/android/hardware/radio/DataProfileId.aidl @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.radio; + +@VintfStability +@Backing(type="int") +enum DataProfileId { + DEFAULT = 0, + TETHERED = 1, + IMS = 2, + FOTA = 3, + CBS = 4, + /** + * Start of OEM-specific profiles + */ + OEM_BASE = 1000, + INVALID = 0xFFFFFFFF, +} diff --git a/radio/aidl/android/hardware/radio/DataProfileInfo.aidl b/radio/aidl/android/hardware/radio/DataProfileInfo.aidl new file mode 100644 index 0000000000..5e2d4d20b9 --- /dev/null +++ b/radio/aidl/android/hardware/radio/DataProfileInfo.aidl @@ -0,0 +1,103 @@ +/* + * 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.radio; + +import android.hardware.radio.ApnAuthType; +import android.hardware.radio.ApnTypes; +import android.hardware.radio.DataProfileId; +import android.hardware.radio.DataProfileInfoType; +import android.hardware.radio.PdpProtocolType; +import android.hardware.radio.RadioAccessFamily; + +@VintfStability +parcelable DataProfileInfo { + /** + * ID of the data profile. + */ + DataProfileId profileId; + /** + * The APN name. + */ + String apn; + /** + * PDP_type values. + */ + PdpProtocolType protocol; + /** + * PDP_type values used on roaming network. + */ + PdpProtocolType roamingProtocol; + /** + * APN authentication type. + */ + ApnAuthType authType; + /** + * The username for APN, or empty string. + */ + String user; + /** + * The password for APN, or empty string. + */ + String password; + /** + * Data profile technology type. + */ + DataProfileInfoType type; + /** + * The period in seconds to limit the maximum connections. + */ + int maxConnsTime; + /** + * The maximum connections during maxConnsTime. + */ + int maxConns; + /** + * The required wait time in seconds after a successful UE initiated disconnect of a given PDN + * connection before the device can send a new PDN connection request for that given PDN. + */ + int waitTime; + /** + * True to enable the profile, false to disable. + */ + boolean enabled; + /** + * Supported APN types bitmap. See ApnTypes for the value of each bit. + */ + ApnTypes supportedApnTypesBitmap; + /** + * The bearer bitmap. See RadioAccessFamily for the value of each bit. + */ + RadioAccessFamily bearerBitmap; + /** + * Maximum transmission unit (MTU) size in bytes for IPv4. + */ + int mtuV4; + /** + * Maximum transmission unit (MTU) size in bytes for IPv6. + */ + int mtuV6; + /** + * True if this data profile was used to bring up the last default (i.e internet) data + * connection successfully. + */ + boolean preferred; + /** + * If true, modem must persist this data profile and profileId must not be set to + * DataProfileId.INVALID. If the same data profile exists, this data profile must overwrite it. + */ + boolean persistent; +} diff --git a/radio/aidl/android/hardware/radio/DataProfileInfoType.aidl b/radio/aidl/android/hardware/radio/DataProfileInfoType.aidl new file mode 100644 index 0000000000..df46ef39fe --- /dev/null +++ b/radio/aidl/android/hardware/radio/DataProfileInfoType.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.radio; + +@VintfStability +@Backing(type="int") +enum DataProfileInfoType { + COMMON, + THREE_GPP, + THREE_GPP2, +} diff --git a/radio/aidl/android/hardware/radio/DataRegStateResult.aidl b/radio/aidl/android/hardware/radio/DataRegStateResult.aidl new file mode 100644 index 0000000000..53a3e52e85 --- /dev/null +++ b/radio/aidl/android/hardware/radio/DataRegStateResult.aidl @@ -0,0 +1,63 @@ +/* + * 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.radio; + +import android.hardware.radio.CellIdentity; +import android.hardware.radio.DataRegStateResultVopsInfo; +import android.hardware.radio.NrIndicators; +import android.hardware.radio.RegState; + +@VintfStability +parcelable DataRegStateResult { + /** + * Valid reg states are NOT_REG_MT_NOT_SEARCHING_OP, REG_HOME, NOT_REG_MT_SEARCHING_OP, + * REG_DENIED, UNKNOWN, REG_ROAMING defined in RegState + */ + RegState regState; + /** + * Indicates the available data radio technology, valid values as defined by RadioTechnology. + */ + int rat; + /** + * If registration state is 3 (Registration denied) this is an enumerated reason why + * registration was denied. See 3GPP TS 24.008, Annex G.6 "Additional cause codes for GMM". + * 7 == GPRS services not allowed + * 8 == GPRS services and non-GPRS services not allowed + * 9 == MS identity cannot be derived by the network + * 10 == Implicitly detached + * 14 == GPRS services not allowed in this PLMN + * 16 == MSC temporarily not reachable + * 40 == No PDP context activated + */ + int reasonDataDenied; + /** + * The maximum number of simultaneous Data Calls must be established using setupDataCall(). + */ + int maxDataCalls; + CellIdentity cellIdentity; + /** + * Network capabilities for voice over PS services. This info is valid only on LTE network and + * must be present when device is camped on LTE. vopsInfo must be empty when device is camped + * only on 2G/3G. + */ + DataRegStateResultVopsInfo vopsInfo; + /** + * The parameters of NR 5G Non-Standalone. This value is only valid on E-UTRAN, otherwise + * must be empty. + */ + NrIndicators nrIndicators; +} diff --git a/radio/aidl/android/hardware/radio/DataRegStateResultVopsInfo.aidl b/radio/aidl/android/hardware/radio/DataRegStateResultVopsInfo.aidl new file mode 100644 index 0000000000..885d5b2395 --- /dev/null +++ b/radio/aidl/android/hardware/radio/DataRegStateResultVopsInfo.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.radio; + +import android.hardware.radio.LteVopsInfo; + +@VintfStability +union DataRegStateResultVopsInfo { + boolean noinit; + /** + * LTE network capability + */ + LteVopsInfo lteVopsInfo; +} diff --git a/radio/aidl/android/hardware/radio/DataRequestReason.aidl b/radio/aidl/android/hardware/radio/DataRequestReason.aidl new file mode 100644 index 0000000000..74afdcb328 --- /dev/null +++ b/radio/aidl/android/hardware/radio/DataRequestReason.aidl @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.radio; + +@VintfStability +@Backing(type="int") +enum DataRequestReason { + /** + * The reason of the data request is normal + */ + NORMAL = 1, + /** + * The reason of the data request is device shutdown + */ + SHUTDOWN = 2, + /** + * The reason of the data request is IWLAN data handover to another transport + * (e.g. from cellular to wifi or vise versa) + */ + HANDOVER = 3, +} diff --git a/radio/aidl/android/hardware/radio/DataThrottlingAction.aidl b/radio/aidl/android/hardware/radio/DataThrottlingAction.aidl new file mode 100644 index 0000000000..1a49762374 --- /dev/null +++ b/radio/aidl/android/hardware/radio/DataThrottlingAction.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. + */ + +package android.hardware.radio; + +@VintfStability +@Backing(type="byte") +enum DataThrottlingAction { + /* + * Clear all existing data throttling. + */ + NO_DATA_THROTTLING, + /** + * Enact secondary carrier data throttling and remove any existing data throttling on + * anchor carrier. + */ + THROTTLE_SECONDARY_CARRIER, + /** + * Enact anchor carrier data throttling and disable data on secondary carrier if currently + * enabled. + */ + THROTTLE_ANCHOR_CARRIER, + /** + * Immediately hold on to current level of throttling. + */ + HOLD, +} diff --git a/radio/aidl/android/hardware/radio/DeviceStateType.aidl b/radio/aidl/android/hardware/radio/DeviceStateType.aidl new file mode 100644 index 0000000000..e622486293 --- /dev/null +++ b/radio/aidl/android/hardware/radio/DeviceStateType.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.radio; + +@VintfStability +@Backing(type="int") +enum DeviceStateType { + /** + * Device power save mode (provided by PowerManager). True indicates the device is in + * power save mode. + */ + POWER_SAVE_MODE, + /** + * Device charging state (provided by BatteryManager). True indicates the device is charging. + */ + CHARGING_STATE, + /** + * Low data expected mode. True indicates low data traffic is expected, for example, when the + * device is idle (e.g. not doing tethering in the background). Note this doesn't mean no data + * is expected. + */ + LOW_DATA_EXPECTED, +} diff --git a/radio/aidl/android/hardware/radio/Dial.aidl b/radio/aidl/android/hardware/radio/Dial.aidl new file mode 100644 index 0000000000..90568158ed --- /dev/null +++ b/radio/aidl/android/hardware/radio/Dial.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.radio; + +import android.hardware.radio.Clir; +import android.hardware.radio.UusInfo; + +@VintfStability +parcelable Dial { + String address; + Clir clir; + /** + * Vector of User-User Signaling Information + */ + UusInfo[] uusInfo; +} diff --git a/radio/aidl/android/hardware/radio/Domain.aidl b/radio/aidl/android/hardware/radio/Domain.aidl new file mode 100644 index 0000000000..f5e5261310 --- /dev/null +++ b/radio/aidl/android/hardware/radio/Domain.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.radio; + +@VintfStability +@Backing(type="int") +enum Domain { + /** + * Circuit-switched + */ + CS = 1 << 0, + /** + * Packet-switched + */ + PS = 1 << 1, +} diff --git a/radio/aidl/android/hardware/radio/EmcIndicator.aidl b/radio/aidl/android/hardware/radio/EmcIndicator.aidl new file mode 100644 index 0000000000..6f0b19fdba --- /dev/null +++ b/radio/aidl/android/hardware/radio/EmcIndicator.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.radio; + +/** + * Defines the values for emergency service indicator of NR as per 3gpp spec 24.501 sec 9.10.3.5 + */ +@VintfStability +@Backing(type="byte") +enum EmcIndicator { + /** + * Emergency services not supported + */ + EMC_NOT_SUPPORTED, + /** + * Emergency services supported in NR connected to 5GCN only + */ + EMC_NR_CONNECTED_TO_5GCN, + /** + * Emergency services supported in E-UTRA connected to 5GCN only + */ + EMC_EUTRA_CONNECTED_TO_5GCN, + /** + * Emergency services supported in NR connected to 5GCN and E-UTRA connected to 5GCN + */ + EMC_BOTH_NR_EUTRA_CONNECTED_TO_5GCN, +} diff --git a/radio/aidl/android/hardware/radio/EmergencyCallRouting.aidl b/radio/aidl/android/hardware/radio/EmergencyCallRouting.aidl new file mode 100644 index 0000000000..a915ee69ce --- /dev/null +++ b/radio/aidl/android/hardware/radio/EmergencyCallRouting.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.radio; + +/** + * Indicates how the implementation should handle the emergency call if it is required by Android. + */ +@VintfStability +@Backing(type="int") +enum EmergencyCallRouting { + /** + * Indicates Android does not require how to handle the corresponding emergency call; it is + * decided by implementation. + */ + UNKNOWN, + /** + * Indicates the implementation must handle the call through emergency routing. + */ + EMERGENCY, + /** + * Indicates the implementation must handle the call through normal call routing. + */ + NORMAL, +} diff --git a/radio/aidl/android/hardware/radio/EmergencyNumber.aidl b/radio/aidl/android/hardware/radio/EmergencyNumber.aidl new file mode 100644 index 0000000000..ee425f87a1 --- /dev/null +++ b/radio/aidl/android/hardware/radio/EmergencyNumber.aidl @@ -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. + */ + +package android.hardware.radio; + +import android.hardware.radio.EmergencyNumberSource; +import android.hardware.radio.EmergencyServiceCategory; + +/** + * Emergency number contains information of number, one or more service category(s), zero or more + * emergency uniform resource names, mobile country code (mcc), mobile network country (mnc) and + * source(s) that indicate where it comes from. + * + * If the emergency number is associated with country, field ‘mcc’ must be provided, otherwise + * field ‘mcc’ must be an empty string. If the emergency number is associated with network operator, + * field ‘mcc’ and 'mnc' must be provided, otherwise field ‘mnc’ must be an empty string. If the + * emergency number is specified with emergency service category(s), field 'categories' must be + * provided, otherwise field 'categories' must be EmergencyServiceCategories::UNSPECIFIED. If the + * emergency number is specified with emergency uniform resource names (URN), field 'urns' must be + * provided, otherwise field 'urns' must be an empty list. + * + * A unique EmergencyNumber has a unique combination of ‘number’, ‘mcc’, 'mnc', 'categories' and + * 'urns' fields. Multiple EmergencyNumberSource should be merged into one 'sources' field via + * bitwise-OR combination for the same EmergencyNumber. + * + * Reference: 3gpp 22.101, Section 10 - Emergency Calls; + * 3gpp 23.167, Section 6 - Functional description; + * 3gpp 24.503, Section 5.1.6.8.1 - General; + * RFC 5031 + */ +@VintfStability +parcelable EmergencyNumber { + /** + * The emergency number. The character in the number string should only be the dial pad + * character('0'-'9', '*', or '#'). For example: 911. + */ + String number; + /** + * 3-digit Mobile Country Code, 0..999. Empty string if not applicable. + */ + String mcc; + /** + * 2 or 3-digit Mobile Network Code, 0..999. Empty string if not applicable. + */ + String mnc; + /** + * The bitfield of EmergencyServiceCategory(s). See EmergencyServiceCategory for the value of + * each bit. + */ + EmergencyServiceCategory categories; + /** + * The list of emergency Uniform Resource Names (URN). + */ + String[] urns; + /** + * The bitfield of EmergencyNumberSource(s). See EmergencyNumberSource for the value of + * each bit. + */ + EmergencyNumberSource sources; +} diff --git a/radio/aidl/android/hardware/radio/EmergencyNumberSource.aidl b/radio/aidl/android/hardware/radio/EmergencyNumberSource.aidl new file mode 100644 index 0000000000..c2d6547d64 --- /dev/null +++ b/radio/aidl/android/hardware/radio/EmergencyNumberSource.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. + */ + +package android.hardware.radio; + +/** + * The source to tell where the corresponding EmergencyNumber comes from. + * Reference: 3gpp 22.101, Section 10 - Emergency Calls + */ +@VintfStability +@Backing(type="int") +enum EmergencyNumberSource { + /** + * Indicates the number is from the network signal. + */ + NETWORK_SIGNALING = 1 << 0, + /** + * Indicates the number is from the sim card. + */ + SIM = 1 << 1, + /** + * Indicates the number is from the modem config. + */ + MODEM_CONFIG = 1 << 2, + /** + * Indicates the number is available as default. Per the reference, 112, 911 must always be + * available; additionally, 000, 08, 110, 999, 118 and 119 must be available when sim is not + * present. + */ + DEFAULT = 1 << 3, +} diff --git a/radio/aidl/android/hardware/radio/EmergencyServiceCategory.aidl b/radio/aidl/android/hardware/radio/EmergencyServiceCategory.aidl new file mode 100644 index 0000000000..30d34ab210 --- /dev/null +++ b/radio/aidl/android/hardware/radio/EmergencyServiceCategory.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.radio; + +/** + * Defining Emergency Service Category as follows: + * - General emergency call, all categories; + * - Police; + * - Ambulance; + * - Fire Brigade; + * - Marine Guard; + * - Mountain Rescue; + * - Manually Initiated eCall (MIeC); + * - Automatically Initiated eCall (AIeC); + * + * Category UNSPECIFIED (General emergency call, all categories) indicates that no specific + * services are associated with this emergency number. + * + * Reference: 3gpp 22.101, Section 10 - Emergency Calls + */ +@VintfStability +@Backing(type="int") +enum EmergencyServiceCategory { + /** + * General emergency call, all categories + */ + UNSPECIFIED = 0, + POLICE = 1 << 0, + AMBULANCE = 1 << 1, + FIRE_BRIGADE = 1 << 2, + MARINE_GUARD = 1 << 3, + MOUNTAIN_RESCUE = 1 << 4, + /** + * Manually Initiated eCall (MIeC) + */ + MIEC = 1 << 5, + /** + * Automatically Initiated eCall (AIeC) + */ + AIEC = 1 << 6, +} diff --git a/radio/aidl/android/hardware/radio/EmfIndicator.aidl b/radio/aidl/android/hardware/radio/EmfIndicator.aidl new file mode 100644 index 0000000000..226e6844fc --- /dev/null +++ b/radio/aidl/android/hardware/radio/EmfIndicator.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.radio; + +/** + * Defines the values for emergency service fallback indicator of NR as per TS 24.501 sec 9.10.3.5. + */ +@VintfStability +@Backing(type="byte") +enum EmfIndicator { + /** + * Emergency services fallback not supported + */ + EMF_NOT_SUPPORTED, + /** + * Emergency services fallback supported in NR connected to 5GCN only + */ + EMF_NR_CONNECTED_TO_5GCN, + /** + * Emergency services fallback supported in E-UTRA connected to 5GCN only + */ + EMF_EUTRA_CONNECTED_TO_5GCN, + /** + * Emergency services fallback supported in NR connected to 5GCN and E-UTRA connected to 5GCN. + */ + EMF_BOTH_NR_EUTRA_CONNECTED_TO_5GCN, +} diff --git a/radio/aidl/android/hardware/radio/EpsQos.aidl b/radio/aidl/android/hardware/radio/EpsQos.aidl new file mode 100644 index 0000000000..ee4cbdd6c2 --- /dev/null +++ b/radio/aidl/android/hardware/radio/EpsQos.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.radio; + +import android.hardware.radio.QosBandwidth; + +/** + * LTE/EPS Quality of Service parameters as per 3gpp spec 24.301 sec 9.9.4.3. + */ +@VintfStability +parcelable EpsQos { + /** + * Quality of Service Class Identifier (QCI), see 3GPP TS 23.203 and 29.212. + * The allowed values are standard values(1-9, 65-68, 69-70, 75, 79-80, 82-85) + * defined in the spec and operator specific values in the range 128-254. + */ + int qci; + QosBandwidth downlink; + QosBandwidth uplink; +} diff --git a/radio/aidl/android/hardware/radio/EutranBands.aidl b/radio/aidl/android/hardware/radio/EutranBands.aidl new file mode 100644 index 0000000000..59fe6c4036 --- /dev/null +++ b/radio/aidl/android/hardware/radio/EutranBands.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.radio; + +/** + * EUTRAN bands up to V16.4.0 + */ +@VintfStability +@Backing(type="int") +enum EutranBands { + BAND_1 = 1, + BAND_2 = 2, + BAND_3 = 3, + BAND_4 = 4, + BAND_5 = 5, + BAND_6 = 6, + BAND_7 = 7, + BAND_8 = 8, + BAND_9 = 9, + BAND_10 = 10, + BAND_11 = 11, + BAND_12 = 12, + BAND_13 = 13, + BAND_14 = 14, + BAND_17 = 17, + BAND_18 = 18, + BAND_19 = 19, + BAND_20 = 20, + BAND_21 = 21, + BAND_22 = 22, + BAND_23 = 23, + BAND_24 = 24, + BAND_25 = 25, + BAND_26 = 26, + BAND_27 = 27, + BAND_28 = 28, + BAND_30 = 30, + BAND_31 = 31, + BAND_33 = 33, + BAND_34 = 34, + BAND_35 = 35, + BAND_36 = 36, + BAND_37 = 37, + BAND_38 = 38, + BAND_39 = 39, + BAND_40 = 40, + BAND_41 = 41, + BAND_42 = 42, + BAND_43 = 43, + BAND_44 = 44, + BAND_45 = 45, + BAND_46 = 46, + BAND_47 = 47, + BAND_48 = 48, + BAND_65 = 65, + BAND_66 = 66, + BAND_68 = 68, + BAND_70 = 70, + BAND_49 = 49, + BAND_50 = 50, + BAND_51 = 51, + BAND_52 = 52, + BAND_53 = 53, + BAND_71 = 71, + BAND_72 = 72, + BAND_73 = 73, + BAND_74 = 74, + BAND_85 = 85, + BAND_87 = 87, + BAND_88 = 88, +} diff --git a/radio/aidl/android/hardware/radio/EvdoSignalStrength.aidl b/radio/aidl/android/hardware/radio/EvdoSignalStrength.aidl new file mode 100644 index 0000000000..ff631f311b --- /dev/null +++ b/radio/aidl/android/hardware/radio/EvdoSignalStrength.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.radio; + +@VintfStability +parcelable EvdoSignalStrength { + /** + * This value is the actual RSSI value multiplied by -1. Example: If the actual RSSI is -75, + * then this response value will be 75; INT_MAX means invalid/unreported. + */ + int dbm; + /** + * This value is the actual Ec/Io multiplied by -10. Example: If the actual Ec/Io is -12.5 dB, + * then this response value will be 125; INT_MAX means invalid/unreported. + */ + int ecio; + /** + * Valid values are 0-8. 8 is the highest signal to noise ratio; INT_MAX means + * invalid/unreported. + */ + int signalNoiseRatio; +} diff --git a/radio/aidl/android/hardware/radio/FrequencyRange.aidl b/radio/aidl/android/hardware/radio/FrequencyRange.aidl new file mode 100644 index 0000000000..09ec3bc1a7 --- /dev/null +++ b/radio/aidl/android/hardware/radio/FrequencyRange.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.radio; + +/** + * Mapping the frequency to a rough range. + */ +@VintfStability +@Backing(type="int") +enum FrequencyRange { + /** + * Indicates the frequency range is below 1GHz. + */ + LOW = 1, + /** + * Indicates the frequency range is between 1GHz and 3GHz. + */ + MID = 2, + /** + * Indicates the frequency range is between 3GHz and 6GHz. + */ + HIGH = 3, + /** + * Indicates the frequency range is above 6GHz (millimeter wave frequency). + */ + MMWAVE = 4, +} diff --git a/radio/aidl/android/hardware/radio/GeranBands.aidl b/radio/aidl/android/hardware/radio/GeranBands.aidl new file mode 100644 index 0000000000..d3a7598570 --- /dev/null +++ b/radio/aidl/android/hardware/radio/GeranBands.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.radio; + +@VintfStability +@Backing(type="int") +enum GeranBands { + BAND_T380 = 1, + BAND_T410 = 2, + BAND_450 = 3, + BAND_480 = 4, + BAND_710 = 5, + BAND_750 = 6, + BAND_T810 = 7, + BAND_850 = 8, + BAND_P900 = 9, + BAND_E900 = 10, + BAND_R900 = 11, + BAND_DCS1800 = 12, + BAND_PCS1900 = 13, + BAND_ER900 = 14, +} diff --git a/radio/aidl/android/hardware/radio/GsmBroadcastSmsConfigInfo.aidl b/radio/aidl/android/hardware/radio/GsmBroadcastSmsConfigInfo.aidl new file mode 100644 index 0000000000..9b08ad9b6a --- /dev/null +++ b/radio/aidl/android/hardware/radio/GsmBroadcastSmsConfigInfo.aidl @@ -0,0 +1,53 @@ +/* + * 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.radio; + +/** + * Which types of Cell Broadcast Message (CBM) are to be received by the ME + */ +@VintfStability +parcelable GsmBroadcastSmsConfigInfo { + /** + * Beginning of the range of CBM message identifiers whose value is 0x0000 - 0xFFFF as defined + * in TS 23.041 9.4.1.2.2 for GMS and 9.4.4.2.2 for UMTS. + * All other values must be treated as empty CBM message ID. + */ + int fromServiceId; + /** + * End of the range of CBM message identifiers whose value is 0x0000 - 0xFFFF as defined in + * TS 23.041 9.4.1.2.2 for GMS and 9.4.4.2.2 for UMTS. + * All other values must be treated as empty CBM message ID. + */ + int toServiceId; + /** + * Beginning of the range of CBM data coding schemes whose value is 0x00 - 0xFF as defined in + * TS 23.041 9.4.1.2.3 for GMS and 9.4.4.2.3 for UMTS. + * All other values must be treated as empty CBM data coding scheme. + */ + int fromCodeScheme; + /** + * End of the range of CBM data coding schemes whose value is 0x00 - 0xFF as defined in + * TS 23.041 9.4.1.2.3 for GMS and 9.4.4.2.3 for UMTS. + * All other values must be treated as empty CBM data coding scheme. + */ + int toCodeScheme; + /** + * False means message types specified in + * and are not accepted, while true means accepted. + */ + boolean selected; +} diff --git a/radio/aidl/android/hardware/radio/GsmSignalStrength.aidl b/radio/aidl/android/hardware/radio/GsmSignalStrength.aidl new file mode 100644 index 0000000000..65f853a1f7 --- /dev/null +++ b/radio/aidl/android/hardware/radio/GsmSignalStrength.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.radio; + +@VintfStability +parcelable GsmSignalStrength { + /** + * Valid values are (0-61, 99) as defined in TS 27.007 8.69; INT_MAX means invalid/unreported. + */ + int signalStrength; + /** + * Bit error rate (0-7, 99) as defined in TS 27.007 8.5; INT_MAX means invalid/unreported. + */ + int bitErrorRate; + /** + * Timing advance in bit periods. 1 bit period = 48/13 us. INT_MAX means invalid/unreported. + */ + int timingAdvance; +} diff --git a/radio/aidl/android/hardware/radio/GsmSmsMessage.aidl b/radio/aidl/android/hardware/radio/GsmSmsMessage.aidl new file mode 100644 index 0000000000..248b4be6a4 --- /dev/null +++ b/radio/aidl/android/hardware/radio/GsmSmsMessage.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.radio; + +@VintfStability +parcelable GsmSmsMessage { + /** + * SMSC address in GSM BCD format prefixed by a length byte (as expected by TS 27.005) + * or empty string for default SMSC + */ + String smscPdu; + /** + * SMS in PDU format as an ASCII hex string less the SMSC address. + * TP-Layer-Length is be "strlen(pdu)/2 + */ + String pdu; +} diff --git a/radio/aidl/android/hardware/radio/HandoverFailureMode.aidl b/radio/aidl/android/hardware/radio/HandoverFailureMode.aidl new file mode 100644 index 0000000000..f6918a8bd6 --- /dev/null +++ b/radio/aidl/android/hardware/radio/HandoverFailureMode.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. + */ + +package android.hardware.radio; + +/** + * The allowed failure modes on an IWLAN handover failure. + */ +@VintfStability +@Backing(type="byte") +enum HandoverFailureMode { + /** + * On data handover failure, fallback to the source data transport when the fail cause is due + * to a hand off preference change. + */ + LEGACY, + /** + * On data handover failure, fallback to the source data transport. + */ + DO_FALLBACK, + /** + * On data handover failure, retry the handover instead of falling back to the source data + * transport. + */ + NO_FALLBACK_RETRY_HANDOVER, + /** + * On data handover failure, setup a new data connection by sending a normal request to the + * underlying data service. + */ + NO_FALLBACK_RETRY_SETUP_NORMAL, +} diff --git a/radio/aidl/android/hardware/radio/HardwareConfig.aidl b/radio/aidl/android/hardware/radio/HardwareConfig.aidl new file mode 100644 index 0000000000..d3902afcce --- /dev/null +++ b/radio/aidl/android/hardware/radio/HardwareConfig.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. + */ + +package android.hardware.radio; + +import android.hardware.radio.HardwareConfigModem; +import android.hardware.radio.HardwareConfigSim; +import android.hardware.radio.HardwareConfigState; +import android.hardware.radio.HardwareConfigType; + +@VintfStability +parcelable HardwareConfig { + HardwareConfigType type; + /** + * RadioConst:MAX_UUID_LENGTH is max length of the string + */ + String uuid; + HardwareConfigState state; + /** + * Valid only if type is Modem and size = 1 else must be empty. Only one of modem or sim must + * have size = 1 based on the HardwareConfigType, and the other must have size = 0. + */ + HardwareConfigModem[] modem; + /** + * Valid only if type is SIM and size = 1 else must be empty. Only one of modem or sim must + * have size = 1 based on the HardwareConfigType, and the other must have size = 0. + */ + HardwareConfigSim[] sim; +} diff --git a/radio/aidl/android/hardware/radio/HardwareConfigModem.aidl b/radio/aidl/android/hardware/radio/HardwareConfigModem.aidl new file mode 100644 index 0000000000..ef348d6699 --- /dev/null +++ b/radio/aidl/android/hardware/radio/HardwareConfigModem.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.radio; + +@VintfStability +parcelable HardwareConfigModem { + int rilModel; + /** + * bitset - ref. RadioTechnology. + */ + int rat; + int maxVoice; + int maxData; + int maxStandby; +} diff --git a/radio/aidl/android/hardware/radio/HardwareConfigSim.aidl b/radio/aidl/android/hardware/radio/HardwareConfigSim.aidl new file mode 100644 index 0000000000..85055de7c4 --- /dev/null +++ b/radio/aidl/android/hardware/radio/HardwareConfigSim.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.radio; + +@VintfStability +parcelable HardwareConfigSim { + /** + * RadioConst:MAX_UUID_LENGTH is max length of the string + */ + String modemUuid; +} diff --git a/radio/aidl/android/hardware/radio/HardwareConfigState.aidl b/radio/aidl/android/hardware/radio/HardwareConfigState.aidl new file mode 100644 index 0000000000..05c806d52a --- /dev/null +++ b/radio/aidl/android/hardware/radio/HardwareConfigState.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.radio; + +@VintfStability +@Backing(type="int") +enum HardwareConfigState { + ENABLED, + STANDBY, + DISABLED, +} diff --git a/radio/aidl/android/hardware/radio/HardwareConfigType.aidl b/radio/aidl/android/hardware/radio/HardwareConfigType.aidl new file mode 100644 index 0000000000..5605c2b802 --- /dev/null +++ b/radio/aidl/android/hardware/radio/HardwareConfigType.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.radio; + +@VintfStability +@Backing(type="int") +enum HardwareConfigType { + MODEM, + SIM, +} diff --git a/radio/aidl/android/hardware/radio/IRadio.aidl b/radio/aidl/android/hardware/radio/IRadio.aidl new file mode 100644 index 0000000000..352cbfbaa8 --- /dev/null +++ b/radio/aidl/android/hardware/radio/IRadio.aidl @@ -0,0 +1,2073 @@ +/* + * 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.radio; + +import android.hardware.radio.AccessNetwork; +import android.hardware.radio.CallForwardInfo; +import android.hardware.radio.CardPowerState; +import android.hardware.radio.CarrierRestrictions; +import android.hardware.radio.CarrierRestrictionsWithPriority; +import android.hardware.radio.CdmaBroadcastSmsConfigInfo; +import android.hardware.radio.CdmaRoamingType; +import android.hardware.radio.CdmaSmsAck; +import android.hardware.radio.CdmaSmsMessage; +import android.hardware.radio.CdmaSmsWriteArgs; +import android.hardware.radio.CdmaSubscriptionSource; +import android.hardware.radio.DataProfileInfo; +import android.hardware.radio.DataRequestReason; +import android.hardware.radio.DataThrottlingAction; +import android.hardware.radio.DeviceStateType; +import android.hardware.radio.Dial; +import android.hardware.radio.EmergencyCallRouting; +import android.hardware.radio.EmergencyServiceCategory; +import android.hardware.radio.GsmBroadcastSmsConfigInfo; +import android.hardware.radio.GsmSmsMessage; +import android.hardware.radio.IRadioIndication; +import android.hardware.radio.IRadioResponse; +import android.hardware.radio.IccIo; +import android.hardware.radio.ImsSmsMessage; +import android.hardware.radio.ImsiEncryptionInfo; +import android.hardware.radio.IndicationFilter; +import android.hardware.radio.KeepaliveRequest; +import android.hardware.radio.LinkAddress; +import android.hardware.radio.NetworkScanRequest; +import android.hardware.radio.NrDualConnectivityState; +import android.hardware.radio.NvItem; +import android.hardware.radio.NvWriteItem; +import android.hardware.radio.OptionalSliceInfo; +import android.hardware.radio.OptionalTrafficDescriptor; +import android.hardware.radio.PersoSubstate; +import android.hardware.radio.PhonebookRecordInfo; +import android.hardware.radio.PreferredNetworkType; +import android.hardware.radio.RadioAccessFamily; +import android.hardware.radio.RadioAccessNetworks; +import android.hardware.radio.RadioAccessSpecifier; +import android.hardware.radio.RadioBandMode; +import android.hardware.radio.RadioCapability; +import android.hardware.radio.RadioTechnology; +import android.hardware.radio.ResetNvType; +import android.hardware.radio.SelectUiccSub; +import android.hardware.radio.SignalThresholdInfo; +import android.hardware.radio.SimApdu; +import android.hardware.radio.SimLockMultiSimPolicy; +import android.hardware.radio.SmsAcknowledgeFailCause; +import android.hardware.radio.SmsWriteArgs; +import android.hardware.radio.TtyMode; + +/** + * This interface is used by telephony and telecom to talk to cellular radio. + * All the functions have minimum one parameter: + * serial: which corresponds to serial no. of request. Serial numbers must only be memorized for the + * duration of a method call. If clients provide colliding serials (including passing the same + * serial to different methods), multiple responses (one for each method call) must still be served. + * setResponseFunctions must work with IRadioResponse and IRadioIndication. + */ +@VintfStability +interface IRadio { + /** + * Answer incoming call. Must not be called for WAITING calls. + * switchWaitingOrHoldingAndActive() must be used in this case instead + * + * @param serial Serial number of request. + * + * Response function is IRadioResponse.acceptCallResponse() + */ + oneway void acceptCall(in int serial); + + /** + * Acknowledge successful or failed receipt of SMS previously indicated via unsol + * responseNewSms(), including acknowledgement TPDU to send as the RP-User-Data element of the + * RP-ACK or RP-ERROR PDU. + * + * @param serial Serial number of request. + * @param success true on successful receipt (send RP-ACK) + * false on failed receipt (send RP-ERROR) + * @param ackPdu acknowledgement TPDU in hexadecimal format + * + * Response callback is IRadioResponse.acknowledgeIncomingGsmSmsWithPduResponse() + */ + oneway void acknowledgeIncomingGsmSmsWithPdu( + in int serial, in boolean success, in String ackPdu); + + /** + * Acknowledge the success or failure in the receipt of SMS previously indicated + * via responseCdmaNewSms() + * + * @param serial Serial number of request. + * @param smsAck Cdma Sms ack to be sent described by CdmaSmsAck in types.hal + * + * Response callback is IRadioResponse.acknowledgeLastIncomingCdmaSmsResponse() + */ + oneway void acknowledgeLastIncomingCdmaSms(in int serial, in CdmaSmsAck smsAck); + + /** + * Acknowledge successful or failed receipt of SMS previously indicated via unsolResponseNewSms + * + * @param serial Serial number of request. + * @param success is true on successful receipt + * (basically, AT+CNMA=1 from TS 27.005 is 0 on failed receipt + * (basically, AT+CNMA=2 from TS 27.005) + * @param cause: if success is false, this contains the failure cause as defined + * in TS 23.040, 9.2.3.22. + * + * Response function is IRadioResponse.acknowledgeLastIncomingGsmSmsResponse() + */ + oneway void acknowledgeLastIncomingGsmSms( + in int serial, in boolean success, in SmsAcknowledgeFailCause cause); + + /** + * Reserves an unallocated pdu session id from the pool of ids. The allocated id is returned + * in the response. When the id is no longer needed, call releasePduSessionId to return it to + * the pool. + * + * Reference: 3GPP TS 24.007 section 11.2.3.1b + * + * @param serial Serial number of request. + * + * Response function is IRadioResponse.allocatePduSessionIdResponse() + */ + oneway void allocatePduSessionId(in int serial); + + /** + * Whether uiccApplications are enabled, or disabled. + * By default uiccApplications must be enabled, unless enableUiccApplications() with enable + * being false is called. + * + * @param serial Serial number of request. + * + * Response callback is IRadioResponse.areUiccApplicationsEnabledResponse() + */ + oneway void areUiccApplicationsEnabled(in int serial); + + /** + * Indicates that a handover was cancelled after a call to IRadio::startHandover. + * Since the handover was unsuccessful, the modem retains ownership over any of the resources + * being transferred and is still responsible for releasing them. + * + * @param serial Serial number of request. + * @param id callId The identifier of the data call which is provided in SetupDataCallResult + * + * Response function is IRadioResponse.cancelHandoverResponse() + */ + oneway void cancelHandover(in int serial, in int callId); + + /** + * Cancel the current USSD session if one exists. + * + * @param serial Serial number of request. + * + * Response function is IRadioResponse.cancelPendingUssdResponse() + */ + oneway void cancelPendingUssd(in int serial); + + /** + * Supplies old ICC PIN2 and new PIN2. + * + * @param serial Serial number of request. + * @param oldPin2 Old pin2 value + * @param newPin2 New pin2 value + * @param aid AID value, See ETSI 102.221 8.1 and 101.220 4, empty string if no value. + * + * Response function is IRadioResponse.changeIccPin2ForAppResponse() + */ + oneway void changeIccPin2ForApp( + in int serial, in String oldPin2, in String newPin2, in String aid); + + /** + * Supplies old ICC PIN and new PIN. + * + * @param serial Serial number of request. + * @param oldPin Old pin value + * @param newPin New pin value + * @param aid AID value, See ETSI 102.221 8.1 and 101.220 4, empty string if no value. + * + * Response function is IRadioResponse.changeIccPinForAppResponse() + */ + oneway void changeIccPinForApp( + in int serial, in String oldPin, in String newPin, in String aid); + + /** + * Conference holding and active (like AT+CHLD=3) + * + * @param serial Serial number of request. + * + * Response function is IRadioResponse.conferenceResponse() + */ + oneway void conference(in int serial); + + /** + * Deactivate packet data connection and remove from the data call list. An + * unsolDataCallListChanged() must be sent when data connection is deactivated. + * + * @param serial Serial number of request. + * @param cid Data call id. + * @param reason The request reason. Must be normal, handover, or shutdown. + * + * Response function is IRadioResponse.deactivateDataCallResponse() + */ + oneway void deactivateDataCall(in int serial, in int cid, in DataRequestReason reason); + + /** + * Deletes a CDMA SMS message from RUIM memory. + * + * @param serial Serial number of request. + * @param index record index of the message to delete + * + * Response callback is IRadioResponse.deleteSmsOnRuimResponse() + */ + oneway void deleteSmsOnRuim(in int serial, in int index); + + /** + * Deletes a SMS message from SIM memory. + * + * @param serial Serial number of request. + * @param index Record index of the message to delete. + * + * Response function is IRadioResponse.deleteSmsOnSimResponse() + */ + oneway void deleteSmsOnSim(in int serial, in int index); + + /** + * Initiate voice call. This method is never used for supplementary service codes. + * + * @param serial Serial number of request. + * @param dialInfo Dial struct + * + * Response function is IRadioResponse.dialResponse() + */ + oneway void dial(in int serial, in Dial dialInfo); + + /** + * Initiate emergency voice call, with zero or more emergency service category(s), zero or + * more emergency Uniform Resource Names (URN), and routing information for handling the call. + * Android uses this request to make its emergency call instead of using @1.0::IRadio.dial + * if the 'address' in the 'dialInfo' field is identified as an emergency number by Android. + * + * In multi-sim scenario, if the emergency number is from a specific subscription, this radio + * request can still be sent out on the other subscription as long as routing is set to + * @1.4::EmergencyNumberRouting#EMERGENCY. This radio request will not be sent on an inactive + * (PIN/PUK locked) subscription unless both subscriptions are PIN/PUK locked. In this case, + * the request will be sent on the primary subscription. + * + * Some countries or carriers require some emergency numbers that must be handled with normal + * call routing if possible or emergency routing. 1) if the 'routing' field is specified as + * @1.4::EmergencyNumberRouting#NORMAL, the implementation must try the full radio service to + * use normal call routing to handle the call; if service cannot support normal routing, the + * implementation must use emergency routing to handle the call. 2) if 'routing' is specified + * as @1.4::EmergencyNumberRouting#EMERGENCY, the implementation must use emergency routing to + * handle the call. 3) if 'routing' is specified as @1.4::EmergencyNumberRouting#UNKNOWN, + * Android does not know how to handle the call. + * + * If the dialed emergency number does not have a specified emergency service category, the + * 'categories' field is set to @1.4::EmergencyServiceCategory#UNSPECIFIED; if the dialed + * emergency number does not have specified emergency Uniform Resource Names, the 'urns' field + * is set to an empty list. If the underlying technology used to request emergency services + * does not support the emergency service category or emergency uniform resource names, the + * field 'categories' or 'urns' may be ignored. + * + * In the scenarios that the 'address' in the 'dialInfo' field has other functions besides the + * emergency number function, if the 'hasKnownUserIntentEmergency' field is true, the user's + * intent for this dial request is emergency call, and the modem must treat this as an actual + * emergency dial; if the 'hasKnownUserIntentEmergency' field is false, Android does not know + * user's intent for this call. + * + * If 'isTesting' is true, this request is for testing purpose, and must not be sent to a real + * emergency service; otherwise it's for a real emergency call request. + * + * Reference: 3gpp 22.101, Section 10 - Emergency Calls; + * 3gpp 23.167, Section 6 - Functional description; + * 3gpp 24.503, Section 5.1.6.8.1 - General; + * RFC 5031 + * + * @param serial Serial number of request. + * @param dialInfo the same @1.0::Dial information used by @1.0::IRadio.dial. + * @param categories bitfield<@1.4::EmergencyServiceCategory> the Emergency Service Category(s) + * of the call. + * @param urns the emergency Uniform Resource Names (URN) + * @param routing @1.4::EmergencyCallRouting the emergency call routing information. + * @param hasKnownUserIntentEmergency Flag indicating if user's intent for the emergency call + * is known. + * @param isTesting Flag indicating if this request is for testing purpose. + * + * Response function is IRadioResponse.emergencyDialResponse() + */ + oneway void emergencyDial(in int serial, in Dial dialInfo, + in EmergencyServiceCategory categories, in String[] urns, + in EmergencyCallRouting routing, in boolean hasKnownUserIntentEmergency, + in boolean isTesting); + + /** + * Toggle logical modem on/off. This is similar to @1.0::IRadio.setRadioPower(), however that + * does not enforce that radio power is toggled only for the corresponding radio and certain + * vendor implementations do it for all radios. This new API should affect only the modem for + * which it is called. A modem stack must be on/active only when both setRadioPower() and + * enableModem() are set to on for it. + * + * SIM must be read if available even if modem is off/inactive. + * + * @param serial Serial number of request. + * @param on True to turn on the logical modem, otherwise turn it off. + * + * Response function is IRadioResponse.enableModemResponse() + */ + oneway void enableModem(in int serial, in boolean on); + + /** + * Enable or disable UiccApplications on the SIM. If disabled: + * - Modem will not register on any network. + * - SIM must be PRESENT, and the IccId of the SIM must still be accessible. + * - The corresponding modem stack is still functional, e.g. able to make emergency calls or + * do network scan. + * By default if this API is not called, the uiccApplications must be enabled automatically. + * It must work for both single SIM and DSDS cases for UX consistency. + * The preference is per SIM, and must be remembered over power cycle, modem reboot, or SIM + * insertion / unplug. + * + * @param serial Serial number of request. + * @param enable true if to enable uiccApplications, false to disable. + * + * Response callback is IRadioResponse.enableUiccApplicationsResponse() + */ + oneway void enableUiccApplications(in int serial, in boolean enable); + + /** + * Request the radio's system selection module to exit emergency callback mode. Radio must not + * respond with SUCCESS until the modem has completely exited from Emergency Callback Mode. + * + * @param serial Serial number of request. + * + * Response callback is IRadioResponse.exitEmergencyCallbackModeResponse() + */ + oneway void exitEmergencyCallbackMode(in int serial); + + /** + * Connects the two calls and disconnects the subscriber from both calls. + * + * @param serial Serial number of request. + * + * Response callback is IRadioResponse.explicitCallTransferResponse() + */ + oneway void explicitCallTransfer(in int serial); + + /** + * Get carrier restrictions. + * + * @param serial Serial number of request. + * + * Response callback is IRadioResponse.getAllowedCarriersResponse_1_4() + */ + oneway void getAllowedCarriers(in int serial); + + /** + * Requests bitmap representing the currently allowed network types. + * getPreferredNetworkType, getPreferredNetworkTypesBitmap will not be called anymore + * except for IRadio v1.5 or older devices. + * + * @param serial Serial number of request. + * + * Response callback is IRadioResponse.getAllowedNetworkTypesBitmapResponse() + */ + oneway void getAllowedNetworkTypesBitmap(in int serial); + + /** + * Get the list of band modes supported by RF. + * + * @param serial Serial number of request. + * + * Response function is IRadioResponse.getAvailableBandModesResponse() + */ + oneway void getAvailableBandModes(in int serial); + + /** + * Scans for available networks + * + * @param serial Serial number of request. + * + * Response function is IRadioResponse.getAvailableNetworksResponse() + */ + oneway void getAvailableNetworks(in int serial); + + /** + * Get all the barring info for the current camped cell applicable to the current user. + * + * @param serial Serial number of request. + * + * Response callback is IRadioResponse.getBarringInfoResponse() + */ + oneway void getBarringInfo(in int serial); + + /** + * Return string value indicating baseband version, eg response from AT+CGMR + * + * @param serial Serial number of request. + * + * Response function is IRadioResponse.getBasebandVersionResponse() + */ + oneway void getBasebandVersion(in int serial); + + /** + * Request the device MDN / H_SID / H_NID. The request is only allowed when CDMA subscription + * is available. When CDMA subscription is changed, application layer must re-issue the request + * to update the subscription information. + * + * @param serial Serial number of request. + * + * Response callback is IRadioResponse.getCDMASubscriptionResponse() + */ + oneway void getCDMASubscription(in int serial); + + /** + * Request call forward status. + * + * @param serial Serial number of request. + * @param callInfo CallForwardInfo + * + * Response function is IRadioResponse.getCallForwardStatusResponse() + */ + oneway void getCallForwardStatus(in int serial, in CallForwardInfo callInfo); + + /** + * Query current call waiting state + * + * @param serial Serial number of request. + * @param serviceClass Service class is the TS 27.007 service class to query + * + * Response function is IRadioResponse.getCallWaitingResponse() + */ + oneway void getCallWaiting(in int serial, in int serviceClass); + + /** + * Request the setting of CDMA Broadcast SMS config + * + * @param serial Serial number of request. + * + * Response callback is IRadioResponse.getCdmaBroadcastConfigResponse() + */ + oneway void getCdmaBroadcastConfig(in int serial); + + /** + * Request the actual setting of the roaming preferences in CDMA in the modem + * + * @param serial Serial number of request. + * + * Response callback is IRadioResponse.getCdmaRoamingPreferenceResponse() + */ + oneway void getCdmaRoamingPreference(in int serial); + + /** + * Request to query the location where the CDMA subscription shall be retrieved. + * + * @param serial Serial number of request. + * + * Response callback is IRadioResponse.getCdmaSubscriptionSourceResponse() + */ + oneway void getCdmaSubscriptionSource(in int serial); + + /** + * Request all of the current cell information known to the radio. The radio + * must return list of all current cells, including the neighboring cells. If for a particular + * cell information isn't known then the appropriate unknown value will be returned. + * This does not cause or change the rate of unsolicited cellInfoList(). + * + * @param serial Serial number of request. + * + * Response callback is IRadioResponse.getCellInfoListResponse() + */ + oneway void getCellInfoList(in int serial); + + /** + * Queries the status of the CLIP supplementary service (for MMI code "*#30#") + * + * @param serial Serial number of request. + * + * Response function is IRadioResponse.getClipResponse() + */ + oneway void getClip(in int serial); + + /** + * Gets current CLIR status + * + * @param serial Serial number of request. + * + * Response function is IRadioResponse.getClirResponse() + */ + oneway void getClir(in int serial); + + /** + * Requests current call list + * + * @param serial Serial number of request. + * + * Response function is IRadioResponse.getCurrentCallsResponse_1_6() + */ + oneway void getCurrentCalls(in int serial); + + /** + * Returns the data call list. An entry is added when a setupDataCall() is issued and removed + * on a deactivateDataCall(). The list is emptied when setRadioPower() off/on issued or when + * the vendor HAL or modem crashes. + * + * @param serial Serial number of request. + * + * Response function is IRadioResponse.getDataCallListResponse_1_6() + */ + oneway void getDataCallList(in int serial); + + /** + * Request current data registration state. + * + * @param serial Serial number of request. + * + * Response function is IRadioResponse.getDataRegistrationStateResponse_1_6() + */ + oneway void getDataRegistrationState(in int serial); + + /** + * Request the device ESN / MEID / IMEI / IMEISV. The request is always allowed and contains + * GSM and CDMA device identity. When CDMA subscription is changed the ESN/MEID changes. + * The application layer must re-issue the request to update the device identity in this case. + * + * @param serial Serial number of request. + * + * Response callback is IRadioResponse.getDeviceIdentityResponse() + */ + oneway void getDeviceIdentity(in int serial); + + /** + * Query the status of a facility lock state + * + * @param serial Serial number of request. + * @param facility is the facility string code from TS 27.007 7.4 + * (eg "AO" for BAOC, "SC" for SIM lock) + * @param password is the password, or "" if not required + * @param serviceClass is the TS 27.007 service class bit vector of services to query + * @param appId is AID value, See ETSI 102.221 8.1 and 101.220 4, empty string if no value. + * This is only applicable in the case of Fixed Dialing Numbers (FDN) requests. + * + * Response function is IRadioResponse.getFacilityLockForAppResponse() + */ + oneway void getFacilityLockForApp(in int serial, in String facility, in String password, + in int serviceClass, in String appId); + + /** + * Request the setting of GSM/WCDMA Cell Broadcast SMS config. + * + * @param serial Serial number of request. + * + * Response callback is IRadioResponse.getGsmBroadcastConfigResponse() + */ + oneway void getGsmBroadcastConfig(in int serial); + + /** + * Request all of the current hardware (modem and sim) associated with Radio. + * + * @param serial Serial number of request. + * + * Response callback is IRadioResponse.getHardwareConfigResponse() + */ + oneway void getHardwareConfig(in int serial); + + /** + * Requests status of the ICC card + * + * @param serial Serial number of request. + * + * Response function is IRadioResponse.getIccCardStatusResponse() + * + */ + oneway void getIccCardStatus(in int serial); + + /** + * Request current IMS registration state + * + * @param serial Serial number of request. + * + * Response callback is IRadioResponse.getImsRegistrationStateResponse() + */ + oneway void getImsRegistrationState(in int serial); + + /** + * Get the SIM IMSI. Only valid when radio state is "RADIO_STATE_ON" + * + * @param serial Serial number of request. + * @param aid AID value, See ETSI 102.221 8.1 and 101.220 4, empty string if no value. + * + * Response function is IRadioResponse.getImsiForAppResponse() + * + */ + oneway void getImsiForApp(in int serial, in String aid); + + /** + * Requests the failure cause code for the most recently terminated call. + * + * @param serial Serial number of request. + * + * Response function is IRadioResponse.getLastCallFailCauseResponse() + * + */ + oneway void getLastCallFailCause(in int serial); + + /** + * Get modem activity information for power consumption estimation. Request clear-on-read + * statistics information that is used for estimating the per-millisecond power consumption + * of the cellular modem. + * + * @param serial Serial number of request. + * + * Response callback is IRadioResponse.getModemActivityInfoResponse() + */ + oneway void getModemActivityInfo(in int serial); + + /** + * Request status of logical modem. It returns isEnabled=true if the logical modem is on. + * This method is the getter method for enableModem. + * + * @param serial Serial number of request. + * + * Response function is IRadioResponse.getModemStackStatusResponse() + */ + oneway void getModemStackStatus(in int serial); + + /** + * Queries the current state of the uplink mute setting + * + * @param serial Serial number of request. + * + * Response function is IRadioResponse.getMuteResponse() + */ + oneway void getMute(in int serial); + + /** + * Request neighboring cell id in GSM network + * + * @param serial Serial number of request. + * + * Response callback is IRadioResponse.getNeighboringCidsResponse() + */ + oneway void getNeighboringCids(in int serial); + + /** + * Query current network selection mode + * + * @param serial Serial number of request. + * + * Response function is IRadioResponse.getNetworkSelectionModeResponse() + */ + oneway void getNetworkSelectionMode(in int serial); + + /** + * Request current operator ONS or EONS + * + * @param serial Serial number of request. + * + * Response function is IRadioResponse.getOperatorResponse() + */ + oneway void getOperator(in int serial); + + /** + * Query the preferred network type (CS/PS domain, RAT, and operation mode) + * for searching and registering + * + * @param serial Serial number of request. + * + * Response callback is IRadioResponse.getPreferredNetworkTypeResponse() + */ + oneway void getPreferredNetworkType(in int serial); + + /** + * Query the preferred network type bitmap. + * + * @param serial Serial number of request. + * + * Response callback is IRadioResponse.getPreferredNetworkTypeBitmapResponse() + */ + oneway void getPreferredNetworkTypeBitmap(in int serial); + + /** + * Request the setting of preferred voice privacy mode. + * + * @param serial Serial number of request. + * + * Response callback is IRadioResponse.getPreferredVoicePrivacyResponse() + */ + oneway void getPreferredVoicePrivacy(in int serial); + + /** + * Used to get phone radio capability. + * + * @param serial Serial number of request. + * + * Response callback is IRadioResponse.getRadioCapabilityResponse() + */ + oneway void getRadioCapability(in int serial); + + /** + * Requests current signal strength and associated information. Must succeed if radio is on. + * + * @param serial Serial number of request. + * + * Response function is IRadioResponse.getSignalStrengthResponse_1_6() + */ + oneway void getSignalStrength(in int serial); + + /** + * Get the phone book capacity + * + * @param serial Serial number of request. + * + * Response function is defined from IRadioResponse.getSimPhonebookCapacityResponse() + */ + oneway void getSimPhonebookCapacity(in int serial); + + /** + * Get the local and global phonebook records from the SIM card. + * This should be called again after a simPhonebookChanged notification is received. + * The phonebook records are received via IRadioIndication.simPhonebookRecordsReceived() + * + * @param serial Serial number of request. + * + * Response callback is IRadioResponse.getSimPhonebookRecordsResponse() + */ + oneway void getSimPhonebookRecords(in int serial); + + /** + * Request to get 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. + * + * Response function is IRadioResponse.getSlicingConfigResponse() + */ + oneway void getSlicingConfig(in int serial); + + /** + * Get the default Short Message Service Center address on the device. + * + * @param serial Serial number of request. + * + * Response callback is IRadioResponse.getSmscAddressResponse() + */ + oneway void getSmscAddress(in int serial); + + /** + * Get which bands the modem's background scan is acting on. + * + * @param serial Serial number of request. + * + * Response callback is IRadioResponse.getSystemSelectionChannelsResponse() + */ + oneway void getSystemSelectionChannels(in int serial); + + /** + * Request the setting of TTY mode + * + * @param serial Serial number of request. + * + * Response callback is IRadioResponse.getTTYModeResponse() + */ + oneway void getTTYMode(in int serial); + + /** + * Query the radio technology type (3GPP/3GPP2) used for voice. Query is valid only + * when radio state is not RADIO_STATE_UNAVAILABLE + * + * @param serial Serial number of request. + * + * Response callback is IRadioResponse.getVoiceRadioTechnologyResponse() + */ + oneway void getVoiceRadioTechnology(in int serial); + + /** + * Request current voice registration state. + * + * @param serial Serial number of request. + * + * Response function is IRadioResponse.getVoiceRegistrationStateResponse() + */ + oneway void getVoiceRegistrationState(in int serial); + + /** + * When STK application gets stkCallSetup(), the call actually has been initialized by the + * mobile device already. (We could see the call has been in the 'call list'). STK application + * needs to accept/reject the call according to user operations. + * + * @param serial Serial number of request. + * @param accept true = accept the call setup, false = reject the call setup + * + * Response callback is IRadioResponse.handleStkCallSetupRequestFromSimResponse() + */ + oneway void handleStkCallSetupRequestFromSim(in int serial, in boolean accept); + + /** + * Hang up a specific line (like AT+CHLD=1x). After this HANGUP request returns, Radio must + * show the connection is NOT active anymore in next getCurrentCalls() query. + * + * @param serial Serial number of request. + * @param gsmIndex Connection index (value of 'x' in CHLD above) + * + * Response function is IRadioResponse.hangupResponse() + */ + oneway void hangup(in int serial, in int gsmIndex); + + /** + * Hang up waiting or held (like AT+CHLD=1). After this HANGUP request returns, Radio must show + * the connection is NOT active anymore in next getCurrentCalls() query. + * + * @param serial Serial number of request. + * + * Response function is IRadioResponse.hangupForegroundResumeBackgroundResponse() + */ + oneway void hangupForegroundResumeBackground(in int serial); + + /** + * Hang up waiting or held (like AT+CHLD=0). After this HANGUP request returns, Radio must show + * the connection is NOT active anymore in next getCurrentCalls() query. + * + * @param serial Serial number of request. + * + * Response function is IRadioResponse.hangupWaitingOrBackgroundResponse() + */ + oneway void hangupWaitingOrBackground(in int serial); + + /** + * Close a previously opened logical channel. This command reflects TS 27.007 + * "close logical channel" operation (+CCHC). + * + * @param serial Serial number of request. + * @param channelId session id of the logical channel (+CCHC). + * + * Response callback is IRadioResponse.iccCloseLogicalChannelResponse() + */ + oneway void iccCloseLogicalChannel(in int serial, in int channelId); + + /** + * Request ICC I/O operation. This is similar to the TS 27.007 "restricted SIM" operation where + * it assumes all of the EF selection must be done by the callee. Arguments and responses that + * are unused for certain values of "command" must be ignored or set to empty string. + * Note that IccIo has a "PIN2" field which may be empty string, or may specify a PIN2 for + * operations that require a PIN2 (eg updating FDN records). + * + * @param serial Serial number of request. + * @param iccIo IccIo + * + * Response function is IRadioResponse.iccIOForAppResponse() + */ + oneway void iccIOForApp(in int serial, in IccIo iccIo); + + /** + * Open a new logical channel and select the given application. This command + * reflects TS 27.007 "open logical channel" operation (+CCHO). + * + * @param serial Serial number of request. + * @param aid AID value, See ETSI 102.221 and 101.220. + * @param p2 P2 value, described in ISO 7816-4. Ignore if equal to P2Constant:NO_P2 + * + * Response callback is IRadioResponse.iccOpenLogicalChannelResponse() + */ + oneway void iccOpenLogicalChannel(in int serial, in String aid, in int p2); + + /** + * Request APDU exchange on the basic channel. This command reflects TS 27.007 + * "generic SIM access" operation (+CSIM). The modem must ensure proper function of GSM/CDMA, + * and filter commands appropriately. It must filter channel management and SELECT by DF + * name commands. "sessionid" field must be ignored. + * + * @param serial Serial number of request. + * @param message SimApdu as defined in types.hal to be sent + * + * Response callback is IRadioResponse.iccTransmitApduBasicChannelResponse() + */ + oneway void iccTransmitApduBasicChannel(in int serial, in SimApdu message); + + /** + * Exchange APDUs with a UICC over a previously opened logical channel. This command reflects + * TS 27.007 "generic logical channel access" operation (+CGLA). The modem must filter channel + * management and SELECT by DF name commands. + * + * @param serial Serial number of request. + * @param message SimApdu as defined in types.hal to be sent + * + * Response callback is IRadioResponse.iccTransmitApduLogicalChannelResponse() + */ + oneway void iccTransmitApduLogicalChannel(in int serial, in SimApdu message); + + /** + * Is E-UTRA-NR Dual Connectivity enabled + * + * @param serial Serial number of request. + * Response callback is IRadioResponse.isNrDualConnectivityEnabledResponse() + */ + oneway void isNrDualConnectivityEnabled(in int serial); + + /** + * Read one of the radio NV items. + * This is used for device configuration by some CDMA operators. + * + * @param serial Serial number of request. + * @param itemId NvItem is radio NV item as defined in types.hal + * + * Response callback is IRadioResponse.nvReadItemResponse() + */ + oneway void nvReadItem(in int serial, in NvItem itemId); + + /** + * Reset the radio NV configuration to the factory state. + * This is used for device configuration by some CDMA operators. + * + * @param serial Serial number of request. + * @param resetType ResetNvType as defined in types.hal + * + * Response callback is IRadioResponse.nvResetConfigResponse() + */ + oneway void nvResetConfig(in int serial, in ResetNvType resetType); + + /** + * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage. + * This is used for device configuration by some CDMA operators. + * + * @param serial Serial number of request. + * @param prl PRL as a byte array + * + * Response callback is IRadioResponse.nvWriteCdmaPrlResponse() + */ + oneway void nvWriteCdmaPrl(in int serial, in byte[] prl); + + /** + * Write one of the radio NV items. + * This is used for device configuration by some CDMA operators. + * + * @param serial Serial number of request. + * @param item NvWriteItem as defined in types.hal + * + * Response callback is IRadioResponse.nvWriteItemResponse() + */ + oneway void nvWriteItem(in int serial, in NvWriteItem item); + + /** + * Pull LCE service for capacity information. + * + * @param serial Serial number of request. + * + * Response callback is IRadioResponse.pullLceDataResponse() which may return + * RadioError:REQUEST_NOT_SUPPORTED if @1.2::IRadio or higher is supported. + * + * DEPRECATED in @1.2 or higher which use the always-on LCE that relies on indications. + */ + oneway void pullLceData(in int serial); + + /** + * Send UDUB (user determined user busy) to ringing or waiting call answer) + * + * @param serial Serial number of request. + * + * Response function is IRadioResponse.rejectCallResponse() + */ + oneway void rejectCall(in int serial); + + /** + * Releases a pdu session id that was previously allocated using allocatePduSessionId. + * Reference: 3GPP TS 24.007 section 11.2.3.1b + * + * @param serial Serial number of request. + * @param id Pdu session id to release. + * + * Response function is IRadioResponse.releasePduSessionIdResponse() + */ + oneway void releasePduSessionId(in int serial, in int id); + + /** + * Indicates whether there is storage available for new SMS messages. + * + * @param serial Serial number of request. + * @param available true if memory is available for storing new messages, + * false if memory capacity is exceeded + * + * Response callback is IRadioResponse.reportSmsMemoryStatusResponse() + */ + oneway void reportSmsMemoryStatus(in int serial, in boolean available); + + /** + * Indicates that the StkService is running and is ready to receive unsolicited stk commands. + * + * @param serial Serial number of request. + * + * Response callback is IRadioResponse.reportStkServiceIsRunningResponse() + */ + oneway void reportStkServiceIsRunning(in int serial); + + /** + * Returns the response of SIM Authentication through Radio challenge request. + * + * @param serial Serial number of request. + * @param authContext P2 value of authentication command, see P2 parameter in + * 3GPP TS 31.102 7.1.2 + * @param authData the challenge string in Base64 format, see 3GPP TS 31.102 7.1.2 + * @param aid AID value, See ETSI 102.221 8.1 and 101.220 4, empty string if no value + * + * Response callback is IRadioResponse.requestIccSimAuthenticationResponse() + */ + oneway void requestIccSimAuthentication( + in int serial, in int authContext, in String authData, in String aid); + + /** + * Request the ISIM application on the UICC to perform AKA challenge/response algorithm + * for IMS authentication + * + * @param serial Serial number of request. + * @param challenge challenge string in Base64 format + * + * Response callback is IRadioResponse.requestIsimAuthenticationResponse() + */ + oneway void requestIsimAuthentication(in int serial, in String challenge); + + /** + * Device is shutting down. All further commands are ignored and RADIO_NOT_AVAILABLE + * must be returned. + * + * @param serial Serial number of request. + * + * Response callback is IRadioResponse.requestShutdownResponse() + */ + oneway void requestShutdown(in int serial); + + /** + * When response type received from a radio indication or radio response is + * RadioIndicationType:UNSOLICITED_ACK_EXP or RadioResponseType:SOLICITED_ACK_EXP respectively, + * acknowledge the receipt of those messages by sending responseAcknowledgement(). + */ + oneway void responseAcknowledgement(); + + /** + * Send DTMF string + * + * @param serial Serial number of request. + * @param dtmf DTMF string + * @param on DTMF ON length in milliseconds, or 0 to use default + * @param off is the DTMF OFF length in milliseconds, or 0 to use default + * + * Response callback is IRadioResponse.sendBurstDtmfResponse() + */ + oneway void sendBurstDtmf(in int serial, in String dtmf, in int on, in int off); + + /** + * Send FLASH command + * + * @param serial Serial number of request. + * @param featureCode String associated with Flash command + * + * Response callback is IRadioResponse.sendCDMAFeatureCodeResponse() + */ + oneway void sendCDMAFeatureCode(in int serial, in String featureCode); + + /** + * Send a CDMA SMS message + * + * @param serial Serial number of request. + * @param sms Cdma Sms to be sent described by CdmaSmsMessage in types.hal + * + * Response callback is IRadioResponse.sendCdmaSmsResponse() + */ + oneway void sendCdmaSms(in int serial, in CdmaSmsMessage sms); + + /** + * Send an SMS message. Identical to sendCdmaSms, except that more messages are expected to be + * sent soon. + * + * @param serial Serial number of request. + * @param sms Cdma Sms to be sent described by CdmaSmsMessage in types.hal + * + * Response callback is IRadioResponse.sendCdmaSMSExpectMoreResponse() + */ + oneway void sendCdmaSmsExpectMore(in int serial, in CdmaSmsMessage sms); + + /** + * Send the updated device state. This is providing the device state information for the modem + * to perform power saving strategies. + * + * @param serial Serial number of request. + * @param deviceStateType The updated device state type. + * @param state The updated state. See the definition of state at DeviceStateType. + * + * Response callback is IRadioResponse.sendDeviceStateResponse() + */ + oneway void sendDeviceState( + in int serial, in DeviceStateType deviceStateType, in boolean state); + + /** + * Send a DTMF tone. If the implementation is currently playing a tone requested via + * startDtmf(), that tone must be cancelled and the new tone must be played instead. + * + * @param serial Serial number of request. + * @param s string with single char having one of 12 values: 0-9, *, # + * + * Response function is IRadioResponse.sendDtmfResponse() + */ + oneway void sendDtmf(in int serial, in String s); + + /** + * Requests to send a SAT/USAT envelope command to SIM. + * The SAT/USAT envelope command refers to 3GPP TS 11.14 and 3GPP TS 31.111 + * + * @param serial Serial number of request. + * @param command SAT/USAT command in hexadecimal format string starting with command tag + * + * Response function is IRadioResponse.sendEnvelopeResponse() + */ + oneway void sendEnvelope(in int serial, in String command); + + /** + * Requests to send a SAT/USAT envelope command to SIM. The SAT/USAT envelope command refers to + * 3GPP TS 11.14 and 3GPP TS 31.111. This request has one difference from sendEnvelope(): + * The SW1 and SW2 status bytes from the UICC response are returned along with the response + * data, using the same structure as iccIOForApp(). The implementation must perform normal + * processing of a '91XX' response in SW1/SW2 to retrieve the pending proactive command and + * send it as an unsolicited response, as sendEnvelope() does. + * + * @param serial Serial number of request. + * @param contents SAT/USAT command in hexadecimal format starting with command tag + * + * Response callback is IRadioResponse.sendEnvelopeWithStatusResponse() + */ + oneway void sendEnvelopeWithStatus(in int serial, in String contents); + + /** + * Send a SMS message over IMS. Based on the return error, caller decides to resend if sending + * sms fails. SMS_SEND_FAIL_RETRY means retry, and other errors means no retry. + * In case of retry, data is encoded based on Voice Technology available. + * + * @param serial Serial number of request. + * @param message ImsSmsMessage as defined in types.hal to be sent + * + * Response callback is IRadioResponse.sendImsSmsResponse() + */ + oneway void sendImsSms(in int serial, in ImsSmsMessage message); + + /** + * Send an SMS message. Identical to sendSms, except that more messages are expected to be sent + * soon. If possible, keep SMS relay protocol link open (eg TS 27.005 AT+CMMS command). + * Based on the returned error, caller decides to resend if sending sms fails. + * RadioError:SMS_SEND_FAIL_RETRY means retry (i.e. error cause is 332) and + * RadioError:GENERIC_FAILURE means no retry (i.e. error cause is 500) + * + * @param serial Serial number of request. + * @param message GsmSmsMessage as defined in types.hal + * + * Response function is IRadioResponse.sendSMSExpectMoreResponse() + * + * DEPRECATED in @1.6 or higher which uses sendSmsExpectMore(). + */ + oneway void sendSMSExpectMore(in int serial, in GsmSmsMessage message); + + /** + * Send an SMS message. Based on the returned error, caller decides to resend if sending sms + * fails. RadioError:SMS_SEND_FAIL_RETRY means retry (i.e. error cause is 332) and + * RadioError:GENERIC_FAILURE means no retry (i.e. error cause is 500) + * + * @param serial Serial number of request. + * @param message GsmSmsMessage as defined in types.hal + * + * Response function is IRadioResponse.sendSmsResponse() + */ + oneway void sendSms(in int serial, in GsmSmsMessage message); + + /** + * Send an SMS message. Identical to sendSms, except that more messages are expected to be sent + * soon. If possible, keep SMS relay protocol link open (eg TS 27.005 AT+CMMS command). + * Based on the return error, caller decides to resend if sending sms fails. + * RadioError:SMS_SEND_FAIL_RETRY means retry (i.e. error cause is 332) and + * RadioError:GENERIC_FAILURE means no retry (i.e. error cause is 500) + * + * @param serial Serial number of request. + * @param message GsmSmsMessage as defined in types.hal + * + * Response function is IRadioResponse.sendSmsExpectMoreResponse() + */ + oneway void sendSmsExpectMore(in int serial, in GsmSmsMessage message); + + /** + * Requests to send a terminal response to SIM for a received proactive command + * + * @param serial Serial number of request. + * @param commandResponse SAT/USAT response in hexadecimal format string starting with + * first byte of response data + * + * Response function is IRadioResponse.sendTerminalResponseResponseToSim() + */ + oneway void sendTerminalResponseToSim(in int serial, in String commandResponse); + + /** + * Send a USSD message. If a USSD session already exists, the message must be sent in the + * context of that session. Otherwise, a new session must be created. The network reply must be + * reported via unsolOnUssd. + * + * Only one USSD session must exist at a time, and the session is assumed to exist until: + * a) The android system invokes cancelUssd() + * b) The implementation sends a unsolOnUssd() with a type code of + * "0" (USSD-Notify/no further action) or "2" (session terminated) + * + * @param serial Serial number of request. + * @param ussd string containing the USSD request in UTF-8 format + * + * Response function is IRadioResponse.sendUssdResponse() + * + * See also requestCancelUssd, unsolOnUssd + */ + oneway void sendUssd(in int serial, in String ussd); + + /** + * Separate a party from a multiparty call placing the multiparty call (less the specified + * party) on hold and leaving the specified party as the only other member of the current + * (active) call. Like AT+CHLD=2x. + * + * See TS 22.084 1.3.8.2 (iii) + * TS 22.030 6.5.5 "Entering "2X followed by send" + * TS 27.007 "AT+CHLD=2x" + * + * @param serial Serial number of request. + * @param gsmIndex contains Connection index (value of 'x' in CHLD above) + * + * Response function is IRadioResponse.separateConnectionResponse() + */ + oneway void separateConnection(in int serial, in int gsmIndex); + + /** + * Set carrier restrictions. Expected modem behavior: + * If never receives this command: + * - Must allow all carriers + * Receives this command: + * - Only allow carriers specified in carriers. The restriction persists across power cycles + * and FDR. If a present SIM is allowed, modem must not reload the SIM. If a present SIM is + * *not* allowed, modem must detach from the registered network and only keep emergency + * service, and notify Android SIM refresh reset with new SIM state being + * CardState:RESTRICTED. Emergency service must be enabled. + * + * @param serial Serial number of request. + * @param carriers CarrierRestrictionsWithPriority consisting allowed and excluded carriers + * as defined in types.hal + * @param multiSimPolicy Policy to be used for devices with multiple SIMs. + * + * Response callback is IRadioResponse.setAllowedCarriersResponse() + */ + oneway void setAllowedCarriers(in int serial, in CarrierRestrictionsWithPriority carriers, + in SimLockMultiSimPolicy multiSimPolicy); + + /** + * Requests to set the network type for searching and registering. Instruct the radio to + * *only* accept the types of network provided. setPreferredNetworkTypesBitmap and + * setPreferredNetworkType will not be called anymore except for IRadio v1.5 or older devices. + * In case of an emergency call, the modem is authorized to bypass this restriction. + * + * @param serial Serial number of request. + * @param networkTypeBitmap a 32-bit bearer bitmap of RadioAccessFamily + * + * Response callback is IRadioResponse.setAllowedNetworkTypesBitmapResponse() + */ + oneway void setAllowedNetworkTypesBitmap(in int serial, in RadioAccessFamily networkTypeBitmap); + + /** + * Assign a specified band for RF configuration. + * + * @param serial Serial number of request. + * @param mode RadioBandMode defined in types.hal + * + * Response function is IRadioResponse.setBandModeResponse() + */ + oneway void setBandMode(in int serial, in RadioBandMode mode); + + /** + * Change call barring facility password + * + * @param serial Serial number of request. + * @param facility facility string code from TS 27.007 7.4 (eg "AO" for BAOC) + * @param oldPassword old password + * @param newPassword new password + * + * Response function is IRadioResponse.setBarringPasswordResponse() + */ + oneway void setBarringPassword( + in int serial, in String facility, in String oldPassword, in String newPassword); + + /** + * Configure call forward rule + * + * @param serial Serial number of request. + * @param callInfo CallForwardInfo + * + * Response function is IRadioResponse.setCallForwardResponse() + */ + oneway void setCallForward(in int serial, in CallForwardInfo callInfo); + + /** + * Configure current call waiting state + * + * @param serial Serial number of request. + * @param enable is false for "disabled" and true for "enabled" + * @param serviceClass is the TS 27.007 service class bit vector of services to modify + * + * Response function is IRadioResponse.setCallWaitingResponse() + */ + oneway void setCallWaiting(in int serial, in boolean enable, in int serviceClass); + + /** + * Provide Carrier specific information to the modem that must be used to encrypt the IMSI and + * IMPI. Sent by the framework during boot, carrier switch and everytime the framework receives + * a new certificate. + * + * @param serial Serial number of request. + * @param imsiEncryptionInfo ImsiEncryptionInfo as defined in types.hal. + * + * Response callback is IRadioResponse.setCarrierInfoForImsiEncryptionResponse() + */ + oneway void setCarrierInfoForImsiEncryption( + in int serial, in ImsiEncryptionInfo imsiEncryptionInfo); + + /** + * Enable or disable the reception of CDMA Cell Broadcast SMS + * + * @param serial Serial number of request. + * @param activate indicates to activate or turn off the reception of CDMA + * Cell Broadcast SMS. true = activate, false = turn off + * + * Response callback is IRadioResponse.setCdmaBroadcastActivationResponse() + */ + oneway void setCdmaBroadcastActivation(in int serial, in boolean activate); + + /** + * Set CDMA Broadcast SMS config + * + * @param serial Serial number of request. + * @param configInfo CDMA Broadcast SMS config to be set. + * + * Response callback is IRadioResponse.setCdmaBroadcastConfigResponse() + */ + oneway void setCdmaBroadcastConfig(in int serial, in CdmaBroadcastSmsConfigInfo[] configInfo); + + /** + * Request to set the roaming preferences in CDMA + * + * @param serial Serial number of request. + * @param type CdmaRoamingType defined in types.hal + * + * Response callback is IRadioResponse.setCdmaRoamingPreferenceResponse() + */ + oneway void setCdmaRoamingPreference(in int serial, in CdmaRoamingType type); + + /** + * Request to set the location where the CDMA subscription shall be retrieved + * + * @param serial Serial number of request. + * @param cdmaSub CdmaSubscriptionSource + * + * Response callback is IRadioResponse.setCdmaSubscriptionSourceResponse() + */ + oneway void setCdmaSubscriptionSource(in int serial, in CdmaSubscriptionSource cdmaSub); + + /** + * Sets the minimum time between when unsolicited cellInfoList() must be invoked. + * A value of 0, means invoke cellInfoList() when any of the reported information changes. + * Setting the value to INT_MAX(0x7fffffff) means never issue a unsolicited cellInfoList(). + * + * @param serial Serial number of request. + * @param rate minimum time in milliseconds to indicate time between unsolicited cellInfoList() + * + * Response callback is IRadioResponse.setCellInfoListRateResponse() + */ + oneway void setCellInfoListRate(in int serial, in int rate); + + /** + * Set current CLIR status + * + * @param serial Serial number of request. + * @param status "n" parameter from TS 27.007 7.7 + * + * Response function is IRadioResponse.setClirResponse() + */ + oneway void setClir(in int serial, in int status); + + /** + * Tells the modem whether data calls are allowed or not + * + * @param serial Serial number of request. + * @param allow true to allow data calls, false to disallow data calls + * + * Response callback is IRadioResponse.setDataAllowedResponse() + */ + oneway void setDataAllowed(in int serial, in boolean allow); + + /** + * Send data profiles of the current carrier to the modem. + * + * @param serial Serial number of request. + * @param profiles Array of DataProfileInfo to set. + * + * Response callback is IRadioResponse.setDataProfileResponse() + */ + oneway void setDataProfile(in int serial, in DataProfileInfo[] profiles); + + /** + * Control data throttling at modem. + * - DataThrottlingAction:NO_DATA_THROTTLING should clear any existing data throttling within + * the requested completion window. + * - DataThrottlingAction:THROTTLE_SECONDARY_CARRIER: Remove any existing throttling on anchor + * carrier and achieve maximum data throttling on secondary carrier within the requested + * completion window. + * - DataThrottlingAction:THROTTLE_ANCHOR_CARRIER: disable secondary carrier and achieve maximum + * data throttling on anchor carrier by requested completion window. + * - DataThrottlingAction:HOLD: Immediately hold on to current level of throttling. + * + * @param serial Serial number of request. + * @param dataThrottlingAction DataThrottlingAction as defined in types.hal + * @param completionDurationMillis window, in milliseconds, in which the requested throttling + * action has to be achieved. This must be 0 when dataThrottlingAction is + * DataThrottlingAction:HOLD. + * + * Response function is IRadioResponse.setDataThrottlingResponse() + */ + oneway void setDataThrottling(in int serial, in DataThrottlingAction dataThrottlingAction, + in long completionDurationMillis); + + /** + * Enable/disable one facility lock + * + * @param serial Serial number of request. + * @param facility is the facility string code from TS 27.007 7.4 (eg "AO" for BAOC) + * @param lockState false for "unlock" and true for "lock" + * @param password is the password + * @param serviceClass is string representation of decimal TS 27.007 service class bit vector. + * Eg, the string "1" means "set this facility for voice services" + * @param appId is AID value, See ETSI 102.221 8.1 and 101.220 4, empty string if no value. + * This is only applicable in the case of Fixed Dialing Numbers (FDN) requests. + * + * Response function is IRadioResponse.setFacilityLockForAppResponse() + */ + oneway void setFacilityLockForApp(in int serial, in String facility, in boolean lockState, + in String password, in int serviceClass, in String appId); + + /** + * Enable or disable the reception of GSM/WCDMA Cell Broadcast SMS + * + * @param serial Serial number of request. + * @param activate indicates to activate or turn off the reception of GSM/WCDMA + * Cell Broadcast SMS. true = activate, false = turn off + * + * Response callback is IRadioResponse.setGsmBroadcastActivationResponse() + */ + oneway void setGsmBroadcastActivation(in int serial, in boolean activate); + + /** + * Set GSM/WCDMA Cell Broadcast SMS config + * + * @param serial Serial number of request. + * @param configInfo Setting of GSM/WCDMA Cell broadcast config + * + * Response callback is IRadioResponse.setGsmBroadcastConfigResponse() + */ + oneway void setGsmBroadcastConfig(in int serial, in GsmBroadcastSmsConfigInfo[] configInfo); + + /** + * Sets the indication filter. Prevents the reporting of specified unsolicited indications from + * the radio. This is used for power saving in instances when those indications are not needed. + * If unset, defaults to IndicationFilter:ALL. + * + * @param serial Serial number of request. + * @param indicationFilter 32-bit bitmap of IndicationFilter. Bits set to 1 indicate the + * indications are enabled. See IndicationFilter for the definition of each bit. + * + * Response callback is IRadioResponse.setIndicationFilterResponse() + */ + oneway void setIndicationFilter(in int serial, in IndicationFilter indicationFilter); + + /** + * Set an APN to initial attach network. + * + * @param serial Serial number of request. + * @param dataProfileInfo data profile containing APN settings + * + * Response callback is IRadioResponse.setInitialAttachApnResponse() + */ + oneway void setInitialAttachApn(in int serial, in DataProfileInfo dataProfileInfo); + + /** + * Sets the link capacity reporting criteria. The resulting reporting criteria are the AND of + * all the supplied criteria. Note that reporting criteria must be individually set for each + * RAN. If unset, reporting criteria for that RAN are implementation-defined. + * + * Response callback is IRadioResponse.setLinkCapacityReportingCriteriaResponse(). + * + * @param serial Serial number of request. + * @param hysteresisMs A hysteresis time in milliseconds to prevent flapping. A value of 0 + * disables hysteresis. + * @param hysteresisDlKbps An interval in kbps defining the required magnitude change between DL + * reports. hysteresisDlKbps must be smaller than the smallest threshold delta. A value + * of 0 disables hysteresis. + * @param hysteresisUlKbps An interval in kbps defining the required magnitude change between UL + * reports. hysteresisUlKbps must be smaller than the smallest threshold delta. A value + * of 0 disables hysteresis. + * @param thresholdsDownlinkKbps A vector of trigger thresholds in kbps for downlink reports. A + * vector size of 0 disables the use of DL thresholds for reporting. + * @param thresholdsUplinkKbps A vector of trigger thresholds in kbps for uplink reports. A + * vector size of 0 disables the use of UL thresholds for reporting. + * @param accessNetwork The type of network for which to apply these thresholds. + */ + oneway void setLinkCapacityReportingCriteria(in int serial, in int hysteresisMs, + in int hysteresisDlKbps, in int hysteresisUlKbps, in int[] thresholdsDownlinkKbps, + in int[] thresholdsUplinkKbps, in AccessNetwork accessNetwork); + + /** + * Enables/disables network state change notifications due to changes in LAC and/or CID (for + * GSM) or BID/SID/NID/latitude/longitude (for CDMA). Basically +CREG=2 vs. +CREG=1 (TS 27.007). + * The Radio implementation must default to "updates enabled" when the screen is on and + * "updates disabled" when the screen is off. + * + * @param serial Serial number of request. + * @param enable true=updates enabled (+CREG=2), false=updates disabled (+CREG=1) + * + * Response callback is IRadioResponse.setLocationUpdatesResponse() + */ + oneway void setLocationUpdates(in int serial, in boolean enable); + + /** + * Turn on or off uplink (microphone) mute. Must only be sent while voice call is active. + * Must always be reset to "disable mute" when a new voice call is initiated + * + * @param serial Serial number of request. + * @param enable true for "enable mute" and false for "disable mute" + * + * Response function is IRadioResponse.setMuteResponse() + */ + oneway void setMute(in int serial, in boolean enable); + + /** + * Specify that the network must be selected automatically. + * This request must not respond until the new operator is selected and registered. + * + * @param serial Serial number of request. + * + * Response function is IRadioResponse.setNetworkSelectionModeAutomaticResponse() + */ + oneway void setNetworkSelectionModeAutomatic(in int serial); + + /** + * Manually select a specified network. This request must not respond until the new operator is + * selected and registered. Per TS 23.122, the RAN is just the initial suggested value. + * If registration fails, the RAN is not available afterwards, or the RAN is not within the + * network types specified by IRadio::setPreferredNetworkTypeBitmap, then the modem will need to + * select the next best RAN for network registration. + * + * @param serial Serial number of request. + * @param operatorNumeric String specifying MCCMNC of network to select (eg "310170"). + * @param ran Initial suggested radio access network type. If value is UNKNOWN, the modem + * will select the next best RAN for network registration. + * + * Response function is IRadioResponse.setNetworkSelectionModeManualResponse() + */ + oneway void setNetworkSelectionModeManual( + in int serial, in String operatorNumeric, in RadioAccessNetworks ran); + + /** + * Enable or disable E-UTRA-NR dual connectivity. If disabled then UE will not connect + * to secondary carrier. + * + * @param serial Serial number of request. + * @param nrDualConnectivityState expected NR dual connectivity state. + * 1: Enable NR dual connectivity {NrDualConnectivityState:ENABLE} + * 2: Disable NR dual connectivity {NrDualConnectivityState:DISABLE} + * 3: Disable NR dual connectivity and force secondary cell to be released + * {NrDualConnectivityState:DISABLE_IMMEDIATE} + * + * Response callback is IRadioResponse.setNRDualConnectivityStateResponse() + */ + oneway void setNrDualConnectivityState( + in int serial, in NrDualConnectivityState nrDualConnectivityState); + + /** + * Requests to set the preferred network type for searching and registering + * (CS/PS domain, RAT, and operation mode) + * + * @param serial Serial number of request. + * @param nwType PreferredNetworkType defined in types.hal + * + * Response callback is IRadioResponse.setPreferredNetworkTypeResponse() + */ + oneway void setPreferredNetworkType(in int serial, in PreferredNetworkType nwType); + + /** + * Requests to set the preferred network type for searching and registering. + * + * @param serial Serial number of request. + * @param networkTypeBitmap a 32-bit bitmap of RadioAccessFamily. + * + * Response callback is IRadioResponse.setPreferredNetworkTypeBitmapResponse() + */ + oneway void setPreferredNetworkTypeBitmap( + in int serial, in RadioAccessFamily networkTypeBitmap); + + /** + * Request to set the preferred voice privacy mode used in voice scrambling. + * + * @param serial Serial number of request. + * @param enable false for Standard Privacy Mode (Public Long Code Mask) + * true for Enhanced Privacy Mode (Private Long Code Mask) + * + * Response callback is IRadioResponse.setPreferredVoicePrivacyResponse() + */ + oneway void setPreferredVoicePrivacy(in int serial, in boolean enable); + + /** + * Used to set the phones radio capability. Be VERY careful using this request as it may cause + * some vendor modems to reset. Because of the possible modem reset any radio commands after + * this one may not be processed. + * + * @param serial Serial number of request. + * @param rc RadioCapability structure to be set + * + * Response callback is IRadioResponse.setRadioCapabilityResponse() + */ + oneway void setRadioCapability(in int serial, in RadioCapability rc); + + /** + * Toggle radio on and off (for "airplane" mode). If the radio is turned off/on the radio modem + * subsystem is expected return to an initialized state. For instance, any voice and data calls + * must be terminated and all associated lists emptied. + * When setting radio power on to exit from airplane mode to place an emergency call on this + * logical modem, powerOn, forEmergencyCall and preferredForEmergencyCall must be true. In + * this case, this modem is optimized to scan only emergency call bands, until: + * 1) Emergency call is completed; or + * 2) Another setRadioPower_1_5 is issued with forEmergencyCall being false or + * preferredForEmergencyCall being false; or + * 3) Timeout after 30 seconds if dial or emergencyDial is not called. + * Once one of these conditions is reached, the modem should move into normal operation. + * + * @param serial Serial number of request. + * @param powerOn To turn on radio -> on = true, to turn off radio -> on = false. + * @param forEmergencyCall To indication to radio if this request is due to emergency call. + * No effect if powerOn is false. + * @param preferredForEmergencyCall indicate whether the following emergency call will be sent + * on this modem or not. No effect if forEmergencyCall is false, or powerOn is false. + * + * Response callback is IRadioConfigResponse.setRadioPowerResponse. + */ + oneway void setRadioPower(in int serial, in boolean powerOn, in boolean forEmergencyCall, + in boolean preferredForEmergencyCall); + + /** + * Set response functions for radio requests & radio indications. + * + * @param radioResponse Object containing response functions + * @param radioIndication Object containing radio indications + */ + void setResponseFunctions(in IRadioResponse radioResponse, in IRadioIndication radioIndication); + + /** + * Sets the signal strength reporting criteria. The resulting reporting rules are the AND of all + * the supplied criteria. For each RAN the hysteresisDb and thresholds apply to only the + * following measured quantities: + * -GERAN - RSSI + * -CDMA2000 - RSSI + * -UTRAN - RSCP + * -EUTRAN - RSRP/RSRQ/RSSNR + * -NGRAN - SSRSRP/SSRSRQ/SSSINR + * Note that reporting criteria must be individually set for each RAN. For each RAN, if none of + * reporting criteria of any measurement is set enabled (see SignalThresholdInfo.isEnabled), + * the reporting criteria for this RAN is implementation-defined. For each RAN, if any reporting + * criteria of any measure is set enabled, the reporting criteria of the other measures in this + * RAN are set disabled (see SignalThresholdInfo.isEnabled) until they are set enabled. + * + * @param serial Serial number of request. + * @param signalThresholdInfo Signal threshold info including the threshold values, + * hysteresisDb, hysteresisMs and isEnabled. See SignalThresholdInfo for details. + * @param accessNetwork The type of network for which to apply these thresholds. + * + * Response callback is IRadioResponse.setSignalStrengthReportingCriteriaResponse() + */ + oneway void setSignalStrengthReportingCriteria(in int serial, + in SignalThresholdInfo signalThresholdInfo, in AccessNetwork accessNetwork); + + /** + * Set SIM card power state. Request is used to power off or power on the card. It should not + * generate a CardState.CARDSTATE_ABSENT indication, since the SIM is still physically inserted. + * When SIM card is in POWER_UP_PASS_THROUGH, the modem does not send any command to it (for + * example SELECT of MF, or TERMINAL CAPABILITY), and the SIM card is controlled completely by + * Telephony sending APDUs directly. The SIM card state must be RIL_CARDSTATE_PRESENT and the + * number of card apps will be 0. No new error code is generated. Emergency calls are supported + * in the same way as if the SIM card is absent. Pass-through mode is valid only for the + * specific card session where it is activated, and normal behavior occurs at the next SIM + * initialization, unless POWER_UP_PASS_THROUGH is requested again. + * The device is required to power down the SIM card before it can switch the mode between + * POWER_UP and POWER_UP_PASS_THROUGH. At device power up, the SIM interface is powered up + * automatically. Each subsequent request to this method is processed only after the completion + * of the previous one. + * When the SIM is in POWER_DOWN, the modem should send an empty vector of AppStatus in + * CardStatus.applications. If a SIM in the POWER_DOWN state is removed and a new SIM is + * inserted, the new SIM should be in POWER_UP mode by default. If the device is turned off or + * restarted while the SIM is in POWER_DOWN, then the SIM should turn on normally in POWER_UP + * mode when the device turns back on. + * + * @param serial Serial number of request + * @param powerUp POWER_DOWN if powering down the SIM card + * POWER_UP if powering up the SIM card + * POWER_UP_PASS_THROUGH if powering up the SIM card in pass through mode + * + * Response callback is IRadioResponse.setSimCardPowerResponse(). + */ + oneway void setSimCardPower(in int serial, in CardPowerState powerUp); + + /** + * Set the default Short Message Service Center address on the device. + * + * @param serial Serial number of request. + * @param smsc Short Message Service Center address to set + * + * Response callback is IRadioResponse.setSmscAddressResponse() + */ + oneway void setSmscAddress(in int serial, in String smsc); + + /** + * Enables/disables supplementary service related notifications from the network. + * Notifications are reported via unsolSuppSvcNotification(). + * + * @param serial Serial number of request. + * @param enable true = notifications enabled, false = notifications disabled. + * + * Response function is IRadioResponse.setSuppServiceNotificationsResponse() + */ + oneway void setSuppServiceNotifications(in int serial, in boolean enable); + + /** + * Specify which bands modem's background scan must act on. If specifyChannels is true, it only + * scans bands specified in specifiers. If specifyChannels is false, it scans all bands. For + * example, CBRS is only on LTE band 48. By specifying this band, modem saves more power. + * + * @param serial Serial number of request. + * @param specifyChannels whether to scan bands defined in specifiers. + * @param specifiers which bands to scan. Only used if specifyChannels is true. + * + * Response callback is IRadioResponse.setSystemSelectionChannelsResponse() + */ + oneway void setSystemSelectionChannels( + in int serial, in boolean specifyChannels, in RadioAccessSpecifier[] specifiers); + + /** + * Request to set the TTY mode + * + * @param serial Serial number of request. + * @param mode TtyMode + * + * Response callback is IRadioResponse.setTTYModeResponse() + */ + oneway void setTTYMode(in int serial, in TtyMode mode); + + /** + * Selection/de-selection of a subscription from a SIM card + * + * @param serial Serial number of request. + * @param uiccSub SelectUiccSub as defined in types.hal + * + * Response callback is IRadioResponse.setUiccSubscriptionResponse() + */ + oneway void setUiccSubscription(in int serial, in SelectUiccSub uiccSub); + + /** + * Setup a packet data connection. If DataCallResponse.status returns DataCallFailCause:NONE, + * the data connection must be added to data calls and a unsolDataCallListChanged() must be + * sent. The call remains until removed by subsequent unsolDataCallIstChanged(). It may be lost + * due to many factors, including deactivateDataCall() being issued, the radio powered off, + * reception lost or even transient factors like congestion. This data call list is returned by + * getDataCallList() and dataCallListChanged(). + * The Radio is expected to: + * - Create one data call context. + * - Create and configure a dedicated interface for the context. + * - The interface must be point to point. + * - The interface is configured with one or more addresses and is capable of sending and + * receiving packets. The format is IP address with optional "/" prefix length (The format is + * defined in RFC-4291 section 2.3). For example, "192.0.1.3", "192.0.1.11/16", or + * "2001:db8::1/64". Typically one IPv4 or one IPv6 or one of each. If the prefix length is + * absent, then the addresses are assumed to be point to point with IPv4 with prefix length 32 + * or IPv6 with prefix length 128. + * - Must not modify routing configuration related to this interface; routing management is + * exclusively within the purview of the Android OS. + * - Support simultaneous data call contexts up to DataRegStateResult.maxDataCalls specified in + * the response of getDataRegistrationState. + * + * @param serial Serial number of request. + * @param accessNetwork The access network to setup the data call. If the data connection cannot + * be established on the specified access network then this should respond with an error. + * @param dataProfileInfo Data profile info. + * @param roamingAllowed Indicates whether or not data roaming is allowed by the user. + * @param reason The request reason. Must be DataRequestReason:NORMAL or + * DataRequestReason:HANDOVER. + * @param addresses If the reason is DataRequestReason:HANDOVER, this indicates the list of link + * addresses of the existing data connection. This parameter must be ignored unless + * reason is DataRequestReason:HANDOVER. + * @param dnses If the reason is DataRequestReason:HANDOVER, this indicates the list of DNS + * addresses of the existing data connection. The format is defined in RFC-4291 section + * 2.2. For example, "192.0.1.3" or "2001:db8::1". This parameter must be ignored unless + * reason is DataRequestReason:HANDOVER. + * @param pduSessionId The pdu session id to be used for this data call. A value of 0 means no + * pdu session id was attached to this call. Reference: 3GPP TS 24.007 section 11.2.3.1b + * @param sliceInfo SliceInfo to be used for the data connection when a handover occurs from + * EPDG to 5G. It is valid only when accessNetwork is AccessNetwork:NGRAN. If the slice + * passed from EPDG is rejected, then the data failure cause must be + * DataCallFailCause:SLICE_REJECTED. + * @param trafficDescriptor TrafficDescriptor for which data connection needs to be established. + * It is used for URSP traffic matching as described in TS 24.526 Section 4.2.2. + * It includes an optional DNN which, if present, must be used for traffic matching -- + * it does not specify the end point to be used for the data call. The end point is + * specified by DataProfileInfo.apn; DataProfileInfo.apn must be used as the end point if + * one is not specified through URSP rules. + * @param matchAllRuleAllowed bool to indicate if using default match-all URSP rule for this + * request is allowed. If false, this request must not use the match-all URSP rule and if + * a non-match-all rule is not found (or if URSP rules are not available) it should + * return failure with cause DataCallFailCause:MATCH_ALL_RULE_NOT_ALLOWED. This is needed + * as some requests need to have a hard failure if the intention cannot be met, for + * example, a zero-rating slice. + * + * Response function is IRadioResponse.setupDataCallResponse() + */ + oneway void setupDataCall(in int serial, in AccessNetwork accessNetwork, + in DataProfileInfo dataProfileInfo, in boolean roamingAllowed, + in DataRequestReason reason, in LinkAddress[] addresses, in String[] dnses, + in int pduSessionId, in OptionalSliceInfo sliceInfo, + in OptionalTrafficDescriptor trafficDescriptor, in boolean matchAllRuleAllowed); + + /** + * Start playing a DTMF tone. Continue playing DTMF tone until stopDtmf is received. If a + * startDtmf() is received while a tone is currently playing, it must cancel the previous tone + * and play the new one. + * + * @param serial Serial number of request. + * @param s string having a single character with one of 12 values: 0-9,*,# + * + * Response function is IRadioResponse.startDtmfResponse() + */ + oneway void startDtmf(in int serial, in String s); + + /** + * Indicates that a handover to the IWLAN transport has begun. Any resources being transferred + * to the IWLAN transport cannot be released while a handover is underway. For example, if a + * pdu session id needs to be transferred to IWLAN, then the modem should not release the id + * while the handover is in progress. If a handover was unsuccessful, then the framework calls + * IRadio::cancelHandover. The modem retains ownership over any of the resources being + * transferred to IWLAN. If a handover was successful, the framework calls + * IRadio::deactivateDataCall with reason HANDOVER. The IWLAN transport now owns the transferred + * resources and is responsible for releasing them. + * + * @param serial Serial number of request. + * @param id callId The identifier of the data call which is provided in SetupDataCallResult + * + * Response function is IRadioResponse.startHandoverResponse() + */ + oneway void startHandover(in int serial, in int callId); + + /** + * Start a Keepalive session (for IPsec) + * + * @param serial Serial number of request. + * @param keepalive A request structure containing all necessary info to describe a keepalive + * + * Response function is IRadioResponse.startKeepaliveResponse() + */ + oneway void startKeepalive(in int serial, in KeepaliveRequest keepalive); + + /** + * Start Link Capacity Estimate (LCE) service if supported by the radio. + * + * @param serial Serial number of request. + * @param reportInterval desired reporting interval (ms). + * @param pullMode LCE service mode. true: PULL; false: PUSH. + * + * Response callback is IRadioResponse.startLceServiceResponse() + * + * DEPRECATED in @1.2 or higher which use the always-on LCE that relies on indications. + */ + oneway void startLceService(in int serial, in int reportInterval, in boolean pullMode); + + /** + * Starts a network scan. + * + * @param serial Serial number of request. + * @param request Defines the radio networks/bands/channels which need to be scanned. + * + * Response function is IRadioResponse.startNetworkScanResponse() + */ + oneway void startNetworkScan(in int serial, in NetworkScanRequest request); + + /** + * Stop playing a currently playing DTMF tone. + * + * @param serial Serial number of request. + * + * Response function is IRadioResponse.stopDtmfResponse() + */ + oneway void stopDtmf(in int serial); + + /** + * Stop an ongoing Keepalive session (for IPsec) + * + * @param serial Serial number of request. + * @param sessionHandle The handle that was provided by IRadioResponse.startKeepaliveResponse + * + * Response function is IRadioResponse.stopKeepaliveResponse() + */ + oneway void stopKeepalive(in int serial, in int sessionHandle); + + /** + * Stop Link Capacity Estimate (LCE) service, the STOP operation must be idempotent for the + * radio modem. + * + * @param serial Serial number of request. + * + * Response callback is IRadioResponse.stopLceServiceResponse() + * + * DEPRECATED in @1.2 or higher which use the always-on LCE that relies on indications. + */ + oneway void stopLceService(in int serial); + + /** + * Stops ongoing network scan + * + * @param serial Serial number of request. + * + * Response function is IRadioResponse.stopNetworkScanResponse() + */ + oneway void stopNetworkScan(in int serial); + + /** + * Supplies ICC PIN2. Only called following operation where SIM_PIN2 was returned as a failure + * from a previous operation. + * + * @param serial Serial number of request. + * @param pin2 PIN2 value + * @param aid AID value, See ETSI 102.221 8.1 and 101.220 4, empty string if no value. + * + * Response function is IRadioResponse.supplyIccPin2ForAppResponse() + */ + oneway void supplyIccPin2ForApp(in int serial, in String pin2, in String aid); + + /** + * Supplies ICC PIN. Only called if CardStatus has AppState.PIN state + * + * @param serial Serial number of request. + * @param pin PIN value + * @param aid AID value, See ETSI 102.221 8.1 and 101.220 4, empty string if no value. + * + * Response function is IRadioResponse.supplyIccPinForAppResponse() + */ + oneway void supplyIccPinForApp(in int serial, in String pin, in String aid); + + /** + * Supplies ICC PUK2 and new PIN2. + * + * @param serial Serial number of request. + * @param puk2 PUK2 value + * @param pin2 New PIN2 value + * @param aid AID value, See ETSI 102.221 8.1 and 101.220 4, empty string if no value. + * + * Response function is IRadioResponse.supplyIccPuk2ForAppResponse() + */ + oneway void supplyIccPuk2ForApp(in int serial, in String puk2, in String pin2, in String aid); + + /** + * Supplies ICC PUK and new PIN. + * + * @param serial Serial number of request. + * @param puk PUK value + * @param pin New PIN value + * @param aid AID value, See ETSI 102.221 8.1 and 101.220 4, empty string if no value. + * + * Response function is IRadioResponse.supplyIccPukForAppResponse() + */ + oneway void supplyIccPukForApp(in int serial, in String puk, in String pin, in String aid); + + /** + * Requests that network personalization be deactivated + * + * @param serial Serial number of request. + * @param netPin Network depersonlization code + * + * Response function is IRadioResponse.supplyNetworkDepersonalizationResponse() + */ + oneway void supplyNetworkDepersonalization(in int serial, in String netPin); + + /** + * Request that deactivates one category of device personalization. Device personalization + * generally binds the device so it can only be used on one carrier or even one carrier subnet + * (See TS 22.022). When the user has gained the rights to unbind the device (at the end of a + * contract period or other event), the controlKey will be delivered to either the user for + * manual entry or to a carrier app on the device for automatic entry. + * + * @param serial Serial number of request. + * @param persoType SIM personalization type. + * @param controlKey the unlock code for removing persoType personalization from this device + * + * Response function is IRadioResponse.supplySimDepersonalizationResponse() + */ + oneway void supplySimDepersonalization( + in int serial, in PersoSubstate persoType, in String controlKey); + + /** + * Switch waiting or holding call and active call (like AT+CHLD=2). + * Call transitions must happen as shown below. + * BEFORE AFTER + * Call 1 Call 2 Call 1 Call 2 + * ACTIVE HOLDING HOLDING ACTIVE + * ACTIVE WAITING HOLDING ACTIVE + * HOLDING WAITING HOLDING ACTIVE + * ACTIVE IDLE HOLDING IDLE + * IDLE IDLE IDLE IDLE + * + * @param serial Serial number of request. + * + * Response function is IRadioResponse.switchWaitingOrHoldingAndActiveResponse() + */ + oneway void switchWaitingOrHoldingAndActive(in int serial); + + /** + * Insert, delete or update a phonebook record on the SIM card. If the index of recordInfo is 0, + * the phonebook record will be added to global or local phonebook, and global phonebook has + * higher priority than local phonebook. If the fields in the recordInfo are all empty except + * for the index, the phonebook record specified by the index will be deleted. The indication + * simPhonebookChanged will be called after every successful call of updateSimPhonebookRecords. + * + * @param serial Serial number of request. + * @param recordInfo Details of the record to insert, delete or update. + * + * Response callback is IRadioResponse.updateSimPhonebookRecordsResponse() + */ + oneway void updateSimPhonebookRecords(in int serial, in PhonebookRecordInfo recordInfo); + + /** + * Stores a CDMA SMS message to RUIM memory. + * + * @param serial Serial number of request. + * @param cdmaSms CDMA message as defined by CdmaSmsWriteArgs in types.hal + * + * Response callback is IRadioResponse.writeSmsToRuimResponse() + */ + oneway void writeSmsToRuim(in int serial, in CdmaSmsWriteArgs cdmaSms); + + /** + * Stores a SMS message to SIM memory. + * + * @param serial Serial number of request. + * @param smsWriteArgs SmsWriteArgs defined in types.hal + * + * Response function is IRadioResponse.writeSmsToSimResponse() + */ + oneway void writeSmsToSim(in int serial, in SmsWriteArgs smsWriteArgs); +} diff --git a/radio/aidl/android/hardware/radio/IRadioIndication.aidl b/radio/aidl/android/hardware/radio/IRadioIndication.aidl new file mode 100644 index 0000000000..054a53ef98 --- /dev/null +++ b/radio/aidl/android/hardware/radio/IRadioIndication.aidl @@ -0,0 +1,632 @@ +/* + * 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.radio; + +import android.hardware.radio.BarringInfo; +import android.hardware.radio.CdmaCallWaiting; +import android.hardware.radio.CdmaInformationRecords; +import android.hardware.radio.CdmaOtaProvisionStatus; +import android.hardware.radio.CdmaSignalInfoRecord; +import android.hardware.radio.CdmaSmsMessage; +import android.hardware.radio.CdmaSubscriptionSource; +import android.hardware.radio.CellIdentity; +import android.hardware.radio.CellInfo; +import android.hardware.radio.Domain; +import android.hardware.radio.EmergencyNumber; +import android.hardware.radio.HardwareConfig; +import android.hardware.radio.KeepaliveStatus; +import android.hardware.radio.LceDataInfo; +import android.hardware.radio.LinkCapacityEstimate; +import android.hardware.radio.NetworkScanResult; +import android.hardware.radio.PbReceivedStatus; +import android.hardware.radio.PcoDataInfo; +import android.hardware.radio.PhoneRestrictedState; +import android.hardware.radio.PhonebookRecordInfo; +import android.hardware.radio.PhysicalChannelConfig; +import android.hardware.radio.RadioCapability; +import android.hardware.radio.RadioIndicationType; +import android.hardware.radio.RadioState; +import android.hardware.radio.RadioTechnology; +import android.hardware.radio.SetupDataCallResult; +import android.hardware.radio.SignalStrength; +import android.hardware.radio.SimRefreshResult; +import android.hardware.radio.SrvccState; +import android.hardware.radio.StkCcUnsolSsResult; +import android.hardware.radio.SuppSvcNotification; +import android.hardware.radio.UssdModeType; + +/** + * Interface declaring unsolicited radio indications. + */ +@VintfStability +interface IRadioIndication { + /** + * Indicate barring information for the user’s access category / access class and PLMN. + * + *

    Provide information about the barring status of the cell for the user. The information + * provided should describe all barring configurations that are applicable to the current user, + * even if the user is not currently barred (due to conditional barring). This informs Android + * of likely future (statistical) barring for specific services. + * + *

    This indication should be sent whenever the cell’s barring config changes for the current + * user, or if the user’s conditional barring status changes due to re-evaluation of the + * barring conditions. Barring status will likely change when the device camps for service, + * when PLMN selection is completed, when the device attempts to access a conditionally barred + * service, and when the System Information including barring info for a camped cell is updated. + */ + oneway void barringInfoChanged(in RadioIndicationType type, in CellIdentity cellIdentity, + in BarringInfo[] barringInfos); + + /** + * Ring indication for an incoming call (eg, RING or CRING event). There must be at least one + * callRing() at the beginning of a call and sending multiple is optional. If the system + * property ro.telephony.call_ring.multiple is false then the upper layers must generate the + * multiple events internally. Otherwise the vendor code must generate multiple callRing() if + * ro.telephony.call_ring.multiple is true or if it is absent. + * The rate of these events is controlled by ro.telephony.call_ring.delay and has a default + * value of 3000 (3 seconds) if absent. + * + * @param type Type of radio indication + * @param isGsm true for GSM & false for CDMA + * @param record Cdma Signal Information + */ + oneway void callRing( + in RadioIndicationType type, in boolean isGsm, in CdmaSignalInfoRecord record); + + /** + * Indicates when call state has changed. Callee must invoke IRadio.getCurrentCalls(). Must be + * invoked on, for example, "RING", "BUSY", "NO CARRIER", and also call state transitions + * (DIALING->ALERTING ALERTING->ACTIVE). Redundent or extraneous invocations are tolerated. + * + * @param type Type of radio indication + */ + oneway void callStateChanged(in RadioIndicationType type); + + /** + * Indicates that the modem requires the Carrier info for IMSI/IMPI encryption. This might + * happen when the modem restarts or for some reason it's cache has been invalidated. + * + * @param type Type of radio indication + */ + oneway void carrierInfoForImsiEncryption(in RadioIndicationType info); + + /** + * Indicates when CDMA radio receives a call waiting indication. + * + * @param type Type of radio indication + * @param callWaitingRecord Cdma CallWaiting information + */ + oneway void cdmaCallWaiting(in RadioIndicationType type, in CdmaCallWaiting callWaitingRecord); + + /** + * Indicates when CDMA radio receives one or more info recs. + * + * @param type Type of radio indication + * @param records New Cdma Information + */ + oneway void cdmaInfoRec(in RadioIndicationType type, in CdmaInformationRecords records); + + /** + * Indicates when new CDMA SMS is received. Callee must subsequently confirm the receipt of the + * SMS with acknowledgeLastIncomingCdmaSms(). Server must not send cdmaNewSms() messages until + * acknowledgeLastIncomingCdmaSms() has been received. + * + * @param type Type of radio indication + * @param msg Cdma Sms Message + */ + oneway void cdmaNewSms(in RadioIndicationType type, in CdmaSmsMessage msg); + + /** + * Indicates when CDMA radio receives an update of the progress of an OTASP/OTAPA call. + * + * @param type Type of radio indication + * @param status Cdma OTA provision status + */ + oneway void cdmaOtaProvisionStatus( + in RadioIndicationType type, in CdmaOtaProvisionStatus status); + + /** + * Indicates when PRL (preferred roaming list) changes. + * + * @param type Type of radio indication + * @param version PRL version after PRL changes + */ + oneway void cdmaPrlChanged(in RadioIndicationType type, in int version); + + /** + * Indicates that SMS storage on the RUIM is full. Messages cannot be saved on the RUIM until + * space is freed. + * + * @param type Type of radio indication + */ + oneway void cdmaRuimSmsStorageFull(in RadioIndicationType type); + + /** + * Indicates when CDMA subscription source changed. + * + * @param type Type of radio indication + * @param cdmaSource New Cdma SubscriptionSource + */ + oneway void cdmaSubscriptionSourceChanged( + in RadioIndicationType type, in CdmaSubscriptionSource cdmaSource); + + /** + * Report all of the current cell information known to the radio. + * + * @param type Type of radio indication + * @param records Current cell information + */ + oneway void cellInfoList(in RadioIndicationType type, in CellInfo[] records); + + /** + * Report the current list of emergency numbers. Each emergency number in the emergency number + * list contains a dialing number, zero or more service category(s), zero or more emergency + * uniform resource names, mobile country code, mobile network code, and source(s) that indicate + * where it comes from. + * Radio must report all the valid emergency numbers with known mobile country code, mobile + * network code, emergency service categories, and emergency uniform resource names from all + * available sources including network signaling, sim, modem/oem configuration, and default + * configuration (112 and 911 must be always available; additionally, 000, 08, 110, 999, 118 + * and 119 must be available when sim is not present). Radio shall not report emergency numbers + * that are invalid in the current locale. The reported emergency number list must not have + * duplicate EmergencyNumber entries. Please refer the documentation of EmergencyNumber to + * construct each emergency number to report. + * Radio must report the complete list of emergency numbers whenever the emergency numbers in + * the list are changed or whenever the client and the radio server are connected. + * + * Reference: 3gpp 22.101, Section 10 - Emergency Calls; + * 3gpp 24.008, Section 9.2.13.4 - Emergency Number List + * + * @param type Type of radio indication + * @param emergencyNumberList Current list of emergency numbers known to radio. + */ + oneway void currentEmergencyNumberList( + in RadioIndicationType type, in EmergencyNumber[] emergencyNumberList); + + /** + * Indicates current link capacity estimate. This indication is sent whenever the reporting + * criteria, as set by IRadio.setLinkCapacityReportingCriteria, are met and the indication is + * not suppressed by IRadio.setIndicationFilter(). + * + * @param type Type of radio indication + * @param lce LinkCapacityEstimate + */ + oneway void currentLinkCapacityEstimate( + in RadioIndicationType type, in LinkCapacityEstimate lce); + + /** + * Indicates physical channel configurations. An empty configs list shall be returned when the + * radio is in idle mode (i.e. RRC idle). + * + * @param type Type of radio indication + * @param configs Vector of PhysicalChannelConfigs + */ + oneway void currentPhysicalChannelConfigs( + in RadioIndicationType type, in PhysicalChannelConfig[] configs); + + /** + * Indicates current signal strength of the radio. + * + * @param type Type of radio indication + * @param signalStrength SignalStrength information + */ + oneway void currentSignalStrength( + in RadioIndicationType type, in SignalStrength signalStrength); + + /** + * Indicates data call contexts have changed. + * + * @param type Type of radio indication + * @param dcList Array of SetupDataCallResult identical to that returned by + * IRadio.getDataCallList(). It is the complete list of current data contexts including + * new contexts that have been activated. A data call is only removed from this list + * when any of the below conditions is matched: + * - The framework sends a IRadio.deactivateDataCall(). + * - The radio is powered off/on. + * - Unsolicited disconnect from either modem or network side. + */ + oneway void dataCallListChanged(in RadioIndicationType type, in SetupDataCallResult[] dcList); + + /** + * Indicates that the radio system selection module has autonomously entered emergency + * callback mode. + * + * @param type Type of radio indication + */ + oneway void enterEmergencyCallbackMode(in RadioIndicationType type); + + /** + * Indicates when Emergency Callback Mode Ends. Indicates that the radio system selection module + * has proactively exited emergency callback mode. + * + * @param type Type of radio indication + */ + oneway void exitEmergencyCallbackMode(in RadioIndicationType type); + + /** + * Indicates when the hardware configuration associated with the RILd changes. + * + * @param type Type of radio indication + * @param configs Array of hardware configs + */ + oneway void hardwareConfigChanged(in RadioIndicationType type, in HardwareConfig[] configs); + + /** + * Indicates when IMS registration state has changed. To get IMS registration state and IMS SMS + * format, callee needs to invoke getImsRegistrationState(). + * + * @param type Type of radio indication + */ + oneway void imsNetworkStateChanged(in RadioIndicationType type); + + /** + * Indicates that nework doesn't have in-band information, need to play out-band tone. + * + * @param type Type of radio indication + * @param start true = start play ringback tone, false = stop playing ringback tone + */ + oneway void indicateRingbackTone(in RadioIndicationType type, in boolean start); + + /** + * Indicates a status update for a particular Keepalive session. This must include a handle for + * a previous session and should include a status update regarding the state of a keepalive. + * Unsolicited keepalive status reports should never be PENDING as unsolicited status should + * only be sent when known. + * + * @param type Type of radio indication + * @param status Status information for a Keepalive session + */ + oneway void keepaliveStatus(in RadioIndicationType type, in KeepaliveStatus status); + + /** + * Indicates when there is an incoming Link Capacity Estimate (LCE) info report. + * + * @param type Type of radio indication + * @param lce LceData information + * + * DEPRECATED in @1.2 and above, use IRadioIndication.currentLinkCapacityEstimate() instead. + */ + oneway void lceData(in RadioIndicationType type, in LceDataInfo lce); + + /** + * Indicates when there is a modem reset. + * When modem restarts, one of the following radio state transitions must happen + * 1) RadioState:ON->RadioState:UNAVAILABLE->RadioState:ON or + * 2) RadioState:OFF->RadioState:UNAVAILABLE->RadioState:OFF + * This message must be sent either just before the Radio State changes to + * RadioState:UNAVAILABLE or just after but must never be sent after the Radio State changes + * from RadioState:UNAVAILABLE to RadioState:ON/RadioState:OFF again. It must NOT be sent after + * the Radio state changes to RadioState:ON/RadioState:OFF after the modem restart as that may + * be interpreted as a second modem reset by the framework. + * + * @param type Type of radio indication + * @param reason the reason for the reset. It may be a crash signature if the restart was due to + * a crash or some string such as "user-initiated restart" or "AT command initiated + * restart" that explains the cause of the modem restart + */ + oneway void modemReset(in RadioIndicationType type, in String reason); + + /** + * Incremental network scan results. + * + * @param type Type of radio indication + * @param result the result of the network scan + */ + oneway void networkScanResult(in RadioIndicationType type, in NetworkScanResult result); + + /** + * Indicates when voice or data network state changed. Callee must invoke + * IRadio.getVoiceRegistrationState(), IRadio.getDataRegistrationState(), and + * IRadio.getOperator() + * + * @param type Type of radio indication + */ + oneway void networkStateChanged(in RadioIndicationType type); + + /** + * Indicates when new Broadcast SMS is received + * + * @param type Type of radio indication + * @param data If received from GSM network, "data" is byte array of 88 bytes which indicates + * each page of a CBS Message sent to the MS by the BTS as coded in 3GPP 23.041 Section + * 9.4.1.2. If received from UMTS network, "data" is byte array of 90 up to 1252 bytes + * which contain between 1 and 15 CBS Message pages sent as one packet to the MS by the + * BTS as coded in 3GPP 23.041 Section 9.4.2.2 + */ + oneway void newBroadcastSms(in RadioIndicationType type, in byte[] data); + + /** + * Indicates when new SMS is received. Callee must subsequently confirm the receipt of the SMS + * with a acknowledgeLastIncomingGsmSms(). Server must not send newSms() or newSmsStatusReport() + * messages until an acknowledgeLastIncomingGsmSms() has been received. + * + * @param type Type of radio indication + * @param pdu PDU of SMS-DELIVER represented as byte array. + * The PDU starts with the SMSC address per TS 27.005 (+CMT:) + */ + oneway void newSms(in RadioIndicationType type, in byte[] pdu); + + /** + * Indicates when new SMS has been stored on SIM card + * + * @param type Type of radio indication + * @param recordNumber Record number on the sim + */ + oneway void newSmsOnSim(in RadioIndicationType type, in int recordNumber); + + /** + * Indicates when new SMS Status Report is received. Callee must subsequently confirm the + * receipt of the SMS with a acknowledgeLastIncomingGsmSms(). Server must not send newSms() or + * newSmsStatusReport() messages until an acknowledgeLastIncomingGsmSms() has been received + * + * @param type Type of radio indication + * @param pdu PDU of SMS-STATUS-REPORT represented as byte array. + * The PDU starts with the SMSC address per TS 27.005 (+CMT:) + */ + oneway void newSmsStatusReport(in RadioIndicationType type, in byte[] pdu); + + /** + * Indicates when radio has received a NITZ time message. + * + * @param type Type of radio indication + * @param nitzTime NITZ time string in the form "yy/mm/dd,hh:mm:ss(+/-)tz,dt" + * @param receivedTime milliseconds since boot that the NITZ time was received + */ + oneway void nitzTimeReceived( + in RadioIndicationType type, in String nitzTime, in long receivedTime); + + /** + * Indicates when Supplementary service(SS) response is received when DIAL/USSD/SS is changed to + * SS by call control. + * + * @param type Type of radio indication + */ + oneway void onSupplementaryServiceIndication( + in RadioIndicationType type, in StkCcUnsolSsResult ss); + + /** + * Indicates when a new USSD message is received. The USSD session is assumed to persist if the + * type code is REQUEST, otherwise the current session (if any) is assumed to have terminated. + * + * @param type Type of radio indication + * @param modeType USSD type code + * @param msg Message string in UTF-8, if applicable + */ + oneway void onUssd(in RadioIndicationType type, in UssdModeType modeType, in String msg); + + /** + * Indicates when there is new Carrier PCO data received for a data call. Ideally only new data + * must be forwarded, though this is not required. Multiple boxes of carrier PCO data for a + * given call must result in a series of pcoData() calls. + * + * @param type Type of radio indication + * @param pco New PcoData + */ + oneway void pcoData(in RadioIndicationType type, in PcoDataInfo pco); + + /** + * Sent when setRadioCapability() completes. Returns the phone radio capability exactly as + * getRadioCapability() and must be the same set as sent by setRadioCapability(). + * + * @param type Type of radio indication + * @param rc Current radio capability + */ + oneway void radioCapabilityIndication(in RadioIndicationType type, in RadioCapability rc); + + /** + * Indicates when radio state changes. + * + * @param type Type of radio indication + * @param radioState Current radio state + */ + oneway void radioStateChanged(in RadioIndicationType type, in RadioState radioState); + + /** + * Report that Registration or a Location/Routing/Tracking Area update has failed. + * + *

    Indicate whenever a registration procedure, including a location, routing, or tracking + * area update fails. This includes procedures that do not necessarily result in a change of + * the modem's registration status. If the modem's registration status changes, that is + * reflected in the onNetworkStateChanged() and subsequent get{Voice/Data}RegistrationState(). + * + * @param cellIdentity the CellIdentity, which must include the globally unique identifier for + * the cell (for example, all components of the CGI or ECGI). + * @param chosenPlmn a 5 or 6 digit alphanumeric PLMN (MCC|MNC) among those broadcast by the + * cell that was chosen for the failed registration attempt. + * @param domain Domain::CS, Domain::PS, or both in case of a combined procedure. + * @param causeCode the primary failure cause code of the procedure. + * For GSM/UMTS (MM), values are in TS 24.008 Sec 10.5.95 + * For GSM/UMTS (GMM), values are in TS 24.008 Sec 10.5.147 + * For LTE (EMM), cause codes are TS 24.301 Sec 9.9.3.9 + * For NR (5GMM), cause codes are TS 24.501 Sec 9.11.3.2 + * MAX_INT if this value is unused. + * @param additionalCauseCode the cause code of any secondary/combined procedure if appropriate. + * For UMTS, if a combined attach succeeds for PS only, then the GMM cause code shall be + * included as an additionalCauseCode. + * For LTE (ESM), cause codes are in TS 24.301 9.9.4.4 + * MAX_INT if this value is unused. + */ + oneway void registrationFailed(in RadioIndicationType type, in CellIdentity cellIdentity, + in String chosenPlmn, in Domain domain, in int causeCode, in int additionalCauseCode); + + /** + * Indicates that framework/application must reset the uplink mute state. + * + * @param type Type of radio indication + */ + oneway void resendIncallMute(in RadioIndicationType type); + + /** + * Indicates a restricted state change (eg, for Domain Specific Access Control). + * Radio must send this msg after radio off/on cycle no matter it is changed or not. + * + * @param type Type of radio indication + * @param state Bitmask of restricted state as defined by PhoneRestrictedState + */ + oneway void restrictedStateChanged(in RadioIndicationType type, in PhoneRestrictedState state); + + /** + * Indicates the ril connects and returns the version + * + * @param type Type of radio indication + */ + oneway void rilConnected(in RadioIndicationType type); + + /** + * Indicates whether SIM phonebook is changed. This indication is sent whenever the SIM + * phonebook is changed, including SIM is inserted or removed and updated by + * IRadio.updateSimPhonebookRecords. + * + * @param type Type of radio indication + */ + oneway void simPhonebookChanged(in RadioIndicationType type); + + /** + * Indicates the content of all the used records in the SIM phonebook. This indication is + * associated with the API getSimPhonebookRecords and might be received more than once that is + * replying on the record count. + * + * @param type Type of radio indication + * @param status Status of PbReceivedStatus + * @param records Vector of PhonebookRecordInfo + */ + oneway void simPhonebookRecordsReceived(in RadioIndicationType type, in PbReceivedStatus status, + in PhonebookRecordInfo[] records); + + /** + * Indicates that file(s) on the SIM have been updated, or the SIM has been reinitialized. + * If the SIM state changes as a result of the SIM refresh (eg, SIM_READY -> + * SIM_LOCKED_OR_ABSENT), simStatusChanged() must be sent. + * + * @param type Type of radio indication + * @param refreshResult Result of sim refresh + */ + oneway void simRefresh(in RadioIndicationType type, in SimRefreshResult refreshResult); + + /** + * Indicates that SMS storage on the SIM is full. Sent when the network attempts to deliver a + * new SMS message. Messages cannot be saved on the SIM until space is freed. In particular, + * incoming Class 2 messages must not be stored. + * + * @param type Type of radio indication + */ + oneway void simSmsStorageFull(in RadioIndicationType type); + + /** + * Indicates that SIM state changes. Callee must invoke getIccCardStatus(). + * + * @param type Type of radio indication + */ + oneway void simStatusChanged(in RadioIndicationType type); + + /** + * Indicates when Single Radio Voice Call Continuity (SRVCC) progress state has changed. + * + * @param type Type of radio indication + * @param state New Srvcc State + */ + oneway void srvccStateNotify(in RadioIndicationType type, in SrvccState state); + + /** + * Indicates when there is an ALPHA from UICC during Call Control. + * + * @param type Type of radio indication + * @param alpha ALPHA string from UICC in UTF-8 format + */ + oneway void stkCallControlAlphaNotify(in RadioIndicationType type, in String alpha); + + /** + * Indicates when SIM wants application to setup a voice call. + * + * @param type Type of radio indication + * @param timeout Timeout value in millisec for setting up voice call + */ + oneway void stkCallSetup(in RadioIndicationType type, in long timeout); + + /** + * Indicates when SIM notifies applcations some event happens. + * + * @param type Type of radio indication + * @param cmd SAT/USAT commands or responses sent by ME to SIM or commands handled by ME, + * represented as byte array starting with first byte of response data for command tag. + * Refer to TS 102.223 section 9.4 for command types + */ + oneway void stkEventNotify(in RadioIndicationType type, in String cmd); + + /** + * Indicates when SIM issue a STK proactive command to applications + * + * @param type Type of radio indication + * @param cmd SAT/USAT proactive represented as byte array starting with command tag. + * Refer to TS 102.223 section 9.4 for command types + */ + oneway void stkProactiveCommand(in RadioIndicationType type, in String cmd); + + /** + * Indicates when STK session is terminated by SIM. + * + * @param type Type of radio indication + */ + oneway void stkSessionEnd(in RadioIndicationType type); + + /** + * Indicated when there is a change in subscription status. + * This event must be sent in the following scenarios + * - subscription readiness at modem, which was selected by telephony layer + * - when subscription is deactivated by modem due to UICC card removal + * - when network invalidates the subscription i.e. attach reject due to authentication reject + * + * @param type Type of radio indication + * @param activate false for subscription deactivated, true for subscription activated + */ + oneway void subscriptionStatusChanged(in RadioIndicationType type, in boolean activate); + + /** + * Reports supplementary service related notification from the network. + * + * @param type Type of radio indication + * @param suppSvc SuppSvcNotification as defined in types.hal + */ + oneway void suppSvcNotify(in RadioIndicationType type, in SuppSvcNotification suppSvc); + + /** + * Report change of whether uiccApplications are enabled, or disabled. + * + * @param type Type of radio indication + * @param enabled whether uiccApplications are enabled, or disabled + */ + oneway void uiccApplicationsEnablementChanged(in RadioIndicationType type, in boolean enabled); + + /** + * The modem can explicitly set SetupDataCallResult::suggestedRetryTime after a failure in + * IRadio.SetupDataCall. During that time, no new calls are allowed to IRadio.SetupDataCall that + * use the same APN. When IRadioIndication.unthrottleApn is sent, AOSP will no longer throttle + * calls to IRadio.SetupDataCall for the given APN. + * + * @param type Type of radio indication + * @param apn Apn to unthrottle + */ + oneway void unthrottleApn(in RadioIndicationType type, in String apn); + + /** + * Indicates that voice technology has changed. Responds with new rat. + * + * @param type Type of radio indication + * @param rat Current new voice rat + */ + oneway void voiceRadioTechChanged(in RadioIndicationType type, in RadioTechnology rat); +} diff --git a/radio/aidl/android/hardware/radio/IRadioResponse.aidl b/radio/aidl/android/hardware/radio/IRadioResponse.aidl new file mode 100644 index 0000000000..9ae6495aa5 --- /dev/null +++ b/radio/aidl/android/hardware/radio/IRadioResponse.aidl @@ -0,0 +1,3055 @@ +/* + * 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.radio; + +import android.hardware.radio.ActivityStatsInfo; +import android.hardware.radio.BarringInfo; +import android.hardware.radio.Call; +import android.hardware.radio.CallForwardInfo; +import android.hardware.radio.CardStatus; +import android.hardware.radio.CarrierRestrictions; +import android.hardware.radio.CarrierRestrictionsWithPriority; +import android.hardware.radio.CdmaBroadcastSmsConfigInfo; +import android.hardware.radio.CdmaRoamingType; +import android.hardware.radio.CdmaSubscriptionSource; +import android.hardware.radio.CellIdentity; +import android.hardware.radio.CellInfo; +import android.hardware.radio.ClipStatus; +import android.hardware.radio.DataRegStateResult; +import android.hardware.radio.GsmBroadcastSmsConfigInfo; +import android.hardware.radio.HardwareConfig; +import android.hardware.radio.IccIoResult; +import android.hardware.radio.KeepaliveStatus; +import android.hardware.radio.LastCallFailCauseInfo; +import android.hardware.radio.LceDataInfo; +import android.hardware.radio.LceStatusInfo; +import android.hardware.radio.NeighboringCell; +import android.hardware.radio.OperatorInfo; +import android.hardware.radio.PersoSubstate; +import android.hardware.radio.PhonebookCapacity; +import android.hardware.radio.PreferredNetworkType; +import android.hardware.radio.RadioAccessFamily; +import android.hardware.radio.RadioAccessSpecifier; +import android.hardware.radio.RadioBandMode; +import android.hardware.radio.RadioCapability; +import android.hardware.radio.RadioResponseInfo; +import android.hardware.radio.RadioTechnology; +import android.hardware.radio.RadioTechnologyFamily; +import android.hardware.radio.RegStateResult; +import android.hardware.radio.SendSmsResult; +import android.hardware.radio.SetupDataCallResult; +import android.hardware.radio.SignalStrength; +import android.hardware.radio.SimLockMultiSimPolicy; +import android.hardware.radio.SlicingConfig; +import android.hardware.radio.TtyMode; +import android.hardware.radio.VoiceRegStateResult; + +/** + * Interface declaring response functions to solicited radio requests. + */ +@VintfStability +interface IRadioResponse { + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_STATE + * RadioError:NO_MEMORY + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:INVALID_CALL_ID + * RadioError:INVALID_ARGUMENTS + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + oneway void acceptCallResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:REQUEST_NOT_SUPPORTED + */ + oneway void acknowledgeIncomingGsmSmsWithPduResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_SMS_TO_ACK + * RadioError:INVALID_STATE + * RadioError:NO_MEMORY + * RadioError:REQUEST_RATE_LIMITED + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:NETWORK_NOT_READY + * RadioError:INVALID_MODEM_STATE + * RadioError:INTERNAL_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + oneway void acknowledgeLastIncomingCdmaSmsResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:REQUEST_NOT_SUPPORTED + */ + oneway void acknowledgeLastIncomingGsmSmsResponse(in RadioResponseInfo info); + + /** + * Acknowledge the receipt of radio request sent to the vendor. This must be sent only for + * radio request which take long time to respond. For more details, refer + * https://source.android.com/devices/tech/connect/ril.html + * + * @param serial Serial no. of the request whose acknowledgement is sent. + */ + oneway void acknowledgeRequest(in int serial); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param id The allocated id. On an error, this is set to 0. + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:NO_RESOURCES- Indicates that no pdu session ids are available + * RadioError:REQUEST_NOT_SUPPORTED + */ + oneway void allocatePduSessionIdResponse(in RadioResponseInfo info, in int id); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param enabled whether Uicc applications are enabled. + * + * Valid errors returned: + * RadioError:NONE + * RadioError:SIM_ABSENT + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + */ + oneway void areUiccApplicationsEnabledResponse(in RadioResponseInfo info, in boolean enabled); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param dcResponse Attributes of data call + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:NO_RESOURCES + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_CALL_ID + */ + oneway void cancelHandoverResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SIM_BUSY + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:INVALID_STATE + * RadioError:INVALID_ARGUMENTS + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_MODEM_STATE + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + oneway void cancelPendingUssdResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param remainingRetries Number of retries remaining, must be equal to -1 if unknown. + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE (radio resetting) + * RadioError:PASSWORD_INCORRECT (old PIN2 is invalid) + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:INVALID_ARGUMENTS + * RadioError:INVALID_SIM_STATE + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:SIM_PUK2 + */ + oneway void changeIccPin2ForAppResponse(in RadioResponseInfo info, in int remainingRetries); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param remainingRetries Number of retries remaining, must be equal to -1 if unknown. + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE (radio resetting) + * RadioError:PASSWORD_INCORRECT + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:INVALID_ARGUMENTS + * RadioError:INVALID_SIM_STATE + * RadioError:REQUEST_NOT_SUPPORTED + */ + oneway void changeIccPinForAppResponse(in RadioResponseInfo info, in int remainingRetries); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE (radio resetting) + * RadioError:NO_MEMORY + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:INVALID_STATE + * RadioError:INVALID_CALL_ID + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:INVALID_ARGUMENTS + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_MODEM_STATE + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + oneway void conferenceResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:REQUEST_NOT_SUPPORTED may be returned when HAL 1.2 or higher is supported. + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_CALL_ID + * RadioError:INVALID_STATE + * RadioError:INVALID_ARGUMENTS + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:SIM_ABSENT + */ + oneway void deactivateDataCallResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_MEMORY + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:NO_SUCH_ENTRY + * RadioError:INTERNAL_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:INVALID_MODEM_STATE + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:SIM_ABSENT + */ + oneway void deleteSmsOnRuimResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SIM_FULL + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_MEMORY + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:NO_SUCH_ENTRY + * RadioError:INTERNAL_ERR + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:INVALID_MODEM_STATE + * RadioError:SIM_ABSENT + */ + oneway void deleteSmsOnSimResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE (radio resetting) + * RadioError:DIAL_MODIFIED_TO_USSD + * RadioError:DIAL_MODIFIED_TO_SS + * RadioError:DIAL_MODIFIED_TO_DIAL + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_MEMORY + * RadioError:INVALID_STATE + * RadioError:NO_RESOURCES + * RadioError:INTERNAL_ERR + * RadioError:FDN_CHECK_FAILURE + * RadioError:MODEM_ERR + * RadioError:NO_SUBSCRIPTION + * RadioError:NO_NETWORK_FOUND + * RadioError:INVALID_CALL_ID + * RadioError:DEVICE_IN_USE + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:ABORTED + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_MODEM_STATE + * RadioError:CANCELLED + */ + oneway void dialResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE (radio resetting) + * RadioError:DIAL_MODIFIED_TO_USSD + * RadioError:DIAL_MODIFIED_TO_SS + * RadioError:DIAL_MODIFIED_TO_DIAL + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_RESOURCES + * RadioError:INTERNAL_ERR + * RadioError:FDN_CHECK_FAILURE + * RadioError:MODEM_ERR + * RadioError:NO_SUBSCRIPTION + * RadioError:NO_NETWORK_FOUND + * RadioError:INVALID_CALL_ID + * RadioError:DEVICE_IN_USE + * RadioError:ABORTED + * RadioError:INVALID_MODEM_STATE + */ + oneway void emergencyDialResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:MODEM_ERR + * RadioError:INVALID_STATE: this is for the case that the API is called in a single-sim + * mode, or when there is only one modem available, as this API should only + * be called in multi sim status. + */ + oneway void enableModemResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:SIM_ABSENT + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:BUSY + */ + oneway void enableUiccApplicationsResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:OPERATION_NO_ALLOWED + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:SYSTEM_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:MODEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:SIM_ABSENT + */ + oneway void exitEmergencyCallbackModeResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:INVALID_STATE + * RadioError:NO_RESOURCES + * RadioError:NO_MEMORY + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:INVALID_CALL_ID + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_MODEM_STATE + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + oneway void explicitCallTransferResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param carriers Carrier restriction information. + * @param multiSimPolicy Policy used for devices with multiple SIM cards. + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:REQUEST_NOT_SUPPORTED + */ + oneway void getAllowedCarriersResponse(in RadioResponseInfo info, + in CarrierRestrictionsWithPriority carriers, in SimLockMultiSimPolicy multiSimPolicy); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param networkTypeBitmap a 32-bit bitmap of RadioAccessFamily. + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:MODE_NOT_SUPPORTED + * RadioError:INTERNAL_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:MODEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + */ + oneway void getAllowedNetworkTypesBitmapResponse( + in RadioResponseInfo info, in RadioAccessFamily networkTypeBitmap); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param bandModes List of RadioBandMode listing supported modes + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + oneway void getAvailableBandModesResponse( + in RadioResponseInfo info, in RadioBandMode[] bandModes); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param networkInfos List of network operator information as OperatorInfos defined in + * types.hal + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:ABORTED + * RadioError:DEVICE_IN_USE + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:MODEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:CANCELLED + * RadioError:NO_RESOURCES + * RadioError:INTERNAL_ERR + */ + oneway void getAvailableNetworksResponse( + in RadioResponseInfo info, in OperatorInfo[] networkInfos); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param cellIdentity CellIdentity for the barring infos. + * @param barringInfos a vector of barring info for all barring service types + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:MODEM_ERR + */ + oneway void getBarringInfoResponse( + in RadioResponseInfo info, in CellIdentity cellIdentity, in BarringInfo[] barringInfos); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param version string containing version string for log reporting + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:EMPTY_RECORD + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:NOT_PROVISIONED + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + oneway void getBasebandVersionResponse(in RadioResponseInfo info, in String version); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param mdn MDN if CDMA subscription is available + * @param hSid is a comma separated list of H_SID (Home SID) if CDMA subscription is available, + * in decimal format + * @param hNid is a comma separated list of H_NID (Home NID) if CDMA subscription is available, + * in decimal format + * @param min MIN (10 digits, MIN2+MIN1) if CDMA subscription is available + * @param prl PRL version if CDMA subscription is available + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SUBSCRIPTION_NOT_AVAILABLE + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:MODEM_ERR + * RadioError:NOT_PROVISIONED + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:SIM_ABSENT + */ + oneway void getCDMASubscriptionResponse(in RadioResponseInfo info, in String mdn, + in String hSid, in String hNid, in String min, in String prl); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param callForwardInfos points to a vector of CallForwardInfo, one for each distinct + * registered phone number. For example, if data is forwarded to +18005551212 and voice + * is forwarded to +18005559999, then two separate CallForwardInfo's must be returned. + * However, if both data and voice are forwarded to +18005551212, then a single + * CallForwardInfo must be returned with the service class set to "data + voice = 3". + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SS_MODIFIED_TO_DIAL + * RadioError:SS_MODIFIED_TO_USSD + * RadioError:SS_MODIFIED_TO_SS + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_MEMORY + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:FDN_CHECK_FAILURE + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:SYSTEM_ERR + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + oneway void getCallForwardStatusResponse( + in RadioResponseInfo info, in CallForwardInfo[] callForwardInfos); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param enable If current call waiting state is disabled, enable = false else true + * @param serviceClass If enable, then callWaitingResp[1] must follow, with the TS 27.007 + * service class bit vector of services for which call waiting is enabled. For example, + * if callWaitingResp[0] is 1 and callWaitingResp[1] is 3, then call waiting is enabled + * for data and voice and disabled for everything else. + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SS_MODIFIED_TO_DIAL + * RadioError:SS_MODIFIED_TO_USSD + * RadioError:SS_MODIFIED_TO_SS + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_MEMORY + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:FDN_CHECK_FAILURE + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + oneway void getCallWaitingResponse( + in RadioResponseInfo info, in boolean enable, in int serviceClass); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param configs Vector of CDMA Broadcast SMS configs. + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:INVALID_STATE + * RadioError:NO_MEMORY + * RadioError:REQUEST_RATE_LIMITED + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:NO_RESOURCES + * RadioError:INTERNAL_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:INVALID_MODEM_STATE + */ + oneway void getCdmaBroadcastConfigResponse( + in RadioResponseInfo info, in CdmaBroadcastSmsConfigInfo[] configs); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param type CdmaRoamingType defined in types.hal + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:SIM_ABSENT + */ + oneway void getCdmaRoamingPreferenceResponse( + in RadioResponseInfo info, in CdmaRoamingType type); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param source CDMA subscription source + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SUBSCRIPTION_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:SIM_ABSENT + */ + oneway void getCdmaSubscriptionSourceResponse( + in RadioResponseInfo info, in CdmaSubscriptionSource source); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param cellInfo List of current cell information known to radio + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + */ + oneway void getCellInfoListResponse(in RadioResponseInfo info, in CellInfo[] cellInfo); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param status indicates CLIP status + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_MEMORY + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:FDN_CHECK_FAILURE + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + oneway void getClipResponse(in RadioResponseInfo info, in ClipStatus status); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param n is "n" parameter from TS 27.007 7.7 + * @param m is "m" parameter from TS 27.007 7.7 + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SS_MODIFIED_TO_DIAL + * RadioError:SS_MODIFIED_TO_USSD + * RadioError:SS_MODIFIED_TO_SS + * RadioError:NO_MEMORY + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:FDN_CHECK_FAILURE + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + oneway void getClirResponse(in RadioResponseInfo info, in int n, in int m); + + /** + * @param info Response info struct containing respontype, serial no. and error + * @param calls Current call list + * + * Valid errors returned: + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + oneway void getCurrentCallsResponse(in RadioResponseInfo info, in Call[] calls); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param dcResponse List of SetupDataCallResult as defined in types.hal + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:SIM_ABSENT + */ + oneway void getDataCallListResponse( + in RadioResponseInfo info, in SetupDataCallResult[] dcResponse); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param dataRegResponse Current Data registration response as defined by RegStateResult in + * types.hal + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:NOT_PROVISIONED + */ + oneway void getDataRegistrationStateResponse( + in RadioResponseInfo info, in RegStateResult dataRegResponse); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param imei IMEI if GSM subscription is available + * @param imeisv IMEISV if GSM subscription is available + * @param esn ESN if CDMA subscription is available + * @param meid MEID if CDMA subscription is available + * + * If a empty string value is returned for any of the device id, it means that there was error + * accessing the device. + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:MODEM_ERR + * RadioError:NOT_PROVISIONED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:REQUEST_NOT_SUPPORTED + */ + oneway void getDeviceIdentityResponse(in RadioResponseInfo info, in String imei, + in String imeisv, in String esn, in String meid); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param response 0 is the TS 27.007 service class bit vector of services for which the + * specified barring facility is active. "0" means "disabled for all" + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SS_MODIFIED_TO_DIAL + * RadioError:SS_MODIFIED_TO_USSD + * RadioError:SS_MODIFIED_TO_SS + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_MEMORY + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:FDN_CHECK_FAILURE + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + oneway void getFacilityLockForAppResponse(in RadioResponseInfo info, in int response); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param configs Vector of GSM/WCDMA Cell broadcast configs + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:INVALID_STATE + * RadioError:NO_MEMORY + * RadioError:REQUEST_RATE_LIMITED + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:NO_RESOURCES + * RadioError:INTERNAL_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:INVALID_MODEM_STATE + */ + oneway void getGsmBroadcastConfigResponse( + in RadioResponseInfo info, in GsmBroadcastSmsConfigInfo[] configs); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param config Array of HardwareConfig of the radio. + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:REQUEST_NOT_SUPPORTED + */ + oneway void getHardwareConfigResponse(in RadioResponseInfo info, in HardwareConfig[] config); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param imsi String containing the IMSI + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE (radio resetting) + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:INVALID_SIM_STATE + * RadioError:SIM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + */ + oneway void getIMSIForAppResponse(in RadioResponseInfo info, in String imsi); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param cardStatus ICC card status as defined by CardStatus in types.hal + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:NO_RESOURCES + * RadioError:REQUEST_NOT_SUPPORTED + */ + oneway void getIccCardStatusResponse(in RadioResponseInfo info, in CardStatus cardStatus); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param isRegistered false = not registered, true = registered + * @param ratFamily RadioTechnologyFamily as defined in types.hal. This value is valid only if + * isRegistered is true. + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:INVALID_MODEM_STATE + * RadioError:REQUEST_NOT_SUPPORTED + */ + oneway void getImsRegistrationStateResponse( + in RadioResponseInfo info, in boolean isRegistered, in RadioTechnologyFamily ratFamily); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param failCauseInfo Contains LastCallFailCause and vendor cause code. + * + * The vendor cause code must be used for debugging purpose only. The implementation must return + * one of the values of LastCallFailCause as mentioned below. + * GSM failure reasons codes for the cause codes defined in TS 24.008 Annex H where possible. + * CDMA failure reasons codes for the possible call failure scenarios described in the + * "CDMA IS-2000 Release A (C.S0005-A v6.0)" standard. + * Any of the following reason codes if the call is failed or dropped due to reason mentioned + * with in the braces. + * LastCallFailCause:RADIO_OFF (Radio is OFF) + * LastCallFailCause:OUT_OF_SERVICE (No cell coverage) + * LastCallFailCause:NO_VALID_SIM (No valid SIM) + * LastCallFailCause:RADIO_INTERNAL_ERROR (Modem hit unexpected error scenario) + * LastCallFailCause:NETWORK_RESP_TIMEOUT (No response from network) + * LastCallFailCause:NETWORK_REJECT (Explicit network reject) + * LastCallFailCause:RADIO_ACCESS_FAILURE (RRC connection failure. Eg.RACH) + * LastCallFailCause:RADIO_LINK_FAILURE (Radio Link Failure) + * LastCallFailCause:RADIO_LINK_LOST (Radio link lost due to poor coverage) + * LastCallFailCause:RADIO_UPLINK_FAILURE (Radio uplink failure) + * LastCallFailCause:RADIO_SETUP_FAILURE (RRC connection setup failure) + * LastCallFailCause:RADIO_RELEASE_NORMAL (RRC connection release, normal) + * LastCallFailCause:RADIO_RELEASE_ABNORMAL (RRC connection release, abnormal) + * LastCallFailCause:ACCESS_CLASS_BLOCKED (Access class barring) + * LastCallFailCause:NETWORK_DETACH (Explicit network detach) + * OEM causes (LastCallFailCause:OEM_CAUSE_XX) must be used for debug purpose only + * + * If the implementation does not have access to the exact cause codes, then it must return one + * of the values listed in LastCallFailCause, as the UI layer needs to distinguish these cases + * for tone generation or error notification. + * + * Valid errors returned: + * RadioError:NONE + * RadioError:NO_MEMORY + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SYSTEM_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:INTERNAL_ERR + * RadioError:MODEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + oneway void getLastCallFailCauseResponse( + in RadioResponseInfo info, in LastCallFailCauseInfo failCauseinfo); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param activityInfo modem activity information + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:NOT_PROVISIONED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:REQUEST_NOT_SUPPORTED + */ + oneway void getModemActivityInfoResponse( + in RadioResponseInfo info, in ActivityStatsInfo activityInfo); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:MODEM_ERR + */ + oneway void getModemStackStatusResponse(in RadioResponseInfo info, in boolean isEnabled); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param enable true for "mute enabled" and false for "mute disabled" + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SS_MODIFIED_TO_DIAL + * RadioError:SS_MODIFIED_TO_USSD + * RadioError:SS_MODIFIED_TO_SS + * RadioError:NO_MEMORY + * RadioError:REQUEST_RATE_LIMITED + * RadioError:INVALID_ARGUMENTS + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + oneway void getMuteResponse(in RadioResponseInfo info, in boolean enable); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param cells Vector of neighboring radio cell + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:NO_NETWORK_FOUND + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + oneway void getNeighboringCidsResponse(in RadioResponseInfo info, in NeighboringCell[] cells); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param selection false for automatic selection, true for manual selection + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:MODEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + oneway void getNetworkSelectionModeResponse(in RadioResponseInfo info, in boolean manual); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param longName is long alpha ONS or EONS or empty string if unregistered + * @param shortName is short alpha ONS or EONS or empty string if unregistered + * @param numeric is 5 or 6 digit numeric code (MCC + MNC) or empty string if unregistered + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + oneway void getOperatorResponse( + in RadioResponseInfo info, in String longName, in String shortName, in String numeric); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param networkTypeBitmap a 32-bit bitmap of RadioAccessFamily. + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:MODEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + */ + oneway void getPreferredNetworkTypeBitmapResponse( + in RadioResponseInfo info, in RadioAccessFamily networkTypeBitmap); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param nwType RadioPreferredNetworkType defined in types.hal + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:MODEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + oneway void getPreferredNetworkTypeResponse( + in RadioResponseInfo info, in PreferredNetworkType nwType); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param enable false for Standard Privacy Mode (Public Long Code Mask) + * true for Enhanced Privacy Mode (Private Long Code Mask) + * + * Valid errors: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + oneway void getPreferredVoicePrivacyResponse(in RadioResponseInfo info, in boolean enable); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param rc Radio capability as defined by RadioCapability in types.hal + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:INVALID_STATE + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + oneway void getRadioCapabilityResponse(in RadioResponseInfo info, in RadioCapability rc); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param signalStrength Current signal strength + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + */ + oneway void getSignalStrengthResponse( + in RadioResponseInfo info, in SignalStrength signalStrength); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param capacity Response capacity enum indicating response processing status + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_ARGUMENTS + * RadioError:INVALID_SIM_STATE + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * REQUEST_NOT_SUPPORTED may only be returned on devices that don't support this API, + * indicated by the HAL capability CAPABILITY_SIM_PHONEBOOK_IN_MODEM. + */ + oneway void getSimPhonebookCapacityResponse( + in RadioResponseInfo info, in PhonebookCapacity capacity); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_ARGUMENTS + * RadioError:INVALID_SIM_STATE + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * REQUEST_NOT_SUPPORTED may only be returned on devices that don't support this API, + * indicated by the HAL capability CAPABILITY_SIM_PHONEBOOK_IN_MODEM. + */ + oneway void getSimPhonebookRecordsResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param slicingConfig Current slicing configuration + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:MODEM_ERR + */ + oneway void getSlicingConfigResponse(in RadioResponseInfo info, in SlicingConfig slicingConfig); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param smsc Short Message Service Center address on the device + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_RATE_LIMITED + * RadioError:MODEM_ERR + * RadioError:INVALID_MODEM_STATE + * RadioError:NOT_PROVISIONED + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:SIM_ABSENT + */ + oneway void getSmscAddressResponse(in RadioResponseInfo info, in String smsc); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param specifiers List of RadioAccessSpecifiers that are scanned. + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:INVALID_ARGUMENTS + */ + oneway void getSystemSelectionChannelsResponse( + in RadioResponseInfo info, in RadioAccessSpecifier[] specifiers); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param mode TtyMode + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + oneway void getTTYModeResponse(in RadioResponseInfo info, in TtyMode mode); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param rat Current voice RAT + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:REQUEST_NOT_SUPPORTED + */ + oneway void getVoiceRadioTechnologyResponse(in RadioResponseInfo info, in RadioTechnology rat); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param voiceRegResponse Current Voice registration response as defined by RegStateResult + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + */ + oneway void getVoiceRegistrationStateResponse( + in RadioResponseInfo info, in RegStateResult voiceRegResponse); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:SIM_ABSENT + */ + oneway void handleStkCallSetupRequestFromSimResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE (radio resetting) + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_MEMORY + * RadioError:INVALID_STATE + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:INVALID_CALL_ID + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:REQUEST_NOT_SUPPORTED + */ + oneway void hangupConnectionResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE (radio resetting) + * RadioError:INVALID_STATE + * RadioError:NO_MEMORY + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:INVALID_CALL_ID + * RadioError:NO_RESOURCES + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:INVALID_ARGUMENTS + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + oneway void hangupForegroundResumeBackgroundResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE (radio resetting) + * RadioError:INVALID_STATE + * RadioError:NO_MEMORY + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:INVALID_CALL_ID + * RadioError:NO_RESOURCES + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:INVALID_ARGUMENTS + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:CANCELLED + */ + oneway void hangupWaitingOrBackgroundResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:REQUEST_NOT_SUPPORTED + */ + oneway void iccCloseLogicalChannelResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param iccIo ICC io operation response as defined by IccIoResult in types.hal + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SIM_PIN2 + * RadioError:SIM_PUK2 + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:INVALID_SIM_STATE + * RadioError:SIM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + */ + oneway void iccIOForAppResponse(in RadioResponseInfo info, in IccIoResult iccIo); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param channelId session id of the logical channel. + * @param selectResponse Contains the select response for the open channel command with one + * byte per integer + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:MISSING_RESOURCE + * RadioError:NO_SUCH_ELEMENT + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:SIM_ERR + * RadioError:INVALID_SIM_STATE + * RadioError:MISSING_RESOURCE + * RadioError:REQUEST_NOT_SUPPORTED + */ + oneway void iccOpenLogicalChannelResponse( + in RadioResponseInfo info, in int channelId, in byte[] selectResponse); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param result IccIoResult as defined in types.hal + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:REQUEST_NOT_SUPPORTED + */ + oneway void iccTransmitApduBasicChannelResponse( + in RadioResponseInfo info, in IccIoResult result); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param result IccIoResult as defined in types.hal + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:REQUEST_NOT_SUPPORTED + */ + oneway void iccTransmitApduLogicalChannelResponse( + in RadioResponseInfo info, in IccIoResult result); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param isEnabled Indicates whether NR dual connectivity is enabled or not, True if enabled + * else false. + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:REQUEST_NOT_SUPPORTED + */ + oneway void isNrDualConnectivityEnabledResponse( + in RadioResponseInfo info, in boolean isEnabled); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param result string containing the contents of the NV item + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:REQUEST_NOT_SUPPORTED + */ + oneway void nvReadItemResponse(in RadioResponseInfo info, in String result); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:REQUEST_NOT_SUPPORTED + */ + oneway void nvResetConfigResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:REQUEST_NOT_SUPPORTED + */ + oneway void nvWriteCdmaPrlResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:REQUEST_NOT_SUPPORTED + */ + oneway void nvWriteItemResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param lceInfo LceDataInfo indicating LCE data + * + * Valid errors returned: + * RadioError:REQUEST_NOT_SUPPORTED may be returned when HAL 1.2 or higher is supported. + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:LCE_NOT_SUPPORTED + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:SIM_ABSENT + */ + oneway void pullLceDataResponse(in RadioResponseInfo info, in LceDataInfo lceInfo); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE (radio resetting) + * RadioError:INVALID_STATE + * RadioError:NO_RESOURCES + * RadioError:NO_MEMORY + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:INVALID_CALL_ID + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:INVALID_ARGUMENTS + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_MODEM_STATE + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + oneway void rejectCallResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:NO_RESOURCES + * RadioError:REQUEST_NOT_SUPPORTED + */ + oneway void releasePduSessionIdResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_MEMORY + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_RATE_LIMITED + * RadioError:MODEM_ERR + * RadioError:INVALID_STATE + * RadioError:INTERNAL_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:SIM_ABSENT + */ + oneway void reportSmsMemoryStatusResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:REQUEST_NOT_SUPPORTED + */ + oneway void reportStkServiceIsRunningResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param result IccIoResult as defined in types.hal + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:INVALID_MODEM_STATE + * RadioError:SIM_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:REQUEST_NOT_SUPPORTED + */ + oneway void requestIccSimAuthenticationResponse( + in RadioResponseInfo info, in IccIoResult result); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param response response string of the challenge/response algo for ISIM auth in base64 format + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:INVALID_MODEM_STATE + * RadioError:INVALID_ARGUMENTS + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:SIM_ABSENT + */ + oneway void requestIsimAuthenticationResponse(in RadioResponseInfo info, in String response); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + oneway void requestShutdownResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:INVALID_CALL_ID + * RadioError:INVALID_STATE + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:INVALID_MODEM_STATE + * RadioError:OPERATION_NOT_ALLOWED + */ + oneway void sendBurstDtmfResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:INVALID_CALL_ID + * RadioError:INVALID_STATE + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_MODEM_STATE + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:OPERATION_NOT_ALLOWED + */ + oneway void sendCDMAFeatureCodeResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param sms Response to sms sent as defined by SendSmsResult in types.hal + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SMS_SEND_FAIL_RETRY + * RadioError:NETWORK_REJECT + * RadioError:INVALID_STATE + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_MEMORY + * RadioError:REQUEST_RATE_LIMITED + * RadioError:INVALID_SMS_FORMAT + * RadioError:SYSTEM_ERR + * RadioError:FDN_CHECK_FAILURE + * RadioError:ENCODING_ERR + * RadioError:INVALID_SMSC_ADDRESS + * RadioError:MODEM_ERR + * RadioError:NETWORK_ERR + * RadioError:INTERNAL_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_MODEM_STATE + * RadioError:NETWORK_NOT_READY + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:SIM_ABSENT + * RadioError:SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED + * RadioError:ACCESS_BARRED + * RadioError:BLOCKED_DUE_TO_CALL + */ + oneway void sendCdmaSmsExpectMoreResponse(in RadioResponseInfo info, in SendSmsResult sms); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param sms Sms result struct as defined by SendSmsResult in types.hal + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:SMS_SEND_FAIL_RETRY + * RadioError:NETWORK_REJECT + * RadioError:INVALID_STATE + * RadioError:NO_MEMORY + * RadioError:REQUEST_RATE_LIMITED + * RadioError:INVALID_SMS_FORMAT + * RadioError:SYSTEM_ERR + * RadioError:FDN_CHECK_FAILURE + * RadioError:MODEM_ERR + * RadioError:NETWORK_ERR + * RadioError:ENCODING_ERR + * RadioError:INVALID_SMSC_ADDRESS + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:ENCODING_ERR + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:SIM_ABSENT + * RadioError:SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED + * RadioError:ACCESS_BARRED + * RadioError:BLOCKED_DUE_TO_CALL + */ + oneway void sendCdmaSmsResponse(in RadioResponseInfo info, in SendSmsResult sms); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + oneway void sendDeviceStateResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_RESOURCES + * RadioError:NO_MEMORY + * RadioError:MODEM_ERR + * RadioError:INVALID_CALL_ID + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:CANCELLED + * RadioError:INVALID_MODEM_STATE + */ + oneway void sendDtmfResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param commandResponse SAT/USAT response in hexadecimal format string starting with first + * byte of response + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SIM_BUSY + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:INVALID_ARGUMENTS + * RadioError:MODEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:SIM_ABSENT + */ + oneway void sendEnvelopeResponse(in RadioResponseInfo info, in String commandResponse); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param iccIo IccIoResult as defined in types.hal corresponding to ICC IO response + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SIM_BUSY + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:SIM_ABSENT + */ + oneway void sendEnvelopeWithStatusResponse(in RadioResponseInfo info, in IccIoResult iccIo); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param sms Response to sms sent as defined by SendSmsResult in types.hal + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SMS_SEND_FAIL_RETRY + * RadioError:FDN_CHECK_FAILURE + * RadioError:NETWORK_REJECT + * RadioError:INVALID_ARGUMENTS + * RadioError:INVALID_STATE + * RadioError:NO_MEMORY + * RadioError:INVALID_SMS_FORMAT + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_RATE_LIMITED + * RadioError:MODEM_ERR + * RadioError:NETWORK_ERR + * RadioError:ENCODING_ERR + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:INTERNAL_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NETWORK_NOT_READY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + oneway void sendImsSmsResponse(in RadioResponseInfo info, in SendSmsResult sms); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param sms Response to sms sent as defined by SendSmsResult in types.hal + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SMS_SEND_FAIL_RETRY + * RadioError:NETWORK_REJECT + * RadioError:INVALID_STATE + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_MEMORY + * RadioError:REQUEST_RATE_LIMITED + * RadioError:INVALID_SMS_FORMAT + * RadioError:SYSTEM_ERR + * RadioError:FDN_CHECK_FAILURE + * RadioError:ENCODING_ERR + * RadioError:INVALID_SMSC_ADDRESS + * RadioError:MODEM_ERR + * RadioError:NETWORK_ERR + * RadioError:INTERNAL_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_MODEM_STATE + * RadioError:NETWORK_NOT_READY + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:SIM_ABSENT + */ + oneway void sendSMSExpectMoreResponse(in RadioResponseInfo info, in SendSmsResult sms); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param sms Response to sms sent as defined by SendSmsResult in types.hal + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SMS_SEND_FAIL_RETRY + * RadioError:NETWORK_REJECT + * RadioError:INVALID_STATE + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_MEMORY + * RadioError:REQUEST_RATE_LIMITED + * RadioError:INVALID_SMS_FORMAT + * RadioError:SYSTEM_ERR + * RadioError:FDN_CHECK_FAILURE + * RadioError:ENCODING_ERR + * RadioError:INVALID_SMSC_ADDRESS + * RadioError:MODEM_ERR + * RadioError:NETWORK_ERR + * RadioError:INTERNAL_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_MODEM_STATE + * RadioError:NETWORK_NOT_READY + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:SIM_ABSENT + * RadioError:ACCESS_BARRED + * RadioError:BLOCKED_DUE_TO_CALL + */ + oneway void sendSmsExpectMoreResponse(in RadioResponseInfo info, in SendSmsResult sms); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param sms Response to sms sent as defined by SendSmsResult in types.hal + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SMS_SEND_FAIL_RETRY + * RadioError:NETWORK_REJECT + * RadioError:INVALID_STATE + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_MEMORY + * RadioError:REQUEST_RATE_LIMITED + * RadioError:INVALID_SMS_FORMAT + * RadioError:SYSTEM_ERR + * RadioError:ENCODING_ERR + * RadioError:INVALID_SMSC_ADDRESS + * RadioError:MODEM_ERR + * RadioError:NETWORK_ERR + * RadioError:INTERNAL_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_MODEM_STATE + * RadioError:NETWORK_NOT_READY + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:SIM_ABSENT + * RadioError:ACCESS_BARRED + * RadioError:BLOCKED_DUE_TO_CALL + */ + oneway void sendSmsResponse(in RadioResponseInfo info, in SendSmsResult sms); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:INVALID_MODEM_STATE + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:SIM_ABSENT + */ + oneway void sendTerminalResponseToSimResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:FDN_CHECK_FAILURE + * RadioError:USSD_MODIFIED_TO_DIAL + * RadioError:USSD_MODIFIED_TO_SS + * RadioError:USSD_MODIFIED_TO_USSD + * RadioError:SIM_BUSY + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_MEMORY + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:ABORTED + * RadioError:SYSTEM_ERR + * RadioError:INVALID_STATE + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_MODEM_STATE + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + oneway void sendUssdResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:INVALID_STATE + * RadioError:NO_RESOURCES + * RadioError:NO_MEMORY + * RadioError:MODEM_ERR + * RadioError:SYSTEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:INVALID_CALL_ID + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_MODEM_STATE + * RadioError:CANCELLED + */ + oneway void separateConnectionResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:REQUEST_NOT_SUPPORTED + */ + oneway void setAllowedCarriersResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:MODE_NOT_SUPPORTED + * RadioError:INTERNAL_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:MODEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + */ + oneway void setAllowedNetworkTypesBitmapResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:MODEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + oneway void setBandModeResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SS_MODIFIED_TO_DIAL + * RadioError:SS_MODIFIED_TO_USSD + * RadioError:SS_MODIFIED_TO_SS + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_MEMORY + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:FDN_CHECK_FAILURE + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + oneway void setBarringPasswordResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SS_MODIFIED_TO_DIAL + * RadioError:SS_MODIFIED_TO_USSD + * RadioError:SS_MODIFIED_TO_SS + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_MEMORY + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:INVALID_STATE + * RadioError:FDN_CHECK_FAILURE + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_MODEM_STATE + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + oneway void setCallForwardResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SS_MODIFIED_TO_DIAL + * RadioError:SS_MODIFIED_TO_USSD + * RadioError:SS_MODIFIED_TO_SS + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_MEMORY + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:INVALID_STATE + * RadioError:FDN_CHECK_FAILURE + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_MODEM_STATE + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + oneway void setCallWaitingResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:RIL_E_SUCCESS + * RadioError:RIL_E_RADIO_NOT_AVAILABLE + * RadioError:SIM_ABSENT + * RadioError:RIL_E_REQUEST_NOT_SUPPORTED + * RadioError:INVALID_ARGUMENTS + * RadioError:MODEM_INTERNAL_FAILURE + */ + oneway void setCarrierInfoForImsiEncryptionResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:INVALID_STATE + * RadioError:NO_MEMORY + * RadioError:REQUEST_RATE_LIMITED + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:INVALID_MODEM_STATE + */ + oneway void setCdmaBroadcastActivationResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:INVALID_STATE + * RadioError:NO_MEMORY + * RadioError:REQUEST_RATE_LIMITED + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:INVALID_MODEM_STATE + */ + oneway void setCdmaBroadcastConfigResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:MODEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:SIM_ABSENT + */ + oneway void setCdmaRoamingPreferenceResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SIM_ABSENT + * RadioError:SUBSCRIPTION_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:REQUEST_NOT_SUPPORTED + */ + oneway void setCdmaSubscriptionSourceResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:REQUEST_NOT_SUPPORTED + */ + oneway void setCellInfoListRateResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:INVALID_ARGUMENTS + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SS_MODIFIED_TO_DIAL + * RadioError:SS_MODIFIED_TO_USSD + * RadioError:SS_MODIFIED_TO_SS + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + oneway void setClirResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:DEVICE_IN_USE + * RadioError:INVALID_MODEM_STATE + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:REQUEST_NOT_SUPPORTED + */ + oneway void setDataAllowedResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SUBSCRIPTION_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:SIM_ABSENT + */ + oneway void setDataProfileResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:MODEM_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:REQUEST_NOT_SUPPORTED + */ + oneway void setDataThrottlingResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param retry 0 is the number of retries remaining, or -1 if unknown + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SS_MODIFIED_TO_DIAL + * RadioError:SS_MODIFIED_TO_USSD + * RadioError:SS_MODIFIED_TO_SS + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_MEMORY + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:INVALID_STATE + * RadioError:FDN_CHECK_FAILURE + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_MODEM_STATE + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + oneway void setFacilityLockForAppResponse(in RadioResponseInfo info, in int retry); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:INVALID_STATE + * RadioError:NO_MEMORY + * RadioError:REQUEST_RATE_LIMITED + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:INVALID_MODEM_STATE + */ + oneway void setGsmBroadcastActivationResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:INVALID_STATE + * RadioError:NO_MEMORY + * RadioError:REQUEST_RATE_LIMITED + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:INVALID_MODEM_STATE + */ + oneway void setGsmBroadcastConfigResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:INVALID_ARGUMENTS + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + */ + oneway void setIndicationFilterResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SUBSCRIPTION_NOT_AVAILABLE + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:NOT_PROVISIONED + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + oneway void setInitialAttachApnResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:INVALID_ARGUMENTS + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + */ + oneway void setLinkCapacityReportingCriteriaResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:MODEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:SIM_ABSENT + */ + oneway void setLocationUpdatesResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_MEMORY + * RadioError:REQUEST_RATE_LIMITED + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + oneway void setMuteResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:ILLEGAL_SIM_OR_ME + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:MODEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * + * Returns RadioError:ILLEGAL_SIM_OR_ME when the failure is permanent and + * no retries needed, such as illegal SIM or ME. + */ + oneway void setNetworkSelectionModeAutomaticResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:ILLEGAL_SIM_OR_ME + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:INVALID_STATE + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:MODEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * + * Returns RadioError:ILLEGAL_SIM_OR_ME when the failure is permanent and + * no retries needed, such as illegal SIM or ME. + */ + oneway void setNetworkSelectionModeManualResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_STATE + */ + oneway void setNrDualConnectivityStateResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:MODE_NOT_SUPPORTED + * RadioError:INTERNAL_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:MODEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + */ + oneway void setPreferredNetworkTypeBitmapResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:MODE_NOT_SUPPORTED + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:MODEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + oneway void setPreferredNetworkTypeResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_CALL_ID + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + oneway void setPreferredVoicePrivacyResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param rc Radio capability as defined by RadioCapability in types.hal used to + * feedback return status + * + * Valid errors returned: + * RadioError:NONE means a unsol radioCapability() will be sent within 30 seconds. + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:MODEM_ERR + * RadioError:INVALID_STATE + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + oneway void setRadioCapabilityResponse(in RadioResponseInfo info, in RadioCapability rc); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:INTERNAL_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:RF_HARDWARE_ISSUE + * RadioError:NO_RF_CALIBRATION_INFO + */ + oneway void setRadioPowerResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:INVALID_ARGUMENTS + * RadioError:RADIO_NOT_AVAILABLE + */ + oneway void setSignalStrengthReportingCriteriaResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:SIM_ERR (indicates a timeout or other issue making the SIM unresponsive) + */ + oneway void setSimCardPowerResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:INVALID_SMS_FORMAT + * RadioError:NO_MEMORY + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_RATE_LIMITED + * RadioError:MODEM_ERR + * RadioError:NO_RESOURCES + * RadioError:INTERNAL_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:SIM_ABSENT + */ + oneway void setSmscAddressResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:SIM_BUSY + * RadioError:NO_MEMORY + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:SIM_ABSENT + */ + oneway void setSuppServiceNotificationsResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:INVALID_ARGUMENTS + */ + oneway void setSystemSelectionChannelsResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + oneway void setTTYModeResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SUBSCRIPTION_NOT_SUPPORTED + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + oneway void setUiccSubscriptionResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param dcResponse SetupDataCallResult defined in types.hal + * + * Valid errors returned: + * RadioError:NONE must be returned on both success and failure of setup with the + * DataCallResponse.status containing the actual status + * For all other errors the DataCallResponse is ignored. + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:OP_NOT_ALLOWED_BEFORE_REG_TO_NW + * RadioError:OP_NOT_ALLOWED_DURING_VOICE_CALL + * RadioError:INVALID_ARGUMENTS + * RadioError:INTERNAL_ERR + * RadioError:NO_RESOURCES if the vendor is unable handle due to resources are full. + * RadioError:SIM_ABSENT + */ + oneway void setupDataCallResponse(in RadioResponseInfo info, in SetupDataCallResult dcResponse); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_RESOURCES + * RadioError:NO_MEMORY + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:INVALID_CALL_ID + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:CANCELLED + * RadioError:INVALID_MODEM_STATE + */ + oneway void startDtmfResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:NO_RESOURCES + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_CALL_ID + */ + oneway void startHandoverResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param status Status object containing a new handle and a current status. The status returned + * here may be PENDING to indicate that the radio has not yet processed the keepalive + * request. + * + * Valid errors returned: + * RadioError:NONE + * RadioError:NO_RESOURCES + * RadioError:INVALID_ARGUMENTS + */ + oneway void startKeepaliveResponse(in RadioResponseInfo info, in KeepaliveStatus status); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param statusInfo LceStatusInfo indicating LCE status + * + * Valid errors returned: + * RadioError:REQUEST_NOT_SUPPORTED may be returned when HAL 1.2 or higher is supported. + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:LCE_NOT_SUPPORTED + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + oneway void startLceServiceResponse(in RadioResponseInfo info, in LceStatusInfo statusInfo); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:DEVICE_IN_USE + * RadioError:INTERNAL_ERR + * RadioError:MODEM_ERR + * RadioError:INVALID_ARGUMENTS + */ + oneway void startNetworkScanResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_RESOURCES + * RadioError:NO_MEMORY + * RadioError:INVALID_ARGUMENTS + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:INVALID_CALL_ID + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:CANCELLED + * RadioError:INVALID_MODEM_STATE + */ + oneway void stopDtmfResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:INVALID_ARGUMENTS + */ + oneway void stopKeepaliveResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param statusInfo LceStatusInfo indicating LCE status + * + * Valid errors returned: + * RadioError:REQUEST_NOT_SUPPORTED may be returned when HAL 1.2 or higher is supported. + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:LCE_NOT_SUPPORTED + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:SIM_ABSENT + */ + oneway void stopLceServiceResponse(in RadioResponseInfo info, in LceStatusInfo statusInfo); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:INTERNAL_ERR + * RadioError:MODEM_ERR + */ + oneway void stopNetworkScanResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param remainingRetries Number of retries remaining, must be equal to -1 if unknown. + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE (radio resetting) + * RadioError:PASSWORD_INCORRECT + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:INVALID_ARGUMENTS + * RadioError:INVALID_SIM_STATE + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:SIM_PUK2 + */ + oneway void supplyIccPin2ForAppResponse(in RadioResponseInfo info, in int remainingRetries); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param remainingRetries Number of retries remaining, must be equal to -1 if unknown. + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE (radio resetting) + * RadioError:PASSWORD_INCORRECT + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:INVALID_ARGUMENTS + * RadioError:INVALID_SIM_STATE + * RadioError:REQUEST_NOT_SUPPORTED + */ + oneway void supplyIccPinForAppResponse(in RadioResponseInfo info, in int remainingRetries); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param remainingRetries Number of retries remaining, must be equal to -1 if unknown. + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE (radio resetting) + * RadioError:PASSWORD_INCORRECT (PUK is invalid) + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:INVALID_ARGUMENTS + * RadioError:INVALID_SIM_STATE + * RadioError:REQUEST_NOT_SUPPORTED + */ + oneway void supplyIccPuk2ForAppResponse(in RadioResponseInfo info, in int remainingRetries); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param remainingRetries Number of retries remaining, must be equal to -1 if unknown. + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE (radio resetting) + * RadioError:PASSWORD_INCORRECT (PUK is invalid) + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:INVALID_ARGUMENTS + * RadioError:INVALID_SIM_STATE + * RadioError:REQUEST_NOT_SUPPORTED + */ + oneway void supplyIccPukForAppResponse(in RadioResponseInfo info, in int remainingRetries); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param remainingRetries Number of retries remaining, must be equal to -1 if unknown. + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:PASSWORD_INCORRECT (code is invalid) + * RadioError:NO_MEMORY + * RadioError:INVALID_SIM_STATE + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:SIM_ABSENT + */ + oneway void supplyNetworkDepersonalizationResponse( + in RadioResponseInfo info, in int remainingRetries); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param persoType SIM Personalisation type + * @param remainingRetries postiive values indicates number of retries remaining, must be equal + * to -1 if number of retries is infinite. + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:PASSWORD_INCORRECT (code is invalid) + * RadioError:NO_MEMORY + * RadioError:INVALID_SIM_STATE + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_RESOURCES + * RadioError:REQUEST_NOT_SUPPORTED + */ + oneway void supplySimDepersonalizationResponse( + in RadioResponseInfo info, in PersoSubstate persoType, in int remainingRetries); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE (radio resetting) + * RadioError:INVALID_STATE + * RadioError:NO_MEMORY + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:INVALID_STATE + * RadioError:INVALID_CALL_ID + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:INVALID_ARGUMENTS + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_MODEM_STATE + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + oneway void switchWaitingOrHoldingAndActiveResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param updatedRecordIndex The index of the updated or inserted record in the phonebook and + * the minimum value is 1 + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_ARGUMENTS + * RadioError:INVALID_SIM_STATE + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:SIM_ERR + * RadioError:NO_SUCH_ENTRY + * RadioError:NO_RESOURCES + * REQUEST_NOT_SUPPORTED may only be returned on devices that don't support this API, + * indicated by the HAL capability CAPABILITY_SIM_PHONEBOOK_IN_MODEM. + */ + oneway void updateSimPhonebookRecordsResponse( + in RadioResponseInfo info, in int updatedRecordIndex); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param index record index where the cmda sms message is stored + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:INVALID_SMS_FORMAT + * RadioError:SIM_FULL + * RadioError:INTERNAL_ERR + * RadioError:MODEM_ERR + * RadioError:ENCODING_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:INVALID_MODEM_STATE + * RadioError:INVALID_SMSC_ADDRESS + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:INVALID_MODEM_STATE + * RadioError:SIM_ABSENT + */ + oneway void writeSmsToRuimResponse(in RadioResponseInfo info, in int index); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param index record index where the message is stored + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SIM_FULL + * RadioError:INVALID_ARGUMENTS + * RadioError:INVALID_SMS_FORMAT + * RadioError:INTERNAL_ERR + * RadioError:MODEM_ERR + * RadioError:ENCODING_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:INVALID_MODEM_STATE + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:INVALID_SMSC_ADDRESS + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:CANCELLED + * RadioError:INVALID_MODEM_STATE + * RadioError:SIM_ABSENT + */ + oneway void writeSmsToSimResponse(in RadioResponseInfo info, in int index); +} diff --git a/radio/aidl/android/hardware/radio/ISap.aidl b/radio/aidl/android/hardware/radio/ISap.aidl new file mode 100644 index 0000000000..55950fd26e --- /dev/null +++ b/radio/aidl/android/hardware/radio/ISap.aidl @@ -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.radio; + +import android.hardware.radio.ISapCallback; +import android.hardware.radio.SapApduType; +import android.hardware.radio.SapTransferProtocol; + +/** + * Empty top level interface. + */ +@VintfStability +interface ISap { + /** + * TRANSFER_APDU_REQ from SAP 1.1 spec 5.1.6 + * + * @param token Id to match req-resp. Resp must include same token. + * @param type APDU command type + * @param command CommandAPDU/CommandAPDU7816 parameter depending on type + */ + oneway void apduReq(in int token, in SapApduType type, in byte[] command); + + /** + * CONNECT_REQ from SAP 1.1 spec 5.1.1 + * + * @param token Id to match req-resp. Resp must include same token. + * @param maxMsgSize MaxMsgSize to be used for SIM Access Profile connection + */ + oneway void connectReq(in int token, in int maxMsgSize); + + /** + * DISCONNECT_REQ from SAP 1.1 spec 5.1.3 + * + * @param token Id to match req-resp. Resp must include same token. + */ + oneway void disconnectReq(in int token); + + /** + * POWER_SIM_OFF_REQ and POWER_SIM_ON_REQ from SAP 1.1 spec 5.1.10 + 5.1.12 + * + * @param token Id to match req-resp. Resp must include same token. + * @param state true for on, false for off + */ + oneway void powerReq(in int token, in boolean state); + + /** + * RESET_SIM_REQ from SAP 1.1 spec 5.1.14 + * + * @param token Id to match req-resp. Resp must include same token. + */ + oneway void resetSimReq(in int token); + + /** + * Set callback that has response and unsolicited indication functions + * + * @param sapCallback Object containing response and unosolicited indication callbacks + */ + void setCallback(in ISapCallback sapCallback); + + /** + * SET_TRANSPORT_PROTOCOL_REQ from SAP 1.1 spec 5.1.20 + * + * @param token Id to match req-resp. Resp must include same token. + * @param transferProtocol Transport Protocol + */ + oneway void setTransferProtocolReq(in int token, in SapTransferProtocol transferProtocol); + + /** + * TRANSFER_ATR_REQ from SAP 1.1 spec 5.1.8 + * + * @param token Id to match req-resp. Resp must include same token. + */ + oneway void transferAtrReq(in int token); + + /** + * TRANSFER_CARD_READER_STATUS_REQ from SAP 1.1 spec 5.1.17 + * + * @param token Id to match req-resp. Resp must include same token. + */ + oneway void transferCardReaderStatusReq(in int token); +} diff --git a/radio/aidl/android/hardware/radio/ISapCallback.aidl b/radio/aidl/android/hardware/radio/ISapCallback.aidl new file mode 100644 index 0000000000..e7a4bac705 --- /dev/null +++ b/radio/aidl/android/hardware/radio/ISapCallback.aidl @@ -0,0 +1,152 @@ +/* + * 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.radio; + +import android.hardware.radio.SapConnectRsp; +import android.hardware.radio.SapDisconnectType; +import android.hardware.radio.SapResultCode; +import android.hardware.radio.SapStatus; + +@VintfStability +interface ISapCallback { + /** + * TRANSFER_APDU_RESP from SAP 1.1 spec 5.1.7 + * + * @param token Id to match req-resp. Value must match the one in req. + * @param resultCode ResultCode to indicate if command was processed correctly + * Possible values: + * SapResultCode:SUCCESS, + * SapResultCode:GENERIC_FAILURE, + * SapResultCode:CARD_NOT_ACCESSSIBLE, + * SapResultCode:CARD_ALREADY_POWERED_OFF, + * SapResultCode:CARD_REMOVED + * @param apduRsp APDU Response. Valid only if command was processed correctly and no error + * occurred. + */ + oneway void apduResponse(in int token, in SapResultCode resultCode, in byte[] apduRsp); + + /** + * CONNECT_RESP from SAP 1.1 spec 5.1.2 + * + * @param token Id to match req-resp. Value must match the one in req. + * @param sapConnectRsp Connection Status + * @param maxMsgSize MaxMsgSize supported by server if request cannot be fulfilled. + * Valid only if connectResponse is SapConnectResponse:MSG_SIZE_TOO_LARGE. + */ + oneway void connectResponse(in int token, in SapConnectRsp sapConnectRsp, in int maxMsgSize); + + /** + * DISCONNECT_IND from SAP 1.1 spec 5.1.5 + * + * @param token Id to match req-resp. Value must match the one in req. + * @param disconnectType Disconnect Type to indicate if shutdown is graceful or immediate + */ + oneway void disconnectIndication(in int token, in SapDisconnectType disconnectType); + + /** + * DISCONNECT_RESP from SAP 1.1 spec 5.1.4 + * + * @param token Id to match req-resp. Value must match the one in req. + */ + oneway void disconnectResponse(in int token); + + /** + * ERROR_RESP from SAP 1.1 spec 5.1.19 + * + * @param token Id to match req-resp. Value must match the one in req. + */ + oneway void errorResponse(in int token); + + /** + * POWER_SIM_OFF_RESP and POWER_SIM_ON_RESP from SAP 1.1 spec 5.1.11 + 5.1.13 + * + * @param token Id to match req-resp. Value must match the one in req. + * @param resultCode ResultCode to indicate if command was processed correctly + * Possible values: + * SapResultCode:SUCCESS, + * SapResultCode:GENERIC_FAILURE, + * SapResultCode:CARD_NOT_ACCESSSIBLE, (possible only for power on req) + * SapResultCode:CARD_ALREADY_POWERED_OFF, (possible only for power off req) + * SapResultCode:CARD_REMOVED, + * SapResultCode:CARD_ALREADY_POWERED_ON (possible only for power on req) + */ + oneway void powerResponse(in int token, in SapResultCode resultCode); + + /** + * RESET_SIM_RESP from SAP 1.1 spec 5.1.15 + * + * @param token Id to match req-resp. Value must match the one in req. + * @param resultCode ResultCode to indicate if command was processed correctly + * Possible values: + * SapResultCode:SUCCESS, + * SapResultCode:GENERIC_FAILURE, + * SapResultCode:CARD_NOT_ACCESSSIBLE, + * SapResultCode:CARD_ALREADY_POWERED_OFF, + * SapResultCode:CARD_REMOVED + */ + oneway void resetSimResponse(in int token, in SapResultCode resultCode); + + /** + * STATUS_IND from SAP 1.1 spec 5.1.16 + * + * @param token Id to match req-resp. Value must match the one in req. + * @param status Parameter to indicate reason for the status change. + */ + oneway void statusIndication(in int token, in SapStatus status); + + /** + * TRANSFER_ATR_RESP from SAP 1.1 spec 5.1.9 + * + * @param token Id to match req-resp. Value must match the one in req. + * @param resultCode ResultCode to indicate if command was processed correctly + * Possible values: + * SapResultCode:SUCCESS, + * SapResultCode:GENERIC_FAILURE, + * SapResultCode:CARD_ALREADY_POWERED_OFF, + * SapResultCode:CARD_REMOVED, + * SapResultCode:DATA_NOT_AVAILABLE + * @param atr Answer to Reset from the subscription module. Included only if no error occurred, + * otherwise empty. + */ + oneway void transferAtrResponse(in int token, in SapResultCode resultCode, in byte[] atr); + + /** + * TRANSFER_CARD_READER_STATUS_REQ from SAP 1.1 spec 5.1.18 + * + * @param token Id to match req-resp. Value must match the one in req. + * @param resultCode ResultCode to indicate if command was processed correctly + * Possible values: + * SapResultCode:SUCCESS, + * SapResultCode:GENERIC_FAILURE + * SapResultCode:DATA_NOT_AVAILABLE + * @param cardReaderStatus Card Reader Status coded as described in 3GPP TS 11.14 Section 12.33 + * and TS 31.111 Section 8.33 + */ + oneway void transferCardReaderStatusResponse( + in int token, in SapResultCode resultCode, in int cardReaderStatus); + + /** + * SET_TRANSPORT_PROTOCOL_RESP from SAP 1.1 spec 5.1.21 + * + * @param token Id to match req-resp. Value must match the one in req. + * @param resultCode ResultCode to indicate if command was processed correctly + * Possible values: + * SapResultCode:SUCCESS + * SapResultCode:NOT_SUPPORTED + */ + oneway void transferProtocolResponse(in int token, in SapResultCode resultCode); +} diff --git a/radio/aidl/android/hardware/radio/IccIo.aidl b/radio/aidl/android/hardware/radio/IccIo.aidl new file mode 100644 index 0000000000..7441758507 --- /dev/null +++ b/radio/aidl/android/hardware/radio/IccIo.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.radio; + +@VintfStability +parcelable IccIo { + /** + * One of the commands listed for TS 27.007 +CRSM + */ + int command; + /** + * EF ID + */ + int fileId; + /** + * "pathid" from TS 27.007 +CRSM command. Path is in hex ASCII format eg "7f205f70" + * Path must always be provided. + */ + String path; + /** + * Value of p1 defined as per 3GPP TS 51.011 + */ + int p1; + /** + * Value of p2 defined as per 3GPP TS 51.011 + */ + int p2; + /** + * Value of p3 defined as per 3GPP TS 51.011 + */ + int p3; + /** + * Information to be written to the SIM + */ + String data; + String pin2; + /** + * AID value, See ETSI 102.221 8.1 and 101.220 4, empty string if no value. + */ + String aid; +} diff --git a/radio/aidl/android/hardware/radio/IccIoResult.aidl b/radio/aidl/android/hardware/radio/IccIoResult.aidl new file mode 100644 index 0000000000..94377b4072 --- /dev/null +++ b/radio/aidl/android/hardware/radio/IccIoResult.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.radio; + +@VintfStability +parcelable IccIoResult { + int sw1; + int sw2; + /** + * In hex string format ([a-fA-F0-9]*), except for SIM_AUTHENTICATION response for which it is + * in Base64 format, see 3GPP TS 31.102 7.1.2 + */ + String simResponse; +} diff --git a/radio/aidl/android/hardware/radio/ImsSmsMessage.aidl b/radio/aidl/android/hardware/radio/ImsSmsMessage.aidl new file mode 100644 index 0000000000..3b4efe68fd --- /dev/null +++ b/radio/aidl/android/hardware/radio/ImsSmsMessage.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.radio; + +import android.hardware.radio.CdmaSmsMessage; +import android.hardware.radio.GsmSmsMessage; +import android.hardware.radio.RadioTechnologyFamily; + +@VintfStability +parcelable ImsSmsMessage { + RadioTechnologyFamily tech; + /** + * Retry if true + */ + boolean retry; + /** + * Valid field if retry is set to true. + * Contains messageRef from SendSmsResult struct corresponding to failed MO SMS. + */ + int messageRef; + /** + * Valid field if tech is 3GPP2 and size = 1 else must be empty. Only one of cdmaMessage and + * gsmMessage must be of size 1 based on the RadioTechnologyFamily and the other must be size 0. + */ + CdmaSmsMessage[] cdmaMessage; + /** + * Valid field if tech is 3GPP and size = 1 else must be empty. Only one of cdmaMessage and + * gsmMessage must be of size 1 based on the RadioTechnologyFamily and the other must be size 0. + */ + GsmSmsMessage[] gsmMessage; +} diff --git a/radio/aidl/android/hardware/radio/ImsiEncryptionInfo.aidl b/radio/aidl/android/hardware/radio/ImsiEncryptionInfo.aidl new file mode 100644 index 0000000000..dbb0a9e2ed --- /dev/null +++ b/radio/aidl/android/hardware/radio/ImsiEncryptionInfo.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.radio; + +import android.hardware.radio.PublicKeyType; + +/** + * Carrier specific Information sent by the carrier, which will be used to encrypt IMSI and IMPI. + */ +@VintfStability +parcelable ImsiEncryptionInfo { + /** + * MCC of the Carrier. + */ + String mcc; + /** + * MNC of the Carrier. + */ + String mnc; + /** + * Carrier specific key to be used for encryption. It must be opaque to the framework. + * This is the byte-stream representation of the key. This is an external encoded form for the + * key used when a standard representation of the key is needed outside the Java Virtual + * Machine, as when transmitting the key to some other party. The key is encoded according to a + * standard format (such as X.509 SubjectPublicKeyInfo or PKCS#8), and is returned using the + * getEncoded method as defined on the java.security.Key interface. + */ + byte[] carrierKey; + /** + * This is an opaque value we're given by the carrier and is returned to the carrier. + * This is used by the server to help it locate the private key to decrypt the + * permanent identity. + */ + String keyIdentifier; + /** + * Date-time in UTC when the key will expire. + */ + long expirationTime; + /** + * Public key type. + */ + PublicKeyType keyType; +} diff --git a/radio/aidl/android/hardware/radio/IncrementalResultsPeriodicityRange.aidl b/radio/aidl/android/hardware/radio/IncrementalResultsPeriodicityRange.aidl new file mode 100644 index 0000000000..4a863a7121 --- /dev/null +++ b/radio/aidl/android/hardware/radio/IncrementalResultsPeriodicityRange.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.radio; + +/** + * Values are in seconds. + */ +@VintfStability +@Backing(type="int") +enum IncrementalResultsPeriodicityRange { + MIN = 1, + MAX = 10, +} diff --git a/radio/aidl/android/hardware/radio/IndicationFilter.aidl b/radio/aidl/android/hardware/radio/IndicationFilter.aidl new file mode 100644 index 0000000000..826c8c1c57 --- /dev/null +++ b/radio/aidl/android/hardware/radio/IndicationFilter.aidl @@ -0,0 +1,69 @@ +/* + * 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.radio; + +@VintfStability +@Backing(type="int") +enum IndicationFilter { + NONE = 0, + ALL = ~0, + /** + * When this bit is set, modem must send the signal strength update through + * IRadioIndication.currentSignalStrength() when all criteria specified by + * IRadio.setSignalStrengthReportingCriteria() are met. + */ + SIGNAL_STRENGTH = 1 << 0, + /** + * When this bit is set, modem must invoke IRadioIndication.networkStateChanged() when any field + * in VoiceRegStateResult or DataRegStateResult changes. When this bit is not set, modem must + * suppress IRadioIndication.networkStateChanged() when there are only changes from + * insignificant fields. Modem must invoke IRadioIndication.networkStateChanged() when + * significant fields are updated regardless of whether this bit is set. + * + * The following fields are considered significant: VoiceRegStateResult.regState, + * VoiceRegStateResult.rat, DataRegStateResult.regState, DataRegStateResult.rat. + */ + FULL_NETWORK_STATE = 1 << 1, + /** + * When this bit is set, modem must send IRadioIndication.dataCallListChanged() whenever any + * field in ITypes.SetupDataCallResult changes. When this bit is not set, modem must suppress + * the indication when the only changed field is 'active' (for data dormancy). For all other + * field changes, the modem must send IRadioIndication.dataCallListChanged() regardless of + * whether this bit is set. + */ + DATA_CALL_DORMANCY_CHANGED = 1 << 2, + /** + * When this bit is set, modem must send the link capacity update through + * IRadioIndication.currentLinkCapacityEstimate() when all criteria specified by + * IRadio.setLinkCapacityReportingCriteria() are met. + */ + LINK_CAPACITY_ESTIMATE = 1 << 3, + /** + * When this bit is set, the modem must send the physical channel configuration update through + * IRadioIndication.currentPhysicalChannelConfigs() when the configuration has changed. It is + * recommended that this be reported whenever link capacity or signal strength is reported. + */ + PHYSICAL_CHANNEL_CONFIG = 1 << 4, + /** + * Control the unsolicited sending of registration failure reports via onRegistrationFailed + */ + REGISTRATION_FAILURE = 1 << 5, + /** + * Control the unsolicited sending of barring info updates via onBarringInfo + */ + BARRING_INFO = 1 << 6, +} diff --git a/radio/aidl/android/hardware/radio/KeepaliveRequest.aidl b/radio/aidl/android/hardware/radio/KeepaliveRequest.aidl new file mode 100644 index 0000000000..ef594ade53 --- /dev/null +++ b/radio/aidl/android/hardware/radio/KeepaliveRequest.aidl @@ -0,0 +1,54 @@ +/* + * 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.radio; + +import android.hardware.radio.KeepaliveType; + +@VintfStability +parcelable KeepaliveRequest { + /** + * The format of the keepalive packet + */ + KeepaliveType type; + /** + * Source address with type = family, in network byte order + */ + byte[] sourceAddress; + /** + * Source port if relevant for the given type + * INT_MAX: 0x7FFFFFFF denotes that the field is unused + */ + int sourcePort; + /** + * Destination address with type = family, in network byte order + */ + byte[] destinationAddress; + /** + * Destination if relevant for the given type + * INT_MAX: 0x7FFFFFFF denotes that the field is unused + */ + int destinationPort; + /** + * The max interval between packets, in milliseconds + */ + int maxKeepaliveIntervalMillis; + /** + * Context ID, returned in setupDataCallResponse that uniquely identifies the data call to which + * this keepalive must applied. + */ + int cid; +} diff --git a/radio/aidl/android/hardware/radio/KeepaliveStatus.aidl b/radio/aidl/android/hardware/radio/KeepaliveStatus.aidl new file mode 100644 index 0000000000..911cdae07a --- /dev/null +++ b/radio/aidl/android/hardware/radio/KeepaliveStatus.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.radio; + +import android.hardware.radio.KeepaliveStatusCode; + +@VintfStability +parcelable KeepaliveStatus { + /** + * The sessionHandle provided by the API + */ + int sessionHandle; + /** + * Status for the given keepalive + */ + KeepaliveStatusCode code; +} diff --git a/radio/aidl/android/hardware/radio/KeepaliveStatusCode.aidl b/radio/aidl/android/hardware/radio/KeepaliveStatusCode.aidl new file mode 100644 index 0000000000..ed4b32777d --- /dev/null +++ b/radio/aidl/android/hardware/radio/KeepaliveStatusCode.aidl @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.radio; + +@VintfStability +@Backing(type="int") +enum KeepaliveStatusCode { + /** + * Keepalive is currently active + */ + ACTIVE, + /** + * Keepalive is inactive, which indicates an error + */ + INACTIVE, + /** + * Requested keepalive has not yet been processed by the modem. + * Only allowed in a RESPONSE message to a REQUEST + */ + PENDING, +} diff --git a/radio/aidl/android/hardware/radio/KeepaliveType.aidl b/radio/aidl/android/hardware/radio/KeepaliveType.aidl new file mode 100644 index 0000000000..86b1509f29 --- /dev/null +++ b/radio/aidl/android/hardware/radio/KeepaliveType.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.radio; + +@VintfStability +@Backing(type="int") +enum KeepaliveType { + /** + * Keepalive specified by RFC 3948 Sec. 2.3 using IPv4 + */ + NATT_IPV4, + /** + * Keepalive specified by RFC 3948 Sec. 2.3 using IPv6 + */ + NATT_IPV6, +} diff --git a/radio/aidl/android/hardware/radio/LastCallFailCause.aidl b/radio/aidl/android/hardware/radio/LastCallFailCause.aidl new file mode 100644 index 0000000000..e5a5145fa4 --- /dev/null +++ b/radio/aidl/android/hardware/radio/LastCallFailCause.aidl @@ -0,0 +1,177 @@ +/* + * 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.radio; + +@VintfStability +@Backing(type="int") +enum LastCallFailCause { + UNOBTAINABLE_NUMBER = 1, + NO_ROUTE_TO_DESTINATION = 3, + CHANNEL_UNACCEPTABLE = 6, + OPERATOR_DETERMINED_BARRING = 8, + NORMAL = 16, + BUSY = 17, + NO_USER_RESPONDING = 18, + NO_ANSWER_FROM_USER = 19, + CALL_REJECTED = 21, + NUMBER_CHANGED = 22, + PREEMPTION = 25, + DESTINATION_OUT_OF_ORDER = 27, + INVALID_NUMBER_FORMAT = 28, + FACILITY_REJECTED = 29, + RESP_TO_STATUS_ENQUIRY = 30, + NORMAL_UNSPECIFIED = 31, + CONGESTION = 34, + NETWORK_OUT_OF_ORDER = 38, + TEMPORARY_FAILURE = 41, + SWITCHING_EQUIPMENT_CONGESTION = 42, + ACCESS_INFORMATION_DISCARDED = 43, + REQUESTED_CIRCUIT_OR_CHANNEL_NOT_AVAILABLE = 44, + RESOURCES_UNAVAILABLE_OR_UNSPECIFIED = 47, + QOS_UNAVAILABLE = 49, + REQUESTED_FACILITY_NOT_SUBSCRIBED = 50, + INCOMING_CALLS_BARRED_WITHIN_CUG = 55, + BEARER_CAPABILITY_NOT_AUTHORIZED = 57, + BEARER_CAPABILITY_UNAVAILABLE = 58, + SERVICE_OPTION_NOT_AVAILABLE = 63, + BEARER_SERVICE_NOT_IMPLEMENTED = 65, + ACM_LIMIT_EXCEEDED = 68, + REQUESTED_FACILITY_NOT_IMPLEMENTED = 69, + ONLY_DIGITAL_INFORMATION_BEARER_AVAILABLE = 70, + SERVICE_OR_OPTION_NOT_IMPLEMENTED = 79, + INVALID_TRANSACTION_IDENTIFIER = 81, + USER_NOT_MEMBER_OF_CUG = 87, + INCOMPATIBLE_DESTINATION = 88, + INVALID_TRANSIT_NW_SELECTION = 91, + SEMANTICALLY_INCORRECT_MESSAGE = 95, + INVALID_MANDATORY_INFORMATION = 96, + MESSAGE_TYPE_NON_IMPLEMENTED = 97, + MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE = 98, + INFORMATION_ELEMENT_NON_EXISTENT = 99, + CONDITIONAL_IE_ERROR = 100, + MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE = 101, + RECOVERY_ON_TIMER_EXPIRED = 102, + PROTOCOL_ERROR_UNSPECIFIED = 111, + INTERWORKING_UNSPECIFIED = 127, + CALL_BARRED = 240, + FDN_BLOCKED = 241, + IMSI_UNKNOWN_IN_VLR = 242, + IMEI_NOT_ACCEPTED = 243, + /** + * STK Call Control + */ + DIAL_MODIFIED_TO_USSD = 244, + DIAL_MODIFIED_TO_SS = 245, + DIAL_MODIFIED_TO_DIAL = 246, + /** + * Radio is off + */ + RADIO_OFF = 247, + /** + * No cellular coverage + */ + OUT_OF_SERVICE = 248, + /** + * No valid SIM is present + */ + NO_VALID_SIM = 249, + /** + * Internal error at modem + */ + RADIO_INTERNAL_ERROR = 250, + /** + * No response from network + */ + NETWORK_RESP_TIMEOUT = 251, + /** + * Explicit network reject + */ + NETWORK_REJECT = 252, + /** + * RRC connection failure. Eg.RACH + */ + RADIO_ACCESS_FAILURE = 253, + /** + * Radio link failure + */ + RADIO_LINK_FAILURE = 254, + /** + * Radio link lost due to poor coverage + */ + RADIO_LINK_LOST = 255, + /** + * Radio uplink failure + */ + RADIO_UPLINK_FAILURE = 256, + /** + * RRC connection setup failure + */ + RADIO_SETUP_FAILURE = 257, + /** + * RRC connection release, normal + */ + RADIO_RELEASE_NORMAL = 258, + /** + * RRC connection release, abnormal + */ + RADIO_RELEASE_ABNORMAL = 259, + /** + * Access class barring + */ + ACCESS_CLASS_BLOCKED = 260, + /** + * Explicit network detach + */ + NETWORK_DETACH = 261, + CDMA_LOCKED_UNTIL_POWER_CYCLE = 1000, + CDMA_DROP = 1001, + CDMA_INTERCEPT = 1002, + CDMA_REORDER = 1003, + CDMA_SO_REJECT = 1004, + CDMA_RETRY_ORDER = 1005, + CDMA_ACCESS_FAILURE = 1006, + CDMA_PREEMPTED = 1007, + /** + * For non-emergency number dialed during emergency callback mode + */ + CDMA_NOT_EMERGENCY = 1008, + CDMA_ACCESS_BLOCKED = 1009, + /** + * OEM specific error codes. Used to distinguish error from + * CALL_FAIL_ERROR_UNSPECIFIED and help assist debugging + */ + OEM_CAUSE_1 = 0xf001, + OEM_CAUSE_2 = 0xf002, + OEM_CAUSE_3 = 0xf003, + OEM_CAUSE_4 = 0xf004, + OEM_CAUSE_5 = 0xf005, + OEM_CAUSE_6 = 0xf006, + OEM_CAUSE_7 = 0xf007, + OEM_CAUSE_8 = 0xf008, + OEM_CAUSE_9 = 0xf009, + OEM_CAUSE_10 = 0xf00a, + OEM_CAUSE_11 = 0xf00b, + OEM_CAUSE_12 = 0xf00c, + OEM_CAUSE_13 = 0xf00d, + OEM_CAUSE_14 = 0xf00e, + OEM_CAUSE_15 = 0xf00f, + /** + * This error will be deprecated soon, vendor code must make sure to map error code to specific + * error + */ + ERROR_UNSPECIFIED = 0xffff, +} diff --git a/radio/aidl/android/hardware/radio/LastCallFailCauseInfo.aidl b/radio/aidl/android/hardware/radio/LastCallFailCauseInfo.aidl new file mode 100644 index 0000000000..6866e99d91 --- /dev/null +++ b/radio/aidl/android/hardware/radio/LastCallFailCauseInfo.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.radio; + +import android.hardware.radio.LastCallFailCause; + +@VintfStability +parcelable LastCallFailCauseInfo { + LastCallFailCause causeCode; + String vendorCause; +} diff --git a/radio/aidl/android/hardware/radio/LceDataInfo.aidl b/radio/aidl/android/hardware/radio/LceDataInfo.aidl new file mode 100644 index 0000000000..68521b559b --- /dev/null +++ b/radio/aidl/android/hardware/radio/LceDataInfo.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.radio; + +@VintfStability +parcelable LceDataInfo { + /** + * Last-hop cellular capacity: kilobits/second. + */ + int lastHopCapacityKbps; + /** + * Capacity estimate confidence: 0-100. + */ + byte confidenceLevel; + /** + * Whether the LCE report is going to be suspended (e.g., radio moves to inactive state or + * network type changes). + */ + boolean lceSuspended; +} diff --git a/radio/aidl/android/hardware/radio/LceStatus.aidl b/radio/aidl/android/hardware/radio/LceStatus.aidl new file mode 100644 index 0000000000..0d3a27e420 --- /dev/null +++ b/radio/aidl/android/hardware/radio/LceStatus.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.radio; + +@VintfStability +@Backing(type="int") +enum LceStatus { + NOT_SUPPORTED, + STOPPED, + ACTIVE, +} diff --git a/radio/aidl/android/hardware/radio/LceStatusInfo.aidl b/radio/aidl/android/hardware/radio/LceStatusInfo.aidl new file mode 100644 index 0000000000..e2b35e1a64 --- /dev/null +++ b/radio/aidl/android/hardware/radio/LceStatusInfo.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.radio; + +import android.hardware.radio.LceStatus; + +@VintfStability +parcelable LceStatusInfo { + LceStatus lceStatus; + /** + * Actual LCE reporting interval, meaningful only if LceStatus = ACTIVE. + */ + byte actualIntervalMs; +} diff --git a/radio/aidl/android/hardware/radio/LinkAddress.aidl b/radio/aidl/android/hardware/radio/LinkAddress.aidl new file mode 100644 index 0000000000..6fc12c777d --- /dev/null +++ b/radio/aidl/android/hardware/radio/LinkAddress.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.radio; + +import android.hardware.radio.AddressProperty; + +/** + * Describes a data link address for mobile data connection. + */ +@VintfStability +parcelable LinkAddress { + /** + * The format is IP address with optional "/" prefix length (The format is defined in RFC-4291 + * section 2.3). For example, "192.0.1.3", "192.0.1.11/16", or "2001:db8::1/64". Typically one + * IPv4 or one IPv6 or one of each. If the prefix length is absent, then the addresses are + * assumed to be point to point with IPv4 with prefix length 32 or IPv6 with prefix length 128. + */ + String address; + /** + * The properties of the link address + */ + AddressProperty properties; + /** + * The time, as reported by SystemClock.elapsedRealtime(), when this link address will be or + * was deprecated. -1 indicates this information is not available. At the time existing + * connections can still use this address until it expires, but new connections should use the + * new address. LONG_MAX(0x7FFFFFFFFFFFFFFF) indicates this link address will never be + * deprecated. + */ + long deprecationTime; + /** + * The time, as reported by SystemClock.elapsedRealtime(), when this link address will expire + * and be removed from the interface. -1 indicates this information is not available. + * LONG_MAX(0x7FFFFFFFFFFFFFFF) indicates this link address will never expire. + */ + long expirationTime; +} diff --git a/radio/aidl/android/hardware/radio/LinkCapacityEstimate.aidl b/radio/aidl/android/hardware/radio/LinkCapacityEstimate.aidl new file mode 100644 index 0000000000..78ddee2f8f --- /dev/null +++ b/radio/aidl/android/hardware/radio/LinkCapacityEstimate.aidl @@ -0,0 +1,53 @@ +/* + * 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.radio; + +@VintfStability +parcelable LinkCapacityEstimate { + /** + * Estimated downlink capacity in kbps. In case of a dual connected network, this includes + * capacity of both primary and secondary. This bandwidth estimate shall be the estimated + * maximum sustainable link bandwidth (as would be measured at the Upper PDCP or SNDCP SAP). + * If the DL Aggregate Maximum Bit Rate is known, this value shall not exceed the DL-AMBR for + * the Internet PDN connection. This must be filled with 0 if network is not connected. + */ + int downlinkCapacityKbps; + /** + * Estimated uplink capacity in kbps. In case of a dual connected network, this includes + * capacity of both primary and secondary. This bandwidth estimate shall be the estimated + * maximum sustainable link bandwidth (as would be measured at the Upper PDCP or SNDCP SAP). + * If the UL Aggregate Maximum Bit Rate is known, this value shall not exceed the UL-AMBR for + * the Internet PDN connection. This must be filled with 0 if network is not connected. + */ + int uplinkCapacityKbps; + /** + * Estimated downlink capacity of secondary carrier in a dual connected NR mode in kbps. This + * bandwidth estimate shall be the estimated maximum sustainable link bandwidth (as would be + * measured at the Upper PDCP or SNDCP SAP). This is valid only in if device is connected to + * both primary and secodary in dual connected mode. This must be filled with 0 if secondary is + * not connected or if modem does not support this feature. + */ + int secondaryDownlinkCapacityKbps; + /** + * Estimated uplink capacity secondary carrier in a dual connected NR mode in kbps. This + * bandwidth estimate shall be the estimated maximum sustainable link bandwidth (as would be + * measured at the Upper PDCP or SNDCP SAP). This is valid only in if device is connected to + * both primary and secodary in dual connected mode.This must be filled with 0 if secondary is + * not connected or if modem does not support this feature. + */ + int secondaryUplinkCapacityKbps; +} diff --git a/radio/aidl/android/hardware/radio/LteSignalStrength.aidl b/radio/aidl/android/hardware/radio/LteSignalStrength.aidl new file mode 100644 index 0000000000..699925d419 --- /dev/null +++ b/radio/aidl/android/hardware/radio/LteSignalStrength.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.radio; + +@VintfStability +parcelable LteSignalStrength { + /** + * Valid values are (0-31, 99) as defined in TS 27.007 8.5; INT_MAX means invalid/unreported. + */ + int signalStrength; + /** + * The current Reference Signal Receive Power in dBm multiplied by -1. Range: 44 to 140 dBm; + * INT_MAX: 0x7FFFFFFF denotes invalid/unreported value. Reference: 3GPP TS 36.133 9.1.4 + */ + int rsrp; + /** + * The current Reference Signal Receive Quality in dB multiplied by -1. Range: 20 to 3 dB; + * INT_MAX: 0x7FFFFFFF denotes invalid/unreported value. Reference: 3GPP TS 36.133 9.1.7 + */ + int rsrq; + /** + * The current reference signal signal-to-noise ratio in 0.1 dB units. + * Range: -200 to +300 (-200 = -20.0 dB, +300 = 30dB). + * INT_MAX: 0x7FFFFFFF denotes invalid/unreported value. Reference: 3GPP TS 36.101 8.1.1 + */ + int rssnr; + /** + * The current Channel Quality Indicator. Range: 0 to 15. + * INT_MAX: 0x7FFFFFFF denotes invalid/unreported value. Reference: 3GPP TS 36.101 9.2, 9.3, A.4 + */ + int cqi; + /** + * Timing advance in micro seconds for a one way trip from cell to device. Approximate distance + * is calculated using 300m/us * timingAdvance. Range: 0 to 1282 inclusive. + * INT_MAX: 0x7FFFFFFF denotes invalid/unreported value. Reference: 3GPP 36.213 section 4.2.3 + */ + int timingAdvance; + /** + * CSI channel quality indicator (CQI) table index. There are multiple CQI tables. + * The definition of CQI in each table is different. + * Reference: 3GPP TS 136.213 section 7.2.3. + * Range [1, 6], INT_MAX means invalid/unreported. + */ + int cqiTableIndex; +} diff --git a/radio/aidl/android/hardware/radio/LteVopsInfo.aidl b/radio/aidl/android/hardware/radio/LteVopsInfo.aidl new file mode 100644 index 0000000000..b487a8f20d --- /dev/null +++ b/radio/aidl/android/hardware/radio/LteVopsInfo.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. + */ + +package android.hardware.radio; + +/** + * Type to define the LTE specific network capabilities for voice over PS including emergency and + * normal voice calls. + */ +@VintfStability +parcelable LteVopsInfo { + /** + * This indicates if camped network support VoLTE services. This information is received from + * LTE network during LTE NAS registration procedure through LTE ATTACH ACCEPT/TAU ACCEPT. + * Refer 3GPP 24.301 EPS network feature support -> IMS VoPS + */ + boolean isVopsSupported; + /** + * This indicates if camped network support VoLTE emergency bearers. This information is + * received from LTE network through two sources: + * a. During LTE NAS registration procedure through LTE ATTACH ACCEPT/TAU ACCEPT. Refer + * 3GPP 24.301 EPS network feature support -> EMC BS + * b. In case device is not registered on network. Refer 3GPP 25.331 LTE RRC + * SIB1 : ims-EmergencySupport-r9 + * If device is registered on LTE, then this field indicates (a). + * In case of limited service on LTE this field indicates (b). + */ + boolean isEmcBearerSupported; +} diff --git a/radio/aidl/android/hardware/radio/MaxSearchTimeRange.aidl b/radio/aidl/android/hardware/radio/MaxSearchTimeRange.aidl new file mode 100644 index 0000000000..babbd3cc47 --- /dev/null +++ b/radio/aidl/android/hardware/radio/MaxSearchTimeRange.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.radio; + +/** + * Values are in seconds. + */ +@VintfStability +@Backing(type="int") +enum MaxSearchTimeRange { + MIN = 60, + MAX = 3600, +} diff --git a/radio/aidl/android/hardware/radio/MaybePort.aidl b/radio/aidl/android/hardware/radio/MaybePort.aidl new file mode 100644 index 0000000000..169f90f794 --- /dev/null +++ b/radio/aidl/android/hardware/radio/MaybePort.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.radio; + +import android.hardware.radio.PortRange; + +/** + * Port is optional, contains either single port or range of ports + */ +@VintfStability +union MaybePort { + boolean noinit; + PortRange range; +} diff --git a/radio/aidl/android/hardware/radio/MvnoType.aidl b/radio/aidl/android/hardware/radio/MvnoType.aidl new file mode 100644 index 0000000000..0f0df6256b --- /dev/null +++ b/radio/aidl/android/hardware/radio/MvnoType.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.radio; + +@VintfStability +@Backing(type="int") +enum MvnoType { + /** + * None + */ + NONE, + /** + * The matching data is based on IMSI. + */ + IMSI, + /** + * The matching data is based on group id. + */ + GID, + /** + * The matching data is based service provider name. + */ + SPN, +} diff --git a/radio/aidl/android/hardware/radio/NeighboringCell.aidl b/radio/aidl/android/hardware/radio/NeighboringCell.aidl new file mode 100644 index 0000000000..b48a2d4e51 --- /dev/null +++ b/radio/aidl/android/hardware/radio/NeighboringCell.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.radio; + +@VintfStability +parcelable NeighboringCell { + /** + * Combination of LAC and cell ID in 32 bits in GSM. Upper 16 bits is LAC and lower 16 bits is + * CID (as described in TS 27.005). + */ + String cid; + /** + * Received RSSI in GSM, level index of CPICH Received Signal Code Power in UMTS + */ + int rssi; +} diff --git a/radio/aidl/android/hardware/radio/NetworkScanRequest.aidl b/radio/aidl/android/hardware/radio/NetworkScanRequest.aidl new file mode 100644 index 0000000000..7659b89ae5 --- /dev/null +++ b/radio/aidl/android/hardware/radio/NetworkScanRequest.aidl @@ -0,0 +1,60 @@ +/* + * 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.radio; + +import android.hardware.radio.RadioAccessSpecifier; +import android.hardware.radio.ScanType; + +@VintfStability +parcelable NetworkScanRequest { + ScanType type; + /** + * Time interval in seconds between the completion of one scan and the start of a subsequent + * scan. Implementations may ignore this field unless the 'type' is 'PERIODIC'. + * Range: ScanIntervalRange:MIN to ScanIntervalRange:MAX. + */ + int interval; + /** + * Networks with bands/channels to scan. + * Maximum length of the vector is RadioConst:RADIO_ACCESS_SPECIFIER_MAX_SIZE. + */ + RadioAccessSpecifier[] specifiers; + /** + * Maximum duration of the periodic search (in seconds). If the search lasts maxSearchTime, it + * must be terminated. Range: MaxSearchTimeRange:MIN to MaxSearchTimeRange:MAX + */ + int maxSearchTime; + /** + * Whether the modem must report incremental results of the network scan to the client. + * FALSE – Incremental results must not be reported. + * TRUE – Incremental must be reported. + */ + boolean incrementalResults; + /** + * Indicates the periodicity with which the modem must report incremental results to the client + * (in seconds). Implementations may ignore this value if the incremental results are not + * requested. This value must be less than or equal to maxSearchTime. + * Range: IncrementalResultsPeriodicityRange:MIN to IncrementalResultsPeriodicityRange:MAX + */ + int incrementalResultsPeriodicity; + /** + * Describes the List of PLMN ids (MCC-MNC). If any PLMN of this list is found, search must end + * at that point and results with all PLMN found until that point should be sent as response. + * If the list is not sent, search to be completed until end and all PLMNs found to be reported. + */ + String[] mccMncs; +} diff --git a/radio/aidl/android/hardware/radio/NetworkScanResult.aidl b/radio/aidl/android/hardware/radio/NetworkScanResult.aidl new file mode 100644 index 0000000000..c542a4753b --- /dev/null +++ b/radio/aidl/android/hardware/radio/NetworkScanResult.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.radio; + +import android.hardware.radio.CellInfo; +import android.hardware.radio.RadioError; +import android.hardware.radio.ScanStatus; + +@VintfStability +parcelable NetworkScanResult { + /** + * The status of the scan. + */ + ScanStatus status; + /** + * The error code of the incremental result. + */ + RadioError error; + /** + * List of network information as CellInfo. + */ + CellInfo[] networkInfos; +} diff --git a/radio/aidl/android/hardware/radio/NgranBands.aidl b/radio/aidl/android/hardware/radio/NgranBands.aidl new file mode 100644 index 0000000000..7887011c77 --- /dev/null +++ b/radio/aidl/android/hardware/radio/NgranBands.aidl @@ -0,0 +1,84 @@ +/* + * 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.radio; + +/** + * NGRAN bands up to V16.5.0 + */ +@VintfStability +@Backing(type="int") +enum NgranBands { + /** + * 3GPP TS 38.101-1, Table 5.2-1: FR1 bands + */ + BAND_1 = 1, + BAND_2 = 2, + BAND_3 = 3, + BAND_5 = 5, + BAND_7 = 7, + BAND_8 = 8, + BAND_12 = 12, + BAND_14 = 14, + BAND_18 = 18, + BAND_20 = 20, + BAND_25 = 25, + BAND_26 = 26, + BAND_28 = 28, + BAND_29 = 29, + BAND_30 = 30, + BAND_34 = 34, + BAND_38 = 38, + BAND_39 = 39, + BAND_40 = 40, + BAND_41 = 41, + BAND_46 = 46, + BAND_48 = 48, + BAND_50 = 50, + BAND_51 = 51, + BAND_53 = 53, + BAND_65 = 65, + BAND_66 = 66, + BAND_70 = 70, + BAND_71 = 71, + BAND_74 = 74, + BAND_75 = 75, + BAND_76 = 76, + BAND_77 = 77, + BAND_78 = 78, + BAND_79 = 79, + BAND_80 = 80, + BAND_81 = 81, + BAND_82 = 82, + BAND_83 = 83, + BAND_84 = 84, + BAND_86 = 86, + BAND_89 = 89, + BAND_90 = 90, + BAND_91 = 91, + BAND_92 = 92, + BAND_93 = 93, + BAND_94 = 94, + BAND_95 = 95, + BAND_96 = 96, + /** + * 3GPP TS 38.101-2, Table 5.2-1: FR2 bands + */ + BAND_257 = 257, + BAND_258 = 258, + BAND_260 = 260, + BAND_261 = 261, +} diff --git a/radio/aidl/android/hardware/radio/NrDualConnectivityState.aidl b/radio/aidl/android/hardware/radio/NrDualConnectivityState.aidl new file mode 100644 index 0000000000..52bd048469 --- /dev/null +++ b/radio/aidl/android/hardware/radio/NrDualConnectivityState.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. + */ + +package android.hardware.radio; + +/** + * NR Dual connectivity state + */ +@VintfStability +@Backing(type="byte") +enum NrDualConnectivityState { + /** + * Enable NR dual connectivity. Enabled state does not mean dual connectivity is active. + * It means device is allowed to connect to both primary and secondary. + */ + ENABLE = 1, + /** + * Disable NR dual connectivity. Disabled state does not mean secondary cell is released. + * Modem will release it only if current bearer is released to avoid radio link failure. + */ + DISABLE = 2, + /** + * Disable NR dual connectivity and force secondary cell to be released if dual connectivity + * was active. This may result in radio link failure. + */ + DISABLE_IMMEDIATE = 3, +} diff --git a/radio/aidl/android/hardware/radio/NrIndicators.aidl b/radio/aidl/android/hardware/radio/NrIndicators.aidl new file mode 100644 index 0000000000..2a1dfece78 --- /dev/null +++ b/radio/aidl/android/hardware/radio/NrIndicators.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.radio; + +/** + * The parameters of NR 5G Non-Standalone. + */ +@VintfStability +parcelable NrIndicators { + /** + * Indicates that if E-UTRA-NR Dual Connectivity (EN-DC) is supported by the primary serving + * cell. True the primary serving cell is LTE cell and the plmn-InfoList-r15 is present in SIB2 + * and at least one bit in this list is true, otherwise this value should be false. + * Reference: 3GPP TS 36.331 v15.2.2 6.3.1 System information blocks. + */ + boolean isEndcAvailable; + /** + * True if use of dual connectivity with NR is restricted. + * Reference: 3GPP TS 24.301 v15.03 section 9.3.3.12A. + */ + boolean isDcNrRestricted; + /** + * True if the bit N is in the PLMN-InfoList-r15 is true and the selected PLMN is present in + * plmn-IdentityList at position N. + * Reference: 3GPP TS 36.331 v15.2.2 section 6.3.1 PLMN-InfoList-r15. + * 3GPP TS 36.331 v15.2.2 section 6.2.2 SystemInformationBlockType1 message. + */ + boolean isNrAvailable; +} diff --git a/radio/aidl/android/hardware/radio/NrQos.aidl b/radio/aidl/android/hardware/radio/NrQos.aidl new file mode 100644 index 0000000000..3d0278c073 --- /dev/null +++ b/radio/aidl/android/hardware/radio/NrQos.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. + */ + +package android.hardware.radio; + +import android.hardware.radio.QosBandwidth; + +/** + * 5G Quality of Service parameters as per 3gpp spec 24.501 sec 9.11.4.12 + */ +@VintfStability +parcelable NrQos { + /** + * 5G QOS Identifier (5QI), see 3GPP TS 24.501 and 23.501. The allowed values are standard + * values (1-9, 65-68, 69-70, 75, 79-80, 82-85) defined in the spec and operator specific values + * in the range 128-254. + */ + int fiveQi; + QosBandwidth downlink; + QosBandwidth uplink; + /** + * QOS flow identifier of the QOS flow description in the range + * (QosFlowIdRange::MIN, QosFlowIdRange::MAX) + */ + byte qfi; + char averagingWindowMs; +} diff --git a/radio/aidl/android/hardware/radio/NrSignalStrength.aidl b/radio/aidl/android/hardware/radio/NrSignalStrength.aidl new file mode 100644 index 0000000000..40c6c3ebe0 --- /dev/null +++ b/radio/aidl/android/hardware/radio/NrSignalStrength.aidl @@ -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. + */ + +package android.hardware.radio; + +@VintfStability +parcelable NrSignalStrength { + /** + * SS reference signal received power, multiplied by -1. + * Reference: 3GPP TS 38.215. + * Range [44, 140], INT_MAX means invalid/unreported. + */ + int ssRsrp; + /** + * SS reference signal received quality, multiplied by -1. + * Reference: 3GPP TS 38.215, 3GPP TS 38.133 section 10. + * Range [-20 dB, 43 dB], INT_MAX means invalid/unreported. + */ + int ssRsrq; + /** + * SS signal-to-noise and interference ratio. + * Reference: 3GPP TS 38.215 section 5.1.*, 3GPP TS 38.133 section 10.1.16.1. + * Range [-23, 40], INT_MAX means invalid/unreported. + */ + int ssSinr; + /** + * CSI reference signal received power, multiplied by -1. + * Reference: 3GPP TS 38.215. + * Range [44, 140], INT_MAX means invalid/unreported. + */ + int csiRsrp; + /** + * CSI reference signal received quality, multiplied by -1. + * Reference: 3GPP TS 38.215. + * Range [3, 20], INT_MAX means invalid/unreported. + */ + int csiRsrq; + /** + * CSI signal-to-noise and interference ratio. + * Reference: 3GPP TS 138.215 section 5.1.*, 3GPP TS 38.133 section 10.1.16.1. + * Range [-23, 40], INT_MAX means invalid/unreported. + */ + int csiSinr; + /** + * CSI channel quality indicator (CQI) table index. There are multiple CQI tables. + * The definition of CQI in each table is different. + * Reference: 3GPP TS 138.214 section 5.2.2.1. + * Range [1, 3], INT_MAX means invalid/unreported. + */ + int csiCqiTableIndex; + /** + * CSI channel quality indicator (CQI) for all subbands. If the CQI report is for the entire + * wideband, a single CQI index is provided. If the CQI report is for all subbands, one CQI + * index is provided for each subband, in ascending order of subband index. If CQI is not + * available, the CQI report is empty. + * Reference: 3GPP TS 138.214 section 5.2.2.1. + * Range [0, 15], 0xFF means invalid/unreported. + */ + byte[] csiCqiReport; +} diff --git a/radio/aidl/android/hardware/radio/NrVopsInfo.aidl b/radio/aidl/android/hardware/radio/NrVopsInfo.aidl new file mode 100644 index 0000000000..4d80f32962 --- /dev/null +++ b/radio/aidl/android/hardware/radio/NrVopsInfo.aidl @@ -0,0 +1,54 @@ +/* + * 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.radio; + +import android.hardware.radio.EmcIndicator; +import android.hardware.radio.EmfIndicator; +import android.hardware.radio.VopsIndicator; + +/** + * Type to define the NR specific network capabilities for voice over PS including emergency and + * normal voice calls. + */ +@VintfStability +parcelable NrVopsInfo { + /** + * This indicates if the camped network supports VoNR services, and what kind of services + * it supports. This information is received from NR network during NR NAS registration + * procedure through NR REGISTRATION ACCEPT. + * Refer 3GPP 24.501 EPS 5GS network feature support -> IMS VoPS + */ + VopsIndicator vopsSupported; + /** + * This indicates if the camped network supports VoNR emergency service. This information + * is received from NR network through two sources: + * a. During NR NAS registration procedure through NR REGISTRATION ACCEPT. + * Refer 3GPP 24.501 EPS 5GS network feature support -> EMC + * b. In case the device is not registered on the network. + * Refer 3GPP 38.331 SIB1 : ims-EmergencySupport + * If device is registered on NR, then this field indicates whether the cell + * supports IMS emergency bearer services for UEs in limited service mode. + */ + EmcIndicator emcSupported; + /** + * This indicates if the camped network supports VoNR emergency service fallback. This + * information is received from NR network during NR NAS registration procedure through + * NR REGISTRATION ACCEPT. + * Refer 3GPP 24.501 EPS 5GS network feature support -> EMF + */ + EmfIndicator emfSupported; +} diff --git a/radio/aidl/android/hardware/radio/NvItem.aidl b/radio/aidl/android/hardware/radio/NvItem.aidl new file mode 100644 index 0000000000..0d4f79f150 --- /dev/null +++ b/radio/aidl/android/hardware/radio/NvItem.aidl @@ -0,0 +1,191 @@ +/* + * 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.radio; + +@VintfStability +@Backing(type="int") +enum NvItem { + /** + * CDMA radio and account information (items 1-10) + * CDMA MEID (hex) + */ + CDMA_MEID = 1, + /** + * CDMA MIN (MSID) + */ + CDMA_MIN = 2, + /** + * CDMA MDN + */ + CDMA_MDN = 3, + /** + * CDMA access overload control + */ + CDMA_ACCOLC = 4, + /** + * Carrier device provisioning (items 11-30) + * Device MSL + */ + DEVICE_MSL = 11, + /** + * RTN reconditioned status + */ + RTN_RECONDITIONED_STATUS = 12, + /** + * RTN activation date + */ + RTN_ACTIVATION_DATE = 13, + /** + * RTN life timer + */ + RTN_LIFE_TIMER = 14, + /** + * RTN life calls + */ + RTN_LIFE_CALLS = 15, + /** + * RTN life data TX + */ + RTN_LIFE_DATA_TX = 16, + /** + * RTN life data RX + */ + RTN_LIFE_DATA_RX = 17, + /** + * HFA in progress + */ + OMADM_HFA_LEVEL = 18, + /** + * Mobile IP profile information (items 31-50) + * NAI realm + */ + MIP_PROFILE_NAI = 31, + /** + * MIP home address + */ + MIP_PROFILE_HOME_ADDRESS = 32, + /** + * AAA auth + */ + MIP_PROFILE_AAA_AUTH = 33, + /** + * HA auth + */ + MIP_PROFILE_HA_AUTH = 34, + /** + * Primary HA address + */ + MIP_PROFILE_PRI_HA_ADDR = 35, + /** + * Secondary HA address + */ + MIP_PROFILE_SEC_HA_ADDR = 36, + /** + * Reverse TUN preference + */ + MIP_PROFILE_REV_TUN_PREF = 37, + /** + * HA SPI + */ + MIP_PROFILE_HA_SPI = 38, + /** + * AAA SPI + */ + MIP_PROFILE_AAA_SPI = 39, + /** + * HA shared secret + */ + MIP_PROFILE_MN_HA_SS = 40, + /** + * AAA shared secret + */ + MIP_PROFILE_MN_AAA_SS = 41, + /** + * CDMA network and band config (items 51-70) + * CDMA PRL version + */ + CDMA_PRL_VERSION = 51, + /** + * CDMA band class 10 + */ + CDMA_BC10 = 52, + /** + * CDMA band class 14 + */ + CDMA_BC14 = 53, + /** + * CDMA SO68 + */ + CDMA_SO68 = 54, + /** + * CDMA SO73 COP0 + */ + CDMA_SO73_COP0 = 55, + /** + * CDMA SO73 COP1-7 + */ + CDMA_SO73_COP1TO7 = 56, + /** + * CDMA 1X Advanced enabled + */ + CDMA_1X_ADVANCED_ENABLED = 57, + /** + * CDMA eHRPD enabled + */ + CDMA_EHRPD_ENABLED = 58, + /** + * CDMA eHRPD forced + */ + CDMA_EHRPD_FORCED = 59, + /** + * LTE network and band config (items 71-90) + * LTE band 25 enabled + */ + LTE_BAND_ENABLE_25 = 71, + /** + * LTE band 26 enabled + */ + LTE_BAND_ENABLE_26 = 72, + /** + * LTE band 41 enabled + */ + LTE_BAND_ENABLE_41 = 73, + /** + * LTE band 25 scan priority + */ + LTE_SCAN_PRIORITY_25 = 74, + /** + * LTE band 26 scan priority + */ + LTE_SCAN_PRIORITY_26 = 75, + /** + * LTE band 41 scan priority + */ + LTE_SCAN_PRIORITY_41 = 76, + /** + * LTE hidden band 25 priority + */ + LTE_HIDDEN_BAND_PRIORITY_25 = 77, + /** + * LTE hidden band 26 priority + */ + LTE_HIDDEN_BAND_PRIORITY_26 = 78, + /** + * LTE hidden band 41 priority + */ + LTE_HIDDEN_BAND_PRIORITY_41 = 79, +} diff --git a/radio/aidl/android/hardware/radio/NvWriteItem.aidl b/radio/aidl/android/hardware/radio/NvWriteItem.aidl new file mode 100644 index 0000000000..f3061612b4 --- /dev/null +++ b/radio/aidl/android/hardware/radio/NvWriteItem.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.radio; + +import android.hardware.radio.NvItem; + +@VintfStability +parcelable NvWriteItem { + NvItem itemId; + String value; +} diff --git a/radio/aidl/android/hardware/radio/OperatorInfo.aidl b/radio/aidl/android/hardware/radio/OperatorInfo.aidl new file mode 100644 index 0000000000..4475ff5506 --- /dev/null +++ b/radio/aidl/android/hardware/radio/OperatorInfo.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.radio; + +import android.hardware.radio.OperatorStatus; + +@VintfStability +parcelable OperatorInfo { + /** + * Long alpha ONS or EONS + */ + String alphaLong; + /** + * Short alpha ONS or EONS + */ + String alphaShort; + /** + * 5 or 6 digit numeric code (MCC + MNC) + */ + String operatorNumeric; + OperatorStatus status; +} diff --git a/radio/aidl/android/hardware/radio/OperatorStatus.aidl b/radio/aidl/android/hardware/radio/OperatorStatus.aidl new file mode 100644 index 0000000000..fcc31eca2f --- /dev/null +++ b/radio/aidl/android/hardware/radio/OperatorStatus.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.radio; + +@VintfStability +@Backing(type="int") +enum OperatorStatus { + UNKNOWN, + AVAILABLE, + CURRENT, + FORBIDDEN, +} diff --git a/radio/aidl/android/hardware/radio/OptionalCsgInfo.aidl b/radio/aidl/android/hardware/radio/OptionalCsgInfo.aidl new file mode 100644 index 0000000000..f7856933a7 --- /dev/null +++ b/radio/aidl/android/hardware/radio/OptionalCsgInfo.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.radio; + +import android.hardware.radio.ClosedSubscriberGroupInfo; + +@VintfStability +union OptionalCsgInfo { + /** + * If no CSG info is provided by the cell, then this structure shall be present. + */ + boolean noinit; + /** + * If CSG info is provided by the cell, this structure shall be present. + */ + ClosedSubscriberGroupInfo csgInfo; +} diff --git a/radio/aidl/android/hardware/radio/OptionalDnn.aidl b/radio/aidl/android/hardware/radio/OptionalDnn.aidl new file mode 100644 index 0000000000..1c38a7103c --- /dev/null +++ b/radio/aidl/android/hardware/radio/OptionalDnn.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.radio; + +/** + * This safe_union represents an optional DNN. DNN stands for Data Network Name and represents + * an APN as defined in 3GPP TS 23.003. + */ +@VintfStability +union OptionalDnn { + boolean noinit; + String value; +} diff --git a/radio/aidl/android/hardware/radio/OptionalOsAppId.aidl b/radio/aidl/android/hardware/radio/OptionalOsAppId.aidl new file mode 100644 index 0000000000..4614601af6 --- /dev/null +++ b/radio/aidl/android/hardware/radio/OptionalOsAppId.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.radio; + +import android.hardware.radio.OsAppId; + +/** + * This safe_union represents an optional OsAppId. + */ +@VintfStability +union OptionalOsAppId { + boolean noinit; + OsAppId value; +} diff --git a/radio/aidl/android/hardware/radio/OptionalPdpProtocolType.aidl b/radio/aidl/android/hardware/radio/OptionalPdpProtocolType.aidl new file mode 100644 index 0000000000..7e51b83756 --- /dev/null +++ b/radio/aidl/android/hardware/radio/OptionalPdpProtocolType.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.radio; + +import android.hardware.radio.PdpProtocolType; + +/** + * This safe_union represents an optional PdpProtocolType. + */ +@VintfStability +union OptionalPdpProtocolType { + boolean noinit; + PdpProtocolType value; +} diff --git a/radio/aidl/android/hardware/radio/OptionalSliceInfo.aidl b/radio/aidl/android/hardware/radio/OptionalSliceInfo.aidl new file mode 100644 index 0000000000..cfc309c49f --- /dev/null +++ b/radio/aidl/android/hardware/radio/OptionalSliceInfo.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.radio; + +import android.hardware.radio.SliceInfo; + +/** + * This safe_union represents an optional slice info. + */ +@VintfStability +union OptionalSliceInfo { + boolean noinit; + SliceInfo value; +} diff --git a/radio/aidl/android/hardware/radio/OptionalSscMode.aidl b/radio/aidl/android/hardware/radio/OptionalSscMode.aidl new file mode 100644 index 0000000000..22933b93b3 --- /dev/null +++ b/radio/aidl/android/hardware/radio/OptionalSscMode.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.radio; + +import android.hardware.radio.SscMode; + +/** + * This safe_union represents an optional SscMode. + */ +@VintfStability +union OptionalSscMode { + boolean noinit; + SscMode value; +} diff --git a/radio/aidl/android/hardware/radio/OptionalTrafficDescriptor.aidl b/radio/aidl/android/hardware/radio/OptionalTrafficDescriptor.aidl new file mode 100644 index 0000000000..b524cb3a77 --- /dev/null +++ b/radio/aidl/android/hardware/radio/OptionalTrafficDescriptor.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.radio; + +import android.hardware.radio.TrafficDescriptor; + +/** + * This safe_union represents an optional TrafficDescriptor. + */ +@VintfStability +union OptionalTrafficDescriptor { + boolean noinit; + TrafficDescriptor value; +} diff --git a/radio/aidl/android/hardware/radio/OsAppId.aidl b/radio/aidl/android/hardware/radio/OsAppId.aidl new file mode 100644 index 0000000000..57dfc80168 --- /dev/null +++ b/radio/aidl/android/hardware/radio/OsAppId.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.radio; + +/** + * This struct represents the OsId + OsAppId as defined in TS 24.526 Section 5.2 + */ +@VintfStability +parcelable OsAppId { + /** + * Byte array representing OsId + OsAppId. The minimum length of the array is 18 and maximum + * length is 272 (16 bytes for OsId + 1 byte for OsAppId length + up to 255 bytes for OsAppId). + */ + byte[] osAppId; +} diff --git a/radio/aidl/android/hardware/radio/P2Constant.aidl b/radio/aidl/android/hardware/radio/P2Constant.aidl new file mode 100644 index 0000000000..d40a44645a --- /dev/null +++ b/radio/aidl/android/hardware/radio/P2Constant.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.radio; + +@VintfStability +@Backing(type="int") +enum P2Constant { + /** + * No P2 value is provided + */ + NO_P2 = -1, +} diff --git a/radio/aidl/android/hardware/radio/PbReceivedStatus.aidl b/radio/aidl/android/hardware/radio/PbReceivedStatus.aidl new file mode 100644 index 0000000000..44ed4d95e5 --- /dev/null +++ b/radio/aidl/android/hardware/radio/PbReceivedStatus.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. + */ + +package android.hardware.radio; + +/** + * Enum representing the status of the received PB indication. + */ +@VintfStability +@Backing(type="byte") +enum PbReceivedStatus { + /** + * Indicates that retrieval is fine. + */ + PB_RECEIVED_OK = 1, + /** + * Indicates that an error happened. In general, the process can't be restored soon. + */ + PB_RECEIVED_ERROR = 2, + /** + * Indicates that the process is interrupted. In this case, the modem might need resources and + * interrupt the current process, or it is timed out to receive all indications, and client can + * retry soon. + */ + PB_RECEIVED_ABORT = 3, + /** + * Indicates that the whole process is finished with a full chunk of phonebook data, meaning + * this is the last indication with the remaining data. + */ + PB_RECEIVED_FINAL = 4, +} diff --git a/radio/aidl/android/hardware/radio/PcoDataInfo.aidl b/radio/aidl/android/hardware/radio/PcoDataInfo.aidl new file mode 100644 index 0000000000..7b600e6622 --- /dev/null +++ b/radio/aidl/android/hardware/radio/PcoDataInfo.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.radio; + +@VintfStability +parcelable PcoDataInfo { + /** + * Context ID, uniquely identifies this call + */ + int cid; + /** + * One of the PDP_type values in TS 27.007 section 10.1.1. For example, "IP", "IPV6", "IPV4V6" + */ + String bearerProto; + /** + * The protocol ID for this box. Note that only IDs from FF00H - FFFFH are accepted. + * If more than one is included from the network, multiple calls must be made to send + * all of them. + */ + int pcoId; + /** + * Carrier-defined content. It is binary, opaque and loosely defined in LTE Layer 3 spec 24.008 + */ + byte[] contents; +} diff --git a/radio/aidl/android/hardware/radio/PdpProtocolType.aidl b/radio/aidl/android/hardware/radio/PdpProtocolType.aidl new file mode 100644 index 0000000000..e74b1e3da2 --- /dev/null +++ b/radio/aidl/android/hardware/radio/PdpProtocolType.aidl @@ -0,0 +1,53 @@ +/* + * 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.radio; + +/** + * Specifies the type of packet data protocol which is defined in TS 27.007 section 10.1.1. + */ +@VintfStability +@Backing(type="int") +enum PdpProtocolType { + /** + * Unknown protocol + */ + UNKNOWN = -1, + /** + * Internet protocol + */ + IP = 0, + /** + * Internet protocol, version 6 + */ + IPV6 = 1, + /** + * Virtual PDP type introduced to handle dual IP stack UE capability. + */ + IPV4V6 = 2, + /** + * Point to point protocol + */ + PPP = 3, + /** + * Transfer of Non-IP data to external packet data network + */ + NON_IP = 4, + /** + * Transfer of Unstructured data to the Data Network via N6 + */ + UNSTRUCTURED = 5, +} diff --git a/radio/aidl/android/hardware/radio/PersoSubstate.aidl b/radio/aidl/android/hardware/radio/PersoSubstate.aidl new file mode 100644 index 0000000000..93b2af53c4 --- /dev/null +++ b/radio/aidl/android/hardware/radio/PersoSubstate.aidl @@ -0,0 +1,98 @@ +/* + * 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.radio; + +/** + * Additional personalization categories in addition to those specified in 3GPP TS 22.022 and + * 3GPP2 C.S0068-0. + */ +@VintfStability +@Backing(type="int") +enum PersoSubstate { + /** + * Initial state + */ + UNKNOWN, + /** + * In between each lock transition + */ + IN_PROGRESS, + /** + * When either SIM or RUIM Perso is finished since each app must only have 1 active perso + * involved. + */ + READY, + SIM_NETWORK, + SIM_NETWORK_SUBSET, + SIM_CORPORATE, + SIM_SERVICE_PROVIDER, + SIM_SIM, + /** + * The corresponding perso lock is blocked + */ + SIM_NETWORK_PUK, + SIM_NETWORK_SUBSET_PUK, + SIM_CORPORATE_PUK, + SIM_SERVICE_PROVIDER_PUK, + SIM_SIM_PUK, + RUIM_NETWORK1, + RUIM_NETWORK2, + RUIM_HRPD, + RUIM_CORPORATE, + RUIM_SERVICE_PROVIDER, + RUIM_RUIM, + /** + * The corresponding perso lock is blocked + */ + RUIM_NETWORK1_PUK, + RUIM_NETWORK2_PUK, + RUIM_HRPD_PUK, + RUIM_CORPORATE_PUK, + RUIM_SERVICE_PROVIDER_PUK, + RUIM_RUIM_PUK, + /** + * The device is personalized using the content of the Service Provider Name (SPN) in the SIM + * card. + */ + SIM_SPN, + SIM_SPN_PUK, + /** + * Service Provider and Equivalent Home PLMN. The device is personalized using both the content + * of the GID1 (equivalent to service provider personalization) and the content of the + * Equivalent Home PLMN (EHPLMN) in the SIM card. If the GID1 in the SIM is absent, then just + * the content of the Equivalent Home PLMN is matched. + */ + SIM_SP_EHPLMN, + SIM_SP_EHPLMN_PUK, + /** + * Device is personalized using the first digits of the ICCID of the SIM card. + */ + SIM_ICCID, + SIM_ICCID_PUK, + /** + * Device is personalized using the content of the IMPI in the ISIM. + */ + SIM_IMPI, + SIM_IMPI_PUK, + /** + * Network Subset and Service Provider. Device is personalized using both the content of GID1 + * (equivalent to service provider personalization) and the first digits of the IMSI (equivalent + * to network subset personalization). + */ + SIM_NS_SP, + SIM_NS_SP_PUK, +} diff --git a/radio/aidl/android/hardware/radio/PhoneRestrictedState.aidl b/radio/aidl/android/hardware/radio/PhoneRestrictedState.aidl new file mode 100644 index 0000000000..5f5f1b8a39 --- /dev/null +++ b/radio/aidl/android/hardware/radio/PhoneRestrictedState.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. + */ + +package android.hardware.radio; + +@VintfStability +@Backing(type="int") +enum PhoneRestrictedState { + /** + * No restriction at all including voice/SMS/USSD/SS/AV64 and packet data. + */ + NONE = 0x00, + /** + * Block emergency call due to restriction. But allow all normal voice/SMS/USSD/SS/AV64. + */ + CS_EMERGENCY = 0x01, + /** + * Block all normal voice/SMS/USSD/SS/AV64 due to restriction. Only Emergency call allowed. + */ + CS_NORMAL = 0x02, + /** + * Block all voice/SMS/USSD/SS/AV64 including emergency call due to restriction. + */ + CS_ALL = 0x04, + /** + * Block packet data access due to restriction. + */ + PS_ALL = 0x10, +} diff --git a/radio/aidl/android/hardware/radio/PhonebookCapacity.aidl b/radio/aidl/android/hardware/radio/PhonebookCapacity.aidl new file mode 100644 index 0000000000..c14141114b --- /dev/null +++ b/radio/aidl/android/hardware/radio/PhonebookCapacity.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.radio; + +@VintfStability +parcelable PhonebookCapacity { + /** + * Maximum number of ADN records possible in the SIM phonebook. Needs to be non-negative. + */ + int maxAdnRecords; + /** + * Used ADN records in the SIM phonebook. Needs to be non-negative. + */ + int usedAdnRecords; + /** + * Maximum email records possible in the SIM phonebook. Needs to be non-negative. + */ + int maxEmailRecords; + /** + * Used email records in the SIM phonebook. Needs to be non-negative. + */ + int usedEmailRecords; + /** + * Maximum additional number records possible in the SIM phonebook. Needs to be non-negative. + */ + int maxAdditionalNumberRecords; + /** + * Used additional number records in the SIM phonebook. Needs to be non-negative. + */ + int usedAdditionalNumberRecords; + /** + * Maximum name length possible in the SIM phonebook. Needs to be non-negative. + */ + int maxNameLen; + /** + * Maximum number length possible in the SIM phonebook. Needs to be non-negative. + */ + int maxNumberLen; + /** + * Maximum email length possible in the SIM phonebook. Needs to be non-negative. + */ + int maxEmailLen; + /** + * Maximum additional number length possible in the SIM phonebook. Needs to be non-negative. + */ + int maxAdditionalNumberLen; +} diff --git a/radio/aidl/android/hardware/radio/PhonebookRecordInfo.aidl b/radio/aidl/android/hardware/radio/PhonebookRecordInfo.aidl new file mode 100644 index 0000000000..eb0c880d26 --- /dev/null +++ b/radio/aidl/android/hardware/radio/PhonebookRecordInfo.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.radio; + +/** + * Phonebook-record-information specified by EF_ADN (Abbreviated dialing numbers) record of SIM + * as per 3GPP spec 31.102 v15 Section-4.4.2.3. + */ +@VintfStability +parcelable PhonebookRecordInfo { + /** + * Record index. 0 is used to insert a record + */ + int recordId; + /** + * Alpha identifier, empty string if no value + */ + String name; + /** + * Dialling number, empty string if no value + */ + String number; + /** + * Email addresses + */ + String[] emails; + /** + * Additional numbers + */ + String[] additionalNumbers; +} diff --git a/radio/aidl/android/hardware/radio/PhysicalChannelConfig.aidl b/radio/aidl/android/hardware/radio/PhysicalChannelConfig.aidl new file mode 100644 index 0000000000..05b31e5dbf --- /dev/null +++ b/radio/aidl/android/hardware/radio/PhysicalChannelConfig.aidl @@ -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. + */ + +package android.hardware.radio; + +import android.hardware.radio.CellConnectionStatus; +import android.hardware.radio.PhysicalChannelConfigBand; +import android.hardware.radio.RadioTechnology; + +@VintfStability +parcelable PhysicalChannelConfig { + /** + * Connection status for cell. Valid values are PRIMARY_SERVING and SECONDARY_SERVING + */ + CellConnectionStatus status; + /** + * The radio technology for this physical channel + */ + RadioTechnology rat; + /** + * Downlink Absolute Radio Frequency Channel Number + */ + int downlinkChannelNumber; + /** + * Uplink Absolute Radio Frequency Channel Number + */ + int uplinkChannelNumber; + /** + * Downlink cell bandwidth, in kHz + */ + int cellBandwidthDownlinkKhz; + /** + * Uplink cell bandwidth, in kHz + */ + int cellBandwidthUplinkKhz; + /** + * A list of data calls mapped to this physical channel. The context id must match the cid of + * SetupDataCallResult. An empty list means the physical channel has no data call mapped to it. + */ + int[] contextIds; + /** + * The physical cell identifier for this cell. + * In UTRAN, this value is primary scrambling code. The range is [0, 511]. + * Reference: 3GPP TS 25.213 section 5.2.2. + * In EUTRAN, this value is physical layer cell identity. The range is [0, 503]. + * Reference: 3GPP TS 36.211 section 6.11. + * In NGRAN, this value is physical layer cell identity. The range is [0, 1007]. + * Reference: 3GPP TS 38.211 section 7.4.2.1. + */ + int physicalCellId; + /** + * The frequency band to scan. + */ + PhysicalChannelConfigBand band; +} diff --git a/radio/aidl/android/hardware/radio/PhysicalChannelConfigBand.aidl b/radio/aidl/android/hardware/radio/PhysicalChannelConfigBand.aidl new file mode 100644 index 0000000000..953b1c4b28 --- /dev/null +++ b/radio/aidl/android/hardware/radio/PhysicalChannelConfigBand.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.radio; + +import android.hardware.radio.EutranBands; +import android.hardware.radio.GeranBands; +import android.hardware.radio.NgranBands; +import android.hardware.radio.UtranBands; + +@VintfStability +union PhysicalChannelConfigBand { + boolean noinit; + /** + * Valid only if radioAccessNetwork = GERAN. + */ + GeranBands geranBand; + /** + * Valid only if radioAccessNetwork = UTRAN. + */ + UtranBands utranBand; + /** + * Valid only if radioAccessNetwork = EUTRAN. + */ + EutranBands eutranBand; + /** + * Valid only if radioAccessNetwork = NGRAN. + */ + NgranBands ngranBand; +} diff --git a/radio/aidl/android/hardware/radio/PinState.aidl b/radio/aidl/android/hardware/radio/PinState.aidl new file mode 100644 index 0000000000..cb42ff232b --- /dev/null +++ b/radio/aidl/android/hardware/radio/PinState.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.radio; + +@VintfStability +@Backing(type="int") +enum PinState { + UNKNOWN, + ENABLED_NOT_VERIFIED, + ENABLED_VERIFIED, + DISABLED, + ENABLED_BLOCKED, + ENABLED_PERM_BLOCKED, +} diff --git a/radio/aidl/android/hardware/radio/PortRange.aidl b/radio/aidl/android/hardware/radio/PortRange.aidl new file mode 100644 index 0000000000..932d54a304 --- /dev/null +++ b/radio/aidl/android/hardware/radio/PortRange.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.radio; + +/** + * Defines range of ports. start and end are the first and last port numbers (inclusive) in the + * range. Both start and end are in QosPortRange.MIN to QosPortRange.MAX range. A single port shall + * be represented by the same start and end value. + */ +@VintfStability +parcelable PortRange { + int start; + int end; +} diff --git a/radio/aidl/android/hardware/radio/PreferredNetworkType.aidl b/radio/aidl/android/hardware/radio/PreferredNetworkType.aidl new file mode 100644 index 0000000000..7ca38c6a79 --- /dev/null +++ b/radio/aidl/android/hardware/radio/PreferredNetworkType.aidl @@ -0,0 +1,114 @@ +/* + * 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.radio; + +@VintfStability +@Backing(type="int") +enum PreferredNetworkType { + /** + * GSM/WCDMA (WCDMA preferred) + */ + GSM_WCDMA, + /** + * GSM only + */ + GSM_ONLY, + /** + * WCDMA + */ + WCDMA, + /** + * GSM/WCDMA (auto mode, according to PRL) + */ + GSM_WCDMA_AUTO, + /** + * CDMA and EvDo (auto mode, according to PRL) + */ + CDMA_EVDO_AUTO, + /** + * CDMA only + */ + CDMA_ONLY, + /** + * EvDo only + */ + EVDO_ONLY, + /** + * GSM/WCDMA, CDMA, and EvDo (auto mode, according to PRL) + */ + GSM_WCDMA_CDMA_EVDO_AUTO, + /** + * LTE, CDMA and EvDo + */ + LTE_CDMA_EVDO, + /** + * LTE, GSM/WCDMA + */ + LTE_GSM_WCDMA, + /** + * LTE, CDMA, EvDo, GSM/WCDMA + */ + LTE_CMDA_EVDO_GSM_WCDMA, + /** + * LTE only + */ + LTE_ONLY, + /** + * LTE/WCDMA only + */ + LTE_WCDMA, + /** + * TD-SCDMA only + */ + TD_SCDMA_ONLY, + /** + * TD-SCDMA and WCDMA + */ + TD_SCDMA_WCDMA, + /** + * TD-SCDMA and LTE + */ + TD_SCDMA_LTE, + /** + * TD-SCDMA and GSM + */ + TD_SCDMA_GSM, + /** + * TD-SCDMA,GSM and LTE + */ + TD_SCDMA_GSM_LTE, + /** + * TD-SCDMA, GSM/WCDMA + */ + TD_SCDMA_GSM_WCDMA, + /** + * TD-SCDMA, WCDMA and LTE + */ + TD_SCDMA_WCDMA_LTE, + /** + * TD-SCDMA, GSM/WCDMA and LTE + */ + TD_SCDMA_GSM_WCDMA_LTE, + /** + * TD-SCDMA, GSM/WCDMA, CDMA and EvDo + */ + TD_SCDMA_GSM_WCDMA_CDMA_EVDO_AUTO, + /** + * TD-SCDMA, LTE, CDMA, EvDo GSM/WCDMA + */ + TD_SCDMA_LTE_CDMA_EVDO_GSM_WCDMA, +} diff --git a/radio/aidl/android/hardware/radio/PrlIndicator.aidl b/radio/aidl/android/hardware/radio/PrlIndicator.aidl new file mode 100644 index 0000000000..acd870e116 --- /dev/null +++ b/radio/aidl/android/hardware/radio/PrlIndicator.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.radio; + +@VintfStability +@Backing(type="int") +enum PrlIndicator { + NOT_REGISTERED = -1, + NOT_IN_PRL = 0, + IN_PRL = 1, +} diff --git a/radio/aidl/android/hardware/radio/PublicKeyType.aidl b/radio/aidl/android/hardware/radio/PublicKeyType.aidl new file mode 100644 index 0000000000..c1babc4356 --- /dev/null +++ b/radio/aidl/android/hardware/radio/PublicKeyType.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.radio; + +/** + * Public key type from carrier certificate. + */ +@VintfStability +@Backing(type="byte") +enum PublicKeyType { + /** + * Key type to be used for ePDG + */ + EPDG = 1, + /** + * Key type to be used for WLAN + */ + WLAN = 2, +} diff --git a/radio/aidl/android/hardware/radio/Qos.aidl b/radio/aidl/android/hardware/radio/Qos.aidl new file mode 100644 index 0000000000..0f84ad1406 --- /dev/null +++ b/radio/aidl/android/hardware/radio/Qos.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.radio; + +import android.hardware.radio.EpsQos; +import android.hardware.radio.NrQos; + +/** + * EPS or NR QOS parameters + */ +@VintfStability +union Qos { + boolean noinit; + EpsQos eps; + NrQos nr; +} diff --git a/radio/aidl/android/hardware/radio/QosBandwidth.aidl b/radio/aidl/android/hardware/radio/QosBandwidth.aidl new file mode 100644 index 0000000000..344b796ed9 --- /dev/null +++ b/radio/aidl/android/hardware/radio/QosBandwidth.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.radio; + +@VintfStability +parcelable QosBandwidth { + /** + * Maximum bit rate possible on the bearer + */ + int maxBitrateKbps; + /** + * Minimum bit rate that is guaranteed to be provided by the network + */ + int guaranteedBitrateKbps; +} diff --git a/radio/aidl/android/hardware/radio/QosFilter.aidl b/radio/aidl/android/hardware/radio/QosFilter.aidl new file mode 100644 index 0000000000..717944a8fa --- /dev/null +++ b/radio/aidl/android/hardware/radio/QosFilter.aidl @@ -0,0 +1,69 @@ +/* + * 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.radio; + +import android.hardware.radio.MaybePort; +import android.hardware.radio.QosFilterDirection; +import android.hardware.radio.QosFilterIpsecSpi; +import android.hardware.radio.QosFilterIpv6FlowLabel; +import android.hardware.radio.QosFilterTypeOfService; +import android.hardware.radio.QosProtocol; + +/** + * See 3gpp 24.008 10.5.6.12 and 3gpp 24.501 9.11.4.13 + */ +@VintfStability +parcelable QosFilter { + /** + * Local and remote IP addresses, typically one IPv4 or one IPv6 or one of each. Addresses could + * be with optional "/" prefix length, e.g.,"192.0.1.3" or "192.0.1.11/16 2001:db8::1/64". + * If the prefix length is absent the addresses are assumed to be point to point with IPv4 + * having a prefix length of 32 and IPv6 128. + */ + String[] localAddresses; + String[] remoteAddresses; + /** + * Local and remote port/ranges + */ + MaybePort localPort; + MaybePort remotePort; + /** + * QoS protocol + */ + QosProtocol protocol; + /** + * Type of service value or mask as defined in RFC 1349 + */ + QosFilterTypeOfService tos; + /** + * IPv6 flow label as defined in RFC 6437 + */ + QosFilterIpv6FlowLabel flowLabel; + /** + * IPSec security parameter index + */ + QosFilterIpsecSpi spi; + /** + * Filter direction + */ + QosFilterDirection direction; + /** + * Specifies the order in which the filter needs to be matched. A lower numerical (positive) + * value has a higher precedence. Set -1 when unspecified. + */ + int precedence; +} diff --git a/radio/aidl/android/hardware/radio/QosFilterDirection.aidl b/radio/aidl/android/hardware/radio/QosFilterDirection.aidl new file mode 100644 index 0000000000..7693c8cf2c --- /dev/null +++ b/radio/aidl/android/hardware/radio/QosFilterDirection.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.radio; + +@VintfStability +@Backing(type="byte") +enum QosFilterDirection { + DOWNLINK, + UPLINK, + BIDIRECTIONAL, +} diff --git a/radio/aidl/android/hardware/radio/QosFilterIpsecSpi.aidl b/radio/aidl/android/hardware/radio/QosFilterIpsecSpi.aidl new file mode 100644 index 0000000000..e213402bc1 --- /dev/null +++ b/radio/aidl/android/hardware/radio/QosFilterIpsecSpi.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.radio; + +@VintfStability +union QosFilterIpsecSpi { + boolean noinit; + int value; +} diff --git a/radio/aidl/android/hardware/radio/QosFilterIpv6FlowLabel.aidl b/radio/aidl/android/hardware/radio/QosFilterIpv6FlowLabel.aidl new file mode 100644 index 0000000000..d5c5a6c830 --- /dev/null +++ b/radio/aidl/android/hardware/radio/QosFilterIpv6FlowLabel.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.radio; + +@VintfStability +union QosFilterIpv6FlowLabel { + boolean noinit; + int value; +} diff --git a/radio/aidl/android/hardware/radio/QosFilterTypeOfService.aidl b/radio/aidl/android/hardware/radio/QosFilterTypeOfService.aidl new file mode 100644 index 0000000000..b91323cb43 --- /dev/null +++ b/radio/aidl/android/hardware/radio/QosFilterTypeOfService.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.radio; + +@VintfStability +union QosFilterTypeOfService { + boolean noinit; + byte value; +} diff --git a/radio/aidl/android/hardware/radio/QosFlowIdRange.aidl b/radio/aidl/android/hardware/radio/QosFlowIdRange.aidl new file mode 100644 index 0000000000..df2398b193 --- /dev/null +++ b/radio/aidl/android/hardware/radio/QosFlowIdRange.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.radio; + +/** + * Allowed values for 5G QOS flow identifier + */ +@VintfStability +@Backing(type="byte") +enum QosFlowIdRange { + MIN = 1, + MAX = 63, +} diff --git a/radio/aidl/android/hardware/radio/QosPortRange.aidl b/radio/aidl/android/hardware/radio/QosPortRange.aidl new file mode 100644 index 0000000000..f3df19f956 --- /dev/null +++ b/radio/aidl/android/hardware/radio/QosPortRange.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.radio; + +/** + * Allowed port numbers + */ +@VintfStability +@Backing(type="int") +enum QosPortRange { + MIN = 20, + MAX = 65535, +} diff --git a/radio/aidl/android/hardware/radio/QosProtocol.aidl b/radio/aidl/android/hardware/radio/QosProtocol.aidl new file mode 100644 index 0000000000..05cd670b18 --- /dev/null +++ b/radio/aidl/android/hardware/radio/QosProtocol.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.radio; + +/** + * Next header protocol numbers defined by IANA, RFC 5237 + */ +@VintfStability +@Backing(type="byte") +enum QosProtocol { + /** + * No protocol specified + */ + UNSPECIFIED = -1, + /** + * Transmission Control Protocol + */ + TCP = 6, + /** + * User Datagram Protocol + */ + UDP = 17, + /** + * Encapsulating Security Payload Protocol + */ + ESP = 50, + /** + * Authentication Header + */ + AH = 51, +} diff --git a/radio/aidl/android/hardware/radio/QosSession.aidl b/radio/aidl/android/hardware/radio/QosSession.aidl new file mode 100644 index 0000000000..2620ac5af1 --- /dev/null +++ b/radio/aidl/android/hardware/radio/QosSession.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.radio; + +import android.hardware.radio.Qos; +import android.hardware.radio.QosFilter; + +/** + * QOS session associated with a dedicated bearer + */ +@VintfStability +parcelable QosSession { + /** + * Unique ID of the QoS session within the data call + */ + int qosSessionId; + /** + * QOS attributes + */ + Qos qos; + /** + * List of QOS filters associated with this session + */ + QosFilter[] qosFilters; +} diff --git a/radio/aidl/android/hardware/radio/RadioAccessFamily.aidl b/radio/aidl/android/hardware/radio/RadioAccessFamily.aidl new file mode 100644 index 0000000000..719837dd56 --- /dev/null +++ b/radio/aidl/android/hardware/radio/RadioAccessFamily.aidl @@ -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. + */ + +package android.hardware.radio; + +import android.hardware.radio.RadioTechnology; + +@VintfStability +@Backing(type="int") +enum RadioAccessFamily { + UNKNOWN = 1 << RadioTechnology.UNKNOWN, + GPRS = 1 << RadioTechnology.GPRS, + EDGE = 1 << RadioTechnology.EDGE, + UMTS = 1 << RadioTechnology.UMTS, + IS95A = 1 << RadioTechnology.IS95A, + IS95B = 1 << RadioTechnology.IS95B, + ONE_X_RTT = 1 << RadioTechnology.ONE_X_RTT, + EVDO_0 = 1 << RadioTechnology.EVDO_0, + EVDO_A = 1 << RadioTechnology.EVDO_A, + HSDPA = 1 << RadioTechnology.HSDPA, + HSUPA = 1 << RadioTechnology.HSUPA, + HSPA = 1 << RadioTechnology.HSPA, + EVDO_B = 1 << RadioTechnology.EVDO_B, + EHRPD = 1 << RadioTechnology.EHRPD, + LTE = 1 << RadioTechnology.LTE, + HSPAP = 1 << RadioTechnology.HSPAP, + GSM = 1 << RadioTechnology.GSM, + TD_SCDMA = 1 << RadioTechnology.TD_SCDMA, + LTE_CA = 1 << RadioTechnology.LTE_CA, + /** + * 5G NR. This is only use in 5G Standalone mode. + */ + NR = 1 << RadioTechnology.NR, +} diff --git a/radio/aidl/android/hardware/radio/RadioAccessNetworks.aidl b/radio/aidl/android/hardware/radio/RadioAccessNetworks.aidl new file mode 100644 index 0000000000..3757233f24 --- /dev/null +++ b/radio/aidl/android/hardware/radio/RadioAccessNetworks.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.radio; + +@VintfStability +@Backing(type="int") +enum RadioAccessNetworks { + UNKNOWN, + /** + * GSM EDGE Radio Access Network + */ + GERAN, + /** + * Universal Terrestrial Radio Access Network + */ + UTRAN, + /** + * Evolved Universal Terrestrial Radio Access Network + */ + EUTRAN, + /** + * Next Generation Radio Access Network + */ + NGRAN, + /** + * CDMA 2000 Network + */ + CDMA2000, +} diff --git a/radio/aidl/android/hardware/radio/RadioAccessSpecifier.aidl b/radio/aidl/android/hardware/radio/RadioAccessSpecifier.aidl new file mode 100644 index 0000000000..889124a728 --- /dev/null +++ b/radio/aidl/android/hardware/radio/RadioAccessSpecifier.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.radio; + +import android.hardware.radio.RadioAccessNetworks; +import android.hardware.radio.RadioAccessSpecifierBands; + +@VintfStability +parcelable RadioAccessSpecifier { + /** + * The type of network to scan. + */ + RadioAccessNetworks radioAccessNetwork; + /** + * The frequency bands to scan. Maximum length of the vector is 8. + */ + RadioAccessSpecifierBands bands; + /** + * The radio channels to scan as defined in 3GPP TS 25.101 and 36.101. + * Maximum length of the vector is 32. + */ + int[] channels; +} diff --git a/radio/aidl/android/hardware/radio/RadioAccessSpecifierBands.aidl b/radio/aidl/android/hardware/radio/RadioAccessSpecifierBands.aidl new file mode 100644 index 0000000000..dde46262dc --- /dev/null +++ b/radio/aidl/android/hardware/radio/RadioAccessSpecifierBands.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.radio; + +import android.hardware.radio.EutranBands; +import android.hardware.radio.GeranBands; +import android.hardware.radio.NgranBands; +import android.hardware.radio.UtranBands; + +@VintfStability +union RadioAccessSpecifierBands { + boolean noinit; + /** + * Valid only if radioAccessNetwork = GERAN. + */ + GeranBands[] geranBands; + /** + * Valid only if radioAccessNetwork = UTRAN. + */ + UtranBands[] utranBands; + /** + * Valid only if radioAccessNetwork = EUTRAN. + */ + EutranBands[] eutranBands; + /** + * Valid only if radioAccessNetwork = NGRAN. + */ + NgranBands[] ngranBands; +} diff --git a/radio/aidl/android/hardware/radio/RadioBandMode.aidl b/radio/aidl/android/hardware/radio/RadioBandMode.aidl new file mode 100644 index 0000000000..e6064c4dad --- /dev/null +++ b/radio/aidl/android/hardware/radio/RadioBandMode.aidl @@ -0,0 +1,98 @@ +/* + * 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.radio; + +@VintfStability +@Backing(type="int") +enum RadioBandMode { + /** + * "Unspecified" (selected by baseband automatically) + */ + BAND_MODE_UNSPECIFIED, + /** + * "EURO band" (GSM-900 / DCS-1800 / WCDMA-IMT-2000) + */ + BAND_MODE_EURO, + /** + * "US band" (GSM-850 / PCS-1900 / WCDMA-850 / WCDMA-PCS-1900) + */ + BAND_MODE_USA, + /** + * "JPN band" (WCDMA-800 / WCDMA-IMT-2000) + */ + BAND_MODE_JPN, + /** + * "AUS band" (GSM-900 / DCS-1800 / WCDMA-850 / WCDMA-IMT-2000) + */ + BAND_MODE_AUS, + /** + * "AUS band 2" (GSM-900 / DCS-1800 / WCDMA-850) + */ + BAND_MODE_AUS_2, + /** + * "Cellular" (800-MHz Band) + */ + BAND_MODE_CELL_800, + /** + * "PCS" (1900-MHz Band) + */ + BAND_MODE_PCS, + /** + * "Band Class 3" (JTACS Band) + */ + BAND_MODE_JTACS, + /** + * "Band Class 4" (Korean PCS Band) + */ + BAND_MODE_KOREA_PCS, + /** + * "Band Class 5" (450-MHz Band) + */ + BAND_MODE_5_450M, + /** + * "Band Class 6" (2-GMHz IMT2000 Band) + */ + BAND_MODE_IMT2000, + /** + * "Band Class 7" (Upper 700-MHz Band) + */ + BAND_MODE_7_700M_2, + /** + * "Band Class 8" (1800-MHz Band) + */ + BAND_MODE_8_1800M, + /** + * "Band Class 9" (900-MHz Band) + */ + BAND_MODE_9_900M, + /** + * "Band Class 10" (Secondary 800-MHz Band) + */ + BAND_MODE_10_800M_2, + /** + * "Band Class 11" (400-MHz European PAMR Band) + */ + BAND_MODE_EURO_PAMR_400M, + /** + * "Band Class 15" (AWS Band) + */ + BAND_MODE_AWS, + /** + * "Band Class 16" (US 2.5-GHz Band) + */ + BAND_MODE_USA_2500M, +} diff --git a/radio/aidl/android/hardware/radio/RadioCapability.aidl b/radio/aidl/android/hardware/radio/RadioCapability.aidl new file mode 100644 index 0000000000..d911b6facf --- /dev/null +++ b/radio/aidl/android/hardware/radio/RadioCapability.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. + */ + +package android.hardware.radio; + +import android.hardware.radio.RadioAccessFamily; +import android.hardware.radio.RadioCapabilityPhase; +import android.hardware.radio.RadioCapabilityStatus; + +@VintfStability +parcelable RadioCapability { + /** + * Unique session value defined by framework returned in all "responses/unslo". + */ + int session; + RadioCapabilityPhase phase; + /** + * 32-bit bitmap of RadioAccessFamily. + */ + RadioAccessFamily raf; + /** + * A UUID typically "com.xxxx.lmX" where X is the logical modem. + * RadioConst:MAX_UUID_LENGTH is the max length. + */ + String logicalModemUuid; + RadioCapabilityStatus status; +} diff --git a/radio/aidl/android/hardware/radio/RadioCapabilityPhase.aidl b/radio/aidl/android/hardware/radio/RadioCapabilityPhase.aidl new file mode 100644 index 0000000000..a586300565 --- /dev/null +++ b/radio/aidl/android/hardware/radio/RadioCapabilityPhase.aidl @@ -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. + */ + +package android.hardware.radio; + +@VintfStability +@Backing(type="int") +enum RadioCapabilityPhase { + /** + * Logical Modem's (LM) initial value and value after FINISH completes + */ + CONFIGURED, + /** + * START is sent before APPLY and indicates that an APPLY is forthcoming with these same + * parameters. + */ + START, + /** + * APPLY is sent after all LM's receive START and returned RadioCapability.status = 0. + * If any START's fail, hal implementation must not send APPLY. + */ + APPLY, + /** + * UNSOL_RSP is sent with unsolicited radioCapability() + */ + UNSOL_RSP, + /** + * FINISH is sent after all commands have completed. If an error occurs in any previous command, + * the RadioAccessFamily and logicalModemUuid fields must be the prior configuration thus + * restoring the configuration to the previous value. An error returned by FINISH will generally + * be ignored or may cause that LM to be removed from service. + */ + FINISH, +} diff --git a/radio/aidl/android/hardware/radio/RadioCapabilityStatus.aidl b/radio/aidl/android/hardware/radio/RadioCapabilityStatus.aidl new file mode 100644 index 0000000000..5b90f38ea5 --- /dev/null +++ b/radio/aidl/android/hardware/radio/RadioCapabilityStatus.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.radio; + +@VintfStability +@Backing(type="int") +enum RadioCapabilityStatus { + /** + * This parameter has no meaning with RadioCapabilityPhase:START, RadioCapabilityPhase:APPLY + */ + NONE, + /** + * Tell modem the action transaction of set radio capability was successful with + * RadioCapabilityPhase:FINISH + */ + SUCCESS, + /** + * Tell modem the action transaction of set radio capability failed with + * RadioCapabilityPhase:FINISH + */ + FAIL, +} diff --git a/radio/aidl/android/hardware/radio/RadioCdmaSmsConst.aidl b/radio/aidl/android/hardware/radio/RadioCdmaSmsConst.aidl new file mode 100644 index 0000000000..f480077e3f --- /dev/null +++ b/radio/aidl/android/hardware/radio/RadioCdmaSmsConst.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.radio; + +@VintfStability +@Backing(type="int") +enum RadioCdmaSmsConst { + ADDRESS_MAX = 36, + SUBADDRESS_MAX = 36, + BEARER_DATA_MAX = 255, + UDH_MAX_SND_SIZE = 128, + UDH_EO_DATA_SEGMENT_MAX = 131, + MAX_UD_HEADERS = 7, + USER_DATA_MAX = 229, + UDH_LARGE_PIC_SIZE = 128, + UDH_SMALL_PIC_SIZE = 32, + UDH_VAR_PIC_SIZE = 134, + UDH_ANIM_NUM_BITMAPS = 4, + UDH_LARGE_BITMAP_SIZE = 32, + UDH_SMALL_BITMAP_SIZE = 8, + UDH_OTHER_SIZE = 226, + IP_ADDRESS_SIZE = 4, +} diff --git a/radio/aidl/android/hardware/radio/RadioConst.aidl b/radio/aidl/android/hardware/radio/RadioConst.aidl new file mode 100644 index 0000000000..815b3b95e8 --- /dev/null +++ b/radio/aidl/android/hardware/radio/RadioConst.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.radio; + +@VintfStability +@Backing(type="int") +enum RadioConst { + CDMA_ALPHA_INFO_BUFFER_LENGTH = 64, + CDMA_NUMBER_INFO_BUFFER_LENGTH = 81, + MAX_RILDS = 3, + MAX_SOCKET_NAME_LENGTH = 6, + MAX_CLIENT_ID_LENGTH = 2, + MAX_DEBUG_SOCKET_NAME_LENGTH = 12, + MAX_QEMU_PIPE_NAME_LENGTH = 11, + MAX_UUID_LENGTH = 64, + CARD_MAX_APPS = 8, + CDMA_MAX_NUMBER_OF_INFO_RECS = 10, + SS_INFO_MAX = 4, + NUM_SERVICE_CLASSES = 7, + NUM_TX_POWER_LEVELS = 5, + RADIO_ACCESS_SPECIFIER_MAX_SIZE = 8, +} diff --git a/radio/aidl/android/hardware/radio/RadioError.aidl b/radio/aidl/android/hardware/radio/RadioError.aidl new file mode 100644 index 0000000000..a708d2bd9c --- /dev/null +++ b/radio/aidl/android/hardware/radio/RadioError.aidl @@ -0,0 +1,299 @@ +/* + * 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.radio; + +@VintfStability +@Backing(type="int") +enum RadioError { + /** + * Success + */ + NONE = 0, + /** + * If radio did not start or is resetting + */ + RADIO_NOT_AVAILABLE = 1, + GENERIC_FAILURE = 2, + /** + * For PIN/PIN2 methods only + */ + PASSWORD_INCORRECT = 3, + /** + * Operation requires SIM PIN2 to be entered + */ + SIM_PIN2 = 4, + /** + * Operation requires SIM PUK2 to be entered + */ + SIM_PUK2 = 5, + REQUEST_NOT_SUPPORTED = 6, + CANCELLED = 7, + /** + * Data ops are not allowed during voice call on a Class C GPRS device + */ + OP_NOT_ALLOWED_DURING_VOICE_CALL = 8, + /** + * Data ops are not allowed before device registers in network + */ + OP_NOT_ALLOWED_BEFORE_REG_TO_NW = 9, + /** + * Fail to send SMS and need to retry + */ + SMS_SEND_FAIL_RETRY = 10, + /** + * Fail to set the location where CDMA subscription shall be retrieved because of SIM or + * RUIM card absent + */ + SIM_ABSENT = 11, + /** + * Fail to find CDMA subscription from specified location + */ + SUBSCRIPTION_NOT_AVAILABLE = 12, + /** + * HW does not support preferred network type + */ + MODE_NOT_SUPPORTED = 13, + /** + * Command failed becausee recipient is not on FDN list + */ + FDN_CHECK_FAILURE = 14, + /** + * Network selection failed due to illegal SIM or ME + */ + ILLEGAL_SIM_OR_ME = 15, + /** + * No logical channel available + */ + MISSING_RESOURCE = 16, + /** + * Application not found on SIM + */ + NO_SUCH_ELEMENT = 17, + /** + * DIAL request modified to USSD + */ + DIAL_MODIFIED_TO_USSD = 18, + /** + * DIAL request modified to SS + */ + DIAL_MODIFIED_TO_SS = 19, + /** + * DIAL request modified to DIAL with different data + */ + DIAL_MODIFIED_TO_DIAL = 20, + /** + * USSD request modified to DIAL + */ + USSD_MODIFIED_TO_DIAL = 21, + /** + * USSD request modified to SS + */ + USSD_MODIFIED_TO_SS = 22, + /** + * USSD request modified to different USSD request + */ + USSD_MODIFIED_TO_USSD = 23, + /** + * SS request modified to DIAL + */ + SS_MODIFIED_TO_DIAL = 24, + /** + * SS request modified to USSD + */ + SS_MODIFIED_TO_USSD = 25, + /** + * Subscription not supported by RIL + */ + SUBSCRIPTION_NOT_SUPPORTED = 26, + /** + * SS request modified to different SS request + */ + SS_MODIFIED_TO_SS = 27, + /** + * LCE service not supported(36 in RILConstants.java) + */ + LCE_NOT_SUPPORTED = 36, + /** + * Not sufficieent memory to process the request + */ + NO_MEMORY = 37, + /** + * Modem hit unexpected error scenario while handling this request + */ + INTERNAL_ERR = 38, + /** + * Hit platform or system error + */ + SYSTEM_ERR = 39, + /** + * Vendor RIL got unexpected or incorrect response from modem for this request + */ + MODEM_ERR = 40, + /** + * Unexpected request for the current state + */ + INVALID_STATE = 41, + /** + * Not sufficient resource to process the request + */ + NO_RESOURCES = 42, + /** + * Received error from SIM card + */ + SIM_ERR = 43, + /** + * Received invalid arguments in request + */ + INVALID_ARGUMENTS = 44, + /** + * Cannot process the request in current SIM state + */ + INVALID_SIM_STATE = 45, + /** + * Cannot process the request in current modem state + */ + INVALID_MODEM_STATE = 46, + /** + * Received invalid call ID in request + */ + INVALID_CALL_ID = 47, + /** + * ACK received when there is no SMS to ack + */ + NO_SMS_TO_ACK = 48, + /** + * Received error from network + */ + NETWORK_ERR = 49, + /** + * Operation denied due to overly-frequent requests + */ + REQUEST_RATE_LIMITED = 50, + /** + * SIM is busy + */ + SIM_BUSY = 51, + /** + * The target EF is full + */ + SIM_FULL = 52, + /** + * Request is rejected by network + */ + NETWORK_REJECT = 53, + /** + * Not allowed the request not + */ + OPERATION_NOT_ALLOWED = 54, + /** + * The request record is empty + */ + EMPTY_RECORD = 55, + /** + * Invalid SMS format + */ + INVALID_SMS_FORMAT = 56, + /** + * Message not encoded properly + */ + ENCODING_ERR = 57, + /** + * SMSC addrss specified is invalid + */ + INVALID_SMSC_ADDRESS = 58, + /** + * No such entry present to perform the request + */ + NO_SUCH_ENTRY = 59, + /** + * Network is not ready to perform the request + */ + NETWORK_NOT_READY = 60, + /** + * Device does not have this value provisioned + */ + NOT_PROVISIONED = 61, + /** + * Device does not have subscription + */ + NO_SUBSCRIPTION = 62, + /** + * Network cannot be found + */ + NO_NETWORK_FOUND = 63, + /** + * Operation cannot be performed because the device is currently in use + */ + DEVICE_IN_USE = 64, + /** + * Operation aborted + */ + ABORTED = 65, + /** + * Response from vendor had invalid data + */ + INVALID_RESPONSE = 66, + OEM_ERROR_1 = 501, + OEM_ERROR_2 = 502, + OEM_ERROR_3 = 503, + OEM_ERROR_4 = 504, + OEM_ERROR_5 = 505, + OEM_ERROR_6 = 506, + OEM_ERROR_7 = 507, + OEM_ERROR_8 = 508, + OEM_ERROR_9 = 509, + OEM_ERROR_10 = 510, + OEM_ERROR_11 = 511, + OEM_ERROR_12 = 512, + OEM_ERROR_13 = 513, + OEM_ERROR_14 = 514, + OEM_ERROR_15 = 515, + OEM_ERROR_16 = 516, + OEM_ERROR_17 = 517, + OEM_ERROR_18 = 518, + OEM_ERROR_19 = 519, + OEM_ERROR_20 = 520, + OEM_ERROR_21 = 521, + OEM_ERROR_22 = 522, + OEM_ERROR_23 = 523, + OEM_ERROR_24 = 524, + OEM_ERROR_25 = 525, + /** + * 1X voice and SMS are not allowed simulteneously. + */ + SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED = 67, + /** + * Access is barred. + */ + ACCESS_BARRED = 68, + /** + * SMS is blocked due to call control, e.g., resource unavailable + * in the SMR entity. + */ + BLOCKED_DUE_TO_CALL = 69, + /** + * Returned from setRadioPowerResponse when detecting RF HW issues. Some RF Front-End (RFFE) + * components like antenna are considered critical for modem to provide telephony service. + * This RadioError is used when modem detect such RFFE problem. + */ + RF_HARDWARE_ISSUE = 70, + /** + * Returned from setRadioPowerResponse when detecting no RF calibration issue. + * Unlike RF_HARDWARE_ISSUE, this is a SW problem and no HW repair is needed. + */ + NO_RF_CALIBRATION_INFO = 71, +} diff --git a/radio/aidl/android/hardware/radio/RadioFrequencyInfo.aidl b/radio/aidl/android/hardware/radio/RadioFrequencyInfo.aidl new file mode 100644 index 0000000000..e5aa9fb187 --- /dev/null +++ b/radio/aidl/android/hardware/radio/RadioFrequencyInfo.aidl @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.radio; + +import android.hardware.radio.FrequencyRange; + +@VintfStability +union RadioFrequencyInfo { + boolean noinit; + /** + * A rough frequency range. + */ + FrequencyRange range; + /** + * The Absolute Radio Frequency Channel Number. + */ + int channelNumber; +} diff --git a/radio/aidl/android/hardware/radio/RadioIndicationType.aidl b/radio/aidl/android/hardware/radio/RadioIndicationType.aidl new file mode 100644 index 0000000000..aa5215f439 --- /dev/null +++ b/radio/aidl/android/hardware/radio/RadioIndicationType.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.radio; + +@VintfStability +@Backing(type="int") +enum RadioIndicationType { + UNSOLICITED, + UNSOLICITED_ACK_EXP, +} diff --git a/radio/aidl/android/hardware/radio/RadioResponseInfo.aidl b/radio/aidl/android/hardware/radio/RadioResponseInfo.aidl new file mode 100644 index 0000000000..d81c49c83e --- /dev/null +++ b/radio/aidl/android/hardware/radio/RadioResponseInfo.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.radio; + +import android.hardware.radio.RadioError; +import android.hardware.radio.RadioResponseType; + +@VintfStability +parcelable RadioResponseInfo { + /** + * Response type + */ + RadioResponseType type; + /** + * Serial number of the request + */ + int serial; + /** + * Response error + */ + RadioError error; +} diff --git a/radio/aidl/android/hardware/radio/RadioResponseInfoModem.aidl b/radio/aidl/android/hardware/radio/RadioResponseInfoModem.aidl new file mode 100644 index 0000000000..8c7b94c1a4 --- /dev/null +++ b/radio/aidl/android/hardware/radio/RadioResponseInfoModem.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. + */ + +package android.hardware.radio; + +import android.hardware.radio.RadioError; +import android.hardware.radio.RadioResponseType; + +@VintfStability +parcelable RadioResponseInfoModem { + /** + * Response type + */ + RadioResponseType type; + /** + * Serial number of the request + */ + int serial; + /** + * Response error + */ + RadioError error; + /** + * Whether the modem is enabled or not + */ + boolean isEnabled; +} diff --git a/radio/aidl/android/hardware/radio/RadioResponseType.aidl b/radio/aidl/android/hardware/radio/RadioResponseType.aidl new file mode 100644 index 0000000000..882c759eb1 --- /dev/null +++ b/radio/aidl/android/hardware/radio/RadioResponseType.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.radio; + +@VintfStability +@Backing(type="int") +enum RadioResponseType { + SOLICITED, + SOLICITED_ACK, + SOLICITED_ACK_EXP, +} diff --git a/radio/aidl/android/hardware/radio/RadioState.aidl b/radio/aidl/android/hardware/radio/RadioState.aidl new file mode 100644 index 0000000000..1915870316 --- /dev/null +++ b/radio/aidl/android/hardware/radio/RadioState.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.radio; + +@VintfStability +@Backing(type="int") +enum RadioState { + /** + * Radio explicitly powered off (eg CFUN=0) + */ + OFF = 0, + /** + * Radio unavailable (eg, resetting or not booted) + */ + UNAVAILABLE = 1, + /** + * Radio is on + */ + ON = 10, +} diff --git a/radio/aidl/android/hardware/radio/RadioTechnology.aidl b/radio/aidl/android/hardware/radio/RadioTechnology.aidl new file mode 100644 index 0000000000..d439866f2f --- /dev/null +++ b/radio/aidl/android/hardware/radio/RadioTechnology.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.radio; + +@VintfStability +@Backing(type="int") +enum RadioTechnology { + UNKNOWN, + GPRS, + EDGE, + UMTS, + IS95A, + IS95B, + ONE_X_RTT, + EVDO_0, + EVDO_A, + HSDPA, + HSUPA, + HSPA, + EVDO_B, + EHRPD, + LTE, + /** + * HSPA+ + */ + HSPAP, + /** + * Only supports voice + */ + GSM, + TD_SCDMA, + IWLAN, + LTE_CA, + /** + * 5G NR. This is only used in 5G Standalone mode. + */ + NR, +} diff --git a/radio/aidl/android/hardware/radio/RadioTechnologyFamily.aidl b/radio/aidl/android/hardware/radio/RadioTechnologyFamily.aidl new file mode 100644 index 0000000000..37a1df238b --- /dev/null +++ b/radio/aidl/android/hardware/radio/RadioTechnologyFamily.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.radio; + +@VintfStability +@Backing(type="int") +enum RadioTechnologyFamily { + /** + * 3GPP Technologies - GSM, WCDMA + */ + THREE_GPP, + /** + * 3GPP2 Technologies - CDMA + */ + THREE_GPP2, +} diff --git a/radio/aidl/android/hardware/radio/RegState.aidl b/radio/aidl/android/hardware/radio/RegState.aidl new file mode 100644 index 0000000000..91fd239868 --- /dev/null +++ b/radio/aidl/android/hardware/radio/RegState.aidl @@ -0,0 +1,67 @@ +/* + * 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.radio; + +/** + * Please note that registration state UNKNOWN is treated as "out of service" in Android telephony. + * Registration state REG_DENIED must be returned if Location Update Reject (with cause 17 - Network + * Failure) is received repeatedly from the network, to facilitate "managed roaming". + */ +@VintfStability +@Backing(type="int") +enum RegState { + /** + * Not registered, MT is not currently searching for a new operator to register + */ + NOT_REG_MT_NOT_SEARCHING_OP = 0, + /** + * Registered, home network + */ + REG_HOME = 1, + /** + * Not registered, but MT is currently searching for a new operator to register + */ + NOT_REG_MT_SEARCHING_OP = 2, + /** + * Registration denied + */ + REG_DENIED = 3, + /** + * Unknown + */ + UNKNOWN = 4, + /** + * Registered, roaming + */ + REG_ROAMING = 5, + /** + * Same as NOT_REG_MT_NOT_SEARCHING_OP but indicates that emergency calls are enabled + */ + NOT_REG_MT_NOT_SEARCHING_OP_EM = 10, + /** + * Same as NOT_REG_MT_SEARCHING_OP but indicatees that emergency calls are enabled + */ + NOT_REG_MT_SEARCHING_OP_EM = 12, + /** + * Same as REG_DENIED but indicates that emergency calls are enabled + */ + REG_DENIED_EM = 13, + /** + * Same as UNKNOWN but indicates that emergency calls are enabled + */ + UNKNOWN_EM = 14, +} diff --git a/radio/aidl/android/hardware/radio/RegStateResult.aidl b/radio/aidl/android/hardware/radio/RegStateResult.aidl new file mode 100644 index 0000000000..4bc55c40c2 --- /dev/null +++ b/radio/aidl/android/hardware/radio/RegStateResult.aidl @@ -0,0 +1,60 @@ +/* + * 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.radio; + +import android.hardware.radio.CellIdentity; +import android.hardware.radio.RadioTechnology; +import android.hardware.radio.RegState; +import android.hardware.radio.RegStateResultAccessTechnologySpecificInfo; +import android.hardware.radio.RegistrationFailCause; + +@VintfStability +parcelable RegStateResult { + /** + * Registration state. If the RAT is indicated as a GERAN, UTRAN, or CDMA2000 technology, this + * value reports registration in the Circuit-switched domain. If the RAT is indicated as an + * EUTRAN, NGRAN, or another technology that does not support circuit-switched services, this + * value reports registration in the Packet-switched domain. + */ + RegState regState; + /** + * Indicates the available voice radio technology, valid values as defined by RadioTechnology, + * except LTE_CA, which is no longer a valid value on 1.5 or above. When the device is on + * carrier aggregation, vendor RIL service should properly report multiple PhysicalChannelConfig + * elements through IRadio::currentPhysicalChannelConfigs. + */ + RadioTechnology rat; + /** + * Cause code reported by the network in case registration fails. This will be a mobility + * management cause code defined for MM, GMM, MME or equivalent as appropriate for the RAT. + */ + RegistrationFailCause reasonForDenial; + /** + * CellIdentity + */ + CellIdentity cellIdentity; + /** + * The most-recent PLMN-ID upon which the UE registered (or attempted to register if a failure + * is reported in the reasonForDenial field). This PLMN shall be in standard format consisting + * of a 3 digit MCC concatenated with a 2 or 3 digit MNC. + */ + String registeredPlmn; + /** + * Access-technology-specific registration information, such as for CDMA2000. + */ + RegStateResultAccessTechnologySpecificInfo accessTechnologySpecificInfo; +} diff --git a/radio/aidl/android/hardware/radio/RegStateResultAccessTechnologySpecificInfo.aidl b/radio/aidl/android/hardware/radio/RegStateResultAccessTechnologySpecificInfo.aidl new file mode 100644 index 0000000000..b22e413dd7 --- /dev/null +++ b/radio/aidl/android/hardware/radio/RegStateResultAccessTechnologySpecificInfo.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.radio; + +import android.hardware.radio.NrVopsInfo; +import android.hardware.radio.RegStateResultAccessTechnologySpecificInfoCdma2000RegistrationInfo; +import android.hardware.radio.RegStateResultAccessTechnologySpecificInfoEutranRegistrationInfo; + +@VintfStability +union RegStateResultAccessTechnologySpecificInfo { + boolean noinit; + RegStateResultAccessTechnologySpecificInfoCdma2000RegistrationInfo cdmaInfo; + RegStateResultAccessTechnologySpecificInfoEutranRegistrationInfo eutranInfo; + /** + * Network capabilities for voice over PS services. This info is valid only on NR network and + * must be present when the device is camped on NR. VopsInfo must be empty when the device is + * not camped on NR. + */ + NrVopsInfo ngranNrVopsInfo; + /** + * True if the dual transfer mode is supported. Refer to 3GPP TS 44.108 section 3.4.25.3 + */ + boolean geranDtmSupported; +} diff --git a/radio/aidl/android/hardware/radio/RegStateResultAccessTechnologySpecificInfoCdma2000RegistrationInfo.aidl b/radio/aidl/android/hardware/radio/RegStateResultAccessTechnologySpecificInfoCdma2000RegistrationInfo.aidl new file mode 100644 index 0000000000..14f68ec025 --- /dev/null +++ b/radio/aidl/android/hardware/radio/RegStateResultAccessTechnologySpecificInfoCdma2000RegistrationInfo.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. + */ + +package android.hardware.radio; + +import android.hardware.radio.PrlIndicator; + +@VintfStability +parcelable RegStateResultAccessTechnologySpecificInfoCdma2000RegistrationInfo { + /** + * Concurrent services support indicator. if registered on a CDMA system. + * false - Concurrent services not supported, + * true - Concurrent services supported + */ + boolean cssSupported; + /** + * TSB-58 Roaming Indicator if registered on a CDMA or EVDO system or -1 if not. + * Valid values are 0-255. + */ + int roamingIndicator; + /** + * Indicates whether the current system is in the PRL if registered on a CDMA or EVDO system + * or -1 if not. 0=not in the PRL, 1=in the PRL. + */ + PrlIndicator systemIsInPrl; + /** + * Default Roaming Indicator from the PRL if registered on a CDMA or EVDO system or -1 if not. + * Valid values are 0-255. + */ + int defaultRoamingIndicator; +} diff --git a/radio/aidl/android/hardware/radio/RegStateResultAccessTechnologySpecificInfoEutranRegistrationInfo.aidl b/radio/aidl/android/hardware/radio/RegStateResultAccessTechnologySpecificInfoEutranRegistrationInfo.aidl new file mode 100644 index 0000000000..5b942f4aa4 --- /dev/null +++ b/radio/aidl/android/hardware/radio/RegStateResultAccessTechnologySpecificInfoEutranRegistrationInfo.aidl @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.radio; + +import android.hardware.radio.LteVopsInfo; +import android.hardware.radio.NrIndicators; + +@VintfStability +parcelable RegStateResultAccessTechnologySpecificInfoEutranRegistrationInfo { + /** + * Network capabilities for voice over PS services. This info is valid only on LTE network and + * must be present when device is camped on LTE. VopsInfo must be empty when device is camped + * only on 2G/3G. + */ + LteVopsInfo lteVopsInfo; + /** + * The parameters of NR 5G Non-Standalone. This value is only valid on E-UTRAN, otherwise must + * be empty. + */ + NrIndicators nrIndicators; +} diff --git a/radio/aidl/android/hardware/radio/RegistrationFailCause.aidl b/radio/aidl/android/hardware/radio/RegistrationFailCause.aidl new file mode 100644 index 0000000000..d9c7f23a3a --- /dev/null +++ b/radio/aidl/android/hardware/radio/RegistrationFailCause.aidl @@ -0,0 +1,189 @@ +/* + * 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.radio; + +/** + * Call fail causes for Circuit-switched service enumerated in 3GPP TS 24.008, 10.5.3.6 and + * 10.5.147. Additional detail is available in 3GPP TS 24.008 Annex G. + */ +@VintfStability +@Backing(type="int") +enum RegistrationFailCause { + /** + * 0 - None + */ + NONE = 0, + /** + * 2 - IMSI unknown in HLR + */ + IMSI_UNKNOWN_IN_HLR = 2, + /** + * 3 - Illegal MS + */ + ILLEGAL_MS = 3, + /** + * 4 - Illegal ME + */ + IMSI_UNKNOWN_IN_VLR = 4, + /** + * 5 - PLMN not allowed + */ + IMEI_NOT_ACCEPTED = 5, + /** + * 6 - Location area not allowed + */ + ILLEGAL_ME = 6, + /** + * 7 - Roaming not allowed + */ + GPRS_SERVICES_NOT_ALLOWED = 7, + /** + * 8 - No Suitable Cells in this Location Area + */ + GPRS_AND_NON_GPRS_SERVICES_NOT_ALLOWED = 8, + /** + * 9 - Network failure + */ + MS_IDENTITY_CANNOT_BE_DERIVED_BY_NETWORK = 9, + /** + * 10 - Persistent location update reject + */ + IMPLICITLY_DETACHED = 10, + /** + * 11 - PLMN not allowed + */ + PLMN_NOT_ALLOWED = 11, + /** + * 12 - Location area not allowed + */ + LOCATION_AREA_NOT_ALLOWED = 12, + /** + * 13 - Roaming not allowed in this Location Area + */ + ROAMING_NOT_ALLOWED = 13, + /** + * 14 - GPRS Services not allowed in this PLMN + */ + GPRS_SERVICES_NOT_ALLOWED_IN_PLMN = 14, + /** + * 15 - No Suitable Cells in this Location Area + */ + NO_SUITABLE_CELLS = 15, + /** + * 16 - MSC temporarily not reachable + */ + MSC_TEMPORARILY_NOT_REACHABLE = 15, + /** + * 17 - Network Failure + */ + NETWORK_FAILURE = 17, + /** + * 20 - MAC Failure + */ + MAC_FAILURE = 20, + /** + * 21 - Sync Failure + */ + SYNC_FAILURE = 21, + /** + * 22 - Congestion + */ + CONGESTION = 22, + /** + * 23 - GSM Authentication unacceptable + */ + GSM_AUTHENTICATION_UNACCEPTABLE = 23, + /** + * 25 - Not Authorized for this CSG + */ + NOT_AUTHORIZED_FOR_THIS_CSG = 25, + /** + * 28 SMS provided via GPRS in this routing area + */ + SMS_PROVIDED_BY_GPRS_IN_ROUTING_AREA, + /** + * 32 - Service option not supported + */ + SERVICE_OPTION_NOT_SUPPORTED = 32, + /** + * 33 - Requested service option not subscribed + */ + SERVICE_OPTION_NOT_SUBSCRIBED = 33, + /** + * 34 - Service option temporarily out of order + */ + SERVICE_OPTION_TEMPORARILY_OUT_OF_ORDER = 34, + /** + * 38 - Call cannot be identified + */ + CALL_CANNOT_BE_IDENTIFIED = 38, + /** + * 40 No PDP context activated + */ + NO_PDP_CONTEXT_ACTIVATED = 40, + /** + * 48-63 - Retry upon entry into a new cell + */ + RETRY_UPON_ENTRY_INTO_NEW_CELL_1 = 48, + RETRY_UPON_ENTRY_INTO_NEW_CELL_2 = 49, + RETRY_UPON_ENTRY_INTO_NEW_CELL_3 = 50, + RETRY_UPON_ENTRY_INTO_NEW_CELL_4 = 51, + RETRY_UPON_ENTRY_INTO_NEW_CELL_5 = 52, + RETRY_UPON_ENTRY_INTO_NEW_CELL_6 = 53, + RETRY_UPON_ENTRY_INTO_NEW_CELL_7 = 54, + RETRY_UPON_ENTRY_INTO_NEW_CELL_8 = 55, + RETRY_UPON_ENTRY_INTO_NEW_CELL_9 = 56, + RETRY_UPON_ENTRY_INTO_NEW_CELL_10 = 57, + RETRY_UPON_ENTRY_INTO_NEW_CELL_11 = 58, + RETRY_UPON_ENTRY_INTO_NEW_CELL_12 = 59, + RETRY_UPON_ENTRY_INTO_NEW_CELL_13 = 60, + RETRY_UPON_ENTRY_INTO_NEW_CELL_14 = 61, + RETRY_UPON_ENTRY_INTO_NEW_CELL_15 = 62, + RETRY_UPON_ENTRY_INTO_NEW_CELL_16 = 63, + /** + * 95 - Semantically incorrect message + */ + SEMANTICALLY_INCORRECT_MESSAGE = 95, + /** + * 96 - Invalid mandatory information + */ + INVALID_MANDATORY_INFORMATION = 96, + /** + * 97 - Message type non-existent or not implemented + */ + MESSAGE_TYPE_NON_EXISTENT_OR_NOT_IMPLEMENTED = 97, + /** + * 98 - Message type not compatible with protocol state + */ + MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE = 98, + /** + * 99 - Information element non-existent or not implemented + */ + INFORMATION_ELEMENT_NON_EXISTENT_OR_NOT_IMPLEMENTED = 99, + /** + * 100 - Conditional IE error + */ + CONDITIONAL_IE_ERROR = 100, + /** + * 101 - Message not compatible with protocol state + */ + MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE = 101, + /** + * 111 - Protocol error, unspecified + */ + PROTOCOL_ERROR_UNSPECIFIED = 111, +} diff --git a/radio/aidl/android/hardware/radio/ResetNvType.aidl b/radio/aidl/android/hardware/radio/ResetNvType.aidl new file mode 100644 index 0000000000..59c74da9f8 --- /dev/null +++ b/radio/aidl/android/hardware/radio/ResetNvType.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.radio; + +@VintfStability +@Backing(type="int") +enum ResetNvType { + /** + * Reload all NV items + */ + RELOAD, + /** + * Erase NV reset (SCRTN) + */ + ERASE, + /** + * Factory reset (RTN) + */ + FACTORY_RESET, +} diff --git a/radio/aidl/android/hardware/radio/RestrictedState.aidl b/radio/aidl/android/hardware/radio/RestrictedState.aidl new file mode 100644 index 0000000000..1cf8be27f0 --- /dev/null +++ b/radio/aidl/android/hardware/radio/RestrictedState.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.radio; + +@VintfStability +@Backing(type="int") +enum RestrictedState { + NONE = 0x00, + CS_EMERGENCY = 0x01, + CS_NORMAL = 0x02, + CS_ALL = 0x04, + PS_ALL = 0x10, +} diff --git a/radio/aidl/android/hardware/radio/RouteSelectionDescriptor.aidl b/radio/aidl/android/hardware/radio/RouteSelectionDescriptor.aidl new file mode 100644 index 0000000000..14591a0ddb --- /dev/null +++ b/radio/aidl/android/hardware/radio/RouteSelectionDescriptor.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.radio; + +import android.hardware.radio.OptionalPdpProtocolType; +import android.hardware.radio.OptionalSscMode; +import android.hardware.radio.SliceInfo; + +/** + * This struct represents a single route selection descriptor as defined in 3GPP TS 24.526. + */ +@VintfStability +parcelable RouteSelectionDescriptor { + /** + * Precedence value in the range of 0 to 255. Higher value has lower precedence. + */ + byte precedence; + /** + * Valid values are IP, IPV6 and IPV4V6. + */ + OptionalPdpProtocolType sessionType; + OptionalSscMode sscMode; + /** + * There can be 0 or more SliceInfo specified in a route descriptor. + */ + SliceInfo[] sliceInfo; + /** + * DNN stands for Data Network Name and represents an APN as defined in 3GPP TS 23.003. + * There can be 0 or more DNNs specified in a route descriptor. + */ + String[] dnn; +} diff --git a/radio/aidl/android/hardware/radio/SapApduType.aidl b/radio/aidl/android/hardware/radio/SapApduType.aidl new file mode 100644 index 0000000000..f697e58aad --- /dev/null +++ b/radio/aidl/android/hardware/radio/SapApduType.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.radio; + +@VintfStability +@Backing(type="int") +enum SapApduType { + APDU, + APDU7816, +} diff --git a/radio/aidl/android/hardware/radio/SapConnectRsp.aidl b/radio/aidl/android/hardware/radio/SapConnectRsp.aidl new file mode 100644 index 0000000000..d2046d21ef --- /dev/null +++ b/radio/aidl/android/hardware/radio/SapConnectRsp.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.radio; + +@VintfStability +@Backing(type="int") +enum SapConnectRsp { + SUCCESS, + CONNECT_FAILURE, + MSG_SIZE_TOO_LARGE, + MSG_SIZE_TOO_SMALL, + CONNECT_OK_CALL_ONGOING, +} diff --git a/radio/aidl/android/hardware/radio/SapDisconnectType.aidl b/radio/aidl/android/hardware/radio/SapDisconnectType.aidl new file mode 100644 index 0000000000..30a04bde46 --- /dev/null +++ b/radio/aidl/android/hardware/radio/SapDisconnectType.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.radio; + +@VintfStability +@Backing(type="int") +enum SapDisconnectType { + GRACEFUL, + IMMEDIATE, +} diff --git a/radio/aidl/android/hardware/radio/SapResultCode.aidl b/radio/aidl/android/hardware/radio/SapResultCode.aidl new file mode 100644 index 0000000000..db87374ce9 --- /dev/null +++ b/radio/aidl/android/hardware/radio/SapResultCode.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.radio; + +@VintfStability +@Backing(type="int") +enum SapResultCode { + SUCCESS, + GENERIC_FAILURE, + CARD_NOT_ACCESSSIBLE, + CARD_ALREADY_POWERED_OFF, + CARD_REMOVED, + CARD_ALREADY_POWERED_ON, + DATA_NOT_AVAILABLE, + NOT_SUPPORTED, +} diff --git a/radio/aidl/android/hardware/radio/SapStatus.aidl b/radio/aidl/android/hardware/radio/SapStatus.aidl new file mode 100644 index 0000000000..0a6b4a757a --- /dev/null +++ b/radio/aidl/android/hardware/radio/SapStatus.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.radio; + +@VintfStability +@Backing(type="int") +enum SapStatus { + UNKNOWN_ERROR, + CARD_RESET, + CARD_NOT_ACCESSIBLE, + CARD_REMOVED, + CARD_INSERTED, + RECOVERED, +} diff --git a/radio/aidl/android/hardware/radio/SapTransferProtocol.aidl b/radio/aidl/android/hardware/radio/SapTransferProtocol.aidl new file mode 100644 index 0000000000..7f385de00d --- /dev/null +++ b/radio/aidl/android/hardware/radio/SapTransferProtocol.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.radio; + +@VintfStability +@Backing(type="int") +enum SapTransferProtocol { + T0, + T1, +} diff --git a/radio/aidl/android/hardware/radio/ScanIntervalRange.aidl b/radio/aidl/android/hardware/radio/ScanIntervalRange.aidl new file mode 100644 index 0000000000..7ea4d123eb --- /dev/null +++ b/radio/aidl/android/hardware/radio/ScanIntervalRange.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.radio; + +/** + * Values are in seconds + */ +@VintfStability +@Backing(type="int") +enum ScanIntervalRange { + MIN = 5, + MAX = 300, +} diff --git a/radio/aidl/android/hardware/radio/ScanStatus.aidl b/radio/aidl/android/hardware/radio/ScanStatus.aidl new file mode 100644 index 0000000000..c9c436e36a --- /dev/null +++ b/radio/aidl/android/hardware/radio/ScanStatus.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.radio; + +@VintfStability +@Backing(type="int") +enum ScanStatus { + /** + * The result contains a part of the scan results + */ + PARTIAL = 1, + /** + * The result contains the last part of the scan results + */ + COMPLETE = 2, +} diff --git a/radio/aidl/android/hardware/radio/ScanType.aidl b/radio/aidl/android/hardware/radio/ScanType.aidl new file mode 100644 index 0000000000..66ed451fff --- /dev/null +++ b/radio/aidl/android/hardware/radio/ScanType.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.radio; + +@VintfStability +@Backing(type="int") +enum ScanType { + /** + * Performs the scan only once + */ + ONE_SHOT, + /** + * Performs the scan periodically until cancelled + */ + PERIODIC, +} diff --git a/radio/aidl/android/hardware/radio/SelectUiccSub.aidl b/radio/aidl/android/hardware/radio/SelectUiccSub.aidl new file mode 100644 index 0000000000..4db5e662b8 --- /dev/null +++ b/radio/aidl/android/hardware/radio/SelectUiccSub.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.radio; + +import android.hardware.radio.SubscriptionType; +import android.hardware.radio.UiccSubActStatus; + +@VintfStability +parcelable SelectUiccSub { + int slot; + /** + * Array subscriptor from applications[RadioConst:CARD_MAX_APPS] in getIccCardStatus() + */ + int appIndex; + SubscriptionType subType; + UiccSubActStatus actStatus; +} diff --git a/radio/aidl/android/hardware/radio/SendSmsResult.aidl b/radio/aidl/android/hardware/radio/SendSmsResult.aidl new file mode 100644 index 0000000000..31865637ee --- /dev/null +++ b/radio/aidl/android/hardware/radio/SendSmsResult.aidl @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.radio; + +@VintfStability +parcelable SendSmsResult { + /** + * TP-Message-Reference for GSM, and BearerData MessageId for CDMA. + * See 3GPP2 C.S0015-B, v2.0, table 4.5-1 + */ + int messageRef; + /** + * Ack PDU or empty string if n/a + */ + String ackPDU; + /** + * See 3GPP 27.005, 3.2.5 for GSM/UMTS, 3GPP2 N.S0005 (IS-41C) Table 171 for CDMA. + * -1 if unknown or not applicable. + */ + int errorCode; +} diff --git a/radio/aidl/android/hardware/radio/SetupDataCallResult.aidl b/radio/aidl/android/hardware/radio/SetupDataCallResult.aidl new file mode 100644 index 0000000000..5fc017cba8 --- /dev/null +++ b/radio/aidl/android/hardware/radio/SetupDataCallResult.aidl @@ -0,0 +1,117 @@ +/* + * 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.radio; + +import android.hardware.radio.DataCallFailCause; +import android.hardware.radio.DataConnActiveStatus; +import android.hardware.radio.HandoverFailureMode; +import android.hardware.radio.LinkAddress; +import android.hardware.radio.OptionalSliceInfo; +import android.hardware.radio.PdpProtocolType; +import android.hardware.radio.Qos; +import android.hardware.radio.QosSession; +import android.hardware.radio.TrafficDescriptor; + +@VintfStability +parcelable SetupDataCallResult { + /** + * Data call fail cause. DataCallFailCause.NONE if no error. + */ + DataCallFailCause cause; + /** + * If cause is not DataCallFailCause.NONE, this field indicates the network suggested data + * retry back-off time in milliseconds. Negative value indicates network does not give any + * suggestion. 0 indicates retry should be performed immediately. 0x7fffffffffffffff indicates + * the device should not retry data setup anymore. During this time, no calls to + * IRadio.setupDataCall for this APN will be made unless IRadioIndication.unthrottleApn is sent + * with the same APN. + */ + long suggestedRetryTime; + /** + * Context ID, uniquely identifies this data connection. + */ + int cid; + /** + * Data connection active status. + */ + DataConnActiveStatus active; + /** + * PDP protocol type. If cause is DataCallFailCause.ONLY_SINGLE_BEARER_ALLOWED, this is the + * protocol type supported, such as "IP" or "IPV6". + */ + PdpProtocolType type; + /** + * The network interface name. + */ + String ifname; + /** + * List of link address. + */ + LinkAddress[] addresses; + /** + * List of DNS server addresses, e.g., "192.0.1.3" or "192.0.1.11 2001:db8::1". Empty if no dns + * server addresses returned. + */ + String[] dnses; + /** + * List of default gateway addresses, e.g., "192.0.1.3" or "192.0.1.11 2001:db8::1". + * When empty, the addresses represent point to point connections. + */ + String[] gateways; + /** + * List of P-CSCF (Proxy Call State Control Function) addresses via PCO (Protocol Configuration + * Option), e.g., "2001:db8::1 2001:db8::2 2001:db8::3". Empty if not IMS client. + */ + String[] pcscf; + /** + * MTU received from network for IPv4. + * Value <= 0 means network has either not sent a value or sent an invalid value. + */ + int mtuV4; + /** + * MTU received from network for IPv6. + * Value <= 0 means network has either not sent a value or sent an invalid value. + */ + int mtuV6; + /** + * Default bearer QoS. Applicable to LTE and NR + */ + Qos defaultQos; + /** + * Active QOS sessions of the dedicated bearers. Applicable to PDNs that support dedicated + * bearers. + */ + QosSession[] qosSessions; + /** + * Specifies the fallback mode on an IWLAN handover failure. + */ + HandoverFailureMode handoverFailureMode; + /** + * The allocated pdu session id for this data call. A value of 0 means no pdu session id was + * attached to this call. Reference: 3GPP TS 24.007 section 11.2.3.1b. + */ + int pduSessionId; + /** + * Slice used for this data call. It is valid only when this data call is on AccessNetwork:NGRAN + */ + OptionalSliceInfo sliceInfo; + /** + * TrafficDescriptors for which this data call must be used. It only includes the TDs for which + * a data call has been requested so far; it is not an exhaustive list. + */ + TrafficDescriptor[] trafficDescriptors; +} diff --git a/radio/aidl/android/hardware/radio/SignalMeasurementType.aidl b/radio/aidl/android/hardware/radio/SignalMeasurementType.aidl new file mode 100644 index 0000000000..d92ae91ae1 --- /dev/null +++ b/radio/aidl/android/hardware/radio/SignalMeasurementType.aidl @@ -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. + */ + +package android.hardware.radio; + +/** + * Defining signal strength type. + */ +@VintfStability +@Backing(type="int") +enum SignalMeasurementType { + /** + * Received Signal Strength Indication. + * Range: -113 dBm and -51 dBm + * Used RAN: GERAN, CDMA2000 + * Reference: 3GPP TS 27.007 section 8.5. + */ + RSSI = 1, + /** + * Received Signal Code Power. + * Range: -120 dBm to -25 dBm; + * Used RAN: UTRAN + * Reference: 3GPP TS 25.123, section 9.1.1.1 + */ + RSCP = 2, + /** + * Reference Signal Received Power. + * Range: -140 dBm to -44 dBm; + * Used RAN: EUTRAN + * Reference: 3GPP TS 36.133 9.1.4 + */ + RSRP = 3, + /** + * Reference Signal Received Quality + * Range: -34 dB to 3 dB; + * Used RAN: EUTRAN + * Reference: 3GPP TS 36.133 v12.6.0 section 9.1.7 + */ + RSRQ = 4, + /** + * Reference Signal Signal to Noise Ratio + * Range: -20 dB to 30 dB; + * Used RAN: EUTRAN + * Note: This field is optional; how to support it can be decided by the corresponding vendor. + * Though the response code is not enforced, vendor's implementation must ensure this interface + * does not crash. + */ + RSSNR = 5, + /** + * 5G SS reference signal received power. + * Range: -140 dBm to -44 dBm. + * Used RAN: NGRAN + * Reference: 3GPP TS 38.215. + */ + SSRSRP = 6, + /** + * 5G SS reference signal received quality. + * Range: -43 dB to 20 dB. + * Used RAN: NGRAN + * Reference: 3GPP TS 38.215, 3GPP TS 38.133 section 10 + */ + SSRSRQ = 7, + /** + * 5G SS signal-to-noise and interference ratio. + * Range: -23 dB to 40 dB + * Used RAN: NGRAN + * Reference: 3GPP TS 38.215 section 5.1.*, 3GPP TS 38.133 section 10.1.16.1. + */ + SSSINR = 8, +} diff --git a/radio/aidl/android/hardware/radio/SignalStrength.aidl b/radio/aidl/android/hardware/radio/SignalStrength.aidl new file mode 100644 index 0000000000..0ffdaa34cc --- /dev/null +++ b/radio/aidl/android/hardware/radio/SignalStrength.aidl @@ -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. + */ + +package android.hardware.radio; + +import android.hardware.radio.CdmaSignalStrength; +import android.hardware.radio.EvdoSignalStrength; +import android.hardware.radio.GsmSignalStrength; +import android.hardware.radio.LteSignalStrength; +import android.hardware.radio.NrSignalStrength; +import android.hardware.radio.TdscdmaSignalStrength; +import android.hardware.radio.WcdmaSignalStrength; + +@VintfStability +parcelable SignalStrength { + /** + * If GSM measurements are provided, this structure must contain valid measurements; otherwise + * all fields should be set to INT_MAX to mark them as invalid. + */ + GsmSignalStrength gsm; + /** + * If CDMA measurements are provided, this structure must contain valid measurements; otherwise + * all fields should be set to INT_MAX to mark them as invalid. + */ + CdmaSignalStrength cdma; + /** + * If EvDO measurements are provided, this structure must contain valid measurements; otherwise + * all fields should be set to INT_MAX to mark them as invalid. + */ + EvdoSignalStrength evdo; + /** + * If LTE measurements are provided, this structure must contain valid measurements; otherwise + * all fields should be set to INT_MAX to mark them as invalid. + */ + LteSignalStrength lte; + /** + * If TD-SCDMA measurements are provided, this structure must contain valid measurements; + * otherwise all fields should be set to INT_MAX to mark them as invalid. + */ + TdscdmaSignalStrength tdscdma; + /** + * If WCDMA measurements are provided, this structure must contain valid measurements; otherwise + * all fields should be set to INT_MAX to mark them as invalid. + */ + WcdmaSignalStrength wcdma; + /** + * If NR 5G measurements are provided, this structure must contain valid measurements; otherwise + * all fields should be set to INT_MAX to mark them as invalid. + */ + NrSignalStrength nr; +} diff --git a/radio/aidl/android/hardware/radio/SignalThresholdInfo.aidl b/radio/aidl/android/hardware/radio/SignalThresholdInfo.aidl new file mode 100644 index 0000000000..9274b42f6b --- /dev/null +++ b/radio/aidl/android/hardware/radio/SignalThresholdInfo.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.radio; + +import android.hardware.radio.SignalMeasurementType; + +/** + * Contains the threshold values of each signal measurement type. + */ +@VintfStability +parcelable SignalThresholdInfo { + /** + * Signal Measurement Type + */ + SignalMeasurementType signalMeasurement; + /** + * A hysteresis time in milliseconds to prevent flapping. A value of 0 disables hysteresis. + */ + int hysteresisMs; + /** + * An interval in dB defining the required magnitude change between reports. This must be + * smaller than the smallest threshold delta. An interval value of 0 disables hysteresis. + */ + int hysteresisDb; + /** + * List of threshold values. Range and unit must reference specific SignalMeasurementType. + * The threshold values for which to apply criteria. A vector size of 0 disables the use of + * thresholds for reporting. + */ + int[] thresholds; + /** + * Indicates whether the reporting criteria of the corresponding measurement is enabled + * (true) or disabled (false). If enabled, modem must trigger the report based on the criteria. + * If disabled, modem must not trigger the report based on the criteria. + */ + boolean isEnabled; +} diff --git a/radio/aidl/android/hardware/radio/SimApdu.aidl b/radio/aidl/android/hardware/radio/SimApdu.aidl new file mode 100644 index 0000000000..65dae4c72e --- /dev/null +++ b/radio/aidl/android/hardware/radio/SimApdu.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.radio; + +@VintfStability +parcelable SimApdu { + /** + * "sessionid" from TS 27.007 +CGLA command. Must be ignored for +CSIM command. + */ + int sessionId; + /** + * Used to derive the APDU ("command" and "length" values in TS 27.007 +CSIM and +CGLA commands) + */ + int cla; + /** + * Used to derive the APDU ("command" and "length" values in TS 27.007 +CSIM and +CGLA commands) + */ + int instruction; + /** + * Used to derive the APDU ("command" and "length" values in TS 27.007 +CSIM and +CGLA commands) + */ + int p1; + /** + * Used to derive the APDU ("command" and "length" values in TS 27.007 +CSIM and +CGLA commands) + */ + int p2; + /** + * Used to derive the APDU ("command" and "length" values in TS 27.007 +CSIM and +CGLA commands) + * A negative P3 implies a 4 byte APDU. + */ + int p3; + /** + * Used to derive the APDU ("command" and "length" values in TS 27.007 +CSIM and +CGLA commands) + * In hex string format ([a-fA-F0-9]*) + */ + String data; +} diff --git a/radio/aidl/android/hardware/radio/SimLockMultiSimPolicy.aidl b/radio/aidl/android/hardware/radio/SimLockMultiSimPolicy.aidl new file mode 100644 index 0000000000..89e13fd27b --- /dev/null +++ b/radio/aidl/android/hardware/radio/SimLockMultiSimPolicy.aidl @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.radio; + +@VintfStability +@Backing(type="int") +enum SimLockMultiSimPolicy { + /** + * Indicates that configuration applies to each slot independently. + */ + NO_MULTISIM_POLICY, + /** + * Indicates that any SIM card can be used as far as one valid card is present in the device. + * For the modem, a SIM card is valid when its content (i.e. MCC, MNC, GID, SPN) matches the + * carrier restriction configuration. + */ + ONE_VALID_SIM_MUST_BE_PRESENT, +} diff --git a/radio/aidl/android/hardware/radio/SimRefreshResult.aidl b/radio/aidl/android/hardware/radio/SimRefreshResult.aidl new file mode 100644 index 0000000000..f4808886a7 --- /dev/null +++ b/radio/aidl/android/hardware/radio/SimRefreshResult.aidl @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.radio; + +import android.hardware.radio.SimRefreshType; + +@VintfStability +parcelable SimRefreshResult { + SimRefreshType type; + /** + * EFID of the updated file if the result is SIM_FILE_UPDATE or 0 for any other result. + */ + int efId; + /** + * AID(application ID) of the card application. See ETSI 102.221 8.1 and 101.220 4. + * For SIM_FILE_UPDATE result it must be set to AID of application in which updated EF resides + * or it must be empty string if EF is outside of an application. For SIM_INIT result this field + * is set to AID of application that caused REFRESH. For SIM_RESET result it is empty string. + */ + String aid; +} diff --git a/radio/aidl/android/hardware/radio/SimRefreshType.aidl b/radio/aidl/android/hardware/radio/SimRefreshType.aidl new file mode 100644 index 0000000000..996cdceb96 --- /dev/null +++ b/radio/aidl/android/hardware/radio/SimRefreshType.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.radio; + +@VintfStability +@Backing(type="int") +enum SimRefreshType { + /** + * A file on SIM has been updated. + */ + SIM_FILE_UPDATE, + /** + * SIM initialized. All files should be re-read. + */ + SIM_INIT, + /** + * SIM reset. SIM power required, SIM may be locked and all files must be re-read. + */ + SIM_RESET, +} diff --git a/radio/aidl/android/hardware/radio/SliceInfo.aidl b/radio/aidl/android/hardware/radio/SliceInfo.aidl new file mode 100644 index 0000000000..91b00677b5 --- /dev/null +++ b/radio/aidl/android/hardware/radio/SliceInfo.aidl @@ -0,0 +1,53 @@ +/* + * 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.radio; + +import android.hardware.radio.SliceServiceType; +import android.hardware.radio.SliceStatus; + +/** + * This struct represents a S-NSSAI as defined in 3GPP TS 24.501. + */ +@VintfStability +parcelable SliceInfo { + /** + * The type of service provided by the slice. See: 3GPP TS 24.501 Section 9.11.2.8. + */ + SliceServiceType sst; + /** + * Slice differentiator is the identifier of a slice that has SliceServiceType as SST. A value + * of -1 indicates that there is no corresponding SliceInfo of the HPLMN. + * See: 3GPP TS 24.501 Section 9.11.2.8. + */ + int sliceDifferentiator; + /** + * This SST corresponds to a SliceInfo (S-NSSAI) of the HPLMN; the SST is mapped to this value. + * See: 3GPP TS 24.501 Section 9.11.2.8. + */ + SliceServiceType mappedHplmnSst; + /** + * Present only if both sliceDifferentiator and mappedHplmnSst are also present. This SD + * corresponds to a SliceInfo (S-NSSAI) of the HPLMN; sliceDifferentiator is mapped to this + * value. A value of -1 indicates that there is no corresponding SliceInfo of the HPLMN. + * See: 3GPP TS 24.501 Section 9.11.2.8. + */ + int mappedHplmnSD; + /** + * Field to indicate the current status of the slice. + */ + SliceStatus status; +} diff --git a/radio/aidl/android/hardware/radio/SliceServiceType.aidl b/radio/aidl/android/hardware/radio/SliceServiceType.aidl new file mode 100644 index 0000000000..624dfb1050 --- /dev/null +++ b/radio/aidl/android/hardware/radio/SliceServiceType.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.radio; + +/** + * Slice/Service Type as defined in 3GPP TS 23.501. + */ +@VintfStability +@Backing(type="byte") +enum SliceServiceType { + /* + * Not specified + */ + NONE, + /* + * Slice suitable for the handling of 5G enhanced Mobile Broadband + */ + EMBB, + /** + * Slice suitable for the handling of ultra-reliable low latency communications + */ + URLLC, + /* + * Slice suitable for the handling of massive IoT + */ + MIOT, +} diff --git a/radio/aidl/android/hardware/radio/SliceStatus.aidl b/radio/aidl/android/hardware/radio/SliceStatus.aidl new file mode 100644 index 0000000000..076e23b269 --- /dev/null +++ b/radio/aidl/android/hardware/radio/SliceStatus.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.radio; + +@VintfStability +@Backing(type="byte") +enum SliceStatus { + UNKNOWN, + /** + * Configured but not allowed or rejected yet + */ + CONFIGURED, + /** + * Allowed to be used + */ + ALLOWED, + /** + * Rejected because not available in PLMN + */ + REJECTED_NOT_AVAILABLE_IN_PLMN, + /** + * Rejected because not available in reg area + */ + REJECTED_NOT_AVAILABLE_IN_REG_AREA, + /** + * Considered valid when configured/allowed slices are not available + */ + DEFAULT_CONFIGURED, +} diff --git a/radio/aidl/android/hardware/radio/SlicingConfig.aidl b/radio/aidl/android/hardware/radio/SlicingConfig.aidl new file mode 100644 index 0000000000..d8d0885142 --- /dev/null +++ b/radio/aidl/android/hardware/radio/SlicingConfig.aidl @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.radio; + +import android.hardware.radio.SliceInfo; +import android.hardware.radio.UrspRule; + +/** + * This struct represents the current slicing configuration. + */ +@VintfStability +parcelable SlicingConfig { + /** + * This vector contains the current URSP rules. Empty vector indicates no rules are configured. + */ + UrspRule[] urspRules; + /** + * List of all slices. + */ + SliceInfo[] sliceInfo; +} diff --git a/radio/aidl/android/hardware/radio/SmsAcknowledgeFailCause.aidl b/radio/aidl/android/hardware/radio/SmsAcknowledgeFailCause.aidl new file mode 100644 index 0000000000..265a10918d --- /dev/null +++ b/radio/aidl/android/hardware/radio/SmsAcknowledgeFailCause.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.radio; + +@VintfStability +@Backing(type="int") +enum SmsAcknowledgeFailCause { + MEMORY_CAPACITY_EXCEEDED = 0xD3, + UNSPECIFIED_ERROR = 0XFF, +} diff --git a/radio/aidl/android/hardware/radio/SmsWriteArgs.aidl b/radio/aidl/android/hardware/radio/SmsWriteArgs.aidl new file mode 100644 index 0000000000..f7a3fd49e2 --- /dev/null +++ b/radio/aidl/android/hardware/radio/SmsWriteArgs.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.radio; + +import android.hardware.radio.SmsWriteArgsStatus; + +@VintfStability +parcelable SmsWriteArgs { + /** + * Status of message. See TS 27.005 3.1. + */ + SmsWriteArgsStatus status; + /** + * PDU of message to write, as an ASCII hex string less the SMSC address, the TP-layer length + * is strlen(pdu)/2. + */ + String pdu; + /** + * SMSC address in GSM BCD format prefixed by a length byte (as expected by TS 27.005) + * or NULL for default SMSC. + */ + String smsc; +} diff --git a/radio/aidl/android/hardware/radio/SmsWriteArgsStatus.aidl b/radio/aidl/android/hardware/radio/SmsWriteArgsStatus.aidl new file mode 100644 index 0000000000..095c71eff6 --- /dev/null +++ b/radio/aidl/android/hardware/radio/SmsWriteArgsStatus.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.radio; + +@VintfStability +@Backing(type="int") +enum SmsWriteArgsStatus { + REC_UNREAD, + REC_READ, + STO_UNSENT, + STO_SENT, +} diff --git a/radio/aidl/android/hardware/radio/SrvccState.aidl b/radio/aidl/android/hardware/radio/SrvccState.aidl new file mode 100644 index 0000000000..d4283149f9 --- /dev/null +++ b/radio/aidl/android/hardware/radio/SrvccState.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.radio; + +@VintfStability +@Backing(type="int") +enum SrvccState { + HANDOVER_STARTED, + HANDOVER_COMPLETED, + HANDOVER_FAILED, + HANDOVER_CANCELED, +} diff --git a/radio/aidl/android/hardware/radio/SsInfoData.aidl b/radio/aidl/android/hardware/radio/SsInfoData.aidl new file mode 100644 index 0000000000..6ee3da0597 --- /dev/null +++ b/radio/aidl/android/hardware/radio/SsInfoData.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.radio; + +@VintfStability +parcelable SsInfoData { + /** + * This is the response data for all of the SS GET/SET Radio requests. + * E.g. IRadio.getClir() returns two ints, so first two values of ssInfo[] will be used for + * response if serviceType is SS_CLIR and requestType is SS_INTERROGATION. + * Max size = RadioConst:SS_INFO_MAX + */ + int[] ssInfo; +} diff --git a/radio/aidl/android/hardware/radio/SsRequestType.aidl b/radio/aidl/android/hardware/radio/SsRequestType.aidl new file mode 100644 index 0000000000..f3decbefa6 --- /dev/null +++ b/radio/aidl/android/hardware/radio/SsRequestType.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.radio; + +@VintfStability +@Backing(type="int") +enum SsRequestType { + ACTIVATION, + DEACTIVATION, + INTERROGATION, + REGISTRATION, + ERASURE, +} diff --git a/radio/aidl/android/hardware/radio/SsServiceType.aidl b/radio/aidl/android/hardware/radio/SsServiceType.aidl new file mode 100644 index 0000000000..eb344f45be --- /dev/null +++ b/radio/aidl/android/hardware/radio/SsServiceType.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.radio; + +@VintfStability +@Backing(type="int") +enum SsServiceType { + CFU, + CF_BUSY, + CF_NO_REPLY, + CF_NOT_REACHABLE, + CF_ALL, + CF_ALL_CONDITIONAL, + CLIP, + CLIR, + COLP, + COLR, + WAIT, + BAOC, + BAOIC, + BAOIC_EXC_HOME, + BAIC, + BAIC_ROAMING, + ALL_BARRING, + OUTGOING_BARRING, + INCOMING_BARRING, +} diff --git a/radio/aidl/android/hardware/radio/SsTeleserviceType.aidl b/radio/aidl/android/hardware/radio/SsTeleserviceType.aidl new file mode 100644 index 0000000000..c11bbfa05d --- /dev/null +++ b/radio/aidl/android/hardware/radio/SsTeleserviceType.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.radio; + +@VintfStability +@Backing(type="int") +enum SsTeleserviceType { + ALL_TELE_AND_BEARER_SERVICES, + ALL_TELESEVICES, + TELEPHONY, + ALL_DATA_TELESERVICES, + SMS_SERVICES, + ALL_TELESERVICES_EXCEPT_SMS, +} diff --git a/radio/aidl/android/hardware/radio/SscMode.aidl b/radio/aidl/android/hardware/radio/SscMode.aidl new file mode 100644 index 0000000000..8722048019 --- /dev/null +++ b/radio/aidl/android/hardware/radio/SscMode.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.radio; + +/** + * Enum representing session and service continuity mode as defined in 3GPP TS 23.501. + */ +@VintfStability +@Backing(type="byte") +enum SscMode { + MODE_1 = 1, + MODE_2 = 2, + MODE_3 = 3, +} diff --git a/radio/aidl/android/hardware/radio/StkCcUnsolSsResult.aidl b/radio/aidl/android/hardware/radio/StkCcUnsolSsResult.aidl new file mode 100644 index 0000000000..0895f9885b --- /dev/null +++ b/radio/aidl/android/hardware/radio/StkCcUnsolSsResult.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. + */ + +package android.hardware.radio; + +import android.hardware.radio.CfData; +import android.hardware.radio.RadioError; +import android.hardware.radio.SsInfoData; +import android.hardware.radio.SsRequestType; +import android.hardware.radio.SsServiceType; +import android.hardware.radio.SsTeleserviceType; +import android.hardware.radio.SuppServiceClass; + +@VintfStability +parcelable StkCcUnsolSsResult { + SsServiceType serviceType; + SsRequestType requestType; + SsTeleserviceType teleserviceType; + SuppServiceClass serviceClass; + RadioError result; + /** + * Valid only for all SsServiceType except SsServiceType:CF_* else empty. + * Only one of ssInfo and cfData may contain values and the other must be empty. + */ + SsInfoData[] ssInfo; + /** + * Valid for SsServiceType:CF_* else empty + * Only one of ssInfo and cfData may contain values and the other must be empty. + */ + CfData[] cfData; +} diff --git a/radio/aidl/android/hardware/radio/SubscriptionType.aidl b/radio/aidl/android/hardware/radio/SubscriptionType.aidl new file mode 100644 index 0000000000..47c54f77a6 --- /dev/null +++ b/radio/aidl/android/hardware/radio/SubscriptionType.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.radio; + +@VintfStability +@Backing(type="int") +enum SubscriptionType { + SUBSCRIPTION_1, + SUBSCRIPTION_2, + SUBSCRIPTION_3, +} diff --git a/radio/aidl/android/hardware/radio/SuppServiceClass.aidl b/radio/aidl/android/hardware/radio/SuppServiceClass.aidl new file mode 100644 index 0000000000..79e73ceffd --- /dev/null +++ b/radio/aidl/android/hardware/radio/SuppServiceClass.aidl @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.radio; + +@VintfStability +@Backing(type="int") +enum SuppServiceClass { + NONE = 0, + VOICE = 1 << 0, + DATA = 1 << 1, + FAX = 1 << 2, + SMS = 1 << 3, + DATA_SYNC = 1 << 4, + DATA_ASYNC = 1 << 5, + PACKET = 1 << 6, + PAD = 1 << 7, + MAX = 1 << 7, +} diff --git a/radio/aidl/android/hardware/radio/SuppSvcNotification.aidl b/radio/aidl/android/hardware/radio/SuppSvcNotification.aidl new file mode 100644 index 0000000000..b41292b170 --- /dev/null +++ b/radio/aidl/android/hardware/radio/SuppSvcNotification.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.radio; + +@VintfStability +parcelable SuppSvcNotification { + /** + * Notification type + * false = MO intermediate result code + * true = MT unsolicited result code + */ + boolean isMT; + /** + * Result code. See 27.007 7.17. + */ + int code; + /** + * CUG index. See 27.007 7.17. + */ + int index; + /** + * "type" from 27.007 7.17 (MT only). + */ + int type; + /** + * "number" from 27.007 7.17. MT only, may be empty string. + */ + String number; +} diff --git a/radio/aidl/android/hardware/radio/TdscdmaSignalStrength.aidl b/radio/aidl/android/hardware/radio/TdscdmaSignalStrength.aidl new file mode 100644 index 0000000000..baed68a17b --- /dev/null +++ b/radio/aidl/android/hardware/radio/TdscdmaSignalStrength.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.radio; + +@VintfStability +parcelable TdscdmaSignalStrength { + /** + * UTRA carrier RSSI as defined in TS 25.225 5.1.4. Valid values are (0-31, 99) as defined in + * TS 27.007 8.5. INT_MAX denotes that the value is invalid/unreported. + */ + int signalStrength; + /** + * Transport Channel BER as defined in TS 25.225 5.2.5. Valid values are (0-7, 99) as defined in + * TS 27.007 8.5. INT_MAX denotes that the value is invalid/unreported. + */ + int bitErrorRate; + /** + * P-CCPCH RSCP as defined in TS 25.225 5.1.1. Valid values are (0-96, 255) as defined in + * TS 27.007 8.69. INT_MAX denotes that the value is invalid/unreported. + */ + int rscp; +} diff --git a/radio/aidl/android/hardware/radio/TimeStampType.aidl b/radio/aidl/android/hardware/radio/TimeStampType.aidl new file mode 100644 index 0000000000..f76a032e16 --- /dev/null +++ b/radio/aidl/android/hardware/radio/TimeStampType.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.radio; + +@VintfStability +@Backing(type="int") +enum TimeStampType { + UNKNOWN, + ANTENNA, + MODEM, + OEM_RIL, + JAVA_RIL, +} diff --git a/radio/aidl/android/hardware/radio/TrafficDescriptor.aidl b/radio/aidl/android/hardware/radio/TrafficDescriptor.aidl new file mode 100644 index 0000000000..4c41e8c89b --- /dev/null +++ b/radio/aidl/android/hardware/radio/TrafficDescriptor.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.radio; + +import android.hardware.radio.OptionalDnn; +import android.hardware.radio.OptionalOsAppId; + +/** + * This struct represents a traffic descriptor. A valid struct must have at least one of the + * optional values present. This is based on the definition of traffic descriptor in + * TS 24.526 Section 5.2. + */ +@VintfStability +parcelable TrafficDescriptor { + /** + * DNN stands for Data Network Name and represents an APN as defined in 3GPP TS 23.003. + */ + OptionalDnn dnn; + /** + * Indicates the OsId + OsAppId (used as category in Android). + */ + OptionalOsAppId osAppId; +} diff --git a/radio/aidl/android/hardware/radio/Translate.java b/radio/aidl/android/hardware/radio/Translate.java new file mode 100644 index 0000000000..a5d32b4e98 --- /dev/null +++ b/radio/aidl/android/hardware/radio/Translate.java @@ -0,0 +1,2520 @@ +/* + * 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.radio; + +import java.util.List; + +public class Translate { + static public android.hardware.radio.IccIo h2aTranslate(android.hardware.radio.V1_0.IccIo in) { + android.hardware.radio.IccIo out = new android.hardware.radio.IccIo(); + out.command = in.command; + out.fileId = in.fileId; + out.path = in.path; + out.p1 = in.p1; + out.p2 = in.p2; + out.p3 = in.p3; + out.data = in.data; + out.pin2 = in.pin2; + out.aid = in.aid; + return out; + } + + static public android.hardware.radio.NeighboringCell h2aTranslate( + android.hardware.radio.V1_0.NeighboringCell in) { + android.hardware.radio.NeighboringCell out = new android.hardware.radio.NeighboringCell(); + out.cid = in.cid; + out.rssi = in.rssi; + return out; + } + + static public android.hardware.radio.UusInfo h2aTranslate( + android.hardware.radio.V1_0.UusInfo in) { + android.hardware.radio.UusInfo out = new android.hardware.radio.UusInfo(); + out.uusType = in.uusType; + out.uusDcs = in.uusDcs; + out.uusData = in.uusData; + return out; + } + + static public android.hardware.radio.Dial h2aTranslate(android.hardware.radio.V1_0.Dial in) { + android.hardware.radio.Dial out = new android.hardware.radio.Dial(); + out.address = in.address; + out.clir = in.clir; + if (in.uusInfo != null) { + out.uusInfo = new android.hardware.radio.UusInfo[in.uusInfo.size()]; + for (int i = 0; i < in.uusInfo.size(); i++) { + out.uusInfo[i] = h2aTranslate(in.uusInfo.get(i)); + } + } + return out; + } + + static public android.hardware.radio.LastCallFailCauseInfo h2aTranslate( + android.hardware.radio.V1_0.LastCallFailCauseInfo in) { + android.hardware.radio.LastCallFailCauseInfo out = + new android.hardware.radio.LastCallFailCauseInfo(); + out.causeCode = in.causeCode; + out.vendorCause = in.vendorCause; + return out; + } + + static public android.hardware.radio.GsmSignalStrength h2aTranslate( + android.hardware.radio.V1_0.GsmSignalStrength in) { + android.hardware.radio.GsmSignalStrength out = + new android.hardware.radio.GsmSignalStrength(); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.signalStrength > 2147483647 || in.signalStrength < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.signalStrength"); + } + out.signalStrength = in.signalStrength; + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.bitErrorRate > 2147483647 || in.bitErrorRate < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.bitErrorRate"); + } + out.bitErrorRate = in.bitErrorRate; + out.timingAdvance = in.timingAdvance; + return out; + } + + static public android.hardware.radio.CdmaSignalStrength h2aTranslate( + android.hardware.radio.V1_0.CdmaSignalStrength in) { + android.hardware.radio.CdmaSignalStrength out = + new android.hardware.radio.CdmaSignalStrength(); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.dbm > 2147483647 || in.dbm < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.dbm"); + } + out.dbm = in.dbm; + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.ecio > 2147483647 || in.ecio < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.ecio"); + } + out.ecio = in.ecio; + return out; + } + + static public android.hardware.radio.EvdoSignalStrength h2aTranslate( + android.hardware.radio.V1_0.EvdoSignalStrength in) { + android.hardware.radio.EvdoSignalStrength out = + new android.hardware.radio.EvdoSignalStrength(); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.dbm > 2147483647 || in.dbm < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.dbm"); + } + out.dbm = in.dbm; + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.ecio > 2147483647 || in.ecio < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.ecio"); + } + out.ecio = in.ecio; + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.signalNoiseRatio > 2147483647 || in.signalNoiseRatio < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.signalNoiseRatio"); + } + out.signalNoiseRatio = in.signalNoiseRatio; + return out; + } + + static public android.hardware.radio.SendSmsResult h2aTranslate( + android.hardware.radio.V1_0.SendSmsResult in) { + android.hardware.radio.SendSmsResult out = new android.hardware.radio.SendSmsResult(); + out.messageRef = in.messageRef; + out.ackPDU = in.ackPDU; + out.errorCode = in.errorCode; + return out; + } + + static public android.hardware.radio.IccIoResult h2aTranslate( + android.hardware.radio.V1_0.IccIoResult in) { + android.hardware.radio.IccIoResult out = new android.hardware.radio.IccIoResult(); + out.sw1 = in.sw1; + out.sw2 = in.sw2; + out.simResponse = in.simResponse; + return out; + } + + static public android.hardware.radio.CallForwardInfo h2aTranslate( + android.hardware.radio.V1_0.CallForwardInfo in) { + android.hardware.radio.CallForwardInfo out = new android.hardware.radio.CallForwardInfo(); + out.status = in.status; + out.reason = in.reason; + out.serviceClass = in.serviceClass; + out.toa = in.toa; + out.number = in.number; + out.timeSeconds = in.timeSeconds; + return out; + } + + static public android.hardware.radio.OperatorInfo h2aTranslate( + android.hardware.radio.V1_0.OperatorInfo in) { + android.hardware.radio.OperatorInfo out = new android.hardware.radio.OperatorInfo(); + out.alphaLong = in.alphaLong; + out.alphaShort = in.alphaShort; + out.operatorNumeric = in.operatorNumeric; + out.status = in.status; + return out; + } + + static public android.hardware.radio.SmsWriteArgs h2aTranslate( + android.hardware.radio.V1_0.SmsWriteArgs in) { + android.hardware.radio.SmsWriteArgs out = new android.hardware.radio.SmsWriteArgs(); + out.status = in.status; + out.pdu = in.pdu; + out.smsc = in.smsc; + return out; + } + + static public android.hardware.radio.CdmaSmsAddress h2aTranslate( + android.hardware.radio.V1_0.CdmaSmsAddress in) { + android.hardware.radio.CdmaSmsAddress out = new android.hardware.radio.CdmaSmsAddress(); + out.digitMode = in.digitMode; + out.numberMode = in.numberMode; + out.numberType = in.numberType; + out.numberPlan = in.numberPlan; + if (in.digits != null) { + out.digits = new byte[in.digits.size()]; + for (int i = 0; i < in.digits.size(); i++) { + // FIXME This requires conversion between signed and unsigned. Change this if it + // doesn't suit your needs. + if (in.digits.get(i) > 127 || in.digits.get(i) < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.digits.get(i)"); + } + out.digits[i] = in.digits.get(i); + } + } + return out; + } + + static public android.hardware.radio.CdmaSmsSubaddress h2aTranslate( + android.hardware.radio.V1_0.CdmaSmsSubaddress in) { + android.hardware.radio.CdmaSmsSubaddress out = + new android.hardware.radio.CdmaSmsSubaddress(); + out.subaddressType = in.subaddressType; + out.odd = in.odd; + if (in.digits != null) { + out.digits = new byte[in.digits.size()]; + for (int i = 0; i < in.digits.size(); i++) { + // FIXME This requires conversion between signed and unsigned. Change this if it + // doesn't suit your needs. + if (in.digits.get(i) > 127 || in.digits.get(i) < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.digits.get(i)"); + } + out.digits[i] = in.digits.get(i); + } + } + return out; + } + + static public android.hardware.radio.CdmaSmsMessage h2aTranslate( + android.hardware.radio.V1_0.CdmaSmsMessage in) { + android.hardware.radio.CdmaSmsMessage out = new android.hardware.radio.CdmaSmsMessage(); + out.teleserviceId = in.teleserviceId; + out.isServicePresent = in.isServicePresent; + out.serviceCategory = in.serviceCategory; + out.address = h2aTranslate(in.address); + out.subAddress = h2aTranslate(in.subAddress); + if (in.bearerData != null) { + out.bearerData = new byte[in.bearerData.size()]; + for (int i = 0; i < in.bearerData.size(); i++) { + // FIXME This requires conversion between signed and unsigned. Change this if it + // doesn't suit your needs. + if (in.bearerData.get(i) > 127 || in.bearerData.get(i) < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.bearerData.get(i)"); + } + out.bearerData[i] = in.bearerData.get(i); + } + } + return out; + } + + static public android.hardware.radio.CdmaSmsAck h2aTranslate( + android.hardware.radio.V1_0.CdmaSmsAck in) { + android.hardware.radio.CdmaSmsAck out = new android.hardware.radio.CdmaSmsAck(); + out.errorClass = in.errorClass; + out.smsCauseCode = in.smsCauseCode; + return out; + } + + static public android.hardware.radio.CdmaBroadcastSmsConfigInfo h2aTranslate( + android.hardware.radio.V1_0.CdmaBroadcastSmsConfigInfo in) { + android.hardware.radio.CdmaBroadcastSmsConfigInfo out = + new android.hardware.radio.CdmaBroadcastSmsConfigInfo(); + out.serviceCategory = in.serviceCategory; + out.language = in.language; + out.selected = in.selected; + return out; + } + + static public android.hardware.radio.CdmaSmsWriteArgs h2aTranslate( + android.hardware.radio.V1_0.CdmaSmsWriteArgs in) { + android.hardware.radio.CdmaSmsWriteArgs out = new android.hardware.radio.CdmaSmsWriteArgs(); + out.status = in.status; + out.message = h2aTranslate(in.message); + return out; + } + + static public android.hardware.radio.GsmBroadcastSmsConfigInfo h2aTranslate( + android.hardware.radio.V1_0.GsmBroadcastSmsConfigInfo in) { + android.hardware.radio.GsmBroadcastSmsConfigInfo out = + new android.hardware.radio.GsmBroadcastSmsConfigInfo(); + out.fromServiceId = in.fromServiceId; + out.toServiceId = in.toServiceId; + out.fromCodeScheme = in.fromCodeScheme; + out.toCodeScheme = in.toCodeScheme; + out.selected = in.selected; + return out; + } + + static public android.hardware.radio.GsmSmsMessage h2aTranslate( + android.hardware.radio.V1_0.GsmSmsMessage in) { + android.hardware.radio.GsmSmsMessage out = new android.hardware.radio.GsmSmsMessage(); + out.smscPdu = in.smscPdu; + out.pdu = in.pdu; + return out; + } + + static public android.hardware.radio.ImsSmsMessage h2aTranslate( + android.hardware.radio.V1_0.ImsSmsMessage in) { + android.hardware.radio.ImsSmsMessage out = new android.hardware.radio.ImsSmsMessage(); + out.tech = in.tech; + out.retry = in.retry; + out.messageRef = in.messageRef; + if (in.cdmaMessage != null) { + out.cdmaMessage = new android.hardware.radio.CdmaSmsMessage[in.cdmaMessage.size()]; + for (int i = 0; i < in.cdmaMessage.size(); i++) { + out.cdmaMessage[i] = h2aTranslate(in.cdmaMessage.get(i)); + } + } + if (in.gsmMessage != null) { + out.gsmMessage = new android.hardware.radio.GsmSmsMessage[in.gsmMessage.size()]; + for (int i = 0; i < in.gsmMessage.size(); i++) { + out.gsmMessage[i] = h2aTranslate(in.gsmMessage.get(i)); + } + } + return out; + } + + static public android.hardware.radio.SimApdu h2aTranslate( + android.hardware.radio.V1_0.SimApdu in) { + android.hardware.radio.SimApdu out = new android.hardware.radio.SimApdu(); + out.sessionId = in.sessionId; + out.cla = in.cla; + out.instruction = in.instruction; + out.p1 = in.p1; + out.p2 = in.p2; + out.p3 = in.p3; + out.data = in.data; + return out; + } + + static public android.hardware.radio.NvWriteItem h2aTranslate( + android.hardware.radio.V1_0.NvWriteItem in) { + android.hardware.radio.NvWriteItem out = new android.hardware.radio.NvWriteItem(); + out.itemId = in.itemId; + out.value = in.value; + return out; + } + + static public android.hardware.radio.SelectUiccSub h2aTranslate( + android.hardware.radio.V1_0.SelectUiccSub in) { + android.hardware.radio.SelectUiccSub out = new android.hardware.radio.SelectUiccSub(); + out.slot = in.slot; + out.appIndex = in.appIndex; + out.subType = in.subType; + out.actStatus = in.actStatus; + return out; + } + + static public android.hardware.radio.HardwareConfigModem h2aTranslate( + android.hardware.radio.V1_0.HardwareConfigModem in) { + android.hardware.radio.HardwareConfigModem out = + new android.hardware.radio.HardwareConfigModem(); + out.rilModel = in.rilModel; + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.rat > 2147483647 || in.rat < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.rat"); + } + out.rat = in.rat; + out.maxVoice = in.maxVoice; + out.maxData = in.maxData; + out.maxStandby = in.maxStandby; + return out; + } + + static public android.hardware.radio.HardwareConfigSim h2aTranslate( + android.hardware.radio.V1_0.HardwareConfigSim in) { + android.hardware.radio.HardwareConfigSim out = + new android.hardware.radio.HardwareConfigSim(); + out.modemUuid = in.modemUuid; + return out; + } + + static public android.hardware.radio.HardwareConfig h2aTranslate( + android.hardware.radio.V1_0.HardwareConfig in) { + android.hardware.radio.HardwareConfig out = new android.hardware.radio.HardwareConfig(); + out.type = in.type; + out.uuid = in.uuid; + out.state = in.state; + if (in.modem != null) { + out.modem = new android.hardware.radio.HardwareConfigModem[in.modem.size()]; + for (int i = 0; i < in.modem.size(); i++) { + out.modem[i] = h2aTranslate(in.modem.get(i)); + } + } + if (in.sim != null) { + out.sim = new android.hardware.radio.HardwareConfigSim[in.sim.size()]; + for (int i = 0; i < in.sim.size(); i++) { + out.sim[i] = h2aTranslate(in.sim.get(i)); + } + } + return out; + } + + static public android.hardware.radio.LceStatusInfo h2aTranslate( + android.hardware.radio.V1_0.LceStatusInfo in) { + android.hardware.radio.LceStatusInfo out = new android.hardware.radio.LceStatusInfo(); + out.lceStatus = in.lceStatus; + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.actualIntervalMs > 127 || in.actualIntervalMs < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.actualIntervalMs"); + } + out.actualIntervalMs = in.actualIntervalMs; + return out; + } + + static public android.hardware.radio.LceDataInfo h2aTranslate( + android.hardware.radio.V1_0.LceDataInfo in) { + android.hardware.radio.LceDataInfo out = new android.hardware.radio.LceDataInfo(); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.lastHopCapacityKbps > 2147483647 || in.lastHopCapacityKbps < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.lastHopCapacityKbps"); + } + out.lastHopCapacityKbps = in.lastHopCapacityKbps; + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.confidenceLevel > 127 || in.confidenceLevel < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.confidenceLevel"); + } + out.confidenceLevel = in.confidenceLevel; + out.lceSuspended = in.lceSuspended; + return out; + } + + static public android.hardware.radio.ActivityStatsInfo h2aTranslate( + android.hardware.radio.V1_0.ActivityStatsInfo in) { + android.hardware.radio.ActivityStatsInfo out = + new android.hardware.radio.ActivityStatsInfo(); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.sleepModeTimeMs > 2147483647 || in.sleepModeTimeMs < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.sleepModeTimeMs"); + } + out.sleepModeTimeMs = in.sleepModeTimeMs; + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.idleModeTimeMs > 2147483647 || in.idleModeTimeMs < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.idleModeTimeMs"); + } + out.idleModeTimeMs = in.idleModeTimeMs; + if (in.txmModetimeMs != null) { + out.txmModetimeMs = new int[in.txmModetimeMs.length]; + for (int i = 0; i < in.txmModetimeMs.length; i++) { + // FIXME This requires conversion between signed and unsigned. Change this if it + // doesn't suit your needs. + if (in.txmModetimeMs[i] > 2147483647 || in.txmModetimeMs[i] < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.txmModetimeMs[i]"); + } + out.txmModetimeMs[i] = in.txmModetimeMs[i]; + } + } + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.rxModeTimeMs > 2147483647 || in.rxModeTimeMs < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.rxModeTimeMs"); + } + out.rxModeTimeMs = in.rxModeTimeMs; + return out; + } + + static public android.hardware.radio.Carrier h2aTranslate( + android.hardware.radio.V1_0.Carrier in) { + android.hardware.radio.Carrier out = new android.hardware.radio.Carrier(); + out.mcc = in.mcc; + out.mnc = in.mnc; + out.matchType = in.matchType; + out.matchData = in.matchData; + return out; + } + + static public android.hardware.radio.CarrierRestrictions h2aTranslate( + android.hardware.radio.V1_0.CarrierRestrictions in) { + android.hardware.radio.CarrierRestrictions out = + new android.hardware.radio.CarrierRestrictions(); + if (in.allowedCarriers != null) { + out.allowedCarriers = new android.hardware.radio.Carrier[in.allowedCarriers.size()]; + for (int i = 0; i < in.allowedCarriers.size(); i++) { + out.allowedCarriers[i] = h2aTranslate(in.allowedCarriers.get(i)); + } + } + if (in.excludedCarriers != null) { + out.excludedCarriers = new android.hardware.radio.Carrier[in.excludedCarriers.size()]; + for (int i = 0; i < in.excludedCarriers.size(); i++) { + out.excludedCarriers[i] = h2aTranslate(in.excludedCarriers.get(i)); + } + } + return out; + } + + static public android.hardware.radio.SuppSvcNotification h2aTranslate( + android.hardware.radio.V1_0.SuppSvcNotification in) { + android.hardware.radio.SuppSvcNotification out = + new android.hardware.radio.SuppSvcNotification(); + out.isMT = in.isMT; + out.code = in.code; + out.index = in.index; + out.type = in.type; + out.number = in.number; + return out; + } + + static public android.hardware.radio.SimRefreshResult h2aTranslate( + android.hardware.radio.V1_0.SimRefreshResult in) { + android.hardware.radio.SimRefreshResult out = new android.hardware.radio.SimRefreshResult(); + out.type = in.type; + out.efId = in.efId; + out.aid = in.aid; + return out; + } + + static public android.hardware.radio.CdmaSignalInfoRecord h2aTranslate( + android.hardware.radio.V1_0.CdmaSignalInfoRecord in) { + android.hardware.radio.CdmaSignalInfoRecord out = + new android.hardware.radio.CdmaSignalInfoRecord(); + out.isPresent = in.isPresent; + out.signalType = in.signalType; + out.alertPitch = in.alertPitch; + out.signal = in.signal; + return out; + } + + static public android.hardware.radio.CdmaCallWaiting h2aTranslate( + android.hardware.radio.V1_0.CdmaCallWaiting in) { + android.hardware.radio.CdmaCallWaiting out = new android.hardware.radio.CdmaCallWaiting(); + out.number = in.number; + out.numberPresentation = in.numberPresentation; + out.name = in.name; + out.signalInfoRecord = h2aTranslate(in.signalInfoRecord); + out.numberType = in.numberType; + out.numberPlan = in.numberPlan; + return out; + } + + static public android.hardware.radio.CdmaDisplayInfoRecord h2aTranslate( + android.hardware.radio.V1_0.CdmaDisplayInfoRecord in) { + android.hardware.radio.CdmaDisplayInfoRecord out = + new android.hardware.radio.CdmaDisplayInfoRecord(); + out.alphaBuf = in.alphaBuf; + return out; + } + + static public android.hardware.radio.CdmaNumberInfoRecord h2aTranslate( + android.hardware.radio.V1_0.CdmaNumberInfoRecord in) { + android.hardware.radio.CdmaNumberInfoRecord out = + new android.hardware.radio.CdmaNumberInfoRecord(); + out.number = in.number; + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.numberType > 127 || in.numberType < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.numberType"); + } + out.numberType = in.numberType; + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.numberPlan > 127 || in.numberPlan < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.numberPlan"); + } + out.numberPlan = in.numberPlan; + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.pi > 127 || in.pi < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.pi"); + } + out.pi = in.pi; + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.si > 127 || in.si < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.si"); + } + out.si = in.si; + return out; + } + + static public android.hardware.radio.CdmaRedirectingNumberInfoRecord h2aTranslate( + android.hardware.radio.V1_0.CdmaRedirectingNumberInfoRecord in) { + android.hardware.radio.CdmaRedirectingNumberInfoRecord out = + new android.hardware.radio.CdmaRedirectingNumberInfoRecord(); + out.redirectingNumber = h2aTranslate(in.redirectingNumber); + out.redirectingReason = in.redirectingReason; + return out; + } + + static public android.hardware.radio.CdmaLineControlInfoRecord h2aTranslate( + android.hardware.radio.V1_0.CdmaLineControlInfoRecord in) { + android.hardware.radio.CdmaLineControlInfoRecord out = + new android.hardware.radio.CdmaLineControlInfoRecord(); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.lineCtrlPolarityIncluded > 127 || in.lineCtrlPolarityIncluded < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.lineCtrlPolarityIncluded"); + } + out.lineCtrlPolarityIncluded = in.lineCtrlPolarityIncluded; + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.lineCtrlToggle > 127 || in.lineCtrlToggle < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.lineCtrlToggle"); + } + out.lineCtrlToggle = in.lineCtrlToggle; + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.lineCtrlReverse > 127 || in.lineCtrlReverse < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.lineCtrlReverse"); + } + out.lineCtrlReverse = in.lineCtrlReverse; + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.lineCtrlPowerDenial > 127 || in.lineCtrlPowerDenial < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.lineCtrlPowerDenial"); + } + out.lineCtrlPowerDenial = in.lineCtrlPowerDenial; + return out; + } + + static public android.hardware.radio.CdmaT53ClirInfoRecord h2aTranslate( + android.hardware.radio.V1_0.CdmaT53ClirInfoRecord in) { + android.hardware.radio.CdmaT53ClirInfoRecord out = + new android.hardware.radio.CdmaT53ClirInfoRecord(); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.cause > 127 || in.cause < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.cause"); + } + out.cause = in.cause; + return out; + } + + static public android.hardware.radio.CdmaT53AudioControlInfoRecord h2aTranslate( + android.hardware.radio.V1_0.CdmaT53AudioControlInfoRecord in) { + android.hardware.radio.CdmaT53AudioControlInfoRecord out = + new android.hardware.radio.CdmaT53AudioControlInfoRecord(); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.upLink > 127 || in.upLink < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.upLink"); + } + out.upLink = in.upLink; + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.downLink > 127 || in.downLink < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.downLink"); + } + out.downLink = in.downLink; + return out; + } + + static public android.hardware.radio.CdmaInformationRecord h2aTranslate( + android.hardware.radio.V1_0.CdmaInformationRecord in) { + android.hardware.radio.CdmaInformationRecord out = + new android.hardware.radio.CdmaInformationRecord(); + out.name = in.name; + if (in.display != null) { + out.display = new android.hardware.radio.CdmaDisplayInfoRecord[in.display.size()]; + for (int i = 0; i < in.display.size(); i++) { + out.display[i] = h2aTranslate(in.display.get(i)); + } + } + if (in.number != null) { + out.number = new android.hardware.radio.CdmaNumberInfoRecord[in.number.size()]; + for (int i = 0; i < in.number.size(); i++) { + out.number[i] = h2aTranslate(in.number.get(i)); + } + } + if (in.signal != null) { + out.signal = new android.hardware.radio.CdmaSignalInfoRecord[in.signal.size()]; + for (int i = 0; i < in.signal.size(); i++) { + out.signal[i] = h2aTranslate(in.signal.get(i)); + } + } + if (in.redir != null) { + out.redir = new android.hardware.radio.CdmaRedirectingNumberInfoRecord[in.redir.size()]; + for (int i = 0; i < in.redir.size(); i++) { + out.redir[i] = h2aTranslate(in.redir.get(i)); + } + } + if (in.lineCtrl != null) { + out.lineCtrl = new android.hardware.radio.CdmaLineControlInfoRecord[in.lineCtrl.size()]; + for (int i = 0; i < in.lineCtrl.size(); i++) { + out.lineCtrl[i] = h2aTranslate(in.lineCtrl.get(i)); + } + } + if (in.clir != null) { + out.clir = new android.hardware.radio.CdmaT53ClirInfoRecord[in.clir.size()]; + for (int i = 0; i < in.clir.size(); i++) { + out.clir[i] = h2aTranslate(in.clir.get(i)); + } + } + if (in.audioCtrl != null) { + out.audioCtrl = + new android.hardware.radio.CdmaT53AudioControlInfoRecord[in.audioCtrl.size()]; + for (int i = 0; i < in.audioCtrl.size(); i++) { + out.audioCtrl[i] = h2aTranslate(in.audioCtrl.get(i)); + } + } + return out; + } + + static public android.hardware.radio.CdmaInformationRecords h2aTranslate( + android.hardware.radio.V1_0.CdmaInformationRecords in) { + android.hardware.radio.CdmaInformationRecords out = + new android.hardware.radio.CdmaInformationRecords(); + if (in.infoRec != null) { + out.infoRec = new android.hardware.radio.CdmaInformationRecord[in.infoRec.size()]; + for (int i = 0; i < in.infoRec.size(); i++) { + out.infoRec[i] = h2aTranslate(in.infoRec.get(i)); + } + } + return out; + } + + static public android.hardware.radio.CfData h2aTranslate( + android.hardware.radio.V1_0.CfData in) { + android.hardware.radio.CfData out = new android.hardware.radio.CfData(); + if (in.cfInfo != null) { + out.cfInfo = new android.hardware.radio.CallForwardInfo[in.cfInfo.size()]; + for (int i = 0; i < in.cfInfo.size(); i++) { + out.cfInfo[i] = h2aTranslate(in.cfInfo.get(i)); + } + } + return out; + } + + static public android.hardware.radio.SsInfoData h2aTranslate( + android.hardware.radio.V1_0.SsInfoData in) { + android.hardware.radio.SsInfoData out = new android.hardware.radio.SsInfoData(); + if (in.ssInfo != null) { + out.ssInfo = new int[in.ssInfo.size()]; + for (int i = 0; i < in.ssInfo.size(); i++) { + out.ssInfo[i] = in.ssInfo.get(i); + } + } + return out; + } + + static public android.hardware.radio.StkCcUnsolSsResult h2aTranslate( + android.hardware.radio.V1_0.StkCcUnsolSsResult in) { + android.hardware.radio.StkCcUnsolSsResult out = + new android.hardware.radio.StkCcUnsolSsResult(); + out.serviceType = in.serviceType; + out.requestType = in.requestType; + out.teleserviceType = in.teleserviceType; + out.serviceClass = in.serviceClass; + out.result = in.result; + if (in.ssInfo != null) { + out.ssInfo = new android.hardware.radio.SsInfoData[in.ssInfo.size()]; + for (int i = 0; i < in.ssInfo.size(); i++) { + out.ssInfo[i] = h2aTranslate(in.ssInfo.get(i)); + } + } + if (in.cfData != null) { + out.cfData = new android.hardware.radio.CfData[in.cfData.size()]; + for (int i = 0; i < in.cfData.size(); i++) { + out.cfData[i] = h2aTranslate(in.cfData.get(i)); + } + } + return out; + } + + static public android.hardware.radio.PcoDataInfo h2aTranslate( + android.hardware.radio.V1_0.PcoDataInfo in) { + android.hardware.radio.PcoDataInfo out = new android.hardware.radio.PcoDataInfo(); + out.cid = in.cid; + out.bearerProto = in.bearerProto; + out.pcoId = in.pcoId; + if (in.contents != null) { + out.contents = new byte[in.contents.size()]; + for (int i = 0; i < in.contents.size(); i++) { + // FIXME This requires conversion between signed and unsigned. Change this if it + // doesn't suit your needs. + if (in.contents.get(i) > 127 || in.contents.get(i) < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.contents.get(i)"); + } + out.contents[i] = in.contents.get(i); + } + } + return out; + } + + static public android.hardware.radio.KeepaliveRequest h2aTranslate( + android.hardware.radio.V1_1.KeepaliveRequest in) { + android.hardware.radio.KeepaliveRequest out = new android.hardware.radio.KeepaliveRequest(); + out.type = in.type; + if (in.sourceAddress != null) { + out.sourceAddress = new byte[in.sourceAddress.size()]; + for (int i = 0; i < in.sourceAddress.size(); i++) { + // FIXME This requires conversion between signed and unsigned. Change this if it + // doesn't suit your needs. + if (in.sourceAddress.get(i) > 127 || in.sourceAddress.get(i) < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.sourceAddress.get(i)"); + } + out.sourceAddress[i] = in.sourceAddress.get(i); + } + } + out.sourcePort = in.sourcePort; + if (in.destinationAddress != null) { + out.destinationAddress = new byte[in.destinationAddress.size()]; + for (int i = 0; i < in.destinationAddress.size(); i++) { + // FIXME This requires conversion between signed and unsigned. Change this if it + // doesn't suit your needs. + if (in.destinationAddress.get(i) > 127 || in.destinationAddress.get(i) < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.destinationAddress.get(i)"); + } + out.destinationAddress[i] = in.destinationAddress.get(i); + } + } + out.destinationPort = in.destinationPort; + out.maxKeepaliveIntervalMillis = in.maxKeepaliveIntervalMillis; + out.cid = in.cid; + return out; + } + + static public android.hardware.radio.KeepaliveStatus h2aTranslate( + android.hardware.radio.V1_1.KeepaliveStatus in) { + android.hardware.radio.KeepaliveStatus out = new android.hardware.radio.KeepaliveStatus(); + out.sessionHandle = in.sessionHandle; + out.code = in.code; + return out; + } + + static public android.hardware.radio.CellIdentityOperatorNames h2aTranslate( + android.hardware.radio.V1_2.CellIdentityOperatorNames in) { + android.hardware.radio.CellIdentityOperatorNames out = + new android.hardware.radio.CellIdentityOperatorNames(); + out.alphaLong = in.alphaLong; + out.alphaShort = in.alphaShort; + return out; + } + + static public android.hardware.radio.CellIdentityCdma h2aTranslate( + android.hardware.radio.V1_2.CellIdentityCdma in) { + android.hardware.radio.CellIdentityCdma out = new android.hardware.radio.CellIdentityCdma(); + out.networkId = in.base.networkId; + out.systemId = in.base.systemId; + out.baseStationId = in.base.baseStationId; + out.longitude = in.base.longitude; + out.latitude = in.base.latitude; + out.operatorNames = h2aTranslate(in.operatorNames); + return out; + } + + static public android.hardware.radio.CellInfoCdma h2aTranslate( + android.hardware.radio.V1_2.CellInfoCdma in) { + android.hardware.radio.CellInfoCdma out = new android.hardware.radio.CellInfoCdma(); + out.cellIdentityCdma = h2aTranslate(in.cellIdentityCdma); + out.signalStrengthCdma = h2aTranslate(in.signalStrengthCdma); + out.signalStrengthEvdo = h2aTranslate(in.signalStrengthEvdo); + return out; + } + + static public android.hardware.radio.WcdmaSignalStrength h2aTranslate( + android.hardware.radio.V1_2.WcdmaSignalStrength in) { + android.hardware.radio.WcdmaSignalStrength out = + new android.hardware.radio.WcdmaSignalStrength(); + out.signalStrength = in.base.signalStrength; + out.bitErrorRate = in.base.bitErrorRate; + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.rscp > 2147483647 || in.rscp < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.rscp"); + } + out.rscp = in.rscp; + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.ecno > 2147483647 || in.ecno < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.ecno"); + } + out.ecno = in.ecno; + return out; + } + + static public android.hardware.radio.TdscdmaSignalStrength h2aTranslate( + android.hardware.radio.V1_2.TdscdmaSignalStrength in) { + android.hardware.radio.TdscdmaSignalStrength out = + new android.hardware.radio.TdscdmaSignalStrength(); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.signalStrength > 2147483647 || in.signalStrength < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.signalStrength"); + } + out.signalStrength = in.signalStrength; + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.bitErrorRate > 2147483647 || in.bitErrorRate < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.bitErrorRate"); + } + out.bitErrorRate = in.bitErrorRate; + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.rscp > 2147483647 || in.rscp < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.rscp"); + } + out.rscp = in.rscp; + return out; + } + + static public android.hardware.radio.VoiceRegStateResult h2aTranslate( + android.hardware.radio.V1_2.VoiceRegStateResult in) { + android.hardware.radio.VoiceRegStateResult out = + new android.hardware.radio.VoiceRegStateResult(); + out.regState = in.regState; + out.rat = in.rat; + out.cssSupported = in.cssSupported; + out.roamingIndicator = in.roamingIndicator; + out.systemIsInPrl = in.systemIsInPrl; + out.defaultRoamingIndicator = in.defaultRoamingIndicator; + out.reasonForDenial = in.reasonForDenial; + // FIXME Unknown type: android.hardware.radio@1.2::CellIdentity + // That type's package needs to be converted separately and the corresponding translate + // function should be added here. + return out; + } + + static public android.hardware.radio.RadioResponseInfoModem h2aTranslate( + android.hardware.radio.V1_3.RadioResponseInfoModem in) { + android.hardware.radio.RadioResponseInfoModem out = + new android.hardware.radio.RadioResponseInfoModem(); + out.type = in.type; + out.serial = in.serial; + out.error = in.error; + out.isEnabled = in.isEnabled; + return out; + } + + static public android.hardware.radio.EmergencyNumber h2aTranslate( + android.hardware.radio.V1_4.EmergencyNumber in) { + android.hardware.radio.EmergencyNumber out = new android.hardware.radio.EmergencyNumber(); + out.number = in.number; + out.mcc = in.mcc; + out.mnc = in.mnc; + out.categories = in.categories; + if (in.urns != null) { + out.urns = new String[in.urns.size()]; + for (int i = 0; i < in.urns.size(); i++) { + out.urns[i] = in.urns.get(i); + } + } + out.sources = in.sources; + return out; + } + + static public android.hardware.radio.RadioFrequencyInfo h2aTranslate( + android.hardware.radio.V1_4.RadioFrequencyInfo in) { + android.hardware.radio.RadioFrequencyInfo out = + new android.hardware.radio.RadioFrequencyInfo(); + switch (in.getDiscriminator()) { + case android.hardware.radio.V1_4.RadioFrequencyInfo.hidl_discriminator.range: + out.setRange(in.range()); + break; + case android.hardware.radio.V1_4.RadioFrequencyInfo.hidl_discriminator.channelNumber: + out.setChannelNumber(in.channelNumber()); + break; + default: + throw new RuntimeException( + "Unknown discriminator value: " + Integer.toString(in.getDiscriminator())); + } + return out; + } + + static public android.hardware.radio.LteVopsInfo h2aTranslate( + android.hardware.radio.V1_4.LteVopsInfo in) { + android.hardware.radio.LteVopsInfo out = new android.hardware.radio.LteVopsInfo(); + out.isVopsSupported = in.isVopsSupported; + out.isEmcBearerSupported = in.isEmcBearerSupported; + return out; + } + + static public android.hardware.radio.NrIndicators h2aTranslate( + android.hardware.radio.V1_4.NrIndicators in) { + android.hardware.radio.NrIndicators out = new android.hardware.radio.NrIndicators(); + out.isEndcAvailable = in.isEndcAvailable; + out.isDcNrRestricted = in.isDcNrRestricted; + out.isNrAvailable = in.isNrAvailable; + return out; + } + + static public android.hardware.radio.DataRegStateResult h2aTranslate( + android.hardware.radio.V1_4.DataRegStateResult in) { + android.hardware.radio.DataRegStateResult out = + new android.hardware.radio.DataRegStateResult(); + out.regState = in.base.regState; + out.rat = in.base.rat; + out.reasonDataDenied = in.base.reasonDataDenied; + out.maxDataCalls = in.base.maxDataCalls; + // FIXME Unknown type: android.hardware.radio@1.2::CellIdentity + // That type's package needs to be converted separately and the corresponding translate + // function should be added here. + out.vopsInfo = h2aTranslate(in.vopsInfo); + out.nrIndicators = h2aTranslate(in.nrIndicators); + return out; + } + + static public android.hardware.radio.DataRegStateResultVopsInfo h2aTranslate( + android.hardware.radio.V1_4.DataRegStateResult.VopsInfo in) { + android.hardware.radio.DataRegStateResultVopsInfo out = + new android.hardware.radio.DataRegStateResultVopsInfo(); + switch (in.getDiscriminator()) { + case android.hardware.radio.V1_4.DataRegStateResult.VopsInfo.hidl_discriminator.noinit: + // Nothing to translate for Monostate. + break; + case android.hardware.radio.V1_4.DataRegStateResult.VopsInfo.hidl_discriminator + .lteVopsInfo: + out.setLteVopsInfo(h2aTranslate(in.lteVopsInfo())); + break; + default: + throw new RuntimeException( + "Unknown discriminator value: " + Integer.toString(in.getDiscriminator())); + } + return out; + } + + static public android.hardware.radio.CellConfigLte h2aTranslate( + android.hardware.radio.V1_4.CellConfigLte in) { + android.hardware.radio.CellConfigLte out = new android.hardware.radio.CellConfigLte(); + out.isEndcAvailable = in.isEndcAvailable; + return out; + } + + static public android.hardware.radio.CellInfoInfo h2aTranslate( + android.hardware.radio.V1_4.CellInfo.Info in) { + android.hardware.radio.CellInfoInfo out = new android.hardware.radio.CellInfoInfo(); + switch (in.getDiscriminator()) { + case android.hardware.radio.V1_4.CellInfo.Info.hidl_discriminator.gsm: + // FIXME Unknown type: android.hardware.radio@1.2::CellInfoGsm + // That type's package needs to be converted separately and the corresponding + // translate function should be added here. + break; + case android.hardware.radio.V1_4.CellInfo.Info.hidl_discriminator.cdma: + out.setCdma(h2aTranslate(in.cdma())); + break; + case android.hardware.radio.V1_4.CellInfo.Info.hidl_discriminator.wcdma: + // FIXME Unknown type: android.hardware.radio@1.2::CellInfoWcdma + // That type's package needs to be converted separately and the corresponding + // translate function should be added here. + break; + case android.hardware.radio.V1_4.CellInfo.Info.hidl_discriminator.tdscdma: + // FIXME Unknown type: android.hardware.radio@1.2::CellInfoTdscdma + // That type's package needs to be converted separately and the corresponding + // translate function should be added here. + break; + case android.hardware.radio.V1_4.CellInfo.Info.hidl_discriminator.lte: + // FIXME Unknown type: android.hardware.radio@1.4::CellInfoLte + // That type's package needs to be converted separately and the corresponding + // translate function should be added here. + break; + case android.hardware.radio.V1_4.CellInfo.Info.hidl_discriminator.nr: + // FIXME Unknown type: android.hardware.radio@1.4::CellInfoNr + // That type's package needs to be converted separately and the corresponding + // translate function should be added here. + break; + default: + throw new RuntimeException( + "Unknown discriminator value: " + Integer.toString(in.getDiscriminator())); + } + return out; + } + + static public android.hardware.radio.RadioCapability h2aTranslate( + android.hardware.radio.V1_4.RadioCapability in) { + android.hardware.radio.RadioCapability out = new android.hardware.radio.RadioCapability(); + out.session = in.session; + out.phase = in.phase; + out.raf = in.raf; + out.logicalModemUuid = in.logicalModemUuid; + out.status = in.status; + return out; + } + + static public android.hardware.radio.CarrierRestrictionsWithPriority h2aTranslate( + android.hardware.radio.V1_4.CarrierRestrictionsWithPriority in) { + android.hardware.radio.CarrierRestrictionsWithPriority out = + new android.hardware.radio.CarrierRestrictionsWithPriority(); + if (in.allowedCarriers != null) { + out.allowedCarriers = new android.hardware.radio.Carrier[in.allowedCarriers.size()]; + for (int i = 0; i < in.allowedCarriers.size(); i++) { + out.allowedCarriers[i] = h2aTranslate(in.allowedCarriers.get(i)); + } + } + if (in.excludedCarriers != null) { + out.excludedCarriers = new android.hardware.radio.Carrier[in.excludedCarriers.size()]; + for (int i = 0; i < in.excludedCarriers.size(); i++) { + out.excludedCarriers[i] = h2aTranslate(in.excludedCarriers.get(i)); + } + } + out.allowedCarriersPrioritized = in.allowedCarriersPrioritized; + return out; + } + + static public android.hardware.radio.RadioAccessSpecifier h2aTranslate( + android.hardware.radio.V1_5.RadioAccessSpecifier in) { + android.hardware.radio.RadioAccessSpecifier out = + new android.hardware.radio.RadioAccessSpecifier(); + out.radioAccessNetwork = in.radioAccessNetwork; + out.bands = h2aTranslate(in.bands); + if (in.channels != null) { + out.channels = new int[in.channels.size()]; + for (int i = 0; i < in.channels.size(); i++) { + out.channels[i] = in.channels.get(i); + } + } + return out; + } + + static public android.hardware.radio.RadioAccessSpecifierBands h2aTranslate( + android.hardware.radio.V1_5.RadioAccessSpecifier.Bands in) { + android.hardware.radio.RadioAccessSpecifierBands out = + new android.hardware.radio.RadioAccessSpecifierBands(); + List bands; + switch (in.getDiscriminator()) { + case android.hardware.radio.V1_5.RadioAccessSpecifier.Bands.hidl_discriminator + .geranBands: + bands = in.geranBands(); + if (bands != null) { + int[] geranBands = new int[bands.size()]; + for (int i = 0; i < bands.size(); i++) { + geranBands[i] = bands.get(i); + } + out.geranBands(geranBands); + } + break; + case android.hardware.radio.V1_5.RadioAccessSpecifier.Bands.hidl_discriminator + .utranBands: + bands = in.utranBands(); + if (bands != null) { + int[] utranBands = new int[bands.size()]; + for (int i = 0; i < bands.size(); i++) { + utranBands[i] = bands.get(i); + } + out.utranBands(utranBands); + } + break; + case android.hardware.radio.V1_5.RadioAccessSpecifier.Bands.hidl_discriminator + .eutranBands: + bands = in.eutranBands(); + if (bands != null) { + int[] eutranBands = new int[bands.size()]; + for (int i = 0; i < bands.size(); i++) { + eutranBands[i] = bands.get(i); + } + out.eutranBands(eutranBands); + } + break; + case android.hardware.radio.V1_5.RadioAccessSpecifier.Bands.hidl_discriminator + .ngranBands: + bands = in.ngranBands(); + if (bands != null) { + int[] ngranBands = new int[bands.size()]; + for (int i = 0; i < bands.size(); i++) { + ngranBands[i] = bands.get(i); + } + out.ngranBands(ngranBands); + } + break; + default: + throw new RuntimeException( + "Unknown discriminator value: " + Integer.toString(in.getDiscriminator())); + } + return out; + } + + static public android.hardware.radio.SignalThresholdInfo h2aTranslate( + android.hardware.radio.V1_5.SignalThresholdInfo in) { + android.hardware.radio.SignalThresholdInfo out = + new android.hardware.radio.SignalThresholdInfo(); + out.signalMeasurement = in.signalMeasurement; + out.hysteresisMs = in.hysteresisMs; + out.hysteresisDb = in.hysteresisDb; + if (in.thresholds != null) { + out.thresholds = new int[in.thresholds.size()]; + for (int i = 0; i < in.thresholds.size(); i++) { + out.thresholds[i] = in.thresholds.get(i); + } + } + out.isEnabled = in.isEnabled; + return out; + } + + static public android.hardware.radio.NetworkScanRequest h2aTranslate( + android.hardware.radio.V1_5.NetworkScanRequest in) { + android.hardware.radio.NetworkScanRequest out = + new android.hardware.radio.NetworkScanRequest(); + out.type = in.type; + out.interval = in.interval; + if (in.specifiers != null) { + out.specifiers = new android.hardware.radio.RadioAccessSpecifier[in.specifiers.size()]; + for (int i = 0; i < in.specifiers.size(); i++) { + out.specifiers[i] = h2aTranslate(in.specifiers.get(i)); + } + } + out.maxSearchTime = in.maxSearchTime; + out.incrementalResults = in.incrementalResults; + out.incrementalResultsPeriodicity = in.incrementalResultsPeriodicity; + if (in.mccMncs != null) { + out.mccMncs = new String[in.mccMncs.size()]; + for (int i = 0; i < in.mccMncs.size(); i++) { + out.mccMncs[i] = in.mccMncs.get(i); + } + } + return out; + } + + static public android.hardware.radio.DataProfileInfo h2aTranslate( + android.hardware.radio.V1_5.DataProfileInfo in) { + android.hardware.radio.DataProfileInfo out = new android.hardware.radio.DataProfileInfo(); + out.profileId = in.profileId; + out.apn = in.apn; + out.protocol = in.protocol; + out.roamingProtocol = in.roamingProtocol; + out.authType = in.authType; + out.user = in.user; + out.password = in.password; + out.type = in.type; + out.maxConnsTime = in.maxConnsTime; + out.maxConns = in.maxConns; + out.waitTime = in.waitTime; + out.enabled = in.enabled; + out.supportedApnTypesBitmap = in.supportedApnTypesBitmap; + out.bearerBitmap = in.bearerBitmap; + out.mtuV4 = in.mtuV4; + out.mtuV6 = in.mtuV6; + out.preferred = in.preferred; + out.persistent = in.persistent; + return out; + } + + static public android.hardware.radio.LinkAddress h2aTranslate( + android.hardware.radio.V1_5.LinkAddress in) { + android.hardware.radio.LinkAddress out = new android.hardware.radio.LinkAddress(); + out.address = in.address; + out.properties = in.properties; + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.deprecationTime > 9223372036854775807L || in.deprecationTime < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.deprecationTime"); + } + out.deprecationTime = in.deprecationTime; + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.expirationTime > 9223372036854775807L || in.expirationTime < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.expirationTime"); + } + out.expirationTime = in.expirationTime; + return out; + } + + static public android.hardware.radio.ClosedSubscriberGroupInfo h2aTranslate( + android.hardware.radio.V1_5.ClosedSubscriberGroupInfo in) { + android.hardware.radio.ClosedSubscriberGroupInfo out = + new android.hardware.radio.ClosedSubscriberGroupInfo(); + out.csgIndication = in.csgIndication; + out.homeNodebName = in.homeNodebName; + out.csgIdentity = in.csgIdentity; + return out; + } + + static public android.hardware.radio.OptionalCsgInfo h2aTranslate( + android.hardware.radio.V1_5.OptionalCsgInfo in) { + android.hardware.radio.OptionalCsgInfo out = new android.hardware.radio.OptionalCsgInfo(); + switch (in.getDiscriminator()) { + case android.hardware.radio.V1_5.OptionalCsgInfo.hidl_discriminator.noinit: + // Nothing to translate for Monostate. + break; + case android.hardware.radio.V1_5.OptionalCsgInfo.hidl_discriminator.csgInfo: + out.setCsgInfo(h2aTranslate(in.csgInfo())); + break; + default: + throw new RuntimeException( + "Unknown discriminator value: " + Integer.toString(in.getDiscriminator())); + } + return out; + } + + static public android.hardware.radio.CellIdentityGsm h2aTranslate( + android.hardware.radio.V1_5.CellIdentityGsm in) { + android.hardware.radio.CellIdentityGsm out = new android.hardware.radio.CellIdentityGsm(); + out.mcc = in.base.base.mcc; + out.mnc = in.base.base.mnc; + out.lac = in.base.base.lac; + out.cid = in.base.base.cid; + out.arfcn = in.base.base.arfcn; + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.base.base.bsic > 127 || in.base.base.bsic < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.base.base.bsic"); + } + out.bsic = in.base.base.bsic; + out.operatorNames = h2aTranslate(in.base.operatorNames); + if (in.additionalPlmns != null) { + out.additionalPlmns = new String[in.additionalPlmns.size()]; + for (int i = 0; i < in.additionalPlmns.size(); i++) { + out.additionalPlmns[i] = in.additionalPlmns.get(i); + } + } + return out; + } + + static public android.hardware.radio.CellIdentityWcdma h2aTranslate( + android.hardware.radio.V1_5.CellIdentityWcdma in) { + android.hardware.radio.CellIdentityWcdma out = + new android.hardware.radio.CellIdentityWcdma(); + out.mcc = in.base.base.mcc; + out.mnc = in.base.base.mnc; + out.lac = in.base.base.lac; + out.cid = in.base.base.cid; + out.psc = in.base.base.psc; + out.uarfcn = in.base.base.uarfcn; + out.operatorNames = h2aTranslate(in.base.operatorNames); + if (in.additionalPlmns != null) { + out.additionalPlmns = new String[in.additionalPlmns.size()]; + for (int i = 0; i < in.additionalPlmns.size(); i++) { + out.additionalPlmns[i] = in.additionalPlmns.get(i); + } + } + out.optionalCsgInfo = h2aTranslate(in.optionalCsgInfo); + return out; + } + + static public android.hardware.radio.CellIdentityTdscdma h2aTranslate( + android.hardware.radio.V1_5.CellIdentityTdscdma in) { + android.hardware.radio.CellIdentityTdscdma out = + new android.hardware.radio.CellIdentityTdscdma(); + out.mcc = in.base.base.mcc; + out.mnc = in.base.base.mnc; + out.lac = in.base.base.lac; + out.cid = in.base.base.cid; + out.cpid = in.base.base.cpid; + out.uarfcn = in.base.uarfcn; + out.operatorNames = h2aTranslate(in.base.operatorNames); + if (in.additionalPlmns != null) { + out.additionalPlmns = new String[in.additionalPlmns.size()]; + for (int i = 0; i < in.additionalPlmns.size(); i++) { + out.additionalPlmns[i] = in.additionalPlmns.get(i); + } + } + out.optionalCsgInfo = h2aTranslate(in.optionalCsgInfo); + return out; + } + + static public android.hardware.radio.CellIdentityLte h2aTranslate( + android.hardware.radio.V1_5.CellIdentityLte in) { + android.hardware.radio.CellIdentityLte out = new android.hardware.radio.CellIdentityLte(); + out.mcc = in.base.base.mcc; + out.mnc = in.base.base.mnc; + out.ci = in.base.base.ci; + out.pci = in.base.base.pci; + out.tac = in.base.base.tac; + out.earfcn = in.base.base.earfcn; + out.operatorNames = h2aTranslate(in.base.operatorNames); + out.bandwidth = in.base.bandwidth; + if (in.additionalPlmns != null) { + out.additionalPlmns = new String[in.additionalPlmns.size()]; + for (int i = 0; i < in.additionalPlmns.size(); i++) { + out.additionalPlmns[i] = in.additionalPlmns.get(i); + } + } + out.optionalCsgInfo = h2aTranslate(in.optionalCsgInfo); + if (in.bands != null) { + out.bands = new int[in.bands.size()]; + for (int i = 0; i < in.bands.size(); i++) { + out.bands[i] = in.bands.get(i); + } + } + return out; + } + + static public android.hardware.radio.CellIdentityNr h2aTranslate( + android.hardware.radio.V1_5.CellIdentityNr in) { + android.hardware.radio.CellIdentityNr out = new android.hardware.radio.CellIdentityNr(); + out.mcc = in.base.mcc; + out.mnc = in.base.mnc; + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.base.nci > 9223372036854775807L || in.base.nci < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.base.nci"); + } + out.nci = in.base.nci; + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.base.pci > 2147483647 || in.base.pci < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.base.pci"); + } + out.pci = in.base.pci; + out.tac = in.base.tac; + out.nrarfcn = in.base.nrarfcn; + out.operatorNames = h2aTranslate(in.base.operatorNames); + if (in.additionalPlmns != null) { + out.additionalPlmns = new String[in.additionalPlmns.size()]; + for (int i = 0; i < in.additionalPlmns.size(); i++) { + out.additionalPlmns[i] = in.additionalPlmns.get(i); + } + } + if (in.bands != null) { + out.bands = new int[in.bands.size()]; + for (int i = 0; i < in.bands.size(); i++) { + out.bands[i] = in.bands.get(i); + } + } + return out; + } + + static public android.hardware.radio.CellInfoGsm h2aTranslate( + android.hardware.radio.V1_5.CellInfoGsm in) { + android.hardware.radio.CellInfoGsm out = new android.hardware.radio.CellInfoGsm(); + out.cellIdentityGsm = h2aTranslate(in.cellIdentityGsm); + out.signalStrengthGsm = h2aTranslate(in.signalStrengthGsm); + return out; + } + + static public android.hardware.radio.CellInfoWcdma h2aTranslate( + android.hardware.radio.V1_5.CellInfoWcdma in) { + android.hardware.radio.CellInfoWcdma out = new android.hardware.radio.CellInfoWcdma(); + out.cellIdentityWcdma = h2aTranslate(in.cellIdentityWcdma); + out.signalStrengthWcdma = h2aTranslate(in.signalStrengthWcdma); + return out; + } + + static public android.hardware.radio.CellInfoTdscdma h2aTranslate( + android.hardware.radio.V1_5.CellInfoTdscdma in) { + android.hardware.radio.CellInfoTdscdma out = new android.hardware.radio.CellInfoTdscdma(); + out.cellIdentityTdscdma = h2aTranslate(in.cellIdentityTdscdma); + out.signalStrengthTdscdma = h2aTranslate(in.signalStrengthTdscdma); + return out; + } + + static public android.hardware.radio.CellIdentity h2aTranslate( + android.hardware.radio.V1_5.CellIdentity in) { + android.hardware.radio.CellIdentity out = new android.hardware.radio.CellIdentity(); + switch (in.getDiscriminator()) { + case android.hardware.radio.V1_5.CellIdentity.hidl_discriminator.noinit: + // Nothing to translate for Monostate. + break; + case android.hardware.radio.V1_5.CellIdentity.hidl_discriminator.gsm: + out.setGsm(h2aTranslate(in.gsm())); + break; + case android.hardware.radio.V1_5.CellIdentity.hidl_discriminator.wcdma: + out.setWcdma(h2aTranslate(in.wcdma())); + break; + case android.hardware.radio.V1_5.CellIdentity.hidl_discriminator.tdscdma: + out.setTdscdma(h2aTranslate(in.tdscdma())); + break; + case android.hardware.radio.V1_5.CellIdentity.hidl_discriminator.cdma: + out.setCdma(h2aTranslate(in.cdma())); + break; + case android.hardware.radio.V1_5.CellIdentity.hidl_discriminator.lte: + out.setLte(h2aTranslate(in.lte())); + break; + case android.hardware.radio.V1_5.CellIdentity.hidl_discriminator.nr: + out.setNr(h2aTranslate(in.nr())); + break; + default: + throw new RuntimeException( + "Unknown discriminator value: " + Integer.toString(in.getDiscriminator())); + } + return out; + } + + static public android.hardware.radio.BarringInfo h2aTranslate( + android.hardware.radio.V1_5.BarringInfo in) { + android.hardware.radio.BarringInfo out = new android.hardware.radio.BarringInfo(); + out.serviceType = in.serviceType; + out.barringType = in.barringType; + out.barringTypeSpecificInfo = h2aTranslate(in.barringTypeSpecificInfo); + return out; + } + + static public android.hardware.radio.BarringInfoBarringTypeSpecificInfoConditional h2aTranslate( + android.hardware.radio.V1_5.BarringInfo.BarringTypeSpecificInfo.Conditional in) { + android.hardware.radio.BarringInfoBarringTypeSpecificInfoConditional out = + new android.hardware.radio.BarringInfoBarringTypeSpecificInfoConditional(); + out.factor = in.factor; + out.timeSeconds = in.timeSeconds; + out.isBarred = in.isBarred; + return out; + } + + static public android.hardware.radio.BarringInfoBarringTypeSpecificInfo h2aTranslate( + android.hardware.radio.V1_5.BarringInfo.BarringTypeSpecificInfo in) { + android.hardware.radio.BarringInfoBarringTypeSpecificInfo out = + new android.hardware.radio.BarringInfoBarringTypeSpecificInfo(); + switch (in.getDiscriminator()) { + case android.hardware.radio.V1_5.BarringInfo.BarringTypeSpecificInfo.hidl_discriminator + .noinit: + // Nothing to translate for Monostate. + break; + case android.hardware.radio.V1_5.BarringInfo.BarringTypeSpecificInfo.hidl_discriminator + .conditional: + out.setConditional(h2aTranslate(in.conditional())); + break; + default: + throw new RuntimeException( + "Unknown discriminator value: " + Integer.toString(in.getDiscriminator())); + } + return out; + } + + static public android.hardware.radio + .RegStateResultAccessTechnologySpecificInfoCdma2000RegistrationInfo + h2aTranslate(android.hardware.radio.V1_5.RegStateResult.AccessTechnologySpecificInfo + .Cdma2000RegistrationInfo in) { + android.hardware.radio + .RegStateResultAccessTechnologySpecificInfoCdma2000RegistrationInfo out = + new android.hardware.radio + .RegStateResultAccessTechnologySpecificInfoCdma2000RegistrationInfo(); + out.cssSupported = in.cssSupported; + out.roamingIndicator = in.roamingIndicator; + out.systemIsInPrl = in.systemIsInPrl; + out.defaultRoamingIndicator = in.defaultRoamingIndicator; + return out; + } + + static public android.hardware.radio + .RegStateResultAccessTechnologySpecificInfoEutranRegistrationInfo + h2aTranslate(android.hardware.radio.V1_5.RegStateResult.AccessTechnologySpecificInfo + .EutranRegistrationInfo in) { + android.hardware.radio + .RegStateResultAccessTechnologySpecificInfoEutranRegistrationInfo out = + new android.hardware.radio + .RegStateResultAccessTechnologySpecificInfoEutranRegistrationInfo(); + out.lteVopsInfo = h2aTranslate(in.lteVopsInfo); + out.nrIndicators = h2aTranslate(in.nrIndicators); + return out; + } + + static public android.hardware.radio.AppStatus h2aTranslate( + android.hardware.radio.V1_5.AppStatus in) { + android.hardware.radio.AppStatus out = new android.hardware.radio.AppStatus(); + out.appType = in.base.appType; + out.appState = in.base.appState; + out.persoSubstate = in.persoSubstate; + out.aidPtr = in.base.aidPtr; + out.appLabelPtr = in.base.appLabelPtr; + out.pin1Replaced = in.base.pin1Replaced; + out.pin1 = in.base.pin1; + out.pin2 = in.base.pin2; + return out; + } + + static public android.hardware.radio.CardStatus h2aTranslate( + android.hardware.radio.V1_5.CardStatus in) { + android.hardware.radio.CardStatus out = new android.hardware.radio.CardStatus(); + out.cardState = in.base.base.base.cardState; + out.universalPinState = in.base.base.base.universalPinState; + out.gsmUmtsSubscriptionAppIndex = in.base.base.base.gsmUmtsSubscriptionAppIndex; + out.cdmaSubscriptionAppIndex = in.base.base.base.cdmaSubscriptionAppIndex; + out.imsSubscriptionAppIndex = in.base.base.base.imsSubscriptionAppIndex; + if (in.applications != null) { + out.applications = new android.hardware.radio.AppStatus[in.applications.size()]; + for (int i = 0; i < in.applications.size(); i++) { + out.applications[i] = h2aTranslate(in.applications.get(i)); + } + } + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.base.base.physicalSlotId > 2147483647 || in.base.base.physicalSlotId < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.base.base.physicalSlotId"); + } + out.physicalSlotId = in.base.base.physicalSlotId; + out.atr = in.base.base.atr; + out.iccid = in.base.base.iccid; + out.eid = in.base.eid; + return out; + } + + static public android.hardware.radio.QosBandwidth h2aTranslate( + android.hardware.radio.V1_6.QosBandwidth in) { + android.hardware.radio.QosBandwidth out = new android.hardware.radio.QosBandwidth(); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.maxBitrateKbps > 2147483647 || in.maxBitrateKbps < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.maxBitrateKbps"); + } + out.maxBitrateKbps = in.maxBitrateKbps; + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.guaranteedBitrateKbps > 2147483647 || in.guaranteedBitrateKbps < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.guaranteedBitrateKbps"); + } + out.guaranteedBitrateKbps = in.guaranteedBitrateKbps; + return out; + } + + static public android.hardware.radio.EpsQos h2aTranslate( + android.hardware.radio.V1_6.EpsQos in) { + android.hardware.radio.EpsQos out = new android.hardware.radio.EpsQos(); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.qci < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.qci"); + } + out.qci = (char) in.qci; + out.downlink = h2aTranslate(in.downlink); + out.uplink = h2aTranslate(in.uplink); + return out; + } + + static public android.hardware.radio.NrQos h2aTranslate(android.hardware.radio.V1_6.NrQos in) { + android.hardware.radio.NrQos out = new android.hardware.radio.NrQos(); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.fiveQi < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.fiveQi"); + } + out.fiveQi = (char) in.fiveQi; + out.downlink = h2aTranslate(in.downlink); + out.uplink = h2aTranslate(in.uplink); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.qfi > 127 || in.qfi < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.qfi"); + } + out.qfi = in.qfi; + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.averagingWindowMs < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.averagingWindowMs"); + } + out.averagingWindowMs = (char) in.averagingWindowMs; + return out; + } + + static public android.hardware.radio.Qos h2aTranslate(android.hardware.radio.V1_6.Qos in) { + android.hardware.radio.Qos out = new android.hardware.radio.Qos(); + switch (in.getDiscriminator()) { + case android.hardware.radio.V1_6.Qos.hidl_discriminator.noinit: + // Nothing to translate for Monostate. + break; + case android.hardware.radio.V1_6.Qos.hidl_discriminator.eps: + out.setEps(h2aTranslate(in.eps())); + break; + case android.hardware.radio.V1_6.Qos.hidl_discriminator.nr: + out.setNr(h2aTranslate(in.nr())); + break; + default: + throw new RuntimeException( + "Unknown discriminator value: " + Integer.toString(in.getDiscriminator())); + } + return out; + } + + static public android.hardware.radio.RadioResponseInfo h2aTranslate( + android.hardware.radio.V1_6.RadioResponseInfo in) { + android.hardware.radio.RadioResponseInfo out = + new android.hardware.radio.RadioResponseInfo(); + out.type = in.type; + out.serial = in.serial; + out.error = in.error; + return out; + } + + static public android.hardware.radio.PortRange h2aTranslate( + android.hardware.radio.V1_6.PortRange in) { + android.hardware.radio.PortRange out = new android.hardware.radio.PortRange(); + out.start = in.start; + out.end = in.end; + return out; + } + + static public android.hardware.radio.MaybePort h2aTranslate( + android.hardware.radio.V1_6.MaybePort in) { + android.hardware.radio.MaybePort out = new android.hardware.radio.MaybePort(); + switch (in.getDiscriminator()) { + case android.hardware.radio.V1_6.MaybePort.hidl_discriminator.noinit: + // Nothing to translate for Monostate. + break; + case android.hardware.radio.V1_6.MaybePort.hidl_discriminator.range: + out.setRange(h2aTranslate(in.range())); + break; + default: + throw new RuntimeException( + "Unknown discriminator value: " + Integer.toString(in.getDiscriminator())); + } + return out; + } + + static public android.hardware.radio.QosFilter h2aTranslate( + android.hardware.radio.V1_6.QosFilter in) { + android.hardware.radio.QosFilter out = new android.hardware.radio.QosFilter(); + if (in.localAddresses != null) { + out.localAddresses = new String[in.localAddresses.size()]; + for (int i = 0; i < in.localAddresses.size(); i++) { + out.localAddresses[i] = in.localAddresses.get(i); + } + } + if (in.remoteAddresses != null) { + out.remoteAddresses = new String[in.remoteAddresses.size()]; + for (int i = 0; i < in.remoteAddresses.size(); i++) { + out.remoteAddresses[i] = in.remoteAddresses.get(i); + } + } + out.localPort = h2aTranslate(in.localPort); + out.remotePort = h2aTranslate(in.remotePort); + out.protocol = in.protocol; + out.tos = h2aTranslate(in.tos); + out.flowLabel = h2aTranslate(in.flowLabel); + out.spi = h2aTranslate(in.spi); + out.direction = in.direction; + out.precedence = in.precedence; + return out; + } + + static public android.hardware.radio.QosFilterTypeOfService h2aTranslate( + android.hardware.radio.V1_6.QosFilter.TypeOfService in) { + android.hardware.radio.QosFilterTypeOfService out = + new android.hardware.radio.QosFilterTypeOfService(); + switch (in.getDiscriminator()) { + case android.hardware.radio.V1_6.QosFilter.TypeOfService.hidl_discriminator.noinit: + // Nothing to translate for Monostate. + break; + case android.hardware.radio.V1_6.QosFilter.TypeOfService.hidl_discriminator.value: + // FIXME This requires conversion between signed and unsigned. Change this if it + // doesn't suit your needs. + if (in.value() > 127 || in.value() < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.value()"); + } + out.setValue(in.value()); + break; + default: + throw new RuntimeException( + "Unknown discriminator value: " + Integer.toString(in.getDiscriminator())); + } + return out; + } + + static public android.hardware.radio.QosFilterIpv6FlowLabel h2aTranslate( + android.hardware.radio.V1_6.QosFilter.Ipv6FlowLabel in) { + android.hardware.radio.QosFilterIpv6FlowLabel out = + new android.hardware.radio.QosFilterIpv6FlowLabel(); + switch (in.getDiscriminator()) { + case android.hardware.radio.V1_6.QosFilter.Ipv6FlowLabel.hidl_discriminator.noinit: + // Nothing to translate for Monostate. + break; + case android.hardware.radio.V1_6.QosFilter.Ipv6FlowLabel.hidl_discriminator.value: + // FIXME This requires conversion between signed and unsigned. Change this if it + // doesn't suit your needs. + if (in.value() > 2147483647 || in.value() < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.value()"); + } + out.setValue(in.value()); + break; + default: + throw new RuntimeException( + "Unknown discriminator value: " + Integer.toString(in.getDiscriminator())); + } + return out; + } + + static public android.hardware.radio.QosFilterIpsecSpi h2aTranslate( + android.hardware.radio.V1_6.QosFilter.IpsecSpi in) { + android.hardware.radio.QosFilterIpsecSpi out = + new android.hardware.radio.QosFilterIpsecSpi(); + switch (in.getDiscriminator()) { + case android.hardware.radio.V1_6.QosFilter.IpsecSpi.hidl_discriminator.noinit: + // Nothing to translate for Monostate. + break; + case android.hardware.radio.V1_6.QosFilter.IpsecSpi.hidl_discriminator.value: + // FIXME This requires conversion between signed and unsigned. Change this if it + // doesn't suit your needs. + if (in.value() > 2147483647 || in.value() < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.value()"); + } + out.setValue(in.value()); + break; + default: + throw new RuntimeException( + "Unknown discriminator value: " + Integer.toString(in.getDiscriminator())); + } + return out; + } + + static public android.hardware.radio.QosSession h2aTranslate( + android.hardware.radio.V1_6.QosSession in) { + android.hardware.radio.QosSession out = new android.hardware.radio.QosSession(); + out.qosSessionId = in.qosSessionId; + out.qos = h2aTranslate(in.qos); + if (in.qosFilters != null) { + out.qosFilters = new android.hardware.radio.QosFilter[in.qosFilters.size()]; + for (int i = 0; i < in.qosFilters.size(); i++) { + out.qosFilters[i] = h2aTranslate(in.qosFilters.get(i)); + } + } + return out; + } + + static public android.hardware.radio.SetupDataCallResult h2aTranslate( + android.hardware.radio.V1_6.SetupDataCallResult in) { + android.hardware.radio.SetupDataCallResult out = + new android.hardware.radio.SetupDataCallResult(); + out.cause = in.cause; + out.suggestedRetryTime = in.suggestedRetryTime; + out.cid = in.cid; + out.active = in.active; + out.type = in.type; + out.ifname = in.ifname; + if (in.addresses != null) { + out.addresses = new android.hardware.radio.LinkAddress[in.addresses.size()]; + for (int i = 0; i < in.addresses.size(); i++) { + out.addresses[i] = h2aTranslate(in.addresses.get(i)); + } + } + if (in.dnses != null) { + out.dnses = new String[in.dnses.size()]; + for (int i = 0; i < in.dnses.size(); i++) { + out.dnses[i] = in.dnses.get(i); + } + } + if (in.gateways != null) { + out.gateways = new String[in.gateways.size()]; + for (int i = 0; i < in.gateways.size(); i++) { + out.gateways[i] = in.gateways.get(i); + } + } + if (in.pcscf != null) { + out.pcscf = new String[in.pcscf.size()]; + for (int i = 0; i < in.pcscf.size(); i++) { + out.pcscf[i] = in.pcscf.get(i); + } + } + out.mtuV4 = in.mtuV4; + out.mtuV6 = in.mtuV6; + out.defaultQos = h2aTranslate(in.defaultQos); + if (in.qosSessions != null) { + out.qosSessions = new android.hardware.radio.QosSession[in.qosSessions.size()]; + for (int i = 0; i < in.qosSessions.size(); i++) { + out.qosSessions[i] = h2aTranslate(in.qosSessions.get(i)); + } + } + out.handoverFailureMode = in.handoverFailureMode; + out.pduSessionId = in.pduSessionId; + out.sliceInfo = h2aTranslate(in.sliceInfo); + if (in.trafficDescriptors != null) { + out.trafficDescriptors = + new android.hardware.radio.TrafficDescriptor[in.trafficDescriptors.size()]; + for (int i = 0; i < in.trafficDescriptors.size(); i++) { + out.trafficDescriptors[i] = h2aTranslate(in.trafficDescriptors.get(i)); + } + } + return out; + } + + static public android.hardware.radio.LinkCapacityEstimate h2aTranslate( + android.hardware.radio.V1_6.LinkCapacityEstimate in) { + android.hardware.radio.LinkCapacityEstimate out = + new android.hardware.radio.LinkCapacityEstimate(); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.downlinkCapacityKbps > 2147483647 || in.downlinkCapacityKbps < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.downlinkCapacityKbps"); + } + out.downlinkCapacityKbps = in.downlinkCapacityKbps; + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.uplinkCapacityKbps > 2147483647 || in.uplinkCapacityKbps < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.uplinkCapacityKbps"); + } + out.uplinkCapacityKbps = in.uplinkCapacityKbps; + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.secondaryDownlinkCapacityKbps > 2147483647 || in.secondaryDownlinkCapacityKbps < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.secondaryDownlinkCapacityKbps"); + } + out.secondaryDownlinkCapacityKbps = in.secondaryDownlinkCapacityKbps; + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.secondaryUplinkCapacityKbps > 2147483647 || in.secondaryUplinkCapacityKbps < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.secondaryUplinkCapacityKbps"); + } + out.secondaryUplinkCapacityKbps = in.secondaryUplinkCapacityKbps; + return out; + } + + static public android.hardware.radio.NrVopsInfo h2aTranslate( + android.hardware.radio.V1_6.NrVopsInfo in) { + android.hardware.radio.NrVopsInfo out = new android.hardware.radio.NrVopsInfo(); + out.vopsSupported = in.vopsSupported; + out.emcSupported = in.emcSupported; + out.emfSupported = in.emfSupported; + return out; + } + + static public android.hardware.radio.LteSignalStrength h2aTranslate( + android.hardware.radio.V1_6.LteSignalStrength in) { + android.hardware.radio.LteSignalStrength out = + new android.hardware.radio.LteSignalStrength(); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.base.signalStrength > 2147483647 || in.base.signalStrength < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.base.signalStrength"); + } + out.signalStrength = in.base.signalStrength; + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.base.rsrp > 2147483647 || in.base.rsrp < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.base.rsrp"); + } + out.rsrp = in.base.rsrp; + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.base.rsrq > 2147483647 || in.base.rsrq < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.base.rsrq"); + } + out.rsrq = in.base.rsrq; + out.rssnr = in.base.rssnr; + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.base.cqi > 2147483647 || in.base.cqi < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.base.cqi"); + } + out.cqi = in.base.cqi; + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.base.timingAdvance > 2147483647 || in.base.timingAdvance < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.base.timingAdvance"); + } + out.timingAdvance = in.base.timingAdvance; + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.cqiTableIndex > 2147483647 || in.cqiTableIndex < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.cqiTableIndex"); + } + out.cqiTableIndex = in.cqiTableIndex; + return out; + } + + static public android.hardware.radio.NrSignalStrength h2aTranslate( + android.hardware.radio.V1_6.NrSignalStrength in) { + android.hardware.radio.NrSignalStrength out = new android.hardware.radio.NrSignalStrength(); + out.ssRsrp = in.base.ssRsrp; + out.ssRsrq = in.base.ssRsrq; + out.ssSinr = in.base.ssSinr; + out.csiRsrp = in.base.csiRsrp; + out.csiRsrq = in.base.csiRsrq; + out.csiSinr = in.base.csiSinr; + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.csiCqiTableIndex > 2147483647 || in.csiCqiTableIndex < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.csiCqiTableIndex"); + } + out.csiCqiTableIndex = in.csiCqiTableIndex; + if (in.csiCqiReport != null) { + out.csiCqiReport = new byte[in.csiCqiReport.size()]; + for (int i = 0; i < in.csiCqiReport.size(); i++) { + // FIXME This requires conversion between signed and unsigned. Change this if it + // doesn't suit your needs. + if (in.csiCqiReport.get(i) > 127 || in.csiCqiReport.get(i) < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.csiCqiReport.get(i)"); + } + out.csiCqiReport[i] = in.csiCqiReport.get(i); + } + } + return out; + } + + static public android.hardware.radio.SignalStrength h2aTranslate( + android.hardware.radio.V1_6.SignalStrength in) { + android.hardware.radio.SignalStrength out = new android.hardware.radio.SignalStrength(); + out.gsm = h2aTranslate(in.gsm); + out.cdma = h2aTranslate(in.cdma); + out.evdo = h2aTranslate(in.evdo); + out.lte = h2aTranslate(in.lte); + out.tdscdma = h2aTranslate(in.tdscdma); + out.wcdma = h2aTranslate(in.wcdma); + out.nr = h2aTranslate(in.nr); + return out; + } + + static public android.hardware.radio.CellInfoLte h2aTranslate( + android.hardware.radio.V1_6.CellInfoLte in) { + android.hardware.radio.CellInfoLte out = new android.hardware.radio.CellInfoLte(); + out.cellIdentityLte = h2aTranslate(in.cellIdentityLte); + out.signalStrengthLte = h2aTranslate(in.signalStrengthLte); + return out; + } + + static public android.hardware.radio.CellInfoNr h2aTranslate( + android.hardware.radio.V1_6.CellInfoNr in) { + android.hardware.radio.CellInfoNr out = new android.hardware.radio.CellInfoNr(); + out.cellIdentityNr = h2aTranslate(in.cellIdentityNr); + out.signalStrengthNr = h2aTranslate(in.signalStrengthNr); + return out; + } + + static public android.hardware.radio.CellInfo h2aTranslate( + android.hardware.radio.V1_6.CellInfo in) { + android.hardware.radio.CellInfo out = new android.hardware.radio.CellInfo(); + out.registered = in.registered; + out.connectionStatus = in.connectionStatus; + out.ratSpecificInfo = h2aTranslate(in.ratSpecificInfo); + return out; + } + + static public android.hardware.radio.CellInfoCellInfoRatSpecificInfo h2aTranslate( + android.hardware.radio.V1_6.CellInfo.CellInfoRatSpecificInfo in) { + android.hardware.radio.CellInfoCellInfoRatSpecificInfo out = + new android.hardware.radio.CellInfoCellInfoRatSpecificInfo(); + switch (in.getDiscriminator()) { + case android.hardware.radio.V1_6.CellInfo.CellInfoRatSpecificInfo.hidl_discriminator + .gsm: + out.setGsm(h2aTranslate(in.gsm())); + break; + case android.hardware.radio.V1_6.CellInfo.CellInfoRatSpecificInfo.hidl_discriminator + .wcdma: + out.setWcdma(h2aTranslate(in.wcdma())); + break; + case android.hardware.radio.V1_6.CellInfo.CellInfoRatSpecificInfo.hidl_discriminator + .tdscdma: + out.setTdscdma(h2aTranslate(in.tdscdma())); + break; + case android.hardware.radio.V1_6.CellInfo.CellInfoRatSpecificInfo.hidl_discriminator + .lte: + out.setLte(h2aTranslate(in.lte())); + break; + case android.hardware.radio.V1_6.CellInfo.CellInfoRatSpecificInfo.hidl_discriminator.nr: + out.setNr(h2aTranslate(in.nr())); + break; + case android.hardware.radio.V1_6.CellInfo.CellInfoRatSpecificInfo.hidl_discriminator + .cdma: + out.setCdma(h2aTranslate(in.cdma())); + break; + default: + throw new RuntimeException( + "Unknown discriminator value: " + Integer.toString(in.getDiscriminator())); + } + return out; + } + + static public android.hardware.radio.NetworkScanResult h2aTranslate( + android.hardware.radio.V1_6.NetworkScanResult in) { + android.hardware.radio.NetworkScanResult out = + new android.hardware.radio.NetworkScanResult(); + out.status = in.status; + out.error = in.error; + if (in.networkInfos != null) { + out.networkInfos = new android.hardware.radio.CellInfo[in.networkInfos.size()]; + for (int i = 0; i < in.networkInfos.size(); i++) { + out.networkInfos[i] = h2aTranslate(in.networkInfos.get(i)); + } + } + return out; + } + + static public android.hardware.radio.RegStateResult h2aTranslate( + android.hardware.radio.V1_6.RegStateResult in) { + android.hardware.radio.RegStateResult out = new android.hardware.radio.RegStateResult(); + out.regState = in.regState; + out.rat = in.rat; + out.reasonForDenial = in.reasonForDenial; + out.cellIdentity = h2aTranslate(in.cellIdentity); + out.registeredPlmn = in.registeredPlmn; + out.accessTechnologySpecificInfo = h2aTranslate(in.accessTechnologySpecificInfo); + return out; + } + + static public android.hardware.radio.RegStateResultAccessTechnologySpecificInfo h2aTranslate( + android.hardware.radio.V1_6.RegStateResult.AccessTechnologySpecificInfo in) { + android.hardware.radio.RegStateResultAccessTechnologySpecificInfo out = + new android.hardware.radio.RegStateResultAccessTechnologySpecificInfo(); + switch (in.getDiscriminator()) { + case android.hardware.radio.V1_6.RegStateResult.AccessTechnologySpecificInfo + .hidl_discriminator.noinit: + // Nothing to translate for Monostate. + break; + case android.hardware.radio.V1_6.RegStateResult.AccessTechnologySpecificInfo + .hidl_discriminator.cdmaInfo: + out.setCdmaInfo(h2aTranslate(in.cdmaInfo())); + break; + case android.hardware.radio.V1_6.RegStateResult.AccessTechnologySpecificInfo + .hidl_discriminator.eutranInfo: + out.setEutranInfo(h2aTranslate(in.eutranInfo())); + break; + case android.hardware.radio.V1_6.RegStateResult.AccessTechnologySpecificInfo + .hidl_discriminator.ngranNrVopsInfo: + out.setNgranNrVopsInfo(h2aTranslate(in.ngranNrVopsInfo())); + break; + case android.hardware.radio.V1_6.RegStateResult.AccessTechnologySpecificInfo + .hidl_discriminator.geranDtmSupported: + out.setGeranDtmSupported(in.geranDtmSupported()); + break; + default: + throw new RuntimeException( + "Unknown discriminator value: " + Integer.toString(in.getDiscriminator())); + } + return out; + } + + static public android.hardware.radio.Call h2aTranslate(android.hardware.radio.V1_6.Call in) { + android.hardware.radio.Call out = new android.hardware.radio.Call(); + out.state = in.base.base.state; + out.index = in.base.base.index; + out.toa = in.base.base.toa; + out.isMpty = in.base.base.isMpty; + out.isMT = in.base.base.isMT; + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.base.base.als > 127 || in.base.base.als < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.base.base.als"); + } + out.als = in.base.base.als; + out.isVoice = in.base.base.isVoice; + out.isVoicePrivacy = in.base.base.isVoicePrivacy; + out.number = in.base.base.number; + out.numberPresentation = in.base.base.numberPresentation; + out.name = in.base.base.name; + out.namePresentation = in.base.base.namePresentation; + if (in.base.base.uusInfo != null) { + out.uusInfo = new android.hardware.radio.UusInfo[in.base.base.uusInfo.size()]; + for (int i = 0; i < in.base.base.uusInfo.size(); i++) { + out.uusInfo[i] = h2aTranslate(in.base.base.uusInfo.get(i)); + } + } + out.audioQuality = in.base.audioQuality; + out.forwardedNumber = in.forwardedNumber; + return out; + } + + static public android.hardware.radio.PhysicalChannelConfig h2aTranslate( + android.hardware.radio.V1_6.PhysicalChannelConfig in) { + android.hardware.radio.PhysicalChannelConfig out = + new android.hardware.radio.PhysicalChannelConfig(); + out.status = in.status; + out.rat = in.rat; + out.downlinkChannelNumber = in.downlinkChannelNumber; + out.uplinkChannelNumber = in.uplinkChannelNumber; + out.cellBandwidthDownlinkKhz = in.cellBandwidthDownlinkKhz; + out.cellBandwidthUplinkKhz = in.cellBandwidthUplinkKhz; + if (in.contextIds != null) { + out.contextIds = new int[in.contextIds.size()]; + for (int i = 0; i < in.contextIds.size(); i++) { + out.contextIds[i] = in.contextIds.get(i); + } + } + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.physicalCellId > 2147483647 || in.physicalCellId < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.physicalCellId"); + } + out.physicalCellId = in.physicalCellId; + out.band = h2aTranslate(in.band); + return out; + } + + static public android.hardware.radio.PhysicalChannelConfigBand h2aTranslate( + android.hardware.radio.V1_6.PhysicalChannelConfig.Band in) { + android.hardware.radio.PhysicalChannelConfigBand out = + new android.hardware.radio.PhysicalChannelConfigBand(); + switch (in.getDiscriminator()) { + case android.hardware.radio.V1_6.PhysicalChannelConfig.Band.hidl_discriminator + .geranBand: + out.setGeranBand(in.geranBand()); + break; + case android.hardware.radio.V1_6.PhysicalChannelConfig.Band.hidl_discriminator + .utranBand: + out.setUtranBand(in.utranBand()); + break; + case android.hardware.radio.V1_6.PhysicalChannelConfig.Band.hidl_discriminator + .eutranBand: + out.setEutranBand(in.eutranBand()); + break; + case android.hardware.radio.V1_6.PhysicalChannelConfig.Band.hidl_discriminator + .ngranBand: + out.setNgranBand(in.ngranBand()); + break; + default: + throw new RuntimeException( + "Unknown discriminator value: " + Integer.toString(in.getDiscriminator())); + } + return out; + } + + static public android.hardware.radio.OptionalSliceInfo h2aTranslate( + android.hardware.radio.V1_6.OptionalSliceInfo in) { + android.hardware.radio.OptionalSliceInfo out = + new android.hardware.radio.OptionalSliceInfo(); + switch (in.getDiscriminator()) { + case android.hardware.radio.V1_6.OptionalSliceInfo.hidl_discriminator.noinit: + // Nothing to translate for Monostate. + break; + case android.hardware.radio.V1_6.OptionalSliceInfo.hidl_discriminator.value: + out.setValue(h2aTranslate(in.value())); + break; + default: + throw new RuntimeException( + "Unknown discriminator value: " + Integer.toString(in.getDiscriminator())); + } + return out; + } + + static public android.hardware.radio.SliceInfo h2aTranslate( + android.hardware.radio.V1_6.SliceInfo in) { + android.hardware.radio.SliceInfo out = new android.hardware.radio.SliceInfo(); + out.sst = in.sst; + out.sliceDifferentiator = in.sliceDifferentiator; + out.mappedHplmnSst = in.mappedHplmnSst; + out.mappedHplmnSD = in.mappedHplmnSD; + out.status = in.status; + return out; + } + + static public android.hardware.radio.OptionalDnn h2aTranslate( + android.hardware.radio.V1_6.OptionalDnn in) { + android.hardware.radio.OptionalDnn out = new android.hardware.radio.OptionalDnn(); + switch (in.getDiscriminator()) { + case android.hardware.radio.V1_6.OptionalDnn.hidl_discriminator.noinit: + // Nothing to translate for Monostate. + break; + case android.hardware.radio.V1_6.OptionalDnn.hidl_discriminator.value: + out.setValue(in.value()); + break; + default: + throw new RuntimeException( + "Unknown discriminator value: " + Integer.toString(in.getDiscriminator())); + } + return out; + } + + static public android.hardware.radio.OptionalOsAppId h2aTranslate( + android.hardware.radio.V1_6.OptionalOsAppId in) { + android.hardware.radio.OptionalOsAppId out = new android.hardware.radio.OptionalOsAppId(); + switch (in.getDiscriminator()) { + case android.hardware.radio.V1_6.OptionalOsAppId.hidl_discriminator.noinit: + // Nothing to translate for Monostate. + break; + case android.hardware.radio.V1_6.OptionalOsAppId.hidl_discriminator.value: + out.setValue(h2aTranslate(in.value())); + break; + default: + throw new RuntimeException( + "Unknown discriminator value: " + Integer.toString(in.getDiscriminator())); + } + return out; + } + + static public android.hardware.radio.OptionalTrafficDescriptor h2aTranslate( + android.hardware.radio.V1_6.OptionalTrafficDescriptor in) { + android.hardware.radio.OptionalTrafficDescriptor out = + new android.hardware.radio.OptionalTrafficDescriptor(); + switch (in.getDiscriminator()) { + case android.hardware.radio.V1_6.OptionalTrafficDescriptor.hidl_discriminator.noinit: + // Nothing to translate for Monostate. + break; + case android.hardware.radio.V1_6.OptionalTrafficDescriptor.hidl_discriminator.value: + out.setValue(h2aTranslate(in.value())); + break; + default: + throw new RuntimeException( + "Unknown discriminator value: " + Integer.toString(in.getDiscriminator())); + } + return out; + } + + static public android.hardware.radio.TrafficDescriptor h2aTranslate( + android.hardware.radio.V1_6.TrafficDescriptor in) { + android.hardware.radio.TrafficDescriptor out = + new android.hardware.radio.TrafficDescriptor(); + out.dnn = h2aTranslate(in.dnn); + out.osAppId = h2aTranslate(in.osAppId); + return out; + } + + static public android.hardware.radio.OsAppId h2aTranslate( + android.hardware.radio.V1_6.OsAppId in) { + android.hardware.radio.OsAppId out = new android.hardware.radio.OsAppId(); + if (in.osAppId != null) { + out.osAppId = new byte[in.osAppId.size()]; + for (int i = 0; i < in.osAppId.size(); i++) { + // FIXME This requires conversion between signed and unsigned. Change this if it + // doesn't suit your needs. + if (in.osAppId.get(i) > 127 || in.osAppId.get(i) < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.osAppId.get(i)"); + } + out.osAppId[i] = in.osAppId.get(i); + } + } + return out; + } + + static public android.hardware.radio.SlicingConfig h2aTranslate( + android.hardware.radio.V1_6.SlicingConfig in) { + android.hardware.radio.SlicingConfig out = new android.hardware.radio.SlicingConfig(); + if (in.urspRules != null) { + out.urspRules = new android.hardware.radio.UrspRule[in.urspRules.size()]; + for (int i = 0; i < in.urspRules.size(); i++) { + out.urspRules[i] = h2aTranslate(in.urspRules.get(i)); + } + } + if (in.sliceInfo != null) { + out.sliceInfo = new android.hardware.radio.SliceInfo[in.sliceInfo.size()]; + for (int i = 0; i < in.sliceInfo.size(); i++) { + out.sliceInfo[i] = h2aTranslate(in.sliceInfo.get(i)); + } + } + return out; + } + + static public android.hardware.radio.UrspRule h2aTranslate( + android.hardware.radio.V1_6.UrspRule in) { + android.hardware.radio.UrspRule out = new android.hardware.radio.UrspRule(); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.precedence > 127 || in.precedence < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.precedence"); + } + out.precedence = in.precedence; + if (in.trafficDescriptors != null) { + out.trafficDescriptors = + new android.hardware.radio.TrafficDescriptor[in.trafficDescriptors.size()]; + for (int i = 0; i < in.trafficDescriptors.size(); i++) { + out.trafficDescriptors[i] = h2aTranslate(in.trafficDescriptors.get(i)); + } + } + if (in.routeSelectionDescriptor != null) { + out.routeSelectionDescriptor = + new android.hardware.radio + .RouteSelectionDescriptor[in.routeSelectionDescriptor.size()]; + for (int i = 0; i < in.routeSelectionDescriptor.size(); i++) { + out.routeSelectionDescriptor[i] = h2aTranslate(in.routeSelectionDescriptor.get(i)); + } + } + return out; + } + + static public android.hardware.radio.RouteSelectionDescriptor h2aTranslate( + android.hardware.radio.V1_6.RouteSelectionDescriptor in) { + android.hardware.radio.RouteSelectionDescriptor out = + new android.hardware.radio.RouteSelectionDescriptor(); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.precedence > 127 || in.precedence < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.precedence"); + } + out.precedence = in.precedence; + out.sessionType = h2aTranslate(in.sessionType); + out.sscMode = h2aTranslate(in.sscMode); + if (in.sliceInfo != null) { + out.sliceInfo = new android.hardware.radio.SliceInfo[in.sliceInfo.size()]; + for (int i = 0; i < in.sliceInfo.size(); i++) { + out.sliceInfo[i] = h2aTranslate(in.sliceInfo.get(i)); + } + } + if (in.dnn != null) { + out.dnn = new String[in.dnn.size()]; + for (int i = 0; i < in.dnn.size(); i++) { + out.dnn[i] = in.dnn.get(i); + } + } + return out; + } + + static public android.hardware.radio.OptionalPdpProtocolType h2aTranslate( + android.hardware.radio.V1_6.OptionalPdpProtocolType in) { + android.hardware.radio.OptionalPdpProtocolType out = + new android.hardware.radio.OptionalPdpProtocolType(); + switch (in.getDiscriminator()) { + case android.hardware.radio.V1_6.OptionalPdpProtocolType.hidl_discriminator.noinit: + // Nothing to translate for Monostate. + break; + case android.hardware.radio.V1_6.OptionalPdpProtocolType.hidl_discriminator.value: + out.setValue(in.value()); + break; + default: + throw new RuntimeException( + "Unknown discriminator value: " + Integer.toString(in.getDiscriminator())); + } + return out; + } + + static public android.hardware.radio.OptionalSscMode h2aTranslate( + android.hardware.radio.V1_6.OptionalSscMode in) { + android.hardware.radio.OptionalSscMode out = new android.hardware.radio.OptionalSscMode(); + switch (in.getDiscriminator()) { + case android.hardware.radio.V1_6.OptionalSscMode.hidl_discriminator.noinit: + // Nothing to translate for Monostate. + break; + case android.hardware.radio.V1_6.OptionalSscMode.hidl_discriminator.value: + out.setValue(in.value()); + break; + default: + throw new RuntimeException( + "Unknown discriminator value: " + Integer.toString(in.getDiscriminator())); + } + return out; + } + + static public android.hardware.radio.ImsiEncryptionInfo h2aTranslate( + android.hardware.radio.V1_6.ImsiEncryptionInfo in) { + android.hardware.radio.ImsiEncryptionInfo out = + new android.hardware.radio.ImsiEncryptionInfo(); + out.mcc = in.base.mcc; + out.mnc = in.base.mnc; + if (in.base.carrierKey != null) { + out.carrierKey = new byte[in.base.carrierKey.size()]; + for (int i = 0; i < in.base.carrierKey.size(); i++) { + // FIXME This requires conversion between signed and unsigned. Change this if it + // doesn't suit your needs. + if (in.base.carrierKey.get(i) > 127 || in.base.carrierKey.get(i) < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.base.carrierKey.get(i)"); + } + out.carrierKey[i] = in.base.carrierKey.get(i); + } + } + out.keyIdentifier = in.base.keyIdentifier; + out.expirationTime = in.base.expirationTime; + out.keyType = in.keyType; + return out; + } + + static public android.hardware.radio.PhonebookRecordInfo h2aTranslate( + android.hardware.radio.V1_6.PhonebookRecordInfo in) { + android.hardware.radio.PhonebookRecordInfo out = + new android.hardware.radio.PhonebookRecordInfo(); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.recordId > 2147483647 || in.recordId < 0) { + throw new RuntimeException( + "Unsafe conversion between signed and unsigned scalars for field: in.recordId"); + } + out.recordId = in.recordId; + out.name = in.name; + out.number = in.number; + if (in.emails != null) { + out.emails = new String[in.emails.size()]; + for (int i = 0; i < in.emails.size(); i++) { + out.emails[i] = in.emails.get(i); + } + } + if (in.additionalNumbers != null) { + out.additionalNumbers = new String[in.additionalNumbers.size()]; + for (int i = 0; i < in.additionalNumbers.size(); i++) { + out.additionalNumbers[i] = in.additionalNumbers.get(i); + } + } + return out; + } + + static public android.hardware.radio.PhonebookCapacity h2aTranslate( + android.hardware.radio.V1_6.PhonebookCapacity in) { + android.hardware.radio.PhonebookCapacity out = + new android.hardware.radio.PhonebookCapacity(); + out.maxAdnRecords = in.maxAdnRecords; + out.usedAdnRecords = in.usedAdnRecords; + out.maxEmailRecords = in.maxEmailRecords; + out.usedEmailRecords = in.usedEmailRecords; + out.maxAdditionalNumberRecords = in.maxAdditionalNumberRecords; + out.usedAdditionalNumberRecords = in.usedAdditionalNumberRecords; + out.maxNameLen = in.maxNameLen; + out.maxNumberLen = in.maxNumberLen; + out.maxEmailLen = in.maxEmailLen; + out.maxAdditionalNumberLen = in.maxAdditionalNumberLen; + return out; + } +} diff --git a/radio/aidl/android/hardware/radio/TtyMode.aidl b/radio/aidl/android/hardware/radio/TtyMode.aidl new file mode 100644 index 0000000000..344ba67734 --- /dev/null +++ b/radio/aidl/android/hardware/radio/TtyMode.aidl @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.radio; + +@VintfStability +@Backing(type="int") +enum TtyMode { + OFF, + FULL, + /** + * Hearing carryover + */ + HCO, + /** + * Voice carryover + */ + VCO, +} diff --git a/radio/aidl/android/hardware/radio/UiccSubActStatus.aidl b/radio/aidl/android/hardware/radio/UiccSubActStatus.aidl new file mode 100644 index 0000000000..b2bb03ecef --- /dev/null +++ b/radio/aidl/android/hardware/radio/UiccSubActStatus.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.radio; + +@VintfStability +@Backing(type="int") +enum UiccSubActStatus { + DEACTIVATE, + ACTIVATE, +} diff --git a/radio/aidl/android/hardware/radio/UrspRule.aidl b/radio/aidl/android/hardware/radio/UrspRule.aidl new file mode 100644 index 0000000000..244bcb13bc --- /dev/null +++ b/radio/aidl/android/hardware/radio/UrspRule.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. + */ + +package android.hardware.radio; + +import android.hardware.radio.RouteSelectionDescriptor; +import android.hardware.radio.TrafficDescriptor; + +/** + * This struct represents a single URSP rule as defined in 3GPP TS 24.526. + */ +@VintfStability +parcelable UrspRule { + /** + * Precedence value in the range of 0 to 255. Higher value has lower precedence. + */ + byte precedence; + /** + * Used as a matcher for network requests. + */ + TrafficDescriptor[] trafficDescriptors; + /** + * List of routes (connection parameters) that must be used for requests matching a + * trafficDescriptor. + */ + RouteSelectionDescriptor[] routeSelectionDescriptor; +} diff --git a/radio/aidl/android/hardware/radio/UssdModeType.aidl b/radio/aidl/android/hardware/radio/UssdModeType.aidl new file mode 100644 index 0000000000..187130c48c --- /dev/null +++ b/radio/aidl/android/hardware/radio/UssdModeType.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.radio; + +@VintfStability +@Backing(type="int") +enum UssdModeType { + /** + * USSD-Notify + */ + NOTIFY, + /** + * USSD-Request + */ + REQUEST, + /** + * Session terminated by network + */ + NW_RELEASE, + /** + * Other local client (eg, SIM Toolkit) has responded + */ + LOCAL_CLIENT, + /** + * Operation not supported + */ + NOT_SUPPORTED, + /** + * Network timeout + */ + NW_TIMEOUT, +} diff --git a/radio/aidl/android/hardware/radio/UtranBands.aidl b/radio/aidl/android/hardware/radio/UtranBands.aidl new file mode 100644 index 0000000000..8a22ed75b3 --- /dev/null +++ b/radio/aidl/android/hardware/radio/UtranBands.aidl @@ -0,0 +1,54 @@ +/* + * 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.radio; + +/** + * UTRAN bands up to V15.0.0 + */ +@VintfStability +@Backing(type="int") +enum UtranBands { + BAND_1 = 1, + BAND_2 = 2, + BAND_3 = 3, + BAND_4 = 4, + BAND_5 = 5, + BAND_6 = 6, + BAND_7 = 7, + BAND_8 = 8, + BAND_9 = 9, + BAND_10 = 10, + BAND_11 = 11, + BAND_12 = 12, + BAND_13 = 13, + BAND_14 = 14, + BAND_19 = 19, + BAND_20 = 20, + BAND_21 = 21, + BAND_22 = 22, + BAND_25 = 25, + BAND_26 = 26, + /** + * TD-SCDMA bands. 3GPP TS 25.102, Table 5.2: Frequency bands + */ + BAND_A = 101, + BAND_B = 102, + BAND_C = 103, + BAND_D = 104, + BAND_E = 105, + BAND_F = 106, +} diff --git a/radio/aidl/android/hardware/radio/UusDcs.aidl b/radio/aidl/android/hardware/radio/UusDcs.aidl new file mode 100644 index 0000000000..b157e47a7d --- /dev/null +++ b/radio/aidl/android/hardware/radio/UusDcs.aidl @@ -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. + */ + +package android.hardware.radio; + +/** + * User-to-User Signaling Information data coding schemes. Possible values for Octet 3 (Protocol + * Discriminator field) in the UUIE. The values have been specified in section 10.5.4.25 of + * 3GPP TS 24.008 + */ +@VintfStability +@Backing(type="int") +enum UusDcs { + /** + * User specified protocol + */ + USP, + /** + * OSI higher layer protocol + */ + OSIHLP, + /** + * X.244 + */ + X244, + /** + * Reserved for system management + */ + RMCF, + /** + * IA5 characters + */ + IA5C, +} diff --git a/radio/aidl/android/hardware/radio/UusInfo.aidl b/radio/aidl/android/hardware/radio/UusInfo.aidl new file mode 100644 index 0000000000..b766b0dc61 --- /dev/null +++ b/radio/aidl/android/hardware/radio/UusInfo.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.radio; + +import android.hardware.radio.UusDcs; +import android.hardware.radio.UusType; + +/** + * User-to-User Signaling Information defined in 3GPP 23.087 v8.0 + */ +@VintfStability +parcelable UusInfo { + /** + * UUS type + */ + UusType uusType; + /** + * UUS data coding scheme + */ + UusDcs uusDcs; + /** + * UUS data + */ + String uusData; +} diff --git a/radio/aidl/android/hardware/radio/UusType.aidl b/radio/aidl/android/hardware/radio/UusType.aidl new file mode 100644 index 0000000000..af86c9780e --- /dev/null +++ b/radio/aidl/android/hardware/radio/UusType.aidl @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.radio; + +/** + * User-to-User signaling Info activation types derived from 3GPP 23.087 v8.0 + */ +@VintfStability +@Backing(type="int") +enum UusType { + TYPE1_IMPLICIT, + TYPE1_REQUIRED, + TYPE1_NOT_REQUIRED, + TYPE2_REQUIRED, + TYPE2_NOT_REQUIRED, + TYPE3_REQUIRED, + TYPE3_NOT_REQUIRED, +} diff --git a/radio/aidl/android/hardware/radio/VoiceRegStateResult.aidl b/radio/aidl/android/hardware/radio/VoiceRegStateResult.aidl new file mode 100644 index 0000000000..897c663621 --- /dev/null +++ b/radio/aidl/android/hardware/radio/VoiceRegStateResult.aidl @@ -0,0 +1,94 @@ +/* + * 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.radio; + +import android.hardware.radio.CellIdentity; +import android.hardware.radio.RegState; + +@VintfStability +parcelable VoiceRegStateResult { + /** + * Valid reg states are NOT_REG_MT_NOT_SEARCHING_OP, REG_HOME, NOT_REG_MT_SEARCHING_OP, + * REG_DENIED, UNKNOWN, REG_ROAMING defined in RegState. + */ + RegState regState; + /** + * Indicates the available voice radio technology, valid values as defined by RadioTechnology. + */ + int rat; + /** + * Concurrent services support indicator, if registered on a CDMA system. + * false - Concurrent services not supported, + * true - Concurrent services supported + */ + boolean cssSupported; + /** + * TSB-58 Roaming Indicator if registered on a CDMA or EVDO system or -1 if not. + * Valid values are 0-255. + */ + int roamingIndicator; + /** + * Indicates whether the current system is in the PRL if registered on a CDMA or EVDO system + * or -1 if not. 0=not in the PRL, 1=in the PRL + */ + int systemIsInPrl; + /** + * Default Roaming Indicator from the PRL if registered on a CDMA or EVDO system or -1 if not. + * Valid values are 0-255. + */ + int defaultRoamingIndicator; + /** + * Reason for denial if registration state is REG_DENIED. This is an enumerated reason why + * registration was denied. See 3GPP TS 24.008, 10.5.3.6 and Annex G. + * 0 - General + * 1 - Authentication Failure + * 2 - IMSI unknown in HLR + * 3 - Illegal MS + * 4 - Illegal ME + * 5 - PLMN not allowed + * 6 - Location area not allowed + * 7 - Roaming not allowed + * 8 - No Suitable Cells in this Location Area + * 9 - Network failure + * 10 - Persistent location update reject + * 11 - PLMN not allowed + * 12 - Location area not allowed + * 13 - Roaming not allowed in this Location Area + * 15 - No Suitable Cells in this Location Area + * 17 - Network Failure + * 20 - MAC Failure + * 21 - Sync Failure + * 22 - Congestion + * 23 - GSM Authentication unacceptable + * 25 - Not Authorized for this CSG + * 32 - Service option not supported + * 33 - Requested service option not subscribed + * 34 - Service option temporarily out of order + * 38 - Call cannot be identified + * 48-63 - Retry upon entry into a new cell + * 95 - Semantically incorrect message + * 96 - Invalid mandatory information + * 97 - Message type non-existent or not implemented + * 98 - Message type not compatible with protocol state + * 99 - Information element non-existent or not implemented + * 100 - Conditional IE error + * 101 - Message not compatible with protocol state + * 111 - Protocol error, unspecified + */ + int reasonForDenial; + CellIdentity cellIdentity; +} diff --git a/radio/aidl/android/hardware/radio/VopsIndicator.aidl b/radio/aidl/android/hardware/radio/VopsIndicator.aidl new file mode 100644 index 0000000000..0533be9393 --- /dev/null +++ b/radio/aidl/android/hardware/radio/VopsIndicator.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.radio; + +/** + * Defines the values for VoPS indicator of NR as per 3gpp spec 24.501 sec 9.10.3.5 + */ +@VintfStability +@Backing(type="byte") +enum VopsIndicator { + /** + * IMS voice over PS session not supported + */ + VOPS_NOT_SUPPORTED, + /** + * IMS voice over PS session supported over 3GPP access + */ + VOPS_OVER_3GPP, + /** + * IMS voice over PS session supported over non-3GPP access + */ + VOPS_OVER_NON_3GPP, +} diff --git a/radio/aidl/android/hardware/radio/WcdmaSignalStrength.aidl b/radio/aidl/android/hardware/radio/WcdmaSignalStrength.aidl new file mode 100644 index 0000000000..95a3455e4c --- /dev/null +++ b/radio/aidl/android/hardware/radio/WcdmaSignalStrength.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.radio; + +@VintfStability +parcelable WcdmaSignalStrength { + /** + * Valid values are (0-31, 99) as defined in TS 27.007 8.5; INT_MAX means unreported. + */ + int signalStrength; + /** + * Bit error rate (0-7, 99) as defined in TS 27.007 8.5; INT_MAX means invalid/unreported. + */ + int bitErrorRate; + /** + * CPICH RSCP as defined in TS 25.215 5.1.1. Valid values are (0-96, 255) as defined in + * TS 27.007 8.69. INT_MAX denotes that the value is invalid/unreported. + */ + int rscp; + /** + * Ec/No value as defined in TS 25.215 5.1.5. Valid values are (0-49, 255) as defined in + * TS 27.007 8.69. INT_MAX denotes that the value is invalid/unreported. + */ + int ecno; +} diff --git a/radio/aidl/android/hardware/radio/translate-ndk.cpp b/radio/aidl/android/hardware/radio/translate-ndk.cpp new file mode 100644 index 0000000000..0492aded9d --- /dev/null +++ b/radio/aidl/android/hardware/radio/translate-ndk.cpp @@ -0,0 +1,7404 @@ +/* + * 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/hardware/radio/translate-ndk.h" + +namespace android::h2a { + +static_assert(aidl::android::hardware::radio::RadioCdmaSmsConst::ADDRESS_MAX == + static_cast( + ::android::hardware::radio::V1_0::RadioCdmaSmsConst::ADDRESS_MAX)); +static_assert(aidl::android::hardware::radio::RadioCdmaSmsConst::SUBADDRESS_MAX == + static_cast( + ::android::hardware::radio::V1_0::RadioCdmaSmsConst::SUBADDRESS_MAX)); +static_assert(aidl::android::hardware::radio::RadioCdmaSmsConst::BEARER_DATA_MAX == + static_cast( + ::android::hardware::radio::V1_0::RadioCdmaSmsConst::BEARER_DATA_MAX)); +static_assert(aidl::android::hardware::radio::RadioCdmaSmsConst::UDH_MAX_SND_SIZE == + static_cast( + ::android::hardware::radio::V1_0::RadioCdmaSmsConst::UDH_MAX_SND_SIZE)); +static_assert( + aidl::android::hardware::radio::RadioCdmaSmsConst::UDH_EO_DATA_SEGMENT_MAX == + static_cast( + ::android::hardware::radio::V1_0::RadioCdmaSmsConst::UDH_EO_DATA_SEGMENT_MAX)); +static_assert(aidl::android::hardware::radio::RadioCdmaSmsConst::MAX_UD_HEADERS == + static_cast( + ::android::hardware::radio::V1_0::RadioCdmaSmsConst::MAX_UD_HEADERS)); +static_assert(aidl::android::hardware::radio::RadioCdmaSmsConst::USER_DATA_MAX == + static_cast( + ::android::hardware::radio::V1_0::RadioCdmaSmsConst::USER_DATA_MAX)); +static_assert(aidl::android::hardware::radio::RadioCdmaSmsConst::UDH_LARGE_PIC_SIZE == + static_cast( + ::android::hardware::radio::V1_0::RadioCdmaSmsConst::UDH_LARGE_PIC_SIZE)); +static_assert(aidl::android::hardware::radio::RadioCdmaSmsConst::UDH_SMALL_PIC_SIZE == + static_cast( + ::android::hardware::radio::V1_0::RadioCdmaSmsConst::UDH_SMALL_PIC_SIZE)); +static_assert(aidl::android::hardware::radio::RadioCdmaSmsConst::UDH_VAR_PIC_SIZE == + static_cast( + ::android::hardware::radio::V1_0::RadioCdmaSmsConst::UDH_VAR_PIC_SIZE)); +static_assert(aidl::android::hardware::radio::RadioCdmaSmsConst::UDH_ANIM_NUM_BITMAPS == + static_cast( + ::android::hardware::radio::V1_0::RadioCdmaSmsConst::UDH_ANIM_NUM_BITMAPS)); +static_assert(aidl::android::hardware::radio::RadioCdmaSmsConst::UDH_LARGE_BITMAP_SIZE == + static_cast( + ::android::hardware::radio::V1_0::RadioCdmaSmsConst::UDH_LARGE_BITMAP_SIZE)); +static_assert(aidl::android::hardware::radio::RadioCdmaSmsConst::UDH_SMALL_BITMAP_SIZE == + static_cast( + ::android::hardware::radio::V1_0::RadioCdmaSmsConst::UDH_SMALL_BITMAP_SIZE)); +static_assert(aidl::android::hardware::radio::RadioCdmaSmsConst::UDH_OTHER_SIZE == + static_cast( + ::android::hardware::radio::V1_0::RadioCdmaSmsConst::UDH_OTHER_SIZE)); +static_assert(aidl::android::hardware::radio::RadioCdmaSmsConst::IP_ADDRESS_SIZE == + static_cast( + ::android::hardware::radio::V1_0::RadioCdmaSmsConst::IP_ADDRESS_SIZE)); + +static_assert(aidl::android::hardware::radio::RadioResponseType::SOLICITED == + static_cast( + ::android::hardware::radio::V1_0::RadioResponseType::SOLICITED)); +static_assert(aidl::android::hardware::radio::RadioResponseType::SOLICITED_ACK == + static_cast( + ::android::hardware::radio::V1_0::RadioResponseType::SOLICITED_ACK)); +static_assert(aidl::android::hardware::radio::RadioResponseType::SOLICITED_ACK_EXP == + static_cast( + ::android::hardware::radio::V1_0::RadioResponseType::SOLICITED_ACK_EXP)); + +static_assert(aidl::android::hardware::radio::RadioIndicationType::UNSOLICITED == + static_cast( + ::android::hardware::radio::V1_0::RadioIndicationType::UNSOLICITED)); +static_assert(aidl::android::hardware::radio::RadioIndicationType::UNSOLICITED_ACK_EXP == + static_cast( + ::android::hardware::radio::V1_0::RadioIndicationType::UNSOLICITED_ACK_EXP)); + +static_assert(aidl::android::hardware::radio::RestrictedState::NONE == + static_cast( + ::android::hardware::radio::V1_0::RestrictedState::NONE)); +static_assert(aidl::android::hardware::radio::RestrictedState::CS_EMERGENCY == + static_cast( + ::android::hardware::radio::V1_0::RestrictedState::CS_EMERGENCY)); +static_assert(aidl::android::hardware::radio::RestrictedState::CS_NORMAL == + static_cast( + ::android::hardware::radio::V1_0::RestrictedState::CS_NORMAL)); +static_assert(aidl::android::hardware::radio::RestrictedState::CS_ALL == + static_cast( + ::android::hardware::radio::V1_0::RestrictedState::CS_ALL)); +static_assert(aidl::android::hardware::radio::RestrictedState::PS_ALL == + static_cast( + ::android::hardware::radio::V1_0::RestrictedState::PS_ALL)); + +static_assert(aidl::android::hardware::radio::CardState::ABSENT == + static_cast( + ::android::hardware::radio::V1_0::CardState::ABSENT)); +static_assert(aidl::android::hardware::radio::CardState::PRESENT == + static_cast( + ::android::hardware::radio::V1_0::CardState::PRESENT)); +static_assert(aidl::android::hardware::radio::CardState::ERROR == + static_cast( + ::android::hardware::radio::V1_0::CardState::ERROR)); +static_assert(aidl::android::hardware::radio::CardState::RESTRICTED == + static_cast( + ::android::hardware::radio::V1_0::CardState::RESTRICTED)); + +static_assert(aidl::android::hardware::radio::PinState::UNKNOWN == + static_cast( + ::android::hardware::radio::V1_0::PinState::UNKNOWN)); +static_assert(aidl::android::hardware::radio::PinState::ENABLED_NOT_VERIFIED == + static_cast( + ::android::hardware::radio::V1_0::PinState::ENABLED_NOT_VERIFIED)); +static_assert(aidl::android::hardware::radio::PinState::ENABLED_VERIFIED == + static_cast( + ::android::hardware::radio::V1_0::PinState::ENABLED_VERIFIED)); +static_assert(aidl::android::hardware::radio::PinState::DISABLED == + static_cast( + ::android::hardware::radio::V1_0::PinState::DISABLED)); +static_assert(aidl::android::hardware::radio::PinState::ENABLED_BLOCKED == + static_cast( + ::android::hardware::radio::V1_0::PinState::ENABLED_BLOCKED)); +static_assert(aidl::android::hardware::radio::PinState::ENABLED_PERM_BLOCKED == + static_cast( + ::android::hardware::radio::V1_0::PinState::ENABLED_PERM_BLOCKED)); + +static_assert(aidl::android::hardware::radio::AppType::UNKNOWN == + static_cast( + ::android::hardware::radio::V1_0::AppType::UNKNOWN)); +static_assert(aidl::android::hardware::radio::AppType::SIM == + static_cast( + ::android::hardware::radio::V1_0::AppType::SIM)); +static_assert(aidl::android::hardware::radio::AppType::USIM == + static_cast( + ::android::hardware::radio::V1_0::AppType::USIM)); +static_assert(aidl::android::hardware::radio::AppType::RUIM == + static_cast( + ::android::hardware::radio::V1_0::AppType::RUIM)); +static_assert(aidl::android::hardware::radio::AppType::CSIM == + static_cast( + ::android::hardware::radio::V1_0::AppType::CSIM)); +static_assert(aidl::android::hardware::radio::AppType::ISIM == + static_cast( + ::android::hardware::radio::V1_0::AppType::ISIM)); + +static_assert(aidl::android::hardware::radio::AppState::UNKNOWN == + static_cast( + ::android::hardware::radio::V1_0::AppState::UNKNOWN)); +static_assert(aidl::android::hardware::radio::AppState::DETECTED == + static_cast( + ::android::hardware::radio::V1_0::AppState::DETECTED)); +static_assert(aidl::android::hardware::radio::AppState::PIN == + static_cast( + ::android::hardware::radio::V1_0::AppState::PIN)); +static_assert(aidl::android::hardware::radio::AppState::PUK == + static_cast( + ::android::hardware::radio::V1_0::AppState::PUK)); +static_assert(aidl::android::hardware::radio::AppState::SUBSCRIPTION_PERSO == + static_cast( + ::android::hardware::radio::V1_0::AppState::SUBSCRIPTION_PERSO)); +static_assert(aidl::android::hardware::radio::AppState::READY == + static_cast( + ::android::hardware::radio::V1_0::AppState::READY)); + +static_assert(aidl::android::hardware::radio::RadioState::OFF == + static_cast( + ::android::hardware::radio::V1_0::RadioState::OFF)); +static_assert(aidl::android::hardware::radio::RadioState::UNAVAILABLE == + static_cast( + ::android::hardware::radio::V1_0::RadioState::UNAVAILABLE)); +static_assert(aidl::android::hardware::radio::RadioState::ON == + static_cast( + ::android::hardware::radio::V1_0::RadioState::ON)); + +static_assert(aidl::android::hardware::radio::SapConnectRsp::SUCCESS == + static_cast( + ::android::hardware::radio::V1_0::SapConnectRsp::SUCCESS)); +static_assert(aidl::android::hardware::radio::SapConnectRsp::CONNECT_FAILURE == + static_cast( + ::android::hardware::radio::V1_0::SapConnectRsp::CONNECT_FAILURE)); +static_assert(aidl::android::hardware::radio::SapConnectRsp::MSG_SIZE_TOO_LARGE == + static_cast( + ::android::hardware::radio::V1_0::SapConnectRsp::MSG_SIZE_TOO_LARGE)); +static_assert(aidl::android::hardware::radio::SapConnectRsp::MSG_SIZE_TOO_SMALL == + static_cast( + ::android::hardware::radio::V1_0::SapConnectRsp::MSG_SIZE_TOO_SMALL)); +static_assert(aidl::android::hardware::radio::SapConnectRsp::CONNECT_OK_CALL_ONGOING == + static_cast( + ::android::hardware::radio::V1_0::SapConnectRsp::CONNECT_OK_CALL_ONGOING)); + +static_assert(aidl::android::hardware::radio::SapDisconnectType::GRACEFUL == + static_cast( + ::android::hardware::radio::V1_0::SapDisconnectType::GRACEFUL)); +static_assert(aidl::android::hardware::radio::SapDisconnectType::IMMEDIATE == + static_cast( + ::android::hardware::radio::V1_0::SapDisconnectType::IMMEDIATE)); + +static_assert(aidl::android::hardware::radio::SapApduType::APDU == + static_cast( + ::android::hardware::radio::V1_0::SapApduType::APDU)); +static_assert(aidl::android::hardware::radio::SapApduType::APDU7816 == + static_cast( + ::android::hardware::radio::V1_0::SapApduType::APDU7816)); + +static_assert(aidl::android::hardware::radio::SapResultCode::SUCCESS == + static_cast( + ::android::hardware::radio::V1_0::SapResultCode::SUCCESS)); +static_assert(aidl::android::hardware::radio::SapResultCode::GENERIC_FAILURE == + static_cast( + ::android::hardware::radio::V1_0::SapResultCode::GENERIC_FAILURE)); +static_assert(aidl::android::hardware::radio::SapResultCode::CARD_NOT_ACCESSSIBLE == + static_cast( + ::android::hardware::radio::V1_0::SapResultCode::CARD_NOT_ACCESSSIBLE)); +static_assert(aidl::android::hardware::radio::SapResultCode::CARD_ALREADY_POWERED_OFF == + static_cast( + ::android::hardware::radio::V1_0::SapResultCode::CARD_ALREADY_POWERED_OFF)); +static_assert(aidl::android::hardware::radio::SapResultCode::CARD_REMOVED == + static_cast( + ::android::hardware::radio::V1_0::SapResultCode::CARD_REMOVED)); +static_assert(aidl::android::hardware::radio::SapResultCode::CARD_ALREADY_POWERED_ON == + static_cast( + ::android::hardware::radio::V1_0::SapResultCode::CARD_ALREADY_POWERED_ON)); +static_assert(aidl::android::hardware::radio::SapResultCode::DATA_NOT_AVAILABLE == + static_cast( + ::android::hardware::radio::V1_0::SapResultCode::DATA_NOT_AVAILABLE)); +static_assert(aidl::android::hardware::radio::SapResultCode::NOT_SUPPORTED == + static_cast( + ::android::hardware::radio::V1_0::SapResultCode::NOT_SUPPORTED)); + +static_assert(aidl::android::hardware::radio::SapStatus::UNKNOWN_ERROR == + static_cast( + ::android::hardware::radio::V1_0::SapStatus::UNKNOWN_ERROR)); +static_assert(aidl::android::hardware::radio::SapStatus::CARD_RESET == + static_cast( + ::android::hardware::radio::V1_0::SapStatus::CARD_RESET)); +static_assert(aidl::android::hardware::radio::SapStatus::CARD_NOT_ACCESSIBLE == + static_cast( + ::android::hardware::radio::V1_0::SapStatus::CARD_NOT_ACCESSIBLE)); +static_assert(aidl::android::hardware::radio::SapStatus::CARD_REMOVED == + static_cast( + ::android::hardware::radio::V1_0::SapStatus::CARD_REMOVED)); +static_assert(aidl::android::hardware::radio::SapStatus::CARD_INSERTED == + static_cast( + ::android::hardware::radio::V1_0::SapStatus::CARD_INSERTED)); +static_assert(aidl::android::hardware::radio::SapStatus::RECOVERED == + static_cast( + ::android::hardware::radio::V1_0::SapStatus::RECOVERED)); + +static_assert(aidl::android::hardware::radio::SapTransferProtocol::T0 == + static_cast( + ::android::hardware::radio::V1_0::SapTransferProtocol::T0)); +static_assert(aidl::android::hardware::radio::SapTransferProtocol::T1 == + static_cast( + ::android::hardware::radio::V1_0::SapTransferProtocol::T1)); + +static_assert(aidl::android::hardware::radio::CallState::ACTIVE == + static_cast( + ::android::hardware::radio::V1_0::CallState::ACTIVE)); +static_assert(aidl::android::hardware::radio::CallState::HOLDING == + static_cast( + ::android::hardware::radio::V1_0::CallState::HOLDING)); +static_assert(aidl::android::hardware::radio::CallState::DIALING == + static_cast( + ::android::hardware::radio::V1_0::CallState::DIALING)); +static_assert(aidl::android::hardware::radio::CallState::ALERTING == + static_cast( + ::android::hardware::radio::V1_0::CallState::ALERTING)); +static_assert(aidl::android::hardware::radio::CallState::INCOMING == + static_cast( + ::android::hardware::radio::V1_0::CallState::INCOMING)); +static_assert(aidl::android::hardware::radio::CallState::WAITING == + static_cast( + ::android::hardware::radio::V1_0::CallState::WAITING)); + +static_assert(aidl::android::hardware::radio::UusType::TYPE1_IMPLICIT == + static_cast( + ::android::hardware::radio::V1_0::UusType::TYPE1_IMPLICIT)); +static_assert(aidl::android::hardware::radio::UusType::TYPE1_REQUIRED == + static_cast( + ::android::hardware::radio::V1_0::UusType::TYPE1_REQUIRED)); +static_assert(aidl::android::hardware::radio::UusType::TYPE1_NOT_REQUIRED == + static_cast( + ::android::hardware::radio::V1_0::UusType::TYPE1_NOT_REQUIRED)); +static_assert(aidl::android::hardware::radio::UusType::TYPE2_REQUIRED == + static_cast( + ::android::hardware::radio::V1_0::UusType::TYPE2_REQUIRED)); +static_assert(aidl::android::hardware::radio::UusType::TYPE2_NOT_REQUIRED == + static_cast( + ::android::hardware::radio::V1_0::UusType::TYPE2_NOT_REQUIRED)); +static_assert(aidl::android::hardware::radio::UusType::TYPE3_REQUIRED == + static_cast( + ::android::hardware::radio::V1_0::UusType::TYPE3_REQUIRED)); +static_assert(aidl::android::hardware::radio::UusType::TYPE3_NOT_REQUIRED == + static_cast( + ::android::hardware::radio::V1_0::UusType::TYPE3_NOT_REQUIRED)); + +static_assert(aidl::android::hardware::radio::UusDcs::USP == + static_cast( + ::android::hardware::radio::V1_0::UusDcs::USP)); +static_assert(aidl::android::hardware::radio::UusDcs::OSIHLP == + static_cast( + ::android::hardware::radio::V1_0::UusDcs::OSIHLP)); +static_assert(aidl::android::hardware::radio::UusDcs::X244 == + static_cast( + ::android::hardware::radio::V1_0::UusDcs::X244)); +static_assert(aidl::android::hardware::radio::UusDcs::RMCF == + static_cast( + ::android::hardware::radio::V1_0::UusDcs::RMCF)); +static_assert(aidl::android::hardware::radio::UusDcs::IA5C == + static_cast( + ::android::hardware::radio::V1_0::UusDcs::IA5C)); + +static_assert(aidl::android::hardware::radio::CallPresentation::ALLOWED == + static_cast( + ::android::hardware::radio::V1_0::CallPresentation::ALLOWED)); +static_assert(aidl::android::hardware::radio::CallPresentation::RESTRICTED == + static_cast( + ::android::hardware::radio::V1_0::CallPresentation::RESTRICTED)); +static_assert(aidl::android::hardware::radio::CallPresentation::UNKNOWN == + static_cast( + ::android::hardware::radio::V1_0::CallPresentation::UNKNOWN)); +static_assert(aidl::android::hardware::radio::CallPresentation::PAYPHONE == + static_cast( + ::android::hardware::radio::V1_0::CallPresentation::PAYPHONE)); + +static_assert(aidl::android::hardware::radio::Clir::DEFAULT == + static_cast( + ::android::hardware::radio::V1_0::Clir::DEFAULT)); +static_assert(aidl::android::hardware::radio::Clir::INVOCATION == + static_cast( + ::android::hardware::radio::V1_0::Clir::INVOCATION)); +static_assert(aidl::android::hardware::radio::Clir::SUPPRESSION == + static_cast( + ::android::hardware::radio::V1_0::Clir::SUPPRESSION)); + +static_assert(aidl::android::hardware::radio::LastCallFailCause::UNOBTAINABLE_NUMBER == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::UNOBTAINABLE_NUMBER)); +static_assert( + aidl::android::hardware::radio::LastCallFailCause::NO_ROUTE_TO_DESTINATION == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::NO_ROUTE_TO_DESTINATION)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::CHANNEL_UNACCEPTABLE == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::CHANNEL_UNACCEPTABLE)); +static_assert( + aidl::android::hardware::radio::LastCallFailCause::OPERATOR_DETERMINED_BARRING == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::OPERATOR_DETERMINED_BARRING)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::NORMAL == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::NORMAL)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::BUSY == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::BUSY)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::NO_USER_RESPONDING == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::NO_USER_RESPONDING)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::NO_ANSWER_FROM_USER == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::NO_ANSWER_FROM_USER)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::CALL_REJECTED == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::CALL_REJECTED)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::NUMBER_CHANGED == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::NUMBER_CHANGED)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::PREEMPTION == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::PREEMPTION)); +static_assert( + aidl::android::hardware::radio::LastCallFailCause::DESTINATION_OUT_OF_ORDER == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::DESTINATION_OUT_OF_ORDER)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::INVALID_NUMBER_FORMAT == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::INVALID_NUMBER_FORMAT)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::FACILITY_REJECTED == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::FACILITY_REJECTED)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::RESP_TO_STATUS_ENQUIRY == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::RESP_TO_STATUS_ENQUIRY)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::NORMAL_UNSPECIFIED == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::NORMAL_UNSPECIFIED)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::CONGESTION == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::CONGESTION)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::NETWORK_OUT_OF_ORDER == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::NETWORK_OUT_OF_ORDER)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::TEMPORARY_FAILURE == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::TEMPORARY_FAILURE)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::SWITCHING_EQUIPMENT_CONGESTION == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause:: + SWITCHING_EQUIPMENT_CONGESTION)); +static_assert( + aidl::android::hardware::radio::LastCallFailCause::ACCESS_INFORMATION_DISCARDED == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::ACCESS_INFORMATION_DISCARDED)); +static_assert(aidl::android::hardware::radio::LastCallFailCause:: + REQUESTED_CIRCUIT_OR_CHANNEL_NOT_AVAILABLE == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause:: + REQUESTED_CIRCUIT_OR_CHANNEL_NOT_AVAILABLE)); +static_assert( + aidl::android::hardware::radio::LastCallFailCause::RESOURCES_UNAVAILABLE_OR_UNSPECIFIED == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause:: + RESOURCES_UNAVAILABLE_OR_UNSPECIFIED)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::QOS_UNAVAILABLE == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::QOS_UNAVAILABLE)); +static_assert( + aidl::android::hardware::radio::LastCallFailCause::REQUESTED_FACILITY_NOT_SUBSCRIBED == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause:: + REQUESTED_FACILITY_NOT_SUBSCRIBED)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::INCOMING_CALLS_BARRED_WITHIN_CUG == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause:: + INCOMING_CALLS_BARRED_WITHIN_CUG)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::BEARER_CAPABILITY_NOT_AUTHORIZED == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause:: + BEARER_CAPABILITY_NOT_AUTHORIZED)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::BEARER_CAPABILITY_UNAVAILABLE == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause:: + BEARER_CAPABILITY_UNAVAILABLE)); +static_assert( + aidl::android::hardware::radio::LastCallFailCause::SERVICE_OPTION_NOT_AVAILABLE == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::SERVICE_OPTION_NOT_AVAILABLE)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::BEARER_SERVICE_NOT_IMPLEMENTED == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause:: + BEARER_SERVICE_NOT_IMPLEMENTED)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::ACM_LIMIT_EXCEEDED == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::ACM_LIMIT_EXCEEDED)); +static_assert( + aidl::android::hardware::radio::LastCallFailCause::REQUESTED_FACILITY_NOT_IMPLEMENTED == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause:: + REQUESTED_FACILITY_NOT_IMPLEMENTED)); +static_assert(aidl::android::hardware::radio::LastCallFailCause:: + ONLY_DIGITAL_INFORMATION_BEARER_AVAILABLE == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause:: + ONLY_DIGITAL_INFORMATION_BEARER_AVAILABLE)); +static_assert( + aidl::android::hardware::radio::LastCallFailCause::SERVICE_OR_OPTION_NOT_IMPLEMENTED == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause:: + SERVICE_OR_OPTION_NOT_IMPLEMENTED)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::INVALID_TRANSACTION_IDENTIFIER == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause:: + INVALID_TRANSACTION_IDENTIFIER)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::USER_NOT_MEMBER_OF_CUG == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::USER_NOT_MEMBER_OF_CUG)); +static_assert( + aidl::android::hardware::radio::LastCallFailCause::INCOMPATIBLE_DESTINATION == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::INCOMPATIBLE_DESTINATION)); +static_assert( + aidl::android::hardware::radio::LastCallFailCause::INVALID_TRANSIT_NW_SELECTION == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::INVALID_TRANSIT_NW_SELECTION)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::SEMANTICALLY_INCORRECT_MESSAGE == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause:: + SEMANTICALLY_INCORRECT_MESSAGE)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::INVALID_MANDATORY_INFORMATION == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause:: + INVALID_MANDATORY_INFORMATION)); +static_assert( + aidl::android::hardware::radio::LastCallFailCause::MESSAGE_TYPE_NON_IMPLEMENTED == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::MESSAGE_TYPE_NON_IMPLEMENTED)); +static_assert(aidl::android::hardware::radio::LastCallFailCause:: + MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause:: + MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::INFORMATION_ELEMENT_NON_EXISTENT == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause:: + INFORMATION_ELEMENT_NON_EXISTENT)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::CONDITIONAL_IE_ERROR == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::CONDITIONAL_IE_ERROR)); +static_assert(aidl::android::hardware::radio::LastCallFailCause:: + MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause:: + MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE)); +static_assert( + aidl::android::hardware::radio::LastCallFailCause::RECOVERY_ON_TIMER_EXPIRED == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::RECOVERY_ON_TIMER_EXPIRED)); +static_assert( + aidl::android::hardware::radio::LastCallFailCause::PROTOCOL_ERROR_UNSPECIFIED == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::PROTOCOL_ERROR_UNSPECIFIED)); +static_assert( + aidl::android::hardware::radio::LastCallFailCause::INTERWORKING_UNSPECIFIED == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::INTERWORKING_UNSPECIFIED)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::CALL_BARRED == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::CALL_BARRED)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::FDN_BLOCKED == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::FDN_BLOCKED)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::IMSI_UNKNOWN_IN_VLR == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::IMSI_UNKNOWN_IN_VLR)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::IMEI_NOT_ACCEPTED == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::IMEI_NOT_ACCEPTED)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::DIAL_MODIFIED_TO_USSD == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::DIAL_MODIFIED_TO_USSD)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::DIAL_MODIFIED_TO_SS == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::DIAL_MODIFIED_TO_SS)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::DIAL_MODIFIED_TO_DIAL == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::DIAL_MODIFIED_TO_DIAL)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::RADIO_OFF == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::RADIO_OFF)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::OUT_OF_SERVICE == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::OUT_OF_SERVICE)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::NO_VALID_SIM == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::NO_VALID_SIM)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::RADIO_INTERNAL_ERROR == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::RADIO_INTERNAL_ERROR)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::NETWORK_RESP_TIMEOUT == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::NETWORK_RESP_TIMEOUT)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::NETWORK_REJECT == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::NETWORK_REJECT)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::RADIO_ACCESS_FAILURE == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::RADIO_ACCESS_FAILURE)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::RADIO_LINK_FAILURE == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::RADIO_LINK_FAILURE)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::RADIO_LINK_LOST == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::RADIO_LINK_LOST)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::RADIO_UPLINK_FAILURE == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::RADIO_UPLINK_FAILURE)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::RADIO_SETUP_FAILURE == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::RADIO_SETUP_FAILURE)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::RADIO_RELEASE_NORMAL == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::RADIO_RELEASE_NORMAL)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::RADIO_RELEASE_ABNORMAL == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::RADIO_RELEASE_ABNORMAL)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::ACCESS_CLASS_BLOCKED == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::ACCESS_CLASS_BLOCKED)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::NETWORK_DETACH == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::NETWORK_DETACH)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::CDMA_LOCKED_UNTIL_POWER_CYCLE == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause:: + CDMA_LOCKED_UNTIL_POWER_CYCLE)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::CDMA_DROP == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::CDMA_DROP)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::CDMA_INTERCEPT == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::CDMA_INTERCEPT)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::CDMA_REORDER == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::CDMA_REORDER)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::CDMA_SO_REJECT == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::CDMA_SO_REJECT)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::CDMA_RETRY_ORDER == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::CDMA_RETRY_ORDER)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::CDMA_ACCESS_FAILURE == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::CDMA_ACCESS_FAILURE)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::CDMA_PREEMPTED == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::CDMA_PREEMPTED)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::CDMA_NOT_EMERGENCY == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::CDMA_NOT_EMERGENCY)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::CDMA_ACCESS_BLOCKED == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::CDMA_ACCESS_BLOCKED)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::OEM_CAUSE_1 == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::OEM_CAUSE_1)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::OEM_CAUSE_2 == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::OEM_CAUSE_2)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::OEM_CAUSE_3 == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::OEM_CAUSE_3)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::OEM_CAUSE_4 == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::OEM_CAUSE_4)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::OEM_CAUSE_5 == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::OEM_CAUSE_5)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::OEM_CAUSE_6 == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::OEM_CAUSE_6)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::OEM_CAUSE_7 == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::OEM_CAUSE_7)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::OEM_CAUSE_8 == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::OEM_CAUSE_8)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::OEM_CAUSE_9 == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::OEM_CAUSE_9)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::OEM_CAUSE_10 == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::OEM_CAUSE_10)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::OEM_CAUSE_11 == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::OEM_CAUSE_11)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::OEM_CAUSE_12 == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::OEM_CAUSE_12)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::OEM_CAUSE_13 == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::OEM_CAUSE_13)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::OEM_CAUSE_14 == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::OEM_CAUSE_14)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::OEM_CAUSE_15 == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::OEM_CAUSE_15)); +static_assert(aidl::android::hardware::radio::LastCallFailCause::ERROR_UNSPECIFIED == + static_cast( + ::android::hardware::radio::V1_0::LastCallFailCause::ERROR_UNSPECIFIED)); + +static_assert(aidl::android::hardware::radio::HardwareConfigType::MODEM == + static_cast( + ::android::hardware::radio::V1_0::HardwareConfigType::MODEM)); +static_assert(aidl::android::hardware::radio::HardwareConfigType::SIM == + static_cast( + ::android::hardware::radio::V1_0::HardwareConfigType::SIM)); + +static_assert(aidl::android::hardware::radio::RegState::NOT_REG_MT_NOT_SEARCHING_OP == + static_cast( + ::android::hardware::radio::V1_0::RegState::NOT_REG_MT_NOT_SEARCHING_OP)); +static_assert(aidl::android::hardware::radio::RegState::REG_HOME == + static_cast( + ::android::hardware::radio::V1_0::RegState::REG_HOME)); +static_assert(aidl::android::hardware::radio::RegState::NOT_REG_MT_SEARCHING_OP == + static_cast( + ::android::hardware::radio::V1_0::RegState::NOT_REG_MT_SEARCHING_OP)); +static_assert(aidl::android::hardware::radio::RegState::REG_DENIED == + static_cast( + ::android::hardware::radio::V1_0::RegState::REG_DENIED)); +static_assert(aidl::android::hardware::radio::RegState::UNKNOWN == + static_cast( + ::android::hardware::radio::V1_0::RegState::UNKNOWN)); +static_assert(aidl::android::hardware::radio::RegState::REG_ROAMING == + static_cast( + ::android::hardware::radio::V1_0::RegState::REG_ROAMING)); +static_assert(aidl::android::hardware::radio::RegState::NOT_REG_MT_NOT_SEARCHING_OP_EM == + static_cast( + ::android::hardware::radio::V1_0::RegState::NOT_REG_MT_NOT_SEARCHING_OP_EM)); +static_assert(aidl::android::hardware::radio::RegState::NOT_REG_MT_SEARCHING_OP_EM == + static_cast( + ::android::hardware::radio::V1_0::RegState::NOT_REG_MT_SEARCHING_OP_EM)); +static_assert(aidl::android::hardware::radio::RegState::REG_DENIED_EM == + static_cast( + ::android::hardware::radio::V1_0::RegState::REG_DENIED_EM)); +static_assert(aidl::android::hardware::radio::RegState::UNKNOWN_EM == + static_cast( + ::android::hardware::radio::V1_0::RegState::UNKNOWN_EM)); + +static_assert(aidl::android::hardware::radio::DataProfileId::DEFAULT == + static_cast( + ::android::hardware::radio::V1_0::DataProfileId::DEFAULT)); +static_assert(aidl::android::hardware::radio::DataProfileId::TETHERED == + static_cast( + ::android::hardware::radio::V1_0::DataProfileId::TETHERED)); +static_assert(aidl::android::hardware::radio::DataProfileId::IMS == + static_cast( + ::android::hardware::radio::V1_0::DataProfileId::IMS)); +static_assert(aidl::android::hardware::radio::DataProfileId::FOTA == + static_cast( + ::android::hardware::radio::V1_0::DataProfileId::FOTA)); +static_assert(aidl::android::hardware::radio::DataProfileId::CBS == + static_cast( + ::android::hardware::radio::V1_0::DataProfileId::CBS)); +static_assert(aidl::android::hardware::radio::DataProfileId::OEM_BASE == + static_cast( + ::android::hardware::radio::V1_0::DataProfileId::OEM_BASE)); +static_assert(aidl::android::hardware::radio::DataProfileId::INVALID == + static_cast( + ::android::hardware::radio::V1_0::DataProfileId::INVALID)); + +static_assert(aidl::android::hardware::radio::SmsAcknowledgeFailCause::MEMORY_CAPACITY_EXCEEDED == + static_cast( + ::android::hardware::radio::V1_0::SmsAcknowledgeFailCause:: + MEMORY_CAPACITY_EXCEEDED)); +static_assert( + aidl::android::hardware::radio::SmsAcknowledgeFailCause::UNSPECIFIED_ERROR == + static_cast( + ::android::hardware::radio::V1_0::SmsAcknowledgeFailCause::UNSPECIFIED_ERROR)); + +static_assert(aidl::android::hardware::radio::CallForwardInfoStatus::DISABLE == + static_cast( + ::android::hardware::radio::V1_0::CallForwardInfoStatus::DISABLE)); +static_assert(aidl::android::hardware::radio::CallForwardInfoStatus::ENABLE == + static_cast( + ::android::hardware::radio::V1_0::CallForwardInfoStatus::ENABLE)); +static_assert(aidl::android::hardware::radio::CallForwardInfoStatus::INTERROGATE == + static_cast( + ::android::hardware::radio::V1_0::CallForwardInfoStatus::INTERROGATE)); +static_assert(aidl::android::hardware::radio::CallForwardInfoStatus::REGISTRATION == + static_cast( + ::android::hardware::radio::V1_0::CallForwardInfoStatus::REGISTRATION)); +static_assert(aidl::android::hardware::radio::CallForwardInfoStatus::ERASURE == + static_cast( + ::android::hardware::radio::V1_0::CallForwardInfoStatus::ERASURE)); + +static_assert(aidl::android::hardware::radio::ClipStatus::CLIP_PROVISIONED == + static_cast( + ::android::hardware::radio::V1_0::ClipStatus::CLIP_PROVISIONED)); +static_assert(aidl::android::hardware::radio::ClipStatus::CLIP_UNPROVISIONED == + static_cast( + ::android::hardware::radio::V1_0::ClipStatus::CLIP_UNPROVISIONED)); +static_assert(aidl::android::hardware::radio::ClipStatus::UNKNOWN == + static_cast( + ::android::hardware::radio::V1_0::ClipStatus::UNKNOWN)); + +static_assert(aidl::android::hardware::radio::SmsWriteArgsStatus::REC_UNREAD == + static_cast( + ::android::hardware::radio::V1_0::SmsWriteArgsStatus::REC_UNREAD)); +static_assert(aidl::android::hardware::radio::SmsWriteArgsStatus::REC_READ == + static_cast( + ::android::hardware::radio::V1_0::SmsWriteArgsStatus::REC_READ)); +static_assert(aidl::android::hardware::radio::SmsWriteArgsStatus::STO_UNSENT == + static_cast( + ::android::hardware::radio::V1_0::SmsWriteArgsStatus::STO_UNSENT)); +static_assert(aidl::android::hardware::radio::SmsWriteArgsStatus::STO_SENT == + static_cast( + ::android::hardware::radio::V1_0::SmsWriteArgsStatus::STO_SENT)); + +static_assert(aidl::android::hardware::radio::RadioBandMode::BAND_MODE_UNSPECIFIED == + static_cast( + ::android::hardware::radio::V1_0::RadioBandMode::BAND_MODE_UNSPECIFIED)); +static_assert(aidl::android::hardware::radio::RadioBandMode::BAND_MODE_EURO == + static_cast( + ::android::hardware::radio::V1_0::RadioBandMode::BAND_MODE_EURO)); +static_assert(aidl::android::hardware::radio::RadioBandMode::BAND_MODE_USA == + static_cast( + ::android::hardware::radio::V1_0::RadioBandMode::BAND_MODE_USA)); +static_assert(aidl::android::hardware::radio::RadioBandMode::BAND_MODE_JPN == + static_cast( + ::android::hardware::radio::V1_0::RadioBandMode::BAND_MODE_JPN)); +static_assert(aidl::android::hardware::radio::RadioBandMode::BAND_MODE_AUS == + static_cast( + ::android::hardware::radio::V1_0::RadioBandMode::BAND_MODE_AUS)); +static_assert(aidl::android::hardware::radio::RadioBandMode::BAND_MODE_AUS_2 == + static_cast( + ::android::hardware::radio::V1_0::RadioBandMode::BAND_MODE_AUS_2)); +static_assert(aidl::android::hardware::radio::RadioBandMode::BAND_MODE_CELL_800 == + static_cast( + ::android::hardware::radio::V1_0::RadioBandMode::BAND_MODE_CELL_800)); +static_assert(aidl::android::hardware::radio::RadioBandMode::BAND_MODE_PCS == + static_cast( + ::android::hardware::radio::V1_0::RadioBandMode::BAND_MODE_PCS)); +static_assert(aidl::android::hardware::radio::RadioBandMode::BAND_MODE_JTACS == + static_cast( + ::android::hardware::radio::V1_0::RadioBandMode::BAND_MODE_JTACS)); +static_assert(aidl::android::hardware::radio::RadioBandMode::BAND_MODE_KOREA_PCS == + static_cast( + ::android::hardware::radio::V1_0::RadioBandMode::BAND_MODE_KOREA_PCS)); +static_assert(aidl::android::hardware::radio::RadioBandMode::BAND_MODE_5_450M == + static_cast( + ::android::hardware::radio::V1_0::RadioBandMode::BAND_MODE_5_450M)); +static_assert(aidl::android::hardware::radio::RadioBandMode::BAND_MODE_IMT2000 == + static_cast( + ::android::hardware::radio::V1_0::RadioBandMode::BAND_MODE_IMT2000)); +static_assert(aidl::android::hardware::radio::RadioBandMode::BAND_MODE_7_700M_2 == + static_cast( + ::android::hardware::radio::V1_0::RadioBandMode::BAND_MODE_7_700M_2)); +static_assert(aidl::android::hardware::radio::RadioBandMode::BAND_MODE_8_1800M == + static_cast( + ::android::hardware::radio::V1_0::RadioBandMode::BAND_MODE_8_1800M)); +static_assert(aidl::android::hardware::radio::RadioBandMode::BAND_MODE_9_900M == + static_cast( + ::android::hardware::radio::V1_0::RadioBandMode::BAND_MODE_9_900M)); +static_assert(aidl::android::hardware::radio::RadioBandMode::BAND_MODE_10_800M_2 == + static_cast( + ::android::hardware::radio::V1_0::RadioBandMode::BAND_MODE_10_800M_2)); +static_assert(aidl::android::hardware::radio::RadioBandMode::BAND_MODE_EURO_PAMR_400M == + static_cast( + ::android::hardware::radio::V1_0::RadioBandMode::BAND_MODE_EURO_PAMR_400M)); +static_assert(aidl::android::hardware::radio::RadioBandMode::BAND_MODE_AWS == + static_cast( + ::android::hardware::radio::V1_0::RadioBandMode::BAND_MODE_AWS)); +static_assert(aidl::android::hardware::radio::RadioBandMode::BAND_MODE_USA_2500M == + static_cast( + ::android::hardware::radio::V1_0::RadioBandMode::BAND_MODE_USA_2500M)); + +static_assert(aidl::android::hardware::radio::OperatorStatus::UNKNOWN == + static_cast( + ::android::hardware::radio::V1_0::OperatorStatus::UNKNOWN)); +static_assert(aidl::android::hardware::radio::OperatorStatus::AVAILABLE == + static_cast( + ::android::hardware::radio::V1_0::OperatorStatus::AVAILABLE)); +static_assert(aidl::android::hardware::radio::OperatorStatus::CURRENT == + static_cast( + ::android::hardware::radio::V1_0::OperatorStatus::CURRENT)); +static_assert(aidl::android::hardware::radio::OperatorStatus::FORBIDDEN == + static_cast( + ::android::hardware::radio::V1_0::OperatorStatus::FORBIDDEN)); + +static_assert(aidl::android::hardware::radio::PreferredNetworkType::GSM_WCDMA == + static_cast( + ::android::hardware::radio::V1_0::PreferredNetworkType::GSM_WCDMA)); +static_assert(aidl::android::hardware::radio::PreferredNetworkType::GSM_ONLY == + static_cast( + ::android::hardware::radio::V1_0::PreferredNetworkType::GSM_ONLY)); +static_assert(aidl::android::hardware::radio::PreferredNetworkType::WCDMA == + static_cast( + ::android::hardware::radio::V1_0::PreferredNetworkType::WCDMA)); +static_assert(aidl::android::hardware::radio::PreferredNetworkType::GSM_WCDMA_AUTO == + static_cast( + ::android::hardware::radio::V1_0::PreferredNetworkType::GSM_WCDMA_AUTO)); +static_assert(aidl::android::hardware::radio::PreferredNetworkType::CDMA_EVDO_AUTO == + static_cast( + ::android::hardware::radio::V1_0::PreferredNetworkType::CDMA_EVDO_AUTO)); +static_assert(aidl::android::hardware::radio::PreferredNetworkType::CDMA_ONLY == + static_cast( + ::android::hardware::radio::V1_0::PreferredNetworkType::CDMA_ONLY)); +static_assert(aidl::android::hardware::radio::PreferredNetworkType::EVDO_ONLY == + static_cast( + ::android::hardware::radio::V1_0::PreferredNetworkType::EVDO_ONLY)); +static_assert( + aidl::android::hardware::radio::PreferredNetworkType::GSM_WCDMA_CDMA_EVDO_AUTO == + static_cast( + ::android::hardware::radio::V1_0::PreferredNetworkType::GSM_WCDMA_CDMA_EVDO_AUTO)); +static_assert(aidl::android::hardware::radio::PreferredNetworkType::LTE_CDMA_EVDO == + static_cast( + ::android::hardware::radio::V1_0::PreferredNetworkType::LTE_CDMA_EVDO)); +static_assert(aidl::android::hardware::radio::PreferredNetworkType::LTE_GSM_WCDMA == + static_cast( + ::android::hardware::radio::V1_0::PreferredNetworkType::LTE_GSM_WCDMA)); +static_assert( + aidl::android::hardware::radio::PreferredNetworkType::LTE_CMDA_EVDO_GSM_WCDMA == + static_cast( + ::android::hardware::radio::V1_0::PreferredNetworkType::LTE_CMDA_EVDO_GSM_WCDMA)); +static_assert(aidl::android::hardware::radio::PreferredNetworkType::LTE_ONLY == + static_cast( + ::android::hardware::radio::V1_0::PreferredNetworkType::LTE_ONLY)); +static_assert(aidl::android::hardware::radio::PreferredNetworkType::LTE_WCDMA == + static_cast( + ::android::hardware::radio::V1_0::PreferredNetworkType::LTE_WCDMA)); +static_assert(aidl::android::hardware::radio::PreferredNetworkType::TD_SCDMA_ONLY == + static_cast( + ::android::hardware::radio::V1_0::PreferredNetworkType::TD_SCDMA_ONLY)); +static_assert(aidl::android::hardware::radio::PreferredNetworkType::TD_SCDMA_WCDMA == + static_cast( + ::android::hardware::radio::V1_0::PreferredNetworkType::TD_SCDMA_WCDMA)); +static_assert(aidl::android::hardware::radio::PreferredNetworkType::TD_SCDMA_LTE == + static_cast( + ::android::hardware::radio::V1_0::PreferredNetworkType::TD_SCDMA_LTE)); +static_assert(aidl::android::hardware::radio::PreferredNetworkType::TD_SCDMA_GSM == + static_cast( + ::android::hardware::radio::V1_0::PreferredNetworkType::TD_SCDMA_GSM)); +static_assert(aidl::android::hardware::radio::PreferredNetworkType::TD_SCDMA_GSM_LTE == + static_cast( + ::android::hardware::radio::V1_0::PreferredNetworkType::TD_SCDMA_GSM_LTE)); +static_assert(aidl::android::hardware::radio::PreferredNetworkType::TD_SCDMA_GSM_WCDMA == + static_cast( + ::android::hardware::radio::V1_0::PreferredNetworkType::TD_SCDMA_GSM_WCDMA)); +static_assert(aidl::android::hardware::radio::PreferredNetworkType::TD_SCDMA_WCDMA_LTE == + static_cast( + ::android::hardware::radio::V1_0::PreferredNetworkType::TD_SCDMA_WCDMA_LTE)); +static_assert( + aidl::android::hardware::radio::PreferredNetworkType::TD_SCDMA_GSM_WCDMA_LTE == + static_cast( + ::android::hardware::radio::V1_0::PreferredNetworkType::TD_SCDMA_GSM_WCDMA_LTE)); +static_assert( + aidl::android::hardware::radio::PreferredNetworkType::TD_SCDMA_GSM_WCDMA_CDMA_EVDO_AUTO == + static_cast( + ::android::hardware::radio::V1_0::PreferredNetworkType:: + TD_SCDMA_GSM_WCDMA_CDMA_EVDO_AUTO)); +static_assert( + aidl::android::hardware::radio::PreferredNetworkType::TD_SCDMA_LTE_CDMA_EVDO_GSM_WCDMA == + static_cast( + ::android::hardware::radio::V1_0::PreferredNetworkType:: + TD_SCDMA_LTE_CDMA_EVDO_GSM_WCDMA)); + +static_assert(aidl::android::hardware::radio::CdmaSubscriptionSource::RUIM_SIM == + static_cast( + ::android::hardware::radio::V1_0::CdmaSubscriptionSource::RUIM_SIM)); +static_assert(aidl::android::hardware::radio::CdmaSubscriptionSource::NV == + static_cast( + ::android::hardware::radio::V1_0::CdmaSubscriptionSource::NV)); + +static_assert(aidl::android::hardware::radio::CdmaRoamingType::HOME_NETWORK == + static_cast( + ::android::hardware::radio::V1_0::CdmaRoamingType::HOME_NETWORK)); +static_assert(aidl::android::hardware::radio::CdmaRoamingType::AFFILIATED_ROAM == + static_cast( + ::android::hardware::radio::V1_0::CdmaRoamingType::AFFILIATED_ROAM)); +static_assert(aidl::android::hardware::radio::CdmaRoamingType::ANY_ROAM == + static_cast( + ::android::hardware::radio::V1_0::CdmaRoamingType::ANY_ROAM)); + +static_assert(aidl::android::hardware::radio::TtyMode::OFF == + static_cast( + ::android::hardware::radio::V1_0::TtyMode::OFF)); +static_assert(aidl::android::hardware::radio::TtyMode::FULL == + static_cast( + ::android::hardware::radio::V1_0::TtyMode::FULL)); +static_assert(aidl::android::hardware::radio::TtyMode::HCO == + static_cast( + ::android::hardware::radio::V1_0::TtyMode::HCO)); +static_assert(aidl::android::hardware::radio::TtyMode::VCO == + static_cast( + ::android::hardware::radio::V1_0::TtyMode::VCO)); + +static_assert(aidl::android::hardware::radio::NvItem::CDMA_MEID == + static_cast( + ::android::hardware::radio::V1_0::NvItem::CDMA_MEID)); +static_assert(aidl::android::hardware::radio::NvItem::CDMA_MIN == + static_cast( + ::android::hardware::radio::V1_0::NvItem::CDMA_MIN)); +static_assert(aidl::android::hardware::radio::NvItem::CDMA_MDN == + static_cast( + ::android::hardware::radio::V1_0::NvItem::CDMA_MDN)); +static_assert(aidl::android::hardware::radio::NvItem::CDMA_ACCOLC == + static_cast( + ::android::hardware::radio::V1_0::NvItem::CDMA_ACCOLC)); +static_assert(aidl::android::hardware::radio::NvItem::DEVICE_MSL == + static_cast( + ::android::hardware::radio::V1_0::NvItem::DEVICE_MSL)); +static_assert(aidl::android::hardware::radio::NvItem::RTN_RECONDITIONED_STATUS == + static_cast( + ::android::hardware::radio::V1_0::NvItem::RTN_RECONDITIONED_STATUS)); +static_assert(aidl::android::hardware::radio::NvItem::RTN_ACTIVATION_DATE == + static_cast( + ::android::hardware::radio::V1_0::NvItem::RTN_ACTIVATION_DATE)); +static_assert(aidl::android::hardware::radio::NvItem::RTN_LIFE_TIMER == + static_cast( + ::android::hardware::radio::V1_0::NvItem::RTN_LIFE_TIMER)); +static_assert(aidl::android::hardware::radio::NvItem::RTN_LIFE_CALLS == + static_cast( + ::android::hardware::radio::V1_0::NvItem::RTN_LIFE_CALLS)); +static_assert(aidl::android::hardware::radio::NvItem::RTN_LIFE_DATA_TX == + static_cast( + ::android::hardware::radio::V1_0::NvItem::RTN_LIFE_DATA_TX)); +static_assert(aidl::android::hardware::radio::NvItem::RTN_LIFE_DATA_RX == + static_cast( + ::android::hardware::radio::V1_0::NvItem::RTN_LIFE_DATA_RX)); +static_assert(aidl::android::hardware::radio::NvItem::OMADM_HFA_LEVEL == + static_cast( + ::android::hardware::radio::V1_0::NvItem::OMADM_HFA_LEVEL)); +static_assert(aidl::android::hardware::radio::NvItem::MIP_PROFILE_NAI == + static_cast( + ::android::hardware::radio::V1_0::NvItem::MIP_PROFILE_NAI)); +static_assert(aidl::android::hardware::radio::NvItem::MIP_PROFILE_HOME_ADDRESS == + static_cast( + ::android::hardware::radio::V1_0::NvItem::MIP_PROFILE_HOME_ADDRESS)); +static_assert(aidl::android::hardware::radio::NvItem::MIP_PROFILE_AAA_AUTH == + static_cast( + ::android::hardware::radio::V1_0::NvItem::MIP_PROFILE_AAA_AUTH)); +static_assert(aidl::android::hardware::radio::NvItem::MIP_PROFILE_HA_AUTH == + static_cast( + ::android::hardware::radio::V1_0::NvItem::MIP_PROFILE_HA_AUTH)); +static_assert(aidl::android::hardware::radio::NvItem::MIP_PROFILE_PRI_HA_ADDR == + static_cast( + ::android::hardware::radio::V1_0::NvItem::MIP_PROFILE_PRI_HA_ADDR)); +static_assert(aidl::android::hardware::radio::NvItem::MIP_PROFILE_SEC_HA_ADDR == + static_cast( + ::android::hardware::radio::V1_0::NvItem::MIP_PROFILE_SEC_HA_ADDR)); +static_assert(aidl::android::hardware::radio::NvItem::MIP_PROFILE_REV_TUN_PREF == + static_cast( + ::android::hardware::radio::V1_0::NvItem::MIP_PROFILE_REV_TUN_PREF)); +static_assert(aidl::android::hardware::radio::NvItem::MIP_PROFILE_HA_SPI == + static_cast( + ::android::hardware::radio::V1_0::NvItem::MIP_PROFILE_HA_SPI)); +static_assert(aidl::android::hardware::radio::NvItem::MIP_PROFILE_AAA_SPI == + static_cast( + ::android::hardware::radio::V1_0::NvItem::MIP_PROFILE_AAA_SPI)); +static_assert(aidl::android::hardware::radio::NvItem::MIP_PROFILE_MN_HA_SS == + static_cast( + ::android::hardware::radio::V1_0::NvItem::MIP_PROFILE_MN_HA_SS)); +static_assert(aidl::android::hardware::radio::NvItem::MIP_PROFILE_MN_AAA_SS == + static_cast( + ::android::hardware::radio::V1_0::NvItem::MIP_PROFILE_MN_AAA_SS)); +static_assert(aidl::android::hardware::radio::NvItem::CDMA_PRL_VERSION == + static_cast( + ::android::hardware::radio::V1_0::NvItem::CDMA_PRL_VERSION)); +static_assert(aidl::android::hardware::radio::NvItem::CDMA_BC10 == + static_cast( + ::android::hardware::radio::V1_0::NvItem::CDMA_BC10)); +static_assert(aidl::android::hardware::radio::NvItem::CDMA_BC14 == + static_cast( + ::android::hardware::radio::V1_0::NvItem::CDMA_BC14)); +static_assert(aidl::android::hardware::radio::NvItem::CDMA_SO68 == + static_cast( + ::android::hardware::radio::V1_0::NvItem::CDMA_SO68)); +static_assert(aidl::android::hardware::radio::NvItem::CDMA_SO73_COP0 == + static_cast( + ::android::hardware::radio::V1_0::NvItem::CDMA_SO73_COP0)); +static_assert(aidl::android::hardware::radio::NvItem::CDMA_SO73_COP1TO7 == + static_cast( + ::android::hardware::radio::V1_0::NvItem::CDMA_SO73_COP1TO7)); +static_assert(aidl::android::hardware::radio::NvItem::CDMA_1X_ADVANCED_ENABLED == + static_cast( + ::android::hardware::radio::V1_0::NvItem::CDMA_1X_ADVANCED_ENABLED)); +static_assert(aidl::android::hardware::radio::NvItem::CDMA_EHRPD_ENABLED == + static_cast( + ::android::hardware::radio::V1_0::NvItem::CDMA_EHRPD_ENABLED)); +static_assert(aidl::android::hardware::radio::NvItem::CDMA_EHRPD_FORCED == + static_cast( + ::android::hardware::radio::V1_0::NvItem::CDMA_EHRPD_FORCED)); +static_assert(aidl::android::hardware::radio::NvItem::LTE_BAND_ENABLE_25 == + static_cast( + ::android::hardware::radio::V1_0::NvItem::LTE_BAND_ENABLE_25)); +static_assert(aidl::android::hardware::radio::NvItem::LTE_BAND_ENABLE_26 == + static_cast( + ::android::hardware::radio::V1_0::NvItem::LTE_BAND_ENABLE_26)); +static_assert(aidl::android::hardware::radio::NvItem::LTE_BAND_ENABLE_41 == + static_cast( + ::android::hardware::radio::V1_0::NvItem::LTE_BAND_ENABLE_41)); +static_assert(aidl::android::hardware::radio::NvItem::LTE_SCAN_PRIORITY_25 == + static_cast( + ::android::hardware::radio::V1_0::NvItem::LTE_SCAN_PRIORITY_25)); +static_assert(aidl::android::hardware::radio::NvItem::LTE_SCAN_PRIORITY_26 == + static_cast( + ::android::hardware::radio::V1_0::NvItem::LTE_SCAN_PRIORITY_26)); +static_assert(aidl::android::hardware::radio::NvItem::LTE_SCAN_PRIORITY_41 == + static_cast( + ::android::hardware::radio::V1_0::NvItem::LTE_SCAN_PRIORITY_41)); +static_assert(aidl::android::hardware::radio::NvItem::LTE_HIDDEN_BAND_PRIORITY_25 == + static_cast( + ::android::hardware::radio::V1_0::NvItem::LTE_HIDDEN_BAND_PRIORITY_25)); +static_assert(aidl::android::hardware::radio::NvItem::LTE_HIDDEN_BAND_PRIORITY_26 == + static_cast( + ::android::hardware::radio::V1_0::NvItem::LTE_HIDDEN_BAND_PRIORITY_26)); +static_assert(aidl::android::hardware::radio::NvItem::LTE_HIDDEN_BAND_PRIORITY_41 == + static_cast( + ::android::hardware::radio::V1_0::NvItem::LTE_HIDDEN_BAND_PRIORITY_41)); + +static_assert(aidl::android::hardware::radio::ResetNvType::RELOAD == + static_cast( + ::android::hardware::radio::V1_0::ResetNvType::RELOAD)); +static_assert(aidl::android::hardware::radio::ResetNvType::ERASE == + static_cast( + ::android::hardware::radio::V1_0::ResetNvType::ERASE)); +static_assert(aidl::android::hardware::radio::ResetNvType::FACTORY_RESET == + static_cast( + ::android::hardware::radio::V1_0::ResetNvType::FACTORY_RESET)); + +static_assert(aidl::android::hardware::radio::HardwareConfigState::ENABLED == + static_cast( + ::android::hardware::radio::V1_0::HardwareConfigState::ENABLED)); +static_assert(aidl::android::hardware::radio::HardwareConfigState::STANDBY == + static_cast( + ::android::hardware::radio::V1_0::HardwareConfigState::STANDBY)); +static_assert(aidl::android::hardware::radio::HardwareConfigState::DISABLED == + static_cast( + ::android::hardware::radio::V1_0::HardwareConfigState::DISABLED)); + +static_assert(aidl::android::hardware::radio::LceStatus::NOT_SUPPORTED == + static_cast( + ::android::hardware::radio::V1_0::LceStatus::NOT_SUPPORTED)); +static_assert(aidl::android::hardware::radio::LceStatus::STOPPED == + static_cast( + ::android::hardware::radio::V1_0::LceStatus::STOPPED)); +static_assert(aidl::android::hardware::radio::LceStatus::ACTIVE == + static_cast( + ::android::hardware::radio::V1_0::LceStatus::ACTIVE)); + +static_assert(aidl::android::hardware::radio::CarrierMatchType::ALL == + static_cast( + ::android::hardware::radio::V1_0::CarrierMatchType::ALL)); +static_assert(aidl::android::hardware::radio::CarrierMatchType::SPN == + static_cast( + ::android::hardware::radio::V1_0::CarrierMatchType::SPN)); +static_assert(aidl::android::hardware::radio::CarrierMatchType::IMSI_PREFIX == + static_cast( + ::android::hardware::radio::V1_0::CarrierMatchType::IMSI_PREFIX)); +static_assert(aidl::android::hardware::radio::CarrierMatchType::GID1 == + static_cast( + ::android::hardware::radio::V1_0::CarrierMatchType::GID1)); +static_assert(aidl::android::hardware::radio::CarrierMatchType::GID2 == + static_cast( + ::android::hardware::radio::V1_0::CarrierMatchType::GID2)); + +static_assert(aidl::android::hardware::radio::CdmaSmsDigitMode::FOUR_BIT == + static_cast( + ::android::hardware::radio::V1_0::CdmaSmsDigitMode::FOUR_BIT)); +static_assert(aidl::android::hardware::radio::CdmaSmsDigitMode::EIGHT_BIT == + static_cast( + ::android::hardware::radio::V1_0::CdmaSmsDigitMode::EIGHT_BIT)); + +static_assert(aidl::android::hardware::radio::CdmaSmsNumberMode::NOT_DATA_NETWORK == + static_cast( + ::android::hardware::radio::V1_0::CdmaSmsNumberMode::NOT_DATA_NETWORK)); +static_assert(aidl::android::hardware::radio::CdmaSmsNumberMode::DATA_NETWORK == + static_cast( + ::android::hardware::radio::V1_0::CdmaSmsNumberMode::DATA_NETWORK)); + +static_assert(aidl::android::hardware::radio::CdmaSmsNumberType::UNKNOWN == + static_cast( + ::android::hardware::radio::V1_0::CdmaSmsNumberType::UNKNOWN)); +static_assert( + aidl::android::hardware::radio::CdmaSmsNumberType::INTERNATIONAL_OR_DATA_IP == + static_cast( + ::android::hardware::radio::V1_0::CdmaSmsNumberType::INTERNATIONAL_OR_DATA_IP)); +static_assert( + aidl::android::hardware::radio::CdmaSmsNumberType::NATIONAL_OR_INTERNET_MAIL == + static_cast( + ::android::hardware::radio::V1_0::CdmaSmsNumberType::NATIONAL_OR_INTERNET_MAIL)); +static_assert(aidl::android::hardware::radio::CdmaSmsNumberType::NETWORK == + static_cast( + ::android::hardware::radio::V1_0::CdmaSmsNumberType::NETWORK)); +static_assert(aidl::android::hardware::radio::CdmaSmsNumberType::SUBSCRIBER == + static_cast( + ::android::hardware::radio::V1_0::CdmaSmsNumberType::SUBSCRIBER)); +static_assert(aidl::android::hardware::radio::CdmaSmsNumberType::ALPHANUMERIC == + static_cast( + ::android::hardware::radio::V1_0::CdmaSmsNumberType::ALPHANUMERIC)); +static_assert(aidl::android::hardware::radio::CdmaSmsNumberType::ABBREVIATED == + static_cast( + ::android::hardware::radio::V1_0::CdmaSmsNumberType::ABBREVIATED)); +static_assert(aidl::android::hardware::radio::CdmaSmsNumberType::RESERVED_7 == + static_cast( + ::android::hardware::radio::V1_0::CdmaSmsNumberType::RESERVED_7)); + +static_assert(aidl::android::hardware::radio::CdmaSmsNumberPlan::UNKNOWN == + static_cast( + ::android::hardware::radio::V1_0::CdmaSmsNumberPlan::UNKNOWN)); +static_assert(aidl::android::hardware::radio::CdmaSmsNumberPlan::TELEPHONY == + static_cast( + ::android::hardware::radio::V1_0::CdmaSmsNumberPlan::TELEPHONY)); +static_assert(aidl::android::hardware::radio::CdmaSmsNumberPlan::RESERVED_2 == + static_cast( + ::android::hardware::radio::V1_0::CdmaSmsNumberPlan::RESERVED_2)); +static_assert(aidl::android::hardware::radio::CdmaSmsNumberPlan::DATA == + static_cast( + ::android::hardware::radio::V1_0::CdmaSmsNumberPlan::DATA)); +static_assert(aidl::android::hardware::radio::CdmaSmsNumberPlan::TELEX == + static_cast( + ::android::hardware::radio::V1_0::CdmaSmsNumberPlan::TELEX)); +static_assert(aidl::android::hardware::radio::CdmaSmsNumberPlan::RESERVED_5 == + static_cast( + ::android::hardware::radio::V1_0::CdmaSmsNumberPlan::RESERVED_5)); +static_assert(aidl::android::hardware::radio::CdmaSmsNumberPlan::RESERVED_6 == + static_cast( + ::android::hardware::radio::V1_0::CdmaSmsNumberPlan::RESERVED_6)); +static_assert(aidl::android::hardware::radio::CdmaSmsNumberPlan::RESERVED_7 == + static_cast( + ::android::hardware::radio::V1_0::CdmaSmsNumberPlan::RESERVED_7)); +static_assert(aidl::android::hardware::radio::CdmaSmsNumberPlan::RESERVED_8 == + static_cast( + ::android::hardware::radio::V1_0::CdmaSmsNumberPlan::RESERVED_8)); +static_assert(aidl::android::hardware::radio::CdmaSmsNumberPlan::PRIVATE == + static_cast( + ::android::hardware::radio::V1_0::CdmaSmsNumberPlan::PRIVATE)); +static_assert(aidl::android::hardware::radio::CdmaSmsNumberPlan::RESERVED_10 == + static_cast( + ::android::hardware::radio::V1_0::CdmaSmsNumberPlan::RESERVED_10)); +static_assert(aidl::android::hardware::radio::CdmaSmsNumberPlan::RESERVED_11 == + static_cast( + ::android::hardware::radio::V1_0::CdmaSmsNumberPlan::RESERVED_11)); +static_assert(aidl::android::hardware::radio::CdmaSmsNumberPlan::RESERVED_12 == + static_cast( + ::android::hardware::radio::V1_0::CdmaSmsNumberPlan::RESERVED_12)); +static_assert(aidl::android::hardware::radio::CdmaSmsNumberPlan::RESERVED_13 == + static_cast( + ::android::hardware::radio::V1_0::CdmaSmsNumberPlan::RESERVED_13)); +static_assert(aidl::android::hardware::radio::CdmaSmsNumberPlan::RESERVED_14 == + static_cast( + ::android::hardware::radio::V1_0::CdmaSmsNumberPlan::RESERVED_14)); +static_assert(aidl::android::hardware::radio::CdmaSmsNumberPlan::RESERVED_15 == + static_cast( + ::android::hardware::radio::V1_0::CdmaSmsNumberPlan::RESERVED_15)); + +static_assert(aidl::android::hardware::radio::CdmaSmsSubaddressType::NSAP == + static_cast( + ::android::hardware::radio::V1_0::CdmaSmsSubaddressType::NSAP)); +static_assert(aidl::android::hardware::radio::CdmaSmsSubaddressType::USER_SPECIFIED == + static_cast( + ::android::hardware::radio::V1_0::CdmaSmsSubaddressType::USER_SPECIFIED)); + +static_assert(aidl::android::hardware::radio::CdmaSmsErrorClass::NO_ERROR == + static_cast( + ::android::hardware::radio::V1_0::CdmaSmsErrorClass::NO_ERROR)); +static_assert(aidl::android::hardware::radio::CdmaSmsErrorClass::ERROR == + static_cast( + ::android::hardware::radio::V1_0::CdmaSmsErrorClass::ERROR)); + +static_assert(aidl::android::hardware::radio::CdmaSmsWriteArgsStatus::REC_UNREAD == + static_cast( + ::android::hardware::radio::V1_0::CdmaSmsWriteArgsStatus::REC_UNREAD)); +static_assert(aidl::android::hardware::radio::CdmaSmsWriteArgsStatus::REC_READ == + static_cast( + ::android::hardware::radio::V1_0::CdmaSmsWriteArgsStatus::REC_READ)); +static_assert(aidl::android::hardware::radio::CdmaSmsWriteArgsStatus::STO_UNSENT == + static_cast( + ::android::hardware::radio::V1_0::CdmaSmsWriteArgsStatus::STO_UNSENT)); +static_assert(aidl::android::hardware::radio::CdmaSmsWriteArgsStatus::STO_SENT == + static_cast( + ::android::hardware::radio::V1_0::CdmaSmsWriteArgsStatus::STO_SENT)); + +static_assert(aidl::android::hardware::radio::CellInfoType::NONE == + static_cast( + ::android::hardware::radio::V1_0::CellInfoType::NONE)); +static_assert(aidl::android::hardware::radio::CellInfoType::GSM == + static_cast( + ::android::hardware::radio::V1_0::CellInfoType::GSM)); +static_assert(aidl::android::hardware::radio::CellInfoType::CDMA == + static_cast( + ::android::hardware::radio::V1_0::CellInfoType::CDMA)); +static_assert(aidl::android::hardware::radio::CellInfoType::LTE == + static_cast( + ::android::hardware::radio::V1_0::CellInfoType::LTE)); +static_assert(aidl::android::hardware::radio::CellInfoType::WCDMA == + static_cast( + ::android::hardware::radio::V1_0::CellInfoType::WCDMA)); +static_assert(aidl::android::hardware::radio::CellInfoType::TD_SCDMA == + static_cast( + ::android::hardware::radio::V1_0::CellInfoType::TD_SCDMA)); + +static_assert(aidl::android::hardware::radio::TimeStampType::UNKNOWN == + static_cast( + ::android::hardware::radio::V1_0::TimeStampType::UNKNOWN)); +static_assert(aidl::android::hardware::radio::TimeStampType::ANTENNA == + static_cast( + ::android::hardware::radio::V1_0::TimeStampType::ANTENNA)); +static_assert(aidl::android::hardware::radio::TimeStampType::MODEM == + static_cast( + ::android::hardware::radio::V1_0::TimeStampType::MODEM)); +static_assert(aidl::android::hardware::radio::TimeStampType::OEM_RIL == + static_cast( + ::android::hardware::radio::V1_0::TimeStampType::OEM_RIL)); +static_assert(aidl::android::hardware::radio::TimeStampType::JAVA_RIL == + static_cast( + ::android::hardware::radio::V1_0::TimeStampType::JAVA_RIL)); + +static_assert(aidl::android::hardware::radio::ApnAuthType::NO_PAP_NO_CHAP == + static_cast( + ::android::hardware::radio::V1_0::ApnAuthType::NO_PAP_NO_CHAP)); +static_assert(aidl::android::hardware::radio::ApnAuthType::PAP_NO_CHAP == + static_cast( + ::android::hardware::radio::V1_0::ApnAuthType::PAP_NO_CHAP)); +static_assert(aidl::android::hardware::radio::ApnAuthType::NO_PAP_CHAP == + static_cast( + ::android::hardware::radio::V1_0::ApnAuthType::NO_PAP_CHAP)); +static_assert(aidl::android::hardware::radio::ApnAuthType::PAP_CHAP == + static_cast( + ::android::hardware::radio::V1_0::ApnAuthType::PAP_CHAP)); + +static_assert(aidl::android::hardware::radio::RadioTechnologyFamily::THREE_GPP == + static_cast( + ::android::hardware::radio::V1_0::RadioTechnologyFamily::THREE_GPP)); +static_assert(aidl::android::hardware::radio::RadioTechnologyFamily::THREE_GPP2 == + static_cast( + ::android::hardware::radio::V1_0::RadioTechnologyFamily::THREE_GPP2)); + +static_assert(aidl::android::hardware::radio::RadioCapabilityPhase::CONFIGURED == + static_cast( + ::android::hardware::radio::V1_0::RadioCapabilityPhase::CONFIGURED)); +static_assert(aidl::android::hardware::radio::RadioCapabilityPhase::START == + static_cast( + ::android::hardware::radio::V1_0::RadioCapabilityPhase::START)); +static_assert(aidl::android::hardware::radio::RadioCapabilityPhase::APPLY == + static_cast( + ::android::hardware::radio::V1_0::RadioCapabilityPhase::APPLY)); +static_assert(aidl::android::hardware::radio::RadioCapabilityPhase::UNSOL_RSP == + static_cast( + ::android::hardware::radio::V1_0::RadioCapabilityPhase::UNSOL_RSP)); +static_assert(aidl::android::hardware::radio::RadioCapabilityPhase::FINISH == + static_cast( + ::android::hardware::radio::V1_0::RadioCapabilityPhase::FINISH)); + +static_assert(aidl::android::hardware::radio::RadioCapabilityStatus::NONE == + static_cast( + ::android::hardware::radio::V1_0::RadioCapabilityStatus::NONE)); +static_assert(aidl::android::hardware::radio::RadioCapabilityStatus::SUCCESS == + static_cast( + ::android::hardware::radio::V1_0::RadioCapabilityStatus::SUCCESS)); +static_assert(aidl::android::hardware::radio::RadioCapabilityStatus::FAIL == + static_cast( + ::android::hardware::radio::V1_0::RadioCapabilityStatus::FAIL)); + +static_assert(aidl::android::hardware::radio::UssdModeType::NOTIFY == + static_cast( + ::android::hardware::radio::V1_0::UssdModeType::NOTIFY)); +static_assert(aidl::android::hardware::radio::UssdModeType::REQUEST == + static_cast( + ::android::hardware::radio::V1_0::UssdModeType::REQUEST)); +static_assert(aidl::android::hardware::radio::UssdModeType::NW_RELEASE == + static_cast( + ::android::hardware::radio::V1_0::UssdModeType::NW_RELEASE)); +static_assert(aidl::android::hardware::radio::UssdModeType::LOCAL_CLIENT == + static_cast( + ::android::hardware::radio::V1_0::UssdModeType::LOCAL_CLIENT)); +static_assert(aidl::android::hardware::radio::UssdModeType::NOT_SUPPORTED == + static_cast( + ::android::hardware::radio::V1_0::UssdModeType::NOT_SUPPORTED)); +static_assert(aidl::android::hardware::radio::UssdModeType::NW_TIMEOUT == + static_cast( + ::android::hardware::radio::V1_0::UssdModeType::NW_TIMEOUT)); + +static_assert(aidl::android::hardware::radio::SimRefreshType::SIM_FILE_UPDATE == + static_cast( + ::android::hardware::radio::V1_0::SimRefreshType::SIM_FILE_UPDATE)); +static_assert(aidl::android::hardware::radio::SimRefreshType::SIM_INIT == + static_cast( + ::android::hardware::radio::V1_0::SimRefreshType::SIM_INIT)); +static_assert(aidl::android::hardware::radio::SimRefreshType::SIM_RESET == + static_cast( + ::android::hardware::radio::V1_0::SimRefreshType::SIM_RESET)); + +static_assert(aidl::android::hardware::radio::SrvccState::HANDOVER_STARTED == + static_cast( + ::android::hardware::radio::V1_0::SrvccState::HANDOVER_STARTED)); +static_assert(aidl::android::hardware::radio::SrvccState::HANDOVER_COMPLETED == + static_cast( + ::android::hardware::radio::V1_0::SrvccState::HANDOVER_COMPLETED)); +static_assert(aidl::android::hardware::radio::SrvccState::HANDOVER_FAILED == + static_cast( + ::android::hardware::radio::V1_0::SrvccState::HANDOVER_FAILED)); +static_assert(aidl::android::hardware::radio::SrvccState::HANDOVER_CANCELED == + static_cast( + ::android::hardware::radio::V1_0::SrvccState::HANDOVER_CANCELED)); + +static_assert(aidl::android::hardware::radio::UiccSubActStatus::DEACTIVATE == + static_cast( + ::android::hardware::radio::V1_0::UiccSubActStatus::DEACTIVATE)); +static_assert(aidl::android::hardware::radio::UiccSubActStatus::ACTIVATE == + static_cast( + ::android::hardware::radio::V1_0::UiccSubActStatus::ACTIVATE)); + +static_assert(aidl::android::hardware::radio::SubscriptionType::SUBSCRIPTION_1 == + static_cast( + ::android::hardware::radio::V1_0::SubscriptionType::SUBSCRIPTION_1)); +static_assert(aidl::android::hardware::radio::SubscriptionType::SUBSCRIPTION_2 == + static_cast( + ::android::hardware::radio::V1_0::SubscriptionType::SUBSCRIPTION_2)); +static_assert(aidl::android::hardware::radio::SubscriptionType::SUBSCRIPTION_3 == + static_cast( + ::android::hardware::radio::V1_0::SubscriptionType::SUBSCRIPTION_3)); + +static_assert(aidl::android::hardware::radio::DataProfileInfoType::COMMON == + static_cast( + ::android::hardware::radio::V1_0::DataProfileInfoType::COMMON)); +static_assert(aidl::android::hardware::radio::DataProfileInfoType::THREE_GPP == + static_cast( + ::android::hardware::radio::V1_0::DataProfileInfoType::THREE_GPP)); +static_assert(aidl::android::hardware::radio::DataProfileInfoType::THREE_GPP2 == + static_cast( + ::android::hardware::radio::V1_0::DataProfileInfoType::THREE_GPP2)); + +static_assert(aidl::android::hardware::radio::PhoneRestrictedState::NONE == + static_cast( + ::android::hardware::radio::V1_0::PhoneRestrictedState::NONE)); +static_assert(aidl::android::hardware::radio::PhoneRestrictedState::CS_EMERGENCY == + static_cast( + ::android::hardware::radio::V1_0::PhoneRestrictedState::CS_EMERGENCY)); +static_assert(aidl::android::hardware::radio::PhoneRestrictedState::CS_NORMAL == + static_cast( + ::android::hardware::radio::V1_0::PhoneRestrictedState::CS_NORMAL)); +static_assert(aidl::android::hardware::radio::PhoneRestrictedState::CS_ALL == + static_cast( + ::android::hardware::radio::V1_0::PhoneRestrictedState::CS_ALL)); +static_assert(aidl::android::hardware::radio::PhoneRestrictedState::PS_ALL == + static_cast( + ::android::hardware::radio::V1_0::PhoneRestrictedState::PS_ALL)); + +static_assert( + aidl::android::hardware::radio::CdmaCallWaitingNumberPresentation::ALLOWED == + static_cast( + ::android::hardware::radio::V1_0::CdmaCallWaitingNumberPresentation::ALLOWED)); +static_assert( + aidl::android::hardware::radio::CdmaCallWaitingNumberPresentation::RESTRICTED == + static_cast( + ::android::hardware::radio::V1_0::CdmaCallWaitingNumberPresentation::RESTRICTED)); +static_assert( + aidl::android::hardware::radio::CdmaCallWaitingNumberPresentation::UNKNOWN == + static_cast( + ::android::hardware::radio::V1_0::CdmaCallWaitingNumberPresentation::UNKNOWN)); + +static_assert(aidl::android::hardware::radio::CdmaCallWaitingNumberType::UNKNOWN == + static_cast( + ::android::hardware::radio::V1_0::CdmaCallWaitingNumberType::UNKNOWN)); +static_assert(aidl::android::hardware::radio::CdmaCallWaitingNumberType::INTERNATIONAL == + static_cast( + ::android::hardware::radio::V1_0::CdmaCallWaitingNumberType::INTERNATIONAL)); +static_assert(aidl::android::hardware::radio::CdmaCallWaitingNumberType::NATIONAL == + static_cast( + ::android::hardware::radio::V1_0::CdmaCallWaitingNumberType::NATIONAL)); +static_assert( + aidl::android::hardware::radio::CdmaCallWaitingNumberType::NETWORK_SPECIFIC == + static_cast( + ::android::hardware::radio::V1_0::CdmaCallWaitingNumberType::NETWORK_SPECIFIC)); +static_assert(aidl::android::hardware::radio::CdmaCallWaitingNumberType::SUBSCRIBER == + static_cast( + ::android::hardware::radio::V1_0::CdmaCallWaitingNumberType::SUBSCRIBER)); + +static_assert(aidl::android::hardware::radio::CdmaCallWaitingNumberPlan::UNKNOWN == + static_cast( + ::android::hardware::radio::V1_0::CdmaCallWaitingNumberPlan::UNKNOWN)); +static_assert(aidl::android::hardware::radio::CdmaCallWaitingNumberPlan::ISDN == + static_cast( + ::android::hardware::radio::V1_0::CdmaCallWaitingNumberPlan::ISDN)); +static_assert(aidl::android::hardware::radio::CdmaCallWaitingNumberPlan::DATA == + static_cast( + ::android::hardware::radio::V1_0::CdmaCallWaitingNumberPlan::DATA)); +static_assert(aidl::android::hardware::radio::CdmaCallWaitingNumberPlan::TELEX == + static_cast( + ::android::hardware::radio::V1_0::CdmaCallWaitingNumberPlan::TELEX)); +static_assert(aidl::android::hardware::radio::CdmaCallWaitingNumberPlan::NATIONAL == + static_cast( + ::android::hardware::radio::V1_0::CdmaCallWaitingNumberPlan::NATIONAL)); +static_assert(aidl::android::hardware::radio::CdmaCallWaitingNumberPlan::PRIVATE == + static_cast( + ::android::hardware::radio::V1_0::CdmaCallWaitingNumberPlan::PRIVATE)); + +static_assert(aidl::android::hardware::radio::CdmaOtaProvisionStatus::SPL_UNLOCKED == + static_cast( + ::android::hardware::radio::V1_0::CdmaOtaProvisionStatus::SPL_UNLOCKED)); +static_assert( + aidl::android::hardware::radio::CdmaOtaProvisionStatus::SPC_RETRIES_EXCEEDED == + static_cast( + ::android::hardware::radio::V1_0::CdmaOtaProvisionStatus::SPC_RETRIES_EXCEEDED)); +static_assert(aidl::android::hardware::radio::CdmaOtaProvisionStatus::A_KEY_EXCHANGED == + static_cast( + ::android::hardware::radio::V1_0::CdmaOtaProvisionStatus::A_KEY_EXCHANGED)); +static_assert(aidl::android::hardware::radio::CdmaOtaProvisionStatus::SSD_UPDATED == + static_cast( + ::android::hardware::radio::V1_0::CdmaOtaProvisionStatus::SSD_UPDATED)); +static_assert(aidl::android::hardware::radio::CdmaOtaProvisionStatus::NAM_DOWNLOADED == + static_cast( + ::android::hardware::radio::V1_0::CdmaOtaProvisionStatus::NAM_DOWNLOADED)); +static_assert(aidl::android::hardware::radio::CdmaOtaProvisionStatus::MDN_DOWNLOADED == + static_cast( + ::android::hardware::radio::V1_0::CdmaOtaProvisionStatus::MDN_DOWNLOADED)); +static_assert(aidl::android::hardware::radio::CdmaOtaProvisionStatus::IMSI_DOWNLOADED == + static_cast( + ::android::hardware::radio::V1_0::CdmaOtaProvisionStatus::IMSI_DOWNLOADED)); +static_assert(aidl::android::hardware::radio::CdmaOtaProvisionStatus::PRL_DOWNLOADED == + static_cast( + ::android::hardware::radio::V1_0::CdmaOtaProvisionStatus::PRL_DOWNLOADED)); +static_assert(aidl::android::hardware::radio::CdmaOtaProvisionStatus::COMMITTED == + static_cast( + ::android::hardware::radio::V1_0::CdmaOtaProvisionStatus::COMMITTED)); +static_assert(aidl::android::hardware::radio::CdmaOtaProvisionStatus::OTAPA_STARTED == + static_cast( + ::android::hardware::radio::V1_0::CdmaOtaProvisionStatus::OTAPA_STARTED)); +static_assert(aidl::android::hardware::radio::CdmaOtaProvisionStatus::OTAPA_STOPPED == + static_cast( + ::android::hardware::radio::V1_0::CdmaOtaProvisionStatus::OTAPA_STOPPED)); +static_assert(aidl::android::hardware::radio::CdmaOtaProvisionStatus::OTAPA_ABORTED == + static_cast( + ::android::hardware::radio::V1_0::CdmaOtaProvisionStatus::OTAPA_ABORTED)); + +static_assert(aidl::android::hardware::radio::CdmaInfoRecName::DISPLAY == + static_cast( + ::android::hardware::radio::V1_0::CdmaInfoRecName::DISPLAY)); +static_assert(aidl::android::hardware::radio::CdmaInfoRecName::CALLED_PARTY_NUMBER == + static_cast( + ::android::hardware::radio::V1_0::CdmaInfoRecName::CALLED_PARTY_NUMBER)); +static_assert(aidl::android::hardware::radio::CdmaInfoRecName::CALLING_PARTY_NUMBER == + static_cast( + ::android::hardware::radio::V1_0::CdmaInfoRecName::CALLING_PARTY_NUMBER)); +static_assert(aidl::android::hardware::radio::CdmaInfoRecName::CONNECTED_NUMBER == + static_cast( + ::android::hardware::radio::V1_0::CdmaInfoRecName::CONNECTED_NUMBER)); +static_assert(aidl::android::hardware::radio::CdmaInfoRecName::SIGNAL == + static_cast( + ::android::hardware::radio::V1_0::CdmaInfoRecName::SIGNAL)); +static_assert(aidl::android::hardware::radio::CdmaInfoRecName::REDIRECTING_NUMBER == + static_cast( + ::android::hardware::radio::V1_0::CdmaInfoRecName::REDIRECTING_NUMBER)); +static_assert(aidl::android::hardware::radio::CdmaInfoRecName::LINE_CONTROL == + static_cast( + ::android::hardware::radio::V1_0::CdmaInfoRecName::LINE_CONTROL)); +static_assert(aidl::android::hardware::radio::CdmaInfoRecName::EXTENDED_DISPLAY == + static_cast( + ::android::hardware::radio::V1_0::CdmaInfoRecName::EXTENDED_DISPLAY)); +static_assert(aidl::android::hardware::radio::CdmaInfoRecName::T53_CLIR == + static_cast( + ::android::hardware::radio::V1_0::CdmaInfoRecName::T53_CLIR)); +static_assert(aidl::android::hardware::radio::CdmaInfoRecName::T53_RELEASE == + static_cast( + ::android::hardware::radio::V1_0::CdmaInfoRecName::T53_RELEASE)); +static_assert(aidl::android::hardware::radio::CdmaInfoRecName::T53_AUDIO_CONTROL == + static_cast( + ::android::hardware::radio::V1_0::CdmaInfoRecName::T53_AUDIO_CONTROL)); + +static_assert(aidl::android::hardware::radio::CdmaRedirectingReason::UNKNOWN == + static_cast( + ::android::hardware::radio::V1_0::CdmaRedirectingReason::UNKNOWN)); +static_assert( + aidl::android::hardware::radio::CdmaRedirectingReason::CALL_FORWARDING_BUSY == + static_cast( + ::android::hardware::radio::V1_0::CdmaRedirectingReason::CALL_FORWARDING_BUSY)); +static_assert( + aidl::android::hardware::radio::CdmaRedirectingReason::CALL_FORWARDING_NO_REPLY == + static_cast( + ::android::hardware::radio::V1_0::CdmaRedirectingReason::CALL_FORWARDING_NO_REPLY)); +static_assert( + aidl::android::hardware::radio::CdmaRedirectingReason::CALLED_DTE_OUT_OF_ORDER == + static_cast( + ::android::hardware::radio::V1_0::CdmaRedirectingReason::CALLED_DTE_OUT_OF_ORDER)); +static_assert( + aidl::android::hardware::radio::CdmaRedirectingReason::CALL_FORWARDING_BY_THE_CALLED_DTE == + static_cast( + ::android::hardware::radio::V1_0::CdmaRedirectingReason:: + CALL_FORWARDING_BY_THE_CALLED_DTE)); +static_assert( + aidl::android::hardware::radio::CdmaRedirectingReason::CALL_FORWARDING_UNCONDITIONAL == + static_cast( + ::android::hardware::radio::V1_0::CdmaRedirectingReason:: + CALL_FORWARDING_UNCONDITIONAL)); +static_assert(aidl::android::hardware::radio::CdmaRedirectingReason::RESERVED == + static_cast( + ::android::hardware::radio::V1_0::CdmaRedirectingReason::RESERVED)); + +static_assert(aidl::android::hardware::radio::SsServiceType::CFU == + static_cast( + ::android::hardware::radio::V1_0::SsServiceType::CFU)); +static_assert(aidl::android::hardware::radio::SsServiceType::CF_BUSY == + static_cast( + ::android::hardware::radio::V1_0::SsServiceType::CF_BUSY)); +static_assert(aidl::android::hardware::radio::SsServiceType::CF_NO_REPLY == + static_cast( + ::android::hardware::radio::V1_0::SsServiceType::CF_NO_REPLY)); +static_assert(aidl::android::hardware::radio::SsServiceType::CF_NOT_REACHABLE == + static_cast( + ::android::hardware::radio::V1_0::SsServiceType::CF_NOT_REACHABLE)); +static_assert(aidl::android::hardware::radio::SsServiceType::CF_ALL == + static_cast( + ::android::hardware::radio::V1_0::SsServiceType::CF_ALL)); +static_assert(aidl::android::hardware::radio::SsServiceType::CF_ALL_CONDITIONAL == + static_cast( + ::android::hardware::radio::V1_0::SsServiceType::CF_ALL_CONDITIONAL)); +static_assert(aidl::android::hardware::radio::SsServiceType::CLIP == + static_cast( + ::android::hardware::radio::V1_0::SsServiceType::CLIP)); +static_assert(aidl::android::hardware::radio::SsServiceType::CLIR == + static_cast( + ::android::hardware::radio::V1_0::SsServiceType::CLIR)); +static_assert(aidl::android::hardware::radio::SsServiceType::COLP == + static_cast( + ::android::hardware::radio::V1_0::SsServiceType::COLP)); +static_assert(aidl::android::hardware::radio::SsServiceType::COLR == + static_cast( + ::android::hardware::radio::V1_0::SsServiceType::COLR)); +static_assert(aidl::android::hardware::radio::SsServiceType::WAIT == + static_cast( + ::android::hardware::radio::V1_0::SsServiceType::WAIT)); +static_assert(aidl::android::hardware::radio::SsServiceType::BAOC == + static_cast( + ::android::hardware::radio::V1_0::SsServiceType::BAOC)); +static_assert(aidl::android::hardware::radio::SsServiceType::BAOIC == + static_cast( + ::android::hardware::radio::V1_0::SsServiceType::BAOIC)); +static_assert(aidl::android::hardware::radio::SsServiceType::BAOIC_EXC_HOME == + static_cast( + ::android::hardware::radio::V1_0::SsServiceType::BAOIC_EXC_HOME)); +static_assert(aidl::android::hardware::radio::SsServiceType::BAIC == + static_cast( + ::android::hardware::radio::V1_0::SsServiceType::BAIC)); +static_assert(aidl::android::hardware::radio::SsServiceType::BAIC_ROAMING == + static_cast( + ::android::hardware::radio::V1_0::SsServiceType::BAIC_ROAMING)); +static_assert(aidl::android::hardware::radio::SsServiceType::ALL_BARRING == + static_cast( + ::android::hardware::radio::V1_0::SsServiceType::ALL_BARRING)); +static_assert(aidl::android::hardware::radio::SsServiceType::OUTGOING_BARRING == + static_cast( + ::android::hardware::radio::V1_0::SsServiceType::OUTGOING_BARRING)); +static_assert(aidl::android::hardware::radio::SsServiceType::INCOMING_BARRING == + static_cast( + ::android::hardware::radio::V1_0::SsServiceType::INCOMING_BARRING)); + +static_assert(aidl::android::hardware::radio::SsRequestType::ACTIVATION == + static_cast( + ::android::hardware::radio::V1_0::SsRequestType::ACTIVATION)); +static_assert(aidl::android::hardware::radio::SsRequestType::DEACTIVATION == + static_cast( + ::android::hardware::radio::V1_0::SsRequestType::DEACTIVATION)); +static_assert(aidl::android::hardware::radio::SsRequestType::INTERROGATION == + static_cast( + ::android::hardware::radio::V1_0::SsRequestType::INTERROGATION)); +static_assert(aidl::android::hardware::radio::SsRequestType::REGISTRATION == + static_cast( + ::android::hardware::radio::V1_0::SsRequestType::REGISTRATION)); +static_assert(aidl::android::hardware::radio::SsRequestType::ERASURE == + static_cast( + ::android::hardware::radio::V1_0::SsRequestType::ERASURE)); + +static_assert( + aidl::android::hardware::radio::SsTeleserviceType::ALL_TELE_AND_BEARER_SERVICES == + static_cast( + ::android::hardware::radio::V1_0::SsTeleserviceType::ALL_TELE_AND_BEARER_SERVICES)); +static_assert(aidl::android::hardware::radio::SsTeleserviceType::ALL_TELESEVICES == + static_cast( + ::android::hardware::radio::V1_0::SsTeleserviceType::ALL_TELESEVICES)); +static_assert(aidl::android::hardware::radio::SsTeleserviceType::TELEPHONY == + static_cast( + ::android::hardware::radio::V1_0::SsTeleserviceType::TELEPHONY)); +static_assert(aidl::android::hardware::radio::SsTeleserviceType::ALL_DATA_TELESERVICES == + static_cast( + ::android::hardware::radio::V1_0::SsTeleserviceType::ALL_DATA_TELESERVICES)); +static_assert(aidl::android::hardware::radio::SsTeleserviceType::SMS_SERVICES == + static_cast( + ::android::hardware::radio::V1_0::SsTeleserviceType::SMS_SERVICES)); +static_assert( + aidl::android::hardware::radio::SsTeleserviceType::ALL_TELESERVICES_EXCEPT_SMS == + static_cast( + ::android::hardware::radio::V1_0::SsTeleserviceType::ALL_TELESERVICES_EXCEPT_SMS)); + +static_assert(aidl::android::hardware::radio::SuppServiceClass::NONE == + static_cast( + ::android::hardware::radio::V1_0::SuppServiceClass::NONE)); +static_assert(aidl::android::hardware::radio::SuppServiceClass::VOICE == + static_cast( + ::android::hardware::radio::V1_0::SuppServiceClass::VOICE)); +static_assert(aidl::android::hardware::radio::SuppServiceClass::DATA == + static_cast( + ::android::hardware::radio::V1_0::SuppServiceClass::DATA)); +static_assert(aidl::android::hardware::radio::SuppServiceClass::FAX == + static_cast( + ::android::hardware::radio::V1_0::SuppServiceClass::FAX)); +static_assert(aidl::android::hardware::radio::SuppServiceClass::SMS == + static_cast( + ::android::hardware::radio::V1_0::SuppServiceClass::SMS)); +static_assert(aidl::android::hardware::radio::SuppServiceClass::DATA_SYNC == + static_cast( + ::android::hardware::radio::V1_0::SuppServiceClass::DATA_SYNC)); +static_assert(aidl::android::hardware::radio::SuppServiceClass::DATA_ASYNC == + static_cast( + ::android::hardware::radio::V1_0::SuppServiceClass::DATA_ASYNC)); +static_assert(aidl::android::hardware::radio::SuppServiceClass::PACKET == + static_cast( + ::android::hardware::radio::V1_0::SuppServiceClass::PACKET)); +static_assert(aidl::android::hardware::radio::SuppServiceClass::PAD == + static_cast( + ::android::hardware::radio::V1_0::SuppServiceClass::PAD)); +static_assert(aidl::android::hardware::radio::SuppServiceClass::MAX == + static_cast( + ::android::hardware::radio::V1_0::SuppServiceClass::MAX)); + +static_assert(aidl::android::hardware::radio::MvnoType::NONE == + static_cast( + ::android::hardware::radio::V1_0::MvnoType::NONE)); +static_assert(aidl::android::hardware::radio::MvnoType::IMSI == + static_cast( + ::android::hardware::radio::V1_0::MvnoType::IMSI)); +static_assert(aidl::android::hardware::radio::MvnoType::GID == + static_cast( + ::android::hardware::radio::V1_0::MvnoType::GID)); +static_assert(aidl::android::hardware::radio::MvnoType::SPN == + static_cast( + ::android::hardware::radio::V1_0::MvnoType::SPN)); + +static_assert(aidl::android::hardware::radio::DeviceStateType::POWER_SAVE_MODE == + static_cast( + ::android::hardware::radio::V1_0::DeviceStateType::POWER_SAVE_MODE)); +static_assert(aidl::android::hardware::radio::DeviceStateType::CHARGING_STATE == + static_cast( + ::android::hardware::radio::V1_0::DeviceStateType::CHARGING_STATE)); +static_assert(aidl::android::hardware::radio::DeviceStateType::LOW_DATA_EXPECTED == + static_cast( + ::android::hardware::radio::V1_0::DeviceStateType::LOW_DATA_EXPECTED)); + +static_assert(aidl::android::hardware::radio::P2Constant::NO_P2 == + static_cast( + ::android::hardware::radio::V1_0::P2Constant::NO_P2)); + +static_assert(aidl::android::hardware::radio::CardPowerState::POWER_DOWN == + static_cast( + ::android::hardware::radio::V1_1::CardPowerState::POWER_DOWN)); +static_assert(aidl::android::hardware::radio::CardPowerState::POWER_UP == + static_cast( + ::android::hardware::radio::V1_1::CardPowerState::POWER_UP)); +static_assert(aidl::android::hardware::radio::CardPowerState::POWER_UP_PASS_THROUGH == + static_cast( + ::android::hardware::radio::V1_1::CardPowerState::POWER_UP_PASS_THROUGH)); + +static_assert(aidl::android::hardware::radio::GeranBands::BAND_T380 == + static_cast( + ::android::hardware::radio::V1_1::GeranBands::BAND_T380)); +static_assert(aidl::android::hardware::radio::GeranBands::BAND_T410 == + static_cast( + ::android::hardware::radio::V1_1::GeranBands::BAND_T410)); +static_assert(aidl::android::hardware::radio::GeranBands::BAND_450 == + static_cast( + ::android::hardware::radio::V1_1::GeranBands::BAND_450)); +static_assert(aidl::android::hardware::radio::GeranBands::BAND_480 == + static_cast( + ::android::hardware::radio::V1_1::GeranBands::BAND_480)); +static_assert(aidl::android::hardware::radio::GeranBands::BAND_710 == + static_cast( + ::android::hardware::radio::V1_1::GeranBands::BAND_710)); +static_assert(aidl::android::hardware::radio::GeranBands::BAND_750 == + static_cast( + ::android::hardware::radio::V1_1::GeranBands::BAND_750)); +static_assert(aidl::android::hardware::radio::GeranBands::BAND_T810 == + static_cast( + ::android::hardware::radio::V1_1::GeranBands::BAND_T810)); +static_assert(aidl::android::hardware::radio::GeranBands::BAND_850 == + static_cast( + ::android::hardware::radio::V1_1::GeranBands::BAND_850)); +static_assert(aidl::android::hardware::radio::GeranBands::BAND_P900 == + static_cast( + ::android::hardware::radio::V1_1::GeranBands::BAND_P900)); +static_assert(aidl::android::hardware::radio::GeranBands::BAND_E900 == + static_cast( + ::android::hardware::radio::V1_1::GeranBands::BAND_E900)); +static_assert(aidl::android::hardware::radio::GeranBands::BAND_R900 == + static_cast( + ::android::hardware::radio::V1_1::GeranBands::BAND_R900)); +static_assert(aidl::android::hardware::radio::GeranBands::BAND_DCS1800 == + static_cast( + ::android::hardware::radio::V1_1::GeranBands::BAND_DCS1800)); +static_assert(aidl::android::hardware::radio::GeranBands::BAND_PCS1900 == + static_cast( + ::android::hardware::radio::V1_1::GeranBands::BAND_PCS1900)); +static_assert(aidl::android::hardware::radio::GeranBands::BAND_ER900 == + static_cast( + ::android::hardware::radio::V1_1::GeranBands::BAND_ER900)); + +static_assert(aidl::android::hardware::radio::ScanType::ONE_SHOT == + static_cast( + ::android::hardware::radio::V1_1::ScanType::ONE_SHOT)); +static_assert(aidl::android::hardware::radio::ScanType::PERIODIC == + static_cast( + ::android::hardware::radio::V1_1::ScanType::PERIODIC)); + +static_assert(aidl::android::hardware::radio::ScanStatus::PARTIAL == + static_cast( + ::android::hardware::radio::V1_1::ScanStatus::PARTIAL)); +static_assert(aidl::android::hardware::radio::ScanStatus::COMPLETE == + static_cast( + ::android::hardware::radio::V1_1::ScanStatus::COMPLETE)); + +static_assert(aidl::android::hardware::radio::KeepaliveType::NATT_IPV4 == + static_cast( + ::android::hardware::radio::V1_1::KeepaliveType::NATT_IPV4)); +static_assert(aidl::android::hardware::radio::KeepaliveType::NATT_IPV6 == + static_cast( + ::android::hardware::radio::V1_1::KeepaliveType::NATT_IPV6)); + +static_assert(aidl::android::hardware::radio::KeepaliveStatusCode::ACTIVE == + static_cast( + ::android::hardware::radio::V1_1::KeepaliveStatusCode::ACTIVE)); +static_assert(aidl::android::hardware::radio::KeepaliveStatusCode::INACTIVE == + static_cast( + ::android::hardware::radio::V1_1::KeepaliveStatusCode::INACTIVE)); +static_assert(aidl::android::hardware::radio::KeepaliveStatusCode::PENDING == + static_cast( + ::android::hardware::radio::V1_1::KeepaliveStatusCode::PENDING)); + +static_assert(aidl::android::hardware::radio::RadioConst::CDMA_ALPHA_INFO_BUFFER_LENGTH == + static_cast( + ::android::hardware::radio::V1_2::RadioConst::CDMA_ALPHA_INFO_BUFFER_LENGTH)); +static_assert( + aidl::android::hardware::radio::RadioConst::CDMA_NUMBER_INFO_BUFFER_LENGTH == + static_cast( + ::android::hardware::radio::V1_2::RadioConst::CDMA_NUMBER_INFO_BUFFER_LENGTH)); +static_assert(aidl::android::hardware::radio::RadioConst::MAX_RILDS == + static_cast( + ::android::hardware::radio::V1_2::RadioConst::MAX_RILDS)); +static_assert(aidl::android::hardware::radio::RadioConst::MAX_SOCKET_NAME_LENGTH == + static_cast( + ::android::hardware::radio::V1_2::RadioConst::MAX_SOCKET_NAME_LENGTH)); +static_assert(aidl::android::hardware::radio::RadioConst::MAX_CLIENT_ID_LENGTH == + static_cast( + ::android::hardware::radio::V1_2::RadioConst::MAX_CLIENT_ID_LENGTH)); +static_assert(aidl::android::hardware::radio::RadioConst::MAX_DEBUG_SOCKET_NAME_LENGTH == + static_cast( + ::android::hardware::radio::V1_2::RadioConst::MAX_DEBUG_SOCKET_NAME_LENGTH)); +static_assert(aidl::android::hardware::radio::RadioConst::MAX_QEMU_PIPE_NAME_LENGTH == + static_cast( + ::android::hardware::radio::V1_2::RadioConst::MAX_QEMU_PIPE_NAME_LENGTH)); +static_assert(aidl::android::hardware::radio::RadioConst::MAX_UUID_LENGTH == + static_cast( + ::android::hardware::radio::V1_2::RadioConst::MAX_UUID_LENGTH)); +static_assert(aidl::android::hardware::radio::RadioConst::CARD_MAX_APPS == + static_cast( + ::android::hardware::radio::V1_2::RadioConst::CARD_MAX_APPS)); +static_assert(aidl::android::hardware::radio::RadioConst::CDMA_MAX_NUMBER_OF_INFO_RECS == + static_cast( + ::android::hardware::radio::V1_2::RadioConst::CDMA_MAX_NUMBER_OF_INFO_RECS)); +static_assert(aidl::android::hardware::radio::RadioConst::SS_INFO_MAX == + static_cast( + ::android::hardware::radio::V1_2::RadioConst::SS_INFO_MAX)); +static_assert(aidl::android::hardware::radio::RadioConst::NUM_SERVICE_CLASSES == + static_cast( + ::android::hardware::radio::V1_2::RadioConst::NUM_SERVICE_CLASSES)); +static_assert(aidl::android::hardware::radio::RadioConst::NUM_TX_POWER_LEVELS == + static_cast( + ::android::hardware::radio::V1_2::RadioConst::NUM_TX_POWER_LEVELS)); +static_assert( + aidl::android::hardware::radio::RadioConst::RADIO_ACCESS_SPECIFIER_MAX_SIZE == + static_cast( + ::android::hardware::radio::V1_2::RadioConst::RADIO_ACCESS_SPECIFIER_MAX_SIZE)); + +static_assert(aidl::android::hardware::radio::ScanIntervalRange::MIN == + static_cast( + ::android::hardware::radio::V1_2::ScanIntervalRange::MIN)); +static_assert(aidl::android::hardware::radio::ScanIntervalRange::MAX == + static_cast( + ::android::hardware::radio::V1_2::ScanIntervalRange::MAX)); + +static_assert(aidl::android::hardware::radio::MaxSearchTimeRange::MIN == + static_cast( + ::android::hardware::radio::V1_2::MaxSearchTimeRange::MIN)); +static_assert(aidl::android::hardware::radio::MaxSearchTimeRange::MAX == + static_cast( + ::android::hardware::radio::V1_2::MaxSearchTimeRange::MAX)); + +static_assert(aidl::android::hardware::radio::IncrementalResultsPeriodicityRange::MIN == + static_cast( + ::android::hardware::radio::V1_2::IncrementalResultsPeriodicityRange::MIN)); +static_assert(aidl::android::hardware::radio::IncrementalResultsPeriodicityRange::MAX == + static_cast( + ::android::hardware::radio::V1_2::IncrementalResultsPeriodicityRange::MAX)); + +static_assert(aidl::android::hardware::radio::CellConnectionStatus::NONE == + static_cast( + ::android::hardware::radio::V1_2::CellConnectionStatus::NONE)); +static_assert(aidl::android::hardware::radio::CellConnectionStatus::PRIMARY_SERVING == + static_cast( + ::android::hardware::radio::V1_2::CellConnectionStatus::PRIMARY_SERVING)); +static_assert(aidl::android::hardware::radio::CellConnectionStatus::SECONDARY_SERVING == + static_cast( + ::android::hardware::radio::V1_2::CellConnectionStatus::SECONDARY_SERVING)); + +static_assert(aidl::android::hardware::radio::AudioQuality::UNSPECIFIED == + static_cast( + ::android::hardware::radio::V1_2::AudioQuality::UNSPECIFIED)); +static_assert(aidl::android::hardware::radio::AudioQuality::AMR == + static_cast( + ::android::hardware::radio::V1_2::AudioQuality::AMR)); +static_assert(aidl::android::hardware::radio::AudioQuality::AMR_WB == + static_cast( + ::android::hardware::radio::V1_2::AudioQuality::AMR_WB)); +static_assert(aidl::android::hardware::radio::AudioQuality::GSM_EFR == + static_cast( + ::android::hardware::radio::V1_2::AudioQuality::GSM_EFR)); +static_assert(aidl::android::hardware::radio::AudioQuality::GSM_FR == + static_cast( + ::android::hardware::radio::V1_2::AudioQuality::GSM_FR)); +static_assert(aidl::android::hardware::radio::AudioQuality::GSM_HR == + static_cast( + ::android::hardware::radio::V1_2::AudioQuality::GSM_HR)); +static_assert(aidl::android::hardware::radio::AudioQuality::EVRC == + static_cast( + ::android::hardware::radio::V1_2::AudioQuality::EVRC)); +static_assert(aidl::android::hardware::radio::AudioQuality::EVRC_B == + static_cast( + ::android::hardware::radio::V1_2::AudioQuality::EVRC_B)); +static_assert(aidl::android::hardware::radio::AudioQuality::EVRC_WB == + static_cast( + ::android::hardware::radio::V1_2::AudioQuality::EVRC_WB)); +static_assert(aidl::android::hardware::radio::AudioQuality::EVRC_NW == + static_cast( + ::android::hardware::radio::V1_2::AudioQuality::EVRC_NW)); + +static_assert(aidl::android::hardware::radio::DataRequestReason::NORMAL == + static_cast( + ::android::hardware::radio::V1_2::DataRequestReason::NORMAL)); +static_assert(aidl::android::hardware::radio::DataRequestReason::SHUTDOWN == + static_cast( + ::android::hardware::radio::V1_2::DataRequestReason::SHUTDOWN)); +static_assert(aidl::android::hardware::radio::DataRequestReason::HANDOVER == + static_cast( + ::android::hardware::radio::V1_2::DataRequestReason::HANDOVER)); + +static_assert(aidl::android::hardware::radio::EmergencyServiceCategory::UNSPECIFIED == + static_cast( + ::android::hardware::radio::V1_4::EmergencyServiceCategory::UNSPECIFIED)); +static_assert(aidl::android::hardware::radio::EmergencyServiceCategory::POLICE == + static_cast( + ::android::hardware::radio::V1_4::EmergencyServiceCategory::POLICE)); +static_assert(aidl::android::hardware::radio::EmergencyServiceCategory::AMBULANCE == + static_cast( + ::android::hardware::radio::V1_4::EmergencyServiceCategory::AMBULANCE)); +static_assert(aidl::android::hardware::radio::EmergencyServiceCategory::FIRE_BRIGADE == + static_cast( + ::android::hardware::radio::V1_4::EmergencyServiceCategory::FIRE_BRIGADE)); +static_assert(aidl::android::hardware::radio::EmergencyServiceCategory::MARINE_GUARD == + static_cast( + ::android::hardware::radio::V1_4::EmergencyServiceCategory::MARINE_GUARD)); +static_assert(aidl::android::hardware::radio::EmergencyServiceCategory::MOUNTAIN_RESCUE == + static_cast( + ::android::hardware::radio::V1_4::EmergencyServiceCategory::MOUNTAIN_RESCUE)); +static_assert(aidl::android::hardware::radio::EmergencyServiceCategory::MIEC == + static_cast( + ::android::hardware::radio::V1_4::EmergencyServiceCategory::MIEC)); +static_assert(aidl::android::hardware::radio::EmergencyServiceCategory::AIEC == + static_cast( + ::android::hardware::radio::V1_4::EmergencyServiceCategory::AIEC)); + +static_assert(aidl::android::hardware::radio::EmergencyNumberSource::NETWORK_SIGNALING == + static_cast( + ::android::hardware::radio::V1_4::EmergencyNumberSource::NETWORK_SIGNALING)); +static_assert(aidl::android::hardware::radio::EmergencyNumberSource::SIM == + static_cast( + ::android::hardware::radio::V1_4::EmergencyNumberSource::SIM)); +static_assert(aidl::android::hardware::radio::EmergencyNumberSource::MODEM_CONFIG == + static_cast( + ::android::hardware::radio::V1_4::EmergencyNumberSource::MODEM_CONFIG)); +static_assert(aidl::android::hardware::radio::EmergencyNumberSource::DEFAULT == + static_cast( + ::android::hardware::radio::V1_4::EmergencyNumberSource::DEFAULT)); + +static_assert(aidl::android::hardware::radio::EmergencyCallRouting::UNKNOWN == + static_cast( + ::android::hardware::radio::V1_4::EmergencyCallRouting::UNKNOWN)); +static_assert(aidl::android::hardware::radio::EmergencyCallRouting::EMERGENCY == + static_cast( + ::android::hardware::radio::V1_4::EmergencyCallRouting::EMERGENCY)); +static_assert(aidl::android::hardware::radio::EmergencyCallRouting::NORMAL == + static_cast( + ::android::hardware::radio::V1_4::EmergencyCallRouting::NORMAL)); + +static_assert(aidl::android::hardware::radio::RadioTechnology::UNKNOWN == + static_cast( + ::android::hardware::radio::V1_4::RadioTechnology::UNKNOWN)); +static_assert(aidl::android::hardware::radio::RadioTechnology::GPRS == + static_cast( + ::android::hardware::radio::V1_4::RadioTechnology::GPRS)); +static_assert(aidl::android::hardware::radio::RadioTechnology::EDGE == + static_cast( + ::android::hardware::radio::V1_4::RadioTechnology::EDGE)); +static_assert(aidl::android::hardware::radio::RadioTechnology::UMTS == + static_cast( + ::android::hardware::radio::V1_4::RadioTechnology::UMTS)); +static_assert(aidl::android::hardware::radio::RadioTechnology::IS95A == + static_cast( + ::android::hardware::radio::V1_4::RadioTechnology::IS95A)); +static_assert(aidl::android::hardware::radio::RadioTechnology::IS95B == + static_cast( + ::android::hardware::radio::V1_4::RadioTechnology::IS95B)); +static_assert(aidl::android::hardware::radio::RadioTechnology::ONE_X_RTT == + static_cast( + ::android::hardware::radio::V1_4::RadioTechnology::ONE_X_RTT)); +static_assert(aidl::android::hardware::radio::RadioTechnology::EVDO_0 == + static_cast( + ::android::hardware::radio::V1_4::RadioTechnology::EVDO_0)); +static_assert(aidl::android::hardware::radio::RadioTechnology::EVDO_A == + static_cast( + ::android::hardware::radio::V1_4::RadioTechnology::EVDO_A)); +static_assert(aidl::android::hardware::radio::RadioTechnology::HSDPA == + static_cast( + ::android::hardware::radio::V1_4::RadioTechnology::HSDPA)); +static_assert(aidl::android::hardware::radio::RadioTechnology::HSUPA == + static_cast( + ::android::hardware::radio::V1_4::RadioTechnology::HSUPA)); +static_assert(aidl::android::hardware::radio::RadioTechnology::HSPA == + static_cast( + ::android::hardware::radio::V1_4::RadioTechnology::HSPA)); +static_assert(aidl::android::hardware::radio::RadioTechnology::EVDO_B == + static_cast( + ::android::hardware::radio::V1_4::RadioTechnology::EVDO_B)); +static_assert(aidl::android::hardware::radio::RadioTechnology::EHRPD == + static_cast( + ::android::hardware::radio::V1_4::RadioTechnology::EHRPD)); +static_assert(aidl::android::hardware::radio::RadioTechnology::LTE == + static_cast( + ::android::hardware::radio::V1_4::RadioTechnology::LTE)); +static_assert(aidl::android::hardware::radio::RadioTechnology::HSPAP == + static_cast( + ::android::hardware::radio::V1_4::RadioTechnology::HSPAP)); +static_assert(aidl::android::hardware::radio::RadioTechnology::GSM == + static_cast( + ::android::hardware::radio::V1_4::RadioTechnology::GSM)); +static_assert(aidl::android::hardware::radio::RadioTechnology::TD_SCDMA == + static_cast( + ::android::hardware::radio::V1_4::RadioTechnology::TD_SCDMA)); +static_assert(aidl::android::hardware::radio::RadioTechnology::IWLAN == + static_cast( + ::android::hardware::radio::V1_4::RadioTechnology::IWLAN)); +static_assert(aidl::android::hardware::radio::RadioTechnology::LTE_CA == + static_cast( + ::android::hardware::radio::V1_4::RadioTechnology::LTE_CA)); +static_assert(aidl::android::hardware::radio::RadioTechnology::NR == + static_cast( + ::android::hardware::radio::V1_4::RadioTechnology::NR)); + +static_assert(aidl::android::hardware::radio::RadioAccessFamily::UNKNOWN == + static_cast( + ::android::hardware::radio::V1_4::RadioAccessFamily::UNKNOWN)); +static_assert(aidl::android::hardware::radio::RadioAccessFamily::GPRS == + static_cast( + ::android::hardware::radio::V1_4::RadioAccessFamily::GPRS)); +static_assert(aidl::android::hardware::radio::RadioAccessFamily::EDGE == + static_cast( + ::android::hardware::radio::V1_4::RadioAccessFamily::EDGE)); +static_assert(aidl::android::hardware::radio::RadioAccessFamily::UMTS == + static_cast( + ::android::hardware::radio::V1_4::RadioAccessFamily::UMTS)); +static_assert(aidl::android::hardware::radio::RadioAccessFamily::IS95A == + static_cast( + ::android::hardware::radio::V1_4::RadioAccessFamily::IS95A)); +static_assert(aidl::android::hardware::radio::RadioAccessFamily::IS95B == + static_cast( + ::android::hardware::radio::V1_4::RadioAccessFamily::IS95B)); +static_assert(aidl::android::hardware::radio::RadioAccessFamily::ONE_X_RTT == + static_cast( + ::android::hardware::radio::V1_4::RadioAccessFamily::ONE_X_RTT)); +static_assert(aidl::android::hardware::radio::RadioAccessFamily::EVDO_0 == + static_cast( + ::android::hardware::radio::V1_4::RadioAccessFamily::EVDO_0)); +static_assert(aidl::android::hardware::radio::RadioAccessFamily::EVDO_A == + static_cast( + ::android::hardware::radio::V1_4::RadioAccessFamily::EVDO_A)); +static_assert(aidl::android::hardware::radio::RadioAccessFamily::HSDPA == + static_cast( + ::android::hardware::radio::V1_4::RadioAccessFamily::HSDPA)); +static_assert(aidl::android::hardware::radio::RadioAccessFamily::HSUPA == + static_cast( + ::android::hardware::radio::V1_4::RadioAccessFamily::HSUPA)); +static_assert(aidl::android::hardware::radio::RadioAccessFamily::HSPA == + static_cast( + ::android::hardware::radio::V1_4::RadioAccessFamily::HSPA)); +static_assert(aidl::android::hardware::radio::RadioAccessFamily::EVDO_B == + static_cast( + ::android::hardware::radio::V1_4::RadioAccessFamily::EVDO_B)); +static_assert(aidl::android::hardware::radio::RadioAccessFamily::EHRPD == + static_cast( + ::android::hardware::radio::V1_4::RadioAccessFamily::EHRPD)); +static_assert(aidl::android::hardware::radio::RadioAccessFamily::LTE == + static_cast( + ::android::hardware::radio::V1_4::RadioAccessFamily::LTE)); +static_assert(aidl::android::hardware::radio::RadioAccessFamily::HSPAP == + static_cast( + ::android::hardware::radio::V1_4::RadioAccessFamily::HSPAP)); +static_assert(aidl::android::hardware::radio::RadioAccessFamily::GSM == + static_cast( + ::android::hardware::radio::V1_4::RadioAccessFamily::GSM)); +static_assert(aidl::android::hardware::radio::RadioAccessFamily::TD_SCDMA == + static_cast( + ::android::hardware::radio::V1_4::RadioAccessFamily::TD_SCDMA)); +static_assert(aidl::android::hardware::radio::RadioAccessFamily::LTE_CA == + static_cast( + ::android::hardware::radio::V1_4::RadioAccessFamily::LTE_CA)); +static_assert(aidl::android::hardware::radio::RadioAccessFamily::NR == + static_cast( + ::android::hardware::radio::V1_4::RadioAccessFamily::NR)); + +static_assert(aidl::android::hardware::radio::FrequencyRange::LOW == + static_cast( + ::android::hardware::radio::V1_4::FrequencyRange::LOW)); +static_assert(aidl::android::hardware::radio::FrequencyRange::MID == + static_cast( + ::android::hardware::radio::V1_4::FrequencyRange::MID)); +static_assert(aidl::android::hardware::radio::FrequencyRange::HIGH == + static_cast( + ::android::hardware::radio::V1_4::FrequencyRange::HIGH)); +static_assert(aidl::android::hardware::radio::FrequencyRange::MMWAVE == + static_cast( + ::android::hardware::radio::V1_4::FrequencyRange::MMWAVE)); + +static_assert(aidl::android::hardware::radio::DataConnActiveStatus::INACTIVE == + static_cast( + ::android::hardware::radio::V1_4::DataConnActiveStatus::INACTIVE)); +static_assert(aidl::android::hardware::radio::DataConnActiveStatus::DORMANT == + static_cast( + ::android::hardware::radio::V1_4::DataConnActiveStatus::DORMANT)); +static_assert(aidl::android::hardware::radio::DataConnActiveStatus::ACTIVE == + static_cast( + ::android::hardware::radio::V1_4::DataConnActiveStatus::ACTIVE)); + +static_assert(aidl::android::hardware::radio::PdpProtocolType::UNKNOWN == + static_cast( + ::android::hardware::radio::V1_4::PdpProtocolType::UNKNOWN)); +static_assert(aidl::android::hardware::radio::PdpProtocolType::IP == + static_cast( + ::android::hardware::radio::V1_4::PdpProtocolType::IP)); +static_assert(aidl::android::hardware::radio::PdpProtocolType::IPV6 == + static_cast( + ::android::hardware::radio::V1_4::PdpProtocolType::IPV6)); +static_assert(aidl::android::hardware::radio::PdpProtocolType::IPV4V6 == + static_cast( + ::android::hardware::radio::V1_4::PdpProtocolType::IPV4V6)); +static_assert(aidl::android::hardware::radio::PdpProtocolType::PPP == + static_cast( + ::android::hardware::radio::V1_4::PdpProtocolType::PPP)); +static_assert(aidl::android::hardware::radio::PdpProtocolType::NON_IP == + static_cast( + ::android::hardware::radio::V1_4::PdpProtocolType::NON_IP)); +static_assert(aidl::android::hardware::radio::PdpProtocolType::UNSTRUCTURED == + static_cast( + ::android::hardware::radio::V1_4::PdpProtocolType::UNSTRUCTURED)); + +static_assert(aidl::android::hardware::radio::AccessNetwork::GERAN == + static_cast( + ::android::hardware::radio::V1_5::AccessNetwork::GERAN)); +static_assert(aidl::android::hardware::radio::AccessNetwork::UTRAN == + static_cast( + ::android::hardware::radio::V1_5::AccessNetwork::UTRAN)); +static_assert(aidl::android::hardware::radio::AccessNetwork::EUTRAN == + static_cast( + ::android::hardware::radio::V1_5::AccessNetwork::EUTRAN)); +static_assert(aidl::android::hardware::radio::AccessNetwork::CDMA2000 == + static_cast( + ::android::hardware::radio::V1_5::AccessNetwork::CDMA2000)); +static_assert(aidl::android::hardware::radio::AccessNetwork::IWLAN == + static_cast( + ::android::hardware::radio::V1_5::AccessNetwork::IWLAN)); +static_assert(aidl::android::hardware::radio::AccessNetwork::UNKNOWN == + static_cast( + ::android::hardware::radio::V1_5::AccessNetwork::UNKNOWN)); +static_assert(aidl::android::hardware::radio::AccessNetwork::NGRAN == + static_cast( + ::android::hardware::radio::V1_5::AccessNetwork::NGRAN)); + +static_assert(aidl::android::hardware::radio::SignalMeasurementType::RSSI == + static_cast( + ::android::hardware::radio::V1_5::SignalMeasurementType::RSSI)); +static_assert(aidl::android::hardware::radio::SignalMeasurementType::RSCP == + static_cast( + ::android::hardware::radio::V1_5::SignalMeasurementType::RSCP)); +static_assert(aidl::android::hardware::radio::SignalMeasurementType::RSRP == + static_cast( + ::android::hardware::radio::V1_5::SignalMeasurementType::RSRP)); +static_assert(aidl::android::hardware::radio::SignalMeasurementType::RSRQ == + static_cast( + ::android::hardware::radio::V1_5::SignalMeasurementType::RSRQ)); +static_assert(aidl::android::hardware::radio::SignalMeasurementType::RSSNR == + static_cast( + ::android::hardware::radio::V1_5::SignalMeasurementType::RSSNR)); +static_assert(aidl::android::hardware::radio::SignalMeasurementType::SSRSRP == + static_cast( + ::android::hardware::radio::V1_5::SignalMeasurementType::SSRSRP)); +static_assert(aidl::android::hardware::radio::SignalMeasurementType::SSRSRQ == + static_cast( + ::android::hardware::radio::V1_5::SignalMeasurementType::SSRSRQ)); +static_assert(aidl::android::hardware::radio::SignalMeasurementType::SSSINR == + static_cast( + ::android::hardware::radio::V1_5::SignalMeasurementType::SSSINR)); + +static_assert(aidl::android::hardware::radio::SimLockMultiSimPolicy::NO_MULTISIM_POLICY == + static_cast( + ::android::hardware::radio::V1_4::SimLockMultiSimPolicy::NO_MULTISIM_POLICY)); +static_assert( + aidl::android::hardware::radio::SimLockMultiSimPolicy::ONE_VALID_SIM_MUST_BE_PRESENT == + static_cast( + ::android::hardware::radio::V1_4::SimLockMultiSimPolicy:: + ONE_VALID_SIM_MUST_BE_PRESENT)); + +static_assert(aidl::android::hardware::radio::RadioAccessNetworks::GERAN == + static_cast( + ::android::hardware::radio::V1_5::RadioAccessNetworks::GERAN)); +static_assert(aidl::android::hardware::radio::RadioAccessNetworks::UTRAN == + static_cast( + ::android::hardware::radio::V1_5::RadioAccessNetworks::UTRAN)); +static_assert(aidl::android::hardware::radio::RadioAccessNetworks::EUTRAN == + static_cast( + ::android::hardware::radio::V1_5::RadioAccessNetworks::EUTRAN)); +static_assert(aidl::android::hardware::radio::RadioAccessNetworks::UNKNOWN == + static_cast( + ::android::hardware::radio::V1_5::RadioAccessNetworks::UNKNOWN)); +static_assert(aidl::android::hardware::radio::RadioAccessNetworks::NGRAN == + static_cast( + ::android::hardware::radio::V1_5::RadioAccessNetworks::NGRAN)); +static_assert(aidl::android::hardware::radio::RadioAccessNetworks::CDMA2000 == + static_cast( + ::android::hardware::radio::V1_5::RadioAccessNetworks::CDMA2000)); + +static_assert(aidl::android::hardware::radio::UtranBands::BAND_1 == + static_cast( + ::android::hardware::radio::V1_5::UtranBands::BAND_1)); +static_assert(aidl::android::hardware::radio::UtranBands::BAND_2 == + static_cast( + ::android::hardware::radio::V1_5::UtranBands::BAND_2)); +static_assert(aidl::android::hardware::radio::UtranBands::BAND_3 == + static_cast( + ::android::hardware::radio::V1_5::UtranBands::BAND_3)); +static_assert(aidl::android::hardware::radio::UtranBands::BAND_4 == + static_cast( + ::android::hardware::radio::V1_5::UtranBands::BAND_4)); +static_assert(aidl::android::hardware::radio::UtranBands::BAND_5 == + static_cast( + ::android::hardware::radio::V1_5::UtranBands::BAND_5)); +static_assert(aidl::android::hardware::radio::UtranBands::BAND_6 == + static_cast( + ::android::hardware::radio::V1_5::UtranBands::BAND_6)); +static_assert(aidl::android::hardware::radio::UtranBands::BAND_7 == + static_cast( + ::android::hardware::radio::V1_5::UtranBands::BAND_7)); +static_assert(aidl::android::hardware::radio::UtranBands::BAND_8 == + static_cast( + ::android::hardware::radio::V1_5::UtranBands::BAND_8)); +static_assert(aidl::android::hardware::radio::UtranBands::BAND_9 == + static_cast( + ::android::hardware::radio::V1_5::UtranBands::BAND_9)); +static_assert(aidl::android::hardware::radio::UtranBands::BAND_10 == + static_cast( + ::android::hardware::radio::V1_5::UtranBands::BAND_10)); +static_assert(aidl::android::hardware::radio::UtranBands::BAND_11 == + static_cast( + ::android::hardware::radio::V1_5::UtranBands::BAND_11)); +static_assert(aidl::android::hardware::radio::UtranBands::BAND_12 == + static_cast( + ::android::hardware::radio::V1_5::UtranBands::BAND_12)); +static_assert(aidl::android::hardware::radio::UtranBands::BAND_13 == + static_cast( + ::android::hardware::radio::V1_5::UtranBands::BAND_13)); +static_assert(aidl::android::hardware::radio::UtranBands::BAND_14 == + static_cast( + ::android::hardware::radio::V1_5::UtranBands::BAND_14)); +static_assert(aidl::android::hardware::radio::UtranBands::BAND_19 == + static_cast( + ::android::hardware::radio::V1_5::UtranBands::BAND_19)); +static_assert(aidl::android::hardware::radio::UtranBands::BAND_20 == + static_cast( + ::android::hardware::radio::V1_5::UtranBands::BAND_20)); +static_assert(aidl::android::hardware::radio::UtranBands::BAND_21 == + static_cast( + ::android::hardware::radio::V1_5::UtranBands::BAND_21)); +static_assert(aidl::android::hardware::radio::UtranBands::BAND_22 == + static_cast( + ::android::hardware::radio::V1_5::UtranBands::BAND_22)); +static_assert(aidl::android::hardware::radio::UtranBands::BAND_25 == + static_cast( + ::android::hardware::radio::V1_5::UtranBands::BAND_25)); +static_assert(aidl::android::hardware::radio::UtranBands::BAND_26 == + static_cast( + ::android::hardware::radio::V1_5::UtranBands::BAND_26)); +static_assert(aidl::android::hardware::radio::UtranBands::BAND_A == + static_cast( + ::android::hardware::radio::V1_5::UtranBands::BAND_A)); +static_assert(aidl::android::hardware::radio::UtranBands::BAND_B == + static_cast( + ::android::hardware::radio::V1_5::UtranBands::BAND_B)); +static_assert(aidl::android::hardware::radio::UtranBands::BAND_C == + static_cast( + ::android::hardware::radio::V1_5::UtranBands::BAND_C)); +static_assert(aidl::android::hardware::radio::UtranBands::BAND_D == + static_cast( + ::android::hardware::radio::V1_5::UtranBands::BAND_D)); +static_assert(aidl::android::hardware::radio::UtranBands::BAND_E == + static_cast( + ::android::hardware::radio::V1_5::UtranBands::BAND_E)); +static_assert(aidl::android::hardware::radio::UtranBands::BAND_F == + static_cast( + ::android::hardware::radio::V1_5::UtranBands::BAND_F)); + +static_assert(aidl::android::hardware::radio::EutranBands::BAND_1 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_1)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_2 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_2)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_3 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_3)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_4 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_4)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_5 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_5)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_6 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_6)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_7 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_7)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_8 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_8)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_9 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_9)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_10 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_10)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_11 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_11)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_12 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_12)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_13 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_13)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_14 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_14)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_17 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_17)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_18 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_18)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_19 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_19)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_20 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_20)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_21 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_21)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_22 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_22)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_23 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_23)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_24 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_24)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_25 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_25)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_26 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_26)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_27 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_27)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_28 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_28)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_30 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_30)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_31 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_31)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_33 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_33)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_34 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_34)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_35 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_35)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_36 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_36)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_37 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_37)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_38 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_38)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_39 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_39)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_40 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_40)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_41 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_41)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_42 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_42)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_43 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_43)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_44 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_44)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_45 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_45)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_46 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_46)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_47 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_47)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_48 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_48)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_65 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_65)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_66 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_66)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_68 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_68)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_70 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_70)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_49 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_49)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_50 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_50)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_51 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_51)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_52 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_52)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_53 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_53)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_71 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_71)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_72 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_72)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_73 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_73)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_74 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_74)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_85 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_85)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_87 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_87)); +static_assert(aidl::android::hardware::radio::EutranBands::BAND_88 == + static_cast( + ::android::hardware::radio::V1_5::EutranBands::BAND_88)); + +static_assert(aidl::android::hardware::radio::ApnTypes::NONE == + static_cast( + ::android::hardware::radio::V1_5::ApnTypes::NONE)); +static_assert(aidl::android::hardware::radio::ApnTypes::DEFAULT == + static_cast( + ::android::hardware::radio::V1_5::ApnTypes::DEFAULT)); +static_assert(aidl::android::hardware::radio::ApnTypes::MMS == + static_cast( + ::android::hardware::radio::V1_5::ApnTypes::MMS)); +static_assert(aidl::android::hardware::radio::ApnTypes::SUPL == + static_cast( + ::android::hardware::radio::V1_5::ApnTypes::SUPL)); +static_assert(aidl::android::hardware::radio::ApnTypes::DUN == + static_cast( + ::android::hardware::radio::V1_5::ApnTypes::DUN)); +static_assert(aidl::android::hardware::radio::ApnTypes::HIPRI == + static_cast( + ::android::hardware::radio::V1_5::ApnTypes::HIPRI)); +static_assert(aidl::android::hardware::radio::ApnTypes::FOTA == + static_cast( + ::android::hardware::radio::V1_5::ApnTypes::FOTA)); +static_assert(aidl::android::hardware::radio::ApnTypes::IMS == + static_cast( + ::android::hardware::radio::V1_5::ApnTypes::IMS)); +static_assert(aidl::android::hardware::radio::ApnTypes::CBS == + static_cast( + ::android::hardware::radio::V1_5::ApnTypes::CBS)); +static_assert(aidl::android::hardware::radio::ApnTypes::IA == + static_cast( + ::android::hardware::radio::V1_5::ApnTypes::IA)); +static_assert(aidl::android::hardware::radio::ApnTypes::EMERGENCY == + static_cast( + ::android::hardware::radio::V1_5::ApnTypes::EMERGENCY)); +static_assert(aidl::android::hardware::radio::ApnTypes::ALL == + static_cast( + ::android::hardware::radio::V1_5::ApnTypes::ALL)); +static_assert(aidl::android::hardware::radio::ApnTypes::MCX == + static_cast( + ::android::hardware::radio::V1_5::ApnTypes::MCX)); +static_assert(aidl::android::hardware::radio::ApnTypes::XCAP == + static_cast( + ::android::hardware::radio::V1_5::ApnTypes::XCAP)); + +static_assert(aidl::android::hardware::radio::AddressProperty::NONE == + static_cast( + ::android::hardware::radio::V1_5::AddressProperty::NONE)); +static_assert(aidl::android::hardware::radio::AddressProperty::DEPRECATED == + static_cast( + ::android::hardware::radio::V1_5::AddressProperty::DEPRECATED)); + +static_assert(aidl::android::hardware::radio::Domain::CS == + static_cast( + ::android::hardware::radio::V1_5::Domain::CS)); +static_assert(aidl::android::hardware::radio::Domain::PS == + static_cast( + ::android::hardware::radio::V1_5::Domain::PS)); + +static_assert(aidl::android::hardware::radio::BarringInfoServiceType::CS_SERVICE == + static_cast( + ::android::hardware::radio::V1_5::BarringInfo::ServiceType::CS_SERVICE)); +static_assert(aidl::android::hardware::radio::BarringInfoServiceType::PS_SERVICE == + static_cast( + ::android::hardware::radio::V1_5::BarringInfo::ServiceType::PS_SERVICE)); +static_assert(aidl::android::hardware::radio::BarringInfoServiceType::CS_VOICE == + static_cast( + ::android::hardware::radio::V1_5::BarringInfo::ServiceType::CS_VOICE)); +static_assert(aidl::android::hardware::radio::BarringInfoServiceType::MO_SIGNALLING == + static_cast( + ::android::hardware::radio::V1_5::BarringInfo::ServiceType::MO_SIGNALLING)); +static_assert(aidl::android::hardware::radio::BarringInfoServiceType::MO_DATA == + static_cast( + ::android::hardware::radio::V1_5::BarringInfo::ServiceType::MO_DATA)); +static_assert(aidl::android::hardware::radio::BarringInfoServiceType::CS_FALLBACK == + static_cast( + ::android::hardware::radio::V1_5::BarringInfo::ServiceType::CS_FALLBACK)); +static_assert(aidl::android::hardware::radio::BarringInfoServiceType::MMTEL_VOICE == + static_cast( + ::android::hardware::radio::V1_5::BarringInfo::ServiceType::MMTEL_VOICE)); +static_assert(aidl::android::hardware::radio::BarringInfoServiceType::MMTEL_VIDEO == + static_cast( + ::android::hardware::radio::V1_5::BarringInfo::ServiceType::MMTEL_VIDEO)); +static_assert(aidl::android::hardware::radio::BarringInfoServiceType::EMERGENCY == + static_cast( + ::android::hardware::radio::V1_5::BarringInfo::ServiceType::EMERGENCY)); +static_assert(aidl::android::hardware::radio::BarringInfoServiceType::SMS == + static_cast( + ::android::hardware::radio::V1_5::BarringInfo::ServiceType::SMS)); +static_assert(aidl::android::hardware::radio::BarringInfoServiceType::OPERATOR_1 == + static_cast( + ::android::hardware::radio::V1_5::BarringInfo::ServiceType::OPERATOR_1)); +static_assert(aidl::android::hardware::radio::BarringInfoServiceType::OPERATOR_2 == + static_cast( + ::android::hardware::radio::V1_5::BarringInfo::ServiceType::OPERATOR_2)); +static_assert(aidl::android::hardware::radio::BarringInfoServiceType::OPERATOR_3 == + static_cast( + ::android::hardware::radio::V1_5::BarringInfo::ServiceType::OPERATOR_3)); +static_assert(aidl::android::hardware::radio::BarringInfoServiceType::OPERATOR_4 == + static_cast( + ::android::hardware::radio::V1_5::BarringInfo::ServiceType::OPERATOR_4)); +static_assert(aidl::android::hardware::radio::BarringInfoServiceType::OPERATOR_5 == + static_cast( + ::android::hardware::radio::V1_5::BarringInfo::ServiceType::OPERATOR_5)); +static_assert(aidl::android::hardware::radio::BarringInfoServiceType::OPERATOR_6 == + static_cast( + ::android::hardware::radio::V1_5::BarringInfo::ServiceType::OPERATOR_6)); +static_assert(aidl::android::hardware::radio::BarringInfoServiceType::OPERATOR_7 == + static_cast( + ::android::hardware::radio::V1_5::BarringInfo::ServiceType::OPERATOR_7)); +static_assert(aidl::android::hardware::radio::BarringInfoServiceType::OPERATOR_8 == + static_cast( + ::android::hardware::radio::V1_5::BarringInfo::ServiceType::OPERATOR_8)); +static_assert(aidl::android::hardware::radio::BarringInfoServiceType::OPERATOR_9 == + static_cast( + ::android::hardware::radio::V1_5::BarringInfo::ServiceType::OPERATOR_9)); +static_assert(aidl::android::hardware::radio::BarringInfoServiceType::OPERATOR_10 == + static_cast( + ::android::hardware::radio::V1_5::BarringInfo::ServiceType::OPERATOR_10)); +static_assert(aidl::android::hardware::radio::BarringInfoServiceType::OPERATOR_11 == + static_cast( + ::android::hardware::radio::V1_5::BarringInfo::ServiceType::OPERATOR_11)); +static_assert(aidl::android::hardware::radio::BarringInfoServiceType::OPERATOR_12 == + static_cast( + ::android::hardware::radio::V1_5::BarringInfo::ServiceType::OPERATOR_12)); +static_assert(aidl::android::hardware::radio::BarringInfoServiceType::OPERATOR_13 == + static_cast( + ::android::hardware::radio::V1_5::BarringInfo::ServiceType::OPERATOR_13)); +static_assert(aidl::android::hardware::radio::BarringInfoServiceType::OPERATOR_14 == + static_cast( + ::android::hardware::radio::V1_5::BarringInfo::ServiceType::OPERATOR_14)); +static_assert(aidl::android::hardware::radio::BarringInfoServiceType::OPERATOR_15 == + static_cast( + ::android::hardware::radio::V1_5::BarringInfo::ServiceType::OPERATOR_15)); +static_assert(aidl::android::hardware::radio::BarringInfoServiceType::OPERATOR_16 == + static_cast( + ::android::hardware::radio::V1_5::BarringInfo::ServiceType::OPERATOR_16)); +static_assert(aidl::android::hardware::radio::BarringInfoServiceType::OPERATOR_17 == + static_cast( + ::android::hardware::radio::V1_5::BarringInfo::ServiceType::OPERATOR_17)); +static_assert(aidl::android::hardware::radio::BarringInfoServiceType::OPERATOR_18 == + static_cast( + ::android::hardware::radio::V1_5::BarringInfo::ServiceType::OPERATOR_18)); +static_assert(aidl::android::hardware::radio::BarringInfoServiceType::OPERATOR_19 == + static_cast( + ::android::hardware::radio::V1_5::BarringInfo::ServiceType::OPERATOR_19)); +static_assert(aidl::android::hardware::radio::BarringInfoServiceType::OPERATOR_20 == + static_cast( + ::android::hardware::radio::V1_5::BarringInfo::ServiceType::OPERATOR_20)); +static_assert(aidl::android::hardware::radio::BarringInfoServiceType::OPERATOR_21 == + static_cast( + ::android::hardware::radio::V1_5::BarringInfo::ServiceType::OPERATOR_21)); +static_assert(aidl::android::hardware::radio::BarringInfoServiceType::OPERATOR_22 == + static_cast( + ::android::hardware::radio::V1_5::BarringInfo::ServiceType::OPERATOR_22)); +static_assert(aidl::android::hardware::radio::BarringInfoServiceType::OPERATOR_23 == + static_cast( + ::android::hardware::radio::V1_5::BarringInfo::ServiceType::OPERATOR_23)); +static_assert(aidl::android::hardware::radio::BarringInfoServiceType::OPERATOR_24 == + static_cast( + ::android::hardware::radio::V1_5::BarringInfo::ServiceType::OPERATOR_24)); +static_assert(aidl::android::hardware::radio::BarringInfoServiceType::OPERATOR_25 == + static_cast( + ::android::hardware::radio::V1_5::BarringInfo::ServiceType::OPERATOR_25)); +static_assert(aidl::android::hardware::radio::BarringInfoServiceType::OPERATOR_26 == + static_cast( + ::android::hardware::radio::V1_5::BarringInfo::ServiceType::OPERATOR_26)); +static_assert(aidl::android::hardware::radio::BarringInfoServiceType::OPERATOR_27 == + static_cast( + ::android::hardware::radio::V1_5::BarringInfo::ServiceType::OPERATOR_27)); +static_assert(aidl::android::hardware::radio::BarringInfoServiceType::OPERATOR_28 == + static_cast( + ::android::hardware::radio::V1_5::BarringInfo::ServiceType::OPERATOR_28)); +static_assert(aidl::android::hardware::radio::BarringInfoServiceType::OPERATOR_29 == + static_cast( + ::android::hardware::radio::V1_5::BarringInfo::ServiceType::OPERATOR_29)); +static_assert(aidl::android::hardware::radio::BarringInfoServiceType::OPERATOR_30 == + static_cast( + ::android::hardware::radio::V1_5::BarringInfo::ServiceType::OPERATOR_30)); +static_assert(aidl::android::hardware::radio::BarringInfoServiceType::OPERATOR_31 == + static_cast( + ::android::hardware::radio::V1_5::BarringInfo::ServiceType::OPERATOR_31)); +static_assert(aidl::android::hardware::radio::BarringInfoServiceType::OPERATOR_32 == + static_cast( + ::android::hardware::radio::V1_5::BarringInfo::ServiceType::OPERATOR_32)); + +static_assert(aidl::android::hardware::radio::BarringInfoBarringType::NONE == + static_cast( + ::android::hardware::radio::V1_5::BarringInfo::BarringType::NONE)); +static_assert(aidl::android::hardware::radio::BarringInfoBarringType::CONDITIONAL == + static_cast( + ::android::hardware::radio::V1_5::BarringInfo::BarringType::CONDITIONAL)); +static_assert(aidl::android::hardware::radio::BarringInfoBarringType::UNCONDITIONAL == + static_cast( + ::android::hardware::radio::V1_5::BarringInfo::BarringType::UNCONDITIONAL)); + +static_assert(aidl::android::hardware::radio::IndicationFilter::NONE == + static_cast( + ::android::hardware::radio::V1_5::IndicationFilter::NONE)); +static_assert(aidl::android::hardware::radio::IndicationFilter::ALL == + static_cast( + ::android::hardware::radio::V1_5::IndicationFilter::ALL)); +static_assert(aidl::android::hardware::radio::IndicationFilter::SIGNAL_STRENGTH == + static_cast( + ::android::hardware::radio::V1_5::IndicationFilter::SIGNAL_STRENGTH)); +static_assert(aidl::android::hardware::radio::IndicationFilter::FULL_NETWORK_STATE == + static_cast( + ::android::hardware::radio::V1_5::IndicationFilter::FULL_NETWORK_STATE)); +static_assert( + aidl::android::hardware::radio::IndicationFilter::DATA_CALL_DORMANCY_CHANGED == + static_cast( + ::android::hardware::radio::V1_5::IndicationFilter::DATA_CALL_DORMANCY_CHANGED)); +static_assert(aidl::android::hardware::radio::IndicationFilter::LINK_CAPACITY_ESTIMATE == + static_cast( + ::android::hardware::radio::V1_5::IndicationFilter::LINK_CAPACITY_ESTIMATE)); +static_assert(aidl::android::hardware::radio::IndicationFilter::PHYSICAL_CHANNEL_CONFIG == + static_cast( + ::android::hardware::radio::V1_5::IndicationFilter::PHYSICAL_CHANNEL_CONFIG)); +static_assert(aidl::android::hardware::radio::IndicationFilter::REGISTRATION_FAILURE == + static_cast( + ::android::hardware::radio::V1_5::IndicationFilter::REGISTRATION_FAILURE)); +static_assert(aidl::android::hardware::radio::IndicationFilter::BARRING_INFO == + static_cast( + ::android::hardware::radio::V1_5::IndicationFilter::BARRING_INFO)); + +static_assert(aidl::android::hardware::radio::RegistrationFailCause::NONE == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause::NONE)); +static_assert( + aidl::android::hardware::radio::RegistrationFailCause::IMSI_UNKNOWN_IN_HLR == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause::IMSI_UNKNOWN_IN_HLR)); +static_assert(aidl::android::hardware::radio::RegistrationFailCause::ILLEGAL_MS == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause::ILLEGAL_MS)); +static_assert( + aidl::android::hardware::radio::RegistrationFailCause::IMSI_UNKNOWN_IN_VLR == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause::IMSI_UNKNOWN_IN_VLR)); +static_assert(aidl::android::hardware::radio::RegistrationFailCause::IMEI_NOT_ACCEPTED == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause::IMEI_NOT_ACCEPTED)); +static_assert(aidl::android::hardware::radio::RegistrationFailCause::ILLEGAL_ME == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause::ILLEGAL_ME)); +static_assert(aidl::android::hardware::radio::RegistrationFailCause::GPRS_SERVICES_NOT_ALLOWED == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause:: + GPRS_SERVICES_NOT_ALLOWED)); +static_assert(aidl::android::hardware::radio::RegistrationFailCause:: + GPRS_AND_NON_GPRS_SERVICES_NOT_ALLOWED == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause:: + GPRS_AND_NON_GPRS_SERVICES_NOT_ALLOWED)); +static_assert(aidl::android::hardware::radio::RegistrationFailCause:: + MS_IDENTITY_CANNOT_BE_DERIVED_BY_NETWORK == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause:: + MS_IDENTITY_CANNOT_BE_DERIVED_BY_NETWORK)); +static_assert( + aidl::android::hardware::radio::RegistrationFailCause::IMPLICITLY_DETACHED == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause::IMPLICITLY_DETACHED)); +static_assert(aidl::android::hardware::radio::RegistrationFailCause::PLMN_NOT_ALLOWED == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause::PLMN_NOT_ALLOWED)); +static_assert(aidl::android::hardware::radio::RegistrationFailCause::LOCATION_AREA_NOT_ALLOWED == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause:: + LOCATION_AREA_NOT_ALLOWED)); +static_assert( + aidl::android::hardware::radio::RegistrationFailCause::ROAMING_NOT_ALLOWED == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause::ROAMING_NOT_ALLOWED)); +static_assert( + aidl::android::hardware::radio::RegistrationFailCause::GPRS_SERVICES_NOT_ALLOWED_IN_PLMN == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause:: + GPRS_SERVICES_NOT_ALLOWED_IN_PLMN)); +static_assert(aidl::android::hardware::radio::RegistrationFailCause::NO_SUITABLE_CELLS == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause::NO_SUITABLE_CELLS)); +static_assert( + aidl::android::hardware::radio::RegistrationFailCause::MSC_TEMPORARILY_NOT_REACHABLE == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause:: + MSC_TEMPORARILY_NOT_REACHABLE)); +static_assert(aidl::android::hardware::radio::RegistrationFailCause::NETWORK_FAILURE == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause::NETWORK_FAILURE)); +static_assert(aidl::android::hardware::radio::RegistrationFailCause::MAC_FAILURE == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause::MAC_FAILURE)); +static_assert(aidl::android::hardware::radio::RegistrationFailCause::SYNC_FAILURE == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause::SYNC_FAILURE)); +static_assert(aidl::android::hardware::radio::RegistrationFailCause::CONGESTION == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause::CONGESTION)); +static_assert( + aidl::android::hardware::radio::RegistrationFailCause::GSM_AUTHENTICATION_UNACCEPTABLE == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause:: + GSM_AUTHENTICATION_UNACCEPTABLE)); +static_assert(aidl::android::hardware::radio::RegistrationFailCause::NOT_AUTHORIZED_FOR_THIS_CSG == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause:: + NOT_AUTHORIZED_FOR_THIS_CSG)); +static_assert(aidl::android::hardware::radio::RegistrationFailCause:: + SMS_PROVIDED_BY_GPRS_IN_ROUTING_AREA == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause:: + SMS_PROVIDED_BY_GPRS_IN_ROUTING_AREA)); +static_assert(aidl::android::hardware::radio::RegistrationFailCause::SERVICE_OPTION_NOT_SUPPORTED == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause:: + SERVICE_OPTION_NOT_SUPPORTED)); +static_assert( + aidl::android::hardware::radio::RegistrationFailCause::SERVICE_OPTION_NOT_SUBSCRIBED == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause:: + SERVICE_OPTION_NOT_SUBSCRIBED)); +static_assert(aidl::android::hardware::radio::RegistrationFailCause:: + SERVICE_OPTION_TEMPORARILY_OUT_OF_ORDER == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause:: + SERVICE_OPTION_TEMPORARILY_OUT_OF_ORDER)); +static_assert(aidl::android::hardware::radio::RegistrationFailCause::CALL_CANNOT_BE_IDENTIFIED == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause:: + CALL_CANNOT_BE_IDENTIFIED)); +static_assert( + aidl::android::hardware::radio::RegistrationFailCause::NO_PDP_CONTEXT_ACTIVATED == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause::NO_PDP_CONTEXT_ACTIVATED)); +static_assert( + aidl::android::hardware::radio::RegistrationFailCause::RETRY_UPON_ENTRY_INTO_NEW_CELL_1 == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause:: + RETRY_UPON_ENTRY_INTO_NEW_CELL_1)); +static_assert( + aidl::android::hardware::radio::RegistrationFailCause::RETRY_UPON_ENTRY_INTO_NEW_CELL_2 == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause:: + RETRY_UPON_ENTRY_INTO_NEW_CELL_2)); +static_assert( + aidl::android::hardware::radio::RegistrationFailCause::RETRY_UPON_ENTRY_INTO_NEW_CELL_3 == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause:: + RETRY_UPON_ENTRY_INTO_NEW_CELL_3)); +static_assert( + aidl::android::hardware::radio::RegistrationFailCause::RETRY_UPON_ENTRY_INTO_NEW_CELL_4 == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause:: + RETRY_UPON_ENTRY_INTO_NEW_CELL_4)); +static_assert( + aidl::android::hardware::radio::RegistrationFailCause::RETRY_UPON_ENTRY_INTO_NEW_CELL_5 == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause:: + RETRY_UPON_ENTRY_INTO_NEW_CELL_5)); +static_assert( + aidl::android::hardware::radio::RegistrationFailCause::RETRY_UPON_ENTRY_INTO_NEW_CELL_6 == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause:: + RETRY_UPON_ENTRY_INTO_NEW_CELL_6)); +static_assert( + aidl::android::hardware::radio::RegistrationFailCause::RETRY_UPON_ENTRY_INTO_NEW_CELL_7 == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause:: + RETRY_UPON_ENTRY_INTO_NEW_CELL_7)); +static_assert( + aidl::android::hardware::radio::RegistrationFailCause::RETRY_UPON_ENTRY_INTO_NEW_CELL_8 == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause:: + RETRY_UPON_ENTRY_INTO_NEW_CELL_8)); +static_assert( + aidl::android::hardware::radio::RegistrationFailCause::RETRY_UPON_ENTRY_INTO_NEW_CELL_9 == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause:: + RETRY_UPON_ENTRY_INTO_NEW_CELL_9)); +static_assert( + aidl::android::hardware::radio::RegistrationFailCause::RETRY_UPON_ENTRY_INTO_NEW_CELL_10 == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause:: + RETRY_UPON_ENTRY_INTO_NEW_CELL_10)); +static_assert( + aidl::android::hardware::radio::RegistrationFailCause::RETRY_UPON_ENTRY_INTO_NEW_CELL_11 == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause:: + RETRY_UPON_ENTRY_INTO_NEW_CELL_11)); +static_assert( + aidl::android::hardware::radio::RegistrationFailCause::RETRY_UPON_ENTRY_INTO_NEW_CELL_12 == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause:: + RETRY_UPON_ENTRY_INTO_NEW_CELL_12)); +static_assert( + aidl::android::hardware::radio::RegistrationFailCause::RETRY_UPON_ENTRY_INTO_NEW_CELL_13 == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause:: + RETRY_UPON_ENTRY_INTO_NEW_CELL_13)); +static_assert( + aidl::android::hardware::radio::RegistrationFailCause::RETRY_UPON_ENTRY_INTO_NEW_CELL_14 == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause:: + RETRY_UPON_ENTRY_INTO_NEW_CELL_14)); +static_assert( + aidl::android::hardware::radio::RegistrationFailCause::RETRY_UPON_ENTRY_INTO_NEW_CELL_15 == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause:: + RETRY_UPON_ENTRY_INTO_NEW_CELL_15)); +static_assert( + aidl::android::hardware::radio::RegistrationFailCause::RETRY_UPON_ENTRY_INTO_NEW_CELL_16 == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause:: + RETRY_UPON_ENTRY_INTO_NEW_CELL_16)); +static_assert( + aidl::android::hardware::radio::RegistrationFailCause::SEMANTICALLY_INCORRECT_MESSAGE == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause:: + SEMANTICALLY_INCORRECT_MESSAGE)); +static_assert( + aidl::android::hardware::radio::RegistrationFailCause::INVALID_MANDATORY_INFORMATION == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause:: + INVALID_MANDATORY_INFORMATION)); +static_assert(aidl::android::hardware::radio::RegistrationFailCause:: + MESSAGE_TYPE_NON_EXISTENT_OR_NOT_IMPLEMENTED == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause:: + MESSAGE_TYPE_NON_EXISTENT_OR_NOT_IMPLEMENTED)); +static_assert(aidl::android::hardware::radio::RegistrationFailCause:: + MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause:: + MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE)); +static_assert(aidl::android::hardware::radio::RegistrationFailCause:: + INFORMATION_ELEMENT_NON_EXISTENT_OR_NOT_IMPLEMENTED == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause:: + INFORMATION_ELEMENT_NON_EXISTENT_OR_NOT_IMPLEMENTED)); +static_assert( + aidl::android::hardware::radio::RegistrationFailCause::CONDITIONAL_IE_ERROR == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause::CONDITIONAL_IE_ERROR)); +static_assert(aidl::android::hardware::radio::RegistrationFailCause:: + MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause:: + MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE)); +static_assert(aidl::android::hardware::radio::RegistrationFailCause::PROTOCOL_ERROR_UNSPECIFIED == + static_cast( + ::android::hardware::radio::V1_5::RegistrationFailCause:: + PROTOCOL_ERROR_UNSPECIFIED)); + +static_assert(aidl::android::hardware::radio::PrlIndicator::NOT_REGISTERED == + static_cast( + ::android::hardware::radio::V1_5::PrlIndicator::NOT_REGISTERED)); +static_assert(aidl::android::hardware::radio::PrlIndicator::NOT_IN_PRL == + static_cast( + ::android::hardware::radio::V1_5::PrlIndicator::NOT_IN_PRL)); +static_assert(aidl::android::hardware::radio::PrlIndicator::IN_PRL == + static_cast( + ::android::hardware::radio::V1_5::PrlIndicator::IN_PRL)); + +static_assert(aidl::android::hardware::radio::PersoSubstate::UNKNOWN == + static_cast( + ::android::hardware::radio::V1_5::PersoSubstate::UNKNOWN)); +static_assert(aidl::android::hardware::radio::PersoSubstate::IN_PROGRESS == + static_cast( + ::android::hardware::radio::V1_5::PersoSubstate::IN_PROGRESS)); +static_assert(aidl::android::hardware::radio::PersoSubstate::READY == + static_cast( + ::android::hardware::radio::V1_5::PersoSubstate::READY)); +static_assert(aidl::android::hardware::radio::PersoSubstate::SIM_NETWORK == + static_cast( + ::android::hardware::radio::V1_5::PersoSubstate::SIM_NETWORK)); +static_assert(aidl::android::hardware::radio::PersoSubstate::SIM_NETWORK_SUBSET == + static_cast( + ::android::hardware::radio::V1_5::PersoSubstate::SIM_NETWORK_SUBSET)); +static_assert(aidl::android::hardware::radio::PersoSubstate::SIM_CORPORATE == + static_cast( + ::android::hardware::radio::V1_5::PersoSubstate::SIM_CORPORATE)); +static_assert(aidl::android::hardware::radio::PersoSubstate::SIM_SERVICE_PROVIDER == + static_cast( + ::android::hardware::radio::V1_5::PersoSubstate::SIM_SERVICE_PROVIDER)); +static_assert(aidl::android::hardware::radio::PersoSubstate::SIM_SIM == + static_cast( + ::android::hardware::radio::V1_5::PersoSubstate::SIM_SIM)); +static_assert(aidl::android::hardware::radio::PersoSubstate::SIM_NETWORK_PUK == + static_cast( + ::android::hardware::radio::V1_5::PersoSubstate::SIM_NETWORK_PUK)); +static_assert(aidl::android::hardware::radio::PersoSubstate::SIM_NETWORK_SUBSET_PUK == + static_cast( + ::android::hardware::radio::V1_5::PersoSubstate::SIM_NETWORK_SUBSET_PUK)); +static_assert(aidl::android::hardware::radio::PersoSubstate::SIM_CORPORATE_PUK == + static_cast( + ::android::hardware::radio::V1_5::PersoSubstate::SIM_CORPORATE_PUK)); +static_assert(aidl::android::hardware::radio::PersoSubstate::SIM_SERVICE_PROVIDER_PUK == + static_cast( + ::android::hardware::radio::V1_5::PersoSubstate::SIM_SERVICE_PROVIDER_PUK)); +static_assert(aidl::android::hardware::radio::PersoSubstate::SIM_SIM_PUK == + static_cast( + ::android::hardware::radio::V1_5::PersoSubstate::SIM_SIM_PUK)); +static_assert(aidl::android::hardware::radio::PersoSubstate::RUIM_NETWORK1 == + static_cast( + ::android::hardware::radio::V1_5::PersoSubstate::RUIM_NETWORK1)); +static_assert(aidl::android::hardware::radio::PersoSubstate::RUIM_NETWORK2 == + static_cast( + ::android::hardware::radio::V1_5::PersoSubstate::RUIM_NETWORK2)); +static_assert(aidl::android::hardware::radio::PersoSubstate::RUIM_HRPD == + static_cast( + ::android::hardware::radio::V1_5::PersoSubstate::RUIM_HRPD)); +static_assert(aidl::android::hardware::radio::PersoSubstate::RUIM_CORPORATE == + static_cast( + ::android::hardware::radio::V1_5::PersoSubstate::RUIM_CORPORATE)); +static_assert(aidl::android::hardware::radio::PersoSubstate::RUIM_SERVICE_PROVIDER == + static_cast( + ::android::hardware::radio::V1_5::PersoSubstate::RUIM_SERVICE_PROVIDER)); +static_assert(aidl::android::hardware::radio::PersoSubstate::RUIM_RUIM == + static_cast( + ::android::hardware::radio::V1_5::PersoSubstate::RUIM_RUIM)); +static_assert(aidl::android::hardware::radio::PersoSubstate::RUIM_NETWORK1_PUK == + static_cast( + ::android::hardware::radio::V1_5::PersoSubstate::RUIM_NETWORK1_PUK)); +static_assert(aidl::android::hardware::radio::PersoSubstate::RUIM_NETWORK2_PUK == + static_cast( + ::android::hardware::radio::V1_5::PersoSubstate::RUIM_NETWORK2_PUK)); +static_assert(aidl::android::hardware::radio::PersoSubstate::RUIM_HRPD_PUK == + static_cast( + ::android::hardware::radio::V1_5::PersoSubstate::RUIM_HRPD_PUK)); +static_assert(aidl::android::hardware::radio::PersoSubstate::RUIM_CORPORATE_PUK == + static_cast( + ::android::hardware::radio::V1_5::PersoSubstate::RUIM_CORPORATE_PUK)); +static_assert(aidl::android::hardware::radio::PersoSubstate::RUIM_SERVICE_PROVIDER_PUK == + static_cast( + ::android::hardware::radio::V1_5::PersoSubstate::RUIM_SERVICE_PROVIDER_PUK)); +static_assert(aidl::android::hardware::radio::PersoSubstate::RUIM_RUIM_PUK == + static_cast( + ::android::hardware::radio::V1_5::PersoSubstate::RUIM_RUIM_PUK)); +static_assert(aidl::android::hardware::radio::PersoSubstate::SIM_SPN == + static_cast( + ::android::hardware::radio::V1_5::PersoSubstate::SIM_SPN)); +static_assert(aidl::android::hardware::radio::PersoSubstate::SIM_SPN_PUK == + static_cast( + ::android::hardware::radio::V1_5::PersoSubstate::SIM_SPN_PUK)); +static_assert(aidl::android::hardware::radio::PersoSubstate::SIM_SP_EHPLMN == + static_cast( + ::android::hardware::radio::V1_5::PersoSubstate::SIM_SP_EHPLMN)); +static_assert(aidl::android::hardware::radio::PersoSubstate::SIM_SP_EHPLMN_PUK == + static_cast( + ::android::hardware::radio::V1_5::PersoSubstate::SIM_SP_EHPLMN_PUK)); +static_assert(aidl::android::hardware::radio::PersoSubstate::SIM_ICCID == + static_cast( + ::android::hardware::radio::V1_5::PersoSubstate::SIM_ICCID)); +static_assert(aidl::android::hardware::radio::PersoSubstate::SIM_ICCID_PUK == + static_cast( + ::android::hardware::radio::V1_5::PersoSubstate::SIM_ICCID_PUK)); +static_assert(aidl::android::hardware::radio::PersoSubstate::SIM_IMPI == + static_cast( + ::android::hardware::radio::V1_5::PersoSubstate::SIM_IMPI)); +static_assert(aidl::android::hardware::radio::PersoSubstate::SIM_IMPI_PUK == + static_cast( + ::android::hardware::radio::V1_5::PersoSubstate::SIM_IMPI_PUK)); +static_assert(aidl::android::hardware::radio::PersoSubstate::SIM_NS_SP == + static_cast( + ::android::hardware::radio::V1_5::PersoSubstate::SIM_NS_SP)); +static_assert(aidl::android::hardware::radio::PersoSubstate::SIM_NS_SP_PUK == + static_cast( + ::android::hardware::radio::V1_5::PersoSubstate::SIM_NS_SP_PUK)); + +static_assert(aidl::android::hardware::radio::QosFlowIdRange::MIN == + static_cast( + ::android::hardware::radio::V1_6::QosFlowIdRange::MIN)); +static_assert(aidl::android::hardware::radio::QosFlowIdRange::MAX == + static_cast( + ::android::hardware::radio::V1_6::QosFlowIdRange::MAX)); + +static_assert(aidl::android::hardware::radio::QosProtocol::UNSPECIFIED == + static_cast( + ::android::hardware::radio::V1_6::QosProtocol::UNSPECIFIED)); +static_assert(aidl::android::hardware::radio::QosProtocol::TCP == + static_cast( + ::android::hardware::radio::V1_6::QosProtocol::TCP)); +static_assert(aidl::android::hardware::radio::QosProtocol::UDP == + static_cast( + ::android::hardware::radio::V1_6::QosProtocol::UDP)); +static_assert(aidl::android::hardware::radio::QosProtocol::ESP == + static_cast( + ::android::hardware::radio::V1_6::QosProtocol::ESP)); +static_assert(aidl::android::hardware::radio::QosProtocol::AH == + static_cast( + ::android::hardware::radio::V1_6::QosProtocol::AH)); + +static_assert(aidl::android::hardware::radio::QosFilterDirection::DOWNLINK == + static_cast( + ::android::hardware::radio::V1_6::QosFilterDirection::DOWNLINK)); +static_assert(aidl::android::hardware::radio::QosFilterDirection::UPLINK == + static_cast( + ::android::hardware::radio::V1_6::QosFilterDirection::UPLINK)); +static_assert(aidl::android::hardware::radio::QosFilterDirection::BIDIRECTIONAL == + static_cast( + ::android::hardware::radio::V1_6::QosFilterDirection::BIDIRECTIONAL)); + +static_assert(aidl::android::hardware::radio::QosPortRange::MIN == + static_cast( + ::android::hardware::radio::V1_6::QosPortRange::MIN)); +static_assert(aidl::android::hardware::radio::QosPortRange::MAX == + static_cast( + ::android::hardware::radio::V1_6::QosPortRange::MAX)); + +static_assert(aidl::android::hardware::radio::RadioError::NONE == + static_cast( + ::android::hardware::radio::V1_6::RadioError::NONE)); +static_assert(aidl::android::hardware::radio::RadioError::RADIO_NOT_AVAILABLE == + static_cast( + ::android::hardware::radio::V1_6::RadioError::RADIO_NOT_AVAILABLE)); +static_assert(aidl::android::hardware::radio::RadioError::GENERIC_FAILURE == + static_cast( + ::android::hardware::radio::V1_6::RadioError::GENERIC_FAILURE)); +static_assert(aidl::android::hardware::radio::RadioError::PASSWORD_INCORRECT == + static_cast( + ::android::hardware::radio::V1_6::RadioError::PASSWORD_INCORRECT)); +static_assert(aidl::android::hardware::radio::RadioError::SIM_PIN2 == + static_cast( + ::android::hardware::radio::V1_6::RadioError::SIM_PIN2)); +static_assert(aidl::android::hardware::radio::RadioError::SIM_PUK2 == + static_cast( + ::android::hardware::radio::V1_6::RadioError::SIM_PUK2)); +static_assert(aidl::android::hardware::radio::RadioError::REQUEST_NOT_SUPPORTED == + static_cast( + ::android::hardware::radio::V1_6::RadioError::REQUEST_NOT_SUPPORTED)); +static_assert(aidl::android::hardware::radio::RadioError::CANCELLED == + static_cast( + ::android::hardware::radio::V1_6::RadioError::CANCELLED)); +static_assert( + aidl::android::hardware::radio::RadioError::OP_NOT_ALLOWED_DURING_VOICE_CALL == + static_cast( + ::android::hardware::radio::V1_6::RadioError::OP_NOT_ALLOWED_DURING_VOICE_CALL)); +static_assert( + aidl::android::hardware::radio::RadioError::OP_NOT_ALLOWED_BEFORE_REG_TO_NW == + static_cast( + ::android::hardware::radio::V1_6::RadioError::OP_NOT_ALLOWED_BEFORE_REG_TO_NW)); +static_assert(aidl::android::hardware::radio::RadioError::SMS_SEND_FAIL_RETRY == + static_cast( + ::android::hardware::radio::V1_6::RadioError::SMS_SEND_FAIL_RETRY)); +static_assert(aidl::android::hardware::radio::RadioError::SIM_ABSENT == + static_cast( + ::android::hardware::radio::V1_6::RadioError::SIM_ABSENT)); +static_assert(aidl::android::hardware::radio::RadioError::SUBSCRIPTION_NOT_AVAILABLE == + static_cast( + ::android::hardware::radio::V1_6::RadioError::SUBSCRIPTION_NOT_AVAILABLE)); +static_assert(aidl::android::hardware::radio::RadioError::MODE_NOT_SUPPORTED == + static_cast( + ::android::hardware::radio::V1_6::RadioError::MODE_NOT_SUPPORTED)); +static_assert(aidl::android::hardware::radio::RadioError::FDN_CHECK_FAILURE == + static_cast( + ::android::hardware::radio::V1_6::RadioError::FDN_CHECK_FAILURE)); +static_assert(aidl::android::hardware::radio::RadioError::ILLEGAL_SIM_OR_ME == + static_cast( + ::android::hardware::radio::V1_6::RadioError::ILLEGAL_SIM_OR_ME)); +static_assert(aidl::android::hardware::radio::RadioError::MISSING_RESOURCE == + static_cast( + ::android::hardware::radio::V1_6::RadioError::MISSING_RESOURCE)); +static_assert(aidl::android::hardware::radio::RadioError::NO_SUCH_ELEMENT == + static_cast( + ::android::hardware::radio::V1_6::RadioError::NO_SUCH_ELEMENT)); +static_assert(aidl::android::hardware::radio::RadioError::DIAL_MODIFIED_TO_USSD == + static_cast( + ::android::hardware::radio::V1_6::RadioError::DIAL_MODIFIED_TO_USSD)); +static_assert(aidl::android::hardware::radio::RadioError::DIAL_MODIFIED_TO_SS == + static_cast( + ::android::hardware::radio::V1_6::RadioError::DIAL_MODIFIED_TO_SS)); +static_assert(aidl::android::hardware::radio::RadioError::DIAL_MODIFIED_TO_DIAL == + static_cast( + ::android::hardware::radio::V1_6::RadioError::DIAL_MODIFIED_TO_DIAL)); +static_assert(aidl::android::hardware::radio::RadioError::USSD_MODIFIED_TO_DIAL == + static_cast( + ::android::hardware::radio::V1_6::RadioError::USSD_MODIFIED_TO_DIAL)); +static_assert(aidl::android::hardware::radio::RadioError::USSD_MODIFIED_TO_SS == + static_cast( + ::android::hardware::radio::V1_6::RadioError::USSD_MODIFIED_TO_SS)); +static_assert(aidl::android::hardware::radio::RadioError::USSD_MODIFIED_TO_USSD == + static_cast( + ::android::hardware::radio::V1_6::RadioError::USSD_MODIFIED_TO_USSD)); +static_assert(aidl::android::hardware::radio::RadioError::SS_MODIFIED_TO_DIAL == + static_cast( + ::android::hardware::radio::V1_6::RadioError::SS_MODIFIED_TO_DIAL)); +static_assert(aidl::android::hardware::radio::RadioError::SS_MODIFIED_TO_USSD == + static_cast( + ::android::hardware::radio::V1_6::RadioError::SS_MODIFIED_TO_USSD)); +static_assert(aidl::android::hardware::radio::RadioError::SUBSCRIPTION_NOT_SUPPORTED == + static_cast( + ::android::hardware::radio::V1_6::RadioError::SUBSCRIPTION_NOT_SUPPORTED)); +static_assert(aidl::android::hardware::radio::RadioError::SS_MODIFIED_TO_SS == + static_cast( + ::android::hardware::radio::V1_6::RadioError::SS_MODIFIED_TO_SS)); +static_assert(aidl::android::hardware::radio::RadioError::LCE_NOT_SUPPORTED == + static_cast( + ::android::hardware::radio::V1_6::RadioError::LCE_NOT_SUPPORTED)); +static_assert(aidl::android::hardware::radio::RadioError::NO_MEMORY == + static_cast( + ::android::hardware::radio::V1_6::RadioError::NO_MEMORY)); +static_assert(aidl::android::hardware::radio::RadioError::INTERNAL_ERR == + static_cast( + ::android::hardware::radio::V1_6::RadioError::INTERNAL_ERR)); +static_assert(aidl::android::hardware::radio::RadioError::SYSTEM_ERR == + static_cast( + ::android::hardware::radio::V1_6::RadioError::SYSTEM_ERR)); +static_assert(aidl::android::hardware::radio::RadioError::MODEM_ERR == + static_cast( + ::android::hardware::radio::V1_6::RadioError::MODEM_ERR)); +static_assert(aidl::android::hardware::radio::RadioError::INVALID_STATE == + static_cast( + ::android::hardware::radio::V1_6::RadioError::INVALID_STATE)); +static_assert(aidl::android::hardware::radio::RadioError::NO_RESOURCES == + static_cast( + ::android::hardware::radio::V1_6::RadioError::NO_RESOURCES)); +static_assert(aidl::android::hardware::radio::RadioError::SIM_ERR == + static_cast( + ::android::hardware::radio::V1_6::RadioError::SIM_ERR)); +static_assert(aidl::android::hardware::radio::RadioError::INVALID_ARGUMENTS == + static_cast( + ::android::hardware::radio::V1_6::RadioError::INVALID_ARGUMENTS)); +static_assert(aidl::android::hardware::radio::RadioError::INVALID_SIM_STATE == + static_cast( + ::android::hardware::radio::V1_6::RadioError::INVALID_SIM_STATE)); +static_assert(aidl::android::hardware::radio::RadioError::INVALID_MODEM_STATE == + static_cast( + ::android::hardware::radio::V1_6::RadioError::INVALID_MODEM_STATE)); +static_assert(aidl::android::hardware::radio::RadioError::INVALID_CALL_ID == + static_cast( + ::android::hardware::radio::V1_6::RadioError::INVALID_CALL_ID)); +static_assert(aidl::android::hardware::radio::RadioError::NO_SMS_TO_ACK == + static_cast( + ::android::hardware::radio::V1_6::RadioError::NO_SMS_TO_ACK)); +static_assert(aidl::android::hardware::radio::RadioError::NETWORK_ERR == + static_cast( + ::android::hardware::radio::V1_6::RadioError::NETWORK_ERR)); +static_assert(aidl::android::hardware::radio::RadioError::REQUEST_RATE_LIMITED == + static_cast( + ::android::hardware::radio::V1_6::RadioError::REQUEST_RATE_LIMITED)); +static_assert(aidl::android::hardware::radio::RadioError::SIM_BUSY == + static_cast( + ::android::hardware::radio::V1_6::RadioError::SIM_BUSY)); +static_assert(aidl::android::hardware::radio::RadioError::SIM_FULL == + static_cast( + ::android::hardware::radio::V1_6::RadioError::SIM_FULL)); +static_assert(aidl::android::hardware::radio::RadioError::NETWORK_REJECT == + static_cast( + ::android::hardware::radio::V1_6::RadioError::NETWORK_REJECT)); +static_assert(aidl::android::hardware::radio::RadioError::OPERATION_NOT_ALLOWED == + static_cast( + ::android::hardware::radio::V1_6::RadioError::OPERATION_NOT_ALLOWED)); +static_assert(aidl::android::hardware::radio::RadioError::EMPTY_RECORD == + static_cast( + ::android::hardware::radio::V1_6::RadioError::EMPTY_RECORD)); +static_assert(aidl::android::hardware::radio::RadioError::INVALID_SMS_FORMAT == + static_cast( + ::android::hardware::radio::V1_6::RadioError::INVALID_SMS_FORMAT)); +static_assert(aidl::android::hardware::radio::RadioError::ENCODING_ERR == + static_cast( + ::android::hardware::radio::V1_6::RadioError::ENCODING_ERR)); +static_assert(aidl::android::hardware::radio::RadioError::INVALID_SMSC_ADDRESS == + static_cast( + ::android::hardware::radio::V1_6::RadioError::INVALID_SMSC_ADDRESS)); +static_assert(aidl::android::hardware::radio::RadioError::NO_SUCH_ENTRY == + static_cast( + ::android::hardware::radio::V1_6::RadioError::NO_SUCH_ENTRY)); +static_assert(aidl::android::hardware::radio::RadioError::NETWORK_NOT_READY == + static_cast( + ::android::hardware::radio::V1_6::RadioError::NETWORK_NOT_READY)); +static_assert(aidl::android::hardware::radio::RadioError::NOT_PROVISIONED == + static_cast( + ::android::hardware::radio::V1_6::RadioError::NOT_PROVISIONED)); +static_assert(aidl::android::hardware::radio::RadioError::NO_SUBSCRIPTION == + static_cast( + ::android::hardware::radio::V1_6::RadioError::NO_SUBSCRIPTION)); +static_assert(aidl::android::hardware::radio::RadioError::NO_NETWORK_FOUND == + static_cast( + ::android::hardware::radio::V1_6::RadioError::NO_NETWORK_FOUND)); +static_assert(aidl::android::hardware::radio::RadioError::DEVICE_IN_USE == + static_cast( + ::android::hardware::radio::V1_6::RadioError::DEVICE_IN_USE)); +static_assert(aidl::android::hardware::radio::RadioError::ABORTED == + static_cast( + ::android::hardware::radio::V1_6::RadioError::ABORTED)); +static_assert(aidl::android::hardware::radio::RadioError::INVALID_RESPONSE == + static_cast( + ::android::hardware::radio::V1_6::RadioError::INVALID_RESPONSE)); +static_assert(aidl::android::hardware::radio::RadioError::OEM_ERROR_1 == + static_cast( + ::android::hardware::radio::V1_6::RadioError::OEM_ERROR_1)); +static_assert(aidl::android::hardware::radio::RadioError::OEM_ERROR_2 == + static_cast( + ::android::hardware::radio::V1_6::RadioError::OEM_ERROR_2)); +static_assert(aidl::android::hardware::radio::RadioError::OEM_ERROR_3 == + static_cast( + ::android::hardware::radio::V1_6::RadioError::OEM_ERROR_3)); +static_assert(aidl::android::hardware::radio::RadioError::OEM_ERROR_4 == + static_cast( + ::android::hardware::radio::V1_6::RadioError::OEM_ERROR_4)); +static_assert(aidl::android::hardware::radio::RadioError::OEM_ERROR_5 == + static_cast( + ::android::hardware::radio::V1_6::RadioError::OEM_ERROR_5)); +static_assert(aidl::android::hardware::radio::RadioError::OEM_ERROR_6 == + static_cast( + ::android::hardware::radio::V1_6::RadioError::OEM_ERROR_6)); +static_assert(aidl::android::hardware::radio::RadioError::OEM_ERROR_7 == + static_cast( + ::android::hardware::radio::V1_6::RadioError::OEM_ERROR_7)); +static_assert(aidl::android::hardware::radio::RadioError::OEM_ERROR_8 == + static_cast( + ::android::hardware::radio::V1_6::RadioError::OEM_ERROR_8)); +static_assert(aidl::android::hardware::radio::RadioError::OEM_ERROR_9 == + static_cast( + ::android::hardware::radio::V1_6::RadioError::OEM_ERROR_9)); +static_assert(aidl::android::hardware::radio::RadioError::OEM_ERROR_10 == + static_cast( + ::android::hardware::radio::V1_6::RadioError::OEM_ERROR_10)); +static_assert(aidl::android::hardware::radio::RadioError::OEM_ERROR_11 == + static_cast( + ::android::hardware::radio::V1_6::RadioError::OEM_ERROR_11)); +static_assert(aidl::android::hardware::radio::RadioError::OEM_ERROR_12 == + static_cast( + ::android::hardware::radio::V1_6::RadioError::OEM_ERROR_12)); +static_assert(aidl::android::hardware::radio::RadioError::OEM_ERROR_13 == + static_cast( + ::android::hardware::radio::V1_6::RadioError::OEM_ERROR_13)); +static_assert(aidl::android::hardware::radio::RadioError::OEM_ERROR_14 == + static_cast( + ::android::hardware::radio::V1_6::RadioError::OEM_ERROR_14)); +static_assert(aidl::android::hardware::radio::RadioError::OEM_ERROR_15 == + static_cast( + ::android::hardware::radio::V1_6::RadioError::OEM_ERROR_15)); +static_assert(aidl::android::hardware::radio::RadioError::OEM_ERROR_16 == + static_cast( + ::android::hardware::radio::V1_6::RadioError::OEM_ERROR_16)); +static_assert(aidl::android::hardware::radio::RadioError::OEM_ERROR_17 == + static_cast( + ::android::hardware::radio::V1_6::RadioError::OEM_ERROR_17)); +static_assert(aidl::android::hardware::radio::RadioError::OEM_ERROR_18 == + static_cast( + ::android::hardware::radio::V1_6::RadioError::OEM_ERROR_18)); +static_assert(aidl::android::hardware::radio::RadioError::OEM_ERROR_19 == + static_cast( + ::android::hardware::radio::V1_6::RadioError::OEM_ERROR_19)); +static_assert(aidl::android::hardware::radio::RadioError::OEM_ERROR_20 == + static_cast( + ::android::hardware::radio::V1_6::RadioError::OEM_ERROR_20)); +static_assert(aidl::android::hardware::radio::RadioError::OEM_ERROR_21 == + static_cast( + ::android::hardware::radio::V1_6::RadioError::OEM_ERROR_21)); +static_assert(aidl::android::hardware::radio::RadioError::OEM_ERROR_22 == + static_cast( + ::android::hardware::radio::V1_6::RadioError::OEM_ERROR_22)); +static_assert(aidl::android::hardware::radio::RadioError::OEM_ERROR_23 == + static_cast( + ::android::hardware::radio::V1_6::RadioError::OEM_ERROR_23)); +static_assert(aidl::android::hardware::radio::RadioError::OEM_ERROR_24 == + static_cast( + ::android::hardware::radio::V1_6::RadioError::OEM_ERROR_24)); +static_assert(aidl::android::hardware::radio::RadioError::OEM_ERROR_25 == + static_cast( + ::android::hardware::radio::V1_6::RadioError::OEM_ERROR_25)); +static_assert(aidl::android::hardware::radio::RadioError::SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED == + static_cast( + ::android::hardware::radio::V1_6::RadioError:: + SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED)); +static_assert(aidl::android::hardware::radio::RadioError::ACCESS_BARRED == + static_cast( + ::android::hardware::radio::V1_6::RadioError::ACCESS_BARRED)); +static_assert(aidl::android::hardware::radio::RadioError::BLOCKED_DUE_TO_CALL == + static_cast( + ::android::hardware::radio::V1_6::RadioError::BLOCKED_DUE_TO_CALL)); +static_assert(aidl::android::hardware::radio::RadioError::RF_HARDWARE_ISSUE == + static_cast( + ::android::hardware::radio::V1_6::RadioError::RF_HARDWARE_ISSUE)); +static_assert(aidl::android::hardware::radio::RadioError::NO_RF_CALIBRATION_INFO == + static_cast( + ::android::hardware::radio::V1_6::RadioError::NO_RF_CALIBRATION_INFO)); + +static_assert(aidl::android::hardware::radio::HandoverFailureMode::LEGACY == + static_cast( + ::android::hardware::radio::V1_6::HandoverFailureMode::LEGACY)); +static_assert(aidl::android::hardware::radio::HandoverFailureMode::DO_FALLBACK == + static_cast( + ::android::hardware::radio::V1_6::HandoverFailureMode::DO_FALLBACK)); +static_assert( + aidl::android::hardware::radio::HandoverFailureMode::NO_FALLBACK_RETRY_HANDOVER == + static_cast( + ::android::hardware::radio::V1_6::HandoverFailureMode::NO_FALLBACK_RETRY_HANDOVER)); +static_assert(aidl::android::hardware::radio::HandoverFailureMode::NO_FALLBACK_RETRY_SETUP_NORMAL == + static_cast( + ::android::hardware::radio::V1_6::HandoverFailureMode:: + NO_FALLBACK_RETRY_SETUP_NORMAL)); + +static_assert(aidl::android::hardware::radio::NrDualConnectivityState::ENABLE == + static_cast( + ::android::hardware::radio::V1_6::NrDualConnectivityState::ENABLE)); +static_assert(aidl::android::hardware::radio::NrDualConnectivityState::DISABLE == + static_cast( + ::android::hardware::radio::V1_6::NrDualConnectivityState::DISABLE)); +static_assert( + aidl::android::hardware::radio::NrDualConnectivityState::DISABLE_IMMEDIATE == + static_cast( + ::android::hardware::radio::V1_6::NrDualConnectivityState::DISABLE_IMMEDIATE)); + +static_assert(aidl::android::hardware::radio::DataThrottlingAction::NO_DATA_THROTTLING == + static_cast( + ::android::hardware::radio::V1_6::DataThrottlingAction::NO_DATA_THROTTLING)); +static_assert(aidl::android::hardware::radio::DataThrottlingAction::THROTTLE_SECONDARY_CARRIER == + static_cast( + ::android::hardware::radio::V1_6::DataThrottlingAction:: + THROTTLE_SECONDARY_CARRIER)); +static_assert( + aidl::android::hardware::radio::DataThrottlingAction::THROTTLE_ANCHOR_CARRIER == + static_cast( + ::android::hardware::radio::V1_6::DataThrottlingAction::THROTTLE_ANCHOR_CARRIER)); +static_assert(aidl::android::hardware::radio::DataThrottlingAction::HOLD == + static_cast( + ::android::hardware::radio::V1_6::DataThrottlingAction::HOLD)); + +static_assert(aidl::android::hardware::radio::VopsIndicator::VOPS_NOT_SUPPORTED == + static_cast( + ::android::hardware::radio::V1_6::VopsIndicator::VOPS_NOT_SUPPORTED)); +static_assert(aidl::android::hardware::radio::VopsIndicator::VOPS_OVER_3GPP == + static_cast( + ::android::hardware::radio::V1_6::VopsIndicator::VOPS_OVER_3GPP)); +static_assert(aidl::android::hardware::radio::VopsIndicator::VOPS_OVER_NON_3GPP == + static_cast( + ::android::hardware::radio::V1_6::VopsIndicator::VOPS_OVER_NON_3GPP)); + +static_assert(aidl::android::hardware::radio::EmcIndicator::EMC_NOT_SUPPORTED == + static_cast( + ::android::hardware::radio::V1_6::EmcIndicator::EMC_NOT_SUPPORTED)); +static_assert(aidl::android::hardware::radio::EmcIndicator::EMC_NR_CONNECTED_TO_5GCN == + static_cast( + ::android::hardware::radio::V1_6::EmcIndicator::EMC_NR_CONNECTED_TO_5GCN)); +static_assert(aidl::android::hardware::radio::EmcIndicator::EMC_EUTRA_CONNECTED_TO_5GCN == + static_cast( + ::android::hardware::radio::V1_6::EmcIndicator::EMC_EUTRA_CONNECTED_TO_5GCN)); +static_assert(aidl::android::hardware::radio::EmcIndicator::EMC_BOTH_NR_EUTRA_CONNECTED_TO_5GCN == + static_cast( + ::android::hardware::radio::V1_6::EmcIndicator:: + EMC_BOTH_NR_EUTRA_CONNECTED_TO_5GCN)); + +static_assert(aidl::android::hardware::radio::EmfIndicator::EMF_NOT_SUPPORTED == + static_cast( + ::android::hardware::radio::V1_6::EmfIndicator::EMF_NOT_SUPPORTED)); +static_assert(aidl::android::hardware::radio::EmfIndicator::EMF_NR_CONNECTED_TO_5GCN == + static_cast( + ::android::hardware::radio::V1_6::EmfIndicator::EMF_NR_CONNECTED_TO_5GCN)); +static_assert(aidl::android::hardware::radio::EmfIndicator::EMF_EUTRA_CONNECTED_TO_5GCN == + static_cast( + ::android::hardware::radio::V1_6::EmfIndicator::EMF_EUTRA_CONNECTED_TO_5GCN)); +static_assert(aidl::android::hardware::radio::EmfIndicator::EMF_BOTH_NR_EUTRA_CONNECTED_TO_5GCN == + static_cast( + ::android::hardware::radio::V1_6::EmfIndicator:: + EMF_BOTH_NR_EUTRA_CONNECTED_TO_5GCN)); + +static_assert(aidl::android::hardware::radio::NgranBands::BAND_1 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_1)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_2 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_2)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_3 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_3)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_5 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_5)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_7 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_7)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_8 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_8)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_12 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_12)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_14 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_14)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_18 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_18)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_20 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_20)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_25 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_25)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_28 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_28)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_29 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_29)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_30 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_30)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_34 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_34)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_38 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_38)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_39 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_39)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_40 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_40)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_41 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_41)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_48 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_48)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_50 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_50)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_51 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_51)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_65 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_65)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_66 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_66)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_70 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_70)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_71 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_71)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_74 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_74)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_75 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_75)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_76 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_76)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_77 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_77)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_78 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_78)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_79 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_79)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_80 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_80)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_81 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_81)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_82 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_82)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_83 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_83)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_84 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_84)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_86 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_86)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_89 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_89)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_90 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_90)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_91 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_91)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_92 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_92)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_93 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_93)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_94 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_94)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_95 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_95)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_257 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_257)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_258 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_258)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_260 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_260)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_261 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_261)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_26 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_26)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_46 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_46)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_53 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_53)); +static_assert(aidl::android::hardware::radio::NgranBands::BAND_96 == + static_cast( + ::android::hardware::radio::V1_6::NgranBands::BAND_96)); + +static_assert(aidl::android::hardware::radio::SliceServiceType::NONE == + static_cast( + ::android::hardware::radio::V1_6::SliceServiceType::NONE)); +static_assert(aidl::android::hardware::radio::SliceServiceType::EMBB == + static_cast( + ::android::hardware::radio::V1_6::SliceServiceType::EMBB)); +static_assert(aidl::android::hardware::radio::SliceServiceType::URLLC == + static_cast( + ::android::hardware::radio::V1_6::SliceServiceType::URLLC)); +static_assert(aidl::android::hardware::radio::SliceServiceType::MIOT == + static_cast( + ::android::hardware::radio::V1_6::SliceServiceType::MIOT)); + +static_assert(aidl::android::hardware::radio::DataCallFailCause::NONE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::NONE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::OPERATOR_BARRED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::OPERATOR_BARRED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::NAS_SIGNALLING == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::NAS_SIGNALLING)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::INSUFFICIENT_RESOURCES == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::INSUFFICIENT_RESOURCES)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::MISSING_UNKNOWN_APN == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::MISSING_UKNOWN_APN)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::UNKNOWN_PDP_ADDRESS_TYPE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::UNKNOWN_PDP_ADDRESS_TYPE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::USER_AUTHENTICATION == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::USER_AUTHENTICATION)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::ACTIVATION_REJECT_GGSN == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::ACTIVATION_REJECT_GGSN)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::ACTIVATION_REJECT_UNSPECIFIED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + ACTIVATION_REJECT_UNSPECIFIED)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::SERVICE_OPTION_NOT_SUPPORTED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::SERVICE_OPTION_NOT_SUPPORTED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::SERVICE_OPTION_NOT_SUBSCRIBED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + SERVICE_OPTION_NOT_SUBSCRIBED)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::SERVICE_OPTION_OUT_OF_ORDER == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::SERVICE_OPTION_OUT_OF_ORDER)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::NSAPI_IN_USE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::NSAPI_IN_USE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::REGULAR_DEACTIVATION == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::REGULAR_DEACTIVATION)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::QOS_NOT_ACCEPTED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::QOS_NOT_ACCEPTED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::NETWORK_FAILURE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::NETWORK_FAILURE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::UMTS_REACTIVATION_REQ == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::UMTS_REACTIVATION_REQ)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::FEATURE_NOT_SUPP == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::FEATURE_NOT_SUPP)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::TFT_SEMANTIC_ERROR == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::TFT_SEMANTIC_ERROR)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::TFT_SYTAX_ERROR == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::TFT_SYTAX_ERROR)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::UNKNOWN_PDP_CONTEXT == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::UNKNOWN_PDP_CONTEXT)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::FILTER_SEMANTIC_ERROR == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::FILTER_SEMANTIC_ERROR)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::FILTER_SYTAX_ERROR == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::FILTER_SYTAX_ERROR)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::PDP_WITHOUT_ACTIVE_TFT == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::PDP_WITHOUT_ACTIVE_TFT)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::ONLY_IPV4_ALLOWED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::ONLY_IPV4_ALLOWED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::ONLY_IPV6_ALLOWED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::ONLY_IPV6_ALLOWED)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::ONLY_SINGLE_BEARER_ALLOWED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::ONLY_SINGLE_BEARER_ALLOWED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::ESM_INFO_NOT_RECEIVED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::ESM_INFO_NOT_RECEIVED)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::PDN_CONN_DOES_NOT_EXIST == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::PDN_CONN_DOES_NOT_EXIST)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::MULTI_CONN_TO_SAME_PDN_NOT_ALLOWED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + MULTI_CONN_TO_SAME_PDN_NOT_ALLOWED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::MAX_ACTIVE_PDP_CONTEXT_REACHED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + MAX_ACTIVE_PDP_CONTEXT_REACHED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::UNSUPPORTED_APN_IN_CURRENT_PLMN == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + UNSUPPORTED_APN_IN_CURRENT_PLMN)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::INVALID_TRANSACTION_ID == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::INVALID_TRANSACTION_ID)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::MESSAGE_INCORRECT_SEMANTIC == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::MESSAGE_INCORRECT_SEMANTIC)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::INVALID_MANDATORY_INFO == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::INVALID_MANDATORY_INFO)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::MESSAGE_TYPE_UNSUPPORTED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::MESSAGE_TYPE_UNSUPPORTED)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::MSG_TYPE_NONCOMPATIBLE_STATE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::MSG_TYPE_NONCOMPATIBLE_STATE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::UNKNOWN_INFO_ELEMENT == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::UNKNOWN_INFO_ELEMENT)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::CONDITIONAL_IE_ERROR == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::CONDITIONAL_IE_ERROR)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::MSG_AND_PROTOCOL_STATE_UNCOMPATIBLE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + MSG_AND_PROTOCOL_STATE_UNCOMPATIBLE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::PROTOCOL_ERRORS == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::PROTOCOL_ERRORS)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::APN_TYPE_CONFLICT == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::APN_TYPE_CONFLICT)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::INVALID_PCSCF_ADDR == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::INVALID_PCSCF_ADDR)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::INTERNAL_CALL_PREEMPT_BY_HIGH_PRIO_APN == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + INTERNAL_CALL_PREEMPT_BY_HIGH_PRIO_APN)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::EMM_ACCESS_BARRED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::EMM_ACCESS_BARRED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::EMERGENCY_IFACE_ONLY == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::EMERGENCY_IFACE_ONLY)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::IFACE_MISMATCH == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::IFACE_MISMATCH)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::COMPANION_IFACE_IN_USE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::COMPANION_IFACE_IN_USE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::IP_ADDRESS_MISMATCH == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::IP_ADDRESS_MISMATCH)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::IFACE_AND_POL_FAMILY_MISMATCH == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + IFACE_AND_POL_FAMILY_MISMATCH)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::EMM_ACCESS_BARRED_INFINITE_RETRY == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + EMM_ACCESS_BARRED_INFINITE_RETRY)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::AUTH_FAILURE_ON_EMERGENCY_CALL == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + AUTH_FAILURE_ON_EMERGENCY_CALL)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::OEM_DCFAILCAUSE_1 == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::OEM_DCFAILCAUSE_1)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::OEM_DCFAILCAUSE_2 == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::OEM_DCFAILCAUSE_2)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::OEM_DCFAILCAUSE_3 == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::OEM_DCFAILCAUSE_3)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::OEM_DCFAILCAUSE_4 == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::OEM_DCFAILCAUSE_4)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::OEM_DCFAILCAUSE_5 == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::OEM_DCFAILCAUSE_5)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::OEM_DCFAILCAUSE_6 == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::OEM_DCFAILCAUSE_6)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::OEM_DCFAILCAUSE_7 == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::OEM_DCFAILCAUSE_7)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::OEM_DCFAILCAUSE_8 == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::OEM_DCFAILCAUSE_8)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::OEM_DCFAILCAUSE_9 == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::OEM_DCFAILCAUSE_9)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::OEM_DCFAILCAUSE_10 == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::OEM_DCFAILCAUSE_10)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::OEM_DCFAILCAUSE_11 == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::OEM_DCFAILCAUSE_11)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::OEM_DCFAILCAUSE_12 == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::OEM_DCFAILCAUSE_12)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::OEM_DCFAILCAUSE_13 == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::OEM_DCFAILCAUSE_13)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::OEM_DCFAILCAUSE_14 == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::OEM_DCFAILCAUSE_14)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::OEM_DCFAILCAUSE_15 == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::OEM_DCFAILCAUSE_15)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::VOICE_REGISTRATION_FAIL == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::VOICE_REGISTRATION_FAIL)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::DATA_REGISTRATION_FAIL == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::DATA_REGISTRATION_FAIL)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::SIGNAL_LOST == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::SIGNAL_LOST)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::PREF_RADIO_TECH_CHANGED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::PREF_RADIO_TECH_CHANGED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::RADIO_POWER_OFF == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::RADIO_POWER_OFF)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::TETHERED_CALL_ACTIVE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::TETHERED_CALL_ACTIVE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::ERROR_UNSPECIFIED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::ERROR_UNSPECIFIED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::LLC_SNDCP == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::LLC_SNDCP)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::ACTIVATION_REJECTED_BCM_VIOLATION == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + ACTIVATION_REJECTED_BCM_VIOLATION)); +static_assert(aidl::android::hardware::radio::DataCallFailCause:: + COLLISION_WITH_NETWORK_INITIATED_REQUEST == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + COLLISION_WITH_NETWORK_INITIATED_REQUEST)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::ONLY_IPV4V6_ALLOWED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::ONLY_IPV4V6_ALLOWED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::ONLY_NON_IP_ALLOWED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::ONLY_NON_IP_ALLOWED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::UNSUPPORTED_QCI_VALUE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::UNSUPPORTED_QCI_VALUE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::BEARER_HANDLING_NOT_SUPPORTED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + BEARER_HANDLING_NOT_SUPPORTED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::INVALID_DNS_ADDR == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::INVALID_DNS_ADDR)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::INVALID_PCSCF_OR_DNS_ADDRESS == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::INVALID_PCSCF_OR_DNS_ADDRESS)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::CALL_PREEMPT_BY_EMERGENCY_APN == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + CALL_PREEMPT_BY_EMERGENCY_APN)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::UE_INITIATED_DETACH_OR_DISCONNECT == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + UE_INITIATED_DETACH_OR_DISCONNECT)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::MIP_FA_REASON_UNSPECIFIED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::MIP_FA_REASON_UNSPECIFIED)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::MIP_FA_ADMIN_PROHIBITED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::MIP_FA_ADMIN_PROHIBITED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::MIP_FA_INSUFFICIENT_RESOURCES == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + MIP_FA_INSUFFICIENT_RESOURCES)); +static_assert(aidl::android::hardware::radio::DataCallFailCause:: + MIP_FA_MOBILE_NODE_AUTHENTICATION_FAILURE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + MIP_FA_MOBILE_NODE_AUTHENTICATION_FAILURE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause:: + MIP_FA_HOME_AGENT_AUTHENTICATION_FAILURE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + MIP_FA_HOME_AGENT_AUTHENTICATION_FAILURE)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::MIP_FA_REQUESTED_LIFETIME_TOO_LONG == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + MIP_FA_REQUESTED_LIFETIME_TOO_LONG)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::MIP_FA_MALFORMED_REQUEST == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::MIP_FA_MALFORMED_REQUEST)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::MIP_FA_MALFORMED_REPLY == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::MIP_FA_MALFORMED_REPLY)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::MIP_FA_ENCAPSULATION_UNAVAILABLE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + MIP_FA_ENCAPSULATION_UNAVAILABLE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause:: + MIP_FA_VJ_HEADER_COMPRESSION_UNAVAILABLE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + MIP_FA_VJ_HEADER_COMPRESSION_UNAVAILABLE)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::MIP_FA_REVERSE_TUNNEL_UNAVAILABLE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + MIP_FA_REVERSE_TUNNEL_UNAVAILABLE)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::MIP_FA_REVERSE_TUNNEL_IS_MANDATORY == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + MIP_FA_REVERSE_TUNNEL_IS_MANDATORY)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::MIP_FA_DELIVERY_STYLE_NOT_SUPPORTED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + MIP_FA_DELIVERY_STYLE_NOT_SUPPORTED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::MIP_FA_MISSING_NAI == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::MIP_FA_MISSING_NAI)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::MIP_FA_MISSING_HOME_AGENT == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::MIP_FA_MISSING_HOME_AGENT)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::MIP_FA_MISSING_HOME_ADDRESS == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::MIP_FA_MISSING_HOME_ADDRESS)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::MIP_FA_UNKNOWN_CHALLENGE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::MIP_FA_UNKNOWN_CHALLENGE)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::MIP_FA_MISSING_CHALLENGE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::MIP_FA_MISSING_CHALLENGE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::MIP_FA_STALE_CHALLENGE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::MIP_FA_STALE_CHALLENGE)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::MIP_HA_REASON_UNSPECIFIED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::MIP_HA_REASON_UNSPECIFIED)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::MIP_HA_ADMIN_PROHIBITED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::MIP_HA_ADMIN_PROHIBITED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::MIP_HA_INSUFFICIENT_RESOURCES == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + MIP_HA_INSUFFICIENT_RESOURCES)); +static_assert(aidl::android::hardware::radio::DataCallFailCause:: + MIP_HA_MOBILE_NODE_AUTHENTICATION_FAILURE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + MIP_HA_MOBILE_NODE_AUTHENTICATION_FAILURE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause:: + MIP_HA_FOREIGN_AGENT_AUTHENTICATION_FAILURE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + MIP_HA_FOREIGN_AGENT_AUTHENTICATION_FAILURE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::MIP_HA_REGISTRATION_ID_MISMATCH == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + MIP_HA_REGISTRATION_ID_MISMATCH)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::MIP_HA_MALFORMED_REQUEST == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::MIP_HA_MALFORMED_REQUEST)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::MIP_HA_UNKNOWN_HOME_AGENT_ADDRESS == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + MIP_HA_UNKNOWN_HOME_AGENT_ADDRESS)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::MIP_HA_REVERSE_TUNNEL_UNAVAILABLE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + MIP_HA_REVERSE_TUNNEL_UNAVAILABLE)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::MIP_HA_REVERSE_TUNNEL_IS_MANDATORY == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + MIP_HA_REVERSE_TUNNEL_IS_MANDATORY)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::MIP_HA_ENCAPSULATION_UNAVAILABLE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + MIP_HA_ENCAPSULATION_UNAVAILABLE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::CLOSE_IN_PROGRESS == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::CLOSE_IN_PROGRESS)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::NETWORK_INITIATED_TERMINATION == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + NETWORK_INITIATED_TERMINATION)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::MODEM_APP_PREEMPTED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::MODEM_APP_PREEMPTED)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::PDN_IPV4_CALL_DISALLOWED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::PDN_IPV4_CALL_DISALLOWED)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::PDN_IPV4_CALL_THROTTLED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::PDN_IPV4_CALL_THROTTLED)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::PDN_IPV6_CALL_DISALLOWED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::PDN_IPV6_CALL_DISALLOWED)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::PDN_IPV6_CALL_THROTTLED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::PDN_IPV6_CALL_THROTTLED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::MODEM_RESTART == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::MODEM_RESTART)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::PDP_PPP_NOT_SUPPORTED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::PDP_PPP_NOT_SUPPORTED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::UNPREFERRED_RAT == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::UNPREFERRED_RAT)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::PHYSICAL_LINK_CLOSE_IN_PROGRESS == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + PHYSICAL_LINK_CLOSE_IN_PROGRESS)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::APN_PENDING_HANDOVER == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::APN_PENDING_HANDOVER)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::PROFILE_BEARER_INCOMPATIBLE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::PROFILE_BEARER_INCOMPATIBLE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::SIM_CARD_CHANGED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::SIM_CARD_CHANGED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::LOW_POWER_MODE_OR_POWERING_DOWN == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + LOW_POWER_MODE_OR_POWERING_DOWN)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::APN_DISABLED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::APN_DISABLED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::MAX_PPP_INACTIVITY_TIMER_EXPIRED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + MAX_PPP_INACTIVITY_TIMER_EXPIRED)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::IPV6_ADDRESS_TRANSFER_FAILED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::IPV6_ADDRESS_TRANSFER_FAILED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::TRAT_SWAP_FAILED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::TRAT_SWAP_FAILED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::EHRPD_TO_HRPD_FALLBACK == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::EHRPD_TO_HRPD_FALLBACK)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::MIP_CONFIG_FAILURE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::MIP_CONFIG_FAILURE)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::PDN_INACTIVITY_TIMER_EXPIRED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::PDN_INACTIVITY_TIMER_EXPIRED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::MAX_IPV4_CONNECTIONS == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::MAX_IPV4_CONNECTIONS)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::MAX_IPV6_CONNECTIONS == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::MAX_IPV6_CONNECTIONS)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::APN_MISMATCH == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::APN_MISMATCH)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::IP_VERSION_MISMATCH == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::IP_VERSION_MISMATCH)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::DUN_CALL_DISALLOWED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::DUN_CALL_DISALLOWED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::INTERNAL_EPC_NONEPC_TRANSITION == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + INTERNAL_EPC_NONEPC_TRANSITION)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::INTERFACE_IN_USE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::INTERFACE_IN_USE)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::APN_DISALLOWED_ON_ROAMING == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::APN_DISALLOWED_ON_ROAMING)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::APN_PARAMETERS_CHANGED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::APN_PARAMETERS_CHANGED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::NULL_APN_DISALLOWED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::NULL_APN_DISALLOWED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::THERMAL_MITIGATION == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::THERMAL_MITIGATION)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::DATA_SETTINGS_DISABLED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::DATA_SETTINGS_DISABLED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::DATA_ROAMING_SETTINGS_DISABLED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + DATA_ROAMING_SETTINGS_DISABLED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::DDS_SWITCHED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::DDS_SWITCHED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::FORBIDDEN_APN_NAME == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::FORBIDDEN_APN_NAME)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::DDS_SWITCH_IN_PROGRESS == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::DDS_SWITCH_IN_PROGRESS)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::CALL_DISALLOWED_IN_ROAMING == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::CALL_DISALLOWED_IN_ROAMING)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::NON_IP_NOT_SUPPORTED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::NON_IP_NOT_SUPPORTED)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::PDN_NON_IP_CALL_THROTTLED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::PDN_NON_IP_CALL_THROTTLED)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::PDN_NON_IP_CALL_DISALLOWED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::PDN_NON_IP_CALL_DISALLOWED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::CDMA_LOCK == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::CDMA_LOCK)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::CDMA_INTERCEPT == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::CDMA_INTERCEPT)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::CDMA_REORDER == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::CDMA_REORDER)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::CDMA_RELEASE_DUE_TO_SO_REJECTION == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + CDMA_RELEASE_DUE_TO_SO_REJECTION)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::CDMA_INCOMING_CALL == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::CDMA_INCOMING_CALL)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::CDMA_ALERT_STOP == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::CDMA_ALERT_STOP)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::CHANNEL_ACQUISITION_FAILURE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::CHANNEL_ACQUISITION_FAILURE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::MAX_ACCESS_PROBE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::MAX_ACCESS_PROBE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause:: + CONCURRENT_SERVICE_NOT_SUPPORTED_BY_BASE_STATION == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + CONCURRENT_SERVICE_NOT_SUPPORTED_BY_BASE_STATION)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::NO_RESPONSE_FROM_BASE_STATION == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + NO_RESPONSE_FROM_BASE_STATION)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::REJECTED_BY_BASE_STATION == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::REJECTED_BY_BASE_STATION)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::CONCURRENT_SERVICES_INCOMPATIBLE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + CONCURRENT_SERVICES_INCOMPATIBLE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::NO_CDMA_SERVICE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::NO_CDMA_SERVICE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::RUIM_NOT_PRESENT == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::RUIM_NOT_PRESENT)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::CDMA_RETRY_ORDER == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::CDMA_RETRY_ORDER)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::ACCESS_BLOCK == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::ACCESS_BLOCK)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::ACCESS_BLOCK_ALL == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::ACCESS_BLOCK_ALL)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::IS707B_MAX_ACCESS_PROBES == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::IS707B_MAX_ACCESS_PROBES)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::THERMAL_EMERGENCY == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::THERMAL_EMERGENCY)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::CONCURRENT_SERVICES_NOT_ALLOWED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + CONCURRENT_SERVICES_NOT_ALLOWED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::INCOMING_CALL_REJECTED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::INCOMING_CALL_REJECTED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::NO_SERVICE_ON_GATEWAY == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::NO_SERVICE_ON_GATEWAY)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::NO_GPRS_CONTEXT == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::NO_GPRS_CONTEXT)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::ILLEGAL_MS == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::ILLEGAL_MS)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::ILLEGAL_ME == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::ILLEGAL_ME)); +static_assert(aidl::android::hardware::radio::DataCallFailCause:: + GPRS_SERVICES_AND_NON_GPRS_SERVICES_NOT_ALLOWED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + GPRS_SERVICES_AND_NON_GPRS_SERVICES_NOT_ALLOWED)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::GPRS_SERVICES_NOT_ALLOWED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::GPRS_SERVICES_NOT_ALLOWED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause:: + MS_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + MS_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::IMPLICITLY_DETACHED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::IMPLICITLY_DETACHED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::PLMN_NOT_ALLOWED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::PLMN_NOT_ALLOWED)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::LOCATION_AREA_NOT_ALLOWED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::LOCATION_AREA_NOT_ALLOWED)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::GPRS_SERVICES_NOT_ALLOWED_IN_THIS_PLMN == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + GPRS_SERVICES_NOT_ALLOWED_IN_THIS_PLMN)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::PDP_DUPLICATE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::PDP_DUPLICATE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::UE_RAT_CHANGE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::UE_RAT_CHANGE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::CONGESTION == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::CONGESTION)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::NO_PDP_CONTEXT_ACTIVATED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::NO_PDP_CONTEXT_ACTIVATED)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::ACCESS_CLASS_DSAC_REJECTION == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::ACCESS_CLASS_DSAC_REJECTION)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::PDP_ACTIVATE_MAX_RETRY_FAILED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + PDP_ACTIVATE_MAX_RETRY_FAILED)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::RADIO_ACCESS_BEARER_FAILURE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::RADIO_ACCESS_BEARER_FAILURE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::ESM_UNKNOWN_EPS_BEARER_CONTEXT == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + ESM_UNKNOWN_EPS_BEARER_CONTEXT)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::DRB_RELEASED_BY_RRC == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::DRB_RELEASED_BY_RRC)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::CONNECTION_RELEASED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::CONNECTION_RELEASED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::EMM_DETACHED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::EMM_DETACHED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::EMM_ATTACH_FAILED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::EMM_ATTACH_FAILED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::EMM_ATTACH_STARTED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::EMM_ATTACH_STARTED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::LTE_NAS_SERVICE_REQUEST_FAILED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + LTE_NAS_SERVICE_REQUEST_FAILED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::DUPLICATE_BEARER_ID == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::DUPLICATE_BEARER_ID)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::ESM_COLLISION_SCENARIOS == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::ESM_COLLISION_SCENARIOS)); +static_assert(aidl::android::hardware::radio::DataCallFailCause:: + ESM_BEARER_DEACTIVATED_TO_SYNC_WITH_NETWORK == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + ESM_BEARER_DEACTIVATED_TO_SYNC_WITH_NETWORK)); +static_assert(aidl::android::hardware::radio::DataCallFailCause:: + ESM_NW_ACTIVATED_DED_BEARER_WITH_ID_OF_DEF_BEARER == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + ESM_NW_ACTIVATED_DED_BEARER_WITH_ID_OF_DEF_BEARER)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::ESM_BAD_OTA_MESSAGE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::ESM_BAD_OTA_MESSAGE)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::ESM_DOWNLOAD_SERVER_REJECTED_THE_CALL == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + ESM_DOWNLOAD_SERVER_REJECTED_THE_CALL)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::ESM_CONTEXT_TRANSFERRED_DUE_TO_IRAT == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + ESM_CONTEXT_TRANSFERRED_DUE_TO_IRAT)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::DS_EXPLICIT_DEACTIVATION == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::DS_EXPLICIT_DEACTIVATION)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::ESM_LOCAL_CAUSE_NONE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::ESM_LOCAL_CAUSE_NONE)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::LTE_THROTTLING_NOT_REQUIRED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::LTE_THROTTLING_NOT_REQUIRED)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::ACCESS_CONTROL_LIST_CHECK_FAILURE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + ACCESS_CONTROL_LIST_CHECK_FAILURE)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::SERVICE_NOT_ALLOWED_ON_PLMN == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::SERVICE_NOT_ALLOWED_ON_PLMN)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::EMM_T3417_EXPIRED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::EMM_T3417_EXPIRED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::EMM_T3417_EXT_EXPIRED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::EMM_T3417_EXT_EXPIRED)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::RRC_UPLINK_DATA_TRANSMISSION_FAILURE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + RRC_UPLINK_DATA_TRANSMISSION_FAILURE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause:: + RRC_UPLINK_DELIVERY_FAILED_DUE_TO_HANDOVER == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + RRC_UPLINK_DELIVERY_FAILED_DUE_TO_HANDOVER)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::RRC_UPLINK_CONNECTION_RELEASE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + RRC_UPLINK_CONNECTION_RELEASE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::RRC_UPLINK_RADIO_LINK_FAILURE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + RRC_UPLINK_RADIO_LINK_FAILURE)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::RRC_UPLINK_ERROR_REQUEST_FROM_NAS == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + RRC_UPLINK_ERROR_REQUEST_FROM_NAS)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::RRC_CONNECTION_ACCESS_STRATUM_FAILURE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + RRC_CONNECTION_ACCESS_STRATUM_FAILURE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause:: + RRC_CONNECTION_ANOTHER_PROCEDURE_IN_PROGRESS == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + RRC_CONNECTION_ANOTHER_PROCEDURE_IN_PROGRESS)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::RRC_CONNECTION_ACCESS_BARRED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::RRC_CONNECTION_ACCESS_BARRED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::RRC_CONNECTION_CELL_RESELECTION == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + RRC_CONNECTION_CELL_RESELECTION)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::RRC_CONNECTION_CONFIG_FAILURE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + RRC_CONNECTION_CONFIG_FAILURE)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::RRC_CONNECTION_TIMER_EXPIRED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::RRC_CONNECTION_TIMER_EXPIRED)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::RRC_CONNECTION_LINK_FAILURE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::RRC_CONNECTION_LINK_FAILURE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::RRC_CONNECTION_CELL_NOT_CAMPED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + RRC_CONNECTION_CELL_NOT_CAMPED)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::RRC_CONNECTION_SYSTEM_INTERVAL_FAILURE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + RRC_CONNECTION_SYSTEM_INTERVAL_FAILURE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::RRC_CONNECTION_REJECT_BY_NETWORK == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + RRC_CONNECTION_REJECT_BY_NETWORK)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::RRC_CONNECTION_NORMAL_RELEASE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + RRC_CONNECTION_NORMAL_RELEASE)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::RRC_CONNECTION_RADIO_LINK_FAILURE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + RRC_CONNECTION_RADIO_LINK_FAILURE)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::RRC_CONNECTION_REESTABLISHMENT_FAILURE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + RRC_CONNECTION_REESTABLISHMENT_FAILURE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause:: + RRC_CONNECTION_OUT_OF_SERVICE_DURING_CELL_REGISTER == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + RRC_CONNECTION_OUT_OF_SERVICE_DURING_CELL_REGISTER)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::RRC_CONNECTION_ABORT_REQUEST == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::RRC_CONNECTION_ABORT_REQUEST)); +static_assert(aidl::android::hardware::radio::DataCallFailCause:: + RRC_CONNECTION_SYSTEM_INFORMATION_BLOCK_READ_ERROR == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + RRC_CONNECTION_SYSTEM_INFORMATION_BLOCK_READ_ERROR)); +static_assert(aidl::android::hardware::radio::DataCallFailCause:: + NETWORK_INITIATED_DETACH_WITH_AUTO_REATTACH == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + NETWORK_INITIATED_DETACH_WITH_AUTO_REATTACH)); +static_assert(aidl::android::hardware::radio::DataCallFailCause:: + NETWORK_INITIATED_DETACH_NO_AUTO_REATTACH == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + NETWORK_INITIATED_DETACH_NO_AUTO_REATTACH)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::ESM_PROCEDURE_TIME_OUT == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::ESM_PROCEDURE_TIME_OUT)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::INVALID_CONNECTION_ID == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::INVALID_CONNECTION_ID)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::MAXIMIUM_NSAPIS_EXCEEDED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::MAXIMIUM_NSAPIS_EXCEEDED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::INVALID_PRIMARY_NSAPI == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::INVALID_PRIMARY_NSAPI)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::CANNOT_ENCODE_OTA_MESSAGE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::CANNOT_ENCODE_OTA_MESSAGE)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::RADIO_ACCESS_BEARER_SETUP_FAILURE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + RADIO_ACCESS_BEARER_SETUP_FAILURE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::PDP_ESTABLISH_TIMEOUT_EXPIRED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + PDP_ESTABLISH_TIMEOUT_EXPIRED)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::PDP_MODIFY_TIMEOUT_EXPIRED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::PDP_MODIFY_TIMEOUT_EXPIRED)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::PDP_INACTIVE_TIMEOUT_EXPIRED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::PDP_INACTIVE_TIMEOUT_EXPIRED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::PDP_LOWERLAYER_ERROR == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::PDP_LOWERLAYER_ERROR)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::PDP_MODIFY_COLLISION == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::PDP_MODIFY_COLLISION)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::MAXINUM_SIZE_OF_L2_MESSAGE_EXCEEDED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + MAXINUM_SIZE_OF_L2_MESSAGE_EXCEEDED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::NAS_REQUEST_REJECTED_BY_NETWORK == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + NAS_REQUEST_REJECTED_BY_NETWORK)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::RRC_CONNECTION_INVALID_REQUEST == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + RRC_CONNECTION_INVALID_REQUEST)); +static_assert(aidl::android::hardware::radio::DataCallFailCause:: + RRC_CONNECTION_TRACKING_AREA_ID_CHANGED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + RRC_CONNECTION_TRACKING_AREA_ID_CHANGED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::RRC_CONNECTION_RF_UNAVAILABLE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + RRC_CONNECTION_RF_UNAVAILABLE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause:: + RRC_CONNECTION_ABORTED_DUE_TO_IRAT_CHANGE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + RRC_CONNECTION_ABORTED_DUE_TO_IRAT_CHANGE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause:: + RRC_CONNECTION_RELEASED_SECURITY_NOT_ACTIVE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + RRC_CONNECTION_RELEASED_SECURITY_NOT_ACTIVE)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::RRC_CONNECTION_ABORTED_AFTER_HANDOVER == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + RRC_CONNECTION_ABORTED_AFTER_HANDOVER)); +static_assert(aidl::android::hardware::radio::DataCallFailCause:: + RRC_CONNECTION_ABORTED_AFTER_IRAT_CELL_CHANGE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + RRC_CONNECTION_ABORTED_AFTER_IRAT_CELL_CHANGE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause:: + RRC_CONNECTION_ABORTED_DURING_IRAT_CELL_CHANGE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + RRC_CONNECTION_ABORTED_DURING_IRAT_CELL_CHANGE)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::IMSI_UNKNOWN_IN_HOME_SUBSCRIBER_SERVER == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + IMSI_UNKNOWN_IN_HOME_SUBSCRIBER_SERVER)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::IMEI_NOT_ACCEPTED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::IMEI_NOT_ACCEPTED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause:: + EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::EPS_SERVICES_NOT_ALLOWED_IN_PLMN == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + EPS_SERVICES_NOT_ALLOWED_IN_PLMN)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::MSC_TEMPORARILY_NOT_REACHABLE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + MSC_TEMPORARILY_NOT_REACHABLE)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::CS_DOMAIN_NOT_AVAILABLE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::CS_DOMAIN_NOT_AVAILABLE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::ESM_FAILURE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::ESM_FAILURE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::MAC_FAILURE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::MAC_FAILURE)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::SYNCHRONIZATION_FAILURE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::SYNCHRONIZATION_FAILURE)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::UE_SECURITY_CAPABILITIES_MISMATCH == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + UE_SECURITY_CAPABILITIES_MISMATCH)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::SECURITY_MODE_REJECTED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::SECURITY_MODE_REJECTED)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::UNACCEPTABLE_NON_EPS_AUTHENTICATION == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + UNACCEPTABLE_NON_EPS_AUTHENTICATION)); +static_assert(aidl::android::hardware::radio::DataCallFailCause:: + CS_FALLBACK_CALL_ESTABLISHMENT_NOT_ALLOWED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + CS_FALLBACK_CALL_ESTABLISHMENT_NOT_ALLOWED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::NO_EPS_BEARER_CONTEXT_ACTIVATED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + NO_EPS_BEARER_CONTEXT_ACTIVATED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::INVALID_EMM_STATE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::INVALID_EMM_STATE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::NAS_LAYER_FAILURE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::NAS_LAYER_FAILURE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::MULTIPLE_PDP_CALL_NOT_ALLOWED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + MULTIPLE_PDP_CALL_NOT_ALLOWED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::EMBMS_NOT_ENABLED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::EMBMS_NOT_ENABLED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::IRAT_HANDOVER_FAILED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::IRAT_HANDOVER_FAILED)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::EMBMS_REGULAR_DEACTIVATION == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::EMBMS_REGULAR_DEACTIVATION)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::TEST_LOOPBACK_REGULAR_DEACTIVATION == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + TEST_LOOPBACK_REGULAR_DEACTIVATION)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::LOWER_LAYER_REGISTRATION_FAILURE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + LOWER_LAYER_REGISTRATION_FAILURE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::DATA_PLAN_EXPIRED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::DATA_PLAN_EXPIRED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::UMTS_HANDOVER_TO_IWLAN == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::UMTS_HANDOVER_TO_IWLAN)); +static_assert(aidl::android::hardware::radio::DataCallFailCause:: + EVDO_CONNECTION_DENY_BY_GENERAL_OR_NETWORK_BUSY == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + EVDO_CONNECTION_DENY_BY_GENERAL_OR_NETWORK_BUSY)); +static_assert(aidl::android::hardware::radio::DataCallFailCause:: + EVDO_CONNECTION_DENY_BY_BILLING_OR_AUTHENTICATION_FAILURE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + EVDO_CONNECTION_DENY_BY_BILLING_OR_AUTHENTICATION_FAILURE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::EVDO_HDR_CHANGED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::EVDO_HDR_CHANGED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::EVDO_HDR_EXITED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::EVDO_HDR_EXITED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::EVDO_HDR_NO_SESSION == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::EVDO_HDR_NO_SESSION)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::EVDO_USING_GPS_FIX_INSTEAD_OF_HDR_CALL == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + EVDO_USING_GPS_FIX_INSTEAD_OF_HDR_CALL)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::EVDO_HDR_CONNECTION_SETUP_TIMEOUT == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + EVDO_HDR_CONNECTION_SETUP_TIMEOUT)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::FAILED_TO_ACQUIRE_COLOCATED_HDR == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + FAILED_TO_ACQUIRE_COLOCATED_HDR)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::OTASP_COMMIT_IN_PROGRESS == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::OTASP_COMMIT_IN_PROGRESS)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::NO_HYBRID_HDR_SERVICE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::NO_HYBRID_HDR_SERVICE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::HDR_NO_LOCK_GRANTED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::HDR_NO_LOCK_GRANTED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::DBM_OR_SMS_IN_PROGRESS == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::DBM_OR_SMS_IN_PROGRESS)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::HDR_FADE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::HDR_FADE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::HDR_ACCESS_FAILURE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::HDR_ACCESS_FAILURE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::UNSUPPORTED_1X_PREV == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::UNSUPPORTED_1X_PREV)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::LOCAL_END == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::LOCAL_END)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::NO_SERVICE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::NO_SERVICE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::FADE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::FADE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::NORMAL_RELEASE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::NORMAL_RELEASE)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::ACCESS_ATTEMPT_ALREADY_IN_PROGRESS == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + ACCESS_ATTEMPT_ALREADY_IN_PROGRESS)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::REDIRECTION_OR_HANDOFF_IN_PROGRESS == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + REDIRECTION_OR_HANDOFF_IN_PROGRESS)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::EMERGENCY_MODE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::EMERGENCY_MODE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::PHONE_IN_USE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::PHONE_IN_USE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::INVALID_MODE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::INVALID_MODE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::INVALID_SIM_STATE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::INVALID_SIM_STATE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::NO_COLLOCATED_HDR == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::NO_COLLOCATED_HDR)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::UE_IS_ENTERING_POWERSAVE_MODE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + UE_IS_ENTERING_POWERSAVE_MODE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::DUAL_SWITCH == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::DUAL_SWITCH)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::PPP_TIMEOUT == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::PPP_TIMEOUT)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::PPP_AUTH_FAILURE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::PPP_AUTH_FAILURE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::PPP_OPTION_MISMATCH == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::PPP_OPTION_MISMATCH)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::PPP_PAP_FAILURE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::PPP_PAP_FAILURE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::PPP_CHAP_FAILURE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::PPP_CHAP_FAILURE)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::PPP_CLOSE_IN_PROGRESS == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::PPP_CLOSE_IN_PROGRESS)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::LIMITED_TO_IPV4 == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::LIMITED_TO_IPV4)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::LIMITED_TO_IPV6 == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::LIMITED_TO_IPV6)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::VSNCP_TIMEOUT == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::VSNCP_TIMEOUT)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::VSNCP_GEN_ERROR == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::VSNCP_GEN_ERROR)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::VSNCP_APN_UNAUTHORIZED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::VSNCP_APN_UNATHORIZED)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::VSNCP_PDN_LIMIT_EXCEEDED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::VSNCP_PDN_LIMIT_EXCEEDED)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::VSNCP_NO_PDN_GATEWAY_ADDRESS == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::VSNCP_NO_PDN_GATEWAY_ADDRESS)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::VSNCP_PDN_GATEWAY_UNREACHABLE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + VSNCP_PDN_GATEWAY_UNREACHABLE)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::VSNCP_PDN_GATEWAY_REJECT == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::VSNCP_PDN_GATEWAY_REJECT)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::VSNCP_INSUFFICIENT_PARAMETERS == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + VSNCP_INSUFFICIENT_PARAMETERS)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::VSNCP_RESOURCE_UNAVAILABLE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::VSNCP_RESOURCE_UNAVAILABLE)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::VSNCP_ADMINISTRATIVELY_PROHIBITED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + VSNCP_ADMINISTRATIVELY_PROHIBITED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::VSNCP_PDN_ID_IN_USE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::VSNCP_PDN_ID_IN_USE)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::VSNCP_SUBSCRIBER_LIMITATION == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::VSNCP_SUBSCRIBER_LIMITATION)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::VSNCP_PDN_EXISTS_FOR_THIS_APN == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause:: + VSNCP_PDN_EXISTS_FOR_THIS_APN)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::VSNCP_RECONNECT_NOT_ALLOWED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::VSNCP_RECONNECT_NOT_ALLOWED)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::IPV6_PREFIX_UNAVAILABLE == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::IPV6_PREFIX_UNAVAILABLE)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::HANDOFF_PREFERENCE_CHANGED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::HANDOFF_PREFERENCE_CHANGED)); +static_assert(aidl::android::hardware::radio::DataCallFailCause::SLICE_REJECTED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::SLICE_REJECTED)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::MATCH_ALL_RULE_NOT_ALLOWED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::MATCH_ALL_RULE_NOT_ALLOWED)); +static_assert( + aidl::android::hardware::radio::DataCallFailCause::ALL_MATCHING_RULES_FAILED == + static_cast( + ::android::hardware::radio::V1_6::DataCallFailCause::ALL_MATCHING_RULES_FAILED)); + +static_assert(aidl::android::hardware::radio::SliceStatus::UNKNOWN == + static_cast( + ::android::hardware::radio::V1_6::SliceStatus::UNKNOWN)); +static_assert(aidl::android::hardware::radio::SliceStatus::CONFIGURED == + static_cast( + ::android::hardware::radio::V1_6::SliceStatus::CONFIGURED)); +static_assert(aidl::android::hardware::radio::SliceStatus::ALLOWED == + static_cast( + ::android::hardware::radio::V1_6::SliceStatus::ALLOWED)); +static_assert( + aidl::android::hardware::radio::SliceStatus::REJECTED_NOT_AVAILABLE_IN_PLMN == + static_cast( + ::android::hardware::radio::V1_6::SliceStatus::REJECTED_NOT_AVAILABLE_IN_PLMN)); +static_assert( + aidl::android::hardware::radio::SliceStatus::REJECTED_NOT_AVAILABLE_IN_REG_AREA == + static_cast( + ::android::hardware::radio::V1_6::SliceStatus::REJECTED_NOT_AVAILABLE_IN_REG_AREA)); +static_assert(aidl::android::hardware::radio::SliceStatus::DEFAULT_CONFIGURED == + static_cast( + ::android::hardware::radio::V1_6::SliceStatus::DEFAULT_CONFIGURED)); + +static_assert(aidl::android::hardware::radio::SscMode::MODE_1 == + static_cast( + ::android::hardware::radio::V1_6::SscMode::MODE_1)); +static_assert(aidl::android::hardware::radio::SscMode::MODE_2 == + static_cast( + ::android::hardware::radio::V1_6::SscMode::MODE_2)); +static_assert(aidl::android::hardware::radio::SscMode::MODE_3 == + static_cast( + ::android::hardware::radio::V1_6::SscMode::MODE_3)); + +static_assert(aidl::android::hardware::radio::PublicKeyType::EPDG == + static_cast( + ::android::hardware::radio::V1_6::PublicKeyType::EPDG)); +static_assert(aidl::android::hardware::radio::PublicKeyType::WLAN == + static_cast( + ::android::hardware::radio::V1_6::PublicKeyType::WLAN)); + +static_assert(aidl::android::hardware::radio::PbReceivedStatus::PB_RECEIVED_OK == + static_cast( + ::android::hardware::radio::V1_6::PbReceivedStatus::PB_RECEIVED_OK)); +static_assert(aidl::android::hardware::radio::PbReceivedStatus::PB_RECEIVED_ERROR == + static_cast( + ::android::hardware::radio::V1_6::PbReceivedStatus::PB_RECEIVED_ERROR)); +static_assert(aidl::android::hardware::radio::PbReceivedStatus::PB_RECEIVED_ABORT == + static_cast( + ::android::hardware::radio::V1_6::PbReceivedStatus::PB_RECEIVED_ABORT)); +static_assert(aidl::android::hardware::radio::PbReceivedStatus::PB_RECEIVED_FINAL == + static_cast( + ::android::hardware::radio::V1_6::PbReceivedStatus::PB_RECEIVED_FINAL)); + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::IccIo& in, + aidl::android::hardware::radio::IccIo* out) { + out->command = static_cast(in.command); + out->fileId = static_cast(in.fileId); + out->path = in.path; + out->p1 = static_cast(in.p1); + out->p2 = static_cast(in.p2); + out->p3 = static_cast(in.p3); + out->data = in.data; + out->pin2 = in.pin2; + out->aid = in.aid; + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::NeighboringCell& in, + aidl::android::hardware::radio::NeighboringCell* out) { + out->cid = in.cid; + out->rssi = static_cast(in.rssi); + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::UusInfo& in, + aidl::android::hardware::radio::UusInfo* out) { + out->uusType = static_cast(in.uusType); + out->uusDcs = static_cast(in.uusDcs); + out->uusData = in.uusData; + return true; +} + +__attribute__((warn_unused_result)) bool translate(const ::android::hardware::radio::V1_0::Dial& in, + aidl::android::hardware::radio::Dial* out) { + out->address = in.address; + out->clir = static_cast(in.clir); + { + size_t size = in.uusInfo.size(); + aidl::android::hardware::radio::UusInfo uusInfo; + for (size_t i = 0; i < size; i++) { + if (!translate(in.uusInfo[i], &uusInfo)) return false; + out->uusInfo.push_back(uusInfo); + } + } + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::LastCallFailCauseInfo& in, + aidl::android::hardware::radio::LastCallFailCauseInfo* out) { + out->causeCode = static_cast(in.causeCode); + out->vendorCause = in.vendorCause; + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::GsmSignalStrength& in, + aidl::android::hardware::radio::GsmSignalStrength* out) { + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.signalStrength > std::numeric_limits::max() || in.signalStrength < 0) { + return false; + } + out->signalStrength = static_cast(in.signalStrength); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.bitErrorRate > std::numeric_limits::max() || in.bitErrorRate < 0) { + return false; + } + out->bitErrorRate = static_cast(in.bitErrorRate); + out->timingAdvance = static_cast(in.timingAdvance); + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::CdmaSignalStrength& in, + aidl::android::hardware::radio::CdmaSignalStrength* out) { + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.dbm > std::numeric_limits::max() || in.dbm < 0) { + return false; + } + out->dbm = static_cast(in.dbm); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.ecio > std::numeric_limits::max() || in.ecio < 0) { + return false; + } + out->ecio = static_cast(in.ecio); + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::EvdoSignalStrength& in, + aidl::android::hardware::radio::EvdoSignalStrength* out) { + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.dbm > std::numeric_limits::max() || in.dbm < 0) { + return false; + } + out->dbm = static_cast(in.dbm); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.ecio > std::numeric_limits::max() || in.ecio < 0) { + return false; + } + out->ecio = static_cast(in.ecio); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.signalNoiseRatio > std::numeric_limits::max() || in.signalNoiseRatio < 0) { + return false; + } + out->signalNoiseRatio = static_cast(in.signalNoiseRatio); + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::SendSmsResult& in, + aidl::android::hardware::radio::SendSmsResult* out) { + out->messageRef = static_cast(in.messageRef); + out->ackPDU = in.ackPDU; + out->errorCode = static_cast(in.errorCode); + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::IccIoResult& in, + aidl::android::hardware::radio::IccIoResult* out) { + out->sw1 = static_cast(in.sw1); + out->sw2 = static_cast(in.sw2); + out->simResponse = in.simResponse; + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::CallForwardInfo& in, + aidl::android::hardware::radio::CallForwardInfo* out) { + out->status = static_cast(in.status); + out->reason = static_cast(in.reason); + out->serviceClass = static_cast(in.serviceClass); + out->toa = static_cast(in.toa); + out->number = in.number; + out->timeSeconds = static_cast(in.timeSeconds); + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::OperatorInfo& in, + aidl::android::hardware::radio::OperatorInfo* out) { + out->alphaLong = in.alphaLong; + out->alphaShort = in.alphaShort; + out->operatorNumeric = in.operatorNumeric; + out->status = static_cast(in.status); + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::SmsWriteArgs& in, + aidl::android::hardware::radio::SmsWriteArgs* out) { + out->status = static_cast(in.status); + out->pdu = in.pdu; + out->smsc = in.smsc; + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::CdmaSmsAddress& in, + aidl::android::hardware::radio::CdmaSmsAddress* out) { + out->digitMode = static_cast(in.digitMode); + out->numberMode = static_cast(in.numberMode); + out->numberType = static_cast(in.numberType); + out->numberPlan = static_cast(in.numberPlan); + { + size_t size = in.digits.size(); + for (size_t i = 0; i < size; i++) { + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.digits[i] > std::numeric_limits::max() || in.digits[i] < 0) { + return false; + } + out->digits.push_back(static_cast(in.digits[i])); + } + } + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::CdmaSmsSubaddress& in, + aidl::android::hardware::radio::CdmaSmsSubaddress* out) { + out->subaddressType = + static_cast(in.subaddressType); + out->odd = static_cast(in.odd); + { + size_t size = in.digits.size(); + for (size_t i = 0; i < size; i++) { + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.digits[i] > std::numeric_limits::max() || in.digits[i] < 0) { + return false; + } + out->digits.push_back(static_cast(in.digits[i])); + } + } + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::CdmaSmsMessage& in, + aidl::android::hardware::radio::CdmaSmsMessage* out) { + out->teleserviceId = static_cast(in.teleserviceId); + out->isServicePresent = static_cast(in.isServicePresent); + out->serviceCategory = static_cast(in.serviceCategory); + if (!translate(in.address, &out->address)) return false; + if (!translate(in.subAddress, &out->subAddress)) return false; + { + size_t size = in.bearerData.size(); + for (size_t i = 0; i < size; i++) { + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.bearerData[i] > std::numeric_limits::max() || in.bearerData[i] < 0) { + return false; + } + out->bearerData.push_back(static_cast(in.bearerData[i])); + } + } + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::CdmaSmsAck& in, + aidl::android::hardware::radio::CdmaSmsAck* out) { + out->errorClass = static_cast(in.errorClass); + out->smsCauseCode = static_cast(in.smsCauseCode); + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::CdmaBroadcastSmsConfigInfo& in, + aidl::android::hardware::radio::CdmaBroadcastSmsConfigInfo* out) { + out->serviceCategory = static_cast(in.serviceCategory); + out->language = static_cast(in.language); + out->selected = static_cast(in.selected); + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::CdmaSmsWriteArgs& in, + aidl::android::hardware::radio::CdmaSmsWriteArgs* out) { + out->status = static_cast(in.status); + if (!translate(in.message, &out->message)) return false; + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::GsmBroadcastSmsConfigInfo& in, + aidl::android::hardware::radio::GsmBroadcastSmsConfigInfo* out) { + out->fromServiceId = static_cast(in.fromServiceId); + out->toServiceId = static_cast(in.toServiceId); + out->fromCodeScheme = static_cast(in.fromCodeScheme); + out->toCodeScheme = static_cast(in.toCodeScheme); + out->selected = static_cast(in.selected); + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::GsmSmsMessage& in, + aidl::android::hardware::radio::GsmSmsMessage* out) { + out->smscPdu = in.smscPdu; + out->pdu = in.pdu; + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::ImsSmsMessage& in, + aidl::android::hardware::radio::ImsSmsMessage* out) { + out->tech = static_cast(in.tech); + out->retry = static_cast(in.retry); + out->messageRef = static_cast(in.messageRef); + { + size_t size = in.cdmaMessage.size(); + aidl::android::hardware::radio::CdmaSmsMessage cdmaMessage; + for (size_t i = 0; i < size; i++) { + if (!translate(in.cdmaMessage[i], &cdmaMessage)) return false; + out->cdmaMessage.push_back(cdmaMessage); + } + } + { + size_t size = in.gsmMessage.size(); + aidl::android::hardware::radio::GsmSmsMessage gsmMessage; + for (size_t i = 0; i < size; i++) { + if (!translate(in.gsmMessage[i], &gsmMessage)) return false; + out->gsmMessage.push_back(gsmMessage); + } + } + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::SimApdu& in, + aidl::android::hardware::radio::SimApdu* out) { + out->sessionId = static_cast(in.sessionId); + out->cla = static_cast(in.cla); + out->instruction = static_cast(in.instruction); + out->p1 = static_cast(in.p1); + out->p2 = static_cast(in.p2); + out->p3 = static_cast(in.p3); + out->data = in.data; + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::NvWriteItem& in, + aidl::android::hardware::radio::NvWriteItem* out) { + out->itemId = static_cast(in.itemId); + out->value = in.value; + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::SelectUiccSub& in, + aidl::android::hardware::radio::SelectUiccSub* out) { + out->slot = static_cast(in.slot); + out->appIndex = static_cast(in.appIndex); + out->subType = static_cast(in.subType); + out->actStatus = static_cast(in.actStatus); + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::HardwareConfigModem& in, + aidl::android::hardware::radio::HardwareConfigModem* out) { + out->rilModel = static_cast(in.rilModel); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.rat > std::numeric_limits::max() || in.rat < 0) { + return false; + } + out->rat = static_cast(in.rat); + out->maxVoice = static_cast(in.maxVoice); + out->maxData = static_cast(in.maxData); + out->maxStandby = static_cast(in.maxStandby); + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::HardwareConfigSim& in, + aidl::android::hardware::radio::HardwareConfigSim* out) { + out->modemUuid = in.modemUuid; + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::HardwareConfig& in, + aidl::android::hardware::radio::HardwareConfig* out) { + out->type = static_cast(in.type); + out->uuid = in.uuid; + out->state = static_cast(in.state); + { + size_t size = in.modem.size(); + aidl::android::hardware::radio::HardwareConfigModem modem; + for (size_t i = 0; i < size; i++) { + if (!translate(in.modem[i], &modem)) return false; + out->modem.push_back(modem); + } + } + { + size_t size = in.sim.size(); + aidl::android::hardware::radio::HardwareConfigSim sim; + for (size_t i = 0; i < size; i++) { + if (!translate(in.sim[i], &sim)) return false; + out->sim.push_back(sim); + } + } + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::LceStatusInfo& in, + aidl::android::hardware::radio::LceStatusInfo* out) { + out->lceStatus = static_cast(in.lceStatus); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.actualIntervalMs > std::numeric_limits::max() || in.actualIntervalMs < 0) { + return false; + } + out->actualIntervalMs = static_cast(in.actualIntervalMs); + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::LceDataInfo& in, + aidl::android::hardware::radio::LceDataInfo* out) { + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.lastHopCapacityKbps > std::numeric_limits::max() || + in.lastHopCapacityKbps < 0) { + return false; + } + out->lastHopCapacityKbps = static_cast(in.lastHopCapacityKbps); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.confidenceLevel > std::numeric_limits::max() || in.confidenceLevel < 0) { + return false; + } + out->confidenceLevel = static_cast(in.confidenceLevel); + out->lceSuspended = static_cast(in.lceSuspended); + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::ActivityStatsInfo& in, + aidl::android::hardware::radio::ActivityStatsInfo* out) { + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.sleepModeTimeMs > std::numeric_limits::max() || in.sleepModeTimeMs < 0) { + return false; + } + out->sleepModeTimeMs = static_cast(in.sleepModeTimeMs); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.idleModeTimeMs > std::numeric_limits::max() || in.idleModeTimeMs < 0) { + return false; + } + out->idleModeTimeMs = static_cast(in.idleModeTimeMs); + { + size_t size = sizeof(in.txmModetimeMs) / sizeof(in.txmModetimeMs[0]); + for (size_t i = 0; i < size; i++) { + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.txmModetimeMs[i] > std::numeric_limits::max() || + in.txmModetimeMs[i] < 0) { + return false; + } + out->txmModetimeMs.push_back(static_cast(in.txmModetimeMs[i])); + } + } + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.rxModeTimeMs > std::numeric_limits::max() || in.rxModeTimeMs < 0) { + return false; + } + out->rxModeTimeMs = static_cast(in.rxModeTimeMs); + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::Carrier& in, + aidl::android::hardware::radio::Carrier* out) { + out->mcc = in.mcc; + out->mnc = in.mnc; + out->matchType = static_cast(in.matchType); + out->matchData = in.matchData; + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::CarrierRestrictions& in, + aidl::android::hardware::radio::CarrierRestrictions* out) { + { + size_t size = in.allowedCarriers.size(); + aidl::android::hardware::radio::Carrier allowedCarriers; + for (size_t i = 0; i < size; i++) { + if (!translate(in.allowedCarriers[i], &allowedCarriers)) return false; + out->allowedCarriers.push_back(allowedCarriers); + } + } + { + size_t size = in.excludedCarriers.size(); + aidl::android::hardware::radio::Carrier excludedCarriers; + for (size_t i = 0; i < size; i++) { + if (!translate(in.excludedCarriers[i], &excludedCarriers)) return false; + out->excludedCarriers.push_back(excludedCarriers); + } + } + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::SuppSvcNotification& in, + aidl::android::hardware::radio::SuppSvcNotification* out) { + out->isMT = static_cast(in.isMT); + out->code = static_cast(in.code); + out->index = static_cast(in.index); + out->type = static_cast(in.type); + out->number = in.number; + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::SimRefreshResult& in, + aidl::android::hardware::radio::SimRefreshResult* out) { + out->type = static_cast(in.type); + out->efId = static_cast(in.efId); + out->aid = in.aid; + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::CdmaSignalInfoRecord& in, + aidl::android::hardware::radio::CdmaSignalInfoRecord* out) { + out->isPresent = static_cast(in.isPresent); + out->signalType = static_cast(in.signalType); + out->alertPitch = static_cast(in.alertPitch); + out->signal = static_cast(in.signal); + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::CdmaCallWaiting& in, + aidl::android::hardware::radio::CdmaCallWaiting* out) { + out->number = in.number; + out->numberPresentation = + static_cast( + in.numberPresentation); + out->name = in.name; + if (!translate(in.signalInfoRecord, &out->signalInfoRecord)) return false; + out->numberType = + static_cast(in.numberType); + out->numberPlan = + static_cast(in.numberPlan); + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::CdmaDisplayInfoRecord& in, + aidl::android::hardware::radio::CdmaDisplayInfoRecord* out) { + out->alphaBuf = in.alphaBuf; + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::CdmaNumberInfoRecord& in, + aidl::android::hardware::radio::CdmaNumberInfoRecord* out) { + out->number = in.number; + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.numberType > std::numeric_limits::max() || in.numberType < 0) { + return false; + } + out->numberType = static_cast(in.numberType); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.numberPlan > std::numeric_limits::max() || in.numberPlan < 0) { + return false; + } + out->numberPlan = static_cast(in.numberPlan); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.pi > std::numeric_limits::max() || in.pi < 0) { + return false; + } + out->pi = static_cast(in.pi); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.si > std::numeric_limits::max() || in.si < 0) { + return false; + } + out->si = static_cast(in.si); + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::CdmaRedirectingNumberInfoRecord& in, + aidl::android::hardware::radio::CdmaRedirectingNumberInfoRecord* out) { + if (!translate(in.redirectingNumber, &out->redirectingNumber)) return false; + out->redirectingReason = static_cast( + in.redirectingReason); + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::CdmaLineControlInfoRecord& in, + aidl::android::hardware::radio::CdmaLineControlInfoRecord* out) { + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.lineCtrlPolarityIncluded > std::numeric_limits::max() || + in.lineCtrlPolarityIncluded < 0) { + return false; + } + out->lineCtrlPolarityIncluded = static_cast(in.lineCtrlPolarityIncluded); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.lineCtrlToggle > std::numeric_limits::max() || in.lineCtrlToggle < 0) { + return false; + } + out->lineCtrlToggle = static_cast(in.lineCtrlToggle); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.lineCtrlReverse > std::numeric_limits::max() || in.lineCtrlReverse < 0) { + return false; + } + out->lineCtrlReverse = static_cast(in.lineCtrlReverse); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.lineCtrlPowerDenial > std::numeric_limits::max() || in.lineCtrlPowerDenial < 0) { + return false; + } + out->lineCtrlPowerDenial = static_cast(in.lineCtrlPowerDenial); + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::CdmaT53ClirInfoRecord& in, + aidl::android::hardware::radio::CdmaT53ClirInfoRecord* out) { + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.cause > std::numeric_limits::max() || in.cause < 0) { + return false; + } + out->cause = static_cast(in.cause); + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::CdmaT53AudioControlInfoRecord& in, + aidl::android::hardware::radio::CdmaT53AudioControlInfoRecord* out) { + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.upLink > std::numeric_limits::max() || in.upLink < 0) { + return false; + } + out->upLink = static_cast(in.upLink); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.downLink > std::numeric_limits::max() || in.downLink < 0) { + return false; + } + out->downLink = static_cast(in.downLink); + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::CdmaInformationRecord& in, + aidl::android::hardware::radio::CdmaInformationRecord* out) { + out->name = static_cast(in.name); + { + size_t size = in.display.size(); + aidl::android::hardware::radio::CdmaDisplayInfoRecord display; + for (size_t i = 0; i < size; i++) { + if (!translate(in.display[i], &display)) return false; + out->display.push_back(display); + } + } + { + size_t size = in.number.size(); + aidl::android::hardware::radio::CdmaNumberInfoRecord number; + for (size_t i = 0; i < size; i++) { + if (!translate(in.number[i], &number)) return false; + out->number.push_back(number); + } + } + { + size_t size = in.signal.size(); + aidl::android::hardware::radio::CdmaSignalInfoRecord signal; + for (size_t i = 0; i < size; i++) { + if (!translate(in.signal[i], &signal)) return false; + out->signal.push_back(signal); + } + } + { + size_t size = in.redir.size(); + aidl::android::hardware::radio::CdmaRedirectingNumberInfoRecord redir; + for (size_t i = 0; i < size; i++) { + if (!translate(in.redir[i], &redir)) return false; + out->redir.push_back(redir); + } + } + { + size_t size = in.lineCtrl.size(); + aidl::android::hardware::radio::CdmaLineControlInfoRecord lineCtrl; + for (size_t i = 0; i < size; i++) { + if (!translate(in.lineCtrl[i], &lineCtrl)) return false; + out->lineCtrl.push_back(lineCtrl); + } + } + { + size_t size = in.clir.size(); + aidl::android::hardware::radio::CdmaT53ClirInfoRecord clir; + for (size_t i = 0; i < size; i++) { + if (!translate(in.clir[i], &clir)) return false; + out->clir.push_back(clir); + } + } + { + size_t size = in.audioCtrl.size(); + aidl::android::hardware::radio::CdmaT53AudioControlInfoRecord audioCtrl; + for (size_t i = 0; i < size; i++) { + if (!translate(in.audioCtrl[i], &audioCtrl)) return false; + out->audioCtrl.push_back(audioCtrl); + } + } + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::CdmaInformationRecords& in, + aidl::android::hardware::radio::CdmaInformationRecords* out) { + { + size_t size = in.infoRec.size(); + aidl::android::hardware::radio::CdmaInformationRecord infoRec; + for (size_t i = 0; i < size; i++) { + if (!translate(in.infoRec[i], &infoRec)) return false; + out->infoRec.push_back(infoRec); + } + } + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::CfData& in, + aidl::android::hardware::radio::CfData* out) { + { + size_t size = in.cfInfo.size(); + aidl::android::hardware::radio::CallForwardInfo cfInfo; + for (size_t i = 0; i < size; i++) { + if (!translate(in.cfInfo[i], &cfInfo)) return false; + out->cfInfo.push_back(cfInfo); + } + } + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::SsInfoData& in, + aidl::android::hardware::radio::SsInfoData* out) { + { + size_t size = in.ssInfo.size(); + for (size_t i = 0; i < size; i++) { + out->ssInfo.push_back(static_cast(in.ssInfo[i])); + } + } + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::StkCcUnsolSsResult& in, + aidl::android::hardware::radio::StkCcUnsolSsResult* out) { + out->serviceType = static_cast(in.serviceType); + out->requestType = static_cast(in.requestType); + out->teleserviceType = + static_cast(in.teleserviceType); + out->serviceClass = + static_cast(in.serviceClass); + out->result = static_cast(in.result); + { + size_t size = in.ssInfo.size(); + aidl::android::hardware::radio::SsInfoData ssInfo; + for (size_t i = 0; i < size; i++) { + if (!translate(in.ssInfo[i], &ssInfo)) return false; + out->ssInfo.push_back(ssInfo); + } + } + { + size_t size = in.cfData.size(); + aidl::android::hardware::radio::CfData cfData; + for (size_t i = 0; i < size; i++) { + if (!translate(in.cfData[i], &cfData)) return false; + out->cfData.push_back(cfData); + } + } + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::PcoDataInfo& in, + aidl::android::hardware::radio::PcoDataInfo* out) { + out->cid = static_cast(in.cid); + out->bearerProto = in.bearerProto; + out->pcoId = static_cast(in.pcoId); + { + size_t size = in.contents.size(); + for (size_t i = 0; i < size; i++) { + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.contents[i] > std::numeric_limits::max() || in.contents[i] < 0) { + return false; + } + out->contents.push_back(static_cast(in.contents[i])); + } + } + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_1::KeepaliveRequest& in, + aidl::android::hardware::radio::KeepaliveRequest* out) { + out->type = static_cast(in.type); + { + size_t size = in.sourceAddress.size(); + for (size_t i = 0; i < size; i++) { + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.sourceAddress[i] > std::numeric_limits::max() || + in.sourceAddress[i] < 0) { + return false; + } + out->sourceAddress.push_back(static_cast(in.sourceAddress[i])); + } + } + out->sourcePort = static_cast(in.sourcePort); + { + size_t size = in.destinationAddress.size(); + for (size_t i = 0; i < size; i++) { + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.destinationAddress[i] > std::numeric_limits::max() || + in.destinationAddress[i] < 0) { + return false; + } + out->destinationAddress.push_back(static_cast(in.destinationAddress[i])); + } + } + out->destinationPort = static_cast(in.destinationPort); + out->maxKeepaliveIntervalMillis = static_cast(in.maxKeepaliveIntervalMillis); + out->cid = static_cast(in.cid); + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_1::KeepaliveStatus& in, + aidl::android::hardware::radio::KeepaliveStatus* out) { + out->sessionHandle = static_cast(in.sessionHandle); + out->code = static_cast(in.code); + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_2::CellIdentityOperatorNames& in, + aidl::android::hardware::radio::CellIdentityOperatorNames* out) { + out->alphaLong = in.alphaLong; + out->alphaShort = in.alphaShort; + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_2::CellIdentityCdma& in, + aidl::android::hardware::radio::CellIdentityCdma* out) { + out->networkId = static_cast(in.base.networkId); + out->systemId = static_cast(in.base.systemId); + out->baseStationId = static_cast(in.base.baseStationId); + out->longitude = static_cast(in.base.longitude); + out->latitude = static_cast(in.base.latitude); + if (!translate(in.operatorNames, &out->operatorNames)) return false; + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_2::CellInfoCdma& in, + aidl::android::hardware::radio::CellInfoCdma* out) { + if (!translate(in.cellIdentityCdma, &out->cellIdentityCdma)) return false; + if (!translate(in.signalStrengthCdma, &out->signalStrengthCdma)) return false; + if (!translate(in.signalStrengthEvdo, &out->signalStrengthEvdo)) return false; + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_2::WcdmaSignalStrength& in, + aidl::android::hardware::radio::WcdmaSignalStrength* out) { + out->signalStrength = static_cast(in.base.signalStrength); + out->bitErrorRate = static_cast(in.base.bitErrorRate); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.rscp > std::numeric_limits::max() || in.rscp < 0) { + return false; + } + out->rscp = static_cast(in.rscp); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.ecno > std::numeric_limits::max() || in.ecno < 0) { + return false; + } + out->ecno = static_cast(in.ecno); + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_2::TdscdmaSignalStrength& in, + aidl::android::hardware::radio::TdscdmaSignalStrength* out) { + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.signalStrength > std::numeric_limits::max() || in.signalStrength < 0) { + return false; + } + out->signalStrength = static_cast(in.signalStrength); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.bitErrorRate > std::numeric_limits::max() || in.bitErrorRate < 0) { + return false; + } + out->bitErrorRate = static_cast(in.bitErrorRate); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.rscp > std::numeric_limits::max() || in.rscp < 0) { + return false; + } + out->rscp = static_cast(in.rscp); + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_2::VoiceRegStateResult& in, + aidl::android::hardware::radio::VoiceRegStateResult* out) { + out->regState = static_cast(in.regState); + out->rat = static_cast(in.rat); + out->cssSupported = static_cast(in.cssSupported); + out->roamingIndicator = static_cast(in.roamingIndicator); + out->systemIsInPrl = static_cast(in.systemIsInPrl); + out->defaultRoamingIndicator = static_cast(in.defaultRoamingIndicator); + out->reasonForDenial = static_cast(in.reasonForDenial); + // FIXME Unknown type: android.hardware.radio@1.2::CellIdentity + // That type's package needs to be converted separately and the corresponding translate function + // should be added here. + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_3::RadioResponseInfoModem& in, + aidl::android::hardware::radio::RadioResponseInfoModem* out) { + out->type = static_cast(in.type); + out->serial = static_cast(in.serial); + out->error = static_cast(in.error); + out->isEnabled = static_cast(in.isEnabled); + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_4::EmergencyNumber& in, + aidl::android::hardware::radio::EmergencyNumber* out) { + out->number = in.number; + out->mcc = in.mcc; + out->mnc = in.mnc; + out->categories = + static_cast(in.categories); + { + size_t size = in.urns.size(); + for (size_t i = 0; i < size; i++) { + out->urns.push_back(in.urns[i]); + } + } + out->sources = static_cast(in.sources); + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_4::RadioFrequencyInfo& in, + aidl::android::hardware::radio::RadioFrequencyInfo* out) { + switch (in.getDiscriminator()) { + case ::android::hardware::radio::V1_4::RadioFrequencyInfo::hidl_discriminator::range: + *out = static_cast(in.range()); + break; + case ::android::hardware::radio::V1_4::RadioFrequencyInfo::hidl_discriminator:: + channelNumber: + *out = static_cast(in.channelNumber()); + break; + default: + return false; + } + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_4::LteVopsInfo& in, + aidl::android::hardware::radio::LteVopsInfo* out) { + out->isVopsSupported = static_cast(in.isVopsSupported); + out->isEmcBearerSupported = static_cast(in.isEmcBearerSupported); + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_4::NrIndicators& in, + aidl::android::hardware::radio::NrIndicators* out) { + out->isEndcAvailable = static_cast(in.isEndcAvailable); + out->isDcNrRestricted = static_cast(in.isDcNrRestricted); + out->isNrAvailable = static_cast(in.isNrAvailable); + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_4::DataRegStateResult& in, + aidl::android::hardware::radio::DataRegStateResult* out) { + out->regState = static_cast(in.base.regState); + out->rat = static_cast(in.base.rat); + out->reasonDataDenied = static_cast(in.base.reasonDataDenied); + out->maxDataCalls = static_cast(in.base.maxDataCalls); + // FIXME Unknown type: android.hardware.radio@1.2::CellIdentity + // That type's package needs to be converted separately and the corresponding translate function + // should be added here. + if (!translate(in.vopsInfo, &out->vopsInfo)) return false; + if (!translate(in.nrIndicators, &out->nrIndicators)) return false; + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_4::DataRegStateResult::VopsInfo& in, + aidl::android::hardware::radio::DataRegStateResultVopsInfo* out) { + switch (in.getDiscriminator()) { + case ::android::hardware::radio::V1_4::DataRegStateResult::VopsInfo::hidl_discriminator:: + noinit: + // Nothing to translate for Monostate. + break; + case ::android::hardware::radio::V1_4::DataRegStateResult::VopsInfo::hidl_discriminator:: + lteVopsInfo: { + aidl::android::hardware::radio::LteVopsInfo lteVopsInfo; + if (!translate(in.lteVopsInfo(), <eVopsInfo)) return false; + out->set( + lteVopsInfo); + } break; + default: + return false; + } + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_4::CellConfigLte& in, + aidl::android::hardware::radio::CellConfigLte* out) { + out->isEndcAvailable = static_cast(in.isEndcAvailable); + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_4::CellInfo::Info& in, + aidl::android::hardware::radio::CellInfoInfo* out) { + switch (in.getDiscriminator()) { + case ::android::hardware::radio::V1_4::CellInfo::Info::hidl_discriminator::gsm: + // FIXME Unknown type: android.hardware.radio@1.2::CellInfoGsm + // That type's package needs to be converted separately and the corresponding translate + // function should be added here. + break; + case ::android::hardware::radio::V1_4::CellInfo::Info::hidl_discriminator::cdma: { + aidl::android::hardware::radio::CellInfoCdma cdma; + if (!translate(in.cdma(), &cdma)) return false; + out->set(cdma); + } break; + case ::android::hardware::radio::V1_4::CellInfo::Info::hidl_discriminator::wcdma: + // FIXME Unknown type: android.hardware.radio@1.2::CellInfoWcdma + // That type's package needs to be converted separately and the corresponding translate + // function should be added here. + break; + case ::android::hardware::radio::V1_4::CellInfo::Info::hidl_discriminator::tdscdma: + // FIXME Unknown type: android.hardware.radio@1.2::CellInfoTdscdma + // That type's package needs to be converted separately and the corresponding translate + // function should be added here. + break; + case ::android::hardware::radio::V1_4::CellInfo::Info::hidl_discriminator::lte: + // FIXME Unknown type: android.hardware.radio@1.4::CellInfoLte + // That type's package needs to be converted separately and the corresponding translate + // function should be added here. + break; + case ::android::hardware::radio::V1_4::CellInfo::Info::hidl_discriminator::nr: + // FIXME Unknown type: android.hardware.radio@1.4::CellInfoNr + // That type's package needs to be converted separately and the corresponding translate + // function should be added here. + break; + default: + return false; + } + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_4::RadioCapability& in, + aidl::android::hardware::radio::RadioCapability* out) { + out->session = static_cast(in.session); + out->phase = static_cast(in.phase); + out->raf = static_cast(in.raf); + out->logicalModemUuid = in.logicalModemUuid; + out->status = static_cast(in.status); + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_4::CarrierRestrictionsWithPriority& in, + aidl::android::hardware::radio::CarrierRestrictionsWithPriority* out) { + { + size_t size = in.allowedCarriers.size(); + aidl::android::hardware::radio::Carrier allowedCarriers; + for (size_t i = 0; i < size; i++) { + if (!translate(in.allowedCarriers[i], &allowedCarriers)) return false; + out->allowedCarriers.push_back(allowedCarriers); + } + } + { + size_t size = in.excludedCarriers.size(); + aidl::android::hardware::radio::Carrier excludedCarriers; + for (size_t i = 0; i < size; i++) { + if (!translate(in.excludedCarriers[i], &excludedCarriers)) return false; + out->excludedCarriers.push_back(excludedCarriers); + } + } + out->allowedCarriersPrioritized = static_cast(in.allowedCarriersPrioritized); + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_5::RadioAccessSpecifier& in, + aidl::android::hardware::radio::RadioAccessSpecifier* out) { + out->radioAccessNetwork = + static_cast(in.radioAccessNetwork); + if (!translate(in.bands, &out->bands)) return false; + { + size_t size = in.channels.size(); + for (size_t i = 0; i < size; i++) { + out->channels.push_back(static_cast(in.channels[i])); + } + } + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands& in, + aidl::android::hardware::radio::RadioAccessSpecifierBands* out) { + switch (in.getDiscriminator()) { + case ::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands::hidl_discriminator:: + geranBands: { + ::android::hardware::hidl_vec<::android::hardware::radio::V1_1::GeranBands> geranBands = + in.geranBands(); + size_t size = geranBands.size(); + for (size_t i = 0; i < size; i++) { + out->get() + .push_back(static_cast( + geranBands[i])); + } + } break; + case ::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands::hidl_discriminator:: + utranBands: { + ::android::hardware::hidl_vec<::android::hardware::radio::V1_5::UtranBands> utranBands = + in.utranBands(); + size_t size = utranBands.size(); + for (size_t i = 0; i < size; i++) { + out->get() + .push_back(static_cast( + utranBands[i])); + } + } break; + case ::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands::hidl_discriminator:: + eutranBands: { + ::android::hardware::hidl_vec<::android::hardware::radio::V1_5::EutranBands> + eutranBands = in.eutranBands(); + size_t size = eutranBands.size(); + for (size_t i = 0; i < size; i++) { + out->get() + .push_back(static_cast( + eutranBands[i])); + } + } break; + case ::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands::hidl_discriminator:: + ngranBands: { + ::android::hardware::hidl_vec<::android::hardware::radio::V1_5::NgranBands> ngranBands = + in.ngranBands(); + size_t size = ngranBands.size(); + for (size_t i = 0; i < size; i++) { + out->get() + .push_back(static_cast( + ngranBands[i])); + } + } break; + default: + return false; + } + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_5::SignalThresholdInfo& in, + aidl::android::hardware::radio::SignalThresholdInfo* out) { + out->signalMeasurement = static_cast( + in.signalMeasurement); + out->hysteresisMs = static_cast(in.hysteresisMs); + out->hysteresisDb = static_cast(in.hysteresisDb); + { + size_t size = in.thresholds.size(); + for (size_t i = 0; i < size; i++) { + out->thresholds.push_back(static_cast(in.thresholds[i])); + } + } + out->isEnabled = static_cast(in.isEnabled); + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_5::NetworkScanRequest& in, + aidl::android::hardware::radio::NetworkScanRequest* out) { + out->type = static_cast(in.type); + out->interval = static_cast(in.interval); + { + size_t size = in.specifiers.size(); + aidl::android::hardware::radio::RadioAccessSpecifier specifiers; + for (size_t i = 0; i < size; i++) { + if (!translate(in.specifiers[i], &specifiers)) return false; + out->specifiers.push_back(specifiers); + } + } + out->maxSearchTime = static_cast(in.maxSearchTime); + out->incrementalResults = static_cast(in.incrementalResults); + out->incrementalResultsPeriodicity = static_cast(in.incrementalResultsPeriodicity); + { + size_t size = in.mccMncs.size(); + for (size_t i = 0; i < size; i++) { + out->mccMncs.push_back(in.mccMncs[i]); + } + } + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_5::DataProfileInfo& in, + aidl::android::hardware::radio::DataProfileInfo* out) { + out->profileId = static_cast(in.profileId); + out->apn = in.apn; + out->protocol = static_cast(in.protocol); + out->roamingProtocol = + static_cast(in.roamingProtocol); + out->authType = static_cast(in.authType); + out->user = in.user; + out->password = in.password; + out->type = static_cast(in.type); + out->maxConnsTime = static_cast(in.maxConnsTime); + out->maxConns = static_cast(in.maxConns); + out->waitTime = static_cast(in.waitTime); + out->enabled = static_cast(in.enabled); + out->supportedApnTypesBitmap = + static_cast(in.supportedApnTypesBitmap); + out->bearerBitmap = + static_cast(in.bearerBitmap); + out->mtuV4 = static_cast(in.mtuV4); + out->mtuV6 = static_cast(in.mtuV6); + out->preferred = static_cast(in.preferred); + out->persistent = static_cast(in.persistent); + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_5::LinkAddress& in, + aidl::android::hardware::radio::LinkAddress* out) { + out->address = in.address; + out->properties = static_cast(in.properties); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.deprecationTime > std::numeric_limits::max() || in.deprecationTime < 0) { + return false; + } + out->deprecationTime = static_cast(in.deprecationTime); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.expirationTime > std::numeric_limits::max() || in.expirationTime < 0) { + return false; + } + out->expirationTime = static_cast(in.expirationTime); + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_5::ClosedSubscriberGroupInfo& in, + aidl::android::hardware::radio::ClosedSubscriberGroupInfo* out) { + out->csgIndication = static_cast(in.csgIndication); + out->homeNodebName = in.homeNodebName; + out->csgIdentity = static_cast(in.csgIdentity); + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_5::OptionalCsgInfo& in, + aidl::android::hardware::radio::OptionalCsgInfo* out) { + switch (in.getDiscriminator()) { + case ::android::hardware::radio::V1_5::OptionalCsgInfo::hidl_discriminator::noinit: + // Nothing to translate for Monostate. + break; + case ::android::hardware::radio::V1_5::OptionalCsgInfo::hidl_discriminator::csgInfo: { + aidl::android::hardware::radio::ClosedSubscriberGroupInfo csgInfo; + if (!translate(in.csgInfo(), &csgInfo)) return false; + out->set(csgInfo); + } break; + default: + return false; + } + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_5::CellIdentityGsm& in, + aidl::android::hardware::radio::CellIdentityGsm* out) { + out->mcc = in.base.base.mcc; + out->mnc = in.base.base.mnc; + out->lac = static_cast(in.base.base.lac); + out->cid = static_cast(in.base.base.cid); + out->arfcn = static_cast(in.base.base.arfcn); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.base.base.bsic > std::numeric_limits::max() || in.base.base.bsic < 0) { + return false; + } + out->bsic = static_cast(in.base.base.bsic); + if (!translate(in.base.operatorNames, &out->operatorNames)) return false; + { + size_t size = in.additionalPlmns.size(); + for (size_t i = 0; i < size; i++) { + out->additionalPlmns.push_back(in.additionalPlmns[i]); + } + } + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_5::CellIdentityWcdma& in, + aidl::android::hardware::radio::CellIdentityWcdma* out) { + out->mcc = in.base.base.mcc; + out->mnc = in.base.base.mnc; + out->lac = static_cast(in.base.base.lac); + out->cid = static_cast(in.base.base.cid); + out->psc = static_cast(in.base.base.psc); + out->uarfcn = static_cast(in.base.base.uarfcn); + if (!translate(in.base.operatorNames, &out->operatorNames)) return false; + { + size_t size = in.additionalPlmns.size(); + for (size_t i = 0; i < size; i++) { + out->additionalPlmns.push_back(in.additionalPlmns[i]); + } + } + if (!translate(in.optionalCsgInfo, &out->optionalCsgInfo)) return false; + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_5::CellIdentityTdscdma& in, + aidl::android::hardware::radio::CellIdentityTdscdma* out) { + out->mcc = in.base.base.mcc; + out->mnc = in.base.base.mnc; + out->lac = static_cast(in.base.base.lac); + out->cid = static_cast(in.base.base.cid); + out->cpid = static_cast(in.base.base.cpid); + out->uarfcn = static_cast(in.base.uarfcn); + if (!translate(in.base.operatorNames, &out->operatorNames)) return false; + { + size_t size = in.additionalPlmns.size(); + for (size_t i = 0; i < size; i++) { + out->additionalPlmns.push_back(in.additionalPlmns[i]); + } + } + if (!translate(in.optionalCsgInfo, &out->optionalCsgInfo)) return false; + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_5::CellIdentityLte& in, + aidl::android::hardware::radio::CellIdentityLte* out) { + out->mcc = in.base.base.mcc; + out->mnc = in.base.base.mnc; + out->ci = static_cast(in.base.base.ci); + out->pci = static_cast(in.base.base.pci); + out->tac = static_cast(in.base.base.tac); + out->earfcn = static_cast(in.base.base.earfcn); + if (!translate(in.base.operatorNames, &out->operatorNames)) return false; + out->bandwidth = static_cast(in.base.bandwidth); + { + size_t size = in.additionalPlmns.size(); + for (size_t i = 0; i < size; i++) { + out->additionalPlmns.push_back(in.additionalPlmns[i]); + } + } + if (!translate(in.optionalCsgInfo, &out->optionalCsgInfo)) return false; + { + size_t size = in.bands.size(); + for (size_t i = 0; i < size; i++) { + out->bands.push_back( + static_cast(in.bands[i])); + } + } + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_5::CellIdentityNr& in, + aidl::android::hardware::radio::CellIdentityNr* out) { + out->mcc = in.base.mcc; + out->mnc = in.base.mnc; + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.base.nci > std::numeric_limits::max() || in.base.nci < 0) { + return false; + } + out->nci = static_cast(in.base.nci); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.base.pci > std::numeric_limits::max() || in.base.pci < 0) { + return false; + } + out->pci = static_cast(in.base.pci); + out->tac = static_cast(in.base.tac); + out->nrarfcn = static_cast(in.base.nrarfcn); + if (!translate(in.base.operatorNames, &out->operatorNames)) return false; + { + size_t size = in.additionalPlmns.size(); + for (size_t i = 0; i < size; i++) { + out->additionalPlmns.push_back(in.additionalPlmns[i]); + } + } + { + size_t size = in.bands.size(); + for (size_t i = 0; i < size; i++) { + out->bands.push_back( + static_cast(in.bands[i])); + } + } + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_5::CellInfoGsm& in, + aidl::android::hardware::radio::CellInfoGsm* out) { + if (!translate(in.cellIdentityGsm, &out->cellIdentityGsm)) return false; + if (!translate(in.signalStrengthGsm, &out->signalStrengthGsm)) return false; + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_5::CellInfoWcdma& in, + aidl::android::hardware::radio::CellInfoWcdma* out) { + if (!translate(in.cellIdentityWcdma, &out->cellIdentityWcdma)) return false; + if (!translate(in.signalStrengthWcdma, &out->signalStrengthWcdma)) return false; + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_5::CellInfoTdscdma& in, + aidl::android::hardware::radio::CellInfoTdscdma* out) { + if (!translate(in.cellIdentityTdscdma, &out->cellIdentityTdscdma)) return false; + if (!translate(in.signalStrengthTdscdma, &out->signalStrengthTdscdma)) return false; + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_5::CellIdentity& in, + aidl::android::hardware::radio::CellIdentity* out) { + switch (in.getDiscriminator()) { + case ::android::hardware::radio::V1_5::CellIdentity::hidl_discriminator::noinit: + // Nothing to translate for Monostate. + break; + case ::android::hardware::radio::V1_5::CellIdentity::hidl_discriminator::gsm: { + aidl::android::hardware::radio::CellIdentityGsm gsm; + if (!translate(in.gsm(), &gsm)) return false; + out->set(gsm); + } break; + case ::android::hardware::radio::V1_5::CellIdentity::hidl_discriminator::wcdma: { + aidl::android::hardware::radio::CellIdentityWcdma wcdma; + if (!translate(in.wcdma(), &wcdma)) return false; + out->set(wcdma); + } break; + case ::android::hardware::radio::V1_5::CellIdentity::hidl_discriminator::tdscdma: { + aidl::android::hardware::radio::CellIdentityTdscdma tdscdma; + if (!translate(in.tdscdma(), &tdscdma)) return false; + out->set(tdscdma); + } break; + case ::android::hardware::radio::V1_5::CellIdentity::hidl_discriminator::cdma: { + aidl::android::hardware::radio::CellIdentityCdma cdma; + if (!translate(in.cdma(), &cdma)) return false; + out->set(cdma); + } break; + case ::android::hardware::radio::V1_5::CellIdentity::hidl_discriminator::lte: { + aidl::android::hardware::radio::CellIdentityLte lte; + if (!translate(in.lte(), <e)) return false; + out->set(lte); + } break; + case ::android::hardware::radio::V1_5::CellIdentity::hidl_discriminator::nr: { + aidl::android::hardware::radio::CellIdentityNr nr; + if (!translate(in.nr(), &nr)) return false; + out->set(nr); + } break; + default: + return false; + } + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_5::BarringInfo& in, + aidl::android::hardware::radio::BarringInfo* out) { + out->serviceType = + static_cast(in.serviceType); + out->barringType = + static_cast(in.barringType); + if (!translate(in.barringTypeSpecificInfo, &out->barringTypeSpecificInfo)) return false; + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_5::BarringInfo::BarringTypeSpecificInfo::Conditional& + in, + aidl::android::hardware::radio::BarringInfoBarringTypeSpecificInfoConditional* out) { + out->factor = static_cast(in.factor); + out->timeSeconds = static_cast(in.timeSeconds); + out->isBarred = static_cast(in.isBarred); + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_5::BarringInfo::BarringTypeSpecificInfo& in, + aidl::android::hardware::radio::BarringInfoBarringTypeSpecificInfo* out) { + switch (in.getDiscriminator()) { + case ::android::hardware::radio::V1_5::BarringInfo::BarringTypeSpecificInfo:: + hidl_discriminator::noinit: + // Nothing to translate for Monostate. + break; + case ::android::hardware::radio::V1_5::BarringInfo::BarringTypeSpecificInfo:: + hidl_discriminator::conditional: { + aidl::android::hardware::radio::BarringInfoBarringTypeSpecificInfoConditional + conditional; + if (!translate(in.conditional(), &conditional)) return false; + out->set(conditional); + } break; + default: + return false; + } + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_5::RegStateResult::AccessTechnologySpecificInfo:: + Cdma2000RegistrationInfo& in, + aidl::android::hardware::radio:: + RegStateResultAccessTechnologySpecificInfoCdma2000RegistrationInfo* out) { + out->cssSupported = static_cast(in.cssSupported); + out->roamingIndicator = static_cast(in.roamingIndicator); + out->systemIsInPrl = + static_cast(in.systemIsInPrl); + out->defaultRoamingIndicator = static_cast(in.defaultRoamingIndicator); + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_5::RegStateResult::AccessTechnologySpecificInfo:: + EutranRegistrationInfo& in, + aidl::android::hardware::radio:: + RegStateResultAccessTechnologySpecificInfoEutranRegistrationInfo* out) { + if (!translate(in.lteVopsInfo, &out->lteVopsInfo)) return false; + if (!translate(in.nrIndicators, &out->nrIndicators)) return false; + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_5::AppStatus& in, + aidl::android::hardware::radio::AppStatus* out) { + out->appType = static_cast(in.base.appType); + out->appState = static_cast(in.base.appState); + out->persoSubstate = + static_cast(in.persoSubstate); + out->aidPtr = in.base.aidPtr; + out->appLabelPtr = in.base.appLabelPtr; + out->pin1Replaced = static_cast(in.base.pin1Replaced); + out->pin1 = static_cast(in.base.pin1); + out->pin2 = static_cast(in.base.pin2); + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_5::CardStatus& in, + aidl::android::hardware::radio::CardStatus* out) { + out->cardState = + static_cast(in.base.base.base.cardState); + out->universalPinState = static_cast( + in.base.base.base.universalPinState); + out->gsmUmtsSubscriptionAppIndex = + static_cast(in.base.base.base.gsmUmtsSubscriptionAppIndex); + out->cdmaSubscriptionAppIndex = + static_cast(in.base.base.base.cdmaSubscriptionAppIndex); + out->imsSubscriptionAppIndex = static_cast(in.base.base.base.imsSubscriptionAppIndex); + { + size_t size = in.applications.size(); + aidl::android::hardware::radio::AppStatus applications; + for (size_t i = 0; i < size; i++) { + if (!translate(in.applications[i], &applications)) return false; + out->applications.push_back(applications); + } + } + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.base.base.physicalSlotId > std::numeric_limits::max() || + in.base.base.physicalSlotId < 0) { + return false; + } + out->physicalSlotId = static_cast(in.base.base.physicalSlotId); + out->atr = in.base.base.atr; + out->iccid = in.base.base.iccid; + out->eid = in.base.eid; + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::QosBandwidth& in, + aidl::android::hardware::radio::QosBandwidth* out) { + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.maxBitrateKbps > std::numeric_limits::max() || in.maxBitrateKbps < 0) { + return false; + } + out->maxBitrateKbps = static_cast(in.maxBitrateKbps); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.guaranteedBitrateKbps > std::numeric_limits::max() || + in.guaranteedBitrateKbps < 0) { + return false; + } + out->guaranteedBitrateKbps = static_cast(in.guaranteedBitrateKbps); + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::EpsQos& in, + aidl::android::hardware::radio::EpsQos* out) { + out->qci = static_cast(in.qci); + if (!translate(in.downlink, &out->downlink)) return false; + if (!translate(in.uplink, &out->uplink)) return false; + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::NrQos& in, + aidl::android::hardware::radio::NrQos* out) { + out->fiveQi = static_cast(in.fiveQi); + if (!translate(in.downlink, &out->downlink)) return false; + if (!translate(in.uplink, &out->uplink)) return false; + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.qfi > std::numeric_limits::max() || in.qfi < 0) { + return false; + } + out->qfi = static_cast(in.qfi); + out->averagingWindowMs = static_cast(in.averagingWindowMs); + return true; +} + +__attribute__((warn_unused_result)) bool translate(const ::android::hardware::radio::V1_6::Qos& in, + aidl::android::hardware::radio::Qos* out) { + switch (in.getDiscriminator()) { + case ::android::hardware::radio::V1_6::Qos::hidl_discriminator::noinit: + // Nothing to translate for Monostate. + break; + case ::android::hardware::radio::V1_6::Qos::hidl_discriminator::eps: { + aidl::android::hardware::radio::EpsQos eps; + if (!translate(in.eps(), &eps)) return false; + out->set(eps); + } break; + case ::android::hardware::radio::V1_6::Qos::hidl_discriminator::nr: { + aidl::android::hardware::radio::NrQos nr; + if (!translate(in.nr(), &nr)) return false; + out->set(nr); + } break; + default: + return false; + } + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::RadioResponseInfo& in, + aidl::android::hardware::radio::RadioResponseInfo* out) { + out->type = static_cast(in.type); + out->serial = static_cast(in.serial); + out->error = static_cast(in.error); + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::PortRange& in, + aidl::android::hardware::radio::PortRange* out) { + out->start = static_cast(in.start); + out->end = static_cast(in.end); + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::MaybePort& in, + aidl::android::hardware::radio::MaybePort* out) { + switch (in.getDiscriminator()) { + case ::android::hardware::radio::V1_6::MaybePort::hidl_discriminator::noinit: + // Nothing to translate for Monostate. + break; + case ::android::hardware::radio::V1_6::MaybePort::hidl_discriminator::range: { + aidl::android::hardware::radio::PortRange range; + if (!translate(in.range(), &range)) return false; + out->set(range); + } break; + default: + return false; + } + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::QosFilter& in, + aidl::android::hardware::radio::QosFilter* out) { + { + size_t size = in.localAddresses.size(); + for (size_t i = 0; i < size; i++) { + out->localAddresses.push_back(in.localAddresses[i]); + } + } + { + size_t size = in.remoteAddresses.size(); + for (size_t i = 0; i < size; i++) { + out->remoteAddresses.push_back(in.remoteAddresses[i]); + } + } + if (!translate(in.localPort, &out->localPort)) return false; + if (!translate(in.remotePort, &out->remotePort)) return false; + out->protocol = static_cast(in.protocol); + if (!translate(in.tos, &out->tos)) return false; + if (!translate(in.flowLabel, &out->flowLabel)) return false; + if (!translate(in.spi, &out->spi)) return false; + out->direction = static_cast(in.direction); + out->precedence = static_cast(in.precedence); + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::QosFilter::TypeOfService& in, + aidl::android::hardware::radio::QosFilterTypeOfService* out) { + switch (in.getDiscriminator()) { + case ::android::hardware::radio::V1_6::QosFilter::TypeOfService::hidl_discriminator::noinit: + // Nothing to translate for Monostate. + break; + case ::android::hardware::radio::V1_6::QosFilter::TypeOfService::hidl_discriminator::value: + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.value() > std::numeric_limits::max() || in.value() < 0) { + return false; + } + *out = static_cast(in.value()); + break; + default: + return false; + } + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::QosFilter::Ipv6FlowLabel& in, + aidl::android::hardware::radio::QosFilterIpv6FlowLabel* out) { + switch (in.getDiscriminator()) { + case ::android::hardware::radio::V1_6::QosFilter::Ipv6FlowLabel::hidl_discriminator::noinit: + // Nothing to translate for Monostate. + break; + case ::android::hardware::radio::V1_6::QosFilter::Ipv6FlowLabel::hidl_discriminator::value: + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.value() > std::numeric_limits::max() || in.value() < 0) { + return false; + } + *out = static_cast(in.value()); + break; + default: + return false; + } + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::QosFilter::IpsecSpi& in, + aidl::android::hardware::radio::QosFilterIpsecSpi* out) { + switch (in.getDiscriminator()) { + case ::android::hardware::radio::V1_6::QosFilter::IpsecSpi::hidl_discriminator::noinit: + // Nothing to translate for Monostate. + break; + case ::android::hardware::radio::V1_6::QosFilter::IpsecSpi::hidl_discriminator::value: + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.value() > std::numeric_limits::max() || in.value() < 0) { + return false; + } + *out = static_cast(in.value()); + break; + default: + return false; + } + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::QosSession& in, + aidl::android::hardware::radio::QosSession* out) { + out->qosSessionId = static_cast(in.qosSessionId); + if (!translate(in.qos, &out->qos)) return false; + { + size_t size = in.qosFilters.size(); + aidl::android::hardware::radio::QosFilter qosFilters; + for (size_t i = 0; i < size; i++) { + if (!translate(in.qosFilters[i], &qosFilters)) return false; + out->qosFilters.push_back(qosFilters); + } + } + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::SetupDataCallResult& in, + aidl::android::hardware::radio::SetupDataCallResult* out) { + out->cause = static_cast(in.cause); + out->suggestedRetryTime = static_cast(in.suggestedRetryTime); + out->cid = static_cast(in.cid); + out->active = static_cast(in.active); + out->type = static_cast(in.type); + out->ifname = in.ifname; + { + size_t size = in.addresses.size(); + aidl::android::hardware::radio::LinkAddress addresses; + for (size_t i = 0; i < size; i++) { + if (!translate(in.addresses[i], &addresses)) return false; + out->addresses.push_back(addresses); + } + } + { + size_t size = in.dnses.size(); + for (size_t i = 0; i < size; i++) { + out->dnses.push_back(in.dnses[i]); + } + } + { + size_t size = in.gateways.size(); + for (size_t i = 0; i < size; i++) { + out->gateways.push_back(in.gateways[i]); + } + } + { + size_t size = in.pcscf.size(); + for (size_t i = 0; i < size; i++) { + out->pcscf.push_back(in.pcscf[i]); + } + } + out->mtuV4 = static_cast(in.mtuV4); + out->mtuV6 = static_cast(in.mtuV6); + if (!translate(in.defaultQos, &out->defaultQos)) return false; + { + size_t size = in.qosSessions.size(); + aidl::android::hardware::radio::QosSession qosSessions; + for (size_t i = 0; i < size; i++) { + if (!translate(in.qosSessions[i], &qosSessions)) return false; + out->qosSessions.push_back(qosSessions); + } + } + out->handoverFailureMode = static_cast( + in.handoverFailureMode); + out->pduSessionId = static_cast(in.pduSessionId); + if (!translate(in.sliceInfo, &out->sliceInfo)) return false; + { + size_t size = in.trafficDescriptors.size(); + aidl::android::hardware::radio::TrafficDescriptor trafficDescriptors; + for (size_t i = 0; i < size; i++) { + if (!translate(in.trafficDescriptors[i], &trafficDescriptors)) return false; + out->trafficDescriptors.push_back(trafficDescriptors); + } + } + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::LinkCapacityEstimate& in, + aidl::android::hardware::radio::LinkCapacityEstimate* out) { + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.downlinkCapacityKbps > std::numeric_limits::max() || + in.downlinkCapacityKbps < 0) { + return false; + } + out->downlinkCapacityKbps = static_cast(in.downlinkCapacityKbps); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.uplinkCapacityKbps > std::numeric_limits::max() || in.uplinkCapacityKbps < 0) { + return false; + } + out->uplinkCapacityKbps = static_cast(in.uplinkCapacityKbps); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.secondaryDownlinkCapacityKbps > std::numeric_limits::max() || + in.secondaryDownlinkCapacityKbps < 0) { + return false; + } + out->secondaryDownlinkCapacityKbps = static_cast(in.secondaryDownlinkCapacityKbps); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.secondaryUplinkCapacityKbps > std::numeric_limits::max() || + in.secondaryUplinkCapacityKbps < 0) { + return false; + } + out->secondaryUplinkCapacityKbps = static_cast(in.secondaryUplinkCapacityKbps); + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::NrVopsInfo& in, + aidl::android::hardware::radio::NrVopsInfo* out) { + out->vopsSupported = + static_cast(in.vopsSupported); + out->emcSupported = static_cast(in.emcSupported); + out->emfSupported = static_cast(in.emfSupported); + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::LteSignalStrength& in, + aidl::android::hardware::radio::LteSignalStrength* out) { + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.base.signalStrength > std::numeric_limits::max() || + in.base.signalStrength < 0) { + return false; + } + out->signalStrength = static_cast(in.base.signalStrength); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.base.rsrp > std::numeric_limits::max() || in.base.rsrp < 0) { + return false; + } + out->rsrp = static_cast(in.base.rsrp); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.base.rsrq > std::numeric_limits::max() || in.base.rsrq < 0) { + return false; + } + out->rsrq = static_cast(in.base.rsrq); + out->rssnr = static_cast(in.base.rssnr); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.base.cqi > std::numeric_limits::max() || in.base.cqi < 0) { + return false; + } + out->cqi = static_cast(in.base.cqi); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.base.timingAdvance > std::numeric_limits::max() || in.base.timingAdvance < 0) { + return false; + } + out->timingAdvance = static_cast(in.base.timingAdvance); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.cqiTableIndex > std::numeric_limits::max() || in.cqiTableIndex < 0) { + return false; + } + out->cqiTableIndex = static_cast(in.cqiTableIndex); + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::NrSignalStrength& in, + aidl::android::hardware::radio::NrSignalStrength* out) { + out->ssRsrp = static_cast(in.base.ssRsrp); + out->ssRsrq = static_cast(in.base.ssRsrq); + out->ssSinr = static_cast(in.base.ssSinr); + out->csiRsrp = static_cast(in.base.csiRsrp); + out->csiRsrq = static_cast(in.base.csiRsrq); + out->csiSinr = static_cast(in.base.csiSinr); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.csiCqiTableIndex > std::numeric_limits::max() || in.csiCqiTableIndex < 0) { + return false; + } + out->csiCqiTableIndex = static_cast(in.csiCqiTableIndex); + { + size_t size = in.csiCqiReport.size(); + for (size_t i = 0; i < size; i++) { + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.csiCqiReport[i] > std::numeric_limits::max() || in.csiCqiReport[i] < 0) { + return false; + } + out->csiCqiReport.push_back(static_cast(in.csiCqiReport[i])); + } + } + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::SignalStrength& in, + aidl::android::hardware::radio::SignalStrength* out) { + if (!translate(in.gsm, &out->gsm)) return false; + if (!translate(in.cdma, &out->cdma)) return false; + if (!translate(in.evdo, &out->evdo)) return false; + if (!translate(in.lte, &out->lte)) return false; + if (!translate(in.tdscdma, &out->tdscdma)) return false; + if (!translate(in.wcdma, &out->wcdma)) return false; + if (!translate(in.nr, &out->nr)) return false; + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::CellInfoLte& in, + aidl::android::hardware::radio::CellInfoLte* out) { + if (!translate(in.cellIdentityLte, &out->cellIdentityLte)) return false; + if (!translate(in.signalStrengthLte, &out->signalStrengthLte)) return false; + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::CellInfoNr& in, + aidl::android::hardware::radio::CellInfoNr* out) { + if (!translate(in.cellIdentityNr, &out->cellIdentityNr)) return false; + if (!translate(in.signalStrengthNr, &out->signalStrengthNr)) return false; + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::CellInfo& in, + aidl::android::hardware::radio::CellInfo* out) { + out->registered = static_cast(in.registered); + out->connectionStatus = + static_cast(in.connectionStatus); + if (!translate(in.ratSpecificInfo, &out->ratSpecificInfo)) return false; + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::CellInfo::CellInfoRatSpecificInfo& in, + aidl::android::hardware::radio::CellInfoCellInfoRatSpecificInfo* out) { + switch (in.getDiscriminator()) { + case ::android::hardware::radio::V1_6::CellInfo::CellInfoRatSpecificInfo:: + hidl_discriminator::gsm: { + aidl::android::hardware::radio::CellInfoGsm gsm; + if (!translate(in.gsm(), &gsm)) return false; + out->set(gsm); + } break; + case ::android::hardware::radio::V1_6::CellInfo::CellInfoRatSpecificInfo:: + hidl_discriminator::wcdma: { + aidl::android::hardware::radio::CellInfoWcdma wcdma; + if (!translate(in.wcdma(), &wcdma)) return false; + out->set(wcdma); + } break; + case ::android::hardware::radio::V1_6::CellInfo::CellInfoRatSpecificInfo:: + hidl_discriminator::tdscdma: { + aidl::android::hardware::radio::CellInfoTdscdma tdscdma; + if (!translate(in.tdscdma(), &tdscdma)) return false; + out->set( + tdscdma); + } break; + case ::android::hardware::radio::V1_6::CellInfo::CellInfoRatSpecificInfo:: + hidl_discriminator::lte: { + aidl::android::hardware::radio::CellInfoLte lte; + if (!translate(in.lte(), <e)) return false; + out->set(lte); + } break; + case ::android::hardware::radio::V1_6::CellInfo::CellInfoRatSpecificInfo:: + hidl_discriminator::nr: { + aidl::android::hardware::radio::CellInfoNr nr; + if (!translate(in.nr(), &nr)) return false; + out->set(nr); + } break; + case ::android::hardware::radio::V1_6::CellInfo::CellInfoRatSpecificInfo:: + hidl_discriminator::cdma: { + aidl::android::hardware::radio::CellInfoCdma cdma; + if (!translate(in.cdma(), &cdma)) return false; + out->set(cdma); + } break; + default: + return false; + } + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::NetworkScanResult& in, + aidl::android::hardware::radio::NetworkScanResult* out) { + out->status = static_cast(in.status); + out->error = static_cast(in.error); + { + size_t size = in.networkInfos.size(); + aidl::android::hardware::radio::CellInfo networkInfos; + for (size_t i = 0; i < size; i++) { + if (!translate(in.networkInfos[i], &networkInfos)) return false; + out->networkInfos.push_back(networkInfos); + } + } + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::RegStateResult& in, + aidl::android::hardware::radio::RegStateResult* out) { + out->regState = static_cast(in.regState); + out->rat = static_cast(in.rat); + out->reasonForDenial = + static_cast(in.reasonForDenial); + if (!translate(in.cellIdentity, &out->cellIdentity)) return false; + out->registeredPlmn = in.registeredPlmn; + if (!translate(in.accessTechnologySpecificInfo, &out->accessTechnologySpecificInfo)) + return false; + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::RegStateResult::AccessTechnologySpecificInfo& in, + aidl::android::hardware::radio::RegStateResultAccessTechnologySpecificInfo* out) { + switch (in.getDiscriminator()) { + case ::android::hardware::radio::V1_6::RegStateResult::AccessTechnologySpecificInfo:: + hidl_discriminator::noinit: + // Nothing to translate for Monostate. + break; + case ::android::hardware::radio::V1_6::RegStateResult::AccessTechnologySpecificInfo:: + hidl_discriminator::cdmaInfo: { + aidl::android::hardware::radio:: + RegStateResultAccessTechnologySpecificInfoCdma2000RegistrationInfo cdmaInfo; + if (!translate(in.cdmaInfo(), &cdmaInfo)) return false; + out->set(cdmaInfo); + } break; + case ::android::hardware::radio::V1_6::RegStateResult::AccessTechnologySpecificInfo:: + hidl_discriminator::eutranInfo: { + aidl::android::hardware::radio:: + RegStateResultAccessTechnologySpecificInfoEutranRegistrationInfo eutranInfo; + if (!translate(in.eutranInfo(), &eutranInfo)) return false; + out->set(eutranInfo); + } break; + case ::android::hardware::radio::V1_6::RegStateResult::AccessTechnologySpecificInfo:: + hidl_discriminator::ngranNrVopsInfo: { + aidl::android::hardware::radio::NrVopsInfo ngranNrVopsInfo; + if (!translate(in.ngranNrVopsInfo(), &ngranNrVopsInfo)) return false; + out->set(ngranNrVopsInfo); + } break; + case ::android::hardware::radio::V1_6::RegStateResult::AccessTechnologySpecificInfo:: + hidl_discriminator::geranDtmSupported: + out->set(static_cast(in.geranDtmSupported())); + break; + default: + return false; + } + return true; +} + +__attribute__((warn_unused_result)) bool translate(const ::android::hardware::radio::V1_6::Call& in, + aidl::android::hardware::radio::Call* out) { + out->state = static_cast(in.base.base.state); + out->index = static_cast(in.base.base.index); + out->toa = static_cast(in.base.base.toa); + out->isMpty = static_cast(in.base.base.isMpty); + out->isMT = static_cast(in.base.base.isMT); + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.base.base.als > std::numeric_limits::max() || in.base.base.als < 0) { + return false; + } + out->als = static_cast(in.base.base.als); + out->isVoice = static_cast(in.base.base.isVoice); + out->isVoicePrivacy = static_cast(in.base.base.isVoicePrivacy); + out->number = in.base.base.number; + out->numberPresentation = static_cast( + in.base.base.numberPresentation); + out->name = in.base.base.name; + out->namePresentation = static_cast( + in.base.base.namePresentation); + { + size_t size = in.base.base.uusInfo.size(); + aidl::android::hardware::radio::UusInfo uusInfo; + for (size_t i = 0; i < size; i++) { + if (!translate(in.base.base.uusInfo[i], &uusInfo)) return false; + out->uusInfo.push_back(uusInfo); + } + } + out->audioQuality = + static_cast(in.base.audioQuality); + out->forwardedNumber = in.forwardedNumber; + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::PhysicalChannelConfig& in, + aidl::android::hardware::radio::PhysicalChannelConfig* out) { + out->status = static_cast(in.status); + out->rat = static_cast(in.rat); + out->downlinkChannelNumber = static_cast(in.downlinkChannelNumber); + out->uplinkChannelNumber = static_cast(in.uplinkChannelNumber); + out->cellBandwidthDownlinkKhz = static_cast(in.cellBandwidthDownlinkKhz); + out->cellBandwidthUplinkKhz = static_cast(in.cellBandwidthUplinkKhz); + { + size_t size = in.contextIds.size(); + for (size_t i = 0; i < size; i++) { + out->contextIds.push_back(static_cast(in.contextIds[i])); + } + } + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.physicalCellId > std::numeric_limits::max() || in.physicalCellId < 0) { + return false; + } + out->physicalCellId = static_cast(in.physicalCellId); + if (!translate(in.band, &out->band)) return false; + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::PhysicalChannelConfig::Band& in, + aidl::android::hardware::radio::PhysicalChannelConfigBand* out) { + switch (in.getDiscriminator()) { + case ::android::hardware::radio::V1_6::PhysicalChannelConfig::Band::hidl_discriminator:: + geranBand: + *out = static_cast(in.geranBand()); + break; + case ::android::hardware::radio::V1_6::PhysicalChannelConfig::Band::hidl_discriminator:: + utranBand: + *out = static_cast(in.utranBand()); + break; + case ::android::hardware::radio::V1_6::PhysicalChannelConfig::Band::hidl_discriminator:: + eutranBand: + *out = static_cast(in.eutranBand()); + break; + case ::android::hardware::radio::V1_6::PhysicalChannelConfig::Band::hidl_discriminator:: + ngranBand: + *out = static_cast(in.ngranBand()); + break; + default: + return false; + } + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::OptionalSliceInfo& in, + aidl::android::hardware::radio::OptionalSliceInfo* out) { + switch (in.getDiscriminator()) { + case ::android::hardware::radio::V1_6::OptionalSliceInfo::hidl_discriminator::noinit: + // Nothing to translate for Monostate. + break; + case ::android::hardware::radio::V1_6::OptionalSliceInfo::hidl_discriminator::value: { + aidl::android::hardware::radio::SliceInfo value; + if (!translate(in.value(), &value)) return false; + out->set(value); + } break; + default: + return false; + } + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::SliceInfo& in, + aidl::android::hardware::radio::SliceInfo* out) { + out->sst = static_cast(in.sst); + out->sliceDifferentiator = static_cast(in.sliceDifferentiator); + out->mappedHplmnSst = + static_cast(in.mappedHplmnSst); + out->mappedHplmnSD = static_cast(in.mappedHplmnSD); + out->status = static_cast(in.status); + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::OptionalDnn& in, + aidl::android::hardware::radio::OptionalDnn* out) { + switch (in.getDiscriminator()) { + case ::android::hardware::radio::V1_6::OptionalDnn::hidl_discriminator::noinit: + // Nothing to translate for Monostate. + break; + case ::android::hardware::radio::V1_6::OptionalDnn::hidl_discriminator::value: + *out = in.value(); + break; + default: + return false; + } + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::OptionalOsAppId& in, + aidl::android::hardware::radio::OptionalOsAppId* out) { + switch (in.getDiscriminator()) { + case ::android::hardware::radio::V1_6::OptionalOsAppId::hidl_discriminator::noinit: + // Nothing to translate for Monostate. + break; + case ::android::hardware::radio::V1_6::OptionalOsAppId::hidl_discriminator::value: { + aidl::android::hardware::radio::OsAppId value; + if (!translate(in.value(), &value)) return false; + out->set(value); + } break; + default: + return false; + } + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::OptionalTrafficDescriptor& in, + aidl::android::hardware::radio::OptionalTrafficDescriptor* out) { + switch (in.getDiscriminator()) { + case ::android::hardware::radio::V1_6::OptionalTrafficDescriptor::hidl_discriminator:: + noinit: + // Nothing to translate for Monostate. + break; + case ::android::hardware::radio::V1_6::OptionalTrafficDescriptor::hidl_discriminator:: + value: { + aidl::android::hardware::radio::TrafficDescriptor value; + if (!translate(in.value(), &value)) return false; + out->set(value); + } break; + default: + return false; + } + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::TrafficDescriptor& in, + aidl::android::hardware::radio::TrafficDescriptor* out) { + if (!translate(in.dnn, &out->dnn)) return false; + if (!translate(in.osAppId, &out->osAppId)) return false; + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::OsAppId& in, + aidl::android::hardware::radio::OsAppId* out) { + { + size_t size = in.osAppId.size(); + for (size_t i = 0; i < size; i++) { + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.osAppId[i] > std::numeric_limits::max() || in.osAppId[i] < 0) { + return false; + } + out->osAppId.push_back(static_cast(in.osAppId[i])); + } + } + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::SlicingConfig& in, + aidl::android::hardware::radio::SlicingConfig* out) { + { + size_t size = in.urspRules.size(); + aidl::android::hardware::radio::UrspRule urspRules; + for (size_t i = 0; i < size; i++) { + if (!translate(in.urspRules[i], &urspRules)) return false; + out->urspRules.push_back(urspRules); + } + } + { + size_t size = in.sliceInfo.size(); + aidl::android::hardware::radio::SliceInfo sliceInfo; + for (size_t i = 0; i < size; i++) { + if (!translate(in.sliceInfo[i], &sliceInfo)) return false; + out->sliceInfo.push_back(sliceInfo); + } + } + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::UrspRule& in, + aidl::android::hardware::radio::UrspRule* out) { + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.precedence > std::numeric_limits::max() || in.precedence < 0) { + return false; + } + out->precedence = static_cast(in.precedence); + { + size_t size = in.trafficDescriptors.size(); + aidl::android::hardware::radio::TrafficDescriptor trafficDescriptors; + for (size_t i = 0; i < size; i++) { + if (!translate(in.trafficDescriptors[i], &trafficDescriptors)) return false; + out->trafficDescriptors.push_back(trafficDescriptors); + } + } + { + size_t size = in.routeSelectionDescriptor.size(); + aidl::android::hardware::radio::RouteSelectionDescriptor routeSelectionDescriptor; + for (size_t i = 0; i < size; i++) { + if (!translate(in.routeSelectionDescriptor[i], &routeSelectionDescriptor)) return false; + out->routeSelectionDescriptor.push_back(routeSelectionDescriptor); + } + } + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::RouteSelectionDescriptor& in, + aidl::android::hardware::radio::RouteSelectionDescriptor* out) { + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.precedence > std::numeric_limits::max() || in.precedence < 0) { + return false; + } + out->precedence = static_cast(in.precedence); + if (!translate(in.sessionType, &out->sessionType)) return false; + if (!translate(in.sscMode, &out->sscMode)) return false; + { + size_t size = in.sliceInfo.size(); + aidl::android::hardware::radio::SliceInfo sliceInfo; + for (size_t i = 0; i < size; i++) { + if (!translate(in.sliceInfo[i], &sliceInfo)) return false; + out->sliceInfo.push_back(sliceInfo); + } + } + { + size_t size = in.dnn.size(); + for (size_t i = 0; i < size; i++) { + out->dnn.push_back(in.dnn[i]); + } + } + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::OptionalPdpProtocolType& in, + aidl::android::hardware::radio::OptionalPdpProtocolType* out) { + switch (in.getDiscriminator()) { + case ::android::hardware::radio::V1_6::OptionalPdpProtocolType::hidl_discriminator::noinit: + // Nothing to translate for Monostate. + break; + case ::android::hardware::radio::V1_6::OptionalPdpProtocolType::hidl_discriminator::value: + *out = static_cast(in.value()); + break; + default: + return false; + } + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::OptionalSscMode& in, + aidl::android::hardware::radio::OptionalSscMode* out) { + switch (in.getDiscriminator()) { + case ::android::hardware::radio::V1_6::OptionalSscMode::hidl_discriminator::noinit: + // Nothing to translate for Monostate. + break; + case ::android::hardware::radio::V1_6::OptionalSscMode::hidl_discriminator::value: + *out = static_cast(in.value()); + break; + default: + return false; + } + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::ImsiEncryptionInfo& in, + aidl::android::hardware::radio::ImsiEncryptionInfo* out) { + out->mcc = in.base.mcc; + out->mnc = in.base.mnc; + { + size_t size = in.base.carrierKey.size(); + for (size_t i = 0; i < size; i++) { + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't + // suit your needs. + if (in.base.carrierKey[i] > std::numeric_limits::max() || + in.base.carrierKey[i] < 0) { + return false; + } + out->carrierKey.push_back(static_cast(in.base.carrierKey[i])); + } + } + out->keyIdentifier = in.base.keyIdentifier; + out->expirationTime = static_cast(in.base.expirationTime); + out->keyType = static_cast(in.keyType); + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::PhonebookRecordInfo& in, + aidl::android::hardware::radio::PhonebookRecordInfo* out) { + // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit + // your needs. + if (in.recordId > std::numeric_limits::max() || in.recordId < 0) { + return false; + } + out->recordId = static_cast(in.recordId); + out->name = in.name; + out->number = in.number; + { + size_t size = in.emails.size(); + for (size_t i = 0; i < size; i++) { + out->emails.push_back(in.emails[i]); + } + } + { + size_t size = in.additionalNumbers.size(); + for (size_t i = 0; i < size; i++) { + out->additionalNumbers.push_back(in.additionalNumbers[i]); + } + } + return true; +} + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::PhonebookCapacity& in, + aidl::android::hardware::radio::PhonebookCapacity* out) { + out->maxAdnRecords = static_cast(in.maxAdnRecords); + out->usedAdnRecords = static_cast(in.usedAdnRecords); + out->maxEmailRecords = static_cast(in.maxEmailRecords); + out->usedEmailRecords = static_cast(in.usedEmailRecords); + out->maxAdditionalNumberRecords = static_cast(in.maxAdditionalNumberRecords); + out->usedAdditionalNumberRecords = static_cast(in.usedAdditionalNumberRecords); + out->maxNameLen = static_cast(in.maxNameLen); + out->maxNumberLen = static_cast(in.maxNumberLen); + out->maxEmailLen = static_cast(in.maxEmailLen); + out->maxAdditionalNumberLen = static_cast(in.maxAdditionalNumberLen); + return true; +} + +} // namespace android::h2a diff --git a/radio/aidl/include/android/hardware/radio/translate-ndk.h b/radio/aidl/include/android/hardware/radio/translate-ndk.h new file mode 100644 index 0000000000..b13602905f --- /dev/null +++ b/radio/aidl/include/android/hardware/radio/translate-ndk.h @@ -0,0 +1,699 @@ +/* + * 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 +#include "aidl/android/hardware/radio/AccessNetwork.h" +#include "aidl/android/hardware/radio/ActivityStatsInfo.h" +#include "aidl/android/hardware/radio/AddressProperty.h" +#include "aidl/android/hardware/radio/ApnAuthType.h" +#include "aidl/android/hardware/radio/ApnTypes.h" +#include "aidl/android/hardware/radio/AppState.h" +#include "aidl/android/hardware/radio/AppStatus.h" +#include "aidl/android/hardware/radio/AppType.h" +#include "aidl/android/hardware/radio/AudioQuality.h" +#include "aidl/android/hardware/radio/BarringInfo.h" +#include "aidl/android/hardware/radio/BarringInfoBarringType.h" +#include "aidl/android/hardware/radio/BarringInfoBarringTypeSpecificInfo.h" +#include "aidl/android/hardware/radio/BarringInfoBarringTypeSpecificInfoConditional.h" +#include "aidl/android/hardware/radio/BarringInfoServiceType.h" +#include "aidl/android/hardware/radio/Call.h" +#include "aidl/android/hardware/radio/CallForwardInfo.h" +#include "aidl/android/hardware/radio/CallForwardInfoStatus.h" +#include "aidl/android/hardware/radio/CallPresentation.h" +#include "aidl/android/hardware/radio/CallState.h" +#include "aidl/android/hardware/radio/CardPowerState.h" +#include "aidl/android/hardware/radio/CardState.h" +#include "aidl/android/hardware/radio/CardStatus.h" +#include "aidl/android/hardware/radio/Carrier.h" +#include "aidl/android/hardware/radio/CarrierMatchType.h" +#include "aidl/android/hardware/radio/CarrierRestrictions.h" +#include "aidl/android/hardware/radio/CarrierRestrictionsWithPriority.h" +#include "aidl/android/hardware/radio/CdmaBroadcastSmsConfigInfo.h" +#include "aidl/android/hardware/radio/CdmaCallWaiting.h" +#include "aidl/android/hardware/radio/CdmaCallWaitingNumberPlan.h" +#include "aidl/android/hardware/radio/CdmaCallWaitingNumberPresentation.h" +#include "aidl/android/hardware/radio/CdmaCallWaitingNumberType.h" +#include "aidl/android/hardware/radio/CdmaDisplayInfoRecord.h" +#include "aidl/android/hardware/radio/CdmaInfoRecName.h" +#include "aidl/android/hardware/radio/CdmaInformationRecord.h" +#include "aidl/android/hardware/radio/CdmaInformationRecords.h" +#include "aidl/android/hardware/radio/CdmaLineControlInfoRecord.h" +#include "aidl/android/hardware/radio/CdmaNumberInfoRecord.h" +#include "aidl/android/hardware/radio/CdmaOtaProvisionStatus.h" +#include "aidl/android/hardware/radio/CdmaRedirectingNumberInfoRecord.h" +#include "aidl/android/hardware/radio/CdmaRedirectingReason.h" +#include "aidl/android/hardware/radio/CdmaRoamingType.h" +#include "aidl/android/hardware/radio/CdmaSignalInfoRecord.h" +#include "aidl/android/hardware/radio/CdmaSignalStrength.h" +#include "aidl/android/hardware/radio/CdmaSmsAck.h" +#include "aidl/android/hardware/radio/CdmaSmsAddress.h" +#include "aidl/android/hardware/radio/CdmaSmsDigitMode.h" +#include "aidl/android/hardware/radio/CdmaSmsErrorClass.h" +#include "aidl/android/hardware/radio/CdmaSmsMessage.h" +#include "aidl/android/hardware/radio/CdmaSmsNumberMode.h" +#include "aidl/android/hardware/radio/CdmaSmsNumberPlan.h" +#include "aidl/android/hardware/radio/CdmaSmsNumberType.h" +#include "aidl/android/hardware/radio/CdmaSmsSubaddress.h" +#include "aidl/android/hardware/radio/CdmaSmsSubaddressType.h" +#include "aidl/android/hardware/radio/CdmaSmsWriteArgs.h" +#include "aidl/android/hardware/radio/CdmaSmsWriteArgsStatus.h" +#include "aidl/android/hardware/radio/CdmaSubscriptionSource.h" +#include "aidl/android/hardware/radio/CdmaT53AudioControlInfoRecord.h" +#include "aidl/android/hardware/radio/CdmaT53ClirInfoRecord.h" +#include "aidl/android/hardware/radio/CellConfigLte.h" +#include "aidl/android/hardware/radio/CellConnectionStatus.h" +#include "aidl/android/hardware/radio/CellIdentity.h" +#include "aidl/android/hardware/radio/CellIdentityCdma.h" +#include "aidl/android/hardware/radio/CellIdentityGsm.h" +#include "aidl/android/hardware/radio/CellIdentityLte.h" +#include "aidl/android/hardware/radio/CellIdentityNr.h" +#include "aidl/android/hardware/radio/CellIdentityOperatorNames.h" +#include "aidl/android/hardware/radio/CellIdentityTdscdma.h" +#include "aidl/android/hardware/radio/CellIdentityWcdma.h" +#include "aidl/android/hardware/radio/CellInfo.h" +#include "aidl/android/hardware/radio/CellInfoCdma.h" +#include "aidl/android/hardware/radio/CellInfoCellInfoRatSpecificInfo.h" +#include "aidl/android/hardware/radio/CellInfoGsm.h" +#include "aidl/android/hardware/radio/CellInfoInfo.h" +#include "aidl/android/hardware/radio/CellInfoLte.h" +#include "aidl/android/hardware/radio/CellInfoNr.h" +#include "aidl/android/hardware/radio/CellInfoTdscdma.h" +#include "aidl/android/hardware/radio/CellInfoType.h" +#include "aidl/android/hardware/radio/CellInfoWcdma.h" +#include "aidl/android/hardware/radio/CfData.h" +#include "aidl/android/hardware/radio/ClipStatus.h" +#include "aidl/android/hardware/radio/Clir.h" +#include "aidl/android/hardware/radio/ClosedSubscriberGroupInfo.h" +#include "aidl/android/hardware/radio/DataCallFailCause.h" +#include "aidl/android/hardware/radio/DataConnActiveStatus.h" +#include "aidl/android/hardware/radio/DataProfileId.h" +#include "aidl/android/hardware/radio/DataProfileInfo.h" +#include "aidl/android/hardware/radio/DataProfileInfoType.h" +#include "aidl/android/hardware/radio/DataRegStateResult.h" +#include "aidl/android/hardware/radio/DataRegStateResultVopsInfo.h" +#include "aidl/android/hardware/radio/DataRequestReason.h" +#include "aidl/android/hardware/radio/DataThrottlingAction.h" +#include "aidl/android/hardware/radio/DeviceStateType.h" +#include "aidl/android/hardware/radio/Dial.h" +#include "aidl/android/hardware/radio/Domain.h" +#include "aidl/android/hardware/radio/EmcIndicator.h" +#include "aidl/android/hardware/radio/EmergencyCallRouting.h" +#include "aidl/android/hardware/radio/EmergencyNumber.h" +#include "aidl/android/hardware/radio/EmergencyNumberSource.h" +#include "aidl/android/hardware/radio/EmergencyServiceCategory.h" +#include "aidl/android/hardware/radio/EmfIndicator.h" +#include "aidl/android/hardware/radio/EpsQos.h" +#include "aidl/android/hardware/radio/EutranBands.h" +#include "aidl/android/hardware/radio/EvdoSignalStrength.h" +#include "aidl/android/hardware/radio/FrequencyRange.h" +#include "aidl/android/hardware/radio/GeranBands.h" +#include "aidl/android/hardware/radio/GsmBroadcastSmsConfigInfo.h" +#include "aidl/android/hardware/radio/GsmSignalStrength.h" +#include "aidl/android/hardware/radio/GsmSmsMessage.h" +#include "aidl/android/hardware/radio/HandoverFailureMode.h" +#include "aidl/android/hardware/radio/HardwareConfig.h" +#include "aidl/android/hardware/radio/HardwareConfigModem.h" +#include "aidl/android/hardware/radio/HardwareConfigSim.h" +#include "aidl/android/hardware/radio/HardwareConfigState.h" +#include "aidl/android/hardware/radio/HardwareConfigType.h" +#include "aidl/android/hardware/radio/IccIo.h" +#include "aidl/android/hardware/radio/IccIoResult.h" +#include "aidl/android/hardware/radio/ImsSmsMessage.h" +#include "aidl/android/hardware/radio/ImsiEncryptionInfo.h" +#include "aidl/android/hardware/radio/IncrementalResultsPeriodicityRange.h" +#include "aidl/android/hardware/radio/IndicationFilter.h" +#include "aidl/android/hardware/radio/KeepaliveRequest.h" +#include "aidl/android/hardware/radio/KeepaliveStatus.h" +#include "aidl/android/hardware/radio/KeepaliveStatusCode.h" +#include "aidl/android/hardware/radio/KeepaliveType.h" +#include "aidl/android/hardware/radio/LastCallFailCause.h" +#include "aidl/android/hardware/radio/LastCallFailCauseInfo.h" +#include "aidl/android/hardware/radio/LceDataInfo.h" +#include "aidl/android/hardware/radio/LceStatus.h" +#include "aidl/android/hardware/radio/LceStatusInfo.h" +#include "aidl/android/hardware/radio/LinkAddress.h" +#include "aidl/android/hardware/radio/LinkCapacityEstimate.h" +#include "aidl/android/hardware/radio/LteSignalStrength.h" +#include "aidl/android/hardware/radio/LteVopsInfo.h" +#include "aidl/android/hardware/radio/MaxSearchTimeRange.h" +#include "aidl/android/hardware/radio/MaybePort.h" +#include "aidl/android/hardware/radio/MvnoType.h" +#include "aidl/android/hardware/radio/NeighboringCell.h" +#include "aidl/android/hardware/radio/NetworkScanRequest.h" +#include "aidl/android/hardware/radio/NetworkScanResult.h" +#include "aidl/android/hardware/radio/NgranBands.h" +#include "aidl/android/hardware/radio/NrDualConnectivityState.h" +#include "aidl/android/hardware/radio/NrIndicators.h" +#include "aidl/android/hardware/radio/NrQos.h" +#include "aidl/android/hardware/radio/NrSignalStrength.h" +#include "aidl/android/hardware/radio/NrVopsInfo.h" +#include "aidl/android/hardware/radio/NvItem.h" +#include "aidl/android/hardware/radio/NvWriteItem.h" +#include "aidl/android/hardware/radio/OperatorInfo.h" +#include "aidl/android/hardware/radio/OperatorStatus.h" +#include "aidl/android/hardware/radio/OptionalCsgInfo.h" +#include "aidl/android/hardware/radio/OptionalDnn.h" +#include "aidl/android/hardware/radio/OptionalOsAppId.h" +#include "aidl/android/hardware/radio/OptionalPdpProtocolType.h" +#include "aidl/android/hardware/radio/OptionalSliceInfo.h" +#include "aidl/android/hardware/radio/OptionalSscMode.h" +#include "aidl/android/hardware/radio/OptionalTrafficDescriptor.h" +#include "aidl/android/hardware/radio/OsAppId.h" +#include "aidl/android/hardware/radio/P2Constant.h" +#include "aidl/android/hardware/radio/PbReceivedStatus.h" +#include "aidl/android/hardware/radio/PcoDataInfo.h" +#include "aidl/android/hardware/radio/PdpProtocolType.h" +#include "aidl/android/hardware/radio/PersoSubstate.h" +#include "aidl/android/hardware/radio/PhoneRestrictedState.h" +#include "aidl/android/hardware/radio/PhonebookCapacity.h" +#include "aidl/android/hardware/radio/PhonebookRecordInfo.h" +#include "aidl/android/hardware/radio/PhysicalChannelConfig.h" +#include "aidl/android/hardware/radio/PhysicalChannelConfigBand.h" +#include "aidl/android/hardware/radio/PinState.h" +#include "aidl/android/hardware/radio/PortRange.h" +#include "aidl/android/hardware/radio/PreferredNetworkType.h" +#include "aidl/android/hardware/radio/PrlIndicator.h" +#include "aidl/android/hardware/radio/PublicKeyType.h" +#include "aidl/android/hardware/radio/Qos.h" +#include "aidl/android/hardware/radio/QosBandwidth.h" +#include "aidl/android/hardware/radio/QosFilter.h" +#include "aidl/android/hardware/radio/QosFilterDirection.h" +#include "aidl/android/hardware/radio/QosFilterIpsecSpi.h" +#include "aidl/android/hardware/radio/QosFilterIpv6FlowLabel.h" +#include "aidl/android/hardware/radio/QosFilterTypeOfService.h" +#include "aidl/android/hardware/radio/QosFlowIdRange.h" +#include "aidl/android/hardware/radio/QosPortRange.h" +#include "aidl/android/hardware/radio/QosProtocol.h" +#include "aidl/android/hardware/radio/QosSession.h" +#include "aidl/android/hardware/radio/RadioAccessFamily.h" +#include "aidl/android/hardware/radio/RadioAccessNetworks.h" +#include "aidl/android/hardware/radio/RadioAccessSpecifier.h" +#include "aidl/android/hardware/radio/RadioAccessSpecifierBands.h" +#include "aidl/android/hardware/radio/RadioBandMode.h" +#include "aidl/android/hardware/radio/RadioCapability.h" +#include "aidl/android/hardware/radio/RadioCapabilityPhase.h" +#include "aidl/android/hardware/radio/RadioCapabilityStatus.h" +#include "aidl/android/hardware/radio/RadioCdmaSmsConst.h" +#include "aidl/android/hardware/radio/RadioConst.h" +#include "aidl/android/hardware/radio/RadioError.h" +#include "aidl/android/hardware/radio/RadioFrequencyInfo.h" +#include "aidl/android/hardware/radio/RadioIndicationType.h" +#include "aidl/android/hardware/radio/RadioResponseInfo.h" +#include "aidl/android/hardware/radio/RadioResponseInfoModem.h" +#include "aidl/android/hardware/radio/RadioResponseType.h" +#include "aidl/android/hardware/radio/RadioState.h" +#include "aidl/android/hardware/radio/RadioTechnology.h" +#include "aidl/android/hardware/radio/RadioTechnologyFamily.h" +#include "aidl/android/hardware/radio/RegState.h" +#include "aidl/android/hardware/radio/RegStateResult.h" +#include "aidl/android/hardware/radio/RegStateResultAccessTechnologySpecificInfo.h" +#include "aidl/android/hardware/radio/RegStateResultAccessTechnologySpecificInfoCdma2000RegistrationInfo.h" +#include "aidl/android/hardware/radio/RegStateResultAccessTechnologySpecificInfoEutranRegistrationInfo.h" +#include "aidl/android/hardware/radio/RegistrationFailCause.h" +#include "aidl/android/hardware/radio/ResetNvType.h" +#include "aidl/android/hardware/radio/RestrictedState.h" +#include "aidl/android/hardware/radio/RouteSelectionDescriptor.h" +#include "aidl/android/hardware/radio/SapApduType.h" +#include "aidl/android/hardware/radio/SapConnectRsp.h" +#include "aidl/android/hardware/radio/SapDisconnectType.h" +#include "aidl/android/hardware/radio/SapResultCode.h" +#include "aidl/android/hardware/radio/SapStatus.h" +#include "aidl/android/hardware/radio/SapTransferProtocol.h" +#include "aidl/android/hardware/radio/ScanIntervalRange.h" +#include "aidl/android/hardware/radio/ScanStatus.h" +#include "aidl/android/hardware/radio/ScanType.h" +#include "aidl/android/hardware/radio/SelectUiccSub.h" +#include "aidl/android/hardware/radio/SendSmsResult.h" +#include "aidl/android/hardware/radio/SetupDataCallResult.h" +#include "aidl/android/hardware/radio/SignalMeasurementType.h" +#include "aidl/android/hardware/radio/SignalStrength.h" +#include "aidl/android/hardware/radio/SignalThresholdInfo.h" +#include "aidl/android/hardware/radio/SimApdu.h" +#include "aidl/android/hardware/radio/SimLockMultiSimPolicy.h" +#include "aidl/android/hardware/radio/SimRefreshResult.h" +#include "aidl/android/hardware/radio/SimRefreshType.h" +#include "aidl/android/hardware/radio/SliceInfo.h" +#include "aidl/android/hardware/radio/SliceServiceType.h" +#include "aidl/android/hardware/radio/SliceStatus.h" +#include "aidl/android/hardware/radio/SlicingConfig.h" +#include "aidl/android/hardware/radio/SmsAcknowledgeFailCause.h" +#include "aidl/android/hardware/radio/SmsWriteArgs.h" +#include "aidl/android/hardware/radio/SmsWriteArgsStatus.h" +#include "aidl/android/hardware/radio/SrvccState.h" +#include "aidl/android/hardware/radio/SsInfoData.h" +#include "aidl/android/hardware/radio/SsRequestType.h" +#include "aidl/android/hardware/radio/SsServiceType.h" +#include "aidl/android/hardware/radio/SsTeleserviceType.h" +#include "aidl/android/hardware/radio/SscMode.h" +#include "aidl/android/hardware/radio/StkCcUnsolSsResult.h" +#include "aidl/android/hardware/radio/SubscriptionType.h" +#include "aidl/android/hardware/radio/SuppServiceClass.h" +#include "aidl/android/hardware/radio/SuppSvcNotification.h" +#include "aidl/android/hardware/radio/TdscdmaSignalStrength.h" +#include "aidl/android/hardware/radio/TimeStampType.h" +#include "aidl/android/hardware/radio/TrafficDescriptor.h" +#include "aidl/android/hardware/radio/TtyMode.h" +#include "aidl/android/hardware/radio/UiccSubActStatus.h" +#include "aidl/android/hardware/radio/UrspRule.h" +#include "aidl/android/hardware/radio/UssdModeType.h" +#include "aidl/android/hardware/radio/UtranBands.h" +#include "aidl/android/hardware/radio/UusDcs.h" +#include "aidl/android/hardware/radio/UusInfo.h" +#include "aidl/android/hardware/radio/UusType.h" +#include "aidl/android/hardware/radio/VoiceRegStateResult.h" +#include "aidl/android/hardware/radio/VopsIndicator.h" +#include "aidl/android/hardware/radio/WcdmaSignalStrength.h" +#include "android/hardware/radio/1.0/types.h" +#include "android/hardware/radio/1.1/types.h" +#include "android/hardware/radio/1.2/types.h" +#include "android/hardware/radio/1.3/types.h" +#include "android/hardware/radio/1.4/types.h" +#include "android/hardware/radio/1.5/types.h" +#include "android/hardware/radio/1.6/types.h" + +namespace android::h2a { + +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::IccIo& in, + aidl::android::hardware::radio::IccIo* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::NeighboringCell& in, + aidl::android::hardware::radio::NeighboringCell* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::UusInfo& in, + aidl::android::hardware::radio::UusInfo* out); +__attribute__((warn_unused_result)) bool translate(const ::android::hardware::radio::V1_0::Dial& in, + aidl::android::hardware::radio::Dial* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::LastCallFailCauseInfo& in, + aidl::android::hardware::radio::LastCallFailCauseInfo* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::GsmSignalStrength& in, + aidl::android::hardware::radio::GsmSignalStrength* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::CdmaSignalStrength& in, + aidl::android::hardware::radio::CdmaSignalStrength* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::EvdoSignalStrength& in, + aidl::android::hardware::radio::EvdoSignalStrength* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::SendSmsResult& in, + aidl::android::hardware::radio::SendSmsResult* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::IccIoResult& in, + aidl::android::hardware::radio::IccIoResult* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::CallForwardInfo& in, + aidl::android::hardware::radio::CallForwardInfo* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::OperatorInfo& in, + aidl::android::hardware::radio::OperatorInfo* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::SmsWriteArgs& in, + aidl::android::hardware::radio::SmsWriteArgs* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::CdmaSmsAddress& in, + aidl::android::hardware::radio::CdmaSmsAddress* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::CdmaSmsSubaddress& in, + aidl::android::hardware::radio::CdmaSmsSubaddress* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::CdmaSmsMessage& in, + aidl::android::hardware::radio::CdmaSmsMessage* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::CdmaSmsAck& in, + aidl::android::hardware::radio::CdmaSmsAck* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::CdmaBroadcastSmsConfigInfo& in, + aidl::android::hardware::radio::CdmaBroadcastSmsConfigInfo* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::CdmaSmsWriteArgs& in, + aidl::android::hardware::radio::CdmaSmsWriteArgs* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::GsmBroadcastSmsConfigInfo& in, + aidl::android::hardware::radio::GsmBroadcastSmsConfigInfo* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::GsmSmsMessage& in, + aidl::android::hardware::radio::GsmSmsMessage* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::ImsSmsMessage& in, + aidl::android::hardware::radio::ImsSmsMessage* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::SimApdu& in, + aidl::android::hardware::radio::SimApdu* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::NvWriteItem& in, + aidl::android::hardware::radio::NvWriteItem* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::SelectUiccSub& in, + aidl::android::hardware::radio::SelectUiccSub* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::HardwareConfigModem& in, + aidl::android::hardware::radio::HardwareConfigModem* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::HardwareConfigSim& in, + aidl::android::hardware::radio::HardwareConfigSim* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::HardwareConfig& in, + aidl::android::hardware::radio::HardwareConfig* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::LceStatusInfo& in, + aidl::android::hardware::radio::LceStatusInfo* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::LceDataInfo& in, + aidl::android::hardware::radio::LceDataInfo* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::ActivityStatsInfo& in, + aidl::android::hardware::radio::ActivityStatsInfo* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::Carrier& in, + aidl::android::hardware::radio::Carrier* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::CarrierRestrictions& in, + aidl::android::hardware::radio::CarrierRestrictions* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::SuppSvcNotification& in, + aidl::android::hardware::radio::SuppSvcNotification* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::SimRefreshResult& in, + aidl::android::hardware::radio::SimRefreshResult* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::CdmaSignalInfoRecord& in, + aidl::android::hardware::radio::CdmaSignalInfoRecord* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::CdmaCallWaiting& in, + aidl::android::hardware::radio::CdmaCallWaiting* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::CdmaDisplayInfoRecord& in, + aidl::android::hardware::radio::CdmaDisplayInfoRecord* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::CdmaNumberInfoRecord& in, + aidl::android::hardware::radio::CdmaNumberInfoRecord* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::CdmaRedirectingNumberInfoRecord& in, + aidl::android::hardware::radio::CdmaRedirectingNumberInfoRecord* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::CdmaLineControlInfoRecord& in, + aidl::android::hardware::radio::CdmaLineControlInfoRecord* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::CdmaT53ClirInfoRecord& in, + aidl::android::hardware::radio::CdmaT53ClirInfoRecord* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::CdmaT53AudioControlInfoRecord& in, + aidl::android::hardware::radio::CdmaT53AudioControlInfoRecord* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::CdmaInformationRecord& in, + aidl::android::hardware::radio::CdmaInformationRecord* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::CdmaInformationRecords& in, + aidl::android::hardware::radio::CdmaInformationRecords* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::CfData& in, + aidl::android::hardware::radio::CfData* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::SsInfoData& in, + aidl::android::hardware::radio::SsInfoData* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::StkCcUnsolSsResult& in, + aidl::android::hardware::radio::StkCcUnsolSsResult* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_0::PcoDataInfo& in, + aidl::android::hardware::radio::PcoDataInfo* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_1::KeepaliveRequest& in, + aidl::android::hardware::radio::KeepaliveRequest* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_1::KeepaliveStatus& in, + aidl::android::hardware::radio::KeepaliveStatus* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_2::CellIdentityOperatorNames& in, + aidl::android::hardware::radio::CellIdentityOperatorNames* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_2::CellIdentityCdma& in, + aidl::android::hardware::radio::CellIdentityCdma* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_2::CellInfoCdma& in, + aidl::android::hardware::radio::CellInfoCdma* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_2::WcdmaSignalStrength& in, + aidl::android::hardware::radio::WcdmaSignalStrength* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_2::TdscdmaSignalStrength& in, + aidl::android::hardware::radio::TdscdmaSignalStrength* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_2::VoiceRegStateResult& in, + aidl::android::hardware::radio::VoiceRegStateResult* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_3::RadioResponseInfoModem& in, + aidl::android::hardware::radio::RadioResponseInfoModem* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_4::EmergencyNumber& in, + aidl::android::hardware::radio::EmergencyNumber* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_4::RadioFrequencyInfo& in, + aidl::android::hardware::radio::RadioFrequencyInfo* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_4::LteVopsInfo& in, + aidl::android::hardware::radio::LteVopsInfo* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_4::NrIndicators& in, + aidl::android::hardware::radio::NrIndicators* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_4::DataRegStateResult& in, + aidl::android::hardware::radio::DataRegStateResult* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_4::DataRegStateResult::VopsInfo& in, + aidl::android::hardware::radio::DataRegStateResultVopsInfo* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_4::CellConfigLte& in, + aidl::android::hardware::radio::CellConfigLte* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_4::CellInfo::Info& in, + aidl::android::hardware::radio::CellInfoInfo* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_4::RadioCapability& in, + aidl::android::hardware::radio::RadioCapability* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_4::CarrierRestrictionsWithPriority& in, + aidl::android::hardware::radio::CarrierRestrictionsWithPriority* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_5::RadioAccessSpecifier& in, + aidl::android::hardware::radio::RadioAccessSpecifier* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands& in, + aidl::android::hardware::radio::RadioAccessSpecifierBands* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_5::SignalThresholdInfo& in, + aidl::android::hardware::radio::SignalThresholdInfo* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_5::NetworkScanRequest& in, + aidl::android::hardware::radio::NetworkScanRequest* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_5::DataProfileInfo& in, + aidl::android::hardware::radio::DataProfileInfo* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_5::LinkAddress& in, + aidl::android::hardware::radio::LinkAddress* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_5::ClosedSubscriberGroupInfo& in, + aidl::android::hardware::radio::ClosedSubscriberGroupInfo* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_5::OptionalCsgInfo& in, + aidl::android::hardware::radio::OptionalCsgInfo* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_5::CellIdentityGsm& in, + aidl::android::hardware::radio::CellIdentityGsm* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_5::CellIdentityWcdma& in, + aidl::android::hardware::radio::CellIdentityWcdma* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_5::CellIdentityTdscdma& in, + aidl::android::hardware::radio::CellIdentityTdscdma* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_5::CellIdentityLte& in, + aidl::android::hardware::radio::CellIdentityLte* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_5::CellIdentityNr& in, + aidl::android::hardware::radio::CellIdentityNr* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_5::CellInfoGsm& in, + aidl::android::hardware::radio::CellInfoGsm* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_5::CellInfoWcdma& in, + aidl::android::hardware::radio::CellInfoWcdma* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_5::CellInfoTdscdma& in, + aidl::android::hardware::radio::CellInfoTdscdma* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_5::CellIdentity& in, + aidl::android::hardware::radio::CellIdentity* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_5::BarringInfo& in, + aidl::android::hardware::radio::BarringInfo* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_5::BarringInfo::BarringTypeSpecificInfo::Conditional& + in, + aidl::android::hardware::radio::BarringInfoBarringTypeSpecificInfoConditional* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_5::BarringInfo::BarringTypeSpecificInfo& in, + aidl::android::hardware::radio::BarringInfoBarringTypeSpecificInfo* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_5::RegStateResult::AccessTechnologySpecificInfo:: + Cdma2000RegistrationInfo& in, + aidl::android::hardware::radio:: + RegStateResultAccessTechnologySpecificInfoCdma2000RegistrationInfo* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_5::RegStateResult::AccessTechnologySpecificInfo:: + EutranRegistrationInfo& in, + aidl::android::hardware::radio:: + RegStateResultAccessTechnologySpecificInfoEutranRegistrationInfo* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_5::AppStatus& in, + aidl::android::hardware::radio::AppStatus* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_5::CardStatus& in, + aidl::android::hardware::radio::CardStatus* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::QosBandwidth& in, + aidl::android::hardware::radio::QosBandwidth* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::EpsQos& in, + aidl::android::hardware::radio::EpsQos* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::NrQos& in, + aidl::android::hardware::radio::NrQos* out); +__attribute__((warn_unused_result)) bool translate(const ::android::hardware::radio::V1_6::Qos& in, + aidl::android::hardware::radio::Qos* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::RadioResponseInfo& in, + aidl::android::hardware::radio::RadioResponseInfo* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::PortRange& in, + aidl::android::hardware::radio::PortRange* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::MaybePort& in, + aidl::android::hardware::radio::MaybePort* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::QosFilter& in, + aidl::android::hardware::radio::QosFilter* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::QosFilter::TypeOfService& in, + aidl::android::hardware::radio::QosFilterTypeOfService* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::QosFilter::Ipv6FlowLabel& in, + aidl::android::hardware::radio::QosFilterIpv6FlowLabel* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::QosFilter::IpsecSpi& in, + aidl::android::hardware::radio::QosFilterIpsecSpi* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::QosSession& in, + aidl::android::hardware::radio::QosSession* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::SetupDataCallResult& in, + aidl::android::hardware::radio::SetupDataCallResult* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::LinkCapacityEstimate& in, + aidl::android::hardware::radio::LinkCapacityEstimate* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::NrVopsInfo& in, + aidl::android::hardware::radio::NrVopsInfo* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::LteSignalStrength& in, + aidl::android::hardware::radio::LteSignalStrength* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::NrSignalStrength& in, + aidl::android::hardware::radio::NrSignalStrength* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::SignalStrength& in, + aidl::android::hardware::radio::SignalStrength* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::CellInfoLte& in, + aidl::android::hardware::radio::CellInfoLte* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::CellInfoNr& in, + aidl::android::hardware::radio::CellInfoNr* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::CellInfo& in, + aidl::android::hardware::radio::CellInfo* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::CellInfo::CellInfoRatSpecificInfo& in, + aidl::android::hardware::radio::CellInfoCellInfoRatSpecificInfo* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::NetworkScanResult& in, + aidl::android::hardware::radio::NetworkScanResult* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::RegStateResult& in, + aidl::android::hardware::radio::RegStateResult* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::RegStateResult::AccessTechnologySpecificInfo& in, + aidl::android::hardware::radio::RegStateResultAccessTechnologySpecificInfo* out); +__attribute__((warn_unused_result)) bool translate(const ::android::hardware::radio::V1_6::Call& in, + aidl::android::hardware::radio::Call* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::PhysicalChannelConfig& in, + aidl::android::hardware::radio::PhysicalChannelConfig* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::PhysicalChannelConfig::Band& in, + aidl::android::hardware::radio::PhysicalChannelConfigBand* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::OptionalSliceInfo& in, + aidl::android::hardware::radio::OptionalSliceInfo* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::SliceInfo& in, + aidl::android::hardware::radio::SliceInfo* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::OptionalDnn& in, + aidl::android::hardware::radio::OptionalDnn* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::OptionalOsAppId& in, + aidl::android::hardware::radio::OptionalOsAppId* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::OptionalTrafficDescriptor& in, + aidl::android::hardware::radio::OptionalTrafficDescriptor* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::TrafficDescriptor& in, + aidl::android::hardware::radio::TrafficDescriptor* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::OsAppId& in, + aidl::android::hardware::radio::OsAppId* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::SlicingConfig& in, + aidl::android::hardware::radio::SlicingConfig* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::UrspRule& in, + aidl::android::hardware::radio::UrspRule* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::RouteSelectionDescriptor& in, + aidl::android::hardware::radio::RouteSelectionDescriptor* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::OptionalPdpProtocolType& in, + aidl::android::hardware::radio::OptionalPdpProtocolType* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::OptionalSscMode& in, + aidl::android::hardware::radio::OptionalSscMode* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::ImsiEncryptionInfo& in, + aidl::android::hardware::radio::ImsiEncryptionInfo* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::PhonebookRecordInfo& in, + aidl::android::hardware::radio::PhonebookRecordInfo* out); +__attribute__((warn_unused_result)) bool translate( + const ::android::hardware::radio::V1_6::PhonebookCapacity& in, + aidl::android::hardware::radio::PhonebookCapacity* out); + +} // namespace android::h2a -- GitLab From 92152ac1a1cac70ef3b9c9f1ff89de28ffd9a9d6 Mon Sep 17 00:00:00 2001 From: Serik Beketayev Date: Tue, 7 Sep 2021 16:00:32 -0700 Subject: [PATCH 788/790] [IRadioConfig] Generating AIDL definitions Generated IRadioConfig.aidl and dependencies using tool hidl2aidl. Bug: 198331805 Test: m android.hardware.radio.config Change-Id: I231f9b2eff50e7a0558dd79e85613b626c7cfb52 Merged-In: I231f9b2eff50e7a0558dd79e85613b626c7cfb52 --- .../compatibility_matrix.current.xml | 8 + radio/config/aidl/Android.bp | 55 +++++++ .../hardware/radio/config/IRadioConfig.aidl | 53 +++++++ .../radio/config/IRadioConfigIndication.aidl | 38 +++++ .../radio/config/IRadioConfigResponse.aidl | 44 ++++++ .../radio/config/PhoneCapability.aidl | 41 +++++ .../hardware/radio/config/SimSlotStatus.aidl | 44 ++++++ .../hardware/radio/config/IRadioConfig.aidl | 149 ++++++++++++++++++ .../radio/config/IRadioConfigIndication.aidl | 39 +++++ .../radio/config/IRadioConfigResponse.aidl | 124 +++++++++++++++ .../radio/config/PhoneCapability.aidl | 48 ++++++ .../hardware/radio/config/SimSlotStatus.aidl | 56 +++++++ 12 files changed, 699 insertions(+) create mode 100644 radio/config/aidl/Android.bp create mode 100644 radio/config/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/IRadioConfig.aidl create mode 100644 radio/config/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/IRadioConfigIndication.aidl create mode 100644 radio/config/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/IRadioConfigResponse.aidl create mode 100644 radio/config/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/PhoneCapability.aidl create mode 100644 radio/config/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimSlotStatus.aidl create mode 100644 radio/config/aidl/android/hardware/radio/config/IRadioConfig.aidl create mode 100644 radio/config/aidl/android/hardware/radio/config/IRadioConfigIndication.aidl create mode 100644 radio/config/aidl/android/hardware/radio/config/IRadioConfigResponse.aidl create mode 100644 radio/config/aidl/android/hardware/radio/config/PhoneCapability.aidl create mode 100644 radio/config/aidl/android/hardware/radio/config/SimSlotStatus.aidl diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index 4600ff4e77..920513b465 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -471,6 +471,14 @@ default + + android.hardware.radio.config + 1 + + IRadioConfig + default + + android.hardware.radio.config 1.3 diff --git a/radio/config/aidl/Android.bp b/radio/config/aidl/Android.bp new file mode 100644 index 0000000000..801747a0a1 --- /dev/null +++ b/radio/config/aidl/Android.bp @@ -0,0 +1,55 @@ +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.radio.config", + vendor_available: true, + srcs: ["android/hardware/radio/config/*.aidl"], + stability: "vintf", + imports: ["android.hardware.radio"], + backend: { + cpp: { + enabled: false, + }, + java: { + sdk_version: "module_current", + }, + ndk: { + vndk: { + enabled: true, + }, + }, + }, +} + +cc_library { + name: "android.hardware.radio.config-translate-ndk", + vendor_available: true, + shared_libs: [ + "libbinder_ndk", + "libhidlbase", + "android.hardware.radio.config-V1-ndk_platform", + "android.hardware.radio.config@1.0", + "android.hardware.radio.config@1.1", + "android.hardware.radio.config@1.2", + "android.hardware.radio.config@1.3", + ], +} + +java_library { + name: "android.hardware.radio.config-translate-java", + libs: [ + "android.hardware.radio.config-V1-java", + "android.hardware.radio.config-V1.0-java", + "android.hardware.radio.config-V1.1-java", + "android.hardware.radio.config-V1.2-java", + "android.hardware.radio.config-V1.3-java", + ], + sdk_version: "module_current", +} diff --git a/radio/config/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/IRadioConfig.aidl b/radio/config/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/IRadioConfig.aidl new file mode 100644 index 0000000000..85106b82d0 --- /dev/null +++ b/radio/config/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/IRadioConfig.aidl @@ -0,0 +1,53 @@ +/* + * 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 interface is used by telephony and telecom to talk to cellular radio for the purpose of + * radio configuration, and it is not associated with any specific modem or slot. + * All the functions have minimum one parameter: + * serial: which corresponds to serial no. of request. Serial numbers must only be memorized for the + * duration of a method call. If clients provide colliding serials (including passing the same + * serial to different methods), multiple responses (one for each method call) must still be served. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.radio.config; +@VintfStability +interface IRadioConfig { + oneway void getHalDeviceCapabilities(in int serial); + oneway void getNumOfLiveModems(in int serial); + oneway void getPhoneCapability(in int serial); + oneway void getSimSlotsStatus(in int serial); + oneway void setNumOfLiveModems(in int serial, in byte numOfLiveModems); + oneway void setPreferredDataModem(in int serial, in byte modemId); + oneway void setResponseFunctions(in android.hardware.radio.config.IRadioConfigResponse radioConfigResponse, in android.hardware.radio.config.IRadioConfigIndication radioConfigIndication); + oneway void setSimSlotsMapping(in int serial, in int[] slotMap); +} diff --git a/radio/config/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/IRadioConfigIndication.aidl b/radio/config/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/IRadioConfigIndication.aidl new file mode 100644 index 0000000000..994e337c04 --- /dev/null +++ b/radio/config/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/IRadioConfigIndication.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 -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.radio.config; +@VintfStability +interface IRadioConfigIndication { + oneway void simSlotsStatusChanged(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.config.SimSlotStatus[] slotStatus); +} diff --git a/radio/config/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/IRadioConfigResponse.aidl b/radio/config/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/IRadioConfigResponse.aidl new file mode 100644 index 0000000000..038b0aeb58 --- /dev/null +++ b/radio/config/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/IRadioConfigResponse.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 -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.radio.config; +@VintfStability +interface IRadioConfigResponse { + oneway void getHalDeviceCapabilitiesResponse(in android.hardware.radio.RadioResponseInfo info, in boolean modemReducedFeatureSet1); + oneway void getNumOfLiveModemsResponse(in android.hardware.radio.RadioResponseInfo info, in byte numOfLiveModems); + oneway void getPhoneCapabilityResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.config.PhoneCapability phoneCapability); + oneway void getSimSlotsStatusResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.config.SimSlotStatus[] slotStatus); + oneway void setNumOfLiveModemsResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setPreferredDataModemResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setSimSlotsMappingResponse(in android.hardware.radio.RadioResponseInfo info); +} diff --git a/radio/config/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/PhoneCapability.aidl b/radio/config/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/PhoneCapability.aidl new file mode 100644 index 0000000000..c60200ce13 --- /dev/null +++ b/radio/config/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/PhoneCapability.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 -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.radio.config; +@VintfStability +parcelable PhoneCapability { + byte maxActiveData; + byte maxActiveInternetData; + boolean isInternetLingeringSupported; + byte[] logicalModemIds; +} diff --git a/radio/config/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimSlotStatus.aidl b/radio/config/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimSlotStatus.aidl new file mode 100644 index 0000000000..3a716cf514 --- /dev/null +++ b/radio/config/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimSlotStatus.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 -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.radio.config; +@VintfStability +parcelable SimSlotStatus { + boolean cardActive; + int cardState; + int slotState; + String atr; + int logicalSlotId; + String iccid; + String eid; +} diff --git a/radio/config/aidl/android/hardware/radio/config/IRadioConfig.aidl b/radio/config/aidl/android/hardware/radio/config/IRadioConfig.aidl new file mode 100644 index 0000000000..bfff16aa43 --- /dev/null +++ b/radio/config/aidl/android/hardware/radio/config/IRadioConfig.aidl @@ -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. + * + * + * This interface is used by telephony and telecom to talk to cellular radio for the purpose of + * radio configuration, and it is not associated with any specific modem or slot. + * All the functions have minimum one parameter: + * serial: which corresponds to serial no. of request. Serial numbers must only be memorized for the + * duration of a method call. If clients provide colliding serials (including passing the same + * serial to different methods), multiple responses (one for each method call) must still be served. + */ + +package android.hardware.radio.config; + +import android.hardware.radio.config.IRadioConfigIndication; +import android.hardware.radio.config.IRadioConfigResponse; + +@VintfStability +oneway interface IRadioConfig { + /** + * Gets the available Radio Hal capabilities on the current device. + * + * This is called once per device boot up. + * + * @param serial Serial number of request + * + * Response callback is + * IRadioConfigResponse.getHalDeviceCapabilitiesResponse() + */ + void getHalDeviceCapabilities(in int serial); + + /** + * Get the number of live modems (i.e modems that are + * enabled and actively working as part of a working telephony stack) + * + * Note: in order to get the overall number of modems available on the phone, + * refer to getPhoneCapability API + * + * @param serial Serial number of request. + * + * Response callback is IRadioConfigResponse.getNumOfLiveModemsResponse() which + * will return . + */ + void getNumOfLiveModems(in int serial); + + /** + * Request current phone capability. + * + * @param serial Serial number of request. + * + * Response callback is IRadioResponse.getPhoneCapabilityResponse() which + * will return . + */ + void getPhoneCapability(in int serial); + + /** + * Get SIM Slot status. + * + * Request provides the slot status of all active and inactive SIM slots and whether card is + * present in the slots or not. + * + * @param serial Serial number of request. + * + * Response callback is IRadioConfigResponse.getSimSlotsStatusResponse() + */ + void getSimSlotsStatus(in int serial); + + /** + * Set modems configurations by specifying the number of live modems (i.e modems that are + * enabled and actively working as part of a working telephony stack). + * + * Example: this interface can be used to switch to single/multi sim mode by specifying + * the number of live modems as 1, 2, etc + * + * Note: by setting the number of live modems in this API, that number of modems will + * subsequently get enabled/disabled + * + * @param serial serial number of request. + * @param modemsConfig byte object including the number of live modems + * + * Response callback is IRadioResponse.setNumOfLiveModemsResponse() + */ + void setNumOfLiveModems(in int serial, in byte numOfLiveModems); + + /** + * Set preferred data modem Id. + * In a multi-SIM device, notify modem layer which logical modem will be used primarily + * for data. It helps modem with resource optimization and decisions of what data connections + * should be satisfied. + * + * @param serial Serial number of request. + * @param modem Id the logical modem ID, which should match one of modem IDs returned + * from getPhoneCapability(). + * + * Response callback is IRadioConfigResponse.setPreferredDataModemResponse() + */ + void setPreferredDataModem(in int serial, in byte modemId); + + /** + * Set response functions for radio config requests & radio config indications. + * + * @param radioConfigResponse Object containing radio config response functions + * @param radioConfigIndication Object containing radio config indications + */ + void setResponseFunctions(in IRadioConfigResponse radioConfigResponse, + in IRadioConfigIndication radioConfigIndication); + + /** + * Set SIM Slot mapping. + * + * Maps the logical slots to the physical slots. Logical slot is the slot that is seen by modem. + * Physical slot is the actual physical slot. Request maps the physical slot to logical slot. + * Logical slots that are already mapped to the requested physical slot are not impacted. + * + * Example no. of logical slots 1 and physical slots 2: + * The only logical slot (index 0) can be mapped to first physical slot (value 0) or second + * physical slot(value 1), while the other physical slot remains unmapped and inactive. + * slotMap[0] = 1 or slotMap[0] = 0 + * + * Example no. of logical slots 2 and physical slots 2: + * First logical slot (index 0) can be mapped to physical slot 1 or 2 and other logical slot + * can be mapped to other physical slot. Each logical slot must be mapped to a physical slot. + * slotMap[0] = 0 and slotMap[1] = 1 or slotMap[0] = 1 and slotMap[1] = 0 + * + * @param serial Serial number of request + * @param slotMap Logical to physical slot mapping, size == no. of radio instances. Index is + * mapping to logical slot and value to physical slot, need to provide all the slots + * mapping when sending request in case of multi slot device. + * EX: uint32_t slotMap[logical slot] = physical slot + * index 0 is the first logical_slot number of logical slots is equal to number of Radio + * instances and number of physical slots is equal to size of slotStatus in + * getSimSlotsStatusResponse + * + * Response callback is IRadioConfigResponse.setSimSlotsMappingResponse() + */ + void setSimSlotsMapping(in int serial, in int[] slotMap); +} diff --git a/radio/config/aidl/android/hardware/radio/config/IRadioConfigIndication.aidl b/radio/config/aidl/android/hardware/radio/config/IRadioConfigIndication.aidl new file mode 100644 index 0000000000..abf55f1f80 --- /dev/null +++ b/radio/config/aidl/android/hardware/radio/config/IRadioConfigIndication.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.radio.config; + +import android.hardware.radio.config.SimSlotStatus; + +/** + * Interface declaring unsolicited radio config indications. + */ +@VintfStability +oneway interface IRadioConfigIndication { + /** + * Indicates SIM slot status change. + * + * This indication must be sent by the modem whenever there is any slot status change, even the + * slot is inactive. For example, this indication must be triggered if a SIM card is inserted + * into an inactive slot. + * + * @param type Type of radio indication + * @param slotStatus new slot status info with size equals to the number of physical slots on + * the device + */ + void simSlotsStatusChanged( + in android.hardware.radio.RadioIndicationType type, in SimSlotStatus[] slotStatus); +} diff --git a/radio/config/aidl/android/hardware/radio/config/IRadioConfigResponse.aidl b/radio/config/aidl/android/hardware/radio/config/IRadioConfigResponse.aidl new file mode 100644 index 0000000000..929f02df0f --- /dev/null +++ b/radio/config/aidl/android/hardware/radio/config/IRadioConfigResponse.aidl @@ -0,0 +1,124 @@ +/* + * 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.radio.config; + +import android.hardware.radio.config.PhoneCapability; +import android.hardware.radio.config.SimSlotStatus; + +/** + * Interface declaring response functions to solicited radio config requests. + */ +@VintfStability +oneway interface IRadioConfigResponse { + /** + * @param info Response info struct containing response type, serial no. and error + * @param modemReducedFeatureSet1 True indicates that the modem does NOT support the following + * features. + * - Providing either LinkCapacityEstimate:secondaryDownlinkCapacityKbps + * or LinkCapacityEstimate:secondaryUplinkCapacityKbps when given from + * RadioIndication:currentLinkCapacityEstimate + * - Calling IRadio.setNrDualConnectivityState or querying + * IRadio.isNrDualConnectivityEnabled + * - Requesting IRadio.setDataThrottling() + * - Providing SlicingConfig through getSlicingConfig() + * - Providing PhysicalChannelConfig through + * IRadioIndication.currentPhysicalChannelConfigs_1_6() + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + */ + void getHalDeviceCapabilitiesResponse( + in android.hardware.radio.RadioResponseInfo info, in boolean modemReducedFeatureSet1); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param numOfLiveModems indicate the number of live modems i.e. modems that + * are enabled and actively working as part of a working connectivity stack + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:REQUEST_NOT_SUPPORTED + */ + void getNumOfLiveModemsResponse( + in android.hardware.radio.RadioResponseInfo info, in byte numOfLiveModems); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param phoneCapability it defines modem's capability for example + * how many logical modems it has, how many data connections it supports. + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + */ + void getPhoneCapabilityResponse( + in android.hardware.radio.RadioResponseInfo info, in PhoneCapability phoneCapability); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param slotStatus Sim slot struct containing all the physical SIM slots info with size + * equal to the number of physical slots on the device + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:MODEM_ERR + */ + void getSimSlotsStatusResponse( + in android.hardware.radio.RadioResponseInfo info, in SimSlotStatus[] slotStatus); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_ARGUMENTS + */ + void setNumOfLiveModemsResponse(in android.hardware.radio.RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:INVALID_ARGUMENTS + */ + void setPreferredDataModemResponse(in android.hardware.radio.RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:MODEM_ERR + * RadioError:INVALID_ARGUMENTS + */ + void setSimSlotsMappingResponse(in android.hardware.radio.RadioResponseInfo info); +} diff --git a/radio/config/aidl/android/hardware/radio/config/PhoneCapability.aidl b/radio/config/aidl/android/hardware/radio/config/PhoneCapability.aidl new file mode 100644 index 0000000000..bc55e3924b --- /dev/null +++ b/radio/config/aidl/android/hardware/radio/config/PhoneCapability.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.radio.config; + +/** + * Phone capability which describes the data connection capability of modem. + * It's used to evaluate possible phone config change, for example from single + * SIM device to multi-SIM device. + */ +@VintfStability +parcelable PhoneCapability { + /** + * maxActiveData defines how many logical modems can have + * PS attached simultaneously. For example, for L+L modem it + * should be 2. + */ + byte maxActiveData; + /** + * maxActiveData defines how many logical modems can have + * internet PDN connections simultaneously. For example, for L+L + * DSDS modem it’s 1, and for DSDA modem it’s 2. + */ + byte maxActiveInternetData; + /** + * Whether modem supports both internet PDN up so + * that we can do ping test before tearing down the + * other one. + */ + boolean isInternetLingeringSupported; + /** + * List of logical modem IDs. + */ + byte[] logicalModemIds; +} diff --git a/radio/config/aidl/android/hardware/radio/config/SimSlotStatus.aidl b/radio/config/aidl/android/hardware/radio/config/SimSlotStatus.aidl new file mode 100644 index 0000000000..f5ea8f99ef --- /dev/null +++ b/radio/config/aidl/android/hardware/radio/config/SimSlotStatus.aidl @@ -0,0 +1,56 @@ +/* + * 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.radio.config; + +@VintfStability +parcelable SimSlotStatus { + boolean cardActive; + /** + * Card state in the physical slot. Values are CardStatus.[STATE_ABSENT, STATE_PRESENT, + * STATE_ERROR, STATE_RESTRICTED]. + */ + int cardState; + /** + * Slot state Active/Inactive + */ + int slotState; + /** + * An Answer To Reset (ATR) is a message output by a Smart Card conforming to ISO/IEC 7816 + * standards, following electrical reset of the card's chip. The ATR conveys information about + * the communication parameters proposed by the card, and the card's nature and state. + * + * This data is applicable only when cardState is CardStatus.STATE_PRESENT. + */ + String atr; + int logicalSlotId; + /** + * Integrated Circuit Card IDentifier (ICCID) is Unique Identifier of the SIM CARD. File is + * located in the SIM card at EFiccid (0x2FE2) as per ETSI 102.221. The ICCID is defined by + * the ITU-T recommendation E.118 ISO/IEC 7816. + * + * This data is applicable only when cardState is CardStatus.STATE_PRESENT. + */ + String iccid; + /** + * The EID is the eUICC identifier. The EID shall be stored within the ECASD and can be + * retrieved by the Device at any time using the standard GlobalPlatform GET DATA command. + * + * This data is mandatory and applicable only when cardState is CardStatus.STATE_PRESENT and SIM + * card supports eUICC. + */ + String eid; +} -- GitLab From 22754c5fa75bdd210d7e597bad78176d6b9390a0 Mon Sep 17 00:00:00 2001 From: Lais Andrade Date: Tue, 14 Sep 2021 12:21:59 +0000 Subject: [PATCH 789/790] Update ActivePwle description for amplitude values Update description to clarify that the value 1 should map to the maximum output acceleration supported by the device at any frequency, not exclusively to the one at resonant frequency. Also add information linking the ActivePwle input parameters of composePwle to the output values returned by getBandwidthAmplitudeMap, and update the bandwidth description as well. Change-Id: Id6e02c5d323aec57db7e7127e219a9705d0289a3 Fix: 199753151 Test: VtsHalVibratorTargetTest --- .../android/hardware/vibrator/ActivePwle.aidl | 28 ++++++- .../android/hardware/vibrator/IVibrator.aidl | 4 + .../aidl/vts/VtsHalVibratorTargetTest.cpp | 78 ++++++++----------- 3 files changed, 62 insertions(+), 48 deletions(-) diff --git a/vibrator/aidl/android/hardware/vibrator/ActivePwle.aidl b/vibrator/aidl/android/hardware/vibrator/ActivePwle.aidl index fd5f8d1973..6757476e01 100644 --- a/vibrator/aidl/android/hardware/vibrator/ActivePwle.aidl +++ b/vibrator/aidl/android/hardware/vibrator/ActivePwle.aidl @@ -22,26 +22,50 @@ parcelable ActivePwle { * Amplitude ranging from 0.0 (inclusive) to 1.0 (inclusive) * in units of output acceleration amplitude, not voltage amplitude. * + * Values should fall within the range of 0.0 (inclusive) to the maximum defined + * by the corresponding entries in IVibrator#getBandwidthAmplitudeMap (inclusive). + * If startFrequency falls between two entries, the value will not exceed the + * largest amplitude of the two bounding frequencies. + * * 0.0 represents no output acceleration amplitude - * 1.0 represents maximum output acceleration amplitude at resonant frequency + * 1.0 represents maximum output acceleration amplitude + * across all supported frequencies */ float startAmplitude; + /** * Absolute frequency point in the units of hertz + * + * Values are within the continuous inclusive frequency range defined by + * IVibrator#getBandwidthAmplitudeMap, and not limited by the + * IVibrator#getFrequencyResolution. */ float startFrequency; + /** * Amplitude ranging from 0.0 (inclusive) to 1.0 (inclusive) * in units of output acceleration amplitude, not voltage amplitude. * + * Values should fall within the range of 0.0 (inclusive) to the maximum defined + * by the corresponding entries in IVibrator#getBandwidthAmplitudeMap (inclusive). + * If endFrequency falls between two entries, the value will not exceed the + * largest amplitude of the two bounding frequencies. + * * 0.0 represents no output acceleration amplitude - * 1.0 represents maximum output acceleration amplitude at resonant frequency + * 1.0 represents maximum output acceleration amplitude + * across all supported frequencies */ float endAmplitude; + /** * Absolute frequency point in the units of hertz + * + * Values are within the continuous inclusive frequency range defined by + * IVibrator#getBandwidthAmplitudeMap, and not limited by the + * IVibrator#getFrequencyResolution. */ float endFrequency; + /** * Total duration from start point to end point in the units of milliseconds */ diff --git a/vibrator/aidl/android/hardware/vibrator/IVibrator.aidl b/vibrator/aidl/android/hardware/vibrator/IVibrator.aidl index 592d151d32..b4e7e44fe0 100644 --- a/vibrator/aidl/android/hardware/vibrator/IVibrator.aidl +++ b/vibrator/aidl/android/hardware/vibrator/IVibrator.aidl @@ -305,6 +305,10 @@ interface IVibrator { * of getFrequencyResolution(). The value returned by getResonantFrequency() must be * represented in the returned list. * + * The amplitude values represent the maximum output acceleration amplitude supported for each + * given frequency. Equal amplitude values for different frequencies represent equal output + * accelerations. + * * @return The maximum output acceleration amplitude for each supported frequency, * starting at getMinimumFrequency() */ diff --git a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp index 553d7f0a4a..53f8c0ef24 100644 --- a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp +++ b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp @@ -717,27 +717,33 @@ TEST_P(VibratorAidl, GetSupportedBraking) { TEST_P(VibratorAidl, ComposeValidPwle) { if (capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS) { - ActivePwle active = composeValidActivePwle(vibrator, capabilities); + ActivePwle firstActive = composeValidActivePwle(vibrator, capabilities); std::vector supported; ASSERT_TRUE(vibrator->getSupportedBraking(&supported).isOk()); bool isClabSupported = std::find(supported.begin(), supported.end(), Braking::CLAB) != supported.end(); - BrakingPwle braking; - braking.braking = isClabSupported ? Braking::CLAB : Braking::NONE; - braking.duration = 100; + BrakingPwle firstBraking; + firstBraking.braking = isClabSupported ? Braking::CLAB : Braking::NONE; + firstBraking.duration = 100; + + ActivePwle secondActive = composeValidActivePwle(vibrator, capabilities); + if (capabilities & IVibrator::CAP_FREQUENCY_CONTROL) { + float minFrequencyHz = getFrequencyMinimumHz(vibrator, capabilities); + float maxFrequencyHz = getFrequencyMaximumHz(vibrator, capabilities); + float freqResolutionHz = getFrequencyResolutionHz(vibrator, capabilities); + secondActive.startFrequency = minFrequencyHz + (freqResolutionHz / 2.0f); + secondActive.endFrequency = maxFrequencyHz - (freqResolutionHz / 3.0f); + } + BrakingPwle secondBraking; + secondBraking.braking = Braking::NONE; + secondBraking.duration = 10; - std::vector pwleQueue; - PrimitivePwle pwle; - pwle = active; - pwleQueue.emplace_back(std::move(pwle)); - pwle = braking; - pwleQueue.emplace_back(std::move(pwle)); - pwle = active; - pwleQueue.emplace_back(std::move(pwle)); + auto pwleQueue = + std::vector{firstActive, firstBraking, secondActive, secondBraking}; EXPECT_EQ(Status::EX_NONE, vibrator->composePwle(pwleQueue, nullptr).exceptionCode()); - vibrator->off(); + EXPECT_TRUE(vibrator->off().isOk()); } } @@ -765,14 +771,7 @@ TEST_P(VibratorAidl, ComposeValidPwleWithCallback) { braking.braking = isClabSupported ? Braking::CLAB : Braking::NONE; braking.duration = 100; - std::vector pwleQueue; - PrimitivePwle pwle; - pwle = active; - pwleQueue.emplace_back(std::move(pwle)); - pwle = braking; - pwleQueue.emplace_back(std::move(pwle)); - pwle = active; - pwleQueue.emplace_back(std::move(pwle)); + auto pwleQueue = std::vector{active, braking, active}; EXPECT_TRUE(vibrator->composePwle(pwleQueue, callback).isOk()); EXPECT_EQ(completionFuture.wait_for(timeout), std::future_status::ready); @@ -785,7 +784,7 @@ TEST_P(VibratorAidl, ComposePwleSegmentBoundary) { // test empty queue EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->composePwle(pwleQueue, nullptr).exceptionCode()); - vibrator->off(); + EXPECT_TRUE(vibrator->off().isOk()); ActivePwle active = composeValidActivePwle(vibrator, capabilities); @@ -801,7 +800,7 @@ TEST_P(VibratorAidl, ComposePwleSegmentBoundary) { EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->composePwle(pwleQueue, nullptr).exceptionCode()); - vibrator->off(); + EXPECT_TRUE(vibrator->off().isOk()); } } @@ -811,25 +810,20 @@ TEST_P(VibratorAidl, ComposePwleAmplitudeParameterBoundary) { active.startAmplitude = getAmplitudeMax() + 1.0; // Amplitude greater than allowed active.endAmplitude = getAmplitudeMax() + 1.0; // Amplitude greater than allowed - std::vector pwleQueueGreater; - PrimitivePwle pwle; - pwle = active; - pwleQueueGreater.emplace_back(std::move(pwle)); + auto pwleQueueGreater = std::vector{active}; EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->composePwle(pwleQueueGreater, nullptr).exceptionCode()); - vibrator->off(); + EXPECT_TRUE(vibrator->off().isOk()); active.startAmplitude = getAmplitudeMin() - 1.0; // Amplitude less than allowed active.endAmplitude = getAmplitudeMin() - 1.0; // Amplitude less than allowed - std::vector pwleQueueLess; - pwle = active; - pwleQueueLess.emplace_back(std::move(pwle)); + auto pwleQueueLess = std::vector{active}; EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->composePwle(pwleQueueLess, nullptr).exceptionCode()); - vibrator->off(); + EXPECT_TRUE(vibrator->off().isOk()); } } @@ -845,25 +839,20 @@ TEST_P(VibratorAidl, ComposePwleFrequencyParameterBoundary) { freqMaximumHz + freqResolutionHz; // Frequency greater than allowed active.endFrequency = freqMaximumHz + freqResolutionHz; // Frequency greater than allowed - std::vector pwleQueueGreater; - PrimitivePwle pwle; - pwle = active; - pwleQueueGreater.emplace_back(std::move(pwle)); + auto pwleQueueGreater = std::vector{active}; EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->composePwle(pwleQueueGreater, nullptr).exceptionCode()); - vibrator->off(); + EXPECT_TRUE(vibrator->off().isOk()); active.startFrequency = freqMinimumHz - freqResolutionHz; // Frequency less than allowed active.endFrequency = freqMinimumHz - freqResolutionHz; // Frequency less than allowed - std::vector pwleQueueLess; - pwle = active; - pwleQueueLess.emplace_back(std::move(pwle)); + auto pwleQueueLess = std::vector{active}; EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->composePwle(pwleQueueLess, nullptr).exceptionCode()); - vibrator->off(); + EXPECT_TRUE(vibrator->off().isOk()); } } @@ -875,14 +864,11 @@ TEST_P(VibratorAidl, ComposePwleSegmentDurationBoundary) { vibrator->getPwlePrimitiveDurationMax(&segmentDurationMaxMs); active.duration = segmentDurationMaxMs + 10; // Segment duration greater than allowed - std::vector pwleQueue; - PrimitivePwle pwle; - pwle = active; - pwleQueue.emplace_back(std::move(pwle)); + auto pwleQueue = std::vector{active}; EXPECT_EQ(Status::EX_ILLEGAL_ARGUMENT, vibrator->composePwle(pwleQueue, nullptr).exceptionCode()); - vibrator->off(); + EXPECT_TRUE(vibrator->off().isOk()); } } -- GitLab From bd8e4761482df950fce906d75a306e29cab5f8f6 Mon Sep 17 00:00:00 2001 From: Sarah Chin Date: Mon, 20 Sep 2021 13:45:18 -0700 Subject: [PATCH 790/790] Create IRadio modules Test: build Bug: 198331451 Change-Id: I6721498d5a0f535fa2fdfac7485765c740e82682 --- .../compatibility_matrix.current.xml | 54 +- .../exclude/fcm_exclude.cpp | 1 + radio/aidl/Android.bp | 148 +- .../hardware/radio/data}/ApnAuthType.aidl | 2 +- .../hardware/radio/data}/ApnTypes.aidl | 3 +- .../radio/data}/DataCallFailCause.aidl | 2 +- .../hardware/radio/data}/DataProfileInfo.aidl | 10 +- .../radio/data}/DataRequestReason.aidl | 2 +- .../radio/data}/DataThrottlingAction.aidl | 2 +- .../android/hardware/radio/data}/EpsQos.aidl | 6 +- .../hardware/radio/data/IRadioData.aidl | 53 + .../radio/data/IRadioDataIndication.aidl | 41 + .../radio/data/IRadioDataResponse.aidl | 52 + .../radio/data}/KeepaliveRequest.aidl | 2 +- .../hardware/radio/data}/KeepaliveStatus.aidl | 2 +- .../hardware/radio/data}/LinkAddress.aidl | 2 +- .../android/hardware/radio/data}/NrQos.aidl | 6 +- .../android/hardware/radio/data}/OsAppId.aidl | 2 +- .../hardware/radio/data}/PcoDataInfo.aidl | 2 +- .../hardware/radio/data}/PdpProtocolType.aidl | 2 +- .../hardware/radio/data}/PortRange.aidl | 2 +- .../android/hardware/radio/data}/Qos.aidl | 6 +- .../hardware/radio/data}/QosBandwidth.aidl | 2 +- .../hardware/radio/data}/QosFilter.aidl | 12 +- .../radio/data}/QosFilterIpsecSpi.aidl | 2 +- .../radio/data}/QosFilterIpv6FlowLabel.aidl | 2 +- .../radio/data}/QosFilterTypeOfService.aidl | 2 +- .../hardware/radio/data}/QosSession.aidl | 6 +- .../radio/data}/RouteSelectionDescriptor.aidl | 6 +- .../radio/data}/SetupDataCallResult.aidl | 16 +- .../hardware/radio/data}/SliceInfo.aidl | 2 +- .../hardware/radio/data}/SlicingConfig.aidl | 6 +- .../radio/data}/TrafficDescriptor.aidl | 4 +- .../hardware/radio/data}/UrspRule.aidl | 6 +- .../CdmaBroadcastSmsConfigInfo.aidl | 2 +- .../hardware/radio/messaging}/CdmaSmsAck.aidl | 2 +- .../radio/messaging}/CdmaSmsAddress.aidl | 2 +- .../radio/messaging}/CdmaSmsMessage.aidl | 6 +- .../radio/messaging}/CdmaSmsSubaddress.aidl | 2 +- .../radio/messaging}/CdmaSmsWriteArgs.aidl | 4 +- .../messaging}/GsmBroadcastSmsConfigInfo.aidl | 2 +- .../radio/messaging}/GsmSmsMessage.aidl | 2 +- .../radio/messaging/IRadioMessaging.aidl | 62 + .../messaging/IRadioMessagingIndication.aidl | 45 + .../messaging/IRadioMessagingResponse.aidl | 61 + .../radio/messaging}/ImsSmsMessage.aidl | 6 +- .../radio/messaging}/SendSmsResult.aidl | 2 +- .../messaging}/SmsAcknowledgeFailCause.aidl | 2 +- .../radio/messaging}/SmsWriteArgs.aidl | 2 +- .../radio/messaging}/UssdModeType.aidl | 2 +- .../radio/modem}/ActivityStatsInfo.aidl | 2 +- .../radio/modem}/DeviceStateType.aidl | 2 +- .../hardware/radio/modem}/HardwareConfig.aidl | 6 +- .../radio/modem}/HardwareConfigModem.aidl | 8 +- .../radio/modem}/HardwareConfigSim.aidl | 2 +- .../hardware/radio/modem/IRadioModem.aidl | 54 + .../radio/modem/IRadioModemIndication.aidl | 42 + .../radio/modem/IRadioModemResponse.aidl | 53 + .../android/hardware/radio/modem}/NvItem.aidl | 2 +- .../hardware/radio/modem}/NvWriteItem.aidl | 4 +- .../radio/modem}/RadioCapability.aidl | 2 +- .../hardware/radio/modem}/RadioState.aidl | 2 +- .../hardware/radio/modem}/ResetNvType.aidl | 2 +- .../AccessTechnologySpecificInfo.aidl | 8 +- .../hardware/radio/network}/BarringInfo.aidl | 4 +- .../network}/BarringTypeSpecificInfo.aidl | 2 +- .../network}/Cdma2000RegistrationInfo.aidl | 2 +- .../radio/network}/CdmaRoamingType.aidl | 2 +- .../radio/network}/CdmaSignalStrength.aidl | 2 +- .../radio/network}/CellConnectionStatus.aidl | 2 +- .../hardware/radio/network}/CellIdentity.aidl | 14 +- .../radio/network}/CellIdentityCdma.aidl | 4 +- .../radio/network}/CellIdentityGsm.aidl | 4 +- .../radio/network}/CellIdentityLte.aidl | 8 +- .../radio/network}/CellIdentityNr.aidl | 6 +- .../network}/CellIdentityOperatorNames.aidl | 2 +- .../radio/network}/CellIdentityTdscdma.aidl | 6 +- .../radio/network}/CellIdentityWcdma.aidl | 6 +- .../hardware/radio/network}/CellInfo.aidl | 6 +- .../hardware/radio/network}/CellInfoCdma.aidl | 8 +- .../hardware/radio/network}/CellInfoGsm.aidl | 6 +- .../hardware/radio/network}/CellInfoLte.aidl | 6 +- .../hardware/radio/network}/CellInfoNr.aidl | 6 +- .../network/CellInfoRatSpecificInfo.aidl | 43 + .../radio/network}/CellInfoTdscdma.aidl | 6 +- .../radio/network}/CellInfoWcdma.aidl | 6 +- .../network}/ClosedSubscriberGroupInfo.aidl | 2 +- .../hardware/radio/network}/Domain.aidl | 2 +- .../hardware/radio/network}/EutranBands.aidl | 2 +- .../network}/EutranRegistrationInfo.aidl | 6 +- .../radio/network}/EvdoSignalStrength.aidl | 2 +- .../hardware/radio/network}/GeranBands.aidl | 2 +- .../radio/network}/GsmSignalStrength.aidl | 2 +- .../hardware/radio/network/IRadioNetwork.aidl | 73 + .../network/IRadioNetworkIndication.aidl | 51 + .../radio/network/IRadioNetworkResponse.aidl | 72 + .../radio/network}/IndicationFilter.aidl | 2 +- .../hardware/radio/network}/LceDataInfo.aidl | 2 +- .../radio/network}/LinkCapacityEstimate.aidl | 2 +- .../radio/network}/LteSignalStrength.aidl | 2 +- .../hardware/radio/network}/LteVopsInfo.aidl | 2 +- .../radio/network}/NeighboringCell.aidl | 2 +- .../radio/network}/NetworkScanRequest.aidl | 4 +- .../radio/network}/NetworkScanResult.aidl | 4 +- .../hardware/radio/network}/NgranBands.aidl | 2 +- .../network}/NrDualConnectivityState.aidl | 2 +- .../hardware/radio/network}/NrIndicators.aidl | 2 +- .../radio/network}/NrSignalStrength.aidl | 2 +- .../hardware/radio/network}/NrVopsInfo.aidl | 2 +- .../hardware/radio/network}/OperatorInfo.aidl | 2 +- .../radio/network}/PhoneRestrictedState.aidl | 2 +- .../radio/network}/PhysicalChannelConfig.aidl | 6 +- .../network}/PhysicalChannelConfigBand.aidl | 10 +- .../radio/network}/RadioAccessSpecifier.aidl | 6 +- .../network}/RadioAccessSpecifierBands.aidl | 10 +- .../radio/network}/RadioBandMode.aidl | 2 +- .../hardware/radio/network}/RegState.aidl | 2 +- .../radio/network}/RegStateResult.aidl | 10 +- .../radio/network}/RegistrationFailCause.aidl | 2 +- .../radio/network}/SignalStrength.aidl | 16 +- .../radio/network}/SignalThresholdInfo.aidl | 2 +- .../radio/network}/SuppSvcNotification.aidl | 2 +- .../radio/network}/TdscdmaSignalStrength.aidl | 2 +- .../hardware/radio/network}/UtranBands.aidl | 2 +- .../radio/network}/WcdmaSignalStrength.aidl | 2 +- .../hardware/radio/sim}/AppStatus.aidl | 8 +- .../hardware/radio/sim}/CardPowerState.aidl | 2 +- .../hardware/radio/sim}/CardStatus.aidl | 6 +- .../android/hardware/radio/sim}/Carrier.aidl | 2 +- .../radio/sim}/CarrierRestrictions.aidl | 6 +- .../radio/sim}/CdmaSubscriptionSource.aidl | 2 +- .../android/hardware/radio/sim/IRadioSim.aidl | 74 + .../radio/sim/IRadioSimIndication.aidl | 48 + .../hardware/radio/sim/IRadioSimResponse.aidl | 73 + .../android/hardware/radio/sim}/IccIo.aidl | 2 +- .../hardware/radio/sim}/IccIoResult.aidl | 2 +- .../radio/sim}/ImsiEncryptionInfo.aidl | 2 +- .../hardware/radio/sim}/PbReceivedStatus.aidl | 2 +- .../hardware/radio/sim}/PersoSubstate.aidl | 2 +- .../radio/sim}/PhonebookCapacity.aidl | 2 +- .../radio/sim}/PhonebookRecordInfo.aidl | 2 +- .../android/hardware/radio/sim}/PinState.aidl | 2 +- .../hardware/radio/sim}/SelectUiccSub.aidl | 2 +- .../android/hardware/radio/sim}/SimApdu.aidl | 2 +- .../radio/sim}/SimLockMultiSimPolicy.aidl | 2 +- .../hardware/radio/sim}/SimRefreshResult.aidl | 2 +- .../hardware/radio/voice}/AudioQuality.aidl | 2 +- .../android/hardware/radio/voice}/Call.aidl | 6 +- .../radio/voice}/CallForwardInfo.aidl | 2 +- .../radio/voice}/CdmaCallWaiting.aidl | 4 +- .../radio/voice}/CdmaDisplayInfoRecord.aidl | 2 +- .../radio/voice}/CdmaInformationRecord.aidl | 16 +- .../radio/voice}/CdmaInformationRecords.aidl | 4 +- .../voice}/CdmaLineControlInfoRecord.aidl | 2 +- .../radio/voice}/CdmaNumberInfoRecord.aidl | 2 +- .../radio/voice}/CdmaOtaProvisionStatus.aidl | 2 +- .../CdmaRedirectingNumberInfoRecord.aidl | 4 +- .../radio/voice}/CdmaSignalInfoRecord.aidl | 2 +- .../voice}/CdmaT53AudioControlInfoRecord.aidl | 2 +- .../radio/voice}/CdmaT53ClirInfoRecord.aidl | 2 +- .../android/hardware/radio/voice}/CfData.aidl | 4 +- .../hardware/radio/voice}/ClipStatus.aidl | 2 +- .../android/hardware/radio/voice}/Dial.aidl | 4 +- .../radio/voice}/EmergencyCallRouting.aidl | 2 +- .../radio/voice}/EmergencyNumber.aidl | 4 +- .../voice}/EmergencyServiceCategory.aidl | 2 +- .../hardware/radio/voice/IRadioVoice.aidl | 72 + .../radio/voice/IRadioVoiceIndication.aidl | 51 + .../radio/voice/IRadioVoiceResponse.aidl | 71 + .../radio/voice}/LastCallFailCause.aidl | 2 +- .../radio/voice}/LastCallFailCauseInfo.aidl | 4 +- .../hardware/radio/voice}/SrvccState.aidl | 2 +- .../hardware/radio/voice}/SsInfoData.aidl | 2 +- .../radio/voice}/StkCcUnsolSsResult.aidl | 6 +- .../hardware/radio/voice}/TtyMode.aidl | 2 +- .../hardware/radio/voice}/UusInfo.aidl | 2 +- .../android/hardware/radio/CellConfigLte.aidl | 38 - .../CellInfoCellInfoRatSpecificInfo.aidl | 43 - .../android/hardware/radio/CellInfoInfo.aidl | 43 - .../android/hardware/radio/CellInfoType.aidl | 43 - .../hardware/radio/DataRegStateResult.aidl | 44 - .../android/hardware/radio/IRadio.aidl | 196 -- .../hardware/radio/IRadioIndication.aidl | 94 - .../hardware/radio/IRadioResponse.aidl | 199 -- .../android/hardware/radio/LceStatusInfo.aidl | 42 - .../hardware/radio/PreferredNetworkType.aidl | 60 - .../hardware/radio/RadioAccessNetworks.aidl | 43 - .../hardware/radio/RadioFrequencyInfo.aidl | 44 - .../hardware/radio/VoiceRegStateResult.aidl | 45 - .../android/hardware/radio/CellConfigLte.aidl | 31 - .../android/hardware/radio/CellInfoInfo.aidl | 34 - .../android/hardware/radio/CellInfoType.aidl | 28 - .../hardware/radio/DataRegStateResult.aidl | 63 - radio/aidl/android/hardware/radio/IRadio.aidl | 2012 ----------- .../hardware/radio/IRadioIndication.aidl | 626 ---- .../hardware/radio/IRadioResponse.aidl | 3039 ----------------- .../android/hardware/radio/LceStatusInfo.aidl | 33 - .../hardware/radio/PreferredNetworkType.aidl | 114 - .../hardware/radio/RadioAccessNetworks.aidl | 43 - .../hardware/radio/RadioFrequencyInfo.aidl | 48 - .../hardware/radio/VoiceRegStateResult.aidl | 94 - .../radio/{ => data}/ApnAuthType.aidl | 2 +- .../hardware/radio/{ => data}/ApnTypes.aidl | 7 +- .../radio/{ => data}/DataCallFailCause.aidl | 2 +- .../radio/{ => data}/DataProfileInfo.aidl | 12 +- .../radio/{ => data}/DataRequestReason.aidl | 2 +- .../{ => data}/DataThrottlingAction.aidl | 2 +- .../hardware/radio/{ => data}/EpsQos.aidl | 4 +- .../hardware/radio/data/IRadioData.aidl | 281 ++ .../radio/data/IRadioDataIndication.aidl | 74 + .../radio/data/IRadioDataResponse.aidl | 237 ++ .../radio/{ => data}/KeepaliveRequest.aidl | 2 +- .../radio/{ => data}/KeepaliveStatus.aidl | 2 +- .../radio/{ => data}/LinkAddress.aidl | 2 +- .../hardware/radio/{ => data}/NrQos.aidl | 4 +- .../hardware/radio/{ => data}/OsAppId.aidl | 2 +- .../radio/{ => data}/PcoDataInfo.aidl | 2 +- .../radio/{ => data}/PdpProtocolType.aidl | 2 +- .../hardware/radio/{ => data}/PortRange.aidl | 2 +- .../hardware/radio/{ => data}/Qos.aidl | 6 +- .../radio/{ => data}/QosBandwidth.aidl | 2 +- .../hardware/radio/{ => data}/QosFilter.aidl | 10 +- .../radio/{ => data}/QosFilterIpsecSpi.aidl | 2 +- .../{ => data}/QosFilterIpv6FlowLabel.aidl | 2 +- .../{ => data}/QosFilterTypeOfService.aidl | 2 +- .../hardware/radio/{ => data}/QosSession.aidl | 6 +- .../{ => data}/RouteSelectionDescriptor.aidl | 6 +- .../radio/{ => data}/SetupDataCallResult.aidl | 20 +- .../hardware/radio/{ => data}/SliceInfo.aidl | 2 +- .../radio/{ => data}/SlicingConfig.aidl | 6 +- .../radio/{ => data}/TrafficDescriptor.aidl | 4 +- .../hardware/radio/{ => data}/UrspRule.aidl | 6 +- .../CdmaBroadcastSmsConfigInfo.aidl | 2 +- .../radio/{ => messaging}/CdmaSmsAck.aidl | 2 +- .../radio/{ => messaging}/CdmaSmsAddress.aidl | 2 +- .../radio/{ => messaging}/CdmaSmsMessage.aidl | 6 +- .../{ => messaging}/CdmaSmsSubaddress.aidl | 2 +- .../{ => messaging}/CdmaSmsWriteArgs.aidl | 4 +- .../GsmBroadcastSmsConfigInfo.aidl | 2 +- .../radio/{ => messaging}/GsmSmsMessage.aidl | 2 +- .../radio/messaging/IRadioMessaging.aidl | 311 ++ .../messaging/IRadioMessagingIndication.aidl | 106 + .../messaging/IRadioMessagingResponse.aidl | 587 ++++ .../radio/{ => messaging}/ImsSmsMessage.aidl | 6 +- .../radio/{ => messaging}/SendSmsResult.aidl | 2 +- .../SmsAcknowledgeFailCause.aidl | 2 +- .../radio/{ => messaging}/SmsWriteArgs.aidl | 2 +- .../radio/{ => messaging}/UssdModeType.aidl | 2 +- .../radio/{ => modem}/ActivityStatsInfo.aidl | 2 +- .../radio/{ => modem}/DeviceStateType.aidl | 2 +- .../radio/{ => modem}/HardwareConfig.aidl | 6 +- .../{ => modem}/HardwareConfigModem.aidl | 10 +- .../radio/{ => modem}/HardwareConfigSim.aidl | 2 +- .../hardware/radio/modem/IRadioModem.aidl | 230 ++ .../radio/modem/IRadioModemIndication.aidl | 78 + .../radio/modem/IRadioModemResponse.aidl | 257 ++ .../hardware/radio/{ => modem}/NvItem.aidl | 2 +- .../radio/{ => modem}/NvWriteItem.aidl | 4 +- .../radio/{ => modem}/RadioCapability.aidl | 2 +- .../radio/{ => modem}/RadioState.aidl | 2 +- .../radio/{ => modem}/ResetNvType.aidl | 2 +- .../AccessTechnologySpecificInfo.aidl | 10 +- .../radio/{ => network}/BarringInfo.aidl | 4 +- .../BarringTypeSpecificInfo.aidl | 2 +- .../Cdma2000RegistrationInfo.aidl | 2 +- .../radio/{ => network}/CdmaRoamingType.aidl | 2 +- .../{ => network}/CdmaSignalStrength.aidl | 2 +- .../{ => network}/CellConnectionStatus.aidl | 4 +- .../radio/{ => network}/CellIdentity.aidl | 14 +- .../radio/{ => network}/CellIdentityCdma.aidl | 4 +- .../radio/{ => network}/CellIdentityGsm.aidl | 4 +- .../radio/{ => network}/CellIdentityLte.aidl | 8 +- .../radio/{ => network}/CellIdentityNr.aidl | 6 +- .../CellIdentityOperatorNames.aidl | 2 +- .../{ => network}/CellIdentityTdscdma.aidl | 6 +- .../{ => network}/CellIdentityWcdma.aidl | 6 +- .../radio/{ => network}/CellInfo.aidl | 8 +- .../radio/{ => network}/CellInfoCdma.aidl | 8 +- .../radio/{ => network}/CellInfoGsm.aidl | 6 +- .../radio/{ => network}/CellInfoLte.aidl | 6 +- .../radio/{ => network}/CellInfoNr.aidl | 6 +- .../CellInfoRatSpecificInfo.aidl} | 16 +- .../radio/{ => network}/CellInfoTdscdma.aidl | 6 +- .../radio/{ => network}/CellInfoWcdma.aidl | 6 +- .../ClosedSubscriberGroupInfo.aidl | 2 +- .../hardware/radio/{ => network}/Domain.aidl | 2 +- .../radio/{ => network}/EutranBands.aidl | 2 +- .../{ => network}/EutranRegistrationInfo.aidl | 6 +- .../{ => network}/EvdoSignalStrength.aidl | 2 +- .../radio/{ => network}/GeranBands.aidl | 2 +- .../{ => network}/GsmSignalStrength.aidl | 2 +- .../hardware/radio/network/IRadioNetwork.aidl | 444 +++ .../network/IRadioNetworkIndication.aidl | 188 + .../radio/network/IRadioNetworkResponse.aidl | 588 ++++ .../radio/{ => network}/IndicationFilter.aidl | 34 +- .../radio/{ => network}/LceDataInfo.aidl | 2 +- .../{ => network}/LinkCapacityEstimate.aidl | 2 +- .../{ => network}/LteSignalStrength.aidl | 2 +- .../radio/{ => network}/LteVopsInfo.aidl | 2 +- .../radio/{ => network}/NeighboringCell.aidl | 2 +- .../{ => network}/NetworkScanRequest.aidl | 4 +- .../{ => network}/NetworkScanResult.aidl | 4 +- .../radio/{ => network}/NgranBands.aidl | 2 +- .../NrDualConnectivityState.aidl | 2 +- .../radio/{ => network}/NrIndicators.aidl | 2 +- .../radio/{ => network}/NrSignalStrength.aidl | 2 +- .../radio/{ => network}/NrVopsInfo.aidl | 4 +- .../radio/{ => network}/OperatorInfo.aidl | 2 +- .../{ => network}/PhoneRestrictedState.aidl | 2 +- .../{ => network}/PhysicalChannelConfig.aidl | 6 +- .../PhysicalChannelConfigBand.aidl | 10 +- .../{ => network}/RadioAccessSpecifier.aidl | 8 +- .../RadioAccessSpecifierBands.aidl | 10 +- .../radio/{ => network}/RadioBandMode.aidl | 2 +- .../radio/{ => network}/RegState.aidl | 2 +- .../radio/{ => network}/RegStateResult.aidl | 12 +- .../{ => network}/RegistrationFailCause.aidl | 2 +- .../radio/{ => network}/SignalStrength.aidl | 16 +- .../{ => network}/SignalThresholdInfo.aidl | 2 +- .../{ => network}/SuppSvcNotification.aidl | 2 +- .../{ => network}/TdscdmaSignalStrength.aidl | 2 +- .../radio/{ => network}/UtranBands.aidl | 2 +- .../{ => network}/WcdmaSignalStrength.aidl | 2 +- .../hardware/radio/{ => sim}/AppStatus.aidl | 6 +- .../radio/{ => sim}/CardPowerState.aidl | 2 +- .../hardware/radio/{ => sim}/CardStatus.aidl | 14 +- .../hardware/radio/{ => sim}/Carrier.aidl | 6 +- .../radio/{ => sim}/CarrierRestrictions.aidl | 4 +- .../{ => sim}/CdmaSubscriptionSource.aidl | 2 +- .../android/hardware/radio/sim/IRadioSim.aidl | 502 +++ .../radio/sim/IRadioSimIndication.aidl | 130 + .../hardware/radio/sim/IRadioSimResponse.aidl | 649 ++++ .../hardware/radio/{ => sim}/IccIo.aidl | 2 +- .../hardware/radio/{ => sim}/IccIoResult.aidl | 2 +- .../radio/{ => sim}/ImsiEncryptionInfo.aidl | 2 +- .../radio/{ => sim}/PbReceivedStatus.aidl | 2 +- .../radio/{ => sim}/PersoSubstate.aidl | 2 +- .../radio/{ => sim}/PhonebookCapacity.aidl | 2 +- .../radio/{ => sim}/PhonebookRecordInfo.aidl | 2 +- .../hardware/radio/{ => sim}/PinState.aidl | 2 +- .../radio/{ => sim}/SelectUiccSub.aidl | 2 +- .../hardware/radio/{ => sim}/SimApdu.aidl | 2 +- .../{ => sim}/SimLockMultiSimPolicy.aidl | 2 +- .../radio/{ => sim}/SimRefreshResult.aidl | 11 +- .../radio/{ => voice}/AudioQuality.aidl | 2 +- .../hardware/radio/{ => voice}/Call.aidl | 6 +- .../radio/{ => voice}/CallForwardInfo.aidl | 7 +- .../radio/{ => voice}/CdmaCallWaiting.aidl | 4 +- .../{ => voice}/CdmaDisplayInfoRecord.aidl | 2 +- .../{ => voice}/CdmaInformationRecord.aidl | 16 +- .../{ => voice}/CdmaInformationRecords.aidl | 4 +- .../CdmaLineControlInfoRecord.aidl | 2 +- .../{ => voice}/CdmaNumberInfoRecord.aidl | 4 +- .../{ => voice}/CdmaOtaProvisionStatus.aidl | 2 +- .../CdmaRedirectingNumberInfoRecord.aidl | 4 +- .../{ => voice}/CdmaSignalInfoRecord.aidl | 2 +- .../CdmaT53AudioControlInfoRecord.aidl | 2 +- .../{ => voice}/CdmaT53ClirInfoRecord.aidl | 2 +- .../hardware/radio/{ => voice}/CfData.aidl | 4 +- .../radio/{ => voice}/ClipStatus.aidl | 2 +- .../hardware/radio/{ => voice}/Dial.aidl | 4 +- .../{ => voice}/EmergencyCallRouting.aidl | 2 +- .../radio/{ => voice}/EmergencyNumber.aidl | 4 +- .../{ => voice}/EmergencyServiceCategory.aidl | 2 +- .../hardware/radio/voice/IRadioVoice.aidl | 443 +++ .../radio/voice/IRadioVoiceIndication.aidl | 169 + .../radio/voice/IRadioVoiceResponse.aidl | 751 ++++ .../radio/{ => voice}/LastCallFailCause.aidl | 2 +- .../{ => voice}/LastCallFailCauseInfo.aidl | 4 +- .../radio/{ => voice}/SrvccState.aidl | 2 +- .../radio/{ => voice}/SsInfoData.aidl | 4 +- .../radio/{ => voice}/StkCcUnsolSsResult.aidl | 10 +- .../hardware/radio/{ => voice}/TtyMode.aidl | 2 +- .../hardware/radio/{ => voice}/UusInfo.aidl | 2 +- 374 files changed, 7906 insertions(+), 7746 deletions(-) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.data/current/android/hardware/radio/data}/ApnAuthType.aidl (98%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.data/current/android/hardware/radio/data}/ApnTypes.aidl (97%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.data/current/android/hardware/radio/data}/DataCallFailCause.aidl (99%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.data/current/android/hardware/radio/data}/DataProfileInfo.aidl (89%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.data/current/android/hardware/radio/data}/DataRequestReason.aidl (98%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.data/current/android/hardware/radio/data}/DataThrottlingAction.aidl (98%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.data/current/android/hardware/radio/data}/EpsQos.aidl (92%) create mode 100644 radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/IRadioData.aidl create mode 100644 radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/IRadioDataIndication.aidl create mode 100644 radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/IRadioDataResponse.aidl rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.data/current/android/hardware/radio/data}/KeepaliveRequest.aidl (98%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.data/current/android/hardware/radio/data}/KeepaliveStatus.aidl (98%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.data/current/android/hardware/radio/data}/LinkAddress.aidl (98%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.data/current/android/hardware/radio/data}/NrQos.aidl (92%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.data/current/android/hardware/radio/data}/OsAppId.aidl (97%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.data/current/android/hardware/radio/data}/PcoDataInfo.aidl (98%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.data/current/android/hardware/radio/data}/PdpProtocolType.aidl (98%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.data/current/android/hardware/radio/data}/PortRange.aidl (98%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.data/current/android/hardware/radio/data}/Qos.aidl (93%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.data/current/android/hardware/radio/data}/QosBandwidth.aidl (97%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.data/current/android/hardware/radio/data}/QosFilter.aidl (86%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.data/current/android/hardware/radio/data}/QosFilterIpsecSpi.aidl (97%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.data/current/android/hardware/radio/data}/QosFilterIpv6FlowLabel.aidl (97%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.data/current/android/hardware/radio/data}/QosFilterTypeOfService.aidl (97%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.data/current/android/hardware/radio/data}/QosSession.aidl (93%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.data/current/android/hardware/radio/data}/RouteSelectionDescriptor.aidl (92%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.data/current/android/hardware/radio/data}/SetupDataCallResult.aidl (84%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.data/current/android/hardware/radio/data}/SliceInfo.aidl (98%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.data/current/android/hardware/radio/data}/SlicingConfig.aidl (92%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.data/current/android/hardware/radio/data}/TrafficDescriptor.aidl (94%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.data/current/android/hardware/radio/data}/UrspRule.aidl (90%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.messaging/current/android/hardware/radio/messaging}/CdmaBroadcastSmsConfigInfo.aidl (97%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.messaging/current/android/hardware/radio/messaging}/CdmaSmsAck.aidl (97%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.messaging/current/android/hardware/radio/messaging}/CdmaSmsAddress.aidl (98%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.messaging/current/android/hardware/radio/messaging}/CdmaSmsMessage.aidl (91%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.messaging/current/android/hardware/radio/messaging}/CdmaSmsSubaddress.aidl (97%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.messaging/current/android/hardware/radio/messaging}/CdmaSmsWriteArgs.aidl (94%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.messaging/current/android/hardware/radio/messaging}/GsmBroadcastSmsConfigInfo.aidl (97%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.messaging/current/android/hardware/radio/messaging}/GsmSmsMessage.aidl (97%) create mode 100644 radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/IRadioMessaging.aidl create mode 100644 radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/IRadioMessagingIndication.aidl create mode 100644 radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/IRadioMessagingResponse.aidl rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.messaging/current/android/hardware/radio/messaging}/ImsSmsMessage.aidl (91%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.messaging/current/android/hardware/radio/messaging}/SendSmsResult.aidl (97%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.messaging/current/android/hardware/radio/messaging}/SmsAcknowledgeFailCause.aidl (97%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.messaging/current/android/hardware/radio/messaging}/SmsWriteArgs.aidl (97%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.messaging/current/android/hardware/radio/messaging}/UssdModeType.aidl (97%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.modem/current/android/hardware/radio/modem}/ActivityStatsInfo.aidl (97%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.modem/current/android/hardware/radio/modem}/DeviceStateType.aidl (97%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.modem/current/android/hardware/radio/modem}/HardwareConfig.aidl (92%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.modem/current/android/hardware/radio/modem}/HardwareConfigModem.aidl (93%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.modem/current/android/hardware/radio/modem}/HardwareConfigSim.aidl (97%) create mode 100644 radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/IRadioModem.aidl create mode 100644 radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/IRadioModemIndication.aidl create mode 100644 radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/IRadioModemResponse.aidl rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.modem/current/android/hardware/radio/modem}/NvItem.aidl (98%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.modem/current/android/hardware/radio/modem}/NvWriteItem.aidl (95%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.modem/current/android/hardware/radio/modem}/RadioCapability.aidl (98%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.modem/current/android/hardware/radio/modem}/RadioState.aidl (97%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.modem/current/android/hardware/radio/modem}/ResetNvType.aidl (97%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/AccessTechnologySpecificInfo.aidl (88%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/BarringInfo.aidl (96%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/BarringTypeSpecificInfo.aidl (97%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/Cdma2000RegistrationInfo.aidl (98%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/CdmaRoamingType.aidl (97%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/CdmaSignalStrength.aidl (97%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/CellConnectionStatus.aidl (97%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/CellIdentity.aidl (82%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/CellIdentityCdma.aidl (94%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/CellIdentityGsm.aidl (94%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/CellIdentityLte.aidl (88%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/CellIdentityNr.aidl (91%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/CellIdentityOperatorNames.aidl (97%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/CellIdentityTdscdma.aidl (90%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/CellIdentityWcdma.aidl (90%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/CellInfo.aidl (90%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/CellInfoCdma.aidl (87%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/CellInfoGsm.aidl (90%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/CellInfoLte.aidl (90%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/CellInfoNr.aidl (91%) create mode 100644 radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoRatSpecificInfo.aidl rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/CellInfoTdscdma.aidl (90%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/CellInfoWcdma.aidl (90%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/ClosedSubscriberGroupInfo.aidl (97%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/Domain.aidl (97%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/EutranBands.aidl (98%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/EutranRegistrationInfo.aidl (91%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/EvdoSignalStrength.aidl (97%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/GeranBands.aidl (98%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/GsmSignalStrength.aidl (97%) create mode 100644 radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetwork.aidl create mode 100644 radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkIndication.aidl create mode 100644 radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkResponse.aidl rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/IndicationFilter.aidl (98%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/LceDataInfo.aidl (97%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/LinkCapacityEstimate.aidl (97%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/LteSignalStrength.aidl (97%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/LteVopsInfo.aidl (97%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/NeighboringCell.aidl (97%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/NetworkScanRequest.aidl (95%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/NetworkScanResult.aidl (95%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/NgranBands.aidl (98%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/NrDualConnectivityState.aidl (97%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/NrIndicators.aidl (97%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/NrSignalStrength.aidl (97%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/NrVopsInfo.aidl (98%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/OperatorInfo.aidl (98%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/PhoneRestrictedState.aidl (97%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/PhysicalChannelConfig.aidl (92%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/PhysicalChannelConfigBand.aidl (87%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/RadioAccessSpecifier.aidl (91%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/RadioAccessSpecifierBands.aidl (86%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/RadioBandMode.aidl (98%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/RegState.aidl (98%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/RegStateResult.aidl (85%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/RegistrationFailCause.aidl (98%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/SignalStrength.aidl (79%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/SignalThresholdInfo.aidl (98%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/SuppSvcNotification.aidl (97%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/TdscdmaSignalStrength.aidl (97%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/UtranBands.aidl (98%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.network/current/android/hardware/radio/network}/WcdmaSignalStrength.aidl (97%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.sim/current/android/hardware/radio/sim}/AppStatus.aidl (92%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.sim/current/android/hardware/radio/sim}/CardPowerState.aidl (98%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.sim/current/android/hardware/radio/sim}/CardStatus.aidl (93%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.sim/current/android/hardware/radio/sim}/Carrier.aidl (98%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.sim/current/android/hardware/radio/sim}/CarrierRestrictions.aidl (92%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.sim/current/android/hardware/radio/sim}/CdmaSubscriptionSource.aidl (98%) create mode 100644 radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IRadioSim.aidl create mode 100644 radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IRadioSimIndication.aidl create mode 100644 radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IRadioSimResponse.aidl rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.sim/current/android/hardware/radio/sim}/IccIo.aidl (98%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.sim/current/android/hardware/radio/sim}/IccIoResult.aidl (98%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.sim/current/android/hardware/radio/sim}/ImsiEncryptionInfo.aidl (98%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.sim/current/android/hardware/radio/sim}/PbReceivedStatus.aidl (98%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.sim/current/android/hardware/radio/sim}/PersoSubstate.aidl (98%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.sim/current/android/hardware/radio/sim}/PhonebookCapacity.aidl (98%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.sim/current/android/hardware/radio/sim}/PhonebookRecordInfo.aidl (98%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.sim/current/android/hardware/radio/sim}/PinState.aidl (98%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.sim/current/android/hardware/radio/sim}/SelectUiccSub.aidl (98%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.sim/current/android/hardware/radio/sim}/SimApdu.aidl (98%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.sim/current/android/hardware/radio/sim}/SimLockMultiSimPolicy.aidl (98%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.sim/current/android/hardware/radio/sim}/SimRefreshResult.aidl (98%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.voice/current/android/hardware/radio/voice}/AudioQuality.aidl (98%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.voice/current/android/hardware/radio/voice}/Call.aidl (94%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.voice/current/android/hardware/radio/voice}/CallForwardInfo.aidl (98%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.voice/current/android/hardware/radio/voice}/CdmaCallWaiting.aidl (95%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.voice/current/android/hardware/radio/voice}/CdmaDisplayInfoRecord.aidl (97%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.voice/current/android/hardware/radio/voice}/CdmaInformationRecord.aidl (81%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.voice/current/android/hardware/radio/voice}/CdmaInformationRecords.aidl (94%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.voice/current/android/hardware/radio/voice}/CdmaLineControlInfoRecord.aidl (98%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.voice/current/android/hardware/radio/voice}/CdmaNumberInfoRecord.aidl (97%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.voice/current/android/hardware/radio/voice}/CdmaOtaProvisionStatus.aidl (98%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.voice/current/android/hardware/radio/voice}/CdmaRedirectingNumberInfoRecord.aidl (95%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.voice/current/android/hardware/radio/voice}/CdmaSignalInfoRecord.aidl (97%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.voice/current/android/hardware/radio/voice}/CdmaT53AudioControlInfoRecord.aidl (97%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.voice/current/android/hardware/radio/voice}/CdmaT53ClirInfoRecord.aidl (97%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.voice/current/android/hardware/radio/voice}/CfData.aidl (94%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.voice/current/android/hardware/radio/voice}/ClipStatus.aidl (97%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.voice/current/android/hardware/radio/voice}/Dial.aidl (95%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.voice/current/android/hardware/radio/voice}/EmergencyCallRouting.aidl (97%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.voice/current/android/hardware/radio/voice}/EmergencyNumber.aidl (94%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.voice/current/android/hardware/radio/voice}/EmergencyServiceCategory.aidl (98%) create mode 100644 radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoice.aidl create mode 100644 radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoiceIndication.aidl create mode 100644 radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoiceResponse.aidl rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.voice/current/android/hardware/radio/voice}/LastCallFailCause.aidl (99%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.voice/current/android/hardware/radio/voice}/LastCallFailCauseInfo.aidl (94%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.voice/current/android/hardware/radio/voice}/SrvccState.aidl (97%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.voice/current/android/hardware/radio/voice}/SsInfoData.aidl (97%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.voice/current/android/hardware/radio/voice}/StkCcUnsolSsResult.aidl (96%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.voice/current/android/hardware/radio/voice}/TtyMode.aidl (97%) rename radio/aidl/aidl_api/{android.hardware.radio/current/android/hardware/radio => android.hardware.radio.voice/current/android/hardware/radio/voice}/UusInfo.aidl (98%) delete mode 100644 radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellConfigLte.aidl delete mode 100644 radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoCellInfoRatSpecificInfo.aidl delete mode 100644 radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoInfo.aidl delete mode 100644 radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoType.aidl delete mode 100644 radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/DataRegStateResult.aidl delete mode 100644 radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/IRadio.aidl delete mode 100644 radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/IRadioIndication.aidl delete mode 100644 radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/IRadioResponse.aidl delete mode 100644 radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LceStatusInfo.aidl delete mode 100644 radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PreferredNetworkType.aidl delete mode 100644 radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioAccessNetworks.aidl delete mode 100644 radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioFrequencyInfo.aidl delete mode 100644 radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/VoiceRegStateResult.aidl delete mode 100644 radio/aidl/android/hardware/radio/CellConfigLte.aidl delete mode 100644 radio/aidl/android/hardware/radio/CellInfoInfo.aidl delete mode 100644 radio/aidl/android/hardware/radio/CellInfoType.aidl delete mode 100644 radio/aidl/android/hardware/radio/DataRegStateResult.aidl delete mode 100644 radio/aidl/android/hardware/radio/IRadio.aidl delete mode 100644 radio/aidl/android/hardware/radio/IRadioIndication.aidl delete mode 100644 radio/aidl/android/hardware/radio/IRadioResponse.aidl delete mode 100644 radio/aidl/android/hardware/radio/LceStatusInfo.aidl delete mode 100644 radio/aidl/android/hardware/radio/PreferredNetworkType.aidl delete mode 100644 radio/aidl/android/hardware/radio/RadioAccessNetworks.aidl delete mode 100644 radio/aidl/android/hardware/radio/RadioFrequencyInfo.aidl delete mode 100644 radio/aidl/android/hardware/radio/VoiceRegStateResult.aidl rename radio/aidl/android/hardware/radio/{ => data}/ApnAuthType.aidl (96%) rename radio/aidl/android/hardware/radio/{ => data}/ApnTypes.aidl (86%) rename radio/aidl/android/hardware/radio/{ => data}/DataCallFailCause.aidl (99%) rename radio/aidl/android/hardware/radio/{ => data}/DataProfileInfo.aidl (90%) rename radio/aidl/android/hardware/radio/{ => data}/DataRequestReason.aidl (96%) rename radio/aidl/android/hardware/radio/{ => data}/DataThrottlingAction.aidl (96%) rename radio/aidl/android/hardware/radio/{ => data}/EpsQos.aidl (92%) create mode 100644 radio/aidl/android/hardware/radio/data/IRadioData.aidl create mode 100644 radio/aidl/android/hardware/radio/data/IRadioDataIndication.aidl create mode 100644 radio/aidl/android/hardware/radio/data/IRadioDataResponse.aidl rename radio/aidl/android/hardware/radio/{ => data}/KeepaliveRequest.aidl (97%) rename radio/aidl/android/hardware/radio/{ => data}/KeepaliveStatus.aidl (97%) rename radio/aidl/android/hardware/radio/{ => data}/LinkAddress.aidl (98%) rename radio/aidl/android/hardware/radio/{ => data}/NrQos.aidl (93%) rename radio/aidl/android/hardware/radio/{ => data}/OsAppId.aidl (96%) rename radio/aidl/android/hardware/radio/{ => data}/PcoDataInfo.aidl (97%) rename radio/aidl/android/hardware/radio/{ => data}/PdpProtocolType.aidl (97%) rename radio/aidl/android/hardware/radio/{ => data}/PortRange.aidl (96%) rename radio/aidl/android/hardware/radio/{ => data}/Qos.aidl (85%) rename radio/aidl/android/hardware/radio/{ => data}/QosBandwidth.aidl (95%) rename radio/aidl/android/hardware/radio/{ => data}/QosFilter.aidl (90%) rename radio/aidl/android/hardware/radio/{ => data}/QosFilterIpsecSpi.aidl (94%) rename radio/aidl/android/hardware/radio/{ => data}/QosFilterIpv6FlowLabel.aidl (95%) rename radio/aidl/android/hardware/radio/{ => data}/QosFilterTypeOfService.aidl (95%) rename radio/aidl/android/hardware/radio/{ => data}/QosSession.aidl (88%) rename radio/aidl/android/hardware/radio/{ => data}/RouteSelectionDescriptor.aidl (92%) rename radio/aidl/android/hardware/radio/{ => data}/SetupDataCallResult.aidl (90%) rename radio/aidl/android/hardware/radio/{ => data}/SliceInfo.aidl (98%) rename radio/aidl/android/hardware/radio/{ => data}/SlicingConfig.aidl (88%) rename radio/aidl/android/hardware/radio/{ => data}/TrafficDescriptor.aidl (93%) rename radio/aidl/android/hardware/radio/{ => data}/UrspRule.aidl (88%) rename radio/aidl/android/hardware/radio/{ => messaging}/CdmaBroadcastSmsConfigInfo.aidl (96%) rename radio/aidl/android/hardware/radio/{ => messaging}/CdmaSmsAck.aidl (95%) rename radio/aidl/android/hardware/radio/{ => messaging}/CdmaSmsAddress.aidl (98%) rename radio/aidl/android/hardware/radio/{ => messaging}/CdmaSmsMessage.aidl (84%) rename radio/aidl/android/hardware/radio/{ => messaging}/CdmaSmsSubaddress.aidl (96%) rename radio/aidl/android/hardware/radio/{ => messaging}/CdmaSmsWriteArgs.aidl (90%) rename radio/aidl/android/hardware/radio/{ => messaging}/GsmBroadcastSmsConfigInfo.aidl (97%) rename radio/aidl/android/hardware/radio/{ => messaging}/GsmSmsMessage.aidl (95%) create mode 100644 radio/aidl/android/hardware/radio/messaging/IRadioMessaging.aidl create mode 100644 radio/aidl/android/hardware/radio/messaging/IRadioMessagingIndication.aidl create mode 100644 radio/aidl/android/hardware/radio/messaging/IRadioMessagingResponse.aidl rename radio/aidl/android/hardware/radio/{ => messaging}/ImsSmsMessage.aidl (90%) rename radio/aidl/android/hardware/radio/{ => messaging}/SendSmsResult.aidl (96%) rename radio/aidl/android/hardware/radio/{ => messaging}/SmsAcknowledgeFailCause.aidl (94%) rename radio/aidl/android/hardware/radio/{ => messaging}/SmsWriteArgs.aidl (96%) rename radio/aidl/android/hardware/radio/{ => messaging}/UssdModeType.aidl (96%) rename radio/aidl/android/hardware/radio/{ => modem}/ActivityStatsInfo.aidl (97%) rename radio/aidl/android/hardware/radio/{ => modem}/DeviceStateType.aidl (96%) rename radio/aidl/android/hardware/radio/{ => modem}/HardwareConfig.aidl (90%) rename radio/aidl/android/hardware/radio/{ => modem}/HardwareConfigModem.aidl (90%) rename radio/aidl/android/hardware/radio/{ => modem}/HardwareConfigSim.aidl (95%) create mode 100644 radio/aidl/android/hardware/radio/modem/IRadioModem.aidl create mode 100644 radio/aidl/android/hardware/radio/modem/IRadioModemIndication.aidl create mode 100644 radio/aidl/android/hardware/radio/modem/IRadioModemResponse.aidl rename radio/aidl/android/hardware/radio/{ => modem}/NvItem.aidl (99%) rename radio/aidl/android/hardware/radio/{ => modem}/NvWriteItem.aidl (89%) rename radio/aidl/android/hardware/radio/{ => modem}/RadioCapability.aidl (98%) rename radio/aidl/android/hardware/radio/{ => modem}/RadioState.aidl (95%) rename radio/aidl/android/hardware/radio/{ => modem}/ResetNvType.aidl (95%) rename radio/aidl/android/hardware/radio/{ => network}/AccessTechnologySpecificInfo.aidl (77%) rename radio/aidl/android/hardware/radio/{ => network}/BarringInfo.aidl (97%) rename radio/aidl/android/hardware/radio/{ => network}/BarringTypeSpecificInfo.aidl (97%) rename radio/aidl/android/hardware/radio/{ => network}/Cdma2000RegistrationInfo.aidl (97%) rename radio/aidl/android/hardware/radio/{ => network}/CdmaRoamingType.aidl (94%) rename radio/aidl/android/hardware/radio/{ => network}/CdmaSignalStrength.aidl (96%) rename radio/aidl/android/hardware/radio/{ => network}/CellConnectionStatus.aidl (87%) rename radio/aidl/android/hardware/radio/{ => network}/CellIdentity.aidl (70%) rename radio/aidl/android/hardware/radio/{ => network}/CellIdentityCdma.aidl (93%) rename radio/aidl/android/hardware/radio/{ => network}/CellIdentityGsm.aidl (93%) rename radio/aidl/android/hardware/radio/{ => network}/CellIdentityLte.aidl (88%) rename radio/aidl/android/hardware/radio/{ => network}/CellIdentityNr.aidl (93%) rename radio/aidl/android/hardware/radio/{ => network}/CellIdentityOperatorNames.aidl (95%) rename radio/aidl/android/hardware/radio/{ => network}/CellIdentityTdscdma.aidl (90%) rename radio/aidl/android/hardware/radio/{ => network}/CellIdentityWcdma.aidl (90%) rename radio/aidl/android/hardware/radio/{ => network}/CellInfo.aidl (80%) rename radio/aidl/android/hardware/radio/{ => network}/CellInfoCdma.aidl (78%) rename radio/aidl/android/hardware/radio/{ => network}/CellInfoGsm.aidl (83%) rename radio/aidl/android/hardware/radio/{ => network}/CellInfoLte.aidl (83%) rename radio/aidl/android/hardware/radio/{ => network}/CellInfoNr.aidl (83%) rename radio/aidl/android/hardware/radio/{CellInfoCellInfoRatSpecificInfo.aidl => network/CellInfoRatSpecificInfo.aidl} (69%) rename radio/aidl/android/hardware/radio/{ => network}/CellInfoTdscdma.aidl (82%) rename radio/aidl/android/hardware/radio/{ => network}/CellInfoWcdma.aidl (82%) rename radio/aidl/android/hardware/radio/{ => network}/ClosedSubscriberGroupInfo.aidl (97%) rename radio/aidl/android/hardware/radio/{ => network}/Domain.aidl (95%) rename radio/aidl/android/hardware/radio/{ => network}/EutranBands.aidl (97%) rename radio/aidl/android/hardware/radio/{ => network}/EutranRegistrationInfo.aidl (88%) rename radio/aidl/android/hardware/radio/{ => network}/EvdoSignalStrength.aidl (96%) rename radio/aidl/android/hardware/radio/{ => network}/GeranBands.aidl (95%) rename radio/aidl/android/hardware/radio/{ => network}/GsmSignalStrength.aidl (96%) create mode 100644 radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl create mode 100644 radio/aidl/android/hardware/radio/network/IRadioNetworkIndication.aidl create mode 100644 radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl rename radio/aidl/android/hardware/radio/{ => network}/IndicationFilter.aidl (52%) rename radio/aidl/android/hardware/radio/{ => network}/LceDataInfo.aidl (96%) rename radio/aidl/android/hardware/radio/{ => network}/LinkCapacityEstimate.aidl (98%) rename radio/aidl/android/hardware/radio/{ => network}/LteSignalStrength.aidl (98%) rename radio/aidl/android/hardware/radio/{ => network}/LteVopsInfo.aidl (97%) rename radio/aidl/android/hardware/radio/{ => network}/NeighboringCell.aidl (95%) rename radio/aidl/android/hardware/radio/{ => network}/NetworkScanRequest.aidl (96%) rename radio/aidl/android/hardware/radio/{ => network}/NetworkScanResult.aidl (93%) rename radio/aidl/android/hardware/radio/{ => network}/NgranBands.aidl (97%) rename radio/aidl/android/hardware/radio/{ => network}/NrDualConnectivityState.aidl (97%) rename radio/aidl/android/hardware/radio/{ => network}/NrIndicators.aidl (97%) rename radio/aidl/android/hardware/radio/{ => network}/NrSignalStrength.aidl (98%) rename radio/aidl/android/hardware/radio/{ => network}/NrVopsInfo.aidl (98%) rename radio/aidl/android/hardware/radio/{ => network}/OperatorInfo.aidl (96%) rename radio/aidl/android/hardware/radio/{ => network}/PhoneRestrictedState.aidl (96%) rename radio/aidl/android/hardware/radio/{ => network}/PhysicalChannelConfig.aidl (92%) rename radio/aidl/android/hardware/radio/{ => network}/PhysicalChannelConfigBand.aidl (81%) rename radio/aidl/android/hardware/radio/{ => network}/RadioAccessSpecifier.aidl (84%) rename radio/aidl/android/hardware/radio/{ => network}/RadioAccessSpecifierBands.aidl (81%) rename radio/aidl/android/hardware/radio/{ => network}/RadioBandMode.aidl (98%) rename radio/aidl/android/hardware/radio/{ => network}/RegState.aidl (98%) rename radio/aidl/android/hardware/radio/{ => network}/RegStateResult.aidl (86%) rename radio/aidl/android/hardware/radio/{ => network}/RegistrationFailCause.aidl (99%) rename radio/aidl/android/hardware/radio/{ => network}/SignalStrength.aidl (82%) rename radio/aidl/android/hardware/radio/{ => network}/SignalThresholdInfo.aidl (98%) rename radio/aidl/android/hardware/radio/{ => network}/SuppSvcNotification.aidl (96%) rename radio/aidl/android/hardware/radio/{ => network}/TdscdmaSignalStrength.aidl (97%) rename radio/aidl/android/hardware/radio/{ => network}/UtranBands.aidl (96%) rename radio/aidl/android/hardware/radio/{ => network}/WcdmaSignalStrength.aidl (97%) rename radio/aidl/android/hardware/radio/{ => sim}/AppStatus.aidl (93%) rename radio/aidl/android/hardware/radio/{ => sim}/CardPowerState.aidl (95%) rename radio/aidl/android/hardware/radio/{ => sim}/CardStatus.aidl (88%) rename radio/aidl/android/hardware/radio/{ => sim}/Carrier.aidl (87%) rename radio/aidl/android/hardware/radio/{ => sim}/CarrierRestrictions.aidl (95%) rename radio/aidl/android/hardware/radio/{ => sim}/CdmaSubscriptionSource.aidl (95%) create mode 100644 radio/aidl/android/hardware/radio/sim/IRadioSim.aidl create mode 100644 radio/aidl/android/hardware/radio/sim/IRadioSimIndication.aidl create mode 100644 radio/aidl/android/hardware/radio/sim/IRadioSimResponse.aidl rename radio/aidl/android/hardware/radio/{ => sim}/IccIo.aidl (97%) rename radio/aidl/android/hardware/radio/{ => sim}/IccIoResult.aidl (96%) rename radio/aidl/android/hardware/radio/{ => sim}/ImsiEncryptionInfo.aidl (98%) rename radio/aidl/android/hardware/radio/{ => sim}/PbReceivedStatus.aidl (97%) rename radio/aidl/android/hardware/radio/{ => sim}/PersoSubstate.aidl (98%) rename radio/aidl/android/hardware/radio/{ => sim}/PhonebookCapacity.aidl (98%) rename radio/aidl/android/hardware/radio/{ => sim}/PhonebookRecordInfo.aidl (97%) rename radio/aidl/android/hardware/radio/{ => sim}/PinState.aidl (95%) rename radio/aidl/android/hardware/radio/{ => sim}/SelectUiccSub.aidl (96%) rename radio/aidl/android/hardware/radio/{ => sim}/SimApdu.aidl (97%) rename radio/aidl/android/hardware/radio/{ => sim}/SimLockMultiSimPolicy.aidl (96%) rename radio/aidl/android/hardware/radio/{ => sim}/SimRefreshResult.aidl (73%) rename radio/aidl/android/hardware/radio/{ => voice}/AudioQuality.aidl (97%) rename radio/aidl/android/hardware/radio/{ => voice}/Call.aidl (94%) rename radio/aidl/android/hardware/radio/{ => voice}/CallForwardInfo.aidl (83%) rename radio/aidl/android/hardware/radio/{ => voice}/CdmaCallWaiting.aidl (94%) rename radio/aidl/android/hardware/radio/{ => voice}/CdmaDisplayInfoRecord.aidl (97%) rename radio/aidl/android/hardware/radio/{ => voice}/CdmaInformationRecord.aidl (81%) rename radio/aidl/android/hardware/radio/{ => voice}/CdmaInformationRecords.aidl (89%) rename radio/aidl/android/hardware/radio/{ => voice}/CdmaLineControlInfoRecord.aidl (95%) rename radio/aidl/android/hardware/radio/{ => voice}/CdmaNumberInfoRecord.aidl (90%) rename radio/aidl/android/hardware/radio/{ => voice}/CdmaOtaProvisionStatus.aidl (96%) rename radio/aidl/android/hardware/radio/{ => voice}/CdmaRedirectingNumberInfoRecord.aidl (93%) rename radio/aidl/android/hardware/radio/{ => voice}/CdmaSignalInfoRecord.aidl (96%) rename radio/aidl/android/hardware/radio/{ => voice}/CdmaT53AudioControlInfoRecord.aidl (95%) rename radio/aidl/android/hardware/radio/{ => voice}/CdmaT53ClirInfoRecord.aidl (95%) rename radio/aidl/android/hardware/radio/{ => voice}/CfData.aidl (90%) rename radio/aidl/android/hardware/radio/{ => voice}/ClipStatus.aidl (95%) rename radio/aidl/android/hardware/radio/{ => voice}/Dial.aidl (92%) rename radio/aidl/android/hardware/radio/{ => voice}/EmergencyCallRouting.aidl (96%) rename radio/aidl/android/hardware/radio/{ => voice}/EmergencyNumber.aidl (97%) rename radio/aidl/android/hardware/radio/{ => voice}/EmergencyServiceCategory.aidl (97%) create mode 100644 radio/aidl/android/hardware/radio/voice/IRadioVoice.aidl create mode 100644 radio/aidl/android/hardware/radio/voice/IRadioVoiceIndication.aidl create mode 100644 radio/aidl/android/hardware/radio/voice/IRadioVoiceResponse.aidl rename radio/aidl/android/hardware/radio/{ => voice}/LastCallFailCause.aidl (99%) rename radio/aidl/android/hardware/radio/{ => voice}/LastCallFailCauseInfo.aidl (88%) rename radio/aidl/android/hardware/radio/{ => voice}/SrvccState.aidl (95%) rename radio/aidl/android/hardware/radio/{ => voice}/SsInfoData.aidl (86%) rename radio/aidl/android/hardware/radio/{ => voice}/StkCcUnsolSsResult.aidl (92%) rename radio/aidl/android/hardware/radio/{ => voice}/TtyMode.aidl (95%) rename radio/aidl/android/hardware/radio/{ => voice}/UusInfo.aidl (98%) diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index 920513b465..7fa586efdb 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -433,10 +433,60 @@ - android.hardware.radio + android.hardware.radio.data 1 - IRadio + IRadioData + slot1 + slot2 + slot3 + + + + android.hardware.radio.messaging + 1 + + IRadioMessaging + slot1 + slot2 + slot3 + + + + android.hardware.radio.modem + 1 + + IRadioModem + slot1 + slot2 + slot3 + + + + android.hardware.radio.network + 1 + + IRadioNetwork + slot1 + slot2 + slot3 + + + + android.hardware.radio.sim + 1 + + IRadioSim + slot1 + slot2 + slot3 + + + + android.hardware.radio.voice + 1 + + IRadioVoice slot1 slot2 slot3 diff --git a/compatibility_matrices/exclude/fcm_exclude.cpp b/compatibility_matrices/exclude/fcm_exclude.cpp index e67c892523..d8c9170000 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.fmq", "android.hardware.graphics.common", "android.hardware.keymaster", + "android.hardware.radio", // Fastboot HAL is only used by recovery. Recovery is owned by OEM. Framework // does not depend on this HAL, hence it is not declared in any manifests or matrices. diff --git a/radio/aidl/Android.bp b/radio/aidl/Android.bp index f2449f686f..2cf824f205 100644 --- a/radio/aidl/Android.bp +++ b/radio/aidl/Android.bp @@ -27,34 +27,128 @@ aidl_interface { }, } -cc_library { - name: "android.hardware.radio-translate-ndk", +aidl_interface { + name: "android.hardware.radio.data", + vendor_available: true, + srcs: ["android/hardware/radio/data/*.aidl"], + stability: "vintf", + imports: ["android.hardware.radio"], + backend: { + cpp: { + enabled: false, + }, + java: { + sdk_version: "module_current", + }, + ndk: { + vndk: { + enabled: true, + }, + }, + }, +} + +aidl_interface { + name: "android.hardware.radio.messaging", + vendor_available: true, + srcs: ["android/hardware/radio/messaging/*.aidl"], + stability: "vintf", + imports: ["android.hardware.radio"], + backend: { + cpp: { + enabled: false, + }, + java: { + sdk_version: "module_current", + }, + ndk: { + vndk: { + enabled: true, + }, + }, + }, +} + +aidl_interface { + name: "android.hardware.radio.modem", vendor_available: true, - shared_libs: [ - "libbinder_ndk", - "libhidlbase", - "android.hardware.radio-V1-ndk_platform", - "android.hardware.radio@1.0", - "android.hardware.radio@1.1", - "android.hardware.radio@1.2", - "android.hardware.radio@1.3", - "android.hardware.radio@1.4", - "android.hardware.radio@1.5", - "android.hardware.radio@1.6", - ], + srcs: ["android/hardware/radio/modem/*.aidl"], + stability: "vintf", + imports: ["android.hardware.radio"], + backend: { + cpp: { + enabled: false, + }, + java: { + sdk_version: "module_current", + }, + ndk: { + vndk: { + enabled: true, + }, + }, + }, } -java_library { - name: "android.hardware.radio-translate-java", - libs: [ - "android.hardware.radio-V1-java", - "android.hardware.radio-V1.0-java", - "android.hardware.radio-V1.1-java", - "android.hardware.radio-V1.2-java", - "android.hardware.radio-V1.3-java", - "android.hardware.radio-V1.4-java", - "android.hardware.radio-V1.5-java", - "android.hardware.radio-V1.6-java", - ], - sdk_version: "module_current", +aidl_interface { + name: "android.hardware.radio.network", + vendor_available: true, + srcs: ["android/hardware/radio/network/*.aidl"], + stability: "vintf", + imports: ["android.hardware.radio"], + backend: { + cpp: { + enabled: false, + }, + java: { + sdk_version: "module_current", + }, + ndk: { + vndk: { + enabled: true, + }, + }, + }, +} + +aidl_interface { + name: "android.hardware.radio.sim", + vendor_available: true, + srcs: ["android/hardware/radio/sim/*.aidl"], + stability: "vintf", + imports: ["android.hardware.radio"], + backend: { + cpp: { + enabled: false, + }, + java: { + sdk_version: "module_current", + }, + ndk: { + vndk: { + enabled: true, + }, + }, + }, +} + +aidl_interface { + name: "android.hardware.radio.voice", + vendor_available: true, + srcs: ["android/hardware/radio/voice/*.aidl"], + stability: "vintf", + imports: ["android.hardware.radio"], + backend: { + cpp: { + enabled: false, + }, + java: { + sdk_version: "module_current", + }, + ndk: { + vndk: { + enabled: true, + }, + }, + }, } diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ApnAuthType.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/ApnAuthType.aidl similarity index 98% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ApnAuthType.aidl rename to radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/ApnAuthType.aidl index bae7d1f261..929cfe3ccf 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ApnAuthType.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/ApnAuthType.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.data; @Backing(type="int") @VintfStability enum ApnAuthType { NO_PAP_NO_CHAP = 0, diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ApnTypes.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/ApnTypes.aidl similarity index 97% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ApnTypes.aidl rename to radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/ApnTypes.aidl index 0829fa619f..6982d404bd 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ApnTypes.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/ApnTypes.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.data; @Backing(type="int") @VintfStability enum ApnTypes { NONE = 0, @@ -45,7 +45,6 @@ enum ApnTypes { CBS = 128, IA = 256, EMERGENCY = 512, - ALL = 1023, MCX = 1024, XCAP = 2048, } diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/DataCallFailCause.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataCallFailCause.aidl similarity index 99% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/DataCallFailCause.aidl rename to radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataCallFailCause.aidl index df895f825c..6130e71a1a 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/DataCallFailCause.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataCallFailCause.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.data; @Backing(type="int") @VintfStability enum DataCallFailCause { NONE = 0, diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/DataProfileInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataProfileInfo.aidl similarity index 89% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/DataProfileInfo.aidl rename to radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataProfileInfo.aidl index b8bba274dd..cfcd42c632 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/DataProfileInfo.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataProfileInfo.aidl @@ -31,14 +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.radio; +package android.hardware.radio.data; @VintfStability parcelable DataProfileInfo { int profileId; String apn; - android.hardware.radio.PdpProtocolType protocol; - android.hardware.radio.PdpProtocolType roamingProtocol; - android.hardware.radio.ApnAuthType authType; + android.hardware.radio.data.PdpProtocolType protocol; + android.hardware.radio.data.PdpProtocolType roamingProtocol; + android.hardware.radio.data.ApnAuthType authType; String user; String password; int type; @@ -46,7 +46,7 @@ parcelable DataProfileInfo { int maxConns; int waitTime; boolean enabled; - android.hardware.radio.ApnTypes supportedApnTypesBitmap; + android.hardware.radio.data.ApnTypes supportedApnTypesBitmap; android.hardware.radio.RadioAccessFamily bearerBitmap; int mtuV4; int mtuV6; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/DataRequestReason.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataRequestReason.aidl similarity index 98% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/DataRequestReason.aidl rename to radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataRequestReason.aidl index 1dd0e08ca9..c94fa6f604 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/DataRequestReason.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataRequestReason.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.data; @Backing(type="int") @VintfStability enum DataRequestReason { NORMAL = 1, diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/DataThrottlingAction.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataThrottlingAction.aidl similarity index 98% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/DataThrottlingAction.aidl rename to radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataThrottlingAction.aidl index 70aaa0f4af..c0ade454dd 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/DataThrottlingAction.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataThrottlingAction.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.data; @Backing(type="byte") @VintfStability enum DataThrottlingAction { NO_DATA_THROTTLING = 0, diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/EpsQos.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/EpsQos.aidl similarity index 92% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/EpsQos.aidl rename to radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/EpsQos.aidl index 8eb3fdaa25..36367315d6 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/EpsQos.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/EpsQos.aidl @@ -31,10 +31,10 @@ // 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.radio; +package android.hardware.radio.data; @VintfStability parcelable EpsQos { int qci; - android.hardware.radio.QosBandwidth downlink; - android.hardware.radio.QosBandwidth uplink; + android.hardware.radio.data.QosBandwidth downlink; + android.hardware.radio.data.QosBandwidth uplink; } diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/IRadioData.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/IRadioData.aidl new file mode 100644 index 0000000000..a648675280 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/IRadioData.aidl @@ -0,0 +1,53 @@ +/* + * 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 -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.radio.data; +@VintfStability +interface IRadioData { + oneway void allocatePduSessionId(in int serial); + oneway void cancelHandover(in int serial, in int callId); + oneway void deactivateDataCall(in int serial, in int cid, in android.hardware.radio.data.DataRequestReason reason); + oneway void getDataCallList(in int serial); + oneway void getSlicingConfig(in int serial); + oneway void releasePduSessionId(in int serial, in int id); + oneway void responseAcknowledgement(); + oneway void setDataAllowed(in int serial, in boolean allow); + oneway void setDataProfile(in int serial, in android.hardware.radio.data.DataProfileInfo[] profiles); + oneway void setDataThrottling(in int serial, in android.hardware.radio.data.DataThrottlingAction dataThrottlingAction, in long completionDurationMillis); + oneway void setInitialAttachApn(in int serial, in android.hardware.radio.data.DataProfileInfo dataProfileInfo); + oneway void setResponseFunctions(in android.hardware.radio.data.IRadioDataResponse radioDataResponse, in android.hardware.radio.data.IRadioDataIndication radioDataIndication); + oneway void setupDataCall(in int serial, in android.hardware.radio.AccessNetwork accessNetwork, in android.hardware.radio.data.DataProfileInfo dataProfileInfo, in boolean roamingAllowed, in android.hardware.radio.data.DataRequestReason reason, in android.hardware.radio.data.LinkAddress[] addresses, in String[] dnses, in int pduSessionId, in @nullable android.hardware.radio.data.SliceInfo sliceInfo, in @nullable android.hardware.radio.data.TrafficDescriptor trafficDescriptor, in boolean matchAllRuleAllowed); + oneway void startHandover(in int serial, in int callId); + oneway void startKeepalive(in int serial, in android.hardware.radio.data.KeepaliveRequest keepalive); + oneway void stopKeepalive(in int serial, in int sessionHandle); +} 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 new file mode 100644 index 0000000000..e496c7be4e --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/IRadioDataIndication.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 -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.radio.data; +@VintfStability +interface IRadioDataIndication { + oneway void dataCallListChanged(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.data.SetupDataCallResult[] dcList); + 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 String apn); +} diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/IRadioDataResponse.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/IRadioDataResponse.aidl new file mode 100644 index 0000000000..4edc17d4ad --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/IRadioDataResponse.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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.radio.data; +@VintfStability +interface IRadioDataResponse { + oneway void acknowledgeRequest(in int serial); + oneway void allocatePduSessionIdResponse(in android.hardware.radio.RadioResponseInfo info, in int id); + oneway void cancelHandoverResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void deactivateDataCallResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void getDataCallListResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.data.SetupDataCallResult[] dcResponse); + oneway void getSlicingConfigResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.data.SlicingConfig slicingConfig); + oneway void releasePduSessionIdResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setDataAllowedResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setDataProfileResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setDataThrottlingResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setInitialAttachApnResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setupDataCallResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.data.SetupDataCallResult dcResponse); + oneway void startHandoverResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void startKeepaliveResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.data.KeepaliveStatus status); + oneway void stopKeepaliveResponse(in android.hardware.radio.RadioResponseInfo info); +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/KeepaliveRequest.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/KeepaliveRequest.aidl similarity index 98% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/KeepaliveRequest.aidl rename to radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/KeepaliveRequest.aidl index 1aeeb55e82..788adfbfde 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/KeepaliveRequest.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/KeepaliveRequest.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.data; @VintfStability parcelable KeepaliveRequest { int type; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/KeepaliveStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/KeepaliveStatus.aidl similarity index 98% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/KeepaliveStatus.aidl rename to radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/KeepaliveStatus.aidl index 3c7a73609f..4729b8e194 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/KeepaliveStatus.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/KeepaliveStatus.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.data; @VintfStability parcelable KeepaliveStatus { int sessionHandle; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LinkAddress.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/LinkAddress.aidl similarity index 98% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LinkAddress.aidl rename to radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/LinkAddress.aidl index bdeb9b8a3a..9aee44c4fc 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LinkAddress.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/LinkAddress.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.data; @VintfStability parcelable LinkAddress { String address; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NrQos.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/NrQos.aidl similarity index 92% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NrQos.aidl rename to radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/NrQos.aidl index a40dda8969..a8a169635e 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NrQos.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/NrQos.aidl @@ -31,12 +31,12 @@ // 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.radio; +package android.hardware.radio.data; @VintfStability parcelable NrQos { int fiveQi; - android.hardware.radio.QosBandwidth downlink; - android.hardware.radio.QosBandwidth uplink; + android.hardware.radio.data.QosBandwidth downlink; + android.hardware.radio.data.QosBandwidth uplink; byte qfi; char averagingWindowMs; const byte FLOW_ID_RANGE_MIN = 1; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/OsAppId.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/OsAppId.aidl similarity index 97% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/OsAppId.aidl rename to radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/OsAppId.aidl index bc112296e9..205b1e92bd 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/OsAppId.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/OsAppId.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.data; @VintfStability parcelable OsAppId { byte[] osAppId; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PcoDataInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/PcoDataInfo.aidl similarity index 98% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PcoDataInfo.aidl rename to radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/PcoDataInfo.aidl index 828b08c610..edfa7592df 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PcoDataInfo.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/PcoDataInfo.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.data; @VintfStability parcelable PcoDataInfo { int cid; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PdpProtocolType.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/PdpProtocolType.aidl similarity index 98% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PdpProtocolType.aidl rename to radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/PdpProtocolType.aidl index 980d3afc39..363cdf30b9 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PdpProtocolType.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/PdpProtocolType.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.data; @Backing(type="int") @VintfStability enum PdpProtocolType { UNKNOWN = -1, diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PortRange.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/PortRange.aidl similarity index 98% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PortRange.aidl rename to radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/PortRange.aidl index 8e02ff3d72..f3749ed7ac 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PortRange.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/PortRange.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.data; @VintfStability parcelable PortRange { int start; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/Qos.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/Qos.aidl similarity index 93% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/Qos.aidl rename to radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/Qos.aidl index d69853fa2b..1981721b5b 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/Qos.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/Qos.aidl @@ -31,10 +31,10 @@ // 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.radio; +package android.hardware.radio.data; @VintfStability union Qos { boolean noinit; - android.hardware.radio.EpsQos eps; - android.hardware.radio.NrQos nr; + android.hardware.radio.data.EpsQos eps; + android.hardware.radio.data.NrQos nr; } diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/QosBandwidth.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosBandwidth.aidl similarity index 97% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/QosBandwidth.aidl rename to radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosBandwidth.aidl index 95622bc31e..d7ebe100bd 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/QosBandwidth.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosBandwidth.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.data; @VintfStability parcelable QosBandwidth { int maxBitrateKbps; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/QosFilter.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilter.aidl similarity index 86% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/QosFilter.aidl rename to radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilter.aidl index a568506e90..b9098f7f88 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/QosFilter.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilter.aidl @@ -31,17 +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.radio; +package android.hardware.radio.data; @VintfStability parcelable QosFilter { String[] localAddresses; String[] remoteAddresses; - @nullable android.hardware.radio.PortRange localPort; - @nullable android.hardware.radio.PortRange remotePort; + @nullable android.hardware.radio.data.PortRange localPort; + @nullable android.hardware.radio.data.PortRange remotePort; byte protocol; - android.hardware.radio.QosFilterTypeOfService tos; - android.hardware.radio.QosFilterIpv6FlowLabel flowLabel; - android.hardware.radio.QosFilterIpsecSpi spi; + android.hardware.radio.data.QosFilterTypeOfService tos; + android.hardware.radio.data.QosFilterIpv6FlowLabel flowLabel; + android.hardware.radio.data.QosFilterIpsecSpi spi; byte direction; int precedence; const byte DIRECTION_DOWNLINK = 0; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/QosFilterIpsecSpi.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilterIpsecSpi.aidl similarity index 97% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/QosFilterIpsecSpi.aidl rename to radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilterIpsecSpi.aidl index 695b7352a2..565e49904e 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/QosFilterIpsecSpi.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilterIpsecSpi.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.data; @VintfStability union QosFilterIpsecSpi { boolean noinit; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/QosFilterIpv6FlowLabel.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilterIpv6FlowLabel.aidl similarity index 97% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/QosFilterIpv6FlowLabel.aidl rename to radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilterIpv6FlowLabel.aidl index 5b9c82c188..16117b252b 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/QosFilterIpv6FlowLabel.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilterIpv6FlowLabel.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.data; @VintfStability union QosFilterIpv6FlowLabel { boolean noinit; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/QosFilterTypeOfService.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilterTypeOfService.aidl similarity index 97% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/QosFilterTypeOfService.aidl rename to radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilterTypeOfService.aidl index c7c0331afc..95fda167f5 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/QosFilterTypeOfService.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilterTypeOfService.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.data; @VintfStability union QosFilterTypeOfService { boolean noinit; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/QosSession.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosSession.aidl similarity index 93% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/QosSession.aidl rename to radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosSession.aidl index 8f1b913fb2..53dcef0131 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/QosSession.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosSession.aidl @@ -31,10 +31,10 @@ // 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.radio; +package android.hardware.radio.data; @VintfStability parcelable QosSession { int qosSessionId; - android.hardware.radio.Qos qos; - android.hardware.radio.QosFilter[] qosFilters; + android.hardware.radio.data.Qos qos; + android.hardware.radio.data.QosFilter[] qosFilters; } diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RouteSelectionDescriptor.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/RouteSelectionDescriptor.aidl similarity index 92% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RouteSelectionDescriptor.aidl rename to radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/RouteSelectionDescriptor.aidl index 233b8b5c0a..02596a1f63 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RouteSelectionDescriptor.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/RouteSelectionDescriptor.aidl @@ -31,13 +31,13 @@ // 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.radio; +package android.hardware.radio.data; @VintfStability parcelable RouteSelectionDescriptor { byte precedence; - android.hardware.radio.PdpProtocolType sessionType; + android.hardware.radio.data.PdpProtocolType sessionType; byte sscMode; - android.hardware.radio.SliceInfo[] sliceInfo; + android.hardware.radio.data.SliceInfo[] sliceInfo; String[] dnn; const byte SSC_MODE_UNKNOWN = -1; const byte SSC_MODE_1 = 1; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SetupDataCallResult.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/SetupDataCallResult.aidl similarity index 84% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SetupDataCallResult.aidl rename to radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/SetupDataCallResult.aidl index edf7a8a012..ff2459c0b2 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SetupDataCallResult.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/SetupDataCallResult.aidl @@ -31,27 +31,27 @@ // 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.radio; +package android.hardware.radio.data; @VintfStability parcelable SetupDataCallResult { - android.hardware.radio.DataCallFailCause cause; + android.hardware.radio.data.DataCallFailCause cause; long suggestedRetryTime; int cid; int active; - android.hardware.radio.PdpProtocolType type; + android.hardware.radio.data.PdpProtocolType type; String ifname; - android.hardware.radio.LinkAddress[] addresses; + android.hardware.radio.data.LinkAddress[] addresses; String[] dnses; String[] gateways; String[] pcscf; int mtuV4; int mtuV6; - android.hardware.radio.Qos defaultQos; - android.hardware.radio.QosSession[] qosSessions; + android.hardware.radio.data.Qos defaultQos; + android.hardware.radio.data.QosSession[] qosSessions; byte handoverFailureMode; int pduSessionId; - @nullable android.hardware.radio.SliceInfo sliceInfo; - android.hardware.radio.TrafficDescriptor[] trafficDescriptors; + @nullable android.hardware.radio.data.SliceInfo sliceInfo; + android.hardware.radio.data.TrafficDescriptor[] trafficDescriptors; const int DATA_CONNECTION_STATUS_INACTIVE = 0; const int DATA_CONNECTION_STATUS_DORMANT = 1; const int DATA_CONNECTION_STATUS_ACTIVE = 2; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SliceInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/SliceInfo.aidl similarity index 98% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SliceInfo.aidl rename to radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/SliceInfo.aidl index f49ff3b82b..0febcd1ea3 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SliceInfo.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/SliceInfo.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.data; @VintfStability parcelable SliceInfo { byte sliceServiceType; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SlicingConfig.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/SlicingConfig.aidl similarity index 92% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SlicingConfig.aidl rename to radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/SlicingConfig.aidl index 9d3633836c..54e2f12171 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SlicingConfig.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/SlicingConfig.aidl @@ -31,9 +31,9 @@ // 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.radio; +package android.hardware.radio.data; @VintfStability parcelable SlicingConfig { - android.hardware.radio.UrspRule[] urspRules; - android.hardware.radio.SliceInfo[] sliceInfo; + android.hardware.radio.data.UrspRule[] urspRules; + android.hardware.radio.data.SliceInfo[] sliceInfo; } diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/TrafficDescriptor.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/TrafficDescriptor.aidl similarity index 94% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/TrafficDescriptor.aidl rename to radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/TrafficDescriptor.aidl index 7dabe99a7c..d5079c1d76 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/TrafficDescriptor.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/TrafficDescriptor.aidl @@ -31,9 +31,9 @@ // 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.radio; +package android.hardware.radio.data; @VintfStability parcelable TrafficDescriptor { @nullable String dnn; - @nullable android.hardware.radio.OsAppId osAppId; + @nullable android.hardware.radio.data.OsAppId osAppId; } diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/UrspRule.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/UrspRule.aidl similarity index 90% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/UrspRule.aidl rename to radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/UrspRule.aidl index 30c851c7f3..c0be05426c 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/UrspRule.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/UrspRule.aidl @@ -31,10 +31,10 @@ // 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.radio; +package android.hardware.radio.data; @VintfStability parcelable UrspRule { int precedence; - android.hardware.radio.TrafficDescriptor[] trafficDescriptors; - android.hardware.radio.RouteSelectionDescriptor[] routeSelectionDescriptor; + android.hardware.radio.data.TrafficDescriptor[] trafficDescriptors; + android.hardware.radio.data.RouteSelectionDescriptor[] routeSelectionDescriptor; } diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaBroadcastSmsConfigInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaBroadcastSmsConfigInfo.aidl similarity index 97% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaBroadcastSmsConfigInfo.aidl rename to radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaBroadcastSmsConfigInfo.aidl index 73c7faeeab..54e8a7b051 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaBroadcastSmsConfigInfo.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaBroadcastSmsConfigInfo.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.messaging; @VintfStability parcelable CdmaBroadcastSmsConfigInfo { int serviceCategory; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSmsAck.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsAck.aidl similarity index 97% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSmsAck.aidl rename to radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsAck.aidl index 8dfa1da348..0de1688f98 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSmsAck.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsAck.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.messaging; @VintfStability parcelable CdmaSmsAck { boolean errorClass; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSmsAddress.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsAddress.aidl similarity index 98% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSmsAddress.aidl rename to radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsAddress.aidl index a24c701468..4a55745724 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSmsAddress.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsAddress.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.messaging; @VintfStability parcelable CdmaSmsAddress { int digitMode; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSmsMessage.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsMessage.aidl similarity index 91% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSmsMessage.aidl rename to radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsMessage.aidl index c419bada63..fdb74fb49b 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSmsMessage.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsMessage.aidl @@ -31,13 +31,13 @@ // 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.radio; +package android.hardware.radio.messaging; @VintfStability parcelable CdmaSmsMessage { int teleserviceId; boolean isServicePresent; int serviceCategory; - android.hardware.radio.CdmaSmsAddress address; - android.hardware.radio.CdmaSmsSubaddress subAddress; + android.hardware.radio.messaging.CdmaSmsAddress address; + android.hardware.radio.messaging.CdmaSmsSubaddress subAddress; byte[] bearerData; } diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSmsSubaddress.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsSubaddress.aidl similarity index 97% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSmsSubaddress.aidl rename to radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsSubaddress.aidl index 0cf3e58c46..deb1102f0d 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSmsSubaddress.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsSubaddress.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.messaging; @VintfStability parcelable CdmaSmsSubaddress { int subaddressType; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSmsWriteArgs.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsWriteArgs.aidl similarity index 94% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSmsWriteArgs.aidl rename to radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsWriteArgs.aidl index e2fd8fdc1a..4969663834 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSmsWriteArgs.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsWriteArgs.aidl @@ -31,11 +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.radio; +package android.hardware.radio.messaging; @VintfStability parcelable CdmaSmsWriteArgs { int status; - android.hardware.radio.CdmaSmsMessage message; + android.hardware.radio.messaging.CdmaSmsMessage message; const int STATUS_REC_UNREAD = 0; const int STATUS_REC_READ = 1; const int STATUS_STO_UNSENT = 2; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/GsmBroadcastSmsConfigInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/GsmBroadcastSmsConfigInfo.aidl similarity index 97% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/GsmBroadcastSmsConfigInfo.aidl rename to radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/GsmBroadcastSmsConfigInfo.aidl index e74845e250..6cc7636f79 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/GsmBroadcastSmsConfigInfo.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/GsmBroadcastSmsConfigInfo.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.messaging; @VintfStability parcelable GsmBroadcastSmsConfigInfo { int fromServiceId; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/GsmSmsMessage.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/GsmSmsMessage.aidl similarity index 97% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/GsmSmsMessage.aidl rename to radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/GsmSmsMessage.aidl index 1b00b0f099..2937d5ca79 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/GsmSmsMessage.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/GsmSmsMessage.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.messaging; @VintfStability parcelable GsmSmsMessage { String smscPdu; diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/IRadioMessaging.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/IRadioMessaging.aidl new file mode 100644 index 0000000000..b0fc349ab8 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/IRadioMessaging.aidl @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.radio.messaging; +@VintfStability +interface IRadioMessaging { + oneway void acknowledgeIncomingGsmSmsWithPdu(in int serial, in boolean success, in String ackPdu); + oneway void acknowledgeLastIncomingCdmaSms(in int serial, in android.hardware.radio.messaging.CdmaSmsAck smsAck); + oneway void acknowledgeLastIncomingGsmSms(in int serial, in boolean success, in android.hardware.radio.messaging.SmsAcknowledgeFailCause cause); + oneway void cancelPendingUssd(in int serial); + oneway void deleteSmsOnRuim(in int serial, in int index); + oneway void deleteSmsOnSim(in int serial, in int index); + oneway void getCdmaBroadcastConfig(in int serial); + oneway void getGsmBroadcastConfig(in int serial); + oneway void getSmscAddress(in int serial); + oneway void reportSmsMemoryStatus(in int serial, in boolean available); + oneway void responseAcknowledgement(); + oneway void sendCdmaSms(in int serial, in android.hardware.radio.messaging.CdmaSmsMessage sms); + oneway void sendCdmaSmsExpectMore(in int serial, in android.hardware.radio.messaging.CdmaSmsMessage sms); + oneway void sendImsSms(in int serial, in android.hardware.radio.messaging.ImsSmsMessage message); + oneway void sendSms(in int serial, in android.hardware.radio.messaging.GsmSmsMessage message); + oneway void sendSmsExpectMore(in int serial, in android.hardware.radio.messaging.GsmSmsMessage message); + oneway void sendUssd(in int serial, in String ussd); + oneway void setCdmaBroadcastActivation(in int serial, in boolean activate); + oneway void setCdmaBroadcastConfig(in int serial, in android.hardware.radio.messaging.CdmaBroadcastSmsConfigInfo[] configInfo); + oneway void setGsmBroadcastActivation(in int serial, in boolean activate); + oneway void setGsmBroadcastConfig(in int serial, in android.hardware.radio.messaging.GsmBroadcastSmsConfigInfo[] configInfo); + oneway void setResponseFunctions(in android.hardware.radio.messaging.IRadioMessagingResponse radioMessagingResponse, in android.hardware.radio.messaging.IRadioMessagingIndication radioMessagingIndication); + oneway void setSmscAddress(in int serial, in String smsc); + oneway void writeSmsToRuim(in int serial, in android.hardware.radio.messaging.CdmaSmsWriteArgs cdmaSms); + oneway void writeSmsToSim(in int serial, in android.hardware.radio.messaging.SmsWriteArgs smsWriteArgs); +} diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/IRadioMessagingIndication.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/IRadioMessagingIndication.aidl new file mode 100644 index 0000000000..89a0f3b656 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/IRadioMessagingIndication.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 -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.radio.messaging; +@VintfStability +interface IRadioMessagingIndication { + oneway void cdmaNewSms(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.messaging.CdmaSmsMessage msg); + oneway void cdmaRuimSmsStorageFull(in android.hardware.radio.RadioIndicationType type); + oneway void newBroadcastSms(in android.hardware.radio.RadioIndicationType type, in byte[] data); + oneway void newSms(in android.hardware.radio.RadioIndicationType type, in byte[] pdu); + oneway void newSmsOnSim(in android.hardware.radio.RadioIndicationType type, in int recordNumber); + oneway void newSmsStatusReport(in android.hardware.radio.RadioIndicationType type, in byte[] pdu); + oneway void onUssd(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.messaging.UssdModeType modeType, in String msg); + oneway void simSmsStorageFull(in android.hardware.radio.RadioIndicationType type); +} diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/IRadioMessagingResponse.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/IRadioMessagingResponse.aidl new file mode 100644 index 0000000000..156f24b653 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/IRadioMessagingResponse.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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.radio.messaging; +@VintfStability +interface IRadioMessagingResponse { + oneway void acknowledgeIncomingGsmSmsWithPduResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void acknowledgeLastIncomingCdmaSmsResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void acknowledgeLastIncomingGsmSmsResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void acknowledgeRequest(in int serial); + oneway void cancelPendingUssdResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void deleteSmsOnRuimResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void deleteSmsOnSimResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void getCdmaBroadcastConfigResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.messaging.CdmaBroadcastSmsConfigInfo[] configs); + oneway void getGsmBroadcastConfigResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.messaging.GsmBroadcastSmsConfigInfo[] configs); + oneway void getSmscAddressResponse(in android.hardware.radio.RadioResponseInfo info, in String smsc); + oneway void reportSmsMemoryStatusResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void sendCdmaSmsExpectMoreResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.messaging.SendSmsResult sms); + oneway void sendCdmaSmsResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.messaging.SendSmsResult sms); + oneway void sendImsSmsResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.messaging.SendSmsResult sms); + oneway void sendSmsExpectMoreResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.messaging.SendSmsResult sms); + oneway void sendSmsResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.messaging.SendSmsResult sms); + oneway void sendUssdResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setCdmaBroadcastActivationResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setCdmaBroadcastConfigResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setGsmBroadcastActivationResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setGsmBroadcastConfigResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setSmscAddressResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void writeSmsToRuimResponse(in android.hardware.radio.RadioResponseInfo info, in int index); + oneway void writeSmsToSimResponse(in android.hardware.radio.RadioResponseInfo info, in int index); +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ImsSmsMessage.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/ImsSmsMessage.aidl similarity index 91% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ImsSmsMessage.aidl rename to radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/ImsSmsMessage.aidl index b5ffcc6474..706bfddd49 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ImsSmsMessage.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/ImsSmsMessage.aidl @@ -31,12 +31,12 @@ // 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.radio; +package android.hardware.radio.messaging; @VintfStability parcelable ImsSmsMessage { android.hardware.radio.RadioTechnologyFamily tech; boolean retry; int messageRef; - android.hardware.radio.CdmaSmsMessage[] cdmaMessage; - android.hardware.radio.GsmSmsMessage[] gsmMessage; + android.hardware.radio.messaging.CdmaSmsMessage[] cdmaMessage; + android.hardware.radio.messaging.GsmSmsMessage[] gsmMessage; } diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SendSmsResult.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/SendSmsResult.aidl similarity index 97% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SendSmsResult.aidl rename to radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/SendSmsResult.aidl index 7063db5a3a..0fbec6fed1 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SendSmsResult.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/SendSmsResult.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.messaging; @VintfStability parcelable SendSmsResult { int messageRef; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SmsAcknowledgeFailCause.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/SmsAcknowledgeFailCause.aidl similarity index 97% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SmsAcknowledgeFailCause.aidl rename to radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/SmsAcknowledgeFailCause.aidl index c5b13b934a..b1f8ff8583 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SmsAcknowledgeFailCause.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/SmsAcknowledgeFailCause.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.messaging; @Backing(type="int") @VintfStability enum SmsAcknowledgeFailCause { MEMORY_CAPACITY_EXCEEDED = 211, diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SmsWriteArgs.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/SmsWriteArgs.aidl similarity index 97% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SmsWriteArgs.aidl rename to radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/SmsWriteArgs.aidl index a42339dc45..1748b62cfc 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SmsWriteArgs.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/SmsWriteArgs.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.messaging; @VintfStability parcelable SmsWriteArgs { int status; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/UssdModeType.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/UssdModeType.aidl similarity index 97% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/UssdModeType.aidl rename to radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/UssdModeType.aidl index 992a55f5d0..5395b11781 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/UssdModeType.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/UssdModeType.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.messaging; @Backing(type="int") @VintfStability enum UssdModeType { NOTIFY = 0, diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ActivityStatsInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ActivityStatsInfo.aidl similarity index 97% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ActivityStatsInfo.aidl rename to radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ActivityStatsInfo.aidl index f9ef742549..2da0167c61 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ActivityStatsInfo.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ActivityStatsInfo.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.modem; @VintfStability parcelable ActivityStatsInfo { int sleepModeTimeMs; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/DeviceStateType.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/DeviceStateType.aidl similarity index 97% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/DeviceStateType.aidl rename to radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/DeviceStateType.aidl index 2d3cea8bba..0f0006d3e4 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/DeviceStateType.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/DeviceStateType.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.modem; @Backing(type="int") @VintfStability enum DeviceStateType { POWER_SAVE_MODE = 0, diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/HardwareConfig.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/HardwareConfig.aidl similarity index 92% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/HardwareConfig.aidl rename to radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/HardwareConfig.aidl index 60ab5112fa..7593ca7a03 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/HardwareConfig.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/HardwareConfig.aidl @@ -31,14 +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.radio; +package android.hardware.radio.modem; @VintfStability parcelable HardwareConfig { int type; String uuid; int state; - android.hardware.radio.HardwareConfigModem[] modem; - android.hardware.radio.HardwareConfigSim[] sim; + android.hardware.radio.modem.HardwareConfigModem[] modem; + android.hardware.radio.modem.HardwareConfigSim[] sim; const int STATE_ENABLED = 0; const int STATE_STANDBY = 1; const int STATE_DISABLED = 2; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/HardwareConfigModem.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/HardwareConfigModem.aidl similarity index 93% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/HardwareConfigModem.aidl rename to radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/HardwareConfigModem.aidl index 08e12e6f25..bf7099541c 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/HardwareConfigModem.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/HardwareConfigModem.aidl @@ -31,12 +31,12 @@ // 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.radio; +package android.hardware.radio.modem; @VintfStability parcelable HardwareConfigModem { int rilModel; - int rat; - int maxVoice; - int maxData; + android.hardware.radio.RadioTechnology rat; + int maxVoiceCalls; + int maxDataCalls; int maxStandby; } diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/HardwareConfigSim.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/HardwareConfigSim.aidl similarity index 97% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/HardwareConfigSim.aidl rename to radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/HardwareConfigSim.aidl index 8df23b4bcc..1b887c220e 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/HardwareConfigSim.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/HardwareConfigSim.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.modem; @VintfStability parcelable HardwareConfigSim { String modemUuid; diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/IRadioModem.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/IRadioModem.aidl new file mode 100644 index 0000000000..41eff51773 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/IRadioModem.aidl @@ -0,0 +1,54 @@ +/* + * 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 -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.radio.modem; +@VintfStability +interface IRadioModem { + oneway void enableModem(in int serial, in boolean on); + oneway void getBasebandVersion(in int serial); + oneway void getDeviceIdentity(in int serial); + oneway void getHardwareConfig(in int serial); + oneway void getModemActivityInfo(in int serial); + oneway void getModemStackStatus(in int serial); + oneway void getRadioCapability(in int serial); + oneway void nvReadItem(in int serial, in android.hardware.radio.modem.NvItem itemId); + oneway void nvResetConfig(in int serial, in android.hardware.radio.modem.ResetNvType resetType); + oneway void nvWriteCdmaPrl(in int serial, in byte[] prl); + oneway void nvWriteItem(in int serial, in android.hardware.radio.modem.NvWriteItem item); + oneway void requestShutdown(in int serial); + oneway void responseAcknowledgement(); + oneway void sendDeviceState(in int serial, in android.hardware.radio.modem.DeviceStateType deviceStateType, in boolean state); + oneway void setRadioCapability(in int serial, in android.hardware.radio.modem.RadioCapability rc); + oneway void setRadioPower(in int serial, in boolean powerOn, in boolean forEmergencyCall, in boolean preferredForEmergencyCall); + oneway void setResponseFunctions(in android.hardware.radio.modem.IRadioModemResponse radioModemResponse, in android.hardware.radio.modem.IRadioModemIndication radioModemIndication); +} diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/IRadioModemIndication.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/IRadioModemIndication.aidl new file mode 100644 index 0000000000..514ff9a03e --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/IRadioModemIndication.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 -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.radio.modem; +@VintfStability +interface IRadioModemIndication { + oneway void hardwareConfigChanged(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.modem.HardwareConfig[] configs); + oneway void modemReset(in android.hardware.radio.RadioIndicationType type, in String reason); + oneway void radioCapabilityIndication(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.modem.RadioCapability rc); + oneway void radioStateChanged(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.modem.RadioState radioState); + oneway void rilConnected(in android.hardware.radio.RadioIndicationType type); +} diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/IRadioModemResponse.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/IRadioModemResponse.aidl new file mode 100644 index 0000000000..dcaff45017 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/IRadioModemResponse.aidl @@ -0,0 +1,53 @@ +/* + * 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 -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.radio.modem; +@VintfStability +interface IRadioModemResponse { + oneway void acknowledgeRequest(in int serial); + oneway void enableModemResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void getBasebandVersionResponse(in android.hardware.radio.RadioResponseInfo info, in String version); + oneway void getDeviceIdentityResponse(in android.hardware.radio.RadioResponseInfo info, in String imei, in String imeisv, in String esn, in String meid); + oneway void getHardwareConfigResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.modem.HardwareConfig[] config); + oneway void getModemActivityInfoResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.modem.ActivityStatsInfo activityInfo); + oneway void getModemStackStatusResponse(in android.hardware.radio.RadioResponseInfo info, in boolean isEnabled); + oneway void getRadioCapabilityResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.modem.RadioCapability rc); + oneway void nvReadItemResponse(in android.hardware.radio.RadioResponseInfo info, in String result); + oneway void nvResetConfigResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void nvWriteCdmaPrlResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void nvWriteItemResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void requestShutdownResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void sendDeviceStateResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setRadioCapabilityResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.modem.RadioCapability rc); + oneway void setRadioPowerResponse(in android.hardware.radio.RadioResponseInfo info); +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NvItem.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/NvItem.aidl similarity index 98% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NvItem.aidl rename to radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/NvItem.aidl index d7706c5dc2..bda4ab7884 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NvItem.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/NvItem.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.modem; @Backing(type="int") @VintfStability enum NvItem { CDMA_MEID = 1, diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NvWriteItem.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/NvWriteItem.aidl similarity index 95% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NvWriteItem.aidl rename to radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/NvWriteItem.aidl index 9e60db6a28..58e84988e8 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NvWriteItem.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/NvWriteItem.aidl @@ -31,9 +31,9 @@ // 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.radio; +package android.hardware.radio.modem; @VintfStability parcelable NvWriteItem { - android.hardware.radio.NvItem itemId; + android.hardware.radio.modem.NvItem itemId; String value; } diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioCapability.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/RadioCapability.aidl similarity index 98% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioCapability.aidl rename to radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/RadioCapability.aidl index ca1e389a11..d5716acf40 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioCapability.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/RadioCapability.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.modem; @VintfStability parcelable RadioCapability { int session; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioState.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/RadioState.aidl similarity index 97% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioState.aidl rename to radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/RadioState.aidl index 3dad483679..4bde770e15 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioState.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/RadioState.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.modem; @Backing(type="int") @VintfStability enum RadioState { OFF = 0, diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ResetNvType.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ResetNvType.aidl similarity index 97% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ResetNvType.aidl rename to radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ResetNvType.aidl index 3852a7719e..81f225433f 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ResetNvType.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ResetNvType.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.modem; @Backing(type="int") @VintfStability enum ResetNvType { RELOAD = 0, diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/AccessTechnologySpecificInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/AccessTechnologySpecificInfo.aidl similarity index 88% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/AccessTechnologySpecificInfo.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/AccessTechnologySpecificInfo.aidl index 988f118d43..4a4a120965 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/AccessTechnologySpecificInfo.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/AccessTechnologySpecificInfo.aidl @@ -31,12 +31,12 @@ // 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.radio; +package android.hardware.radio.network; @VintfStability union AccessTechnologySpecificInfo { boolean noinit; - android.hardware.radio.Cdma2000RegistrationInfo cdmaInfo; - android.hardware.radio.EutranRegistrationInfo eutranInfo; - android.hardware.radio.NrVopsInfo ngranNrVopsInfo; + android.hardware.radio.network.Cdma2000RegistrationInfo cdmaInfo; + android.hardware.radio.network.EutranRegistrationInfo eutranInfo; + android.hardware.radio.network.NrVopsInfo ngranNrVopsInfo; boolean geranDtmSupported; } diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/BarringInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/BarringInfo.aidl similarity index 96% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/BarringInfo.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/BarringInfo.aidl index 1623764df1..a96ef510c4 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/BarringInfo.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/BarringInfo.aidl @@ -31,12 +31,12 @@ // 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.radio; +package android.hardware.radio.network; @VintfStability parcelable BarringInfo { int serviceType; int barringType; - @nullable android.hardware.radio.BarringTypeSpecificInfo barringTypeSpecificInfo; + @nullable android.hardware.radio.network.BarringTypeSpecificInfo barringTypeSpecificInfo; const int BARRING_TYPE_NONE = 0; const int BARRING_TYPE_CONDITIONAL = 1; const int BARRING_TYPE_UNCONDITIONAL = 2; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/BarringTypeSpecificInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/BarringTypeSpecificInfo.aidl similarity index 97% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/BarringTypeSpecificInfo.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/BarringTypeSpecificInfo.aidl index 98b46c99e3..c04cdb54bc 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/BarringTypeSpecificInfo.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/BarringTypeSpecificInfo.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.network; @VintfStability parcelable BarringTypeSpecificInfo { int factor; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/Cdma2000RegistrationInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/Cdma2000RegistrationInfo.aidl similarity index 98% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/Cdma2000RegistrationInfo.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/Cdma2000RegistrationInfo.aidl index 6e4d7b63f8..7d9292d9b3 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/Cdma2000RegistrationInfo.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/Cdma2000RegistrationInfo.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.network; @VintfStability parcelable Cdma2000RegistrationInfo { boolean cssSupported; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaRoamingType.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CdmaRoamingType.aidl similarity index 97% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaRoamingType.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CdmaRoamingType.aidl index 09a59a0c35..54c431b015 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaRoamingType.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CdmaRoamingType.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.network; @Backing(type="int") @VintfStability enum CdmaRoamingType { HOME_NETWORK = 0, diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSignalStrength.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CdmaSignalStrength.aidl similarity index 97% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSignalStrength.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CdmaSignalStrength.aidl index 29391838f4..b4aee1cdd2 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSignalStrength.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CdmaSignalStrength.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.network; @VintfStability parcelable CdmaSignalStrength { int dbm; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellConnectionStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellConnectionStatus.aidl similarity index 97% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellConnectionStatus.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellConnectionStatus.aidl index 96f8368a7a..066cb60594 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellConnectionStatus.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellConnectionStatus.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.network; @Backing(type="int") @VintfStability enum CellConnectionStatus { NONE = 0, diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellIdentity.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentity.aidl similarity index 82% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellIdentity.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentity.aidl index aa37fdfa71..1c68e8c817 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellIdentity.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentity.aidl @@ -31,14 +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.radio; +package android.hardware.radio.network; @VintfStability union CellIdentity { boolean noinit; - android.hardware.radio.CellIdentityGsm gsm; - android.hardware.radio.CellIdentityWcdma wcdma; - android.hardware.radio.CellIdentityTdscdma tdscdma; - android.hardware.radio.CellIdentityCdma cdma; - android.hardware.radio.CellIdentityLte lte; - android.hardware.radio.CellIdentityNr nr; + android.hardware.radio.network.CellIdentityGsm gsm; + android.hardware.radio.network.CellIdentityWcdma wcdma; + android.hardware.radio.network.CellIdentityTdscdma tdscdma; + android.hardware.radio.network.CellIdentityCdma cdma; + android.hardware.radio.network.CellIdentityLte lte; + android.hardware.radio.network.CellIdentityNr nr; } diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellIdentityCdma.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityCdma.aidl similarity index 94% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellIdentityCdma.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityCdma.aidl index d24b91d213..7dd1341666 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellIdentityCdma.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityCdma.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.network; @VintfStability parcelable CellIdentityCdma { int networkId; @@ -39,5 +39,5 @@ parcelable CellIdentityCdma { int baseStationId; int longitude; int latitude; - android.hardware.radio.CellIdentityOperatorNames operatorNames; + android.hardware.radio.network.CellIdentityOperatorNames operatorNames; } diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellIdentityGsm.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityGsm.aidl similarity index 94% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellIdentityGsm.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityGsm.aidl index 4ee2148798..3991af7692 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellIdentityGsm.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityGsm.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.network; @VintfStability parcelable CellIdentityGsm { String mcc; @@ -40,6 +40,6 @@ parcelable CellIdentityGsm { int cid; int arfcn; byte bsic; - android.hardware.radio.CellIdentityOperatorNames operatorNames; + android.hardware.radio.network.CellIdentityOperatorNames operatorNames; String[] additionalPlmns; } diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellIdentityLte.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityLte.aidl similarity index 88% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellIdentityLte.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityLte.aidl index 4f7c90b6a4..9ea0974f07 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellIdentityLte.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityLte.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.network; @VintfStability parcelable CellIdentityLte { String mcc; @@ -40,9 +40,9 @@ parcelable CellIdentityLte { int pci; int tac; int earfcn; - android.hardware.radio.CellIdentityOperatorNames operatorNames; + android.hardware.radio.network.CellIdentityOperatorNames operatorNames; int bandwidth; String[] additionalPlmns; - @nullable android.hardware.radio.ClosedSubscriberGroupInfo csgInfo; - android.hardware.radio.EutranBands[] bands; + @nullable android.hardware.radio.network.ClosedSubscriberGroupInfo csgInfo; + android.hardware.radio.network.EutranBands[] bands; } diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellIdentityNr.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityNr.aidl similarity index 91% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellIdentityNr.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityNr.aidl index 60a24d7e38..865e0dd884 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellIdentityNr.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityNr.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.network; @VintfStability parcelable CellIdentityNr { String mcc; @@ -40,7 +40,7 @@ parcelable CellIdentityNr { int pci; int tac; int nrarfcn; - android.hardware.radio.CellIdentityOperatorNames operatorNames; + android.hardware.radio.network.CellIdentityOperatorNames operatorNames; String[] additionalPlmns; - android.hardware.radio.NgranBands[] bands; + android.hardware.radio.network.NgranBands[] bands; } diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellIdentityOperatorNames.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityOperatorNames.aidl similarity index 97% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellIdentityOperatorNames.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityOperatorNames.aidl index 161797f3f8..a03f5195d6 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellIdentityOperatorNames.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityOperatorNames.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.network; @VintfStability parcelable CellIdentityOperatorNames { String alphaLong; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellIdentityTdscdma.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityTdscdma.aidl similarity index 90% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellIdentityTdscdma.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityTdscdma.aidl index 7cc13b54a9..836b5b5c8a 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellIdentityTdscdma.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityTdscdma.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.network; @VintfStability parcelable CellIdentityTdscdma { String mcc; @@ -40,7 +40,7 @@ parcelable CellIdentityTdscdma { int cid; int cpid; int uarfcn; - android.hardware.radio.CellIdentityOperatorNames operatorNames; + android.hardware.radio.network.CellIdentityOperatorNames operatorNames; String[] additionalPlmns; - @nullable android.hardware.radio.ClosedSubscriberGroupInfo csgInfo; + @nullable android.hardware.radio.network.ClosedSubscriberGroupInfo csgInfo; } diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellIdentityWcdma.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityWcdma.aidl similarity index 90% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellIdentityWcdma.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityWcdma.aidl index c43a8ad601..f832449a51 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellIdentityWcdma.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityWcdma.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.network; @VintfStability parcelable CellIdentityWcdma { String mcc; @@ -40,7 +40,7 @@ parcelable CellIdentityWcdma { int cid; int psc; int uarfcn; - android.hardware.radio.CellIdentityOperatorNames operatorNames; + android.hardware.radio.network.CellIdentityOperatorNames operatorNames; String[] additionalPlmns; - @nullable android.hardware.radio.ClosedSubscriberGroupInfo csgInfo; + @nullable android.hardware.radio.network.ClosedSubscriberGroupInfo csgInfo; } diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfo.aidl similarity index 90% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfo.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfo.aidl index 20ea3cb18a..38e0a44e95 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfo.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfo.aidl @@ -31,10 +31,10 @@ // 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.radio; +package android.hardware.radio.network; @VintfStability parcelable CellInfo { boolean registered; - android.hardware.radio.CellConnectionStatus connectionStatus; - android.hardware.radio.CellInfoCellInfoRatSpecificInfo ratSpecificInfo; + android.hardware.radio.network.CellConnectionStatus connectionStatus; + android.hardware.radio.network.CellInfoRatSpecificInfo ratSpecificInfo; } diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoCdma.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoCdma.aidl similarity index 87% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoCdma.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoCdma.aidl index dd940c2fa7..d171a4b7df 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoCdma.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoCdma.aidl @@ -31,10 +31,10 @@ // 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.radio; +package android.hardware.radio.network; @VintfStability parcelable CellInfoCdma { - android.hardware.radio.CellIdentityCdma cellIdentityCdma; - android.hardware.radio.CdmaSignalStrength signalStrengthCdma; - android.hardware.radio.EvdoSignalStrength signalStrengthEvdo; + android.hardware.radio.network.CellIdentityCdma cellIdentityCdma; + android.hardware.radio.network.CdmaSignalStrength signalStrengthCdma; + android.hardware.radio.network.EvdoSignalStrength signalStrengthEvdo; } diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoGsm.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoGsm.aidl similarity index 90% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoGsm.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoGsm.aidl index fda976c6b3..491b6868ec 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoGsm.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoGsm.aidl @@ -31,9 +31,9 @@ // 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.radio; +package android.hardware.radio.network; @VintfStability parcelable CellInfoGsm { - android.hardware.radio.CellIdentityGsm cellIdentityGsm; - android.hardware.radio.GsmSignalStrength signalStrengthGsm; + android.hardware.radio.network.CellIdentityGsm cellIdentityGsm; + android.hardware.radio.network.GsmSignalStrength signalStrengthGsm; } diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoLte.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoLte.aidl similarity index 90% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoLte.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoLte.aidl index 9976feb52a..67c5a18b22 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoLte.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoLte.aidl @@ -31,9 +31,9 @@ // 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.radio; +package android.hardware.radio.network; @VintfStability parcelable CellInfoLte { - android.hardware.radio.CellIdentityLte cellIdentityLte; - android.hardware.radio.LteSignalStrength signalStrengthLte; + android.hardware.radio.network.CellIdentityLte cellIdentityLte; + android.hardware.radio.network.LteSignalStrength signalStrengthLte; } diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoNr.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoNr.aidl similarity index 91% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoNr.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoNr.aidl index 7883692b55..a094600b6b 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoNr.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoNr.aidl @@ -31,9 +31,9 @@ // 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.radio; +package android.hardware.radio.network; @VintfStability parcelable CellInfoNr { - android.hardware.radio.CellIdentityNr cellIdentityNr; - android.hardware.radio.NrSignalStrength signalStrengthNr; + android.hardware.radio.network.CellIdentityNr cellIdentityNr; + android.hardware.radio.network.NrSignalStrength signalStrengthNr; } diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoRatSpecificInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoRatSpecificInfo.aidl new file mode 100644 index 0000000000..4e0719cd7f --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoRatSpecificInfo.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 -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.radio.network; +@VintfStability +union CellInfoRatSpecificInfo { + android.hardware.radio.network.CellInfoGsm gsm; + android.hardware.radio.network.CellInfoWcdma wcdma; + android.hardware.radio.network.CellInfoTdscdma tdscdma; + android.hardware.radio.network.CellInfoLte lte; + android.hardware.radio.network.CellInfoNr nr; + android.hardware.radio.network.CellInfoCdma cdma; +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoTdscdma.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoTdscdma.aidl similarity index 90% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoTdscdma.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoTdscdma.aidl index 4fbe5b61e6..d4e0874914 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoTdscdma.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoTdscdma.aidl @@ -31,9 +31,9 @@ // 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.radio; +package android.hardware.radio.network; @VintfStability parcelable CellInfoTdscdma { - android.hardware.radio.CellIdentityTdscdma cellIdentityTdscdma; - android.hardware.radio.TdscdmaSignalStrength signalStrengthTdscdma; + android.hardware.radio.network.CellIdentityTdscdma cellIdentityTdscdma; + android.hardware.radio.network.TdscdmaSignalStrength signalStrengthTdscdma; } diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoWcdma.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoWcdma.aidl similarity index 90% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoWcdma.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoWcdma.aidl index 88ca975ba6..da19e37952 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoWcdma.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoWcdma.aidl @@ -31,9 +31,9 @@ // 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.radio; +package android.hardware.radio.network; @VintfStability parcelable CellInfoWcdma { - android.hardware.radio.CellIdentityWcdma cellIdentityWcdma; - android.hardware.radio.WcdmaSignalStrength signalStrengthWcdma; + android.hardware.radio.network.CellIdentityWcdma cellIdentityWcdma; + android.hardware.radio.network.WcdmaSignalStrength signalStrengthWcdma; } diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ClosedSubscriberGroupInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/ClosedSubscriberGroupInfo.aidl similarity index 97% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ClosedSubscriberGroupInfo.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/ClosedSubscriberGroupInfo.aidl index 0c10ca4622..5c45d93e68 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ClosedSubscriberGroupInfo.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/ClosedSubscriberGroupInfo.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.network; @VintfStability parcelable ClosedSubscriberGroupInfo { boolean csgIndication; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/Domain.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/Domain.aidl similarity index 97% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/Domain.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/Domain.aidl index 062af35c27..712bbdb91e 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/Domain.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/Domain.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.network; @Backing(type="int") @VintfStability enum Domain { CS = 1, diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/EutranBands.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EutranBands.aidl similarity index 98% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/EutranBands.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EutranBands.aidl index 1449865474..6c94d156cc 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/EutranBands.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EutranBands.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.network; @Backing(type="int") @VintfStability enum EutranBands { BAND_1 = 1, diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/EutranRegistrationInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EutranRegistrationInfo.aidl similarity index 91% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/EutranRegistrationInfo.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EutranRegistrationInfo.aidl index 0ab883334f..098b57e9cd 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/EutranRegistrationInfo.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EutranRegistrationInfo.aidl @@ -31,9 +31,9 @@ // 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.radio; +package android.hardware.radio.network; @VintfStability parcelable EutranRegistrationInfo { - android.hardware.radio.LteVopsInfo lteVopsInfo; - android.hardware.radio.NrIndicators nrIndicators; + android.hardware.radio.network.LteVopsInfo lteVopsInfo; + android.hardware.radio.network.NrIndicators nrIndicators; } diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/EvdoSignalStrength.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EvdoSignalStrength.aidl similarity index 97% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/EvdoSignalStrength.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EvdoSignalStrength.aidl index 148dfa093c..7ec1635c4d 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/EvdoSignalStrength.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EvdoSignalStrength.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.network; @VintfStability parcelable EvdoSignalStrength { int dbm; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/GeranBands.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/GeranBands.aidl similarity index 98% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/GeranBands.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/GeranBands.aidl index 0efe023429..7cb0fd5bad 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/GeranBands.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/GeranBands.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.network; @Backing(type="int") @VintfStability enum GeranBands { BAND_T380 = 1, diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/GsmSignalStrength.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/GsmSignalStrength.aidl similarity index 97% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/GsmSignalStrength.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/GsmSignalStrength.aidl index 5d3a6e1a32..4142ae7781 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/GsmSignalStrength.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/GsmSignalStrength.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.network; @VintfStability parcelable GsmSignalStrength { int signalStrength; diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetwork.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetwork.aidl new file mode 100644 index 0000000000..8131007348 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetwork.aidl @@ -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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.radio.network; +@VintfStability +interface IRadioNetwork { + oneway void getAllowedNetworkTypesBitmap(in int serial); + oneway void getAvailableBandModes(in int serial); + oneway void getAvailableNetworks(in int serial); + oneway void getBarringInfo(in int serial); + oneway void getCdmaRoamingPreference(in int serial); + oneway void getCellInfoList(in int serial); + oneway void getDataRegistrationState(in int serial); + oneway void getImsRegistrationState(in int serial); + oneway void getNeighboringCids(in int serial); + oneway void getNetworkSelectionMode(in int serial); + oneway void getOperator(in int serial); + oneway void getSignalStrength(in int serial); + oneway void getSystemSelectionChannels(in int serial); + oneway void getVoiceRadioTechnology(in int serial); + oneway void getVoiceRegistrationState(in int serial); + oneway void isNrDualConnectivityEnabled(in int serial); + oneway void pullLceData(in int serial); + oneway void responseAcknowledgement(); + oneway void setAllowedNetworkTypesBitmap(in int serial, in android.hardware.radio.RadioAccessFamily networkTypeBitmap); + oneway void setBandMode(in int serial, in android.hardware.radio.network.RadioBandMode mode); + oneway void setBarringPassword(in int serial, in String facility, in String oldPassword, in String newPassword); + oneway void setCdmaRoamingPreference(in int serial, in android.hardware.radio.network.CdmaRoamingType type); + oneway void setCellInfoListRate(in int serial, in int rate); + oneway void setIndicationFilter(in int serial, in android.hardware.radio.network.IndicationFilter indicationFilter); + oneway void setLinkCapacityReportingCriteria(in int serial, in int hysteresisMs, in int hysteresisDlKbps, in int hysteresisUlKbps, in int[] thresholdsDownlinkKbps, in int[] thresholdsUplinkKbps, in android.hardware.radio.AccessNetwork accessNetwork); + oneway void setLocationUpdates(in int serial, in boolean enable); + oneway void setNetworkSelectionModeAutomatic(in int serial); + oneway void setNetworkSelectionModeManual(in int serial, in String operatorNumeric, in android.hardware.radio.AccessNetwork ran); + oneway void setNrDualConnectivityState(in int serial, in android.hardware.radio.network.NrDualConnectivityState nrDualConnectivityState); + oneway void setResponseFunctions(in android.hardware.radio.network.IRadioNetworkResponse radioNetworkResponse, in android.hardware.radio.network.IRadioNetworkIndication radioNetworkIndication); + oneway void setSignalStrengthReportingCriteria(in int serial, in android.hardware.radio.network.SignalThresholdInfo signalThresholdInfo, in android.hardware.radio.AccessNetwork accessNetwork); + oneway void setSuppServiceNotifications(in int serial, in boolean enable); + oneway void setSystemSelectionChannels(in int serial, in boolean specifyChannels, in android.hardware.radio.network.RadioAccessSpecifier[] specifiers); + oneway void startNetworkScan(in int serial, in android.hardware.radio.network.NetworkScanRequest request); + oneway void stopNetworkScan(in int serial); + oneway void supplyNetworkDepersonalization(in int serial, in String netPin); +} diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkIndication.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkIndication.aidl new file mode 100644 index 0000000000..71b17657c8 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkIndication.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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.radio.network; +@VintfStability +interface IRadioNetworkIndication { + oneway void barringInfoChanged(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.network.CellIdentity cellIdentity, in android.hardware.radio.network.BarringInfo[] barringInfos); + oneway void cdmaPrlChanged(in android.hardware.radio.RadioIndicationType type, in int version); + oneway void cellInfoList(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.network.CellInfo[] records); + oneway void currentLinkCapacityEstimate(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.network.LinkCapacityEstimate lce); + oneway void currentPhysicalChannelConfigs(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.network.PhysicalChannelConfig[] configs); + oneway void currentSignalStrength(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.network.SignalStrength signalStrength); + oneway void imsNetworkStateChanged(in android.hardware.radio.RadioIndicationType type); + oneway void networkScanResult(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.network.NetworkScanResult result); + oneway void networkStateChanged(in android.hardware.radio.RadioIndicationType type); + oneway void nitzTimeReceived(in android.hardware.radio.RadioIndicationType type, in String nitzTime, in long receivedTime); + oneway void registrationFailed(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.network.CellIdentity cellIdentity, in String chosenPlmn, in android.hardware.radio.network.Domain domain, in int causeCode, in int additionalCauseCode); + oneway void restrictedStateChanged(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.network.PhoneRestrictedState state); + oneway void suppSvcNotify(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.network.SuppSvcNotification suppSvc); + oneway void voiceRadioTechChanged(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.RadioTechnology rat); +} diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkResponse.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkResponse.aidl new file mode 100644 index 0000000000..e03e4df236 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkResponse.aidl @@ -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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.radio.network; +@VintfStability +interface IRadioNetworkResponse { + oneway void acknowledgeRequest(in int serial); + oneway void getAllowedNetworkTypesBitmapResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.RadioAccessFamily networkTypeBitmap); + oneway void getAvailableBandModesResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.RadioBandMode[] bandModes); + oneway void getAvailableNetworksResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.OperatorInfo[] networkInfos); + oneway void getBarringInfoResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.CellIdentity cellIdentity, in android.hardware.radio.network.BarringInfo[] barringInfos); + oneway void getCdmaRoamingPreferenceResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.CdmaRoamingType type); + oneway void getCellInfoListResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.CellInfo[] cellInfo); + oneway void getDataRegistrationStateResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.RegStateResult dataRegResponse); + oneway void getImsRegistrationStateResponse(in android.hardware.radio.RadioResponseInfo info, in boolean isRegistered, in android.hardware.radio.RadioTechnologyFamily ratFamily); + oneway void getNeighboringCidsResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.NeighboringCell[] cells); + oneway void getNetworkSelectionModeResponse(in android.hardware.radio.RadioResponseInfo info, in boolean manual); + oneway void getOperatorResponse(in android.hardware.radio.RadioResponseInfo info, in String longName, in String shortName, in String numeric); + oneway void getSignalStrengthResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.SignalStrength signalStrength); + oneway void getSystemSelectionChannelsResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.RadioAccessSpecifier[] specifiers); + oneway void getVoiceRadioTechnologyResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.RadioTechnology rat); + oneway void getVoiceRegistrationStateResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.RegStateResult voiceRegResponse); + oneway void isNrDualConnectivityEnabledResponse(in android.hardware.radio.RadioResponseInfo info, in boolean isEnabled); + oneway void pullLceDataResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.LceDataInfo lceInfo); + oneway void setAllowedNetworkTypesBitmapResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setBandModeResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setBarringPasswordResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setCdmaRoamingPreferenceResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setCellInfoListRateResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setIndicationFilterResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setLinkCapacityReportingCriteriaResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setLocationUpdatesResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setNetworkSelectionModeAutomaticResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setNetworkSelectionModeManualResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setNrDualConnectivityStateResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setSignalStrengthReportingCriteriaResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setSuppServiceNotificationsResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setSystemSelectionChannelsResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void startNetworkScanResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void stopNetworkScanResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void supplyNetworkDepersonalizationResponse(in android.hardware.radio.RadioResponseInfo info, in int remainingRetries); +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/IndicationFilter.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IndicationFilter.aidl similarity index 98% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/IndicationFilter.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IndicationFilter.aidl index 629af68d64..f79ff2a8b7 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/IndicationFilter.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IndicationFilter.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.network; @Backing(type="int") @VintfStability enum IndicationFilter { NONE = 0, diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LceDataInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/LceDataInfo.aidl similarity index 97% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LceDataInfo.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/LceDataInfo.aidl index 64c63674c6..1876465e41 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LceDataInfo.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/LceDataInfo.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.network; @VintfStability parcelable LceDataInfo { int lastHopCapacityKbps; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LinkCapacityEstimate.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/LinkCapacityEstimate.aidl similarity index 97% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LinkCapacityEstimate.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/LinkCapacityEstimate.aidl index d2a5c83a3c..c34f177722 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LinkCapacityEstimate.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/LinkCapacityEstimate.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.network; @VintfStability parcelable LinkCapacityEstimate { int downlinkCapacityKbps; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LteSignalStrength.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/LteSignalStrength.aidl similarity index 97% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LteSignalStrength.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/LteSignalStrength.aidl index 28840bccef..c7b41f1173 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LteSignalStrength.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/LteSignalStrength.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.network; @VintfStability parcelable LteSignalStrength { int signalStrength; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LteVopsInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/LteVopsInfo.aidl similarity index 97% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LteVopsInfo.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/LteVopsInfo.aidl index b28c415c3e..9f20b1026e 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LteVopsInfo.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/LteVopsInfo.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.network; @VintfStability parcelable LteVopsInfo { boolean isVopsSupported; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NeighboringCell.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NeighboringCell.aidl similarity index 97% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NeighboringCell.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NeighboringCell.aidl index 89d7818fe8..4f29c0b95b 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NeighboringCell.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NeighboringCell.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.network; @VintfStability parcelable NeighboringCell { String cid; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NetworkScanRequest.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NetworkScanRequest.aidl similarity index 95% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NetworkScanRequest.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NetworkScanRequest.aidl index 992ac48321..948a1f6139 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NetworkScanRequest.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NetworkScanRequest.aidl @@ -31,12 +31,12 @@ // 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.radio; +package android.hardware.radio.network; @VintfStability parcelable NetworkScanRequest { int type; int interval; - android.hardware.radio.RadioAccessSpecifier[] specifiers; + android.hardware.radio.network.RadioAccessSpecifier[] specifiers; int maxSearchTime; boolean incrementalResults; int incrementalResultsPeriodicity; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NetworkScanResult.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NetworkScanResult.aidl similarity index 95% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NetworkScanResult.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NetworkScanResult.aidl index 670c17317d..3dc39406e7 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NetworkScanResult.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NetworkScanResult.aidl @@ -31,12 +31,12 @@ // 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.radio; +package android.hardware.radio.network; @VintfStability parcelable NetworkScanResult { int status; android.hardware.radio.RadioError error; - android.hardware.radio.CellInfo[] networkInfos; + android.hardware.radio.network.CellInfo[] networkInfos; const int SCAN_STATUS_PARTIAL = 1; const int SCAN_STATUS_COMPLETE = 2; } diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NgranBands.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NgranBands.aidl similarity index 98% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NgranBands.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NgranBands.aidl index 14db49b1ec..aa60cde74f 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NgranBands.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NgranBands.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.network; @Backing(type="int") @VintfStability enum NgranBands { BAND_1 = 1, diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NrDualConnectivityState.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrDualConnectivityState.aidl similarity index 97% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NrDualConnectivityState.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrDualConnectivityState.aidl index c3fb9f2fd8..6ee526ff2b 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NrDualConnectivityState.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrDualConnectivityState.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.network; @Backing(type="byte") @VintfStability enum NrDualConnectivityState { ENABLE = 1, diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NrIndicators.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrIndicators.aidl similarity index 97% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NrIndicators.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrIndicators.aidl index 81dc51c36e..54f9b8f75f 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NrIndicators.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrIndicators.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.network; @VintfStability parcelable NrIndicators { boolean isEndcAvailable; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NrSignalStrength.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrSignalStrength.aidl similarity index 97% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NrSignalStrength.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrSignalStrength.aidl index daf6a418ff..14b60a622c 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NrSignalStrength.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrSignalStrength.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.network; @VintfStability parcelable NrSignalStrength { int ssRsrp; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NrVopsInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrVopsInfo.aidl similarity index 98% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NrVopsInfo.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrVopsInfo.aidl index 52abce6791..7f58ee17fa 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/NrVopsInfo.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrVopsInfo.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.network; @VintfStability parcelable NrVopsInfo { byte vopsSupported; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/OperatorInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/OperatorInfo.aidl similarity index 98% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/OperatorInfo.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/OperatorInfo.aidl index bb90f1210d..c3658d9f91 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/OperatorInfo.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/OperatorInfo.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.network; @VintfStability parcelable OperatorInfo { String alphaLong; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PhoneRestrictedState.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/PhoneRestrictedState.aidl similarity index 97% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PhoneRestrictedState.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/PhoneRestrictedState.aidl index 7a4982f5ea..dff8be052e 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PhoneRestrictedState.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/PhoneRestrictedState.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.network; @Backing(type="int") @VintfStability enum PhoneRestrictedState { NONE = 0, diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PhysicalChannelConfig.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/PhysicalChannelConfig.aidl similarity index 92% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PhysicalChannelConfig.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/PhysicalChannelConfig.aidl index 91c4a96a1f..8db6bc40da 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PhysicalChannelConfig.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/PhysicalChannelConfig.aidl @@ -31,10 +31,10 @@ // 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.radio; +package android.hardware.radio.network; @VintfStability parcelable PhysicalChannelConfig { - android.hardware.radio.CellConnectionStatus status; + android.hardware.radio.network.CellConnectionStatus status; android.hardware.radio.RadioTechnology rat; int downlinkChannelNumber; int uplinkChannelNumber; @@ -42,5 +42,5 @@ parcelable PhysicalChannelConfig { int cellBandwidthUplinkKhz; int[] contextIds; int physicalCellId; - android.hardware.radio.PhysicalChannelConfigBand band; + android.hardware.radio.network.PhysicalChannelConfigBand band; } diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PhysicalChannelConfigBand.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/PhysicalChannelConfigBand.aidl similarity index 87% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PhysicalChannelConfigBand.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/PhysicalChannelConfigBand.aidl index 1953083771..50af816485 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PhysicalChannelConfigBand.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/PhysicalChannelConfigBand.aidl @@ -31,12 +31,12 @@ // 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.radio; +package android.hardware.radio.network; @VintfStability union PhysicalChannelConfigBand { boolean noinit; - android.hardware.radio.GeranBands geranBand; - android.hardware.radio.UtranBands utranBand; - android.hardware.radio.EutranBands eutranBand; - android.hardware.radio.NgranBands ngranBand; + android.hardware.radio.network.GeranBands geranBand; + android.hardware.radio.network.UtranBands utranBand; + android.hardware.radio.network.EutranBands eutranBand; + android.hardware.radio.network.NgranBands ngranBand; } diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioAccessSpecifier.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RadioAccessSpecifier.aidl similarity index 91% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioAccessSpecifier.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RadioAccessSpecifier.aidl index b47ee2d49c..b412f63899 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioAccessSpecifier.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RadioAccessSpecifier.aidl @@ -31,10 +31,10 @@ // 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.radio; +package android.hardware.radio.network; @VintfStability parcelable RadioAccessSpecifier { - android.hardware.radio.RadioAccessNetworks radioAccessNetwork; - android.hardware.radio.RadioAccessSpecifierBands bands; + android.hardware.radio.AccessNetwork accessNetwork; + android.hardware.radio.network.RadioAccessSpecifierBands bands; int[] channels; } diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioAccessSpecifierBands.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RadioAccessSpecifierBands.aidl similarity index 86% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioAccessSpecifierBands.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RadioAccessSpecifierBands.aidl index 9d0a99733c..d44a883671 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioAccessSpecifierBands.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RadioAccessSpecifierBands.aidl @@ -31,12 +31,12 @@ // 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.radio; +package android.hardware.radio.network; @VintfStability union RadioAccessSpecifierBands { boolean noinit; - android.hardware.radio.GeranBands[] geranBands; - android.hardware.radio.UtranBands[] utranBands; - android.hardware.radio.EutranBands[] eutranBands; - android.hardware.radio.NgranBands[] ngranBands; + android.hardware.radio.network.GeranBands[] geranBands; + android.hardware.radio.network.UtranBands[] utranBands; + android.hardware.radio.network.EutranBands[] eutranBands; + android.hardware.radio.network.NgranBands[] ngranBands; } diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioBandMode.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RadioBandMode.aidl similarity index 98% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioBandMode.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RadioBandMode.aidl index 973ca524b1..7266fd5e06 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioBandMode.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RadioBandMode.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.network; @Backing(type="int") @VintfStability enum RadioBandMode { BAND_MODE_UNSPECIFIED = 0, diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RegState.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RegState.aidl similarity index 98% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RegState.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RegState.aidl index 049ded1c1d..d10f41313d 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RegState.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RegState.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.network; @Backing(type="int") @VintfStability enum RegState { NOT_REG_MT_NOT_SEARCHING_OP = 0, diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RegStateResult.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RegStateResult.aidl similarity index 85% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RegStateResult.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RegStateResult.aidl index e5b5aa5b71..eff22166b9 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RegStateResult.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RegStateResult.aidl @@ -31,13 +31,13 @@ // 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.radio; +package android.hardware.radio.network; @VintfStability parcelable RegStateResult { - android.hardware.radio.RegState regState; + android.hardware.radio.network.RegState regState; android.hardware.radio.RadioTechnology rat; - android.hardware.radio.RegistrationFailCause reasonForDenial; - android.hardware.radio.CellIdentity cellIdentity; + android.hardware.radio.network.RegistrationFailCause reasonForDenial; + android.hardware.radio.network.CellIdentity cellIdentity; String registeredPlmn; - android.hardware.radio.AccessTechnologySpecificInfo accessTechnologySpecificInfo; + android.hardware.radio.network.AccessTechnologySpecificInfo accessTechnologySpecificInfo; } diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RegistrationFailCause.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RegistrationFailCause.aidl similarity index 98% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RegistrationFailCause.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RegistrationFailCause.aidl index c5529b6ddb..75fcdf453d 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RegistrationFailCause.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RegistrationFailCause.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.network; @Backing(type="int") @VintfStability enum RegistrationFailCause { NONE = 0, diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SignalStrength.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SignalStrength.aidl similarity index 79% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SignalStrength.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SignalStrength.aidl index 7c7eade8a3..7187116fce 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SignalStrength.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SignalStrength.aidl @@ -31,14 +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.radio; +package android.hardware.radio.network; @VintfStability parcelable SignalStrength { - android.hardware.radio.GsmSignalStrength gsm; - android.hardware.radio.CdmaSignalStrength cdma; - android.hardware.radio.EvdoSignalStrength evdo; - android.hardware.radio.LteSignalStrength lte; - android.hardware.radio.TdscdmaSignalStrength tdscdma; - android.hardware.radio.WcdmaSignalStrength wcdma; - android.hardware.radio.NrSignalStrength nr; + android.hardware.radio.network.GsmSignalStrength gsm; + android.hardware.radio.network.CdmaSignalStrength cdma; + android.hardware.radio.network.EvdoSignalStrength evdo; + android.hardware.radio.network.LteSignalStrength lte; + android.hardware.radio.network.TdscdmaSignalStrength tdscdma; + android.hardware.radio.network.WcdmaSignalStrength wcdma; + android.hardware.radio.network.NrSignalStrength nr; } diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SignalThresholdInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SignalThresholdInfo.aidl similarity index 98% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SignalThresholdInfo.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SignalThresholdInfo.aidl index 381984eff9..3ea6c4e5db 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SignalThresholdInfo.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SignalThresholdInfo.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.network; @VintfStability parcelable SignalThresholdInfo { int signalMeasurement; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SuppSvcNotification.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SuppSvcNotification.aidl similarity index 97% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SuppSvcNotification.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SuppSvcNotification.aidl index c098e245fc..541754e3ad 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SuppSvcNotification.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SuppSvcNotification.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.network; @VintfStability parcelable SuppSvcNotification { boolean isMT; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/TdscdmaSignalStrength.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/TdscdmaSignalStrength.aidl similarity index 97% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/TdscdmaSignalStrength.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/TdscdmaSignalStrength.aidl index a2ba211d3f..a00345f16a 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/TdscdmaSignalStrength.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/TdscdmaSignalStrength.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.network; @VintfStability parcelable TdscdmaSignalStrength { int signalStrength; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/UtranBands.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/UtranBands.aidl similarity index 98% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/UtranBands.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/UtranBands.aidl index 32cff727ff..87d5b8535d 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/UtranBands.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/UtranBands.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.network; @Backing(type="int") @VintfStability enum UtranBands { BAND_1 = 1, diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/WcdmaSignalStrength.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/WcdmaSignalStrength.aidl similarity index 97% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/WcdmaSignalStrength.aidl rename to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/WcdmaSignalStrength.aidl index 764ddedfa1..678ace9735 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/WcdmaSignalStrength.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/WcdmaSignalStrength.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.network; @VintfStability parcelable WcdmaSignalStrength { int signalStrength; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/AppStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/AppStatus.aidl similarity index 92% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/AppStatus.aidl rename to radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/AppStatus.aidl index ea2cd3a08e..89d8f9a6ee 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/AppStatus.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/AppStatus.aidl @@ -31,17 +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.radio; +package android.hardware.radio.sim; @VintfStability parcelable AppStatus { int appType; int appState; - android.hardware.radio.PersoSubstate persoSubstate; + android.hardware.radio.sim.PersoSubstate persoSubstate; String aidPtr; String appLabelPtr; boolean pin1Replaced; - android.hardware.radio.PinState pin1; - android.hardware.radio.PinState pin2; + android.hardware.radio.sim.PinState pin1; + android.hardware.radio.sim.PinState pin2; const int APP_STATE_UNKNOWN = 0; const int APP_STATE_DETECTED = 1; const int APP_STATE_PIN = 2; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CardPowerState.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CardPowerState.aidl similarity index 98% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CardPowerState.aidl rename to radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CardPowerState.aidl index 1a3b4c6295..c0026ba95c 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CardPowerState.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CardPowerState.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.sim; @Backing(type="int") @VintfStability enum CardPowerState { POWER_DOWN = 0, diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CardStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CardStatus.aidl similarity index 93% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CardStatus.aidl rename to radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CardStatus.aidl index e7a666f903..2d95b979d8 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CardStatus.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CardStatus.aidl @@ -31,15 +31,15 @@ // 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.radio; +package android.hardware.radio.sim; @VintfStability parcelable CardStatus { int cardState; - android.hardware.radio.PinState universalPinState; + android.hardware.radio.sim.PinState universalPinState; int gsmUmtsSubscriptionAppIndex; int cdmaSubscriptionAppIndex; int imsSubscriptionAppIndex; - android.hardware.radio.AppStatus[] applications; + android.hardware.radio.sim.AppStatus[] applications; int physicalSlotId; String atr; String iccid; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/Carrier.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/Carrier.aidl similarity index 98% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/Carrier.aidl rename to radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/Carrier.aidl index 46d5dca2ff..c7fced175f 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/Carrier.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/Carrier.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.sim; @VintfStability parcelable Carrier { String mcc; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CarrierRestrictions.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CarrierRestrictions.aidl similarity index 92% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CarrierRestrictions.aidl rename to radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CarrierRestrictions.aidl index f7c7a5a436..ef9c779d56 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CarrierRestrictions.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CarrierRestrictions.aidl @@ -31,11 +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.radio; +package android.hardware.radio.sim; @VintfStability parcelable CarrierRestrictions { - android.hardware.radio.Carrier[] allowedCarriers; - android.hardware.radio.Carrier[] excludedCarriers; + android.hardware.radio.sim.Carrier[] allowedCarriers; + android.hardware.radio.sim.Carrier[] excludedCarriers; boolean priority; boolean allowedCarriersPrioritized; } diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSubscriptionSource.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CdmaSubscriptionSource.aidl similarity index 98% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSubscriptionSource.aidl rename to radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CdmaSubscriptionSource.aidl index 11e8a2466e..50e768c10e 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSubscriptionSource.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CdmaSubscriptionSource.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.sim; @Backing(type="int") @VintfStability enum CdmaSubscriptionSource { RUIM_SIM = 0, diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IRadioSim.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IRadioSim.aidl new file mode 100644 index 0000000000..cc5a53ef6d --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IRadioSim.aidl @@ -0,0 +1,74 @@ +/* + * 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 -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.radio.sim; +@VintfStability +interface IRadioSim { + oneway void areUiccApplicationsEnabled(in int serial); + oneway void changeIccPin2ForApp(in int serial, in String oldPin2, in String newPin2, in String aid); + oneway void changeIccPinForApp(in int serial, in String oldPin, in String newPin, in String aid); + oneway void enableUiccApplications(in int serial, in boolean enable); + oneway void getAllowedCarriers(in int serial); + oneway void getCdmaSubscription(in int serial); + oneway void getCdmaSubscriptionSource(in int serial); + oneway void getFacilityLockForApp(in int serial, in String facility, in String password, in int serviceClass, in String appId); + oneway void getIccCardStatus(in int serial); + oneway void getImsiForApp(in int serial, in String aid); + oneway void getSimPhonebookCapacity(in int serial); + oneway void getSimPhonebookRecords(in int serial); + oneway void iccCloseLogicalChannel(in int serial, in int channelId); + oneway void iccIoForApp(in int serial, in android.hardware.radio.sim.IccIo iccIo); + oneway void iccOpenLogicalChannel(in int serial, in String aid, in int p2); + oneway void iccTransmitApduBasicChannel(in int serial, in android.hardware.radio.sim.SimApdu message); + oneway void iccTransmitApduLogicalChannel(in int serial, in android.hardware.radio.sim.SimApdu message); + oneway void reportStkServiceIsRunning(in int serial); + oneway void requestIccSimAuthentication(in int serial, in int authContext, in String authData, in String aid); + oneway void requestIsimAuthentication(in int serial, in String challenge); + oneway void responseAcknowledgement(); + oneway void sendEnvelope(in int serial, in String command); + oneway void sendEnvelopeWithStatus(in int serial, in String contents); + oneway void sendTerminalResponseToSim(in int serial, in String commandResponse); + oneway void setAllowedCarriers(in int serial, in android.hardware.radio.sim.CarrierRestrictions carriers, in android.hardware.radio.sim.SimLockMultiSimPolicy multiSimPolicy); + oneway void setCarrierInfoForImsiEncryption(in int serial, in android.hardware.radio.sim.ImsiEncryptionInfo imsiEncryptionInfo); + oneway void setCdmaSubscriptionSource(in int serial, in android.hardware.radio.sim.CdmaSubscriptionSource cdmaSub); + oneway void setFacilityLockForApp(in int serial, in String facility, in boolean lockState, in String password, in int serviceClass, in String appId); + oneway void setResponseFunctions(in android.hardware.radio.sim.IRadioSimResponse radioSimResponse, in android.hardware.radio.sim.IRadioSimIndication radioSimIndication); + oneway void setSimCardPower(in int serial, in android.hardware.radio.sim.CardPowerState powerUp); + oneway void setUiccSubscription(in int serial, in android.hardware.radio.sim.SelectUiccSub uiccSub); + oneway void supplyIccPin2ForApp(in int serial, in String pin2, in String aid); + oneway void supplyIccPinForApp(in int serial, in String pin, in String aid); + oneway void supplyIccPuk2ForApp(in int serial, in String puk2, in String pin2, in String aid); + oneway void supplyIccPukForApp(in int serial, in String puk, in String pin, in String aid); + oneway void supplySimDepersonalization(in int serial, in android.hardware.radio.sim.PersoSubstate persoType, in String controlKey); + oneway void updateSimPhonebookRecords(in int serial, in android.hardware.radio.sim.PhonebookRecordInfo recordInfo); +} diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IRadioSimIndication.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IRadioSimIndication.aidl new file mode 100644 index 0000000000..d4371b8e69 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IRadioSimIndication.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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.radio.sim; +@VintfStability +interface IRadioSimIndication { + oneway void carrierInfoForImsiEncryption(in android.hardware.radio.RadioIndicationType info); + oneway void cdmaSubscriptionSourceChanged(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.sim.CdmaSubscriptionSource cdmaSource); + oneway void simPhonebookChanged(in android.hardware.radio.RadioIndicationType type); + oneway void simPhonebookRecordsReceived(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.sim.PbReceivedStatus status, in android.hardware.radio.sim.PhonebookRecordInfo[] records); + oneway void simRefresh(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.sim.SimRefreshResult refreshResult); + oneway void simStatusChanged(in android.hardware.radio.RadioIndicationType type); + oneway void stkEventNotify(in android.hardware.radio.RadioIndicationType type, in String cmd); + oneway void stkProactiveCommand(in android.hardware.radio.RadioIndicationType type, in String cmd); + oneway void stkSessionEnd(in android.hardware.radio.RadioIndicationType type); + oneway void subscriptionStatusChanged(in android.hardware.radio.RadioIndicationType type, in boolean activate); + oneway void uiccApplicationsEnablementChanged(in android.hardware.radio.RadioIndicationType type, in boolean enabled); +} diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IRadioSimResponse.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IRadioSimResponse.aidl new file mode 100644 index 0000000000..e164257218 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IRadioSimResponse.aidl @@ -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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.radio.sim; +@VintfStability +interface IRadioSimResponse { + oneway void acknowledgeRequest(in int serial); + oneway void areUiccApplicationsEnabledResponse(in android.hardware.radio.RadioResponseInfo info, in boolean enabled); + oneway void changeIccPin2ForAppResponse(in android.hardware.radio.RadioResponseInfo info, in int remainingRetries); + oneway void changeIccPinForAppResponse(in android.hardware.radio.RadioResponseInfo info, in int remainingRetries); + oneway void enableUiccApplicationsResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void getAllowedCarriersResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.sim.CarrierRestrictions carriers, in android.hardware.radio.sim.SimLockMultiSimPolicy multiSimPolicy); + oneway void getCdmaSubscriptionResponse(in android.hardware.radio.RadioResponseInfo info, in String mdn, in String hSid, in String hNid, in String min, in String prl); + oneway void getCdmaSubscriptionSourceResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.sim.CdmaSubscriptionSource source); + oneway void getFacilityLockForAppResponse(in android.hardware.radio.RadioResponseInfo info, in int response); + oneway void getIccCardStatusResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.sim.CardStatus cardStatus); + oneway void getImsiForAppResponse(in android.hardware.radio.RadioResponseInfo info, in String imsi); + oneway void getSimPhonebookCapacityResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.sim.PhonebookCapacity capacity); + oneway void getSimPhonebookRecordsResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void iccCloseLogicalChannelResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void iccIoForAppResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.sim.IccIoResult iccIo); + oneway void iccOpenLogicalChannelResponse(in android.hardware.radio.RadioResponseInfo info, in int channelId, in byte[] selectResponse); + oneway void iccTransmitApduBasicChannelResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.sim.IccIoResult result); + oneway void iccTransmitApduLogicalChannelResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.sim.IccIoResult result); + oneway void reportStkServiceIsRunningResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void requestIccSimAuthenticationResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.sim.IccIoResult result); + oneway void requestIsimAuthenticationResponse(in android.hardware.radio.RadioResponseInfo info, in String response); + oneway void sendEnvelopeResponse(in android.hardware.radio.RadioResponseInfo info, in String commandResponse); + oneway void sendEnvelopeWithStatusResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.sim.IccIoResult iccIo); + oneway void sendTerminalResponseToSimResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setAllowedCarriersResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setCarrierInfoForImsiEncryptionResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setCdmaSubscriptionSourceResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setFacilityLockForAppResponse(in android.hardware.radio.RadioResponseInfo info, in int retry); + oneway void setSimCardPowerResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setUiccSubscriptionResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void supplyIccPin2ForAppResponse(in android.hardware.radio.RadioResponseInfo info, in int remainingRetries); + oneway void supplyIccPinForAppResponse(in android.hardware.radio.RadioResponseInfo info, in int remainingRetries); + oneway void supplyIccPuk2ForAppResponse(in android.hardware.radio.RadioResponseInfo info, in int remainingRetries); + oneway void supplyIccPukForAppResponse(in android.hardware.radio.RadioResponseInfo info, in int remainingRetries); + oneway void supplySimDepersonalizationResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.sim.PersoSubstate persoType, in int remainingRetries); + oneway void updateSimPhonebookRecordsResponse(in android.hardware.radio.RadioResponseInfo info, in int updatedRecordIndex); +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/IccIo.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IccIo.aidl similarity index 98% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/IccIo.aidl rename to radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IccIo.aidl index 1bea23a438..3e4dcf6730 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/IccIo.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IccIo.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.sim; @VintfStability parcelable IccIo { int command; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/IccIoResult.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IccIoResult.aidl similarity index 98% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/IccIoResult.aidl rename to radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IccIoResult.aidl index 50b1e9e68f..58e43ebcca 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/IccIoResult.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IccIoResult.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.sim; @VintfStability parcelable IccIoResult { int sw1; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ImsiEncryptionInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/ImsiEncryptionInfo.aidl similarity index 98% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ImsiEncryptionInfo.aidl rename to radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/ImsiEncryptionInfo.aidl index fb85eca34a..087f399ce7 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ImsiEncryptionInfo.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/ImsiEncryptionInfo.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.sim; @VintfStability parcelable ImsiEncryptionInfo { String mcc; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PbReceivedStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PbReceivedStatus.aidl similarity index 98% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PbReceivedStatus.aidl rename to radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PbReceivedStatus.aidl index dd95ad5127..61babacce2 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PbReceivedStatus.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PbReceivedStatus.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.sim; @Backing(type="byte") @VintfStability enum PbReceivedStatus { PB_RECEIVED_OK = 1, diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PersoSubstate.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PersoSubstate.aidl similarity index 98% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PersoSubstate.aidl rename to radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PersoSubstate.aidl index 35b75c63dd..a09d7816c9 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PersoSubstate.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PersoSubstate.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.sim; @Backing(type="int") @VintfStability enum PersoSubstate { UNKNOWN = 0, diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PhonebookCapacity.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PhonebookCapacity.aidl similarity index 98% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PhonebookCapacity.aidl rename to radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PhonebookCapacity.aidl index 8d2623bbb5..c1fa765de7 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PhonebookCapacity.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PhonebookCapacity.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.sim; @VintfStability parcelable PhonebookCapacity { int maxAdnRecords; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PhonebookRecordInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PhonebookRecordInfo.aidl similarity index 98% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PhonebookRecordInfo.aidl rename to radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PhonebookRecordInfo.aidl index 02a166e18c..36bc9201e7 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PhonebookRecordInfo.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PhonebookRecordInfo.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.sim; @VintfStability parcelable PhonebookRecordInfo { int recordId; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PinState.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PinState.aidl similarity index 98% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PinState.aidl rename to radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PinState.aidl index 3b65179748..c78b92c70b 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PinState.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PinState.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.sim; @Backing(type="int") @VintfStability enum PinState { UNKNOWN = 0, diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SelectUiccSub.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SelectUiccSub.aidl similarity index 98% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SelectUiccSub.aidl rename to radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SelectUiccSub.aidl index b7acc66a85..4842fbe6df 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SelectUiccSub.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SelectUiccSub.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.sim; @VintfStability parcelable SelectUiccSub { int slot; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SimApdu.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimApdu.aidl similarity index 98% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SimApdu.aidl rename to radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimApdu.aidl index 511031aec7..d8e1dde370 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SimApdu.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimApdu.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.sim; @VintfStability parcelable SimApdu { int sessionId; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SimLockMultiSimPolicy.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimLockMultiSimPolicy.aidl similarity index 98% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SimLockMultiSimPolicy.aidl rename to radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimLockMultiSimPolicy.aidl index ad967940fd..6fd89d50c6 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SimLockMultiSimPolicy.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimLockMultiSimPolicy.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.sim; @Backing(type="int") @VintfStability enum SimLockMultiSimPolicy { NO_MULTISIM_POLICY = 0, diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SimRefreshResult.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimRefreshResult.aidl similarity index 98% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SimRefreshResult.aidl rename to radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimRefreshResult.aidl index ce870c54a5..dd3c1f2cf3 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SimRefreshResult.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimRefreshResult.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.sim; @VintfStability parcelable SimRefreshResult { int type; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/AudioQuality.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/AudioQuality.aidl similarity index 98% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/AudioQuality.aidl rename to radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/AudioQuality.aidl index a596969147..89bd2dcf5b 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/AudioQuality.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/AudioQuality.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.voice; @Backing(type="int") @VintfStability enum AudioQuality { UNSPECIFIED = 0, diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/Call.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/Call.aidl similarity index 94% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/Call.aidl rename to radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/Call.aidl index b4a3cc7557..7f445314b6 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/Call.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/Call.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.voice; @VintfStability parcelable Call { int state; @@ -46,8 +46,8 @@ parcelable Call { int numberPresentation; String name; int namePresentation; - android.hardware.radio.UusInfo[] uusInfo; - android.hardware.radio.AudioQuality audioQuality; + android.hardware.radio.voice.UusInfo[] uusInfo; + android.hardware.radio.voice.AudioQuality audioQuality; String forwardedNumber; const int PRESENTATION_ALLOWED = 0; const int PRESENTATION_RESTRICTED = 1; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CallForwardInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CallForwardInfo.aidl similarity index 98% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CallForwardInfo.aidl rename to radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CallForwardInfo.aidl index 0b79272721..7ef9e46387 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CallForwardInfo.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CallForwardInfo.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.voice; @VintfStability parcelable CallForwardInfo { int status; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaCallWaiting.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaCallWaiting.aidl similarity index 95% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaCallWaiting.aidl rename to radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaCallWaiting.aidl index b4866919cd..9edf1e7e75 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaCallWaiting.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaCallWaiting.aidl @@ -31,13 +31,13 @@ // 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.radio; +package android.hardware.radio.voice; @VintfStability parcelable CdmaCallWaiting { String number; int numberPresentation; String name; - android.hardware.radio.CdmaSignalInfoRecord signalInfoRecord; + android.hardware.radio.voice.CdmaSignalInfoRecord signalInfoRecord; int numberType; int numberPlan; const int NUMBER_PLAN_UNKNOWN = 0; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaDisplayInfoRecord.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaDisplayInfoRecord.aidl similarity index 97% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaDisplayInfoRecord.aidl rename to radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaDisplayInfoRecord.aidl index 11f082f1b0..579dd29c63 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaDisplayInfoRecord.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaDisplayInfoRecord.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.voice; @VintfStability parcelable CdmaDisplayInfoRecord { String alphaBuf; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaInformationRecord.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecord.aidl similarity index 81% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaInformationRecord.aidl rename to radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecord.aidl index c2f2df273b..6648358247 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaInformationRecord.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecord.aidl @@ -31,17 +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.radio; +package android.hardware.radio.voice; @VintfStability parcelable CdmaInformationRecord { int name; - android.hardware.radio.CdmaDisplayInfoRecord[] display; - android.hardware.radio.CdmaNumberInfoRecord[] number; - android.hardware.radio.CdmaSignalInfoRecord[] signal; - android.hardware.radio.CdmaRedirectingNumberInfoRecord[] redir; - android.hardware.radio.CdmaLineControlInfoRecord[] lineCtrl; - android.hardware.radio.CdmaT53ClirInfoRecord[] clir; - android.hardware.radio.CdmaT53AudioControlInfoRecord[] audioCtrl; + android.hardware.radio.voice.CdmaDisplayInfoRecord[] display; + android.hardware.radio.voice.CdmaNumberInfoRecord[] number; + android.hardware.radio.voice.CdmaSignalInfoRecord[] signal; + android.hardware.radio.voice.CdmaRedirectingNumberInfoRecord[] redir; + android.hardware.radio.voice.CdmaLineControlInfoRecord[] lineCtrl; + android.hardware.radio.voice.CdmaT53ClirInfoRecord[] clir; + android.hardware.radio.voice.CdmaT53AudioControlInfoRecord[] audioCtrl; const int NAME_DISPLAY = 0; const int NAME_CALLED_PARTY_NUMBER = 1; const int NAME_CALLING_PARTY_NUMBER = 2; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaInformationRecords.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl similarity index 94% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaInformationRecords.aidl rename to radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl index 88a433148b..d7eecbb0d4 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaInformationRecords.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecords.aidl @@ -31,8 +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.radio; +package android.hardware.radio.voice; @VintfStability parcelable CdmaInformationRecords { - android.hardware.radio.CdmaInformationRecord[] infoRec; + android.hardware.radio.voice.CdmaInformationRecord[] infoRec; } diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaLineControlInfoRecord.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaLineControlInfoRecord.aidl similarity index 98% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaLineControlInfoRecord.aidl rename to radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaLineControlInfoRecord.aidl index 48180a7717..d7f6cd4e2c 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaLineControlInfoRecord.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaLineControlInfoRecord.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.voice; @VintfStability parcelable CdmaLineControlInfoRecord { byte lineCtrlPolarityIncluded; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaNumberInfoRecord.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaNumberInfoRecord.aidl similarity index 97% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaNumberInfoRecord.aidl rename to radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaNumberInfoRecord.aidl index 86376a7034..f3fcb2f9b8 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaNumberInfoRecord.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaNumberInfoRecord.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.voice; @VintfStability parcelable CdmaNumberInfoRecord { String number; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaOtaProvisionStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaOtaProvisionStatus.aidl similarity index 98% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaOtaProvisionStatus.aidl rename to radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaOtaProvisionStatus.aidl index 7cd88ac9cd..5ea4e50546 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaOtaProvisionStatus.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaOtaProvisionStatus.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.voice; @Backing(type="int") @VintfStability enum CdmaOtaProvisionStatus { SPL_UNLOCKED = 0, diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaRedirectingNumberInfoRecord.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaRedirectingNumberInfoRecord.aidl similarity index 95% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaRedirectingNumberInfoRecord.aidl rename to radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaRedirectingNumberInfoRecord.aidl index 9713f80d75..f0f2b04c95 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaRedirectingNumberInfoRecord.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaRedirectingNumberInfoRecord.aidl @@ -31,10 +31,10 @@ // 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.radio; +package android.hardware.radio.voice; @VintfStability parcelable CdmaRedirectingNumberInfoRecord { - android.hardware.radio.CdmaNumberInfoRecord redirectingNumber; + android.hardware.radio.voice.CdmaNumberInfoRecord redirectingNumber; int redirectingReason; const int REDIRECTING_REASON_UNKNOWN = 0; const int REDIRECTING_REASON_CALL_FORWARDING_BUSY = 1; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSignalInfoRecord.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaSignalInfoRecord.aidl similarity index 97% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSignalInfoRecord.aidl rename to radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaSignalInfoRecord.aidl index efb396af56..2ebb3960ba 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaSignalInfoRecord.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaSignalInfoRecord.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.voice; @VintfStability parcelable CdmaSignalInfoRecord { boolean isPresent; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaT53AudioControlInfoRecord.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaT53AudioControlInfoRecord.aidl similarity index 97% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaT53AudioControlInfoRecord.aidl rename to radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaT53AudioControlInfoRecord.aidl index 9285eb79f1..33e2c2bd3f 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaT53AudioControlInfoRecord.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaT53AudioControlInfoRecord.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.voice; @VintfStability parcelable CdmaT53AudioControlInfoRecord { byte upLink; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaT53ClirInfoRecord.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaT53ClirInfoRecord.aidl similarity index 97% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaT53ClirInfoRecord.aidl rename to radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaT53ClirInfoRecord.aidl index ff4d3c3da5..457fd18f75 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CdmaT53ClirInfoRecord.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaT53ClirInfoRecord.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.voice; @VintfStability parcelable CdmaT53ClirInfoRecord { byte cause; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CfData.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CfData.aidl similarity index 94% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CfData.aidl rename to radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CfData.aidl index 6a2b0269e5..d48102bec5 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CfData.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CfData.aidl @@ -31,8 +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.radio; +package android.hardware.radio.voice; @VintfStability parcelable CfData { - android.hardware.radio.CallForwardInfo[] cfInfo; + android.hardware.radio.voice.CallForwardInfo[] cfInfo; } diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ClipStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/ClipStatus.aidl similarity index 97% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ClipStatus.aidl rename to radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/ClipStatus.aidl index 36a15100b9..dafc2b9d36 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/ClipStatus.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/ClipStatus.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.voice; @Backing(type="int") @VintfStability enum ClipStatus { CLIP_PROVISIONED = 0, diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/Dial.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/Dial.aidl similarity index 95% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/Dial.aidl rename to radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/Dial.aidl index cc9fc783ce..c9a02a91c4 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/Dial.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/Dial.aidl @@ -31,12 +31,12 @@ // 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.radio; +package android.hardware.radio.voice; @VintfStability parcelable Dial { String address; int clir; - android.hardware.radio.UusInfo[] uusInfo; + android.hardware.radio.voice.UusInfo[] uusInfo; const int CLIR_DEFAULT = 0; const int CLIR_INVOCATION = 1; const int CLIR_SUPPRESSION = 2; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/EmergencyCallRouting.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyCallRouting.aidl similarity index 97% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/EmergencyCallRouting.aidl rename to radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyCallRouting.aidl index 95f5a46059..b31a661158 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/EmergencyCallRouting.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyCallRouting.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.voice; @Backing(type="int") @VintfStability enum EmergencyCallRouting { UNKNOWN = 0, diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/EmergencyNumber.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyNumber.aidl similarity index 94% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/EmergencyNumber.aidl rename to radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyNumber.aidl index 1de62467f7..4f415ee3a2 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/EmergencyNumber.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyNumber.aidl @@ -31,13 +31,13 @@ // 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.radio; +package android.hardware.radio.voice; @VintfStability parcelable EmergencyNumber { String number; String mcc; String mnc; - android.hardware.radio.EmergencyServiceCategory categories; + android.hardware.radio.voice.EmergencyServiceCategory categories; String[] urns; int sources; const int SOURCE_NETWORK_SIGNALING = 1; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/EmergencyServiceCategory.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyServiceCategory.aidl similarity index 98% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/EmergencyServiceCategory.aidl rename to radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyServiceCategory.aidl index 0341572f10..34d3c40eb3 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/EmergencyServiceCategory.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyServiceCategory.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.voice; @Backing(type="int") @VintfStability enum EmergencyServiceCategory { UNSPECIFIED = 0, diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoice.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoice.aidl new file mode 100644 index 0000000000..4cac560051 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoice.aidl @@ -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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.radio.voice; +@VintfStability +interface IRadioVoice { + oneway void acceptCall(in int serial); + oneway void conference(in int serial); + oneway void dial(in int serial, in android.hardware.radio.voice.Dial dialInfo); + oneway void emergencyDial(in int serial, in android.hardware.radio.voice.Dial dialInfo, in android.hardware.radio.voice.EmergencyServiceCategory categories, in String[] urns, in android.hardware.radio.voice.EmergencyCallRouting routing, in boolean hasKnownUserIntentEmergency, in boolean isTesting); + oneway void exitEmergencyCallbackMode(in int serial); + oneway void explicitCallTransfer(in int serial); + oneway void getCallForwardStatus(in int serial, in android.hardware.radio.voice.CallForwardInfo callInfo); + oneway void getCallWaiting(in int serial, in int serviceClass); + oneway void getClip(in int serial); + oneway void getClir(in int serial); + oneway void getCurrentCalls(in int serial); + oneway void getLastCallFailCause(in int serial); + oneway void getMute(in int serial); + oneway void getPreferredVoicePrivacy(in int serial); + oneway void getTtyMode(in int serial); + oneway void handleStkCallSetupRequestFromSim(in int serial, in boolean accept); + oneway void hangup(in int serial, in int gsmIndex); + oneway void hangupForegroundResumeBackground(in int serial); + oneway void hangupWaitingOrBackground(in int serial); + oneway void rejectCall(in int serial); + oneway void responseAcknowledgement(); + oneway void sendBurstDtmf(in int serial, in String dtmf, in int on, in int off); + oneway void sendCdmaFeatureCode(in int serial, in String featureCode); + oneway void sendDtmf(in int serial, in String s); + oneway void separateConnection(in int serial, in int gsmIndex); + oneway void setCallForward(in int serial, in android.hardware.radio.voice.CallForwardInfo callInfo); + oneway void setCallWaiting(in int serial, in boolean enable, in int serviceClass); + oneway void setClir(in int serial, in int status); + oneway void setMute(in int serial, in boolean enable); + oneway void setPreferredVoicePrivacy(in int serial, in boolean enable); + oneway void setResponseFunctions(in android.hardware.radio.voice.IRadioVoiceResponse radioVoiceResponse, in android.hardware.radio.voice.IRadioVoiceIndication radioVoiceIndication); + oneway void setTtyMode(in int serial, in android.hardware.radio.voice.TtyMode mode); + oneway void startDtmf(in int serial, in String s); + oneway void stopDtmf(in int serial); + oneway void switchWaitingOrHoldingAndActive(in int serial); +} diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoiceIndication.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoiceIndication.aidl new file mode 100644 index 0000000000..4f87c12044 --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoiceIndication.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. + */ +/////////////////////////////////////////////////////////////////////////////// +// 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 -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.radio.voice; +@VintfStability +interface IRadioVoiceIndication { + oneway void callRing(in android.hardware.radio.RadioIndicationType type, in boolean isGsm, in android.hardware.radio.voice.CdmaSignalInfoRecord record); + oneway void callStateChanged(in android.hardware.radio.RadioIndicationType type); + oneway void cdmaCallWaiting(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.voice.CdmaCallWaiting callWaitingRecord); + oneway void cdmaInfoRec(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.voice.CdmaInformationRecords records); + oneway void cdmaOtaProvisionStatus(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.voice.CdmaOtaProvisionStatus status); + oneway void currentEmergencyNumberList(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.voice.EmergencyNumber[] emergencyNumberList); + oneway void enterEmergencyCallbackMode(in android.hardware.radio.RadioIndicationType type); + oneway void exitEmergencyCallbackMode(in android.hardware.radio.RadioIndicationType type); + oneway void indicateRingbackTone(in android.hardware.radio.RadioIndicationType type, in boolean start); + oneway void onSupplementaryServiceIndication(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.voice.StkCcUnsolSsResult ss); + oneway void resendIncallMute(in android.hardware.radio.RadioIndicationType type); + oneway void srvccStateNotify(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.voice.SrvccState state); + oneway void stkCallControlAlphaNotify(in android.hardware.radio.RadioIndicationType type, in String alpha); + oneway void stkCallSetup(in android.hardware.radio.RadioIndicationType type, in long timeout); +} diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoiceResponse.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoiceResponse.aidl new file mode 100644 index 0000000000..9f490a86eb --- /dev/null +++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoiceResponse.aidl @@ -0,0 +1,71 @@ +/* + * 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 -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.radio.voice; +@VintfStability +interface IRadioVoiceResponse { + oneway void acceptCallResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void acknowledgeRequest(in int serial); + oneway void conferenceResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void dialResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void emergencyDialResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void exitEmergencyCallbackModeResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void explicitCallTransferResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void getCallForwardStatusResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.voice.CallForwardInfo[] callForwardInfos); + oneway void getCallWaitingResponse(in android.hardware.radio.RadioResponseInfo info, in boolean enable, in int serviceClass); + oneway void getClipResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.voice.ClipStatus status); + oneway void getClirResponse(in android.hardware.radio.RadioResponseInfo info, in int n, in int m); + oneway void getCurrentCallsResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.voice.Call[] calls); + oneway void getLastCallFailCauseResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.voice.LastCallFailCauseInfo failCauseinfo); + oneway void getMuteResponse(in android.hardware.radio.RadioResponseInfo info, in boolean enable); + oneway void getPreferredVoicePrivacyResponse(in android.hardware.radio.RadioResponseInfo info, in boolean enable); + oneway void getTtyModeResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.voice.TtyMode mode); + oneway void handleStkCallSetupRequestFromSimResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void hangupConnectionResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void hangupForegroundResumeBackgroundResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void hangupWaitingOrBackgroundResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void rejectCallResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void sendBurstDtmfResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void sendCdmaFeatureCodeResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void sendDtmfResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void separateConnectionResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setCallForwardResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setCallWaitingResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setClirResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setMuteResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setPreferredVoicePrivacyResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void setTtyModeResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void startDtmfResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void stopDtmfResponse(in android.hardware.radio.RadioResponseInfo info); + oneway void switchWaitingOrHoldingAndActiveResponse(in android.hardware.radio.RadioResponseInfo info); +} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LastCallFailCause.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/LastCallFailCause.aidl similarity index 99% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LastCallFailCause.aidl rename to radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/LastCallFailCause.aidl index 024f7ead24..3e178405df 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LastCallFailCause.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/LastCallFailCause.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.voice; @Backing(type="int") @VintfStability enum LastCallFailCause { UNOBTAINABLE_NUMBER = 1, diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LastCallFailCauseInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/LastCallFailCauseInfo.aidl similarity index 94% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LastCallFailCauseInfo.aidl rename to radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/LastCallFailCauseInfo.aidl index 43ef0cd01b..af75a4063a 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LastCallFailCauseInfo.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/LastCallFailCauseInfo.aidl @@ -31,9 +31,9 @@ // 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.radio; +package android.hardware.radio.voice; @VintfStability parcelable LastCallFailCauseInfo { - android.hardware.radio.LastCallFailCause causeCode; + android.hardware.radio.voice.LastCallFailCause causeCode; String vendorCause; } diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SrvccState.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/SrvccState.aidl similarity index 97% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SrvccState.aidl rename to radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/SrvccState.aidl index d4a941763c..8e7e9fbdf7 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SrvccState.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/SrvccState.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.voice; @Backing(type="int") @VintfStability enum SrvccState { HANDOVER_STARTED = 0, diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SsInfoData.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/SsInfoData.aidl similarity index 97% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SsInfoData.aidl rename to radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/SsInfoData.aidl index 10b4c3d81a..c5ba29363b 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/SsInfoData.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/SsInfoData.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.voice; @VintfStability parcelable SsInfoData { int[] ssInfo; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/StkCcUnsolSsResult.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/StkCcUnsolSsResult.aidl similarity index 96% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/StkCcUnsolSsResult.aidl rename to radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/StkCcUnsolSsResult.aidl index 31c2494017..71ef7a77fc 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/StkCcUnsolSsResult.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/StkCcUnsolSsResult.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.voice; @VintfStability parcelable StkCcUnsolSsResult { int serviceType; @@ -39,8 +39,8 @@ parcelable StkCcUnsolSsResult { int teleserviceType; int serviceClass; android.hardware.radio.RadioError result; - android.hardware.radio.SsInfoData[] ssInfo; - android.hardware.radio.CfData[] cfData; + android.hardware.radio.voice.SsInfoData[] ssInfo; + android.hardware.radio.voice.CfData[] cfData; const int REQUEST_TYPE_ACTIVATION = 0; const int REQUEST_TYPE_DEACTIVATION = 1; const int REQUEST_TYPE_INTERROGATION = 2; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/TtyMode.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/TtyMode.aidl similarity index 97% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/TtyMode.aidl rename to radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/TtyMode.aidl index cee3057c27..bb0a9f1ac9 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/TtyMode.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/TtyMode.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.voice; @Backing(type="int") @VintfStability enum TtyMode { OFF = 0, diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/UusInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/UusInfo.aidl similarity index 98% rename from radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/UusInfo.aidl rename to radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/UusInfo.aidl index 5b7190e99e..0198de9bb0 100644 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/UusInfo.aidl +++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/UusInfo.aidl @@ -31,7 +31,7 @@ // 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.radio; +package android.hardware.radio.voice; @VintfStability parcelable UusInfo { int uusType; diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellConfigLte.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellConfigLte.aidl deleted file mode 100644 index 184af1cb04..0000000000 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellConfigLte.aidl +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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 -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.radio; -@VintfStability -parcelable CellConfigLte { - boolean isEndcAvailable; -} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoCellInfoRatSpecificInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoCellInfoRatSpecificInfo.aidl deleted file mode 100644 index 7084e5e2ad..0000000000 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoCellInfoRatSpecificInfo.aidl +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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 -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.radio; -@VintfStability -union CellInfoCellInfoRatSpecificInfo { - android.hardware.radio.CellInfoGsm gsm; - android.hardware.radio.CellInfoWcdma wcdma; - android.hardware.radio.CellInfoTdscdma tdscdma; - android.hardware.radio.CellInfoLte lte; - android.hardware.radio.CellInfoNr nr; - android.hardware.radio.CellInfoCdma cdma; -} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoInfo.aidl deleted file mode 100644 index 9c2255520d..0000000000 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoInfo.aidl +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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 -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.radio; -@VintfStability -union CellInfoInfo { - android.hardware.radio.CellInfoGsm gsm; - android.hardware.radio.CellInfoCdma cdma; - android.hardware.radio.CellInfoWcdma wcdma; - android.hardware.radio.CellInfoTdscdma tdscdma; - android.hardware.radio.CellInfoLte lte; - android.hardware.radio.CellInfoNr nr; -} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoType.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoType.aidl deleted file mode 100644 index cb92ed9fd4..0000000000 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/CellInfoType.aidl +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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 -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.radio; -@Backing(type="int") @VintfStability -enum CellInfoType { - NONE = 0, - GSM = 1, - CDMA = 2, - LTE = 3, - WCDMA = 4, - TD_SCDMA = 5, -} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/DataRegStateResult.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/DataRegStateResult.aidl deleted file mode 100644 index 8eac451b50..0000000000 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/DataRegStateResult.aidl +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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 -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.radio; -@VintfStability -parcelable DataRegStateResult { - android.hardware.radio.RegState regState; - int rat; - int reasonDataDenied; - int maxDataCalls; - android.hardware.radio.CellIdentity cellIdentity; - @nullable android.hardware.radio.LteVopsInfo lteVopsInfo; - android.hardware.radio.NrIndicators nrIndicators; -} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/IRadio.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/IRadio.aidl deleted file mode 100644 index 0bcbd55435..0000000000 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/IRadio.aidl +++ /dev/null @@ -1,196 +0,0 @@ -/* - * 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 -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.radio; -@VintfStability -interface IRadio { - oneway void acceptCall(in int serial); - oneway void acknowledgeIncomingGsmSmsWithPdu(in int serial, in boolean success, in String ackPdu); - oneway void acknowledgeLastIncomingCdmaSms(in int serial, in android.hardware.radio.CdmaSmsAck smsAck); - oneway void acknowledgeLastIncomingGsmSms(in int serial, in boolean success, in android.hardware.radio.SmsAcknowledgeFailCause cause); - oneway void allocatePduSessionId(in int serial); - oneway void areUiccApplicationsEnabled(in int serial); - oneway void cancelHandover(in int serial, in int callId); - oneway void cancelPendingUssd(in int serial); - oneway void changeIccPin2ForApp(in int serial, in String oldPin2, in String newPin2, in String aid); - oneway void changeIccPinForApp(in int serial, in String oldPin, in String newPin, in String aid); - oneway void conference(in int serial); - oneway void deactivateDataCall(in int serial, in int cid, in android.hardware.radio.DataRequestReason reason); - oneway void deleteSmsOnRuim(in int serial, in int index); - oneway void deleteSmsOnSim(in int serial, in int index); - oneway void dial(in int serial, in android.hardware.radio.Dial dialInfo); - oneway void emergencyDial(in int serial, in android.hardware.radio.Dial dialInfo, in android.hardware.radio.EmergencyServiceCategory categories, in String[] urns, in android.hardware.radio.EmergencyCallRouting routing, in boolean hasKnownUserIntentEmergency, in boolean isTesting); - oneway void enableModem(in int serial, in boolean on); - oneway void enableUiccApplications(in int serial, in boolean enable); - oneway void exitEmergencyCallbackMode(in int serial); - oneway void explicitCallTransfer(in int serial); - oneway void getAllowedCarriers(in int serial); - oneway void getAllowedNetworkTypesBitmap(in int serial); - oneway void getAvailableBandModes(in int serial); - oneway void getAvailableNetworks(in int serial); - oneway void getBarringInfo(in int serial); - oneway void getBasebandVersion(in int serial); - oneway void getCDMASubscription(in int serial); - oneway void getCallForwardStatus(in int serial, in android.hardware.radio.CallForwardInfo callInfo); - oneway void getCallWaiting(in int serial, in int serviceClass); - oneway void getCdmaBroadcastConfig(in int serial); - oneway void getCdmaRoamingPreference(in int serial); - oneway void getCdmaSubscriptionSource(in int serial); - oneway void getCellInfoList(in int serial); - oneway void getClip(in int serial); - oneway void getClir(in int serial); - oneway void getCurrentCalls(in int serial); - oneway void getDataCallList(in int serial); - oneway void getDataRegistrationState(in int serial); - oneway void getDeviceIdentity(in int serial); - oneway void getFacilityLockForApp(in int serial, in String facility, in String password, in int serviceClass, in String appId); - oneway void getGsmBroadcastConfig(in int serial); - oneway void getHardwareConfig(in int serial); - oneway void getIccCardStatus(in int serial); - oneway void getImsRegistrationState(in int serial); - oneway void getImsiForApp(in int serial, in String aid); - oneway void getLastCallFailCause(in int serial); - oneway void getModemActivityInfo(in int serial); - oneway void getModemStackStatus(in int serial); - oneway void getMute(in int serial); - oneway void getNeighboringCids(in int serial); - oneway void getNetworkSelectionMode(in int serial); - oneway void getOperator(in int serial); - oneway void getPreferredNetworkType(in int serial); - oneway void getPreferredNetworkTypeBitmap(in int serial); - oneway void getPreferredVoicePrivacy(in int serial); - oneway void getRadioCapability(in int serial); - oneway void getSignalStrength(in int serial); - oneway void getSimPhonebookCapacity(in int serial); - oneway void getSimPhonebookRecords(in int serial); - oneway void getSlicingConfig(in int serial); - oneway void getSmscAddress(in int serial); - oneway void getSystemSelectionChannels(in int serial); - oneway void getTTYMode(in int serial); - oneway void getVoiceRadioTechnology(in int serial); - oneway void getVoiceRegistrationState(in int serial); - oneway void handleStkCallSetupRequestFromSim(in int serial, in boolean accept); - oneway void hangup(in int serial, in int gsmIndex); - oneway void hangupForegroundResumeBackground(in int serial); - oneway void hangupWaitingOrBackground(in int serial); - oneway void iccCloseLogicalChannel(in int serial, in int channelId); - oneway void iccIOForApp(in int serial, in android.hardware.radio.IccIo iccIo); - oneway void iccOpenLogicalChannel(in int serial, in String aid, in int p2); - oneway void iccTransmitApduBasicChannel(in int serial, in android.hardware.radio.SimApdu message); - oneway void iccTransmitApduLogicalChannel(in int serial, in android.hardware.radio.SimApdu message); - oneway void isNrDualConnectivityEnabled(in int serial); - oneway void nvReadItem(in int serial, in android.hardware.radio.NvItem itemId); - oneway void nvResetConfig(in int serial, in android.hardware.radio.ResetNvType resetType); - oneway void nvWriteCdmaPrl(in int serial, in byte[] prl); - oneway void nvWriteItem(in int serial, in android.hardware.radio.NvWriteItem item); - oneway void rejectCall(in int serial); - oneway void releasePduSessionId(in int serial, in int id); - oneway void reportSmsMemoryStatus(in int serial, in boolean available); - oneway void reportStkServiceIsRunning(in int serial); - oneway void requestIccSimAuthentication(in int serial, in int authContext, in String authData, in String aid); - oneway void requestIsimAuthentication(in int serial, in String challenge); - oneway void requestShutdown(in int serial); - oneway void responseAcknowledgement(); - oneway void sendBurstDtmf(in int serial, in String dtmf, in int on, in int off); - oneway void sendCDMAFeatureCode(in int serial, in String featureCode); - oneway void sendCdmaSms(in int serial, in android.hardware.radio.CdmaSmsMessage sms); - oneway void sendCdmaSmsExpectMore(in int serial, in android.hardware.radio.CdmaSmsMessage sms); - oneway void sendDeviceState(in int serial, in android.hardware.radio.DeviceStateType deviceStateType, in boolean state); - oneway void sendDtmf(in int serial, in String s); - oneway void sendEnvelope(in int serial, in String command); - oneway void sendEnvelopeWithStatus(in int serial, in String contents); - oneway void sendImsSms(in int serial, in android.hardware.radio.ImsSmsMessage message); - oneway void sendSms(in int serial, in android.hardware.radio.GsmSmsMessage message); - oneway void sendSmsExpectMore(in int serial, in android.hardware.radio.GsmSmsMessage message); - oneway void sendTerminalResponseToSim(in int serial, in String commandResponse); - oneway void sendUssd(in int serial, in String ussd); - oneway void separateConnection(in int serial, in int gsmIndex); - oneway void setAllowedCarriers(in int serial, in android.hardware.radio.CarrierRestrictions carriers, in android.hardware.radio.SimLockMultiSimPolicy multiSimPolicy); - oneway void setAllowedNetworkTypesBitmap(in int serial, in android.hardware.radio.RadioAccessFamily networkTypeBitmap); - oneway void setBandMode(in int serial, in android.hardware.radio.RadioBandMode mode); - oneway void setBarringPassword(in int serial, in String facility, in String oldPassword, in String newPassword); - oneway void setCallForward(in int serial, in android.hardware.radio.CallForwardInfo callInfo); - oneway void setCallWaiting(in int serial, in boolean enable, in int serviceClass); - oneway void setCarrierInfoForImsiEncryption(in int serial, in android.hardware.radio.ImsiEncryptionInfo imsiEncryptionInfo); - oneway void setCdmaBroadcastActivation(in int serial, in boolean activate); - oneway void setCdmaBroadcastConfig(in int serial, in android.hardware.radio.CdmaBroadcastSmsConfigInfo[] configInfo); - oneway void setCdmaRoamingPreference(in int serial, in android.hardware.radio.CdmaRoamingType type); - oneway void setCdmaSubscriptionSource(in int serial, in android.hardware.radio.CdmaSubscriptionSource cdmaSub); - oneway void setCellInfoListRate(in int serial, in int rate); - oneway void setClir(in int serial, in int status); - oneway void setDataAllowed(in int serial, in boolean allow); - oneway void setDataProfile(in int serial, in android.hardware.radio.DataProfileInfo[] profiles); - oneway void setDataThrottling(in int serial, in android.hardware.radio.DataThrottlingAction dataThrottlingAction, in long completionDurationMillis); - oneway void setFacilityLockForApp(in int serial, in String facility, in boolean lockState, in String password, in int serviceClass, in String appId); - oneway void setGsmBroadcastActivation(in int serial, in boolean activate); - oneway void setGsmBroadcastConfig(in int serial, in android.hardware.radio.GsmBroadcastSmsConfigInfo[] configInfo); - oneway void setIndicationFilter(in int serial, in android.hardware.radio.IndicationFilter indicationFilter); - oneway void setInitialAttachApn(in int serial, in android.hardware.radio.DataProfileInfo dataProfileInfo); - oneway void setLinkCapacityReportingCriteria(in int serial, in int hysteresisMs, in int hysteresisDlKbps, in int hysteresisUlKbps, in int[] thresholdsDownlinkKbps, in int[] thresholdsUplinkKbps, in android.hardware.radio.AccessNetwork accessNetwork); - oneway void setLocationUpdates(in int serial, in boolean enable); - oneway void setMute(in int serial, in boolean enable); - oneway void setNetworkSelectionModeAutomatic(in int serial); - oneway void setNetworkSelectionModeManual(in int serial, in String operatorNumeric, in android.hardware.radio.RadioAccessNetworks ran); - oneway void setNrDualConnectivityState(in int serial, in android.hardware.radio.NrDualConnectivityState nrDualConnectivityState); - oneway void setPreferredNetworkType(in int serial, in android.hardware.radio.PreferredNetworkType nwType); - oneway void setPreferredNetworkTypeBitmap(in int serial, in android.hardware.radio.RadioAccessFamily networkTypeBitmap); - oneway void setPreferredVoicePrivacy(in int serial, in boolean enable); - oneway void setRadioCapability(in int serial, in android.hardware.radio.RadioCapability rc); - oneway void setRadioPower(in int serial, in boolean powerOn, in boolean forEmergencyCall, in boolean preferredForEmergencyCall); - oneway void setResponseFunctions(in android.hardware.radio.IRadioResponse radioResponse, in android.hardware.radio.IRadioIndication radioIndication); - oneway void setSignalStrengthReportingCriteria(in int serial, in android.hardware.radio.SignalThresholdInfo signalThresholdInfo, in android.hardware.radio.AccessNetwork accessNetwork); - oneway void setSimCardPower(in int serial, in android.hardware.radio.CardPowerState powerUp); - oneway void setSmscAddress(in int serial, in String smsc); - oneway void setSuppServiceNotifications(in int serial, in boolean enable); - oneway void setSystemSelectionChannels(in int serial, in boolean specifyChannels, in android.hardware.radio.RadioAccessSpecifier[] specifiers); - oneway void setTTYMode(in int serial, in android.hardware.radio.TtyMode mode); - oneway void setUiccSubscription(in int serial, in android.hardware.radio.SelectUiccSub uiccSub); - oneway void setupDataCall(in int serial, in android.hardware.radio.AccessNetwork accessNetwork, in android.hardware.radio.DataProfileInfo dataProfileInfo, in boolean roamingAllowed, in android.hardware.radio.DataRequestReason reason, in android.hardware.radio.LinkAddress[] addresses, in String[] dnses, in int pduSessionId, in @nullable android.hardware.radio.SliceInfo sliceInfo, in @nullable android.hardware.radio.TrafficDescriptor trafficDescriptor, in boolean matchAllRuleAllowed); - oneway void startDtmf(in int serial, in String s); - oneway void startHandover(in int serial, in int callId); - oneway void startKeepalive(in int serial, in android.hardware.radio.KeepaliveRequest keepalive); - oneway void startNetworkScan(in int serial, in android.hardware.radio.NetworkScanRequest request); - oneway void stopDtmf(in int serial); - oneway void stopKeepalive(in int serial, in int sessionHandle); - oneway void stopNetworkScan(in int serial); - oneway void supplyIccPin2ForApp(in int serial, in String pin2, in String aid); - oneway void supplyIccPinForApp(in int serial, in String pin, in String aid); - oneway void supplyIccPuk2ForApp(in int serial, in String puk2, in String pin2, in String aid); - oneway void supplyIccPukForApp(in int serial, in String puk, in String pin, in String aid); - oneway void supplyNetworkDepersonalization(in int serial, in String netPin); - oneway void supplySimDepersonalization(in int serial, in android.hardware.radio.PersoSubstate persoType, in String controlKey); - oneway void switchWaitingOrHoldingAndActive(in int serial); - oneway void updateSimPhonebookRecords(in int serial, in android.hardware.radio.PhonebookRecordInfo recordInfo); - oneway void writeSmsToRuim(in int serial, in android.hardware.radio.CdmaSmsWriteArgs cdmaSms); - oneway void writeSmsToSim(in int serial, in android.hardware.radio.SmsWriteArgs smsWriteArgs); -} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/IRadioIndication.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/IRadioIndication.aidl deleted file mode 100644 index 48e9e3ec3e..0000000000 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/IRadioIndication.aidl +++ /dev/null @@ -1,94 +0,0 @@ -/* - * 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 -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.radio; -@VintfStability -interface IRadioIndication { - oneway void barringInfoChanged(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.CellIdentity cellIdentity, in android.hardware.radio.BarringInfo[] barringInfos); - oneway void callRing(in android.hardware.radio.RadioIndicationType type, in boolean isGsm, in android.hardware.radio.CdmaSignalInfoRecord record); - oneway void callStateChanged(in android.hardware.radio.RadioIndicationType type); - oneway void carrierInfoForImsiEncryption(in android.hardware.radio.RadioIndicationType info); - oneway void cdmaCallWaiting(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.CdmaCallWaiting callWaitingRecord); - oneway void cdmaInfoRec(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.CdmaInformationRecords records); - oneway void cdmaNewSms(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.CdmaSmsMessage msg); - oneway void cdmaOtaProvisionStatus(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.CdmaOtaProvisionStatus status); - oneway void cdmaPrlChanged(in android.hardware.radio.RadioIndicationType type, in int version); - oneway void cdmaRuimSmsStorageFull(in android.hardware.radio.RadioIndicationType type); - oneway void cdmaSubscriptionSourceChanged(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.CdmaSubscriptionSource cdmaSource); - oneway void cellInfoList(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.CellInfo[] records); - oneway void currentEmergencyNumberList(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.EmergencyNumber[] emergencyNumberList); - oneway void currentLinkCapacityEstimate(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.LinkCapacityEstimate lce); - oneway void currentPhysicalChannelConfigs(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.PhysicalChannelConfig[] configs); - oneway void currentSignalStrength(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.SignalStrength signalStrength); - oneway void dataCallListChanged(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.SetupDataCallResult[] dcList); - oneway void enterEmergencyCallbackMode(in android.hardware.radio.RadioIndicationType type); - oneway void exitEmergencyCallbackMode(in android.hardware.radio.RadioIndicationType type); - oneway void hardwareConfigChanged(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.HardwareConfig[] configs); - oneway void imsNetworkStateChanged(in android.hardware.radio.RadioIndicationType type); - oneway void indicateRingbackTone(in android.hardware.radio.RadioIndicationType type, in boolean start); - oneway void keepaliveStatus(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.KeepaliveStatus status); - oneway void lceData(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.LceDataInfo lce); - oneway void modemReset(in android.hardware.radio.RadioIndicationType type, in String reason); - oneway void networkScanResult(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.NetworkScanResult result); - oneway void networkStateChanged(in android.hardware.radio.RadioIndicationType type); - oneway void newBroadcastSms(in android.hardware.radio.RadioIndicationType type, in byte[] data); - oneway void newSms(in android.hardware.radio.RadioIndicationType type, in byte[] pdu); - oneway void newSmsOnSim(in android.hardware.radio.RadioIndicationType type, in int recordNumber); - oneway void newSmsStatusReport(in android.hardware.radio.RadioIndicationType type, in byte[] pdu); - oneway void nitzTimeReceived(in android.hardware.radio.RadioIndicationType type, in String nitzTime, in long receivedTime); - oneway void onSupplementaryServiceIndication(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.StkCcUnsolSsResult ss); - oneway void onUssd(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.UssdModeType modeType, in String msg); - oneway void pcoData(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.PcoDataInfo pco); - oneway void radioCapabilityIndication(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.RadioCapability rc); - oneway void radioStateChanged(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.RadioState radioState); - oneway void registrationFailed(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.CellIdentity cellIdentity, in String chosenPlmn, in android.hardware.radio.Domain domain, in int causeCode, in int additionalCauseCode); - oneway void resendIncallMute(in android.hardware.radio.RadioIndicationType type); - oneway void restrictedStateChanged(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.PhoneRestrictedState state); - oneway void rilConnected(in android.hardware.radio.RadioIndicationType type); - oneway void simPhonebookChanged(in android.hardware.radio.RadioIndicationType type); - oneway void simPhonebookRecordsReceived(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.PbReceivedStatus status, in android.hardware.radio.PhonebookRecordInfo[] records); - oneway void simRefresh(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.SimRefreshResult refreshResult); - oneway void simSmsStorageFull(in android.hardware.radio.RadioIndicationType type); - oneway void simStatusChanged(in android.hardware.radio.RadioIndicationType type); - oneway void srvccStateNotify(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.SrvccState state); - oneway void stkCallControlAlphaNotify(in android.hardware.radio.RadioIndicationType type, in String alpha); - oneway void stkCallSetup(in android.hardware.radio.RadioIndicationType type, in long timeout); - oneway void stkEventNotify(in android.hardware.radio.RadioIndicationType type, in String cmd); - oneway void stkProactiveCommand(in android.hardware.radio.RadioIndicationType type, in String cmd); - oneway void stkSessionEnd(in android.hardware.radio.RadioIndicationType type); - oneway void subscriptionStatusChanged(in android.hardware.radio.RadioIndicationType type, in boolean activate); - oneway void suppSvcNotify(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.SuppSvcNotification suppSvc); - oneway void uiccApplicationsEnablementChanged(in android.hardware.radio.RadioIndicationType type, in boolean enabled); - oneway void unthrottleApn(in android.hardware.radio.RadioIndicationType type, in String apn); - oneway void voiceRadioTechChanged(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.RadioTechnology rat); -} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/IRadioResponse.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/IRadioResponse.aidl deleted file mode 100644 index 0d18cf8aaa..0000000000 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/IRadioResponse.aidl +++ /dev/null @@ -1,199 +0,0 @@ -/* - * 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 -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.radio; -@VintfStability -interface IRadioResponse { - oneway void acceptCallResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void acknowledgeIncomingGsmSmsWithPduResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void acknowledgeLastIncomingCdmaSmsResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void acknowledgeLastIncomingGsmSmsResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void acknowledgeRequest(in int serial); - oneway void allocatePduSessionIdResponse(in android.hardware.radio.RadioResponseInfo info, in int id); - oneway void areUiccApplicationsEnabledResponse(in android.hardware.radio.RadioResponseInfo info, in boolean enabled); - oneway void cancelHandoverResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void cancelPendingUssdResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void changeIccPin2ForAppResponse(in android.hardware.radio.RadioResponseInfo info, in int remainingRetries); - oneway void changeIccPinForAppResponse(in android.hardware.radio.RadioResponseInfo info, in int remainingRetries); - oneway void conferenceResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void deactivateDataCallResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void deleteSmsOnRuimResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void deleteSmsOnSimResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void dialResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void emergencyDialResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void enableModemResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void enableUiccApplicationsResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void exitEmergencyCallbackModeResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void explicitCallTransferResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void getAllowedCarriersResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.CarrierRestrictions carriers, in android.hardware.radio.SimLockMultiSimPolicy multiSimPolicy); - oneway void getAllowedNetworkTypesBitmapResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.RadioAccessFamily networkTypeBitmap); - oneway void getAvailableBandModesResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.RadioBandMode[] bandModes); - oneway void getAvailableNetworksResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.OperatorInfo[] networkInfos); - oneway void getBarringInfoResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.CellIdentity cellIdentity, in android.hardware.radio.BarringInfo[] barringInfos); - oneway void getBasebandVersionResponse(in android.hardware.radio.RadioResponseInfo info, in String version); - oneway void getCDMASubscriptionResponse(in android.hardware.radio.RadioResponseInfo info, in String mdn, in String hSid, in String hNid, in String min, in String prl); - oneway void getCallForwardStatusResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.CallForwardInfo[] callForwardInfos); - oneway void getCallWaitingResponse(in android.hardware.radio.RadioResponseInfo info, in boolean enable, in int serviceClass); - oneway void getCdmaBroadcastConfigResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.CdmaBroadcastSmsConfigInfo[] configs); - oneway void getCdmaRoamingPreferenceResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.CdmaRoamingType type); - oneway void getCdmaSubscriptionSourceResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.CdmaSubscriptionSource source); - oneway void getCellInfoListResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.CellInfo[] cellInfo); - oneway void getClipResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.ClipStatus status); - oneway void getClirResponse(in android.hardware.radio.RadioResponseInfo info, in int n, in int m); - oneway void getCurrentCallsResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.Call[] calls); - oneway void getDataCallListResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.SetupDataCallResult[] dcResponse); - oneway void getDataRegistrationStateResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.RegStateResult dataRegResponse); - oneway void getDeviceIdentityResponse(in android.hardware.radio.RadioResponseInfo info, in String imei, in String imeisv, in String esn, in String meid); - oneway void getFacilityLockForAppResponse(in android.hardware.radio.RadioResponseInfo info, in int response); - oneway void getGsmBroadcastConfigResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.GsmBroadcastSmsConfigInfo[] configs); - oneway void getHardwareConfigResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.HardwareConfig[] config); - oneway void getIMSIForAppResponse(in android.hardware.radio.RadioResponseInfo info, in String imsi); - oneway void getIccCardStatusResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.CardStatus cardStatus); - oneway void getImsRegistrationStateResponse(in android.hardware.radio.RadioResponseInfo info, in boolean isRegistered, in android.hardware.radio.RadioTechnologyFamily ratFamily); - oneway void getLastCallFailCauseResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.LastCallFailCauseInfo failCauseinfo); - oneway void getModemActivityInfoResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.ActivityStatsInfo activityInfo); - oneway void getModemStackStatusResponse(in android.hardware.radio.RadioResponseInfo info, in boolean isEnabled); - oneway void getMuteResponse(in android.hardware.radio.RadioResponseInfo info, in boolean enable); - oneway void getNeighboringCidsResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.NeighboringCell[] cells); - oneway void getNetworkSelectionModeResponse(in android.hardware.radio.RadioResponseInfo info, in boolean manual); - oneway void getOperatorResponse(in android.hardware.radio.RadioResponseInfo info, in String longName, in String shortName, in String numeric); - oneway void getPreferredNetworkTypeBitmapResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.RadioAccessFamily networkTypeBitmap); - oneway void getPreferredNetworkTypeResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.PreferredNetworkType nwType); - oneway void getPreferredVoicePrivacyResponse(in android.hardware.radio.RadioResponseInfo info, in boolean enable); - oneway void getRadioCapabilityResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.RadioCapability rc); - oneway void getSignalStrengthResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.SignalStrength signalStrength); - oneway void getSimPhonebookCapacityResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.PhonebookCapacity capacity); - oneway void getSimPhonebookRecordsResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void getSlicingConfigResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.SlicingConfig slicingConfig); - oneway void getSmscAddressResponse(in android.hardware.radio.RadioResponseInfo info, in String smsc); - oneway void getSystemSelectionChannelsResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.RadioAccessSpecifier[] specifiers); - oneway void getTTYModeResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.TtyMode mode); - oneway void getVoiceRadioTechnologyResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.RadioTechnology rat); - oneway void getVoiceRegistrationStateResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.RegStateResult voiceRegResponse); - oneway void handleStkCallSetupRequestFromSimResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void hangupConnectionResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void hangupForegroundResumeBackgroundResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void hangupWaitingOrBackgroundResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void iccCloseLogicalChannelResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void iccIOForAppResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.IccIoResult iccIo); - oneway void iccOpenLogicalChannelResponse(in android.hardware.radio.RadioResponseInfo info, in int channelId, in byte[] selectResponse); - oneway void iccTransmitApduBasicChannelResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.IccIoResult result); - oneway void iccTransmitApduLogicalChannelResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.IccIoResult result); - oneway void isNrDualConnectivityEnabledResponse(in android.hardware.radio.RadioResponseInfo info, in boolean isEnabled); - oneway void nvReadItemResponse(in android.hardware.radio.RadioResponseInfo info, in String result); - oneway void nvResetConfigResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void nvWriteCdmaPrlResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void nvWriteItemResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void pullLceDataResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.LceDataInfo lceInfo); - oneway void rejectCallResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void releasePduSessionIdResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void reportSmsMemoryStatusResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void reportStkServiceIsRunningResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void requestIccSimAuthenticationResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.IccIoResult result); - oneway void requestIsimAuthenticationResponse(in android.hardware.radio.RadioResponseInfo info, in String response); - oneway void requestShutdownResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void sendBurstDtmfResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void sendCDMAFeatureCodeResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void sendCdmaSmsExpectMoreResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.SendSmsResult sms); - oneway void sendCdmaSmsResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.SendSmsResult sms); - oneway void sendDeviceStateResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void sendDtmfResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void sendEnvelopeResponse(in android.hardware.radio.RadioResponseInfo info, in String commandResponse); - oneway void sendEnvelopeWithStatusResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.IccIoResult iccIo); - oneway void sendImsSmsResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.SendSmsResult sms); - oneway void sendSMSExpectMoreResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.SendSmsResult sms); - oneway void sendSmsExpectMoreResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.SendSmsResult sms); - oneway void sendSmsResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.SendSmsResult sms); - oneway void sendTerminalResponseToSimResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void sendUssdResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void separateConnectionResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void setAllowedCarriersResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void setAllowedNetworkTypesBitmapResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void setBandModeResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void setBarringPasswordResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void setCallForwardResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void setCallWaitingResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void setCarrierInfoForImsiEncryptionResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void setCdmaBroadcastActivationResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void setCdmaBroadcastConfigResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void setCdmaRoamingPreferenceResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void setCdmaSubscriptionSourceResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void setCellInfoListRateResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void setClirResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void setDataAllowedResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void setDataProfileResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void setDataThrottlingResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void setFacilityLockForAppResponse(in android.hardware.radio.RadioResponseInfo info, in int retry); - oneway void setGsmBroadcastActivationResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void setGsmBroadcastConfigResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void setIndicationFilterResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void setInitialAttachApnResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void setLinkCapacityReportingCriteriaResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void setLocationUpdatesResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void setMuteResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void setNetworkSelectionModeAutomaticResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void setNetworkSelectionModeManualResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void setNrDualConnectivityStateResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void setPreferredNetworkTypeBitmapResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void setPreferredNetworkTypeResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void setPreferredVoicePrivacyResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void setRadioCapabilityResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.RadioCapability rc); - oneway void setRadioPowerResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void setSignalStrengthReportingCriteriaResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void setSimCardPowerResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void setSmscAddressResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void setSuppServiceNotificationsResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void setSystemSelectionChannelsResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void setTTYModeResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void setUiccSubscriptionResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void setupDataCallResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.SetupDataCallResult dcResponse); - oneway void startDtmfResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void startHandoverResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void startKeepaliveResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.KeepaliveStatus status); - oneway void startLceServiceResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.LceStatusInfo statusInfo); - oneway void startNetworkScanResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void stopDtmfResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void stopKeepaliveResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void stopLceServiceResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.LceStatusInfo statusInfo); - oneway void stopNetworkScanResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void supplyIccPin2ForAppResponse(in android.hardware.radio.RadioResponseInfo info, in int remainingRetries); - oneway void supplyIccPinForAppResponse(in android.hardware.radio.RadioResponseInfo info, in int remainingRetries); - oneway void supplyIccPuk2ForAppResponse(in android.hardware.radio.RadioResponseInfo info, in int remainingRetries); - oneway void supplyIccPukForAppResponse(in android.hardware.radio.RadioResponseInfo info, in int remainingRetries); - oneway void supplyNetworkDepersonalizationResponse(in android.hardware.radio.RadioResponseInfo info, in int remainingRetries); - oneway void supplySimDepersonalizationResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.PersoSubstate persoType, in int remainingRetries); - oneway void switchWaitingOrHoldingAndActiveResponse(in android.hardware.radio.RadioResponseInfo info); - oneway void updateSimPhonebookRecordsResponse(in android.hardware.radio.RadioResponseInfo info, in int updatedRecordIndex); - oneway void writeSmsToRuimResponse(in android.hardware.radio.RadioResponseInfo info, in int index); - oneway void writeSmsToSimResponse(in android.hardware.radio.RadioResponseInfo info, in int index); -} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LceStatusInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LceStatusInfo.aidl deleted file mode 100644 index 74166c384b..0000000000 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/LceStatusInfo.aidl +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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 -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.radio; -@VintfStability -parcelable LceStatusInfo { - int lceStatus; - byte actualIntervalMs; - const int LCE_STATUS_NOT_SUPPORTED = 0; - const int LCE_STATUS_STOPPED = 1; - const int LCE_STATUS_ACTIVE = 2; -} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PreferredNetworkType.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PreferredNetworkType.aidl deleted file mode 100644 index 7615dff86f..0000000000 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/PreferredNetworkType.aidl +++ /dev/null @@ -1,60 +0,0 @@ -/* - * 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 -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.radio; -@Backing(type="int") @VintfStability -enum PreferredNetworkType { - GSM_WCDMA = 0, - GSM_ONLY = 1, - WCDMA = 2, - GSM_WCDMA_AUTO = 3, - CDMA_EVDO_AUTO = 4, - CDMA_ONLY = 5, - EVDO_ONLY = 6, - GSM_WCDMA_CDMA_EVDO_AUTO = 7, - LTE_CDMA_EVDO = 8, - LTE_GSM_WCDMA = 9, - LTE_CMDA_EVDO_GSM_WCDMA = 10, - LTE_ONLY = 11, - LTE_WCDMA = 12, - TD_SCDMA_ONLY = 13, - TD_SCDMA_WCDMA = 14, - TD_SCDMA_LTE = 15, - TD_SCDMA_GSM = 16, - TD_SCDMA_GSM_LTE = 17, - TD_SCDMA_GSM_WCDMA = 18, - TD_SCDMA_WCDMA_LTE = 19, - TD_SCDMA_GSM_WCDMA_LTE = 20, - TD_SCDMA_GSM_WCDMA_CDMA_EVDO_AUTO = 21, - TD_SCDMA_LTE_CDMA_EVDO_GSM_WCDMA = 22, -} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioAccessNetworks.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioAccessNetworks.aidl deleted file mode 100644 index 67f5e8a246..0000000000 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioAccessNetworks.aidl +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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 -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.radio; -@Backing(type="int") @VintfStability -enum RadioAccessNetworks { - UNKNOWN = 0, - GERAN = 1, - UTRAN = 2, - EUTRAN = 3, - NGRAN = 4, - CDMA2000 = 5, -} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioFrequencyInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioFrequencyInfo.aidl deleted file mode 100644 index cd0f6c2e13..0000000000 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioFrequencyInfo.aidl +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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 -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.radio; -@VintfStability -union RadioFrequencyInfo { - boolean noinit; - int range; - int channelNumber; - const int FREQUENCY_RANGE_LOW = 1; - const int FREQUENCY_RANGE_MID = 2; - const int FREQUENCY_RANGE_HIGH = 3; - const int FREQUENCY_RANGE_MMWAVE = 4; -} diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/VoiceRegStateResult.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/VoiceRegStateResult.aidl deleted file mode 100644 index a693ff5240..0000000000 --- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/VoiceRegStateResult.aidl +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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 -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.radio; -@VintfStability -parcelable VoiceRegStateResult { - android.hardware.radio.RegState regState; - int rat; - boolean cssSupported; - int roamingIndicator; - int systemIsInPrl; - int defaultRoamingIndicator; - int reasonForDenial; - android.hardware.radio.CellIdentity cellIdentity; -} diff --git a/radio/aidl/android/hardware/radio/CellConfigLte.aidl b/radio/aidl/android/hardware/radio/CellConfigLte.aidl deleted file mode 100644 index 56a1a10c1d..0000000000 --- a/radio/aidl/android/hardware/radio/CellConfigLte.aidl +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 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.radio; - -/** - * Contains the configuration of the LTE cell tower. - */ -@VintfStability -parcelable CellConfigLte { - /** - * Indicates that if E-UTRA-NR Dual Connectivity (EN-DC) is supported by the LTE cell. - * True if the plmn-InfoList-r15 is present in SIB2 and at least one bit in this list is true, - * otherwise this value should be false. - * Reference: 3GPP TS 36.331 v15.2.2 6.3.1 System information blocks. - */ - boolean isEndcAvailable; -} diff --git a/radio/aidl/android/hardware/radio/CellInfoInfo.aidl b/radio/aidl/android/hardware/radio/CellInfoInfo.aidl deleted file mode 100644 index 4d5e12d4cd..0000000000 --- a/radio/aidl/android/hardware/radio/CellInfoInfo.aidl +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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.radio; - -import android.hardware.radio.CellInfoCdma; -import android.hardware.radio.CellInfoGsm; -import android.hardware.radio.CellInfoLte; -import android.hardware.radio.CellInfoNr; -import android.hardware.radio.CellInfoTdscdma; -import android.hardware.radio.CellInfoWcdma; - -@VintfStability -union CellInfoInfo { - CellInfoGsm gsm; - CellInfoCdma cdma; - CellInfoWcdma wcdma; - CellInfoTdscdma tdscdma; - CellInfoLte lte; - CellInfoNr nr; -} diff --git a/radio/aidl/android/hardware/radio/CellInfoType.aidl b/radio/aidl/android/hardware/radio/CellInfoType.aidl deleted file mode 100644 index 8e5e8c92d3..0000000000 --- a/radio/aidl/android/hardware/radio/CellInfoType.aidl +++ /dev/null @@ -1,28 +0,0 @@ -/* - * 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.radio; - -@VintfStability -@Backing(type="int") -enum CellInfoType { - NONE, - GSM, - CDMA, - LTE, - WCDMA, - TD_SCDMA, -} diff --git a/radio/aidl/android/hardware/radio/DataRegStateResult.aidl b/radio/aidl/android/hardware/radio/DataRegStateResult.aidl deleted file mode 100644 index dcc39c8032..0000000000 --- a/radio/aidl/android/hardware/radio/DataRegStateResult.aidl +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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.radio; - -import android.hardware.radio.CellIdentity; -import android.hardware.radio.LteVopsInfo; -import android.hardware.radio.NrIndicators; -import android.hardware.radio.RegState; - -@VintfStability -parcelable DataRegStateResult { - /** - * Valid reg states are NOT_REG_MT_NOT_SEARCHING_OP, REG_HOME, NOT_REG_MT_SEARCHING_OP, - * REG_DENIED, UNKNOWN, REG_ROAMING defined in RegState - */ - RegState regState; - /** - * Indicates the available data radio technology, valid values as defined by RadioTechnology. - */ - int rat; - /** - * If registration state is 3 (Registration denied) this is an enumerated reason why - * registration was denied. See 3GPP TS 24.008, Annex G.6 "Additional cause codes for GMM". - * 7 == GPRS services not allowed - * 8 == GPRS services and non-GPRS services not allowed - * 9 == MS identity cannot be derived by the network - * 10 == Implicitly detached - * 14 == GPRS services not allowed in this PLMN - * 16 == MSC temporarily not reachable - * 40 == No PDP context activated - */ - int reasonDataDenied; - /** - * The maximum number of simultaneous Data Calls must be established using setupDataCall(). - */ - int maxDataCalls; - CellIdentity cellIdentity; - /** - * Network capabilities for voice over PS services. This info is valid only on LTE network and - * must be present when device is camped on LTE. vopsInfo must be empty when device is camped - * only on 2G/3G. - */ - @nullable LteVopsInfo lteVopsInfo; - /** - * The parameters of NR 5G Non-Standalone. This value is only valid on E-UTRAN, otherwise - * must be empty. - */ - NrIndicators nrIndicators; -} diff --git a/radio/aidl/android/hardware/radio/IRadio.aidl b/radio/aidl/android/hardware/radio/IRadio.aidl deleted file mode 100644 index ebf3c9b565..0000000000 --- a/radio/aidl/android/hardware/radio/IRadio.aidl +++ /dev/null @@ -1,2012 +0,0 @@ -/* - * 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.radio; - -import android.hardware.radio.AccessNetwork; -import android.hardware.radio.CallForwardInfo; -import android.hardware.radio.CardPowerState; -import android.hardware.radio.CarrierRestrictions; -import android.hardware.radio.CdmaBroadcastSmsConfigInfo; -import android.hardware.radio.CdmaRoamingType; -import android.hardware.radio.CdmaSmsAck; -import android.hardware.radio.CdmaSmsMessage; -import android.hardware.radio.CdmaSmsWriteArgs; -import android.hardware.radio.CdmaSubscriptionSource; -import android.hardware.radio.DataProfileInfo; -import android.hardware.radio.DataRequestReason; -import android.hardware.radio.DataThrottlingAction; -import android.hardware.radio.DeviceStateType; -import android.hardware.radio.Dial; -import android.hardware.radio.EmergencyCallRouting; -import android.hardware.radio.EmergencyServiceCategory; -import android.hardware.radio.GsmBroadcastSmsConfigInfo; -import android.hardware.radio.GsmSmsMessage; -import android.hardware.radio.IRadioIndication; -import android.hardware.radio.IRadioResponse; -import android.hardware.radio.IccIo; -import android.hardware.radio.ImsSmsMessage; -import android.hardware.radio.ImsiEncryptionInfo; -import android.hardware.radio.IndicationFilter; -import android.hardware.radio.KeepaliveRequest; -import android.hardware.radio.LinkAddress; -import android.hardware.radio.NetworkScanRequest; -import android.hardware.radio.NrDualConnectivityState; -import android.hardware.radio.NvItem; -import android.hardware.radio.NvWriteItem; -import android.hardware.radio.PersoSubstate; -import android.hardware.radio.PhonebookRecordInfo; -import android.hardware.radio.PreferredNetworkType; -import android.hardware.radio.RadioAccessFamily; -import android.hardware.radio.RadioAccessNetworks; -import android.hardware.radio.RadioAccessSpecifier; -import android.hardware.radio.RadioBandMode; -import android.hardware.radio.RadioCapability; -import android.hardware.radio.RadioTechnology; -import android.hardware.radio.ResetNvType; -import android.hardware.radio.SelectUiccSub; -import android.hardware.radio.SignalThresholdInfo; -import android.hardware.radio.SimApdu; -import android.hardware.radio.SimLockMultiSimPolicy; -import android.hardware.radio.SliceInfo; -import android.hardware.radio.SmsAcknowledgeFailCause; -import android.hardware.radio.SmsWriteArgs; -import android.hardware.radio.TrafficDescriptor; -import android.hardware.radio.TtyMode; - -/** - * This interface is used by telephony and telecom to talk to cellular radio. - * All the functions have minimum one parameter: - * serial: which corresponds to serial no. of request. Serial numbers must only be memorized for the - * duration of a method call. If clients provide colliding serials (including passing the same - * serial to different methods), multiple responses (one for each method call) must still be served. - * setResponseFunctions must work with IRadioResponse and IRadioIndication. - */ -@VintfStability -oneway interface IRadio { - /** - * Answer incoming call. Must not be called for WAITING calls. - * switchWaitingOrHoldingAndActive() must be used in this case instead - * - * @param serial Serial number of request. - * - * Response function is IRadioResponse.acceptCallResponse() - */ - void acceptCall(in int serial); - - /** - * Acknowledge successful or failed receipt of SMS previously indicated via unsol - * responseNewSms(), including acknowledgement TPDU to send as the RP-User-Data element of the - * RP-ACK or RP-ERROR PDU. - * - * @param serial Serial number of request. - * @param success true on successful receipt (send RP-ACK) - * false on failed receipt (send RP-ERROR) - * @param ackPdu acknowledgement TPDU in hexadecimal format - * - * Response callback is IRadioResponse.acknowledgeIncomingGsmSmsWithPduResponse() - */ - void acknowledgeIncomingGsmSmsWithPdu(in int serial, in boolean success, in String ackPdu); - - /** - * Acknowledge the success or failure in the receipt of SMS previously indicated - * via responseCdmaNewSms() - * - * @param serial Serial number of request. - * @param smsAck Cdma Sms ack to be sent described by CdmaSmsAck in types.hal - * - * Response callback is IRadioResponse.acknowledgeLastIncomingCdmaSmsResponse() - */ - void acknowledgeLastIncomingCdmaSms(in int serial, in CdmaSmsAck smsAck); - - /** - * Acknowledge successful or failed receipt of SMS previously indicated via unsolResponseNewSms - * - * @param serial Serial number of request. - * @param success is true on successful receipt - * (basically, AT+CNMA=1 from TS 27.005 is 0 on failed receipt - * (basically, AT+CNMA=2 from TS 27.005) - * @param cause: if success is false, this contains the failure cause as defined - * in TS 23.040, 9.2.3.22. - * - * Response function is IRadioResponse.acknowledgeLastIncomingGsmSmsResponse() - */ - void acknowledgeLastIncomingGsmSms( - in int serial, in boolean success, in SmsAcknowledgeFailCause cause); - - /** - * Reserves an unallocated pdu session id from the pool of ids. The allocated id is returned - * in the response. When the id is no longer needed, call releasePduSessionId to return it to - * the pool. - * - * Reference: 3GPP TS 24.007 section 11.2.3.1b - * - * @param serial Serial number of request. - * - * Response function is IRadioResponse.allocatePduSessionIdResponse() - */ - void allocatePduSessionId(in int serial); - - /** - * Whether uiccApplications are enabled, or disabled. - * By default uiccApplications must be enabled, unless enableUiccApplications() with enable - * being false is called. - * - * @param serial Serial number of request. - * - * Response callback is IRadioResponse.areUiccApplicationsEnabledResponse() - */ - void areUiccApplicationsEnabled(in int serial); - - /** - * Indicates that a handover was cancelled after a call to IRadio::startHandover. - * Since the handover was unsuccessful, the modem retains ownership over any of the resources - * being transferred and is still responsible for releasing them. - * - * @param serial Serial number of request. - * @param id callId The identifier of the data call which is provided in SetupDataCallResult - * - * Response function is IRadioResponse.cancelHandoverResponse() - */ - void cancelHandover(in int serial, in int callId); - - /** - * Cancel the current USSD session if one exists. - * - * @param serial Serial number of request. - * - * Response function is IRadioResponse.cancelPendingUssdResponse() - */ - void cancelPendingUssd(in int serial); - - /** - * Supplies old ICC PIN2 and new PIN2. - * - * @param serial Serial number of request. - * @param oldPin2 Old pin2 value - * @param newPin2 New pin2 value - * @param aid AID value, See ETSI 102.221 8.1 and 101.220 4, empty string if no value. - * - * Response function is IRadioResponse.changeIccPin2ForAppResponse() - */ - void changeIccPin2ForApp(in int serial, in String oldPin2, in String newPin2, in String aid); - - /** - * Supplies old ICC PIN and new PIN. - * - * @param serial Serial number of request. - * @param oldPin Old pin value - * @param newPin New pin value - * @param aid AID value, See ETSI 102.221 8.1 and 101.220 4, empty string if no value. - * - * Response function is IRadioResponse.changeIccPinForAppResponse() - */ - void changeIccPinForApp(in int serial, in String oldPin, in String newPin, in String aid); - - /** - * Conference holding and active (like AT+CHLD=3) - * - * @param serial Serial number of request. - * - * Response function is IRadioResponse.conferenceResponse() - */ - void conference(in int serial); - - /** - * Deactivate packet data connection and remove from the data call list. An - * unsolDataCallListChanged() must be sent when data connection is deactivated. - * - * @param serial Serial number of request. - * @param cid Data call id. - * @param reason The request reason. Must be normal, handover, or shutdown. - * - * Response function is IRadioResponse.deactivateDataCallResponse() - */ - void deactivateDataCall(in int serial, in int cid, in DataRequestReason reason); - - /** - * Deletes a CDMA SMS message from RUIM memory. - * - * @param serial Serial number of request. - * @param index record index of the message to delete - * - * Response callback is IRadioResponse.deleteSmsOnRuimResponse() - */ - void deleteSmsOnRuim(in int serial, in int index); - - /** - * Deletes a SMS message from SIM memory. - * - * @param serial Serial number of request. - * @param index Record index of the message to delete. - * - * Response function is IRadioResponse.deleteSmsOnSimResponse() - */ - void deleteSmsOnSim(in int serial, in int index); - - /** - * Initiate voice call. This method is never used for supplementary service codes. - * - * @param serial Serial number of request. - * @param dialInfo Dial struct - * - * Response function is IRadioResponse.dialResponse() - */ - void dial(in int serial, in Dial dialInfo); - - /** - * Initiate emergency voice call, with zero or more emergency service category(s), zero or - * more emergency Uniform Resource Names (URN), and routing information for handling the call. - * Android uses this request to make its emergency call instead of using IRadio.dial if the - * 'address' in the 'dialInfo' field is identified as an emergency number by Android. - * - * In multi-sim scenario, if the emergency number is from a specific subscription, this radio - * request can still be sent out on the other subscription as long as routing is set to - * EmergencyNumberRouting#EMERGENCY. This radio request will not be sent on an inactive - * (PIN/PUK locked) subscription unless both subscriptions are PIN/PUK locked. In this case, - * the request will be sent on the primary subscription. - * - * Some countries or carriers require some emergency numbers that must be handled with normal - * call routing if possible or emergency routing. 1) if the 'routing' field is specified as - * EmergencyNumberRouting#NORMAL, the implementation must try the full radio service to use - * normal call routing to handle the call; if service cannot support normal routing, the - * implementation must use emergency routing to handle the call. 2) if 'routing' is specified - * as EmergencyNumberRouting#EMERGENCY, the implementation must use emergency routing to handle - * the call. 3) if 'routing' is specified as EmergencyNumberRouting#UNKNOWN, Android does not - * know how to handle the call. - * - * If the dialed emergency number does not have a specified emergency service category, the - * 'categories' field is set to EmergencyServiceCategory#UNSPECIFIED; if the dialed emergency - * number does not have specified emergency Uniform Resource Names, the 'urns' field is set to - * an empty list. If the underlying technology used to request emergency services does not - * support the emergency service category or emergency uniform resource names, the field - * 'categories' or 'urns' may be ignored. - * - * In the scenarios that the 'address' in the 'dialInfo' field has other functions besides the - * emergency number function, if the 'hasKnownUserIntentEmergency' field is true, the user's - * intent for this dial request is emergency call, and the modem must treat this as an actual - * emergency dial; if the 'hasKnownUserIntentEmergency' field is false, Android does not know - * user's intent for this call. - * - * If 'isTesting' is true, this request is for testing purpose, and must not be sent to a real - * emergency service; otherwise it's for a real emergency call request. - * - * Reference: 3gpp 22.101, Section 10 - Emergency Calls; - * 3gpp 23.167, Section 6 - Functional description; - * 3gpp 24.503, Section 5.1.6.8.1 - General; - * RFC 5031 - * - * @param serial Serial number of request. - * @param dialInfo the same Dial information used by IRadio.dial. - * @param categories bitfield the Emergency Service Category(s) - * of the call. - * @param urns the emergency Uniform Resource Names (URN) - * @param routing EmergencyCallRouting the emergency call routing information. - * @param hasKnownUserIntentEmergency Flag indicating if user's intent for the emergency call - * is known. - * @param isTesting Flag indicating if this request is for testing purpose. - * - * Response function is IRadioResponse.emergencyDialResponse() - */ - void emergencyDial(in int serial, in Dial dialInfo, in EmergencyServiceCategory categories, - in String[] urns, in EmergencyCallRouting routing, - in boolean hasKnownUserIntentEmergency, in boolean isTesting); - - /** - * Toggle logical modem on/off. This is similar to IRadio.setRadioPower(), however that - * does not enforce that radio power is toggled only for the corresponding radio and certain - * vendor implementations do it for all radios. This new API should affect only the modem for - * which it is called. A modem stack must be on/active only when both setRadioPower() and - * enableModem() are set to on for it. - * - * SIM must be read if available even if modem is off/inactive. - * - * @param serial Serial number of request. - * @param on True to turn on the logical modem, otherwise turn it off. - * - * Response function is IRadioResponse.enableModemResponse() - */ - void enableModem(in int serial, in boolean on); - - /** - * Enable or disable UiccApplications on the SIM. If disabled: - * - Modem will not register on any network. - * - SIM must be PRESENT, and the IccId of the SIM must still be accessible. - * - The corresponding modem stack is still functional, e.g. able to make emergency calls or - * do network scan. - * By default if this API is not called, the uiccApplications must be enabled automatically. - * It must work for both single SIM and DSDS cases for UX consistency. - * The preference is per SIM, and must be remembered over power cycle, modem reboot, or SIM - * insertion / unplug. - * - * @param serial Serial number of request. - * @param enable true if to enable uiccApplications, false to disable. - * - * Response callback is IRadioResponse.enableUiccApplicationsResponse() - */ - void enableUiccApplications(in int serial, in boolean enable); - - /** - * Request the radio's system selection module to exit emergency callback mode. Radio must not - * respond with SUCCESS until the modem has completely exited from Emergency Callback Mode. - * - * @param serial Serial number of request. - * - * Response callback is IRadioResponse.exitEmergencyCallbackModeResponse() - */ - void exitEmergencyCallbackMode(in int serial); - - /** - * Connects the two calls and disconnects the subscriber from both calls. - * - * @param serial Serial number of request. - * - * Response callback is IRadioResponse.explicitCallTransferResponse() - */ - void explicitCallTransfer(in int serial); - - /** - * Get carrier restrictions. - * - * @param serial Serial number of request. - * - * Response callback is IRadioResponse.getAllowedCarriersResponse() - */ - void getAllowedCarriers(in int serial); - - /** - * Requests bitmap representing the currently allowed network types. - * getPreferredNetworkType, getPreferredNetworkTypesBitmap will not be called anymore - * except for IRadio v1.5 or older devices. - * - * @param serial Serial number of request. - * - * Response callback is IRadioResponse.getAllowedNetworkTypesBitmapResponse() - */ - void getAllowedNetworkTypesBitmap(in int serial); - - /** - * Get the list of band modes supported by RF. - * - * @param serial Serial number of request. - * - * Response function is IRadioResponse.getAvailableBandModesResponse() - */ - void getAvailableBandModes(in int serial); - - /** - * Scans for available networks - * - * @param serial Serial number of request. - * - * Response function is IRadioResponse.getAvailableNetworksResponse() - */ - void getAvailableNetworks(in int serial); - - /** - * Get all the barring info for the current camped cell applicable to the current user. - * - * @param serial Serial number of request. - * - * Response callback is IRadioResponse.getBarringInfoResponse() - */ - void getBarringInfo(in int serial); - - /** - * Return string value indicating baseband version, eg response from AT+CGMR - * - * @param serial Serial number of request. - * - * Response function is IRadioResponse.getBasebandVersionResponse() - */ - void getBasebandVersion(in int serial); - - /** - * Request the device MDN / H_SID / H_NID. The request is only allowed when CDMA subscription - * is available. When CDMA subscription is changed, application layer must re-issue the request - * to update the subscription information. - * - * @param serial Serial number of request. - * - * Response callback is IRadioResponse.getCDMASubscriptionResponse() - */ - void getCDMASubscription(in int serial); - - /** - * Request call forward status. - * - * @param serial Serial number of request. - * @param callInfo CallForwardInfo - * - * Response function is IRadioResponse.getCallForwardStatusResponse() - */ - void getCallForwardStatus(in int serial, in CallForwardInfo callInfo); - - /** - * Query current call waiting state - * - * @param serial Serial number of request. - * @param serviceClass Service class is the TS 27.007 service class to query - * - * Response function is IRadioResponse.getCallWaitingResponse() - */ - void getCallWaiting(in int serial, in int serviceClass); - - /** - * Request the setting of CDMA Broadcast SMS config - * - * @param serial Serial number of request. - * - * Response callback is IRadioResponse.getCdmaBroadcastConfigResponse() - */ - void getCdmaBroadcastConfig(in int serial); - - /** - * Request the actual setting of the roaming preferences in CDMA in the modem - * - * @param serial Serial number of request. - * - * Response callback is IRadioResponse.getCdmaRoamingPreferenceResponse() - */ - void getCdmaRoamingPreference(in int serial); - - /** - * Request to query the location where the CDMA subscription shall be retrieved. - * - * @param serial Serial number of request. - * - * Response callback is IRadioResponse.getCdmaSubscriptionSourceResponse() - */ - void getCdmaSubscriptionSource(in int serial); - - /** - * Request all of the current cell information known to the radio. The radio must return a list - * of all current cells, including the neighboring cells. If for a particular cell information - * isn't known then the appropriate unknown value will be returned. - * This does not cause or change the rate of unsolicited cellInfoList(). - * - * @param serial Serial number of request. - * - * Response callback is IRadioResponse.getCellInfoListResponse() - */ - void getCellInfoList(in int serial); - - /** - * Queries the status of the CLIP supplementary service (for MMI code "*#30#") - * - * @param serial Serial number of request. - * - * Response function is IRadioResponse.getClipResponse() - */ - void getClip(in int serial); - - /** - * Gets current CLIR status - * - * @param serial Serial number of request. - * - * Response function is IRadioResponse.getClirResponse() - */ - void getClir(in int serial); - - /** - * Requests current call list - * - * @param serial Serial number of request. - * - * Response function is IRadioResponse.getCurrentCallsResponse() - */ - void getCurrentCalls(in int serial); - - /** - * Returns the data call list. An entry is added when a setupDataCall() is issued and removed - * on a deactivateDataCall(). The list is emptied when setRadioPower() off/on issued or when - * the vendor HAL or modem crashes. - * - * @param serial Serial number of request. - * - * Response function is IRadioResponse.getDataCallListResponse() - */ - void getDataCallList(in int serial); - - /** - * Request current data registration state. - * - * @param serial Serial number of request. - * - * Response function is IRadioResponse.getDataRegistrationStateResponse() - */ - void getDataRegistrationState(in int serial); - - /** - * Request the device ESN / MEID / IMEI / IMEISV. The request is always allowed and contains - * GSM and CDMA device identity. When CDMA subscription is changed the ESN/MEID changes. - * The application layer must re-issue the request to update the device identity in this case. - * - * @param serial Serial number of request. - * - * Response callback is IRadioResponse.getDeviceIdentityResponse() - */ - void getDeviceIdentity(in int serial); - - /** - * Query the status of a facility lock state - * - * @param serial Serial number of request. - * @param facility is the facility string code from TS 27.007 7.4 - * (eg "AO" for BAOC, "SC" for SIM lock) - * @param password is the password, or "" if not required - * @param serviceClass is the TS 27.007 service class bit vector of services to query - * @param appId is AID value, See ETSI 102.221 8.1 and 101.220 4, empty string if no value. - * This is only applicable in the case of Fixed Dialing Numbers (FDN) requests. - * - * Response function is IRadioResponse.getFacilityLockForAppResponse() - */ - void getFacilityLockForApp(in int serial, in String facility, in String password, - in int serviceClass, in String appId); - - /** - * Request the setting of GSM/WCDMA Cell Broadcast SMS config. - * - * @param serial Serial number of request. - * - * Response callback is IRadioResponse.getGsmBroadcastConfigResponse() - */ - void getGsmBroadcastConfig(in int serial); - - /** - * Request all of the current hardware (modem and sim) associated with Radio. - * - * @param serial Serial number of request. - * - * Response callback is IRadioResponse.getHardwareConfigResponse() - */ - void getHardwareConfig(in int serial); - - /** - * Requests status of the ICC card - * - * @param serial Serial number of request. - * - * Response function is IRadioResponse.getIccCardStatusResponse() - * - */ - void getIccCardStatus(in int serial); - - /** - * Request current IMS registration state - * - * @param serial Serial number of request. - * - * Response callback is IRadioResponse.getImsRegistrationStateResponse() - */ - void getImsRegistrationState(in int serial); - - /** - * Get the SIM IMSI. Only valid when radio state is "RADIO_STATE_ON" - * - * @param serial Serial number of request. - * @param aid AID value, See ETSI 102.221 8.1 and 101.220 4, empty string if no value. - * - * Response function is IRadioResponse.getImsiForAppResponse() - * - */ - void getImsiForApp(in int serial, in String aid); - - /** - * Requests the failure cause code for the most recently terminated call. - * - * @param serial Serial number of request. - * - * Response function is IRadioResponse.getLastCallFailCauseResponse() - * - */ - void getLastCallFailCause(in int serial); - - /** - * Get modem activity information for power consumption estimation. Request clear-on-read - * statistics information that is used for estimating the per-millisecond power consumption - * of the cellular modem. - * - * @param serial Serial number of request. - * - * Response callback is IRadioResponse.getModemActivityInfoResponse() - */ - void getModemActivityInfo(in int serial); - - /** - * Request status of logical modem. It returns isEnabled=true if the logical modem is on. - * This method is the getter method for enableModem. - * - * @param serial Serial number of request. - * - * Response function is IRadioResponse.getModemStackStatusResponse() - */ - void getModemStackStatus(in int serial); - - /** - * Queries the current state of the uplink mute setting - * - * @param serial Serial number of request. - * - * Response function is IRadioResponse.getMuteResponse() - */ - void getMute(in int serial); - - /** - * Request neighboring cell id in GSM network - * - * @param serial Serial number of request. - * - * Response callback is IRadioResponse.getNeighboringCidsResponse() - */ - void getNeighboringCids(in int serial); - - /** - * Query current network selection mode - * - * @param serial Serial number of request. - * - * Response function is IRadioResponse.getNetworkSelectionModeResponse() - */ - void getNetworkSelectionMode(in int serial); - - /** - * Request current operator ONS or EONS - * - * @param serial Serial number of request. - * - * Response function is IRadioResponse.getOperatorResponse() - */ - void getOperator(in int serial); - - /** - * Query the preferred network type (CS/PS domain, RAT, and operation mode) - * for searching and registering - * - * @param serial Serial number of request. - * - * Response callback is IRadioResponse.getPreferredNetworkTypeResponse() - */ - void getPreferredNetworkType(in int serial); - - /** - * Query the preferred network type bitmap. - * - * @param serial Serial number of request. - * - * Response callback is IRadioResponse.getPreferredNetworkTypeBitmapResponse() - */ - void getPreferredNetworkTypeBitmap(in int serial); - - /** - * Request the setting of preferred voice privacy mode. - * - * @param serial Serial number of request. - * - * Response callback is IRadioResponse.getPreferredVoicePrivacyResponse() - */ - void getPreferredVoicePrivacy(in int serial); - - /** - * Used to get phone radio capability. - * - * @param serial Serial number of request. - * - * Response callback is IRadioResponse.getRadioCapabilityResponse() - */ - void getRadioCapability(in int serial); - - /** - * Requests current signal strength and associated information. Must succeed if radio is on. - * - * @param serial Serial number of request. - * - * Response function is IRadioResponse.getSignalStrengthResponse() - */ - void getSignalStrength(in int serial); - - /** - * Get the phone book capacity - * - * @param serial Serial number of request. - * - * Response function is defined from IRadioResponse.getSimPhonebookCapacityResponse() - */ - void getSimPhonebookCapacity(in int serial); - - /** - * Get the local and global phonebook records from the SIM card. - * This should be called again after a simPhonebookChanged notification is received. - * The phonebook records are received via IRadioIndication.simPhonebookRecordsReceived() - * - * @param serial Serial number of request. - * - * Response callback is IRadioResponse.getSimPhonebookRecordsResponse() - */ - void getSimPhonebookRecords(in int serial); - - /** - * Request to get 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. - * - * Response function is IRadioResponse.getSlicingConfigResponse() - */ - void getSlicingConfig(in int serial); - - /** - * Get the default Short Message Service Center address on the device. - * - * @param serial Serial number of request. - * - * Response callback is IRadioResponse.getSmscAddressResponse() - */ - void getSmscAddress(in int serial); - - /** - * Get which bands the modem's background scan is acting on. - * - * @param serial Serial number of request. - * - * Response callback is IRadioResponse.getSystemSelectionChannelsResponse() - */ - void getSystemSelectionChannels(in int serial); - - /** - * Request the setting of TTY mode - * - * @param serial Serial number of request. - * - * Response callback is IRadioResponse.getTTYModeResponse() - */ - void getTTYMode(in int serial); - - /** - * Query the radio technology type (3GPP/3GPP2) used for voice. Query is valid only - * when radio state is not RADIO_STATE_UNAVAILABLE - * - * @param serial Serial number of request. - * - * Response callback is IRadioResponse.getVoiceRadioTechnologyResponse() - */ - void getVoiceRadioTechnology(in int serial); - - /** - * Request current voice registration state. - * - * @param serial Serial number of request. - * - * Response function is IRadioResponse.getVoiceRegistrationStateResponse() - */ - void getVoiceRegistrationState(in int serial); - - /** - * When STK application gets stkCallSetup(), the call actually has been initialized by the - * mobile device already. (We could see the call has been in the 'call list'). STK application - * needs to accept/reject the call according to user operations. - * - * @param serial Serial number of request. - * @param accept true = accept the call setup, false = reject the call setup - * - * Response callback is IRadioResponse.handleStkCallSetupRequestFromSimResponse() - */ - void handleStkCallSetupRequestFromSim(in int serial, in boolean accept); - - /** - * Hang up a specific line (like AT+CHLD=1x). After this HANGUP request returns, Radio must - * show the connection is NOT active anymore in next getCurrentCalls() query. - * - * @param serial Serial number of request. - * @param gsmIndex Connection index (value of 'x' in CHLD above) - * - * Response function is IRadioResponse.hangupResponse() - */ - void hangup(in int serial, in int gsmIndex); - - /** - * Hang up waiting or held (like AT+CHLD=1). After this HANGUP request returns, Radio must show - * the connection is NOT active anymore in next getCurrentCalls() query. - * - * @param serial Serial number of request. - * - * Response function is IRadioResponse.hangupForegroundResumeBackgroundResponse() - */ - void hangupForegroundResumeBackground(in int serial); - - /** - * Hang up waiting or held (like AT+CHLD=0). After this HANGUP request returns, Radio must show - * the connection is NOT active anymore in next getCurrentCalls() query. - * - * @param serial Serial number of request. - * - * Response function is IRadioResponse.hangupWaitingOrBackgroundResponse() - */ - void hangupWaitingOrBackground(in int serial); - - /** - * Close a previously opened logical channel. This command reflects TS 27.007 - * "close logical channel" operation (+CCHC). - * - * @param serial Serial number of request. - * @param channelId session id of the logical channel (+CCHC). - * - * Response callback is IRadioResponse.iccCloseLogicalChannelResponse() - */ - void iccCloseLogicalChannel(in int serial, in int channelId); - - /** - * Request ICC I/O operation. This is similar to the TS 27.007 "restricted SIM" operation where - * it assumes all of the EF selection must be done by the callee. Arguments and responses that - * are unused for certain values of "command" must be ignored or set to empty string. - * Note that IccIo has a "PIN2" field which may be empty string, or may specify a PIN2 for - * operations that require a PIN2 (eg updating FDN records). - * - * @param serial Serial number of request. - * @param iccIo IccIo - * - * Response function is IRadioResponse.iccIOForAppResponse() - */ - void iccIOForApp(in int serial, in IccIo iccIo); - - /** - * Open a new logical channel and select the given application. This command - * reflects TS 27.007 "open logical channel" operation (+CCHO). - * - * @param serial Serial number of request. - * @param aid AID value, See ETSI 102.221 and 101.220. - * @param p2 P2 value, described in ISO 7816-4. Ignore if equal to RadioConst:P2_CONSTANT_NO_P2 - * - * Response callback is IRadioResponse.iccOpenLogicalChannelResponse() - */ - void iccOpenLogicalChannel(in int serial, in String aid, in int p2); - - /** - * Request APDU exchange on the basic channel. This command reflects TS 27.007 - * "generic SIM access" operation (+CSIM). The modem must ensure proper function of GSM/CDMA, - * and filter commands appropriately. It must filter channel management and SELECT by DF - * name commands. "sessionid" field must be ignored. - * - * @param serial Serial number of request. - * @param message SimApdu as defined in types.hal to be sent - * - * Response callback is IRadioResponse.iccTransmitApduBasicChannelResponse() - */ - void iccTransmitApduBasicChannel(in int serial, in SimApdu message); - - /** - * Exchange APDUs with a UICC over a previously opened logical channel. This command reflects - * TS 27.007 "generic logical channel access" operation (+CGLA). The modem must filter channel - * management and SELECT by DF name commands. - * - * @param serial Serial number of request. - * @param message SimApdu as defined in types.hal to be sent - * - * Response callback is IRadioResponse.iccTransmitApduLogicalChannelResponse() - */ - void iccTransmitApduLogicalChannel(in int serial, in SimApdu message); - - /** - * Is E-UTRA-NR Dual Connectivity enabled - * - * @param serial Serial number of request. - * Response callback is IRadioResponse.isNrDualConnectivityEnabledResponse() - */ - void isNrDualConnectivityEnabled(in int serial); - - /** - * Read one of the radio NV items. - * This is used for device configuration by some CDMA operators. - * - * @param serial Serial number of request. - * @param itemId NvItem is radio NV item as defined in types.hal - * - * Response callback is IRadioResponse.nvReadItemResponse() - */ - void nvReadItem(in int serial, in NvItem itemId); - - /** - * Reset the radio NV configuration to the factory state. - * This is used for device configuration by some CDMA operators. - * - * @param serial Serial number of request. - * @param resetType ResetNvType as defined in types.hal - * - * Response callback is IRadioResponse.nvResetConfigResponse() - */ - void nvResetConfig(in int serial, in ResetNvType resetType); - - /** - * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage. - * This is used for device configuration by some CDMA operators. - * - * @param serial Serial number of request. - * @param prl PRL as a byte array - * - * Response callback is IRadioResponse.nvWriteCdmaPrlResponse() - */ - void nvWriteCdmaPrl(in int serial, in byte[] prl); - - /** - * Write one of the radio NV items. - * This is used for device configuration by some CDMA operators. - * - * @param serial Serial number of request. - * @param item NvWriteItem as defined in types.hal - * - * Response callback is IRadioResponse.nvWriteItemResponse() - */ - void nvWriteItem(in int serial, in NvWriteItem item); - - /** - * Send UDUB (user determined user busy) to ringing or waiting call answer) - * - * @param serial Serial number of request. - * - * Response function is IRadioResponse.rejectCallResponse() - */ - void rejectCall(in int serial); - - /** - * Releases a pdu session id that was previously allocated using allocatePduSessionId. - * Reference: 3GPP TS 24.007 section 11.2.3.1b - * - * @param serial Serial number of request. - * @param id Pdu session id to release. - * - * Response function is IRadioResponse.releasePduSessionIdResponse() - */ - void releasePduSessionId(in int serial, in int id); - - /** - * Indicates whether there is storage available for new SMS messages. - * - * @param serial Serial number of request. - * @param available true if memory is available for storing new messages, - * false if memory capacity is exceeded - * - * Response callback is IRadioResponse.reportSmsMemoryStatusResponse() - */ - void reportSmsMemoryStatus(in int serial, in boolean available); - - /** - * Indicates that the StkService is running and is ready to receive unsolicited stk commands. - * - * @param serial Serial number of request. - * - * Response callback is IRadioResponse.reportStkServiceIsRunningResponse() - */ - void reportStkServiceIsRunning(in int serial); - - /** - * Returns the response of SIM Authentication through Radio challenge request. - * - * @param serial Serial number of request. - * @param authContext P2 value of authentication command, see P2 parameter in - * 3GPP TS 31.102 7.1.2 - * @param authData the challenge string in Base64 format, see 3GPP TS 31.102 7.1.2 - * @param aid AID value, See ETSI 102.221 8.1 and 101.220 4, empty string if no value - * - * Response callback is IRadioResponse.requestIccSimAuthenticationResponse() - */ - void requestIccSimAuthentication( - in int serial, in int authContext, in String authData, in String aid); - - /** - * Request the ISIM application on the UICC to perform AKA challenge/response algorithm - * for IMS authentication - * - * @param serial Serial number of request. - * @param challenge challenge string in Base64 format - * - * Response callback is IRadioResponse.requestIsimAuthenticationResponse() - */ - void requestIsimAuthentication(in int serial, in String challenge); - - /** - * Device is shutting down. All further commands are ignored and RADIO_NOT_AVAILABLE - * must be returned. - * - * @param serial Serial number of request. - * - * Response callback is IRadioResponse.requestShutdownResponse() - */ - void requestShutdown(in int serial); - - /** - * When response type received from a radio indication or radio response is - * RadioIndicationType:UNSOLICITED_ACK_EXP or RadioResponseType:SOLICITED_ACK_EXP respectively, - * acknowledge the receipt of those messages by sending responseAcknowledgement(). - */ - void responseAcknowledgement(); - - /** - * Send DTMF string - * - * @param serial Serial number of request. - * @param dtmf DTMF string - * @param on DTMF ON length in milliseconds, or 0 to use default - * @param off is the DTMF OFF length in milliseconds, or 0 to use default - * - * Response callback is IRadioResponse.sendBurstDtmfResponse() - */ - void sendBurstDtmf(in int serial, in String dtmf, in int on, in int off); - - /** - * Send FLASH command - * - * @param serial Serial number of request. - * @param featureCode String associated with Flash command - * - * Response callback is IRadioResponse.sendCDMAFeatureCodeResponse() - */ - void sendCDMAFeatureCode(in int serial, in String featureCode); - - /** - * Send a CDMA SMS message - * - * @param serial Serial number of request. - * @param sms Cdma Sms to be sent described by CdmaSmsMessage in types.hal - * - * Response callback is IRadioResponse.sendCdmaSmsResponse() - */ - void sendCdmaSms(in int serial, in CdmaSmsMessage sms); - - /** - * Send an SMS message. Identical to sendCdmaSms, except that more messages are expected to be - * sent soon. - * - * @param serial Serial number of request. - * @param sms Cdma Sms to be sent described by CdmaSmsMessage in types.hal - * - * Response callback is IRadioResponse.sendCdmaSMSExpectMoreResponse() - */ - void sendCdmaSmsExpectMore(in int serial, in CdmaSmsMessage sms); - - /** - * Send the updated device state. This is providing the device state information for the modem - * to perform power saving strategies. - * - * @param serial Serial number of request. - * @param deviceStateType The updated device state type. - * @param state The updated state. See the definition of state at DeviceStateType. - * - * Response callback is IRadioResponse.sendDeviceStateResponse() - */ - void sendDeviceState(in int serial, in DeviceStateType deviceStateType, in boolean state); - - /** - * Send a DTMF tone. If the implementation is currently playing a tone requested via - * startDtmf(), that tone must be cancelled and the new tone must be played instead. - * - * @param serial Serial number of request. - * @param s string with single char having one of 12 values: 0-9, *, # - * - * Response function is IRadioResponse.sendDtmfResponse() - */ - void sendDtmf(in int serial, in String s); - - /** - * Requests to send a SAT/USAT envelope command to SIM. - * The SAT/USAT envelope command refers to 3GPP TS 11.14 and 3GPP TS 31.111 - * - * @param serial Serial number of request. - * @param command SAT/USAT command in hexadecimal format string starting with command tag - * - * Response function is IRadioResponse.sendEnvelopeResponse() - */ - void sendEnvelope(in int serial, in String command); - - /** - * Requests to send a SAT/USAT envelope command to SIM. The SAT/USAT envelope command refers to - * 3GPP TS 11.14 and 3GPP TS 31.111. This request has one difference from sendEnvelope(): - * The SW1 and SW2 status bytes from the UICC response are returned along with the response - * data, using the same structure as iccIOForApp(). The implementation must perform normal - * processing of a '91XX' response in SW1/SW2 to retrieve the pending proactive command and - * send it as an unsolicited response, as sendEnvelope() does. - * - * @param serial Serial number of request. - * @param contents SAT/USAT command in hexadecimal format starting with command tag - * - * Response callback is IRadioResponse.sendEnvelopeWithStatusResponse() - */ - void sendEnvelopeWithStatus(in int serial, in String contents); - - /** - * Send a SMS message over IMS. Based on the return error, caller decides to resend if sending - * sms fails. SMS_SEND_FAIL_RETRY means retry, and other errors means no retry. - * In case of retry, data is encoded based on Voice Technology available. - * - * @param serial Serial number of request. - * @param message ImsSmsMessage as defined in types.hal to be sent - * - * Response callback is IRadioResponse.sendImsSmsResponse() - */ - void sendImsSms(in int serial, in ImsSmsMessage message); - - /** - * Send an SMS message. Based on the returned error, caller decides to resend if sending sms - * fails. RadioError:SMS_SEND_FAIL_RETRY means retry (i.e. error cause is 332) and - * RadioError:GENERIC_FAILURE means no retry (i.e. error cause is 500) - * - * @param serial Serial number of request. - * @param message GsmSmsMessage as defined in types.hal - * - * Response function is IRadioResponse.sendSmsResponse() - */ - void sendSms(in int serial, in GsmSmsMessage message); - - /** - * Send an SMS message. Identical to sendSms, except that more messages are expected to be sent - * soon. If possible, keep SMS relay protocol link open (eg TS 27.005 AT+CMMS command). - * Based on the return error, caller decides to resend if sending sms fails. - * RadioError:SMS_SEND_FAIL_RETRY means retry (i.e. error cause is 332) and - * RadioError:GENERIC_FAILURE means no retry (i.e. error cause is 500) - * - * @param serial Serial number of request. - * @param message GsmSmsMessage as defined in types.hal - * - * Response function is IRadioResponse.sendSmsExpectMoreResponse() - */ - void sendSmsExpectMore(in int serial, in GsmSmsMessage message); - - /** - * Requests to send a terminal response to SIM for a received proactive command - * - * @param serial Serial number of request. - * @param commandResponse SAT/USAT response in hexadecimal format string starting with - * first byte of response data - * - * Response function is IRadioResponse.sendTerminalResponseResponseToSim() - */ - void sendTerminalResponseToSim(in int serial, in String commandResponse); - - /** - * Send a USSD message. If a USSD session already exists, the message must be sent in the - * context of that session. Otherwise, a new session must be created. The network reply must be - * reported via unsolOnUssd. - * - * Only one USSD session must exist at a time, and the session is assumed to exist until: - * a) The android system invokes cancelUssd() - * b) The implementation sends a unsolOnUssd() with a type code of - * "0" (USSD-Notify/no further action) or "2" (session terminated) - * - * @param serial Serial number of request. - * @param ussd string containing the USSD request in UTF-8 format - * - * Response function is IRadioResponse.sendUssdResponse() - * - * See also requestCancelUssd, unsolOnUssd - */ - void sendUssd(in int serial, in String ussd); - - /** - * Separate a party from a multiparty call placing the multiparty call (less the specified - * party) on hold and leaving the specified party as the only other member of the current - * (active) call. Like AT+CHLD=2x. - * - * See TS 22.084 1.3.8.2 (iii) - * TS 22.030 6.5.5 "Entering "2X followed by send" - * TS 27.007 "AT+CHLD=2x" - * - * @param serial Serial number of request. - * @param gsmIndex contains Connection index (value of 'x' in CHLD above) - * - * Response function is IRadioResponse.separateConnectionResponse() - */ - void separateConnection(in int serial, in int gsmIndex); - - /** - * Set carrier restrictions. Expected modem behavior: - * If never receives this command: - * - Must allow all carriers - * Receives this command: - * - Only allow carriers specified in carriers. The restriction persists across power cycles - * and FDR. If a present SIM is allowed, modem must not reload the SIM. If a present SIM is - * *not* allowed, modem must detach from the registered network and only keep emergency - * service, and notify Android SIM refresh reset with new SIM state being - * CardState:RESTRICTED. Emergency service must be enabled. - * - * @param serial Serial number of request. - * @param carriers CarrierRestrictions consisting allowed and excluded carriers - * @param multiSimPolicy Policy to be used for devices with multiple SIMs. - * - * Response callback is IRadioResponse.setAllowedCarriersResponse() - */ - void setAllowedCarriers(in int serial, in CarrierRestrictions carriers, - in SimLockMultiSimPolicy multiSimPolicy); - - /** - * Requests to set the network type for searching and registering. Instruct the radio to - * *only* accept the types of network provided. setPreferredNetworkTypesBitmap and - * setPreferredNetworkType will not be called anymore except for IRadio v1.5 or older devices. - * In case of an emergency call, the modem is authorized to bypass this restriction. - * - * @param serial Serial number of request. - * @param networkTypeBitmap a 32-bit bearer bitmap of RadioAccessFamily - * - * Response callback is IRadioResponse.setAllowedNetworkTypesBitmapResponse() - */ - void setAllowedNetworkTypesBitmap(in int serial, in RadioAccessFamily networkTypeBitmap); - - /** - * Assign a specified band for RF configuration. - * - * @param serial Serial number of request. - * @param mode RadioBandMode defined in types.hal - * - * Response function is IRadioResponse.setBandModeResponse() - */ - void setBandMode(in int serial, in RadioBandMode mode); - - /** - * Change call barring facility password - * - * @param serial Serial number of request. - * @param facility facility string code from TS 27.007 7.4 (eg "AO" for BAOC) - * @param oldPassword old password - * @param newPassword new password - * - * Response function is IRadioResponse.setBarringPasswordResponse() - */ - void setBarringPassword( - in int serial, in String facility, in String oldPassword, in String newPassword); - - /** - * Configure call forward rule - * - * @param serial Serial number of request. - * @param callInfo CallForwardInfo - * - * Response function is IRadioResponse.setCallForwardResponse() - */ - void setCallForward(in int serial, in CallForwardInfo callInfo); - - /** - * Configure current call waiting state - * - * @param serial Serial number of request. - * @param enable is false for "disabled" and true for "enabled" - * @param serviceClass is the TS 27.007 service class bit vector of services to modify - * - * Response function is IRadioResponse.setCallWaitingResponse() - */ - void setCallWaiting(in int serial, in boolean enable, in int serviceClass); - - /** - * Provide Carrier specific information to the modem that must be used to encrypt the IMSI and - * IMPI. Sent by the framework during boot, carrier switch and everytime the framework receives - * a new certificate. - * - * @param serial Serial number of request. - * @param imsiEncryptionInfo ImsiEncryptionInfo as defined in types.hal. - * - * Response callback is IRadioResponse.setCarrierInfoForImsiEncryptionResponse() - */ - void setCarrierInfoForImsiEncryption(in int serial, in ImsiEncryptionInfo imsiEncryptionInfo); - - /** - * Enable or disable the reception of CDMA Cell Broadcast SMS - * - * @param serial Serial number of request. - * @param activate indicates to activate or turn off the reception of CDMA - * Cell Broadcast SMS. true = activate, false = turn off - * - * Response callback is IRadioResponse.setCdmaBroadcastActivationResponse() - */ - void setCdmaBroadcastActivation(in int serial, in boolean activate); - - /** - * Set CDMA Broadcast SMS config - * - * @param serial Serial number of request. - * @param configInfo CDMA Broadcast SMS config to be set. - * - * Response callback is IRadioResponse.setCdmaBroadcastConfigResponse() - */ - void setCdmaBroadcastConfig(in int serial, in CdmaBroadcastSmsConfigInfo[] configInfo); - - /** - * Request to set the roaming preferences in CDMA - * - * @param serial Serial number of request. - * @param type CdmaRoamingType defined in types.hal - * - * Response callback is IRadioResponse.setCdmaRoamingPreferenceResponse() - */ - void setCdmaRoamingPreference(in int serial, in CdmaRoamingType type); - - /** - * Request to set the location where the CDMA subscription shall be retrieved - * - * @param serial Serial number of request. - * @param cdmaSub CdmaSubscriptionSource - * - * Response callback is IRadioResponse.setCdmaSubscriptionSourceResponse() - */ - void setCdmaSubscriptionSource(in int serial, in CdmaSubscriptionSource cdmaSub); - - /** - * Sets the minimum time between when unsolicited cellInfoList() must be invoked. - * A value of 0, means invoke cellInfoList() when any of the reported information changes. - * Setting the value to INT_MAX(0x7fffffff) means never issue a unsolicited cellInfoList(). - * - * @param serial Serial number of request. - * @param rate minimum time in milliseconds to indicate time between unsolicited cellInfoList() - * - * Response callback is IRadioResponse.setCellInfoListRateResponse() - */ - void setCellInfoListRate(in int serial, in int rate); - - /** - * Set current CLIR status - * - * @param serial Serial number of request. - * @param status "n" parameter from TS 27.007 7.7 - * - * Response function is IRadioResponse.setClirResponse() - */ - void setClir(in int serial, in int status); - - /** - * Tells the modem whether data calls are allowed or not - * - * @param serial Serial number of request. - * @param allow true to allow data calls, false to disallow data calls - * - * Response callback is IRadioResponse.setDataAllowedResponse() - */ - void setDataAllowed(in int serial, in boolean allow); - - /** - * Send data profiles of the current carrier to the modem. - * - * @param serial Serial number of request. - * @param profiles Array of DataProfileInfo to set. - * - * Response callback is IRadioResponse.setDataProfileResponse() - */ - void setDataProfile(in int serial, in DataProfileInfo[] profiles); - - /** - * Control data throttling at modem. - * - DataThrottlingAction:NO_DATA_THROTTLING should clear any existing data throttling within - * the requested completion window. - * - DataThrottlingAction:THROTTLE_SECONDARY_CARRIER: Remove any existing throttling on anchor - * carrier and achieve maximum data throttling on secondary carrier within the requested - * completion window. - * - DataThrottlingAction:THROTTLE_ANCHOR_CARRIER: disable secondary carrier and achieve maximum - * data throttling on anchor carrier by requested completion window. - * - DataThrottlingAction:HOLD: Immediately hold on to current level of throttling. - * - * @param serial Serial number of request. - * @param dataThrottlingAction DataThrottlingAction as defined in types.hal - * @param completionDurationMillis window, in milliseconds, in which the requested throttling - * action has to be achieved. This must be 0 when dataThrottlingAction is - * DataThrottlingAction:HOLD. - * - * Response function is IRadioResponse.setDataThrottlingResponse() - */ - void setDataThrottling(in int serial, in DataThrottlingAction dataThrottlingAction, - in long completionDurationMillis); - - /** - * Enable/disable one facility lock - * - * @param serial Serial number of request. - * @param facility is the facility string code from TS 27.007 7.4 (eg "AO" for BAOC) - * @param lockState false for "unlock" and true for "lock" - * @param password is the password - * @param serviceClass is string representation of decimal TS 27.007 service class bit vector. - * Eg, the string "1" means "set this facility for voice services" - * @param appId is AID value, See ETSI 102.221 8.1 and 101.220 4, empty string if no value. - * This is only applicable in the case of Fixed Dialing Numbers (FDN) requests. - * - * Response function is IRadioResponse.setFacilityLockForAppResponse() - */ - void setFacilityLockForApp(in int serial, in String facility, in boolean lockState, - in String password, in int serviceClass, in String appId); - - /** - * Enable or disable the reception of GSM/WCDMA Cell Broadcast SMS - * - * @param serial Serial number of request. - * @param activate indicates to activate or turn off the reception of GSM/WCDMA - * Cell Broadcast SMS. true = activate, false = turn off - * - * Response callback is IRadioResponse.setGsmBroadcastActivationResponse() - */ - void setGsmBroadcastActivation(in int serial, in boolean activate); - - /** - * Set GSM/WCDMA Cell Broadcast SMS config - * - * @param serial Serial number of request. - * @param configInfo Setting of GSM/WCDMA Cell broadcast config - * - * Response callback is IRadioResponse.setGsmBroadcastConfigResponse() - */ - void setGsmBroadcastConfig(in int serial, in GsmBroadcastSmsConfigInfo[] configInfo); - - /** - * Sets the indication filter. Prevents the reporting of specified unsolicited indications from - * the radio. This is used for power saving in instances when those indications are not needed. - * If unset, defaults to IndicationFilter:ALL. - * - * @param serial Serial number of request. - * @param indicationFilter 32-bit bitmap of IndicationFilter. Bits set to 1 indicate the - * indications are enabled. See IndicationFilter for the definition of each bit. - * - * Response callback is IRadioResponse.setIndicationFilterResponse() - */ - void setIndicationFilter(in int serial, in IndicationFilter indicationFilter); - - /** - * Set an APN to initial attach network. - * - * @param serial Serial number of request. - * @param dataProfileInfo data profile containing APN settings - * - * Response callback is IRadioResponse.setInitialAttachApnResponse() - */ - void setInitialAttachApn(in int serial, in DataProfileInfo dataProfileInfo); - - /** - * Sets the link capacity reporting criteria. The resulting reporting criteria are the AND of - * all the supplied criteria. Note that reporting criteria must be individually set for each - * RAN. If unset, reporting criteria for that RAN are implementation-defined. - * - * Response callback is IRadioResponse.setLinkCapacityReportingCriteriaResponse(). - * - * @param serial Serial number of request. - * @param hysteresisMs A hysteresis time in milliseconds to prevent flapping. A value of 0 - * disables hysteresis. - * @param hysteresisDlKbps An interval in kbps defining the required magnitude change between DL - * reports. hysteresisDlKbps must be smaller than the smallest threshold delta. A value - * of 0 disables hysteresis. - * @param hysteresisUlKbps An interval in kbps defining the required magnitude change between UL - * reports. hysteresisUlKbps must be smaller than the smallest threshold delta. A value - * of 0 disables hysteresis. - * @param thresholdsDownlinkKbps A vector of trigger thresholds in kbps for downlink reports. A - * vector size of 0 disables the use of DL thresholds for reporting. - * @param thresholdsUplinkKbps A vector of trigger thresholds in kbps for uplink reports. A - * vector size of 0 disables the use of UL thresholds for reporting. - * @param accessNetwork The type of network for which to apply these thresholds. - */ - void setLinkCapacityReportingCriteria(in int serial, in int hysteresisMs, - in int hysteresisDlKbps, in int hysteresisUlKbps, in int[] thresholdsDownlinkKbps, - in int[] thresholdsUplinkKbps, in AccessNetwork accessNetwork); - - /** - * Enables/disables network state change notifications due to changes in LAC and/or CID (for - * GSM) or BID/SID/NID/latitude/longitude (for CDMA). Basically +CREG=2 vs. +CREG=1 (TS 27.007). - * The Radio implementation must default to "updates enabled" when the screen is on and - * "updates disabled" when the screen is off. - * - * @param serial Serial number of request. - * @param enable true=updates enabled (+CREG=2), false=updates disabled (+CREG=1) - * - * Response callback is IRadioResponse.setLocationUpdatesResponse() - */ - void setLocationUpdates(in int serial, in boolean enable); - - /** - * Turn on or off uplink (microphone) mute. Must only be sent while voice call is active. - * Must always be reset to "disable mute" when a new voice call is initiated - * - * @param serial Serial number of request. - * @param enable true for "enable mute" and false for "disable mute" - * - * Response function is IRadioResponse.setMuteResponse() - */ - void setMute(in int serial, in boolean enable); - - /** - * Specify that the network must be selected automatically. - * This request must not respond until the new operator is selected and registered. - * - * @param serial Serial number of request. - * - * Response function is IRadioResponse.setNetworkSelectionModeAutomaticResponse() - */ - void setNetworkSelectionModeAutomatic(in int serial); - - /** - * Manually select a specified network. This request must not respond until the new operator is - * selected and registered. Per TS 23.122, the RAN is just the initial suggested value. - * If registration fails, the RAN is not available afterwards, or the RAN is not within the - * network types specified by IRadio::setPreferredNetworkTypeBitmap, then the modem will need to - * select the next best RAN for network registration. - * - * @param serial Serial number of request. - * @param operatorNumeric String specifying MCCMNC of network to select (eg "310170"). - * @param ran Initial suggested radio access network type. If value is UNKNOWN, the modem - * will select the next best RAN for network registration. - * - * Response function is IRadioResponse.setNetworkSelectionModeManualResponse() - */ - void setNetworkSelectionModeManual( - in int serial, in String operatorNumeric, in RadioAccessNetworks ran); - - /** - * Enable or disable E-UTRA-NR dual connectivity. If disabled then UE will not connect - * to secondary carrier. - * - * @param serial Serial number of request. - * @param nrDualConnectivityState expected NR dual connectivity state. - * 1: Enable NR dual connectivity {NrDualConnectivityState:ENABLE} - * 2: Disable NR dual connectivity {NrDualConnectivityState:DISABLE} - * 3: Disable NR dual connectivity and force secondary cell to be released - * {NrDualConnectivityState:DISABLE_IMMEDIATE} - * - * Response callback is IRadioResponse.setNRDualConnectivityStateResponse() - */ - void setNrDualConnectivityState( - in int serial, in NrDualConnectivityState nrDualConnectivityState); - - /** - * Requests to set the preferred network type for searching and registering - * (CS/PS domain, RAT, and operation mode) - * - * @param serial Serial number of request. - * @param nwType PreferredNetworkType defined in types.hal - * - * Response callback is IRadioResponse.setPreferredNetworkTypeResponse() - */ - void setPreferredNetworkType(in int serial, in PreferredNetworkType nwType); - - /** - * Requests to set the preferred network type for searching and registering. - * - * @param serial Serial number of request. - * @param networkTypeBitmap a 32-bit bitmap of RadioAccessFamily. - * - * Response callback is IRadioResponse.setPreferredNetworkTypeBitmapResponse() - */ - void setPreferredNetworkTypeBitmap(in int serial, in RadioAccessFamily networkTypeBitmap); - - /** - * Request to set the preferred voice privacy mode used in voice scrambling. - * - * @param serial Serial number of request. - * @param enable false for Standard Privacy Mode (Public Long Code Mask) - * true for Enhanced Privacy Mode (Private Long Code Mask) - * - * Response callback is IRadioResponse.setPreferredVoicePrivacyResponse() - */ - void setPreferredVoicePrivacy(in int serial, in boolean enable); - - /** - * Used to set the phones radio capability. Be VERY careful using this request as it may cause - * some vendor modems to reset. Because of the possible modem reset any radio commands after - * this one may not be processed. - * - * @param serial Serial number of request. - * @param rc RadioCapability structure to be set - * - * Response callback is IRadioResponse.setRadioCapabilityResponse() - */ - void setRadioCapability(in int serial, in RadioCapability rc); - - /** - * Toggle radio on and off (for "airplane" mode). If the radio is turned off/on the radio modem - * subsystem is expected return to an initialized state. For instance, any voice and data calls - * must be terminated and all associated lists emptied. - * When setting radio power on to exit from airplane mode to place an emergency call on this - * logical modem, powerOn, forEmergencyCall and preferredForEmergencyCall must be true. In - * this case, this modem is optimized to scan only emergency call bands, until: - * 1) Emergency call is completed; or - * 2) Another setRadioPower is issued with forEmergencyCall being false or - * preferredForEmergencyCall being false; or - * 3) Timeout after 30 seconds if dial or emergencyDial is not called. - * Once one of these conditions is reached, the modem should move into normal operation. - * - * @param serial Serial number of request. - * @param powerOn To turn on radio -> on = true, to turn off radio -> on = false. - * @param forEmergencyCall To indication to radio if this request is due to emergency call. - * No effect if powerOn is false. - * @param preferredForEmergencyCall indicate whether the following emergency call will be sent - * on this modem or not. No effect if forEmergencyCall is false, or powerOn is false. - * - * Response callback is IRadioConfigResponse.setRadioPowerResponse. - */ - void setRadioPower(in int serial, in boolean powerOn, in boolean forEmergencyCall, - in boolean preferredForEmergencyCall); - - /** - * Set response functions for radio requests & radio indications. - * - * @param radioResponse Object containing response functions - * @param radioIndication Object containing radio indications - */ - void setResponseFunctions(in IRadioResponse radioResponse, in IRadioIndication radioIndication); - - /** - * Sets the signal strength reporting criteria. The resulting reporting rules are the AND of all - * the supplied criteria. For each RAN the hysteresisDb and thresholds apply to only the - * following measured quantities: - * -GERAN - RSSI - * -CDMA2000 - RSSI - * -UTRAN - RSCP - * -EUTRAN - RSRP/RSRQ/RSSNR - * -NGRAN - SSRSRP/SSRSRQ/SSSINR - * Note that reporting criteria must be individually set for each RAN. For each RAN, if none of - * reporting criteria of any measurement is set enabled (see SignalThresholdInfo.isEnabled), - * the reporting criteria for this RAN is implementation-defined. For each RAN, if any reporting - * criteria of any measure is set enabled, the reporting criteria of the other measures in this - * RAN are set disabled (see SignalThresholdInfo.isEnabled) until they are set enabled. - * - * @param serial Serial number of request. - * @param signalThresholdInfo Signal threshold info including the threshold values, - * hysteresisDb, hysteresisMs and isEnabled. See SignalThresholdInfo for details. - * @param accessNetwork The type of network for which to apply these thresholds. - * - * Response callback is IRadioResponse.setSignalStrengthReportingCriteriaResponse() - */ - void setSignalStrengthReportingCriteria(in int serial, - in SignalThresholdInfo signalThresholdInfo, in AccessNetwork accessNetwork); - - /** - * Set SIM card power state. Request is used to power off or power on the card. It should not - * generate a CardState.CARDSTATE_ABSENT indication, since the SIM is still physically inserted. - * When SIM card is in POWER_UP_PASS_THROUGH, the modem does not send any command to it (for - * example SELECT of MF, or TERMINAL CAPABILITY), and the SIM card is controlled completely by - * Telephony sending APDUs directly. The SIM card state must be RIL_CARDSTATE_PRESENT and the - * number of card apps will be 0. No new error code is generated. Emergency calls are supported - * in the same way as if the SIM card is absent. Pass-through mode is valid only for the - * specific card session where it is activated, and normal behavior occurs at the next SIM - * initialization, unless POWER_UP_PASS_THROUGH is requested again. - * The device is required to power down the SIM card before it can switch the mode between - * POWER_UP and POWER_UP_PASS_THROUGH. At device power up, the SIM interface is powered up - * automatically. Each subsequent request to this method is processed only after the completion - * of the previous one. - * When the SIM is in POWER_DOWN, the modem should send an empty vector of AppStatus in - * CardStatus.applications. If a SIM in the POWER_DOWN state is removed and a new SIM is - * inserted, the new SIM should be in POWER_UP mode by default. If the device is turned off or - * restarted while the SIM is in POWER_DOWN, then the SIM should turn on normally in POWER_UP - * mode when the device turns back on. - * - * @param serial Serial number of request - * @param powerUp POWER_DOWN if powering down the SIM card - * POWER_UP if powering up the SIM card - * POWER_UP_PASS_THROUGH if powering up the SIM card in pass through mode - * - * Response callback is IRadioResponse.setSimCardPowerResponse(). - */ - void setSimCardPower(in int serial, in CardPowerState powerUp); - - /** - * Set the default Short Message Service Center address on the device. - * - * @param serial Serial number of request. - * @param smsc Short Message Service Center address to set - * - * Response callback is IRadioResponse.setSmscAddressResponse() - */ - void setSmscAddress(in int serial, in String smsc); - - /** - * Enables/disables supplementary service related notifications from the network. - * Notifications are reported via unsolSuppSvcNotification(). - * - * @param serial Serial number of request. - * @param enable true = notifications enabled, false = notifications disabled. - * - * Response function is IRadioResponse.setSuppServiceNotificationsResponse() - */ - void setSuppServiceNotifications(in int serial, in boolean enable); - - /** - * Specify which bands modem's background scan must act on. If specifyChannels is true, it only - * scans bands specified in specifiers. If specifyChannels is false, it scans all bands. For - * example, CBRS is only on LTE band 48. By specifying this band, modem saves more power. - * - * @param serial Serial number of request. - * @param specifyChannels whether to scan bands defined in specifiers. - * @param specifiers which bands to scan. Only used if specifyChannels is true. - * - * Response callback is IRadioResponse.setSystemSelectionChannelsResponse() - */ - void setSystemSelectionChannels( - in int serial, in boolean specifyChannels, in RadioAccessSpecifier[] specifiers); - - /** - * Request to set the TTY mode - * - * @param serial Serial number of request. - * @param mode TtyMode - * - * Response callback is IRadioResponse.setTTYModeResponse() - */ - void setTTYMode(in int serial, in TtyMode mode); - - /** - * Selection/de-selection of a subscription from a SIM card - * - * @param serial Serial number of request. - * @param uiccSub SelectUiccSub as defined in types.hal - * - * Response callback is IRadioResponse.setUiccSubscriptionResponse() - */ - void setUiccSubscription(in int serial, in SelectUiccSub uiccSub); - - /** - * Setup a packet data connection. If DataCallResponse.status returns DataCallFailCause:NONE, - * the data connection must be added to data calls and a unsolDataCallListChanged() must be - * sent. The call remains until removed by subsequent unsolDataCallIstChanged(). It may be lost - * due to many factors, including deactivateDataCall() being issued, the radio powered off, - * reception lost or even transient factors like congestion. This data call list is returned by - * getDataCallList() and dataCallListChanged(). - * The Radio is expected to: - * - Create one data call context. - * - Create and configure a dedicated interface for the context. - * - The interface must be point to point. - * - The interface is configured with one or more addresses and is capable of sending and - * receiving packets. The format is IP address with optional "/" prefix length (The format is - * defined in RFC-4291 section 2.3). For example, "192.0.1.3", "192.0.1.11/16", or - * "2001:db8::1/64". Typically one IPv4 or one IPv6 or one of each. If the prefix length is - * absent, then the addresses are assumed to be point to point with IPv4 with prefix length 32 - * or IPv6 with prefix length 128. - * - Must not modify routing configuration related to this interface; routing management is - * exclusively within the purview of the Android OS. - * - Support simultaneous data call contexts up to DataRegStateResult.maxDataCalls specified in - * the response of getDataRegistrationState. - * - * @param serial Serial number of request. - * @param accessNetwork The access network to setup the data call. If the data connection cannot - * be established on the specified access network then this should respond with an error. - * @param dataProfileInfo Data profile info. - * @param roamingAllowed Indicates whether or not data roaming is allowed by the user. - * @param reason The request reason. Must be DataRequestReason:NORMAL or - * DataRequestReason:HANDOVER. - * @param addresses If the reason is DataRequestReason:HANDOVER, this indicates the list of link - * addresses of the existing data connection. This parameter must be ignored unless - * reason is DataRequestReason:HANDOVER. - * @param dnses If the reason is DataRequestReason:HANDOVER, this indicates the list of DNS - * addresses of the existing data connection. The format is defined in RFC-4291 section - * 2.2. For example, "192.0.1.3" or "2001:db8::1". This parameter must be ignored unless - * reason is DataRequestReason:HANDOVER. - * @param pduSessionId The pdu session id to be used for this data call. A value of 0 means no - * pdu session id was attached to this call. Reference: 3GPP TS 24.007 section 11.2.3.1b - * @param sliceInfo SliceInfo to be used for the data connection when a handover occurs from - * EPDG to 5G. It is valid only when accessNetwork is AccessNetwork:NGRAN. If the slice - * passed from EPDG is rejected, then the data failure cause must be - * DataCallFailCause:SLICE_REJECTED. - * @param trafficDescriptor TrafficDescriptor for which data connection needs to be established. - * It is used for URSP traffic matching as described in TS 24.526 Section 4.2.2. - * It includes an optional DNN which, if present, must be used for traffic matching -- - * it does not specify the end point to be used for the data call. The end point is - * specified by DataProfileInfo.apn; DataProfileInfo.apn must be used as the end point if - * one is not specified through URSP rules. - * @param matchAllRuleAllowed bool to indicate if using default match-all URSP rule for this - * request is allowed. If false, this request must not use the match-all URSP rule and if - * a non-match-all rule is not found (or if URSP rules are not available) it should - * return failure with cause DataCallFailCause:MATCH_ALL_RULE_NOT_ALLOWED. This is needed - * as some requests need to have a hard failure if the intention cannot be met, for - * example, a zero-rating slice. - * - * Response function is IRadioResponse.setupDataCallResponse() - */ - void setupDataCall(in int serial, in AccessNetwork accessNetwork, - in DataProfileInfo dataProfileInfo, in boolean roamingAllowed, - in DataRequestReason reason, in LinkAddress[] addresses, in String[] dnses, - in int pduSessionId, in @nullable SliceInfo sliceInfo, - in @nullable TrafficDescriptor trafficDescriptor, - in boolean matchAllRuleAllowed); - - /** - * Start playing a DTMF tone. Continue playing DTMF tone until stopDtmf is received. If a - * startDtmf() is received while a tone is currently playing, it must cancel the previous tone - * and play the new one. - * - * @param serial Serial number of request. - * @param s string having a single character with one of 12 values: 0-9,*,# - * - * Response function is IRadioResponse.startDtmfResponse() - */ - void startDtmf(in int serial, in String s); - - /** - * Indicates that a handover to the IWLAN transport has begun. Any resources being transferred - * to the IWLAN transport cannot be released while a handover is underway. For example, if a - * pdu session id needs to be transferred to IWLAN, then the modem should not release the id - * while the handover is in progress. If a handover was unsuccessful, then the framework calls - * IRadio::cancelHandover. The modem retains ownership over any of the resources being - * transferred to IWLAN. If a handover was successful, the framework calls - * IRadio::deactivateDataCall with reason HANDOVER. The IWLAN transport now owns the transferred - * resources and is responsible for releasing them. - * - * @param serial Serial number of request. - * @param id callId The identifier of the data call which is provided in SetupDataCallResult - * - * Response function is IRadioResponse.startHandoverResponse() - */ - void startHandover(in int serial, in int callId); - - /** - * Start a Keepalive session (for IPsec) - * - * @param serial Serial number of request. - * @param keepalive A request structure containing all necessary info to describe a keepalive - * - * Response function is IRadioResponse.startKeepaliveResponse() - */ - void startKeepalive(in int serial, in KeepaliveRequest keepalive); - - /** - * Starts a network scan. - * - * @param serial Serial number of request. - * @param request Defines the radio networks/bands/channels which need to be scanned. - * - * Response function is IRadioResponse.startNetworkScanResponse() - */ - void startNetworkScan(in int serial, in NetworkScanRequest request); - - /** - * Stop playing a currently playing DTMF tone. - * - * @param serial Serial number of request. - * - * Response function is IRadioResponse.stopDtmfResponse() - */ - void stopDtmf(in int serial); - - /** - * Stop an ongoing Keepalive session (for IPsec) - * - * @param serial Serial number of request. - * @param sessionHandle The handle that was provided by IRadioResponse.startKeepaliveResponse - * - * Response function is IRadioResponse.stopKeepaliveResponse() - */ - void stopKeepalive(in int serial, in int sessionHandle); - - /** - * Stops ongoing network scan - * - * @param serial Serial number of request. - * - * Response function is IRadioResponse.stopNetworkScanResponse() - */ - void stopNetworkScan(in int serial); - - /** - * Supplies ICC PIN2. Only called following operation where SIM_PIN2 was returned as a failure - * from a previous operation. - * - * @param serial Serial number of request. - * @param pin2 PIN2 value - * @param aid AID value, See ETSI 102.221 8.1 and 101.220 4, empty string if no value. - * - * Response function is IRadioResponse.supplyIccPin2ForAppResponse() - */ - void supplyIccPin2ForApp(in int serial, in String pin2, in String aid); - - /** - * Supplies ICC PIN. Only called if CardStatus has AppState.PIN state - * - * @param serial Serial number of request. - * @param pin PIN value - * @param aid AID value, See ETSI 102.221 8.1 and 101.220 4, empty string if no value. - * - * Response function is IRadioResponse.supplyIccPinForAppResponse() - */ - void supplyIccPinForApp(in int serial, in String pin, in String aid); - - /** - * Supplies ICC PUK2 and new PIN2. - * - * @param serial Serial number of request. - * @param puk2 PUK2 value - * @param pin2 New PIN2 value - * @param aid AID value, See ETSI 102.221 8.1 and 101.220 4, empty string if no value. - * - * Response function is IRadioResponse.supplyIccPuk2ForAppResponse() - */ - void supplyIccPuk2ForApp(in int serial, in String puk2, in String pin2, in String aid); - - /** - * Supplies ICC PUK and new PIN. - * - * @param serial Serial number of request. - * @param puk PUK value - * @param pin New PIN value - * @param aid AID value, See ETSI 102.221 8.1 and 101.220 4, empty string if no value. - * - * Response function is IRadioResponse.supplyIccPukForAppResponse() - */ - void supplyIccPukForApp(in int serial, in String puk, in String pin, in String aid); - - /** - * Requests that network personalization be deactivated - * - * @param serial Serial number of request. - * @param netPin Network depersonlization code - * - * Response function is IRadioResponse.supplyNetworkDepersonalizationResponse() - */ - void supplyNetworkDepersonalization(in int serial, in String netPin); - - /** - * Request that deactivates one category of device personalization. Device personalization - * generally binds the device so it can only be used on one carrier or even one carrier subnet - * (See TS 22.022). When the user has gained the rights to unbind the device (at the end of a - * contract period or other event), the controlKey will be delivered to either the user for - * manual entry or to a carrier app on the device for automatic entry. - * - * @param serial Serial number of request. - * @param persoType SIM personalization type. - * @param controlKey the unlock code for removing persoType personalization from this device - * - * Response function is IRadioResponse.supplySimDepersonalizationResponse() - */ - void supplySimDepersonalization( - in int serial, in PersoSubstate persoType, in String controlKey); - - /** - * Switch waiting or holding call and active call (like AT+CHLD=2). - * Call transitions must happen as shown below. - * BEFORE AFTER - * Call 1 Call 2 Call 1 Call 2 - * ACTIVE HOLDING HOLDING ACTIVE - * ACTIVE WAITING HOLDING ACTIVE - * HOLDING WAITING HOLDING ACTIVE - * ACTIVE IDLE HOLDING IDLE - * IDLE IDLE IDLE IDLE - * - * @param serial Serial number of request. - * - * Response function is IRadioResponse.switchWaitingOrHoldingAndActiveResponse() - */ - void switchWaitingOrHoldingAndActive(in int serial); - - /** - * Insert, delete or update a phonebook record on the SIM card. If the index of recordInfo is 0, - * the phonebook record will be added to global or local phonebook, and global phonebook has - * higher priority than local phonebook. If the fields in the recordInfo are all empty except - * for the index, the phonebook record specified by the index will be deleted. The indication - * simPhonebookChanged will be called after every successful call of updateSimPhonebookRecords. - * - * @param serial Serial number of request. - * @param recordInfo Details of the record to insert, delete or update. - * - * Response callback is IRadioResponse.updateSimPhonebookRecordsResponse() - */ - void updateSimPhonebookRecords(in int serial, in PhonebookRecordInfo recordInfo); - - /** - * Stores a CDMA SMS message to RUIM memory. - * - * @param serial Serial number of request. - * @param cdmaSms CDMA message as defined by CdmaSmsWriteArgs in types.hal - * - * Response callback is IRadioResponse.writeSmsToRuimResponse() - */ - void writeSmsToRuim(in int serial, in CdmaSmsWriteArgs cdmaSms); - - /** - * Stores a SMS message to SIM memory. - * - * @param serial Serial number of request. - * @param smsWriteArgs SmsWriteArgs defined in types.hal - * - * Response function is IRadioResponse.writeSmsToSimResponse() - */ - void writeSmsToSim(in int serial, in SmsWriteArgs smsWriteArgs); -} diff --git a/radio/aidl/android/hardware/radio/IRadioIndication.aidl b/radio/aidl/android/hardware/radio/IRadioIndication.aidl deleted file mode 100644 index ec6addecb0..0000000000 --- a/radio/aidl/android/hardware/radio/IRadioIndication.aidl +++ /dev/null @@ -1,626 +0,0 @@ -/* - * 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.radio; - -import android.hardware.radio.BarringInfo; -import android.hardware.radio.CdmaCallWaiting; -import android.hardware.radio.CdmaInformationRecords; -import android.hardware.radio.CdmaOtaProvisionStatus; -import android.hardware.radio.CdmaSignalInfoRecord; -import android.hardware.radio.CdmaSmsMessage; -import android.hardware.radio.CdmaSubscriptionSource; -import android.hardware.radio.CellIdentity; -import android.hardware.radio.CellInfo; -import android.hardware.radio.Domain; -import android.hardware.radio.EmergencyNumber; -import android.hardware.radio.HardwareConfig; -import android.hardware.radio.KeepaliveStatus; -import android.hardware.radio.LceDataInfo; -import android.hardware.radio.LinkCapacityEstimate; -import android.hardware.radio.NetworkScanResult; -import android.hardware.radio.PbReceivedStatus; -import android.hardware.radio.PcoDataInfo; -import android.hardware.radio.PhoneRestrictedState; -import android.hardware.radio.PhonebookRecordInfo; -import android.hardware.radio.PhysicalChannelConfig; -import android.hardware.radio.RadioCapability; -import android.hardware.radio.RadioIndicationType; -import android.hardware.radio.RadioState; -import android.hardware.radio.RadioTechnology; -import android.hardware.radio.SetupDataCallResult; -import android.hardware.radio.SignalStrength; -import android.hardware.radio.SimRefreshResult; -import android.hardware.radio.SrvccState; -import android.hardware.radio.StkCcUnsolSsResult; -import android.hardware.radio.SuppSvcNotification; -import android.hardware.radio.UssdModeType; - -/** - * Interface declaring unsolicited radio indications. - */ -@VintfStability -oneway interface IRadioIndication { - /** - * Indicate barring information for the user’s access category / access class and PLMN. - * - *

    Provide information about the barring status of the cell for the user. The information - * provided should describe all barring configurations that are applicable to the current user, - * even if the user is not currently barred (due to conditional barring). This informs Android - * of likely future (statistical) barring for specific services. - * - *

    This indication should be sent whenever the cell’s barring config changes for the current - * user, or if the user’s conditional barring status changes due to re-evaluation of the - * barring conditions. Barring status will likely change when the device camps for service, - * when PLMN selection is completed, when the device attempts to access a conditionally barred - * service, and when the System Information including barring info for a camped cell is updated. - */ - void barringInfoChanged(in RadioIndicationType type, in CellIdentity cellIdentity, - in BarringInfo[] barringInfos); - - /** - * Ring indication for an incoming call (eg, RING or CRING event). There must be at least one - * callRing() at the beginning of a call and sending multiple is optional. If the system - * property ro.telephony.call_ring.multiple is false then the upper layers must generate the - * multiple events internally. Otherwise the vendor code must generate multiple callRing() if - * ro.telephony.call_ring.multiple is true or if it is absent. - * The rate of these events is controlled by ro.telephony.call_ring.delay and has a default - * value of 3000 (3 seconds) if absent. - * - * @param type Type of radio indication - * @param isGsm true for GSM & false for CDMA - * @param record Cdma Signal Information - */ - void callRing(in RadioIndicationType type, in boolean isGsm, in CdmaSignalInfoRecord record); - - /** - * Indicates when call state has changed. Callee must invoke IRadio.getCurrentCalls(). Must be - * invoked on, for example, "RING", "BUSY", "NO CARRIER", and also call state transitions - * (DIALING->ALERTING ALERTING->ACTIVE). Redundent or extraneous invocations are tolerated. - * - * @param type Type of radio indication - */ - void callStateChanged(in RadioIndicationType type); - - /** - * Indicates that the modem requires the Carrier info for IMSI/IMPI encryption. This might - * happen when the modem restarts or for some reason it's cache has been invalidated. - * - * @param type Type of radio indication - */ - void carrierInfoForImsiEncryption(in RadioIndicationType info); - - /** - * Indicates when CDMA radio receives a call waiting indication. - * - * @param type Type of radio indication - * @param callWaitingRecord Cdma CallWaiting information - */ - void cdmaCallWaiting(in RadioIndicationType type, in CdmaCallWaiting callWaitingRecord); - - /** - * Indicates when CDMA radio receives one or more info recs. - * - * @param type Type of radio indication - * @param records New Cdma Information - */ - void cdmaInfoRec(in RadioIndicationType type, in CdmaInformationRecords records); - - /** - * Indicates when new CDMA SMS is received. Callee must subsequently confirm the receipt of the - * SMS with acknowledgeLastIncomingCdmaSms(). Server must not send cdmaNewSms() messages until - * acknowledgeLastIncomingCdmaSms() has been received. - * - * @param type Type of radio indication - * @param msg Cdma Sms Message - */ - void cdmaNewSms(in RadioIndicationType type, in CdmaSmsMessage msg); - - /** - * Indicates when CDMA radio receives an update of the progress of an OTASP/OTAPA call. - * - * @param type Type of radio indication - * @param status Cdma OTA provision status - */ - void cdmaOtaProvisionStatus(in RadioIndicationType type, in CdmaOtaProvisionStatus status); - - /** - * Indicates when PRL (preferred roaming list) changes. - * - * @param type Type of radio indication - * @param version PRL version after PRL changes - */ - void cdmaPrlChanged(in RadioIndicationType type, in int version); - - /** - * Indicates that SMS storage on the RUIM is full. Messages cannot be saved on the RUIM until - * space is freed. - * - * @param type Type of radio indication - */ - void cdmaRuimSmsStorageFull(in RadioIndicationType type); - - /** - * Indicates when CDMA subscription source changed. - * - * @param type Type of radio indication - * @param cdmaSource New Cdma SubscriptionSource - */ - void cdmaSubscriptionSourceChanged( - in RadioIndicationType type, in CdmaSubscriptionSource cdmaSource); - - /** - * Report all of the current cell information known to the radio. - * - * @param type Type of radio indication - * @param records Current cell information - */ - void cellInfoList(in RadioIndicationType type, in CellInfo[] records); - - /** - * Report the current list of emergency numbers. Each emergency number in the emergency number - * list contains a dialing number, zero or more service category(s), zero or more emergency - * uniform resource names, mobile country code, mobile network code, and source(s) that indicate - * where it comes from. - * Radio must report all the valid emergency numbers with known mobile country code, mobile - * network code, emergency service categories, and emergency uniform resource names from all - * available sources including network signaling, sim, modem/oem configuration, and default - * configuration (112 and 911 must be always available; additionally, 000, 08, 110, 999, 118 - * and 119 must be available when sim is not present). Radio shall not report emergency numbers - * that are invalid in the current locale. The reported emergency number list must not have - * duplicate EmergencyNumber entries. Please refer the documentation of EmergencyNumber to - * construct each emergency number to report. - * Radio must report the complete list of emergency numbers whenever the emergency numbers in - * the list are changed or whenever the client and the radio server are connected. - * - * Reference: 3gpp 22.101, Section 10 - Emergency Calls; - * 3gpp 24.008, Section 9.2.13.4 - Emergency Number List - * - * @param type Type of radio indication - * @param emergencyNumberList Current list of emergency numbers known to radio. - */ - void currentEmergencyNumberList( - in RadioIndicationType type, in EmergencyNumber[] emergencyNumberList); - - /** - * Indicates current link capacity estimate. This indication is sent whenever the reporting - * criteria, as set by IRadio.setLinkCapacityReportingCriteria, are met and the indication is - * not suppressed by IRadio.setIndicationFilter(). - * - * @param type Type of radio indication - * @param lce LinkCapacityEstimate - */ - void currentLinkCapacityEstimate(in RadioIndicationType type, in LinkCapacityEstimate lce); - - /** - * Indicates physical channel configurations. An empty configs list shall be returned when the - * radio is in idle mode (i.e. RRC idle). - * - * @param type Type of radio indication - * @param configs Vector of PhysicalChannelConfigs - */ - void currentPhysicalChannelConfigs( - in RadioIndicationType type, in PhysicalChannelConfig[] configs); - - /** - * Indicates current signal strength of the radio. - * - * @param type Type of radio indication - * @param signalStrength SignalStrength information - */ - void currentSignalStrength(in RadioIndicationType type, in SignalStrength signalStrength); - - /** - * Indicates data call contexts have changed. - * - * @param type Type of radio indication - * @param dcList Array of SetupDataCallResult identical to that returned by - * IRadio.getDataCallList(). It is the complete list of current data contexts including - * new contexts that have been activated. A data call is only removed from this list - * when any of the below conditions is matched: - * - The framework sends a IRadio.deactivateDataCall(). - * - The radio is powered off/on. - * - Unsolicited disconnect from either modem or network side. - */ - void dataCallListChanged(in RadioIndicationType type, in SetupDataCallResult[] dcList); - - /** - * Indicates that the radio system selection module has autonomously entered emergency - * callback mode. - * - * @param type Type of radio indication - */ - void enterEmergencyCallbackMode(in RadioIndicationType type); - - /** - * Indicates when Emergency Callback Mode Ends. Indicates that the radio system selection module - * has proactively exited emergency callback mode. - * - * @param type Type of radio indication - */ - void exitEmergencyCallbackMode(in RadioIndicationType type); - - /** - * Indicates when the hardware configuration associated with the RILd changes. - * - * @param type Type of radio indication - * @param configs Array of hardware configs - */ - void hardwareConfigChanged(in RadioIndicationType type, in HardwareConfig[] configs); - - /** - * Indicates when IMS registration state has changed. To get IMS registration state and IMS SMS - * format, callee needs to invoke getImsRegistrationState(). - * - * @param type Type of radio indication - */ - void imsNetworkStateChanged(in RadioIndicationType type); - - /** - * Indicates that nework doesn't have in-band information, need to play out-band tone. - * - * @param type Type of radio indication - * @param start true = start play ringback tone, false = stop playing ringback tone - */ - void indicateRingbackTone(in RadioIndicationType type, in boolean start); - - /** - * Indicates a status update for a particular Keepalive session. This must include a handle for - * a previous session and should include a status update regarding the state of a keepalive. - * Unsolicited keepalive status reports should never be PENDING as unsolicited status should - * only be sent when known. - * - * @param type Type of radio indication - * @param status Status information for a Keepalive session - */ - void keepaliveStatus(in RadioIndicationType type, in KeepaliveStatus status); - - /** - * Indicates when there is an incoming Link Capacity Estimate (LCE) info report. - * - * @param type Type of radio indication - * @param lce LceData information - * - * DEPRECATED in @1.2 and above, use IRadioIndication.currentLinkCapacityEstimate() instead. - */ - void lceData(in RadioIndicationType type, in LceDataInfo lce); - - /** - * Indicates when there is a modem reset. - * When modem restarts, one of the following radio state transitions must happen - * 1) RadioState:ON->RadioState:UNAVAILABLE->RadioState:ON or - * 2) RadioState:OFF->RadioState:UNAVAILABLE->RadioState:OFF - * This message must be sent either just before the Radio State changes to - * RadioState:UNAVAILABLE or just after but must never be sent after the Radio State changes - * from RadioState:UNAVAILABLE to RadioState:ON/RadioState:OFF again. It must NOT be sent after - * the Radio state changes to RadioState:ON/RadioState:OFF after the modem restart as that may - * be interpreted as a second modem reset by the framework. - * - * @param type Type of radio indication - * @param reason the reason for the reset. It may be a crash signature if the restart was due to - * a crash or some string such as "user-initiated restart" or "AT command initiated - * restart" that explains the cause of the modem restart - */ - void modemReset(in RadioIndicationType type, in String reason); - - /** - * Incremental network scan results. - * - * @param type Type of radio indication - * @param result the result of the network scan - */ - void networkScanResult(in RadioIndicationType type, in NetworkScanResult result); - - /** - * Indicates when voice or data network state changed. Callee must invoke - * IRadio.getVoiceRegistrationState(), IRadio.getDataRegistrationState(), and - * IRadio.getOperator() - * - * @param type Type of radio indication - */ - void networkStateChanged(in RadioIndicationType type); - - /** - * Indicates when new Broadcast SMS is received - * - * @param type Type of radio indication - * @param data If received from GSM network, "data" is byte array of 88 bytes which indicates - * each page of a CBS Message sent to the MS by the BTS as coded in 3GPP 23.041 Section - * 9.4.1.2. If received from UMTS network, "data" is byte array of 90 up to 1252 bytes - * which contain between 1 and 15 CBS Message pages sent as one packet to the MS by the - * BTS as coded in 3GPP 23.041 Section 9.4.2.2 - */ - void newBroadcastSms(in RadioIndicationType type, in byte[] data); - - /** - * Indicates when new SMS is received. Callee must subsequently confirm the receipt of the SMS - * with a acknowledgeLastIncomingGsmSms(). Server must not send newSms() or newSmsStatusReport() - * messages until an acknowledgeLastIncomingGsmSms() has been received. - * - * @param type Type of radio indication - * @param pdu PDU of SMS-DELIVER represented as byte array. - * The PDU starts with the SMSC address per TS 27.005 (+CMT:) - */ - void newSms(in RadioIndicationType type, in byte[] pdu); - - /** - * Indicates when new SMS has been stored on SIM card - * - * @param type Type of radio indication - * @param recordNumber Record number on the sim - */ - void newSmsOnSim(in RadioIndicationType type, in int recordNumber); - - /** - * Indicates when new SMS Status Report is received. Callee must subsequently confirm the - * receipt of the SMS with a acknowledgeLastIncomingGsmSms(). Server must not send newSms() or - * newSmsStatusReport() messages until an acknowledgeLastIncomingGsmSms() has been received - * - * @param type Type of radio indication - * @param pdu PDU of SMS-STATUS-REPORT represented as byte array. - * The PDU starts with the SMSC address per TS 27.005 (+CMT:) - */ - void newSmsStatusReport(in RadioIndicationType type, in byte[] pdu); - - /** - * Indicates when radio has received a NITZ time message. - * - * @param type Type of radio indication - * @param nitzTime NITZ time string in the form "yy/mm/dd,hh:mm:ss(+/-)tz,dt" - * @param receivedTime milliseconds since boot that the NITZ time was received - */ - void nitzTimeReceived(in RadioIndicationType type, in String nitzTime, in long receivedTime); - - /** - * Indicates when Supplementary service(SS) response is received when DIAL/USSD/SS is changed to - * SS by call control. - * - * @param type Type of radio indication - */ - void onSupplementaryServiceIndication(in RadioIndicationType type, in StkCcUnsolSsResult ss); - - /** - * Indicates when a new USSD message is received. The USSD session is assumed to persist if the - * type code is REQUEST, otherwise the current session (if any) is assumed to have terminated. - * - * @param type Type of radio indication - * @param modeType USSD type code - * @param msg Message string in UTF-8, if applicable - */ - void onUssd(in RadioIndicationType type, in UssdModeType modeType, in String msg); - - /** - * Indicates when there is new Carrier PCO data received for a data call. Ideally only new data - * must be forwarded, though this is not required. Multiple boxes of carrier PCO data for a - * given call must result in a series of pcoData() calls. - * - * @param type Type of radio indication - * @param pco New PcoData - */ - void pcoData(in RadioIndicationType type, in PcoDataInfo pco); - - /** - * Sent when setRadioCapability() completes. Returns the phone radio capability exactly as - * getRadioCapability() and must be the same set as sent by setRadioCapability(). - * - * @param type Type of radio indication - * @param rc Current radio capability - */ - void radioCapabilityIndication(in RadioIndicationType type, in RadioCapability rc); - - /** - * Indicates when radio state changes. - * - * @param type Type of radio indication - * @param radioState Current radio state - */ - void radioStateChanged(in RadioIndicationType type, in RadioState radioState); - - /** - * Report that Registration or a Location/Routing/Tracking Area update has failed. - * - *

    Indicate whenever a registration procedure, including a location, routing, or tracking - * area update fails. This includes procedures that do not necessarily result in a change of - * the modem's registration status. If the modem's registration status changes, that is - * reflected in the onNetworkStateChanged() and subsequent get{Voice/Data}RegistrationState(). - * - * @param cellIdentity the CellIdentity, which must include the globally unique identifier for - * the cell (for example, all components of the CGI or ECGI). - * @param chosenPlmn a 5 or 6 digit alphanumeric PLMN (MCC|MNC) among those broadcast by the - * cell that was chosen for the failed registration attempt. - * @param domain Domain::CS, Domain::PS, or both in case of a combined procedure. - * @param causeCode the primary failure cause code of the procedure. - * For GSM/UMTS (MM), values are in TS 24.008 Sec 10.5.95 - * For GSM/UMTS (GMM), values are in TS 24.008 Sec 10.5.147 - * For LTE (EMM), cause codes are TS 24.301 Sec 9.9.3.9 - * For NR (5GMM), cause codes are TS 24.501 Sec 9.11.3.2 - * MAX_INT if this value is unused. - * @param additionalCauseCode the cause code of any secondary/combined procedure if appropriate. - * For UMTS, if a combined attach succeeds for PS only, then the GMM cause code shall be - * included as an additionalCauseCode. - * For LTE (ESM), cause codes are in TS 24.301 9.9.4.4 - * MAX_INT if this value is unused. - */ - void registrationFailed(in RadioIndicationType type, in CellIdentity cellIdentity, - in String chosenPlmn, in Domain domain, in int causeCode, in int additionalCauseCode); - - /** - * Indicates that framework/application must reset the uplink mute state. - * - * @param type Type of radio indication - */ - void resendIncallMute(in RadioIndicationType type); - - /** - * Indicates a restricted state change (eg, for Domain Specific Access Control). - * Radio must send this msg after radio off/on cycle no matter it is changed or not. - * - * @param type Type of radio indication - * @param state Bitmask of restricted state as defined by PhoneRestrictedState - */ - void restrictedStateChanged(in RadioIndicationType type, in PhoneRestrictedState state); - - /** - * Indicates the ril connects and returns the version - * - * @param type Type of radio indication - */ - void rilConnected(in RadioIndicationType type); - - /** - * Indicates whether SIM phonebook is changed. This indication is sent whenever the SIM - * phonebook is changed, including SIM is inserted or removed and updated by - * IRadio.updateSimPhonebookRecords. - * - * @param type Type of radio indication - */ - void simPhonebookChanged(in RadioIndicationType type); - - /** - * Indicates the content of all the used records in the SIM phonebook. This indication is - * associated with the API getSimPhonebookRecords and might be received more than once that is - * replying on the record count. - * - * @param type Type of radio indication - * @param status Status of PbReceivedStatus - * @param records Vector of PhonebookRecordInfo - */ - void simPhonebookRecordsReceived(in RadioIndicationType type, in PbReceivedStatus status, - in PhonebookRecordInfo[] records); - - /** - * Indicates that file(s) on the SIM have been updated, or the SIM has been reinitialized. - * If the SIM state changes as a result of the SIM refresh (eg, SIM_READY -> - * SIM_LOCKED_OR_ABSENT), simStatusChanged() must be sent. - * - * @param type Type of radio indication - * @param refreshResult Result of sim refresh - */ - void simRefresh(in RadioIndicationType type, in SimRefreshResult refreshResult); - - /** - * Indicates that SMS storage on the SIM is full. Sent when the network attempts to deliver a - * new SMS message. Messages cannot be saved on the SIM until space is freed. In particular, - * incoming Class 2 messages must not be stored. - * - * @param type Type of radio indication - */ - void simSmsStorageFull(in RadioIndicationType type); - - /** - * Indicates that SIM state changes. Callee must invoke getIccCardStatus(). - * - * @param type Type of radio indication - */ - void simStatusChanged(in RadioIndicationType type); - - /** - * Indicates when Single Radio Voice Call Continuity (SRVCC) progress state has changed. - * - * @param type Type of radio indication - * @param state New Srvcc State - */ - void srvccStateNotify(in RadioIndicationType type, in SrvccState state); - - /** - * Indicates when there is an ALPHA from UICC during Call Control. - * - * @param type Type of radio indication - * @param alpha ALPHA string from UICC in UTF-8 format - */ - void stkCallControlAlphaNotify(in RadioIndicationType type, in String alpha); - - /** - * Indicates when SIM wants application to setup a voice call. - * - * @param type Type of radio indication - * @param timeout Timeout value in millisec for setting up voice call - */ - void stkCallSetup(in RadioIndicationType type, in long timeout); - - /** - * Indicates when SIM notifies applcations some event happens. - * - * @param type Type of radio indication - * @param cmd SAT/USAT commands or responses sent by ME to SIM or commands handled by ME, - * represented as byte array starting with first byte of response data for command tag. - * Refer to TS 102.223 section 9.4 for command types - */ - void stkEventNotify(in RadioIndicationType type, in String cmd); - - /** - * Indicates when SIM issue a STK proactive command to applications - * - * @param type Type of radio indication - * @param cmd SAT/USAT proactive represented as byte array starting with command tag. - * Refer to TS 102.223 section 9.4 for command types - */ - void stkProactiveCommand(in RadioIndicationType type, in String cmd); - - /** - * Indicates when STK session is terminated by SIM. - * - * @param type Type of radio indication - */ - void stkSessionEnd(in RadioIndicationType type); - - /** - * Indicated when there is a change in subscription status. - * This event must be sent in the following scenarios - * - subscription readiness at modem, which was selected by telephony layer - * - when subscription is deactivated by modem due to UICC card removal - * - when network invalidates the subscription i.e. attach reject due to authentication reject - * - * @param type Type of radio indication - * @param activate false for subscription deactivated, true for subscription activated - */ - void subscriptionStatusChanged(in RadioIndicationType type, in boolean activate); - - /** - * Reports supplementary service related notification from the network. - * - * @param type Type of radio indication - * @param suppSvc SuppSvcNotification as defined in types.hal - */ - void suppSvcNotify(in RadioIndicationType type, in SuppSvcNotification suppSvc); - - /** - * Report change of whether uiccApplications are enabled, or disabled. - * - * @param type Type of radio indication - * @param enabled whether uiccApplications are enabled, or disabled - */ - void uiccApplicationsEnablementChanged(in RadioIndicationType type, in boolean enabled); - - /** - * The modem can explicitly set SetupDataCallResult::suggestedRetryTime after a failure in - * IRadio.SetupDataCall. During that time, no new calls are allowed to IRadio.SetupDataCall that - * use the same APN. When IRadioIndication.unthrottleApn is sent, AOSP will no longer throttle - * calls to IRadio.SetupDataCall for the given APN. - * - * @param type Type of radio indication - * @param apn Apn to unthrottle - */ - void unthrottleApn(in RadioIndicationType type, in String apn); - - /** - * Indicates that voice technology has changed. Responds with new rat. - * - * @param type Type of radio indication - * @param rat Current new voice rat - */ - void voiceRadioTechChanged(in RadioIndicationType type, in RadioTechnology rat); -} diff --git a/radio/aidl/android/hardware/radio/IRadioResponse.aidl b/radio/aidl/android/hardware/radio/IRadioResponse.aidl deleted file mode 100644 index 4447bb121d..0000000000 --- a/radio/aidl/android/hardware/radio/IRadioResponse.aidl +++ /dev/null @@ -1,3039 +0,0 @@ -/* - * 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.radio; - -import android.hardware.radio.ActivityStatsInfo; -import android.hardware.radio.BarringInfo; -import android.hardware.radio.Call; -import android.hardware.radio.CallForwardInfo; -import android.hardware.radio.CardStatus; -import android.hardware.radio.CarrierRestrictions; -import android.hardware.radio.CdmaBroadcastSmsConfigInfo; -import android.hardware.radio.CdmaRoamingType; -import android.hardware.radio.CdmaSubscriptionSource; -import android.hardware.radio.CellIdentity; -import android.hardware.radio.CellInfo; -import android.hardware.radio.ClipStatus; -import android.hardware.radio.DataRegStateResult; -import android.hardware.radio.GsmBroadcastSmsConfigInfo; -import android.hardware.radio.HardwareConfig; -import android.hardware.radio.IccIoResult; -import android.hardware.radio.KeepaliveStatus; -import android.hardware.radio.LastCallFailCauseInfo; -import android.hardware.radio.LceDataInfo; -import android.hardware.radio.LceStatusInfo; -import android.hardware.radio.NeighboringCell; -import android.hardware.radio.OperatorInfo; -import android.hardware.radio.PersoSubstate; -import android.hardware.radio.PhonebookCapacity; -import android.hardware.radio.PreferredNetworkType; -import android.hardware.radio.RadioAccessFamily; -import android.hardware.radio.RadioAccessSpecifier; -import android.hardware.radio.RadioBandMode; -import android.hardware.radio.RadioCapability; -import android.hardware.radio.RadioResponseInfo; -import android.hardware.radio.RadioTechnology; -import android.hardware.radio.RadioTechnologyFamily; -import android.hardware.radio.RegStateResult; -import android.hardware.radio.SendSmsResult; -import android.hardware.radio.SetupDataCallResult; -import android.hardware.radio.SignalStrength; -import android.hardware.radio.SimLockMultiSimPolicy; -import android.hardware.radio.SlicingConfig; -import android.hardware.radio.TtyMode; -import android.hardware.radio.VoiceRegStateResult; - -/** - * Interface declaring response functions to solicited radio requests. - */ -@VintfStability -oneway interface IRadioResponse { - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INVALID_STATE - * RadioError:NO_MEMORY - * RadioError:SYSTEM_ERR - * RadioError:MODEM_ERR - * RadioError:INTERNAL_ERR - * RadioError:INVALID_CALL_ID - * RadioError:INVALID_ARGUMENTS - * RadioError:SYSTEM_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - */ - void acceptCallResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INTERNAL_ERR - * RadioError:NO_MEMORY - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:REQUEST_NOT_SUPPORTED - */ - void acknowledgeIncomingGsmSmsWithPduResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INVALID_ARGUMENTS - * RadioError:NO_SMS_TO_ACK - * RadioError:INVALID_STATE - * RadioError:NO_MEMORY - * RadioError:REQUEST_RATE_LIMITED - * RadioError:SYSTEM_ERR - * RadioError:MODEM_ERR - * RadioError:NETWORK_NOT_READY - * RadioError:INVALID_MODEM_STATE - * RadioError:INTERNAL_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:OPERATION_NOT_ALLOWED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - */ - void acknowledgeLastIncomingCdmaSmsResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INTERNAL_ERR - * RadioError:NO_MEMORY - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:REQUEST_NOT_SUPPORTED - */ - void acknowledgeLastIncomingGsmSmsResponse(in RadioResponseInfo info); - - /** - * Acknowledge the receipt of radio request sent to the vendor. This must be sent only for - * radio request which take long time to respond. For more details, refer - * https://source.android.com/devices/tech/connect/ril.html - * - * @param serial Serial no. of the request whose acknowledgement is sent. - */ - void acknowledgeRequest(in int serial); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param id The allocated id. On an error, this is set to 0. - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INTERNAL_ERR - * RadioError:NO_RESOURCES- Indicates that no pdu session ids are available - * RadioError:REQUEST_NOT_SUPPORTED - */ - void allocatePduSessionIdResponse(in RadioResponseInfo info, in int id); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param enabled whether Uicc applications are enabled. - * - * Valid errors returned: - * RadioError:NONE - * RadioError:SIM_ABSENT - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INTERNAL_ERR - */ - void areUiccApplicationsEnabledResponse(in RadioResponseInfo info, in boolean enabled); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param dcResponse Attributes of data call - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INTERNAL_ERR - * RadioError:NO_RESOURCES - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:INVALID_CALL_ID - */ - void cancelHandoverResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:SIM_BUSY - * RadioError:OPERATION_NOT_ALLOWED - * RadioError:MODEM_ERR - * RadioError:INTERNAL_ERR - * RadioError:NO_MEMORY - * RadioError:INVALID_STATE - * RadioError:INVALID_ARGUMENTS - * RadioError:SYSTEM_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:INVALID_MODEM_STATE - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - */ - void cancelPendingUssdResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param remainingRetries Number of retries remaining, must be equal to -1 if unknown. - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE (radio resetting) - * RadioError:PASSWORD_INCORRECT (old PIN2 is invalid) - * RadioError:INTERNAL_ERR - * RadioError:NO_MEMORY - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:INVALID_ARGUMENTS - * RadioError:INVALID_SIM_STATE - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:SIM_PUK2 - */ - void changeIccPin2ForAppResponse(in RadioResponseInfo info, in int remainingRetries); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param remainingRetries Number of retries remaining, must be equal to -1 if unknown. - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE (radio resetting) - * RadioError:PASSWORD_INCORRECT - * RadioError:INTERNAL_ERR - * RadioError:NO_MEMORY - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:INVALID_ARGUMENTS - * RadioError:INVALID_SIM_STATE - * RadioError:REQUEST_NOT_SUPPORTED - */ - void changeIccPinForAppResponse(in RadioResponseInfo info, in int remainingRetries); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE (radio resetting) - * RadioError:NO_MEMORY - * RadioError:MODEM_ERR - * RadioError:INTERNAL_ERR - * RadioError:INVALID_STATE - * RadioError:INVALID_CALL_ID - * RadioError:OPERATION_NOT_ALLOWED - * RadioError:INVALID_ARGUMENTS - * RadioError:SYSTEM_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:INVALID_MODEM_STATE - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - */ - void conferenceResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:REQUEST_NOT_SUPPORTED may be returned when HAL 1.2 or higher is supported. - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INVALID_CALL_ID - * RadioError:INVALID_STATE - * RadioError:INVALID_ARGUMENTS - * RadioError:INTERNAL_ERR - * RadioError:NO_MEMORY - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:SIM_ABSENT - */ - void deactivateDataCallResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INVALID_ARGUMENTS - * RadioError:NO_MEMORY - * RadioError:SYSTEM_ERR - * RadioError:MODEM_ERR - * RadioError:NO_SUCH_ENTRY - * RadioError:INTERNAL_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:OPERATION_NOT_ALLOWED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:INVALID_MODEM_STATE - * RadioError:OPERATION_NOT_ALLOWED - * RadioError:SIM_ABSENT - */ - void deleteSmsOnRuimResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:SIM_FULL - * RadioError:INVALID_ARGUMENTS - * RadioError:NO_MEMORY - * RadioError:SYSTEM_ERR - * RadioError:MODEM_ERR - * RadioError:NO_SUCH_ENTRY - * RadioError:INTERNAL_ERR - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:INVALID_MODEM_STATE - * RadioError:SIM_ABSENT - */ - void deleteSmsOnSimResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE (radio resetting) - * RadioError:DIAL_MODIFIED_TO_USSD - * RadioError:DIAL_MODIFIED_TO_SS - * RadioError:DIAL_MODIFIED_TO_DIAL - * RadioError:INVALID_ARGUMENTS - * RadioError:NO_MEMORY - * RadioError:INVALID_STATE - * RadioError:NO_RESOURCES - * RadioError:INTERNAL_ERR - * RadioError:FDN_CHECK_FAILURE - * RadioError:MODEM_ERR - * RadioError:NO_SUBSCRIPTION - * RadioError:NO_NETWORK_FOUND - * RadioError:INVALID_CALL_ID - * RadioError:DEVICE_IN_USE - * RadioError:OPERATION_NOT_ALLOWED - * RadioError:ABORTED - * RadioError:SYSTEM_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:INVALID_MODEM_STATE - * RadioError:CANCELLED - */ - void dialResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE (radio resetting) - * RadioError:DIAL_MODIFIED_TO_USSD - * RadioError:DIAL_MODIFIED_TO_SS - * RadioError:DIAL_MODIFIED_TO_DIAL - * RadioError:INVALID_ARGUMENTS - * RadioError:NO_RESOURCES - * RadioError:INTERNAL_ERR - * RadioError:FDN_CHECK_FAILURE - * RadioError:MODEM_ERR - * RadioError:NO_SUBSCRIPTION - * RadioError:NO_NETWORK_FOUND - * RadioError:INVALID_CALL_ID - * RadioError:DEVICE_IN_USE - * RadioError:ABORTED - * RadioError:INVALID_MODEM_STATE - */ - void emergencyDialResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:MODEM_ERR - * RadioError:INVALID_STATE: this is for the case that the API is called in a single-sim - * mode, or when there is only one modem available, as this API should only - * be called in multi sim status. - */ - void enableModemResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:SIM_ABSENT - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INTERNAL_ERR - * RadioError:BUSY - */ - void enableUiccApplicationsResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:OPERATION_NO_ALLOWED - * RadioError:INTERNAL_ERR - * RadioError:NO_MEMORY - * RadioError:SYSTEM_ERR - * RadioError:INVALID_ARGUMENTS - * RadioError:MODEM_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:SIM_ABSENT - */ - void exitEmergencyCallbackModeResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INVALID_ARGUMENTS - * RadioError:INVALID_STATE - * RadioError:NO_RESOURCES - * RadioError:NO_MEMORY - * RadioError:SYSTEM_ERR - * RadioError:MODEM_ERR - * RadioError:INTERNAL_ERR - * RadioError:INVALID_CALL_ID - * RadioError:OPERATION_NOT_ALLOWED - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:INVALID_MODEM_STATE - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - */ - void explicitCallTransferResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param carriers Carrier restriction information. - * @param multiSimPolicy Policy used for devices with multiple SIM cards. - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:REQUEST_NOT_SUPPORTED - */ - void getAllowedCarriersResponse(in RadioResponseInfo info, in CarrierRestrictions carriers, - in SimLockMultiSimPolicy multiSimPolicy); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param networkTypeBitmap a 32-bit bitmap of RadioAccessFamily. - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:OPERATION_NOT_ALLOWED - * RadioError:MODE_NOT_SUPPORTED - * RadioError:INTERNAL_ERR - * RadioError:INVALID_ARGUMENTS - * RadioError:MODEM_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:NO_RESOURCES - */ - void getAllowedNetworkTypesBitmapResponse( - in RadioResponseInfo info, in RadioAccessFamily networkTypeBitmap); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param bandModes List of RadioBandMode listing supported modes - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INVALID_ARGUMENTS - * RadioError:NO_MEMORY - * RadioError:INTERNAL_ERR - * RadioError:SYSTEM_ERR - * RadioError:MODEM_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - */ - void getAvailableBandModesResponse(in RadioResponseInfo info, in RadioBandMode[] bandModes); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param networkInfos List of network operator information as OperatorInfos defined in - * types.hal - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:OPERATION_NOT_ALLOWED - * RadioError:ABORTED - * RadioError:DEVICE_IN_USE - * RadioError:INTERNAL_ERR - * RadioError:NO_MEMORY - * RadioError:MODEM_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:CANCELLED - * RadioError:NO_RESOURCES - * RadioError:INTERNAL_ERR - */ - void getAvailableNetworksResponse(in RadioResponseInfo info, in OperatorInfo[] networkInfos); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param cellIdentity CellIdentity for the barring infos. - * @param barringInfos a vector of barring info for all barring service types - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INTERNAL_ERR - * RadioError:MODEM_ERR - */ - void getBarringInfoResponse( - in RadioResponseInfo info, in CellIdentity cellIdentity, in BarringInfo[] barringInfos); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param version string containing version string for log reporting - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:EMPTY_RECORD - * RadioError:NO_MEMORY - * RadioError:INTERNAL_ERR - * RadioError:SYSTEM_ERR - * RadioError:MODEM_ERR - * RadioError:NOT_PROVISIONED - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - */ - void getBasebandVersionResponse(in RadioResponseInfo info, in String version); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param mdn MDN if CDMA subscription is available - * @param hSid is a comma separated list of H_SID (Home SID) if CDMA subscription is available, - * in decimal format - * @param hNid is a comma separated list of H_NID (Home NID) if CDMA subscription is available, - * in decimal format - * @param min MIN (10 digits, MIN2+MIN1) if CDMA subscription is available - * @param prl PRL version if CDMA subscription is available - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:SUBSCRIPTION_NOT_AVAILABLE - * RadioError:NO_MEMORY - * RadioError:INTERNAL_ERR - * RadioError:SYSTEM_ERR - * RadioError:INVALID_ARGUMENTS - * RadioError:MODEM_ERR - * RadioError:NOT_PROVISIONED - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:SIM_ABSENT - */ - void getCDMASubscriptionResponse(in RadioResponseInfo info, in String mdn, in String hSid, - in String hNid, in String min, in String prl); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param callForwardInfos points to a vector of CallForwardInfo, one for each distinct - * registered phone number. For example, if data is forwarded to +18005551212 and voice - * is forwarded to +18005559999, then two separate CallForwardInfo's must be returned. - * However, if both data and voice are forwarded to +18005551212, then a single - * CallForwardInfo must be returned with the service class set to "data + voice = 3". - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:SS_MODIFIED_TO_DIAL - * RadioError:SS_MODIFIED_TO_USSD - * RadioError:SS_MODIFIED_TO_SS - * RadioError:INVALID_ARGUMENTS - * RadioError:NO_MEMORY - * RadioError:SYSTEM_ERR - * RadioError:MODEM_ERR - * RadioError:INTERNAL_ERR - * RadioError:FDN_CHECK_FAILURE - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:SYSTEM_ERR - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - */ - void getCallForwardStatusResponse( - in RadioResponseInfo info, in CallForwardInfo[] callForwardInfos); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param enable If current call waiting state is disabled, enable = false else true - * @param serviceClass If enable, then callWaitingResp[1] must follow, with the TS 27.007 - * service class bit vector of services for which call waiting is enabled. For example, - * if callWaitingResp[0] is 1 and callWaitingResp[1] is 3, then call waiting is enabled - * for data and voice and disabled for everything else. - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:SS_MODIFIED_TO_DIAL - * RadioError:SS_MODIFIED_TO_USSD - * RadioError:SS_MODIFIED_TO_SS - * RadioError:INVALID_ARGUMENTS - * RadioError:NO_MEMORY - * RadioError:MODEM_ERR - * RadioError:INTERNAL_ERR - * RadioError:FDN_CHECK_FAILURE - * RadioError:INTERNAL_ERR - * RadioError:SYSTEM_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - */ - void getCallWaitingResponse(in RadioResponseInfo info, in boolean enable, in int serviceClass); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param configs Vector of CDMA Broadcast SMS configs. - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INVALID_ARGUMENTS - * RadioError:INVALID_STATE - * RadioError:NO_MEMORY - * RadioError:REQUEST_RATE_LIMITED - * RadioError:SYSTEM_ERR - * RadioError:MODEM_ERR - * RadioError:NO_RESOURCES - * RadioError:INTERNAL_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:INVALID_MODEM_STATE - */ - void getCdmaBroadcastConfigResponse( - in RadioResponseInfo info, in CdmaBroadcastSmsConfigInfo[] configs); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param type CdmaRoamingType defined in types.hal - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INVALID_ARGUMENTS - * RadioError:NO_MEMORY - * RadioError:INTERNAL_ERR - * RadioError:SYSTEM_ERR - * RadioError:MODEM_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:SIM_ABSENT - */ - void getCdmaRoamingPreferenceResponse(in RadioResponseInfo info, in CdmaRoamingType type); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param source CDMA subscription source - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:SUBSCRIPTION_NOT_AVAILABLE - * RadioError:INTERNAL_ERR - * RadioError:NO_MEMORY - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:SIM_ABSENT - */ - void getCdmaSubscriptionSourceResponse( - in RadioResponseInfo info, in CdmaSubscriptionSource source); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param cellInfo List of current cell information known to radio - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INTERNAL_ERR - */ - void getCellInfoListResponse(in RadioResponseInfo info, in CellInfo[] cellInfo); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param status indicates CLIP status - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INVALID_ARGUMENTS - * RadioError:NO_MEMORY - * RadioError:SYSTEM_ERR - * RadioError:MODEM_ERR - * RadioError:INTERNAL_ERR - * RadioError:FDN_CHECK_FAILURE - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - */ - void getClipResponse(in RadioResponseInfo info, in ClipStatus status); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param n is "n" parameter from TS 27.007 7.7 - * @param m is "m" parameter from TS 27.007 7.7 - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:SS_MODIFIED_TO_DIAL - * RadioError:SS_MODIFIED_TO_USSD - * RadioError:SS_MODIFIED_TO_SS - * RadioError:NO_MEMORY - * RadioError:MODEM_ERR - * RadioError:INTERNAL_ERR - * RadioError:FDN_CHECK_FAILURE - * RadioError:SYSTEM_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:INVALID_ARGUMENTS - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - */ - void getClirResponse(in RadioResponseInfo info, in int n, in int m); - - /** - * @param info Response info struct containing respontype, serial no. and error - * @param calls Current call list - * - * Valid errors returned: - * RadioError:NO_MEMORY - * RadioError:INTERNAL_ERR - * RadioError:SYSTEM_ERR - * RadioError:INVALID_ARGUMENTS - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - */ - void getCurrentCallsResponse(in RadioResponseInfo info, in Call[] calls); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param dcResponse List of SetupDataCallResult as defined in types.hal - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INTERNAL_ERR - * RadioError:SIM_ABSENT - */ - void getDataCallListResponse(in RadioResponseInfo info, in SetupDataCallResult[] dcResponse); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param dataRegResponse Current Data registration response as defined by RegStateResult in - * types.hal - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INTERNAL_ERR - * RadioError:NOT_PROVISIONED - */ - void getDataRegistrationStateResponse( - in RadioResponseInfo info, in RegStateResult dataRegResponse); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param imei IMEI if GSM subscription is available - * @param imeisv IMEISV if GSM subscription is available - * @param esn ESN if CDMA subscription is available - * @param meid MEID if CDMA subscription is available - * - * If a empty string value is returned for any of the device id, it means that there was error - * accessing the device. - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:NO_MEMORY - * RadioError:INTERNAL_ERR - * RadioError:SYSTEM_ERR - * RadioError:INVALID_ARGUMENTS - * RadioError:MODEM_ERR - * RadioError:NOT_PROVISIONED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:REQUEST_NOT_SUPPORTED - */ - void getDeviceIdentityResponse(in RadioResponseInfo info, in String imei, in String imeisv, - in String esn, in String meid); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param response 0 is the TS 27.007 service class bit vector of services for which the - * specified barring facility is active. "0" means "disabled for all" - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:SS_MODIFIED_TO_DIAL - * RadioError:SS_MODIFIED_TO_USSD - * RadioError:SS_MODIFIED_TO_SS - * RadioError:INVALID_ARGUMENTS - * RadioError:NO_MEMORY - * RadioError:MODEM_ERR - * RadioError:INTERNAL_ERR - * RadioError:SYSTEM_ERR - * RadioError:FDN_CHECK_FAILURE - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - */ - void getFacilityLockForAppResponse(in RadioResponseInfo info, in int response); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param configs Vector of GSM/WCDMA Cell broadcast configs - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INVALID_ARGUMENTS - * RadioError:INVALID_STATE - * RadioError:NO_MEMORY - * RadioError:REQUEST_RATE_LIMITED - * RadioError:SYSTEM_ERR - * RadioError:MODEM_ERR - * RadioError:NO_RESOURCES - * RadioError:INTERNAL_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:INVALID_MODEM_STATE - */ - void getGsmBroadcastConfigResponse( - in RadioResponseInfo info, in GsmBroadcastSmsConfigInfo[] configs); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param config Array of HardwareConfig of the radio. - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:REQUEST_NOT_SUPPORTED - */ - void getHardwareConfigResponse(in RadioResponseInfo info, in HardwareConfig[] config); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param imsi String containing the IMSI - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE (radio resetting) - * RadioError:INTERNAL_ERR - * RadioError:NO_MEMORY - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:INVALID_SIM_STATE - * RadioError:SIM_ERR - * RadioError:REQUEST_NOT_SUPPORTED - */ - void getIMSIForAppResponse(in RadioResponseInfo info, in String imsi); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param cardStatus ICC card status as defined by CardStatus in types.hal - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INTERNAL_ERR - * RadioError:NO_RESOURCES - * RadioError:REQUEST_NOT_SUPPORTED - */ - void getIccCardStatusResponse(in RadioResponseInfo info, in CardStatus cardStatus); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param isRegistered false = not registered, true = registered - * @param ratFamily RadioTechnologyFamily as defined in types.hal. This value is valid only if - * isRegistered is true. - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INTERNAL_ERR - * RadioError:NO_MEMORY - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:INVALID_MODEM_STATE - * RadioError:REQUEST_NOT_SUPPORTED - */ - void getImsRegistrationStateResponse( - in RadioResponseInfo info, in boolean isRegistered, in RadioTechnologyFamily ratFamily); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param failCauseInfo Contains LastCallFailCause and vendor cause code. - * - * The vendor cause code must be used for debugging purpose only. The implementation must return - * one of the values of LastCallFailCause as mentioned below. - * GSM failure reasons codes for the cause codes defined in TS 24.008 Annex H where possible. - * CDMA failure reasons codes for the possible call failure scenarios described in the - * "CDMA IS-2000 Release A (C.S0005-A v6.0)" standard. - * Any of the following reason codes if the call is failed or dropped due to reason mentioned - * with in the braces. - * LastCallFailCause:RADIO_OFF (Radio is OFF) - * LastCallFailCause:OUT_OF_SERVICE (No cell coverage) - * LastCallFailCause:NO_VALID_SIM (No valid SIM) - * LastCallFailCause:RADIO_INTERNAL_ERROR (Modem hit unexpected error scenario) - * LastCallFailCause:NETWORK_RESP_TIMEOUT (No response from network) - * LastCallFailCause:NETWORK_REJECT (Explicit network reject) - * LastCallFailCause:RADIO_ACCESS_FAILURE (RRC connection failure. Eg.RACH) - * LastCallFailCause:RADIO_LINK_FAILURE (Radio Link Failure) - * LastCallFailCause:RADIO_LINK_LOST (Radio link lost due to poor coverage) - * LastCallFailCause:RADIO_UPLINK_FAILURE (Radio uplink failure) - * LastCallFailCause:RADIO_SETUP_FAILURE (RRC connection setup failure) - * LastCallFailCause:RADIO_RELEASE_NORMAL (RRC connection release, normal) - * LastCallFailCause:RADIO_RELEASE_ABNORMAL (RRC connection release, abnormal) - * LastCallFailCause:ACCESS_CLASS_BLOCKED (Access class barring) - * LastCallFailCause:NETWORK_DETACH (Explicit network detach) - * OEM causes (LastCallFailCause:OEM_CAUSE_XX) must be used for debug purpose only - * - * If the implementation does not have access to the exact cause codes, then it must return one - * of the values listed in LastCallFailCause, as the UI layer needs to distinguish these cases - * for tone generation or error notification. - * - * Valid errors returned: - * RadioError:NONE - * RadioError:NO_MEMORY - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:SYSTEM_ERR - * RadioError:INVALID_ARGUMENTS - * RadioError:INTERNAL_ERR - * RadioError:MODEM_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:NO_MEMORY - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - */ - void getLastCallFailCauseResponse( - in RadioResponseInfo info, in LastCallFailCauseInfo failCauseinfo); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param activityInfo modem activity information - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:NO_MEMORY - * RadioError:INTERNAL_ERR - * RadioError:SYSTEM_ERR - * RadioError:MODEM_ERR - * RadioError:NOT_PROVISIONED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:REQUEST_NOT_SUPPORTED - */ - void getModemActivityInfoResponse(in RadioResponseInfo info, in ActivityStatsInfo activityInfo); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:MODEM_ERR - */ - void getModemStackStatusResponse(in RadioResponseInfo info, in boolean isEnabled); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param enable true for "mute enabled" and false for "mute disabled" - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:SS_MODIFIED_TO_DIAL - * RadioError:SS_MODIFIED_TO_USSD - * RadioError:SS_MODIFIED_TO_SS - * RadioError:NO_MEMORY - * RadioError:REQUEST_RATE_LIMITED - * RadioError:INVALID_ARGUMENTS - * RadioError:INTERNAL_ERR - * RadioError:SYSTEM_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - */ - void getMuteResponse(in RadioResponseInfo info, in boolean enable); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param cells Vector of neighboring radio cell - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INVALID_ARGUMENTS - * RadioError:NO_MEMORY - * RadioError:INTERNAL_ERR - * RadioError:SYSTEM_ERR - * RadioError:MODEM_ERR - * RadioError:NO_NETWORK_FOUND - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - */ - void getNeighboringCidsResponse(in RadioResponseInfo info, in NeighboringCell[] cells); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param selection false for automatic selection, true for manual selection - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:NO_MEMORY - * RadioError:INTERNAL_ERR - * RadioError:SYSTEM_ERR - * RadioError:INVALID_ARGUMENTS - * RadioError:MODEM_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - */ - void getNetworkSelectionModeResponse(in RadioResponseInfo info, in boolean manual); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param longName is long alpha ONS or EONS or empty string if unregistered - * @param shortName is short alpha ONS or EONS or empty string if unregistered - * @param numeric is 5 or 6 digit numeric code (MCC + MNC) or empty string if unregistered - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:NO_MEMORY - * RadioError:INTERNAL_ERR - * RadioError:SYSTEM_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - */ - void getOperatorResponse( - in RadioResponseInfo info, in String longName, in String shortName, in String numeric); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param networkTypeBitmap a 32-bit bitmap of RadioAccessFamily. - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INTERNAL_ERR - * RadioError:INVALID_ARGUMENTS - * RadioError:MODEM_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:NO_RESOURCES - */ - void getPreferredNetworkTypeBitmapResponse( - in RadioResponseInfo info, in RadioAccessFamily networkTypeBitmap); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param nwType RadioPreferredNetworkType defined in types.hal - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:NO_MEMORY - * RadioError:INTERNAL_ERR - * RadioError:SYSTEM_ERR - * RadioError:INVALID_ARGUMENTS - * RadioError:MODEM_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - */ - void getPreferredNetworkTypeResponse(in RadioResponseInfo info, in PreferredNetworkType nwType); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param enable false for Standard Privacy Mode (Public Long Code Mask) - * true for Enhanced Privacy Mode (Private Long Code Mask) - * - * Valid errors: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INVALID_ARGUMENTS - * RadioError:MODEM_ERR - * RadioError:INTERNAL_ERR - * RadioError:NO_MEMORY - * RadioError:SYSTEM_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - */ - void getPreferredVoicePrivacyResponse(in RadioResponseInfo info, in boolean enable); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param rc Radio capability as defined by RadioCapability in types.hal - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:OPERATION_NOT_ALLOWED - * RadioError:INVALID_STATE - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:INTERNAL_ERR - * RadioError:NO_MEMORY - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - */ - void getRadioCapabilityResponse(in RadioResponseInfo info, in RadioCapability rc); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param signalStrength Current signal strength - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INTERNAL_ERR - */ - void getSignalStrengthResponse(in RadioResponseInfo info, in SignalStrength signalStrength); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param capacity Response capacity enum indicating response processing status - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:INVALID_ARGUMENTS - * RadioError:INVALID_SIM_STATE - * RadioError:MODEM_ERR - * RadioError:INTERNAL_ERR - * REQUEST_NOT_SUPPORTED may only be returned on devices that don't support this API, - * indicated by the HAL capability CAPABILITY_SIM_PHONEBOOK_IN_MODEM. - */ - void getSimPhonebookCapacityResponse(in RadioResponseInfo info, in PhonebookCapacity capacity); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:INVALID_ARGUMENTS - * RadioError:INVALID_SIM_STATE - * RadioError:MODEM_ERR - * RadioError:INTERNAL_ERR - * REQUEST_NOT_SUPPORTED may only be returned on devices that don't support this API, - * indicated by the HAL capability CAPABILITY_SIM_PHONEBOOK_IN_MODEM. - */ - void getSimPhonebookRecordsResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param slicingConfig Current slicing configuration - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INTERNAL_ERR - * RadioError:MODEM_ERR - */ - void getSlicingConfigResponse(in RadioResponseInfo info, in SlicingConfig slicingConfig); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param smsc Short Message Service Center address on the device - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INVALID_ARGUMENTS - * RadioError:INTERNAL_ERR - * RadioError:NO_MEMORY - * RadioError:SYSTEM_ERR - * RadioError:REQUEST_RATE_LIMITED - * RadioError:MODEM_ERR - * RadioError:INVALID_MODEM_STATE - * RadioError:NOT_PROVISIONED - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:OPERATION_NOT_ALLOWED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:SIM_ABSENT - */ - void getSmscAddressResponse(in RadioResponseInfo info, in String smsc); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param specifiers List of RadioAccessSpecifiers that are scanned. - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INTERNAL_ERR - * RadioError:INVALID_ARGUMENTS - */ - void getSystemSelectionChannelsResponse( - in RadioResponseInfo info, in RadioAccessSpecifier[] specifiers); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param mode TtyMode - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INVALID_ARGUMENTS - * RadioError:MODEM_ERR - * RadioError:INTERNAL_ERR - * RadioError:NO_MEMORY - * RadioError:SYSTEM_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - */ - void getTTYModeResponse(in RadioResponseInfo info, in TtyMode mode); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param rat Current voice RAT - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INTERNAL_ERR - * RadioError:NO_MEMORY - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:REQUEST_NOT_SUPPORTED - */ - void getVoiceRadioTechnologyResponse(in RadioResponseInfo info, in RadioTechnology rat); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param voiceRegResponse Current Voice registration response as defined by RegStateResult - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INTERNAL_ERR - */ - void getVoiceRegistrationStateResponse( - in RadioResponseInfo info, in RegStateResult voiceRegResponse); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:NO_MEMORY - * RadioError:INTERNAL_ERR - * RadioError:SYSTEM_ERR - * RadioError:MODEM_ERR - * RadioError:INVALID_ARGUMENTS - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:SIM_ABSENT - */ - void handleStkCallSetupRequestFromSimResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE (radio resetting) - * RadioError:INVALID_ARGUMENTS - * RadioError:NO_MEMORY - * RadioError:INVALID_STATE - * RadioError:MODEM_ERR - * RadioError:INTERNAL_ERR - * RadioError:INVALID_CALL_ID - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:REQUEST_NOT_SUPPORTED - */ - void hangupConnectionResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE (radio resetting) - * RadioError:INVALID_STATE - * RadioError:NO_MEMORY - * RadioError:MODEM_ERR - * RadioError:INTERNAL_ERR - * RadioError:INVALID_CALL_ID - * RadioError:NO_RESOURCES - * RadioError:OPERATION_NOT_ALLOWED - * RadioError:INVALID_ARGUMENTS - * RadioError:SYSTEM_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - */ - void hangupForegroundResumeBackgroundResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE (radio resetting) - * RadioError:INVALID_STATE - * RadioError:NO_MEMORY - * RadioError:MODEM_ERR - * RadioError:INTERNAL_ERR - * RadioError:INVALID_CALL_ID - * RadioError:NO_RESOURCES - * RadioError:OPERATION_NOT_ALLOWED - * RadioError:INVALID_ARGUMENTS - * RadioError:SYSTEM_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:CANCELLED - */ - void hangupWaitingOrBackgroundResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INTERNAL_ERR - * RadioError:NO_MEMORY - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:REQUEST_NOT_SUPPORTED - */ - void iccCloseLogicalChannelResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param iccIo ICC io operation response as defined by IccIoResult in types.hal - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:SIM_PIN2 - * RadioError:SIM_PUK2 - * RadioError:INTERNAL_ERR - * RadioError:NO_MEMORY - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:INVALID_SIM_STATE - * RadioError:SIM_ERR - * RadioError:REQUEST_NOT_SUPPORTED - */ - void iccIOForAppResponse(in RadioResponseInfo info, in IccIoResult iccIo); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param channelId session id of the logical channel. - * @param selectResponse Contains the select response for the open channel command with one - * byte per integer - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:MISSING_RESOURCE - * RadioError:NO_SUCH_ELEMENT - * RadioError:INTERNAL_ERR - * RadioError:NO_MEMORY - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:SIM_ERR - * RadioError:INVALID_SIM_STATE - * RadioError:MISSING_RESOURCE - * RadioError:REQUEST_NOT_SUPPORTED - */ - void iccOpenLogicalChannelResponse( - in RadioResponseInfo info, in int channelId, in byte[] selectResponse); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param result IccIoResult as defined in types.hal - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INTERNAL_ERR - * RadioError:NO_MEMORY - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:REQUEST_NOT_SUPPORTED - */ - void iccTransmitApduBasicChannelResponse(in RadioResponseInfo info, in IccIoResult result); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param result IccIoResult as defined in types.hal - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INTERNAL_ERR - * RadioError:NO_MEMORY - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:REQUEST_NOT_SUPPORTED - */ - void iccTransmitApduLogicalChannelResponse(in RadioResponseInfo info, in IccIoResult result); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param isEnabled Indicates whether NR dual connectivity is enabled or not, True if enabled - * else false. - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INTERNAL_ERR - * RadioError:REQUEST_NOT_SUPPORTED - */ - void isNrDualConnectivityEnabledResponse(in RadioResponseInfo info, in boolean isEnabled); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param result string containing the contents of the NV item - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:REQUEST_NOT_SUPPORTED - */ - void nvReadItemResponse(in RadioResponseInfo info, in String result); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:REQUEST_NOT_SUPPORTED - */ - void nvResetConfigResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:REQUEST_NOT_SUPPORTED - */ - void nvWriteCdmaPrlResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:REQUEST_NOT_SUPPORTED - */ - void nvWriteItemResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param lceInfo LceDataInfo indicating LCE data - * - * Valid errors returned: - * RadioError:REQUEST_NOT_SUPPORTED may be returned when HAL 1.2 or higher is supported. - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:LCE_NOT_SUPPORTED - * RadioError:INTERNAL_ERR - * RadioError:NO_MEMORY - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:SIM_ABSENT - */ - void pullLceDataResponse(in RadioResponseInfo info, in LceDataInfo lceInfo); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE (radio resetting) - * RadioError:INVALID_STATE - * RadioError:NO_RESOURCES - * RadioError:NO_MEMORY - * RadioError:MODEM_ERR - * RadioError:INTERNAL_ERR - * RadioError:INVALID_CALL_ID - * RadioError:OPERATION_NOT_ALLOWED - * RadioError:INVALID_ARGUMENTS - * RadioError:SYSTEM_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:INVALID_MODEM_STATE - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - */ - void rejectCallResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INTERNAL_ERR - * RadioError:NO_RESOURCES - * RadioError:REQUEST_NOT_SUPPORTED - */ - void releasePduSessionIdResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INVALID_ARGUMENTS - * RadioError:NO_MEMORY - * RadioError:SYSTEM_ERR - * RadioError:REQUEST_RATE_LIMITED - * RadioError:MODEM_ERR - * RadioError:INVALID_STATE - * RadioError:INTERNAL_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:SIM_ABSENT - */ - void reportSmsMemoryStatusResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INTERNAL_ERR - * RadioError:NO_MEMORY - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:REQUEST_NOT_SUPPORTED - */ - void reportStkServiceIsRunningResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param result IccIoResult as defined in types.hal - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INTERNAL_ERR - * RadioError:NO_MEMORY - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:INVALID_MODEM_STATE - * RadioError:SIM_ERR - * RadioError:INVALID_ARGUMENTS - * RadioError:REQUEST_NOT_SUPPORTED - */ - void requestIccSimAuthenticationResponse(in RadioResponseInfo info, in IccIoResult result); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param response response string of the challenge/response algo for ISIM auth in base64 format - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INTERNAL_ERR - * RadioError:NO_MEMORY - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:INVALID_MODEM_STATE - * RadioError:INVALID_ARGUMENTS - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:SIM_ABSENT - */ - void requestIsimAuthenticationResponse(in RadioResponseInfo info, in String response); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:OPERATION_NOT_ALLOWED - * RadioError:NO_MEMORY - * RadioError:INTERNAL_ERR - * RadioError:SYSTEM_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - */ - void requestShutdownResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INVALID_ARGUMENTS - * RadioError:NO_MEMORY - * RadioError:INTERNAL_ERR - * RadioError:SYSTEM_ERR - * RadioError:MODEM_ERR - * RadioError:INVALID_CALL_ID - * RadioError:INVALID_STATE - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:INVALID_MODEM_STATE - * RadioError:OPERATION_NOT_ALLOWED - */ - void sendBurstDtmfResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INVALID_ARGUMENTS - * RadioError:NO_MEMORY - * RadioError:INTERNAL_ERR - * RadioError:SYSTEM_ERR - * RadioError:MODEM_ERR - * RadioError:INVALID_CALL_ID - * RadioError:INVALID_STATE - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:INVALID_MODEM_STATE - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:OPERATION_NOT_ALLOWED - */ - void sendCDMAFeatureCodeResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param sms Response to sms sent as defined by SendSmsResult in types.hal - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:SMS_SEND_FAIL_RETRY - * RadioError:NETWORK_REJECT - * RadioError:INVALID_STATE - * RadioError:INVALID_ARGUMENTS - * RadioError:NO_MEMORY - * RadioError:REQUEST_RATE_LIMITED - * RadioError:INVALID_SMS_FORMAT - * RadioError:SYSTEM_ERR - * RadioError:FDN_CHECK_FAILURE - * RadioError:ENCODING_ERR - * RadioError:INVALID_SMSC_ADDRESS - * RadioError:MODEM_ERR - * RadioError:NETWORK_ERR - * RadioError:INTERNAL_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:INVALID_MODEM_STATE - * RadioError:NETWORK_NOT_READY - * RadioError:OPERATION_NOT_ALLOWED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:SIM_ABSENT - * RadioError:SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED - * RadioError:ACCESS_BARRED - * RadioError:BLOCKED_DUE_TO_CALL - */ - void sendCdmaSmsExpectMoreResponse(in RadioResponseInfo info, in SendSmsResult sms); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param sms Sms result struct as defined by SendSmsResult in types.hal - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INVALID_ARGUMENTS - * RadioError:SMS_SEND_FAIL_RETRY - * RadioError:NETWORK_REJECT - * RadioError:INVALID_STATE - * RadioError:NO_MEMORY - * RadioError:REQUEST_RATE_LIMITED - * RadioError:INVALID_SMS_FORMAT - * RadioError:SYSTEM_ERR - * RadioError:FDN_CHECK_FAILURE - * RadioError:MODEM_ERR - * RadioError:NETWORK_ERR - * RadioError:ENCODING_ERR - * RadioError:INVALID_SMSC_ADDRESS - * RadioError:INTERNAL_ERR - * RadioError:SYSTEM_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:OPERATION_NOT_ALLOWED - * RadioError:ENCODING_ERR - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:SIM_ABSENT - * RadioError:SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED - * RadioError:ACCESS_BARRED - * RadioError:BLOCKED_DUE_TO_CALL - */ - void sendCdmaSmsResponse(in RadioResponseInfo info, in SendSmsResult sms); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:NO_MEMORY - * RadioError:INTERNAL_ERR - * RadioError:SYSTEM_ERR - * RadioError:INVALID_ARGUMENTS - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - */ - void sendDeviceStateResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INVALID_ARGUMENTS - * RadioError:NO_RESOURCES - * RadioError:NO_MEMORY - * RadioError:MODEM_ERR - * RadioError:INVALID_CALL_ID - * RadioError:INTERNAL_ERR - * RadioError:SYSTEM_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:CANCELLED - * RadioError:INVALID_MODEM_STATE - */ - void sendDtmfResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param commandResponse SAT/USAT response in hexadecimal format string starting with first - * byte of response - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:SIM_BUSY - * RadioError:OPERATION_NOT_ALLOWED - * RadioError:INTERNAL_ERR - * RadioError:NO_MEMORY - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:INVALID_ARGUMENTS - * RadioError:MODEM_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:SIM_ABSENT - */ - void sendEnvelopeResponse(in RadioResponseInfo info, in String commandResponse); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param iccIo IccIoResult as defined in types.hal corresponding to ICC IO response - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:SIM_BUSY - * RadioError:OPERATION_NOT_ALLOWED - * RadioError:INTERNAL_ERR - * RadioError:NO_MEMORY - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:SIM_ABSENT - */ - void sendEnvelopeWithStatusResponse(in RadioResponseInfo info, in IccIoResult iccIo); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param sms Response to sms sent as defined by SendSmsResult in types.hal - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:SMS_SEND_FAIL_RETRY - * RadioError:FDN_CHECK_FAILURE - * RadioError:NETWORK_REJECT - * RadioError:INVALID_ARGUMENTS - * RadioError:INVALID_STATE - * RadioError:NO_MEMORY - * RadioError:INVALID_SMS_FORMAT - * RadioError:SYSTEM_ERR - * RadioError:REQUEST_RATE_LIMITED - * RadioError:MODEM_ERR - * RadioError:NETWORK_ERR - * RadioError:ENCODING_ERR - * RadioError:OPERATION_NOT_ALLOWED - * RadioError:INTERNAL_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:NETWORK_NOT_READY - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - */ - void sendImsSmsResponse(in RadioResponseInfo info, in SendSmsResult sms); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param sms Response to sms sent as defined by SendSmsResult in types.hal - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:SMS_SEND_FAIL_RETRY - * RadioError:NETWORK_REJECT - * RadioError:INVALID_STATE - * RadioError:INVALID_ARGUMENTS - * RadioError:NO_MEMORY - * RadioError:REQUEST_RATE_LIMITED - * RadioError:INVALID_SMS_FORMAT - * RadioError:SYSTEM_ERR - * RadioError:FDN_CHECK_FAILURE - * RadioError:ENCODING_ERR - * RadioError:INVALID_SMSC_ADDRESS - * RadioError:MODEM_ERR - * RadioError:NETWORK_ERR - * RadioError:INTERNAL_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:INVALID_MODEM_STATE - * RadioError:NETWORK_NOT_READY - * RadioError:OPERATION_NOT_ALLOWED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:SIM_ABSENT - */ - void sendSMSExpectMoreResponse(in RadioResponseInfo info, in SendSmsResult sms); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param sms Response to sms sent as defined by SendSmsResult in types.hal - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:SMS_SEND_FAIL_RETRY - * RadioError:NETWORK_REJECT - * RadioError:INVALID_STATE - * RadioError:INVALID_ARGUMENTS - * RadioError:NO_MEMORY - * RadioError:REQUEST_RATE_LIMITED - * RadioError:INVALID_SMS_FORMAT - * RadioError:SYSTEM_ERR - * RadioError:FDN_CHECK_FAILURE - * RadioError:ENCODING_ERR - * RadioError:INVALID_SMSC_ADDRESS - * RadioError:MODEM_ERR - * RadioError:NETWORK_ERR - * RadioError:INTERNAL_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:INVALID_MODEM_STATE - * RadioError:NETWORK_NOT_READY - * RadioError:OPERATION_NOT_ALLOWED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:SIM_ABSENT - * RadioError:ACCESS_BARRED - * RadioError:BLOCKED_DUE_TO_CALL - */ - void sendSmsExpectMoreResponse(in RadioResponseInfo info, in SendSmsResult sms); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param sms Response to sms sent as defined by SendSmsResult in types.hal - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:SMS_SEND_FAIL_RETRY - * RadioError:NETWORK_REJECT - * RadioError:INVALID_STATE - * RadioError:INVALID_ARGUMENTS - * RadioError:NO_MEMORY - * RadioError:REQUEST_RATE_LIMITED - * RadioError:INVALID_SMS_FORMAT - * RadioError:SYSTEM_ERR - * RadioError:ENCODING_ERR - * RadioError:INVALID_SMSC_ADDRESS - * RadioError:MODEM_ERR - * RadioError:NETWORK_ERR - * RadioError:INTERNAL_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:INVALID_MODEM_STATE - * RadioError:NETWORK_NOT_READY - * RadioError:OPERATION_NOT_ALLOWED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:SIM_ABSENT - * RadioError:ACCESS_BARRED - * RadioError:BLOCKED_DUE_TO_CALL - */ - void sendSmsResponse(in RadioResponseInfo info, in SendSmsResult sms); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INVALID_ARGUMENTS - * RadioError:OPERATION_NOT_ALLOWED - * RadioError:INTERNAL_ERR - * RadioError:NO_MEMORY - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:INVALID_MODEM_STATE - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:SIM_ABSENT - */ - void sendTerminalResponseToSimResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:FDN_CHECK_FAILURE - * RadioError:USSD_MODIFIED_TO_DIAL - * RadioError:USSD_MODIFIED_TO_SS - * RadioError:USSD_MODIFIED_TO_USSD - * RadioError:SIM_BUSY - * RadioError:OPERATION_NOT_ALLOWED - * RadioError:INVALID_ARGUMENTS - * RadioError:NO_MEMORY - * RadioError:MODEM_ERR - * RadioError:INTERNAL_ERR - * RadioError:ABORTED - * RadioError:SYSTEM_ERR - * RadioError:INVALID_STATE - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:INVALID_MODEM_STATE - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - */ - void sendUssdResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INVALID_ARGUMENTS - * RadioError:INVALID_STATE - * RadioError:NO_RESOURCES - * RadioError:NO_MEMORY - * RadioError:MODEM_ERR - * RadioError:SYSTEM_ERR - * RadioError:INTERNAL_ERR - * RadioError:INVALID_CALL_ID - * RadioError:OPERATION_NOT_ALLOWED - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:INVALID_MODEM_STATE - * RadioError:CANCELLED - */ - void separateConnectionResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INVALID_ARGUMENTS - * RadioError:REQUEST_NOT_SUPPORTED - */ - void setAllowedCarriersResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:OPERATION_NOT_ALLOWED - * RadioError:MODE_NOT_SUPPORTED - * RadioError:INTERNAL_ERR - * RadioError:INVALID_ARGUMENTS - * RadioError:MODEM_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:NO_RESOURCES - */ - void setAllowedNetworkTypesBitmapResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:OPERATION_NOT_ALLOWED - * RadioError:NO_MEMORY - * RadioError:INTERNAL_ERR - * RadioError:SYSTEM_ERR - * RadioError:INVALID_ARGUMENTS - * RadioError:MODEM_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - */ - void setBandModeResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:SS_MODIFIED_TO_DIAL - * RadioError:SS_MODIFIED_TO_USSD - * RadioError:SS_MODIFIED_TO_SS - * RadioError:INVALID_ARGUMENTS - * RadioError:NO_MEMORY - * RadioError:MODEM_ERR - * RadioError:INTERNAL_ERR - * RadioError:SYSTEM_ERR - * RadioError:FDN_CHECK_FAILURE - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - */ - void setBarringPasswordResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:SS_MODIFIED_TO_DIAL - * RadioError:SS_MODIFIED_TO_USSD - * RadioError:SS_MODIFIED_TO_SS - * RadioError:INVALID_ARGUMENTS - * RadioError:NO_MEMORY - * RadioError:SYSTEM_ERR - * RadioError:MODEM_ERR - * RadioError:INTERNAL_ERR - * RadioError:INVALID_STATE - * RadioError:FDN_CHECK_FAILURE - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:INVALID_MODEM_STATE - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - */ - void setCallForwardResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:SS_MODIFIED_TO_DIAL - * RadioError:SS_MODIFIED_TO_USSD - * RadioError:SS_MODIFIED_TO_SS - * RadioError:INVALID_ARGUMENTS - * RadioError:NO_MEMORY - * RadioError:MODEM_ERR - * RadioError:INTERNAL_ERR - * RadioError:INVALID_STATE - * RadioError:FDN_CHECK_FAILURE - * RadioError:SYSTEM_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:INVALID_MODEM_STATE - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - */ - void setCallWaitingResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:RIL_E_SUCCESS - * RadioError:RIL_E_RADIO_NOT_AVAILABLE - * RadioError:SIM_ABSENT - * RadioError:RIL_E_REQUEST_NOT_SUPPORTED - * RadioError:INVALID_ARGUMENTS - * RadioError:MODEM_INTERNAL_FAILURE - */ - void setCarrierInfoForImsiEncryptionResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INVALID_ARGUMENTS - * RadioError:INVALID_STATE - * RadioError:NO_MEMORY - * RadioError:REQUEST_RATE_LIMITED - * RadioError:SYSTEM_ERR - * RadioError:MODEM_ERR - * RadioError:INTERNAL_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:OPERATION_NOT_ALLOWED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:INVALID_MODEM_STATE - */ - void setCdmaBroadcastActivationResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INVALID_ARGUMENTS - * RadioError:INVALID_STATE - * RadioError:NO_MEMORY - * RadioError:REQUEST_RATE_LIMITED - * RadioError:SYSTEM_ERR - * RadioError:MODEM_ERR - * RadioError:INTERNAL_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:INVALID_MODEM_STATE - */ - void setCdmaBroadcastConfigResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:NO_MEMORY - * RadioError:INTERNAL_ERR - * RadioError:SYSTEM_ERR - * RadioError:INVALID_ARGUMENTS - * RadioError:MODEM_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:OPERATION_NOT_ALLOWED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:SIM_ABSENT - */ - void setCdmaRoamingPreferenceResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:SIM_ABSENT - * RadioError:SUBSCRIPTION_NOT_AVAILABLE - * RadioError:INTERNAL_ERR - * RadioError:NO_MEMORY - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:REQUEST_NOT_SUPPORTED - */ - void setCdmaSubscriptionSourceResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:NO_MEMORY - * RadioError:INTERNAL_ERR - * RadioError:SYSTEM_ERR - * RadioError:INVALID_ARGUMENTS - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:REQUEST_NOT_SUPPORTED - */ - void setCellInfoListRateResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:INVALID_ARGUMENTS - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:SS_MODIFIED_TO_DIAL - * RadioError:SS_MODIFIED_TO_USSD - * RadioError:SS_MODIFIED_TO_SS - * RadioError:NO_MEMORY - * RadioError:INTERNAL_ERR - * RadioError:SYSTEM_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - */ - void setClirResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:NO_MEMORY - * RadioError:INTERNAL_ERR - * RadioError:SYSTEM_ERR - * RadioError:MODEM_ERR - * RadioError:INVALID_ARGUMENTS - * RadioError:DEVICE_IN_USE - * RadioError:INVALID_MODEM_STATE - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:REQUEST_NOT_SUPPORTED - */ - void setDataAllowedResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:SUBSCRIPTION_NOT_AVAILABLE - * RadioError:INTERNAL_ERR - * RadioError:NO_MEMORY - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:SIM_ABSENT - */ - void setDataProfileResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:MODEM_ERR - * RadioError:INVALID_ARGUMENTS - * RadioError:REQUEST_NOT_SUPPORTED - */ - void setDataThrottlingResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param retry 0 is the number of retries remaining, or -1 if unknown - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:SS_MODIFIED_TO_DIAL - * RadioError:SS_MODIFIED_TO_USSD - * RadioError:SS_MODIFIED_TO_SS - * RadioError:INVALID_ARGUMENTS - * RadioError:NO_MEMORY - * RadioError:MODEM_ERR - * RadioError:INTERNAL_ERR - * RadioError:SYSTEM_ERR - * RadioError:INVALID_STATE - * RadioError:FDN_CHECK_FAILURE - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:INVALID_MODEM_STATE - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - */ - void setFacilityLockForAppResponse(in RadioResponseInfo info, in int retry); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INVALID_ARGUMENTS - * RadioError:INVALID_STATE - * RadioError:NO_MEMORY - * RadioError:REQUEST_RATE_LIMITED - * RadioError:SYSTEM_ERR - * RadioError:MODEM_ERR - * RadioError:INTERNAL_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:OPERATION_NOT_ALLOWED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:INVALID_MODEM_STATE - */ - void setGsmBroadcastActivationResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INVALID_ARGUMENTS - * RadioError:INVALID_STATE - * RadioError:NO_MEMORY - * RadioError:REQUEST_RATE_LIMITED - * RadioError:SYSTEM_ERR - * RadioError:MODEM_ERR - * RadioError:INTERNAL_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:INVALID_MODEM_STATE - */ - void setGsmBroadcastConfigResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:INVALID_ARGUMENTS - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INTERNAL_ERR - * RadioError:SYSTEM_ERR - */ - void setIndicationFilterResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:SUBSCRIPTION_NOT_AVAILABLE - * RadioError:NO_MEMORY - * RadioError:INTERNAL_ERR - * RadioError:SYSTEM_ERR - * RadioError:MODEM_ERR - * RadioError:INVALID_ARGUMENTS - * RadioError:NOT_PROVISIONED - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - */ - void setInitialAttachApnResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:INVALID_ARGUMENTS - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INTERNAL_ERR - */ - void setLinkCapacityReportingCriteriaResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:NO_MEMORY - * RadioError:INTERNAL_ERR - * RadioError:SYSTEM_ERR - * RadioError:INVALID_ARGUMENTS - * RadioError:MODEM_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:SIM_ABSENT - */ - void setLocationUpdatesResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INVALID_ARGUMENTS - * RadioError:NO_MEMORY - * RadioError:REQUEST_RATE_LIMITED - * RadioError:INTERNAL_ERR - * RadioError:SYSTEM_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - */ - void setMuteResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:ILLEGAL_SIM_OR_ME - * RadioError:OPERATION_NOT_ALLOWED - * RadioError:NO_MEMORY - * RadioError:INTERNAL_ERR - * RadioError:SYSTEM_ERR - * RadioError:INVALID_ARGUMENTS - * RadioError:MODEM_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * - * Returns RadioError:ILLEGAL_SIM_OR_ME when the failure is permanent and - * no retries needed, such as illegal SIM or ME. - */ - void setNetworkSelectionModeAutomaticResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:ILLEGAL_SIM_OR_ME - * RadioError:OPERATION_NOT_ALLOWED - * RadioError:INVALID_STATE - * RadioError:NO_MEMORY - * RadioError:INTERNAL_ERR - * RadioError:SYSTEM_ERR - * RadioError:INVALID_ARGUMENTS - * RadioError:MODEM_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * - * Returns RadioError:ILLEGAL_SIM_OR_ME when the failure is permanent and - * no retries needed, such as illegal SIM or ME. - */ - void setNetworkSelectionModeManualResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INTERNAL_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:INVALID_STATE - */ - void setNrDualConnectivityStateResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:OPERATION_NOT_ALLOWED - * RadioError:MODE_NOT_SUPPORTED - * RadioError:INTERNAL_ERR - * RadioError:INVALID_ARGUMENTS - * RadioError:MODEM_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:NO_RESOURCES - */ - void setPreferredNetworkTypeBitmapResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:OPERATION_NOT_ALLOWED - * RadioError:MODE_NOT_SUPPORTED - * RadioError:NO_MEMORY - * RadioError:INTERNAL_ERR - * RadioError:SYSTEM_ERR - * RadioError:INVALID_ARGUMENTS - * RadioError:MODEM_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - */ - void setPreferredNetworkTypeResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INVALID_ARGUMENTS - * RadioError:MODEM_ERR - * RadioError:INTERNAL_ERR - * RadioError:NO_MEMORY - * RadioError:SYSTEM_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:INVALID_CALL_ID - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - */ - void setPreferredVoicePrivacyResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param rc Radio capability as defined by RadioCapability in types.hal used to - * feedback return status - * - * Valid errors returned: - * RadioError:NONE means a unsol radioCapability() will be sent within 30 seconds. - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:OPERATION_NOT_ALLOWED - * RadioError:NO_MEMORY - * RadioError:INTERNAL_ERR - * RadioError:SYSTEM_ERR - * RadioError:INVALID_ARGUMENTS - * RadioError:MODEM_ERR - * RadioError:INVALID_STATE - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - */ - void setRadioCapabilityResponse(in RadioResponseInfo info, in RadioCapability rc); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:INTERNAL_ERR - * RadioError:INVALID_ARGUMENTS - * RadioError:RF_HARDWARE_ISSUE - * RadioError:NO_RF_CALIBRATION_INFO - */ - void setRadioPowerResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:INVALID_ARGUMENTS - * RadioError:RADIO_NOT_AVAILABLE - */ - void setSignalStrengthReportingCriteriaResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INVALID_ARGUMENTS - * RadioError:SIM_ERR (indicates a timeout or other issue making the SIM unresponsive) - */ - void setSimCardPowerResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INVALID_ARGUMENTS - * RadioError:INVALID_SMS_FORMAT - * RadioError:NO_MEMORY - * RadioError:SYSTEM_ERR - * RadioError:REQUEST_RATE_LIMITED - * RadioError:MODEM_ERR - * RadioError:NO_RESOURCES - * RadioError:INTERNAL_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:OPERATION_NOT_ALLOWED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:SIM_ABSENT - */ - void setSmscAddressResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INVALID_ARGUMENTS - * RadioError:SIM_BUSY - * RadioError:NO_MEMORY - * RadioError:SYSTEM_ERR - * RadioError:MODEM_ERR - * RadioError:INTERNAL_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:SIM_ABSENT - */ - void setSuppServiceNotificationsResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INTERNAL_ERR - * RadioError:INVALID_ARGUMENTS - */ - void setSystemSelectionChannelsResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INVALID_ARGUMENTS - * RadioError:MODEM_ERR - * RadioError:INTERNAL_ERR - * RadioError:NO_MEMORY - * RadioError:SYSTEM_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - */ - void setTTYModeResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:SUBSCRIPTION_NOT_SUPPORTED - * RadioError:NO_MEMORY - * RadioError:INTERNAL_ERR - * RadioError:SYSTEM_ERR - * RadioError:MODEM_ERR - * RadioError:INVALID_ARGUMENTS - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - */ - void setUiccSubscriptionResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param dcResponse SetupDataCallResult defined in types.hal - * - * Valid errors returned: - * RadioError:NONE must be returned on both success and failure of setup with the - * DataCallResponse.status containing the actual status - * For all other errors the DataCallResponse is ignored. - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:OP_NOT_ALLOWED_BEFORE_REG_TO_NW - * RadioError:OP_NOT_ALLOWED_DURING_VOICE_CALL - * RadioError:INVALID_ARGUMENTS - * RadioError:INTERNAL_ERR - * RadioError:NO_RESOURCES if the vendor is unable handle due to resources are full. - * RadioError:SIM_ABSENT - */ - void setupDataCallResponse(in RadioResponseInfo info, in SetupDataCallResult dcResponse); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INVALID_ARGUMENTS - * RadioError:NO_RESOURCES - * RadioError:NO_MEMORY - * RadioError:SYSTEM_ERR - * RadioError:MODEM_ERR - * RadioError:INTERNAL_ERR - * RadioError:INVALID_CALL_ID - * RadioError:SYSTEM_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:CANCELLED - * RadioError:INVALID_MODEM_STATE - */ - void startDtmfResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INTERNAL_ERR - * RadioError:NO_RESOURCES - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:INVALID_CALL_ID - */ - void startHandoverResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param status Status object containing a new handle and a current status. The status returned - * here may be PENDING to indicate that the radio has not yet processed the keepalive - * request. - * - * Valid errors returned: - * RadioError:NONE - * RadioError:NO_RESOURCES - * RadioError:INVALID_ARGUMENTS - */ - void startKeepaliveResponse(in RadioResponseInfo info, in KeepaliveStatus status); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param statusInfo LceStatusInfo indicating LCE status - * - * Valid errors returned: - * RadioError:REQUEST_NOT_SUPPORTED may be returned when HAL 1.2 or higher is supported. - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:LCE_NOT_SUPPORTED - * RadioError:INTERNAL_ERR - * RadioError:NO_MEMORY - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - */ - void startLceServiceResponse(in RadioResponseInfo info, in LceStatusInfo statusInfo); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:DEVICE_IN_USE - * RadioError:INTERNAL_ERR - * RadioError:MODEM_ERR - * RadioError:INVALID_ARGUMENTS - */ - void startNetworkScanResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INVALID_ARGUMENTS - * RadioError:NO_RESOURCES - * RadioError:NO_MEMORY - * RadioError:INVALID_ARGUMENTS - * RadioError:SYSTEM_ERR - * RadioError:MODEM_ERR - * RadioError:INTERNAL_ERR - * RadioError:INVALID_CALL_ID - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:CANCELLED - * RadioError:INVALID_MODEM_STATE - */ - void stopDtmfResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:INVALID_ARGUMENTS - */ - void stopKeepaliveResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param statusInfo LceStatusInfo indicating LCE status - * - * Valid errors returned: - * RadioError:REQUEST_NOT_SUPPORTED may be returned when HAL 1.2 or higher is supported. - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:LCE_NOT_SUPPORTED - * RadioError:INTERNAL_ERR - * RadioError:NO_MEMORY - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:SIM_ABSENT - */ - void stopLceServiceResponse(in RadioResponseInfo info, in LceStatusInfo statusInfo); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:INTERNAL_ERR - * RadioError:MODEM_ERR - */ - void stopNetworkScanResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param remainingRetries Number of retries remaining, must be equal to -1 if unknown. - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE (radio resetting) - * RadioError:PASSWORD_INCORRECT - * RadioError:INTERNAL_ERR - * RadioError:NO_MEMORY - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:INVALID_ARGUMENTS - * RadioError:INVALID_SIM_STATE - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:SIM_PUK2 - */ - void supplyIccPin2ForAppResponse(in RadioResponseInfo info, in int remainingRetries); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param remainingRetries Number of retries remaining, must be equal to -1 if unknown. - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE (radio resetting) - * RadioError:PASSWORD_INCORRECT - * RadioError:INTERNAL_ERR - * RadioError:NO_MEMORY - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:INVALID_ARGUMENTS - * RadioError:INVALID_SIM_STATE - * RadioError:REQUEST_NOT_SUPPORTED - */ - void supplyIccPinForAppResponse(in RadioResponseInfo info, in int remainingRetries); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param remainingRetries Number of retries remaining, must be equal to -1 if unknown. - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE (radio resetting) - * RadioError:PASSWORD_INCORRECT (PUK is invalid) - * RadioError:INTERNAL_ERR - * RadioError:NO_MEMORY - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:INVALID_ARGUMENTS - * RadioError:INVALID_SIM_STATE - * RadioError:REQUEST_NOT_SUPPORTED - */ - void supplyIccPuk2ForAppResponse(in RadioResponseInfo info, in int remainingRetries); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param remainingRetries Number of retries remaining, must be equal to -1 if unknown. - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE (radio resetting) - * RadioError:PASSWORD_INCORRECT (PUK is invalid) - * RadioError:INTERNAL_ERR - * RadioError:NO_MEMORY - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:INVALID_ARGUMENTS - * RadioError:INVALID_SIM_STATE - * RadioError:REQUEST_NOT_SUPPORTED - */ - void supplyIccPukForAppResponse(in RadioResponseInfo info, in int remainingRetries); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param remainingRetries Number of retries remaining, must be equal to -1 if unknown. - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:PASSWORD_INCORRECT (code is invalid) - * RadioError:NO_MEMORY - * RadioError:INVALID_SIM_STATE - * RadioError:INTERNAL_ERR - * RadioError:SYSTEM_ERR - * RadioError:MODEM_ERR - * RadioError:INVALID_ARGUMENTS - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:SIM_ABSENT - */ - void supplyNetworkDepersonalizationResponse(in RadioResponseInfo info, in int remainingRetries); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param persoType SIM Personalisation type - * @param remainingRetries postiive values indicates number of retries remaining, must be equal - * to -1 if number of retries is infinite. - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:PASSWORD_INCORRECT (code is invalid) - * RadioError:NO_MEMORY - * RadioError:INVALID_SIM_STATE - * RadioError:INTERNAL_ERR - * RadioError:SYSTEM_ERR - * RadioError:MODEM_ERR - * RadioError:INVALID_ARGUMENTS - * RadioError:NO_RESOURCES - * RadioError:REQUEST_NOT_SUPPORTED - */ - void supplySimDepersonalizationResponse( - in RadioResponseInfo info, in PersoSubstate persoType, in int remainingRetries); - - /** - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE (radio resetting) - * RadioError:INVALID_STATE - * RadioError:NO_MEMORY - * RadioError:MODEM_ERR - * RadioError:INTERNAL_ERR - * RadioError:INVALID_STATE - * RadioError:INVALID_CALL_ID - * RadioError:OPERATION_NOT_ALLOWED - * RadioError:INVALID_ARGUMENTS - * RadioError:SYSTEM_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:INVALID_MODEM_STATE - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - */ - void switchWaitingOrHoldingAndActiveResponse(in RadioResponseInfo info); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param updatedRecordIndex The index of the updated or inserted record in the phonebook and - * the minimum value is 1 - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:INVALID_ARGUMENTS - * RadioError:INVALID_SIM_STATE - * RadioError:MODEM_ERR - * RadioError:INTERNAL_ERR - * RadioError:SIM_ERR - * RadioError:NO_SUCH_ENTRY - * RadioError:NO_RESOURCES - * REQUEST_NOT_SUPPORTED may only be returned on devices that don't support this API, - * indicated by the HAL capability CAPABILITY_SIM_PHONEBOOK_IN_MODEM. - */ - void updateSimPhonebookRecordsResponse(in RadioResponseInfo info, in int updatedRecordIndex); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param index record index where the cmda sms message is stored - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INVALID_ARGUMENTS - * RadioError:INVALID_SMS_FORMAT - * RadioError:SIM_FULL - * RadioError:INTERNAL_ERR - * RadioError:MODEM_ERR - * RadioError:ENCODING_ERR - * RadioError:NO_MEMORY - * RadioError:NO_RESOURCES - * RadioError:INVALID_MODEM_STATE - * RadioError:INVALID_SMSC_ADDRESS - * RadioError:SYSTEM_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:OPERATION_NOT_ALLOWED - * RadioError:NO_RESOURCES - * RadioError:CANCELLED - * RadioError:INVALID_MODEM_STATE - * RadioError:SIM_ABSENT - */ - void writeSmsToRuimResponse(in RadioResponseInfo info, in int index); - - /** - * @param info Response info struct containing response type, serial no. and error - * @param index record index where the message is stored - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:SIM_FULL - * RadioError:INVALID_ARGUMENTS - * RadioError:INVALID_SMS_FORMAT - * RadioError:INTERNAL_ERR - * RadioError:MODEM_ERR - * RadioError:ENCODING_ERR - * RadioError:NO_MEMORY - * RadioError:NO_RESOURCES - * RadioError:INVALID_MODEM_STATE - * RadioError:OPERATION_NOT_ALLOWED - * RadioError:INVALID_SMSC_ADDRESS - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:SYSTEM_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:CANCELLED - * RadioError:INVALID_MODEM_STATE - * RadioError:SIM_ABSENT - */ - void writeSmsToSimResponse(in RadioResponseInfo info, in int index); -} diff --git a/radio/aidl/android/hardware/radio/LceStatusInfo.aidl b/radio/aidl/android/hardware/radio/LceStatusInfo.aidl deleted file mode 100644 index d663d38597..0000000000 --- a/radio/aidl/android/hardware/radio/LceStatusInfo.aidl +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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.radio; - -@VintfStability -parcelable LceStatusInfo { - const int LCE_STATUS_NOT_SUPPORTED = 0; - const int LCE_STATUS_STOPPED = 1; - const int LCE_STATUS_ACTIVE = 2; - - /** - * Values are LCE_STATUS_ - */ - int lceStatus; - /** - * Actual LCE reporting interval, meaningful only if LceStatus = ACTIVE. - */ - byte actualIntervalMs; -} diff --git a/radio/aidl/android/hardware/radio/PreferredNetworkType.aidl b/radio/aidl/android/hardware/radio/PreferredNetworkType.aidl deleted file mode 100644 index 7ca38c6a79..0000000000 --- a/radio/aidl/android/hardware/radio/PreferredNetworkType.aidl +++ /dev/null @@ -1,114 +0,0 @@ -/* - * 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.radio; - -@VintfStability -@Backing(type="int") -enum PreferredNetworkType { - /** - * GSM/WCDMA (WCDMA preferred) - */ - GSM_WCDMA, - /** - * GSM only - */ - GSM_ONLY, - /** - * WCDMA - */ - WCDMA, - /** - * GSM/WCDMA (auto mode, according to PRL) - */ - GSM_WCDMA_AUTO, - /** - * CDMA and EvDo (auto mode, according to PRL) - */ - CDMA_EVDO_AUTO, - /** - * CDMA only - */ - CDMA_ONLY, - /** - * EvDo only - */ - EVDO_ONLY, - /** - * GSM/WCDMA, CDMA, and EvDo (auto mode, according to PRL) - */ - GSM_WCDMA_CDMA_EVDO_AUTO, - /** - * LTE, CDMA and EvDo - */ - LTE_CDMA_EVDO, - /** - * LTE, GSM/WCDMA - */ - LTE_GSM_WCDMA, - /** - * LTE, CDMA, EvDo, GSM/WCDMA - */ - LTE_CMDA_EVDO_GSM_WCDMA, - /** - * LTE only - */ - LTE_ONLY, - /** - * LTE/WCDMA only - */ - LTE_WCDMA, - /** - * TD-SCDMA only - */ - TD_SCDMA_ONLY, - /** - * TD-SCDMA and WCDMA - */ - TD_SCDMA_WCDMA, - /** - * TD-SCDMA and LTE - */ - TD_SCDMA_LTE, - /** - * TD-SCDMA and GSM - */ - TD_SCDMA_GSM, - /** - * TD-SCDMA,GSM and LTE - */ - TD_SCDMA_GSM_LTE, - /** - * TD-SCDMA, GSM/WCDMA - */ - TD_SCDMA_GSM_WCDMA, - /** - * TD-SCDMA, WCDMA and LTE - */ - TD_SCDMA_WCDMA_LTE, - /** - * TD-SCDMA, GSM/WCDMA and LTE - */ - TD_SCDMA_GSM_WCDMA_LTE, - /** - * TD-SCDMA, GSM/WCDMA, CDMA and EvDo - */ - TD_SCDMA_GSM_WCDMA_CDMA_EVDO_AUTO, - /** - * TD-SCDMA, LTE, CDMA, EvDo GSM/WCDMA - */ - TD_SCDMA_LTE_CDMA_EVDO_GSM_WCDMA, -} diff --git a/radio/aidl/android/hardware/radio/RadioAccessNetworks.aidl b/radio/aidl/android/hardware/radio/RadioAccessNetworks.aidl deleted file mode 100644 index 3757233f24..0000000000 --- a/radio/aidl/android/hardware/radio/RadioAccessNetworks.aidl +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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.radio; - -@VintfStability -@Backing(type="int") -enum RadioAccessNetworks { - UNKNOWN, - /** - * GSM EDGE Radio Access Network - */ - GERAN, - /** - * Universal Terrestrial Radio Access Network - */ - UTRAN, - /** - * Evolved Universal Terrestrial Radio Access Network - */ - EUTRAN, - /** - * Next Generation Radio Access Network - */ - NGRAN, - /** - * CDMA 2000 Network - */ - CDMA2000, -} diff --git a/radio/aidl/android/hardware/radio/RadioFrequencyInfo.aidl b/radio/aidl/android/hardware/radio/RadioFrequencyInfo.aidl deleted file mode 100644 index 140d65af46..0000000000 --- a/radio/aidl/android/hardware/radio/RadioFrequencyInfo.aidl +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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.radio; - -@VintfStability -union RadioFrequencyInfo { - /** - * Indicates the frequency range is below 1GHz. - */ - const int FREQUENCY_RANGE_LOW = 1; - /** - * Indicates the frequency range is between 1GHz and 3GHz. - */ - const int FREQUENCY_RANGE_MID = 2; - /** - * Indicates the frequency range is between 3GHz and 6GHz. - */ - const int FREQUENCY_RANGE_HIGH = 3; - /** - * Indicates the frequency range is above 6GHz (millimeter wave frequency). - */ - const int FREQUENCY_RANGE_MMWAVE = 4; - - boolean noinit; - /** - * A rough frequency range. - * Values are FREQUENCY_RANGE_ - */ - int range; - /** - * The Absolute Radio Frequency Channel Number. - */ - int channelNumber; -} diff --git a/radio/aidl/android/hardware/radio/VoiceRegStateResult.aidl b/radio/aidl/android/hardware/radio/VoiceRegStateResult.aidl deleted file mode 100644 index 897c663621..0000000000 --- a/radio/aidl/android/hardware/radio/VoiceRegStateResult.aidl +++ /dev/null @@ -1,94 +0,0 @@ -/* - * 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.radio; - -import android.hardware.radio.CellIdentity; -import android.hardware.radio.RegState; - -@VintfStability -parcelable VoiceRegStateResult { - /** - * Valid reg states are NOT_REG_MT_NOT_SEARCHING_OP, REG_HOME, NOT_REG_MT_SEARCHING_OP, - * REG_DENIED, UNKNOWN, REG_ROAMING defined in RegState. - */ - RegState regState; - /** - * Indicates the available voice radio technology, valid values as defined by RadioTechnology. - */ - int rat; - /** - * Concurrent services support indicator, if registered on a CDMA system. - * false - Concurrent services not supported, - * true - Concurrent services supported - */ - boolean cssSupported; - /** - * TSB-58 Roaming Indicator if registered on a CDMA or EVDO system or -1 if not. - * Valid values are 0-255. - */ - int roamingIndicator; - /** - * Indicates whether the current system is in the PRL if registered on a CDMA or EVDO system - * or -1 if not. 0=not in the PRL, 1=in the PRL - */ - int systemIsInPrl; - /** - * Default Roaming Indicator from the PRL if registered on a CDMA or EVDO system or -1 if not. - * Valid values are 0-255. - */ - int defaultRoamingIndicator; - /** - * Reason for denial if registration state is REG_DENIED. This is an enumerated reason why - * registration was denied. See 3GPP TS 24.008, 10.5.3.6 and Annex G. - * 0 - General - * 1 - Authentication Failure - * 2 - IMSI unknown in HLR - * 3 - Illegal MS - * 4 - Illegal ME - * 5 - PLMN not allowed - * 6 - Location area not allowed - * 7 - Roaming not allowed - * 8 - No Suitable Cells in this Location Area - * 9 - Network failure - * 10 - Persistent location update reject - * 11 - PLMN not allowed - * 12 - Location area not allowed - * 13 - Roaming not allowed in this Location Area - * 15 - No Suitable Cells in this Location Area - * 17 - Network Failure - * 20 - MAC Failure - * 21 - Sync Failure - * 22 - Congestion - * 23 - GSM Authentication unacceptable - * 25 - Not Authorized for this CSG - * 32 - Service option not supported - * 33 - Requested service option not subscribed - * 34 - Service option temporarily out of order - * 38 - Call cannot be identified - * 48-63 - Retry upon entry into a new cell - * 95 - Semantically incorrect message - * 96 - Invalid mandatory information - * 97 - Message type non-existent or not implemented - * 98 - Message type not compatible with protocol state - * 99 - Information element non-existent or not implemented - * 100 - Conditional IE error - * 101 - Message not compatible with protocol state - * 111 - Protocol error, unspecified - */ - int reasonForDenial; - CellIdentity cellIdentity; -} diff --git a/radio/aidl/android/hardware/radio/ApnAuthType.aidl b/radio/aidl/android/hardware/radio/data/ApnAuthType.aidl similarity index 96% rename from radio/aidl/android/hardware/radio/ApnAuthType.aidl rename to radio/aidl/android/hardware/radio/data/ApnAuthType.aidl index c836a31476..8209dfec02 100644 --- a/radio/aidl/android/hardware/radio/ApnAuthType.aidl +++ b/radio/aidl/android/hardware/radio/data/ApnAuthType.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.data; @VintfStability @Backing(type="int") diff --git a/radio/aidl/android/hardware/radio/ApnTypes.aidl b/radio/aidl/android/hardware/radio/data/ApnTypes.aidl similarity index 86% rename from radio/aidl/android/hardware/radio/ApnTypes.aidl rename to radio/aidl/android/hardware/radio/data/ApnTypes.aidl index 340301fd40..e780d8ee6b 100644 --- a/radio/aidl/android/hardware/radio/ApnTypes.aidl +++ b/radio/aidl/android/hardware/radio/data/ApnTypes.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.data; @VintfStability @Backing(type="int") @@ -64,11 +64,6 @@ enum ApnTypes { * in an emergency call situation. */ EMERGENCY = 1 << 9, - /** - * Due to the addition of values after EMERGENCY (eg. MCX, XCAP), this value is now deprecated - * and should not be used. - */ - ALL = DEFAULT | MMS | SUPL | DUN | HIPRI | FOTA | IMS | CBS | IA | EMERGENCY, /** * APN type for Mission Critical Service * Reference: 3GPP TS 22.280 V15.3.0 diff --git a/radio/aidl/android/hardware/radio/DataCallFailCause.aidl b/radio/aidl/android/hardware/radio/data/DataCallFailCause.aidl similarity index 99% rename from radio/aidl/android/hardware/radio/DataCallFailCause.aidl rename to radio/aidl/android/hardware/radio/data/DataCallFailCause.aidl index 021988b221..89cd8f2626 100644 --- a/radio/aidl/android/hardware/radio/DataCallFailCause.aidl +++ b/radio/aidl/android/hardware/radio/data/DataCallFailCause.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.data; @VintfStability @Backing(type="int") diff --git a/radio/aidl/android/hardware/radio/DataProfileInfo.aidl b/radio/aidl/android/hardware/radio/data/DataProfileInfo.aidl similarity index 90% rename from radio/aidl/android/hardware/radio/DataProfileInfo.aidl rename to radio/aidl/android/hardware/radio/data/DataProfileInfo.aidl index 2f7bbb19e0..7657fc9dac 100644 --- a/radio/aidl/android/hardware/radio/DataProfileInfo.aidl +++ b/radio/aidl/android/hardware/radio/data/DataProfileInfo.aidl @@ -14,12 +14,12 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.data; -import android.hardware.radio.ApnAuthType; -import android.hardware.radio.ApnTypes; -import android.hardware.radio.PdpProtocolType; import android.hardware.radio.RadioAccessFamily; +import android.hardware.radio.data.ApnAuthType; +import android.hardware.radio.data.ApnTypes; +import android.hardware.radio.data.PdpProtocolType; @VintfStability parcelable DataProfileInfo { @@ -111,8 +111,8 @@ parcelable DataProfileInfo { */ boolean preferred; /** - * If true, modem must persist this data profile and profileId must not be set to - * DataProfileId.INVALID. If the same data profile exists, this data profile must overwrite it. + * If true, modem must persist this data profile and profileId must not be set to ID_INVALID. + * If the same data profile exists, this data profile must overwrite it. */ boolean persistent; } diff --git a/radio/aidl/android/hardware/radio/DataRequestReason.aidl b/radio/aidl/android/hardware/radio/data/DataRequestReason.aidl similarity index 96% rename from radio/aidl/android/hardware/radio/DataRequestReason.aidl rename to radio/aidl/android/hardware/radio/data/DataRequestReason.aidl index 74afdcb328..2bb5bd69b3 100644 --- a/radio/aidl/android/hardware/radio/DataRequestReason.aidl +++ b/radio/aidl/android/hardware/radio/data/DataRequestReason.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.data; @VintfStability @Backing(type="int") diff --git a/radio/aidl/android/hardware/radio/DataThrottlingAction.aidl b/radio/aidl/android/hardware/radio/data/DataThrottlingAction.aidl similarity index 96% rename from radio/aidl/android/hardware/radio/DataThrottlingAction.aidl rename to radio/aidl/android/hardware/radio/data/DataThrottlingAction.aidl index 1a49762374..dfa64e2b9d 100644 --- a/radio/aidl/android/hardware/radio/DataThrottlingAction.aidl +++ b/radio/aidl/android/hardware/radio/data/DataThrottlingAction.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.data; @VintfStability @Backing(type="byte") diff --git a/radio/aidl/android/hardware/radio/EpsQos.aidl b/radio/aidl/android/hardware/radio/data/EpsQos.aidl similarity index 92% rename from radio/aidl/android/hardware/radio/EpsQos.aidl rename to radio/aidl/android/hardware/radio/data/EpsQos.aidl index ee4cbdd6c2..559a153e05 100644 --- a/radio/aidl/android/hardware/radio/EpsQos.aidl +++ b/radio/aidl/android/hardware/radio/data/EpsQos.aidl @@ -14,9 +14,9 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.data; -import android.hardware.radio.QosBandwidth; +import android.hardware.radio.data.QosBandwidth; /** * LTE/EPS Quality of Service parameters as per 3gpp spec 24.301 sec 9.9.4.3. diff --git a/radio/aidl/android/hardware/radio/data/IRadioData.aidl b/radio/aidl/android/hardware/radio/data/IRadioData.aidl new file mode 100644 index 0000000000..9f5ba4c147 --- /dev/null +++ b/radio/aidl/android/hardware/radio/data/IRadioData.aidl @@ -0,0 +1,281 @@ +/* + * 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.radio.data; + +import android.hardware.radio.AccessNetwork; +import android.hardware.radio.data.DataProfileInfo; +import android.hardware.radio.data.DataRequestReason; +import android.hardware.radio.data.DataThrottlingAction; +import android.hardware.radio.data.IRadioDataIndication; +import android.hardware.radio.data.IRadioDataResponse; +import android.hardware.radio.data.KeepaliveRequest; +import android.hardware.radio.data.LinkAddress; +import android.hardware.radio.data.SliceInfo; +import android.hardware.radio.data.TrafficDescriptor; + +/** + * This interface is used by telephony and telecom to talk to cellular radio for data APIs. + * All the functions have minimum one parameter: + * serial: which corresponds to serial no. of request. Serial numbers must only be memorized for the + * duration of a method call. If clients provide colliding serials (including passing the same + * serial to different methods), multiple responses (one for each method call) must still be served. + * setResponseFunctions must work with IRadioDataResponse and IRadioDataIndication. + */ +@VintfStability +oneway interface IRadioData { + /** + * Reserves an unallocated pdu session id from the pool of ids. The allocated id is returned + * in the response. When the id is no longer needed, call releasePduSessionId to return it to + * the pool. + * + * Reference: 3GPP TS 24.007 section 11.2.3.1b + * + * @param serial Serial number of request. + * + * Response function is IRadioDataResponse.allocatePduSessionIdResponse() + */ + void allocatePduSessionId(in int serial); + + /** + * Indicates that a handover was cancelled after a call to IRadioData::startHandover. + * Since the handover was unsuccessful, the modem retains ownership over any of the resources + * being transferred and is still responsible for releasing them. + * + * @param serial Serial number of request. + * @param id callId The identifier of the data call which is provided in SetupDataCallResult + * + * Response function is IRadioDataResponse.cancelHandoverResponse() + */ + void cancelHandover(in int serial, in int callId); + + /** + * Deactivate packet data connection and remove from the data call list. An + * unsolDataCallListChanged() must be sent when data connection is deactivated. + * + * @param serial Serial number of request. + * @param cid Data call id. + * @param reason The request reason. Must be normal, handover, or shutdown. + * + * Response function is IRadioDataResponse.deactivateDataCallResponse() + */ + void deactivateDataCall(in int serial, in int cid, in DataRequestReason reason); + + /** + * Returns the data call list. An entry is added when a setupDataCall() is issued and removed + * on a deactivateDataCall(). The list is emptied when setRadioPower() off/on issued or when + * the vendor HAL or modem crashes. + * + * @param serial Serial number of request. + * + * Response function is IRadioDataResponse.getDataCallListResponse() + */ + void getDataCallList(in int serial); + + /** + * Request to get 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 serial Serial number of request. + * + * Response function is IRadioDataResponse.getSlicingConfigResponse() + */ + void getSlicingConfig(in int serial); + + /** + * Releases a pdu session id that was previously allocated using allocatePduSessionId. + * Reference: 3GPP TS 24.007 section 11.2.3.1b + * + * @param serial Serial number of request. + * @param id Pdu session id to release. + * + * Response function is IRadioDataResponse.releasePduSessionIdResponse() + */ + void releasePduSessionId(in int serial, in int id); + + /** + * When response type received from a radio indication or radio response is + * RadioIndicationType:UNSOLICITED_ACK_EXP or RadioResponseType:SOLICITED_ACK_EXP respectively, + * acknowledge the receipt of those messages by sending responseAcknowledgement(). + */ + void responseAcknowledgement(); + + /** + * Tells the modem whether data calls are allowed or not + * + * @param serial Serial number of request. + * @param allow true to allow data calls, false to disallow data calls + * + * Response function is IRadioDataResponse.setDataAllowedResponse() + */ + void setDataAllowed(in int serial, in boolean allow); + + /** + * Send data profiles of the current carrier to the modem. + * + * @param serial Serial number of request. + * @param profiles Array of DataProfileInfo to set. + * + * Response function is IRadioDataResponse.setDataProfileResponse() + */ + void setDataProfile(in int serial, in DataProfileInfo[] profiles); + + /** + * Control data throttling at modem. + * - DataThrottlingAction:NO_DATA_THROTTLING should clear any existing data throttling within + * the requested completion window. + * - DataThrottlingAction:THROTTLE_SECONDARY_CARRIER: Remove any existing throttling on anchor + * carrier and achieve maximum data throttling on secondary carrier within the requested + * completion window. + * - DataThrottlingAction:THROTTLE_ANCHOR_CARRIER: disable secondary carrier and achieve maximum + * data throttling on anchor carrier by requested completion window. + * - DataThrottlingAction:HOLD: Immediately hold on to current level of throttling. + * + * @param serial Serial number of request. + * @param dataThrottlingAction DataThrottlingAction as defined in types.hal + * @param completionDurationMillis window, in milliseconds, in which the requested throttling + * action has to be achieved. This must be 0 when dataThrottlingAction is + * DataThrottlingAction:HOLD. + * + * Response function is IRadioDataResponse.setDataThrottlingResponse() + */ + void setDataThrottling(in int serial, in DataThrottlingAction dataThrottlingAction, + in long completionDurationMillis); + + /** + * Set an APN to initial attach network. + * + * @param serial Serial number of request. + * @param dataProfileInfo data profile containing APN settings + * + * Response function is IRadioDataResponse.setInitialAttachApnResponse() + */ + void setInitialAttachApn(in int serial, in DataProfileInfo dataProfileInfo); + + /** + * Set response functions for data radio requests and indications. + * + * @param radioDataResponse Object containing response functions + * @param radioDataIndication Object containing radio indications + */ + void setResponseFunctions( + in IRadioDataResponse radioDataResponse, in IRadioDataIndication radioDataIndication); + + /** + * Setup a packet data connection. If DataCallResponse.status returns DataCallFailCause:NONE, + * the data connection must be added to data calls and a unsolDataCallListChanged() must be + * sent. The call remains until removed by subsequent unsolDataCallIstChanged(). It may be lost + * due to many factors, including deactivateDataCall() being issued, the radio powered off, + * reception lost or even transient factors like congestion. This data call list is returned by + * getDataCallList() and dataCallListChanged(). + * The Radio is expected to: + * - Create one data call context. + * - Create and configure a dedicated interface for the context. + * - The interface must be point to point. + * - The interface is configured with one or more addresses and is capable of sending and + * receiving packets. The format is IP address with optional "/" prefix length (The format is + * defined in RFC-4291 section 2.3). For example, "192.0.1.3", "192.0.1.11/16", or + * "2001:db8::1/64". Typically one IPv4 or one IPv6 or one of each. If the prefix length is + * absent, then the addresses are assumed to be point to point with IPv4 with prefix length 32 + * or IPv6 with prefix length 128. + * - Must not modify routing configuration related to this interface; routing management is + * exclusively within the purview of the Android OS. + * - Support simultaneous data call context, with limits defined in the specifications. For LTE, + * the max number of data calls is equal to the max number of EPS bearers that can be active. + * + * @param serial Serial number of request. + * @param accessNetwork The access network to setup the data call. If the data connection cannot + * be established on the specified access network then this should respond with an error. + * @param dataProfileInfo Data profile info. + * @param roamingAllowed Indicates whether or not data roaming is allowed by the user. + * @param reason The request reason. Must be DataRequestReason:NORMAL or + * DataRequestReason:HANDOVER. + * @param addresses If the reason is DataRequestReason:HANDOVER, this indicates the list of link + * addresses of the existing data connection. This parameter must be ignored unless + * reason is DataRequestReason:HANDOVER. + * @param dnses If the reason is DataRequestReason:HANDOVER, this indicates the list of DNS + * addresses of the existing data connection. The format is defined in RFC-4291 section + * 2.2. For example, "192.0.1.3" or "2001:db8::1". This parameter must be ignored unless + * reason is DataRequestReason:HANDOVER. + * @param pduSessionId The pdu session id to be used for this data call. A value of 0 means no + * pdu session id was attached to this call. Reference: 3GPP TS 24.007 section 11.2.3.1b + * @param sliceInfo SliceInfo to be used for the data connection when a handover occurs from + * EPDG to 5G. It is valid only when accessNetwork is AccessNetwork:NGRAN. If the slice + * passed from EPDG is rejected, then the data failure cause must be + * DataCallFailCause:SLICE_REJECTED. + * @param trafficDescriptor TrafficDescriptor for which data connection needs to be established. + * It is used for URSP traffic matching as described in TS 24.526 Section 4.2.2. + * It includes an optional DNN which, if present, must be used for traffic matching -- + * it does not specify the end point to be used for the data call. The end point is + * specified by DataProfileInfo.apn; DataProfileInfo.apn must be used as the end point if + * one is not specified through URSP rules. + * @param matchAllRuleAllowed bool to indicate if using default match-all URSP rule for this + * request is allowed. If false, this request must not use the match-all URSP rule and if + * a non-match-all rule is not found (or if URSP rules are not available) it should + * return failure with cause DataCallFailCause:MATCH_ALL_RULE_NOT_ALLOWED. This is needed + * as some requests need to have a hard failure if the intention cannot be met, for + * example, a zero-rating slice. + * + * Response function is IRadioDataResponse.setupDataCallResponse() + */ + void setupDataCall(in int serial, in AccessNetwork accessNetwork, + in DataProfileInfo dataProfileInfo, in boolean roamingAllowed, + in DataRequestReason reason, in LinkAddress[] addresses, in String[] dnses, + in int pduSessionId, in @nullable SliceInfo sliceInfo, + in @nullable TrafficDescriptor trafficDescriptor, + in boolean matchAllRuleAllowed); + + /** + * Indicates that a handover to the IWLAN transport has begun. Any resources being transferred + * to the IWLAN transport cannot be released while a handover is underway. For example, if a + * pdu session id needs to be transferred to IWLAN, then the modem should not release the id + * while the handover is in progress. If a handover was unsuccessful, then the framework calls + * IRadio::cancelHandover. The modem retains ownership over any of the resources being + * transferred to IWLAN. If a handover was successful, the framework calls + * IRadio::deactivateDataCall with reason HANDOVER. The IWLAN transport now owns the transferred + * resources and is responsible for releasing them. + * + * @param serial Serial number of request. + * @param id callId The identifier of the data call which is provided in SetupDataCallResult + * + * Response function is IRadioDataResponse.startHandoverResponse() + */ + void startHandover(in int serial, in int callId); + + /** + * Start a Keepalive session (for IPsec) + * + * @param serial Serial number of request. + * @param keepalive A request structure containing all necessary info to describe a keepalive + * + * Response function is IRadioDataResponse.startKeepaliveResponse() + */ + void startKeepalive(in int serial, in KeepaliveRequest keepalive); + + /** + * Stop an ongoing Keepalive session (for IPsec) + * + * @param serial Serial number of request. + * @param sessionHandle The handle that was provided by + * IRadioDataResponse.startKeepaliveResponse + * + * Response function is IRadioDataResponse.stopKeepaliveResponse() + */ + void stopKeepalive(in int serial, in int sessionHandle); +} diff --git a/radio/aidl/android/hardware/radio/data/IRadioDataIndication.aidl b/radio/aidl/android/hardware/radio/data/IRadioDataIndication.aidl new file mode 100644 index 0000000000..8e73ee33af --- /dev/null +++ b/radio/aidl/android/hardware/radio/data/IRadioDataIndication.aidl @@ -0,0 +1,74 @@ +/* + * 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.radio.data; + +import android.hardware.radio.RadioIndicationType; +import android.hardware.radio.data.KeepaliveStatus; +import android.hardware.radio.data.PcoDataInfo; +import android.hardware.radio.data.SetupDataCallResult; + +/** + * Interface declaring unsolicited radio indications for data APIs. + */ +@VintfStability +oneway interface IRadioDataIndication { + /** + * Indicates data call contexts have changed. + * + * @param type Type of radio indication + * @param dcList Array of SetupDataCallResult identical to that returned by + * IRadioData.getDataCallList(). It is the complete list of current data contexts + * including new contexts that have been activated. A data call is only removed from + * this list when any of the below conditions is matched: + * - The framework sends a IRadioData.deactivateDataCall(). + * - The radio is powered off/on. + * - Unsolicited disconnect from either modem or network side. + */ + void dataCallListChanged(in RadioIndicationType type, in SetupDataCallResult[] dcList); + + /** + * Indicates a status update for a particular Keepalive session. This must include a handle for + * a previous session and should include a status update regarding the state of a keepalive. + * Unsolicited keepalive status reports should never be PENDING as unsolicited status should + * only be sent when known. + * + * @param type Type of radio indication + * @param status Status information for a Keepalive session + */ + void keepaliveStatus(in RadioIndicationType type, in KeepaliveStatus status); + + /** + * Indicates when there is new Carrier PCO data received for a data call. Ideally only new data + * must be forwarded, though this is not required. Multiple boxes of carrier PCO data for a + * given call must result in a series of pcoData() calls. + * + * @param type Type of radio indication + * @param pco New PcoData + */ + void pcoData(in RadioIndicationType type, in PcoDataInfo pco); + + /** + * The modem can explicitly set SetupDataCallResult::suggestedRetryTime after a failure in + * IRadioData.SetupDataCall. During that time, no new calls are allowed to + * IRadioData.SetupDataCall that use the same APN. When IRadioDataIndication.unthrottleApn + * is sent, AOSP will no longer throttle calls to IRadioData.SetupDataCall for the given APN. + * + * @param type Type of radio indication + * @param apn Apn to unthrottle + */ + void unthrottleApn(in RadioIndicationType type, in String apn); +} diff --git a/radio/aidl/android/hardware/radio/data/IRadioDataResponse.aidl b/radio/aidl/android/hardware/radio/data/IRadioDataResponse.aidl new file mode 100644 index 0000000000..bbc8d07b0a --- /dev/null +++ b/radio/aidl/android/hardware/radio/data/IRadioDataResponse.aidl @@ -0,0 +1,237 @@ +/* + * 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.radio.data; + +import android.hardware.radio.RadioResponseInfo; +import android.hardware.radio.data.KeepaliveStatus; +import android.hardware.radio.data.SetupDataCallResult; +import android.hardware.radio.data.SlicingConfig; + +/** + * Interface declaring response functions to solicited radio requests for data APIs. + */ +@VintfStability +oneway interface IRadioDataResponse { + /** + * Acknowledge the receipt of radio request sent to the vendor. This must be sent only for + * radio request which take long time to respond. For more details, refer + * https://source.android.com/devices/tech/connect/ril.html + * + * @param serial Serial no. of the request whose acknowledgement is sent. + */ + void acknowledgeRequest(in int serial); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param id The allocated id. On an error, this is set to 0. + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:NO_RESOURCES- Indicates that no pdu session ids are available + * RadioError:REQUEST_NOT_SUPPORTED + */ + void allocatePduSessionIdResponse(in RadioResponseInfo info, in int id); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param dcResponse Attributes of data call + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:NO_RESOURCES + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_CALL_ID + */ + void cancelHandoverResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:REQUEST_NOT_SUPPORTED may be returned when HAL 1.2 or higher is supported. + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_CALL_ID + * RadioError:INVALID_STATE + * RadioError:INVALID_ARGUMENTS + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:SIM_ABSENT + */ + void deactivateDataCallResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param dcResponse List of SetupDataCallResult + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:SIM_ABSENT + */ + void getDataCallListResponse(in RadioResponseInfo info, in SetupDataCallResult[] dcResponse); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param slicingConfig Current slicing configuration + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:MODEM_ERR + */ + void getSlicingConfigResponse(in RadioResponseInfo info, in SlicingConfig slicingConfig); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:NO_RESOURCES + * RadioError:REQUEST_NOT_SUPPORTED + */ + void releasePduSessionIdResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:DEVICE_IN_USE + * RadioError:INVALID_MODEM_STATE + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:REQUEST_NOT_SUPPORTED + */ + void setDataAllowedResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SUBSCRIPTION_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:SIM_ABSENT + */ + void setDataProfileResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:MODEM_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:REQUEST_NOT_SUPPORTED + */ + void setDataThrottlingResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SUBSCRIPTION_NOT_AVAILABLE + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:NOT_PROVISIONED + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + void setInitialAttachApnResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param dcResponse SetupDataCallResult + * + * Valid errors returned: + * RadioError:NONE must be returned on both success and failure of setup with the + * DataCallResponse.status containing the actual status + * For all other errors the DataCallResponse is ignored. + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:OP_NOT_ALLOWED_BEFORE_REG_TO_NW + * RadioError:OP_NOT_ALLOWED_DURING_VOICE_CALL + * RadioError:INVALID_ARGUMENTS + * RadioError:INTERNAL_ERR + * RadioError:NO_RESOURCES if the vendor is unable handle due to resources are full. + * RadioError:SIM_ABSENT + */ + void setupDataCallResponse(in RadioResponseInfo info, in SetupDataCallResult dcResponse); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:NO_RESOURCES + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_CALL_ID + */ + void startHandoverResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param status Status object containing a new handle and a current status. The status returned + * here may be PENDING to indicate that the radio has not yet processed the keepalive + * request. + * + * Valid errors returned: + * RadioError:NONE + * RadioError:NO_RESOURCES + * RadioError:INVALID_ARGUMENTS + */ + void startKeepaliveResponse(in RadioResponseInfo info, in KeepaliveStatus status); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:INVALID_ARGUMENTS + */ + void stopKeepaliveResponse(in RadioResponseInfo info); +} diff --git a/radio/aidl/android/hardware/radio/KeepaliveRequest.aidl b/radio/aidl/android/hardware/radio/data/KeepaliveRequest.aidl similarity index 97% rename from radio/aidl/android/hardware/radio/KeepaliveRequest.aidl rename to radio/aidl/android/hardware/radio/data/KeepaliveRequest.aidl index 1433b96397..57c9f68414 100644 --- a/radio/aidl/android/hardware/radio/KeepaliveRequest.aidl +++ b/radio/aidl/android/hardware/radio/data/KeepaliveRequest.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.data; @VintfStability parcelable KeepaliveRequest { diff --git a/radio/aidl/android/hardware/radio/KeepaliveStatus.aidl b/radio/aidl/android/hardware/radio/data/KeepaliveStatus.aidl similarity index 97% rename from radio/aidl/android/hardware/radio/KeepaliveStatus.aidl rename to radio/aidl/android/hardware/radio/data/KeepaliveStatus.aidl index 0cf6767929..2df280c1ef 100644 --- a/radio/aidl/android/hardware/radio/KeepaliveStatus.aidl +++ b/radio/aidl/android/hardware/radio/data/KeepaliveStatus.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.data; @VintfStability parcelable KeepaliveStatus { diff --git a/radio/aidl/android/hardware/radio/LinkAddress.aidl b/radio/aidl/android/hardware/radio/data/LinkAddress.aidl similarity index 98% rename from radio/aidl/android/hardware/radio/LinkAddress.aidl rename to radio/aidl/android/hardware/radio/data/LinkAddress.aidl index 0c18e271cc..599d382ddf 100644 --- a/radio/aidl/android/hardware/radio/LinkAddress.aidl +++ b/radio/aidl/android/hardware/radio/data/LinkAddress.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.data; /** * Describes a data link address for mobile data connection. diff --git a/radio/aidl/android/hardware/radio/NrQos.aidl b/radio/aidl/android/hardware/radio/data/NrQos.aidl similarity index 93% rename from radio/aidl/android/hardware/radio/NrQos.aidl rename to radio/aidl/android/hardware/radio/data/NrQos.aidl index d791eefe80..1d69b4fc53 100644 --- a/radio/aidl/android/hardware/radio/NrQos.aidl +++ b/radio/aidl/android/hardware/radio/data/NrQos.aidl @@ -14,9 +14,9 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.data; -import android.hardware.radio.QosBandwidth; +import android.hardware.radio.data.QosBandwidth; /** * 5G Quality of Service parameters as per 3gpp spec 24.501 sec 9.11.4.12 diff --git a/radio/aidl/android/hardware/radio/OsAppId.aidl b/radio/aidl/android/hardware/radio/data/OsAppId.aidl similarity index 96% rename from radio/aidl/android/hardware/radio/OsAppId.aidl rename to radio/aidl/android/hardware/radio/data/OsAppId.aidl index 57dfc80168..0bf6d7eb53 100644 --- a/radio/aidl/android/hardware/radio/OsAppId.aidl +++ b/radio/aidl/android/hardware/radio/data/OsAppId.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.data; /** * This struct represents the OsId + OsAppId as defined in TS 24.526 Section 5.2 diff --git a/radio/aidl/android/hardware/radio/PcoDataInfo.aidl b/radio/aidl/android/hardware/radio/data/PcoDataInfo.aidl similarity index 97% rename from radio/aidl/android/hardware/radio/PcoDataInfo.aidl rename to radio/aidl/android/hardware/radio/data/PcoDataInfo.aidl index 7b600e6622..958761436f 100644 --- a/radio/aidl/android/hardware/radio/PcoDataInfo.aidl +++ b/radio/aidl/android/hardware/radio/data/PcoDataInfo.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.data; @VintfStability parcelable PcoDataInfo { diff --git a/radio/aidl/android/hardware/radio/PdpProtocolType.aidl b/radio/aidl/android/hardware/radio/data/PdpProtocolType.aidl similarity index 97% rename from radio/aidl/android/hardware/radio/PdpProtocolType.aidl rename to radio/aidl/android/hardware/radio/data/PdpProtocolType.aidl index e74b1e3da2..9b1136c128 100644 --- a/radio/aidl/android/hardware/radio/PdpProtocolType.aidl +++ b/radio/aidl/android/hardware/radio/data/PdpProtocolType.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.data; /** * Specifies the type of packet data protocol which is defined in TS 27.007 section 10.1.1. diff --git a/radio/aidl/android/hardware/radio/PortRange.aidl b/radio/aidl/android/hardware/radio/data/PortRange.aidl similarity index 96% rename from radio/aidl/android/hardware/radio/PortRange.aidl rename to radio/aidl/android/hardware/radio/data/PortRange.aidl index 2b67e0eb2a..b1f88e60e1 100644 --- a/radio/aidl/android/hardware/radio/PortRange.aidl +++ b/radio/aidl/android/hardware/radio/data/PortRange.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.data; /** * Defines range of ports. start and end are the first and last port numbers (inclusive) in the diff --git a/radio/aidl/android/hardware/radio/Qos.aidl b/radio/aidl/android/hardware/radio/data/Qos.aidl similarity index 85% rename from radio/aidl/android/hardware/radio/Qos.aidl rename to radio/aidl/android/hardware/radio/data/Qos.aidl index 0f84ad1406..3d458de5dc 100644 --- a/radio/aidl/android/hardware/radio/Qos.aidl +++ b/radio/aidl/android/hardware/radio/data/Qos.aidl @@ -14,10 +14,10 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.data; -import android.hardware.radio.EpsQos; -import android.hardware.radio.NrQos; +import android.hardware.radio.data.EpsQos; +import android.hardware.radio.data.NrQos; /** * EPS or NR QOS parameters diff --git a/radio/aidl/android/hardware/radio/QosBandwidth.aidl b/radio/aidl/android/hardware/radio/data/QosBandwidth.aidl similarity index 95% rename from radio/aidl/android/hardware/radio/QosBandwidth.aidl rename to radio/aidl/android/hardware/radio/data/QosBandwidth.aidl index 344b796ed9..a21003af2d 100644 --- a/radio/aidl/android/hardware/radio/QosBandwidth.aidl +++ b/radio/aidl/android/hardware/radio/data/QosBandwidth.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.data; @VintfStability parcelable QosBandwidth { diff --git a/radio/aidl/android/hardware/radio/QosFilter.aidl b/radio/aidl/android/hardware/radio/data/QosFilter.aidl similarity index 90% rename from radio/aidl/android/hardware/radio/QosFilter.aidl rename to radio/aidl/android/hardware/radio/data/QosFilter.aidl index 8b126490b2..626f2b4614 100644 --- a/radio/aidl/android/hardware/radio/QosFilter.aidl +++ b/radio/aidl/android/hardware/radio/data/QosFilter.aidl @@ -14,12 +14,12 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.data; -import android.hardware.radio.PortRange; -import android.hardware.radio.QosFilterIpsecSpi; -import android.hardware.radio.QosFilterIpv6FlowLabel; -import android.hardware.radio.QosFilterTypeOfService; +import android.hardware.radio.data.PortRange; +import android.hardware.radio.data.QosFilterIpsecSpi; +import android.hardware.radio.data.QosFilterIpv6FlowLabel; +import android.hardware.radio.data.QosFilterTypeOfService; /** * See 3gpp 24.008 10.5.6.12 and 3gpp 24.501 9.11.4.13 diff --git a/radio/aidl/android/hardware/radio/QosFilterIpsecSpi.aidl b/radio/aidl/android/hardware/radio/data/QosFilterIpsecSpi.aidl similarity index 94% rename from radio/aidl/android/hardware/radio/QosFilterIpsecSpi.aidl rename to radio/aidl/android/hardware/radio/data/QosFilterIpsecSpi.aidl index e213402bc1..fd7efb1c75 100644 --- a/radio/aidl/android/hardware/radio/QosFilterIpsecSpi.aidl +++ b/radio/aidl/android/hardware/radio/data/QosFilterIpsecSpi.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.data; @VintfStability union QosFilterIpsecSpi { diff --git a/radio/aidl/android/hardware/radio/QosFilterIpv6FlowLabel.aidl b/radio/aidl/android/hardware/radio/data/QosFilterIpv6FlowLabel.aidl similarity index 95% rename from radio/aidl/android/hardware/radio/QosFilterIpv6FlowLabel.aidl rename to radio/aidl/android/hardware/radio/data/QosFilterIpv6FlowLabel.aidl index d5c5a6c830..d6ce84b353 100644 --- a/radio/aidl/android/hardware/radio/QosFilterIpv6FlowLabel.aidl +++ b/radio/aidl/android/hardware/radio/data/QosFilterIpv6FlowLabel.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.data; @VintfStability union QosFilterIpv6FlowLabel { diff --git a/radio/aidl/android/hardware/radio/QosFilterTypeOfService.aidl b/radio/aidl/android/hardware/radio/data/QosFilterTypeOfService.aidl similarity index 95% rename from radio/aidl/android/hardware/radio/QosFilterTypeOfService.aidl rename to radio/aidl/android/hardware/radio/data/QosFilterTypeOfService.aidl index b91323cb43..c50c5b6f20 100644 --- a/radio/aidl/android/hardware/radio/QosFilterTypeOfService.aidl +++ b/radio/aidl/android/hardware/radio/data/QosFilterTypeOfService.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.data; @VintfStability union QosFilterTypeOfService { diff --git a/radio/aidl/android/hardware/radio/QosSession.aidl b/radio/aidl/android/hardware/radio/data/QosSession.aidl similarity index 88% rename from radio/aidl/android/hardware/radio/QosSession.aidl rename to radio/aidl/android/hardware/radio/data/QosSession.aidl index 2620ac5af1..389c3491e5 100644 --- a/radio/aidl/android/hardware/radio/QosSession.aidl +++ b/radio/aidl/android/hardware/radio/data/QosSession.aidl @@ -14,10 +14,10 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.data; -import android.hardware.radio.Qos; -import android.hardware.radio.QosFilter; +import android.hardware.radio.data.Qos; +import android.hardware.radio.data.QosFilter; /** * QOS session associated with a dedicated bearer diff --git a/radio/aidl/android/hardware/radio/RouteSelectionDescriptor.aidl b/radio/aidl/android/hardware/radio/data/RouteSelectionDescriptor.aidl similarity index 92% rename from radio/aidl/android/hardware/radio/RouteSelectionDescriptor.aidl rename to radio/aidl/android/hardware/radio/data/RouteSelectionDescriptor.aidl index a1b482bcdd..d9d602e5df 100644 --- a/radio/aidl/android/hardware/radio/RouteSelectionDescriptor.aidl +++ b/radio/aidl/android/hardware/radio/data/RouteSelectionDescriptor.aidl @@ -14,10 +14,10 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.data; -import android.hardware.radio.PdpProtocolType; -import android.hardware.radio.SliceInfo; +import android.hardware.radio.data.PdpProtocolType; +import android.hardware.radio.data.SliceInfo; /** * This struct represents a single route selection descriptor as defined in 3GPP TS 24.526. diff --git a/radio/aidl/android/hardware/radio/SetupDataCallResult.aidl b/radio/aidl/android/hardware/radio/data/SetupDataCallResult.aidl similarity index 90% rename from radio/aidl/android/hardware/radio/SetupDataCallResult.aidl rename to radio/aidl/android/hardware/radio/data/SetupDataCallResult.aidl index 0fae8b0d83..ebfc55d260 100644 --- a/radio/aidl/android/hardware/radio/SetupDataCallResult.aidl +++ b/radio/aidl/android/hardware/radio/data/SetupDataCallResult.aidl @@ -14,15 +14,15 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.data; -import android.hardware.radio.DataCallFailCause; -import android.hardware.radio.LinkAddress; -import android.hardware.radio.PdpProtocolType; -import android.hardware.radio.Qos; -import android.hardware.radio.QosSession; -import android.hardware.radio.SliceInfo; -import android.hardware.radio.TrafficDescriptor; +import android.hardware.radio.data.DataCallFailCause; +import android.hardware.radio.data.LinkAddress; +import android.hardware.radio.data.PdpProtocolType; +import android.hardware.radio.data.Qos; +import android.hardware.radio.data.QosSession; +import android.hardware.radio.data.SliceInfo; +import android.hardware.radio.data.TrafficDescriptor; @VintfStability parcelable SetupDataCallResult { @@ -68,8 +68,8 @@ parcelable SetupDataCallResult { * retry back-off time in milliseconds. Negative value indicates network does not give any * suggestion. 0 indicates retry should be performed immediately. 0x7fffffffffffffff indicates * the device should not retry data setup anymore. During this time, no calls to - * IRadio.setupDataCall for this APN will be made unless IRadioIndication.unthrottleApn is sent - * with the same APN. + * IRadioData.setupDataCall for this APN will be made unless IRadioDataIndication.unthrottleApn + * is sent with the same APN. */ long suggestedRetryTime; /** diff --git a/radio/aidl/android/hardware/radio/SliceInfo.aidl b/radio/aidl/android/hardware/radio/data/SliceInfo.aidl similarity index 98% rename from radio/aidl/android/hardware/radio/SliceInfo.aidl rename to radio/aidl/android/hardware/radio/data/SliceInfo.aidl index e5b435461d..dd315e8bf5 100644 --- a/radio/aidl/android/hardware/radio/SliceInfo.aidl +++ b/radio/aidl/android/hardware/radio/data/SliceInfo.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.data; /** * This struct represents a S-NSSAI as defined in 3GPP TS 24.501. diff --git a/radio/aidl/android/hardware/radio/SlicingConfig.aidl b/radio/aidl/android/hardware/radio/data/SlicingConfig.aidl similarity index 88% rename from radio/aidl/android/hardware/radio/SlicingConfig.aidl rename to radio/aidl/android/hardware/radio/data/SlicingConfig.aidl index d8d0885142..eea2d4982f 100644 --- a/radio/aidl/android/hardware/radio/SlicingConfig.aidl +++ b/radio/aidl/android/hardware/radio/data/SlicingConfig.aidl @@ -14,10 +14,10 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.data; -import android.hardware.radio.SliceInfo; -import android.hardware.radio.UrspRule; +import android.hardware.radio.data.SliceInfo; +import android.hardware.radio.data.UrspRule; /** * This struct represents the current slicing configuration. diff --git a/radio/aidl/android/hardware/radio/TrafficDescriptor.aidl b/radio/aidl/android/hardware/radio/data/TrafficDescriptor.aidl similarity index 93% rename from radio/aidl/android/hardware/radio/TrafficDescriptor.aidl rename to radio/aidl/android/hardware/radio/data/TrafficDescriptor.aidl index 2580a4c069..e6ea27c749 100644 --- a/radio/aidl/android/hardware/radio/TrafficDescriptor.aidl +++ b/radio/aidl/android/hardware/radio/data/TrafficDescriptor.aidl @@ -14,9 +14,9 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.data; -import android.hardware.radio.OsAppId; +import android.hardware.radio.data.OsAppId; /** * This struct represents a traffic descriptor. A valid struct must have at least one of the diff --git a/radio/aidl/android/hardware/radio/UrspRule.aidl b/radio/aidl/android/hardware/radio/data/UrspRule.aidl similarity index 88% rename from radio/aidl/android/hardware/radio/UrspRule.aidl rename to radio/aidl/android/hardware/radio/data/UrspRule.aidl index 67d797a1bb..de85be5662 100644 --- a/radio/aidl/android/hardware/radio/UrspRule.aidl +++ b/radio/aidl/android/hardware/radio/data/UrspRule.aidl @@ -14,10 +14,10 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.data; -import android.hardware.radio.RouteSelectionDescriptor; -import android.hardware.radio.TrafficDescriptor; +import android.hardware.radio.data.RouteSelectionDescriptor; +import android.hardware.radio.data.TrafficDescriptor; /** * This struct represents a single URSP rule as defined in 3GPP TS 24.526. diff --git a/radio/aidl/android/hardware/radio/CdmaBroadcastSmsConfigInfo.aidl b/radio/aidl/android/hardware/radio/messaging/CdmaBroadcastSmsConfigInfo.aidl similarity index 96% rename from radio/aidl/android/hardware/radio/CdmaBroadcastSmsConfigInfo.aidl rename to radio/aidl/android/hardware/radio/messaging/CdmaBroadcastSmsConfigInfo.aidl index 46f634558c..3d715e2934 100644 --- a/radio/aidl/android/hardware/radio/CdmaBroadcastSmsConfigInfo.aidl +++ b/radio/aidl/android/hardware/radio/messaging/CdmaBroadcastSmsConfigInfo.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.messaging; @VintfStability parcelable CdmaBroadcastSmsConfigInfo { diff --git a/radio/aidl/android/hardware/radio/CdmaSmsAck.aidl b/radio/aidl/android/hardware/radio/messaging/CdmaSmsAck.aidl similarity index 95% rename from radio/aidl/android/hardware/radio/CdmaSmsAck.aidl rename to radio/aidl/android/hardware/radio/messaging/CdmaSmsAck.aidl index b1e85ff2ed..25871c8bb1 100644 --- a/radio/aidl/android/hardware/radio/CdmaSmsAck.aidl +++ b/radio/aidl/android/hardware/radio/messaging/CdmaSmsAck.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.messaging; @VintfStability parcelable CdmaSmsAck { diff --git a/radio/aidl/android/hardware/radio/CdmaSmsAddress.aidl b/radio/aidl/android/hardware/radio/messaging/CdmaSmsAddress.aidl similarity index 98% rename from radio/aidl/android/hardware/radio/CdmaSmsAddress.aidl rename to radio/aidl/android/hardware/radio/messaging/CdmaSmsAddress.aidl index d449ccfc33..835dda5be2 100644 --- a/radio/aidl/android/hardware/radio/CdmaSmsAddress.aidl +++ b/radio/aidl/android/hardware/radio/messaging/CdmaSmsAddress.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.messaging; @VintfStability parcelable CdmaSmsAddress { diff --git a/radio/aidl/android/hardware/radio/CdmaSmsMessage.aidl b/radio/aidl/android/hardware/radio/messaging/CdmaSmsMessage.aidl similarity index 84% rename from radio/aidl/android/hardware/radio/CdmaSmsMessage.aidl rename to radio/aidl/android/hardware/radio/messaging/CdmaSmsMessage.aidl index f38cc5b5ea..f1f065f0ee 100644 --- a/radio/aidl/android/hardware/radio/CdmaSmsMessage.aidl +++ b/radio/aidl/android/hardware/radio/messaging/CdmaSmsMessage.aidl @@ -14,10 +14,10 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.messaging; -import android.hardware.radio.CdmaSmsAddress; -import android.hardware.radio.CdmaSmsSubaddress; +import android.hardware.radio.messaging.CdmaSmsAddress; +import android.hardware.radio.messaging.CdmaSmsSubaddress; @VintfStability parcelable CdmaSmsMessage { diff --git a/radio/aidl/android/hardware/radio/CdmaSmsSubaddress.aidl b/radio/aidl/android/hardware/radio/messaging/CdmaSmsSubaddress.aidl similarity index 96% rename from radio/aidl/android/hardware/radio/CdmaSmsSubaddress.aidl rename to radio/aidl/android/hardware/radio/messaging/CdmaSmsSubaddress.aidl index e5d749408b..9dfe503369 100644 --- a/radio/aidl/android/hardware/radio/CdmaSmsSubaddress.aidl +++ b/radio/aidl/android/hardware/radio/messaging/CdmaSmsSubaddress.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.messaging; @VintfStability parcelable CdmaSmsSubaddress { diff --git a/radio/aidl/android/hardware/radio/CdmaSmsWriteArgs.aidl b/radio/aidl/android/hardware/radio/messaging/CdmaSmsWriteArgs.aidl similarity index 90% rename from radio/aidl/android/hardware/radio/CdmaSmsWriteArgs.aidl rename to radio/aidl/android/hardware/radio/messaging/CdmaSmsWriteArgs.aidl index 57896f4ef0..e73a0d791f 100644 --- a/radio/aidl/android/hardware/radio/CdmaSmsWriteArgs.aidl +++ b/radio/aidl/android/hardware/radio/messaging/CdmaSmsWriteArgs.aidl @@ -14,9 +14,9 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.messaging; -import android.hardware.radio.CdmaSmsMessage; +import android.hardware.radio.messaging.CdmaSmsMessage; @VintfStability parcelable CdmaSmsWriteArgs { diff --git a/radio/aidl/android/hardware/radio/GsmBroadcastSmsConfigInfo.aidl b/radio/aidl/android/hardware/radio/messaging/GsmBroadcastSmsConfigInfo.aidl similarity index 97% rename from radio/aidl/android/hardware/radio/GsmBroadcastSmsConfigInfo.aidl rename to radio/aidl/android/hardware/radio/messaging/GsmBroadcastSmsConfigInfo.aidl index 9b08ad9b6a..2a52f0a56e 100644 --- a/radio/aidl/android/hardware/radio/GsmBroadcastSmsConfigInfo.aidl +++ b/radio/aidl/android/hardware/radio/messaging/GsmBroadcastSmsConfigInfo.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.messaging; /** * Which types of Cell Broadcast Message (CBM) are to be received by the ME diff --git a/radio/aidl/android/hardware/radio/GsmSmsMessage.aidl b/radio/aidl/android/hardware/radio/messaging/GsmSmsMessage.aidl similarity index 95% rename from radio/aidl/android/hardware/radio/GsmSmsMessage.aidl rename to radio/aidl/android/hardware/radio/messaging/GsmSmsMessage.aidl index 248b4be6a4..45c09afac7 100644 --- a/radio/aidl/android/hardware/radio/GsmSmsMessage.aidl +++ b/radio/aidl/android/hardware/radio/messaging/GsmSmsMessage.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.messaging; @VintfStability parcelable GsmSmsMessage { diff --git a/radio/aidl/android/hardware/radio/messaging/IRadioMessaging.aidl b/radio/aidl/android/hardware/radio/messaging/IRadioMessaging.aidl new file mode 100644 index 0000000000..1dbaed3787 --- /dev/null +++ b/radio/aidl/android/hardware/radio/messaging/IRadioMessaging.aidl @@ -0,0 +1,311 @@ +/* + * 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.radio.messaging; + +import android.hardware.radio.messaging.CdmaBroadcastSmsConfigInfo; +import android.hardware.radio.messaging.CdmaSmsAck; +import android.hardware.radio.messaging.CdmaSmsMessage; +import android.hardware.radio.messaging.CdmaSmsWriteArgs; +import android.hardware.radio.messaging.GsmBroadcastSmsConfigInfo; +import android.hardware.radio.messaging.GsmSmsMessage; +import android.hardware.radio.messaging.IRadioMessagingIndication; +import android.hardware.radio.messaging.IRadioMessagingResponse; +import android.hardware.radio.messaging.ImsSmsMessage; +import android.hardware.radio.messaging.SmsAcknowledgeFailCause; +import android.hardware.radio.messaging.SmsWriteArgs; + +/** + * This interface is used by telephony and telecom to talk to cellular radio for messaging APIs. + * All the functions have minimum one parameter: + * serial: which corresponds to serial no. of request. Serial numbers must only be memorized for the + * duration of a method call. If clients provide colliding serials (including passing the same + * serial to different methods), multiple responses (one for each method call) must still be served. + * setResponseFunctions must work with IRadioMessagingResponse and IRadioMessagingIndication. + */ +@VintfStability +oneway interface IRadioMessaging { + /** + * Acknowledge successful or failed receipt of SMS previously indicated via unsol + * responseNewSms(), including acknowledgement TPDU to send as the RP-User-Data element of the + * RP-ACK or RP-ERROR PDU. + * + * @param serial Serial number of request. + * @param success true on successful receipt (send RP-ACK) + * false on failed receipt (send RP-ERROR) + * @param ackPdu acknowledgement TPDU in hexadecimal format + * + * Response function is IRadioMessagingResponse.acknowledgeIncomingGsmSmsWithPduResponse() + */ + void acknowledgeIncomingGsmSmsWithPdu(in int serial, in boolean success, in String ackPdu); + + /** + * Acknowledge the success or failure in the receipt of SMS previously indicated + * via responseCdmaNewSms() + * + * @param serial Serial number of request. + * @param smsAck Cdma Sms ack to be sent described by CdmaSmsAck + * + * Response function is IRadioMessagingResponse.acknowledgeLastIncomingCdmaSmsResponse() + */ + void acknowledgeLastIncomingCdmaSms(in int serial, in CdmaSmsAck smsAck); + + /** + * Acknowledge successful or failed receipt of SMS previously indicated via unsolResponseNewSms + * + * @param serial Serial number of request. + * @param success is true on successful receipt + * (basically, AT+CNMA=1 from TS 27.005 is 0 on failed receipt + * (basically, AT+CNMA=2 from TS 27.005) + * @param cause: if success is false, this contains the failure cause as defined + * in TS 23.040, 9.2.3.22. + * + * Response function is IRadioMessagingResponse.acknowledgeLastIncomingGsmSmsResponse() + */ + void acknowledgeLastIncomingGsmSms( + in int serial, in boolean success, in SmsAcknowledgeFailCause cause); + + /** + * Cancel the current USSD session if one exists. + * + * @param serial Serial number of request. + * + * Response function is IRadioMessagingResponse.cancelPendingUssdResponse() + */ + void cancelPendingUssd(in int serial); + + /** + * Deletes a CDMA SMS message from RUIM memory. + * + * @param serial Serial number of request. + * @param index record index of the message to delete + * + * Response function is IRadioMessagingResponse.deleteSmsOnRuimResponse() + */ + void deleteSmsOnRuim(in int serial, in int index); + + /** + * Deletes a SMS message from SIM memory. + * + * @param serial Serial number of request. + * @param index Record index of the message to delete. + * + * Response function is IRadioMessagingResponse.deleteSmsOnSimResponse() + */ + void deleteSmsOnSim(in int serial, in int index); + + /** + * Request the setting of CDMA Broadcast SMS config + * + * @param serial Serial number of request. + * + * Response function is IRadioMessagingResponse.getCdmaBroadcastConfigResponse() + */ + void getCdmaBroadcastConfig(in int serial); + + /** + * Request the setting of GSM/WCDMA Cell Broadcast SMS config. + * + * @param serial Serial number of request. + * + * Response function is IRadioMessagingResponse.getGsmBroadcastConfigResponse() + */ + void getGsmBroadcastConfig(in int serial); + + /** + * Get the default Short Message Service Center address on the device. + * + * @param serial Serial number of request. + * + * Response function is IRadioMessagingResponse.getSmscAddressResponse() + */ + void getSmscAddress(in int serial); + + /** + * Indicates whether there is storage available for new SMS messages. + * + * @param serial Serial number of request. + * @param available true if memory is available for storing new messages, + * false if memory capacity is exceeded + * + * Response function is IRadioMessagingResponse.reportSmsMemoryStatusResponse() + */ + void reportSmsMemoryStatus(in int serial, in boolean available); + + /** + * When response type received from a radio indication or radio response is + * RadioIndicationType:UNSOLICITED_ACK_EXP or RadioResponseType:SOLICITED_ACK_EXP respectively, + * acknowledge the receipt of those messages by sending responseAcknowledgement(). + */ + void responseAcknowledgement(); + + /** + * Send a CDMA SMS message + * + * @param serial Serial number of request. + * @param sms CdmaSmsMessage to be sent + * + * Response function is IRadioMessagingResponse.sendCdmaSmsResponse() + */ + void sendCdmaSms(in int serial, in CdmaSmsMessage sms); + + /** + * Send an SMS message. Identical to sendCdmaSms, except that more messages are expected to be + * sent soon. + * + * @param serial Serial number of request. + * @param sms CdmaSmsMessage to be sent + * + * Response function is IRadioMessagingResponse.sendCdmaSmsExpectMoreResponse() + */ + void sendCdmaSmsExpectMore(in int serial, in CdmaSmsMessage sms); + + /** + * Send a SMS message over IMS. Based on the return error, caller decides to resend if sending + * sms fails. SMS_SEND_FAIL_RETRY means retry, and other errors means no retry. + * In case of retry, data is encoded based on Voice Technology available. + * + * @param serial Serial number of request. + * @param message ImsSmsMessage to be sent + * + * Response function is IRadioMessagingResponse.sendImsSmsResponse() + */ + void sendImsSms(in int serial, in ImsSmsMessage message); + + /** + * Send an SMS message. Based on the returned error, caller decides to resend if sending sms + * fails. RadioError:SMS_SEND_FAIL_RETRY means retry (i.e. error cause is 332) and + * RadioError:GENERIC_FAILURE means no retry (i.e. error cause is 500) + * + * @param serial Serial number of request. + * @param message GsmSmsMessage to be sent + * + * Response function is IRadioMessagingResponse.sendSmsResponse() + */ + void sendSms(in int serial, in GsmSmsMessage message); + + /** + * Send an SMS message. Identical to sendSms, except that more messages are expected to be sent + * soon. If possible, keep SMS relay protocol link open (eg TS 27.005 AT+CMMS command). + * Based on the return error, caller decides to resend if sending sms fails. + * RadioError:SMS_SEND_FAIL_RETRY means retry (i.e. error cause is 332) and + * RadioError:GENERIC_FAILURE means no retry (i.e. error cause is 500) + * + * @param serial Serial number of request. + * @param message GsmSmsMessage to be sent + * + * Response function is IRadioMessagingResponse.sendSmsExpectMoreResponse() + */ + void sendSmsExpectMore(in int serial, in GsmSmsMessage message); + + /** + * Send a USSD message. If a USSD session already exists, the message must be sent in the + * context of that session. Otherwise, a new session must be created. The network reply must be + * reported via unsolOnUssd. + * + * Only one USSD session must exist at a time, and the session is assumed to exist until: + * a) The android system invokes cancelUssd() + * b) The implementation sends a unsolOnUssd() with a type code of + * "0" (USSD-Notify/no further action) or "2" (session terminated) + * + * @param serial Serial number of request. + * @param ussd string containing the USSD request in UTF-8 format + * + * Response function is IRadioMessagingResponse.sendUssdResponse() + */ + void sendUssd(in int serial, in String ussd); + + /** + * Enable or disable the reception of CDMA Cell Broadcast SMS + * + * @param serial Serial number of request. + * @param activate indicates to activate or turn off the reception of CDMA Cell Broadcast SMS. + * true = activate, false = turn off + * + * Response function is IRadioMessagingResponse.setCdmaBroadcastActivationResponse() + */ + void setCdmaBroadcastActivation(in int serial, in boolean activate); + + /** + * Set CDMA Broadcast SMS config + * + * @param serial Serial number of request. + * @param configInfo CDMA Broadcast SMS config to be set. + * + * Response function is IRadioMessagingResponse.setCdmaBroadcastConfigResponse() + */ + void setCdmaBroadcastConfig(in int serial, in CdmaBroadcastSmsConfigInfo[] configInfo); + + /** + * Enable or disable the reception of GSM/WCDMA Cell Broadcast SMS + * + * @param serial Serial number of request. + * @param activate indicates to activate or turn off the reception of GSM/WCDMA + * Cell Broadcast SMS. true = activate, false = turn off + * + * Response function is IRadioMessagingResponse.setGsmBroadcastActivationResponse() + */ + void setGsmBroadcastActivation(in int serial, in boolean activate); + + /** + * Set GSM/WCDMA Cell Broadcast SMS config + * + * @param serial Serial number of request. + * @param configInfo Setting of GSM/WCDMA Cell broadcast config + * + * Response function is IRadioMessagingResponse.setGsmBroadcastConfigResponse() + */ + void setGsmBroadcastConfig(in int serial, in GsmBroadcastSmsConfigInfo[] configInfo); + + /** + * Set response functions for messaging radio requests and indications. + * + * @param radioMessagingResponse Object containing response functions + * @param radioMessagingIndication Object containing radio indications + */ + void setResponseFunctions(in IRadioMessagingResponse radioMessagingResponse, + in IRadioMessagingIndication radioMessagingIndication); + + /** + * Set the default Short Message Service Center address on the device. + * + * @param serial Serial number of request. + * @param smsc Short Message Service Center address to set + * + * Response function is IRadioMessagingResponse.setSmscAddressResponse() + */ + void setSmscAddress(in int serial, in String smsc); + + /** + * Stores a CDMA SMS message to RUIM memory. + * + * @param serial Serial number of request. + * @param cdmaSms CdmaSmsWriteArgs + * + * Response function is IRadioMessagingResponse.writeSmsToRuimResponse() + */ + void writeSmsToRuim(in int serial, in CdmaSmsWriteArgs cdmaSms); + + /** + * Stores a SMS message to SIM memory. + * + * @param serial Serial number of request. + * @param smsWriteArgs SmsWriteArgs + * + * Response function is IRadioMessagingResponse.writeSmsToSimResponse() + */ + void writeSmsToSim(in int serial, in SmsWriteArgs smsWriteArgs); +} diff --git a/radio/aidl/android/hardware/radio/messaging/IRadioMessagingIndication.aidl b/radio/aidl/android/hardware/radio/messaging/IRadioMessagingIndication.aidl new file mode 100644 index 0000000000..4b40bfb6c1 --- /dev/null +++ b/radio/aidl/android/hardware/radio/messaging/IRadioMessagingIndication.aidl @@ -0,0 +1,106 @@ +/* + * 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.radio.messaging; + +import android.hardware.radio.RadioIndicationType; +import android.hardware.radio.messaging.CdmaSmsMessage; +import android.hardware.radio.messaging.UssdModeType; + +/** + * Interface declaring unsolicited radio indications for messaging APIs. + */ +@VintfStability +oneway interface IRadioMessagingIndication { + /** + * Indicates when new CDMA SMS is received. Callee must subsequently confirm the receipt of the + * SMS with acknowledgeLastIncomingCdmaSms(). Server must not send cdmaNewSms() messages until + * acknowledgeLastIncomingCdmaSms() has been received. + * + * @param type Type of radio indication + * @param msg Cdma Sms Message + */ + void cdmaNewSms(in RadioIndicationType type, in CdmaSmsMessage msg); + + /** + * Indicates that SMS storage on the RUIM is full. Messages cannot be saved on the RUIM until + * space is freed. + * + * @param type Type of radio indication + */ + void cdmaRuimSmsStorageFull(in RadioIndicationType type); + + /** + * Indicates when new Broadcast SMS is received + * + * @param type Type of radio indication + * @param data If received from GSM network, "data" is byte array of 88 bytes which indicates + * each page of a CBS Message sent to the MS by the BTS as coded in 3GPP 23.041 Section + * 9.4.1.2. If received from UMTS network, "data" is byte array of 90 up to 1252 bytes + * which contain between 1 and 15 CBS Message pages sent as one packet to the MS by the + * BTS as coded in 3GPP 23.041 Section 9.4.2.2 + */ + void newBroadcastSms(in RadioIndicationType type, in byte[] data); + + /** + * Indicates when new SMS is received. Callee must subsequently confirm the receipt of the SMS + * with a acknowledgeLastIncomingGsmSms(). Server must not send newSms() or newSmsStatusReport() + * messages until an acknowledgeLastIncomingGsmSms() has been received. + * + * @param type Type of radio indication + * @param pdu PDU of SMS-DELIVER represented as byte array. + * The PDU starts with the SMSC address per TS 27.005 (+CMT:) + */ + void newSms(in RadioIndicationType type, in byte[] pdu); + + /** + * Indicates when new SMS has been stored on SIM card + * + * @param type Type of radio indication + * @param recordNumber Record number on the sim + */ + void newSmsOnSim(in RadioIndicationType type, in int recordNumber); + + /** + * Indicates when new SMS Status Report is received. Callee must subsequently confirm the + * receipt of the SMS with a acknowledgeLastIncomingGsmSms(). Server must not send newSms() or + * newSmsStatusReport() messages until an acknowledgeLastIncomingGsmSms() has been received + * + * @param type Type of radio indication + * @param pdu PDU of SMS-STATUS-REPORT represented as byte array. + * The PDU starts with the SMSC address per TS 27.005 (+CMT:) + */ + void newSmsStatusReport(in RadioIndicationType type, in byte[] pdu); + + /** + * Indicates when a new USSD message is received. The USSD session is assumed to persist if the + * type code is REQUEST, otherwise the current session (if any) is assumed to have terminated. + * + * @param type Type of radio indication + * @param modeType USSD type code + * @param msg Message string in UTF-8, if applicable + */ + void onUssd(in RadioIndicationType type, in UssdModeType modeType, in String msg); + + /** + * Indicates that SMS storage on the SIM is full. Sent when the network attempts to deliver a + * new SMS message. Messages cannot be saved on the SIM until space is freed. In particular, + * incoming Class 2 messages must not be stored. + * + * @param type Type of radio indication + */ + void simSmsStorageFull(in RadioIndicationType type); +} diff --git a/radio/aidl/android/hardware/radio/messaging/IRadioMessagingResponse.aidl b/radio/aidl/android/hardware/radio/messaging/IRadioMessagingResponse.aidl new file mode 100644 index 0000000000..75fa390cba --- /dev/null +++ b/radio/aidl/android/hardware/radio/messaging/IRadioMessagingResponse.aidl @@ -0,0 +1,587 @@ +/* + * 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.radio.messaging; + +import android.hardware.radio.RadioResponseInfo; +import android.hardware.radio.messaging.CdmaBroadcastSmsConfigInfo; +import android.hardware.radio.messaging.GsmBroadcastSmsConfigInfo; +import android.hardware.radio.messaging.SendSmsResult; + +/** + * Interface declaring response functions to solicited radio requests for messaging APIs. + */ +@VintfStability +oneway interface IRadioMessagingResponse { + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:REQUEST_NOT_SUPPORTED + */ + void acknowledgeIncomingGsmSmsWithPduResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_SMS_TO_ACK + * RadioError:INVALID_STATE + * RadioError:NO_MEMORY + * RadioError:REQUEST_RATE_LIMITED + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:NETWORK_NOT_READY + * RadioError:INVALID_MODEM_STATE + * RadioError:INTERNAL_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + void acknowledgeLastIncomingCdmaSmsResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:REQUEST_NOT_SUPPORTED + */ + void acknowledgeLastIncomingGsmSmsResponse(in RadioResponseInfo info); + + /** + * Acknowledge the receipt of radio request sent to the vendor. This must be sent only for + * radio request which take long time to respond. For more details, refer + * https://source.android.com/devices/tech/connect/ril.html + * + * @param serial Serial no. of the request whose acknowledgement is sent. + */ + void acknowledgeRequest(in int serial); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SIM_BUSY + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:INVALID_STATE + * RadioError:INVALID_ARGUMENTS + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_MODEM_STATE + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + void cancelPendingUssdResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_MEMORY + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:NO_SUCH_ENTRY + * RadioError:INTERNAL_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:INVALID_MODEM_STATE + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:SIM_ABSENT + */ + void deleteSmsOnRuimResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SIM_FULL + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_MEMORY + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:NO_SUCH_ENTRY + * RadioError:INTERNAL_ERR + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:INVALID_MODEM_STATE + * RadioError:SIM_ABSENT + */ + void deleteSmsOnSimResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param configs Vector of CDMA Broadcast SMS configs. + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:INVALID_STATE + * RadioError:NO_MEMORY + * RadioError:REQUEST_RATE_LIMITED + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:NO_RESOURCES + * RadioError:INTERNAL_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:INVALID_MODEM_STATE + */ + void getCdmaBroadcastConfigResponse( + in RadioResponseInfo info, in CdmaBroadcastSmsConfigInfo[] configs); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param configs Vector of GSM/WCDMA Cell broadcast configs + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:INVALID_STATE + * RadioError:NO_MEMORY + * RadioError:REQUEST_RATE_LIMITED + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:NO_RESOURCES + * RadioError:INTERNAL_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:INVALID_MODEM_STATE + */ + void getGsmBroadcastConfigResponse( + in RadioResponseInfo info, in GsmBroadcastSmsConfigInfo[] configs); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param smsc Short Message Service Center address on the device + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_RATE_LIMITED + * RadioError:MODEM_ERR + * RadioError:INVALID_MODEM_STATE + * RadioError:NOT_PROVISIONED + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:SIM_ABSENT + */ + void getSmscAddressResponse(in RadioResponseInfo info, in String smsc); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_MEMORY + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_RATE_LIMITED + * RadioError:MODEM_ERR + * RadioError:INVALID_STATE + * RadioError:INTERNAL_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:SIM_ABSENT + */ + void reportSmsMemoryStatusResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param sms Response to sms sent as defined by SendSmsResult + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SMS_SEND_FAIL_RETRY + * RadioError:NETWORK_REJECT + * RadioError:INVALID_STATE + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_MEMORY + * RadioError:REQUEST_RATE_LIMITED + * RadioError:INVALID_SMS_FORMAT + * RadioError:SYSTEM_ERR + * RadioError:FDN_CHECK_FAILURE + * RadioError:ENCODING_ERR + * RadioError:INVALID_SMSC_ADDRESS + * RadioError:MODEM_ERR + * RadioError:NETWORK_ERR + * RadioError:INTERNAL_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_MODEM_STATE + * RadioError:NETWORK_NOT_READY + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:SIM_ABSENT + * RadioError:SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED + * RadioError:ACCESS_BARRED + * RadioError:BLOCKED_DUE_TO_CALL + */ + void sendCdmaSmsExpectMoreResponse(in RadioResponseInfo info, in SendSmsResult sms); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param sms Sms result struct as defined by SendSmsResult + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:SMS_SEND_FAIL_RETRY + * RadioError:NETWORK_REJECT + * RadioError:INVALID_STATE + * RadioError:NO_MEMORY + * RadioError:REQUEST_RATE_LIMITED + * RadioError:INVALID_SMS_FORMAT + * RadioError:SYSTEM_ERR + * RadioError:FDN_CHECK_FAILURE + * RadioError:MODEM_ERR + * RadioError:NETWORK_ERR + * RadioError:ENCODING_ERR + * RadioError:INVALID_SMSC_ADDRESS + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:ENCODING_ERR + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:SIM_ABSENT + * RadioError:SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED + * RadioError:ACCESS_BARRED + * RadioError:BLOCKED_DUE_TO_CALL + */ + void sendCdmaSmsResponse(in RadioResponseInfo info, in SendSmsResult sms); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param sms Response to sms sent as defined by SendSmsResult + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SMS_SEND_FAIL_RETRY + * RadioError:FDN_CHECK_FAILURE + * RadioError:NETWORK_REJECT + * RadioError:INVALID_ARGUMENTS + * RadioError:INVALID_STATE + * RadioError:NO_MEMORY + * RadioError:INVALID_SMS_FORMAT + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_RATE_LIMITED + * RadioError:MODEM_ERR + * RadioError:NETWORK_ERR + * RadioError:ENCODING_ERR + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:INTERNAL_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NETWORK_NOT_READY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + void sendImsSmsResponse(in RadioResponseInfo info, in SendSmsResult sms); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param sms Response to sms sent as defined by SendSmsResult + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SMS_SEND_FAIL_RETRY + * RadioError:NETWORK_REJECT + * RadioError:INVALID_STATE + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_MEMORY + * RadioError:REQUEST_RATE_LIMITED + * RadioError:INVALID_SMS_FORMAT + * RadioError:SYSTEM_ERR + * RadioError:FDN_CHECK_FAILURE + * RadioError:ENCODING_ERR + * RadioError:INVALID_SMSC_ADDRESS + * RadioError:MODEM_ERR + * RadioError:NETWORK_ERR + * RadioError:INTERNAL_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_MODEM_STATE + * RadioError:NETWORK_NOT_READY + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:SIM_ABSENT + * RadioError:ACCESS_BARRED + * RadioError:BLOCKED_DUE_TO_CALL + */ + void sendSmsExpectMoreResponse(in RadioResponseInfo info, in SendSmsResult sms); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param sms Response to sms sent as defined by SendSmsResult + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SMS_SEND_FAIL_RETRY + * RadioError:NETWORK_REJECT + * RadioError:INVALID_STATE + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_MEMORY + * RadioError:REQUEST_RATE_LIMITED + * RadioError:INVALID_SMS_FORMAT + * RadioError:SYSTEM_ERR + * RadioError:ENCODING_ERR + * RadioError:INVALID_SMSC_ADDRESS + * RadioError:MODEM_ERR + * RadioError:NETWORK_ERR + * RadioError:INTERNAL_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_MODEM_STATE + * RadioError:NETWORK_NOT_READY + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:SIM_ABSENT + * RadioError:ACCESS_BARRED + * RadioError:BLOCKED_DUE_TO_CALL + */ + void sendSmsResponse(in RadioResponseInfo info, in SendSmsResult sms); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:FDN_CHECK_FAILURE + * RadioError:USSD_MODIFIED_TO_DIAL + * RadioError:USSD_MODIFIED_TO_SS + * RadioError:USSD_MODIFIED_TO_USSD + * RadioError:SIM_BUSY + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_MEMORY + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:ABORTED + * RadioError:SYSTEM_ERR + * RadioError:INVALID_STATE + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_MODEM_STATE + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + void sendUssdResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:INVALID_STATE + * RadioError:NO_MEMORY + * RadioError:REQUEST_RATE_LIMITED + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:INVALID_MODEM_STATE + */ + void setCdmaBroadcastActivationResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:INVALID_STATE + * RadioError:NO_MEMORY + * RadioError:REQUEST_RATE_LIMITED + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:INVALID_MODEM_STATE + */ + void setCdmaBroadcastConfigResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:INVALID_STATE + * RadioError:NO_MEMORY + * RadioError:REQUEST_RATE_LIMITED + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:INVALID_MODEM_STATE + */ + void setGsmBroadcastActivationResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:INVALID_STATE + * RadioError:NO_MEMORY + * RadioError:REQUEST_RATE_LIMITED + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:INVALID_MODEM_STATE + */ + void setGsmBroadcastConfigResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:INVALID_SMS_FORMAT + * RadioError:NO_MEMORY + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_RATE_LIMITED + * RadioError:MODEM_ERR + * RadioError:NO_RESOURCES + * RadioError:INTERNAL_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:SIM_ABSENT + */ + void setSmscAddressResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param index record index where the cmda sms message is stored + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:INVALID_SMS_FORMAT + * RadioError:SIM_FULL + * RadioError:INTERNAL_ERR + * RadioError:MODEM_ERR + * RadioError:ENCODING_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:INVALID_MODEM_STATE + * RadioError:INVALID_SMSC_ADDRESS + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:INVALID_MODEM_STATE + * RadioError:SIM_ABSENT + */ + void writeSmsToRuimResponse(in RadioResponseInfo info, in int index); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param index record index where the message is stored + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SIM_FULL + * RadioError:INVALID_ARGUMENTS + * RadioError:INVALID_SMS_FORMAT + * RadioError:INTERNAL_ERR + * RadioError:MODEM_ERR + * RadioError:ENCODING_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:INVALID_MODEM_STATE + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:INVALID_SMSC_ADDRESS + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:CANCELLED + * RadioError:INVALID_MODEM_STATE + * RadioError:SIM_ABSENT + */ + void writeSmsToSimResponse(in RadioResponseInfo info, in int index); +} diff --git a/radio/aidl/android/hardware/radio/ImsSmsMessage.aidl b/radio/aidl/android/hardware/radio/messaging/ImsSmsMessage.aidl similarity index 90% rename from radio/aidl/android/hardware/radio/ImsSmsMessage.aidl rename to radio/aidl/android/hardware/radio/messaging/ImsSmsMessage.aidl index 3b4efe68fd..809cfb38bd 100644 --- a/radio/aidl/android/hardware/radio/ImsSmsMessage.aidl +++ b/radio/aidl/android/hardware/radio/messaging/ImsSmsMessage.aidl @@ -14,11 +14,11 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.messaging; -import android.hardware.radio.CdmaSmsMessage; -import android.hardware.radio.GsmSmsMessage; import android.hardware.radio.RadioTechnologyFamily; +import android.hardware.radio.messaging.CdmaSmsMessage; +import android.hardware.radio.messaging.GsmSmsMessage; @VintfStability parcelable ImsSmsMessage { diff --git a/radio/aidl/android/hardware/radio/SendSmsResult.aidl b/radio/aidl/android/hardware/radio/messaging/SendSmsResult.aidl similarity index 96% rename from radio/aidl/android/hardware/radio/SendSmsResult.aidl rename to radio/aidl/android/hardware/radio/messaging/SendSmsResult.aidl index 31865637ee..15d68f14a0 100644 --- a/radio/aidl/android/hardware/radio/SendSmsResult.aidl +++ b/radio/aidl/android/hardware/radio/messaging/SendSmsResult.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.messaging; @VintfStability parcelable SendSmsResult { diff --git a/radio/aidl/android/hardware/radio/SmsAcknowledgeFailCause.aidl b/radio/aidl/android/hardware/radio/messaging/SmsAcknowledgeFailCause.aidl similarity index 94% rename from radio/aidl/android/hardware/radio/SmsAcknowledgeFailCause.aidl rename to radio/aidl/android/hardware/radio/messaging/SmsAcknowledgeFailCause.aidl index 265a10918d..a47cdb61c8 100644 --- a/radio/aidl/android/hardware/radio/SmsAcknowledgeFailCause.aidl +++ b/radio/aidl/android/hardware/radio/messaging/SmsAcknowledgeFailCause.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.messaging; @VintfStability @Backing(type="int") diff --git a/radio/aidl/android/hardware/radio/SmsWriteArgs.aidl b/radio/aidl/android/hardware/radio/messaging/SmsWriteArgs.aidl similarity index 96% rename from radio/aidl/android/hardware/radio/SmsWriteArgs.aidl rename to radio/aidl/android/hardware/radio/messaging/SmsWriteArgs.aidl index 7258e0aeef..539f68bf67 100644 --- a/radio/aidl/android/hardware/radio/SmsWriteArgs.aidl +++ b/radio/aidl/android/hardware/radio/messaging/SmsWriteArgs.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.messaging; @VintfStability parcelable SmsWriteArgs { diff --git a/radio/aidl/android/hardware/radio/UssdModeType.aidl b/radio/aidl/android/hardware/radio/messaging/UssdModeType.aidl similarity index 96% rename from radio/aidl/android/hardware/radio/UssdModeType.aidl rename to radio/aidl/android/hardware/radio/messaging/UssdModeType.aidl index 187130c48c..c3c111ea77 100644 --- a/radio/aidl/android/hardware/radio/UssdModeType.aidl +++ b/radio/aidl/android/hardware/radio/messaging/UssdModeType.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.messaging; @VintfStability @Backing(type="int") diff --git a/radio/aidl/android/hardware/radio/ActivityStatsInfo.aidl b/radio/aidl/android/hardware/radio/modem/ActivityStatsInfo.aidl similarity index 97% rename from radio/aidl/android/hardware/radio/ActivityStatsInfo.aidl rename to radio/aidl/android/hardware/radio/modem/ActivityStatsInfo.aidl index f1a6e0e355..764a86dd68 100644 --- a/radio/aidl/android/hardware/radio/ActivityStatsInfo.aidl +++ b/radio/aidl/android/hardware/radio/modem/ActivityStatsInfo.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.modem; @VintfStability parcelable ActivityStatsInfo { diff --git a/radio/aidl/android/hardware/radio/DeviceStateType.aidl b/radio/aidl/android/hardware/radio/modem/DeviceStateType.aidl similarity index 96% rename from radio/aidl/android/hardware/radio/DeviceStateType.aidl rename to radio/aidl/android/hardware/radio/modem/DeviceStateType.aidl index e622486293..0dae351c41 100644 --- a/radio/aidl/android/hardware/radio/DeviceStateType.aidl +++ b/radio/aidl/android/hardware/radio/modem/DeviceStateType.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.modem; @VintfStability @Backing(type="int") diff --git a/radio/aidl/android/hardware/radio/HardwareConfig.aidl b/radio/aidl/android/hardware/radio/modem/HardwareConfig.aidl similarity index 90% rename from radio/aidl/android/hardware/radio/HardwareConfig.aidl rename to radio/aidl/android/hardware/radio/modem/HardwareConfig.aidl index 59850ad22e..c38df5e859 100644 --- a/radio/aidl/android/hardware/radio/HardwareConfig.aidl +++ b/radio/aidl/android/hardware/radio/modem/HardwareConfig.aidl @@ -14,10 +14,10 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.modem; -import android.hardware.radio.HardwareConfigModem; -import android.hardware.radio.HardwareConfigSim; +import android.hardware.radio.modem.HardwareConfigModem; +import android.hardware.radio.modem.HardwareConfigSim; @VintfStability parcelable HardwareConfig { diff --git a/radio/aidl/android/hardware/radio/HardwareConfigModem.aidl b/radio/aidl/android/hardware/radio/modem/HardwareConfigModem.aidl similarity index 90% rename from radio/aidl/android/hardware/radio/HardwareConfigModem.aidl rename to radio/aidl/android/hardware/radio/modem/HardwareConfigModem.aidl index 8e3bc473f8..0b7343b3d6 100644 --- a/radio/aidl/android/hardware/radio/HardwareConfigModem.aidl +++ b/radio/aidl/android/hardware/radio/modem/HardwareConfigModem.aidl @@ -14,7 +14,9 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.modem; + +import android.hardware.radio.RadioTechnology; @VintfStability parcelable HardwareConfigModem { @@ -30,15 +32,15 @@ parcelable HardwareConfigModem { /** * Bitset value, based on RadioTechnology. */ - int rat; + RadioTechnology rat; /** * Maximum number of concurrent active voice calls. */ - int maxVoice; + int maxVoiceCalls; /** * Maximum number of concurrent active data calls. */ - int maxData; + int maxDataCalls; /** * Maximum number of concurrent standby connections. This is not necessarily an equal sum of the * maxVoice and maxData (or a derivative of it) since it really depends on the modem capability, diff --git a/radio/aidl/android/hardware/radio/HardwareConfigSim.aidl b/radio/aidl/android/hardware/radio/modem/HardwareConfigSim.aidl similarity index 95% rename from radio/aidl/android/hardware/radio/HardwareConfigSim.aidl rename to radio/aidl/android/hardware/radio/modem/HardwareConfigSim.aidl index 85055de7c4..0f0c05fe6f 100644 --- a/radio/aidl/android/hardware/radio/HardwareConfigSim.aidl +++ b/radio/aidl/android/hardware/radio/modem/HardwareConfigSim.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.modem; @VintfStability parcelable HardwareConfigSim { diff --git a/radio/aidl/android/hardware/radio/modem/IRadioModem.aidl b/radio/aidl/android/hardware/radio/modem/IRadioModem.aidl new file mode 100644 index 0000000000..ba0ddb94b1 --- /dev/null +++ b/radio/aidl/android/hardware/radio/modem/IRadioModem.aidl @@ -0,0 +1,230 @@ +/* + * 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.radio.modem; + +import android.hardware.radio.modem.DeviceStateType; +import android.hardware.radio.modem.IRadioModemIndication; +import android.hardware.radio.modem.IRadioModemResponse; +import android.hardware.radio.modem.NvItem; +import android.hardware.radio.modem.NvWriteItem; +import android.hardware.radio.modem.RadioCapability; +import android.hardware.radio.modem.ResetNvType; + +/** + * This interface is used by telephony and telecom to talk to cellular radio for modem APIs. + * All the functions have minimum one parameter: + * serial: which corresponds to serial no. of request. Serial numbers must only be memorized for the + * duration of a method call. If clients provide colliding serials (including passing the same + * serial to different methods), multiple responses (one for each method call) must still be served. + * setResponseFunctions must work with IRadioModemResponse and IRadioModemIndication. + */ +@VintfStability +oneway interface IRadioModem { + /** + * Toggle logical modem on/off. This is similar to IRadioModem.setRadioPower(), however that + * does not enforce that radio power is toggled only for the corresponding radio and certain + * vendor implementations do it for all radios. This new API should affect only the modem for + * which it is called. A modem stack must be on/active only when both setRadioPower() and + * enableModem() are set to on for it. + * + * SIM must be read if available even if modem is off/inactive. + * + * @param serial Serial number of request. + * @param on True to turn on the logical modem, otherwise turn it off. + * + * Response function is IRadioModemResponse.enableModemResponse() + */ + void enableModem(in int serial, in boolean on); + + /** + * Return string value indicating baseband version, eg response from AT+CGMR + * + * @param serial Serial number of request. + * + * Response function is IRadioModemResponse.getBasebandVersionResponse() + */ + void getBasebandVersion(in int serial); + + /** + * Request the device ESN / MEID / IMEI / IMEISV. The request is always allowed and contains + * GSM and CDMA device identity. When CDMA subscription is changed the ESN/MEID changes. + * The application layer must re-issue the request to update the device identity in this case. + * + * @param serial Serial number of request. + * + * Response function is IRadioModemResponse.getDeviceIdentityResponse() + */ + void getDeviceIdentity(in int serial); + + /** + * Request all of the current hardware (modem and sim) associated with Radio. + * + * @param serial Serial number of request. + * + * Response function is IRadioModemResponse.getHardwareConfigResponse() + */ + void getHardwareConfig(in int serial); + + /** + * Get modem activity information for power consumption estimation. Request clear-on-read + * statistics information that is used for estimating the per-millisecond power consumption + * of the cellular modem. + * + * @param serial Serial number of request. + * + * Response function is IRadioModemResponse.getModemActivityInfoResponse() + */ + void getModemActivityInfo(in int serial); + + /** + * Request status of logical modem. It returns isEnabled=true if the logical modem is on. + * This method is the getter method for enableModem. + * + * @param serial Serial number of request. + * + * Response function is IRadioModemResponse.getModemStackStatusResponse() + */ + void getModemStackStatus(in int serial); + + /** + * Get phone radio capability. + * + * @param serial Serial number of request. + * + * Response function is IRadioModemResponse.getRadioCapabilityResponse() + */ + void getRadioCapability(in int serial); + + /** + * Read one of the radio NV items. + * This is used for device configuration by some CDMA operators. + * + * @param serial Serial number of request. + * @param itemId NvItem + * + * Response function is IRadioModemResponse.nvReadItemResponse() + */ + void nvReadItem(in int serial, in NvItem itemId); + + /** + * Reset the radio NV configuration to the factory state. + * This is used for device configuration by some CDMA operators. + * + * @param serial Serial number of request. + * @param resetType ResetNvType + * + * Response function is IRadioModemResponse.nvResetConfigResponse() + */ + void nvResetConfig(in int serial, in ResetNvType resetType); + + /** + * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage. + * This is used for device configuration by some CDMA operators. + * + * @param serial Serial number of request. + * @param prl PRL as a byte array + * + * Response function is IRadioModemResponse.nvWriteCdmaPrlResponse() + */ + void nvWriteCdmaPrl(in int serial, in byte[] prl); + + /** + * Write one of the radio NV items. + * This is used for device configuration by some CDMA operators. + * + * @param serial Serial number of request. + * @param item NvWriteItem + * + * Response function is IRadioModemResponse.nvWriteItemResponse() + */ + void nvWriteItem(in int serial, in NvWriteItem item); + + /** + * Device is shutting down. All further commands are ignored and RADIO_NOT_AVAILABLE + * must be returned. + * + * @param serial Serial number of request. + * + * Response function is IRadioModemResponse.requestShutdownResponse() + */ + void requestShutdown(in int serial); + + /** + * When response type received from a radio indication or radio response is + * RadioIndicationType:UNSOLICITED_ACK_EXP or RadioResponseType:SOLICITED_ACK_EXP respectively, + * acknowledge the receipt of those messages by sending responseAcknowledgement(). + */ + void responseAcknowledgement(); + + /** + * Send the updated device state. This is providing the device state information for the modem + * to perform power saving strategies. + * + * @param serial Serial number of request. + * @param deviceStateType The updated device state type. + * @param state The updated state. See the definition of state at DeviceStateType. + * + * Response function is IRadioModemResponse.sendDeviceStateResponse() + */ + void sendDeviceState(in int serial, in DeviceStateType deviceStateType, in boolean state); + + /** + * Used to set the phones radio capability. Be VERY careful using this request as it may cause + * some vendor modems to reset. Because of the possible modem reset any radio commands after + * this one may not be processed. + * + * @param serial Serial number of request. + * @param rc RadioCapability structure to be set + * + * Response function is IRadioModemResponse.setRadioCapabilityResponse() + */ + void setRadioCapability(in int serial, in RadioCapability rc); + + /** + * Toggle radio on and off (for "airplane" mode). If the radio is turned off/on the radio modem + * subsystem is expected return to an initialized state. For instance, any voice and data calls + * must be terminated and all associated lists emptied. + * When setting radio power on to exit from airplane mode to place an emergency call on this + * logical modem, powerOn, forEmergencyCall and preferredForEmergencyCall must be true. In + * this case, this modem is optimized to scan only emergency call bands, until: + * 1) Emergency call is completed; or + * 2) Another setRadioPower is issued with forEmergencyCall being false or + * preferredForEmergencyCall being false; or + * 3) Timeout after 30 seconds if dial or emergencyDial is not called. + * Once one of these conditions is reached, the modem should move into normal operation. + * + * @param serial Serial number of request. + * @param powerOn To turn on radio -> on = true, to turn off radio -> on = false. + * @param forEmergencyCall To indication to radio if this request is due to emergency call. + * No effect if powerOn is false. + * @param preferredForEmergencyCall indicate whether the following emergency call will be sent + * on this modem or not. No effect if forEmergencyCall is false, or powerOn is false. + * + * Response function is IRadioConfigResponse.setRadioPowerResponse() + */ + void setRadioPower(in int serial, in boolean powerOn, in boolean forEmergencyCall, + in boolean preferredForEmergencyCall); + + /** + * Set response functions for modem radio requests and indications. + * + * @param radioModemResponse Object containing response functions + * @param radioModemIndication Object containing radio indications + */ + void setResponseFunctions(in IRadioModemResponse radioModemResponse, + in IRadioModemIndication radioModemIndication); +} diff --git a/radio/aidl/android/hardware/radio/modem/IRadioModemIndication.aidl b/radio/aidl/android/hardware/radio/modem/IRadioModemIndication.aidl new file mode 100644 index 0000000000..c61de99cd6 --- /dev/null +++ b/radio/aidl/android/hardware/radio/modem/IRadioModemIndication.aidl @@ -0,0 +1,78 @@ +/* + * 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.radio.modem; + +import android.hardware.radio.RadioIndicationType; +import android.hardware.radio.modem.HardwareConfig; +import android.hardware.radio.modem.RadioCapability; +import android.hardware.radio.modem.RadioState; + +/** + * Interface declaring unsolicited radio indications for modem APIs. + */ +@VintfStability +oneway interface IRadioModemIndication { + /** + * Indicates when the hardware configuration associated with the RILd changes. + * + * @param type Type of radio indication + * @param configs Array of hardware configs + */ + void hardwareConfigChanged(in RadioIndicationType type, in HardwareConfig[] configs); + + /** + * Indicates when there is a modem reset. + * When modem restarts, one of the following radio state transitions must happen + * 1) RadioState:ON->RadioState:UNAVAILABLE->RadioState:ON or + * 2) RadioState:OFF->RadioState:UNAVAILABLE->RadioState:OFF + * This message must be sent either just before the Radio State changes to + * RadioState:UNAVAILABLE or just after but must never be sent after the Radio State changes + * from RadioState:UNAVAILABLE to RadioState:ON/RadioState:OFF again. It must NOT be sent after + * the Radio state changes to RadioState:ON/RadioState:OFF after the modem restart as that may + * be interpreted as a second modem reset by the framework. + * + * @param type Type of radio indication + * @param reason the reason for the reset. It may be a crash signature if the restart was due to + * a crash or some string such as "user-initiated restart" or "AT command initiated + * restart" that explains the cause of the modem restart + */ + void modemReset(in RadioIndicationType type, in String reason); + + /** + * Sent when setRadioCapability() completes. Returns the phone radio capability exactly as + * getRadioCapability() and must be the same set as sent by setRadioCapability(). + * + * @param type Type of radio indication + * @param rc Current radio capability + */ + void radioCapabilityIndication(in RadioIndicationType type, in RadioCapability rc); + + /** + * Indicates when radio state changes. + * + * @param type Type of radio indication + * @param radioState Current radio state + */ + void radioStateChanged(in RadioIndicationType type, in RadioState radioState); + + /** + * Indicates the ril connects and returns the version + * + * @param type Type of radio indication + */ + void rilConnected(in RadioIndicationType type); +} diff --git a/radio/aidl/android/hardware/radio/modem/IRadioModemResponse.aidl b/radio/aidl/android/hardware/radio/modem/IRadioModemResponse.aidl new file mode 100644 index 0000000000..b17cac41c7 --- /dev/null +++ b/radio/aidl/android/hardware/radio/modem/IRadioModemResponse.aidl @@ -0,0 +1,257 @@ +/* + * 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.radio.modem; + +import android.hardware.radio.RadioResponseInfo; +import android.hardware.radio.modem.ActivityStatsInfo; +import android.hardware.radio.modem.HardwareConfig; +import android.hardware.radio.modem.RadioCapability; + +/** + * Interface declaring response functions to solicited radio requests for modem APIs. + */ +@VintfStability +oneway interface IRadioModemResponse { + /** + * Acknowledge the receipt of radio request sent to the vendor. This must be sent only for + * radio request which take long time to respond. For more details, refer + * https://source.android.com/devices/tech/connect/ril.html + * + * @param serial Serial no. of the request whose acknowledgement is sent. + */ + void acknowledgeRequest(in int serial); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:MODEM_ERR + * RadioError:INVALID_STATE: this is for the case that the API is called in a single-sim + * mode, or when there is only one modem available, as this API should only + * be called in multi sim status. + */ + void enableModemResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param version string containing version string for log reporting + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:EMPTY_RECORD + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:NOT_PROVISIONED + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + void getBasebandVersionResponse(in RadioResponseInfo info, in String version); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param imei IMEI if GSM subscription is available + * @param imeisv IMEISV if GSM subscription is available + * @param esn ESN if CDMA subscription is available + * @param meid MEID if CDMA subscription is available + * + * If a empty string value is returned for any of the device id, it means that there was error + * accessing the device. + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:MODEM_ERR + * RadioError:NOT_PROVISIONED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:REQUEST_NOT_SUPPORTED + */ + void getDeviceIdentityResponse(in RadioResponseInfo info, in String imei, in String imeisv, + in String esn, in String meid); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param config Array of HardwareConfig of the radio. + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:REQUEST_NOT_SUPPORTED + */ + void getHardwareConfigResponse(in RadioResponseInfo info, in HardwareConfig[] config); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param activityInfo modem activity information + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:NOT_PROVISIONED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:REQUEST_NOT_SUPPORTED + */ + void getModemActivityInfoResponse(in RadioResponseInfo info, in ActivityStatsInfo activityInfo); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:MODEM_ERR + */ + void getModemStackStatusResponse(in RadioResponseInfo info, in boolean isEnabled); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param rc Radio capability as defined by RadioCapability in types.hal + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:INVALID_STATE + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + void getRadioCapabilityResponse(in RadioResponseInfo info, in RadioCapability rc); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param result string containing the contents of the NV item + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:REQUEST_NOT_SUPPORTED + */ + void nvReadItemResponse(in RadioResponseInfo info, in String result); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:REQUEST_NOT_SUPPORTED + */ + void nvResetConfigResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:REQUEST_NOT_SUPPORTED + */ + void nvWriteCdmaPrlResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:REQUEST_NOT_SUPPORTED + */ + void nvWriteItemResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + void requestShutdownResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + void sendDeviceStateResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param rc Radio capability as defined by RadioCapability in types.hal used to + * feedback return status + * + * Valid errors returned: + * RadioError:NONE means a unsol radioCapability() will be sent within 30 seconds. + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:MODEM_ERR + * RadioError:INVALID_STATE + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + void setRadioCapabilityResponse(in RadioResponseInfo info, in RadioCapability rc); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:INTERNAL_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:RF_HARDWARE_ISSUE + * RadioError:NO_RF_CALIBRATION_INFO + */ + void setRadioPowerResponse(in RadioResponseInfo info); +} diff --git a/radio/aidl/android/hardware/radio/NvItem.aidl b/radio/aidl/android/hardware/radio/modem/NvItem.aidl similarity index 99% rename from radio/aidl/android/hardware/radio/NvItem.aidl rename to radio/aidl/android/hardware/radio/modem/NvItem.aidl index 0d4f79f150..cdae1c8b05 100644 --- a/radio/aidl/android/hardware/radio/NvItem.aidl +++ b/radio/aidl/android/hardware/radio/modem/NvItem.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.modem; @VintfStability @Backing(type="int") diff --git a/radio/aidl/android/hardware/radio/NvWriteItem.aidl b/radio/aidl/android/hardware/radio/modem/NvWriteItem.aidl similarity index 89% rename from radio/aidl/android/hardware/radio/NvWriteItem.aidl rename to radio/aidl/android/hardware/radio/modem/NvWriteItem.aidl index f3061612b4..d66c2cdcd6 100644 --- a/radio/aidl/android/hardware/radio/NvWriteItem.aidl +++ b/radio/aidl/android/hardware/radio/modem/NvWriteItem.aidl @@ -14,9 +14,9 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.modem; -import android.hardware.radio.NvItem; +import android.hardware.radio.modem.NvItem; @VintfStability parcelable NvWriteItem { diff --git a/radio/aidl/android/hardware/radio/RadioCapability.aidl b/radio/aidl/android/hardware/radio/modem/RadioCapability.aidl similarity index 98% rename from radio/aidl/android/hardware/radio/RadioCapability.aidl rename to radio/aidl/android/hardware/radio/modem/RadioCapability.aidl index a94e96abce..b7b8ef3552 100644 --- a/radio/aidl/android/hardware/radio/RadioCapability.aidl +++ b/radio/aidl/android/hardware/radio/modem/RadioCapability.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.modem; import android.hardware.radio.RadioAccessFamily; diff --git a/radio/aidl/android/hardware/radio/RadioState.aidl b/radio/aidl/android/hardware/radio/modem/RadioState.aidl similarity index 95% rename from radio/aidl/android/hardware/radio/RadioState.aidl rename to radio/aidl/android/hardware/radio/modem/RadioState.aidl index 1915870316..b9826a4b36 100644 --- a/radio/aidl/android/hardware/radio/RadioState.aidl +++ b/radio/aidl/android/hardware/radio/modem/RadioState.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.modem; @VintfStability @Backing(type="int") diff --git a/radio/aidl/android/hardware/radio/ResetNvType.aidl b/radio/aidl/android/hardware/radio/modem/ResetNvType.aidl similarity index 95% rename from radio/aidl/android/hardware/radio/ResetNvType.aidl rename to radio/aidl/android/hardware/radio/modem/ResetNvType.aidl index 59c74da9f8..a1411c9290 100644 --- a/radio/aidl/android/hardware/radio/ResetNvType.aidl +++ b/radio/aidl/android/hardware/radio/modem/ResetNvType.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.modem; @VintfStability @Backing(type="int") diff --git a/radio/aidl/android/hardware/radio/AccessTechnologySpecificInfo.aidl b/radio/aidl/android/hardware/radio/network/AccessTechnologySpecificInfo.aidl similarity index 77% rename from radio/aidl/android/hardware/radio/AccessTechnologySpecificInfo.aidl rename to radio/aidl/android/hardware/radio/network/AccessTechnologySpecificInfo.aidl index 6f0640c63c..dfd62a7b8e 100644 --- a/radio/aidl/android/hardware/radio/AccessTechnologySpecificInfo.aidl +++ b/radio/aidl/android/hardware/radio/network/AccessTechnologySpecificInfo.aidl @@ -14,11 +14,11 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; -import android.hardware.radio.Cdma2000RegistrationInfo; -import android.hardware.radio.EutranRegistrationInfo; -import android.hardware.radio.NrVopsInfo; +import android.hardware.radio.network.Cdma2000RegistrationInfo; +import android.hardware.radio.network.EutranRegistrationInfo; +import android.hardware.radio.network.NrVopsInfo; @VintfStability union AccessTechnologySpecificInfo { @@ -27,7 +27,7 @@ union AccessTechnologySpecificInfo { EutranRegistrationInfo eutranInfo; /** * Network capabilities for voice over PS services. This info is valid only on NR network and - * must be present when the device is camped on NR. VopsInfo must be empty when the device is + * must be present when the device is camped on NR. NrVopsInfo must be empty when the device is * not camped on NR. */ NrVopsInfo ngranNrVopsInfo; diff --git a/radio/aidl/android/hardware/radio/BarringInfo.aidl b/radio/aidl/android/hardware/radio/network/BarringInfo.aidl similarity index 97% rename from radio/aidl/android/hardware/radio/BarringInfo.aidl rename to radio/aidl/android/hardware/radio/network/BarringInfo.aidl index 2bffa2e67c..da49ba51f3 100644 --- a/radio/aidl/android/hardware/radio/BarringInfo.aidl +++ b/radio/aidl/android/hardware/radio/network/BarringInfo.aidl @@ -14,9 +14,9 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; -import android.hardware.radio.BarringTypeSpecificInfo; +import android.hardware.radio.network.BarringTypeSpecificInfo; @VintfStability parcelable BarringInfo { diff --git a/radio/aidl/android/hardware/radio/BarringTypeSpecificInfo.aidl b/radio/aidl/android/hardware/radio/network/BarringTypeSpecificInfo.aidl similarity index 97% rename from radio/aidl/android/hardware/radio/BarringTypeSpecificInfo.aidl rename to radio/aidl/android/hardware/radio/network/BarringTypeSpecificInfo.aidl index c3b892b479..3899711420 100644 --- a/radio/aidl/android/hardware/radio/BarringTypeSpecificInfo.aidl +++ b/radio/aidl/android/hardware/radio/network/BarringTypeSpecificInfo.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; @VintfStability parcelable BarringTypeSpecificInfo { diff --git a/radio/aidl/android/hardware/radio/Cdma2000RegistrationInfo.aidl b/radio/aidl/android/hardware/radio/network/Cdma2000RegistrationInfo.aidl similarity index 97% rename from radio/aidl/android/hardware/radio/Cdma2000RegistrationInfo.aidl rename to radio/aidl/android/hardware/radio/network/Cdma2000RegistrationInfo.aidl index b9f3b66c54..6ea6cf92dc 100644 --- a/radio/aidl/android/hardware/radio/Cdma2000RegistrationInfo.aidl +++ b/radio/aidl/android/hardware/radio/network/Cdma2000RegistrationInfo.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; @VintfStability parcelable Cdma2000RegistrationInfo { diff --git a/radio/aidl/android/hardware/radio/CdmaRoamingType.aidl b/radio/aidl/android/hardware/radio/network/CdmaRoamingType.aidl similarity index 94% rename from radio/aidl/android/hardware/radio/CdmaRoamingType.aidl rename to radio/aidl/android/hardware/radio/network/CdmaRoamingType.aidl index df09e0337c..3da8c98346 100644 --- a/radio/aidl/android/hardware/radio/CdmaRoamingType.aidl +++ b/radio/aidl/android/hardware/radio/network/CdmaRoamingType.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; @VintfStability @Backing(type="int") diff --git a/radio/aidl/android/hardware/radio/CdmaSignalStrength.aidl b/radio/aidl/android/hardware/radio/network/CdmaSignalStrength.aidl similarity index 96% rename from radio/aidl/android/hardware/radio/CdmaSignalStrength.aidl rename to radio/aidl/android/hardware/radio/network/CdmaSignalStrength.aidl index e6c2fb5e2f..c7754f2ac7 100644 --- a/radio/aidl/android/hardware/radio/CdmaSignalStrength.aidl +++ b/radio/aidl/android/hardware/radio/network/CdmaSignalStrength.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; @VintfStability parcelable CdmaSignalStrength { diff --git a/radio/aidl/android/hardware/radio/CellConnectionStatus.aidl b/radio/aidl/android/hardware/radio/network/CellConnectionStatus.aidl similarity index 87% rename from radio/aidl/android/hardware/radio/CellConnectionStatus.aidl rename to radio/aidl/android/hardware/radio/network/CellConnectionStatus.aidl index faa9b28635..d9f5766d76 100644 --- a/radio/aidl/android/hardware/radio/CellConnectionStatus.aidl +++ b/radio/aidl/android/hardware/radio/network/CellConnectionStatus.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; @VintfStability @Backing(type="int") @@ -24,7 +24,7 @@ enum CellConnectionStatus { */ NONE, /** - * UE has connection to cell for signalling and possibly data (3GPP 36.331, 25.331). + * UE has connection to cell for signaling and possibly data (3GPP 36.331, 25.331). */ PRIMARY_SERVING, /** diff --git a/radio/aidl/android/hardware/radio/CellIdentity.aidl b/radio/aidl/android/hardware/radio/network/CellIdentity.aidl similarity index 70% rename from radio/aidl/android/hardware/radio/CellIdentity.aidl rename to radio/aidl/android/hardware/radio/network/CellIdentity.aidl index abfcc9d11f..af6d38e34f 100644 --- a/radio/aidl/android/hardware/radio/CellIdentity.aidl +++ b/radio/aidl/android/hardware/radio/network/CellIdentity.aidl @@ -14,14 +14,14 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; -import android.hardware.radio.CellIdentityCdma; -import android.hardware.radio.CellIdentityGsm; -import android.hardware.radio.CellIdentityLte; -import android.hardware.radio.CellIdentityNr; -import android.hardware.radio.CellIdentityTdscdma; -import android.hardware.radio.CellIdentityWcdma; +import android.hardware.radio.network.CellIdentityCdma; +import android.hardware.radio.network.CellIdentityGsm; +import android.hardware.radio.network.CellIdentityLte; +import android.hardware.radio.network.CellIdentityNr; +import android.hardware.radio.network.CellIdentityTdscdma; +import android.hardware.radio.network.CellIdentityWcdma; /** * A union representing the CellIdentity of a single cell. diff --git a/radio/aidl/android/hardware/radio/CellIdentityCdma.aidl b/radio/aidl/android/hardware/radio/network/CellIdentityCdma.aidl similarity index 93% rename from radio/aidl/android/hardware/radio/CellIdentityCdma.aidl rename to radio/aidl/android/hardware/radio/network/CellIdentityCdma.aidl index 56867e982b..e271e50eac 100644 --- a/radio/aidl/android/hardware/radio/CellIdentityCdma.aidl +++ b/radio/aidl/android/hardware/radio/network/CellIdentityCdma.aidl @@ -14,9 +14,9 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; -import android.hardware.radio.CellIdentityOperatorNames; +import android.hardware.radio.network.CellIdentityOperatorNames; @VintfStability parcelable CellIdentityCdma { diff --git a/radio/aidl/android/hardware/radio/CellIdentityGsm.aidl b/radio/aidl/android/hardware/radio/network/CellIdentityGsm.aidl similarity index 93% rename from radio/aidl/android/hardware/radio/CellIdentityGsm.aidl rename to radio/aidl/android/hardware/radio/network/CellIdentityGsm.aidl index f1c5042fe8..7b711ad747 100644 --- a/radio/aidl/android/hardware/radio/CellIdentityGsm.aidl +++ b/radio/aidl/android/hardware/radio/network/CellIdentityGsm.aidl @@ -14,9 +14,9 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; -import android.hardware.radio.CellIdentityOperatorNames; +import android.hardware.radio.network.CellIdentityOperatorNames; @VintfStability parcelable CellIdentityGsm { diff --git a/radio/aidl/android/hardware/radio/CellIdentityLte.aidl b/radio/aidl/android/hardware/radio/network/CellIdentityLte.aidl similarity index 88% rename from radio/aidl/android/hardware/radio/CellIdentityLte.aidl rename to radio/aidl/android/hardware/radio/network/CellIdentityLte.aidl index 1a261a648f..d4f83a34b3 100644 --- a/radio/aidl/android/hardware/radio/CellIdentityLte.aidl +++ b/radio/aidl/android/hardware/radio/network/CellIdentityLte.aidl @@ -14,11 +14,11 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; -import android.hardware.radio.CellIdentityOperatorNames; -import android.hardware.radio.ClosedSubscriberGroupInfo; -import android.hardware.radio.EutranBands; +import android.hardware.radio.network.CellIdentityOperatorNames; +import android.hardware.radio.network.ClosedSubscriberGroupInfo; +import android.hardware.radio.network.EutranBands; @VintfStability parcelable CellIdentityLte { diff --git a/radio/aidl/android/hardware/radio/CellIdentityNr.aidl b/radio/aidl/android/hardware/radio/network/CellIdentityNr.aidl similarity index 93% rename from radio/aidl/android/hardware/radio/CellIdentityNr.aidl rename to radio/aidl/android/hardware/radio/network/CellIdentityNr.aidl index 6879c63faa..dfccbf7e63 100644 --- a/radio/aidl/android/hardware/radio/CellIdentityNr.aidl +++ b/radio/aidl/android/hardware/radio/network/CellIdentityNr.aidl @@ -14,10 +14,10 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; -import android.hardware.radio.CellIdentityOperatorNames; -import android.hardware.radio.NgranBands; +import android.hardware.radio.network.CellIdentityOperatorNames; +import android.hardware.radio.network.NgranBands; /** * The CellIdentity structure should be reported once for each element of the PLMN-IdentityInfoList diff --git a/radio/aidl/android/hardware/radio/CellIdentityOperatorNames.aidl b/radio/aidl/android/hardware/radio/network/CellIdentityOperatorNames.aidl similarity index 95% rename from radio/aidl/android/hardware/radio/CellIdentityOperatorNames.aidl rename to radio/aidl/android/hardware/radio/network/CellIdentityOperatorNames.aidl index dea9929f73..540014ad52 100644 --- a/radio/aidl/android/hardware/radio/CellIdentityOperatorNames.aidl +++ b/radio/aidl/android/hardware/radio/network/CellIdentityOperatorNames.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; @VintfStability parcelable CellIdentityOperatorNames { diff --git a/radio/aidl/android/hardware/radio/CellIdentityTdscdma.aidl b/radio/aidl/android/hardware/radio/network/CellIdentityTdscdma.aidl similarity index 90% rename from radio/aidl/android/hardware/radio/CellIdentityTdscdma.aidl rename to radio/aidl/android/hardware/radio/network/CellIdentityTdscdma.aidl index 8232245833..99c8151fc8 100644 --- a/radio/aidl/android/hardware/radio/CellIdentityTdscdma.aidl +++ b/radio/aidl/android/hardware/radio/network/CellIdentityTdscdma.aidl @@ -14,10 +14,10 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; -import android.hardware.radio.CellIdentityOperatorNames; -import android.hardware.radio.ClosedSubscriberGroupInfo; +import android.hardware.radio.network.CellIdentityOperatorNames; +import android.hardware.radio.network.ClosedSubscriberGroupInfo; @VintfStability parcelable CellIdentityTdscdma { diff --git a/radio/aidl/android/hardware/radio/CellIdentityWcdma.aidl b/radio/aidl/android/hardware/radio/network/CellIdentityWcdma.aidl similarity index 90% rename from radio/aidl/android/hardware/radio/CellIdentityWcdma.aidl rename to radio/aidl/android/hardware/radio/network/CellIdentityWcdma.aidl index 3432747943..302be9645d 100644 --- a/radio/aidl/android/hardware/radio/CellIdentityWcdma.aidl +++ b/radio/aidl/android/hardware/radio/network/CellIdentityWcdma.aidl @@ -14,10 +14,10 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; -import android.hardware.radio.CellIdentityOperatorNames; -import android.hardware.radio.ClosedSubscriberGroupInfo; +import android.hardware.radio.network.CellIdentityOperatorNames; +import android.hardware.radio.network.ClosedSubscriberGroupInfo; @VintfStability parcelable CellIdentityWcdma { diff --git a/radio/aidl/android/hardware/radio/CellInfo.aidl b/radio/aidl/android/hardware/radio/network/CellInfo.aidl similarity index 80% rename from radio/aidl/android/hardware/radio/CellInfo.aidl rename to radio/aidl/android/hardware/radio/network/CellInfo.aidl index fe4f330611..58cf9f5838 100644 --- a/radio/aidl/android/hardware/radio/CellInfo.aidl +++ b/radio/aidl/android/hardware/radio/network/CellInfo.aidl @@ -14,10 +14,10 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; -import android.hardware.radio.CellConnectionStatus; -import android.hardware.radio.CellInfoCellInfoRatSpecificInfo; +import android.hardware.radio.network.CellConnectionStatus; +import android.hardware.radio.network.CellInfoRatSpecificInfo; @VintfStability parcelable CellInfo { @@ -29,5 +29,5 @@ parcelable CellInfo { * Connection status for the cell. */ CellConnectionStatus connectionStatus; - CellInfoCellInfoRatSpecificInfo ratSpecificInfo; + CellInfoRatSpecificInfo ratSpecificInfo; } diff --git a/radio/aidl/android/hardware/radio/CellInfoCdma.aidl b/radio/aidl/android/hardware/radio/network/CellInfoCdma.aidl similarity index 78% rename from radio/aidl/android/hardware/radio/CellInfoCdma.aidl rename to radio/aidl/android/hardware/radio/network/CellInfoCdma.aidl index 27a35d1247..6d9291827a 100644 --- a/radio/aidl/android/hardware/radio/CellInfoCdma.aidl +++ b/radio/aidl/android/hardware/radio/network/CellInfoCdma.aidl @@ -14,11 +14,11 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; -import android.hardware.radio.CdmaSignalStrength; -import android.hardware.radio.CellIdentityCdma; -import android.hardware.radio.EvdoSignalStrength; +import android.hardware.radio.network.CdmaSignalStrength; +import android.hardware.radio.network.CellIdentityCdma; +import android.hardware.radio.network.EvdoSignalStrength; @VintfStability parcelable CellInfoCdma { diff --git a/radio/aidl/android/hardware/radio/CellInfoGsm.aidl b/radio/aidl/android/hardware/radio/network/CellInfoGsm.aidl similarity index 83% rename from radio/aidl/android/hardware/radio/CellInfoGsm.aidl rename to radio/aidl/android/hardware/radio/network/CellInfoGsm.aidl index 16ba8574ef..fc85248590 100644 --- a/radio/aidl/android/hardware/radio/CellInfoGsm.aidl +++ b/radio/aidl/android/hardware/radio/network/CellInfoGsm.aidl @@ -14,10 +14,10 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; -import android.hardware.radio.CellIdentityGsm; -import android.hardware.radio.GsmSignalStrength; +import android.hardware.radio.network.CellIdentityGsm; +import android.hardware.radio.network.GsmSignalStrength; @VintfStability parcelable CellInfoGsm { diff --git a/radio/aidl/android/hardware/radio/CellInfoLte.aidl b/radio/aidl/android/hardware/radio/network/CellInfoLte.aidl similarity index 83% rename from radio/aidl/android/hardware/radio/CellInfoLte.aidl rename to radio/aidl/android/hardware/radio/network/CellInfoLte.aidl index d3389c1564..22db722c99 100644 --- a/radio/aidl/android/hardware/radio/CellInfoLte.aidl +++ b/radio/aidl/android/hardware/radio/network/CellInfoLte.aidl @@ -14,10 +14,10 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; -import android.hardware.radio.CellIdentityLte; -import android.hardware.radio.LteSignalStrength; +import android.hardware.radio.network.CellIdentityLte; +import android.hardware.radio.network.LteSignalStrength; @VintfStability parcelable CellInfoLte { diff --git a/radio/aidl/android/hardware/radio/CellInfoNr.aidl b/radio/aidl/android/hardware/radio/network/CellInfoNr.aidl similarity index 83% rename from radio/aidl/android/hardware/radio/CellInfoNr.aidl rename to radio/aidl/android/hardware/radio/network/CellInfoNr.aidl index b1f311f113..fbf026ec32 100644 --- a/radio/aidl/android/hardware/radio/CellInfoNr.aidl +++ b/radio/aidl/android/hardware/radio/network/CellInfoNr.aidl @@ -14,10 +14,10 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; -import android.hardware.radio.CellIdentityNr; -import android.hardware.radio.NrSignalStrength; +import android.hardware.radio.network.CellIdentityNr; +import android.hardware.radio.network.NrSignalStrength; @VintfStability parcelable CellInfoNr { diff --git a/radio/aidl/android/hardware/radio/CellInfoCellInfoRatSpecificInfo.aidl b/radio/aidl/android/hardware/radio/network/CellInfoRatSpecificInfo.aidl similarity index 69% rename from radio/aidl/android/hardware/radio/CellInfoCellInfoRatSpecificInfo.aidl rename to radio/aidl/android/hardware/radio/network/CellInfoRatSpecificInfo.aidl index cdd33863de..7e8a437873 100644 --- a/radio/aidl/android/hardware/radio/CellInfoCellInfoRatSpecificInfo.aidl +++ b/radio/aidl/android/hardware/radio/network/CellInfoRatSpecificInfo.aidl @@ -14,17 +14,17 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; -import android.hardware.radio.CellInfoCdma; -import android.hardware.radio.CellInfoGsm; -import android.hardware.radio.CellInfoLte; -import android.hardware.radio.CellInfoNr; -import android.hardware.radio.CellInfoTdscdma; -import android.hardware.radio.CellInfoWcdma; +import android.hardware.radio.network.CellInfoCdma; +import android.hardware.radio.network.CellInfoGsm; +import android.hardware.radio.network.CellInfoLte; +import android.hardware.radio.network.CellInfoNr; +import android.hardware.radio.network.CellInfoTdscdma; +import android.hardware.radio.network.CellInfoWcdma; @VintfStability -union CellInfoCellInfoRatSpecificInfo { +union CellInfoRatSpecificInfo { /** * 3gpp CellInfo types. */ diff --git a/radio/aidl/android/hardware/radio/CellInfoTdscdma.aidl b/radio/aidl/android/hardware/radio/network/CellInfoTdscdma.aidl similarity index 82% rename from radio/aidl/android/hardware/radio/CellInfoTdscdma.aidl rename to radio/aidl/android/hardware/radio/network/CellInfoTdscdma.aidl index b7d09bc07b..e07e721c7d 100644 --- a/radio/aidl/android/hardware/radio/CellInfoTdscdma.aidl +++ b/radio/aidl/android/hardware/radio/network/CellInfoTdscdma.aidl @@ -14,10 +14,10 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; -import android.hardware.radio.CellIdentityTdscdma; -import android.hardware.radio.TdscdmaSignalStrength; +import android.hardware.radio.network.CellIdentityTdscdma; +import android.hardware.radio.network.TdscdmaSignalStrength; @VintfStability parcelable CellInfoTdscdma { diff --git a/radio/aidl/android/hardware/radio/CellInfoWcdma.aidl b/radio/aidl/android/hardware/radio/network/CellInfoWcdma.aidl similarity index 82% rename from radio/aidl/android/hardware/radio/CellInfoWcdma.aidl rename to radio/aidl/android/hardware/radio/network/CellInfoWcdma.aidl index 03b086367a..38b6903109 100644 --- a/radio/aidl/android/hardware/radio/CellInfoWcdma.aidl +++ b/radio/aidl/android/hardware/radio/network/CellInfoWcdma.aidl @@ -14,10 +14,10 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; -import android.hardware.radio.CellIdentityWcdma; -import android.hardware.radio.WcdmaSignalStrength; +import android.hardware.radio.network.CellIdentityWcdma; +import android.hardware.radio.network.WcdmaSignalStrength; @VintfStability parcelable CellInfoWcdma { diff --git a/radio/aidl/android/hardware/radio/ClosedSubscriberGroupInfo.aidl b/radio/aidl/android/hardware/radio/network/ClosedSubscriberGroupInfo.aidl similarity index 97% rename from radio/aidl/android/hardware/radio/ClosedSubscriberGroupInfo.aidl rename to radio/aidl/android/hardware/radio/network/ClosedSubscriberGroupInfo.aidl index 7c6fb7a5fe..b5b4add416 100644 --- a/radio/aidl/android/hardware/radio/ClosedSubscriberGroupInfo.aidl +++ b/radio/aidl/android/hardware/radio/network/ClosedSubscriberGroupInfo.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; @VintfStability parcelable ClosedSubscriberGroupInfo { diff --git a/radio/aidl/android/hardware/radio/Domain.aidl b/radio/aidl/android/hardware/radio/network/Domain.aidl similarity index 95% rename from radio/aidl/android/hardware/radio/Domain.aidl rename to radio/aidl/android/hardware/radio/network/Domain.aidl index f5e5261310..b62f0eeb72 100644 --- a/radio/aidl/android/hardware/radio/Domain.aidl +++ b/radio/aidl/android/hardware/radio/network/Domain.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; @VintfStability @Backing(type="int") diff --git a/radio/aidl/android/hardware/radio/EutranBands.aidl b/radio/aidl/android/hardware/radio/network/EutranBands.aidl similarity index 97% rename from radio/aidl/android/hardware/radio/EutranBands.aidl rename to radio/aidl/android/hardware/radio/network/EutranBands.aidl index 59fe6c4036..48ee26e179 100644 --- a/radio/aidl/android/hardware/radio/EutranBands.aidl +++ b/radio/aidl/android/hardware/radio/network/EutranBands.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; /** * EUTRAN bands up to V16.4.0 diff --git a/radio/aidl/android/hardware/radio/EutranRegistrationInfo.aidl b/radio/aidl/android/hardware/radio/network/EutranRegistrationInfo.aidl similarity index 88% rename from radio/aidl/android/hardware/radio/EutranRegistrationInfo.aidl rename to radio/aidl/android/hardware/radio/network/EutranRegistrationInfo.aidl index 0f8f949b9d..5e19c56690 100644 --- a/radio/aidl/android/hardware/radio/EutranRegistrationInfo.aidl +++ b/radio/aidl/android/hardware/radio/network/EutranRegistrationInfo.aidl @@ -14,10 +14,10 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; -import android.hardware.radio.LteVopsInfo; -import android.hardware.radio.NrIndicators; +import android.hardware.radio.network.LteVopsInfo; +import android.hardware.radio.network.NrIndicators; @VintfStability parcelable EutranRegistrationInfo { diff --git a/radio/aidl/android/hardware/radio/EvdoSignalStrength.aidl b/radio/aidl/android/hardware/radio/network/EvdoSignalStrength.aidl similarity index 96% rename from radio/aidl/android/hardware/radio/EvdoSignalStrength.aidl rename to radio/aidl/android/hardware/radio/network/EvdoSignalStrength.aidl index ff631f311b..0ab8b59024 100644 --- a/radio/aidl/android/hardware/radio/EvdoSignalStrength.aidl +++ b/radio/aidl/android/hardware/radio/network/EvdoSignalStrength.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; @VintfStability parcelable EvdoSignalStrength { diff --git a/radio/aidl/android/hardware/radio/GeranBands.aidl b/radio/aidl/android/hardware/radio/network/GeranBands.aidl similarity index 95% rename from radio/aidl/android/hardware/radio/GeranBands.aidl rename to radio/aidl/android/hardware/radio/network/GeranBands.aidl index d3a7598570..573d77146b 100644 --- a/radio/aidl/android/hardware/radio/GeranBands.aidl +++ b/radio/aidl/android/hardware/radio/network/GeranBands.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; @VintfStability @Backing(type="int") diff --git a/radio/aidl/android/hardware/radio/GsmSignalStrength.aidl b/radio/aidl/android/hardware/radio/network/GsmSignalStrength.aidl similarity index 96% rename from radio/aidl/android/hardware/radio/GsmSignalStrength.aidl rename to radio/aidl/android/hardware/radio/network/GsmSignalStrength.aidl index 65f853a1f7..539e1cec87 100644 --- a/radio/aidl/android/hardware/radio/GsmSignalStrength.aidl +++ b/radio/aidl/android/hardware/radio/network/GsmSignalStrength.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; @VintfStability parcelable GsmSignalStrength { diff --git a/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl b/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl new file mode 100644 index 0000000000..0db918d8f5 --- /dev/null +++ b/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl @@ -0,0 +1,444 @@ +/* + * 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.radio.network; + +import android.hardware.radio.AccessNetwork; +import android.hardware.radio.RadioAccessFamily; +import android.hardware.radio.network.CdmaRoamingType; +import android.hardware.radio.network.IRadioNetworkIndication; +import android.hardware.radio.network.IRadioNetworkResponse; +import android.hardware.radio.network.IndicationFilter; +import android.hardware.radio.network.NetworkScanRequest; +import android.hardware.radio.network.NrDualConnectivityState; +import android.hardware.radio.network.RadioAccessSpecifier; +import android.hardware.radio.network.RadioBandMode; +import android.hardware.radio.network.SignalThresholdInfo; + +/** + * This interface is used by telephony and telecom to talk to cellular radio for network APIs. + * All the functions have minimum one parameter: + * serial: which corresponds to serial no. of request. Serial numbers must only be memorized for the + * duration of a method call. If clients provide colliding serials (including passing the same + * serial to different methods), multiple responses (one for each method call) must still be served. + * setResponseFunctions must work with IRadioNetworkResponse and IRadioNetworkIndication. + */ +@VintfStability +oneway interface IRadioNetwork { + /** + * Requests bitmap representing the currently allowed network types. + * + * @param serial Serial number of request. + * + * Response function is IRadioNetworkResponse.getAllowedNetworkTypesBitmapResponse() + */ + void getAllowedNetworkTypesBitmap(in int serial); + + /** + * Get the list of band modes supported by RF. + * + * @param serial Serial number of request. + * + * Response function is IRadioNetworkResponse.getAvailableBandModesResponse() + */ + void getAvailableBandModes(in int serial); + + /** + * Scans for available networks + * + * @param serial Serial number of request. + * + * Response function is IRadioNetworkResponse.getAvailableNetworksResponse() + */ + void getAvailableNetworks(in int serial); + + /** + * Get all the barring info for the current camped cell applicable to the current user. + * + * @param serial Serial number of request. + * + * Response function is IRadioNetworkResponse.getBarringInfoResponse() + */ + void getBarringInfo(in int serial); + + /** + * Request the actual setting of the roaming preferences in CDMA in the modem + * + * @param serial Serial number of request. + * + * Response function is IRadioNetworkResponse.getCdmaRoamingPreferenceResponse() + */ + void getCdmaRoamingPreference(in int serial); + + /** + * Request all of the current cell information known to the radio. The radio must return a list + * of all current cells, including the neighboring cells. If for a particular cell information + * isn't known then the appropriate unknown value will be returned. + * This does not cause or change the rate of unsolicited cellInfoList(). + * + * @param serial Serial number of request. + * + * Response function is IRadioNetworkResponse.getCellInfoListResponse() + */ + void getCellInfoList(in int serial); + + /** + * Request current data registration state. + * + * @param serial Serial number of request. + * + * Response function is IRadioNetworkResponse.getDataRegistrationStateResponse() + */ + void getDataRegistrationState(in int serial); + + /** + * Request current IMS registration state + * + * @param serial Serial number of request. + * + * Response function is IRadioNetworkResponse.getImsRegistrationStateResponse() + */ + void getImsRegistrationState(in int serial); + + /** + * Request neighboring cell id in GSM network + * + * @param serial Serial number of request. + * + * Response function is IRadioNetworkResponse.getNeighboringCidsResponse() + */ + void getNeighboringCids(in int serial); + + /** + * Query current network selection mode + * + * @param serial Serial number of request. + * + * Response function is IRadioNetworkResponse.getNetworkSelectionModeResponse() + */ + void getNetworkSelectionMode(in int serial); + + /** + * Request current operator ONS or EONS + * + * @param serial Serial number of request. + * + * Response function is IRadioNetworkResponse.getOperatorResponse() + */ + void getOperator(in int serial); + + /** + * Requests current signal strength and associated information. Must succeed if radio is on. + * + * @param serial Serial number of request. + * + * Response function is IRadioNetworkResponse.getSignalStrengthResponse() + */ + void getSignalStrength(in int serial); + + /** + * Get which bands the modem's background scan is acting on. + * + * @param serial Serial number of request. + * + * Response function is IRadioNetworkResponse.getSystemSelectionChannelsResponse() + */ + void getSystemSelectionChannels(in int serial); + + /** + * Query the radio technology type (3GPP/3GPP2) used for voice. Query is valid only + * when radio state is not RADIO_STATE_UNAVAILABLE + * + * @param serial Serial number of request. + * + * Response function is IRadioNetworkResponse.getVoiceRadioTechnologyResponse() + */ + void getVoiceRadioTechnology(in int serial); + + /** + * Request current voice registration state. + * + * @param serial Serial number of request. + * + * Response function is IRadioNetworkResponse.getVoiceRegistrationStateResponse() + */ + void getVoiceRegistrationState(in int serial); + + /** + * Is E-UTRA-NR Dual Connectivity enabled + * + * @param serial Serial number of request. + * + * Response function is IRadioNetworkResponse.isNrDualConnectivityEnabledResponse() + */ + void isNrDualConnectivityEnabled(in int serial); + + /** + * Pull LCE service for capacity information. + * + * @param serial Serial number of request. + * + * Response function is IRadioNetworkResponse.pullLceDataResponse() + */ + void pullLceData(in int serial); + + /** + * When response type received from a radio indication or radio response is + * RadioIndicationType:UNSOLICITED_ACK_EXP or RadioResponseType:SOLICITED_ACK_EXP respectively, + * acknowledge the receipt of those messages by sending responseAcknowledgement(). + */ + void responseAcknowledgement(); + + /** + * Requests to set the network type for searching and registering. Instruct the radio to + * *only* accept the types of network provided. In case of an emergency call, the modem is + * authorized to bypass this restriction. + * + * @param serial Serial number of request. + * @param networkTypeBitmap a 32-bit bearer bitmap of RadioAccessFamily + * + * Response function is IRadioNetworkResponse.setAllowedNetworkTypesBitmapResponse() + */ + void setAllowedNetworkTypesBitmap(in int serial, in RadioAccessFamily networkTypeBitmap); + + /** + * Assign a specified band for RF configuration. + * + * @param serial Serial number of request. + * @param mode RadioBandMode + * + * Response function is IRadioNetworkResponse.setBandModeResponse() + */ + void setBandMode(in int serial, in RadioBandMode mode); + + /** + * Change call barring facility password + * + * @param serial Serial number of request. + * @param facility facility string code from TS 27.007 7.4 (eg "AO" for BAOC) + * @param oldPassword old password + * @param newPassword new password + * + * Response function is IRadioNetworkResponse.setBarringPasswordResponse() + */ + void setBarringPassword( + in int serial, in String facility, in String oldPassword, in String newPassword); + + /** + * Request to set the roaming preferences in CDMA + * + * @param serial Serial number of request. + * @param type CdmaRoamingType defined in types.hal + * + * Response function is IRadioNetworkResponse.setCdmaRoamingPreferenceResponse() + */ + void setCdmaRoamingPreference(in int serial, in CdmaRoamingType type); + + /** + * Sets the minimum time between when unsolicited cellInfoList() must be invoked. + * A value of 0, means invoke cellInfoList() when any of the reported information changes. + * Setting the value to INT_MAX(0x7fffffff) means never issue a unsolicited cellInfoList(). + * + * @param serial Serial number of request. + * @param rate minimum time in milliseconds to indicate time between unsolicited cellInfoList() + * + * Response function is IRadioNetworkResponse.setCellInfoListRateResponse() + */ + void setCellInfoListRate(in int serial, in int rate); + + /** + * Sets the indication filter. Prevents the reporting of specified unsolicited indications from + * the radio. This is used for power saving in instances when those indications are not needed. + * If unset, defaults to IndicationFilter:ALL. + * + * @param serial Serial number of request. + * @param indicationFilter 32-bit bitmap of IndicationFilter. Bits set to 1 indicate the + * indications are enabled. See IndicationFilter for the definition of each bit. + * + * Response function is IRadioNetworkResponse.setIndicationFilterResponse() + */ + void setIndicationFilter(in int serial, in IndicationFilter indicationFilter); + + /** + * Sets the link capacity reporting criteria. The resulting reporting criteria are the AND of + * all the supplied criteria. Note that reporting criteria must be individually set for each + * RAN. If unset, reporting criteria for that RAN are implementation-defined. + * + * @param serial Serial number of request. + * @param hysteresisMs A hysteresis time in milliseconds to prevent flapping. A value of 0 + * disables hysteresis. + * @param hysteresisDlKbps An interval in kbps defining the required magnitude change between DL + * reports. hysteresisDlKbps must be smaller than the smallest threshold delta. A value + * of 0 disables hysteresis. + * @param hysteresisUlKbps An interval in kbps defining the required magnitude change between UL + * reports. hysteresisUlKbps must be smaller than the smallest threshold delta. A value + * of 0 disables hysteresis. + * @param thresholdsDownlinkKbps A vector of trigger thresholds in kbps for downlink reports. A + * vector size of 0 disables the use of DL thresholds for reporting. + * @param thresholdsUplinkKbps A vector of trigger thresholds in kbps for uplink reports. A + * vector size of 0 disables the use of UL thresholds for reporting. + * @param accessNetwork The type of network for which to apply these thresholds. + * + * Response function is IRadioNetworkResponse.setLinkCapacityReportingCriteriaResponse(). + */ + void setLinkCapacityReportingCriteria(in int serial, in int hysteresisMs, + in int hysteresisDlKbps, in int hysteresisUlKbps, in int[] thresholdsDownlinkKbps, + in int[] thresholdsUplinkKbps, in AccessNetwork accessNetwork); + + /** + * Enables/disables network state change notifications due to changes in LAC and/or CID (for + * GSM) or BID/SID/NID/latitude/longitude (for CDMA). Basically +CREG=2 vs. +CREG=1 (TS 27.007). + * The Radio implementation must default to "updates enabled" when the screen is on and + * "updates disabled" when the screen is off. + * + * @param serial Serial number of request. + * @param enable true=updates enabled (+CREG=2), false=updates disabled (+CREG=1) + * + * Response function is IRadioNetworkResponse.setLocationUpdatesResponse() + */ + void setLocationUpdates(in int serial, in boolean enable); + + /** + * Specify that the network must be selected automatically. + * This request must not respond until the new operator is selected and registered. + * + * @param serial Serial number of request. + * + * Response function is IRadioNetworkResponse.setNetworkSelectionModeAutomaticResponse() + */ + void setNetworkSelectionModeAutomatic(in int serial); + + /** + * Manually select a specified network. This request must not respond until the new operator is + * selected and registered. Per TS 23.122, the RAN is just the initial suggested value. + * If registration fails, the RAN is not available afterwards, or the RAN is not within the + * network types specified by IRadioNetwork::setAllowedNetworkTypeBitmap, then the modem will + * need to select the next best RAN for network registration. + * + * @param serial Serial number of request. + * @param operatorNumeric String specifying MCCMNC of network to select (eg "310170"). + * @param ran Initial suggested access network type. If value is UNKNOWN, the modem will select + * the next best RAN for network registration. + * + * Response function is IRadioNetworkResponse.setNetworkSelectionModeManualResponse() + */ + void setNetworkSelectionModeManual( + in int serial, in String operatorNumeric, in AccessNetwork ran); + + /** + * Enable or disable E-UTRA-NR dual connectivity. If disabled then UE will not connect + * to secondary carrier. + * + * @param serial Serial number of request. + * @param nrDualConnectivityState expected NR dual connectivity state. + * 1: Enable NR dual connectivity {NrDualConnectivityState:ENABLE} + * 2: Disable NR dual connectivity {NrDualConnectivityState:DISABLE} + * 3: Disable NR dual connectivity and force secondary cell to be released + * {NrDualConnectivityState:DISABLE_IMMEDIATE} + * + * Response function is IRadioNetworkResponse.setNrDualConnectivityStateResponse() + */ + void setNrDualConnectivityState( + in int serial, in NrDualConnectivityState nrDualConnectivityState); + + /** + * Set response functions for network radio requests and indications. + * + * @param radioNetworkResponse Object containing response functions + * @param radioNetworkIndication Object containing radio indications + */ + void setResponseFunctions(in IRadioNetworkResponse radioNetworkResponse, + in IRadioNetworkIndication radioNetworkIndication); + + /** + * Sets the signal strength reporting criteria. The resulting reporting rules are the AND of all + * the supplied criteria. For each RAN the hysteresisDb and thresholds apply to only the + * following measured quantities: + * -GERAN - RSSI + * -CDMA2000 - RSSI + * -UTRAN - RSCP + * -EUTRAN - RSRP/RSRQ/RSSNR + * -NGRAN - SSRSRP/SSRSRQ/SSSINR + * Note that reporting criteria must be individually set for each RAN. For each RAN, if none of + * reporting criteria of any measurement is set enabled (see SignalThresholdInfo.isEnabled), + * the reporting criteria for this RAN is implementation-defined. For each RAN, if any reporting + * criteria of any measure is set enabled, the reporting criteria of the other measures in this + * RAN are set disabled (see SignalThresholdInfo.isEnabled) until they are set enabled. + * + * @param serial Serial number of request. + * @param signalThresholdInfo Signal threshold info including the threshold values, + * hysteresisDb, hysteresisMs and isEnabled. See SignalThresholdInfo for details. + * @param accessNetwork The type of network for which to apply these thresholds. + * + * Response function is IRadioNetworkResponse.setSignalStrengthReportingCriteriaResponse() + */ + void setSignalStrengthReportingCriteria(in int serial, + in SignalThresholdInfo signalThresholdInfo, in AccessNetwork accessNetwork); + + /** + * Enables/disables supplementary service related notifications from the network. + * Notifications are reported via unsolSuppSvcNotification(). + * + * @param serial Serial number of request. + * @param enable true = notifications enabled, false = notifications disabled. + * + * Response function is IRadioNetworkResponse.setSuppServiceNotificationsResponse() + */ + void setSuppServiceNotifications(in int serial, in boolean enable); + + /** + * Specify which bands modem's background scan must act on. If specifyChannels is true, it only + * scans bands specified in specifiers. If specifyChannels is false, it scans all bands. For + * example, CBRS is only on LTE band 48. By specifying this band, modem saves more power. + * + * @param serial Serial number of request. + * @param specifyChannels whether to scan bands defined in specifiers. + * @param specifiers which bands to scan. Only used if specifyChannels is true. + * + * Response function is IRadioNetworkResponse.setSystemSelectionChannelsResponse() + */ + void setSystemSelectionChannels( + in int serial, in boolean specifyChannels, in RadioAccessSpecifier[] specifiers); + + /** + * Starts a network scan. + * + * @param serial Serial number of request. + * @param request Defines the radio networks/bands/channels which need to be scanned. + * + * Response function is IRadioNetworkResponse.startNetworkScanResponse() + */ + void startNetworkScan(in int serial, in NetworkScanRequest request); + + /** + * Stops ongoing network scan + * + * @param serial Serial number of request. + * + * Response function is IRadioNetworkResponse.stopNetworkScanResponse() + */ + void stopNetworkScan(in int serial); + + /** + * Requests that network personalization be deactivated + * + * @param serial Serial number of request. + * @param netPin Network depersonlization code + * + * Response function is IRadioNetworkResponse.supplyNetworkDepersonalizationResponse() + */ + void supplyNetworkDepersonalization(in int serial, in String netPin); +} diff --git a/radio/aidl/android/hardware/radio/network/IRadioNetworkIndication.aidl b/radio/aidl/android/hardware/radio/network/IRadioNetworkIndication.aidl new file mode 100644 index 0000000000..a2fac202c5 --- /dev/null +++ b/radio/aidl/android/hardware/radio/network/IRadioNetworkIndication.aidl @@ -0,0 +1,188 @@ +/* + * 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.radio.network; + +import android.hardware.radio.RadioIndicationType; +import android.hardware.radio.RadioTechnology; +import android.hardware.radio.network.BarringInfo; +import android.hardware.radio.network.CellIdentity; +import android.hardware.radio.network.CellInfo; +import android.hardware.radio.network.Domain; +import android.hardware.radio.network.LinkCapacityEstimate; +import android.hardware.radio.network.NetworkScanResult; +import android.hardware.radio.network.PhoneRestrictedState; +import android.hardware.radio.network.PhysicalChannelConfig; +import android.hardware.radio.network.SignalStrength; +import android.hardware.radio.network.SuppSvcNotification; + +/** + * Interface declaring unsolicited radio indications for network APIs. + */ +@VintfStability +oneway interface IRadioNetworkIndication { + /** + * Indicate barring information for the user’s access category / access class and PLMN. + * + *

    Provide information about the barring status of the cell for the user. The information + * provided should describe all barring configurations that are applicable to the current user, + * even if the user is not currently barred (due to conditional barring). This informs Android + * of likely future (statistical) barring for specific services. + * + *

    This indication should be sent whenever the cell’s barring config changes for the current + * user, or if the user’s conditional barring status changes due to re-evaluation of the + * barring conditions. Barring status will likely change when the device camps for service, + * when PLMN selection is completed, when the device attempts to access a conditionally barred + * service, and when the System Information including barring info for a camped cell is updated. + * + * @param type Type of radio indication + * @param cellIdentity cellIdentity for the barring infos + * @param barringInfos a vector of BarringInfos for all barring service types + */ + void barringInfoChanged(in RadioIndicationType type, in CellIdentity cellIdentity, + in BarringInfo[] barringInfos); + + /** + * Indicates when PRL (preferred roaming list) changes. + * + * @param type Type of radio indication + * @param version PRL version after PRL changes + */ + void cdmaPrlChanged(in RadioIndicationType type, in int version); + + /** + * Report all of the current cell information known to the radio. + * + * @param type Type of radio indication + * @param records Current cell information + */ + void cellInfoList(in RadioIndicationType type, in CellInfo[] records); + + /** + * Indicates current link capacity estimate. This indication is sent whenever the reporting + * criteria, as set by IRadioNetwork.setLinkCapacityReportingCriteria(), are met and the + * indication is not suppressed by IRadioNetwork.setIndicationFilter(). + * + * @param type Type of radio indication + * @param lce LinkCapacityEstimate + */ + void currentLinkCapacityEstimate(in RadioIndicationType type, in LinkCapacityEstimate lce); + + /** + * Indicates physical channel configurations. An empty configs list shall be returned when the + * radio is in idle mode (i.e. RRC idle). + * + * @param type Type of radio indication + * @param configs Vector of PhysicalChannelConfigs + */ + void currentPhysicalChannelConfigs( + in RadioIndicationType type, in PhysicalChannelConfig[] configs); + + /** + * Indicates current signal strength of the radio. + * + * @param type Type of radio indication + * @param signalStrength SignalStrength information + */ + void currentSignalStrength(in RadioIndicationType type, in SignalStrength signalStrength); + + /** + * Indicates when IMS registration state has changed. To get IMS registration state and IMS SMS + * format, callee needs to invoke getImsRegistrationState(). + * + * @param type Type of radio indication + */ + void imsNetworkStateChanged(in RadioIndicationType type); + + /** + * Incremental network scan results. + * + * @param type Type of radio indication + * @param result the result of the network scan + */ + void networkScanResult(in RadioIndicationType type, in NetworkScanResult result); + + /** + * Indicates when voice or data network state changed. Callee must invoke + * IRadioNetwork.getVoiceRegistrationState(), IRadioNetwork.getDataRegistrationState(), and + * IRadioNetwork.getOperator() + * + * @param type Type of radio indication + */ + void networkStateChanged(in RadioIndicationType type); + + /** + * Indicates when radio has received a NITZ time message. + * + * @param type Type of radio indication + * @param nitzTime NITZ time string in the form "yy/mm/dd,hh:mm:ss(+/-)tz,dt" + * @param receivedTime milliseconds since boot that the NITZ time was received + */ + void nitzTimeReceived(in RadioIndicationType type, in String nitzTime, in long receivedTime); + + /** + * Report that Registration or a Location/Routing/Tracking Area update has failed. + * + *

    Indicate whenever a registration procedure, including a location, routing, or tracking + * area update fails. This includes procedures that do not necessarily result in a change of + * the modem's registration status. If the modem's registration status changes, that is + * reflected in the onNetworkStateChanged() and subsequent get{Voice/Data}RegistrationState(). + * + * @param cellIdentity the CellIdentity, which must include the globally unique identifier for + * the cell (for example, all components of the CGI or ECGI). + * @param chosenPlmn a 5 or 6 digit alphanumeric PLMN (MCC|MNC) among those broadcast by the + * cell that was chosen for the failed registration attempt. + * @param domain Domain::CS, Domain::PS, or both in case of a combined procedure. + * @param causeCode the primary failure cause code of the procedure. + * For GSM/UMTS (MM), values are in TS 24.008 Sec 10.5.95 + * For GSM/UMTS (GMM), values are in TS 24.008 Sec 10.5.147 + * For LTE (EMM), cause codes are TS 24.301 Sec 9.9.3.9 + * For NR (5GMM), cause codes are TS 24.501 Sec 9.11.3.2 + * MAX_INT if this value is unused. + * @param additionalCauseCode the cause code of any secondary/combined procedure if appropriate. + * For UMTS, if a combined attach succeeds for PS only, then the GMM cause code shall be + * included as an additionalCauseCode. + * For LTE (ESM), cause codes are in TS 24.301 9.9.4.4 + * MAX_INT if this value is unused. + */ + void registrationFailed(in RadioIndicationType type, in CellIdentity cellIdentity, + in String chosenPlmn, in Domain domain, in int causeCode, in int additionalCauseCode); + + /** + * Indicates a restricted state change (eg, for Domain Specific Access Control). + * Radio must send this msg after radio off/on cycle no matter it is changed or not. + * + * @param type Type of radio indication + * @param state Bitmask of restricted state as defined by PhoneRestrictedState + */ + void restrictedStateChanged(in RadioIndicationType type, in PhoneRestrictedState state); + + /** + * Reports supplementary service related notification from the network. + * + * @param type Type of radio indication + * @param suppSvc SuppSvcNotification + */ + void suppSvcNotify(in RadioIndicationType type, in SuppSvcNotification suppSvc); + + /** + * Indicates that voice technology has changed. Responds with new rat. + * + * @param type Type of radio indication + * @param rat Current new voice rat + */ + void voiceRadioTechChanged(in RadioIndicationType type, in RadioTechnology rat); +} diff --git a/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl b/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl new file mode 100644 index 0000000000..ae2646dd9f --- /dev/null +++ b/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl @@ -0,0 +1,588 @@ +/* + * 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.radio.network; + +import android.hardware.radio.RadioAccessFamily; +import android.hardware.radio.RadioResponseInfo; +import android.hardware.radio.RadioTechnology; +import android.hardware.radio.RadioTechnologyFamily; +import android.hardware.radio.network.BarringInfo; +import android.hardware.radio.network.CdmaRoamingType; +import android.hardware.radio.network.CellIdentity; +import android.hardware.radio.network.CellInfo; +import android.hardware.radio.network.LceDataInfo; +import android.hardware.radio.network.NeighboringCell; +import android.hardware.radio.network.OperatorInfo; +import android.hardware.radio.network.RadioAccessSpecifier; +import android.hardware.radio.network.RadioBandMode; +import android.hardware.radio.network.RegStateResult; +import android.hardware.radio.network.SignalStrength; + +/** + * Interface declaring response functions to solicited radio requests for network APIs. + */ +@VintfStability +oneway interface IRadioNetworkResponse { + /** + * Acknowledge the receipt of radio request sent to the vendor. This must be sent only for + * radio request which take long time to respond. For more details, refer + * https://source.android.com/devices/tech/connect/ril.html + * + * @param serial Serial no. of the request whose acknowledgement is sent. + */ + void acknowledgeRequest(in int serial); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param networkTypeBitmap a 32-bit bitmap of RadioAccessFamily. + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:MODE_NOT_SUPPORTED + * RadioError:INTERNAL_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:MODEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + */ + void getAllowedNetworkTypesBitmapResponse( + in RadioResponseInfo info, in RadioAccessFamily networkTypeBitmap); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param bandModes List of RadioBandMode listing supported modes + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + void getAvailableBandModesResponse(in RadioResponseInfo info, in RadioBandMode[] bandModes); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param networkInfos List of network operator information as OperatorInfos + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:ABORTED + * RadioError:DEVICE_IN_USE + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:MODEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:CANCELLED + * RadioError:NO_RESOURCES + * RadioError:INTERNAL_ERR + */ + void getAvailableNetworksResponse(in RadioResponseInfo info, in OperatorInfo[] networkInfos); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param cellIdentity CellIdentity for the barring infos. + * @param barringInfos a vector of barring info for all barring service types + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:MODEM_ERR + */ + void getBarringInfoResponse( + in RadioResponseInfo info, in CellIdentity cellIdentity, in BarringInfo[] barringInfos); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param type CdmaRoamingType + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:SIM_ABSENT + */ + void getCdmaRoamingPreferenceResponse(in RadioResponseInfo info, in CdmaRoamingType type); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param cellInfo List of current cell information known to radio + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + */ + void getCellInfoListResponse(in RadioResponseInfo info, in CellInfo[] cellInfo); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param dataRegResponse Current data registration response as defined by RegStateResult + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:NOT_PROVISIONED + */ + void getDataRegistrationStateResponse( + in RadioResponseInfo info, in RegStateResult dataRegResponse); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param isRegistered false = not registered, true = registered + * @param ratFamily RadioTechnologyFamily. This value is valid only if isRegistered is true. + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:INVALID_MODEM_STATE + * RadioError:REQUEST_NOT_SUPPORTED + */ + void getImsRegistrationStateResponse( + in RadioResponseInfo info, in boolean isRegistered, in RadioTechnologyFamily ratFamily); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param cells Vector of neighboring radio cell + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:NO_NETWORK_FOUND + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + void getNeighboringCidsResponse(in RadioResponseInfo info, in NeighboringCell[] cells); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param selection false for automatic selection, true for manual selection + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:MODEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + void getNetworkSelectionModeResponse(in RadioResponseInfo info, in boolean manual); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param longName is long alpha ONS or EONS or empty string if unregistered + * @param shortName is short alpha ONS or EONS or empty string if unregistered + * @param numeric is 5 or 6 digit numeric code (MCC + MNC) or empty string if unregistered + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + void getOperatorResponse( + in RadioResponseInfo info, in String longName, in String shortName, in String numeric); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param signalStrength Current signal strength + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + */ + void getSignalStrengthResponse(in RadioResponseInfo info, in SignalStrength signalStrength); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param specifiers List of RadioAccessSpecifiers that are scanned. + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:INVALID_ARGUMENTS + */ + void getSystemSelectionChannelsResponse( + in RadioResponseInfo info, in RadioAccessSpecifier[] specifiers); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param rat Current voice RAT + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:REQUEST_NOT_SUPPORTED + */ + void getVoiceRadioTechnologyResponse(in RadioResponseInfo info, in RadioTechnology rat); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param voiceRegResponse Current Voice registration response as defined by RegStateResult + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + */ + void getVoiceRegistrationStateResponse( + in RadioResponseInfo info, in RegStateResult voiceRegResponse); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param isEnabled Indicates whether NR dual connectivity is enabled or not, True if enabled + * else false. + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:REQUEST_NOT_SUPPORTED + */ + void isNrDualConnectivityEnabledResponse(in RadioResponseInfo info, in boolean isEnabled); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param lceInfo LceDataInfo indicating LCE data + * + * Valid errors returned: + * RadioError:REQUEST_NOT_SUPPORTED may be returned when HAL 1.2 or higher is supported. + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:LCE_NOT_SUPPORTED + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:SIM_ABSENT + */ + void pullLceDataResponse(in RadioResponseInfo info, in LceDataInfo lceInfo); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:MODE_NOT_SUPPORTED + * RadioError:INTERNAL_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:MODEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + */ + void setAllowedNetworkTypesBitmapResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:MODEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + void setBandModeResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SS_MODIFIED_TO_DIAL + * RadioError:SS_MODIFIED_TO_USSD + * RadioError:SS_MODIFIED_TO_SS + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_MEMORY + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:FDN_CHECK_FAILURE + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + void setBarringPasswordResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:MODEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:SIM_ABSENT + */ + void setCdmaRoamingPreferenceResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:REQUEST_NOT_SUPPORTED + */ + void setCellInfoListRateResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:INVALID_ARGUMENTS + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + */ + void setIndicationFilterResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:INVALID_ARGUMENTS + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + */ + void setLinkCapacityReportingCriteriaResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:MODEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:SIM_ABSENT + */ + void setLocationUpdatesResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:ILLEGAL_SIM_OR_ME + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:MODEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * + * Returns RadioError:ILLEGAL_SIM_OR_ME when the failure is permanent and + * no retries needed, such as illegal SIM or ME. + */ + void setNetworkSelectionModeAutomaticResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:ILLEGAL_SIM_OR_ME + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:INVALID_STATE + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:MODEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * + * Returns RadioError:ILLEGAL_SIM_OR_ME when the failure is permanent and + * no retries needed, such as illegal SIM or ME. + */ + void setNetworkSelectionModeManualResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_STATE + */ + void setNrDualConnectivityStateResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:INVALID_ARGUMENTS + * RadioError:RADIO_NOT_AVAILABLE + */ + void setSignalStrengthReportingCriteriaResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:SIM_BUSY + * RadioError:NO_MEMORY + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:SIM_ABSENT + */ + void setSuppServiceNotificationsResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:INVALID_ARGUMENTS + */ + void setSystemSelectionChannelsResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:DEVICE_IN_USE + * RadioError:INTERNAL_ERR + * RadioError:MODEM_ERR + * RadioError:INVALID_ARGUMENTS + */ + void startNetworkScanResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:INTERNAL_ERR + * RadioError:MODEM_ERR + */ + void stopNetworkScanResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param remainingRetries Number of retries remaining, must be equal to -1 if unknown. + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:PASSWORD_INCORRECT (code is invalid) + * RadioError:NO_MEMORY + * RadioError:INVALID_SIM_STATE + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:SIM_ABSENT + */ + void supplyNetworkDepersonalizationResponse(in RadioResponseInfo info, in int remainingRetries); +} diff --git a/radio/aidl/android/hardware/radio/IndicationFilter.aidl b/radio/aidl/android/hardware/radio/network/IndicationFilter.aidl similarity index 52% rename from radio/aidl/android/hardware/radio/IndicationFilter.aidl rename to radio/aidl/android/hardware/radio/network/IndicationFilter.aidl index 826c8c1c57..ac482277c0 100644 --- a/radio/aidl/android/hardware/radio/IndicationFilter.aidl +++ b/radio/aidl/android/hardware/radio/network/IndicationFilter.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; @VintfStability @Backing(type="int") @@ -23,39 +23,39 @@ enum IndicationFilter { ALL = ~0, /** * When this bit is set, modem must send the signal strength update through - * IRadioIndication.currentSignalStrength() when all criteria specified by - * IRadio.setSignalStrengthReportingCriteria() are met. + * IRadioNetworkIndication.currentSignalStrength() when all criteria specified by + * IRadioNetwork.setSignalStrengthReportingCriteria() are met. */ SIGNAL_STRENGTH = 1 << 0, /** - * When this bit is set, modem must invoke IRadioIndication.networkStateChanged() when any field - * in VoiceRegStateResult or DataRegStateResult changes. When this bit is not set, modem must - * suppress IRadioIndication.networkStateChanged() when there are only changes from - * insignificant fields. Modem must invoke IRadioIndication.networkStateChanged() when + * When this bit is set, modem must invoke IRadioNetworkIndication.networkStateChanged() when + * any field in the voice or data RegStateResult changes. When this bit is not set, modem must + * suppress IRadioNetworkIndication.networkStateChanged() when there are only changes from + * insignificant fields. Modem must invoke IRadioNetworkIndication.networkStateChanged() when * significant fields are updated regardless of whether this bit is set. * - * The following fields are considered significant: VoiceRegStateResult.regState, - * VoiceRegStateResult.rat, DataRegStateResult.regState, DataRegStateResult.rat. + * The following fields in RegStateResult are considered significant: regState, rat. */ FULL_NETWORK_STATE = 1 << 1, /** - * When this bit is set, modem must send IRadioIndication.dataCallListChanged() whenever any - * field in ITypes.SetupDataCallResult changes. When this bit is not set, modem must suppress - * the indication when the only changed field is 'active' (for data dormancy). For all other - * field changes, the modem must send IRadioIndication.dataCallListChanged() regardless of + * When this bit is set, modem must send IRadioNetworkIndication.dataCallListChanged() whenever + * any field in SetupDataCallResult changes. When this bit is not set, modem must suppress the + * indication when the only changed field is 'active' (for data dormancy). For all other field + * changes, the modem must send IRadioNetworkIndication.dataCallListChanged() regardless of * whether this bit is set. */ DATA_CALL_DORMANCY_CHANGED = 1 << 2, /** * When this bit is set, modem must send the link capacity update through - * IRadioIndication.currentLinkCapacityEstimate() when all criteria specified by - * IRadio.setLinkCapacityReportingCriteria() are met. + * IRadioNetworkIndication.currentLinkCapacityEstimate() when all criteria specified by + * IRadioNetwork.setLinkCapacityReportingCriteria() are met. */ LINK_CAPACITY_ESTIMATE = 1 << 3, /** * When this bit is set, the modem must send the physical channel configuration update through - * IRadioIndication.currentPhysicalChannelConfigs() when the configuration has changed. It is - * recommended that this be reported whenever link capacity or signal strength is reported. + * IRadioNetworkIndication.currentPhysicalChannelConfigs() when the configuration has changed. + * It is recommended that this be reported whenever link capacity or signal strength is + * reported. */ PHYSICAL_CHANNEL_CONFIG = 1 << 4, /** diff --git a/radio/aidl/android/hardware/radio/LceDataInfo.aidl b/radio/aidl/android/hardware/radio/network/LceDataInfo.aidl similarity index 96% rename from radio/aidl/android/hardware/radio/LceDataInfo.aidl rename to radio/aidl/android/hardware/radio/network/LceDataInfo.aidl index 68521b559b..344227e570 100644 --- a/radio/aidl/android/hardware/radio/LceDataInfo.aidl +++ b/radio/aidl/android/hardware/radio/network/LceDataInfo.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; @VintfStability parcelable LceDataInfo { diff --git a/radio/aidl/android/hardware/radio/LinkCapacityEstimate.aidl b/radio/aidl/android/hardware/radio/network/LinkCapacityEstimate.aidl similarity index 98% rename from radio/aidl/android/hardware/radio/LinkCapacityEstimate.aidl rename to radio/aidl/android/hardware/radio/network/LinkCapacityEstimate.aidl index 78ddee2f8f..8d31bbc240 100644 --- a/radio/aidl/android/hardware/radio/LinkCapacityEstimate.aidl +++ b/radio/aidl/android/hardware/radio/network/LinkCapacityEstimate.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; @VintfStability parcelable LinkCapacityEstimate { diff --git a/radio/aidl/android/hardware/radio/LteSignalStrength.aidl b/radio/aidl/android/hardware/radio/network/LteSignalStrength.aidl similarity index 98% rename from radio/aidl/android/hardware/radio/LteSignalStrength.aidl rename to radio/aidl/android/hardware/radio/network/LteSignalStrength.aidl index 699925d419..a727aa5658 100644 --- a/radio/aidl/android/hardware/radio/LteSignalStrength.aidl +++ b/radio/aidl/android/hardware/radio/network/LteSignalStrength.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; @VintfStability parcelable LteSignalStrength { diff --git a/radio/aidl/android/hardware/radio/LteVopsInfo.aidl b/radio/aidl/android/hardware/radio/network/LteVopsInfo.aidl similarity index 97% rename from radio/aidl/android/hardware/radio/LteVopsInfo.aidl rename to radio/aidl/android/hardware/radio/network/LteVopsInfo.aidl index b487a8f20d..1cda8db0d3 100644 --- a/radio/aidl/android/hardware/radio/LteVopsInfo.aidl +++ b/radio/aidl/android/hardware/radio/network/LteVopsInfo.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; /** * Type to define the LTE specific network capabilities for voice over PS including emergency and diff --git a/radio/aidl/android/hardware/radio/NeighboringCell.aidl b/radio/aidl/android/hardware/radio/network/NeighboringCell.aidl similarity index 95% rename from radio/aidl/android/hardware/radio/NeighboringCell.aidl rename to radio/aidl/android/hardware/radio/network/NeighboringCell.aidl index b48a2d4e51..270bdee021 100644 --- a/radio/aidl/android/hardware/radio/NeighboringCell.aidl +++ b/radio/aidl/android/hardware/radio/network/NeighboringCell.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; @VintfStability parcelable NeighboringCell { diff --git a/radio/aidl/android/hardware/radio/NetworkScanRequest.aidl b/radio/aidl/android/hardware/radio/network/NetworkScanRequest.aidl similarity index 96% rename from radio/aidl/android/hardware/radio/NetworkScanRequest.aidl rename to radio/aidl/android/hardware/radio/network/NetworkScanRequest.aidl index d495a9de58..ec8aa9511c 100644 --- a/radio/aidl/android/hardware/radio/NetworkScanRequest.aidl +++ b/radio/aidl/android/hardware/radio/network/NetworkScanRequest.aidl @@ -14,9 +14,9 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; -import android.hardware.radio.RadioAccessSpecifier; +import android.hardware.radio.network.RadioAccessSpecifier; @VintfStability parcelable NetworkScanRequest { diff --git a/radio/aidl/android/hardware/radio/NetworkScanResult.aidl b/radio/aidl/android/hardware/radio/network/NetworkScanResult.aidl similarity index 93% rename from radio/aidl/android/hardware/radio/NetworkScanResult.aidl rename to radio/aidl/android/hardware/radio/network/NetworkScanResult.aidl index dd71d11627..e08d63e312 100644 --- a/radio/aidl/android/hardware/radio/NetworkScanResult.aidl +++ b/radio/aidl/android/hardware/radio/network/NetworkScanResult.aidl @@ -14,10 +14,10 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; -import android.hardware.radio.CellInfo; import android.hardware.radio.RadioError; +import android.hardware.radio.network.CellInfo; @VintfStability parcelable NetworkScanResult { diff --git a/radio/aidl/android/hardware/radio/NgranBands.aidl b/radio/aidl/android/hardware/radio/network/NgranBands.aidl similarity index 97% rename from radio/aidl/android/hardware/radio/NgranBands.aidl rename to radio/aidl/android/hardware/radio/network/NgranBands.aidl index 7887011c77..a1c2957c5d 100644 --- a/radio/aidl/android/hardware/radio/NgranBands.aidl +++ b/radio/aidl/android/hardware/radio/network/NgranBands.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; /** * NGRAN bands up to V16.5.0 diff --git a/radio/aidl/android/hardware/radio/NrDualConnectivityState.aidl b/radio/aidl/android/hardware/radio/network/NrDualConnectivityState.aidl similarity index 97% rename from radio/aidl/android/hardware/radio/NrDualConnectivityState.aidl rename to radio/aidl/android/hardware/radio/network/NrDualConnectivityState.aidl index 52bd048469..e40d4f92b1 100644 --- a/radio/aidl/android/hardware/radio/NrDualConnectivityState.aidl +++ b/radio/aidl/android/hardware/radio/network/NrDualConnectivityState.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; /** * NR Dual connectivity state diff --git a/radio/aidl/android/hardware/radio/NrIndicators.aidl b/radio/aidl/android/hardware/radio/network/NrIndicators.aidl similarity index 97% rename from radio/aidl/android/hardware/radio/NrIndicators.aidl rename to radio/aidl/android/hardware/radio/network/NrIndicators.aidl index 2a1dfece78..98fac25747 100644 --- a/radio/aidl/android/hardware/radio/NrIndicators.aidl +++ b/radio/aidl/android/hardware/radio/network/NrIndicators.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; /** * The parameters of NR 5G Non-Standalone. diff --git a/radio/aidl/android/hardware/radio/NrSignalStrength.aidl b/radio/aidl/android/hardware/radio/network/NrSignalStrength.aidl similarity index 98% rename from radio/aidl/android/hardware/radio/NrSignalStrength.aidl rename to radio/aidl/android/hardware/radio/network/NrSignalStrength.aidl index 40c6c3ebe0..d2ac02bdfa 100644 --- a/radio/aidl/android/hardware/radio/NrSignalStrength.aidl +++ b/radio/aidl/android/hardware/radio/network/NrSignalStrength.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; @VintfStability parcelable NrSignalStrength { diff --git a/radio/aidl/android/hardware/radio/NrVopsInfo.aidl b/radio/aidl/android/hardware/radio/network/NrVopsInfo.aidl similarity index 98% rename from radio/aidl/android/hardware/radio/NrVopsInfo.aidl rename to radio/aidl/android/hardware/radio/network/NrVopsInfo.aidl index 0d01aaba3f..bae5f40c25 100644 --- a/radio/aidl/android/hardware/radio/NrVopsInfo.aidl +++ b/radio/aidl/android/hardware/radio/network/NrVopsInfo.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; /** * Type to define the NR specific network capabilities for voice over PS including emergency and @@ -74,7 +74,7 @@ parcelable NrVopsInfo { * it supports. This information is received from NR network during NR NAS registration * procedure through NR REGISTRATION ACCEPT. * Refer 3GPP 24.501 EPS 5GS network feature support -> IMS VoPS - * Values are VOPS_INDICATOR + * Values are VOPS_INDICATOR_ */ byte vopsSupported; /** diff --git a/radio/aidl/android/hardware/radio/OperatorInfo.aidl b/radio/aidl/android/hardware/radio/network/OperatorInfo.aidl similarity index 96% rename from radio/aidl/android/hardware/radio/OperatorInfo.aidl rename to radio/aidl/android/hardware/radio/network/OperatorInfo.aidl index e0234fca8a..9fa126d399 100644 --- a/radio/aidl/android/hardware/radio/OperatorInfo.aidl +++ b/radio/aidl/android/hardware/radio/network/OperatorInfo.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; @VintfStability parcelable OperatorInfo { diff --git a/radio/aidl/android/hardware/radio/PhoneRestrictedState.aidl b/radio/aidl/android/hardware/radio/network/PhoneRestrictedState.aidl similarity index 96% rename from radio/aidl/android/hardware/radio/PhoneRestrictedState.aidl rename to radio/aidl/android/hardware/radio/network/PhoneRestrictedState.aidl index 5f5f1b8a39..bf3f75a989 100644 --- a/radio/aidl/android/hardware/radio/PhoneRestrictedState.aidl +++ b/radio/aidl/android/hardware/radio/network/PhoneRestrictedState.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; @VintfStability @Backing(type="int") diff --git a/radio/aidl/android/hardware/radio/PhysicalChannelConfig.aidl b/radio/aidl/android/hardware/radio/network/PhysicalChannelConfig.aidl similarity index 92% rename from radio/aidl/android/hardware/radio/PhysicalChannelConfig.aidl rename to radio/aidl/android/hardware/radio/network/PhysicalChannelConfig.aidl index 05b31e5dbf..b6072ba400 100644 --- a/radio/aidl/android/hardware/radio/PhysicalChannelConfig.aidl +++ b/radio/aidl/android/hardware/radio/network/PhysicalChannelConfig.aidl @@ -14,11 +14,11 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; -import android.hardware.radio.CellConnectionStatus; -import android.hardware.radio.PhysicalChannelConfigBand; import android.hardware.radio.RadioTechnology; +import android.hardware.radio.network.CellConnectionStatus; +import android.hardware.radio.network.PhysicalChannelConfigBand; @VintfStability parcelable PhysicalChannelConfig { diff --git a/radio/aidl/android/hardware/radio/PhysicalChannelConfigBand.aidl b/radio/aidl/android/hardware/radio/network/PhysicalChannelConfigBand.aidl similarity index 81% rename from radio/aidl/android/hardware/radio/PhysicalChannelConfigBand.aidl rename to radio/aidl/android/hardware/radio/network/PhysicalChannelConfigBand.aidl index 953b1c4b28..f5b248e2fd 100644 --- a/radio/aidl/android/hardware/radio/PhysicalChannelConfigBand.aidl +++ b/radio/aidl/android/hardware/radio/network/PhysicalChannelConfigBand.aidl @@ -14,12 +14,12 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; -import android.hardware.radio.EutranBands; -import android.hardware.radio.GeranBands; -import android.hardware.radio.NgranBands; -import android.hardware.radio.UtranBands; +import android.hardware.radio.network.EutranBands; +import android.hardware.radio.network.GeranBands; +import android.hardware.radio.network.NgranBands; +import android.hardware.radio.network.UtranBands; @VintfStability union PhysicalChannelConfigBand { diff --git a/radio/aidl/android/hardware/radio/RadioAccessSpecifier.aidl b/radio/aidl/android/hardware/radio/network/RadioAccessSpecifier.aidl similarity index 84% rename from radio/aidl/android/hardware/radio/RadioAccessSpecifier.aidl rename to radio/aidl/android/hardware/radio/network/RadioAccessSpecifier.aidl index 889124a728..dcc9d53572 100644 --- a/radio/aidl/android/hardware/radio/RadioAccessSpecifier.aidl +++ b/radio/aidl/android/hardware/radio/network/RadioAccessSpecifier.aidl @@ -14,17 +14,17 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; -import android.hardware.radio.RadioAccessNetworks; -import android.hardware.radio.RadioAccessSpecifierBands; +import android.hardware.radio.AccessNetwork; +import android.hardware.radio.network.RadioAccessSpecifierBands; @VintfStability parcelable RadioAccessSpecifier { /** * The type of network to scan. */ - RadioAccessNetworks radioAccessNetwork; + AccessNetwork accessNetwork; /** * The frequency bands to scan. Maximum length of the vector is 8. */ diff --git a/radio/aidl/android/hardware/radio/RadioAccessSpecifierBands.aidl b/radio/aidl/android/hardware/radio/network/RadioAccessSpecifierBands.aidl similarity index 81% rename from radio/aidl/android/hardware/radio/RadioAccessSpecifierBands.aidl rename to radio/aidl/android/hardware/radio/network/RadioAccessSpecifierBands.aidl index dde46262dc..c72d8c947b 100644 --- a/radio/aidl/android/hardware/radio/RadioAccessSpecifierBands.aidl +++ b/radio/aidl/android/hardware/radio/network/RadioAccessSpecifierBands.aidl @@ -14,12 +14,12 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; -import android.hardware.radio.EutranBands; -import android.hardware.radio.GeranBands; -import android.hardware.radio.NgranBands; -import android.hardware.radio.UtranBands; +import android.hardware.radio.network.EutranBands; +import android.hardware.radio.network.GeranBands; +import android.hardware.radio.network.NgranBands; +import android.hardware.radio.network.UtranBands; @VintfStability union RadioAccessSpecifierBands { diff --git a/radio/aidl/android/hardware/radio/RadioBandMode.aidl b/radio/aidl/android/hardware/radio/network/RadioBandMode.aidl similarity index 98% rename from radio/aidl/android/hardware/radio/RadioBandMode.aidl rename to radio/aidl/android/hardware/radio/network/RadioBandMode.aidl index e6064c4dad..4fdc614f8c 100644 --- a/radio/aidl/android/hardware/radio/RadioBandMode.aidl +++ b/radio/aidl/android/hardware/radio/network/RadioBandMode.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; @VintfStability @Backing(type="int") diff --git a/radio/aidl/android/hardware/radio/RegState.aidl b/radio/aidl/android/hardware/radio/network/RegState.aidl similarity index 98% rename from radio/aidl/android/hardware/radio/RegState.aidl rename to radio/aidl/android/hardware/radio/network/RegState.aidl index 91fd239868..bb2c3c30e7 100644 --- a/radio/aidl/android/hardware/radio/RegState.aidl +++ b/radio/aidl/android/hardware/radio/network/RegState.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; /** * Please note that registration state UNKNOWN is treated as "out of service" in Android telephony. diff --git a/radio/aidl/android/hardware/radio/RegStateResult.aidl b/radio/aidl/android/hardware/radio/network/RegStateResult.aidl similarity index 86% rename from radio/aidl/android/hardware/radio/RegStateResult.aidl rename to radio/aidl/android/hardware/radio/network/RegStateResult.aidl index 615392c011..bd681e7e7d 100644 --- a/radio/aidl/android/hardware/radio/RegStateResult.aidl +++ b/radio/aidl/android/hardware/radio/network/RegStateResult.aidl @@ -14,13 +14,13 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; -import android.hardware.radio.AccessTechnologySpecificInfo; -import android.hardware.radio.CellIdentity; import android.hardware.radio.RadioTechnology; -import android.hardware.radio.RegState; -import android.hardware.radio.RegistrationFailCause; +import android.hardware.radio.network.AccessTechnologySpecificInfo; +import android.hardware.radio.network.CellIdentity; +import android.hardware.radio.network.RegState; +import android.hardware.radio.network.RegistrationFailCause; @VintfStability parcelable RegStateResult { @@ -35,7 +35,7 @@ parcelable RegStateResult { * Indicates the available voice radio technology, valid values as defined by RadioTechnology, * except LTE_CA, which is no longer a valid value on 1.5 or above. When the device is on * carrier aggregation, vendor RIL service should properly report multiple PhysicalChannelConfig - * elements through IRadio::currentPhysicalChannelConfigs. + * elements through IRadioNetwork::currentPhysicalChannelConfigs. */ RadioTechnology rat; /** diff --git a/radio/aidl/android/hardware/radio/RegistrationFailCause.aidl b/radio/aidl/android/hardware/radio/network/RegistrationFailCause.aidl similarity index 99% rename from radio/aidl/android/hardware/radio/RegistrationFailCause.aidl rename to radio/aidl/android/hardware/radio/network/RegistrationFailCause.aidl index d9c7f23a3a..586436efb6 100644 --- a/radio/aidl/android/hardware/radio/RegistrationFailCause.aidl +++ b/radio/aidl/android/hardware/radio/network/RegistrationFailCause.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; /** * Call fail causes for Circuit-switched service enumerated in 3GPP TS 24.008, 10.5.3.6 and diff --git a/radio/aidl/android/hardware/radio/SignalStrength.aidl b/radio/aidl/android/hardware/radio/network/SignalStrength.aidl similarity index 82% rename from radio/aidl/android/hardware/radio/SignalStrength.aidl rename to radio/aidl/android/hardware/radio/network/SignalStrength.aidl index 0ffdaa34cc..5a18b18280 100644 --- a/radio/aidl/android/hardware/radio/SignalStrength.aidl +++ b/radio/aidl/android/hardware/radio/network/SignalStrength.aidl @@ -14,15 +14,15 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; -import android.hardware.radio.CdmaSignalStrength; -import android.hardware.radio.EvdoSignalStrength; -import android.hardware.radio.GsmSignalStrength; -import android.hardware.radio.LteSignalStrength; -import android.hardware.radio.NrSignalStrength; -import android.hardware.radio.TdscdmaSignalStrength; -import android.hardware.radio.WcdmaSignalStrength; +import android.hardware.radio.network.CdmaSignalStrength; +import android.hardware.radio.network.EvdoSignalStrength; +import android.hardware.radio.network.GsmSignalStrength; +import android.hardware.radio.network.LteSignalStrength; +import android.hardware.radio.network.NrSignalStrength; +import android.hardware.radio.network.TdscdmaSignalStrength; +import android.hardware.radio.network.WcdmaSignalStrength; @VintfStability parcelable SignalStrength { diff --git a/radio/aidl/android/hardware/radio/SignalThresholdInfo.aidl b/radio/aidl/android/hardware/radio/network/SignalThresholdInfo.aidl similarity index 98% rename from radio/aidl/android/hardware/radio/SignalThresholdInfo.aidl rename to radio/aidl/android/hardware/radio/network/SignalThresholdInfo.aidl index 0d818b4e19..696292dc14 100644 --- a/radio/aidl/android/hardware/radio/SignalThresholdInfo.aidl +++ b/radio/aidl/android/hardware/radio/network/SignalThresholdInfo.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; /** * Contains the threshold values of each signal measurement type. diff --git a/radio/aidl/android/hardware/radio/SuppSvcNotification.aidl b/radio/aidl/android/hardware/radio/network/SuppSvcNotification.aidl similarity index 96% rename from radio/aidl/android/hardware/radio/SuppSvcNotification.aidl rename to radio/aidl/android/hardware/radio/network/SuppSvcNotification.aidl index b41292b170..dce437aaf8 100644 --- a/radio/aidl/android/hardware/radio/SuppSvcNotification.aidl +++ b/radio/aidl/android/hardware/radio/network/SuppSvcNotification.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; @VintfStability parcelable SuppSvcNotification { diff --git a/radio/aidl/android/hardware/radio/TdscdmaSignalStrength.aidl b/radio/aidl/android/hardware/radio/network/TdscdmaSignalStrength.aidl similarity index 97% rename from radio/aidl/android/hardware/radio/TdscdmaSignalStrength.aidl rename to radio/aidl/android/hardware/radio/network/TdscdmaSignalStrength.aidl index baed68a17b..13f394abb2 100644 --- a/radio/aidl/android/hardware/radio/TdscdmaSignalStrength.aidl +++ b/radio/aidl/android/hardware/radio/network/TdscdmaSignalStrength.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; @VintfStability parcelable TdscdmaSignalStrength { diff --git a/radio/aidl/android/hardware/radio/UtranBands.aidl b/radio/aidl/android/hardware/radio/network/UtranBands.aidl similarity index 96% rename from radio/aidl/android/hardware/radio/UtranBands.aidl rename to radio/aidl/android/hardware/radio/network/UtranBands.aidl index 8a22ed75b3..da21f9bcb8 100644 --- a/radio/aidl/android/hardware/radio/UtranBands.aidl +++ b/radio/aidl/android/hardware/radio/network/UtranBands.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; /** * UTRAN bands up to V15.0.0 diff --git a/radio/aidl/android/hardware/radio/WcdmaSignalStrength.aidl b/radio/aidl/android/hardware/radio/network/WcdmaSignalStrength.aidl similarity index 97% rename from radio/aidl/android/hardware/radio/WcdmaSignalStrength.aidl rename to radio/aidl/android/hardware/radio/network/WcdmaSignalStrength.aidl index 95a3455e4c..21021e51c3 100644 --- a/radio/aidl/android/hardware/radio/WcdmaSignalStrength.aidl +++ b/radio/aidl/android/hardware/radio/network/WcdmaSignalStrength.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.network; @VintfStability parcelable WcdmaSignalStrength { diff --git a/radio/aidl/android/hardware/radio/AppStatus.aidl b/radio/aidl/android/hardware/radio/sim/AppStatus.aidl similarity index 93% rename from radio/aidl/android/hardware/radio/AppStatus.aidl rename to radio/aidl/android/hardware/radio/sim/AppStatus.aidl index 6fd17e42c0..07939bba6d 100644 --- a/radio/aidl/android/hardware/radio/AppStatus.aidl +++ b/radio/aidl/android/hardware/radio/sim/AppStatus.aidl @@ -14,10 +14,10 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.sim; -import android.hardware.radio.PersoSubstate; -import android.hardware.radio.PinState; +import android.hardware.radio.sim.PersoSubstate; +import android.hardware.radio.sim.PinState; @VintfStability parcelable AppStatus { diff --git a/radio/aidl/android/hardware/radio/CardPowerState.aidl b/radio/aidl/android/hardware/radio/sim/CardPowerState.aidl similarity index 95% rename from radio/aidl/android/hardware/radio/CardPowerState.aidl rename to radio/aidl/android/hardware/radio/sim/CardPowerState.aidl index 23088c9635..b69296d36c 100644 --- a/radio/aidl/android/hardware/radio/CardPowerState.aidl +++ b/radio/aidl/android/hardware/radio/sim/CardPowerState.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.sim; @VintfStability @Backing(type="int") diff --git a/radio/aidl/android/hardware/radio/CardStatus.aidl b/radio/aidl/android/hardware/radio/sim/CardStatus.aidl similarity index 88% rename from radio/aidl/android/hardware/radio/CardStatus.aidl rename to radio/aidl/android/hardware/radio/sim/CardStatus.aidl index a6a287d707..629f4033c7 100644 --- a/radio/aidl/android/hardware/radio/CardStatus.aidl +++ b/radio/aidl/android/hardware/radio/sim/CardStatus.aidl @@ -14,15 +14,15 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.sim; -import android.hardware.radio.AppStatus; -import android.hardware.radio.PinState; +import android.hardware.radio.sim.AppStatus; +import android.hardware.radio.sim.PinState; @VintfStability parcelable CardStatus { /* - * Card is physically absent from device. (Some old modems use CardState.ABSENT when the SIM + * Card is physically absent from device. (Some old modems use STATE_ABSENT when the SIM * is powered off. This is no longer correct, however the platform will still support this * legacy behavior.) */ @@ -67,7 +67,7 @@ parcelable CardStatus { * standards, following electrical reset of the card's chip. The ATR conveys information about * the communication parameters proposed by the card, and the card's nature and state. * - * This data is applicable only when cardState is CardState:PRESENT. + * This data is applicable only when cardState is STATE_PRESENT. */ String atr; /** @@ -75,14 +75,14 @@ parcelable CardStatus { * located in the SIM card at EFiccid (0x2FE2) as per ETSI 102.221. The ICCID is defined by * the ITU-T recommendation E.118 ISO/IEC 7816. * - * This data is applicable only when cardState is CardState:PRESENT. + * This data is applicable only when cardState is STATE_PRESENT. */ String iccid; /** * The EID is the eUICC identifier. The EID shall be stored within the ECASD and can be * retrieved by the Device at any time using the standard GlobalPlatform GET DATA command. * - * This data is mandatory and applicable only when cardState is CardState:PRESENT and SIM card + * This data is mandatory and applicable only when cardState is STATE_PRESENT and SIM card * supports eUICC. */ String eid; diff --git a/radio/aidl/android/hardware/radio/Carrier.aidl b/radio/aidl/android/hardware/radio/sim/Carrier.aidl similarity index 87% rename from radio/aidl/android/hardware/radio/Carrier.aidl rename to radio/aidl/android/hardware/radio/sim/Carrier.aidl index cde9b5ff0d..c870c00e89 100644 --- a/radio/aidl/android/hardware/radio/Carrier.aidl +++ b/radio/aidl/android/hardware/radio/sim/Carrier.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.sim; @VintfStability parcelable Carrier { @@ -42,8 +42,8 @@ parcelable Carrier { String mcc; String mnc; /** - * Specify match type for the carrier. If it’s ALL, matchData is empty string; otherwise, - * matchData is the value for the match type. + * Specify match type for the carrier. If it’s MATCH_TYPE_ALL, matchData is empty string; + * otherwise, matchData is the value for the match type. * Values are MATCH_TYPE_ */ int matchType; diff --git a/radio/aidl/android/hardware/radio/CarrierRestrictions.aidl b/radio/aidl/android/hardware/radio/sim/CarrierRestrictions.aidl similarity index 95% rename from radio/aidl/android/hardware/radio/CarrierRestrictions.aidl rename to radio/aidl/android/hardware/radio/sim/CarrierRestrictions.aidl index 5e1f8155e2..12df138b5f 100644 --- a/radio/aidl/android/hardware/radio/CarrierRestrictions.aidl +++ b/radio/aidl/android/hardware/radio/sim/CarrierRestrictions.aidl @@ -14,9 +14,9 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.sim; -import android.hardware.radio.Carrier; +import android.hardware.radio.sim.Carrier; @VintfStability parcelable CarrierRestrictions { diff --git a/radio/aidl/android/hardware/radio/CdmaSubscriptionSource.aidl b/radio/aidl/android/hardware/radio/sim/CdmaSubscriptionSource.aidl similarity index 95% rename from radio/aidl/android/hardware/radio/CdmaSubscriptionSource.aidl rename to radio/aidl/android/hardware/radio/sim/CdmaSubscriptionSource.aidl index b83e81a227..bdd7e07904 100644 --- a/radio/aidl/android/hardware/radio/CdmaSubscriptionSource.aidl +++ b/radio/aidl/android/hardware/radio/sim/CdmaSubscriptionSource.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.sim; @VintfStability @Backing(type="int") diff --git a/radio/aidl/android/hardware/radio/sim/IRadioSim.aidl b/radio/aidl/android/hardware/radio/sim/IRadioSim.aidl new file mode 100644 index 0000000000..902c90c6f3 --- /dev/null +++ b/radio/aidl/android/hardware/radio/sim/IRadioSim.aidl @@ -0,0 +1,502 @@ +/* + * 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.radio.sim; + +import android.hardware.radio.sim.CardPowerState; +import android.hardware.radio.sim.CarrierRestrictions; +import android.hardware.radio.sim.CdmaSubscriptionSource; +import android.hardware.radio.sim.IRadioSimIndication; +import android.hardware.radio.sim.IRadioSimResponse; +import android.hardware.radio.sim.IccIo; +import android.hardware.radio.sim.ImsiEncryptionInfo; +import android.hardware.radio.sim.PersoSubstate; +import android.hardware.radio.sim.PhonebookRecordInfo; +import android.hardware.radio.sim.SelectUiccSub; +import android.hardware.radio.sim.SimApdu; +import android.hardware.radio.sim.SimLockMultiSimPolicy; + +/** + * This interface is used by telephony and telecom to talk to cellular radio for SIM APIs. + * All the functions have minimum one parameter: + * serial: which corresponds to serial no. of request. Serial numbers must only be memorized for the + * duration of a method call. If clients provide colliding serials (including passing the same + * serial to different methods), multiple responses (one for each method call) must still be served. + * setResponseFunctions must work with IRadioSimResponse and IRadioSimIndication. + */ +@VintfStability +oneway interface IRadioSim { + /** + * Whether uiccApplications are enabled or disabled. + * By default uiccApplications must be enabled, unless enableUiccApplications() with enable + * being false is called. + * + * @param serial Serial number of request. + * + * Response function is IRadioSimResponse.areUiccApplicationsEnabledResponse() + */ + void areUiccApplicationsEnabled(in int serial); + + /** + * Supplies old ICC PIN2 and new PIN2. + * + * @param serial Serial number of request. + * @param oldPin2 Old pin2 value + * @param newPin2 New pin2 value + * @param aid AID value, See ETSI 102.221 8.1 and 101.220 4, empty string if no value. + * + * Response function is IRadioSimResponse.changeIccPin2ForAppResponse() + */ + void changeIccPin2ForApp(in int serial, in String oldPin2, in String newPin2, in String aid); + + /** + * Supplies old ICC PIN and new PIN. + * + * @param serial Serial number of request. + * @param oldPin Old pin value + * @param newPin New pin value + * @param aid AID value, See ETSI 102.221 8.1 and 101.220 4, empty string if no value. + * + * Response function is IRadioSimResponse.changeIccPinForAppResponse() + */ + void changeIccPinForApp(in int serial, in String oldPin, in String newPin, in String aid); + + /** + * Enable or disable UiccApplications on the SIM. If disabled: + * - Modem will not register on any network. + * - SIM must be PRESENT, and the IccId of the SIM must still be accessible. + * - The corresponding modem stack is still functional, e.g. able to make emergency calls or + * do network scan. + * By default if this API is not called, the uiccApplications must be enabled automatically. + * It must work for both single SIM and DSDS cases for UX consistency. + * The preference is per SIM, and must be remembered over power cycle, modem reboot, or SIM + * insertion / unplug. + * + * @param serial Serial number of request. + * @param enable true if to enable uiccApplications, false to disable. + * + * Response function is IRadioSimResponse.enableUiccApplicationsResponse() + */ + void enableUiccApplications(in int serial, in boolean enable); + + /** + * Get carrier restrictions. + * + * @param serial Serial number of request. + * + * Response function is IRadioSimResponse.getAllowedCarriersResponse() + */ + void getAllowedCarriers(in int serial); + + /** + * Request the device MDN / H_SID / H_NID. The request is only allowed when CDMA subscription + * is available. When CDMA subscription is changed, application layer must re-issue the request + * to update the subscription information. + * + * @param serial Serial number of request. + * + * Response function is IRadioSimResponse.getCdmaSubscriptionResponse() + */ + void getCdmaSubscription(in int serial); + + /** + * Request to query the location where the CDMA subscription shall be retrieved. + * + * @param serial Serial number of request. + * + * Response function is IRadioSimResponse.getCdmaSubscriptionSourceResponse() + */ + void getCdmaSubscriptionSource(in int serial); + + /** + * Query the status of a facility lock state + * + * @param serial Serial number of request. + * @param facility is the facility string code from TS 27.007 7.4 + * (eg "AO" for BAOC, "SC" for SIM lock) + * @param password is the password, or "" if not required + * @param serviceClass is the TS 27.007 service class bit vector of services to query + * @param appId is AID value, See ETSI 102.221 8.1 and 101.220 4, empty string if no value. + * This is only applicable in the case of Fixed Dialing Numbers (FDN) requests. + * + * Response function is IRadioSimResponse.getFacilityLockForAppResponse() + */ + void getFacilityLockForApp(in int serial, in String facility, in String password, + in int serviceClass, in String appId); + + /** + * Requests status of the ICC card + * + * @param serial Serial number of request. + * + * Response function is IRadioSimResponse.getIccCardStatusResponse() + */ + void getIccCardStatus(in int serial); + + /** + * Get the SIM IMSI. Only valid when radio state is "RADIO_STATE_ON" + * + * @param serial Serial number of request. + * @param aid AID value, See ETSI 102.221 8.1 and 101.220 4, empty string if no value. + * + * Response function is IRadioSimResponse.getImsiForAppResponse() + */ + void getImsiForApp(in int serial, in String aid); + + /** + * Get the phonebook capacity. + * + * @param serial Serial number of request. + * + * Response function is IRadioSimResponse.getSimPhonebookCapacityResponse() + */ + void getSimPhonebookCapacity(in int serial); + + /** + * Get the local and global phonebook records from the SIM card. + * This should be called again after a simPhonebookChanged notification is received. + * The phonebook records are received via IRadioSimIndication.simPhonebookRecordsReceived() + * + * @param serial Serial number of request. + * + * Response function is IRadioSimResponse.getSimPhonebookRecordsResponse() + */ + void getSimPhonebookRecords(in int serial); + + /** + * Close a previously opened logical channel. This command reflects TS 27.007 + * "close logical channel" operation (+CCHC). + * + * @param serial Serial number of request. + * @param channelId session id of the logical channel (+CCHC). + * + * Response function is IRadioSimResponse.iccCloseLogicalChannelResponse() + */ + void iccCloseLogicalChannel(in int serial, in int channelId); + + /** + * Request ICC I/O operation. This is similar to the TS 27.007 "restricted SIM" operation where + * it assumes all of the EF selection must be done by the callee. Arguments and responses that + * are unused for certain values of "command" must be ignored or set to empty string. + * Note that IccIo has a "PIN2" field which may be empty string, or may specify a PIN2 for + * operations that require a PIN2 (eg updating FDN records). + * + * @param serial Serial number of request. + * @param iccIo IccIo + * + * Response function is IRadioSimResponse.iccIoForAppResponse() + */ + void iccIoForApp(in int serial, in IccIo iccIo); + + /** + * Open a new logical channel and select the given application. This command + * reflects TS 27.007 "open logical channel" operation (+CCHO). + * + * @param serial Serial number of request. + * @param aid AID value, See ETSI 102.221 and 101.220. + * @param p2 P2 value, described in ISO 7816-4. Ignore if equal to RadioConst:P2_CONSTANT_NO_P2 + * + * Response function is IRadioSimResponse.iccOpenLogicalChannelResponse() + */ + void iccOpenLogicalChannel(in int serial, in String aid, in int p2); + + /** + * Request APDU exchange on the basic channel. This command reflects TS 27.007 + * "generic SIM access" operation (+CSIM). The modem must ensure proper function of GSM/CDMA, + * and filter commands appropriately. It must filter channel management and SELECT by DF + * name commands. "sessionid" field must be ignored. + * + * @param serial Serial number of request. + * @param message SimApdu to be sent + * + * Response function is IRadioSimResponse.iccTransmitApduBasicChannelResponse() + */ + void iccTransmitApduBasicChannel(in int serial, in SimApdu message); + + /** + * Exchange APDUs with a UICC over a previously opened logical channel. This command reflects + * TS 27.007 "generic logical channel access" operation (+CGLA). The modem must filter channel + * management and SELECT by DF name commands. + * + * @param serial Serial number of request. + * @param message SimApdu to be sent + * + * Response function is IRadioSimResponse.iccTransmitApduLogicalChannelResponse() + */ + void iccTransmitApduLogicalChannel(in int serial, in SimApdu message); + + /** + * Indicates that the StkService is running and is ready to receive unsolicited stk commands. + * + * @param serial Serial number of request. + * + * Response function is IRadioSimResponse.reportStkServiceIsRunningResponse() + */ + void reportStkServiceIsRunning(in int serial); + + /** + * Returns the response of SIM Authentication through Radio challenge request. + * + * @param serial Serial number of request. + * @param authContext P2 value of authentication command, see P2 parameter in + * 3GPP TS 31.102 7.1.2 + * @param authData the challenge string in Base64 format, see 3GPP TS 31.102 7.1.2 + * @param aid AID value, See ETSI 102.221 8.1 and 101.220 4, empty string if no value + * + * Response function is IRadioSimResponse.requestIccSimAuthenticationResponse() + */ + void requestIccSimAuthentication( + in int serial, in int authContext, in String authData, in String aid); + + /** + * Request the ISIM application on the UICC to perform AKA challenge/response algorithm + * for IMS authentication + * + * @param serial Serial number of request. + * @param challenge challenge string in Base64 format + * + * Response function is IRadioSimResponse.requestIsimAuthenticationResponse() + */ + void requestIsimAuthentication(in int serial, in String challenge); + + /** + * When response type received from a radio indication or radio response is + * RadioIndicationType:UNSOLICITED_ACK_EXP or RadioResponseType:SOLICITED_ACK_EXP respectively, + * acknowledge the receipt of those messages by sending responseAcknowledgement(). + */ + void responseAcknowledgement(); + + /** + * Requests to send a SAT/USAT envelope command to SIM. + * The SAT/USAT envelope command refers to 3GPP TS 11.14 and 3GPP TS 31.111 + * + * @param serial Serial number of request. + * @param command SAT/USAT command in hexadecimal format string starting with command tag + * + * Response function is IRadioSimResponse.sendEnvelopeResponse() + */ + void sendEnvelope(in int serial, in String command); + + /** + * Requests to send a SAT/USAT envelope command to SIM. The SAT/USAT envelope command refers to + * 3GPP TS 11.14 and 3GPP TS 31.111. This request has one difference from sendEnvelope(): + * The SW1 and SW2 status bytes from the UICC response are returned along with the response + * data, using the same structure as iccIOForApp(). The implementation must perform normal + * processing of a '91XX' response in SW1/SW2 to retrieve the pending proactive command and + * send it as an unsolicited response, as sendEnvelope() does. + * + * @param serial Serial number of request. + * @param contents SAT/USAT command in hexadecimal format starting with command tag + * + * Response function is IRadioSimResponse.sendEnvelopeWithStatusResponse() + */ + void sendEnvelopeWithStatus(in int serial, in String contents); + + /** + * Requests to send a terminal response to SIM for a received proactive command + * + * @param serial Serial number of request. + * @param commandResponse SAT/USAT response in hexadecimal format string starting with + * first byte of response data + * + * Response function is IRadioSimResponse.sendTerminalResponseResponseToSim() + */ + void sendTerminalResponseToSim(in int serial, in String commandResponse); + + /** + * Set carrier restrictions. Expected modem behavior: + * If never receives this command: + * - Must allow all carriers + * Receives this command: + * - Only allow carriers specified in carriers. The restriction persists across power cycles + * and FDR. If a present SIM is allowed, modem must not reload the SIM. If a present SIM is + * *not* allowed, modem must detach from the registered network and only keep emergency + * service, and notify Android SIM refresh reset with new SIM state being + * CardState:RESTRICTED. Emergency service must be enabled. + * + * @param serial Serial number of request. + * @param carriers CarrierRestrictions consisting allowed and excluded carriers + * @param multiSimPolicy Policy to be used for devices with multiple SIMs. + * + * Response function is IRadioSimResponse.setAllowedCarriersResponse() + */ + void setAllowedCarriers(in int serial, in CarrierRestrictions carriers, + in SimLockMultiSimPolicy multiSimPolicy); + + /** + * Provide Carrier specific information to the modem that must be used to encrypt the IMSI and + * IMPI. Sent by the framework during boot, carrier switch and everytime the framework receives + * a new certificate. + * + * @param serial Serial number of request. + * @param imsiEncryptionInfo ImsiEncryptionInfo + * + * Response function is IRadioSimResponse.setCarrierInfoForImsiEncryptionResponse() + */ + void setCarrierInfoForImsiEncryption(in int serial, in ImsiEncryptionInfo imsiEncryptionInfo); + + /** + * Request to set the location where the CDMA subscription shall be retrieved + * + * @param serial Serial number of request. + * @param cdmaSub CdmaSubscriptionSource + * + * Response function is IRadioSimResponse.setCdmaSubscriptionSourceResponse() + */ + void setCdmaSubscriptionSource(in int serial, in CdmaSubscriptionSource cdmaSub); + + /** + * Enable/disable one facility lock + * + * @param serial Serial number of request. + * @param facility is the facility string code from TS 27.007 7.4 (eg "AO" for BAOC) + * @param lockState false for "unlock" and true for "lock" + * @param password is the password + * @param serviceClass is string representation of decimal TS 27.007 service class bit vector. + * Eg, the string "1" means "set this facility for voice services" + * @param appId is AID value, See ETSI 102.221 8.1 and 101.220 4, empty string if no value. + * This is only applicable in the case of Fixed Dialing Numbers (FDN) requests. + * + * Response function is IRadioSimResponse.setFacilityLockForAppResponse() + */ + void setFacilityLockForApp(in int serial, in String facility, in boolean lockState, + in String password, in int serviceClass, in String appId); + + /** + * Set response functions for SIM radio requests and indications. + * + * @param radioSimResponse Object containing response functions + * @param radioSimIndication Object containing radio indications + */ + void setResponseFunctions( + in IRadioSimResponse radioSimResponse, in IRadioSimIndication radioSimIndication); + + /** + * Set SIM card power state. Request is used to power off or power on the card. It should not + * generate a CardState.CARDSTATE_ABSENT indication, since the SIM is still physically inserted. + * When SIM card is in POWER_UP_PASS_THROUGH, the modem does not send any command to it (for + * example SELECT of MF, or TERMINAL CAPABILITY), and the SIM card is controlled completely by + * Telephony sending APDUs directly. The SIM card state must be RIL_CARDSTATE_PRESENT and the + * number of card apps will be 0. No new error code is generated. Emergency calls are supported + * in the same way as if the SIM card is absent. Pass-through mode is valid only for the + * specific card session where it is activated, and normal behavior occurs at the next SIM + * initialization, unless POWER_UP_PASS_THROUGH is requested again. + * The device is required to power down the SIM card before it can switch the mode between + * POWER_UP and POWER_UP_PASS_THROUGH. At device power up, the SIM interface is powered up + * automatically. Each subsequent request to this method is processed only after the completion + * of the previous one. + * When the SIM is in POWER_DOWN, the modem should send an empty vector of AppStatus in + * CardStatus.applications. If a SIM in the POWER_DOWN state is removed and a new SIM is + * inserted, the new SIM should be in POWER_UP mode by default. If the device is turned off or + * restarted while the SIM is in POWER_DOWN, then the SIM should turn on normally in POWER_UP + * mode when the device turns back on. + * + * @param serial Serial number of request + * @param powerUp POWER_DOWN if powering down the SIM card + * POWER_UP if powering up the SIM card + * POWER_UP_PASS_THROUGH if powering up the SIM card in pass through mode + * + * Response function is IRadioSimResponse.setSimCardPowerResponse() + */ + void setSimCardPower(in int serial, in CardPowerState powerUp); + + /** + * Selection/de-selection of a subscription from a SIM card + * + * @param serial Serial number of request. + * @param uiccSub SelectUiccSub + * + * Response function is IRadioSimResponse.setUiccSubscriptionResponse() + */ + void setUiccSubscription(in int serial, in SelectUiccSub uiccSub); + + /** + * Supplies ICC PIN2. Only called following operation where SIM_PIN2 was returned as a failure + * from a previous operation. + * + * @param serial Serial number of request. + * @param pin2 PIN2 value + * @param aid AID value, See ETSI 102.221 8.1 and 101.220 4, empty string if no value. + * + * Response function is IRadioSimResponse.supplyIccPin2ForAppResponse() + */ + void supplyIccPin2ForApp(in int serial, in String pin2, in String aid); + + /** + * Supplies ICC PIN. Only called if CardStatus has AppState.PIN state + * + * @param serial Serial number of request. + * @param pin PIN value + * @param aid AID value, See ETSI 102.221 8.1 and 101.220 4, empty string if no value. + * + * Response function is IRadioSimResponse.supplyIccPinForAppResponse() + */ + void supplyIccPinForApp(in int serial, in String pin, in String aid); + + /** + * Supplies ICC PUK2 and new PIN2. + * + * @param serial Serial number of request. + * @param puk2 PUK2 value + * @param pin2 New PIN2 value + * @param aid AID value, See ETSI 102.221 8.1 and 101.220 4, empty string if no value. + * + * Response function is IRadioSimResponse.supplyIccPuk2ForAppResponse() + */ + void supplyIccPuk2ForApp(in int serial, in String puk2, in String pin2, in String aid); + + /** + * Supplies ICC PUK and new PIN. + * + * @param serial Serial number of request. + * @param puk PUK value + * @param pin New PIN value + * @param aid AID value, See ETSI 102.221 8.1 and 101.220 4, empty string if no value. + * + * Response function is IRadioSimResponse.supplyIccPukForAppResponse() + */ + void supplyIccPukForApp(in int serial, in String puk, in String pin, in String aid); + + /** + * Request that deactivates one category of device personalization. Device personalization + * generally binds the device so it can only be used on one carrier or even one carrier subnet + * (See TS 22.022). When the user has gained the rights to unbind the device (at the end of a + * contract period or other event), the controlKey will be delivered to either the user for + * manual entry or to a carrier app on the device for automatic entry. + * + * @param serial Serial number of request. + * @param persoType SIM personalization type. + * @param controlKey the unlock code for removing persoType personalization from this device + * + * Response function is IRadioSimResponse.supplySimDepersonalizationResponse() + */ + void supplySimDepersonalization( + in int serial, in PersoSubstate persoType, in String controlKey); + + /** + * Insert, delete or update a phonebook record on the SIM card. If the index of recordInfo is 0, + * the phonebook record will be added to global or local phonebook, and global phonebook has + * higher priority than local phonebook. If the fields in the recordInfo are all empty except + * for the index, the phonebook record specified by the index will be deleted. The indication + * simPhonebookChanged will be called after every successful call of updateSimPhonebookRecords. + * + * @param serial Serial number of request. + * @param recordInfo Details of the record to insert, delete or update. + * + * Response function is IRadioSimResponse.updateSimPhonebookRecordsResponse() + */ + void updateSimPhonebookRecords(in int serial, in PhonebookRecordInfo recordInfo); +} diff --git a/radio/aidl/android/hardware/radio/sim/IRadioSimIndication.aidl b/radio/aidl/android/hardware/radio/sim/IRadioSimIndication.aidl new file mode 100644 index 0000000000..a13904099d --- /dev/null +++ b/radio/aidl/android/hardware/radio/sim/IRadioSimIndication.aidl @@ -0,0 +1,130 @@ +/* + * 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.radio.sim; + +import android.hardware.radio.RadioIndicationType; +import android.hardware.radio.sim.CdmaSubscriptionSource; +import android.hardware.radio.sim.PbReceivedStatus; +import android.hardware.radio.sim.PhonebookRecordInfo; +import android.hardware.radio.sim.SimRefreshResult; + +/** + * Interface declaring unsolicited radio indications for SIM APIs. + */ +@VintfStability +oneway interface IRadioSimIndication { + /** + * Indicates that the modem requires the Carrier info for IMSI/IMPI encryption. This might + * happen when the modem restarts or for some reason it's cache has been invalidated. + * + * @param type Type of radio indication + */ + void carrierInfoForImsiEncryption(in RadioIndicationType info); + + /** + * Indicates when CDMA subscription source changed. + * + * @param type Type of radio indication + * @param cdmaSource New CdmaSubscriptionSource + */ + void cdmaSubscriptionSourceChanged( + in RadioIndicationType type, in CdmaSubscriptionSource cdmaSource); + + /** + * Indicates whether SIM phonebook is changed. This indication is sent whenever the SIM + * phonebook is changed, including SIM is inserted or removed and updated by + * IRadioSim.updateSimPhonebookRecords. + * + * @param type Type of radio indication + */ + void simPhonebookChanged(in RadioIndicationType type); + + /** + * Indicates the content of all the used records in the SIM phonebook. This indication is + * associated with the API getSimPhonebookRecords and might be received more than once that is + * replying on the record count. + * + * @param type Type of radio indication + * @param status Status of PbReceivedStatus + * @param records Vector of PhonebookRecordInfo + */ + void simPhonebookRecordsReceived(in RadioIndicationType type, in PbReceivedStatus status, + in PhonebookRecordInfo[] records); + + /** + * Indicates that file(s) on the SIM have been updated, or the SIM has been reinitialized. + * If the SIM state changes as a result of the SIM refresh (eg, SIM_READY -> + * SIM_LOCKED_OR_ABSENT), simStatusChanged() must be sent. + * + * @param type Type of radio indication + * @param refreshResult Result of sim refresh + */ + void simRefresh(in RadioIndicationType type, in SimRefreshResult refreshResult); + + /** + * Indicates that SIM state changes. Callee must invoke getIccCardStatus(). + * + * @param type Type of radio indication + */ + void simStatusChanged(in RadioIndicationType type); + + /** + * Indicates when SIM notifies applcations some event happens. + * + * @param type Type of radio indication + * @param cmd SAT/USAT commands or responses sent by ME to SIM or commands handled by ME, + * represented as byte array starting with first byte of response data for command tag. + * Refer to TS 102.223 section 9.4 for command types + */ + void stkEventNotify(in RadioIndicationType type, in String cmd); + + /** + * Indicates when SIM issue a STK proactive command to applications. + * + * @param type Type of radio indication + * @param cmd SAT/USAT proactive represented as byte array starting with command tag. + * Refer to TS 102.223 section 9.4 for command types + */ + void stkProactiveCommand(in RadioIndicationType type, in String cmd); + + /** + * Indicates when STK session is terminated by SIM. + * + * @param type Type of radio indication + */ + void stkSessionEnd(in RadioIndicationType type); + + /** + * Indicated when there is a change in subscription status. + * This event must be sent in the following scenarios + * - subscription readiness at modem, which was selected by telephony layer + * - when subscription is deactivated by modem due to UICC card removal + * - when network invalidates the subscription i.e. attach reject due to authentication reject + * + * @param type Type of radio indication + * @param activate false for subscription deactivated, true for subscription activated + */ + void subscriptionStatusChanged(in RadioIndicationType type, in boolean activate); + + /** + * Report change of whether uiccApplications are enabled, or disabled. + * + * @param type Type of radio indication + * @param enabled whether uiccApplications are enabled or disabled + */ + void uiccApplicationsEnablementChanged(in RadioIndicationType type, in boolean enabled); +} diff --git a/radio/aidl/android/hardware/radio/sim/IRadioSimResponse.aidl b/radio/aidl/android/hardware/radio/sim/IRadioSimResponse.aidl new file mode 100644 index 0000000000..dcc70290f5 --- /dev/null +++ b/radio/aidl/android/hardware/radio/sim/IRadioSimResponse.aidl @@ -0,0 +1,649 @@ +/* + * 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.radio.sim; + +import android.hardware.radio.RadioResponseInfo; +import android.hardware.radio.sim.CardStatus; +import android.hardware.radio.sim.CarrierRestrictions; +import android.hardware.radio.sim.CdmaSubscriptionSource; +import android.hardware.radio.sim.IccIoResult; +import android.hardware.radio.sim.PersoSubstate; +import android.hardware.radio.sim.PhonebookCapacity; +import android.hardware.radio.sim.SimLockMultiSimPolicy; + +/** + * Interface declaring response functions to solicited radio requests for SIM APIs. + */ +@VintfStability +oneway interface IRadioSimResponse { + /** + * Acknowledge the receipt of radio request sent to the vendor. This must be sent only for + * radio request which take long time to respond. For more details, refer + * https://source.android.com/devices/tech/connect/ril.html + * + * @param serial Serial no. of the request whose acknowledgement is sent. + */ + void acknowledgeRequest(in int serial); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param enabled whether Uicc applications are enabled. + * + * Valid errors returned: + * RadioError:NONE + * RadioError:SIM_ABSENT + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + */ + void areUiccApplicationsEnabledResponse(in RadioResponseInfo info, in boolean enabled); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param remainingRetries Number of retries remaining, must be equal to -1 if unknown. + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE (radio resetting) + * RadioError:PASSWORD_INCORRECT (old PIN2 is invalid) + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:INVALID_ARGUMENTS + * RadioError:INVALID_SIM_STATE + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:SIM_PUK2 + */ + void changeIccPin2ForAppResponse(in RadioResponseInfo info, in int remainingRetries); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param remainingRetries Number of retries remaining, must be equal to -1 if unknown. + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE (radio resetting) + * RadioError:PASSWORD_INCORRECT + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:INVALID_ARGUMENTS + * RadioError:INVALID_SIM_STATE + * RadioError:REQUEST_NOT_SUPPORTED + */ + void changeIccPinForAppResponse(in RadioResponseInfo info, in int remainingRetries); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:SIM_ABSENT + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:BUSY + */ + void enableUiccApplicationsResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param carriers Carrier restriction information. + * @param multiSimPolicy Policy used for devices with multiple SIM cards. + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:REQUEST_NOT_SUPPORTED + */ + void getAllowedCarriersResponse(in RadioResponseInfo info, in CarrierRestrictions carriers, + in SimLockMultiSimPolicy multiSimPolicy); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param mdn MDN if CDMA subscription is available + * @param hSid is a comma separated list of H_SID (Home SID) if CDMA subscription is available, + * in decimal format + * @param hNid is a comma separated list of H_NID (Home NID) if CDMA subscription is available, + * in decimal format + * @param min MIN (10 digits, MIN2+MIN1) if CDMA subscription is available + * @param prl PRL version if CDMA subscription is available + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SUBSCRIPTION_NOT_AVAILABLE + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:MODEM_ERR + * RadioError:NOT_PROVISIONED + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:SIM_ABSENT + */ + void getCdmaSubscriptionResponse(in RadioResponseInfo info, in String mdn, in String hSid, + in String hNid, in String min, in String prl); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param source CDMA subscription source + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SUBSCRIPTION_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:SIM_ABSENT + */ + void getCdmaSubscriptionSourceResponse( + in RadioResponseInfo info, in CdmaSubscriptionSource source); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param response 0 is the TS 27.007 service class bit vector of services for which the + * specified barring facility is active. "0" means "disabled for all" + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SS_MODIFIED_TO_DIAL + * RadioError:SS_MODIFIED_TO_USSD + * RadioError:SS_MODIFIED_TO_SS + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_MEMORY + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:FDN_CHECK_FAILURE + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + void getFacilityLockForAppResponse(in RadioResponseInfo info, in int response); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param cardStatus ICC card status as defined by CardStatus + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:NO_RESOURCES + * RadioError:REQUEST_NOT_SUPPORTED + */ + void getIccCardStatusResponse(in RadioResponseInfo info, in CardStatus cardStatus); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param imsi String containing the IMSI + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE (radio resetting) + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:INVALID_SIM_STATE + * RadioError:SIM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + */ + void getImsiForAppResponse(in RadioResponseInfo info, in String imsi); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param capacity Response capacity enum indicating response processing status + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_ARGUMENTS + * RadioError:INVALID_SIM_STATE + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * REQUEST_NOT_SUPPORTED may only be returned on devices that don't support this API, + * indicated by the HAL capability CAPABILITY_SIM_PHONEBOOK_IN_MODEM. + */ + void getSimPhonebookCapacityResponse(in RadioResponseInfo info, in PhonebookCapacity capacity); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_ARGUMENTS + * RadioError:INVALID_SIM_STATE + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * REQUEST_NOT_SUPPORTED may only be returned on devices that don't support this API, + * indicated by the HAL capability CAPABILITY_SIM_PHONEBOOK_IN_MODEM. + */ + void getSimPhonebookRecordsResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:REQUEST_NOT_SUPPORTED + */ + void iccCloseLogicalChannelResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param iccIo ICC IO operation response + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SIM_PIN2 + * RadioError:SIM_PUK2 + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:INVALID_SIM_STATE + * RadioError:SIM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + */ + void iccIoForAppResponse(in RadioResponseInfo info, in IccIoResult iccIo); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param channelId session id of the logical channel. + * @param selectResponse Contains the select response for the open channel command with one + * byte per integer + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:MISSING_RESOURCE + * RadioError:NO_SUCH_ELEMENT + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:SIM_ERR + * RadioError:INVALID_SIM_STATE + * RadioError:MISSING_RESOURCE + * RadioError:REQUEST_NOT_SUPPORTED + */ + void iccOpenLogicalChannelResponse( + in RadioResponseInfo info, in int channelId, in byte[] selectResponse); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param result IccIoResult + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:REQUEST_NOT_SUPPORTED + */ + void iccTransmitApduBasicChannelResponse(in RadioResponseInfo info, in IccIoResult result); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param result IccIoResult + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:REQUEST_NOT_SUPPORTED + */ + void iccTransmitApduLogicalChannelResponse(in RadioResponseInfo info, in IccIoResult result); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:REQUEST_NOT_SUPPORTED + */ + void reportStkServiceIsRunningResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param result IccIoResult + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:INVALID_MODEM_STATE + * RadioError:SIM_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:REQUEST_NOT_SUPPORTED + */ + void requestIccSimAuthenticationResponse(in RadioResponseInfo info, in IccIoResult result); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param response response string of the challenge/response algo for ISIM auth in base64 format + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:INVALID_MODEM_STATE + * RadioError:INVALID_ARGUMENTS + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:SIM_ABSENT + */ + void requestIsimAuthenticationResponse(in RadioResponseInfo info, in String response); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param commandResponse SAT/USAT response in hexadecimal format string starting with first + * byte of response + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SIM_BUSY + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:INVALID_ARGUMENTS + * RadioError:MODEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:SIM_ABSENT + */ + void sendEnvelopeResponse(in RadioResponseInfo info, in String commandResponse); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param iccIo IccIoResult corresponding to ICC IO response + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SIM_BUSY + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:SIM_ABSENT + */ + void sendEnvelopeWithStatusResponse(in RadioResponseInfo info, in IccIoResult iccIo); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:INVALID_MODEM_STATE + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:SIM_ABSENT + */ + void sendTerminalResponseToSimResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:REQUEST_NOT_SUPPORTED + */ + void setAllowedCarriersResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:RIL_E_SUCCESS + * RadioError:RIL_E_RADIO_NOT_AVAILABLE + * RadioError:SIM_ABSENT + * RadioError:RIL_E_REQUEST_NOT_SUPPORTED + * RadioError:INVALID_ARGUMENTS + * RadioError:MODEM_INTERNAL_FAILURE + */ + void setCarrierInfoForImsiEncryptionResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SIM_ABSENT + * RadioError:SUBSCRIPTION_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:REQUEST_NOT_SUPPORTED + */ + void setCdmaSubscriptionSourceResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param retry 0 is the number of retries remaining, or -1 if unknown + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SS_MODIFIED_TO_DIAL + * RadioError:SS_MODIFIED_TO_USSD + * RadioError:SS_MODIFIED_TO_SS + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_MEMORY + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:INVALID_STATE + * RadioError:FDN_CHECK_FAILURE + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_MODEM_STATE + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + void setFacilityLockForAppResponse(in RadioResponseInfo info, in int retry); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:SIM_ERR (indicates a timeout or other issue making the SIM unresponsive) + */ + void setSimCardPowerResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SUBSCRIPTION_NOT_SUPPORTED + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + void setUiccSubscriptionResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param remainingRetries Number of retries remaining, must be equal to -1 if unknown. + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE (radio resetting) + * RadioError:PASSWORD_INCORRECT + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:INVALID_ARGUMENTS + * RadioError:INVALID_SIM_STATE + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:SIM_PUK2 + */ + void supplyIccPin2ForAppResponse(in RadioResponseInfo info, in int remainingRetries); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param remainingRetries Number of retries remaining, must be equal to -1 if unknown. + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE (radio resetting) + * RadioError:PASSWORD_INCORRECT + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:INVALID_ARGUMENTS + * RadioError:INVALID_SIM_STATE + * RadioError:REQUEST_NOT_SUPPORTED + */ + void supplyIccPinForAppResponse(in RadioResponseInfo info, in int remainingRetries); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param remainingRetries Number of retries remaining, must be equal to -1 if unknown. + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE (radio resetting) + * RadioError:PASSWORD_INCORRECT (PUK is invalid) + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:INVALID_ARGUMENTS + * RadioError:INVALID_SIM_STATE + * RadioError:REQUEST_NOT_SUPPORTED + */ + void supplyIccPuk2ForAppResponse(in RadioResponseInfo info, in int remainingRetries); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param remainingRetries Number of retries remaining, must be equal to -1 if unknown. + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE (radio resetting) + * RadioError:PASSWORD_INCORRECT (PUK is invalid) + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:INVALID_ARGUMENTS + * RadioError:INVALID_SIM_STATE + * RadioError:REQUEST_NOT_SUPPORTED + */ + void supplyIccPukForAppResponse(in RadioResponseInfo info, in int remainingRetries); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param persoType SIM Personalization type + * @param remainingRetries postiive values indicates number of retries remaining, must be equal + * to -1 if number of retries is infinite. + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:PASSWORD_INCORRECT (code is invalid) + * RadioError:NO_MEMORY + * RadioError:INVALID_SIM_STATE + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_RESOURCES + * RadioError:REQUEST_NOT_SUPPORTED + */ + void supplySimDepersonalizationResponse( + in RadioResponseInfo info, in PersoSubstate persoType, in int remainingRetries); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param updatedRecordIndex The index of the updated or inserted record in the phonebook and + * the minimum value is 1 + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_ARGUMENTS + * RadioError:INVALID_SIM_STATE + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:SIM_ERR + * RadioError:NO_SUCH_ENTRY + * RadioError:NO_RESOURCES + * REQUEST_NOT_SUPPORTED may only be returned on devices that don't support this API, + * indicated by the HAL capability CAPABILITY_SIM_PHONEBOOK_IN_MODEM. + */ + void updateSimPhonebookRecordsResponse(in RadioResponseInfo info, in int updatedRecordIndex); +} diff --git a/radio/aidl/android/hardware/radio/IccIo.aidl b/radio/aidl/android/hardware/radio/sim/IccIo.aidl similarity index 97% rename from radio/aidl/android/hardware/radio/IccIo.aidl rename to radio/aidl/android/hardware/radio/sim/IccIo.aidl index 7441758507..be5e832c99 100644 --- a/radio/aidl/android/hardware/radio/IccIo.aidl +++ b/radio/aidl/android/hardware/radio/sim/IccIo.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.sim; @VintfStability parcelable IccIo { diff --git a/radio/aidl/android/hardware/radio/IccIoResult.aidl b/radio/aidl/android/hardware/radio/sim/IccIoResult.aidl similarity index 96% rename from radio/aidl/android/hardware/radio/IccIoResult.aidl rename to radio/aidl/android/hardware/radio/sim/IccIoResult.aidl index 94377b4072..8aa9e8fadb 100644 --- a/radio/aidl/android/hardware/radio/IccIoResult.aidl +++ b/radio/aidl/android/hardware/radio/sim/IccIoResult.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.sim; @VintfStability parcelable IccIoResult { diff --git a/radio/aidl/android/hardware/radio/ImsiEncryptionInfo.aidl b/radio/aidl/android/hardware/radio/sim/ImsiEncryptionInfo.aidl similarity index 98% rename from radio/aidl/android/hardware/radio/ImsiEncryptionInfo.aidl rename to radio/aidl/android/hardware/radio/sim/ImsiEncryptionInfo.aidl index 3429beb7e8..e8b3807ce2 100644 --- a/radio/aidl/android/hardware/radio/ImsiEncryptionInfo.aidl +++ b/radio/aidl/android/hardware/radio/sim/ImsiEncryptionInfo.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.sim; /** * Carrier specific Information sent by the carrier, which will be used to encrypt IMSI and IMPI. diff --git a/radio/aidl/android/hardware/radio/PbReceivedStatus.aidl b/radio/aidl/android/hardware/radio/sim/PbReceivedStatus.aidl similarity index 97% rename from radio/aidl/android/hardware/radio/PbReceivedStatus.aidl rename to radio/aidl/android/hardware/radio/sim/PbReceivedStatus.aidl index 44ed4d95e5..953335baf2 100644 --- a/radio/aidl/android/hardware/radio/PbReceivedStatus.aidl +++ b/radio/aidl/android/hardware/radio/sim/PbReceivedStatus.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.sim; /** * Enum representing the status of the received PB indication. diff --git a/radio/aidl/android/hardware/radio/PersoSubstate.aidl b/radio/aidl/android/hardware/radio/sim/PersoSubstate.aidl similarity index 98% rename from radio/aidl/android/hardware/radio/PersoSubstate.aidl rename to radio/aidl/android/hardware/radio/sim/PersoSubstate.aidl index 93b2af53c4..f01ff61a50 100644 --- a/radio/aidl/android/hardware/radio/PersoSubstate.aidl +++ b/radio/aidl/android/hardware/radio/sim/PersoSubstate.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.sim; /** * Additional personalization categories in addition to those specified in 3GPP TS 22.022 and diff --git a/radio/aidl/android/hardware/radio/PhonebookCapacity.aidl b/radio/aidl/android/hardware/radio/sim/PhonebookCapacity.aidl similarity index 98% rename from radio/aidl/android/hardware/radio/PhonebookCapacity.aidl rename to radio/aidl/android/hardware/radio/sim/PhonebookCapacity.aidl index c14141114b..23a0208ecc 100644 --- a/radio/aidl/android/hardware/radio/PhonebookCapacity.aidl +++ b/radio/aidl/android/hardware/radio/sim/PhonebookCapacity.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.sim; @VintfStability parcelable PhonebookCapacity { diff --git a/radio/aidl/android/hardware/radio/PhonebookRecordInfo.aidl b/radio/aidl/android/hardware/radio/sim/PhonebookRecordInfo.aidl similarity index 97% rename from radio/aidl/android/hardware/radio/PhonebookRecordInfo.aidl rename to radio/aidl/android/hardware/radio/sim/PhonebookRecordInfo.aidl index eb0c880d26..03326b8877 100644 --- a/radio/aidl/android/hardware/radio/PhonebookRecordInfo.aidl +++ b/radio/aidl/android/hardware/radio/sim/PhonebookRecordInfo.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.sim; /** * Phonebook-record-information specified by EF_ADN (Abbreviated dialing numbers) record of SIM diff --git a/radio/aidl/android/hardware/radio/PinState.aidl b/radio/aidl/android/hardware/radio/sim/PinState.aidl similarity index 95% rename from radio/aidl/android/hardware/radio/PinState.aidl rename to radio/aidl/android/hardware/radio/sim/PinState.aidl index cb42ff232b..03b8e4ea6e 100644 --- a/radio/aidl/android/hardware/radio/PinState.aidl +++ b/radio/aidl/android/hardware/radio/sim/PinState.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.sim; @VintfStability @Backing(type="int") diff --git a/radio/aidl/android/hardware/radio/SelectUiccSub.aidl b/radio/aidl/android/hardware/radio/sim/SelectUiccSub.aidl similarity index 96% rename from radio/aidl/android/hardware/radio/SelectUiccSub.aidl rename to radio/aidl/android/hardware/radio/sim/SelectUiccSub.aidl index f762e9f953..3c152d6a6b 100644 --- a/radio/aidl/android/hardware/radio/SelectUiccSub.aidl +++ b/radio/aidl/android/hardware/radio/sim/SelectUiccSub.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.sim; @VintfStability parcelable SelectUiccSub { diff --git a/radio/aidl/android/hardware/radio/SimApdu.aidl b/radio/aidl/android/hardware/radio/sim/SimApdu.aidl similarity index 97% rename from radio/aidl/android/hardware/radio/SimApdu.aidl rename to radio/aidl/android/hardware/radio/sim/SimApdu.aidl index 65dae4c72e..1dc707ecb9 100644 --- a/radio/aidl/android/hardware/radio/SimApdu.aidl +++ b/radio/aidl/android/hardware/radio/sim/SimApdu.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.sim; @VintfStability parcelable SimApdu { diff --git a/radio/aidl/android/hardware/radio/SimLockMultiSimPolicy.aidl b/radio/aidl/android/hardware/radio/sim/SimLockMultiSimPolicy.aidl similarity index 96% rename from radio/aidl/android/hardware/radio/SimLockMultiSimPolicy.aidl rename to radio/aidl/android/hardware/radio/sim/SimLockMultiSimPolicy.aidl index 89e13fd27b..6c031220d9 100644 --- a/radio/aidl/android/hardware/radio/SimLockMultiSimPolicy.aidl +++ b/radio/aidl/android/hardware/radio/sim/SimLockMultiSimPolicy.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.sim; @VintfStability @Backing(type="int") diff --git a/radio/aidl/android/hardware/radio/SimRefreshResult.aidl b/radio/aidl/android/hardware/radio/sim/SimRefreshResult.aidl similarity index 73% rename from radio/aidl/android/hardware/radio/SimRefreshResult.aidl rename to radio/aidl/android/hardware/radio/sim/SimRefreshResult.aidl index 9e38fff6b0..483a54c611 100644 --- a/radio/aidl/android/hardware/radio/SimRefreshResult.aidl +++ b/radio/aidl/android/hardware/radio/sim/SimRefreshResult.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.sim; @VintfStability parcelable SimRefreshResult { @@ -40,10 +40,11 @@ parcelable SimRefreshResult { */ int efId; /** - * AID(application ID) of the card application. See ETSI 102.221 8.1 and 101.220 4. - * For SIM_FILE_UPDATE result it must be set to AID of application in which updated EF resides - * or it must be empty string if EF is outside of an application. For SIM_INIT result this field - * is set to AID of application that caused REFRESH. For SIM_RESET result it is empty string. + * AID (application ID) of the card application. See ETSI 102.221 8.1 and 101.220 4. + * For TYPE_SIM_FILE_UPDATE result, it must be set to AID of application in which updated EF + * resides or it must be empty string if EF is outside of an application. For TYPE_SIM_INIT + * result, this field is set to AID of application that caused REFRESH. For TYPE_SIM_RESET + * result, it is empty string. */ String aid; } diff --git a/radio/aidl/android/hardware/radio/AudioQuality.aidl b/radio/aidl/android/hardware/radio/voice/AudioQuality.aidl similarity index 97% rename from radio/aidl/android/hardware/radio/AudioQuality.aidl rename to radio/aidl/android/hardware/radio/voice/AudioQuality.aidl index bc4c2f1201..94d5f880b7 100644 --- a/radio/aidl/android/hardware/radio/AudioQuality.aidl +++ b/radio/aidl/android/hardware/radio/voice/AudioQuality.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.voice; /** * Audio codec which is used on GSM, UMTS, and CDMA. These values must be opaque to the Android diff --git a/radio/aidl/android/hardware/radio/Call.aidl b/radio/aidl/android/hardware/radio/voice/Call.aidl similarity index 94% rename from radio/aidl/android/hardware/radio/Call.aidl rename to radio/aidl/android/hardware/radio/voice/Call.aidl index 467a5b9514..beb079b838 100644 --- a/radio/aidl/android/hardware/radio/Call.aidl +++ b/radio/aidl/android/hardware/radio/voice/Call.aidl @@ -14,10 +14,10 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.voice; -import android.hardware.radio.AudioQuality; -import android.hardware.radio.UusInfo; +import android.hardware.radio.voice.AudioQuality; +import android.hardware.radio.voice.UusInfo; @VintfStability parcelable Call { diff --git a/radio/aidl/android/hardware/radio/CallForwardInfo.aidl b/radio/aidl/android/hardware/radio/voice/CallForwardInfo.aidl similarity index 83% rename from radio/aidl/android/hardware/radio/CallForwardInfo.aidl rename to radio/aidl/android/hardware/radio/voice/CallForwardInfo.aidl index 18356318f0..b7ddcd9fac 100644 --- a/radio/aidl/android/hardware/radio/CallForwardInfo.aidl +++ b/radio/aidl/android/hardware/radio/voice/CallForwardInfo.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.voice; /** * See also com.android.internal.telephony.gsm.CallForwardInfo @@ -28,8 +28,9 @@ parcelable CallForwardInfo { const int STATUS_ERASURE = 4; /** - * For queryCallForwardStatus() status is DISABLE (Not used by vendor code currently) - * For setCallForward() status must be DISABLE, ENABLE, INTERROGATE, REGISTRATION, ERASURE + * For queryCallForwardStatus() status is STATUS_DISABLE (Not used by vendor code currently) + * For setCallForward() status must be STATUS_DISABLE, STATUS_ENABLE, STATUS_INTERROGATE, + * STATUS_REGISTRATION, STATUS_ERASURE * Values are STATUS_ */ int status; diff --git a/radio/aidl/android/hardware/radio/CdmaCallWaiting.aidl b/radio/aidl/android/hardware/radio/voice/CdmaCallWaiting.aidl similarity index 94% rename from radio/aidl/android/hardware/radio/CdmaCallWaiting.aidl rename to radio/aidl/android/hardware/radio/voice/CdmaCallWaiting.aidl index b08ba7f125..7ba6a72744 100644 --- a/radio/aidl/android/hardware/radio/CdmaCallWaiting.aidl +++ b/radio/aidl/android/hardware/radio/voice/CdmaCallWaiting.aidl @@ -14,9 +14,9 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.voice; -import android.hardware.radio.CdmaSignalInfoRecord; +import android.hardware.radio.voice.CdmaSignalInfoRecord; @VintfStability parcelable CdmaCallWaiting { diff --git a/radio/aidl/android/hardware/radio/CdmaDisplayInfoRecord.aidl b/radio/aidl/android/hardware/radio/voice/CdmaDisplayInfoRecord.aidl similarity index 97% rename from radio/aidl/android/hardware/radio/CdmaDisplayInfoRecord.aidl rename to radio/aidl/android/hardware/radio/voice/CdmaDisplayInfoRecord.aidl index 9b11f37c6d..18a1ce4977 100644 --- a/radio/aidl/android/hardware/radio/CdmaDisplayInfoRecord.aidl +++ b/radio/aidl/android/hardware/radio/voice/CdmaDisplayInfoRecord.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.voice; /** * Display Info Rec as defined in C.S0005 section 3.7.5.1. Extended Display Info Rec as defined in diff --git a/radio/aidl/android/hardware/radio/CdmaInformationRecord.aidl b/radio/aidl/android/hardware/radio/voice/CdmaInformationRecord.aidl similarity index 81% rename from radio/aidl/android/hardware/radio/CdmaInformationRecord.aidl rename to radio/aidl/android/hardware/radio/voice/CdmaInformationRecord.aidl index 20eabffb96..af37dac3ec 100644 --- a/radio/aidl/android/hardware/radio/CdmaInformationRecord.aidl +++ b/radio/aidl/android/hardware/radio/voice/CdmaInformationRecord.aidl @@ -14,15 +14,15 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.voice; -import android.hardware.radio.CdmaDisplayInfoRecord; -import android.hardware.radio.CdmaLineControlInfoRecord; -import android.hardware.radio.CdmaNumberInfoRecord; -import android.hardware.radio.CdmaRedirectingNumberInfoRecord; -import android.hardware.radio.CdmaSignalInfoRecord; -import android.hardware.radio.CdmaT53AudioControlInfoRecord; -import android.hardware.radio.CdmaT53ClirInfoRecord; +import android.hardware.radio.voice.CdmaDisplayInfoRecord; +import android.hardware.radio.voice.CdmaLineControlInfoRecord; +import android.hardware.radio.voice.CdmaNumberInfoRecord; +import android.hardware.radio.voice.CdmaRedirectingNumberInfoRecord; +import android.hardware.radio.voice.CdmaSignalInfoRecord; +import android.hardware.radio.voice.CdmaT53AudioControlInfoRecord; +import android.hardware.radio.voice.CdmaT53ClirInfoRecord; @VintfStability parcelable CdmaInformationRecord { diff --git a/radio/aidl/android/hardware/radio/CdmaInformationRecords.aidl b/radio/aidl/android/hardware/radio/voice/CdmaInformationRecords.aidl similarity index 89% rename from radio/aidl/android/hardware/radio/CdmaInformationRecords.aidl rename to radio/aidl/android/hardware/radio/voice/CdmaInformationRecords.aidl index dcf0ed20ac..46a9b1a81c 100644 --- a/radio/aidl/android/hardware/radio/CdmaInformationRecords.aidl +++ b/radio/aidl/android/hardware/radio/voice/CdmaInformationRecords.aidl @@ -14,9 +14,9 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.voice; -import android.hardware.radio.CdmaInformationRecord; +import android.hardware.radio.voice.CdmaInformationRecord; @VintfStability parcelable CdmaInformationRecords { diff --git a/radio/aidl/android/hardware/radio/CdmaLineControlInfoRecord.aidl b/radio/aidl/android/hardware/radio/voice/CdmaLineControlInfoRecord.aidl similarity index 95% rename from radio/aidl/android/hardware/radio/CdmaLineControlInfoRecord.aidl rename to radio/aidl/android/hardware/radio/voice/CdmaLineControlInfoRecord.aidl index a6178afd52..c3bda23013 100644 --- a/radio/aidl/android/hardware/radio/CdmaLineControlInfoRecord.aidl +++ b/radio/aidl/android/hardware/radio/voice/CdmaLineControlInfoRecord.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.voice; /** * Line Control Information Record as defined in C.S0005 section 3.7.5.15 diff --git a/radio/aidl/android/hardware/radio/CdmaNumberInfoRecord.aidl b/radio/aidl/android/hardware/radio/voice/CdmaNumberInfoRecord.aidl similarity index 90% rename from radio/aidl/android/hardware/radio/CdmaNumberInfoRecord.aidl rename to radio/aidl/android/hardware/radio/voice/CdmaNumberInfoRecord.aidl index 06e8317bd0..41ce08f441 100644 --- a/radio/aidl/android/hardware/radio/CdmaNumberInfoRecord.aidl +++ b/radio/aidl/android/hardware/radio/voice/CdmaNumberInfoRecord.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.voice; /** * Called Party Number Info Rec as defined in C.S0005 section 3.7.5.2 @@ -24,7 +24,7 @@ package android.hardware.radio; @VintfStability parcelable CdmaNumberInfoRecord { /** - * Max length = RADIO_CDMA_NUMBER_INFO_BUFFER_LENGTH + * Max length = RadioConst::CDMA_NUMBER_INFO_BUFFER_LENGTH */ String number; byte numberType; diff --git a/radio/aidl/android/hardware/radio/CdmaOtaProvisionStatus.aidl b/radio/aidl/android/hardware/radio/voice/CdmaOtaProvisionStatus.aidl similarity index 96% rename from radio/aidl/android/hardware/radio/CdmaOtaProvisionStatus.aidl rename to radio/aidl/android/hardware/radio/voice/CdmaOtaProvisionStatus.aidl index 0cb43141f6..7b4205ac6f 100644 --- a/radio/aidl/android/hardware/radio/CdmaOtaProvisionStatus.aidl +++ b/radio/aidl/android/hardware/radio/voice/CdmaOtaProvisionStatus.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.voice; @VintfStability @Backing(type="int") diff --git a/radio/aidl/android/hardware/radio/CdmaRedirectingNumberInfoRecord.aidl b/radio/aidl/android/hardware/radio/voice/CdmaRedirectingNumberInfoRecord.aidl similarity index 93% rename from radio/aidl/android/hardware/radio/CdmaRedirectingNumberInfoRecord.aidl rename to radio/aidl/android/hardware/radio/voice/CdmaRedirectingNumberInfoRecord.aidl index 7ba272b8a6..f3bcc0f9b6 100644 --- a/radio/aidl/android/hardware/radio/CdmaRedirectingNumberInfoRecord.aidl +++ b/radio/aidl/android/hardware/radio/voice/CdmaRedirectingNumberInfoRecord.aidl @@ -14,9 +14,9 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.voice; -import android.hardware.radio.CdmaNumberInfoRecord; +import android.hardware.radio.voice.CdmaNumberInfoRecord; @VintfStability parcelable CdmaRedirectingNumberInfoRecord { diff --git a/radio/aidl/android/hardware/radio/CdmaSignalInfoRecord.aidl b/radio/aidl/android/hardware/radio/voice/CdmaSignalInfoRecord.aidl similarity index 96% rename from radio/aidl/android/hardware/radio/CdmaSignalInfoRecord.aidl rename to radio/aidl/android/hardware/radio/voice/CdmaSignalInfoRecord.aidl index 36ecb1813d..5fc877680c 100644 --- a/radio/aidl/android/hardware/radio/CdmaSignalInfoRecord.aidl +++ b/radio/aidl/android/hardware/radio/voice/CdmaSignalInfoRecord.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.voice; /** * CDMA Signal Information Record as defined in C.S0005 section 3.7.5.5 diff --git a/radio/aidl/android/hardware/radio/CdmaT53AudioControlInfoRecord.aidl b/radio/aidl/android/hardware/radio/voice/CdmaT53AudioControlInfoRecord.aidl similarity index 95% rename from radio/aidl/android/hardware/radio/CdmaT53AudioControlInfoRecord.aidl rename to radio/aidl/android/hardware/radio/voice/CdmaT53AudioControlInfoRecord.aidl index 715a2f7b2c..c41f8e365a 100644 --- a/radio/aidl/android/hardware/radio/CdmaT53AudioControlInfoRecord.aidl +++ b/radio/aidl/android/hardware/radio/voice/CdmaT53AudioControlInfoRecord.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.voice; /** * T53 Audio Control Information Record diff --git a/radio/aidl/android/hardware/radio/CdmaT53ClirInfoRecord.aidl b/radio/aidl/android/hardware/radio/voice/CdmaT53ClirInfoRecord.aidl similarity index 95% rename from radio/aidl/android/hardware/radio/CdmaT53ClirInfoRecord.aidl rename to radio/aidl/android/hardware/radio/voice/CdmaT53ClirInfoRecord.aidl index 636d40c48a..e37a072258 100644 --- a/radio/aidl/android/hardware/radio/CdmaT53ClirInfoRecord.aidl +++ b/radio/aidl/android/hardware/radio/voice/CdmaT53ClirInfoRecord.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.voice; /** * T53 CLIR Information Record diff --git a/radio/aidl/android/hardware/radio/CfData.aidl b/radio/aidl/android/hardware/radio/voice/CfData.aidl similarity index 90% rename from radio/aidl/android/hardware/radio/CfData.aidl rename to radio/aidl/android/hardware/radio/voice/CfData.aidl index c6a91b9807..8d7c4bd813 100644 --- a/radio/aidl/android/hardware/radio/CfData.aidl +++ b/radio/aidl/android/hardware/radio/voice/CfData.aidl @@ -14,9 +14,9 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.voice; -import android.hardware.radio.CallForwardInfo; +import android.hardware.radio.voice.CallForwardInfo; @VintfStability parcelable CfData { diff --git a/radio/aidl/android/hardware/radio/ClipStatus.aidl b/radio/aidl/android/hardware/radio/voice/ClipStatus.aidl similarity index 95% rename from radio/aidl/android/hardware/radio/ClipStatus.aidl rename to radio/aidl/android/hardware/radio/voice/ClipStatus.aidl index c75c609092..4b10ecc5d0 100644 --- a/radio/aidl/android/hardware/radio/ClipStatus.aidl +++ b/radio/aidl/android/hardware/radio/voice/ClipStatus.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.voice; @VintfStability @Backing(type="int") diff --git a/radio/aidl/android/hardware/radio/Dial.aidl b/radio/aidl/android/hardware/radio/voice/Dial.aidl similarity index 92% rename from radio/aidl/android/hardware/radio/Dial.aidl rename to radio/aidl/android/hardware/radio/voice/Dial.aidl index f4097ff696..7d61fe5fe0 100644 --- a/radio/aidl/android/hardware/radio/Dial.aidl +++ b/radio/aidl/android/hardware/radio/voice/Dial.aidl @@ -14,9 +14,9 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.voice; -import android.hardware.radio.UusInfo; +import android.hardware.radio.voice.UusInfo; @VintfStability parcelable Dial { diff --git a/radio/aidl/android/hardware/radio/EmergencyCallRouting.aidl b/radio/aidl/android/hardware/radio/voice/EmergencyCallRouting.aidl similarity index 96% rename from radio/aidl/android/hardware/radio/EmergencyCallRouting.aidl rename to radio/aidl/android/hardware/radio/voice/EmergencyCallRouting.aidl index a915ee69ce..75a41c9c36 100644 --- a/radio/aidl/android/hardware/radio/EmergencyCallRouting.aidl +++ b/radio/aidl/android/hardware/radio/voice/EmergencyCallRouting.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.voice; /** * Indicates how the implementation should handle the emergency call if it is required by Android. diff --git a/radio/aidl/android/hardware/radio/EmergencyNumber.aidl b/radio/aidl/android/hardware/radio/voice/EmergencyNumber.aidl similarity index 97% rename from radio/aidl/android/hardware/radio/EmergencyNumber.aidl rename to radio/aidl/android/hardware/radio/voice/EmergencyNumber.aidl index 152be90fdf..aa4dde2893 100644 --- a/radio/aidl/android/hardware/radio/EmergencyNumber.aidl +++ b/radio/aidl/android/hardware/radio/voice/EmergencyNumber.aidl @@ -14,9 +14,9 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.voice; -import android.hardware.radio.EmergencyServiceCategory; +import android.hardware.radio.voice.EmergencyServiceCategory; /** * Emergency number contains information of number, one or more service category(s), zero or more diff --git a/radio/aidl/android/hardware/radio/EmergencyServiceCategory.aidl b/radio/aidl/android/hardware/radio/voice/EmergencyServiceCategory.aidl similarity index 97% rename from radio/aidl/android/hardware/radio/EmergencyServiceCategory.aidl rename to radio/aidl/android/hardware/radio/voice/EmergencyServiceCategory.aidl index 30d34ab210..cfebc47e35 100644 --- a/radio/aidl/android/hardware/radio/EmergencyServiceCategory.aidl +++ b/radio/aidl/android/hardware/radio/voice/EmergencyServiceCategory.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.voice; /** * Defining Emergency Service Category as follows: diff --git a/radio/aidl/android/hardware/radio/voice/IRadioVoice.aidl b/radio/aidl/android/hardware/radio/voice/IRadioVoice.aidl new file mode 100644 index 0000000000..1e60de509d --- /dev/null +++ b/radio/aidl/android/hardware/radio/voice/IRadioVoice.aidl @@ -0,0 +1,443 @@ +/* + * 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.radio.voice; + +import android.hardware.radio.voice.CallForwardInfo; +import android.hardware.radio.voice.Dial; +import android.hardware.radio.voice.EmergencyCallRouting; +import android.hardware.radio.voice.EmergencyServiceCategory; +import android.hardware.radio.voice.IRadioVoiceIndication; +import android.hardware.radio.voice.IRadioVoiceResponse; +import android.hardware.radio.voice.TtyMode; + +/** + * This interface is used by telephony and telecom to talk to cellular radio for voice APIs. + * All the functions have minimum one parameter: + * serial: which corresponds to serial no. of request. Serial numbers must only be memorized for the + * duration of a method call. If clients provide colliding serials (including passing the same + * serial to different methods), multiple responses (one for each method call) must still be served. + * setResponseFunctions must work with IRadioVoiceResponse and IRadioVoiceIndication. + */ +@VintfStability +oneway interface IRadioVoice { + /** + * Answer incoming call. Must not be called for WAITING calls. + * switchWaitingOrHoldingAndActive() must be used in this case instead + * + * @param serial Serial number of request. + * + * Response function is IRadioVoiceResponse.acceptCallResponse() + */ + void acceptCall(in int serial); + + /** + * Conference holding and active (like AT+CHLD=3) + * + * @param serial Serial number of request. + * + * Response function is IRadioVoiceResponse.conferenceResponse() + */ + void conference(in int serial); + + /** + * Initiate voice call. This method is never used for supplementary service codes. + * + * @param serial Serial number of request. + * @param dialInfo Dial struct + * + * Response function is IRadioVoiceResponse.dialResponse() + */ + void dial(in int serial, in Dial dialInfo); + + /** + * Initiate emergency voice call, with zero or more emergency service category(s), zero or + * more emergency Uniform Resource Names (URN), and routing information for handling the call. + * Android uses this request to make its emergency call instead of using IRadio.dial if the + * 'address' in the 'dialInfo' field is identified as an emergency number by Android. + * + * In multi-sim scenario, if the emergency number is from a specific subscription, this radio + * request can still be sent out on the other subscription as long as routing is set to + * EmergencyNumberRouting#EMERGENCY. This radio request will not be sent on an inactive + * (PIN/PUK locked) subscription unless both subscriptions are PIN/PUK locked. In this case, + * the request will be sent on the primary subscription. + * + * Some countries or carriers require some emergency numbers that must be handled with normal + * call routing if possible or emergency routing. 1) if the 'routing' field is specified as + * EmergencyNumberRouting#NORMAL, the implementation must try the full radio service to use + * normal call routing to handle the call; if service cannot support normal routing, the + * implementation must use emergency routing to handle the call. 2) if 'routing' is specified + * as EmergencyNumberRouting#EMERGENCY, the implementation must use emergency routing to handle + * the call. 3) if 'routing' is specified as EmergencyNumberRouting#UNKNOWN, Android does not + * know how to handle the call. + * + * If the dialed emergency number does not have a specified emergency service category, the + * 'categories' field is set to EmergencyServiceCategory#UNSPECIFIED; if the dialed emergency + * number does not have specified emergency Uniform Resource Names, the 'urns' field is set to + * an empty list. If the underlying technology used to request emergency services does not + * support the emergency service category or emergency uniform resource names, the field + * 'categories' or 'urns' may be ignored. + * + * In the scenarios that the 'address' in the 'dialInfo' field has other functions besides the + * emergency number function, if the 'hasKnownUserIntentEmergency' field is true, the user's + * intent for this dial request is emergency call, and the modem must treat this as an actual + * emergency dial; if the 'hasKnownUserIntentEmergency' field is false, Android does not know + * user's intent for this call. + * + * If 'isTesting' is true, this request is for testing purpose, and must not be sent to a real + * emergency service; otherwise it's for a real emergency call request. + * + * Reference: 3gpp 22.101, Section 10 - Emergency Calls; + * 3gpp 23.167, Section 6 - Functional description; + * 3gpp 24.503, Section 5.1.6.8.1 - General; + * RFC 5031 + * + * @param serial Serial number of request. + * @param dialInfo the same Dial information used by IRadioVoice.dial. + * @param categories bitfield the Emergency Service Category(s) + * of the call. + * @param urns the emergency Uniform Resource Names (URN) + * @param routing EmergencyCallRouting the emergency call routing information. + * @param hasKnownUserIntentEmergency Flag indicating if user's intent for the emergency call + * is known. + * @param isTesting Flag indicating if this request is for testing purpose. + * + * Response function is IRadioVoiceResponse.emergencyDialResponse() + */ + void emergencyDial(in int serial, in Dial dialInfo, in EmergencyServiceCategory categories, + in String[] urns, in EmergencyCallRouting routing, + in boolean hasKnownUserIntentEmergency, in boolean isTesting); + + /** + * Request the radio's system selection module to exit emergency callback mode. Radio must not + * respond with SUCCESS until the modem has completely exited from Emergency Callback Mode. + * + * @param serial Serial number of request. + * + * Response function is IRadioVoiceResponse.exitEmergencyCallbackModeResponse() + */ + void exitEmergencyCallbackMode(in int serial); + + /** + * Connects the two calls and disconnects the subscriber from both calls. + * + * @param serial Serial number of request. + * + * Response function is IRadioVoiceResponse.explicitCallTransferResponse() + */ + void explicitCallTransfer(in int serial); + + /** + * Request call forward status. + * + * @param serial Serial number of request. + * @param callInfo CallForwardInfo + * + * Response function is IRadioVoiceResponse.getCallForwardStatusResponse() + */ + void getCallForwardStatus(in int serial, in CallForwardInfo callInfo); + + /** + * Query current call waiting state + * + * @param serial Serial number of request. + * @param serviceClass Service class is the TS 27.007 service class to query + * + * Response function is IRadioVoiceResponse.getCallWaitingResponse() + */ + void getCallWaiting(in int serial, in int serviceClass); + + /** + * Queries the status of the CLIP supplementary service (for MMI code "*#30#") + * + * @param serial Serial number of request. + * + * Response function is IRadioVoiceResponse.getClipResponse() + */ + void getClip(in int serial); + + /** + * Gets current CLIR status + * + * @param serial Serial number of request. + * + * Response function is IRadioVoiceResponse.getClirResponse() + */ + void getClir(in int serial); + + /** + * Requests current call list + * + * @param serial Serial number of request. + * + * Response function is IRadioVoiceResponse.getCurrentCallsResponse() + */ + void getCurrentCalls(in int serial); + + /** + * Requests the failure cause code for the most recently terminated call. + * + * @param serial Serial number of request. + * + * Response function is IRadioVoiceResponse.getLastCallFailCauseResponse() + */ + void getLastCallFailCause(in int serial); + + /** + * Queries the current state of the uplink mute setting + * + * @param serial Serial number of request. + * + * Response function is IRadioVoiceResponse.getMuteResponse() + */ + void getMute(in int serial); + + /** + * Request the setting of preferred voice privacy mode. + * + * @param serial Serial number of request. + * + * Response function is IRadioVoiceResponse.getPreferredVoicePrivacyResponse() + */ + void getPreferredVoicePrivacy(in int serial); + + /** + * Request the setting of TTY mode + * + * @param serial Serial number of request. + * + * Response function is IRadioVoiceResponse.getTtyModeResponse() + */ + void getTtyMode(in int serial); + + /** + * When STK application gets stkCallSetup(), the call actually has been initialized by the + * mobile device already. (We could see the call has been in the 'call list'). STK application + * needs to accept/reject the call according to user operations. + * + * @param serial Serial number of request. + * @param accept true = accept the call setup, false = reject the call setup + * + * Response function is IRadioVoiceResponse.handleStkCallSetupRequestFromSimResponse() + */ + void handleStkCallSetupRequestFromSim(in int serial, in boolean accept); + + /** + * Hang up a specific line (like AT+CHLD=1x). After this HANGUP request returns, Radio must + * show the connection is NOT active anymore in next getCurrentCalls() query. + * + * @param serial Serial number of request. + * @param gsmIndex Connection index (value of 'x' in CHLD above) + * + * Response function is IRadioVoiceResponse.hangupResponse() + */ + void hangup(in int serial, in int gsmIndex); + + /** + * Hang up waiting or held (like AT+CHLD=1). After this HANGUP request returns, Radio must show + * the connection is NOT active anymore in next getCurrentCalls() query. + * + * @param serial Serial number of request. + * + * Response function is IRadioVoiceResponse.hangupForegroundResumeBackgroundResponse() + */ + void hangupForegroundResumeBackground(in int serial); + + /** + * Hang up waiting or held (like AT+CHLD=0). After this HANGUP request returns, Radio must show + * the connection is NOT active anymore in next getCurrentCalls() query. + * + * @param serial Serial number of request. + * + * Response function is IRadioVoiceResponse.hangupWaitingOrBackgroundResponse() + */ + void hangupWaitingOrBackground(in int serial); + + /** + * Send UDUB (user determined user busy) to ringing or waiting call answer) + * + * @param serial Serial number of request. + * + * Response function is IRadioVoiceResponse.rejectCallResponse() + */ + void rejectCall(in int serial); + + /** + * When response type received from a radio indication or radio response is + * RadioIndicationType:UNSOLICITED_ACK_EXP or RadioResponseType:SOLICITED_ACK_EXP respectively, + * acknowledge the receipt of those messages by sending responseAcknowledgement(). + */ + void responseAcknowledgement(); + + /** + * Send DTMF string + * + * @param serial Serial number of request. + * @param dtmf DTMF string + * @param on DTMF ON length in milliseconds, or 0 to use default + * @param off is the DTMF OFF length in milliseconds, or 0 to use default + * + * Response function is IRadioVoiceResponse.sendBurstDtmfResponse() + */ + void sendBurstDtmf(in int serial, in String dtmf, in int on, in int off); + + /** + * Send FLASH command + * + * @param serial Serial number of request. + * @param featureCode String associated with Flash command + * + * Response function is IRadioVoiceResponse.sendCdmaFeatureCodeResponse() + */ + void sendCdmaFeatureCode(in int serial, in String featureCode); + + /** + * Send a DTMF tone. If the implementation is currently playing a tone requested via + * startDtmf(), that tone must be cancelled and the new tone must be played instead. + * + * @param serial Serial number of request. + * @param s string with single char having one of 12 values: 0-9, *, # + * + * Response function is IRadioVoiceResponse.sendDtmfResponse() + */ + void sendDtmf(in int serial, in String s); + + /** + * Separate a party from a multiparty call placing the multiparty call (less the specified + * party) on hold and leaving the specified party as the only other member of the current + * (active) call. Like AT+CHLD=2x. + * + * See TS 22.084 1.3.8.2 (iii) + * TS 22.030 6.5.5 "Entering "2X followed by send" + * TS 27.007 "AT+CHLD=2x" + * + * @param serial Serial number of request. + * @param gsmIndex contains Connection index (value of 'x' in CHLD above) + * + * Response function is IRadioVoiceResponse.separateConnectionResponse() + */ + void separateConnection(in int serial, in int gsmIndex); + + /** + * Configure call forward rule + * + * @param serial Serial number of request. + * @param callInfo CallForwardInfo + * + * Response function is IRadioVoiceResponse.setCallForwardResponse() + */ + void setCallForward(in int serial, in CallForwardInfo callInfo); + + /** + * Configure current call waiting state + * + * @param serial Serial number of request. + * @param enable is false for "disabled" and true for "enabled" + * @param serviceClass is the TS 27.007 service class bit vector of services to modify + * + * Response function is IRadioVoiceResponse.setCallWaitingResponse() + */ + void setCallWaiting(in int serial, in boolean enable, in int serviceClass); + + /** + * Set current CLIR status + * + * @param serial Serial number of request. + * @param status "n" parameter from TS 27.007 7.7 + * + * Response function is IRadioVoiceResponse.setClirResponse() + */ + void setClir(in int serial, in int status); + + /** + * Turn on or off uplink (microphone) mute. Must only be sent while voice call is active. + * Must always be reset to "disable mute" when a new voice call is initiated + * + * @param serial Serial number of request. + * @param enable true for "enable mute" and false for "disable mute" + * + * Response function is IRadioVoiceResponse.setMuteResponse() + */ + void setMute(in int serial, in boolean enable); + + /** + * Request to set the preferred voice privacy mode used in voice scrambling. + * + * @param serial Serial number of request. + * @param enable false for Standard Privacy Mode (Public Long Code Mask) + * true for Enhanced Privacy Mode (Private Long Code Mask) + * + * Response function is IRadioVoiceResponse.setPreferredVoicePrivacyResponse() + */ + void setPreferredVoicePrivacy(in int serial, in boolean enable); + + /** + * Set response functions for voice radio requests and indications. + * + * @param radioVoiceResponse Object containing response functions + * @param radioVoiceIndication Object containing radio indications + */ + void setResponseFunctions(in IRadioVoiceResponse radioVoiceResponse, + in IRadioVoiceIndication radioVoiceIndication); + + /** + * Request to set the TTY mode + * + * @param serial Serial number of request. + * @param mode TtyMode + * + * Response function is IRadioVoiceResponse.setTtyModeResponse() + */ + void setTtyMode(in int serial, in TtyMode mode); + + /** + * Start playing a DTMF tone. Continue playing DTMF tone until stopDtmf is received. If a + * startDtmf() is received while a tone is currently playing, it must cancel the previous tone + * and play the new one. + * + * @param serial Serial number of request. + * @param s string having a single character with one of 12 values: 0-9,*,# + * + * Response function is IRadioVoiceResponse.startDtmfResponse() + */ + void startDtmf(in int serial, in String s); + + /** + * Stop playing a currently playing DTMF tone. + * + * @param serial Serial number of request. + * + * Response function is IRadioVoiceResponse.stopDtmfResponse() + */ + void stopDtmf(in int serial); + + /** + * Switch waiting or holding call and active call (like AT+CHLD=2). + * Call transitions must happen as shown below. + * BEFORE AFTER + * Call 1 Call 2 Call 1 Call 2 + * ACTIVE HOLDING HOLDING ACTIVE + * ACTIVE WAITING HOLDING ACTIVE + * HOLDING WAITING HOLDING ACTIVE + * ACTIVE IDLE HOLDING IDLE + * IDLE IDLE IDLE IDLE + * + * @param serial Serial number of request. + * + * Response function is IRadioVoiceResponse.switchWaitingOrHoldingAndActiveResponse() + */ + void switchWaitingOrHoldingAndActive(in int serial); +} diff --git a/radio/aidl/android/hardware/radio/voice/IRadioVoiceIndication.aidl b/radio/aidl/android/hardware/radio/voice/IRadioVoiceIndication.aidl new file mode 100644 index 0000000000..81640f32ea --- /dev/null +++ b/radio/aidl/android/hardware/radio/voice/IRadioVoiceIndication.aidl @@ -0,0 +1,169 @@ +/* + * 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.radio.voice; + +import android.hardware.radio.RadioIndicationType; +import android.hardware.radio.voice.CdmaCallWaiting; +import android.hardware.radio.voice.CdmaInformationRecords; +import android.hardware.radio.voice.CdmaOtaProvisionStatus; +import android.hardware.radio.voice.CdmaSignalInfoRecord; +import android.hardware.radio.voice.EmergencyNumber; +import android.hardware.radio.voice.SrvccState; +import android.hardware.radio.voice.StkCcUnsolSsResult; + +/** + * Interface declaring unsolicited radio indications for voice APIs. + */ +@VintfStability +oneway interface IRadioVoiceIndication { + /** + * Ring indication for an incoming call (eg, RING or CRING event). There must be at least one + * callRing() at the beginning of a call and sending multiple is optional. If the system + * property ro.telephony.call_ring.multiple is false then the upper layers must generate the + * multiple events internally. Otherwise the vendor code must generate multiple callRing() if + * ro.telephony.call_ring.multiple is true or if it is absent. + * The rate of these events is controlled by ro.telephony.call_ring.delay and has a default + * value of 3000 (3 seconds) if absent. + * + * @param type Type of radio indication + * @param isGsm true for GSM & false for CDMA + * @param record Cdma Signal Information + */ + void callRing(in RadioIndicationType type, in boolean isGsm, in CdmaSignalInfoRecord record); + + /** + * Indicates when call state has changed. Callee must invoke IRadioVoice.getCurrentCalls(). + * Must be invoked on, for example, "RING", "BUSY", "NO CARRIER", and also call state + * transitions (DIALING->ALERTING ALERTING->ACTIVE). Redundent or extraneous invocations are + * tolerated. + * + * @param type Type of radio indication + */ + void callStateChanged(in RadioIndicationType type); + + /** + * Indicates when CDMA radio receives a call waiting indication. + * + * @param type Type of radio indication + * @param callWaitingRecord Cdma CallWaiting information + */ + void cdmaCallWaiting(in RadioIndicationType type, in CdmaCallWaiting callWaitingRecord); + + /** + * Indicates when CDMA radio receives one or more info recs. + * + * @param type Type of radio indication + * @param records New Cdma Information + */ + void cdmaInfoRec(in RadioIndicationType type, in CdmaInformationRecords records); + + /** + * Indicates when CDMA radio receives an update of the progress of an OTASP/OTAPA call. + * + * @param type Type of radio indication + * @param status Cdma OTA provision status + */ + void cdmaOtaProvisionStatus(in RadioIndicationType type, in CdmaOtaProvisionStatus status); + + /** + * Report the current list of emergency numbers. Each emergency number in the emergency number + * list contains a dialing number, zero or more service category(s), zero or more emergency + * uniform resource names, mobile country code, mobile network code, and source(s) that indicate + * where it comes from. + * Radio must report all the valid emergency numbers with known mobile country code, mobile + * network code, emergency service categories, and emergency uniform resource names from all + * available sources including network signaling, sim, modem/oem configuration, and default + * configuration (112 and 911 must be always available; additionally, 000, 08, 110, 999, 118 + * and 119 must be available when sim is not present). Radio shall not report emergency numbers + * that are invalid in the current locale. The reported emergency number list must not have + * duplicate EmergencyNumber entries. Please refer the documentation of EmergencyNumber to + * construct each emergency number to report. + * Radio must report the complete list of emergency numbers whenever the emergency numbers in + * the list are changed or whenever the client and the radio server are connected. + * + * Reference: 3gpp 22.101, Section 10 - Emergency Calls; + * 3gpp 24.008, Section 9.2.13.4 - Emergency Number List + * + * @param type Type of radio indication + * @param emergencyNumberList Current list of emergency numbers known to radio. + */ + void currentEmergencyNumberList( + in RadioIndicationType type, in EmergencyNumber[] emergencyNumberList); + + /** + * Indicates that the radio system selection module has autonomously entered emergency + * callback mode. + * + * @param type Type of radio indication + */ + void enterEmergencyCallbackMode(in RadioIndicationType type); + + /** + * Indicates when Emergency Callback Mode ends. Indicates that the radio system selection module + * has proactively exited emergency callback mode. + * + * @param type Type of radio indication + */ + void exitEmergencyCallbackMode(in RadioIndicationType type); + + /** + * Indicates that nework doesn't have in-band information, need to play out-band tone. + * + * @param type Type of radio indication + * @param start true = start play ringback tone, false = stop playing ringback tone + */ + void indicateRingbackTone(in RadioIndicationType type, in boolean start); + + /** + * Indicates when Supplementary service(SS) response is received when DIAL/USSD/SS is changed to + * SS by call control. + * + * @param type Type of radio indication + */ + void onSupplementaryServiceIndication(in RadioIndicationType type, in StkCcUnsolSsResult ss); + + /** + * Indicates that framework/application must reset the uplink mute state. + * + * @param type Type of radio indication + */ + void resendIncallMute(in RadioIndicationType type); + + /** + * Indicates when Single Radio Voice Call Continuity (SRVCC) progress state has changed. + * + * @param type Type of radio indication + * @param state New Srvcc State + */ + void srvccStateNotify(in RadioIndicationType type, in SrvccState state); + + /** + * Indicates when there is an ALPHA from UICC during Call Control. + * + * @param type Type of radio indication + * @param alpha ALPHA string from UICC in UTF-8 format + */ + void stkCallControlAlphaNotify(in RadioIndicationType type, in String alpha); + + /** + * Indicates when SIM wants application to setup a voice call. + * + * @param type Type of radio indication + * @param timeout Timeout value in millisec for setting up voice call + */ + void stkCallSetup(in RadioIndicationType type, in long timeout); +} diff --git a/radio/aidl/android/hardware/radio/voice/IRadioVoiceResponse.aidl b/radio/aidl/android/hardware/radio/voice/IRadioVoiceResponse.aidl new file mode 100644 index 0000000000..f3cf5fba67 --- /dev/null +++ b/radio/aidl/android/hardware/radio/voice/IRadioVoiceResponse.aidl @@ -0,0 +1,751 @@ +/* + * 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.radio.voice; + +import android.hardware.radio.RadioResponseInfo; +import android.hardware.radio.voice.Call; +import android.hardware.radio.voice.CallForwardInfo; +import android.hardware.radio.voice.ClipStatus; +import android.hardware.radio.voice.LastCallFailCauseInfo; +import android.hardware.radio.voice.TtyMode; + +/** + * Interface declaring response functions to solicited radio requests for voice APIs. + */ +@VintfStability +oneway interface IRadioVoiceResponse { + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_STATE + * RadioError:NO_MEMORY + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:INVALID_CALL_ID + * RadioError:INVALID_ARGUMENTS + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + void acceptCallResponse(in RadioResponseInfo info); + + /** + * Acknowledge the receipt of radio request sent to the vendor. This must be sent only for + * radio request which take long time to respond. For more details, refer + * https://source.android.com/devices/tech/connect/ril.html + * + * @param serial Serial no. of the request whose acknowledgement is sent. + */ + void acknowledgeRequest(in int serial); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE (radio resetting) + * RadioError:NO_MEMORY + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:INVALID_STATE + * RadioError:INVALID_CALL_ID + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:INVALID_ARGUMENTS + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_MODEM_STATE + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + void conferenceResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE (radio resetting) + * RadioError:DIAL_MODIFIED_TO_USSD + * RadioError:DIAL_MODIFIED_TO_SS + * RadioError:DIAL_MODIFIED_TO_DIAL + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_MEMORY + * RadioError:INVALID_STATE + * RadioError:NO_RESOURCES + * RadioError:INTERNAL_ERR + * RadioError:FDN_CHECK_FAILURE + * RadioError:MODEM_ERR + * RadioError:NO_SUBSCRIPTION + * RadioError:NO_NETWORK_FOUND + * RadioError:INVALID_CALL_ID + * RadioError:DEVICE_IN_USE + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:ABORTED + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_MODEM_STATE + * RadioError:CANCELLED + */ + void dialResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE (radio resetting) + * RadioError:DIAL_MODIFIED_TO_USSD + * RadioError:DIAL_MODIFIED_TO_SS + * RadioError:DIAL_MODIFIED_TO_DIAL + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_RESOURCES + * RadioError:INTERNAL_ERR + * RadioError:FDN_CHECK_FAILURE + * RadioError:MODEM_ERR + * RadioError:NO_SUBSCRIPTION + * RadioError:NO_NETWORK_FOUND + * RadioError:INVALID_CALL_ID + * RadioError:DEVICE_IN_USE + * RadioError:ABORTED + * RadioError:INVALID_MODEM_STATE + */ + void emergencyDialResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:OPERATION_NO_ALLOWED + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:SYSTEM_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:MODEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:SIM_ABSENT + */ + void exitEmergencyCallbackModeResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:INVALID_STATE + * RadioError:NO_RESOURCES + * RadioError:NO_MEMORY + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:INVALID_CALL_ID + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_MODEM_STATE + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + void explicitCallTransferResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param callForwardInfos points to a vector of CallForwardInfo, one for each distinct + * registered phone number. For example, if data is forwarded to +18005551212 and voice + * is forwarded to +18005559999, then two separate CallForwardInfo's must be returned. + * However, if both data and voice are forwarded to +18005551212, then a single + * CallForwardInfo must be returned with the service class set to "data + voice = 3". + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SS_MODIFIED_TO_DIAL + * RadioError:SS_MODIFIED_TO_USSD + * RadioError:SS_MODIFIED_TO_SS + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_MEMORY + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:FDN_CHECK_FAILURE + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:SYSTEM_ERR + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + void getCallForwardStatusResponse( + in RadioResponseInfo info, in CallForwardInfo[] callForwardInfos); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param enable If current call waiting state is disabled, enable = false else true + * @param serviceClass If enable, then callWaitingResp[1] must follow, with the TS 27.007 + * service class bit vector of services for which call waiting is enabled. For example, + * if callWaitingResp[0] is 1 and callWaitingResp[1] is 3, then call waiting is enabled + * for data and voice and disabled for everything else. + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SS_MODIFIED_TO_DIAL + * RadioError:SS_MODIFIED_TO_USSD + * RadioError:SS_MODIFIED_TO_SS + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_MEMORY + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:FDN_CHECK_FAILURE + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + void getCallWaitingResponse(in RadioResponseInfo info, in boolean enable, in int serviceClass); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param status indicates CLIP status + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_MEMORY + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:FDN_CHECK_FAILURE + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + void getClipResponse(in RadioResponseInfo info, in ClipStatus status); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param n is "n" parameter from TS 27.007 7.7 + * @param m is "m" parameter from TS 27.007 7.7 + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SS_MODIFIED_TO_DIAL + * RadioError:SS_MODIFIED_TO_USSD + * RadioError:SS_MODIFIED_TO_SS + * RadioError:NO_MEMORY + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:FDN_CHECK_FAILURE + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + void getClirResponse(in RadioResponseInfo info, in int n, in int m); + + /** + * @param info Response info struct containing respontype, serial no. and error + * @param calls Current call list + * + * Valid errors returned: + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + void getCurrentCallsResponse(in RadioResponseInfo info, in Call[] calls); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param failCauseInfo Contains LastCallFailCause and vendor cause code. + * + * The vendor cause code must be used for debugging purpose only. The implementation must return + * one of the values of LastCallFailCause as mentioned below. + * GSM failure reasons codes for the cause codes defined in TS 24.008 Annex H where possible. + * CDMA failure reasons codes for the possible call failure scenarios described in the + * "CDMA IS-2000 Release A (C.S0005-A v6.0)" standard. + * Any of the following reason codes if the call is failed or dropped due to reason mentioned + * with in the braces. + * LastCallFailCause:RADIO_OFF (Radio is OFF) + * LastCallFailCause:OUT_OF_SERVICE (No cell coverage) + * LastCallFailCause:NO_VALID_SIM (No valid SIM) + * LastCallFailCause:RADIO_INTERNAL_ERROR (Modem hit unexpected error scenario) + * LastCallFailCause:NETWORK_RESP_TIMEOUT (No response from network) + * LastCallFailCause:NETWORK_REJECT (Explicit network reject) + * LastCallFailCause:RADIO_ACCESS_FAILURE (RRC connection failure. Eg.RACH) + * LastCallFailCause:RADIO_LINK_FAILURE (Radio Link Failure) + * LastCallFailCause:RADIO_LINK_LOST (Radio link lost due to poor coverage) + * LastCallFailCause:RADIO_UPLINK_FAILURE (Radio uplink failure) + * LastCallFailCause:RADIO_SETUP_FAILURE (RRC connection setup failure) + * LastCallFailCause:RADIO_RELEASE_NORMAL (RRC connection release, normal) + * LastCallFailCause:RADIO_RELEASE_ABNORMAL (RRC connection release, abnormal) + * LastCallFailCause:ACCESS_CLASS_BLOCKED (Access class barring) + * LastCallFailCause:NETWORK_DETACH (Explicit network detach) + * OEM causes (LastCallFailCause:OEM_CAUSE_XX) must be used for debug purpose only + * + * If the implementation does not have access to the exact cause codes, then it must return one + * of the values listed in LastCallFailCause, as the UI layer needs to distinguish these cases + * for tone generation or error notification. + * + * Valid errors returned: + * RadioError:NONE + * RadioError:NO_MEMORY + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SYSTEM_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:INTERNAL_ERR + * RadioError:MODEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_MEMORY + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + void getLastCallFailCauseResponse( + in RadioResponseInfo info, in LastCallFailCauseInfo failCauseinfo); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param enable true for "mute enabled" and false for "mute disabled" + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SS_MODIFIED_TO_DIAL + * RadioError:SS_MODIFIED_TO_USSD + * RadioError:SS_MODIFIED_TO_SS + * RadioError:NO_MEMORY + * RadioError:REQUEST_RATE_LIMITED + * RadioError:INVALID_ARGUMENTS + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + void getMuteResponse(in RadioResponseInfo info, in boolean enable); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param enable false for Standard Privacy Mode (Public Long Code Mask) + * true for Enhanced Privacy Mode (Private Long Code Mask) + * + * Valid errors: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + void getPreferredVoicePrivacyResponse(in RadioResponseInfo info, in boolean enable); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param mode TtyMode + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + void getTtyModeResponse(in RadioResponseInfo info, in TtyMode mode); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:SIM_ABSENT + */ + void handleStkCallSetupRequestFromSimResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE (radio resetting) + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_MEMORY + * RadioError:INVALID_STATE + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:INVALID_CALL_ID + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:REQUEST_NOT_SUPPORTED + */ + void hangupConnectionResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE (radio resetting) + * RadioError:INVALID_STATE + * RadioError:NO_MEMORY + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:INVALID_CALL_ID + * RadioError:NO_RESOURCES + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:INVALID_ARGUMENTS + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + void hangupForegroundResumeBackgroundResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE (radio resetting) + * RadioError:INVALID_STATE + * RadioError:NO_MEMORY + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:INVALID_CALL_ID + * RadioError:NO_RESOURCES + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:INVALID_ARGUMENTS + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:CANCELLED + */ + void hangupWaitingOrBackgroundResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE (radio resetting) + * RadioError:INVALID_STATE + * RadioError:NO_RESOURCES + * RadioError:NO_MEMORY + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:INVALID_CALL_ID + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:INVALID_ARGUMENTS + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_MODEM_STATE + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + void rejectCallResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:INVALID_CALL_ID + * RadioError:INVALID_STATE + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:INVALID_MODEM_STATE + * RadioError:OPERATION_NOT_ALLOWED + */ + void sendBurstDtmfResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:INVALID_CALL_ID + * RadioError:INVALID_STATE + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_MODEM_STATE + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + * RadioError:OPERATION_NOT_ALLOWED + */ + void sendCdmaFeatureCodeResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_RESOURCES + * RadioError:NO_MEMORY + * RadioError:MODEM_ERR + * RadioError:INVALID_CALL_ID + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:CANCELLED + * RadioError:INVALID_MODEM_STATE + */ + void sendDtmfResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:INVALID_STATE + * RadioError:NO_RESOURCES + * RadioError:NO_MEMORY + * RadioError:MODEM_ERR + * RadioError:SYSTEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:INVALID_CALL_ID + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_MODEM_STATE + * RadioError:CANCELLED + */ + void separateConnectionResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SS_MODIFIED_TO_DIAL + * RadioError:SS_MODIFIED_TO_USSD + * RadioError:SS_MODIFIED_TO_SS + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_MEMORY + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:INVALID_STATE + * RadioError:FDN_CHECK_FAILURE + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_MODEM_STATE + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + void setCallForwardResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SS_MODIFIED_TO_DIAL + * RadioError:SS_MODIFIED_TO_USSD + * RadioError:SS_MODIFIED_TO_SS + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_MEMORY + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:INVALID_STATE + * RadioError:FDN_CHECK_FAILURE + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_MODEM_STATE + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + void setCallWaitingResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:INVALID_ARGUMENTS + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:SS_MODIFIED_TO_DIAL + * RadioError:SS_MODIFIED_TO_USSD + * RadioError:SS_MODIFIED_TO_SS + * RadioError:NO_MEMORY + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + void setClirResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_MEMORY + * RadioError:REQUEST_RATE_LIMITED + * RadioError:INTERNAL_ERR + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + void setMuteResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_CALL_ID + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + void setPreferredVoicePrivacyResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:NO_MEMORY + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + void setTtyModeResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_RESOURCES + * RadioError:NO_MEMORY + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:INVALID_CALL_ID + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:CANCELLED + * RadioError:INVALID_MODEM_STATE + */ + void startDtmfResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INVALID_ARGUMENTS + * RadioError:NO_RESOURCES + * RadioError:NO_MEMORY + * RadioError:INVALID_ARGUMENTS + * RadioError:SYSTEM_ERR + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:INVALID_CALL_ID + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:CANCELLED + * RadioError:INVALID_MODEM_STATE + */ + void stopDtmfResponse(in RadioResponseInfo info); + + /** + * @param info Response info struct containing response type, serial no. and error + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE (radio resetting) + * RadioError:INVALID_STATE + * RadioError:NO_MEMORY + * RadioError:MODEM_ERR + * RadioError:INTERNAL_ERR + * RadioError:INVALID_STATE + * RadioError:INVALID_CALL_ID + * RadioError:OPERATION_NOT_ALLOWED + * RadioError:INVALID_ARGUMENTS + * RadioError:SYSTEM_ERR + * RadioError:REQUEST_NOT_SUPPORTED + * RadioError:INVALID_MODEM_STATE + * RadioError:NO_RESOURCES + * RadioError:CANCELLED + */ + void switchWaitingOrHoldingAndActiveResponse(in RadioResponseInfo info); +} diff --git a/radio/aidl/android/hardware/radio/LastCallFailCause.aidl b/radio/aidl/android/hardware/radio/voice/LastCallFailCause.aidl similarity index 99% rename from radio/aidl/android/hardware/radio/LastCallFailCause.aidl rename to radio/aidl/android/hardware/radio/voice/LastCallFailCause.aidl index e5a5145fa4..5e328d4bd1 100644 --- a/radio/aidl/android/hardware/radio/LastCallFailCause.aidl +++ b/radio/aidl/android/hardware/radio/voice/LastCallFailCause.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.voice; @VintfStability @Backing(type="int") diff --git a/radio/aidl/android/hardware/radio/LastCallFailCauseInfo.aidl b/radio/aidl/android/hardware/radio/voice/LastCallFailCauseInfo.aidl similarity index 88% rename from radio/aidl/android/hardware/radio/LastCallFailCauseInfo.aidl rename to radio/aidl/android/hardware/radio/voice/LastCallFailCauseInfo.aidl index 6866e99d91..084beddcbb 100644 --- a/radio/aidl/android/hardware/radio/LastCallFailCauseInfo.aidl +++ b/radio/aidl/android/hardware/radio/voice/LastCallFailCauseInfo.aidl @@ -14,9 +14,9 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.voice; -import android.hardware.radio.LastCallFailCause; +import android.hardware.radio.voice.LastCallFailCause; @VintfStability parcelable LastCallFailCauseInfo { diff --git a/radio/aidl/android/hardware/radio/SrvccState.aidl b/radio/aidl/android/hardware/radio/voice/SrvccState.aidl similarity index 95% rename from radio/aidl/android/hardware/radio/SrvccState.aidl rename to radio/aidl/android/hardware/radio/voice/SrvccState.aidl index d4283149f9..ddf75dbbbd 100644 --- a/radio/aidl/android/hardware/radio/SrvccState.aidl +++ b/radio/aidl/android/hardware/radio/voice/SrvccState.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.voice; @VintfStability @Backing(type="int") diff --git a/radio/aidl/android/hardware/radio/SsInfoData.aidl b/radio/aidl/android/hardware/radio/voice/SsInfoData.aidl similarity index 86% rename from radio/aidl/android/hardware/radio/SsInfoData.aidl rename to radio/aidl/android/hardware/radio/voice/SsInfoData.aidl index 6ee3da0597..40af3934fd 100644 --- a/radio/aidl/android/hardware/radio/SsInfoData.aidl +++ b/radio/aidl/android/hardware/radio/voice/SsInfoData.aidl @@ -14,13 +14,13 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.voice; @VintfStability parcelable SsInfoData { /** * This is the response data for all of the SS GET/SET Radio requests. - * E.g. IRadio.getClir() returns two ints, so first two values of ssInfo[] will be used for + * E.g. IRadioVoice.getClir() returns two ints, so first two values of ssInfo[] will be used for * response if serviceType is SS_CLIR and requestType is SS_INTERROGATION. * Max size = RadioConst:SS_INFO_MAX */ diff --git a/radio/aidl/android/hardware/radio/StkCcUnsolSsResult.aidl b/radio/aidl/android/hardware/radio/voice/StkCcUnsolSsResult.aidl similarity index 92% rename from radio/aidl/android/hardware/radio/StkCcUnsolSsResult.aidl rename to radio/aidl/android/hardware/radio/voice/StkCcUnsolSsResult.aidl index d73f68751b..be1b6116f2 100644 --- a/radio/aidl/android/hardware/radio/StkCcUnsolSsResult.aidl +++ b/radio/aidl/android/hardware/radio/voice/StkCcUnsolSsResult.aidl @@ -14,11 +14,11 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.voice; -import android.hardware.radio.CfData; import android.hardware.radio.RadioError; -import android.hardware.radio.SsInfoData; +import android.hardware.radio.voice.CfData; +import android.hardware.radio.voice.SsInfoData; @VintfStability parcelable StkCcUnsolSsResult { @@ -84,12 +84,12 @@ parcelable StkCcUnsolSsResult { int serviceClass; RadioError result; /** - * Valid only for all SsServiceType except SsServiceType:CF_* else empty. + * Valid only for all serviceType except SERVICE_TYPE_CF_* else empty. * Only one of ssInfo and cfData may contain values and the other must be empty. */ SsInfoData[] ssInfo; /** - * Valid for SsServiceType:CF_* else empty + * Valid for serviceType SERVICE_TYPE_CF_* else empty * Only one of ssInfo and cfData may contain values and the other must be empty. */ CfData[] cfData; diff --git a/radio/aidl/android/hardware/radio/TtyMode.aidl b/radio/aidl/android/hardware/radio/voice/TtyMode.aidl similarity index 95% rename from radio/aidl/android/hardware/radio/TtyMode.aidl rename to radio/aidl/android/hardware/radio/voice/TtyMode.aidl index 344ba67734..81a846bcca 100644 --- a/radio/aidl/android/hardware/radio/TtyMode.aidl +++ b/radio/aidl/android/hardware/radio/voice/TtyMode.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.voice; @VintfStability @Backing(type="int") diff --git a/radio/aidl/android/hardware/radio/UusInfo.aidl b/radio/aidl/android/hardware/radio/voice/UusInfo.aidl similarity index 98% rename from radio/aidl/android/hardware/radio/UusInfo.aidl rename to radio/aidl/android/hardware/radio/voice/UusInfo.aidl index c96c626f7a..19e73f724c 100644 --- a/radio/aidl/android/hardware/radio/UusInfo.aidl +++ b/radio/aidl/android/hardware/radio/voice/UusInfo.aidl @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.hardware.radio; +package android.hardware.radio.voice; /** * User-to-User Signaling Information defined in 3GPP 23.087 v8.0 -- GitLab

    List of available high speed video size, fps range and max batch size configurations + * supported by the camera device, in the format of + * (width, height, fps_min, fps_max, batch_size_max), + * when ANDROID_SENSOR_PIXEL_MODE is set to + * CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION.